ZGlmZiAtLWdpdCBhL1B5dGhvbi0yLjcuNS9PYmplY3RzL2Fic3RyYWN0LmMgYi9QeXRob24tMi43LjUvT2JqZWN0cy9hYnN0cmFjdC5jCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjNjODg3MTEKLS0tIC9kZXYvbnVsbAorKysgYi9QeXRob24tMi43LjUvT2JqZWN0cy9hYnN0cmFjdC5jCkBAIC0wLDAgKzEsMzExMyBAQAorLyogQWJzdHJhY3QgT2JqZWN0IEludGVyZmFjZSAobWFueSB0aGFua3MgdG8gSmltIEZ1bHRvbikgKi8KKworI2luY2x1ZGUgIlB5dGhvbi5oIgorI2luY2x1ZGUgPGN0eXBlLmg+CisjaW5jbHVkZSAic3RydWN0bWVtYmVyLmgiIC8qIHdlIG5lZWQgdGhlIG9mZnNldG9mKCkgbWFjcm8gZnJvbSB0aGVyZSAqLworI2luY2x1ZGUgImxvbmdpbnRyZXByLmgiCisKKyNkZWZpbmUgTkVXX1NUWUxFX05VTUJFUihvKSBQeVR5cGVfSGFzRmVhdHVyZSgobyktPm9iX3R5cGUsIFwKKyAgICAgICAgICAgICAgICBQeV9UUEZMQUdTX0NIRUNLVFlQRVMpCisKKworLyogU2hvcnRoYW5kcyB0byByZXR1cm4gY2VydGFpbiBlcnJvcnMgKi8KKworc3RhdGljIFB5T2JqZWN0ICoKK3R5cGVfZXJyb3IoY29uc3QgY2hhciAqbXNnLCBQeU9iamVjdCAqb2JqKQoreworICAgIFB5RXJyX0Zvcm1hdChQeUV4Y19UeXBlRXJyb3IsIG1zZywgb2JqLT5vYl90eXBlLT50cF9uYW1lKTsKKyAgICByZXR1cm4gTlVMTDsKK30KKworc3RhdGljIFB5T2JqZWN0ICoKK251bGxfZXJyb3Iodm9pZCkKK3sKKyAgICBpZiAoIVB5RXJyX09jY3VycmVkKCkpCisgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19TeXN0ZW1FcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICJudWxsIGFyZ3VtZW50IHRvIGludGVybmFsIHJvdXRpbmUiKTsKKyAgICByZXR1cm4gTlVMTDsKK30KKworLyogT3BlcmF0aW9ucyBvbiBhbnkgb2JqZWN0ICovCisKK2ludAorUHlPYmplY3RfQ21wKFB5T2JqZWN0ICpvMSwgUHlPYmplY3QgKm8yLCBpbnQgKnJlc3VsdCkKK3sKKyAgICBpbnQgcjsKKworICAgIGlmIChvMSA9PSBOVUxMIHx8IG8yID09IE5VTEwpIHsKKyAgICAgICAgbnVsbF9lcnJvcigpOworICAgICAgICByZXR1cm4gLTE7CisgICAgfQorICAgIHIgPSBQeU9iamVjdF9Db21wYXJlKG8xLCBvMik7CisgICAgaWYgKFB5RXJyX09jY3VycmVkKCkpCisgICAgICAgIHJldHVybiAtMTsKKyAgICAqcmVzdWx0ID0gcjsKKyAgICByZXR1cm4gMDsKK30KKworUHlPYmplY3QgKgorUHlPYmplY3RfVHlwZShQeU9iamVjdCAqbykKK3sKKyAgICBQeU9iamVjdCAqdjsKKworICAgIGlmIChvID09IE5VTEwpCisgICAgICAgIHJldHVybiBudWxsX2Vycm9yKCk7CisgICAgdiA9IChQeU9iamVjdCAqKW8tPm9iX3R5cGU7CisgICAgUHlfSU5DUkVGKHYpOworICAgIHJldHVybiB2OworfQorCitQeV9zc2l6ZV90CitQeU9iamVjdF9TaXplKFB5T2JqZWN0ICpvKQoreworICAgIFB5U2VxdWVuY2VNZXRob2RzICptOworCisgICAgaWYgKG8gPT0gTlVMTCkgeworICAgICAgICBudWxsX2Vycm9yKCk7CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisKKyAgICBtID0gby0+b2JfdHlwZS0+dHBfYXNfc2VxdWVuY2U7CisgICAgaWYgKG0gJiYgbS0+c3FfbGVuZ3RoKQorICAgICAgICByZXR1cm4gbS0+c3FfbGVuZ3RoKG8pOworCisgICAgcmV0dXJuIFB5TWFwcGluZ19TaXplKG8pOworfQorCisjdW5kZWYgUHlPYmplY3RfTGVuZ3RoCitQeV9zc2l6ZV90CitQeU9iamVjdF9MZW5ndGgoUHlPYmplY3QgKm8pCit7CisgICAgcmV0dXJuIFB5T2JqZWN0X1NpemUobyk7Cit9CisjZGVmaW5lIFB5T2JqZWN0X0xlbmd0aCBQeU9iamVjdF9TaXplCisKKworLyogVGhlIGxlbmd0aCBoaW50IGZ1bmN0aW9uIHJldHVybnMgYSBub24tbmVnYXRpdmUgdmFsdWUgZnJvbSBvLl9fbGVuX18oKQorICAgb3Igby5fX2xlbmd0aF9oaW50X18oKS4gIElmIHRob3NlIG1ldGhvZHMgYXJlbid0IGZvdW5kIG9yIHJldHVybiBhIG5lZ2F0aXZlCisgICB2YWx1ZSwgdGhlbiB0aGUgZGVmYXVsdHZhbHVlIGlzIHJldHVybmVkLiAgSWYgb25lIG9mIHRoZSBjYWxscyBmYWlscywKKyAgIHRoaXMgZnVuY3Rpb24gcmV0dXJucyAtMS4KKyovCisKK1B5X3NzaXplX3QKK19QeU9iamVjdF9MZW5ndGhIaW50KFB5T2JqZWN0ICpvLCBQeV9zc2l6ZV90IGRlZmF1bHR2YWx1ZSkKK3sKKyAgICBzdGF0aWMgUHlPYmplY3QgKmhpbnRzdHJvYmogPSBOVUxMOworICAgIFB5T2JqZWN0ICpybywgKmhpbnRtZXRoOworICAgIFB5X3NzaXplX3QgcnY7CisKKyAgICAvKiB0cnkgby5fX2xlbl9fKCkgKi8KKyAgICBydiA9IFB5T2JqZWN0X1NpemUobyk7CisgICAgaWYgKHJ2ID49IDApCisgICAgICAgIHJldHVybiBydjsKKyAgICBpZiAoUHlFcnJfT2NjdXJyZWQoKSkgeworICAgICAgICBpZiAoIVB5RXJyX0V4Y2VwdGlvbk1hdGNoZXMoUHlFeGNfVHlwZUVycm9yKSAmJgorICAgICAgICAgICAgIVB5RXJyX0V4Y2VwdGlvbk1hdGNoZXMoUHlFeGNfQXR0cmlidXRlRXJyb3IpKQorICAgICAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgUHlFcnJfQ2xlYXIoKTsKKyAgICB9CisKKyAgICBpZiAoUHlJbnN0YW5jZV9DaGVjayhvKSkKKyAgICAgICAgcmV0dXJuIGRlZmF1bHR2YWx1ZTsKKyAgICAvKiB0cnkgby5fX2xlbmd0aF9oaW50X18oKSAqLworICAgIGhpbnRtZXRoID0gX1B5T2JqZWN0X0xvb2t1cFNwZWNpYWwobywgIl9fbGVuZ3RoX2hpbnRfXyIsICZoaW50c3Ryb2JqKTsKKyAgICBpZiAoaGludG1ldGggPT0gTlVMTCkgeworICAgICAgICBpZiAoUHlFcnJfT2NjdXJyZWQoKSkKKyAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgZWxzZQorICAgICAgICAgICAgcmV0dXJuIGRlZmF1bHR2YWx1ZTsKKyAgICB9CisgICAgcm8gPSBQeU9iamVjdF9DYWxsRnVuY3Rpb25PYmpBcmdzKGhpbnRtZXRoLCBOVUxMKTsKKyAgICBQeV9ERUNSRUYoaGludG1ldGgpOworICAgIGlmIChybyA9PSBOVUxMKSB7CisgICAgICAgIGlmICghUHlFcnJfRXhjZXB0aW9uTWF0Y2hlcyhQeUV4Y19UeXBlRXJyb3IpICYmCisgICAgICAgICAgICAhUHlFcnJfRXhjZXB0aW9uTWF0Y2hlcyhQeUV4Y19BdHRyaWJ1dGVFcnJvcikpCisgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgIFB5RXJyX0NsZWFyKCk7CisgICAgICAgIHJldHVybiBkZWZhdWx0dmFsdWU7CisgICAgfQorICAgIHJ2ID0gUHlOdW1iZXJfQ2hlY2socm8pID8gUHlJbnRfQXNTc2l6ZV90KHJvKSA6IGRlZmF1bHR2YWx1ZTsKKyAgICBQeV9ERUNSRUYocm8pOworICAgIHJldHVybiBydjsKK30KKworUHlPYmplY3QgKgorUHlPYmplY3RfR2V0SXRlbShQeU9iamVjdCAqbywgUHlPYmplY3QgKmtleSkKK3sKKyAgICBQeU1hcHBpbmdNZXRob2RzICptOworCisgICAgaWYgKG8gPT0gTlVMTCB8fCBrZXkgPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIG51bGxfZXJyb3IoKTsKKworICAgIG0gPSBvLT5vYl90eXBlLT50cF9hc19tYXBwaW5nOworICAgIGlmIChtICYmIG0tPm1wX3N1YnNjcmlwdCkKKyAgICAgICAgcmV0dXJuIG0tPm1wX3N1YnNjcmlwdChvLCBrZXkpOworCisgICAgaWYgKG8tPm9iX3R5cGUtPnRwX2FzX3NlcXVlbmNlKSB7CisgICAgICAgIGlmIChQeUluZGV4X0NoZWNrKGtleSkpIHsKKyAgICAgICAgICAgIFB5X3NzaXplX3Qga2V5X3ZhbHVlOworICAgICAgICAgICAga2V5X3ZhbHVlID0gUHlOdW1iZXJfQXNTc2l6ZV90KGtleSwgUHlFeGNfSW5kZXhFcnJvcik7CisgICAgICAgICAgICBpZiAoa2V5X3ZhbHVlID09IC0xICYmIFB5RXJyX09jY3VycmVkKCkpCisgICAgICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgICAgICAgICByZXR1cm4gUHlTZXF1ZW5jZV9HZXRJdGVtKG8sIGtleV92YWx1ZSk7CisgICAgICAgIH0KKyAgICAgICAgZWxzZSBpZiAoby0+b2JfdHlwZS0+dHBfYXNfc2VxdWVuY2UtPnNxX2l0ZW0pCisgICAgICAgICAgICByZXR1cm4gdHlwZV9lcnJvcigic2VxdWVuY2UgaW5kZXggbXVzdCAiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiYmUgaW50ZWdlciwgbm90ICclLjIwMHMnIiwga2V5KTsKKyAgICB9CisKKyAgICByZXR1cm4gdHlwZV9lcnJvcigiJyUuMjAwcycgb2JqZWN0IGhhcyBubyBhdHRyaWJ1dGUgJ19fZ2V0aXRlbV9fJyIsIG8pOworfQorCitpbnQKK1B5T2JqZWN0X1NldEl0ZW0oUHlPYmplY3QgKm8sIFB5T2JqZWN0ICprZXksIFB5T2JqZWN0ICp2YWx1ZSkKK3sKKyAgICBQeU1hcHBpbmdNZXRob2RzICptOworCisgICAgaWYgKG8gPT0gTlVMTCB8fCBrZXkgPT0gTlVMTCB8fCB2YWx1ZSA9PSBOVUxMKSB7CisgICAgICAgIG51bGxfZXJyb3IoKTsKKyAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKyAgICBtID0gby0+b2JfdHlwZS0+dHBfYXNfbWFwcGluZzsKKyAgICBpZiAobSAmJiBtLT5tcF9hc3Nfc3Vic2NyaXB0KQorICAgICAgICByZXR1cm4gbS0+bXBfYXNzX3N1YnNjcmlwdChvLCBrZXksIHZhbHVlKTsKKworICAgIGlmIChvLT5vYl90eXBlLT50cF9hc19zZXF1ZW5jZSkgeworICAgICAgICBpZiAoUHlJbmRleF9DaGVjayhrZXkpKSB7CisgICAgICAgICAgICBQeV9zc2l6ZV90IGtleV92YWx1ZTsKKyAgICAgICAgICAgIGtleV92YWx1ZSA9IFB5TnVtYmVyX0FzU3NpemVfdChrZXksIFB5RXhjX0luZGV4RXJyb3IpOworICAgICAgICAgICAgaWYgKGtleV92YWx1ZSA9PSAtMSAmJiBQeUVycl9PY2N1cnJlZCgpKQorICAgICAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgICAgIHJldHVybiBQeVNlcXVlbmNlX1NldEl0ZW0obywga2V5X3ZhbHVlLCB2YWx1ZSk7CisgICAgICAgIH0KKyAgICAgICAgZWxzZSBpZiAoby0+b2JfdHlwZS0+dHBfYXNfc2VxdWVuY2UtPnNxX2Fzc19pdGVtKSB7CisgICAgICAgICAgICB0eXBlX2Vycm9yKCJzZXF1ZW5jZSBpbmRleCBtdXN0IGJlICIKKyAgICAgICAgICAgICAgICAgICAgICAgImludGVnZXIsIG5vdCAnJS4yMDBzJyIsIGtleSk7CisgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgIH0KKyAgICB9CisKKyAgICB0eXBlX2Vycm9yKCInJS4yMDBzJyBvYmplY3QgZG9lcyBub3Qgc3VwcG9ydCBpdGVtIGFzc2lnbm1lbnQiLCBvKTsKKyAgICByZXR1cm4gLTE7Cit9CisKK2ludAorUHlPYmplY3RfRGVsSXRlbShQeU9iamVjdCAqbywgUHlPYmplY3QgKmtleSkKK3sKKyAgICBQeU1hcHBpbmdNZXRob2RzICptOworCisgICAgaWYgKG8gPT0gTlVMTCB8fCBrZXkgPT0gTlVMTCkgeworICAgICAgICBudWxsX2Vycm9yKCk7CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisgICAgbSA9IG8tPm9iX3R5cGUtPnRwX2FzX21hcHBpbmc7CisgICAgaWYgKG0gJiYgbS0+bXBfYXNzX3N1YnNjcmlwdCkKKyAgICAgICAgcmV0dXJuIG0tPm1wX2Fzc19zdWJzY3JpcHQobywga2V5LCAoUHlPYmplY3QqKU5VTEwpOworCisgICAgaWYgKG8tPm9iX3R5cGUtPnRwX2FzX3NlcXVlbmNlKSB7CisgICAgICAgIGlmIChQeUluZGV4X0NoZWNrKGtleSkpIHsKKyAgICAgICAgICAgIFB5X3NzaXplX3Qga2V5X3ZhbHVlOworICAgICAgICAgICAga2V5X3ZhbHVlID0gUHlOdW1iZXJfQXNTc2l6ZV90KGtleSwgUHlFeGNfSW5kZXhFcnJvcik7CisgICAgICAgICAgICBpZiAoa2V5X3ZhbHVlID09IC0xICYmIFB5RXJyX09jY3VycmVkKCkpCisgICAgICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICAgICAgcmV0dXJuIFB5U2VxdWVuY2VfRGVsSXRlbShvLCBrZXlfdmFsdWUpOworICAgICAgICB9CisgICAgICAgIGVsc2UgaWYgKG8tPm9iX3R5cGUtPnRwX2FzX3NlcXVlbmNlLT5zcV9hc3NfaXRlbSkgeworICAgICAgICAgICAgdHlwZV9lcnJvcigic2VxdWVuY2UgaW5kZXggbXVzdCBiZSAiCisgICAgICAgICAgICAgICAgICAgICAgICJpbnRlZ2VyLCBub3QgJyUuMjAwcyciLCBrZXkpOworICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICB9CisgICAgfQorCisgICAgdHlwZV9lcnJvcigiJyUuMjAwcycgb2JqZWN0IGRvZXMgbm90IHN1cHBvcnQgaXRlbSBkZWxldGlvbiIsIG8pOworICAgIHJldHVybiAtMTsKK30KKworaW50CitQeU9iamVjdF9EZWxJdGVtU3RyaW5nKFB5T2JqZWN0ICpvLCBjaGFyICprZXkpCit7CisgICAgUHlPYmplY3QgKm9rZXk7CisgICAgaW50IHJldDsKKworICAgIGlmIChvID09IE5VTEwgfHwga2V5ID09IE5VTEwpIHsKKyAgICAgICAgbnVsbF9lcnJvcigpOworICAgICAgICByZXR1cm4gLTE7CisgICAgfQorICAgIG9rZXkgPSBQeVN0cmluZ19Gcm9tU3RyaW5nKGtleSk7CisgICAgaWYgKG9rZXkgPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIC0xOworICAgIHJldCA9IFB5T2JqZWN0X0RlbEl0ZW0obywgb2tleSk7CisgICAgUHlfREVDUkVGKG9rZXkpOworICAgIHJldHVybiByZXQ7Cit9CisKK2ludAorUHlPYmplY3RfQXNDaGFyQnVmZmVyKFB5T2JqZWN0ICpvYmosCisgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgKipidWZmZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgIFB5X3NzaXplX3QgKmJ1ZmZlcl9sZW4pCit7CisgICAgUHlCdWZmZXJQcm9jcyAqcGI7CisgICAgY2hhciAqcHA7CisgICAgUHlfc3NpemVfdCBsZW47CisKKyAgICBpZiAob2JqID09IE5VTEwgfHwgYnVmZmVyID09IE5VTEwgfHwgYnVmZmVyX2xlbiA9PSBOVUxMKSB7CisgICAgICAgIG51bGxfZXJyb3IoKTsKKyAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKyAgICBwYiA9IG9iai0+b2JfdHlwZS0+dHBfYXNfYnVmZmVyOworICAgIGlmIChwYiA9PSBOVUxMIHx8CisgICAgICAgICBwYi0+YmZfZ2V0Y2hhcmJ1ZmZlciA9PSBOVUxMIHx8CisgICAgICAgICBwYi0+YmZfZ2V0c2VnY291bnQgPT0gTlVMTCkgeworICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfVHlwZUVycm9yLAorICAgICAgICAgICAgICAgICAgICAgICAgImV4cGVjdGVkIGEgY2hhcmFjdGVyIGJ1ZmZlciBvYmplY3QiKTsKKyAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKyAgICBpZiAoKCpwYi0+YmZfZ2V0c2VnY291bnQpKG9iaixOVUxMKSAhPSAxKSB7CisgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19UeXBlRXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAgICAiZXhwZWN0ZWQgYSBzaW5nbGUtc2VnbWVudCBidWZmZXIgb2JqZWN0Iik7CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisgICAgbGVuID0gKCpwYi0+YmZfZ2V0Y2hhcmJ1ZmZlcikob2JqLCAwLCAmcHApOworICAgIGlmIChsZW4gPCAwKQorICAgICAgICByZXR1cm4gLTE7CisgICAgKmJ1ZmZlciA9IHBwOworICAgICpidWZmZXJfbGVuID0gbGVuOworICAgIHJldHVybiAwOworfQorCitpbnQKK1B5T2JqZWN0X0NoZWNrUmVhZEJ1ZmZlcihQeU9iamVjdCAqb2JqKQoreworICAgIFB5QnVmZmVyUHJvY3MgKnBiID0gb2JqLT5vYl90eXBlLT50cF9hc19idWZmZXI7CisKKyAgICBpZiAocGIgPT0gTlVMTCB8fAorICAgICAgICBwYi0+YmZfZ2V0cmVhZGJ1ZmZlciA9PSBOVUxMIHx8CisgICAgICAgIHBiLT5iZl9nZXRzZWdjb3VudCA9PSBOVUxMIHx8CisgICAgICAgICgqcGItPmJmX2dldHNlZ2NvdW50KShvYmosIE5VTEwpICE9IDEpCisgICAgICAgIHJldHVybiAwOworICAgIHJldHVybiAxOworfQorCitpbnQgUHlPYmplY3RfQXNSZWFkQnVmZmVyKFB5T2JqZWN0ICpvYmosCisgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHZvaWQgKipidWZmZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgIFB5X3NzaXplX3QgKmJ1ZmZlcl9sZW4pCit7CisgICAgUHlCdWZmZXJQcm9jcyAqcGI7CisgICAgdm9pZCAqcHA7CisgICAgUHlfc3NpemVfdCBsZW47CisKKyAgICBpZiAob2JqID09IE5VTEwgfHwgYnVmZmVyID09IE5VTEwgfHwgYnVmZmVyX2xlbiA9PSBOVUxMKSB7CisgICAgICAgIG51bGxfZXJyb3IoKTsKKyAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKyAgICBwYiA9IG9iai0+b2JfdHlwZS0+dHBfYXNfYnVmZmVyOworICAgIGlmIChwYiA9PSBOVUxMIHx8CisgICAgICAgICBwYi0+YmZfZ2V0cmVhZGJ1ZmZlciA9PSBOVUxMIHx8CisgICAgICAgICBwYi0+YmZfZ2V0c2VnY291bnQgPT0gTlVMTCkgeworICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfVHlwZUVycm9yLAorICAgICAgICAgICAgICAgICAgICAgICAgImV4cGVjdGVkIGEgcmVhZGFibGUgYnVmZmVyIG9iamVjdCIpOworICAgICAgICByZXR1cm4gLTE7CisgICAgfQorICAgIGlmICgoKnBiLT5iZl9nZXRzZWdjb3VudCkob2JqLCBOVUxMKSAhPSAxKSB7CisgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19UeXBlRXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAgICAiZXhwZWN0ZWQgYSBzaW5nbGUtc2VnbWVudCBidWZmZXIgb2JqZWN0Iik7CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisgICAgbGVuID0gKCpwYi0+YmZfZ2V0cmVhZGJ1ZmZlcikob2JqLCAwLCAmcHApOworICAgIGlmIChsZW4gPCAwKQorICAgICAgICByZXR1cm4gLTE7CisgICAgKmJ1ZmZlciA9IHBwOworICAgICpidWZmZXJfbGVuID0gbGVuOworICAgIHJldHVybiAwOworfQorCitpbnQgUHlPYmplY3RfQXNXcml0ZUJ1ZmZlcihQeU9iamVjdCAqb2JqLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgdm9pZCAqKmJ1ZmZlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIFB5X3NzaXplX3QgKmJ1ZmZlcl9sZW4pCit7CisgICAgUHlCdWZmZXJQcm9jcyAqcGI7CisgICAgdm9pZCpwcDsKKyAgICBQeV9zc2l6ZV90IGxlbjsKKworICAgIGlmIChvYmogPT0gTlVMTCB8fCBidWZmZXIgPT0gTlVMTCB8fCBidWZmZXJfbGVuID09IE5VTEwpIHsKKyAgICAgICAgbnVsbF9lcnJvcigpOworICAgICAgICByZXR1cm4gLTE7CisgICAgfQorICAgIHBiID0gb2JqLT5vYl90eXBlLT50cF9hc19idWZmZXI7CisgICAgaWYgKHBiID09IE5VTEwgfHwKKyAgICAgICAgIHBiLT5iZl9nZXR3cml0ZWJ1ZmZlciA9PSBOVUxMIHx8CisgICAgICAgICBwYi0+YmZfZ2V0c2VnY291bnQgPT0gTlVMTCkgeworICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfVHlwZUVycm9yLAorICAgICAgICAgICAgICAgICAgICAgICAgImV4cGVjdGVkIGEgd3JpdGVhYmxlIGJ1ZmZlciBvYmplY3QiKTsKKyAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKyAgICBpZiAoKCpwYi0+YmZfZ2V0c2VnY291bnQpKG9iaiwgTlVMTCkgIT0gMSkgeworICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfVHlwZUVycm9yLAorICAgICAgICAgICAgICAgICAgICAgICAgImV4cGVjdGVkIGEgc2luZ2xlLXNlZ21lbnQgYnVmZmVyIG9iamVjdCIpOworICAgICAgICByZXR1cm4gLTE7CisgICAgfQorICAgIGxlbiA9ICgqcGItPmJmX2dldHdyaXRlYnVmZmVyKShvYmosMCwmcHApOworICAgIGlmIChsZW4gPCAwKQorICAgICAgICByZXR1cm4gLTE7CisgICAgKmJ1ZmZlciA9IHBwOworICAgICpidWZmZXJfbGVuID0gbGVuOworICAgIHJldHVybiAwOworfQorCisvKiBCdWZmZXIgQy1BUEkgZm9yIFB5dGhvbiAzLjAgKi8KKworaW50CitQeU9iamVjdF9HZXRCdWZmZXIoUHlPYmplY3QgKm9iaiwgUHlfYnVmZmVyICp2aWV3LCBpbnQgZmxhZ3MpCit7CisgICAgaWYgKCFQeU9iamVjdF9DaGVja0J1ZmZlcihvYmopKSB7CisgICAgICAgIFB5RXJyX0Zvcm1hdChQeUV4Y19UeXBlRXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAiJyUxMDBzJyBkb2VzIG5vdCBoYXZlIHRoZSBidWZmZXIgaW50ZXJmYWNlIiwKKyAgICAgICAgICAgICAgICAgICAgIFB5X1RZUEUob2JqKS0+dHBfbmFtZSk7CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisgICAgcmV0dXJuICgqKG9iai0+b2JfdHlwZS0+dHBfYXNfYnVmZmVyLT5iZl9nZXRidWZmZXIpKShvYmosIHZpZXcsIGZsYWdzKTsKK30KKworc3RhdGljIGludAorX0lzRm9ydHJhbkNvbnRpZ3VvdXMoUHlfYnVmZmVyICp2aWV3KQoreworICAgIFB5X3NzaXplX3Qgc2QsIGRpbTsKKyAgICBpbnQgaTsKKworICAgIGlmICh2aWV3LT5uZGltID09IDApIHJldHVybiAxOworICAgIGlmICh2aWV3LT5zdHJpZGVzID09IE5VTEwpIHJldHVybiAodmlldy0+bmRpbSA9PSAxKTsKKworICAgIHNkID0gdmlldy0+aXRlbXNpemU7CisgICAgaWYgKHZpZXctPm5kaW0gPT0gMSkgcmV0dXJuICh2aWV3LT5zaGFwZVswXSA9PSAxIHx8CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2QgPT0gdmlldy0+c3RyaWRlc1swXSk7CisgICAgZm9yIChpPTA7IGk8dmlldy0+bmRpbTsgaSsrKSB7CisgICAgICAgIGRpbSA9IHZpZXctPnNoYXBlW2ldOworICAgICAgICBpZiAoZGltID09IDApIHJldHVybiAxOworICAgICAgICBpZiAodmlldy0+c3RyaWRlc1tpXSAhPSBzZCkgcmV0dXJuIDA7CisgICAgICAgIHNkICo9IGRpbTsKKyAgICB9CisgICAgcmV0dXJuIDE7Cit9CisKK3N0YXRpYyBpbnQKK19Jc0NDb250aWd1b3VzKFB5X2J1ZmZlciAqdmlldykKK3sKKyAgICBQeV9zc2l6ZV90IHNkLCBkaW07CisgICAgaW50IGk7CisKKyAgICBpZiAodmlldy0+bmRpbSA9PSAwKSByZXR1cm4gMTsKKyAgICBpZiAodmlldy0+c3RyaWRlcyA9PSBOVUxMKSByZXR1cm4gMTsKKworICAgIHNkID0gdmlldy0+aXRlbXNpemU7CisgICAgaWYgKHZpZXctPm5kaW0gPT0gMSkgcmV0dXJuICh2aWV3LT5zaGFwZVswXSA9PSAxIHx8CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2QgPT0gdmlldy0+c3RyaWRlc1swXSk7CisgICAgZm9yIChpPXZpZXctPm5kaW0tMTsgaT49MDsgaS0tKSB7CisgICAgICAgIGRpbSA9IHZpZXctPnNoYXBlW2ldOworICAgICAgICBpZiAoZGltID09IDApIHJldHVybiAxOworICAgICAgICBpZiAodmlldy0+c3RyaWRlc1tpXSAhPSBzZCkgcmV0dXJuIDA7CisgICAgICAgIHNkICo9IGRpbTsKKyAgICB9CisgICAgcmV0dXJuIDE7Cit9CisKK2ludAorUHlCdWZmZXJfSXNDb250aWd1b3VzKFB5X2J1ZmZlciAqdmlldywgY2hhciBmb3J0KQoreworCisgICAgaWYgKHZpZXctPnN1Ym9mZnNldHMgIT0gTlVMTCkgcmV0dXJuIDA7CisKKyAgICBpZiAoZm9ydCA9PSAnQycpCisgICAgICAgIHJldHVybiBfSXNDQ29udGlndW91cyh2aWV3KTsKKyAgICBlbHNlIGlmIChmb3J0ID09ICdGJykKKyAgICAgICAgcmV0dXJuIF9Jc0ZvcnRyYW5Db250aWd1b3VzKHZpZXcpOworICAgIGVsc2UgaWYgKGZvcnQgPT0gJ0EnKQorICAgICAgICByZXR1cm4gKF9Jc0NDb250aWd1b3VzKHZpZXcpIHx8IF9Jc0ZvcnRyYW5Db250aWd1b3VzKHZpZXcpKTsKKyAgICByZXR1cm4gMDsKK30KKworCit2b2lkKgorUHlCdWZmZXJfR2V0UG9pbnRlcihQeV9idWZmZXIgKnZpZXcsIFB5X3NzaXplX3QgKmluZGljZXMpCit7CisgICAgY2hhciogcG9pbnRlcjsKKyAgICBpbnQgaTsKKyAgICBwb2ludGVyID0gKGNoYXIgKil2aWV3LT5idWY7CisgICAgZm9yIChpID0gMDsgaSA8IHZpZXctPm5kaW07IGkrKykgeworICAgICAgICBwb2ludGVyICs9IHZpZXctPnN0cmlkZXNbaV0qaW5kaWNlc1tpXTsKKyAgICAgICAgaWYgKCh2aWV3LT5zdWJvZmZzZXRzICE9IE5VTEwpICYmICh2aWV3LT5zdWJvZmZzZXRzW2ldID49IDApKSB7CisgICAgICAgICAgICBwb2ludGVyID0gKigoY2hhcioqKXBvaW50ZXIpICsgdmlldy0+c3Vib2Zmc2V0c1tpXTsKKyAgICAgICAgfQorICAgIH0KKyAgICByZXR1cm4gKHZvaWQqKXBvaW50ZXI7Cit9CisKKwordm9pZAorX1B5X2FkZF9vbmVfdG9faW5kZXhfRihpbnQgbmQsIFB5X3NzaXplX3QgKmluZGV4LCBjb25zdCBQeV9zc2l6ZV90ICpzaGFwZSkKK3sKKyAgICBpbnQgazsKKworICAgIGZvciAoaz0wOyBrPG5kOyBrKyspIHsKKyAgICAgICAgaWYgKGluZGV4W2tdIDwgc2hhcGVba10tMSkgeworICAgICAgICAgICAgaW5kZXhba10rKzsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisgICAgICAgIGVsc2UgeworICAgICAgICAgICAgaW5kZXhba10gPSAwOworICAgICAgICB9CisgICAgfQorfQorCit2b2lkCitfUHlfYWRkX29uZV90b19pbmRleF9DKGludCBuZCwgUHlfc3NpemVfdCAqaW5kZXgsIGNvbnN0IFB5X3NzaXplX3QgKnNoYXBlKQoreworICAgIGludCBrOworCisgICAgZm9yIChrPW5kLTE7IGs+PTA7IGstLSkgeworICAgICAgICBpZiAoaW5kZXhba10gPCBzaGFwZVtrXS0xKSB7CisgICAgICAgICAgICBpbmRleFtrXSsrOworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKyAgICAgICAgZWxzZSB7CisgICAgICAgICAgICBpbmRleFtrXSA9IDA7CisgICAgICAgIH0KKyAgICB9Cit9CisKKyAgLyogdmlldyBpcyBub3QgY2hlY2tlZCBmb3IgY29uc2lzdGVuY3kgaW4gZWl0aGVyIG9mIHRoZXNlLiAgSXQgaXMKKyAgICAgYXNzdW1lZCB0aGF0IHRoZSBzaXplIG9mIHRoZSBidWZmZXIgaXMgdmlldy0+bGVuIGluCisgICAgIHZpZXctPmxlbiAvIHZpZXctPml0ZW1zaXplIGVsZW1lbnRzLgorICAqLworCitpbnQKK1B5QnVmZmVyX1RvQ29udGlndW91cyh2b2lkICpidWYsIFB5X2J1ZmZlciAqdmlldywgUHlfc3NpemVfdCBsZW4sIGNoYXIgZm9ydCkKK3sKKyAgICBpbnQgazsKKyAgICB2b2lkICgqYWRkb25lKShpbnQsIFB5X3NzaXplX3QgKiwgY29uc3QgUHlfc3NpemVfdCAqKTsKKyAgICBQeV9zc2l6ZV90ICppbmRpY2VzLCBlbGVtZW50czsKKyAgICBjaGFyICpkZXN0LCAqcHRyOworCisgICAgaWYgKGxlbiA+IHZpZXctPmxlbikgeworICAgICAgICBsZW4gPSB2aWV3LT5sZW47CisgICAgfQorCisgICAgaWYgKFB5QnVmZmVyX0lzQ29udGlndW91cyh2aWV3LCBmb3J0KSkgeworICAgICAgICAvKiBzaW1wbGVzdCBjb3B5IGlzIGFsbCB0aGF0IGlzIG5lZWRlZCAqLworICAgICAgICBtZW1jcHkoYnVmLCB2aWV3LT5idWYsIGxlbik7CisgICAgICAgIHJldHVybiAwOworICAgIH0KKworICAgIC8qIE90aGVyd2lzZSBhIG1vcmUgZWxhYm9yYXRlIHNjaGVtZSBpcyBuZWVkZWQgKi8KKworICAgIC8qIFhYWChubm9yd2l0eik6IG5lZWQgdG8gY2hlY2sgZm9yIG92ZXJmbG93ISAqLworICAgIGluZGljZXMgPSAoUHlfc3NpemVfdCAqKVB5TWVtX01hbGxvYyhzaXplb2YoUHlfc3NpemVfdCkqKHZpZXctPm5kaW0pKTsKKyAgICBpZiAoaW5kaWNlcyA9PSBOVUxMKSB7CisgICAgICAgIFB5RXJyX05vTWVtb3J5KCk7CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisgICAgZm9yIChrPTA7IGs8dmlldy0+bmRpbTtrKyspIHsKKyAgICAgICAgaW5kaWNlc1trXSA9IDA7CisgICAgfQorCisgICAgaWYgKGZvcnQgPT0gJ0YnKSB7CisgICAgICAgIGFkZG9uZSA9IF9QeV9hZGRfb25lX3RvX2luZGV4X0Y7CisgICAgfQorICAgIGVsc2UgeworICAgICAgICBhZGRvbmUgPSBfUHlfYWRkX29uZV90b19pbmRleF9DOworICAgIH0KKyAgICBkZXN0ID0gYnVmOworICAgIC8qIFhYWCA6IFRoaXMgaXMgbm90IGdvaW5nIHRvIGJlIHRoZSBmYXN0ZXN0IGNvZGUgaW4gdGhlIHdvcmxkCisgICAgICAgICAgICAgc2V2ZXJhbCBvcHRpbWl6YXRpb25zIGFyZSBwb3NzaWJsZS4KKyAgICAgKi8KKyAgICBlbGVtZW50cyA9IGxlbiAvIHZpZXctPml0ZW1zaXplOworICAgIHdoaWxlIChlbGVtZW50cy0tKSB7CisgICAgICAgIGFkZG9uZSh2aWV3LT5uZGltLCBpbmRpY2VzLCB2aWV3LT5zaGFwZSk7CisgICAgICAgIHB0ciA9IFB5QnVmZmVyX0dldFBvaW50ZXIodmlldywgaW5kaWNlcyk7CisgICAgICAgIG1lbWNweShkZXN0LCBwdHIsIHZpZXctPml0ZW1zaXplKTsKKyAgICAgICAgZGVzdCArPSB2aWV3LT5pdGVtc2l6ZTsKKyAgICB9CisgICAgUHlNZW1fRnJlZShpbmRpY2VzKTsKKyAgICByZXR1cm4gMDsKK30KKworaW50CitQeUJ1ZmZlcl9Gcm9tQ29udGlndW91cyhQeV9idWZmZXIgKnZpZXcsIHZvaWQgKmJ1ZiwgUHlfc3NpemVfdCBsZW4sIGNoYXIgZm9ydCkKK3sKKyAgICBpbnQgazsKKyAgICB2b2lkICgqYWRkb25lKShpbnQsIFB5X3NzaXplX3QgKiwgY29uc3QgUHlfc3NpemVfdCAqKTsKKyAgICBQeV9zc2l6ZV90ICppbmRpY2VzLCBlbGVtZW50czsKKyAgICBjaGFyICpzcmMsICpwdHI7CisKKyAgICBpZiAobGVuID4gdmlldy0+bGVuKSB7CisgICAgICAgIGxlbiA9IHZpZXctPmxlbjsKKyAgICB9CisKKyAgICBpZiAoUHlCdWZmZXJfSXNDb250aWd1b3VzKHZpZXcsIGZvcnQpKSB7CisgICAgICAgIC8qIHNpbXBsZXN0IGNvcHkgaXMgYWxsIHRoYXQgaXMgbmVlZGVkICovCisgICAgICAgIG1lbWNweSh2aWV3LT5idWYsIGJ1ZiwgbGVuKTsKKyAgICAgICAgcmV0dXJuIDA7CisgICAgfQorCisgICAgLyogT3RoZXJ3aXNlIGEgbW9yZSBlbGFib3JhdGUgc2NoZW1lIGlzIG5lZWRlZCAqLworCisgICAgLyogWFhYKG5ub3J3aXR6KTogbmVlZCB0byBjaGVjayBmb3Igb3ZlcmZsb3chICovCisgICAgaW5kaWNlcyA9IChQeV9zc2l6ZV90ICopUHlNZW1fTWFsbG9jKHNpemVvZihQeV9zc2l6ZV90KSoodmlldy0+bmRpbSkpOworICAgIGlmIChpbmRpY2VzID09IE5VTEwpIHsKKyAgICAgICAgUHlFcnJfTm9NZW1vcnkoKTsKKyAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKyAgICBmb3IgKGs9MDsgazx2aWV3LT5uZGltO2srKykgeworICAgICAgICBpbmRpY2VzW2tdID0gMDsKKyAgICB9CisKKyAgICBpZiAoZm9ydCA9PSAnRicpIHsKKyAgICAgICAgYWRkb25lID0gX1B5X2FkZF9vbmVfdG9faW5kZXhfRjsKKyAgICB9CisgICAgZWxzZSB7CisgICAgICAgIGFkZG9uZSA9IF9QeV9hZGRfb25lX3RvX2luZGV4X0M7CisgICAgfQorICAgIHNyYyA9IGJ1ZjsKKyAgICAvKiBYWFggOiBUaGlzIGlzIG5vdCBnb2luZyB0byBiZSB0aGUgZmFzdGVzdCBjb2RlIGluIHRoZSB3b3JsZAorICAgICAgICAgICAgIHNldmVyYWwgb3B0aW1pemF0aW9ucyBhcmUgcG9zc2libGUuCisgICAgICovCisgICAgZWxlbWVudHMgPSBsZW4gLyB2aWV3LT5pdGVtc2l6ZTsKKyAgICB3aGlsZSAoZWxlbWVudHMtLSkgeworICAgICAgICBhZGRvbmUodmlldy0+bmRpbSwgaW5kaWNlcywgdmlldy0+c2hhcGUpOworICAgICAgICBwdHIgPSBQeUJ1ZmZlcl9HZXRQb2ludGVyKHZpZXcsIGluZGljZXMpOworICAgICAgICBtZW1jcHkocHRyLCBzcmMsIHZpZXctPml0ZW1zaXplKTsKKyAgICAgICAgc3JjICs9IHZpZXctPml0ZW1zaXplOworICAgIH0KKworICAgIFB5TWVtX0ZyZWUoaW5kaWNlcyk7CisgICAgcmV0dXJuIDA7Cit9CisKK2ludCBQeU9iamVjdF9Db3B5RGF0YShQeU9iamVjdCAqZGVzdCwgUHlPYmplY3QgKnNyYykKK3sKKyAgICBQeV9idWZmZXIgdmlld19kZXN0LCB2aWV3X3NyYzsKKyAgICBpbnQgazsKKyAgICBQeV9zc2l6ZV90ICppbmRpY2VzLCBlbGVtZW50czsKKyAgICBjaGFyICpkcHRyLCAqc3B0cjsKKworICAgIGlmICghUHlPYmplY3RfQ2hlY2tCdWZmZXIoZGVzdCkgfHwKKyAgICAgICAgIVB5T2JqZWN0X0NoZWNrQnVmZmVyKHNyYykpIHsKKyAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1R5cGVFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICJib3RoIGRlc3RpbmF0aW9uIGFuZCBzb3VyY2UgbXVzdCBoYXZlIHRoZSAiXAorICAgICAgICAgICAgICAgICAgICAgICAgImJ1ZmZlciBpbnRlcmZhY2UiKTsKKyAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKworICAgIGlmIChQeU9iamVjdF9HZXRCdWZmZXIoZGVzdCwgJnZpZXdfZGVzdCwgUHlCVUZfRlVMTCkgIT0gMCkgcmV0dXJuIC0xOworICAgIGlmIChQeU9iamVjdF9HZXRCdWZmZXIoc3JjLCAmdmlld19zcmMsIFB5QlVGX0ZVTExfUk8pICE9IDApIHsKKyAgICAgICAgUHlCdWZmZXJfUmVsZWFzZSgmdmlld19kZXN0KTsKKyAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKworICAgIGlmICh2aWV3X2Rlc3QubGVuIDwgdmlld19zcmMubGVuKSB7CisgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19CdWZmZXJFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICJkZXN0aW5hdGlvbiBpcyB0b28gc21hbGwgdG8gcmVjZWl2ZSBkYXRhIGZyb20gc291cmNlIik7CisgICAgICAgIFB5QnVmZmVyX1JlbGVhc2UoJnZpZXdfZGVzdCk7CisgICAgICAgIFB5QnVmZmVyX1JlbGVhc2UoJnZpZXdfc3JjKTsKKyAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKworICAgIGlmICgoUHlCdWZmZXJfSXNDb250aWd1b3VzKCZ2aWV3X2Rlc3QsICdDJykgJiYKKyAgICAgICAgIFB5QnVmZmVyX0lzQ29udGlndW91cygmdmlld19zcmMsICdDJykpIHx8CisgICAgICAgIChQeUJ1ZmZlcl9Jc0NvbnRpZ3VvdXMoJnZpZXdfZGVzdCwgJ0YnKSAmJgorICAgICAgICAgUHlCdWZmZXJfSXNDb250aWd1b3VzKCZ2aWV3X3NyYywgJ0YnKSkpIHsKKyAgICAgICAgLyogc2ltcGxlc3QgY29weSBpcyBhbGwgdGhhdCBpcyBuZWVkZWQgKi8KKyAgICAgICAgbWVtY3B5KHZpZXdfZGVzdC5idWYsIHZpZXdfc3JjLmJ1Ziwgdmlld19zcmMubGVuKTsKKyAgICAgICAgUHlCdWZmZXJfUmVsZWFzZSgmdmlld19kZXN0KTsKKyAgICAgICAgUHlCdWZmZXJfUmVsZWFzZSgmdmlld19zcmMpOworICAgICAgICByZXR1cm4gMDsKKyAgICB9CisKKyAgICAvKiBPdGhlcndpc2UgYSBtb3JlIGVsYWJvcmF0ZSBjb3B5IHNjaGVtZSBpcyBuZWVkZWQgKi8KKworICAgIC8qIFhYWChubm9yd2l0eik6IG5lZWQgdG8gY2hlY2sgZm9yIG92ZXJmbG93ISAqLworICAgIGluZGljZXMgPSAoUHlfc3NpemVfdCAqKVB5TWVtX01hbGxvYyhzaXplb2YoUHlfc3NpemVfdCkqdmlld19zcmMubmRpbSk7CisgICAgaWYgKGluZGljZXMgPT0gTlVMTCkgeworICAgICAgICBQeUVycl9Ob01lbW9yeSgpOworICAgICAgICBQeUJ1ZmZlcl9SZWxlYXNlKCZ2aWV3X2Rlc3QpOworICAgICAgICBQeUJ1ZmZlcl9SZWxlYXNlKCZ2aWV3X3NyYyk7CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisgICAgZm9yIChrPTA7IGs8dmlld19zcmMubmRpbTtrKyspIHsKKyAgICAgICAgaW5kaWNlc1trXSA9IDA7CisgICAgfQorICAgIGVsZW1lbnRzID0gMTsKKyAgICBmb3IgKGs9MDsgazx2aWV3X3NyYy5uZGltOyBrKyspIHsKKyAgICAgICAgLyogWFhYKG5ub3J3aXR6KTogY2FuIHRoaXMgb3ZlcmZsb3c/ICovCisgICAgICAgIGVsZW1lbnRzICo9IHZpZXdfc3JjLnNoYXBlW2tdOworICAgIH0KKyAgICB3aGlsZSAoZWxlbWVudHMtLSkgeworICAgICAgICBfUHlfYWRkX29uZV90b19pbmRleF9DKHZpZXdfc3JjLm5kaW0sIGluZGljZXMsIHZpZXdfc3JjLnNoYXBlKTsKKyAgICAgICAgZHB0ciA9IFB5QnVmZmVyX0dldFBvaW50ZXIoJnZpZXdfZGVzdCwgaW5kaWNlcyk7CisgICAgICAgIHNwdHIgPSBQeUJ1ZmZlcl9HZXRQb2ludGVyKCZ2aWV3X3NyYywgaW5kaWNlcyk7CisgICAgICAgIG1lbWNweShkcHRyLCBzcHRyLCB2aWV3X3NyYy5pdGVtc2l6ZSk7CisgICAgfQorICAgIFB5TWVtX0ZyZWUoaW5kaWNlcyk7CisgICAgUHlCdWZmZXJfUmVsZWFzZSgmdmlld19kZXN0KTsKKyAgICBQeUJ1ZmZlcl9SZWxlYXNlKCZ2aWV3X3NyYyk7CisgICAgcmV0dXJuIDA7Cit9CisKK3ZvaWQKK1B5QnVmZmVyX0ZpbGxDb250aWd1b3VzU3RyaWRlcyhpbnQgbmQsIFB5X3NzaXplX3QgKnNoYXBlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFB5X3NzaXplX3QgKnN0cmlkZXMsIGludCBpdGVtc2l6ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjaGFyIGZvcnQpCit7CisgICAgaW50IGs7CisgICAgUHlfc3NpemVfdCBzZDsKKworICAgIHNkID0gaXRlbXNpemU7CisgICAgaWYgKGZvcnQgPT0gJ0YnKSB7CisgICAgICAgIGZvciAoaz0wOyBrPG5kOyBrKyspIHsKKyAgICAgICAgICAgIHN0cmlkZXNba10gPSBzZDsKKyAgICAgICAgICAgIHNkICo9IHNoYXBlW2tdOworICAgICAgICB9CisgICAgfQorICAgIGVsc2UgeworICAgICAgICBmb3IgKGs9bmQtMTsgaz49MDsgay0tKSB7CisgICAgICAgICAgICBzdHJpZGVzW2tdID0gc2Q7CisgICAgICAgICAgICBzZCAqPSBzaGFwZVtrXTsKKyAgICAgICAgfQorICAgIH0KKyAgICByZXR1cm47Cit9CisKK2ludAorUHlCdWZmZXJfRmlsbEluZm8oUHlfYnVmZmVyICp2aWV3LCBQeU9iamVjdCAqb2JqLCB2b2lkICpidWYsIFB5X3NzaXplX3QgbGVuLAorICAgICAgICAgICAgICBpbnQgcmVhZG9ubHksIGludCBmbGFncykKK3sKKyAgICBpZiAodmlldyA9PSBOVUxMKSByZXR1cm4gMDsKKyAgICBpZiAoKChmbGFncyAmIFB5QlVGX1dSSVRBQkxFKSA9PSBQeUJVRl9XUklUQUJMRSkgJiYKKyAgICAgICAgKHJlYWRvbmx5ID09IDEpKSB7CisgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19CdWZmZXJFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICJPYmplY3QgaXMgbm90IHdyaXRhYmxlLiIpOworICAgICAgICByZXR1cm4gLTE7CisgICAgfQorCisgICAgdmlldy0+b2JqID0gb2JqOworICAgIGlmIChvYmopCisgICAgICAgIFB5X0lOQ1JFRihvYmopOworICAgIHZpZXctPmJ1ZiA9IGJ1ZjsKKyAgICB2aWV3LT5sZW4gPSBsZW47CisgICAgdmlldy0+cmVhZG9ubHkgPSByZWFkb25seTsKKyAgICB2aWV3LT5pdGVtc2l6ZSA9IDE7CisgICAgdmlldy0+Zm9ybWF0ID0gTlVMTDsKKyAgICBpZiAoKGZsYWdzICYgUHlCVUZfRk9STUFUKSA9PSBQeUJVRl9GT1JNQVQpCisgICAgICAgIHZpZXctPmZvcm1hdCA9ICJCIjsKKyAgICB2aWV3LT5uZGltID0gMTsKKyAgICB2aWV3LT5zaGFwZSA9IE5VTEw7CisgICAgaWYgKChmbGFncyAmIFB5QlVGX05EKSA9PSBQeUJVRl9ORCkKKyAgICAgICAgdmlldy0+c2hhcGUgPSAmKHZpZXctPmxlbik7CisgICAgdmlldy0+c3RyaWRlcyA9IE5VTEw7CisgICAgaWYgKChmbGFncyAmIFB5QlVGX1NUUklERVMpID09IFB5QlVGX1NUUklERVMpCisgICAgICAgIHZpZXctPnN0cmlkZXMgPSAmKHZpZXctPml0ZW1zaXplKTsKKyAgICB2aWV3LT5zdWJvZmZzZXRzID0gTlVMTDsKKyAgICB2aWV3LT5pbnRlcm5hbCA9IE5VTEw7CisgICAgcmV0dXJuIDA7Cit9CisKK3ZvaWQKK1B5QnVmZmVyX1JlbGVhc2UoUHlfYnVmZmVyICp2aWV3KQoreworICAgIFB5T2JqZWN0ICpvYmogPSB2aWV3LT5vYmo7CisgICAgaWYgKG9iaiAmJiBQeV9UWVBFKG9iaiktPnRwX2FzX2J1ZmZlciAmJiBQeV9UWVBFKG9iaiktPnRwX2FzX2J1ZmZlci0+YmZfcmVsZWFzZWJ1ZmZlcikKKyAgICAgICAgUHlfVFlQRShvYmopLT50cF9hc19idWZmZXItPmJmX3JlbGVhc2VidWZmZXIob2JqLCB2aWV3KTsKKyAgICBQeV9YREVDUkVGKG9iaik7CisgICAgdmlldy0+b2JqID0gTlVMTDsKK30KKworUHlPYmplY3QgKgorUHlPYmplY3RfRm9ybWF0KFB5T2JqZWN0KiBvYmosIFB5T2JqZWN0ICpmb3JtYXRfc3BlYykKK3sKKyAgICBQeU9iamVjdCAqZW1wdHkgPSBOVUxMOworICAgIFB5T2JqZWN0ICpyZXN1bHQgPSBOVUxMOworI2lmZGVmIFB5X1VTSU5HX1VOSUNPREUKKyAgICBpbnQgc3BlY19pc191bmljb2RlOworICAgIGludCByZXN1bHRfaXNfdW5pY29kZTsKKyNlbmRpZgorCisgICAgLyogSWYgbm8gZm9ybWF0X3NwZWMgaXMgcHJvdmlkZWQsIHVzZSBhbiBlbXB0eSBzdHJpbmcgKi8KKyAgICBpZiAoZm9ybWF0X3NwZWMgPT0gTlVMTCkgeworICAgICAgICBlbXB0eSA9IFB5U3RyaW5nX0Zyb21TdHJpbmdBbmRTaXplKE5VTEwsIDApOworICAgICAgICBmb3JtYXRfc3BlYyA9IGVtcHR5OworICAgIH0KKworICAgIC8qIENoZWNrIHRoZSBmb3JtYXRfc3BlYyB0eXBlLCBhbmQgbWFrZSBzdXJlIGl0J3Mgc3RyIG9yIHVuaWNvZGUgKi8KKyNpZmRlZiBQeV9VU0lOR19VTklDT0RFCisgICAgaWYgKFB5VW5pY29kZV9DaGVjayhmb3JtYXRfc3BlYykpCisgICAgICAgIHNwZWNfaXNfdW5pY29kZSA9IDE7CisgICAgZWxzZSBpZiAoUHlTdHJpbmdfQ2hlY2soZm9ybWF0X3NwZWMpKQorICAgICAgICBzcGVjX2lzX3VuaWNvZGUgPSAwOworICAgIGVsc2UgeworI2Vsc2UKKyAgICBpZiAoIVB5U3RyaW5nX0NoZWNrKGZvcm1hdF9zcGVjKSkgeworI2VuZGlmCisgICAgICAgIFB5RXJyX0Zvcm1hdChQeUV4Y19UeXBlRXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAiZm9ybWF0IGV4cGVjdHMgYXJnIDIgdG8gYmUgc3RyaW5nICIKKyAgICAgICAgICAgICAgICAgICAgICJvciB1bmljb2RlLCBub3QgJS4xMDBzIiwgUHlfVFlQRShmb3JtYXRfc3BlYyktPnRwX25hbWUpOworICAgICAgICBnb3RvIGRvbmU7CisgICAgfQorCisgICAgLyogQ2hlY2sgZm9yIGEgX19mb3JtYXRfXyBtZXRob2QgYW5kIGNhbGwgaXQuICovCisgICAgaWYgKFB5SW5zdGFuY2VfQ2hlY2sob2JqKSkgeworICAgICAgICAvKiBXZSdyZSBhbiBpbnN0YW5jZSBvZiBhIGNsYXNzaWMgY2xhc3MgKi8KKyAgICAgICAgUHlPYmplY3QgKmJvdW5kX21ldGhvZCA9IFB5T2JqZWN0X0dldEF0dHJTdHJpbmcob2JqLCAiX19mb3JtYXRfXyIpOworICAgICAgICBpZiAoYm91bmRfbWV0aG9kICE9IE5VTEwpIHsKKyAgICAgICAgICAgIHJlc3VsdCA9IFB5T2JqZWN0X0NhbGxGdW5jdGlvbk9iakFyZ3MoYm91bmRfbWV0aG9kLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3JtYXRfc3BlYywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCk7CisgICAgICAgICAgICBQeV9ERUNSRUYoYm91bmRfbWV0aG9kKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIFB5T2JqZWN0ICpzZWxmX2FzX3N0ciA9IE5VTEw7CisgICAgICAgICAgICBQeU9iamVjdCAqZm9ybWF0X21ldGhvZCA9IE5VTEw7CisgICAgICAgICAgICBQeV9zc2l6ZV90IGZvcm1hdF9sZW47CisKKyAgICAgICAgICAgIFB5RXJyX0NsZWFyKCk7CisgICAgICAgICAgICAvKiBQZXIgdGhlIFBFUCwgY29udmVydCB0byBzdHIgKG9yIHVuaWNvZGUsCisgICAgICAgICAgICAgICBkZXBlbmRpbmcgb24gdGhlIHR5cGUgb2YgdGhlIGZvcm1hdAorICAgICAgICAgICAgICAgc3BlY2lmaWVyKS4gIEZvciBuZXctc3R5bGUgY2xhc3NlcywgdGhpcworICAgICAgICAgICAgICAgbG9naWMgaXMgZG9uZSBieSBvYmplY3QuX19mb3JtYXRfXygpLiAqLworI2lmZGVmIFB5X1VTSU5HX1VOSUNPREUKKyAgICAgICAgICAgIGlmIChzcGVjX2lzX3VuaWNvZGUpIHsKKyAgICAgICAgICAgICAgICBmb3JtYXRfbGVuID0gUHlVbmljb2RlX0dFVF9TSVpFKGZvcm1hdF9zcGVjKTsKKyAgICAgICAgICAgICAgICBzZWxmX2FzX3N0ciA9IFB5T2JqZWN0X1VuaWNvZGUob2JqKTsKKyAgICAgICAgICAgIH0gZWxzZQorI2VuZGlmCisgICAgICAgICAgICB7CisgICAgICAgICAgICAgICAgZm9ybWF0X2xlbiA9IFB5U3RyaW5nX0dFVF9TSVpFKGZvcm1hdF9zcGVjKTsKKyAgICAgICAgICAgICAgICBzZWxmX2FzX3N0ciA9IFB5T2JqZWN0X1N0cihvYmopOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKHNlbGZfYXNfc3RyID09IE5VTEwpCisgICAgICAgICAgICAgICAgZ290byBkb25lMTsKKworICAgICAgICAgICAgaWYgKGZvcm1hdF9sZW4gPiAwKSB7CisgICAgICAgICAgICAgICAgLyogU2VlIHRoZSBhbG1vc3QgaWRlbnRpY2FsIGNvZGUgaW4KKyAgICAgICAgICAgICAgICAgICB0eXBlb2JqZWN0LmMgZm9yIG5ldy1zdHlsZQorICAgICAgICAgICAgICAgICAgIGNsYXNzZXMuICovCisgICAgICAgICAgICAgICAgaWYgKFB5RXJyX1dhcm5FeCgKKyAgICAgICAgICAgICAgICAgICAgUHlFeGNfUGVuZGluZ0RlcHJlY2F0aW9uV2FybmluZywKKyAgICAgICAgICAgICAgICAgICAgIm9iamVjdC5fX2Zvcm1hdF9fIHdpdGggYSBub24tZW1wdHkgIgorICAgICAgICAgICAgICAgICAgICAiZm9ybWF0IHN0cmluZyBpcyBkZXByZWNhdGVkIiwgMSkKKyAgICAgICAgICAgICAgICAgICAgIDwgMCkgeworICAgICAgICAgICAgICAgICAgICBnb3RvIGRvbmUxOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAvKiBFdmVudHVhbGx5IHRoaXMgd2lsbCBiZWNvbWUgYW4KKyAgICAgICAgICAgICAgICAgICBlcnJvcjoKKyAgICAgICAgICAgICAgICBQeUVycl9Gb3JtYXQoUHlFeGNfVHlwZUVycm9yLAorICAgICAgICAgICAgICAgICAgICJub24tZW1wdHkgZm9ybWF0IHN0cmluZyBwYXNzZWQgdG8gIgorICAgICAgICAgICAgICAgICAgICJvYmplY3QuX19mb3JtYXRfXyIpOworICAgICAgICAgICAgICAgIGdvdG8gZG9uZTE7CisgICAgICAgICAgICAgICAgKi8KKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgLyogVGhlbiBjYWxsIHN0ci5fX2Zvcm1hdF9fIG9uIHRoYXQgcmVzdWx0ICovCisgICAgICAgICAgICBmb3JtYXRfbWV0aG9kID0gUHlPYmplY3RfR2V0QXR0clN0cmluZyhzZWxmX2FzX3N0ciwgIl9fZm9ybWF0X18iKTsKKyAgICAgICAgICAgIGlmIChmb3JtYXRfbWV0aG9kID09IE5VTEwpIHsKKyAgICAgICAgICAgICAgICBnb3RvIGRvbmUxOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmVzdWx0ID0gUHlPYmplY3RfQ2FsbEZ1bmN0aW9uT2JqQXJncyhmb3JtYXRfbWV0aG9kLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3JtYXRfc3BlYywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCk7Citkb25lMToKKyAgICAgICAgICAgIFB5X1hERUNSRUYoc2VsZl9hc19zdHIpOworICAgICAgICAgICAgUHlfWERFQ1JFRihmb3JtYXRfbWV0aG9kKTsKKyAgICAgICAgICAgIGlmIChyZXN1bHQgPT0gTlVMTCkKKyAgICAgICAgICAgICAgICBnb3RvIGRvbmU7CisgICAgICAgIH0KKyAgICB9IGVsc2UgeworICAgICAgICAvKiBOb3QgYW4gaW5zdGFuY2Ugb2YgYSBjbGFzc2ljIGNsYXNzLCB1c2UgdGhlIGNvZGUKKyAgICAgICAgICAgZnJvbSBweTNrICovCisgICAgICAgIHN0YXRpYyBQeU9iamVjdCAqZm9ybWF0X2NhY2hlID0gTlVMTDsKKworICAgICAgICAvKiBGaW5kIHRoZSAodW5ib3VuZCEpIF9fZm9ybWF0X18gbWV0aG9kIChhIGJvcnJvd2VkCisgICAgICAgICAgIHJlZmVyZW5jZSkgKi8KKyAgICAgICAgUHlPYmplY3QgKm1ldGhvZCA9IF9QeU9iamVjdF9Mb29rdXBTcGVjaWFsKG9iaiwgIl9fZm9ybWF0X18iLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJmZvcm1hdF9jYWNoZSk7CisgICAgICAgIGlmIChtZXRob2QgPT0gTlVMTCkgeworICAgICAgICAgICAgaWYgKCFQeUVycl9PY2N1cnJlZCgpKQorICAgICAgICAgICAgICAgIFB5RXJyX0Zvcm1hdChQeUV4Y19UeXBlRXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJUeXBlICUuMTAwcyBkb2Vzbid0IGRlZmluZSBfX2Zvcm1hdF9fIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHlfVFlQRShvYmopLT50cF9uYW1lKTsKKyAgICAgICAgICAgIGdvdG8gZG9uZTsKKyAgICAgICAgfQorICAgICAgICAvKiBBbmQgY2FsbCBpdC4gKi8KKyAgICAgICAgcmVzdWx0ID0gUHlPYmplY3RfQ2FsbEZ1bmN0aW9uT2JqQXJncyhtZXRob2QsIGZvcm1hdF9zcGVjLCBOVUxMKTsKKyAgICAgICAgUHlfREVDUkVGKG1ldGhvZCk7CisgICAgfQorCisgICAgaWYgKHJlc3VsdCA9PSBOVUxMKQorICAgICAgICBnb3RvIGRvbmU7CisKKyAgICAvKiBDaGVjayB0aGUgcmVzdWx0IHR5cGUsIGFuZCBtYWtlIHN1cmUgaXQncyBzdHIgb3IgdW5pY29kZSAqLworI2lmZGVmIFB5X1VTSU5HX1VOSUNPREUKKyAgICBpZiAoUHlVbmljb2RlX0NoZWNrKHJlc3VsdCkpCisgICAgICAgIHJlc3VsdF9pc191bmljb2RlID0gMTsKKyAgICBlbHNlIGlmIChQeVN0cmluZ19DaGVjayhyZXN1bHQpKQorICAgICAgICByZXN1bHRfaXNfdW5pY29kZSA9IDA7CisgICAgZWxzZSB7CisjZWxzZQorICAgIGlmICghUHlTdHJpbmdfQ2hlY2socmVzdWx0KSkgeworI2VuZGlmCisgICAgICAgIFB5RXJyX0Zvcm1hdChQeUV4Y19UeXBlRXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAiJS4xMDBzLl9fZm9ybWF0X18gbXVzdCByZXR1cm4gc3RyaW5nIG9yICIKKyAgICAgICAgICAgICAgICAgICAgICJ1bmljb2RlLCBub3QgJS4xMDBzIiwgUHlfVFlQRShvYmopLT50cF9uYW1lLAorICAgICAgICAgICAgICAgICAgICAgUHlfVFlQRShyZXN1bHQpLT50cF9uYW1lKTsKKyAgICAgICAgUHlfREVDUkVGKHJlc3VsdCk7CisgICAgICAgIHJlc3VsdCA9IE5VTEw7CisgICAgICAgIGdvdG8gZG9uZTsKKyAgICB9CisKKyAgICAvKiBDb252ZXJ0IHRvIHVuaWNvZGUsIGlmIG5lZWRlZC4gIFJlcXVpcmVkIGlmIHNwZWMgaXMgdW5pY29kZQorICAgICAgIGFuZCByZXN1bHQgaXMgc3RyICovCisjaWZkZWYgUHlfVVNJTkdfVU5JQ09ERQorICAgIGlmIChzcGVjX2lzX3VuaWNvZGUgJiYgIXJlc3VsdF9pc191bmljb2RlKSB7CisgICAgICAgIFB5T2JqZWN0ICp0bXAgPSBQeU9iamVjdF9Vbmljb2RlKHJlc3VsdCk7CisgICAgICAgIC8qIFRoaXMgbG9naWMgd29ya3Mgd2hldGhlciBvciBub3QgdG1wIGlzIE5VTEwgKi8KKyAgICAgICAgUHlfREVDUkVGKHJlc3VsdCk7CisgICAgICAgIHJlc3VsdCA9IHRtcDsKKyAgICB9CisjZW5kaWYKKworZG9uZToKKyAgICBQeV9YREVDUkVGKGVtcHR5KTsKKyAgICByZXR1cm4gcmVzdWx0OworfQorCisvKiBPcGVyYXRpb25zIG9uIG51bWJlcnMgKi8KKworaW50CitQeU51bWJlcl9DaGVjayhQeU9iamVjdCAqbykKK3sKKyAgICByZXR1cm4gbyAmJiBvLT5vYl90eXBlLT50cF9hc19udW1iZXIgJiYKKyAgICAgICAgICAgKG8tPm9iX3R5cGUtPnRwX2FzX251bWJlci0+bmJfaW50IHx8CisgICAgICAgIG8tPm9iX3R5cGUtPnRwX2FzX251bWJlci0+bmJfZmxvYXQpOworfQorCisvKiBCaW5hcnkgb3BlcmF0b3JzICovCisKKy8qIE5ldyBzdHlsZSBudW1iZXIgcHJvdG9jb2wgc3VwcG9ydCAqLworCisjZGVmaW5lIE5CX1NMT1QoeCkgb2Zmc2V0b2YoUHlOdW1iZXJNZXRob2RzLCB4KQorI2RlZmluZSBOQl9CSU5PUChuYl9tZXRob2RzLCBzbG90KSBcCisgICAgICAgICgqKGJpbmFyeWZ1bmMqKSgmICgoY2hhciopbmJfbWV0aG9kcylbc2xvdF0pKQorI2RlZmluZSBOQl9URVJOT1AobmJfbWV0aG9kcywgc2xvdCkgXAorICAgICAgICAoKih0ZXJuYXJ5ZnVuYyopKCYgKChjaGFyKiluYl9tZXRob2RzKVtzbG90XSkpCisKKy8qCisgIENhbGxpbmcgc2NoZW1lIHVzZWQgZm9yIGJpbmFyeSBvcGVyYXRpb25zOgorCisgIHYgICAgIHcgICAgICAgQWN0aW9uCisgIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgbmV3ICAgbmV3ICAgICB3Lm9wKHYsdylbKl0sIHYub3Aodix3KSwgdy5vcCh2LHcpCisgIG5ldyAgIG9sZCAgICAgdi5vcCh2LHcpLCBjb2VyY2Uodix3KSwgdi5vcCh2LHcpCisgIG9sZCAgIG5ldyAgICAgdy5vcCh2LHcpLCBjb2VyY2Uodix3KSwgdi5vcCh2LHcpCisgIG9sZCAgIG9sZCAgICAgY29lcmNlKHYsdyksIHYub3Aodix3KQorCisgIFsqXSBvbmx5IHdoZW4gdi0+b2JfdHlwZSAhPSB3LT5vYl90eXBlICYmIHctPm9iX3R5cGUgaXMgYSBzdWJjbGFzcyBvZgorICAgICAgdi0+b2JfdHlwZQorCisgIExlZ2VuZDoKKyAgLS0tLS0tLQorICAqIG5ldyA9PSBuZXcgc3R5bGUgbnVtYmVyCisgICogb2xkID09IG9sZCBzdHlsZSBudW1iZXIKKyAgKiBBY3Rpb24gaW5kaWNhdGVzIHRoZSBvcmRlciBpbiB3aGljaCBvcGVyYXRpb25zIGFyZSB0cmllZCB1bnRpbCBlaXRoZXIKKyAgICBhIHZhbGlkIHJlc3VsdCBpcyBwcm9kdWNlZCBvciBhbiBlcnJvciBvY2N1cnMuCisKKyAqLworCitzdGF0aWMgUHlPYmplY3QgKgorYmluYXJ5X29wMShQeU9iamVjdCAqdiwgUHlPYmplY3QgKncsIGNvbnN0IGludCBvcF9zbG90KQoreworICAgIFB5T2JqZWN0ICp4OworICAgIGJpbmFyeWZ1bmMgc2xvdHYgPSBOVUxMOworICAgIGJpbmFyeWZ1bmMgc2xvdHcgPSBOVUxMOworCisgICAgaWYgKHYtPm9iX3R5cGUtPnRwX2FzX251bWJlciAhPSBOVUxMICYmIE5FV19TVFlMRV9OVU1CRVIodikpCisgICAgICAgIHNsb3R2ID0gTkJfQklOT1Aodi0+b2JfdHlwZS0+dHBfYXNfbnVtYmVyLCBvcF9zbG90KTsKKyAgICBpZiAody0+b2JfdHlwZSAhPSB2LT5vYl90eXBlICYmCisgICAgICAgIHctPm9iX3R5cGUtPnRwX2FzX251bWJlciAhPSBOVUxMICYmIE5FV19TVFlMRV9OVU1CRVIodykpIHsKKyAgICAgICAgc2xvdHcgPSBOQl9CSU5PUCh3LT5vYl90eXBlLT50cF9hc19udW1iZXIsIG9wX3Nsb3QpOworICAgICAgICBpZiAoc2xvdHcgPT0gc2xvdHYpCisgICAgICAgICAgICBzbG90dyA9IE5VTEw7CisgICAgfQorICAgIGlmIChzbG90dikgeworICAgICAgICBpZiAoc2xvdHcgJiYgUHlUeXBlX0lzU3VidHlwZSh3LT5vYl90eXBlLCB2LT5vYl90eXBlKSkgeworICAgICAgICAgICAgeCA9IHNsb3R3KHYsIHcpOworICAgICAgICAgICAgaWYgKHggIT0gUHlfTm90SW1wbGVtZW50ZWQpCisgICAgICAgICAgICAgICAgcmV0dXJuIHg7CisgICAgICAgICAgICBQeV9ERUNSRUYoeCk7IC8qIGNhbid0IGRvIGl0ICovCisgICAgICAgICAgICBzbG90dyA9IE5VTEw7CisgICAgICAgIH0KKyAgICAgICAgeCA9IHNsb3R2KHYsIHcpOworICAgICAgICBpZiAoeCAhPSBQeV9Ob3RJbXBsZW1lbnRlZCkKKyAgICAgICAgICAgIHJldHVybiB4OworICAgICAgICBQeV9ERUNSRUYoeCk7IC8qIGNhbid0IGRvIGl0ICovCisgICAgfQorICAgIGlmIChzbG90dykgeworICAgICAgICB4ID0gc2xvdHcodiwgdyk7CisgICAgICAgIGlmICh4ICE9IFB5X05vdEltcGxlbWVudGVkKQorICAgICAgICAgICAgcmV0dXJuIHg7CisgICAgICAgIFB5X0RFQ1JFRih4KTsgLyogY2FuJ3QgZG8gaXQgKi8KKyAgICB9CisgICAgaWYgKCFORVdfU1RZTEVfTlVNQkVSKHYpIHx8ICFORVdfU1RZTEVfTlVNQkVSKHcpKSB7CisgICAgICAgIGludCBlcnIgPSBQeU51bWJlcl9Db2VyY2VFeCgmdiwgJncpOworICAgICAgICBpZiAoZXJyIDwgMCkgeworICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGVyciA9PSAwKSB7CisgICAgICAgICAgICBQeU51bWJlck1ldGhvZHMgKm12ID0gdi0+b2JfdHlwZS0+dHBfYXNfbnVtYmVyOworICAgICAgICAgICAgaWYgKG12KSB7CisgICAgICAgICAgICAgICAgYmluYXJ5ZnVuYyBzbG90OworICAgICAgICAgICAgICAgIHNsb3QgPSBOQl9CSU5PUChtdiwgb3Bfc2xvdCk7CisgICAgICAgICAgICAgICAgaWYgKHNsb3QpIHsKKyAgICAgICAgICAgICAgICAgICAgeCA9IHNsb3Qodiwgdyk7CisgICAgICAgICAgICAgICAgICAgIFB5X0RFQ1JFRih2KTsKKyAgICAgICAgICAgICAgICAgICAgUHlfREVDUkVGKHcpOworICAgICAgICAgICAgICAgICAgICByZXR1cm4geDsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICAvKiBDb2VyY2VFeCBpbmNyZW1lbnRlZCB0aGUgcmVmZXJlbmNlIGNvdW50cyAqLworICAgICAgICAgICAgUHlfREVDUkVGKHYpOworICAgICAgICAgICAgUHlfREVDUkVGKHcpOworICAgICAgICB9CisgICAgfQorICAgIFB5X0lOQ1JFRihQeV9Ob3RJbXBsZW1lbnRlZCk7CisgICAgcmV0dXJuIFB5X05vdEltcGxlbWVudGVkOworfQorCitzdGF0aWMgUHlPYmplY3QgKgorYmlub3BfdHlwZV9lcnJvcihQeU9iamVjdCAqdiwgUHlPYmplY3QgKncsIGNvbnN0IGNoYXIgKm9wX25hbWUpCit7CisgICAgUHlFcnJfRm9ybWF0KFB5RXhjX1R5cGVFcnJvciwKKyAgICAgICAgICAgICAgICAgInVuc3VwcG9ydGVkIG9wZXJhbmQgdHlwZShzKSBmb3IgJS4xMDBzOiAiCisgICAgICAgICAgICAgICAgICInJS4xMDBzJyBhbmQgJyUuMTAwcyciLAorICAgICAgICAgICAgICAgICBvcF9uYW1lLAorICAgICAgICAgICAgICAgICB2LT5vYl90eXBlLT50cF9uYW1lLAorICAgICAgICAgICAgICAgICB3LT5vYl90eXBlLT50cF9uYW1lKTsKKyAgICByZXR1cm4gTlVMTDsKK30KKworc3RhdGljIFB5T2JqZWN0ICoKK2JpbmFyeV9vcChQeU9iamVjdCAqdiwgUHlPYmplY3QgKncsIGNvbnN0IGludCBvcF9zbG90LCBjb25zdCBjaGFyICpvcF9uYW1lKQoreworICAgIFB5T2JqZWN0ICpyZXN1bHQgPSBiaW5hcnlfb3AxKHYsIHcsIG9wX3Nsb3QpOworICAgIGlmIChyZXN1bHQgPT0gUHlfTm90SW1wbGVtZW50ZWQpIHsKKyAgICAgICAgUHlfREVDUkVGKHJlc3VsdCk7CisgICAgICAgIHJldHVybiBiaW5vcF90eXBlX2Vycm9yKHYsIHcsIG9wX25hbWUpOworICAgIH0KKyAgICByZXR1cm4gcmVzdWx0OworfQorCisKKy8qCisgIENhbGxpbmcgc2NoZW1lIHVzZWQgZm9yIHRlcm5hcnkgb3BlcmF0aW9uczoKKworICAqKiogSW4gc29tZSBjYXNlcywgdy5vcCBpcyBjYWxsZWQgYmVmb3JlIHYub3A7IHNlZSBiaW5hcnlfb3AxLiAqKioKKworICB2ICAgICB3ICAgICAgIHogICAgICAgQWN0aW9uCisgIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAgbmV3ICAgbmV3ICAgICBuZXcgICAgIHYub3Aodix3LHopLCB3Lm9wKHYsdyx6KSwgei5vcCh2LHcseikKKyAgbmV3ICAgb2xkICAgICBuZXcgICAgIHYub3Aodix3LHopLCB6Lm9wKHYsdyx6KSwgY29lcmNlKHYsdyx6KSwgdi5vcCh2LHcseikKKyAgb2xkICAgbmV3ICAgICBuZXcgICAgIHcub3Aodix3LHopLCB6Lm9wKHYsdyx6KSwgY29lcmNlKHYsdyx6KSwgdi5vcCh2LHcseikKKyAgb2xkICAgb2xkICAgICBuZXcgICAgIHoub3Aodix3LHopLCBjb2VyY2Uodix3LHopLCB2Lm9wKHYsdyx6KQorICBuZXcgICBuZXcgICAgIG9sZCAgICAgdi5vcCh2LHcseiksIHcub3Aodix3LHopLCBjb2VyY2Uodix3LHopLCB2Lm9wKHYsdyx6KQorICBuZXcgICBvbGQgICAgIG9sZCAgICAgdi5vcCh2LHcseiksIGNvZXJjZSh2LHcseiksIHYub3Aodix3LHopCisgIG9sZCAgIG5ldyAgICAgb2xkICAgICB3Lm9wKHYsdyx6KSwgY29lcmNlKHYsdyx6KSwgdi5vcCh2LHcseikKKyAgb2xkICAgb2xkICAgICBvbGQgICAgIGNvZXJjZSh2LHcseiksIHYub3Aodix3LHopCisKKyAgTGVnZW5kOgorICAtLS0tLS0tCisgICogbmV3ID09IG5ldyBzdHlsZSBudW1iZXIKKyAgKiBvbGQgPT0gb2xkIHN0eWxlIG51bWJlcgorICAqIEFjdGlvbiBpbmRpY2F0ZXMgdGhlIG9yZGVyIGluIHdoaWNoIG9wZXJhdGlvbnMgYXJlIHRyaWVkIHVudGlsIGVpdGhlcgorICAgIGEgdmFsaWQgcmVzdWx0IGlzIHByb2R1Y2VkIG9yIGFuIGVycm9yIG9jY3Vycy4KKyAgKiBjb2VyY2Uodix3LHopIGFjdHVhbGx5IGRvZXM6IGNvZXJjZSh2LHcpLCBjb2VyY2Uodix6KSwgY29lcmNlKHcseikgYW5kCisgICAgb25seSBpZiB6ICE9IFB5X05vbmU7IGlmIHogPT0gUHlfTm9uZSwgdGhlbiBpdCBpcyB0cmVhdGVkIGFzIGFic2VudAorICAgIHZhcmlhYmxlIGFuZCBvbmx5IGNvZXJjZSh2LHcpIGlzIHRyaWVkLgorCisgKi8KKworc3RhdGljIFB5T2JqZWN0ICoKK3Rlcm5hcnlfb3AoUHlPYmplY3QgKnYsCisgICAgICAgICAgIFB5T2JqZWN0ICp3LAorICAgICAgICAgICBQeU9iamVjdCAqeiwKKyAgICAgICAgICAgY29uc3QgaW50IG9wX3Nsb3QsCisgICAgICAgICAgIGNvbnN0IGNoYXIgKm9wX25hbWUpCit7CisgICAgUHlOdW1iZXJNZXRob2RzICptdiwgKm13LCAqbXo7CisgICAgUHlPYmplY3QgKnggPSBOVUxMOworICAgIHRlcm5hcnlmdW5jIHNsb3R2ID0gTlVMTDsKKyAgICB0ZXJuYXJ5ZnVuYyBzbG90dyA9IE5VTEw7CisgICAgdGVybmFyeWZ1bmMgc2xvdHogPSBOVUxMOworCisgICAgbXYgPSB2LT5vYl90eXBlLT50cF9hc19udW1iZXI7CisgICAgbXcgPSB3LT5vYl90eXBlLT50cF9hc19udW1iZXI7CisgICAgaWYgKG12ICE9IE5VTEwgJiYgTkVXX1NUWUxFX05VTUJFUih2KSkKKyAgICAgICAgc2xvdHYgPSBOQl9URVJOT1AobXYsIG9wX3Nsb3QpOworICAgIGlmICh3LT5vYl90eXBlICE9IHYtPm9iX3R5cGUgJiYKKyAgICAgICAgbXcgIT0gTlVMTCAmJiBORVdfU1RZTEVfTlVNQkVSKHcpKSB7CisgICAgICAgIHNsb3R3ID0gTkJfVEVSTk9QKG13LCBvcF9zbG90KTsKKyAgICAgICAgaWYgKHNsb3R3ID09IHNsb3R2KQorICAgICAgICAgICAgc2xvdHcgPSBOVUxMOworICAgIH0KKyAgICBpZiAoc2xvdHYpIHsKKyAgICAgICAgaWYgKHNsb3R3ICYmIFB5VHlwZV9Jc1N1YnR5cGUody0+b2JfdHlwZSwgdi0+b2JfdHlwZSkpIHsKKyAgICAgICAgICAgIHggPSBzbG90dyh2LCB3LCB6KTsKKyAgICAgICAgICAgIGlmICh4ICE9IFB5X05vdEltcGxlbWVudGVkKQorICAgICAgICAgICAgICAgIHJldHVybiB4OworICAgICAgICAgICAgUHlfREVDUkVGKHgpOyAvKiBjYW4ndCBkbyBpdCAqLworICAgICAgICAgICAgc2xvdHcgPSBOVUxMOworICAgICAgICB9CisgICAgICAgIHggPSBzbG90dih2LCB3LCB6KTsKKyAgICAgICAgaWYgKHggIT0gUHlfTm90SW1wbGVtZW50ZWQpCisgICAgICAgICAgICByZXR1cm4geDsKKyAgICAgICAgUHlfREVDUkVGKHgpOyAvKiBjYW4ndCBkbyBpdCAqLworICAgIH0KKyAgICBpZiAoc2xvdHcpIHsKKyAgICAgICAgeCA9IHNsb3R3KHYsIHcsIHopOworICAgICAgICBpZiAoeCAhPSBQeV9Ob3RJbXBsZW1lbnRlZCkKKyAgICAgICAgICAgIHJldHVybiB4OworICAgICAgICBQeV9ERUNSRUYoeCk7IC8qIGNhbid0IGRvIGl0ICovCisgICAgfQorICAgIG16ID0gei0+b2JfdHlwZS0+dHBfYXNfbnVtYmVyOworICAgIGlmIChteiAhPSBOVUxMICYmIE5FV19TVFlMRV9OVU1CRVIoeikpIHsKKyAgICAgICAgc2xvdHogPSBOQl9URVJOT1AobXosIG9wX3Nsb3QpOworICAgICAgICBpZiAoc2xvdHogPT0gc2xvdHYgfHwgc2xvdHogPT0gc2xvdHcpCisgICAgICAgICAgICBzbG90eiA9IE5VTEw7CisgICAgICAgIGlmIChzbG90eikgeworICAgICAgICAgICAgeCA9IHNsb3R6KHYsIHcsIHopOworICAgICAgICAgICAgaWYgKHggIT0gUHlfTm90SW1wbGVtZW50ZWQpCisgICAgICAgICAgICAgICAgcmV0dXJuIHg7CisgICAgICAgICAgICBQeV9ERUNSRUYoeCk7IC8qIGNhbid0IGRvIGl0ICovCisgICAgICAgIH0KKyAgICB9CisKKyAgICBpZiAoIU5FV19TVFlMRV9OVU1CRVIodikgfHwgIU5FV19TVFlMRV9OVU1CRVIodykgfHwKKyAgICAgICAgICAgICAgICAgICAgKHogIT0gUHlfTm9uZSAmJiAhTkVXX1NUWUxFX05VTUJFUih6KSkpIHsKKyAgICAgICAgLyogd2UgaGF2ZSBhbiBvbGQgc3R5bGUgb3BlcmFuZCwgY29lcmNlICovCisgICAgICAgIFB5T2JqZWN0ICp2MSwgKnoxLCAqdzIsICp6MjsKKyAgICAgICAgaW50IGM7CisKKyAgICAgICAgYyA9IFB5TnVtYmVyX0NvZXJjZSgmdiwgJncpOworICAgICAgICBpZiAoYyAhPSAwKQorICAgICAgICAgICAgZ290byBlcnJvcjM7CisKKyAgICAgICAgLyogU3BlY2lhbCBjYXNlOiBpZiB0aGUgdGhpcmQgYXJndW1lbnQgaXMgTm9uZSwgaXQgaXMKKyAgICAgICAgICAgdHJlYXRlZCBhcyBhYnNlbnQgYXJndW1lbnQgYW5kIG5vdCBjb2VyY2VkLiAqLworICAgICAgICBpZiAoeiA9PSBQeV9Ob25lKSB7CisgICAgICAgICAgICBpZiAodi0+b2JfdHlwZS0+dHBfYXNfbnVtYmVyKSB7CisgICAgICAgICAgICAgICAgc2xvdHogPSBOQl9URVJOT1Aodi0+b2JfdHlwZS0+dHBfYXNfbnVtYmVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9wX3Nsb3QpOworICAgICAgICAgICAgICAgIGlmIChzbG90eikKKyAgICAgICAgICAgICAgICAgICAgeCA9IHNsb3R6KHYsIHcsIHopOworICAgICAgICAgICAgICAgIGVsc2UKKyAgICAgICAgICAgICAgICAgICAgYyA9IC0xOworICAgICAgICAgICAgfQorICAgICAgICAgICAgZWxzZQorICAgICAgICAgICAgICAgIGMgPSAtMTsKKyAgICAgICAgICAgIGdvdG8gZXJyb3IyOworICAgICAgICB9CisgICAgICAgIHYxID0gdjsKKyAgICAgICAgejEgPSB6OworICAgICAgICBjID0gUHlOdW1iZXJfQ29lcmNlKCZ2MSwgJnoxKTsKKyAgICAgICAgaWYgKGMgIT0gMCkKKyAgICAgICAgICAgIGdvdG8gZXJyb3IyOworICAgICAgICB3MiA9IHc7CisgICAgICAgIHoyID0gejE7CisgICAgICAgIGMgPSBQeU51bWJlcl9Db2VyY2UoJncyLCAmejIpOworICAgICAgICBpZiAoYyAhPSAwKQorICAgICAgICAgICAgZ290byBlcnJvcjE7CisKKyAgICAgICAgaWYgKHYxLT5vYl90eXBlLT50cF9hc19udW1iZXIgIT0gTlVMTCkgeworICAgICAgICAgICAgc2xvdHYgPSBOQl9URVJOT1AodjEtPm9iX3R5cGUtPnRwX2FzX251bWJlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9wX3Nsb3QpOworICAgICAgICAgICAgaWYgKHNsb3R2KQorICAgICAgICAgICAgICAgIHggPSBzbG90dih2MSwgdzIsIHoyKTsKKyAgICAgICAgICAgIGVsc2UKKyAgICAgICAgICAgICAgICBjID0gLTE7CisgICAgICAgIH0KKyAgICAgICAgZWxzZQorICAgICAgICAgICAgYyA9IC0xOworCisgICAgICAgIFB5X0RFQ1JFRih3Mik7CisgICAgICAgIFB5X0RFQ1JFRih6Mik7CisgICAgZXJyb3IxOgorICAgICAgICBQeV9ERUNSRUYodjEpOworICAgICAgICBQeV9ERUNSRUYoejEpOworICAgIGVycm9yMjoKKyAgICAgICAgUHlfREVDUkVGKHYpOworICAgICAgICBQeV9ERUNSRUYodyk7CisgICAgZXJyb3IzOgorICAgICAgICBpZiAoYyA+PSAwKQorICAgICAgICAgICAgcmV0dXJuIHg7CisgICAgfQorCisgICAgaWYgKHogPT0gUHlfTm9uZSkKKyAgICAgICAgUHlFcnJfRm9ybWF0KAorICAgICAgICAgICAgUHlFeGNfVHlwZUVycm9yLAorICAgICAgICAgICAgInVuc3VwcG9ydGVkIG9wZXJhbmQgdHlwZShzKSBmb3IgKiogb3IgcG93KCk6ICIKKyAgICAgICAgICAgICInJS4xMDBzJyBhbmQgJyUuMTAwcyciLAorICAgICAgICAgICAgdi0+b2JfdHlwZS0+dHBfbmFtZSwKKyAgICAgICAgICAgIHctPm9iX3R5cGUtPnRwX25hbWUpOworICAgIGVsc2UKKyAgICAgICAgUHlFcnJfRm9ybWF0KAorICAgICAgICAgICAgUHlFeGNfVHlwZUVycm9yLAorICAgICAgICAgICAgInVuc3VwcG9ydGVkIG9wZXJhbmQgdHlwZShzKSBmb3IgcG93KCk6ICIKKyAgICAgICAgICAgICInJS4xMDBzJywgJyUuMTAwcycsICclLjEwMHMnIiwKKyAgICAgICAgICAgIHYtPm9iX3R5cGUtPnRwX25hbWUsCisgICAgICAgICAgICB3LT5vYl90eXBlLT50cF9uYW1lLAorICAgICAgICAgICAgei0+b2JfdHlwZS0+dHBfbmFtZSk7CisgICAgcmV0dXJuIE5VTEw7Cit9CisKKyNkZWZpbmUgQklOQVJZX0ZVTkMoZnVuYywgb3AsIG9wX25hbWUpIFwKKyAgICBQeU9iamVjdCAqIFwKKyAgICBmdW5jKFB5T2JqZWN0ICp2LCBQeU9iamVjdCAqdykgeyBcCisgICAgICAgIHJldHVybiBiaW5hcnlfb3AodiwgdywgTkJfU0xPVChvcCksIG9wX25hbWUpOyBcCisgICAgfQorCitCSU5BUllfRlVOQyhQeU51bWJlcl9PciwgbmJfb3IsICJ8IikKK0JJTkFSWV9GVU5DKFB5TnVtYmVyX1hvciwgbmJfeG9yLCAiXiIpCitCSU5BUllfRlVOQyhQeU51bWJlcl9BbmQsIG5iX2FuZCwgIiYiKQorQklOQVJZX0ZVTkMoUHlOdW1iZXJfTHNoaWZ0LCBuYl9sc2hpZnQsICI8PCIpCitCSU5BUllfRlVOQyhQeU51bWJlcl9Sc2hpZnQsIG5iX3JzaGlmdCwgIj4+IikKK0JJTkFSWV9GVU5DKFB5TnVtYmVyX1N1YnRyYWN0LCBuYl9zdWJ0cmFjdCwgIi0iKQorQklOQVJZX0ZVTkMoUHlOdW1iZXJfRGl2aWRlLCBuYl9kaXZpZGUsICIvIikKK0JJTkFSWV9GVU5DKFB5TnVtYmVyX0Rpdm1vZCwgbmJfZGl2bW9kLCAiZGl2bW9kKCkiKQorCitQeU9iamVjdCAqCitQeU51bWJlcl9BZGQoUHlPYmplY3QgKnYsIFB5T2JqZWN0ICp3KQoreworICAgIFB5T2JqZWN0ICpyZXN1bHQgPSBiaW5hcnlfb3AxKHYsIHcsIE5CX1NMT1QobmJfYWRkKSk7CisgICAgaWYgKHJlc3VsdCA9PSBQeV9Ob3RJbXBsZW1lbnRlZCkgeworICAgICAgICBQeVNlcXVlbmNlTWV0aG9kcyAqbSA9IHYtPm9iX3R5cGUtPnRwX2FzX3NlcXVlbmNlOworICAgICAgICBQeV9ERUNSRUYocmVzdWx0KTsKKyAgICAgICAgaWYgKG0gJiYgbS0+c3FfY29uY2F0KSB7CisgICAgICAgICAgICByZXR1cm4gKCptLT5zcV9jb25jYXQpKHYsIHcpOworICAgICAgICB9CisgICAgICAgIHJlc3VsdCA9IGJpbm9wX3R5cGVfZXJyb3IodiwgdywgIisiKTsKKyAgICB9CisgICAgcmV0dXJuIHJlc3VsdDsKK30KKworc3RhdGljIFB5T2JqZWN0ICoKK3NlcXVlbmNlX3JlcGVhdChzc2l6ZWFyZ2Z1bmMgcmVwZWF0ZnVuYywgUHlPYmplY3QgKnNlcSwgUHlPYmplY3QgKm4pCit7CisgICAgUHlfc3NpemVfdCBjb3VudDsKKyAgICBpZiAoUHlJbmRleF9DaGVjayhuKSkgeworICAgICAgICBjb3VudCA9IFB5TnVtYmVyX0FzU3NpemVfdChuLCBQeUV4Y19PdmVyZmxvd0Vycm9yKTsKKyAgICAgICAgaWYgKGNvdW50ID09IC0xICYmIFB5RXJyX09jY3VycmVkKCkpCisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgZWxzZSB7CisgICAgICAgIHJldHVybiB0eXBlX2Vycm9yKCJjYW4ndCBtdWx0aXBseSBzZXF1ZW5jZSBieSAiCisgICAgICAgICAgICAgICAgICAgICAgICAgICJub24taW50IG9mIHR5cGUgJyUuMjAwcyciLCBuKTsKKyAgICB9CisgICAgcmV0dXJuICgqcmVwZWF0ZnVuYykoc2VxLCBjb3VudCk7Cit9CisKK1B5T2JqZWN0ICoKK1B5TnVtYmVyX011bHRpcGx5KFB5T2JqZWN0ICp2LCBQeU9iamVjdCAqdykKK3sKKyAgICBQeU9iamVjdCAqcmVzdWx0ID0gYmluYXJ5X29wMSh2LCB3LCBOQl9TTE9UKG5iX211bHRpcGx5KSk7CisgICAgaWYgKHJlc3VsdCA9PSBQeV9Ob3RJbXBsZW1lbnRlZCkgeworICAgICAgICBQeVNlcXVlbmNlTWV0aG9kcyAqbXYgPSB2LT5vYl90eXBlLT50cF9hc19zZXF1ZW5jZTsKKyAgICAgICAgUHlTZXF1ZW5jZU1ldGhvZHMgKm13ID0gdy0+b2JfdHlwZS0+dHBfYXNfc2VxdWVuY2U7CisgICAgICAgIFB5X0RFQ1JFRihyZXN1bHQpOworICAgICAgICBpZiAgKG12ICYmIG12LT5zcV9yZXBlYXQpIHsKKyAgICAgICAgICAgIHJldHVybiBzZXF1ZW5jZV9yZXBlYXQobXYtPnNxX3JlcGVhdCwgdiwgdyk7CisgICAgICAgIH0KKyAgICAgICAgZWxzZSBpZiAobXcgJiYgbXctPnNxX3JlcGVhdCkgeworICAgICAgICAgICAgcmV0dXJuIHNlcXVlbmNlX3JlcGVhdChtdy0+c3FfcmVwZWF0LCB3LCB2KTsKKyAgICAgICAgfQorICAgICAgICByZXN1bHQgPSBiaW5vcF90eXBlX2Vycm9yKHYsIHcsICIqIik7CisgICAgfQorICAgIHJldHVybiByZXN1bHQ7Cit9CisKK1B5T2JqZWN0ICoKK1B5TnVtYmVyX0Zsb29yRGl2aWRlKFB5T2JqZWN0ICp2LCBQeU9iamVjdCAqdykKK3sKKyAgICAvKiBYWFggdHBfZmxhZ3MgdGVzdCAqLworICAgIHJldHVybiBiaW5hcnlfb3AodiwgdywgTkJfU0xPVChuYl9mbG9vcl9kaXZpZGUpLCAiLy8iKTsKK30KKworUHlPYmplY3QgKgorUHlOdW1iZXJfVHJ1ZURpdmlkZShQeU9iamVjdCAqdiwgUHlPYmplY3QgKncpCit7CisgICAgLyogWFhYIHRwX2ZsYWdzIHRlc3QgKi8KKyAgICByZXR1cm4gYmluYXJ5X29wKHYsIHcsIE5CX1NMT1QobmJfdHJ1ZV9kaXZpZGUpLCAiLyIpOworfQorCitQeU9iamVjdCAqCitQeU51bWJlcl9SZW1haW5kZXIoUHlPYmplY3QgKnYsIFB5T2JqZWN0ICp3KQoreworICAgIHJldHVybiBiaW5hcnlfb3AodiwgdywgTkJfU0xPVChuYl9yZW1haW5kZXIpLCAiJSIpOworfQorCitQeU9iamVjdCAqCitQeU51bWJlcl9Qb3dlcihQeU9iamVjdCAqdiwgUHlPYmplY3QgKncsIFB5T2JqZWN0ICp6KQoreworICAgIHJldHVybiB0ZXJuYXJ5X29wKHYsIHcsIHosIE5CX1NMT1QobmJfcG93ZXIpLCAiKiogb3IgcG93KCkiKTsKK30KKworLyogQmluYXJ5IGluLXBsYWNlIG9wZXJhdG9ycyAqLworCisvKiBUaGUgaW4tcGxhY2Ugb3BlcmF0b3JzIGFyZSBkZWZpbmVkIHRvIGZhbGwgYmFjayB0byB0aGUgJ25vcm1hbCcsCisgICBub24gaW4tcGxhY2Ugb3BlcmF0aW9ucywgaWYgdGhlIGluLXBsYWNlIG1ldGhvZHMgYXJlIG5vdCBpbiBwbGFjZS4KKworICAgLSBJZiB0aGUgbGVmdCBoYW5kIG9iamVjdCBoYXMgdGhlIGFwcHJvcHJpYXRlIHN0cnVjdCBtZW1iZXJzLCBhbmQKKyAgICAgdGhleSBhcmUgZmlsbGVkLCBjYWxsIHRoZSBhcHByb3ByaWF0ZSBmdW5jdGlvbiBhbmQgcmV0dXJuIHRoZQorICAgICByZXN1bHQuICBObyBjb2VyY2lvbiBpcyBkb25lIG9uIHRoZSBhcmd1bWVudHM7IHRoZSBsZWZ0LWhhbmQgb2JqZWN0CisgICAgIGlzIHRoZSBvbmUgdGhlIG9wZXJhdGlvbiBpcyBwZXJmb3JtZWQgb24sIGFuZCBpdCdzIHVwIHRvIHRoZQorICAgICBmdW5jdGlvbiB0byBkZWFsIHdpdGggdGhlIHJpZ2h0LWhhbmQgb2JqZWN0LgorCisgICAtIE90aGVyd2lzZSwgaW4tcGxhY2UgbW9kaWZpY2F0aW9uIGlzIG5vdCBzdXBwb3J0ZWQuIEhhbmRsZSBpdCBleGFjdGx5IGFzCisgICAgIGEgbm9uIGluLXBsYWNlIG9wZXJhdGlvbiBvZiB0aGUgc2FtZSBraW5kLgorCisgICAqLworCisjZGVmaW5lIEhBU0lOUExBQ0UodCkgXAorICAgIFB5VHlwZV9IYXNGZWF0dXJlKCh0KS0+b2JfdHlwZSwgUHlfVFBGTEFHU19IQVZFX0lOUExBQ0VPUFMpCisKK3N0YXRpYyBQeU9iamVjdCAqCitiaW5hcnlfaW9wMShQeU9iamVjdCAqdiwgUHlPYmplY3QgKncsIGNvbnN0IGludCBpb3Bfc2xvdCwgY29uc3QgaW50IG9wX3Nsb3QpCit7CisgICAgUHlOdW1iZXJNZXRob2RzICptdiA9IHYtPm9iX3R5cGUtPnRwX2FzX251bWJlcjsKKyAgICBpZiAobXYgIT0gTlVMTCAmJiBIQVNJTlBMQUNFKHYpKSB7CisgICAgICAgIGJpbmFyeWZ1bmMgc2xvdCA9IE5CX0JJTk9QKG12LCBpb3Bfc2xvdCk7CisgICAgICAgIGlmIChzbG90KSB7CisgICAgICAgICAgICBQeU9iamVjdCAqeCA9IChzbG90KSh2LCB3KTsKKyAgICAgICAgICAgIGlmICh4ICE9IFB5X05vdEltcGxlbWVudGVkKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIHg7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBQeV9ERUNSRUYoeCk7CisgICAgICAgIH0KKyAgICB9CisgICAgcmV0dXJuIGJpbmFyeV9vcDEodiwgdywgb3Bfc2xvdCk7Cit9CisKK3N0YXRpYyBQeU9iamVjdCAqCitiaW5hcnlfaW9wKFB5T2JqZWN0ICp2LCBQeU9iamVjdCAqdywgY29uc3QgaW50IGlvcF9zbG90LCBjb25zdCBpbnQgb3Bfc2xvdCwKKyAgICAgICAgICAgICAgICBjb25zdCBjaGFyICpvcF9uYW1lKQoreworICAgIFB5T2JqZWN0ICpyZXN1bHQgPSBiaW5hcnlfaW9wMSh2LCB3LCBpb3Bfc2xvdCwgb3Bfc2xvdCk7CisgICAgaWYgKHJlc3VsdCA9PSBQeV9Ob3RJbXBsZW1lbnRlZCkgeworICAgICAgICBQeV9ERUNSRUYocmVzdWx0KTsKKyAgICAgICAgcmV0dXJuIGJpbm9wX3R5cGVfZXJyb3Iodiwgdywgb3BfbmFtZSk7CisgICAgfQorICAgIHJldHVybiByZXN1bHQ7Cit9CisKKyNkZWZpbmUgSU5QTEFDRV9CSU5PUChmdW5jLCBpb3AsIG9wLCBvcF9uYW1lKSBcCisgICAgUHlPYmplY3QgKiBcCisgICAgZnVuYyhQeU9iamVjdCAqdiwgUHlPYmplY3QgKncpIHsgXAorICAgICAgICByZXR1cm4gYmluYXJ5X2lvcCh2LCB3LCBOQl9TTE9UKGlvcCksIE5CX1NMT1Qob3ApLCBvcF9uYW1lKTsgXAorICAgIH0KKworSU5QTEFDRV9CSU5PUChQeU51bWJlcl9JblBsYWNlT3IsIG5iX2lucGxhY2Vfb3IsIG5iX29yLCAifD0iKQorSU5QTEFDRV9CSU5PUChQeU51bWJlcl9JblBsYWNlWG9yLCBuYl9pbnBsYWNlX3hvciwgbmJfeG9yLCAiXj0iKQorSU5QTEFDRV9CSU5PUChQeU51bWJlcl9JblBsYWNlQW5kLCBuYl9pbnBsYWNlX2FuZCwgbmJfYW5kLCAiJj0iKQorSU5QTEFDRV9CSU5PUChQeU51bWJlcl9JblBsYWNlTHNoaWZ0LCBuYl9pbnBsYWNlX2xzaGlmdCwgbmJfbHNoaWZ0LCAiPDw9IikKK0lOUExBQ0VfQklOT1AoUHlOdW1iZXJfSW5QbGFjZVJzaGlmdCwgbmJfaW5wbGFjZV9yc2hpZnQsIG5iX3JzaGlmdCwgIj4+PSIpCitJTlBMQUNFX0JJTk9QKFB5TnVtYmVyX0luUGxhY2VTdWJ0cmFjdCwgbmJfaW5wbGFjZV9zdWJ0cmFjdCwgbmJfc3VidHJhY3QsICItPSIpCitJTlBMQUNFX0JJTk9QKFB5TnVtYmVyX0luUGxhY2VEaXZpZGUsIG5iX2lucGxhY2VfZGl2aWRlLCBuYl9kaXZpZGUsICIvPSIpCisKK1B5T2JqZWN0ICoKK1B5TnVtYmVyX0luUGxhY2VGbG9vckRpdmlkZShQeU9iamVjdCAqdiwgUHlPYmplY3QgKncpCit7CisgICAgLyogWFhYIHRwX2ZsYWdzIHRlc3QgKi8KKyAgICByZXR1cm4gYmluYXJ5X2lvcCh2LCB3LCBOQl9TTE9UKG5iX2lucGxhY2VfZmxvb3JfZGl2aWRlKSwKKyAgICAgICAgICAgICAgICAgICAgICBOQl9TTE9UKG5iX2Zsb29yX2RpdmlkZSksICIvLz0iKTsKK30KKworUHlPYmplY3QgKgorUHlOdW1iZXJfSW5QbGFjZVRydWVEaXZpZGUoUHlPYmplY3QgKnYsIFB5T2JqZWN0ICp3KQoreworICAgIC8qIFhYWCB0cF9mbGFncyB0ZXN0ICovCisgICAgcmV0dXJuIGJpbmFyeV9pb3AodiwgdywgTkJfU0xPVChuYl9pbnBsYWNlX3RydWVfZGl2aWRlKSwKKyAgICAgICAgICAgICAgICAgICAgICBOQl9TTE9UKG5iX3RydWVfZGl2aWRlKSwgIi89Iik7Cit9CisKK1B5T2JqZWN0ICoKK1B5TnVtYmVyX0luUGxhY2VBZGQoUHlPYmplY3QgKnYsIFB5T2JqZWN0ICp3KQoreworICAgIFB5T2JqZWN0ICpyZXN1bHQgPSBiaW5hcnlfaW9wMSh2LCB3LCBOQl9TTE9UKG5iX2lucGxhY2VfYWRkKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTkJfU0xPVChuYl9hZGQpKTsKKyAgICBpZiAocmVzdWx0ID09IFB5X05vdEltcGxlbWVudGVkKSB7CisgICAgICAgIFB5U2VxdWVuY2VNZXRob2RzICptID0gdi0+b2JfdHlwZS0+dHBfYXNfc2VxdWVuY2U7CisgICAgICAgIFB5X0RFQ1JFRihyZXN1bHQpOworICAgICAgICBpZiAobSAhPSBOVUxMKSB7CisgICAgICAgICAgICBiaW5hcnlmdW5jIGYgPSBOVUxMOworICAgICAgICAgICAgaWYgKEhBU0lOUExBQ0UodikpCisgICAgICAgICAgICAgICAgZiA9IG0tPnNxX2lucGxhY2VfY29uY2F0OworICAgICAgICAgICAgaWYgKGYgPT0gTlVMTCkKKyAgICAgICAgICAgICAgICBmID0gbS0+c3FfY29uY2F0OworICAgICAgICAgICAgaWYgKGYgIT0gTlVMTCkKKyAgICAgICAgICAgICAgICByZXR1cm4gKCpmKSh2LCB3KTsKKyAgICAgICAgfQorICAgICAgICByZXN1bHQgPSBiaW5vcF90eXBlX2Vycm9yKHYsIHcsICIrPSIpOworICAgIH0KKyAgICByZXR1cm4gcmVzdWx0OworfQorCitQeU9iamVjdCAqCitQeU51bWJlcl9JblBsYWNlTXVsdGlwbHkoUHlPYmplY3QgKnYsIFB5T2JqZWN0ICp3KQoreworICAgIFB5T2JqZWN0ICpyZXN1bHQgPSBiaW5hcnlfaW9wMSh2LCB3LCBOQl9TTE9UKG5iX2lucGxhY2VfbXVsdGlwbHkpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOQl9TTE9UKG5iX211bHRpcGx5KSk7CisgICAgaWYgKHJlc3VsdCA9PSBQeV9Ob3RJbXBsZW1lbnRlZCkgeworICAgICAgICBzc2l6ZWFyZ2Z1bmMgZiA9IE5VTEw7CisgICAgICAgIFB5U2VxdWVuY2VNZXRob2RzICptdiA9IHYtPm9iX3R5cGUtPnRwX2FzX3NlcXVlbmNlOworICAgICAgICBQeVNlcXVlbmNlTWV0aG9kcyAqbXcgPSB3LT5vYl90eXBlLT50cF9hc19zZXF1ZW5jZTsKKyAgICAgICAgUHlfREVDUkVGKHJlc3VsdCk7CisgICAgICAgIGlmIChtdiAhPSBOVUxMKSB7CisgICAgICAgICAgICBpZiAoSEFTSU5QTEFDRSh2KSkKKyAgICAgICAgICAgICAgICBmID0gbXYtPnNxX2lucGxhY2VfcmVwZWF0OworICAgICAgICAgICAgaWYgKGYgPT0gTlVMTCkKKyAgICAgICAgICAgICAgICBmID0gbXYtPnNxX3JlcGVhdDsKKyAgICAgICAgICAgIGlmIChmICE9IE5VTEwpCisgICAgICAgICAgICAgICAgcmV0dXJuIHNlcXVlbmNlX3JlcGVhdChmLCB2LCB3KTsKKyAgICAgICAgfQorICAgICAgICBlbHNlIGlmIChtdyAhPSBOVUxMKSB7CisgICAgICAgICAgICAvKiBOb3RlIHRoYXQgdGhlIHJpZ2h0IGhhbmQgb3BlcmFuZCBzaG91bGQgbm90IGJlCisgICAgICAgICAgICAgKiBtdXRhdGVkIGluIHRoaXMgY2FzZSBzbyBzcV9pbnBsYWNlX3JlcGVhdCBpcyBub3QKKyAgICAgICAgICAgICAqIHVzZWQuICovCisgICAgICAgICAgICBpZiAobXctPnNxX3JlcGVhdCkKKyAgICAgICAgICAgICAgICByZXR1cm4gc2VxdWVuY2VfcmVwZWF0KG13LT5zcV9yZXBlYXQsIHcsIHYpOworICAgICAgICB9CisgICAgICAgIHJlc3VsdCA9IGJpbm9wX3R5cGVfZXJyb3IodiwgdywgIio9Iik7CisgICAgfQorICAgIHJldHVybiByZXN1bHQ7Cit9CisKK1B5T2JqZWN0ICoKK1B5TnVtYmVyX0luUGxhY2VSZW1haW5kZXIoUHlPYmplY3QgKnYsIFB5T2JqZWN0ICp3KQoreworICAgIHJldHVybiBiaW5hcnlfaW9wKHYsIHcsIE5CX1NMT1QobmJfaW5wbGFjZV9yZW1haW5kZXIpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5CX1NMT1QobmJfcmVtYWluZGVyKSwgIiU9Iik7Cit9CisKK1B5T2JqZWN0ICoKK1B5TnVtYmVyX0luUGxhY2VQb3dlcihQeU9iamVjdCAqdiwgUHlPYmplY3QgKncsIFB5T2JqZWN0ICp6KQoreworICAgIGlmIChIQVNJTlBMQUNFKHYpICYmIHYtPm9iX3R5cGUtPnRwX2FzX251bWJlciAmJgorICAgICAgICB2LT5vYl90eXBlLT50cF9hc19udW1iZXItPm5iX2lucGxhY2VfcG93ZXIgIT0gTlVMTCkgeworICAgICAgICByZXR1cm4gdGVybmFyeV9vcCh2LCB3LCB6LCBOQl9TTE9UKG5iX2lucGxhY2VfcG93ZXIpLCAiKio9Iik7CisgICAgfQorICAgIGVsc2UgeworICAgICAgICByZXR1cm4gdGVybmFyeV9vcCh2LCB3LCB6LCBOQl9TTE9UKG5iX3Bvd2VyKSwgIioqPSIpOworICAgIH0KK30KKworCisvKiBVbmFyeSBvcGVyYXRvcnMgYW5kIGZ1bmN0aW9ucyAqLworCitQeU9iamVjdCAqCitQeU51bWJlcl9OZWdhdGl2ZShQeU9iamVjdCAqbykKK3sKKyAgICBQeU51bWJlck1ldGhvZHMgKm07CisKKyAgICBpZiAobyA9PSBOVUxMKQorICAgICAgICByZXR1cm4gbnVsbF9lcnJvcigpOworICAgIG0gPSBvLT5vYl90eXBlLT50cF9hc19udW1iZXI7CisgICAgaWYgKG0gJiYgbS0+bmJfbmVnYXRpdmUpCisgICAgICAgIHJldHVybiAoKm0tPm5iX25lZ2F0aXZlKShvKTsKKworICAgIHJldHVybiB0eXBlX2Vycm9yKCJiYWQgb3BlcmFuZCB0eXBlIGZvciB1bmFyeSAtOiAnJS4yMDBzJyIsIG8pOworfQorCitQeU9iamVjdCAqCitQeU51bWJlcl9Qb3NpdGl2ZShQeU9iamVjdCAqbykKK3sKKyAgICBQeU51bWJlck1ldGhvZHMgKm07CisKKyAgICBpZiAobyA9PSBOVUxMKQorICAgICAgICByZXR1cm4gbnVsbF9lcnJvcigpOworICAgIG0gPSBvLT5vYl90eXBlLT50cF9hc19udW1iZXI7CisgICAgaWYgKG0gJiYgbS0+bmJfcG9zaXRpdmUpCisgICAgICAgIHJldHVybiAoKm0tPm5iX3Bvc2l0aXZlKShvKTsKKworICAgIHJldHVybiB0eXBlX2Vycm9yKCJiYWQgb3BlcmFuZCB0eXBlIGZvciB1bmFyeSArOiAnJS4yMDBzJyIsIG8pOworfQorCitQeU9iamVjdCAqCitQeU51bWJlcl9JbnZlcnQoUHlPYmplY3QgKm8pCit7CisgICAgUHlOdW1iZXJNZXRob2RzICptOworCisgICAgaWYgKG8gPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIG51bGxfZXJyb3IoKTsKKyAgICBtID0gby0+b2JfdHlwZS0+dHBfYXNfbnVtYmVyOworICAgIGlmIChtICYmIG0tPm5iX2ludmVydCkKKyAgICAgICAgcmV0dXJuICgqbS0+bmJfaW52ZXJ0KShvKTsKKworICAgIHJldHVybiB0eXBlX2Vycm9yKCJiYWQgb3BlcmFuZCB0eXBlIGZvciB1bmFyeSB+OiAnJS4yMDBzJyIsIG8pOworfQorCitQeU9iamVjdCAqCitQeU51bWJlcl9BYnNvbHV0ZShQeU9iamVjdCAqbykKK3sKKyAgICBQeU51bWJlck1ldGhvZHMgKm07CisKKyAgICBpZiAobyA9PSBOVUxMKQorICAgICAgICByZXR1cm4gbnVsbF9lcnJvcigpOworICAgIG0gPSBvLT5vYl90eXBlLT50cF9hc19udW1iZXI7CisgICAgaWYgKG0gJiYgbS0+bmJfYWJzb2x1dGUpCisgICAgICAgIHJldHVybiBtLT5uYl9hYnNvbHV0ZShvKTsKKworICAgIHJldHVybiB0eXBlX2Vycm9yKCJiYWQgb3BlcmFuZCB0eXBlIGZvciBhYnMoKTogJyUuMjAwcyciLCBvKTsKK30KKworLyogQWRkIGEgY2hlY2sgZm9yIGVtYmVkZGVkIE5VTEwtYnl0ZXMgaW4gdGhlIGFyZ3VtZW50LiAqLworc3RhdGljIFB5T2JqZWN0ICoKK2ludF9mcm9tX3N0cmluZyhjb25zdCBjaGFyICpzLCBQeV9zc2l6ZV90IGxlbikKK3sKKyAgICBjaGFyICplbmQ7CisgICAgUHlPYmplY3QgKng7CisKKyAgICB4ID0gUHlJbnRfRnJvbVN0cmluZygoY2hhciopcywgJmVuZCwgMTApOworICAgIGlmICh4ID09IE5VTEwpCisgICAgICAgIHJldHVybiBOVUxMOworICAgIGlmIChlbmQgIT0gcyArIGxlbikgeworICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfVmFsdWVFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICJudWxsIGJ5dGUgaW4gYXJndW1lbnQgZm9yIGludCgpIik7CisgICAgICAgIFB5X0RFQ1JFRih4KTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIHJldHVybiB4OworfQorCisvKiBSZXR1cm4gYSBQeXRob24gSW50IG9yIExvbmcgZnJvbSB0aGUgb2JqZWN0IGl0ZW0KKyAgIFJhaXNlIFR5cGVFcnJvciBpZiB0aGUgcmVzdWx0IGlzIG5vdCBhbiBpbnQtb3ItbG9uZworICAgb3IgaWYgdGhlIG9iamVjdCBjYW5ub3QgYmUgaW50ZXJwcmV0ZWQgYXMgYW4gaW5kZXguCisqLworUHlPYmplY3QgKgorUHlOdW1iZXJfSW5kZXgoUHlPYmplY3QgKml0ZW0pCit7CisgICAgUHlPYmplY3QgKnJlc3VsdCA9IE5VTEw7CisgICAgaWYgKGl0ZW0gPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIG51bGxfZXJyb3IoKTsKKyAgICBpZiAoUHlJbnRfQ2hlY2soaXRlbSkgfHwgUHlMb25nX0NoZWNrKGl0ZW0pKSB7CisgICAgICAgIFB5X0lOQ1JFRihpdGVtKTsKKyAgICAgICAgcmV0dXJuIGl0ZW07CisgICAgfQorICAgIGlmIChQeUluZGV4X0NoZWNrKGl0ZW0pKSB7CisgICAgICAgIHJlc3VsdCA9IGl0ZW0tPm9iX3R5cGUtPnRwX2FzX251bWJlci0+bmJfaW5kZXgoaXRlbSk7CisgICAgICAgIGlmIChyZXN1bHQgJiYKKyAgICAgICAgICAgICFQeUludF9DaGVjayhyZXN1bHQpICYmICFQeUxvbmdfQ2hlY2socmVzdWx0KSkgeworICAgICAgICAgICAgUHlFcnJfRm9ybWF0KFB5RXhjX1R5cGVFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAiX19pbmRleF9fIHJldHVybmVkIG5vbi0oaW50LGxvbmcpICIgXAorICAgICAgICAgICAgICAgICAgICAgICAgICIodHlwZSAlLjIwMHMpIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICByZXN1bHQtPm9iX3R5cGUtPnRwX25hbWUpOworICAgICAgICAgICAgUHlfREVDUkVGKHJlc3VsdCk7CisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgfQorICAgIH0KKyAgICBlbHNlIHsKKyAgICAgICAgUHlFcnJfRm9ybWF0KFB5RXhjX1R5cGVFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICInJS4yMDBzJyBvYmplY3QgY2Fubm90IGJlIGludGVycHJldGVkICIKKyAgICAgICAgICAgICAgICAgICAgICJhcyBhbiBpbmRleCIsIGl0ZW0tPm9iX3R5cGUtPnRwX25hbWUpOworICAgIH0KKyAgICByZXR1cm4gcmVzdWx0OworfQorCisvKiBSZXR1cm4gYW4gZXJyb3Igb24gT3ZlcmZsb3cgb25seSBpZiBlcnIgaXMgbm90IE5VTEwqLworCitQeV9zc2l6ZV90CitQeU51bWJlcl9Bc1NzaXplX3QoUHlPYmplY3QgKml0ZW0sIFB5T2JqZWN0ICplcnIpCit7CisgICAgUHlfc3NpemVfdCByZXN1bHQ7CisgICAgUHlPYmplY3QgKnJ1bmVycjsKKyAgICBQeU9iamVjdCAqdmFsdWUgPSBQeU51bWJlcl9JbmRleChpdGVtKTsKKyAgICBpZiAodmFsdWUgPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIC0xOworCisgICAgLyogV2UncmUgZG9uZSBpZiBQeUludF9Bc1NzaXplX3QoKSByZXR1cm5zIHdpdGhvdXQgZXJyb3IuICovCisgICAgcmVzdWx0ID0gUHlJbnRfQXNTc2l6ZV90KHZhbHVlKTsKKyAgICBpZiAocmVzdWx0ICE9IC0xIHx8ICEocnVuZXJyID0gUHlFcnJfT2NjdXJyZWQoKSkpCisgICAgICAgIGdvdG8gZmluaXNoOworCisgICAgLyogRXJyb3IgaGFuZGxpbmcgY29kZSAtLSBvbmx5IG1hbmFnZSBPdmVyZmxvd0Vycm9yIGRpZmZlcmVudGx5ICovCisgICAgaWYgKCFQeUVycl9HaXZlbkV4Y2VwdGlvbk1hdGNoZXMocnVuZXJyLCBQeUV4Y19PdmVyZmxvd0Vycm9yKSkKKyAgICAgICAgZ290byBmaW5pc2g7CisKKyAgICBQeUVycl9DbGVhcigpOworICAgIC8qIElmIG5vIGVycm9yLWhhbmRsaW5nIGRlc2lyZWQgdGhlbiB0aGUgZGVmYXVsdCBjbGlwcGluZworICAgICAgIGlzIHN1ZmZpY2llbnQuCisgICAgICovCisgICAgaWYgKCFlcnIpIHsKKyAgICAgICAgYXNzZXJ0KFB5TG9uZ19DaGVjayh2YWx1ZSkpOworICAgICAgICAvKiBXaGV0aGVyIG9yIG5vdCBpdCBpcyBsZXNzIHRoYW4gb3IgZXF1YWwgdG8KKyAgICAgICAgICAgemVybyBpcyBkZXRlcm1pbmVkIGJ5IHRoZSBzaWduIG9mIG9iX3NpemUKKyAgICAgICAgKi8KKyAgICAgICAgaWYgKF9QeUxvbmdfU2lnbih2YWx1ZSkgPCAwKQorICAgICAgICAgICAgcmVzdWx0ID0gUFlfU1NJWkVfVF9NSU47CisgICAgICAgIGVsc2UKKyAgICAgICAgICAgIHJlc3VsdCA9IFBZX1NTSVpFX1RfTUFYOworICAgIH0KKyAgICBlbHNlIHsKKyAgICAgICAgLyogT3RoZXJ3aXNlIHJlcGxhY2UgdGhlIGVycm9yIHdpdGggY2FsbGVyJ3MgZXJyb3Igb2JqZWN0LiAqLworICAgICAgICBQeUVycl9Gb3JtYXQoZXJyLAorICAgICAgICAgICAgICAgICAgICAgImNhbm5vdCBmaXQgJyUuMjAwcycgaW50byBhbiBpbmRleC1zaXplZCBpbnRlZ2VyIiwKKyAgICAgICAgICAgICAgICAgICAgIGl0ZW0tPm9iX3R5cGUtPnRwX25hbWUpOworICAgIH0KKworIGZpbmlzaDoKKyAgICBQeV9ERUNSRUYodmFsdWUpOworICAgIHJldHVybiByZXN1bHQ7Cit9CisKKworUHlPYmplY3QgKgorX1B5TnVtYmVyX0NvbnZlcnRJbnRlZ3JhbFRvSW50KFB5T2JqZWN0ICppbnRlZ3JhbCwgY29uc3QgY2hhciogZXJyb3JfZm9ybWF0KQoreworICAgIGNvbnN0IGNoYXIgKnR5cGVfbmFtZTsKKyAgICBzdGF0aWMgUHlPYmplY3QgKmludF9uYW1lID0gTlVMTDsKKyAgICBpZiAoaW50X25hbWUgPT0gTlVMTCkgeworICAgICAgICBpbnRfbmFtZSA9IFB5U3RyaW5nX0ludGVybkZyb21TdHJpbmcoIl9faW50X18iKTsKKyAgICAgICAgaWYgKGludF9uYW1lID09IE5VTEwpCisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisKKyAgICBpZiAoaW50ZWdyYWwgJiYgKCFQeUludF9DaGVjayhpbnRlZ3JhbCkgJiYKKyAgICAgICAgICAgICAgICAgICAgICFQeUxvbmdfQ2hlY2soaW50ZWdyYWwpKSkgeworICAgICAgICAvKiBEb24ndCBnbyB0aHJvdWdoIHRwX2FzX251bWJlci0+bmJfaW50IHRvIGF2b2lkCisgICAgICAgICAgIGhpdHRpbmcgdGhlIGNsYXNzaWMgY2xhc3MgZmFsbGJhY2sgdG8gX190cnVuY19fLiAqLworICAgICAgICBQeU9iamVjdCAqaW50X2Z1bmMgPSBQeU9iamVjdF9HZXRBdHRyKGludGVncmFsLCBpbnRfbmFtZSk7CisgICAgICAgIGlmIChpbnRfZnVuYyA9PSBOVUxMKSB7CisgICAgICAgICAgICBQeUVycl9DbGVhcigpOyAvKiBSYWlzZSBhIGRpZmZlcmVudCBlcnJvci4gKi8KKyAgICAgICAgICAgIGdvdG8gbm9uX2ludGVncmFsX2Vycm9yOworICAgICAgICB9CisgICAgICAgIFB5X0RFQ1JFRihpbnRlZ3JhbCk7CisgICAgICAgIGludGVncmFsID0gUHlFdmFsX0NhbGxPYmplY3QoaW50X2Z1bmMsIE5VTEwpOworICAgICAgICBQeV9ERUNSRUYoaW50X2Z1bmMpOworICAgICAgICBpZiAoaW50ZWdyYWwgJiYgKCFQeUludF9DaGVjayhpbnRlZ3JhbCkgJiYKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIVB5TG9uZ19DaGVjayhpbnRlZ3JhbCkpKSB7CisgICAgICAgICAgICBnb3RvIG5vbl9pbnRlZ3JhbF9lcnJvcjsKKyAgICAgICAgfQorICAgIH0KKyAgICByZXR1cm4gaW50ZWdyYWw7CisKK25vbl9pbnRlZ3JhbF9lcnJvcjoKKyAgICBpZiAoUHlJbnN0YW5jZV9DaGVjayhpbnRlZ3JhbCkpIHsKKyAgICAgICAgdHlwZV9uYW1lID0gUHlTdHJpbmdfQVNfU1RSSU5HKCgoUHlJbnN0YW5jZU9iamVjdCAqKWludGVncmFsKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLT5pbl9jbGFzcy0+Y2xfbmFtZSk7CisgICAgfQorICAgIGVsc2UgeworICAgICAgICB0eXBlX25hbWUgPSBpbnRlZ3JhbC0+b2JfdHlwZS0+dHBfbmFtZTsKKyAgICB9CisgICAgUHlFcnJfRm9ybWF0KFB5RXhjX1R5cGVFcnJvciwgZXJyb3JfZm9ybWF0LCB0eXBlX25hbWUpOworICAgIFB5X0RFQ1JFRihpbnRlZ3JhbCk7CisgICAgcmV0dXJuIE5VTEw7Cit9CisKKworUHlPYmplY3QgKgorUHlOdW1iZXJfSW50KFB5T2JqZWN0ICpvKQoreworICAgIFB5TnVtYmVyTWV0aG9kcyAqbTsKKyAgICBzdGF0aWMgUHlPYmplY3QgKnRydW5jX25hbWUgPSBOVUxMOworICAgIFB5T2JqZWN0ICp0cnVuY19mdW5jOworICAgIGNvbnN0IGNoYXIgKmJ1ZmZlcjsKKyAgICBQeV9zc2l6ZV90IGJ1ZmZlcl9sZW47CisKKyAgICBpZiAodHJ1bmNfbmFtZSA9PSBOVUxMKSB7CisgICAgICAgIHRydW5jX25hbWUgPSBQeVN0cmluZ19JbnRlcm5Gcm9tU3RyaW5nKCJfX3RydW5jX18iKTsKKyAgICAgICAgaWYgKHRydW5jX25hbWUgPT0gTlVMTCkKKyAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKworICAgIGlmIChvID09IE5VTEwpCisgICAgICAgIHJldHVybiBudWxsX2Vycm9yKCk7CisgICAgaWYgKFB5SW50X0NoZWNrRXhhY3QobykpIHsKKyAgICAgICAgUHlfSU5DUkVGKG8pOworICAgICAgICByZXR1cm4gbzsKKyAgICB9CisgICAgbSA9IG8tPm9iX3R5cGUtPnRwX2FzX251bWJlcjsKKyAgICBpZiAobSAmJiBtLT5uYl9pbnQpIHsgLyogVGhpcyBzaG91bGQgaW5jbHVkZSBzdWJjbGFzc2VzIG9mIGludCAqLworICAgICAgICAvKiBDbGFzc2ljIGNsYXNzZXMgYWx3YXlzIHRha2UgdGhpcyBicmFuY2guICovCisgICAgICAgIFB5T2JqZWN0ICpyZXMgPSBtLT5uYl9pbnQobyk7CisgICAgICAgIGlmIChyZXMgJiYgKCFQeUludF9DaGVjayhyZXMpICYmICFQeUxvbmdfQ2hlY2socmVzKSkpIHsKKyAgICAgICAgICAgIFB5RXJyX0Zvcm1hdChQeUV4Y19UeXBlRXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgIl9faW50X18gcmV0dXJuZWQgbm9uLWludCAodHlwZSAlLjIwMHMpIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICByZXMtPm9iX3R5cGUtPnRwX25hbWUpOworICAgICAgICAgICAgUHlfREVDUkVGKHJlcyk7CisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gcmVzOworICAgIH0KKyAgICBpZiAoUHlJbnRfQ2hlY2sobykpIHsgLyogQSBpbnQgc3ViY2xhc3Mgd2l0aG91dCBuYl9pbnQgKi8KKyAgICAgICAgUHlJbnRPYmplY3QgKmlvID0gKFB5SW50T2JqZWN0KilvOworICAgICAgICByZXR1cm4gUHlJbnRfRnJvbUxvbmcoaW8tPm9iX2l2YWwpOworICAgIH0KKyAgICB0cnVuY19mdW5jID0gUHlPYmplY3RfR2V0QXR0cihvLCB0cnVuY19uYW1lKTsKKyAgICBpZiAodHJ1bmNfZnVuYykgeworICAgICAgICBQeU9iamVjdCAqdHJ1bmNhdGVkID0gUHlFdmFsX0NhbGxPYmplY3QodHJ1bmNfZnVuYywgTlVMTCk7CisgICAgICAgIFB5X0RFQ1JFRih0cnVuY19mdW5jKTsKKyAgICAgICAgLyogX190cnVuY19fIGlzIHNwZWNpZmllZCB0byByZXR1cm4gYW4gSW50ZWdyYWwgdHlwZSwgYnV0CisgICAgICAgICAgIGludCgpIG5lZWRzIHRvIHJldHVybiBhbiBpbnQuICovCisgICAgICAgIHJldHVybiBfUHlOdW1iZXJfQ29udmVydEludGVncmFsVG9JbnQoCisgICAgICAgICAgICB0cnVuY2F0ZWQsCisgICAgICAgICAgICAiX190cnVuY19fIHJldHVybmVkIG5vbi1JbnRlZ3JhbCAodHlwZSAlLjIwMHMpIik7CisgICAgfQorICAgIFB5RXJyX0NsZWFyKCk7ICAvKiBJdCdzIG5vdCBhbiBlcnJvciBpZiAgby5fX3RydW5jX18gZG9lc24ndCBleGlzdC4gKi8KKworICAgIGlmIChQeVN0cmluZ19DaGVjayhvKSkKKyAgICAgICAgcmV0dXJuIGludF9mcm9tX3N0cmluZyhQeVN0cmluZ19BU19TVFJJTkcobyksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHlTdHJpbmdfR0VUX1NJWkUobykpOworI2lmZGVmIFB5X1VTSU5HX1VOSUNPREUKKyAgICBpZiAoUHlVbmljb2RlX0NoZWNrKG8pKQorICAgICAgICByZXR1cm4gUHlJbnRfRnJvbVVuaWNvZGUoUHlVbmljb2RlX0FTX1VOSUNPREUobyksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQeVVuaWNvZGVfR0VUX1NJWkUobyksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAxMCk7CisjZW5kaWYKKyAgICBpZiAoIVB5T2JqZWN0X0FzQ2hhckJ1ZmZlcihvLCAmYnVmZmVyLCAmYnVmZmVyX2xlbikpCisgICAgICAgIHJldHVybiBpbnRfZnJvbV9zdHJpbmcoKGNoYXIqKWJ1ZmZlciwgYnVmZmVyX2xlbik7CisKKyAgICByZXR1cm4gdHlwZV9lcnJvcigiaW50KCkgYXJndW1lbnQgbXVzdCBiZSBhIHN0cmluZyBvciBhICIKKyAgICAgICAgICAgICAgICAgICAgICAibnVtYmVyLCBub3QgJyUuMjAwcyciLCBvKTsKK30KKworLyogQWRkIGEgY2hlY2sgZm9yIGVtYmVkZGVkIE5VTEwtYnl0ZXMgaW4gdGhlIGFyZ3VtZW50LiAqLworc3RhdGljIFB5T2JqZWN0ICoKK2xvbmdfZnJvbV9zdHJpbmcoY29uc3QgY2hhciAqcywgUHlfc3NpemVfdCBsZW4pCit7CisgICAgY2hhciAqZW5kOworICAgIFB5T2JqZWN0ICp4OworCisgICAgeCA9IFB5TG9uZ19Gcm9tU3RyaW5nKChjaGFyKilzLCAmZW5kLCAxMCk7CisgICAgaWYgKHggPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgaWYgKGVuZCAhPSBzICsgbGVuKSB7CisgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19WYWx1ZUVycm9yLAorICAgICAgICAgICAgICAgICAgICAgICAgIm51bGwgYnl0ZSBpbiBhcmd1bWVudCBmb3IgbG9uZygpIik7CisgICAgICAgIFB5X0RFQ1JFRih4KTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIHJldHVybiB4OworfQorCitQeU9iamVjdCAqCitQeU51bWJlcl9Mb25nKFB5T2JqZWN0ICpvKQoreworICAgIFB5TnVtYmVyTWV0aG9kcyAqbTsKKyAgICBzdGF0aWMgUHlPYmplY3QgKnRydW5jX25hbWUgPSBOVUxMOworICAgIFB5T2JqZWN0ICp0cnVuY19mdW5jOworICAgIGNvbnN0IGNoYXIgKmJ1ZmZlcjsKKyAgICBQeV9zc2l6ZV90IGJ1ZmZlcl9sZW47CisKKyAgICBpZiAodHJ1bmNfbmFtZSA9PSBOVUxMKSB7CisgICAgICAgIHRydW5jX25hbWUgPSBQeVN0cmluZ19JbnRlcm5Gcm9tU3RyaW5nKCJfX3RydW5jX18iKTsKKyAgICAgICAgaWYgKHRydW5jX25hbWUgPT0gTlVMTCkKKyAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKworICAgIGlmIChvID09IE5VTEwpCisgICAgICAgIHJldHVybiBudWxsX2Vycm9yKCk7CisgICAgbSA9IG8tPm9iX3R5cGUtPnRwX2FzX251bWJlcjsKKyAgICBpZiAobSAmJiBtLT5uYl9sb25nKSB7IC8qIFRoaXMgc2hvdWxkIGluY2x1ZGUgc3ViY2xhc3NlcyBvZiBsb25nICovCisgICAgICAgIC8qIENsYXNzaWMgY2xhc3NlcyBhbHdheXMgdGFrZSB0aGlzIGJyYW5jaC4gKi8KKyAgICAgICAgUHlPYmplY3QgKnJlcyA9IG0tPm5iX2xvbmcobyk7CisgICAgICAgIGlmIChyZXMgPT0gTlVMTCkKKyAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgICAgICBpZiAoUHlJbnRfQ2hlY2socmVzKSkgeworICAgICAgICAgICAgbG9uZyB2YWx1ZSA9IFB5SW50X0FTX0xPTkcocmVzKTsKKyAgICAgICAgICAgIFB5X0RFQ1JFRihyZXMpOworICAgICAgICAgICAgcmV0dXJuIFB5TG9uZ19Gcm9tTG9uZyh2YWx1ZSk7CisgICAgICAgIH0KKyAgICAgICAgZWxzZSBpZiAoIVB5TG9uZ19DaGVjayhyZXMpKSB7CisgICAgICAgICAgICBQeUVycl9Gb3JtYXQoUHlFeGNfVHlwZUVycm9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICJfX2xvbmdfXyByZXR1cm5lZCBub24tbG9uZyAodHlwZSAlLjIwMHMpIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICByZXMtPm9iX3R5cGUtPnRwX25hbWUpOworICAgICAgICAgICAgUHlfREVDUkVGKHJlcyk7CisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gcmVzOworICAgIH0KKyAgICBpZiAoUHlMb25nX0NoZWNrKG8pKSAvKiBBIGxvbmcgc3ViY2xhc3Mgd2l0aG91dCBuYl9sb25nICovCisgICAgICAgIHJldHVybiBfUHlMb25nX0NvcHkoKFB5TG9uZ09iamVjdCAqKW8pOworICAgIHRydW5jX2Z1bmMgPSBQeU9iamVjdF9HZXRBdHRyKG8sIHRydW5jX25hbWUpOworICAgIGlmICh0cnVuY19mdW5jKSB7CisgICAgICAgIFB5T2JqZWN0ICp0cnVuY2F0ZWQgPSBQeUV2YWxfQ2FsbE9iamVjdCh0cnVuY19mdW5jLCBOVUxMKTsKKyAgICAgICAgUHlPYmplY3QgKmludF9pbnN0YW5jZTsKKyAgICAgICAgUHlfREVDUkVGKHRydW5jX2Z1bmMpOworICAgICAgICAvKiBfX3RydW5jX18gaXMgc3BlY2lmaWVkIHRvIHJldHVybiBhbiBJbnRlZ3JhbCB0eXBlLAorICAgICAgICAgICBidXQgbG9uZygpIG5lZWRzIHRvIHJldHVybiBhIGxvbmcuICovCisgICAgICAgIGludF9pbnN0YW5jZSA9IF9QeU51bWJlcl9Db252ZXJ0SW50ZWdyYWxUb0ludCgKKyAgICAgICAgICAgIHRydW5jYXRlZCwKKyAgICAgICAgICAgICJfX3RydW5jX18gcmV0dXJuZWQgbm9uLUludGVncmFsICh0eXBlICUuMjAwcykiKTsKKyAgICAgICAgaWYgKGludF9pbnN0YW5jZSAmJiBQeUludF9DaGVjayhpbnRfaW5zdGFuY2UpKSB7CisgICAgICAgICAgICAvKiBNYWtlIHN1cmUgdGhhdCBsb25nKCkgcmV0dXJucyBhIGxvbmcgaW5zdGFuY2UuICovCisgICAgICAgICAgICBsb25nIHZhbHVlID0gUHlJbnRfQVNfTE9ORyhpbnRfaW5zdGFuY2UpOworICAgICAgICAgICAgUHlfREVDUkVGKGludF9pbnN0YW5jZSk7CisgICAgICAgICAgICByZXR1cm4gUHlMb25nX0Zyb21Mb25nKHZhbHVlKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gaW50X2luc3RhbmNlOworICAgIH0KKyAgICBQeUVycl9DbGVhcigpOyAgLyogSXQncyBub3QgYW4gZXJyb3IgaWYgIG8uX190cnVuY19fIGRvZXNuJ3QgZXhpc3QuICovCisKKyAgICBpZiAoUHlTdHJpbmdfQ2hlY2sobykpCisgICAgICAgIC8qIG5lZWQgdG8gZG8gZXh0cmEgZXJyb3IgY2hlY2tpbmcgdGhhdCBQeUxvbmdfRnJvbVN0cmluZygpCisgICAgICAgICAqIGRvZXNuJ3QgZG8uICBJbiBwYXJ0aWN1bGFyIGxvbmcoJzkuNScpIG11c3QgcmFpc2UgYW4KKyAgICAgICAgICogZXhjZXB0aW9uLCBub3QgdHJ1bmNhdGUgdGhlIGZsb2F0LgorICAgICAgICAgKi8KKyAgICAgICAgcmV0dXJuIGxvbmdfZnJvbV9zdHJpbmcoUHlTdHJpbmdfQVNfU1RSSU5HKG8pLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQeVN0cmluZ19HRVRfU0laRShvKSk7CisjaWZkZWYgUHlfVVNJTkdfVU5JQ09ERQorICAgIGlmIChQeVVuaWNvZGVfQ2hlY2sobykpCisgICAgICAgIC8qIFRoZSBhYm92ZSBjaGVjayBpcyBkb25lIGluIFB5TG9uZ19Gcm9tVW5pY29kZSgpLiAqLworICAgICAgICByZXR1cm4gUHlMb25nX0Zyb21Vbmljb2RlKFB5VW5pY29kZV9BU19VTklDT0RFKG8pLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFB5VW5pY29kZV9HRVRfU0laRShvKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAxMCk7CisjZW5kaWYKKyAgICBpZiAoIVB5T2JqZWN0X0FzQ2hhckJ1ZmZlcihvLCAmYnVmZmVyLCAmYnVmZmVyX2xlbikpCisgICAgICAgIHJldHVybiBsb25nX2Zyb21fc3RyaW5nKGJ1ZmZlciwgYnVmZmVyX2xlbik7CisKKyAgICByZXR1cm4gdHlwZV9lcnJvcigibG9uZygpIGFyZ3VtZW50IG11c3QgYmUgYSBzdHJpbmcgb3IgYSAiCisgICAgICAgICAgICAgICAgICAgICAgIm51bWJlciwgbm90ICclLjIwMHMnIiwgbyk7Cit9CisKK1B5T2JqZWN0ICoKK1B5TnVtYmVyX0Zsb2F0KFB5T2JqZWN0ICpvKQoreworICAgIFB5TnVtYmVyTWV0aG9kcyAqbTsKKworICAgIGlmIChvID09IE5VTEwpCisgICAgICAgIHJldHVybiBudWxsX2Vycm9yKCk7CisgICAgbSA9IG8tPm9iX3R5cGUtPnRwX2FzX251bWJlcjsKKyAgICBpZiAobSAmJiBtLT5uYl9mbG9hdCkgeyAvKiBUaGlzIHNob3VsZCBpbmNsdWRlIHN1YmNsYXNzZXMgb2YgZmxvYXQgKi8KKyAgICAgICAgUHlPYmplY3QgKnJlcyA9IG0tPm5iX2Zsb2F0KG8pOworICAgICAgICBpZiAocmVzICYmICFQeUZsb2F0X0NoZWNrKHJlcykpIHsKKyAgICAgICAgICAgIFB5RXJyX0Zvcm1hdChQeUV4Y19UeXBlRXJyb3IsCisgICAgICAgICAgICAgICJfX2Zsb2F0X18gcmV0dXJuZWQgbm9uLWZsb2F0ICh0eXBlICUuMjAwcykiLAorICAgICAgICAgICAgICByZXMtPm9iX3R5cGUtPnRwX25hbWUpOworICAgICAgICAgICAgUHlfREVDUkVGKHJlcyk7CisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gcmVzOworICAgIH0KKyAgICBpZiAoUHlGbG9hdF9DaGVjayhvKSkgeyAvKiBBIGZsb2F0IHN1YmNsYXNzIHdpdGggbmJfZmxvYXQgPT0gTlVMTCAqLworICAgICAgICBQeUZsb2F0T2JqZWN0ICpwbyA9IChQeUZsb2F0T2JqZWN0ICopbzsKKyAgICAgICAgcmV0dXJuIFB5RmxvYXRfRnJvbURvdWJsZShwby0+b2JfZnZhbCk7CisgICAgfQorICAgIHJldHVybiBQeUZsb2F0X0Zyb21TdHJpbmcobywgTlVMTCk7Cit9CisKK1B5T2JqZWN0ICoKK1B5TnVtYmVyX1RvQmFzZShQeU9iamVjdCAqbiwgaW50IGJhc2UpCit7CisgICAgUHlPYmplY3QgKnJlcyA9IE5VTEw7CisgICAgUHlPYmplY3QgKmluZGV4ID0gUHlOdW1iZXJfSW5kZXgobik7CisKKyAgICBpZiAoIWluZGV4KQorICAgICAgICByZXR1cm4gTlVMTDsKKyAgICBpZiAoUHlMb25nX0NoZWNrKGluZGV4KSkKKyAgICAgICAgcmVzID0gX1B5TG9uZ19Gb3JtYXQoaW5kZXgsIGJhc2UsIDAsIDEpOworICAgIGVsc2UgaWYgKFB5SW50X0NoZWNrKGluZGV4KSkKKyAgICAgICAgcmVzID0gX1B5SW50X0Zvcm1hdCgoUHlJbnRPYmplY3QqKWluZGV4LCBiYXNlLCAxKTsKKyAgICBlbHNlCisgICAgICAgIC8qIEl0IHNob3VsZCBub3QgYmUgcG9zc2libGUgdG8gZ2V0IGhlcmUsIGFzCisgICAgICAgICAgIFB5TnVtYmVyX0luZGV4IGFscmVhZHkgaGFzIGEgY2hlY2sgZm9yIHRoZSBzYW1lCisgICAgICAgICAgIGNvbmRpdGlvbiAqLworICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfVmFsdWVFcnJvciwgIlB5TnVtYmVyX1RvQmFzZTogaW5kZXggbm90ICIKKyAgICAgICAgICAgICAgICAgICAgICAgICJpbnQgb3IgbG9uZyIpOworICAgIFB5X0RFQ1JFRihpbmRleCk7CisgICAgcmV0dXJuIHJlczsKK30KKworCisvKiBPcGVyYXRpb25zIG9uIHNlcXVlbmNlcyAqLworCitpbnQKK1B5U2VxdWVuY2VfQ2hlY2soUHlPYmplY3QgKnMpCit7CisgICAgaWYgKHMgPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIDA7CisgICAgaWYgKFB5SW5zdGFuY2VfQ2hlY2socykpCisgICAgICAgIHJldHVybiBQeU9iamVjdF9IYXNBdHRyU3RyaW5nKHMsICJfX2dldGl0ZW1fXyIpOworICAgIGlmIChQeURpY3RfQ2hlY2socykpCisgICAgICAgIHJldHVybiAwOworICAgIHJldHVybiAgcy0+b2JfdHlwZS0+dHBfYXNfc2VxdWVuY2UgJiYKKyAgICAgICAgcy0+b2JfdHlwZS0+dHBfYXNfc2VxdWVuY2UtPnNxX2l0ZW0gIT0gTlVMTDsKK30KKworUHlfc3NpemVfdAorUHlTZXF1ZW5jZV9TaXplKFB5T2JqZWN0ICpzKQoreworICAgIFB5U2VxdWVuY2VNZXRob2RzICptOworCisgICAgaWYgKHMgPT0gTlVMTCkgeworICAgICAgICBudWxsX2Vycm9yKCk7CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisKKyAgICBtID0gcy0+b2JfdHlwZS0+dHBfYXNfc2VxdWVuY2U7CisgICAgaWYgKG0gJiYgbS0+c3FfbGVuZ3RoKQorICAgICAgICByZXR1cm4gbS0+c3FfbGVuZ3RoKHMpOworCisgICAgdHlwZV9lcnJvcigib2JqZWN0IG9mIHR5cGUgJyUuMjAwcycgaGFzIG5vIGxlbigpIiwgcyk7CisgICAgcmV0dXJuIC0xOworfQorCisjdW5kZWYgUHlTZXF1ZW5jZV9MZW5ndGgKK1B5X3NzaXplX3QKK1B5U2VxdWVuY2VfTGVuZ3RoKFB5T2JqZWN0ICpzKQoreworICAgIHJldHVybiBQeVNlcXVlbmNlX1NpemUocyk7Cit9CisjZGVmaW5lIFB5U2VxdWVuY2VfTGVuZ3RoIFB5U2VxdWVuY2VfU2l6ZQorCitQeU9iamVjdCAqCitQeVNlcXVlbmNlX0NvbmNhdChQeU9iamVjdCAqcywgUHlPYmplY3QgKm8pCit7CisgICAgUHlTZXF1ZW5jZU1ldGhvZHMgKm07CisKKyAgICBpZiAocyA9PSBOVUxMIHx8IG8gPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIG51bGxfZXJyb3IoKTsKKworICAgIG0gPSBzLT5vYl90eXBlLT50cF9hc19zZXF1ZW5jZTsKKyAgICBpZiAobSAmJiBtLT5zcV9jb25jYXQpCisgICAgICAgIHJldHVybiBtLT5zcV9jb25jYXQocywgbyk7CisKKyAgICAvKiBJbnN0YW5jZXMgb2YgdXNlciBjbGFzc2VzIGRlZmluaW5nIGFuIF9fYWRkX18oKSBtZXRob2Qgb25seQorICAgICAgIGhhdmUgYW4gbmJfYWRkIHNsb3QsIG5vdCBhbiBzcV9jb25jYXQgc2xvdC4gIFNvIHdlIGZhbGwgYmFjaworICAgICAgIHRvIG5iX2FkZCBpZiBib3RoIGFyZ3VtZW50cyBhcHBlYXIgdG8gYmUgc2VxdWVuY2VzLiAqLworICAgIGlmIChQeVNlcXVlbmNlX0NoZWNrKHMpICYmIFB5U2VxdWVuY2VfQ2hlY2sobykpIHsKKyAgICAgICAgUHlPYmplY3QgKnJlc3VsdCA9IGJpbmFyeV9vcDEocywgbywgTkJfU0xPVChuYl9hZGQpKTsKKyAgICAgICAgaWYgKHJlc3VsdCAhPSBQeV9Ob3RJbXBsZW1lbnRlZCkKKyAgICAgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgICAgIFB5X0RFQ1JFRihyZXN1bHQpOworICAgIH0KKyAgICByZXR1cm4gdHlwZV9lcnJvcigiJyUuMjAwcycgb2JqZWN0IGNhbid0IGJlIGNvbmNhdGVuYXRlZCIsIHMpOworfQorCitQeU9iamVjdCAqCitQeVNlcXVlbmNlX1JlcGVhdChQeU9iamVjdCAqbywgUHlfc3NpemVfdCBjb3VudCkKK3sKKyAgICBQeVNlcXVlbmNlTWV0aG9kcyAqbTsKKworICAgIGlmIChvID09IE5VTEwpCisgICAgICAgIHJldHVybiBudWxsX2Vycm9yKCk7CisKKyAgICBtID0gby0+b2JfdHlwZS0+dHBfYXNfc2VxdWVuY2U7CisgICAgaWYgKG0gJiYgbS0+c3FfcmVwZWF0KQorICAgICAgICByZXR1cm4gbS0+c3FfcmVwZWF0KG8sIGNvdW50KTsKKworICAgIC8qIEluc3RhbmNlcyBvZiB1c2VyIGNsYXNzZXMgZGVmaW5pbmcgYSBfX211bF9fKCkgbWV0aG9kIG9ubHkKKyAgICAgICBoYXZlIGFuIG5iX211bHRpcGx5IHNsb3QsIG5vdCBhbiBzcV9yZXBlYXQgc2xvdC4gc28gd2UgZmFsbCBiYWNrCisgICAgICAgdG8gbmJfbXVsdGlwbHkgaWYgbyBhcHBlYXJzIHRvIGJlIGEgc2VxdWVuY2UuICovCisgICAgaWYgKFB5U2VxdWVuY2VfQ2hlY2sobykpIHsKKyAgICAgICAgUHlPYmplY3QgKm4sICpyZXN1bHQ7CisgICAgICAgIG4gPSBQeUludF9Gcm9tU3NpemVfdChjb3VudCk7CisgICAgICAgIGlmIChuID09IE5VTEwpCisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgcmVzdWx0ID0gYmluYXJ5X29wMShvLCBuLCBOQl9TTE9UKG5iX211bHRpcGx5KSk7CisgICAgICAgIFB5X0RFQ1JFRihuKTsKKyAgICAgICAgaWYgKHJlc3VsdCAhPSBQeV9Ob3RJbXBsZW1lbnRlZCkKKyAgICAgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgICAgIFB5X0RFQ1JFRihyZXN1bHQpOworICAgIH0KKyAgICByZXR1cm4gdHlwZV9lcnJvcigiJyUuMjAwcycgb2JqZWN0IGNhbid0IGJlIHJlcGVhdGVkIiwgbyk7Cit9CisKK1B5T2JqZWN0ICoKK1B5U2VxdWVuY2VfSW5QbGFjZUNvbmNhdChQeU9iamVjdCAqcywgUHlPYmplY3QgKm8pCit7CisgICAgUHlTZXF1ZW5jZU1ldGhvZHMgKm07CisKKyAgICBpZiAocyA9PSBOVUxMIHx8IG8gPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIG51bGxfZXJyb3IoKTsKKworICAgIG0gPSBzLT5vYl90eXBlLT50cF9hc19zZXF1ZW5jZTsKKyAgICBpZiAobSAmJiBIQVNJTlBMQUNFKHMpICYmIG0tPnNxX2lucGxhY2VfY29uY2F0KQorICAgICAgICByZXR1cm4gbS0+c3FfaW5wbGFjZV9jb25jYXQocywgbyk7CisgICAgaWYgKG0gJiYgbS0+c3FfY29uY2F0KQorICAgICAgICByZXR1cm4gbS0+c3FfY29uY2F0KHMsIG8pOworCisgICAgaWYgKFB5U2VxdWVuY2VfQ2hlY2socykgJiYgUHlTZXF1ZW5jZV9DaGVjayhvKSkgeworICAgICAgICBQeU9iamVjdCAqcmVzdWx0ID0gYmluYXJ5X2lvcDEocywgbywgTkJfU0xPVChuYl9pbnBsYWNlX2FkZCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOQl9TTE9UKG5iX2FkZCkpOworICAgICAgICBpZiAocmVzdWx0ICE9IFB5X05vdEltcGxlbWVudGVkKQorICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICAgICAgUHlfREVDUkVGKHJlc3VsdCk7CisgICAgfQorICAgIHJldHVybiB0eXBlX2Vycm9yKCInJS4yMDBzJyBvYmplY3QgY2FuJ3QgYmUgY29uY2F0ZW5hdGVkIiwgcyk7Cit9CisKK1B5T2JqZWN0ICoKK1B5U2VxdWVuY2VfSW5QbGFjZVJlcGVhdChQeU9iamVjdCAqbywgUHlfc3NpemVfdCBjb3VudCkKK3sKKyAgICBQeVNlcXVlbmNlTWV0aG9kcyAqbTsKKworICAgIGlmIChvID09IE5VTEwpCisgICAgICAgIHJldHVybiBudWxsX2Vycm9yKCk7CisKKyAgICBtID0gby0+b2JfdHlwZS0+dHBfYXNfc2VxdWVuY2U7CisgICAgaWYgKG0gJiYgSEFTSU5QTEFDRShvKSAmJiBtLT5zcV9pbnBsYWNlX3JlcGVhdCkKKyAgICAgICAgcmV0dXJuIG0tPnNxX2lucGxhY2VfcmVwZWF0KG8sIGNvdW50KTsKKyAgICBpZiAobSAmJiBtLT5zcV9yZXBlYXQpCisgICAgICAgIHJldHVybiBtLT5zcV9yZXBlYXQobywgY291bnQpOworCisgICAgaWYgKFB5U2VxdWVuY2VfQ2hlY2sobykpIHsKKyAgICAgICAgUHlPYmplY3QgKm4sICpyZXN1bHQ7CisgICAgICAgIG4gPSBQeUludF9Gcm9tU3NpemVfdChjb3VudCk7CisgICAgICAgIGlmIChuID09IE5VTEwpCisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgcmVzdWx0ID0gYmluYXJ5X2lvcDEobywgbiwgTkJfU0xPVChuYl9pbnBsYWNlX211bHRpcGx5KSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTkJfU0xPVChuYl9tdWx0aXBseSkpOworICAgICAgICBQeV9ERUNSRUYobik7CisgICAgICAgIGlmIChyZXN1bHQgIT0gUHlfTm90SW1wbGVtZW50ZWQpCisgICAgICAgICAgICByZXR1cm4gcmVzdWx0OworICAgICAgICBQeV9ERUNSRUYocmVzdWx0KTsKKyAgICB9CisgICAgcmV0dXJuIHR5cGVfZXJyb3IoIiclLjIwMHMnIG9iamVjdCBjYW4ndCBiZSByZXBlYXRlZCIsIG8pOworfQorCitQeU9iamVjdCAqCitQeVNlcXVlbmNlX0dldEl0ZW0oUHlPYmplY3QgKnMsIFB5X3NzaXplX3QgaSkKK3sKKyAgICBQeVNlcXVlbmNlTWV0aG9kcyAqbTsKKworICAgIGlmIChzID09IE5VTEwpCisgICAgICAgIHJldHVybiBudWxsX2Vycm9yKCk7CisKKyAgICBtID0gcy0+b2JfdHlwZS0+dHBfYXNfc2VxdWVuY2U7CisgICAgaWYgKG0gJiYgbS0+c3FfaXRlbSkgeworICAgICAgICBpZiAoaSA8IDApIHsKKyAgICAgICAgICAgIGlmIChtLT5zcV9sZW5ndGgpIHsKKyAgICAgICAgICAgICAgICBQeV9zc2l6ZV90IGwgPSAoKm0tPnNxX2xlbmd0aCkocyk7CisgICAgICAgICAgICAgICAgaWYgKGwgPCAwKQorICAgICAgICAgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgICAgICAgICBpICs9IGw7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG0tPnNxX2l0ZW0ocywgaSk7CisgICAgfQorCisgICAgcmV0dXJuIHR5cGVfZXJyb3IoIiclLjIwMHMnIG9iamVjdCBkb2VzIG5vdCBzdXBwb3J0IGluZGV4aW5nIiwgcyk7Cit9CisKK1B5T2JqZWN0ICoKK1B5U2VxdWVuY2VfR2V0U2xpY2UoUHlPYmplY3QgKnMsIFB5X3NzaXplX3QgaTEsIFB5X3NzaXplX3QgaTIpCit7CisgICAgUHlTZXF1ZW5jZU1ldGhvZHMgKm07CisgICAgUHlNYXBwaW5nTWV0aG9kcyAqbXA7CisKKyAgICBpZiAoIXMpIHJldHVybiBudWxsX2Vycm9yKCk7CisKKyAgICBtID0gcy0+b2JfdHlwZS0+dHBfYXNfc2VxdWVuY2U7CisgICAgaWYgKG0gJiYgbS0+c3Ffc2xpY2UpIHsKKyAgICAgICAgaWYgKGkxIDwgMCB8fCBpMiA8IDApIHsKKyAgICAgICAgICAgIGlmIChtLT5zcV9sZW5ndGgpIHsKKyAgICAgICAgICAgICAgICBQeV9zc2l6ZV90IGwgPSAoKm0tPnNxX2xlbmd0aCkocyk7CisgICAgICAgICAgICAgICAgaWYgKGwgPCAwKQorICAgICAgICAgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgICAgICAgICBpZiAoaTEgPCAwKQorICAgICAgICAgICAgICAgICAgICBpMSArPSBsOworICAgICAgICAgICAgICAgIGlmIChpMiA8IDApCisgICAgICAgICAgICAgICAgICAgIGkyICs9IGw7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG0tPnNxX3NsaWNlKHMsIGkxLCBpMik7CisgICAgfSBlbHNlIGlmICgobXAgPSBzLT5vYl90eXBlLT50cF9hc19tYXBwaW5nKSAmJiBtcC0+bXBfc3Vic2NyaXB0KSB7CisgICAgICAgIFB5T2JqZWN0ICpyZXM7CisgICAgICAgIFB5T2JqZWN0ICpzbGljZSA9IF9QeVNsaWNlX0Zyb21JbmRpY2VzKGkxLCBpMik7CisgICAgICAgIGlmICghc2xpY2UpCisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgcmVzID0gbXAtPm1wX3N1YnNjcmlwdChzLCBzbGljZSk7CisgICAgICAgIFB5X0RFQ1JFRihzbGljZSk7CisgICAgICAgIHJldHVybiByZXM7CisgICAgfQorCisgICAgcmV0dXJuIHR5cGVfZXJyb3IoIiclLjIwMHMnIG9iamVjdCBpcyB1bnNsaWNlYWJsZSIsIHMpOworfQorCitpbnQKK1B5U2VxdWVuY2VfU2V0SXRlbShQeU9iamVjdCAqcywgUHlfc3NpemVfdCBpLCBQeU9iamVjdCAqbykKK3sKKyAgICBQeVNlcXVlbmNlTWV0aG9kcyAqbTsKKworICAgIGlmIChzID09IE5VTEwpIHsKKyAgICAgICAgbnVsbF9lcnJvcigpOworICAgICAgICByZXR1cm4gLTE7CisgICAgfQorCisgICAgbSA9IHMtPm9iX3R5cGUtPnRwX2FzX3NlcXVlbmNlOworICAgIGlmIChtICYmIG0tPnNxX2Fzc19pdGVtKSB7CisgICAgICAgIGlmIChpIDwgMCkgeworICAgICAgICAgICAgaWYgKG0tPnNxX2xlbmd0aCkgeworICAgICAgICAgICAgICAgIFB5X3NzaXplX3QgbCA9ICgqbS0+c3FfbGVuZ3RoKShzKTsKKyAgICAgICAgICAgICAgICBpZiAobCA8IDApCisgICAgICAgICAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgICAgICAgICBpICs9IGw7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG0tPnNxX2Fzc19pdGVtKHMsIGksIG8pOworICAgIH0KKworICAgIHR5cGVfZXJyb3IoIiclLjIwMHMnIG9iamVjdCBkb2VzIG5vdCBzdXBwb3J0IGl0ZW0gYXNzaWdubWVudCIsIHMpOworICAgIHJldHVybiAtMTsKK30KKworaW50CitQeVNlcXVlbmNlX0RlbEl0ZW0oUHlPYmplY3QgKnMsIFB5X3NzaXplX3QgaSkKK3sKKyAgICBQeVNlcXVlbmNlTWV0aG9kcyAqbTsKKworICAgIGlmIChzID09IE5VTEwpIHsKKyAgICAgICAgbnVsbF9lcnJvcigpOworICAgICAgICByZXR1cm4gLTE7CisgICAgfQorCisgICAgbSA9IHMtPm9iX3R5cGUtPnRwX2FzX3NlcXVlbmNlOworICAgIGlmIChtICYmIG0tPnNxX2Fzc19pdGVtKSB7CisgICAgICAgIGlmIChpIDwgMCkgeworICAgICAgICAgICAgaWYgKG0tPnNxX2xlbmd0aCkgeworICAgICAgICAgICAgICAgIFB5X3NzaXplX3QgbCA9ICgqbS0+c3FfbGVuZ3RoKShzKTsKKyAgICAgICAgICAgICAgICBpZiAobCA8IDApCisgICAgICAgICAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgICAgICAgICBpICs9IGw7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG0tPnNxX2Fzc19pdGVtKHMsIGksIChQeU9iamVjdCAqKU5VTEwpOworICAgIH0KKworICAgIHR5cGVfZXJyb3IoIiclLjIwMHMnIG9iamVjdCBkb2Vzbid0IHN1cHBvcnQgaXRlbSBkZWxldGlvbiIsIHMpOworICAgIHJldHVybiAtMTsKK30KKworaW50CitQeVNlcXVlbmNlX1NldFNsaWNlKFB5T2JqZWN0ICpzLCBQeV9zc2l6ZV90IGkxLCBQeV9zc2l6ZV90IGkyLCBQeU9iamVjdCAqbykKK3sKKyAgICBQeVNlcXVlbmNlTWV0aG9kcyAqbTsKKyAgICBQeU1hcHBpbmdNZXRob2RzICptcDsKKworICAgIGlmIChzID09IE5VTEwpIHsKKyAgICAgICAgbnVsbF9lcnJvcigpOworICAgICAgICByZXR1cm4gLTE7CisgICAgfQorCisgICAgbSA9IHMtPm9iX3R5cGUtPnRwX2FzX3NlcXVlbmNlOworICAgIGlmIChtICYmIG0tPnNxX2Fzc19zbGljZSkgeworICAgICAgICBpZiAoaTEgPCAwIHx8IGkyIDwgMCkgeworICAgICAgICAgICAgaWYgKG0tPnNxX2xlbmd0aCkgeworICAgICAgICAgICAgICAgIFB5X3NzaXplX3QgbCA9ICgqbS0+c3FfbGVuZ3RoKShzKTsKKyAgICAgICAgICAgICAgICBpZiAobCA8IDApCisgICAgICAgICAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgICAgICAgICBpZiAoaTEgPCAwKQorICAgICAgICAgICAgICAgICAgICBpMSArPSBsOworICAgICAgICAgICAgICAgIGlmIChpMiA8IDApCisgICAgICAgICAgICAgICAgICAgIGkyICs9IGw7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIG0tPnNxX2Fzc19zbGljZShzLCBpMSwgaTIsIG8pOworICAgIH0gZWxzZSBpZiAoKG1wID0gcy0+b2JfdHlwZS0+dHBfYXNfbWFwcGluZykgJiYgbXAtPm1wX2Fzc19zdWJzY3JpcHQpIHsKKyAgICAgICAgaW50IHJlczsKKyAgICAgICAgUHlPYmplY3QgKnNsaWNlID0gX1B5U2xpY2VfRnJvbUluZGljZXMoaTEsIGkyKTsKKyAgICAgICAgaWYgKCFzbGljZSkKKyAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgcmVzID0gbXAtPm1wX2Fzc19zdWJzY3JpcHQocywgc2xpY2UsIG8pOworICAgICAgICBQeV9ERUNSRUYoc2xpY2UpOworICAgICAgICByZXR1cm4gcmVzOworICAgIH0KKworICAgIHR5cGVfZXJyb3IoIiclLjIwMHMnIG9iamVjdCBkb2Vzbid0IHN1cHBvcnQgc2xpY2UgYXNzaWdubWVudCIsIHMpOworICAgIHJldHVybiAtMTsKK30KKworaW50CitQeVNlcXVlbmNlX0RlbFNsaWNlKFB5T2JqZWN0ICpzLCBQeV9zc2l6ZV90IGkxLCBQeV9zc2l6ZV90IGkyKQoreworICAgIFB5U2VxdWVuY2VNZXRob2RzICptOworCisgICAgaWYgKHMgPT0gTlVMTCkgeworICAgICAgICBudWxsX2Vycm9yKCk7CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisKKyAgICBtID0gcy0+b2JfdHlwZS0+dHBfYXNfc2VxdWVuY2U7CisgICAgaWYgKG0gJiYgbS0+c3FfYXNzX3NsaWNlKSB7CisgICAgICAgIGlmIChpMSA8IDAgfHwgaTIgPCAwKSB7CisgICAgICAgICAgICBpZiAobS0+c3FfbGVuZ3RoKSB7CisgICAgICAgICAgICAgICAgUHlfc3NpemVfdCBsID0gKCptLT5zcV9sZW5ndGgpKHMpOworICAgICAgICAgICAgICAgIGlmIChsIDwgMCkKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICAgICAgICAgIGlmIChpMSA8IDApCisgICAgICAgICAgICAgICAgICAgIGkxICs9IGw7CisgICAgICAgICAgICAgICAgaWYgKGkyIDwgMCkKKyAgICAgICAgICAgICAgICAgICAgaTIgKz0gbDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICByZXR1cm4gbS0+c3FfYXNzX3NsaWNlKHMsIGkxLCBpMiwgKFB5T2JqZWN0ICopTlVMTCk7CisgICAgfQorICAgIHR5cGVfZXJyb3IoIiclLjIwMHMnIG9iamVjdCBkb2Vzbid0IHN1cHBvcnQgc2xpY2UgZGVsZXRpb24iLCBzKTsKKyAgICByZXR1cm4gLTE7Cit9CisKK1B5T2JqZWN0ICoKK1B5U2VxdWVuY2VfVHVwbGUoUHlPYmplY3QgKnYpCit7CisgICAgUHlPYmplY3QgKml0OyAgLyogaXRlcih2KSAqLworICAgIFB5X3NzaXplX3QgbjsgICAgICAgICAvKiBndWVzcyBmb3IgcmVzdWx0IHR1cGxlIHNpemUgKi8KKyAgICBQeU9iamVjdCAqcmVzdWx0ID0gTlVMTDsKKyAgICBQeV9zc2l6ZV90IGo7CisKKyAgICBpZiAodiA9PSBOVUxMKQorICAgICAgICByZXR1cm4gbnVsbF9lcnJvcigpOworCisgICAgLyogU3BlY2lhbC1jYXNlIHRoZSBjb21tb24gdHVwbGUgYW5kIGxpc3QgY2FzZXMsIGZvciBlZmZpY2llbmN5LiAqLworICAgIGlmIChQeVR1cGxlX0NoZWNrRXhhY3QodikpIHsKKyAgICAgICAgLyogTm90ZSB0aGF0IHdlIGNhbid0IGtub3cgd2hldGhlciBpdCdzIHNhZmUgdG8gcmV0dXJuCisgICAgICAgICAgIGEgdHVwbGUgKnN1YmNsYXNzKiBpbnN0YW5jZSBhcy1pcywgaGVuY2UgdGhlIHJlc3RyaWN0aW9uCisgICAgICAgICAgIHRvIGV4YWN0IHR1cGxlcyBoZXJlLiAgSW4gY29udHJhc3QsIGxpc3RzIGFsd2F5cyBtYWtlCisgICAgICAgICAgIGEgY29weSwgc28gdGhlcmUncyBubyBuZWVkIGZvciBleGFjdG5lc3MgYmVsb3cuICovCisgICAgICAgIFB5X0lOQ1JFRih2KTsKKyAgICAgICAgcmV0dXJuIHY7CisgICAgfQorICAgIGlmIChQeUxpc3RfQ2hlY2sodikpCisgICAgICAgIHJldHVybiBQeUxpc3RfQXNUdXBsZSh2KTsKKworICAgIC8qIEdldCBpdGVyYXRvci4gKi8KKyAgICBpdCA9IFB5T2JqZWN0X0dldEl0ZXIodik7CisgICAgaWYgKGl0ID09IE5VTEwpCisgICAgICAgIHJldHVybiBOVUxMOworCisgICAgLyogR3Vlc3MgcmVzdWx0IHNpemUgYW5kIGFsbG9jYXRlIHNwYWNlLiAqLworICAgIG4gPSBfUHlPYmplY3RfTGVuZ3RoSGludCh2LCAxMCk7CisgICAgaWYgKG4gPT0gLTEpCisgICAgICAgIGdvdG8gRmFpbDsKKyAgICByZXN1bHQgPSBQeVR1cGxlX05ldyhuKTsKKyAgICBpZiAocmVzdWx0ID09IE5VTEwpCisgICAgICAgIGdvdG8gRmFpbDsKKworICAgIC8qIEZpbGwgdGhlIHR1cGxlLiAqLworICAgIGZvciAoaiA9IDA7IDsgKytqKSB7CisgICAgICAgIFB5T2JqZWN0ICppdGVtID0gUHlJdGVyX05leHQoaXQpOworICAgICAgICBpZiAoaXRlbSA9PSBOVUxMKSB7CisgICAgICAgICAgICBpZiAoUHlFcnJfT2NjdXJyZWQoKSkKKyAgICAgICAgICAgICAgICBnb3RvIEZhaWw7CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgfQorICAgICAgICBpZiAoaiA+PSBuKSB7CisgICAgICAgICAgICBQeV9zc2l6ZV90IG9sZG4gPSBuOworICAgICAgICAgICAgLyogVGhlIG92ZXItYWxsb2NhdGlvbiBzdHJhdGVneSBjYW4gZ3JvdyBhIGJpdCBmYXN0ZXIKKyAgICAgICAgICAgICAgIHRoYW4gZm9yIGxpc3RzIGJlY2F1c2UgdW5saWtlIGxpc3RzIHRoZQorICAgICAgICAgICAgICAgb3Zlci1hbGxvY2F0aW9uIGlzbid0IHBlcm1hbmVudCAtLSB3ZSByZWNsYWltCisgICAgICAgICAgICAgICB0aGUgZXhjZXNzIGJlZm9yZSB0aGUgZW5kIG9mIHRoaXMgcm91dGluZS4KKyAgICAgICAgICAgICAgIFNvLCBncm93IGJ5IHRlbiBhbmQgdGhlbiBhZGQgMjUlLgorICAgICAgICAgICAgKi8KKyAgICAgICAgICAgIG4gKz0gMTA7CisgICAgICAgICAgICBuICs9IG4gPj4gMjsKKyAgICAgICAgICAgIGlmIChuIDwgb2xkbikgeworICAgICAgICAgICAgICAgIC8qIENoZWNrIGZvciBvdmVyZmxvdyAqLworICAgICAgICAgICAgICAgIFB5RXJyX05vTWVtb3J5KCk7CisgICAgICAgICAgICAgICAgUHlfREVDUkVGKGl0ZW0pOworICAgICAgICAgICAgICAgIGdvdG8gRmFpbDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChfUHlUdXBsZV9SZXNpemUoJnJlc3VsdCwgbikgIT0gMCkgeworICAgICAgICAgICAgICAgIFB5X0RFQ1JFRihpdGVtKTsKKyAgICAgICAgICAgICAgICBnb3RvIEZhaWw7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgUHlUdXBsZV9TRVRfSVRFTShyZXN1bHQsIGosIGl0ZW0pOworICAgIH0KKworICAgIC8qIEN1dCB0dXBsZSBiYWNrIGlmIGd1ZXNzIHdhcyB0b28gbGFyZ2UuICovCisgICAgaWYgKGogPCBuICYmCisgICAgICAgIF9QeVR1cGxlX1Jlc2l6ZSgmcmVzdWx0LCBqKSAhPSAwKQorICAgICAgICBnb3RvIEZhaWw7CisKKyAgICBQeV9ERUNSRUYoaXQpOworICAgIHJldHVybiByZXN1bHQ7CisKK0ZhaWw6CisgICAgUHlfWERFQ1JFRihyZXN1bHQpOworICAgIFB5X0RFQ1JFRihpdCk7CisgICAgcmV0dXJuIE5VTEw7Cit9CisKK1B5T2JqZWN0ICoKK1B5U2VxdWVuY2VfTGlzdChQeU9iamVjdCAqdikKK3sKKyAgICBQeU9iamVjdCAqcmVzdWx0OyAgLyogcmVzdWx0IGxpc3QgKi8KKyAgICBQeU9iamVjdCAqcnY7ICAgICAgLyogcmV0dXJuIHZhbHVlIGZyb20gUHlMaXN0X0V4dGVuZCAqLworCisgICAgaWYgKHYgPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIG51bGxfZXJyb3IoKTsKKworICAgIHJlc3VsdCA9IFB5TGlzdF9OZXcoMCk7CisgICAgaWYgKHJlc3VsdCA9PSBOVUxMKQorICAgICAgICByZXR1cm4gTlVMTDsKKworICAgIHJ2ID0gX1B5TGlzdF9FeHRlbmQoKFB5TGlzdE9iamVjdCAqKXJlc3VsdCwgdik7CisgICAgaWYgKHJ2ID09IE5VTEwpIHsKKyAgICAgICAgUHlfREVDUkVGKHJlc3VsdCk7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICBQeV9ERUNSRUYocnYpOworICAgIHJldHVybiByZXN1bHQ7Cit9CisKK1B5T2JqZWN0ICoKK1B5U2VxdWVuY2VfRmFzdChQeU9iamVjdCAqdiwgY29uc3QgY2hhciAqbSkKK3sKKyAgICBQeU9iamVjdCAqaXQ7CisKKyAgICBpZiAodiA9PSBOVUxMKQorICAgICAgICByZXR1cm4gbnVsbF9lcnJvcigpOworCisgICAgaWYgKFB5TGlzdF9DaGVja0V4YWN0KHYpIHx8IFB5VHVwbGVfQ2hlY2tFeGFjdCh2KSkgeworICAgICAgICBQeV9JTkNSRUYodik7CisgICAgICAgIHJldHVybiB2OworICAgIH0KKworICAgIGl0ID0gUHlPYmplY3RfR2V0SXRlcih2KTsKKyAgICBpZiAoaXQgPT0gTlVMTCkgeworICAgICAgICBpZiAoUHlFcnJfRXhjZXB0aW9uTWF0Y2hlcyhQeUV4Y19UeXBlRXJyb3IpKQorICAgICAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1R5cGVFcnJvciwgbSk7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKworICAgIHYgPSBQeVNlcXVlbmNlX0xpc3QoaXQpOworICAgIFB5X0RFQ1JFRihpdCk7CisKKyAgICByZXR1cm4gdjsKK30KKworLyogSXRlcmF0ZSBvdmVyIHNlcS4gIFJlc3VsdCBkZXBlbmRzIG9uIHRoZSBvcGVyYXRpb246CisgICBQWV9JVEVSU0VBUkNIX0NPVU5UOiAgLTEgaWYgZXJyb3IsIGVsc2UgIyBvZiB0aW1lcyBvYmogYXBwZWFycyBpbiBzZXEuCisgICBQWV9JVEVSU0VBUkNIX0lOREVYOiAgMC1iYXNlZCBpbmRleCBvZiBmaXJzdCBvY2N1cnJlbmNlIG9mIG9iaiBpbiBzZXE7CisgICAgc2V0IFZhbHVlRXJyb3IgYW5kIHJldHVybiAtMSBpZiBub25lIGZvdW5kOyBhbHNvIHJldHVybiAtMSBvbiBlcnJvci4KKyAgIFB5X0lURVJTRUFSQ0hfQ09OVEFJTlM6ICByZXR1cm4gMSBpZiBvYmogaW4gc2VxLCBlbHNlIDA7IC0xIG9uIGVycm9yLgorKi8KK1B5X3NzaXplX3QKK19QeVNlcXVlbmNlX0l0ZXJTZWFyY2goUHlPYmplY3QgKnNlcSwgUHlPYmplY3QgKm9iaiwgaW50IG9wZXJhdGlvbikKK3sKKyAgICBQeV9zc2l6ZV90IG47CisgICAgaW50IHdyYXBwZWQ7ICAvKiBmb3IgUFlfSVRFUlNFQVJDSF9JTkRFWCwgdHJ1ZSBpZmYgbiB3cmFwcGVkIGFyb3VuZCAqLworICAgIFB5T2JqZWN0ICppdDsgIC8qIGl0ZXIoc2VxKSAqLworCisgICAgaWYgKHNlcSA9PSBOVUxMIHx8IG9iaiA9PSBOVUxMKSB7CisgICAgICAgIG51bGxfZXJyb3IoKTsKKyAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKworICAgIGl0ID0gUHlPYmplY3RfR2V0SXRlcihzZXEpOworICAgIGlmIChpdCA9PSBOVUxMKSB7CisgICAgICAgIHR5cGVfZXJyb3IoImFyZ3VtZW50IG9mIHR5cGUgJyUuMjAwcycgaXMgbm90IGl0ZXJhYmxlIiwgc2VxKTsKKyAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKworICAgIG4gPSB3cmFwcGVkID0gMDsKKyAgICBmb3IgKDs7KSB7CisgICAgICAgIGludCBjbXA7CisgICAgICAgIFB5T2JqZWN0ICppdGVtID0gUHlJdGVyX05leHQoaXQpOworICAgICAgICBpZiAoaXRlbSA9PSBOVUxMKSB7CisgICAgICAgICAgICBpZiAoUHlFcnJfT2NjdXJyZWQoKSkKKyAgICAgICAgICAgICAgICBnb3RvIEZhaWw7CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgfQorCisgICAgICAgIGNtcCA9IFB5T2JqZWN0X1JpY2hDb21wYXJlQm9vbChvYmosIGl0ZW0sIFB5X0VRKTsKKyAgICAgICAgUHlfREVDUkVGKGl0ZW0pOworICAgICAgICBpZiAoY21wIDwgMCkKKyAgICAgICAgICAgIGdvdG8gRmFpbDsKKyAgICAgICAgaWYgKGNtcCA+IDApIHsKKyAgICAgICAgICAgIHN3aXRjaCAob3BlcmF0aW9uKSB7CisgICAgICAgICAgICBjYXNlIFBZX0lURVJTRUFSQ0hfQ09VTlQ6CisgICAgICAgICAgICAgICAgaWYgKG4gPT0gUFlfU1NJWkVfVF9NQVgpIHsKKyAgICAgICAgICAgICAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX092ZXJmbG93RXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAiY291bnQgZXhjZWVkcyBDIGludGVnZXIgc2l6ZSIpOworICAgICAgICAgICAgICAgICAgICBnb3RvIEZhaWw7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICsrbjsKKyAgICAgICAgICAgICAgICBicmVhazsKKworICAgICAgICAgICAgY2FzZSBQWV9JVEVSU0VBUkNIX0lOREVYOgorICAgICAgICAgICAgICAgIGlmICh3cmFwcGVkKSB7CisgICAgICAgICAgICAgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19PdmVyZmxvd0Vycm9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgImluZGV4IGV4Y2VlZHMgQyBpbnRlZ2VyIHNpemUiKTsKKyAgICAgICAgICAgICAgICAgICAgZ290byBGYWlsOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBnb3RvIERvbmU7CisKKyAgICAgICAgICAgIGNhc2UgUFlfSVRFUlNFQVJDSF9DT05UQUlOUzoKKyAgICAgICAgICAgICAgICBuID0gMTsKKyAgICAgICAgICAgICAgICBnb3RvIERvbmU7CisKKyAgICAgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICAgICAgYXNzZXJ0KCEidW5rbm93biBvcGVyYXRpb24iKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIGlmIChvcGVyYXRpb24gPT0gUFlfSVRFUlNFQVJDSF9JTkRFWCkgeworICAgICAgICAgICAgaWYgKG4gPT0gUFlfU1NJWkVfVF9NQVgpCisgICAgICAgICAgICAgICAgd3JhcHBlZCA9IDE7CisgICAgICAgICAgICArK247CisgICAgICAgIH0KKyAgICB9CisKKyAgICBpZiAob3BlcmF0aW9uICE9IFBZX0lURVJTRUFSQ0hfSU5ERVgpCisgICAgICAgIGdvdG8gRG9uZTsKKworICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19WYWx1ZUVycm9yLAorICAgICAgICAgICAgICAgICAgICAic2VxdWVuY2UuaW5kZXgoeCk6IHggbm90IGluIHNlcXVlbmNlIik7CisgICAgLyogZmFsbCBpbnRvIGZhaWx1cmUgY29kZSAqLworRmFpbDoKKyAgICBuID0gLTE7CisgICAgLyogZmFsbCB0aHJvdWdoICovCitEb25lOgorICAgIFB5X0RFQ1JFRihpdCk7CisgICAgcmV0dXJuIG47CisKK30KKworLyogUmV0dXJuICMgb2YgdGltZXMgbyBhcHBlYXJzIGluIHMuICovCitQeV9zc2l6ZV90CitQeVNlcXVlbmNlX0NvdW50KFB5T2JqZWN0ICpzLCBQeU9iamVjdCAqbykKK3sKKyAgICByZXR1cm4gX1B5U2VxdWVuY2VfSXRlclNlYXJjaChzLCBvLCBQWV9JVEVSU0VBUkNIX0NPVU5UKTsKK30KKworLyogUmV0dXJuIC0xIGlmIGVycm9yOyAxIGlmIG9iIGluIHNlcTsgMCBpZiBvYiBub3QgaW4gc2VxLgorICogVXNlIHNxX2NvbnRhaW5zIGlmIHBvc3NpYmxlLCBlbHNlIGRlZmVyIHRvIF9QeVNlcXVlbmNlX0l0ZXJTZWFyY2goKS4KKyAqLworaW50CitQeVNlcXVlbmNlX0NvbnRhaW5zKFB5T2JqZWN0ICpzZXEsIFB5T2JqZWN0ICpvYikKK3sKKyAgICBQeV9zc2l6ZV90IHJlc3VsdDsKKyAgICBpZiAoUHlUeXBlX0hhc0ZlYXR1cmUoc2VxLT5vYl90eXBlLCBQeV9UUEZMQUdTX0hBVkVfU0VRVUVOQ0VfSU4pKSB7CisgICAgICAgIFB5U2VxdWVuY2VNZXRob2RzICpzcW0gPSBzZXEtPm9iX3R5cGUtPnRwX2FzX3NlcXVlbmNlOworICAgICAgICBpZiAoc3FtICE9IE5VTEwgJiYgc3FtLT5zcV9jb250YWlucyAhPSBOVUxMKQorICAgICAgICAgICAgcmV0dXJuICgqc3FtLT5zcV9jb250YWlucykoc2VxLCBvYik7CisgICAgfQorICAgIHJlc3VsdCA9IF9QeVNlcXVlbmNlX0l0ZXJTZWFyY2goc2VxLCBvYiwgUFlfSVRFUlNFQVJDSF9DT05UQUlOUyk7CisgICAgcmV0dXJuIFB5X1NBRkVfRE9XTkNBU1QocmVzdWx0LCBQeV9zc2l6ZV90LCBpbnQpOworfQorCisvKiBCYWNrd2FyZHMgY29tcGF0aWJpbGl0eSAqLworI3VuZGVmIFB5U2VxdWVuY2VfSW4KK2ludAorUHlTZXF1ZW5jZV9JbihQeU9iamVjdCAqdywgUHlPYmplY3QgKnYpCit7CisgICAgcmV0dXJuIFB5U2VxdWVuY2VfQ29udGFpbnModywgdik7Cit9CisKK1B5X3NzaXplX3QKK1B5U2VxdWVuY2VfSW5kZXgoUHlPYmplY3QgKnMsIFB5T2JqZWN0ICpvKQoreworICAgIHJldHVybiBfUHlTZXF1ZW5jZV9JdGVyU2VhcmNoKHMsIG8sIFBZX0lURVJTRUFSQ0hfSU5ERVgpOworfQorCisvKiBPcGVyYXRpb25zIG9uIG1hcHBpbmdzICovCisKK2ludAorUHlNYXBwaW5nX0NoZWNrKFB5T2JqZWN0ICpvKQoreworICAgIGlmIChvICYmIFB5SW5zdGFuY2VfQ2hlY2sobykpCisgICAgICAgIHJldHVybiBQeU9iamVjdF9IYXNBdHRyU3RyaW5nKG8sICJfX2dldGl0ZW1fXyIpOworCisgICAgcmV0dXJuICBvICYmIG8tPm9iX3R5cGUtPnRwX2FzX21hcHBpbmcgJiYKKyAgICAgICAgby0+b2JfdHlwZS0+dHBfYXNfbWFwcGluZy0+bXBfc3Vic2NyaXB0ICYmCisgICAgICAgICEoby0+b2JfdHlwZS0+dHBfYXNfc2VxdWVuY2UgJiYKKyAgICAgICAgICBvLT5vYl90eXBlLT50cF9hc19zZXF1ZW5jZS0+c3Ffc2xpY2UpOworfQorCitQeV9zc2l6ZV90CitQeU1hcHBpbmdfU2l6ZShQeU9iamVjdCAqbykKK3sKKyAgICBQeU1hcHBpbmdNZXRob2RzICptOworCisgICAgaWYgKG8gPT0gTlVMTCkgeworICAgICAgICBudWxsX2Vycm9yKCk7CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisKKyAgICBtID0gby0+b2JfdHlwZS0+dHBfYXNfbWFwcGluZzsKKyAgICBpZiAobSAmJiBtLT5tcF9sZW5ndGgpCisgICAgICAgIHJldHVybiBtLT5tcF9sZW5ndGgobyk7CisKKyAgICB0eXBlX2Vycm9yKCJvYmplY3Qgb2YgdHlwZSAnJS4yMDBzJyBoYXMgbm8gbGVuKCkiLCBvKTsKKyAgICByZXR1cm4gLTE7Cit9CisKKyN1bmRlZiBQeU1hcHBpbmdfTGVuZ3RoCitQeV9zc2l6ZV90CitQeU1hcHBpbmdfTGVuZ3RoKFB5T2JqZWN0ICpvKQoreworICAgIHJldHVybiBQeU1hcHBpbmdfU2l6ZShvKTsKK30KKyNkZWZpbmUgUHlNYXBwaW5nX0xlbmd0aCBQeU1hcHBpbmdfU2l6ZQorCitQeU9iamVjdCAqCitQeU1hcHBpbmdfR2V0SXRlbVN0cmluZyhQeU9iamVjdCAqbywgY2hhciAqa2V5KQoreworICAgIFB5T2JqZWN0ICpva2V5LCAqcjsKKworICAgIGlmIChrZXkgPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIG51bGxfZXJyb3IoKTsKKworICAgIG9rZXkgPSBQeVN0cmluZ19Gcm9tU3RyaW5nKGtleSk7CisgICAgaWYgKG9rZXkgPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgciA9IFB5T2JqZWN0X0dldEl0ZW0obywgb2tleSk7CisgICAgUHlfREVDUkVGKG9rZXkpOworICAgIHJldHVybiByOworfQorCitpbnQKK1B5TWFwcGluZ19TZXRJdGVtU3RyaW5nKFB5T2JqZWN0ICpvLCBjaGFyICprZXksIFB5T2JqZWN0ICp2YWx1ZSkKK3sKKyAgICBQeU9iamVjdCAqb2tleTsKKyAgICBpbnQgcjsKKworICAgIGlmIChrZXkgPT0gTlVMTCkgeworICAgICAgICBudWxsX2Vycm9yKCk7CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisKKyAgICBva2V5ID0gUHlTdHJpbmdfRnJvbVN0cmluZyhrZXkpOworICAgIGlmIChva2V5ID09IE5VTEwpCisgICAgICAgIHJldHVybiAtMTsKKyAgICByID0gUHlPYmplY3RfU2V0SXRlbShvLCBva2V5LCB2YWx1ZSk7CisgICAgUHlfREVDUkVGKG9rZXkpOworICAgIHJldHVybiByOworfQorCitpbnQKK1B5TWFwcGluZ19IYXNLZXlTdHJpbmcoUHlPYmplY3QgKm8sIGNoYXIgKmtleSkKK3sKKyAgICBQeU9iamVjdCAqdjsKKworICAgIHYgPSBQeU1hcHBpbmdfR2V0SXRlbVN0cmluZyhvLCBrZXkpOworICAgIGlmICh2KSB7CisgICAgICAgIFB5X0RFQ1JFRih2KTsKKyAgICAgICAgcmV0dXJuIDE7CisgICAgfQorICAgIFB5RXJyX0NsZWFyKCk7CisgICAgcmV0dXJuIDA7Cit9CisKK2ludAorUHlNYXBwaW5nX0hhc0tleShQeU9iamVjdCAqbywgUHlPYmplY3QgKmtleSkKK3sKKyAgICBQeU9iamVjdCAqdjsKKworICAgIHYgPSBQeU9iamVjdF9HZXRJdGVtKG8sIGtleSk7CisgICAgaWYgKHYpIHsKKyAgICAgICAgUHlfREVDUkVGKHYpOworICAgICAgICByZXR1cm4gMTsKKyAgICB9CisgICAgUHlFcnJfQ2xlYXIoKTsKKyAgICByZXR1cm4gMDsKK30KKworLyogT3BlcmF0aW9ucyBvbiBjYWxsYWJsZSBvYmplY3RzICovCisKKy8qIFhYWCBQeUNhbGxhYmxlX0NoZWNrKCkgaXMgaW4gb2JqZWN0LmMgKi8KKworUHlPYmplY3QgKgorUHlPYmplY3RfQ2FsbE9iamVjdChQeU9iamVjdCAqbywgUHlPYmplY3QgKmEpCit7CisgICAgcmV0dXJuIFB5RXZhbF9DYWxsT2JqZWN0V2l0aEtleXdvcmRzKG8sIGEsIE5VTEwpOworfQorCitQeU9iamVjdCAqCitQeU9iamVjdF9DYWxsKFB5T2JqZWN0ICpmdW5jLCBQeU9iamVjdCAqYXJnLCBQeU9iamVjdCAqa3cpCit7CisgICAgdGVybmFyeWZ1bmMgY2FsbDsKKworICAgIGlmICgoY2FsbCA9IGZ1bmMtPm9iX3R5cGUtPnRwX2NhbGwpICE9IE5VTEwpIHsKKyAgICAgICAgUHlPYmplY3QgKnJlc3VsdDsKKyAgICAgICAgaWYgKFB5X0VudGVyUmVjdXJzaXZlQ2FsbCgiIHdoaWxlIGNhbGxpbmcgYSBQeXRob24gb2JqZWN0IikpCisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgcmVzdWx0ID0gKCpjYWxsKShmdW5jLCBhcmcsIGt3KTsKKyAgICAgICAgUHlfTGVhdmVSZWN1cnNpdmVDYWxsKCk7CisgICAgICAgIGlmIChyZXN1bHQgPT0gTlVMTCAmJiAhUHlFcnJfT2NjdXJyZWQoKSkKKyAgICAgICAgICAgIFB5RXJyX1NldFN0cmluZygKKyAgICAgICAgICAgICAgICBQeUV4Y19TeXN0ZW1FcnJvciwKKyAgICAgICAgICAgICAgICAiTlVMTCByZXN1bHQgd2l0aG91dCBlcnJvciBpbiBQeU9iamVjdF9DYWxsIik7CisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorICAgIFB5RXJyX0Zvcm1hdChQeUV4Y19UeXBlRXJyb3IsICInJS4yMDBzJyBvYmplY3QgaXMgbm90IGNhbGxhYmxlIiwKKyAgICAgICAgICAgICAgICAgZnVuYy0+b2JfdHlwZS0+dHBfbmFtZSk7CisgICAgcmV0dXJuIE5VTEw7Cit9CisKK3N0YXRpYyBQeU9iamVjdCoKK2NhbGxfZnVuY3Rpb25fdGFpbChQeU9iamVjdCAqY2FsbGFibGUsIFB5T2JqZWN0ICphcmdzKQoreworICAgIFB5T2JqZWN0ICpyZXR2YWw7CisKKyAgICBpZiAoYXJncyA9PSBOVUxMKQorICAgICAgICByZXR1cm4gTlVMTDsKKworICAgIGlmICghUHlUdXBsZV9DaGVjayhhcmdzKSkgeworICAgICAgICBQeU9iamVjdCAqYTsKKworICAgICAgICBhID0gUHlUdXBsZV9OZXcoMSk7CisgICAgICAgIGlmIChhID09IE5VTEwpIHsKKyAgICAgICAgICAgIFB5X0RFQ1JFRihhcmdzKTsKKyAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgICAgICB9CisgICAgICAgIFB5VHVwbGVfU0VUX0lURU0oYSwgMCwgYXJncyk7CisgICAgICAgIGFyZ3MgPSBhOworICAgIH0KKyAgICByZXR2YWwgPSBQeU9iamVjdF9DYWxsKGNhbGxhYmxlLCBhcmdzLCBOVUxMKTsKKworICAgIFB5X0RFQ1JFRihhcmdzKTsKKworICAgIHJldHVybiByZXR2YWw7Cit9CisKK1B5T2JqZWN0ICoKK1B5T2JqZWN0X0NhbGxGdW5jdGlvbihQeU9iamVjdCAqY2FsbGFibGUsIGNoYXIgKmZvcm1hdCwgLi4uKQoreworICAgIHZhX2xpc3QgdmE7CisgICAgUHlPYmplY3QgKmFyZ3M7CisKKyAgICBpZiAoY2FsbGFibGUgPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIG51bGxfZXJyb3IoKTsKKworICAgIGlmIChmb3JtYXQgJiYgKmZvcm1hdCkgeworICAgICAgICB2YV9zdGFydCh2YSwgZm9ybWF0KTsKKyAgICAgICAgYXJncyA9IFB5X1ZhQnVpbGRWYWx1ZShmb3JtYXQsIHZhKTsKKyAgICAgICAgdmFfZW5kKHZhKTsKKyAgICB9CisgICAgZWxzZQorICAgICAgICBhcmdzID0gUHlUdXBsZV9OZXcoMCk7CisKKyAgICByZXR1cm4gY2FsbF9mdW5jdGlvbl90YWlsKGNhbGxhYmxlLCBhcmdzKTsKK30KKworUHlPYmplY3QgKgorX1B5T2JqZWN0X0NhbGxGdW5jdGlvbl9TaXplVChQeU9iamVjdCAqY2FsbGFibGUsIGNoYXIgKmZvcm1hdCwgLi4uKQoreworICAgIHZhX2xpc3QgdmE7CisgICAgUHlPYmplY3QgKmFyZ3M7CisKKyAgICBpZiAoY2FsbGFibGUgPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIG51bGxfZXJyb3IoKTsKKworICAgIGlmIChmb3JtYXQgJiYgKmZvcm1hdCkgeworICAgICAgICB2YV9zdGFydCh2YSwgZm9ybWF0KTsKKyAgICAgICAgYXJncyA9IF9QeV9WYUJ1aWxkVmFsdWVfU2l6ZVQoZm9ybWF0LCB2YSk7CisgICAgICAgIHZhX2VuZCh2YSk7CisgICAgfQorICAgIGVsc2UKKyAgICAgICAgYXJncyA9IFB5VHVwbGVfTmV3KDApOworCisgICAgcmV0dXJuIGNhbGxfZnVuY3Rpb25fdGFpbChjYWxsYWJsZSwgYXJncyk7Cit9CisKK1B5T2JqZWN0ICoKK1B5T2JqZWN0X0NhbGxNZXRob2QoUHlPYmplY3QgKm8sIGNoYXIgKm5hbWUsIGNoYXIgKmZvcm1hdCwgLi4uKQoreworICAgIHZhX2xpc3QgdmE7CisgICAgUHlPYmplY3QgKmFyZ3M7CisgICAgUHlPYmplY3QgKmZ1bmMgPSBOVUxMOworICAgIFB5T2JqZWN0ICpyZXR2YWwgPSBOVUxMOworCisgICAgaWYgKG8gPT0gTlVMTCB8fCBuYW1lID09IE5VTEwpCisgICAgICAgIHJldHVybiBudWxsX2Vycm9yKCk7CisKKyAgICBmdW5jID0gUHlPYmplY3RfR2V0QXR0clN0cmluZyhvLCBuYW1lKTsKKyAgICBpZiAoZnVuYyA9PSBOVUxMKSB7CisgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19BdHRyaWJ1dGVFcnJvciwgbmFtZSk7CisgICAgICAgIHJldHVybiAwOworICAgIH0KKworICAgIGlmICghUHlDYWxsYWJsZV9DaGVjayhmdW5jKSkgeworICAgICAgICB0eXBlX2Vycm9yKCJhdHRyaWJ1dGUgb2YgdHlwZSAnJS4yMDBzJyBpcyBub3QgY2FsbGFibGUiLCBmdW5jKTsKKyAgICAgICAgZ290byBleGl0OworICAgIH0KKworICAgIGlmIChmb3JtYXQgJiYgKmZvcm1hdCkgeworICAgICAgICB2YV9zdGFydCh2YSwgZm9ybWF0KTsKKyAgICAgICAgYXJncyA9IFB5X1ZhQnVpbGRWYWx1ZShmb3JtYXQsIHZhKTsKKyAgICAgICAgdmFfZW5kKHZhKTsKKyAgICB9CisgICAgZWxzZQorICAgICAgICBhcmdzID0gUHlUdXBsZV9OZXcoMCk7CisKKyAgICByZXR2YWwgPSBjYWxsX2Z1bmN0aW9uX3RhaWwoZnVuYywgYXJncyk7CisKKyAgZXhpdDoKKyAgICAvKiBhcmdzIGdldHMgY29uc3VtZWQgaW4gY2FsbF9mdW5jdGlvbl90YWlsICovCisgICAgUHlfWERFQ1JFRihmdW5jKTsKKworICAgIHJldHVybiByZXR2YWw7Cit9CisKK1B5T2JqZWN0ICoKK19QeU9iamVjdF9DYWxsTWV0aG9kX1NpemVUKFB5T2JqZWN0ICpvLCBjaGFyICpuYW1lLCBjaGFyICpmb3JtYXQsIC4uLikKK3sKKyAgICB2YV9saXN0IHZhOworICAgIFB5T2JqZWN0ICphcmdzOworICAgIFB5T2JqZWN0ICpmdW5jID0gTlVMTDsKKyAgICBQeU9iamVjdCAqcmV0dmFsID0gTlVMTDsKKworICAgIGlmIChvID09IE5VTEwgfHwgbmFtZSA9PSBOVUxMKQorICAgICAgICByZXR1cm4gbnVsbF9lcnJvcigpOworCisgICAgZnVuYyA9IFB5T2JqZWN0X0dldEF0dHJTdHJpbmcobywgbmFtZSk7CisgICAgaWYgKGZ1bmMgPT0gTlVMTCkgeworICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfQXR0cmlidXRlRXJyb3IsIG5hbWUpOworICAgICAgICByZXR1cm4gMDsKKyAgICB9CisKKyAgICBpZiAoIVB5Q2FsbGFibGVfQ2hlY2soZnVuYykpIHsKKyAgICAgICAgdHlwZV9lcnJvcigiYXR0cmlidXRlIG9mIHR5cGUgJyUuMjAwcycgaXMgbm90IGNhbGxhYmxlIiwgZnVuYyk7CisgICAgICAgIGdvdG8gZXhpdDsKKyAgICB9CisKKyAgICBpZiAoZm9ybWF0ICYmICpmb3JtYXQpIHsKKyAgICAgICAgdmFfc3RhcnQodmEsIGZvcm1hdCk7CisgICAgICAgIGFyZ3MgPSBfUHlfVmFCdWlsZFZhbHVlX1NpemVUKGZvcm1hdCwgdmEpOworICAgICAgICB2YV9lbmQodmEpOworICAgIH0KKyAgICBlbHNlCisgICAgICAgIGFyZ3MgPSBQeVR1cGxlX05ldygwKTsKKworICAgIHJldHZhbCA9IGNhbGxfZnVuY3Rpb25fdGFpbChmdW5jLCBhcmdzKTsKKworICBleGl0OgorICAgIC8qIGFyZ3MgZ2V0cyBjb25zdW1lZCBpbiBjYWxsX2Z1bmN0aW9uX3RhaWwgKi8KKyAgICBQeV9YREVDUkVGKGZ1bmMpOworCisgICAgcmV0dXJuIHJldHZhbDsKK30KKworCitzdGF0aWMgUHlPYmplY3QgKgorb2JqYXJnc19ta3R1cGxlKHZhX2xpc3QgdmEpCit7CisgICAgaW50IGksIG4gPSAwOworICAgIHZhX2xpc3QgY291bnR2YTsKKyAgICBQeU9iamVjdCAqcmVzdWx0LCAqdG1wOworCisjaWZkZWYgVkFfTElTVF9JU19BUlJBWQorICAgIG1lbWNweShjb3VudHZhLCB2YSwgc2l6ZW9mKHZhX2xpc3QpKTsKKyNlbHNlCisjaWZkZWYgX192YV9jb3B5CisgICAgX192YV9jb3B5KGNvdW50dmEsIHZhKTsKKyNlbHNlCisgICAgY291bnR2YSA9IHZhOworI2VuZGlmCisjZW5kaWYKKworICAgIHdoaWxlICgoKFB5T2JqZWN0ICopdmFfYXJnKGNvdW50dmEsIFB5T2JqZWN0ICopKSAhPSBOVUxMKQorICAgICAgICArK247CisgICAgcmVzdWx0ID0gUHlUdXBsZV9OZXcobik7CisgICAgaWYgKHJlc3VsdCAhPSBOVUxMICYmIG4gPiAwKSB7CisgICAgICAgIGZvciAoaSA9IDA7IGkgPCBuOyArK2kpIHsKKyAgICAgICAgICAgIHRtcCA9IChQeU9iamVjdCAqKXZhX2FyZyh2YSwgUHlPYmplY3QgKik7CisgICAgICAgICAgICBQeVR1cGxlX1NFVF9JVEVNKHJlc3VsdCwgaSwgdG1wKTsKKyAgICAgICAgICAgIFB5X0lOQ1JFRih0bXApOworICAgICAgICB9CisgICAgfQorICAgIHJldHVybiByZXN1bHQ7Cit9CisKK1B5T2JqZWN0ICoKK1B5T2JqZWN0X0NhbGxNZXRob2RPYmpBcmdzKFB5T2JqZWN0ICpjYWxsYWJsZSwgUHlPYmplY3QgKm5hbWUsIC4uLikKK3sKKyAgICBQeU9iamVjdCAqYXJncywgKnRtcDsKKyAgICB2YV9saXN0IHZhcmdzOworCisgICAgaWYgKGNhbGxhYmxlID09IE5VTEwgfHwgbmFtZSA9PSBOVUxMKQorICAgICAgICByZXR1cm4gbnVsbF9lcnJvcigpOworCisgICAgY2FsbGFibGUgPSBQeU9iamVjdF9HZXRBdHRyKGNhbGxhYmxlLCBuYW1lKTsKKyAgICBpZiAoY2FsbGFibGUgPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisKKyAgICAvKiBjb3VudCB0aGUgYXJncyAqLworICAgIHZhX3N0YXJ0KHZhcmdzLCBuYW1lKTsKKyAgICBhcmdzID0gb2JqYXJnc19ta3R1cGxlKHZhcmdzKTsKKyAgICB2YV9lbmQodmFyZ3MpOworICAgIGlmIChhcmdzID09IE5VTEwpIHsKKyAgICAgICAgUHlfREVDUkVGKGNhbGxhYmxlKTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIHRtcCA9IFB5T2JqZWN0X0NhbGwoY2FsbGFibGUsIGFyZ3MsIE5VTEwpOworICAgIFB5X0RFQ1JFRihhcmdzKTsKKyAgICBQeV9ERUNSRUYoY2FsbGFibGUpOworCisgICAgcmV0dXJuIHRtcDsKK30KKworUHlPYmplY3QgKgorUHlPYmplY3RfQ2FsbEZ1bmN0aW9uT2JqQXJncyhQeU9iamVjdCAqY2FsbGFibGUsIC4uLikKK3sKKyAgICBQeU9iamVjdCAqYXJncywgKnRtcDsKKyAgICB2YV9saXN0IHZhcmdzOworCisgICAgaWYgKGNhbGxhYmxlID09IE5VTEwpCisgICAgICAgIHJldHVybiBudWxsX2Vycm9yKCk7CisKKyAgICAvKiBjb3VudCB0aGUgYXJncyAqLworICAgIHZhX3N0YXJ0KHZhcmdzLCBjYWxsYWJsZSk7CisgICAgYXJncyA9IG9iamFyZ3NfbWt0dXBsZSh2YXJncyk7CisgICAgdmFfZW5kKHZhcmdzKTsKKyAgICBpZiAoYXJncyA9PSBOVUxMKQorICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB0bXAgPSBQeU9iamVjdF9DYWxsKGNhbGxhYmxlLCBhcmdzLCBOVUxMKTsKKyAgICBQeV9ERUNSRUYoYXJncyk7CisKKyAgICByZXR1cm4gdG1wOworfQorCisKKy8qIGlzaW5zdGFuY2UoKSwgaXNzdWJjbGFzcygpICovCisKKy8qIGFic3RyYWN0X2dldF9iYXNlcygpIGhhcyBsb2dpY2FsbHkgNCByZXR1cm4gc3RhdGVzLCB3aXRoIGEgc29ydCBvZiAwdGgKKyAqIHN0YXRlIHRoYXQgd2lsbCBhbG1vc3QgbmV2ZXIgaGFwcGVuLgorICoKKyAqIDAuIGNyZWF0aW5nIHRoZSBfX2Jhc2VzX18gc3RhdGljIHN0cmluZyBjb3VsZCBnZXQgYSBNZW1vcnlFcnJvcgorICogMS4gZ2V0YXR0cihjbHMsICdfX2Jhc2VzX18nKSBjb3VsZCByYWlzZSBhbiBBdHRyaWJ1dGVFcnJvcgorICogMi4gZ2V0YXR0cihjbHMsICdfX2Jhc2VzX18nKSBjb3VsZCByYWlzZSBzb21lIG90aGVyIGV4Y2VwdGlvbgorICogMy4gZ2V0YXR0cihjbHMsICdfX2Jhc2VzX18nKSBjb3VsZCByZXR1cm4gYSB0dXBsZQorICogNC4gZ2V0YXR0cihjbHMsICdfX2Jhc2VzX18nKSBjb3VsZCByZXR1cm4gc29tZXRoaW5nIG90aGVyIHRoYW4gYSB0dXBsZQorICoKKyAqIE9ubHkgc3RhdGUgIzMgaXMgYSBub24tZXJyb3Igc3RhdGUgYW5kIG9ubHkgaXQgcmV0dXJucyBhIG5vbi1OVUxMIG9iamVjdAorICogKGl0IHJldHVybnMgdGhlIHJldHJpZXZlZCB0dXBsZSkuCisgKgorICogQW55IHJhaXNlZCBBdHRyaWJ1dGVFcnJvcnMgYXJlIG1hc2tlZCBieSBjbGVhcmluZyB0aGUgZXhjZXB0aW9uIGFuZAorICogcmV0dXJuaW5nIE5VTEwuICBJZiBhbiBvYmplY3Qgb3RoZXIgdGhhbiBhIHR1cGxlIGNvbWVzIG91dCBvZiBfX2Jhc2VzX18sCisgKiB0aGVuIGFnYWluLCB0aGUgcmV0dXJuIHZhbHVlIGlzIE5VTEwuICBTbyB5ZXMsIHRoZXNlIHR3byBzaXR1YXRpb25zCisgKiBwcm9kdWNlIGV4YWN0bHkgdGhlIHNhbWUgcmVzdWx0czogTlVMTCBpcyByZXR1cm5lZCBhbmQgbm8gZXJyb3IgaXMgc2V0LgorICoKKyAqIElmIHNvbWUgZXhjZXB0aW9uIG90aGVyIHRoYW4gQXR0cmlidXRlRXJyb3IgaXMgcmFpc2VkLCB0aGVuIE5VTEwgaXMgYWxzbworICogcmV0dXJuZWQsIGJ1dCB0aGUgZXhjZXB0aW9uIGlzIG5vdCBjbGVhcmVkLiAgVGhhdCdzIGJlY2F1c2Ugd2Ugd2FudCB0aGUKKyAqIGV4Y2VwdGlvbiB0byBiZSBwcm9wYWdhdGVkIGFsb25nLgorICoKKyAqIENhbGxlcnMgYXJlIGV4cGVjdGVkIHRvIHRlc3QgZm9yIFB5RXJyX09jY3VycmVkKCkgd2hlbiB0aGUgcmV0dXJuIHZhbHVlCisgKiBpcyBOVUxMIHRvIGRlY2lkZSB3aGV0aGVyIGEgdmFsaWQgZXhjZXB0aW9uIHNob3VsZCBiZSBwcm9wYWdhdGVkIG9yIG5vdC4KKyAqIFdoZW4gdGhlcmUncyBubyBleGNlcHRpb24gdG8gcHJvcGFnYXRlLCBpdCdzIGN1c3RvbWFyeSBmb3IgdGhlIGNhbGxlciB0bworICogc2V0IGEgVHlwZUVycm9yLgorICovCitzdGF0aWMgUHlPYmplY3QgKgorYWJzdHJhY3RfZ2V0X2Jhc2VzKFB5T2JqZWN0ICpjbHMpCit7CisgICAgc3RhdGljIFB5T2JqZWN0ICpfX2Jhc2VzX18gPSBOVUxMOworICAgIFB5T2JqZWN0ICpiYXNlczsKKworICAgIGlmIChfX2Jhc2VzX18gPT0gTlVMTCkgeworICAgICAgICBfX2Jhc2VzX18gPSBQeVN0cmluZ19JbnRlcm5Gcm9tU3RyaW5nKCJfX2Jhc2VzX18iKTsKKyAgICAgICAgaWYgKF9fYmFzZXNfXyA9PSBOVUxMKQorICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIGJhc2VzID0gUHlPYmplY3RfR2V0QXR0cihjbHMsIF9fYmFzZXNfXyk7CisgICAgaWYgKGJhc2VzID09IE5VTEwpIHsKKyAgICAgICAgaWYgKFB5RXJyX0V4Y2VwdGlvbk1hdGNoZXMoUHlFeGNfQXR0cmlidXRlRXJyb3IpKQorICAgICAgICAgICAgUHlFcnJfQ2xlYXIoKTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIGlmICghUHlUdXBsZV9DaGVjayhiYXNlcykpIHsKKyAgICAgICAgUHlfREVDUkVGKGJhc2VzKTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIHJldHVybiBiYXNlczsKK30KKworCitzdGF0aWMgaW50CithYnN0cmFjdF9pc3N1YmNsYXNzKFB5T2JqZWN0ICpkZXJpdmVkLCBQeU9iamVjdCAqY2xzKQoreworICAgIFB5T2JqZWN0ICpiYXNlcyA9IE5VTEw7CisgICAgUHlfc3NpemVfdCBpLCBuOworICAgIGludCByID0gMDsKKworICAgIHdoaWxlICgxKSB7CisgICAgICAgIGlmIChkZXJpdmVkID09IGNscykKKyAgICAgICAgICAgIHJldHVybiAxOworICAgICAgICBiYXNlcyA9IGFic3RyYWN0X2dldF9iYXNlcyhkZXJpdmVkKTsKKyAgICAgICAgaWYgKGJhc2VzID09IE5VTEwpIHsKKyAgICAgICAgICAgIGlmIChQeUVycl9PY2N1cnJlZCgpKQorICAgICAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICB9CisgICAgICAgIG4gPSBQeVR1cGxlX0dFVF9TSVpFKGJhc2VzKTsKKyAgICAgICAgaWYgKG4gPT0gMCkgeworICAgICAgICAgICAgUHlfREVDUkVGKGJhc2VzKTsKKyAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICB9CisgICAgICAgIC8qIEF2b2lkIHJlY3Vyc2l2aXR5IGluIHRoZSBzaW5nbGUgaW5oZXJpdGFuY2UgY2FzZSAqLworICAgICAgICBpZiAobiA9PSAxKSB7CisgICAgICAgICAgICBkZXJpdmVkID0gUHlUdXBsZV9HRVRfSVRFTShiYXNlcywgMCk7CisgICAgICAgICAgICBQeV9ERUNSRUYoYmFzZXMpOworICAgICAgICAgICAgY29udGludWU7CisgICAgICAgIH0KKyAgICAgICAgZm9yIChpID0gMDsgaSA8IG47IGkrKykgeworICAgICAgICAgICAgciA9IGFic3RyYWN0X2lzc3ViY2xhc3MoUHlUdXBsZV9HRVRfSVRFTShiYXNlcywgaSksIGNscyk7CisgICAgICAgICAgICBpZiAociAhPSAwKQorICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisgICAgICAgIFB5X0RFQ1JFRihiYXNlcyk7CisgICAgICAgIHJldHVybiByOworICAgIH0KK30KKworc3RhdGljIGludAorY2hlY2tfY2xhc3MoUHlPYmplY3QgKmNscywgY29uc3QgY2hhciAqZXJyb3IpCit7CisgICAgUHlPYmplY3QgKmJhc2VzID0gYWJzdHJhY3RfZ2V0X2Jhc2VzKGNscyk7CisgICAgaWYgKGJhc2VzID09IE5VTEwpIHsKKyAgICAgICAgLyogRG8gbm90IG1hc2sgZXJyb3JzLiAqLworICAgICAgICBpZiAoIVB5RXJyX09jY3VycmVkKCkpCisgICAgICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfVHlwZUVycm9yLCBlcnJvcik7CisgICAgICAgIHJldHVybiAwOworICAgIH0KKyAgICBQeV9ERUNSRUYoYmFzZXMpOworICAgIHJldHVybiAtMTsKK30KKworc3RhdGljIGludAorcmVjdXJzaXZlX2lzaW5zdGFuY2UoUHlPYmplY3QgKmluc3QsIFB5T2JqZWN0ICpjbHMpCit7CisgICAgUHlPYmplY3QgKmljbHM7CisgICAgc3RhdGljIFB5T2JqZWN0ICpfX2NsYXNzX18gPSBOVUxMOworICAgIGludCByZXR2YWwgPSAwOworCisgICAgaWYgKF9fY2xhc3NfXyA9PSBOVUxMKSB7CisgICAgICAgIF9fY2xhc3NfXyA9IFB5U3RyaW5nX0ludGVybkZyb21TdHJpbmcoIl9fY2xhc3NfXyIpOworICAgICAgICBpZiAoX19jbGFzc19fID09IE5VTEwpCisgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgfQorCisgICAgaWYgKFB5Q2xhc3NfQ2hlY2soY2xzKSAmJiBQeUluc3RhbmNlX0NoZWNrKGluc3QpKSB7CisgICAgICAgIFB5T2JqZWN0ICppbmNsYXNzID0KKyAgICAgICAgICAgIChQeU9iamVjdCopKChQeUluc3RhbmNlT2JqZWN0KilpbnN0KS0+aW5fY2xhc3M7CisgICAgICAgIHJldHZhbCA9IFB5Q2xhc3NfSXNTdWJjbGFzcyhpbmNsYXNzLCBjbHMpOworICAgIH0KKyAgICBlbHNlIGlmIChQeVR5cGVfQ2hlY2soY2xzKSkgeworICAgICAgICByZXR2YWwgPSBQeU9iamVjdF9UeXBlQ2hlY2soaW5zdCwgKFB5VHlwZU9iamVjdCAqKWNscyk7CisgICAgICAgIGlmIChyZXR2YWwgPT0gMCkgeworICAgICAgICAgICAgUHlPYmplY3QgKmMgPSBQeU9iamVjdF9HZXRBdHRyKGluc3QsIF9fY2xhc3NfXyk7CisgICAgICAgICAgICBpZiAoYyA9PSBOVUxMKSB7CisgICAgICAgICAgICAgICAgUHlFcnJfQ2xlYXIoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGVsc2UgeworICAgICAgICAgICAgICAgIGlmIChjICE9IChQeU9iamVjdCAqKShpbnN0LT5vYl90eXBlKSAmJgorICAgICAgICAgICAgICAgICAgICBQeVR5cGVfQ2hlY2soYykpCisgICAgICAgICAgICAgICAgICAgIHJldHZhbCA9IFB5VHlwZV9Jc1N1YnR5cGUoCisgICAgICAgICAgICAgICAgICAgICAgICAoUHlUeXBlT2JqZWN0ICopYywKKyAgICAgICAgICAgICAgICAgICAgICAgIChQeVR5cGVPYmplY3QgKiljbHMpOworICAgICAgICAgICAgICAgIFB5X0RFQ1JFRihjKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKyAgICBlbHNlIHsKKyAgICAgICAgaWYgKCFjaGVja19jbGFzcyhjbHMsCisgICAgICAgICAgICAiaXNpbnN0YW5jZSgpIGFyZyAyIG11c3QgYmUgYSBjbGFzcywgdHlwZSwiCisgICAgICAgICAgICAiIG9yIHR1cGxlIG9mIGNsYXNzZXMgYW5kIHR5cGVzIikpCisgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgIGljbHMgPSBQeU9iamVjdF9HZXRBdHRyKGluc3QsIF9fY2xhc3NfXyk7CisgICAgICAgIGlmIChpY2xzID09IE5VTEwpIHsKKyAgICAgICAgICAgIFB5RXJyX0NsZWFyKCk7CisgICAgICAgICAgICByZXR2YWwgPSAwOworICAgICAgICB9CisgICAgICAgIGVsc2UgeworICAgICAgICAgICAgcmV0dmFsID0gYWJzdHJhY3RfaXNzdWJjbGFzcyhpY2xzLCBjbHMpOworICAgICAgICAgICAgUHlfREVDUkVGKGljbHMpOworICAgICAgICB9CisgICAgfQorCisgICAgcmV0dXJuIHJldHZhbDsKK30KKworaW50CitQeU9iamVjdF9Jc0luc3RhbmNlKFB5T2JqZWN0ICppbnN0LCBQeU9iamVjdCAqY2xzKQoreworICAgIHN0YXRpYyBQeU9iamVjdCAqbmFtZSA9IE5VTEw7CisKKyAgICAvKiBRdWljayB0ZXN0IGZvciBhbiBleGFjdCBtYXRjaCAqLworICAgIGlmIChQeV9UWVBFKGluc3QpID09IChQeVR5cGVPYmplY3QgKiljbHMpCisgICAgICAgIHJldHVybiAxOworCisgICAgaWYgKFB5VHVwbGVfQ2hlY2soY2xzKSkgeworICAgICAgICBQeV9zc2l6ZV90IGk7CisgICAgICAgIFB5X3NzaXplX3QgbjsKKyAgICAgICAgaW50IHIgPSAwOworCisgICAgICAgIGlmIChQeV9FbnRlclJlY3Vyc2l2ZUNhbGwoIiBpbiBfX2luc3RhbmNlY2hlY2tfXyIpKQorICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICBuID0gUHlUdXBsZV9HRVRfU0laRShjbHMpOworICAgICAgICBmb3IgKGkgPSAwOyBpIDwgbjsgKytpKSB7CisgICAgICAgICAgICBQeU9iamVjdCAqaXRlbSA9IFB5VHVwbGVfR0VUX0lURU0oY2xzLCBpKTsKKyAgICAgICAgICAgIHIgPSBQeU9iamVjdF9Jc0luc3RhbmNlKGluc3QsIGl0ZW0pOworICAgICAgICAgICAgaWYgKHIgIT0gMCkKKyAgICAgICAgICAgICAgICAvKiBlaXRoZXIgZm91bmQgaXQsIG9yIGdvdCBhbiBlcnJvciAqLworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisgICAgICAgIFB5X0xlYXZlUmVjdXJzaXZlQ2FsbCgpOworICAgICAgICByZXR1cm4gcjsKKyAgICB9CisKKyAgICBpZiAoIShQeUNsYXNzX0NoZWNrKGNscykgfHwgUHlJbnN0YW5jZV9DaGVjayhjbHMpKSkgeworICAgICAgICBQeU9iamVjdCAqY2hlY2tlcjsKKyAgICAgICAgY2hlY2tlciA9IF9QeU9iamVjdF9Mb29rdXBTcGVjaWFsKGNscywgIl9faW5zdGFuY2VjaGVja19fIiwgJm5hbWUpOworICAgICAgICBpZiAoY2hlY2tlciAhPSBOVUxMKSB7CisgICAgICAgICAgICBQeU9iamVjdCAqcmVzOworICAgICAgICAgICAgaW50IG9rID0gLTE7CisgICAgICAgICAgICBpZiAoUHlfRW50ZXJSZWN1cnNpdmVDYWxsKCIgaW4gX19pbnN0YW5jZWNoZWNrX18iKSkgeworICAgICAgICAgICAgICAgIFB5X0RFQ1JFRihjaGVja2VyKTsKKyAgICAgICAgICAgICAgICByZXR1cm4gb2s7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXMgPSBQeU9iamVjdF9DYWxsRnVuY3Rpb25PYmpBcmdzKGNoZWNrZXIsIGluc3QsIE5VTEwpOworICAgICAgICAgICAgUHlfTGVhdmVSZWN1cnNpdmVDYWxsKCk7CisgICAgICAgICAgICBQeV9ERUNSRUYoY2hlY2tlcik7CisgICAgICAgICAgICBpZiAocmVzICE9IE5VTEwpIHsKKyAgICAgICAgICAgICAgICBvayA9IFB5T2JqZWN0X0lzVHJ1ZShyZXMpOworICAgICAgICAgICAgICAgIFB5X0RFQ1JFRihyZXMpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIG9rOworICAgICAgICB9CisgICAgICAgIGVsc2UgaWYgKFB5RXJyX09jY3VycmVkKCkpCisgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgfQorICAgIHJldHVybiByZWN1cnNpdmVfaXNpbnN0YW5jZShpbnN0LCBjbHMpOworfQorCitzdGF0aWMgIGludAorcmVjdXJzaXZlX2lzc3ViY2xhc3MoUHlPYmplY3QgKmRlcml2ZWQsIFB5T2JqZWN0ICpjbHMpCit7CisgICAgaW50IHJldHZhbDsKKworICAgIGlmIChQeVR5cGVfQ2hlY2soY2xzKSAmJiBQeVR5cGVfQ2hlY2soZGVyaXZlZCkpIHsKKyAgICAgICAgLyogRmFzdCBwYXRoIChub24tcmVjdXJzaXZlKSAqLworICAgICAgICByZXR1cm4gUHlUeXBlX0lzU3VidHlwZSgKKyAgICAgICAgICAgIChQeVR5cGVPYmplY3QgKilkZXJpdmVkLCAoUHlUeXBlT2JqZWN0ICopY2xzKTsKKyAgICB9CisgICAgaWYgKCFQeUNsYXNzX0NoZWNrKGRlcml2ZWQpIHx8ICFQeUNsYXNzX0NoZWNrKGNscykpIHsKKyAgICAgICAgaWYgKCFjaGVja19jbGFzcyhkZXJpdmVkLAorICAgICAgICAgICAgICAgICAgICAgICAgICJpc3N1YmNsYXNzKCkgYXJnIDEgbXVzdCBiZSBhIGNsYXNzIikpCisgICAgICAgICAgICByZXR1cm4gLTE7CisKKyAgICAgICAgaWYgKCFjaGVja19jbGFzcyhjbHMsCisgICAgICAgICAgICAgICAgICAgICAgICAiaXNzdWJjbGFzcygpIGFyZyAyIG11c3QgYmUgYSBjbGFzcyIKKyAgICAgICAgICAgICAgICAgICAgICAgICIgb3IgdHVwbGUgb2YgY2xhc3NlcyIpKQorICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICByZXR2YWwgPSBhYnN0cmFjdF9pc3N1YmNsYXNzKGRlcml2ZWQsIGNscyk7CisgICAgfQorICAgIGVsc2UgeworICAgICAgICAvKiBzaG9ydGN1dCAqLworICAgICAgICBpZiAoIShyZXR2YWwgPSAoZGVyaXZlZCA9PSBjbHMpKSkKKyAgICAgICAgICAgIHJldHZhbCA9IFB5Q2xhc3NfSXNTdWJjbGFzcyhkZXJpdmVkLCBjbHMpOworICAgIH0KKworICAgIHJldHVybiByZXR2YWw7Cit9CisKK2ludAorUHlPYmplY3RfSXNTdWJjbGFzcyhQeU9iamVjdCAqZGVyaXZlZCwgUHlPYmplY3QgKmNscykKK3sKKyAgICBzdGF0aWMgUHlPYmplY3QgKm5hbWUgPSBOVUxMOworCisgICAgaWYgKFB5VHVwbGVfQ2hlY2soY2xzKSkgeworICAgICAgICBQeV9zc2l6ZV90IGk7CisgICAgICAgIFB5X3NzaXplX3QgbjsKKyAgICAgICAgaW50IHIgPSAwOworCisgICAgICAgIGlmIChQeV9FbnRlclJlY3Vyc2l2ZUNhbGwoIiBpbiBfX3N1YmNsYXNzY2hlY2tfXyIpKQorICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICBuID0gUHlUdXBsZV9HRVRfU0laRShjbHMpOworICAgICAgICBmb3IgKGkgPSAwOyBpIDwgbjsgKytpKSB7CisgICAgICAgICAgICBQeU9iamVjdCAqaXRlbSA9IFB5VHVwbGVfR0VUX0lURU0oY2xzLCBpKTsKKyAgICAgICAgICAgIHIgPSBQeU9iamVjdF9Jc1N1YmNsYXNzKGRlcml2ZWQsIGl0ZW0pOworICAgICAgICAgICAgaWYgKHIgIT0gMCkKKyAgICAgICAgICAgICAgICAvKiBlaXRoZXIgZm91bmQgaXQsIG9yIGdvdCBhbiBlcnJvciAqLworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisgICAgICAgIFB5X0xlYXZlUmVjdXJzaXZlQ2FsbCgpOworICAgICAgICByZXR1cm4gcjsKKyAgICB9CisgICAgaWYgKCEoUHlDbGFzc19DaGVjayhjbHMpIHx8IFB5SW5zdGFuY2VfQ2hlY2soY2xzKSkpIHsKKyAgICAgICAgUHlPYmplY3QgKmNoZWNrZXI7CisgICAgICAgIGNoZWNrZXIgPSBfUHlPYmplY3RfTG9va3VwU3BlY2lhbChjbHMsICJfX3N1YmNsYXNzY2hlY2tfXyIsICZuYW1lKTsKKyAgICAgICAgaWYgKGNoZWNrZXIgIT0gTlVMTCkgeworICAgICAgICAgICAgUHlPYmplY3QgKnJlczsKKyAgICAgICAgICAgIGludCBvayA9IC0xOworICAgICAgICAgICAgaWYgKFB5X0VudGVyUmVjdXJzaXZlQ2FsbCgiIGluIF9fc3ViY2xhc3NjaGVja19fIikpIHsKKyAgICAgICAgICAgICAgICBQeV9ERUNSRUYoY2hlY2tlcik7CisgICAgICAgICAgICAgICAgcmV0dXJuIG9rOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmVzID0gUHlPYmplY3RfQ2FsbEZ1bmN0aW9uT2JqQXJncyhjaGVja2VyLCBkZXJpdmVkLCBOVUxMKTsKKyAgICAgICAgICAgIFB5X0xlYXZlUmVjdXJzaXZlQ2FsbCgpOworICAgICAgICAgICAgUHlfREVDUkVGKGNoZWNrZXIpOworICAgICAgICAgICAgaWYgKHJlcyAhPSBOVUxMKSB7CisgICAgICAgICAgICAgICAgb2sgPSBQeU9iamVjdF9Jc1RydWUocmVzKTsKKyAgICAgICAgICAgICAgICBQeV9ERUNSRUYocmVzKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBvazsKKyAgICAgICAgfQorICAgICAgICBlbHNlIGlmIChQeUVycl9PY2N1cnJlZCgpKSB7CisgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgIH0KKyAgICB9CisgICAgcmV0dXJuIHJlY3Vyc2l2ZV9pc3N1YmNsYXNzKGRlcml2ZWQsIGNscyk7Cit9CisKK2ludAorX1B5T2JqZWN0X1JlYWxJc0luc3RhbmNlKFB5T2JqZWN0ICppbnN0LCBQeU9iamVjdCAqY2xzKQoreworICAgIHJldHVybiByZWN1cnNpdmVfaXNpbnN0YW5jZShpbnN0LCBjbHMpOworfQorCitpbnQKK19QeU9iamVjdF9SZWFsSXNTdWJjbGFzcyhQeU9iamVjdCAqZGVyaXZlZCwgUHlPYmplY3QgKmNscykKK3sKKyAgICByZXR1cm4gcmVjdXJzaXZlX2lzc3ViY2xhc3MoZGVyaXZlZCwgY2xzKTsKK30KKworCitQeU9iamVjdCAqCitQeU9iamVjdF9HZXRJdGVyKFB5T2JqZWN0ICpvKQoreworICAgIFB5VHlwZU9iamVjdCAqdCA9IG8tPm9iX3R5cGU7CisgICAgZ2V0aXRlcmZ1bmMgZiA9IE5VTEw7CisgICAgaWYgKFB5VHlwZV9IYXNGZWF0dXJlKHQsIFB5X1RQRkxBR1NfSEFWRV9JVEVSKSkKKyAgICAgICAgZiA9IHQtPnRwX2l0ZXI7CisgICAgaWYgKGYgPT0gTlVMTCkgeworICAgICAgICBpZiAoUHlTZXF1ZW5jZV9DaGVjayhvKSkKKyAgICAgICAgICAgIHJldHVybiBQeVNlcUl0ZXJfTmV3KG8pOworICAgICAgICByZXR1cm4gdHlwZV9lcnJvcigiJyUuMjAwcycgb2JqZWN0IGlzIG5vdCBpdGVyYWJsZSIsIG8pOworICAgIH0KKyAgICBlbHNlIHsKKyAgICAgICAgUHlPYmplY3QgKnJlcyA9ICgqZikobyk7CisgICAgICAgIGlmIChyZXMgIT0gTlVMTCAmJiAhUHlJdGVyX0NoZWNrKHJlcykpIHsKKyAgICAgICAgICAgIFB5RXJyX0Zvcm1hdChQeUV4Y19UeXBlRXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgIml0ZXIoKSByZXR1cm5lZCBub24taXRlcmF0b3IgIgorICAgICAgICAgICAgICAgICAgICAgICAgICJvZiB0eXBlICclLjEwMHMnIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICByZXMtPm9iX3R5cGUtPnRwX25hbWUpOworICAgICAgICAgICAgUHlfREVDUkVGKHJlcyk7CisgICAgICAgICAgICByZXMgPSBOVUxMOworICAgICAgICB9CisgICAgICAgIHJldHVybiByZXM7CisgICAgfQorfQorCisvKiBSZXR1cm4gbmV4dCBpdGVtLgorICogSWYgYW4gZXJyb3Igb2NjdXJzLCByZXR1cm4gTlVMTC4gIFB5RXJyX09jY3VycmVkKCkgd2lsbCBiZSB0cnVlLgorICogSWYgdGhlIGl0ZXJhdGlvbiB0ZXJtaW5hdGVzIG5vcm1hbGx5LCByZXR1cm4gTlVMTCBhbmQgY2xlYXIgdGhlCisgKiBQeUV4Y19TdG9wSXRlcmF0aW9uIGV4Y2VwdGlvbiAoaWYgaXQgd2FzIHNldCkuICBQeUVycl9PY2N1cnJlZCgpCisgKiB3aWxsIGJlIGZhbHNlLgorICogRWxzZSByZXR1cm4gdGhlIG5leHQgb2JqZWN0LiAgUHlFcnJfT2NjdXJyZWQoKSB3aWxsIGJlIGZhbHNlLgorICovCitQeU9iamVjdCAqCitQeUl0ZXJfTmV4dChQeU9iamVjdCAqaXRlcikKK3sKKyAgICBQeU9iamVjdCAqcmVzdWx0OworICAgIHJlc3VsdCA9ICgqaXRlci0+b2JfdHlwZS0+dHBfaXRlcm5leHQpKGl0ZXIpOworICAgIGlmIChyZXN1bHQgPT0gTlVMTCAmJgorICAgICAgICBQeUVycl9PY2N1cnJlZCgpICYmCisgICAgICAgIFB5RXJyX0V4Y2VwdGlvbk1hdGNoZXMoUHlFeGNfU3RvcEl0ZXJhdGlvbikpCisgICAgICAgIFB5RXJyX0NsZWFyKCk7CisgICAgcmV0dXJuIHJlc3VsdDsKK30KZGlmZiAtLWdpdCBhL1B5dGhvbi0yLjcuNS9PYmplY3RzL2Jvb2xvYmplY3QuYyBiL1B5dGhvbi0yLjcuNS9PYmplY3RzL2Jvb2xvYmplY3QuYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41OTU4MzJhCi0tLSAvZGV2L251bGwKKysrIGIvUHl0aG9uLTIuNy41L09iamVjdHMvYm9vbG9iamVjdC5jCkBAIC0wLDAgKzEsMjAyIEBACisvKiBCb29sZWFuIHR5cGUsIGEgc3VidHlwZSBvZiBpbnQgKi8KKworI2luY2x1ZGUgIlB5dGhvbi5oIgorCisvKiBXZSBuZWVkIHRvIGRlZmluZSBib29sX3ByaW50IHRvIG92ZXJyaWRlIGludF9wcmludCAqLworCitzdGF0aWMgaW50Citib29sX3ByaW50KFB5Qm9vbE9iamVjdCAqc2VsZiwgRklMRSAqZnAsIGludCBmbGFncykKK3sKKyAgICBQeV9CRUdJTl9BTExPV19USFJFQURTCisgICAgZnB1dHMoc2VsZi0+b2JfaXZhbCA9PSAwID8gIkZhbHNlIiA6ICJUcnVlIiwgZnApOworICAgIFB5X0VORF9BTExPV19USFJFQURTCisgICAgcmV0dXJuIDA7Cit9CisKKy8qIFdlIGRlZmluZSBib29sX3JlcHIgdG8gcmV0dXJuICJGYWxzZSIgb3IgIlRydWUiICovCisKK3N0YXRpYyBQeU9iamVjdCAqZmFsc2Vfc3RyID0gTlVMTDsKK3N0YXRpYyBQeU9iamVjdCAqdHJ1ZV9zdHIgPSBOVUxMOworCitzdGF0aWMgUHlPYmplY3QgKgorYm9vbF9yZXByKFB5Qm9vbE9iamVjdCAqc2VsZikKK3sKKyAgICBQeU9iamVjdCAqczsKKworICAgIGlmIChzZWxmLT5vYl9pdmFsKQorICAgICAgICBzID0gdHJ1ZV9zdHIgPyB0cnVlX3N0ciA6CisgICAgICAgICAgICAodHJ1ZV9zdHIgPSBQeVN0cmluZ19JbnRlcm5Gcm9tU3RyaW5nKCJUcnVlIikpOworICAgIGVsc2UKKyAgICAgICAgcyA9IGZhbHNlX3N0ciA/IGZhbHNlX3N0ciA6CisgICAgICAgICAgICAoZmFsc2Vfc3RyID0gUHlTdHJpbmdfSW50ZXJuRnJvbVN0cmluZygiRmFsc2UiKSk7CisgICAgUHlfWElOQ1JFRihzKTsKKyAgICByZXR1cm4gczsKK30KKworLyogRnVuY3Rpb24gdG8gcmV0dXJuIGEgYm9vbCBmcm9tIGEgQyBsb25nICovCisKK1B5T2JqZWN0ICpQeUJvb2xfRnJvbUxvbmcobG9uZyBvaykKK3sKKyAgICBQeU9iamVjdCAqcmVzdWx0OworCisgICAgaWYgKG9rKQorICAgICAgICByZXN1bHQgPSBQeV9UcnVlOworICAgIGVsc2UKKyAgICAgICAgcmVzdWx0ID0gUHlfRmFsc2U7CisgICAgUHlfSU5DUkVGKHJlc3VsdCk7CisgICAgcmV0dXJuIHJlc3VsdDsKK30KKworLyogV2UgZGVmaW5lIGJvb2xfbmV3IHRvIGFsd2F5cyByZXR1cm4gZWl0aGVyIFB5X1RydWUgb3IgUHlfRmFsc2UgKi8KKworc3RhdGljIFB5T2JqZWN0ICoKK2Jvb2xfbmV3KFB5VHlwZU9iamVjdCAqdHlwZSwgUHlPYmplY3QgKmFyZ3MsIFB5T2JqZWN0ICprd2RzKQoreworICAgIHN0YXRpYyBjaGFyICprd2xpc3RbXSA9IHsieCIsIDB9OworICAgIFB5T2JqZWN0ICp4ID0gUHlfRmFsc2U7CisgICAgbG9uZyBvazsKKworICAgIGlmICghUHlBcmdfUGFyc2VUdXBsZUFuZEtleXdvcmRzKGFyZ3MsIGt3ZHMsICJ8Tzpib29sIiwga3dsaXN0LCAmeCkpCisgICAgICAgIHJldHVybiBOVUxMOworICAgIG9rID0gUHlPYmplY3RfSXNUcnVlKHgpOworICAgIGlmIChvayA8IDApCisgICAgICAgIHJldHVybiBOVUxMOworICAgIHJldHVybiBQeUJvb2xfRnJvbUxvbmcob2spOworfQorCisvKiBBcml0aG1ldGljIG9wZXJhdGlvbnMgcmVkZWZpbmVkIHRvIHJldHVybiBib29sIGlmIGJvdGggYXJncyBhcmUgYm9vbC4gKi8KKworc3RhdGljIFB5T2JqZWN0ICoKK2Jvb2xfYW5kKFB5T2JqZWN0ICphLCBQeU9iamVjdCAqYikKK3sKKyAgICBpZiAoIVB5Qm9vbF9DaGVjayhhKSB8fCAhUHlCb29sX0NoZWNrKGIpKQorICAgICAgICByZXR1cm4gUHlJbnRfVHlwZS50cF9hc19udW1iZXItPm5iX2FuZChhLCBiKTsKKyAgICByZXR1cm4gUHlCb29sX0Zyb21Mb25nKAorICAgICAgICAoKFB5Qm9vbE9iamVjdCAqKWEpLT5vYl9pdmFsICYgKChQeUJvb2xPYmplY3QgKiliKS0+b2JfaXZhbCk7Cit9CisKK3N0YXRpYyBQeU9iamVjdCAqCitib29sX29yKFB5T2JqZWN0ICphLCBQeU9iamVjdCAqYikKK3sKKyAgICBpZiAoIVB5Qm9vbF9DaGVjayhhKSB8fCAhUHlCb29sX0NoZWNrKGIpKQorICAgICAgICByZXR1cm4gUHlJbnRfVHlwZS50cF9hc19udW1iZXItPm5iX29yKGEsIGIpOworICAgIHJldHVybiBQeUJvb2xfRnJvbUxvbmcoCisgICAgICAgICgoUHlCb29sT2JqZWN0ICopYSktPm9iX2l2YWwgfCAoKFB5Qm9vbE9iamVjdCAqKWIpLT5vYl9pdmFsKTsKK30KKworc3RhdGljIFB5T2JqZWN0ICoKK2Jvb2xfeG9yKFB5T2JqZWN0ICphLCBQeU9iamVjdCAqYikKK3sKKyAgICBpZiAoIVB5Qm9vbF9DaGVjayhhKSB8fCAhUHlCb29sX0NoZWNrKGIpKQorICAgICAgICByZXR1cm4gUHlJbnRfVHlwZS50cF9hc19udW1iZXItPm5iX3hvcihhLCBiKTsKKyAgICByZXR1cm4gUHlCb29sX0Zyb21Mb25nKAorICAgICAgICAoKFB5Qm9vbE9iamVjdCAqKWEpLT5vYl9pdmFsIF4gKChQeUJvb2xPYmplY3QgKiliKS0+b2JfaXZhbCk7Cit9CisKKy8qIERvYyBzdHJpbmcgKi8KKworUHlEb2NfU1RSVkFSKGJvb2xfZG9jLAorImJvb2woeCkgLT4gYm9vbFxuXAorXG5cCitSZXR1cm5zIFRydWUgd2hlbiB0aGUgYXJndW1lbnQgeCBpcyB0cnVlLCBGYWxzZSBvdGhlcndpc2UuXG5cCitUaGUgYnVpbHRpbnMgVHJ1ZSBhbmQgRmFsc2UgYXJlIHRoZSBvbmx5IHR3byBpbnN0YW5jZXMgb2YgdGhlIGNsYXNzIGJvb2wuXG5cCitUaGUgY2xhc3MgYm9vbCBpcyBhIHN1YmNsYXNzIG9mIHRoZSBjbGFzcyBpbnQsIGFuZCBjYW5ub3QgYmUgc3ViY2xhc3NlZC4iKTsKKworLyogQXJpdGhtZXRpYyBtZXRob2RzIC0tIG9ubHkgc28gd2UgY2FuIG92ZXJyaWRlICYsIHwsIF4uICovCisKK3N0YXRpYyBQeU51bWJlck1ldGhvZHMgYm9vbF9hc19udW1iZXIgPSB7CisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIG5iX2FkZCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBuYl9zdWJ0cmFjdCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBuYl9tdWx0aXBseSAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBuYl9kaXZpZGUgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgLyogbmJfcmVtYWluZGVyICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIG5iX2Rpdm1vZCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBuYl9wb3dlciAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBuYl9uZWdhdGl2ZSAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBuYl9wb3NpdGl2ZSAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBuYl9hYnNvbHV0ZSAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBuYl9ub256ZXJvICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIG5iX2ludmVydCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBuYl9sc2hpZnQgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgLyogbmJfcnNoaWZ0ICovCisgICAgYm9vbF9hbmQsICAgICAgICAgICAgICAgICAgIC8qIG5iX2FuZCAqLworICAgIGJvb2xfeG9yLCAgICAgICAgICAgICAgICAgICAvKiBuYl94b3IgKi8KKyAgICBib29sX29yLCAgICAgICAgICAgICAgICAgICAgLyogbmJfb3IgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgLyogbmJfY29lcmNlICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIG5iX2ludCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBuYl9sb25nICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIG5iX2Zsb2F0ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIG5iX29jdCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBuYl9oZXggKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgLyogbmJfaW5wbGFjZV9hZGQgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgLyogbmJfaW5wbGFjZV9zdWJ0cmFjdCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBuYl9pbnBsYWNlX211bHRpcGx5ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIG5iX2lucGxhY2VfZGl2aWRlICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIG5iX2lucGxhY2VfcmVtYWluZGVyICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIG5iX2lucGxhY2VfcG93ZXIgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgLyogbmJfaW5wbGFjZV9sc2hpZnQgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgLyogbmJfaW5wbGFjZV9yc2hpZnQgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgLyogbmJfaW5wbGFjZV9hbmQgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgLyogbmJfaW5wbGFjZV94b3IgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgLyogbmJfaW5wbGFjZV9vciAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBuYl9mbG9vcl9kaXZpZGUgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgLyogbmJfdHJ1ZV9kaXZpZGUgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgLyogbmJfaW5wbGFjZV9mbG9vcl9kaXZpZGUgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgLyogbmJfaW5wbGFjZV90cnVlX2RpdmlkZSAqLworfTsKKworLyogVGhlIHR5cGUgb2JqZWN0IGZvciBib29sLiAgTm90ZSB0aGF0IHRoaXMgY2Fubm90IGJlIHN1YmNsYXNzZWQhICovCisKK1B5VHlwZU9iamVjdCBQeUJvb2xfVHlwZSA9IHsKKyAgICBQeVZhck9iamVjdF9IRUFEX0lOSVQoJlB5VHlwZV9UeXBlLCAwKQorICAgICJib29sIiwKKyAgICBzaXplb2YoUHlJbnRPYmplY3QpLAorICAgIDAsCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9kZWFsbG9jICovCisgICAgKHByaW50ZnVuYylib29sX3ByaW50LCAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9wcmludCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZ2V0YXR0ciAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfc2V0YXR0ciAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfY29tcGFyZSAqLworICAgIChyZXByZnVuYylib29sX3JlcHIsICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfcmVwciAqLworICAgICZib29sX2FzX251bWJlciwgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfYXNfbnVtYmVyICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9hc19zZXF1ZW5jZSAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfYXNfbWFwcGluZyAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfaGFzaCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfY2FsbCAqLworICAgIChyZXByZnVuYylib29sX3JlcHIsICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfc3RyICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9nZXRhdHRybyAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfc2V0YXR0cm8gKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2FzX2J1ZmZlciAqLworICAgIFB5X1RQRkxBR1NfREVGQVVMVCB8IFB5X1RQRkxBR1NfQ0hFQ0tUWVBFUywgLyogdHBfZmxhZ3MgKi8KKyAgICBib29sX2RvYywgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2RvYyAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfdHJhdmVyc2UgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2NsZWFyICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9yaWNoY29tcGFyZSAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfd2Vha2xpc3RvZmZzZXQgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2l0ZXIgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2l0ZXJuZXh0ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9tZXRob2RzICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9tZW1iZXJzICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9nZXRzZXQgKi8KKyAgICAmUHlJbnRfVHlwZSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2Jhc2UgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2RpY3QgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2Rlc2NyX2dldCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZGVzY3Jfc2V0ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9kaWN0b2Zmc2V0ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9pbml0ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9hbGxvYyAqLworICAgIGJvb2xfbmV3LCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfbmV3ICovCit9OworCisvKiBUaGUgb2JqZWN0cyByZXByZXNlbnRpbmcgYm9vbCB2YWx1ZXMgRmFsc2UgYW5kIFRydWUgKi8KKworLyogTmFtZWQgWmVybyBmb3IgbGluay1sZXZlbCBjb21wYXRpYmlsaXR5ICovCitQeUludE9iamVjdCBfUHlfWmVyb1N0cnVjdCA9IHsKKyAgICBQeU9iamVjdF9IRUFEX0lOSVQoJlB5Qm9vbF9UeXBlKQorICAgIDAKK307CisKK1B5SW50T2JqZWN0IF9QeV9UcnVlU3RydWN0ID0geworICAgIFB5T2JqZWN0X0hFQURfSU5JVCgmUHlCb29sX1R5cGUpCisgICAgMQorfTsKZGlmZiAtLWdpdCBhL1B5dGhvbi0yLjcuNS9PYmplY3RzL2J1ZmZlcm9iamVjdC5jIGIvUHl0aG9uLTIuNy41L09iamVjdHMvYnVmZmVyb2JqZWN0LmMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjNiOTdiMgotLS0gL2Rldi9udWxsCisrKyBiL1B5dGhvbi0yLjcuNS9PYmplY3RzL2J1ZmZlcm9iamVjdC5jCkBAIC0wLDAgKzEsODc4IEBACisKKy8qIEJ1ZmZlciBvYmplY3QgaW1wbGVtZW50YXRpb24gKi8KKworI2luY2x1ZGUgIlB5dGhvbi5oIgorCisKK3R5cGVkZWYgc3RydWN0IHsKKyAgICBQeU9iamVjdF9IRUFECisgICAgUHlPYmplY3QgKmJfYmFzZTsKKyAgICB2b2lkICpiX3B0cjsKKyAgICBQeV9zc2l6ZV90IGJfc2l6ZTsKKyAgICBQeV9zc2l6ZV90IGJfb2Zmc2V0OworICAgIGludCBiX3JlYWRvbmx5OworICAgIGxvbmcgYl9oYXNoOworfSBQeUJ1ZmZlck9iamVjdDsKKworCitlbnVtIGJ1ZmZlcl90IHsKKyAgICBSRUFEX0JVRkZFUiwKKyAgICBXUklURV9CVUZGRVIsCisgICAgQ0hBUl9CVUZGRVIsCisgICAgQU5ZX0JVRkZFUgorfTsKKworc3RhdGljIGludAorZ2V0X2J1ZihQeUJ1ZmZlck9iamVjdCAqc2VsZiwgdm9pZCAqKnB0ciwgUHlfc3NpemVfdCAqc2l6ZSwKKyAgICBlbnVtIGJ1ZmZlcl90IGJ1ZmZlcl90eXBlKQoreworICAgIGlmIChzZWxmLT5iX2Jhc2UgPT0gTlVMTCkgeworICAgICAgICBhc3NlcnQgKHB0ciAhPSBOVUxMKTsKKyAgICAgICAgKnB0ciA9IHNlbGYtPmJfcHRyOworICAgICAgICAqc2l6ZSA9IHNlbGYtPmJfc2l6ZTsKKyAgICB9CisgICAgZWxzZSB7CisgICAgICAgIFB5X3NzaXplX3QgY291bnQsIG9mZnNldDsKKyAgICAgICAgcmVhZGJ1ZmZlcnByb2MgcHJvYyA9IDA7CisgICAgICAgIFB5QnVmZmVyUHJvY3MgKmJwID0gc2VsZi0+Yl9iYXNlLT5vYl90eXBlLT50cF9hc19idWZmZXI7CisgICAgICAgIGlmICgoKmJwLT5iZl9nZXRzZWdjb3VudCkoc2VsZi0+Yl9iYXNlLCBOVUxMKSAhPSAxKSB7CisgICAgICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfVHlwZUVycm9yLAorICAgICAgICAgICAgICAgICJzaW5nbGUtc2VnbWVudCBidWZmZXIgb2JqZWN0IGV4cGVjdGVkIik7CisgICAgICAgICAgICByZXR1cm4gMDsKKyAgICAgICAgfQorICAgICAgICBpZiAoKGJ1ZmZlcl90eXBlID09IFJFQURfQlVGRkVSKSB8fAorICAgICAgICAgICAgKChidWZmZXJfdHlwZSA9PSBBTllfQlVGRkVSKSAmJiBzZWxmLT5iX3JlYWRvbmx5KSkKKyAgICAgICAgICAgIHByb2MgPSBicC0+YmZfZ2V0cmVhZGJ1ZmZlcjsKKyAgICAgICAgZWxzZSBpZiAoKGJ1ZmZlcl90eXBlID09IFdSSVRFX0JVRkZFUikgfHwKKyAgICAgICAgICAgIChidWZmZXJfdHlwZSA9PSBBTllfQlVGRkVSKSkKKyAgICAgICAgICAgIHByb2MgPSAocmVhZGJ1ZmZlcnByb2MpYnAtPmJmX2dldHdyaXRlYnVmZmVyOworICAgICAgICBlbHNlIGlmIChidWZmZXJfdHlwZSA9PSBDSEFSX0JVRkZFUikgeworICAgICAgICAgICAgaWYgKCFQeVR5cGVfSGFzRmVhdHVyZShzZWxmLT5vYl90eXBlLAorICAgICAgICAgICAgICAgICAgICAgICAgUHlfVFBGTEFHU19IQVZFX0dFVENIQVJCVUZGRVIpKSB7CisgICAgICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfVHlwZUVycm9yLAorICAgICAgICAgICAgICAgICJQeV9UUEZMQUdTX0hBVkVfR0VUQ0hBUkJVRkZFUiBuZWVkZWQiKTsKKyAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcHJvYyA9IChyZWFkYnVmZmVycHJvYylicC0+YmZfZ2V0Y2hhcmJ1ZmZlcjsKKyAgICAgICAgfQorICAgICAgICBpZiAoIXByb2MpIHsKKyAgICAgICAgICAgIGNoYXIgKmJ1ZmZlcl90eXBlX25hbWU7CisgICAgICAgICAgICBzd2l0Y2ggKGJ1ZmZlcl90eXBlKSB7CisgICAgICAgICAgICBjYXNlIFJFQURfQlVGRkVSOgorICAgICAgICAgICAgICAgIGJ1ZmZlcl90eXBlX25hbWUgPSAicmVhZCI7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICBjYXNlIFdSSVRFX0JVRkZFUjoKKyAgICAgICAgICAgICAgICBidWZmZXJfdHlwZV9uYW1lID0gIndyaXRlIjsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIGNhc2UgQ0hBUl9CVUZGRVI6CisgICAgICAgICAgICAgICAgYnVmZmVyX3R5cGVfbmFtZSA9ICJjaGFyIjsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICAgICAgYnVmZmVyX3R5cGVfbmFtZSA9ICJubyI7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBQeUVycl9Gb3JtYXQoUHlFeGNfVHlwZUVycm9yLAorICAgICAgICAgICAgICAgICIlcyBidWZmZXIgdHlwZSBub3QgYXZhaWxhYmxlIiwKKyAgICAgICAgICAgICAgICBidWZmZXJfdHlwZV9uYW1lKTsKKyAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICB9CisgICAgICAgIGlmICgoY291bnQgPSAoKnByb2MpKHNlbGYtPmJfYmFzZSwgMCwgcHRyKSkgPCAwKQorICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgIC8qIGFwcGx5IGNvbnN0cmFpbnRzIHRvIHRoZSBzdGFydC9lbmQgKi8KKyAgICAgICAgaWYgKHNlbGYtPmJfb2Zmc2V0ID4gY291bnQpCisgICAgICAgICAgICBvZmZzZXQgPSBjb3VudDsKKyAgICAgICAgZWxzZQorICAgICAgICAgICAgb2Zmc2V0ID0gc2VsZi0+Yl9vZmZzZXQ7CisgICAgICAgICooY2hhciAqKilwdHIgPSAqKGNoYXIgKiopcHRyICsgb2Zmc2V0OworICAgICAgICBpZiAoc2VsZi0+Yl9zaXplID09IFB5X0VORF9PRl9CVUZGRVIpCisgICAgICAgICAgICAqc2l6ZSA9IGNvdW50OworICAgICAgICBlbHNlCisgICAgICAgICAgICAqc2l6ZSA9IHNlbGYtPmJfc2l6ZTsKKyAgICAgICAgaWYgKG9mZnNldCArICpzaXplID4gY291bnQpCisgICAgICAgICAgICAqc2l6ZSA9IGNvdW50IC0gb2Zmc2V0OworICAgIH0KKyAgICByZXR1cm4gMTsKK30KKworCitzdGF0aWMgUHlPYmplY3QgKgorYnVmZmVyX2Zyb21fbWVtb3J5KFB5T2JqZWN0ICpiYXNlLCBQeV9zc2l6ZV90IHNpemUsIFB5X3NzaXplX3Qgb2Zmc2V0LCB2b2lkICpwdHIsCisgICAgICAgICAgICAgICAgICAgaW50IHJlYWRvbmx5KQoreworICAgIFB5QnVmZmVyT2JqZWN0ICogYjsKKworICAgIGlmIChzaXplIDwgMCAmJiBzaXplICE9IFB5X0VORF9PRl9CVUZGRVIpIHsKKyAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1ZhbHVlRXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAgICAic2l6ZSBtdXN0IGJlIHplcm8gb3IgcG9zaXRpdmUiKTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIGlmIChvZmZzZXQgPCAwKSB7CisgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19WYWx1ZUVycm9yLAorICAgICAgICAgICAgICAgICAgICAgICAgIm9mZnNldCBtdXN0IGJlIHplcm8gb3IgcG9zaXRpdmUiKTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorCisgICAgYiA9IFB5T2JqZWN0X05FVyhQeUJ1ZmZlck9iamVjdCwgJlB5QnVmZmVyX1R5cGUpOworICAgIGlmICggYiA9PSBOVUxMICkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisKKyAgICBQeV9YSU5DUkVGKGJhc2UpOworICAgIGItPmJfYmFzZSA9IGJhc2U7CisgICAgYi0+Yl9wdHIgPSBwdHI7CisgICAgYi0+Yl9zaXplID0gc2l6ZTsKKyAgICBiLT5iX29mZnNldCA9IG9mZnNldDsKKyAgICBiLT5iX3JlYWRvbmx5ID0gcmVhZG9ubHk7CisgICAgYi0+Yl9oYXNoID0gLTE7CisKKyAgICByZXR1cm4gKFB5T2JqZWN0ICopIGI7Cit9CisKK3N0YXRpYyBQeU9iamVjdCAqCitidWZmZXJfZnJvbV9vYmplY3QoUHlPYmplY3QgKmJhc2UsIFB5X3NzaXplX3Qgc2l6ZSwgUHlfc3NpemVfdCBvZmZzZXQsIGludCByZWFkb25seSkKK3sKKyAgICBpZiAob2Zmc2V0IDwgMCkgeworICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfVmFsdWVFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICJvZmZzZXQgbXVzdCBiZSB6ZXJvIG9yIHBvc2l0aXZlIik7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICBpZiAoIFB5QnVmZmVyX0NoZWNrKGJhc2UpICYmICgoKFB5QnVmZmVyT2JqZWN0ICopYmFzZSktPmJfYmFzZSkgKSB7CisgICAgICAgIC8qIGFub3RoZXIgYnVmZmVyLCByZWZlciB0byB0aGUgYmFzZSBvYmplY3QgKi8KKyAgICAgICAgUHlCdWZmZXJPYmplY3QgKmIgPSAoUHlCdWZmZXJPYmplY3QgKiliYXNlOworICAgICAgICBpZiAoYi0+Yl9zaXplICE9IFB5X0VORF9PRl9CVUZGRVIpIHsKKyAgICAgICAgICAgIFB5X3NzaXplX3QgYmFzZV9zaXplID0gYi0+Yl9zaXplIC0gb2Zmc2V0OworICAgICAgICAgICAgaWYgKGJhc2Vfc2l6ZSA8IDApCisgICAgICAgICAgICAgICAgYmFzZV9zaXplID0gMDsKKyAgICAgICAgICAgIGlmIChzaXplID09IFB5X0VORF9PRl9CVUZGRVIgfHwgc2l6ZSA+IGJhc2Vfc2l6ZSkKKyAgICAgICAgICAgICAgICBzaXplID0gYmFzZV9zaXplOworICAgICAgICB9CisgICAgICAgIG9mZnNldCArPSBiLT5iX29mZnNldDsKKyAgICAgICAgYmFzZSA9IGItPmJfYmFzZTsKKyAgICB9CisgICAgcmV0dXJuIGJ1ZmZlcl9mcm9tX21lbW9yeShiYXNlLCBzaXplLCBvZmZzZXQsIE5VTEwsIHJlYWRvbmx5KTsKK30KKworCitQeU9iamVjdCAqCitQeUJ1ZmZlcl9Gcm9tT2JqZWN0KFB5T2JqZWN0ICpiYXNlLCBQeV9zc2l6ZV90IG9mZnNldCwgUHlfc3NpemVfdCBzaXplKQoreworICAgIFB5QnVmZmVyUHJvY3MgKnBiID0gYmFzZS0+b2JfdHlwZS0+dHBfYXNfYnVmZmVyOworCisgICAgaWYgKCBwYiA9PSBOVUxMIHx8CisgICAgICAgICBwYi0+YmZfZ2V0cmVhZGJ1ZmZlciA9PSBOVUxMIHx8CisgICAgICAgICBwYi0+YmZfZ2V0c2VnY291bnQgPT0gTlVMTCApCisgICAgeworICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfVHlwZUVycm9yLCAiYnVmZmVyIG9iamVjdCBleHBlY3RlZCIpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisKKyAgICByZXR1cm4gYnVmZmVyX2Zyb21fb2JqZWN0KGJhc2UsIHNpemUsIG9mZnNldCwgMSk7Cit9CisKK1B5T2JqZWN0ICoKK1B5QnVmZmVyX0Zyb21SZWFkV3JpdGVPYmplY3QoUHlPYmplY3QgKmJhc2UsIFB5X3NzaXplX3Qgb2Zmc2V0LCBQeV9zc2l6ZV90IHNpemUpCit7CisgICAgUHlCdWZmZXJQcm9jcyAqcGIgPSBiYXNlLT5vYl90eXBlLT50cF9hc19idWZmZXI7CisKKyAgICBpZiAoIHBiID09IE5VTEwgfHwKKyAgICAgICAgIHBiLT5iZl9nZXR3cml0ZWJ1ZmZlciA9PSBOVUxMIHx8CisgICAgICAgICBwYi0+YmZfZ2V0c2VnY291bnQgPT0gTlVMTCApCisgICAgeworICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfVHlwZUVycm9yLCAiYnVmZmVyIG9iamVjdCBleHBlY3RlZCIpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisKKyAgICByZXR1cm4gYnVmZmVyX2Zyb21fb2JqZWN0KGJhc2UsIHNpemUsICBvZmZzZXQsIDApOworfQorCitQeU9iamVjdCAqCitQeUJ1ZmZlcl9Gcm9tTWVtb3J5KHZvaWQgKnB0ciwgUHlfc3NpemVfdCBzaXplKQoreworICAgIHJldHVybiBidWZmZXJfZnJvbV9tZW1vcnkoTlVMTCwgc2l6ZSwgMCwgcHRyLCAxKTsKK30KKworUHlPYmplY3QgKgorUHlCdWZmZXJfRnJvbVJlYWRXcml0ZU1lbW9yeSh2b2lkICpwdHIsIFB5X3NzaXplX3Qgc2l6ZSkKK3sKKyAgICByZXR1cm4gYnVmZmVyX2Zyb21fbWVtb3J5KE5VTEwsIHNpemUsIDAsIHB0ciwgMCk7Cit9CisKK1B5T2JqZWN0ICoKK1B5QnVmZmVyX05ldyhQeV9zc2l6ZV90IHNpemUpCit7CisgICAgUHlPYmplY3QgKm87CisgICAgUHlCdWZmZXJPYmplY3QgKiBiOworCisgICAgaWYgKHNpemUgPCAwKSB7CisgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19WYWx1ZUVycm9yLAorICAgICAgICAgICAgICAgICAgICAgICAgInNpemUgbXVzdCBiZSB6ZXJvIG9yIHBvc2l0aXZlIik7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICBpZiAoc2l6ZW9mKCpiKSA+IFBZX1NTSVpFX1RfTUFYIC0gc2l6ZSkgeworICAgICAgICAvKiB1bmxpa2VseSAqLworICAgICAgICByZXR1cm4gUHlFcnJfTm9NZW1vcnkoKTsKKyAgICB9CisgICAgLyogSW5saW5lIFB5T2JqZWN0X05ldyAqLworICAgIG8gPSAoUHlPYmplY3QgKilQeU9iamVjdF9NQUxMT0Moc2l6ZW9mKCpiKSArIHNpemUpOworICAgIGlmICggbyA9PSBOVUxMICkKKyAgICAgICAgcmV0dXJuIFB5RXJyX05vTWVtb3J5KCk7CisgICAgYiA9IChQeUJ1ZmZlck9iamVjdCAqKSBQeU9iamVjdF9JTklUKG8sICZQeUJ1ZmZlcl9UeXBlKTsKKworICAgIGItPmJfYmFzZSA9IE5VTEw7CisgICAgYi0+Yl9wdHIgPSAodm9pZCAqKShiICsgMSk7CisgICAgYi0+Yl9zaXplID0gc2l6ZTsKKyAgICBiLT5iX29mZnNldCA9IDA7CisgICAgYi0+Yl9yZWFkb25seSA9IDA7CisgICAgYi0+Yl9oYXNoID0gLTE7CisKKyAgICByZXR1cm4gbzsKK30KKworLyogTWV0aG9kcyAqLworCitzdGF0aWMgUHlPYmplY3QgKgorYnVmZmVyX25ldyhQeVR5cGVPYmplY3QgKnR5cGUsIFB5T2JqZWN0ICphcmdzLCBQeU9iamVjdCAqa3cpCit7CisgICAgUHlPYmplY3QgKm9iOworICAgIFB5X3NzaXplX3Qgb2Zmc2V0ID0gMDsKKyAgICBQeV9zc2l6ZV90IHNpemUgPSBQeV9FTkRfT0ZfQlVGRkVSOworCisgICAgaWYgKFB5RXJyX1dhcm5QeTNrKCJidWZmZXIoKSBub3Qgc3VwcG9ydGVkIGluIDMueCIsIDEpIDwgMCkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisKKyAgICBpZiAoIV9QeUFyZ19Ob0tleXdvcmRzKCJidWZmZXIoKSIsIGt3KSkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisKKyAgICBpZiAoIVB5QXJnX1BhcnNlVHVwbGUoYXJncywgIk98bm46YnVmZmVyIiwgJm9iLCAmb2Zmc2V0LCAmc2l6ZSkpCisgICAgICAgIHJldHVybiBOVUxMOworICAgIHJldHVybiBQeUJ1ZmZlcl9Gcm9tT2JqZWN0KG9iLCBvZmZzZXQsIHNpemUpOworfQorCitQeURvY19TVFJWQVIoYnVmZmVyX2RvYywKKyJidWZmZXIob2JqZWN0IFssIG9mZnNldFssIHNpemVdXSlcblwKK1xuXAorQ3JlYXRlIGEgbmV3IGJ1ZmZlciBvYmplY3Qgd2hpY2ggcmVmZXJlbmNlcyB0aGUgZ2l2ZW4gb2JqZWN0LlxuXAorVGhlIGJ1ZmZlciB3aWxsIHJlZmVyZW5jZSBhIHNsaWNlIG9mIHRoZSB0YXJnZXQgb2JqZWN0IGZyb20gdGhlXG5cCitzdGFydCBvZiB0aGUgb2JqZWN0IChvciBhdCB0aGUgc3BlY2lmaWVkIG9mZnNldCkuIFRoZSBzbGljZSB3aWxsXG5cCitleHRlbmQgdG8gdGhlIGVuZCBvZiB0aGUgdGFyZ2V0IG9iamVjdCAob3Igd2l0aCB0aGUgc3BlY2lmaWVkIHNpemUpLiIpOworCisKK3N0YXRpYyB2b2lkCitidWZmZXJfZGVhbGxvYyhQeUJ1ZmZlck9iamVjdCAqc2VsZikKK3sKKyAgICBQeV9YREVDUkVGKHNlbGYtPmJfYmFzZSk7CisgICAgUHlPYmplY3RfREVMKHNlbGYpOworfQorCitzdGF0aWMgaW50CitidWZmZXJfY29tcGFyZShQeUJ1ZmZlck9iamVjdCAqc2VsZiwgUHlCdWZmZXJPYmplY3QgKm90aGVyKQoreworICAgIHZvaWQgKnAxLCAqcDI7CisgICAgUHlfc3NpemVfdCBsZW5fc2VsZiwgbGVuX290aGVyLCBtaW5fbGVuOworICAgIGludCBjbXA7CisKKyAgICBpZiAoIWdldF9idWYoc2VsZiwgJnAxLCAmbGVuX3NlbGYsIEFOWV9CVUZGRVIpKQorICAgICAgICByZXR1cm4gLTE7CisgICAgaWYgKCFnZXRfYnVmKG90aGVyLCAmcDIsICZsZW5fb3RoZXIsIEFOWV9CVUZGRVIpKQorICAgICAgICByZXR1cm4gLTE7CisgICAgbWluX2xlbiA9IChsZW5fc2VsZiA8IGxlbl9vdGhlcikgPyBsZW5fc2VsZiA6IGxlbl9vdGhlcjsKKyAgICBpZiAobWluX2xlbiA+IDApIHsKKyAgICAgICAgY21wID0gbWVtY21wKHAxLCBwMiwgbWluX2xlbik7CisgICAgICAgIGlmIChjbXAgIT0gMCkKKyAgICAgICAgICAgIHJldHVybiBjbXAgPCAwID8gLTEgOiAxOworICAgIH0KKyAgICByZXR1cm4gKGxlbl9zZWxmIDwgbGVuX290aGVyKSA/IC0xIDogKGxlbl9zZWxmID4gbGVuX290aGVyKSA/IDEgOiAwOworfQorCitzdGF0aWMgUHlPYmplY3QgKgorYnVmZmVyX3JlcHIoUHlCdWZmZXJPYmplY3QgKnNlbGYpCit7CisgICAgY29uc3QgY2hhciAqc3RhdHVzID0gc2VsZi0+Yl9yZWFkb25seSA/ICJyZWFkLW9ubHkiIDogInJlYWQtd3JpdGUiOworCisgICAgaWYgKCBzZWxmLT5iX2Jhc2UgPT0gTlVMTCApCisgICAgICAgIHJldHVybiBQeVN0cmluZ19Gcm9tRm9ybWF0KCI8JXMgYnVmZmVyIHB0ciAlcCwgc2l6ZSAlemQgYXQgJXA+IiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhdHVzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLT5iX3B0ciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi0+Yl9zaXplLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmKTsKKyAgICBlbHNlCisgICAgICAgIHJldHVybiBQeVN0cmluZ19Gcm9tRm9ybWF0KAorICAgICAgICAgICAgIjwlcyBidWZmZXIgZm9yICVwLCBzaXplICV6ZCwgb2Zmc2V0ICV6ZCBhdCAlcD4iLAorICAgICAgICAgICAgc3RhdHVzLAorICAgICAgICAgICAgc2VsZi0+Yl9iYXNlLAorICAgICAgICAgICAgc2VsZi0+Yl9zaXplLAorICAgICAgICAgICAgc2VsZi0+Yl9vZmZzZXQsCisgICAgICAgICAgICBzZWxmKTsKK30KKworc3RhdGljIGxvbmcKK2J1ZmZlcl9oYXNoKFB5QnVmZmVyT2JqZWN0ICpzZWxmKQoreworICAgIHZvaWQgKnB0cjsKKyAgICBQeV9zc2l6ZV90IHNpemU7CisgICAgcmVnaXN0ZXIgUHlfc3NpemVfdCBsZW47CisgICAgcmVnaXN0ZXIgdW5zaWduZWQgY2hhciAqcDsKKyAgICByZWdpc3RlciBsb25nIHg7CisKKyAgICBpZiAoIHNlbGYtPmJfaGFzaCAhPSAtMSApCisgICAgICAgIHJldHVybiBzZWxmLT5iX2hhc2g7CisKKyAgICAvKiBYWFggcG90ZW50aWFsIGJ1Z3MgaGVyZSwgYSByZWFkb25seSBidWZmZXIgZG9lcyBub3QgaW1wbHkgdGhhdCB0aGUKKyAgICAgKiB1bmRlcmx5aW5nIG1lbW9yeSBpcyBpbW11dGFibGUuICBiX3JlYWRvbmx5IGlzIGEgbmVjZXNzYXJ5IGJ1dCBub3QKKyAgICAgKiBzdWZmaWNpZW50IGNvbmRpdGlvbiBmb3IgYSBidWZmZXIgdG8gYmUgaGFzaGFibGUuICBQZXJoYXBzIGl0IHdvdWxkCisgICAgICogYmUgYmV0dGVyIHRvIG9ubHkgYWxsb3cgaGFzaGluZyBpZiB0aGUgdW5kZXJseWluZyBvYmplY3QgaXMga25vd24gdG8KKyAgICAgKiBiZSBpbW11dGFibGUgKGUuZy4gUHlTdHJpbmdfQ2hlY2soKSBpcyB0cnVlKS4gIEFub3RoZXIgaWRlYSB3b3VsZAorICAgICAqIGJlIHRvIGNhbGwgdHBfaGFzaCBvbiB0aGUgdW5kZXJseWluZyBvYmplY3QgYW5kIHNlZSBpZiBpdCByYWlzZXMKKyAgICAgKiBhbiBlcnJvci4gKi8KKyAgICBpZiAoICFzZWxmLT5iX3JlYWRvbmx5ICkKKyAgICB7CisgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19UeXBlRXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAgICAid3JpdGFibGUgYnVmZmVycyBhcmUgbm90IGhhc2hhYmxlIik7CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisKKyAgICBpZiAoIWdldF9idWYoc2VsZiwgJnB0ciwgJnNpemUsIEFOWV9CVUZGRVIpKQorICAgICAgICByZXR1cm4gLTE7CisgICAgcCA9ICh1bnNpZ25lZCBjaGFyICopIHB0cjsKKyAgICBsZW4gPSBzaXplOworICAgIC8qCisgICAgICBXZSBtYWtlIHRoZSBoYXNoIG9mIHRoZSBlbXB0eSBidWZmZXIgYmUgMCwgcmF0aGVyIHRoYW4gdXNpbmcKKyAgICAgIChwcmVmaXggXiBzdWZmaXgpLCBzaW5jZSB0aGlzIHNsaWdodGx5IG9iZnVzY2F0ZXMgdGhlIGhhc2ggc2VjcmV0CisgICAgKi8KKyAgICBpZiAobGVuID09IDApIHsKKyAgICAgICAgc2VsZi0+Yl9oYXNoID0gMDsKKyAgICAgICAgcmV0dXJuIDA7CisgICAgfQorICAgIHggPSBfUHlfSGFzaFNlY3JldC5wcmVmaXg7CisgICAgeCBePSAqcCA8PCA3OworICAgIHdoaWxlICgtLWxlbiA+PSAwKQorICAgICAgICB4ID0gKDEwMDAwMDMqeCkgXiAqcCsrOworICAgIHggXj0gc2l6ZTsKKyAgICB4IF49IF9QeV9IYXNoU2VjcmV0LnN1ZmZpeDsKKyAgICBpZiAoeCA9PSAtMSkKKyAgICAgICAgeCA9IC0yOworICAgIHNlbGYtPmJfaGFzaCA9IHg7CisgICAgcmV0dXJuIHg7Cit9CisKK3N0YXRpYyBQeU9iamVjdCAqCitidWZmZXJfc3RyKFB5QnVmZmVyT2JqZWN0ICpzZWxmKQoreworICAgIHZvaWQgKnB0cjsKKyAgICBQeV9zc2l6ZV90IHNpemU7CisgICAgaWYgKCFnZXRfYnVmKHNlbGYsICZwdHIsICZzaXplLCBBTllfQlVGRkVSKSkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgcmV0dXJuIFB5U3RyaW5nX0Zyb21TdHJpbmdBbmRTaXplKChjb25zdCBjaGFyICopcHRyLCBzaXplKTsKK30KKworLyogU2VxdWVuY2UgbWV0aG9kcyAqLworCitzdGF0aWMgUHlfc3NpemVfdAorYnVmZmVyX2xlbmd0aChQeUJ1ZmZlck9iamVjdCAqc2VsZikKK3sKKyAgICB2b2lkICpwdHI7CisgICAgUHlfc3NpemVfdCBzaXplOworICAgIGlmICghZ2V0X2J1ZihzZWxmLCAmcHRyLCAmc2l6ZSwgQU5ZX0JVRkZFUikpCisgICAgICAgIHJldHVybiAtMTsKKyAgICByZXR1cm4gc2l6ZTsKK30KKworc3RhdGljIFB5T2JqZWN0ICoKK2J1ZmZlcl9jb25jYXQoUHlCdWZmZXJPYmplY3QgKnNlbGYsIFB5T2JqZWN0ICpvdGhlcikKK3sKKyAgICBQeUJ1ZmZlclByb2NzICpwYiA9IG90aGVyLT5vYl90eXBlLT50cF9hc19idWZmZXI7CisgICAgdm9pZCAqcHRyMSwgKnB0cjI7CisgICAgY2hhciAqcDsKKyAgICBQeU9iamVjdCAqb2I7CisgICAgUHlfc3NpemVfdCBzaXplLCBjb3VudDsKKworICAgIGlmICggcGIgPT0gTlVMTCB8fAorICAgICAgICAgcGItPmJmX2dldHJlYWRidWZmZXIgPT0gTlVMTCB8fAorICAgICAgICAgcGItPmJmX2dldHNlZ2NvdW50ID09IE5VTEwgKQorICAgIHsKKyAgICAgICAgUHlFcnJfQmFkQXJndW1lbnQoKTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIGlmICggKCpwYi0+YmZfZ2V0c2VnY291bnQpKG90aGVyLCBOVUxMKSAhPSAxICkKKyAgICB7CisgICAgICAgIC8qICMjIyB1c2UgYSBkaWZmZXJlbnQgZXhjZXB0aW9uIHR5cGUvbWVzc2FnZT8gKi8KKyAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1R5cGVFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICJzaW5nbGUtc2VnbWVudCBidWZmZXIgb2JqZWN0IGV4cGVjdGVkIik7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKworICAgIGlmICghZ2V0X2J1ZihzZWxmLCAmcHRyMSwgJnNpemUsIEFOWV9CVUZGRVIpKQorICAgICAgICByZXR1cm4gTlVMTDsKKworICAgIC8qIG9wdGltaXplIHNwZWNpYWwgY2FzZSAqLworICAgIGlmICggc2l6ZSA9PSAwICkKKyAgICB7CisgICAgICAgIFB5X0lOQ1JFRihvdGhlcik7CisgICAgICAgIHJldHVybiBvdGhlcjsKKyAgICB9CisKKyAgICBpZiAoIChjb3VudCA9ICgqcGItPmJmX2dldHJlYWRidWZmZXIpKG90aGVyLCAwLCAmcHRyMikpIDwgMCApCisgICAgICAgIHJldHVybiBOVUxMOworCisgICAgYXNzZXJ0KGNvdW50IDw9IFBZX1NJWkVfTUFYIC0gc2l6ZSk7CisKKyAgICBvYiA9IFB5U3RyaW5nX0Zyb21TdHJpbmdBbmRTaXplKE5VTEwsIHNpemUgKyBjb3VudCk7CisgICAgaWYgKCBvYiA9PSBOVUxMICkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgcCA9IFB5U3RyaW5nX0FTX1NUUklORyhvYik7CisgICAgbWVtY3B5KHAsIHB0cjEsIHNpemUpOworICAgIG1lbWNweShwICsgc2l6ZSwgcHRyMiwgY291bnQpOworCisgICAgLyogdGhlcmUgaXMgYW4gZXh0cmEgYnl0ZSBpbiB0aGUgc3RyaW5nIG9iamVjdCwgc28gdGhpcyBpcyBzYWZlICovCisgICAgcFtzaXplICsgY291bnRdID0gJ1wwJzsKKworICAgIHJldHVybiBvYjsKK30KKworc3RhdGljIFB5T2JqZWN0ICoKK2J1ZmZlcl9yZXBlYXQoUHlCdWZmZXJPYmplY3QgKnNlbGYsIFB5X3NzaXplX3QgY291bnQpCit7CisgICAgUHlPYmplY3QgKm9iOworICAgIHJlZ2lzdGVyIGNoYXIgKnA7CisgICAgdm9pZCAqcHRyOworICAgIFB5X3NzaXplX3Qgc2l6ZTsKKworICAgIGlmICggY291bnQgPCAwICkKKyAgICAgICAgY291bnQgPSAwOworICAgIGlmICghZ2V0X2J1ZihzZWxmLCAmcHRyLCAmc2l6ZSwgQU5ZX0JVRkZFUikpCisgICAgICAgIHJldHVybiBOVUxMOworICAgIGlmIChjb3VudCA+IFBZX1NTSVpFX1RfTUFYIC8gc2l6ZSkgeworICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfTWVtb3J5RXJyb3IsICJyZXN1bHQgdG9vIGxhcmdlIik7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICBvYiA9IFB5U3RyaW5nX0Zyb21TdHJpbmdBbmRTaXplKE5VTEwsIHNpemUgKiBjb3VudCk7CisgICAgaWYgKCBvYiA9PSBOVUxMICkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisKKyAgICBwID0gUHlTdHJpbmdfQVNfU1RSSU5HKG9iKTsKKyAgICB3aGlsZSAoIGNvdW50LS0gKQorICAgIHsKKyAgICAgICAgbWVtY3B5KHAsIHB0ciwgc2l6ZSk7CisgICAgICAgIHAgKz0gc2l6ZTsKKyAgICB9CisKKyAgICAvKiB0aGVyZSBpcyBhbiBleHRyYSBieXRlIGluIHRoZSBzdHJpbmcgb2JqZWN0LCBzbyB0aGlzIGlzIHNhZmUgKi8KKyAgICAqcCA9ICdcMCc7CisKKyAgICByZXR1cm4gb2I7Cit9CisKK3N0YXRpYyBQeU9iamVjdCAqCitidWZmZXJfaXRlbShQeUJ1ZmZlck9iamVjdCAqc2VsZiwgUHlfc3NpemVfdCBpZHgpCit7CisgICAgdm9pZCAqcHRyOworICAgIFB5X3NzaXplX3Qgc2l6ZTsKKyAgICBpZiAoIWdldF9idWYoc2VsZiwgJnB0ciwgJnNpemUsIEFOWV9CVUZGRVIpKQorICAgICAgICByZXR1cm4gTlVMTDsKKyAgICBpZiAoIGlkeCA8IDAgfHwgaWR4ID49IHNpemUgKSB7CisgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19JbmRleEVycm9yLCAiYnVmZmVyIGluZGV4IG91dCBvZiByYW5nZSIpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgcmV0dXJuIFB5U3RyaW5nX0Zyb21TdHJpbmdBbmRTaXplKChjaGFyICopcHRyICsgaWR4LCAxKTsKK30KKworc3RhdGljIFB5T2JqZWN0ICoKK2J1ZmZlcl9zbGljZShQeUJ1ZmZlck9iamVjdCAqc2VsZiwgUHlfc3NpemVfdCBsZWZ0LCBQeV9zc2l6ZV90IHJpZ2h0KQoreworICAgIHZvaWQgKnB0cjsKKyAgICBQeV9zc2l6ZV90IHNpemU7CisgICAgaWYgKCFnZXRfYnVmKHNlbGYsICZwdHIsICZzaXplLCBBTllfQlVGRkVSKSkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgaWYgKCBsZWZ0IDwgMCApCisgICAgICAgIGxlZnQgPSAwOworICAgIGlmICggcmlnaHQgPCAwICkKKyAgICAgICAgcmlnaHQgPSAwOworICAgIGlmICggcmlnaHQgPiBzaXplICkKKyAgICAgICAgcmlnaHQgPSBzaXplOworICAgIGlmICggcmlnaHQgPCBsZWZ0ICkKKyAgICAgICAgcmlnaHQgPSBsZWZ0OworICAgIHJldHVybiBQeVN0cmluZ19Gcm9tU3RyaW5nQW5kU2l6ZSgoY2hhciAqKXB0ciArIGxlZnQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJpZ2h0IC0gbGVmdCk7Cit9CisKK3N0YXRpYyBQeU9iamVjdCAqCitidWZmZXJfc3Vic2NyaXB0KFB5QnVmZmVyT2JqZWN0ICpzZWxmLCBQeU9iamVjdCAqaXRlbSkKK3sKKyAgICB2b2lkICpwOworICAgIFB5X3NzaXplX3Qgc2l6ZTsKKworICAgIGlmICghZ2V0X2J1ZihzZWxmLCAmcCwgJnNpemUsIEFOWV9CVUZGRVIpKQorICAgICAgICByZXR1cm4gTlVMTDsKKyAgICBpZiAoUHlJbmRleF9DaGVjayhpdGVtKSkgeworICAgICAgICBQeV9zc2l6ZV90IGkgPSBQeU51bWJlcl9Bc1NzaXplX3QoaXRlbSwgUHlFeGNfSW5kZXhFcnJvcik7CisgICAgICAgIGlmIChpID09IC0xICYmIFB5RXJyX09jY3VycmVkKCkpCisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgaWYgKGkgPCAwKQorICAgICAgICAgICAgaSArPSBzaXplOworICAgICAgICByZXR1cm4gYnVmZmVyX2l0ZW0oc2VsZiwgaSk7CisgICAgfQorICAgIGVsc2UgaWYgKFB5U2xpY2VfQ2hlY2soaXRlbSkpIHsKKyAgICAgICAgUHlfc3NpemVfdCBzdGFydCwgc3RvcCwgc3RlcCwgc2xpY2VsZW5ndGgsIGN1ciwgaTsKKworICAgICAgICBpZiAoUHlTbGljZV9HZXRJbmRpY2VzRXgoKFB5U2xpY2VPYmplY3QqKWl0ZW0sIHNpemUsCisgICAgICAgICAgICAgICAgICAgICAgICAgJnN0YXJ0LCAmc3RvcCwgJnN0ZXAsICZzbGljZWxlbmd0aCkgPCAwKSB7CisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChzbGljZWxlbmd0aCA8PSAwKQorICAgICAgICAgICAgcmV0dXJuIFB5U3RyaW5nX0Zyb21TdHJpbmdBbmRTaXplKCIiLCAwKTsKKyAgICAgICAgZWxzZSBpZiAoc3RlcCA9PSAxKQorICAgICAgICAgICAgcmV0dXJuIFB5U3RyaW5nX0Zyb21TdHJpbmdBbmRTaXplKChjaGFyICopcCArIHN0YXJ0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0b3AgLSBzdGFydCk7CisgICAgICAgIGVsc2UgeworICAgICAgICAgICAgUHlPYmplY3QgKnJlc3VsdDsKKyAgICAgICAgICAgIGNoYXIgKnNvdXJjZV9idWYgPSAoY2hhciAqKXA7CisgICAgICAgICAgICBjaGFyICpyZXN1bHRfYnVmID0gKGNoYXIgKilQeU1lbV9NYWxsb2Moc2xpY2VsZW5ndGgpOworCisgICAgICAgICAgICBpZiAocmVzdWx0X2J1ZiA9PSBOVUxMKQorICAgICAgICAgICAgICAgIHJldHVybiBQeUVycl9Ob01lbW9yeSgpOworCisgICAgICAgICAgICBmb3IgKGN1ciA9IHN0YXJ0LCBpID0gMDsgaSA8IHNsaWNlbGVuZ3RoOworICAgICAgICAgICAgICAgICBjdXIgKz0gc3RlcCwgaSsrKSB7CisgICAgICAgICAgICAgICAgcmVzdWx0X2J1ZltpXSA9IHNvdXJjZV9idWZbY3VyXTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgcmVzdWx0ID0gUHlTdHJpbmdfRnJvbVN0cmluZ0FuZFNpemUocmVzdWx0X2J1ZiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNsaWNlbGVuZ3RoKTsKKyAgICAgICAgICAgIFB5TWVtX0ZyZWUocmVzdWx0X2J1Zik7CisgICAgICAgICAgICByZXR1cm4gcmVzdWx0OworICAgICAgICB9CisgICAgfQorICAgIGVsc2UgeworICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfVHlwZUVycm9yLAorICAgICAgICAgICAgICAgICAgICAgICAgInNlcXVlbmNlIGluZGV4IG11c3QgYmUgaW50ZWdlciIpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9Cit9CisKK3N0YXRpYyBpbnQKK2J1ZmZlcl9hc3NfaXRlbShQeUJ1ZmZlck9iamVjdCAqc2VsZiwgUHlfc3NpemVfdCBpZHgsIFB5T2JqZWN0ICpvdGhlcikKK3sKKyAgICBQeUJ1ZmZlclByb2NzICpwYjsKKyAgICB2b2lkICpwdHIxLCAqcHRyMjsKKyAgICBQeV9zc2l6ZV90IHNpemU7CisgICAgUHlfc3NpemVfdCBjb3VudDsKKworICAgIGlmICggc2VsZi0+Yl9yZWFkb25seSApIHsKKyAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1R5cGVFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICJidWZmZXIgaXMgcmVhZC1vbmx5Iik7CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisKKyAgICBpZiAoIWdldF9idWYoc2VsZiwgJnB0cjEsICZzaXplLCBBTllfQlVGRkVSKSkKKyAgICAgICAgcmV0dXJuIC0xOworCisgICAgaWYgKGlkeCA8IDAgfHwgaWR4ID49IHNpemUpIHsKKyAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX0luZGV4RXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAgICAiYnVmZmVyIGFzc2lnbm1lbnQgaW5kZXggb3V0IG9mIHJhbmdlIik7CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisKKyAgICBwYiA9IG90aGVyID8gb3RoZXItPm9iX3R5cGUtPnRwX2FzX2J1ZmZlciA6IE5VTEw7CisgICAgaWYgKCBwYiA9PSBOVUxMIHx8CisgICAgICAgICBwYi0+YmZfZ2V0cmVhZGJ1ZmZlciA9PSBOVUxMIHx8CisgICAgICAgICBwYi0+YmZfZ2V0c2VnY291bnQgPT0gTlVMTCApCisgICAgeworICAgICAgICBQeUVycl9CYWRBcmd1bWVudCgpOworICAgICAgICByZXR1cm4gLTE7CisgICAgfQorICAgIGlmICggKCpwYi0+YmZfZ2V0c2VnY291bnQpKG90aGVyLCBOVUxMKSAhPSAxICkKKyAgICB7CisgICAgICAgIC8qICMjIyB1c2UgYSBkaWZmZXJlbnQgZXhjZXB0aW9uIHR5cGUvbWVzc2FnZT8gKi8KKyAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1R5cGVFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICJzaW5nbGUtc2VnbWVudCBidWZmZXIgb2JqZWN0IGV4cGVjdGVkIik7CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisKKyAgICBpZiAoIChjb3VudCA9ICgqcGItPmJmX2dldHJlYWRidWZmZXIpKG90aGVyLCAwLCAmcHRyMikpIDwgMCApCisgICAgICAgIHJldHVybiAtMTsKKyAgICBpZiAoIGNvdW50ICE9IDEgKSB7CisgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19UeXBlRXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAgICAicmlnaHQgb3BlcmFuZCBtdXN0IGJlIGEgc2luZ2xlIGJ5dGUiKTsKKyAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKworICAgICgoY2hhciAqKXB0cjEpW2lkeF0gPSAqKGNoYXIgKilwdHIyOworICAgIHJldHVybiAwOworfQorCitzdGF0aWMgaW50CitidWZmZXJfYXNzX3NsaWNlKFB5QnVmZmVyT2JqZWN0ICpzZWxmLCBQeV9zc2l6ZV90IGxlZnQsIFB5X3NzaXplX3QgcmlnaHQsIFB5T2JqZWN0ICpvdGhlcikKK3sKKyAgICBQeUJ1ZmZlclByb2NzICpwYjsKKyAgICB2b2lkICpwdHIxLCAqcHRyMjsKKyAgICBQeV9zc2l6ZV90IHNpemU7CisgICAgUHlfc3NpemVfdCBzbGljZV9sZW47CisgICAgUHlfc3NpemVfdCBjb3VudDsKKworICAgIGlmICggc2VsZi0+Yl9yZWFkb25seSApIHsKKyAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1R5cGVFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICJidWZmZXIgaXMgcmVhZC1vbmx5Iik7CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisKKyAgICBwYiA9IG90aGVyID8gb3RoZXItPm9iX3R5cGUtPnRwX2FzX2J1ZmZlciA6IE5VTEw7CisgICAgaWYgKCBwYiA9PSBOVUxMIHx8CisgICAgICAgICBwYi0+YmZfZ2V0cmVhZGJ1ZmZlciA9PSBOVUxMIHx8CisgICAgICAgICBwYi0+YmZfZ2V0c2VnY291bnQgPT0gTlVMTCApCisgICAgeworICAgICAgICBQeUVycl9CYWRBcmd1bWVudCgpOworICAgICAgICByZXR1cm4gLTE7CisgICAgfQorICAgIGlmICggKCpwYi0+YmZfZ2V0c2VnY291bnQpKG90aGVyLCBOVUxMKSAhPSAxICkKKyAgICB7CisgICAgICAgIC8qICMjIyB1c2UgYSBkaWZmZXJlbnQgZXhjZXB0aW9uIHR5cGUvbWVzc2FnZT8gKi8KKyAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1R5cGVFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICJzaW5nbGUtc2VnbWVudCBidWZmZXIgb2JqZWN0IGV4cGVjdGVkIik7CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisgICAgaWYgKCFnZXRfYnVmKHNlbGYsICZwdHIxLCAmc2l6ZSwgQU5ZX0JVRkZFUikpCisgICAgICAgIHJldHVybiAtMTsKKyAgICBpZiAoIChjb3VudCA9ICgqcGItPmJmX2dldHJlYWRidWZmZXIpKG90aGVyLCAwLCAmcHRyMikpIDwgMCApCisgICAgICAgIHJldHVybiAtMTsKKworICAgIGlmICggbGVmdCA8IDAgKQorICAgICAgICBsZWZ0ID0gMDsKKyAgICBlbHNlIGlmICggbGVmdCA+IHNpemUgKQorICAgICAgICBsZWZ0ID0gc2l6ZTsKKyAgICBpZiAoIHJpZ2h0IDwgbGVmdCApCisgICAgICAgIHJpZ2h0ID0gbGVmdDsKKyAgICBlbHNlIGlmICggcmlnaHQgPiBzaXplICkKKyAgICAgICAgcmlnaHQgPSBzaXplOworICAgIHNsaWNlX2xlbiA9IHJpZ2h0IC0gbGVmdDsKKworICAgIGlmICggY291bnQgIT0gc2xpY2VfbGVuICkgeworICAgICAgICBQeUVycl9TZXRTdHJpbmcoCisgICAgICAgICAgICBQeUV4Y19UeXBlRXJyb3IsCisgICAgICAgICAgICAicmlnaHQgb3BlcmFuZCBsZW5ndGggbXVzdCBtYXRjaCBzbGljZSBsZW5ndGgiKTsKKyAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKworICAgIGlmICggc2xpY2VfbGVuICkKKyAgICAgICAgbWVtY3B5KChjaGFyICopcHRyMSArIGxlZnQsIHB0cjIsIHNsaWNlX2xlbik7CisKKyAgICByZXR1cm4gMDsKK30KKworc3RhdGljIGludAorYnVmZmVyX2Fzc19zdWJzY3JpcHQoUHlCdWZmZXJPYmplY3QgKnNlbGYsIFB5T2JqZWN0ICppdGVtLCBQeU9iamVjdCAqdmFsdWUpCit7CisgICAgUHlCdWZmZXJQcm9jcyAqcGI7CisgICAgdm9pZCAqcHRyMSwgKnB0cjI7CisgICAgUHlfc3NpemVfdCBzZWxmc2l6ZTsKKyAgICBQeV9zc2l6ZV90IG90aGVyc2l6ZTsKKworICAgIGlmICggc2VsZi0+Yl9yZWFkb25seSApIHsKKyAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1R5cGVFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICJidWZmZXIgaXMgcmVhZC1vbmx5Iik7CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisKKyAgICBwYiA9IHZhbHVlID8gdmFsdWUtPm9iX3R5cGUtPnRwX2FzX2J1ZmZlciA6IE5VTEw7CisgICAgaWYgKCBwYiA9PSBOVUxMIHx8CisgICAgICAgICBwYi0+YmZfZ2V0cmVhZGJ1ZmZlciA9PSBOVUxMIHx8CisgICAgICAgICBwYi0+YmZfZ2V0c2VnY291bnQgPT0gTlVMTCApCisgICAgeworICAgICAgICBQeUVycl9CYWRBcmd1bWVudCgpOworICAgICAgICByZXR1cm4gLTE7CisgICAgfQorICAgIGlmICggKCpwYi0+YmZfZ2V0c2VnY291bnQpKHZhbHVlLCBOVUxMKSAhPSAxICkKKyAgICB7CisgICAgICAgIC8qICMjIyB1c2UgYSBkaWZmZXJlbnQgZXhjZXB0aW9uIHR5cGUvbWVzc2FnZT8gKi8KKyAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1R5cGVFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICJzaW5nbGUtc2VnbWVudCBidWZmZXIgb2JqZWN0IGV4cGVjdGVkIik7CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisgICAgaWYgKCFnZXRfYnVmKHNlbGYsICZwdHIxLCAmc2VsZnNpemUsIEFOWV9CVUZGRVIpKQorICAgICAgICByZXR1cm4gLTE7CisgICAgaWYgKFB5SW5kZXhfQ2hlY2soaXRlbSkpIHsKKyAgICAgICAgUHlfc3NpemVfdCBpID0gUHlOdW1iZXJfQXNTc2l6ZV90KGl0ZW0sIFB5RXhjX0luZGV4RXJyb3IpOworICAgICAgICBpZiAoaSA9PSAtMSAmJiBQeUVycl9PY2N1cnJlZCgpKQorICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICBpZiAoaSA8IDApCisgICAgICAgICAgICBpICs9IHNlbGZzaXplOworICAgICAgICByZXR1cm4gYnVmZmVyX2Fzc19pdGVtKHNlbGYsIGksIHZhbHVlKTsKKyAgICB9CisgICAgZWxzZSBpZiAoUHlTbGljZV9DaGVjayhpdGVtKSkgeworICAgICAgICBQeV9zc2l6ZV90IHN0YXJ0LCBzdG9wLCBzdGVwLCBzbGljZWxlbmd0aDsKKworICAgICAgICBpZiAoUHlTbGljZV9HZXRJbmRpY2VzRXgoKFB5U2xpY2VPYmplY3QgKilpdGVtLCBzZWxmc2l6ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICZzdGFydCwgJnN0b3AsICZzdGVwLCAmc2xpY2VsZW5ndGgpIDwgMCkKKyAgICAgICAgICAgIHJldHVybiAtMTsKKworICAgICAgICBpZiAoKG90aGVyc2l6ZSA9ICgqcGItPmJmX2dldHJlYWRidWZmZXIpKHZhbHVlLCAwLCAmcHRyMikpIDwgMCkKKyAgICAgICAgICAgIHJldHVybiAtMTsKKworICAgICAgICBpZiAob3RoZXJzaXplICE9IHNsaWNlbGVuZ3RoKSB7CisgICAgICAgICAgICBQeUVycl9TZXRTdHJpbmcoCisgICAgICAgICAgICAgICAgUHlFeGNfVHlwZUVycm9yLAorICAgICAgICAgICAgICAgICJyaWdodCBvcGVyYW5kIGxlbmd0aCBtdXN0IG1hdGNoIHNsaWNlIGxlbmd0aCIpOworICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICB9CisKKyAgICAgICAgaWYgKHNsaWNlbGVuZ3RoID09IDApCisgICAgICAgICAgICByZXR1cm4gMDsKKyAgICAgICAgZWxzZSBpZiAoc3RlcCA9PSAxKSB7CisgICAgICAgICAgICBtZW1jcHkoKGNoYXIgKilwdHIxICsgc3RhcnQsIHB0cjIsIHNsaWNlbGVuZ3RoKTsKKyAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICB9CisgICAgICAgIGVsc2UgeworICAgICAgICAgICAgUHlfc3NpemVfdCBjdXIsIGk7CisKKyAgICAgICAgICAgIGZvciAoY3VyID0gc3RhcnQsIGkgPSAwOyBpIDwgc2xpY2VsZW5ndGg7CisgICAgICAgICAgICAgICAgIGN1ciArPSBzdGVwLCBpKyspIHsKKyAgICAgICAgICAgICAgICAoKGNoYXIgKilwdHIxKVtjdXJdID0gKChjaGFyICopcHRyMilbaV07CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICB9CisgICAgfSBlbHNlIHsKKyAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1R5cGVFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICJidWZmZXIgaW5kaWNlcyBtdXN0IGJlIGludGVnZXJzIik7CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9Cit9CisKKy8qIEJ1ZmZlciBtZXRob2RzICovCisKK3N0YXRpYyBQeV9zc2l6ZV90CitidWZmZXJfZ2V0cmVhZGJ1ZihQeUJ1ZmZlck9iamVjdCAqc2VsZiwgUHlfc3NpemVfdCBpZHgsIHZvaWQgKipwcCkKK3sKKyAgICBQeV9zc2l6ZV90IHNpemU7CisgICAgaWYgKCBpZHggIT0gMCApIHsKKyAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1N5c3RlbUVycm9yLAorICAgICAgICAgICAgICAgICAgICAgICAgImFjY2Vzc2luZyBub24tZXhpc3RlbnQgYnVmZmVyIHNlZ21lbnQiKTsKKyAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKyAgICBpZiAoIWdldF9idWYoc2VsZiwgcHAsICZzaXplLCBSRUFEX0JVRkZFUikpCisgICAgICAgIHJldHVybiAtMTsKKyAgICByZXR1cm4gc2l6ZTsKK30KKworc3RhdGljIFB5X3NzaXplX3QKK2J1ZmZlcl9nZXR3cml0ZWJ1ZihQeUJ1ZmZlck9iamVjdCAqc2VsZiwgUHlfc3NpemVfdCBpZHgsIHZvaWQgKipwcCkKK3sKKyAgICBQeV9zc2l6ZV90IHNpemU7CisKKyAgICBpZiAoIHNlbGYtPmJfcmVhZG9ubHkgKQorICAgIHsKKyAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1R5cGVFcnJvciwgImJ1ZmZlciBpcyByZWFkLW9ubHkiKTsKKyAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKworICAgIGlmICggaWR4ICE9IDAgKSB7CisgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19TeXN0ZW1FcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICJhY2Nlc3Npbmcgbm9uLWV4aXN0ZW50IGJ1ZmZlciBzZWdtZW50Iik7CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisgICAgaWYgKCFnZXRfYnVmKHNlbGYsIHBwLCAmc2l6ZSwgV1JJVEVfQlVGRkVSKSkKKyAgICAgICAgcmV0dXJuIC0xOworICAgIHJldHVybiBzaXplOworfQorCitzdGF0aWMgUHlfc3NpemVfdAorYnVmZmVyX2dldHNlZ2NvdW50KFB5QnVmZmVyT2JqZWN0ICpzZWxmLCBQeV9zc2l6ZV90ICpsZW5wKQoreworICAgIHZvaWQgKnB0cjsKKyAgICBQeV9zc2l6ZV90IHNpemU7CisgICAgaWYgKCFnZXRfYnVmKHNlbGYsICZwdHIsICZzaXplLCBBTllfQlVGRkVSKSkKKyAgICAgICAgcmV0dXJuIC0xOworICAgIGlmIChsZW5wKQorICAgICAgICAqbGVucCA9IHNpemU7CisgICAgcmV0dXJuIDE7Cit9CisKK3N0YXRpYyBQeV9zc2l6ZV90CitidWZmZXJfZ2V0Y2hhcmJ1ZihQeUJ1ZmZlck9iamVjdCAqc2VsZiwgUHlfc3NpemVfdCBpZHgsIGNvbnN0IGNoYXIgKipwcCkKK3sKKyAgICB2b2lkICpwdHI7CisgICAgUHlfc3NpemVfdCBzaXplOworICAgIGlmICggaWR4ICE9IDAgKSB7CisgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19TeXN0ZW1FcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICJhY2Nlc3Npbmcgbm9uLWV4aXN0ZW50IGJ1ZmZlciBzZWdtZW50Iik7CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisgICAgaWYgKCFnZXRfYnVmKHNlbGYsICZwdHIsICZzaXplLCBDSEFSX0JVRkZFUikpCisgICAgICAgIHJldHVybiAtMTsKKyAgICAqcHAgPSAoY29uc3QgY2hhciAqKXB0cjsKKyAgICByZXR1cm4gc2l6ZTsKK30KKworc3RhdGljIGludCBidWZmZXJfZ2V0YnVmZmVyKFB5QnVmZmVyT2JqZWN0ICpzZWxmLCBQeV9idWZmZXIgKmJ1ZiwgaW50IGZsYWdzKQoreworICAgIHZvaWQgKnB0cjsKKyAgICBQeV9zc2l6ZV90IHNpemU7CisgICAgaWYgKCFnZXRfYnVmKHNlbGYsICZwdHIsICZzaXplLCBBTllfQlVGRkVSKSkKKyAgICAgICAgcmV0dXJuIC0xOworICAgIHJldHVybiBQeUJ1ZmZlcl9GaWxsSW5mbyhidWYsIChQeU9iamVjdCopc2VsZiwgcHRyLCBzaXplLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLT5iX3JlYWRvbmx5LCBmbGFncyk7Cit9CisKK3N0YXRpYyBQeVNlcXVlbmNlTWV0aG9kcyBidWZmZXJfYXNfc2VxdWVuY2UgPSB7CisgICAgKGxlbmZ1bmMpYnVmZmVyX2xlbmd0aCwgLypzcV9sZW5ndGgqLworICAgIChiaW5hcnlmdW5jKWJ1ZmZlcl9jb25jYXQsIC8qc3FfY29uY2F0Ki8KKyAgICAoc3NpemVhcmdmdW5jKWJ1ZmZlcl9yZXBlYXQsIC8qc3FfcmVwZWF0Ki8KKyAgICAoc3NpemVhcmdmdW5jKWJ1ZmZlcl9pdGVtLCAvKnNxX2l0ZW0qLworICAgIChzc2l6ZXNzaXplYXJnZnVuYylidWZmZXJfc2xpY2UsIC8qc3Ffc2xpY2UqLworICAgIChzc2l6ZW9iamFyZ3Byb2MpYnVmZmVyX2Fzc19pdGVtLCAvKnNxX2Fzc19pdGVtKi8KKyAgICAoc3NpemVzc2l6ZW9iamFyZ3Byb2MpYnVmZmVyX2Fzc19zbGljZSwgLypzcV9hc3Nfc2xpY2UqLworfTsKKworc3RhdGljIFB5TWFwcGluZ01ldGhvZHMgYnVmZmVyX2FzX21hcHBpbmcgPSB7CisgICAgKGxlbmZ1bmMpYnVmZmVyX2xlbmd0aCwKKyAgICAoYmluYXJ5ZnVuYylidWZmZXJfc3Vic2NyaXB0LAorICAgIChvYmpvYmphcmdwcm9jKWJ1ZmZlcl9hc3Nfc3Vic2NyaXB0LAorfTsKKworc3RhdGljIFB5QnVmZmVyUHJvY3MgYnVmZmVyX2FzX2J1ZmZlciA9IHsKKyAgICAocmVhZGJ1ZmZlcnByb2MpYnVmZmVyX2dldHJlYWRidWYsCisgICAgKHdyaXRlYnVmZmVycHJvYylidWZmZXJfZ2V0d3JpdGVidWYsCisgICAgKHNlZ2NvdW50cHJvYylidWZmZXJfZ2V0c2VnY291bnQsCisgICAgKGNoYXJidWZmZXJwcm9jKWJ1ZmZlcl9nZXRjaGFyYnVmLAorICAgIChnZXRidWZmZXJwcm9jKWJ1ZmZlcl9nZXRidWZmZXIsCit9OworCitQeVR5cGVPYmplY3QgUHlCdWZmZXJfVHlwZSA9IHsKKyAgICBQeVZhck9iamVjdF9IRUFEX0lOSVQoJlB5VHlwZV9UeXBlLCAwKQorICAgICJidWZmZXIiLAorICAgIHNpemVvZihQeUJ1ZmZlck9iamVjdCksCisgICAgMCwKKyAgICAoZGVzdHJ1Y3RvcilidWZmZXJfZGVhbGxvYywgICAgICAgICAgICAgICAgIC8qIHRwX2RlYWxsb2MgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3ByaW50ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9nZXRhdHRyICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9zZXRhdHRyICovCisgICAgKGNtcGZ1bmMpYnVmZmVyX2NvbXBhcmUsICAgICAgICAgICAgICAgICAgICAvKiB0cF9jb21wYXJlICovCisgICAgKHJlcHJmdW5jKWJ1ZmZlcl9yZXByLCAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9yZXByICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9hc19udW1iZXIgKi8KKyAgICAmYnVmZmVyX2FzX3NlcXVlbmNlLCAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2FzX3NlcXVlbmNlICovCisgICAgJmJ1ZmZlcl9hc19tYXBwaW5nLCAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9hc19tYXBwaW5nICovCisgICAgKGhhc2hmdW5jKWJ1ZmZlcl9oYXNoLCAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9oYXNoICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9jYWxsICovCisgICAgKHJlcHJmdW5jKWJ1ZmZlcl9zdHIsICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9zdHIgKi8KKyAgICBQeU9iamVjdF9HZW5lcmljR2V0QXR0ciwgICAgICAgICAgICAgICAgICAgIC8qIHRwX2dldGF0dHJvICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9zZXRhdHRybyAqLworICAgICZidWZmZXJfYXNfYnVmZmVyLCAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfYXNfYnVmZmVyICovCisgICAgUHlfVFBGTEFHU19ERUZBVUxUIHwgUHlfVFBGTEFHU19IQVZFX0dFVENIQVJCVUZGRVIgfCBQeV9UUEZMQUdTX0hBVkVfTkVXQlVGRkVSLCAvKiB0cF9mbGFncyAqLworICAgIGJ1ZmZlcl9kb2MsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZG9jICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF90cmF2ZXJzZSAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfY2xlYXIgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3JpY2hjb21wYXJlICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF93ZWFrbGlzdG9mZnNldCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfaXRlciAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfaXRlcm5leHQgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX21ldGhvZHMgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX21lbWJlcnMgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2dldHNldCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfYmFzZSAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZGljdCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZGVzY3JfZ2V0ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9kZXNjcl9zZXQgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2RpY3RvZmZzZXQgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2luaXQgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2FsbG9jICovCisgICAgYnVmZmVyX25ldywgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9uZXcgKi8KK307ClwgTm8gbmV3bGluZSBhdCBlbmQgb2YgZmlsZQpkaWZmIC0tZ2l0IGEvUHl0aG9uLTIuNy41L09iamVjdHMvYnl0ZWFycmF5b2JqZWN0LmMgYi9QeXRob24tMi43LjUvT2JqZWN0cy9ieXRlYXJyYXlvYmplY3QuYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yMWM1OGNlCi0tLSAvZGV2L251bGwKKysrIGIvUHl0aG9uLTIuNy41L09iamVjdHMvYnl0ZWFycmF5b2JqZWN0LmMKQEAgLTAsMCArMSwzMDU0IEBACisvKiBQeUJ5dGVzIChieXRlYXJyYXkpIGltcGxlbWVudGF0aW9uICovCisKKyNkZWZpbmUgUFlfU1NJWkVfVF9DTEVBTgorI2luY2x1ZGUgIlB5dGhvbi5oIgorI2luY2x1ZGUgInN0cnVjdG1lbWJlci5oIgorI2luY2x1ZGUgImJ5dGVzX21ldGhvZHMuaCIKKworY2hhciBfUHlCeXRlQXJyYXlfZW1wdHlfc3RyaW5nW10gPSAiIjsKKwordm9pZAorUHlCeXRlQXJyYXlfRmluaSh2b2lkKQoreworfQorCitpbnQKK1B5Qnl0ZUFycmF5X0luaXQodm9pZCkKK3sKKyAgICByZXR1cm4gMTsKK30KKworLyogZW5kIG51bGxieXRlcyBzdXBwb3J0ICovCisKKy8qIEhlbHBlcnMgKi8KKworc3RhdGljIGludAorX2dldGJ5dGV2YWx1ZShQeU9iamVjdCogYXJnLCBpbnQgKnZhbHVlKQoreworICAgIGxvbmcgZmFjZV92YWx1ZTsKKworICAgIGlmIChQeUJ5dGVzX0NoZWNrRXhhY3QoYXJnKSkgeworICAgICAgICBpZiAoUHlfU0laRShhcmcpICE9IDEpIHsKKyAgICAgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19WYWx1ZUVycm9yLCAic3RyaW5nIG11c3QgYmUgb2Ygc2l6ZSAxIik7CisgICAgICAgICAgICByZXR1cm4gMDsKKyAgICAgICAgfQorICAgICAgICAqdmFsdWUgPSBQeV9DSEFSTUFTSygoKFB5Qnl0ZXNPYmplY3QqKWFyZyktPm9iX3N2YWxbMF0pOworICAgICAgICByZXR1cm4gMTsKKyAgICB9CisgICAgZWxzZSBpZiAoUHlJbnRfQ2hlY2soYXJnKSB8fCBQeUxvbmdfQ2hlY2soYXJnKSkgeworICAgICAgICBmYWNlX3ZhbHVlID0gUHlMb25nX0FzTG9uZyhhcmcpOworICAgIH0KKyAgICBlbHNlIHsKKyAgICAgICAgUHlPYmplY3QgKmluZGV4ID0gUHlOdW1iZXJfSW5kZXgoYXJnKTsKKyAgICAgICAgaWYgKGluZGV4ID09IE5VTEwpIHsKKyAgICAgICAgICAgIFB5RXJyX0Zvcm1hdChQeUV4Y19UeXBlRXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgImFuIGludGVnZXIgb3Igc3RyaW5nIG9mIHNpemUgMSBpcyByZXF1aXJlZCIpOworICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgIH0KKyAgICAgICAgZmFjZV92YWx1ZSA9IFB5TG9uZ19Bc0xvbmcoaW5kZXgpOworICAgICAgICBQeV9ERUNSRUYoaW5kZXgpOworICAgIH0KKworICAgIGlmIChmYWNlX3ZhbHVlIDwgMCB8fCBmYWNlX3ZhbHVlID49IDI1NikgeworICAgICAgICAvKiB0aGlzIGluY2x1ZGVzIHRoZSBPdmVyZmxvd0Vycm9yIGluIGNhc2UgdGhlIGxvbmcgaXMgdG9vIGxhcmdlICovCisgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19WYWx1ZUVycm9yLCAiYnl0ZSBtdXN0IGJlIGluIHJhbmdlKDAsIDI1NikiKTsKKyAgICAgICAgcmV0dXJuIDA7CisgICAgfQorCisgICAgKnZhbHVlID0gZmFjZV92YWx1ZTsKKyAgICByZXR1cm4gMTsKK30KKworc3RhdGljIFB5X3NzaXplX3QKK2J5dGVhcnJheV9idWZmZXJfZ2V0cmVhZGJ1ZihQeUJ5dGVBcnJheU9iamVjdCAqc2VsZiwgUHlfc3NpemVfdCBpbmRleCwgY29uc3Qgdm9pZCAqKnB0cikKK3sKKyAgICBpZiAoIGluZGV4ICE9IDAgKSB7CisgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19TeXN0ZW1FcnJvciwKKyAgICAgICAgICAgICAgICAiYWNjZXNzaW5nIG5vbi1leGlzdGVudCBieXRlcyBzZWdtZW50Iik7CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisgICAgKnB0ciA9ICh2b2lkICopUHlCeXRlQXJyYXlfQVNfU1RSSU5HKHNlbGYpOworICAgIHJldHVybiBQeV9TSVpFKHNlbGYpOworfQorCitzdGF0aWMgUHlfc3NpemVfdAorYnl0ZWFycmF5X2J1ZmZlcl9nZXR3cml0ZWJ1ZihQeUJ5dGVBcnJheU9iamVjdCAqc2VsZiwgUHlfc3NpemVfdCBpbmRleCwgY29uc3Qgdm9pZCAqKnB0cikKK3sKKyAgICBpZiAoIGluZGV4ICE9IDAgKSB7CisgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19TeXN0ZW1FcnJvciwKKyAgICAgICAgICAgICAgICAiYWNjZXNzaW5nIG5vbi1leGlzdGVudCBieXRlcyBzZWdtZW50Iik7CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisgICAgKnB0ciA9ICh2b2lkICopUHlCeXRlQXJyYXlfQVNfU1RSSU5HKHNlbGYpOworICAgIHJldHVybiBQeV9TSVpFKHNlbGYpOworfQorCitzdGF0aWMgUHlfc3NpemVfdAorYnl0ZWFycmF5X2J1ZmZlcl9nZXRzZWdjb3VudChQeUJ5dGVBcnJheU9iamVjdCAqc2VsZiwgUHlfc3NpemVfdCAqbGVucCkKK3sKKyAgICBpZiAoIGxlbnAgKQorICAgICAgICAqbGVucCA9IFB5X1NJWkUoc2VsZik7CisgICAgcmV0dXJuIDE7Cit9CisKK3N0YXRpYyBQeV9zc2l6ZV90CitieXRlYXJyYXlfYnVmZmVyX2dldGNoYXJidWYoUHlCeXRlQXJyYXlPYmplY3QgKnNlbGYsIFB5X3NzaXplX3QgaW5kZXgsIGNvbnN0IGNoYXIgKipwdHIpCit7CisgICAgaWYgKCBpbmRleCAhPSAwICkgeworICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfU3lzdGVtRXJyb3IsCisgICAgICAgICAgICAgICAgImFjY2Vzc2luZyBub24tZXhpc3RlbnQgYnl0ZXMgc2VnbWVudCIpOworICAgICAgICByZXR1cm4gLTE7CisgICAgfQorICAgICpwdHIgPSBQeUJ5dGVBcnJheV9BU19TVFJJTkcoc2VsZik7CisgICAgcmV0dXJuIFB5X1NJWkUoc2VsZik7Cit9CisKK3N0YXRpYyBpbnQKK2J5dGVhcnJheV9nZXRidWZmZXIoUHlCeXRlQXJyYXlPYmplY3QgKm9iaiwgUHlfYnVmZmVyICp2aWV3LCBpbnQgZmxhZ3MpCit7CisgICAgaW50IHJldDsKKyAgICB2b2lkICpwdHI7CisgICAgaWYgKHZpZXcgPT0gTlVMTCkgeworICAgICAgICBvYmotPm9iX2V4cG9ydHMrKzsKKyAgICAgICAgcmV0dXJuIDA7CisgICAgfQorICAgIHB0ciA9ICh2b2lkICopIFB5Qnl0ZUFycmF5X0FTX1NUUklORyhvYmopOworICAgIHJldCA9IFB5QnVmZmVyX0ZpbGxJbmZvKHZpZXcsIChQeU9iamVjdCopb2JqLCBwdHIsIFB5X1NJWkUob2JqKSwgMCwgZmxhZ3MpOworICAgIGlmIChyZXQgPj0gMCkgeworICAgICAgICBvYmotPm9iX2V4cG9ydHMrKzsKKyAgICB9CisgICAgcmV0dXJuIHJldDsKK30KKworc3RhdGljIHZvaWQKK2J5dGVhcnJheV9yZWxlYXNlYnVmZmVyKFB5Qnl0ZUFycmF5T2JqZWN0ICpvYmosIFB5X2J1ZmZlciAqdmlldykKK3sKKyAgICBvYmotPm9iX2V4cG9ydHMtLTsKK30KKworc3RhdGljIFB5X3NzaXplX3QKK19nZXRidWZmZXIoUHlPYmplY3QgKm9iaiwgUHlfYnVmZmVyICp2aWV3KQoreworICAgIFB5QnVmZmVyUHJvY3MgKmJ1ZmZlciA9IFB5X1RZUEUob2JqKS0+dHBfYXNfYnVmZmVyOworCisgICAgaWYgKGJ1ZmZlciA9PSBOVUxMIHx8IGJ1ZmZlci0+YmZfZ2V0YnVmZmVyID09IE5VTEwpCisgICAgeworICAgICAgICBQeUVycl9Gb3JtYXQoUHlFeGNfVHlwZUVycm9yLAorICAgICAgICAgICAgICAgICAgICAgIlR5cGUgJS4xMDBzIGRvZXNuJ3Qgc3VwcG9ydCB0aGUgYnVmZmVyIEFQSSIsCisgICAgICAgICAgICAgICAgICAgICBQeV9UWVBFKG9iaiktPnRwX25hbWUpOworICAgICAgICByZXR1cm4gLTE7CisgICAgfQorCisgICAgaWYgKGJ1ZmZlci0+YmZfZ2V0YnVmZmVyKG9iaiwgdmlldywgUHlCVUZfU0lNUExFKSA8IDApCisgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgcmV0dXJuIHZpZXctPmxlbjsKK30KKworc3RhdGljIGludAorX2NhbnJlc2l6ZShQeUJ5dGVBcnJheU9iamVjdCAqc2VsZikKK3sKKyAgICBpZiAoc2VsZi0+b2JfZXhwb3J0cyA+IDApIHsKKyAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX0J1ZmZlckVycm9yLAorICAgICAgICAgICAgICAgICJFeGlzdGluZyBleHBvcnRzIG9mIGRhdGE6IG9iamVjdCBjYW5ub3QgYmUgcmUtc2l6ZWQiKTsKKyAgICAgICAgcmV0dXJuIDA7CisgICAgfQorICAgIHJldHVybiAxOworfQorCisvKiBEaXJlY3QgQVBJIGZ1bmN0aW9ucyAqLworCitQeU9iamVjdCAqCitQeUJ5dGVBcnJheV9Gcm9tT2JqZWN0KFB5T2JqZWN0ICppbnB1dCkKK3sKKyAgICByZXR1cm4gUHlPYmplY3RfQ2FsbEZ1bmN0aW9uT2JqQXJncygoUHlPYmplY3QgKikmUHlCeXRlQXJyYXlfVHlwZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnB1dCwgTlVMTCk7Cit9CisKK1B5T2JqZWN0ICoKK1B5Qnl0ZUFycmF5X0Zyb21TdHJpbmdBbmRTaXplKGNvbnN0IGNoYXIgKmJ5dGVzLCBQeV9zc2l6ZV90IHNpemUpCit7CisgICAgUHlCeXRlQXJyYXlPYmplY3QgKm5ldzsKKyAgICBQeV9zc2l6ZV90IGFsbG9jOworCisgICAgaWYgKHNpemUgPCAwKSB7CisgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19TeXN0ZW1FcnJvciwKKyAgICAgICAgICAgICJOZWdhdGl2ZSBzaXplIHBhc3NlZCB0byBQeUJ5dGVBcnJheV9Gcm9tU3RyaW5nQW5kU2l6ZSIpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisKKyAgICBuZXcgPSBQeU9iamVjdF9OZXcoUHlCeXRlQXJyYXlPYmplY3QsICZQeUJ5dGVBcnJheV9UeXBlKTsKKyAgICBpZiAobmV3ID09IE5VTEwpCisgICAgICAgIHJldHVybiBOVUxMOworCisgICAgaWYgKHNpemUgPT0gMCkgeworICAgICAgICBuZXctPm9iX2J5dGVzID0gTlVMTDsKKyAgICAgICAgYWxsb2MgPSAwOworICAgIH0KKyAgICBlbHNlIHsKKyAgICAgICAgYWxsb2MgPSBzaXplICsgMTsKKyAgICAgICAgbmV3LT5vYl9ieXRlcyA9IFB5TWVtX01hbGxvYyhhbGxvYyk7CisgICAgICAgIGlmIChuZXctPm9iX2J5dGVzID09IE5VTEwpIHsKKyAgICAgICAgICAgIFB5X0RFQ1JFRihuZXcpOworICAgICAgICAgICAgcmV0dXJuIFB5RXJyX05vTWVtb3J5KCk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGJ5dGVzICE9IE5VTEwgJiYgc2l6ZSA+IDApCisgICAgICAgICAgICBtZW1jcHkobmV3LT5vYl9ieXRlcywgYnl0ZXMsIHNpemUpOworICAgICAgICBuZXctPm9iX2J5dGVzW3NpemVdID0gJ1wwJzsgIC8qIFRyYWlsaW5nIG51bGwgYnl0ZSAqLworICAgIH0KKyAgICBQeV9TSVpFKG5ldykgPSBzaXplOworICAgIG5ldy0+b2JfYWxsb2MgPSBhbGxvYzsKKyAgICBuZXctPm9iX2V4cG9ydHMgPSAwOworCisgICAgcmV0dXJuIChQeU9iamVjdCAqKW5ldzsKK30KKworUHlfc3NpemVfdAorUHlCeXRlQXJyYXlfU2l6ZShQeU9iamVjdCAqc2VsZikKK3sKKyAgICBhc3NlcnQoc2VsZiAhPSBOVUxMKTsKKyAgICBhc3NlcnQoUHlCeXRlQXJyYXlfQ2hlY2soc2VsZikpOworCisgICAgcmV0dXJuIFB5Qnl0ZUFycmF5X0dFVF9TSVpFKHNlbGYpOworfQorCitjaGFyICAqCitQeUJ5dGVBcnJheV9Bc1N0cmluZyhQeU9iamVjdCAqc2VsZikKK3sKKyAgICBhc3NlcnQoc2VsZiAhPSBOVUxMKTsKKyAgICBhc3NlcnQoUHlCeXRlQXJyYXlfQ2hlY2soc2VsZikpOworCisgICAgcmV0dXJuIFB5Qnl0ZUFycmF5X0FTX1NUUklORyhzZWxmKTsKK30KKworaW50CitQeUJ5dGVBcnJheV9SZXNpemUoUHlPYmplY3QgKnNlbGYsIFB5X3NzaXplX3Qgc2l6ZSkKK3sKKyAgICB2b2lkICpzdmFsOworICAgIFB5X3NzaXplX3QgYWxsb2MgPSAoKFB5Qnl0ZUFycmF5T2JqZWN0ICopc2VsZiktPm9iX2FsbG9jOworCisgICAgYXNzZXJ0KHNlbGYgIT0gTlVMTCk7CisgICAgYXNzZXJ0KFB5Qnl0ZUFycmF5X0NoZWNrKHNlbGYpKTsKKyAgICBhc3NlcnQoc2l6ZSA+PSAwKTsKKworICAgIGlmIChzaXplID09IFB5X1NJWkUoc2VsZikpIHsKKyAgICAgICAgcmV0dXJuIDA7CisgICAgfQorICAgIGlmICghX2NhbnJlc2l6ZSgoUHlCeXRlQXJyYXlPYmplY3QgKilzZWxmKSkgeworICAgICAgICByZXR1cm4gLTE7CisgICAgfQorCisgICAgaWYgKHNpemUgPCBhbGxvYyAvIDIpIHsKKyAgICAgICAgLyogTWFqb3IgZG93bnNpemU7IHJlc2l6ZSBkb3duIHRvIGV4YWN0IHNpemUgKi8KKyAgICAgICAgYWxsb2MgPSBzaXplICsgMTsKKyAgICB9CisgICAgZWxzZSBpZiAoc2l6ZSA8IGFsbG9jKSB7CisgICAgICAgIC8qIFdpdGhpbiBhbGxvY2F0ZWQgc2l6ZTsgcXVpY2sgZXhpdCAqLworICAgICAgICBQeV9TSVpFKHNlbGYpID0gc2l6ZTsKKyAgICAgICAgKChQeUJ5dGVBcnJheU9iamVjdCAqKXNlbGYpLT5vYl9ieXRlc1tzaXplXSA9ICdcMCc7IC8qIFRyYWlsaW5nIG51bGwgKi8KKyAgICAgICAgcmV0dXJuIDA7CisgICAgfQorICAgIGVsc2UgaWYgKHNpemUgPD0gYWxsb2MgKiAxLjEyNSkgeworICAgICAgICAvKiBNb2RlcmF0ZSB1cHNpemU7IG92ZXJhbGxvY2F0ZSBzaW1pbGFyIHRvIGxpc3RfcmVzaXplKCkgKi8KKyAgICAgICAgYWxsb2MgPSBzaXplICsgKHNpemUgPj4gMykgKyAoc2l6ZSA8IDkgPyAzIDogNik7CisgICAgfQorICAgIGVsc2UgeworICAgICAgICAvKiBNYWpvciB1cHNpemU7IHJlc2l6ZSB1cCB0byBleGFjdCBzaXplICovCisgICAgICAgIGFsbG9jID0gc2l6ZSArIDE7CisgICAgfQorCisgICAgc3ZhbCA9IFB5TWVtX1JlYWxsb2MoKChQeUJ5dGVBcnJheU9iamVjdCAqKXNlbGYpLT5vYl9ieXRlcywgYWxsb2MpOworICAgIGlmIChzdmFsID09IE5VTEwpIHsKKyAgICAgICAgUHlFcnJfTm9NZW1vcnkoKTsKKyAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKworICAgICgoUHlCeXRlQXJyYXlPYmplY3QgKilzZWxmKS0+b2JfYnl0ZXMgPSBzdmFsOworICAgIFB5X1NJWkUoc2VsZikgPSBzaXplOworICAgICgoUHlCeXRlQXJyYXlPYmplY3QgKilzZWxmKS0+b2JfYWxsb2MgPSBhbGxvYzsKKyAgICAoKFB5Qnl0ZUFycmF5T2JqZWN0ICopc2VsZiktPm9iX2J5dGVzW3NpemVdID0gJ1wwJzsgLyogVHJhaWxpbmcgbnVsbCBieXRlICovCisKKyAgICByZXR1cm4gMDsKK30KKworUHlPYmplY3QgKgorUHlCeXRlQXJyYXlfQ29uY2F0KFB5T2JqZWN0ICphLCBQeU9iamVjdCAqYikKK3sKKyAgICBQeV9zc2l6ZV90IHNpemU7CisgICAgUHlfYnVmZmVyIHZhLCB2YjsKKyAgICBQeUJ5dGVBcnJheU9iamVjdCAqcmVzdWx0ID0gTlVMTDsKKworICAgIHZhLmxlbiA9IC0xOworICAgIHZiLmxlbiA9IC0xOworICAgIGlmIChfZ2V0YnVmZmVyKGEsICZ2YSkgPCAwICB8fAorICAgICAgICBfZ2V0YnVmZmVyKGIsICZ2YikgPCAwKSB7CisgICAgICAgICAgICBQeUVycl9Gb3JtYXQoUHlFeGNfVHlwZUVycm9yLCAiY2FuJ3QgY29uY2F0ICUuMTAwcyB0byAlLjEwMHMiLAorICAgICAgICAgICAgICAgICAgICAgICAgIFB5X1RZUEUoYSktPnRwX25hbWUsIFB5X1RZUEUoYiktPnRwX25hbWUpOworICAgICAgICAgICAgZ290byBkb25lOworICAgIH0KKworICAgIHNpemUgPSB2YS5sZW4gKyB2Yi5sZW47CisgICAgaWYgKHNpemUgPCAwKSB7CisgICAgICAgICAgICBQeUVycl9Ob01lbW9yeSgpOworICAgICAgICAgICAgZ290byBkb25lOworICAgIH0KKworICAgIHJlc3VsdCA9IChQeUJ5dGVBcnJheU9iamVjdCAqKSBQeUJ5dGVBcnJheV9Gcm9tU3RyaW5nQW5kU2l6ZShOVUxMLCBzaXplKTsKKyAgICBpZiAocmVzdWx0ICE9IE5VTEwpIHsKKyAgICAgICAgbWVtY3B5KHJlc3VsdC0+b2JfYnl0ZXMsIHZhLmJ1ZiwgdmEubGVuKTsKKyAgICAgICAgbWVtY3B5KHJlc3VsdC0+b2JfYnl0ZXMgKyB2YS5sZW4sIHZiLmJ1ZiwgdmIubGVuKTsKKyAgICB9CisKKyAgZG9uZToKKyAgICBpZiAodmEubGVuICE9IC0xKQorICAgICAgICBQeUJ1ZmZlcl9SZWxlYXNlKCZ2YSk7CisgICAgaWYgKHZiLmxlbiAhPSAtMSkKKyAgICAgICAgUHlCdWZmZXJfUmVsZWFzZSgmdmIpOworICAgIHJldHVybiAoUHlPYmplY3QgKilyZXN1bHQ7Cit9CisKKy8qIEZ1bmN0aW9ucyBzdHVmZmVkIGludG8gdGhlIHR5cGUgb2JqZWN0ICovCisKK3N0YXRpYyBQeV9zc2l6ZV90CitieXRlYXJyYXlfbGVuZ3RoKFB5Qnl0ZUFycmF5T2JqZWN0ICpzZWxmKQoreworICAgIHJldHVybiBQeV9TSVpFKHNlbGYpOworfQorCitzdGF0aWMgUHlPYmplY3QgKgorYnl0ZWFycmF5X2ljb25jYXQoUHlCeXRlQXJyYXlPYmplY3QgKnNlbGYsIFB5T2JqZWN0ICpvdGhlcikKK3sKKyAgICBQeV9zc2l6ZV90IG15c2l6ZTsKKyAgICBQeV9zc2l6ZV90IHNpemU7CisgICAgUHlfYnVmZmVyIHZvOworCisgICAgaWYgKF9nZXRidWZmZXIob3RoZXIsICZ2bykgPCAwKSB7CisgICAgICAgIFB5RXJyX0Zvcm1hdChQeUV4Y19UeXBlRXJyb3IsICJjYW4ndCBjb25jYXQgJS4xMDBzIHRvICUuMTAwcyIsCisgICAgICAgICAgICAgICAgICAgICBQeV9UWVBFKG90aGVyKS0+dHBfbmFtZSwgUHlfVFlQRShzZWxmKS0+dHBfbmFtZSk7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKworICAgIG15c2l6ZSA9IFB5X1NJWkUoc2VsZik7CisgICAgc2l6ZSA9IG15c2l6ZSArIHZvLmxlbjsKKyAgICBpZiAoc2l6ZSA8IDApIHsKKyAgICAgICAgUHlCdWZmZXJfUmVsZWFzZSgmdm8pOworICAgICAgICByZXR1cm4gUHlFcnJfTm9NZW1vcnkoKTsKKyAgICB9CisgICAgaWYgKHNpemUgPCBzZWxmLT5vYl9hbGxvYykgeworICAgICAgICBQeV9TSVpFKHNlbGYpID0gc2l6ZTsKKyAgICAgICAgc2VsZi0+b2JfYnl0ZXNbUHlfU0laRShzZWxmKV0gPSAnXDAnOyAvKiBUcmFpbGluZyBudWxsIGJ5dGUgKi8KKyAgICB9CisgICAgZWxzZSBpZiAoUHlCeXRlQXJyYXlfUmVzaXplKChQeU9iamVjdCAqKXNlbGYsIHNpemUpIDwgMCkgeworICAgICAgICBQeUJ1ZmZlcl9SZWxlYXNlKCZ2byk7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICBtZW1jcHkoc2VsZi0+b2JfYnl0ZXMgKyBteXNpemUsIHZvLmJ1Ziwgdm8ubGVuKTsKKyAgICBQeUJ1ZmZlcl9SZWxlYXNlKCZ2byk7CisgICAgUHlfSU5DUkVGKHNlbGYpOworICAgIHJldHVybiAoUHlPYmplY3QgKilzZWxmOworfQorCitzdGF0aWMgUHlPYmplY3QgKgorYnl0ZWFycmF5X3JlcGVhdChQeUJ5dGVBcnJheU9iamVjdCAqc2VsZiwgUHlfc3NpemVfdCBjb3VudCkKK3sKKyAgICBQeUJ5dGVBcnJheU9iamVjdCAqcmVzdWx0OworICAgIFB5X3NzaXplX3QgbXlzaXplOworICAgIFB5X3NzaXplX3Qgc2l6ZTsKKworICAgIGlmIChjb3VudCA8IDApCisgICAgICAgIGNvdW50ID0gMDsKKyAgICBteXNpemUgPSBQeV9TSVpFKHNlbGYpOworICAgIHNpemUgPSBteXNpemUgKiBjb3VudDsKKyAgICBpZiAoY291bnQgIT0gMCAmJiBzaXplIC8gY291bnQgIT0gbXlzaXplKQorICAgICAgICByZXR1cm4gUHlFcnJfTm9NZW1vcnkoKTsKKyAgICByZXN1bHQgPSAoUHlCeXRlQXJyYXlPYmplY3QgKilQeUJ5dGVBcnJheV9Gcm9tU3RyaW5nQW5kU2l6ZShOVUxMLCBzaXplKTsKKyAgICBpZiAocmVzdWx0ICE9IE5VTEwgJiYgc2l6ZSAhPSAwKSB7CisgICAgICAgIGlmIChteXNpemUgPT0gMSkKKyAgICAgICAgICAgIG1lbXNldChyZXN1bHQtPm9iX2J5dGVzLCBzZWxmLT5vYl9ieXRlc1swXSwgc2l6ZSk7CisgICAgICAgIGVsc2UgeworICAgICAgICAgICAgUHlfc3NpemVfdCBpOworICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IGNvdW50OyBpKyspCisgICAgICAgICAgICAgICAgbWVtY3B5KHJlc3VsdC0+b2JfYnl0ZXMgKyBpKm15c2l6ZSwgc2VsZi0+b2JfYnl0ZXMsIG15c2l6ZSk7CisgICAgICAgIH0KKyAgICB9CisgICAgcmV0dXJuIChQeU9iamVjdCAqKXJlc3VsdDsKK30KKworc3RhdGljIFB5T2JqZWN0ICoKK2J5dGVhcnJheV9pcmVwZWF0KFB5Qnl0ZUFycmF5T2JqZWN0ICpzZWxmLCBQeV9zc2l6ZV90IGNvdW50KQoreworICAgIFB5X3NzaXplX3QgbXlzaXplOworICAgIFB5X3NzaXplX3Qgc2l6ZTsKKworICAgIGlmIChjb3VudCA8IDApCisgICAgICAgIGNvdW50ID0gMDsKKyAgICBteXNpemUgPSBQeV9TSVpFKHNlbGYpOworICAgIHNpemUgPSBteXNpemUgKiBjb3VudDsKKyAgICBpZiAoY291bnQgIT0gMCAmJiBzaXplIC8gY291bnQgIT0gbXlzaXplKQorICAgICAgICByZXR1cm4gUHlFcnJfTm9NZW1vcnkoKTsKKyAgICBpZiAoc2l6ZSA8IHNlbGYtPm9iX2FsbG9jKSB7CisgICAgICAgIFB5X1NJWkUoc2VsZikgPSBzaXplOworICAgICAgICBzZWxmLT5vYl9ieXRlc1tQeV9TSVpFKHNlbGYpXSA9ICdcMCc7IC8qIFRyYWlsaW5nIG51bGwgYnl0ZSAqLworICAgIH0KKyAgICBlbHNlIGlmIChQeUJ5dGVBcnJheV9SZXNpemUoKFB5T2JqZWN0ICopc2VsZiwgc2l6ZSkgPCAwKQorICAgICAgICByZXR1cm4gTlVMTDsKKworICAgIGlmIChteXNpemUgPT0gMSkKKyAgICAgICAgbWVtc2V0KHNlbGYtPm9iX2J5dGVzLCBzZWxmLT5vYl9ieXRlc1swXSwgc2l6ZSk7CisgICAgZWxzZSB7CisgICAgICAgIFB5X3NzaXplX3QgaTsKKyAgICAgICAgZm9yIChpID0gMTsgaSA8IGNvdW50OyBpKyspCisgICAgICAgICAgICBtZW1jcHkoc2VsZi0+b2JfYnl0ZXMgKyBpKm15c2l6ZSwgc2VsZi0+b2JfYnl0ZXMsIG15c2l6ZSk7CisgICAgfQorCisgICAgUHlfSU5DUkVGKHNlbGYpOworICAgIHJldHVybiAoUHlPYmplY3QgKilzZWxmOworfQorCitzdGF0aWMgUHlPYmplY3QgKgorYnl0ZWFycmF5X2dldGl0ZW0oUHlCeXRlQXJyYXlPYmplY3QgKnNlbGYsIFB5X3NzaXplX3QgaSkKK3sKKyAgICBpZiAoaSA8IDApCisgICAgICAgIGkgKz0gUHlfU0laRShzZWxmKTsKKyAgICBpZiAoaSA8IDAgfHwgaSA+PSBQeV9TSVpFKHNlbGYpKSB7CisgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19JbmRleEVycm9yLCAiYnl0ZWFycmF5IGluZGV4IG91dCBvZiByYW5nZSIpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgcmV0dXJuIFB5SW50X0Zyb21Mb25nKCh1bnNpZ25lZCBjaGFyKShzZWxmLT5vYl9ieXRlc1tpXSkpOworfQorCitzdGF0aWMgUHlPYmplY3QgKgorYnl0ZWFycmF5X3N1YnNjcmlwdChQeUJ5dGVBcnJheU9iamVjdCAqc2VsZiwgUHlPYmplY3QgKmluZGV4KQoreworICAgIGlmIChQeUluZGV4X0NoZWNrKGluZGV4KSkgeworICAgICAgICBQeV9zc2l6ZV90IGkgPSBQeU51bWJlcl9Bc1NzaXplX3QoaW5kZXgsIFB5RXhjX0luZGV4RXJyb3IpOworCisgICAgICAgIGlmIChpID09IC0xICYmIFB5RXJyX09jY3VycmVkKCkpCisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKworICAgICAgICBpZiAoaSA8IDApCisgICAgICAgICAgICBpICs9IFB5Qnl0ZUFycmF5X0dFVF9TSVpFKHNlbGYpOworCisgICAgICAgIGlmIChpIDwgMCB8fCBpID49IFB5X1NJWkUoc2VsZikpIHsKKyAgICAgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19JbmRleEVycm9yLCAiYnl0ZWFycmF5IGluZGV4IG91dCBvZiByYW5nZSIpOworICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIFB5SW50X0Zyb21Mb25nKCh1bnNpZ25lZCBjaGFyKShzZWxmLT5vYl9ieXRlc1tpXSkpOworICAgIH0KKyAgICBlbHNlIGlmIChQeVNsaWNlX0NoZWNrKGluZGV4KSkgeworICAgICAgICBQeV9zc2l6ZV90IHN0YXJ0LCBzdG9wLCBzdGVwLCBzbGljZWxlbmd0aCwgY3VyLCBpOworICAgICAgICBpZiAoUHlTbGljZV9HZXRJbmRpY2VzRXgoKFB5U2xpY2VPYmplY3QgKilpbmRleCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFB5Qnl0ZUFycmF5X0dFVF9TSVpFKHNlbGYpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnN0YXJ0LCAmc3RvcCwgJnN0ZXAsICZzbGljZWxlbmd0aCkgPCAwKSB7CisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChzbGljZWxlbmd0aCA8PSAwKQorICAgICAgICAgICAgcmV0dXJuIFB5Qnl0ZUFycmF5X0Zyb21TdHJpbmdBbmRTaXplKCIiLCAwKTsKKyAgICAgICAgZWxzZSBpZiAoc3RlcCA9PSAxKSB7CisgICAgICAgICAgICByZXR1cm4gUHlCeXRlQXJyYXlfRnJvbVN0cmluZ0FuZFNpemUoc2VsZi0+b2JfYnl0ZXMgKyBzdGFydCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNsaWNlbGVuZ3RoKTsKKyAgICAgICAgfQorICAgICAgICBlbHNlIHsKKyAgICAgICAgICAgIGNoYXIgKnNvdXJjZV9idWYgPSBQeUJ5dGVBcnJheV9BU19TVFJJTkcoc2VsZik7CisgICAgICAgICAgICBjaGFyICpyZXN1bHRfYnVmID0gKGNoYXIgKilQeU1lbV9NYWxsb2Moc2xpY2VsZW5ndGgpOworICAgICAgICAgICAgUHlPYmplY3QgKnJlc3VsdDsKKworICAgICAgICAgICAgaWYgKHJlc3VsdF9idWYgPT0gTlVMTCkKKyAgICAgICAgICAgICAgICByZXR1cm4gUHlFcnJfTm9NZW1vcnkoKTsKKworICAgICAgICAgICAgZm9yIChjdXIgPSBzdGFydCwgaSA9IDA7IGkgPCBzbGljZWxlbmd0aDsKKyAgICAgICAgICAgICAgICAgY3VyICs9IHN0ZXAsIGkrKykgeworICAgICAgICAgICAgICAgICAgICAgcmVzdWx0X2J1ZltpXSA9IHNvdXJjZV9idWZbY3VyXTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJlc3VsdCA9IFB5Qnl0ZUFycmF5X0Zyb21TdHJpbmdBbmRTaXplKHJlc3VsdF9idWYsIHNsaWNlbGVuZ3RoKTsKKyAgICAgICAgICAgIFB5TWVtX0ZyZWUocmVzdWx0X2J1Zik7CisgICAgICAgICAgICByZXR1cm4gcmVzdWx0OworICAgICAgICB9CisgICAgfQorICAgIGVsc2UgeworICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfVHlwZUVycm9yLCAiYnl0ZWFycmF5IGluZGljZXMgbXVzdCBiZSBpbnRlZ2VycyIpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9Cit9CisKK3N0YXRpYyBpbnQKK2J5dGVhcnJheV9zZXRzbGljZShQeUJ5dGVBcnJheU9iamVjdCAqc2VsZiwgUHlfc3NpemVfdCBsbywgUHlfc3NpemVfdCBoaSwKKyAgICAgICAgICAgICAgIFB5T2JqZWN0ICp2YWx1ZXMpCit7CisgICAgUHlfc3NpemVfdCBhdmFpbCwgbmVlZGVkOworICAgIHZvaWQgKmJ5dGVzOworICAgIFB5X2J1ZmZlciB2Ynl0ZXM7CisgICAgaW50IHJlcyA9IDA7CisKKyAgICB2Ynl0ZXMubGVuID0gLTE7CisgICAgaWYgKHZhbHVlcyA9PSAoUHlPYmplY3QgKilzZWxmKSB7CisgICAgICAgIC8qIE1ha2UgYSBjb3B5IGFuZCBjYWxsIHRoaXMgZnVuY3Rpb24gcmVjdXJzaXZlbHkgKi8KKyAgICAgICAgaW50IGVycjsKKyAgICAgICAgdmFsdWVzID0gUHlCeXRlQXJyYXlfRnJvbU9iamVjdCh2YWx1ZXMpOworICAgICAgICBpZiAodmFsdWVzID09IE5VTEwpCisgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgIGVyciA9IGJ5dGVhcnJheV9zZXRzbGljZShzZWxmLCBsbywgaGksIHZhbHVlcyk7CisgICAgICAgIFB5X0RFQ1JFRih2YWx1ZXMpOworICAgICAgICByZXR1cm4gZXJyOworICAgIH0KKyAgICBpZiAodmFsdWVzID09IE5VTEwpIHsKKyAgICAgICAgLyogZGVsIGJbbG86aGldICovCisgICAgICAgIGJ5dGVzID0gTlVMTDsKKyAgICAgICAgbmVlZGVkID0gMDsKKyAgICB9CisgICAgZWxzZSB7CisgICAgICAgICAgICBpZiAoX2dldGJ1ZmZlcih2YWx1ZXMsICZ2Ynl0ZXMpIDwgMCkgeworICAgICAgICAgICAgICAgICAgICBQeUVycl9Gb3JtYXQoUHlFeGNfVHlwZUVycm9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImNhbid0IHNldCBieXRlYXJyYXkgc2xpY2UgZnJvbSAlLjEwMHMiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHlfVFlQRSh2YWx1ZXMpLT50cF9uYW1lKTsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICAgICAgfQorICAgICAgICAgICAgbmVlZGVkID0gdmJ5dGVzLmxlbjsKKyAgICAgICAgICAgIGJ5dGVzID0gdmJ5dGVzLmJ1ZjsKKyAgICB9CisKKyAgICBpZiAobG8gPCAwKQorICAgICAgICBsbyA9IDA7CisgICAgaWYgKGhpIDwgbG8pCisgICAgICAgIGhpID0gbG87CisgICAgaWYgKGhpID4gUHlfU0laRShzZWxmKSkKKyAgICAgICAgaGkgPSBQeV9TSVpFKHNlbGYpOworCisgICAgYXZhaWwgPSBoaSAtIGxvOworICAgIGlmIChhdmFpbCA8IDApCisgICAgICAgIGxvID0gaGkgPSBhdmFpbCA9IDA7CisKKyAgICBpZiAoYXZhaWwgIT0gbmVlZGVkKSB7CisgICAgICAgIGlmIChhdmFpbCA+IG5lZWRlZCkgeworICAgICAgICAgICAgaWYgKCFfY2FucmVzaXplKHNlbGYpKSB7CisgICAgICAgICAgICAgICAgcmVzID0gLTE7CisgICAgICAgICAgICAgICAgZ290byBmaW5pc2g7CisgICAgICAgICAgICB9CisgICAgICAgICAgICAvKgorICAgICAgICAgICAgICAwICAgbG8gICAgICAgICAgICAgICBoaSAgICAgICAgICAgICAgIG9sZF9zaXplCisgICAgICAgICAgICAgIHwgICB8PC0tLS1hdmFpbC0tLS0tPnw8LS0tLS10b21vdmUtLS0tLS0+fAorICAgICAgICAgICAgICB8ICAgfDwtbmVlZGVkLT58PC0tLS0tdG9tb3ZlLS0tLS0tPnwKKyAgICAgICAgICAgICAgMCAgIGxvICAgICAgbmV3X2hpICAgICAgICAgICAgICBuZXdfc2l6ZQorICAgICAgICAgICAgKi8KKyAgICAgICAgICAgIG1lbW1vdmUoc2VsZi0+b2JfYnl0ZXMgKyBsbyArIG5lZWRlZCwgc2VsZi0+b2JfYnl0ZXMgKyBoaSwKKyAgICAgICAgICAgICAgICAgICAgUHlfU0laRShzZWxmKSAtIGhpKTsKKyAgICAgICAgfQorICAgICAgICAvKiBYWFgobm5vcndpdHopOiBuZWVkIHRvIHZlcmlmeSB0aGlzIGNhbid0IG92ZXJmbG93ISAqLworICAgICAgICBpZiAoUHlCeXRlQXJyYXlfUmVzaXplKChQeU9iamVjdCAqKXNlbGYsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBQeV9TSVpFKHNlbGYpICsgbmVlZGVkIC0gYXZhaWwpIDwgMCkgeworICAgICAgICAgICAgICAgIHJlcyA9IC0xOworICAgICAgICAgICAgICAgIGdvdG8gZmluaXNoOworICAgICAgICB9CisgICAgICAgIGlmIChhdmFpbCA8IG5lZWRlZCkgeworICAgICAgICAgICAgLyoKKyAgICAgICAgICAgICAgMCAgIGxvICAgICAgICBoaSAgICAgICAgICAgICAgIG9sZF9zaXplCisgICAgICAgICAgICAgIHwgICB8PC1hdmFpbC0+fDwtLS0tLXRvbW92ZS0tLS0tLT58CisgICAgICAgICAgICAgIHwgICB8PC0tLS1uZWVkZWQtLS0tPnw8LS0tLS10b21vdmUtLS0tLS0+fAorICAgICAgICAgICAgICAwICAgbG8gICAgICAgICAgICBuZXdfaGkgICAgICAgICAgICAgIG5ld19zaXplCisgICAgICAgICAgICAgKi8KKyAgICAgICAgICAgIG1lbW1vdmUoc2VsZi0+b2JfYnl0ZXMgKyBsbyArIG5lZWRlZCwgc2VsZi0+b2JfYnl0ZXMgKyBoaSwKKyAgICAgICAgICAgICAgICAgICAgUHlfU0laRShzZWxmKSAtIGxvIC0gbmVlZGVkKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIGlmIChuZWVkZWQgPiAwKQorICAgICAgICBtZW1jcHkoc2VsZi0+b2JfYnl0ZXMgKyBsbywgYnl0ZXMsIG5lZWRlZCk7CisKKworIGZpbmlzaDoKKyAgICBpZiAodmJ5dGVzLmxlbiAhPSAtMSkKKyAgICAgICAgICAgIFB5QnVmZmVyX1JlbGVhc2UoJnZieXRlcyk7CisgICAgcmV0dXJuIHJlczsKK30KKworc3RhdGljIGludAorYnl0ZWFycmF5X3NldGl0ZW0oUHlCeXRlQXJyYXlPYmplY3QgKnNlbGYsIFB5X3NzaXplX3QgaSwgUHlPYmplY3QgKnZhbHVlKQoreworICAgIGludCBpdmFsOworCisgICAgaWYgKGkgPCAwKQorICAgICAgICBpICs9IFB5X1NJWkUoc2VsZik7CisKKyAgICBpZiAoaSA8IDAgfHwgaSA+PSBQeV9TSVpFKHNlbGYpKSB7CisgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19JbmRleEVycm9yLCAiYnl0ZWFycmF5IGluZGV4IG91dCBvZiByYW5nZSIpOworICAgICAgICByZXR1cm4gLTE7CisgICAgfQorCisgICAgaWYgKHZhbHVlID09IE5VTEwpCisgICAgICAgIHJldHVybiBieXRlYXJyYXlfc2V0c2xpY2Uoc2VsZiwgaSwgaSsxLCBOVUxMKTsKKworICAgIGlmICghX2dldGJ5dGV2YWx1ZSh2YWx1ZSwgJml2YWwpKQorICAgICAgICByZXR1cm4gLTE7CisKKyAgICBzZWxmLT5vYl9ieXRlc1tpXSA9IGl2YWw7CisgICAgcmV0dXJuIDA7Cit9CisKK3N0YXRpYyBpbnQKK2J5dGVhcnJheV9hc3Nfc3Vic2NyaXB0KFB5Qnl0ZUFycmF5T2JqZWN0ICpzZWxmLCBQeU9iamVjdCAqaW5kZXgsIFB5T2JqZWN0ICp2YWx1ZXMpCit7CisgICAgUHlfc3NpemVfdCBzdGFydCwgc3RvcCwgc3RlcCwgc2xpY2VsZW4sIG5lZWRlZDsKKyAgICBjaGFyICpieXRlczsKKworICAgIGlmIChQeUluZGV4X0NoZWNrKGluZGV4KSkgeworICAgICAgICBQeV9zc2l6ZV90IGkgPSBQeU51bWJlcl9Bc1NzaXplX3QoaW5kZXgsIFB5RXhjX0luZGV4RXJyb3IpOworCisgICAgICAgIGlmIChpID09IC0xICYmIFB5RXJyX09jY3VycmVkKCkpCisgICAgICAgICAgICByZXR1cm4gLTE7CisKKyAgICAgICAgaWYgKGkgPCAwKQorICAgICAgICAgICAgaSArPSBQeUJ5dGVBcnJheV9HRVRfU0laRShzZWxmKTsKKworICAgICAgICBpZiAoaSA8IDAgfHwgaSA+PSBQeV9TSVpFKHNlbGYpKSB7CisgICAgICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfSW5kZXhFcnJvciwgImJ5dGVhcnJheSBpbmRleCBvdXQgb2YgcmFuZ2UiKTsKKyAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgfQorCisgICAgICAgIGlmICh2YWx1ZXMgPT0gTlVMTCkgeworICAgICAgICAgICAgLyogRmFsbCB0aHJvdWdoIHRvIHNsaWNlIGFzc2lnbm1lbnQgKi8KKyAgICAgICAgICAgIHN0YXJ0ID0gaTsKKyAgICAgICAgICAgIHN0b3AgPSBpICsgMTsKKyAgICAgICAgICAgIHN0ZXAgPSAxOworICAgICAgICAgICAgc2xpY2VsZW4gPSAxOworICAgICAgICB9CisgICAgICAgIGVsc2UgeworICAgICAgICAgICAgaW50IGl2YWw7CisgICAgICAgICAgICBpZiAoIV9nZXRieXRldmFsdWUodmFsdWVzLCAmaXZhbCkpCisgICAgICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICAgICAgc2VsZi0+b2JfYnl0ZXNbaV0gPSAoY2hhcilpdmFsOworICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgIH0KKyAgICB9CisgICAgZWxzZSBpZiAoUHlTbGljZV9DaGVjayhpbmRleCkpIHsKKyAgICAgICAgaWYgKFB5U2xpY2VfR2V0SW5kaWNlc0V4KChQeVNsaWNlT2JqZWN0ICopaW5kZXgsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQeUJ5dGVBcnJheV9HRVRfU0laRShzZWxmKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZzdGFydCwgJnN0b3AsICZzdGVwLCAmc2xpY2VsZW4pIDwgMCkgeworICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICB9CisgICAgfQorICAgIGVsc2UgeworICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfVHlwZUVycm9yLCAiYnl0ZWFycmF5IGluZGljZXMgbXVzdCBiZSBpbnRlZ2VyIik7CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisKKyAgICBpZiAodmFsdWVzID09IE5VTEwpIHsKKyAgICAgICAgYnl0ZXMgPSBOVUxMOworICAgICAgICBuZWVkZWQgPSAwOworICAgIH0KKyAgICBlbHNlIGlmICh2YWx1ZXMgPT0gKFB5T2JqZWN0ICopc2VsZiB8fCAhUHlCeXRlQXJyYXlfQ2hlY2sodmFsdWVzKSkgeworICAgICAgICBpbnQgZXJyOworICAgICAgICBpZiAoUHlOdW1iZXJfQ2hlY2sodmFsdWVzKSB8fCBQeVVuaWNvZGVfQ2hlY2sodmFsdWVzKSkgeworICAgICAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1R5cGVFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAiY2FuIGFzc2lnbiBvbmx5IGJ5dGVzLCBidWZmZXJzLCBvciBpdGVyYWJsZXMgIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICJvZiBpbnRzIGluIHJhbmdlKDAsIDI1NikiKTsKKyAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgfQorICAgICAgICAvKiBNYWtlIGEgY29weSBhbmQgY2FsbCB0aGlzIGZ1bmN0aW9uIHJlY3Vyc2l2ZWx5ICovCisgICAgICAgIHZhbHVlcyA9IFB5Qnl0ZUFycmF5X0Zyb21PYmplY3QodmFsdWVzKTsKKyAgICAgICAgaWYgKHZhbHVlcyA9PSBOVUxMKQorICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICBlcnIgPSBieXRlYXJyYXlfYXNzX3N1YnNjcmlwdChzZWxmLCBpbmRleCwgdmFsdWVzKTsKKyAgICAgICAgUHlfREVDUkVGKHZhbHVlcyk7CisgICAgICAgIHJldHVybiBlcnI7CisgICAgfQorICAgIGVsc2UgeworICAgICAgICBhc3NlcnQoUHlCeXRlQXJyYXlfQ2hlY2sodmFsdWVzKSk7CisgICAgICAgIGJ5dGVzID0gKChQeUJ5dGVBcnJheU9iamVjdCAqKXZhbHVlcyktPm9iX2J5dGVzOworICAgICAgICBuZWVkZWQgPSBQeV9TSVpFKHZhbHVlcyk7CisgICAgfQorICAgIC8qIE1ha2Ugc3VyZSBiWzU6Ml0gPSAuLi4gaW5zZXJ0cyBiZWZvcmUgNSwgbm90IGJlZm9yZSAyLiAqLworICAgIGlmICgoc3RlcCA8IDAgJiYgc3RhcnQgPCBzdG9wKSB8fAorICAgICAgICAoc3RlcCA+IDAgJiYgc3RhcnQgPiBzdG9wKSkKKyAgICAgICAgc3RvcCA9IHN0YXJ0OworICAgIGlmIChzdGVwID09IDEpIHsKKyAgICAgICAgaWYgKHNsaWNlbGVuICE9IG5lZWRlZCkgeworICAgICAgICAgICAgaWYgKCFfY2FucmVzaXplKHNlbGYpKQorICAgICAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgICAgIGlmIChzbGljZWxlbiA+IG5lZWRlZCkgeworICAgICAgICAgICAgICAgIC8qCisgICAgICAgICAgICAgICAgICAwICAgc3RhcnQgICAgICAgICAgIHN0b3AgICAgICAgICAgICAgIG9sZF9zaXplCisgICAgICAgICAgICAgICAgICB8ICAgfDwtLS1zbGljZWxlbi0tLT58PC0tLS0tdG9tb3ZlLS0tLS0tPnwKKyAgICAgICAgICAgICAgICAgIHwgICB8PC1uZWVkZWQtPnw8LS0tLS10b21vdmUtLS0tLS0+fAorICAgICAgICAgICAgICAgICAgMCAgIGxvICAgICAgbmV3X2hpICAgICAgICAgICAgICBuZXdfc2l6ZQorICAgICAgICAgICAgICAgICovCisgICAgICAgICAgICAgICAgbWVtbW92ZShzZWxmLT5vYl9ieXRlcyArIHN0YXJ0ICsgbmVlZGVkLCBzZWxmLT5vYl9ieXRlcyArIHN0b3AsCisgICAgICAgICAgICAgICAgICAgICAgICBQeV9TSVpFKHNlbGYpIC0gc3RvcCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoUHlCeXRlQXJyYXlfUmVzaXplKChQeU9iamVjdCAqKXNlbGYsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHlfU0laRShzZWxmKSArIG5lZWRlZCAtIHNsaWNlbGVuKSA8IDApCisgICAgICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICAgICAgaWYgKHNsaWNlbGVuIDwgbmVlZGVkKSB7CisgICAgICAgICAgICAgICAgLyoKKyAgICAgICAgICAgICAgICAgIDAgICBsbyAgICAgICAgaGkgICAgICAgICAgICAgICBvbGRfc2l6ZQorICAgICAgICAgICAgICAgICAgfCAgIHw8LWF2YWlsLT58PC0tLS0tdG9tb3ZlLS0tLS0tPnwKKyAgICAgICAgICAgICAgICAgIHwgICB8PC0tLS1uZWVkZWQtLS0tPnw8LS0tLS10b21vdmUtLS0tLS0+fAorICAgICAgICAgICAgICAgICAgMCAgIGxvICAgICAgICAgICAgbmV3X2hpICAgICAgICAgICAgICBuZXdfc2l6ZQorICAgICAgICAgICAgICAgICAqLworICAgICAgICAgICAgICAgIG1lbW1vdmUoc2VsZi0+b2JfYnl0ZXMgKyBzdGFydCArIG5lZWRlZCwgc2VsZi0+b2JfYnl0ZXMgKyBzdG9wLAorICAgICAgICAgICAgICAgICAgICAgICAgUHlfU0laRShzZWxmKSAtIHN0YXJ0IC0gbmVlZGVkKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIGlmIChuZWVkZWQgPiAwKQorICAgICAgICAgICAgbWVtY3B5KHNlbGYtPm9iX2J5dGVzICsgc3RhcnQsIGJ5dGVzLCBuZWVkZWQpOworCisgICAgICAgIHJldHVybiAwOworICAgIH0KKyAgICBlbHNlIHsKKyAgICAgICAgaWYgKG5lZWRlZCA9PSAwKSB7CisgICAgICAgICAgICAvKiBEZWxldGUgc2xpY2UgKi8KKyAgICAgICAgICAgIHNpemVfdCBjdXI7CisgICAgICAgICAgICBQeV9zc2l6ZV90IGk7CisKKyAgICAgICAgICAgIGlmICghX2NhbnJlc2l6ZShzZWxmKSkKKyAgICAgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgICAgICBpZiAoc3RlcCA8IDApIHsKKyAgICAgICAgICAgICAgICBzdG9wID0gc3RhcnQgKyAxOworICAgICAgICAgICAgICAgIHN0YXJ0ID0gc3RvcCArIHN0ZXAgKiAoc2xpY2VsZW4gLSAxKSAtIDE7CisgICAgICAgICAgICAgICAgc3RlcCA9IC1zdGVwOworICAgICAgICAgICAgfQorICAgICAgICAgICAgZm9yIChjdXIgPSBzdGFydCwgaSA9IDA7CisgICAgICAgICAgICAgICAgIGkgPCBzbGljZWxlbjsgY3VyICs9IHN0ZXAsIGkrKykgeworICAgICAgICAgICAgICAgIFB5X3NzaXplX3QgbGltID0gc3RlcCAtIDE7CisKKyAgICAgICAgICAgICAgICBpZiAoY3VyICsgc3RlcCA+PSAoc2l6ZV90KVB5Qnl0ZUFycmF5X0dFVF9TSVpFKHNlbGYpKQorICAgICAgICAgICAgICAgICAgICBsaW0gPSBQeUJ5dGVBcnJheV9HRVRfU0laRShzZWxmKSAtIGN1ciAtIDE7CisKKyAgICAgICAgICAgICAgICBtZW1tb3ZlKHNlbGYtPm9iX2J5dGVzICsgY3VyIC0gaSwKKyAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYtPm9iX2J5dGVzICsgY3VyICsgMSwgbGltKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIC8qIE1vdmUgdGhlIHRhaWwgb2YgdGhlIGJ5dGVzLCBpbiBvbmUgY2h1bmsgKi8KKyAgICAgICAgICAgIGN1ciA9IHN0YXJ0ICsgc2xpY2VsZW4qc3RlcDsKKyAgICAgICAgICAgIGlmIChjdXIgPCAoc2l6ZV90KVB5Qnl0ZUFycmF5X0dFVF9TSVpFKHNlbGYpKSB7CisgICAgICAgICAgICAgICAgbWVtbW92ZShzZWxmLT5vYl9ieXRlcyArIGN1ciAtIHNsaWNlbGVuLAorICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi0+b2JfYnl0ZXMgKyBjdXIsCisgICAgICAgICAgICAgICAgICAgICAgICBQeUJ5dGVBcnJheV9HRVRfU0laRShzZWxmKSAtIGN1cik7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoUHlCeXRlQXJyYXlfUmVzaXplKChQeU9iamVjdCAqKXNlbGYsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHlCeXRlQXJyYXlfR0VUX1NJWkUoc2VsZikgLSBzbGljZWxlbikgPCAwKQorICAgICAgICAgICAgICAgIHJldHVybiAtMTsKKworICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgIH0KKyAgICAgICAgZWxzZSB7CisgICAgICAgICAgICAvKiBBc3NpZ24gc2xpY2UgKi8KKyAgICAgICAgICAgIFB5X3NzaXplX3QgY3VyLCBpOworCisgICAgICAgICAgICBpZiAobmVlZGVkICE9IHNsaWNlbGVuKSB7CisgICAgICAgICAgICAgICAgUHlFcnJfRm9ybWF0KFB5RXhjX1ZhbHVlRXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJhdHRlbXB0IHRvIGFzc2lnbiBieXRlcyBvZiBzaXplICV6ZCAiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0byBleHRlbmRlZCBzbGljZSBvZiBzaXplICV6ZCIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5lZWRlZCwgc2xpY2VsZW4pOworICAgICAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGZvciAoY3VyID0gc3RhcnQsIGkgPSAwOyBpIDwgc2xpY2VsZW47IGN1ciArPSBzdGVwLCBpKyspCisgICAgICAgICAgICAgICAgc2VsZi0+b2JfYnl0ZXNbY3VyXSA9IGJ5dGVzW2ldOworICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgIH0KKyAgICB9Cit9CisKK3N0YXRpYyBpbnQKK2J5dGVhcnJheV9pbml0KFB5Qnl0ZUFycmF5T2JqZWN0ICpzZWxmLCBQeU9iamVjdCAqYXJncywgUHlPYmplY3QgKmt3ZHMpCit7CisgICAgc3RhdGljIGNoYXIgKmt3bGlzdFtdID0geyJzb3VyY2UiLCAiZW5jb2RpbmciLCAiZXJyb3JzIiwgMH07CisgICAgUHlPYmplY3QgKmFyZyA9IE5VTEw7CisgICAgY29uc3QgY2hhciAqZW5jb2RpbmcgPSBOVUxMOworICAgIGNvbnN0IGNoYXIgKmVycm9ycyA9IE5VTEw7CisgICAgUHlfc3NpemVfdCBjb3VudDsKKyAgICBQeU9iamVjdCAqaXQ7CisgICAgUHlPYmplY3QgKigqaXRlcm5leHQpKFB5T2JqZWN0ICopOworCisgICAgaWYgKFB5X1NJWkUoc2VsZikgIT0gMCkgeworICAgICAgICAvKiBFbXB0eSBwcmV2aW91cyBjb250ZW50cyAoeWVzLCBkbyB0aGlzIGZpcnN0IG9mIGFsbCEpICovCisgICAgICAgIGlmIChQeUJ5dGVBcnJheV9SZXNpemUoKFB5T2JqZWN0ICopc2VsZiwgMCkgPCAwKQorICAgICAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKworICAgIC8qIFBhcnNlIGFyZ3VtZW50cyAqLworICAgIGlmICghUHlBcmdfUGFyc2VUdXBsZUFuZEtleXdvcmRzKGFyZ3MsIGt3ZHMsICJ8T3NzOmJ5dGVhcnJheSIsIGt3bGlzdCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmYXJnLCAmZW5jb2RpbmcsICZlcnJvcnMpKQorICAgICAgICByZXR1cm4gLTE7CisKKyAgICAvKiBNYWtlIGEgcXVpY2sgZXhpdCBpZiBubyBmaXJzdCBhcmd1bWVudCAqLworICAgIGlmIChhcmcgPT0gTlVMTCkgeworICAgICAgICBpZiAoZW5jb2RpbmcgIT0gTlVMTCB8fCBlcnJvcnMgIT0gTlVMTCkgeworICAgICAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1R5cGVFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZW5jb2Rpbmcgb3IgZXJyb3JzIHdpdGhvdXQgc2VxdWVuY2UgYXJndW1lbnQiKTsKKyAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gMDsKKyAgICB9CisKKyAgICBpZiAoUHlCeXRlc19DaGVjayhhcmcpKSB7CisgICAgICAgIFB5T2JqZWN0ICpuZXcsICplbmNvZGVkOworICAgICAgICBpZiAoZW5jb2RpbmcgIT0gTlVMTCkgeworICAgICAgICAgICAgZW5jb2RlZCA9IFB5Q29kZWNfRW5jb2RlKGFyZywgZW5jb2RpbmcsIGVycm9ycyk7CisgICAgICAgICAgICBpZiAoZW5jb2RlZCA9PSBOVUxMKQorICAgICAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgICAgIGFzc2VydChQeUJ5dGVzX0NoZWNrKGVuY29kZWQpKTsKKyAgICAgICAgfQorICAgICAgICBlbHNlIHsKKyAgICAgICAgICAgIGVuY29kZWQgPSBhcmc7CisgICAgICAgICAgICBQeV9JTkNSRUYoYXJnKTsKKyAgICAgICAgfQorICAgICAgICBuZXcgPSBieXRlYXJyYXlfaWNvbmNhdChzZWxmLCBhcmcpOworICAgICAgICBQeV9ERUNSRUYoZW5jb2RlZCk7CisgICAgICAgIGlmIChuZXcgPT0gTlVMTCkKKyAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgUHlfREVDUkVGKG5ldyk7CisgICAgICAgIHJldHVybiAwOworICAgIH0KKworI2lmZGVmIFB5X1VTSU5HX1VOSUNPREUKKyAgICBpZiAoUHlVbmljb2RlX0NoZWNrKGFyZykpIHsKKyAgICAgICAgLyogRW5jb2RlIHZpYSB0aGUgY29kZWMgcmVnaXN0cnkgKi8KKyAgICAgICAgUHlPYmplY3QgKmVuY29kZWQsICpuZXc7CisgICAgICAgIGlmIChlbmNvZGluZyA9PSBOVUxMKSB7CisgICAgICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfVHlwZUVycm9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ1bmljb2RlIGFyZ3VtZW50IHdpdGhvdXQgYW4gZW5jb2RpbmciKTsKKyAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgfQorICAgICAgICBlbmNvZGVkID0gUHlDb2RlY19FbmNvZGUoYXJnLCBlbmNvZGluZywgZXJyb3JzKTsKKyAgICAgICAgaWYgKGVuY29kZWQgPT0gTlVMTCkKKyAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgYXNzZXJ0KFB5Qnl0ZXNfQ2hlY2soZW5jb2RlZCkpOworICAgICAgICBuZXcgPSBieXRlYXJyYXlfaWNvbmNhdChzZWxmLCBlbmNvZGVkKTsKKyAgICAgICAgUHlfREVDUkVGKGVuY29kZWQpOworICAgICAgICBpZiAobmV3ID09IE5VTEwpCisgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgIFB5X0RFQ1JFRihuZXcpOworICAgICAgICByZXR1cm4gMDsKKyAgICB9CisjZW5kaWYKKworICAgIC8qIElmIGl0J3Mgbm90IHVuaWNvZGUsIHRoZXJlIGNhbid0IGJlIGVuY29kaW5nIG9yIGVycm9ycyAqLworICAgIGlmIChlbmNvZGluZyAhPSBOVUxMIHx8IGVycm9ycyAhPSBOVUxMKSB7CisgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19UeXBlRXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAgICAiZW5jb2Rpbmcgb3IgZXJyb3JzIHdpdGhvdXQgYSBzdHJpbmcgYXJndW1lbnQiKTsKKyAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKworICAgIC8qIElzIGl0IGFuIGludD8gKi8KKyAgICBjb3VudCA9IFB5TnVtYmVyX0FzU3NpemVfdChhcmcsIFB5RXhjX092ZXJmbG93RXJyb3IpOworICAgIGlmIChjb3VudCA9PSAtMSAmJiBQeUVycl9PY2N1cnJlZCgpKSB7CisgICAgICAgIGlmIChQeUVycl9FeGNlcHRpb25NYXRjaGVzKFB5RXhjX092ZXJmbG93RXJyb3IpKQorICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICBQeUVycl9DbGVhcigpOworICAgIH0KKyAgICBlbHNlIGlmIChjb3VudCA8IDApIHsKKyAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1ZhbHVlRXJyb3IsICJuZWdhdGl2ZSBjb3VudCIpOworICAgICAgICByZXR1cm4gLTE7CisgICAgfQorICAgIGVsc2UgeworICAgICAgICBpZiAoY291bnQgPiAwKSB7CisgICAgICAgICAgICBpZiAoUHlCeXRlQXJyYXlfUmVzaXplKChQeU9iamVjdCAqKXNlbGYsIGNvdW50KSkKKyAgICAgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgICAgICBtZW1zZXQoc2VsZi0+b2JfYnl0ZXMsIDAsIGNvdW50KTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gMDsKKyAgICB9CisKKyAgICAvKiBVc2UgdGhlIGJ1ZmZlciBBUEkgKi8KKyAgICBpZiAoUHlPYmplY3RfQ2hlY2tCdWZmZXIoYXJnKSkgeworICAgICAgICBQeV9zc2l6ZV90IHNpemU7CisgICAgICAgIFB5X2J1ZmZlciB2aWV3OworICAgICAgICBpZiAoUHlPYmplY3RfR2V0QnVmZmVyKGFyZywgJnZpZXcsIFB5QlVGX0ZVTExfUk8pIDwgMCkKKyAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgc2l6ZSA9IHZpZXcubGVuOworICAgICAgICBpZiAoUHlCeXRlQXJyYXlfUmVzaXplKChQeU9iamVjdCAqKXNlbGYsIHNpemUpIDwgMCkgZ290byBmYWlsOworICAgICAgICBpZiAoUHlCdWZmZXJfVG9Db250aWd1b3VzKHNlbGYtPm9iX2J5dGVzLCAmdmlldywgc2l6ZSwgJ0MnKSA8IDApCisgICAgICAgICAgICAgICAgZ290byBmYWlsOworICAgICAgICBQeUJ1ZmZlcl9SZWxlYXNlKCZ2aWV3KTsKKyAgICAgICAgcmV0dXJuIDA7CisgICAgZmFpbDoKKyAgICAgICAgUHlCdWZmZXJfUmVsZWFzZSgmdmlldyk7CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisKKyAgICAvKiBYWFggT3B0aW1pemUgdGhpcyBpZiB0aGUgYXJndW1lbnRzIGlzIGEgbGlzdCwgdHVwbGUgKi8KKworICAgIC8qIEdldCB0aGUgaXRlcmF0b3IgKi8KKyAgICBpdCA9IFB5T2JqZWN0X0dldEl0ZXIoYXJnKTsKKyAgICBpZiAoaXQgPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIC0xOworICAgIGl0ZXJuZXh0ID0gKlB5X1RZUEUoaXQpLT50cF9pdGVybmV4dDsKKworICAgIC8qIFJ1biB0aGUgaXRlcmF0b3IgdG8gZXhoYXVzdGlvbiAqLworICAgIGZvciAoOzspIHsKKyAgICAgICAgUHlPYmplY3QgKml0ZW07CisgICAgICAgIGludCByYywgdmFsdWU7CisKKyAgICAgICAgLyogR2V0IHRoZSBuZXh0IGl0ZW0gKi8KKyAgICAgICAgaXRlbSA9IGl0ZXJuZXh0KGl0KTsKKyAgICAgICAgaWYgKGl0ZW0gPT0gTlVMTCkgeworICAgICAgICAgICAgaWYgKFB5RXJyX09jY3VycmVkKCkpIHsKKyAgICAgICAgICAgICAgICBpZiAoIVB5RXJyX0V4Y2VwdGlvbk1hdGNoZXMoUHlFeGNfU3RvcEl0ZXJhdGlvbikpCisgICAgICAgICAgICAgICAgICAgIGdvdG8gZXJyb3I7CisgICAgICAgICAgICAgICAgUHlFcnJfQ2xlYXIoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisKKyAgICAgICAgLyogSW50ZXJwcmV0IGl0IGFzIGFuIGludCAoX19pbmRleF9fKSAqLworICAgICAgICByYyA9IF9nZXRieXRldmFsdWUoaXRlbSwgJnZhbHVlKTsKKyAgICAgICAgUHlfREVDUkVGKGl0ZW0pOworICAgICAgICBpZiAoIXJjKQorICAgICAgICAgICAgZ290byBlcnJvcjsKKworICAgICAgICAvKiBBcHBlbmQgdGhlIGJ5dGUgKi8KKyAgICAgICAgaWYgKFB5X1NJWkUoc2VsZikgPCBzZWxmLT5vYl9hbGxvYykKKyAgICAgICAgICAgIFB5X1NJWkUoc2VsZikrKzsKKyAgICAgICAgZWxzZSBpZiAoUHlCeXRlQXJyYXlfUmVzaXplKChQeU9iamVjdCAqKXNlbGYsIFB5X1NJWkUoc2VsZikrMSkgPCAwKQorICAgICAgICAgICAgZ290byBlcnJvcjsKKyAgICAgICAgc2VsZi0+b2JfYnl0ZXNbUHlfU0laRShzZWxmKS0xXSA9IHZhbHVlOworICAgIH0KKworICAgIC8qIENsZWFuIHVwIGFuZCByZXR1cm4gc3VjY2VzcyAqLworICAgIFB5X0RFQ1JFRihpdCk7CisgICAgcmV0dXJuIDA7CisKKyBlcnJvcjoKKyAgICAvKiBFcnJvciBoYW5kbGluZyB3aGVuIGl0ICE9IE5VTEwgKi8KKyAgICBQeV9ERUNSRUYoaXQpOworICAgIHJldHVybiAtMTsKK30KKworLyogTW9zdGx5IGNvcGllZCBmcm9tIHN0cmluZ19yZXByLCBidXQgd2l0aG91dCB0aGUKKyAgICJzbWFydCBxdW90ZSIgZnVuY3Rpb25hbGl0eS4gKi8KK3N0YXRpYyBQeU9iamVjdCAqCitieXRlYXJyYXlfcmVwcihQeUJ5dGVBcnJheU9iamVjdCAqc2VsZikKK3sKKyAgICBzdGF0aWMgY29uc3QgY2hhciAqaGV4ZGlnaXRzID0gIjAxMjM0NTY3ODlhYmNkZWYiOworICAgIGNvbnN0IGNoYXIgKnF1b3RlX3ByZWZpeCA9ICJieXRlYXJyYXkoYiI7CisgICAgY29uc3QgY2hhciAqcXVvdGVfcG9zdGZpeCA9ICIpIjsKKyAgICBQeV9zc2l6ZV90IGxlbmd0aCA9IFB5X1NJWkUoc2VsZik7CisgICAgLyogMTQgPT0gc3RybGVuKHF1b3RlX3ByZWZpeCkgKyAyICsgc3RybGVuKHF1b3RlX3Bvc3RmaXgpICovCisgICAgc2l6ZV90IG5ld3NpemU7CisgICAgUHlPYmplY3QgKnY7CisgICAgaWYgKGxlbmd0aCA+IChQWV9TU0laRV9UX01BWCAtIDE0KSAvIDQpIHsKKyAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX092ZXJmbG93RXJyb3IsCisgICAgICAgICAgICAiYnl0ZWFycmF5IG9iamVjdCBpcyB0b28gbGFyZ2UgdG8gbWFrZSByZXByIik7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICBuZXdzaXplID0gMTQgKyA0ICogbGVuZ3RoOworICAgIHYgPSBQeVN0cmluZ19Gcm9tU3RyaW5nQW5kU2l6ZShOVUxMLCBuZXdzaXplKTsKKyAgICBpZiAodiA9PSBOVUxMKSB7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICBlbHNlIHsKKyAgICAgICAgcmVnaXN0ZXIgUHlfc3NpemVfdCBpOworICAgICAgICByZWdpc3RlciBjaGFyIGM7CisgICAgICAgIHJlZ2lzdGVyIGNoYXIgKnA7CisgICAgICAgIGludCBxdW90ZTsKKworICAgICAgICAvKiBGaWd1cmUgb3V0IHdoaWNoIHF1b3RlIHRvIHVzZTsgc2luZ2xlIGlzIHByZWZlcnJlZCAqLworICAgICAgICBxdW90ZSA9ICdcJyc7CisgICAgICAgIHsKKyAgICAgICAgICAgIGNoYXIgKnRlc3QsICpzdGFydDsKKyAgICAgICAgICAgIHN0YXJ0ID0gUHlCeXRlQXJyYXlfQVNfU1RSSU5HKHNlbGYpOworICAgICAgICAgICAgZm9yICh0ZXN0ID0gc3RhcnQ7IHRlc3QgPCBzdGFydCtsZW5ndGg7ICsrdGVzdCkgeworICAgICAgICAgICAgICAgIGlmICgqdGVzdCA9PSAnIicpIHsKKyAgICAgICAgICAgICAgICAgICAgcXVvdGUgPSAnXCcnOyAvKiBiYWNrIHRvIHNpbmdsZSAqLworICAgICAgICAgICAgICAgICAgICBnb3RvIGRlY2lkZWQ7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGVsc2UgaWYgKCp0ZXN0ID09ICdcJycpCisgICAgICAgICAgICAgICAgICAgIHF1b3RlID0gJyInOworICAgICAgICAgICAgfQorICAgICAgICAgIGRlY2lkZWQ6CisgICAgICAgICAgICA7CisgICAgICAgIH0KKworICAgICAgICBwID0gUHlTdHJpbmdfQVNfU1RSSU5HKHYpOworICAgICAgICB3aGlsZSAoKnF1b3RlX3ByZWZpeCkKKyAgICAgICAgICAgICpwKysgPSAqcXVvdGVfcHJlZml4Kys7CisgICAgICAgICpwKysgPSBxdW90ZTsKKworICAgICAgICBmb3IgKGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgIC8qIFRoZXJlJ3MgYXQgbGVhc3QgZW5vdWdoIHJvb20gZm9yIGEgaGV4IGVzY2FwZQorICAgICAgICAgICAgICAgYW5kIGEgY2xvc2luZyBxdW90ZS4gKi8KKyAgICAgICAgICAgIGFzc2VydChuZXdzaXplIC0gKHAgLSBQeVN0cmluZ19BU19TVFJJTkcodikpID49IDUpOworICAgICAgICAgICAgYyA9IHNlbGYtPm9iX2J5dGVzW2ldOworICAgICAgICAgICAgaWYgKGMgPT0gJ1wnJyB8fCBjID09ICdcXCcpCisgICAgICAgICAgICAgICAgKnArKyA9ICdcXCcsICpwKysgPSBjOworICAgICAgICAgICAgZWxzZSBpZiAoYyA9PSAnXHQnKQorICAgICAgICAgICAgICAgICpwKysgPSAnXFwnLCAqcCsrID0gJ3QnOworICAgICAgICAgICAgZWxzZSBpZiAoYyA9PSAnXG4nKQorICAgICAgICAgICAgICAgICpwKysgPSAnXFwnLCAqcCsrID0gJ24nOworICAgICAgICAgICAgZWxzZSBpZiAoYyA9PSAnXHInKQorICAgICAgICAgICAgICAgICpwKysgPSAnXFwnLCAqcCsrID0gJ3InOworICAgICAgICAgICAgZWxzZSBpZiAoYyA9PSAwKQorICAgICAgICAgICAgICAgICpwKysgPSAnXFwnLCAqcCsrID0gJ3gnLCAqcCsrID0gJzAnLCAqcCsrID0gJzAnOworICAgICAgICAgICAgZWxzZSBpZiAoYyA8ICcgJyB8fCBjID49IDB4N2YpIHsKKyAgICAgICAgICAgICAgICAqcCsrID0gJ1xcJzsKKyAgICAgICAgICAgICAgICAqcCsrID0gJ3gnOworICAgICAgICAgICAgICAgICpwKysgPSBoZXhkaWdpdHNbKGMgJiAweGYwKSA+PiA0XTsKKyAgICAgICAgICAgICAgICAqcCsrID0gaGV4ZGlnaXRzW2MgJiAweGZdOworICAgICAgICAgICAgfQorICAgICAgICAgICAgZWxzZQorICAgICAgICAgICAgICAgICpwKysgPSBjOworICAgICAgICB9CisgICAgICAgIGFzc2VydChuZXdzaXplIC0gKHAgLSBQeVN0cmluZ19BU19TVFJJTkcodikpID49IDEpOworICAgICAgICAqcCsrID0gcXVvdGU7CisgICAgICAgIHdoaWxlICgqcXVvdGVfcG9zdGZpeCkgeworICAgICAgICAgICAqcCsrID0gKnF1b3RlX3Bvc3RmaXgrKzsKKyAgICAgICAgfQorICAgICAgICAqcCA9ICdcMCc7CisgICAgICAgIGlmIChfUHlTdHJpbmdfUmVzaXplKCZ2LCAocCAtIFB5U3RyaW5nX0FTX1NUUklORyh2KSkpKSB7CisgICAgICAgICAgICBQeV9ERUNSRUYodik7CisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gdjsKKyAgICB9Cit9CisKK3N0YXRpYyBQeU9iamVjdCAqCitieXRlYXJyYXlfc3RyKFB5T2JqZWN0ICpvcCkKK3sKKyNpZiAwCisgICAgaWYgKFB5X0J5dGVzV2FybmluZ0ZsYWcpIHsKKyAgICAgICAgaWYgKFB5RXJyX1dhcm5FeChQeUV4Y19CeXRlc1dhcm5pbmcsCisgICAgICAgICAgICAgICAgICJzdHIoKSBvbiBhIGJ5dGVhcnJheSBpbnN0YW5jZSIsIDEpKQorICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIHJldHVybiBieXRlYXJyYXlfcmVwcigoUHlCeXRlQXJyYXlPYmplY3QqKW9wKTsKKyNlbmRpZgorICAgIHJldHVybiBQeUJ5dGVzX0Zyb21TdHJpbmdBbmRTaXplKCgoUHlCeXRlQXJyYXlPYmplY3QqKW9wKS0+b2JfYnl0ZXMsIFB5X1NJWkUob3ApKTsKK30KKworc3RhdGljIFB5T2JqZWN0ICoKK2J5dGVhcnJheV9yaWNoY29tcGFyZShQeU9iamVjdCAqc2VsZiwgUHlPYmplY3QgKm90aGVyLCBpbnQgb3ApCit7CisgICAgUHlfc3NpemVfdCBzZWxmX3NpemUsIG90aGVyX3NpemU7CisgICAgUHlfYnVmZmVyIHNlbGZfYnl0ZXMsIG90aGVyX2J5dGVzOworICAgIFB5T2JqZWN0ICpyZXM7CisgICAgUHlfc3NpemVfdCBtaW5zaXplOworICAgIGludCBjbXA7CisKKyAgICAvKiBCeXRlcyBjYW4gYmUgY29tcGFyZWQgdG8gYW55dGhpbmcgdGhhdCBzdXBwb3J0cyB0aGUgKGJpbmFyeSkKKyAgICAgICBidWZmZXIgQVBJLiAgRXhjZXB0IHRoYXQgYSBjb21wYXJpc29uIHdpdGggVW5pY29kZSBpcyBhbHdheXMgYW4KKyAgICAgICBlcnJvciwgZXZlbiBpZiB0aGUgY29tcGFyaXNvbiBpcyBmb3IgZXF1YWxpdHkuICovCisjaWZkZWYgUHlfVVNJTkdfVU5JQ09ERQorICAgIGlmIChQeU9iamVjdF9Jc0luc3RhbmNlKHNlbGYsIChQeU9iamVjdCopJlB5VW5pY29kZV9UeXBlKSB8fAorICAgICAgICBQeU9iamVjdF9Jc0luc3RhbmNlKG90aGVyLCAoUHlPYmplY3QqKSZQeVVuaWNvZGVfVHlwZSkpIHsKKyAgICAgICAgaWYgKFB5X0J5dGVzV2FybmluZ0ZsYWcgJiYgb3AgPT0gUHlfRVEpIHsKKyAgICAgICAgICAgIGlmIChQeUVycl9XYXJuRXgoUHlFeGNfQnl0ZXNXYXJuaW5nLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICJDb21wYXJpc29uIGJldHdlZW4gYnl0ZWFycmF5IGFuZCBzdHJpbmciLCAxKSkKKyAgICAgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgfQorCisgICAgICAgIFB5X0lOQ1JFRihQeV9Ob3RJbXBsZW1lbnRlZCk7CisgICAgICAgIHJldHVybiBQeV9Ob3RJbXBsZW1lbnRlZDsKKyAgICB9CisjZW5kaWYKKworICAgIHNlbGZfc2l6ZSA9IF9nZXRidWZmZXIoc2VsZiwgJnNlbGZfYnl0ZXMpOworICAgIGlmIChzZWxmX3NpemUgPCAwKSB7CisgICAgICAgIFB5RXJyX0NsZWFyKCk7CisgICAgICAgIFB5X0lOQ1JFRihQeV9Ob3RJbXBsZW1lbnRlZCk7CisgICAgICAgIHJldHVybiBQeV9Ob3RJbXBsZW1lbnRlZDsKKyAgICB9CisKKyAgICBvdGhlcl9zaXplID0gX2dldGJ1ZmZlcihvdGhlciwgJm90aGVyX2J5dGVzKTsKKyAgICBpZiAob3RoZXJfc2l6ZSA8IDApIHsKKyAgICAgICAgUHlFcnJfQ2xlYXIoKTsKKyAgICAgICAgUHlCdWZmZXJfUmVsZWFzZSgmc2VsZl9ieXRlcyk7CisgICAgICAgIFB5X0lOQ1JFRihQeV9Ob3RJbXBsZW1lbnRlZCk7CisgICAgICAgIHJldHVybiBQeV9Ob3RJbXBsZW1lbnRlZDsKKyAgICB9CisKKyAgICBpZiAoc2VsZl9zaXplICE9IG90aGVyX3NpemUgJiYgKG9wID09IFB5X0VRIHx8IG9wID09IFB5X05FKSkgeworICAgICAgICAvKiBTaG9ydGN1dDogaWYgdGhlIGxlbmd0aHMgZGlmZmVyLCB0aGUgb2JqZWN0cyBkaWZmZXIgKi8KKyAgICAgICAgY21wID0gKG9wID09IFB5X05FKTsKKyAgICB9CisgICAgZWxzZSB7CisgICAgICAgIG1pbnNpemUgPSBzZWxmX3NpemU7CisgICAgICAgIGlmIChvdGhlcl9zaXplIDwgbWluc2l6ZSkKKyAgICAgICAgICAgIG1pbnNpemUgPSBvdGhlcl9zaXplOworCisgICAgICAgIGNtcCA9IG1lbWNtcChzZWxmX2J5dGVzLmJ1Ziwgb3RoZXJfYnl0ZXMuYnVmLCBtaW5zaXplKTsKKyAgICAgICAgLyogSW4gSVNPIEMsIG1lbWNtcCgpIGd1YXJhbnRlZXMgdG8gdXNlIHVuc2lnbmVkIGJ5dGVzISAqLworCisgICAgICAgIGlmIChjbXAgPT0gMCkgeworICAgICAgICAgICAgaWYgKHNlbGZfc2l6ZSA8IG90aGVyX3NpemUpCisgICAgICAgICAgICAgICAgY21wID0gLTE7CisgICAgICAgICAgICBlbHNlIGlmIChzZWxmX3NpemUgPiBvdGhlcl9zaXplKQorICAgICAgICAgICAgICAgIGNtcCA9IDE7CisgICAgICAgIH0KKworICAgICAgICBzd2l0Y2ggKG9wKSB7CisgICAgICAgIGNhc2UgUHlfTFQ6IGNtcCA9IGNtcCA8ICAwOyBicmVhazsKKyAgICAgICAgY2FzZSBQeV9MRTogY21wID0gY21wIDw9IDA7IGJyZWFrOworICAgICAgICBjYXNlIFB5X0VROiBjbXAgPSBjbXAgPT0gMDsgYnJlYWs7CisgICAgICAgIGNhc2UgUHlfTkU6IGNtcCA9IGNtcCAhPSAwOyBicmVhazsKKyAgICAgICAgY2FzZSBQeV9HVDogY21wID0gY21wID4gIDA7IGJyZWFrOworICAgICAgICBjYXNlIFB5X0dFOiBjbXAgPSBjbXAgPj0gMDsgYnJlYWs7CisgICAgICAgIH0KKyAgICB9CisKKyAgICByZXMgPSBjbXAgPyBQeV9UcnVlIDogUHlfRmFsc2U7CisgICAgUHlCdWZmZXJfUmVsZWFzZSgmc2VsZl9ieXRlcyk7CisgICAgUHlCdWZmZXJfUmVsZWFzZSgmb3RoZXJfYnl0ZXMpOworICAgIFB5X0lOQ1JFRihyZXMpOworICAgIHJldHVybiByZXM7Cit9CisKK3N0YXRpYyB2b2lkCitieXRlYXJyYXlfZGVhbGxvYyhQeUJ5dGVBcnJheU9iamVjdCAqc2VsZikKK3sKKyAgICBpZiAoc2VsZi0+b2JfZXhwb3J0cyA+IDApIHsKKyAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1N5c3RlbUVycm9yLAorICAgICAgICAgICAgICAgICAgICAgICAgImRlYWxsb2NhdGVkIGJ5dGVhcnJheSBvYmplY3QgaGFzIGV4cG9ydGVkIGJ1ZmZlcnMiKTsKKyAgICAgICAgUHlFcnJfUHJpbnQoKTsKKyAgICB9CisgICAgaWYgKHNlbGYtPm9iX2J5dGVzICE9IDApIHsKKyAgICAgICAgUHlNZW1fRnJlZShzZWxmLT5vYl9ieXRlcyk7CisgICAgfQorICAgIFB5X1RZUEUoc2VsZiktPnRwX2ZyZWUoKFB5T2JqZWN0ICopc2VsZik7Cit9CisKKworLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KKy8qIE1ldGhvZHMgKi8KKworI2RlZmluZSBTVFJJTkdMSUJfQ0hBUiBjaGFyCisjZGVmaW5lIFNUUklOR0xJQl9MRU4gUHlCeXRlQXJyYXlfR0VUX1NJWkUKKyNkZWZpbmUgU1RSSU5HTElCX1NUUiBQeUJ5dGVBcnJheV9BU19TVFJJTkcKKyNkZWZpbmUgU1RSSU5HTElCX05FVyBQeUJ5dGVBcnJheV9Gcm9tU3RyaW5nQW5kU2l6ZQorI2RlZmluZSBTVFJJTkdMSUJfSVNTUEFDRSBQeV9JU1NQQUNFCisjZGVmaW5lIFNUUklOR0xJQl9JU0xJTkVCUkVBSyh4KSAoKHggPT0gJ1xuJykgfHwgKHggPT0gJ1xyJykpCisjZGVmaW5lIFNUUklOR0xJQl9DSEVDS19FWEFDVCBQeUJ5dGVBcnJheV9DaGVja0V4YWN0CisjZGVmaW5lIFNUUklOR0xJQl9NVVRBQkxFIDEKKworI2luY2x1ZGUgInN0cmluZ2xpYi9mYXN0c2VhcmNoLmgiCisjaW5jbHVkZSAic3RyaW5nbGliL2NvdW50LmgiCisjaW5jbHVkZSAic3RyaW5nbGliL2ZpbmQuaCIKKyNpbmNsdWRlICJzdHJpbmdsaWIvcGFydGl0aW9uLmgiCisjaW5jbHVkZSAic3RyaW5nbGliL3NwbGl0LmgiCisjaW5jbHVkZSAic3RyaW5nbGliL2N0eXBlLmgiCisjaW5jbHVkZSAic3RyaW5nbGliL3RyYW5zbW9ncmlmeS5oIgorCisKKy8qIFRoZSBmb2xsb3dpbmcgUHlfTE9DQUxfSU5MSU5FIGFuZCBQeV9MT0NBTCBmdW5jdGlvbnMKK3dlcmUgY29waWVkIGZyb20gdGhlIG9sZCBjaGFyKiBzdHlsZSBzdHJpbmcgb2JqZWN0LiAqLworCisvKiBoZWxwZXIgbWFjcm8gdG8gZml4dXAgc3RhcnQvZW5kIHNsaWNlIHZhbHVlcyAqLworI2RlZmluZSBBREpVU1RfSU5ESUNFUyhzdGFydCwgZW5kLCBsZW4pICAgICAgICAgXAorICAgIGlmIChlbmQgPiBsZW4pICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICBlbmQgPSBsZW47ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIGVsc2UgaWYgKGVuZCA8IDApIHsgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICBlbmQgKz0gbGVuOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICBpZiAoZW5kIDwgMCkgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgICAgZW5kID0gMDsgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIH0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIGlmIChzdGFydCA8IDApIHsgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICBzdGFydCArPSBsZW47ICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICBpZiAoc3RhcnQgPCAwKSAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgICAgc3RhcnQgPSAwOyAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIH0KKworUHlfTE9DQUxfSU5MSU5FKFB5X3NzaXplX3QpCitieXRlYXJyYXlfZmluZF9pbnRlcm5hbChQeUJ5dGVBcnJheU9iamVjdCAqc2VsZiwgUHlPYmplY3QgKmFyZ3MsIGludCBkaXIpCit7CisgICAgUHlPYmplY3QgKnN1Ym9iajsKKyAgICBQeV9idWZmZXIgc3ViYnVmOworICAgIFB5X3NzaXplX3Qgc3RhcnQ9MCwgZW5kPVBZX1NTSVpFX1RfTUFYOworICAgIFB5X3NzaXplX3QgcmVzOworCisgICAgaWYgKCFzdHJpbmdsaWJfcGFyc2VfYXJnc19maW5kcygiZmluZC9yZmluZC9pbmRleC9yaW5kZXgiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJncywgJnN1Ym9iaiwgJnN0YXJ0LCAmZW5kKSkKKyAgICAgICAgcmV0dXJuIC0yOworICAgIGlmIChfZ2V0YnVmZmVyKHN1Ym9iaiwgJnN1YmJ1ZikgPCAwKQorICAgICAgICByZXR1cm4gLTI7CisgICAgaWYgKGRpciA+IDApCisgICAgICAgIHJlcyA9IHN0cmluZ2xpYl9maW5kX3NsaWNlKAorICAgICAgICAgICAgUHlCeXRlQXJyYXlfQVNfU1RSSU5HKHNlbGYpLCBQeUJ5dGVBcnJheV9HRVRfU0laRShzZWxmKSwKKyAgICAgICAgICAgIHN1YmJ1Zi5idWYsIHN1YmJ1Zi5sZW4sIHN0YXJ0LCBlbmQpOworICAgIGVsc2UKKyAgICAgICAgcmVzID0gc3RyaW5nbGliX3JmaW5kX3NsaWNlKAorICAgICAgICAgICAgUHlCeXRlQXJyYXlfQVNfU1RSSU5HKHNlbGYpLCBQeUJ5dGVBcnJheV9HRVRfU0laRShzZWxmKSwKKyAgICAgICAgICAgIHN1YmJ1Zi5idWYsIHN1YmJ1Zi5sZW4sIHN0YXJ0LCBlbmQpOworICAgIFB5QnVmZmVyX1JlbGVhc2UoJnN1YmJ1Zik7CisgICAgcmV0dXJuIHJlczsKK30KKworUHlEb2NfU1RSVkFSKGZpbmRfX2RvY19fLAorIkIuZmluZChzdWIgWyxzdGFydCBbLGVuZF1dKSAtPiBpbnRcblwKK1xuXAorUmV0dXJuIHRoZSBsb3dlc3QgaW5kZXggaW4gQiB3aGVyZSBzdWJzZWN0aW9uIHN1YiBpcyBmb3VuZCxcblwKK3N1Y2ggdGhhdCBzdWIgaXMgY29udGFpbmVkIHdpdGhpbiBCW3N0YXJ0LGVuZF0uICBPcHRpb25hbFxuXAorYXJndW1lbnRzIHN0YXJ0IGFuZCBlbmQgYXJlIGludGVycHJldGVkIGFzIGluIHNsaWNlIG5vdGF0aW9uLlxuXAorXG5cCitSZXR1cm4gLTEgb24gZmFpbHVyZS4iKTsKKworc3RhdGljIFB5T2JqZWN0ICoKK2J5dGVhcnJheV9maW5kKFB5Qnl0ZUFycmF5T2JqZWN0ICpzZWxmLCBQeU9iamVjdCAqYXJncykKK3sKKyAgICBQeV9zc2l6ZV90IHJlc3VsdCA9IGJ5dGVhcnJheV9maW5kX2ludGVybmFsKHNlbGYsIGFyZ3MsICsxKTsKKyAgICBpZiAocmVzdWx0ID09IC0yKQorICAgICAgICByZXR1cm4gTlVMTDsKKyAgICByZXR1cm4gUHlJbnRfRnJvbVNzaXplX3QocmVzdWx0KTsKK30KKworUHlEb2NfU1RSVkFSKGNvdW50X19kb2NfXywKKyJCLmNvdW50KHN1YiBbLHN0YXJ0IFssZW5kXV0pIC0+IGludFxuXAorXG5cCitSZXR1cm4gdGhlIG51bWJlciBvZiBub24tb3ZlcmxhcHBpbmcgb2NjdXJyZW5jZXMgb2Ygc3Vic2VjdGlvbiBzdWIgaW5cblwKK2J5dGVzIEJbc3RhcnQ6ZW5kXS4gIE9wdGlvbmFsIGFyZ3VtZW50cyBzdGFydCBhbmQgZW5kIGFyZSBpbnRlcnByZXRlZFxuXAorYXMgaW4gc2xpY2Ugbm90YXRpb24uIik7CisKK3N0YXRpYyBQeU9iamVjdCAqCitieXRlYXJyYXlfY291bnQoUHlCeXRlQXJyYXlPYmplY3QgKnNlbGYsIFB5T2JqZWN0ICphcmdzKQoreworICAgIFB5T2JqZWN0ICpzdWJfb2JqOworICAgIGNvbnN0IGNoYXIgKnN0ciA9IFB5Qnl0ZUFycmF5X0FTX1NUUklORyhzZWxmKTsKKyAgICBQeV9zc2l6ZV90IHN0YXJ0ID0gMCwgZW5kID0gUFlfU1NJWkVfVF9NQVg7CisgICAgUHlfYnVmZmVyIHZzdWI7CisgICAgUHlPYmplY3QgKmNvdW50X29iajsKKworICAgIGlmICghc3RyaW5nbGliX3BhcnNlX2FyZ3NfZmluZHMoImNvdW50IiwgYXJncywgJnN1Yl9vYmosICZzdGFydCwgJmVuZCkpCisgICAgICAgIHJldHVybiBOVUxMOworCisgICAgaWYgKF9nZXRidWZmZXIoc3ViX29iaiwgJnZzdWIpIDwgMCkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisKKyAgICBBREpVU1RfSU5ESUNFUyhzdGFydCwgZW5kLCBQeUJ5dGVBcnJheV9HRVRfU0laRShzZWxmKSk7CisKKyAgICBjb3VudF9vYmogPSBQeUludF9Gcm9tU3NpemVfdCgKKyAgICAgICAgc3RyaW5nbGliX2NvdW50KHN0ciArIHN0YXJ0LCBlbmQgLSBzdGFydCwgdnN1Yi5idWYsIHZzdWIubGVuLCBQWV9TU0laRV9UX01BWCkKKyAgICAgICAgKTsKKyAgICBQeUJ1ZmZlcl9SZWxlYXNlKCZ2c3ViKTsKKyAgICByZXR1cm4gY291bnRfb2JqOworfQorCisKK1B5RG9jX1NUUlZBUihpbmRleF9fZG9jX18sCisiQi5pbmRleChzdWIgWyxzdGFydCBbLGVuZF1dKSAtPiBpbnRcblwKK1xuXAorTGlrZSBCLmZpbmQoKSBidXQgcmFpc2UgVmFsdWVFcnJvciB3aGVuIHRoZSBzdWJzZWN0aW9uIGlzIG5vdCBmb3VuZC4iKTsKKworc3RhdGljIFB5T2JqZWN0ICoKK2J5dGVhcnJheV9pbmRleChQeUJ5dGVBcnJheU9iamVjdCAqc2VsZiwgUHlPYmplY3QgKmFyZ3MpCit7CisgICAgUHlfc3NpemVfdCByZXN1bHQgPSBieXRlYXJyYXlfZmluZF9pbnRlcm5hbChzZWxmLCBhcmdzLCArMSk7CisgICAgaWYgKHJlc3VsdCA9PSAtMikKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgaWYgKHJlc3VsdCA9PSAtMSkgeworICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfVmFsdWVFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICJzdWJzZWN0aW9uIG5vdCBmb3VuZCIpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgcmV0dXJuIFB5SW50X0Zyb21Tc2l6ZV90KHJlc3VsdCk7Cit9CisKKworUHlEb2NfU1RSVkFSKHJmaW5kX19kb2NfXywKKyJCLnJmaW5kKHN1YiBbLHN0YXJ0IFssZW5kXV0pIC0+IGludFxuXAorXG5cCitSZXR1cm4gdGhlIGhpZ2hlc3QgaW5kZXggaW4gQiB3aGVyZSBzdWJzZWN0aW9uIHN1YiBpcyBmb3VuZCxcblwKK3N1Y2ggdGhhdCBzdWIgaXMgY29udGFpbmVkIHdpdGhpbiBCW3N0YXJ0LGVuZF0uICBPcHRpb25hbFxuXAorYXJndW1lbnRzIHN0YXJ0IGFuZCBlbmQgYXJlIGludGVycHJldGVkIGFzIGluIHNsaWNlIG5vdGF0aW9uLlxuXAorXG5cCitSZXR1cm4gLTEgb24gZmFpbHVyZS4iKTsKKworc3RhdGljIFB5T2JqZWN0ICoKK2J5dGVhcnJheV9yZmluZChQeUJ5dGVBcnJheU9iamVjdCAqc2VsZiwgUHlPYmplY3QgKmFyZ3MpCit7CisgICAgUHlfc3NpemVfdCByZXN1bHQgPSBieXRlYXJyYXlfZmluZF9pbnRlcm5hbChzZWxmLCBhcmdzLCAtMSk7CisgICAgaWYgKHJlc3VsdCA9PSAtMikKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgcmV0dXJuIFB5SW50X0Zyb21Tc2l6ZV90KHJlc3VsdCk7Cit9CisKKworUHlEb2NfU1RSVkFSKHJpbmRleF9fZG9jX18sCisiQi5yaW5kZXgoc3ViIFssc3RhcnQgWyxlbmRdXSkgLT4gaW50XG5cCitcblwKK0xpa2UgQi5yZmluZCgpIGJ1dCByYWlzZSBWYWx1ZUVycm9yIHdoZW4gdGhlIHN1YnNlY3Rpb24gaXMgbm90IGZvdW5kLiIpOworCitzdGF0aWMgUHlPYmplY3QgKgorYnl0ZWFycmF5X3JpbmRleChQeUJ5dGVBcnJheU9iamVjdCAqc2VsZiwgUHlPYmplY3QgKmFyZ3MpCit7CisgICAgUHlfc3NpemVfdCByZXN1bHQgPSBieXRlYXJyYXlfZmluZF9pbnRlcm5hbChzZWxmLCBhcmdzLCAtMSk7CisgICAgaWYgKHJlc3VsdCA9PSAtMikKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgaWYgKHJlc3VsdCA9PSAtMSkgeworICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfVmFsdWVFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICJzdWJzZWN0aW9uIG5vdCBmb3VuZCIpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgcmV0dXJuIFB5SW50X0Zyb21Tc2l6ZV90KHJlc3VsdCk7Cit9CisKKworc3RhdGljIGludAorYnl0ZWFycmF5X2NvbnRhaW5zKFB5T2JqZWN0ICpzZWxmLCBQeU9iamVjdCAqYXJnKQoreworICAgIFB5X3NzaXplX3QgaXZhbCA9IFB5TnVtYmVyX0FzU3NpemVfdChhcmcsIFB5RXhjX1ZhbHVlRXJyb3IpOworICAgIGlmIChpdmFsID09IC0xICYmIFB5RXJyX09jY3VycmVkKCkpIHsKKyAgICAgICAgUHlfYnVmZmVyIHZhcmc7CisgICAgICAgIGludCBwb3M7CisgICAgICAgIFB5RXJyX0NsZWFyKCk7CisgICAgICAgIGlmIChfZ2V0YnVmZmVyKGFyZywgJnZhcmcpIDwgMCkKKyAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgcG9zID0gc3RyaW5nbGliX2ZpbmQoUHlCeXRlQXJyYXlfQVNfU1RSSU5HKHNlbGYpLCBQeV9TSVpFKHNlbGYpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXJnLmJ1ZiwgdmFyZy5sZW4sIDApOworICAgICAgICBQeUJ1ZmZlcl9SZWxlYXNlKCZ2YXJnKTsKKyAgICAgICAgcmV0dXJuIHBvcyA+PSAwOworICAgIH0KKyAgICBpZiAoaXZhbCA8IDAgfHwgaXZhbCA+PSAyNTYpIHsKKyAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1ZhbHVlRXJyb3IsICJieXRlIG11c3QgYmUgaW4gcmFuZ2UoMCwgMjU2KSIpOworICAgICAgICByZXR1cm4gLTE7CisgICAgfQorCisgICAgcmV0dXJuIG1lbWNocihQeUJ5dGVBcnJheV9BU19TVFJJTkcoc2VsZiksIGl2YWwsIFB5X1NJWkUoc2VsZikpICE9IE5VTEw7Cit9CisKKworLyogTWF0Y2hlcyB0aGUgZW5kIChkaXJlY3Rpb24gPj0gMCkgb3Igc3RhcnQgKGRpcmVjdGlvbiA8IDApIG9mIHNlbGYKKyAqIGFnYWluc3Qgc3Vic3RyLCB1c2luZyB0aGUgc3RhcnQgYW5kIGVuZCBhcmd1bWVudHMuIFJldHVybnMKKyAqIC0xIG9uIGVycm9yLCAwIGlmIG5vdCBmb3VuZCBhbmQgMSBpZiBmb3VuZC4KKyAqLworUHlfTE9DQUwoaW50KQorX2J5dGVhcnJheV90YWlsbWF0Y2goUHlCeXRlQXJyYXlPYmplY3QgKnNlbGYsIFB5T2JqZWN0ICpzdWJzdHIsIFB5X3NzaXplX3Qgc3RhcnQsCisgICAgICAgICAgICAgICAgIFB5X3NzaXplX3QgZW5kLCBpbnQgZGlyZWN0aW9uKQoreworICAgIFB5X3NzaXplX3QgbGVuID0gUHlCeXRlQXJyYXlfR0VUX1NJWkUoc2VsZik7CisgICAgY29uc3QgY2hhciogc3RyOworICAgIFB5X2J1ZmZlciB2c3Vic3RyOworICAgIGludCBydiA9IDA7CisKKyAgICBzdHIgPSBQeUJ5dGVBcnJheV9BU19TVFJJTkcoc2VsZik7CisKKyAgICBpZiAoX2dldGJ1ZmZlcihzdWJzdHIsICZ2c3Vic3RyKSA8IDApCisgICAgICAgIHJldHVybiAtMTsKKworICAgIEFESlVTVF9JTkRJQ0VTKHN0YXJ0LCBlbmQsIGxlbik7CisKKyAgICBpZiAoZGlyZWN0aW9uIDwgMCkgeworICAgICAgICAvKiBzdGFydHN3aXRoICovCisgICAgICAgIGlmIChzdGFydCt2c3Vic3RyLmxlbiA+IGxlbikgeworICAgICAgICAgICAgZ290byBkb25lOworICAgICAgICB9CisgICAgfSBlbHNlIHsKKyAgICAgICAgLyogZW5kc3dpdGggKi8KKyAgICAgICAgaWYgKGVuZC1zdGFydCA8IHZzdWJzdHIubGVuIHx8IHN0YXJ0ID4gbGVuKSB7CisgICAgICAgICAgICBnb3RvIGRvbmU7CisgICAgICAgIH0KKworICAgICAgICBpZiAoZW5kLXZzdWJzdHIubGVuID4gc3RhcnQpCisgICAgICAgICAgICBzdGFydCA9IGVuZCAtIHZzdWJzdHIubGVuOworICAgIH0KKyAgICBpZiAoZW5kLXN0YXJ0ID49IHZzdWJzdHIubGVuKQorICAgICAgICBydiA9ICEgbWVtY21wKHN0citzdGFydCwgdnN1YnN0ci5idWYsIHZzdWJzdHIubGVuKTsKKworZG9uZToKKyAgICBQeUJ1ZmZlcl9SZWxlYXNlKCZ2c3Vic3RyKTsKKyAgICByZXR1cm4gcnY7Cit9CisKKworUHlEb2NfU1RSVkFSKHN0YXJ0c3dpdGhfX2RvY19fLAorIkIuc3RhcnRzd2l0aChwcmVmaXggWyxzdGFydCBbLGVuZF1dKSAtPiBib29sXG5cCitcblwKK1JldHVybiBUcnVlIGlmIEIgc3RhcnRzIHdpdGggdGhlIHNwZWNpZmllZCBwcmVmaXgsIEZhbHNlIG90aGVyd2lzZS5cblwKK1dpdGggb3B0aW9uYWwgc3RhcnQsIHRlc3QgQiBiZWdpbm5pbmcgYXQgdGhhdCBwb3NpdGlvbi5cblwKK1dpdGggb3B0aW9uYWwgZW5kLCBzdG9wIGNvbXBhcmluZyBCIGF0IHRoYXQgcG9zaXRpb24uXG5cCitwcmVmaXggY2FuIGFsc28gYmUgYSB0dXBsZSBvZiBzdHJpbmdzIHRvIHRyeS4iKTsKKworc3RhdGljIFB5T2JqZWN0ICoKK2J5dGVhcnJheV9zdGFydHN3aXRoKFB5Qnl0ZUFycmF5T2JqZWN0ICpzZWxmLCBQeU9iamVjdCAqYXJncykKK3sKKyAgICBQeV9zc2l6ZV90IHN0YXJ0ID0gMDsKKyAgICBQeV9zc2l6ZV90IGVuZCA9IFBZX1NTSVpFX1RfTUFYOworICAgIFB5T2JqZWN0ICpzdWJvYmo7CisgICAgaW50IHJlc3VsdDsKKworICAgIGlmICghc3RyaW5nbGliX3BhcnNlX2FyZ3NfZmluZHMoInN0YXJ0c3dpdGgiLCBhcmdzLCAmc3Vib2JqLCAmc3RhcnQsICZlbmQpKQorICAgICAgICByZXR1cm4gTlVMTDsKKyAgICBpZiAoUHlUdXBsZV9DaGVjayhzdWJvYmopKSB7CisgICAgICAgIFB5X3NzaXplX3QgaTsKKyAgICAgICAgZm9yIChpID0gMDsgaSA8IFB5VHVwbGVfR0VUX1NJWkUoc3Vib2JqKTsgaSsrKSB7CisgICAgICAgICAgICByZXN1bHQgPSBfYnl0ZWFycmF5X3RhaWxtYXRjaChzZWxmLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQeVR1cGxlX0dFVF9JVEVNKHN1Ym9iaiwgaSksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXJ0LCBlbmQsIC0xKTsKKyAgICAgICAgICAgIGlmIChyZXN1bHQgPT0gLTEpCisgICAgICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgICAgICAgICBlbHNlIGlmIChyZXN1bHQpIHsKKyAgICAgICAgICAgICAgICBQeV9SRVRVUk5fVFJVRTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBQeV9SRVRVUk5fRkFMU0U7CisgICAgfQorICAgIHJlc3VsdCA9IF9ieXRlYXJyYXlfdGFpbG1hdGNoKHNlbGYsIHN1Ym9iaiwgc3RhcnQsIGVuZCwgLTEpOworICAgIGlmIChyZXN1bHQgPT0gLTEpCisgICAgICAgIHJldHVybiBOVUxMOworICAgIGVsc2UKKyAgICAgICAgcmV0dXJuIFB5Qm9vbF9Gcm9tTG9uZyhyZXN1bHQpOworfQorCitQeURvY19TVFJWQVIoZW5kc3dpdGhfX2RvY19fLAorIkIuZW5kc3dpdGgoc3VmZml4IFssc3RhcnQgWyxlbmRdXSkgLT4gYm9vbFxuXAorXG5cCitSZXR1cm4gVHJ1ZSBpZiBCIGVuZHMgd2l0aCB0aGUgc3BlY2lmaWVkIHN1ZmZpeCwgRmFsc2Ugb3RoZXJ3aXNlLlxuXAorV2l0aCBvcHRpb25hbCBzdGFydCwgdGVzdCBCIGJlZ2lubmluZyBhdCB0aGF0IHBvc2l0aW9uLlxuXAorV2l0aCBvcHRpb25hbCBlbmQsIHN0b3AgY29tcGFyaW5nIEIgYXQgdGhhdCBwb3NpdGlvbi5cblwKK3N1ZmZpeCBjYW4gYWxzbyBiZSBhIHR1cGxlIG9mIHN0cmluZ3MgdG8gdHJ5LiIpOworCitzdGF0aWMgUHlPYmplY3QgKgorYnl0ZWFycmF5X2VuZHN3aXRoKFB5Qnl0ZUFycmF5T2JqZWN0ICpzZWxmLCBQeU9iamVjdCAqYXJncykKK3sKKyAgICBQeV9zc2l6ZV90IHN0YXJ0ID0gMDsKKyAgICBQeV9zc2l6ZV90IGVuZCA9IFBZX1NTSVpFX1RfTUFYOworICAgIFB5T2JqZWN0ICpzdWJvYmo7CisgICAgaW50IHJlc3VsdDsKKworICAgIGlmICghc3RyaW5nbGliX3BhcnNlX2FyZ3NfZmluZHMoImVuZHN3aXRoIiwgYXJncywgJnN1Ym9iaiwgJnN0YXJ0LCAmZW5kKSkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgaWYgKFB5VHVwbGVfQ2hlY2soc3Vib2JqKSkgeworICAgICAgICBQeV9zc2l6ZV90IGk7CisgICAgICAgIGZvciAoaSA9IDA7IGkgPCBQeVR1cGxlX0dFVF9TSVpFKHN1Ym9iaik7IGkrKykgeworICAgICAgICAgICAgcmVzdWx0ID0gX2J5dGVhcnJheV90YWlsbWF0Y2goc2VsZiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHlUdXBsZV9HRVRfSVRFTShzdWJvYmosIGkpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGFydCwgZW5kLCArMSk7CisgICAgICAgICAgICBpZiAocmVzdWx0ID09IC0xKQorICAgICAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgICAgICAgICAgZWxzZSBpZiAocmVzdWx0KSB7CisgICAgICAgICAgICAgICAgUHlfUkVUVVJOX1RSVUU7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgUHlfUkVUVVJOX0ZBTFNFOworICAgIH0KKyAgICByZXN1bHQgPSBfYnl0ZWFycmF5X3RhaWxtYXRjaChzZWxmLCBzdWJvYmosIHN0YXJ0LCBlbmQsICsxKTsKKyAgICBpZiAocmVzdWx0ID09IC0xKQorICAgICAgICByZXR1cm4gTlVMTDsKKyAgICBlbHNlCisgICAgICAgIHJldHVybiBQeUJvb2xfRnJvbUxvbmcocmVzdWx0KTsKK30KKworCitQeURvY19TVFJWQVIodHJhbnNsYXRlX19kb2NfXywKKyJCLnRyYW5zbGF0ZSh0YWJsZVssIGRlbGV0ZWNoYXJzXSkgLT4gYnl0ZWFycmF5XG5cCitcblwKK1JldHVybiBhIGNvcHkgb2YgQiwgd2hlcmUgYWxsIGNoYXJhY3RlcnMgb2NjdXJyaW5nIGluIHRoZVxuXAorb3B0aW9uYWwgYXJndW1lbnQgZGVsZXRlY2hhcnMgYXJlIHJlbW92ZWQsIGFuZCB0aGUgcmVtYWluaW5nXG5cCitjaGFyYWN0ZXJzIGhhdmUgYmVlbiBtYXBwZWQgdGhyb3VnaCB0aGUgZ2l2ZW4gdHJhbnNsYXRpb25cblwKK3RhYmxlLCB3aGljaCBtdXN0IGJlIGEgYnl0ZXMgb2JqZWN0IG9mIGxlbmd0aCAyNTYuIik7CisKK3N0YXRpYyBQeU9iamVjdCAqCitieXRlYXJyYXlfdHJhbnNsYXRlKFB5Qnl0ZUFycmF5T2JqZWN0ICpzZWxmLCBQeU9iamVjdCAqYXJncykKK3sKKyAgICByZWdpc3RlciBjaGFyICppbnB1dCwgKm91dHB1dDsKKyAgICByZWdpc3RlciBjb25zdCBjaGFyICp0YWJsZTsKKyAgICByZWdpc3RlciBQeV9zc2l6ZV90IGksIGM7CisgICAgUHlPYmplY3QgKmlucHV0X29iaiA9IChQeU9iamVjdCopc2VsZjsKKyAgICBjb25zdCBjaGFyICpvdXRwdXRfc3RhcnQ7CisgICAgUHlfc3NpemVfdCBpbmxlbjsKKyAgICBQeU9iamVjdCAqcmVzdWx0ID0gTlVMTDsKKyAgICBpbnQgdHJhbnNfdGFibGVbMjU2XTsKKyAgICBQeU9iamVjdCAqdGFibGVvYmogPSBOVUxMLCAqZGVsb2JqID0gTlVMTDsKKyAgICBQeV9idWZmZXIgdnRhYmxlLCB2ZGVsOworCisgICAgaWYgKCFQeUFyZ19VbnBhY2tUdXBsZShhcmdzLCAidHJhbnNsYXRlIiwgMSwgMiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICZ0YWJsZW9iaiwgJmRlbG9iaikpCisgICAgICAgICAgcmV0dXJuIE5VTEw7CisKKyAgICBpZiAodGFibGVvYmogPT0gUHlfTm9uZSkgeworICAgICAgICB0YWJsZSA9IE5VTEw7CisgICAgICAgIHRhYmxlb2JqID0gTlVMTDsKKyAgICB9IGVsc2UgaWYgKF9nZXRidWZmZXIodGFibGVvYmosICZ2dGFibGUpIDwgMCkgeworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9IGVsc2UgeworICAgICAgICBpZiAodnRhYmxlLmxlbiAhPSAyNTYpIHsKKyAgICAgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19WYWx1ZUVycm9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0cmFuc2xhdGlvbiB0YWJsZSBtdXN0IGJlIDI1NiBjaGFyYWN0ZXJzIGxvbmciKTsKKyAgICAgICAgICAgIFB5QnVmZmVyX1JlbGVhc2UoJnZ0YWJsZSk7CisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgfQorICAgICAgICB0YWJsZSA9IChjb25zdCBjaGFyKil2dGFibGUuYnVmOworICAgIH0KKworICAgIGlmIChkZWxvYmogIT0gTlVMTCkgeworICAgICAgICBpZiAoX2dldGJ1ZmZlcihkZWxvYmosICZ2ZGVsKSA8IDApIHsKKyAgICAgICAgICAgIGlmICh0YWJsZW9iaiAhPSBOVUxMKQorICAgICAgICAgICAgICAgIFB5QnVmZmVyX1JlbGVhc2UoJnZ0YWJsZSk7CisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgfQorICAgIH0KKyAgICBlbHNlIHsKKyAgICAgICAgdmRlbC5idWYgPSBOVUxMOworICAgICAgICB2ZGVsLmxlbiA9IDA7CisgICAgfQorCisgICAgaW5sZW4gPSBQeUJ5dGVBcnJheV9HRVRfU0laRShpbnB1dF9vYmopOworICAgIHJlc3VsdCA9IFB5Qnl0ZUFycmF5X0Zyb21TdHJpbmdBbmRTaXplKChjaGFyICopTlVMTCwgaW5sZW4pOworICAgIGlmIChyZXN1bHQgPT0gTlVMTCkKKyAgICAgICAgZ290byBkb25lOworICAgIG91dHB1dF9zdGFydCA9IG91dHB1dCA9IFB5Qnl0ZUFycmF5X0FzU3RyaW5nKHJlc3VsdCk7CisgICAgaW5wdXQgPSBQeUJ5dGVBcnJheV9BU19TVFJJTkcoaW5wdXRfb2JqKTsKKworICAgIGlmICh2ZGVsLmxlbiA9PSAwICYmIHRhYmxlICE9IE5VTEwpIHsKKyAgICAgICAgLyogSWYgbm8gZGVsZXRpb25zIGFyZSByZXF1aXJlZCwgdXNlIGZhc3RlciBjb2RlICovCisgICAgICAgIGZvciAoaSA9IGlubGVuOyAtLWkgPj0gMDsgKSB7CisgICAgICAgICAgICBjID0gUHlfQ0hBUk1BU0soKmlucHV0KyspOworICAgICAgICAgICAgKm91dHB1dCsrID0gdGFibGVbY107CisgICAgICAgIH0KKyAgICAgICAgZ290byBkb25lOworICAgIH0KKworICAgIGlmICh0YWJsZSA9PSBOVUxMKSB7CisgICAgICAgIGZvciAoaSA9IDA7IGkgPCAyNTY7IGkrKykKKyAgICAgICAgICAgIHRyYW5zX3RhYmxlW2ldID0gUHlfQ0hBUk1BU0soaSk7CisgICAgfSBlbHNlIHsKKyAgICAgICAgZm9yIChpID0gMDsgaSA8IDI1NjsgaSsrKQorICAgICAgICAgICAgdHJhbnNfdGFibGVbaV0gPSBQeV9DSEFSTUFTSyh0YWJsZVtpXSk7CisgICAgfQorCisgICAgZm9yIChpID0gMDsgaSA8IHZkZWwubGVuOyBpKyspCisgICAgICAgIHRyYW5zX3RhYmxlWyhpbnQpIFB5X0NIQVJNQVNLKCAoKHVuc2lnbmVkIGNoYXIqKXZkZWwuYnVmKVtpXSApXSA9IC0xOworCisgICAgZm9yIChpID0gaW5sZW47IC0taSA+PSAwOyApIHsKKyAgICAgICAgYyA9IFB5X0NIQVJNQVNLKCppbnB1dCsrKTsKKyAgICAgICAgaWYgKHRyYW5zX3RhYmxlW2NdICE9IC0xKQorICAgICAgICAgICAgaWYgKFB5X0NIQVJNQVNLKCpvdXRwdXQrKyA9IChjaGFyKXRyYW5zX3RhYmxlW2NdKSA9PSBjKQorICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICB9CisgICAgLyogRml4IHRoZSBzaXplIG9mIHRoZSByZXN1bHRpbmcgc3RyaW5nICovCisgICAgaWYgKGlubGVuID4gMCkKKyAgICAgICAgUHlCeXRlQXJyYXlfUmVzaXplKHJlc3VsdCwgb3V0cHV0IC0gb3V0cHV0X3N0YXJ0KTsKKworZG9uZToKKyAgICBpZiAodGFibGVvYmogIT0gTlVMTCkKKyAgICAgICAgUHlCdWZmZXJfUmVsZWFzZSgmdnRhYmxlKTsKKyAgICBpZiAoZGVsb2JqICE9IE5VTEwpCisgICAgICAgIFB5QnVmZmVyX1JlbGVhc2UoJnZkZWwpOworICAgIHJldHVybiByZXN1bHQ7Cit9CisKKworLyogZmluZCBhbmQgY291bnQgY2hhcmFjdGVycyBhbmQgc3Vic3RyaW5ncyAqLworCisjZGVmaW5lIGZpbmRjaGFyKHRhcmdldCwgdGFyZ2V0X2xlbiwgYykgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAoKGNoYXIgKiltZW1jaHIoKGNvbnN0IHZvaWQgKikodGFyZ2V0KSwgYywgdGFyZ2V0X2xlbikpCisKKworLyogQnl0ZXMgb3BzIG11c3QgcmV0dXJuIGEgc3RyaW5nLCBjcmVhdGUgYSBjb3B5ICovCitQeV9MT0NBTChQeUJ5dGVBcnJheU9iamVjdCAqKQorcmV0dXJuX3NlbGYoUHlCeXRlQXJyYXlPYmplY3QgKnNlbGYpCit7CisgICAgcmV0dXJuIChQeUJ5dGVBcnJheU9iamVjdCAqKVB5Qnl0ZUFycmF5X0Zyb21TdHJpbmdBbmRTaXplKAorICAgICAgICAgICAgUHlCeXRlQXJyYXlfQVNfU1RSSU5HKHNlbGYpLAorICAgICAgICAgICAgUHlCeXRlQXJyYXlfR0VUX1NJWkUoc2VsZikpOworfQorCitQeV9MT0NBTF9JTkxJTkUoUHlfc3NpemVfdCkKK2NvdW50Y2hhcihjb25zdCBjaGFyICp0YXJnZXQsIFB5X3NzaXplX3QgdGFyZ2V0X2xlbiwgY2hhciBjLCBQeV9zc2l6ZV90IG1heGNvdW50KQoreworICAgIFB5X3NzaXplX3QgY291bnQ9MDsKKyAgICBjb25zdCBjaGFyICpzdGFydD10YXJnZXQ7CisgICAgY29uc3QgY2hhciAqZW5kPXRhcmdldCt0YXJnZXRfbGVuOworCisgICAgd2hpbGUgKCAoc3RhcnQ9ZmluZGNoYXIoc3RhcnQsIGVuZC1zdGFydCwgYykpICE9IE5VTEwgKSB7CisgICAgICAgIGNvdW50Kys7CisgICAgICAgIGlmIChjb3VudCA+PSBtYXhjb3VudCkKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICBzdGFydCArPSAxOworICAgIH0KKyAgICByZXR1cm4gY291bnQ7Cit9CisKKworLyogQWxnb3JpdGhtcyBmb3IgZGlmZmVyZW50IGNhc2VzIG9mIHN0cmluZyByZXBsYWNlbWVudCAqLworCisvKiBsZW4oc2VsZik+PTEsIGZyb209IiIsIGxlbih0byk+PTEsIG1heGNvdW50Pj0xICovCitQeV9MT0NBTChQeUJ5dGVBcnJheU9iamVjdCAqKQorcmVwbGFjZV9pbnRlcmxlYXZlKFB5Qnl0ZUFycmF5T2JqZWN0ICpzZWxmLAorICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgKnRvX3MsIFB5X3NzaXplX3QgdG9fbGVuLAorICAgICAgICAgICAgICAgICAgIFB5X3NzaXplX3QgbWF4Y291bnQpCit7CisgICAgY2hhciAqc2VsZl9zLCAqcmVzdWx0X3M7CisgICAgUHlfc3NpemVfdCBzZWxmX2xlbiwgcmVzdWx0X2xlbjsKKyAgICBQeV9zc2l6ZV90IGNvdW50LCBpLCBwcm9kdWN0OworICAgIFB5Qnl0ZUFycmF5T2JqZWN0ICpyZXN1bHQ7CisKKyAgICBzZWxmX2xlbiA9IFB5Qnl0ZUFycmF5X0dFVF9TSVpFKHNlbGYpOworCisgICAgLyogMSBhdCB0aGUgZW5kIHBsdXMgMSBhZnRlciBldmVyeSBjaGFyYWN0ZXIgKi8KKyAgICBjb3VudCA9IHNlbGZfbGVuKzE7CisgICAgaWYgKG1heGNvdW50IDwgY291bnQpCisgICAgICAgIGNvdW50ID0gbWF4Y291bnQ7CisKKyAgICAvKiBDaGVjayBmb3Igb3ZlcmZsb3cgKi8KKyAgICAvKiAgIHJlc3VsdF9sZW4gPSBjb3VudCAqIHRvX2xlbiArIHNlbGZfbGVuOyAqLworICAgIHByb2R1Y3QgPSBjb3VudCAqIHRvX2xlbjsKKyAgICBpZiAocHJvZHVjdCAvIHRvX2xlbiAhPSBjb3VudCkgeworICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfT3ZlcmZsb3dFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICJyZXBsYWNlIHN0cmluZyBpcyB0b28gbG9uZyIpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgcmVzdWx0X2xlbiA9IHByb2R1Y3QgKyBzZWxmX2xlbjsKKyAgICBpZiAocmVzdWx0X2xlbiA8IDApIHsKKyAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX092ZXJmbG93RXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAgICAicmVwbGFjZSBzdHJpbmcgaXMgdG9vIGxvbmciKTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorCisgICAgaWYgKCEgKHJlc3VsdCA9IChQeUJ5dGVBcnJheU9iamVjdCAqKQorICAgICAgICAgICAgICAgICAgICAgUHlCeXRlQXJyYXlfRnJvbVN0cmluZ0FuZFNpemUoTlVMTCwgcmVzdWx0X2xlbikpICkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisKKyAgICBzZWxmX3MgPSBQeUJ5dGVBcnJheV9BU19TVFJJTkcoc2VsZik7CisgICAgcmVzdWx0X3MgPSBQeUJ5dGVBcnJheV9BU19TVFJJTkcocmVzdWx0KTsKKworICAgIC8qIFRPRE86IHNwZWNpYWwgY2FzZSBzaW5nbGUgY2hhcmFjdGVyLCB3aGljaCBkb2Vzbid0IG5lZWQgbWVtY3B5ICovCisKKyAgICAvKiBMYXkgdGhlIGZpcnN0IG9uZSBkb3duIChndWFyYW50ZWVkIHRoaXMgd2lsbCBvY2N1cikgKi8KKyAgICBQeV9NRU1DUFkocmVzdWx0X3MsIHRvX3MsIHRvX2xlbik7CisgICAgcmVzdWx0X3MgKz0gdG9fbGVuOworICAgIGNvdW50IC09IDE7CisKKyAgICBmb3IgKGk9MDsgaTxjb3VudDsgaSsrKSB7CisgICAgICAgICpyZXN1bHRfcysrID0gKnNlbGZfcysrOworICAgICAgICBQeV9NRU1DUFkocmVzdWx0X3MsIHRvX3MsIHRvX2xlbik7CisgICAgICAgIHJlc3VsdF9zICs9IHRvX2xlbjsKKyAgICB9CisKKyAgICAvKiBDb3B5IHRoZSByZXN0IG9mIHRoZSBvcmlnaW5hbCBzdHJpbmcgKi8KKyAgICBQeV9NRU1DUFkocmVzdWx0X3MsIHNlbGZfcywgc2VsZl9sZW4taSk7CisKKyAgICByZXR1cm4gcmVzdWx0OworfQorCisvKiBTcGVjaWFsIGNhc2UgZm9yIGRlbGV0aW5nIGEgc2luZ2xlIGNoYXJhY3RlciAqLworLyogbGVuKHNlbGYpPj0xLCBsZW4oZnJvbSk9PTEsIHRvPSIiLCBtYXhjb3VudD49MSAqLworUHlfTE9DQUwoUHlCeXRlQXJyYXlPYmplY3QgKikKK3JlcGxhY2VfZGVsZXRlX3NpbmdsZV9jaGFyYWN0ZXIoUHlCeXRlQXJyYXlPYmplY3QgKnNlbGYsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYXIgZnJvbV9jLCBQeV9zc2l6ZV90IG1heGNvdW50KQoreworICAgIGNoYXIgKnNlbGZfcywgKnJlc3VsdF9zOworICAgIGNoYXIgKnN0YXJ0LCAqbmV4dCwgKmVuZDsKKyAgICBQeV9zc2l6ZV90IHNlbGZfbGVuLCByZXN1bHRfbGVuOworICAgIFB5X3NzaXplX3QgY291bnQ7CisgICAgUHlCeXRlQXJyYXlPYmplY3QgKnJlc3VsdDsKKworICAgIHNlbGZfbGVuID0gUHlCeXRlQXJyYXlfR0VUX1NJWkUoc2VsZik7CisgICAgc2VsZl9zID0gUHlCeXRlQXJyYXlfQVNfU1RSSU5HKHNlbGYpOworCisgICAgY291bnQgPSBjb3VudGNoYXIoc2VsZl9zLCBzZWxmX2xlbiwgZnJvbV9jLCBtYXhjb3VudCk7CisgICAgaWYgKGNvdW50ID09IDApIHsKKyAgICAgICAgcmV0dXJuIHJldHVybl9zZWxmKHNlbGYpOworICAgIH0KKworICAgIHJlc3VsdF9sZW4gPSBzZWxmX2xlbiAtIGNvdW50OyAgLyogZnJvbV9sZW4gPT0gMSAqLworICAgIGFzc2VydChyZXN1bHRfbGVuPj0wKTsKKworICAgIGlmICggKHJlc3VsdCA9IChQeUJ5dGVBcnJheU9iamVjdCAqKQorICAgICAgICAgICAgICAgICAgICBQeUJ5dGVBcnJheV9Gcm9tU3RyaW5nQW5kU2l6ZShOVUxMLCByZXN1bHRfbGVuKSkgPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgcmVzdWx0X3MgPSBQeUJ5dGVBcnJheV9BU19TVFJJTkcocmVzdWx0KTsKKworICAgIHN0YXJ0ID0gc2VsZl9zOworICAgIGVuZCA9IHNlbGZfcyArIHNlbGZfbGVuOworICAgIHdoaWxlIChjb3VudC0tID4gMCkgeworICAgICAgICBuZXh0ID0gZmluZGNoYXIoc3RhcnQsIGVuZC1zdGFydCwgZnJvbV9jKTsKKyAgICAgICAgaWYgKG5leHQgPT0gTlVMTCkKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICBQeV9NRU1DUFkocmVzdWx0X3MsIHN0YXJ0LCBuZXh0LXN0YXJ0KTsKKyAgICAgICAgcmVzdWx0X3MgKz0gKG5leHQtc3RhcnQpOworICAgICAgICBzdGFydCA9IG5leHQrMTsKKyAgICB9CisgICAgUHlfTUVNQ1BZKHJlc3VsdF9zLCBzdGFydCwgZW5kLXN0YXJ0KTsKKworICAgIHJldHVybiByZXN1bHQ7Cit9CisKKy8qIGxlbihzZWxmKT49MSwgbGVuKGZyb20pPj0yLCB0bz0iIiwgbWF4Y291bnQ+PTEgKi8KKworUHlfTE9DQUwoUHlCeXRlQXJyYXlPYmplY3QgKikKK3JlcGxhY2VfZGVsZXRlX3N1YnN0cmluZyhQeUJ5dGVBcnJheU9iamVjdCAqc2VsZiwKKyAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyICpmcm9tX3MsIFB5X3NzaXplX3QgZnJvbV9sZW4sCisgICAgICAgICAgICAgICAgICAgICAgICAgUHlfc3NpemVfdCBtYXhjb3VudCkKK3sKKyAgICBjaGFyICpzZWxmX3MsICpyZXN1bHRfczsKKyAgICBjaGFyICpzdGFydCwgKm5leHQsICplbmQ7CisgICAgUHlfc3NpemVfdCBzZWxmX2xlbiwgcmVzdWx0X2xlbjsKKyAgICBQeV9zc2l6ZV90IGNvdW50LCBvZmZzZXQ7CisgICAgUHlCeXRlQXJyYXlPYmplY3QgKnJlc3VsdDsKKworICAgIHNlbGZfbGVuID0gUHlCeXRlQXJyYXlfR0VUX1NJWkUoc2VsZik7CisgICAgc2VsZl9zID0gUHlCeXRlQXJyYXlfQVNfU1RSSU5HKHNlbGYpOworCisgICAgY291bnQgPSBzdHJpbmdsaWJfY291bnQoc2VsZl9zLCBzZWxmX2xlbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBmcm9tX3MsIGZyb21fbGVuLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1heGNvdW50KTsKKworICAgIGlmIChjb3VudCA9PSAwKSB7CisgICAgICAgIC8qIG5vIG1hdGNoZXMgKi8KKyAgICAgICAgcmV0dXJuIHJldHVybl9zZWxmKHNlbGYpOworICAgIH0KKworICAgIHJlc3VsdF9sZW4gPSBzZWxmX2xlbiAtIChjb3VudCAqIGZyb21fbGVuKTsKKyAgICBhc3NlcnQgKHJlc3VsdF9sZW4+PTApOworCisgICAgaWYgKCAocmVzdWx0ID0gKFB5Qnl0ZUFycmF5T2JqZWN0ICopCisgICAgICAgIFB5Qnl0ZUFycmF5X0Zyb21TdHJpbmdBbmRTaXplKE5VTEwsIHJlc3VsdF9sZW4pKSA9PSBOVUxMICkKKyAgICAgICAgICAgIHJldHVybiBOVUxMOworCisgICAgcmVzdWx0X3MgPSBQeUJ5dGVBcnJheV9BU19TVFJJTkcocmVzdWx0KTsKKworICAgIHN0YXJ0ID0gc2VsZl9zOworICAgIGVuZCA9IHNlbGZfcyArIHNlbGZfbGVuOworICAgIHdoaWxlIChjb3VudC0tID4gMCkgeworICAgICAgICBvZmZzZXQgPSBzdHJpbmdsaWJfZmluZChzdGFydCwgZW5kLXN0YXJ0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmcm9tX3MsIGZyb21fbGVuLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwKTsKKyAgICAgICAgaWYgKG9mZnNldCA9PSAtMSkKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICBuZXh0ID0gc3RhcnQgKyBvZmZzZXQ7CisKKyAgICAgICAgUHlfTUVNQ1BZKHJlc3VsdF9zLCBzdGFydCwgbmV4dC1zdGFydCk7CisKKyAgICAgICAgcmVzdWx0X3MgKz0gKG5leHQtc3RhcnQpOworICAgICAgICBzdGFydCA9IG5leHQrZnJvbV9sZW47CisgICAgfQorICAgIFB5X01FTUNQWShyZXN1bHRfcywgc3RhcnQsIGVuZC1zdGFydCk7CisgICAgcmV0dXJuIHJlc3VsdDsKK30KKworLyogbGVuKHNlbGYpPj0xLCBsZW4oZnJvbSk9PWxlbih0byk9PTEsIG1heGNvdW50Pj0xICovCitQeV9MT0NBTChQeUJ5dGVBcnJheU9iamVjdCAqKQorcmVwbGFjZV9zaW5nbGVfY2hhcmFjdGVyX2luX3BsYWNlKFB5Qnl0ZUFycmF5T2JqZWN0ICpzZWxmLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYXIgZnJvbV9jLCBjaGFyIHRvX2MsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHlfc3NpemVfdCBtYXhjb3VudCkKK3sKKyAgICBjaGFyICpzZWxmX3MsICpyZXN1bHRfcywgKnN0YXJ0LCAqZW5kLCAqbmV4dDsKKyAgICBQeV9zc2l6ZV90IHNlbGZfbGVuOworICAgIFB5Qnl0ZUFycmF5T2JqZWN0ICpyZXN1bHQ7CisKKyAgICAvKiBUaGUgcmVzdWx0IHN0cmluZyB3aWxsIGJlIHRoZSBzYW1lIHNpemUgKi8KKyAgICBzZWxmX3MgPSBQeUJ5dGVBcnJheV9BU19TVFJJTkcoc2VsZik7CisgICAgc2VsZl9sZW4gPSBQeUJ5dGVBcnJheV9HRVRfU0laRShzZWxmKTsKKworICAgIG5leHQgPSBmaW5kY2hhcihzZWxmX3MsIHNlbGZfbGVuLCBmcm9tX2MpOworCisgICAgaWYgKG5leHQgPT0gTlVMTCkgeworICAgICAgICAvKiBObyBtYXRjaGVzOyByZXR1cm4gdGhlIG9yaWdpbmFsIGJ5dGVzICovCisgICAgICAgIHJldHVybiByZXR1cm5fc2VsZihzZWxmKTsKKyAgICB9CisKKyAgICAvKiBOZWVkIHRvIG1ha2UgYSBuZXcgYnl0ZXMgKi8KKyAgICByZXN1bHQgPSAoUHlCeXRlQXJyYXlPYmplY3QgKikgUHlCeXRlQXJyYXlfRnJvbVN0cmluZ0FuZFNpemUoTlVMTCwgc2VsZl9sZW4pOworICAgIGlmIChyZXN1bHQgPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgcmVzdWx0X3MgPSBQeUJ5dGVBcnJheV9BU19TVFJJTkcocmVzdWx0KTsKKyAgICBQeV9NRU1DUFkocmVzdWx0X3MsIHNlbGZfcywgc2VsZl9sZW4pOworCisgICAgLyogY2hhbmdlIGV2ZXJ5dGhpbmcgaW4tcGxhY2UsIHN0YXJ0aW5nIHdpdGggdGhpcyBvbmUgKi8KKyAgICBzdGFydCA9ICByZXN1bHRfcyArIChuZXh0LXNlbGZfcyk7CisgICAgKnN0YXJ0ID0gdG9fYzsKKyAgICBzdGFydCsrOworICAgIGVuZCA9IHJlc3VsdF9zICsgc2VsZl9sZW47CisKKyAgICB3aGlsZSAoLS1tYXhjb3VudCA+IDApIHsKKyAgICAgICAgbmV4dCA9IGZpbmRjaGFyKHN0YXJ0LCBlbmQtc3RhcnQsIGZyb21fYyk7CisgICAgICAgIGlmIChuZXh0ID09IE5VTEwpCisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgKm5leHQgPSB0b19jOworICAgICAgICBzdGFydCA9IG5leHQrMTsKKyAgICB9CisKKyAgICByZXR1cm4gcmVzdWx0OworfQorCisvKiBsZW4oc2VsZik+PTEsIGxlbihmcm9tKT09bGVuKHRvKT49MiwgbWF4Y291bnQ+PTEgKi8KK1B5X0xPQ0FMKFB5Qnl0ZUFycmF5T2JqZWN0ICopCityZXBsYWNlX3N1YnN0cmluZ19pbl9wbGFjZShQeUJ5dGVBcnJheU9iamVjdCAqc2VsZiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgKmZyb21fcywgUHlfc3NpemVfdCBmcm9tX2xlbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgKnRvX3MsIFB5X3NzaXplX3QgdG9fbGVuLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgUHlfc3NpemVfdCBtYXhjb3VudCkKK3sKKyAgICBjaGFyICpyZXN1bHRfcywgKnN0YXJ0LCAqZW5kOworICAgIGNoYXIgKnNlbGZfczsKKyAgICBQeV9zc2l6ZV90IHNlbGZfbGVuLCBvZmZzZXQ7CisgICAgUHlCeXRlQXJyYXlPYmplY3QgKnJlc3VsdDsKKworICAgIC8qIFRoZSByZXN1bHQgYnl0ZXMgd2lsbCBiZSB0aGUgc2FtZSBzaXplICovCisKKyAgICBzZWxmX3MgPSBQeUJ5dGVBcnJheV9BU19TVFJJTkcoc2VsZik7CisgICAgc2VsZl9sZW4gPSBQeUJ5dGVBcnJheV9HRVRfU0laRShzZWxmKTsKKworICAgIG9mZnNldCA9IHN0cmluZ2xpYl9maW5kKHNlbGZfcywgc2VsZl9sZW4sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgZnJvbV9zLCBmcm9tX2xlbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAwKTsKKyAgICBpZiAob2Zmc2V0ID09IC0xKSB7CisgICAgICAgIC8qIE5vIG1hdGNoZXM7IHJldHVybiB0aGUgb3JpZ2luYWwgYnl0ZXMgKi8KKyAgICAgICAgcmV0dXJuIHJldHVybl9zZWxmKHNlbGYpOworICAgIH0KKworICAgIC8qIE5lZWQgdG8gbWFrZSBhIG5ldyBieXRlcyAqLworICAgIHJlc3VsdCA9IChQeUJ5dGVBcnJheU9iamVjdCAqKSBQeUJ5dGVBcnJheV9Gcm9tU3RyaW5nQW5kU2l6ZShOVUxMLCBzZWxmX2xlbik7CisgICAgaWYgKHJlc3VsdCA9PSBOVUxMKQorICAgICAgICByZXR1cm4gTlVMTDsKKyAgICByZXN1bHRfcyA9IFB5Qnl0ZUFycmF5X0FTX1NUUklORyhyZXN1bHQpOworICAgIFB5X01FTUNQWShyZXN1bHRfcywgc2VsZl9zLCBzZWxmX2xlbik7CisKKyAgICAvKiBjaGFuZ2UgZXZlcnl0aGluZyBpbi1wbGFjZSwgc3RhcnRpbmcgd2l0aCB0aGlzIG9uZSAqLworICAgIHN0YXJ0ID0gIHJlc3VsdF9zICsgb2Zmc2V0OworICAgIFB5X01FTUNQWShzdGFydCwgdG9fcywgZnJvbV9sZW4pOworICAgIHN0YXJ0ICs9IGZyb21fbGVuOworICAgIGVuZCA9IHJlc3VsdF9zICsgc2VsZl9sZW47CisKKyAgICB3aGlsZSAoIC0tbWF4Y291bnQgPiAwKSB7CisgICAgICAgIG9mZnNldCA9IHN0cmluZ2xpYl9maW5kKHN0YXJ0LCBlbmQtc3RhcnQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZyb21fcywgZnJvbV9sZW4sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDApOworICAgICAgICBpZiAob2Zmc2V0PT0tMSkKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICBQeV9NRU1DUFkoc3RhcnQrb2Zmc2V0LCB0b19zLCBmcm9tX2xlbik7CisgICAgICAgIHN0YXJ0ICs9IG9mZnNldCtmcm9tX2xlbjsKKyAgICB9CisKKyAgICByZXR1cm4gcmVzdWx0OworfQorCisvKiBsZW4oc2VsZik+PTEsIGxlbihmcm9tKT09MSwgbGVuKHRvKT49MiwgbWF4Y291bnQ+PTEgKi8KK1B5X0xPQ0FMKFB5Qnl0ZUFycmF5T2JqZWN0ICopCityZXBsYWNlX3NpbmdsZV9jaGFyYWN0ZXIoUHlCeXRlQXJyYXlPYmplY3QgKnNlbGYsCisgICAgICAgICAgICAgICAgICAgICAgICAgY2hhciBmcm9tX2MsCisgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciAqdG9fcywgUHlfc3NpemVfdCB0b19sZW4sCisgICAgICAgICAgICAgICAgICAgICAgICAgUHlfc3NpemVfdCBtYXhjb3VudCkKK3sKKyAgICBjaGFyICpzZWxmX3MsICpyZXN1bHRfczsKKyAgICBjaGFyICpzdGFydCwgKm5leHQsICplbmQ7CisgICAgUHlfc3NpemVfdCBzZWxmX2xlbiwgcmVzdWx0X2xlbjsKKyAgICBQeV9zc2l6ZV90IGNvdW50LCBwcm9kdWN0OworICAgIFB5Qnl0ZUFycmF5T2JqZWN0ICpyZXN1bHQ7CisKKyAgICBzZWxmX3MgPSBQeUJ5dGVBcnJheV9BU19TVFJJTkcoc2VsZik7CisgICAgc2VsZl9sZW4gPSBQeUJ5dGVBcnJheV9HRVRfU0laRShzZWxmKTsKKworICAgIGNvdW50ID0gY291bnRjaGFyKHNlbGZfcywgc2VsZl9sZW4sIGZyb21fYywgbWF4Y291bnQpOworICAgIGlmIChjb3VudCA9PSAwKSB7CisgICAgICAgIC8qIG5vIG1hdGNoZXMsIHJldHVybiB1bmNoYW5nZWQgKi8KKyAgICAgICAgcmV0dXJuIHJldHVybl9zZWxmKHNlbGYpOworICAgIH0KKworICAgIC8qIHVzZSB0aGUgZGlmZmVyZW5jZSBiZXR3ZWVuIGN1cnJlbnQgYW5kIG5ldywgaGVuY2UgdGhlICItMSIgKi8KKyAgICAvKiAgIHJlc3VsdF9sZW4gPSBzZWxmX2xlbiArIGNvdW50ICogKHRvX2xlbi0xKSAgKi8KKyAgICBwcm9kdWN0ID0gY291bnQgKiAodG9fbGVuLTEpOworICAgIGlmIChwcm9kdWN0IC8gKHRvX2xlbi0xKSAhPSBjb3VudCkgeworICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfT3ZlcmZsb3dFcnJvciwgInJlcGxhY2UgYnl0ZXMgaXMgdG9vIGxvbmciKTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIHJlc3VsdF9sZW4gPSBzZWxmX2xlbiArIHByb2R1Y3Q7CisgICAgaWYgKHJlc3VsdF9sZW4gPCAwKSB7CisgICAgICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfT3ZlcmZsb3dFcnJvciwgInJlcGxhY2UgYnl0ZXMgaXMgdG9vIGxvbmciKTsKKyAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKworICAgIGlmICggKHJlc3VsdCA9IChQeUJ5dGVBcnJheU9iamVjdCAqKQorICAgICAgICAgIFB5Qnl0ZUFycmF5X0Zyb21TdHJpbmdBbmRTaXplKE5VTEwsIHJlc3VsdF9sZW4pKSA9PSBOVUxMKQorICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgcmVzdWx0X3MgPSBQeUJ5dGVBcnJheV9BU19TVFJJTkcocmVzdWx0KTsKKworICAgIHN0YXJ0ID0gc2VsZl9zOworICAgIGVuZCA9IHNlbGZfcyArIHNlbGZfbGVuOworICAgIHdoaWxlIChjb3VudC0tID4gMCkgeworICAgICAgICBuZXh0ID0gZmluZGNoYXIoc3RhcnQsIGVuZC1zdGFydCwgZnJvbV9jKTsKKyAgICAgICAgaWYgKG5leHQgPT0gTlVMTCkKKyAgICAgICAgICAgIGJyZWFrOworCisgICAgICAgIGlmIChuZXh0ID09IHN0YXJ0KSB7CisgICAgICAgICAgICAvKiByZXBsYWNlIHdpdGggdGhlICd0bycgKi8KKyAgICAgICAgICAgIFB5X01FTUNQWShyZXN1bHRfcywgdG9fcywgdG9fbGVuKTsKKyAgICAgICAgICAgIHJlc3VsdF9zICs9IHRvX2xlbjsKKyAgICAgICAgICAgIHN0YXJ0ICs9IDE7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAvKiBjb3B5IHRoZSB1bmNoYW5nZWQgb2xkIHRoZW4gdGhlICd0bycgKi8KKyAgICAgICAgICAgIFB5X01FTUNQWShyZXN1bHRfcywgc3RhcnQsIG5leHQtc3RhcnQpOworICAgICAgICAgICAgcmVzdWx0X3MgKz0gKG5leHQtc3RhcnQpOworICAgICAgICAgICAgUHlfTUVNQ1BZKHJlc3VsdF9zLCB0b19zLCB0b19sZW4pOworICAgICAgICAgICAgcmVzdWx0X3MgKz0gdG9fbGVuOworICAgICAgICAgICAgc3RhcnQgPSBuZXh0KzE7CisgICAgICAgIH0KKyAgICB9CisgICAgLyogQ29weSB0aGUgcmVtYWluZGVyIG9mIHRoZSByZW1haW5pbmcgYnl0ZXMgKi8KKyAgICBQeV9NRU1DUFkocmVzdWx0X3MsIHN0YXJ0LCBlbmQtc3RhcnQpOworCisgICAgcmV0dXJuIHJlc3VsdDsKK30KKworLyogbGVuKHNlbGYpPj0xLCBsZW4oZnJvbSk+PTIsIGxlbih0byk+PTIsIG1heGNvdW50Pj0xICovCitQeV9MT0NBTChQeUJ5dGVBcnJheU9iamVjdCAqKQorcmVwbGFjZV9zdWJzdHJpbmcoUHlCeXRlQXJyYXlPYmplY3QgKnNlbGYsCisgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyICpmcm9tX3MsIFB5X3NzaXplX3QgZnJvbV9sZW4sCisgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyICp0b19zLCBQeV9zc2l6ZV90IHRvX2xlbiwKKyAgICAgICAgICAgICAgICAgIFB5X3NzaXplX3QgbWF4Y291bnQpCit7CisgICAgY2hhciAqc2VsZl9zLCAqcmVzdWx0X3M7CisgICAgY2hhciAqc3RhcnQsICpuZXh0LCAqZW5kOworICAgIFB5X3NzaXplX3Qgc2VsZl9sZW4sIHJlc3VsdF9sZW47CisgICAgUHlfc3NpemVfdCBjb3VudCwgb2Zmc2V0LCBwcm9kdWN0OworICAgIFB5Qnl0ZUFycmF5T2JqZWN0ICpyZXN1bHQ7CisKKyAgICBzZWxmX3MgPSBQeUJ5dGVBcnJheV9BU19TVFJJTkcoc2VsZik7CisgICAgc2VsZl9sZW4gPSBQeUJ5dGVBcnJheV9HRVRfU0laRShzZWxmKTsKKworICAgIGNvdW50ID0gc3RyaW5nbGliX2NvdW50KHNlbGZfcywgc2VsZl9sZW4sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgZnJvbV9zLCBmcm9tX2xlbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXhjb3VudCk7CisKKyAgICBpZiAoY291bnQgPT0gMCkgeworICAgICAgICAvKiBubyBtYXRjaGVzLCByZXR1cm4gdW5jaGFuZ2VkICovCisgICAgICAgIHJldHVybiByZXR1cm5fc2VsZihzZWxmKTsKKyAgICB9CisKKyAgICAvKiBDaGVjayBmb3Igb3ZlcmZsb3cgKi8KKyAgICAvKiAgICByZXN1bHRfbGVuID0gc2VsZl9sZW4gKyBjb3VudCAqICh0b19sZW4tZnJvbV9sZW4pICovCisgICAgcHJvZHVjdCA9IGNvdW50ICogKHRvX2xlbi1mcm9tX2xlbik7CisgICAgaWYgKHByb2R1Y3QgLyAodG9fbGVuLWZyb21fbGVuKSAhPSBjb3VudCkgeworICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfT3ZlcmZsb3dFcnJvciwgInJlcGxhY2UgYnl0ZXMgaXMgdG9vIGxvbmciKTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIHJlc3VsdF9sZW4gPSBzZWxmX2xlbiArIHByb2R1Y3Q7CisgICAgaWYgKHJlc3VsdF9sZW4gPCAwKSB7CisgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19PdmVyZmxvd0Vycm9yLCAicmVwbGFjZSBieXRlcyBpcyB0b28gbG9uZyIpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisKKyAgICBpZiAoIChyZXN1bHQgPSAoUHlCeXRlQXJyYXlPYmplY3QgKikKKyAgICAgICAgICBQeUJ5dGVBcnJheV9Gcm9tU3RyaW5nQW5kU2l6ZShOVUxMLCByZXN1bHRfbGVuKSkgPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgcmVzdWx0X3MgPSBQeUJ5dGVBcnJheV9BU19TVFJJTkcocmVzdWx0KTsKKworICAgIHN0YXJ0ID0gc2VsZl9zOworICAgIGVuZCA9IHNlbGZfcyArIHNlbGZfbGVuOworICAgIHdoaWxlIChjb3VudC0tID4gMCkgeworICAgICAgICBvZmZzZXQgPSBzdHJpbmdsaWJfZmluZChzdGFydCwgZW5kLXN0YXJ0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmcm9tX3MsIGZyb21fbGVuLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwKTsKKyAgICAgICAgaWYgKG9mZnNldCA9PSAtMSkKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICBuZXh0ID0gc3RhcnQrb2Zmc2V0OworICAgICAgICBpZiAobmV4dCA9PSBzdGFydCkgeworICAgICAgICAgICAgLyogcmVwbGFjZSB3aXRoIHRoZSAndG8nICovCisgICAgICAgICAgICBQeV9NRU1DUFkocmVzdWx0X3MsIHRvX3MsIHRvX2xlbik7CisgICAgICAgICAgICByZXN1bHRfcyArPSB0b19sZW47CisgICAgICAgICAgICBzdGFydCArPSBmcm9tX2xlbjsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIC8qIGNvcHkgdGhlIHVuY2hhbmdlZCBvbGQgdGhlbiB0aGUgJ3RvJyAqLworICAgICAgICAgICAgUHlfTUVNQ1BZKHJlc3VsdF9zLCBzdGFydCwgbmV4dC1zdGFydCk7CisgICAgICAgICAgICByZXN1bHRfcyArPSAobmV4dC1zdGFydCk7CisgICAgICAgICAgICBQeV9NRU1DUFkocmVzdWx0X3MsIHRvX3MsIHRvX2xlbik7CisgICAgICAgICAgICByZXN1bHRfcyArPSB0b19sZW47CisgICAgICAgICAgICBzdGFydCA9IG5leHQrZnJvbV9sZW47CisgICAgICAgIH0KKyAgICB9CisgICAgLyogQ29weSB0aGUgcmVtYWluZGVyIG9mIHRoZSByZW1haW5pbmcgYnl0ZXMgKi8KKyAgICBQeV9NRU1DUFkocmVzdWx0X3MsIHN0YXJ0LCBlbmQtc3RhcnQpOworCisgICAgcmV0dXJuIHJlc3VsdDsKK30KKworCitQeV9MT0NBTChQeUJ5dGVBcnJheU9iamVjdCAqKQorcmVwbGFjZShQeUJ5dGVBcnJheU9iamVjdCAqc2VsZiwKKyAgICAgICAgY29uc3QgY2hhciAqZnJvbV9zLCBQeV9zc2l6ZV90IGZyb21fbGVuLAorICAgICAgICBjb25zdCBjaGFyICp0b19zLCBQeV9zc2l6ZV90IHRvX2xlbiwKKyAgICAgICAgUHlfc3NpemVfdCBtYXhjb3VudCkKK3sKKyAgICBpZiAobWF4Y291bnQgPCAwKSB7CisgICAgICAgIG1heGNvdW50ID0gUFlfU1NJWkVfVF9NQVg7CisgICAgfSBlbHNlIGlmIChtYXhjb3VudCA9PSAwIHx8IFB5Qnl0ZUFycmF5X0dFVF9TSVpFKHNlbGYpID09IDApIHsKKyAgICAgICAgLyogbm90aGluZyB0byBkbzsgcmV0dXJuIHRoZSBvcmlnaW5hbCBieXRlcyAqLworICAgICAgICByZXR1cm4gcmV0dXJuX3NlbGYoc2VsZik7CisgICAgfQorCisgICAgaWYgKG1heGNvdW50ID09IDAgfHwKKyAgICAgICAgKGZyb21fbGVuID09IDAgJiYgdG9fbGVuID09IDApKSB7CisgICAgICAgIC8qIG5vdGhpbmcgdG8gZG87IHJldHVybiB0aGUgb3JpZ2luYWwgYnl0ZXMgKi8KKyAgICAgICAgcmV0dXJuIHJldHVybl9zZWxmKHNlbGYpOworICAgIH0KKworICAgIC8qIEhhbmRsZSB6ZXJvLWxlbmd0aCBzcGVjaWFsIGNhc2VzICovCisKKyAgICBpZiAoZnJvbV9sZW4gPT0gMCkgeworICAgICAgICAvKiBpbnNlcnQgdGhlICd0bycgYnl0ZXMgZXZlcnl3aGVyZS4gICAqLworICAgICAgICAvKiAgICA+Pj4gIlB5dGhvbiIucmVwbGFjZSgiIiwgIi4iKSAgICAgKi8KKyAgICAgICAgLyogICAgJy5QLnkudC5oLm8ubi4nICAgICAgICAgICAgICAgICAgICovCisgICAgICAgIHJldHVybiByZXBsYWNlX2ludGVybGVhdmUoc2VsZiwgdG9fcywgdG9fbGVuLCBtYXhjb3VudCk7CisgICAgfQorCisgICAgLyogRXhjZXB0IGZvciAiIi5yZXBsYWNlKCIiLCAiQSIpID09ICJBIiB0aGVyZSBpcyBubyB3YXkgYmV5b25kIHRoaXMgKi8KKyAgICAvKiBwb2ludCBmb3IgYW4gZW1wdHkgc2VsZiBieXRlcyB0byBnZW5lcmF0ZSBhIG5vbi1lbXB0eSBieXRlcyAqLworICAgIC8qIFNwZWNpYWwgY2FzZSBzbyB0aGUgcmVtYWluaW5nIGNvZGUgYWx3YXlzIGdldHMgYSBub24tZW1wdHkgYnl0ZXMgKi8KKyAgICBpZiAoUHlCeXRlQXJyYXlfR0VUX1NJWkUoc2VsZikgPT0gMCkgeworICAgICAgICByZXR1cm4gcmV0dXJuX3NlbGYoc2VsZik7CisgICAgfQorCisgICAgaWYgKHRvX2xlbiA9PSAwKSB7CisgICAgICAgIC8qIGRlbGV0ZSBhbGwgb2NjdXJhbmNlcyBvZiAnZnJvbScgYnl0ZXMgKi8KKyAgICAgICAgaWYgKGZyb21fbGVuID09IDEpIHsKKyAgICAgICAgICAgIHJldHVybiByZXBsYWNlX2RlbGV0ZV9zaW5nbGVfY2hhcmFjdGVyKAorICAgICAgICAgICAgICAgICAgICBzZWxmLCBmcm9tX3NbMF0sIG1heGNvdW50KTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHJldHVybiByZXBsYWNlX2RlbGV0ZV9zdWJzdHJpbmcoc2VsZiwgZnJvbV9zLCBmcm9tX2xlbiwgbWF4Y291bnQpOworICAgICAgICB9CisgICAgfQorCisgICAgLyogSGFuZGxlIHNwZWNpYWwgY2FzZSB3aGVyZSBib3RoIGJ5dGVzIGhhdmUgdGhlIHNhbWUgbGVuZ3RoICovCisKKyAgICBpZiAoZnJvbV9sZW4gPT0gdG9fbGVuKSB7CisgICAgICAgIGlmIChmcm9tX2xlbiA9PSAxKSB7CisgICAgICAgICAgICByZXR1cm4gcmVwbGFjZV9zaW5nbGVfY2hhcmFjdGVyX2luX3BsYWNlKAorICAgICAgICAgICAgICAgICAgICBzZWxmLAorICAgICAgICAgICAgICAgICAgICBmcm9tX3NbMF0sCisgICAgICAgICAgICAgICAgICAgIHRvX3NbMF0sCisgICAgICAgICAgICAgICAgICAgIG1heGNvdW50KTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHJldHVybiByZXBsYWNlX3N1YnN0cmluZ19pbl9wbGFjZSgKKyAgICAgICAgICAgICAgICBzZWxmLCBmcm9tX3MsIGZyb21fbGVuLCB0b19zLCB0b19sZW4sIG1heGNvdW50KTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qIE90aGVyd2lzZSB1c2UgdGhlIG1vcmUgZ2VuZXJpYyBhbGdvcml0aG1zICovCisgICAgaWYgKGZyb21fbGVuID09IDEpIHsKKyAgICAgICAgcmV0dXJuIHJlcGxhY2Vfc2luZ2xlX2NoYXJhY3RlcihzZWxmLCBmcm9tX3NbMF0sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG9fcywgdG9fbGVuLCBtYXhjb3VudCk7CisgICAgfSBlbHNlIHsKKyAgICAgICAgLyogbGVuKCdmcm9tJyk+PTIsIGxlbigndG8nKT49MSAqLworICAgICAgICByZXR1cm4gcmVwbGFjZV9zdWJzdHJpbmcoc2VsZiwgZnJvbV9zLCBmcm9tX2xlbiwgdG9fcywgdG9fbGVuLCBtYXhjb3VudCk7CisgICAgfQorfQorCisKK1B5RG9jX1NUUlZBUihyZXBsYWNlX19kb2NfXywKKyJCLnJlcGxhY2Uob2xkLCBuZXdbLCBjb3VudF0pIC0+IGJ5dGVzXG5cCitcblwKK1JldHVybiBhIGNvcHkgb2YgQiB3aXRoIGFsbCBvY2N1cnJlbmNlcyBvZiBzdWJzZWN0aW9uXG5cCitvbGQgcmVwbGFjZWQgYnkgbmV3LiAgSWYgdGhlIG9wdGlvbmFsIGFyZ3VtZW50IGNvdW50IGlzXG5cCitnaXZlbiwgb25seSB0aGUgZmlyc3QgY291bnQgb2NjdXJyZW5jZXMgYXJlIHJlcGxhY2VkLiIpOworCitzdGF0aWMgUHlPYmplY3QgKgorYnl0ZWFycmF5X3JlcGxhY2UoUHlCeXRlQXJyYXlPYmplY3QgKnNlbGYsIFB5T2JqZWN0ICphcmdzKQoreworICAgIFB5X3NzaXplX3QgY291bnQgPSAtMTsKKyAgICBQeU9iamVjdCAqZnJvbSwgKnRvLCAqcmVzOworICAgIFB5X2J1ZmZlciB2ZnJvbSwgdnRvOworCisgICAgaWYgKCFQeUFyZ19QYXJzZVR1cGxlKGFyZ3MsICJPT3xuOnJlcGxhY2UiLCAmZnJvbSwgJnRvLCAmY291bnQpKQorICAgICAgICByZXR1cm4gTlVMTDsKKworICAgIGlmIChfZ2V0YnVmZmVyKGZyb20sICZ2ZnJvbSkgPCAwKQorICAgICAgICByZXR1cm4gTlVMTDsKKyAgICBpZiAoX2dldGJ1ZmZlcih0bywgJnZ0bykgPCAwKSB7CisgICAgICAgIFB5QnVmZmVyX1JlbGVhc2UoJnZmcm9tKTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorCisgICAgcmVzID0gKFB5T2JqZWN0ICopcmVwbGFjZSgoUHlCeXRlQXJyYXlPYmplY3QgKikgc2VsZiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZmcm9tLmJ1ZiwgdmZyb20ubGVuLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdnRvLmJ1ZiwgdnRvLmxlbiwgY291bnQpOworCisgICAgUHlCdWZmZXJfUmVsZWFzZSgmdmZyb20pOworICAgIFB5QnVmZmVyX1JlbGVhc2UoJnZ0byk7CisgICAgcmV0dXJuIHJlczsKK30KKworUHlEb2NfU1RSVkFSKHNwbGl0X19kb2NfXywKKyJCLnNwbGl0KFtzZXBbLCBtYXhzcGxpdF1dKSAtPiBsaXN0IG9mIGJ5dGVhcnJheVxuXAorXG5cCitSZXR1cm4gYSBsaXN0IG9mIHRoZSBzZWN0aW9ucyBpbiBCLCB1c2luZyBzZXAgYXMgdGhlIGRlbGltaXRlci5cblwKK0lmIHNlcCBpcyBub3QgZ2l2ZW4sIEIgaXMgc3BsaXQgb24gQVNDSUkgd2hpdGVzcGFjZSBjaGFyYWN0ZXJzXG5cCisoc3BhY2UsIHRhYiwgcmV0dXJuLCBuZXdsaW5lLCBmb3JtZmVlZCwgdmVydGljYWwgdGFiKS5cblwKK0lmIG1heHNwbGl0IGlzIGdpdmVuLCBhdCBtb3N0IG1heHNwbGl0IHNwbGl0cyBhcmUgZG9uZS4iKTsKKworc3RhdGljIFB5T2JqZWN0ICoKK2J5dGVhcnJheV9zcGxpdChQeUJ5dGVBcnJheU9iamVjdCAqc2VsZiwgUHlPYmplY3QgKmFyZ3MpCit7CisgICAgUHlfc3NpemVfdCBsZW4gPSBQeUJ5dGVBcnJheV9HRVRfU0laRShzZWxmKSwgbjsKKyAgICBQeV9zc2l6ZV90IG1heHNwbGl0ID0gLTE7CisgICAgY29uc3QgY2hhciAqcyA9IFB5Qnl0ZUFycmF5X0FTX1NUUklORyhzZWxmKSwgKnN1YjsKKyAgICBQeU9iamVjdCAqbGlzdCwgKnN1Ym9iaiA9IFB5X05vbmU7CisgICAgUHlfYnVmZmVyIHZzdWI7CisKKyAgICBpZiAoIVB5QXJnX1BhcnNlVHVwbGUoYXJncywgInxPbjpzcGxpdCIsICZzdWJvYmosICZtYXhzcGxpdCkpCisgICAgICAgIHJldHVybiBOVUxMOworICAgIGlmIChtYXhzcGxpdCA8IDApCisgICAgICAgIG1heHNwbGl0ID0gUFlfU1NJWkVfVF9NQVg7CisKKyAgICBpZiAoc3Vib2JqID09IFB5X05vbmUpCisgICAgICAgIHJldHVybiBzdHJpbmdsaWJfc3BsaXRfd2hpdGVzcGFjZSgoUHlPYmplY3QqKSBzZWxmLCBzLCBsZW4sIG1heHNwbGl0KTsKKworICAgIGlmIChfZ2V0YnVmZmVyKHN1Ym9iaiwgJnZzdWIpIDwgMCkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgc3ViID0gdnN1Yi5idWY7CisgICAgbiA9IHZzdWIubGVuOworCisgICAgbGlzdCA9IHN0cmluZ2xpYl9zcGxpdCgKKyAgICAgICAgKFB5T2JqZWN0Kikgc2VsZiwgcywgbGVuLCBzdWIsIG4sIG1heHNwbGl0CisgICAgICAgICk7CisgICAgUHlCdWZmZXJfUmVsZWFzZSgmdnN1Yik7CisgICAgcmV0dXJuIGxpc3Q7Cit9CisKK1B5RG9jX1NUUlZBUihwYXJ0aXRpb25fX2RvY19fLAorIkIucGFydGl0aW9uKHNlcCkgLT4gKGhlYWQsIHNlcCwgdGFpbClcblwKK1xuXAorU2VhcmNoZXMgZm9yIHRoZSBzZXBhcmF0b3Igc2VwIGluIEIsIGFuZCByZXR1cm5zIHRoZSBwYXJ0IGJlZm9yZSBpdCxcblwKK3RoZSBzZXBhcmF0b3IgaXRzZWxmLCBhbmQgdGhlIHBhcnQgYWZ0ZXIgaXQuICBJZiB0aGUgc2VwYXJhdG9yIGlzIG5vdFxuXAorZm91bmQsIHJldHVybnMgQiBhbmQgdHdvIGVtcHR5IGJ5dGVhcnJheSBvYmplY3RzLiIpOworCitzdGF0aWMgUHlPYmplY3QgKgorYnl0ZWFycmF5X3BhcnRpdGlvbihQeUJ5dGVBcnJheU9iamVjdCAqc2VsZiwgUHlPYmplY3QgKnNlcF9vYmopCit7CisgICAgUHlPYmplY3QgKmJ5dGVzZXAsICpyZXN1bHQ7CisKKyAgICBieXRlc2VwID0gUHlCeXRlQXJyYXlfRnJvbU9iamVjdChzZXBfb2JqKTsKKyAgICBpZiAoISBieXRlc2VwKQorICAgICAgICByZXR1cm4gTlVMTDsKKworICAgIHJlc3VsdCA9IHN0cmluZ2xpYl9wYXJ0aXRpb24oCisgICAgICAgICAgICAoUHlPYmplY3QqKSBzZWxmLAorICAgICAgICAgICAgUHlCeXRlQXJyYXlfQVNfU1RSSU5HKHNlbGYpLCBQeUJ5dGVBcnJheV9HRVRfU0laRShzZWxmKSwKKyAgICAgICAgICAgIGJ5dGVzZXAsCisgICAgICAgICAgICBQeUJ5dGVBcnJheV9BU19TVFJJTkcoYnl0ZXNlcCksIFB5Qnl0ZUFycmF5X0dFVF9TSVpFKGJ5dGVzZXApCisgICAgICAgICAgICApOworCisgICAgUHlfREVDUkVGKGJ5dGVzZXApOworICAgIHJldHVybiByZXN1bHQ7Cit9CisKK1B5RG9jX1NUUlZBUihycGFydGl0aW9uX19kb2NfXywKKyJCLnJwYXJ0aXRpb24oc2VwKSAtPiAoaGVhZCwgc2VwLCB0YWlsKVxuXAorXG5cCitTZWFyY2hlcyBmb3IgdGhlIHNlcGFyYXRvciBzZXAgaW4gQiwgc3RhcnRpbmcgYXQgdGhlIGVuZCBvZiBCLFxuXAorYW5kIHJldHVybnMgdGhlIHBhcnQgYmVmb3JlIGl0LCB0aGUgc2VwYXJhdG9yIGl0c2VsZiwgYW5kIHRoZVxuXAorcGFydCBhZnRlciBpdC4gIElmIHRoZSBzZXBhcmF0b3IgaXMgbm90IGZvdW5kLCByZXR1cm5zIHR3byBlbXB0eVxuXAorYnl0ZWFycmF5IG9iamVjdHMgYW5kIEIuIik7CisKK3N0YXRpYyBQeU9iamVjdCAqCitieXRlYXJyYXlfcnBhcnRpdGlvbihQeUJ5dGVBcnJheU9iamVjdCAqc2VsZiwgUHlPYmplY3QgKnNlcF9vYmopCit7CisgICAgUHlPYmplY3QgKmJ5dGVzZXAsICpyZXN1bHQ7CisKKyAgICBieXRlc2VwID0gUHlCeXRlQXJyYXlfRnJvbU9iamVjdChzZXBfb2JqKTsKKyAgICBpZiAoISBieXRlc2VwKQorICAgICAgICByZXR1cm4gTlVMTDsKKworICAgIHJlc3VsdCA9IHN0cmluZ2xpYl9ycGFydGl0aW9uKAorICAgICAgICAgICAgKFB5T2JqZWN0Kikgc2VsZiwKKyAgICAgICAgICAgIFB5Qnl0ZUFycmF5X0FTX1NUUklORyhzZWxmKSwgUHlCeXRlQXJyYXlfR0VUX1NJWkUoc2VsZiksCisgICAgICAgICAgICBieXRlc2VwLAorICAgICAgICAgICAgUHlCeXRlQXJyYXlfQVNfU1RSSU5HKGJ5dGVzZXApLCBQeUJ5dGVBcnJheV9HRVRfU0laRShieXRlc2VwKQorICAgICAgICAgICAgKTsKKworICAgIFB5X0RFQ1JFRihieXRlc2VwKTsKKyAgICByZXR1cm4gcmVzdWx0OworfQorCitQeURvY19TVFJWQVIocnNwbGl0X19kb2NfXywKKyJCLnJzcGxpdChzZXBbLCBtYXhzcGxpdF0pIC0+IGxpc3Qgb2YgYnl0ZWFycmF5XG5cCitcblwKK1JldHVybiBhIGxpc3Qgb2YgdGhlIHNlY3Rpb25zIGluIEIsIHVzaW5nIHNlcCBhcyB0aGUgZGVsaW1pdGVyLFxuXAorc3RhcnRpbmcgYXQgdGhlIGVuZCBvZiBCIGFuZCB3b3JraW5nIHRvIHRoZSBmcm9udC5cblwKK0lmIHNlcCBpcyBub3QgZ2l2ZW4sIEIgaXMgc3BsaXQgb24gQVNDSUkgd2hpdGVzcGFjZSBjaGFyYWN0ZXJzXG5cCisoc3BhY2UsIHRhYiwgcmV0dXJuLCBuZXdsaW5lLCBmb3JtZmVlZCwgdmVydGljYWwgdGFiKS5cblwKK0lmIG1heHNwbGl0IGlzIGdpdmVuLCBhdCBtb3N0IG1heHNwbGl0IHNwbGl0cyBhcmUgZG9uZS4iKTsKKworc3RhdGljIFB5T2JqZWN0ICoKK2J5dGVhcnJheV9yc3BsaXQoUHlCeXRlQXJyYXlPYmplY3QgKnNlbGYsIFB5T2JqZWN0ICphcmdzKQoreworICAgIFB5X3NzaXplX3QgbGVuID0gUHlCeXRlQXJyYXlfR0VUX1NJWkUoc2VsZiksIG47CisgICAgUHlfc3NpemVfdCBtYXhzcGxpdCA9IC0xOworICAgIGNvbnN0IGNoYXIgKnMgPSBQeUJ5dGVBcnJheV9BU19TVFJJTkcoc2VsZiksICpzdWI7CisgICAgUHlPYmplY3QgKmxpc3QsICpzdWJvYmogPSBQeV9Ob25lOworICAgIFB5X2J1ZmZlciB2c3ViOworCisgICAgaWYgKCFQeUFyZ19QYXJzZVR1cGxlKGFyZ3MsICJ8T246cnNwbGl0IiwgJnN1Ym9iaiwgJm1heHNwbGl0KSkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgaWYgKG1heHNwbGl0IDwgMCkKKyAgICAgICAgbWF4c3BsaXQgPSBQWV9TU0laRV9UX01BWDsKKworICAgIGlmIChzdWJvYmogPT0gUHlfTm9uZSkKKyAgICAgICAgcmV0dXJuIHN0cmluZ2xpYl9yc3BsaXRfd2hpdGVzcGFjZSgoUHlPYmplY3QqKSBzZWxmLCBzLCBsZW4sIG1heHNwbGl0KTsKKworICAgIGlmIChfZ2V0YnVmZmVyKHN1Ym9iaiwgJnZzdWIpIDwgMCkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgc3ViID0gdnN1Yi5idWY7CisgICAgbiA9IHZzdWIubGVuOworCisgICAgbGlzdCA9IHN0cmluZ2xpYl9yc3BsaXQoCisgICAgICAgIChQeU9iamVjdCopIHNlbGYsIHMsIGxlbiwgc3ViLCBuLCBtYXhzcGxpdAorICAgICAgICApOworICAgIFB5QnVmZmVyX1JlbGVhc2UoJnZzdWIpOworICAgIHJldHVybiBsaXN0OworfQorCitQeURvY19TVFJWQVIocmV2ZXJzZV9fZG9jX18sCisiQi5yZXZlcnNlKCkgLT4gTm9uZVxuXAorXG5cCitSZXZlcnNlIHRoZSBvcmRlciBvZiB0aGUgdmFsdWVzIGluIEIgaW4gcGxhY2UuIik7CitzdGF0aWMgUHlPYmplY3QgKgorYnl0ZWFycmF5X3JldmVyc2UoUHlCeXRlQXJyYXlPYmplY3QgKnNlbGYsIFB5T2JqZWN0ICp1bnVzZWQpCit7CisgICAgY2hhciBzd2FwLCAqaGVhZCwgKnRhaWw7CisgICAgUHlfc3NpemVfdCBpLCBqLCBuID0gUHlfU0laRShzZWxmKTsKKworICAgIGogPSBuIC8gMjsKKyAgICBoZWFkID0gc2VsZi0+b2JfYnl0ZXM7CisgICAgdGFpbCA9IGhlYWQgKyBuIC0gMTsKKyAgICBmb3IgKGkgPSAwOyBpIDwgajsgaSsrKSB7CisgICAgICAgIHN3YXAgPSAqaGVhZDsKKyAgICAgICAgKmhlYWQrKyA9ICp0YWlsOworICAgICAgICAqdGFpbC0tID0gc3dhcDsKKyAgICB9CisKKyAgICBQeV9SRVRVUk5fTk9ORTsKK30KKworUHlEb2NfU1RSVkFSKGluc2VydF9fZG9jX18sCisiQi5pbnNlcnQoaW5kZXgsIGludCkgLT4gTm9uZVxuXAorXG5cCitJbnNlcnQgYSBzaW5nbGUgaXRlbSBpbnRvIHRoZSBieXRlYXJyYXkgYmVmb3JlIHRoZSBnaXZlbiBpbmRleC4iKTsKK3N0YXRpYyBQeU9iamVjdCAqCitieXRlYXJyYXlfaW5zZXJ0KFB5Qnl0ZUFycmF5T2JqZWN0ICpzZWxmLCBQeU9iamVjdCAqYXJncykKK3sKKyAgICBQeU9iamVjdCAqdmFsdWU7CisgICAgaW50IGl2YWw7CisgICAgUHlfc3NpemVfdCB3aGVyZSwgbiA9IFB5X1NJWkUoc2VsZik7CisKKyAgICBpZiAoIVB5QXJnX1BhcnNlVHVwbGUoYXJncywgIm5POmluc2VydCIsICZ3aGVyZSwgJnZhbHVlKSkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisKKyAgICBpZiAobiA9PSBQWV9TU0laRV9UX01BWCkgeworICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfT3ZlcmZsb3dFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICJjYW5ub3QgYWRkIG1vcmUgb2JqZWN0cyB0byBieXRlYXJyYXkiKTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIGlmICghX2dldGJ5dGV2YWx1ZSh2YWx1ZSwgJml2YWwpKQorICAgICAgICByZXR1cm4gTlVMTDsKKyAgICBpZiAoUHlCeXRlQXJyYXlfUmVzaXplKChQeU9iamVjdCAqKXNlbGYsIG4gKyAxKSA8IDApCisgICAgICAgIHJldHVybiBOVUxMOworCisgICAgaWYgKHdoZXJlIDwgMCkgeworICAgICAgICB3aGVyZSArPSBuOworICAgICAgICBpZiAod2hlcmUgPCAwKQorICAgICAgICAgICAgd2hlcmUgPSAwOworICAgIH0KKyAgICBpZiAod2hlcmUgPiBuKQorICAgICAgICB3aGVyZSA9IG47CisgICAgbWVtbW92ZShzZWxmLT5vYl9ieXRlcyArIHdoZXJlICsgMSwgc2VsZi0+b2JfYnl0ZXMgKyB3aGVyZSwgbiAtIHdoZXJlKTsKKyAgICBzZWxmLT5vYl9ieXRlc1t3aGVyZV0gPSBpdmFsOworCisgICAgUHlfUkVUVVJOX05PTkU7Cit9CisKK1B5RG9jX1NUUlZBUihhcHBlbmRfX2RvY19fLAorIkIuYXBwZW5kKGludCkgLT4gTm9uZVxuXAorXG5cCitBcHBlbmQgYSBzaW5nbGUgaXRlbSB0byB0aGUgZW5kIG9mIEIuIik7CitzdGF0aWMgUHlPYmplY3QgKgorYnl0ZWFycmF5X2FwcGVuZChQeUJ5dGVBcnJheU9iamVjdCAqc2VsZiwgUHlPYmplY3QgKmFyZykKK3sKKyAgICBpbnQgdmFsdWU7CisgICAgUHlfc3NpemVfdCBuID0gUHlfU0laRShzZWxmKTsKKworICAgIGlmICghIF9nZXRieXRldmFsdWUoYXJnLCAmdmFsdWUpKQorICAgICAgICByZXR1cm4gTlVMTDsKKyAgICBpZiAobiA9PSBQWV9TU0laRV9UX01BWCkgeworICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfT3ZlcmZsb3dFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICJjYW5ub3QgYWRkIG1vcmUgb2JqZWN0cyB0byBieXRlYXJyYXkiKTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIGlmIChQeUJ5dGVBcnJheV9SZXNpemUoKFB5T2JqZWN0ICopc2VsZiwgbiArIDEpIDwgMCkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisKKyAgICBzZWxmLT5vYl9ieXRlc1tuXSA9IHZhbHVlOworCisgICAgUHlfUkVUVVJOX05PTkU7Cit9CisKK1B5RG9jX1NUUlZBUihleHRlbmRfX2RvY19fLAorIkIuZXh0ZW5kKGl0ZXJhYmxlIGludCkgLT4gTm9uZVxuXAorXG5cCitBcHBlbmQgYWxsIHRoZSBlbGVtZW50cyBmcm9tIHRoZSBpdGVyYXRvciBvciBzZXF1ZW5jZSB0byB0aGVcblwKK2VuZCBvZiBCLiIpOworc3RhdGljIFB5T2JqZWN0ICoKK2J5dGVhcnJheV9leHRlbmQoUHlCeXRlQXJyYXlPYmplY3QgKnNlbGYsIFB5T2JqZWN0ICphcmcpCit7CisgICAgUHlPYmplY3QgKml0LCAqaXRlbSwgKmJ5dGVhcnJheV9vYmo7CisgICAgUHlfc3NpemVfdCBidWZfc2l6ZSA9IDAsIGxlbiA9IDA7CisgICAgaW50IHZhbHVlOworICAgIGNoYXIgKmJ1ZjsKKworICAgIC8qIGJ5dGVhcnJheV9zZXRzbGljZSBjb2RlIG9ubHkgYWNjZXB0cyBzb21ldGhpbmcgc3VwcG9ydGluZyBQRVAgMzExOC4gKi8KKyAgICBpZiAoUHlPYmplY3RfQ2hlY2tCdWZmZXIoYXJnKSkgeworICAgICAgICBpZiAoYnl0ZWFycmF5X3NldHNsaWNlKHNlbGYsIFB5X1NJWkUoc2VsZiksIFB5X1NJWkUoc2VsZiksIGFyZykgPT0gLTEpCisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKworICAgICAgICBQeV9SRVRVUk5fTk9ORTsKKyAgICB9CisKKyAgICBpdCA9IFB5T2JqZWN0X0dldEl0ZXIoYXJnKTsKKyAgICBpZiAoaXQgPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisKKyAgICAvKiBUcnkgdG8gZGV0ZXJtaW5lIHRoZSBsZW5ndGggb2YgdGhlIGFyZ3VtZW50LiAzMiBpcyBhcmJpdHJhcnkuICovCisgICAgYnVmX3NpemUgPSBfUHlPYmplY3RfTGVuZ3RoSGludChhcmcsIDMyKTsKKyAgICBpZiAoYnVmX3NpemUgPT0gLTEpIHsKKyAgICAgICAgUHlfREVDUkVGKGl0KTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorCisgICAgYnl0ZWFycmF5X29iaiA9IFB5Qnl0ZUFycmF5X0Zyb21TdHJpbmdBbmRTaXplKE5VTEwsIGJ1Zl9zaXplKTsKKyAgICBpZiAoYnl0ZWFycmF5X29iaiA9PSBOVUxMKSB7CisgICAgICAgIFB5X0RFQ1JFRihpdCk7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICBidWYgPSBQeUJ5dGVBcnJheV9BU19TVFJJTkcoYnl0ZWFycmF5X29iaik7CisKKyAgICB3aGlsZSAoKGl0ZW0gPSBQeUl0ZXJfTmV4dChpdCkpICE9IE5VTEwpIHsKKyAgICAgICAgaWYgKCEgX2dldGJ5dGV2YWx1ZShpdGVtLCAmdmFsdWUpKSB7CisgICAgICAgICAgICBQeV9ERUNSRUYoaXRlbSk7CisgICAgICAgICAgICBQeV9ERUNSRUYoaXQpOworICAgICAgICAgICAgUHlfREVDUkVGKGJ5dGVhcnJheV9vYmopOworICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgICAgIH0KKyAgICAgICAgYnVmW2xlbisrXSA9IHZhbHVlOworICAgICAgICBQeV9ERUNSRUYoaXRlbSk7CisKKyAgICAgICAgaWYgKGxlbiA+PSBidWZfc2l6ZSkgeworICAgICAgICAgICAgYnVmX3NpemUgPSBsZW4gKyAobGVuID4+IDEpICsgMTsKKyAgICAgICAgICAgIGlmIChQeUJ5dGVBcnJheV9SZXNpemUoKFB5T2JqZWN0ICopYnl0ZWFycmF5X29iaiwgYnVmX3NpemUpIDwgMCkgeworICAgICAgICAgICAgICAgIFB5X0RFQ1JFRihpdCk7CisgICAgICAgICAgICAgICAgUHlfREVDUkVGKGJ5dGVhcnJheV9vYmopOworICAgICAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgICAgICAgICAgfQorICAgICAgICAgICAgLyogUmVjb21wdXRlIHRoZSBgYnVmJyBwb2ludGVyLCBzaW5jZSB0aGUgcmVzaXppbmcgb3BlcmF0aW9uIG1heQorICAgICAgICAgICAgICAgaGF2ZSBpbnZhbGlkYXRlZCBpdC4gKi8KKyAgICAgICAgICAgIGJ1ZiA9IFB5Qnl0ZUFycmF5X0FTX1NUUklORyhieXRlYXJyYXlfb2JqKTsKKyAgICAgICAgfQorICAgIH0KKyAgICBQeV9ERUNSRUYoaXQpOworCisgICAgLyogUmVzaXplIGRvd24gdG8gZXhhY3Qgc2l6ZS4gKi8KKyAgICBpZiAoUHlCeXRlQXJyYXlfUmVzaXplKChQeU9iamVjdCAqKWJ5dGVhcnJheV9vYmosIGxlbikgPCAwKSB7CisgICAgICAgIFB5X0RFQ1JFRihieXRlYXJyYXlfb2JqKTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorCisgICAgaWYgKGJ5dGVhcnJheV9zZXRzbGljZShzZWxmLCBQeV9TSVpFKHNlbGYpLCBQeV9TSVpFKHNlbGYpLCBieXRlYXJyYXlfb2JqKSA9PSAtMSkgeworICAgICAgICBQeV9ERUNSRUYoYnl0ZWFycmF5X29iaik7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICBQeV9ERUNSRUYoYnl0ZWFycmF5X29iaik7CisKKyAgICBQeV9SRVRVUk5fTk9ORTsKK30KKworUHlEb2NfU1RSVkFSKHBvcF9fZG9jX18sCisiQi5wb3AoW2luZGV4XSkgLT4gaW50XG5cCitcblwKK1JlbW92ZSBhbmQgcmV0dXJuIGEgc2luZ2xlIGl0ZW0gZnJvbSBCLiBJZiBubyBpbmRleFxuXAorYXJndW1lbnQgaXMgZ2l2ZW4sIHdpbGwgcG9wIHRoZSBsYXN0IHZhbHVlLiIpOworc3RhdGljIFB5T2JqZWN0ICoKK2J5dGVhcnJheV9wb3AoUHlCeXRlQXJyYXlPYmplY3QgKnNlbGYsIFB5T2JqZWN0ICphcmdzKQoreworICAgIGludCB2YWx1ZTsKKyAgICBQeV9zc2l6ZV90IHdoZXJlID0gLTEsIG4gPSBQeV9TSVpFKHNlbGYpOworCisgICAgaWYgKCFQeUFyZ19QYXJzZVR1cGxlKGFyZ3MsICJ8bjpwb3AiLCAmd2hlcmUpKQorICAgICAgICByZXR1cm4gTlVMTDsKKworICAgIGlmIChuID09IDApIHsKKyAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX0luZGV4RXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAgICAicG9wIGZyb20gZW1wdHkgYnl0ZWFycmF5Iik7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICBpZiAod2hlcmUgPCAwKQorICAgICAgICB3aGVyZSArPSBQeV9TSVpFKHNlbGYpOworICAgIGlmICh3aGVyZSA8IDAgfHwgd2hlcmUgPj0gUHlfU0laRShzZWxmKSkgeworICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfSW5kZXhFcnJvciwgInBvcCBpbmRleCBvdXQgb2YgcmFuZ2UiKTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIGlmICghX2NhbnJlc2l6ZShzZWxmKSkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisKKyAgICB2YWx1ZSA9IHNlbGYtPm9iX2J5dGVzW3doZXJlXTsKKyAgICBtZW1tb3ZlKHNlbGYtPm9iX2J5dGVzICsgd2hlcmUsIHNlbGYtPm9iX2J5dGVzICsgd2hlcmUgKyAxLCBuIC0gd2hlcmUpOworICAgIGlmIChQeUJ5dGVBcnJheV9SZXNpemUoKFB5T2JqZWN0ICopc2VsZiwgbiAtIDEpIDwgMCkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisKKyAgICByZXR1cm4gUHlJbnRfRnJvbUxvbmcoKHVuc2lnbmVkIGNoYXIpdmFsdWUpOworfQorCitQeURvY19TVFJWQVIocmVtb3ZlX19kb2NfXywKKyJCLnJlbW92ZShpbnQpIC0+IE5vbmVcblwKK1xuXAorUmVtb3ZlIHRoZSBmaXJzdCBvY2N1cmFuY2Ugb2YgYSB2YWx1ZSBpbiBCLiIpOworc3RhdGljIFB5T2JqZWN0ICoKK2J5dGVhcnJheV9yZW1vdmUoUHlCeXRlQXJyYXlPYmplY3QgKnNlbGYsIFB5T2JqZWN0ICphcmcpCit7CisgICAgaW50IHZhbHVlOworICAgIFB5X3NzaXplX3Qgd2hlcmUsIG4gPSBQeV9TSVpFKHNlbGYpOworCisgICAgaWYgKCEgX2dldGJ5dGV2YWx1ZShhcmcsICZ2YWx1ZSkpCisgICAgICAgIHJldHVybiBOVUxMOworCisgICAgZm9yICh3aGVyZSA9IDA7IHdoZXJlIDwgbjsgd2hlcmUrKykgeworICAgICAgICBpZiAoc2VsZi0+b2JfYnl0ZXNbd2hlcmVdID09IHZhbHVlKQorICAgICAgICAgICAgYnJlYWs7CisgICAgfQorICAgIGlmICh3aGVyZSA9PSBuKSB7CisgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19WYWx1ZUVycm9yLCAidmFsdWUgbm90IGZvdW5kIGluIGJ5dGVhcnJheSIpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgaWYgKCFfY2FucmVzaXplKHNlbGYpKQorICAgICAgICByZXR1cm4gTlVMTDsKKworICAgIG1lbW1vdmUoc2VsZi0+b2JfYnl0ZXMgKyB3aGVyZSwgc2VsZi0+b2JfYnl0ZXMgKyB3aGVyZSArIDEsIG4gLSB3aGVyZSk7CisgICAgaWYgKFB5Qnl0ZUFycmF5X1Jlc2l6ZSgoUHlPYmplY3QgKilzZWxmLCBuIC0gMSkgPCAwKQorICAgICAgICByZXR1cm4gTlVMTDsKKworICAgIFB5X1JFVFVSTl9OT05FOworfQorCisvKiBYWFggVGhlc2UgdHdvIGhlbHBlcnMgY291bGQgYmUgb3B0aW1pemVkIGlmIGFyZ3NpemUgPT0gMSAqLworCitzdGF0aWMgUHlfc3NpemVfdAorbHN0cmlwX2hlbHBlcih1bnNpZ25lZCBjaGFyICpteXB0ciwgUHlfc3NpemVfdCBteXNpemUsCisgICAgICAgICAgICAgIHZvaWQgKmFyZ3B0ciwgUHlfc3NpemVfdCBhcmdzaXplKQoreworICAgIFB5X3NzaXplX3QgaSA9IDA7CisgICAgd2hpbGUgKGkgPCBteXNpemUgJiYgbWVtY2hyKGFyZ3B0ciwgbXlwdHJbaV0sIGFyZ3NpemUpKQorICAgICAgICBpKys7CisgICAgcmV0dXJuIGk7Cit9CisKK3N0YXRpYyBQeV9zc2l6ZV90Cityc3RyaXBfaGVscGVyKHVuc2lnbmVkIGNoYXIgKm15cHRyLCBQeV9zc2l6ZV90IG15c2l6ZSwKKyAgICAgICAgICAgICAgdm9pZCAqYXJncHRyLCBQeV9zc2l6ZV90IGFyZ3NpemUpCit7CisgICAgUHlfc3NpemVfdCBpID0gbXlzaXplIC0gMTsKKyAgICB3aGlsZSAoaSA+PSAwICYmIG1lbWNocihhcmdwdHIsIG15cHRyW2ldLCBhcmdzaXplKSkKKyAgICAgICAgaS0tOworICAgIHJldHVybiBpICsgMTsKK30KKworUHlEb2NfU1RSVkFSKHN0cmlwX19kb2NfXywKKyJCLnN0cmlwKFtieXRlc10pIC0+IGJ5dGVhcnJheVxuXAorXG5cCitTdHJpcCBsZWFkaW5nIGFuZCB0cmFpbGluZyBieXRlcyBjb250YWluZWQgaW4gdGhlIGFyZ3VtZW50LlxuXAorSWYgdGhlIGFyZ3VtZW50IGlzIG9taXR0ZWQsIHN0cmlwIEFTQ0lJIHdoaXRlc3BhY2UuIik7CitzdGF0aWMgUHlPYmplY3QgKgorYnl0ZWFycmF5X3N0cmlwKFB5Qnl0ZUFycmF5T2JqZWN0ICpzZWxmLCBQeU9iamVjdCAqYXJncykKK3sKKyAgICBQeV9zc2l6ZV90IGxlZnQsIHJpZ2h0LCBteXNpemUsIGFyZ3NpemU7CisgICAgdm9pZCAqbXlwdHIsICphcmdwdHI7CisgICAgUHlPYmplY3QgKmFyZyA9IFB5X05vbmU7CisgICAgUHlfYnVmZmVyIHZhcmc7CisgICAgaWYgKCFQeUFyZ19QYXJzZVR1cGxlKGFyZ3MsICJ8TzpzdHJpcCIsICZhcmcpKQorICAgICAgICByZXR1cm4gTlVMTDsKKyAgICBpZiAoYXJnID09IFB5X05vbmUpIHsKKyAgICAgICAgYXJncHRyID0gIlx0XG5cclxmXHYgIjsKKyAgICAgICAgYXJnc2l6ZSA9IDY7CisgICAgfQorICAgIGVsc2UgeworICAgICAgICBpZiAoX2dldGJ1ZmZlcihhcmcsICZ2YXJnKSA8IDApCisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgYXJncHRyID0gdmFyZy5idWY7CisgICAgICAgIGFyZ3NpemUgPSB2YXJnLmxlbjsKKyAgICB9CisgICAgbXlwdHIgPSBzZWxmLT5vYl9ieXRlczsKKyAgICBteXNpemUgPSBQeV9TSVpFKHNlbGYpOworICAgIGxlZnQgPSBsc3RyaXBfaGVscGVyKG15cHRyLCBteXNpemUsIGFyZ3B0ciwgYXJnc2l6ZSk7CisgICAgaWYgKGxlZnQgPT0gbXlzaXplKQorICAgICAgICByaWdodCA9IGxlZnQ7CisgICAgZWxzZQorICAgICAgICByaWdodCA9IHJzdHJpcF9oZWxwZXIobXlwdHIsIG15c2l6ZSwgYXJncHRyLCBhcmdzaXplKTsKKyAgICBpZiAoYXJnICE9IFB5X05vbmUpCisgICAgICAgIFB5QnVmZmVyX1JlbGVhc2UoJnZhcmcpOworICAgIHJldHVybiBQeUJ5dGVBcnJheV9Gcm9tU3RyaW5nQW5kU2l6ZShzZWxmLT5vYl9ieXRlcyArIGxlZnQsIHJpZ2h0IC0gbGVmdCk7Cit9CisKK1B5RG9jX1NUUlZBUihsc3RyaXBfX2RvY19fLAorIkIubHN0cmlwKFtieXRlc10pIC0+IGJ5dGVhcnJheVxuXAorXG5cCitTdHJpcCBsZWFkaW5nIGJ5dGVzIGNvbnRhaW5lZCBpbiB0aGUgYXJndW1lbnQuXG5cCitJZiB0aGUgYXJndW1lbnQgaXMgb21pdHRlZCwgc3RyaXAgbGVhZGluZyBBU0NJSSB3aGl0ZXNwYWNlLiIpOworc3RhdGljIFB5T2JqZWN0ICoKK2J5dGVhcnJheV9sc3RyaXAoUHlCeXRlQXJyYXlPYmplY3QgKnNlbGYsIFB5T2JqZWN0ICphcmdzKQoreworICAgIFB5X3NzaXplX3QgbGVmdCwgcmlnaHQsIG15c2l6ZSwgYXJnc2l6ZTsKKyAgICB2b2lkICpteXB0ciwgKmFyZ3B0cjsKKyAgICBQeU9iamVjdCAqYXJnID0gUHlfTm9uZTsKKyAgICBQeV9idWZmZXIgdmFyZzsKKyAgICBpZiAoIVB5QXJnX1BhcnNlVHVwbGUoYXJncywgInxPOmxzdHJpcCIsICZhcmcpKQorICAgICAgICByZXR1cm4gTlVMTDsKKyAgICBpZiAoYXJnID09IFB5X05vbmUpIHsKKyAgICAgICAgYXJncHRyID0gIlx0XG5cclxmXHYgIjsKKyAgICAgICAgYXJnc2l6ZSA9IDY7CisgICAgfQorICAgIGVsc2UgeworICAgICAgICBpZiAoX2dldGJ1ZmZlcihhcmcsICZ2YXJnKSA8IDApCisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgYXJncHRyID0gdmFyZy5idWY7CisgICAgICAgIGFyZ3NpemUgPSB2YXJnLmxlbjsKKyAgICB9CisgICAgbXlwdHIgPSBzZWxmLT5vYl9ieXRlczsKKyAgICBteXNpemUgPSBQeV9TSVpFKHNlbGYpOworICAgIGxlZnQgPSBsc3RyaXBfaGVscGVyKG15cHRyLCBteXNpemUsIGFyZ3B0ciwgYXJnc2l6ZSk7CisgICAgcmlnaHQgPSBteXNpemU7CisgICAgaWYgKGFyZyAhPSBQeV9Ob25lKQorICAgICAgICBQeUJ1ZmZlcl9SZWxlYXNlKCZ2YXJnKTsKKyAgICByZXR1cm4gUHlCeXRlQXJyYXlfRnJvbVN0cmluZ0FuZFNpemUoc2VsZi0+b2JfYnl0ZXMgKyBsZWZ0LCByaWdodCAtIGxlZnQpOworfQorCitQeURvY19TVFJWQVIocnN0cmlwX19kb2NfXywKKyJCLnJzdHJpcChbYnl0ZXNdKSAtPiBieXRlYXJyYXlcblwKK1xuXAorU3RyaXAgdHJhaWxpbmcgYnl0ZXMgY29udGFpbmVkIGluIHRoZSBhcmd1bWVudC5cblwKK0lmIHRoZSBhcmd1bWVudCBpcyBvbWl0dGVkLCBzdHJpcCB0cmFpbGluZyBBU0NJSSB3aGl0ZXNwYWNlLiIpOworc3RhdGljIFB5T2JqZWN0ICoKK2J5dGVhcnJheV9yc3RyaXAoUHlCeXRlQXJyYXlPYmplY3QgKnNlbGYsIFB5T2JqZWN0ICphcmdzKQoreworICAgIFB5X3NzaXplX3QgbGVmdCwgcmlnaHQsIG15c2l6ZSwgYXJnc2l6ZTsKKyAgICB2b2lkICpteXB0ciwgKmFyZ3B0cjsKKyAgICBQeU9iamVjdCAqYXJnID0gUHlfTm9uZTsKKyAgICBQeV9idWZmZXIgdmFyZzsKKyAgICBpZiAoIVB5QXJnX1BhcnNlVHVwbGUoYXJncywgInxPOnJzdHJpcCIsICZhcmcpKQorICAgICAgICByZXR1cm4gTlVMTDsKKyAgICBpZiAoYXJnID09IFB5X05vbmUpIHsKKyAgICAgICAgYXJncHRyID0gIlx0XG5cclxmXHYgIjsKKyAgICAgICAgYXJnc2l6ZSA9IDY7CisgICAgfQorICAgIGVsc2UgeworICAgICAgICBpZiAoX2dldGJ1ZmZlcihhcmcsICZ2YXJnKSA8IDApCisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgYXJncHRyID0gdmFyZy5idWY7CisgICAgICAgIGFyZ3NpemUgPSB2YXJnLmxlbjsKKyAgICB9CisgICAgbXlwdHIgPSBzZWxmLT5vYl9ieXRlczsKKyAgICBteXNpemUgPSBQeV9TSVpFKHNlbGYpOworICAgIGxlZnQgPSAwOworICAgIHJpZ2h0ID0gcnN0cmlwX2hlbHBlcihteXB0ciwgbXlzaXplLCBhcmdwdHIsIGFyZ3NpemUpOworICAgIGlmIChhcmcgIT0gUHlfTm9uZSkKKyAgICAgICAgUHlCdWZmZXJfUmVsZWFzZSgmdmFyZyk7CisgICAgcmV0dXJuIFB5Qnl0ZUFycmF5X0Zyb21TdHJpbmdBbmRTaXplKHNlbGYtPm9iX2J5dGVzICsgbGVmdCwgcmlnaHQgLSBsZWZ0KTsKK30KKworUHlEb2NfU1RSVkFSKGRlY29kZV9kb2MsCisiQi5kZWNvZGUoW2VuY29kaW5nWywgZXJyb3JzXV0pIC0+IHVuaWNvZGUgb2JqZWN0LlxuXAorXG5cCitEZWNvZGVzIEIgdXNpbmcgdGhlIGNvZGVjIHJlZ2lzdGVyZWQgZm9yIGVuY29kaW5nLiBlbmNvZGluZyBkZWZhdWx0c1xuXAordG8gdGhlIGRlZmF1bHQgZW5jb2RpbmcuIGVycm9ycyBtYXkgYmUgZ2l2ZW4gdG8gc2V0IGEgZGlmZmVyZW50IGVycm9yXG5cCitoYW5kbGluZyBzY2hlbWUuICBEZWZhdWx0IGlzICdzdHJpY3QnIG1lYW5pbmcgdGhhdCBlbmNvZGluZyBlcnJvcnMgcmFpc2VcblwKK2EgVW5pY29kZURlY29kZUVycm9yLiAgT3RoZXIgcG9zc2libGUgdmFsdWVzIGFyZSAnaWdub3JlJyBhbmQgJ3JlcGxhY2UnXG5cCithcyB3ZWxsIGFzIGFueSBvdGhlciBuYW1lIHJlZ2lzdGVyZWQgd2l0aCBjb2RlY3MucmVnaXN0ZXJfZXJyb3IgdGhhdCBpc1xuXAorYWJsZSB0byBoYW5kbGUgVW5pY29kZURlY29kZUVycm9ycy4iKTsKKworc3RhdGljIFB5T2JqZWN0ICoKK2J5dGVhcnJheV9kZWNvZGUoUHlPYmplY3QgKnNlbGYsIFB5T2JqZWN0ICphcmdzLCBQeU9iamVjdCAqa3dhcmdzKQoreworICAgIGNvbnN0IGNoYXIgKmVuY29kaW5nID0gTlVMTDsKKyAgICBjb25zdCBjaGFyICplcnJvcnMgPSBOVUxMOworICAgIHN0YXRpYyBjaGFyICprd2xpc3RbXSA9IHsiZW5jb2RpbmciLCAiZXJyb3JzIiwgMH07CisKKyAgICBpZiAoIVB5QXJnX1BhcnNlVHVwbGVBbmRLZXl3b3JkcyhhcmdzLCBrd2FyZ3MsICJ8c3M6ZGVjb2RlIiwga3dsaXN0LCAmZW5jb2RpbmcsICZlcnJvcnMpKQorICAgICAgICByZXR1cm4gTlVMTDsKKyAgICBpZiAoZW5jb2RpbmcgPT0gTlVMTCkgeworI2lmZGVmIFB5X1VTSU5HX1VOSUNPREUKKyAgICAgICAgZW5jb2RpbmcgPSBQeVVuaWNvZGVfR2V0RGVmYXVsdEVuY29kaW5nKCk7CisjZWxzZQorICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfVmFsdWVFcnJvciwgIm5vIGVuY29kaW5nIHNwZWNpZmllZCIpOworICAgICAgICByZXR1cm4gTlVMTDsKKyNlbmRpZgorICAgIH0KKyAgICByZXR1cm4gUHlDb2RlY19EZWNvZGUoc2VsZiwgZW5jb2RpbmcsIGVycm9ycyk7Cit9CisKK1B5RG9jX1NUUlZBUihhbGxvY19kb2MsCisiQi5fX2FsbG9jX18oKSAtPiBpbnRcblwKK1xuXAorUmV0dXJucyB0aGUgbnVtYmVyIG9mIGJ5dGVzIGFjdHVhbGx5IGFsbG9jYXRlZC4iKTsKKworc3RhdGljIFB5T2JqZWN0ICoKK2J5dGVhcnJheV9hbGxvYyhQeUJ5dGVBcnJheU9iamVjdCAqc2VsZikKK3sKKyAgICByZXR1cm4gUHlJbnRfRnJvbVNzaXplX3Qoc2VsZi0+b2JfYWxsb2MpOworfQorCitQeURvY19TVFJWQVIoam9pbl9kb2MsCisiQi5qb2luKGl0ZXJhYmxlX29mX2J5dGVzKSAtPiBieXRlc1xuXAorXG5cCitDb25jYXRlbmF0ZXMgYW55IG51bWJlciBvZiBieXRlYXJyYXkgb2JqZWN0cywgd2l0aCBCIGluIGJldHdlZW4gZWFjaCBwYWlyLiIpOworCitzdGF0aWMgUHlPYmplY3QgKgorYnl0ZWFycmF5X2pvaW4oUHlCeXRlQXJyYXlPYmplY3QgKnNlbGYsIFB5T2JqZWN0ICppdCkKK3sKKyAgICBQeU9iamVjdCAqc2VxOworICAgIFB5X3NzaXplX3QgbXlzaXplID0gUHlfU0laRShzZWxmKTsKKyAgICBQeV9zc2l6ZV90IGk7CisgICAgUHlfc3NpemVfdCBuOworICAgIFB5T2JqZWN0ICoqaXRlbXM7CisgICAgUHlfc3NpemVfdCB0b3RhbHNpemUgPSAwOworICAgIFB5T2JqZWN0ICpyZXN1bHQ7CisgICAgY2hhciAqZGVzdDsKKworICAgIHNlcSA9IFB5U2VxdWVuY2VfRmFzdChpdCwgImNhbiBvbmx5IGpvaW4gYW4gaXRlcmFibGUiKTsKKyAgICBpZiAoc2VxID09IE5VTEwpCisgICAgICAgIHJldHVybiBOVUxMOworICAgIG4gPSBQeVNlcXVlbmNlX0Zhc3RfR0VUX1NJWkUoc2VxKTsKKyAgICBpdGVtcyA9IFB5U2VxdWVuY2VfRmFzdF9JVEVNUyhzZXEpOworCisgICAgLyogQ29tcHV0ZSB0aGUgdG90YWwgc2l6ZSwgYW5kIGNoZWNrIHRoYXQgdGhleSBhcmUgYWxsIGJ5dGVzICovCisgICAgLyogWFhYIFNob3VsZG4ndCB3ZSB1c2UgX2dldGJ1ZmZlcigpIG9uIHRoZXNlIGl0ZW1zIGluc3RlYWQ/ICovCisgICAgZm9yIChpID0gMDsgaSA8IG47IGkrKykgeworICAgICAgICBQeU9iamVjdCAqb2JqID0gaXRlbXNbaV07CisgICAgICAgIGlmICghUHlCeXRlQXJyYXlfQ2hlY2sob2JqKSAmJiAhUHlCeXRlc19DaGVjayhvYmopKSB7CisgICAgICAgICAgICBQeUVycl9Gb3JtYXQoUHlFeGNfVHlwZUVycm9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICJjYW4gb25seSBqb2luIGFuIGl0ZXJhYmxlIG9mIGJ5dGVzICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAiKGl0ZW0gJWxkIGhhcyB0eXBlICclLjEwMHMnKSIsCisgICAgICAgICAgICAgICAgICAgICAgICAgLyogWFhYICVsZCBpc24ndCByaWdodCBvbiBXaW42NCAqLworICAgICAgICAgICAgICAgICAgICAgICAgIChsb25nKWksIFB5X1RZUEUob2JqKS0+dHBfbmFtZSk7CisgICAgICAgICAgICBnb3RvIGVycm9yOworICAgICAgICB9CisgICAgICAgIGlmIChpID4gMCkKKyAgICAgICAgICAgIHRvdGFsc2l6ZSArPSBteXNpemU7CisgICAgICAgIHRvdGFsc2l6ZSArPSBQeV9TSVpFKG9iaik7CisgICAgICAgIGlmICh0b3RhbHNpemUgPCAwKSB7CisgICAgICAgICAgICBQeUVycl9Ob01lbW9yeSgpOworICAgICAgICAgICAgZ290byBlcnJvcjsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qIEFsbG9jYXRlIHRoZSByZXN1bHQsIGFuZCBjb3B5IHRoZSBieXRlcyAqLworICAgIHJlc3VsdCA9IFB5Qnl0ZUFycmF5X0Zyb21TdHJpbmdBbmRTaXplKE5VTEwsIHRvdGFsc2l6ZSk7CisgICAgaWYgKHJlc3VsdCA9PSBOVUxMKQorICAgICAgICBnb3RvIGVycm9yOworICAgIGRlc3QgPSBQeUJ5dGVBcnJheV9BU19TVFJJTkcocmVzdWx0KTsKKyAgICBmb3IgKGkgPSAwOyBpIDwgbjsgaSsrKSB7CisgICAgICAgIFB5T2JqZWN0ICpvYmogPSBpdGVtc1tpXTsKKyAgICAgICAgUHlfc3NpemVfdCBzaXplID0gUHlfU0laRShvYmopOworICAgICAgICBjaGFyICpidWY7CisgICAgICAgIGlmIChQeUJ5dGVBcnJheV9DaGVjayhvYmopKQorICAgICAgICAgICBidWYgPSBQeUJ5dGVBcnJheV9BU19TVFJJTkcob2JqKTsKKyAgICAgICAgZWxzZQorICAgICAgICAgICBidWYgPSBQeUJ5dGVzX0FTX1NUUklORyhvYmopOworICAgICAgICBpZiAoaSkgeworICAgICAgICAgICAgbWVtY3B5KGRlc3QsIHNlbGYtPm9iX2J5dGVzLCBteXNpemUpOworICAgICAgICAgICAgZGVzdCArPSBteXNpemU7CisgICAgICAgIH0KKyAgICAgICAgbWVtY3B5KGRlc3QsIGJ1Ziwgc2l6ZSk7CisgICAgICAgIGRlc3QgKz0gc2l6ZTsKKyAgICB9CisKKyAgICAvKiBEb25lICovCisgICAgUHlfREVDUkVGKHNlcSk7CisgICAgcmV0dXJuIHJlc3VsdDsKKworICAgIC8qIEVycm9yIGhhbmRsaW5nICovCisgIGVycm9yOgorICAgIFB5X0RFQ1JFRihzZXEpOworICAgIHJldHVybiBOVUxMOworfQorCitQeURvY19TVFJWQVIoc3BsaXRsaW5lc19fZG9jX18sCisiQi5zcGxpdGxpbmVzKGtlZXBlbmRzPUZhbHNlKSAtPiBsaXN0IG9mIGxpbmVzXG5cCitcblwKK1JldHVybiBhIGxpc3Qgb2YgdGhlIGxpbmVzIGluIEIsIGJyZWFraW5nIGF0IGxpbmUgYm91bmRhcmllcy5cblwKK0xpbmUgYnJlYWtzIGFyZSBub3QgaW5jbHVkZWQgaW4gdGhlIHJlc3VsdGluZyBsaXN0IHVubGVzcyBrZWVwZW5kc1xuXAoraXMgZ2l2ZW4gYW5kIHRydWUuIik7CisKK3N0YXRpYyBQeU9iamVjdCoKK2J5dGVhcnJheV9zcGxpdGxpbmVzKFB5T2JqZWN0ICpzZWxmLCBQeU9iamVjdCAqYXJncykKK3sKKyAgICBpbnQga2VlcGVuZHMgPSAwOworCisgICAgaWYgKCFQeUFyZ19QYXJzZVR1cGxlKGFyZ3MsICJ8aTpzcGxpdGxpbmVzIiwgJmtlZXBlbmRzKSkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisKKyAgICByZXR1cm4gc3RyaW5nbGliX3NwbGl0bGluZXMoCisgICAgICAgIChQeU9iamVjdCopIHNlbGYsIFB5Qnl0ZUFycmF5X0FTX1NUUklORyhzZWxmKSwKKyAgICAgICAgUHlCeXRlQXJyYXlfR0VUX1NJWkUoc2VsZiksIGtlZXBlbmRzCisgICAgICAgICk7Cit9CisKK1B5RG9jX1NUUlZBUihmcm9taGV4X2RvYywKKyJieXRlYXJyYXkuZnJvbWhleChzdHJpbmcpIC0+IGJ5dGVhcnJheVxuXAorXG5cCitDcmVhdGUgYSBieXRlYXJyYXkgb2JqZWN0IGZyb20gYSBzdHJpbmcgb2YgaGV4YWRlY2ltYWwgbnVtYmVycy5cblwKK1NwYWNlcyBiZXR3ZWVuIHR3byBudW1iZXJzIGFyZSBhY2NlcHRlZC5cblwKK0V4YW1wbGU6IGJ5dGVhcnJheS5mcm9taGV4KCdCOSAwMUVGJykgLT4gYnl0ZWFycmF5KGInXFx4YjlcXHgwMVxceGVmJykuIik7CisKK3N0YXRpYyBpbnQKK2hleF9kaWdpdF90b19pbnQoY2hhciBjKQoreworICAgIGlmIChQeV9JU0RJR0lUKGMpKQorICAgICAgICByZXR1cm4gYyAtICcwJzsKKyAgICBlbHNlIHsKKyAgICAgICAgaWYgKFB5X0lTVVBQRVIoYykpCisgICAgICAgICAgICBjID0gUHlfVE9MT1dFUihjKTsKKyAgICAgICAgaWYgKGMgPj0gJ2EnICYmIGMgPD0gJ2YnKQorICAgICAgICAgICAgcmV0dXJuIGMgLSAnYScgKyAxMDsKKyAgICB9CisgICAgcmV0dXJuIC0xOworfQorCitzdGF0aWMgUHlPYmplY3QgKgorYnl0ZWFycmF5X2Zyb21oZXgoUHlPYmplY3QgKmNscywgUHlPYmplY3QgKmFyZ3MpCit7CisgICAgUHlPYmplY3QgKm5ld2J5dGVzOworICAgIGNoYXIgKmJ1ZjsKKyAgICBjaGFyICpoZXg7CisgICAgUHlfc3NpemVfdCBoZXhsZW4sIGJ5dGVzbGVuLCBpLCBqOworICAgIGludCB0b3AsIGJvdDsKKworICAgIGlmICghUHlBcmdfUGFyc2VUdXBsZShhcmdzLCAicyM6ZnJvbWhleCIsICZoZXgsICZoZXhsZW4pKQorICAgICAgICByZXR1cm4gTlVMTDsKKyAgICBieXRlc2xlbiA9IGhleGxlbi8yOyAvKiBUaGlzIG92ZXJlc3RpbWF0ZXMgaWYgdGhlcmUgYXJlIHNwYWNlcyAqLworICAgIG5ld2J5dGVzID0gUHlCeXRlQXJyYXlfRnJvbVN0cmluZ0FuZFNpemUoTlVMTCwgYnl0ZXNsZW4pOworICAgIGlmICghbmV3Ynl0ZXMpCisgICAgICAgIHJldHVybiBOVUxMOworICAgIGJ1ZiA9IFB5Qnl0ZUFycmF5X0FTX1NUUklORyhuZXdieXRlcyk7CisgICAgZm9yIChpID0gaiA9IDA7IGkgPCBoZXhsZW47IGkgKz0gMikgeworICAgICAgICAvKiBza2lwIG92ZXIgc3BhY2VzIGluIHRoZSBpbnB1dCAqLworICAgICAgICB3aGlsZSAoaGV4W2ldID09ICcgJykKKyAgICAgICAgICAgIGkrKzsKKyAgICAgICAgaWYgKGkgPj0gaGV4bGVuKQorICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIHRvcCA9IGhleF9kaWdpdF90b19pbnQoaGV4W2ldKTsKKyAgICAgICAgYm90ID0gaGV4X2RpZ2l0X3RvX2ludChoZXhbaSsxXSk7CisgICAgICAgIGlmICh0b3AgPT0gLTEgfHwgYm90ID09IC0xKSB7CisgICAgICAgICAgICBQeUVycl9Gb3JtYXQoUHlFeGNfVmFsdWVFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAibm9uLWhleGFkZWNpbWFsIG51bWJlciBmb3VuZCBpbiAiCisgICAgICAgICAgICAgICAgICAgICAgICAgImZyb21oZXgoKSBhcmcgYXQgcG9zaXRpb24gJXpkIiwgaSk7CisgICAgICAgICAgICBnb3RvIGVycm9yOworICAgICAgICB9CisgICAgICAgIGJ1ZltqKytdID0gKHRvcCA8PCA0KSArIGJvdDsKKyAgICB9CisgICAgaWYgKFB5Qnl0ZUFycmF5X1Jlc2l6ZShuZXdieXRlcywgaikgPCAwKQorICAgICAgICBnb3RvIGVycm9yOworICAgIHJldHVybiBuZXdieXRlczsKKworICBlcnJvcjoKKyAgICBQeV9ERUNSRUYobmV3Ynl0ZXMpOworICAgIHJldHVybiBOVUxMOworfQorCitQeURvY19TVFJWQVIocmVkdWNlX2RvYywgIlJldHVybiBzdGF0ZSBpbmZvcm1hdGlvbiBmb3IgcGlja2xpbmcuIik7CisKK3N0YXRpYyBQeU9iamVjdCAqCitieXRlYXJyYXlfcmVkdWNlKFB5Qnl0ZUFycmF5T2JqZWN0ICpzZWxmKQoreworICAgIFB5T2JqZWN0ICpsYXRpbjEsICpkaWN0OworICAgIGlmIChzZWxmLT5vYl9ieXRlcykKKyNpZmRlZiBQeV9VU0lOR19VTklDT0RFCisgICAgICAgIGxhdGluMSA9IFB5VW5pY29kZV9EZWNvZGVMYXRpbjEoc2VsZi0+b2JfYnl0ZXMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHlfU0laRShzZWxmKSwgTlVMTCk7CisjZWxzZQorICAgICAgICBsYXRpbjEgPSBQeVN0cmluZ19Gcm9tU3RyaW5nQW5kU2l6ZShzZWxmLT5vYl9ieXRlcywgUHlfU0laRShzZWxmKSk7CisjZW5kaWYKKyAgICBlbHNlCisjaWZkZWYgUHlfVVNJTkdfVU5JQ09ERQorICAgICAgICBsYXRpbjEgPSBQeVVuaWNvZGVfRnJvbVN0cmluZygiIik7CisjZWxzZQorICAgICAgICBsYXRpbjEgPSBQeVN0cmluZ19Gcm9tU3RyaW5nKCIiKTsKKyNlbmRpZgorCisgICAgZGljdCA9IFB5T2JqZWN0X0dldEF0dHJTdHJpbmcoKFB5T2JqZWN0ICopc2VsZiwgIl9fZGljdF9fIik7CisgICAgaWYgKGRpY3QgPT0gTlVMTCkgeworICAgICAgICBQeUVycl9DbGVhcigpOworICAgICAgICBkaWN0ID0gUHlfTm9uZTsKKyAgICAgICAgUHlfSU5DUkVGKGRpY3QpOworICAgIH0KKworICAgIHJldHVybiBQeV9CdWlsZFZhbHVlKCIoTyhOcylOKSIsIFB5X1RZUEUoc2VsZiksIGxhdGluMSwgImxhdGluLTEiLCBkaWN0KTsKK30KKworUHlEb2NfU1RSVkFSKHNpemVvZl9kb2MsCisiQi5fX3NpemVvZl9fKCkgLT4gaW50XG5cCisgXG5cCitSZXR1cm5zIHRoZSBzaXplIG9mIEIgaW4gbWVtb3J5LCBpbiBieXRlcyIpOworc3RhdGljIFB5T2JqZWN0ICoKK2J5dGVhcnJheV9zaXplb2YoUHlCeXRlQXJyYXlPYmplY3QgKnNlbGYpCit7CisgICAgUHlfc3NpemVfdCByZXM7CisKKyAgICByZXMgPSBzaXplb2YoUHlCeXRlQXJyYXlPYmplY3QpICsgc2VsZi0+b2JfYWxsb2MgKiBzaXplb2YoY2hhcik7CisgICAgcmV0dXJuIFB5SW50X0Zyb21Tc2l6ZV90KHJlcyk7Cit9CisKK3N0YXRpYyBQeVNlcXVlbmNlTWV0aG9kcyBieXRlYXJyYXlfYXNfc2VxdWVuY2UgPSB7CisgICAgKGxlbmZ1bmMpYnl0ZWFycmF5X2xlbmd0aCwgICAgICAgICAgICAgIC8qIHNxX2xlbmd0aCAqLworICAgIChiaW5hcnlmdW5jKVB5Qnl0ZUFycmF5X0NvbmNhdCwgICAgICAgICAvKiBzcV9jb25jYXQgKi8KKyAgICAoc3NpemVhcmdmdW5jKWJ5dGVhcnJheV9yZXBlYXQsICAgICAgICAgLyogc3FfcmVwZWF0ICovCisgICAgKHNzaXplYXJnZnVuYylieXRlYXJyYXlfZ2V0aXRlbSwgICAgICAgIC8qIHNxX2l0ZW0gKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogc3Ffc2xpY2UgKi8KKyAgICAoc3NpemVvYmphcmdwcm9jKWJ5dGVhcnJheV9zZXRpdGVtLCAgICAgLyogc3FfYXNzX2l0ZW0gKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogc3FfYXNzX3NsaWNlICovCisgICAgKG9iam9ianByb2MpYnl0ZWFycmF5X2NvbnRhaW5zLCAgICAgICAgIC8qIHNxX2NvbnRhaW5zICovCisgICAgKGJpbmFyeWZ1bmMpYnl0ZWFycmF5X2ljb25jYXQsICAgICAgICAgIC8qIHNxX2lucGxhY2VfY29uY2F0ICovCisgICAgKHNzaXplYXJnZnVuYylieXRlYXJyYXlfaXJlcGVhdCwgICAgICAgIC8qIHNxX2lucGxhY2VfcmVwZWF0ICovCit9OworCitzdGF0aWMgUHlNYXBwaW5nTWV0aG9kcyBieXRlYXJyYXlfYXNfbWFwcGluZyA9IHsKKyAgICAobGVuZnVuYylieXRlYXJyYXlfbGVuZ3RoLAorICAgIChiaW5hcnlmdW5jKWJ5dGVhcnJheV9zdWJzY3JpcHQsCisgICAgKG9iam9iamFyZ3Byb2MpYnl0ZWFycmF5X2Fzc19zdWJzY3JpcHQsCit9OworCitzdGF0aWMgUHlCdWZmZXJQcm9jcyBieXRlYXJyYXlfYXNfYnVmZmVyID0geworICAgIChyZWFkYnVmZmVycHJvYylieXRlYXJyYXlfYnVmZmVyX2dldHJlYWRidWYsCisgICAgKHdyaXRlYnVmZmVycHJvYylieXRlYXJyYXlfYnVmZmVyX2dldHdyaXRlYnVmLAorICAgIChzZWdjb3VudHByb2MpYnl0ZWFycmF5X2J1ZmZlcl9nZXRzZWdjb3VudCwKKyAgICAoY2hhcmJ1ZmZlcnByb2MpYnl0ZWFycmF5X2J1ZmZlcl9nZXRjaGFyYnVmLAorICAgIChnZXRidWZmZXJwcm9jKWJ5dGVhcnJheV9nZXRidWZmZXIsCisgICAgKHJlbGVhc2VidWZmZXJwcm9jKWJ5dGVhcnJheV9yZWxlYXNlYnVmZmVyLAorfTsKKworc3RhdGljIFB5TWV0aG9kRGVmCitieXRlYXJyYXlfbWV0aG9kc1tdID0geworICAgIHsiX19hbGxvY19fIiwgKFB5Q0Z1bmN0aW9uKWJ5dGVhcnJheV9hbGxvYywgTUVUSF9OT0FSR1MsIGFsbG9jX2RvY30sCisgICAgeyJfX3JlZHVjZV9fIiwgKFB5Q0Z1bmN0aW9uKWJ5dGVhcnJheV9yZWR1Y2UsIE1FVEhfTk9BUkdTLCByZWR1Y2VfZG9jfSwKKyAgICB7Il9fc2l6ZW9mX18iLCAoUHlDRnVuY3Rpb24pYnl0ZWFycmF5X3NpemVvZiwgTUVUSF9OT0FSR1MsIHNpemVvZl9kb2N9LAorICAgIHsiYXBwZW5kIiwgKFB5Q0Z1bmN0aW9uKWJ5dGVhcnJheV9hcHBlbmQsIE1FVEhfTywgYXBwZW5kX19kb2NfX30sCisgICAgeyJjYXBpdGFsaXplIiwgKFB5Q0Z1bmN0aW9uKXN0cmluZ2xpYl9jYXBpdGFsaXplLCBNRVRIX05PQVJHUywKKyAgICAgX1B5X2NhcGl0YWxpemVfX2RvY19ffSwKKyAgICB7ImNlbnRlciIsIChQeUNGdW5jdGlvbilzdHJpbmdsaWJfY2VudGVyLCBNRVRIX1ZBUkFSR1MsIGNlbnRlcl9fZG9jX199LAorICAgIHsiY291bnQiLCAoUHlDRnVuY3Rpb24pYnl0ZWFycmF5X2NvdW50LCBNRVRIX1ZBUkFSR1MsIGNvdW50X19kb2NfX30sCisgICAgeyJkZWNvZGUiLCAoUHlDRnVuY3Rpb24pYnl0ZWFycmF5X2RlY29kZSwgTUVUSF9WQVJBUkdTIHwgTUVUSF9LRVlXT1JEUywgZGVjb2RlX2RvY30sCisgICAgeyJlbmRzd2l0aCIsIChQeUNGdW5jdGlvbilieXRlYXJyYXlfZW5kc3dpdGgsIE1FVEhfVkFSQVJHUywgZW5kc3dpdGhfX2RvY19ffSwKKyAgICB7ImV4cGFuZHRhYnMiLCAoUHlDRnVuY3Rpb24pc3RyaW5nbGliX2V4cGFuZHRhYnMsIE1FVEhfVkFSQVJHUywKKyAgICAgZXhwYW5kdGFic19fZG9jX199LAorICAgIHsiZXh0ZW5kIiwgKFB5Q0Z1bmN0aW9uKWJ5dGVhcnJheV9leHRlbmQsIE1FVEhfTywgZXh0ZW5kX19kb2NfX30sCisgICAgeyJmaW5kIiwgKFB5Q0Z1bmN0aW9uKWJ5dGVhcnJheV9maW5kLCBNRVRIX1ZBUkFSR1MsIGZpbmRfX2RvY19ffSwKKyAgICB7ImZyb21oZXgiLCAoUHlDRnVuY3Rpb24pYnl0ZWFycmF5X2Zyb21oZXgsIE1FVEhfVkFSQVJHU3xNRVRIX0NMQVNTLAorICAgICBmcm9taGV4X2RvY30sCisgICAgeyJpbmRleCIsIChQeUNGdW5jdGlvbilieXRlYXJyYXlfaW5kZXgsIE1FVEhfVkFSQVJHUywgaW5kZXhfX2RvY19ffSwKKyAgICB7Imluc2VydCIsIChQeUNGdW5jdGlvbilieXRlYXJyYXlfaW5zZXJ0LCBNRVRIX1ZBUkFSR1MsIGluc2VydF9fZG9jX199LAorICAgIHsiaXNhbG51bSIsIChQeUNGdW5jdGlvbilzdHJpbmdsaWJfaXNhbG51bSwgTUVUSF9OT0FSR1MsCisgICAgIF9QeV9pc2FsbnVtX19kb2NfX30sCisgICAgeyJpc2FscGhhIiwgKFB5Q0Z1bmN0aW9uKXN0cmluZ2xpYl9pc2FscGhhLCBNRVRIX05PQVJHUywKKyAgICAgX1B5X2lzYWxwaGFfX2RvY19ffSwKKyAgICB7ImlzZGlnaXQiLCAoUHlDRnVuY3Rpb24pc3RyaW5nbGliX2lzZGlnaXQsIE1FVEhfTk9BUkdTLAorICAgICBfUHlfaXNkaWdpdF9fZG9jX199LAorICAgIHsiaXNsb3dlciIsIChQeUNGdW5jdGlvbilzdHJpbmdsaWJfaXNsb3dlciwgTUVUSF9OT0FSR1MsCisgICAgIF9QeV9pc2xvd2VyX19kb2NfX30sCisgICAgeyJpc3NwYWNlIiwgKFB5Q0Z1bmN0aW9uKXN0cmluZ2xpYl9pc3NwYWNlLCBNRVRIX05PQVJHUywKKyAgICAgX1B5X2lzc3BhY2VfX2RvY19ffSwKKyAgICB7ImlzdGl0bGUiLCAoUHlDRnVuY3Rpb24pc3RyaW5nbGliX2lzdGl0bGUsIE1FVEhfTk9BUkdTLAorICAgICBfUHlfaXN0aXRsZV9fZG9jX199LAorICAgIHsiaXN1cHBlciIsIChQeUNGdW5jdGlvbilzdHJpbmdsaWJfaXN1cHBlciwgTUVUSF9OT0FSR1MsCisgICAgIF9QeV9pc3VwcGVyX19kb2NfX30sCisgICAgeyJqb2luIiwgKFB5Q0Z1bmN0aW9uKWJ5dGVhcnJheV9qb2luLCBNRVRIX08sIGpvaW5fZG9jfSwKKyAgICB7ImxqdXN0IiwgKFB5Q0Z1bmN0aW9uKXN0cmluZ2xpYl9sanVzdCwgTUVUSF9WQVJBUkdTLCBsanVzdF9fZG9jX199LAorICAgIHsibG93ZXIiLCAoUHlDRnVuY3Rpb24pc3RyaW5nbGliX2xvd2VyLCBNRVRIX05PQVJHUywgX1B5X2xvd2VyX19kb2NfX30sCisgICAgeyJsc3RyaXAiLCAoUHlDRnVuY3Rpb24pYnl0ZWFycmF5X2xzdHJpcCwgTUVUSF9WQVJBUkdTLCBsc3RyaXBfX2RvY19ffSwKKyAgICB7InBhcnRpdGlvbiIsIChQeUNGdW5jdGlvbilieXRlYXJyYXlfcGFydGl0aW9uLCBNRVRIX08sIHBhcnRpdGlvbl9fZG9jX199LAorICAgIHsicG9wIiwgKFB5Q0Z1bmN0aW9uKWJ5dGVhcnJheV9wb3AsIE1FVEhfVkFSQVJHUywgcG9wX19kb2NfX30sCisgICAgeyJyZW1vdmUiLCAoUHlDRnVuY3Rpb24pYnl0ZWFycmF5X3JlbW92ZSwgTUVUSF9PLCByZW1vdmVfX2RvY19ffSwKKyAgICB7InJlcGxhY2UiLCAoUHlDRnVuY3Rpb24pYnl0ZWFycmF5X3JlcGxhY2UsIE1FVEhfVkFSQVJHUywgcmVwbGFjZV9fZG9jX199LAorICAgIHsicmV2ZXJzZSIsIChQeUNGdW5jdGlvbilieXRlYXJyYXlfcmV2ZXJzZSwgTUVUSF9OT0FSR1MsIHJldmVyc2VfX2RvY19ffSwKKyAgICB7InJmaW5kIiwgKFB5Q0Z1bmN0aW9uKWJ5dGVhcnJheV9yZmluZCwgTUVUSF9WQVJBUkdTLCByZmluZF9fZG9jX199LAorICAgIHsicmluZGV4IiwgKFB5Q0Z1bmN0aW9uKWJ5dGVhcnJheV9yaW5kZXgsIE1FVEhfVkFSQVJHUywgcmluZGV4X19kb2NfX30sCisgICAgeyJyanVzdCIsIChQeUNGdW5jdGlvbilzdHJpbmdsaWJfcmp1c3QsIE1FVEhfVkFSQVJHUywgcmp1c3RfX2RvY19ffSwKKyAgICB7InJwYXJ0aXRpb24iLCAoUHlDRnVuY3Rpb24pYnl0ZWFycmF5X3JwYXJ0aXRpb24sIE1FVEhfTywgcnBhcnRpdGlvbl9fZG9jX199LAorICAgIHsicnNwbGl0IiwgKFB5Q0Z1bmN0aW9uKWJ5dGVhcnJheV9yc3BsaXQsIE1FVEhfVkFSQVJHUywgcnNwbGl0X19kb2NfX30sCisgICAgeyJyc3RyaXAiLCAoUHlDRnVuY3Rpb24pYnl0ZWFycmF5X3JzdHJpcCwgTUVUSF9WQVJBUkdTLCByc3RyaXBfX2RvY19ffSwKKyAgICB7InNwbGl0IiwgKFB5Q0Z1bmN0aW9uKWJ5dGVhcnJheV9zcGxpdCwgTUVUSF9WQVJBUkdTLCBzcGxpdF9fZG9jX199LAorICAgIHsic3BsaXRsaW5lcyIsIChQeUNGdW5jdGlvbilieXRlYXJyYXlfc3BsaXRsaW5lcywgTUVUSF9WQVJBUkdTLAorICAgICBzcGxpdGxpbmVzX19kb2NfX30sCisgICAgeyJzdGFydHN3aXRoIiwgKFB5Q0Z1bmN0aW9uKWJ5dGVhcnJheV9zdGFydHN3aXRoLCBNRVRIX1ZBUkFSR1MgLAorICAgICBzdGFydHN3aXRoX19kb2NfX30sCisgICAgeyJzdHJpcCIsIChQeUNGdW5jdGlvbilieXRlYXJyYXlfc3RyaXAsIE1FVEhfVkFSQVJHUywgc3RyaXBfX2RvY19ffSwKKyAgICB7InN3YXBjYXNlIiwgKFB5Q0Z1bmN0aW9uKXN0cmluZ2xpYl9zd2FwY2FzZSwgTUVUSF9OT0FSR1MsCisgICAgIF9QeV9zd2FwY2FzZV9fZG9jX199LAorICAgIHsidGl0bGUiLCAoUHlDRnVuY3Rpb24pc3RyaW5nbGliX3RpdGxlLCBNRVRIX05PQVJHUywgX1B5X3RpdGxlX19kb2NfX30sCisgICAgeyJ0cmFuc2xhdGUiLCAoUHlDRnVuY3Rpb24pYnl0ZWFycmF5X3RyYW5zbGF0ZSwgTUVUSF9WQVJBUkdTLAorICAgICB0cmFuc2xhdGVfX2RvY19ffSwKKyAgICB7InVwcGVyIiwgKFB5Q0Z1bmN0aW9uKXN0cmluZ2xpYl91cHBlciwgTUVUSF9OT0FSR1MsIF9QeV91cHBlcl9fZG9jX199LAorICAgIHsiemZpbGwiLCAoUHlDRnVuY3Rpb24pc3RyaW5nbGliX3pmaWxsLCBNRVRIX1ZBUkFSR1MsIHpmaWxsX19kb2NfX30sCisgICAge05VTEx9Cit9OworCitQeURvY19TVFJWQVIoYnl0ZWFycmF5X2RvYywKKyJieXRlYXJyYXkoaXRlcmFibGVfb2ZfaW50cykgLT4gYnl0ZWFycmF5LlxuXAorYnl0ZWFycmF5KHN0cmluZywgZW5jb2RpbmdbLCBlcnJvcnNdKSAtPiBieXRlYXJyYXkuXG5cCitieXRlYXJyYXkoYnl0ZXNfb3JfYnl0ZWFycmF5KSAtPiBtdXRhYmxlIGNvcHkgb2YgYnl0ZXNfb3JfYnl0ZWFycmF5LlxuXAorYnl0ZWFycmF5KG1lbW9yeV92aWV3KSAtPiBieXRlYXJyYXkuXG5cCitcblwKK0NvbnN0cnVjdCBhbiBtdXRhYmxlIGJ5dGVhcnJheSBvYmplY3QgZnJvbTpcblwKKyAgLSBhbiBpdGVyYWJsZSB5aWVsZGluZyBpbnRlZ2VycyBpbiByYW5nZSgyNTYpXG5cCisgIC0gYSB0ZXh0IHN0cmluZyBlbmNvZGVkIHVzaW5nIHRoZSBzcGVjaWZpZWQgZW5jb2RpbmdcblwKKyAgLSBhIGJ5dGVzIG9yIGEgYnl0ZWFycmF5IG9iamVjdFxuXAorICAtIGFueSBvYmplY3QgaW1wbGVtZW50aW5nIHRoZSBidWZmZXIgQVBJLlxuXAorXG5cCitieXRlYXJyYXkoaW50KSAtPiBieXRlYXJyYXkuXG5cCitcblwKK0NvbnN0cnVjdCBhIHplcm8taW5pdGlhbGl6ZWQgYnl0ZWFycmF5IG9mIHRoZSBnaXZlbiBsZW5ndGguIik7CisKKworc3RhdGljIFB5T2JqZWN0ICpieXRlYXJyYXlfaXRlcihQeU9iamVjdCAqc2VxKTsKKworUHlUeXBlT2JqZWN0IFB5Qnl0ZUFycmF5X1R5cGUgPSB7CisgICAgUHlWYXJPYmplY3RfSEVBRF9JTklUKCZQeVR5cGVfVHlwZSwgMCkKKyAgICAiYnl0ZWFycmF5IiwKKyAgICBzaXplb2YoUHlCeXRlQXJyYXlPYmplY3QpLAorICAgIDAsCisgICAgKGRlc3RydWN0b3IpYnl0ZWFycmF5X2RlYWxsb2MsICAgICAgIC8qIHRwX2RlYWxsb2MgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9wcmludCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2dldGF0dHIgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9zZXRhdHRyICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfY29tcGFyZSAqLworICAgIChyZXByZnVuYylieXRlYXJyYXlfcmVwciwgICAgICAgICAgIC8qIHRwX3JlcHIgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9hc19udW1iZXIgKi8KKyAgICAmYnl0ZWFycmF5X2FzX3NlcXVlbmNlLCAgICAgICAgICAgICAvKiB0cF9hc19zZXF1ZW5jZSAqLworICAgICZieXRlYXJyYXlfYXNfbWFwcGluZywgICAgICAgICAgICAgIC8qIHRwX2FzX21hcHBpbmcgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9oYXNoICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfY2FsbCAqLworICAgIGJ5dGVhcnJheV9zdHIsICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3N0ciAqLworICAgIFB5T2JqZWN0X0dlbmVyaWNHZXRBdHRyLCAgICAgICAgICAgIC8qIHRwX2dldGF0dHJvICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfc2V0YXR0cm8gKi8KKyAgICAmYnl0ZWFycmF5X2FzX2J1ZmZlciwgICAgICAgICAgICAgICAvKiB0cF9hc19idWZmZXIgKi8KKyAgICBQeV9UUEZMQUdTX0RFRkFVTFQgfCBQeV9UUEZMQUdTX0JBU0VUWVBFIHwKKyAgICBQeV9UUEZMQUdTX0hBVkVfTkVXQlVGRkVSLCAgICAgICAgICAvKiB0cF9mbGFncyAqLworICAgIGJ5dGVhcnJheV9kb2MsICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2RvYyAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3RyYXZlcnNlICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfY2xlYXIgKi8KKyAgICAocmljaGNtcGZ1bmMpYnl0ZWFycmF5X3JpY2hjb21wYXJlLCAvKiB0cF9yaWNoY29tcGFyZSAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3dlYWtsaXN0b2Zmc2V0ICovCisgICAgYnl0ZWFycmF5X2l0ZXIsICAgICAgICAgICAgICAgICAgICAgLyogdHBfaXRlciAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2l0ZXJuZXh0ICovCisgICAgYnl0ZWFycmF5X21ldGhvZHMsICAgICAgICAgICAgICAgICAgLyogdHBfbWV0aG9kcyAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX21lbWJlcnMgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9nZXRzZXQgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9iYXNlICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZGljdCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2Rlc2NyX2dldCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2Rlc2NyX3NldCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2RpY3RvZmZzZXQgKi8KKyAgICAoaW5pdHByb2MpYnl0ZWFycmF5X2luaXQsICAgICAgICAgICAvKiB0cF9pbml0ICovCisgICAgUHlUeXBlX0dlbmVyaWNBbGxvYywgICAgICAgICAgICAgICAgLyogdHBfYWxsb2MgKi8KKyAgICBQeVR5cGVfR2VuZXJpY05ldywgICAgICAgICAgICAgICAgICAvKiB0cF9uZXcgKi8KKyAgICBQeU9iamVjdF9EZWwsICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9mcmVlICovCit9OworCisvKioqKioqKioqKioqKioqKioqKioqKiogQnl0ZXMgSXRlcmF0b3IgKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KKwordHlwZWRlZiBzdHJ1Y3QgeworICAgIFB5T2JqZWN0X0hFQUQKKyAgICBQeV9zc2l6ZV90IGl0X2luZGV4OworICAgIFB5Qnl0ZUFycmF5T2JqZWN0ICppdF9zZXE7IC8qIFNldCB0byBOVUxMIHdoZW4gaXRlcmF0b3IgaXMgZXhoYXVzdGVkICovCit9IGJ5dGVzaXRlcm9iamVjdDsKKworc3RhdGljIHZvaWQKK2J5dGVhcnJheWl0ZXJfZGVhbGxvYyhieXRlc2l0ZXJvYmplY3QgKml0KQoreworICAgIF9QeU9iamVjdF9HQ19VTlRSQUNLKGl0KTsKKyAgICBQeV9YREVDUkVGKGl0LT5pdF9zZXEpOworICAgIFB5T2JqZWN0X0dDX0RlbChpdCk7Cit9CisKK3N0YXRpYyBpbnQKK2J5dGVhcnJheWl0ZXJfdHJhdmVyc2UoYnl0ZXNpdGVyb2JqZWN0ICppdCwgdmlzaXRwcm9jIHZpc2l0LCB2b2lkICphcmcpCit7CisgICAgUHlfVklTSVQoaXQtPml0X3NlcSk7CisgICAgcmV0dXJuIDA7Cit9CisKK3N0YXRpYyBQeU9iamVjdCAqCitieXRlYXJyYXlpdGVyX25leHQoYnl0ZXNpdGVyb2JqZWN0ICppdCkKK3sKKyAgICBQeUJ5dGVBcnJheU9iamVjdCAqc2VxOworICAgIFB5T2JqZWN0ICppdGVtOworCisgICAgYXNzZXJ0KGl0ICE9IE5VTEwpOworICAgIHNlcSA9IGl0LT5pdF9zZXE7CisgICAgaWYgKHNlcSA9PSBOVUxMKQorICAgICAgICByZXR1cm4gTlVMTDsKKyAgICBhc3NlcnQoUHlCeXRlQXJyYXlfQ2hlY2soc2VxKSk7CisKKyAgICBpZiAoaXQtPml0X2luZGV4IDwgUHlCeXRlQXJyYXlfR0VUX1NJWkUoc2VxKSkgeworICAgICAgICBpdGVtID0gUHlJbnRfRnJvbUxvbmcoCisgICAgICAgICAgICAodW5zaWduZWQgY2hhcilzZXEtPm9iX2J5dGVzW2l0LT5pdF9pbmRleF0pOworICAgICAgICBpZiAoaXRlbSAhPSBOVUxMKQorICAgICAgICAgICAgKytpdC0+aXRfaW5kZXg7CisgICAgICAgIHJldHVybiBpdGVtOworICAgIH0KKworICAgIFB5X0RFQ1JFRihzZXEpOworICAgIGl0LT5pdF9zZXEgPSBOVUxMOworICAgIHJldHVybiBOVUxMOworfQorCitzdGF0aWMgUHlPYmplY3QgKgorYnl0ZXNhcnJheWl0ZXJfbGVuZ3RoX2hpbnQoYnl0ZXNpdGVyb2JqZWN0ICppdCkKK3sKKyAgICBQeV9zc2l6ZV90IGxlbiA9IDA7CisgICAgaWYgKGl0LT5pdF9zZXEpCisgICAgICAgIGxlbiA9IFB5Qnl0ZUFycmF5X0dFVF9TSVpFKGl0LT5pdF9zZXEpIC0gaXQtPml0X2luZGV4OworICAgIHJldHVybiBQeUludF9Gcm9tU3NpemVfdChsZW4pOworfQorCitQeURvY19TVFJWQVIobGVuZ3RoX2hpbnRfZG9jLAorICAgICJQcml2YXRlIG1ldGhvZCByZXR1cm5pbmcgYW4gZXN0aW1hdGUgb2YgbGVuKGxpc3QoaXQpKS4iKTsKKworc3RhdGljIFB5TWV0aG9kRGVmIGJ5dGVhcnJheWl0ZXJfbWV0aG9kc1tdID0geworICAgIHsiX19sZW5ndGhfaGludF9fIiwgKFB5Q0Z1bmN0aW9uKWJ5dGVzYXJyYXlpdGVyX2xlbmd0aF9oaW50LCBNRVRIX05PQVJHUywKKyAgICAgbGVuZ3RoX2hpbnRfZG9jfSwKKyAgICB7TlVMTCwgTlVMTH0gLyogc2VudGluZWwgKi8KK307CisKK1B5VHlwZU9iamVjdCBQeUJ5dGVBcnJheUl0ZXJfVHlwZSA9IHsKKyAgICBQeVZhck9iamVjdF9IRUFEX0lOSVQoJlB5VHlwZV9UeXBlLCAwKQorICAgICJieXRlYXJyYXlfaXRlcmF0b3IiLCAgICAgICAgICAgICAgLyogdHBfbmFtZSAqLworICAgIHNpemVvZihieXRlc2l0ZXJvYmplY3QpLCAgICAgICAgICAgLyogdHBfYmFzaWNzaXplICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9pdGVtc2l6ZSAqLworICAgIC8qIG1ldGhvZHMgKi8KKyAgICAoZGVzdHJ1Y3RvcilieXRlYXJyYXlpdGVyX2RlYWxsb2MsIC8qIHRwX2RlYWxsb2MgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3ByaW50ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9nZXRhdHRyICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9zZXRhdHRyICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9jb21wYXJlICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9yZXByICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9hc19udW1iZXIgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2FzX3NlcXVlbmNlICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9hc19tYXBwaW5nICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9oYXNoICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9jYWxsICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9zdHIgKi8KKyAgICBQeU9iamVjdF9HZW5lcmljR2V0QXR0ciwgICAgICAgICAgIC8qIHRwX2dldGF0dHJvICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9zZXRhdHRybyAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfYXNfYnVmZmVyICovCisgICAgUHlfVFBGTEFHU19ERUZBVUxUIHwgUHlfVFBGTEFHU19IQVZFX0dDLCAvKiB0cF9mbGFncyAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZG9jICovCisgICAgKHRyYXZlcnNlcHJvYylieXRlYXJyYXlpdGVyX3RyYXZlcnNlLCAgLyogdHBfdHJhdmVyc2UgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2NsZWFyICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9yaWNoY29tcGFyZSAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfd2Vha2xpc3RvZmZzZXQgKi8KKyAgICBQeU9iamVjdF9TZWxmSXRlciwgICAgICAgICAgICAgICAgIC8qIHRwX2l0ZXIgKi8KKyAgICAoaXRlcm5leHRmdW5jKWJ5dGVhcnJheWl0ZXJfbmV4dCwgIC8qIHRwX2l0ZXJuZXh0ICovCisgICAgYnl0ZWFycmF5aXRlcl9tZXRob2RzLCAgICAgICAgICAgICAvKiB0cF9tZXRob2RzICovCisgICAgMCwKK307CisKK3N0YXRpYyBQeU9iamVjdCAqCitieXRlYXJyYXlfaXRlcihQeU9iamVjdCAqc2VxKQoreworICAgIGJ5dGVzaXRlcm9iamVjdCAqaXQ7CisKKyAgICBpZiAoIVB5Qnl0ZUFycmF5X0NoZWNrKHNlcSkpIHsKKyAgICAgICAgUHlFcnJfQmFkSW50ZXJuYWxDYWxsKCk7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICBpdCA9IFB5T2JqZWN0X0dDX05ldyhieXRlc2l0ZXJvYmplY3QsICZQeUJ5dGVBcnJheUl0ZXJfVHlwZSk7CisgICAgaWYgKGl0ID09IE5VTEwpCisgICAgICAgIHJldHVybiBOVUxMOworICAgIGl0LT5pdF9pbmRleCA9IDA7CisgICAgUHlfSU5DUkVGKHNlcSk7CisgICAgaXQtPml0X3NlcSA9IChQeUJ5dGVBcnJheU9iamVjdCAqKXNlcTsKKyAgICBfUHlPYmplY3RfR0NfVFJBQ0soaXQpOworICAgIHJldHVybiAoUHlPYmplY3QgKilpdDsKK30KZGlmZiAtLWdpdCBhL1B5dGhvbi0yLjcuNS9PYmplY3RzL2J5dGVzX21ldGhvZHMuYyBiL1B5dGhvbi0yLjcuNS9PYmplY3RzL2J5dGVzX21ldGhvZHMuYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4xNDA2YWMxCi0tLSAvZGV2L251bGwKKysrIGIvUHl0aG9uLTIuNy41L09iamVjdHMvYnl0ZXNfbWV0aG9kcy5jCkBAIC0wLDAgKzEsMzk4IEBACisjaW5jbHVkZSAiUHl0aG9uLmgiCisjaW5jbHVkZSAiYnl0ZXNfbWV0aG9kcy5oIgorCitQeURvY19TVFJWQVJfc2hhcmVkKF9QeV9pc3NwYWNlX19kb2NfXywKKyJCLmlzc3BhY2UoKSAtPiBib29sXG5cCitcblwKK1JldHVybiBUcnVlIGlmIGFsbCBjaGFyYWN0ZXJzIGluIEIgYXJlIHdoaXRlc3BhY2VcblwKK2FuZCB0aGVyZSBpcyBhdCBsZWFzdCBvbmUgY2hhcmFjdGVyIGluIEIsIEZhbHNlIG90aGVyd2lzZS4iKTsKKworUHlPYmplY3QqCitfUHlfYnl0ZXNfaXNzcGFjZShjb25zdCBjaGFyICpjcHRyLCBQeV9zc2l6ZV90IGxlbikKK3sKKyAgICByZWdpc3RlciBjb25zdCB1bnNpZ25lZCBjaGFyICpwCisgICAgICAgID0gKHVuc2lnbmVkIGNoYXIgKikgY3B0cjsKKyAgICByZWdpc3RlciBjb25zdCB1bnNpZ25lZCBjaGFyICplOworCisgICAgLyogU2hvcnRjdXQgZm9yIHNpbmdsZSBjaGFyYWN0ZXIgc3RyaW5ncyAqLworICAgIGlmIChsZW4gPT0gMSAmJiBQeV9JU1NQQUNFKCpwKSkKKyAgICAgICAgUHlfUkVUVVJOX1RSVUU7CisKKyAgICAvKiBTcGVjaWFsIGNhc2UgZm9yIGVtcHR5IHN0cmluZ3MgKi8KKyAgICBpZiAobGVuID09IDApCisgICAgICAgIFB5X1JFVFVSTl9GQUxTRTsKKworICAgIGUgPSBwICsgbGVuOworICAgIGZvciAoOyBwIDwgZTsgcCsrKSB7CisgICAgICAgIGlmICghUHlfSVNTUEFDRSgqcCkpCisgICAgICAgICAgICBQeV9SRVRVUk5fRkFMU0U7CisgICAgfQorICAgIFB5X1JFVFVSTl9UUlVFOworfQorCisKK1B5RG9jX1NUUlZBUl9zaGFyZWQoX1B5X2lzYWxwaGFfX2RvY19fLAorIkIuaXNhbHBoYSgpIC0+IGJvb2xcblwKK1xuXAorUmV0dXJuIFRydWUgaWYgYWxsIGNoYXJhY3RlcnMgaW4gQiBhcmUgYWxwaGFiZXRpY1xuXAorYW5kIHRoZXJlIGlzIGF0IGxlYXN0IG9uZSBjaGFyYWN0ZXIgaW4gQiwgRmFsc2Ugb3RoZXJ3aXNlLiIpOworCitQeU9iamVjdCoKK19QeV9ieXRlc19pc2FscGhhKGNvbnN0IGNoYXIgKmNwdHIsIFB5X3NzaXplX3QgbGVuKQoreworICAgIHJlZ2lzdGVyIGNvbnN0IHVuc2lnbmVkIGNoYXIgKnAKKyAgICAgICAgPSAodW5zaWduZWQgY2hhciAqKSBjcHRyOworICAgIHJlZ2lzdGVyIGNvbnN0IHVuc2lnbmVkIGNoYXIgKmU7CisKKyAgICAvKiBTaG9ydGN1dCBmb3Igc2luZ2xlIGNoYXJhY3RlciBzdHJpbmdzICovCisgICAgaWYgKGxlbiA9PSAxICYmIFB5X0lTQUxQSEEoKnApKQorICAgICAgICBQeV9SRVRVUk5fVFJVRTsKKworICAgIC8qIFNwZWNpYWwgY2FzZSBmb3IgZW1wdHkgc3RyaW5ncyAqLworICAgIGlmIChsZW4gPT0gMCkKKyAgICAgICAgUHlfUkVUVVJOX0ZBTFNFOworCisgICAgZSA9IHAgKyBsZW47CisgICAgZm9yICg7IHAgPCBlOyBwKyspIHsKKyAgICAgICAgaWYgKCFQeV9JU0FMUEhBKCpwKSkKKyAgICAgICAgICAgIFB5X1JFVFVSTl9GQUxTRTsKKyAgICB9CisgICAgUHlfUkVUVVJOX1RSVUU7Cit9CisKKworUHlEb2NfU1RSVkFSX3NoYXJlZChfUHlfaXNhbG51bV9fZG9jX18sCisiQi5pc2FsbnVtKCkgLT4gYm9vbFxuXAorXG5cCitSZXR1cm4gVHJ1ZSBpZiBhbGwgY2hhcmFjdGVycyBpbiBCIGFyZSBhbHBoYW51bWVyaWNcblwKK2FuZCB0aGVyZSBpcyBhdCBsZWFzdCBvbmUgY2hhcmFjdGVyIGluIEIsIEZhbHNlIG90aGVyd2lzZS4iKTsKKworUHlPYmplY3QqCitfUHlfYnl0ZXNfaXNhbG51bShjb25zdCBjaGFyICpjcHRyLCBQeV9zc2l6ZV90IGxlbikKK3sKKyAgICByZWdpc3RlciBjb25zdCB1bnNpZ25lZCBjaGFyICpwCisgICAgICAgID0gKHVuc2lnbmVkIGNoYXIgKikgY3B0cjsKKyAgICByZWdpc3RlciBjb25zdCB1bnNpZ25lZCBjaGFyICplOworCisgICAgLyogU2hvcnRjdXQgZm9yIHNpbmdsZSBjaGFyYWN0ZXIgc3RyaW5ncyAqLworICAgIGlmIChsZW4gPT0gMSAmJiBQeV9JU0FMTlVNKCpwKSkKKyAgICAgICAgUHlfUkVUVVJOX1RSVUU7CisKKyAgICAvKiBTcGVjaWFsIGNhc2UgZm9yIGVtcHR5IHN0cmluZ3MgKi8KKyAgICBpZiAobGVuID09IDApCisgICAgICAgIFB5X1JFVFVSTl9GQUxTRTsKKworICAgIGUgPSBwICsgbGVuOworICAgIGZvciAoOyBwIDwgZTsgcCsrKSB7CisgICAgICAgIGlmICghUHlfSVNBTE5VTSgqcCkpCisgICAgICAgICAgICBQeV9SRVRVUk5fRkFMU0U7CisgICAgfQorICAgIFB5X1JFVFVSTl9UUlVFOworfQorCisKK1B5RG9jX1NUUlZBUl9zaGFyZWQoX1B5X2lzZGlnaXRfX2RvY19fLAorIkIuaXNkaWdpdCgpIC0+IGJvb2xcblwKK1xuXAorUmV0dXJuIFRydWUgaWYgYWxsIGNoYXJhY3RlcnMgaW4gQiBhcmUgZGlnaXRzXG5cCithbmQgdGhlcmUgaXMgYXQgbGVhc3Qgb25lIGNoYXJhY3RlciBpbiBCLCBGYWxzZSBvdGhlcndpc2UuIik7CisKK1B5T2JqZWN0KgorX1B5X2J5dGVzX2lzZGlnaXQoY29uc3QgY2hhciAqY3B0ciwgUHlfc3NpemVfdCBsZW4pCit7CisgICAgcmVnaXN0ZXIgY29uc3QgdW5zaWduZWQgY2hhciAqcAorICAgICAgICA9ICh1bnNpZ25lZCBjaGFyICopIGNwdHI7CisgICAgcmVnaXN0ZXIgY29uc3QgdW5zaWduZWQgY2hhciAqZTsKKworICAgIC8qIFNob3J0Y3V0IGZvciBzaW5nbGUgY2hhcmFjdGVyIHN0cmluZ3MgKi8KKyAgICBpZiAobGVuID09IDEgJiYgUHlfSVNESUdJVCgqcCkpCisgICAgICAgIFB5X1JFVFVSTl9UUlVFOworCisgICAgLyogU3BlY2lhbCBjYXNlIGZvciBlbXB0eSBzdHJpbmdzICovCisgICAgaWYgKGxlbiA9PSAwKQorICAgICAgICBQeV9SRVRVUk5fRkFMU0U7CisKKyAgICBlID0gcCArIGxlbjsKKyAgICBmb3IgKDsgcCA8IGU7IHArKykgeworICAgICAgICBpZiAoIVB5X0lTRElHSVQoKnApKQorICAgICAgICAgICAgUHlfUkVUVVJOX0ZBTFNFOworICAgIH0KKyAgICBQeV9SRVRVUk5fVFJVRTsKK30KKworCitQeURvY19TVFJWQVJfc2hhcmVkKF9QeV9pc2xvd2VyX19kb2NfXywKKyJCLmlzbG93ZXIoKSAtPiBib29sXG5cCitcblwKK1JldHVybiBUcnVlIGlmIGFsbCBjYXNlZCBjaGFyYWN0ZXJzIGluIEIgYXJlIGxvd2VyY2FzZSBhbmQgdGhlcmUgaXNcblwKK2F0IGxlYXN0IG9uZSBjYXNlZCBjaGFyYWN0ZXIgaW4gQiwgRmFsc2Ugb3RoZXJ3aXNlLiIpOworCitQeU9iamVjdCoKK19QeV9ieXRlc19pc2xvd2VyKGNvbnN0IGNoYXIgKmNwdHIsIFB5X3NzaXplX3QgbGVuKQoreworICAgIHJlZ2lzdGVyIGNvbnN0IHVuc2lnbmVkIGNoYXIgKnAKKyAgICAgICAgPSAodW5zaWduZWQgY2hhciAqKSBjcHRyOworICAgIHJlZ2lzdGVyIGNvbnN0IHVuc2lnbmVkIGNoYXIgKmU7CisgICAgaW50IGNhc2VkOworCisgICAgLyogU2hvcnRjdXQgZm9yIHNpbmdsZSBjaGFyYWN0ZXIgc3RyaW5ncyAqLworICAgIGlmIChsZW4gPT0gMSkKKyAgICAgICAgcmV0dXJuIFB5Qm9vbF9Gcm9tTG9uZyhQeV9JU0xPV0VSKCpwKSk7CisKKyAgICAvKiBTcGVjaWFsIGNhc2UgZm9yIGVtcHR5IHN0cmluZ3MgKi8KKyAgICBpZiAobGVuID09IDApCisgICAgICAgIFB5X1JFVFVSTl9GQUxTRTsKKworICAgIGUgPSBwICsgbGVuOworICAgIGNhc2VkID0gMDsKKyAgICBmb3IgKDsgcCA8IGU7IHArKykgeworICAgICAgICBpZiAoUHlfSVNVUFBFUigqcCkpCisgICAgICAgICAgICBQeV9SRVRVUk5fRkFMU0U7CisgICAgICAgIGVsc2UgaWYgKCFjYXNlZCAmJiBQeV9JU0xPV0VSKCpwKSkKKyAgICAgICAgICAgIGNhc2VkID0gMTsKKyAgICB9CisgICAgcmV0dXJuIFB5Qm9vbF9Gcm9tTG9uZyhjYXNlZCk7Cit9CisKKworUHlEb2NfU1RSVkFSX3NoYXJlZChfUHlfaXN1cHBlcl9fZG9jX18sCisiQi5pc3VwcGVyKCkgLT4gYm9vbFxuXAorXG5cCitSZXR1cm4gVHJ1ZSBpZiBhbGwgY2FzZWQgY2hhcmFjdGVycyBpbiBCIGFyZSB1cHBlcmNhc2UgYW5kIHRoZXJlIGlzXG5cCithdCBsZWFzdCBvbmUgY2FzZWQgY2hhcmFjdGVyIGluIEIsIEZhbHNlIG90aGVyd2lzZS4iKTsKKworUHlPYmplY3QqCitfUHlfYnl0ZXNfaXN1cHBlcihjb25zdCBjaGFyICpjcHRyLCBQeV9zc2l6ZV90IGxlbikKK3sKKyAgICByZWdpc3RlciBjb25zdCB1bnNpZ25lZCBjaGFyICpwCisgICAgICAgID0gKHVuc2lnbmVkIGNoYXIgKikgY3B0cjsKKyAgICByZWdpc3RlciBjb25zdCB1bnNpZ25lZCBjaGFyICplOworICAgIGludCBjYXNlZDsKKworICAgIC8qIFNob3J0Y3V0IGZvciBzaW5nbGUgY2hhcmFjdGVyIHN0cmluZ3MgKi8KKyAgICBpZiAobGVuID09IDEpCisgICAgICAgIHJldHVybiBQeUJvb2xfRnJvbUxvbmcoUHlfSVNVUFBFUigqcCkpOworCisgICAgLyogU3BlY2lhbCBjYXNlIGZvciBlbXB0eSBzdHJpbmdzICovCisgICAgaWYgKGxlbiA9PSAwKQorICAgICAgICBQeV9SRVRVUk5fRkFMU0U7CisKKyAgICBlID0gcCArIGxlbjsKKyAgICBjYXNlZCA9IDA7CisgICAgZm9yICg7IHAgPCBlOyBwKyspIHsKKyAgICAgICAgaWYgKFB5X0lTTE9XRVIoKnApKQorICAgICAgICAgICAgUHlfUkVUVVJOX0ZBTFNFOworICAgICAgICBlbHNlIGlmICghY2FzZWQgJiYgUHlfSVNVUFBFUigqcCkpCisgICAgICAgICAgICBjYXNlZCA9IDE7CisgICAgfQorICAgIHJldHVybiBQeUJvb2xfRnJvbUxvbmcoY2FzZWQpOworfQorCisKK1B5RG9jX1NUUlZBUl9zaGFyZWQoX1B5X2lzdGl0bGVfX2RvY19fLAorIkIuaXN0aXRsZSgpIC0+IGJvb2xcblwKK1xuXAorUmV0dXJuIFRydWUgaWYgQiBpcyBhIHRpdGxlY2FzZWQgc3RyaW5nIGFuZCB0aGVyZSBpcyBhdCBsZWFzdCBvbmVcblwKK2NoYXJhY3RlciBpbiBCLCBpLmUuIHVwcGVyY2FzZSBjaGFyYWN0ZXJzIG1heSBvbmx5IGZvbGxvdyB1bmNhc2VkXG5cCitjaGFyYWN0ZXJzIGFuZCBsb3dlcmNhc2UgY2hhcmFjdGVycyBvbmx5IGNhc2VkIG9uZXMuIFJldHVybiBGYWxzZVxuXAorb3RoZXJ3aXNlLiIpOworCitQeU9iamVjdCoKK19QeV9ieXRlc19pc3RpdGxlKGNvbnN0IGNoYXIgKmNwdHIsIFB5X3NzaXplX3QgbGVuKQoreworICAgIHJlZ2lzdGVyIGNvbnN0IHVuc2lnbmVkIGNoYXIgKnAKKyAgICAgICAgPSAodW5zaWduZWQgY2hhciAqKSBjcHRyOworICAgIHJlZ2lzdGVyIGNvbnN0IHVuc2lnbmVkIGNoYXIgKmU7CisgICAgaW50IGNhc2VkLCBwcmV2aW91c19pc19jYXNlZDsKKworICAgIC8qIFNob3J0Y3V0IGZvciBzaW5nbGUgY2hhcmFjdGVyIHN0cmluZ3MgKi8KKyAgICBpZiAobGVuID09IDEpCisgICAgICAgIHJldHVybiBQeUJvb2xfRnJvbUxvbmcoUHlfSVNVUFBFUigqcCkpOworCisgICAgLyogU3BlY2lhbCBjYXNlIGZvciBlbXB0eSBzdHJpbmdzICovCisgICAgaWYgKGxlbiA9PSAwKQorICAgICAgICBQeV9SRVRVUk5fRkFMU0U7CisKKyAgICBlID0gcCArIGxlbjsKKyAgICBjYXNlZCA9IDA7CisgICAgcHJldmlvdXNfaXNfY2FzZWQgPSAwOworICAgIGZvciAoOyBwIDwgZTsgcCsrKSB7CisgICAgICAgIHJlZ2lzdGVyIGNvbnN0IHVuc2lnbmVkIGNoYXIgY2ggPSAqcDsKKworICAgICAgICBpZiAoUHlfSVNVUFBFUihjaCkpIHsKKyAgICAgICAgICAgIGlmIChwcmV2aW91c19pc19jYXNlZCkKKyAgICAgICAgICAgICAgICBQeV9SRVRVUk5fRkFMU0U7CisgICAgICAgICAgICBwcmV2aW91c19pc19jYXNlZCA9IDE7CisgICAgICAgICAgICBjYXNlZCA9IDE7CisgICAgICAgIH0KKyAgICAgICAgZWxzZSBpZiAoUHlfSVNMT1dFUihjaCkpIHsKKyAgICAgICAgICAgIGlmICghcHJldmlvdXNfaXNfY2FzZWQpCisgICAgICAgICAgICAgICAgUHlfUkVUVVJOX0ZBTFNFOworICAgICAgICAgICAgcHJldmlvdXNfaXNfY2FzZWQgPSAxOworICAgICAgICAgICAgY2FzZWQgPSAxOworICAgICAgICB9CisgICAgICAgIGVsc2UKKyAgICAgICAgICAgIHByZXZpb3VzX2lzX2Nhc2VkID0gMDsKKyAgICB9CisgICAgcmV0dXJuIFB5Qm9vbF9Gcm9tTG9uZyhjYXNlZCk7Cit9CisKKworUHlEb2NfU1RSVkFSX3NoYXJlZChfUHlfbG93ZXJfX2RvY19fLAorIkIubG93ZXIoKSAtPiBjb3B5IG9mIEJcblwKK1xuXAorUmV0dXJuIGEgY29weSBvZiBCIHdpdGggYWxsIEFTQ0lJIGNoYXJhY3RlcnMgY29udmVydGVkIHRvIGxvd2VyY2FzZS4iKTsKKwordm9pZAorX1B5X2J5dGVzX2xvd2VyKGNoYXIgKnJlc3VsdCwgY29uc3QgY2hhciAqY3B0ciwgUHlfc3NpemVfdCBsZW4pCit7CisgICAgICAgIFB5X3NzaXplX3QgaTsKKworICAgICAgICAvKgorICAgICAgICBuZXdvYmogPSBQeVN0cmluZ19Gcm9tU3RyaW5nQW5kU2l6ZShOVUxMLCBsZW4pOworICAgICAgICBpZiAoIW5ld29iaikKKyAgICAgICAgICAgICAgICByZXR1cm4gTlVMTDsKKworICAgICAgICBzID0gUHlTdHJpbmdfQVNfU1RSSU5HKG5ld29iaik7CisgICAgICAgICovCisKKyAgICAgICAgUHlfTUVNQ1BZKHJlc3VsdCwgY3B0ciwgbGVuKTsKKworICAgICAgICBmb3IgKGkgPSAwOyBpIDwgbGVuOyBpKyspIHsKKyAgICAgICAgICAgICAgICBpbnQgYyA9IFB5X0NIQVJNQVNLKHJlc3VsdFtpXSk7CisgICAgICAgICAgICAgICAgaWYgKFB5X0lTVVBQRVIoYykpCisgICAgICAgICAgICAgICAgICAgICAgICByZXN1bHRbaV0gPSBQeV9UT0xPV0VSKGMpOworICAgICAgICB9Cit9CisKKworUHlEb2NfU1RSVkFSX3NoYXJlZChfUHlfdXBwZXJfX2RvY19fLAorIkIudXBwZXIoKSAtPiBjb3B5IG9mIEJcblwKK1xuXAorUmV0dXJuIGEgY29weSBvZiBCIHdpdGggYWxsIEFTQ0lJIGNoYXJhY3RlcnMgY29udmVydGVkIHRvIHVwcGVyY2FzZS4iKTsKKwordm9pZAorX1B5X2J5dGVzX3VwcGVyKGNoYXIgKnJlc3VsdCwgY29uc3QgY2hhciAqY3B0ciwgUHlfc3NpemVfdCBsZW4pCit7CisgICAgICAgIFB5X3NzaXplX3QgaTsKKworICAgICAgICAvKgorICAgICAgICBuZXdvYmogPSBQeVN0cmluZ19Gcm9tU3RyaW5nQW5kU2l6ZShOVUxMLCBsZW4pOworICAgICAgICBpZiAoIW5ld29iaikKKyAgICAgICAgICAgICAgICByZXR1cm4gTlVMTDsKKworICAgICAgICBzID0gUHlTdHJpbmdfQVNfU1RSSU5HKG5ld29iaik7CisgICAgICAgICovCisKKyAgICAgICAgUHlfTUVNQ1BZKHJlc3VsdCwgY3B0ciwgbGVuKTsKKworICAgICAgICBmb3IgKGkgPSAwOyBpIDwgbGVuOyBpKyspIHsKKyAgICAgICAgICAgICAgICBpbnQgYyA9IFB5X0NIQVJNQVNLKHJlc3VsdFtpXSk7CisgICAgICAgICAgICAgICAgaWYgKFB5X0lTTE9XRVIoYykpCisgICAgICAgICAgICAgICAgICAgICAgICByZXN1bHRbaV0gPSBQeV9UT1VQUEVSKGMpOworICAgICAgICB9Cit9CisKKworUHlEb2NfU1RSVkFSX3NoYXJlZChfUHlfdGl0bGVfX2RvY19fLAorIkIudGl0bGUoKSAtPiBjb3B5IG9mIEJcblwKK1xuXAorUmV0dXJuIGEgdGl0bGVjYXNlZCB2ZXJzaW9uIG9mIEIsIGkuZS4gQVNDSUkgd29yZHMgc3RhcnQgd2l0aCB1cHBlcmNhc2VcblwKK2NoYXJhY3RlcnMsIGFsbCByZW1haW5pbmcgY2FzZWQgY2hhcmFjdGVycyBoYXZlIGxvd2VyY2FzZS4iKTsKKwordm9pZAorX1B5X2J5dGVzX3RpdGxlKGNoYXIgKnJlc3VsdCwgY2hhciAqcywgUHlfc3NpemVfdCBsZW4pCit7CisgICAgICAgIFB5X3NzaXplX3QgaTsKKyAgICAgICAgaW50IHByZXZpb3VzX2lzX2Nhc2VkID0gMDsKKworICAgICAgICAvKgorICAgICAgICBuZXdvYmogPSBQeVN0cmluZ19Gcm9tU3RyaW5nQW5kU2l6ZShOVUxMLCBsZW4pOworICAgICAgICBpZiAobmV3b2JqID09IE5VTEwpCisgICAgICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgICAgIHNfbmV3ID0gUHlTdHJpbmdfQXNTdHJpbmcobmV3b2JqKTsKKyAgICAgICAgKi8KKyAgICAgICAgZm9yIChpID0gMDsgaSA8IGxlbjsgaSsrKSB7CisgICAgICAgICAgICAgICAgaW50IGMgPSBQeV9DSEFSTUFTSygqcysrKTsKKyAgICAgICAgICAgICAgICBpZiAoUHlfSVNMT1dFUihjKSkgeworICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFwcmV2aW91c19pc19jYXNlZCkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBjID0gUHlfVE9VUFBFUihjKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIHByZXZpb3VzX2lzX2Nhc2VkID0gMTsKKyAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKFB5X0lTVVBQRVIoYykpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGlmIChwcmV2aW91c19pc19jYXNlZCkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBjID0gUHlfVE9MT1dFUihjKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIHByZXZpb3VzX2lzX2Nhc2VkID0gMTsKKyAgICAgICAgICAgICAgICB9IGVsc2UKKyAgICAgICAgICAgICAgICAgICAgICAgIHByZXZpb3VzX2lzX2Nhc2VkID0gMDsKKyAgICAgICAgICAgICAgICAqcmVzdWx0KysgPSBjOworICAgICAgICB9Cit9CisKKworUHlEb2NfU1RSVkFSX3NoYXJlZChfUHlfY2FwaXRhbGl6ZV9fZG9jX18sCisiQi5jYXBpdGFsaXplKCkgLT4gY29weSBvZiBCXG5cCitcblwKK1JldHVybiBhIGNvcHkgb2YgQiB3aXRoIG9ubHkgaXRzIGZpcnN0IGNoYXJhY3RlciBjYXBpdGFsaXplZCAoQVNDSUkpXG5cCithbmQgdGhlIHJlc3QgbG93ZXItY2FzZWQuIik7CisKK3ZvaWQKK19QeV9ieXRlc19jYXBpdGFsaXplKGNoYXIgKnJlc3VsdCwgY2hhciAqcywgUHlfc3NpemVfdCBsZW4pCit7CisgICAgICAgIFB5X3NzaXplX3QgaTsKKworICAgICAgICAvKgorICAgICAgICBuZXdvYmogPSBQeVN0cmluZ19Gcm9tU3RyaW5nQW5kU2l6ZShOVUxMLCBsZW4pOworICAgICAgICBpZiAobmV3b2JqID09IE5VTEwpCisgICAgICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgICAgIHNfbmV3ID0gUHlTdHJpbmdfQXNTdHJpbmcobmV3b2JqKTsKKyAgICAgICAgKi8KKyAgICAgICAgaWYgKDAgPCBsZW4pIHsKKyAgICAgICAgICAgICAgICBpbnQgYyA9IFB5X0NIQVJNQVNLKCpzKyspOworICAgICAgICAgICAgICAgIGlmIChQeV9JU0xPV0VSKGMpKQorICAgICAgICAgICAgICAgICAgICAgICAgKnJlc3VsdCA9IFB5X1RPVVBQRVIoYyk7CisgICAgICAgICAgICAgICAgZWxzZQorICAgICAgICAgICAgICAgICAgICAgICAgKnJlc3VsdCA9IGM7CisgICAgICAgICAgICAgICAgcmVzdWx0Kys7CisgICAgICAgIH0KKyAgICAgICAgZm9yIChpID0gMTsgaSA8IGxlbjsgaSsrKSB7CisgICAgICAgICAgICAgICAgaW50IGMgPSBQeV9DSEFSTUFTSygqcysrKTsKKyAgICAgICAgICAgICAgICBpZiAoUHlfSVNVUFBFUihjKSkKKyAgICAgICAgICAgICAgICAgICAgICAgICpyZXN1bHQgPSBQeV9UT0xPV0VSKGMpOworICAgICAgICAgICAgICAgIGVsc2UKKyAgICAgICAgICAgICAgICAgICAgICAgICpyZXN1bHQgPSBjOworICAgICAgICAgICAgICAgIHJlc3VsdCsrOworICAgICAgICB9Cit9CisKKworUHlEb2NfU1RSVkFSX3NoYXJlZChfUHlfc3dhcGNhc2VfX2RvY19fLAorIkIuc3dhcGNhc2UoKSAtPiBjb3B5IG9mIEJcblwKK1xuXAorUmV0dXJuIGEgY29weSBvZiBCIHdpdGggdXBwZXJjYXNlIEFTQ0lJIGNoYXJhY3RlcnMgY29udmVydGVkXG5cCit0byBsb3dlcmNhc2UgQVNDSUkgYW5kIHZpY2UgdmVyc2EuIik7CisKK3ZvaWQKK19QeV9ieXRlc19zd2FwY2FzZShjaGFyICpyZXN1bHQsIGNoYXIgKnMsIFB5X3NzaXplX3QgbGVuKQoreworICAgICAgICBQeV9zc2l6ZV90IGk7CisKKyAgICAgICAgLyoKKyAgICAgICAgbmV3b2JqID0gUHlTdHJpbmdfRnJvbVN0cmluZ0FuZFNpemUoTlVMTCwgbGVuKTsKKyAgICAgICAgaWYgKG5ld29iaiA9PSBOVUxMKQorICAgICAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgICAgICBzX25ldyA9IFB5U3RyaW5nX0FzU3RyaW5nKG5ld29iaik7CisgICAgICAgICovCisgICAgICAgIGZvciAoaSA9IDA7IGkgPCBsZW47IGkrKykgeworICAgICAgICAgICAgICAgIGludCBjID0gUHlfQ0hBUk1BU0soKnMrKyk7CisgICAgICAgICAgICAgICAgaWYgKFB5X0lTTE9XRVIoYykpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICpyZXN1bHQgPSBQeV9UT1VQUEVSKGMpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBlbHNlIGlmIChQeV9JU1VQUEVSKGMpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAqcmVzdWx0ID0gUHlfVE9MT1dFUihjKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgZWxzZQorICAgICAgICAgICAgICAgICAgICAgICAgKnJlc3VsdCA9IGM7CisgICAgICAgICAgICAgICAgcmVzdWx0Kys7CisgICAgICAgIH0KK30KKwpkaWZmIC0tZ2l0IGEvUHl0aG9uLTIuNy41L09iamVjdHMvY2Fwc3VsZS5jIGIvUHl0aG9uLTIuNy41L09iamVjdHMvY2Fwc3VsZS5jCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmVhMjBmODIKLS0tIC9kZXYvbnVsbAorKysgYi9QeXRob24tMi43LjUvT2JqZWN0cy9jYXBzdWxlLmMKQEAgLTAsMCArMSwzMjQgQEAKKy8qIFdyYXAgdm9pZCAqIHBvaW50ZXJzIHRvIGJlIHBhc3NlZCBiZXR3ZWVuIEMgbW9kdWxlcyAqLworCisjaW5jbHVkZSAiUHl0aG9uLmgiCisKKy8qIEludGVybmFsIHN0cnVjdHVyZSBvZiBQeUNhcHN1bGUgKi8KK3R5cGVkZWYgc3RydWN0IHsKKyAgICBQeU9iamVjdF9IRUFECisgICAgdm9pZCAqcG9pbnRlcjsKKyAgICBjb25zdCBjaGFyICpuYW1lOworICAgIHZvaWQgKmNvbnRleHQ7CisgICAgUHlDYXBzdWxlX0Rlc3RydWN0b3IgZGVzdHJ1Y3RvcjsKK30gUHlDYXBzdWxlOworCisKKworc3RhdGljIGludAorX2lzX2xlZ2FsX2NhcHN1bGUoUHlDYXBzdWxlICpjYXBzdWxlLCBjb25zdCBjaGFyICppbnZhbGlkX2NhcHN1bGUpCit7CisgICAgaWYgKCFjYXBzdWxlIHx8ICFQeUNhcHN1bGVfQ2hlY2tFeGFjdChjYXBzdWxlKSB8fCBjYXBzdWxlLT5wb2ludGVyID09IE5VTEwpIHsKKyAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1ZhbHVlRXJyb3IsIGludmFsaWRfY2Fwc3VsZSk7CisgICAgICAgIHJldHVybiAwOworICAgIH0KKyAgICByZXR1cm4gMTsKK30KKworI2RlZmluZSBpc19sZWdhbF9jYXBzdWxlKGNhcHN1bGUsIG5hbWUpIFwKKyAgICAoX2lzX2xlZ2FsX2NhcHN1bGUoY2Fwc3VsZSwgXAorICAgICBuYW1lICIgY2FsbGVkIHdpdGggaW52YWxpZCBQeUNhcHN1bGUgb2JqZWN0IikpCisKKworc3RhdGljIGludAorbmFtZV9tYXRjaGVzKGNvbnN0IGNoYXIgKm5hbWUxLCBjb25zdCBjaGFyICpuYW1lMikgeworICAgIC8qIGlmIGVpdGhlciBpcyBOVUxMLCAqLworICAgIGlmICghbmFtZTEgfHwgIW5hbWUyKSB7CisgICAgICAgIC8qIHRoZXkncmUgb25seSB0aGUgc2FtZSBpZiB0aGV5J3JlIGJvdGggTlVMTC4gKi8KKyAgICAgICAgcmV0dXJuIG5hbWUxID09IG5hbWUyOworICAgIH0KKyAgICByZXR1cm4gIXN0cmNtcChuYW1lMSwgbmFtZTIpOworfQorCisKKworUHlPYmplY3QgKgorUHlDYXBzdWxlX05ldyh2b2lkICpwb2ludGVyLCBjb25zdCBjaGFyICpuYW1lLCBQeUNhcHN1bGVfRGVzdHJ1Y3RvciBkZXN0cnVjdG9yKQoreworICAgIFB5Q2Fwc3VsZSAqY2Fwc3VsZTsKKworICAgIGlmICghcG9pbnRlcikgeworICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfVmFsdWVFcnJvciwgIlB5Q2Fwc3VsZV9OZXcgY2FsbGVkIHdpdGggbnVsbCBwb2ludGVyIik7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKworICAgIGNhcHN1bGUgPSBQeU9iamVjdF9ORVcoUHlDYXBzdWxlLCAmUHlDYXBzdWxlX1R5cGUpOworICAgIGlmIChjYXBzdWxlID09IE5VTEwpIHsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorCisgICAgY2Fwc3VsZS0+cG9pbnRlciA9IHBvaW50ZXI7CisgICAgY2Fwc3VsZS0+bmFtZSA9IG5hbWU7CisgICAgY2Fwc3VsZS0+Y29udGV4dCA9IE5VTEw7CisgICAgY2Fwc3VsZS0+ZGVzdHJ1Y3RvciA9IGRlc3RydWN0b3I7CisKKyAgICByZXR1cm4gKFB5T2JqZWN0ICopY2Fwc3VsZTsKK30KKworCitpbnQKK1B5Q2Fwc3VsZV9Jc1ZhbGlkKFB5T2JqZWN0ICpvLCBjb25zdCBjaGFyICpuYW1lKQoreworICAgIFB5Q2Fwc3VsZSAqY2Fwc3VsZSA9IChQeUNhcHN1bGUgKilvOworCisgICAgcmV0dXJuIChjYXBzdWxlICE9IE5VTEwgJiYKKyAgICAgICAgICAgIFB5Q2Fwc3VsZV9DaGVja0V4YWN0KGNhcHN1bGUpICYmCisgICAgICAgICAgICBjYXBzdWxlLT5wb2ludGVyICE9IE5VTEwgJiYKKyAgICAgICAgICAgIG5hbWVfbWF0Y2hlcyhjYXBzdWxlLT5uYW1lLCBuYW1lKSk7Cit9CisKKwordm9pZCAqCitQeUNhcHN1bGVfR2V0UG9pbnRlcihQeU9iamVjdCAqbywgY29uc3QgY2hhciAqbmFtZSkKK3sKKyAgICBQeUNhcHN1bGUgKmNhcHN1bGUgPSAoUHlDYXBzdWxlICopbzsKKworICAgIGlmICghaXNfbGVnYWxfY2Fwc3VsZShjYXBzdWxlLCAiUHlDYXBzdWxlX0dldFBvaW50ZXIiKSkgeworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisKKyAgICBpZiAoIW5hbWVfbWF0Y2hlcyhuYW1lLCBjYXBzdWxlLT5uYW1lKSkgeworICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfVmFsdWVFcnJvciwgIlB5Q2Fwc3VsZV9HZXRQb2ludGVyIGNhbGxlZCB3aXRoIGluY29ycmVjdCBuYW1lIik7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKworICAgIHJldHVybiBjYXBzdWxlLT5wb2ludGVyOworfQorCisKK2NvbnN0IGNoYXIgKgorUHlDYXBzdWxlX0dldE5hbWUoUHlPYmplY3QgKm8pCit7CisgICAgUHlDYXBzdWxlICpjYXBzdWxlID0gKFB5Q2Fwc3VsZSAqKW87CisKKyAgICBpZiAoIWlzX2xlZ2FsX2NhcHN1bGUoY2Fwc3VsZSwgIlB5Q2Fwc3VsZV9HZXROYW1lIikpIHsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIHJldHVybiBjYXBzdWxlLT5uYW1lOworfQorCisKK1B5Q2Fwc3VsZV9EZXN0cnVjdG9yCitQeUNhcHN1bGVfR2V0RGVzdHJ1Y3RvcihQeU9iamVjdCAqbykKK3sKKyAgICBQeUNhcHN1bGUgKmNhcHN1bGUgPSAoUHlDYXBzdWxlICopbzsKKworICAgIGlmICghaXNfbGVnYWxfY2Fwc3VsZShjYXBzdWxlLCAiUHlDYXBzdWxlX0dldERlc3RydWN0b3IiKSkgeworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgcmV0dXJuIGNhcHN1bGUtPmRlc3RydWN0b3I7Cit9CisKKwordm9pZCAqCitQeUNhcHN1bGVfR2V0Q29udGV4dChQeU9iamVjdCAqbykKK3sKKyAgICBQeUNhcHN1bGUgKmNhcHN1bGUgPSAoUHlDYXBzdWxlICopbzsKKworICAgIGlmICghaXNfbGVnYWxfY2Fwc3VsZShjYXBzdWxlLCAiUHlDYXBzdWxlX0dldENvbnRleHQiKSkgeworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgcmV0dXJuIGNhcHN1bGUtPmNvbnRleHQ7Cit9CisKKworaW50CitQeUNhcHN1bGVfU2V0UG9pbnRlcihQeU9iamVjdCAqbywgdm9pZCAqcG9pbnRlcikKK3sKKyAgICBQeUNhcHN1bGUgKmNhcHN1bGUgPSAoUHlDYXBzdWxlICopbzsKKworICAgIGlmICghcG9pbnRlcikgeworICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfVmFsdWVFcnJvciwgIlB5Q2Fwc3VsZV9TZXRQb2ludGVyIGNhbGxlZCB3aXRoIG51bGwgcG9pbnRlciIpOworICAgICAgICByZXR1cm4gLTE7CisgICAgfQorCisgICAgaWYgKCFpc19sZWdhbF9jYXBzdWxlKGNhcHN1bGUsICJQeUNhcHN1bGVfU2V0UG9pbnRlciIpKSB7CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisKKyAgICBjYXBzdWxlLT5wb2ludGVyID0gcG9pbnRlcjsKKyAgICByZXR1cm4gMDsKK30KKworCitpbnQKK1B5Q2Fwc3VsZV9TZXROYW1lKFB5T2JqZWN0ICpvLCBjb25zdCBjaGFyICpuYW1lKQoreworICAgIFB5Q2Fwc3VsZSAqY2Fwc3VsZSA9IChQeUNhcHN1bGUgKilvOworCisgICAgaWYgKCFpc19sZWdhbF9jYXBzdWxlKGNhcHN1bGUsICJQeUNhcHN1bGVfU2V0TmFtZSIpKSB7CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisKKyAgICBjYXBzdWxlLT5uYW1lID0gbmFtZTsKKyAgICByZXR1cm4gMDsKK30KKworCitpbnQKK1B5Q2Fwc3VsZV9TZXREZXN0cnVjdG9yKFB5T2JqZWN0ICpvLCBQeUNhcHN1bGVfRGVzdHJ1Y3RvciBkZXN0cnVjdG9yKQoreworICAgIFB5Q2Fwc3VsZSAqY2Fwc3VsZSA9IChQeUNhcHN1bGUgKilvOworCisgICAgaWYgKCFpc19sZWdhbF9jYXBzdWxlKGNhcHN1bGUsICJQeUNhcHN1bGVfU2V0RGVzdHJ1Y3RvciIpKSB7CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisKKyAgICBjYXBzdWxlLT5kZXN0cnVjdG9yID0gZGVzdHJ1Y3RvcjsKKyAgICByZXR1cm4gMDsKK30KKworCitpbnQKK1B5Q2Fwc3VsZV9TZXRDb250ZXh0KFB5T2JqZWN0ICpvLCB2b2lkICpjb250ZXh0KQoreworICAgIFB5Q2Fwc3VsZSAqY2Fwc3VsZSA9IChQeUNhcHN1bGUgKilvOworCisgICAgaWYgKCFpc19sZWdhbF9jYXBzdWxlKGNhcHN1bGUsICJQeUNhcHN1bGVfU2V0Q29udGV4dCIpKSB7CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisKKyAgICBjYXBzdWxlLT5jb250ZXh0ID0gY29udGV4dDsKKyAgICByZXR1cm4gMDsKK30KKworCit2b2lkICoKK1B5Q2Fwc3VsZV9JbXBvcnQoY29uc3QgY2hhciAqbmFtZSwgaW50IG5vX2Jsb2NrKQoreworICAgIFB5T2JqZWN0ICpvYmplY3QgPSBOVUxMOworICAgIHZvaWQgKnJldHVybl92YWx1ZSA9IE5VTEw7CisgICAgY2hhciAqdHJhY2U7CisgICAgc2l6ZV90IG5hbWVfbGVuZ3RoID0gKHN0cmxlbihuYW1lKSArIDEpICogc2l6ZW9mKGNoYXIpOworICAgIGNoYXIgKm5hbWVfZHVwID0gKGNoYXIgKilQeU1lbV9NQUxMT0MobmFtZV9sZW5ndGgpOworCisgICAgaWYgKCFuYW1lX2R1cCkgeworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisKKyAgICBtZW1jcHkobmFtZV9kdXAsIG5hbWUsIG5hbWVfbGVuZ3RoKTsKKworICAgIHRyYWNlID0gbmFtZV9kdXA7CisgICAgd2hpbGUgKHRyYWNlKSB7CisgICAgICAgIGNoYXIgKmRvdCA9IHN0cmNocih0cmFjZSwgJy4nKTsKKyAgICAgICAgaWYgKGRvdCkgeworICAgICAgICAgICAgKmRvdCsrID0gJ1wwJzsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChvYmplY3QgPT0gTlVMTCkgeworICAgICAgICAgICAgaWYgKG5vX2Jsb2NrKSB7CisgICAgICAgICAgICAgICAgb2JqZWN0ID0gUHlJbXBvcnRfSW1wb3J0TW9kdWxlTm9CbG9jayh0cmFjZSk7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIG9iamVjdCA9IFB5SW1wb3J0X0ltcG9ydE1vZHVsZSh0cmFjZSk7CisgICAgICAgICAgICAgICAgaWYgKCFvYmplY3QpIHsKKyAgICAgICAgICAgICAgICAgICAgUHlFcnJfRm9ybWF0KFB5RXhjX0ltcG9ydEVycm9yLCAiUHlDYXBzdWxlX0ltcG9ydCBjb3VsZCBub3QgaW1wb3J0IG1vZHVsZSBcIiVzXCIiLCB0cmFjZSk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgUHlPYmplY3QgKm9iamVjdDIgPSBQeU9iamVjdF9HZXRBdHRyU3RyaW5nKG9iamVjdCwgdHJhY2UpOworICAgICAgICAgICAgUHlfREVDUkVGKG9iamVjdCk7CisgICAgICAgICAgICBvYmplY3QgPSBvYmplY3QyOworICAgICAgICB9CisgICAgICAgIGlmICghb2JqZWN0KSB7CisgICAgICAgICAgICBnb3RvIEVYSVQ7CisgICAgICAgIH0KKworICAgICAgICB0cmFjZSA9IGRvdDsKKyAgICB9CisKKyAgICAvKiBjb21wYXJlIGF0dHJpYnV0ZSBuYW1lIHRvIG1vZHVsZS5uYW1lIGJ5IGhhbmQgKi8KKyAgICBpZiAoUHlDYXBzdWxlX0lzVmFsaWQob2JqZWN0LCBuYW1lKSkgeworICAgICAgICBQeUNhcHN1bGUgKmNhcHN1bGUgPSAoUHlDYXBzdWxlICopb2JqZWN0OworICAgICAgICByZXR1cm5fdmFsdWUgPSBjYXBzdWxlLT5wb2ludGVyOworICAgIH0gZWxzZSB7CisgICAgICAgIFB5RXJyX0Zvcm1hdChQeUV4Y19BdHRyaWJ1dGVFcnJvciwKKyAgICAgICAgICAgICJQeUNhcHN1bGVfSW1wb3J0IFwiJXNcIiBpcyBub3QgdmFsaWQiLAorICAgICAgICAgICAgbmFtZSk7CisgICAgfQorCitFWElUOgorICAgIFB5X1hERUNSRUYob2JqZWN0KTsKKyAgICBpZiAobmFtZV9kdXApIHsKKyAgICAgICAgUHlNZW1fRlJFRShuYW1lX2R1cCk7CisgICAgfQorICAgIHJldHVybiByZXR1cm5fdmFsdWU7Cit9CisKKworc3RhdGljIHZvaWQKK2NhcHN1bGVfZGVhbGxvYyhQeU9iamVjdCAqbykKK3sKKyAgICBQeUNhcHN1bGUgKmNhcHN1bGUgPSAoUHlDYXBzdWxlICopbzsKKyAgICBpZiAoY2Fwc3VsZS0+ZGVzdHJ1Y3RvcikgeworICAgICAgICBjYXBzdWxlLT5kZXN0cnVjdG9yKG8pOworICAgIH0KKyAgICBQeU9iamVjdF9ERUwobyk7Cit9CisKKworc3RhdGljIFB5T2JqZWN0ICoKK2NhcHN1bGVfcmVwcihQeU9iamVjdCAqbykKK3sKKyAgICBQeUNhcHN1bGUgKmNhcHN1bGUgPSAoUHlDYXBzdWxlICopbzsKKyAgICBjb25zdCBjaGFyICpuYW1lOworICAgIGNvbnN0IGNoYXIgKnF1b3RlOworCisgICAgaWYgKGNhcHN1bGUtPm5hbWUpIHsKKyAgICAgICAgcXVvdGUgPSAiXCIiOworICAgICAgICBuYW1lID0gY2Fwc3VsZS0+bmFtZTsKKyAgICB9IGVsc2UgeworICAgICAgICBxdW90ZSA9ICIiOworICAgICAgICBuYW1lID0gIk5VTEwiOworICAgIH0KKworICAgIHJldHVybiBQeVN0cmluZ19Gcm9tRm9ybWF0KCI8Y2Fwc3VsZSBvYmplY3QgJXMlcyVzIGF0ICVwPiIsCisgICAgICAgIHF1b3RlLCBuYW1lLCBxdW90ZSwgY2Fwc3VsZSk7Cit9CisKKworCitQeURvY19TVFJWQVIoUHlDYXBzdWxlX1R5cGVfX2RvY19fLAorIkNhcHN1bGUgb2JqZWN0cyBsZXQgeW91IHdyYXAgYSBDIFwidm9pZCAqXCIgcG9pbnRlciBpbiBhIFB5dGhvblxuXAorb2JqZWN0LiAgVGhleSdyZSBhIHdheSBvZiBwYXNzaW5nIGRhdGEgdGhyb3VnaCB0aGUgUHl0aG9uIGludGVycHJldGVyXG5cCit3aXRob3V0IGNyZWF0aW5nIHlvdXIgb3duIGN1c3RvbSB0eXBlLlxuXAorXG5cCitDYXBzdWxlcyBhcmUgdXNlZCBmb3IgY29tbXVuaWNhdGlvbiBiZXR3ZWVuIGV4dGVuc2lvbiBtb2R1bGVzLlxuXAorVGhleSBwcm92aWRlIGEgd2F5IGZvciBhbiBleHRlbnNpb24gbW9kdWxlIHRvIGV4cG9ydCBhIEMgaW50ZXJmYWNlXG5cCit0byBvdGhlciBleHRlbnNpb24gbW9kdWxlcywgc28gdGhhdCBleHRlbnNpb24gbW9kdWxlcyBjYW4gdXNlIHRoZVxuXAorUHl0aG9uIGltcG9ydCBtZWNoYW5pc20gdG8gbGluayB0byBvbmUgYW5vdGhlci5cblwKKyIpOworCitQeVR5cGVPYmplY3QgUHlDYXBzdWxlX1R5cGUgPSB7CisgICAgUHlWYXJPYmplY3RfSEVBRF9JTklUKCZQeVR5cGVfVHlwZSwgMCkKKyAgICAiUHlDYXBzdWxlIiwJCS8qdHBfbmFtZSovCisgICAgc2l6ZW9mKFB5Q2Fwc3VsZSksCQkvKnRwX2Jhc2ljc2l6ZSovCisgICAgMCwJCQkJLyp0cF9pdGVtc2l6ZSovCisgICAgLyogbWV0aG9kcyAqLworICAgIGNhcHN1bGVfZGVhbGxvYywgLyp0cF9kZWFsbG9jKi8KKyAgICAwLAkJCQkvKnRwX3ByaW50Ki8KKyAgICAwLAkJCQkvKnRwX2dldGF0dHIqLworICAgIDAsCQkJCS8qdHBfc2V0YXR0ciovCisgICAgMCwJCQkJLyp0cF9yZXNlcnZlZCovCisgICAgY2Fwc3VsZV9yZXByLCAvKnRwX3JlcHIqLworICAgIDAsCQkJCS8qdHBfYXNfbnVtYmVyKi8KKyAgICAwLAkJCQkvKnRwX2FzX3NlcXVlbmNlKi8KKyAgICAwLAkJCQkvKnRwX2FzX21hcHBpbmcqLworICAgIDAsCQkJCS8qdHBfaGFzaCovCisgICAgMCwJCQkJLyp0cF9jYWxsKi8KKyAgICAwLAkJCQkvKnRwX3N0ciovCisgICAgMCwJCQkJLyp0cF9nZXRhdHRybyovCisgICAgMCwJCQkJLyp0cF9zZXRhdHRybyovCisgICAgMCwJCQkJLyp0cF9hc19idWZmZXIqLworICAgIDAsCQkJCS8qdHBfZmxhZ3MqLworICAgIFB5Q2Fwc3VsZV9UeXBlX19kb2NfXwkvKnRwX2RvYyovCit9OworCisKZGlmZiAtLWdpdCBhL1B5dGhvbi0yLjcuNS9PYmplY3RzL2NlbGxvYmplY3QuYyBiL1B5dGhvbi0yLjcuNS9PYmplY3RzL2NlbGxvYmplY3QuYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kMGY2Y2RhCi0tLSAvZGV2L251bGwKKysrIGIvUHl0aG9uLTIuNy41L09iamVjdHMvY2VsbG9iamVjdC5jCkBAIC0wLDAgKzEsMTQ1IEBACisvKiBDZWxsIG9iamVjdCBpbXBsZW1lbnRhdGlvbiAqLworCisjaW5jbHVkZSAiUHl0aG9uLmgiCisKK1B5T2JqZWN0ICoKK1B5Q2VsbF9OZXcoUHlPYmplY3QgKm9iaikKK3sKKyAgICBQeUNlbGxPYmplY3QgKm9wOworCisgICAgb3AgPSAoUHlDZWxsT2JqZWN0ICopUHlPYmplY3RfR0NfTmV3KFB5Q2VsbE9iamVjdCwgJlB5Q2VsbF9UeXBlKTsKKyAgICBpZiAob3AgPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgb3AtPm9iX3JlZiA9IG9iajsKKyAgICBQeV9YSU5DUkVGKG9iaik7CisKKyAgICBfUHlPYmplY3RfR0NfVFJBQ0sob3ApOworICAgIHJldHVybiAoUHlPYmplY3QgKilvcDsKK30KKworUHlPYmplY3QgKgorUHlDZWxsX0dldChQeU9iamVjdCAqb3ApCit7CisgICAgaWYgKCFQeUNlbGxfQ2hlY2sob3ApKSB7CisgICAgICAgIFB5RXJyX0JhZEludGVybmFsQ2FsbCgpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgUHlfWElOQ1JFRigoKFB5Q2VsbE9iamVjdCopb3ApLT5vYl9yZWYpOworICAgIHJldHVybiBQeUNlbGxfR0VUKG9wKTsKK30KKworaW50CitQeUNlbGxfU2V0KFB5T2JqZWN0ICpvcCwgUHlPYmplY3QgKm9iaikKK3sKKyAgICBQeU9iamVjdCogb2xkb2JqOworICAgIGlmICghUHlDZWxsX0NoZWNrKG9wKSkgeworICAgICAgICBQeUVycl9CYWRJbnRlcm5hbENhbGwoKTsKKyAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKyAgICBvbGRvYmogPSBQeUNlbGxfR0VUKG9wKTsKKyAgICBQeV9YSU5DUkVGKG9iaik7CisgICAgUHlDZWxsX1NFVChvcCwgb2JqKTsKKyAgICBQeV9YREVDUkVGKG9sZG9iaik7CisgICAgcmV0dXJuIDA7Cit9CisKK3N0YXRpYyB2b2lkCitjZWxsX2RlYWxsb2MoUHlDZWxsT2JqZWN0ICpvcCkKK3sKKyAgICBfUHlPYmplY3RfR0NfVU5UUkFDSyhvcCk7CisgICAgUHlfWERFQ1JFRihvcC0+b2JfcmVmKTsKKyAgICBQeU9iamVjdF9HQ19EZWwob3ApOworfQorCitzdGF0aWMgaW50CitjZWxsX2NvbXBhcmUoUHlDZWxsT2JqZWN0ICphLCBQeUNlbGxPYmplY3QgKmIpCit7CisgICAgLyogUHkzSyB3YXJuaW5nIGZvciBjb21wYXJpc29ucyAgKi8KKyAgICBpZiAoUHlFcnJfV2FyblB5M2soImNlbGwgY29tcGFyaXNvbnMgbm90IHN1cHBvcnRlZCBpbiAzLngiLAorICAgICAgICAgICAgICAgICAgICAgICAxKSA8IDApIHsKKyAgICAgICAgcmV0dXJuIC0yOworICAgIH0KKworICAgIGlmIChhLT5vYl9yZWYgPT0gTlVMTCkgeworICAgICAgICBpZiAoYi0+b2JfcmVmID09IE5VTEwpCisgICAgICAgICAgICByZXR1cm4gMDsKKyAgICAgICAgcmV0dXJuIC0xOworICAgIH0gZWxzZSBpZiAoYi0+b2JfcmVmID09IE5VTEwpCisgICAgICAgIHJldHVybiAxOworICAgIHJldHVybiBQeU9iamVjdF9Db21wYXJlKGEtPm9iX3JlZiwgYi0+b2JfcmVmKTsKK30KKworc3RhdGljIFB5T2JqZWN0ICoKK2NlbGxfcmVwcihQeUNlbGxPYmplY3QgKm9wKQoreworICAgIGlmIChvcC0+b2JfcmVmID09IE5VTEwpCisgICAgICAgIHJldHVybiBQeVN0cmluZ19Gcm9tRm9ybWF0KCI8Y2VsbCBhdCAlcDogZW1wdHk+Iiwgb3ApOworCisgICAgcmV0dXJuIFB5U3RyaW5nX0Zyb21Gb3JtYXQoIjxjZWxsIGF0ICVwOiAlLjgwcyBvYmplY3QgYXQgJXA+IiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcCwgb3AtPm9iX3JlZi0+b2JfdHlwZS0+dHBfbmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvcC0+b2JfcmVmKTsKK30KKworc3RhdGljIGludAorY2VsbF90cmF2ZXJzZShQeUNlbGxPYmplY3QgKm9wLCB2aXNpdHByb2MgdmlzaXQsIHZvaWQgKmFyZykKK3sKKyAgICBQeV9WSVNJVChvcC0+b2JfcmVmKTsKKyAgICByZXR1cm4gMDsKK30KKworc3RhdGljIGludAorY2VsbF9jbGVhcihQeUNlbGxPYmplY3QgKm9wKQoreworICAgIFB5X0NMRUFSKG9wLT5vYl9yZWYpOworICAgIHJldHVybiAwOworfQorCitzdGF0aWMgUHlPYmplY3QgKgorY2VsbF9nZXRfY29udGVudHMoUHlDZWxsT2JqZWN0ICpvcCwgdm9pZCAqY2xvc3VyZSkKK3sKKyAgICBpZiAob3AtPm9iX3JlZiA9PSBOVUxMKQorICAgIHsKKyAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1ZhbHVlRXJyb3IsICJDZWxsIGlzIGVtcHR5Iik7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICBQeV9JTkNSRUYob3AtPm9iX3JlZik7CisgICAgcmV0dXJuIG9wLT5vYl9yZWY7Cit9CisKK3N0YXRpYyBQeUdldFNldERlZiBjZWxsX2dldHNldGxpc3RbXSA9IHsKKyAgICB7ImNlbGxfY29udGVudHMiLCAoZ2V0dGVyKWNlbGxfZ2V0X2NvbnRlbnRzLCBOVUxMfSwKKyAgICB7TlVMTH0gLyogc2VudGluZWwgKi8KK307CisKK1B5VHlwZU9iamVjdCBQeUNlbGxfVHlwZSA9IHsKKyAgICBQeVZhck9iamVjdF9IRUFEX0lOSVQoJlB5VHlwZV9UeXBlLCAwKQorICAgICJjZWxsIiwKKyAgICBzaXplb2YoUHlDZWxsT2JqZWN0KSwKKyAgICAwLAorICAgIChkZXN0cnVjdG9yKWNlbGxfZGVhbGxvYywgICAgICAgICAgICAgICAvKiB0cF9kZWFsbG9jICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3ByaW50ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9nZXRhdHRyICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9zZXRhdHRyICovCisgICAgKGNtcGZ1bmMpY2VsbF9jb21wYXJlLCAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9jb21wYXJlICovCisgICAgKHJlcHJmdW5jKWNlbGxfcmVwciwgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9yZXByICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9hc19udW1iZXIgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2FzX3NlcXVlbmNlICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9hc19tYXBwaW5nICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9oYXNoICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9jYWxsICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9zdHIgKi8KKyAgICBQeU9iamVjdF9HZW5lcmljR2V0QXR0ciwgICAgICAgICAgICAgICAgICAgIC8qIHRwX2dldGF0dHJvICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9zZXRhdHRybyAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfYXNfYnVmZmVyICovCisgICAgUHlfVFBGTEFHU19ERUZBVUxUIHwgUHlfVFBGTEFHU19IQVZFX0dDLC8qIHRwX2ZsYWdzICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9kb2MgKi8KKyAgICAodHJhdmVyc2Vwcm9jKWNlbGxfdHJhdmVyc2UsICAgICAgICAgICAgICAgIC8qIHRwX3RyYXZlcnNlICovCisgICAgKGlucXVpcnkpY2VsbF9jbGVhciwgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9jbGVhciAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfcmljaGNvbXBhcmUgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3dlYWtsaXN0b2Zmc2V0ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9pdGVyICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9pdGVybmV4dCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfbWV0aG9kcyAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfbWVtYmVycyAqLworICAgIGNlbGxfZ2V0c2V0bGlzdCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZ2V0c2V0ICovCit9OwpkaWZmIC0tZ2l0IGEvUHl0aG9uLTIuNy41L09iamVjdHMvY2xhc3NvYmplY3QuYyBiL1B5dGhvbi0yLjcuNS9PYmplY3RzL2NsYXNzb2JqZWN0LmMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMmM5YzIxNgotLS0gL2Rldi9udWxsCisrKyBiL1B5dGhvbi0yLjcuNS9PYmplY3RzL2NsYXNzb2JqZWN0LmMKQEAgLTAsMCArMSwyNjk2IEBACisKKy8qIENsYXNzIG9iamVjdCBpbXBsZW1lbnRhdGlvbiAqLworCisjaW5jbHVkZSAiUHl0aG9uLmgiCisjaW5jbHVkZSAic3RydWN0bWVtYmVyLmgiCisKKy8qIEZyZWUgbGlzdCBmb3IgbWV0aG9kIG9iamVjdHMgdG8gc2FmZSBtYWxsb2MvZnJlZSBvdmVyaGVhZAorICogVGhlIGltX3NlbGYgZWxlbWVudCBpcyB1c2VkIHRvIGNoYWluIHRoZSBlbGVtZW50cy4KKyAqLworc3RhdGljIFB5TWV0aG9kT2JqZWN0ICpmcmVlX2xpc3Q7CitzdGF0aWMgaW50IG51bWZyZWUgPSAwOworI2lmbmRlZiBQeU1ldGhvZF9NQVhGUkVFTElTVAorI2RlZmluZSBQeU1ldGhvZF9NQVhGUkVFTElTVCAyNTYKKyNlbmRpZgorCisjZGVmaW5lIFRQX0RFU0NSX0dFVCh0KSBcCisgICAgKFB5VHlwZV9IYXNGZWF0dXJlKHQsIFB5X1RQRkxBR1NfSEFWRV9DTEFTUykgPyAodCktPnRwX2Rlc2NyX2dldCA6IE5VTEwpCisKKy8qIEZvcndhcmQgKi8KK3N0YXRpYyBQeU9iamVjdCAqY2xhc3NfbG9va3VwKFB5Q2xhc3NPYmplY3QgKiwgUHlPYmplY3QgKiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFB5Q2xhc3NPYmplY3QgKiopOworc3RhdGljIFB5T2JqZWN0ICppbnN0YW5jZV9nZXRhdHRyMShQeUluc3RhbmNlT2JqZWN0ICosIFB5T2JqZWN0ICopOworc3RhdGljIFB5T2JqZWN0ICppbnN0YW5jZV9nZXRhdHRyMihQeUluc3RhbmNlT2JqZWN0ICosIFB5T2JqZWN0ICopOworCitzdGF0aWMgUHlPYmplY3QgKmdldGF0dHJzdHIsICpzZXRhdHRyc3RyLCAqZGVsYXR0cnN0cjsKKworCitQeU9iamVjdCAqCitQeUNsYXNzX05ldyhQeU9iamVjdCAqYmFzZXMsIFB5T2JqZWN0ICpkaWN0LCBQeU9iamVjdCAqbmFtZSkKKyAgICAgLyogYmFzZXMgaXMgTlVMTCBvciB0dXBsZSBvZiBjbGFzc29iamVjdHMhICovCit7CisgICAgUHlDbGFzc09iamVjdCAqb3AsICpkdW1teTsKKyAgICBzdGF0aWMgUHlPYmplY3QgKmRvY3N0ciwgKm1vZHN0ciwgKm5hbWVzdHI7CisgICAgaWYgKGRvY3N0ciA9PSBOVUxMKSB7CisgICAgICAgIGRvY3N0cj0gUHlTdHJpbmdfSW50ZXJuRnJvbVN0cmluZygiX19kb2NfXyIpOworICAgICAgICBpZiAoZG9jc3RyID09IE5VTEwpCisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgaWYgKG1vZHN0ciA9PSBOVUxMKSB7CisgICAgICAgIG1vZHN0cj0gUHlTdHJpbmdfSW50ZXJuRnJvbVN0cmluZygiX19tb2R1bGVfXyIpOworICAgICAgICBpZiAobW9kc3RyID09IE5VTEwpCisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgaWYgKG5hbWVzdHIgPT0gTlVMTCkgeworICAgICAgICBuYW1lc3RyPSBQeVN0cmluZ19JbnRlcm5Gcm9tU3RyaW5nKCJfX25hbWVfXyIpOworICAgICAgICBpZiAobmFtZXN0ciA9PSBOVUxMKQorICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIGlmIChuYW1lID09IE5VTEwgfHwgIVB5U3RyaW5nX0NoZWNrKG5hbWUpKSB7CisgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19UeXBlRXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAgICAiUHlDbGFzc19OZXc6IG5hbWUgbXVzdCBiZSBhIHN0cmluZyIpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgaWYgKGRpY3QgPT0gTlVMTCB8fCAhUHlEaWN0X0NoZWNrKGRpY3QpKSB7CisgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19UeXBlRXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAgICAiUHlDbGFzc19OZXc6IGRpY3QgbXVzdCBiZSBhIGRpY3Rpb25hcnkiKTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIGlmIChQeURpY3RfR2V0SXRlbShkaWN0LCBkb2NzdHIpID09IE5VTEwpIHsKKyAgICAgICAgaWYgKFB5RGljdF9TZXRJdGVtKGRpY3QsIGRvY3N0ciwgUHlfTm9uZSkgPCAwKQorICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIGlmIChQeURpY3RfR2V0SXRlbShkaWN0LCBtb2RzdHIpID09IE5VTEwpIHsKKyAgICAgICAgUHlPYmplY3QgKmdsb2JhbHMgPSBQeUV2YWxfR2V0R2xvYmFscygpOworICAgICAgICBpZiAoZ2xvYmFscyAhPSBOVUxMKSB7CisgICAgICAgICAgICBQeU9iamVjdCAqbW9kbmFtZSA9IFB5RGljdF9HZXRJdGVtKGdsb2JhbHMsIG5hbWVzdHIpOworICAgICAgICAgICAgaWYgKG1vZG5hbWUgIT0gTlVMTCkgeworICAgICAgICAgICAgICAgIGlmIChQeURpY3RfU2V0SXRlbShkaWN0LCBtb2RzdHIsIG1vZG5hbWUpIDwgMCkKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisgICAgaWYgKGJhc2VzID09IE5VTEwpIHsKKyAgICAgICAgYmFzZXMgPSBQeVR1cGxlX05ldygwKTsKKyAgICAgICAgaWYgKGJhc2VzID09IE5VTEwpCisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgZWxzZSB7CisgICAgICAgIFB5X3NzaXplX3QgaSwgbjsKKyAgICAgICAgUHlPYmplY3QgKmJhc2U7CisgICAgICAgIGlmICghUHlUdXBsZV9DaGVjayhiYXNlcykpIHsKKyAgICAgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19UeXBlRXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlB5Q2xhc3NfTmV3OiBiYXNlcyBtdXN0IGJlIGEgdHVwbGUiKTsKKyAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgICAgICB9CisgICAgICAgIG4gPSBQeVR1cGxlX1NpemUoYmFzZXMpOworICAgICAgICBmb3IgKGkgPSAwOyBpIDwgbjsgaSsrKSB7CisgICAgICAgICAgICBiYXNlID0gUHlUdXBsZV9HRVRfSVRFTShiYXNlcywgaSk7CisgICAgICAgICAgICBpZiAoIVB5Q2xhc3NfQ2hlY2soYmFzZSkpIHsKKyAgICAgICAgICAgICAgICBpZiAoUHlDYWxsYWJsZV9DaGVjaygKKyAgICAgICAgICAgICAgICAgICAgKFB5T2JqZWN0ICopIGJhc2UtPm9iX3R5cGUpKQorICAgICAgICAgICAgICAgICAgICByZXR1cm4gUHlPYmplY3RfQ2FsbEZ1bmN0aW9uT2JqQXJncygKKyAgICAgICAgICAgICAgICAgICAgICAgIChQeU9iamVjdCAqKSBiYXNlLT5vYl90eXBlLAorICAgICAgICAgICAgICAgICAgICAgICAgbmFtZSwgYmFzZXMsIGRpY3QsIE5VTEwpOworICAgICAgICAgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19UeXBlRXJyb3IsCisgICAgICAgICAgICAgICAgICAgICJQeUNsYXNzX05ldzogYmFzZSBtdXN0IGJlIGEgY2xhc3MiKTsKKyAgICAgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBQeV9JTkNSRUYoYmFzZXMpOworICAgIH0KKworICAgIGlmIChnZXRhdHRyc3RyID09IE5VTEwpIHsKKyAgICAgICAgZ2V0YXR0cnN0ciA9IFB5U3RyaW5nX0ludGVybkZyb21TdHJpbmcoIl9fZ2V0YXR0cl9fIik7CisgICAgICAgIGlmIChnZXRhdHRyc3RyID09IE5VTEwpCisgICAgICAgICAgICBnb3RvIGFsbG9jX2Vycm9yOworICAgICAgICBzZXRhdHRyc3RyID0gUHlTdHJpbmdfSW50ZXJuRnJvbVN0cmluZygiX19zZXRhdHRyX18iKTsKKyAgICAgICAgaWYgKHNldGF0dHJzdHIgPT0gTlVMTCkKKyAgICAgICAgICAgIGdvdG8gYWxsb2NfZXJyb3I7CisgICAgICAgIGRlbGF0dHJzdHIgPSBQeVN0cmluZ19JbnRlcm5Gcm9tU3RyaW5nKCJfX2RlbGF0dHJfXyIpOworICAgICAgICBpZiAoZGVsYXR0cnN0ciA9PSBOVUxMKQorICAgICAgICAgICAgZ290byBhbGxvY19lcnJvcjsKKyAgICB9CisKKyAgICBvcCA9IFB5T2JqZWN0X0dDX05ldyhQeUNsYXNzT2JqZWN0LCAmUHlDbGFzc19UeXBlKTsKKyAgICBpZiAob3AgPT0gTlVMTCkgeworYWxsb2NfZXJyb3I6CisgICAgICAgIFB5X0RFQ1JFRihiYXNlcyk7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICBvcC0+Y2xfYmFzZXMgPSBiYXNlczsKKyAgICBQeV9JTkNSRUYoZGljdCk7CisgICAgb3AtPmNsX2RpY3QgPSBkaWN0OworICAgIFB5X1hJTkNSRUYobmFtZSk7CisgICAgb3AtPmNsX25hbWUgPSBuYW1lOworICAgIG9wLT5jbF93ZWFrcmVmbGlzdCA9IE5VTEw7CisKKyAgICBvcC0+Y2xfZ2V0YXR0ciA9IGNsYXNzX2xvb2t1cChvcCwgZ2V0YXR0cnN0ciwgJmR1bW15KTsKKyAgICBvcC0+Y2xfc2V0YXR0ciA9IGNsYXNzX2xvb2t1cChvcCwgc2V0YXR0cnN0ciwgJmR1bW15KTsKKyAgICBvcC0+Y2xfZGVsYXR0ciA9IGNsYXNzX2xvb2t1cChvcCwgZGVsYXR0cnN0ciwgJmR1bW15KTsKKyAgICBQeV9YSU5DUkVGKG9wLT5jbF9nZXRhdHRyKTsKKyAgICBQeV9YSU5DUkVGKG9wLT5jbF9zZXRhdHRyKTsKKyAgICBQeV9YSU5DUkVGKG9wLT5jbF9kZWxhdHRyKTsKKyAgICBfUHlPYmplY3RfR0NfVFJBQ0sob3ApOworICAgIHJldHVybiAoUHlPYmplY3QgKikgb3A7Cit9CisKK1B5T2JqZWN0ICoKK1B5TWV0aG9kX0Z1bmN0aW9uKFB5T2JqZWN0ICppbSkKK3sKKyAgICBpZiAoIVB5TWV0aG9kX0NoZWNrKGltKSkgeworICAgICAgICBQeUVycl9CYWRJbnRlcm5hbENhbGwoKTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIHJldHVybiAoKFB5TWV0aG9kT2JqZWN0ICopaW0pLT5pbV9mdW5jOworfQorCitQeU9iamVjdCAqCitQeU1ldGhvZF9TZWxmKFB5T2JqZWN0ICppbSkKK3sKKyAgICBpZiAoIVB5TWV0aG9kX0NoZWNrKGltKSkgeworICAgICAgICBQeUVycl9CYWRJbnRlcm5hbENhbGwoKTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIHJldHVybiAoKFB5TWV0aG9kT2JqZWN0ICopaW0pLT5pbV9zZWxmOworfQorCitQeU9iamVjdCAqCitQeU1ldGhvZF9DbGFzcyhQeU9iamVjdCAqaW0pCit7CisgICAgaWYgKCFQeU1ldGhvZF9DaGVjayhpbSkpIHsKKyAgICAgICAgUHlFcnJfQmFkSW50ZXJuYWxDYWxsKCk7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICByZXR1cm4gKChQeU1ldGhvZE9iamVjdCAqKWltKS0+aW1fY2xhc3M7Cit9CisKK1B5RG9jX1NUUlZBUihjbGFzc19kb2MsCisiY2xhc3NvYmoobmFtZSwgYmFzZXMsIGRpY3QpXG5cCitcblwKK0NyZWF0ZSBhIGNsYXNzIG9iamVjdC4gIFRoZSBuYW1lIG11c3QgYmUgYSBzdHJpbmc7IHRoZSBzZWNvbmQgYXJndW1lbnRcblwKK2EgdHVwbGUgb2YgY2xhc3NlcywgYW5kIHRoZSB0aGlyZCBhIGRpY3Rpb25hcnkuIik7CisKK3N0YXRpYyBQeU9iamVjdCAqCitjbGFzc19uZXcoUHlUeXBlT2JqZWN0ICp0eXBlLCBQeU9iamVjdCAqYXJncywgUHlPYmplY3QgKmt3ZHMpCit7CisgICAgUHlPYmplY3QgKm5hbWUsICpiYXNlcywgKmRpY3Q7CisgICAgc3RhdGljIGNoYXIgKmt3bGlzdFtdID0geyJuYW1lIiwgImJhc2VzIiwgImRpY3QiLCAwfTsKKworICAgIGlmICghUHlBcmdfUGFyc2VUdXBsZUFuZEtleXdvcmRzKGFyZ3MsIGt3ZHMsICJTT08iLCBrd2xpc3QsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJm5hbWUsICZiYXNlcywgJmRpY3QpKQorICAgICAgICByZXR1cm4gTlVMTDsKKyAgICByZXR1cm4gUHlDbGFzc19OZXcoYmFzZXMsIGRpY3QsIG5hbWUpOworfQorCisvKiBDbGFzcyBtZXRob2RzICovCisKK3N0YXRpYyB2b2lkCitjbGFzc19kZWFsbG9jKFB5Q2xhc3NPYmplY3QgKm9wKQoreworICAgIF9QeU9iamVjdF9HQ19VTlRSQUNLKG9wKTsKKyAgICBpZiAob3AtPmNsX3dlYWtyZWZsaXN0ICE9IE5VTEwpCisgICAgICAgIFB5T2JqZWN0X0NsZWFyV2Vha1JlZnMoKFB5T2JqZWN0ICopIG9wKTsKKyAgICBQeV9ERUNSRUYob3AtPmNsX2Jhc2VzKTsKKyAgICBQeV9ERUNSRUYob3AtPmNsX2RpY3QpOworICAgIFB5X1hERUNSRUYob3AtPmNsX25hbWUpOworICAgIFB5X1hERUNSRUYob3AtPmNsX2dldGF0dHIpOworICAgIFB5X1hERUNSRUYob3AtPmNsX3NldGF0dHIpOworICAgIFB5X1hERUNSRUYob3AtPmNsX2RlbGF0dHIpOworICAgIFB5T2JqZWN0X0dDX0RlbChvcCk7Cit9CisKK3N0YXRpYyBQeU9iamVjdCAqCitjbGFzc19sb29rdXAoUHlDbGFzc09iamVjdCAqY3AsIFB5T2JqZWN0ICpuYW1lLCBQeUNsYXNzT2JqZWN0ICoqcGNsYXNzKQoreworICAgIFB5X3NzaXplX3QgaSwgbjsKKyAgICBQeU9iamVjdCAqdmFsdWUgPSBQeURpY3RfR2V0SXRlbShjcC0+Y2xfZGljdCwgbmFtZSk7CisgICAgaWYgKHZhbHVlICE9IE5VTEwpIHsKKyAgICAgICAgKnBjbGFzcyA9IGNwOworICAgICAgICByZXR1cm4gdmFsdWU7CisgICAgfQorICAgIG4gPSBQeVR1cGxlX1NpemUoY3AtPmNsX2Jhc2VzKTsKKyAgICBmb3IgKGkgPSAwOyBpIDwgbjsgaSsrKSB7CisgICAgICAgIC8qIFhYWCBXaGF0IGlmIG9uZSBvZiB0aGUgYmFzZXMgaXMgbm90IGEgY2xhc3M/ICovCisgICAgICAgIFB5T2JqZWN0ICp2ID0gY2xhc3NfbG9va3VwKAorICAgICAgICAgICAgKFB5Q2xhc3NPYmplY3QgKikKKyAgICAgICAgICAgIFB5VHVwbGVfR2V0SXRlbShjcC0+Y2xfYmFzZXMsIGkpLCBuYW1lLCBwY2xhc3MpOworICAgICAgICBpZiAodiAhPSBOVUxMKQorICAgICAgICAgICAgcmV0dXJuIHY7CisgICAgfQorICAgIHJldHVybiBOVUxMOworfQorCitzdGF0aWMgUHlPYmplY3QgKgorY2xhc3NfZ2V0YXR0cihyZWdpc3RlciBQeUNsYXNzT2JqZWN0ICpvcCwgUHlPYmplY3QgKm5hbWUpCit7CisgICAgcmVnaXN0ZXIgUHlPYmplY3QgKnY7CisgICAgcmVnaXN0ZXIgY2hhciAqc25hbWU7CisgICAgUHlDbGFzc09iamVjdCAqa2xhc3M7CisgICAgZGVzY3JnZXRmdW5jIGY7CisKKyAgICBpZiAoIVB5U3RyaW5nX0NoZWNrKG5hbWUpKSB7CisgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19UeXBlRXJyb3IsICJhdHRyaWJ1dGUgbmFtZSBtdXN0IGJlIGEgc3RyaW5nIik7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKworICAgIHNuYW1lID0gUHlTdHJpbmdfQXNTdHJpbmcobmFtZSk7CisgICAgaWYgKHNuYW1lWzBdID09ICdfJyAmJiBzbmFtZVsxXSA9PSAnXycpIHsKKyAgICAgICAgaWYgKHN0cmNtcChzbmFtZSwgIl9fZGljdF9fIikgPT0gMCkgeworICAgICAgICAgICAgaWYgKFB5RXZhbF9HZXRSZXN0cmljdGVkKCkpIHsKKyAgICAgICAgICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfUnVudGltZUVycm9yLAorICAgICAgICAgICAgICAgImNsYXNzLl9fZGljdF9fIG5vdCBhY2Nlc3NpYmxlIGluIHJlc3RyaWN0ZWQgbW9kZSIpOworICAgICAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgICAgICAgICAgfQorICAgICAgICAgICAgUHlfSU5DUkVGKG9wLT5jbF9kaWN0KTsKKyAgICAgICAgICAgIHJldHVybiBvcC0+Y2xfZGljdDsKKyAgICAgICAgfQorICAgICAgICBpZiAoc3RyY21wKHNuYW1lLCAiX19iYXNlc19fIikgPT0gMCkgeworICAgICAgICAgICAgUHlfSU5DUkVGKG9wLT5jbF9iYXNlcyk7CisgICAgICAgICAgICByZXR1cm4gb3AtPmNsX2Jhc2VzOworICAgICAgICB9CisgICAgICAgIGlmIChzdHJjbXAoc25hbWUsICJfX25hbWVfXyIpID09IDApIHsKKyAgICAgICAgICAgIGlmIChvcC0+Y2xfbmFtZSA9PSBOVUxMKQorICAgICAgICAgICAgICAgIHYgPSBQeV9Ob25lOworICAgICAgICAgICAgZWxzZQorICAgICAgICAgICAgICAgIHYgPSBvcC0+Y2xfbmFtZTsKKyAgICAgICAgICAgIFB5X0lOQ1JFRih2KTsKKyAgICAgICAgICAgIHJldHVybiB2OworICAgICAgICB9CisgICAgfQorICAgIHYgPSBjbGFzc19sb29rdXAob3AsIG5hbWUsICZrbGFzcyk7CisgICAgaWYgKHYgPT0gTlVMTCkgeworICAgICAgICBQeUVycl9Gb3JtYXQoUHlFeGNfQXR0cmlidXRlRXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAiY2xhc3MgJS41MHMgaGFzIG5vIGF0dHJpYnV0ZSAnJS40MDBzJyIsCisgICAgICAgICAgICAgICAgICAgICBQeVN0cmluZ19BU19TVFJJTkcob3AtPmNsX25hbWUpLCBzbmFtZSk7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICBmID0gVFBfREVTQ1JfR0VUKHYtPm9iX3R5cGUpOworICAgIGlmIChmID09IE5VTEwpCisgICAgICAgIFB5X0lOQ1JFRih2KTsKKyAgICBlbHNlCisgICAgICAgIHYgPSBmKHYsIChQeU9iamVjdCAqKU5VTEwsIChQeU9iamVjdCAqKW9wKTsKKyAgICByZXR1cm4gdjsKK30KKworc3RhdGljIHZvaWQKK3NldF9zbG90KFB5T2JqZWN0ICoqc2xvdCwgUHlPYmplY3QgKnYpCit7CisgICAgUHlPYmplY3QgKnRlbXAgPSAqc2xvdDsKKyAgICBQeV9YSU5DUkVGKHYpOworICAgICpzbG90ID0gdjsKKyAgICBQeV9YREVDUkVGKHRlbXApOworfQorCitzdGF0aWMgdm9pZAorc2V0X2F0dHJfc2xvdHMoUHlDbGFzc09iamVjdCAqYykKK3sKKyAgICBQeUNsYXNzT2JqZWN0ICpkdW1teTsKKworICAgIHNldF9zbG90KCZjLT5jbF9nZXRhdHRyLCBjbGFzc19sb29rdXAoYywgZ2V0YXR0cnN0ciwgJmR1bW15KSk7CisgICAgc2V0X3Nsb3QoJmMtPmNsX3NldGF0dHIsIGNsYXNzX2xvb2t1cChjLCBzZXRhdHRyc3RyLCAmZHVtbXkpKTsKKyAgICBzZXRfc2xvdCgmYy0+Y2xfZGVsYXR0ciwgY2xhc3NfbG9va3VwKGMsIGRlbGF0dHJzdHIsICZkdW1teSkpOworfQorCitzdGF0aWMgY2hhciAqCitzZXRfZGljdChQeUNsYXNzT2JqZWN0ICpjLCBQeU9iamVjdCAqdikKK3sKKyAgICBpZiAodiA9PSBOVUxMIHx8ICFQeURpY3RfQ2hlY2sodikpCisgICAgICAgIHJldHVybiAiX19kaWN0X18gbXVzdCBiZSBhIGRpY3Rpb25hcnkgb2JqZWN0IjsKKyAgICBzZXRfc2xvdCgmYy0+Y2xfZGljdCwgdik7CisgICAgc2V0X2F0dHJfc2xvdHMoYyk7CisgICAgcmV0dXJuICIiOworfQorCitzdGF0aWMgY2hhciAqCitzZXRfYmFzZXMoUHlDbGFzc09iamVjdCAqYywgUHlPYmplY3QgKnYpCit7CisgICAgUHlfc3NpemVfdCBpLCBuOworCisgICAgaWYgKHYgPT0gTlVMTCB8fCAhUHlUdXBsZV9DaGVjayh2KSkKKyAgICAgICAgcmV0dXJuICJfX2Jhc2VzX18gbXVzdCBiZSBhIHR1cGxlIG9iamVjdCI7CisgICAgbiA9IFB5VHVwbGVfU2l6ZSh2KTsKKyAgICBmb3IgKGkgPSAwOyBpIDwgbjsgaSsrKSB7CisgICAgICAgIFB5T2JqZWN0ICp4ID0gUHlUdXBsZV9HRVRfSVRFTSh2LCBpKTsKKyAgICAgICAgaWYgKCFQeUNsYXNzX0NoZWNrKHgpKQorICAgICAgICAgICAgcmV0dXJuICJfX2Jhc2VzX18gaXRlbXMgbXVzdCBiZSBjbGFzc2VzIjsKKyAgICAgICAgaWYgKFB5Q2xhc3NfSXNTdWJjbGFzcyh4LCAoUHlPYmplY3QgKiljKSkKKyAgICAgICAgICAgIHJldHVybiAiYSBfX2Jhc2VzX18gaXRlbSBjYXVzZXMgYW4gaW5oZXJpdGFuY2UgY3ljbGUiOworICAgIH0KKyAgICBzZXRfc2xvdCgmYy0+Y2xfYmFzZXMsIHYpOworICAgIHNldF9hdHRyX3Nsb3RzKGMpOworICAgIHJldHVybiAiIjsKK30KKworc3RhdGljIGNoYXIgKgorc2V0X25hbWUoUHlDbGFzc09iamVjdCAqYywgUHlPYmplY3QgKnYpCit7CisgICAgaWYgKHYgPT0gTlVMTCB8fCAhUHlTdHJpbmdfQ2hlY2sodikpCisgICAgICAgIHJldHVybiAiX19uYW1lX18gbXVzdCBiZSBhIHN0cmluZyBvYmplY3QiOworICAgIGlmIChzdHJsZW4oUHlTdHJpbmdfQVNfU1RSSU5HKHYpKSAhPSAoc2l6ZV90KVB5U3RyaW5nX0dFVF9TSVpFKHYpKQorICAgICAgICByZXR1cm4gIl9fbmFtZV9fIG11c3Qgbm90IGNvbnRhaW4gbnVsbCBieXRlcyI7CisgICAgc2V0X3Nsb3QoJmMtPmNsX25hbWUsIHYpOworICAgIHJldHVybiAiIjsKK30KKworc3RhdGljIGludAorY2xhc3Nfc2V0YXR0cihQeUNsYXNzT2JqZWN0ICpvcCwgUHlPYmplY3QgKm5hbWUsIFB5T2JqZWN0ICp2KQoreworICAgIGNoYXIgKnNuYW1lOworICAgIGlmIChQeUV2YWxfR2V0UmVzdHJpY3RlZCgpKSB7CisgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19SdW50aW1lRXJyb3IsCisgICAgICAgICAgICAgICAgICAgImNsYXNzZXMgYXJlIHJlYWQtb25seSBpbiByZXN0cmljdGVkIG1vZGUiKTsKKyAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKyAgICBpZiAoIVB5U3RyaW5nX0NoZWNrKG5hbWUpKSB7CisgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19UeXBlRXJyb3IsICJhdHRyaWJ1dGUgbmFtZSBtdXN0IGJlIGEgc3RyaW5nIik7CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisgICAgc25hbWUgPSBQeVN0cmluZ19Bc1N0cmluZyhuYW1lKTsKKyAgICBpZiAoc25hbWVbMF0gPT0gJ18nICYmIHNuYW1lWzFdID09ICdfJykgeworICAgICAgICBQeV9zc2l6ZV90IG4gPSBQeVN0cmluZ19TaXplKG5hbWUpOworICAgICAgICBpZiAoc25hbWVbbi0xXSA9PSAnXycgJiYgc25hbWVbbi0yXSA9PSAnXycpIHsKKyAgICAgICAgICAgIGNoYXIgKmVyciA9IE5VTEw7CisgICAgICAgICAgICBpZiAoc3RyY21wKHNuYW1lLCAiX19kaWN0X18iKSA9PSAwKQorICAgICAgICAgICAgICAgIGVyciA9IHNldF9kaWN0KG9wLCB2KTsKKyAgICAgICAgICAgIGVsc2UgaWYgKHN0cmNtcChzbmFtZSwgIl9fYmFzZXNfXyIpID09IDApCisgICAgICAgICAgICAgICAgZXJyID0gc2V0X2Jhc2VzKG9wLCB2KTsKKyAgICAgICAgICAgIGVsc2UgaWYgKHN0cmNtcChzbmFtZSwgIl9fbmFtZV9fIikgPT0gMCkKKyAgICAgICAgICAgICAgICBlcnIgPSBzZXRfbmFtZShvcCwgdik7CisgICAgICAgICAgICBlbHNlIGlmIChzdHJjbXAoc25hbWUsICJfX2dldGF0dHJfXyIpID09IDApCisgICAgICAgICAgICAgICAgc2V0X3Nsb3QoJm9wLT5jbF9nZXRhdHRyLCB2KTsKKyAgICAgICAgICAgIGVsc2UgaWYgKHN0cmNtcChzbmFtZSwgIl9fc2V0YXR0cl9fIikgPT0gMCkKKyAgICAgICAgICAgICAgICBzZXRfc2xvdCgmb3AtPmNsX3NldGF0dHIsIHYpOworICAgICAgICAgICAgZWxzZSBpZiAoc3RyY21wKHNuYW1lLCAiX19kZWxhdHRyX18iKSA9PSAwKQorICAgICAgICAgICAgICAgIHNldF9zbG90KCZvcC0+Y2xfZGVsYXR0ciwgdik7CisgICAgICAgICAgICAvKiBGb3IgdGhlIGxhc3QgdGhyZWUsIHdlIGZhbGwgdGhyb3VnaCB0byB1cGRhdGUgdGhlCisgICAgICAgICAgICAgICBkaWN0aW9uYXJ5IGFzIHdlbGwuICovCisgICAgICAgICAgICBpZiAoZXJyICE9IE5VTEwpIHsKKyAgICAgICAgICAgICAgICBpZiAoKmVyciA9PSAnXDAnKQorICAgICAgICAgICAgICAgICAgICByZXR1cm4gMDsKKyAgICAgICAgICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfVHlwZUVycm9yLCBlcnIpOworICAgICAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKyAgICBpZiAodiA9PSBOVUxMKSB7CisgICAgICAgIGludCBydiA9IFB5RGljdF9EZWxJdGVtKG9wLT5jbF9kaWN0LCBuYW1lKTsKKyAgICAgICAgaWYgKHJ2IDwgMCkKKyAgICAgICAgICAgIFB5RXJyX0Zvcm1hdChQeUV4Y19BdHRyaWJ1dGVFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAiY2xhc3MgJS41MHMgaGFzIG5vIGF0dHJpYnV0ZSAnJS40MDBzJyIsCisgICAgICAgICAgICAgICAgICAgICAgICAgUHlTdHJpbmdfQVNfU1RSSU5HKG9wLT5jbF9uYW1lKSwgc25hbWUpOworICAgICAgICByZXR1cm4gcnY7CisgICAgfQorICAgIGVsc2UKKyAgICAgICAgcmV0dXJuIFB5RGljdF9TZXRJdGVtKG9wLT5jbF9kaWN0LCBuYW1lLCB2KTsKK30KKworc3RhdGljIFB5T2JqZWN0ICoKK2NsYXNzX3JlcHIoUHlDbGFzc09iamVjdCAqb3ApCit7CisgICAgUHlPYmplY3QgKm1vZCA9IFB5RGljdF9HZXRJdGVtU3RyaW5nKG9wLT5jbF9kaWN0LCAiX19tb2R1bGVfXyIpOworICAgIGNoYXIgKm5hbWU7CisgICAgaWYgKG9wLT5jbF9uYW1lID09IE5VTEwgfHwgIVB5U3RyaW5nX0NoZWNrKG9wLT5jbF9uYW1lKSkKKyAgICAgICAgbmFtZSA9ICI/IjsKKyAgICBlbHNlCisgICAgICAgIG5hbWUgPSBQeVN0cmluZ19Bc1N0cmluZyhvcC0+Y2xfbmFtZSk7CisgICAgaWYgKG1vZCA9PSBOVUxMIHx8ICFQeVN0cmluZ19DaGVjayhtb2QpKQorICAgICAgICByZXR1cm4gUHlTdHJpbmdfRnJvbUZvcm1hdCgiPGNsYXNzID8uJXMgYXQgJXA+IiwgbmFtZSwgb3ApOworICAgIGVsc2UKKyAgICAgICAgcmV0dXJuIFB5U3RyaW5nX0Zyb21Gb3JtYXQoIjxjbGFzcyAlcy4lcyBhdCAlcD4iLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQeVN0cmluZ19Bc1N0cmluZyhtb2QpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lLCBvcCk7Cit9CisKK3N0YXRpYyBQeU9iamVjdCAqCitjbGFzc19zdHIoUHlDbGFzc09iamVjdCAqb3ApCit7CisgICAgUHlPYmplY3QgKm1vZCA9IFB5RGljdF9HZXRJdGVtU3RyaW5nKG9wLT5jbF9kaWN0LCAiX19tb2R1bGVfXyIpOworICAgIFB5T2JqZWN0ICpuYW1lID0gb3AtPmNsX25hbWU7CisgICAgUHlPYmplY3QgKnJlczsKKyAgICBQeV9zc2l6ZV90IG0sIG47CisKKyAgICBpZiAobmFtZSA9PSBOVUxMIHx8ICFQeVN0cmluZ19DaGVjayhuYW1lKSkKKyAgICAgICAgcmV0dXJuIGNsYXNzX3JlcHIob3ApOworICAgIGlmIChtb2QgPT0gTlVMTCB8fCAhUHlTdHJpbmdfQ2hlY2sobW9kKSkgeworICAgICAgICBQeV9JTkNSRUYobmFtZSk7CisgICAgICAgIHJldHVybiBuYW1lOworICAgIH0KKyAgICBtID0gUHlTdHJpbmdfR0VUX1NJWkUobW9kKTsKKyAgICBuID0gUHlTdHJpbmdfR0VUX1NJWkUobmFtZSk7CisgICAgcmVzID0gUHlTdHJpbmdfRnJvbVN0cmluZ0FuZFNpemUoKGNoYXIgKilOVUxMLCBtKzErbik7CisgICAgaWYgKHJlcyAhPSBOVUxMKSB7CisgICAgICAgIGNoYXIgKnMgPSBQeVN0cmluZ19BU19TVFJJTkcocmVzKTsKKyAgICAgICAgbWVtY3B5KHMsIFB5U3RyaW5nX0FTX1NUUklORyhtb2QpLCBtKTsKKyAgICAgICAgcyArPSBtOworICAgICAgICAqcysrID0gJy4nOworICAgICAgICBtZW1jcHkocywgUHlTdHJpbmdfQVNfU1RSSU5HKG5hbWUpLCBuKTsKKyAgICB9CisgICAgcmV0dXJuIHJlczsKK30KKworc3RhdGljIGludAorY2xhc3NfdHJhdmVyc2UoUHlDbGFzc09iamVjdCAqbywgdmlzaXRwcm9jIHZpc2l0LCB2b2lkICphcmcpCit7CisgICAgUHlfVklTSVQoby0+Y2xfYmFzZXMpOworICAgIFB5X1ZJU0lUKG8tPmNsX2RpY3QpOworICAgIFB5X1ZJU0lUKG8tPmNsX25hbWUpOworICAgIFB5X1ZJU0lUKG8tPmNsX2dldGF0dHIpOworICAgIFB5X1ZJU0lUKG8tPmNsX3NldGF0dHIpOworICAgIFB5X1ZJU0lUKG8tPmNsX2RlbGF0dHIpOworICAgIHJldHVybiAwOworfQorCitQeVR5cGVPYmplY3QgUHlDbGFzc19UeXBlID0geworICAgIFB5T2JqZWN0X0hFQURfSU5JVCgmUHlUeXBlX1R5cGUpCisgICAgMCwKKyAgICAiY2xhc3NvYmoiLAorICAgIHNpemVvZihQeUNsYXNzT2JqZWN0KSwKKyAgICAwLAorICAgIChkZXN0cnVjdG9yKWNsYXNzX2RlYWxsb2MsICAgICAgICAgICAgICAgICAgLyogdHBfZGVhbGxvYyAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfcHJpbnQgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2dldGF0dHIgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3NldGF0dHIgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2NvbXBhcmUgKi8KKyAgICAocmVwcmZ1bmMpY2xhc3NfcmVwciwgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3JlcHIgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2FzX251bWJlciAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfYXNfc2VxdWVuY2UgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2FzX21hcHBpbmcgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2hhc2ggKi8KKyAgICBQeUluc3RhbmNlX05ldywgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2NhbGwgKi8KKyAgICAocmVwcmZ1bmMpY2xhc3Nfc3RyLCAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3N0ciAqLworICAgIChnZXRhdHRyb2Z1bmMpY2xhc3NfZ2V0YXR0ciwgICAgICAgICAgICAgICAgLyogdHBfZ2V0YXR0cm8gKi8KKyAgICAoc2V0YXR0cm9mdW5jKWNsYXNzX3NldGF0dHIsICAgICAgICAgICAgICAgIC8qIHRwX3NldGF0dHJvICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9hc19idWZmZXIgKi8KKyAgICBQeV9UUEZMQUdTX0RFRkFVTFQgfCBQeV9UUEZMQUdTX0hBVkVfR0MsLyogdHBfZmxhZ3MgKi8KKyAgICBjbGFzc19kb2MsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2RvYyAqLworICAgICh0cmF2ZXJzZXByb2MpY2xhc3NfdHJhdmVyc2UsICAgICAgICAgICAgICAgLyogdHBfdHJhdmVyc2UgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2NsZWFyICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9yaWNoY29tcGFyZSAqLworICAgIG9mZnNldG9mKFB5Q2xhc3NPYmplY3QsIGNsX3dlYWtyZWZsaXN0KSwgLyogdHBfd2Vha2xpc3RvZmZzZXQgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2l0ZXIgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2l0ZXJuZXh0ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9tZXRob2RzICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9tZW1iZXJzICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9nZXRzZXQgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2Jhc2UgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2RpY3QgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2Rlc2NyX2dldCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZGVzY3Jfc2V0ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9kaWN0b2Zmc2V0ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9pbml0ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9hbGxvYyAqLworICAgIGNsYXNzX25ldywgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfbmV3ICovCit9OworCitpbnQKK1B5Q2xhc3NfSXNTdWJjbGFzcyhQeU9iamVjdCAqa2xhc3MsIFB5T2JqZWN0ICpiYXNlKQoreworICAgIFB5X3NzaXplX3QgaSwgbjsKKyAgICBQeUNsYXNzT2JqZWN0ICpjcDsKKyAgICBpZiAoa2xhc3MgPT0gYmFzZSkKKyAgICAgICAgcmV0dXJuIDE7CisgICAgaWYgKFB5VHVwbGVfQ2hlY2soYmFzZSkpIHsKKyAgICAgICAgbiA9IFB5VHVwbGVfR0VUX1NJWkUoYmFzZSk7CisgICAgICAgIGZvciAoaSA9IDA7IGkgPCBuOyBpKyspIHsKKyAgICAgICAgICAgIGlmIChQeUNsYXNzX0lzU3ViY2xhc3Moa2xhc3MsIFB5VHVwbGVfR0VUX0lURU0oYmFzZSwgaSkpKQorICAgICAgICAgICAgICAgIHJldHVybiAxOworICAgICAgICB9CisgICAgICAgIHJldHVybiAwOworICAgIH0KKyAgICBpZiAoa2xhc3MgPT0gTlVMTCB8fCAhUHlDbGFzc19DaGVjayhrbGFzcykpCisgICAgICAgIHJldHVybiAwOworICAgIGNwID0gKFB5Q2xhc3NPYmplY3QgKilrbGFzczsKKyAgICBuID0gUHlUdXBsZV9TaXplKGNwLT5jbF9iYXNlcyk7CisgICAgZm9yIChpID0gMDsgaSA8IG47IGkrKykgeworICAgICAgICBpZiAoUHlDbGFzc19Jc1N1YmNsYXNzKFB5VHVwbGVfR2V0SXRlbShjcC0+Y2xfYmFzZXMsIGkpLCBiYXNlKSkKKyAgICAgICAgICAgIHJldHVybiAxOworICAgIH0KKyAgICByZXR1cm4gMDsKK30KKworCisvKiBJbnN0YW5jZSBvYmplY3RzICovCisKK1B5T2JqZWN0ICoKK1B5SW5zdGFuY2VfTmV3UmF3KFB5T2JqZWN0ICprbGFzcywgUHlPYmplY3QgKmRpY3QpCit7CisgICAgUHlJbnN0YW5jZU9iamVjdCAqaW5zdDsKKworICAgIGlmICghUHlDbGFzc19DaGVjayhrbGFzcykpIHsKKyAgICAgICAgUHlFcnJfQmFkSW50ZXJuYWxDYWxsKCk7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICBpZiAoZGljdCA9PSBOVUxMKSB7CisgICAgICAgIGRpY3QgPSBQeURpY3RfTmV3KCk7CisgICAgICAgIGlmIChkaWN0ID09IE5VTEwpCisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgZWxzZSB7CisgICAgICAgIGlmICghUHlEaWN0X0NoZWNrKGRpY3QpKSB7CisgICAgICAgICAgICBQeUVycl9CYWRJbnRlcm5hbENhbGwoKTsKKyAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgICAgICB9CisgICAgICAgIFB5X0lOQ1JFRihkaWN0KTsKKyAgICB9CisgICAgaW5zdCA9IFB5T2JqZWN0X0dDX05ldyhQeUluc3RhbmNlT2JqZWN0LCAmUHlJbnN0YW5jZV9UeXBlKTsKKyAgICBpZiAoaW5zdCA9PSBOVUxMKSB7CisgICAgICAgIFB5X0RFQ1JFRihkaWN0KTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIGluc3QtPmluX3dlYWtyZWZsaXN0ID0gTlVMTDsKKyAgICBQeV9JTkNSRUYoa2xhc3MpOworICAgIGluc3QtPmluX2NsYXNzID0gKFB5Q2xhc3NPYmplY3QgKilrbGFzczsKKyAgICBpbnN0LT5pbl9kaWN0ID0gZGljdDsKKyAgICBfUHlPYmplY3RfR0NfVFJBQ0soaW5zdCk7CisgICAgcmV0dXJuIChQeU9iamVjdCAqKWluc3Q7Cit9CisKK1B5T2JqZWN0ICoKK1B5SW5zdGFuY2VfTmV3KFB5T2JqZWN0ICprbGFzcywgUHlPYmplY3QgKmFyZywgUHlPYmplY3QgKmt3KQoreworICAgIHJlZ2lzdGVyIFB5SW5zdGFuY2VPYmplY3QgKmluc3Q7CisgICAgUHlPYmplY3QgKmluaXQ7CisgICAgc3RhdGljIFB5T2JqZWN0ICppbml0c3RyOworCisgICAgaWYgKGluaXRzdHIgPT0gTlVMTCkgeworICAgICAgICBpbml0c3RyID0gUHlTdHJpbmdfSW50ZXJuRnJvbVN0cmluZygiX19pbml0X18iKTsKKyAgICAgICAgaWYgKGluaXRzdHIgPT0gTlVMTCkKKyAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICBpbnN0ID0gKFB5SW5zdGFuY2VPYmplY3QgKikgUHlJbnN0YW5jZV9OZXdSYXcoa2xhc3MsIE5VTEwpOworICAgIGlmIChpbnN0ID09IE5VTEwpCisgICAgICAgIHJldHVybiBOVUxMOworICAgIGluaXQgPSBpbnN0YW5jZV9nZXRhdHRyMihpbnN0LCBpbml0c3RyKTsKKyAgICBpZiAoaW5pdCA9PSBOVUxMKSB7CisgICAgICAgIGlmIChQeUVycl9PY2N1cnJlZCgpKSB7CisgICAgICAgICAgICBQeV9ERUNSRUYoaW5zdCk7CisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgfQorICAgICAgICBpZiAoKGFyZyAhPSBOVUxMICYmICghUHlUdXBsZV9DaGVjayhhcmcpIHx8CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFB5VHVwbGVfU2l6ZShhcmcpICE9IDApKQorICAgICAgICAgICAgfHwgKGt3ICE9IE5VTEwgJiYgKCFQeURpY3RfQ2hlY2soa3cpIHx8CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQeURpY3RfU2l6ZShrdykgIT0gMCkpKSB7CisgICAgICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfVHlwZUVycm9yLAorICAgICAgICAgICAgICAgICAgICAgICAidGhpcyBjb25zdHJ1Y3RvciB0YWtlcyBubyBhcmd1bWVudHMiKTsKKyAgICAgICAgICAgIFB5X0RFQ1JFRihpbnN0KTsKKyAgICAgICAgICAgIGluc3QgPSBOVUxMOworICAgICAgICB9CisgICAgfQorICAgIGVsc2UgeworICAgICAgICBQeU9iamVjdCAqcmVzID0gUHlFdmFsX0NhbGxPYmplY3RXaXRoS2V5d29yZHMoaW5pdCwgYXJnLCBrdyk7CisgICAgICAgIFB5X0RFQ1JFRihpbml0KTsKKyAgICAgICAgaWYgKHJlcyA9PSBOVUxMKSB7CisgICAgICAgICAgICBQeV9ERUNSRUYoaW5zdCk7CisgICAgICAgICAgICBpbnN0ID0gTlVMTDsKKyAgICAgICAgfQorICAgICAgICBlbHNlIHsKKyAgICAgICAgICAgIGlmIChyZXMgIT0gUHlfTm9uZSkgeworICAgICAgICAgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19UeXBlRXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAiX19pbml0X18oKSBzaG91bGQgcmV0dXJuIE5vbmUiKTsKKyAgICAgICAgICAgICAgICBQeV9ERUNSRUYoaW5zdCk7CisgICAgICAgICAgICAgICAgaW5zdCA9IE5VTEw7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBQeV9ERUNSRUYocmVzKTsKKyAgICAgICAgfQorICAgIH0KKyAgICByZXR1cm4gKFB5T2JqZWN0ICopaW5zdDsKK30KKworLyogSW5zdGFuY2UgbWV0aG9kcyAqLworCitQeURvY19TVFJWQVIoaW5zdGFuY2VfZG9jLAorImluc3RhbmNlKGNsYXNzWywgZGljdF0pXG5cCitcblwKK0NyZWF0ZSBhbiBpbnN0YW5jZSB3aXRob3V0IGNhbGxpbmcgaXRzIF9faW5pdF9fKCkgbWV0aG9kLlxuXAorVGhlIGNsYXNzIG11c3QgYmUgYSBjbGFzc2ljIGNsYXNzLlxuXAorSWYgcHJlc2VudCwgZGljdCBtdXN0IGJlIGEgZGljdGlvbmFyeSBvciBOb25lLiIpOworCitzdGF0aWMgUHlPYmplY3QgKgoraW5zdGFuY2VfbmV3KFB5VHlwZU9iamVjdCogdHlwZSwgUHlPYmplY3QqIGFyZ3MsIFB5T2JqZWN0ICprdykKK3sKKyAgICBQeU9iamVjdCAqa2xhc3M7CisgICAgUHlPYmplY3QgKmRpY3QgPSBQeV9Ob25lOworCisgICAgaWYgKCFQeUFyZ19QYXJzZVR1cGxlKGFyZ3MsICJPIXxPOmluc3RhbmNlIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgJlB5Q2xhc3NfVHlwZSwgJmtsYXNzLCAmZGljdCkpCisgICAgICAgIHJldHVybiBOVUxMOworCisgICAgaWYgKGRpY3QgPT0gUHlfTm9uZSkKKyAgICAgICAgZGljdCA9IE5VTEw7CisgICAgZWxzZSBpZiAoIVB5RGljdF9DaGVjayhkaWN0KSkgeworICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfVHlwZUVycm9yLAorICAgICAgICAgICAgICAiaW5zdGFuY2UoKSBzZWNvbmQgYXJnIG11c3QgYmUgZGljdGlvbmFyeSBvciBOb25lIik7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICByZXR1cm4gUHlJbnN0YW5jZV9OZXdSYXcoa2xhc3MsIGRpY3QpOworfQorCisKK3N0YXRpYyB2b2lkCitpbnN0YW5jZV9kZWFsbG9jKHJlZ2lzdGVyIFB5SW5zdGFuY2VPYmplY3QgKmluc3QpCit7CisgICAgUHlPYmplY3QgKmVycm9yX3R5cGUsICplcnJvcl92YWx1ZSwgKmVycm9yX3RyYWNlYmFjazsKKyAgICBQeU9iamVjdCAqZGVsOworICAgIHN0YXRpYyBQeU9iamVjdCAqZGVsc3RyOworCisgICAgX1B5T2JqZWN0X0dDX1VOVFJBQ0soaW5zdCk7CisgICAgaWYgKGluc3QtPmluX3dlYWtyZWZsaXN0ICE9IE5VTEwpCisgICAgICAgIFB5T2JqZWN0X0NsZWFyV2Vha1JlZnMoKFB5T2JqZWN0ICopIGluc3QpOworCisgICAgLyogVGVtcG9yYXJpbHkgcmVzdXJyZWN0IHRoZSBvYmplY3QuICovCisgICAgYXNzZXJ0KGluc3QtPm9iX3R5cGUgPT0gJlB5SW5zdGFuY2VfVHlwZSk7CisgICAgYXNzZXJ0KGluc3QtPm9iX3JlZmNudCA9PSAwKTsKKyAgICBpbnN0LT5vYl9yZWZjbnQgPSAxOworCisgICAgLyogU2F2ZSB0aGUgY3VycmVudCBleGNlcHRpb24sIGlmIGFueS4gKi8KKyAgICBQeUVycl9GZXRjaCgmZXJyb3JfdHlwZSwgJmVycm9yX3ZhbHVlLCAmZXJyb3JfdHJhY2ViYWNrKTsKKyAgICAvKiBFeGVjdXRlIF9fZGVsX18gbWV0aG9kLCBpZiBhbnkuICovCisgICAgaWYgKGRlbHN0ciA9PSBOVUxMKSB7CisgICAgICAgIGRlbHN0ciA9IFB5U3RyaW5nX0ludGVybkZyb21TdHJpbmcoIl9fZGVsX18iKTsKKyAgICAgICAgaWYgKGRlbHN0ciA9PSBOVUxMKQorICAgICAgICAgICAgUHlFcnJfV3JpdGVVbnJhaXNhYmxlKChQeU9iamVjdCopaW5zdCk7CisgICAgfQorICAgIGlmIChkZWxzdHIgJiYgKGRlbCA9IGluc3RhbmNlX2dldGF0dHIyKGluc3QsIGRlbHN0cikpICE9IE5VTEwpIHsKKyAgICAgICAgUHlPYmplY3QgKnJlcyA9IFB5RXZhbF9DYWxsT2JqZWN0KGRlbCwgKFB5T2JqZWN0ICopTlVMTCk7CisgICAgICAgIGlmIChyZXMgPT0gTlVMTCkKKyAgICAgICAgICAgIFB5RXJyX1dyaXRlVW5yYWlzYWJsZShkZWwpOworICAgICAgICBlbHNlCisgICAgICAgICAgICBQeV9ERUNSRUYocmVzKTsKKyAgICAgICAgUHlfREVDUkVGKGRlbCk7CisgICAgfQorICAgIC8qIFJlc3RvcmUgdGhlIHNhdmVkIGV4Y2VwdGlvbi4gKi8KKyAgICBQeUVycl9SZXN0b3JlKGVycm9yX3R5cGUsIGVycm9yX3ZhbHVlLCBlcnJvcl90cmFjZWJhY2spOworCisgICAgLyogVW5kbyB0aGUgdGVtcG9yYXJ5IHJlc3VycmVjdGlvbjsgY2FuJ3QgdXNlIERFQ1JFRiBoZXJlLCBpdCB3b3VsZAorICAgICAqIGNhdXNlIGEgcmVjdXJzaXZlIGNhbGwuCisgICAgICovCisgICAgYXNzZXJ0KGluc3QtPm9iX3JlZmNudCA+IDApOworICAgIGlmICgtLWluc3QtPm9iX3JlZmNudCA9PSAwKSB7CisKKyAgICAgICAgLyogTmV3IHdlYWtyZWZzIGNvdWxkIGJlIGNyZWF0ZWQgZHVyaW5nIHRoZSBmaW5hbGl6ZXIgY2FsbC4KKyAgICAgICAgICAgIElmIHRoaXMgb2NjdXJzLCBjbGVhciB0aGVtIG91dCB3aXRob3V0IGNhbGxpbmcgdGhlaXIKKyAgICAgICAgICAgIGZpbmFsaXplcnMgc2luY2UgdGhleSBtaWdodCByZWx5IG9uIHBhcnQgb2YgdGhlIG9iamVjdAorICAgICAgICAgICAgYmVpbmcgZmluYWxpemVkIHRoYXQgaGFzIGFscmVhZHkgYmVlbiBkZXN0cm95ZWQuICovCisgICAgICAgIHdoaWxlIChpbnN0LT5pbl93ZWFrcmVmbGlzdCAhPSBOVUxMKSB7CisgICAgICAgICAgICBfUHlXZWFrcmVmX0NsZWFyUmVmKChQeVdlYWtSZWZlcmVuY2UgKikKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGluc3QtPmluX3dlYWtyZWZsaXN0KSk7CisgICAgICAgIH0KKworICAgICAgICBQeV9ERUNSRUYoaW5zdC0+aW5fY2xhc3MpOworICAgICAgICBQeV9YREVDUkVGKGluc3QtPmluX2RpY3QpOworICAgICAgICBQeU9iamVjdF9HQ19EZWwoaW5zdCk7CisgICAgfQorICAgIGVsc2UgeworICAgICAgICBQeV9zc2l6ZV90IHJlZmNudCA9IGluc3QtPm9iX3JlZmNudDsKKyAgICAgICAgLyogX19kZWxfXyByZXN1cnJlY3RlZCBpdCEgIE1ha2UgaXQgbG9vayBsaWtlIHRoZSBvcmlnaW5hbAorICAgICAgICAgKiBQeV9ERUNSRUYgbmV2ZXIgaGFwcGVuZWQuCisgICAgICAgICAqLworICAgICAgICBfUHlfTmV3UmVmZXJlbmNlKChQeU9iamVjdCAqKWluc3QpOworICAgICAgICBpbnN0LT5vYl9yZWZjbnQgPSByZWZjbnQ7CisgICAgICAgIF9QeU9iamVjdF9HQ19UUkFDSyhpbnN0KTsKKyAgICAgICAgLyogSWYgUHlfUkVGX0RFQlVHLCBfUHlfTmV3UmVmZXJlbmNlIGJ1bXBlZCBfUHlfUmVmVG90YWwsIHNvCisgICAgICAgICAqIHdlIG5lZWQgdG8gdW5kbyB0aGF0LiAqLworICAgICAgICBfUHlfREVDX1JFRlRPVEFMOworICAgICAgICAvKiBJZiBQeV9UUkFDRV9SRUZTLCBfUHlfTmV3UmVmZXJlbmNlIHJlLWFkZGVkIHNlbGYgdG8gdGhlCisgICAgICAgICAqIG9iamVjdCBjaGFpbiwgc28gbm8gbW9yZSB0byBkbyB0aGVyZS4KKyAgICAgICAgICogSWYgQ09VTlRfQUxMT0NTLCB0aGUgb3JpZ2luYWwgZGVjcmVmIGJ1bXBlZCB0cF9mcmVlcywgYW5kCisgICAgICAgICAqIF9QeV9OZXdSZWZlcmVuY2UgYnVtcGVkIHRwX2FsbG9jczogYm90aCBvZiB0aG9zZSBuZWVkIHRvIGJlCisgICAgICAgICAqIHVuZG9uZS4KKyAgICAgICAgICovCisjaWZkZWYgQ09VTlRfQUxMT0NTCisgICAgICAgIC0taW5zdC0+b2JfdHlwZS0+dHBfZnJlZXM7CisgICAgICAgIC0taW5zdC0+b2JfdHlwZS0+dHBfYWxsb2NzOworI2VuZGlmCisgICAgfQorfQorCitzdGF0aWMgUHlPYmplY3QgKgoraW5zdGFuY2VfZ2V0YXR0cjEocmVnaXN0ZXIgUHlJbnN0YW5jZU9iamVjdCAqaW5zdCwgUHlPYmplY3QgKm5hbWUpCit7CisgICAgcmVnaXN0ZXIgUHlPYmplY3QgKnY7CisgICAgcmVnaXN0ZXIgY2hhciAqc25hbWU7CisKKyAgICBpZiAoIVB5U3RyaW5nX0NoZWNrKG5hbWUpKSB7CisgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19UeXBlRXJyb3IsICJhdHRyaWJ1dGUgbmFtZSBtdXN0IGJlIGEgc3RyaW5nIik7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKworICAgIHNuYW1lID0gUHlTdHJpbmdfQXNTdHJpbmcobmFtZSk7CisgICAgaWYgKHNuYW1lWzBdID09ICdfJyAmJiBzbmFtZVsxXSA9PSAnXycpIHsKKyAgICAgICAgaWYgKHN0cmNtcChzbmFtZSwgIl9fZGljdF9fIikgPT0gMCkgeworICAgICAgICAgICAgaWYgKFB5RXZhbF9HZXRSZXN0cmljdGVkKCkpIHsKKyAgICAgICAgICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfUnVudGltZUVycm9yLAorICAgICAgICAgICAgImluc3RhbmNlLl9fZGljdF9fIG5vdCBhY2Nlc3NpYmxlIGluIHJlc3RyaWN0ZWQgbW9kZSIpOworICAgICAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgICAgICAgICAgfQorICAgICAgICAgICAgUHlfSU5DUkVGKGluc3QtPmluX2RpY3QpOworICAgICAgICAgICAgcmV0dXJuIGluc3QtPmluX2RpY3Q7CisgICAgICAgIH0KKyAgICAgICAgaWYgKHN0cmNtcChzbmFtZSwgIl9fY2xhc3NfXyIpID09IDApIHsKKyAgICAgICAgICAgIFB5X0lOQ1JFRihpbnN0LT5pbl9jbGFzcyk7CisgICAgICAgICAgICByZXR1cm4gKFB5T2JqZWN0ICopaW5zdC0+aW5fY2xhc3M7CisgICAgICAgIH0KKyAgICB9CisgICAgdiA9IGluc3RhbmNlX2dldGF0dHIyKGluc3QsIG5hbWUpOworICAgIGlmICh2ID09IE5VTEwgJiYgIVB5RXJyX09jY3VycmVkKCkpIHsKKyAgICAgICAgUHlFcnJfRm9ybWF0KFB5RXhjX0F0dHJpYnV0ZUVycm9yLAorICAgICAgICAgICAgICAgICAgICAgIiUuNTBzIGluc3RhbmNlIGhhcyBubyBhdHRyaWJ1dGUgJyUuNDAwcyciLAorICAgICAgICAgICAgICAgICAgICAgUHlTdHJpbmdfQVNfU1RSSU5HKGluc3QtPmluX2NsYXNzLT5jbF9uYW1lKSwgc25hbWUpOworICAgIH0KKyAgICByZXR1cm4gdjsKK30KKworc3RhdGljIFB5T2JqZWN0ICoKK2luc3RhbmNlX2dldGF0dHIyKHJlZ2lzdGVyIFB5SW5zdGFuY2VPYmplY3QgKmluc3QsIFB5T2JqZWN0ICpuYW1lKQoreworICAgIHJlZ2lzdGVyIFB5T2JqZWN0ICp2OworICAgIFB5Q2xhc3NPYmplY3QgKmtsYXNzOworICAgIGRlc2NyZ2V0ZnVuYyBmOworCisgICAgdiA9IFB5RGljdF9HZXRJdGVtKGluc3QtPmluX2RpY3QsIG5hbWUpOworICAgIGlmICh2ICE9IE5VTEwpIHsKKyAgICAgICAgUHlfSU5DUkVGKHYpOworICAgICAgICByZXR1cm4gdjsKKyAgICB9CisgICAgdiA9IGNsYXNzX2xvb2t1cChpbnN0LT5pbl9jbGFzcywgbmFtZSwgJmtsYXNzKTsKKyAgICBpZiAodiAhPSBOVUxMKSB7CisgICAgICAgIFB5X0lOQ1JFRih2KTsKKyAgICAgICAgZiA9IFRQX0RFU0NSX0dFVCh2LT5vYl90eXBlKTsKKyAgICAgICAgaWYgKGYgIT0gTlVMTCkgeworICAgICAgICAgICAgUHlPYmplY3QgKncgPSBmKHYsIChQeU9iamVjdCAqKWluc3QsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgKFB5T2JqZWN0ICopKGluc3QtPmluX2NsYXNzKSk7CisgICAgICAgICAgICBQeV9ERUNSRUYodik7CisgICAgICAgICAgICB2ID0gdzsKKyAgICAgICAgfQorICAgIH0KKyAgICByZXR1cm4gdjsKK30KKworc3RhdGljIFB5T2JqZWN0ICoKK2luc3RhbmNlX2dldGF0dHIocmVnaXN0ZXIgUHlJbnN0YW5jZU9iamVjdCAqaW5zdCwgUHlPYmplY3QgKm5hbWUpCit7CisgICAgcmVnaXN0ZXIgUHlPYmplY3QgKmZ1bmMsICpyZXM7CisgICAgcmVzID0gaW5zdGFuY2VfZ2V0YXR0cjEoaW5zdCwgbmFtZSk7CisgICAgaWYgKHJlcyA9PSBOVUxMICYmIChmdW5jID0gaW5zdC0+aW5fY2xhc3MtPmNsX2dldGF0dHIpICE9IE5VTEwpIHsKKyAgICAgICAgUHlPYmplY3QgKmFyZ3M7CisgICAgICAgIGlmICghUHlFcnJfRXhjZXB0aW9uTWF0Y2hlcyhQeUV4Y19BdHRyaWJ1dGVFcnJvcikpCisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgUHlFcnJfQ2xlYXIoKTsKKyAgICAgICAgYXJncyA9IFB5VHVwbGVfUGFjaygyLCBpbnN0LCBuYW1lKTsKKyAgICAgICAgaWYgKGFyZ3MgPT0gTlVMTCkKKyAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgICAgICByZXMgPSBQeUV2YWxfQ2FsbE9iamVjdChmdW5jLCBhcmdzKTsKKyAgICAgICAgUHlfREVDUkVGKGFyZ3MpOworICAgIH0KKyAgICByZXR1cm4gcmVzOworfQorCisvKiBTZWUgY2xhc3NvYmplY3QuaCBjb21tZW50czogIHRoaXMgb25seSBkb2VzIGRpY3QgbG9va3VwcywgYW5kIGlzIGFsd2F5cworICogc2FmZSB0byBjYWxsLgorICovCitQeU9iamVjdCAqCitfUHlJbnN0YW5jZV9Mb29rdXAoUHlPYmplY3QgKnBpbnN0LCBQeU9iamVjdCAqbmFtZSkKK3sKKyAgICBQeU9iamVjdCAqdjsKKyAgICBQeUNsYXNzT2JqZWN0ICprbGFzczsKKyAgICBQeUluc3RhbmNlT2JqZWN0ICppbnN0OyAgICAgLyogcGluc3QgY2FzdCB0byB0aGUgcmlnaHQgdHlwZSAqLworCisgICAgYXNzZXJ0KFB5SW5zdGFuY2VfQ2hlY2socGluc3QpKTsKKyAgICBpbnN0ID0gKFB5SW5zdGFuY2VPYmplY3QgKilwaW5zdDsKKworICAgIGFzc2VydChQeVN0cmluZ19DaGVjayhuYW1lKSk7CisKKyAgICB2ID0gUHlEaWN0X0dldEl0ZW0oaW5zdC0+aW5fZGljdCwgbmFtZSk7CisgICAgaWYgKHYgPT0gTlVMTCkKKyAgICAgICAgdiA9IGNsYXNzX2xvb2t1cChpbnN0LT5pbl9jbGFzcywgbmFtZSwgJmtsYXNzKTsKKyAgICByZXR1cm4gdjsKK30KKworc3RhdGljIGludAoraW5zdGFuY2Vfc2V0YXR0cjEoUHlJbnN0YW5jZU9iamVjdCAqaW5zdCwgUHlPYmplY3QgKm5hbWUsIFB5T2JqZWN0ICp2KQoreworICAgIGlmICh2ID09IE5VTEwpIHsKKyAgICAgICAgaW50IHJ2ID0gUHlEaWN0X0RlbEl0ZW0oaW5zdC0+aW5fZGljdCwgbmFtZSk7CisgICAgICAgIGlmIChydiA8IDApCisgICAgICAgICAgICBQeUVycl9Gb3JtYXQoUHlFeGNfQXR0cmlidXRlRXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgIiUuNTBzIGluc3RhbmNlIGhhcyBubyBhdHRyaWJ1dGUgJyUuNDAwcyciLAorICAgICAgICAgICAgICAgICAgICAgICAgIFB5U3RyaW5nX0FTX1NUUklORyhpbnN0LT5pbl9jbGFzcy0+Y2xfbmFtZSksCisgICAgICAgICAgICAgICAgICAgICAgICAgUHlTdHJpbmdfQVNfU1RSSU5HKG5hbWUpKTsKKyAgICAgICAgcmV0dXJuIHJ2OworICAgIH0KKyAgICBlbHNlCisgICAgICAgIHJldHVybiBQeURpY3RfU2V0SXRlbShpbnN0LT5pbl9kaWN0LCBuYW1lLCB2KTsKK30KKworc3RhdGljIGludAoraW5zdGFuY2Vfc2V0YXR0cihQeUluc3RhbmNlT2JqZWN0ICppbnN0LCBQeU9iamVjdCAqbmFtZSwgUHlPYmplY3QgKnYpCit7CisgICAgUHlPYmplY3QgKmZ1bmMsICphcmdzLCAqcmVzLCAqdG1wOworICAgIGNoYXIgKnNuYW1lOworCisgICAgaWYgKCFQeVN0cmluZ19DaGVjayhuYW1lKSkgeworICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfVHlwZUVycm9yLCAiYXR0cmlidXRlIG5hbWUgbXVzdCBiZSBhIHN0cmluZyIpOworICAgICAgICByZXR1cm4gLTE7CisgICAgfQorCisgICAgc25hbWUgPSBQeVN0cmluZ19Bc1N0cmluZyhuYW1lKTsKKyAgICBpZiAoc25hbWVbMF0gPT0gJ18nICYmIHNuYW1lWzFdID09ICdfJykgeworICAgICAgICBQeV9zc2l6ZV90IG4gPSBQeVN0cmluZ19TaXplKG5hbWUpOworICAgICAgICBpZiAoc25hbWVbbi0xXSA9PSAnXycgJiYgc25hbWVbbi0yXSA9PSAnXycpIHsKKyAgICAgICAgICAgIGlmIChzdHJjbXAoc25hbWUsICJfX2RpY3RfXyIpID09IDApIHsKKyAgICAgICAgICAgICAgICBpZiAoUHlFdmFsX0dldFJlc3RyaWN0ZWQoKSkgeworICAgICAgICAgICAgICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfUnVudGltZUVycm9yLAorICAgICAgICAgICAgICAgICAiX19kaWN0X18gbm90IGFjY2Vzc2libGUgaW4gcmVzdHJpY3RlZCBtb2RlIik7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgaWYgKHYgPT0gTlVMTCB8fCAhUHlEaWN0X0NoZWNrKHYpKSB7CisgICAgICAgICAgICAgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19UeXBlRXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAgICJfX2RpY3RfXyBtdXN0IGJlIHNldCB0byBhIGRpY3Rpb25hcnkiKTsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB0bXAgPSBpbnN0LT5pbl9kaWN0OworICAgICAgICAgICAgICAgIFB5X0lOQ1JFRih2KTsKKyAgICAgICAgICAgICAgICBpbnN0LT5pbl9kaWN0ID0gdjsKKyAgICAgICAgICAgICAgICBQeV9ERUNSRUYodG1wKTsKKyAgICAgICAgICAgICAgICByZXR1cm4gMDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChzdHJjbXAoc25hbWUsICJfX2NsYXNzX18iKSA9PSAwKSB7CisgICAgICAgICAgICAgICAgaWYgKFB5RXZhbF9HZXRSZXN0cmljdGVkKCkpIHsKKyAgICAgICAgICAgICAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1J1bnRpbWVFcnJvciwKKyAgICAgICAgICAgICAgICAiX19jbGFzc19fIG5vdCBhY2Nlc3NpYmxlIGluIHJlc3RyaWN0ZWQgbW9kZSIpOworICAgICAgICAgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGlmICh2ID09IE5VTEwgfHwgIVB5Q2xhc3NfQ2hlY2sodikpIHsKKyAgICAgICAgICAgICAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1R5cGVFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICAgIl9fY2xhc3NfXyBtdXN0IGJlIHNldCB0byBhIGNsYXNzIik7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgdG1wID0gKFB5T2JqZWN0ICopKGluc3QtPmluX2NsYXNzKTsKKyAgICAgICAgICAgICAgICBQeV9JTkNSRUYodik7CisgICAgICAgICAgICAgICAgaW5zdC0+aW5fY2xhc3MgPSAoUHlDbGFzc09iamVjdCAqKXY7CisgICAgICAgICAgICAgICAgUHlfREVDUkVGKHRtcCk7CisgICAgICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisgICAgaWYgKHYgPT0gTlVMTCkKKyAgICAgICAgZnVuYyA9IGluc3QtPmluX2NsYXNzLT5jbF9kZWxhdHRyOworICAgIGVsc2UKKyAgICAgICAgZnVuYyA9IGluc3QtPmluX2NsYXNzLT5jbF9zZXRhdHRyOworICAgIGlmIChmdW5jID09IE5VTEwpCisgICAgICAgIHJldHVybiBpbnN0YW5jZV9zZXRhdHRyMShpbnN0LCBuYW1lLCB2KTsKKyAgICBpZiAodiA9PSBOVUxMKQorICAgICAgICBhcmdzID0gUHlUdXBsZV9QYWNrKDIsIGluc3QsIG5hbWUpOworICAgIGVsc2UKKyAgICAgICAgYXJncyA9IFB5VHVwbGVfUGFjaygzLCBpbnN0LCBuYW1lLCB2KTsKKyAgICBpZiAoYXJncyA9PSBOVUxMKQorICAgICAgICByZXR1cm4gLTE7CisgICAgcmVzID0gUHlFdmFsX0NhbGxPYmplY3QoZnVuYywgYXJncyk7CisgICAgUHlfREVDUkVGKGFyZ3MpOworICAgIGlmIChyZXMgPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIC0xOworICAgIFB5X0RFQ1JFRihyZXMpOworICAgIHJldHVybiAwOworfQorCitzdGF0aWMgUHlPYmplY3QgKgoraW5zdGFuY2VfcmVwcihQeUluc3RhbmNlT2JqZWN0ICppbnN0KQoreworICAgIFB5T2JqZWN0ICpmdW5jOworICAgIFB5T2JqZWN0ICpyZXM7CisgICAgc3RhdGljIFB5T2JqZWN0ICpyZXByc3RyOworCisgICAgaWYgKHJlcHJzdHIgPT0gTlVMTCkgeworICAgICAgICByZXByc3RyID0gUHlTdHJpbmdfSW50ZXJuRnJvbVN0cmluZygiX19yZXByX18iKTsKKyAgICAgICAgaWYgKHJlcHJzdHIgPT0gTlVMTCkKKyAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICBmdW5jID0gaW5zdGFuY2VfZ2V0YXR0cihpbnN0LCByZXByc3RyKTsKKyAgICBpZiAoZnVuYyA9PSBOVUxMKSB7CisgICAgICAgIFB5T2JqZWN0ICpjbGFzc25hbWUsICptb2Q7CisgICAgICAgIGNoYXIgKmNuYW1lOworICAgICAgICBpZiAoIVB5RXJyX0V4Y2VwdGlvbk1hdGNoZXMoUHlFeGNfQXR0cmlidXRlRXJyb3IpKQorICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgICAgIFB5RXJyX0NsZWFyKCk7CisgICAgICAgIGNsYXNzbmFtZSA9IGluc3QtPmluX2NsYXNzLT5jbF9uYW1lOworICAgICAgICBtb2QgPSBQeURpY3RfR2V0SXRlbVN0cmluZyhpbnN0LT5pbl9jbGFzcy0+Y2xfZGljdCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIl9fbW9kdWxlX18iKTsKKyAgICAgICAgaWYgKGNsYXNzbmFtZSAhPSBOVUxMICYmIFB5U3RyaW5nX0NoZWNrKGNsYXNzbmFtZSkpCisgICAgICAgICAgICBjbmFtZSA9IFB5U3RyaW5nX0FzU3RyaW5nKGNsYXNzbmFtZSk7CisgICAgICAgIGVsc2UKKyAgICAgICAgICAgIGNuYW1lID0gIj8iOworICAgICAgICBpZiAobW9kID09IE5VTEwgfHwgIVB5U3RyaW5nX0NoZWNrKG1vZCkpCisgICAgICAgICAgICByZXR1cm4gUHlTdHJpbmdfRnJvbUZvcm1hdCgiPD8uJXMgaW5zdGFuY2UgYXQgJXA+IiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNuYW1lLCBpbnN0KTsKKyAgICAgICAgZWxzZQorICAgICAgICAgICAgcmV0dXJuIFB5U3RyaW5nX0Zyb21Gb3JtYXQoIjwlcy4lcyBpbnN0YW5jZSBhdCAlcD4iLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHlTdHJpbmdfQXNTdHJpbmcobW9kKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNuYW1lLCBpbnN0KTsKKyAgICB9CisgICAgcmVzID0gUHlFdmFsX0NhbGxPYmplY3QoZnVuYywgKFB5T2JqZWN0ICopTlVMTCk7CisgICAgUHlfREVDUkVGKGZ1bmMpOworICAgIHJldHVybiByZXM7Cit9CisKK3N0YXRpYyBQeU9iamVjdCAqCitpbnN0YW5jZV9zdHIoUHlJbnN0YW5jZU9iamVjdCAqaW5zdCkKK3sKKyAgICBQeU9iamVjdCAqZnVuYzsKKyAgICBQeU9iamVjdCAqcmVzOworICAgIHN0YXRpYyBQeU9iamVjdCAqc3Ryc3RyOworCisgICAgaWYgKHN0cnN0ciA9PSBOVUxMKSB7CisgICAgICAgIHN0cnN0ciA9IFB5U3RyaW5nX0ludGVybkZyb21TdHJpbmcoIl9fc3RyX18iKTsKKyAgICAgICAgaWYgKHN0cnN0ciA9PSBOVUxMKQorICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIGZ1bmMgPSBpbnN0YW5jZV9nZXRhdHRyKGluc3QsIHN0cnN0cik7CisgICAgaWYgKGZ1bmMgPT0gTlVMTCkgeworICAgICAgICBpZiAoIVB5RXJyX0V4Y2VwdGlvbk1hdGNoZXMoUHlFeGNfQXR0cmlidXRlRXJyb3IpKQorICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgICAgIFB5RXJyX0NsZWFyKCk7CisgICAgICAgIHJldHVybiBpbnN0YW5jZV9yZXByKGluc3QpOworICAgIH0KKyAgICByZXMgPSBQeUV2YWxfQ2FsbE9iamVjdChmdW5jLCAoUHlPYmplY3QgKilOVUxMKTsKKyAgICBQeV9ERUNSRUYoZnVuYyk7CisgICAgcmV0dXJuIHJlczsKK30KKworc3RhdGljIGxvbmcKK2luc3RhbmNlX2hhc2goUHlJbnN0YW5jZU9iamVjdCAqaW5zdCkKK3sKKyAgICBQeU9iamVjdCAqZnVuYzsKKyAgICBQeU9iamVjdCAqcmVzOworICAgIGxvbmcgb3V0Y29tZTsKKyAgICBzdGF0aWMgUHlPYmplY3QgKmhhc2hzdHIsICplcXN0ciwgKmNtcHN0cjsKKworICAgIGlmIChoYXNoc3RyID09IE5VTEwpIHsKKyAgICAgICAgaGFzaHN0ciA9IFB5U3RyaW5nX0ludGVybkZyb21TdHJpbmcoIl9faGFzaF9fIik7CisgICAgICAgIGlmIChoYXNoc3RyID09IE5VTEwpCisgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgfQorICAgIGZ1bmMgPSBpbnN0YW5jZV9nZXRhdHRyKGluc3QsIGhhc2hzdHIpOworICAgIGlmIChmdW5jID09IE5VTEwpIHsKKyAgICAgICAgaWYgKCFQeUVycl9FeGNlcHRpb25NYXRjaGVzKFB5RXhjX0F0dHJpYnV0ZUVycm9yKSkKKyAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgUHlFcnJfQ2xlYXIoKTsKKyAgICAgICAgLyogSWYgdGhlcmUgaXMgbm8gX19lcV9fIGFuZCBubyBfX2NtcF9fIG1ldGhvZCwgd2UgaGFzaCBvbiB0aGUKKyAgICAgICAgICAgYWRkcmVzcy4gIElmIGFuIF9fZXFfXyBvciBfX2NtcF9fIG1ldGhvZCBleGlzdHMsIHRoZXJlIG11c3QKKyAgICAgICAgICAgYmUgYSBfX2hhc2hfXy4gKi8KKyAgICAgICAgaWYgKGVxc3RyID09IE5VTEwpIHsKKyAgICAgICAgICAgIGVxc3RyID0gUHlTdHJpbmdfSW50ZXJuRnJvbVN0cmluZygiX19lcV9fIik7CisgICAgICAgICAgICBpZiAoZXFzdHIgPT0gTlVMTCkKKyAgICAgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgIH0KKyAgICAgICAgZnVuYyA9IGluc3RhbmNlX2dldGF0dHIoaW5zdCwgZXFzdHIpOworICAgICAgICBpZiAoZnVuYyA9PSBOVUxMKSB7CisgICAgICAgICAgICBpZiAoIVB5RXJyX0V4Y2VwdGlvbk1hdGNoZXMoUHlFeGNfQXR0cmlidXRlRXJyb3IpKQorICAgICAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgICAgIFB5RXJyX0NsZWFyKCk7CisgICAgICAgICAgICBpZiAoY21wc3RyID09IE5VTEwpIHsKKyAgICAgICAgICAgICAgICBjbXBzdHIgPSBQeVN0cmluZ19JbnRlcm5Gcm9tU3RyaW5nKCJfX2NtcF9fIik7CisgICAgICAgICAgICAgICAgaWYgKGNtcHN0ciA9PSBOVUxMKQorICAgICAgICAgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBmdW5jID0gaW5zdGFuY2VfZ2V0YXR0cihpbnN0LCBjbXBzdHIpOworICAgICAgICAgICAgaWYgKGZ1bmMgPT0gTlVMTCkgeworICAgICAgICAgICAgICAgIGlmICghUHlFcnJfRXhjZXB0aW9uTWF0Y2hlcygKKyAgICAgICAgICAgICAgICAgICAgUHlFeGNfQXR0cmlidXRlRXJyb3IpKQorICAgICAgICAgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgICAgICAgICAgUHlFcnJfQ2xlYXIoKTsKKyAgICAgICAgICAgICAgICByZXR1cm4gX1B5X0hhc2hQb2ludGVyKGluc3QpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIFB5X1hERUNSRUYoZnVuYyk7CisgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19UeXBlRXJyb3IsICJ1bmhhc2hhYmxlIGluc3RhbmNlIik7CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisgICAgcmVzID0gUHlFdmFsX0NhbGxPYmplY3QoZnVuYywgKFB5T2JqZWN0ICopTlVMTCk7CisgICAgUHlfREVDUkVGKGZ1bmMpOworICAgIGlmIChyZXMgPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIC0xOworICAgIGlmIChQeUludF9DaGVjayhyZXMpIHx8IFB5TG9uZ19DaGVjayhyZXMpKQorICAgICAgICAvKiBUaGlzIGFscmVhZHkgY29udmVydHMgYSAtMSByZXN1bHQgdG8gLTIuICovCisgICAgICAgIG91dGNvbWUgPSByZXMtPm9iX3R5cGUtPnRwX2hhc2gocmVzKTsKKyAgICBlbHNlIHsKKyAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1R5cGVFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICJfX2hhc2hfXygpIHNob3VsZCByZXR1cm4gYW4gaW50Iik7CisgICAgICAgIG91dGNvbWUgPSAtMTsKKyAgICB9CisgICAgUHlfREVDUkVGKHJlcyk7CisgICAgcmV0dXJuIG91dGNvbWU7Cit9CisKK3N0YXRpYyBpbnQKK2luc3RhbmNlX3RyYXZlcnNlKFB5SW5zdGFuY2VPYmplY3QgKm8sIHZpc2l0cHJvYyB2aXNpdCwgdm9pZCAqYXJnKQoreworICAgIFB5X1ZJU0lUKG8tPmluX2NsYXNzKTsKKyAgICBQeV9WSVNJVChvLT5pbl9kaWN0KTsKKyAgICByZXR1cm4gMDsKK30KKworc3RhdGljIFB5T2JqZWN0ICpnZXRpdGVtc3RyLCAqc2V0aXRlbXN0ciwgKmRlbGl0ZW1zdHIsICpsZW5zdHI7CitzdGF0aWMgUHlPYmplY3QgKml0ZXJzdHIsICpuZXh0c3RyOworCitzdGF0aWMgUHlfc3NpemVfdAoraW5zdGFuY2VfbGVuZ3RoKFB5SW5zdGFuY2VPYmplY3QgKmluc3QpCit7CisgICAgUHlPYmplY3QgKmZ1bmM7CisgICAgUHlPYmplY3QgKnJlczsKKyAgICBQeV9zc2l6ZV90IG91dGNvbWU7CisKKyAgICBpZiAobGVuc3RyID09IE5VTEwpIHsKKyAgICAgICAgbGVuc3RyID0gUHlTdHJpbmdfSW50ZXJuRnJvbVN0cmluZygiX19sZW5fXyIpOworICAgICAgICBpZiAobGVuc3RyID09IE5VTEwpCisgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgfQorICAgIGZ1bmMgPSBpbnN0YW5jZV9nZXRhdHRyKGluc3QsIGxlbnN0cik7CisgICAgaWYgKGZ1bmMgPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIC0xOworICAgIHJlcyA9IFB5RXZhbF9DYWxsT2JqZWN0KGZ1bmMsIChQeU9iamVjdCAqKU5VTEwpOworICAgIFB5X0RFQ1JFRihmdW5jKTsKKyAgICBpZiAocmVzID09IE5VTEwpCisgICAgICAgIHJldHVybiAtMTsKKyAgICBpZiAoUHlJbnRfQ2hlY2socmVzKSkgeworICAgICAgICBvdXRjb21lID0gUHlJbnRfQXNTc2l6ZV90KHJlcyk7CisgICAgICAgIGlmIChvdXRjb21lID09IC0xICYmIFB5RXJyX09jY3VycmVkKCkpIHsKKyAgICAgICAgICAgIFB5X0RFQ1JFRihyZXMpOworICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICB9CisjaWYgU0laRU9GX1NJWkVfVCA8IFNJWkVPRl9JTlQKKyAgICAgICAgLyogT3ZlcmZsb3cgY2hlY2sgLS0gcmFuZ2Ugb2YgUHlJbnQgaXMgbW9yZSB0aGFuIEMgaW50ICovCisgICAgICAgIGlmIChvdXRjb21lICE9IChpbnQpb3V0Y29tZSkgeworICAgICAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX092ZXJmbG93RXJyb3IsCisgICAgICAgICAgICAgIl9fbGVuX18oKSBzaG91bGQgcmV0dXJuIDAgPD0gb3V0Y29tZSA8IDIqKjMxIik7CisgICAgICAgICAgICBvdXRjb21lID0gLTE7CisgICAgICAgIH0KKyAgICAgICAgZWxzZQorI2VuZGlmCisgICAgICAgIGlmIChvdXRjb21lIDwgMCkgeworICAgICAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1ZhbHVlRXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIl9fbGVuX18oKSBzaG91bGQgcmV0dXJuID49IDAiKTsKKyAgICAgICAgICAgIG91dGNvbWUgPSAtMTsKKyAgICAgICAgfQorICAgIH0KKyAgICBlbHNlIHsKKyAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1R5cGVFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICJfX2xlbl9fKCkgc2hvdWxkIHJldHVybiBhbiBpbnQiKTsKKyAgICAgICAgb3V0Y29tZSA9IC0xOworICAgIH0KKyAgICBQeV9ERUNSRUYocmVzKTsKKyAgICByZXR1cm4gb3V0Y29tZTsKK30KKworc3RhdGljIFB5T2JqZWN0ICoKK2luc3RhbmNlX3N1YnNjcmlwdChQeUluc3RhbmNlT2JqZWN0ICppbnN0LCBQeU9iamVjdCAqa2V5KQoreworICAgIFB5T2JqZWN0ICpmdW5jOworICAgIFB5T2JqZWN0ICphcmc7CisgICAgUHlPYmplY3QgKnJlczsKKworICAgIGlmIChnZXRpdGVtc3RyID09IE5VTEwpIHsKKyAgICAgICAgZ2V0aXRlbXN0ciA9IFB5U3RyaW5nX0ludGVybkZyb21TdHJpbmcoIl9fZ2V0aXRlbV9fIik7CisgICAgICAgIGlmIChnZXRpdGVtc3RyID09IE5VTEwpCisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgZnVuYyA9IGluc3RhbmNlX2dldGF0dHIoaW5zdCwgZ2V0aXRlbXN0cik7CisgICAgaWYgKGZ1bmMgPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgYXJnID0gUHlUdXBsZV9QYWNrKDEsIGtleSk7CisgICAgaWYgKGFyZyA9PSBOVUxMKSB7CisgICAgICAgIFB5X0RFQ1JFRihmdW5jKTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIHJlcyA9IFB5RXZhbF9DYWxsT2JqZWN0KGZ1bmMsIGFyZyk7CisgICAgUHlfREVDUkVGKGZ1bmMpOworICAgIFB5X0RFQ1JFRihhcmcpOworICAgIHJldHVybiByZXM7Cit9CisKK3N0YXRpYyBpbnQKK2luc3RhbmNlX2Fzc19zdWJzY3JpcHQoUHlJbnN0YW5jZU9iamVjdCAqaW5zdCwgUHlPYmplY3QgKmtleSwgUHlPYmplY3QgKnZhbHVlKQoreworICAgIFB5T2JqZWN0ICpmdW5jOworICAgIFB5T2JqZWN0ICphcmc7CisgICAgUHlPYmplY3QgKnJlczsKKworICAgIGlmICh2YWx1ZSA9PSBOVUxMKSB7CisgICAgICAgIGlmIChkZWxpdGVtc3RyID09IE5VTEwpIHsKKyAgICAgICAgICAgIGRlbGl0ZW1zdHIgPSBQeVN0cmluZ19JbnRlcm5Gcm9tU3RyaW5nKCJfX2RlbGl0ZW1fXyIpOworICAgICAgICAgICAgaWYgKGRlbGl0ZW1zdHIgPT0gTlVMTCkKKyAgICAgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgIH0KKyAgICAgICAgZnVuYyA9IGluc3RhbmNlX2dldGF0dHIoaW5zdCwgZGVsaXRlbXN0cik7CisgICAgfQorICAgIGVsc2UgeworICAgICAgICBpZiAoc2V0aXRlbXN0ciA9PSBOVUxMKSB7CisgICAgICAgICAgICBzZXRpdGVtc3RyID0gUHlTdHJpbmdfSW50ZXJuRnJvbVN0cmluZygiX19zZXRpdGVtX18iKTsKKyAgICAgICAgICAgIGlmIChzZXRpdGVtc3RyID09IE5VTEwpCisgICAgICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICB9CisgICAgICAgIGZ1bmMgPSBpbnN0YW5jZV9nZXRhdHRyKGluc3QsIHNldGl0ZW1zdHIpOworICAgIH0KKyAgICBpZiAoZnVuYyA9PSBOVUxMKQorICAgICAgICByZXR1cm4gLTE7CisgICAgaWYgKHZhbHVlID09IE5VTEwpCisgICAgICAgIGFyZyA9IFB5VHVwbGVfUGFjaygxLCBrZXkpOworICAgIGVsc2UKKyAgICAgICAgYXJnID0gUHlUdXBsZV9QYWNrKDIsIGtleSwgdmFsdWUpOworICAgIGlmIChhcmcgPT0gTlVMTCkgeworICAgICAgICBQeV9ERUNSRUYoZnVuYyk7CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisgICAgcmVzID0gUHlFdmFsX0NhbGxPYmplY3QoZnVuYywgYXJnKTsKKyAgICBQeV9ERUNSRUYoZnVuYyk7CisgICAgUHlfREVDUkVGKGFyZyk7CisgICAgaWYgKHJlcyA9PSBOVUxMKQorICAgICAgICByZXR1cm4gLTE7CisgICAgUHlfREVDUkVGKHJlcyk7CisgICAgcmV0dXJuIDA7Cit9CisKK3N0YXRpYyBQeU1hcHBpbmdNZXRob2RzIGluc3RhbmNlX2FzX21hcHBpbmcgPSB7CisgICAgKGxlbmZ1bmMpaW5zdGFuY2VfbGVuZ3RoLCAgICAgICAgICAgICAgICAgICAvKiBtcF9sZW5ndGggKi8KKyAgICAoYmluYXJ5ZnVuYylpbnN0YW5jZV9zdWJzY3JpcHQsICAgICAgICAgICAgIC8qIG1wX3N1YnNjcmlwdCAqLworICAgIChvYmpvYmphcmdwcm9jKWluc3RhbmNlX2Fzc19zdWJzY3JpcHQsICAgICAgLyogbXBfYXNzX3N1YnNjcmlwdCAqLworfTsKKworc3RhdGljIFB5T2JqZWN0ICoKK2luc3RhbmNlX2l0ZW0oUHlJbnN0YW5jZU9iamVjdCAqaW5zdCwgUHlfc3NpemVfdCBpKQoreworICAgIFB5T2JqZWN0ICpmdW5jLCAqcmVzOworCisgICAgaWYgKGdldGl0ZW1zdHIgPT0gTlVMTCkgeworICAgICAgICBnZXRpdGVtc3RyID0gUHlTdHJpbmdfSW50ZXJuRnJvbVN0cmluZygiX19nZXRpdGVtX18iKTsKKyAgICAgICAgaWYgKGdldGl0ZW1zdHIgPT0gTlVMTCkKKyAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICBmdW5jID0gaW5zdGFuY2VfZ2V0YXR0cihpbnN0LCBnZXRpdGVtc3RyKTsKKyAgICBpZiAoZnVuYyA9PSBOVUxMKQorICAgICAgICByZXR1cm4gTlVMTDsKKyAgICByZXMgPSBQeU9iamVjdF9DYWxsRnVuY3Rpb24oZnVuYywgIm4iLCBpKTsKKyAgICBQeV9ERUNSRUYoZnVuYyk7CisgICAgcmV0dXJuIHJlczsKK30KKworc3RhdGljIFB5T2JqZWN0ICoKK2luc3RhbmNlX3NsaWNlKFB5SW5zdGFuY2VPYmplY3QgKmluc3QsIFB5X3NzaXplX3QgaSwgUHlfc3NpemVfdCBqKQoreworICAgIFB5T2JqZWN0ICpmdW5jLCAqYXJnLCAqcmVzOworICAgIHN0YXRpYyBQeU9iamVjdCAqZ2V0c2xpY2VzdHI7CisKKyAgICBpZiAoZ2V0c2xpY2VzdHIgPT0gTlVMTCkgeworICAgICAgICBnZXRzbGljZXN0ciA9IFB5U3RyaW5nX0ludGVybkZyb21TdHJpbmcoIl9fZ2V0c2xpY2VfXyIpOworICAgICAgICBpZiAoZ2V0c2xpY2VzdHIgPT0gTlVMTCkKKyAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICBmdW5jID0gaW5zdGFuY2VfZ2V0YXR0cihpbnN0LCBnZXRzbGljZXN0cik7CisKKyAgICBpZiAoZnVuYyA9PSBOVUxMKSB7CisgICAgICAgIGlmICghUHlFcnJfRXhjZXB0aW9uTWF0Y2hlcyhQeUV4Y19BdHRyaWJ1dGVFcnJvcikpCisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgUHlFcnJfQ2xlYXIoKTsKKworICAgICAgICBpZiAoZ2V0aXRlbXN0ciA9PSBOVUxMKSB7CisgICAgICAgICAgICBnZXRpdGVtc3RyID0gUHlTdHJpbmdfSW50ZXJuRnJvbVN0cmluZygiX19nZXRpdGVtX18iKTsKKyAgICAgICAgICAgIGlmIChnZXRpdGVtc3RyID09IE5VTEwpCisgICAgICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgICAgIH0KKyAgICAgICAgZnVuYyA9IGluc3RhbmNlX2dldGF0dHIoaW5zdCwgZ2V0aXRlbXN0cik7CisgICAgICAgIGlmIChmdW5jID09IE5VTEwpCisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgYXJnID0gUHlfQnVpbGRWYWx1ZSgiKE4pIiwgX1B5U2xpY2VfRnJvbUluZGljZXMoaSwgaikpOworICAgIH0KKyAgICBlbHNlIHsKKyAgICAgICAgaWYgKFB5RXJyX1dhcm5QeTNrKCJpbiAzLngsIF9fZ2V0c2xpY2VfXyBoYXMgYmVlbiByZW1vdmVkOyAiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAidXNlIF9fZ2V0aXRlbV9fIiwgMSkgPCAwKSB7CisgICAgICAgICAgICBQeV9ERUNSRUYoZnVuYyk7CisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgfQorICAgICAgICBhcmcgPSBQeV9CdWlsZFZhbHVlKCIobm4pIiwgaSwgaik7CisgICAgfQorCisgICAgaWYgKGFyZyA9PSBOVUxMKSB7CisgICAgICAgIFB5X0RFQ1JFRihmdW5jKTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIHJlcyA9IFB5RXZhbF9DYWxsT2JqZWN0KGZ1bmMsIGFyZyk7CisgICAgUHlfREVDUkVGKGZ1bmMpOworICAgIFB5X0RFQ1JFRihhcmcpOworICAgIHJldHVybiByZXM7Cit9CisKK3N0YXRpYyBpbnQKK2luc3RhbmNlX2Fzc19pdGVtKFB5SW5zdGFuY2VPYmplY3QgKmluc3QsIFB5X3NzaXplX3QgaSwgUHlPYmplY3QgKml0ZW0pCit7CisgICAgUHlPYmplY3QgKmZ1bmMsICphcmcsICpyZXM7CisKKyAgICBpZiAoaXRlbSA9PSBOVUxMKSB7CisgICAgICAgIGlmIChkZWxpdGVtc3RyID09IE5VTEwpIHsKKyAgICAgICAgICAgIGRlbGl0ZW1zdHIgPSBQeVN0cmluZ19JbnRlcm5Gcm9tU3RyaW5nKCJfX2RlbGl0ZW1fXyIpOworICAgICAgICAgICAgaWYgKGRlbGl0ZW1zdHIgPT0gTlVMTCkKKyAgICAgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgIH0KKyAgICAgICAgZnVuYyA9IGluc3RhbmNlX2dldGF0dHIoaW5zdCwgZGVsaXRlbXN0cik7CisgICAgfQorICAgIGVsc2UgeworICAgICAgICBpZiAoc2V0aXRlbXN0ciA9PSBOVUxMKSB7CisgICAgICAgICAgICBzZXRpdGVtc3RyID0gUHlTdHJpbmdfSW50ZXJuRnJvbVN0cmluZygiX19zZXRpdGVtX18iKTsKKyAgICAgICAgICAgIGlmIChzZXRpdGVtc3RyID09IE5VTEwpCisgICAgICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICB9CisgICAgICAgIGZ1bmMgPSBpbnN0YW5jZV9nZXRhdHRyKGluc3QsIHNldGl0ZW1zdHIpOworICAgIH0KKyAgICBpZiAoZnVuYyA9PSBOVUxMKQorICAgICAgICByZXR1cm4gLTE7CisgICAgaWYgKGl0ZW0gPT0gTlVMTCkKKyAgICAgICAgYXJnID0gUHlfQnVpbGRWYWx1ZSgiKG4pIiwgaSk7CisgICAgZWxzZQorICAgICAgICBhcmcgPSBQeV9CdWlsZFZhbHVlKCIobk8pIiwgaSwgaXRlbSk7CisgICAgaWYgKGFyZyA9PSBOVUxMKSB7CisgICAgICAgIFB5X0RFQ1JFRihmdW5jKTsKKyAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKyAgICByZXMgPSBQeUV2YWxfQ2FsbE9iamVjdChmdW5jLCBhcmcpOworICAgIFB5X0RFQ1JFRihmdW5jKTsKKyAgICBQeV9ERUNSRUYoYXJnKTsKKyAgICBpZiAocmVzID09IE5VTEwpCisgICAgICAgIHJldHVybiAtMTsKKyAgICBQeV9ERUNSRUYocmVzKTsKKyAgICByZXR1cm4gMDsKK30KKworc3RhdGljIGludAoraW5zdGFuY2VfYXNzX3NsaWNlKFB5SW5zdGFuY2VPYmplY3QgKmluc3QsIFB5X3NzaXplX3QgaSwgUHlfc3NpemVfdCBqLCBQeU9iamVjdCAqdmFsdWUpCit7CisgICAgUHlPYmplY3QgKmZ1bmMsICphcmcsICpyZXM7CisgICAgc3RhdGljIFB5T2JqZWN0ICpzZXRzbGljZXN0ciwgKmRlbHNsaWNlc3RyOworCisgICAgaWYgKHZhbHVlID09IE5VTEwpIHsKKyAgICAgICAgaWYgKGRlbHNsaWNlc3RyID09IE5VTEwpIHsKKyAgICAgICAgICAgIGRlbHNsaWNlc3RyID0KKyAgICAgICAgICAgICAgICBQeVN0cmluZ19JbnRlcm5Gcm9tU3RyaW5nKCJfX2RlbHNsaWNlX18iKTsKKyAgICAgICAgICAgIGlmIChkZWxzbGljZXN0ciA9PSBOVUxMKQorICAgICAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgfQorICAgICAgICBmdW5jID0gaW5zdGFuY2VfZ2V0YXR0cihpbnN0LCBkZWxzbGljZXN0cik7CisgICAgICAgIGlmIChmdW5jID09IE5VTEwpIHsKKyAgICAgICAgICAgIGlmICghUHlFcnJfRXhjZXB0aW9uTWF0Y2hlcyhQeUV4Y19BdHRyaWJ1dGVFcnJvcikpCisgICAgICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICAgICAgUHlFcnJfQ2xlYXIoKTsKKyAgICAgICAgICAgIGlmIChkZWxpdGVtc3RyID09IE5VTEwpIHsKKyAgICAgICAgICAgICAgICBkZWxpdGVtc3RyID0KKyAgICAgICAgICAgICAgICAgICAgUHlTdHJpbmdfSW50ZXJuRnJvbVN0cmluZygiX19kZWxpdGVtX18iKTsKKyAgICAgICAgICAgICAgICBpZiAoZGVsaXRlbXN0ciA9PSBOVUxMKQorICAgICAgICAgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBmdW5jID0gaW5zdGFuY2VfZ2V0YXR0cihpbnN0LCBkZWxpdGVtc3RyKTsKKyAgICAgICAgICAgIGlmIChmdW5jID09IE5VTEwpCisgICAgICAgICAgICAgICAgcmV0dXJuIC0xOworCisgICAgICAgICAgICBhcmcgPSBQeV9CdWlsZFZhbHVlKCIoTikiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfUHlTbGljZV9Gcm9tSW5kaWNlcyhpLCBqKSk7CisgICAgICAgIH0KKyAgICAgICAgZWxzZSB7CisgICAgICAgICAgICBpZiAoUHlFcnJfV2FyblB5M2soImluIDMueCwgX19kZWxzbGljZV9fIGhhcyBiZWVuICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInJlbW92ZWQ7IHVzZSBfX2RlbGl0ZW1fXyIsIDEpIDwgMCkgeworICAgICAgICAgICAgICAgIFB5X0RFQ1JFRihmdW5jKTsKKyAgICAgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBhcmcgPSBQeV9CdWlsZFZhbHVlKCIobm4pIiwgaSwgaik7CisgICAgICAgIH0KKyAgICB9CisgICAgZWxzZSB7CisgICAgICAgIGlmIChzZXRzbGljZXN0ciA9PSBOVUxMKSB7CisgICAgICAgICAgICBzZXRzbGljZXN0ciA9CisgICAgICAgICAgICAgICAgUHlTdHJpbmdfSW50ZXJuRnJvbVN0cmluZygiX19zZXRzbGljZV9fIik7CisgICAgICAgICAgICBpZiAoc2V0c2xpY2VzdHIgPT0gTlVMTCkKKyAgICAgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgIH0KKyAgICAgICAgZnVuYyA9IGluc3RhbmNlX2dldGF0dHIoaW5zdCwgc2V0c2xpY2VzdHIpOworICAgICAgICBpZiAoZnVuYyA9PSBOVUxMKSB7CisgICAgICAgICAgICBpZiAoIVB5RXJyX0V4Y2VwdGlvbk1hdGNoZXMoUHlFeGNfQXR0cmlidXRlRXJyb3IpKQorICAgICAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgICAgIFB5RXJyX0NsZWFyKCk7CisgICAgICAgICAgICBpZiAoc2V0aXRlbXN0ciA9PSBOVUxMKSB7CisgICAgICAgICAgICAgICAgc2V0aXRlbXN0ciA9CisgICAgICAgICAgICAgICAgICAgIFB5U3RyaW5nX0ludGVybkZyb21TdHJpbmcoIl9fc2V0aXRlbV9fIik7CisgICAgICAgICAgICAgICAgaWYgKHNldGl0ZW1zdHIgPT0gTlVMTCkKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICAgICAgfQorICAgICAgICAgICAgZnVuYyA9IGluc3RhbmNlX2dldGF0dHIoaW5zdCwgc2V0aXRlbXN0cik7CisgICAgICAgICAgICBpZiAoZnVuYyA9PSBOVUxMKQorICAgICAgICAgICAgICAgIHJldHVybiAtMTsKKworICAgICAgICAgICAgYXJnID0gUHlfQnVpbGRWYWx1ZSgiKE5PKSIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9QeVNsaWNlX0Zyb21JbmRpY2VzKGksIGopLCB2YWx1ZSk7CisgICAgICAgIH0KKyAgICAgICAgZWxzZSB7CisgICAgICAgICAgICBpZiAoUHlFcnJfV2FyblB5M2soImluIDMueCwgX19zZXRzbGljZV9fIGhhcyBiZWVuICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAicmVtb3ZlZDsgdXNlIF9fc2V0aXRlbV9fIiwgMSkgPCAwKSB7CisgICAgICAgICAgICAgICAgUHlfREVDUkVGKGZ1bmMpOworICAgICAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGFyZyA9IFB5X0J1aWxkVmFsdWUoIihubk8pIiwgaSwgaiwgdmFsdWUpOworICAgICAgICB9CisgICAgfQorICAgIGlmIChhcmcgPT0gTlVMTCkgeworICAgICAgICBQeV9ERUNSRUYoZnVuYyk7CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisgICAgcmVzID0gUHlFdmFsX0NhbGxPYmplY3QoZnVuYywgYXJnKTsKKyAgICBQeV9ERUNSRUYoZnVuYyk7CisgICAgUHlfREVDUkVGKGFyZyk7CisgICAgaWYgKHJlcyA9PSBOVUxMKQorICAgICAgICByZXR1cm4gLTE7CisgICAgUHlfREVDUkVGKHJlcyk7CisgICAgcmV0dXJuIDA7Cit9CisKK3N0YXRpYyBpbnQKK2luc3RhbmNlX2NvbnRhaW5zKFB5SW5zdGFuY2VPYmplY3QgKmluc3QsIFB5T2JqZWN0ICptZW1iZXIpCit7CisgICAgc3RhdGljIFB5T2JqZWN0ICpfX2NvbnRhaW5zX187CisgICAgUHlPYmplY3QgKmZ1bmM7CisKKyAgICAvKiBUcnkgX19jb250YWluc19fIGZpcnN0LgorICAgICAqIElmIHRoYXQgY2FuJ3QgYmUgZG9uZSwgdHJ5IGl0ZXJhdG9yLWJhc2VkIHNlYXJjaGluZy4KKyAgICAgKi8KKworICAgIGlmKF9fY29udGFpbnNfXyA9PSBOVUxMKSB7CisgICAgICAgIF9fY29udGFpbnNfXyA9IFB5U3RyaW5nX0ludGVybkZyb21TdHJpbmcoIl9fY29udGFpbnNfXyIpOworICAgICAgICBpZihfX2NvbnRhaW5zX18gPT0gTlVMTCkKKyAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisgICAgZnVuYyA9IGluc3RhbmNlX2dldGF0dHIoaW5zdCwgX19jb250YWluc19fKTsKKyAgICBpZiAoZnVuYykgeworICAgICAgICBQeU9iamVjdCAqcmVzOworICAgICAgICBpbnQgcmV0OworICAgICAgICBQeU9iamVjdCAqYXJnID0gUHlUdXBsZV9QYWNrKDEsIG1lbWJlcik7CisgICAgICAgIGlmKGFyZyA9PSBOVUxMKSB7CisgICAgICAgICAgICBQeV9ERUNSRUYoZnVuYyk7CisgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgIH0KKyAgICAgICAgcmVzID0gUHlFdmFsX0NhbGxPYmplY3QoZnVuYywgYXJnKTsKKyAgICAgICAgUHlfREVDUkVGKGZ1bmMpOworICAgICAgICBQeV9ERUNSRUYoYXJnKTsKKyAgICAgICAgaWYocmVzID09IE5VTEwpCisgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgIHJldCA9IFB5T2JqZWN0X0lzVHJ1ZShyZXMpOworICAgICAgICBQeV9ERUNSRUYocmVzKTsKKyAgICAgICAgcmV0dXJuIHJldDsKKyAgICB9CisKKyAgICAvKiBDb3VsZG4ndCBmaW5kIF9fY29udGFpbnNfXy4gKi8KKyAgICBpZiAoUHlFcnJfRXhjZXB0aW9uTWF0Y2hlcyhQeUV4Y19BdHRyaWJ1dGVFcnJvcikpIHsKKyAgICAgICAgUHlfc3NpemVfdCByYzsKKyAgICAgICAgLyogQXNzdW1lIHRoZSBmYWlsdXJlIHdhcyBzaW1wbHkgZHVlIHRvIHRoYXQgdGhlcmUgaXMgbm8KKyAgICAgICAgICogX19jb250YWluc19fIGF0dHJpYnV0ZSwgYW5kIHRyeSBpdGVyYXRpbmcgaW5zdGVhZC4KKyAgICAgICAgICovCisgICAgICAgIFB5RXJyX0NsZWFyKCk7CisgICAgICAgIHJjID0gX1B5U2VxdWVuY2VfSXRlclNlYXJjaCgoUHlPYmplY3QgKilpbnN0LCBtZW1iZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQWV9JVEVSU0VBUkNIX0NPTlRBSU5TKTsKKyAgICAgICAgaWYgKHJjID49IDApCisgICAgICAgICAgICByZXR1cm4gcmMgPiAwOworICAgIH0KKyAgICByZXR1cm4gLTE7Cit9CisKK3N0YXRpYyBQeVNlcXVlbmNlTWV0aG9kcworaW5zdGFuY2VfYXNfc2VxdWVuY2UgPSB7CisgICAgKGxlbmZ1bmMpaW5zdGFuY2VfbGVuZ3RoLCAgICAgICAgICAgICAgICAgICAvKiBzcV9sZW5ndGggKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHNxX2NvbmNhdCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogc3FfcmVwZWF0ICovCisgICAgKHNzaXplYXJnZnVuYylpbnN0YW5jZV9pdGVtLCAgICAgICAgICAgICAgICAvKiBzcV9pdGVtICovCisgICAgKHNzaXplc3NpemVhcmdmdW5jKWluc3RhbmNlX3NsaWNlLCAgICAgICAgICAvKiBzcV9zbGljZSAqLworICAgIChzc2l6ZW9iamFyZ3Byb2MpaW5zdGFuY2VfYXNzX2l0ZW0sICAgICAgICAgLyogc3FfYXNzX2l0ZW0gKi8KKyAgICAoc3NpemVzc2l6ZW9iamFyZ3Byb2MpaW5zdGFuY2VfYXNzX3NsaWNlLC8qIHNxX2Fzc19zbGljZSAqLworICAgIChvYmpvYmpwcm9jKWluc3RhbmNlX2NvbnRhaW5zLCAgICAgICAgICAgICAgLyogc3FfY29udGFpbnMgKi8KK307CisKK3N0YXRpYyBQeU9iamVjdCAqCitnZW5lcmljX3VuYXJ5X29wKFB5SW5zdGFuY2VPYmplY3QgKnNlbGYsIFB5T2JqZWN0ICptZXRob2RuYW1lKQoreworICAgIFB5T2JqZWN0ICpmdW5jLCAqcmVzOworCisgICAgaWYgKChmdW5jID0gaW5zdGFuY2VfZ2V0YXR0cihzZWxmLCBtZXRob2RuYW1lKSkgPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgcmVzID0gUHlFdmFsX0NhbGxPYmplY3QoZnVuYywgKFB5T2JqZWN0ICopTlVMTCk7CisgICAgUHlfREVDUkVGKGZ1bmMpOworICAgIHJldHVybiByZXM7Cit9CisKK3N0YXRpYyBQeU9iamVjdCAqCitnZW5lcmljX2JpbmFyeV9vcChQeU9iamVjdCAqdiwgUHlPYmplY3QgKncsIGNoYXIgKm9wbmFtZSkKK3sKKyAgICBQeU9iamVjdCAqcmVzdWx0OworICAgIFB5T2JqZWN0ICphcmdzOworICAgIFB5T2JqZWN0ICpmdW5jID0gUHlPYmplY3RfR2V0QXR0clN0cmluZyh2LCBvcG5hbWUpOworICAgIGlmIChmdW5jID09IE5VTEwpIHsKKyAgICAgICAgaWYgKCFQeUVycl9FeGNlcHRpb25NYXRjaGVzKFB5RXhjX0F0dHJpYnV0ZUVycm9yKSkKKyAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgICAgICBQeUVycl9DbGVhcigpOworICAgICAgICBQeV9JTkNSRUYoUHlfTm90SW1wbGVtZW50ZWQpOworICAgICAgICByZXR1cm4gUHlfTm90SW1wbGVtZW50ZWQ7CisgICAgfQorICAgIGFyZ3MgPSBQeVR1cGxlX1BhY2soMSwgdyk7CisgICAgaWYgKGFyZ3MgPT0gTlVMTCkgeworICAgICAgICBQeV9ERUNSRUYoZnVuYyk7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICByZXN1bHQgPSBQeUV2YWxfQ2FsbE9iamVjdChmdW5jLCBhcmdzKTsKKyAgICBQeV9ERUNSRUYoYXJncyk7CisgICAgUHlfREVDUkVGKGZ1bmMpOworICAgIHJldHVybiByZXN1bHQ7Cit9CisKKworc3RhdGljIFB5T2JqZWN0ICpjb2VyY2Vfb2JqOworCisvKiBUcnkgb25lIGhhbGYgb2YgYSBiaW5hcnkgb3BlcmF0b3IgaW52b2x2aW5nIGEgY2xhc3MgaW5zdGFuY2UuICovCitzdGF0aWMgUHlPYmplY3QgKgoraGFsZl9iaW5vcChQeU9iamVjdCAqdiwgUHlPYmplY3QgKncsIGNoYXIgKm9wbmFtZSwgYmluYXJ5ZnVuYyB0aGlzZnVuYywKKyAgICAgICAgICAgICAgICBpbnQgc3dhcHBlZCkKK3sKKyAgICBQeU9iamVjdCAqYXJnczsKKyAgICBQeU9iamVjdCAqY29lcmNlZnVuYzsKKyAgICBQeU9iamVjdCAqY29lcmNlZCA9IE5VTEw7CisgICAgUHlPYmplY3QgKnYxOworICAgIFB5T2JqZWN0ICpyZXN1bHQ7CisKKyAgICBpZiAoIVB5SW5zdGFuY2VfQ2hlY2sodikpIHsKKyAgICAgICAgUHlfSU5DUkVGKFB5X05vdEltcGxlbWVudGVkKTsKKyAgICAgICAgcmV0dXJuIFB5X05vdEltcGxlbWVudGVkOworICAgIH0KKworICAgIGlmIChjb2VyY2Vfb2JqID09IE5VTEwpIHsKKyAgICAgICAgY29lcmNlX29iaiA9IFB5U3RyaW5nX0ludGVybkZyb21TdHJpbmcoIl9fY29lcmNlX18iKTsKKyAgICAgICAgaWYgKGNvZXJjZV9vYmogPT0gTlVMTCkKKyAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICBjb2VyY2VmdW5jID0gUHlPYmplY3RfR2V0QXR0cih2LCBjb2VyY2Vfb2JqKTsKKyAgICBpZiAoY29lcmNlZnVuYyA9PSBOVUxMKSB7CisgICAgICAgIGlmICghUHlFcnJfRXhjZXB0aW9uTWF0Y2hlcyhQeUV4Y19BdHRyaWJ1dGVFcnJvcikpCisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgUHlFcnJfQ2xlYXIoKTsKKyAgICAgICAgcmV0dXJuIGdlbmVyaWNfYmluYXJ5X29wKHYsIHcsIG9wbmFtZSk7CisgICAgfQorCisgICAgYXJncyA9IFB5VHVwbGVfUGFjaygxLCB3KTsKKyAgICBpZiAoYXJncyA9PSBOVUxMKSB7CisgICAgICAgIFB5X0RFQ1JFRihjb2VyY2VmdW5jKTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIGNvZXJjZWQgPSBQeUV2YWxfQ2FsbE9iamVjdChjb2VyY2VmdW5jLCBhcmdzKTsKKyAgICBQeV9ERUNSRUYoYXJncyk7CisgICAgUHlfREVDUkVGKGNvZXJjZWZ1bmMpOworICAgIGlmIChjb2VyY2VkID09IE5VTEwpIHsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIGlmIChjb2VyY2VkID09IFB5X05vbmUgfHwgY29lcmNlZCA9PSBQeV9Ob3RJbXBsZW1lbnRlZCkgeworICAgICAgICBQeV9ERUNSRUYoY29lcmNlZCk7CisgICAgICAgIHJldHVybiBnZW5lcmljX2JpbmFyeV9vcCh2LCB3LCBvcG5hbWUpOworICAgIH0KKyAgICBpZiAoIVB5VHVwbGVfQ2hlY2soY29lcmNlZCkgfHwgUHlUdXBsZV9TaXplKGNvZXJjZWQpICE9IDIpIHsKKyAgICAgICAgUHlfREVDUkVGKGNvZXJjZWQpOworICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfVHlwZUVycm9yLAorICAgICAgICAgICAgICAgICAgICAgICAgImNvZXJjaW9uIHNob3VsZCByZXR1cm4gTm9uZSBvciAyLXR1cGxlIik7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICB2MSA9IFB5VHVwbGVfR2V0SXRlbShjb2VyY2VkLCAwKTsKKyAgICB3ID0gUHlUdXBsZV9HZXRJdGVtKGNvZXJjZWQsIDEpOworICAgIGlmICh2MS0+b2JfdHlwZSA9PSB2LT5vYl90eXBlICYmIFB5SW5zdGFuY2VfQ2hlY2sodikpIHsKKyAgICAgICAgLyogcHJldmVudCByZWN1cnNpb24gaWYgX19jb2VyY2VfXyByZXR1cm5zIHNlbGYgYXMgdGhlIGZpcnN0CisgICAgICAgICAqIGFyZ3VtZW50ICovCisgICAgICAgIHJlc3VsdCA9IGdlbmVyaWNfYmluYXJ5X29wKHYxLCB3LCBvcG5hbWUpOworICAgIH0gZWxzZSB7CisgICAgICAgIGlmIChQeV9FbnRlclJlY3Vyc2l2ZUNhbGwoIiBhZnRlciBjb2VyY2lvbiIpKQorICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgICAgIGlmIChzd2FwcGVkKQorICAgICAgICAgICAgcmVzdWx0ID0gKHRoaXNmdW5jKSh3LCB2MSk7CisgICAgICAgIGVsc2UKKyAgICAgICAgICAgIHJlc3VsdCA9ICh0aGlzZnVuYykodjEsIHcpOworICAgICAgICBQeV9MZWF2ZVJlY3Vyc2l2ZUNhbGwoKTsKKyAgICB9CisgICAgUHlfREVDUkVGKGNvZXJjZWQpOworICAgIHJldHVybiByZXN1bHQ7Cit9CisKKy8qIEltcGxlbWVudCBhIGJpbmFyeSBvcGVyYXRvciBpbnZvbHZpbmcgYXQgbGVhc3Qgb25lIGNsYXNzIGluc3RhbmNlLiAqLworc3RhdGljIFB5T2JqZWN0ICoKK2RvX2Jpbm9wKFB5T2JqZWN0ICp2LCBQeU9iamVjdCAqdywgY2hhciAqb3BuYW1lLCBjaGFyICpyb3BuYW1lLAorICAgICAgICAgICAgICAgICAgIGJpbmFyeWZ1bmMgdGhpc2Z1bmMpCit7CisgICAgUHlPYmplY3QgKnJlc3VsdCA9IGhhbGZfYmlub3Aodiwgdywgb3BuYW1lLCB0aGlzZnVuYywgMCk7CisgICAgaWYgKHJlc3VsdCA9PSBQeV9Ob3RJbXBsZW1lbnRlZCkgeworICAgICAgICBQeV9ERUNSRUYocmVzdWx0KTsKKyAgICAgICAgcmVzdWx0ID0gaGFsZl9iaW5vcCh3LCB2LCByb3BuYW1lLCB0aGlzZnVuYywgMSk7CisgICAgfQorICAgIHJldHVybiByZXN1bHQ7Cit9CisKK3N0YXRpYyBQeU9iamVjdCAqCitkb19iaW5vcF9pbnBsYWNlKFB5T2JqZWN0ICp2LCBQeU9iamVjdCAqdywgY2hhciAqaW9wbmFtZSwgY2hhciAqb3BuYW1lLAorICAgICAgICAgICAgICAgICAgICAgICAgY2hhciAqcm9wbmFtZSwgYmluYXJ5ZnVuYyB0aGlzZnVuYykKK3sKKyAgICBQeU9iamVjdCAqcmVzdWx0ID0gaGFsZl9iaW5vcCh2LCB3LCBpb3BuYW1lLCB0aGlzZnVuYywgMCk7CisgICAgaWYgKHJlc3VsdCA9PSBQeV9Ob3RJbXBsZW1lbnRlZCkgeworICAgICAgICBQeV9ERUNSRUYocmVzdWx0KTsKKyAgICAgICAgcmVzdWx0ID0gZG9fYmlub3Aodiwgdywgb3BuYW1lLCByb3BuYW1lLCB0aGlzZnVuYyk7CisgICAgfQorICAgIHJldHVybiByZXN1bHQ7Cit9CisKK3N0YXRpYyBpbnQKK2luc3RhbmNlX2NvZXJjZShQeU9iamVjdCAqKnB2LCBQeU9iamVjdCAqKnB3KQoreworICAgIFB5T2JqZWN0ICp2ID0gKnB2OworICAgIFB5T2JqZWN0ICp3ID0gKnB3OworICAgIFB5T2JqZWN0ICpjb2VyY2VmdW5jOworICAgIFB5T2JqZWN0ICphcmdzOworICAgIFB5T2JqZWN0ICpjb2VyY2VkOworCisgICAgaWYgKGNvZXJjZV9vYmogPT0gTlVMTCkgeworICAgICAgICBjb2VyY2Vfb2JqID0gUHlTdHJpbmdfSW50ZXJuRnJvbVN0cmluZygiX19jb2VyY2VfXyIpOworICAgICAgICBpZiAoY29lcmNlX29iaiA9PSBOVUxMKQorICAgICAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKyAgICBjb2VyY2VmdW5jID0gUHlPYmplY3RfR2V0QXR0cih2LCBjb2VyY2Vfb2JqKTsKKyAgICBpZiAoY29lcmNlZnVuYyA9PSBOVUxMKSB7CisgICAgICAgIC8qIE5vIF9fY29lcmNlX18gbWV0aG9kICovCisgICAgICAgIGlmICghUHlFcnJfRXhjZXB0aW9uTWF0Y2hlcyhQeUV4Y19BdHRyaWJ1dGVFcnJvcikpCisgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgIFB5RXJyX0NsZWFyKCk7CisgICAgICAgIHJldHVybiAxOworICAgIH0KKyAgICAvKiBIYXMgX19jb2VyY2VfXyBtZXRob2Q6IGNhbGwgaXQgKi8KKyAgICBhcmdzID0gUHlUdXBsZV9QYWNrKDEsIHcpOworICAgIGlmIChhcmdzID09IE5VTEwpIHsKKyAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKyAgICBjb2VyY2VkID0gUHlFdmFsX0NhbGxPYmplY3QoY29lcmNlZnVuYywgYXJncyk7CisgICAgUHlfREVDUkVGKGFyZ3MpOworICAgIFB5X0RFQ1JFRihjb2VyY2VmdW5jKTsKKyAgICBpZiAoY29lcmNlZCA9PSBOVUxMKSB7CisgICAgICAgIC8qIF9fY29lcmNlX18gY2FsbCByYWlzZWQgYW4gZXhjZXB0aW9uICovCisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisgICAgaWYgKGNvZXJjZWQgPT0gUHlfTm9uZSB8fCBjb2VyY2VkID09IFB5X05vdEltcGxlbWVudGVkKSB7CisgICAgICAgIC8qIF9fY29lcmNlX18gc2F5cyAiSSBjYW4ndCBkbyBpdCIgKi8KKyAgICAgICAgUHlfREVDUkVGKGNvZXJjZWQpOworICAgICAgICByZXR1cm4gMTsKKyAgICB9CisgICAgaWYgKCFQeVR1cGxlX0NoZWNrKGNvZXJjZWQpIHx8IFB5VHVwbGVfU2l6ZShjb2VyY2VkKSAhPSAyKSB7CisgICAgICAgIC8qIF9fY29lcmNlX18gcmV0dXJuIHZhbHVlIGlzIG1hbGZvcm1lZCAqLworICAgICAgICBQeV9ERUNSRUYoY29lcmNlZCk7CisgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19UeXBlRXJyb3IsCisgICAgICAgICAgICAgICAgICAgImNvZXJjaW9uIHNob3VsZCByZXR1cm4gTm9uZSBvciAyLXR1cGxlIik7CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisgICAgLyogX19jb2VyY2VfXyByZXR1cm5lZCB0d28gbmV3IHZhbHVlcyAqLworICAgICpwdiA9IFB5VHVwbGVfR2V0SXRlbShjb2VyY2VkLCAwKTsKKyAgICAqcHcgPSBQeVR1cGxlX0dldEl0ZW0oY29lcmNlZCwgMSk7CisgICAgUHlfSU5DUkVGKCpwdik7CisgICAgUHlfSU5DUkVGKCpwdyk7CisgICAgUHlfREVDUkVGKGNvZXJjZWQpOworICAgIHJldHVybiAwOworfQorCisjZGVmaW5lIFVOQVJZKGZ1bmNuYW1lLCBtZXRob2RuYW1lKSBcCitzdGF0aWMgUHlPYmplY3QgKmZ1bmNuYW1lKFB5SW5zdGFuY2VPYmplY3QgKnNlbGYpIHsgXAorICAgIHN0YXRpYyBQeU9iamVjdCAqbzsgXAorICAgIGlmIChvID09IE5VTEwpIHsgbyA9IFB5U3RyaW5nX0ludGVybkZyb21TdHJpbmcobWV0aG9kbmFtZSk7IFwKKyAgICAgICAgICAgICAgICAgICAgIGlmIChvID09IE5VTEwpIHJldHVybiBOVUxMOyB9IFwKKyAgICByZXR1cm4gZ2VuZXJpY191bmFyeV9vcChzZWxmLCBvKTsgXAorfQorCisvKiB1bmFyeSBmdW5jdGlvbiB3aXRoIGEgZmFsbGJhY2sgKi8KKyNkZWZpbmUgVU5BUllfRkIoZnVuY25hbWUsIG1ldGhvZG5hbWUsIGZ1bmNuYW1lX2ZiKSBcCitzdGF0aWMgUHlPYmplY3QgKmZ1bmNuYW1lKFB5SW5zdGFuY2VPYmplY3QgKnNlbGYpIHsgXAorICAgIHN0YXRpYyBQeU9iamVjdCAqbzsgXAorICAgIGlmIChvID09IE5VTEwpIHsgbyA9IFB5U3RyaW5nX0ludGVybkZyb21TdHJpbmcobWV0aG9kbmFtZSk7IFwKKyAgICAgICAgICAgICAgICAgICAgIGlmIChvID09IE5VTEwpIHJldHVybiBOVUxMOyB9IFwKKyAgICBpZiAoUHlPYmplY3RfSGFzQXR0cigoUHlPYmplY3QqKXNlbGYsIG8pKSBcCisgICAgICAgIHJldHVybiBnZW5lcmljX3VuYXJ5X29wKHNlbGYsIG8pOyBcCisgICAgZWxzZSBcCisgICAgICAgIHJldHVybiBmdW5jbmFtZV9mYihzZWxmKTsgXAorfQorCisjZGVmaW5lIEJJTkFSWShmLCBtLCBuKSBcCitzdGF0aWMgUHlPYmplY3QgKmYoUHlPYmplY3QgKnYsIFB5T2JqZWN0ICp3KSB7IFwKKyAgICByZXR1cm4gZG9fYmlub3AodiwgdywgIl9fIiBtICJfXyIsICJfX3IiIG0gIl9fIiwgbik7IFwKK30KKworI2RlZmluZSBCSU5BUllfSU5QTEFDRShmLCBtLCBuKSBcCitzdGF0aWMgUHlPYmplY3QgKmYoUHlPYmplY3QgKnYsIFB5T2JqZWN0ICp3KSB7IFwKKyAgICByZXR1cm4gZG9fYmlub3BfaW5wbGFjZSh2LCB3LCAiX19pIiBtICJfXyIsICJfXyIgbSAiX18iLCBcCisgICAgICAgICAgICAgICAgICAgICJfX3IiIG0gIl9fIiwgbik7IFwKK30KKworVU5BUlkoaW5zdGFuY2VfbmVnLCAiX19uZWdfXyIpCitVTkFSWShpbnN0YW5jZV9wb3MsICJfX3Bvc19fIikKK1VOQVJZKGluc3RhbmNlX2FicywgIl9fYWJzX18iKQorCitCSU5BUlkoaW5zdGFuY2Vfb3IsICJvciIsIFB5TnVtYmVyX09yKQorQklOQVJZKGluc3RhbmNlX2FuZCwgImFuZCIsIFB5TnVtYmVyX0FuZCkKK0JJTkFSWShpbnN0YW5jZV94b3IsICJ4b3IiLCBQeU51bWJlcl9Yb3IpCitCSU5BUlkoaW5zdGFuY2VfbHNoaWZ0LCAibHNoaWZ0IiwgUHlOdW1iZXJfTHNoaWZ0KQorQklOQVJZKGluc3RhbmNlX3JzaGlmdCwgInJzaGlmdCIsIFB5TnVtYmVyX1JzaGlmdCkKK0JJTkFSWShpbnN0YW5jZV9hZGQsICJhZGQiLCBQeU51bWJlcl9BZGQpCitCSU5BUlkoaW5zdGFuY2Vfc3ViLCAic3ViIiwgUHlOdW1iZXJfU3VidHJhY3QpCitCSU5BUlkoaW5zdGFuY2VfbXVsLCAibXVsIiwgUHlOdW1iZXJfTXVsdGlwbHkpCitCSU5BUlkoaW5zdGFuY2VfZGl2LCAiZGl2IiwgUHlOdW1iZXJfRGl2aWRlKQorQklOQVJZKGluc3RhbmNlX21vZCwgIm1vZCIsIFB5TnVtYmVyX1JlbWFpbmRlcikKK0JJTkFSWShpbnN0YW5jZV9kaXZtb2QsICJkaXZtb2QiLCBQeU51bWJlcl9EaXZtb2QpCitCSU5BUlkoaW5zdGFuY2VfZmxvb3JkaXYsICJmbG9vcmRpdiIsIFB5TnVtYmVyX0Zsb29yRGl2aWRlKQorQklOQVJZKGluc3RhbmNlX3RydWVkaXYsICJ0cnVlZGl2IiwgUHlOdW1iZXJfVHJ1ZURpdmlkZSkKKworQklOQVJZX0lOUExBQ0UoaW5zdGFuY2VfaW9yLCAib3IiLCBQeU51bWJlcl9JblBsYWNlT3IpCitCSU5BUllfSU5QTEFDRShpbnN0YW5jZV9peG9yLCAieG9yIiwgUHlOdW1iZXJfSW5QbGFjZVhvcikKK0JJTkFSWV9JTlBMQUNFKGluc3RhbmNlX2lhbmQsICJhbmQiLCBQeU51bWJlcl9JblBsYWNlQW5kKQorQklOQVJZX0lOUExBQ0UoaW5zdGFuY2VfaWxzaGlmdCwgImxzaGlmdCIsIFB5TnVtYmVyX0luUGxhY2VMc2hpZnQpCitCSU5BUllfSU5QTEFDRShpbnN0YW5jZV9pcnNoaWZ0LCAicnNoaWZ0IiwgUHlOdW1iZXJfSW5QbGFjZVJzaGlmdCkKK0JJTkFSWV9JTlBMQUNFKGluc3RhbmNlX2lhZGQsICJhZGQiLCBQeU51bWJlcl9JblBsYWNlQWRkKQorQklOQVJZX0lOUExBQ0UoaW5zdGFuY2VfaXN1YiwgInN1YiIsIFB5TnVtYmVyX0luUGxhY2VTdWJ0cmFjdCkKK0JJTkFSWV9JTlBMQUNFKGluc3RhbmNlX2ltdWwsICJtdWwiLCBQeU51bWJlcl9JblBsYWNlTXVsdGlwbHkpCitCSU5BUllfSU5QTEFDRShpbnN0YW5jZV9pZGl2LCAiZGl2IiwgUHlOdW1iZXJfSW5QbGFjZURpdmlkZSkKK0JJTkFSWV9JTlBMQUNFKGluc3RhbmNlX2ltb2QsICJtb2QiLCBQeU51bWJlcl9JblBsYWNlUmVtYWluZGVyKQorQklOQVJZX0lOUExBQ0UoaW5zdGFuY2VfaWZsb29yZGl2LCAiZmxvb3JkaXYiLCBQeU51bWJlcl9JblBsYWNlRmxvb3JEaXZpZGUpCitCSU5BUllfSU5QTEFDRShpbnN0YW5jZV9pdHJ1ZWRpdiwgInRydWVkaXYiLCBQeU51bWJlcl9JblBsYWNlVHJ1ZURpdmlkZSkKKworLyogVHJ5IGEgMy13YXkgY29tcGFyaXNvbiwgcmV0dXJuaW5nIGFuIGludDsgdiBpcyBhbiBpbnN0YW5jZS4gIFJldHVybjoKKyAgIC0yIGZvciBhbiBleGNlcHRpb247CisgICAtMSBpZiB2IDwgdzsKKyAgIDAgaWYgdiA9PSB3OworICAgMSBpZiB2ID4gdzsKKyAgIDIgaWYgdGhpcyBwYXJ0aWN1bGFyIDMtd2F5IGNvbXBhcmlzb24gaXMgbm90IGltcGxlbWVudGVkIG9yIHVuZGVmaW5lZC4KKyovCitzdGF0aWMgaW50CitoYWxmX2NtcChQeU9iamVjdCAqdiwgUHlPYmplY3QgKncpCit7CisgICAgc3RhdGljIFB5T2JqZWN0ICpjbXBfb2JqOworICAgIFB5T2JqZWN0ICphcmdzOworICAgIFB5T2JqZWN0ICpjbXBfZnVuYzsKKyAgICBQeU9iamVjdCAqcmVzdWx0OworICAgIGxvbmcgbDsKKworICAgIGFzc2VydChQeUluc3RhbmNlX0NoZWNrKHYpKTsKKworICAgIGlmIChjbXBfb2JqID09IE5VTEwpIHsKKyAgICAgICAgY21wX29iaiA9IFB5U3RyaW5nX0ludGVybkZyb21TdHJpbmcoIl9fY21wX18iKTsKKyAgICAgICAgaWYgKGNtcF9vYmogPT0gTlVMTCkKKyAgICAgICAgICAgIHJldHVybiAtMjsKKyAgICB9CisKKyAgICBjbXBfZnVuYyA9IFB5T2JqZWN0X0dldEF0dHIodiwgY21wX29iaik7CisgICAgaWYgKGNtcF9mdW5jID09IE5VTEwpIHsKKyAgICAgICAgaWYgKCFQeUVycl9FeGNlcHRpb25NYXRjaGVzKFB5RXhjX0F0dHJpYnV0ZUVycm9yKSkKKyAgICAgICAgICAgIHJldHVybiAtMjsKKyAgICAgICAgUHlFcnJfQ2xlYXIoKTsKKyAgICAgICAgcmV0dXJuIDI7CisgICAgfQorCisgICAgYXJncyA9IFB5VHVwbGVfUGFjaygxLCB3KTsKKyAgICBpZiAoYXJncyA9PSBOVUxMKSB7CisgICAgICAgIFB5X0RFQ1JFRihjbXBfZnVuYyk7CisgICAgICAgIHJldHVybiAtMjsKKyAgICB9CisKKyAgICByZXN1bHQgPSBQeUV2YWxfQ2FsbE9iamVjdChjbXBfZnVuYywgYXJncyk7CisgICAgUHlfREVDUkVGKGFyZ3MpOworICAgIFB5X0RFQ1JFRihjbXBfZnVuYyk7CisKKyAgICBpZiAocmVzdWx0ID09IE5VTEwpCisgICAgICAgIHJldHVybiAtMjsKKworICAgIGlmIChyZXN1bHQgPT0gUHlfTm90SW1wbGVtZW50ZWQpIHsKKyAgICAgICAgUHlfREVDUkVGKHJlc3VsdCk7CisgICAgICAgIHJldHVybiAyOworICAgIH0KKworICAgIGwgPSBQeUludF9Bc0xvbmcocmVzdWx0KTsKKyAgICBQeV9ERUNSRUYocmVzdWx0KTsKKyAgICBpZiAobCA9PSAtMSAmJiBQeUVycl9PY2N1cnJlZCgpKSB7CisgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19UeXBlRXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAiY29tcGFyaXNvbiBkaWQgbm90IHJldHVybiBhbiBpbnQiKTsKKyAgICAgICAgcmV0dXJuIC0yOworICAgIH0KKworICAgIHJldHVybiBsIDwgMCA/IC0xIDogbCA+IDAgPyAxIDogMDsKK30KKworLyogVHJ5IGEgMy13YXkgY29tcGFyaXNvbiwgcmV0dXJuaW5nIGFuIGludDsgZWl0aGVyIHYgb3IgdyBpcyBhbiBpbnN0YW5jZS4KKyAgIFdlIGZpcnN0IHRyeSBhIGNvZXJjaW9uLiAgUmV0dXJuOgorICAgLTIgZm9yIGFuIGV4Y2VwdGlvbjsKKyAgIC0xIGlmIHYgPCB3OworICAgMCBpZiB2ID09IHc7CisgICAxIGlmIHYgPiB3OworICAgMiBpZiB0aGlzIHBhcnRpY3VsYXIgMy13YXkgY29tcGFyaXNvbiBpcyBub3QgaW1wbGVtZW50ZWQgb3IgdW5kZWZpbmVkLgorICAgVEhJUyBJUyBPTkxZIENBTExFRCBGUk9NIG9iamVjdC5jIQorKi8KK3N0YXRpYyBpbnQKK2luc3RhbmNlX2NvbXBhcmUoUHlPYmplY3QgKnYsIFB5T2JqZWN0ICp3KQoreworICAgIGludCBjOworCisgICAgYyA9IFB5TnVtYmVyX0NvZXJjZUV4KCZ2LCAmdyk7CisgICAgaWYgKGMgPCAwKQorICAgICAgICByZXR1cm4gLTI7CisgICAgaWYgKGMgPT0gMCkgeworICAgICAgICAvKiBJZiBuZWl0aGVyIGlzIG5vdyBhbiBpbnN0YW5jZSwgdXNlIHJlZ3VsYXIgY29tcGFyaXNvbiAqLworICAgICAgICBpZiAoIVB5SW5zdGFuY2VfQ2hlY2sodikgJiYgIVB5SW5zdGFuY2VfQ2hlY2sodykpIHsKKyAgICAgICAgICAgIGMgPSBQeU9iamVjdF9Db21wYXJlKHYsIHcpOworICAgICAgICAgICAgUHlfREVDUkVGKHYpOworICAgICAgICAgICAgUHlfREVDUkVGKHcpOworICAgICAgICAgICAgaWYgKFB5RXJyX09jY3VycmVkKCkpCisgICAgICAgICAgICAgICAgcmV0dXJuIC0yOworICAgICAgICAgICAgcmV0dXJuIGMgPCAwID8gLTEgOiBjID4gMCA/IDEgOiAwOworICAgICAgICB9CisgICAgfQorICAgIGVsc2UgeworICAgICAgICAvKiBUaGUgY29lcmNpb24gZGlkbid0IGRvIGFueXRoaW5nLgorICAgICAgICAgICBUcmVhdCB0aGlzIHRoZSBzYW1lIGFzIHJldHVybmluZyB2IGFuZCB3IHVuY2hhbmdlZC4gKi8KKyAgICAgICAgUHlfSU5DUkVGKHYpOworICAgICAgICBQeV9JTkNSRUYodyk7CisgICAgfQorCisgICAgaWYgKFB5SW5zdGFuY2VfQ2hlY2sodikpIHsKKyAgICAgICAgYyA9IGhhbGZfY21wKHYsIHcpOworICAgICAgICBpZiAoYyA8PSAxKSB7CisgICAgICAgICAgICBQeV9ERUNSRUYodik7CisgICAgICAgICAgICBQeV9ERUNSRUYodyk7CisgICAgICAgICAgICByZXR1cm4gYzsKKyAgICAgICAgfQorICAgIH0KKyAgICBpZiAoUHlJbnN0YW5jZV9DaGVjayh3KSkgeworICAgICAgICBjID0gaGFsZl9jbXAodywgdik7CisgICAgICAgIGlmIChjIDw9IDEpIHsKKyAgICAgICAgICAgIFB5X0RFQ1JFRih2KTsKKyAgICAgICAgICAgIFB5X0RFQ1JFRih3KTsKKyAgICAgICAgICAgIGlmIChjID49IC0xKQorICAgICAgICAgICAgICAgIGMgPSAtYzsKKyAgICAgICAgICAgIHJldHVybiBjOworICAgICAgICB9CisgICAgfQorICAgIFB5X0RFQ1JFRih2KTsKKyAgICBQeV9ERUNSRUYodyk7CisgICAgcmV0dXJuIDI7Cit9CisKK3N0YXRpYyBpbnQKK2luc3RhbmNlX25vbnplcm8oUHlJbnN0YW5jZU9iamVjdCAqc2VsZikKK3sKKyAgICBQeU9iamVjdCAqZnVuYywgKnJlczsKKyAgICBsb25nIG91dGNvbWU7CisgICAgc3RhdGljIFB5T2JqZWN0ICpub256ZXJvc3RyOworCisgICAgaWYgKG5vbnplcm9zdHIgPT0gTlVMTCkgeworICAgICAgICBub256ZXJvc3RyID0gUHlTdHJpbmdfSW50ZXJuRnJvbVN0cmluZygiX19ub256ZXJvX18iKTsKKyAgICAgICAgaWYgKG5vbnplcm9zdHIgPT0gTlVMTCkKKyAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisgICAgaWYgKChmdW5jID0gaW5zdGFuY2VfZ2V0YXR0cihzZWxmLCBub256ZXJvc3RyKSkgPT0gTlVMTCkgeworICAgICAgICBpZiAoIVB5RXJyX0V4Y2VwdGlvbk1hdGNoZXMoUHlFeGNfQXR0cmlidXRlRXJyb3IpKQorICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICBQeUVycl9DbGVhcigpOworICAgICAgICBpZiAobGVuc3RyID09IE5VTEwpIHsKKyAgICAgICAgICAgIGxlbnN0ciA9IFB5U3RyaW5nX0ludGVybkZyb21TdHJpbmcoIl9fbGVuX18iKTsKKyAgICAgICAgICAgIGlmIChsZW5zdHIgPT0gTlVMTCkKKyAgICAgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgIH0KKyAgICAgICAgaWYgKChmdW5jID0gaW5zdGFuY2VfZ2V0YXR0cihzZWxmLCBsZW5zdHIpKSA9PSBOVUxMKSB7CisgICAgICAgICAgICBpZiAoIVB5RXJyX0V4Y2VwdGlvbk1hdGNoZXMoUHlFeGNfQXR0cmlidXRlRXJyb3IpKQorICAgICAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgICAgIFB5RXJyX0NsZWFyKCk7CisgICAgICAgICAgICAvKiBGYWxsIGJhY2sgdG8gdGhlIGRlZmF1bHQgYmVoYXZpb3I6CisgICAgICAgICAgICAgICBhbGwgaW5zdGFuY2VzIGFyZSBub256ZXJvICovCisgICAgICAgICAgICByZXR1cm4gMTsKKyAgICAgICAgfQorICAgIH0KKyAgICByZXMgPSBQeUV2YWxfQ2FsbE9iamVjdChmdW5jLCAoUHlPYmplY3QgKilOVUxMKTsKKyAgICBQeV9ERUNSRUYoZnVuYyk7CisgICAgaWYgKHJlcyA9PSBOVUxMKQorICAgICAgICByZXR1cm4gLTE7CisgICAgaWYgKCFQeUludF9DaGVjayhyZXMpKSB7CisgICAgICAgIFB5X0RFQ1JFRihyZXMpOworICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfVHlwZUVycm9yLAorICAgICAgICAgICAgICAgICAgICAgICAgIl9fbm9uemVyb19fIHNob3VsZCByZXR1cm4gYW4gaW50Iik7CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisgICAgb3V0Y29tZSA9IFB5SW50X0FzTG9uZyhyZXMpOworICAgIFB5X0RFQ1JFRihyZXMpOworICAgIGlmIChvdXRjb21lIDwgMCkgeworICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfVmFsdWVFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICJfX25vbnplcm9fXyBzaG91bGQgcmV0dXJuID49IDAiKTsKKyAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKyAgICByZXR1cm4gb3V0Y29tZSA+IDA7Cit9CisKK3N0YXRpYyBQeU9iamVjdCAqCitpbnN0YW5jZV9pbmRleChQeUluc3RhbmNlT2JqZWN0ICpzZWxmKQoreworICAgIFB5T2JqZWN0ICpmdW5jLCAqcmVzOworICAgIHN0YXRpYyBQeU9iamVjdCAqaW5kZXhzdHIgPSBOVUxMOworCisgICAgaWYgKGluZGV4c3RyID09IE5VTEwpIHsKKyAgICAgICAgaW5kZXhzdHIgPSBQeVN0cmluZ19JbnRlcm5Gcm9tU3RyaW5nKCJfX2luZGV4X18iKTsKKyAgICAgICAgaWYgKGluZGV4c3RyID09IE5VTEwpCisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgaWYgKChmdW5jID0gaW5zdGFuY2VfZ2V0YXR0cihzZWxmLCBpbmRleHN0cikpID09IE5VTEwpIHsKKyAgICAgICAgaWYgKCFQeUVycl9FeGNlcHRpb25NYXRjaGVzKFB5RXhjX0F0dHJpYnV0ZUVycm9yKSkKKyAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgICAgICBQeUVycl9DbGVhcigpOworICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfVHlwZUVycm9yLAorICAgICAgICAgICAgICAgICAgICAgICAgIm9iamVjdCBjYW5ub3QgYmUgaW50ZXJwcmV0ZWQgYXMgYW4gaW5kZXgiKTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIHJlcyA9IFB5RXZhbF9DYWxsT2JqZWN0KGZ1bmMsIChQeU9iamVjdCAqKU5VTEwpOworICAgIFB5X0RFQ1JFRihmdW5jKTsKKyAgICByZXR1cm4gcmVzOworfQorCisKK1VOQVJZKGluc3RhbmNlX2ludmVydCwgIl9faW52ZXJ0X18iKQorVU5BUlkoX2luc3RhbmNlX3RydW5jLCAiX190cnVuY19fIikKKworc3RhdGljIFB5T2JqZWN0ICoKK2luc3RhbmNlX2ludChQeUluc3RhbmNlT2JqZWN0ICpzZWxmKQoreworICAgIFB5T2JqZWN0ICp0cnVuY2F0ZWQ7CisgICAgc3RhdGljIFB5T2JqZWN0ICppbnRfbmFtZTsKKyAgICBpZiAoaW50X25hbWUgPT0gTlVMTCkgeworICAgICAgICBpbnRfbmFtZSA9IFB5U3RyaW5nX0ludGVybkZyb21TdHJpbmcoIl9faW50X18iKTsKKyAgICAgICAgaWYgKGludF9uYW1lID09IE5VTEwpCisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgaWYgKFB5T2JqZWN0X0hhc0F0dHIoKFB5T2JqZWN0KilzZWxmLCBpbnRfbmFtZSkpCisgICAgICAgIHJldHVybiBnZW5lcmljX3VuYXJ5X29wKHNlbGYsIGludF9uYW1lKTsKKworICAgIHRydW5jYXRlZCA9IF9pbnN0YW5jZV90cnVuYyhzZWxmKTsKKyAgICAvKiBfX3RydW5jX18gaXMgc3BlY2lmaWVkIHRvIHJldHVybiBhbiBJbnRlZ3JhbCB0eXBlLCBidXQKKyAgICAgICBpbnQoKSBuZWVkcyB0byByZXR1cm4gYW4gaW50LiAqLworICAgIHJldHVybiBfUHlOdW1iZXJfQ29udmVydEludGVncmFsVG9JbnQoCisgICAgICAgIHRydW5jYXRlZCwKKyAgICAgICAgIl9fdHJ1bmNfXyByZXR1cm5lZCBub24tSW50ZWdyYWwgKHR5cGUgJS4yMDBzKSIpOworfQorCitVTkFSWV9GQihpbnN0YW5jZV9sb25nLCAiX19sb25nX18iLCBpbnN0YW5jZV9pbnQpCitVTkFSWShpbnN0YW5jZV9mbG9hdCwgIl9fZmxvYXRfXyIpCitVTkFSWShpbnN0YW5jZV9vY3QsICJfX29jdF9fIikKK1VOQVJZKGluc3RhbmNlX2hleCwgIl9faGV4X18iKQorCitzdGF0aWMgUHlPYmplY3QgKgorYmluX3Bvd2VyKFB5T2JqZWN0ICp2LCBQeU9iamVjdCAqdykKK3sKKyAgICByZXR1cm4gUHlOdW1iZXJfUG93ZXIodiwgdywgUHlfTm9uZSk7Cit9CisKKy8qIFRoaXMgdmVyc2lvbiBpcyBmb3IgdGVybmFyeSBjYWxscyBvbmx5ICh6ICE9IE5vbmUpICovCitzdGF0aWMgUHlPYmplY3QgKgoraW5zdGFuY2VfcG93KFB5T2JqZWN0ICp2LCBQeU9iamVjdCAqdywgUHlPYmplY3QgKnopCit7CisgICAgaWYgKHogPT0gUHlfTm9uZSkgeworICAgICAgICByZXR1cm4gZG9fYmlub3AodiwgdywgIl9fcG93X18iLCAiX19ycG93X18iLCBiaW5fcG93ZXIpOworICAgIH0KKyAgICBlbHNlIHsKKyAgICAgICAgUHlPYmplY3QgKmZ1bmM7CisgICAgICAgIFB5T2JqZWN0ICphcmdzOworICAgICAgICBQeU9iamVjdCAqcmVzdWx0OworCisgICAgICAgIC8qIFhYWCBEb2Vzbid0IGRvIGNvZXJjaW9ucy4uLiAqLworICAgICAgICBmdW5jID0gUHlPYmplY3RfR2V0QXR0clN0cmluZyh2LCAiX19wb3dfXyIpOworICAgICAgICBpZiAoZnVuYyA9PSBOVUxMKQorICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgICAgIGFyZ3MgPSBQeVR1cGxlX1BhY2soMiwgdywgeik7CisgICAgICAgIGlmIChhcmdzID09IE5VTEwpIHsKKyAgICAgICAgICAgIFB5X0RFQ1JFRihmdW5jKTsKKyAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgICAgICB9CisgICAgICAgIHJlc3VsdCA9IFB5RXZhbF9DYWxsT2JqZWN0KGZ1bmMsIGFyZ3MpOworICAgICAgICBQeV9ERUNSRUYoZnVuYyk7CisgICAgICAgIFB5X0RFQ1JFRihhcmdzKTsKKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9Cit9CisKK3N0YXRpYyBQeU9iamVjdCAqCitiaW5faW5wbGFjZV9wb3dlcihQeU9iamVjdCAqdiwgUHlPYmplY3QgKncpCit7CisgICAgcmV0dXJuIFB5TnVtYmVyX0luUGxhY2VQb3dlcih2LCB3LCBQeV9Ob25lKTsKK30KKworCitzdGF0aWMgUHlPYmplY3QgKgoraW5zdGFuY2VfaXBvdyhQeU9iamVjdCAqdiwgUHlPYmplY3QgKncsIFB5T2JqZWN0ICp6KQoreworICAgIGlmICh6ID09IFB5X05vbmUpIHsKKyAgICAgICAgcmV0dXJuIGRvX2Jpbm9wX2lucGxhY2UodiwgdywgIl9faXBvd19fIiwgIl9fcG93X18iLAorICAgICAgICAgICAgIl9fcnBvd19fIiwgYmluX2lucGxhY2VfcG93ZXIpOworICAgIH0KKyAgICBlbHNlIHsKKyAgICAgICAgLyogWFhYIERvZXNuJ3QgZG8gY29lcmNpb25zLi4uICovCisgICAgICAgIFB5T2JqZWN0ICpmdW5jOworICAgICAgICBQeU9iamVjdCAqYXJnczsKKyAgICAgICAgUHlPYmplY3QgKnJlc3VsdDsKKworICAgICAgICBmdW5jID0gUHlPYmplY3RfR2V0QXR0clN0cmluZyh2LCAiX19pcG93X18iKTsKKyAgICAgICAgaWYgKGZ1bmMgPT0gTlVMTCkgeworICAgICAgICAgICAgaWYgKCFQeUVycl9FeGNlcHRpb25NYXRjaGVzKFB5RXhjX0F0dHJpYnV0ZUVycm9yKSkKKyAgICAgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgICAgIFB5RXJyX0NsZWFyKCk7CisgICAgICAgICAgICByZXR1cm4gaW5zdGFuY2VfcG93KHYsIHcsIHopOworICAgICAgICB9CisgICAgICAgIGFyZ3MgPSBQeVR1cGxlX1BhY2soMiwgdywgeik7CisgICAgICAgIGlmIChhcmdzID09IE5VTEwpIHsKKyAgICAgICAgICAgIFB5X0RFQ1JFRihmdW5jKTsKKyAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgICAgICB9CisgICAgICAgIHJlc3VsdCA9IFB5RXZhbF9DYWxsT2JqZWN0KGZ1bmMsIGFyZ3MpOworICAgICAgICBQeV9ERUNSRUYoZnVuYyk7CisgICAgICAgIFB5X0RFQ1JFRihhcmdzKTsKKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9Cit9CisKKworLyogTWFwIHJpY2ggY29tcGFyaXNvbiBvcGVyYXRvcnMgdG8gdGhlaXIgX194eF9fIG5hbWVzYWtlcyAqLworI2RlZmluZSBOQU1FX09QUyA2CitzdGF0aWMgUHlPYmplY3QgKipuYW1lX29wID0gTlVMTDsKKworc3RhdGljIGludAoraW5pdF9uYW1lX29wKHZvaWQpCit7CisgICAgaW50IGk7CisgICAgY2hhciAqX25hbWVfb3BbXSA9IHsKKyAgICAgICAgIl9fbHRfXyIsCisgICAgICAgICJfX2xlX18iLAorICAgICAgICAiX19lcV9fIiwKKyAgICAgICAgIl9fbmVfXyIsCisgICAgICAgICJfX2d0X18iLAorICAgICAgICAiX19nZV9fIiwKKyAgICB9OworCisgICAgbmFtZV9vcCA9IChQeU9iamVjdCAqKiltYWxsb2Moc2l6ZW9mKFB5T2JqZWN0ICopICogTkFNRV9PUFMpOworICAgIGlmIChuYW1lX29wID09IE5VTEwpCisgICAgICAgIHJldHVybiAtMTsKKyAgICBmb3IgKGkgPSAwOyBpIDwgTkFNRV9PUFM7ICsraSkgeworICAgICAgICBuYW1lX29wW2ldID0gUHlTdHJpbmdfSW50ZXJuRnJvbVN0cmluZyhfbmFtZV9vcFtpXSk7CisgICAgICAgIGlmIChuYW1lX29wW2ldID09IE5VTEwpCisgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgfQorICAgIHJldHVybiAwOworfQorCitzdGF0aWMgUHlPYmplY3QgKgoraGFsZl9yaWNoY29tcGFyZShQeU9iamVjdCAqdiwgUHlPYmplY3QgKncsIGludCBvcCkKK3sKKyAgICBQeU9iamVjdCAqbWV0aG9kOworICAgIFB5T2JqZWN0ICphcmdzOworICAgIFB5T2JqZWN0ICpyZXM7CisKKyAgICBhc3NlcnQoUHlJbnN0YW5jZV9DaGVjayh2KSk7CisKKyAgICBpZiAobmFtZV9vcCA9PSBOVUxMKSB7CisgICAgICAgIGlmIChpbml0X25hbWVfb3AoKSA8IDApCisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgLyogSWYgdGhlIGluc3RhbmNlIGRvZXNuJ3QgZGVmaW5lIGFuIF9fZ2V0YXR0cl9fIG1ldGhvZCwgdXNlCisgICAgICAgaW5zdGFuY2VfZ2V0YXR0cjIgZGlyZWN0bHkgYmVjYXVzZSBpdCB3aWxsIG5vdCBzZXQgYW4KKyAgICAgICBleGNlcHRpb24gb24gZmFpbHVyZS4gKi8KKyAgICBpZiAoKChQeUluc3RhbmNlT2JqZWN0ICopdiktPmluX2NsYXNzLT5jbF9nZXRhdHRyID09IE5VTEwpCisgICAgICAgIG1ldGhvZCA9IGluc3RhbmNlX2dldGF0dHIyKChQeUluc3RhbmNlT2JqZWN0ICopdiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZV9vcFtvcF0pOworICAgIGVsc2UKKyAgICAgICAgbWV0aG9kID0gUHlPYmplY3RfR2V0QXR0cih2LCBuYW1lX29wW29wXSk7CisgICAgaWYgKG1ldGhvZCA9PSBOVUxMKSB7CisgICAgICAgIGlmIChQeUVycl9PY2N1cnJlZCgpKSB7CisgICAgICAgICAgICBpZiAoIVB5RXJyX0V4Y2VwdGlvbk1hdGNoZXMoUHlFeGNfQXR0cmlidXRlRXJyb3IpKQorICAgICAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgICAgICAgICAgUHlFcnJfQ2xlYXIoKTsKKyAgICAgICAgfQorICAgICAgICByZXMgPSBQeV9Ob3RJbXBsZW1lbnRlZDsKKyAgICAgICAgUHlfSU5DUkVGKHJlcyk7CisgICAgICAgIHJldHVybiByZXM7CisgICAgfQorCisgICAgYXJncyA9IFB5VHVwbGVfUGFjaygxLCB3KTsKKyAgICBpZiAoYXJncyA9PSBOVUxMKSB7CisgICAgICAgIFB5X0RFQ1JFRihtZXRob2QpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisKKyAgICByZXMgPSBQeUV2YWxfQ2FsbE9iamVjdChtZXRob2QsIGFyZ3MpOworICAgIFB5X0RFQ1JFRihhcmdzKTsKKyAgICBQeV9ERUNSRUYobWV0aG9kKTsKKworICAgIHJldHVybiByZXM7Cit9CisKK3N0YXRpYyBQeU9iamVjdCAqCitpbnN0YW5jZV9yaWNoY29tcGFyZShQeU9iamVjdCAqdiwgUHlPYmplY3QgKncsIGludCBvcCkKK3sKKyAgICBQeU9iamVjdCAqcmVzOworCisgICAgaWYgKFB5SW5zdGFuY2VfQ2hlY2sodikpIHsKKyAgICAgICAgcmVzID0gaGFsZl9yaWNoY29tcGFyZSh2LCB3LCBvcCk7CisgICAgICAgIGlmIChyZXMgIT0gUHlfTm90SW1wbGVtZW50ZWQpCisgICAgICAgICAgICByZXR1cm4gcmVzOworICAgICAgICBQeV9ERUNSRUYocmVzKTsKKyAgICB9CisKKyAgICBpZiAoUHlJbnN0YW5jZV9DaGVjayh3KSkgeworICAgICAgICByZXMgPSBoYWxmX3JpY2hjb21wYXJlKHcsIHYsIF9QeV9Td2FwcGVkT3Bbb3BdKTsKKyAgICAgICAgaWYgKHJlcyAhPSBQeV9Ob3RJbXBsZW1lbnRlZCkKKyAgICAgICAgICAgIHJldHVybiByZXM7CisgICAgICAgIFB5X0RFQ1JFRihyZXMpOworICAgIH0KKworICAgIFB5X0lOQ1JFRihQeV9Ob3RJbXBsZW1lbnRlZCk7CisgICAgcmV0dXJuIFB5X05vdEltcGxlbWVudGVkOworfQorCisKKy8qIEdldCB0aGUgaXRlcmF0b3IgKi8KK3N0YXRpYyBQeU9iamVjdCAqCitpbnN0YW5jZV9nZXRpdGVyKFB5SW5zdGFuY2VPYmplY3QgKnNlbGYpCit7CisgICAgUHlPYmplY3QgKmZ1bmM7CisKKyAgICBpZiAoaXRlcnN0ciA9PSBOVUxMKSB7CisgICAgICAgIGl0ZXJzdHIgPSBQeVN0cmluZ19JbnRlcm5Gcm9tU3RyaW5nKCJfX2l0ZXJfXyIpOworICAgICAgICBpZiAoaXRlcnN0ciA9PSBOVUxMKQorICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIGlmIChnZXRpdGVtc3RyID09IE5VTEwpIHsKKyAgICAgICAgZ2V0aXRlbXN0ciA9IFB5U3RyaW5nX0ludGVybkZyb21TdHJpbmcoIl9fZ2V0aXRlbV9fIik7CisgICAgICAgIGlmIChnZXRpdGVtc3RyID09IE5VTEwpCisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisKKyAgICBpZiAoKGZ1bmMgPSBpbnN0YW5jZV9nZXRhdHRyKHNlbGYsIGl0ZXJzdHIpKSAhPSBOVUxMKSB7CisgICAgICAgIFB5T2JqZWN0ICpyZXMgPSBQeUV2YWxfQ2FsbE9iamVjdChmdW5jLCAoUHlPYmplY3QgKilOVUxMKTsKKyAgICAgICAgUHlfREVDUkVGKGZ1bmMpOworICAgICAgICBpZiAocmVzICE9IE5VTEwgJiYgIVB5SXRlcl9DaGVjayhyZXMpKSB7CisgICAgICAgICAgICBQeUVycl9Gb3JtYXQoUHlFeGNfVHlwZUVycm9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICJfX2l0ZXJfXyByZXR1cm5lZCBub24taXRlcmF0b3IgIgorICAgICAgICAgICAgICAgICAgICAgICAgICJvZiB0eXBlICclLjEwMHMnIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICByZXMtPm9iX3R5cGUtPnRwX25hbWUpOworICAgICAgICAgICAgUHlfREVDUkVGKHJlcyk7CisgICAgICAgICAgICByZXMgPSBOVUxMOworICAgICAgICB9CisgICAgICAgIHJldHVybiByZXM7CisgICAgfQorICAgIGlmICghUHlFcnJfRXhjZXB0aW9uTWF0Y2hlcyhQeUV4Y19BdHRyaWJ1dGVFcnJvcikpCisgICAgICAgIHJldHVybiBOVUxMOworICAgIFB5RXJyX0NsZWFyKCk7CisgICAgaWYgKChmdW5jID0gaW5zdGFuY2VfZ2V0YXR0cihzZWxmLCBnZXRpdGVtc3RyKSkgPT0gTlVMTCkgeworICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfVHlwZUVycm9yLAorICAgICAgICAgICAgICAgICAgICAgICAgIml0ZXJhdGlvbiBvdmVyIG5vbi1zZXF1ZW5jZSIpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgUHlfREVDUkVGKGZ1bmMpOworICAgIHJldHVybiBQeVNlcUl0ZXJfTmV3KChQeU9iamVjdCAqKXNlbGYpOworfQorCisKKy8qIENhbGwgdGhlIGl0ZXJhdG9yJ3MgbmV4dCAqLworc3RhdGljIFB5T2JqZWN0ICoKK2luc3RhbmNlX2l0ZXJuZXh0KFB5SW5zdGFuY2VPYmplY3QgKnNlbGYpCit7CisgICAgUHlPYmplY3QgKmZ1bmM7CisKKyAgICBpZiAobmV4dHN0ciA9PSBOVUxMKSB7CisgICAgICAgIG5leHRzdHIgPSBQeVN0cmluZ19JbnRlcm5Gcm9tU3RyaW5nKCJuZXh0Iik7CisgICAgICAgIGlmIChuZXh0c3RyID09IE5VTEwpCisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisKKyAgICBpZiAoKGZ1bmMgPSBpbnN0YW5jZV9nZXRhdHRyKHNlbGYsIG5leHRzdHIpKSAhPSBOVUxMKSB7CisgICAgICAgIFB5T2JqZWN0ICpyZXMgPSBQeUV2YWxfQ2FsbE9iamVjdChmdW5jLCAoUHlPYmplY3QgKilOVUxMKTsKKyAgICAgICAgUHlfREVDUkVGKGZ1bmMpOworICAgICAgICBpZiAocmVzICE9IE5VTEwpIHsKKyAgICAgICAgICAgIHJldHVybiByZXM7CisgICAgICAgIH0KKyAgICAgICAgaWYgKFB5RXJyX0V4Y2VwdGlvbk1hdGNoZXMoUHlFeGNfU3RvcEl0ZXJhdGlvbikpIHsKKyAgICAgICAgICAgIFB5RXJyX0NsZWFyKCk7CisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1R5cGVFcnJvciwgImluc3RhbmNlIGhhcyBubyBuZXh0KCkgbWV0aG9kIik7CisgICAgcmV0dXJuIE5VTEw7Cit9CisKK3N0YXRpYyBQeU9iamVjdCAqCitpbnN0YW5jZV9jYWxsKFB5T2JqZWN0ICpmdW5jLCBQeU9iamVjdCAqYXJnLCBQeU9iamVjdCAqa3cpCit7CisgICAgUHlPYmplY3QgKnJlcywgKmNhbGwgPSBQeU9iamVjdF9HZXRBdHRyU3RyaW5nKGZ1bmMsICJfX2NhbGxfXyIpOworICAgIGlmIChjYWxsID09IE5VTEwpIHsKKyAgICAgICAgUHlJbnN0YW5jZU9iamVjdCAqaW5zdCA9IChQeUluc3RhbmNlT2JqZWN0KikgZnVuYzsKKyAgICAgICAgaWYgKCFQeUVycl9FeGNlcHRpb25NYXRjaGVzKFB5RXhjX0F0dHJpYnV0ZUVycm9yKSkKKyAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgICAgICBQeUVycl9DbGVhcigpOworICAgICAgICBQeUVycl9Gb3JtYXQoUHlFeGNfQXR0cmlidXRlRXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAiJS4yMDBzIGluc3RhbmNlIGhhcyBubyBfX2NhbGxfXyBtZXRob2QiLAorICAgICAgICAgICAgICAgICAgICAgUHlTdHJpbmdfQXNTdHJpbmcoaW5zdC0+aW5fY2xhc3MtPmNsX25hbWUpKTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIC8qIFdlIG11c3QgY2hlY2sgYW5kIGluY3JlbWVudCB0aGUgcmVjdXJzaW9uIGRlcHRoIGhlcmUuIFNjZW5hcmlvOgorICAgICAgICAgICBjbGFzcyBBOgorICAgICAgICAgICBwYXNzCisgICAgICAgICAgIEEuX19jYWxsX18gPSBBKCkgIyB0aGF0J3MgcmlnaHQKKyAgICAgICAgICAgYSA9IEEoKSAjIG9rCisgICAgICAgICAgIGEoKSAjIGluZmluaXRlIHJlY3Vyc2lvbgorICAgICAgIFRoaXMgYm91bmNlcyBiZXR3ZWVuIGluc3RhbmNlX2NhbGwoKSBhbmQgUHlPYmplY3RfQ2FsbCgpIHdpdGhvdXQKKyAgICAgICBldmVyIGhpdHRpbmcgZXZhbF9mcmFtZSgpICh3aGljaCBoYXMgdGhlIG1haW4gcmVjdXJzaW9uIGNoZWNrKS4gKi8KKyAgICBpZiAoUHlfRW50ZXJSZWN1cnNpdmVDYWxsKCIgaW4gX19jYWxsX18iKSkgeworICAgICAgICByZXMgPSBOVUxMOworICAgIH0KKyAgICBlbHNlIHsKKyAgICAgICAgcmVzID0gUHlPYmplY3RfQ2FsbChjYWxsLCBhcmcsIGt3KTsKKyAgICAgICAgUHlfTGVhdmVSZWN1cnNpdmVDYWxsKCk7CisgICAgfQorICAgIFB5X0RFQ1JFRihjYWxsKTsKKyAgICByZXR1cm4gcmVzOworfQorCisKK3N0YXRpYyBQeU51bWJlck1ldGhvZHMgaW5zdGFuY2VfYXNfbnVtYmVyID0geworICAgIGluc3RhbmNlX2FkZCwgICAgICAgICAgICAgICAgICAgICAgIC8qIG5iX2FkZCAqLworICAgIGluc3RhbmNlX3N1YiwgICAgICAgICAgICAgICAgICAgICAgIC8qIG5iX3N1YnRyYWN0ICovCisgICAgaW5zdGFuY2VfbXVsLCAgICAgICAgICAgICAgICAgICAgICAgLyogbmJfbXVsdGlwbHkgKi8KKyAgICBpbnN0YW5jZV9kaXYsICAgICAgICAgICAgICAgICAgICAgICAvKiBuYl9kaXZpZGUgKi8KKyAgICBpbnN0YW5jZV9tb2QsICAgICAgICAgICAgICAgICAgICAgICAvKiBuYl9yZW1haW5kZXIgKi8KKyAgICBpbnN0YW5jZV9kaXZtb2QsICAgICAgICAgICAgICAgICAgICAvKiBuYl9kaXZtb2QgKi8KKyAgICBpbnN0YW5jZV9wb3csICAgICAgICAgICAgICAgICAgICAgICAvKiBuYl9wb3dlciAqLworICAgICh1bmFyeWZ1bmMpaW5zdGFuY2VfbmVnLCAgICAgICAgICAgIC8qIG5iX25lZ2F0aXZlICovCisgICAgKHVuYXJ5ZnVuYylpbnN0YW5jZV9wb3MsICAgICAgICAgICAgLyogbmJfcG9zaXRpdmUgKi8KKyAgICAodW5hcnlmdW5jKWluc3RhbmNlX2FicywgICAgICAgICAgICAvKiBuYl9hYnNvbHV0ZSAqLworICAgIChpbnF1aXJ5KWluc3RhbmNlX25vbnplcm8sICAgICAgICAgIC8qIG5iX25vbnplcm8gKi8KKyAgICAodW5hcnlmdW5jKWluc3RhbmNlX2ludmVydCwgICAgICAgICAvKiBuYl9pbnZlcnQgKi8KKyAgICBpbnN0YW5jZV9sc2hpZnQsICAgICAgICAgICAgICAgICAgICAvKiBuYl9sc2hpZnQgKi8KKyAgICBpbnN0YW5jZV9yc2hpZnQsICAgICAgICAgICAgICAgICAgICAvKiBuYl9yc2hpZnQgKi8KKyAgICBpbnN0YW5jZV9hbmQsICAgICAgICAgICAgICAgICAgICAgICAvKiBuYl9hbmQgKi8KKyAgICBpbnN0YW5jZV94b3IsICAgICAgICAgICAgICAgICAgICAgICAvKiBuYl94b3IgKi8KKyAgICBpbnN0YW5jZV9vciwgICAgICAgICAgICAgICAgICAgICAgICAvKiBuYl9vciAqLworICAgIGluc3RhbmNlX2NvZXJjZSwgICAgICAgICAgICAgICAgICAgIC8qIG5iX2NvZXJjZSAqLworICAgICh1bmFyeWZ1bmMpaW5zdGFuY2VfaW50LCAgICAgICAgICAgIC8qIG5iX2ludCAqLworICAgICh1bmFyeWZ1bmMpaW5zdGFuY2VfbG9uZywgICAgICAgICAgIC8qIG5iX2xvbmcgKi8KKyAgICAodW5hcnlmdW5jKWluc3RhbmNlX2Zsb2F0LCAgICAgICAgICAvKiBuYl9mbG9hdCAqLworICAgICh1bmFyeWZ1bmMpaW5zdGFuY2Vfb2N0LCAgICAgICAgICAgIC8qIG5iX29jdCAqLworICAgICh1bmFyeWZ1bmMpaW5zdGFuY2VfaGV4LCAgICAgICAgICAgIC8qIG5iX2hleCAqLworICAgIGluc3RhbmNlX2lhZGQsICAgICAgICAgICAgICAgICAgICAgIC8qIG5iX2lucGxhY2VfYWRkICovCisgICAgaW5zdGFuY2VfaXN1YiwgICAgICAgICAgICAgICAgICAgICAgLyogbmJfaW5wbGFjZV9zdWJ0cmFjdCAqLworICAgIGluc3RhbmNlX2ltdWwsICAgICAgICAgICAgICAgICAgICAgIC8qIG5iX2lucGxhY2VfbXVsdGlwbHkgKi8KKyAgICBpbnN0YW5jZV9pZGl2LCAgICAgICAgICAgICAgICAgICAgICAvKiBuYl9pbnBsYWNlX2RpdmlkZSAqLworICAgIGluc3RhbmNlX2ltb2QsICAgICAgICAgICAgICAgICAgICAgIC8qIG5iX2lucGxhY2VfcmVtYWluZGVyICovCisgICAgaW5zdGFuY2VfaXBvdywgICAgICAgICAgICAgICAgICAgICAgLyogbmJfaW5wbGFjZV9wb3dlciAqLworICAgIGluc3RhbmNlX2lsc2hpZnQsICAgICAgICAgICAgICAgICAgIC8qIG5iX2lucGxhY2VfbHNoaWZ0ICovCisgICAgaW5zdGFuY2VfaXJzaGlmdCwgICAgICAgICAgICAgICAgICAgLyogbmJfaW5wbGFjZV9yc2hpZnQgKi8KKyAgICBpbnN0YW5jZV9pYW5kLCAgICAgICAgICAgICAgICAgICAgICAvKiBuYl9pbnBsYWNlX2FuZCAqLworICAgIGluc3RhbmNlX2l4b3IsICAgICAgICAgICAgICAgICAgICAgIC8qIG5iX2lucGxhY2VfeG9yICovCisgICAgaW5zdGFuY2VfaW9yLCAgICAgICAgICAgICAgICAgICAgICAgLyogbmJfaW5wbGFjZV9vciAqLworICAgIGluc3RhbmNlX2Zsb29yZGl2LCAgICAgICAgICAgICAgICAgIC8qIG5iX2Zsb29yX2RpdmlkZSAqLworICAgIGluc3RhbmNlX3RydWVkaXYsICAgICAgICAgICAgICAgICAgIC8qIG5iX3RydWVfZGl2aWRlICovCisgICAgaW5zdGFuY2VfaWZsb29yZGl2LCAgICAgICAgICAgICAgICAgLyogbmJfaW5wbGFjZV9mbG9vcl9kaXZpZGUgKi8KKyAgICBpbnN0YW5jZV9pdHJ1ZWRpdiwgICAgICAgICAgICAgICAgICAvKiBuYl9pbnBsYWNlX3RydWVfZGl2aWRlICovCisgICAgKHVuYXJ5ZnVuYylpbnN0YW5jZV9pbmRleCwgICAgICAgICAgLyogbmJfaW5kZXggKi8KK307CisKK1B5VHlwZU9iamVjdCBQeUluc3RhbmNlX1R5cGUgPSB7CisgICAgUHlPYmplY3RfSEVBRF9JTklUKCZQeVR5cGVfVHlwZSkKKyAgICAwLAorICAgICJpbnN0YW5jZSIsCisgICAgc2l6ZW9mKFB5SW5zdGFuY2VPYmplY3QpLAorICAgIDAsCisgICAgKGRlc3RydWN0b3IpaW5zdGFuY2VfZGVhbGxvYywgICAgICAgICAgICAgICAvKiB0cF9kZWFsbG9jICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9wcmludCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZ2V0YXR0ciAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfc2V0YXR0ciAqLworICAgIGluc3RhbmNlX2NvbXBhcmUsICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfY29tcGFyZSAqLworICAgIChyZXByZnVuYylpbnN0YW5jZV9yZXByLCAgICAgICAgICAgICAgICAgICAgLyogdHBfcmVwciAqLworICAgICZpbnN0YW5jZV9hc19udW1iZXIsICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfYXNfbnVtYmVyICovCisgICAgJmluc3RhbmNlX2FzX3NlcXVlbmNlLCAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9hc19zZXF1ZW5jZSAqLworICAgICZpbnN0YW5jZV9hc19tYXBwaW5nLCAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfYXNfbWFwcGluZyAqLworICAgIChoYXNoZnVuYylpbnN0YW5jZV9oYXNoLCAgICAgICAgICAgICAgICAgICAgLyogdHBfaGFzaCAqLworICAgIGluc3RhbmNlX2NhbGwsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfY2FsbCAqLworICAgIChyZXByZnVuYylpbnN0YW5jZV9zdHIsICAgICAgICAgICAgICAgICAgICAgLyogdHBfc3RyICovCisgICAgKGdldGF0dHJvZnVuYylpbnN0YW5jZV9nZXRhdHRyLCAgICAgICAgICAgICAvKiB0cF9nZXRhdHRybyAqLworICAgIChzZXRhdHRyb2Z1bmMpaW5zdGFuY2Vfc2V0YXR0ciwgICAgICAgICAgICAgLyogdHBfc2V0YXR0cm8gKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2FzX2J1ZmZlciAqLworICAgIFB5X1RQRkxBR1NfREVGQVVMVCB8IFB5X1RQRkxBR1NfSEFWRV9HQyB8IFB5X1RQRkxBR1NfQ0hFQ0tUWVBFUywvKnRwX2ZsYWdzKi8KKyAgICBpbnN0YW5jZV9kb2MsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2RvYyAqLworICAgICh0cmF2ZXJzZXByb2MpaW5zdGFuY2VfdHJhdmVyc2UsICAgICAgICAgICAgLyogdHBfdHJhdmVyc2UgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2NsZWFyICovCisgICAgaW5zdGFuY2VfcmljaGNvbXBhcmUsICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9yaWNoY29tcGFyZSAqLworICAgIG9mZnNldG9mKFB5SW5zdGFuY2VPYmplY3QsIGluX3dlYWtyZWZsaXN0KSwgLyogdHBfd2Vha2xpc3RvZmZzZXQgKi8KKyAgICAoZ2V0aXRlcmZ1bmMpaW5zdGFuY2VfZ2V0aXRlciwgICAgICAgICAgICAgIC8qIHRwX2l0ZXIgKi8KKyAgICAoaXRlcm5leHRmdW5jKWluc3RhbmNlX2l0ZXJuZXh0LCAgICAgICAgICAgIC8qIHRwX2l0ZXJuZXh0ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9tZXRob2RzICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9tZW1iZXJzICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9nZXRzZXQgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2Jhc2UgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2RpY3QgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2Rlc2NyX2dldCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZGVzY3Jfc2V0ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9kaWN0b2Zmc2V0ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9pbml0ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9hbGxvYyAqLworICAgIGluc3RhbmNlX25ldywgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfbmV3ICovCit9OworCisKKy8qIEluc3RhbmNlIG1ldGhvZCBvYmplY3RzIGFyZSB1c2VkIGZvciB0d28gcHVycG9zZXM6CisgICAoYSkgYXMgYm91bmQgaW5zdGFuY2UgbWV0aG9kcyAocmV0dXJuZWQgYnkgaW5zdGFuY2VuYW1lLm1ldGhvZG5hbWUpCisgICAoYikgYXMgdW5ib3VuZCBtZXRob2RzIChyZXR1cm5lZCBieSBDbGFzc05hbWUubWV0aG9kbmFtZSkKKyAgIEluIGNhc2UgKGIpLCBpbV9zZWxmIGlzIE5VTEwKKyovCisKK1B5T2JqZWN0ICoKK1B5TWV0aG9kX05ldyhQeU9iamVjdCAqZnVuYywgUHlPYmplY3QgKnNlbGYsIFB5T2JqZWN0ICprbGFzcykKK3sKKyAgICByZWdpc3RlciBQeU1ldGhvZE9iamVjdCAqaW07CisgICAgaW0gPSBmcmVlX2xpc3Q7CisgICAgaWYgKGltICE9IE5VTEwpIHsKKyAgICAgICAgZnJlZV9saXN0ID0gKFB5TWV0aG9kT2JqZWN0ICopKGltLT5pbV9zZWxmKTsKKyAgICAgICAgUHlPYmplY3RfSU5JVChpbSwgJlB5TWV0aG9kX1R5cGUpOworICAgICAgICBudW1mcmVlLS07CisgICAgfQorICAgIGVsc2UgeworICAgICAgICBpbSA9IFB5T2JqZWN0X0dDX05ldyhQeU1ldGhvZE9iamVjdCwgJlB5TWV0aG9kX1R5cGUpOworICAgICAgICBpZiAoaW0gPT0gTlVMTCkKKyAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICBpbS0+aW1fd2Vha3JlZmxpc3QgPSBOVUxMOworICAgIFB5X0lOQ1JFRihmdW5jKTsKKyAgICBpbS0+aW1fZnVuYyA9IGZ1bmM7CisgICAgUHlfWElOQ1JFRihzZWxmKTsKKyAgICBpbS0+aW1fc2VsZiA9IHNlbGY7CisgICAgUHlfWElOQ1JFRihrbGFzcyk7CisgICAgaW0tPmltX2NsYXNzID0ga2xhc3M7CisgICAgX1B5T2JqZWN0X0dDX1RSQUNLKGltKTsKKyAgICByZXR1cm4gKFB5T2JqZWN0ICopaW07Cit9CisKKy8qIERlc2NyaXB0b3JzIGZvciBQeU1ldGhvZCBhdHRyaWJ1dGVzICovCisKKy8qIGltX2NsYXNzLCBpbV9mdW5jIGFuZCBpbV9zZWxmIGFyZSBzdG9yZWQgaW4gdGhlIFB5TWV0aG9kIG9iamVjdCAqLworCisjZGVmaW5lIE9GRih4KSBvZmZzZXRvZihQeU1ldGhvZE9iamVjdCwgeCkKKworc3RhdGljIFB5TWVtYmVyRGVmIGluc3RhbmNlbWV0aG9kX21lbWJlcmxpc3RbXSA9IHsKKyAgICB7ImltX2NsYXNzIiwgICAgICAgIFRfT0JKRUNULCAgICAgICBPRkYoaW1fY2xhc3MpLCAgUkVBRE9OTFl8UkVTVFJJQ1RFRCwKKyAgICAgInRoZSBjbGFzcyBhc3NvY2lhdGVkIHdpdGggYSBtZXRob2QifSwKKyAgICB7ImltX2Z1bmMiLCAgICAgICAgIFRfT0JKRUNULCAgICAgICBPRkYoaW1fZnVuYyksICAgUkVBRE9OTFl8UkVTVFJJQ1RFRCwKKyAgICAgInRoZSBmdW5jdGlvbiAob3Igb3RoZXIgY2FsbGFibGUpIGltcGxlbWVudGluZyBhIG1ldGhvZCJ9LAorICAgIHsiX19mdW5jX18iLCAgICAgICAgVF9PQkpFQ1QsICAgICAgIE9GRihpbV9mdW5jKSwgICBSRUFET05MWXxSRVNUUklDVEVELAorICAgICAidGhlIGZ1bmN0aW9uIChvciBvdGhlciBjYWxsYWJsZSkgaW1wbGVtZW50aW5nIGEgbWV0aG9kIn0sCisgICAgeyJpbV9zZWxmIiwgICAgICAgICBUX09CSkVDVCwgICAgICAgT0ZGKGltX3NlbGYpLCAgIFJFQURPTkxZfFJFU1RSSUNURUQsCisgICAgICJ0aGUgaW5zdGFuY2UgdG8gd2hpY2ggYSBtZXRob2QgaXMgYm91bmQ7IE5vbmUgZm9yIHVuYm91bmQgbWV0aG9kcyJ9LAorICAgIHsiX19zZWxmX18iLCAgICAgICAgVF9PQkpFQ1QsICAgICAgIE9GRihpbV9zZWxmKSwgICBSRUFET05MWXxSRVNUUklDVEVELAorICAgICAidGhlIGluc3RhbmNlIHRvIHdoaWNoIGEgbWV0aG9kIGlzIGJvdW5kOyBOb25lIGZvciB1bmJvdW5kIG1ldGhvZHMifSwKKyAgICB7TlVMTH0gICAgICAvKiBTZW50aW5lbCAqLworfTsKKworLyogQ2hyaXN0aWFuIFRpc21lciBhcmd1ZWQgY29udmluY2luZ2x5IHRoYXQgbWV0aG9kIGF0dHJpYnV0ZXMgc2hvdWxkCisgICAobmVhcmx5KSBhbHdheXMgb3ZlcnJpZGUgZnVuY3Rpb24gYXR0cmlidXRlcy4KKyAgIFRoZSBvbmUgZXhjZXB0aW9uIGlzIF9fZG9jX187IHRoZXJlJ3MgYSBkZWZhdWx0IF9fZG9jX18gd2hpY2gKKyAgIHNob3VsZCBvbmx5IGJlIHVzZWQgZm9yIHRoZSBjbGFzcywgbm90IGZvciBpbnN0YW5jZXMgKi8KKworc3RhdGljIFB5T2JqZWN0ICoKK2luc3RhbmNlbWV0aG9kX2dldF9kb2MoUHlNZXRob2RPYmplY3QgKmltLCB2b2lkICpjb250ZXh0KQoreworICAgIHN0YXRpYyBQeU9iamVjdCAqZG9jc3RyOworICAgIGlmIChkb2NzdHIgPT0gTlVMTCkgeworICAgICAgICBkb2NzdHI9IFB5U3RyaW5nX0ludGVybkZyb21TdHJpbmcoIl9fZG9jX18iKTsKKyAgICAgICAgaWYgKGRvY3N0ciA9PSBOVUxMKQorICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIHJldHVybiBQeU9iamVjdF9HZXRBdHRyKGltLT5pbV9mdW5jLCBkb2NzdHIpOworfQorCitzdGF0aWMgUHlHZXRTZXREZWYgaW5zdGFuY2VtZXRob2RfZ2V0c2V0W10gPSB7CisgICAgeyJfX2RvY19fIiwgKGdldHRlcilpbnN0YW5jZW1ldGhvZF9nZXRfZG9jLCBOVUxMLCBOVUxMfSwKKyAgICB7MH0KK307CisKK3N0YXRpYyBQeU9iamVjdCAqCitpbnN0YW5jZW1ldGhvZF9nZXRhdHRybyhQeU9iamVjdCAqb2JqLCBQeU9iamVjdCAqbmFtZSkKK3sKKyAgICBQeU1ldGhvZE9iamVjdCAqaW0gPSAoUHlNZXRob2RPYmplY3QgKilvYmo7CisgICAgUHlUeXBlT2JqZWN0ICp0cCA9IG9iai0+b2JfdHlwZTsKKyAgICBQeU9iamVjdCAqZGVzY3IgPSBOVUxMOworCisgICAgaWYgKFB5VHlwZV9IYXNGZWF0dXJlKHRwLCBQeV9UUEZMQUdTX0hBVkVfQ0xBU1MpKSB7CisgICAgICAgIGlmICh0cC0+dHBfZGljdCA9PSBOVUxMKSB7CisgICAgICAgICAgICBpZiAoUHlUeXBlX1JlYWR5KHRwKSA8IDApCisgICAgICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgICAgIH0KKyAgICAgICAgZGVzY3IgPSBfUHlUeXBlX0xvb2t1cCh0cCwgbmFtZSk7CisgICAgfQorCisgICAgaWYgKGRlc2NyICE9IE5VTEwpIHsKKyAgICAgICAgZGVzY3JnZXRmdW5jIGYgPSBUUF9ERVNDUl9HRVQoZGVzY3ItPm9iX3R5cGUpOworICAgICAgICBpZiAoZiAhPSBOVUxMKQorICAgICAgICAgICAgcmV0dXJuIGYoZGVzY3IsIG9iaiwgKFB5T2JqZWN0ICopb2JqLT5vYl90eXBlKTsKKyAgICAgICAgZWxzZSB7CisgICAgICAgICAgICBQeV9JTkNSRUYoZGVzY3IpOworICAgICAgICAgICAgcmV0dXJuIGRlc2NyOworICAgICAgICB9CisgICAgfQorCisgICAgcmV0dXJuIFB5T2JqZWN0X0dldEF0dHIoaW0tPmltX2Z1bmMsIG5hbWUpOworfQorCitQeURvY19TVFJWQVIoaW5zdGFuY2VtZXRob2RfZG9jLAorImluc3RhbmNlbWV0aG9kKGZ1bmN0aW9uLCBpbnN0YW5jZSwgY2xhc3MpXG5cCitcblwKK0NyZWF0ZSBhbiBpbnN0YW5jZSBtZXRob2Qgb2JqZWN0LiIpOworCitzdGF0aWMgUHlPYmplY3QgKgoraW5zdGFuY2VtZXRob2RfbmV3KFB5VHlwZU9iamVjdCogdHlwZSwgUHlPYmplY3QqIGFyZ3MsIFB5T2JqZWN0ICprdykKK3sKKyAgICBQeU9iamVjdCAqZnVuYzsKKyAgICBQeU9iamVjdCAqc2VsZjsKKyAgICBQeU9iamVjdCAqY2xhc3NPYmogPSBOVUxMOworCisgICAgaWYgKCFfUHlBcmdfTm9LZXl3b3JkcygiaW5zdGFuY2VtZXRob2QiLCBrdykpCisgICAgICAgIHJldHVybiBOVUxMOworICAgIGlmICghUHlBcmdfVW5wYWNrVHVwbGUoYXJncywgImluc3RhbmNlbWV0aG9kIiwgMiwgMywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgJmZ1bmMsICZzZWxmLCAmY2xhc3NPYmopKQorICAgICAgICByZXR1cm4gTlVMTDsKKyAgICBpZiAoIVB5Q2FsbGFibGVfQ2hlY2soZnVuYykpIHsKKyAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1R5cGVFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICJmaXJzdCBhcmd1bWVudCBtdXN0IGJlIGNhbGxhYmxlIik7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICBpZiAoc2VsZiA9PSBQeV9Ob25lKQorICAgICAgICBzZWxmID0gTlVMTDsKKyAgICBpZiAoc2VsZiA9PSBOVUxMICYmIGNsYXNzT2JqID09IE5VTEwpIHsKKyAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1R5cGVFcnJvciwKKyAgICAgICAgICAgICJ1bmJvdW5kIG1ldGhvZHMgbXVzdCBoYXZlIG5vbi1OVUxMIGltX2NsYXNzIik7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKworICAgIHJldHVybiBQeU1ldGhvZF9OZXcoZnVuYywgc2VsZiwgY2xhc3NPYmopOworfQorCitzdGF0aWMgdm9pZAoraW5zdGFuY2VtZXRob2RfZGVhbGxvYyhyZWdpc3RlciBQeU1ldGhvZE9iamVjdCAqaW0pCit7CisgICAgX1B5T2JqZWN0X0dDX1VOVFJBQ0soaW0pOworICAgIGlmIChpbS0+aW1fd2Vha3JlZmxpc3QgIT0gTlVMTCkKKyAgICAgICAgUHlPYmplY3RfQ2xlYXJXZWFrUmVmcygoUHlPYmplY3QgKilpbSk7CisgICAgUHlfREVDUkVGKGltLT5pbV9mdW5jKTsKKyAgICBQeV9YREVDUkVGKGltLT5pbV9zZWxmKTsKKyAgICBQeV9YREVDUkVGKGltLT5pbV9jbGFzcyk7CisgICAgaWYgKG51bWZyZWUgPCBQeU1ldGhvZF9NQVhGUkVFTElTVCkgeworICAgICAgICBpbS0+aW1fc2VsZiA9IChQeU9iamVjdCAqKWZyZWVfbGlzdDsKKyAgICAgICAgZnJlZV9saXN0ID0gaW07CisgICAgICAgIG51bWZyZWUrKzsKKyAgICB9CisgICAgZWxzZSB7CisgICAgICAgIFB5T2JqZWN0X0dDX0RlbChpbSk7CisgICAgfQorfQorCitzdGF0aWMgaW50CitpbnN0YW5jZW1ldGhvZF9jb21wYXJlKFB5TWV0aG9kT2JqZWN0ICphLCBQeU1ldGhvZE9iamVjdCAqYikKK3sKKyAgICBpbnQgY21wOworICAgIGNtcCA9IFB5T2JqZWN0X0NvbXBhcmUoYS0+aW1fZnVuYywgYi0+aW1fZnVuYyk7CisgICAgaWYgKGNtcCkKKyAgICAgICAgcmV0dXJuIGNtcDsKKworICAgIGlmIChhLT5pbV9zZWxmID09IGItPmltX3NlbGYpCisgICAgICAgIHJldHVybiAwOworICAgIGlmIChhLT5pbV9zZWxmID09IE5VTEwgfHwgYi0+aW1fc2VsZiA9PSBOVUxMKQorICAgICAgICByZXR1cm4gKGEtPmltX3NlbGYgPCBiLT5pbV9zZWxmKSA/IC0xIDogMTsKKyAgICBlbHNlCisgICAgICAgIHJldHVybiBQeU9iamVjdF9Db21wYXJlKGEtPmltX3NlbGYsIGItPmltX3NlbGYpOworfQorCitzdGF0aWMgUHlPYmplY3QgKgoraW5zdGFuY2VtZXRob2RfcmVwcihQeU1ldGhvZE9iamVjdCAqYSkKK3sKKyAgICBQeU9iamVjdCAqc2VsZiA9IGEtPmltX3NlbGY7CisgICAgUHlPYmplY3QgKmZ1bmMgPSBhLT5pbV9mdW5jOworICAgIFB5T2JqZWN0ICprbGFzcyA9IGEtPmltX2NsYXNzOworICAgIFB5T2JqZWN0ICpmdW5jbmFtZSA9IE5VTEwsICprbGFzc25hbWUgPSBOVUxMLCAqcmVzdWx0ID0gTlVMTDsKKyAgICBjaGFyICpzZnVuY25hbWUgPSAiPyIsICpza2xhc3NuYW1lID0gIj8iOworCisgICAgZnVuY25hbWUgPSBQeU9iamVjdF9HZXRBdHRyU3RyaW5nKGZ1bmMsICJfX25hbWVfXyIpOworICAgIGlmIChmdW5jbmFtZSA9PSBOVUxMKSB7CisgICAgICAgIGlmICghUHlFcnJfRXhjZXB0aW9uTWF0Y2hlcyhQeUV4Y19BdHRyaWJ1dGVFcnJvcikpCisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgUHlFcnJfQ2xlYXIoKTsKKyAgICB9CisgICAgZWxzZSBpZiAoIVB5U3RyaW5nX0NoZWNrKGZ1bmNuYW1lKSkgeworICAgICAgICBQeV9ERUNSRUYoZnVuY25hbWUpOworICAgICAgICBmdW5jbmFtZSA9IE5VTEw7CisgICAgfQorICAgIGVsc2UKKyAgICAgICAgc2Z1bmNuYW1lID0gUHlTdHJpbmdfQVNfU1RSSU5HKGZ1bmNuYW1lKTsKKyAgICBpZiAoa2xhc3MgPT0gTlVMTCkKKyAgICAgICAga2xhc3NuYW1lID0gTlVMTDsKKyAgICBlbHNlIHsKKyAgICAgICAga2xhc3NuYW1lID0gUHlPYmplY3RfR2V0QXR0clN0cmluZyhrbGFzcywgIl9fbmFtZV9fIik7CisgICAgICAgIGlmIChrbGFzc25hbWUgPT0gTlVMTCkgeworICAgICAgICAgICAgaWYgKCFQeUVycl9FeGNlcHRpb25NYXRjaGVzKFB5RXhjX0F0dHJpYnV0ZUVycm9yKSkKKyAgICAgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgICAgIFB5RXJyX0NsZWFyKCk7CisgICAgICAgIH0KKyAgICAgICAgZWxzZSBpZiAoIVB5U3RyaW5nX0NoZWNrKGtsYXNzbmFtZSkpIHsKKyAgICAgICAgICAgIFB5X0RFQ1JFRihrbGFzc25hbWUpOworICAgICAgICAgICAga2xhc3NuYW1lID0gTlVMTDsKKyAgICAgICAgfQorICAgICAgICBlbHNlCisgICAgICAgICAgICBza2xhc3NuYW1lID0gUHlTdHJpbmdfQVNfU1RSSU5HKGtsYXNzbmFtZSk7CisgICAgfQorICAgIGlmIChzZWxmID09IE5VTEwpCisgICAgICAgIHJlc3VsdCA9IFB5U3RyaW5nX0Zyb21Gb3JtYXQoIjx1bmJvdW5kIG1ldGhvZCAlcy4lcz4iLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNrbGFzc25hbWUsIHNmdW5jbmFtZSk7CisgICAgZWxzZSB7CisgICAgICAgIC8qIFhYWCBTaG91bGRuJ3QgdXNlIHJlcHIoKSBoZXJlISAqLworICAgICAgICBQeU9iamVjdCAqc2VsZnJlcHIgPSBQeU9iamVjdF9SZXByKHNlbGYpOworICAgICAgICBpZiAoc2VsZnJlcHIgPT0gTlVMTCkKKyAgICAgICAgICAgIGdvdG8gZmFpbDsKKyAgICAgICAgaWYgKCFQeVN0cmluZ19DaGVjayhzZWxmcmVwcikpIHsKKyAgICAgICAgICAgIFB5X0RFQ1JFRihzZWxmcmVwcik7CisgICAgICAgICAgICBnb3RvIGZhaWw7CisgICAgICAgIH0KKyAgICAgICAgcmVzdWx0ID0gUHlTdHJpbmdfRnJvbUZvcm1hdCgiPGJvdW5kIG1ldGhvZCAlcy4lcyBvZiAlcz4iLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNrbGFzc25hbWUsIHNmdW5jbmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQeVN0cmluZ19BU19TVFJJTkcoc2VsZnJlcHIpKTsKKyAgICAgICAgUHlfREVDUkVGKHNlbGZyZXByKTsKKyAgICB9CisgIGZhaWw6CisgICAgUHlfWERFQ1JFRihmdW5jbmFtZSk7CisgICAgUHlfWERFQ1JFRihrbGFzc25hbWUpOworICAgIHJldHVybiByZXN1bHQ7Cit9CisKK3N0YXRpYyBsb25nCitpbnN0YW5jZW1ldGhvZF9oYXNoKFB5TWV0aG9kT2JqZWN0ICphKQoreworICAgIGxvbmcgeCwgeTsKKyAgICBpZiAoYS0+aW1fc2VsZiA9PSBOVUxMKQorICAgICAgICB4ID0gUHlPYmplY3RfSGFzaChQeV9Ob25lKTsKKyAgICBlbHNlCisgICAgICAgIHggPSBQeU9iamVjdF9IYXNoKGEtPmltX3NlbGYpOworICAgIGlmICh4ID09IC0xKQorICAgICAgICByZXR1cm4gLTE7CisgICAgeSA9IFB5T2JqZWN0X0hhc2goYS0+aW1fZnVuYyk7CisgICAgaWYgKHkgPT0gLTEpCisgICAgICAgIHJldHVybiAtMTsKKyAgICB4ID0geCBeIHk7CisgICAgaWYgKHggPT0gLTEpCisgICAgICAgIHggPSAtMjsKKyAgICByZXR1cm4geDsKK30KKworc3RhdGljIGludAoraW5zdGFuY2VtZXRob2RfdHJhdmVyc2UoUHlNZXRob2RPYmplY3QgKmltLCB2aXNpdHByb2MgdmlzaXQsIHZvaWQgKmFyZykKK3sKKyAgICBQeV9WSVNJVChpbS0+aW1fZnVuYyk7CisgICAgUHlfVklTSVQoaW0tPmltX3NlbGYpOworICAgIFB5X1ZJU0lUKGltLT5pbV9jbGFzcyk7CisgICAgcmV0dXJuIDA7Cit9CisKK3N0YXRpYyB2b2lkCitnZXRjbGFzc25hbWUoUHlPYmplY3QgKmtsYXNzLCBjaGFyICpidWYsIGludCBidWZzaXplKQoreworICAgIFB5T2JqZWN0ICpuYW1lOworCisgICAgYXNzZXJ0KGJ1ZnNpemUgPiAxKTsKKyAgICBzdHJjcHkoYnVmLCAiPyIpOyAvKiBEZWZhdWx0IG91dGNvbWUgKi8KKyAgICBpZiAoa2xhc3MgPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuOworICAgIG5hbWUgPSBQeU9iamVjdF9HZXRBdHRyU3RyaW5nKGtsYXNzLCAiX19uYW1lX18iKTsKKyAgICBpZiAobmFtZSA9PSBOVUxMKSB7CisgICAgICAgIC8qIFRoaXMgZnVuY3Rpb24gY2Fubm90IHJldHVybiBhbiBleGNlcHRpb24gKi8KKyAgICAgICAgUHlFcnJfQ2xlYXIoKTsKKyAgICAgICAgcmV0dXJuOworICAgIH0KKyAgICBpZiAoUHlTdHJpbmdfQ2hlY2sobmFtZSkpIHsKKyAgICAgICAgc3RybmNweShidWYsIFB5U3RyaW5nX0FTX1NUUklORyhuYW1lKSwgYnVmc2l6ZSk7CisgICAgICAgIGJ1ZltidWZzaXplLTFdID0gJ1wwJzsKKyAgICB9CisgICAgUHlfREVDUkVGKG5hbWUpOworfQorCitzdGF0aWMgdm9pZAorZ2V0aW5zdGNsYXNzbmFtZShQeU9iamVjdCAqaW5zdCwgY2hhciAqYnVmLCBpbnQgYnVmc2l6ZSkKK3sKKyAgICBQeU9iamVjdCAqa2xhc3M7CisKKyAgICBpZiAoaW5zdCA9PSBOVUxMKSB7CisgICAgICAgIGFzc2VydChidWZzaXplID4gMCAmJiAoc2l6ZV90KWJ1ZnNpemUgPiBzdHJsZW4oIm5vdGhpbmciKSk7CisgICAgICAgIHN0cmNweShidWYsICJub3RoaW5nIik7CisgICAgICAgIHJldHVybjsKKyAgICB9CisKKyAgICBrbGFzcyA9IFB5T2JqZWN0X0dldEF0dHJTdHJpbmcoaW5zdCwgIl9fY2xhc3NfXyIpOworICAgIGlmIChrbGFzcyA9PSBOVUxMKSB7CisgICAgICAgIC8qIFRoaXMgZnVuY3Rpb24gY2Fubm90IHJldHVybiBhbiBleGNlcHRpb24gKi8KKyAgICAgICAgUHlFcnJfQ2xlYXIoKTsKKyAgICAgICAga2xhc3MgPSAoUHlPYmplY3QgKikoaW5zdC0+b2JfdHlwZSk7CisgICAgICAgIFB5X0lOQ1JFRihrbGFzcyk7CisgICAgfQorICAgIGdldGNsYXNzbmFtZShrbGFzcywgYnVmLCBidWZzaXplKTsKKyAgICBQeV9YREVDUkVGKGtsYXNzKTsKK30KKworc3RhdGljIFB5T2JqZWN0ICoKK2luc3RhbmNlbWV0aG9kX2NhbGwoUHlPYmplY3QgKmZ1bmMsIFB5T2JqZWN0ICphcmcsIFB5T2JqZWN0ICprdykKK3sKKyAgICBQeU9iamVjdCAqc2VsZiA9IFB5TWV0aG9kX0dFVF9TRUxGKGZ1bmMpOworICAgIFB5T2JqZWN0ICprbGFzcyA9IFB5TWV0aG9kX0dFVF9DTEFTUyhmdW5jKTsKKyAgICBQeU9iamVjdCAqcmVzdWx0OworCisgICAgZnVuYyA9IFB5TWV0aG9kX0dFVF9GVU5DVElPTihmdW5jKTsKKyAgICBpZiAoc2VsZiA9PSBOVUxMKSB7CisgICAgICAgIC8qIFVuYm91bmQgbWV0aG9kcyBtdXN0IGJlIGNhbGxlZCB3aXRoIGFuIGluc3RhbmNlIG9mCisgICAgICAgICAgIHRoZSBjbGFzcyAob3IgYSBkZXJpdmVkIGNsYXNzKSBhcyBmaXJzdCBhcmd1bWVudCAqLworICAgICAgICBpbnQgb2s7CisgICAgICAgIGlmIChQeVR1cGxlX1NpemUoYXJnKSA+PSAxKQorICAgICAgICAgICAgc2VsZiA9IFB5VHVwbGVfR0VUX0lURU0oYXJnLCAwKTsKKyAgICAgICAgaWYgKHNlbGYgPT0gTlVMTCkKKyAgICAgICAgICAgIG9rID0gMDsKKyAgICAgICAgZWxzZSB7CisgICAgICAgICAgICBvayA9IFB5T2JqZWN0X0lzSW5zdGFuY2Uoc2VsZiwga2xhc3MpOworICAgICAgICAgICAgaWYgKG9rIDwgMCkKKyAgICAgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgfQorICAgICAgICBpZiAoIW9rKSB7CisgICAgICAgICAgICBjaGFyIGNsc2J1ZlsyNTZdOworICAgICAgICAgICAgY2hhciBpbnN0YnVmWzI1Nl07CisgICAgICAgICAgICBnZXRjbGFzc25hbWUoa2xhc3MsIGNsc2J1Ziwgc2l6ZW9mKGNsc2J1ZikpOworICAgICAgICAgICAgZ2V0aW5zdGNsYXNzbmFtZShzZWxmLCBpbnN0YnVmLCBzaXplb2YoaW5zdGJ1ZikpOworICAgICAgICAgICAgUHlFcnJfRm9ybWF0KFB5RXhjX1R5cGVFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAidW5ib3VuZCBtZXRob2QgJXMlcyBtdXN0IGJlIGNhbGxlZCB3aXRoICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAiJXMgaW5zdGFuY2UgYXMgZmlyc3QgYXJndW1lbnQgIgorICAgICAgICAgICAgICAgICAgICAgICAgICIoZ290ICVzJXMgaW5zdGVhZCkiLAorICAgICAgICAgICAgICAgICAgICAgICAgIFB5RXZhbF9HZXRGdW5jTmFtZShmdW5jKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICBQeUV2YWxfR2V0RnVuY0Rlc2MoZnVuYyksCisgICAgICAgICAgICAgICAgICAgICAgICAgY2xzYnVmLAorICAgICAgICAgICAgICAgICAgICAgICAgIGluc3RidWYsCisgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZiA9PSBOVUxMID8gIiIgOiAiIGluc3RhbmNlIik7CisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgfQorICAgICAgICBQeV9JTkNSRUYoYXJnKTsKKyAgICB9CisgICAgZWxzZSB7CisgICAgICAgIFB5X3NzaXplX3QgYXJnY291bnQgPSBQeVR1cGxlX1NpemUoYXJnKTsKKyAgICAgICAgUHlPYmplY3QgKm5ld2FyZyA9IFB5VHVwbGVfTmV3KGFyZ2NvdW50ICsgMSk7CisgICAgICAgIGludCBpOworICAgICAgICBpZiAobmV3YXJnID09IE5VTEwpCisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgUHlfSU5DUkVGKHNlbGYpOworICAgICAgICBQeVR1cGxlX1NFVF9JVEVNKG5ld2FyZywgMCwgc2VsZik7CisgICAgICAgIGZvciAoaSA9IDA7IGkgPCBhcmdjb3VudDsgaSsrKSB7CisgICAgICAgICAgICBQeU9iamVjdCAqdiA9IFB5VHVwbGVfR0VUX0lURU0oYXJnLCBpKTsKKyAgICAgICAgICAgIFB5X1hJTkNSRUYodik7CisgICAgICAgICAgICBQeVR1cGxlX1NFVF9JVEVNKG5ld2FyZywgaSsxLCB2KTsKKyAgICAgICAgfQorICAgICAgICBhcmcgPSBuZXdhcmc7CisgICAgfQorICAgIHJlc3VsdCA9IFB5T2JqZWN0X0NhbGwoKFB5T2JqZWN0ICopZnVuYywgYXJnLCBrdyk7CisgICAgUHlfREVDUkVGKGFyZyk7CisgICAgcmV0dXJuIHJlc3VsdDsKK30KKworc3RhdGljIFB5T2JqZWN0ICoKK2luc3RhbmNlbWV0aG9kX2Rlc2NyX2dldChQeU9iamVjdCAqbWV0aCwgUHlPYmplY3QgKm9iaiwgUHlPYmplY3QgKmNscykKK3sKKyAgICAvKiBEb24ndCByZWJpbmQgYW4gYWxyZWFkeSBib3VuZCBtZXRob2QsIG9yIGFuIHVuYm91bmQgbWV0aG9kCisgICAgICAgb2YgYSBjbGFzcyB0aGF0J3Mgbm90IGEgYmFzZSBjbGFzcyBvZiBjbHMuICovCisKKyAgICBpZiAoUHlNZXRob2RfR0VUX1NFTEYobWV0aCkgIT0gTlVMTCkgeworICAgICAgICAvKiBBbHJlYWR5IGJvdW5kICovCisgICAgICAgIFB5X0lOQ1JFRihtZXRoKTsKKyAgICAgICAgcmV0dXJuIG1ldGg7CisgICAgfQorICAgIC8qIE5vLCBpdCBpcyBhbiB1bmJvdW5kIG1ldGhvZCAqLworICAgIGlmIChQeU1ldGhvZF9HRVRfQ0xBU1MobWV0aCkgIT0gTlVMTCAmJiBjbHMgIT0gTlVMTCkgeworICAgICAgICAvKiBEbyBzdWJjbGFzcyB0ZXN0LiAgSWYgaXQgZmFpbHMsIHJldHVybiBtZXRoIHVuY2hhbmdlZC4gKi8KKyAgICAgICAgaW50IG9rID0gUHlPYmplY3RfSXNTdWJjbGFzcyhjbHMsIFB5TWV0aG9kX0dFVF9DTEFTUyhtZXRoKSk7CisgICAgICAgIGlmIChvayA8IDApCisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgaWYgKCFvaykgeworICAgICAgICAgICAgUHlfSU5DUkVGKG1ldGgpOworICAgICAgICAgICAgcmV0dXJuIG1ldGg7CisgICAgICAgIH0KKyAgICB9CisgICAgLyogQmluZCBpdCB0byBvYmogKi8KKyAgICByZXR1cm4gUHlNZXRob2RfTmV3KFB5TWV0aG9kX0dFVF9GVU5DVElPTihtZXRoKSwgb2JqLCBjbHMpOworfQorCitQeVR5cGVPYmplY3QgUHlNZXRob2RfVHlwZSA9IHsKKyAgICBQeU9iamVjdF9IRUFEX0lOSVQoJlB5VHlwZV9UeXBlKQorICAgIDAsCisgICAgImluc3RhbmNlbWV0aG9kIiwKKyAgICBzaXplb2YoUHlNZXRob2RPYmplY3QpLAorICAgIDAsCisgICAgKGRlc3RydWN0b3IpaW5zdGFuY2VtZXRob2RfZGVhbGxvYywgICAgICAgICAvKiB0cF9kZWFsbG9jICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9wcmludCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZ2V0YXR0ciAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfc2V0YXR0ciAqLworICAgIChjbXBmdW5jKWluc3RhbmNlbWV0aG9kX2NvbXBhcmUsICAgICAgICAgICAgLyogdHBfY29tcGFyZSAqLworICAgIChyZXByZnVuYylpbnN0YW5jZW1ldGhvZF9yZXByLCAgICAgICAgICAgICAgLyogdHBfcmVwciAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfYXNfbnVtYmVyICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9hc19zZXF1ZW5jZSAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfYXNfbWFwcGluZyAqLworICAgIChoYXNoZnVuYylpbnN0YW5jZW1ldGhvZF9oYXNoLCAgICAgICAgICAgICAgLyogdHBfaGFzaCAqLworICAgIGluc3RhbmNlbWV0aG9kX2NhbGwsICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfY2FsbCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfc3RyICovCisgICAgaW5zdGFuY2VtZXRob2RfZ2V0YXR0cm8sICAgICAgICAgICAgICAgICAgICAvKiB0cF9nZXRhdHRybyAqLworICAgIFB5T2JqZWN0X0dlbmVyaWNTZXRBdHRyLCAgICAgICAgICAgICAgICAgICAgLyogdHBfc2V0YXR0cm8gKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2FzX2J1ZmZlciAqLworICAgIFB5X1RQRkxBR1NfREVGQVVMVCB8IFB5X1RQRkxBR1NfSEFWRV9HQyAgfCBQeV9UUEZMQUdTX0hBVkVfV0VBS1JFRlMsIC8qIHRwX2ZsYWdzICovCisgICAgaW5zdGFuY2VtZXRob2RfZG9jLCAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9kb2MgKi8KKyAgICAodHJhdmVyc2Vwcm9jKWluc3RhbmNlbWV0aG9kX3RyYXZlcnNlLCAgICAgIC8qIHRwX3RyYXZlcnNlICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9jbGVhciAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfcmljaGNvbXBhcmUgKi8KKyAgICBvZmZzZXRvZihQeU1ldGhvZE9iamVjdCwgaW1fd2Vha3JlZmxpc3QpLCAvKiB0cF93ZWFrbGlzdG9mZnNldCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfaXRlciAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfaXRlcm5leHQgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX21ldGhvZHMgKi8KKyAgICBpbnN0YW5jZW1ldGhvZF9tZW1iZXJsaXN0LCAgICAgICAgICAgICAgICAgIC8qIHRwX21lbWJlcnMgKi8KKyAgICBpbnN0YW5jZW1ldGhvZF9nZXRzZXQsICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2dldHNldCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfYmFzZSAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZGljdCAqLworICAgIGluc3RhbmNlbWV0aG9kX2Rlc2NyX2dldCwgICAgICAgICAgICAgICAgICAgLyogdHBfZGVzY3JfZ2V0ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9kZXNjcl9zZXQgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2RpY3RvZmZzZXQgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2luaXQgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2FsbG9jICovCisgICAgaW5zdGFuY2VtZXRob2RfbmV3LCAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9uZXcgKi8KK307CisKKy8qIENsZWFyIG91dCB0aGUgZnJlZSBsaXN0ICovCisKK2ludAorUHlNZXRob2RfQ2xlYXJGcmVlTGlzdCh2b2lkKQoreworICAgIGludCBmcmVlbGlzdF9zaXplID0gbnVtZnJlZTsKKworICAgIHdoaWxlIChmcmVlX2xpc3QpIHsKKyAgICAgICAgUHlNZXRob2RPYmplY3QgKmltID0gZnJlZV9saXN0OworICAgICAgICBmcmVlX2xpc3QgPSAoUHlNZXRob2RPYmplY3QgKikoaW0tPmltX3NlbGYpOworICAgICAgICBQeU9iamVjdF9HQ19EZWwoaW0pOworICAgICAgICBudW1mcmVlLS07CisgICAgfQorICAgIGFzc2VydChudW1mcmVlID09IDApOworICAgIHJldHVybiBmcmVlbGlzdF9zaXplOworfQorCit2b2lkCitQeU1ldGhvZF9GaW5pKHZvaWQpCit7CisgICAgKHZvaWQpUHlNZXRob2RfQ2xlYXJGcmVlTGlzdCgpOworfQpkaWZmIC0tZ2l0IGEvUHl0aG9uLTIuNy41L09iamVjdHMvY29iamVjdC5jIGIvUHl0aG9uLTIuNy41L09iamVjdHMvY29iamVjdC5jCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjM1NTQyMWUKLS0tIC9kZXYvbnVsbAorKysgYi9QeXRob24tMi43LjUvT2JqZWN0cy9jb2JqZWN0LmMKQEAgLTAsMCArMSwxNzIgQEAKKworLyogV3JhcCB2b2lkKiBwb2ludGVycyB0byBiZSBwYXNzZWQgYmV0d2VlbiBDIG1vZHVsZXMgKi8KKworI2luY2x1ZGUgIlB5dGhvbi5oIgorCisKKy8qIERlY2xhcmF0aW9ucyBmb3Igb2JqZWN0cyBvZiB0eXBlIFB5Q09iamVjdCAqLworCit0eXBlZGVmIHZvaWQgKCpkZXN0cnVjdG9yMSkodm9pZCAqKTsKK3R5cGVkZWYgdm9pZCAoKmRlc3RydWN0b3IyKSh2b2lkICosIHZvaWQqKTsKKworc3RhdGljIGludCBjb2JqZWN0X2RlcHJlY2F0aW9uX3dhcm5pbmcodm9pZCkKK3sKKyAgICByZXR1cm4gUHlFcnJfV2FyblB5M2soIkNPYmplY3QgdHlwZSBpcyBub3Qgc3VwcG9ydGVkIGluIDMueC4gIgorICAgICAgICAiUGxlYXNlIHVzZSBjYXBzdWxlIG9iamVjdHMgaW5zdGVhZC4iLCAxKTsKK30KKworCitQeU9iamVjdCAqCitQeUNPYmplY3RfRnJvbVZvaWRQdHIodm9pZCAqY29iaiwgdm9pZCAoKmRlc3RyKSh2b2lkICopKQoreworICAgIFB5Q09iamVjdCAqc2VsZjsKKworICAgIGlmIChjb2JqZWN0X2RlcHJlY2F0aW9uX3dhcm5pbmcoKSkgeworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisKKyAgICBzZWxmID0gUHlPYmplY3RfTkVXKFB5Q09iamVjdCwgJlB5Q09iamVjdF9UeXBlKTsKKyAgICBpZiAoc2VsZiA9PSBOVUxMKQorICAgICAgICByZXR1cm4gTlVMTDsKKyAgICBzZWxmLT5jb2JqZWN0PWNvYmo7CisgICAgc2VsZi0+ZGVzdHJ1Y3Rvcj1kZXN0cjsKKyAgICBzZWxmLT5kZXNjPU5VTEw7CisKKyAgICByZXR1cm4gKFB5T2JqZWN0ICopc2VsZjsKK30KKworUHlPYmplY3QgKgorUHlDT2JqZWN0X0Zyb21Wb2lkUHRyQW5kRGVzYyh2b2lkICpjb2JqLCB2b2lkICpkZXNjLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2b2lkICgqZGVzdHIpKHZvaWQgKiwgdm9pZCAqKSkKK3sKKyAgICBQeUNPYmplY3QgKnNlbGY7CisKKyAgICBpZiAoY29iamVjdF9kZXByZWNhdGlvbl93YXJuaW5nKCkpIHsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorCisgICAgaWYgKCFkZXNjKSB7CisgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19UeXBlRXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAgICAiUHlDT2JqZWN0X0Zyb21Wb2lkUHRyQW5kRGVzYyBjYWxsZWQgd2l0aCBudWxsIgorICAgICAgICAgICAgICAgICAgICAgICAgIiBkZXNjcmlwdGlvbiIpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgc2VsZiA9IFB5T2JqZWN0X05FVyhQeUNPYmplY3QsICZQeUNPYmplY3RfVHlwZSk7CisgICAgaWYgKHNlbGYgPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgc2VsZi0+Y29iamVjdCA9IGNvYmo7CisgICAgc2VsZi0+ZGVzdHJ1Y3RvciA9IChkZXN0cnVjdG9yMSlkZXN0cjsKKyAgICBzZWxmLT5kZXNjID0gZGVzYzsKKworICAgIHJldHVybiAoUHlPYmplY3QgKilzZWxmOworfQorCit2b2lkICoKK1B5Q09iamVjdF9Bc1ZvaWRQdHIoUHlPYmplY3QgKnNlbGYpCit7CisgICAgaWYgKHNlbGYpIHsKKyAgICAgICAgaWYgKFB5Q2Fwc3VsZV9DaGVja0V4YWN0KHNlbGYpKSB7CisgICAgICAgICAgICBjb25zdCBjaGFyICpuYW1lID0gUHlDYXBzdWxlX0dldE5hbWUoc2VsZik7CisgICAgICAgICAgICByZXR1cm4gKHZvaWQgKilQeUNhcHN1bGVfR2V0UG9pbnRlcihzZWxmLCBuYW1lKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoc2VsZi0+b2JfdHlwZSA9PSAmUHlDT2JqZWN0X1R5cGUpCisgICAgICAgICAgICByZXR1cm4gKChQeUNPYmplY3QgKilzZWxmKS0+Y29iamVjdDsKKyAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1R5cGVFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICJQeUNPYmplY3RfQXNWb2lkUHRyIHdpdGggbm9uLUMtb2JqZWN0Iik7CisgICAgfQorICAgIGlmICghUHlFcnJfT2NjdXJyZWQoKSkKKyAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1R5cGVFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICJQeUNPYmplY3RfQXNWb2lkUHRyIGNhbGxlZCB3aXRoIG51bGwgcG9pbnRlciIpOworICAgIHJldHVybiBOVUxMOworfQorCit2b2lkICoKK1B5Q09iamVjdF9HZXREZXNjKFB5T2JqZWN0ICpzZWxmKQoreworICAgIGlmIChzZWxmKSB7CisgICAgICAgIGlmIChzZWxmLT5vYl90eXBlID09ICZQeUNPYmplY3RfVHlwZSkKKyAgICAgICAgICAgIHJldHVybiAoKFB5Q09iamVjdCAqKXNlbGYpLT5kZXNjOworICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfVHlwZUVycm9yLAorICAgICAgICAgICAgICAgICAgICAgICAgIlB5Q09iamVjdF9HZXREZXNjIHdpdGggbm9uLUMtb2JqZWN0Iik7CisgICAgfQorICAgIGlmICghUHlFcnJfT2NjdXJyZWQoKSkKKyAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1R5cGVFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICJQeUNPYmplY3RfR2V0RGVzYyBjYWxsZWQgd2l0aCBudWxsIHBvaW50ZXIiKTsKKyAgICByZXR1cm4gTlVMTDsKK30KKwordm9pZCAqCitQeUNPYmplY3RfSW1wb3J0KGNoYXIgKm1vZHVsZV9uYW1lLCBjaGFyICpuYW1lKQoreworICAgIFB5T2JqZWN0ICptLCAqYzsKKyAgICB2b2lkICpyID0gTlVMTDsKKworICAgIGlmICgobSA9IFB5SW1wb3J0X0ltcG9ydE1vZHVsZShtb2R1bGVfbmFtZSkpKSB7CisgICAgICAgIGlmICgoYyA9IFB5T2JqZWN0X0dldEF0dHJTdHJpbmcobSxuYW1lKSkpIHsKKyAgICAgICAgICAgIHIgPSBQeUNPYmplY3RfQXNWb2lkUHRyKGMpOworICAgICAgICAgICAgUHlfREVDUkVGKGMpOworCX0KKyAgICAgICAgUHlfREVDUkVGKG0pOworICAgIH0KKyAgICByZXR1cm4gcjsKK30KKworaW50CitQeUNPYmplY3RfU2V0Vm9pZFB0cihQeU9iamVjdCAqc2VsZiwgdm9pZCAqY29iaikKK3sKKyAgICBQeUNPYmplY3QqIGNzZWxmID0gKFB5Q09iamVjdCopc2VsZjsKKyAgICBpZiAoY3NlbGYgPT0gTlVMTCB8fCAhUHlDT2JqZWN0X0NoZWNrKGNzZWxmKSB8fAorCWNzZWxmLT5kZXN0cnVjdG9yICE9IE5VTEwpIHsKKwlQeUVycl9TZXRTdHJpbmcoUHlFeGNfVHlwZUVycm9yLCAKKwkJCSJJbnZhbGlkIGNhbGwgdG8gUHlDT2JqZWN0X1NldFZvaWRQdHIiKTsKKwlyZXR1cm4gMDsKKyAgICB9CisgICAgY3NlbGYtPmNvYmplY3QgPSBjb2JqOworICAgIHJldHVybiAxOworfQorCitzdGF0aWMgdm9pZAorUHlDT2JqZWN0X2RlYWxsb2MoUHlDT2JqZWN0ICpzZWxmKQoreworICAgIGlmIChzZWxmLT5kZXN0cnVjdG9yKSB7CisgICAgICAgIGlmKHNlbGYtPmRlc2MpCisgICAgICAgICAgICAoKGRlc3RydWN0b3IyKShzZWxmLT5kZXN0cnVjdG9yKSkoc2VsZi0+Y29iamVjdCwgc2VsZi0+ZGVzYyk7CisgICAgICAgIGVsc2UKKyAgICAgICAgICAgIChzZWxmLT5kZXN0cnVjdG9yKShzZWxmLT5jb2JqZWN0KTsKKyAgICB9CisgICAgUHlPYmplY3RfREVMKHNlbGYpOworfQorCisKK1B5RG9jX1NUUlZBUihQeUNPYmplY3RfVHlwZV9fZG9jX18sCisiQyBvYmplY3RzIHRvIGJlIGV4cG9ydGVkIGZyb20gb25lIGV4dGVuc2lvbiBtb2R1bGUgdG8gYW5vdGhlclxuXAorXG5cCitDIG9iamVjdHMgYXJlIHVzZWQgZm9yIGNvbW11bmljYXRpb24gYmV0d2VlbiBleHRlbnNpb24gbW9kdWxlcy4gIFRoZXlcblwKK3Byb3ZpZGUgYSB3YXkgZm9yIGFuIGV4dGVuc2lvbiBtb2R1bGUgdG8gZXhwb3J0IGEgQyBpbnRlcmZhY2UgdG8gb3RoZXJcblwKK2V4dGVuc2lvbiBtb2R1bGVzLCBzbyB0aGF0IGV4dGVuc2lvbiBtb2R1bGVzIGNhbiB1c2UgdGhlIFB5dGhvbiBpbXBvcnRcblwKK21lY2hhbmlzbSB0byBsaW5rIHRvIG9uZSBhbm90aGVyLiIpOworCitQeVR5cGVPYmplY3QgUHlDT2JqZWN0X1R5cGUgPSB7CisgICAgUHlWYXJPYmplY3RfSEVBRF9JTklUKCZQeVR5cGVfVHlwZSwgMCkKKyAgICAiUHlDT2JqZWN0IiwJCS8qdHBfbmFtZSovCisgICAgc2l6ZW9mKFB5Q09iamVjdCksCQkvKnRwX2Jhc2ljc2l6ZSovCisgICAgMCwJCQkJLyp0cF9pdGVtc2l6ZSovCisgICAgLyogbWV0aG9kcyAqLworICAgIChkZXN0cnVjdG9yKVB5Q09iamVjdF9kZWFsbG9jLCAvKnRwX2RlYWxsb2MqLworICAgIDAsCQkJCS8qdHBfcHJpbnQqLworICAgIDAsCQkJCS8qdHBfZ2V0YXR0ciovCisgICAgMCwJCQkJLyp0cF9zZXRhdHRyKi8KKyAgICAwLAkJCQkvKnRwX2NvbXBhcmUqLworICAgIDAsCQkJCS8qdHBfcmVwciovCisgICAgMCwJCQkJLyp0cF9hc19udW1iZXIqLworICAgIDAsCQkJCS8qdHBfYXNfc2VxdWVuY2UqLworICAgIDAsCQkJCS8qdHBfYXNfbWFwcGluZyovCisgICAgMCwJCQkJLyp0cF9oYXNoKi8KKyAgICAwLAkJCQkvKnRwX2NhbGwqLworICAgIDAsCQkJCS8qdHBfc3RyKi8KKyAgICAwLAkJCQkvKnRwX2dldGF0dHJvKi8KKyAgICAwLAkJCQkvKnRwX3NldGF0dHJvKi8KKyAgICAwLAkJCQkvKnRwX2FzX2J1ZmZlciovCisgICAgMCwJCQkJLyp0cF9mbGFncyovCisgICAgUHlDT2JqZWN0X1R5cGVfX2RvY19fCS8qdHBfZG9jKi8KK307CmRpZmYgLS1naXQgYS9QeXRob24tMi43LjUvT2JqZWN0cy9jb2Rlb2JqZWN0LmMgYi9QeXRob24tMi43LjUvT2JqZWN0cy9jb2Rlb2JqZWN0LmMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uOTg3OWRmNQotLS0gL2Rldi9udWxsCisrKyBiL1B5dGhvbi0yLjcuNS9PYmplY3RzL2NvZGVvYmplY3QuYwpAQCAtMCwwICsxLDU4MSBAQAorI2luY2x1ZGUgIlB5dGhvbi5oIgorI2luY2x1ZGUgImNvZGUuaCIKKyNpbmNsdWRlICJzdHJ1Y3RtZW1iZXIuaCIKKworI2RlZmluZSBOQU1FX0NIQVJTIFwKKyAgICAiMDEyMzQ1Njc4OUFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaX2FiY2RlZmdoaWprbG1ub3BxcnN0dXZ3eHl6IgorCisvKiBhbGxfbmFtZV9jaGFycyhzKTogdHJ1ZSBpZmYgYWxsIGNoYXJzIGluIHMgYXJlIHZhbGlkIE5BTUVfQ0hBUlMgKi8KKworc3RhdGljIGludAorYWxsX25hbWVfY2hhcnModW5zaWduZWQgY2hhciAqcykKK3sKKyAgICBzdGF0aWMgY2hhciBva19uYW1lX2NoYXJbMjU2XTsKKyAgICBzdGF0aWMgdW5zaWduZWQgY2hhciAqbmFtZV9jaGFycyA9ICh1bnNpZ25lZCBjaGFyICopTkFNRV9DSEFSUzsKKworICAgIGlmIChva19uYW1lX2NoYXJbKm5hbWVfY2hhcnNdID09IDApIHsKKyAgICAgICAgdW5zaWduZWQgY2hhciAqcDsKKyAgICAgICAgZm9yIChwID0gbmFtZV9jaGFyczsgKnA7IHArKykKKyAgICAgICAgICAgIG9rX25hbWVfY2hhclsqcF0gPSAxOworICAgIH0KKyAgICB3aGlsZSAoKnMpIHsKKyAgICAgICAgaWYgKG9rX25hbWVfY2hhclsqcysrXSA9PSAwKQorICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgfQorICAgIHJldHVybiAxOworfQorCitzdGF0aWMgdm9pZAoraW50ZXJuX3N0cmluZ3MoUHlPYmplY3QgKnR1cGxlKQoreworICAgIFB5X3NzaXplX3QgaTsKKworICAgIGZvciAoaSA9IFB5VHVwbGVfR0VUX1NJWkUodHVwbGUpOyAtLWkgPj0gMDsgKSB7CisgICAgICAgIFB5T2JqZWN0ICp2ID0gUHlUdXBsZV9HRVRfSVRFTSh0dXBsZSwgaSk7CisgICAgICAgIGlmICh2ID09IE5VTEwgfHwgIVB5U3RyaW5nX0NoZWNrRXhhY3QodikpIHsKKyAgICAgICAgICAgIFB5X0ZhdGFsRXJyb3IoIm5vbi1zdHJpbmcgZm91bmQgaW4gY29kZSBzbG90Iik7CisgICAgICAgIH0KKyAgICAgICAgUHlTdHJpbmdfSW50ZXJuSW5QbGFjZSgmUHlUdXBsZV9HRVRfSVRFTSh0dXBsZSwgaSkpOworICAgIH0KK30KKworCitQeUNvZGVPYmplY3QgKgorUHlDb2RlX05ldyhpbnQgYXJnY291bnQsIGludCBubG9jYWxzLCBpbnQgc3RhY2tzaXplLCBpbnQgZmxhZ3MsCisgICAgICAgICAgIFB5T2JqZWN0ICpjb2RlLCBQeU9iamVjdCAqY29uc3RzLCBQeU9iamVjdCAqbmFtZXMsCisgICAgICAgICAgIFB5T2JqZWN0ICp2YXJuYW1lcywgUHlPYmplY3QgKmZyZWV2YXJzLCBQeU9iamVjdCAqY2VsbHZhcnMsCisgICAgICAgICAgIFB5T2JqZWN0ICpmaWxlbmFtZSwgUHlPYmplY3QgKm5hbWUsIGludCBmaXJzdGxpbmVubywKKyAgICAgICAgICAgUHlPYmplY3QgKmxub3RhYikKK3sKKyAgICBQeUNvZGVPYmplY3QgKmNvOworICAgIFB5X3NzaXplX3QgaTsKKyAgICAvKiBDaGVjayBhcmd1bWVudCB0eXBlcyAqLworICAgIGlmIChhcmdjb3VudCA8IDAgfHwgbmxvY2FscyA8IDAgfHwKKyAgICAgICAgY29kZSA9PSBOVUxMIHx8CisgICAgICAgIGNvbnN0cyA9PSBOVUxMIHx8ICFQeVR1cGxlX0NoZWNrKGNvbnN0cykgfHwKKyAgICAgICAgbmFtZXMgPT0gTlVMTCB8fCAhUHlUdXBsZV9DaGVjayhuYW1lcykgfHwKKyAgICAgICAgdmFybmFtZXMgPT0gTlVMTCB8fCAhUHlUdXBsZV9DaGVjayh2YXJuYW1lcykgfHwKKyAgICAgICAgZnJlZXZhcnMgPT0gTlVMTCB8fCAhUHlUdXBsZV9DaGVjayhmcmVldmFycykgfHwKKyAgICAgICAgY2VsbHZhcnMgPT0gTlVMTCB8fCAhUHlUdXBsZV9DaGVjayhjZWxsdmFycykgfHwKKyAgICAgICAgbmFtZSA9PSBOVUxMIHx8ICFQeVN0cmluZ19DaGVjayhuYW1lKSB8fAorICAgICAgICBmaWxlbmFtZSA9PSBOVUxMIHx8ICFQeVN0cmluZ19DaGVjayhmaWxlbmFtZSkgfHwKKyAgICAgICAgbG5vdGFiID09IE5VTEwgfHwgIVB5U3RyaW5nX0NoZWNrKGxub3RhYikgfHwKKyAgICAgICAgIVB5T2JqZWN0X0NoZWNrUmVhZEJ1ZmZlcihjb2RlKSkgeworICAgICAgICBQeUVycl9CYWRJbnRlcm5hbENhbGwoKTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIGludGVybl9zdHJpbmdzKG5hbWVzKTsKKyAgICBpbnRlcm5fc3RyaW5ncyh2YXJuYW1lcyk7CisgICAgaW50ZXJuX3N0cmluZ3MoZnJlZXZhcnMpOworICAgIGludGVybl9zdHJpbmdzKGNlbGx2YXJzKTsKKyAgICAvKiBJbnRlcm4gc2VsZWN0ZWQgc3RyaW5nIGNvbnN0YW50cyAqLworICAgIGZvciAoaSA9IFB5VHVwbGVfU2l6ZShjb25zdHMpOyAtLWkgPj0gMDsgKSB7CisgICAgICAgIFB5T2JqZWN0ICp2ID0gUHlUdXBsZV9HZXRJdGVtKGNvbnN0cywgaSk7CisgICAgICAgIGlmICghUHlTdHJpbmdfQ2hlY2sodikpCisgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgaWYgKCFhbGxfbmFtZV9jaGFycygodW5zaWduZWQgY2hhciAqKVB5U3RyaW5nX0FTX1NUUklORyh2KSkpCisgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgUHlTdHJpbmdfSW50ZXJuSW5QbGFjZSgmUHlUdXBsZV9HRVRfSVRFTShjb25zdHMsIGkpKTsKKyAgICB9CisgICAgY28gPSBQeU9iamVjdF9ORVcoUHlDb2RlT2JqZWN0LCAmUHlDb2RlX1R5cGUpOworICAgIGlmIChjbyAhPSBOVUxMKSB7CisgICAgICAgIGNvLT5jb19hcmdjb3VudCA9IGFyZ2NvdW50OworICAgICAgICBjby0+Y29fbmxvY2FscyA9IG5sb2NhbHM7CisgICAgICAgIGNvLT5jb19zdGFja3NpemUgPSBzdGFja3NpemU7CisgICAgICAgIGNvLT5jb19mbGFncyA9IGZsYWdzOworICAgICAgICBQeV9JTkNSRUYoY29kZSk7CisgICAgICAgIGNvLT5jb19jb2RlID0gY29kZTsKKyAgICAgICAgUHlfSU5DUkVGKGNvbnN0cyk7CisgICAgICAgIGNvLT5jb19jb25zdHMgPSBjb25zdHM7CisgICAgICAgIFB5X0lOQ1JFRihuYW1lcyk7CisgICAgICAgIGNvLT5jb19uYW1lcyA9IG5hbWVzOworICAgICAgICBQeV9JTkNSRUYodmFybmFtZXMpOworICAgICAgICBjby0+Y29fdmFybmFtZXMgPSB2YXJuYW1lczsKKyAgICAgICAgUHlfSU5DUkVGKGZyZWV2YXJzKTsKKyAgICAgICAgY28tPmNvX2ZyZWV2YXJzID0gZnJlZXZhcnM7CisgICAgICAgIFB5X0lOQ1JFRihjZWxsdmFycyk7CisgICAgICAgIGNvLT5jb19jZWxsdmFycyA9IGNlbGx2YXJzOworICAgICAgICBQeV9JTkNSRUYoZmlsZW5hbWUpOworICAgICAgICBjby0+Y29fZmlsZW5hbWUgPSBmaWxlbmFtZTsKKyAgICAgICAgUHlfSU5DUkVGKG5hbWUpOworICAgICAgICBjby0+Y29fbmFtZSA9IG5hbWU7CisgICAgICAgIGNvLT5jb19maXJzdGxpbmVubyA9IGZpcnN0bGluZW5vOworICAgICAgICBQeV9JTkNSRUYobG5vdGFiKTsKKyAgICAgICAgY28tPmNvX2xub3RhYiA9IGxub3RhYjsKKyAgICAgICAgY28tPmNvX3pvbWJpZWZyYW1lID0gTlVMTDsKKyAgICAgICAgY28tPmNvX3dlYWtyZWZsaXN0ID0gTlVMTDsKKyAgICB9CisgICAgcmV0dXJuIGNvOworfQorCitQeUNvZGVPYmplY3QgKgorUHlDb2RlX05ld0VtcHR5KGNvbnN0IGNoYXIgKmZpbGVuYW1lLCBjb25zdCBjaGFyICpmdW5jbmFtZSwgaW50IGZpcnN0bGluZW5vKQoreworICAgIHN0YXRpYyBQeU9iamVjdCAqZW1wdHlzdHJpbmcgPSBOVUxMOworICAgIHN0YXRpYyBQeU9iamVjdCAqbnVsbHR1cGxlID0gTlVMTDsKKyAgICBQeU9iamVjdCAqZmlsZW5hbWVfb2IgPSBOVUxMOworICAgIFB5T2JqZWN0ICpmdW5jbmFtZV9vYiA9IE5VTEw7CisgICAgUHlDb2RlT2JqZWN0ICpyZXN1bHQgPSBOVUxMOworICAgIGlmIChlbXB0eXN0cmluZyA9PSBOVUxMKSB7CisgICAgICAgIGVtcHR5c3RyaW5nID0gUHlTdHJpbmdfRnJvbVN0cmluZygiIik7CisgICAgICAgIGlmIChlbXB0eXN0cmluZyA9PSBOVUxMKQorICAgICAgICAgICAgZ290byBmYWlsZWQ7CisgICAgfQorICAgIGlmIChudWxsdHVwbGUgPT0gTlVMTCkgeworICAgICAgICBudWxsdHVwbGUgPSBQeVR1cGxlX05ldygwKTsKKyAgICAgICAgaWYgKG51bGx0dXBsZSA9PSBOVUxMKQorICAgICAgICAgICAgZ290byBmYWlsZWQ7CisgICAgfQorICAgIGZ1bmNuYW1lX29iID0gUHlTdHJpbmdfRnJvbVN0cmluZyhmdW5jbmFtZSk7CisgICAgaWYgKGZ1bmNuYW1lX29iID09IE5VTEwpCisgICAgICAgIGdvdG8gZmFpbGVkOworICAgIGZpbGVuYW1lX29iID0gUHlTdHJpbmdfRnJvbVN0cmluZyhmaWxlbmFtZSk7CisgICAgaWYgKGZpbGVuYW1lX29iID09IE5VTEwpCisgICAgICAgIGdvdG8gZmFpbGVkOworCisgICAgcmVzdWx0ID0gUHlDb2RlX05ldygwLCAgICAgICAgICAgICAgICAgICAgICAvKiBhcmdjb3VudCAqLworICAgICAgICAgICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogbmxvY2FscyAqLworICAgICAgICAgICAgICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogc3RhY2tzaXplICovCisgICAgICAgICAgICAgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBmbGFncyAqLworICAgICAgICAgICAgICAgIGVtcHR5c3RyaW5nLCAgICAgICAgICAgICAgICAgICAgLyogY29kZSAqLworICAgICAgICAgICAgICAgIG51bGx0dXBsZSwgICAgICAgICAgICAgICAgICAgICAgLyogY29uc3RzICovCisgICAgICAgICAgICAgICAgbnVsbHR1cGxlLCAgICAgICAgICAgICAgICAgICAgICAvKiBuYW1lcyAqLworICAgICAgICAgICAgICAgIG51bGx0dXBsZSwgICAgICAgICAgICAgICAgICAgICAgLyogdmFybmFtZXMgKi8KKyAgICAgICAgICAgICAgICBudWxsdHVwbGUsICAgICAgICAgICAgICAgICAgICAgIC8qIGZyZWV2YXJzICovCisgICAgICAgICAgICAgICAgbnVsbHR1cGxlLCAgICAgICAgICAgICAgICAgICAgICAvKiBjZWxsdmFycyAqLworICAgICAgICAgICAgICAgIGZpbGVuYW1lX29iLCAgICAgICAgICAgICAgICAgICAgLyogZmlsZW5hbWUgKi8KKyAgICAgICAgICAgICAgICBmdW5jbmFtZV9vYiwgICAgICAgICAgICAgICAgICAgIC8qIG5hbWUgKi8KKyAgICAgICAgICAgICAgICBmaXJzdGxpbmVubywgICAgICAgICAgICAgICAgICAgIC8qIGZpcnN0bGluZW5vICovCisgICAgICAgICAgICAgICAgZW1wdHlzdHJpbmcgICAgICAgICAgICAgICAgICAgICAvKiBsbm90YWIgKi8KKyAgICAgICAgICAgICAgICApOworCitmYWlsZWQ6CisgICAgUHlfWERFQ1JFRihmdW5jbmFtZV9vYik7CisgICAgUHlfWERFQ1JFRihmaWxlbmFtZV9vYik7CisgICAgcmV0dXJuIHJlc3VsdDsKK30KKworI2RlZmluZSBPRkYoeCkgb2Zmc2V0b2YoUHlDb2RlT2JqZWN0LCB4KQorCitzdGF0aWMgUHlNZW1iZXJEZWYgY29kZV9tZW1iZXJsaXN0W10gPSB7CisgICAgeyJjb19hcmdjb3VudCIsICAgICBUX0lOVCwgICAgICAgICAgT0ZGKGNvX2FyZ2NvdW50KSwgICAgICAgUkVBRE9OTFl9LAorICAgIHsiY29fbmxvY2FscyIsICAgICAgVF9JTlQsICAgICAgICAgIE9GRihjb19ubG9jYWxzKSwgICAgICAgIFJFQURPTkxZfSwKKyAgICB7ImNvX3N0YWNrc2l6ZSIsVF9JTlQsICAgICAgICAgICAgICBPRkYoY29fc3RhY2tzaXplKSwgICAgICBSRUFET05MWX0sCisgICAgeyJjb19mbGFncyIsICAgICAgICBUX0lOVCwgICAgICAgICAgT0ZGKGNvX2ZsYWdzKSwgICAgICAgICAgUkVBRE9OTFl9LAorICAgIHsiY29fY29kZSIsICAgICAgICAgVF9PQkpFQ1QsICAgICAgIE9GRihjb19jb2RlKSwgICAgICAgICAgIFJFQURPTkxZfSwKKyAgICB7ImNvX2NvbnN0cyIsICAgICAgIFRfT0JKRUNULCAgICAgICBPRkYoY29fY29uc3RzKSwgICAgICAgICBSRUFET05MWX0sCisgICAgeyJjb19uYW1lcyIsICAgICAgICBUX09CSkVDVCwgICAgICAgT0ZGKGNvX25hbWVzKSwgICAgICAgICAgUkVBRE9OTFl9LAorICAgIHsiY29fdmFybmFtZXMiLCAgICAgVF9PQkpFQ1QsICAgICAgIE9GRihjb192YXJuYW1lcyksICAgICAgIFJFQURPTkxZfSwKKyAgICB7ImNvX2ZyZWV2YXJzIiwgICAgIFRfT0JKRUNULCAgICAgICBPRkYoY29fZnJlZXZhcnMpLCAgICAgICBSRUFET05MWX0sCisgICAgeyJjb19jZWxsdmFycyIsICAgICBUX09CSkVDVCwgICAgICAgT0ZGKGNvX2NlbGx2YXJzKSwgICAgICAgUkVBRE9OTFl9LAorICAgIHsiY29fZmlsZW5hbWUiLCAgICAgVF9PQkpFQ1QsICAgICAgIE9GRihjb19maWxlbmFtZSksICAgICAgIFJFQURPTkxZfSwKKyAgICB7ImNvX25hbWUiLCAgICAgICAgIFRfT0JKRUNULCAgICAgICBPRkYoY29fbmFtZSksICAgICAgICAgICBSRUFET05MWX0sCisgICAgeyJjb19maXJzdGxpbmVubyIsIFRfSU5ULCAgICAgICAgICAgT0ZGKGNvX2ZpcnN0bGluZW5vKSwgICAgUkVBRE9OTFl9LAorICAgIHsiY29fbG5vdGFiIiwgICAgICAgVF9PQkpFQ1QsICAgICAgIE9GRihjb19sbm90YWIpLCAgICAgICAgIFJFQURPTkxZfSwKKyAgICB7TlVMTH0gICAgICAvKiBTZW50aW5lbCAqLworfTsKKworLyogSGVscGVyIGZvciBjb2RlX25ldzogcmV0dXJuIGEgc2hhbGxvdyBjb3B5IG9mIGEgdHVwbGUgdGhhdCBpcworICAgZ3VhcmFudGVlZCB0byBjb250YWluIGV4YWN0IHN0cmluZ3MsIGJ5IGNvbnZlcnRpbmcgc3RyaW5nIHN1YmNsYXNzZXMKKyAgIHRvIGV4YWN0IHN0cmluZ3MgYW5kIGNvbXBsYWluaW5nIGlmIGEgbm9uLXN0cmluZyBpcyBmb3VuZC4gKi8KK3N0YXRpYyBQeU9iamVjdCoKK3ZhbGlkYXRlX2FuZF9jb3B5X3R1cGxlKFB5T2JqZWN0ICp0dXApCit7CisgICAgUHlPYmplY3QgKm5ld3R1cGxlOworICAgIFB5T2JqZWN0ICppdGVtOworICAgIFB5X3NzaXplX3QgaSwgbGVuOworCisgICAgbGVuID0gUHlUdXBsZV9HRVRfU0laRSh0dXApOworICAgIG5ld3R1cGxlID0gUHlUdXBsZV9OZXcobGVuKTsKKyAgICBpZiAobmV3dHVwbGUgPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisKKyAgICBmb3IgKGkgPSAwOyBpIDwgbGVuOyBpKyspIHsKKyAgICAgICAgaXRlbSA9IFB5VHVwbGVfR0VUX0lURU0odHVwLCBpKTsKKyAgICAgICAgaWYgKFB5U3RyaW5nX0NoZWNrRXhhY3QoaXRlbSkpIHsKKyAgICAgICAgICAgIFB5X0lOQ1JFRihpdGVtKTsKKyAgICAgICAgfQorICAgICAgICBlbHNlIGlmICghUHlTdHJpbmdfQ2hlY2soaXRlbSkpIHsKKyAgICAgICAgICAgIFB5RXJyX0Zvcm1hdCgKKyAgICAgICAgICAgICAgICBQeUV4Y19UeXBlRXJyb3IsCisgICAgICAgICAgICAgICAgIm5hbWUgdHVwbGVzIG11c3QgY29udGFpbiBvbmx5ICIKKyAgICAgICAgICAgICAgICAic3RyaW5ncywgbm90ICclLjUwMHMnIiwKKyAgICAgICAgICAgICAgICBpdGVtLT5vYl90eXBlLT50cF9uYW1lKTsKKyAgICAgICAgICAgIFB5X0RFQ1JFRihuZXd0dXBsZSk7CisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgfQorICAgICAgICBlbHNlIHsKKyAgICAgICAgICAgIGl0ZW0gPSBQeVN0cmluZ19Gcm9tU3RyaW5nQW5kU2l6ZSgKKyAgICAgICAgICAgICAgICBQeVN0cmluZ19BU19TVFJJTkcoaXRlbSksCisgICAgICAgICAgICAgICAgUHlTdHJpbmdfR0VUX1NJWkUoaXRlbSkpOworICAgICAgICAgICAgaWYgKGl0ZW0gPT0gTlVMTCkgeworICAgICAgICAgICAgICAgIFB5X0RFQ1JFRihuZXd0dXBsZSk7CisgICAgICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgUHlUdXBsZV9TRVRfSVRFTShuZXd0dXBsZSwgaSwgaXRlbSk7CisgICAgfQorCisgICAgcmV0dXJuIG5ld3R1cGxlOworfQorCitQeURvY19TVFJWQVIoY29kZV9kb2MsCisiY29kZShhcmdjb3VudCwgbmxvY2Fscywgc3RhY2tzaXplLCBmbGFncywgY29kZXN0cmluZywgY29uc3RhbnRzLCBuYW1lcyxcblwKKyAgICAgIHZhcm5hbWVzLCBmaWxlbmFtZSwgbmFtZSwgZmlyc3RsaW5lbm8sIGxub3RhYlssIGZyZWV2YXJzWywgY2VsbHZhcnNdXSlcblwKK1xuXAorQ3JlYXRlIGEgY29kZSBvYmplY3QuICBOb3QgZm9yIHRoZSBmYWludCBvZiBoZWFydC4iKTsKKworc3RhdGljIFB5T2JqZWN0ICoKK2NvZGVfbmV3KFB5VHlwZU9iamVjdCAqdHlwZSwgUHlPYmplY3QgKmFyZ3MsIFB5T2JqZWN0ICprdykKK3sKKyAgICBpbnQgYXJnY291bnQ7CisgICAgaW50IG5sb2NhbHM7CisgICAgaW50IHN0YWNrc2l6ZTsKKyAgICBpbnQgZmxhZ3M7CisgICAgUHlPYmplY3QgKmNvID0gTlVMTDsKKyAgICBQeU9iamVjdCAqY29kZTsKKyAgICBQeU9iamVjdCAqY29uc3RzOworICAgIFB5T2JqZWN0ICpuYW1lcywgKm91cm5hbWVzID0gTlVMTDsKKyAgICBQeU9iamVjdCAqdmFybmFtZXMsICpvdXJ2YXJuYW1lcyA9IE5VTEw7CisgICAgUHlPYmplY3QgKmZyZWV2YXJzID0gTlVMTCwgKm91cmZyZWV2YXJzID0gTlVMTDsKKyAgICBQeU9iamVjdCAqY2VsbHZhcnMgPSBOVUxMLCAqb3VyY2VsbHZhcnMgPSBOVUxMOworICAgIFB5T2JqZWN0ICpmaWxlbmFtZTsKKyAgICBQeU9iamVjdCAqbmFtZTsKKyAgICBpbnQgZmlyc3RsaW5lbm87CisgICAgUHlPYmplY3QgKmxub3RhYjsKKworICAgIGlmICghUHlBcmdfUGFyc2VUdXBsZShhcmdzLCAiaWlpaVNPIU8hTyFTU2lTfE8hTyE6Y29kZSIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICZhcmdjb3VudCwgJm5sb2NhbHMsICZzdGFja3NpemUsICZmbGFncywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgJmNvZGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICZQeVR1cGxlX1R5cGUsICZjb25zdHMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICZQeVR1cGxlX1R5cGUsICZuYW1lcywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgJlB5VHVwbGVfVHlwZSwgJnZhcm5hbWVzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAmZmlsZW5hbWUsICZuYW1lLAorICAgICAgICAgICAgICAgICAgICAgICAgICAmZmlyc3RsaW5lbm8sICZsbm90YWIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICZQeVR1cGxlX1R5cGUsICZmcmVldmFycywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgJlB5VHVwbGVfVHlwZSwgJmNlbGx2YXJzKSkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisKKyAgICBpZiAoYXJnY291bnQgPCAwKSB7CisgICAgICAgIFB5RXJyX1NldFN0cmluZygKKyAgICAgICAgICAgIFB5RXhjX1ZhbHVlRXJyb3IsCisgICAgICAgICAgICAiY29kZTogYXJnY291bnQgbXVzdCBub3QgYmUgbmVnYXRpdmUiKTsKKyAgICAgICAgZ290byBjbGVhbnVwOworICAgIH0KKworICAgIGlmIChubG9jYWxzIDwgMCkgeworICAgICAgICBQeUVycl9TZXRTdHJpbmcoCisgICAgICAgICAgICBQeUV4Y19WYWx1ZUVycm9yLAorICAgICAgICAgICAgImNvZGU6IG5sb2NhbHMgbXVzdCBub3QgYmUgbmVnYXRpdmUiKTsKKyAgICAgICAgZ290byBjbGVhbnVwOworICAgIH0KKworICAgIG91cm5hbWVzID0gdmFsaWRhdGVfYW5kX2NvcHlfdHVwbGUobmFtZXMpOworICAgIGlmIChvdXJuYW1lcyA9PSBOVUxMKQorICAgICAgICBnb3RvIGNsZWFudXA7CisgICAgb3VydmFybmFtZXMgPSB2YWxpZGF0ZV9hbmRfY29weV90dXBsZSh2YXJuYW1lcyk7CisgICAgaWYgKG91cnZhcm5hbWVzID09IE5VTEwpCisgICAgICAgIGdvdG8gY2xlYW51cDsKKyAgICBpZiAoZnJlZXZhcnMpCisgICAgICAgIG91cmZyZWV2YXJzID0gdmFsaWRhdGVfYW5kX2NvcHlfdHVwbGUoZnJlZXZhcnMpOworICAgIGVsc2UKKyAgICAgICAgb3VyZnJlZXZhcnMgPSBQeVR1cGxlX05ldygwKTsKKyAgICBpZiAob3VyZnJlZXZhcnMgPT0gTlVMTCkKKyAgICAgICAgZ290byBjbGVhbnVwOworICAgIGlmIChjZWxsdmFycykKKyAgICAgICAgb3VyY2VsbHZhcnMgPSB2YWxpZGF0ZV9hbmRfY29weV90dXBsZShjZWxsdmFycyk7CisgICAgZWxzZQorICAgICAgICBvdXJjZWxsdmFycyA9IFB5VHVwbGVfTmV3KDApOworICAgIGlmIChvdXJjZWxsdmFycyA9PSBOVUxMKQorICAgICAgICBnb3RvIGNsZWFudXA7CisKKyAgICBjbyA9IChQeU9iamVjdCAqKVB5Q29kZV9OZXcoYXJnY291bnQsIG5sb2NhbHMsIHN0YWNrc2l6ZSwgZmxhZ3MsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvZGUsIGNvbnN0cywgb3VybmFtZXMsIG91cnZhcm5hbWVzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvdXJmcmVldmFycywgb3VyY2VsbHZhcnMsIGZpbGVuYW1lLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lLCBmaXJzdGxpbmVubywgbG5vdGFiKTsKKyAgY2xlYW51cDoKKyAgICBQeV9YREVDUkVGKG91cm5hbWVzKTsKKyAgICBQeV9YREVDUkVGKG91cnZhcm5hbWVzKTsKKyAgICBQeV9YREVDUkVGKG91cmZyZWV2YXJzKTsKKyAgICBQeV9YREVDUkVGKG91cmNlbGx2YXJzKTsKKyAgICByZXR1cm4gY287Cit9CisKK3N0YXRpYyB2b2lkCitjb2RlX2RlYWxsb2MoUHlDb2RlT2JqZWN0ICpjbykKK3sKKyAgICBQeV9YREVDUkVGKGNvLT5jb19jb2RlKTsKKyAgICBQeV9YREVDUkVGKGNvLT5jb19jb25zdHMpOworICAgIFB5X1hERUNSRUYoY28tPmNvX25hbWVzKTsKKyAgICBQeV9YREVDUkVGKGNvLT5jb192YXJuYW1lcyk7CisgICAgUHlfWERFQ1JFRihjby0+Y29fZnJlZXZhcnMpOworICAgIFB5X1hERUNSRUYoY28tPmNvX2NlbGx2YXJzKTsKKyAgICBQeV9YREVDUkVGKGNvLT5jb19maWxlbmFtZSk7CisgICAgUHlfWERFQ1JFRihjby0+Y29fbmFtZSk7CisgICAgUHlfWERFQ1JFRihjby0+Y29fbG5vdGFiKTsKKyAgICBpZiAoY28tPmNvX3pvbWJpZWZyYW1lICE9IE5VTEwpCisgICAgICAgIFB5T2JqZWN0X0dDX0RlbChjby0+Y29fem9tYmllZnJhbWUpOworICAgIGlmIChjby0+Y29fd2Vha3JlZmxpc3QgIT0gTlVMTCkKKyAgICAgICAgUHlPYmplY3RfQ2xlYXJXZWFrUmVmcygoUHlPYmplY3QqKWNvKTsKKyAgICBQeU9iamVjdF9ERUwoY28pOworfQorCitzdGF0aWMgUHlPYmplY3QgKgorY29kZV9yZXByKFB5Q29kZU9iamVjdCAqY28pCit7CisgICAgY2hhciBidWZbNTAwXTsKKyAgICBpbnQgbGluZW5vID0gLTE7CisgICAgY2hhciAqZmlsZW5hbWUgPSAiPz8/IjsKKyAgICBjaGFyICpuYW1lID0gIj8/PyI7CisKKyAgICBpZiAoY28tPmNvX2ZpcnN0bGluZW5vICE9IDApCisgICAgICAgIGxpbmVubyA9IGNvLT5jb19maXJzdGxpbmVubzsKKyAgICBpZiAoY28tPmNvX2ZpbGVuYW1lICYmIFB5U3RyaW5nX0NoZWNrKGNvLT5jb19maWxlbmFtZSkpCisgICAgICAgIGZpbGVuYW1lID0gUHlTdHJpbmdfQVNfU1RSSU5HKGNvLT5jb19maWxlbmFtZSk7CisgICAgaWYgKGNvLT5jb19uYW1lICYmIFB5U3RyaW5nX0NoZWNrKGNvLT5jb19uYW1lKSkKKyAgICAgICAgbmFtZSA9IFB5U3RyaW5nX0FTX1NUUklORyhjby0+Y29fbmFtZSk7CisgICAgUHlPU19zbnByaW50ZihidWYsIHNpemVvZihidWYpLAorICAgICAgICAgICAgICAgICAgIjxjb2RlIG9iamVjdCAlLjEwMHMgYXQgJXAsIGZpbGUgXCIlLjMwMHNcIiwgbGluZSAlZD4iLAorICAgICAgICAgICAgICAgICAgbmFtZSwgY28sIGZpbGVuYW1lLCBsaW5lbm8pOworICAgIHJldHVybiBQeVN0cmluZ19Gcm9tU3RyaW5nKGJ1Zik7Cit9CisKK3N0YXRpYyBpbnQKK2NvZGVfY29tcGFyZShQeUNvZGVPYmplY3QgKmNvLCBQeUNvZGVPYmplY3QgKmNwKQoreworICAgIGludCBjbXA7CisgICAgY21wID0gUHlPYmplY3RfQ29tcGFyZShjby0+Y29fbmFtZSwgY3AtPmNvX25hbWUpOworICAgIGlmIChjbXApIHJldHVybiBjbXA7CisgICAgY21wID0gY28tPmNvX2FyZ2NvdW50IC0gY3AtPmNvX2FyZ2NvdW50OworICAgIGlmIChjbXApIGdvdG8gbm9ybWFsaXplOworICAgIGNtcCA9IGNvLT5jb19ubG9jYWxzIC0gY3AtPmNvX25sb2NhbHM7CisgICAgaWYgKGNtcCkgZ290byBub3JtYWxpemU7CisgICAgY21wID0gY28tPmNvX2ZsYWdzIC0gY3AtPmNvX2ZsYWdzOworICAgIGlmIChjbXApIGdvdG8gbm9ybWFsaXplOworICAgIGNtcCA9IGNvLT5jb19maXJzdGxpbmVubyAtIGNwLT5jb19maXJzdGxpbmVubzsKKyAgICBpZiAoY21wKSBnb3RvIG5vcm1hbGl6ZTsKKyAgICBjbXAgPSBQeU9iamVjdF9Db21wYXJlKGNvLT5jb19jb2RlLCBjcC0+Y29fY29kZSk7CisgICAgaWYgKGNtcCkgcmV0dXJuIGNtcDsKKyAgICBjbXAgPSBQeU9iamVjdF9Db21wYXJlKGNvLT5jb19jb25zdHMsIGNwLT5jb19jb25zdHMpOworICAgIGlmIChjbXApIHJldHVybiBjbXA7CisgICAgY21wID0gUHlPYmplY3RfQ29tcGFyZShjby0+Y29fbmFtZXMsIGNwLT5jb19uYW1lcyk7CisgICAgaWYgKGNtcCkgcmV0dXJuIGNtcDsKKyAgICBjbXAgPSBQeU9iamVjdF9Db21wYXJlKGNvLT5jb192YXJuYW1lcywgY3AtPmNvX3Zhcm5hbWVzKTsKKyAgICBpZiAoY21wKSByZXR1cm4gY21wOworICAgIGNtcCA9IFB5T2JqZWN0X0NvbXBhcmUoY28tPmNvX2ZyZWV2YXJzLCBjcC0+Y29fZnJlZXZhcnMpOworICAgIGlmIChjbXApIHJldHVybiBjbXA7CisgICAgY21wID0gUHlPYmplY3RfQ29tcGFyZShjby0+Y29fY2VsbHZhcnMsIGNwLT5jb19jZWxsdmFycyk7CisgICAgcmV0dXJuIGNtcDsKKworIG5vcm1hbGl6ZToKKyAgICBpZiAoY21wID4gMCkKKyAgICAgICAgcmV0dXJuIDE7CisgICAgZWxzZSBpZiAoY21wIDwgMCkKKyAgICAgICAgcmV0dXJuIC0xOworICAgIGVsc2UKKyAgICAgICAgcmV0dXJuIDA7Cit9CisKK3N0YXRpYyBQeU9iamVjdCAqCitjb2RlX3JpY2hjb21wYXJlKFB5T2JqZWN0ICpzZWxmLCBQeU9iamVjdCAqb3RoZXIsIGludCBvcCkKK3sKKyAgICBQeUNvZGVPYmplY3QgKmNvLCAqY3A7CisgICAgaW50IGVxOworICAgIFB5T2JqZWN0ICpyZXM7CisKKyAgICBpZiAoKG9wICE9IFB5X0VRICYmIG9wICE9IFB5X05FKSB8fAorICAgICAgICAhUHlDb2RlX0NoZWNrKHNlbGYpIHx8CisgICAgICAgICFQeUNvZGVfQ2hlY2sob3RoZXIpKSB7CisKKyAgICAgICAgLyogUHkzSyB3YXJuaW5nIGlmIHR5cGVzIGFyZSBub3QgZXF1YWwgYW5kIGNvbXBhcmlzb24KKyAgICAgICAgaXNuJ3QgPT0gb3IgIT0gICovCisgICAgICAgIGlmIChQeUVycl9XYXJuUHkzaygiY29kZSBpbmVxdWFsaXR5IGNvbXBhcmlzb25zIG5vdCBzdXBwb3J0ZWQgIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgImluIDMueCIsIDEpIDwgMCkgeworICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgICAgIH0KKworICAgICAgICBQeV9JTkNSRUYoUHlfTm90SW1wbGVtZW50ZWQpOworICAgICAgICByZXR1cm4gUHlfTm90SW1wbGVtZW50ZWQ7CisgICAgfQorCisgICAgY28gPSAoUHlDb2RlT2JqZWN0ICopc2VsZjsKKyAgICBjcCA9IChQeUNvZGVPYmplY3QgKilvdGhlcjsKKworICAgIGVxID0gUHlPYmplY3RfUmljaENvbXBhcmVCb29sKGNvLT5jb19uYW1lLCBjcC0+Y29fbmFtZSwgUHlfRVEpOworICAgIGlmIChlcSA8PSAwKSBnb3RvIHVuZXF1YWw7CisgICAgZXEgPSBjby0+Y29fYXJnY291bnQgPT0gY3AtPmNvX2FyZ2NvdW50OworICAgIGlmICghZXEpIGdvdG8gdW5lcXVhbDsKKyAgICBlcSA9IGNvLT5jb19ubG9jYWxzID09IGNwLT5jb19ubG9jYWxzOworICAgIGlmICghZXEpIGdvdG8gdW5lcXVhbDsKKyAgICBlcSA9IGNvLT5jb19mbGFncyA9PSBjcC0+Y29fZmxhZ3M7CisgICAgaWYgKCFlcSkgZ290byB1bmVxdWFsOworICAgIGVxID0gY28tPmNvX2ZpcnN0bGluZW5vID09IGNwLT5jb19maXJzdGxpbmVubzsKKyAgICBpZiAoIWVxKSBnb3RvIHVuZXF1YWw7CisgICAgZXEgPSBQeU9iamVjdF9SaWNoQ29tcGFyZUJvb2woY28tPmNvX2NvZGUsIGNwLT5jb19jb2RlLCBQeV9FUSk7CisgICAgaWYgKGVxIDw9IDApIGdvdG8gdW5lcXVhbDsKKyAgICBlcSA9IFB5T2JqZWN0X1JpY2hDb21wYXJlQm9vbChjby0+Y29fY29uc3RzLCBjcC0+Y29fY29uc3RzLCBQeV9FUSk7CisgICAgaWYgKGVxIDw9IDApIGdvdG8gdW5lcXVhbDsKKyAgICBlcSA9IFB5T2JqZWN0X1JpY2hDb21wYXJlQm9vbChjby0+Y29fbmFtZXMsIGNwLT5jb19uYW1lcywgUHlfRVEpOworICAgIGlmIChlcSA8PSAwKSBnb3RvIHVuZXF1YWw7CisgICAgZXEgPSBQeU9iamVjdF9SaWNoQ29tcGFyZUJvb2woY28tPmNvX3Zhcm5hbWVzLCBjcC0+Y29fdmFybmFtZXMsIFB5X0VRKTsKKyAgICBpZiAoZXEgPD0gMCkgZ290byB1bmVxdWFsOworICAgIGVxID0gUHlPYmplY3RfUmljaENvbXBhcmVCb29sKGNvLT5jb19mcmVldmFycywgY3AtPmNvX2ZyZWV2YXJzLCBQeV9FUSk7CisgICAgaWYgKGVxIDw9IDApIGdvdG8gdW5lcXVhbDsKKyAgICBlcSA9IFB5T2JqZWN0X1JpY2hDb21wYXJlQm9vbChjby0+Y29fY2VsbHZhcnMsIGNwLT5jb19jZWxsdmFycywgUHlfRVEpOworICAgIGlmIChlcSA8PSAwKSBnb3RvIHVuZXF1YWw7CisKKyAgICBpZiAob3AgPT0gUHlfRVEpCisgICAgICAgIHJlcyA9IFB5X1RydWU7CisgICAgZWxzZQorICAgICAgICByZXMgPSBQeV9GYWxzZTsKKyAgICBnb3RvIGRvbmU7CisKKyAgdW5lcXVhbDoKKyAgICBpZiAoZXEgPCAwKQorICAgICAgICByZXR1cm4gTlVMTDsKKyAgICBpZiAob3AgPT0gUHlfTkUpCisgICAgICAgIHJlcyA9IFB5X1RydWU7CisgICAgZWxzZQorICAgICAgICByZXMgPSBQeV9GYWxzZTsKKworICBkb25lOgorICAgIFB5X0lOQ1JFRihyZXMpOworICAgIHJldHVybiByZXM7Cit9CisKK3N0YXRpYyBsb25nCitjb2RlX2hhc2goUHlDb2RlT2JqZWN0ICpjbykKK3sKKyAgICBsb25nIGgsIGgwLCBoMSwgaDIsIGgzLCBoNCwgaDUsIGg2OworICAgIGgwID0gUHlPYmplY3RfSGFzaChjby0+Y29fbmFtZSk7CisgICAgaWYgKGgwID09IC0xKSByZXR1cm4gLTE7CisgICAgaDEgPSBQeU9iamVjdF9IYXNoKGNvLT5jb19jb2RlKTsKKyAgICBpZiAoaDEgPT0gLTEpIHJldHVybiAtMTsKKyAgICBoMiA9IFB5T2JqZWN0X0hhc2goY28tPmNvX2NvbnN0cyk7CisgICAgaWYgKGgyID09IC0xKSByZXR1cm4gLTE7CisgICAgaDMgPSBQeU9iamVjdF9IYXNoKGNvLT5jb19uYW1lcyk7CisgICAgaWYgKGgzID09IC0xKSByZXR1cm4gLTE7CisgICAgaDQgPSBQeU9iamVjdF9IYXNoKGNvLT5jb192YXJuYW1lcyk7CisgICAgaWYgKGg0ID09IC0xKSByZXR1cm4gLTE7CisgICAgaDUgPSBQeU9iamVjdF9IYXNoKGNvLT5jb19mcmVldmFycyk7CisgICAgaWYgKGg1ID09IC0xKSByZXR1cm4gLTE7CisgICAgaDYgPSBQeU9iamVjdF9IYXNoKGNvLT5jb19jZWxsdmFycyk7CisgICAgaWYgKGg2ID09IC0xKSByZXR1cm4gLTE7CisgICAgaCA9IGgwIF4gaDEgXiBoMiBeIGgzIF4gaDQgXiBoNSBeIGg2IF4KKyAgICAgICAgY28tPmNvX2FyZ2NvdW50IF4gY28tPmNvX25sb2NhbHMgXiBjby0+Y29fZmxhZ3M7CisgICAgaWYgKGggPT0gLTEpIGggPSAtMjsKKyAgICByZXR1cm4gaDsKK30KKworLyogWFhYIGNvZGUgb2JqZWN0cyBuZWVkIHRvIHBhcnRpY2lwYXRlIGluIEdDPyAqLworCitQeVR5cGVPYmplY3QgUHlDb2RlX1R5cGUgPSB7CisgICAgUHlWYXJPYmplY3RfSEVBRF9JTklUKCZQeVR5cGVfVHlwZSwgMCkKKyAgICAiY29kZSIsCisgICAgc2l6ZW9mKFB5Q29kZU9iamVjdCksCisgICAgMCwKKyAgICAoZGVzdHJ1Y3Rvciljb2RlX2RlYWxsb2MsICAgICAgICAgICAvKiB0cF9kZWFsbG9jICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfcHJpbnQgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9nZXRhdHRyICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfc2V0YXR0ciAqLworICAgIChjbXBmdW5jKWNvZGVfY29tcGFyZSwgICAgICAgICAgICAgIC8qIHRwX2NvbXBhcmUgKi8KKyAgICAocmVwcmZ1bmMpY29kZV9yZXByLCAgICAgICAgICAgICAgICAvKiB0cF9yZXByICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfYXNfbnVtYmVyICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfYXNfc2VxdWVuY2UgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9hc19tYXBwaW5nICovCisgICAgKGhhc2hmdW5jKWNvZGVfaGFzaCwgICAgICAgICAgICAgICAgLyogdHBfaGFzaCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2NhbGwgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9zdHIgKi8KKyAgICBQeU9iamVjdF9HZW5lcmljR2V0QXR0ciwgICAgICAgICAgICAvKiB0cF9nZXRhdHRybyAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3NldGF0dHJvICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfYXNfYnVmZmVyICovCisgICAgUHlfVFBGTEFHU19ERUZBVUxULCAgICAgICAgICAgICAgICAgLyogdHBfZmxhZ3MgKi8KKyAgICBjb2RlX2RvYywgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9kb2MgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF90cmF2ZXJzZSAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2NsZWFyICovCisgICAgY29kZV9yaWNoY29tcGFyZSwgICAgICAgICAgICAgICAgICAgLyogdHBfcmljaGNvbXBhcmUgKi8KKyAgICBvZmZzZXRvZihQeUNvZGVPYmplY3QsIGNvX3dlYWtyZWZsaXN0KSwgLyogdHBfd2Vha2xpc3RvZmZzZXQgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9pdGVyICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfaXRlcm5leHQgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9tZXRob2RzICovCisgICAgY29kZV9tZW1iZXJsaXN0LCAgICAgICAgICAgICAgICAgICAgLyogdHBfbWVtYmVycyAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2dldHNldCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2Jhc2UgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9kaWN0ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZGVzY3JfZ2V0ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZGVzY3Jfc2V0ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZGljdG9mZnNldCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2luaXQgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9hbGxvYyAqLworICAgIGNvZGVfbmV3LCAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX25ldyAqLworfTsKKworLyogVXNlIGNvX2xub3RhYiB0byBjb21wdXRlIHRoZSBsaW5lIG51bWJlciBmcm9tIGEgYnl0ZWNvZGUgaW5kZXgsIGFkZHJxLiAgU2VlCisgICBsbm90YWJfbm90ZXMudHh0IGZvciB0aGUgZGV0YWlscyBvZiB0aGUgbG5vdGFiIHJlcHJlc2VudGF0aW9uLgorKi8KKworaW50CitQeUNvZGVfQWRkcjJMaW5lKFB5Q29kZU9iamVjdCAqY28sIGludCBhZGRycSkKK3sKKyAgICBpbnQgc2l6ZSA9IFB5U3RyaW5nX1NpemUoY28tPmNvX2xub3RhYikgLyAyOworICAgIHVuc2lnbmVkIGNoYXIgKnAgPSAodW5zaWduZWQgY2hhciopUHlTdHJpbmdfQXNTdHJpbmcoY28tPmNvX2xub3RhYik7CisgICAgaW50IGxpbmUgPSBjby0+Y29fZmlyc3RsaW5lbm87CisgICAgaW50IGFkZHIgPSAwOworICAgIHdoaWxlICgtLXNpemUgPj0gMCkgeworICAgICAgICBhZGRyICs9ICpwKys7CisgICAgICAgIGlmIChhZGRyID4gYWRkcnEpCisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgbGluZSArPSAqcCsrOworICAgIH0KKyAgICByZXR1cm4gbGluZTsKK30KKworLyogVXBkYXRlICpib3VuZHMgdG8gZGVzY3JpYmUgdGhlIGZpcnN0IGFuZCBvbmUtcGFzdC10aGUtbGFzdCBpbnN0cnVjdGlvbnMgaW4KKyAgIHRoZSBzYW1lIGxpbmUgYXMgbGFzdGkuICBSZXR1cm4gdGhlIG51bWJlciBvZiB0aGF0IGxpbmUuICovCitpbnQKK19QeUNvZGVfQ2hlY2tMaW5lTnVtYmVyKFB5Q29kZU9iamVjdCogY28sIGludCBsYXN0aSwgUHlBZGRyUGFpciAqYm91bmRzKQoreworICAgIGludCBzaXplLCBhZGRyLCBsaW5lOworICAgIHVuc2lnbmVkIGNoYXIqIHA7CisKKyAgICBwID0gKHVuc2lnbmVkIGNoYXIqKVB5U3RyaW5nX0FTX1NUUklORyhjby0+Y29fbG5vdGFiKTsKKyAgICBzaXplID0gUHlTdHJpbmdfR0VUX1NJWkUoY28tPmNvX2xub3RhYikgLyAyOworCisgICAgYWRkciA9IDA7CisgICAgbGluZSA9IGNvLT5jb19maXJzdGxpbmVubzsKKyAgICBhc3NlcnQobGluZSA+IDApOworCisgICAgLyogcG9zc2libGUgb3B0aW1pemF0aW9uOiBpZiBmLT5mX2xhc3RpID09IGluc3RyX3ViCisgICAgICAgKGxpa2VseSB0byBiZSBhIGNvbW1vbiBjYXNlKSB0aGVuIHdlIGFscmVhZHkga25vdworICAgICAgIGluc3RyX2xiIC0tIGlmIHdlIHN0b3JlZCB0aGUgbWF0Y2hpbmcgdmFsdWUgb2YgcAorICAgICAgIHNvbXdoZXJlIHdlIGNvdWxkIHNraXAgdGhlIGZpcnN0IHdoaWxlIGxvb3AuICovCisKKyAgICAvKiBTZWUgbG5vdGFiX25vdGVzLnR4dCBmb3IgdGhlIGRlc2NyaXB0aW9uIG9mCisgICAgICAgY29fbG5vdGFiLiAgQSBwb2ludCB0byByZW1lbWJlcjogaW5jcmVtZW50cyB0byBwCisgICAgICAgY29tZSBpbiAoYWRkciwgbGluZSkgcGFpcnMuICovCisKKyAgICBib3VuZHMtPmFwX2xvd2VyID0gMDsKKyAgICB3aGlsZSAoc2l6ZSA+IDApIHsKKyAgICAgICAgaWYgKGFkZHIgKyAqcCA+IGxhc3RpKQorICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIGFkZHIgKz0gKnArKzsKKyAgICAgICAgaWYgKCpwKQorICAgICAgICAgICAgYm91bmRzLT5hcF9sb3dlciA9IGFkZHI7CisgICAgICAgIGxpbmUgKz0gKnArKzsKKyAgICAgICAgLS1zaXplOworICAgIH0KKworICAgIGlmIChzaXplID4gMCkgeworICAgICAgICB3aGlsZSAoLS1zaXplID49IDApIHsKKyAgICAgICAgICAgIGFkZHIgKz0gKnArKzsKKyAgICAgICAgICAgIGlmICgqcCsrKQorICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisgICAgICAgIGJvdW5kcy0+YXBfdXBwZXIgPSBhZGRyOworICAgIH0KKyAgICBlbHNlIHsKKyAgICAgICAgYm91bmRzLT5hcF91cHBlciA9IElOVF9NQVg7CisgICAgfQorCisgICAgcmV0dXJuIGxpbmU7Cit9CmRpZmYgLS1naXQgYS9QeXRob24tMi43LjUvT2JqZWN0cy9jb21wbGV4b2JqZWN0LmMgYi9QeXRob24tMi43LjUvT2JqZWN0cy9jb21wbGV4b2JqZWN0LmMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNjc3YWMwZQotLS0gL2Rldi9udWxsCisrKyBiL1B5dGhvbi0yLjcuNS9PYmplY3RzL2NvbXBsZXhvYmplY3QuYwpAQCAtMCwwICsxLDEzNTMgQEAKKworLyogQ29tcGxleCBvYmplY3QgaW1wbGVtZW50YXRpb24gKi8KKworLyogQm9ycm93cyBoZWF2aWx5IGZyb20gZmxvYXRvYmplY3QuYyAqLworCisvKiBTdWJtaXR0ZWQgYnkgSmltIEh1Z3VuaW4gKi8KKworI2luY2x1ZGUgIlB5dGhvbi5oIgorI2luY2x1ZGUgInN0cnVjdG1lbWJlci5oIgorCisjaWZuZGVmIFdJVEhPVVRfQ09NUExFWAorCisvKiBQcmVjaXNpb25zIHVzZWQgYnkgcmVwcigpIGFuZCBzdHIoKSwgcmVzcGVjdGl2ZWx5LgorCisgICBUaGUgcmVwcigpIHByZWNpc2lvbiAoMTcgc2lnbmlmaWNhbnQgZGVjaW1hbCBkaWdpdHMpIGlzIHRoZSBtaW5pbWFsIG51bWJlcgorICAgdGhhdCBpcyBndWFyYW50ZWVkIHRvIGhhdmUgZW5vdWdoIHByZWNpc2lvbiBzbyB0aGF0IGlmIHRoZSBudW1iZXIgaXMgcmVhZAorICAgYmFjayBpbiB0aGUgZXhhY3Qgc2FtZSBiaW5hcnkgdmFsdWUgaXMgcmVjcmVhdGVkLiAgVGhpcyBpcyB0cnVlIGZvciBJRUVFCisgICBmbG9hdGluZyBwb2ludCBieSBkZXNpZ24sIGFuZCBhbHNvIGhhcHBlbnMgdG8gd29yayBmb3IgYWxsIG90aGVyIG1vZGVybgorICAgaGFyZHdhcmUuCisKKyAgIFRoZSBzdHIoKSBwcmVjaXNpb24gaXMgY2hvc2VuIHNvIHRoYXQgaW4gbW9zdCBjYXNlcywgdGhlIHJvdW5kaW5nIG5vaXNlCisgICBjcmVhdGVkIGJ5IHZhcmlvdXMgb3BlcmF0aW9ucyBpcyBzdXBwcmVzc2VkLCB3aGlsZSBnaXZpbmcgcGxlbnR5IG9mCisgICBwcmVjaXNpb24gZm9yIHByYWN0aWNhbCB1c2UuCisqLworCisjZGVmaW5lIFBSRUNfUkVQUiAgICAgICAxNworI2RlZmluZSBQUkVDX1NUUiAgICAgICAgMTIKKworLyogZWxlbWVudGFyeSBvcGVyYXRpb25zIG9uIGNvbXBsZXggbnVtYmVycyAqLworCitzdGF0aWMgUHlfY29tcGxleCBjXzEgPSB7MS4sIDAufTsKKworUHlfY29tcGxleAorY19zdW0oUHlfY29tcGxleCBhLCBQeV9jb21wbGV4IGIpCit7CisgICAgUHlfY29tcGxleCByOworICAgIHIucmVhbCA9IGEucmVhbCArIGIucmVhbDsKKyAgICByLmltYWcgPSBhLmltYWcgKyBiLmltYWc7CisgICAgcmV0dXJuIHI7Cit9CisKK1B5X2NvbXBsZXgKK2NfZGlmZihQeV9jb21wbGV4IGEsIFB5X2NvbXBsZXggYikKK3sKKyAgICBQeV9jb21wbGV4IHI7CisgICAgci5yZWFsID0gYS5yZWFsIC0gYi5yZWFsOworICAgIHIuaW1hZyA9IGEuaW1hZyAtIGIuaW1hZzsKKyAgICByZXR1cm4gcjsKK30KKworUHlfY29tcGxleAorY19uZWcoUHlfY29tcGxleCBhKQoreworICAgIFB5X2NvbXBsZXggcjsKKyAgICByLnJlYWwgPSAtYS5yZWFsOworICAgIHIuaW1hZyA9IC1hLmltYWc7CisgICAgcmV0dXJuIHI7Cit9CisKK1B5X2NvbXBsZXgKK2NfcHJvZChQeV9jb21wbGV4IGEsIFB5X2NvbXBsZXggYikKK3sKKyAgICBQeV9jb21wbGV4IHI7CisgICAgci5yZWFsID0gYS5yZWFsKmIucmVhbCAtIGEuaW1hZypiLmltYWc7CisgICAgci5pbWFnID0gYS5yZWFsKmIuaW1hZyArIGEuaW1hZypiLnJlYWw7CisgICAgcmV0dXJuIHI7Cit9CisKK1B5X2NvbXBsZXgKK2NfcXVvdChQeV9jb21wbGV4IGEsIFB5X2NvbXBsZXggYikKK3sKKyAgICAvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCisgICAgVGhpcyB3YXMgdGhlIG9yaWdpbmFsIGFsZ29yaXRobS4gIEl0J3MgZ3Jvc3NseSBwcm9uZSB0byBzcHVyaW91cworICAgIG92ZXJmbG93IGFuZCB1bmRlcmZsb3cgZXJyb3JzLiAgSXQgYWxzbyBtZXJyaWx5IGRpdmlkZXMgYnkgMCBkZXNwaXRlCisgICAgY2hlY2tpbmcgZm9yIHRoYXQoISkuICBUaGUgY29kZSBzdGlsbCBzZXJ2ZXMgYSBkb2MgcHVycG9zZSBoZXJlLCBhcworICAgIHRoZSBhbGdvcml0aG0gZm9sbG93aW5nIGlzIGEgc2ltcGxlIGJ5LWNhc2VzIHRyYW5zZm9ybWF0aW9uIG9mIHRoaXMKKyAgICBvbmU6CisKKyAgICBQeV9jb21wbGV4IHI7CisgICAgZG91YmxlIGQgPSBiLnJlYWwqYi5yZWFsICsgYi5pbWFnKmIuaW1hZzsKKyAgICBpZiAoZCA9PSAwLikKKyAgICAgICAgZXJybm8gPSBFRE9NOworICAgIHIucmVhbCA9IChhLnJlYWwqYi5yZWFsICsgYS5pbWFnKmIuaW1hZykvZDsKKyAgICByLmltYWcgPSAoYS5pbWFnKmIucmVhbCAtIGEucmVhbCpiLmltYWcpL2Q7CisgICAgcmV0dXJuIHI7CisgICAgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLworCisgICAgLyogVGhpcyBhbGdvcml0aG0gaXMgYmV0dGVyLCBhbmQgaXMgcHJldHR5IG9idmlvdXM6ICBmaXJzdCBkaXZpZGUgdGhlCisgICAgICogbnVtZXJhdG9ycyBhbmQgZGVub21pbmF0b3IgYnkgd2hpY2hldmVyIG9mIHtiLnJlYWwsIGIuaW1hZ30gaGFzCisgICAgICogbGFyZ2VyIG1hZ25pdHVkZS4gIFRoZSBlYXJsaWVzdCByZWZlcmVuY2UgSSBmb3VuZCB3YXMgdG8gQ0FDTQorICAgICAqIEFsZ29yaXRobSAxMTYgKENvbXBsZXggRGl2aXNpb24sIFJvYmVydCBMLiBTbWl0aCwgU3RhbmZvcmQKKyAgICAgKiBVbml2ZXJzaXR5KS4gIEFzIHVzdWFsLCB0aG91Z2gsIHdlJ3JlIHN0aWxsIGlnbm9yaW5nIGFsbCBJRUVFCisgICAgICogZW5kY2FzZXMuCisgICAgICovCisgICAgIFB5X2NvbXBsZXggcjsgICAgICAvKiB0aGUgcmVzdWx0ICovCisgICAgIGNvbnN0IGRvdWJsZSBhYnNfYnJlYWwgPSBiLnJlYWwgPCAwID8gLWIucmVhbCA6IGIucmVhbDsKKyAgICAgY29uc3QgZG91YmxlIGFic19iaW1hZyA9IGIuaW1hZyA8IDAgPyAtYi5pbWFnIDogYi5pbWFnOworCisgICAgIGlmIChhYnNfYnJlYWwgPj0gYWJzX2JpbWFnKSB7CisgICAgICAgIC8qIGRpdmlkZSB0b3BzIGFuZCBib3R0b20gYnkgYi5yZWFsICovCisgICAgICAgIGlmIChhYnNfYnJlYWwgPT0gMC4wKSB7CisgICAgICAgICAgICBlcnJubyA9IEVET007CisgICAgICAgICAgICByLnJlYWwgPSByLmltYWcgPSAwLjA7CisgICAgICAgIH0KKyAgICAgICAgZWxzZSB7CisgICAgICAgICAgICBjb25zdCBkb3VibGUgcmF0aW8gPSBiLmltYWcgLyBiLnJlYWw7CisgICAgICAgICAgICBjb25zdCBkb3VibGUgZGVub20gPSBiLnJlYWwgKyBiLmltYWcgKiByYXRpbzsKKyAgICAgICAgICAgIHIucmVhbCA9IChhLnJlYWwgKyBhLmltYWcgKiByYXRpbykgLyBkZW5vbTsKKyAgICAgICAgICAgIHIuaW1hZyA9IChhLmltYWcgLSBhLnJlYWwgKiByYXRpbykgLyBkZW5vbTsKKyAgICAgICAgfQorICAgIH0KKyAgICBlbHNlIHsKKyAgICAgICAgLyogZGl2aWRlIHRvcHMgYW5kIGJvdHRvbSBieSBiLmltYWcgKi8KKyAgICAgICAgY29uc3QgZG91YmxlIHJhdGlvID0gYi5yZWFsIC8gYi5pbWFnOworICAgICAgICBjb25zdCBkb3VibGUgZGVub20gPSBiLnJlYWwgKiByYXRpbyArIGIuaW1hZzsKKyAgICAgICAgYXNzZXJ0KGIuaW1hZyAhPSAwLjApOworICAgICAgICByLnJlYWwgPSAoYS5yZWFsICogcmF0aW8gKyBhLmltYWcpIC8gZGVub207CisgICAgICAgIHIuaW1hZyA9IChhLmltYWcgKiByYXRpbyAtIGEucmVhbCkgLyBkZW5vbTsKKyAgICB9CisgICAgcmV0dXJuIHI7Cit9CisKK1B5X2NvbXBsZXgKK2NfcG93KFB5X2NvbXBsZXggYSwgUHlfY29tcGxleCBiKQoreworICAgIFB5X2NvbXBsZXggcjsKKyAgICBkb3VibGUgdmFicyxsZW4sYXQscGhhc2U7CisgICAgaWYgKGIucmVhbCA9PSAwLiAmJiBiLmltYWcgPT0gMC4pIHsKKyAgICAgICAgci5yZWFsID0gMS47CisgICAgICAgIHIuaW1hZyA9IDAuOworICAgIH0KKyAgICBlbHNlIGlmIChhLnJlYWwgPT0gMC4gJiYgYS5pbWFnID09IDAuKSB7CisgICAgICAgIGlmIChiLmltYWcgIT0gMC4gfHwgYi5yZWFsIDwgMC4pCisgICAgICAgICAgICBlcnJubyA9IEVET007CisgICAgICAgIHIucmVhbCA9IDAuOworICAgICAgICByLmltYWcgPSAwLjsKKyAgICB9CisgICAgZWxzZSB7CisgICAgICAgIHZhYnMgPSBoeXBvdChhLnJlYWwsYS5pbWFnKTsKKyAgICAgICAgbGVuID0gcG93KHZhYnMsYi5yZWFsKTsKKyAgICAgICAgYXQgPSBhdGFuMihhLmltYWcsIGEucmVhbCk7CisgICAgICAgIHBoYXNlID0gYXQqYi5yZWFsOworICAgICAgICBpZiAoYi5pbWFnICE9IDAuMCkgeworICAgICAgICAgICAgbGVuIC89IGV4cChhdCpiLmltYWcpOworICAgICAgICAgICAgcGhhc2UgKz0gYi5pbWFnKmxvZyh2YWJzKTsKKyAgICAgICAgfQorICAgICAgICByLnJlYWwgPSBsZW4qY29zKHBoYXNlKTsKKyAgICAgICAgci5pbWFnID0gbGVuKnNpbihwaGFzZSk7CisgICAgfQorICAgIHJldHVybiByOworfQorCitzdGF0aWMgUHlfY29tcGxleAorY19wb3d1KFB5X2NvbXBsZXggeCwgbG9uZyBuKQoreworICAgIFB5X2NvbXBsZXggciwgcDsKKyAgICBsb25nIG1hc2sgPSAxOworICAgIHIgPSBjXzE7CisgICAgcCA9IHg7CisgICAgd2hpbGUgKG1hc2sgPiAwICYmIG4gPj0gbWFzaykgeworICAgICAgICBpZiAobiAmIG1hc2spCisgICAgICAgICAgICByID0gY19wcm9kKHIscCk7CisgICAgICAgIG1hc2sgPDw9IDE7CisgICAgICAgIHAgPSBjX3Byb2QocCxwKTsKKyAgICB9CisgICAgcmV0dXJuIHI7Cit9CisKK3N0YXRpYyBQeV9jb21wbGV4CitjX3Bvd2koUHlfY29tcGxleCB4LCBsb25nIG4pCit7CisgICAgUHlfY29tcGxleCBjbjsKKworICAgIGlmIChuID4gMTAwIHx8IG4gPCAtMTAwKSB7CisgICAgICAgIGNuLnJlYWwgPSAoZG91YmxlKSBuOworICAgICAgICBjbi5pbWFnID0gMC47CisgICAgICAgIHJldHVybiBjX3Bvdyh4LGNuKTsKKyAgICB9CisgICAgZWxzZSBpZiAobiA+IDApCisgICAgICAgIHJldHVybiBjX3Bvd3UoeCxuKTsKKyAgICBlbHNlCisgICAgICAgIHJldHVybiBjX3F1b3QoY18xLGNfcG93dSh4LC1uKSk7CisKK30KKworZG91YmxlCitjX2FicyhQeV9jb21wbGV4IHopCit7CisgICAgLyogc2V0cyBlcnJubyA9IEVSQU5HRSBvbiBvdmVyZmxvdzsgIG90aGVyd2lzZSBlcnJubyA9IDAgKi8KKyAgICBkb3VibGUgcmVzdWx0OworCisgICAgaWYgKCFQeV9JU19GSU5JVEUoei5yZWFsKSB8fCAhUHlfSVNfRklOSVRFKHouaW1hZykpIHsKKyAgICAgICAgLyogQzk5IHJ1bGVzOiBpZiBlaXRoZXIgdGhlIHJlYWwgb3IgdGhlIGltYWdpbmFyeSBwYXJ0IGlzIGFuCisgICAgICAgICAgIGluZmluaXR5LCByZXR1cm4gaW5maW5pdHksIGV2ZW4gaWYgdGhlIG90aGVyIHBhcnQgaXMgYQorICAgICAgICAgICBOYU4uICovCisgICAgICAgIGlmIChQeV9JU19JTkZJTklUWSh6LnJlYWwpKSB7CisgICAgICAgICAgICByZXN1bHQgPSBmYWJzKHoucmVhbCk7CisgICAgICAgICAgICBlcnJubyA9IDA7CisgICAgICAgICAgICByZXR1cm4gcmVzdWx0OworICAgICAgICB9CisgICAgICAgIGlmIChQeV9JU19JTkZJTklUWSh6LmltYWcpKSB7CisgICAgICAgICAgICByZXN1bHQgPSBmYWJzKHouaW1hZyk7CisgICAgICAgICAgICBlcnJubyA9IDA7CisgICAgICAgICAgICByZXR1cm4gcmVzdWx0OworICAgICAgICB9CisgICAgICAgIC8qIGVpdGhlciB0aGUgcmVhbCBvciBpbWFnaW5hcnkgcGFydCBpcyBhIE5hTiwKKyAgICAgICAgICAgYW5kIG5laXRoZXIgaXMgaW5maW5pdGUuIFJlc3VsdCBzaG91bGQgYmUgTmFOLiAqLworICAgICAgICByZXR1cm4gUHlfTkFOOworICAgIH0KKyAgICByZXN1bHQgPSBoeXBvdCh6LnJlYWwsIHouaW1hZyk7CisgICAgaWYgKCFQeV9JU19GSU5JVEUocmVzdWx0KSkKKyAgICAgICAgZXJybm8gPSBFUkFOR0U7CisgICAgZWxzZQorICAgICAgICBlcnJubyA9IDA7CisgICAgcmV0dXJuIHJlc3VsdDsKK30KKworc3RhdGljIFB5T2JqZWN0ICoKK2NvbXBsZXhfc3VidHlwZV9mcm9tX2NfY29tcGxleChQeVR5cGVPYmplY3QgKnR5cGUsIFB5X2NvbXBsZXggY3ZhbCkKK3sKKyAgICBQeU9iamVjdCAqb3A7CisKKyAgICBvcCA9IHR5cGUtPnRwX2FsbG9jKHR5cGUsIDApOworICAgIGlmIChvcCAhPSBOVUxMKQorICAgICAgICAoKFB5Q29tcGxleE9iamVjdCAqKW9wKS0+Y3ZhbCA9IGN2YWw7CisgICAgcmV0dXJuIG9wOworfQorCitQeU9iamVjdCAqCitQeUNvbXBsZXhfRnJvbUNDb21wbGV4KFB5X2NvbXBsZXggY3ZhbCkKK3sKKyAgICByZWdpc3RlciBQeUNvbXBsZXhPYmplY3QgKm9wOworCisgICAgLyogSW5saW5lIFB5T2JqZWN0X05ldyAqLworICAgIG9wID0gKFB5Q29tcGxleE9iamVjdCAqKSBQeU9iamVjdF9NQUxMT0Moc2l6ZW9mKFB5Q29tcGxleE9iamVjdCkpOworICAgIGlmIChvcCA9PSBOVUxMKQorICAgICAgICByZXR1cm4gUHlFcnJfTm9NZW1vcnkoKTsKKyAgICBQeU9iamVjdF9JTklUKG9wLCAmUHlDb21wbGV4X1R5cGUpOworICAgIG9wLT5jdmFsID0gY3ZhbDsKKyAgICByZXR1cm4gKFB5T2JqZWN0ICopIG9wOworfQorCitzdGF0aWMgUHlPYmplY3QgKgorY29tcGxleF9zdWJ0eXBlX2Zyb21fZG91YmxlcyhQeVR5cGVPYmplY3QgKnR5cGUsIGRvdWJsZSByZWFsLCBkb3VibGUgaW1hZykKK3sKKyAgICBQeV9jb21wbGV4IGM7CisgICAgYy5yZWFsID0gcmVhbDsKKyAgICBjLmltYWcgPSBpbWFnOworICAgIHJldHVybiBjb21wbGV4X3N1YnR5cGVfZnJvbV9jX2NvbXBsZXgodHlwZSwgYyk7Cit9CisKK1B5T2JqZWN0ICoKK1B5Q29tcGxleF9Gcm9tRG91Ymxlcyhkb3VibGUgcmVhbCwgZG91YmxlIGltYWcpCit7CisgICAgUHlfY29tcGxleCBjOworICAgIGMucmVhbCA9IHJlYWw7CisgICAgYy5pbWFnID0gaW1hZzsKKyAgICByZXR1cm4gUHlDb21wbGV4X0Zyb21DQ29tcGxleChjKTsKK30KKworZG91YmxlCitQeUNvbXBsZXhfUmVhbEFzRG91YmxlKFB5T2JqZWN0ICpvcCkKK3sKKyAgICBpZiAoUHlDb21wbGV4X0NoZWNrKG9wKSkgeworICAgICAgICByZXR1cm4gKChQeUNvbXBsZXhPYmplY3QgKilvcCktPmN2YWwucmVhbDsKKyAgICB9CisgICAgZWxzZSB7CisgICAgICAgIHJldHVybiBQeUZsb2F0X0FzRG91YmxlKG9wKTsKKyAgICB9Cit9CisKK2RvdWJsZQorUHlDb21wbGV4X0ltYWdBc0RvdWJsZShQeU9iamVjdCAqb3ApCit7CisgICAgaWYgKFB5Q29tcGxleF9DaGVjayhvcCkpIHsKKyAgICAgICAgcmV0dXJuICgoUHlDb21wbGV4T2JqZWN0ICopb3ApLT5jdmFsLmltYWc7CisgICAgfQorICAgIGVsc2UgeworICAgICAgICByZXR1cm4gMC4wOworICAgIH0KK30KKworc3RhdGljIFB5T2JqZWN0ICoKK3RyeV9jb21wbGV4X3NwZWNpYWxfbWV0aG9kKFB5T2JqZWN0ICpvcCkgeworICAgIFB5T2JqZWN0ICpmOworICAgIHN0YXRpYyBQeU9iamVjdCAqY29tcGxleHN0cjsKKworICAgIGlmIChjb21wbGV4c3RyID09IE5VTEwpIHsKKyAgICAgICAgY29tcGxleHN0ciA9IFB5U3RyaW5nX0ludGVybkZyb21TdHJpbmcoIl9fY29tcGxleF9fIik7CisgICAgICAgIGlmIChjb21wbGV4c3RyID09IE5VTEwpCisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgaWYgKFB5SW5zdGFuY2VfQ2hlY2sob3ApKSB7CisgICAgICAgIGYgPSBQeU9iamVjdF9HZXRBdHRyKG9wLCBjb21wbGV4c3RyKTsKKyAgICAgICAgaWYgKGYgPT0gTlVMTCkgeworICAgICAgICAgICAgaWYgKFB5RXJyX0V4Y2VwdGlvbk1hdGNoZXMoUHlFeGNfQXR0cmlidXRlRXJyb3IpKQorICAgICAgICAgICAgICAgIFB5RXJyX0NsZWFyKCk7CisgICAgICAgICAgICBlbHNlCisgICAgICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgICAgIH0KKyAgICB9CisgICAgZWxzZSB7CisgICAgICAgIGYgPSBfUHlPYmplY3RfTG9va3VwU3BlY2lhbChvcCwgIl9fY29tcGxleF9fIiwgJmNvbXBsZXhzdHIpOworICAgICAgICBpZiAoZiA9PSBOVUxMICYmIFB5RXJyX09jY3VycmVkKCkpCisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgaWYgKGYgIT0gTlVMTCkgeworICAgICAgICBQeU9iamVjdCAqcmVzID0gUHlPYmplY3RfQ2FsbEZ1bmN0aW9uT2JqQXJncyhmLCBOVUxMKTsKKyAgICAgICAgUHlfREVDUkVGKGYpOworICAgICAgICByZXR1cm4gcmVzOworICAgIH0KKyAgICByZXR1cm4gTlVMTDsKK30KKworUHlfY29tcGxleAorUHlDb21wbGV4X0FzQ0NvbXBsZXgoUHlPYmplY3QgKm9wKQoreworICAgIFB5X2NvbXBsZXggY3Y7CisgICAgUHlPYmplY3QgKm5ld29wID0gTlVMTDsKKworICAgIGFzc2VydChvcCk7CisgICAgLyogSWYgb3AgaXMgYWxyZWFkeSBvZiB0eXBlIFB5Q29tcGxleF9UeXBlLCByZXR1cm4gaXRzIHZhbHVlICovCisgICAgaWYgKFB5Q29tcGxleF9DaGVjayhvcCkpIHsKKyAgICAgICAgcmV0dXJuICgoUHlDb21wbGV4T2JqZWN0ICopb3ApLT5jdmFsOworICAgIH0KKyAgICAvKiBJZiBub3QsIHVzZSBvcCdzIF9fY29tcGxleF9fICBtZXRob2QsIGlmIGl0IGV4aXN0cyAqLworCisgICAgLyogcmV0dXJuIC0xIG9uIGZhaWx1cmUgKi8KKyAgICBjdi5yZWFsID0gLTEuOworICAgIGN2LmltYWcgPSAwLjsKKworICAgIG5ld29wID0gdHJ5X2NvbXBsZXhfc3BlY2lhbF9tZXRob2Qob3ApOworCisgICAgaWYgKG5ld29wKSB7CisgICAgICAgIGlmICghUHlDb21wbGV4X0NoZWNrKG5ld29wKSkgeworICAgICAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1R5cGVFcnJvciwKKyAgICAgICAgICAgICAgICAiX19jb21wbGV4X18gc2hvdWxkIHJldHVybiBhIGNvbXBsZXggb2JqZWN0Iik7CisgICAgICAgICAgICBQeV9ERUNSRUYobmV3b3ApOworICAgICAgICAgICAgcmV0dXJuIGN2OworICAgICAgICB9CisgICAgICAgIGN2ID0gKChQeUNvbXBsZXhPYmplY3QgKiluZXdvcCktPmN2YWw7CisgICAgICAgIFB5X0RFQ1JFRihuZXdvcCk7CisgICAgICAgIHJldHVybiBjdjsKKyAgICB9CisgICAgZWxzZSBpZiAoUHlFcnJfT2NjdXJyZWQoKSkgeworICAgICAgICByZXR1cm4gY3Y7CisgICAgfQorICAgIC8qIElmIG5laXRoZXIgb2YgdGhlIGFib3ZlIHdvcmtzLCBpbnRlcnByZXQgb3AgYXMgYSBmbG9hdCBnaXZpbmcgdGhlCisgICAgICAgcmVhbCBwYXJ0IG9mIHRoZSByZXN1bHQsIGFuZCBmaWxsIGluIHRoZSBpbWFnaW5hcnkgcGFydCBhcyAwLiAqLworICAgIGVsc2UgeworICAgICAgICAvKiBQeUZsb2F0X0FzRG91YmxlIHdpbGwgcmV0dXJuIC0xIG9uIGZhaWx1cmUgKi8KKyAgICAgICAgY3YucmVhbCA9IFB5RmxvYXRfQXNEb3VibGUob3ApOworICAgICAgICByZXR1cm4gY3Y7CisgICAgfQorfQorCitzdGF0aWMgdm9pZAorY29tcGxleF9kZWFsbG9jKFB5T2JqZWN0ICpvcCkKK3sKKyAgICBvcC0+b2JfdHlwZS0+dHBfZnJlZShvcCk7Cit9CisKKworc3RhdGljIFB5T2JqZWN0ICoKK2NvbXBsZXhfZm9ybWF0KFB5Q29tcGxleE9iamVjdCAqdiwgaW50IHByZWNpc2lvbiwgY2hhciBmb3JtYXRfY29kZSkKK3sKKyAgICBQeU9iamVjdCAqcmVzdWx0ID0gTlVMTDsKKyAgICBQeV9zc2l6ZV90IGxlbjsKKworICAgIC8qIElmIHRoZXNlIGFyZSBub24tTlVMTCwgdGhleSdsbCBuZWVkIHRvIGJlIGZyZWVkLiAqLworICAgIGNoYXIgKnByZSA9IE5VTEw7CisgICAgY2hhciAqaW0gPSBOVUxMOworICAgIGNoYXIgKmJ1ZiA9IE5VTEw7CisKKyAgICAvKiBUaGVzZSBkbyBub3QgbmVlZCB0byBiZSBmcmVlZC4gcmUgaXMgZWl0aGVyIGFuIGFsaWFzCisgICAgICAgZm9yIHByZSBvciBhIHBvaW50ZXIgdG8gYSBjb25zdGFudC4gIGxlYWQgYW5kIHRhaWwKKyAgICAgICBhcmUgcG9pbnRlcnMgdG8gY29uc3RhbnRzLiAqLworICAgIGNoYXIgKnJlID0gTlVMTDsKKyAgICBjaGFyICpsZWFkID0gIiI7CisgICAgY2hhciAqdGFpbCA9ICIiOworCisgICAgaWYgKHYtPmN2YWwucmVhbCA9PSAwLiAmJiBjb3B5c2lnbigxLjAsIHYtPmN2YWwucmVhbCk9PTEuMCkgeworICAgICAgICByZSA9ICIiOworICAgICAgICBpbSA9IFB5T1NfZG91YmxlX3RvX3N0cmluZyh2LT5jdmFsLmltYWcsIGZvcm1hdF9jb2RlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcmVjaXNpb24sIDAsIE5VTEwpOworICAgICAgICBpZiAoIWltKSB7CisgICAgICAgICAgICBQeUVycl9Ob01lbW9yeSgpOworICAgICAgICAgICAgZ290byBkb25lOworICAgICAgICB9CisgICAgfSBlbHNlIHsKKyAgICAgICAgLyogRm9ybWF0IGltYWdpbmFyeSBwYXJ0IHdpdGggc2lnbiwgcmVhbCBwYXJ0IHdpdGhvdXQgKi8KKyAgICAgICAgcHJlID0gUHlPU19kb3VibGVfdG9fc3RyaW5nKHYtPmN2YWwucmVhbCwgZm9ybWF0X2NvZGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcmVjaXNpb24sIDAsIE5VTEwpOworICAgICAgICBpZiAoIXByZSkgeworICAgICAgICAgICAgUHlFcnJfTm9NZW1vcnkoKTsKKyAgICAgICAgICAgIGdvdG8gZG9uZTsKKyAgICAgICAgfQorICAgICAgICByZSA9IHByZTsKKworICAgICAgICBpbSA9IFB5T1NfZG91YmxlX3RvX3N0cmluZyh2LT5jdmFsLmltYWcsIGZvcm1hdF9jb2RlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcmVjaXNpb24sIFB5X0RUU0ZfU0lHTiwgTlVMTCk7CisgICAgICAgIGlmICghaW0pIHsKKyAgICAgICAgICAgIFB5RXJyX05vTWVtb3J5KCk7CisgICAgICAgICAgICBnb3RvIGRvbmU7CisgICAgICAgIH0KKyAgICAgICAgbGVhZCA9ICIoIjsKKyAgICAgICAgdGFpbCA9ICIpIjsKKyAgICB9CisgICAgLyogQWxsb2MgdGhlIGZpbmFsIGJ1ZmZlci4gQWRkIG9uZSBmb3IgdGhlICJqIiBpbiB0aGUgZm9ybWF0IHN0cmluZywKKyAgICAgICBhbmQgb25lIGZvciB0aGUgdHJhaWxpbmcgemVyby4gKi8KKyAgICBsZW4gPSBzdHJsZW4obGVhZCkgKyBzdHJsZW4ocmUpICsgc3RybGVuKGltKSArIHN0cmxlbih0YWlsKSArIDI7CisgICAgYnVmID0gUHlNZW1fTWFsbG9jKGxlbik7CisgICAgaWYgKCFidWYpIHsKKyAgICAgICAgUHlFcnJfTm9NZW1vcnkoKTsKKyAgICAgICAgZ290byBkb25lOworICAgIH0KKyAgICBQeU9TX3NucHJpbnRmKGJ1ZiwgbGVuLCAiJXMlcyVzaiVzIiwgbGVhZCwgcmUsIGltLCB0YWlsKTsKKyAgICByZXN1bHQgPSBQeVN0cmluZ19Gcm9tU3RyaW5nKGJ1Zik7CisgIGRvbmU6CisgICAgUHlNZW1fRnJlZShpbSk7CisgICAgUHlNZW1fRnJlZShwcmUpOworICAgIFB5TWVtX0ZyZWUoYnVmKTsKKworICAgIHJldHVybiByZXN1bHQ7Cit9CisKK3N0YXRpYyBpbnQKK2NvbXBsZXhfcHJpbnQoUHlDb21wbGV4T2JqZWN0ICp2LCBGSUxFICpmcCwgaW50IGZsYWdzKQoreworICAgIFB5T2JqZWN0ICpmb3JtYXR2OworICAgIGNoYXIgKmJ1ZjsKKyAgICBpZiAoZmxhZ3MgJiBQeV9QUklOVF9SQVcpCisgICAgICAgIGZvcm1hdHYgPSBjb21wbGV4X2Zvcm1hdCh2LCBQeUZsb2F0X1NUUl9QUkVDSVNJT04sICdnJyk7CisgICAgZWxzZQorICAgICAgICBmb3JtYXR2ID0gY29tcGxleF9mb3JtYXQodiwgMCwgJ3InKTsKKyAgICBpZiAoZm9ybWF0diA9PSBOVUxMKQorICAgICAgICByZXR1cm4gLTE7CisgICAgYnVmID0gUHlTdHJpbmdfQVNfU1RSSU5HKGZvcm1hdHYpOworICAgIFB5X0JFR0lOX0FMTE9XX1RIUkVBRFMKKyAgICBmcHV0cyhidWYsIGZwKTsKKyAgICBQeV9FTkRfQUxMT1dfVEhSRUFEUworICAgIFB5X0RFQ1JFRihmb3JtYXR2KTsKKyAgICByZXR1cm4gMDsKK30KKworc3RhdGljIFB5T2JqZWN0ICoKK2NvbXBsZXhfcmVwcihQeUNvbXBsZXhPYmplY3QgKnYpCit7CisgICAgcmV0dXJuIGNvbXBsZXhfZm9ybWF0KHYsIDAsICdyJyk7Cit9CisKK3N0YXRpYyBQeU9iamVjdCAqCitjb21wbGV4X3N0cihQeUNvbXBsZXhPYmplY3QgKnYpCit7CisgICAgcmV0dXJuIGNvbXBsZXhfZm9ybWF0KHYsIFB5RmxvYXRfU1RSX1BSRUNJU0lPTiwgJ2cnKTsKK30KKworc3RhdGljIGxvbmcKK2NvbXBsZXhfaGFzaChQeUNvbXBsZXhPYmplY3QgKnYpCit7CisgICAgbG9uZyBoYXNocmVhbCwgaGFzaGltYWcsIGNvbWJpbmVkOworICAgIGhhc2hyZWFsID0gX1B5X0hhc2hEb3VibGUodi0+Y3ZhbC5yZWFsKTsKKyAgICBpZiAoaGFzaHJlYWwgPT0gLTEpCisgICAgICAgIHJldHVybiAtMTsKKyAgICBoYXNoaW1hZyA9IF9QeV9IYXNoRG91YmxlKHYtPmN2YWwuaW1hZyk7CisgICAgaWYgKGhhc2hpbWFnID09IC0xKQorICAgICAgICByZXR1cm4gLTE7CisgICAgLyogTm90ZTogIGlmIHRoZSBpbWFnaW5hcnkgcGFydCBpcyAwLCBoYXNoaW1hZyBpcyAwIG5vdywKKyAgICAgKiBzbyB0aGUgZm9sbG93aW5nIHJldHVybnMgaGFzaHJlYWwgdW5jaGFuZ2VkLiAgVGhpcyBpcworICAgICAqIGltcG9ydGFudCBiZWNhdXNlIG51bWJlcnMgb2YgZGlmZmVyZW50IHR5cGVzIHRoYXQKKyAgICAgKiBjb21wYXJlIGVxdWFsIG11c3QgaGF2ZSB0aGUgc2FtZSBoYXNoIHZhbHVlLCBzbyB0aGF0CisgICAgICogaGFzaCh4ICsgMCpqKSBtdXN0IGVxdWFsIGhhc2goeCkuCisgICAgICovCisgICAgY29tYmluZWQgPSBoYXNocmVhbCArIDEwMDAwMDMgKiBoYXNoaW1hZzsKKyAgICBpZiAoY29tYmluZWQgPT0gLTEpCisgICAgICAgIGNvbWJpbmVkID0gLTI7CisgICAgcmV0dXJuIGNvbWJpbmVkOworfQorCisvKiBUaGlzIG1hY3JvIG1heSByZXR1cm4hICovCisjZGVmaW5lIFRPX0NPTVBMRVgob2JqLCBjKSBcCisgICAgaWYgKFB5Q29tcGxleF9DaGVjayhvYmopKSBcCisgICAgICAgIGMgPSAoKFB5Q29tcGxleE9iamVjdCAqKShvYmopKS0+Y3ZhbDsgXAorICAgIGVsc2UgaWYgKHRvX2NvbXBsZXgoJihvYmopLCAmKGMpKSA8IDApIFwKKyAgICAgICAgcmV0dXJuIChvYmopCisKK3N0YXRpYyBpbnQKK3RvX2NvbXBsZXgoUHlPYmplY3QgKipwb2JqLCBQeV9jb21wbGV4ICpwYykKK3sKKyAgICBQeU9iamVjdCAqb2JqID0gKnBvYmo7CisKKyAgICBwYy0+cmVhbCA9IHBjLT5pbWFnID0gMC4wOworICAgIGlmIChQeUludF9DaGVjayhvYmopKSB7CisgICAgcGMtPnJlYWwgPSBQeUludF9BU19MT05HKG9iaik7CisgICAgcmV0dXJuIDA7CisgICAgfQorICAgIGlmIChQeUxvbmdfQ2hlY2sob2JqKSkgeworICAgIHBjLT5yZWFsID0gUHlMb25nX0FzRG91YmxlKG9iaik7CisgICAgaWYgKHBjLT5yZWFsID09IC0xLjAgJiYgUHlFcnJfT2NjdXJyZWQoKSkgeworICAgICAgICAqcG9iaiA9IE5VTEw7CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisgICAgcmV0dXJuIDA7CisgICAgfQorICAgIGlmIChQeUZsb2F0X0NoZWNrKG9iaikpIHsKKyAgICBwYy0+cmVhbCA9IFB5RmxvYXRfQXNEb3VibGUob2JqKTsKKyAgICByZXR1cm4gMDsKKyAgICB9CisgICAgUHlfSU5DUkVGKFB5X05vdEltcGxlbWVudGVkKTsKKyAgICAqcG9iaiA9IFB5X05vdEltcGxlbWVudGVkOworICAgIHJldHVybiAtMTsKK30KKworCitzdGF0aWMgUHlPYmplY3QgKgorY29tcGxleF9hZGQoUHlPYmplY3QgKnYsIFB5T2JqZWN0ICp3KQoreworICAgIFB5X2NvbXBsZXggcmVzdWx0OworICAgIFB5X2NvbXBsZXggYSwgYjsKKyAgICBUT19DT01QTEVYKHYsIGEpOworICAgIFRPX0NPTVBMRVgodywgYik7CisgICAgUHlGUEVfU1RBUlRfUFJPVEVDVCgiY29tcGxleF9hZGQiLCByZXR1cm4gMCkKKyAgICByZXN1bHQgPSBjX3N1bShhLCBiKTsKKyAgICBQeUZQRV9FTkRfUFJPVEVDVChyZXN1bHQpCisgICAgcmV0dXJuIFB5Q29tcGxleF9Gcm9tQ0NvbXBsZXgocmVzdWx0KTsKK30KKworc3RhdGljIFB5T2JqZWN0ICoKK2NvbXBsZXhfc3ViKFB5T2JqZWN0ICp2LCBQeU9iamVjdCAqdykKK3sKKyAgICBQeV9jb21wbGV4IHJlc3VsdDsKKyAgICBQeV9jb21wbGV4IGEsIGI7CisgICAgVE9fQ09NUExFWCh2LCBhKTsKKyAgICBUT19DT01QTEVYKHcsIGIpOzsKKyAgICBQeUZQRV9TVEFSVF9QUk9URUNUKCJjb21wbGV4X3N1YiIsIHJldHVybiAwKQorICAgIHJlc3VsdCA9IGNfZGlmZihhLCBiKTsKKyAgICBQeUZQRV9FTkRfUFJPVEVDVChyZXN1bHQpCisgICAgcmV0dXJuIFB5Q29tcGxleF9Gcm9tQ0NvbXBsZXgocmVzdWx0KTsKK30KKworc3RhdGljIFB5T2JqZWN0ICoKK2NvbXBsZXhfbXVsKFB5T2JqZWN0ICp2LCBQeU9iamVjdCAqdykKK3sKKyAgICBQeV9jb21wbGV4IHJlc3VsdDsKKyAgICBQeV9jb21wbGV4IGEsIGI7CisgICAgVE9fQ09NUExFWCh2LCBhKTsKKyAgICBUT19DT01QTEVYKHcsIGIpOworICAgIFB5RlBFX1NUQVJUX1BST1RFQ1QoImNvbXBsZXhfbXVsIiwgcmV0dXJuIDApCisgICAgcmVzdWx0ID0gY19wcm9kKGEsIGIpOworICAgIFB5RlBFX0VORF9QUk9URUNUKHJlc3VsdCkKKyAgICByZXR1cm4gUHlDb21wbGV4X0Zyb21DQ29tcGxleChyZXN1bHQpOworfQorCitzdGF0aWMgUHlPYmplY3QgKgorY29tcGxleF9kaXYoUHlPYmplY3QgKnYsIFB5T2JqZWN0ICp3KQoreworICAgIFB5X2NvbXBsZXggcXVvdDsKKyAgICBQeV9jb21wbGV4IGEsIGI7CisgICAgVE9fQ09NUExFWCh2LCBhKTsKKyAgICBUT19DT01QTEVYKHcsIGIpOworICAgIFB5RlBFX1NUQVJUX1BST1RFQ1QoImNvbXBsZXhfZGl2IiwgcmV0dXJuIDApCisgICAgZXJybm8gPSAwOworICAgIHF1b3QgPSBjX3F1b3QoYSwgYik7CisgICAgUHlGUEVfRU5EX1BST1RFQ1QocXVvdCkKKyAgICBpZiAoZXJybm8gPT0gRURPTSkgeworICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfWmVyb0RpdmlzaW9uRXJyb3IsICJjb21wbGV4IGRpdmlzaW9uIGJ5IHplcm8iKTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIHJldHVybiBQeUNvbXBsZXhfRnJvbUNDb21wbGV4KHF1b3QpOworfQorCitzdGF0aWMgUHlPYmplY3QgKgorY29tcGxleF9jbGFzc2ljX2RpdihQeU9iamVjdCAqdiwgUHlPYmplY3QgKncpCit7CisgICAgUHlfY29tcGxleCBxdW90OworICAgIFB5X2NvbXBsZXggYSwgYjsKKyAgICBUT19DT01QTEVYKHYsIGEpOworICAgIFRPX0NPTVBMRVgodywgYik7CisgICAgaWYgKFB5X0RpdmlzaW9uV2FybmluZ0ZsYWcgPj0gMiAmJgorICAgICAgICBQeUVycl9XYXJuKFB5RXhjX0RlcHJlY2F0aW9uV2FybmluZywKKyAgICAgICAgICAgICAgICAgICAiY2xhc3NpYyBjb21wbGV4IGRpdmlzaW9uIikgPCAwKQorICAgICAgICByZXR1cm4gTlVMTDsKKworICAgIFB5RlBFX1NUQVJUX1BST1RFQ1QoImNvbXBsZXhfY2xhc3NpY19kaXYiLCByZXR1cm4gMCkKKyAgICBlcnJubyA9IDA7CisgICAgcXVvdCA9IGNfcXVvdChhLCBiKTsKKyAgICBQeUZQRV9FTkRfUFJPVEVDVChxdW90KQorICAgIGlmIChlcnJubyA9PSBFRE9NKSB7CisgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19aZXJvRGl2aXNpb25FcnJvciwgImNvbXBsZXggZGl2aXNpb24gYnkgemVybyIpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgcmV0dXJuIFB5Q29tcGxleF9Gcm9tQ0NvbXBsZXgocXVvdCk7Cit9CisKK3N0YXRpYyBQeU9iamVjdCAqCitjb21wbGV4X3JlbWFpbmRlcihQeU9iamVjdCAqdiwgUHlPYmplY3QgKncpCit7CisgICAgUHlfY29tcGxleCBkaXYsIG1vZDsKKyAgICBQeV9jb21wbGV4IGEsIGI7CisgICAgVE9fQ09NUExFWCh2LCBhKTsKKyAgICBUT19DT01QTEVYKHcsIGIpOworICAgIGlmIChQeUVycl9XYXJuKFB5RXhjX0RlcHJlY2F0aW9uV2FybmluZywKKyAgICAgICAgICAgICAgICAgICAiY29tcGxleCBkaXZtb2QoKSwgLy8gYW5kICUgYXJlIGRlcHJlY2F0ZWQiKSA8IDApCisgICAgICAgIHJldHVybiBOVUxMOworCisgICAgZXJybm8gPSAwOworICAgIGRpdiA9IGNfcXVvdChhLCBiKTsgLyogVGhlIHJhdyBkaXZpc29yIHZhbHVlLiAqLworICAgIGlmIChlcnJubyA9PSBFRE9NKSB7CisgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19aZXJvRGl2aXNpb25FcnJvciwgImNvbXBsZXggcmVtYWluZGVyIik7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICBkaXYucmVhbCA9IGZsb29yKGRpdi5yZWFsKTsgLyogVXNlIHRoZSBmbG9vciBvZiB0aGUgcmVhbCBwYXJ0LiAqLworICAgIGRpdi5pbWFnID0gMC4wOworICAgIG1vZCA9IGNfZGlmZihhLCBjX3Byb2QoYiwgZGl2KSk7CisKKyAgICByZXR1cm4gUHlDb21wbGV4X0Zyb21DQ29tcGxleChtb2QpOworfQorCisKK3N0YXRpYyBQeU9iamVjdCAqCitjb21wbGV4X2Rpdm1vZChQeU9iamVjdCAqdiwgUHlPYmplY3QgKncpCit7CisgICAgUHlfY29tcGxleCBkaXYsIG1vZDsKKyAgICBQeU9iamVjdCAqZCwgKm0sICp6OworICAgIFB5X2NvbXBsZXggYSwgYjsKKyAgICBUT19DT01QTEVYKHYsIGEpOworICAgIFRPX0NPTVBMRVgodywgYik7CisgICAgaWYgKFB5RXJyX1dhcm4oUHlFeGNfRGVwcmVjYXRpb25XYXJuaW5nLAorICAgICAgICAgICAgICAgICAgICJjb21wbGV4IGRpdm1vZCgpLCAvLyBhbmQgJSBhcmUgZGVwcmVjYXRlZCIpIDwgMCkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisKKyAgICBlcnJubyA9IDA7CisgICAgZGl2ID0gY19xdW90KGEsIGIpOyAvKiBUaGUgcmF3IGRpdmlzb3IgdmFsdWUuICovCisgICAgaWYgKGVycm5vID09IEVET00pIHsKKyAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1plcm9EaXZpc2lvbkVycm9yLCAiY29tcGxleCBkaXZtb2QoKSIpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgZGl2LnJlYWwgPSBmbG9vcihkaXYucmVhbCk7IC8qIFVzZSB0aGUgZmxvb3Igb2YgdGhlIHJlYWwgcGFydC4gKi8KKyAgICBkaXYuaW1hZyA9IDAuMDsKKyAgICBtb2QgPSBjX2RpZmYoYSwgY19wcm9kKGIsIGRpdikpOworICAgIGQgPSBQeUNvbXBsZXhfRnJvbUNDb21wbGV4KGRpdik7CisgICAgbSA9IFB5Q29tcGxleF9Gcm9tQ0NvbXBsZXgobW9kKTsKKyAgICB6ID0gUHlUdXBsZV9QYWNrKDIsIGQsIG0pOworICAgIFB5X1hERUNSRUYoZCk7CisgICAgUHlfWERFQ1JFRihtKTsKKyAgICByZXR1cm4gejsKK30KKworc3RhdGljIFB5T2JqZWN0ICoKK2NvbXBsZXhfcG93KFB5T2JqZWN0ICp2LCBQeU9iamVjdCAqdywgUHlPYmplY3QgKnopCit7CisgICAgUHlfY29tcGxleCBwOworICAgIFB5X2NvbXBsZXggZXhwb25lbnQ7CisgICAgbG9uZyBpbnRfZXhwb25lbnQ7CisgICAgUHlfY29tcGxleCBhLCBiOworICAgIFRPX0NPTVBMRVgodiwgYSk7CisgICAgVE9fQ09NUExFWCh3LCBiKTsKKyAgICBpZiAoeiE9UHlfTm9uZSkgeworICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfVmFsdWVFcnJvciwgImNvbXBsZXggbW9kdWxvIik7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICBQeUZQRV9TVEFSVF9QUk9URUNUKCJjb21wbGV4X3BvdyIsIHJldHVybiAwKQorICAgIGVycm5vID0gMDsKKyAgICBleHBvbmVudCA9IGI7CisgICAgaW50X2V4cG9uZW50ID0gKGxvbmcpZXhwb25lbnQucmVhbDsKKyAgICBpZiAoZXhwb25lbnQuaW1hZyA9PSAwLiAmJiBleHBvbmVudC5yZWFsID09IGludF9leHBvbmVudCkKKyAgICAgICAgcCA9IGNfcG93aShhLGludF9leHBvbmVudCk7CisgICAgZWxzZQorICAgICAgICBwID0gY19wb3coYSxleHBvbmVudCk7CisKKyAgICBQeUZQRV9FTkRfUFJPVEVDVChwKQorICAgIFB5X0FESlVTVF9FUkFOR0UyKHAucmVhbCwgcC5pbWFnKTsKKyAgICBpZiAoZXJybm8gPT0gRURPTSkgeworICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfWmVyb0RpdmlzaW9uRXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAgICAiMC4wIHRvIGEgbmVnYXRpdmUgb3IgY29tcGxleCBwb3dlciIpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgZWxzZSBpZiAoZXJybm8gPT0gRVJBTkdFKSB7CisgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19PdmVyZmxvd0Vycm9yLAorICAgICAgICAgICAgICAgICAgICAgICAgImNvbXBsZXggZXhwb25lbnRpYXRpb24iKTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIHJldHVybiBQeUNvbXBsZXhfRnJvbUNDb21wbGV4KHApOworfQorCitzdGF0aWMgUHlPYmplY3QgKgorY29tcGxleF9pbnRfZGl2KFB5T2JqZWN0ICp2LCBQeU9iamVjdCAqdykKK3sKKyAgICBQeU9iamVjdCAqdCwgKnI7CisgICAgUHlfY29tcGxleCBhLCBiOworICAgIFRPX0NPTVBMRVgodiwgYSk7CisgICAgVE9fQ09NUExFWCh3LCBiKTsKKyAgICBpZiAoUHlFcnJfV2FybihQeUV4Y19EZXByZWNhdGlvbldhcm5pbmcsCisgICAgICAgICAgICAgICAgICAgImNvbXBsZXggZGl2bW9kKCksIC8vIGFuZCAlIGFyZSBkZXByZWNhdGVkIikgPCAwKQorICAgICAgICByZXR1cm4gTlVMTDsKKworICAgIHQgPSBjb21wbGV4X2Rpdm1vZCh2LCB3KTsKKyAgICBpZiAodCAhPSBOVUxMKSB7CisgICAgICAgIHIgPSBQeVR1cGxlX0dFVF9JVEVNKHQsIDApOworICAgICAgICBQeV9JTkNSRUYocik7CisgICAgICAgIFB5X0RFQ1JFRih0KTsKKyAgICAgICAgcmV0dXJuIHI7CisgICAgfQorICAgIHJldHVybiBOVUxMOworfQorCitzdGF0aWMgUHlPYmplY3QgKgorY29tcGxleF9uZWcoUHlDb21wbGV4T2JqZWN0ICp2KQoreworICAgIFB5X2NvbXBsZXggbmVnOworICAgIG5lZy5yZWFsID0gLXYtPmN2YWwucmVhbDsKKyAgICBuZWcuaW1hZyA9IC12LT5jdmFsLmltYWc7CisgICAgcmV0dXJuIFB5Q29tcGxleF9Gcm9tQ0NvbXBsZXgobmVnKTsKK30KKworc3RhdGljIFB5T2JqZWN0ICoKK2NvbXBsZXhfcG9zKFB5Q29tcGxleE9iamVjdCAqdikKK3sKKyAgICBpZiAoUHlDb21wbGV4X0NoZWNrRXhhY3QodikpIHsKKyAgICAgICAgUHlfSU5DUkVGKHYpOworICAgICAgICByZXR1cm4gKFB5T2JqZWN0ICopdjsKKyAgICB9CisgICAgZWxzZQorICAgICAgICByZXR1cm4gUHlDb21wbGV4X0Zyb21DQ29tcGxleCh2LT5jdmFsKTsKK30KKworc3RhdGljIFB5T2JqZWN0ICoKK2NvbXBsZXhfYWJzKFB5Q29tcGxleE9iamVjdCAqdikKK3sKKyAgICBkb3VibGUgcmVzdWx0OworCisgICAgUHlGUEVfU1RBUlRfUFJPVEVDVCgiY29tcGxleF9hYnMiLCByZXR1cm4gMCkKKyAgICByZXN1bHQgPSBjX2Ficyh2LT5jdmFsKTsKKyAgICBQeUZQRV9FTkRfUFJPVEVDVChyZXN1bHQpCisKKyAgICBpZiAoZXJybm8gPT0gRVJBTkdFKSB7CisgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19PdmVyZmxvd0Vycm9yLAorICAgICAgICAgICAgICAgICAgICAgICAgImFic29sdXRlIHZhbHVlIHRvbyBsYXJnZSIpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgcmV0dXJuIFB5RmxvYXRfRnJvbURvdWJsZShyZXN1bHQpOworfQorCitzdGF0aWMgaW50Citjb21wbGV4X25vbnplcm8oUHlDb21wbGV4T2JqZWN0ICp2KQoreworICAgIHJldHVybiB2LT5jdmFsLnJlYWwgIT0gMC4wIHx8IHYtPmN2YWwuaW1hZyAhPSAwLjA7Cit9CisKK3N0YXRpYyBpbnQKK2NvbXBsZXhfY29lcmNlKFB5T2JqZWN0ICoqcHYsIFB5T2JqZWN0ICoqcHcpCit7CisgICAgUHlfY29tcGxleCBjdmFsOworICAgIGN2YWwuaW1hZyA9IDAuOworICAgIGlmIChQeUludF9DaGVjaygqcHcpKSB7CisgICAgICAgIGN2YWwucmVhbCA9IChkb3VibGUpUHlJbnRfQXNMb25nKCpwdyk7CisgICAgICAgICpwdyA9IFB5Q29tcGxleF9Gcm9tQ0NvbXBsZXgoY3ZhbCk7CisgICAgICAgIFB5X0lOQ1JFRigqcHYpOworICAgICAgICByZXR1cm4gMDsKKyAgICB9CisgICAgZWxzZSBpZiAoUHlMb25nX0NoZWNrKCpwdykpIHsKKyAgICAgICAgY3ZhbC5yZWFsID0gUHlMb25nX0FzRG91YmxlKCpwdyk7CisgICAgICAgIGlmIChjdmFsLnJlYWwgPT0gLTEuMCAmJiBQeUVycl9PY2N1cnJlZCgpKQorICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICAqcHcgPSBQeUNvbXBsZXhfRnJvbUNDb21wbGV4KGN2YWwpOworICAgICAgICBQeV9JTkNSRUYoKnB2KTsKKyAgICAgICAgcmV0dXJuIDA7CisgICAgfQorICAgIGVsc2UgaWYgKFB5RmxvYXRfQ2hlY2soKnB3KSkgeworICAgICAgICBjdmFsLnJlYWwgPSBQeUZsb2F0X0FzRG91YmxlKCpwdyk7CisgICAgICAgICpwdyA9IFB5Q29tcGxleF9Gcm9tQ0NvbXBsZXgoY3ZhbCk7CisgICAgICAgIFB5X0lOQ1JFRigqcHYpOworICAgICAgICByZXR1cm4gMDsKKyAgICB9CisgICAgZWxzZSBpZiAoUHlDb21wbGV4X0NoZWNrKCpwdykpIHsKKyAgICAgICAgUHlfSU5DUkVGKCpwdik7CisgICAgICAgIFB5X0lOQ1JFRigqcHcpOworICAgICAgICByZXR1cm4gMDsKKyAgICB9CisgICAgcmV0dXJuIDE7IC8qIENhbid0IGRvIGl0ICovCit9CisKK3N0YXRpYyBQeU9iamVjdCAqCitjb21wbGV4X3JpY2hjb21wYXJlKFB5T2JqZWN0ICp2LCBQeU9iamVjdCAqdywgaW50IG9wKQoreworICAgIFB5T2JqZWN0ICpyZXM7CisgICAgUHlfY29tcGxleCBpOworICAgIGludCBlcXVhbDsKKworICAgIGlmIChvcCAhPSBQeV9FUSAmJiBvcCAhPSBQeV9ORSkgeworICAgICAgICAvKiBmb3IgYmFja3dhcmRzIGNvbXBhdGliaWxpdHksIGNvbXBhcmlzb25zIHdpdGggbm9uLW51bWJlcnMgcmV0dXJuCisgICAgICAgICAqIE5vdEltcGxlbWVudGVkLiAgT25seSBjb21wYXJpc29ucyB3aXRoIGNvcmUgbnVtZXJpYyB0eXBlcyByYWlzZQorICAgICAgICAgKiBUeXBlRXJyb3IuCisgICAgICAgICAqLworICAgICAgICBpZiAoUHlJbnRfQ2hlY2sodykgfHwgUHlMb25nX0NoZWNrKHcpIHx8CisgICAgICAgICAgICBQeUZsb2F0X0NoZWNrKHcpIHx8IFB5Q29tcGxleF9DaGVjayh3KSkgeworICAgICAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1R5cGVFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAibm8gb3JkZXJpbmcgcmVsYXRpb24gaXMgZGVmaW5lZCAiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgImZvciBjb21wbGV4IG51bWJlcnMiKTsKKyAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgICAgICB9CisgICAgICAgIGdvdG8gVW5pbXBsZW1lbnRlZDsKKyAgICB9CisKKyAgICBhc3NlcnQoUHlDb21wbGV4X0NoZWNrKHYpKTsKKyAgICBUT19DT01QTEVYKHYsIGkpOworCisgICAgaWYgKFB5SW50X0NoZWNrKHcpIHx8IFB5TG9uZ19DaGVjayh3KSkgeworICAgICAgICAvKiBDaGVjayBmb3IgMC4wIGltYWdpbmFyeSBwYXJ0IGZpcnN0IHRvIGF2b2lkIHRoZSByaWNoCisgICAgICAgICAqIGNvbXBhcmlzb24gd2hlbiBwb3NzaWJsZS4KKyAgICAgICAgICovCisgICAgICAgIGlmIChpLmltYWcgPT0gMC4wKSB7CisgICAgICAgICAgICBQeU9iamVjdCAqaiwgKnN1Yl9yZXM7CisgICAgICAgICAgICBqID0gUHlGbG9hdF9Gcm9tRG91YmxlKGkucmVhbCk7CisgICAgICAgICAgICBpZiAoaiA9PSBOVUxMKQorICAgICAgICAgICAgICAgIHJldHVybiBOVUxMOworCisgICAgICAgICAgICBzdWJfcmVzID0gUHlPYmplY3RfUmljaENvbXBhcmUoaiwgdywgb3ApOworICAgICAgICAgICAgUHlfREVDUkVGKGopOworICAgICAgICAgICAgcmV0dXJuIHN1Yl9yZXM7CisgICAgICAgIH0KKyAgICAgICAgZWxzZSB7CisgICAgICAgICAgICBlcXVhbCA9IDA7CisgICAgICAgIH0KKyAgICB9CisgICAgZWxzZSBpZiAoUHlGbG9hdF9DaGVjayh3KSkgeworICAgICAgICBlcXVhbCA9IChpLnJlYWwgPT0gUHlGbG9hdF9Bc0RvdWJsZSh3KSAmJiBpLmltYWcgPT0gMC4wKTsKKyAgICB9CisgICAgZWxzZSBpZiAoUHlDb21wbGV4X0NoZWNrKHcpKSB7CisgICAgICAgIFB5X2NvbXBsZXggajsKKworICAgICAgICBUT19DT01QTEVYKHcsIGopOworICAgICAgICBlcXVhbCA9IChpLnJlYWwgPT0gai5yZWFsICYmIGkuaW1hZyA9PSBqLmltYWcpOworICAgIH0KKyAgICBlbHNlIHsKKyAgICAgICAgZ290byBVbmltcGxlbWVudGVkOworICAgIH0KKworICAgIGlmIChlcXVhbCA9PSAob3AgPT0gUHlfRVEpKQorICAgICAgICAgcmVzID0gUHlfVHJ1ZTsKKyAgICBlbHNlCisgICAgICAgICByZXMgPSBQeV9GYWxzZTsKKworICAgIFB5X0lOQ1JFRihyZXMpOworICAgIHJldHVybiByZXM7CisKKyAgVW5pbXBsZW1lbnRlZDoKKyAgICBQeV9JTkNSRUYoUHlfTm90SW1wbGVtZW50ZWQpOworICAgIHJldHVybiBQeV9Ob3RJbXBsZW1lbnRlZDsKK30KKworc3RhdGljIFB5T2JqZWN0ICoKK2NvbXBsZXhfaW50KFB5T2JqZWN0ICp2KQoreworICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19UeXBlRXJyb3IsCisgICAgICAgICAgICAgICAiY2FuJ3QgY29udmVydCBjb21wbGV4IHRvIGludCIpOworICAgIHJldHVybiBOVUxMOworfQorCitzdGF0aWMgUHlPYmplY3QgKgorY29tcGxleF9sb25nKFB5T2JqZWN0ICp2KQoreworICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19UeXBlRXJyb3IsCisgICAgICAgICAgICAgICAiY2FuJ3QgY29udmVydCBjb21wbGV4IHRvIGxvbmciKTsKKyAgICByZXR1cm4gTlVMTDsKK30KKworc3RhdGljIFB5T2JqZWN0ICoKK2NvbXBsZXhfZmxvYXQoUHlPYmplY3QgKnYpCit7CisgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1R5cGVFcnJvciwKKyAgICAgICAgICAgICAgICJjYW4ndCBjb252ZXJ0IGNvbXBsZXggdG8gZmxvYXQiKTsKKyAgICByZXR1cm4gTlVMTDsKK30KKworc3RhdGljIFB5T2JqZWN0ICoKK2NvbXBsZXhfY29uanVnYXRlKFB5T2JqZWN0ICpzZWxmKQoreworICAgIFB5X2NvbXBsZXggYzsKKyAgICBjID0gKChQeUNvbXBsZXhPYmplY3QgKilzZWxmKS0+Y3ZhbDsKKyAgICBjLmltYWcgPSAtYy5pbWFnOworICAgIHJldHVybiBQeUNvbXBsZXhfRnJvbUNDb21wbGV4KGMpOworfQorCitQeURvY19TVFJWQVIoY29tcGxleF9jb25qdWdhdGVfZG9jLAorImNvbXBsZXguY29uanVnYXRlKCkgLT4gY29tcGxleFxuIgorIlxuIgorIlJldHVybnMgdGhlIGNvbXBsZXggY29uanVnYXRlIG9mIGl0cyBhcmd1bWVudC4gKDMtNGopLmNvbmp1Z2F0ZSgpID09IDMrNGouIik7CisKK3N0YXRpYyBQeU9iamVjdCAqCitjb21wbGV4X2dldG5ld2FyZ3MoUHlDb21wbGV4T2JqZWN0ICp2KQoreworICAgIFB5X2NvbXBsZXggYyA9IHYtPmN2YWw7CisgICAgcmV0dXJuIFB5X0J1aWxkVmFsdWUoIihkZCkiLCBjLnJlYWwsIGMuaW1hZyk7Cit9CisKK1B5RG9jX1NUUlZBUihjb21wbGV4X19mb3JtYXRfX2RvYywKKyJjb21wbGV4Ll9fZm9ybWF0X18oKSAtPiBzdHJcbiIKKyJcbiIKKyJDb252ZXJ0cyB0byBhIHN0cmluZyBhY2NvcmRpbmcgdG8gZm9ybWF0X3NwZWMuIik7CisKK3N0YXRpYyBQeU9iamVjdCAqCitjb21wbGV4X19mb3JtYXRfXyhQeU9iamVjdCogc2VsZiwgUHlPYmplY3QqIGFyZ3MpCit7CisgICAgUHlPYmplY3QgKmZvcm1hdF9zcGVjOworCisgICAgaWYgKCFQeUFyZ19QYXJzZVR1cGxlKGFyZ3MsICJPOl9fZm9ybWF0X18iLCAmZm9ybWF0X3NwZWMpKQorICAgIHJldHVybiBOVUxMOworICAgIGlmIChQeUJ5dGVzX0NoZWNrKGZvcm1hdF9zcGVjKSkKKyAgICByZXR1cm4gX1B5Q29tcGxleF9Gb3JtYXRBZHZhbmNlZChzZWxmLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFB5Qnl0ZXNfQVNfU1RSSU5HKGZvcm1hdF9zcGVjKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQeUJ5dGVzX0dFVF9TSVpFKGZvcm1hdF9zcGVjKSk7CisgICAgaWYgKFB5VW5pY29kZV9DaGVjayhmb3JtYXRfc3BlYykpIHsKKyAgICAvKiBDb252ZXJ0IGZvcm1hdF9zcGVjIHRvIGEgc3RyICovCisgICAgUHlPYmplY3QgKnJlc3VsdDsKKyAgICBQeU9iamVjdCAqc3RyX3NwZWMgPSBQeU9iamVjdF9TdHIoZm9ybWF0X3NwZWMpOworCisgICAgaWYgKHN0cl9zcGVjID09IE5VTEwpCisgICAgICAgIHJldHVybiBOVUxMOworCisgICAgcmVzdWx0ID0gX1B5Q29tcGxleF9Gb3JtYXRBZHZhbmNlZChzZWxmLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHlCeXRlc19BU19TVFJJTkcoc3RyX3NwZWMpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHlCeXRlc19HRVRfU0laRShzdHJfc3BlYykpOworCisgICAgUHlfREVDUkVGKHN0cl9zcGVjKTsKKyAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKyAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfVHlwZUVycm9yLCAiX19mb3JtYXRfXyByZXF1aXJlcyBzdHIgb3IgdW5pY29kZSIpOworICAgIHJldHVybiBOVUxMOworfQorCisjaWYgMAorc3RhdGljIFB5T2JqZWN0ICoKK2NvbXBsZXhfaXNfZmluaXRlKFB5T2JqZWN0ICpzZWxmKQoreworICAgIFB5X2NvbXBsZXggYzsKKyAgICBjID0gKChQeUNvbXBsZXhPYmplY3QgKilzZWxmKS0+Y3ZhbDsKKyAgICByZXR1cm4gUHlCb29sX0Zyb21Mb25nKChsb25nKShQeV9JU19GSU5JVEUoYy5yZWFsKSAmJgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFB5X0lTX0ZJTklURShjLmltYWcpKSk7Cit9CisKK1B5RG9jX1NUUlZBUihjb21wbGV4X2lzX2Zpbml0ZV9kb2MsCisiY29tcGxleC5pc19maW5pdGUoKSAtPiBib29sXG4iCisiXG4iCisiUmV0dXJucyBUcnVlIGlmIHRoZSByZWFsIGFuZCB0aGUgaW1hZ2luYXJ5IHBhcnQgaXMgZmluaXRlLiIpOworI2VuZGlmCisKK3N0YXRpYyBQeU1ldGhvZERlZiBjb21wbGV4X21ldGhvZHNbXSA9IHsKKyAgICB7ImNvbmp1Z2F0ZSIsICAgICAgIChQeUNGdW5jdGlvbiljb21wbGV4X2Nvbmp1Z2F0ZSwgTUVUSF9OT0FSR1MsCisgICAgIGNvbXBsZXhfY29uanVnYXRlX2RvY30sCisjaWYgMAorICAgIHsiaXNfZmluaXRlIiwgICAgICAgKFB5Q0Z1bmN0aW9uKWNvbXBsZXhfaXNfZmluaXRlLCBNRVRIX05PQVJHUywKKyAgICAgY29tcGxleF9pc19maW5pdGVfZG9jfSwKKyNlbmRpZgorICAgIHsiX19nZXRuZXdhcmdzX18iLCAgICAgICAgICAoUHlDRnVuY3Rpb24pY29tcGxleF9nZXRuZXdhcmdzLCAgICAgICAgTUVUSF9OT0FSR1N9LAorICAgIHsiX19mb3JtYXRfXyIsICAgICAgICAgIChQeUNGdW5jdGlvbiljb21wbGV4X19mb3JtYXRfXywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1FVEhfVkFSQVJHUywgY29tcGxleF9fZm9ybWF0X19kb2N9LAorICAgIHtOVUxMLCAgICAgICAgICAgICAgTlVMTH0gICAgICAgICAgIC8qIHNlbnRpbmVsICovCit9OworCitzdGF0aWMgUHlNZW1iZXJEZWYgY29tcGxleF9tZW1iZXJzW10gPSB7CisgICAgeyJyZWFsIiwgVF9ET1VCTEUsIG9mZnNldG9mKFB5Q29tcGxleE9iamVjdCwgY3ZhbC5yZWFsKSwgUkVBRE9OTFksCisgICAgICJ0aGUgcmVhbCBwYXJ0IG9mIGEgY29tcGxleCBudW1iZXIifSwKKyAgICB7ImltYWciLCBUX0RPVUJMRSwgb2Zmc2V0b2YoUHlDb21wbGV4T2JqZWN0LCBjdmFsLmltYWcpLCBSRUFET05MWSwKKyAgICAgInRoZSBpbWFnaW5hcnkgcGFydCBvZiBhIGNvbXBsZXggbnVtYmVyIn0sCisgICAgezB9LAorfTsKKworc3RhdGljIFB5T2JqZWN0ICoKK2NvbXBsZXhfc3VidHlwZV9mcm9tX3N0cmluZyhQeVR5cGVPYmplY3QgKnR5cGUsIFB5T2JqZWN0ICp2KQoreworICAgIGNvbnN0IGNoYXIgKnMsICpzdGFydDsKKyAgICBjaGFyICplbmQ7CisgICAgZG91YmxlIHg9MC4wLCB5PTAuMCwgejsKKyAgICBpbnQgZ290X2JyYWNrZXQ9MDsKKyNpZmRlZiBQeV9VU0lOR19VTklDT0RFCisgICAgY2hhciAqc19idWZmZXIgPSBOVUxMOworI2VuZGlmCisgICAgUHlfc3NpemVfdCBsZW47CisKKyAgICBpZiAoUHlTdHJpbmdfQ2hlY2sodikpIHsKKyAgICAgICAgcyA9IFB5U3RyaW5nX0FTX1NUUklORyh2KTsKKyAgICAgICAgbGVuID0gUHlTdHJpbmdfR0VUX1NJWkUodik7CisgICAgfQorI2lmZGVmIFB5X1VTSU5HX1VOSUNPREUKKyAgICBlbHNlIGlmIChQeVVuaWNvZGVfQ2hlY2sodikpIHsKKyAgICAgICAgc19idWZmZXIgPSAoY2hhciAqKVB5TWVtX01BTExPQyhQeVVuaWNvZGVfR0VUX1NJWkUodikrMSk7CisgICAgICAgIGlmIChzX2J1ZmZlciA9PSBOVUxMKQorICAgICAgICAgICAgcmV0dXJuIFB5RXJyX05vTWVtb3J5KCk7CisgICAgICAgIGlmIChQeVVuaWNvZGVfRW5jb2RlRGVjaW1hbChQeVVuaWNvZGVfQVNfVU5JQ09ERSh2KSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFB5VW5pY29kZV9HRVRfU0laRSh2KSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNfYnVmZmVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCkpCisgICAgICAgICAgICBnb3RvIGVycm9yOworICAgICAgICBzID0gc19idWZmZXI7CisgICAgICAgIGxlbiA9IHN0cmxlbihzKTsKKyAgICB9CisjZW5kaWYKKyAgICBlbHNlIGlmIChQeU9iamVjdF9Bc0NoYXJCdWZmZXIodiwgJnMsICZsZW4pKSB7CisgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19UeXBlRXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAgICAiY29tcGxleCgpIGFyZyBpcyBub3QgYSBzdHJpbmciKTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorCisgICAgLyogcG9zaXRpb24gb24gZmlyc3Qgbm9uYmxhbmsgKi8KKyAgICBzdGFydCA9IHM7CisgICAgd2hpbGUgKFB5X0lTU1BBQ0UoKnMpKQorICAgICAgICBzKys7CisgICAgaWYgKCpzID09ICcoJykgeworICAgICAgICAvKiBTa2lwIG92ZXIgcG9zc2libGUgYnJhY2tldCBmcm9tIHJlcHIoKS4gKi8KKyAgICAgICAgZ290X2JyYWNrZXQgPSAxOworICAgICAgICBzKys7CisgICAgICAgIHdoaWxlIChQeV9JU1NQQUNFKCpzKSkKKyAgICAgICAgICAgIHMrKzsKKyAgICB9CisKKyAgICAvKiBhIHZhbGlkIGNvbXBsZXggc3RyaW5nIHVzdWFsbHkgdGFrZXMgb25lIG9mIHRoZSB0aHJlZSBmb3JtczoKKworICAgICAgICAgPGZsb2F0PiAgICAgICAgICAgICAgICAgIC0gcmVhbCBwYXJ0IG9ubHkKKyAgICAgICAgIDxmbG9hdD5qICAgICAgICAgICAgICAgICAtIGltYWdpbmFyeSBwYXJ0IG9ubHkKKyAgICAgICAgIDxmbG9hdD48c2lnbmVkLWZsb2F0PmogICAtIHJlYWwgYW5kIGltYWdpbmFyeSBwYXJ0cworCisgICAgICAgd2hlcmUgPGZsb2F0PiByZXByZXNlbnRzIGFueSBudW1lcmljIHN0cmluZyB0aGF0J3MgYWNjZXB0ZWQgYnkgdGhlCisgICAgICAgZmxvYXQgY29uc3RydWN0b3IgKGluY2x1ZGluZyAnbmFuJywgJ2luZicsICdpbmZpbml0eScsIGV0Yy4pLCBhbmQKKyAgICAgICA8c2lnbmVkLWZsb2F0PiBpcyBhbnkgc3RyaW5nIG9mIHRoZSBmb3JtIDxmbG9hdD4gd2hvc2UgZmlyc3QKKyAgICAgICBjaGFyYWN0ZXIgaXMgJysnIG9yICctJy4KKworICAgICAgIEZvciBiYWNrd2FyZHMgY29tcGF0aWJpbGl0eSwgdGhlIGV4dHJhIGZvcm1zCisKKyAgICAgICAgIDxmbG9hdD48c2lnbj5qCisgICAgICAgICA8c2lnbj5qCisgICAgICAgICBqCisKKyAgICAgICBhcmUgYWxzbyBhY2NlcHRlZCwgdGhvdWdoIHN1cHBvcnQgZm9yIHRoZXNlIGZvcm1zIG1heSBiZSByZW1vdmVkIGZyb20KKyAgICAgICBhIGZ1dHVyZSB2ZXJzaW9uIG9mIFB5dGhvbi4KKyAgICAqLworCisgICAgLyogZmlyc3QgbG9vayBmb3IgZm9ybXMgc3RhcnRpbmcgd2l0aCA8ZmxvYXQ+ICovCisgICAgeiA9IFB5T1Nfc3RyaW5nX3RvX2RvdWJsZShzLCAmZW5kLCBOVUxMKTsKKyAgICBpZiAoeiA9PSAtMS4wICYmIFB5RXJyX09jY3VycmVkKCkpIHsKKyAgICAgICAgaWYgKFB5RXJyX0V4Y2VwdGlvbk1hdGNoZXMoUHlFeGNfVmFsdWVFcnJvcikpCisgICAgICAgICAgICBQeUVycl9DbGVhcigpOworICAgICAgICBlbHNlCisgICAgICAgICAgICBnb3RvIGVycm9yOworICAgIH0KKyAgICBpZiAoZW5kICE9IHMpIHsKKyAgICAgICAgLyogYWxsIDQgZm9ybXMgc3RhcnRpbmcgd2l0aCA8ZmxvYXQ+IGxhbmQgaGVyZSAqLworICAgICAgICBzID0gZW5kOworICAgICAgICBpZiAoKnMgPT0gJysnIHx8ICpzID09ICctJykgeworICAgICAgICAgICAgLyogPGZsb2F0PjxzaWduZWQtZmxvYXQ+aiB8IDxmbG9hdD48c2lnbj5qICovCisgICAgICAgICAgICB4ID0gejsKKyAgICAgICAgICAgIHkgPSBQeU9TX3N0cmluZ190b19kb3VibGUocywgJmVuZCwgTlVMTCk7CisgICAgICAgICAgICBpZiAoeSA9PSAtMS4wICYmIFB5RXJyX09jY3VycmVkKCkpIHsKKyAgICAgICAgICAgICAgICBpZiAoUHlFcnJfRXhjZXB0aW9uTWF0Y2hlcyhQeUV4Y19WYWx1ZUVycm9yKSkKKyAgICAgICAgICAgICAgICAgICAgUHlFcnJfQ2xlYXIoKTsKKyAgICAgICAgICAgICAgICBlbHNlCisgICAgICAgICAgICAgICAgICAgIGdvdG8gZXJyb3I7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoZW5kICE9IHMpCisgICAgICAgICAgICAgICAgLyogPGZsb2F0PjxzaWduZWQtZmxvYXQ+aiAqLworICAgICAgICAgICAgICAgIHMgPSBlbmQ7CisgICAgICAgICAgICBlbHNlIHsKKyAgICAgICAgICAgICAgICAvKiA8ZmxvYXQ+PHNpZ24+aiAqLworICAgICAgICAgICAgICAgIHkgPSAqcyA9PSAnKycgPyAxLjAgOiAtMS4wOworICAgICAgICAgICAgICAgIHMrKzsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmICghKCpzID09ICdqJyB8fCAqcyA9PSAnSicpKQorICAgICAgICAgICAgICAgIGdvdG8gcGFyc2VfZXJyb3I7CisgICAgICAgICAgICBzKys7CisgICAgICAgIH0KKyAgICAgICAgZWxzZSBpZiAoKnMgPT0gJ2onIHx8ICpzID09ICdKJykgeworICAgICAgICAgICAgLyogPGZsb2F0PmogKi8KKyAgICAgICAgICAgIHMrKzsKKyAgICAgICAgICAgIHkgPSB6OworICAgICAgICB9CisgICAgICAgIGVsc2UKKyAgICAgICAgICAgIC8qIDxmbG9hdD4gKi8KKyAgICAgICAgICAgIHggPSB6OworICAgIH0KKyAgICBlbHNlIHsKKyAgICAgICAgLyogbm90IHN0YXJ0aW5nIHdpdGggPGZsb2F0PjsgbXVzdCBiZSA8c2lnbj5qIG9yIGogKi8KKyAgICAgICAgaWYgKCpzID09ICcrJyB8fCAqcyA9PSAnLScpIHsKKyAgICAgICAgICAgIC8qIDxzaWduPmogKi8KKyAgICAgICAgICAgIHkgPSAqcyA9PSAnKycgPyAxLjAgOiAtMS4wOworICAgICAgICAgICAgcysrOworICAgICAgICB9CisgICAgICAgIGVsc2UKKyAgICAgICAgICAgIC8qIGogKi8KKyAgICAgICAgICAgIHkgPSAxLjA7CisgICAgICAgIGlmICghKCpzID09ICdqJyB8fCAqcyA9PSAnSicpKQorICAgICAgICAgICAgZ290byBwYXJzZV9lcnJvcjsKKyAgICAgICAgcysrOworICAgIH0KKworICAgIC8qIHRyYWlsaW5nIHdoaXRlc3BhY2UgYW5kIGNsb3NpbmcgYnJhY2tldCAqLworICAgIHdoaWxlIChQeV9JU1NQQUNFKCpzKSkKKyAgICAgICAgcysrOworICAgIGlmIChnb3RfYnJhY2tldCkgeworICAgICAgICAvKiBpZiB0aGVyZSB3YXMgYW4gb3BlbmluZyBwYXJlbnRoZXNpcywgdGhlbiB0aGUgY29ycmVzcG9uZGluZworICAgICAgICAgICBjbG9zaW5nIHBhcmVudGhlc2lzIHNob3VsZCBiZSByaWdodCBoZXJlICovCisgICAgICAgIGlmICgqcyAhPSAnKScpCisgICAgICAgICAgICBnb3RvIHBhcnNlX2Vycm9yOworICAgICAgICBzKys7CisgICAgICAgIHdoaWxlIChQeV9JU1NQQUNFKCpzKSkKKyAgICAgICAgICAgIHMrKzsKKyAgICB9CisKKyAgICAvKiB3ZSBzaG91bGQgbm93IGJlIGF0IHRoZSBlbmQgb2YgdGhlIHN0cmluZyAqLworICAgIGlmIChzLXN0YXJ0ICE9IGxlbikKKyAgICAgICAgZ290byBwYXJzZV9lcnJvcjsKKworCisjaWZkZWYgUHlfVVNJTkdfVU5JQ09ERQorICAgIGlmIChzX2J1ZmZlcikKKyAgICAgICAgUHlNZW1fRlJFRShzX2J1ZmZlcik7CisjZW5kaWYKKyAgICByZXR1cm4gY29tcGxleF9zdWJ0eXBlX2Zyb21fZG91Ymxlcyh0eXBlLCB4LCB5KTsKKworICBwYXJzZV9lcnJvcjoKKyAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfVmFsdWVFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgImNvbXBsZXgoKSBhcmcgaXMgYSBtYWxmb3JtZWQgc3RyaW5nIik7CisgIGVycm9yOgorI2lmZGVmIFB5X1VTSU5HX1VOSUNPREUKKyAgICBpZiAoc19idWZmZXIpCisgICAgICAgIFB5TWVtX0ZSRUUoc19idWZmZXIpOworI2VuZGlmCisgICAgcmV0dXJuIE5VTEw7Cit9CisKK3N0YXRpYyBQeU9iamVjdCAqCitjb21wbGV4X25ldyhQeVR5cGVPYmplY3QgKnR5cGUsIFB5T2JqZWN0ICphcmdzLCBQeU9iamVjdCAqa3dkcykKK3sKKyAgICBQeU9iamVjdCAqciwgKmksICp0bXA7CisgICAgUHlOdW1iZXJNZXRob2RzICpuYnIsICpuYmkgPSBOVUxMOworICAgIFB5X2NvbXBsZXggY3IsIGNpOworICAgIGludCBvd25fciA9IDA7CisgICAgaW50IGNyX2lzX2NvbXBsZXggPSAwOworICAgIGludCBjaV9pc19jb21wbGV4ID0gMDsKKyAgICBzdGF0aWMgY2hhciAqa3dsaXN0W10gPSB7InJlYWwiLCAiaW1hZyIsIDB9OworCisgICAgciA9IFB5X0ZhbHNlOworICAgIGkgPSBOVUxMOworICAgIGlmICghUHlBcmdfUGFyc2VUdXBsZUFuZEtleXdvcmRzKGFyZ3MsIGt3ZHMsICJ8T086Y29tcGxleCIsIGt3bGlzdCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmciwgJmkpKQorICAgICAgICByZXR1cm4gTlVMTDsKKworICAgIC8qIFNwZWNpYWwtY2FzZSBmb3IgYSBzaW5nbGUgYXJndW1lbnQgd2hlbiB0eXBlKGFyZykgaXMgY29tcGxleC4gKi8KKyAgICBpZiAoUHlDb21wbGV4X0NoZWNrRXhhY3QocikgJiYgaSA9PSBOVUxMICYmCisgICAgICAgIHR5cGUgPT0gJlB5Q29tcGxleF9UeXBlKSB7CisgICAgICAgIC8qIE5vdGUgdGhhdCB3ZSBjYW4ndCBrbm93IHdoZXRoZXIgaXQncyBzYWZlIHRvIHJldHVybgorICAgICAgICAgICBhIGNvbXBsZXggKnN1YmNsYXNzKiBpbnN0YW5jZSBhcy1pcywgaGVuY2UgdGhlIHJlc3RyaWN0aW9uCisgICAgICAgICAgIHRvIGV4YWN0IGNvbXBsZXhlcyBoZXJlLiAgSWYgZWl0aGVyIHRoZSBpbnB1dCBvciB0aGUKKyAgICAgICAgICAgb3V0cHV0IGlzIGEgY29tcGxleCBzdWJjbGFzcywgaXQgd2lsbCBiZSBoYW5kbGVkIGJlbG93CisgICAgICAgICAgIGFzIGEgbm9uLW9ydGhvZ29uYWwgdmVjdG9yLiAgKi8KKyAgICAgICAgUHlfSU5DUkVGKHIpOworICAgICAgICByZXR1cm4gcjsKKyAgICB9CisgICAgaWYgKFB5U3RyaW5nX0NoZWNrKHIpIHx8IFB5VW5pY29kZV9DaGVjayhyKSkgeworICAgICAgICBpZiAoaSAhPSBOVUxMKSB7CisgICAgICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfVHlwZUVycm9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICJjb21wbGV4KCkgY2FuJ3QgdGFrZSBzZWNvbmQgYXJnIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICIgaWYgZmlyc3QgaXMgYSBzdHJpbmciKTsKKyAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgICAgICB9CisgICAgICAgIHJldHVybiBjb21wbGV4X3N1YnR5cGVfZnJvbV9zdHJpbmcodHlwZSwgcik7CisgICAgfQorICAgIGlmIChpICE9IE5VTEwgJiYgKFB5U3RyaW5nX0NoZWNrKGkpIHx8IFB5VW5pY29kZV9DaGVjayhpKSkpIHsKKyAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1R5cGVFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICJjb21wbGV4KCkgc2Vjb25kIGFyZyBjYW4ndCBiZSBhIHN0cmluZyIpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisKKyAgICB0bXAgPSB0cnlfY29tcGxleF9zcGVjaWFsX21ldGhvZChyKTsKKyAgICBpZiAodG1wKSB7CisgICAgICAgIHIgPSB0bXA7CisgICAgICAgIG93bl9yID0gMTsKKyAgICB9CisgICAgZWxzZSBpZiAoUHlFcnJfT2NjdXJyZWQoKSkgeworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisKKyAgICBuYnIgPSByLT5vYl90eXBlLT50cF9hc19udW1iZXI7CisgICAgaWYgKGkgIT0gTlVMTCkKKyAgICAgICAgbmJpID0gaS0+b2JfdHlwZS0+dHBfYXNfbnVtYmVyOworICAgIGlmIChuYnIgPT0gTlVMTCB8fCBuYnItPm5iX2Zsb2F0ID09IE5VTEwgfHwKKyAgICAgICAgKChpICE9IE5VTEwpICYmIChuYmkgPT0gTlVMTCB8fCBuYmktPm5iX2Zsb2F0ID09IE5VTEwpKSkgeworICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfVHlwZUVycm9yLAorICAgICAgICAgICAgICAgICAgICJjb21wbGV4KCkgYXJndW1lbnQgbXVzdCBiZSBhIHN0cmluZyBvciBhIG51bWJlciIpOworICAgICAgICBpZiAob3duX3IpIHsKKyAgICAgICAgICAgIFB5X0RFQ1JFRihyKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisKKyAgICAvKiBJZiB3ZSBnZXQgdGhpcyBmYXIsIHRoZW4gdGhlICJyZWFsIiBhbmQgImltYWciIHBhcnRzIHNob3VsZAorICAgICAgIGJvdGggYmUgdHJlYXRlZCBhcyBudW1iZXJzLCBhbmQgdGhlIGNvbnN0cnVjdG9yIHNob3VsZCByZXR1cm4gYQorICAgICAgIGNvbXBsZXggbnVtYmVyIGVxdWFsIHRvIChyZWFsICsgaW1hZyoxaikuCisKKyAgICAgICBOb3RlIHRoYXQgd2UgZG8gTk9UIGFzc3VtZSB0aGUgaW5wdXQgdG8gYWxyZWFkeSBiZSBpbiBjYW5vbmljYWwKKyAgICAgICBmb3JtOyB0aGUgInJlYWwiIGFuZCAiaW1hZyIgcGFydHMgbWlnaHQgdGhlbXNlbHZlcyBiZSBjb21wbGV4CisgICAgICAgbnVtYmVycywgd2hpY2ggc2xpZ2h0bHkgY29tcGxpY2F0ZXMgdGhlIGNvZGUgYmVsb3cuICovCisgICAgaWYgKFB5Q29tcGxleF9DaGVjayhyKSkgeworICAgICAgICAvKiBOb3RlIHRoYXQgaWYgciBpcyBvZiBhIGNvbXBsZXggc3VidHlwZSwgd2UncmUgb25seQorICAgICAgICAgICByZXRhaW5pbmcgaXRzIHJlYWwgJiBpbWFnIHBhcnRzIGhlcmUsIGFuZCB0aGUgcmV0dXJuCisgICAgICAgICAgIHZhbHVlIGlzIChwcm9wZXJseSkgb2YgdGhlIGJ1aWx0aW4gY29tcGxleCB0eXBlLiAqLworICAgICAgICBjciA9ICgoUHlDb21wbGV4T2JqZWN0KilyKS0+Y3ZhbDsKKyAgICAgICAgY3JfaXNfY29tcGxleCA9IDE7CisgICAgICAgIGlmIChvd25fcikgeworICAgICAgICAgICAgUHlfREVDUkVGKHIpOworICAgICAgICB9CisgICAgfQorICAgIGVsc2UgeworICAgICAgICAvKiBUaGUgInJlYWwiIHBhcnQgcmVhbGx5IGlzIGVudGlyZWx5IHJlYWwsIGFuZCBjb250cmlidXRlcworICAgICAgICAgICBub3RoaW5nIGluIHRoZSBpbWFnaW5hcnkgZGlyZWN0aW9uLgorICAgICAgICAgICBKdXN0IHRyZWF0IGl0IGFzIGEgZG91YmxlLiAqLworICAgICAgICB0bXAgPSBQeU51bWJlcl9GbG9hdChyKTsKKyAgICAgICAgaWYgKG93bl9yKSB7CisgICAgICAgICAgICAvKiByIHdhcyBhIG5ld2x5IGNyZWF0ZWQgY29tcGxleCBudW1iZXIsIHJhdGhlcgorICAgICAgICAgICAgICAgdGhhbiB0aGUgb3JpZ2luYWwgInJlYWwiIGFyZ3VtZW50LiAqLworICAgICAgICAgICAgUHlfREVDUkVGKHIpOworICAgICAgICB9CisgICAgICAgIGlmICh0bXAgPT0gTlVMTCkKKyAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgICAgICBpZiAoIVB5RmxvYXRfQ2hlY2sodG1wKSkgeworICAgICAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1R5cGVFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZmxvYXQocikgZGlkbid0IHJldHVybiBhIGZsb2F0Iik7CisgICAgICAgICAgICBQeV9ERUNSRUYodG1wKTsKKyAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgICAgICB9CisgICAgICAgIGNyLnJlYWwgPSBQeUZsb2F0X0FzRG91YmxlKHRtcCk7CisgICAgICAgIGNyLmltYWcgPSAwLjA7IC8qIFNodXQgdXAgY29tcGlsZXIgd2FybmluZyAqLworICAgICAgICBQeV9ERUNSRUYodG1wKTsKKyAgICB9CisgICAgaWYgKGkgPT0gTlVMTCkgeworICAgICAgICBjaS5yZWFsID0gMC4wOworICAgIH0KKyAgICBlbHNlIGlmIChQeUNvbXBsZXhfQ2hlY2soaSkpIHsKKyAgICAgICAgY2kgPSAoKFB5Q29tcGxleE9iamVjdCopaSktPmN2YWw7CisgICAgICAgIGNpX2lzX2NvbXBsZXggPSAxOworICAgIH0gZWxzZSB7CisgICAgICAgIC8qIFRoZSAiaW1hZyIgcGFydCByZWFsbHkgaXMgZW50aXJlbHkgaW1hZ2luYXJ5LCBhbmQKKyAgICAgICAgICAgY29udHJpYnV0ZXMgbm90aGluZyBpbiB0aGUgcmVhbCBkaXJlY3Rpb24uCisgICAgICAgICAgIEp1c3QgdHJlYXQgaXQgYXMgYSBkb3VibGUuICovCisgICAgICAgIHRtcCA9ICgqbmJpLT5uYl9mbG9hdCkoaSk7CisgICAgICAgIGlmICh0bXAgPT0gTlVMTCkKKyAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgICAgICBjaS5yZWFsID0gUHlGbG9hdF9Bc0RvdWJsZSh0bXApOworICAgICAgICBQeV9ERUNSRUYodG1wKTsKKyAgICB9CisgICAgLyogIElmIHRoZSBpbnB1dCB3YXMgaW4gY2Fub25pY2FsIGZvcm0sIHRoZW4gdGhlICJyZWFsIiBhbmQgImltYWciCisgICAgICAgIHBhcnRzIGFyZSByZWFsIG51bWJlcnMsIHNvIHRoYXQgY2kuaW1hZyBhbmQgY3IuaW1hZyBhcmUgemVyby4KKyAgICAgICAgV2UgbmVlZCB0aGlzIGNvcnJlY3Rpb24gaW4gY2FzZSB0aGV5IHdlcmUgbm90IHJlYWwgbnVtYmVycy4gKi8KKworICAgIGlmIChjaV9pc19jb21wbGV4KSB7CisgICAgICAgIGNyLnJlYWwgLT0gY2kuaW1hZzsKKyAgICB9CisgICAgaWYgKGNyX2lzX2NvbXBsZXgpIHsKKyAgICAgICAgY2kucmVhbCArPSBjci5pbWFnOworICAgIH0KKyAgICByZXR1cm4gY29tcGxleF9zdWJ0eXBlX2Zyb21fZG91Ymxlcyh0eXBlLCBjci5yZWFsLCBjaS5yZWFsKTsKK30KKworUHlEb2NfU1RSVkFSKGNvbXBsZXhfZG9jLAorImNvbXBsZXgocmVhbFssIGltYWddKSAtPiBjb21wbGV4IG51bWJlclxuIgorIlxuIgorIkNyZWF0ZSBhIGNvbXBsZXggbnVtYmVyIGZyb20gYSByZWFsIHBhcnQgYW5kIGFuIG9wdGlvbmFsIGltYWdpbmFyeSBwYXJ0LlxuIgorIlRoaXMgaXMgZXF1aXZhbGVudCB0byAocmVhbCArIGltYWcqMWopIHdoZXJlIGltYWcgZGVmYXVsdHMgdG8gMC4iKTsKKworc3RhdGljIFB5TnVtYmVyTWV0aG9kcyBjb21wbGV4X2FzX251bWJlciA9IHsKKyAgICAoYmluYXJ5ZnVuYyljb21wbGV4X2FkZCwgICAgICAgICAgICAgICAgICAgIC8qIG5iX2FkZCAqLworICAgIChiaW5hcnlmdW5jKWNvbXBsZXhfc3ViLCAgICAgICAgICAgICAgICAgICAgLyogbmJfc3VidHJhY3QgKi8KKyAgICAoYmluYXJ5ZnVuYyljb21wbGV4X211bCwgICAgICAgICAgICAgICAgICAgIC8qIG5iX211bHRpcGx5ICovCisgICAgKGJpbmFyeWZ1bmMpY29tcGxleF9jbGFzc2ljX2RpdiwgICAgICAgICAgICAvKiBuYl9kaXZpZGUgKi8KKyAgICAoYmluYXJ5ZnVuYyljb21wbGV4X3JlbWFpbmRlciwgICAgICAgICAgICAgIC8qIG5iX3JlbWFpbmRlciAqLworICAgIChiaW5hcnlmdW5jKWNvbXBsZXhfZGl2bW9kLCAgICAgICAgICAgICAgICAgLyogbmJfZGl2bW9kICovCisgICAgKHRlcm5hcnlmdW5jKWNvbXBsZXhfcG93LCAgICAgICAgICAgICAgICAgICAvKiBuYl9wb3dlciAqLworICAgICh1bmFyeWZ1bmMpY29tcGxleF9uZWcsICAgICAgICAgICAgICAgICAgICAgLyogbmJfbmVnYXRpdmUgKi8KKyAgICAodW5hcnlmdW5jKWNvbXBsZXhfcG9zLCAgICAgICAgICAgICAgICAgICAgIC8qIG5iX3Bvc2l0aXZlICovCisgICAgKHVuYXJ5ZnVuYyljb21wbGV4X2FicywgICAgICAgICAgICAgICAgICAgICAvKiBuYl9hYnNvbHV0ZSAqLworICAgIChpbnF1aXJ5KWNvbXBsZXhfbm9uemVybywgICAgICAgICAgICAgICAgICAgLyogbmJfbm9uemVybyAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogbmJfaW52ZXJ0ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBuYl9sc2hpZnQgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIG5iX3JzaGlmdCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogbmJfYW5kICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBuYl94b3IgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIG5iX29yICovCisgICAgY29tcGxleF9jb2VyY2UsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBuYl9jb2VyY2UgKi8KKyAgICBjb21wbGV4X2ludCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIG5iX2ludCAqLworICAgIGNvbXBsZXhfbG9uZywgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogbmJfbG9uZyAqLworICAgIGNvbXBsZXhfZmxvYXQsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogbmJfZmxvYXQgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIG5iX29jdCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogbmJfaGV4ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBuYl9pbnBsYWNlX2FkZCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogbmJfaW5wbGFjZV9zdWJ0cmFjdCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogbmJfaW5wbGFjZV9tdWx0aXBseSovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBuYl9pbnBsYWNlX2RpdmlkZSAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogbmJfaW5wbGFjZV9yZW1haW5kZXIgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIG5iX2lucGxhY2VfcG93ZXIgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIG5iX2lucGxhY2VfbHNoaWZ0ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBuYl9pbnBsYWNlX3JzaGlmdCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogbmJfaW5wbGFjZV9hbmQgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIG5iX2lucGxhY2VfeG9yICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBuYl9pbnBsYWNlX29yICovCisgICAgKGJpbmFyeWZ1bmMpY29tcGxleF9pbnRfZGl2LCAgICAgICAgICAgICAgICAvKiBuYl9mbG9vcl9kaXZpZGUgKi8KKyAgICAoYmluYXJ5ZnVuYyljb21wbGV4X2RpdiwgICAgICAgICAgICAgICAgICAgIC8qIG5iX3RydWVfZGl2aWRlICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBuYl9pbnBsYWNlX2Zsb29yX2RpdmlkZSAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogbmJfaW5wbGFjZV90cnVlX2RpdmlkZSAqLworfTsKKworUHlUeXBlT2JqZWN0IFB5Q29tcGxleF9UeXBlID0geworICAgIFB5VmFyT2JqZWN0X0hFQURfSU5JVCgmUHlUeXBlX1R5cGUsIDApCisgICAgImNvbXBsZXgiLAorICAgIHNpemVvZihQeUNvbXBsZXhPYmplY3QpLAorICAgIDAsCisgICAgY29tcGxleF9kZWFsbG9jLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9kZWFsbG9jICovCisgICAgKHByaW50ZnVuYyljb21wbGV4X3ByaW50LCAgICAgICAgICAgICAgICAgICAvKiB0cF9wcmludCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZ2V0YXR0ciAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfc2V0YXR0ciAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfY29tcGFyZSAqLworICAgIChyZXByZnVuYyljb21wbGV4X3JlcHIsICAgICAgICAgICAgICAgICAgICAgLyogdHBfcmVwciAqLworICAgICZjb21wbGV4X2FzX251bWJlciwgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfYXNfbnVtYmVyICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9hc19zZXF1ZW5jZSAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfYXNfbWFwcGluZyAqLworICAgIChoYXNoZnVuYyljb21wbGV4X2hhc2gsICAgICAgICAgICAgICAgICAgICAgLyogdHBfaGFzaCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfY2FsbCAqLworICAgIChyZXByZnVuYyljb21wbGV4X3N0ciwgICAgICAgICAgICAgICAgICAgICAgLyogdHBfc3RyICovCisgICAgUHlPYmplY3RfR2VuZXJpY0dldEF0dHIsICAgICAgICAgICAgICAgICAgICAvKiB0cF9nZXRhdHRybyAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfc2V0YXR0cm8gKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2FzX2J1ZmZlciAqLworICAgIFB5X1RQRkxBR1NfREVGQVVMVCB8IFB5X1RQRkxBR1NfQ0hFQ0tUWVBFUyB8CisgICAgICAgIFB5X1RQRkxBR1NfQkFTRVRZUEUsICAgICAgICAgICAgICAgICAgICAvKiB0cF9mbGFncyAqLworICAgIGNvbXBsZXhfZG9jLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZG9jICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF90cmF2ZXJzZSAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfY2xlYXIgKi8KKyAgICBjb21wbGV4X3JpY2hjb21wYXJlLCAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3JpY2hjb21wYXJlICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF93ZWFrbGlzdG9mZnNldCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfaXRlciAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfaXRlcm5leHQgKi8KKyAgICBjb21wbGV4X21ldGhvZHMsICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX21ldGhvZHMgKi8KKyAgICBjb21wbGV4X21lbWJlcnMsICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX21lbWJlcnMgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2dldHNldCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfYmFzZSAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZGljdCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZGVzY3JfZ2V0ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9kZXNjcl9zZXQgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2RpY3RvZmZzZXQgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2luaXQgKi8KKyAgICBQeVR5cGVfR2VuZXJpY0FsbG9jLCAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2FsbG9jICovCisgICAgY29tcGxleF9uZXcsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9uZXcgKi8KKyAgICBQeU9iamVjdF9EZWwsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2ZyZWUgKi8KK307CisKKyNlbmRpZgpkaWZmIC0tZ2l0IGEvUHl0aG9uLTIuNy41L09iamVjdHMvZGVzY3JvYmplY3QuYyBiL1B5dGhvbi0yLjcuNS9PYmplY3RzL2Rlc2Nyb2JqZWN0LmMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uN2JmMTg1OQotLS0gL2Rldi9udWxsCisrKyBiL1B5dGhvbi0yLjcuNS9PYmplY3RzL2Rlc2Nyb2JqZWN0LmMKQEAgLTAsMCArMSwxNDM2IEBACisvKiBEZXNjcmlwdG9ycyAtLSBhIG5ldywgZmxleGlibGUgd2F5IHRvIGRlc2NyaWJlIGF0dHJpYnV0ZXMgKi8KKworI2luY2x1ZGUgIlB5dGhvbi5oIgorI2luY2x1ZGUgInN0cnVjdG1lbWJlci5oIiAvKiBXaHkgaXMgdGhpcyBub3QgaW5jbHVkZWQgaW4gUHl0aG9uLmg/ICovCisKK3N0YXRpYyB2b2lkCitkZXNjcl9kZWFsbG9jKFB5RGVzY3JPYmplY3QgKmRlc2NyKQoreworICAgIF9QeU9iamVjdF9HQ19VTlRSQUNLKGRlc2NyKTsKKyAgICBQeV9YREVDUkVGKGRlc2NyLT5kX3R5cGUpOworICAgIFB5X1hERUNSRUYoZGVzY3ItPmRfbmFtZSk7CisgICAgUHlPYmplY3RfR0NfRGVsKGRlc2NyKTsKK30KKworc3RhdGljIGNoYXIgKgorZGVzY3JfbmFtZShQeURlc2NyT2JqZWN0ICpkZXNjcikKK3sKKyAgICBpZiAoZGVzY3ItPmRfbmFtZSAhPSBOVUxMICYmIFB5U3RyaW5nX0NoZWNrKGRlc2NyLT5kX25hbWUpKQorICAgICAgICByZXR1cm4gUHlTdHJpbmdfQVNfU1RSSU5HKGRlc2NyLT5kX25hbWUpOworICAgIGVsc2UKKyAgICAgICAgcmV0dXJuICI/IjsKK30KKworc3RhdGljIFB5T2JqZWN0ICoKK2Rlc2NyX3JlcHIoUHlEZXNjck9iamVjdCAqZGVzY3IsIGNoYXIgKmZvcm1hdCkKK3sKKyAgICByZXR1cm4gUHlTdHJpbmdfRnJvbUZvcm1hdChmb3JtYXQsIGRlc2NyX25hbWUoZGVzY3IpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRlc2NyLT5kX3R5cGUtPnRwX25hbWUpOworfQorCitzdGF0aWMgUHlPYmplY3QgKgorbWV0aG9kX3JlcHIoUHlNZXRob2REZXNjck9iamVjdCAqZGVzY3IpCit7CisgICAgcmV0dXJuIGRlc2NyX3JlcHIoKFB5RGVzY3JPYmplY3QgKilkZXNjciwKKyAgICAgICAgICAgICAgICAgICAgICAiPG1ldGhvZCAnJXMnIG9mICclcycgb2JqZWN0cz4iKTsKK30KKworc3RhdGljIFB5T2JqZWN0ICoKK21lbWJlcl9yZXByKFB5TWVtYmVyRGVzY3JPYmplY3QgKmRlc2NyKQoreworICAgIHJldHVybiBkZXNjcl9yZXByKChQeURlc2NyT2JqZWN0ICopZGVzY3IsCisgICAgICAgICAgICAgICAgICAgICAgIjxtZW1iZXIgJyVzJyBvZiAnJXMnIG9iamVjdHM+Iik7Cit9CisKK3N0YXRpYyBQeU9iamVjdCAqCitnZXRzZXRfcmVwcihQeUdldFNldERlc2NyT2JqZWN0ICpkZXNjcikKK3sKKyAgICByZXR1cm4gZGVzY3JfcmVwcigoUHlEZXNjck9iamVjdCAqKWRlc2NyLAorICAgICAgICAgICAgICAgICAgICAgICI8YXR0cmlidXRlICclcycgb2YgJyVzJyBvYmplY3RzPiIpOworfQorCitzdGF0aWMgUHlPYmplY3QgKgord3JhcHBlcmRlc2NyX3JlcHIoUHlXcmFwcGVyRGVzY3JPYmplY3QgKmRlc2NyKQoreworICAgIHJldHVybiBkZXNjcl9yZXByKChQeURlc2NyT2JqZWN0ICopZGVzY3IsCisgICAgICAgICAgICAgICAgICAgICAgIjxzbG90IHdyYXBwZXIgJyVzJyBvZiAnJXMnIG9iamVjdHM+Iik7Cit9CisKK3N0YXRpYyBpbnQKK2Rlc2NyX2NoZWNrKFB5RGVzY3JPYmplY3QgKmRlc2NyLCBQeU9iamVjdCAqb2JqLCBQeU9iamVjdCAqKnByZXMpCit7CisgICAgaWYgKG9iaiA9PSBOVUxMKSB7CisgICAgICAgIFB5X0lOQ1JFRihkZXNjcik7CisgICAgICAgICpwcmVzID0gKFB5T2JqZWN0ICopZGVzY3I7CisgICAgICAgIHJldHVybiAxOworICAgIH0KKyAgICBpZiAoIVB5T2JqZWN0X1R5cGVDaGVjayhvYmosIGRlc2NyLT5kX3R5cGUpKSB7CisgICAgICAgIFB5RXJyX0Zvcm1hdChQeUV4Y19UeXBlRXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAiZGVzY3JpcHRvciAnJXMnIGZvciAnJXMnIG9iamVjdHMgIgorICAgICAgICAgICAgICAgICAgICAgImRvZXNuJ3QgYXBwbHkgdG8gJyVzJyBvYmplY3QiLAorICAgICAgICAgICAgICAgICAgICAgZGVzY3JfbmFtZSgoUHlEZXNjck9iamVjdCAqKWRlc2NyKSwKKyAgICAgICAgICAgICAgICAgICAgIGRlc2NyLT5kX3R5cGUtPnRwX25hbWUsCisgICAgICAgICAgICAgICAgICAgICBvYmotPm9iX3R5cGUtPnRwX25hbWUpOworICAgICAgICAqcHJlcyA9IE5VTEw7CisgICAgICAgIHJldHVybiAxOworICAgIH0KKyAgICByZXR1cm4gMDsKK30KKworc3RhdGljIFB5T2JqZWN0ICoKK2NsYXNzbWV0aG9kX2dldChQeU1ldGhvZERlc2NyT2JqZWN0ICpkZXNjciwgUHlPYmplY3QgKm9iaiwgUHlPYmplY3QgKnR5cGUpCit7CisgICAgLyogRW5zdXJlIGEgdmFsaWQgdHlwZS4gIENsYXNzIG1ldGhvZHMgaWdub3JlIG9iai4gKi8KKyAgICBpZiAodHlwZSA9PSBOVUxMKSB7CisgICAgICAgIGlmIChvYmogIT0gTlVMTCkKKyAgICAgICAgICAgIHR5cGUgPSAoUHlPYmplY3QgKilvYmotPm9iX3R5cGU7CisgICAgICAgIGVsc2UgeworICAgICAgICAgICAgLyogV290IC0gbm8gdHlwZT8hICovCisgICAgICAgICAgICBQeUVycl9Gb3JtYXQoUHlFeGNfVHlwZUVycm9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICJkZXNjcmlwdG9yICclcycgZm9yIHR5cGUgJyVzJyAiCisgICAgICAgICAgICAgICAgICAgICAgICAgIm5lZWRzIGVpdGhlciBhbiBvYmplY3Qgb3IgYSB0eXBlIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICBkZXNjcl9uYW1lKChQeURlc2NyT2JqZWN0ICopZGVzY3IpLAorICAgICAgICAgICAgICAgICAgICAgICAgIGRlc2NyLT5kX3R5cGUtPnRwX25hbWUpOworICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgICAgIH0KKyAgICB9CisgICAgaWYgKCFQeVR5cGVfQ2hlY2sodHlwZSkpIHsKKyAgICAgICAgUHlFcnJfRm9ybWF0KFB5RXhjX1R5cGVFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICJkZXNjcmlwdG9yICclcycgZm9yIHR5cGUgJyVzJyAiCisgICAgICAgICAgICAgICAgICAgICAibmVlZHMgYSB0eXBlLCBub3QgYSAnJXMnIGFzIGFyZyAyIiwKKyAgICAgICAgICAgICAgICAgICAgIGRlc2NyX25hbWUoKFB5RGVzY3JPYmplY3QgKilkZXNjciksCisgICAgICAgICAgICAgICAgICAgICBkZXNjci0+ZF90eXBlLT50cF9uYW1lLAorICAgICAgICAgICAgICAgICAgICAgdHlwZS0+b2JfdHlwZS0+dHBfbmFtZSk7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICBpZiAoIVB5VHlwZV9Jc1N1YnR5cGUoKFB5VHlwZU9iamVjdCAqKXR5cGUsIGRlc2NyLT5kX3R5cGUpKSB7CisgICAgICAgIFB5RXJyX0Zvcm1hdChQeUV4Y19UeXBlRXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAiZGVzY3JpcHRvciAnJXMnIGZvciB0eXBlICclcycgIgorICAgICAgICAgICAgICAgICAgICAgImRvZXNuJ3QgYXBwbHkgdG8gdHlwZSAnJXMnIiwKKyAgICAgICAgICAgICAgICAgICAgIGRlc2NyX25hbWUoKFB5RGVzY3JPYmplY3QgKilkZXNjciksCisgICAgICAgICAgICAgICAgICAgICBkZXNjci0+ZF90eXBlLT50cF9uYW1lLAorICAgICAgICAgICAgICAgICAgICAgKChQeVR5cGVPYmplY3QgKil0eXBlKS0+dHBfbmFtZSk7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICByZXR1cm4gUHlDRnVuY3Rpb25fTmV3KGRlc2NyLT5kX21ldGhvZCwgdHlwZSk7Cit9CisKK3N0YXRpYyBQeU9iamVjdCAqCittZXRob2RfZ2V0KFB5TWV0aG9kRGVzY3JPYmplY3QgKmRlc2NyLCBQeU9iamVjdCAqb2JqLCBQeU9iamVjdCAqdHlwZSkKK3sKKyAgICBQeU9iamVjdCAqcmVzOworCisgICAgaWYgKGRlc2NyX2NoZWNrKChQeURlc2NyT2JqZWN0ICopZGVzY3IsIG9iaiwgJnJlcykpCisgICAgICAgIHJldHVybiByZXM7CisgICAgcmV0dXJuIFB5Q0Z1bmN0aW9uX05ldyhkZXNjci0+ZF9tZXRob2QsIG9iaik7Cit9CisKK3N0YXRpYyBQeU9iamVjdCAqCittZW1iZXJfZ2V0KFB5TWVtYmVyRGVzY3JPYmplY3QgKmRlc2NyLCBQeU9iamVjdCAqb2JqLCBQeU9iamVjdCAqdHlwZSkKK3sKKyAgICBQeU9iamVjdCAqcmVzOworCisgICAgaWYgKGRlc2NyX2NoZWNrKChQeURlc2NyT2JqZWN0ICopZGVzY3IsIG9iaiwgJnJlcykpCisgICAgICAgIHJldHVybiByZXM7CisgICAgcmV0dXJuIFB5TWVtYmVyX0dldE9uZSgoY2hhciAqKW9iaiwgZGVzY3ItPmRfbWVtYmVyKTsKK30KKworc3RhdGljIFB5T2JqZWN0ICoKK2dldHNldF9nZXQoUHlHZXRTZXREZXNjck9iamVjdCAqZGVzY3IsIFB5T2JqZWN0ICpvYmosIFB5T2JqZWN0ICp0eXBlKQoreworICAgIFB5T2JqZWN0ICpyZXM7CisKKyAgICBpZiAoZGVzY3JfY2hlY2soKFB5RGVzY3JPYmplY3QgKilkZXNjciwgb2JqLCAmcmVzKSkKKyAgICAgICAgcmV0dXJuIHJlczsKKyAgICBpZiAoZGVzY3ItPmRfZ2V0c2V0LT5nZXQgIT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIGRlc2NyLT5kX2dldHNldC0+Z2V0KG9iaiwgZGVzY3ItPmRfZ2V0c2V0LT5jbG9zdXJlKTsKKyAgICBQeUVycl9Gb3JtYXQoUHlFeGNfQXR0cmlidXRlRXJyb3IsCisgICAgICAgICAgICAgICAgICJhdHRyaWJ1dGUgJyUuMzAwcycgb2YgJyUuMTAwcycgb2JqZWN0cyBpcyBub3QgcmVhZGFibGUiLAorICAgICAgICAgICAgICAgICBkZXNjcl9uYW1lKChQeURlc2NyT2JqZWN0ICopZGVzY3IpLAorICAgICAgICAgICAgICAgICBkZXNjci0+ZF90eXBlLT50cF9uYW1lKTsKKyAgICByZXR1cm4gTlVMTDsKK30KKworc3RhdGljIFB5T2JqZWN0ICoKK3dyYXBwZXJkZXNjcl9nZXQoUHlXcmFwcGVyRGVzY3JPYmplY3QgKmRlc2NyLCBQeU9iamVjdCAqb2JqLCBQeU9iamVjdCAqdHlwZSkKK3sKKyAgICBQeU9iamVjdCAqcmVzOworCisgICAgaWYgKGRlc2NyX2NoZWNrKChQeURlc2NyT2JqZWN0ICopZGVzY3IsIG9iaiwgJnJlcykpCisgICAgICAgIHJldHVybiByZXM7CisgICAgcmV0dXJuIFB5V3JhcHBlcl9OZXcoKFB5T2JqZWN0ICopZGVzY3IsIG9iaik7Cit9CisKK3N0YXRpYyBpbnQKK2Rlc2NyX3NldGNoZWNrKFB5RGVzY3JPYmplY3QgKmRlc2NyLCBQeU9iamVjdCAqb2JqLCBQeU9iamVjdCAqdmFsdWUsCisgICAgICAgICAgICAgICBpbnQgKnByZXMpCit7CisgICAgYXNzZXJ0KG9iaiAhPSBOVUxMKTsKKyAgICBpZiAoIVB5T2JqZWN0X1R5cGVDaGVjayhvYmosIGRlc2NyLT5kX3R5cGUpKSB7CisgICAgICAgIFB5RXJyX0Zvcm1hdChQeUV4Y19UeXBlRXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAiZGVzY3JpcHRvciAnJS4yMDBzJyBmb3IgJyUuMTAwcycgb2JqZWN0cyAiCisgICAgICAgICAgICAgICAgICAgICAiZG9lc24ndCBhcHBseSB0byAnJS4xMDBzJyBvYmplY3QiLAorICAgICAgICAgICAgICAgICAgICAgZGVzY3JfbmFtZShkZXNjciksCisgICAgICAgICAgICAgICAgICAgICBkZXNjci0+ZF90eXBlLT50cF9uYW1lLAorICAgICAgICAgICAgICAgICAgICAgb2JqLT5vYl90eXBlLT50cF9uYW1lKTsKKyAgICAgICAgKnByZXMgPSAtMTsKKyAgICAgICAgcmV0dXJuIDE7CisgICAgfQorICAgIHJldHVybiAwOworfQorCitzdGF0aWMgaW50CittZW1iZXJfc2V0KFB5TWVtYmVyRGVzY3JPYmplY3QgKmRlc2NyLCBQeU9iamVjdCAqb2JqLCBQeU9iamVjdCAqdmFsdWUpCit7CisgICAgaW50IHJlczsKKworICAgIGlmIChkZXNjcl9zZXRjaGVjaygoUHlEZXNjck9iamVjdCAqKWRlc2NyLCBvYmosIHZhbHVlLCAmcmVzKSkKKyAgICAgICAgcmV0dXJuIHJlczsKKyAgICByZXR1cm4gUHlNZW1iZXJfU2V0T25lKChjaGFyICopb2JqLCBkZXNjci0+ZF9tZW1iZXIsIHZhbHVlKTsKK30KKworc3RhdGljIGludAorZ2V0c2V0X3NldChQeUdldFNldERlc2NyT2JqZWN0ICpkZXNjciwgUHlPYmplY3QgKm9iaiwgUHlPYmplY3QgKnZhbHVlKQoreworICAgIGludCByZXM7CisKKyAgICBpZiAoZGVzY3Jfc2V0Y2hlY2soKFB5RGVzY3JPYmplY3QgKilkZXNjciwgb2JqLCB2YWx1ZSwgJnJlcykpCisgICAgICAgIHJldHVybiByZXM7CisgICAgaWYgKGRlc2NyLT5kX2dldHNldC0+c2V0ICE9IE5VTEwpCisgICAgICAgIHJldHVybiBkZXNjci0+ZF9nZXRzZXQtPnNldChvYmosIHZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGVzY3ItPmRfZ2V0c2V0LT5jbG9zdXJlKTsKKyAgICBQeUVycl9Gb3JtYXQoUHlFeGNfQXR0cmlidXRlRXJyb3IsCisgICAgICAgICAgICAgICAgICJhdHRyaWJ1dGUgJyUuMzAwcycgb2YgJyUuMTAwcycgb2JqZWN0cyBpcyBub3Qgd3JpdGFibGUiLAorICAgICAgICAgICAgICAgICBkZXNjcl9uYW1lKChQeURlc2NyT2JqZWN0ICopZGVzY3IpLAorICAgICAgICAgICAgICAgICBkZXNjci0+ZF90eXBlLT50cF9uYW1lKTsKKyAgICByZXR1cm4gLTE7Cit9CisKK3N0YXRpYyBQeU9iamVjdCAqCittZXRob2RkZXNjcl9jYWxsKFB5TWV0aG9kRGVzY3JPYmplY3QgKmRlc2NyLCBQeU9iamVjdCAqYXJncywgUHlPYmplY3QgKmt3ZHMpCit7CisgICAgUHlfc3NpemVfdCBhcmdjOworICAgIFB5T2JqZWN0ICpzZWxmLCAqZnVuYywgKnJlc3VsdDsKKworICAgIC8qIE1ha2Ugc3VyZSB0aGF0IHRoZSBmaXJzdCBhcmd1bWVudCBpcyBhY2NlcHRhYmxlIGFzICdzZWxmJyAqLworICAgIGFzc2VydChQeVR1cGxlX0NoZWNrKGFyZ3MpKTsKKyAgICBhcmdjID0gUHlUdXBsZV9HRVRfU0laRShhcmdzKTsKKyAgICBpZiAoYXJnYyA8IDEpIHsKKyAgICAgICAgUHlFcnJfRm9ybWF0KFB5RXhjX1R5cGVFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICJkZXNjcmlwdG9yICclLjMwMHMnIG9mICclLjEwMHMnICIKKyAgICAgICAgICAgICAgICAgICAgICJvYmplY3QgbmVlZHMgYW4gYXJndW1lbnQiLAorICAgICAgICAgICAgICAgICAgICAgZGVzY3JfbmFtZSgoUHlEZXNjck9iamVjdCAqKWRlc2NyKSwKKyAgICAgICAgICAgICAgICAgICAgIGRlc2NyLT5kX3R5cGUtPnRwX25hbWUpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgc2VsZiA9IFB5VHVwbGVfR0VUX0lURU0oYXJncywgMCk7CisgICAgaWYgKCFfUHlPYmplY3RfUmVhbElzU3ViY2xhc3MoKFB5T2JqZWN0ICopUHlfVFlQRShzZWxmKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoUHlPYmplY3QgKikoZGVzY3ItPmRfdHlwZSkpKSB7CisgICAgICAgIFB5RXJyX0Zvcm1hdChQeUV4Y19UeXBlRXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAiZGVzY3JpcHRvciAnJS4yMDBzJyAiCisgICAgICAgICAgICAgICAgICAgICAicmVxdWlyZXMgYSAnJS4xMDBzJyBvYmplY3QgIgorICAgICAgICAgICAgICAgICAgICAgImJ1dCByZWNlaXZlZCBhICclLjEwMHMnIiwKKyAgICAgICAgICAgICAgICAgICAgIGRlc2NyX25hbWUoKFB5RGVzY3JPYmplY3QgKilkZXNjciksCisgICAgICAgICAgICAgICAgICAgICBkZXNjci0+ZF90eXBlLT50cF9uYW1lLAorICAgICAgICAgICAgICAgICAgICAgc2VsZi0+b2JfdHlwZS0+dHBfbmFtZSk7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKworICAgIGZ1bmMgPSBQeUNGdW5jdGlvbl9OZXcoZGVzY3ItPmRfbWV0aG9kLCBzZWxmKTsKKyAgICBpZiAoZnVuYyA9PSBOVUxMKQorICAgICAgICByZXR1cm4gTlVMTDsKKyAgICBhcmdzID0gUHlUdXBsZV9HZXRTbGljZShhcmdzLCAxLCBhcmdjKTsKKyAgICBpZiAoYXJncyA9PSBOVUxMKSB7CisgICAgICAgIFB5X0RFQ1JFRihmdW5jKTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIHJlc3VsdCA9IFB5RXZhbF9DYWxsT2JqZWN0V2l0aEtleXdvcmRzKGZ1bmMsIGFyZ3MsIGt3ZHMpOworICAgIFB5X0RFQ1JFRihhcmdzKTsKKyAgICBQeV9ERUNSRUYoZnVuYyk7CisgICAgcmV0dXJuIHJlc3VsdDsKK30KKworc3RhdGljIFB5T2JqZWN0ICoKK2NsYXNzbWV0aG9kZGVzY3JfY2FsbChQeU1ldGhvZERlc2NyT2JqZWN0ICpkZXNjciwgUHlPYmplY3QgKmFyZ3MsCisgICAgICAgICAgICAgICAgICAgICAgUHlPYmplY3QgKmt3ZHMpCit7CisgICAgUHlfc3NpemVfdCBhcmdjOworICAgIFB5T2JqZWN0ICpzZWxmLCAqZnVuYywgKnJlc3VsdDsKKworICAgIC8qIE1ha2Ugc3VyZSB0aGF0IHRoZSBmaXJzdCBhcmd1bWVudCBpcyBhY2NlcHRhYmxlIGFzICdzZWxmJyAqLworICAgIGFzc2VydChQeVR1cGxlX0NoZWNrKGFyZ3MpKTsKKyAgICBhcmdjID0gUHlUdXBsZV9HRVRfU0laRShhcmdzKTsKKyAgICBpZiAoYXJnYyA8IDEpIHsKKyAgICAgICAgUHlFcnJfRm9ybWF0KFB5RXhjX1R5cGVFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICJkZXNjcmlwdG9yICclcycgb2YgJyUuMTAwcycgIgorICAgICAgICAgICAgICAgICAgICAgIm9iamVjdCBuZWVkcyBhbiBhcmd1bWVudCIsCisgICAgICAgICAgICAgICAgICAgICBkZXNjcl9uYW1lKChQeURlc2NyT2JqZWN0ICopZGVzY3IpLAorICAgICAgICAgICAgICAgICAgICAgZGVzY3ItPmRfdHlwZS0+dHBfbmFtZSk7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICBzZWxmID0gUHlUdXBsZV9HRVRfSVRFTShhcmdzLCAwKTsKKyAgICBpZiAoIVB5VHlwZV9DaGVjayhzZWxmKSkgeworICAgICAgICBQeUVycl9Gb3JtYXQoUHlFeGNfVHlwZUVycm9yLAorICAgICAgICAgICAgICAgICAgICAgImRlc2NyaXB0b3IgJyVzJyByZXF1aXJlcyBhIHR5cGUgIgorICAgICAgICAgICAgICAgICAgICAgImJ1dCByZWNlaXZlZCBhICclLjEwMHMnIiwKKyAgICAgICAgICAgICAgICAgICAgIGRlc2NyX25hbWUoKFB5RGVzY3JPYmplY3QgKilkZXNjciksCisgICAgICAgICAgICAgICAgICAgICBzZWxmLT5vYl90eXBlLT50cF9uYW1lKTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIGlmICghUHlUeXBlX0lzU3VidHlwZSgoUHlUeXBlT2JqZWN0ICopc2VsZiwgZGVzY3ItPmRfdHlwZSkpIHsKKyAgICAgICAgUHlFcnJfRm9ybWF0KFB5RXhjX1R5cGVFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICJkZXNjcmlwdG9yICclcycgIgorICAgICAgICAgICAgICAgICAgICAgInJlcXVpcmVzIGEgc3VidHlwZSBvZiAnJS4xMDBzJyAiCisgICAgICAgICAgICAgICAgICAgICAiYnV0IHJlY2VpdmVkICclLjEwMHMiLAorICAgICAgICAgICAgICAgICAgICAgZGVzY3JfbmFtZSgoUHlEZXNjck9iamVjdCAqKWRlc2NyKSwKKyAgICAgICAgICAgICAgICAgICAgIGRlc2NyLT5kX3R5cGUtPnRwX25hbWUsCisgICAgICAgICAgICAgICAgICAgICBzZWxmLT5vYl90eXBlLT50cF9uYW1lKTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorCisgICAgZnVuYyA9IFB5Q0Z1bmN0aW9uX05ldyhkZXNjci0+ZF9tZXRob2QsIHNlbGYpOworICAgIGlmIChmdW5jID09IE5VTEwpCisgICAgICAgIHJldHVybiBOVUxMOworICAgIGFyZ3MgPSBQeVR1cGxlX0dldFNsaWNlKGFyZ3MsIDEsIGFyZ2MpOworICAgIGlmIChhcmdzID09IE5VTEwpIHsKKyAgICAgICAgUHlfREVDUkVGKGZ1bmMpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgcmVzdWx0ID0gUHlFdmFsX0NhbGxPYmplY3RXaXRoS2V5d29yZHMoZnVuYywgYXJncywga3dkcyk7CisgICAgUHlfREVDUkVGKGZ1bmMpOworICAgIFB5X0RFQ1JFRihhcmdzKTsKKyAgICByZXR1cm4gcmVzdWx0OworfQorCitzdGF0aWMgUHlPYmplY3QgKgord3JhcHBlcmRlc2NyX2NhbGwoUHlXcmFwcGVyRGVzY3JPYmplY3QgKmRlc2NyLCBQeU9iamVjdCAqYXJncywgUHlPYmplY3QgKmt3ZHMpCit7CisgICAgUHlfc3NpemVfdCBhcmdjOworICAgIFB5T2JqZWN0ICpzZWxmLCAqZnVuYywgKnJlc3VsdDsKKworICAgIC8qIE1ha2Ugc3VyZSB0aGF0IHRoZSBmaXJzdCBhcmd1bWVudCBpcyBhY2NlcHRhYmxlIGFzICdzZWxmJyAqLworICAgIGFzc2VydChQeVR1cGxlX0NoZWNrKGFyZ3MpKTsKKyAgICBhcmdjID0gUHlUdXBsZV9HRVRfU0laRShhcmdzKTsKKyAgICBpZiAoYXJnYyA8IDEpIHsKKyAgICAgICAgUHlFcnJfRm9ybWF0KFB5RXhjX1R5cGVFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICJkZXNjcmlwdG9yICclLjMwMHMnIG9mICclLjEwMHMnICIKKyAgICAgICAgICAgICAgICAgICAgICJvYmplY3QgbmVlZHMgYW4gYXJndW1lbnQiLAorICAgICAgICAgICAgICAgICAgICAgZGVzY3JfbmFtZSgoUHlEZXNjck9iamVjdCAqKWRlc2NyKSwKKyAgICAgICAgICAgICAgICAgICAgIGRlc2NyLT5kX3R5cGUtPnRwX25hbWUpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgc2VsZiA9IFB5VHVwbGVfR0VUX0lURU0oYXJncywgMCk7CisgICAgaWYgKCFfUHlPYmplY3RfUmVhbElzU3ViY2xhc3MoKFB5T2JqZWN0ICopUHlfVFlQRShzZWxmKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoUHlPYmplY3QgKikoZGVzY3ItPmRfdHlwZSkpKSB7CisgICAgICAgIFB5RXJyX0Zvcm1hdChQeUV4Y19UeXBlRXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAiZGVzY3JpcHRvciAnJS4yMDBzJyAiCisgICAgICAgICAgICAgICAgICAgICAicmVxdWlyZXMgYSAnJS4xMDBzJyBvYmplY3QgIgorICAgICAgICAgICAgICAgICAgICAgImJ1dCByZWNlaXZlZCBhICclLjEwMHMnIiwKKyAgICAgICAgICAgICAgICAgICAgIGRlc2NyX25hbWUoKFB5RGVzY3JPYmplY3QgKilkZXNjciksCisgICAgICAgICAgICAgICAgICAgICBkZXNjci0+ZF90eXBlLT50cF9uYW1lLAorICAgICAgICAgICAgICAgICAgICAgc2VsZi0+b2JfdHlwZS0+dHBfbmFtZSk7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKworICAgIGZ1bmMgPSBQeVdyYXBwZXJfTmV3KChQeU9iamVjdCAqKWRlc2NyLCBzZWxmKTsKKyAgICBpZiAoZnVuYyA9PSBOVUxMKQorICAgICAgICByZXR1cm4gTlVMTDsKKyAgICBhcmdzID0gUHlUdXBsZV9HZXRTbGljZShhcmdzLCAxLCBhcmdjKTsKKyAgICBpZiAoYXJncyA9PSBOVUxMKSB7CisgICAgICAgIFB5X0RFQ1JFRihmdW5jKTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIHJlc3VsdCA9IFB5RXZhbF9DYWxsT2JqZWN0V2l0aEtleXdvcmRzKGZ1bmMsIGFyZ3MsIGt3ZHMpOworICAgIFB5X0RFQ1JFRihhcmdzKTsKKyAgICBQeV9ERUNSRUYoZnVuYyk7CisgICAgcmV0dXJuIHJlc3VsdDsKK30KKworc3RhdGljIFB5T2JqZWN0ICoKK21ldGhvZF9nZXRfZG9jKFB5TWV0aG9kRGVzY3JPYmplY3QgKmRlc2NyLCB2b2lkICpjbG9zdXJlKQoreworICAgIGlmIChkZXNjci0+ZF9tZXRob2QtPm1sX2RvYyA9PSBOVUxMKSB7CisgICAgICAgIFB5X0lOQ1JFRihQeV9Ob25lKTsKKyAgICAgICAgcmV0dXJuIFB5X05vbmU7CisgICAgfQorICAgIHJldHVybiBQeVN0cmluZ19Gcm9tU3RyaW5nKGRlc2NyLT5kX21ldGhvZC0+bWxfZG9jKTsKK30KKworc3RhdGljIFB5TWVtYmVyRGVmIGRlc2NyX21lbWJlcnNbXSA9IHsKKyAgICB7Il9fb2JqY2xhc3NfXyIsIFRfT0JKRUNULCBvZmZzZXRvZihQeURlc2NyT2JqZWN0LCBkX3R5cGUpLCBSRUFET05MWX0sCisgICAgeyJfX25hbWVfXyIsIFRfT0JKRUNULCBvZmZzZXRvZihQeURlc2NyT2JqZWN0LCBkX25hbWUpLCBSRUFET05MWX0sCisgICAgezB9Cit9OworCitzdGF0aWMgUHlHZXRTZXREZWYgbWV0aG9kX2dldHNldFtdID0geworICAgIHsiX19kb2NfXyIsIChnZXR0ZXIpbWV0aG9kX2dldF9kb2N9LAorICAgIHswfQorfTsKKworc3RhdGljIFB5T2JqZWN0ICoKK21lbWJlcl9nZXRfZG9jKFB5TWVtYmVyRGVzY3JPYmplY3QgKmRlc2NyLCB2b2lkICpjbG9zdXJlKQoreworICAgIGlmIChkZXNjci0+ZF9tZW1iZXItPmRvYyA9PSBOVUxMKSB7CisgICAgICAgIFB5X0lOQ1JFRihQeV9Ob25lKTsKKyAgICAgICAgcmV0dXJuIFB5X05vbmU7CisgICAgfQorICAgIHJldHVybiBQeVN0cmluZ19Gcm9tU3RyaW5nKGRlc2NyLT5kX21lbWJlci0+ZG9jKTsKK30KKworc3RhdGljIFB5R2V0U2V0RGVmIG1lbWJlcl9nZXRzZXRbXSA9IHsKKyAgICB7Il9fZG9jX18iLCAoZ2V0dGVyKW1lbWJlcl9nZXRfZG9jfSwKKyAgICB7MH0KK307CisKK3N0YXRpYyBQeU9iamVjdCAqCitnZXRzZXRfZ2V0X2RvYyhQeUdldFNldERlc2NyT2JqZWN0ICpkZXNjciwgdm9pZCAqY2xvc3VyZSkKK3sKKyAgICBpZiAoZGVzY3ItPmRfZ2V0c2V0LT5kb2MgPT0gTlVMTCkgeworICAgICAgICBQeV9JTkNSRUYoUHlfTm9uZSk7CisgICAgICAgIHJldHVybiBQeV9Ob25lOworICAgIH0KKyAgICByZXR1cm4gUHlTdHJpbmdfRnJvbVN0cmluZyhkZXNjci0+ZF9nZXRzZXQtPmRvYyk7Cit9CisKK3N0YXRpYyBQeUdldFNldERlZiBnZXRzZXRfZ2V0c2V0W10gPSB7CisgICAgeyJfX2RvY19fIiwgKGdldHRlcilnZXRzZXRfZ2V0X2RvY30sCisgICAgezB9Cit9OworCitzdGF0aWMgUHlPYmplY3QgKgord3JhcHBlcmRlc2NyX2dldF9kb2MoUHlXcmFwcGVyRGVzY3JPYmplY3QgKmRlc2NyLCB2b2lkICpjbG9zdXJlKQoreworICAgIGlmIChkZXNjci0+ZF9iYXNlLT5kb2MgPT0gTlVMTCkgeworICAgICAgICBQeV9JTkNSRUYoUHlfTm9uZSk7CisgICAgICAgIHJldHVybiBQeV9Ob25lOworICAgIH0KKyAgICByZXR1cm4gUHlTdHJpbmdfRnJvbVN0cmluZyhkZXNjci0+ZF9iYXNlLT5kb2MpOworfQorCitzdGF0aWMgUHlHZXRTZXREZWYgd3JhcHBlcmRlc2NyX2dldHNldFtdID0geworICAgIHsiX19kb2NfXyIsIChnZXR0ZXIpd3JhcHBlcmRlc2NyX2dldF9kb2N9LAorICAgIHswfQorfTsKKworc3RhdGljIGludAorZGVzY3JfdHJhdmVyc2UoUHlPYmplY3QgKnNlbGYsIHZpc2l0cHJvYyB2aXNpdCwgdm9pZCAqYXJnKQoreworICAgIFB5RGVzY3JPYmplY3QgKmRlc2NyID0gKFB5RGVzY3JPYmplY3QgKilzZWxmOworICAgIFB5X1ZJU0lUKGRlc2NyLT5kX3R5cGUpOworICAgIHJldHVybiAwOworfQorCitzdGF0aWMgUHlUeXBlT2JqZWN0IFB5TWV0aG9kRGVzY3JfVHlwZSA9IHsKKyAgICBQeVZhck9iamVjdF9IRUFEX0lOSVQoJlB5VHlwZV9UeXBlLCAwKQorICAgICJtZXRob2RfZGVzY3JpcHRvciIsCisgICAgc2l6ZW9mKFB5TWV0aG9kRGVzY3JPYmplY3QpLAorICAgIDAsCisgICAgKGRlc3RydWN0b3IpZGVzY3JfZGVhbGxvYywgICAgICAgICAgICAgICAgICAvKiB0cF9kZWFsbG9jICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9wcmludCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZ2V0YXR0ciAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfc2V0YXR0ciAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfY29tcGFyZSAqLworICAgIChyZXByZnVuYyltZXRob2RfcmVwciwgICAgICAgICAgICAgICAgICAgICAgLyogdHBfcmVwciAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfYXNfbnVtYmVyICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9hc19zZXF1ZW5jZSAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfYXNfbWFwcGluZyAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfaGFzaCAqLworICAgICh0ZXJuYXJ5ZnVuYyltZXRob2RkZXNjcl9jYWxsLCAgICAgICAgICAgICAgLyogdHBfY2FsbCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfc3RyICovCisgICAgUHlPYmplY3RfR2VuZXJpY0dldEF0dHIsICAgICAgICAgICAgICAgICAgICAvKiB0cF9nZXRhdHRybyAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfc2V0YXR0cm8gKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2FzX2J1ZmZlciAqLworICAgIFB5X1RQRkxBR1NfREVGQVVMVCB8IFB5X1RQRkxBR1NfSEFWRV9HQywgLyogdHBfZmxhZ3MgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2RvYyAqLworICAgIGRlc2NyX3RyYXZlcnNlLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfdHJhdmVyc2UgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2NsZWFyICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9yaWNoY29tcGFyZSAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfd2Vha2xpc3RvZmZzZXQgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2l0ZXIgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2l0ZXJuZXh0ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9tZXRob2RzICovCisgICAgZGVzY3JfbWVtYmVycywgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9tZW1iZXJzICovCisgICAgbWV0aG9kX2dldHNldCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9nZXRzZXQgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2Jhc2UgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2RpY3QgKi8KKyAgICAoZGVzY3JnZXRmdW5jKW1ldGhvZF9nZXQsICAgICAgICAgICAgICAgICAgIC8qIHRwX2Rlc2NyX2dldCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZGVzY3Jfc2V0ICovCit9OworCisvKiBUaGlzIGlzIGZvciBNRVRIX0NMQVNTIGluIEMsIG5vdCBmb3IgImYgPSBjbGFzc21ldGhvZChmKSIgaW4gUHl0aG9uISAqLworc3RhdGljIFB5VHlwZU9iamVjdCBQeUNsYXNzTWV0aG9kRGVzY3JfVHlwZSA9IHsKKyAgICBQeVZhck9iamVjdF9IRUFEX0lOSVQoJlB5VHlwZV9UeXBlLCAwKQorICAgICJjbGFzc21ldGhvZF9kZXNjcmlwdG9yIiwKKyAgICBzaXplb2YoUHlNZXRob2REZXNjck9iamVjdCksCisgICAgMCwKKyAgICAoZGVzdHJ1Y3RvcilkZXNjcl9kZWFsbG9jLCAgICAgICAgICAgICAgICAgIC8qIHRwX2RlYWxsb2MgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3ByaW50ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9nZXRhdHRyICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9zZXRhdHRyICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9jb21wYXJlICovCisgICAgKHJlcHJmdW5jKW1ldGhvZF9yZXByLCAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9yZXByICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9hc19udW1iZXIgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2FzX3NlcXVlbmNlICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9hc19tYXBwaW5nICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9oYXNoICovCisgICAgKHRlcm5hcnlmdW5jKWNsYXNzbWV0aG9kZGVzY3JfY2FsbCwgICAgICAgICAvKiB0cF9jYWxsICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9zdHIgKi8KKyAgICBQeU9iamVjdF9HZW5lcmljR2V0QXR0ciwgICAgICAgICAgICAgICAgICAgIC8qIHRwX2dldGF0dHJvICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9zZXRhdHRybyAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfYXNfYnVmZmVyICovCisgICAgUHlfVFBGTEFHU19ERUZBVUxUIHwgUHlfVFBGTEFHU19IQVZFX0dDLCAvKiB0cF9mbGFncyAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZG9jICovCisgICAgZGVzY3JfdHJhdmVyc2UsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF90cmF2ZXJzZSAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfY2xlYXIgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3JpY2hjb21wYXJlICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF93ZWFrbGlzdG9mZnNldCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfaXRlciAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfaXRlcm5leHQgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX21ldGhvZHMgKi8KKyAgICBkZXNjcl9tZW1iZXJzLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX21lbWJlcnMgKi8KKyAgICBtZXRob2RfZ2V0c2V0LCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2dldHNldCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfYmFzZSAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZGljdCAqLworICAgIChkZXNjcmdldGZ1bmMpY2xhc3NtZXRob2RfZ2V0LCAgICAgICAgICAgICAgLyogdHBfZGVzY3JfZ2V0ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9kZXNjcl9zZXQgKi8KK307CisKK1B5VHlwZU9iamVjdCBQeU1lbWJlckRlc2NyX1R5cGUgPSB7CisgICAgUHlWYXJPYmplY3RfSEVBRF9JTklUKCZQeVR5cGVfVHlwZSwgMCkKKyAgICAibWVtYmVyX2Rlc2NyaXB0b3IiLAorICAgIHNpemVvZihQeU1lbWJlckRlc2NyT2JqZWN0KSwKKyAgICAwLAorICAgIChkZXN0cnVjdG9yKWRlc2NyX2RlYWxsb2MsICAgICAgICAgICAgICAgICAgLyogdHBfZGVhbGxvYyAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfcHJpbnQgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2dldGF0dHIgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3NldGF0dHIgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2NvbXBhcmUgKi8KKyAgICAocmVwcmZ1bmMpbWVtYmVyX3JlcHIsICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3JlcHIgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2FzX251bWJlciAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfYXNfc2VxdWVuY2UgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2FzX21hcHBpbmcgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2hhc2ggKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2NhbGwgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3N0ciAqLworICAgIFB5T2JqZWN0X0dlbmVyaWNHZXRBdHRyLCAgICAgICAgICAgICAgICAgICAgLyogdHBfZ2V0YXR0cm8gKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3NldGF0dHJvICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9hc19idWZmZXIgKi8KKyAgICBQeV9UUEZMQUdTX0RFRkFVTFQgfCBQeV9UUEZMQUdTX0hBVkVfR0MsIC8qIHRwX2ZsYWdzICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9kb2MgKi8KKyAgICBkZXNjcl90cmF2ZXJzZSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3RyYXZlcnNlICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9jbGVhciAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfcmljaGNvbXBhcmUgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3dlYWtsaXN0b2Zmc2V0ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9pdGVyICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9pdGVybmV4dCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfbWV0aG9kcyAqLworICAgIGRlc2NyX21lbWJlcnMsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfbWVtYmVycyAqLworICAgIG1lbWJlcl9nZXRzZXQsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZ2V0c2V0ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9iYXNlICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9kaWN0ICovCisgICAgKGRlc2NyZ2V0ZnVuYyltZW1iZXJfZ2V0LCAgICAgICAgICAgICAgICAgICAvKiB0cF9kZXNjcl9nZXQgKi8KKyAgICAoZGVzY3JzZXRmdW5jKW1lbWJlcl9zZXQsICAgICAgICAgICAgICAgICAgIC8qIHRwX2Rlc2NyX3NldCAqLworfTsKKworUHlUeXBlT2JqZWN0IFB5R2V0U2V0RGVzY3JfVHlwZSA9IHsKKyAgICBQeVZhck9iamVjdF9IRUFEX0lOSVQoJlB5VHlwZV9UeXBlLCAwKQorICAgICJnZXRzZXRfZGVzY3JpcHRvciIsCisgICAgc2l6ZW9mKFB5R2V0U2V0RGVzY3JPYmplY3QpLAorICAgIDAsCisgICAgKGRlc3RydWN0b3IpZGVzY3JfZGVhbGxvYywgICAgICAgICAgICAgICAgICAvKiB0cF9kZWFsbG9jICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9wcmludCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZ2V0YXR0ciAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfc2V0YXR0ciAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfY29tcGFyZSAqLworICAgIChyZXByZnVuYylnZXRzZXRfcmVwciwgICAgICAgICAgICAgICAgICAgICAgLyogdHBfcmVwciAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfYXNfbnVtYmVyICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9hc19zZXF1ZW5jZSAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfYXNfbWFwcGluZyAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfaGFzaCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfY2FsbCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfc3RyICovCisgICAgUHlPYmplY3RfR2VuZXJpY0dldEF0dHIsICAgICAgICAgICAgICAgICAgICAvKiB0cF9nZXRhdHRybyAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfc2V0YXR0cm8gKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2FzX2J1ZmZlciAqLworICAgIFB5X1RQRkxBR1NfREVGQVVMVCB8IFB5X1RQRkxBR1NfSEFWRV9HQywgLyogdHBfZmxhZ3MgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2RvYyAqLworICAgIGRlc2NyX3RyYXZlcnNlLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfdHJhdmVyc2UgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2NsZWFyICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9yaWNoY29tcGFyZSAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfd2Vha2xpc3RvZmZzZXQgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2l0ZXIgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2l0ZXJuZXh0ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9tZXRob2RzICovCisgICAgZGVzY3JfbWVtYmVycywgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9tZW1iZXJzICovCisgICAgZ2V0c2V0X2dldHNldCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9nZXRzZXQgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2Jhc2UgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2RpY3QgKi8KKyAgICAoZGVzY3JnZXRmdW5jKWdldHNldF9nZXQsICAgICAgICAgICAgICAgICAgIC8qIHRwX2Rlc2NyX2dldCAqLworICAgIChkZXNjcnNldGZ1bmMpZ2V0c2V0X3NldCwgICAgICAgICAgICAgICAgICAgLyogdHBfZGVzY3Jfc2V0ICovCit9OworCitQeVR5cGVPYmplY3QgUHlXcmFwcGVyRGVzY3JfVHlwZSA9IHsKKyAgICBQeVZhck9iamVjdF9IRUFEX0lOSVQoJlB5VHlwZV9UeXBlLCAwKQorICAgICJ3cmFwcGVyX2Rlc2NyaXB0b3IiLAorICAgIHNpemVvZihQeVdyYXBwZXJEZXNjck9iamVjdCksCisgICAgMCwKKyAgICAoZGVzdHJ1Y3RvcilkZXNjcl9kZWFsbG9jLCAgICAgICAgICAgICAgICAgIC8qIHRwX2RlYWxsb2MgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3ByaW50ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9nZXRhdHRyICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9zZXRhdHRyICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9jb21wYXJlICovCisgICAgKHJlcHJmdW5jKXdyYXBwZXJkZXNjcl9yZXByLCAgICAgICAgICAgICAgICAvKiB0cF9yZXByICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9hc19udW1iZXIgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2FzX3NlcXVlbmNlICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9hc19tYXBwaW5nICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9oYXNoICovCisgICAgKHRlcm5hcnlmdW5jKXdyYXBwZXJkZXNjcl9jYWxsLCAgICAgICAgICAgICAvKiB0cF9jYWxsICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9zdHIgKi8KKyAgICBQeU9iamVjdF9HZW5lcmljR2V0QXR0ciwgICAgICAgICAgICAgICAgICAgIC8qIHRwX2dldGF0dHJvICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9zZXRhdHRybyAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfYXNfYnVmZmVyICovCisgICAgUHlfVFBGTEFHU19ERUZBVUxUIHwgUHlfVFBGTEFHU19IQVZFX0dDLCAvKiB0cF9mbGFncyAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZG9jICovCisgICAgZGVzY3JfdHJhdmVyc2UsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF90cmF2ZXJzZSAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfY2xlYXIgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3JpY2hjb21wYXJlICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF93ZWFrbGlzdG9mZnNldCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfaXRlciAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfaXRlcm5leHQgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX21ldGhvZHMgKi8KKyAgICBkZXNjcl9tZW1iZXJzLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX21lbWJlcnMgKi8KKyAgICB3cmFwcGVyZGVzY3JfZ2V0c2V0LCAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2dldHNldCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfYmFzZSAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZGljdCAqLworICAgIChkZXNjcmdldGZ1bmMpd3JhcHBlcmRlc2NyX2dldCwgICAgICAgICAgICAgLyogdHBfZGVzY3JfZ2V0ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9kZXNjcl9zZXQgKi8KK307CisKK3N0YXRpYyBQeURlc2NyT2JqZWN0ICoKK2Rlc2NyX25ldyhQeVR5cGVPYmplY3QgKmRlc2NydHlwZSwgUHlUeXBlT2JqZWN0ICp0eXBlLCBjb25zdCBjaGFyICpuYW1lKQoreworICAgIFB5RGVzY3JPYmplY3QgKmRlc2NyOworCisgICAgZGVzY3IgPSAoUHlEZXNjck9iamVjdCAqKVB5VHlwZV9HZW5lcmljQWxsb2MoZGVzY3J0eXBlLCAwKTsKKyAgICBpZiAoZGVzY3IgIT0gTlVMTCkgeworICAgICAgICBQeV9YSU5DUkVGKHR5cGUpOworICAgICAgICBkZXNjci0+ZF90eXBlID0gdHlwZTsKKyAgICAgICAgZGVzY3ItPmRfbmFtZSA9IFB5U3RyaW5nX0ludGVybkZyb21TdHJpbmcobmFtZSk7CisgICAgICAgIGlmIChkZXNjci0+ZF9uYW1lID09IE5VTEwpIHsKKyAgICAgICAgICAgIFB5X0RFQ1JFRihkZXNjcik7CisgICAgICAgICAgICBkZXNjciA9IE5VTEw7CisgICAgICAgIH0KKyAgICB9CisgICAgcmV0dXJuIGRlc2NyOworfQorCitQeU9iamVjdCAqCitQeURlc2NyX05ld01ldGhvZChQeVR5cGVPYmplY3QgKnR5cGUsIFB5TWV0aG9kRGVmICptZXRob2QpCit7CisgICAgUHlNZXRob2REZXNjck9iamVjdCAqZGVzY3I7CisKKyAgICBkZXNjciA9IChQeU1ldGhvZERlc2NyT2JqZWN0ICopZGVzY3JfbmV3KCZQeU1ldGhvZERlc2NyX1R5cGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlLCBtZXRob2QtPm1sX25hbWUpOworICAgIGlmIChkZXNjciAhPSBOVUxMKQorICAgICAgICBkZXNjci0+ZF9tZXRob2QgPSBtZXRob2Q7CisgICAgcmV0dXJuIChQeU9iamVjdCAqKWRlc2NyOworfQorCitQeU9iamVjdCAqCitQeURlc2NyX05ld0NsYXNzTWV0aG9kKFB5VHlwZU9iamVjdCAqdHlwZSwgUHlNZXRob2REZWYgKm1ldGhvZCkKK3sKKyAgICBQeU1ldGhvZERlc2NyT2JqZWN0ICpkZXNjcjsKKworICAgIGRlc2NyID0gKFB5TWV0aG9kRGVzY3JPYmplY3QgKilkZXNjcl9uZXcoJlB5Q2xhc3NNZXRob2REZXNjcl9UeXBlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZSwgbWV0aG9kLT5tbF9uYW1lKTsKKyAgICBpZiAoZGVzY3IgIT0gTlVMTCkKKyAgICAgICAgZGVzY3ItPmRfbWV0aG9kID0gbWV0aG9kOworICAgIHJldHVybiAoUHlPYmplY3QgKilkZXNjcjsKK30KKworUHlPYmplY3QgKgorUHlEZXNjcl9OZXdNZW1iZXIoUHlUeXBlT2JqZWN0ICp0eXBlLCBQeU1lbWJlckRlZiAqbWVtYmVyKQoreworICAgIFB5TWVtYmVyRGVzY3JPYmplY3QgKmRlc2NyOworCisgICAgZGVzY3IgPSAoUHlNZW1iZXJEZXNjck9iamVjdCAqKWRlc2NyX25ldygmUHlNZW1iZXJEZXNjcl9UeXBlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZSwgbWVtYmVyLT5uYW1lKTsKKyAgICBpZiAoZGVzY3IgIT0gTlVMTCkKKyAgICAgICAgZGVzY3ItPmRfbWVtYmVyID0gbWVtYmVyOworICAgIHJldHVybiAoUHlPYmplY3QgKilkZXNjcjsKK30KKworUHlPYmplY3QgKgorUHlEZXNjcl9OZXdHZXRTZXQoUHlUeXBlT2JqZWN0ICp0eXBlLCBQeUdldFNldERlZiAqZ2V0c2V0KQoreworICAgIFB5R2V0U2V0RGVzY3JPYmplY3QgKmRlc2NyOworCisgICAgZGVzY3IgPSAoUHlHZXRTZXREZXNjck9iamVjdCAqKWRlc2NyX25ldygmUHlHZXRTZXREZXNjcl9UeXBlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZSwgZ2V0c2V0LT5uYW1lKTsKKyAgICBpZiAoZGVzY3IgIT0gTlVMTCkKKyAgICAgICAgZGVzY3ItPmRfZ2V0c2V0ID0gZ2V0c2V0OworICAgIHJldHVybiAoUHlPYmplY3QgKilkZXNjcjsKK30KKworUHlPYmplY3QgKgorUHlEZXNjcl9OZXdXcmFwcGVyKFB5VHlwZU9iamVjdCAqdHlwZSwgc3RydWN0IHdyYXBwZXJiYXNlICpiYXNlLCB2b2lkICp3cmFwcGVkKQoreworICAgIFB5V3JhcHBlckRlc2NyT2JqZWN0ICpkZXNjcjsKKworICAgIGRlc2NyID0gKFB5V3JhcHBlckRlc2NyT2JqZWN0ICopZGVzY3JfbmV3KCZQeVdyYXBwZXJEZXNjcl9UeXBlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZSwgYmFzZS0+bmFtZSk7CisgICAgaWYgKGRlc2NyICE9IE5VTEwpIHsKKyAgICAgICAgZGVzY3ItPmRfYmFzZSA9IGJhc2U7CisgICAgICAgIGRlc2NyLT5kX3dyYXBwZWQgPSB3cmFwcGVkOworICAgIH0KKyAgICByZXR1cm4gKFB5T2JqZWN0ICopZGVzY3I7Cit9CisKKworLyogLS0tIFJlYWRvbmx5IHByb3h5IGZvciBkaWN0aW9uYXJpZXMgKGFjdHVhbGx5IGFueSBtYXBwaW5nKSAtLS0gKi8KKworLyogVGhpcyBoYXMgbm8gcmVhc29uIHRvIGJlIGluIHRoaXMgZmlsZSBleGNlcHQgdGhhdCBhZGRpbmcgbmV3IGZpbGVzIGlzIGEKKyAgIGJpdCBvZiBhIHBhaW4gKi8KKwordHlwZWRlZiBzdHJ1Y3QgeworICAgIFB5T2JqZWN0X0hFQUQKKyAgICBQeU9iamVjdCAqZGljdDsKK30gcHJveHlvYmplY3Q7CisKK3N0YXRpYyBQeV9zc2l6ZV90Citwcm94eV9sZW4ocHJveHlvYmplY3QgKnBwKQoreworICAgIHJldHVybiBQeU9iamVjdF9TaXplKHBwLT5kaWN0KTsKK30KKworc3RhdGljIFB5T2JqZWN0ICoKK3Byb3h5X2dldGl0ZW0ocHJveHlvYmplY3QgKnBwLCBQeU9iamVjdCAqa2V5KQoreworICAgIHJldHVybiBQeU9iamVjdF9HZXRJdGVtKHBwLT5kaWN0LCBrZXkpOworfQorCitzdGF0aWMgUHlNYXBwaW5nTWV0aG9kcyBwcm94eV9hc19tYXBwaW5nID0geworICAgIChsZW5mdW5jKXByb3h5X2xlbiwgICAgICAgICAgICAgICAgICAgICAgICAgLyogbXBfbGVuZ3RoICovCisgICAgKGJpbmFyeWZ1bmMpcHJveHlfZ2V0aXRlbSwgICAgICAgICAgICAgICAgICAvKiBtcF9zdWJzY3JpcHQgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIG1wX2Fzc19zdWJzY3JpcHQgKi8KK307CisKK3N0YXRpYyBpbnQKK3Byb3h5X2NvbnRhaW5zKHByb3h5b2JqZWN0ICpwcCwgUHlPYmplY3QgKmtleSkKK3sKKyAgICByZXR1cm4gUHlEaWN0X0NvbnRhaW5zKHBwLT5kaWN0LCBrZXkpOworfQorCitzdGF0aWMgUHlTZXF1ZW5jZU1ldGhvZHMgcHJveHlfYXNfc2VxdWVuY2UgPSB7CisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBzcV9sZW5ndGggKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHNxX2NvbmNhdCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogc3FfcmVwZWF0ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBzcV9pdGVtICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBzcV9zbGljZSAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogc3FfYXNzX2l0ZW0gKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHNxX2Fzc19zbGljZSAqLworICAgIChvYmpvYmpwcm9jKXByb3h5X2NvbnRhaW5zLCAgICAgICAgICAgICAgICAgLyogc3FfY29udGFpbnMgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHNxX2lucGxhY2VfY29uY2F0ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBzcV9pbnBsYWNlX3JlcGVhdCAqLworfTsKKworc3RhdGljIFB5T2JqZWN0ICoKK3Byb3h5X2hhc19rZXkocHJveHlvYmplY3QgKnBwLCBQeU9iamVjdCAqa2V5KQoreworICAgIGludCByZXMgPSBQeURpY3RfQ29udGFpbnMocHAtPmRpY3QsIGtleSk7CisgICAgaWYgKHJlcyA8IDApCisgICAgICAgIHJldHVybiBOVUxMOworICAgIHJldHVybiBQeUJvb2xfRnJvbUxvbmcocmVzKTsKK30KKworc3RhdGljIFB5T2JqZWN0ICoKK3Byb3h5X2dldChwcm94eW9iamVjdCAqcHAsIFB5T2JqZWN0ICphcmdzKQoreworICAgIFB5T2JqZWN0ICprZXksICpkZWYgPSBQeV9Ob25lOworCisgICAgaWYgKCFQeUFyZ19VbnBhY2tUdXBsZShhcmdzLCAiZ2V0IiwgMSwgMiwgJmtleSwgJmRlZikpCisgICAgICAgIHJldHVybiBOVUxMOworICAgIHJldHVybiBQeU9iamVjdF9DYWxsTWV0aG9kKHBwLT5kaWN0LCAiZ2V0IiwgIihPTykiLCBrZXksIGRlZik7Cit9CisKK3N0YXRpYyBQeU9iamVjdCAqCitwcm94eV9rZXlzKHByb3h5b2JqZWN0ICpwcCkKK3sKKyAgICByZXR1cm4gUHlNYXBwaW5nX0tleXMocHAtPmRpY3QpOworfQorCitzdGF0aWMgUHlPYmplY3QgKgorcHJveHlfdmFsdWVzKHByb3h5b2JqZWN0ICpwcCkKK3sKKyAgICByZXR1cm4gUHlNYXBwaW5nX1ZhbHVlcyhwcC0+ZGljdCk7Cit9CisKK3N0YXRpYyBQeU9iamVjdCAqCitwcm94eV9pdGVtcyhwcm94eW9iamVjdCAqcHApCit7CisgICAgcmV0dXJuIFB5TWFwcGluZ19JdGVtcyhwcC0+ZGljdCk7Cit9CisKK3N0YXRpYyBQeU9iamVjdCAqCitwcm94eV9pdGVya2V5cyhwcm94eW9iamVjdCAqcHApCit7CisgICAgcmV0dXJuIFB5T2JqZWN0X0NhbGxNZXRob2QocHAtPmRpY3QsICJpdGVya2V5cyIsIE5VTEwpOworfQorCitzdGF0aWMgUHlPYmplY3QgKgorcHJveHlfaXRlcnZhbHVlcyhwcm94eW9iamVjdCAqcHApCit7CisgICAgcmV0dXJuIFB5T2JqZWN0X0NhbGxNZXRob2QocHAtPmRpY3QsICJpdGVydmFsdWVzIiwgTlVMTCk7Cit9CisKK3N0YXRpYyBQeU9iamVjdCAqCitwcm94eV9pdGVyaXRlbXMocHJveHlvYmplY3QgKnBwKQoreworICAgIHJldHVybiBQeU9iamVjdF9DYWxsTWV0aG9kKHBwLT5kaWN0LCAiaXRlcml0ZW1zIiwgTlVMTCk7Cit9CitzdGF0aWMgUHlPYmplY3QgKgorcHJveHlfY29weShwcm94eW9iamVjdCAqcHApCit7CisgICAgcmV0dXJuIFB5T2JqZWN0X0NhbGxNZXRob2QocHAtPmRpY3QsICJjb3B5IiwgTlVMTCk7Cit9CisKK3N0YXRpYyBQeU1ldGhvZERlZiBwcm94eV9tZXRob2RzW10gPSB7CisgICAgeyJoYXNfa2V5IiwgICAoUHlDRnVuY3Rpb24pcHJveHlfaGFzX2tleSwgICAgTUVUSF9PLAorICAgICBQeURvY19TVFIoIkQuaGFzX2tleShrKSAtPiBUcnVlIGlmIEQgaGFzIGEga2V5IGssIGVsc2UgRmFsc2UiKX0sCisgICAgeyJnZXQiLCAgICAgICAoUHlDRnVuY3Rpb24pcHJveHlfZ2V0LCAgICAgICAgTUVUSF9WQVJBUkdTLAorICAgICBQeURvY19TVFIoIkQuZ2V0KGtbLGRdKSAtPiBEW2tdIGlmIEQuaGFzX2tleShrKSwgZWxzZSBkLiIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIgIGQgZGVmYXVsdHMgdG8gTm9uZS4iKX0sCisgICAgeyJrZXlzIiwgICAgICAoUHlDRnVuY3Rpb24pcHJveHlfa2V5cywgICAgICAgTUVUSF9OT0FSR1MsCisgICAgIFB5RG9jX1NUUigiRC5rZXlzKCkgLT4gbGlzdCBvZiBEJ3Mga2V5cyIpfSwKKyAgICB7InZhbHVlcyIsICAgIChQeUNGdW5jdGlvbilwcm94eV92YWx1ZXMsICAgICBNRVRIX05PQVJHUywKKyAgICAgUHlEb2NfU1RSKCJELnZhbHVlcygpIC0+IGxpc3Qgb2YgRCdzIHZhbHVlcyIpfSwKKyAgICB7Iml0ZW1zIiwgICAgIChQeUNGdW5jdGlvbilwcm94eV9pdGVtcywgICAgICBNRVRIX05PQVJHUywKKyAgICAgUHlEb2NfU1RSKCJELml0ZW1zKCkgLT4gbGlzdCBvZiBEJ3MgKGtleSwgdmFsdWUpIHBhaXJzLCBhcyAyLXR1cGxlcyIpfSwKKyAgICB7Iml0ZXJrZXlzIiwgIChQeUNGdW5jdGlvbilwcm94eV9pdGVya2V5cywgICBNRVRIX05PQVJHUywKKyAgICAgUHlEb2NfU1RSKCJELml0ZXJrZXlzKCkgLT4gYW4gaXRlcmF0b3Igb3ZlciB0aGUga2V5cyBvZiBEIil9LAorICAgIHsiaXRlcnZhbHVlcyIsKFB5Q0Z1bmN0aW9uKXByb3h5X2l0ZXJ2YWx1ZXMsIE1FVEhfTk9BUkdTLAorICAgICBQeURvY19TVFIoIkQuaXRlcnZhbHVlcygpIC0+IGFuIGl0ZXJhdG9yIG92ZXIgdGhlIHZhbHVlcyBvZiBEIil9LAorICAgIHsiaXRlcml0ZW1zIiwgKFB5Q0Z1bmN0aW9uKXByb3h5X2l0ZXJpdGVtcywgIE1FVEhfTk9BUkdTLAorICAgICBQeURvY19TVFIoIkQuaXRlcml0ZW1zKCkgLT4iCisgICAgICAgICAgICAgICAiIGFuIGl0ZXJhdG9yIG92ZXIgdGhlIChrZXksIHZhbHVlKSBpdGVtcyBvZiBEIil9LAorICAgIHsiY29weSIsICAgICAgKFB5Q0Z1bmN0aW9uKXByb3h5X2NvcHksICAgICAgIE1FVEhfTk9BUkdTLAorICAgICBQeURvY19TVFIoIkQuY29weSgpIC0+IGEgc2hhbGxvdyBjb3B5IG9mIEQiKX0sCisgICAgezB9Cit9OworCitzdGF0aWMgdm9pZAorcHJveHlfZGVhbGxvYyhwcm94eW9iamVjdCAqcHApCit7CisgICAgX1B5T2JqZWN0X0dDX1VOVFJBQ0socHApOworICAgIFB5X0RFQ1JFRihwcC0+ZGljdCk7CisgICAgUHlPYmplY3RfR0NfRGVsKHBwKTsKK30KKworc3RhdGljIFB5T2JqZWN0ICoKK3Byb3h5X2dldGl0ZXIocHJveHlvYmplY3QgKnBwKQoreworICAgIHJldHVybiBQeU9iamVjdF9HZXRJdGVyKHBwLT5kaWN0KTsKK30KKworc3RhdGljIFB5T2JqZWN0ICoKK3Byb3h5X3N0cihwcm94eW9iamVjdCAqcHApCit7CisgICAgcmV0dXJuIFB5T2JqZWN0X1N0cihwcC0+ZGljdCk7Cit9CisKK3N0YXRpYyBQeU9iamVjdCAqCitwcm94eV9yZXByKHByb3h5b2JqZWN0ICpwcCkKK3sKKyAgICBQeU9iamVjdCAqZGljdHJlcHI7CisgICAgUHlPYmplY3QgKnJlc3VsdDsKKworICAgIGRpY3RyZXByID0gUHlPYmplY3RfUmVwcihwcC0+ZGljdCk7CisgICAgaWYgKGRpY3RyZXByID09IE5VTEwpCisgICAgICAgIHJldHVybiBOVUxMOworICAgIHJlc3VsdCA9IFB5U3RyaW5nX0Zyb21Gb3JtYXQoImRpY3RfcHJveHkoJXMpIiwgUHlTdHJpbmdfQVNfU1RSSU5HKGRpY3RyZXByKSk7CisgICAgUHlfREVDUkVGKGRpY3RyZXByKTsKKyAgICByZXR1cm4gcmVzdWx0OworfQorCitzdGF0aWMgaW50Citwcm94eV90cmF2ZXJzZShQeU9iamVjdCAqc2VsZiwgdmlzaXRwcm9jIHZpc2l0LCB2b2lkICphcmcpCit7CisgICAgcHJveHlvYmplY3QgKnBwID0gKHByb3h5b2JqZWN0ICopc2VsZjsKKyAgICBQeV9WSVNJVChwcC0+ZGljdCk7CisgICAgcmV0dXJuIDA7Cit9CisKK3N0YXRpYyBpbnQKK3Byb3h5X2NvbXBhcmUocHJveHlvYmplY3QgKnYsIFB5T2JqZWN0ICp3KQoreworICAgIHJldHVybiBQeU9iamVjdF9Db21wYXJlKHYtPmRpY3QsIHcpOworfQorCitzdGF0aWMgUHlPYmplY3QgKgorcHJveHlfcmljaGNvbXBhcmUocHJveHlvYmplY3QgKnYsIFB5T2JqZWN0ICp3LCBpbnQgb3ApCit7CisgICAgcmV0dXJuIFB5T2JqZWN0X1JpY2hDb21wYXJlKHYtPmRpY3QsIHcsIG9wKTsKK30KKworUHlUeXBlT2JqZWN0IFB5RGljdFByb3h5X1R5cGUgPSB7CisgICAgUHlWYXJPYmplY3RfSEVBRF9JTklUKCZQeVR5cGVfVHlwZSwgMCkKKyAgICAiZGljdHByb3h5IiwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX25hbWUgKi8KKyAgICBzaXplb2YocHJveHlvYmplY3QpLCAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2Jhc2ljc2l6ZSAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfaXRlbXNpemUgKi8KKyAgICAvKiBtZXRob2RzICovCisgICAgKGRlc3RydWN0b3IpcHJveHlfZGVhbGxvYywgICAgICAgICAgICAgICAgICAvKiB0cF9kZWFsbG9jICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9wcmludCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZ2V0YXR0ciAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfc2V0YXR0ciAqLworICAgIChjbXBmdW5jKXByb3h5X2NvbXBhcmUsICAgICAgICAgICAgICAgICAgICAgLyogdHBfY29tcGFyZSAqLworICAgIChyZXByZnVuYylwcm94eV9yZXByLCAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfcmVwciAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfYXNfbnVtYmVyICovCisgICAgJnByb3h5X2FzX3NlcXVlbmNlLCAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9hc19zZXF1ZW5jZSAqLworICAgICZwcm94eV9hc19tYXBwaW5nLCAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfYXNfbWFwcGluZyAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfaGFzaCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfY2FsbCAqLworICAgIChyZXByZnVuYylwcm94eV9zdHIsICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfc3RyICovCisgICAgUHlPYmplY3RfR2VuZXJpY0dldEF0dHIsICAgICAgICAgICAgICAgICAgICAvKiB0cF9nZXRhdHRybyAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfc2V0YXR0cm8gKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2FzX2J1ZmZlciAqLworICAgIFB5X1RQRkxBR1NfREVGQVVMVCB8IFB5X1RQRkxBR1NfSEFWRV9HQywgLyogdHBfZmxhZ3MgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2RvYyAqLworICAgIHByb3h5X3RyYXZlcnNlLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfdHJhdmVyc2UgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2NsZWFyICovCisgICAgKHJpY2hjbXBmdW5jKXByb3h5X3JpY2hjb21wYXJlLCAgICAgICAgICAgICAvKiB0cF9yaWNoY29tcGFyZSAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfd2Vha2xpc3RvZmZzZXQgKi8KKyAgICAoZ2V0aXRlcmZ1bmMpcHJveHlfZ2V0aXRlciwgICAgICAgICAgICAgICAgIC8qIHRwX2l0ZXIgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2l0ZXJuZXh0ICovCisgICAgcHJveHlfbWV0aG9kcywgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9tZXRob2RzICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9tZW1iZXJzICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9nZXRzZXQgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2Jhc2UgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2RpY3QgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2Rlc2NyX2dldCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZGVzY3Jfc2V0ICovCit9OworCitQeU9iamVjdCAqCitQeURpY3RQcm94eV9OZXcoUHlPYmplY3QgKmRpY3QpCit7CisgICAgcHJveHlvYmplY3QgKnBwOworCisgICAgcHAgPSBQeU9iamVjdF9HQ19OZXcocHJveHlvYmplY3QsICZQeURpY3RQcm94eV9UeXBlKTsKKyAgICBpZiAocHAgIT0gTlVMTCkgeworICAgICAgICBQeV9JTkNSRUYoZGljdCk7CisgICAgICAgIHBwLT5kaWN0ID0gZGljdDsKKyAgICAgICAgX1B5T2JqZWN0X0dDX1RSQUNLKHBwKTsKKyAgICB9CisgICAgcmV0dXJuIChQeU9iamVjdCAqKXBwOworfQorCisKKy8qIC0tLSBXcmFwcGVyIG9iamVjdCBmb3IgInNsb3QiIG1ldGhvZHMgLS0tICovCisKKy8qIFRoaXMgaGFzIG5vIHJlYXNvbiB0byBiZSBpbiB0aGlzIGZpbGUgZXhjZXB0IHRoYXQgYWRkaW5nIG5ldyBmaWxlcyBpcyBhCisgICBiaXQgb2YgYSBwYWluICovCisKK3R5cGVkZWYgc3RydWN0IHsKKyAgICBQeU9iamVjdF9IRUFECisgICAgUHlXcmFwcGVyRGVzY3JPYmplY3QgKmRlc2NyOworICAgIFB5T2JqZWN0ICpzZWxmOworfSB3cmFwcGVyb2JqZWN0OworCitzdGF0aWMgdm9pZAord3JhcHBlcl9kZWFsbG9jKHdyYXBwZXJvYmplY3QgKndwKQoreworICAgIFB5T2JqZWN0X0dDX1VuVHJhY2sod3ApOworICAgIFB5X1RSQVNIQ0FOX1NBRkVfQkVHSU4od3ApCisgICAgUHlfWERFQ1JFRih3cC0+ZGVzY3IpOworICAgIFB5X1hERUNSRUYod3AtPnNlbGYpOworICAgIFB5T2JqZWN0X0dDX0RlbCh3cCk7CisgICAgUHlfVFJBU0hDQU5fU0FGRV9FTkQod3ApCit9CisKK3N0YXRpYyBpbnQKK3dyYXBwZXJfY29tcGFyZSh3cmFwcGVyb2JqZWN0ICphLCB3cmFwcGVyb2JqZWN0ICpiKQoreworICAgIGlmIChhLT5kZXNjciA9PSBiLT5kZXNjcikKKyAgICAgICAgcmV0dXJuIFB5T2JqZWN0X0NvbXBhcmUoYS0+c2VsZiwgYi0+c2VsZik7CisgICAgZWxzZQorICAgICAgICByZXR1cm4gKGEtPmRlc2NyIDwgYi0+ZGVzY3IpID8gLTEgOiAxOworfQorCitzdGF0aWMgbG9uZword3JhcHBlcl9oYXNoKHdyYXBwZXJvYmplY3QgKndwKQoreworICAgIGludCB4LCB5OworICAgIHggPSBfUHlfSGFzaFBvaW50ZXIod3AtPmRlc2NyKTsKKyAgICBpZiAoeCA9PSAtMSkKKyAgICAgICAgcmV0dXJuIC0xOworICAgIHkgPSBQeU9iamVjdF9IYXNoKHdwLT5zZWxmKTsKKyAgICBpZiAoeSA9PSAtMSkKKyAgICAgICAgcmV0dXJuIC0xOworICAgIHggPSB4IF4geTsKKyAgICBpZiAoeCA9PSAtMSkKKyAgICAgICAgeCA9IC0yOworICAgIHJldHVybiB4OworfQorCitzdGF0aWMgUHlPYmplY3QgKgord3JhcHBlcl9yZXByKHdyYXBwZXJvYmplY3QgKndwKQoreworICAgIHJldHVybiBQeVN0cmluZ19Gcm9tRm9ybWF0KCI8bWV0aG9kLXdyYXBwZXIgJyVzJyBvZiAlcyBvYmplY3QgYXQgJXA+IiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3cC0+ZGVzY3ItPmRfYmFzZS0+bmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3cC0+c2VsZi0+b2JfdHlwZS0+dHBfbmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3cC0+c2VsZik7Cit9CisKK3N0YXRpYyBQeU1lbWJlckRlZiB3cmFwcGVyX21lbWJlcnNbXSA9IHsKKyAgICB7Il9fc2VsZl9fIiwgVF9PQkpFQ1QsIG9mZnNldG9mKHdyYXBwZXJvYmplY3QsIHNlbGYpLCBSRUFET05MWX0sCisgICAgezB9Cit9OworCitzdGF0aWMgUHlPYmplY3QgKgord3JhcHBlcl9vYmpjbGFzcyh3cmFwcGVyb2JqZWN0ICp3cCkKK3sKKyAgICBQeU9iamVjdCAqYyA9IChQeU9iamVjdCAqKXdwLT5kZXNjci0+ZF90eXBlOworCisgICAgUHlfSU5DUkVGKGMpOworICAgIHJldHVybiBjOworfQorCitzdGF0aWMgUHlPYmplY3QgKgord3JhcHBlcl9uYW1lKHdyYXBwZXJvYmplY3QgKndwKQoreworICAgIGNoYXIgKnMgPSB3cC0+ZGVzY3ItPmRfYmFzZS0+bmFtZTsKKworICAgIHJldHVybiBQeVN0cmluZ19Gcm9tU3RyaW5nKHMpOworfQorCitzdGF0aWMgUHlPYmplY3QgKgord3JhcHBlcl9kb2Mod3JhcHBlcm9iamVjdCAqd3ApCit7CisgICAgY2hhciAqcyA9IHdwLT5kZXNjci0+ZF9iYXNlLT5kb2M7CisKKyAgICBpZiAocyA9PSBOVUxMKSB7CisgICAgICAgIFB5X0lOQ1JFRihQeV9Ob25lKTsKKyAgICAgICAgcmV0dXJuIFB5X05vbmU7CisgICAgfQorICAgIGVsc2UgeworICAgICAgICByZXR1cm4gUHlTdHJpbmdfRnJvbVN0cmluZyhzKTsKKyAgICB9Cit9CisKK3N0YXRpYyBQeUdldFNldERlZiB3cmFwcGVyX2dldHNldHNbXSA9IHsKKyAgICB7Il9fb2JqY2xhc3NfXyIsIChnZXR0ZXIpd3JhcHBlcl9vYmpjbGFzc30sCisgICAgeyJfX25hbWVfXyIsIChnZXR0ZXIpd3JhcHBlcl9uYW1lfSwKKyAgICB7Il9fZG9jX18iLCAoZ2V0dGVyKXdyYXBwZXJfZG9jfSwKKyAgICB7MH0KK307CisKK3N0YXRpYyBQeU9iamVjdCAqCit3cmFwcGVyX2NhbGwod3JhcHBlcm9iamVjdCAqd3AsIFB5T2JqZWN0ICphcmdzLCBQeU9iamVjdCAqa3dkcykKK3sKKyAgICB3cmFwcGVyZnVuYyB3cmFwcGVyID0gd3AtPmRlc2NyLT5kX2Jhc2UtPndyYXBwZXI7CisgICAgUHlPYmplY3QgKnNlbGYgPSB3cC0+c2VsZjsKKworICAgIGlmICh3cC0+ZGVzY3ItPmRfYmFzZS0+ZmxhZ3MgJiBQeVdyYXBwZXJGbGFnX0tFWVdPUkRTKSB7CisgICAgICAgIHdyYXBwZXJmdW5jX2t3ZHMgd2sgPSAod3JhcHBlcmZ1bmNfa3dkcyl3cmFwcGVyOworICAgICAgICByZXR1cm4gKCp3aykoc2VsZiwgYXJncywgd3AtPmRlc2NyLT5kX3dyYXBwZWQsIGt3ZHMpOworICAgIH0KKworICAgIGlmIChrd2RzICE9IE5VTEwgJiYgKCFQeURpY3RfQ2hlY2soa3dkcykgfHwgUHlEaWN0X1NpemUoa3dkcykgIT0gMCkpIHsKKyAgICAgICAgUHlFcnJfRm9ybWF0KFB5RXhjX1R5cGVFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICJ3cmFwcGVyICVzIGRvZXNuJ3QgdGFrZSBrZXl3b3JkIGFyZ3VtZW50cyIsCisgICAgICAgICAgICAgICAgICAgICB3cC0+ZGVzY3ItPmRfYmFzZS0+bmFtZSk7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICByZXR1cm4gKCp3cmFwcGVyKShzZWxmLCBhcmdzLCB3cC0+ZGVzY3ItPmRfd3JhcHBlZCk7Cit9CisKK3N0YXRpYyBpbnQKK3dyYXBwZXJfdHJhdmVyc2UoUHlPYmplY3QgKnNlbGYsIHZpc2l0cHJvYyB2aXNpdCwgdm9pZCAqYXJnKQoreworICAgIHdyYXBwZXJvYmplY3QgKndwID0gKHdyYXBwZXJvYmplY3QgKilzZWxmOworICAgIFB5X1ZJU0lUKHdwLT5kZXNjcik7CisgICAgUHlfVklTSVQod3AtPnNlbGYpOworICAgIHJldHVybiAwOworfQorCitzdGF0aWMgUHlUeXBlT2JqZWN0IHdyYXBwZXJ0eXBlID0geworICAgIFB5VmFyT2JqZWN0X0hFQURfSU5JVCgmUHlUeXBlX1R5cGUsIDApCisgICAgIm1ldGhvZC13cmFwcGVyIiwgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9uYW1lICovCisgICAgc2l6ZW9mKHdyYXBwZXJvYmplY3QpLCAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9iYXNpY3NpemUgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2l0ZW1zaXplICovCisgICAgLyogbWV0aG9kcyAqLworICAgIChkZXN0cnVjdG9yKXdyYXBwZXJfZGVhbGxvYywgICAgICAgICAgICAgICAgLyogdHBfZGVhbGxvYyAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfcHJpbnQgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2dldGF0dHIgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3NldGF0dHIgKi8KKyAgICAoY21wZnVuYyl3cmFwcGVyX2NvbXBhcmUsICAgICAgICAgICAgICAgICAgIC8qIHRwX2NvbXBhcmUgKi8KKyAgICAocmVwcmZ1bmMpd3JhcHBlcl9yZXByLCAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3JlcHIgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2FzX251bWJlciAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfYXNfc2VxdWVuY2UgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2FzX21hcHBpbmcgKi8KKyAgICAoaGFzaGZ1bmMpd3JhcHBlcl9oYXNoLCAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2hhc2ggKi8KKyAgICAodGVybmFyeWZ1bmMpd3JhcHBlcl9jYWxsLCAgICAgICAgICAgICAgICAgIC8qIHRwX2NhbGwgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3N0ciAqLworICAgIFB5T2JqZWN0X0dlbmVyaWNHZXRBdHRyLCAgICAgICAgICAgICAgICAgICAgLyogdHBfZ2V0YXR0cm8gKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3NldGF0dHJvICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9hc19idWZmZXIgKi8KKyAgICBQeV9UUEZMQUdTX0RFRkFVTFQgfCBQeV9UUEZMQUdTX0hBVkVfR0MsIC8qIHRwX2ZsYWdzICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9kb2MgKi8KKyAgICB3cmFwcGVyX3RyYXZlcnNlLCAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3RyYXZlcnNlICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9jbGVhciAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfcmljaGNvbXBhcmUgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3dlYWtsaXN0b2Zmc2V0ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9pdGVyICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9pdGVybmV4dCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfbWV0aG9kcyAqLworICAgIHdyYXBwZXJfbWVtYmVycywgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfbWVtYmVycyAqLworICAgIHdyYXBwZXJfZ2V0c2V0cywgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZ2V0c2V0ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9iYXNlICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9kaWN0ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9kZXNjcl9nZXQgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2Rlc2NyX3NldCAqLworfTsKKworUHlPYmplY3QgKgorUHlXcmFwcGVyX05ldyhQeU9iamVjdCAqZCwgUHlPYmplY3QgKnNlbGYpCit7CisgICAgd3JhcHBlcm9iamVjdCAqd3A7CisgICAgUHlXcmFwcGVyRGVzY3JPYmplY3QgKmRlc2NyOworCisgICAgYXNzZXJ0KFB5T2JqZWN0X1R5cGVDaGVjayhkLCAmUHlXcmFwcGVyRGVzY3JfVHlwZSkpOworICAgIGRlc2NyID0gKFB5V3JhcHBlckRlc2NyT2JqZWN0ICopZDsKKyAgICBhc3NlcnQoX1B5T2JqZWN0X1JlYWxJc1N1YmNsYXNzKChQeU9iamVjdCAqKVB5X1RZUEUoc2VsZiksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoUHlPYmplY3QgKikoZGVzY3ItPmRfdHlwZSkpKTsKKworICAgIHdwID0gUHlPYmplY3RfR0NfTmV3KHdyYXBwZXJvYmplY3QsICZ3cmFwcGVydHlwZSk7CisgICAgaWYgKHdwICE9IE5VTEwpIHsKKyAgICAgICAgUHlfSU5DUkVGKGRlc2NyKTsKKyAgICAgICAgd3AtPmRlc2NyID0gZGVzY3I7CisgICAgICAgIFB5X0lOQ1JFRihzZWxmKTsKKyAgICAgICAgd3AtPnNlbGYgPSBzZWxmOworICAgICAgICBfUHlPYmplY3RfR0NfVFJBQ0sod3ApOworICAgIH0KKyAgICByZXR1cm4gKFB5T2JqZWN0ICopd3A7Cit9CisKKworLyogQSBidWlsdC1pbiAncHJvcGVydHknIHR5cGUgKi8KKworLyoKKyAgICBjbGFzcyBwcm9wZXJ0eShvYmplY3QpOgorCisgICAgZGVmIF9faW5pdF9fKHNlbGYsIGZnZXQ9Tm9uZSwgZnNldD1Ob25lLCBmZGVsPU5vbmUsIGRvYz1Ob25lKToKKyAgICAgICAgaWYgZG9jIGlzIE5vbmUgYW5kIGZnZXQgaXMgbm90IE5vbmUgYW5kIGhhc2F0dHIoZmdldCwgIl9fZG9jX18iKToKKyAgICAgICAgZG9jID0gZmdldC5fX2RvY19fCisgICAgICAgIHNlbGYuX19nZXQgPSBmZ2V0CisgICAgICAgIHNlbGYuX19zZXQgPSBmc2V0CisgICAgICAgIHNlbGYuX19kZWwgPSBmZGVsCisgICAgICAgIHNlbGYuX19kb2NfXyA9IGRvYworCisgICAgZGVmIF9fZ2V0X18oc2VsZiwgaW5zdCwgdHlwZT1Ob25lKToKKyAgICAgICAgaWYgaW5zdCBpcyBOb25lOgorICAgICAgICByZXR1cm4gc2VsZgorICAgICAgICBpZiBzZWxmLl9fZ2V0IGlzIE5vbmU6CisgICAgICAgIHJhaXNlIEF0dHJpYnV0ZUVycm9yLCAidW5yZWFkYWJsZSBhdHRyaWJ1dGUiCisgICAgICAgIHJldHVybiBzZWxmLl9fZ2V0KGluc3QpCisKKyAgICBkZWYgX19zZXRfXyhzZWxmLCBpbnN0LCB2YWx1ZSk6CisgICAgICAgIGlmIHNlbGYuX19zZXQgaXMgTm9uZToKKyAgICAgICAgcmFpc2UgQXR0cmlidXRlRXJyb3IsICJjYW4ndCBzZXQgYXR0cmlidXRlIgorICAgICAgICByZXR1cm4gc2VsZi5fX3NldChpbnN0LCB2YWx1ZSkKKworICAgIGRlZiBfX2RlbGV0ZV9fKHNlbGYsIGluc3QpOgorICAgICAgICBpZiBzZWxmLl9fZGVsIGlzIE5vbmU6CisgICAgICAgIHJhaXNlIEF0dHJpYnV0ZUVycm9yLCAiY2FuJ3QgZGVsZXRlIGF0dHJpYnV0ZSIKKyAgICAgICAgcmV0dXJuIHNlbGYuX19kZWwoaW5zdCkKKworKi8KKwordHlwZWRlZiBzdHJ1Y3QgeworICAgIFB5T2JqZWN0X0hFQUQKKyAgICBQeU9iamVjdCAqcHJvcF9nZXQ7CisgICAgUHlPYmplY3QgKnByb3Bfc2V0OworICAgIFB5T2JqZWN0ICpwcm9wX2RlbDsKKyAgICBQeU9iamVjdCAqcHJvcF9kb2M7CisgICAgaW50IGdldHRlcl9kb2M7Cit9IHByb3BlcnR5b2JqZWN0OworCitzdGF0aWMgUHlPYmplY3QgKiBwcm9wZXJ0eV9jb3B5KFB5T2JqZWN0ICosIFB5T2JqZWN0ICosIFB5T2JqZWN0ICosCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHlPYmplY3QgKik7CisKK3N0YXRpYyBQeU1lbWJlckRlZiBwcm9wZXJ0eV9tZW1iZXJzW10gPSB7CisgICAgeyJmZ2V0IiwgVF9PQkpFQ1QsIG9mZnNldG9mKHByb3BlcnR5b2JqZWN0LCBwcm9wX2dldCksIFJFQURPTkxZfSwKKyAgICB7ImZzZXQiLCBUX09CSkVDVCwgb2Zmc2V0b2YocHJvcGVydHlvYmplY3QsIHByb3Bfc2V0KSwgUkVBRE9OTFl9LAorICAgIHsiZmRlbCIsIFRfT0JKRUNULCBvZmZzZXRvZihwcm9wZXJ0eW9iamVjdCwgcHJvcF9kZWwpLCBSRUFET05MWX0sCisgICAgeyJfX2RvY19fIiwgIFRfT0JKRUNULCBvZmZzZXRvZihwcm9wZXJ0eW9iamVjdCwgcHJvcF9kb2MpLCBSRUFET05MWX0sCisgICAgezB9Cit9OworCisKK1B5RG9jX1NUUlZBUihnZXR0ZXJfZG9jLAorICAgICAgICAgICAgICJEZXNjcmlwdG9yIHRvIGNoYW5nZSB0aGUgZ2V0dGVyIG9uIGEgcHJvcGVydHkuIik7CisKK3N0YXRpYyBQeU9iamVjdCAqCitwcm9wZXJ0eV9nZXR0ZXIoUHlPYmplY3QgKnNlbGYsIFB5T2JqZWN0ICpnZXR0ZXIpCit7CisgICAgcmV0dXJuIHByb3BlcnR5X2NvcHkoc2VsZiwgZ2V0dGVyLCBOVUxMLCBOVUxMKTsKK30KKworCitQeURvY19TVFJWQVIoc2V0dGVyX2RvYywKKyAgICAgICAgICAgICAiRGVzY3JpcHRvciB0byBjaGFuZ2UgdGhlIHNldHRlciBvbiBhIHByb3BlcnR5LiIpOworCitzdGF0aWMgUHlPYmplY3QgKgorcHJvcGVydHlfc2V0dGVyKFB5T2JqZWN0ICpzZWxmLCBQeU9iamVjdCAqc2V0dGVyKQoreworICAgIHJldHVybiBwcm9wZXJ0eV9jb3B5KHNlbGYsIE5VTEwsIHNldHRlciwgTlVMTCk7Cit9CisKKworUHlEb2NfU1RSVkFSKGRlbGV0ZXJfZG9jLAorICAgICAgICAgICAgICJEZXNjcmlwdG9yIHRvIGNoYW5nZSB0aGUgZGVsZXRlciBvbiBhIHByb3BlcnR5LiIpOworCitzdGF0aWMgUHlPYmplY3QgKgorcHJvcGVydHlfZGVsZXRlcihQeU9iamVjdCAqc2VsZiwgUHlPYmplY3QgKmRlbGV0ZXIpCit7CisgICAgcmV0dXJuIHByb3BlcnR5X2NvcHkoc2VsZiwgTlVMTCwgTlVMTCwgZGVsZXRlcik7Cit9CisKKworc3RhdGljIFB5TWV0aG9kRGVmIHByb3BlcnR5X21ldGhvZHNbXSA9IHsKKyAgICB7ImdldHRlciIsIHByb3BlcnR5X2dldHRlciwgTUVUSF9PLCBnZXR0ZXJfZG9jfSwKKyAgICB7InNldHRlciIsIHByb3BlcnR5X3NldHRlciwgTUVUSF9PLCBzZXR0ZXJfZG9jfSwKKyAgICB7ImRlbGV0ZXIiLCBwcm9wZXJ0eV9kZWxldGVyLCBNRVRIX08sIGRlbGV0ZXJfZG9jfSwKKyAgICB7MH0KK307CisKKworc3RhdGljIHZvaWQKK3Byb3BlcnR5X2RlYWxsb2MoUHlPYmplY3QgKnNlbGYpCit7CisgICAgcHJvcGVydHlvYmplY3QgKmdzID0gKHByb3BlcnR5b2JqZWN0ICopc2VsZjsKKworICAgIF9QeU9iamVjdF9HQ19VTlRSQUNLKHNlbGYpOworICAgIFB5X1hERUNSRUYoZ3MtPnByb3BfZ2V0KTsKKyAgICBQeV9YREVDUkVGKGdzLT5wcm9wX3NldCk7CisgICAgUHlfWERFQ1JFRihncy0+cHJvcF9kZWwpOworICAgIFB5X1hERUNSRUYoZ3MtPnByb3BfZG9jKTsKKyAgICBzZWxmLT5vYl90eXBlLT50cF9mcmVlKHNlbGYpOworfQorCitzdGF0aWMgUHlPYmplY3QgKgorcHJvcGVydHlfZGVzY3JfZ2V0KFB5T2JqZWN0ICpzZWxmLCBQeU9iamVjdCAqb2JqLCBQeU9iamVjdCAqdHlwZSkKK3sKKyAgICBwcm9wZXJ0eW9iamVjdCAqZ3MgPSAocHJvcGVydHlvYmplY3QgKilzZWxmOworCisgICAgaWYgKG9iaiA9PSBOVUxMIHx8IG9iaiA9PSBQeV9Ob25lKSB7CisgICAgICAgIFB5X0lOQ1JFRihzZWxmKTsKKyAgICAgICAgcmV0dXJuIHNlbGY7CisgICAgfQorICAgIGlmIChncy0+cHJvcF9nZXQgPT0gTlVMTCkgeworICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfQXR0cmlidXRlRXJyb3IsICJ1bnJlYWRhYmxlIGF0dHJpYnV0ZSIpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgcmV0dXJuIFB5T2JqZWN0X0NhbGxGdW5jdGlvbihncy0+cHJvcF9nZXQsICIoTykiLCBvYmopOworfQorCitzdGF0aWMgaW50Citwcm9wZXJ0eV9kZXNjcl9zZXQoUHlPYmplY3QgKnNlbGYsIFB5T2JqZWN0ICpvYmosIFB5T2JqZWN0ICp2YWx1ZSkKK3sKKyAgICBwcm9wZXJ0eW9iamVjdCAqZ3MgPSAocHJvcGVydHlvYmplY3QgKilzZWxmOworICAgIFB5T2JqZWN0ICpmdW5jLCAqcmVzOworCisgICAgaWYgKHZhbHVlID09IE5VTEwpCisgICAgICAgIGZ1bmMgPSBncy0+cHJvcF9kZWw7CisgICAgZWxzZQorICAgICAgICBmdW5jID0gZ3MtPnByb3Bfc2V0OworICAgIGlmIChmdW5jID09IE5VTEwpIHsKKyAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX0F0dHJpYnV0ZUVycm9yLAorICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWUgPT0gTlVMTCA/CisgICAgICAgICAgICAgICAgICAgICAgICAiY2FuJ3QgZGVsZXRlIGF0dHJpYnV0ZSIgOgorICAgICAgICAgICAgICAgICJjYW4ndCBzZXQgYXR0cmlidXRlIik7CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisgICAgaWYgKHZhbHVlID09IE5VTEwpCisgICAgICAgIHJlcyA9IFB5T2JqZWN0X0NhbGxGdW5jdGlvbihmdW5jLCAiKE8pIiwgb2JqKTsKKyAgICBlbHNlCisgICAgICAgIHJlcyA9IFB5T2JqZWN0X0NhbGxGdW5jdGlvbihmdW5jLCAiKE9PKSIsIG9iaiwgdmFsdWUpOworICAgIGlmIChyZXMgPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIC0xOworICAgIFB5X0RFQ1JFRihyZXMpOworICAgIHJldHVybiAwOworfQorCitzdGF0aWMgUHlPYmplY3QgKgorcHJvcGVydHlfY29weShQeU9iamVjdCAqb2xkLCBQeU9iamVjdCAqZ2V0LCBQeU9iamVjdCAqc2V0LCBQeU9iamVjdCAqZGVsKQoreworICAgIHByb3BlcnR5b2JqZWN0ICpwb2xkID0gKHByb3BlcnR5b2JqZWN0ICopb2xkOworICAgIFB5T2JqZWN0ICpuZXcsICp0eXBlLCAqZG9jOworCisgICAgdHlwZSA9IFB5T2JqZWN0X1R5cGUob2xkKTsKKyAgICBpZiAodHlwZSA9PSBOVUxMKQorICAgICAgICByZXR1cm4gTlVMTDsKKworICAgIGlmIChnZXQgPT0gTlVMTCB8fCBnZXQgPT0gUHlfTm9uZSkgeworICAgICAgICBQeV9YREVDUkVGKGdldCk7CisgICAgICAgIGdldCA9IHBvbGQtPnByb3BfZ2V0ID8gcG9sZC0+cHJvcF9nZXQgOiBQeV9Ob25lOworICAgIH0KKyAgICBpZiAoc2V0ID09IE5VTEwgfHwgc2V0ID09IFB5X05vbmUpIHsKKyAgICAgICAgUHlfWERFQ1JFRihzZXQpOworICAgICAgICBzZXQgPSBwb2xkLT5wcm9wX3NldCA/IHBvbGQtPnByb3Bfc2V0IDogUHlfTm9uZTsKKyAgICB9CisgICAgaWYgKGRlbCA9PSBOVUxMIHx8IGRlbCA9PSBQeV9Ob25lKSB7CisgICAgICAgIFB5X1hERUNSRUYoZGVsKTsKKyAgICAgICAgZGVsID0gcG9sZC0+cHJvcF9kZWwgPyBwb2xkLT5wcm9wX2RlbCA6IFB5X05vbmU7CisgICAgfQorICAgIGlmIChwb2xkLT5nZXR0ZXJfZG9jICYmIGdldCAhPSBQeV9Ob25lKSB7CisgICAgICAgIC8qIG1ha2UgX2luaXQgdXNlIF9fZG9jX18gZnJvbSBnZXR0ZXIgKi8KKyAgICAgICAgZG9jID0gUHlfTm9uZTsKKyAgICB9CisgICAgZWxzZSB7CisgICAgICAgIGRvYyA9IHBvbGQtPnByb3BfZG9jID8gcG9sZC0+cHJvcF9kb2MgOiBQeV9Ob25lOworICAgIH0KKworICAgIG5ldyA9ICBQeU9iamVjdF9DYWxsRnVuY3Rpb24odHlwZSwgIk9PT08iLCBnZXQsIHNldCwgZGVsLCBkb2MpOworICAgIFB5X0RFQ1JFRih0eXBlKTsKKyAgICBpZiAobmV3ID09IE5VTEwpCisgICAgICAgIHJldHVybiBOVUxMOworICAgIHJldHVybiBuZXc7Cit9CisKK3N0YXRpYyBpbnQKK3Byb3BlcnR5X2luaXQoUHlPYmplY3QgKnNlbGYsIFB5T2JqZWN0ICphcmdzLCBQeU9iamVjdCAqa3dkcykKK3sKKyAgICBQeU9iamVjdCAqZ2V0ID0gTlVMTCwgKnNldCA9IE5VTEwsICpkZWwgPSBOVUxMLCAqZG9jID0gTlVMTDsKKyAgICBzdGF0aWMgY2hhciAqa3dsaXN0W10gPSB7ImZnZXQiLCAiZnNldCIsICJmZGVsIiwgImRvYyIsIDB9OworICAgIHByb3BlcnR5b2JqZWN0ICpwcm9wID0gKHByb3BlcnR5b2JqZWN0ICopc2VsZjsKKworICAgIGlmICghUHlBcmdfUGFyc2VUdXBsZUFuZEtleXdvcmRzKGFyZ3MsIGt3ZHMsICJ8T09PTzpwcm9wZXJ0eSIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAga3dsaXN0LCAmZ2V0LCAmc2V0LCAmZGVsLCAmZG9jKSkKKyAgICAgICAgcmV0dXJuIC0xOworCisgICAgaWYgKGdldCA9PSBQeV9Ob25lKQorICAgICAgICBnZXQgPSBOVUxMOworICAgIGlmIChzZXQgPT0gUHlfTm9uZSkKKyAgICAgICAgc2V0ID0gTlVMTDsKKyAgICBpZiAoZGVsID09IFB5X05vbmUpCisgICAgICAgIGRlbCA9IE5VTEw7CisKKyAgICBQeV9YSU5DUkVGKGdldCk7CisgICAgUHlfWElOQ1JFRihzZXQpOworICAgIFB5X1hJTkNSRUYoZGVsKTsKKyAgICBQeV9YSU5DUkVGKGRvYyk7CisKKyAgICBwcm9wLT5wcm9wX2dldCA9IGdldDsKKyAgICBwcm9wLT5wcm9wX3NldCA9IHNldDsKKyAgICBwcm9wLT5wcm9wX2RlbCA9IGRlbDsKKyAgICBwcm9wLT5wcm9wX2RvYyA9IGRvYzsKKyAgICBwcm9wLT5nZXR0ZXJfZG9jID0gMDsKKworICAgIC8qIGlmIG5vIGRvY3N0cmluZyBnaXZlbiBhbmQgdGhlIGdldHRlciBoYXMgb25lLCB1c2UgdGhhdCBvbmUgKi8KKyAgICBpZiAoKGRvYyA9PSBOVUxMIHx8IGRvYyA9PSBQeV9Ob25lKSAmJiBnZXQgIT0gTlVMTCkgeworICAgICAgICBQeU9iamVjdCAqZ2V0X2RvYyA9IFB5T2JqZWN0X0dldEF0dHJTdHJpbmcoZ2V0LCAiX19kb2NfXyIpOworICAgICAgICBpZiAoZ2V0X2RvYykgeworICAgICAgICAgICAgaWYgKFB5X1RZUEUoc2VsZikgPT0gJlB5UHJvcGVydHlfVHlwZSkgeworICAgICAgICAgICAgICAgIFB5X1hERUNSRUYocHJvcC0+cHJvcF9kb2MpOworICAgICAgICAgICAgICAgIHByb3AtPnByb3BfZG9jID0gZ2V0X2RvYzsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGVsc2UgeworICAgICAgICAgICAgICAgIC8qIElmIHRoaXMgaXMgYSBwcm9wZXJ0eSBzdWJjbGFzcywgcHV0IF9fZG9jX18KKyAgICAgICAgICAgICAgICBpbiBkaWN0IG9mIHRoZSBzdWJjbGFzcyBpbnN0YW5jZSBpbnN0ZWFkLAorICAgICAgICAgICAgICAgIG90aGVyd2lzZSBpdCBnZXRzIHNoYWRvd2VkIGJ5IF9fZG9jX18gaW4gdGhlCisgICAgICAgICAgICAgICAgY2xhc3MncyBkaWN0LiAqLworICAgICAgICAgICAgICAgIGludCBlcnIgPSBQeU9iamVjdF9TZXRBdHRyU3RyaW5nKHNlbGYsICJfX2RvY19fIiwgZ2V0X2RvYyk7CisgICAgICAgICAgICAgICAgUHlfREVDUkVGKGdldF9kb2MpOworICAgICAgICAgICAgICAgIGlmIChlcnIgPCAwKQorICAgICAgICAgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBwcm9wLT5nZXR0ZXJfZG9jID0gMTsKKyAgICAgICAgfQorICAgICAgICBlbHNlIGlmIChQeUVycl9FeGNlcHRpb25NYXRjaGVzKFB5RXhjX0V4Y2VwdGlvbikpIHsKKyAgICAgICAgICAgIFB5RXJyX0NsZWFyKCk7CisgICAgICAgIH0KKyAgICAgICAgZWxzZSB7CisgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgIH0KKyAgICB9CisKKyAgICByZXR1cm4gMDsKK30KKworUHlEb2NfU1RSVkFSKHByb3BlcnR5X2RvYywKKyJwcm9wZXJ0eShmZ2V0PU5vbmUsIGZzZXQ9Tm9uZSwgZmRlbD1Ob25lLCBkb2M9Tm9uZSkgLT4gcHJvcGVydHkgYXR0cmlidXRlXG4iCisiXG4iCisiZmdldCBpcyBhIGZ1bmN0aW9uIHRvIGJlIHVzZWQgZm9yIGdldHRpbmcgYW4gYXR0cmlidXRlIHZhbHVlLCBhbmQgbGlrZXdpc2VcbiIKKyJmc2V0IGlzIGEgZnVuY3Rpb24gZm9yIHNldHRpbmcsIGFuZCBmZGVsIGEgZnVuY3Rpb24gZm9yIGRlbCdpbmcsIGFuXG4iCisiYXR0cmlidXRlLiAgVHlwaWNhbCB1c2UgaXMgdG8gZGVmaW5lIGEgbWFuYWdlZCBhdHRyaWJ1dGUgeDpcbiIKKyJjbGFzcyBDKG9iamVjdCk6XG4iCisiICAgIGRlZiBnZXR4KHNlbGYpOiByZXR1cm4gc2VsZi5feFxuIgorIiAgICBkZWYgc2V0eChzZWxmLCB2YWx1ZSk6IHNlbGYuX3ggPSB2YWx1ZVxuIgorIiAgICBkZWYgZGVseChzZWxmKTogZGVsIHNlbGYuX3hcbiIKKyIgICAgeCA9IHByb3BlcnR5KGdldHgsIHNldHgsIGRlbHgsIFwiSSdtIHRoZSAneCcgcHJvcGVydHkuXCIpXG4iCisiXG4iCisiRGVjb3JhdG9ycyBtYWtlIGRlZmluaW5nIG5ldyBwcm9wZXJ0aWVzIG9yIG1vZGlmeWluZyBleGlzdGluZyBvbmVzIGVhc3k6XG4iCisiY2xhc3MgQyhvYmplY3QpOlxuIgorIiAgICBAcHJvcGVydHlcbiIKKyIgICAgZGVmIHgoc2VsZik6IHJldHVybiBzZWxmLl94XG4iCisiICAgIEB4LnNldHRlclxuIgorIiAgICBkZWYgeChzZWxmLCB2YWx1ZSk6IHNlbGYuX3ggPSB2YWx1ZVxuIgorIiAgICBAeC5kZWxldGVyXG4iCisiICAgIGRlZiB4KHNlbGYpOiBkZWwgc2VsZi5feFxuIgorKTsKKworc3RhdGljIGludAorcHJvcGVydHlfdHJhdmVyc2UoUHlPYmplY3QgKnNlbGYsIHZpc2l0cHJvYyB2aXNpdCwgdm9pZCAqYXJnKQoreworICAgIHByb3BlcnR5b2JqZWN0ICpwcCA9IChwcm9wZXJ0eW9iamVjdCAqKXNlbGY7CisgICAgUHlfVklTSVQocHAtPnByb3BfZ2V0KTsKKyAgICBQeV9WSVNJVChwcC0+cHJvcF9zZXQpOworICAgIFB5X1ZJU0lUKHBwLT5wcm9wX2RlbCk7CisgICAgUHlfVklTSVQocHAtPnByb3BfZG9jKTsKKyAgICByZXR1cm4gMDsKK30KKworUHlUeXBlT2JqZWN0IFB5UHJvcGVydHlfVHlwZSA9IHsKKyAgICBQeVZhck9iamVjdF9IRUFEX0lOSVQoJlB5VHlwZV9UeXBlLCAwKQorICAgICJwcm9wZXJ0eSIsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfbmFtZSAqLworICAgIHNpemVvZihwcm9wZXJ0eW9iamVjdCksICAgICAgICAgICAgICAgICAgICAgLyogdHBfYmFzaWNzaXplICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9pdGVtc2l6ZSAqLworICAgIC8qIG1ldGhvZHMgKi8KKyAgICBwcm9wZXJ0eV9kZWFsbG9jLCAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2RlYWxsb2MgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3ByaW50ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9nZXRhdHRyICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9zZXRhdHRyICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9jb21wYXJlICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9yZXByICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9hc19udW1iZXIgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2FzX3NlcXVlbmNlICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9hc19tYXBwaW5nICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9oYXNoICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9jYWxsICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9zdHIgKi8KKyAgICBQeU9iamVjdF9HZW5lcmljR2V0QXR0ciwgICAgICAgICAgICAgICAgICAgIC8qIHRwX2dldGF0dHJvICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9zZXRhdHRybyAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfYXNfYnVmZmVyICovCisgICAgUHlfVFBGTEFHU19ERUZBVUxUIHwgUHlfVFBGTEFHU19IQVZFX0dDIHwKKyAgICAgICAgUHlfVFBGTEFHU19CQVNFVFlQRSwgICAgICAgICAgICAgICAgICAgIC8qIHRwX2ZsYWdzICovCisgICAgcHJvcGVydHlfZG9jLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9kb2MgKi8KKyAgICBwcm9wZXJ0eV90cmF2ZXJzZSwgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3RyYXZlcnNlICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9jbGVhciAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfcmljaGNvbXBhcmUgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3dlYWtsaXN0b2Zmc2V0ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9pdGVyICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9pdGVybmV4dCAqLworICAgIHByb3BlcnR5X21ldGhvZHMsICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfbWV0aG9kcyAqLworICAgIHByb3BlcnR5X21lbWJlcnMsICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfbWVtYmVycyAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZ2V0c2V0ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9iYXNlICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9kaWN0ICovCisgICAgcHJvcGVydHlfZGVzY3JfZ2V0LCAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9kZXNjcl9nZXQgKi8KKyAgICBwcm9wZXJ0eV9kZXNjcl9zZXQsICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2Rlc2NyX3NldCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZGljdG9mZnNldCAqLworICAgIHByb3BlcnR5X2luaXQsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfaW5pdCAqLworICAgIFB5VHlwZV9HZW5lcmljQWxsb2MsICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfYWxsb2MgKi8KKyAgICBQeVR5cGVfR2VuZXJpY05ldywgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX25ldyAqLworICAgIFB5T2JqZWN0X0dDX0RlbCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZnJlZSAqLworfTsKZGlmZiAtLWdpdCBhL1B5dGhvbi0yLjcuNS9PYmplY3RzL2RpY3Rub3Rlcy50eHQgYi9QeXRob24tMi43LjUvT2JqZWN0cy9kaWN0bm90ZXMudHh0Cm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQzYWE3NzQKLS0tIC9kZXYvbnVsbAorKysgYi9QeXRob24tMi43LjUvT2JqZWN0cy9kaWN0bm90ZXMudHh0CkBAIC0wLDAgKzEsMjcwIEBACitOT1RFUyBPTiBPUFRJTUlaSU5HIERJQ1RJT05BUklFUworPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KKworCitQcmluY2lwYWwgVXNlIENhc2VzIGZvciBEaWN0aW9uYXJpZXMKKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitQYXNzaW5nIGtleXdvcmQgYXJndW1lbnRzCisgICAgVHlwaWNhbGx5LCBvbmUgcmVhZCBhbmQgb25lIHdyaXRlIGZvciAxIHRvIDMgZWxlbWVudHMuCisgICAgT2NjdXJzIGZyZXF1ZW50bHkgaW4gbm9ybWFsIHB5dGhvbiBjb2RlLgorCitDbGFzcyBtZXRob2QgbG9va3VwCisgICAgRGljdGlvbmFyaWVzIHZhcnkgaW4gc2l6ZSB3aXRoIDggdG8gMTYgZWxlbWVudHMgYmVpbmcgY29tbW9uLgorICAgIFVzdWFsbHkgd3JpdHRlbiBvbmNlIHdpdGggbWFueSBsb29rdXBzLgorICAgIFdoZW4gYmFzZSBjbGFzc2VzIGFyZSB1c2VkLCB0aGVyZSBhcmUgbWFueSBmYWlsZWQgbG9va3VwcworICAgICAgICBmb2xsb3dlZCBieSBhIGxvb2t1cCBpbiBhIGJhc2UgY2xhc3MuCisKK0luc3RhbmNlIGF0dHJpYnV0ZSBsb29rdXAgYW5kIEdsb2JhbCB2YXJpYWJsZXMKKyAgICBEaWN0aW9uYXJpZXMgdmFyeSBpbiBzaXplLiAgNCB0byAxMCBlbGVtZW50cyBhcmUgY29tbW9uLgorICAgIEJvdGggcmVhZHMgYW5kIHdyaXRlcyBhcmUgY29tbW9uLgorCitCdWlsdGlucworICAgIEZyZXF1ZW50IHJlYWRzLiAgQWxtb3N0IG5ldmVyIHdyaXR0ZW4uCisgICAgU2l6ZSAxMjYgaW50ZXJuZWQgc3RyaW5ncyAoYXMgb2YgUHkyLjNiMSkuCisgICAgQSBmZXcga2V5cyBhcmUgYWNjZXNzZWQgbXVjaCBtb3JlIGZyZXF1ZW50bHkgdGhhbiBvdGhlcnMuCisKK1VuaXF1aWZpY2F0aW9uCisgICAgRGljdGlvbmFyaWVzIG9mIGFueSBzaXplLiAgQnVsayBvZiB3b3JrIGlzIGluIGNyZWF0aW9uLgorICAgIFJlcGVhdGVkIHdyaXRlcyB0byBhIHNtYWxsZXIgc2V0IG9mIGtleXMuCisgICAgU2luZ2xlIHJlYWQgb2YgZWFjaCBrZXkuCisgICAgU29tZSB1c2UgY2FzZXMgaGF2ZSB0d28gY29uc2VjdXRpdmUgYWNjZXNzZXMgdG8gdGhlIHNhbWUga2V5LgorCisgICAgKiBSZW1vdmluZyBkdXBsaWNhdGVzIGZyb20gYSBzZXF1ZW5jZS4KKyAgICAgICAgZGljdC5mcm9ta2V5cyhzZXFuKS5rZXlzKCkKKworICAgICogQ291bnRpbmcgZWxlbWVudHMgaW4gYSBzZXF1ZW5jZS4KKyAgICAgICAgZm9yIGUgaW4gc2VxbjoKKyAgICAgICAgICBkW2VdID0gZC5nZXQoZSwwKSArIDEKKworICAgICogQWNjdW11bGF0aW5nIHJlZmVyZW5jZXMgaW4gYSBkaWN0aW9uYXJ5IG9mIGxpc3RzOgorCisgICAgICAgIGZvciBwYWdlbnVtYmVyLCBwYWdlIGluIGVudW1lcmF0ZShwYWdlcyk6CisgICAgICAgICAgZm9yIHdvcmQgaW4gcGFnZToKKyAgICAgICAgICAgIGQuc2V0ZGVmYXVsdCh3b3JkLCBbXSkuYXBwZW5kKHBhZ2VudW1iZXIpCisKKyAgICBOb3RlLCB0aGUgc2Vjb25kIGV4YW1wbGUgaXMgYSB1c2UgY2FzZSBjaGFyYWN0ZXJpemVkIGJ5IGEgZ2V0IGFuZCBzZXQKKyAgICB0byB0aGUgc2FtZSBrZXkuICBUaGVyZSBhcmUgc2ltaWxhciB1c2UgY2FzZXMgd2l0aCBhIF9fY29udGFpbnNfXworICAgIGZvbGxvd2VkIGJ5IGEgZ2V0LCBzZXQsIG9yIGRlbCB0byB0aGUgc2FtZSBrZXkuICBQYXJ0IG9mIHRoZQorICAgIGp1c3RpZmljYXRpb24gZm9yIGQuc2V0ZGVmYXVsdCBpcyBjb21iaW5pbmcgdGhlIHR3byBsb29rdXBzIGludG8gb25lLgorCitNZW1iZXJzaGlwIFRlc3RpbmcKKyAgICBEaWN0aW9uYXJpZXMgb2YgYW55IHNpemUuICBDcmVhdGVkIG9uY2UgYW5kIHRoZW4gcmFyZWx5IGNoYW5nZXMuCisgICAgU2luZ2xlIHdyaXRlIHRvIGVhY2gga2V5LgorICAgIE1hbnkgY2FsbHMgdG8gX19jb250YWluc19fKCkgb3IgaGFzX2tleSgpLgorICAgIFNpbWlsYXIgYWNjZXNzIHBhdHRlcm5zIG9jY3VyIHdpdGggcmVwbGFjZW1lbnQgZGljdGlvbmFyaWVzCisgICAgICAgIHN1Y2ggYXMgd2l0aCB0aGUgJSBmb3JtYXR0aW5nIG9wZXJhdG9yLgorCitEeW5hbWljIE1hcHBpbmdzCisgICAgQ2hhcmFjdGVyaXplZCBieSBkZWxldGlvbnMgaW50ZXJzcGVyc2VkIHdpdGggYWRkcyBhbmQgcmVwbGFjZW1lbnRzLgorICAgIFBlcmZvcm1hbmNlIGJlbmVmaXRzIGdyZWF0bHkgZnJvbSB0aGUgcmUtdXNlIG9mIGR1bW15IGVudHJpZXMuCisKKworRGF0YSBMYXlvdXQgKGFzc3VtaW5nIGEgMzItYml0IGJveCB3aXRoIDY0IGJ5dGVzIHBlciBjYWNoZSBsaW5lKQorLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitTbWFsbGRpY3RzICg4IGVudHJpZXMpIGFyZSBhdHRhY2hlZCB0byB0aGUgZGljdG9iamVjdCBzdHJ1Y3R1cmUKK2FuZCB0aGUgd2hvbGUgZ3JvdXAgbmVhcmx5IGZpbGxzIHR3byBjb25zZWN1dGl2ZSBjYWNoZSBsaW5lcy4KKworTGFyZ2VyIGRpY3RzIHVzZSB0aGUgZmlyc3QgaGFsZiBvZiB0aGUgZGljdG9iamVjdCBzdHJ1Y3R1cmUgKG9uZSBjYWNoZQorbGluZSkgYW5kIGEgc2VwYXJhdGUsIGNvbnRpbnVvdXMgYmxvY2sgb2YgZW50cmllcyAoYXQgMTIgYnl0ZXMgZWFjaAorZm9yIGEgdG90YWwgb2YgNS4zMzMgZW50cmllcyBwZXIgY2FjaGUgbGluZSkuCisKKworVHVuYWJsZSBEaWN0aW9uYXJ5IFBhcmFtZXRlcnMKKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKKyogUHlEaWN0X01JTlNJWkUuICBDdXJyZW50bHkgc2V0IHRvIDguCisgICAgTXVzdCBiZSBhIHBvd2VyIG9mIHR3by4gIE5ldyBkaWN0cyBoYXZlIHRvIHplcm8tb3V0IGV2ZXJ5IGNlbGwuCisgICAgRWFjaCBhZGRpdGlvbmFsIDggY29uc3VtZXMgMS41IGNhY2hlIGxpbmVzLiAgSW5jcmVhc2luZyBpbXByb3ZlcworICAgIHRoZSBzcGFyc2VuZXNzIG9mIHNtYWxsIGRpY3Rpb25hcmllcyBidXQgY29zdHMgdGltZSB0byByZWFkIGluCisgICAgdGhlIGFkZGl0aW9uYWwgY2FjaGUgbGluZXMgaWYgdGhleSBhcmUgbm90IGFscmVhZHkgaW4gY2FjaGUuCisgICAgVGhhdCBjYXNlIGlzIGNvbW1vbiB3aGVuIGtleXdvcmQgYXJndW1lbnRzIGFyZSBwYXNzZWQuCisKKyogTWF4aW11bSBkaWN0aW9uYXJ5IGxvYWQgaW4gUHlEaWN0X1NldEl0ZW0uICBDdXJyZW50bHkgc2V0IHRvIDIvMy4KKyAgICBJbmNyZWFzaW5nIHRoaXMgcmF0aW8gbWFrZXMgZGljdGlvbmFyaWVzIG1vcmUgZGVuc2UgcmVzdWx0aW5nCisgICAgaW4gbW9yZSBjb2xsaXNpb25zLiAgRGVjcmVhc2luZyBpdCBpbXByb3ZlcyBzcGFyc2VuZXNzIGF0IHRoZQorICAgIGV4cGVuc2Ugb2Ygc3ByZWFkaW5nIGVudHJpZXMgb3ZlciBtb3JlIGNhY2hlIGxpbmVzIGFuZCBhdCB0aGUKKyAgICBjb3N0IG9mIHRvdGFsIG1lbW9yeSBjb25zdW1lZC4KKworICAgIFRoZSBsb2FkIHRlc3Qgb2NjdXJzIGluIGhpZ2hseSB0aW1lIHNlbnNpdGl2ZSBjb2RlLiAgRWZmb3J0cworICAgIHRvIG1ha2UgdGhlIHRlc3QgbW9yZSBjb21wbGV4IChmb3IgZXhhbXBsZSwgdmFyeWluZyB0aGUgbG9hZAorICAgIGZvciBkaWZmZXJlbnQgc2l6ZXMpIGhhdmUgZGVncmFkZWQgcGVyZm9ybWFuY2UuCisKKyogR3Jvd3RoIHJhdGUgdXBvbiBoaXR0aW5nIG1heGltdW0gbG9hZC4gIEN1cnJlbnRseSBzZXQgdG8gKjIuCisgICAgUmFpc2luZyB0aGlzIHRvICo0IHJlc3VsdHMgaW4gaGFsZiB0aGUgbnVtYmVyIG9mIHJlc2l6ZXMsCisgICAgbGVzcyBlZmZvcnQgdG8gcmVzaXplLCBiZXR0ZXIgc3BhcnNlbmVzcyBmb3Igc29tZSAoYnV0IG5vdAorICAgIGFsbCBkaWN0IHNpemVzKSwgYW5kIHBvdGVudGlhbGx5IGRvdWJsZXMgbWVtb3J5IGNvbnN1bXB0aW9uCisgICAgZGVwZW5kaW5nIG9uIHRoZSBzaXplIG9mIHRoZSBkaWN0aW9uYXJ5LiAgU2V0dGluZyB0byAqNAorICAgIGVsaW1pbmF0ZXMgZXZlcnkgb3RoZXIgcmVzaXplIHN0ZXAuCisKKyogTWF4aW11bSBzcGFyc2VuZXNzIChtaW5pbXVtIGRpY3Rpb25hcnkgbG9hZCkuICBXaGF0IHBlcmNlbnRhZ2UKKyAgICBvZiBlbnRyaWVzIGNhbiBiZSB1bnVzZWQgYmVmb3JlIHRoZSBkaWN0aW9uYXJ5IHNocmlua3MgdG8KKyAgICBmcmVlIHVwIG1lbW9yeSBhbmQgc3BlZWQgdXAgaXRlcmF0aW9uPyAgKFRoZSBjdXJyZW50IENQeXRob24KKyAgICBjb2RlIGRvZXMgbm90IHJlcHJlc2VudCB0aGlzIHBhcmFtZXRlciBkaXJlY3RseS4pCisKKyogU2hyaW5rYWdlIHJhdGUgdXBvbiBleGNlZWRpbmcgbWF4aW11bSBzcGFyc2VuZXNzLiAgVGhlIGN1cnJlbnQKKyAgICBDUHl0aG9uIGNvZGUgbmV2ZXIgZXZlbiBjaGVja3Mgc3BhcnNlbmVzcyB3aGVuIGRlbGV0aW5nIGEKKyAgICBrZXkuICBXaGVuIGEgbmV3IGtleSBpcyBhZGRlZCwgaXQgcmVzaXplcyBiYXNlZCBvbiB0aGUgbnVtYmVyCisgICAgb2YgYWN0aXZlIGtleXMsIHNvIHRoYXQgdGhlIGFkZGl0aW9uIG1heSB0cmlnZ2VyIHNocmlua2FnZQorICAgIHJhdGhlciB0aGFuIGdyb3d0aC4KKworVHVuZS11cHMgc2hvdWxkIGJlIG1lYXN1cmVkIGFjcm9zcyBhIGJyb2FkIHJhbmdlIG9mIGFwcGxpY2F0aW9ucyBhbmQKK3VzZSBjYXNlcy4gIEEgY2hhbmdlIHRvIGFueSBwYXJhbWV0ZXIgd2lsbCBoZWxwIGluIHNvbWUgc2l0dWF0aW9ucyBhbmQKK2h1cnQgaW4gb3RoZXJzLiAgVGhlIGtleSBpcyB0byBmaW5kIHNldHRpbmdzIHRoYXQgaGVscCB0aGUgbW9zdCBjb21tb24KK2Nhc2VzIGFuZCBkbyB0aGUgbGVhc3QgZGFtYWdlIHRvIHRoZSBsZXNzIGNvbW1vbiBjYXNlcy4gIFJlc3VsdHMgd2lsbAordmFyeSBkcmFtYXRpY2FsbHkgZGVwZW5kaW5nIG9uIHRoZSBleGFjdCBudW1iZXIgb2Yga2V5cywgd2hldGhlciB0aGUKK2tleXMgYXJlIGFsbCBzdHJpbmdzLCB3aGV0aGVyIHJlYWRzIG9yIHdyaXRlcyBkb21pbmF0ZSwgdGhlIGV4YWN0CitoYXNoIHZhbHVlcyBvZiB0aGUga2V5cyAoc29tZSBzZXRzIG9mIHZhbHVlcyBoYXZlIGZld2VyIGNvbGxpc2lvbnMgdGhhbgorb3RoZXJzKS4gIEFueSBvbmUgdGVzdCBvciBiZW5jaG1hcmsgaXMgbGlrZWx5IHRvIHByb3ZlIG1pc2xlYWRpbmcuCisKK1doaWxlIG1ha2luZyBhIGRpY3Rpb25hcnkgbW9yZSBzcGFyc2UgcmVkdWNlcyBjb2xsaXNpb25zLCBpdCBpbXBhaXJzCitpdGVyYXRpb24gYW5kIGtleSBsaXN0aW5nLiAgVGhvc2UgbWV0aG9kcyBsb29wIG92ZXIgZXZlcnkgcG90ZW50aWFsCitlbnRyeS4gIERvdWJsaW5nIHRoZSBzaXplIG9mIGRpY3Rpb25hcnkgcmVzdWx0cyBpbiB0d2ljZSBhcyBtYW55Citub24tb3ZlcmxhcHBpbmcgbWVtb3J5IGFjY2Vzc2VzIGZvciBrZXlzKCksIGl0ZW1zKCksIHZhbHVlcygpLAorX19pdGVyX18oKSwgaXRlcmtleXMoKSwgaXRlcml0ZW1zKCksIGl0ZXJ2YWx1ZXMoKSwgYW5kIHVwZGF0ZSgpLgorQWxzbywgZXZlcnkgZGljdGlvbmFyeSBpdGVyYXRlcyBhdCBsZWFzdCB0d2ljZSwgb25jZSBmb3IgdGhlIG1lbXNldCgpCit3aGVuIGl0IGlzIGNyZWF0ZWQgYW5kIG9uY2UgYnkgZGVhbGxvYygpLgorCitEaWN0aW9uYXJ5IG9wZXJhdGlvbnMgaW52b2x2aW5nIG9ubHkgYSBzaW5nbGUga2V5IGNhbiBiZSBPKDEpIHVubGVzcyAKK3Jlc2l6aW5nIGlzIHBvc3NpYmxlLiAgQnkgY2hlY2tpbmcgZm9yIGEgcmVzaXplIG9ubHkgd2hlbiB0aGUgCitkaWN0aW9uYXJ5IGNhbiBncm93IChhbmQgbWF5ICpyZXF1aXJlKiByZXNpemluZyksIG90aGVyIG9wZXJhdGlvbnMKK3JlbWFpbiBPKDEpLCBhbmQgdGhlIG9kZHMgb2YgcmVzaXplIHRocmFzaGluZyBvciBtZW1vcnkgZnJhZ21lbnRhdGlvbgorYXJlIHJlZHVjZWQuIEluIHBhcnRpY3VsYXIsIGFuIGFsZ29yaXRobSB0aGF0IGVtcHRpZXMgYSBkaWN0aW9uYXJ5CitieSByZXBlYXRlZGx5IGludm9raW5nIC5wb3Agd2lsbCBzZWUgbm8gcmVzaXppbmcsIHdoaWNoIG1pZ2h0Citub3QgYmUgbmVjZXNzYXJ5IGF0IGFsbCBiZWNhdXNlIHRoZSBkaWN0aW9uYXJ5IGlzIGV2ZW50dWFsbHkKK2Rpc2NhcmRlZCBlbnRpcmVseS4KKworCitSZXN1bHRzIG9mIENhY2hlIExvY2FsaXR5IEV4cGVyaW1lbnRzCistLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisKK1doZW4gYW4gZW50cnkgaXMgcmV0cmlldmVkIGZyb20gbWVtb3J5LCA0LjMzMyBhZGphY2VudCBlbnRyaWVzIGFyZSBhbHNvCityZXRyaWV2ZWQgaW50byBhIGNhY2hlIGxpbmUuICBTaW5jZSBhY2Nlc3NpbmcgaXRlbXMgaW4gY2FjaGUgaXMgKm11Y2gqCitjaGVhcGVyIHRoYW4gYSBjYWNoZSBtaXNzLCBhbiBlbnRpY2luZyBpZGVhIGlzIHRvIHByb2JlIHRoZSBhZGphY2VudAorZW50cmllcyBhcyBhIGZpcnN0IHN0ZXAgaW4gY29sbGlzaW9uIHJlc29sdXRpb24uICBVbmZvcnR1bmF0ZWx5LCB0aGUKK2ludHJvZHVjdGlvbiBvZiBhbnkgcmVndWxhcml0eSBpbnRvIGNvbGxpc2lvbiBzZWFyY2hlcyByZXN1bHRzIGluIG1vcmUKK2NvbGxpc2lvbnMgdGhhbiB0aGUgY3VycmVudCByYW5kb20gY2hhaW5pbmcgYXBwcm9hY2guCisKK0V4cGxvaXRpbmcgY2FjaGUgbG9jYWxpdHkgYXQgdGhlIGV4cGVuc2Ugb2YgYWRkaXRpb25hbCBjb2xsaXNpb25zIGZhaWxzCit0byBwYXlvZmYgd2hlbiB0aGUgZW50cmllcyBhcmUgYWxyZWFkeSBsb2FkZWQgaW4gY2FjaGUgKHRoZSBleHBlbnNlCitpcyBwYWlkIHdpdGggbm8gY29tcGVuc2F0aW5nIGJlbmVmaXQpLiAgVGhpcyBvY2N1cnMgaW4gc21hbGwgZGljdGlvbmFyaWVzCit3aGVyZSB0aGUgd2hvbGUgZGljdGlvbmFyeSBmaXRzIGludG8gYSBwYWlyIG9mIGNhY2hlIGxpbmVzLiAgSXQgYWxzbworb2NjdXJzIGZyZXF1ZW50bHkgaW4gbGFyZ2UgZGljdGlvbmFyaWVzIHdoaWNoIGhhdmUgYSBjb21tb24gYWNjZXNzIHBhdHRlcm4KK3doZXJlIHNvbWUga2V5cyBhcmUgYWNjZXNzZWQgbXVjaCBtb3JlIGZyZXF1ZW50bHkgdGhhbiBvdGhlcnMuICBUaGUKK21vcmUgcG9wdWxhciBlbnRyaWVzICphbmQqIHRoZWlyIGNvbGxpc2lvbiBjaGFpbnMgdGVuZCB0byByZW1haW4gaW4gY2FjaGUuCisKK1RvIGV4cGxvaXQgY2FjaGUgbG9jYWxpdHksIGNoYW5nZSB0aGUgY29sbGlzaW9uIHJlc29sdXRpb24gc2VjdGlvbgoraW4gbG9va2RpY3QoKSBhbmQgbG9va2RpY3Rfc3RyaW5nKCkuICBTZXQgaV49MSBhdCB0aGUgdG9wIG9mIHRoZQorbG9vcCBhbmQgbW92ZSB0aGUgIGkgPSAoaSA8PCAyKSArIGkgKyBwZXJ0dXJiICsgMSB0byBhbiB1bnJvbGxlZAordmVyc2lvbiBvZiB0aGUgbG9vcC4KKworVGhpcyBvcHRpbWl6YXRpb24gc3RyYXRlZ3kgY2FuIGJlIGxldmVyYWdlZCBpbiBzZXZlcmFsIHdheXM6CisKKyogSWYgdGhlIGRpY3Rpb25hcnkgaXMga2VwdCBzcGFyc2UgKHRocm91Z2ggdGhlIHR1bmFibGUgcGFyYW1ldGVycyksCit0aGVuIHRoZSBvY2N1cnJlbmNlIG9mIGFkZGl0aW9uYWwgY29sbGlzaW9ucyBpcyBsZXNzZW5lZC4KKworKiBJZiBsb29rZGljdCgpIGFuZCBsb29rZGljdF9zdHJpbmcoKSBhcmUgc3BlY2lhbGl6ZWQgZm9yIHNtYWxsIGRpY3RzCithbmQgZm9yIGxhcmdlZGljdHMsIHRoZW4gdGhlIHZlcnNpb25zIGZvciBsYXJnZV9kaWN0cyBjYW4gYmUgZ2l2ZW4KK2FuIGFsdGVybmF0ZSBzZWFyY2ggc3RyYXRlZ3kgd2l0aG91dCBpbmNyZWFzaW5nIGNvbGxpc2lvbnMgaW4gc21hbGwgZGljdHMKK3doaWNoIGFscmVhZHkgaGF2ZSB0aGUgbWF4aW11bSBiZW5lZml0IG9mIGNhY2hlIGxvY2FsaXR5LgorCisqIElmIHRoZSB1c2UgY2FzZSBmb3IgYSBkaWN0aW9uYXJ5IGlzIGtub3duIHRvIGhhdmUgYSByYW5kb20ga2V5CithY2Nlc3MgcGF0dGVybiAoYXMgb3Bwb3NlZCB0byBhIG1vcmUgY29tbW9uIHBhdHRlcm4gd2l0aCBhIFppcGYncyBsYXcKK2Rpc3RyaWJ1dGlvbiksIHRoZW4gdGhlcmUgd2lsbCBiZSBtb3JlIGJlbmVmaXQgZm9yIGxhcmdlIGRpY3Rpb25hcmllcworYmVjYXVzZSBhbnkgZ2l2ZW4ga2V5IGlzIG5vIG1vcmUgbGlrZWx5IHRoYW4gYW5vdGhlciB0byBhbHJlYWR5IGJlCitpbiBjYWNoZS4KKworKiBJbiB1c2UgY2FzZXMgd2l0aCBwYWlyZWQgYWNjZXNzZXMgdG8gdGhlIHNhbWUga2V5LCB0aGUgc2Vjb25kIGFjY2VzcworaXMgYWx3YXlzIGluIGNhY2hlIGFuZCBnZXRzIG5vIGJlbmVmaXQgZnJvbSBlZmZvcnRzIHRvIGZ1cnRoZXIgaW1wcm92ZQorY2FjaGUgbG9jYWxpdHkuCisKK09wdGltaXppbmcgdGhlIFNlYXJjaCBvZiBTbWFsbCBEaWN0aW9uYXJpZXMKKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworSWYgbG9va2RpY3QoKSBhbmQgbG9va2RpY3Rfc3RyaW5nKCkgYXJlIHNwZWNpYWxpemVkIGZvciBzbWFsbGVyIGRpY3Rpb25hcmllcywKK3RoZW4gYSBjdXN0b20gc2VhcmNoIGFwcHJvYWNoIGNhbiBiZSBpbXBsZW1lbnRlZCB0aGF0IGV4cGxvaXRzIHRoZSBzbWFsbAorc2VhcmNoIHNwYWNlIGFuZCBjYWNoZSBsb2NhbGl0eS4KKworKiBUaGUgc2ltcGxlc3QgZXhhbXBsZSBpcyBhIGxpbmVhciBzZWFyY2ggb2YgY29udGlndW91cyBlbnRyaWVzLiAgVGhpcyBpcworICBzaW1wbGUgdG8gaW1wbGVtZW50LCBndWFyYW50ZWVkIHRvIHRlcm1pbmF0ZSByYXBpZGx5LCBuZXZlciBzZWFyY2hlcworICB0aGUgc2FtZSBlbnRyeSB0d2ljZSwgYW5kIHByZWNsdWRlcyB0aGUgbmVlZCB0byBjaGVjayBmb3IgZHVtbXkgZW50cmllcy4KKworKiBBIG1vcmUgYWR2YW5jZWQgZXhhbXBsZSBpcyBhIHNlbGYtb3JnYW5pemluZyBzZWFyY2ggc28gdGhhdCB0aGUgbW9zdAorICBmcmVxdWVudGx5IGFjY2Vzc2VkIGVudHJpZXMgZ2V0IHByb2JlZCBmaXJzdC4gIFRoZSBvcmdhbml6YXRpb24KKyAgYWRhcHRzIGlmIHRoZSBhY2Nlc3MgcGF0dGVybiBjaGFuZ2VzIG92ZXIgdGltZS4gIFRyZWFwcyBhcmUgaWRlYWxseQorICBzdWl0ZWQgZm9yIHNlbGYtb3JnYW5pemF0aW9uIHdpdGggdGhlIG1vc3QgY29tbW9uIGVudHJpZXMgYXQgdGhlCisgIHRvcCBvZiB0aGUgaGVhcCBhbmQgYSByYXBpZCBiaW5hcnkgc2VhcmNoIHBhdHRlcm4uICBNb3N0IHByb2JlcyBhbmQKKyAgcmVzdWx0cyBhcmUgYWxsIGxvY2F0ZWQgYXQgdGhlIHRvcCBvZiB0aGUgdHJlZSBhbGxvd2luZyB0aGVtIGFsbCB0bworICBiZSBsb2NhdGVkIGluIG9uZSBvciB0d28gY2FjaGUgbGluZXMuCisKKyogQWxzbywgc21hbGwgZGljdGlvbmFyaWVzIG1heSBiZSBtYWRlIG1vcmUgZGVuc2UsIHBlcmhhcHMgZmlsbGluZyBhbGwKKyAgZWlnaHQgY2VsbHMgdG8gdGFrZSB0aGUgbWF4aW11bSBhZHZhbnRhZ2Ugb2YgdHdvIGNhY2hlIGxpbmVzLgorCisKK1N0cmF0ZWd5IFBhdHRlcm4KKy0tLS0tLS0tLS0tLS0tLS0KKworQ29uc2lkZXIgYWxsb3dpbmcgdGhlIHVzZXIgdG8gc2V0IHRoZSB0dW5hYmxlIHBhcmFtZXRlcnMgb3IgdG8gc2VsZWN0IGEKK3BhcnRpY3VsYXIgc2VhcmNoIG1ldGhvZC4gIFNpbmNlIHNvbWUgZGljdGlvbmFyeSB1c2UgY2FzZXMgaGF2ZSBrbm93bgorc2l6ZXMgYW5kIGFjY2VzcyBwYXR0ZXJucywgdGhlIHVzZXIgbWF5IGJlIGFibGUgdG8gcHJvdmlkZSB1c2VmdWwgaGludHMuCisKKzEpIEZvciBleGFtcGxlLCBpZiBtZW1iZXJzaGlwIHRlc3Rpbmcgb3IgbG9va3VwcyBkb21pbmF0ZSBydW50aW1lIGFuZCBtZW1vcnkKKyAgIGlzIG5vdCBhdCBhIHByZW1pdW0sIHRoZSB1c2VyIG1heSBiZW5lZml0IGZyb20gc2V0dGluZyB0aGUgbWF4aW11bSBsb2FkCisgICByYXRpbyBhdCA1JSBvciAxMCUgaW5zdGVhZCBvZiB0aGUgdXN1YWwgNjYuNyUuICBUaGlzIHdpbGwgc2hhcnBseQorICAgY3VydGFpbCB0aGUgbnVtYmVyIG9mIGNvbGxpc2lvbnMgYnV0IHdpbGwgaW5jcmVhc2UgaXRlcmF0aW9uIHRpbWUuCisgICBUaGUgYnVpbHRpbiBuYW1lc3BhY2UgaXMgYSBwcmltZSBleGFtcGxlIG9mIGEgZGljdGlvbmFyeSB0aGF0IGNhbgorICAgYmVuZWZpdCBmcm9tIGJlaW5nIGhpZ2hseSBzcGFyc2UuCisKKzIpIERpY3Rpb25hcnkgY3JlYXRpb24gdGltZSBjYW4gYmUgc2hvcnRlbmVkIGluIGNhc2VzIHdoZXJlIHRoZSB1bHRpbWF0ZQorICAgc2l6ZSBvZiB0aGUgZGljdGlvbmFyeSBpcyBrbm93biBpbiBhZHZhbmNlLiAgVGhlIGRpY3Rpb25hcnkgY2FuIGJlCisgICBwcmUtc2l6ZWQgc28gdGhhdCBubyByZXNpemUgb3BlcmF0aW9ucyBhcmUgcmVxdWlyZWQgZHVyaW5nIGNyZWF0aW9uLgorICAgTm90IG9ubHkgZG9lcyB0aGlzIHNhdmUgcmVzaXplcywgYnV0IHRoZSBrZXkgaW5zZXJ0aW9uIHdpbGwgZ28KKyAgIG1vcmUgcXVpY2tseSBiZWNhdXNlIHRoZSBmaXJzdCBoYWxmIG9mIHRoZSBrZXlzIHdpbGwgYmUgaW5zZXJ0ZWQgaW50bworICAgYSBtb3JlIHNwYXJzZSBlbnZpcm9ubWVudCB0aGFuIGJlZm9yZS4gIFRoZSBwcmVjb25kaXRpb25zIGZvciB0aGlzCisgICBzdHJhdGVneSBhcmlzZSB3aGVuZXZlciBhIGRpY3Rpb25hcnkgaXMgY3JlYXRlZCBmcm9tIGEga2V5IG9yIGl0ZW0KKyAgIHNlcXVlbmNlIGFuZCB0aGUgbnVtYmVyIG9mICp1bmlxdWUqIGtleXMgaXMga25vd24uCisKKzMpIElmIHRoZSBrZXkgc3BhY2UgaXMgbGFyZ2UgYW5kIHRoZSBhY2Nlc3MgcGF0dGVybiBpcyBrbm93biB0byBiZSByYW5kb20sCisgICB0aGVuIHNlYXJjaCBzdHJhdGVnaWVzIGV4cGxvaXRpbmcgY2FjaGUgbG9jYWxpdHkgY2FuIGJlIGZydWl0ZnVsLgorICAgVGhlIHByZWNvbmRpdGlvbnMgZm9yIHRoaXMgc3RyYXRlZ3kgYXJpc2UgaW4gc2ltdWxhdGlvbnMgYW5kCisgICBudW1lcmljYWwgYW5hbHlzaXMuCisKKzQpIElmIHRoZSBrZXlzIGFyZSBmaXhlZCBhbmQgdGhlIGFjY2VzcyBwYXR0ZXJuIHN0cm9uZ2x5IGZhdm9ycyBzb21lIG9mCisgICB0aGUga2V5cywgdGhlbiB0aGUgZW50cmllcyBjYW4gYmUgc3RvcmVkIGNvbnRpZ3VvdXNseSBhbmQgYWNjZXNzZWQKKyAgIHdpdGggYSBsaW5lYXIgc2VhcmNoIG9yIHRyZWFwLiAgVGhpcyBleHBsb2l0cyBrbm93bGVkZ2Ugb2YgdGhlIGRhdGEsCisgICBjYWNoZSBsb2NhbGl0eSwgYW5kIGEgc2ltcGxpZmllZCBzZWFyY2ggcm91dGluZS4gIEl0IGFsc28gZWxpbWluYXRlcworICAgdGhlIG5lZWQgdG8gdGVzdCBmb3IgZHVtbXkgZW50cmllcyBvbiBlYWNoIHByb2JlLiAgVGhlIHByZWNvbmRpdGlvbnMKKyAgIGZvciB0aGlzIHN0cmF0ZWd5IGFyaXNlIGluIHN5bWJvbCB0YWJsZXMgYW5kIGluIHRoZSBidWlsdGluIGRpY3Rpb25hcnkuCisKKworUmVhZG9ubHkgRGljdGlvbmFyaWVzCistLS0tLS0tLS0tLS0tLS0tLS0tLS0KK1NvbWUgZGljdGlvbmFyeSB1c2UgY2FzZXMgcGFzcyB0aHJvdWdoIGEgYnVpbGQgc3RhZ2UgYW5kIHRoZW4gbW92ZSB0byBhCittb3JlIGhlYXZpbHkgZXhlcmNpc2VkIGxvb2t1cCBzdGFnZSB3aXRoIG5vIGZ1cnRoZXIgY2hhbmdlcyB0byB0aGUKK2RpY3Rpb25hcnkuCisKK0FuIGlkZWEgdGhhdCBlbWVyZ2VkIG9uIHB5dGhvbi1kZXYgaXMgdG8gYmUgYWJsZSB0byBjb252ZXJ0IGEgZGljdGlvbmFyeQordG8gYSByZWFkLW9ubHkgc3RhdGUuICBUaGlzIGNhbiBoZWxwIHByZXZlbnQgcHJvZ3JhbW1pbmcgZXJyb3JzIGFuZCBhbHNvCitwcm92aWRlIGtub3dsZWRnZSB0aGF0IGNhbiBiZSBleHBsb2l0ZWQgZm9yIGxvb2t1cCBvcHRpbWl6YXRpb24uCisKK1RoZSBkaWN0aW9uYXJ5IGNhbiBiZSBpbW1lZGlhdGVseSByZWJ1aWx0IChlbGltaW5hdGluZyBkdW1teSBlbnRyaWVzKSwKK3Jlc2l6ZWQgKHRvIGFuIGFwcHJvcHJpYXRlIGxldmVsIG9mIHNwYXJzZW5lc3MpLCBhbmQgdGhlIGtleXMgY2FuIGJlCitqb3N0bGVkICh0byBtaW5pbWl6ZSBjb2xsaXNpb25zKS4gIFRoZSBsb29rZGljdCgpIHJvdXRpbmUgY2FuIHRoZW4KK2VsaW1pbmF0ZSB0aGUgdGVzdCBmb3IgZHVtbXkgZW50cmllcyAoc2F2aW5nIGFib3V0IDEvNCBvZiB0aGUgdGltZQorc3BlbnQgaW4gdGhlIGNvbGxpc2lvbiByZXNvbHV0aW9uIGxvb3ApLgorCitBbiBhZGRpdGlvbmFsIHBvc3NpYmlsaXR5IGlzIHRvIGluc2VydCBsaW5rcyBpbnRvIHRoZSBlbXB0eSBzcGFjZXMKK3NvIHRoYXQgZGljdGlvbmFyeSBpdGVyYXRpb24gY2FuIHByb2NlZWQgaW4gbGVuKGQpIHN0ZXBzIGluc3RlYWQgb2YKKyhtcC0+bWFzayArIDEpIHN0ZXBzLiAgQWx0ZXJuYXRpdmVseSwgYSBzZXBhcmF0ZSB0dXBsZSBvZiBrZXlzIGNhbiBiZQora2VwdCBqdXN0IGZvciBpdGVyYXRpb24uCisKKworQ2FjaGluZyBMb29rdXBzCistLS0tLS0tLS0tLS0tLS0KK1RoZSBpZGVhIGlzIHRvIGV4cGxvaXQga2V5IGFjY2VzcyBwYXR0ZXJucyBieSBhbnRpY2lwYXRpbmcgZnV0dXJlIGxvb2t1cHMKK2Jhc2VkIG9uIHByZXZpb3VzIGxvb2t1cHMuCisKK1RoZSBzaW1wbGVzdCBpbmNhcm5hdGlvbiBpcyB0byBzYXZlIHRoZSBtb3N0IHJlY2VudGx5IGFjY2Vzc2VkIGVudHJ5LgorVGhpcyBnaXZlcyBvcHRpbWFsIHBlcmZvcm1hbmNlIGZvciB1c2UgY2FzZXMgd2hlcmUgZXZlcnkgZ2V0IGlzIGZvbGxvd2VkCitieSBhIHNldCBvciBkZWwgdG8gdGhlIHNhbWUga2V5LgpkaWZmIC0tZ2l0IGEvUHl0aG9uLTIuNy41L09iamVjdHMvZGljdG9iamVjdC5jIGIvUHl0aG9uLTIuNy41L09iamVjdHMvZGljdG9iamVjdC5jCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmJhMzZiMTgKLS0tIC9kZXYvbnVsbAorKysgYi9QeXRob24tMi43LjUvT2JqZWN0cy9kaWN0b2JqZWN0LmMKQEAgLTAsMCArMSwzMjQ0IEBACisKKy8qIERpY3Rpb25hcnkgb2JqZWN0IGltcGxlbWVudGF0aW9uIHVzaW5nIGEgaGFzaCB0YWJsZSAqLworCisvKiBUaGUgZGlzdHJpYnV0aW9uIGluY2x1ZGVzIGEgc2VwYXJhdGUgZmlsZSwgT2JqZWN0cy9kaWN0bm90ZXMudHh0LAorICAgZGVzY3JpYmluZyBleHBsb3JhdGlvbnMgaW50byBkaWN0aW9uYXJ5IGRlc2lnbiBhbmQgb3B0aW1pemF0aW9uLgorICAgSXQgY292ZXJzIHR5cGljYWwgZGljdGlvbmFyeSB1c2UgcGF0dGVybnMsIHRoZSBwYXJhbWV0ZXJzIGZvcgorICAgdHVuaW5nIGRpY3Rpb25hcmllcywgYW5kIHNldmVyYWwgaWRlYXMgZm9yIHBvc3NpYmxlIG9wdGltaXphdGlvbnMuCisqLworCisjaW5jbHVkZSAiUHl0aG9uLmgiCisKKworLyogU2V0IGEga2V5IGVycm9yIHdpdGggdGhlIHNwZWNpZmllZCBhcmd1bWVudCwgd3JhcHBpbmcgaXQgaW4gYQorICogdHVwbGUgYXV0b21hdGljYWxseSBzbyB0aGF0IHR1cGxlIGtleXMgYXJlIG5vdCB1bnBhY2tlZCBhcyB0aGUKKyAqIGV4Y2VwdGlvbiBhcmd1bWVudHMuICovCitzdGF0aWMgdm9pZAorc2V0X2tleV9lcnJvcihQeU9iamVjdCAqYXJnKQoreworICAgIFB5T2JqZWN0ICp0dXA7CisgICAgdHVwID0gUHlUdXBsZV9QYWNrKDEsIGFyZyk7CisgICAgaWYgKCF0dXApCisgICAgICAgIHJldHVybjsgLyogY2FsbGVyIHdpbGwgZXhwZWN0IGVycm9yIHRvIGJlIHNldCBhbnl3YXkgKi8KKyAgICBQeUVycl9TZXRPYmplY3QoUHlFeGNfS2V5RXJyb3IsIHR1cCk7CisgICAgUHlfREVDUkVGKHR1cCk7Cit9CisKKy8qIERlZmluZSB0aGlzIG91dCBpZiB5b3UgZG9uJ3Qgd2FudCBjb252ZXJzaW9uIHN0YXRpc3RpY3Mgb24gZXhpdC4gKi8KKyN1bmRlZiBTSE9XX0NPTlZFUlNJT05fQ09VTlRTCisKKy8qIFNlZSBsYXJnZSBjb21tZW50IGJsb2NrIGJlbG93LiAgVGhpcyBtdXN0IGJlID49IDEuICovCisjZGVmaW5lIFBFUlRVUkJfU0hJRlQgNQorCisvKgorTWFqb3Igc3VidGxldGllcyBhaGVhZDogIE1vc3QgaGFzaCBzY2hlbWVzIGRlcGVuZCBvbiBoYXZpbmcgYSAiZ29vZCIgaGFzaAorZnVuY3Rpb24sIGluIHRoZSBzZW5zZSBvZiBzaW11bGF0aW5nIHJhbmRvbW5lc3MuICBQeXRob24gZG9lc24ndDogIGl0cyBtb3N0CitpbXBvcnRhbnQgaGFzaCBmdW5jdGlvbnMgKGZvciBzdHJpbmdzIGFuZCBpbnRzKSBhcmUgdmVyeSByZWd1bGFyIGluIGNvbW1vbgorY2FzZXM6CisKKz4+PiBtYXAoaGFzaCwgKDAsIDEsIDIsIDMpKQorWzAsIDEsIDIsIDNdCis+Pj4gbWFwKGhhc2gsICgibmFtZWEiLCAibmFtZWIiLCAibmFtZWMiLCAibmFtZWQiKSkKK1stMTY1ODM5ODQ1NywgLTE2NTgzOTg0NjAsIC0xNjU4Mzk4NDU5LCAtMTY1ODM5ODQ2Ml0KKz4+PgorCitUaGlzIGlzbid0IG5lY2Vzc2FyaWx5IGJhZCEgIFRvIHRoZSBjb250cmFyeSwgaW4gYSB0YWJsZSBvZiBzaXplIDIqKmksIHRha2luZwordGhlIGxvdy1vcmRlciBpIGJpdHMgYXMgdGhlIGluaXRpYWwgdGFibGUgaW5kZXggaXMgZXh0cmVtZWx5IGZhc3QsIGFuZCB0aGVyZQorYXJlIG5vIGNvbGxpc2lvbnMgYXQgYWxsIGZvciBkaWN0cyBpbmRleGVkIGJ5IGEgY29udGlndW91cyByYW5nZSBvZiBpbnRzLgorVGhlIHNhbWUgaXMgYXBwcm94aW1hdGVseSB0cnVlIHdoZW4ga2V5cyBhcmUgImNvbnNlY3V0aXZlIiBzdHJpbmdzLiAgU28gdGhpcworZ2l2ZXMgYmV0dGVyLXRoYW4tcmFuZG9tIGJlaGF2aW9yIGluIGNvbW1vbiBjYXNlcywgYW5kIHRoYXQncyB2ZXJ5IGRlc2lyYWJsZS4KKworT1RPSCwgd2hlbiBjb2xsaXNpb25zIG9jY3VyLCB0aGUgdGVuZGVuY3kgdG8gZmlsbCBjb250aWd1b3VzIHNsaWNlcyBvZiB0aGUKK2hhc2ggdGFibGUgbWFrZXMgYSBnb29kIGNvbGxpc2lvbiByZXNvbHV0aW9uIHN0cmF0ZWd5IGNydWNpYWwuICBUYWtpbmcgb25seQordGhlIGxhc3QgaSBiaXRzIG9mIHRoZSBoYXNoIGNvZGUgaXMgYWxzbyB2dWxuZXJhYmxlOiAgZm9yIGV4YW1wbGUsIGNvbnNpZGVyCitbaSA8PCAxNiBmb3IgaSBpbiByYW5nZSgyMDAwMCldIGFzIGEgc2V0IG9mIGtleXMuICBTaW5jZSBpbnRzIGFyZSB0aGVpciBvd24KK2hhc2ggY29kZXMsIGFuZCB0aGlzIGZpdHMgaW4gYSBkaWN0IG9mIHNpemUgMioqMTUsIHRoZSBsYXN0IDE1IGJpdHMgb2YgZXZlcnkKK2hhc2ggY29kZSBhcmUgYWxsIDA6ICB0aGV5ICphbGwqIG1hcCB0byB0aGUgc2FtZSB0YWJsZSBpbmRleC4KKworQnV0IGNhdGVyaW5nIHRvIHVudXN1YWwgY2FzZXMgc2hvdWxkIG5vdCBzbG93IHRoZSB1c3VhbCBvbmVzLCBzbyB3ZSBqdXN0IHRha2UKK3RoZSBsYXN0IGkgYml0cyBhbnl3YXkuICBJdCdzIHVwIHRvIGNvbGxpc2lvbiByZXNvbHV0aW9uIHRvIGRvIHRoZSByZXN0LiAgSWYKK3dlICp1c3VhbGx5KiBmaW5kIHRoZSBrZXkgd2UncmUgbG9va2luZyBmb3Igb24gdGhlIGZpcnN0IHRyeSAoYW5kLCBpdCB0dXJucworb3V0LCB3ZSB1c3VhbGx5IGRvIC0tIHRoZSB0YWJsZSBsb2FkIGZhY3RvciBpcyBrZXB0IHVuZGVyIDIvMywgc28gdGhlIG9kZHMKK2FyZSBzb2xpZGx5IGluIG91ciBmYXZvciksIHRoZW4gaXQgbWFrZXMgYmVzdCBzZW5zZSB0byBrZWVwIHRoZSBpbml0aWFsIGluZGV4Citjb21wdXRhdGlvbiBkaXJ0IGNoZWFwLgorCitUaGUgZmlyc3QgaGFsZiBvZiBjb2xsaXNpb24gcmVzb2x1dGlvbiBpcyB0byB2aXNpdCB0YWJsZSBpbmRpY2VzIHZpYSB0aGlzCityZWN1cnJlbmNlOgorCisgICAgaiA9ICgoNSpqKSArIDEpIG1vZCAyKippCisKK0ZvciBhbnkgaW5pdGlhbCBqIGluIHJhbmdlKDIqKmkpLCByZXBlYXRpbmcgdGhhdCAyKippIHRpbWVzIGdlbmVyYXRlcyBlYWNoCitpbnQgaW4gcmFuZ2UoMioqaSkgZXhhY3RseSBvbmNlIChzZWUgYW55IHRleHQgb24gcmFuZG9tLW51bWJlciBnZW5lcmF0aW9uIGZvcgorcHJvb2YpLiAgQnkgaXRzZWxmLCB0aGlzIGRvZXNuJ3QgaGVscCBtdWNoOiAgbGlrZSBsaW5lYXIgcHJvYmluZyAoc2V0dGluZworaiArPSAxLCBvciBqIC09IDEsIG9uIGVhY2ggbG9vcCB0cmlwKSwgaXQgc2NhbnMgdGhlIHRhYmxlIGVudHJpZXMgaW4gYSBmaXhlZAorb3JkZXIuICBUaGlzIHdvdWxkIGJlIGJhZCwgZXhjZXB0IHRoYXQncyBub3QgdGhlIG9ubHkgdGhpbmcgd2UgZG8sIGFuZCBpdCdzCithY3R1YWxseSAqZ29vZCogaW4gdGhlIGNvbW1vbiBjYXNlcyB3aGVyZSBoYXNoIGtleXMgYXJlIGNvbnNlY3V0aXZlLiAgSW4gYW4KK2V4YW1wbGUgdGhhdCdzIHJlYWxseSB0b28gc21hbGwgdG8gbWFrZSB0aGlzIGVudGlyZWx5IGNsZWFyLCBmb3IgYSB0YWJsZSBvZgorc2l6ZSAyKiozIHRoZSBvcmRlciBvZiBpbmRpY2VzIGlzOgorCisgICAgMCAtPiAxIC0+IDYgLT4gNyAtPiA0IC0+IDUgLT4gMiAtPiAzIC0+IDAgW2FuZCBoZXJlIGl0J3MgcmVwZWF0aW5nXQorCitJZiB0d28gdGhpbmdzIGNvbWUgaW4gYXQgaW5kZXggNSwgdGhlIGZpcnN0IHBsYWNlIHdlIGxvb2sgYWZ0ZXIgaXMgaW5kZXggMiwKK25vdCA2LCBzbyBpZiBhbm90aGVyIGNvbWVzIGluIGF0IGluZGV4IDYgdGhlIGNvbGxpc2lvbiBhdCA1IGRpZG4ndCBodXJ0IGl0LgorTGluZWFyIHByb2JpbmcgaXMgZGVhZGx5IGluIHRoaXMgY2FzZSBiZWNhdXNlIHRoZXJlIHRoZSBmaXhlZCBwcm9iZSBvcmRlcgoraXMgdGhlICpzYW1lKiBhcyB0aGUgb3JkZXIgY29uc2VjdXRpdmUga2V5cyBhcmUgbGlrZWx5IHRvIGFycml2ZS4gIEJ1dCBpdCdzCitleHRyZW1lbHkgdW5saWtlbHkgaGFzaCBjb2RlcyB3aWxsIGZvbGxvdyBhIDUqaisxIHJlY3VycmVuY2UgYnkgYWNjaWRlbnQsCithbmQgY2VydGFpbiB0aGF0IGNvbnNlY3V0aXZlIGhhc2ggY29kZXMgZG8gbm90LgorCitUaGUgb3RoZXIgaGFsZiBvZiB0aGUgc3RyYXRlZ3kgaXMgdG8gZ2V0IHRoZSBvdGhlciBiaXRzIG9mIHRoZSBoYXNoIGNvZGUKK2ludG8gcGxheS4gIFRoaXMgaXMgZG9uZSBieSBpbml0aWFsaXppbmcgYSAodW5zaWduZWQpIHZyYmwgInBlcnR1cmIiIHRvIHRoZQorZnVsbCBoYXNoIGNvZGUsIGFuZCBjaGFuZ2luZyB0aGUgcmVjdXJyZW5jZSB0bzoKKworICAgIGogPSAoNSpqKSArIDEgKyBwZXJ0dXJiOworICAgIHBlcnR1cmIgPj49IFBFUlRVUkJfU0hJRlQ7CisgICAgdXNlIGogJSAyKippIGFzIHRoZSBuZXh0IHRhYmxlIGluZGV4OworCitOb3cgdGhlIHByb2JlIHNlcXVlbmNlIGRlcGVuZHMgKGV2ZW50dWFsbHkpIG9uIGV2ZXJ5IGJpdCBpbiB0aGUgaGFzaCBjb2RlLAorYW5kIHRoZSBwc2V1ZG8tc2NyYW1ibGluZyBwcm9wZXJ0eSBvZiByZWN1cnJpbmcgb24gNSpqKzEgaXMgbW9yZSB2YWx1YWJsZSwKK2JlY2F1c2UgaXQgcXVpY2tseSBtYWduaWZpZXMgc21hbGwgZGlmZmVyZW5jZXMgaW4gdGhlIGJpdHMgdGhhdCBkaWRuJ3QgYWZmZWN0Cit0aGUgaW5pdGlhbCBpbmRleC4gIE5vdGUgdGhhdCBiZWNhdXNlIHBlcnR1cmIgaXMgdW5zaWduZWQsIGlmIHRoZSByZWN1cnJlbmNlCitpcyBleGVjdXRlZCBvZnRlbiBlbm91Z2ggcGVydHVyYiBldmVudHVhbGx5IGJlY29tZXMgYW5kIHJlbWFpbnMgMC4gIEF0IHRoYXQKK3BvaW50ICh2ZXJ5IHJhcmVseSByZWFjaGVkKSB0aGUgcmVjdXJyZW5jZSBpcyBvbiAoanVzdCkgNSpqKzEgYWdhaW4sIGFuZAordGhhdCdzIGNlcnRhaW4gdG8gZmluZCBhbiBlbXB0eSBzbG90IGV2ZW50dWFsbHkgKHNpbmNlIGl0IGdlbmVyYXRlcyBldmVyeSBpbnQKK2luIHJhbmdlKDIqKmkpLCBhbmQgd2UgbWFrZSBzdXJlIHRoZXJlJ3MgYWx3YXlzIGF0IGxlYXN0IG9uZSBlbXB0eSBzbG90KS4KKworU2VsZWN0aW5nIGEgZ29vZCB2YWx1ZSBmb3IgUEVSVFVSQl9TSElGVCBpcyBhIGJhbGFuY2luZyBhY3QuICBZb3Ugd2FudCBpdAorc21hbGwgc28gdGhhdCB0aGUgaGlnaCBiaXRzIG9mIHRoZSBoYXNoIGNvZGUgY29udGludWUgdG8gYWZmZWN0IHRoZSBwcm9iZQorc2VxdWVuY2UgYWNyb3NzIGl0ZXJhdGlvbnM7IGJ1dCB5b3Ugd2FudCBpdCBsYXJnZSBzbyB0aGF0IGluIHJlYWxseSBiYWQgY2FzZXMKK3RoZSBoaWdoLW9yZGVyIGhhc2ggYml0cyBoYXZlIGFuIGVmZmVjdCBvbiBlYXJseSBpdGVyYXRpb25zLiAgNSB3YXMgInRoZQorYmVzdCIgaW4gbWluaW1pemluZyB0b3RhbCBjb2xsaXNpb25zIGFjcm9zcyBleHBlcmltZW50cyBUaW0gUGV0ZXJzIHJhbiAob24KK2JvdGggbm9ybWFsIGFuZCBwYXRob2xvZ2ljYWwgY2FzZXMpLCBidXQgNCBhbmQgNiB3ZXJlbid0IHNpZ25pZmljYW50bHkgd29yc2UuCisKK0hpc3RvcmljYWw6ICBSZWltZXIgQmVocmVuZHMgY29udHJpYnV0ZWQgdGhlIGlkZWEgb2YgdXNpbmcgYSBwb2x5bm9taWFsLWJhc2VkCithcHByb2FjaCwgdXNpbmcgcmVwZWF0ZWQgbXVsdGlwbGljYXRpb24gYnkgeCBpbiBHRigyKipuKSB3aGVyZSBhbiBpcnJlZHVjaWJsZQorcG9seW5vbWlhbCBmb3IgZWFjaCB0YWJsZSBzaXplIHdhcyBjaG9zZW4gc3VjaCB0aGF0IHggd2FzIGEgcHJpbWl0aXZlIHJvb3QuCitDaHJpc3RpYW4gVGlzbWVyIGxhdGVyIGV4dGVuZGVkIHRoYXQgdG8gdXNlIGRpdmlzaW9uIGJ5IHggaW5zdGVhZCwgYXMgYW4KK2VmZmljaWVudCB3YXkgdG8gZ2V0IHRoZSBoaWdoIGJpdHMgb2YgdGhlIGhhc2ggY29kZSBpbnRvIHBsYXkuICBUaGlzIHNjaGVtZQorYWxzbyBnYXZlIGV4Y2VsbGVudCBjb2xsaXNpb24gc3RhdGlzdGljcywgYnV0IHdhcyBtb3JlIGV4cGVuc2l2ZTogIHR3bworaWYtdGVzdHMgd2VyZSByZXF1aXJlZCBpbnNpZGUgdGhlIGxvb3A7IGNvbXB1dGluZyAidGhlIG5leHQiIGluZGV4IHRvb2sgYWJvdXQKK3RoZSBzYW1lIG51bWJlciBvZiBvcGVyYXRpb25zIGJ1dCB3aXRob3V0IGFzIG11Y2ggcG90ZW50aWFsIHBhcmFsbGVsaXNtCisoZS5nLiwgY29tcHV0aW5nIDUqaiBjYW4gZ28gb24gYXQgdGhlIHNhbWUgdGltZSBhcyBjb21wdXRpbmcgMStwZXJ0dXJiIGluIHRoZQorYWJvdmUsIGFuZCB0aGVuIHNoaWZ0aW5nIHBlcnR1cmIgY2FuIGJlIGRvbmUgd2hpbGUgdGhlIHRhYmxlIGluZGV4IGlzIGJlaW5nCittYXNrZWQpOyBhbmQgdGhlIFB5RGljdE9iamVjdCBzdHJ1Y3QgcmVxdWlyZWQgYSBtZW1iZXIgdG8gaG9sZCB0aGUgdGFibGUncworcG9seW5vbWlhbC4gIEluIFRpbSdzIGV4cGVyaW1lbnRzIHRoZSBjdXJyZW50IHNjaGVtZSByYW4gZmFzdGVyLCBwcm9kdWNlZAorZXF1YWxseSBnb29kIGNvbGxpc2lvbiBzdGF0aXN0aWNzLCBuZWVkZWQgbGVzcyBjb2RlICYgdXNlZCBsZXNzIG1lbW9yeS4KKworVGhlb3JldGljYWwgUHl0aG9uIDIuNSBoZWFkYWNoZTogIGhhc2ggY29kZXMgYXJlIG9ubHkgQyAibG9uZyIsIGJ1dAorc2l6ZW9mKFB5X3NzaXplX3QpID4gc2l6ZW9mKGxvbmcpIG1heSBiZSBwb3NzaWJsZS4gIEluIHRoYXQgY2FzZSwgYW5kIGlmIGEKK2RpY3QgaXMgZ2VudWluZWx5IGh1Z2UsIHRoZW4gb25seSB0aGUgc2xvdHMgZGlyZWN0bHkgcmVhY2hhYmxlIHZpYSBpbmRleGluZworYnkgYSBDIGxvbmcgY2FuIGJlIHRoZSBmaXJzdCBzbG90IGluIGEgcHJvYmUgc2VxdWVuY2UuICBUaGUgcHJvYmUgc2VxdWVuY2UKK3dpbGwgc3RpbGwgZXZlbnR1YWxseSByZWFjaCBldmVyeSBzbG90IGluIHRoZSB0YWJsZSwgYnV0IHRoZSBjb2xsaXNpb24gcmF0ZQorb24gaW5pdGlhbCBwcm9iZXMgbWF5IGJlIG11Y2ggaGlnaGVyIHRoYW4gdGhpcyBzY2hlbWUgd2FzIGRlc2lnbmVkIGZvci4KK0dldHRpbmcgYSBoYXNoIGNvZGUgYXMgZmF0IGFzIFB5X3NzaXplX3QgaXMgdGhlIG9ubHkgcmVhbCBjdXJlLiAgQnV0IGluCitwcmFjdGljZSwgdGhpcyBwcm9iYWJseSB3b24ndCBtYWtlIGEgbGljayBvZiBkaWZmZXJlbmNlIGZvciBtYW55IHllYXJzIChhdAord2hpY2ggcG9pbnQgZXZlcnlvbmUgd2lsbCBoYXZlIHRlcmFieXRlcyBvZiBSQU0gb24gNjQtYml0IGJveGVzKS4KKyovCisKKy8qIE9iamVjdCB1c2VkIGFzIGR1bW15IGtleSB0byBmaWxsIGRlbGV0ZWQgZW50cmllcyAqLworc3RhdGljIFB5T2JqZWN0ICpkdW1teSA9IE5VTEw7IC8qIEluaXRpYWxpemVkIGJ5IGZpcnN0IGNhbGwgdG8gbmV3UHlEaWN0T2JqZWN0KCkgKi8KKworI2lmZGVmIFB5X1JFRl9ERUJVRworUHlPYmplY3QgKgorX1B5RGljdF9EdW1teSh2b2lkKQoreworICAgIHJldHVybiBkdW1teTsKK30KKyNlbmRpZgorCisvKiBmb3J3YXJkIGRlY2xhcmF0aW9ucyAqLworc3RhdGljIFB5RGljdEVudHJ5ICoKK2xvb2tkaWN0X3N0cmluZyhQeURpY3RPYmplY3QgKm1wLCBQeU9iamVjdCAqa2V5LCBsb25nIGhhc2gpOworCisjaWZkZWYgU0hPV19DT05WRVJTSU9OX0NPVU5UUworc3RhdGljIGxvbmcgY3JlYXRlZCA9IDBMOworc3RhdGljIGxvbmcgY29udmVydGVkID0gMEw7CisKK3N0YXRpYyB2b2lkCitzaG93X2NvdW50cyh2b2lkKQoreworICAgIGZwcmludGYoc3RkZXJyLCAiY3JlYXRlZCAlbGQgc3RyaW5nIGRpY3RzXG4iLCBjcmVhdGVkKTsKKyAgICBmcHJpbnRmKHN0ZGVyciwgImNvbnZlcnRlZCAlbGQgdG8gbm9ybWFsIGRpY3RzXG4iLCBjb252ZXJ0ZWQpOworICAgIGZwcmludGYoc3RkZXJyLCAiJS4yZiUlIGNvbnZlcnNpb24gcmF0ZVxuIiwgKDEwMC4wKmNvbnZlcnRlZCkvY3JlYXRlZCk7Cit9CisjZW5kaWYKKworLyogRGVidWcgc3RhdGlzdGljIHRvIGNvbXBhcmUgYWxsb2NhdGlvbnMgd2l0aCByZXVzZSB0aHJvdWdoIHRoZSBmcmVlIGxpc3QgKi8KKyN1bmRlZiBTSE9XX0FMTE9DX0NPVU5UCisjaWZkZWYgU0hPV19BTExPQ19DT1VOVAorc3RhdGljIHNpemVfdCBjb3VudF9hbGxvYyA9IDA7CitzdGF0aWMgc2l6ZV90IGNvdW50X3JldXNlID0gMDsKKworc3RhdGljIHZvaWQKK3Nob3dfYWxsb2Modm9pZCkKK3sKKyAgICBmcHJpbnRmKHN0ZGVyciwgIkRpY3QgYWxsb2NhdGlvbnM6ICUiIFBZX0ZPUk1BVF9TSVpFX1QgImRcbiIsCisgICAgICAgIGNvdW50X2FsbG9jKTsKKyAgICBmcHJpbnRmKHN0ZGVyciwgIkRpY3QgcmV1c2UgdGhyb3VnaCBmcmVlbGlzdDogJSIgUFlfRk9STUFUX1NJWkVfVAorICAgICAgICAiZFxuIiwgY291bnRfcmV1c2UpOworICAgIGZwcmludGYoc3RkZXJyLCAiJS4yZiUlIHJldXNlIHJhdGVcblxuIiwKKyAgICAgICAgKDEwMC4wKmNvdW50X3JldXNlLyhjb3VudF9hbGxvYytjb3VudF9yZXVzZSkpKTsKK30KKyNlbmRpZgorCisvKiBEZWJ1ZyBzdGF0aXN0aWMgdG8gY291bnQgR0MgdHJhY2tpbmcgb2YgZGljdHMgKi8KKyNpZmRlZiBTSE9XX1RSQUNLX0NPVU5UCitzdGF0aWMgUHlfc3NpemVfdCBjb3VudF91bnRyYWNrZWQgPSAwOworc3RhdGljIFB5X3NzaXplX3QgY291bnRfdHJhY2tlZCA9IDA7CisKK3N0YXRpYyB2b2lkCitzaG93X3RyYWNrKHZvaWQpCit7CisgICAgZnByaW50ZihzdGRlcnIsICJEaWN0cyBjcmVhdGVkOiAlIiBQWV9GT1JNQVRfU0laRV9UICJkXG4iLAorICAgICAgICBjb3VudF90cmFja2VkICsgY291bnRfdW50cmFja2VkKTsKKyAgICBmcHJpbnRmKHN0ZGVyciwgIkRpY3RzIHRyYWNrZWQgYnkgdGhlIEdDOiAlIiBQWV9GT1JNQVRfU0laRV9UCisgICAgICAgICJkXG4iLCBjb3VudF90cmFja2VkKTsKKyAgICBmcHJpbnRmKHN0ZGVyciwgIiUuMmYlJSBkaWN0IHRyYWNraW5nIHJhdGVcblxuIiwKKyAgICAgICAgKDEwMC4wKmNvdW50X3RyYWNrZWQvKGNvdW50X3VudHJhY2tlZCtjb3VudF90cmFja2VkKSkpOworfQorI2VuZGlmCisKKworLyogSW5pdGlhbGl6YXRpb24gbWFjcm9zLgorICAgVGhlcmUgYXJlIHR3byB3YXlzIHRvIGNyZWF0ZSBhIGRpY3Q6ICBQeURpY3RfTmV3KCkgaXMgdGhlIG1haW4gQyBBUEkKKyAgIGZ1bmN0aW9uLCBhbmQgdGhlIHRwX25ldyBzbG90IG1hcHMgdG8gZGljdF9uZXcoKS4gIEluIHRoZSBsYXR0ZXIgY2FzZSB3ZQorICAgY2FuIHNhdmUgYSBsaXR0bGUgdGltZSBvdmVyIHdoYXQgUHlEaWN0X05ldyBkb2VzIGJlY2F1c2UgaXQncyBndWFyYW50ZWVkCisgICB0aGF0IHRoZSBQeURpY3RPYmplY3Qgc3RydWN0IGlzIGFscmVhZHkgemVyb2VkIG91dC4KKyAgIEV2ZXJ5b25lIGV4Y2VwdCBkaWN0X25ldygpIHNob3VsZCB1c2UgRU1QVFlfVE9fTUlOU0laRSAodW5sZXNzIHRoZXkgaGF2ZQorICAgYW4gZXhjZWxsZW50IHJlYXNvbiBub3QgdG8pLgorKi8KKworI2RlZmluZSBJTklUX05PTlpFUk9fRElDVF9TTE9UUyhtcCkgZG8geyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIChtcCktPm1hX3RhYmxlID0gKG1wKS0+bWFfc21hbGx0YWJsZTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIChtcCktPm1hX21hc2sgPSBQeURpY3RfTUlOU0laRSAtIDE7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIH0gd2hpbGUoMCkKKworI2RlZmluZSBFTVBUWV9UT19NSU5TSVpFKG1wKSBkbyB7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIG1lbXNldCgobXApLT5tYV9zbWFsbHRhYmxlLCAwLCBzaXplb2YoKG1wKS0+bWFfc21hbGx0YWJsZSkpOyAgICAgICAgXAorICAgIChtcCktPm1hX3VzZWQgPSAobXApLT5tYV9maWxsID0gMDsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIElOSVRfTk9OWkVST19ESUNUX1NMT1RTKG1wKTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIH0gd2hpbGUoMCkKKworLyogRGljdGlvbmFyeSByZXVzZSBzY2hlbWUgdG8gc2F2ZSBjYWxscyB0byBtYWxsb2MsIGZyZWUsIGFuZCBtZW1zZXQgKi8KKyNpZm5kZWYgUHlEaWN0X01BWEZSRUVMSVNUCisjZGVmaW5lIFB5RGljdF9NQVhGUkVFTElTVCA4MAorI2VuZGlmCitzdGF0aWMgUHlEaWN0T2JqZWN0ICpmcmVlX2xpc3RbUHlEaWN0X01BWEZSRUVMSVNUXTsKK3N0YXRpYyBpbnQgbnVtZnJlZSA9IDA7CisKK3ZvaWQKK1B5RGljdF9GaW5pKHZvaWQpCit7CisgICAgUHlEaWN0T2JqZWN0ICpvcDsKKworICAgIHdoaWxlIChudW1mcmVlKSB7CisgICAgICAgIG9wID0gZnJlZV9saXN0Wy0tbnVtZnJlZV07CisgICAgICAgIGFzc2VydChQeURpY3RfQ2hlY2tFeGFjdChvcCkpOworICAgICAgICBQeU9iamVjdF9HQ19EZWwob3ApOworICAgIH0KK30KKworUHlPYmplY3QgKgorUHlEaWN0X05ldyh2b2lkKQoreworICAgIHJlZ2lzdGVyIFB5RGljdE9iamVjdCAqbXA7CisgICAgaWYgKGR1bW15ID09IE5VTEwpIHsgLyogQXV0by1pbml0aWFsaXplIGR1bW15ICovCisgICAgICAgIGR1bW15ID0gUHlTdHJpbmdfRnJvbVN0cmluZygiPGR1bW15IGtleT4iKTsKKyAgICAgICAgaWYgKGR1bW15ID09IE5VTEwpCisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyNpZmRlZiBTSE9XX0NPTlZFUlNJT05fQ09VTlRTCisgICAgICAgIFB5X0F0RXhpdChzaG93X2NvdW50cyk7CisjZW5kaWYKKyNpZmRlZiBTSE9XX0FMTE9DX0NPVU5UCisgICAgICAgIFB5X0F0RXhpdChzaG93X2FsbG9jKTsKKyNlbmRpZgorI2lmZGVmIFNIT1dfVFJBQ0tfQ09VTlQKKyAgICAgICAgUHlfQXRFeGl0KHNob3dfdHJhY2spOworI2VuZGlmCisgICAgfQorICAgIGlmIChudW1mcmVlKSB7CisgICAgICAgIG1wID0gZnJlZV9saXN0Wy0tbnVtZnJlZV07CisgICAgICAgIGFzc2VydCAobXAgIT0gTlVMTCk7CisgICAgICAgIGFzc2VydCAoUHlfVFlQRShtcCkgPT0gJlB5RGljdF9UeXBlKTsKKyAgICAgICAgX1B5X05ld1JlZmVyZW5jZSgoUHlPYmplY3QgKiltcCk7CisgICAgICAgIGlmIChtcC0+bWFfZmlsbCkgeworICAgICAgICAgICAgRU1QVFlfVE9fTUlOU0laRShtcCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAvKiBBdCBsZWFzdCBzZXQgbWFfdGFibGUgYW5kIG1hX21hc2s7IHRoZXNlIGFyZSB3cm9uZworICAgICAgICAgICAgICAgaWYgYW4gZW1wdHkgYnV0IHByZXNpemVkIGRpY3QgaXMgYWRkZWQgdG8gZnJlZWxpc3QgKi8KKyAgICAgICAgICAgIElOSVRfTk9OWkVST19ESUNUX1NMT1RTKG1wKTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnQgKG1wLT5tYV91c2VkID09IDApOworICAgICAgICBhc3NlcnQgKG1wLT5tYV90YWJsZSA9PSBtcC0+bWFfc21hbGx0YWJsZSk7CisgICAgICAgIGFzc2VydCAobXAtPm1hX21hc2sgPT0gUHlEaWN0X01JTlNJWkUgLSAxKTsKKyNpZmRlZiBTSE9XX0FMTE9DX0NPVU5UCisgICAgICAgIGNvdW50X3JldXNlKys7CisjZW5kaWYKKyAgICB9IGVsc2UgeworICAgICAgICBtcCA9IFB5T2JqZWN0X0dDX05ldyhQeURpY3RPYmplY3QsICZQeURpY3RfVHlwZSk7CisgICAgICAgIGlmIChtcCA9PSBOVUxMKQorICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgICAgIEVNUFRZX1RPX01JTlNJWkUobXApOworI2lmZGVmIFNIT1dfQUxMT0NfQ09VTlQKKyAgICAgICAgY291bnRfYWxsb2MrKzsKKyNlbmRpZgorICAgIH0KKyAgICBtcC0+bWFfbG9va3VwID0gbG9va2RpY3Rfc3RyaW5nOworI2lmZGVmIFNIT1dfVFJBQ0tfQ09VTlQKKyAgICBjb3VudF91bnRyYWNrZWQrKzsKKyNlbmRpZgorI2lmZGVmIFNIT1dfQ09OVkVSU0lPTl9DT1VOVFMKKyAgICArK2NyZWF0ZWQ7CisjZW5kaWYKKyAgICByZXR1cm4gKFB5T2JqZWN0ICopbXA7Cit9CisKKy8qCitUaGUgYmFzaWMgbG9va3VwIGZ1bmN0aW9uIHVzZWQgYnkgYWxsIG9wZXJhdGlvbnMuCitUaGlzIGlzIGJhc2VkIG9uIEFsZ29yaXRobSBEIGZyb20gS251dGggVm9sLiAzLCBTZWMuIDYuNC4KK09wZW4gYWRkcmVzc2luZyBpcyBwcmVmZXJyZWQgb3ZlciBjaGFpbmluZyBzaW5jZSB0aGUgbGluayBvdmVyaGVhZCBmb3IKK2NoYWluaW5nIHdvdWxkIGJlIHN1YnN0YW50aWFsICgxMDAlIHdpdGggdHlwaWNhbCBtYWxsb2Mgb3ZlcmhlYWQpLgorCitUaGUgaW5pdGlhbCBwcm9iZSBpbmRleCBpcyBjb21wdXRlZCBhcyBoYXNoIG1vZCB0aGUgdGFibGUgc2l6ZS4gU3Vic2VxdWVudAorcHJvYmUgaW5kaWNlcyBhcmUgY29tcHV0ZWQgYXMgZXhwbGFpbmVkIGVhcmxpZXIuCisKK0FsbCBhcml0aG1ldGljIG9uIGhhc2ggc2hvdWxkIGlnbm9yZSBvdmVyZmxvdy4KKworKFRoZSBkZXRhaWxzIGluIHRoaXMgdmVyc2lvbiBhcmUgZHVlIHRvIFRpbSBQZXRlcnMsIGJ1aWxkaW5nIG9uIG1hbnkgcGFzdAorY29udHJpYnV0aW9ucyBieSBSZWltZXIgQmVocmVuZHMsIEp5cmtpIEFsYWt1aWphbGEsIFZsYWRpbWlyIE1hcmFuZ296b3YgYW5kCitDaHJpc3RpYW4gVGlzbWVyKS4KKworbG9va2RpY3QoKSBpcyBnZW5lcmFsLXB1cnBvc2UsIGFuZCBtYXkgcmV0dXJuIE5VTEwgaWYgKGFuZCBvbmx5IGlmKSBhCitjb21wYXJpc29uIHJhaXNlcyBhbiBleGNlcHRpb24gKHRoaXMgd2FzIG5ldyBpbiBQeXRob24gMi41KS4KK2xvb2tkaWN0X3N0cmluZygpIGJlbG93IGlzIHNwZWNpYWxpemVkIHRvIHN0cmluZyBrZXlzLCBjb21wYXJpc29uIG9mIHdoaWNoIGNhbgorbmV2ZXIgcmFpc2UgYW4gZXhjZXB0aW9uOyB0aGF0IGZ1bmN0aW9uIGNhbiBuZXZlciByZXR1cm4gTlVMTC4gIEZvciBib3RoLCB3aGVuCit0aGUga2V5IGlzbid0IGZvdW5kIGEgUHlEaWN0RW50cnkqIGlzIHJldHVybmVkIGZvciB3aGljaCB0aGUgbWVfdmFsdWUgZmllbGQgaXMKK05VTEw7IHRoaXMgaXMgdGhlIHNsb3QgaW4gdGhlIGRpY3QgYXQgd2hpY2ggdGhlIGtleSB3b3VsZCBoYXZlIGJlZW4gZm91bmQsIGFuZAordGhlIGNhbGxlciBjYW4gKGlmIGl0IHdpc2hlcykgYWRkIHRoZSA8a2V5LCB2YWx1ZT4gcGFpciB0byB0aGUgcmV0dXJuZWQKK1B5RGljdEVudHJ5Ki4KKyovCitzdGF0aWMgUHlEaWN0RW50cnkgKgorbG9va2RpY3QoUHlEaWN0T2JqZWN0ICptcCwgUHlPYmplY3QgKmtleSwgcmVnaXN0ZXIgbG9uZyBoYXNoKQoreworICAgIHJlZ2lzdGVyIHNpemVfdCBpOworICAgIHJlZ2lzdGVyIHNpemVfdCBwZXJ0dXJiOworICAgIHJlZ2lzdGVyIFB5RGljdEVudHJ5ICpmcmVlc2xvdDsKKyAgICByZWdpc3RlciBzaXplX3QgbWFzayA9IChzaXplX3QpbXAtPm1hX21hc2s7CisgICAgUHlEaWN0RW50cnkgKmVwMCA9IG1wLT5tYV90YWJsZTsKKyAgICByZWdpc3RlciBQeURpY3RFbnRyeSAqZXA7CisgICAgcmVnaXN0ZXIgaW50IGNtcDsKKyAgICBQeU9iamVjdCAqc3RhcnRrZXk7CisKKyAgICBpID0gKHNpemVfdCloYXNoICYgbWFzazsKKyAgICBlcCA9ICZlcDBbaV07CisgICAgaWYgKGVwLT5tZV9rZXkgPT0gTlVMTCB8fCBlcC0+bWVfa2V5ID09IGtleSkKKyAgICAgICAgcmV0dXJuIGVwOworCisgICAgaWYgKGVwLT5tZV9rZXkgPT0gZHVtbXkpCisgICAgICAgIGZyZWVzbG90ID0gZXA7CisgICAgZWxzZSB7CisgICAgICAgIGlmIChlcC0+bWVfaGFzaCA9PSBoYXNoKSB7CisgICAgICAgICAgICBzdGFydGtleSA9IGVwLT5tZV9rZXk7CisgICAgICAgICAgICBQeV9JTkNSRUYoc3RhcnRrZXkpOworICAgICAgICAgICAgY21wID0gUHlPYmplY3RfUmljaENvbXBhcmVCb29sKHN0YXJ0a2V5LCBrZXksIFB5X0VRKTsKKyAgICAgICAgICAgIFB5X0RFQ1JFRihzdGFydGtleSk7CisgICAgICAgICAgICBpZiAoY21wIDwgMCkKKyAgICAgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgICAgIGlmIChlcDAgPT0gbXAtPm1hX3RhYmxlICYmIGVwLT5tZV9rZXkgPT0gc3RhcnRrZXkpIHsKKyAgICAgICAgICAgICAgICBpZiAoY21wID4gMCkKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGVwOworICAgICAgICAgICAgfQorICAgICAgICAgICAgZWxzZSB7CisgICAgICAgICAgICAgICAgLyogVGhlIGNvbXBhcmUgZGlkIG1ham9yIG5hc3R5IHN0dWZmIHRvIHRoZQorICAgICAgICAgICAgICAgICAqIGRpY3Q6ICBzdGFydCBvdmVyLgorICAgICAgICAgICAgICAgICAqIFhYWCBBIGNsZXZlciBhZHZlcnNhcnkgY291bGQgcHJldmVudCB0aGlzCisgICAgICAgICAgICAgICAgICogWFhYIGZyb20gdGVybWluYXRpbmcuCisgICAgICAgICAgICAgICAgICovCisgICAgICAgICAgICAgICAgcmV0dXJuIGxvb2tkaWN0KG1wLCBrZXksIGhhc2gpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGZyZWVzbG90ID0gTlVMTDsKKyAgICB9CisKKyAgICAvKiBJbiB0aGUgbG9vcCwgbWVfa2V5ID09IGR1bW15IGlzIGJ5IGZhciAoZmFjdG9yIG9mIDEwMHMpIHRoZQorICAgICAgIGxlYXN0IGxpa2VseSBvdXRjb21lLCBzbyB0ZXN0IGZvciB0aGF0IGxhc3QuICovCisgICAgZm9yIChwZXJ0dXJiID0gaGFzaDsgOyBwZXJ0dXJiID4+PSBQRVJUVVJCX1NISUZUKSB7CisgICAgICAgIGkgPSAoaSA8PCAyKSArIGkgKyBwZXJ0dXJiICsgMTsKKyAgICAgICAgZXAgPSAmZXAwW2kgJiBtYXNrXTsKKyAgICAgICAgaWYgKGVwLT5tZV9rZXkgPT0gTlVMTCkKKyAgICAgICAgICAgIHJldHVybiBmcmVlc2xvdCA9PSBOVUxMID8gZXAgOiBmcmVlc2xvdDsKKyAgICAgICAgaWYgKGVwLT5tZV9rZXkgPT0ga2V5KQorICAgICAgICAgICAgcmV0dXJuIGVwOworICAgICAgICBpZiAoZXAtPm1lX2hhc2ggPT0gaGFzaCAmJiBlcC0+bWVfa2V5ICE9IGR1bW15KSB7CisgICAgICAgICAgICBzdGFydGtleSA9IGVwLT5tZV9rZXk7CisgICAgICAgICAgICBQeV9JTkNSRUYoc3RhcnRrZXkpOworICAgICAgICAgICAgY21wID0gUHlPYmplY3RfUmljaENvbXBhcmVCb29sKHN0YXJ0a2V5LCBrZXksIFB5X0VRKTsKKyAgICAgICAgICAgIFB5X0RFQ1JFRihzdGFydGtleSk7CisgICAgICAgICAgICBpZiAoY21wIDwgMCkKKyAgICAgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgICAgIGlmIChlcDAgPT0gbXAtPm1hX3RhYmxlICYmIGVwLT5tZV9rZXkgPT0gc3RhcnRrZXkpIHsKKyAgICAgICAgICAgICAgICBpZiAoY21wID4gMCkKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGVwOworICAgICAgICAgICAgfQorICAgICAgICAgICAgZWxzZSB7CisgICAgICAgICAgICAgICAgLyogVGhlIGNvbXBhcmUgZGlkIG1ham9yIG5hc3R5IHN0dWZmIHRvIHRoZQorICAgICAgICAgICAgICAgICAqIGRpY3Q6ICBzdGFydCBvdmVyLgorICAgICAgICAgICAgICAgICAqIFhYWCBBIGNsZXZlciBhZHZlcnNhcnkgY291bGQgcHJldmVudCB0aGlzCisgICAgICAgICAgICAgICAgICogWFhYIGZyb20gdGVybWluYXRpbmcuCisgICAgICAgICAgICAgICAgICovCisgICAgICAgICAgICAgICAgcmV0dXJuIGxvb2tkaWN0KG1wLCBrZXksIGhhc2gpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGVsc2UgaWYgKGVwLT5tZV9rZXkgPT0gZHVtbXkgJiYgZnJlZXNsb3QgPT0gTlVMTCkKKyAgICAgICAgICAgIGZyZWVzbG90ID0gZXA7CisgICAgfQorICAgIGFzc2VydCgwKTsgICAgICAgICAgLyogTk9UIFJFQUNIRUQgKi8KKyAgICByZXR1cm4gMDsKK30KKworLyoKKyAqIEhhY2tlZCB1cCB2ZXJzaW9uIG9mIGxvb2tkaWN0IHdoaWNoIGNhbiBhc3N1bWUga2V5cyBhcmUgYWx3YXlzIHN0cmluZ3M7CisgKiB0aGlzIGFzc3VtcHRpb24gYWxsb3dzIHRlc3RpbmcgZm9yIGVycm9ycyBkdXJpbmcgUHlPYmplY3RfUmljaENvbXBhcmVCb29sKCkKKyAqIHRvIGJlIGRyb3BwZWQ7IHN0cmluZy1zdHJpbmcgY29tcGFyaXNvbnMgbmV2ZXIgcmFpc2UgZXhjZXB0aW9ucy4gIFRoaXMgYWxzbworICogbWVhbnMgd2UgZG9uJ3QgbmVlZCB0byBnbyB0aHJvdWdoIFB5T2JqZWN0X1JpY2hDb21wYXJlQm9vbCgpOyB3ZSBjYW4gYWx3YXlzCisgKiB1c2UgX1B5U3RyaW5nX0VxKCkgZGlyZWN0bHkuCisgKgorICogVGhpcyBpcyB2YWx1YWJsZSBiZWNhdXNlIGRpY3RzIHdpdGggb25seSBzdHJpbmcga2V5cyBhcmUgdmVyeSBjb21tb24uCisgKi8KK3N0YXRpYyBQeURpY3RFbnRyeSAqCitsb29rZGljdF9zdHJpbmcoUHlEaWN0T2JqZWN0ICptcCwgUHlPYmplY3QgKmtleSwgcmVnaXN0ZXIgbG9uZyBoYXNoKQoreworICAgIHJlZ2lzdGVyIHNpemVfdCBpOworICAgIHJlZ2lzdGVyIHNpemVfdCBwZXJ0dXJiOworICAgIHJlZ2lzdGVyIFB5RGljdEVudHJ5ICpmcmVlc2xvdDsKKyAgICByZWdpc3RlciBzaXplX3QgbWFzayA9IChzaXplX3QpbXAtPm1hX21hc2s7CisgICAgUHlEaWN0RW50cnkgKmVwMCA9IG1wLT5tYV90YWJsZTsKKyAgICByZWdpc3RlciBQeURpY3RFbnRyeSAqZXA7CisKKyAgICAvKiBNYWtlIHN1cmUgdGhpcyBmdW5jdGlvbiBkb2Vzbid0IGhhdmUgdG8gaGFuZGxlIG5vbi1zdHJpbmcga2V5cywKKyAgICAgICBpbmNsdWRpbmcgc3ViY2xhc3NlcyBvZiBzdHI7IGUuZy4sIG9uZSByZWFzb24gdG8gc3ViY2xhc3MKKyAgICAgICBzdHJpbmdzIGlzIHRvIG92ZXJyaWRlIF9fZXFfXywgYW5kIGZvciBzcGVlZCB3ZSBkb24ndCBjYXRlciB0bworICAgICAgIHRoYXQgaGVyZS4gKi8KKyAgICBpZiAoIVB5U3RyaW5nX0NoZWNrRXhhY3Qoa2V5KSkgeworI2lmZGVmIFNIT1dfQ09OVkVSU0lPTl9DT1VOVFMKKyAgICAgICAgKytjb252ZXJ0ZWQ7CisjZW5kaWYKKyAgICAgICAgbXAtPm1hX2xvb2t1cCA9IGxvb2tkaWN0OworICAgICAgICByZXR1cm4gbG9va2RpY3QobXAsIGtleSwgaGFzaCk7CisgICAgfQorICAgIGkgPSBoYXNoICYgbWFzazsKKyAgICBlcCA9ICZlcDBbaV07CisgICAgaWYgKGVwLT5tZV9rZXkgPT0gTlVMTCB8fCBlcC0+bWVfa2V5ID09IGtleSkKKyAgICAgICAgcmV0dXJuIGVwOworICAgIGlmIChlcC0+bWVfa2V5ID09IGR1bW15KQorICAgICAgICBmcmVlc2xvdCA9IGVwOworICAgIGVsc2UgeworICAgICAgICBpZiAoZXAtPm1lX2hhc2ggPT0gaGFzaCAmJiBfUHlTdHJpbmdfRXEoZXAtPm1lX2tleSwga2V5KSkKKyAgICAgICAgICAgIHJldHVybiBlcDsKKyAgICAgICAgZnJlZXNsb3QgPSBOVUxMOworICAgIH0KKworICAgIC8qIEluIHRoZSBsb29wLCBtZV9rZXkgPT0gZHVtbXkgaXMgYnkgZmFyIChmYWN0b3Igb2YgMTAwcykgdGhlCisgICAgICAgbGVhc3QgbGlrZWx5IG91dGNvbWUsIHNvIHRlc3QgZm9yIHRoYXQgbGFzdC4gKi8KKyAgICBmb3IgKHBlcnR1cmIgPSBoYXNoOyA7IHBlcnR1cmIgPj49IFBFUlRVUkJfU0hJRlQpIHsKKyAgICAgICAgaSA9IChpIDw8IDIpICsgaSArIHBlcnR1cmIgKyAxOworICAgICAgICBlcCA9ICZlcDBbaSAmIG1hc2tdOworICAgICAgICBpZiAoZXAtPm1lX2tleSA9PSBOVUxMKQorICAgICAgICAgICAgcmV0dXJuIGZyZWVzbG90ID09IE5VTEwgPyBlcCA6IGZyZWVzbG90OworICAgICAgICBpZiAoZXAtPm1lX2tleSA9PSBrZXkKKyAgICAgICAgICAgIHx8IChlcC0+bWVfaGFzaCA9PSBoYXNoCisgICAgICAgICAgICAmJiBlcC0+bWVfa2V5ICE9IGR1bW15CisgICAgICAgICAgICAmJiBfUHlTdHJpbmdfRXEoZXAtPm1lX2tleSwga2V5KSkpCisgICAgICAgICAgICByZXR1cm4gZXA7CisgICAgICAgIGlmIChlcC0+bWVfa2V5ID09IGR1bW15ICYmIGZyZWVzbG90ID09IE5VTEwpCisgICAgICAgICAgICBmcmVlc2xvdCA9IGVwOworICAgIH0KKyAgICBhc3NlcnQoMCk7ICAgICAgICAgIC8qIE5PVCBSRUFDSEVEICovCisgICAgcmV0dXJuIDA7Cit9CisKKyNpZmRlZiBTSE9XX1RSQUNLX0NPVU5UCisjZGVmaW5lIElOQ1JFQVNFX1RSQUNLX0NPVU5UIFwKKyAgICAoY291bnRfdHJhY2tlZCsrLCBjb3VudF91bnRyYWNrZWQtLSk7CisjZGVmaW5lIERFQ1JFQVNFX1RSQUNLX0NPVU5UIFwKKyAgICAoY291bnRfdHJhY2tlZC0tLCBjb3VudF91bnRyYWNrZWQrKyk7CisjZWxzZQorI2RlZmluZSBJTkNSRUFTRV9UUkFDS19DT1VOVAorI2RlZmluZSBERUNSRUFTRV9UUkFDS19DT1VOVAorI2VuZGlmCisKKyNkZWZpbmUgTUFJTlRBSU5fVFJBQ0tJTkcobXAsIGtleSwgdmFsdWUpIFwKKyAgICBkbyB7IFwKKyAgICAgICAgaWYgKCFfUHlPYmplY3RfR0NfSVNfVFJBQ0tFRChtcCkpIHsgXAorICAgICAgICAgICAgaWYgKF9QeU9iamVjdF9HQ19NQVlfQkVfVFJBQ0tFRChrZXkpIHx8IFwKKyAgICAgICAgICAgICAgICBfUHlPYmplY3RfR0NfTUFZX0JFX1RSQUNLRUQodmFsdWUpKSB7IFwKKyAgICAgICAgICAgICAgICBfUHlPYmplY3RfR0NfVFJBQ0sobXApOyBcCisgICAgICAgICAgICAgICAgSU5DUkVBU0VfVFJBQ0tfQ09VTlQgXAorICAgICAgICAgICAgfSBcCisgICAgICAgIH0gXAorICAgIH0gd2hpbGUoMCkKKwordm9pZAorX1B5RGljdF9NYXliZVVudHJhY2soUHlPYmplY3QgKm9wKQoreworICAgIFB5RGljdE9iamVjdCAqbXA7CisgICAgUHlPYmplY3QgKnZhbHVlOworICAgIFB5X3NzaXplX3QgbWFzaywgaTsKKyAgICBQeURpY3RFbnRyeSAqZXA7CisKKyAgICBpZiAoIVB5RGljdF9DaGVja0V4YWN0KG9wKSB8fCAhX1B5T2JqZWN0X0dDX0lTX1RSQUNLRUQob3ApKQorICAgICAgICByZXR1cm47CisKKyAgICBtcCA9IChQeURpY3RPYmplY3QgKikgb3A7CisgICAgZXAgPSBtcC0+bWFfdGFibGU7CisgICAgbWFzayA9IG1wLT5tYV9tYXNrOworICAgIGZvciAoaSA9IDA7IGkgPD0gbWFzazsgaSsrKSB7CisgICAgICAgIGlmICgodmFsdWUgPSBlcFtpXS5tZV92YWx1ZSkgPT0gTlVMTCkKKyAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICBpZiAoX1B5T2JqZWN0X0dDX01BWV9CRV9UUkFDS0VEKHZhbHVlKSB8fAorICAgICAgICAgICAgX1B5T2JqZWN0X0dDX01BWV9CRV9UUkFDS0VEKGVwW2ldLm1lX2tleSkpCisgICAgICAgICAgICByZXR1cm47CisgICAgfQorICAgIERFQ1JFQVNFX1RSQUNLX0NPVU5UCisgICAgX1B5T2JqZWN0X0dDX1VOVFJBQ0sob3ApOworfQorCisvKgorSW50ZXJuYWwgcm91dGluZSB0byBpbnNlcnQgYSBuZXcgaXRlbSBpbnRvIHRoZSB0YWJsZSB3aGVuIHlvdSBoYXZlIGVudHJ5IG9iamVjdC4KK1VzZWQgYnkgaW5zZXJ0ZGljdC4KKyovCitzdGF0aWMgaW50CitpbnNlcnRkaWN0X2J5X2VudHJ5KHJlZ2lzdGVyIFB5RGljdE9iamVjdCAqbXAsIFB5T2JqZWN0ICprZXksIGxvbmcgaGFzaCwKKyAgICAgICAgICAgICAgICAgICAgUHlEaWN0RW50cnkgKmVwLCBQeU9iamVjdCAqdmFsdWUpCit7CisgICAgUHlPYmplY3QgKm9sZF92YWx1ZTsKKworICAgIE1BSU5UQUlOX1RSQUNLSU5HKG1wLCBrZXksIHZhbHVlKTsKKyAgICBpZiAoZXAtPm1lX3ZhbHVlICE9IE5VTEwpIHsKKyAgICAgICAgb2xkX3ZhbHVlID0gZXAtPm1lX3ZhbHVlOworICAgICAgICBlcC0+bWVfdmFsdWUgPSB2YWx1ZTsKKyAgICAgICAgUHlfREVDUkVGKG9sZF92YWx1ZSk7IC8qIHdoaWNoICoqQ0FOKiogcmUtZW50ZXIgKi8KKyAgICAgICAgUHlfREVDUkVGKGtleSk7CisgICAgfQorICAgIGVsc2UgeworICAgICAgICBpZiAoZXAtPm1lX2tleSA9PSBOVUxMKQorICAgICAgICAgICAgbXAtPm1hX2ZpbGwrKzsKKyAgICAgICAgZWxzZSB7CisgICAgICAgICAgICBhc3NlcnQoZXAtPm1lX2tleSA9PSBkdW1teSk7CisgICAgICAgICAgICBQeV9ERUNSRUYoZHVtbXkpOworICAgICAgICB9CisgICAgICAgIGVwLT5tZV9rZXkgPSBrZXk7CisgICAgICAgIGVwLT5tZV9oYXNoID0gKFB5X3NzaXplX3QpaGFzaDsKKyAgICAgICAgZXAtPm1lX3ZhbHVlID0gdmFsdWU7CisgICAgICAgIG1wLT5tYV91c2VkKys7CisgICAgfQorICAgIHJldHVybiAwOworfQorCisKKy8qCitJbnRlcm5hbCByb3V0aW5lIHRvIGluc2VydCBhIG5ldyBpdGVtIGludG8gdGhlIHRhYmxlLgorVXNlZCBib3RoIGJ5IHRoZSBpbnRlcm5hbCByZXNpemUgcm91dGluZSBhbmQgYnkgdGhlIHB1YmxpYyBpbnNlcnQgcm91dGluZS4KK0VhdHMgYSByZWZlcmVuY2UgdG8ga2V5IGFuZCBvbmUgdG8gdmFsdWUuCitSZXR1cm5zIC0xIGlmIGFuIGVycm9yIG9jY3VycmVkLCBvciAwIG9uIHN1Y2Nlc3MuCisqLworc3RhdGljIGludAoraW5zZXJ0ZGljdChyZWdpc3RlciBQeURpY3RPYmplY3QgKm1wLCBQeU9iamVjdCAqa2V5LCBsb25nIGhhc2gsIFB5T2JqZWN0ICp2YWx1ZSkKK3sKKyAgICByZWdpc3RlciBQeURpY3RFbnRyeSAqZXA7CisKKyAgICBhc3NlcnQobXAtPm1hX2xvb2t1cCAhPSBOVUxMKTsKKyAgICBlcCA9IG1wLT5tYV9sb29rdXAobXAsIGtleSwgaGFzaCk7CisgICAgaWYgKGVwID09IE5VTEwpIHsKKyAgICAgICAgUHlfREVDUkVGKGtleSk7CisgICAgICAgIFB5X0RFQ1JFRih2YWx1ZSk7CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisgICAgcmV0dXJuIGluc2VydGRpY3RfYnlfZW50cnkobXAsIGtleSwgaGFzaCwgZXAsIHZhbHVlKTsKK30KKworLyoKK0ludGVybmFsIHJvdXRpbmUgdXNlZCBieSBkaWN0cmVzaXplKCkgdG8gaW5zZXJ0IGFuIGl0ZW0gd2hpY2ggaXMKK2tub3duIHRvIGJlIGFic2VudCBmcm9tIHRoZSBkaWN0LiAgVGhpcyByb3V0aW5lIGFsc28gYXNzdW1lcyB0aGF0Cit0aGUgZGljdCBjb250YWlucyBubyBkZWxldGVkIGVudHJpZXMuICBCZXNpZGVzIHRoZSBwZXJmb3JtYW5jZSBiZW5lZml0LAordXNpbmcgaW5zZXJ0ZGljdCgpIGluIGRpY3RyZXNpemUoKSBpcyBkYW5nZXJvdXMgKFNGIGJ1ZyAjMTQ1NjIwOSkuCitOb3RlIHRoYXQgbm8gcmVmY291bnRzIGFyZSBjaGFuZ2VkIGJ5IHRoaXMgcm91dGluZTsgaWYgbmVlZGVkLCB0aGUgY2FsbGVyCitpcyByZXNwb25zaWJsZSBmb3IgaW5jcmVmJ2luZyBga2V5YCBhbmQgYHZhbHVlYC4KKyovCitzdGF0aWMgdm9pZAoraW5zZXJ0ZGljdF9jbGVhbihyZWdpc3RlciBQeURpY3RPYmplY3QgKm1wLCBQeU9iamVjdCAqa2V5LCBsb25nIGhhc2gsCisgICAgICAgICAgICAgICAgIFB5T2JqZWN0ICp2YWx1ZSkKK3sKKyAgICByZWdpc3RlciBzaXplX3QgaTsKKyAgICByZWdpc3RlciBzaXplX3QgcGVydHVyYjsKKyAgICByZWdpc3RlciBzaXplX3QgbWFzayA9IChzaXplX3QpbXAtPm1hX21hc2s7CisgICAgUHlEaWN0RW50cnkgKmVwMCA9IG1wLT5tYV90YWJsZTsKKyAgICByZWdpc3RlciBQeURpY3RFbnRyeSAqZXA7CisKKyAgICBNQUlOVEFJTl9UUkFDS0lORyhtcCwga2V5LCB2YWx1ZSk7CisgICAgaSA9IGhhc2ggJiBtYXNrOworICAgIGVwID0gJmVwMFtpXTsKKyAgICBmb3IgKHBlcnR1cmIgPSBoYXNoOyBlcC0+bWVfa2V5ICE9IE5VTEw7IHBlcnR1cmIgPj49IFBFUlRVUkJfU0hJRlQpIHsKKyAgICAgICAgaSA9IChpIDw8IDIpICsgaSArIHBlcnR1cmIgKyAxOworICAgICAgICBlcCA9ICZlcDBbaSAmIG1hc2tdOworICAgIH0KKyAgICBhc3NlcnQoZXAtPm1lX3ZhbHVlID09IE5VTEwpOworICAgIG1wLT5tYV9maWxsKys7CisgICAgZXAtPm1lX2tleSA9IGtleTsKKyAgICBlcC0+bWVfaGFzaCA9IChQeV9zc2l6ZV90KWhhc2g7CisgICAgZXAtPm1lX3ZhbHVlID0gdmFsdWU7CisgICAgbXAtPm1hX3VzZWQrKzsKK30KKworLyoKK1Jlc3RydWN0dXJlIHRoZSB0YWJsZSBieSBhbGxvY2F0aW5nIGEgbmV3IHRhYmxlIGFuZCByZWluc2VydGluZyBhbGwKK2l0ZW1zIGFnYWluLiAgV2hlbiBlbnRyaWVzIGhhdmUgYmVlbiBkZWxldGVkLCB0aGUgbmV3IHRhYmxlIG1heQorYWN0dWFsbHkgYmUgc21hbGxlciB0aGFuIHRoZSBvbGQgb25lLgorKi8KK3N0YXRpYyBpbnQKK2RpY3RyZXNpemUoUHlEaWN0T2JqZWN0ICptcCwgUHlfc3NpemVfdCBtaW51c2VkKQoreworICAgIFB5X3NzaXplX3QgbmV3c2l6ZTsKKyAgICBQeURpY3RFbnRyeSAqb2xkdGFibGUsICpuZXd0YWJsZSwgKmVwOworICAgIFB5X3NzaXplX3QgaTsKKyAgICBpbnQgaXNfb2xkdGFibGVfbWFsbG9jZWQ7CisgICAgUHlEaWN0RW50cnkgc21hbGxfY29weVtQeURpY3RfTUlOU0laRV07CisKKyAgICBhc3NlcnQobWludXNlZCA+PSAwKTsKKworICAgIC8qIEZpbmQgdGhlIHNtYWxsZXN0IHRhYmxlIHNpemUgPiBtaW51c2VkLiAqLworICAgIGZvciAobmV3c2l6ZSA9IFB5RGljdF9NSU5TSVpFOworICAgICAgICAgbmV3c2l6ZSA8PSBtaW51c2VkICYmIG5ld3NpemUgPiAwOworICAgICAgICAgbmV3c2l6ZSA8PD0gMSkKKyAgICAgICAgOworICAgIGlmIChuZXdzaXplIDw9IDApIHsKKyAgICAgICAgUHlFcnJfTm9NZW1vcnkoKTsKKyAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKworICAgIC8qIEdldCBzcGFjZSBmb3IgYSBuZXcgdGFibGUuICovCisgICAgb2xkdGFibGUgPSBtcC0+bWFfdGFibGU7CisgICAgYXNzZXJ0KG9sZHRhYmxlICE9IE5VTEwpOworICAgIGlzX29sZHRhYmxlX21hbGxvY2VkID0gb2xkdGFibGUgIT0gbXAtPm1hX3NtYWxsdGFibGU7CisKKyAgICBpZiAobmV3c2l6ZSA9PSBQeURpY3RfTUlOU0laRSkgeworICAgICAgICAvKiBBIGxhcmdlIHRhYmxlIGlzIHNocmlua2luZywgb3Igd2UgY2FuJ3QgZ2V0IGFueSBzbWFsbGVyLiAqLworICAgICAgICBuZXd0YWJsZSA9IG1wLT5tYV9zbWFsbHRhYmxlOworICAgICAgICBpZiAobmV3dGFibGUgPT0gb2xkdGFibGUpIHsKKyAgICAgICAgICAgIGlmIChtcC0+bWFfZmlsbCA9PSBtcC0+bWFfdXNlZCkgeworICAgICAgICAgICAgICAgIC8qIE5vIGR1bW1pZXMsIHNvIG5vIHBvaW50IGRvaW5nIGFueXRoaW5nLiAqLworICAgICAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICAgICAgfQorICAgICAgICAgICAgLyogV2UncmUgbm90IGdvaW5nIHRvIHJlc2l6ZSBpdCwgYnV0IHJlYnVpbGQgdGhlCisgICAgICAgICAgICAgICB0YWJsZSBhbnl3YXkgdG8gcHVyZ2Ugb2xkIGR1bW15IGVudHJpZXMuCisgICAgICAgICAgICAgICBTdWJ0bGU6ICBUaGlzIGlzICpuZWNlc3NhcnkqIGlmIGZpbGw9PXNpemUsCisgICAgICAgICAgICAgICBhcyBsb29rZGljdCBuZWVkcyBhdCBsZWFzdCBvbmUgdmlyZ2luIHNsb3QgdG8KKyAgICAgICAgICAgICAgIHRlcm1pbmF0ZSBmYWlsaW5nIHNlYXJjaGVzLiAgSWYgZmlsbCA8IHNpemUsIGl0J3MKKyAgICAgICAgICAgICAgIG1lcmVseSBkZXNpcmFibGUsIGFzIGR1bW1pZXMgc2xvdyBzZWFyY2hlcy4gKi8KKyAgICAgICAgICAgIGFzc2VydChtcC0+bWFfZmlsbCA+IG1wLT5tYV91c2VkKTsKKyAgICAgICAgICAgIG1lbWNweShzbWFsbF9jb3B5LCBvbGR0YWJsZSwgc2l6ZW9mKHNtYWxsX2NvcHkpKTsKKyAgICAgICAgICAgIG9sZHRhYmxlID0gc21hbGxfY29weTsKKyAgICAgICAgfQorICAgIH0KKyAgICBlbHNlIHsKKyAgICAgICAgbmV3dGFibGUgPSBQeU1lbV9ORVcoUHlEaWN0RW50cnksIG5ld3NpemUpOworICAgICAgICBpZiAobmV3dGFibGUgPT0gTlVMTCkgeworICAgICAgICAgICAgUHlFcnJfTm9NZW1vcnkoKTsKKyAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qIE1ha2UgdGhlIGRpY3QgZW1wdHksIHVzaW5nIHRoZSBuZXcgdGFibGUuICovCisgICAgYXNzZXJ0KG5ld3RhYmxlICE9IG9sZHRhYmxlKTsKKyAgICBtcC0+bWFfdGFibGUgPSBuZXd0YWJsZTsKKyAgICBtcC0+bWFfbWFzayA9IG5ld3NpemUgLSAxOworICAgIG1lbXNldChuZXd0YWJsZSwgMCwgc2l6ZW9mKFB5RGljdEVudHJ5KSAqIG5ld3NpemUpOworICAgIG1wLT5tYV91c2VkID0gMDsKKyAgICBpID0gbXAtPm1hX2ZpbGw7CisgICAgbXAtPm1hX2ZpbGwgPSAwOworCisgICAgLyogQ29weSB0aGUgZGF0YSBvdmVyOyB0aGlzIGlzIHJlZmNvdW50LW5ldXRyYWwgZm9yIGFjdGl2ZSBlbnRyaWVzOworICAgICAgIGR1bW15IGVudHJpZXMgYXJlbid0IGNvcGllZCBvdmVyLCBvZiBjb3Vyc2UgKi8KKyAgICBmb3IgKGVwID0gb2xkdGFibGU7IGkgPiAwOyBlcCsrKSB7CisgICAgICAgIGlmIChlcC0+bWVfdmFsdWUgIT0gTlVMTCkgeyAgICAgICAgICAgICAvKiBhY3RpdmUgZW50cnkgKi8KKyAgICAgICAgICAgIC0taTsKKyAgICAgICAgICAgIGluc2VydGRpY3RfY2xlYW4obXAsIGVwLT5tZV9rZXksIChsb25nKWVwLT5tZV9oYXNoLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlcC0+bWVfdmFsdWUpOworICAgICAgICB9CisgICAgICAgIGVsc2UgaWYgKGVwLT5tZV9rZXkgIT0gTlVMTCkgeyAgICAgICAgICAvKiBkdW1teSBlbnRyeSAqLworICAgICAgICAgICAgLS1pOworICAgICAgICAgICAgYXNzZXJ0KGVwLT5tZV9rZXkgPT0gZHVtbXkpOworICAgICAgICAgICAgUHlfREVDUkVGKGVwLT5tZV9rZXkpOworICAgICAgICB9CisgICAgICAgIC8qIGVsc2Uga2V5ID09IHZhbHVlID09IE5VTEw6ICBub3RoaW5nIHRvIGRvICovCisgICAgfQorCisgICAgaWYgKGlzX29sZHRhYmxlX21hbGxvY2VkKQorICAgICAgICBQeU1lbV9ERUwob2xkdGFibGUpOworICAgIHJldHVybiAwOworfQorCisvKiBDcmVhdGUgYSBuZXcgZGljdGlvbmFyeSBwcmUtc2l6ZWQgdG8gaG9sZCBhbiBlc3RpbWF0ZWQgbnVtYmVyIG9mIGVsZW1lbnRzLgorICAgVW5kZXJlc3RpbWF0ZXMgYXJlIG9rYXkgYmVjYXVzZSB0aGUgZGljdGlvbmFyeSB3aWxsIHJlc2l6ZSBhcyBuZWNlc3NhcnkuCisgICBPdmVyZXN0aW1hdGVzIGp1c3QgbWVhbiB0aGUgZGljdGlvbmFyeSB3aWxsIGJlIG1vcmUgc3BhcnNlIHRoYW4gdXN1YWwuCisqLworCitQeU9iamVjdCAqCitfUHlEaWN0X05ld1ByZXNpemVkKFB5X3NzaXplX3QgbWludXNlZCkKK3sKKyAgICBQeU9iamVjdCAqb3AgPSBQeURpY3RfTmV3KCk7CisKKyAgICBpZiAobWludXNlZD41ICYmIG9wICE9IE5VTEwgJiYgZGljdHJlc2l6ZSgoUHlEaWN0T2JqZWN0ICopb3AsIG1pbnVzZWQpID09IC0xKSB7CisgICAgICAgIFB5X0RFQ1JFRihvcCk7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICByZXR1cm4gb3A7Cit9CisKKy8qIE5vdGUgdGhhdCwgZm9yIGhpc3RvcmljYWwgcmVhc29ucywgUHlEaWN0X0dldEl0ZW0oKSBzdXBwcmVzc2VzIGFsbCBlcnJvcnMKKyAqIHRoYXQgbWF5IG9jY3VyIChvcmlnaW5hbGx5IGRpY3RzIHN1cHBvcnRlZCBvbmx5IHN0cmluZyBrZXlzLCBhbmQgZXhjZXB0aW9ucworICogd2VyZW4ndCBwb3NzaWJsZSkuICBTbywgd2hpbGUgdGhlIG9yaWdpbmFsIGludGVudCB3YXMgdGhhdCBhIE5VTEwgcmV0dXJuCisgKiBtZWFudCB0aGUga2V5IHdhc24ndCBwcmVzZW50LCBpbiByZWFsaXR5IGl0IGNhbiBtZWFuIHRoYXQsIG9yIHRoYXQgYW4gZXJyb3IKKyAqIChzdXBwcmVzc2VkKSBvY2N1cnJlZCB3aGlsZSBjb21wdXRpbmcgdGhlIGtleSdzIGhhc2gsIG9yIHRoYXQgc29tZSBlcnJvcgorICogKHN1cHByZXNzZWQpIG9jY3VycmVkIHdoZW4gY29tcGFyaW5nIGtleXMgaW4gdGhlIGRpY3QncyBpbnRlcm5hbCBwcm9iZQorICogc2VxdWVuY2UuICBBIG5hc3R5IGV4YW1wbGUgb2YgdGhlIGxhdHRlciBpcyB3aGVuIGEgUHl0aG9uLWNvZGVkIGNvbXBhcmlzb24KKyAqIGZ1bmN0aW9uIGhpdHMgYSBzdGFjay1kZXB0aCBlcnJvciwgd2hpY2ggY2FuIGNhdXNlIHRoaXMgdG8gcmV0dXJuIE5VTEwKKyAqIGV2ZW4gaWYgdGhlIGtleSBpcyBwcmVzZW50LgorICovCitQeU9iamVjdCAqCitQeURpY3RfR2V0SXRlbShQeU9iamVjdCAqb3AsIFB5T2JqZWN0ICprZXkpCit7CisgICAgbG9uZyBoYXNoOworICAgIFB5RGljdE9iamVjdCAqbXAgPSAoUHlEaWN0T2JqZWN0ICopb3A7CisgICAgUHlEaWN0RW50cnkgKmVwOworICAgIFB5VGhyZWFkU3RhdGUgKnRzdGF0ZTsKKyAgICBpZiAoIVB5RGljdF9DaGVjayhvcCkpCisgICAgICAgIHJldHVybiBOVUxMOworICAgIGlmICghUHlTdHJpbmdfQ2hlY2tFeGFjdChrZXkpIHx8CisgICAgICAgIChoYXNoID0gKChQeVN0cmluZ09iamVjdCAqKSBrZXkpLT5vYl9zaGFzaCkgPT0gLTEpCisgICAgeworICAgICAgICBoYXNoID0gUHlPYmplY3RfSGFzaChrZXkpOworICAgICAgICBpZiAoaGFzaCA9PSAtMSkgeworICAgICAgICAgICAgUHlFcnJfQ2xlYXIoKTsKKyAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgICAgICB9CisgICAgfQorCisgICAgLyogV2UgY2FuIGFycml2ZSBoZXJlIHdpdGggYSBOVUxMIHRzdGF0ZSBkdXJpbmcgaW5pdGlhbGl6YXRpb246IHRyeQorICAgICAgIHJ1bm5pbmcgInB5dGhvbiAtV2kiIGZvciBhbiBleGFtcGxlIHJlbGF0ZWQgdG8gc3RyaW5nIGludGVybmluZy4KKyAgICAgICBMZXQncyBqdXN0IGhvcGUgdGhhdCBubyBleGNlcHRpb24gb2NjdXJzIHRoZW4uLi4gIFRoaXMgbXVzdCBiZQorICAgICAgIF9QeVRocmVhZFN0YXRlX0N1cnJlbnQgYW5kIG5vdCBQeVRocmVhZFN0YXRlX0dFVCgpIGJlY2F1c2UgaW4gZGVidWcKKyAgICAgICBtb2RlLCB0aGUgbGF0dGVyIGNvbXBsYWlucyBpZiB0c3RhdGUgaXMgTlVMTC4gKi8KKyAgICB0c3RhdGUgPSBfUHlUaHJlYWRTdGF0ZV9DdXJyZW50OworICAgIGlmICh0c3RhdGUgIT0gTlVMTCAmJiB0c3RhdGUtPmN1cmV4Y190eXBlICE9IE5VTEwpIHsKKyAgICAgICAgLyogcHJlc2VydmUgdGhlIGV4aXN0aW5nIGV4Y2VwdGlvbiAqLworICAgICAgICBQeU9iamVjdCAqZXJyX3R5cGUsICplcnJfdmFsdWUsICplcnJfdGI7CisgICAgICAgIFB5RXJyX0ZldGNoKCZlcnJfdHlwZSwgJmVycl92YWx1ZSwgJmVycl90Yik7CisgICAgICAgIGVwID0gKG1wLT5tYV9sb29rdXApKG1wLCBrZXksIGhhc2gpOworICAgICAgICAvKiBpZ25vcmUgZXJyb3JzICovCisgICAgICAgIFB5RXJyX1Jlc3RvcmUoZXJyX3R5cGUsIGVycl92YWx1ZSwgZXJyX3RiKTsKKyAgICAgICAgaWYgKGVwID09IE5VTEwpCisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgZWxzZSB7CisgICAgICAgIGVwID0gKG1wLT5tYV9sb29rdXApKG1wLCBrZXksIGhhc2gpOworICAgICAgICBpZiAoZXAgPT0gTlVMTCkgeworICAgICAgICAgICAgUHlFcnJfQ2xlYXIoKTsKKyAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgICAgICB9CisgICAgfQorICAgIHJldHVybiBlcC0+bWVfdmFsdWU7Cit9CisKK3N0YXRpYyBpbnQKK2RpY3Rfc2V0X2l0ZW1fYnlfaGFzaF9vcl9lbnRyeShyZWdpc3RlciBQeU9iamVjdCAqb3AsIFB5T2JqZWN0ICprZXksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9uZyBoYXNoLCBQeURpY3RFbnRyeSAqZXAsIFB5T2JqZWN0ICp2YWx1ZSkKK3sKKyAgICByZWdpc3RlciBQeURpY3RPYmplY3QgKm1wOworICAgIHJlZ2lzdGVyIFB5X3NzaXplX3Qgbl91c2VkOworCisgICAgbXAgPSAoUHlEaWN0T2JqZWN0ICopb3A7CisgICAgYXNzZXJ0KG1wLT5tYV9maWxsIDw9IG1wLT5tYV9tYXNrKTsgIC8qIGF0IGxlYXN0IG9uZSBlbXB0eSBzbG90ICovCisgICAgbl91c2VkID0gbXAtPm1hX3VzZWQ7CisgICAgUHlfSU5DUkVGKHZhbHVlKTsKKyAgICBQeV9JTkNSRUYoa2V5KTsKKyAgICBpZiAoZXAgPT0gTlVMTCkgeworICAgICAgICBpZiAoaW5zZXJ0ZGljdChtcCwga2V5LCBoYXNoLCB2YWx1ZSkgIT0gMCkKKyAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisgICAgZWxzZSB7CisgICAgICAgIGlmIChpbnNlcnRkaWN0X2J5X2VudHJ5KG1wLCBrZXksIGhhc2gsIGVwLCB2YWx1ZSkgIT0gMCkKKyAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisgICAgLyogSWYgd2UgYWRkZWQgYSBrZXksIHdlIGNhbiBzYWZlbHkgcmVzaXplLiAgT3RoZXJ3aXNlIGp1c3QgcmV0dXJuIQorICAgICAqIElmIGZpbGwgPj0gMi8zIHNpemUsIGFkanVzdCBzaXplLiAgTm9ybWFsbHksIHRoaXMgZG91YmxlcyBvcgorICAgICAqIHF1YWR1cGxlcyB0aGUgc2l6ZSwgYnV0IGl0J3MgYWxzbyBwb3NzaWJsZSBmb3IgdGhlIGRpY3QgdG8gc2hyaW5rCisgICAgICogKGlmIG1hX2ZpbGwgaXMgbXVjaCBsYXJnZXIgdGhhbiBtYV91c2VkLCBtZWFuaW5nIGEgbG90IG9mIGRpY3QKKyAgICAgKiBrZXlzIGhhdmUgYmVlbiAqIGRlbGV0ZWQpLgorICAgICAqCisgICAgICogUXVhZHJ1cGxpbmcgdGhlIHNpemUgaW1wcm92ZXMgYXZlcmFnZSBkaWN0aW9uYXJ5IHNwYXJzZW5lc3MKKyAgICAgKiAocmVkdWNpbmcgY29sbGlzaW9ucykgYXQgdGhlIGNvc3Qgb2Ygc29tZSBtZW1vcnkgYW5kIGl0ZXJhdGlvbgorICAgICAqIHNwZWVkICh3aGljaCBsb29wcyBvdmVyIGV2ZXJ5IHBvc3NpYmxlIGVudHJ5KS4gIEl0IGFsc28gaGFsdmVzCisgICAgICogdGhlIG51bWJlciBvZiBleHBlbnNpdmUgcmVzaXplIG9wZXJhdGlvbnMgaW4gYSBncm93aW5nIGRpY3Rpb25hcnkuCisgICAgICoKKyAgICAgKiBWZXJ5IGxhcmdlIGRpY3Rpb25hcmllcyAob3ZlciA1MEsgaXRlbXMpIHVzZSBkb3VibGluZyBpbnN0ZWFkLgorICAgICAqIFRoaXMgbWF5IGhlbHAgYXBwbGljYXRpb25zIHdpdGggc2V2ZXJlIG1lbW9yeSBjb25zdHJhaW50cy4KKyAgICAgKi8KKyAgICBpZiAoIShtcC0+bWFfdXNlZCA+IG5fdXNlZCAmJiBtcC0+bWFfZmlsbCozID49IChtcC0+bWFfbWFzaysxKSoyKSkKKyAgICAgICAgcmV0dXJuIDA7CisgICAgcmV0dXJuIGRpY3RyZXNpemUobXAsIChtcC0+bWFfdXNlZCA+IDUwMDAwID8gMiA6IDQpICogbXAtPm1hX3VzZWQpOworfQorCisvKiBDQVVUSU9OOiBQeURpY3RfU2V0SXRlbSgpIG11c3QgZ3VhcmFudGVlIHRoYXQgaXQgd29uJ3QgcmVzaXplIHRoZQorICogZGljdGlvbmFyeSBpZiBpdCdzIG1lcmVseSByZXBsYWNpbmcgdGhlIHZhbHVlIGZvciBhbiBleGlzdGluZyBrZXkuCisgKiBUaGlzIG1lYW5zIHRoYXQgaXQncyBzYWZlIHRvIGxvb3Agb3ZlciBhIGRpY3Rpb25hcnkgd2l0aCBQeURpY3RfTmV4dCgpCisgKiBhbmQgb2NjYXNpb25hbGx5IHJlcGxhY2UgYSB2YWx1ZSAtLSBidXQgeW91IGNhbid0IGluc2VydCBuZXcga2V5cyBvcgorICogcmVtb3ZlIHRoZW0uCisgKi8KK2ludAorUHlEaWN0X1NldEl0ZW0ocmVnaXN0ZXIgUHlPYmplY3QgKm9wLCBQeU9iamVjdCAqa2V5LCBQeU9iamVjdCAqdmFsdWUpCit7CisgICAgcmVnaXN0ZXIgbG9uZyBoYXNoOworCisgICAgaWYgKCFQeURpY3RfQ2hlY2sob3ApKSB7CisgICAgICAgIFB5RXJyX0JhZEludGVybmFsQ2FsbCgpOworICAgICAgICByZXR1cm4gLTE7CisgICAgfQorICAgIGFzc2VydChrZXkpOworICAgIGFzc2VydCh2YWx1ZSk7CisgICAgaWYgKFB5U3RyaW5nX0NoZWNrRXhhY3Qoa2V5KSkgeworICAgICAgICBoYXNoID0gKChQeVN0cmluZ09iamVjdCAqKWtleSktPm9iX3NoYXNoOworICAgICAgICBpZiAoaGFzaCA9PSAtMSkKKyAgICAgICAgICAgIGhhc2ggPSBQeU9iamVjdF9IYXNoKGtleSk7CisgICAgfQorICAgIGVsc2UgeworICAgICAgICBoYXNoID0gUHlPYmplY3RfSGFzaChrZXkpOworICAgICAgICBpZiAoaGFzaCA9PSAtMSkKKyAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisgICAgcmV0dXJuIGRpY3Rfc2V0X2l0ZW1fYnlfaGFzaF9vcl9lbnRyeShvcCwga2V5LCBoYXNoLCBOVUxMLCB2YWx1ZSk7Cit9CisKK2ludAorUHlEaWN0X0RlbEl0ZW0oUHlPYmplY3QgKm9wLCBQeU9iamVjdCAqa2V5KQoreworICAgIHJlZ2lzdGVyIFB5RGljdE9iamVjdCAqbXA7CisgICAgcmVnaXN0ZXIgbG9uZyBoYXNoOworICAgIHJlZ2lzdGVyIFB5RGljdEVudHJ5ICplcDsKKyAgICBQeU9iamVjdCAqb2xkX3ZhbHVlLCAqb2xkX2tleTsKKworICAgIGlmICghUHlEaWN0X0NoZWNrKG9wKSkgeworICAgICAgICBQeUVycl9CYWRJbnRlcm5hbENhbGwoKTsKKyAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKyAgICBhc3NlcnQoa2V5KTsKKyAgICBpZiAoIVB5U3RyaW5nX0NoZWNrRXhhY3Qoa2V5KSB8fAorICAgICAgICAoaGFzaCA9ICgoUHlTdHJpbmdPYmplY3QgKikga2V5KS0+b2Jfc2hhc2gpID09IC0xKSB7CisgICAgICAgIGhhc2ggPSBQeU9iamVjdF9IYXNoKGtleSk7CisgICAgICAgIGlmIChoYXNoID09IC0xKQorICAgICAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKyAgICBtcCA9IChQeURpY3RPYmplY3QgKilvcDsKKyAgICBlcCA9IChtcC0+bWFfbG9va3VwKShtcCwga2V5LCBoYXNoKTsKKyAgICBpZiAoZXAgPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIC0xOworICAgIGlmIChlcC0+bWVfdmFsdWUgPT0gTlVMTCkgeworICAgICAgICBzZXRfa2V5X2Vycm9yKGtleSk7CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisgICAgb2xkX2tleSA9IGVwLT5tZV9rZXk7CisgICAgUHlfSU5DUkVGKGR1bW15KTsKKyAgICBlcC0+bWVfa2V5ID0gZHVtbXk7CisgICAgb2xkX3ZhbHVlID0gZXAtPm1lX3ZhbHVlOworICAgIGVwLT5tZV92YWx1ZSA9IE5VTEw7CisgICAgbXAtPm1hX3VzZWQtLTsKKyAgICBQeV9ERUNSRUYob2xkX3ZhbHVlKTsKKyAgICBQeV9ERUNSRUYob2xkX2tleSk7CisgICAgcmV0dXJuIDA7Cit9CisKK3ZvaWQKK1B5RGljdF9DbGVhcihQeU9iamVjdCAqb3ApCit7CisgICAgUHlEaWN0T2JqZWN0ICptcDsKKyAgICBQeURpY3RFbnRyeSAqZXAsICp0YWJsZTsKKyAgICBpbnQgdGFibGVfaXNfbWFsbG9jZWQ7CisgICAgUHlfc3NpemVfdCBmaWxsOworICAgIFB5RGljdEVudHJ5IHNtYWxsX2NvcHlbUHlEaWN0X01JTlNJWkVdOworI2lmZGVmIFB5X0RFQlVHCisgICAgUHlfc3NpemVfdCBpLCBuOworI2VuZGlmCisKKyAgICBpZiAoIVB5RGljdF9DaGVjayhvcCkpCisgICAgICAgIHJldHVybjsKKyAgICBtcCA9IChQeURpY3RPYmplY3QgKilvcDsKKyNpZmRlZiBQeV9ERUJVRworICAgIG4gPSBtcC0+bWFfbWFzayArIDE7CisgICAgaSA9IDA7CisjZW5kaWYKKworICAgIHRhYmxlID0gbXAtPm1hX3RhYmxlOworICAgIGFzc2VydCh0YWJsZSAhPSBOVUxMKTsKKyAgICB0YWJsZV9pc19tYWxsb2NlZCA9IHRhYmxlICE9IG1wLT5tYV9zbWFsbHRhYmxlOworCisgICAgLyogVGhpcyBpcyBkZWxpY2F0ZS4gIER1cmluZyB0aGUgcHJvY2VzcyBvZiBjbGVhcmluZyB0aGUgZGljdCwKKyAgICAgKiBkZWNyZWZzIGNhbiBjYXVzZSB0aGUgZGljdCB0byBtdXRhdGUuICBUbyBhdm9pZCBmYXRhbCBjb25mdXNpb24KKyAgICAgKiAodm9pY2Ugb2YgZXhwZXJpZW5jZSksIHdlIGhhdmUgdG8gbWFrZSB0aGUgZGljdCBlbXB0eSBiZWZvcmUKKyAgICAgKiBjbGVhcmluZyB0aGUgc2xvdHMsIGFuZCBuZXZlciByZWZlciB0byBhbnl0aGluZyB2aWEgbXAtPnh4eCB3aGlsZQorICAgICAqIGNsZWFyaW5nLgorICAgICAqLworICAgIGZpbGwgPSBtcC0+bWFfZmlsbDsKKyAgICBpZiAodGFibGVfaXNfbWFsbG9jZWQpCisgICAgICAgIEVNUFRZX1RPX01JTlNJWkUobXApOworCisgICAgZWxzZSBpZiAoZmlsbCA+IDApIHsKKyAgICAgICAgLyogSXQncyBhIHNtYWxsIHRhYmxlIHdpdGggc29tZXRoaW5nIHRoYXQgbmVlZHMgdG8gYmUgY2xlYXJlZC4KKyAgICAgICAgICogQWZyYWlkIHRoZSBvbmx5IHNhZmUgd2F5IGlzIHRvIGNvcHkgdGhlIGRpY3QgZW50cmllcyBpbnRvCisgICAgICAgICAqIGFub3RoZXIgc21hbGwgdGFibGUgZmlyc3QuCisgICAgICAgICAqLworICAgICAgICBtZW1jcHkoc21hbGxfY29weSwgdGFibGUsIHNpemVvZihzbWFsbF9jb3B5KSk7CisgICAgICAgIHRhYmxlID0gc21hbGxfY29weTsKKyAgICAgICAgRU1QVFlfVE9fTUlOU0laRShtcCk7CisgICAgfQorICAgIC8qIGVsc2UgaXQncyBhIHNtYWxsIHRhYmxlIHRoYXQncyBhbHJlYWR5IGVtcHR5ICovCisKKyAgICAvKiBOb3cgd2UgY2FuIGZpbmFsbHkgY2xlYXIgdGhpbmdzLiAgSWYgQyBoYWQgcmVmY291bnRzLCB3ZSBjb3VsZAorICAgICAqIGFzc2VydCB0aGF0IHRoZSByZWZjb3VudCBvbiB0YWJsZSBpcyAxIG5vdywgaS5lLiB0aGF0IHRoaXMgZnVuY3Rpb24KKyAgICAgKiBoYXMgdW5pcXVlIGFjY2VzcyB0byBpdCwgc28gZGVjcmVmIHNpZGUtZWZmZWN0cyBjYW4ndCBhbHRlciBpdC4KKyAgICAgKi8KKyAgICBmb3IgKGVwID0gdGFibGU7IGZpbGwgPiAwOyArK2VwKSB7CisjaWZkZWYgUHlfREVCVUcKKyAgICAgICAgYXNzZXJ0KGkgPCBuKTsKKyAgICAgICAgKytpOworI2VuZGlmCisgICAgICAgIGlmIChlcC0+bWVfa2V5KSB7CisgICAgICAgICAgICAtLWZpbGw7CisgICAgICAgICAgICBQeV9ERUNSRUYoZXAtPm1lX2tleSk7CisgICAgICAgICAgICBQeV9YREVDUkVGKGVwLT5tZV92YWx1ZSk7CisgICAgICAgIH0KKyNpZmRlZiBQeV9ERUJVRworICAgICAgICBlbHNlCisgICAgICAgICAgICBhc3NlcnQoZXAtPm1lX3ZhbHVlID09IE5VTEwpOworI2VuZGlmCisgICAgfQorCisgICAgaWYgKHRhYmxlX2lzX21hbGxvY2VkKQorICAgICAgICBQeU1lbV9ERUwodGFibGUpOworfQorCisvKgorICogSXRlcmF0ZSBvdmVyIGEgZGljdC4gIFVzZSBsaWtlIHNvOgorICoKKyAqICAgICBQeV9zc2l6ZV90IGk7CisgKiAgICAgUHlPYmplY3QgKmtleSwgKnZhbHVlOworICogICAgIGkgPSAwOyAgICMgaW1wb3J0YW50ISAgaSBzaG91bGQgbm90IG90aGVyd2lzZSBiZSBjaGFuZ2VkIGJ5IHlvdQorICogICAgIHdoaWxlIChQeURpY3RfTmV4dCh5b3VyZGljdCwgJmksICZrZXksICZ2YWx1ZSkpIHsKKyAqICAgICAgICAgICAgICBSZWZlciB0byBib3Jyb3dlZCByZWZlcmVuY2VzIGluIGtleSBhbmQgdmFsdWUuCisgKiAgICAgfQorICoKKyAqIENBVVRJT046ICBJbiBnZW5lcmFsLCBpdCBpc24ndCBzYWZlIHRvIHVzZSBQeURpY3RfTmV4dCBpbiBhIGxvb3AgdGhhdAorICogbXV0YXRlcyB0aGUgZGljdC4gIE9uZSBleGNlcHRpb246ICBpdCBpcyBzYWZlIGlmIHRoZSBsb29wIG1lcmVseSBjaGFuZ2VzCisgKiB0aGUgdmFsdWVzIGFzc29jaWF0ZWQgd2l0aCB0aGUga2V5cyAoYnV0IGRvZXNuJ3QgaW5zZXJ0IG5ldyBrZXlzIG9yCisgKiBkZWxldGUga2V5cyksIHZpYSBQeURpY3RfU2V0SXRlbSgpLgorICovCitpbnQKK1B5RGljdF9OZXh0KFB5T2JqZWN0ICpvcCwgUHlfc3NpemVfdCAqcHBvcywgUHlPYmplY3QgKipwa2V5LCBQeU9iamVjdCAqKnB2YWx1ZSkKK3sKKyAgICByZWdpc3RlciBQeV9zc2l6ZV90IGk7CisgICAgcmVnaXN0ZXIgUHlfc3NpemVfdCBtYXNrOworICAgIHJlZ2lzdGVyIFB5RGljdEVudHJ5ICplcDsKKworICAgIGlmICghUHlEaWN0X0NoZWNrKG9wKSkKKyAgICAgICAgcmV0dXJuIDA7CisgICAgaSA9ICpwcG9zOworICAgIGlmIChpIDwgMCkKKyAgICAgICAgcmV0dXJuIDA7CisgICAgZXAgPSAoKFB5RGljdE9iamVjdCAqKW9wKS0+bWFfdGFibGU7CisgICAgbWFzayA9ICgoUHlEaWN0T2JqZWN0ICopb3ApLT5tYV9tYXNrOworICAgIHdoaWxlIChpIDw9IG1hc2sgJiYgZXBbaV0ubWVfdmFsdWUgPT0gTlVMTCkKKyAgICAgICAgaSsrOworICAgICpwcG9zID0gaSsxOworICAgIGlmIChpID4gbWFzaykKKyAgICAgICAgcmV0dXJuIDA7CisgICAgaWYgKHBrZXkpCisgICAgICAgICpwa2V5ID0gZXBbaV0ubWVfa2V5OworICAgIGlmIChwdmFsdWUpCisgICAgICAgICpwdmFsdWUgPSBlcFtpXS5tZV92YWx1ZTsKKyAgICByZXR1cm4gMTsKK30KKworLyogSW50ZXJuYWwgdmVyc2lvbiBvZiBQeURpY3RfTmV4dCB0aGF0IHJldHVybnMgYSBoYXNoIHZhbHVlIGluIGFkZGl0aW9uIHRvIHRoZSBrZXkgYW5kIHZhbHVlLiovCitpbnQKK19QeURpY3RfTmV4dChQeU9iamVjdCAqb3AsIFB5X3NzaXplX3QgKnBwb3MsIFB5T2JqZWN0ICoqcGtleSwgUHlPYmplY3QgKipwdmFsdWUsIGxvbmcgKnBoYXNoKQoreworICAgIHJlZ2lzdGVyIFB5X3NzaXplX3QgaTsKKyAgICByZWdpc3RlciBQeV9zc2l6ZV90IG1hc2s7CisgICAgcmVnaXN0ZXIgUHlEaWN0RW50cnkgKmVwOworCisgICAgaWYgKCFQeURpY3RfQ2hlY2sob3ApKQorICAgICAgICByZXR1cm4gMDsKKyAgICBpID0gKnBwb3M7CisgICAgaWYgKGkgPCAwKQorICAgICAgICByZXR1cm4gMDsKKyAgICBlcCA9ICgoUHlEaWN0T2JqZWN0ICopb3ApLT5tYV90YWJsZTsKKyAgICBtYXNrID0gKChQeURpY3RPYmplY3QgKilvcCktPm1hX21hc2s7CisgICAgd2hpbGUgKGkgPD0gbWFzayAmJiBlcFtpXS5tZV92YWx1ZSA9PSBOVUxMKQorICAgICAgICBpKys7CisgICAgKnBwb3MgPSBpKzE7CisgICAgaWYgKGkgPiBtYXNrKQorICAgICAgICByZXR1cm4gMDsKKyAgICAqcGhhc2ggPSAobG9uZykoZXBbaV0ubWVfaGFzaCk7CisgICAgaWYgKHBrZXkpCisgICAgICAgICpwa2V5ID0gZXBbaV0ubWVfa2V5OworICAgIGlmIChwdmFsdWUpCisgICAgICAgICpwdmFsdWUgPSBlcFtpXS5tZV92YWx1ZTsKKyAgICByZXR1cm4gMTsKK30KKworLyogTWV0aG9kcyAqLworCitzdGF0aWMgdm9pZAorZGljdF9kZWFsbG9jKHJlZ2lzdGVyIFB5RGljdE9iamVjdCAqbXApCit7CisgICAgcmVnaXN0ZXIgUHlEaWN0RW50cnkgKmVwOworICAgIFB5X3NzaXplX3QgZmlsbCA9IG1wLT5tYV9maWxsOworICAgIFB5T2JqZWN0X0dDX1VuVHJhY2sobXApOworICAgIFB5X1RSQVNIQ0FOX1NBRkVfQkVHSU4obXApCisgICAgZm9yIChlcCA9IG1wLT5tYV90YWJsZTsgZmlsbCA+IDA7IGVwKyspIHsKKyAgICAgICAgaWYgKGVwLT5tZV9rZXkpIHsKKyAgICAgICAgICAgIC0tZmlsbDsKKyAgICAgICAgICAgIFB5X0RFQ1JFRihlcC0+bWVfa2V5KTsKKyAgICAgICAgICAgIFB5X1hERUNSRUYoZXAtPm1lX3ZhbHVlKTsKKyAgICAgICAgfQorICAgIH0KKyAgICBpZiAobXAtPm1hX3RhYmxlICE9IG1wLT5tYV9zbWFsbHRhYmxlKQorICAgICAgICBQeU1lbV9ERUwobXAtPm1hX3RhYmxlKTsKKyAgICBpZiAobnVtZnJlZSA8IFB5RGljdF9NQVhGUkVFTElTVCAmJiBQeV9UWVBFKG1wKSA9PSAmUHlEaWN0X1R5cGUpCisgICAgICAgIGZyZWVfbGlzdFtudW1mcmVlKytdID0gbXA7CisgICAgZWxzZQorICAgICAgICBQeV9UWVBFKG1wKS0+dHBfZnJlZSgoUHlPYmplY3QgKiltcCk7CisgICAgUHlfVFJBU0hDQU5fU0FGRV9FTkQobXApCit9CisKK3N0YXRpYyBpbnQKK2RpY3RfcHJpbnQocmVnaXN0ZXIgUHlEaWN0T2JqZWN0ICptcCwgcmVnaXN0ZXIgRklMRSAqZnAsIHJlZ2lzdGVyIGludCBmbGFncykKK3sKKyAgICByZWdpc3RlciBQeV9zc2l6ZV90IGk7CisgICAgcmVnaXN0ZXIgUHlfc3NpemVfdCBhbnk7CisgICAgaW50IHN0YXR1czsKKworICAgIHN0YXR1cyA9IFB5X1JlcHJFbnRlcigoUHlPYmplY3QqKW1wKTsKKyAgICBpZiAoc3RhdHVzICE9IDApIHsKKyAgICAgICAgaWYgKHN0YXR1cyA8IDApCisgICAgICAgICAgICByZXR1cm4gc3RhdHVzOworICAgICAgICBQeV9CRUdJTl9BTExPV19USFJFQURTCisgICAgICAgIGZwcmludGYoZnAsICJ7Li4ufSIpOworICAgICAgICBQeV9FTkRfQUxMT1dfVEhSRUFEUworICAgICAgICByZXR1cm4gMDsKKyAgICB9CisKKyAgICBQeV9CRUdJTl9BTExPV19USFJFQURTCisgICAgZnByaW50ZihmcCwgInsiKTsKKyAgICBQeV9FTkRfQUxMT1dfVEhSRUFEUworICAgIGFueSA9IDA7CisgICAgZm9yIChpID0gMDsgaSA8PSBtcC0+bWFfbWFzazsgaSsrKSB7CisgICAgICAgIFB5RGljdEVudHJ5ICplcCA9IG1wLT5tYV90YWJsZSArIGk7CisgICAgICAgIFB5T2JqZWN0ICpwdmFsdWUgPSBlcC0+bWVfdmFsdWU7CisgICAgICAgIGlmIChwdmFsdWUgIT0gTlVMTCkgeworICAgICAgICAgICAgLyogUHJldmVudCBQeU9iamVjdF9SZXByIGZyb20gZGVsZXRpbmcgdmFsdWUgZHVyaW5nCisgICAgICAgICAgICAgICBrZXkgZm9ybWF0ICovCisgICAgICAgICAgICBQeV9JTkNSRUYocHZhbHVlKTsKKyAgICAgICAgICAgIGlmIChhbnkrKyA+IDApIHsKKyAgICAgICAgICAgICAgICBQeV9CRUdJTl9BTExPV19USFJFQURTCisgICAgICAgICAgICAgICAgZnByaW50ZihmcCwgIiwgIik7CisgICAgICAgICAgICAgICAgUHlfRU5EX0FMTE9XX1RIUkVBRFMKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChQeU9iamVjdF9QcmludCgoUHlPYmplY3QgKillcC0+bWVfa2V5LCBmcCwgMCkhPTApIHsKKyAgICAgICAgICAgICAgICBQeV9ERUNSRUYocHZhbHVlKTsKKyAgICAgICAgICAgICAgICBQeV9SZXByTGVhdmUoKFB5T2JqZWN0KiltcCk7CisgICAgICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICAgICAgfQorICAgICAgICAgICAgUHlfQkVHSU5fQUxMT1dfVEhSRUFEUworICAgICAgICAgICAgZnByaW50ZihmcCwgIjogIik7CisgICAgICAgICAgICBQeV9FTkRfQUxMT1dfVEhSRUFEUworICAgICAgICAgICAgaWYgKFB5T2JqZWN0X1ByaW50KHB2YWx1ZSwgZnAsIDApICE9IDApIHsKKyAgICAgICAgICAgICAgICBQeV9ERUNSRUYocHZhbHVlKTsKKyAgICAgICAgICAgICAgICBQeV9SZXByTGVhdmUoKFB5T2JqZWN0KiltcCk7CisgICAgICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICAgICAgfQorICAgICAgICAgICAgUHlfREVDUkVGKHB2YWx1ZSk7CisgICAgICAgIH0KKyAgICB9CisgICAgUHlfQkVHSU5fQUxMT1dfVEhSRUFEUworICAgIGZwcmludGYoZnAsICJ9Iik7CisgICAgUHlfRU5EX0FMTE9XX1RIUkVBRFMKKyAgICBQeV9SZXByTGVhdmUoKFB5T2JqZWN0KiltcCk7CisgICAgcmV0dXJuIDA7Cit9CisKK3N0YXRpYyBQeU9iamVjdCAqCitkaWN0X3JlcHIoUHlEaWN0T2JqZWN0ICptcCkKK3sKKyAgICBQeV9zc2l6ZV90IGk7CisgICAgUHlPYmplY3QgKnMsICp0ZW1wLCAqY29sb24gPSBOVUxMOworICAgIFB5T2JqZWN0ICpwaWVjZXMgPSBOVUxMLCAqcmVzdWx0ID0gTlVMTDsKKyAgICBQeU9iamVjdCAqa2V5LCAqdmFsdWU7CisKKyAgICBpID0gUHlfUmVwckVudGVyKChQeU9iamVjdCAqKW1wKTsKKyAgICBpZiAoaSAhPSAwKSB7CisgICAgICAgIHJldHVybiBpID4gMCA/IFB5U3RyaW5nX0Zyb21TdHJpbmcoInsuLi59IikgOiBOVUxMOworICAgIH0KKworICAgIGlmIChtcC0+bWFfdXNlZCA9PSAwKSB7CisgICAgICAgIHJlc3VsdCA9IFB5U3RyaW5nX0Zyb21TdHJpbmcoInt9Iik7CisgICAgICAgIGdvdG8gRG9uZTsKKyAgICB9CisKKyAgICBwaWVjZXMgPSBQeUxpc3RfTmV3KDApOworICAgIGlmIChwaWVjZXMgPT0gTlVMTCkKKyAgICAgICAgZ290byBEb25lOworCisgICAgY29sb24gPSBQeVN0cmluZ19Gcm9tU3RyaW5nKCI6ICIpOworICAgIGlmIChjb2xvbiA9PSBOVUxMKQorICAgICAgICBnb3RvIERvbmU7CisKKyAgICAvKiBEbyByZXByKCkgb24gZWFjaCBrZXkrdmFsdWUgcGFpciwgYW5kIGluc2VydCAiOiAiIGJldHdlZW4gdGhlbS4KKyAgICAgICBOb3RlIHRoYXQgcmVwciBtYXkgbXV0YXRlIHRoZSBkaWN0LiAqLworICAgIGkgPSAwOworICAgIHdoaWxlIChQeURpY3RfTmV4dCgoUHlPYmplY3QgKiltcCwgJmksICZrZXksICZ2YWx1ZSkpIHsKKyAgICAgICAgaW50IHN0YXR1czsKKyAgICAgICAgLyogUHJldmVudCByZXByIGZyb20gZGVsZXRpbmcgdmFsdWUgZHVyaW5nIGtleSBmb3JtYXQuICovCisgICAgICAgIFB5X0lOQ1JFRih2YWx1ZSk7CisgICAgICAgIHMgPSBQeU9iamVjdF9SZXByKGtleSk7CisgICAgICAgIFB5U3RyaW5nX0NvbmNhdCgmcywgY29sb24pOworICAgICAgICBQeVN0cmluZ19Db25jYXRBbmREZWwoJnMsIFB5T2JqZWN0X1JlcHIodmFsdWUpKTsKKyAgICAgICAgUHlfREVDUkVGKHZhbHVlKTsKKyAgICAgICAgaWYgKHMgPT0gTlVMTCkKKyAgICAgICAgICAgIGdvdG8gRG9uZTsKKyAgICAgICAgc3RhdHVzID0gUHlMaXN0X0FwcGVuZChwaWVjZXMsIHMpOworICAgICAgICBQeV9ERUNSRUYocyk7ICAvKiBhcHBlbmQgY3JlYXRlZCBhIG5ldyByZWYgKi8KKyAgICAgICAgaWYgKHN0YXR1cyA8IDApCisgICAgICAgICAgICBnb3RvIERvbmU7CisgICAgfQorCisgICAgLyogQWRkICJ7fSIgZGVjb3JhdGlvbnMgdG8gdGhlIGZpcnN0IGFuZCBsYXN0IGl0ZW1zLiAqLworICAgIGFzc2VydChQeUxpc3RfR0VUX1NJWkUocGllY2VzKSA+IDApOworICAgIHMgPSBQeVN0cmluZ19Gcm9tU3RyaW5nKCJ7Iik7CisgICAgaWYgKHMgPT0gTlVMTCkKKyAgICAgICAgZ290byBEb25lOworICAgIHRlbXAgPSBQeUxpc3RfR0VUX0lURU0ocGllY2VzLCAwKTsKKyAgICBQeVN0cmluZ19Db25jYXRBbmREZWwoJnMsIHRlbXApOworICAgIFB5TGlzdF9TRVRfSVRFTShwaWVjZXMsIDAsIHMpOworICAgIGlmIChzID09IE5VTEwpCisgICAgICAgIGdvdG8gRG9uZTsKKworICAgIHMgPSBQeVN0cmluZ19Gcm9tU3RyaW5nKCJ9Iik7CisgICAgaWYgKHMgPT0gTlVMTCkKKyAgICAgICAgZ290byBEb25lOworICAgIHRlbXAgPSBQeUxpc3RfR0VUX0lURU0ocGllY2VzLCBQeUxpc3RfR0VUX1NJWkUocGllY2VzKSAtIDEpOworICAgIFB5U3RyaW5nX0NvbmNhdEFuZERlbCgmdGVtcCwgcyk7CisgICAgUHlMaXN0X1NFVF9JVEVNKHBpZWNlcywgUHlMaXN0X0dFVF9TSVpFKHBpZWNlcykgLSAxLCB0ZW1wKTsKKyAgICBpZiAodGVtcCA9PSBOVUxMKQorICAgICAgICBnb3RvIERvbmU7CisKKyAgICAvKiBQYXN0ZSB0aGVtIGFsbCB0b2dldGhlciB3aXRoICIsICIgYmV0d2Vlbi4gKi8KKyAgICBzID0gUHlTdHJpbmdfRnJvbVN0cmluZygiLCAiKTsKKyAgICBpZiAocyA9PSBOVUxMKQorICAgICAgICBnb3RvIERvbmU7CisgICAgcmVzdWx0ID0gX1B5U3RyaW5nX0pvaW4ocywgcGllY2VzKTsKKyAgICBQeV9ERUNSRUYocyk7CisKK0RvbmU6CisgICAgUHlfWERFQ1JFRihwaWVjZXMpOworICAgIFB5X1hERUNSRUYoY29sb24pOworICAgIFB5X1JlcHJMZWF2ZSgoUHlPYmplY3QgKiltcCk7CisgICAgcmV0dXJuIHJlc3VsdDsKK30KKworc3RhdGljIFB5X3NzaXplX3QKK2RpY3RfbGVuZ3RoKFB5RGljdE9iamVjdCAqbXApCit7CisgICAgcmV0dXJuIG1wLT5tYV91c2VkOworfQorCitzdGF0aWMgUHlPYmplY3QgKgorZGljdF9zdWJzY3JpcHQoUHlEaWN0T2JqZWN0ICptcCwgcmVnaXN0ZXIgUHlPYmplY3QgKmtleSkKK3sKKyAgICBQeU9iamVjdCAqdjsKKyAgICBsb25nIGhhc2g7CisgICAgUHlEaWN0RW50cnkgKmVwOworICAgIGFzc2VydChtcC0+bWFfdGFibGUgIT0gTlVMTCk7CisgICAgaWYgKCFQeVN0cmluZ19DaGVja0V4YWN0KGtleSkgfHwKKyAgICAgICAgKGhhc2ggPSAoKFB5U3RyaW5nT2JqZWN0ICopIGtleSktPm9iX3NoYXNoKSA9PSAtMSkgeworICAgICAgICBoYXNoID0gUHlPYmplY3RfSGFzaChrZXkpOworICAgICAgICBpZiAoaGFzaCA9PSAtMSkKKyAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICBlcCA9IChtcC0+bWFfbG9va3VwKShtcCwga2V5LCBoYXNoKTsKKyAgICBpZiAoZXAgPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgdiA9IGVwLT5tZV92YWx1ZTsKKyAgICBpZiAodiA9PSBOVUxMKSB7CisgICAgICAgIGlmICghUHlEaWN0X0NoZWNrRXhhY3QobXApKSB7CisgICAgICAgICAgICAvKiBMb29rIHVwIF9fbWlzc2luZ19fIG1ldGhvZCBpZiB3ZSdyZSBhIHN1YmNsYXNzLiAqLworICAgICAgICAgICAgUHlPYmplY3QgKm1pc3NpbmcsICpyZXM7CisgICAgICAgICAgICBzdGF0aWMgUHlPYmplY3QgKm1pc3Npbmdfc3RyID0gTlVMTDsKKyAgICAgICAgICAgIG1pc3NpbmcgPSBfUHlPYmplY3RfTG9va3VwU3BlY2lhbCgoUHlPYmplY3QgKiltcCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiX19taXNzaW5nX18iLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZtaXNzaW5nX3N0cik7CisgICAgICAgICAgICBpZiAobWlzc2luZyAhPSBOVUxMKSB7CisgICAgICAgICAgICAgICAgcmVzID0gUHlPYmplY3RfQ2FsbEZ1bmN0aW9uT2JqQXJncyhtaXNzaW5nLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAga2V5LCBOVUxMKTsKKyAgICAgICAgICAgICAgICBQeV9ERUNSRUYobWlzc2luZyk7CisgICAgICAgICAgICAgICAgcmV0dXJuIHJlczsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGVsc2UgaWYgKFB5RXJyX09jY3VycmVkKCkpCisgICAgICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgICAgIH0KKyAgICAgICAgc2V0X2tleV9lcnJvcihrZXkpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgZWxzZQorICAgICAgICBQeV9JTkNSRUYodik7CisgICAgcmV0dXJuIHY7Cit9CisKK3N0YXRpYyBpbnQKK2RpY3RfYXNzX3N1YihQeURpY3RPYmplY3QgKm1wLCBQeU9iamVjdCAqdiwgUHlPYmplY3QgKncpCit7CisgICAgaWYgKHcgPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIFB5RGljdF9EZWxJdGVtKChQeU9iamVjdCAqKW1wLCB2KTsKKyAgICBlbHNlCisgICAgICAgIHJldHVybiBQeURpY3RfU2V0SXRlbSgoUHlPYmplY3QgKiltcCwgdiwgdyk7Cit9CisKK3N0YXRpYyBQeU1hcHBpbmdNZXRob2RzIGRpY3RfYXNfbWFwcGluZyA9IHsKKyAgICAobGVuZnVuYylkaWN0X2xlbmd0aCwgLyptcF9sZW5ndGgqLworICAgIChiaW5hcnlmdW5jKWRpY3Rfc3Vic2NyaXB0LCAvKm1wX3N1YnNjcmlwdCovCisgICAgKG9iam9iamFyZ3Byb2MpZGljdF9hc3Nfc3ViLCAvKm1wX2Fzc19zdWJzY3JpcHQqLworfTsKKworc3RhdGljIFB5T2JqZWN0ICoKK2RpY3Rfa2V5cyhyZWdpc3RlciBQeURpY3RPYmplY3QgKm1wKQoreworICAgIHJlZ2lzdGVyIFB5T2JqZWN0ICp2OworICAgIHJlZ2lzdGVyIFB5X3NzaXplX3QgaSwgajsKKyAgICBQeURpY3RFbnRyeSAqZXA7CisgICAgUHlfc3NpemVfdCBtYXNrLCBuOworCisgIGFnYWluOgorICAgIG4gPSBtcC0+bWFfdXNlZDsKKyAgICB2ID0gUHlMaXN0X05ldyhuKTsKKyAgICBpZiAodiA9PSBOVUxMKQorICAgICAgICByZXR1cm4gTlVMTDsKKyAgICBpZiAobiAhPSBtcC0+bWFfdXNlZCkgeworICAgICAgICAvKiBEdXJuaXQuICBUaGUgYWxsb2NhdGlvbnMgY2F1c2VkIHRoZSBkaWN0IHRvIHJlc2l6ZS4KKyAgICAgICAgICogSnVzdCBzdGFydCBvdmVyLCB0aGlzIHNob3VsZG4ndCBub3JtYWxseSBoYXBwZW4uCisgICAgICAgICAqLworICAgICAgICBQeV9ERUNSRUYodik7CisgICAgICAgIGdvdG8gYWdhaW47CisgICAgfQorICAgIGVwID0gbXAtPm1hX3RhYmxlOworICAgIG1hc2sgPSBtcC0+bWFfbWFzazsKKyAgICBmb3IgKGkgPSAwLCBqID0gMDsgaSA8PSBtYXNrOyBpKyspIHsKKyAgICAgICAgaWYgKGVwW2ldLm1lX3ZhbHVlICE9IE5VTEwpIHsKKyAgICAgICAgICAgIFB5T2JqZWN0ICprZXkgPSBlcFtpXS5tZV9rZXk7CisgICAgICAgICAgICBQeV9JTkNSRUYoa2V5KTsKKyAgICAgICAgICAgIFB5TGlzdF9TRVRfSVRFTSh2LCBqLCBrZXkpOworICAgICAgICAgICAgaisrOworICAgICAgICB9CisgICAgfQorICAgIGFzc2VydChqID09IG4pOworICAgIHJldHVybiB2OworfQorCitzdGF0aWMgUHlPYmplY3QgKgorZGljdF92YWx1ZXMocmVnaXN0ZXIgUHlEaWN0T2JqZWN0ICptcCkKK3sKKyAgICByZWdpc3RlciBQeU9iamVjdCAqdjsKKyAgICByZWdpc3RlciBQeV9zc2l6ZV90IGksIGo7CisgICAgUHlEaWN0RW50cnkgKmVwOworICAgIFB5X3NzaXplX3QgbWFzaywgbjsKKworICBhZ2FpbjoKKyAgICBuID0gbXAtPm1hX3VzZWQ7CisgICAgdiA9IFB5TGlzdF9OZXcobik7CisgICAgaWYgKHYgPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgaWYgKG4gIT0gbXAtPm1hX3VzZWQpIHsKKyAgICAgICAgLyogRHVybml0LiAgVGhlIGFsbG9jYXRpb25zIGNhdXNlZCB0aGUgZGljdCB0byByZXNpemUuCisgICAgICAgICAqIEp1c3Qgc3RhcnQgb3ZlciwgdGhpcyBzaG91bGRuJ3Qgbm9ybWFsbHkgaGFwcGVuLgorICAgICAgICAgKi8KKyAgICAgICAgUHlfREVDUkVGKHYpOworICAgICAgICBnb3RvIGFnYWluOworICAgIH0KKyAgICBlcCA9IG1wLT5tYV90YWJsZTsKKyAgICBtYXNrID0gbXAtPm1hX21hc2s7CisgICAgZm9yIChpID0gMCwgaiA9IDA7IGkgPD0gbWFzazsgaSsrKSB7CisgICAgICAgIGlmIChlcFtpXS5tZV92YWx1ZSAhPSBOVUxMKSB7CisgICAgICAgICAgICBQeU9iamVjdCAqdmFsdWUgPSBlcFtpXS5tZV92YWx1ZTsKKyAgICAgICAgICAgIFB5X0lOQ1JFRih2YWx1ZSk7CisgICAgICAgICAgICBQeUxpc3RfU0VUX0lURU0odiwgaiwgdmFsdWUpOworICAgICAgICAgICAgaisrOworICAgICAgICB9CisgICAgfQorICAgIGFzc2VydChqID09IG4pOworICAgIHJldHVybiB2OworfQorCitzdGF0aWMgUHlPYmplY3QgKgorZGljdF9pdGVtcyhyZWdpc3RlciBQeURpY3RPYmplY3QgKm1wKQoreworICAgIHJlZ2lzdGVyIFB5T2JqZWN0ICp2OworICAgIHJlZ2lzdGVyIFB5X3NzaXplX3QgaSwgaiwgbjsKKyAgICBQeV9zc2l6ZV90IG1hc2s7CisgICAgUHlPYmplY3QgKml0ZW0sICprZXksICp2YWx1ZTsKKyAgICBQeURpY3RFbnRyeSAqZXA7CisKKyAgICAvKiBQcmVhbGxvY2F0ZSB0aGUgbGlzdCBvZiB0dXBsZXMsIHRvIGF2b2lkIGFsbG9jYXRpb25zIGR1cmluZworICAgICAqIHRoZSBsb29wIG92ZXIgdGhlIGl0ZW1zLCB3aGljaCBjb3VsZCB0cmlnZ2VyIEdDLCB3aGljaAorICAgICAqIGNvdWxkIHJlc2l6ZSB0aGUgZGljdC4gOi0oCisgICAgICovCisgIGFnYWluOgorICAgIG4gPSBtcC0+bWFfdXNlZDsKKyAgICB2ID0gUHlMaXN0X05ldyhuKTsKKyAgICBpZiAodiA9PSBOVUxMKQorICAgICAgICByZXR1cm4gTlVMTDsKKyAgICBmb3IgKGkgPSAwOyBpIDwgbjsgaSsrKSB7CisgICAgICAgIGl0ZW0gPSBQeVR1cGxlX05ldygyKTsKKyAgICAgICAgaWYgKGl0ZW0gPT0gTlVMTCkgeworICAgICAgICAgICAgUHlfREVDUkVGKHYpOworICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgICAgIH0KKyAgICAgICAgUHlMaXN0X1NFVF9JVEVNKHYsIGksIGl0ZW0pOworICAgIH0KKyAgICBpZiAobiAhPSBtcC0+bWFfdXNlZCkgeworICAgICAgICAvKiBEdXJuaXQuICBUaGUgYWxsb2NhdGlvbnMgY2F1c2VkIHRoZSBkaWN0IHRvIHJlc2l6ZS4KKyAgICAgICAgICogSnVzdCBzdGFydCBvdmVyLCB0aGlzIHNob3VsZG4ndCBub3JtYWxseSBoYXBwZW4uCisgICAgICAgICAqLworICAgICAgICBQeV9ERUNSRUYodik7CisgICAgICAgIGdvdG8gYWdhaW47CisgICAgfQorICAgIC8qIE5vdGhpbmcgd2UgZG8gYmVsb3cgbWFrZXMgYW55IGZ1bmN0aW9uIGNhbGxzLiAqLworICAgIGVwID0gbXAtPm1hX3RhYmxlOworICAgIG1hc2sgPSBtcC0+bWFfbWFzazsKKyAgICBmb3IgKGkgPSAwLCBqID0gMDsgaSA8PSBtYXNrOyBpKyspIHsKKyAgICAgICAgaWYgKCh2YWx1ZT1lcFtpXS5tZV92YWx1ZSkgIT0gTlVMTCkgeworICAgICAgICAgICAga2V5ID0gZXBbaV0ubWVfa2V5OworICAgICAgICAgICAgaXRlbSA9IFB5TGlzdF9HRVRfSVRFTSh2LCBqKTsKKyAgICAgICAgICAgIFB5X0lOQ1JFRihrZXkpOworICAgICAgICAgICAgUHlUdXBsZV9TRVRfSVRFTShpdGVtLCAwLCBrZXkpOworICAgICAgICAgICAgUHlfSU5DUkVGKHZhbHVlKTsKKyAgICAgICAgICAgIFB5VHVwbGVfU0VUX0lURU0oaXRlbSwgMSwgdmFsdWUpOworICAgICAgICAgICAgaisrOworICAgICAgICB9CisgICAgfQorICAgIGFzc2VydChqID09IG4pOworICAgIHJldHVybiB2OworfQorCitzdGF0aWMgUHlPYmplY3QgKgorZGljdF9mcm9ta2V5cyhQeU9iamVjdCAqY2xzLCBQeU9iamVjdCAqYXJncykKK3sKKyAgICBQeU9iamVjdCAqc2VxOworICAgIFB5T2JqZWN0ICp2YWx1ZSA9IFB5X05vbmU7CisgICAgUHlPYmplY3QgKml0OyAgICAgICAvKiBpdGVyKHNlcSkgKi8KKyAgICBQeU9iamVjdCAqa2V5OworICAgIFB5T2JqZWN0ICpkOworICAgIGludCBzdGF0dXM7CisKKyAgICBpZiAoIVB5QXJnX1VucGFja1R1cGxlKGFyZ3MsICJmcm9ta2V5cyIsIDEsIDIsICZzZXEsICZ2YWx1ZSkpCisgICAgICAgIHJldHVybiBOVUxMOworCisgICAgZCA9IFB5T2JqZWN0X0NhbGxPYmplY3QoY2xzLCBOVUxMKTsKKyAgICBpZiAoZCA9PSBOVUxMKQorICAgICAgICByZXR1cm4gTlVMTDsKKworICAgIGlmIChQeURpY3RfQ2hlY2tFeGFjdChkKSAmJiAoKFB5RGljdE9iamVjdCAqKWQpLT5tYV91c2VkID09IDApIHsKKyAgICAgICAgaWYgKFB5RGljdF9DaGVja0V4YWN0KHNlcSkpIHsKKyAgICAgICAgICAgIFB5RGljdE9iamVjdCAqbXAgPSAoUHlEaWN0T2JqZWN0ICopZDsKKyAgICAgICAgICAgIFB5T2JqZWN0ICpvbGR2YWx1ZTsKKyAgICAgICAgICAgIFB5X3NzaXplX3QgcG9zID0gMDsKKyAgICAgICAgICAgIFB5T2JqZWN0ICprZXk7CisgICAgICAgICAgICBsb25nIGhhc2g7CisKKyAgICAgICAgICAgIGlmIChkaWN0cmVzaXplKG1wLCBQeV9TSVpFKHNlcSkpKSB7CisgICAgICAgICAgICAgICAgUHlfREVDUkVGKGQpOworICAgICAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICB3aGlsZSAoX1B5RGljdF9OZXh0KHNlcSwgJnBvcywgJmtleSwgJm9sZHZhbHVlLCAmaGFzaCkpIHsKKyAgICAgICAgICAgICAgICBQeV9JTkNSRUYoa2V5KTsKKyAgICAgICAgICAgICAgICBQeV9JTkNSRUYodmFsdWUpOworICAgICAgICAgICAgICAgIGlmIChpbnNlcnRkaWN0KG1wLCBrZXksIGhhc2gsIHZhbHVlKSkgeworICAgICAgICAgICAgICAgICAgICBQeV9ERUNSRUYoZCk7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBkOworICAgICAgICB9CisgICAgICAgIGlmIChQeUFueVNldF9DaGVja0V4YWN0KHNlcSkpIHsKKyAgICAgICAgICAgIFB5RGljdE9iamVjdCAqbXAgPSAoUHlEaWN0T2JqZWN0ICopZDsKKyAgICAgICAgICAgIFB5X3NzaXplX3QgcG9zID0gMDsKKyAgICAgICAgICAgIFB5T2JqZWN0ICprZXk7CisgICAgICAgICAgICBsb25nIGhhc2g7CisKKyAgICAgICAgICAgIGlmIChkaWN0cmVzaXplKG1wLCBQeVNldF9HRVRfU0laRShzZXEpKSkgeworICAgICAgICAgICAgICAgIFB5X0RFQ1JFRihkKTsKKyAgICAgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgd2hpbGUgKF9QeVNldF9OZXh0RW50cnkoc2VxLCAmcG9zLCAma2V5LCAmaGFzaCkpIHsKKyAgICAgICAgICAgICAgICBQeV9JTkNSRUYoa2V5KTsKKyAgICAgICAgICAgICAgICBQeV9JTkNSRUYodmFsdWUpOworICAgICAgICAgICAgICAgIGlmIChpbnNlcnRkaWN0KG1wLCBrZXksIGhhc2gsIHZhbHVlKSkgeworICAgICAgICAgICAgICAgICAgICBQeV9ERUNSRUYoZCk7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBkOworICAgICAgICB9CisgICAgfQorCisgICAgaXQgPSBQeU9iamVjdF9HZXRJdGVyKHNlcSk7CisgICAgaWYgKGl0ID09IE5VTEwpeworICAgICAgICBQeV9ERUNSRUYoZCk7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKworICAgIGlmIChQeURpY3RfQ2hlY2tFeGFjdChkKSkgeworICAgICAgICB3aGlsZSAoKGtleSA9IFB5SXRlcl9OZXh0KGl0KSkgIT0gTlVMTCkgeworICAgICAgICAgICAgc3RhdHVzID0gUHlEaWN0X1NldEl0ZW0oZCwga2V5LCB2YWx1ZSk7CisgICAgICAgICAgICBQeV9ERUNSRUYoa2V5KTsKKyAgICAgICAgICAgIGlmIChzdGF0dXMgPCAwKQorICAgICAgICAgICAgICAgIGdvdG8gRmFpbDsKKyAgICAgICAgfQorICAgIH0gZWxzZSB7CisgICAgICAgIHdoaWxlICgoa2V5ID0gUHlJdGVyX05leHQoaXQpKSAhPSBOVUxMKSB7CisgICAgICAgICAgICBzdGF0dXMgPSBQeU9iamVjdF9TZXRJdGVtKGQsIGtleSwgdmFsdWUpOworICAgICAgICAgICAgUHlfREVDUkVGKGtleSk7CisgICAgICAgICAgICBpZiAoc3RhdHVzIDwgMCkKKyAgICAgICAgICAgICAgICBnb3RvIEZhaWw7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBpZiAoUHlFcnJfT2NjdXJyZWQoKSkKKyAgICAgICAgZ290byBGYWlsOworICAgIFB5X0RFQ1JFRihpdCk7CisgICAgcmV0dXJuIGQ7CisKK0ZhaWw6CisgICAgUHlfREVDUkVGKGl0KTsKKyAgICBQeV9ERUNSRUYoZCk7CisgICAgcmV0dXJuIE5VTEw7Cit9CisKK3N0YXRpYyBpbnQKK2RpY3RfdXBkYXRlX2NvbW1vbihQeU9iamVjdCAqc2VsZiwgUHlPYmplY3QgKmFyZ3MsIFB5T2JqZWN0ICprd2RzLCBjaGFyICptZXRobmFtZSkKK3sKKyAgICBQeU9iamVjdCAqYXJnID0gTlVMTDsKKyAgICBpbnQgcmVzdWx0ID0gMDsKKworICAgIGlmICghUHlBcmdfVW5wYWNrVHVwbGUoYXJncywgbWV0aG5hbWUsIDAsIDEsICZhcmcpKQorICAgICAgICByZXN1bHQgPSAtMTsKKworICAgIGVsc2UgaWYgKGFyZyAhPSBOVUxMKSB7CisgICAgICAgIGlmIChQeU9iamVjdF9IYXNBdHRyU3RyaW5nKGFyZywgImtleXMiKSkKKyAgICAgICAgICAgIHJlc3VsdCA9IFB5RGljdF9NZXJnZShzZWxmLCBhcmcsIDEpOworICAgICAgICBlbHNlCisgICAgICAgICAgICByZXN1bHQgPSBQeURpY3RfTWVyZ2VGcm9tU2VxMihzZWxmLCBhcmcsIDEpOworICAgIH0KKyAgICBpZiAocmVzdWx0ID09IDAgJiYga3dkcyAhPSBOVUxMKQorICAgICAgICByZXN1bHQgPSBQeURpY3RfTWVyZ2Uoc2VsZiwga3dkcywgMSk7CisgICAgcmV0dXJuIHJlc3VsdDsKK30KKworc3RhdGljIFB5T2JqZWN0ICoKK2RpY3RfdXBkYXRlKFB5T2JqZWN0ICpzZWxmLCBQeU9iamVjdCAqYXJncywgUHlPYmplY3QgKmt3ZHMpCit7CisgICAgaWYgKGRpY3RfdXBkYXRlX2NvbW1vbihzZWxmLCBhcmdzLCBrd2RzLCAidXBkYXRlIikgIT0gLTEpCisgICAgICAgIFB5X1JFVFVSTl9OT05FOworICAgIHJldHVybiBOVUxMOworfQorCisvKiBVcGRhdGUgdW5jb25kaXRpb25hbGx5IHJlcGxhY2VzIGV4aXN0aW5nIGl0ZW1zLgorICAgTWVyZ2UgaGFzIGEgM3JkIGFyZ3VtZW50ICdvdmVycmlkZSc7IGlmIHNldCwgaXQgYWN0cyBsaWtlIFVwZGF0ZSwKKyAgIG90aGVyd2lzZSBpdCBsZWF2ZXMgZXhpc3RpbmcgaXRlbXMgdW5jaGFuZ2VkLgorCisgICBQeURpY3Rfe1VwZGF0ZSxNZXJnZX0gdXBkYXRlL21lcmdlIGZyb20gYSBtYXBwaW5nIG9iamVjdC4KKworICAgUHlEaWN0X01lcmdlRnJvbVNlcTIgdXBkYXRlcy9tZXJnZXMgZnJvbSBhbnkgaXRlcmFibGUgb2JqZWN0CisgICBwcm9kdWNpbmcgaXRlcmFibGUgb2JqZWN0cyBvZiBsZW5ndGggMi4KKyovCisKK2ludAorUHlEaWN0X01lcmdlRnJvbVNlcTIoUHlPYmplY3QgKmQsIFB5T2JqZWN0ICpzZXEyLCBpbnQgb3ZlcnJpZGUpCit7CisgICAgUHlPYmplY3QgKml0OyAgICAgICAvKiBpdGVyKHNlcTIpICovCisgICAgUHlfc3NpemVfdCBpOyAgICAgICAvKiBpbmRleCBpbnRvIHNlcTIgb2YgY3VycmVudCBlbGVtZW50ICovCisgICAgUHlPYmplY3QgKml0ZW07ICAgICAvKiBzZXEyW2ldICovCisgICAgUHlPYmplY3QgKmZhc3Q7ICAgICAvKiBpdGVtIGFzIGEgMi10dXBsZSBvciAyLWxpc3QgKi8KKworICAgIGFzc2VydChkICE9IE5VTEwpOworICAgIGFzc2VydChQeURpY3RfQ2hlY2soZCkpOworICAgIGFzc2VydChzZXEyICE9IE5VTEwpOworCisgICAgaXQgPSBQeU9iamVjdF9HZXRJdGVyKHNlcTIpOworICAgIGlmIChpdCA9PSBOVUxMKQorICAgICAgICByZXR1cm4gLTE7CisKKyAgICBmb3IgKGkgPSAwOyA7ICsraSkgeworICAgICAgICBQeU9iamVjdCAqa2V5LCAqdmFsdWU7CisgICAgICAgIFB5X3NzaXplX3QgbjsKKworICAgICAgICBmYXN0ID0gTlVMTDsKKyAgICAgICAgaXRlbSA9IFB5SXRlcl9OZXh0KGl0KTsKKyAgICAgICAgaWYgKGl0ZW0gPT0gTlVMTCkgeworICAgICAgICAgICAgaWYgKFB5RXJyX09jY3VycmVkKCkpCisgICAgICAgICAgICAgICAgZ290byBGYWlsOworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKworICAgICAgICAvKiBDb252ZXJ0IGl0ZW0gdG8gc2VxdWVuY2UsIGFuZCB2ZXJpZnkgbGVuZ3RoIDIuICovCisgICAgICAgIGZhc3QgPSBQeVNlcXVlbmNlX0Zhc3QoaXRlbSwgIiIpOworICAgICAgICBpZiAoZmFzdCA9PSBOVUxMKSB7CisgICAgICAgICAgICBpZiAoUHlFcnJfRXhjZXB0aW9uTWF0Y2hlcyhQeUV4Y19UeXBlRXJyb3IpKQorICAgICAgICAgICAgICAgIFB5RXJyX0Zvcm1hdChQeUV4Y19UeXBlRXJyb3IsCisgICAgICAgICAgICAgICAgICAgICJjYW5ub3QgY29udmVydCBkaWN0aW9uYXJ5IHVwZGF0ZSAiCisgICAgICAgICAgICAgICAgICAgICJzZXF1ZW5jZSBlbGVtZW50ICMlemQgdG8gYSBzZXF1ZW5jZSIsCisgICAgICAgICAgICAgICAgICAgIGkpOworICAgICAgICAgICAgZ290byBGYWlsOworICAgICAgICB9CisgICAgICAgIG4gPSBQeVNlcXVlbmNlX0Zhc3RfR0VUX1NJWkUoZmFzdCk7CisgICAgICAgIGlmIChuICE9IDIpIHsKKyAgICAgICAgICAgIFB5RXJyX0Zvcm1hdChQeUV4Y19WYWx1ZUVycm9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICJkaWN0aW9uYXJ5IHVwZGF0ZSBzZXF1ZW5jZSBlbGVtZW50ICMlemQgIgorICAgICAgICAgICAgICAgICAgICAgICAgICJoYXMgbGVuZ3RoICV6ZDsgMiBpcyByZXF1aXJlZCIsCisgICAgICAgICAgICAgICAgICAgICAgICAgaSwgbik7CisgICAgICAgICAgICBnb3RvIEZhaWw7CisgICAgICAgIH0KKworICAgICAgICAvKiBVcGRhdGUvbWVyZ2Ugd2l0aCB0aGlzIChrZXksIHZhbHVlKSBwYWlyLiAqLworICAgICAgICBrZXkgPSBQeVNlcXVlbmNlX0Zhc3RfR0VUX0lURU0oZmFzdCwgMCk7CisgICAgICAgIHZhbHVlID0gUHlTZXF1ZW5jZV9GYXN0X0dFVF9JVEVNKGZhc3QsIDEpOworICAgICAgICBpZiAob3ZlcnJpZGUgfHwgUHlEaWN0X0dldEl0ZW0oZCwga2V5KSA9PSBOVUxMKSB7CisgICAgICAgICAgICBpbnQgc3RhdHVzID0gUHlEaWN0X1NldEl0ZW0oZCwga2V5LCB2YWx1ZSk7CisgICAgICAgICAgICBpZiAoc3RhdHVzIDwgMCkKKyAgICAgICAgICAgICAgICBnb3RvIEZhaWw7CisgICAgICAgIH0KKyAgICAgICAgUHlfREVDUkVGKGZhc3QpOworICAgICAgICBQeV9ERUNSRUYoaXRlbSk7CisgICAgfQorCisgICAgaSA9IDA7CisgICAgZ290byBSZXR1cm47CitGYWlsOgorICAgIFB5X1hERUNSRUYoaXRlbSk7CisgICAgUHlfWERFQ1JFRihmYXN0KTsKKyAgICBpID0gLTE7CitSZXR1cm46CisgICAgUHlfREVDUkVGKGl0KTsKKyAgICByZXR1cm4gUHlfU0FGRV9ET1dOQ0FTVChpLCBQeV9zc2l6ZV90LCBpbnQpOworfQorCitpbnQKK1B5RGljdF9VcGRhdGUoUHlPYmplY3QgKmEsIFB5T2JqZWN0ICpiKQoreworICAgIHJldHVybiBQeURpY3RfTWVyZ2UoYSwgYiwgMSk7Cit9CisKK2ludAorUHlEaWN0X01lcmdlKFB5T2JqZWN0ICphLCBQeU9iamVjdCAqYiwgaW50IG92ZXJyaWRlKQoreworICAgIHJlZ2lzdGVyIFB5RGljdE9iamVjdCAqbXAsICpvdGhlcjsKKyAgICByZWdpc3RlciBQeV9zc2l6ZV90IGk7CisgICAgUHlEaWN0RW50cnkgKmVudHJ5OworCisgICAgLyogV2UgYWNjZXB0IGZvciB0aGUgYXJndW1lbnQgZWl0aGVyIGEgY29uY3JldGUgZGljdGlvbmFyeSBvYmplY3QsCisgICAgICogb3IgYW4gYWJzdHJhY3QgIm1hcHBpbmciIG9iamVjdC4gIEZvciB0aGUgZm9ybWVyLCB3ZSBjYW4gZG8KKyAgICAgKiB0aGluZ3MgcXVpdGUgZWZmaWNpZW50bHkuICBGb3IgdGhlIGxhdHRlciwgd2Ugb25seSByZXF1aXJlIHRoYXQKKyAgICAgKiBQeU1hcHBpbmdfS2V5cygpIGFuZCBQeU9iamVjdF9HZXRJdGVtKCkgYmUgc3VwcG9ydGVkLgorICAgICAqLworICAgIGlmIChhID09IE5VTEwgfHwgIVB5RGljdF9DaGVjayhhKSB8fCBiID09IE5VTEwpIHsKKyAgICAgICAgUHlFcnJfQmFkSW50ZXJuYWxDYWxsKCk7CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisgICAgbXAgPSAoUHlEaWN0T2JqZWN0KilhOworICAgIGlmIChQeURpY3RfQ2hlY2soYikpIHsKKyAgICAgICAgb3RoZXIgPSAoUHlEaWN0T2JqZWN0KiliOworICAgICAgICBpZiAob3RoZXIgPT0gbXAgfHwgb3RoZXItPm1hX3VzZWQgPT0gMCkKKyAgICAgICAgICAgIC8qIGEudXBkYXRlKGEpIG9yIGEudXBkYXRlKHt9KTsgbm90aGluZyB0byBkbyAqLworICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgIGlmIChtcC0+bWFfdXNlZCA9PSAwKQorICAgICAgICAgICAgLyogU2luY2UgdGhlIHRhcmdldCBkaWN0IGlzIGVtcHR5LCBQeURpY3RfR2V0SXRlbSgpCisgICAgICAgICAgICAgKiBhbHdheXMgcmV0dXJucyBOVUxMLiAgU2V0dGluZyBvdmVycmlkZSB0byAxCisgICAgICAgICAgICAgKiBza2lwcyB0aGUgdW5uZWNlc3NhcnkgdGVzdC4KKyAgICAgICAgICAgICAqLworICAgICAgICAgICAgb3ZlcnJpZGUgPSAxOworICAgICAgICAvKiBEbyBvbmUgYmlnIHJlc2l6ZSBhdCB0aGUgc3RhcnQsIHJhdGhlciB0aGFuCisgICAgICAgICAqIGluY3JlbWVudGFsbHkgcmVzaXppbmcgYXMgd2UgaW5zZXJ0IG5ldyBpdGVtcy4gIEV4cGVjdAorICAgICAgICAgKiB0aGF0IHRoZXJlIHdpbGwgYmUgbm8gKG9yIGZldykgb3ZlcmxhcHBpbmcga2V5cy4KKyAgICAgICAgICovCisgICAgICAgIGlmICgobXAtPm1hX2ZpbGwgKyBvdGhlci0+bWFfdXNlZCkqMyA+PSAobXAtPm1hX21hc2srMSkqMikgeworICAgICAgICAgICBpZiAoZGljdHJlc2l6ZShtcCwgKG1wLT5tYV91c2VkICsgb3RoZXItPm1hX3VzZWQpKjIpICE9IDApCisgICAgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgIH0KKyAgICAgICAgZm9yIChpID0gMDsgaSA8PSBvdGhlci0+bWFfbWFzazsgaSsrKSB7CisgICAgICAgICAgICBlbnRyeSA9ICZvdGhlci0+bWFfdGFibGVbaV07CisgICAgICAgICAgICBpZiAoZW50cnktPm1lX3ZhbHVlICE9IE5VTEwgJiYKKyAgICAgICAgICAgICAgICAob3ZlcnJpZGUgfHwKKyAgICAgICAgICAgICAgICAgUHlEaWN0X0dldEl0ZW0oYSwgZW50cnktPm1lX2tleSkgPT0gTlVMTCkpIHsKKyAgICAgICAgICAgICAgICBQeV9JTkNSRUYoZW50cnktPm1lX2tleSk7CisgICAgICAgICAgICAgICAgUHlfSU5DUkVGKGVudHJ5LT5tZV92YWx1ZSk7CisgICAgICAgICAgICAgICAgaWYgKGluc2VydGRpY3QobXAsIGVudHJ5LT5tZV9rZXksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGxvbmcpZW50cnktPm1lX2hhc2gsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZW50cnktPm1lX3ZhbHVlKSAhPSAwKQorICAgICAgICAgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisgICAgZWxzZSB7CisgICAgICAgIC8qIERvIGl0IHRoZSBnZW5lcmljLCBzbG93ZXIgd2F5ICovCisgICAgICAgIFB5T2JqZWN0ICprZXlzID0gUHlNYXBwaW5nX0tleXMoYik7CisgICAgICAgIFB5T2JqZWN0ICppdGVyOworICAgICAgICBQeU9iamVjdCAqa2V5LCAqdmFsdWU7CisgICAgICAgIGludCBzdGF0dXM7CisKKyAgICAgICAgaWYgKGtleXMgPT0gTlVMTCkKKyAgICAgICAgICAgIC8qIERvY3N0cmluZyBzYXlzIHRoaXMgaXMgZXF1aXZhbGVudCB0byBFLmtleXMoKSBzbworICAgICAgICAgICAgICogaWYgRSBkb2Vzbid0IGhhdmUgYSAua2V5cygpIG1ldGhvZCB3ZSB3YW50CisgICAgICAgICAgICAgKiBBdHRyaWJ1dGVFcnJvciB0byBwZXJjb2xhdGUgdXAuICBNaWdodCBhcyB3ZWxsCisgICAgICAgICAgICAgKiBkbyB0aGUgc2FtZSBmb3IgYW55IG90aGVyIGVycm9yLgorICAgICAgICAgICAgICovCisgICAgICAgICAgICByZXR1cm4gLTE7CisKKyAgICAgICAgaXRlciA9IFB5T2JqZWN0X0dldEl0ZXIoa2V5cyk7CisgICAgICAgIFB5X0RFQ1JFRihrZXlzKTsKKyAgICAgICAgaWYgKGl0ZXIgPT0gTlVMTCkKKyAgICAgICAgICAgIHJldHVybiAtMTsKKworICAgICAgICBmb3IgKGtleSA9IFB5SXRlcl9OZXh0KGl0ZXIpOyBrZXk7IGtleSA9IFB5SXRlcl9OZXh0KGl0ZXIpKSB7CisgICAgICAgICAgICBpZiAoIW92ZXJyaWRlICYmIFB5RGljdF9HZXRJdGVtKGEsIGtleSkgIT0gTlVMTCkgeworICAgICAgICAgICAgICAgIFB5X0RFQ1JFRihrZXkpOworICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgfQorICAgICAgICAgICAgdmFsdWUgPSBQeU9iamVjdF9HZXRJdGVtKGIsIGtleSk7CisgICAgICAgICAgICBpZiAodmFsdWUgPT0gTlVMTCkgeworICAgICAgICAgICAgICAgIFB5X0RFQ1JFRihpdGVyKTsKKyAgICAgICAgICAgICAgICBQeV9ERUNSRUYoa2V5KTsKKyAgICAgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBzdGF0dXMgPSBQeURpY3RfU2V0SXRlbShhLCBrZXksIHZhbHVlKTsKKyAgICAgICAgICAgIFB5X0RFQ1JFRihrZXkpOworICAgICAgICAgICAgUHlfREVDUkVGKHZhbHVlKTsKKyAgICAgICAgICAgIGlmIChzdGF0dXMgPCAwKSB7CisgICAgICAgICAgICAgICAgUHlfREVDUkVGKGl0ZXIpOworICAgICAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBQeV9ERUNSRUYoaXRlcik7CisgICAgICAgIGlmIChQeUVycl9PY2N1cnJlZCgpKQorICAgICAgICAgICAgLyogSXRlcmF0b3IgY29tcGxldGVkLCB2aWEgZXJyb3IgKi8KKyAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisgICAgcmV0dXJuIDA7Cit9CisKK3N0YXRpYyBQeU9iamVjdCAqCitkaWN0X2NvcHkocmVnaXN0ZXIgUHlEaWN0T2JqZWN0ICptcCkKK3sKKyAgICByZXR1cm4gUHlEaWN0X0NvcHkoKFB5T2JqZWN0KiltcCk7Cit9CisKK1B5T2JqZWN0ICoKK1B5RGljdF9Db3B5KFB5T2JqZWN0ICpvKQoreworICAgIFB5T2JqZWN0ICpjb3B5OworCisgICAgaWYgKG8gPT0gTlVMTCB8fCAhUHlEaWN0X0NoZWNrKG8pKSB7CisgICAgICAgIFB5RXJyX0JhZEludGVybmFsQ2FsbCgpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgY29weSA9IFB5RGljdF9OZXcoKTsKKyAgICBpZiAoY29weSA9PSBOVUxMKQorICAgICAgICByZXR1cm4gTlVMTDsKKyAgICBpZiAoUHlEaWN0X01lcmdlKGNvcHksIG8sIDEpID09IDApCisgICAgICAgIHJldHVybiBjb3B5OworICAgIFB5X0RFQ1JFRihjb3B5KTsKKyAgICByZXR1cm4gTlVMTDsKK30KKworUHlfc3NpemVfdAorUHlEaWN0X1NpemUoUHlPYmplY3QgKm1wKQoreworICAgIGlmIChtcCA9PSBOVUxMIHx8ICFQeURpY3RfQ2hlY2sobXApKSB7CisgICAgICAgIFB5RXJyX0JhZEludGVybmFsQ2FsbCgpOworICAgICAgICByZXR1cm4gLTE7CisgICAgfQorICAgIHJldHVybiAoKFB5RGljdE9iamVjdCAqKW1wKS0+bWFfdXNlZDsKK30KKworUHlPYmplY3QgKgorUHlEaWN0X0tleXMoUHlPYmplY3QgKm1wKQoreworICAgIGlmIChtcCA9PSBOVUxMIHx8ICFQeURpY3RfQ2hlY2sobXApKSB7CisgICAgICAgIFB5RXJyX0JhZEludGVybmFsQ2FsbCgpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgcmV0dXJuIGRpY3Rfa2V5cygoUHlEaWN0T2JqZWN0ICopbXApOworfQorCitQeU9iamVjdCAqCitQeURpY3RfVmFsdWVzKFB5T2JqZWN0ICptcCkKK3sKKyAgICBpZiAobXAgPT0gTlVMTCB8fCAhUHlEaWN0X0NoZWNrKG1wKSkgeworICAgICAgICBQeUVycl9CYWRJbnRlcm5hbENhbGwoKTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIHJldHVybiBkaWN0X3ZhbHVlcygoUHlEaWN0T2JqZWN0ICopbXApOworfQorCitQeU9iamVjdCAqCitQeURpY3RfSXRlbXMoUHlPYmplY3QgKm1wKQoreworICAgIGlmIChtcCA9PSBOVUxMIHx8ICFQeURpY3RfQ2hlY2sobXApKSB7CisgICAgICAgIFB5RXJyX0JhZEludGVybmFsQ2FsbCgpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgcmV0dXJuIGRpY3RfaXRlbXMoKFB5RGljdE9iamVjdCAqKW1wKTsKK30KKworLyogU3Vicm91dGluZSB3aGljaCByZXR1cm5zIHRoZSBzbWFsbGVzdCBrZXkgaW4gYSBmb3Igd2hpY2ggYidzIHZhbHVlCisgICBpcyBkaWZmZXJlbnQgb3IgYWJzZW50LiAgVGhlIHZhbHVlIGlzIHJldHVybmVkIHRvbywgdGhyb3VnaCB0aGUKKyAgIHB2YWwgYXJndW1lbnQuICBCb3RoIGFyZSBOVUxMIGlmIG5vIGtleSBpbiBhIGlzIGZvdW5kIGZvciB3aGljaCBiJ3Mgc3RhdHVzCisgICBkaWZmZXJzLiAgVGhlIHJlZmNvdW50cyBvbiAoYW5kIG9ubHkgb24pIG5vbi1OVUxMICpwdmFsIGFuZCBmdW5jdGlvbiByZXR1cm4KKyAgIHZhbHVlcyBtdXN0IGJlIGRlY3JlbWVudGVkIGJ5IHRoZSBjYWxsZXIgKGNoYXJhY3Rlcml6ZSgpIGluY3JlbWVudHMgdGhlbQorICAgdG8gZW5zdXJlIHRoYXQgbXV0YXRpbmcgY29tcGFyaXNvbiBhbmQgUHlEaWN0X0dldEl0ZW0gY2FsbHMgY2FuJ3QgZGVsZXRlCisgICB0aGVtIGJlZm9yZSB0aGUgY2FsbGVyIGlzIGRvbmUgbG9va2luZyBhdCB0aGVtKS4gKi8KKworc3RhdGljIFB5T2JqZWN0ICoKK2NoYXJhY3Rlcml6ZShQeURpY3RPYmplY3QgKmEsIFB5RGljdE9iamVjdCAqYiwgUHlPYmplY3QgKipwdmFsKQoreworICAgIFB5T2JqZWN0ICpha2V5ID0gTlVMTDsgLyogc21hbGxlc3Qga2V5IGluIGEgcy50LiBhW2FrZXldICE9IGJbYWtleV0gKi8KKyAgICBQeU9iamVjdCAqYXZhbCA9IE5VTEw7IC8qIGFbYWtleV0gKi8KKyAgICBQeV9zc2l6ZV90IGk7CisgICAgaW50IGNtcDsKKworICAgIGZvciAoaSA9IDA7IGkgPD0gYS0+bWFfbWFzazsgaSsrKSB7CisgICAgICAgIFB5T2JqZWN0ICp0aGlza2V5LCAqdGhpc2F2YWwsICp0aGlzYnZhbDsKKyAgICAgICAgaWYgKGEtPm1hX3RhYmxlW2ldLm1lX3ZhbHVlID09IE5VTEwpCisgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgdGhpc2tleSA9IGEtPm1hX3RhYmxlW2ldLm1lX2tleTsKKyAgICAgICAgUHlfSU5DUkVGKHRoaXNrZXkpOyAgLyoga2VlcCBhbGl2ZSBhY3Jvc3MgY29tcGFyZXMgKi8KKyAgICAgICAgaWYgKGFrZXkgIT0gTlVMTCkgeworICAgICAgICAgICAgY21wID0gUHlPYmplY3RfUmljaENvbXBhcmVCb29sKGFrZXksIHRoaXNrZXksIFB5X0xUKTsKKyAgICAgICAgICAgIGlmIChjbXAgPCAwKSB7CisgICAgICAgICAgICAgICAgUHlfREVDUkVGKHRoaXNrZXkpOworICAgICAgICAgICAgICAgIGdvdG8gRmFpbDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChjbXAgPiAwIHx8CisgICAgICAgICAgICAgICAgaSA+IGEtPm1hX21hc2sgfHwKKyAgICAgICAgICAgICAgICBhLT5tYV90YWJsZVtpXS5tZV92YWx1ZSA9PSBOVUxMKQorICAgICAgICAgICAgeworICAgICAgICAgICAgICAgIC8qIE5vdCB0aGUgKnNtYWxsZXN0KiBhIGtleTsgb3IgbWF5YmUgaXQgaXMKKyAgICAgICAgICAgICAgICAgKiBidXQgdGhlIGNvbXBhcmUgc2hydW5rIHRoZSBkaWN0IHNvIHdlIGNhbid0CisgICAgICAgICAgICAgICAgICogZmluZCBpdHMgYXNzb2NpYXRlZCB2YWx1ZSBhbnltb3JlOyBvcgorICAgICAgICAgICAgICAgICAqIG1heWJlIGl0IGlzIGJ1dCB0aGUgY29tcGFyZSBkZWxldGVkIHRoZQorICAgICAgICAgICAgICAgICAqIGFbdGhpc2tleV0gZW50cnkuCisgICAgICAgICAgICAgICAgICovCisgICAgICAgICAgICAgICAgUHlfREVDUkVGKHRoaXNrZXkpOworICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgLyogQ29tcGFyZSBhW3RoaXNrZXldIHRvIGJbdGhpc2tleV07IGNtcCA8LSB0cnVlIGlmZiBlcXVhbC4gKi8KKyAgICAgICAgdGhpc2F2YWwgPSBhLT5tYV90YWJsZVtpXS5tZV92YWx1ZTsKKyAgICAgICAgYXNzZXJ0KHRoaXNhdmFsKTsKKyAgICAgICAgUHlfSU5DUkVGKHRoaXNhdmFsKTsgICAvKiBrZWVwIGFsaXZlICovCisgICAgICAgIHRoaXNidmFsID0gUHlEaWN0X0dldEl0ZW0oKFB5T2JqZWN0ICopYiwgdGhpc2tleSk7CisgICAgICAgIGlmICh0aGlzYnZhbCA9PSBOVUxMKQorICAgICAgICAgICAgY21wID0gMDsKKyAgICAgICAgZWxzZSB7CisgICAgICAgICAgICAvKiBib3RoIGRpY3RzIGhhdmUgdGhpc2tleTogIHNhbWUgdmFsdWVzPyAqLworICAgICAgICAgICAgY21wID0gUHlPYmplY3RfUmljaENvbXBhcmVCb29sKAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpc2F2YWwsIHRoaXNidmFsLCBQeV9FUSk7CisgICAgICAgICAgICBpZiAoY21wIDwgMCkgeworICAgICAgICAgICAgICAgIFB5X0RFQ1JFRih0aGlza2V5KTsKKyAgICAgICAgICAgICAgICBQeV9ERUNSRUYodGhpc2F2YWwpOworICAgICAgICAgICAgICAgIGdvdG8gRmFpbDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBpZiAoY21wID09IDApIHsKKyAgICAgICAgICAgIC8qIE5ldyB3aW5uZXIuICovCisgICAgICAgICAgICBQeV9YREVDUkVGKGFrZXkpOworICAgICAgICAgICAgUHlfWERFQ1JFRihhdmFsKTsKKyAgICAgICAgICAgIGFrZXkgPSB0aGlza2V5OworICAgICAgICAgICAgYXZhbCA9IHRoaXNhdmFsOworICAgICAgICB9CisgICAgICAgIGVsc2UgeworICAgICAgICAgICAgUHlfREVDUkVGKHRoaXNrZXkpOworICAgICAgICAgICAgUHlfREVDUkVGKHRoaXNhdmFsKTsKKyAgICAgICAgfQorICAgIH0KKyAgICAqcHZhbCA9IGF2YWw7CisgICAgcmV0dXJuIGFrZXk7CisKK0ZhaWw6CisgICAgUHlfWERFQ1JFRihha2V5KTsKKyAgICBQeV9YREVDUkVGKGF2YWwpOworICAgICpwdmFsID0gTlVMTDsKKyAgICByZXR1cm4gTlVMTDsKK30KKworc3RhdGljIGludAorZGljdF9jb21wYXJlKFB5RGljdE9iamVjdCAqYSwgUHlEaWN0T2JqZWN0ICpiKQoreworICAgIFB5T2JqZWN0ICphZGlmZiwgKmJkaWZmLCAqYXZhbCwgKmJ2YWw7CisgICAgaW50IHJlczsKKworICAgIC8qIENvbXBhcmUgbGVuZ3RocyBmaXJzdCAqLworICAgIGlmIChhLT5tYV91c2VkIDwgYi0+bWFfdXNlZCkKKyAgICAgICAgcmV0dXJuIC0xOyAgICAgICAgICAgICAgLyogYSBpcyBzaG9ydGVyICovCisgICAgZWxzZSBpZiAoYS0+bWFfdXNlZCA+IGItPm1hX3VzZWQpCisgICAgICAgIHJldHVybiAxOyAgICAgICAgICAgICAgIC8qIGIgaXMgc2hvcnRlciAqLworCisgICAgLyogU2FtZSBsZW5ndGggLS0gY2hlY2sgYWxsIGtleXMgKi8KKyAgICBiZGlmZiA9IGJ2YWwgPSBOVUxMOworICAgIGFkaWZmID0gY2hhcmFjdGVyaXplKGEsIGIsICZhdmFsKTsKKyAgICBpZiAoYWRpZmYgPT0gTlVMTCkgeworICAgICAgICBhc3NlcnQoIWF2YWwpOworICAgICAgICAvKiBFaXRoZXIgYW4gZXJyb3IsIG9yIGEgaXMgYSBzdWJzZXQgd2l0aCB0aGUgc2FtZSBsZW5ndGggc28KKyAgICAgICAgICogbXVzdCBiZSBlcXVhbC4KKyAgICAgICAgICovCisgICAgICAgIHJlcyA9IFB5RXJyX09jY3VycmVkKCkgPyAtMSA6IDA7CisgICAgICAgIGdvdG8gRmluaXNoZWQ7CisgICAgfQorICAgIGJkaWZmID0gY2hhcmFjdGVyaXplKGIsIGEsICZidmFsKTsKKyAgICBpZiAoYmRpZmYgPT0gTlVMTCAmJiBQeUVycl9PY2N1cnJlZCgpKSB7CisgICAgICAgIGFzc2VydCghYnZhbCk7CisgICAgICAgIHJlcyA9IC0xOworICAgICAgICBnb3RvIEZpbmlzaGVkOworICAgIH0KKyAgICByZXMgPSAwOworICAgIGlmIChiZGlmZikgeworICAgICAgICAvKiBiZGlmZiA9PSBOVUxMICJzaG91bGQgYmUiIGltcG9zc2libGUgbm93LCBidXQgcGVyaGFwcworICAgICAgICAgKiB0aGUgbGFzdCBjb21wYXJpc29uIGRvbmUgYnkgdGhlIGNoYXJhY3Rlcml6ZSgpIG9uIGEgaGFkCisgICAgICAgICAqIHRoZSBzaWRlIGVmZmVjdCBvZiBtYWtpbmcgdGhlIGRpY3RzIGVxdWFsIQorICAgICAgICAgKi8KKyAgICAgICAgcmVzID0gUHlPYmplY3RfQ29tcGFyZShhZGlmZiwgYmRpZmYpOworICAgIH0KKyAgICBpZiAocmVzID09IDAgJiYgYnZhbCAhPSBOVUxMKQorICAgICAgICByZXMgPSBQeU9iamVjdF9Db21wYXJlKGF2YWwsIGJ2YWwpOworCitGaW5pc2hlZDoKKyAgICBQeV9YREVDUkVGKGFkaWZmKTsKKyAgICBQeV9YREVDUkVGKGJkaWZmKTsKKyAgICBQeV9YREVDUkVGKGF2YWwpOworICAgIFB5X1hERUNSRUYoYnZhbCk7CisgICAgcmV0dXJuIHJlczsKK30KKworLyogUmV0dXJuIDEgaWYgZGljdHMgZXF1YWwsIDAgaWYgbm90LCAtMSBpZiBlcnJvci4KKyAqIEdldHMgb3V0IGFzIHNvb24gYXMgYW55IGRpZmZlcmVuY2UgaXMgZGV0ZWN0ZWQuCisgKiBVc2VzIG9ubHkgUHlfRVEgY29tcGFyaXNvbi4KKyAqLworc3RhdGljIGludAorZGljdF9lcXVhbChQeURpY3RPYmplY3QgKmEsIFB5RGljdE9iamVjdCAqYikKK3sKKyAgICBQeV9zc2l6ZV90IGk7CisKKyAgICBpZiAoYS0+bWFfdXNlZCAhPSBiLT5tYV91c2VkKQorICAgICAgICAvKiBjYW4ndCBiZSBlcXVhbCBpZiAjIG9mIGVudHJpZXMgZGlmZmVyICovCisgICAgICAgIHJldHVybiAwOworCisgICAgLyogU2FtZSAjIG9mIGVudHJpZXMgLS0gY2hlY2sgYWxsIG9mICdlbS4gIEV4aXQgZWFybHkgb24gYW55IGRpZmYuICovCisgICAgZm9yIChpID0gMDsgaSA8PSBhLT5tYV9tYXNrOyBpKyspIHsKKyAgICAgICAgUHlPYmplY3QgKmF2YWwgPSBhLT5tYV90YWJsZVtpXS5tZV92YWx1ZTsKKyAgICAgICAgaWYgKGF2YWwgIT0gTlVMTCkgeworICAgICAgICAgICAgaW50IGNtcDsKKyAgICAgICAgICAgIFB5T2JqZWN0ICpidmFsOworICAgICAgICAgICAgUHlPYmplY3QgKmtleSA9IGEtPm1hX3RhYmxlW2ldLm1lX2tleTsKKyAgICAgICAgICAgIC8qIHRlbXBvcmFyaWx5IGJ1bXAgYXZhbCdzIHJlZmNvdW50IHRvIGVuc3VyZSBpdCBzdGF5cworICAgICAgICAgICAgICAgYWxpdmUgdW50aWwgd2UncmUgZG9uZSB3aXRoIGl0ICovCisgICAgICAgICAgICBQeV9JTkNSRUYoYXZhbCk7CisgICAgICAgICAgICAvKiBkaXR0byBmb3Iga2V5ICovCisgICAgICAgICAgICBQeV9JTkNSRUYoa2V5KTsKKyAgICAgICAgICAgIGJ2YWwgPSBQeURpY3RfR2V0SXRlbSgoUHlPYmplY3QgKiliLCBrZXkpOworICAgICAgICAgICAgUHlfREVDUkVGKGtleSk7CisgICAgICAgICAgICBpZiAoYnZhbCA9PSBOVUxMKSB7CisgICAgICAgICAgICAgICAgUHlfREVDUkVGKGF2YWwpOworICAgICAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICAgICAgfQorICAgICAgICAgICAgY21wID0gUHlPYmplY3RfUmljaENvbXBhcmVCb29sKGF2YWwsIGJ2YWwsIFB5X0VRKTsKKyAgICAgICAgICAgIFB5X0RFQ1JFRihhdmFsKTsKKyAgICAgICAgICAgIGlmIChjbXAgPD0gMCkgIC8qIGVycm9yIG9yIG5vdCBlcXVhbCAqLworICAgICAgICAgICAgICAgIHJldHVybiBjbXA7CisgICAgICAgIH0KKyAgICB9CisgICAgcmV0dXJuIDE7CisgfQorCitzdGF0aWMgUHlPYmplY3QgKgorZGljdF9yaWNoY29tcGFyZShQeU9iamVjdCAqdiwgUHlPYmplY3QgKncsIGludCBvcCkKK3sKKyAgICBpbnQgY21wOworICAgIFB5T2JqZWN0ICpyZXM7CisKKyAgICBpZiAoIVB5RGljdF9DaGVjayh2KSB8fCAhUHlEaWN0X0NoZWNrKHcpKSB7CisgICAgICAgIHJlcyA9IFB5X05vdEltcGxlbWVudGVkOworICAgIH0KKyAgICBlbHNlIGlmIChvcCA9PSBQeV9FUSB8fCBvcCA9PSBQeV9ORSkgeworICAgICAgICBjbXAgPSBkaWN0X2VxdWFsKChQeURpY3RPYmplY3QgKil2LCAoUHlEaWN0T2JqZWN0ICopdyk7CisgICAgICAgIGlmIChjbXAgPCAwKQorICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgICAgIHJlcyA9IChjbXAgPT0gKG9wID09IFB5X0VRKSkgPyBQeV9UcnVlIDogUHlfRmFsc2U7CisgICAgfQorICAgIGVsc2UgeworICAgICAgICAvKiBQeTNLIHdhcm5pbmcgaWYgY29tcGFyaXNvbiBpc24ndCA9PSBvciAhPSAgKi8KKyAgICAgICAgaWYgKFB5RXJyX1dhcm5QeTNrKCJkaWN0IGluZXF1YWxpdHkgY29tcGFyaXNvbnMgbm90IHN1cHBvcnRlZCAiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAiaW4gMy54IiwgMSkgPCAwKSB7CisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgfQorICAgICAgICByZXMgPSBQeV9Ob3RJbXBsZW1lbnRlZDsKKyAgICB9CisgICAgUHlfSU5DUkVGKHJlcyk7CisgICAgcmV0dXJuIHJlczsKKyB9CisKK3N0YXRpYyBQeU9iamVjdCAqCitkaWN0X2NvbnRhaW5zKHJlZ2lzdGVyIFB5RGljdE9iamVjdCAqbXAsIFB5T2JqZWN0ICprZXkpCit7CisgICAgbG9uZyBoYXNoOworICAgIFB5RGljdEVudHJ5ICplcDsKKworICAgIGlmICghUHlTdHJpbmdfQ2hlY2tFeGFjdChrZXkpIHx8CisgICAgICAgIChoYXNoID0gKChQeVN0cmluZ09iamVjdCAqKSBrZXkpLT5vYl9zaGFzaCkgPT0gLTEpIHsKKyAgICAgICAgaGFzaCA9IFB5T2JqZWN0X0hhc2goa2V5KTsKKyAgICAgICAgaWYgKGhhc2ggPT0gLTEpCisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgZXAgPSAobXAtPm1hX2xvb2t1cCkobXAsIGtleSwgaGFzaCk7CisgICAgaWYgKGVwID09IE5VTEwpCisgICAgICAgIHJldHVybiBOVUxMOworICAgIHJldHVybiBQeUJvb2xfRnJvbUxvbmcoZXAtPm1lX3ZhbHVlICE9IE5VTEwpOworfQorCitzdGF0aWMgUHlPYmplY3QgKgorZGljdF9oYXNfa2V5KHJlZ2lzdGVyIFB5RGljdE9iamVjdCAqbXAsIFB5T2JqZWN0ICprZXkpCit7CisgICAgaWYgKFB5RXJyX1dhcm5QeTNrKCJkaWN0Lmhhc19rZXkoKSBub3Qgc3VwcG9ydGVkIGluIDMueDsgIgorICAgICAgICAgICAgICAgICAgICAgICAidXNlIHRoZSBpbiBvcGVyYXRvciIsIDEpIDwgMCkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgcmV0dXJuIGRpY3RfY29udGFpbnMobXAsIGtleSk7Cit9CisKK3N0YXRpYyBQeU9iamVjdCAqCitkaWN0X2dldChyZWdpc3RlciBQeURpY3RPYmplY3QgKm1wLCBQeU9iamVjdCAqYXJncykKK3sKKyAgICBQeU9iamVjdCAqa2V5OworICAgIFB5T2JqZWN0ICpmYWlsb2JqID0gUHlfTm9uZTsKKyAgICBQeU9iamVjdCAqdmFsID0gTlVMTDsKKyAgICBsb25nIGhhc2g7CisgICAgUHlEaWN0RW50cnkgKmVwOworCisgICAgaWYgKCFQeUFyZ19VbnBhY2tUdXBsZShhcmdzLCAiZ2V0IiwgMSwgMiwgJmtleSwgJmZhaWxvYmopKQorICAgICAgICByZXR1cm4gTlVMTDsKKworICAgIGlmICghUHlTdHJpbmdfQ2hlY2tFeGFjdChrZXkpIHx8CisgICAgICAgIChoYXNoID0gKChQeVN0cmluZ09iamVjdCAqKSBrZXkpLT5vYl9zaGFzaCkgPT0gLTEpIHsKKyAgICAgICAgaGFzaCA9IFB5T2JqZWN0X0hhc2goa2V5KTsKKyAgICAgICAgaWYgKGhhc2ggPT0gLTEpCisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgZXAgPSAobXAtPm1hX2xvb2t1cCkobXAsIGtleSwgaGFzaCk7CisgICAgaWYgKGVwID09IE5VTEwpCisgICAgICAgIHJldHVybiBOVUxMOworICAgIHZhbCA9IGVwLT5tZV92YWx1ZTsKKyAgICBpZiAodmFsID09IE5VTEwpCisgICAgICAgIHZhbCA9IGZhaWxvYmo7CisgICAgUHlfSU5DUkVGKHZhbCk7CisgICAgcmV0dXJuIHZhbDsKK30KKworCitzdGF0aWMgUHlPYmplY3QgKgorZGljdF9zZXRkZWZhdWx0KHJlZ2lzdGVyIFB5RGljdE9iamVjdCAqbXAsIFB5T2JqZWN0ICphcmdzKQoreworICAgIFB5T2JqZWN0ICprZXk7CisgICAgUHlPYmplY3QgKmZhaWxvYmogPSBQeV9Ob25lOworICAgIFB5T2JqZWN0ICp2YWwgPSBOVUxMOworICAgIGxvbmcgaGFzaDsKKyAgICBQeURpY3RFbnRyeSAqZXA7CisKKyAgICBpZiAoIVB5QXJnX1VucGFja1R1cGxlKGFyZ3MsICJzZXRkZWZhdWx0IiwgMSwgMiwgJmtleSwgJmZhaWxvYmopKQorICAgICAgICByZXR1cm4gTlVMTDsKKworICAgIGlmICghUHlTdHJpbmdfQ2hlY2tFeGFjdChrZXkpIHx8CisgICAgICAgIChoYXNoID0gKChQeVN0cmluZ09iamVjdCAqKSBrZXkpLT5vYl9zaGFzaCkgPT0gLTEpIHsKKyAgICAgICAgaGFzaCA9IFB5T2JqZWN0X0hhc2goa2V5KTsKKyAgICAgICAgaWYgKGhhc2ggPT0gLTEpCisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgZXAgPSAobXAtPm1hX2xvb2t1cCkobXAsIGtleSwgaGFzaCk7CisgICAgaWYgKGVwID09IE5VTEwpCisgICAgICAgIHJldHVybiBOVUxMOworICAgIHZhbCA9IGVwLT5tZV92YWx1ZTsKKyAgICBpZiAodmFsID09IE5VTEwpIHsKKyAgICAgICAgaWYgKGRpY3Rfc2V0X2l0ZW1fYnlfaGFzaF9vcl9lbnRyeSgoUHlPYmplY3QqKW1wLCBrZXksIGhhc2gsIGVwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZhaWxvYmopID09IDApCisgICAgICAgICAgICB2YWwgPSBmYWlsb2JqOworICAgIH0KKyAgICBQeV9YSU5DUkVGKHZhbCk7CisgICAgcmV0dXJuIHZhbDsKK30KKworCitzdGF0aWMgUHlPYmplY3QgKgorZGljdF9jbGVhcihyZWdpc3RlciBQeURpY3RPYmplY3QgKm1wKQoreworICAgIFB5RGljdF9DbGVhcigoUHlPYmplY3QgKiltcCk7CisgICAgUHlfUkVUVVJOX05PTkU7Cit9CisKK3N0YXRpYyBQeU9iamVjdCAqCitkaWN0X3BvcChQeURpY3RPYmplY3QgKm1wLCBQeU9iamVjdCAqYXJncykKK3sKKyAgICBsb25nIGhhc2g7CisgICAgUHlEaWN0RW50cnkgKmVwOworICAgIFB5T2JqZWN0ICpvbGRfdmFsdWUsICpvbGRfa2V5OworICAgIFB5T2JqZWN0ICprZXksICpkZWZsdCA9IE5VTEw7CisKKyAgICBpZighUHlBcmdfVW5wYWNrVHVwbGUoYXJncywgInBvcCIsIDEsIDIsICZrZXksICZkZWZsdCkpCisgICAgICAgIHJldHVybiBOVUxMOworICAgIGlmIChtcC0+bWFfdXNlZCA9PSAwKSB7CisgICAgICAgIGlmIChkZWZsdCkgeworICAgICAgICAgICAgUHlfSU5DUkVGKGRlZmx0KTsKKyAgICAgICAgICAgIHJldHVybiBkZWZsdDsKKyAgICAgICAgfQorICAgICAgICBzZXRfa2V5X2Vycm9yKGtleSk7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICBpZiAoIVB5U3RyaW5nX0NoZWNrRXhhY3Qoa2V5KSB8fAorICAgICAgICAoaGFzaCA9ICgoUHlTdHJpbmdPYmplY3QgKikga2V5KS0+b2Jfc2hhc2gpID09IC0xKSB7CisgICAgICAgIGhhc2ggPSBQeU9iamVjdF9IYXNoKGtleSk7CisgICAgICAgIGlmIChoYXNoID09IC0xKQorICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIGVwID0gKG1wLT5tYV9sb29rdXApKG1wLCBrZXksIGhhc2gpOworICAgIGlmIChlcCA9PSBOVUxMKQorICAgICAgICByZXR1cm4gTlVMTDsKKyAgICBpZiAoZXAtPm1lX3ZhbHVlID09IE5VTEwpIHsKKyAgICAgICAgaWYgKGRlZmx0KSB7CisgICAgICAgICAgICBQeV9JTkNSRUYoZGVmbHQpOworICAgICAgICAgICAgcmV0dXJuIGRlZmx0OworICAgICAgICB9CisgICAgICAgIHNldF9rZXlfZXJyb3Ioa2V5KTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIG9sZF9rZXkgPSBlcC0+bWVfa2V5OworICAgIFB5X0lOQ1JFRihkdW1teSk7CisgICAgZXAtPm1lX2tleSA9IGR1bW15OworICAgIG9sZF92YWx1ZSA9IGVwLT5tZV92YWx1ZTsKKyAgICBlcC0+bWVfdmFsdWUgPSBOVUxMOworICAgIG1wLT5tYV91c2VkLS07CisgICAgUHlfREVDUkVGKG9sZF9rZXkpOworICAgIHJldHVybiBvbGRfdmFsdWU7Cit9CisKK3N0YXRpYyBQeU9iamVjdCAqCitkaWN0X3BvcGl0ZW0oUHlEaWN0T2JqZWN0ICptcCkKK3sKKyAgICBQeV9zc2l6ZV90IGkgPSAwOworICAgIFB5RGljdEVudHJ5ICplcDsKKyAgICBQeU9iamVjdCAqcmVzOworCisgICAgLyogQWxsb2NhdGUgdGhlIHJlc3VsdCB0dXBsZSBiZWZvcmUgY2hlY2tpbmcgdGhlIHNpemUuICBCZWxpZXZlIGl0CisgICAgICogb3Igbm90LCB0aGlzIGFsbG9jYXRpb24gY291bGQgdHJpZ2dlciBhIGdhcmJhZ2UgY29sbGVjdGlvbiB3aGljaAorICAgICAqIGNvdWxkIGVtcHR5IHRoZSBkaWN0LCBzbyBpZiB3ZSBjaGVja2VkIHRoZSBzaXplIGZpcnN0IGFuZCB0aGF0CisgICAgICogaGFwcGVuZWQsIHRoZSByZXN1bHQgd291bGQgYmUgYW4gaW5maW5pdGUgbG9vcCAoc2VhcmNoaW5nIGZvciBhbgorICAgICAqIGVudHJ5IHRoYXQgbm8gbG9uZ2VyIGV4aXN0cykuICBOb3RlIHRoYXQgdGhlIHVzdWFsIHBvcGl0ZW0oKQorICAgICAqIGlkaW9tIGlzICJ3aGlsZSBkOiBrLCB2ID0gZC5wb3BpdGVtKCkiLiBzbyBuZWVkaW5nIHRvIHRocm93IHRoZQorICAgICAqIHR1cGxlIGF3YXkgaWYgdGhlIGRpY3QgKmlzKiBlbXB0eSBpc24ndCBhIHNpZ25pZmljYW50CisgICAgICogaW5lZmZpY2llbmN5IC0tIHBvc3NpYmxlLCBidXQgdW5saWtlbHkgaW4gcHJhY3RpY2UuCisgICAgICovCisgICAgcmVzID0gUHlUdXBsZV9OZXcoMik7CisgICAgaWYgKHJlcyA9PSBOVUxMKQorICAgICAgICByZXR1cm4gTlVMTDsKKyAgICBpZiAobXAtPm1hX3VzZWQgPT0gMCkgeworICAgICAgICBQeV9ERUNSRUYocmVzKTsKKyAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX0tleUVycm9yLAorICAgICAgICAgICAgICAgICAgICAgICAgInBvcGl0ZW0oKTogZGljdGlvbmFyeSBpcyBlbXB0eSIpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgLyogU2V0IGVwIHRvICJ0aGUgZmlyc3QiIGRpY3QgZW50cnkgd2l0aCBhIHZhbHVlLiAgV2UgYWJ1c2UgdGhlIGhhc2gKKyAgICAgKiBmaWVsZCBvZiBzbG90IDAgdG8gaG9sZCBhIHNlYXJjaCBmaW5nZXI6CisgICAgICogSWYgc2xvdCAwIGhhcyBhIHZhbHVlLCB1c2Ugc2xvdCAwLgorICAgICAqIEVsc2Ugc2xvdCAwIGlzIGJlaW5nIHVzZWQgdG8gaG9sZCBhIHNlYXJjaCBmaW5nZXIsCisgICAgICogYW5kIHdlIHVzZSBpdHMgaGFzaCB2YWx1ZSBhcyB0aGUgZmlyc3QgaW5kZXggdG8gbG9vay4KKyAgICAgKi8KKyAgICBlcCA9ICZtcC0+bWFfdGFibGVbMF07CisgICAgaWYgKGVwLT5tZV92YWx1ZSA9PSBOVUxMKSB7CisgICAgICAgIGkgPSBlcC0+bWVfaGFzaDsKKyAgICAgICAgLyogVGhlIGhhc2ggZmllbGQgbWF5IGJlIGEgcmVhbCBoYXNoIHZhbHVlLCBvciBpdCBtYXkgYmUgYQorICAgICAgICAgKiBsZWdpdCBzZWFyY2ggZmluZ2VyLCBvciBpdCBtYXkgYmUgYSBvbmNlLWxlZ2l0IHNlYXJjaAorICAgICAgICAgKiBmaW5nZXIgdGhhdCdzIG91dCBvZiBib3VuZHMgbm93IGJlY2F1c2UgaXQgd3JhcHBlZCBhcm91bmQKKyAgICAgICAgICogb3IgdGhlIHRhYmxlIHNocnVuayAtLSBzaW1wbHkgbWFrZSBzdXJlIGl0J3MgaW4gYm91bmRzIG5vdy4KKyAgICAgICAgICovCisgICAgICAgIGlmIChpID4gbXAtPm1hX21hc2sgfHwgaSA8IDEpCisgICAgICAgICAgICBpID0gMTsgICAgICAgICAgICAgIC8qIHNraXAgc2xvdCAwICovCisgICAgICAgIHdoaWxlICgoZXAgPSAmbXAtPm1hX3RhYmxlW2ldKS0+bWVfdmFsdWUgPT0gTlVMTCkgeworICAgICAgICAgICAgaSsrOworICAgICAgICAgICAgaWYgKGkgPiBtcC0+bWFfbWFzaykKKyAgICAgICAgICAgICAgICBpID0gMTsKKyAgICAgICAgfQorICAgIH0KKyAgICBQeVR1cGxlX1NFVF9JVEVNKHJlcywgMCwgZXAtPm1lX2tleSk7CisgICAgUHlUdXBsZV9TRVRfSVRFTShyZXMsIDEsIGVwLT5tZV92YWx1ZSk7CisgICAgUHlfSU5DUkVGKGR1bW15KTsKKyAgICBlcC0+bWVfa2V5ID0gZHVtbXk7CisgICAgZXAtPm1lX3ZhbHVlID0gTlVMTDsKKyAgICBtcC0+bWFfdXNlZC0tOworICAgIGFzc2VydChtcC0+bWFfdGFibGVbMF0ubWVfdmFsdWUgPT0gTlVMTCk7CisgICAgbXAtPm1hX3RhYmxlWzBdLm1lX2hhc2ggPSBpICsgMTsgIC8qIG5leHQgcGxhY2UgdG8gc3RhcnQgKi8KKyAgICByZXR1cm4gcmVzOworfQorCitzdGF0aWMgaW50CitkaWN0X3RyYXZlcnNlKFB5T2JqZWN0ICpvcCwgdmlzaXRwcm9jIHZpc2l0LCB2b2lkICphcmcpCit7CisgICAgUHlfc3NpemVfdCBpID0gMDsKKyAgICBQeU9iamVjdCAqcGs7CisgICAgUHlPYmplY3QgKnB2OworCisgICAgd2hpbGUgKFB5RGljdF9OZXh0KG9wLCAmaSwgJnBrLCAmcHYpKSB7CisgICAgICAgIFB5X1ZJU0lUKHBrKTsKKyAgICAgICAgUHlfVklTSVQocHYpOworICAgIH0KKyAgICByZXR1cm4gMDsKK30KKworc3RhdGljIGludAorZGljdF90cF9jbGVhcihQeU9iamVjdCAqb3ApCit7CisgICAgUHlEaWN0X0NsZWFyKG9wKTsKKyAgICByZXR1cm4gMDsKK30KKworCitleHRlcm4gUHlUeXBlT2JqZWN0IFB5RGljdEl0ZXJLZXlfVHlwZTsgLyogRm9yd2FyZCAqLworZXh0ZXJuIFB5VHlwZU9iamVjdCBQeURpY3RJdGVyVmFsdWVfVHlwZTsgLyogRm9yd2FyZCAqLworZXh0ZXJuIFB5VHlwZU9iamVjdCBQeURpY3RJdGVySXRlbV9UeXBlOyAvKiBGb3J3YXJkICovCitzdGF0aWMgUHlPYmplY3QgKmRpY3RpdGVyX25ldyhQeURpY3RPYmplY3QgKiwgUHlUeXBlT2JqZWN0ICopOworCitzdGF0aWMgUHlPYmplY3QgKgorZGljdF9pdGVya2V5cyhQeURpY3RPYmplY3QgKmRpY3QpCit7CisgICAgcmV0dXJuIGRpY3RpdGVyX25ldyhkaWN0LCAmUHlEaWN0SXRlcktleV9UeXBlKTsKK30KKworc3RhdGljIFB5T2JqZWN0ICoKK2RpY3RfaXRlcnZhbHVlcyhQeURpY3RPYmplY3QgKmRpY3QpCit7CisgICAgcmV0dXJuIGRpY3RpdGVyX25ldyhkaWN0LCAmUHlEaWN0SXRlclZhbHVlX1R5cGUpOworfQorCitzdGF0aWMgUHlPYmplY3QgKgorZGljdF9pdGVyaXRlbXMoUHlEaWN0T2JqZWN0ICpkaWN0KQoreworICAgIHJldHVybiBkaWN0aXRlcl9uZXcoZGljdCwgJlB5RGljdEl0ZXJJdGVtX1R5cGUpOworfQorCitzdGF0aWMgUHlPYmplY3QgKgorZGljdF9zaXplb2YoUHlEaWN0T2JqZWN0ICptcCkKK3sKKyAgICBQeV9zc2l6ZV90IHJlczsKKworICAgIHJlcyA9IHNpemVvZihQeURpY3RPYmplY3QpOworICAgIGlmIChtcC0+bWFfdGFibGUgIT0gbXAtPm1hX3NtYWxsdGFibGUpCisgICAgICAgIHJlcyA9IHJlcyArIChtcC0+bWFfbWFzayArIDEpICogc2l6ZW9mKFB5RGljdEVudHJ5KTsKKyAgICByZXR1cm4gUHlJbnRfRnJvbVNzaXplX3QocmVzKTsKK30KKworUHlEb2NfU1RSVkFSKGhhc19rZXlfX2RvY19fLAorIkQuaGFzX2tleShrKSAtPiBUcnVlIGlmIEQgaGFzIGEga2V5IGssIGVsc2UgRmFsc2UiKTsKKworUHlEb2NfU1RSVkFSKGNvbnRhaW5zX19kb2NfXywKKyJELl9fY29udGFpbnNfXyhrKSAtPiBUcnVlIGlmIEQgaGFzIGEga2V5IGssIGVsc2UgRmFsc2UiKTsKKworUHlEb2NfU1RSVkFSKGdldGl0ZW1fX2RvY19fLCAieC5fX2dldGl0ZW1fXyh5KSA8PT0+IHhbeV0iKTsKKworUHlEb2NfU1RSVkFSKHNpemVvZl9fZG9jX18sCisiRC5fX3NpemVvZl9fKCkgLT4gc2l6ZSBvZiBEIGluIG1lbW9yeSwgaW4gYnl0ZXMiKTsKKworUHlEb2NfU1RSVkFSKGdldF9fZG9jX18sCisiRC5nZXQoa1ssZF0pIC0+IERba10gaWYgayBpbiBELCBlbHNlIGQuICBkIGRlZmF1bHRzIHRvIE5vbmUuIik7CisKK1B5RG9jX1NUUlZBUihzZXRkZWZhdWx0X2RvY19fLAorIkQuc2V0ZGVmYXVsdChrWyxkXSkgLT4gRC5nZXQoayxkKSwgYWxzbyBzZXQgRFtrXT1kIGlmIGsgbm90IGluIEQiKTsKKworUHlEb2NfU1RSVkFSKHBvcF9fZG9jX18sCisiRC5wb3Aoa1ssZF0pIC0+IHYsIHJlbW92ZSBzcGVjaWZpZWQga2V5IGFuZCByZXR1cm4gdGhlIGNvcnJlc3BvbmRpbmcgdmFsdWUuXG5cCitJZiBrZXkgaXMgbm90IGZvdW5kLCBkIGlzIHJldHVybmVkIGlmIGdpdmVuLCBvdGhlcndpc2UgS2V5RXJyb3IgaXMgcmFpc2VkIik7CisKK1B5RG9jX1NUUlZBUihwb3BpdGVtX19kb2NfXywKKyJELnBvcGl0ZW0oKSAtPiAoaywgdiksIHJlbW92ZSBhbmQgcmV0dXJuIHNvbWUgKGtleSwgdmFsdWUpIHBhaXIgYXMgYVxuXAorMi10dXBsZTsgYnV0IHJhaXNlIEtleUVycm9yIGlmIEQgaXMgZW1wdHkuIik7CisKK1B5RG9jX1NUUlZBUihrZXlzX19kb2NfXywKKyJELmtleXMoKSAtPiBsaXN0IG9mIEQncyBrZXlzIik7CisKK1B5RG9jX1NUUlZBUihpdGVtc19fZG9jX18sCisiRC5pdGVtcygpIC0+IGxpc3Qgb2YgRCdzIChrZXksIHZhbHVlKSBwYWlycywgYXMgMi10dXBsZXMiKTsKKworUHlEb2NfU1RSVkFSKHZhbHVlc19fZG9jX18sCisiRC52YWx1ZXMoKSAtPiBsaXN0IG9mIEQncyB2YWx1ZXMiKTsKKworUHlEb2NfU1RSVkFSKHVwZGF0ZV9fZG9jX18sCisiRC51cGRhdGUoW0UsIF0qKkYpIC0+IE5vbmUuICBVcGRhdGUgRCBmcm9tIGRpY3QvaXRlcmFibGUgRSBhbmQgRi5cbiIKKyJJZiBFIHByZXNlbnQgYW5kIGhhcyBhIC5rZXlzKCkgbWV0aG9kLCBkb2VzOiAgICAgZm9yIGsgaW4gRTogRFtrXSA9IEVba11cblwKK0lmIEUgcHJlc2VudCBhbmQgbGFja3MgLmtleXMoKSBtZXRob2QsIGRvZXM6ICAgICBmb3IgKGssIHYpIGluIEU6IERba10gPSB2XG5cCitJbiBlaXRoZXIgY2FzZSwgdGhpcyBpcyBmb2xsb3dlZCBieTogZm9yIGsgaW4gRjogRFtrXSA9IEZba10iKTsKKworUHlEb2NfU1RSVkFSKGZyb21rZXlzX19kb2NfXywKKyJkaWN0LmZyb21rZXlzKFNbLHZdKSAtPiBOZXcgZGljdCB3aXRoIGtleXMgZnJvbSBTIGFuZCB2YWx1ZXMgZXF1YWwgdG8gdi5cblwKK3YgZGVmYXVsdHMgdG8gTm9uZS4iKTsKKworUHlEb2NfU1RSVkFSKGNsZWFyX19kb2NfXywKKyJELmNsZWFyKCkgLT4gTm9uZS4gIFJlbW92ZSBhbGwgaXRlbXMgZnJvbSBELiIpOworCitQeURvY19TVFJWQVIoY29weV9fZG9jX18sCisiRC5jb3B5KCkgLT4gYSBzaGFsbG93IGNvcHkgb2YgRCIpOworCitQeURvY19TVFJWQVIoaXRlcmtleXNfX2RvY19fLAorIkQuaXRlcmtleXMoKSAtPiBhbiBpdGVyYXRvciBvdmVyIHRoZSBrZXlzIG9mIEQiKTsKKworUHlEb2NfU1RSVkFSKGl0ZXJ2YWx1ZXNfX2RvY19fLAorIkQuaXRlcnZhbHVlcygpIC0+IGFuIGl0ZXJhdG9yIG92ZXIgdGhlIHZhbHVlcyBvZiBEIik7CisKK1B5RG9jX1NUUlZBUihpdGVyaXRlbXNfX2RvY19fLAorIkQuaXRlcml0ZW1zKCkgLT4gYW4gaXRlcmF0b3Igb3ZlciB0aGUgKGtleSwgdmFsdWUpIGl0ZW1zIG9mIEQiKTsKKworLyogRm9yd2FyZCAqLworc3RhdGljIFB5T2JqZWN0ICpkaWN0a2V5c19uZXcoUHlPYmplY3QgKik7CitzdGF0aWMgUHlPYmplY3QgKmRpY3RpdGVtc19uZXcoUHlPYmplY3QgKik7CitzdGF0aWMgUHlPYmplY3QgKmRpY3R2YWx1ZXNfbmV3KFB5T2JqZWN0ICopOworCitQeURvY19TVFJWQVIodmlld2tleXNfX2RvY19fLAorICAgICAgICAgICAgICJELnZpZXdrZXlzKCkgLT4gYSBzZXQtbGlrZSBvYmplY3QgcHJvdmlkaW5nIGEgdmlldyBvbiBEJ3Mga2V5cyIpOworUHlEb2NfU1RSVkFSKHZpZXdpdGVtc19fZG9jX18sCisgICAgICAgICAgICAgIkQudmlld2l0ZW1zKCkgLT4gYSBzZXQtbGlrZSBvYmplY3QgcHJvdmlkaW5nIGEgdmlldyBvbiBEJ3MgaXRlbXMiKTsKK1B5RG9jX1NUUlZBUih2aWV3dmFsdWVzX19kb2NfXywKKyAgICAgICAgICAgICAiRC52aWV3dmFsdWVzKCkgLT4gYW4gb2JqZWN0IHByb3ZpZGluZyBhIHZpZXcgb24gRCdzIHZhbHVlcyIpOworCitzdGF0aWMgUHlNZXRob2REZWYgbWFwcF9tZXRob2RzW10gPSB7CisgICAgeyJfX2NvbnRhaW5zX18iLChQeUNGdW5jdGlvbilkaWN0X2NvbnRhaW5zLCAgICAgICAgIE1FVEhfTyB8IE1FVEhfQ09FWElTVCwKKyAgICAgY29udGFpbnNfX2RvY19ffSwKKyAgICB7Il9fZ2V0aXRlbV9fIiwgKFB5Q0Z1bmN0aW9uKWRpY3Rfc3Vic2NyaXB0LCAgICAgICAgTUVUSF9PIHwgTUVUSF9DT0VYSVNULAorICAgICBnZXRpdGVtX19kb2NfX30sCisgICAgeyJfX3NpemVvZl9fIiwgICAgICAoUHlDRnVuY3Rpb24pZGljdF9zaXplb2YsICAgICAgIE1FVEhfTk9BUkdTLAorICAgICBzaXplb2ZfX2RvY19ffSwKKyAgICB7Imhhc19rZXkiLCAgICAgICAgIChQeUNGdW5jdGlvbilkaWN0X2hhc19rZXksICAgICAgTUVUSF9PLAorICAgICBoYXNfa2V5X19kb2NfX30sCisgICAgeyJnZXQiLCAgICAgICAgIChQeUNGdW5jdGlvbilkaWN0X2dldCwgICAgICAgICAgTUVUSF9WQVJBUkdTLAorICAgICBnZXRfX2RvY19ffSwKKyAgICB7InNldGRlZmF1bHQiLCAgKFB5Q0Z1bmN0aW9uKWRpY3Rfc2V0ZGVmYXVsdCwgICBNRVRIX1ZBUkFSR1MsCisgICAgIHNldGRlZmF1bHRfZG9jX199LAorICAgIHsicG9wIiwgICAgICAgICAoUHlDRnVuY3Rpb24pZGljdF9wb3AsICAgICAgICAgIE1FVEhfVkFSQVJHUywKKyAgICAgcG9wX19kb2NfX30sCisgICAgeyJwb3BpdGVtIiwgICAgICAgICAoUHlDRnVuY3Rpb24pZGljdF9wb3BpdGVtLCAgICAgIE1FVEhfTk9BUkdTLAorICAgICBwb3BpdGVtX19kb2NfX30sCisgICAgeyJrZXlzIiwgICAgICAgICAgICAoUHlDRnVuY3Rpb24pZGljdF9rZXlzLCAgICAgICAgIE1FVEhfTk9BUkdTLAorICAgIGtleXNfX2RvY19ffSwKKyAgICB7Iml0ZW1zIiwgICAgICAgICAgIChQeUNGdW5jdGlvbilkaWN0X2l0ZW1zLCAgICAgICAgTUVUSF9OT0FSR1MsCisgICAgIGl0ZW1zX19kb2NfX30sCisgICAgeyJ2YWx1ZXMiLCAgICAgICAgICAoUHlDRnVuY3Rpb24pZGljdF92YWx1ZXMsICAgICAgIE1FVEhfTk9BUkdTLAorICAgICB2YWx1ZXNfX2RvY19ffSwKKyAgICB7InZpZXdrZXlzIiwgICAgICAgIChQeUNGdW5jdGlvbilkaWN0a2V5c19uZXcsICAgICAgTUVUSF9OT0FSR1MsCisgICAgIHZpZXdrZXlzX19kb2NfX30sCisgICAgeyJ2aWV3aXRlbXMiLCAgICAgICAoUHlDRnVuY3Rpb24pZGljdGl0ZW1zX25ldywgICAgIE1FVEhfTk9BUkdTLAorICAgICB2aWV3aXRlbXNfX2RvY19ffSwKKyAgICB7InZpZXd2YWx1ZXMiLCAgICAgIChQeUNGdW5jdGlvbilkaWN0dmFsdWVzX25ldywgICAgTUVUSF9OT0FSR1MsCisgICAgIHZpZXd2YWx1ZXNfX2RvY19ffSwKKyAgICB7InVwZGF0ZSIsICAgICAgICAgIChQeUNGdW5jdGlvbilkaWN0X3VwZGF0ZSwgICAgICAgTUVUSF9WQVJBUkdTIHwgTUVUSF9LRVlXT1JEUywKKyAgICAgdXBkYXRlX19kb2NfX30sCisgICAgeyJmcm9ta2V5cyIsICAgICAgICAoUHlDRnVuY3Rpb24pZGljdF9mcm9ta2V5cywgICAgIE1FVEhfVkFSQVJHUyB8IE1FVEhfQ0xBU1MsCisgICAgIGZyb21rZXlzX19kb2NfX30sCisgICAgeyJjbGVhciIsICAgICAgICAgICAoUHlDRnVuY3Rpb24pZGljdF9jbGVhciwgICAgICAgIE1FVEhfTk9BUkdTLAorICAgICBjbGVhcl9fZG9jX199LAorICAgIHsiY29weSIsICAgICAgICAgICAgKFB5Q0Z1bmN0aW9uKWRpY3RfY29weSwgICAgICAgICBNRVRIX05PQVJHUywKKyAgICAgY29weV9fZG9jX199LAorICAgIHsiaXRlcmtleXMiLCAgICAgICAgKFB5Q0Z1bmN0aW9uKWRpY3RfaXRlcmtleXMsICAgICBNRVRIX05PQVJHUywKKyAgICAgaXRlcmtleXNfX2RvY19ffSwKKyAgICB7Iml0ZXJ2YWx1ZXMiLCAgICAgIChQeUNGdW5jdGlvbilkaWN0X2l0ZXJ2YWx1ZXMsICAgTUVUSF9OT0FSR1MsCisgICAgIGl0ZXJ2YWx1ZXNfX2RvY19ffSwKKyAgICB7Iml0ZXJpdGVtcyIsICAgICAgIChQeUNGdW5jdGlvbilkaWN0X2l0ZXJpdGVtcywgICAgTUVUSF9OT0FSR1MsCisgICAgIGl0ZXJpdGVtc19fZG9jX199LAorICAgIHtOVUxMLCAgICAgICAgICAgICAgTlVMTH0gICAvKiBzZW50aW5lbCAqLworfTsKKworLyogUmV0dXJuIDEgaWYgYGtleWAgaXMgaW4gZGljdCBgb3BgLCAwIGlmIG5vdCwgYW5kIC0xIG9uIGVycm9yLiAqLworaW50CitQeURpY3RfQ29udGFpbnMoUHlPYmplY3QgKm9wLCBQeU9iamVjdCAqa2V5KQoreworICAgIGxvbmcgaGFzaDsKKyAgICBQeURpY3RPYmplY3QgKm1wID0gKFB5RGljdE9iamVjdCAqKW9wOworICAgIFB5RGljdEVudHJ5ICplcDsKKworICAgIGlmICghUHlTdHJpbmdfQ2hlY2tFeGFjdChrZXkpIHx8CisgICAgICAgIChoYXNoID0gKChQeVN0cmluZ09iamVjdCAqKSBrZXkpLT5vYl9zaGFzaCkgPT0gLTEpIHsKKyAgICAgICAgaGFzaCA9IFB5T2JqZWN0X0hhc2goa2V5KTsKKyAgICAgICAgaWYgKGhhc2ggPT0gLTEpCisgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgfQorICAgIGVwID0gKG1wLT5tYV9sb29rdXApKG1wLCBrZXksIGhhc2gpOworICAgIHJldHVybiBlcCA9PSBOVUxMID8gLTEgOiAoZXAtPm1lX3ZhbHVlICE9IE5VTEwpOworfQorCisvKiBJbnRlcm5hbCB2ZXJzaW9uIG9mIFB5RGljdF9Db250YWlucyB1c2VkIHdoZW4gdGhlIGhhc2ggdmFsdWUgaXMgYWxyZWFkeSBrbm93biAqLworaW50CitfUHlEaWN0X0NvbnRhaW5zKFB5T2JqZWN0ICpvcCwgUHlPYmplY3QgKmtleSwgbG9uZyBoYXNoKQoreworICAgIFB5RGljdE9iamVjdCAqbXAgPSAoUHlEaWN0T2JqZWN0ICopb3A7CisgICAgUHlEaWN0RW50cnkgKmVwOworCisgICAgZXAgPSAobXAtPm1hX2xvb2t1cCkobXAsIGtleSwgaGFzaCk7CisgICAgcmV0dXJuIGVwID09IE5VTEwgPyAtMSA6IChlcC0+bWVfdmFsdWUgIT0gTlVMTCk7Cit9CisKKy8qIEhhY2sgdG8gaW1wbGVtZW50ICJrZXkgaW4gZGljdCIgKi8KK3N0YXRpYyBQeVNlcXVlbmNlTWV0aG9kcyBkaWN0X2FzX3NlcXVlbmNlID0geworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBzcV9sZW5ndGggKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgLyogc3FfY29uY2F0ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHNxX3JlcGVhdCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBzcV9pdGVtICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHNxX3NsaWNlICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHNxX2Fzc19pdGVtICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHNxX2Fzc19zbGljZSAqLworICAgIFB5RGljdF9Db250YWlucywgICAgICAgICAgICAvKiBzcV9jb250YWlucyAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBzcV9pbnBsYWNlX2NvbmNhdCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBzcV9pbnBsYWNlX3JlcGVhdCAqLworfTsKKworc3RhdGljIFB5T2JqZWN0ICoKK2RpY3RfbmV3KFB5VHlwZU9iamVjdCAqdHlwZSwgUHlPYmplY3QgKmFyZ3MsIFB5T2JqZWN0ICprd2RzKQoreworICAgIFB5T2JqZWN0ICpzZWxmOworCisgICAgYXNzZXJ0KHR5cGUgIT0gTlVMTCAmJiB0eXBlLT50cF9hbGxvYyAhPSBOVUxMKTsKKyAgICBzZWxmID0gdHlwZS0+dHBfYWxsb2ModHlwZSwgMCk7CisgICAgaWYgKHNlbGYgIT0gTlVMTCkgeworICAgICAgICBQeURpY3RPYmplY3QgKmQgPSAoUHlEaWN0T2JqZWN0ICopc2VsZjsKKyAgICAgICAgLyogSXQncyBndWFyYW50ZWVkIHRoYXQgdHAtPmFsbG9jIHplcm9lZCBvdXQgdGhlIHN0cnVjdC4gKi8KKyAgICAgICAgYXNzZXJ0KGQtPm1hX3RhYmxlID09IE5VTEwgJiYgZC0+bWFfZmlsbCA9PSAwICYmIGQtPm1hX3VzZWQgPT0gMCk7CisgICAgICAgIElOSVRfTk9OWkVST19ESUNUX1NMT1RTKGQpOworICAgICAgICBkLT5tYV9sb29rdXAgPSBsb29rZGljdF9zdHJpbmc7CisgICAgICAgIC8qIFRoZSBvYmplY3QgaGFzIGJlZW4gaW1wbGljaXRseSB0cmFja2VkIGJ5IHRwX2FsbG9jICovCisgICAgICAgIGlmICh0eXBlID09ICZQeURpY3RfVHlwZSkKKyAgICAgICAgICAgIF9QeU9iamVjdF9HQ19VTlRSQUNLKGQpOworI2lmZGVmIFNIT1dfQ09OVkVSU0lPTl9DT1VOVFMKKyAgICAgICAgKytjcmVhdGVkOworI2VuZGlmCisjaWZkZWYgU0hPV19UUkFDS19DT1VOVAorICAgICAgICBpZiAoX1B5T2JqZWN0X0dDX0lTX1RSQUNLRUQoZCkpCisgICAgICAgICAgICBjb3VudF90cmFja2VkKys7CisgICAgICAgIGVsc2UKKyAgICAgICAgICAgIGNvdW50X3VudHJhY2tlZCsrOworI2VuZGlmCisgICAgfQorICAgIHJldHVybiBzZWxmOworfQorCitzdGF0aWMgaW50CitkaWN0X2luaXQoUHlPYmplY3QgKnNlbGYsIFB5T2JqZWN0ICphcmdzLCBQeU9iamVjdCAqa3dkcykKK3sKKyAgICByZXR1cm4gZGljdF91cGRhdGVfY29tbW9uKHNlbGYsIGFyZ3MsIGt3ZHMsICJkaWN0Iik7Cit9CisKK3N0YXRpYyBQeU9iamVjdCAqCitkaWN0X2l0ZXIoUHlEaWN0T2JqZWN0ICpkaWN0KQoreworICAgIHJldHVybiBkaWN0aXRlcl9uZXcoZGljdCwgJlB5RGljdEl0ZXJLZXlfVHlwZSk7Cit9CisKK1B5RG9jX1NUUlZBUihkaWN0aW9uYXJ5X2RvYywKKyJkaWN0KCkgLT4gbmV3IGVtcHR5IGRpY3Rpb25hcnlcbiIKKyJkaWN0KG1hcHBpbmcpIC0+IG5ldyBkaWN0aW9uYXJ5IGluaXRpYWxpemVkIGZyb20gYSBtYXBwaW5nIG9iamVjdCdzXG4iCisiICAgIChrZXksIHZhbHVlKSBwYWlyc1xuIgorImRpY3QoaXRlcmFibGUpIC0+IG5ldyBkaWN0aW9uYXJ5IGluaXRpYWxpemVkIGFzIGlmIHZpYTpcbiIKKyIgICAgZCA9IHt9XG4iCisiICAgIGZvciBrLCB2IGluIGl0ZXJhYmxlOlxuIgorIiAgICAgICAgZFtrXSA9IHZcbiIKKyJkaWN0KCoqa3dhcmdzKSAtPiBuZXcgZGljdGlvbmFyeSBpbml0aWFsaXplZCB3aXRoIHRoZSBuYW1lPXZhbHVlIHBhaXJzXG4iCisiICAgIGluIHRoZSBrZXl3b3JkIGFyZ3VtZW50IGxpc3QuICBGb3IgZXhhbXBsZTogIGRpY3Qob25lPTEsIHR3bz0yKSIpOworCitQeVR5cGVPYmplY3QgUHlEaWN0X1R5cGUgPSB7CisgICAgUHlWYXJPYmplY3RfSEVBRF9JTklUKCZQeVR5cGVfVHlwZSwgMCkKKyAgICAiZGljdCIsCisgICAgc2l6ZW9mKFB5RGljdE9iamVjdCksCisgICAgMCwKKyAgICAoZGVzdHJ1Y3RvcilkaWN0X2RlYWxsb2MsICAgICAgICAgICAgICAgICAgIC8qIHRwX2RlYWxsb2MgKi8KKyAgICAocHJpbnRmdW5jKWRpY3RfcHJpbnQsICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3ByaW50ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9nZXRhdHRyICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9zZXRhdHRyICovCisgICAgKGNtcGZ1bmMpZGljdF9jb21wYXJlLCAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9jb21wYXJlICovCisgICAgKHJlcHJmdW5jKWRpY3RfcmVwciwgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9yZXByICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9hc19udW1iZXIgKi8KKyAgICAmZGljdF9hc19zZXF1ZW5jZSwgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2FzX3NlcXVlbmNlICovCisgICAgJmRpY3RfYXNfbWFwcGluZywgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9hc19tYXBwaW5nICovCisgICAgKGhhc2hmdW5jKVB5T2JqZWN0X0hhc2hOb3RJbXBsZW1lbnRlZCwgICAgICAvKiB0cF9oYXNoICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9jYWxsICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9zdHIgKi8KKyAgICBQeU9iamVjdF9HZW5lcmljR2V0QXR0ciwgICAgICAgICAgICAgICAgICAgIC8qIHRwX2dldGF0dHJvICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9zZXRhdHRybyAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfYXNfYnVmZmVyICovCisgICAgUHlfVFBGTEFHU19ERUZBVUxUIHwgUHlfVFBGTEFHU19IQVZFX0dDIHwKKyAgICAgICAgUHlfVFBGTEFHU19CQVNFVFlQRSB8IFB5X1RQRkxBR1NfRElDVF9TVUJDTEFTUywgICAgICAgICAvKiB0cF9mbGFncyAqLworICAgIGRpY3Rpb25hcnlfZG9jLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZG9jICovCisgICAgZGljdF90cmF2ZXJzZSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF90cmF2ZXJzZSAqLworICAgIGRpY3RfdHBfY2xlYXIsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfY2xlYXIgKi8KKyAgICBkaWN0X3JpY2hjb21wYXJlLCAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3JpY2hjb21wYXJlICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF93ZWFrbGlzdG9mZnNldCAqLworICAgIChnZXRpdGVyZnVuYylkaWN0X2l0ZXIsICAgICAgICAgICAgICAgICAgICAgLyogdHBfaXRlciAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfaXRlcm5leHQgKi8KKyAgICBtYXBwX21ldGhvZHMsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX21ldGhvZHMgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX21lbWJlcnMgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2dldHNldCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfYmFzZSAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZGljdCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZGVzY3JfZ2V0ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9kZXNjcl9zZXQgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2RpY3RvZmZzZXQgKi8KKyAgICBkaWN0X2luaXQsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2luaXQgKi8KKyAgICBQeVR5cGVfR2VuZXJpY0FsbG9jLCAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2FsbG9jICovCisgICAgZGljdF9uZXcsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9uZXcgKi8KKyAgICBQeU9iamVjdF9HQ19EZWwsICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2ZyZWUgKi8KK307CisKKy8qIEZvciBiYWNrd2FyZCBjb21wYXRpYmlsaXR5IHdpdGggb2xkIGRpY3Rpb25hcnkgaW50ZXJmYWNlICovCisKK1B5T2JqZWN0ICoKK1B5RGljdF9HZXRJdGVtU3RyaW5nKFB5T2JqZWN0ICp2LCBjb25zdCBjaGFyICprZXkpCit7CisgICAgUHlPYmplY3QgKmt2LCAqcnY7CisgICAga3YgPSBQeVN0cmluZ19Gcm9tU3RyaW5nKGtleSk7CisgICAgaWYgKGt2ID09IE5VTEwpCisgICAgICAgIHJldHVybiBOVUxMOworICAgIHJ2ID0gUHlEaWN0X0dldEl0ZW0odiwga3YpOworICAgIFB5X0RFQ1JFRihrdik7CisgICAgcmV0dXJuIHJ2OworfQorCitpbnQKK1B5RGljdF9TZXRJdGVtU3RyaW5nKFB5T2JqZWN0ICp2LCBjb25zdCBjaGFyICprZXksIFB5T2JqZWN0ICppdGVtKQoreworICAgIFB5T2JqZWN0ICprdjsKKyAgICBpbnQgZXJyOworICAgIGt2ID0gUHlTdHJpbmdfRnJvbVN0cmluZyhrZXkpOworICAgIGlmIChrdiA9PSBOVUxMKQorICAgICAgICByZXR1cm4gLTE7CisgICAgUHlTdHJpbmdfSW50ZXJuSW5QbGFjZSgma3YpOyAvKiBYWFggU2hvdWxkIHdlIHJlYWxseT8gKi8KKyAgICBlcnIgPSBQeURpY3RfU2V0SXRlbSh2LCBrdiwgaXRlbSk7CisgICAgUHlfREVDUkVGKGt2KTsKKyAgICByZXR1cm4gZXJyOworfQorCitpbnQKK1B5RGljdF9EZWxJdGVtU3RyaW5nKFB5T2JqZWN0ICp2LCBjb25zdCBjaGFyICprZXkpCit7CisgICAgUHlPYmplY3QgKmt2OworICAgIGludCBlcnI7CisgICAga3YgPSBQeVN0cmluZ19Gcm9tU3RyaW5nKGtleSk7CisgICAgaWYgKGt2ID09IE5VTEwpCisgICAgICAgIHJldHVybiAtMTsKKyAgICBlcnIgPSBQeURpY3RfRGVsSXRlbSh2LCBrdik7CisgICAgUHlfREVDUkVGKGt2KTsKKyAgICByZXR1cm4gZXJyOworfQorCisvKiBEaWN0aW9uYXJ5IGl0ZXJhdG9yIHR5cGVzICovCisKK3R5cGVkZWYgc3RydWN0IHsKKyAgICBQeU9iamVjdF9IRUFECisgICAgUHlEaWN0T2JqZWN0ICpkaV9kaWN0OyAvKiBTZXQgdG8gTlVMTCB3aGVuIGl0ZXJhdG9yIGlzIGV4aGF1c3RlZCAqLworICAgIFB5X3NzaXplX3QgZGlfdXNlZDsKKyAgICBQeV9zc2l6ZV90IGRpX3BvczsKKyAgICBQeU9iamVjdCogZGlfcmVzdWx0OyAvKiByZXVzYWJsZSByZXN1bHQgdHVwbGUgZm9yIGl0ZXJpdGVtcyAqLworICAgIFB5X3NzaXplX3QgbGVuOworfSBkaWN0aXRlcm9iamVjdDsKKworc3RhdGljIFB5T2JqZWN0ICoKK2RpY3RpdGVyX25ldyhQeURpY3RPYmplY3QgKmRpY3QsIFB5VHlwZU9iamVjdCAqaXRlcnR5cGUpCit7CisgICAgZGljdGl0ZXJvYmplY3QgKmRpOworICAgIGRpID0gUHlPYmplY3RfR0NfTmV3KGRpY3RpdGVyb2JqZWN0LCBpdGVydHlwZSk7CisgICAgaWYgKGRpID09IE5VTEwpCisgICAgICAgIHJldHVybiBOVUxMOworICAgIFB5X0lOQ1JFRihkaWN0KTsKKyAgICBkaS0+ZGlfZGljdCA9IGRpY3Q7CisgICAgZGktPmRpX3VzZWQgPSBkaWN0LT5tYV91c2VkOworICAgIGRpLT5kaV9wb3MgPSAwOworICAgIGRpLT5sZW4gPSBkaWN0LT5tYV91c2VkOworICAgIGlmIChpdGVydHlwZSA9PSAmUHlEaWN0SXRlckl0ZW1fVHlwZSkgeworICAgICAgICBkaS0+ZGlfcmVzdWx0ID0gUHlUdXBsZV9QYWNrKDIsIFB5X05vbmUsIFB5X05vbmUpOworICAgICAgICBpZiAoZGktPmRpX3Jlc3VsdCA9PSBOVUxMKSB7CisgICAgICAgICAgICBQeV9ERUNSRUYoZGkpOworICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgICAgIH0KKyAgICB9CisgICAgZWxzZQorICAgICAgICBkaS0+ZGlfcmVzdWx0ID0gTlVMTDsKKyAgICBfUHlPYmplY3RfR0NfVFJBQ0soZGkpOworICAgIHJldHVybiAoUHlPYmplY3QgKilkaTsKK30KKworc3RhdGljIHZvaWQKK2RpY3RpdGVyX2RlYWxsb2MoZGljdGl0ZXJvYmplY3QgKmRpKQoreworICAgIFB5X1hERUNSRUYoZGktPmRpX2RpY3QpOworICAgIFB5X1hERUNSRUYoZGktPmRpX3Jlc3VsdCk7CisgICAgUHlPYmplY3RfR0NfRGVsKGRpKTsKK30KKworc3RhdGljIGludAorZGljdGl0ZXJfdHJhdmVyc2UoZGljdGl0ZXJvYmplY3QgKmRpLCB2aXNpdHByb2MgdmlzaXQsIHZvaWQgKmFyZykKK3sKKyAgICBQeV9WSVNJVChkaS0+ZGlfZGljdCk7CisgICAgUHlfVklTSVQoZGktPmRpX3Jlc3VsdCk7CisgICAgcmV0dXJuIDA7Cit9CisKK3N0YXRpYyBQeU9iamVjdCAqCitkaWN0aXRlcl9sZW4oZGljdGl0ZXJvYmplY3QgKmRpKQoreworICAgIFB5X3NzaXplX3QgbGVuID0gMDsKKyAgICBpZiAoZGktPmRpX2RpY3QgIT0gTlVMTCAmJiBkaS0+ZGlfdXNlZCA9PSBkaS0+ZGlfZGljdC0+bWFfdXNlZCkKKyAgICAgICAgbGVuID0gZGktPmxlbjsKKyAgICByZXR1cm4gUHlJbnRfRnJvbVNpemVfdChsZW4pOworfQorCitQeURvY19TVFJWQVIobGVuZ3RoX2hpbnRfZG9jLCAiUHJpdmF0ZSBtZXRob2QgcmV0dXJuaW5nIGFuIGVzdGltYXRlIG9mIGxlbihsaXN0KGl0KSkuIik7CisKK3N0YXRpYyBQeU1ldGhvZERlZiBkaWN0aXRlcl9tZXRob2RzW10gPSB7CisgICAgeyJfX2xlbmd0aF9oaW50X18iLCAoUHlDRnVuY3Rpb24pZGljdGl0ZXJfbGVuLCBNRVRIX05PQVJHUywgbGVuZ3RoX2hpbnRfZG9jfSwKKyAgICB7TlVMTCwgICAgICAgICAgICAgIE5VTEx9ICAgICAgICAgICAvKiBzZW50aW5lbCAqLworfTsKKworc3RhdGljIFB5T2JqZWN0ICpkaWN0aXRlcl9pdGVybmV4dGtleShkaWN0aXRlcm9iamVjdCAqZGkpCit7CisgICAgUHlPYmplY3QgKmtleTsKKyAgICByZWdpc3RlciBQeV9zc2l6ZV90IGksIG1hc2s7CisgICAgcmVnaXN0ZXIgUHlEaWN0RW50cnkgKmVwOworICAgIFB5RGljdE9iamVjdCAqZCA9IGRpLT5kaV9kaWN0OworCisgICAgaWYgKGQgPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgYXNzZXJ0IChQeURpY3RfQ2hlY2soZCkpOworCisgICAgaWYgKGRpLT5kaV91c2VkICE9IGQtPm1hX3VzZWQpIHsKKyAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1J1bnRpbWVFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICJkaWN0aW9uYXJ5IGNoYW5nZWQgc2l6ZSBkdXJpbmcgaXRlcmF0aW9uIik7CisgICAgICAgIGRpLT5kaV91c2VkID0gLTE7IC8qIE1ha2UgdGhpcyBzdGF0ZSBzdGlja3kgKi8KKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorCisgICAgaSA9IGRpLT5kaV9wb3M7CisgICAgaWYgKGkgPCAwKQorICAgICAgICBnb3RvIGZhaWw7CisgICAgZXAgPSBkLT5tYV90YWJsZTsKKyAgICBtYXNrID0gZC0+bWFfbWFzazsKKyAgICB3aGlsZSAoaSA8PSBtYXNrICYmIGVwW2ldLm1lX3ZhbHVlID09IE5VTEwpCisgICAgICAgIGkrKzsKKyAgICBkaS0+ZGlfcG9zID0gaSsxOworICAgIGlmIChpID4gbWFzaykKKyAgICAgICAgZ290byBmYWlsOworICAgIGRpLT5sZW4tLTsKKyAgICBrZXkgPSBlcFtpXS5tZV9rZXk7CisgICAgUHlfSU5DUkVGKGtleSk7CisgICAgcmV0dXJuIGtleTsKKworZmFpbDoKKyAgICBQeV9ERUNSRUYoZCk7CisgICAgZGktPmRpX2RpY3QgPSBOVUxMOworICAgIHJldHVybiBOVUxMOworfQorCitQeVR5cGVPYmplY3QgUHlEaWN0SXRlcktleV9UeXBlID0geworICAgIFB5VmFyT2JqZWN0X0hFQURfSU5JVCgmUHlUeXBlX1R5cGUsIDApCisgICAgImRpY3Rpb25hcnkta2V5aXRlcmF0b3IiLCAgICAgICAgICAgICAgICAgICAvKiB0cF9uYW1lICovCisgICAgc2l6ZW9mKGRpY3RpdGVyb2JqZWN0KSwgICAgICAgICAgICAgICAgICAgICAvKiB0cF9iYXNpY3NpemUgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2l0ZW1zaXplICovCisgICAgLyogbWV0aG9kcyAqLworICAgIChkZXN0cnVjdG9yKWRpY3RpdGVyX2RlYWxsb2MsICAgICAgICAgICAgICAgLyogdHBfZGVhbGxvYyAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfcHJpbnQgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2dldGF0dHIgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3NldGF0dHIgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2NvbXBhcmUgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3JlcHIgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2FzX251bWJlciAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfYXNfc2VxdWVuY2UgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2FzX21hcHBpbmcgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2hhc2ggKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2NhbGwgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3N0ciAqLworICAgIFB5T2JqZWN0X0dlbmVyaWNHZXRBdHRyLCAgICAgICAgICAgICAgICAgICAgLyogdHBfZ2V0YXR0cm8gKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3NldGF0dHJvICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9hc19idWZmZXIgKi8KKyAgICBQeV9UUEZMQUdTX0RFRkFVTFQgfCBQeV9UUEZMQUdTX0hBVkVfR0MsLyogdHBfZmxhZ3MgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2RvYyAqLworICAgICh0cmF2ZXJzZXByb2MpZGljdGl0ZXJfdHJhdmVyc2UsICAgICAgICAgICAgLyogdHBfdHJhdmVyc2UgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2NsZWFyICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9yaWNoY29tcGFyZSAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfd2Vha2xpc3RvZmZzZXQgKi8KKyAgICBQeU9iamVjdF9TZWxmSXRlciwgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2l0ZXIgKi8KKyAgICAoaXRlcm5leHRmdW5jKWRpY3RpdGVyX2l0ZXJuZXh0a2V5LCAgICAgICAgIC8qIHRwX2l0ZXJuZXh0ICovCisgICAgZGljdGl0ZXJfbWV0aG9kcywgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9tZXRob2RzICovCisgICAgMCwKK307CisKK3N0YXRpYyBQeU9iamVjdCAqZGljdGl0ZXJfaXRlcm5leHR2YWx1ZShkaWN0aXRlcm9iamVjdCAqZGkpCit7CisgICAgUHlPYmplY3QgKnZhbHVlOworICAgIHJlZ2lzdGVyIFB5X3NzaXplX3QgaSwgbWFzazsKKyAgICByZWdpc3RlciBQeURpY3RFbnRyeSAqZXA7CisgICAgUHlEaWN0T2JqZWN0ICpkID0gZGktPmRpX2RpY3Q7CisKKyAgICBpZiAoZCA9PSBOVUxMKQorICAgICAgICByZXR1cm4gTlVMTDsKKyAgICBhc3NlcnQgKFB5RGljdF9DaGVjayhkKSk7CisKKyAgICBpZiAoZGktPmRpX3VzZWQgIT0gZC0+bWFfdXNlZCkgeworICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfUnVudGltZUVycm9yLAorICAgICAgICAgICAgICAgICAgICAgICAgImRpY3Rpb25hcnkgY2hhbmdlZCBzaXplIGR1cmluZyBpdGVyYXRpb24iKTsKKyAgICAgICAgZGktPmRpX3VzZWQgPSAtMTsgLyogTWFrZSB0aGlzIHN0YXRlIHN0aWNreSAqLworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisKKyAgICBpID0gZGktPmRpX3BvczsKKyAgICBtYXNrID0gZC0+bWFfbWFzazsKKyAgICBpZiAoaSA8IDAgfHwgaSA+IG1hc2spCisgICAgICAgIGdvdG8gZmFpbDsKKyAgICBlcCA9IGQtPm1hX3RhYmxlOworICAgIHdoaWxlICgodmFsdWU9ZXBbaV0ubWVfdmFsdWUpID09IE5VTEwpIHsKKyAgICAgICAgaSsrOworICAgICAgICBpZiAoaSA+IG1hc2spCisgICAgICAgICAgICBnb3RvIGZhaWw7CisgICAgfQorICAgIGRpLT5kaV9wb3MgPSBpKzE7CisgICAgZGktPmxlbi0tOworICAgIFB5X0lOQ1JFRih2YWx1ZSk7CisgICAgcmV0dXJuIHZhbHVlOworCitmYWlsOgorICAgIFB5X0RFQ1JFRihkKTsKKyAgICBkaS0+ZGlfZGljdCA9IE5VTEw7CisgICAgcmV0dXJuIE5VTEw7Cit9CisKK1B5VHlwZU9iamVjdCBQeURpY3RJdGVyVmFsdWVfVHlwZSA9IHsKKyAgICBQeVZhck9iamVjdF9IRUFEX0lOSVQoJlB5VHlwZV9UeXBlLCAwKQorICAgICJkaWN0aW9uYXJ5LXZhbHVlaXRlcmF0b3IiLCAgICAgICAgICAgICAgICAgLyogdHBfbmFtZSAqLworICAgIHNpemVvZihkaWN0aXRlcm9iamVjdCksICAgICAgICAgICAgICAgICAgICAgLyogdHBfYmFzaWNzaXplICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9pdGVtc2l6ZSAqLworICAgIC8qIG1ldGhvZHMgKi8KKyAgICAoZGVzdHJ1Y3RvcilkaWN0aXRlcl9kZWFsbG9jLCAgICAgICAgICAgICAgIC8qIHRwX2RlYWxsb2MgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3ByaW50ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9nZXRhdHRyICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9zZXRhdHRyICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9jb21wYXJlICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9yZXByICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9hc19udW1iZXIgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2FzX3NlcXVlbmNlICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9hc19tYXBwaW5nICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9oYXNoICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9jYWxsICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9zdHIgKi8KKyAgICBQeU9iamVjdF9HZW5lcmljR2V0QXR0ciwgICAgICAgICAgICAgICAgICAgIC8qIHRwX2dldGF0dHJvICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9zZXRhdHRybyAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfYXNfYnVmZmVyICovCisgICAgUHlfVFBGTEFHU19ERUZBVUxUIHwgUHlfVFBGTEFHU19IQVZFX0dDLC8qIHRwX2ZsYWdzICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9kb2MgKi8KKyAgICAodHJhdmVyc2Vwcm9jKWRpY3RpdGVyX3RyYXZlcnNlLCAgICAgICAgICAgIC8qIHRwX3RyYXZlcnNlICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9jbGVhciAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfcmljaGNvbXBhcmUgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3dlYWtsaXN0b2Zmc2V0ICovCisgICAgUHlPYmplY3RfU2VsZkl0ZXIsICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9pdGVyICovCisgICAgKGl0ZXJuZXh0ZnVuYylkaWN0aXRlcl9pdGVybmV4dHZhbHVlLCAgICAgICAvKiB0cF9pdGVybmV4dCAqLworICAgIGRpY3RpdGVyX21ldGhvZHMsICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfbWV0aG9kcyAqLworICAgIDAsCit9OworCitzdGF0aWMgUHlPYmplY3QgKmRpY3RpdGVyX2l0ZXJuZXh0aXRlbShkaWN0aXRlcm9iamVjdCAqZGkpCit7CisgICAgUHlPYmplY3QgKmtleSwgKnZhbHVlLCAqcmVzdWx0ID0gZGktPmRpX3Jlc3VsdDsKKyAgICByZWdpc3RlciBQeV9zc2l6ZV90IGksIG1hc2s7CisgICAgcmVnaXN0ZXIgUHlEaWN0RW50cnkgKmVwOworICAgIFB5RGljdE9iamVjdCAqZCA9IGRpLT5kaV9kaWN0OworCisgICAgaWYgKGQgPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgYXNzZXJ0IChQeURpY3RfQ2hlY2soZCkpOworCisgICAgaWYgKGRpLT5kaV91c2VkICE9IGQtPm1hX3VzZWQpIHsKKyAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1J1bnRpbWVFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICJkaWN0aW9uYXJ5IGNoYW5nZWQgc2l6ZSBkdXJpbmcgaXRlcmF0aW9uIik7CisgICAgICAgIGRpLT5kaV91c2VkID0gLTE7IC8qIE1ha2UgdGhpcyBzdGF0ZSBzdGlja3kgKi8KKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorCisgICAgaSA9IGRpLT5kaV9wb3M7CisgICAgaWYgKGkgPCAwKQorICAgICAgICBnb3RvIGZhaWw7CisgICAgZXAgPSBkLT5tYV90YWJsZTsKKyAgICBtYXNrID0gZC0+bWFfbWFzazsKKyAgICB3aGlsZSAoaSA8PSBtYXNrICYmIGVwW2ldLm1lX3ZhbHVlID09IE5VTEwpCisgICAgICAgIGkrKzsKKyAgICBkaS0+ZGlfcG9zID0gaSsxOworICAgIGlmIChpID4gbWFzaykKKyAgICAgICAgZ290byBmYWlsOworCisgICAgaWYgKHJlc3VsdC0+b2JfcmVmY250ID09IDEpIHsKKyAgICAgICAgUHlfSU5DUkVGKHJlc3VsdCk7CisgICAgICAgIFB5X0RFQ1JFRihQeVR1cGxlX0dFVF9JVEVNKHJlc3VsdCwgMCkpOworICAgICAgICBQeV9ERUNSRUYoUHlUdXBsZV9HRVRfSVRFTShyZXN1bHQsIDEpKTsKKyAgICB9IGVsc2UgeworICAgICAgICByZXN1bHQgPSBQeVR1cGxlX05ldygyKTsKKyAgICAgICAgaWYgKHJlc3VsdCA9PSBOVUxMKQorICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIGRpLT5sZW4tLTsKKyAgICBrZXkgPSBlcFtpXS5tZV9rZXk7CisgICAgdmFsdWUgPSBlcFtpXS5tZV92YWx1ZTsKKyAgICBQeV9JTkNSRUYoa2V5KTsKKyAgICBQeV9JTkNSRUYodmFsdWUpOworICAgIFB5VHVwbGVfU0VUX0lURU0ocmVzdWx0LCAwLCBrZXkpOworICAgIFB5VHVwbGVfU0VUX0lURU0ocmVzdWx0LCAxLCB2YWx1ZSk7CisgICAgcmV0dXJuIHJlc3VsdDsKKworZmFpbDoKKyAgICBQeV9ERUNSRUYoZCk7CisgICAgZGktPmRpX2RpY3QgPSBOVUxMOworICAgIHJldHVybiBOVUxMOworfQorCitQeVR5cGVPYmplY3QgUHlEaWN0SXRlckl0ZW1fVHlwZSA9IHsKKyAgICBQeVZhck9iamVjdF9IRUFEX0lOSVQoJlB5VHlwZV9UeXBlLCAwKQorICAgICJkaWN0aW9uYXJ5LWl0ZW1pdGVyYXRvciIsICAgICAgICAgICAgICAgICAgLyogdHBfbmFtZSAqLworICAgIHNpemVvZihkaWN0aXRlcm9iamVjdCksICAgICAgICAgICAgICAgICAgICAgLyogdHBfYmFzaWNzaXplICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9pdGVtc2l6ZSAqLworICAgIC8qIG1ldGhvZHMgKi8KKyAgICAoZGVzdHJ1Y3RvcilkaWN0aXRlcl9kZWFsbG9jLCAgICAgICAgICAgICAgIC8qIHRwX2RlYWxsb2MgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3ByaW50ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9nZXRhdHRyICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9zZXRhdHRyICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9jb21wYXJlICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9yZXByICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9hc19udW1iZXIgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2FzX3NlcXVlbmNlICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9hc19tYXBwaW5nICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9oYXNoICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9jYWxsICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9zdHIgKi8KKyAgICBQeU9iamVjdF9HZW5lcmljR2V0QXR0ciwgICAgICAgICAgICAgICAgICAgIC8qIHRwX2dldGF0dHJvICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9zZXRhdHRybyAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfYXNfYnVmZmVyICovCisgICAgUHlfVFBGTEFHU19ERUZBVUxUIHwgUHlfVFBGTEFHU19IQVZFX0dDLC8qIHRwX2ZsYWdzICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9kb2MgKi8KKyAgICAodHJhdmVyc2Vwcm9jKWRpY3RpdGVyX3RyYXZlcnNlLCAgICAgICAgICAgIC8qIHRwX3RyYXZlcnNlICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9jbGVhciAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfcmljaGNvbXBhcmUgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3dlYWtsaXN0b2Zmc2V0ICovCisgICAgUHlPYmplY3RfU2VsZkl0ZXIsICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9pdGVyICovCisgICAgKGl0ZXJuZXh0ZnVuYylkaWN0aXRlcl9pdGVybmV4dGl0ZW0sICAgICAgICAvKiB0cF9pdGVybmV4dCAqLworICAgIGRpY3RpdGVyX21ldGhvZHMsICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfbWV0aG9kcyAqLworICAgIDAsCit9OworCisvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCisvKiBWaWV3IG9iamVjdHMgZm9yIGtleXMoKSwgaXRlbXMoKSwgdmFsdWVzKCkuICovCisvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCisKKy8qIFRoZSBpbnN0YW5jZSBsYXktb3V0IGlzIHRoZSBzYW1lIGZvciBhbGwgdGhyZWU7IGJ1dCB0aGUgdHlwZSBkaWZmZXJzLiAqLworCit0eXBlZGVmIHN0cnVjdCB7CisgICAgUHlPYmplY3RfSEVBRAorICAgIFB5RGljdE9iamVjdCAqZHZfZGljdDsKK30gZGljdHZpZXdvYmplY3Q7CisKKworc3RhdGljIHZvaWQKK2RpY3R2aWV3X2RlYWxsb2MoZGljdHZpZXdvYmplY3QgKmR2KQoreworICAgIFB5X1hERUNSRUYoZHYtPmR2X2RpY3QpOworICAgIFB5T2JqZWN0X0dDX0RlbChkdik7Cit9CisKK3N0YXRpYyBpbnQKK2RpY3R2aWV3X3RyYXZlcnNlKGRpY3R2aWV3b2JqZWN0ICpkdiwgdmlzaXRwcm9jIHZpc2l0LCB2b2lkICphcmcpCit7CisgICAgUHlfVklTSVQoZHYtPmR2X2RpY3QpOworICAgIHJldHVybiAwOworfQorCitzdGF0aWMgUHlfc3NpemVfdAorZGljdHZpZXdfbGVuKGRpY3R2aWV3b2JqZWN0ICpkdikKK3sKKyAgICBQeV9zc2l6ZV90IGxlbiA9IDA7CisgICAgaWYgKGR2LT5kdl9kaWN0ICE9IE5VTEwpCisgICAgICAgIGxlbiA9IGR2LT5kdl9kaWN0LT5tYV91c2VkOworICAgIHJldHVybiBsZW47Cit9CisKK3N0YXRpYyBQeU9iamVjdCAqCitkaWN0dmlld19uZXcoUHlPYmplY3QgKmRpY3QsIFB5VHlwZU9iamVjdCAqdHlwZSkKK3sKKyAgICBkaWN0dmlld29iamVjdCAqZHY7CisgICAgaWYgKGRpY3QgPT0gTlVMTCkgeworICAgICAgICBQeUVycl9CYWRJbnRlcm5hbENhbGwoKTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIGlmICghUHlEaWN0X0NoZWNrKGRpY3QpKSB7CisgICAgICAgIC8qIFhYWCBHZXQgcmlkIG9mIHRoaXMgcmVzdHJpY3Rpb24gbGF0ZXIgKi8KKyAgICAgICAgUHlFcnJfRm9ybWF0KFB5RXhjX1R5cGVFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICIlcygpIHJlcXVpcmVzIGEgZGljdCBhcmd1bWVudCwgbm90ICclcyciLAorICAgICAgICAgICAgICAgICAgICAgdHlwZS0+dHBfbmFtZSwgZGljdC0+b2JfdHlwZS0+dHBfbmFtZSk7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICBkdiA9IFB5T2JqZWN0X0dDX05ldyhkaWN0dmlld29iamVjdCwgdHlwZSk7CisgICAgaWYgKGR2ID09IE5VTEwpCisgICAgICAgIHJldHVybiBOVUxMOworICAgIFB5X0lOQ1JFRihkaWN0KTsKKyAgICBkdi0+ZHZfZGljdCA9IChQeURpY3RPYmplY3QgKilkaWN0OworICAgIF9QeU9iamVjdF9HQ19UUkFDSyhkdik7CisgICAgcmV0dXJuIChQeU9iamVjdCAqKWR2OworfQorCisvKiBUT0RPKGd1aWRvKTogVGhlIHZpZXdzIG9iamVjdHMgYXJlIG5vdCBjb21wbGV0ZToKKworICogc3VwcG9ydCBtb3JlIHNldCBvcGVyYXRpb25zCisgKiBzdXBwb3J0IGFyYml0cmFyeSBtYXBwaW5ncz8KKyAgIC0gZWl0aGVyIHRoZXNlIHNob3VsZCBiZSBzdGF0aWMgb3IgZXhwb3J0ZWQgaW4gZGljdG9iamVjdC5oCisgICAtIGlmIHB1YmxpYyB0aGVuIHRoZXkgc2hvdWxkIHByb2JhYmx5IGJlIGluIGJ1aWx0aW5zCisqLworCisvKiBSZXR1cm4gMSBpZiBzZWxmIGlzIGEgc3Vic2V0IG9mIG90aGVyLCBpdGVyYXRpbmcgb3ZlciBzZWxmOworICAgMCBpZiBub3Q7IC0xIGlmIGFuIGVycm9yIG9jY3VycmVkLiAqLworc3RhdGljIGludAorYWxsX2NvbnRhaW5lZF9pbihQeU9iamVjdCAqc2VsZiwgUHlPYmplY3QgKm90aGVyKQoreworICAgIFB5T2JqZWN0ICppdGVyID0gUHlPYmplY3RfR2V0SXRlcihzZWxmKTsKKyAgICBpbnQgb2sgPSAxOworCisgICAgaWYgKGl0ZXIgPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIC0xOworICAgIGZvciAoOzspIHsKKyAgICAgICAgUHlPYmplY3QgKm5leHQgPSBQeUl0ZXJfTmV4dChpdGVyKTsKKyAgICAgICAgaWYgKG5leHQgPT0gTlVMTCkgeworICAgICAgICAgICAgaWYgKFB5RXJyX09jY3VycmVkKCkpCisgICAgICAgICAgICAgICAgb2sgPSAtMTsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisgICAgICAgIG9rID0gUHlTZXF1ZW5jZV9Db250YWlucyhvdGhlciwgbmV4dCk7CisgICAgICAgIFB5X0RFQ1JFRihuZXh0KTsKKyAgICAgICAgaWYgKG9rIDw9IDApCisgICAgICAgICAgICBicmVhazsKKyAgICB9CisgICAgUHlfREVDUkVGKGl0ZXIpOworICAgIHJldHVybiBvazsKK30KKworc3RhdGljIFB5T2JqZWN0ICoKK2RpY3R2aWV3X3JpY2hjb21wYXJlKFB5T2JqZWN0ICpzZWxmLCBQeU9iamVjdCAqb3RoZXIsIGludCBvcCkKK3sKKyAgICBQeV9zc2l6ZV90IGxlbl9zZWxmLCBsZW5fb3RoZXI7CisgICAgaW50IG9rOworICAgIFB5T2JqZWN0ICpyZXN1bHQ7CisKKyAgICBhc3NlcnQoc2VsZiAhPSBOVUxMKTsKKyAgICBhc3NlcnQoUHlEaWN0Vmlld1NldF9DaGVjayhzZWxmKSk7CisgICAgYXNzZXJ0KG90aGVyICE9IE5VTEwpOworCisgICAgaWYgKCFQeUFueVNldF9DaGVjayhvdGhlcikgJiYgIVB5RGljdFZpZXdTZXRfQ2hlY2sob3RoZXIpKSB7CisgICAgICAgIFB5X0lOQ1JFRihQeV9Ob3RJbXBsZW1lbnRlZCk7CisgICAgICAgIHJldHVybiBQeV9Ob3RJbXBsZW1lbnRlZDsKKyAgICB9CisKKyAgICBsZW5fc2VsZiA9IFB5T2JqZWN0X1NpemUoc2VsZik7CisgICAgaWYgKGxlbl9zZWxmIDwgMCkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgbGVuX290aGVyID0gUHlPYmplY3RfU2l6ZShvdGhlcik7CisgICAgaWYgKGxlbl9vdGhlciA8IDApCisgICAgICAgIHJldHVybiBOVUxMOworCisgICAgb2sgPSAwOworICAgIHN3aXRjaChvcCkgeworCisgICAgY2FzZSBQeV9ORToKKyAgICBjYXNlIFB5X0VROgorICAgICAgICBpZiAobGVuX3NlbGYgPT0gbGVuX290aGVyKQorICAgICAgICAgICAgb2sgPSBhbGxfY29udGFpbmVkX2luKHNlbGYsIG90aGVyKTsKKyAgICAgICAgaWYgKG9wID09IFB5X05FICYmIG9rID49IDApCisgICAgICAgICAgICBvayA9ICFvazsKKyAgICAgICAgYnJlYWs7CisKKyAgICBjYXNlIFB5X0xUOgorICAgICAgICBpZiAobGVuX3NlbGYgPCBsZW5fb3RoZXIpCisgICAgICAgICAgICBvayA9IGFsbF9jb250YWluZWRfaW4oc2VsZiwgb3RoZXIpOworICAgICAgICBicmVhazsKKworICAgICAgY2FzZSBQeV9MRToKKyAgICAgICAgICBpZiAobGVuX3NlbGYgPD0gbGVuX290aGVyKQorICAgICAgICAgICAgICBvayA9IGFsbF9jb250YWluZWRfaW4oc2VsZiwgb3RoZXIpOworICAgICAgICAgIGJyZWFrOworCisgICAgY2FzZSBQeV9HVDoKKyAgICAgICAgaWYgKGxlbl9zZWxmID4gbGVuX290aGVyKQorICAgICAgICAgICAgb2sgPSBhbGxfY29udGFpbmVkX2luKG90aGVyLCBzZWxmKTsKKyAgICAgICAgYnJlYWs7CisKKyAgICBjYXNlIFB5X0dFOgorICAgICAgICBpZiAobGVuX3NlbGYgPj0gbGVuX290aGVyKQorICAgICAgICAgICAgb2sgPSBhbGxfY29udGFpbmVkX2luKG90aGVyLCBzZWxmKTsKKyAgICAgICAgYnJlYWs7CisKKyAgICB9CisgICAgaWYgKG9rIDwgMCkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgcmVzdWx0ID0gb2sgPyBQeV9UcnVlIDogUHlfRmFsc2U7CisgICAgUHlfSU5DUkVGKHJlc3VsdCk7CisgICAgcmV0dXJuIHJlc3VsdDsKK30KKworc3RhdGljIFB5T2JqZWN0ICoKK2RpY3R2aWV3X3JlcHIoZGljdHZpZXdvYmplY3QgKmR2KQoreworICAgIFB5T2JqZWN0ICpzZXE7CisgICAgUHlPYmplY3QgKnNlcV9zdHI7CisgICAgUHlPYmplY3QgKnJlc3VsdDsKKworICAgIHNlcSA9IFB5U2VxdWVuY2VfTGlzdCgoUHlPYmplY3QgKilkdik7CisgICAgaWYgKHNlcSA9PSBOVUxMKQorICAgICAgICByZXR1cm4gTlVMTDsKKworICAgIHNlcV9zdHIgPSBQeU9iamVjdF9SZXByKHNlcSk7CisgICAgcmVzdWx0ID0gUHlTdHJpbmdfRnJvbUZvcm1hdCgiJXMoJXMpIiwgUHlfVFlQRShkdiktPnRwX25hbWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQeVN0cmluZ19BU19TVFJJTkcoc2VxX3N0cikpOworICAgIFB5X0RFQ1JFRihzZXFfc3RyKTsKKyAgICBQeV9ERUNSRUYoc2VxKTsKKyAgICByZXR1cm4gcmVzdWx0OworfQorCisvKioqIGRpY3Rfa2V5cyAqKiovCisKK3N0YXRpYyBQeU9iamVjdCAqCitkaWN0a2V5c19pdGVyKGRpY3R2aWV3b2JqZWN0ICpkdikKK3sKKyAgICBpZiAoZHYtPmR2X2RpY3QgPT0gTlVMTCkgeworICAgICAgICBQeV9SRVRVUk5fTk9ORTsKKyAgICB9CisgICAgcmV0dXJuIGRpY3RpdGVyX25ldyhkdi0+ZHZfZGljdCwgJlB5RGljdEl0ZXJLZXlfVHlwZSk7Cit9CisKK3N0YXRpYyBpbnQKK2RpY3RrZXlzX2NvbnRhaW5zKGRpY3R2aWV3b2JqZWN0ICpkdiwgUHlPYmplY3QgKm9iaikKK3sKKyAgICBpZiAoZHYtPmR2X2RpY3QgPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIDA7CisgICAgcmV0dXJuIFB5RGljdF9Db250YWlucygoUHlPYmplY3QgKilkdi0+ZHZfZGljdCwgb2JqKTsKK30KKworc3RhdGljIFB5U2VxdWVuY2VNZXRob2RzIGRpY3RrZXlzX2FzX3NlcXVlbmNlID0geworICAgIChsZW5mdW5jKWRpY3R2aWV3X2xlbiwgICAgICAgICAgICAgIC8qIHNxX2xlbmd0aCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHNxX2NvbmNhdCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHNxX3JlcGVhdCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHNxX2l0ZW0gKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBzcV9zbGljZSAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHNxX2Fzc19pdGVtICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogc3FfYXNzX3NsaWNlICovCisgICAgKG9iam9ianByb2MpZGljdGtleXNfY29udGFpbnMsICAgICAgLyogc3FfY29udGFpbnMgKi8KK307CisKK3N0YXRpYyBQeU9iamVjdCoKK2RpY3R2aWV3c19zdWIoUHlPYmplY3QqIHNlbGYsIFB5T2JqZWN0ICpvdGhlcikKK3sKKyAgICBQeU9iamVjdCAqcmVzdWx0ID0gUHlTZXRfTmV3KHNlbGYpOworICAgIFB5T2JqZWN0ICp0bXA7CisgICAgaWYgKHJlc3VsdCA9PSBOVUxMKQorICAgICAgICByZXR1cm4gTlVMTDsKKworICAgIHRtcCA9IFB5T2JqZWN0X0NhbGxNZXRob2QocmVzdWx0LCAiZGlmZmVyZW5jZV91cGRhdGUiLCAiTyIsIG90aGVyKTsKKyAgICBpZiAodG1wID09IE5VTEwpIHsKKyAgICAgICAgUHlfREVDUkVGKHJlc3VsdCk7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKworICAgIFB5X0RFQ1JFRih0bXApOworICAgIHJldHVybiByZXN1bHQ7Cit9CisKK3N0YXRpYyBQeU9iamVjdCoKK2RpY3R2aWV3c19hbmQoUHlPYmplY3QqIHNlbGYsIFB5T2JqZWN0ICpvdGhlcikKK3sKKyAgICBQeU9iamVjdCAqcmVzdWx0ID0gUHlTZXRfTmV3KHNlbGYpOworICAgIFB5T2JqZWN0ICp0bXA7CisgICAgaWYgKHJlc3VsdCA9PSBOVUxMKQorICAgICAgICByZXR1cm4gTlVMTDsKKworICAgIHRtcCA9IFB5T2JqZWN0X0NhbGxNZXRob2QocmVzdWx0LCAiaW50ZXJzZWN0aW9uX3VwZGF0ZSIsICJPIiwgb3RoZXIpOworICAgIGlmICh0bXAgPT0gTlVMTCkgeworICAgICAgICBQeV9ERUNSRUYocmVzdWx0KTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorCisgICAgUHlfREVDUkVGKHRtcCk7CisgICAgcmV0dXJuIHJlc3VsdDsKK30KKworc3RhdGljIFB5T2JqZWN0KgorZGljdHZpZXdzX29yKFB5T2JqZWN0KiBzZWxmLCBQeU9iamVjdCAqb3RoZXIpCit7CisgICAgUHlPYmplY3QgKnJlc3VsdCA9IFB5U2V0X05ldyhzZWxmKTsKKyAgICBQeU9iamVjdCAqdG1wOworICAgIGlmIChyZXN1bHQgPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisKKyAgICB0bXAgPSBQeU9iamVjdF9DYWxsTWV0aG9kKHJlc3VsdCwgInVwZGF0ZSIsICJPIiwgb3RoZXIpOworICAgIGlmICh0bXAgPT0gTlVMTCkgeworICAgICAgICBQeV9ERUNSRUYocmVzdWx0KTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorCisgICAgUHlfREVDUkVGKHRtcCk7CisgICAgcmV0dXJuIHJlc3VsdDsKK30KKworc3RhdGljIFB5T2JqZWN0KgorZGljdHZpZXdzX3hvcihQeU9iamVjdCogc2VsZiwgUHlPYmplY3QgKm90aGVyKQoreworICAgIFB5T2JqZWN0ICpyZXN1bHQgPSBQeVNldF9OZXcoc2VsZik7CisgICAgUHlPYmplY3QgKnRtcDsKKyAgICBpZiAocmVzdWx0ID09IE5VTEwpCisgICAgICAgIHJldHVybiBOVUxMOworCisgICAgdG1wID0gUHlPYmplY3RfQ2FsbE1ldGhvZChyZXN1bHQsICJzeW1tZXRyaWNfZGlmZmVyZW5jZV91cGRhdGUiLCAiTyIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvdGhlcik7CisgICAgaWYgKHRtcCA9PSBOVUxMKSB7CisgICAgICAgIFB5X0RFQ1JFRihyZXN1bHQpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisKKyAgICBQeV9ERUNSRUYodG1wKTsKKyAgICByZXR1cm4gcmVzdWx0OworfQorCitzdGF0aWMgUHlOdW1iZXJNZXRob2RzIGRpY3R2aWV3c19hc19udW1iZXIgPSB7CisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLypuYl9hZGQqLworICAgIChiaW5hcnlmdW5jKWRpY3R2aWV3c19zdWIsICAgICAgICAgIC8qbmJfc3VidHJhY3QqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qbmJfbXVsdGlwbHkqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qbmJfZGl2aWRlKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKm5iX3JlbWFpbmRlciovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLypuYl9kaXZtb2QqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qbmJfcG93ZXIqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qbmJfbmVnYXRpdmUqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qbmJfcG9zaXRpdmUqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qbmJfYWJzb2x1dGUqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qbmJfbm9uemVybyovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLypuYl9pbnZlcnQqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qbmJfbHNoaWZ0Ki8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKm5iX3JzaGlmdCovCisgICAgKGJpbmFyeWZ1bmMpZGljdHZpZXdzX2FuZCwgICAgICAgICAgLypuYl9hbmQqLworICAgIChiaW5hcnlmdW5jKWRpY3R2aWV3c194b3IsICAgICAgICAgIC8qbmJfeG9yKi8KKyAgICAoYmluYXJ5ZnVuYylkaWN0dmlld3Nfb3IsICAgICAgICAgICAvKm5iX29yKi8KK307CisKK3N0YXRpYyBQeU1ldGhvZERlZiBkaWN0a2V5c19tZXRob2RzW10gPSB7CisgICAge05VTEwsICAgICAgICAgICAgICBOVUxMfSAgICAgICAgICAgLyogc2VudGluZWwgKi8KK307CisKK1B5VHlwZU9iamVjdCBQeURpY3RLZXlzX1R5cGUgPSB7CisgICAgUHlWYXJPYmplY3RfSEVBRF9JTklUKCZQeVR5cGVfVHlwZSwgMCkKKyAgICAiZGljdF9rZXlzIiwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX25hbWUgKi8KKyAgICBzaXplb2YoZGljdHZpZXdvYmplY3QpLCAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2Jhc2ljc2l6ZSAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfaXRlbXNpemUgKi8KKyAgICAvKiBtZXRob2RzICovCisgICAgKGRlc3RydWN0b3IpZGljdHZpZXdfZGVhbGxvYywgICAgICAgICAgICAgICAvKiB0cF9kZWFsbG9jICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9wcmludCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZ2V0YXR0ciAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfc2V0YXR0ciAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfcmVzZXJ2ZWQgKi8KKyAgICAocmVwcmZ1bmMpZGljdHZpZXdfcmVwciwgICAgICAgICAgICAgICAgICAgIC8qIHRwX3JlcHIgKi8KKyAgICAmZGljdHZpZXdzX2FzX251bWJlciwgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2FzX251bWJlciAqLworICAgICZkaWN0a2V5c19hc19zZXF1ZW5jZSwgICAgICAgICAgICAgICAgICAgICAgLyogdHBfYXNfc2VxdWVuY2UgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2FzX21hcHBpbmcgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2hhc2ggKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2NhbGwgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3N0ciAqLworICAgIFB5T2JqZWN0X0dlbmVyaWNHZXRBdHRyLCAgICAgICAgICAgICAgICAgICAgLyogdHBfZ2V0YXR0cm8gKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3NldGF0dHJvICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9hc19idWZmZXIgKi8KKyAgICBQeV9UUEZMQUdTX0RFRkFVTFQgfCBQeV9UUEZMQUdTX0hBVkVfR0MgfAorICAgICAgICBQeV9UUEZMQUdTX0NIRUNLVFlQRVMsICAgICAgICAgICAgICAgICAgLyogdHBfZmxhZ3MgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2RvYyAqLworICAgICh0cmF2ZXJzZXByb2MpZGljdHZpZXdfdHJhdmVyc2UsICAgICAgICAgICAgLyogdHBfdHJhdmVyc2UgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2NsZWFyICovCisgICAgZGljdHZpZXdfcmljaGNvbXBhcmUsICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9yaWNoY29tcGFyZSAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfd2Vha2xpc3RvZmZzZXQgKi8KKyAgICAoZ2V0aXRlcmZ1bmMpZGljdGtleXNfaXRlciwgICAgICAgICAgICAgICAgIC8qIHRwX2l0ZXIgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2l0ZXJuZXh0ICovCisgICAgZGljdGtleXNfbWV0aG9kcywgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9tZXRob2RzICovCisgICAgMCwKK307CisKK3N0YXRpYyBQeU9iamVjdCAqCitkaWN0a2V5c19uZXcoUHlPYmplY3QgKmRpY3QpCit7CisgICAgcmV0dXJuIGRpY3R2aWV3X25ldyhkaWN0LCAmUHlEaWN0S2V5c19UeXBlKTsKK30KKworLyoqKiBkaWN0X2l0ZW1zICoqKi8KKworc3RhdGljIFB5T2JqZWN0ICoKK2RpY3RpdGVtc19pdGVyKGRpY3R2aWV3b2JqZWN0ICpkdikKK3sKKyAgICBpZiAoZHYtPmR2X2RpY3QgPT0gTlVMTCkgeworICAgICAgICBQeV9SRVRVUk5fTk9ORTsKKyAgICB9CisgICAgcmV0dXJuIGRpY3RpdGVyX25ldyhkdi0+ZHZfZGljdCwgJlB5RGljdEl0ZXJJdGVtX1R5cGUpOworfQorCitzdGF0aWMgaW50CitkaWN0aXRlbXNfY29udGFpbnMoZGljdHZpZXdvYmplY3QgKmR2LCBQeU9iamVjdCAqb2JqKQoreworICAgIFB5T2JqZWN0ICprZXksICp2YWx1ZSwgKmZvdW5kOworICAgIGlmIChkdi0+ZHZfZGljdCA9PSBOVUxMKQorICAgICAgICByZXR1cm4gMDsKKyAgICBpZiAoIVB5VHVwbGVfQ2hlY2sob2JqKSB8fCBQeVR1cGxlX0dFVF9TSVpFKG9iaikgIT0gMikKKyAgICAgICAgcmV0dXJuIDA7CisgICAga2V5ID0gUHlUdXBsZV9HRVRfSVRFTShvYmosIDApOworICAgIHZhbHVlID0gUHlUdXBsZV9HRVRfSVRFTShvYmosIDEpOworICAgIGZvdW5kID0gUHlEaWN0X0dldEl0ZW0oKFB5T2JqZWN0ICopZHYtPmR2X2RpY3QsIGtleSk7CisgICAgaWYgKGZvdW5kID09IE5VTEwpIHsKKyAgICAgICAgaWYgKFB5RXJyX09jY3VycmVkKCkpCisgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgIHJldHVybiAwOworICAgIH0KKyAgICByZXR1cm4gUHlPYmplY3RfUmljaENvbXBhcmVCb29sKHZhbHVlLCBmb3VuZCwgUHlfRVEpOworfQorCitzdGF0aWMgUHlTZXF1ZW5jZU1ldGhvZHMgZGljdGl0ZW1zX2FzX3NlcXVlbmNlID0geworICAgIChsZW5mdW5jKWRpY3R2aWV3X2xlbiwgICAgICAgICAgICAgIC8qIHNxX2xlbmd0aCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHNxX2NvbmNhdCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHNxX3JlcGVhdCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHNxX2l0ZW0gKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBzcV9zbGljZSAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHNxX2Fzc19pdGVtICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogc3FfYXNzX3NsaWNlICovCisgICAgKG9iam9ianByb2MpZGljdGl0ZW1zX2NvbnRhaW5zLCAgICAgLyogc3FfY29udGFpbnMgKi8KK307CisKK3N0YXRpYyBQeU1ldGhvZERlZiBkaWN0aXRlbXNfbWV0aG9kc1tdID0geworICAgIHtOVUxMLCAgICAgICAgICAgICAgTlVMTH0gICAgICAgICAgIC8qIHNlbnRpbmVsICovCit9OworCitQeVR5cGVPYmplY3QgUHlEaWN0SXRlbXNfVHlwZSA9IHsKKyAgICBQeVZhck9iamVjdF9IRUFEX0lOSVQoJlB5VHlwZV9UeXBlLCAwKQorICAgICJkaWN0X2l0ZW1zIiwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfbmFtZSAqLworICAgIHNpemVvZihkaWN0dmlld29iamVjdCksICAgICAgICAgICAgICAgICAgICAgLyogdHBfYmFzaWNzaXplICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9pdGVtc2l6ZSAqLworICAgIC8qIG1ldGhvZHMgKi8KKyAgICAoZGVzdHJ1Y3RvcilkaWN0dmlld19kZWFsbG9jLCAgICAgICAgICAgICAgIC8qIHRwX2RlYWxsb2MgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3ByaW50ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9nZXRhdHRyICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9zZXRhdHRyICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9yZXNlcnZlZCAqLworICAgIChyZXByZnVuYylkaWN0dmlld19yZXByLCAgICAgICAgICAgICAgICAgICAgLyogdHBfcmVwciAqLworICAgICZkaWN0dmlld3NfYXNfbnVtYmVyLCAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfYXNfbnVtYmVyICovCisgICAgJmRpY3RpdGVtc19hc19zZXF1ZW5jZSwgICAgICAgICAgICAgICAgICAgICAvKiB0cF9hc19zZXF1ZW5jZSAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfYXNfbWFwcGluZyAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfaGFzaCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfY2FsbCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfc3RyICovCisgICAgUHlPYmplY3RfR2VuZXJpY0dldEF0dHIsICAgICAgICAgICAgICAgICAgICAvKiB0cF9nZXRhdHRybyAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfc2V0YXR0cm8gKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2FzX2J1ZmZlciAqLworICAgIFB5X1RQRkxBR1NfREVGQVVMVCB8IFB5X1RQRkxBR1NfSEFWRV9HQyB8CisgICAgICAgIFB5X1RQRkxBR1NfQ0hFQ0tUWVBFUywgICAgICAgICAgICAgICAgICAvKiB0cF9mbGFncyAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZG9jICovCisgICAgKHRyYXZlcnNlcHJvYylkaWN0dmlld190cmF2ZXJzZSwgICAgICAgICAgICAvKiB0cF90cmF2ZXJzZSAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfY2xlYXIgKi8KKyAgICBkaWN0dmlld19yaWNoY29tcGFyZSwgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3JpY2hjb21wYXJlICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF93ZWFrbGlzdG9mZnNldCAqLworICAgIChnZXRpdGVyZnVuYylkaWN0aXRlbXNfaXRlciwgICAgICAgICAgICAgICAgLyogdHBfaXRlciAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfaXRlcm5leHQgKi8KKyAgICBkaWN0aXRlbXNfbWV0aG9kcywgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX21ldGhvZHMgKi8KKyAgICAwLAorfTsKKworc3RhdGljIFB5T2JqZWN0ICoKK2RpY3RpdGVtc19uZXcoUHlPYmplY3QgKmRpY3QpCit7CisgICAgcmV0dXJuIGRpY3R2aWV3X25ldyhkaWN0LCAmUHlEaWN0SXRlbXNfVHlwZSk7Cit9CisKKy8qKiogZGljdF92YWx1ZXMgKioqLworCitzdGF0aWMgUHlPYmplY3QgKgorZGljdHZhbHVlc19pdGVyKGRpY3R2aWV3b2JqZWN0ICpkdikKK3sKKyAgICBpZiAoZHYtPmR2X2RpY3QgPT0gTlVMTCkgeworICAgICAgICBQeV9SRVRVUk5fTk9ORTsKKyAgICB9CisgICAgcmV0dXJuIGRpY3RpdGVyX25ldyhkdi0+ZHZfZGljdCwgJlB5RGljdEl0ZXJWYWx1ZV9UeXBlKTsKK30KKworc3RhdGljIFB5U2VxdWVuY2VNZXRob2RzIGRpY3R2YWx1ZXNfYXNfc2VxdWVuY2UgPSB7CisgICAgKGxlbmZ1bmMpZGljdHZpZXdfbGVuLCAgICAgICAgICAgICAgLyogc3FfbGVuZ3RoICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogc3FfY29uY2F0ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogc3FfcmVwZWF0ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogc3FfaXRlbSAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHNxX3NsaWNlICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogc3FfYXNzX2l0ZW0gKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBzcV9hc3Nfc2xpY2UgKi8KKyAgICAob2Jqb2JqcHJvYykwLCAgICAgICAgICAgICAgICAgICAgICAvKiBzcV9jb250YWlucyAqLworfTsKKworc3RhdGljIFB5TWV0aG9kRGVmIGRpY3R2YWx1ZXNfbWV0aG9kc1tdID0geworICAgIHtOVUxMLCAgICAgICAgICAgICAgTlVMTH0gICAgICAgICAgIC8qIHNlbnRpbmVsICovCit9OworCitQeVR5cGVPYmplY3QgUHlEaWN0VmFsdWVzX1R5cGUgPSB7CisgICAgUHlWYXJPYmplY3RfSEVBRF9JTklUKCZQeVR5cGVfVHlwZSwgMCkKKyAgICAiZGljdF92YWx1ZXMiLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX25hbWUgKi8KKyAgICBzaXplb2YoZGljdHZpZXdvYmplY3QpLCAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2Jhc2ljc2l6ZSAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfaXRlbXNpemUgKi8KKyAgICAvKiBtZXRob2RzICovCisgICAgKGRlc3RydWN0b3IpZGljdHZpZXdfZGVhbGxvYywgICAgICAgICAgICAgICAvKiB0cF9kZWFsbG9jICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9wcmludCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZ2V0YXR0ciAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfc2V0YXR0ciAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfcmVzZXJ2ZWQgKi8KKyAgICAocmVwcmZ1bmMpZGljdHZpZXdfcmVwciwgICAgICAgICAgICAgICAgICAgIC8qIHRwX3JlcHIgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2FzX251bWJlciAqLworICAgICZkaWN0dmFsdWVzX2FzX3NlcXVlbmNlLCAgICAgICAgICAgICAgICAgICAgLyogdHBfYXNfc2VxdWVuY2UgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2FzX21hcHBpbmcgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2hhc2ggKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2NhbGwgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3N0ciAqLworICAgIFB5T2JqZWN0X0dlbmVyaWNHZXRBdHRyLCAgICAgICAgICAgICAgICAgICAgLyogdHBfZ2V0YXR0cm8gKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3NldGF0dHJvICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9hc19idWZmZXIgKi8KKyAgICBQeV9UUEZMQUdTX0RFRkFVTFQgfCBQeV9UUEZMQUdTX0hBVkVfR0MsLyogdHBfZmxhZ3MgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2RvYyAqLworICAgICh0cmF2ZXJzZXByb2MpZGljdHZpZXdfdHJhdmVyc2UsICAgICAgICAgICAgLyogdHBfdHJhdmVyc2UgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2NsZWFyICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9yaWNoY29tcGFyZSAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfd2Vha2xpc3RvZmZzZXQgKi8KKyAgICAoZ2V0aXRlcmZ1bmMpZGljdHZhbHVlc19pdGVyLCAgICAgICAgICAgICAgIC8qIHRwX2l0ZXIgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2l0ZXJuZXh0ICovCisgICAgZGljdHZhbHVlc19tZXRob2RzLCAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9tZXRob2RzICovCisgICAgMCwKK307CisKK3N0YXRpYyBQeU9iamVjdCAqCitkaWN0dmFsdWVzX25ldyhQeU9iamVjdCAqZGljdCkKK3sKKyAgICByZXR1cm4gZGljdHZpZXdfbmV3KGRpY3QsICZQeURpY3RWYWx1ZXNfVHlwZSk7Cit9CmRpZmYgLS1naXQgYS9QeXRob24tMi43LjUvT2JqZWN0cy9lbnVtb2JqZWN0LmMgYi9QeXRob24tMi43LjUvT2JqZWN0cy9lbnVtb2JqZWN0LmMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMWVmMzgxZgotLS0gL2Rldi9udWxsCisrKyBiL1B5dGhvbi0yLjcuNS9PYmplY3RzL2VudW1vYmplY3QuYwpAQCAtMCwwICsxLDM4MSBAQAorLyogZW51bWVyYXRlIG9iamVjdCAqLworCisjaW5jbHVkZSAiUHl0aG9uLmgiCisKK3R5cGVkZWYgc3RydWN0IHsKKyAgICBQeU9iamVjdF9IRUFECisgICAgUHlfc3NpemVfdCBlbl9pbmRleDsgICAgICAgICAgIC8qIGN1cnJlbnQgaW5kZXggb2YgZW51bWVyYXRpb24gKi8KKyAgICBQeU9iamVjdCogZW5fc2l0OyAgICAgICAgICAvKiBzZWNvbmRhcnkgaXRlcmF0b3Igb2YgZW51bWVyYXRpb24gKi8KKyAgICBQeU9iamVjdCogZW5fcmVzdWx0OyAgICAgICAgICAgLyogcmVzdWx0IHR1cGxlICAqLworICAgIFB5T2JqZWN0KiBlbl9sb25naW5kZXg7ICAgICAgICAvKiBpbmRleCBmb3Igc2VxdWVuY2VzID49IFBZX1NTSVpFX1RfTUFYICovCit9IGVudW1vYmplY3Q7CisKK3N0YXRpYyBQeU9iamVjdCAqCitlbnVtX25ldyhQeVR5cGVPYmplY3QgKnR5cGUsIFB5T2JqZWN0ICphcmdzLCBQeU9iamVjdCAqa3dkcykKK3sKKyAgICBlbnVtb2JqZWN0ICplbjsKKyAgICBQeU9iamVjdCAqc2VxID0gTlVMTDsKKyAgICBQeU9iamVjdCAqc3RhcnQgPSBOVUxMOworICAgIHN0YXRpYyBjaGFyICprd2xpc3RbXSA9IHsic2VxdWVuY2UiLCAic3RhcnQiLCAwfTsKKworICAgIGlmICghUHlBcmdfUGFyc2VUdXBsZUFuZEtleXdvcmRzKGFyZ3MsIGt3ZHMsICJPfE86ZW51bWVyYXRlIiwga3dsaXN0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZzZXEsICZzdGFydCkpCisgICAgICAgIHJldHVybiBOVUxMOworCisgICAgZW4gPSAoZW51bW9iamVjdCAqKXR5cGUtPnRwX2FsbG9jKHR5cGUsIDApOworICAgIGlmIChlbiA9PSBOVUxMKQorICAgICAgICByZXR1cm4gTlVMTDsKKyAgICBpZiAoc3RhcnQgIT0gTlVMTCkgeworICAgICAgICBzdGFydCA9IFB5TnVtYmVyX0luZGV4KHN0YXJ0KTsKKyAgICAgICAgaWYgKHN0YXJ0ID09IE5VTEwpIHsKKyAgICAgICAgICAgIFB5X0RFQ1JFRihlbik7CisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnQoUHlJbnRfQ2hlY2soc3RhcnQpIHx8IFB5TG9uZ19DaGVjayhzdGFydCkpOworICAgICAgICBlbi0+ZW5faW5kZXggPSBQeUludF9Bc1NzaXplX3Qoc3RhcnQpOworICAgICAgICBpZiAoZW4tPmVuX2luZGV4ID09IC0xICYmIFB5RXJyX09jY3VycmVkKCkpIHsKKyAgICAgICAgICAgIFB5RXJyX0NsZWFyKCk7CisgICAgICAgICAgICBlbi0+ZW5faW5kZXggPSBQWV9TU0laRV9UX01BWDsKKyAgICAgICAgICAgIGVuLT5lbl9sb25naW5kZXggPSBzdGFydDsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIGVuLT5lbl9sb25naW5kZXggPSBOVUxMOworICAgICAgICAgICAgUHlfREVDUkVGKHN0YXJ0KTsKKyAgICAgICAgfQorICAgIH0gZWxzZSB7CisgICAgICAgIGVuLT5lbl9pbmRleCA9IDA7CisgICAgICAgIGVuLT5lbl9sb25naW5kZXggPSBOVUxMOworICAgIH0KKyAgICBlbi0+ZW5fc2l0ID0gUHlPYmplY3RfR2V0SXRlcihzZXEpOworICAgIGlmIChlbi0+ZW5fc2l0ID09IE5VTEwpIHsKKyAgICAgICAgUHlfREVDUkVGKGVuKTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIGVuLT5lbl9yZXN1bHQgPSBQeVR1cGxlX1BhY2soMiwgUHlfTm9uZSwgUHlfTm9uZSk7CisgICAgaWYgKGVuLT5lbl9yZXN1bHQgPT0gTlVMTCkgeworICAgICAgICBQeV9ERUNSRUYoZW4pOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgcmV0dXJuIChQeU9iamVjdCAqKWVuOworfQorCitzdGF0aWMgdm9pZAorZW51bV9kZWFsbG9jKGVudW1vYmplY3QgKmVuKQoreworICAgIFB5T2JqZWN0X0dDX1VuVHJhY2soZW4pOworICAgIFB5X1hERUNSRUYoZW4tPmVuX3NpdCk7CisgICAgUHlfWERFQ1JFRihlbi0+ZW5fcmVzdWx0KTsKKyAgICBQeV9YREVDUkVGKGVuLT5lbl9sb25naW5kZXgpOworICAgIFB5X1RZUEUoZW4pLT50cF9mcmVlKGVuKTsKK30KKworc3RhdGljIGludAorZW51bV90cmF2ZXJzZShlbnVtb2JqZWN0ICplbiwgdmlzaXRwcm9jIHZpc2l0LCB2b2lkICphcmcpCit7CisgICAgUHlfVklTSVQoZW4tPmVuX3NpdCk7CisgICAgUHlfVklTSVQoZW4tPmVuX3Jlc3VsdCk7CisgICAgUHlfVklTSVQoZW4tPmVuX2xvbmdpbmRleCk7CisgICAgcmV0dXJuIDA7Cit9CisKK3N0YXRpYyBQeU9iamVjdCAqCitlbnVtX25leHRfbG9uZyhlbnVtb2JqZWN0ICplbiwgUHlPYmplY3QqIG5leHRfaXRlbSkKK3sKKyAgICBzdGF0aWMgUHlPYmplY3QgKm9uZSA9IE5VTEw7CisgICAgUHlPYmplY3QgKnJlc3VsdCA9IGVuLT5lbl9yZXN1bHQ7CisgICAgUHlPYmplY3QgKm5leHRfaW5kZXg7CisgICAgUHlPYmplY3QgKnN0ZXBwZWRfdXA7CisKKyAgICBpZiAoZW4tPmVuX2xvbmdpbmRleCA9PSBOVUxMKSB7CisgICAgICAgIGVuLT5lbl9sb25naW5kZXggPSBQeUludF9Gcm9tU3NpemVfdChQWV9TU0laRV9UX01BWCk7CisgICAgICAgIGlmIChlbi0+ZW5fbG9uZ2luZGV4ID09IE5VTEwpCisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgaWYgKG9uZSA9PSBOVUxMKSB7CisgICAgICAgIG9uZSA9IFB5SW50X0Zyb21Mb25nKDEpOworICAgICAgICBpZiAob25lID09IE5VTEwpCisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgbmV4dF9pbmRleCA9IGVuLT5lbl9sb25naW5kZXg7CisgICAgYXNzZXJ0KG5leHRfaW5kZXggIT0gTlVMTCk7CisgICAgc3RlcHBlZF91cCA9IFB5TnVtYmVyX0FkZChuZXh0X2luZGV4LCBvbmUpOworICAgIGlmIChzdGVwcGVkX3VwID09IE5VTEwpCisgICAgICAgIHJldHVybiBOVUxMOworICAgIGVuLT5lbl9sb25naW5kZXggPSBzdGVwcGVkX3VwOworCisgICAgaWYgKHJlc3VsdC0+b2JfcmVmY250ID09IDEpIHsKKyAgICAgICAgUHlfSU5DUkVGKHJlc3VsdCk7CisgICAgICAgIFB5X0RFQ1JFRihQeVR1cGxlX0dFVF9JVEVNKHJlc3VsdCwgMCkpOworICAgICAgICBQeV9ERUNSRUYoUHlUdXBsZV9HRVRfSVRFTShyZXN1bHQsIDEpKTsKKyAgICB9IGVsc2UgeworICAgICAgICByZXN1bHQgPSBQeVR1cGxlX05ldygyKTsKKyAgICAgICAgaWYgKHJlc3VsdCA9PSBOVUxMKSB7CisgICAgICAgICAgICBQeV9ERUNSRUYobmV4dF9pbmRleCk7CisgICAgICAgICAgICBQeV9ERUNSRUYobmV4dF9pdGVtKTsKKyAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgICAgICB9CisgICAgfQorICAgIFB5VHVwbGVfU0VUX0lURU0ocmVzdWx0LCAwLCBuZXh0X2luZGV4KTsKKyAgICBQeVR1cGxlX1NFVF9JVEVNKHJlc3VsdCwgMSwgbmV4dF9pdGVtKTsKKyAgICByZXR1cm4gcmVzdWx0OworfQorCitzdGF0aWMgUHlPYmplY3QgKgorZW51bV9uZXh0KGVudW1vYmplY3QgKmVuKQoreworICAgIFB5T2JqZWN0ICpuZXh0X2luZGV4OworICAgIFB5T2JqZWN0ICpuZXh0X2l0ZW07CisgICAgUHlPYmplY3QgKnJlc3VsdCA9IGVuLT5lbl9yZXN1bHQ7CisgICAgUHlPYmplY3QgKml0ID0gZW4tPmVuX3NpdDsKKworICAgIG5leHRfaXRlbSA9ICgqUHlfVFlQRShpdCktPnRwX2l0ZXJuZXh0KShpdCk7CisgICAgaWYgKG5leHRfaXRlbSA9PSBOVUxMKQorICAgICAgICByZXR1cm4gTlVMTDsKKworICAgIGlmIChlbi0+ZW5faW5kZXggPT0gUFlfU1NJWkVfVF9NQVgpCisgICAgICAgIHJldHVybiBlbnVtX25leHRfbG9uZyhlbiwgbmV4dF9pdGVtKTsKKworICAgIG5leHRfaW5kZXggPSBQeUludF9Gcm9tU3NpemVfdChlbi0+ZW5faW5kZXgpOworICAgIGlmIChuZXh0X2luZGV4ID09IE5VTEwpIHsKKyAgICAgICAgUHlfREVDUkVGKG5leHRfaXRlbSk7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICBlbi0+ZW5faW5kZXgrKzsKKworICAgIGlmIChyZXN1bHQtPm9iX3JlZmNudCA9PSAxKSB7CisgICAgICAgIFB5X0lOQ1JFRihyZXN1bHQpOworICAgICAgICBQeV9ERUNSRUYoUHlUdXBsZV9HRVRfSVRFTShyZXN1bHQsIDApKTsKKyAgICAgICAgUHlfREVDUkVGKFB5VHVwbGVfR0VUX0lURU0ocmVzdWx0LCAxKSk7CisgICAgfSBlbHNlIHsKKyAgICAgICAgcmVzdWx0ID0gUHlUdXBsZV9OZXcoMik7CisgICAgICAgIGlmIChyZXN1bHQgPT0gTlVMTCkgeworICAgICAgICAgICAgUHlfREVDUkVGKG5leHRfaW5kZXgpOworICAgICAgICAgICAgUHlfREVDUkVGKG5leHRfaXRlbSk7CisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgfQorICAgIH0KKyAgICBQeVR1cGxlX1NFVF9JVEVNKHJlc3VsdCwgMCwgbmV4dF9pbmRleCk7CisgICAgUHlUdXBsZV9TRVRfSVRFTShyZXN1bHQsIDEsIG5leHRfaXRlbSk7CisgICAgcmV0dXJuIHJlc3VsdDsKK30KKworUHlEb2NfU1RSVkFSKGVudW1fZG9jLAorImVudW1lcmF0ZShpdGVyYWJsZVssIHN0YXJ0XSkgLT4gaXRlcmF0b3IgZm9yIGluZGV4LCB2YWx1ZSBvZiBpdGVyYWJsZVxuIgorIlxuIgorIlJldHVybiBhbiBlbnVtZXJhdGUgb2JqZWN0LiAgaXRlcmFibGUgbXVzdCBiZSBhbm90aGVyIG9iamVjdCB0aGF0IHN1cHBvcnRzXG4iCisiaXRlcmF0aW9uLiAgVGhlIGVudW1lcmF0ZSBvYmplY3QgeWllbGRzIHBhaXJzIGNvbnRhaW5pbmcgYSBjb3VudCAoZnJvbVxuIgorInN0YXJ0LCB3aGljaCBkZWZhdWx0cyB0byB6ZXJvKSBhbmQgYSB2YWx1ZSB5aWVsZGVkIGJ5IHRoZSBpdGVyYWJsZSBhcmd1bWVudC5cbiIKKyJlbnVtZXJhdGUgaXMgdXNlZnVsIGZvciBvYnRhaW5pbmcgYW4gaW5kZXhlZCBsaXN0OlxuIgorIiAgICAoMCwgc2VxWzBdKSwgKDEsIHNlcVsxXSksICgyLCBzZXFbMl0pLCAuLi4iKTsKKworUHlUeXBlT2JqZWN0IFB5RW51bV9UeXBlID0geworICAgIFB5VmFyT2JqZWN0X0hFQURfSU5JVCgmUHlUeXBlX1R5cGUsIDApCisgICAgImVudW1lcmF0ZSIsICAgICAgICAgICAgICAgICAgICAvKiB0cF9uYW1lICovCisgICAgc2l6ZW9mKGVudW1vYmplY3QpLCAgICAgICAgICAgICAvKiB0cF9iYXNpY3NpemUgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2l0ZW1zaXplICovCisgICAgLyogbWV0aG9kcyAqLworICAgIChkZXN0cnVjdG9yKWVudW1fZGVhbGxvYywgICAgICAgLyogdHBfZGVhbGxvYyAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfcHJpbnQgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2dldGF0dHIgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3NldGF0dHIgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2NvbXBhcmUgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3JlcHIgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2FzX251bWJlciAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfYXNfc2VxdWVuY2UgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2FzX21hcHBpbmcgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2hhc2ggKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2NhbGwgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3N0ciAqLworICAgIFB5T2JqZWN0X0dlbmVyaWNHZXRBdHRyLCAgICAgICAgLyogdHBfZ2V0YXR0cm8gKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3NldGF0dHJvICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9hc19idWZmZXIgKi8KKyAgICBQeV9UUEZMQUdTX0RFRkFVTFQgfCBQeV9UUEZMQUdTX0hBVkVfR0MgfAorICAgICAgICBQeV9UUEZMQUdTX0JBU0VUWVBFLCAgICAvKiB0cF9mbGFncyAqLworICAgIGVudW1fZG9jLCAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZG9jICovCisgICAgKHRyYXZlcnNlcHJvYyllbnVtX3RyYXZlcnNlLCAgICAvKiB0cF90cmF2ZXJzZSAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfY2xlYXIgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3JpY2hjb21wYXJlICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF93ZWFrbGlzdG9mZnNldCAqLworICAgIFB5T2JqZWN0X1NlbGZJdGVyLCAgICAgICAgICAgICAgICAgIC8qIHRwX2l0ZXIgKi8KKyAgICAoaXRlcm5leHRmdW5jKWVudW1fbmV4dCwgICAgICAgIC8qIHRwX2l0ZXJuZXh0ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9tZXRob2RzICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9tZW1iZXJzICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9nZXRzZXQgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2Jhc2UgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2RpY3QgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2Rlc2NyX2dldCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZGVzY3Jfc2V0ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9kaWN0b2Zmc2V0ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9pbml0ICovCisgICAgUHlUeXBlX0dlbmVyaWNBbGxvYywgICAgICAgICAgICAvKiB0cF9hbGxvYyAqLworICAgIGVudW1fbmV3LCAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfbmV3ICovCisgICAgUHlPYmplY3RfR0NfRGVsLCAgICAgICAgICAgICAgICAvKiB0cF9mcmVlICovCit9OworCisvKiBSZXZlcnNlZCBPYmplY3QgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLworCit0eXBlZGVmIHN0cnVjdCB7CisgICAgUHlPYmplY3RfSEVBRAorICAgIFB5X3NzaXplX3QgICAgICBpbmRleDsKKyAgICBQeU9iamVjdCogc2VxOworfSByZXZlcnNlZG9iamVjdDsKKworc3RhdGljIFB5T2JqZWN0ICoKK3JldmVyc2VkX25ldyhQeVR5cGVPYmplY3QgKnR5cGUsIFB5T2JqZWN0ICphcmdzLCBQeU9iamVjdCAqa3dkcykKK3sKKyAgICBQeV9zc2l6ZV90IG47CisgICAgUHlPYmplY3QgKnNlcSwgKnJldmVyc2VkX21ldGg7CisgICAgc3RhdGljIFB5T2JqZWN0ICpyZXZlcnNlZF9jYWNoZSA9IE5VTEw7CisgICAgcmV2ZXJzZWRvYmplY3QgKnJvOworCisgICAgaWYgKHR5cGUgPT0gJlB5UmV2ZXJzZWRfVHlwZSAmJiAhX1B5QXJnX05vS2V5d29yZHMoInJldmVyc2VkKCkiLCBrd2RzKSkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisKKyAgICBpZiAoIVB5QXJnX1VucGFja1R1cGxlKGFyZ3MsICJyZXZlcnNlZCIsIDEsIDEsICZzZXEpICkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisKKyAgICBpZiAoUHlJbnN0YW5jZV9DaGVjayhzZXEpKSB7CisgICAgICAgIHJldmVyc2VkX21ldGggPSBQeU9iamVjdF9HZXRBdHRyU3RyaW5nKHNlcSwgIl9fcmV2ZXJzZWRfXyIpOworICAgICAgICBpZiAocmV2ZXJzZWRfbWV0aCA9PSBOVUxMKSB7CisgICAgICAgICAgICBpZiAoUHlFcnJfRXhjZXB0aW9uTWF0Y2hlcyhQeUV4Y19BdHRyaWJ1dGVFcnJvcikpCisgICAgICAgICAgICAgICAgUHlFcnJfQ2xlYXIoKTsKKyAgICAgICAgICAgIGVsc2UKKyAgICAgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgfQorICAgIH0KKyAgICBlbHNlIHsKKyAgICAgICAgcmV2ZXJzZWRfbWV0aCA9IF9QeU9iamVjdF9Mb29rdXBTcGVjaWFsKHNlcSwgIl9fcmV2ZXJzZWRfXyIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmcmV2ZXJzZWRfY2FjaGUpOworICAgICAgICBpZiAocmV2ZXJzZWRfbWV0aCA9PSBOVUxMICYmIFB5RXJyX09jY3VycmVkKCkpCisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgaWYgKHJldmVyc2VkX21ldGggIT0gTlVMTCkgeworICAgICAgICBQeU9iamVjdCAqcmVzID0gUHlPYmplY3RfQ2FsbEZ1bmN0aW9uT2JqQXJncyhyZXZlcnNlZF9tZXRoLCBOVUxMKTsKKyAgICAgICAgUHlfREVDUkVGKHJldmVyc2VkX21ldGgpOworICAgICAgICByZXR1cm4gcmVzOworICAgIH0KKworICAgIGlmICghUHlTZXF1ZW5jZV9DaGVjayhzZXEpKSB7CisgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19UeXBlRXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAgICAiYXJndW1lbnQgdG8gcmV2ZXJzZWQoKSBtdXN0IGJlIGEgc2VxdWVuY2UiKTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorCisgICAgbiA9IFB5U2VxdWVuY2VfU2l6ZShzZXEpOworICAgIGlmIChuID09IC0xKQorICAgICAgICByZXR1cm4gTlVMTDsKKworICAgIHJvID0gKHJldmVyc2Vkb2JqZWN0ICopdHlwZS0+dHBfYWxsb2ModHlwZSwgMCk7CisgICAgaWYgKHJvID09IE5VTEwpCisgICAgICAgIHJldHVybiBOVUxMOworCisgICAgcm8tPmluZGV4ID0gbi0xOworICAgIFB5X0lOQ1JFRihzZXEpOworICAgIHJvLT5zZXEgPSBzZXE7CisgICAgcmV0dXJuIChQeU9iamVjdCAqKXJvOworfQorCitzdGF0aWMgdm9pZAorcmV2ZXJzZWRfZGVhbGxvYyhyZXZlcnNlZG9iamVjdCAqcm8pCit7CisgICAgUHlPYmplY3RfR0NfVW5UcmFjayhybyk7CisgICAgUHlfWERFQ1JFRihyby0+c2VxKTsKKyAgICBQeV9UWVBFKHJvKS0+dHBfZnJlZShybyk7Cit9CisKK3N0YXRpYyBpbnQKK3JldmVyc2VkX3RyYXZlcnNlKHJldmVyc2Vkb2JqZWN0ICpybywgdmlzaXRwcm9jIHZpc2l0LCB2b2lkICphcmcpCit7CisgICAgUHlfVklTSVQocm8tPnNlcSk7CisgICAgcmV0dXJuIDA7Cit9CisKK3N0YXRpYyBQeU9iamVjdCAqCityZXZlcnNlZF9uZXh0KHJldmVyc2Vkb2JqZWN0ICpybykKK3sKKyAgICBQeU9iamVjdCAqaXRlbTsKKyAgICBQeV9zc2l6ZV90IGluZGV4ID0gcm8tPmluZGV4OworCisgICAgaWYgKGluZGV4ID49IDApIHsKKyAgICAgICAgaXRlbSA9IFB5U2VxdWVuY2VfR2V0SXRlbShyby0+c2VxLCBpbmRleCk7CisgICAgICAgIGlmIChpdGVtICE9IE5VTEwpIHsKKyAgICAgICAgICAgIHJvLT5pbmRleC0tOworICAgICAgICAgICAgcmV0dXJuIGl0ZW07CisgICAgICAgIH0KKyAgICAgICAgaWYgKFB5RXJyX0V4Y2VwdGlvbk1hdGNoZXMoUHlFeGNfSW5kZXhFcnJvcikgfHwKKyAgICAgICAgICAgIFB5RXJyX0V4Y2VwdGlvbk1hdGNoZXMoUHlFeGNfU3RvcEl0ZXJhdGlvbikpCisgICAgICAgICAgICBQeUVycl9DbGVhcigpOworICAgIH0KKyAgICByby0+aW5kZXggPSAtMTsKKyAgICBQeV9DTEVBUihyby0+c2VxKTsKKyAgICByZXR1cm4gTlVMTDsKK30KKworUHlEb2NfU1RSVkFSKHJldmVyc2VkX2RvYywKKyJyZXZlcnNlZChzZXF1ZW5jZSkgLT4gcmV2ZXJzZSBpdGVyYXRvciBvdmVyIHZhbHVlcyBvZiB0aGUgc2VxdWVuY2VcbiIKKyJcbiIKKyJSZXR1cm4gYSByZXZlcnNlIGl0ZXJhdG9yIik7CisKK3N0YXRpYyBQeU9iamVjdCAqCityZXZlcnNlZF9sZW4ocmV2ZXJzZWRvYmplY3QgKnJvKQoreworICAgIFB5X3NzaXplX3QgcG9zaXRpb24sIHNlcXNpemU7CisKKyAgICBpZiAocm8tPnNlcSA9PSBOVUxMKQorICAgICAgICByZXR1cm4gUHlJbnRfRnJvbUxvbmcoMCk7CisgICAgc2Vxc2l6ZSA9IFB5U2VxdWVuY2VfU2l6ZShyby0+c2VxKTsKKyAgICBpZiAoc2Vxc2l6ZSA9PSAtMSkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgcG9zaXRpb24gPSByby0+aW5kZXggKyAxOworICAgIHJldHVybiBQeUludF9Gcm9tU3NpemVfdCgoc2Vxc2l6ZSA8IHBvc2l0aW9uKSAgPyAgMCAgOiAgcG9zaXRpb24pOworfQorCitQeURvY19TVFJWQVIobGVuZ3RoX2hpbnRfZG9jLCAiUHJpdmF0ZSBtZXRob2QgcmV0dXJuaW5nIGFuIGVzdGltYXRlIG9mIGxlbihsaXN0KGl0KSkuIik7CisKK3N0YXRpYyBQeU1ldGhvZERlZiByZXZlcnNlZGl0ZXJfbWV0aG9kc1tdID0geworICAgIHsiX19sZW5ndGhfaGludF9fIiwgKFB5Q0Z1bmN0aW9uKXJldmVyc2VkX2xlbiwgTUVUSF9OT0FSR1MsIGxlbmd0aF9oaW50X2RvY30sCisgICAge05VTEwsICAgICAgICAgICAgICBOVUxMfSAgICAgICAgICAgLyogc2VudGluZWwgKi8KK307CisKK1B5VHlwZU9iamVjdCBQeVJldmVyc2VkX1R5cGUgPSB7CisgICAgUHlWYXJPYmplY3RfSEVBRF9JTklUKCZQeVR5cGVfVHlwZSwgMCkKKyAgICAicmV2ZXJzZWQiLCAgICAgICAgICAgICAgICAgICAgIC8qIHRwX25hbWUgKi8KKyAgICBzaXplb2YocmV2ZXJzZWRvYmplY3QpLCAgICAgICAgIC8qIHRwX2Jhc2ljc2l6ZSAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfaXRlbXNpemUgKi8KKyAgICAvKiBtZXRob2RzICovCisgICAgKGRlc3RydWN0b3IpcmV2ZXJzZWRfZGVhbGxvYywgICAvKiB0cF9kZWFsbG9jICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9wcmludCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZ2V0YXR0ciAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfc2V0YXR0ciAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfY29tcGFyZSAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfcmVwciAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfYXNfbnVtYmVyICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfYXNfc2VxdWVuY2UgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2FzX21hcHBpbmcgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2hhc2ggKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2NhbGwgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3N0ciAqLworICAgIFB5T2JqZWN0X0dlbmVyaWNHZXRBdHRyLCAgICAgICAgLyogdHBfZ2V0YXR0cm8gKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3NldGF0dHJvICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9hc19idWZmZXIgKi8KKyAgICBQeV9UUEZMQUdTX0RFRkFVTFQgfCBQeV9UUEZMQUdTX0hBVkVfR0MgfAorICAgICAgICBQeV9UUEZMQUdTX0JBU0VUWVBFLCAgICAvKiB0cF9mbGFncyAqLworICAgIHJldmVyc2VkX2RvYywgICAgICAgICAgICAgICAgICAgLyogdHBfZG9jICovCisgICAgKHRyYXZlcnNlcHJvYylyZXZlcnNlZF90cmF2ZXJzZSwvKiB0cF90cmF2ZXJzZSAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfY2xlYXIgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3JpY2hjb21wYXJlICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF93ZWFrbGlzdG9mZnNldCAqLworICAgIFB5T2JqZWN0X1NlbGZJdGVyLCAgICAgICAgICAgICAgICAgIC8qIHRwX2l0ZXIgKi8KKyAgICAoaXRlcm5leHRmdW5jKXJldmVyc2VkX25leHQsICAgIC8qIHRwX2l0ZXJuZXh0ICovCisgICAgcmV2ZXJzZWRpdGVyX21ldGhvZHMsICAgICAgICAgICAgICAgLyogdHBfbWV0aG9kcyAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfbWVtYmVycyAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZ2V0c2V0ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9iYXNlICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9kaWN0ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9kZXNjcl9nZXQgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2Rlc2NyX3NldCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZGljdG9mZnNldCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfaW5pdCAqLworICAgIFB5VHlwZV9HZW5lcmljQWxsb2MsICAgICAgICAgICAgLyogdHBfYWxsb2MgKi8KKyAgICByZXZlcnNlZF9uZXcsICAgICAgICAgICAgICAgICAgIC8qIHRwX25ldyAqLworICAgIFB5T2JqZWN0X0dDX0RlbCwgICAgICAgICAgICAgICAgLyogdHBfZnJlZSAqLworfTsKZGlmZiAtLWdpdCBhL1B5dGhvbi0yLjcuNS9PYmplY3RzL2V4Y2VwdGlvbnMuYyBiL1B5dGhvbi0yLjcuNS9PYmplY3RzL2V4Y2VwdGlvbnMuYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wZjg2Y2ZiCi0tLSAvZGV2L251bGwKKysrIGIvUHl0aG9uLTIuNy41L09iamVjdHMvZXhjZXB0aW9ucy5jCkBAIC0wLDAgKzEsMjIxOSBAQAorLyoKKyAqIE5ldyBleGNlcHRpb25zLmMgd3JpdHRlbiBpbiBJY2VsYW5kIGJ5IFJpY2hhcmQgSm9uZXMgYW5kIEdlb3JnIEJyYW5kbC4KKyAqCisgKiBUaGFua3MgZ28gdG8gVGltIFBldGVycyBhbmQgTWljaGFlbCBIdWRzb24gZm9yIGRlYnVnZ2luZy4KKyAqLworCisjZGVmaW5lIFBZX1NTSVpFX1RfQ0xFQU4KKyNpbmNsdWRlIDxQeXRob24uaD4KKyNpbmNsdWRlICJzdHJ1Y3RtZW1iZXIuaCIKKyNpbmNsdWRlICJvc2RlZnMuaCIKKworI2RlZmluZSBFWENfTU9EVUxFX05BTUUgImV4Y2VwdGlvbnMuIgorCisvKiBOT1RFOiBJZiB0aGUgZXhjZXB0aW9uIGNsYXNzIGhpZXJhcmNoeSBjaGFuZ2VzLCBkb24ndCBmb3JnZXQgdG8gdXBkYXRlCisgKiBMaWIvdGVzdC9leGNlcHRpb25faGllcmFyY2h5LnR4dAorICovCisKK1B5RG9jX1NUUlZBUihleGNlcHRpb25zX2RvYywgIlB5dGhvbidzIHN0YW5kYXJkIGV4Y2VwdGlvbiBjbGFzcyBoaWVyYXJjaHkuXG5cCitcblwKK0V4Y2VwdGlvbnMgZm91bmQgaGVyZSBhcmUgZGVmaW5lZCBib3RoIGluIHRoZSBleGNlcHRpb25zIG1vZHVsZSBhbmQgdGhlXG5cCitidWlsdC1pbiBuYW1lc3BhY2UuICBJdCBpcyByZWNvbW1lbmRlZCB0aGF0IHVzZXItZGVmaW5lZCBleGNlcHRpb25zXG5cCitpbmhlcml0IGZyb20gRXhjZXB0aW9uLiAgU2VlIHRoZSBkb2N1bWVudGF0aW9uIGZvciB0aGUgZXhjZXB0aW9uXG5cCitpbmhlcml0YW5jZSBoaWVyYXJjaHkuXG5cCisiKTsKKworLyoKKyAqICAgIEJhc2VFeGNlcHRpb24KKyAqLworc3RhdGljIFB5T2JqZWN0ICoKK0Jhc2VFeGNlcHRpb25fbmV3KFB5VHlwZU9iamVjdCAqdHlwZSwgUHlPYmplY3QgKmFyZ3MsIFB5T2JqZWN0ICprd2RzKQoreworICAgIFB5QmFzZUV4Y2VwdGlvbk9iamVjdCAqc2VsZjsKKworICAgIHNlbGYgPSAoUHlCYXNlRXhjZXB0aW9uT2JqZWN0ICopdHlwZS0+dHBfYWxsb2ModHlwZSwgMCk7CisgICAgaWYgKCFzZWxmKQorICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAvKiB0aGUgZGljdCBpcyBjcmVhdGVkIG9uIHRoZSBmbHkgaW4gUHlPYmplY3RfR2VuZXJpY1NldEF0dHIgKi8KKyAgICBzZWxmLT5tZXNzYWdlID0gc2VsZi0+ZGljdCA9IE5VTEw7CisKKyAgICBzZWxmLT5hcmdzID0gUHlUdXBsZV9OZXcoMCk7CisgICAgaWYgKCFzZWxmLT5hcmdzKSB7CisgICAgICAgIFB5X0RFQ1JFRihzZWxmKTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorCisgICAgc2VsZi0+bWVzc2FnZSA9IFB5U3RyaW5nX0Zyb21TdHJpbmcoIiIpOworICAgIGlmICghc2VsZi0+bWVzc2FnZSkgeworICAgICAgICBQeV9ERUNSRUYoc2VsZik7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKworICAgIHJldHVybiAoUHlPYmplY3QgKilzZWxmOworfQorCitzdGF0aWMgaW50CitCYXNlRXhjZXB0aW9uX2luaXQoUHlCYXNlRXhjZXB0aW9uT2JqZWN0ICpzZWxmLCBQeU9iamVjdCAqYXJncywgUHlPYmplY3QgKmt3ZHMpCit7CisgICAgaWYgKCFfUHlBcmdfTm9LZXl3b3JkcyhQeV9UWVBFKHNlbGYpLT50cF9uYW1lLCBrd2RzKSkKKyAgICAgICAgcmV0dXJuIC0xOworCisgICAgUHlfREVDUkVGKHNlbGYtPmFyZ3MpOworICAgIHNlbGYtPmFyZ3MgPSBhcmdzOworICAgIFB5X0lOQ1JFRihzZWxmLT5hcmdzKTsKKworICAgIGlmIChQeVR1cGxlX0dFVF9TSVpFKHNlbGYtPmFyZ3MpID09IDEpIHsKKyAgICAgICAgUHlfQ0xFQVIoc2VsZi0+bWVzc2FnZSk7CisgICAgICAgIHNlbGYtPm1lc3NhZ2UgPSBQeVR1cGxlX0dFVF9JVEVNKHNlbGYtPmFyZ3MsIDApOworICAgICAgICBQeV9JTkNSRUYoc2VsZi0+bWVzc2FnZSk7CisgICAgfQorICAgIHJldHVybiAwOworfQorCitzdGF0aWMgaW50CitCYXNlRXhjZXB0aW9uX2NsZWFyKFB5QmFzZUV4Y2VwdGlvbk9iamVjdCAqc2VsZikKK3sKKyAgICBQeV9DTEVBUihzZWxmLT5kaWN0KTsKKyAgICBQeV9DTEVBUihzZWxmLT5hcmdzKTsKKyAgICBQeV9DTEVBUihzZWxmLT5tZXNzYWdlKTsKKyAgICByZXR1cm4gMDsKK30KKworc3RhdGljIHZvaWQKK0Jhc2VFeGNlcHRpb25fZGVhbGxvYyhQeUJhc2VFeGNlcHRpb25PYmplY3QgKnNlbGYpCit7CisgICAgX1B5T2JqZWN0X0dDX1VOVFJBQ0soc2VsZik7CisgICAgQmFzZUV4Y2VwdGlvbl9jbGVhcihzZWxmKTsKKyAgICBQeV9UWVBFKHNlbGYpLT50cF9mcmVlKChQeU9iamVjdCAqKXNlbGYpOworfQorCitzdGF0aWMgaW50CitCYXNlRXhjZXB0aW9uX3RyYXZlcnNlKFB5QmFzZUV4Y2VwdGlvbk9iamVjdCAqc2VsZiwgdmlzaXRwcm9jIHZpc2l0LCB2b2lkICphcmcpCit7CisgICAgUHlfVklTSVQoc2VsZi0+ZGljdCk7CisgICAgUHlfVklTSVQoc2VsZi0+YXJncyk7CisgICAgUHlfVklTSVQoc2VsZi0+bWVzc2FnZSk7CisgICAgcmV0dXJuIDA7Cit9CisKK3N0YXRpYyBQeU9iamVjdCAqCitCYXNlRXhjZXB0aW9uX3N0cihQeUJhc2VFeGNlcHRpb25PYmplY3QgKnNlbGYpCit7CisgICAgUHlPYmplY3QgKm91dDsKKworICAgIHN3aXRjaCAoUHlUdXBsZV9HRVRfU0laRShzZWxmLT5hcmdzKSkgeworICAgIGNhc2UgMDoKKyAgICAgICAgb3V0ID0gUHlTdHJpbmdfRnJvbVN0cmluZygiIik7CisgICAgICAgIGJyZWFrOworICAgIGNhc2UgMToKKyAgICAgICAgb3V0ID0gUHlPYmplY3RfU3RyKFB5VHVwbGVfR0VUX0lURU0oc2VsZi0+YXJncywgMCkpOworICAgICAgICBicmVhazsKKyAgICBkZWZhdWx0OgorICAgICAgICBvdXQgPSBQeU9iamVjdF9TdHIoc2VsZi0+YXJncyk7CisgICAgICAgIGJyZWFrOworICAgIH0KKworICAgIHJldHVybiBvdXQ7Cit9CisKKyNpZmRlZiBQeV9VU0lOR19VTklDT0RFCitzdGF0aWMgUHlPYmplY3QgKgorQmFzZUV4Y2VwdGlvbl91bmljb2RlKFB5QmFzZUV4Y2VwdGlvbk9iamVjdCAqc2VsZikKK3sKKyAgICBQeU9iamVjdCAqb3V0OworCisgICAgLyogaXNzdWU2MTA4OiBpZiBfX3N0cl9fIGhhcyBiZWVuIG92ZXJyaWRkZW4gaW4gdGhlIHN1YmNsYXNzLCB1bmljb2RlKCkKKyAgICAgICBzaG91bGQgcmV0dXJuIHRoZSBtZXNzYWdlIHJldHVybmVkIGJ5IF9fc3RyX18gYXMgdXNlZCB0byBoYXBwZW4KKyAgICAgICBiZWZvcmUgdGhpcyBtZXRob2Qgd2FzIGltcGxlbWVudGVkLiAqLworICAgIGlmIChQeV9UWVBFKHNlbGYpLT50cF9zdHIgIT0gKHJlcHJmdW5jKUJhc2VFeGNlcHRpb25fc3RyKSB7CisgICAgICAgIFB5T2JqZWN0ICpzdHI7CisgICAgICAgIC8qIFVubGlrZSBQeU9iamVjdF9TdHIsIHRwX3N0ciBjYW4gcmV0dXJuIHVuaWNvZGUgKGkuZS4gcmV0dXJuIHRoZQorICAgICAgICAgICBlcXVpdmFsZW50IG9mIHVuaWNvZGUoZS5fX3N0cl9fKCkpIGluc3RlYWQgb2YgdW5pY29kZShzdHIoZSkpKS4gKi8KKyAgICAgICAgc3RyID0gUHlfVFlQRShzZWxmKS0+dHBfc3RyKChQeU9iamVjdCopc2VsZik7CisgICAgICAgIGlmIChzdHIgPT0gTlVMTCkKKyAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgICAgICBvdXQgPSBQeU9iamVjdF9Vbmljb2RlKHN0cik7CisgICAgICAgIFB5X0RFQ1JFRihzdHIpOworICAgICAgICByZXR1cm4gb3V0OworICAgIH0KKworICAgIHN3aXRjaCAoUHlUdXBsZV9HRVRfU0laRShzZWxmLT5hcmdzKSkgeworICAgIGNhc2UgMDoKKyAgICAgICAgb3V0ID0gUHlVbmljb2RlX0Zyb21TdHJpbmcoIiIpOworICAgICAgICBicmVhazsKKyAgICBjYXNlIDE6CisgICAgICAgIG91dCA9IFB5T2JqZWN0X1VuaWNvZGUoUHlUdXBsZV9HRVRfSVRFTShzZWxmLT5hcmdzLCAwKSk7CisgICAgICAgIGJyZWFrOworICAgIGRlZmF1bHQ6CisgICAgICAgIG91dCA9IFB5T2JqZWN0X1VuaWNvZGUoc2VsZi0+YXJncyk7CisgICAgICAgIGJyZWFrOworICAgIH0KKworICAgIHJldHVybiBvdXQ7Cit9CisjZW5kaWYKKworc3RhdGljIFB5T2JqZWN0ICoKK0Jhc2VFeGNlcHRpb25fcmVwcihQeUJhc2VFeGNlcHRpb25PYmplY3QgKnNlbGYpCit7CisgICAgUHlPYmplY3QgKnJlcHJfc3VmZml4OworICAgIFB5T2JqZWN0ICpyZXByOworICAgIGNoYXIgKm5hbWU7CisgICAgY2hhciAqZG90OworCisgICAgcmVwcl9zdWZmaXggPSBQeU9iamVjdF9SZXByKHNlbGYtPmFyZ3MpOworICAgIGlmICghcmVwcl9zdWZmaXgpCisgICAgICAgIHJldHVybiBOVUxMOworCisgICAgbmFtZSA9IChjaGFyICopUHlfVFlQRShzZWxmKS0+dHBfbmFtZTsKKyAgICBkb3QgPSBzdHJyY2hyKG5hbWUsICcuJyk7CisgICAgaWYgKGRvdCAhPSBOVUxMKSBuYW1lID0gZG90KzE7CisKKyAgICByZXByID0gUHlTdHJpbmdfRnJvbVN0cmluZyhuYW1lKTsKKyAgICBpZiAoIXJlcHIpIHsKKyAgICAgICAgUHlfREVDUkVGKHJlcHJfc3VmZml4KTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorCisgICAgUHlTdHJpbmdfQ29uY2F0QW5kRGVsKCZyZXByLCByZXByX3N1ZmZpeCk7CisgICAgcmV0dXJuIHJlcHI7Cit9CisKKy8qIFBpY2tsaW5nIHN1cHBvcnQgKi8KK3N0YXRpYyBQeU9iamVjdCAqCitCYXNlRXhjZXB0aW9uX3JlZHVjZShQeUJhc2VFeGNlcHRpb25PYmplY3QgKnNlbGYpCit7CisgICAgaWYgKHNlbGYtPmFyZ3MgJiYgc2VsZi0+ZGljdCkKKyAgICAgICAgcmV0dXJuIFB5VHVwbGVfUGFjaygzLCBQeV9UWVBFKHNlbGYpLCBzZWxmLT5hcmdzLCBzZWxmLT5kaWN0KTsKKyAgICBlbHNlCisgICAgICAgIHJldHVybiBQeVR1cGxlX1BhY2soMiwgUHlfVFlQRShzZWxmKSwgc2VsZi0+YXJncyk7Cit9CisKKy8qCisgKiBOZWVkZWQgZm9yIGJhY2t3YXJkIGNvbXBhdGliaWxpdHksIHNpbmNlIGV4Y2VwdGlvbnMgdXNlZCB0byBzdG9yZQorICogYWxsIHRoZWlyIGF0dHJpYnV0ZXMgaW4gdGhlIF9fZGljdF9fLiBDb2RlIGlzIHRha2VuIGZyb20gY1BpY2tsZSdzCisgKiBsb2FkX2J1aWxkIGZ1bmN0aW9uLgorICovCitzdGF0aWMgUHlPYmplY3QgKgorQmFzZUV4Y2VwdGlvbl9zZXRzdGF0ZShQeU9iamVjdCAqc2VsZiwgUHlPYmplY3QgKnN0YXRlKQoreworICAgIFB5T2JqZWN0ICpkX2tleSwgKmRfdmFsdWU7CisgICAgUHlfc3NpemVfdCBpID0gMDsKKworICAgIGlmIChzdGF0ZSAhPSBQeV9Ob25lKSB7CisgICAgICAgIGlmICghUHlEaWN0X0NoZWNrKHN0YXRlKSkgeworICAgICAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1R5cGVFcnJvciwgInN0YXRlIGlzIG5vdCBhIGRpY3Rpb25hcnkiKTsKKyAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgICAgICB9CisgICAgICAgIHdoaWxlIChQeURpY3RfTmV4dChzdGF0ZSwgJmksICZkX2tleSwgJmRfdmFsdWUpKSB7CisgICAgICAgICAgICBpZiAoUHlPYmplY3RfU2V0QXR0cihzZWxmLCBkX2tleSwgZF92YWx1ZSkgPCAwKQorICAgICAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgICAgICB9CisgICAgfQorICAgIFB5X1JFVFVSTl9OT05FOworfQorCisKK3N0YXRpYyBQeU1ldGhvZERlZiBCYXNlRXhjZXB0aW9uX21ldGhvZHNbXSA9IHsKKyAgIHsiX19yZWR1Y2VfXyIsIChQeUNGdW5jdGlvbilCYXNlRXhjZXB0aW9uX3JlZHVjZSwgTUVUSF9OT0FSR1MgfSwKKyAgIHsiX19zZXRzdGF0ZV9fIiwgKFB5Q0Z1bmN0aW9uKUJhc2VFeGNlcHRpb25fc2V0c3RhdGUsIE1FVEhfTyB9LAorI2lmZGVmIFB5X1VTSU5HX1VOSUNPREUKKyAgIHsiX191bmljb2RlX18iLCAoUHlDRnVuY3Rpb24pQmFzZUV4Y2VwdGlvbl91bmljb2RlLCBNRVRIX05PQVJHUyB9LAorI2VuZGlmCisgICB7TlVMTCwgTlVMTCwgMCwgTlVMTH0sCit9OworCisKKworc3RhdGljIFB5T2JqZWN0ICoKK0Jhc2VFeGNlcHRpb25fZ2V0aXRlbShQeUJhc2VFeGNlcHRpb25PYmplY3QgKnNlbGYsIFB5X3NzaXplX3QgaW5kZXgpCit7CisgICAgaWYgKFB5RXJyX1dhcm5QeTNrKCJfX2dldGl0ZW1fXyBub3Qgc3VwcG9ydGVkIGZvciBleGNlcHRpb24gIgorICAgICAgICAgICAgICAgICAgICAgICAiY2xhc3NlcyBpbiAzLng7IHVzZSBhcmdzIGF0dHJpYnV0ZSIsIDEpIDwgMCkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgcmV0dXJuIFB5U2VxdWVuY2VfR2V0SXRlbShzZWxmLT5hcmdzLCBpbmRleCk7Cit9CisKK3N0YXRpYyBQeU9iamVjdCAqCitCYXNlRXhjZXB0aW9uX2dldHNsaWNlKFB5QmFzZUV4Y2VwdGlvbk9iamVjdCAqc2VsZiwKKyAgICAgICAgICAgICAgICAgICAgICAgIFB5X3NzaXplX3Qgc3RhcnQsIFB5X3NzaXplX3Qgc3RvcCkKK3sKKyAgICBpZiAoUHlFcnJfV2FyblB5M2soIl9fZ2V0c2xpY2VfXyBub3Qgc3VwcG9ydGVkIGZvciBleGNlcHRpb24gIgorICAgICAgICAgICAgICAgICAgICAgICAiY2xhc3NlcyBpbiAzLng7IHVzZSBhcmdzIGF0dHJpYnV0ZSIsIDEpIDwgMCkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgcmV0dXJuIFB5U2VxdWVuY2VfR2V0U2xpY2Uoc2VsZi0+YXJncywgc3RhcnQsIHN0b3ApOworfQorCitzdGF0aWMgUHlTZXF1ZW5jZU1ldGhvZHMgQmFzZUV4Y2VwdGlvbl9hc19zZXF1ZW5jZSA9IHsKKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAvKiBzcV9sZW5ndGg7ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgLyogc3FfY29uY2F0OyAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgIC8qIHNxX3JlcGVhdDsgKi8KKyAgICAoc3NpemVhcmdmdW5jKUJhc2VFeGNlcHRpb25fZ2V0aXRlbSwgIC8qIHNxX2l0ZW07ICovCisgICAgKHNzaXplc3NpemVhcmdmdW5jKUJhc2VFeGNlcHRpb25fZ2V0c2xpY2UsICAvKiBzcV9zbGljZTsgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAvKiBzcV9hc3NfaXRlbTsgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAvKiBzcV9hc3Nfc2xpY2U7ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgLyogc3FfY29udGFpbnM7ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgLyogc3FfaW5wbGFjZV9jb25jYXQ7ICovCisgICAgMCAgICAgICAgICAgICAgICAgICAgICAgLyogc3FfaW5wbGFjZV9yZXBlYXQ7ICovCit9OworCitzdGF0aWMgUHlPYmplY3QgKgorQmFzZUV4Y2VwdGlvbl9nZXRfZGljdChQeUJhc2VFeGNlcHRpb25PYmplY3QgKnNlbGYpCit7CisgICAgaWYgKHNlbGYtPmRpY3QgPT0gTlVMTCkgeworICAgICAgICBzZWxmLT5kaWN0ID0gUHlEaWN0X05ldygpOworICAgICAgICBpZiAoIXNlbGYtPmRpY3QpCisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgUHlfSU5DUkVGKHNlbGYtPmRpY3QpOworICAgIHJldHVybiBzZWxmLT5kaWN0OworfQorCitzdGF0aWMgaW50CitCYXNlRXhjZXB0aW9uX3NldF9kaWN0KFB5QmFzZUV4Y2VwdGlvbk9iamVjdCAqc2VsZiwgUHlPYmplY3QgKnZhbCkKK3sKKyAgICBpZiAodmFsID09IE5VTEwpIHsKKyAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1R5cGVFcnJvciwgIl9fZGljdF9fIG1heSBub3QgYmUgZGVsZXRlZCIpOworICAgICAgICByZXR1cm4gLTE7CisgICAgfQorICAgIGlmICghUHlEaWN0X0NoZWNrKHZhbCkpIHsKKyAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1R5cGVFcnJvciwgIl9fZGljdF9fIG11c3QgYmUgYSBkaWN0aW9uYXJ5Iik7CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisgICAgUHlfQ0xFQVIoc2VsZi0+ZGljdCk7CisgICAgUHlfSU5DUkVGKHZhbCk7CisgICAgc2VsZi0+ZGljdCA9IHZhbDsKKyAgICByZXR1cm4gMDsKK30KKworc3RhdGljIFB5T2JqZWN0ICoKK0Jhc2VFeGNlcHRpb25fZ2V0X2FyZ3MoUHlCYXNlRXhjZXB0aW9uT2JqZWN0ICpzZWxmKQoreworICAgIGlmIChzZWxmLT5hcmdzID09IE5VTEwpIHsKKyAgICAgICAgUHlfSU5DUkVGKFB5X05vbmUpOworICAgICAgICByZXR1cm4gUHlfTm9uZTsKKyAgICB9CisgICAgUHlfSU5DUkVGKHNlbGYtPmFyZ3MpOworICAgIHJldHVybiBzZWxmLT5hcmdzOworfQorCitzdGF0aWMgaW50CitCYXNlRXhjZXB0aW9uX3NldF9hcmdzKFB5QmFzZUV4Y2VwdGlvbk9iamVjdCAqc2VsZiwgUHlPYmplY3QgKnZhbCkKK3sKKyAgICBQeU9iamVjdCAqc2VxOworICAgIGlmICh2YWwgPT0gTlVMTCkgeworICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfVHlwZUVycm9yLCAiYXJncyBtYXkgbm90IGJlIGRlbGV0ZWQiKTsKKyAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKyAgICBzZXEgPSBQeVNlcXVlbmNlX1R1cGxlKHZhbCk7CisgICAgaWYgKCFzZXEpCisgICAgICAgIHJldHVybiAtMTsKKyAgICBQeV9DTEVBUihzZWxmLT5hcmdzKTsKKyAgICBzZWxmLT5hcmdzID0gc2VxOworICAgIHJldHVybiAwOworfQorCitzdGF0aWMgUHlPYmplY3QgKgorQmFzZUV4Y2VwdGlvbl9nZXRfbWVzc2FnZShQeUJhc2VFeGNlcHRpb25PYmplY3QgKnNlbGYpCit7CisgICAgUHlPYmplY3QgKm1zZzsKKworICAgIC8qIGlmICJtZXNzYWdlIiBpcyBpbiBzZWxmLT5kaWN0LCBhY2Nlc3NpbmcgYSB1c2VyLXNldCBtZXNzYWdlIGF0dHJpYnV0ZSAqLworICAgIGlmIChzZWxmLT5kaWN0ICYmCisgICAgICAgIChtc2cgPSBQeURpY3RfR2V0SXRlbVN0cmluZyhzZWxmLT5kaWN0LCAibWVzc2FnZSIpKSkgeworICAgICAgICBQeV9JTkNSRUYobXNnKTsKKyAgICAgICAgcmV0dXJuIG1zZzsKKyAgICB9CisKKyAgICBpZiAoc2VsZi0+bWVzc2FnZSA9PSBOVUxMKSB7CisgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19BdHRyaWJ1dGVFcnJvciwgIm1lc3NhZ2UgYXR0cmlidXRlIHdhcyBkZWxldGVkIik7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKworICAgIC8qIGFjY2Vzc2luZyB0aGUgZGVwcmVjYXRlZCAiYnVpbHRpbiIgbWVzc2FnZSBhdHRyaWJ1dGUgb2YgRXhjZXB0aW9uICovCisgICAgaWYgKFB5RXJyX1dhcm5FeChQeUV4Y19EZXByZWNhdGlvbldhcm5pbmcsCisgICAgICAgICAgICAgICAgICAgICAiQmFzZUV4Y2VwdGlvbi5tZXNzYWdlIGhhcyBiZWVuIGRlcHJlY2F0ZWQgYXMgIgorICAgICAgICAgICAgICAgICAgICAgIm9mIFB5dGhvbiAyLjYiLCAxKSA8IDApCisgICAgICAgIHJldHVybiBOVUxMOworCisgICAgUHlfSU5DUkVGKHNlbGYtPm1lc3NhZ2UpOworICAgIHJldHVybiBzZWxmLT5tZXNzYWdlOworfQorCitzdGF0aWMgaW50CitCYXNlRXhjZXB0aW9uX3NldF9tZXNzYWdlKFB5QmFzZUV4Y2VwdGlvbk9iamVjdCAqc2VsZiwgUHlPYmplY3QgKnZhbCkKK3sKKyAgICAvKiBpZiB2YWwgaXMgTlVMTCwgZGVsZXRlIHRoZSBtZXNzYWdlIGF0dHJpYnV0ZSAqLworICAgIGlmICh2YWwgPT0gTlVMTCkgeworICAgICAgICBpZiAoc2VsZi0+ZGljdCAmJiBQeURpY3RfR2V0SXRlbVN0cmluZyhzZWxmLT5kaWN0LCAibWVzc2FnZSIpKSB7CisgICAgICAgICAgICBpZiAoUHlEaWN0X0RlbEl0ZW1TdHJpbmcoc2VsZi0+ZGljdCwgIm1lc3NhZ2UiKSA8IDApCisgICAgICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICB9CisgICAgICAgIFB5X0NMRUFSKHNlbGYtPm1lc3NhZ2UpOworICAgICAgICByZXR1cm4gMDsKKyAgICB9CisKKyAgICAvKiBlbHNlIHNldCBpdCBpbiBfX2RpY3RfXywgYnV0IG1heSBuZWVkIHRvIGNyZWF0ZSB0aGUgZGljdCBmaXJzdCAqLworICAgIGlmIChzZWxmLT5kaWN0ID09IE5VTEwpIHsKKyAgICAgICAgc2VsZi0+ZGljdCA9IFB5RGljdF9OZXcoKTsKKyAgICAgICAgaWYgKCFzZWxmLT5kaWN0KQorICAgICAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKyAgICByZXR1cm4gUHlEaWN0X1NldEl0ZW1TdHJpbmcoc2VsZi0+ZGljdCwgIm1lc3NhZ2UiLCB2YWwpOworfQorCitzdGF0aWMgUHlHZXRTZXREZWYgQmFzZUV4Y2VwdGlvbl9nZXRzZXRbXSA9IHsKKyAgICB7Il9fZGljdF9fIiwgKGdldHRlcilCYXNlRXhjZXB0aW9uX2dldF9kaWN0LCAoc2V0dGVyKUJhc2VFeGNlcHRpb25fc2V0X2RpY3R9LAorICAgIHsiYXJncyIsIChnZXR0ZXIpQmFzZUV4Y2VwdGlvbl9nZXRfYXJncywgKHNldHRlcilCYXNlRXhjZXB0aW9uX3NldF9hcmdzfSwKKyAgICB7Im1lc3NhZ2UiLCAoZ2V0dGVyKUJhc2VFeGNlcHRpb25fZ2V0X21lc3NhZ2UsCisgICAgICAgICAgICAoc2V0dGVyKUJhc2VFeGNlcHRpb25fc2V0X21lc3NhZ2V9LAorICAgIHtOVUxMfSwKK307CisKKworc3RhdGljIFB5VHlwZU9iamVjdCBfUHlFeGNfQmFzZUV4Y2VwdGlvbiA9IHsKKyAgICBQeU9iamVjdF9IRUFEX0lOSVQoTlVMTCkKKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgLypvYl9zaXplKi8KKyAgICBFWENfTU9EVUxFX05BTUUgIkJhc2VFeGNlcHRpb24iLCAvKnRwX25hbWUqLworICAgIHNpemVvZihQeUJhc2VFeGNlcHRpb25PYmplY3QpLCAvKnRwX2Jhc2ljc2l6ZSovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgIC8qdHBfaXRlbXNpemUqLworICAgIChkZXN0cnVjdG9yKUJhc2VFeGNlcHRpb25fZGVhbGxvYywgLyp0cF9kZWFsbG9jKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgLyp0cF9wcmludCovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgIC8qdHBfZ2V0YXR0ciovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgIC8qdHBfc2V0YXR0ciovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2NvbXBhcmU7ICovCisgICAgKHJlcHJmdW5jKUJhc2VFeGNlcHRpb25fcmVwciwgLyp0cF9yZXByKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgLyp0cF9hc19udW1iZXIqLworICAgICZCYXNlRXhjZXB0aW9uX2FzX3NlcXVlbmNlLCAvKnRwX2FzX3NlcXVlbmNlKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgLyp0cF9hc19tYXBwaW5nKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgLyp0cF9oYXNoICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgIC8qdHBfY2FsbCovCisgICAgKHJlcHJmdW5jKUJhc2VFeGNlcHRpb25fc3RyLCAgLyp0cF9zdHIqLworICAgIFB5T2JqZWN0X0dlbmVyaWNHZXRBdHRyLCAgICAvKnRwX2dldGF0dHJvKi8KKyAgICBQeU9iamVjdF9HZW5lcmljU2V0QXR0ciwgICAgLyp0cF9zZXRhdHRybyovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgIC8qdHBfYXNfYnVmZmVyKi8KKyAgICBQeV9UUEZMQUdTX0RFRkFVTFQgfCBQeV9UUEZMQUdTX0JBU0VUWVBFIHwgUHlfVFBGTEFHU19IQVZFX0dDIHwKKyAgICAgICAgUHlfVFBGTEFHU19CQVNFX0VYQ19TVUJDTEFTUywgIC8qdHBfZmxhZ3MqLworICAgIFB5RG9jX1NUUigiQ29tbW9uIGJhc2UgY2xhc3MgZm9yIGFsbCBleGNlcHRpb25zIiksIC8qIHRwX2RvYyAqLworICAgICh0cmF2ZXJzZXByb2MpQmFzZUV4Y2VwdGlvbl90cmF2ZXJzZSwgLyogdHBfdHJhdmVyc2UgKi8KKyAgICAoaW5xdWlyeSlCYXNlRXhjZXB0aW9uX2NsZWFyLCAvKiB0cF9jbGVhciAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9yaWNoY29tcGFyZSAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF93ZWFrbGlzdG9mZnNldCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9pdGVyICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2l0ZXJuZXh0ICovCisgICAgQmFzZUV4Y2VwdGlvbl9tZXRob2RzLCAgICAgIC8qIHRwX21ldGhvZHMgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfbWVtYmVycyAqLworICAgIEJhc2VFeGNlcHRpb25fZ2V0c2V0LCAgICAgICAvKiB0cF9nZXRzZXQgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfYmFzZSAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9kaWN0ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2Rlc2NyX2dldCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9kZXNjcl9zZXQgKi8KKyAgICBvZmZzZXRvZihQeUJhc2VFeGNlcHRpb25PYmplY3QsIGRpY3QpLCAvKiB0cF9kaWN0b2Zmc2V0ICovCisgICAgKGluaXRwcm9jKUJhc2VFeGNlcHRpb25faW5pdCwgLyogdHBfaW5pdCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9hbGxvYyAqLworICAgIEJhc2VFeGNlcHRpb25fbmV3LCAgICAgICAgICAvKiB0cF9uZXcgKi8KK307CisvKiB0aGUgQ1B5dGhvbiBBUEkgZXhwZWN0cyBleGNlcHRpb25zIHRvIGJlIChQeU9iamVjdCAqKSAtIGJvdGggYSBob2xkLW92ZXIKK2Zyb20gdGhlIHByZXZpb3VzIGltcGxtZW50YXRpb24gYW5kIGFsc28gYWxsb3dpbmcgUHl0aG9uIG9iamVjdHMgdG8gYmUgdXNlZAoraW4gdGhlIEFQSSAqLworUHlPYmplY3QgKlB5RXhjX0Jhc2VFeGNlcHRpb24gPSAoUHlPYmplY3QgKikmX1B5RXhjX0Jhc2VFeGNlcHRpb247CisKKy8qIG5vdGUgdGhlc2UgbWFjcm9zIG9taXQgdGhlIGxhc3Qgc2VtaWNvbG9uIHNvIHRoZSBtYWNybyBpbnZvY2F0aW9uIG1heQorICogaW5jbHVkZSBpdCBhbmQgbm90IGxvb2sgc3RyYW5nZS4KKyAqLworI2RlZmluZSBTaW1wbGVFeHRlbmRzRXhjZXB0aW9uKEVYQ0JBU0UsIEVYQ05BTUUsIEVYQ0RPQykgXAorc3RhdGljIFB5VHlwZU9iamVjdCBfUHlFeGNfICMjIEVYQ05BTUUgPSB7IFwKKyAgICBQeU9iamVjdF9IRUFEX0lOSVQoTlVMTCkgXAorICAgIDAsIFwKKyAgICBFWENfTU9EVUxFX05BTUUgIyBFWENOQU1FLCBcCisgICAgc2l6ZW9mKFB5QmFzZUV4Y2VwdGlvbk9iamVjdCksIFwKKyAgICAwLCAoZGVzdHJ1Y3RvcilCYXNlRXhjZXB0aW9uX2RlYWxsb2MsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIFwKKyAgICAwLCAwLCAwLCAwLCAwLCAwLCAwLCBcCisgICAgUHlfVFBGTEFHU19ERUZBVUxUIHwgUHlfVFBGTEFHU19CQVNFVFlQRSB8IFB5X1RQRkxBR1NfSEFWRV9HQywgXAorICAgIFB5RG9jX1NUUihFWENET0MpLCAodHJhdmVyc2Vwcm9jKUJhc2VFeGNlcHRpb25fdHJhdmVyc2UsIFwKKyAgICAoaW5xdWlyeSlCYXNlRXhjZXB0aW9uX2NsZWFyLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAmXyAjIyBFWENCQVNFLCBcCisgICAgMCwgMCwgMCwgb2Zmc2V0b2YoUHlCYXNlRXhjZXB0aW9uT2JqZWN0LCBkaWN0KSwgXAorICAgIChpbml0cHJvYylCYXNlRXhjZXB0aW9uX2luaXQsIDAsIEJhc2VFeGNlcHRpb25fbmV3LFwKK307IFwKK1B5T2JqZWN0ICpQeUV4Y18gIyMgRVhDTkFNRSA9IChQeU9iamVjdCAqKSZfUHlFeGNfICMjIEVYQ05BTUUKKworI2RlZmluZSBNaWRkbGluZ0V4dGVuZHNFeGNlcHRpb24oRVhDQkFTRSwgRVhDTkFNRSwgRVhDU1RPUkUsIEVYQ0RPQykgXAorc3RhdGljIFB5VHlwZU9iamVjdCBfUHlFeGNfICMjIEVYQ05BTUUgPSB7IFwKKyAgICBQeU9iamVjdF9IRUFEX0lOSVQoTlVMTCkgXAorICAgIDAsIFwKKyAgICBFWENfTU9EVUxFX05BTUUgIyBFWENOQU1FLCBcCisgICAgc2l6ZW9mKFB5ICMjIEVYQ1NUT1JFICMjIE9iamVjdCksIFwKKyAgICAwLCAoZGVzdHJ1Y3RvcilFWENTVE9SRSAjIyBfZGVhbGxvYywgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgXAorICAgIDAsIDAsIDAsIDAsIDAsIFwKKyAgICBQeV9UUEZMQUdTX0RFRkFVTFQgfCBQeV9UUEZMQUdTX0JBU0VUWVBFIHwgUHlfVFBGTEFHU19IQVZFX0dDLCBcCisgICAgUHlEb2NfU1RSKEVYQ0RPQyksICh0cmF2ZXJzZXByb2MpRVhDU1RPUkUgIyMgX3RyYXZlcnNlLCBcCisgICAgKGlucXVpcnkpRVhDU1RPUkUgIyMgX2NsZWFyLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAmXyAjIyBFWENCQVNFLCBcCisgICAgMCwgMCwgMCwgb2Zmc2V0b2YoUHkgIyMgRVhDU1RPUkUgIyMgT2JqZWN0LCBkaWN0KSwgXAorICAgIChpbml0cHJvYylFWENTVE9SRSAjIyBfaW5pdCwgMCwgQmFzZUV4Y2VwdGlvbl9uZXcsXAorfTsgXAorUHlPYmplY3QgKlB5RXhjXyAjIyBFWENOQU1FID0gKFB5T2JqZWN0ICopJl9QeUV4Y18gIyMgRVhDTkFNRQorCisjZGVmaW5lIENvbXBsZXhFeHRlbmRzRXhjZXB0aW9uKEVYQ0JBU0UsIEVYQ05BTUUsIEVYQ1NUT1JFLCBFWENERUFMTE9DLCBFWENNRVRIT0RTLCBFWENNRU1CRVJTLCBFWENTVFIsIEVYQ0RPQykgXAorc3RhdGljIFB5VHlwZU9iamVjdCBfUHlFeGNfICMjIEVYQ05BTUUgPSB7IFwKKyAgICBQeU9iamVjdF9IRUFEX0lOSVQoTlVMTCkgXAorICAgIDAsIFwKKyAgICBFWENfTU9EVUxFX05BTUUgIyBFWENOQU1FLCBcCisgICAgc2l6ZW9mKFB5ICMjIEVYQ1NUT1JFICMjIE9iamVjdCksIDAsIFwKKyAgICAoZGVzdHJ1Y3RvcilFWENTVE9SRSAjIyBfZGVhbGxvYywgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgXAorICAgIChyZXByZnVuYylFWENTVFIsIDAsIDAsIDAsIFwKKyAgICBQeV9UUEZMQUdTX0RFRkFVTFQgfCBQeV9UUEZMQUdTX0JBU0VUWVBFIHwgUHlfVFBGTEFHU19IQVZFX0dDLCBcCisgICAgUHlEb2NfU1RSKEVYQ0RPQyksICh0cmF2ZXJzZXByb2MpRVhDU1RPUkUgIyMgX3RyYXZlcnNlLCBcCisgICAgKGlucXVpcnkpRVhDU1RPUkUgIyMgX2NsZWFyLCAwLCAwLCAwLCAwLCBFWENNRVRIT0RTLCBcCisgICAgRVhDTUVNQkVSUywgMCwgJl8gIyMgRVhDQkFTRSwgXAorICAgIDAsIDAsIDAsIG9mZnNldG9mKFB5ICMjIEVYQ1NUT1JFICMjIE9iamVjdCwgZGljdCksIFwKKyAgICAoaW5pdHByb2MpRVhDU1RPUkUgIyMgX2luaXQsIDAsIEJhc2VFeGNlcHRpb25fbmV3LFwKK307IFwKK1B5T2JqZWN0ICpQeUV4Y18gIyMgRVhDTkFNRSA9IChQeU9iamVjdCAqKSZfUHlFeGNfICMjIEVYQ05BTUUKKworCisvKgorICogICAgRXhjZXB0aW9uIGV4dGVuZHMgQmFzZUV4Y2VwdGlvbgorICovCitTaW1wbGVFeHRlbmRzRXhjZXB0aW9uKFB5RXhjX0Jhc2VFeGNlcHRpb24sIEV4Y2VwdGlvbiwKKyAgICAgICAgICAgICAgICAgICAgICAgIkNvbW1vbiBiYXNlIGNsYXNzIGZvciBhbGwgbm9uLWV4aXQgZXhjZXB0aW9ucy4iKTsKKworCisvKgorICogICAgU3RhbmRhcmRFcnJvciBleHRlbmRzIEV4Y2VwdGlvbgorICovCitTaW1wbGVFeHRlbmRzRXhjZXB0aW9uKFB5RXhjX0V4Y2VwdGlvbiwgU3RhbmRhcmRFcnJvciwKKyAgICAiQmFzZSBjbGFzcyBmb3IgYWxsIHN0YW5kYXJkIFB5dGhvbiBleGNlcHRpb25zIHRoYXQgZG8gbm90IHJlcHJlc2VudFxuIgorICAgICJpbnRlcnByZXRlciBleGl0aW5nLiIpOworCisKKy8qCisgKiAgICBUeXBlRXJyb3IgZXh0ZW5kcyBTdGFuZGFyZEVycm9yCisgKi8KK1NpbXBsZUV4dGVuZHNFeGNlcHRpb24oUHlFeGNfU3RhbmRhcmRFcnJvciwgVHlwZUVycm9yLAorICAgICAgICAgICAgICAgICAgICAgICAiSW5hcHByb3ByaWF0ZSBhcmd1bWVudCB0eXBlLiIpOworCisKKy8qCisgKiAgICBTdG9wSXRlcmF0aW9uIGV4dGVuZHMgRXhjZXB0aW9uCisgKi8KK1NpbXBsZUV4dGVuZHNFeGNlcHRpb24oUHlFeGNfRXhjZXB0aW9uLCBTdG9wSXRlcmF0aW9uLAorICAgICAgICAgICAgICAgICAgICAgICAiU2lnbmFsIHRoZSBlbmQgZnJvbSBpdGVyYXRvci5uZXh0KCkuIik7CisKKworLyoKKyAqICAgIEdlbmVyYXRvckV4aXQgZXh0ZW5kcyBCYXNlRXhjZXB0aW9uCisgKi8KK1NpbXBsZUV4dGVuZHNFeGNlcHRpb24oUHlFeGNfQmFzZUV4Y2VwdGlvbiwgR2VuZXJhdG9yRXhpdCwKKyAgICAgICAgICAgICAgICAgICAgICAgIlJlcXVlc3QgdGhhdCBhIGdlbmVyYXRvciBleGl0LiIpOworCisKKy8qCisgKiAgICBTeXN0ZW1FeGl0IGV4dGVuZHMgQmFzZUV4Y2VwdGlvbgorICovCisKK3N0YXRpYyBpbnQKK1N5c3RlbUV4aXRfaW5pdChQeVN5c3RlbUV4aXRPYmplY3QgKnNlbGYsIFB5T2JqZWN0ICphcmdzLCBQeU9iamVjdCAqa3dkcykKK3sKKyAgICBQeV9zc2l6ZV90IHNpemUgPSBQeVR1cGxlX0dFVF9TSVpFKGFyZ3MpOworCisgICAgaWYgKEJhc2VFeGNlcHRpb25faW5pdCgoUHlCYXNlRXhjZXB0aW9uT2JqZWN0ICopc2VsZiwgYXJncywga3dkcykgPT0gLTEpCisgICAgICAgIHJldHVybiAtMTsKKworICAgIGlmIChzaXplID09IDApCisgICAgICAgIHJldHVybiAwOworICAgIFB5X0NMRUFSKHNlbGYtPmNvZGUpOworICAgIGlmIChzaXplID09IDEpCisgICAgICAgIHNlbGYtPmNvZGUgPSBQeVR1cGxlX0dFVF9JVEVNKGFyZ3MsIDApOworICAgIGVsc2UgaWYgKHNpemUgPiAxKQorICAgICAgICBzZWxmLT5jb2RlID0gYXJnczsKKyAgICBQeV9JTkNSRUYoc2VsZi0+Y29kZSk7CisgICAgcmV0dXJuIDA7Cit9CisKK3N0YXRpYyBpbnQKK1N5c3RlbUV4aXRfY2xlYXIoUHlTeXN0ZW1FeGl0T2JqZWN0ICpzZWxmKQoreworICAgIFB5X0NMRUFSKHNlbGYtPmNvZGUpOworICAgIHJldHVybiBCYXNlRXhjZXB0aW9uX2NsZWFyKChQeUJhc2VFeGNlcHRpb25PYmplY3QgKilzZWxmKTsKK30KKworc3RhdGljIHZvaWQKK1N5c3RlbUV4aXRfZGVhbGxvYyhQeVN5c3RlbUV4aXRPYmplY3QgKnNlbGYpCit7CisgICAgX1B5T2JqZWN0X0dDX1VOVFJBQ0soc2VsZik7CisgICAgU3lzdGVtRXhpdF9jbGVhcihzZWxmKTsKKyAgICBQeV9UWVBFKHNlbGYpLT50cF9mcmVlKChQeU9iamVjdCAqKXNlbGYpOworfQorCitzdGF0aWMgaW50CitTeXN0ZW1FeGl0X3RyYXZlcnNlKFB5U3lzdGVtRXhpdE9iamVjdCAqc2VsZiwgdmlzaXRwcm9jIHZpc2l0LCB2b2lkICphcmcpCit7CisgICAgUHlfVklTSVQoc2VsZi0+Y29kZSk7CisgICAgcmV0dXJuIEJhc2VFeGNlcHRpb25fdHJhdmVyc2UoKFB5QmFzZUV4Y2VwdGlvbk9iamVjdCAqKXNlbGYsIHZpc2l0LCBhcmcpOworfQorCitzdGF0aWMgUHlNZW1iZXJEZWYgU3lzdGVtRXhpdF9tZW1iZXJzW10gPSB7CisgICAgeyJjb2RlIiwgVF9PQkpFQ1QsIG9mZnNldG9mKFB5U3lzdGVtRXhpdE9iamVjdCwgY29kZSksIDAsCisgICAgICAgIFB5RG9jX1NUUigiZXhjZXB0aW9uIGNvZGUiKX0sCisgICAge05VTEx9ICAvKiBTZW50aW5lbCAqLworfTsKKworQ29tcGxleEV4dGVuZHNFeGNlcHRpb24oUHlFeGNfQmFzZUV4Y2VwdGlvbiwgU3lzdGVtRXhpdCwgU3lzdGVtRXhpdCwKKyAgICAgICAgICAgICAgICAgICAgICAgIFN5c3RlbUV4aXRfZGVhbGxvYywgMCwgU3lzdGVtRXhpdF9tZW1iZXJzLCAwLAorICAgICAgICAgICAgICAgICAgICAgICAgIlJlcXVlc3QgdG8gZXhpdCBmcm9tIHRoZSBpbnRlcnByZXRlci4iKTsKKworLyoKKyAqICAgIEtleWJvYXJkSW50ZXJydXB0IGV4dGVuZHMgQmFzZUV4Y2VwdGlvbgorICovCitTaW1wbGVFeHRlbmRzRXhjZXB0aW9uKFB5RXhjX0Jhc2VFeGNlcHRpb24sIEtleWJvYXJkSW50ZXJydXB0LAorICAgICAgICAgICAgICAgICAgICAgICAiUHJvZ3JhbSBpbnRlcnJ1cHRlZCBieSB1c2VyLiIpOworCisKKy8qCisgKiAgICBJbXBvcnRFcnJvciBleHRlbmRzIFN0YW5kYXJkRXJyb3IKKyAqLworU2ltcGxlRXh0ZW5kc0V4Y2VwdGlvbihQeUV4Y19TdGFuZGFyZEVycm9yLCBJbXBvcnRFcnJvciwKKyAgICAgICAgICAiSW1wb3J0IGNhbid0IGZpbmQgbW9kdWxlLCBvciBjYW4ndCBmaW5kIG5hbWUgaW4gbW9kdWxlLiIpOworCisKKy8qCisgKiAgICBFbnZpcm9ubWVudEVycm9yIGV4dGVuZHMgU3RhbmRhcmRFcnJvcgorICovCisKKy8qIFdoZXJlIGEgZnVuY3Rpb24gaGFzIGEgc2luZ2xlIGZpbGVuYW1lLCBzdWNoIGFzIG9wZW4oKSBvciBzb21lCisgKiBvZiB0aGUgb3MgbW9kdWxlIGZ1bmN0aW9ucywgUHlFcnJfU2V0RnJvbUVycm5vV2l0aEZpbGVuYW1lKCkgaXMKKyAqIGNhbGxlZCwgZ2l2aW5nIGEgdGhpcmQgYXJndW1lbnQgd2hpY2ggaXMgdGhlIGZpbGVuYW1lLiAgQnV0LCBzbworICogdGhhdCBvbGQgY29kZSB1c2luZyBpbi1wbGFjZSB1bnBhY2tpbmcgZG9lc24ndCBicmVhaywgZS5nLjoKKyAqCisgKiBleGNlcHQgSU9FcnJvciwgKGVycm5vLCBzdHJlcnJvcik6CisgKgorICogd2UgaGFjayBhcmdzIHNvIHRoYXQgaXQgb25seSBjb250YWlucyB0d28gaXRlbXMuICBUaGlzIGFsc28KKyAqIG1lYW5zIHdlIG5lZWQgb3VyIG93biBfX3N0cl9fKCkgd2hpY2ggcHJpbnRzIG91dCB0aGUgZmlsZW5hbWUKKyAqIHdoZW4gaXQgd2FzIHN1cHBsaWVkLgorICovCitzdGF0aWMgaW50CitFbnZpcm9ubWVudEVycm9yX2luaXQoUHlFbnZpcm9ubWVudEVycm9yT2JqZWN0ICpzZWxmLCBQeU9iamVjdCAqYXJncywKKyAgICBQeU9iamVjdCAqa3dkcykKK3sKKyAgICBQeU9iamVjdCAqbXllcnJubyA9IE5VTEwsICpzdHJlcnJvciA9IE5VTEwsICpmaWxlbmFtZSA9IE5VTEw7CisgICAgUHlPYmplY3QgKnN1YnNsaWNlID0gTlVMTDsKKworICAgIGlmIChCYXNlRXhjZXB0aW9uX2luaXQoKFB5QmFzZUV4Y2VwdGlvbk9iamVjdCAqKXNlbGYsIGFyZ3MsIGt3ZHMpID09IC0xKQorICAgICAgICByZXR1cm4gLTE7CisKKyAgICBpZiAoUHlUdXBsZV9HRVRfU0laRShhcmdzKSA8PSAxIHx8IFB5VHVwbGVfR0VUX1NJWkUoYXJncykgPiAzKSB7CisgICAgICAgIHJldHVybiAwOworICAgIH0KKworICAgIGlmICghUHlBcmdfVW5wYWNrVHVwbGUoYXJncywgIkVudmlyb25tZW50RXJyb3IiLCAyLCAzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgJm15ZXJybm8sICZzdHJlcnJvciwgJmZpbGVuYW1lKSkgeworICAgICAgICByZXR1cm4gLTE7CisgICAgfQorICAgIFB5X0NMRUFSKHNlbGYtPm15ZXJybm8pOyAgICAgICAvKiByZXBsYWNpbmcgKi8KKyAgICBzZWxmLT5teWVycm5vID0gbXllcnJubzsKKyAgICBQeV9JTkNSRUYoc2VsZi0+bXllcnJubyk7CisKKyAgICBQeV9DTEVBUihzZWxmLT5zdHJlcnJvcik7ICAgICAgLyogcmVwbGFjaW5nICovCisgICAgc2VsZi0+c3RyZXJyb3IgPSBzdHJlcnJvcjsKKyAgICBQeV9JTkNSRUYoc2VsZi0+c3RyZXJyb3IpOworCisgICAgLyogc2VsZi0+ZmlsZW5hbWUgd2lsbCByZW1haW4gUHlfTm9uZSBvdGhlcndpc2UgKi8KKyAgICBpZiAoZmlsZW5hbWUgIT0gTlVMTCkgeworICAgICAgICBQeV9DTEVBUihzZWxmLT5maWxlbmFtZSk7ICAgICAgLyogcmVwbGFjaW5nICovCisgICAgICAgIHNlbGYtPmZpbGVuYW1lID0gZmlsZW5hbWU7CisgICAgICAgIFB5X0lOQ1JFRihzZWxmLT5maWxlbmFtZSk7CisKKyAgICAgICAgc3Vic2xpY2UgPSBQeVR1cGxlX0dldFNsaWNlKGFyZ3MsIDAsIDIpOworICAgICAgICBpZiAoIXN1YnNsaWNlKQorICAgICAgICAgICAgcmV0dXJuIC0xOworCisgICAgICAgIFB5X0RFQ1JFRihzZWxmLT5hcmdzKTsgIC8qIHJlcGxhY2luZyBhcmdzICovCisgICAgICAgIHNlbGYtPmFyZ3MgPSBzdWJzbGljZTsKKyAgICB9CisgICAgcmV0dXJuIDA7Cit9CisKK3N0YXRpYyBpbnQKK0Vudmlyb25tZW50RXJyb3JfY2xlYXIoUHlFbnZpcm9ubWVudEVycm9yT2JqZWN0ICpzZWxmKQoreworICAgIFB5X0NMRUFSKHNlbGYtPm15ZXJybm8pOworICAgIFB5X0NMRUFSKHNlbGYtPnN0cmVycm9yKTsKKyAgICBQeV9DTEVBUihzZWxmLT5maWxlbmFtZSk7CisgICAgcmV0dXJuIEJhc2VFeGNlcHRpb25fY2xlYXIoKFB5QmFzZUV4Y2VwdGlvbk9iamVjdCAqKXNlbGYpOworfQorCitzdGF0aWMgdm9pZAorRW52aXJvbm1lbnRFcnJvcl9kZWFsbG9jKFB5RW52aXJvbm1lbnRFcnJvck9iamVjdCAqc2VsZikKK3sKKyAgICBfUHlPYmplY3RfR0NfVU5UUkFDSyhzZWxmKTsKKyAgICBFbnZpcm9ubWVudEVycm9yX2NsZWFyKHNlbGYpOworICAgIFB5X1RZUEUoc2VsZiktPnRwX2ZyZWUoKFB5T2JqZWN0ICopc2VsZik7Cit9CisKK3N0YXRpYyBpbnQKK0Vudmlyb25tZW50RXJyb3JfdHJhdmVyc2UoUHlFbnZpcm9ubWVudEVycm9yT2JqZWN0ICpzZWxmLCB2aXNpdHByb2MgdmlzaXQsCisgICAgICAgIHZvaWQgKmFyZykKK3sKKyAgICBQeV9WSVNJVChzZWxmLT5teWVycm5vKTsKKyAgICBQeV9WSVNJVChzZWxmLT5zdHJlcnJvcik7CisgICAgUHlfVklTSVQoc2VsZi0+ZmlsZW5hbWUpOworICAgIHJldHVybiBCYXNlRXhjZXB0aW9uX3RyYXZlcnNlKChQeUJhc2VFeGNlcHRpb25PYmplY3QgKilzZWxmLCB2aXNpdCwgYXJnKTsKK30KKworc3RhdGljIFB5T2JqZWN0ICoKK0Vudmlyb25tZW50RXJyb3Jfc3RyKFB5RW52aXJvbm1lbnRFcnJvck9iamVjdCAqc2VsZikKK3sKKyAgICBQeU9iamVjdCAqcnRudmFsID0gTlVMTDsKKworICAgIGlmIChzZWxmLT5maWxlbmFtZSkgeworICAgICAgICBQeU9iamVjdCAqZm10OworICAgICAgICBQeU9iamVjdCAqcmVwcjsKKyAgICAgICAgUHlPYmplY3QgKnR1cGxlOworCisgICAgICAgIGZtdCA9IFB5U3RyaW5nX0Zyb21TdHJpbmcoIltFcnJubyAlc10gJXM6ICVzIik7CisgICAgICAgIGlmICghZm10KQorICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisKKyAgICAgICAgcmVwciA9IFB5T2JqZWN0X1JlcHIoc2VsZi0+ZmlsZW5hbWUpOworICAgICAgICBpZiAoIXJlcHIpIHsKKyAgICAgICAgICAgIFB5X0RFQ1JFRihmbXQpOworICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgICAgIH0KKyAgICAgICAgdHVwbGUgPSBQeVR1cGxlX05ldygzKTsKKyAgICAgICAgaWYgKCF0dXBsZSkgeworICAgICAgICAgICAgUHlfREVDUkVGKHJlcHIpOworICAgICAgICAgICAgUHlfREVDUkVGKGZtdCk7CisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChzZWxmLT5teWVycm5vKSB7CisgICAgICAgICAgICBQeV9JTkNSRUYoc2VsZi0+bXllcnJubyk7CisgICAgICAgICAgICBQeVR1cGxlX1NFVF9JVEVNKHR1cGxlLCAwLCBzZWxmLT5teWVycm5vKTsKKyAgICAgICAgfQorICAgICAgICBlbHNlIHsKKyAgICAgICAgICAgIFB5X0lOQ1JFRihQeV9Ob25lKTsKKyAgICAgICAgICAgIFB5VHVwbGVfU0VUX0lURU0odHVwbGUsIDAsIFB5X05vbmUpOworICAgICAgICB9CisgICAgICAgIGlmIChzZWxmLT5zdHJlcnJvcikgeworICAgICAgICAgICAgUHlfSU5DUkVGKHNlbGYtPnN0cmVycm9yKTsKKyAgICAgICAgICAgIFB5VHVwbGVfU0VUX0lURU0odHVwbGUsIDEsIHNlbGYtPnN0cmVycm9yKTsKKyAgICAgICAgfQorICAgICAgICBlbHNlIHsKKyAgICAgICAgICAgIFB5X0lOQ1JFRihQeV9Ob25lKTsKKyAgICAgICAgICAgIFB5VHVwbGVfU0VUX0lURU0odHVwbGUsIDEsIFB5X05vbmUpOworICAgICAgICB9CisKKyAgICAgICAgUHlUdXBsZV9TRVRfSVRFTSh0dXBsZSwgMiwgcmVwcik7CisKKyAgICAgICAgcnRudmFsID0gUHlTdHJpbmdfRm9ybWF0KGZtdCwgdHVwbGUpOworCisgICAgICAgIFB5X0RFQ1JFRihmbXQpOworICAgICAgICBQeV9ERUNSRUYodHVwbGUpOworICAgIH0KKyAgICBlbHNlIGlmIChzZWxmLT5teWVycm5vICYmIHNlbGYtPnN0cmVycm9yKSB7CisgICAgICAgIFB5T2JqZWN0ICpmbXQ7CisgICAgICAgIFB5T2JqZWN0ICp0dXBsZTsKKworICAgICAgICBmbXQgPSBQeVN0cmluZ19Gcm9tU3RyaW5nKCJbRXJybm8gJXNdICVzIik7CisgICAgICAgIGlmICghZm10KQorICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisKKyAgICAgICAgdHVwbGUgPSBQeVR1cGxlX05ldygyKTsKKyAgICAgICAgaWYgKCF0dXBsZSkgeworICAgICAgICAgICAgUHlfREVDUkVGKGZtdCk7CisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChzZWxmLT5teWVycm5vKSB7CisgICAgICAgICAgICBQeV9JTkNSRUYoc2VsZi0+bXllcnJubyk7CisgICAgICAgICAgICBQeVR1cGxlX1NFVF9JVEVNKHR1cGxlLCAwLCBzZWxmLT5teWVycm5vKTsKKyAgICAgICAgfQorICAgICAgICBlbHNlIHsKKyAgICAgICAgICAgIFB5X0lOQ1JFRihQeV9Ob25lKTsKKyAgICAgICAgICAgIFB5VHVwbGVfU0VUX0lURU0odHVwbGUsIDAsIFB5X05vbmUpOworICAgICAgICB9CisgICAgICAgIGlmIChzZWxmLT5zdHJlcnJvcikgeworICAgICAgICAgICAgUHlfSU5DUkVGKHNlbGYtPnN0cmVycm9yKTsKKyAgICAgICAgICAgIFB5VHVwbGVfU0VUX0lURU0odHVwbGUsIDEsIHNlbGYtPnN0cmVycm9yKTsKKyAgICAgICAgfQorICAgICAgICBlbHNlIHsKKyAgICAgICAgICAgIFB5X0lOQ1JFRihQeV9Ob25lKTsKKyAgICAgICAgICAgIFB5VHVwbGVfU0VUX0lURU0odHVwbGUsIDEsIFB5X05vbmUpOworICAgICAgICB9CisKKyAgICAgICAgcnRudmFsID0gUHlTdHJpbmdfRm9ybWF0KGZtdCwgdHVwbGUpOworCisgICAgICAgIFB5X0RFQ1JFRihmbXQpOworICAgICAgICBQeV9ERUNSRUYodHVwbGUpOworICAgIH0KKyAgICBlbHNlCisgICAgICAgIHJ0bnZhbCA9IEJhc2VFeGNlcHRpb25fc3RyKChQeUJhc2VFeGNlcHRpb25PYmplY3QgKilzZWxmKTsKKworICAgIHJldHVybiBydG52YWw7Cit9CisKK3N0YXRpYyBQeU1lbWJlckRlZiBFbnZpcm9ubWVudEVycm9yX21lbWJlcnNbXSA9IHsKKyAgICB7ImVycm5vIiwgVF9PQkpFQ1QsIG9mZnNldG9mKFB5RW52aXJvbm1lbnRFcnJvck9iamVjdCwgbXllcnJubyksIDAsCisgICAgICAgIFB5RG9jX1NUUigiZXhjZXB0aW9uIGVycm5vIil9LAorICAgIHsic3RyZXJyb3IiLCBUX09CSkVDVCwgb2Zmc2V0b2YoUHlFbnZpcm9ubWVudEVycm9yT2JqZWN0LCBzdHJlcnJvciksIDAsCisgICAgICAgIFB5RG9jX1NUUigiZXhjZXB0aW9uIHN0cmVycm9yIil9LAorICAgIHsiZmlsZW5hbWUiLCBUX09CSkVDVCwgb2Zmc2V0b2YoUHlFbnZpcm9ubWVudEVycm9yT2JqZWN0LCBmaWxlbmFtZSksIDAsCisgICAgICAgIFB5RG9jX1NUUigiZXhjZXB0aW9uIGZpbGVuYW1lIil9LAorICAgIHtOVUxMfSAgLyogU2VudGluZWwgKi8KK307CisKKworc3RhdGljIFB5T2JqZWN0ICoKK0Vudmlyb25tZW50RXJyb3JfcmVkdWNlKFB5RW52aXJvbm1lbnRFcnJvck9iamVjdCAqc2VsZikKK3sKKyAgICBQeU9iamVjdCAqYXJncyA9IHNlbGYtPmFyZ3M7CisgICAgUHlPYmplY3QgKnJlcyA9IE5VTEwsICp0bXA7CisKKyAgICAvKiBzZWxmLT5hcmdzIGlzIG9ubHkgdGhlIGZpcnN0IHR3byByZWFsIGFyZ3VtZW50cyBpZiB0aGVyZSB3YXMgYQorICAgICAqIGZpbGUgbmFtZSBnaXZlbiB0byBFbnZpcm9ubWVudEVycm9yLiAqLworICAgIGlmIChQeVR1cGxlX0dFVF9TSVpFKGFyZ3MpID09IDIgJiYgc2VsZi0+ZmlsZW5hbWUpIHsKKyAgICAgICAgYXJncyA9IFB5VHVwbGVfTmV3KDMpOworICAgICAgICBpZiAoIWFyZ3MpCisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKworICAgICAgICB0bXAgPSBQeVR1cGxlX0dFVF9JVEVNKHNlbGYtPmFyZ3MsIDApOworICAgICAgICBQeV9JTkNSRUYodG1wKTsKKyAgICAgICAgUHlUdXBsZV9TRVRfSVRFTShhcmdzLCAwLCB0bXApOworCisgICAgICAgIHRtcCA9IFB5VHVwbGVfR0VUX0lURU0oc2VsZi0+YXJncywgMSk7CisgICAgICAgIFB5X0lOQ1JFRih0bXApOworICAgICAgICBQeVR1cGxlX1NFVF9JVEVNKGFyZ3MsIDEsIHRtcCk7CisKKyAgICAgICAgUHlfSU5DUkVGKHNlbGYtPmZpbGVuYW1lKTsKKyAgICAgICAgUHlUdXBsZV9TRVRfSVRFTShhcmdzLCAyLCBzZWxmLT5maWxlbmFtZSk7CisgICAgfSBlbHNlCisgICAgICAgIFB5X0lOQ1JFRihhcmdzKTsKKworICAgIGlmIChzZWxmLT5kaWN0KQorICAgICAgICByZXMgPSBQeVR1cGxlX1BhY2soMywgUHlfVFlQRShzZWxmKSwgYXJncywgc2VsZi0+ZGljdCk7CisgICAgZWxzZQorICAgICAgICByZXMgPSBQeVR1cGxlX1BhY2soMiwgUHlfVFlQRShzZWxmKSwgYXJncyk7CisgICAgUHlfREVDUkVGKGFyZ3MpOworICAgIHJldHVybiByZXM7Cit9CisKKworc3RhdGljIFB5TWV0aG9kRGVmIEVudmlyb25tZW50RXJyb3JfbWV0aG9kc1tdID0geworICAgIHsiX19yZWR1Y2VfXyIsIChQeUNGdW5jdGlvbilFbnZpcm9ubWVudEVycm9yX3JlZHVjZSwgTUVUSF9OT0FSR1N9LAorICAgIHtOVUxMfQorfTsKKworQ29tcGxleEV4dGVuZHNFeGNlcHRpb24oUHlFeGNfU3RhbmRhcmRFcnJvciwgRW52aXJvbm1lbnRFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICAgIEVudmlyb25tZW50RXJyb3IsIEVudmlyb25tZW50RXJyb3JfZGVhbGxvYywKKyAgICAgICAgICAgICAgICAgICAgICAgIEVudmlyb25tZW50RXJyb3JfbWV0aG9kcywgRW52aXJvbm1lbnRFcnJvcl9tZW1iZXJzLAorICAgICAgICAgICAgICAgICAgICAgICAgRW52aXJvbm1lbnRFcnJvcl9zdHIsCisgICAgICAgICAgICAgICAgICAgICAgICAiQmFzZSBjbGFzcyBmb3IgSS9PIHJlbGF0ZWQgZXJyb3JzLiIpOworCisKKy8qCisgKiAgICBJT0Vycm9yIGV4dGVuZHMgRW52aXJvbm1lbnRFcnJvcgorICovCitNaWRkbGluZ0V4dGVuZHNFeGNlcHRpb24oUHlFeGNfRW52aXJvbm1lbnRFcnJvciwgSU9FcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICBFbnZpcm9ubWVudEVycm9yLCAiSS9PIG9wZXJhdGlvbiBmYWlsZWQuIik7CisKKworLyoKKyAqICAgIE9TRXJyb3IgZXh0ZW5kcyBFbnZpcm9ubWVudEVycm9yCisgKi8KK01pZGRsaW5nRXh0ZW5kc0V4Y2VwdGlvbihQeUV4Y19FbnZpcm9ubWVudEVycm9yLCBPU0Vycm9yLAorICAgICAgICAgICAgICAgICAgICAgICAgIEVudmlyb25tZW50RXJyb3IsICJPUyBzeXN0ZW0gY2FsbCBmYWlsZWQuIik7CisKKworLyoKKyAqICAgIFdpbmRvd3NFcnJvciBleHRlbmRzIE9TRXJyb3IKKyAqLworI2lmZGVmIE1TX1dJTkRPV1MKKyNpbmNsdWRlICJlcnJtYXAuaCIKKworc3RhdGljIGludAorV2luZG93c0Vycm9yX2NsZWFyKFB5V2luZG93c0Vycm9yT2JqZWN0ICpzZWxmKQoreworICAgIFB5X0NMRUFSKHNlbGYtPm15ZXJybm8pOworICAgIFB5X0NMRUFSKHNlbGYtPnN0cmVycm9yKTsKKyAgICBQeV9DTEVBUihzZWxmLT5maWxlbmFtZSk7CisgICAgUHlfQ0xFQVIoc2VsZi0+d2luZXJyb3IpOworICAgIHJldHVybiBCYXNlRXhjZXB0aW9uX2NsZWFyKChQeUJhc2VFeGNlcHRpb25PYmplY3QgKilzZWxmKTsKK30KKworc3RhdGljIHZvaWQKK1dpbmRvd3NFcnJvcl9kZWFsbG9jKFB5V2luZG93c0Vycm9yT2JqZWN0ICpzZWxmKQoreworICAgIF9QeU9iamVjdF9HQ19VTlRSQUNLKHNlbGYpOworICAgIFdpbmRvd3NFcnJvcl9jbGVhcihzZWxmKTsKKyAgICBQeV9UWVBFKHNlbGYpLT50cF9mcmVlKChQeU9iamVjdCAqKXNlbGYpOworfQorCitzdGF0aWMgaW50CitXaW5kb3dzRXJyb3JfdHJhdmVyc2UoUHlXaW5kb3dzRXJyb3JPYmplY3QgKnNlbGYsIHZpc2l0cHJvYyB2aXNpdCwgdm9pZCAqYXJnKQoreworICAgIFB5X1ZJU0lUKHNlbGYtPm15ZXJybm8pOworICAgIFB5X1ZJU0lUKHNlbGYtPnN0cmVycm9yKTsKKyAgICBQeV9WSVNJVChzZWxmLT5maWxlbmFtZSk7CisgICAgUHlfVklTSVQoc2VsZi0+d2luZXJyb3IpOworICAgIHJldHVybiBCYXNlRXhjZXB0aW9uX3RyYXZlcnNlKChQeUJhc2VFeGNlcHRpb25PYmplY3QgKilzZWxmLCB2aXNpdCwgYXJnKTsKK30KKworc3RhdGljIGludAorV2luZG93c0Vycm9yX2luaXQoUHlXaW5kb3dzRXJyb3JPYmplY3QgKnNlbGYsIFB5T2JqZWN0ICphcmdzLCBQeU9iamVjdCAqa3dkcykKK3sKKyAgICBQeU9iamVjdCAqb19lcnJjb2RlID0gTlVMTDsKKyAgICBsb25nIGVycmNvZGU7CisgICAgbG9uZyBwb3NpeF9lcnJubzsKKworICAgIGlmIChFbnZpcm9ubWVudEVycm9yX2luaXQoKFB5RW52aXJvbm1lbnRFcnJvck9iamVjdCAqKXNlbGYsIGFyZ3MsIGt3ZHMpCisgICAgICAgICAgICA9PSAtMSkKKyAgICAgICAgcmV0dXJuIC0xOworCisgICAgaWYgKHNlbGYtPm15ZXJybm8gPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIDA7CisKKyAgICAvKiBTZXQgZXJybm8gdG8gdGhlIFBPU0lYIGVycm5vLCBhbmQgd2luZXJyb3IgdG8gdGhlIFdpbjMyCisgICAgICAgZXJyb3IgY29kZS4gKi8KKyAgICBlcnJjb2RlID0gUHlJbnRfQXNMb25nKHNlbGYtPm15ZXJybm8pOworICAgIGlmIChlcnJjb2RlID09IC0xICYmIFB5RXJyX09jY3VycmVkKCkpCisgICAgICAgIHJldHVybiAtMTsKKyAgICBwb3NpeF9lcnJubyA9IHdpbmVycm9yX3RvX2Vycm5vKGVycmNvZGUpOworCisgICAgUHlfQ0xFQVIoc2VsZi0+d2luZXJyb3IpOworICAgIHNlbGYtPndpbmVycm9yID0gc2VsZi0+bXllcnJubzsKKworICAgIG9fZXJyY29kZSA9IFB5SW50X0Zyb21Mb25nKHBvc2l4X2Vycm5vKTsKKyAgICBpZiAoIW9fZXJyY29kZSkKKyAgICAgICAgcmV0dXJuIC0xOworCisgICAgc2VsZi0+bXllcnJubyA9IG9fZXJyY29kZTsKKworICAgIHJldHVybiAwOworfQorCisKK3N0YXRpYyBQeU9iamVjdCAqCitXaW5kb3dzRXJyb3Jfc3RyKFB5V2luZG93c0Vycm9yT2JqZWN0ICpzZWxmKQoreworICAgIFB5T2JqZWN0ICpydG52YWwgPSBOVUxMOworCisgICAgaWYgKHNlbGYtPmZpbGVuYW1lKSB7CisgICAgICAgIFB5T2JqZWN0ICpmbXQ7CisgICAgICAgIFB5T2JqZWN0ICpyZXByOworICAgICAgICBQeU9iamVjdCAqdHVwbGU7CisKKyAgICAgICAgZm10ID0gUHlTdHJpbmdfRnJvbVN0cmluZygiW0Vycm9yICVzXSAlczogJXMiKTsKKyAgICAgICAgaWYgKCFmbXQpCisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKworICAgICAgICByZXByID0gUHlPYmplY3RfUmVwcihzZWxmLT5maWxlbmFtZSk7CisgICAgICAgIGlmICghcmVwcikgeworICAgICAgICAgICAgUHlfREVDUkVGKGZtdCk7CisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgfQorICAgICAgICB0dXBsZSA9IFB5VHVwbGVfTmV3KDMpOworICAgICAgICBpZiAoIXR1cGxlKSB7CisgICAgICAgICAgICBQeV9ERUNSRUYocmVwcik7CisgICAgICAgICAgICBQeV9ERUNSRUYoZm10KTsKKyAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgICAgICB9CisKKyAgICAgICAgaWYgKHNlbGYtPndpbmVycm9yKSB7CisgICAgICAgICAgICBQeV9JTkNSRUYoc2VsZi0+d2luZXJyb3IpOworICAgICAgICAgICAgUHlUdXBsZV9TRVRfSVRFTSh0dXBsZSwgMCwgc2VsZi0+d2luZXJyb3IpOworICAgICAgICB9CisgICAgICAgIGVsc2UgeworICAgICAgICAgICAgUHlfSU5DUkVGKFB5X05vbmUpOworICAgICAgICAgICAgUHlUdXBsZV9TRVRfSVRFTSh0dXBsZSwgMCwgUHlfTm9uZSk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKHNlbGYtPnN0cmVycm9yKSB7CisgICAgICAgICAgICBQeV9JTkNSRUYoc2VsZi0+c3RyZXJyb3IpOworICAgICAgICAgICAgUHlUdXBsZV9TRVRfSVRFTSh0dXBsZSwgMSwgc2VsZi0+c3RyZXJyb3IpOworICAgICAgICB9CisgICAgICAgIGVsc2UgeworICAgICAgICAgICAgUHlfSU5DUkVGKFB5X05vbmUpOworICAgICAgICAgICAgUHlUdXBsZV9TRVRfSVRFTSh0dXBsZSwgMSwgUHlfTm9uZSk7CisgICAgICAgIH0KKworICAgICAgICBQeVR1cGxlX1NFVF9JVEVNKHR1cGxlLCAyLCByZXByKTsKKworICAgICAgICBydG52YWwgPSBQeVN0cmluZ19Gb3JtYXQoZm10LCB0dXBsZSk7CisKKyAgICAgICAgUHlfREVDUkVGKGZtdCk7CisgICAgICAgIFB5X0RFQ1JFRih0dXBsZSk7CisgICAgfQorICAgIGVsc2UgaWYgKHNlbGYtPndpbmVycm9yICYmIHNlbGYtPnN0cmVycm9yKSB7CisgICAgICAgIFB5T2JqZWN0ICpmbXQ7CisgICAgICAgIFB5T2JqZWN0ICp0dXBsZTsKKworICAgICAgICBmbXQgPSBQeVN0cmluZ19Gcm9tU3RyaW5nKCJbRXJyb3IgJXNdICVzIik7CisgICAgICAgIGlmICghZm10KQorICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisKKyAgICAgICAgdHVwbGUgPSBQeVR1cGxlX05ldygyKTsKKyAgICAgICAgaWYgKCF0dXBsZSkgeworICAgICAgICAgICAgUHlfREVDUkVGKGZtdCk7CisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChzZWxmLT53aW5lcnJvcikgeworICAgICAgICAgICAgUHlfSU5DUkVGKHNlbGYtPndpbmVycm9yKTsKKyAgICAgICAgICAgIFB5VHVwbGVfU0VUX0lURU0odHVwbGUsIDAsIHNlbGYtPndpbmVycm9yKTsKKyAgICAgICAgfQorICAgICAgICBlbHNlIHsKKyAgICAgICAgICAgIFB5X0lOQ1JFRihQeV9Ob25lKTsKKyAgICAgICAgICAgIFB5VHVwbGVfU0VUX0lURU0odHVwbGUsIDAsIFB5X05vbmUpOworICAgICAgICB9CisgICAgICAgIGlmIChzZWxmLT5zdHJlcnJvcikgeworICAgICAgICAgICAgUHlfSU5DUkVGKHNlbGYtPnN0cmVycm9yKTsKKyAgICAgICAgICAgIFB5VHVwbGVfU0VUX0lURU0odHVwbGUsIDEsIHNlbGYtPnN0cmVycm9yKTsKKyAgICAgICAgfQorICAgICAgICBlbHNlIHsKKyAgICAgICAgICAgIFB5X0lOQ1JFRihQeV9Ob25lKTsKKyAgICAgICAgICAgIFB5VHVwbGVfU0VUX0lURU0odHVwbGUsIDEsIFB5X05vbmUpOworICAgICAgICB9CisKKyAgICAgICAgcnRudmFsID0gUHlTdHJpbmdfRm9ybWF0KGZtdCwgdHVwbGUpOworCisgICAgICAgIFB5X0RFQ1JFRihmbXQpOworICAgICAgICBQeV9ERUNSRUYodHVwbGUpOworICAgIH0KKyAgICBlbHNlCisgICAgICAgIHJ0bnZhbCA9IEVudmlyb25tZW50RXJyb3Jfc3RyKChQeUVudmlyb25tZW50RXJyb3JPYmplY3QgKilzZWxmKTsKKworICAgIHJldHVybiBydG52YWw7Cit9CisKK3N0YXRpYyBQeU1lbWJlckRlZiBXaW5kb3dzRXJyb3JfbWVtYmVyc1tdID0geworICAgIHsiZXJybm8iLCBUX09CSkVDVCwgb2Zmc2V0b2YoUHlXaW5kb3dzRXJyb3JPYmplY3QsIG15ZXJybm8pLCAwLAorICAgICAgICBQeURvY19TVFIoIlBPU0lYIGV4Y2VwdGlvbiBjb2RlIil9LAorICAgIHsic3RyZXJyb3IiLCBUX09CSkVDVCwgb2Zmc2V0b2YoUHlXaW5kb3dzRXJyb3JPYmplY3QsIHN0cmVycm9yKSwgMCwKKyAgICAgICAgUHlEb2NfU1RSKCJleGNlcHRpb24gc3RyZXJyb3IiKX0sCisgICAgeyJmaWxlbmFtZSIsIFRfT0JKRUNULCBvZmZzZXRvZihQeVdpbmRvd3NFcnJvck9iamVjdCwgZmlsZW5hbWUpLCAwLAorICAgICAgICBQeURvY19TVFIoImV4Y2VwdGlvbiBmaWxlbmFtZSIpfSwKKyAgICB7IndpbmVycm9yIiwgVF9PQkpFQ1QsIG9mZnNldG9mKFB5V2luZG93c0Vycm9yT2JqZWN0LCB3aW5lcnJvciksIDAsCisgICAgICAgIFB5RG9jX1NUUigiV2luMzIgZXhjZXB0aW9uIGNvZGUiKX0sCisgICAge05VTEx9ICAvKiBTZW50aW5lbCAqLworfTsKKworQ29tcGxleEV4dGVuZHNFeGNlcHRpb24oUHlFeGNfT1NFcnJvciwgV2luZG93c0Vycm9yLCBXaW5kb3dzRXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAgICBXaW5kb3dzRXJyb3JfZGVhbGxvYywgMCwgV2luZG93c0Vycm9yX21lbWJlcnMsCisgICAgICAgICAgICAgICAgICAgICAgICBXaW5kb3dzRXJyb3Jfc3RyLCAiTVMtV2luZG93cyBPUyBzeXN0ZW0gY2FsbCBmYWlsZWQuIik7CisKKyNlbmRpZiAvKiBNU19XSU5ET1dTICovCisKKworLyoKKyAqICAgIFZNU0Vycm9yIGV4dGVuZHMgT1NFcnJvciAoSSB0aGluaykKKyAqLworI2lmZGVmIF9fVk1TCitNaWRkbGluZ0V4dGVuZHNFeGNlcHRpb24oUHlFeGNfT1NFcnJvciwgVk1TRXJyb3IsIEVudmlyb25tZW50RXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgIk9wZW5WTVMgT1Mgc3lzdGVtIGNhbGwgZmFpbGVkLiIpOworI2VuZGlmCisKKworLyoKKyAqICAgIEVPRkVycm9yIGV4dGVuZHMgU3RhbmRhcmRFcnJvcgorICovCitTaW1wbGVFeHRlbmRzRXhjZXB0aW9uKFB5RXhjX1N0YW5kYXJkRXJyb3IsIEVPRkVycm9yLAorICAgICAgICAgICAgICAgICAgICAgICAiUmVhZCBiZXlvbmQgZW5kIG9mIGZpbGUuIik7CisKKworLyoKKyAqICAgIFJ1bnRpbWVFcnJvciBleHRlbmRzIFN0YW5kYXJkRXJyb3IKKyAqLworU2ltcGxlRXh0ZW5kc0V4Y2VwdGlvbihQeUV4Y19TdGFuZGFyZEVycm9yLCBSdW50aW1lRXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAgICJVbnNwZWNpZmllZCBydW4tdGltZSBlcnJvci4iKTsKKworCisvKgorICogICAgTm90SW1wbGVtZW50ZWRFcnJvciBleHRlbmRzIFJ1bnRpbWVFcnJvcgorICovCitTaW1wbGVFeHRlbmRzRXhjZXB0aW9uKFB5RXhjX1J1bnRpbWVFcnJvciwgTm90SW1wbGVtZW50ZWRFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICAgIk1ldGhvZCBvciBmdW5jdGlvbiBoYXNuJ3QgYmVlbiBpbXBsZW1lbnRlZCB5ZXQuIik7CisKKy8qCisgKiAgICBOYW1lRXJyb3IgZXh0ZW5kcyBTdGFuZGFyZEVycm9yCisgKi8KK1NpbXBsZUV4dGVuZHNFeGNlcHRpb24oUHlFeGNfU3RhbmRhcmRFcnJvciwgTmFtZUVycm9yLAorICAgICAgICAgICAgICAgICAgICAgICAiTmFtZSBub3QgZm91bmQgZ2xvYmFsbHkuIik7CisKKy8qCisgKiAgICBVbmJvdW5kTG9jYWxFcnJvciBleHRlbmRzIE5hbWVFcnJvcgorICovCitTaW1wbGVFeHRlbmRzRXhjZXB0aW9uKFB5RXhjX05hbWVFcnJvciwgVW5ib3VuZExvY2FsRXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAgICJMb2NhbCBuYW1lIHJlZmVyZW5jZWQgYnV0IG5vdCBib3VuZCB0byBhIHZhbHVlLiIpOworCisvKgorICogICAgQXR0cmlidXRlRXJyb3IgZXh0ZW5kcyBTdGFuZGFyZEVycm9yCisgKi8KK1NpbXBsZUV4dGVuZHNFeGNlcHRpb24oUHlFeGNfU3RhbmRhcmRFcnJvciwgQXR0cmlidXRlRXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAgICJBdHRyaWJ1dGUgbm90IGZvdW5kLiIpOworCisKKy8qCisgKiAgICBTeW50YXhFcnJvciBleHRlbmRzIFN0YW5kYXJkRXJyb3IKKyAqLworCitzdGF0aWMgaW50CitTeW50YXhFcnJvcl9pbml0KFB5U3ludGF4RXJyb3JPYmplY3QgKnNlbGYsIFB5T2JqZWN0ICphcmdzLCBQeU9iamVjdCAqa3dkcykKK3sKKyAgICBQeU9iamVjdCAqaW5mbyA9IE5VTEw7CisgICAgUHlfc3NpemVfdCBsZW5hcmdzID0gUHlUdXBsZV9HRVRfU0laRShhcmdzKTsKKworICAgIGlmIChCYXNlRXhjZXB0aW9uX2luaXQoKFB5QmFzZUV4Y2VwdGlvbk9iamVjdCAqKXNlbGYsIGFyZ3MsIGt3ZHMpID09IC0xKQorICAgICAgICByZXR1cm4gLTE7CisKKyAgICBpZiAobGVuYXJncyA+PSAxKSB7CisgICAgICAgIFB5X0NMRUFSKHNlbGYtPm1zZyk7CisgICAgICAgIHNlbGYtPm1zZyA9IFB5VHVwbGVfR0VUX0lURU0oYXJncywgMCk7CisgICAgICAgIFB5X0lOQ1JFRihzZWxmLT5tc2cpOworICAgIH0KKyAgICBpZiAobGVuYXJncyA9PSAyKSB7CisgICAgICAgIGluZm8gPSBQeVR1cGxlX0dFVF9JVEVNKGFyZ3MsIDEpOworICAgICAgICBpbmZvID0gUHlTZXF1ZW5jZV9UdXBsZShpbmZvKTsKKyAgICAgICAgaWYgKCFpbmZvKQorICAgICAgICAgICAgcmV0dXJuIC0xOworCisgICAgICAgIGlmIChQeVR1cGxlX0dFVF9TSVpFKGluZm8pICE9IDQpIHsKKyAgICAgICAgICAgIC8qIG5vdCBhIHZlcnkgZ29vZCBlcnJvciBtZXNzYWdlLCBidXQgaXQncyB3aGF0IFB5dGhvbiAyLjQgZ2l2ZXMgKi8KKyAgICAgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19JbmRleEVycm9yLCAidHVwbGUgaW5kZXggb3V0IG9mIHJhbmdlIik7CisgICAgICAgICAgICBQeV9ERUNSRUYoaW5mbyk7CisgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgIH0KKworICAgICAgICBQeV9DTEVBUihzZWxmLT5maWxlbmFtZSk7CisgICAgICAgIHNlbGYtPmZpbGVuYW1lID0gUHlUdXBsZV9HRVRfSVRFTShpbmZvLCAwKTsKKyAgICAgICAgUHlfSU5DUkVGKHNlbGYtPmZpbGVuYW1lKTsKKworICAgICAgICBQeV9DTEVBUihzZWxmLT5saW5lbm8pOworICAgICAgICBzZWxmLT5saW5lbm8gPSBQeVR1cGxlX0dFVF9JVEVNKGluZm8sIDEpOworICAgICAgICBQeV9JTkNSRUYoc2VsZi0+bGluZW5vKTsKKworICAgICAgICBQeV9DTEVBUihzZWxmLT5vZmZzZXQpOworICAgICAgICBzZWxmLT5vZmZzZXQgPSBQeVR1cGxlX0dFVF9JVEVNKGluZm8sIDIpOworICAgICAgICBQeV9JTkNSRUYoc2VsZi0+b2Zmc2V0KTsKKworICAgICAgICBQeV9DTEVBUihzZWxmLT50ZXh0KTsKKyAgICAgICAgc2VsZi0+dGV4dCA9IFB5VHVwbGVfR0VUX0lURU0oaW5mbywgMyk7CisgICAgICAgIFB5X0lOQ1JFRihzZWxmLT50ZXh0KTsKKworICAgICAgICBQeV9ERUNSRUYoaW5mbyk7CisgICAgfQorICAgIHJldHVybiAwOworfQorCitzdGF0aWMgaW50CitTeW50YXhFcnJvcl9jbGVhcihQeVN5bnRheEVycm9yT2JqZWN0ICpzZWxmKQoreworICAgIFB5X0NMRUFSKHNlbGYtPm1zZyk7CisgICAgUHlfQ0xFQVIoc2VsZi0+ZmlsZW5hbWUpOworICAgIFB5X0NMRUFSKHNlbGYtPmxpbmVubyk7CisgICAgUHlfQ0xFQVIoc2VsZi0+b2Zmc2V0KTsKKyAgICBQeV9DTEVBUihzZWxmLT50ZXh0KTsKKyAgICBQeV9DTEVBUihzZWxmLT5wcmludF9maWxlX2FuZF9saW5lKTsKKyAgICByZXR1cm4gQmFzZUV4Y2VwdGlvbl9jbGVhcigoUHlCYXNlRXhjZXB0aW9uT2JqZWN0ICopc2VsZik7Cit9CisKK3N0YXRpYyB2b2lkCitTeW50YXhFcnJvcl9kZWFsbG9jKFB5U3ludGF4RXJyb3JPYmplY3QgKnNlbGYpCit7CisgICAgX1B5T2JqZWN0X0dDX1VOVFJBQ0soc2VsZik7CisgICAgU3ludGF4RXJyb3JfY2xlYXIoc2VsZik7CisgICAgUHlfVFlQRShzZWxmKS0+dHBfZnJlZSgoUHlPYmplY3QgKilzZWxmKTsKK30KKworc3RhdGljIGludAorU3ludGF4RXJyb3JfdHJhdmVyc2UoUHlTeW50YXhFcnJvck9iamVjdCAqc2VsZiwgdmlzaXRwcm9jIHZpc2l0LCB2b2lkICphcmcpCit7CisgICAgUHlfVklTSVQoc2VsZi0+bXNnKTsKKyAgICBQeV9WSVNJVChzZWxmLT5maWxlbmFtZSk7CisgICAgUHlfVklTSVQoc2VsZi0+bGluZW5vKTsKKyAgICBQeV9WSVNJVChzZWxmLT5vZmZzZXQpOworICAgIFB5X1ZJU0lUKHNlbGYtPnRleHQpOworICAgIFB5X1ZJU0lUKHNlbGYtPnByaW50X2ZpbGVfYW5kX2xpbmUpOworICAgIHJldHVybiBCYXNlRXhjZXB0aW9uX3RyYXZlcnNlKChQeUJhc2VFeGNlcHRpb25PYmplY3QgKilzZWxmLCB2aXNpdCwgYXJnKTsKK30KKworLyogVGhpcyBpcyBjYWxsZWQgIm15X2Jhc2VuYW1lIiBpbnN0ZWFkIG9mIGp1c3QgImJhc2VuYW1lIiB0byBhdm9pZCBuYW1lCisgICBjb25mbGljdHMgd2l0aCBnbGliYzsgYmFzZW5hbWUgaXMgYWxyZWFkeSBwcm90b3R5cGVkIGlmIF9HTlVfU09VUkNFIGlzCisgICBkZWZpbmVkLCBhbmQgUHl0aG9uIGRvZXMgZGVmaW5lIHRoYXQuICovCitzdGF0aWMgY2hhciAqCitteV9iYXNlbmFtZShjaGFyICpuYW1lKQoreworICAgIGNoYXIgKmNwID0gbmFtZTsKKyAgICBjaGFyICpyZXN1bHQgPSBuYW1lOworCisgICAgaWYgKG5hbWUgPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuICI/Pz8iOworICAgIHdoaWxlICgqY3AgIT0gJ1wwJykgeworICAgICAgICBpZiAoKmNwID09IFNFUCkKKyAgICAgICAgICAgIHJlc3VsdCA9IGNwICsgMTsKKyAgICAgICAgKytjcDsKKyAgICB9CisgICAgcmV0dXJuIHJlc3VsdDsKK30KKworCitzdGF0aWMgUHlPYmplY3QgKgorU3ludGF4RXJyb3Jfc3RyKFB5U3ludGF4RXJyb3JPYmplY3QgKnNlbGYpCit7CisgICAgUHlPYmplY3QgKnN0cjsKKyAgICBQeU9iamVjdCAqcmVzdWx0OworICAgIGludCBoYXZlX2ZpbGVuYW1lID0gMDsKKyAgICBpbnQgaGF2ZV9saW5lbm8gPSAwOworICAgIGNoYXIgKmJ1ZmZlciA9IE5VTEw7CisgICAgUHlfc3NpemVfdCBidWZzaXplOworCisgICAgaWYgKHNlbGYtPm1zZykKKyAgICAgICAgc3RyID0gUHlPYmplY3RfU3RyKHNlbGYtPm1zZyk7CisgICAgZWxzZQorICAgICAgICBzdHIgPSBQeU9iamVjdF9TdHIoUHlfTm9uZSk7CisgICAgaWYgKCFzdHIpCisgICAgICAgIHJldHVybiBOVUxMOworICAgIC8qIERvbid0IGZpZGRsZSB3aXRoIG5vbi1zdHJpbmcgcmV0dXJuIChzaG91bGRuJ3QgaGFwcGVuIGFueXdheSkgKi8KKyAgICBpZiAoIVB5U3RyaW5nX0NoZWNrKHN0cikpCisgICAgICAgIHJldHVybiBzdHI7CisKKyAgICAvKiBYWFggLS0gZG8gYWxsIHRoZSBhZGRpdGlvbmFsIGZvcm1hdHRpbmcgd2l0aCBmaWxlbmFtZSBhbmQKKyAgICAgICBsaW5lbm8gaGVyZSAqLworCisgICAgaGF2ZV9maWxlbmFtZSA9IChzZWxmLT5maWxlbmFtZSAhPSBOVUxMKSAmJgorICAgICAgICBQeVN0cmluZ19DaGVjayhzZWxmLT5maWxlbmFtZSk7CisgICAgaGF2ZV9saW5lbm8gPSAoc2VsZi0+bGluZW5vICE9IE5VTEwpICYmIFB5SW50X0NoZWNrKHNlbGYtPmxpbmVubyk7CisKKyAgICBpZiAoIWhhdmVfZmlsZW5hbWUgJiYgIWhhdmVfbGluZW5vKQorICAgICAgICByZXR1cm4gc3RyOworCisgICAgYnVmc2l6ZSA9IFB5U3RyaW5nX0dFVF9TSVpFKHN0cikgKyA2NDsKKyAgICBpZiAoaGF2ZV9maWxlbmFtZSkKKyAgICAgICAgYnVmc2l6ZSArPSBQeVN0cmluZ19HRVRfU0laRShzZWxmLT5maWxlbmFtZSk7CisKKyAgICBidWZmZXIgPSBQeU1lbV9NQUxMT0MoYnVmc2l6ZSk7CisgICAgaWYgKGJ1ZmZlciA9PSBOVUxMKQorICAgICAgICByZXR1cm4gc3RyOworCisgICAgaWYgKGhhdmVfZmlsZW5hbWUgJiYgaGF2ZV9saW5lbm8pCisgICAgICAgIFB5T1Nfc25wcmludGYoYnVmZmVyLCBidWZzaXplLCAiJXMgKCVzLCBsaW5lICVsZCkiLAorICAgICAgICAgICAgUHlTdHJpbmdfQVNfU1RSSU5HKHN0ciksCisgICAgICAgICAgICBteV9iYXNlbmFtZShQeVN0cmluZ19BU19TVFJJTkcoc2VsZi0+ZmlsZW5hbWUpKSwKKyAgICAgICAgICAgIFB5SW50X0FzTG9uZyhzZWxmLT5saW5lbm8pKTsKKyAgICBlbHNlIGlmIChoYXZlX2ZpbGVuYW1lKQorICAgICAgICBQeU9TX3NucHJpbnRmKGJ1ZmZlciwgYnVmc2l6ZSwgIiVzICglcykiLAorICAgICAgICAgICAgUHlTdHJpbmdfQVNfU1RSSU5HKHN0ciksCisgICAgICAgICAgICBteV9iYXNlbmFtZShQeVN0cmluZ19BU19TVFJJTkcoc2VsZi0+ZmlsZW5hbWUpKSk7CisgICAgZWxzZSAvKiBvbmx5IGhhdmVfbGluZW5vICovCisgICAgICAgIFB5T1Nfc25wcmludGYoYnVmZmVyLCBidWZzaXplLCAiJXMgKGxpbmUgJWxkKSIsCisgICAgICAgICAgICBQeVN0cmluZ19BU19TVFJJTkcoc3RyKSwKKyAgICAgICAgICAgIFB5SW50X0FzTG9uZyhzZWxmLT5saW5lbm8pKTsKKworICAgIHJlc3VsdCA9IFB5U3RyaW5nX0Zyb21TdHJpbmcoYnVmZmVyKTsKKyAgICBQeU1lbV9GUkVFKGJ1ZmZlcik7CisKKyAgICBpZiAocmVzdWx0ID09IE5VTEwpCisgICAgICAgIHJlc3VsdCA9IHN0cjsKKyAgICBlbHNlCisgICAgICAgIFB5X0RFQ1JFRihzdHIpOworICAgIHJldHVybiByZXN1bHQ7Cit9CisKK3N0YXRpYyBQeU1lbWJlckRlZiBTeW50YXhFcnJvcl9tZW1iZXJzW10gPSB7CisgICAgeyJtc2ciLCBUX09CSkVDVCwgb2Zmc2V0b2YoUHlTeW50YXhFcnJvck9iamVjdCwgbXNnKSwgMCwKKyAgICAgICAgUHlEb2NfU1RSKCJleGNlcHRpb24gbXNnIil9LAorICAgIHsiZmlsZW5hbWUiLCBUX09CSkVDVCwgb2Zmc2V0b2YoUHlTeW50YXhFcnJvck9iamVjdCwgZmlsZW5hbWUpLCAwLAorICAgICAgICBQeURvY19TVFIoImV4Y2VwdGlvbiBmaWxlbmFtZSIpfSwKKyAgICB7ImxpbmVubyIsIFRfT0JKRUNULCBvZmZzZXRvZihQeVN5bnRheEVycm9yT2JqZWN0LCBsaW5lbm8pLCAwLAorICAgICAgICBQeURvY19TVFIoImV4Y2VwdGlvbiBsaW5lbm8iKX0sCisgICAgeyJvZmZzZXQiLCBUX09CSkVDVCwgb2Zmc2V0b2YoUHlTeW50YXhFcnJvck9iamVjdCwgb2Zmc2V0KSwgMCwKKyAgICAgICAgUHlEb2NfU1RSKCJleGNlcHRpb24gb2Zmc2V0Iil9LAorICAgIHsidGV4dCIsIFRfT0JKRUNULCBvZmZzZXRvZihQeVN5bnRheEVycm9yT2JqZWN0LCB0ZXh0KSwgMCwKKyAgICAgICAgUHlEb2NfU1RSKCJleGNlcHRpb24gdGV4dCIpfSwKKyAgICB7InByaW50X2ZpbGVfYW5kX2xpbmUiLCBUX09CSkVDVCwKKyAgICAgICAgb2Zmc2V0b2YoUHlTeW50YXhFcnJvck9iamVjdCwgcHJpbnRfZmlsZV9hbmRfbGluZSksIDAsCisgICAgICAgIFB5RG9jX1NUUigiZXhjZXB0aW9uIHByaW50X2ZpbGVfYW5kX2xpbmUiKX0sCisgICAge05VTEx9ICAvKiBTZW50aW5lbCAqLworfTsKKworQ29tcGxleEV4dGVuZHNFeGNlcHRpb24oUHlFeGNfU3RhbmRhcmRFcnJvciwgU3ludGF4RXJyb3IsIFN5bnRheEVycm9yLAorICAgICAgICAgICAgICAgICAgICAgICAgU3ludGF4RXJyb3JfZGVhbGxvYywgMCwgU3ludGF4RXJyb3JfbWVtYmVycywKKyAgICAgICAgICAgICAgICAgICAgICAgIFN5bnRheEVycm9yX3N0ciwgIkludmFsaWQgc3ludGF4LiIpOworCisKKy8qCisgKiAgICBJbmRlbnRhdGlvbkVycm9yIGV4dGVuZHMgU3ludGF4RXJyb3IKKyAqLworTWlkZGxpbmdFeHRlbmRzRXhjZXB0aW9uKFB5RXhjX1N5bnRheEVycm9yLCBJbmRlbnRhdGlvbkVycm9yLCBTeW50YXhFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAiSW1wcm9wZXIgaW5kZW50YXRpb24uIik7CisKKworLyoKKyAqICAgIFRhYkVycm9yIGV4dGVuZHMgSW5kZW50YXRpb25FcnJvcgorICovCitNaWRkbGluZ0V4dGVuZHNFeGNlcHRpb24oUHlFeGNfSW5kZW50YXRpb25FcnJvciwgVGFiRXJyb3IsIFN5bnRheEVycm9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICJJbXByb3BlciBtaXh0dXJlIG9mIHNwYWNlcyBhbmQgdGFicy4iKTsKKworCisvKgorICogICAgTG9va3VwRXJyb3IgZXh0ZW5kcyBTdGFuZGFyZEVycm9yCisgKi8KK1NpbXBsZUV4dGVuZHNFeGNlcHRpb24oUHlFeGNfU3RhbmRhcmRFcnJvciwgTG9va3VwRXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAgICJCYXNlIGNsYXNzIGZvciBsb29rdXAgZXJyb3JzLiIpOworCisKKy8qCisgKiAgICBJbmRleEVycm9yIGV4dGVuZHMgTG9va3VwRXJyb3IKKyAqLworU2ltcGxlRXh0ZW5kc0V4Y2VwdGlvbihQeUV4Y19Mb29rdXBFcnJvciwgSW5kZXhFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICAgIlNlcXVlbmNlIGluZGV4IG91dCBvZiByYW5nZS4iKTsKKworCisvKgorICogICAgS2V5RXJyb3IgZXh0ZW5kcyBMb29rdXBFcnJvcgorICovCitzdGF0aWMgUHlPYmplY3QgKgorS2V5RXJyb3Jfc3RyKFB5QmFzZUV4Y2VwdGlvbk9iamVjdCAqc2VsZikKK3sKKyAgICAvKiBJZiBhcmdzIGlzIGEgdHVwbGUgb2YgZXhhY3RseSBvbmUgaXRlbSwgYXBwbHkgcmVwciB0byBhcmdzWzBdLgorICAgICAgIFRoaXMgaXMgZG9uZSBzbyB0aGF0IGUuZy4gdGhlIGV4Y2VwdGlvbiByYWlzZWQgYnkge31bJyddIHByaW50cworICAgICAgICAgS2V5RXJyb3I6ICcnCisgICAgICAgcmF0aGVyIHRoYW4gdGhlIGNvbmZ1c2luZworICAgICAgICAgS2V5RXJyb3IKKyAgICAgICBhbG9uZS4gIFRoZSBkb3duc2lkZSBpcyB0aGF0IGlmIEtleUVycm9yIGlzIHJhaXNlZCB3aXRoIGFuIGV4cGxhbmF0b3J5CisgICAgICAgc3RyaW5nLCB0aGF0IHN0cmluZyB3aWxsIGJlIGRpc3BsYXllZCBpbiBxdW90ZXMuICBUb28gYmFkLgorICAgICAgIElmIGFyZ3MgaXMgYW55dGhpbmcgZWxzZSwgdXNlIHRoZSBkZWZhdWx0IEJhc2VFeGNlcHRpb25fX3N0cl9fKCkuCisgICAgKi8KKyAgICBpZiAoUHlUdXBsZV9HRVRfU0laRShzZWxmLT5hcmdzKSA9PSAxKSB7CisgICAgICAgIHJldHVybiBQeU9iamVjdF9SZXByKFB5VHVwbGVfR0VUX0lURU0oc2VsZi0+YXJncywgMCkpOworICAgIH0KKyAgICByZXR1cm4gQmFzZUV4Y2VwdGlvbl9zdHIoc2VsZik7Cit9CisKK0NvbXBsZXhFeHRlbmRzRXhjZXB0aW9uKFB5RXhjX0xvb2t1cEVycm9yLCBLZXlFcnJvciwgQmFzZUV4Y2VwdGlvbiwKKyAgICAgICAgICAgICAgICAgICAgICAgIDAsIDAsIDAsIEtleUVycm9yX3N0ciwgIk1hcHBpbmcga2V5IG5vdCBmb3VuZC4iKTsKKworCisvKgorICogICAgVmFsdWVFcnJvciBleHRlbmRzIFN0YW5kYXJkRXJyb3IKKyAqLworU2ltcGxlRXh0ZW5kc0V4Y2VwdGlvbihQeUV4Y19TdGFuZGFyZEVycm9yLCBWYWx1ZUVycm9yLAorICAgICAgICAgICAgICAgICAgICAgICAiSW5hcHByb3ByaWF0ZSBhcmd1bWVudCB2YWx1ZSAob2YgY29ycmVjdCB0eXBlKS4iKTsKKworLyoKKyAqICAgIFVuaWNvZGVFcnJvciBleHRlbmRzIFZhbHVlRXJyb3IKKyAqLworCitTaW1wbGVFeHRlbmRzRXhjZXB0aW9uKFB5RXhjX1ZhbHVlRXJyb3IsIFVuaWNvZGVFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICAgIlVuaWNvZGUgcmVsYXRlZCBlcnJvci4iKTsKKworI2lmZGVmIFB5X1VTSU5HX1VOSUNPREUKK3N0YXRpYyBQeU9iamVjdCAqCitnZXRfc3RyaW5nKFB5T2JqZWN0ICphdHRyLCBjb25zdCBjaGFyICpuYW1lKQoreworICAgIGlmICghYXR0cikgeworICAgICAgICBQeUVycl9Gb3JtYXQoUHlFeGNfVHlwZUVycm9yLCAiJS4yMDBzIGF0dHJpYnV0ZSBub3Qgc2V0IiwgbmFtZSk7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKworICAgIGlmICghUHlTdHJpbmdfQ2hlY2soYXR0cikpIHsKKyAgICAgICAgUHlFcnJfRm9ybWF0KFB5RXhjX1R5cGVFcnJvciwgIiUuMjAwcyBhdHRyaWJ1dGUgbXVzdCBiZSBzdHIiLCBuYW1lKTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIFB5X0lOQ1JFRihhdHRyKTsKKyAgICByZXR1cm4gYXR0cjsKK30KKworCitzdGF0aWMgaW50CitzZXRfc3RyaW5nKFB5T2JqZWN0ICoqYXR0ciwgY29uc3QgY2hhciAqdmFsdWUpCit7CisgICAgUHlPYmplY3QgKm9iaiA9IFB5U3RyaW5nX0Zyb21TdHJpbmcodmFsdWUpOworICAgIGlmICghb2JqKQorICAgICAgICByZXR1cm4gLTE7CisgICAgUHlfQ0xFQVIoKmF0dHIpOworICAgICphdHRyID0gb2JqOworICAgIHJldHVybiAwOworfQorCisKK3N0YXRpYyBQeU9iamVjdCAqCitnZXRfdW5pY29kZShQeU9iamVjdCAqYXR0ciwgY29uc3QgY2hhciAqbmFtZSkKK3sKKyAgICBpZiAoIWF0dHIpIHsKKyAgICAgICAgUHlFcnJfRm9ybWF0KFB5RXhjX1R5cGVFcnJvciwgIiUuMjAwcyBhdHRyaWJ1dGUgbm90IHNldCIsIG5hbWUpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisKKyAgICBpZiAoIVB5VW5pY29kZV9DaGVjayhhdHRyKSkgeworICAgICAgICBQeUVycl9Gb3JtYXQoUHlFeGNfVHlwZUVycm9yLAorICAgICAgICAgICAgICAgICAgICAgIiUuMjAwcyBhdHRyaWJ1dGUgbXVzdCBiZSB1bmljb2RlIiwgbmFtZSk7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICBQeV9JTkNSRUYoYXR0cik7CisgICAgcmV0dXJuIGF0dHI7Cit9CisKK1B5T2JqZWN0ICoKK1B5VW5pY29kZUVuY29kZUVycm9yX0dldEVuY29kaW5nKFB5T2JqZWN0ICpleGMpCit7CisgICAgcmV0dXJuIGdldF9zdHJpbmcoKChQeVVuaWNvZGVFcnJvck9iamVjdCAqKWV4YyktPmVuY29kaW5nLCAiZW5jb2RpbmciKTsKK30KKworUHlPYmplY3QgKgorUHlVbmljb2RlRGVjb2RlRXJyb3JfR2V0RW5jb2RpbmcoUHlPYmplY3QgKmV4YykKK3sKKyAgICByZXR1cm4gZ2V0X3N0cmluZygoKFB5VW5pY29kZUVycm9yT2JqZWN0ICopZXhjKS0+ZW5jb2RpbmcsICJlbmNvZGluZyIpOworfQorCitQeU9iamVjdCAqCitQeVVuaWNvZGVFbmNvZGVFcnJvcl9HZXRPYmplY3QoUHlPYmplY3QgKmV4YykKK3sKKyAgICByZXR1cm4gZ2V0X3VuaWNvZGUoKChQeVVuaWNvZGVFcnJvck9iamVjdCAqKWV4YyktPm9iamVjdCwgIm9iamVjdCIpOworfQorCitQeU9iamVjdCAqCitQeVVuaWNvZGVEZWNvZGVFcnJvcl9HZXRPYmplY3QoUHlPYmplY3QgKmV4YykKK3sKKyAgICByZXR1cm4gZ2V0X3N0cmluZygoKFB5VW5pY29kZUVycm9yT2JqZWN0ICopZXhjKS0+b2JqZWN0LCAib2JqZWN0Iik7Cit9CisKK1B5T2JqZWN0ICoKK1B5VW5pY29kZVRyYW5zbGF0ZUVycm9yX0dldE9iamVjdChQeU9iamVjdCAqZXhjKQoreworICAgIHJldHVybiBnZXRfdW5pY29kZSgoKFB5VW5pY29kZUVycm9yT2JqZWN0ICopZXhjKS0+b2JqZWN0LCAib2JqZWN0Iik7Cit9CisKK2ludAorUHlVbmljb2RlRW5jb2RlRXJyb3JfR2V0U3RhcnQoUHlPYmplY3QgKmV4YywgUHlfc3NpemVfdCAqc3RhcnQpCit7CisgICAgUHlfc3NpemVfdCBzaXplOworICAgIFB5T2JqZWN0ICpvYmogPSBnZXRfdW5pY29kZSgoKFB5VW5pY29kZUVycm9yT2JqZWN0ICopZXhjKS0+b2JqZWN0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAib2JqZWN0Iik7CisgICAgaWYgKCFvYmopCisgICAgICAgIHJldHVybiAtMTsKKyAgICAqc3RhcnQgPSAoKFB5VW5pY29kZUVycm9yT2JqZWN0ICopZXhjKS0+c3RhcnQ7CisgICAgc2l6ZSA9IFB5VW5pY29kZV9HRVRfU0laRShvYmopOworICAgIGlmICgqc3RhcnQ8MCkKKyAgICAgICAgKnN0YXJ0ID0gMDsgLypYWFggY2hlY2sgZm9yIHZhbHVlcyA8MCovCisgICAgaWYgKCpzdGFydD49c2l6ZSkKKyAgICAgICAgKnN0YXJ0ID0gc2l6ZS0xOworICAgIFB5X0RFQ1JFRihvYmopOworICAgIHJldHVybiAwOworfQorCisKK2ludAorUHlVbmljb2RlRGVjb2RlRXJyb3JfR2V0U3RhcnQoUHlPYmplY3QgKmV4YywgUHlfc3NpemVfdCAqc3RhcnQpCit7CisgICAgUHlfc3NpemVfdCBzaXplOworICAgIFB5T2JqZWN0ICpvYmogPSBnZXRfc3RyaW5nKCgoUHlVbmljb2RlRXJyb3JPYmplY3QgKilleGMpLT5vYmplY3QsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIm9iamVjdCIpOworICAgIGlmICghb2JqKQorICAgICAgICByZXR1cm4gLTE7CisgICAgc2l6ZSA9IFB5U3RyaW5nX0dFVF9TSVpFKG9iaik7CisgICAgKnN0YXJ0ID0gKChQeVVuaWNvZGVFcnJvck9iamVjdCAqKWV4YyktPnN0YXJ0OworICAgIGlmICgqc3RhcnQ8MCkKKyAgICAgICAgKnN0YXJ0ID0gMDsKKyAgICBpZiAoKnN0YXJ0Pj1zaXplKQorICAgICAgICAqc3RhcnQgPSBzaXplLTE7CisgICAgUHlfREVDUkVGKG9iaik7CisgICAgcmV0dXJuIDA7Cit9CisKKworaW50CitQeVVuaWNvZGVUcmFuc2xhdGVFcnJvcl9HZXRTdGFydChQeU9iamVjdCAqZXhjLCBQeV9zc2l6ZV90ICpzdGFydCkKK3sKKyAgICByZXR1cm4gUHlVbmljb2RlRW5jb2RlRXJyb3JfR2V0U3RhcnQoZXhjLCBzdGFydCk7Cit9CisKKworaW50CitQeVVuaWNvZGVFbmNvZGVFcnJvcl9TZXRTdGFydChQeU9iamVjdCAqZXhjLCBQeV9zc2l6ZV90IHN0YXJ0KQoreworICAgICgoUHlVbmljb2RlRXJyb3JPYmplY3QgKilleGMpLT5zdGFydCA9IHN0YXJ0OworICAgIHJldHVybiAwOworfQorCisKK2ludAorUHlVbmljb2RlRGVjb2RlRXJyb3JfU2V0U3RhcnQoUHlPYmplY3QgKmV4YywgUHlfc3NpemVfdCBzdGFydCkKK3sKKyAgICAoKFB5VW5pY29kZUVycm9yT2JqZWN0ICopZXhjKS0+c3RhcnQgPSBzdGFydDsKKyAgICByZXR1cm4gMDsKK30KKworCitpbnQKK1B5VW5pY29kZVRyYW5zbGF0ZUVycm9yX1NldFN0YXJ0KFB5T2JqZWN0ICpleGMsIFB5X3NzaXplX3Qgc3RhcnQpCit7CisgICAgKChQeVVuaWNvZGVFcnJvck9iamVjdCAqKWV4YyktPnN0YXJ0ID0gc3RhcnQ7CisgICAgcmV0dXJuIDA7Cit9CisKKworaW50CitQeVVuaWNvZGVFbmNvZGVFcnJvcl9HZXRFbmQoUHlPYmplY3QgKmV4YywgUHlfc3NpemVfdCAqZW5kKQoreworICAgIFB5X3NzaXplX3Qgc2l6ZTsKKyAgICBQeU9iamVjdCAqb2JqID0gZ2V0X3VuaWNvZGUoKChQeVVuaWNvZGVFcnJvck9iamVjdCAqKWV4YyktPm9iamVjdCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIm9iamVjdCIpOworICAgIGlmICghb2JqKQorICAgICAgICByZXR1cm4gLTE7CisgICAgKmVuZCA9ICgoUHlVbmljb2RlRXJyb3JPYmplY3QgKilleGMpLT5lbmQ7CisgICAgc2l6ZSA9IFB5VW5pY29kZV9HRVRfU0laRShvYmopOworICAgIGlmICgqZW5kPDEpCisgICAgICAgICplbmQgPSAxOworICAgIGlmICgqZW5kPnNpemUpCisgICAgICAgICplbmQgPSBzaXplOworICAgIFB5X0RFQ1JFRihvYmopOworICAgIHJldHVybiAwOworfQorCisKK2ludAorUHlVbmljb2RlRGVjb2RlRXJyb3JfR2V0RW5kKFB5T2JqZWN0ICpleGMsIFB5X3NzaXplX3QgKmVuZCkKK3sKKyAgICBQeV9zc2l6ZV90IHNpemU7CisgICAgUHlPYmplY3QgKm9iaiA9IGdldF9zdHJpbmcoKChQeVVuaWNvZGVFcnJvck9iamVjdCAqKWV4YyktPm9iamVjdCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAib2JqZWN0Iik7CisgICAgaWYgKCFvYmopCisgICAgICAgIHJldHVybiAtMTsKKyAgICAqZW5kID0gKChQeVVuaWNvZGVFcnJvck9iamVjdCAqKWV4YyktPmVuZDsKKyAgICBzaXplID0gUHlTdHJpbmdfR0VUX1NJWkUob2JqKTsKKyAgICBpZiAoKmVuZDwxKQorICAgICAgICAqZW5kID0gMTsKKyAgICBpZiAoKmVuZD5zaXplKQorICAgICAgICAqZW5kID0gc2l6ZTsKKyAgICBQeV9ERUNSRUYob2JqKTsKKyAgICByZXR1cm4gMDsKK30KKworCitpbnQKK1B5VW5pY29kZVRyYW5zbGF0ZUVycm9yX0dldEVuZChQeU9iamVjdCAqZXhjLCBQeV9zc2l6ZV90ICpzdGFydCkKK3sKKyAgICByZXR1cm4gUHlVbmljb2RlRW5jb2RlRXJyb3JfR2V0RW5kKGV4Yywgc3RhcnQpOworfQorCisKK2ludAorUHlVbmljb2RlRW5jb2RlRXJyb3JfU2V0RW5kKFB5T2JqZWN0ICpleGMsIFB5X3NzaXplX3QgZW5kKQoreworICAgICgoUHlVbmljb2RlRXJyb3JPYmplY3QgKilleGMpLT5lbmQgPSBlbmQ7CisgICAgcmV0dXJuIDA7Cit9CisKKworaW50CitQeVVuaWNvZGVEZWNvZGVFcnJvcl9TZXRFbmQoUHlPYmplY3QgKmV4YywgUHlfc3NpemVfdCBlbmQpCit7CisgICAgKChQeVVuaWNvZGVFcnJvck9iamVjdCAqKWV4YyktPmVuZCA9IGVuZDsKKyAgICByZXR1cm4gMDsKK30KKworCitpbnQKK1B5VW5pY29kZVRyYW5zbGF0ZUVycm9yX1NldEVuZChQeU9iamVjdCAqZXhjLCBQeV9zc2l6ZV90IGVuZCkKK3sKKyAgICAoKFB5VW5pY29kZUVycm9yT2JqZWN0ICopZXhjKS0+ZW5kID0gZW5kOworICAgIHJldHVybiAwOworfQorCitQeU9iamVjdCAqCitQeVVuaWNvZGVFbmNvZGVFcnJvcl9HZXRSZWFzb24oUHlPYmplY3QgKmV4YykKK3sKKyAgICByZXR1cm4gZ2V0X3N0cmluZygoKFB5VW5pY29kZUVycm9yT2JqZWN0ICopZXhjKS0+cmVhc29uLCAicmVhc29uIik7Cit9CisKKworUHlPYmplY3QgKgorUHlVbmljb2RlRGVjb2RlRXJyb3JfR2V0UmVhc29uKFB5T2JqZWN0ICpleGMpCit7CisgICAgcmV0dXJuIGdldF9zdHJpbmcoKChQeVVuaWNvZGVFcnJvck9iamVjdCAqKWV4YyktPnJlYXNvbiwgInJlYXNvbiIpOworfQorCisKK1B5T2JqZWN0ICoKK1B5VW5pY29kZVRyYW5zbGF0ZUVycm9yX0dldFJlYXNvbihQeU9iamVjdCAqZXhjKQoreworICAgIHJldHVybiBnZXRfc3RyaW5nKCgoUHlVbmljb2RlRXJyb3JPYmplY3QgKilleGMpLT5yZWFzb24sICJyZWFzb24iKTsKK30KKworCitpbnQKK1B5VW5pY29kZUVuY29kZUVycm9yX1NldFJlYXNvbihQeU9iamVjdCAqZXhjLCBjb25zdCBjaGFyICpyZWFzb24pCit7CisgICAgcmV0dXJuIHNldF9zdHJpbmcoJigoUHlVbmljb2RlRXJyb3JPYmplY3QgKilleGMpLT5yZWFzb24sIHJlYXNvbik7Cit9CisKKworaW50CitQeVVuaWNvZGVEZWNvZGVFcnJvcl9TZXRSZWFzb24oUHlPYmplY3QgKmV4YywgY29uc3QgY2hhciAqcmVhc29uKQoreworICAgIHJldHVybiBzZXRfc3RyaW5nKCYoKFB5VW5pY29kZUVycm9yT2JqZWN0ICopZXhjKS0+cmVhc29uLCByZWFzb24pOworfQorCisKK2ludAorUHlVbmljb2RlVHJhbnNsYXRlRXJyb3JfU2V0UmVhc29uKFB5T2JqZWN0ICpleGMsIGNvbnN0IGNoYXIgKnJlYXNvbikKK3sKKyAgICByZXR1cm4gc2V0X3N0cmluZygmKChQeVVuaWNvZGVFcnJvck9iamVjdCAqKWV4YyktPnJlYXNvbiwgcmVhc29uKTsKK30KKworCitzdGF0aWMgaW50CitVbmljb2RlRXJyb3JfaW5pdChQeVVuaWNvZGVFcnJvck9iamVjdCAqc2VsZiwgUHlPYmplY3QgKmFyZ3MsIFB5T2JqZWN0ICprd2RzLAorICAgICAgICAgICAgICAgICAgUHlUeXBlT2JqZWN0ICpvYmplY3R0eXBlKQoreworICAgIFB5X0NMRUFSKHNlbGYtPmVuY29kaW5nKTsKKyAgICBQeV9DTEVBUihzZWxmLT5vYmplY3QpOworICAgIFB5X0NMRUFSKHNlbGYtPnJlYXNvbik7CisKKyAgICBpZiAoIVB5QXJnX1BhcnNlVHVwbGUoYXJncywgIk8hTyFubk8hIiwKKyAgICAgICAgJlB5U3RyaW5nX1R5cGUsICZzZWxmLT5lbmNvZGluZywKKyAgICAgICAgb2JqZWN0dHlwZSwgJnNlbGYtPm9iamVjdCwKKyAgICAgICAgJnNlbGYtPnN0YXJ0LAorICAgICAgICAmc2VsZi0+ZW5kLAorICAgICAgICAmUHlTdHJpbmdfVHlwZSwgJnNlbGYtPnJlYXNvbikpIHsKKyAgICAgICAgc2VsZi0+ZW5jb2RpbmcgPSBzZWxmLT5vYmplY3QgPSBzZWxmLT5yZWFzb24gPSBOVUxMOworICAgICAgICByZXR1cm4gLTE7CisgICAgfQorCisgICAgUHlfSU5DUkVGKHNlbGYtPmVuY29kaW5nKTsKKyAgICBQeV9JTkNSRUYoc2VsZi0+b2JqZWN0KTsKKyAgICBQeV9JTkNSRUYoc2VsZi0+cmVhc29uKTsKKworICAgIHJldHVybiAwOworfQorCitzdGF0aWMgaW50CitVbmljb2RlRXJyb3JfY2xlYXIoUHlVbmljb2RlRXJyb3JPYmplY3QgKnNlbGYpCit7CisgICAgUHlfQ0xFQVIoc2VsZi0+ZW5jb2RpbmcpOworICAgIFB5X0NMRUFSKHNlbGYtPm9iamVjdCk7CisgICAgUHlfQ0xFQVIoc2VsZi0+cmVhc29uKTsKKyAgICByZXR1cm4gQmFzZUV4Y2VwdGlvbl9jbGVhcigoUHlCYXNlRXhjZXB0aW9uT2JqZWN0ICopc2VsZik7Cit9CisKK3N0YXRpYyB2b2lkCitVbmljb2RlRXJyb3JfZGVhbGxvYyhQeVVuaWNvZGVFcnJvck9iamVjdCAqc2VsZikKK3sKKyAgICBfUHlPYmplY3RfR0NfVU5UUkFDSyhzZWxmKTsKKyAgICBVbmljb2RlRXJyb3JfY2xlYXIoc2VsZik7CisgICAgUHlfVFlQRShzZWxmKS0+dHBfZnJlZSgoUHlPYmplY3QgKilzZWxmKTsKK30KKworc3RhdGljIGludAorVW5pY29kZUVycm9yX3RyYXZlcnNlKFB5VW5pY29kZUVycm9yT2JqZWN0ICpzZWxmLCB2aXNpdHByb2MgdmlzaXQsIHZvaWQgKmFyZykKK3sKKyAgICBQeV9WSVNJVChzZWxmLT5lbmNvZGluZyk7CisgICAgUHlfVklTSVQoc2VsZi0+b2JqZWN0KTsKKyAgICBQeV9WSVNJVChzZWxmLT5yZWFzb24pOworICAgIHJldHVybiBCYXNlRXhjZXB0aW9uX3RyYXZlcnNlKChQeUJhc2VFeGNlcHRpb25PYmplY3QgKilzZWxmLCB2aXNpdCwgYXJnKTsKK30KKworc3RhdGljIFB5TWVtYmVyRGVmIFVuaWNvZGVFcnJvcl9tZW1iZXJzW10gPSB7CisgICAgeyJlbmNvZGluZyIsIFRfT0JKRUNULCBvZmZzZXRvZihQeVVuaWNvZGVFcnJvck9iamVjdCwgZW5jb2RpbmcpLCAwLAorICAgICAgICBQeURvY19TVFIoImV4Y2VwdGlvbiBlbmNvZGluZyIpfSwKKyAgICB7Im9iamVjdCIsIFRfT0JKRUNULCBvZmZzZXRvZihQeVVuaWNvZGVFcnJvck9iamVjdCwgb2JqZWN0KSwgMCwKKyAgICAgICAgUHlEb2NfU1RSKCJleGNlcHRpb24gb2JqZWN0Iil9LAorICAgIHsic3RhcnQiLCBUX1BZU1NJWkVULCBvZmZzZXRvZihQeVVuaWNvZGVFcnJvck9iamVjdCwgc3RhcnQpLCAwLAorICAgICAgICBQeURvY19TVFIoImV4Y2VwdGlvbiBzdGFydCIpfSwKKyAgICB7ImVuZCIsIFRfUFlTU0laRVQsIG9mZnNldG9mKFB5VW5pY29kZUVycm9yT2JqZWN0LCBlbmQpLCAwLAorICAgICAgICBQeURvY19TVFIoImV4Y2VwdGlvbiBlbmQiKX0sCisgICAgeyJyZWFzb24iLCBUX09CSkVDVCwgb2Zmc2V0b2YoUHlVbmljb2RlRXJyb3JPYmplY3QsIHJlYXNvbiksIDAsCisgICAgICAgIFB5RG9jX1NUUigiZXhjZXB0aW9uIHJlYXNvbiIpfSwKKyAgICB7TlVMTH0gIC8qIFNlbnRpbmVsICovCit9OworCisKKy8qCisgKiAgICBVbmljb2RlRW5jb2RlRXJyb3IgZXh0ZW5kcyBVbmljb2RlRXJyb3IKKyAqLworCitzdGF0aWMgaW50CitVbmljb2RlRW5jb2RlRXJyb3JfaW5pdChQeU9iamVjdCAqc2VsZiwgUHlPYmplY3QgKmFyZ3MsIFB5T2JqZWN0ICprd2RzKQoreworICAgIGlmIChCYXNlRXhjZXB0aW9uX2luaXQoKFB5QmFzZUV4Y2VwdGlvbk9iamVjdCAqKXNlbGYsIGFyZ3MsIGt3ZHMpID09IC0xKQorICAgICAgICByZXR1cm4gLTE7CisgICAgcmV0dXJuIFVuaWNvZGVFcnJvcl9pbml0KChQeVVuaWNvZGVFcnJvck9iamVjdCAqKXNlbGYsIGFyZ3MsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGt3ZHMsICZQeVVuaWNvZGVfVHlwZSk7Cit9CisKK3N0YXRpYyBQeU9iamVjdCAqCitVbmljb2RlRW5jb2RlRXJyb3Jfc3RyKFB5T2JqZWN0ICpzZWxmKQoreworICAgIFB5VW5pY29kZUVycm9yT2JqZWN0ICp1c2VsZiA9IChQeVVuaWNvZGVFcnJvck9iamVjdCAqKXNlbGY7CisgICAgUHlPYmplY3QgKnJlc3VsdCA9IE5VTEw7CisgICAgUHlPYmplY3QgKnJlYXNvbl9zdHIgPSBOVUxMOworICAgIFB5T2JqZWN0ICplbmNvZGluZ19zdHIgPSBOVUxMOworCisgICAgLyogR2V0IHJlYXNvbiBhbmQgZW5jb2RpbmcgYXMgc3RyaW5ncywgd2hpY2ggdGhleSBtaWdodCBub3QgYmUgaWYKKyAgICAgICB0aGV5J3ZlIGJlZW4gbW9kaWZpZWQgYWZ0ZXIgd2Ugd2VyZSBjb250cnVjdGVkLiAqLworICAgIHJlYXNvbl9zdHIgPSBQeU9iamVjdF9TdHIodXNlbGYtPnJlYXNvbik7CisgICAgaWYgKHJlYXNvbl9zdHIgPT0gTlVMTCkKKyAgICAgICAgZ290byBkb25lOworICAgIGVuY29kaW5nX3N0ciA9IFB5T2JqZWN0X1N0cih1c2VsZi0+ZW5jb2RpbmcpOworICAgIGlmIChlbmNvZGluZ19zdHIgPT0gTlVMTCkKKyAgICAgICAgZ290byBkb25lOworCisgICAgaWYgKHVzZWxmLT5zdGFydCA8IFB5VW5pY29kZV9HRVRfU0laRSh1c2VsZi0+b2JqZWN0KSAmJiB1c2VsZi0+ZW5kID09IHVzZWxmLT5zdGFydCsxKSB7CisgICAgICAgIGludCBiYWRjaGFyID0gKGludClQeVVuaWNvZGVfQVNfVU5JQ09ERSh1c2VsZi0+b2JqZWN0KVt1c2VsZi0+c3RhcnRdOworICAgICAgICBjaGFyIGJhZGNoYXJfc3RyWzIwXTsKKyAgICAgICAgaWYgKGJhZGNoYXIgPD0gMHhmZikKKyAgICAgICAgICAgIFB5T1Nfc25wcmludGYoYmFkY2hhcl9zdHIsIHNpemVvZihiYWRjaGFyX3N0ciksICJ4JTAyeCIsIGJhZGNoYXIpOworICAgICAgICBlbHNlIGlmIChiYWRjaGFyIDw9IDB4ZmZmZikKKyAgICAgICAgICAgIFB5T1Nfc25wcmludGYoYmFkY2hhcl9zdHIsIHNpemVvZihiYWRjaGFyX3N0ciksICJ1JTA0eCIsIGJhZGNoYXIpOworICAgICAgICBlbHNlCisgICAgICAgICAgICBQeU9TX3NucHJpbnRmKGJhZGNoYXJfc3RyLCBzaXplb2YoYmFkY2hhcl9zdHIpLCAiVSUwOHgiLCBiYWRjaGFyKTsKKyAgICAgICAgcmVzdWx0ID0gUHlTdHJpbmdfRnJvbUZvcm1hdCgKKyAgICAgICAgICAgICInJS40MDBzJyBjb2RlYyBjYW4ndCBlbmNvZGUgY2hhcmFjdGVyIHUnXFwlcycgaW4gcG9zaXRpb24gJXpkOiAlLjQwMHMiLAorICAgICAgICAgICAgUHlTdHJpbmdfQVNfU1RSSU5HKGVuY29kaW5nX3N0ciksCisgICAgICAgICAgICBiYWRjaGFyX3N0ciwKKyAgICAgICAgICAgIHVzZWxmLT5zdGFydCwKKyAgICAgICAgICAgIFB5U3RyaW5nX0FTX1NUUklORyhyZWFzb25fc3RyKSk7CisgICAgfQorICAgIGVsc2UgeworICAgICAgICByZXN1bHQgPSBQeVN0cmluZ19Gcm9tRm9ybWF0KAorICAgICAgICAgICAgIiclLjQwMHMnIGNvZGVjIGNhbid0IGVuY29kZSBjaGFyYWN0ZXJzIGluIHBvc2l0aW9uICV6ZC0lemQ6ICUuNDAwcyIsCisgICAgICAgICAgICBQeVN0cmluZ19BU19TVFJJTkcoZW5jb2Rpbmdfc3RyKSwKKyAgICAgICAgICAgIHVzZWxmLT5zdGFydCwKKyAgICAgICAgICAgIHVzZWxmLT5lbmQtMSwKKyAgICAgICAgICAgIFB5U3RyaW5nX0FTX1NUUklORyhyZWFzb25fc3RyKSk7CisgICAgfQorZG9uZToKKyAgICBQeV9YREVDUkVGKHJlYXNvbl9zdHIpOworICAgIFB5X1hERUNSRUYoZW5jb2Rpbmdfc3RyKTsKKyAgICByZXR1cm4gcmVzdWx0OworfQorCitzdGF0aWMgUHlUeXBlT2JqZWN0IF9QeUV4Y19Vbmljb2RlRW5jb2RlRXJyb3IgPSB7CisgICAgUHlPYmplY3RfSEVBRF9JTklUKE5VTEwpCisgICAgMCwKKyAgICBFWENfTU9EVUxFX05BTUUgIlVuaWNvZGVFbmNvZGVFcnJvciIsCisgICAgc2l6ZW9mKFB5VW5pY29kZUVycm9yT2JqZWN0KSwgMCwKKyAgICAoZGVzdHJ1Y3RvcilVbmljb2RlRXJyb3JfZGVhbGxvYywgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwKKyAgICAocmVwcmZ1bmMpVW5pY29kZUVuY29kZUVycm9yX3N0ciwgMCwgMCwgMCwKKyAgICBQeV9UUEZMQUdTX0RFRkFVTFQgfCBQeV9UUEZMQUdTX0JBU0VUWVBFIHwgUHlfVFBGTEFHU19IQVZFX0dDLAorICAgIFB5RG9jX1NUUigiVW5pY29kZSBlbmNvZGluZyBlcnJvci4iKSwgKHRyYXZlcnNlcHJvYylVbmljb2RlRXJyb3JfdHJhdmVyc2UsCisgICAgKGlucXVpcnkpVW5pY29kZUVycm9yX2NsZWFyLCAwLCAwLCAwLCAwLCAwLCBVbmljb2RlRXJyb3JfbWVtYmVycywKKyAgICAwLCAmX1B5RXhjX1VuaWNvZGVFcnJvciwgMCwgMCwgMCwgb2Zmc2V0b2YoUHlVbmljb2RlRXJyb3JPYmplY3QsIGRpY3QpLAorICAgIChpbml0cHJvYylVbmljb2RlRW5jb2RlRXJyb3JfaW5pdCwgMCwgQmFzZUV4Y2VwdGlvbl9uZXcsCit9OworUHlPYmplY3QgKlB5RXhjX1VuaWNvZGVFbmNvZGVFcnJvciA9IChQeU9iamVjdCAqKSZfUHlFeGNfVW5pY29kZUVuY29kZUVycm9yOworCitQeU9iamVjdCAqCitQeVVuaWNvZGVFbmNvZGVFcnJvcl9DcmVhdGUoCisgICAgY29uc3QgY2hhciAqZW5jb2RpbmcsIGNvbnN0IFB5X1VOSUNPREUgKm9iamVjdCwgUHlfc3NpemVfdCBsZW5ndGgsCisgICAgUHlfc3NpemVfdCBzdGFydCwgUHlfc3NpemVfdCBlbmQsIGNvbnN0IGNoYXIgKnJlYXNvbikKK3sKKyAgICByZXR1cm4gUHlPYmplY3RfQ2FsbEZ1bmN0aW9uKFB5RXhjX1VuaWNvZGVFbmNvZGVFcnJvciwgInN1I25ucyIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbmNvZGluZywgb2JqZWN0LCBsZW5ndGgsIHN0YXJ0LCBlbmQsIHJlYXNvbik7Cit9CisKKworLyoKKyAqICAgIFVuaWNvZGVEZWNvZGVFcnJvciBleHRlbmRzIFVuaWNvZGVFcnJvcgorICovCisKK3N0YXRpYyBpbnQKK1VuaWNvZGVEZWNvZGVFcnJvcl9pbml0KFB5T2JqZWN0ICpzZWxmLCBQeU9iamVjdCAqYXJncywgUHlPYmplY3QgKmt3ZHMpCit7CisgICAgaWYgKEJhc2VFeGNlcHRpb25faW5pdCgoUHlCYXNlRXhjZXB0aW9uT2JqZWN0ICopc2VsZiwgYXJncywga3dkcykgPT0gLTEpCisgICAgICAgIHJldHVybiAtMTsKKyAgICByZXR1cm4gVW5pY29kZUVycm9yX2luaXQoKFB5VW5pY29kZUVycm9yT2JqZWN0ICopc2VsZiwgYXJncywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAga3dkcywgJlB5U3RyaW5nX1R5cGUpOworfQorCitzdGF0aWMgUHlPYmplY3QgKgorVW5pY29kZURlY29kZUVycm9yX3N0cihQeU9iamVjdCAqc2VsZikKK3sKKyAgICBQeVVuaWNvZGVFcnJvck9iamVjdCAqdXNlbGYgPSAoUHlVbmljb2RlRXJyb3JPYmplY3QgKilzZWxmOworICAgIFB5T2JqZWN0ICpyZXN1bHQgPSBOVUxMOworICAgIFB5T2JqZWN0ICpyZWFzb25fc3RyID0gTlVMTDsKKyAgICBQeU9iamVjdCAqZW5jb2Rpbmdfc3RyID0gTlVMTDsKKworICAgIC8qIEdldCByZWFzb24gYW5kIGVuY29kaW5nIGFzIHN0cmluZ3MsIHdoaWNoIHRoZXkgbWlnaHQgbm90IGJlIGlmCisgICAgICAgdGhleSd2ZSBiZWVuIG1vZGlmaWVkIGFmdGVyIHdlIHdlcmUgY29udHJ1Y3RlZC4gKi8KKyAgICByZWFzb25fc3RyID0gUHlPYmplY3RfU3RyKHVzZWxmLT5yZWFzb24pOworICAgIGlmIChyZWFzb25fc3RyID09IE5VTEwpCisgICAgICAgIGdvdG8gZG9uZTsKKyAgICBlbmNvZGluZ19zdHIgPSBQeU9iamVjdF9TdHIodXNlbGYtPmVuY29kaW5nKTsKKyAgICBpZiAoZW5jb2Rpbmdfc3RyID09IE5VTEwpCisgICAgICAgIGdvdG8gZG9uZTsKKworICAgIGlmICh1c2VsZi0+c3RhcnQgPCBQeVVuaWNvZGVfR0VUX1NJWkUodXNlbGYtPm9iamVjdCkgJiYgdXNlbGYtPmVuZCA9PSB1c2VsZi0+c3RhcnQrMSkgeworICAgICAgICAvKiBGcm9tRm9ybWF0IGRvZXMgbm90IHN1cHBvcnQgJTAyeCwgc28gZm9ybWF0IHRoYXQgc2VwYXJhdGVseSAqLworICAgICAgICBjaGFyIGJ5dGVbNF07CisgICAgICAgIFB5T1Nfc25wcmludGYoYnl0ZSwgc2l6ZW9mKGJ5dGUpLCAiJTAyeCIsCisgICAgICAgICAgICAgICAgICAgICAgKChpbnQpUHlTdHJpbmdfQVNfU1RSSU5HKHVzZWxmLT5vYmplY3QpW3VzZWxmLT5zdGFydF0pJjB4ZmYpOworICAgICAgICByZXN1bHQgPSBQeVN0cmluZ19Gcm9tRm9ybWF0KAorICAgICAgICAgICAgIiclLjQwMHMnIGNvZGVjIGNhbid0IGRlY29kZSBieXRlIDB4JXMgaW4gcG9zaXRpb24gJXpkOiAlLjQwMHMiLAorICAgICAgICAgICAgUHlTdHJpbmdfQVNfU1RSSU5HKGVuY29kaW5nX3N0ciksCisgICAgICAgICAgICBieXRlLAorICAgICAgICAgICAgdXNlbGYtPnN0YXJ0LAorICAgICAgICAgICAgUHlTdHJpbmdfQVNfU1RSSU5HKHJlYXNvbl9zdHIpKTsKKyAgICB9CisgICAgZWxzZSB7CisgICAgICAgIHJlc3VsdCA9IFB5U3RyaW5nX0Zyb21Gb3JtYXQoCisgICAgICAgICAgICAiJyUuNDAwcycgY29kZWMgY2FuJ3QgZGVjb2RlIGJ5dGVzIGluIHBvc2l0aW9uICV6ZC0lemQ6ICUuNDAwcyIsCisgICAgICAgICAgICBQeVN0cmluZ19BU19TVFJJTkcoZW5jb2Rpbmdfc3RyKSwKKyAgICAgICAgICAgIHVzZWxmLT5zdGFydCwKKyAgICAgICAgICAgIHVzZWxmLT5lbmQtMSwKKyAgICAgICAgICAgIFB5U3RyaW5nX0FTX1NUUklORyhyZWFzb25fc3RyKSk7CisgICAgfQorZG9uZToKKyAgICBQeV9YREVDUkVGKHJlYXNvbl9zdHIpOworICAgIFB5X1hERUNSRUYoZW5jb2Rpbmdfc3RyKTsKKyAgICByZXR1cm4gcmVzdWx0OworfQorCitzdGF0aWMgUHlUeXBlT2JqZWN0IF9QeUV4Y19Vbmljb2RlRGVjb2RlRXJyb3IgPSB7CisgICAgUHlPYmplY3RfSEVBRF9JTklUKE5VTEwpCisgICAgMCwKKyAgICBFWENfTU9EVUxFX05BTUUgIlVuaWNvZGVEZWNvZGVFcnJvciIsCisgICAgc2l6ZW9mKFB5VW5pY29kZUVycm9yT2JqZWN0KSwgMCwKKyAgICAoZGVzdHJ1Y3RvcilVbmljb2RlRXJyb3JfZGVhbGxvYywgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwKKyAgICAocmVwcmZ1bmMpVW5pY29kZURlY29kZUVycm9yX3N0ciwgMCwgMCwgMCwKKyAgICBQeV9UUEZMQUdTX0RFRkFVTFQgfCBQeV9UUEZMQUdTX0JBU0VUWVBFIHwgUHlfVFBGTEFHU19IQVZFX0dDLAorICAgIFB5RG9jX1NUUigiVW5pY29kZSBkZWNvZGluZyBlcnJvci4iKSwgKHRyYXZlcnNlcHJvYylVbmljb2RlRXJyb3JfdHJhdmVyc2UsCisgICAgKGlucXVpcnkpVW5pY29kZUVycm9yX2NsZWFyLCAwLCAwLCAwLCAwLCAwLCBVbmljb2RlRXJyb3JfbWVtYmVycywKKyAgICAwLCAmX1B5RXhjX1VuaWNvZGVFcnJvciwgMCwgMCwgMCwgb2Zmc2V0b2YoUHlVbmljb2RlRXJyb3JPYmplY3QsIGRpY3QpLAorICAgIChpbml0cHJvYylVbmljb2RlRGVjb2RlRXJyb3JfaW5pdCwgMCwgQmFzZUV4Y2VwdGlvbl9uZXcsCit9OworUHlPYmplY3QgKlB5RXhjX1VuaWNvZGVEZWNvZGVFcnJvciA9IChQeU9iamVjdCAqKSZfUHlFeGNfVW5pY29kZURlY29kZUVycm9yOworCitQeU9iamVjdCAqCitQeVVuaWNvZGVEZWNvZGVFcnJvcl9DcmVhdGUoCisgICAgY29uc3QgY2hhciAqZW5jb2RpbmcsIGNvbnN0IGNoYXIgKm9iamVjdCwgUHlfc3NpemVfdCBsZW5ndGgsCisgICAgUHlfc3NpemVfdCBzdGFydCwgUHlfc3NpemVfdCBlbmQsIGNvbnN0IGNoYXIgKnJlYXNvbikKK3sKKyAgICByZXR1cm4gUHlPYmplY3RfQ2FsbEZ1bmN0aW9uKFB5RXhjX1VuaWNvZGVEZWNvZGVFcnJvciwgInNzI25ucyIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbmNvZGluZywgb2JqZWN0LCBsZW5ndGgsIHN0YXJ0LCBlbmQsIHJlYXNvbik7Cit9CisKKworLyoKKyAqICAgIFVuaWNvZGVUcmFuc2xhdGVFcnJvciBleHRlbmRzIFVuaWNvZGVFcnJvcgorICovCisKK3N0YXRpYyBpbnQKK1VuaWNvZGVUcmFuc2xhdGVFcnJvcl9pbml0KFB5VW5pY29kZUVycm9yT2JqZWN0ICpzZWxmLCBQeU9iamVjdCAqYXJncywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIFB5T2JqZWN0ICprd2RzKQoreworICAgIGlmIChCYXNlRXhjZXB0aW9uX2luaXQoKFB5QmFzZUV4Y2VwdGlvbk9iamVjdCAqKXNlbGYsIGFyZ3MsIGt3ZHMpID09IC0xKQorICAgICAgICByZXR1cm4gLTE7CisKKyAgICBQeV9DTEVBUihzZWxmLT5vYmplY3QpOworICAgIFB5X0NMRUFSKHNlbGYtPnJlYXNvbik7CisKKyAgICBpZiAoIVB5QXJnX1BhcnNlVHVwbGUoYXJncywgIk8hbm5PISIsCisgICAgICAgICZQeVVuaWNvZGVfVHlwZSwgJnNlbGYtPm9iamVjdCwKKyAgICAgICAgJnNlbGYtPnN0YXJ0LAorICAgICAgICAmc2VsZi0+ZW5kLAorICAgICAgICAmUHlTdHJpbmdfVHlwZSwgJnNlbGYtPnJlYXNvbikpIHsKKyAgICAgICAgc2VsZi0+b2JqZWN0ID0gc2VsZi0+cmVhc29uID0gTlVMTDsKKyAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKworICAgIFB5X0lOQ1JFRihzZWxmLT5vYmplY3QpOworICAgIFB5X0lOQ1JFRihzZWxmLT5yZWFzb24pOworCisgICAgcmV0dXJuIDA7Cit9CisKKworc3RhdGljIFB5T2JqZWN0ICoKK1VuaWNvZGVUcmFuc2xhdGVFcnJvcl9zdHIoUHlPYmplY3QgKnNlbGYpCit7CisgICAgUHlVbmljb2RlRXJyb3JPYmplY3QgKnVzZWxmID0gKFB5VW5pY29kZUVycm9yT2JqZWN0ICopc2VsZjsKKyAgICBQeU9iamVjdCAqcmVzdWx0ID0gTlVMTDsKKyAgICBQeU9iamVjdCAqcmVhc29uX3N0ciA9IE5VTEw7CisKKyAgICAvKiBHZXQgcmVhc29uIGFzIGEgc3RyaW5nLCB3aGljaCBpdCBtaWdodCBub3QgYmUgaWYgaXQncyBiZWVuCisgICAgICAgbW9kaWZpZWQgYWZ0ZXIgd2Ugd2VyZSBjb250cnVjdGVkLiAqLworICAgIHJlYXNvbl9zdHIgPSBQeU9iamVjdF9TdHIodXNlbGYtPnJlYXNvbik7CisgICAgaWYgKHJlYXNvbl9zdHIgPT0gTlVMTCkKKyAgICAgICAgZ290byBkb25lOworCisgICAgaWYgKHVzZWxmLT5zdGFydCA8IFB5VW5pY29kZV9HRVRfU0laRSh1c2VsZi0+b2JqZWN0KSAmJiB1c2VsZi0+ZW5kID09IHVzZWxmLT5zdGFydCsxKSB7CisgICAgICAgIGludCBiYWRjaGFyID0gKGludClQeVVuaWNvZGVfQVNfVU5JQ09ERSh1c2VsZi0+b2JqZWN0KVt1c2VsZi0+c3RhcnRdOworICAgICAgICBjaGFyIGJhZGNoYXJfc3RyWzIwXTsKKyAgICAgICAgaWYgKGJhZGNoYXIgPD0gMHhmZikKKyAgICAgICAgICAgIFB5T1Nfc25wcmludGYoYmFkY2hhcl9zdHIsIHNpemVvZihiYWRjaGFyX3N0ciksICJ4JTAyeCIsIGJhZGNoYXIpOworICAgICAgICBlbHNlIGlmIChiYWRjaGFyIDw9IDB4ZmZmZikKKyAgICAgICAgICAgIFB5T1Nfc25wcmludGYoYmFkY2hhcl9zdHIsIHNpemVvZihiYWRjaGFyX3N0ciksICJ1JTA0eCIsIGJhZGNoYXIpOworICAgICAgICBlbHNlCisgICAgICAgICAgICBQeU9TX3NucHJpbnRmKGJhZGNoYXJfc3RyLCBzaXplb2YoYmFkY2hhcl9zdHIpLCAiVSUwOHgiLCBiYWRjaGFyKTsKKyAgICAgICAgcmVzdWx0ID0gUHlTdHJpbmdfRnJvbUZvcm1hdCgKKyAgICAgICAgICAgICJjYW4ndCB0cmFuc2xhdGUgY2hhcmFjdGVyIHUnXFwlcycgaW4gcG9zaXRpb24gJXpkOiAlLjQwMHMiLAorICAgICAgICAgICAgYmFkY2hhcl9zdHIsCisgICAgICAgICAgICB1c2VsZi0+c3RhcnQsCisgICAgICAgICAgICBQeVN0cmluZ19BU19TVFJJTkcocmVhc29uX3N0cikpOworICAgIH0gZWxzZSB7CisgICAgICAgIHJlc3VsdCA9IFB5U3RyaW5nX0Zyb21Gb3JtYXQoCisgICAgICAgICAgICAiY2FuJ3QgdHJhbnNsYXRlIGNoYXJhY3RlcnMgaW4gcG9zaXRpb24gJXpkLSV6ZDogJS40MDBzIiwKKyAgICAgICAgICAgIHVzZWxmLT5zdGFydCwKKyAgICAgICAgICAgIHVzZWxmLT5lbmQtMSwKKyAgICAgICAgICAgIFB5U3RyaW5nX0FTX1NUUklORyhyZWFzb25fc3RyKSk7CisgICAgfQorZG9uZToKKyAgICBQeV9YREVDUkVGKHJlYXNvbl9zdHIpOworICAgIHJldHVybiByZXN1bHQ7Cit9CisKK3N0YXRpYyBQeVR5cGVPYmplY3QgX1B5RXhjX1VuaWNvZGVUcmFuc2xhdGVFcnJvciA9IHsKKyAgICBQeU9iamVjdF9IRUFEX0lOSVQoTlVMTCkKKyAgICAwLAorICAgIEVYQ19NT0RVTEVfTkFNRSAiVW5pY29kZVRyYW5zbGF0ZUVycm9yIiwKKyAgICBzaXplb2YoUHlVbmljb2RlRXJyb3JPYmplY3QpLCAwLAorICAgIChkZXN0cnVjdG9yKVVuaWNvZGVFcnJvcl9kZWFsbG9jLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLAorICAgIChyZXByZnVuYylVbmljb2RlVHJhbnNsYXRlRXJyb3Jfc3RyLCAwLCAwLCAwLAorICAgIFB5X1RQRkxBR1NfREVGQVVMVCB8IFB5X1RQRkxBR1NfQkFTRVRZUEUgfCBQeV9UUEZMQUdTX0hBVkVfR0MsCisgICAgUHlEb2NfU1RSKCJVbmljb2RlIHRyYW5zbGF0aW9uIGVycm9yLiIpLCAodHJhdmVyc2Vwcm9jKVVuaWNvZGVFcnJvcl90cmF2ZXJzZSwKKyAgICAoaW5xdWlyeSlVbmljb2RlRXJyb3JfY2xlYXIsIDAsIDAsIDAsIDAsIDAsIFVuaWNvZGVFcnJvcl9tZW1iZXJzLAorICAgIDAsICZfUHlFeGNfVW5pY29kZUVycm9yLCAwLCAwLCAwLCBvZmZzZXRvZihQeVVuaWNvZGVFcnJvck9iamVjdCwgZGljdCksCisgICAgKGluaXRwcm9jKVVuaWNvZGVUcmFuc2xhdGVFcnJvcl9pbml0LCAwLCBCYXNlRXhjZXB0aW9uX25ldywKK307CitQeU9iamVjdCAqUHlFeGNfVW5pY29kZVRyYW5zbGF0ZUVycm9yID0gKFB5T2JqZWN0ICopJl9QeUV4Y19Vbmljb2RlVHJhbnNsYXRlRXJyb3I7CisKK1B5T2JqZWN0ICoKK1B5VW5pY29kZVRyYW5zbGF0ZUVycm9yX0NyZWF0ZSgKKyAgICBjb25zdCBQeV9VTklDT0RFICpvYmplY3QsIFB5X3NzaXplX3QgbGVuZ3RoLAorICAgIFB5X3NzaXplX3Qgc3RhcnQsIFB5X3NzaXplX3QgZW5kLCBjb25zdCBjaGFyICpyZWFzb24pCit7CisgICAgcmV0dXJuIFB5T2JqZWN0X0NhbGxGdW5jdGlvbihQeUV4Y19Vbmljb2RlVHJhbnNsYXRlRXJyb3IsICJ1I25ucyIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvYmplY3QsIGxlbmd0aCwgc3RhcnQsIGVuZCwgcmVhc29uKTsKK30KKyNlbmRpZgorCisKKy8qCisgKiAgICBBc3NlcnRpb25FcnJvciBleHRlbmRzIFN0YW5kYXJkRXJyb3IKKyAqLworU2ltcGxlRXh0ZW5kc0V4Y2VwdGlvbihQeUV4Y19TdGFuZGFyZEVycm9yLCBBc3NlcnRpb25FcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICAgIkFzc2VydGlvbiBmYWlsZWQuIik7CisKKworLyoKKyAqICAgIEFyaXRobWV0aWNFcnJvciBleHRlbmRzIFN0YW5kYXJkRXJyb3IKKyAqLworU2ltcGxlRXh0ZW5kc0V4Y2VwdGlvbihQeUV4Y19TdGFuZGFyZEVycm9yLCBBcml0aG1ldGljRXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAgICJCYXNlIGNsYXNzIGZvciBhcml0aG1ldGljIGVycm9ycy4iKTsKKworCisvKgorICogICAgRmxvYXRpbmdQb2ludEVycm9yIGV4dGVuZHMgQXJpdGhtZXRpY0Vycm9yCisgKi8KK1NpbXBsZUV4dGVuZHNFeGNlcHRpb24oUHlFeGNfQXJpdGhtZXRpY0Vycm9yLCBGbG9hdGluZ1BvaW50RXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAgICJGbG9hdGluZyBwb2ludCBvcGVyYXRpb24gZmFpbGVkLiIpOworCisKKy8qCisgKiAgICBPdmVyZmxvd0Vycm9yIGV4dGVuZHMgQXJpdGhtZXRpY0Vycm9yCisgKi8KK1NpbXBsZUV4dGVuZHNFeGNlcHRpb24oUHlFeGNfQXJpdGhtZXRpY0Vycm9yLCBPdmVyZmxvd0Vycm9yLAorICAgICAgICAgICAgICAgICAgICAgICAiUmVzdWx0IHRvbyBsYXJnZSB0byBiZSByZXByZXNlbnRlZC4iKTsKKworCisvKgorICogICAgWmVyb0RpdmlzaW9uRXJyb3IgZXh0ZW5kcyBBcml0aG1ldGljRXJyb3IKKyAqLworU2ltcGxlRXh0ZW5kc0V4Y2VwdGlvbihQeUV4Y19Bcml0aG1ldGljRXJyb3IsIFplcm9EaXZpc2lvbkVycm9yLAorICAgICAgICAgICJTZWNvbmQgYXJndW1lbnQgdG8gYSBkaXZpc2lvbiBvciBtb2R1bG8gb3BlcmF0aW9uIHdhcyB6ZXJvLiIpOworCisKKy8qCisgKiAgICBTeXN0ZW1FcnJvciBleHRlbmRzIFN0YW5kYXJkRXJyb3IKKyAqLworU2ltcGxlRXh0ZW5kc0V4Y2VwdGlvbihQeUV4Y19TdGFuZGFyZEVycm9yLCBTeXN0ZW1FcnJvciwKKyAgICAiSW50ZXJuYWwgZXJyb3IgaW4gdGhlIFB5dGhvbiBpbnRlcnByZXRlci5cbiIKKyAgICAiXG4iCisgICAgIlBsZWFzZSByZXBvcnQgdGhpcyB0byB0aGUgUHl0aG9uIG1haW50YWluZXIsIGFsb25nIHdpdGggdGhlIHRyYWNlYmFjayxcbiIKKyAgICAidGhlIFB5dGhvbiB2ZXJzaW9uLCBhbmQgdGhlIGhhcmR3YXJlL09TIHBsYXRmb3JtIGFuZCB2ZXJzaW9uLiIpOworCisKKy8qCisgKiAgICBSZWZlcmVuY2VFcnJvciBleHRlbmRzIFN0YW5kYXJkRXJyb3IKKyAqLworU2ltcGxlRXh0ZW5kc0V4Y2VwdGlvbihQeUV4Y19TdGFuZGFyZEVycm9yLCBSZWZlcmVuY2VFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICAgIldlYWsgcmVmIHByb3h5IHVzZWQgYWZ0ZXIgcmVmZXJlbnQgd2VudCBhd2F5LiIpOworCisKKy8qCisgKiAgICBNZW1vcnlFcnJvciBleHRlbmRzIFN0YW5kYXJkRXJyb3IKKyAqLworU2ltcGxlRXh0ZW5kc0V4Y2VwdGlvbihQeUV4Y19TdGFuZGFyZEVycm9yLCBNZW1vcnlFcnJvciwgIk91dCBvZiBtZW1vcnkuIik7CisKKy8qCisgKiAgICBCdWZmZXJFcnJvciBleHRlbmRzIFN0YW5kYXJkRXJyb3IKKyAqLworU2ltcGxlRXh0ZW5kc0V4Y2VwdGlvbihQeUV4Y19TdGFuZGFyZEVycm9yLCBCdWZmZXJFcnJvciwgIkJ1ZmZlciBlcnJvci4iKTsKKworCisvKiBXYXJuaW5nIGNhdGVnb3J5IGRvY3N0cmluZ3MgKi8KKworLyoKKyAqICAgIFdhcm5pbmcgZXh0ZW5kcyBFeGNlcHRpb24KKyAqLworU2ltcGxlRXh0ZW5kc0V4Y2VwdGlvbihQeUV4Y19FeGNlcHRpb24sIFdhcm5pbmcsCisgICAgICAgICAgICAgICAgICAgICAgICJCYXNlIGNsYXNzIGZvciB3YXJuaW5nIGNhdGVnb3JpZXMuIik7CisKKworLyoKKyAqICAgIFVzZXJXYXJuaW5nIGV4dGVuZHMgV2FybmluZworICovCitTaW1wbGVFeHRlbmRzRXhjZXB0aW9uKFB5RXhjX1dhcm5pbmcsIFVzZXJXYXJuaW5nLAorICAgICAgICAgICAgICAgICAgICAgICAiQmFzZSBjbGFzcyBmb3Igd2FybmluZ3MgZ2VuZXJhdGVkIGJ5IHVzZXIgY29kZS4iKTsKKworCisvKgorICogICAgRGVwcmVjYXRpb25XYXJuaW5nIGV4dGVuZHMgV2FybmluZworICovCitTaW1wbGVFeHRlbmRzRXhjZXB0aW9uKFB5RXhjX1dhcm5pbmcsIERlcHJlY2F0aW9uV2FybmluZywKKyAgICAgICAgICAgICAgICAgICAgICAgIkJhc2UgY2xhc3MgZm9yIHdhcm5pbmdzIGFib3V0IGRlcHJlY2F0ZWQgZmVhdHVyZXMuIik7CisKKworLyoKKyAqICAgIFBlbmRpbmdEZXByZWNhdGlvbldhcm5pbmcgZXh0ZW5kcyBXYXJuaW5nCisgKi8KK1NpbXBsZUV4dGVuZHNFeGNlcHRpb24oUHlFeGNfV2FybmluZywgUGVuZGluZ0RlcHJlY2F0aW9uV2FybmluZywKKyAgICAiQmFzZSBjbGFzcyBmb3Igd2FybmluZ3MgYWJvdXQgZmVhdHVyZXMgd2hpY2ggd2lsbCBiZSBkZXByZWNhdGVkXG4iCisgICAgImluIHRoZSBmdXR1cmUuIik7CisKKworLyoKKyAqICAgIFN5bnRheFdhcm5pbmcgZXh0ZW5kcyBXYXJuaW5nCisgKi8KK1NpbXBsZUV4dGVuZHNFeGNlcHRpb24oUHlFeGNfV2FybmluZywgU3ludGF4V2FybmluZywKKyAgICAgICAgICAgICAgICAgICAgICAgIkJhc2UgY2xhc3MgZm9yIHdhcm5pbmdzIGFib3V0IGR1YmlvdXMgc3ludGF4LiIpOworCisKKy8qCisgKiAgICBSdW50aW1lV2FybmluZyBleHRlbmRzIFdhcm5pbmcKKyAqLworU2ltcGxlRXh0ZW5kc0V4Y2VwdGlvbihQeUV4Y19XYXJuaW5nLCBSdW50aW1lV2FybmluZywKKyAgICAgICAgICAgICAgICAgIkJhc2UgY2xhc3MgZm9yIHdhcm5pbmdzIGFib3V0IGR1YmlvdXMgcnVudGltZSBiZWhhdmlvci4iKTsKKworCisvKgorICogICAgRnV0dXJlV2FybmluZyBleHRlbmRzIFdhcm5pbmcKKyAqLworU2ltcGxlRXh0ZW5kc0V4Y2VwdGlvbihQeUV4Y19XYXJuaW5nLCBGdXR1cmVXYXJuaW5nLAorICAgICJCYXNlIGNsYXNzIGZvciB3YXJuaW5ncyBhYm91dCBjb25zdHJ1Y3RzIHRoYXQgd2lsbCBjaGFuZ2Ugc2VtYW50aWNhbGx5XG4iCisgICAgImluIHRoZSBmdXR1cmUuIik7CisKKworLyoKKyAqICAgIEltcG9ydFdhcm5pbmcgZXh0ZW5kcyBXYXJuaW5nCisgKi8KK1NpbXBsZUV4dGVuZHNFeGNlcHRpb24oUHlFeGNfV2FybmluZywgSW1wb3J0V2FybmluZywKKyAgICAgICAgICAiQmFzZSBjbGFzcyBmb3Igd2FybmluZ3MgYWJvdXQgcHJvYmFibGUgbWlzdGFrZXMgaW4gbW9kdWxlIGltcG9ydHMiKTsKKworCisvKgorICogICAgVW5pY29kZVdhcm5pbmcgZXh0ZW5kcyBXYXJuaW5nCisgKi8KK1NpbXBsZUV4dGVuZHNFeGNlcHRpb24oUHlFeGNfV2FybmluZywgVW5pY29kZVdhcm5pbmcsCisgICAgIkJhc2UgY2xhc3MgZm9yIHdhcm5pbmdzIGFib3V0IFVuaWNvZGUgcmVsYXRlZCBwcm9ibGVtcywgbW9zdGx5XG4iCisgICAgInJlbGF0ZWQgdG8gY29udmVyc2lvbiBwcm9ibGVtcy4iKTsKKworLyoKKyAqICAgIEJ5dGVzV2FybmluZyBleHRlbmRzIFdhcm5pbmcKKyAqLworU2ltcGxlRXh0ZW5kc0V4Y2VwdGlvbihQeUV4Y19XYXJuaW5nLCBCeXRlc1dhcm5pbmcsCisgICAgIkJhc2UgY2xhc3MgZm9yIHdhcm5pbmdzIGFib3V0IGJ5dGVzIGFuZCBidWZmZXIgcmVsYXRlZCBwcm9ibGVtcywgbW9zdGx5XG4iCisgICAgInJlbGF0ZWQgdG8gY29udmVyc2lvbiBmcm9tIHN0ciBvciBjb21wYXJpbmcgdG8gc3RyLiIpOworCisvKiBQcmUtY29tcHV0ZWQgTWVtb3J5RXJyb3IgaW5zdGFuY2UuICBCZXN0IHRvIGNyZWF0ZSB0aGlzIGFzIGVhcmx5IGFzCisgKiBwb3NzaWJsZSBhbmQgbm90IHdhaXQgdW50aWwgYSBNZW1vcnlFcnJvciBpcyBhY3R1YWxseSByYWlzZWQhCisgKi8KK1B5T2JqZWN0ICpQeUV4Y19NZW1vcnlFcnJvckluc3Q9TlVMTDsKKworLyogUHJlLWNvbXB1dGVkIFJ1bnRpbWVFcnJvciBpbnN0YW5jZSBmb3Igd2hlbiByZWN1cnNpb24gZGVwdGggaXMgcmVhY2hlZC4KKyAgIE1lYW50IHRvIGJlIHVzZWQgd2hlbiBub3JtYWxpemluZyB0aGUgZXhjZXB0aW9uIGZvciBleGNlZWRpbmcgdGhlIHJlY3Vyc2lvbgorICAgZGVwdGggd2lsbCBjYXVzZSBpdHMgb3duIGluZmluaXRlIHJlY3Vyc2lvbi4KKyovCitQeU9iamVjdCAqUHlFeGNfUmVjdXJzaW9uRXJyb3JJbnN0ID0gTlVMTDsKKworLyogbW9kdWxlIGdsb2JhbCBmdW5jdGlvbnMgKi8KK3N0YXRpYyBQeU1ldGhvZERlZiBmdW5jdGlvbnNbXSA9IHsKKyAgICAvKiBTZW50aW5lbCAqLworICAgIHtOVUxMLCBOVUxMfQorfTsKKworI2RlZmluZSBQUkVfSU5JVChUWVBFKSBpZiAoUHlUeXBlX1JlYWR5KCZfUHlFeGNfICMjIFRZUEUpIDwgMCkgXAorICAgIFB5X0ZhdGFsRXJyb3IoImV4Y2VwdGlvbnMgYm9vdHN0cmFwcGluZyBlcnJvci4iKTsKKworI2RlZmluZSBQT1NUX0lOSVQoVFlQRSkgUHlfSU5DUkVGKFB5RXhjXyAjIyBUWVBFKTsgXAorICAgIFB5TW9kdWxlX0FkZE9iamVjdChtLCAjIFRZUEUsIFB5RXhjXyAjIyBUWVBFKTsgXAorICAgIGlmIChQeURpY3RfU2V0SXRlbVN0cmluZyhiZGljdCwgIyBUWVBFLCBQeUV4Y18gIyMgVFlQRSkpIFwKKyAgICAgICAgUHlfRmF0YWxFcnJvcigiTW9kdWxlIGRpY3Rpb25hcnkgaW5zZXJ0aW9uIHByb2JsZW0uIik7CisKKworUHlNT0RJTklUX0ZVTkMKK19QeUV4Y19Jbml0KHZvaWQpCit7CisgICAgUHlPYmplY3QgKm0sICpibHRpbm1vZCwgKmJkaWN0OworCisgICAgUFJFX0lOSVQoQmFzZUV4Y2VwdGlvbikKKyAgICBQUkVfSU5JVChFeGNlcHRpb24pCisgICAgUFJFX0lOSVQoU3RhbmRhcmRFcnJvcikKKyAgICBQUkVfSU5JVChUeXBlRXJyb3IpCisgICAgUFJFX0lOSVQoU3RvcEl0ZXJhdGlvbikKKyAgICBQUkVfSU5JVChHZW5lcmF0b3JFeGl0KQorICAgIFBSRV9JTklUKFN5c3RlbUV4aXQpCisgICAgUFJFX0lOSVQoS2V5Ym9hcmRJbnRlcnJ1cHQpCisgICAgUFJFX0lOSVQoSW1wb3J0RXJyb3IpCisgICAgUFJFX0lOSVQoRW52aXJvbm1lbnRFcnJvcikKKyAgICBQUkVfSU5JVChJT0Vycm9yKQorICAgIFBSRV9JTklUKE9TRXJyb3IpCisjaWZkZWYgTVNfV0lORE9XUworICAgIFBSRV9JTklUKFdpbmRvd3NFcnJvcikKKyNlbmRpZgorI2lmZGVmIF9fVk1TCisgICAgUFJFX0lOSVQoVk1TRXJyb3IpCisjZW5kaWYKKyAgICBQUkVfSU5JVChFT0ZFcnJvcikKKyAgICBQUkVfSU5JVChSdW50aW1lRXJyb3IpCisgICAgUFJFX0lOSVQoTm90SW1wbGVtZW50ZWRFcnJvcikKKyAgICBQUkVfSU5JVChOYW1lRXJyb3IpCisgICAgUFJFX0lOSVQoVW5ib3VuZExvY2FsRXJyb3IpCisgICAgUFJFX0lOSVQoQXR0cmlidXRlRXJyb3IpCisgICAgUFJFX0lOSVQoU3ludGF4RXJyb3IpCisgICAgUFJFX0lOSVQoSW5kZW50YXRpb25FcnJvcikKKyAgICBQUkVfSU5JVChUYWJFcnJvcikKKyAgICBQUkVfSU5JVChMb29rdXBFcnJvcikKKyAgICBQUkVfSU5JVChJbmRleEVycm9yKQorICAgIFBSRV9JTklUKEtleUVycm9yKQorICAgIFBSRV9JTklUKFZhbHVlRXJyb3IpCisgICAgUFJFX0lOSVQoVW5pY29kZUVycm9yKQorI2lmZGVmIFB5X1VTSU5HX1VOSUNPREUKKyAgICBQUkVfSU5JVChVbmljb2RlRW5jb2RlRXJyb3IpCisgICAgUFJFX0lOSVQoVW5pY29kZURlY29kZUVycm9yKQorICAgIFBSRV9JTklUKFVuaWNvZGVUcmFuc2xhdGVFcnJvcikKKyNlbmRpZgorICAgIFBSRV9JTklUKEFzc2VydGlvbkVycm9yKQorICAgIFBSRV9JTklUKEFyaXRobWV0aWNFcnJvcikKKyAgICBQUkVfSU5JVChGbG9hdGluZ1BvaW50RXJyb3IpCisgICAgUFJFX0lOSVQoT3ZlcmZsb3dFcnJvcikKKyAgICBQUkVfSU5JVChaZXJvRGl2aXNpb25FcnJvcikKKyAgICBQUkVfSU5JVChTeXN0ZW1FcnJvcikKKyAgICBQUkVfSU5JVChSZWZlcmVuY2VFcnJvcikKKyAgICBQUkVfSU5JVChNZW1vcnlFcnJvcikKKyAgICBQUkVfSU5JVChCdWZmZXJFcnJvcikKKyAgICBQUkVfSU5JVChXYXJuaW5nKQorICAgIFBSRV9JTklUKFVzZXJXYXJuaW5nKQorICAgIFBSRV9JTklUKERlcHJlY2F0aW9uV2FybmluZykKKyAgICBQUkVfSU5JVChQZW5kaW5nRGVwcmVjYXRpb25XYXJuaW5nKQorICAgIFBSRV9JTklUKFN5bnRheFdhcm5pbmcpCisgICAgUFJFX0lOSVQoUnVudGltZVdhcm5pbmcpCisgICAgUFJFX0lOSVQoRnV0dXJlV2FybmluZykKKyAgICBQUkVfSU5JVChJbXBvcnRXYXJuaW5nKQorICAgIFBSRV9JTklUKFVuaWNvZGVXYXJuaW5nKQorICAgIFBSRV9JTklUKEJ5dGVzV2FybmluZykKKworICAgIG0gPSBQeV9Jbml0TW9kdWxlNCgiZXhjZXB0aW9ucyIsIGZ1bmN0aW9ucywgZXhjZXB0aW9uc19kb2MsCisgICAgICAgIChQeU9iamVjdCAqKU5VTEwsIFBZVEhPTl9BUElfVkVSU0lPTik7CisgICAgaWYgKG0gPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuOworCisgICAgYmx0aW5tb2QgPSBQeUltcG9ydF9JbXBvcnRNb2R1bGUoIl9fYnVpbHRpbl9fIik7CisgICAgaWYgKGJsdGlubW9kID09IE5VTEwpCisgICAgICAgIFB5X0ZhdGFsRXJyb3IoImV4Y2VwdGlvbnMgYm9vdHN0cmFwcGluZyBlcnJvci4iKTsKKyAgICBiZGljdCA9IFB5TW9kdWxlX0dldERpY3QoYmx0aW5tb2QpOworICAgIGlmIChiZGljdCA9PSBOVUxMKQorICAgICAgICBQeV9GYXRhbEVycm9yKCJleGNlcHRpb25zIGJvb3RzdHJhcHBpbmcgZXJyb3IuIik7CisKKyAgICBQT1NUX0lOSVQoQmFzZUV4Y2VwdGlvbikKKyAgICBQT1NUX0lOSVQoRXhjZXB0aW9uKQorICAgIFBPU1RfSU5JVChTdGFuZGFyZEVycm9yKQorICAgIFBPU1RfSU5JVChUeXBlRXJyb3IpCisgICAgUE9TVF9JTklUKFN0b3BJdGVyYXRpb24pCisgICAgUE9TVF9JTklUKEdlbmVyYXRvckV4aXQpCisgICAgUE9TVF9JTklUKFN5c3RlbUV4aXQpCisgICAgUE9TVF9JTklUKEtleWJvYXJkSW50ZXJydXB0KQorICAgIFBPU1RfSU5JVChJbXBvcnRFcnJvcikKKyAgICBQT1NUX0lOSVQoRW52aXJvbm1lbnRFcnJvcikKKyAgICBQT1NUX0lOSVQoSU9FcnJvcikKKyAgICBQT1NUX0lOSVQoT1NFcnJvcikKKyNpZmRlZiBNU19XSU5ET1dTCisgICAgUE9TVF9JTklUKFdpbmRvd3NFcnJvcikKKyNlbmRpZgorI2lmZGVmIF9fVk1TCisgICAgUE9TVF9JTklUKFZNU0Vycm9yKQorI2VuZGlmCisgICAgUE9TVF9JTklUKEVPRkVycm9yKQorICAgIFBPU1RfSU5JVChSdW50aW1lRXJyb3IpCisgICAgUE9TVF9JTklUKE5vdEltcGxlbWVudGVkRXJyb3IpCisgICAgUE9TVF9JTklUKE5hbWVFcnJvcikKKyAgICBQT1NUX0lOSVQoVW5ib3VuZExvY2FsRXJyb3IpCisgICAgUE9TVF9JTklUKEF0dHJpYnV0ZUVycm9yKQorICAgIFBPU1RfSU5JVChTeW50YXhFcnJvcikKKyAgICBQT1NUX0lOSVQoSW5kZW50YXRpb25FcnJvcikKKyAgICBQT1NUX0lOSVQoVGFiRXJyb3IpCisgICAgUE9TVF9JTklUKExvb2t1cEVycm9yKQorICAgIFBPU1RfSU5JVChJbmRleEVycm9yKQorICAgIFBPU1RfSU5JVChLZXlFcnJvcikKKyAgICBQT1NUX0lOSVQoVmFsdWVFcnJvcikKKyAgICBQT1NUX0lOSVQoVW5pY29kZUVycm9yKQorI2lmZGVmIFB5X1VTSU5HX1VOSUNPREUKKyAgICBQT1NUX0lOSVQoVW5pY29kZUVuY29kZUVycm9yKQorICAgIFBPU1RfSU5JVChVbmljb2RlRGVjb2RlRXJyb3IpCisgICAgUE9TVF9JTklUKFVuaWNvZGVUcmFuc2xhdGVFcnJvcikKKyNlbmRpZgorICAgIFBPU1RfSU5JVChBc3NlcnRpb25FcnJvcikKKyAgICBQT1NUX0lOSVQoQXJpdGhtZXRpY0Vycm9yKQorICAgIFBPU1RfSU5JVChGbG9hdGluZ1BvaW50RXJyb3IpCisgICAgUE9TVF9JTklUKE92ZXJmbG93RXJyb3IpCisgICAgUE9TVF9JTklUKFplcm9EaXZpc2lvbkVycm9yKQorICAgIFBPU1RfSU5JVChTeXN0ZW1FcnJvcikKKyAgICBQT1NUX0lOSVQoUmVmZXJlbmNlRXJyb3IpCisgICAgUE9TVF9JTklUKE1lbW9yeUVycm9yKQorICAgIFBPU1RfSU5JVChCdWZmZXJFcnJvcikKKyAgICBQT1NUX0lOSVQoV2FybmluZykKKyAgICBQT1NUX0lOSVQoVXNlcldhcm5pbmcpCisgICAgUE9TVF9JTklUKERlcHJlY2F0aW9uV2FybmluZykKKyAgICBQT1NUX0lOSVQoUGVuZGluZ0RlcHJlY2F0aW9uV2FybmluZykKKyAgICBQT1NUX0lOSVQoU3ludGF4V2FybmluZykKKyAgICBQT1NUX0lOSVQoUnVudGltZVdhcm5pbmcpCisgICAgUE9TVF9JTklUKEZ1dHVyZVdhcm5pbmcpCisgICAgUE9TVF9JTklUKEltcG9ydFdhcm5pbmcpCisgICAgUE9TVF9JTklUKFVuaWNvZGVXYXJuaW5nKQorICAgIFBPU1RfSU5JVChCeXRlc1dhcm5pbmcpCisKKyAgICBQeUV4Y19NZW1vcnlFcnJvckluc3QgPSBCYXNlRXhjZXB0aW9uX25ldygmX1B5RXhjX01lbW9yeUVycm9yLCBOVUxMLCBOVUxMKTsKKyAgICBpZiAoIVB5RXhjX01lbW9yeUVycm9ySW5zdCkKKyAgICAgICAgUHlfRmF0YWxFcnJvcigiQ2Fubm90IHByZS1hbGxvY2F0ZSBNZW1vcnlFcnJvciBpbnN0YW5jZSIpOworCisgICAgUHlFeGNfUmVjdXJzaW9uRXJyb3JJbnN0ID0gQmFzZUV4Y2VwdGlvbl9uZXcoJl9QeUV4Y19SdW50aW1lRXJyb3IsIE5VTEwsIE5VTEwpOworICAgIGlmICghUHlFeGNfUmVjdXJzaW9uRXJyb3JJbnN0KQorICAgICAgICBQeV9GYXRhbEVycm9yKCJDYW5ub3QgcHJlLWFsbG9jYXRlIFJ1bnRpbWVFcnJvciBpbnN0YW5jZSBmb3IgIgorICAgICAgICAgICAgICAgICAgICAgICAgInJlY3Vyc2lvbiBlcnJvcnMiKTsKKyAgICBlbHNlIHsKKyAgICAgICAgUHlCYXNlRXhjZXB0aW9uT2JqZWN0ICplcnJfaW5zdCA9CisgICAgICAgICAgICAoUHlCYXNlRXhjZXB0aW9uT2JqZWN0ICopUHlFeGNfUmVjdXJzaW9uRXJyb3JJbnN0OworICAgICAgICBQeU9iamVjdCAqYXJnc190dXBsZTsKKyAgICAgICAgUHlPYmplY3QgKmV4Y19tZXNzYWdlOworICAgICAgICBleGNfbWVzc2FnZSA9IFB5U3RyaW5nX0Zyb21TdHJpbmcoIm1heGltdW0gcmVjdXJzaW9uIGRlcHRoIGV4Y2VlZGVkIik7CisgICAgICAgIGlmICghZXhjX21lc3NhZ2UpCisgICAgICAgICAgICBQeV9GYXRhbEVycm9yKCJjYW5ub3QgYWxsb2NhdGUgYXJndW1lbnQgZm9yIFJ1bnRpbWVFcnJvciAiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgInByZS1hbGxvY2F0aW9uIik7CisgICAgICAgIGFyZ3NfdHVwbGUgPSBQeVR1cGxlX1BhY2soMSwgZXhjX21lc3NhZ2UpOworICAgICAgICBpZiAoIWFyZ3NfdHVwbGUpCisgICAgICAgICAgICBQeV9GYXRhbEVycm9yKCJjYW5ub3QgYWxsb2NhdGUgdHVwbGUgZm9yIFJ1bnRpbWVFcnJvciAiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgInByZS1hbGxvY2F0aW9uIik7CisgICAgICAgIFB5X0RFQ1JFRihleGNfbWVzc2FnZSk7CisgICAgICAgIGlmIChCYXNlRXhjZXB0aW9uX2luaXQoZXJyX2luc3QsIGFyZ3NfdHVwbGUsIE5VTEwpKQorICAgICAgICAgICAgUHlfRmF0YWxFcnJvcigiaW5pdCBvZiBwcmUtYWxsb2NhdGVkIFJ1bnRpbWVFcnJvciBmYWlsZWQiKTsKKyAgICAgICAgUHlfREVDUkVGKGFyZ3NfdHVwbGUpOworICAgIH0KKyAgICBQeV9ERUNSRUYoYmx0aW5tb2QpOworfQorCit2b2lkCitfUHlFeGNfRmluaSh2b2lkKQoreworICAgIFB5X0NMRUFSKFB5RXhjX01lbW9yeUVycm9ySW5zdCk7CisgICAgUHlfQ0xFQVIoUHlFeGNfUmVjdXJzaW9uRXJyb3JJbnN0KTsKK30KZGlmZiAtLWdpdCBhL1B5dGhvbi0yLjcuNS9PYmplY3RzL2ZpbGVvYmplY3QuYyBiL1B5dGhvbi0yLjcuNS9PYmplY3RzL2ZpbGVvYmplY3QuYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43NmNkZjc0Ci0tLSAvZGV2L251bGwKKysrIGIvUHl0aG9uLTIuNy41L09iamVjdHMvZmlsZW9iamVjdC5jCkBAIC0wLDAgKzEsMjg4NCBAQAorLyogRmlsZSBvYmplY3QgaW1wbGVtZW50YXRpb24gKi8KKworI2RlZmluZSBQWV9TU0laRV9UX0NMRUFOCisjaW5jbHVkZSAiUHl0aG9uLmgiCisjaW5jbHVkZSAic3RydWN0bWVtYmVyLmgiCisKKyNpZmRlZiBIQVZFX1NZU19UWVBFU19ICisjaW5jbHVkZSA8c3lzL3R5cGVzLmg+CisjZW5kaWYgLyogSEFWRV9TWVNfVFlQRVNfSCAqLworCisjaWZkZWYgTVNfV0lORE9XUworI2RlZmluZSBmaWxlbm8gX2ZpbGVubworLyogY2FuIHNpbXVsYXRlIHRydW5jYXRlIHdpdGggV2luMzIgQVBJIGZ1bmN0aW9uczsgc2VlIGZpbGVfdHJ1bmNhdGUgKi8KKyNkZWZpbmUgSEFWRV9GVFJVTkNBVEUKKyNkZWZpbmUgV0lOMzJfTEVBTl9BTkRfTUVBTgorI2luY2x1ZGUgPHdpbmRvd3MuaD4KKyNlbmRpZgorCisjaWYgZGVmaW5lZChQWU9TX09TMikgJiYgZGVmaW5lZChQWUNDX0dDQykKKyNpbmNsdWRlIDxpby5oPgorI2VuZGlmCisKKyNkZWZpbmUgQlVGKHYpIFB5U3RyaW5nX0FTX1NUUklORygoUHlTdHJpbmdPYmplY3QgKil2KQorCisjaWZkZWYgSEFWRV9FUlJOT19ICisjaW5jbHVkZSA8ZXJybm8uaD4KKyNlbmRpZgorCisjaWZkZWYgSEFWRV9HRVRDX1VOTE9DS0VECisjZGVmaW5lIEdFVEMoZikgZ2V0Y191bmxvY2tlZChmKQorI2RlZmluZSBGTE9DS0ZJTEUoZikgZmxvY2tmaWxlKGYpCisjZGVmaW5lIEZVTkxPQ0tGSUxFKGYpIGZ1bmxvY2tmaWxlKGYpCisjZWxzZQorI2RlZmluZSBHRVRDKGYpIGdldGMoZikKKyNkZWZpbmUgRkxPQ0tGSUxFKGYpCisjZGVmaW5lIEZVTkxPQ0tGSUxFKGYpCisjZW5kaWYKKworLyogQml0cyBpbiBmX25ld2xpbmV0eXBlcyAqLworI2RlZmluZSBORVdMSU5FX1VOS05PV04gMCAgICAgICAvKiBObyBuZXdsaW5lIHNlZW4sIHlldCAqLworI2RlZmluZSBORVdMSU5FX0NSIDEgICAgICAgICAgICAvKiBcciBuZXdsaW5lIHNlZW4gKi8KKyNkZWZpbmUgTkVXTElORV9MRiAyICAgICAgICAgICAgLyogXG4gbmV3bGluZSBzZWVuICovCisjZGVmaW5lIE5FV0xJTkVfQ1JMRiA0ICAgICAgICAgIC8qIFxyXG4gbmV3bGluZSBzZWVuICovCisKKy8qCisgKiBUaGVzZSBtYWNyb3MgcmVsZWFzZSB0aGUgR0lMIHdoaWxlIHByZXZlbnRpbmcgdGhlIGZfY2xvc2UoKSBmdW5jdGlvbiBiZWluZworICogY2FsbGVkIGluIHRoZSBpbnRlcnZhbCBiZXR3ZWVuIHRoZW0uICBGb3IgdGhhdCBwdXJwb3NlLCBhIHJ1bm5pbmcgdG90YWwgb2YKKyAqIHRoZSBudW1iZXIgb2YgY3VycmVudGx5IHJ1bm5pbmcgdW5sb2NrZWQgY29kZSBzZWN0aW9ucyBpcyBrZXB0IGluCisgKiB0aGUgdW5sb2NrZWRfY291bnQgZmllbGQgb2YgdGhlIFB5RmlsZU9iamVjdC4gVGhlIGNsb3NlKCkgbWV0aG9kIHJhaXNlcworICogYW4gSU9FcnJvciBpZiB0aGF0IGZpZWxkIGlzIG5vbi16ZXJvLiAgU2VlIGlzc3VlICM4MTU2NDYsICM1OTU2MDEuCisgKi8KKworI2RlZmluZSBGSUxFX0JFR0lOX0FMTE9XX1RIUkVBRFMoZm9iaikgXAoreyBcCisgICAgZm9iai0+dW5sb2NrZWRfY291bnQrKzsgXAorICAgIFB5X0JFR0lOX0FMTE9XX1RIUkVBRFMKKworI2RlZmluZSBGSUxFX0VORF9BTExPV19USFJFQURTKGZvYmopIFwKKyAgICBQeV9FTkRfQUxMT1dfVEhSRUFEUyBcCisgICAgZm9iai0+dW5sb2NrZWRfY291bnQtLTsgXAorICAgIGFzc2VydChmb2JqLT51bmxvY2tlZF9jb3VudCA+PSAwKTsgXAorfQorCisjZGVmaW5lIEZJTEVfQUJPUlRfQUxMT1dfVEhSRUFEUyhmb2JqKSBcCisgICAgUHlfQkxPQ0tfVEhSRUFEUyBcCisgICAgZm9iai0+dW5sb2NrZWRfY291bnQtLTsgXAorICAgIGFzc2VydChmb2JqLT51bmxvY2tlZF9jb3VudCA+PSAwKTsKKworI2lmZGVmIF9fY3BsdXNwbHVzCitleHRlcm4gIkMiIHsKKyNlbmRpZgorCitGSUxFICoKK1B5RmlsZV9Bc0ZpbGUoUHlPYmplY3QgKmYpCit7CisgICAgaWYgKGYgPT0gTlVMTCB8fCAhUHlGaWxlX0NoZWNrKGYpKQorICAgICAgICByZXR1cm4gTlVMTDsKKyAgICBlbHNlCisgICAgICAgIHJldHVybiAoKFB5RmlsZU9iamVjdCAqKWYpLT5mX2ZwOworfQorCit2b2lkIFB5RmlsZV9JbmNVc2VDb3VudChQeUZpbGVPYmplY3QgKmZvYmopCit7CisgICAgZm9iai0+dW5sb2NrZWRfY291bnQrKzsKK30KKwordm9pZCBQeUZpbGVfRGVjVXNlQ291bnQoUHlGaWxlT2JqZWN0ICpmb2JqKQoreworICAgIGZvYmotPnVubG9ja2VkX2NvdW50LS07CisgICAgYXNzZXJ0KGZvYmotPnVubG9ja2VkX2NvdW50ID49IDApOworfQorCitQeU9iamVjdCAqCitQeUZpbGVfTmFtZShQeU9iamVjdCAqZikKK3sKKyAgICBpZiAoZiA9PSBOVUxMIHx8ICFQeUZpbGVfQ2hlY2soZikpCisgICAgICAgIHJldHVybiBOVUxMOworICAgIGVsc2UKKyAgICAgICAgcmV0dXJuICgoUHlGaWxlT2JqZWN0ICopZiktPmZfbmFtZTsKK30KKworLyogVGhpcyBpcyBhIHNhZmUgd3JhcHBlciBhcm91bmQgUHlPYmplY3RfUHJpbnQgdG8gcHJpbnQgdG8gdGhlIEZJTEUKKyAgIG9mIGEgUHlGaWxlT2JqZWN0LiBQeU9iamVjdF9QcmludCByZWxlYXNlcyB0aGUgR0lMIGJ1dCBrbm93cyBub3RoaW5nCisgICBhYm91dCBQeUZpbGVPYmplY3QuICovCitzdGF0aWMgaW50CitmaWxlX1B5T2JqZWN0X1ByaW50KFB5T2JqZWN0ICpvcCwgUHlGaWxlT2JqZWN0ICpmLCBpbnQgZmxhZ3MpCit7CisgICAgaW50IHJlc3VsdDsKKyAgICBQeUZpbGVfSW5jVXNlQ291bnQoZik7CisgICAgcmVzdWx0ID0gUHlPYmplY3RfUHJpbnQob3AsIGYtPmZfZnAsIGZsYWdzKTsKKyAgICBQeUZpbGVfRGVjVXNlQ291bnQoZik7CisgICAgcmV0dXJuIHJlc3VsdDsKK30KKworLyogT24gVW5peCwgZm9wZW4gd2lsbCBzdWNjZWVkIGZvciBkaXJlY3Rvcmllcy4KKyAgIEluIFB5dGhvbiwgdGhlcmUgc2hvdWxkIGJlIG5vIGZpbGUgb2JqZWN0cyByZWZlcnJpbmcgdG8KKyAgIGRpcmVjdG9yaWVzLCBzbyB3ZSBuZWVkIGEgY2hlY2suICAqLworCitzdGF0aWMgUHlGaWxlT2JqZWN0KgorZGlyY2hlY2soUHlGaWxlT2JqZWN0KiBmKQoreworI2lmIGRlZmluZWQoSEFWRV9GU1RBVCkgJiYgZGVmaW5lZChTX0lGRElSKSAmJiBkZWZpbmVkKEVJU0RJUikKKyAgICBzdHJ1Y3Qgc3RhdCBidWY7CisgICAgaWYgKGYtPmZfZnAgPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIGY7CisgICAgaWYgKGZzdGF0KGZpbGVubyhmLT5mX2ZwKSwgJmJ1ZikgPT0gMCAmJgorICAgICAgICBTX0lTRElSKGJ1Zi5zdF9tb2RlKSkgeworICAgICAgICBjaGFyICptc2cgPSBzdHJlcnJvcihFSVNESVIpOworICAgICAgICBQeU9iamVjdCAqZXhjID0gUHlPYmplY3RfQ2FsbEZ1bmN0aW9uKFB5RXhjX0lPRXJyb3IsICIoaXNPKSIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRUlTRElSLCBtc2csIGYtPmZfbmFtZSk7CisgICAgICAgIFB5RXJyX1NldE9iamVjdChQeUV4Y19JT0Vycm9yLCBleGMpOworICAgICAgICBQeV9YREVDUkVGKGV4Yyk7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyNlbmRpZgorICAgIHJldHVybiBmOworfQorCisKK3N0YXRpYyBQeU9iamVjdCAqCitmaWxsX2ZpbGVfZmllbGRzKFB5RmlsZU9iamVjdCAqZiwgRklMRSAqZnAsIFB5T2JqZWN0ICpuYW1lLCBjaGFyICptb2RlLAorICAgICAgICAgICAgICAgICBpbnQgKCpjbG9zZSkoRklMRSAqKSkKK3sKKyAgICBhc3NlcnQobmFtZSAhPSBOVUxMKTsKKyAgICBhc3NlcnQoZiAhPSBOVUxMKTsKKyAgICBhc3NlcnQoUHlGaWxlX0NoZWNrKGYpKTsKKyAgICBhc3NlcnQoZi0+Zl9mcCA9PSBOVUxMKTsKKworICAgIFB5X0RFQ1JFRihmLT5mX25hbWUpOworICAgIFB5X0RFQ1JFRihmLT5mX21vZGUpOworICAgIFB5X0RFQ1JFRihmLT5mX2VuY29kaW5nKTsKKyAgICBQeV9ERUNSRUYoZi0+Zl9lcnJvcnMpOworCisgICAgUHlfSU5DUkVGKG5hbWUpOworICAgIGYtPmZfbmFtZSA9IG5hbWU7CisKKyAgICBmLT5mX21vZGUgPSBQeVN0cmluZ19Gcm9tU3RyaW5nKG1vZGUpOworCisgICAgZi0+Zl9jbG9zZSA9IGNsb3NlOworICAgIGYtPmZfc29mdHNwYWNlID0gMDsKKyAgICBmLT5mX2JpbmFyeSA9IHN0cmNocihtb2RlLCdiJykgIT0gTlVMTDsKKyAgICBmLT5mX2J1ZiA9IE5VTEw7CisgICAgZi0+Zl91bml2X25ld2xpbmUgPSAoc3RyY2hyKG1vZGUsICdVJykgIT0gTlVMTCk7CisgICAgZi0+Zl9uZXdsaW5ldHlwZXMgPSBORVdMSU5FX1VOS05PV047CisgICAgZi0+Zl9za2lwbmV4dGxmID0gMDsKKyAgICBQeV9JTkNSRUYoUHlfTm9uZSk7CisgICAgZi0+Zl9lbmNvZGluZyA9IFB5X05vbmU7CisgICAgUHlfSU5DUkVGKFB5X05vbmUpOworICAgIGYtPmZfZXJyb3JzID0gUHlfTm9uZTsKKyAgICBmLT5yZWFkYWJsZSA9IGYtPndyaXRhYmxlID0gMDsKKyAgICBpZiAoc3RyY2hyKG1vZGUsICdyJykgIT0gTlVMTCB8fCBmLT5mX3VuaXZfbmV3bGluZSkKKyAgICAgICAgZi0+cmVhZGFibGUgPSAxOworICAgIGlmIChzdHJjaHIobW9kZSwgJ3cnKSAhPSBOVUxMIHx8IHN0cmNocihtb2RlLCAnYScpICE9IE5VTEwpCisgICAgICAgIGYtPndyaXRhYmxlID0gMTsKKyAgICBpZiAoc3RyY2hyKG1vZGUsICcrJykgIT0gTlVMTCkKKyAgICAgICAgZi0+cmVhZGFibGUgPSBmLT53cml0YWJsZSA9IDE7CisKKyAgICBpZiAoZi0+Zl9tb2RlID09IE5VTEwpCisgICAgICAgIHJldHVybiBOVUxMOworICAgIGYtPmZfZnAgPSBmcDsKKyAgICBmID0gZGlyY2hlY2soZik7CisgICAgcmV0dXJuIChQeU9iamVjdCAqKSBmOworfQorCisjaWYgZGVmaW5lZCBfTVNDX1ZFUiAmJiBfTVNDX1ZFUiA+PSAxNDAwICYmIGRlZmluZWQoX19TVERDX1NFQ1VSRV9MSUJfXykKKyNkZWZpbmUgUHlfVkVSSUZZX1dJTk5UCisvKiBUaGUgQ1JUIG9uIHdpbmRvd3MgY29tcGlsZWQgd2l0aCBWaXN1YWwgU3R1ZGlvIDIwMDUgYW5kIGhpZ2hlciBtYXkKKyAqIGFzc2VydCBpZiBnaXZlbiBpbnZhbGlkIG1vZGUgc3RyaW5ncy4gIFRoaXMgaXMgYWxsIGZpbmUgYW5kIHdlbGwKKyAqIGluIHN0YXRpYyBsYW5ndWFnZXMgbGlrZSBDIHdoZXJlIHRoZSBtb2RlIHN0cmluZyBpcyB0eXBjaWFsbHkgaGFyZAorICogY29kZWQuICBCdXQgaW4gUHl0aG9uLCB3ZXJlIHdlIHBhc3MgaW4gdGhlIG1vZGUgc3RyaW5nIGZyb20gdGhlIHVzZXIsCisgKiB3ZSBuZWVkIHRvIHZlcmlmeSBpdCBmaXJzdCBtYW51YWxseQorICovCitzdGF0aWMgaW50IF9QeVZlcmlmeV9Nb2RlX1dJTk5UKGNvbnN0IGNoYXIgKm1vZGUpCit7CisgICAgLyogU2VlIGlmIG1vZGUgc3RyaW5nIGlzIHZhbGlkIG9uIFdpbmRvd3MgdG8gYXZvaWQgaGFyZCBhc3NlcnRpb25zICovCisgICAgLyogcmVtb3ZlIGxlYWRpbmcgc3BhY2VzZSAqLworICAgIGludCBzaW5nbGVzID0gMDsKKyAgICBpbnQgcGFpcnMgPSAwOworICAgIGludCBlbmNvZGluZyA9IDA7CisgICAgY29uc3QgY2hhciAqcywgKmM7CisKKyAgICB3aGlsZSgqbW9kZSA9PSAnICcpIC8qIHN0cmlwIGluaXRpYWwgc3BhY2VzICovCisgICAgICAgICsrbW9kZTsKKyAgICBpZiAoIXN0cmNocigicndhIiwgKm1vZGUpKSAvKiBtdXN0IHN0YXJ0IHdpdGggb25lIG9mIHRoZXNlICovCisgICAgICAgIHJldHVybiAwOworICAgIHdoaWxlICgqKyttb2RlKSB7CisgICAgICAgIGlmICgqbW9kZSA9PSAnICcgfHwgKm1vZGUgPT0gJ04nKSAvKiBpZ25vcmUgc3BhY2VzIGFuZCBOICovCisgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgcyA9ICIrVEQiOyAvKiBlYWNoIG9mIHRoaXMgY2FuIGFwcGVhciBvbmx5IG9uY2UgKi8KKyAgICAgICAgYyA9IHN0cmNocihzLCAqbW9kZSk7CisgICAgICAgIGlmIChjKSB7CisgICAgICAgICAgICBwdHJkaWZmX3QgaWR4ID0gcy1jOworICAgICAgICAgICAgaWYgKHNpbmdsZXMgJiAoMTw8aWR4KSkKKyAgICAgICAgICAgICAgICByZXR1cm4gMDsKKyAgICAgICAgICAgIHNpbmdsZXMgfD0gKDE8PGlkeCk7CisgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgfQorICAgICAgICBzID0gImJ0Y25TUiI7IC8qIG9ubHkgb25lIG9mIGVhY2ggbGV0dGVyIGluIHRoZSBwYWlycyBhbGxvd2VkICovCisgICAgICAgIGMgPSBzdHJjaHIocywgKm1vZGUpOworICAgICAgICBpZiAoYykgeworICAgICAgICAgICAgcHRyZGlmZl90IGlkeCA9IChzLWMpLzI7CisgICAgICAgICAgICBpZiAocGFpcnMgJiAoMTw8aWR4KSkKKyAgICAgICAgICAgICAgICByZXR1cm4gMDsKKyAgICAgICAgICAgIHBhaXJzIHw9ICgxPDxpZHgpOworICAgICAgICAgICAgY29udGludWU7CisgICAgICAgIH0KKyAgICAgICAgaWYgKCptb2RlID09ICcsJykgeworICAgICAgICAgICAgZW5jb2RpbmcgPSAxOworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIDA7IC8qIGZvdW5kIGFuIGludmFsaWQgY2hhciAqLworICAgIH0KKworICAgIGlmIChlbmNvZGluZykgeworICAgICAgICBjaGFyICplW10gPSB7IlVURi04IiwgIlVURi0xNkxFIiwgIlVOSUNPREUifTsKKyAgICAgICAgd2hpbGUgKCptb2RlID09ICcgJykKKyAgICAgICAgICAgICsrbW9kZTsKKyAgICAgICAgLyogZmluZCAnY2NzID0nICovCisgICAgICAgIGlmIChzdHJuY21wKG1vZGUsICJjY3MiLCAzKSkKKyAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICBtb2RlICs9IDM7CisgICAgICAgIHdoaWxlICgqbW9kZSA9PSAnICcpCisgICAgICAgICAgICArK21vZGU7CisgICAgICAgIGlmICgqbW9kZSAhPSAnPScpCisgICAgICAgICAgICByZXR1cm4gMDsKKyAgICAgICAgd2hpbGUgKCptb2RlID09ICcgJykKKyAgICAgICAgICAgICsrbW9kZTsKKyAgICAgICAgZm9yKGVuY29kaW5nID0gMDsgZW5jb2Rpbmc8X2NvdW50b2YoZSk7ICsrZW5jb2RpbmcpIHsKKyAgICAgICAgICAgIHNpemVfdCBsID0gc3RybGVuKGVbZW5jb2RpbmddKTsKKyAgICAgICAgICAgIGlmICghc3RybmNtcChtb2RlLCBlW2VuY29kaW5nXSwgbCkpIHsKKyAgICAgICAgICAgICAgICBtb2RlICs9IGw7IC8qIGZvdW5kIGEgdmFsaWQgZW5jb2RpbmcgKi8KKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBpZiAoZW5jb2RpbmcgPT0gX2NvdW50b2YoZSkpCisgICAgICAgICAgICByZXR1cm4gMDsKKyAgICB9CisgICAgLyogc2tpcCB0cmFpbGluZyBzcGFjZXMgKi8KKyAgICB3aGlsZSAoKm1vZGUgPT0gJyAnKQorICAgICAgICArK21vZGU7CisKKyAgICByZXR1cm4gKm1vZGUgPT0gJ1wwJzsgLyogbXVzdCBiZSBhdCB0aGUgZW5kIG9mIHRoZSBzdHJpbmcgKi8KK30KKyNlbmRpZgorCisvKiBjaGVjayBmb3Iga25vd24gaW5jb3JyZWN0IG1vZGUgc3RyaW5ncyAtIHByb2JsZW0gaXMsIHBsYXRmb3JtcyBhcmUKKyAgIGZyZWUgdG8gYWNjZXB0IGFueSBtb2RlIGNoYXJhY3RlcnMgdGhleSBsaWtlIGFuZCBhcmUgc3VwcG9zZWQgdG8KKyAgIGlnbm9yZSBzdHVmZiB0aGV5IGRvbid0IHVuZGVyc3RhbmQuLi4gd3JpdGUgb3IgYXBwZW5kIG1vZGUgd2l0aAorICAgdW5pdmVyc2FsIG5ld2xpbmUgc3VwcG9ydCBpcyBleHByZXNzbHkgZm9yYmlkZGVuIGJ5IFBFUCAyNzguCisgICBBZGRpdGlvbmFsbHksIHJlbW92ZSB0aGUgJ1UnIGZyb20gdGhlIG1vZGUgc3RyaW5nIGFzIHBsYXRmb3JtcworICAgd29uJ3Qga25vdyB3aGF0IGl0IGlzLiBOb24temVybyByZXR1cm4gc2lnbmFscyBhbiBleGNlcHRpb24gKi8KK2ludAorX1B5RmlsZV9TYW5pdGl6ZU1vZGUoY2hhciAqbW9kZSkKK3sKKyAgICBjaGFyICp1cG9zOworICAgIHNpemVfdCBsZW4gPSBzdHJsZW4obW9kZSk7CisKKyAgICBpZiAoIWxlbikgeworICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfVmFsdWVFcnJvciwgImVtcHR5IG1vZGUgc3RyaW5nIik7CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisKKyAgICB1cG9zID0gc3RyY2hyKG1vZGUsICdVJyk7CisgICAgaWYgKHVwb3MpIHsKKyAgICAgICAgbWVtbW92ZSh1cG9zLCB1cG9zKzEsIGxlbi0odXBvcy1tb2RlKSk7IC8qIGluY2wgbnVsbCBjaGFyICovCisKKyAgICAgICAgaWYgKG1vZGVbMF0gPT0gJ3cnIHx8IG1vZGVbMF0gPT0gJ2EnKSB7CisgICAgICAgICAgICBQeUVycl9Gb3JtYXQoUHlFeGNfVmFsdWVFcnJvciwgInVuaXZlcnNhbCBuZXdsaW5lICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAibW9kZSBjYW4gb25seSBiZSB1c2VkIHdpdGggbW9kZXMgIgorICAgICAgICAgICAgICAgICAgICAgICAgICJzdGFydGluZyB3aXRoICdyJyIpOworICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICB9CisKKyAgICAgICAgaWYgKG1vZGVbMF0gIT0gJ3InKSB7CisgICAgICAgICAgICBtZW1tb3ZlKG1vZGUrMSwgbW9kZSwgc3RybGVuKG1vZGUpKzEpOworICAgICAgICAgICAgbW9kZVswXSA9ICdyJzsKKyAgICAgICAgfQorCisgICAgICAgIGlmICghc3RyY2hyKG1vZGUsICdiJykpIHsKKyAgICAgICAgICAgIG1lbW1vdmUobW9kZSsyLCBtb2RlKzEsIHN0cmxlbihtb2RlKSk7CisgICAgICAgICAgICBtb2RlWzFdID0gJ2InOworICAgICAgICB9CisgICAgfSBlbHNlIGlmIChtb2RlWzBdICE9ICdyJyAmJiBtb2RlWzBdICE9ICd3JyAmJiBtb2RlWzBdICE9ICdhJykgeworICAgICAgICBQeUVycl9Gb3JtYXQoUHlFeGNfVmFsdWVFcnJvciwgIm1vZGUgc3RyaW5nIG11c3QgYmVnaW4gd2l0aCAiCisgICAgICAgICAgICAgICAgICAgICJvbmUgb2YgJ3InLCAndycsICdhJyBvciAnVScsIG5vdCAnJS4yMDBzJyIsIG1vZGUpOworICAgICAgICByZXR1cm4gLTE7CisgICAgfQorI2lmZGVmIFB5X1ZFUklGWV9XSU5OVAorICAgIC8qIGFkZGl0aW9uYWwgY2hlY2tzIG9uIE5UIHdpdGggdmlzdWFsIHN0dWRpbyAyMDA1IGFuZCBoaWdoZXIgKi8KKyAgICBpZiAoIV9QeVZlcmlmeV9Nb2RlX1dJTk5UKG1vZGUpKSB7CisgICAgICAgIFB5RXJyX0Zvcm1hdChQeUV4Y19WYWx1ZUVycm9yLCAiSW52YWxpZCBtb2RlICgnJS41MHMnKSIsIG1vZGUpOworICAgICAgICByZXR1cm4gLTE7CisgICAgfQorI2VuZGlmCisgICAgcmV0dXJuIDA7Cit9CisKK3N0YXRpYyBQeU9iamVjdCAqCitvcGVuX3RoZV9maWxlKFB5RmlsZU9iamVjdCAqZiwgY2hhciAqbmFtZSwgY2hhciAqbW9kZSkKK3sKKyAgICBjaGFyICpuZXdtb2RlOworICAgIGFzc2VydChmICE9IE5VTEwpOworICAgIGFzc2VydChQeUZpbGVfQ2hlY2soZikpOworI2lmZGVmIE1TX1dJTkRPV1MKKyAgICAvKiB3aW5kb3dzIGlnbm9yZXMgdGhlIHBhc3NlZCBuYW1lIGluIG9yZGVyIHRvIHN1cHBvcnQgVW5pY29kZSAqLworICAgIGFzc2VydChmLT5mX25hbWUgIT0gTlVMTCk7CisjZWxzZQorICAgIGFzc2VydChuYW1lICE9IE5VTEwpOworI2VuZGlmCisgICAgYXNzZXJ0KG1vZGUgIT0gTlVMTCk7CisgICAgYXNzZXJ0KGYtPmZfZnAgPT0gTlVMTCk7CisKKyAgICAvKiBwcm9iYWJseSBuZWVkIHRvIHJlcGxhY2UgJ1UnIGJ5ICdyYicgKi8KKyAgICBuZXdtb2RlID0gUHlNZW1fTUFMTE9DKHN0cmxlbihtb2RlKSArIDMpOworICAgIGlmICghbmV3bW9kZSkgeworICAgICAgICBQeUVycl9Ob01lbW9yeSgpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgc3RyY3B5KG5ld21vZGUsIG1vZGUpOworCisgICAgaWYgKF9QeUZpbGVfU2FuaXRpemVNb2RlKG5ld21vZGUpKSB7CisgICAgICAgIGYgPSBOVUxMOworICAgICAgICBnb3RvIGNsZWFudXA7CisgICAgfQorCisgICAgLyogcmV4ZWMucHkgY2FuJ3Qgc3RvcCBhIHVzZXIgZnJvbSBnZXR0aW5nIHRoZSBmaWxlKCkgY29uc3RydWN0b3IgLS0KKyAgICAgICBhbGwgdGhleSBoYXZlIHRvIGRvIGlzIGdldCAqYW55KiBmaWxlIG9iamVjdCBmLCBhbmQgdGhlbiBkbworICAgICAgIHR5cGUoZikuICBIZXJlIHdlIHByZXZlbnQgdGhlbSBmcm9tIGRvaW5nIGRhbWFnZSB3aXRoIGl0LiAqLworICAgIGlmIChQeUV2YWxfR2V0UmVzdHJpY3RlZCgpKSB7CisgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19JT0Vycm9yLAorICAgICAgICAiZmlsZSgpIGNvbnN0cnVjdG9yIG5vdCBhY2Nlc3NpYmxlIGluIHJlc3RyaWN0ZWQgbW9kZSIpOworICAgICAgICBmID0gTlVMTDsKKyAgICAgICAgZ290byBjbGVhbnVwOworICAgIH0KKyAgICBlcnJubyA9IDA7CisKKyNpZmRlZiBNU19XSU5ET1dTCisgICAgaWYgKFB5VW5pY29kZV9DaGVjayhmLT5mX25hbWUpKSB7CisgICAgICAgIFB5T2JqZWN0ICp3bW9kZTsKKyAgICAgICAgd21vZGUgPSBQeVVuaWNvZGVfRGVjb2RlQVNDSUkobmV3bW9kZSwgc3RybGVuKG5ld21vZGUpLCBOVUxMKTsKKyAgICAgICAgaWYgKGYtPmZfbmFtZSAmJiB3bW9kZSkgeworICAgICAgICAgICAgRklMRV9CRUdJTl9BTExPV19USFJFQURTKGYpCisgICAgICAgICAgICAvKiBQeVVuaWNvZGVfQVNfVU5JQ09ERSBPSyB3aXRob3V0IHRocmVhZAorICAgICAgICAgICAgICAgbG9jayBhcyBpdCBpcyBhIHNpbXBsZSBkZXJlZmVyZW5jZS4gKi8KKyAgICAgICAgICAgIGYtPmZfZnAgPSBfd2ZvcGVuKFB5VW5pY29kZV9BU19VTklDT0RFKGYtPmZfbmFtZSksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQeVVuaWNvZGVfQVNfVU5JQ09ERSh3bW9kZSkpOworICAgICAgICAgICAgRklMRV9FTkRfQUxMT1dfVEhSRUFEUyhmKQorICAgICAgICB9CisgICAgICAgIFB5X1hERUNSRUYod21vZGUpOworICAgIH0KKyNlbmRpZgorICAgIGlmIChOVUxMID09IGYtPmZfZnAgJiYgTlVMTCAhPSBuYW1lKSB7CisgICAgICAgIEZJTEVfQkVHSU5fQUxMT1dfVEhSRUFEUyhmKQorICAgICAgICBmLT5mX2ZwID0gZm9wZW4obmFtZSwgbmV3bW9kZSk7CisgICAgICAgIEZJTEVfRU5EX0FMTE9XX1RIUkVBRFMoZikKKyAgICB9CisKKyAgICBpZiAoZi0+Zl9mcCA9PSBOVUxMKSB7CisjaWYgZGVmaW5lZCAgX01TQ19WRVIgJiYgKF9NU0NfVkVSIDwgMTQwMCB8fCAhZGVmaW5lZChfX1NURENfU0VDVVJFX0xJQl9fKSkKKyAgICAgICAgLyogTVNWQyA2IChNaWNyb3NvZnQpIGxlYXZlcyBlcnJubyBhdCAwIGZvciBiYWQgbW9kZSBzdHJpbmdzLAorICAgICAgICAgKiBhY3Jvc3MgYWxsIFdpbmRvd3MgZmxhdm9ycy4gIFdoZW4gaXQgc2V0cyBFSU5WQUwgdmFyaWVzCisgICAgICAgICAqIGFjcm9zcyBXaW5kb3dzIGZsYXZvcnMsIHRoZSBleGFjdCBjb25kaXRpb25zIGFyZW4ndAorICAgICAgICAgKiBkb2N1bWVudGVkLCBhbmQgdGhlIGFuc3dlciBsaWVzIGluIHRoZSBPUydzIGltcGxlbWVudGF0aW9uCisgICAgICAgICAqIG9mIFdpbjMyJ3MgQ3JlYXRlRmlsZSBmdW5jdGlvbiAod2hvc2Ugc291cmNlIGlzIHNlY3JldCkuCisgICAgICAgICAqIFNlZW1zIHRoZSBiZXN0IHdlIGNhbiBkbyBpcyBtYXAgRUlOVkFMIHRvIEVOT0VOVC4KKyAgICAgICAgICogU3RhcnRpbmcgd2l0aCBWaXN1YWwgU3R1ZGlvIC5ORVQgMjAwNSwgRUlOVkFMIGlzIGNvcnJlY3RseQorICAgICAgICAgKiBzZXQgYnkgb3VyIENSVCBlcnJvciBoYW5kbGVyIChzZXQgaW4gZXhjZXB0aW9ucy5jLikKKyAgICAgICAgICovCisgICAgICAgIGlmIChlcnJubyA9PSAwKSAgICAgICAgIC8qIGJhZCBtb2RlIHN0cmluZyAqLworICAgICAgICAgICAgZXJybm8gPSBFSU5WQUw7CisgICAgICAgIGVsc2UgaWYgKGVycm5vID09IEVJTlZBTCkgLyogdW5rbm93biwgYnV0IG5vdCBhIG1vZGUgc3RyaW5nICovCisgICAgICAgICAgICBlcnJubyA9IEVOT0VOVDsKKyNlbmRpZgorICAgICAgICAvKiBFSU5WQUwgaXMgcmV0dXJuZWQgd2hlbiBhbiBpbnZhbGlkIGZpbGVuYW1lIG9yCisgICAgICAgICAqIGFuIGludmFsaWQgbW9kZSBpcyBzdXBwbGllZC4gKi8KKyAgICAgICAgaWYgKGVycm5vID09IEVJTlZBTCkgeworICAgICAgICAgICAgUHlPYmplY3QgKnY7CisgICAgICAgICAgICBjaGFyIG1lc3NhZ2VbMTAwXTsKKyAgICAgICAgICAgIFB5T1Nfc25wcmludGYobWVzc2FnZSwgMTAwLAorICAgICAgICAgICAgICAgICJpbnZhbGlkIG1vZGUgKCclLjUwcycpIG9yIGZpbGVuYW1lIiwgbW9kZSk7CisgICAgICAgICAgICB2ID0gUHlfQnVpbGRWYWx1ZSgiKGlzTykiLCBlcnJubywgbWVzc2FnZSwgZi0+Zl9uYW1lKTsKKyAgICAgICAgICAgIGlmICh2ICE9IE5VTEwpIHsKKyAgICAgICAgICAgICAgICBQeUVycl9TZXRPYmplY3QoUHlFeGNfSU9FcnJvciwgdik7CisgICAgICAgICAgICAgICAgUHlfREVDUkVGKHYpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGVsc2UKKyAgICAgICAgICAgIFB5RXJyX1NldEZyb21FcnJub1dpdGhGaWxlbmFtZU9iamVjdChQeUV4Y19JT0Vycm9yLCBmLT5mX25hbWUpOworICAgICAgICBmID0gTlVMTDsKKyAgICB9CisgICAgaWYgKGYgIT0gTlVMTCkKKyAgICAgICAgZiA9IGRpcmNoZWNrKGYpOworCitjbGVhbnVwOgorICAgIFB5TWVtX0ZSRUUobmV3bW9kZSk7CisKKyAgICByZXR1cm4gKFB5T2JqZWN0ICopZjsKK30KKworc3RhdGljIFB5T2JqZWN0ICoKK2Nsb3NlX3RoZV9maWxlKFB5RmlsZU9iamVjdCAqZikKK3sKKyAgICBpbnQgc3RzID0gMDsKKyAgICBpbnQgKCpsb2NhbF9jbG9zZSkoRklMRSAqKTsKKyAgICBGSUxFICpsb2NhbF9mcCA9IGYtPmZfZnA7CisgICAgY2hhciAqbG9jYWxfc2V0YnVmID0gZi0+Zl9zZXRidWY7CisgICAgaWYgKGxvY2FsX2ZwICE9IE5VTEwpIHsKKyAgICAgICAgbG9jYWxfY2xvc2UgPSBmLT5mX2Nsb3NlOworICAgICAgICBpZiAobG9jYWxfY2xvc2UgIT0gTlVMTCAmJiBmLT51bmxvY2tlZF9jb3VudCA+IDApIHsKKyAgICAgICAgICAgIGlmIChmLT5vYl9yZWZjbnQgPiAwKSB7CisgICAgICAgICAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX0lPRXJyb3IsCisgICAgICAgICAgICAgICAgICAgICJjbG9zZSgpIGNhbGxlZCBkdXJpbmcgY29uY3VycmVudCAiCisgICAgICAgICAgICAgICAgICAgICJvcGVyYXRpb24gb24gdGhlIHNhbWUgZmlsZSBvYmplY3QuIik7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIC8qIFRoaXMgc2hvdWxkIG5vdCBoYXBwZW4gdW5sZXNzIHNvbWVvbmUgaXMKKyAgICAgICAgICAgICAgICAgKiBjYXJlbGVzc2x5IHBsYXlpbmcgd2l0aCB0aGUgUHlGaWxlT2JqZWN0CisgICAgICAgICAgICAgICAgICogc3RydWN0IGZpZWxkcyBhbmQvb3IgaXRzIGFzc29jaWF0ZWQgRklMRQorICAgICAgICAgICAgICAgICAqIHBvaW50ZXIuICovCisgICAgICAgICAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1N5c3RlbUVycm9yLAorICAgICAgICAgICAgICAgICAgICAiUHlGaWxlT2JqZWN0IGxvY2tpbmcgZXJyb3IgaW4gIgorICAgICAgICAgICAgICAgICAgICAiZGVzdHJ1Y3RvciAocmVmY250IDw9IDAgYXQgY2xvc2UpLiIpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgICAgIH0KKyAgICAgICAgLyogTlVMTCBvdXQgdGhlIEZJTEUgcG9pbnRlciBiZWZvcmUgcmVsZWFzaW5nIHRoZSBHSUwsIGJlY2F1c2UKKyAgICAgICAgICogaXQgd2lsbCBub3QgYmUgdmFsaWQgYW55bW9yZSBhZnRlciB0aGUgY2xvc2UoKSBmdW5jdGlvbiBpcworICAgICAgICAgKiBjYWxsZWQuICovCisgICAgICAgIGYtPmZfZnAgPSBOVUxMOworICAgICAgICBpZiAobG9jYWxfY2xvc2UgIT0gTlVMTCkgeworICAgICAgICAgICAgLyogSXNzdWUgIzkyOTU6IG11c3QgdGVtcG9yYXJpbHkgcmVzZXQgZl9zZXRidWYgc28gdGhhdCBhbm90aGVyCisgICAgICAgICAgICAgICB0aHJlYWQgZG9lc24ndCBmcmVlIGl0IHdoZW4gcnVubmluZyBmaWxlX2Nsb3NlKCkgY29uY3VycmVudGx5LgorICAgICAgICAgICAgICAgT3RoZXJ3aXNlIHRoaXMgY2xvc2UoKSB3aWxsIGNyYXNoIHdoZW4gZmx1c2hpbmcgdGhlIGJ1ZmZlci4gKi8KKyAgICAgICAgICAgIGYtPmZfc2V0YnVmID0gTlVMTDsKKyAgICAgICAgICAgIFB5X0JFR0lOX0FMTE9XX1RIUkVBRFMKKyAgICAgICAgICAgIGVycm5vID0gMDsKKyAgICAgICAgICAgIHN0cyA9ICgqbG9jYWxfY2xvc2UpKGxvY2FsX2ZwKTsKKyAgICAgICAgICAgIFB5X0VORF9BTExPV19USFJFQURTCisgICAgICAgICAgICBmLT5mX3NldGJ1ZiA9IGxvY2FsX3NldGJ1ZjsKKyAgICAgICAgICAgIGlmIChzdHMgPT0gRU9GKQorICAgICAgICAgICAgICAgIHJldHVybiBQeUVycl9TZXRGcm9tRXJybm8oUHlFeGNfSU9FcnJvcik7CisgICAgICAgICAgICBpZiAoc3RzICE9IDApCisgICAgICAgICAgICAgICAgcmV0dXJuIFB5SW50X0Zyb21Mb25nKChsb25nKXN0cyk7CisgICAgICAgIH0KKyAgICB9CisgICAgUHlfUkVUVVJOX05PTkU7Cit9CisKK1B5T2JqZWN0ICoKK1B5RmlsZV9Gcm9tRmlsZShGSUxFICpmcCwgY2hhciAqbmFtZSwgY2hhciAqbW9kZSwgaW50ICgqY2xvc2UpKEZJTEUgKikpCit7CisgICAgUHlGaWxlT2JqZWN0ICpmOworICAgIFB5T2JqZWN0ICpvX25hbWU7CisKKyAgICBmID0gKFB5RmlsZU9iamVjdCAqKVB5RmlsZV9UeXBlLnRwX25ldygmUHlGaWxlX1R5cGUsIE5VTEwsIE5VTEwpOworICAgIGlmIChmID09IE5VTEwpCisgICAgICAgIHJldHVybiBOVUxMOworICAgIG9fbmFtZSA9IFB5U3RyaW5nX0Zyb21TdHJpbmcobmFtZSk7CisgICAgaWYgKG9fbmFtZSA9PSBOVUxMKSB7CisgICAgICAgIGlmIChjbG9zZSAhPSBOVUxMICYmIGZwICE9IE5VTEwpCisgICAgICAgICAgICBjbG9zZShmcCk7CisgICAgICAgIFB5X0RFQ1JFRihmKTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIGlmIChmaWxsX2ZpbGVfZmllbGRzKGYsIGZwLCBvX25hbWUsIG1vZGUsIGNsb3NlKSA9PSBOVUxMKSB7CisgICAgICAgIFB5X0RFQ1JFRihmKTsKKyAgICAgICAgUHlfREVDUkVGKG9fbmFtZSk7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICBQeV9ERUNSRUYob19uYW1lKTsKKyAgICByZXR1cm4gKFB5T2JqZWN0ICopZjsKK30KKworUHlPYmplY3QgKgorUHlGaWxlX0Zyb21TdHJpbmcoY2hhciAqbmFtZSwgY2hhciAqbW9kZSkKK3sKKyAgICBleHRlcm4gaW50IGZjbG9zZShGSUxFICopOworICAgIFB5RmlsZU9iamVjdCAqZjsKKworICAgIGYgPSAoUHlGaWxlT2JqZWN0ICopUHlGaWxlX0Zyb21GaWxlKChGSUxFICopTlVMTCwgbmFtZSwgbW9kZSwgZmNsb3NlKTsKKyAgICBpZiAoZiAhPSBOVUxMKSB7CisgICAgICAgIGlmIChvcGVuX3RoZV9maWxlKGYsIG5hbWUsIG1vZGUpID09IE5VTEwpIHsKKyAgICAgICAgICAgIFB5X0RFQ1JFRihmKTsKKyAgICAgICAgICAgIGYgPSBOVUxMOworICAgICAgICB9CisgICAgfQorICAgIHJldHVybiAoUHlPYmplY3QgKilmOworfQorCit2b2lkCitQeUZpbGVfU2V0QnVmU2l6ZShQeU9iamVjdCAqZiwgaW50IGJ1ZnNpemUpCit7CisgICAgUHlGaWxlT2JqZWN0ICpmaWxlID0gKFB5RmlsZU9iamVjdCAqKWY7CisgICAgaWYgKGJ1ZnNpemUgPj0gMCkgeworICAgICAgICBpbnQgdHlwZTsKKyAgICAgICAgc3dpdGNoIChidWZzaXplKSB7CisgICAgICAgIGNhc2UgMDoKKyAgICAgICAgICAgIHR5cGUgPSBfSU9OQkY7CisgICAgICAgICAgICBicmVhazsKKyNpZmRlZiBIQVZFX1NFVFZCVUYKKyAgICAgICAgY2FzZSAxOgorICAgICAgICAgICAgdHlwZSA9IF9JT0xCRjsKKyAgICAgICAgICAgIGJ1ZnNpemUgPSBCVUZTSVo7CisgICAgICAgICAgICBicmVhazsKKyNlbmRpZgorICAgICAgICBkZWZhdWx0OgorICAgICAgICAgICAgdHlwZSA9IF9JT0ZCRjsKKyNpZm5kZWYgSEFWRV9TRVRWQlVGCisgICAgICAgICAgICBidWZzaXplID0gQlVGU0laOworI2VuZGlmCisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgfQorICAgICAgICBmZmx1c2goZmlsZS0+Zl9mcCk7CisgICAgICAgIGlmICh0eXBlID09IF9JT05CRikgeworICAgICAgICAgICAgUHlNZW1fRnJlZShmaWxlLT5mX3NldGJ1Zik7CisgICAgICAgICAgICBmaWxlLT5mX3NldGJ1ZiA9IE5VTEw7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBmaWxlLT5mX3NldGJ1ZiA9IChjaGFyICopUHlNZW1fUmVhbGxvYyhmaWxlLT5mX3NldGJ1ZiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBidWZzaXplKTsKKyAgICAgICAgfQorI2lmZGVmIEhBVkVfU0VUVkJVRgorICAgICAgICBzZXR2YnVmKGZpbGUtPmZfZnAsIGZpbGUtPmZfc2V0YnVmLCB0eXBlLCBidWZzaXplKTsKKyNlbHNlIC8qICFIQVZFX1NFVFZCVUYgKi8KKyAgICAgICAgc2V0YnVmKGZpbGUtPmZfZnAsIGZpbGUtPmZfc2V0YnVmKTsKKyNlbmRpZiAvKiAhSEFWRV9TRVRWQlVGICovCisgICAgfQorfQorCisvKiBTZXQgdGhlIGVuY29kaW5nIHVzZWQgdG8gb3V0cHV0IFVuaWNvZGUgc3RyaW5ncy4KKyAgIFJldHVybiAxIG9uIHN1Y2Nlc3MsIDAgb24gZmFpbHVyZS4gKi8KKworaW50CitQeUZpbGVfU2V0RW5jb2RpbmcoUHlPYmplY3QgKmYsIGNvbnN0IGNoYXIgKmVuYykKK3sKKyAgICByZXR1cm4gUHlGaWxlX1NldEVuY29kaW5nQW5kRXJyb3JzKGYsIGVuYywgTlVMTCk7Cit9CisKK2ludAorUHlGaWxlX1NldEVuY29kaW5nQW5kRXJyb3JzKFB5T2JqZWN0ICpmLCBjb25zdCBjaGFyICplbmMsIGNoYXIqIGVycm9ycykKK3sKKyAgICBQeUZpbGVPYmplY3QgKmZpbGUgPSAoUHlGaWxlT2JqZWN0KilmOworICAgIFB5T2JqZWN0ICpzdHIsICpvZXJyb3JzOworCisgICAgYXNzZXJ0KFB5RmlsZV9DaGVjayhmKSk7CisgICAgc3RyID0gUHlTdHJpbmdfRnJvbVN0cmluZyhlbmMpOworICAgIGlmICghc3RyKQorICAgICAgICByZXR1cm4gMDsKKyAgICBpZiAoZXJyb3JzKSB7CisgICAgICAgIG9lcnJvcnMgPSBQeVN0cmluZ19Gcm9tU3RyaW5nKGVycm9ycyk7CisgICAgICAgIGlmICghb2Vycm9ycykgeworICAgICAgICAgICAgUHlfREVDUkVGKHN0cik7CisgICAgICAgICAgICByZXR1cm4gMDsKKyAgICAgICAgfQorICAgIH0gZWxzZSB7CisgICAgICAgIG9lcnJvcnMgPSBQeV9Ob25lOworICAgICAgICBQeV9JTkNSRUYoUHlfTm9uZSk7CisgICAgfQorICAgIFB5X0RFQ1JFRihmaWxlLT5mX2VuY29kaW5nKTsKKyAgICBmaWxlLT5mX2VuY29kaW5nID0gc3RyOworICAgIFB5X0RFQ1JFRihmaWxlLT5mX2Vycm9ycyk7CisgICAgZmlsZS0+Zl9lcnJvcnMgPSBvZXJyb3JzOworICAgIHJldHVybiAxOworfQorCitzdGF0aWMgUHlPYmplY3QgKgorZXJyX2Nsb3NlZCh2b2lkKQoreworICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19WYWx1ZUVycm9yLCAiSS9PIG9wZXJhdGlvbiBvbiBjbG9zZWQgZmlsZSIpOworICAgIHJldHVybiBOVUxMOworfQorCitzdGF0aWMgUHlPYmplY3QgKgorZXJyX21vZGUoY2hhciAqYWN0aW9uKQoreworICAgIFB5RXJyX0Zvcm1hdChQeUV4Y19JT0Vycm9yLCAiRmlsZSBub3Qgb3BlbiBmb3IgJXMiLCBhY3Rpb24pOworICAgIHJldHVybiBOVUxMOworfQorCisvKiBSZWZ1c2UgcmVndWxhciBmaWxlIEkvTyBpZiB0aGVyZSdzIGRhdGEgaW4gdGhlIGl0ZXJhdGlvbi1idWZmZXIuCisgKiBNaXhpbmcgdGhlbSB3b3VsZCBjYXVzZSBkYXRhIHRvIGFycml2ZSBvdXQgb2Ygb3JkZXIsIGFzIHRoZSByZWFkKgorICogbWV0aG9kcyBkb24ndCB1c2UgdGhlIGl0ZXJhdGlvbiBidWZmZXIuICovCitzdGF0aWMgUHlPYmplY3QgKgorZXJyX2l0ZXJidWZmZXJlZCh2b2lkKQoreworICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19WYWx1ZUVycm9yLAorICAgICAgICAiTWl4aW5nIGl0ZXJhdGlvbiBhbmQgcmVhZCBtZXRob2RzIHdvdWxkIGxvc2UgZGF0YSIpOworICAgIHJldHVybiBOVUxMOworfQorCitzdGF0aWMgdm9pZCBkcm9wX3JlYWRhaGVhZChQeUZpbGVPYmplY3QgKik7CisKKy8qIE1ldGhvZHMgKi8KKworc3RhdGljIHZvaWQKK2ZpbGVfZGVhbGxvYyhQeUZpbGVPYmplY3QgKmYpCit7CisgICAgUHlPYmplY3QgKnJldDsKKyAgICBpZiAoZi0+d2Vha3JlZmxpc3QgIT0gTlVMTCkKKyAgICAgICAgUHlPYmplY3RfQ2xlYXJXZWFrUmVmcygoUHlPYmplY3QgKikgZik7CisgICAgcmV0ID0gY2xvc2VfdGhlX2ZpbGUoZik7CisgICAgaWYgKCFyZXQpIHsKKyAgICAgICAgUHlTeXNfV3JpdGVTdGRlcnIoImNsb3NlIGZhaWxlZCBpbiBmaWxlIG9iamVjdCBkZXN0cnVjdG9yOlxuIik7CisgICAgICAgIFB5RXJyX1ByaW50KCk7CisgICAgfQorICAgIGVsc2UgeworICAgICAgICBQeV9ERUNSRUYocmV0KTsKKyAgICB9CisgICAgUHlNZW1fRnJlZShmLT5mX3NldGJ1Zik7CisgICAgUHlfWERFQ1JFRihmLT5mX25hbWUpOworICAgIFB5X1hERUNSRUYoZi0+Zl9tb2RlKTsKKyAgICBQeV9YREVDUkVGKGYtPmZfZW5jb2RpbmcpOworICAgIFB5X1hERUNSRUYoZi0+Zl9lcnJvcnMpOworICAgIGRyb3BfcmVhZGFoZWFkKGYpOworICAgIFB5X1RZUEUoZiktPnRwX2ZyZWUoKFB5T2JqZWN0ICopZik7Cit9CisKK3N0YXRpYyBQeU9iamVjdCAqCitmaWxlX3JlcHIoUHlGaWxlT2JqZWN0ICpmKQoreworICAgIFB5T2JqZWN0ICpyZXQgPSBOVUxMOworICAgIFB5T2JqZWN0ICpuYW1lID0gTlVMTDsKKyAgICBpZiAoUHlVbmljb2RlX0NoZWNrKGYtPmZfbmFtZSkpIHsKKyNpZmRlZiBQeV9VU0lOR19VTklDT0RFCisgICAgICAgIGNvbnN0IGNoYXIgKm5hbWVfc3RyOworICAgICAgICBuYW1lID0gUHlVbmljb2RlX0FzVW5pY29kZUVzY2FwZVN0cmluZyhmLT5mX25hbWUpOworICAgICAgICBuYW1lX3N0ciA9IG5hbWUgPyBQeVN0cmluZ19Bc1N0cmluZyhuYW1lKSA6ICI/IjsKKyAgICAgICAgcmV0ID0gUHlTdHJpbmdfRnJvbUZvcm1hdCgiPCVzIGZpbGUgdSclcycsIG1vZGUgJyVzJyBhdCAlcD4iLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgZi0+Zl9mcCA9PSBOVUxMID8gImNsb3NlZCIgOiAib3BlbiIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lX3N0ciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIFB5U3RyaW5nX0FzU3RyaW5nKGYtPmZfbW9kZSksCisgICAgICAgICAgICAgICAgICAgICAgICAgICBmKTsKKyAgICAgICAgUHlfWERFQ1JFRihuYW1lKTsKKyAgICAgICAgcmV0dXJuIHJldDsKKyNlbmRpZgorICAgIH0gZWxzZSB7CisgICAgICAgIG5hbWUgPSBQeU9iamVjdF9SZXByKGYtPmZfbmFtZSk7CisgICAgICAgIGlmIChuYW1lID09IE5VTEwpCisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgcmV0ID0gUHlTdHJpbmdfRnJvbUZvcm1hdCgiPCVzIGZpbGUgJXMsIG1vZGUgJyVzJyBhdCAlcD4iLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgZi0+Zl9mcCA9PSBOVUxMID8gImNsb3NlZCIgOiAib3BlbiIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBQeVN0cmluZ19Bc1N0cmluZyhuYW1lKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIFB5U3RyaW5nX0FzU3RyaW5nKGYtPmZfbW9kZSksCisgICAgICAgICAgICAgICAgICAgICAgICAgICBmKTsKKyAgICAgICAgUHlfWERFQ1JFRihuYW1lKTsKKyAgICAgICAgcmV0dXJuIHJldDsKKyAgICB9Cit9CisKK3N0YXRpYyBQeU9iamVjdCAqCitmaWxlX2Nsb3NlKFB5RmlsZU9iamVjdCAqZikKK3sKKyAgICBQeU9iamVjdCAqc3RzID0gY2xvc2VfdGhlX2ZpbGUoZik7CisgICAgaWYgKHN0cykgeworICAgICAgICBQeU1lbV9GcmVlKGYtPmZfc2V0YnVmKTsKKyAgICAgICAgZi0+Zl9zZXRidWYgPSBOVUxMOworICAgIH0KKyAgICByZXR1cm4gc3RzOworfQorCisKKy8qIE91ciB2ZXJ5IG93biBvZmZfdC1saWtlIHR5cGUsIDY0LWJpdCBpZiBwb3NzaWJsZSAqLworI2lmICFkZWZpbmVkKEhBVkVfTEFSR0VGSUxFX1NVUFBPUlQpCit0eXBlZGVmIG9mZl90IFB5X29mZl90OworI2VsaWYgU0laRU9GX09GRl9UID49IDgKK3R5cGVkZWYgb2ZmX3QgUHlfb2ZmX3Q7CisjZWxpZiBTSVpFT0ZfRlBPU19UID49IDgKK3R5cGVkZWYgZnBvc190IFB5X29mZl90OworI2Vsc2UKKyNlcnJvciAiTGFyZ2UgZmlsZSBzdXBwb3J0LCBidXQgbmVpdGhlciBvZmZfdCBub3IgZnBvc190IGlzIGxhcmdlIGVub3VnaC4iCisjZW5kaWYKKworCisvKiBhIHBvcnRhYmxlIGZzZWVrKCkgZnVuY3Rpb24KKyAgIHJldHVybiAwIG9uIHN1Y2Nlc3MsIG5vbi16ZXJvIG9uIGZhaWx1cmUgKHdpdGggZXJybm8gc2V0KSAqLworc3RhdGljIGludAorX3BvcnRhYmxlX2ZzZWVrKEZJTEUgKmZwLCBQeV9vZmZfdCBvZmZzZXQsIGludCB3aGVuY2UpCit7CisjaWYgIWRlZmluZWQoSEFWRV9MQVJHRUZJTEVfU1VQUE9SVCkKKyAgICByZXR1cm4gZnNlZWsoZnAsIG9mZnNldCwgd2hlbmNlKTsKKyNlbGlmIGRlZmluZWQoSEFWRV9GU0VFS08pICYmIFNJWkVPRl9PRkZfVCA+PSA4CisgICAgcmV0dXJuIGZzZWVrbyhmcCwgb2Zmc2V0LCB3aGVuY2UpOworI2VsaWYgZGVmaW5lZChIQVZFX0ZTRUVLNjQpCisgICAgcmV0dXJuIGZzZWVrNjQoZnAsIG9mZnNldCwgd2hlbmNlKTsKKyNlbGlmIGRlZmluZWQoX19CRU9TX18pCisgICAgcmV0dXJuIF9mc2VlayhmcCwgb2Zmc2V0LCB3aGVuY2UpOworI2VsaWYgU0laRU9GX0ZQT1NfVCA+PSA4CisgICAgLyogbGFja2luZyBhIDY0LWJpdCBjYXBhYmxlIGZzZWVrKCksIHVzZSBhIDY0LWJpdCBjYXBhYmxlIGZzZXRwb3MoKQorICAgICAgIGFuZCBmZ2V0cG9zKCkgdG8gaW1wbGVtZW50IGZzZWVrKCkqLworICAgIGZwb3NfdCBwb3M7CisgICAgc3dpdGNoICh3aGVuY2UpIHsKKyAgICBjYXNlIFNFRUtfRU5EOgorI2lmZGVmIE1TX1dJTkRPV1MKKyAgICAgICAgZmZsdXNoKGZwKTsKKyAgICAgICAgaWYgKF9sc2Vla2k2NChmaWxlbm8oZnApLCAwLCAyKSA9PSAtMSkKKyAgICAgICAgICAgIHJldHVybiAtMTsKKyNlbHNlCisgICAgICAgIGlmIChmc2VlayhmcCwgMCwgU0VFS19FTkQpICE9IDApCisgICAgICAgICAgICByZXR1cm4gLTE7CisjZW5kaWYKKyAgICAgICAgLyogZmFsbCB0aHJvdWdoICovCisgICAgY2FzZSBTRUVLX0NVUjoKKyAgICAgICAgaWYgKGZnZXRwb3MoZnAsICZwb3MpICE9IDApCisgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgIG9mZnNldCArPSBwb3M7CisgICAgICAgIGJyZWFrOworICAgIC8qIGNhc2UgU0VFS19TRVQ6IGJyZWFrOyAqLworICAgIH0KKyAgICByZXR1cm4gZnNldHBvcyhmcCwgJm9mZnNldCk7CisjZWxzZQorI2Vycm9yICJMYXJnZSBmaWxlIHN1cHBvcnQsIGJ1dCBubyB3YXkgdG8gZnNlZWsuIgorI2VuZGlmCit9CisKKworLyogYSBwb3J0YWJsZSBmdGVsbCgpIGZ1bmN0aW9uCisgICBSZXR1cm4gLTEgb24gZmFpbHVyZSB3aXRoIGVycm5vIHNldCBhcHByb3ByaWF0ZWx5LCBjdXJyZW50IGZpbGUKKyAgIHBvc2l0aW9uIG9uIHN1Y2Nlc3MgKi8KK3N0YXRpYyBQeV9vZmZfdAorX3BvcnRhYmxlX2Z0ZWxsKEZJTEUqIGZwKQoreworI2lmICFkZWZpbmVkKEhBVkVfTEFSR0VGSUxFX1NVUFBPUlQpCisgICAgcmV0dXJuIGZ0ZWxsKGZwKTsKKyNlbGlmIGRlZmluZWQoSEFWRV9GVEVMTE8pICYmIFNJWkVPRl9PRkZfVCA+PSA4CisgICAgcmV0dXJuIGZ0ZWxsbyhmcCk7CisjZWxpZiBkZWZpbmVkKEhBVkVfRlRFTEw2NCkKKyAgICByZXR1cm4gZnRlbGw2NChmcCk7CisjZWxpZiBTSVpFT0ZfRlBPU19UID49IDgKKyAgICBmcG9zX3QgcG9zOworICAgIGlmIChmZ2V0cG9zKGZwLCAmcG9zKSAhPSAwKQorICAgICAgICByZXR1cm4gLTE7CisgICAgcmV0dXJuIHBvczsKKyNlbHNlCisjZXJyb3IgIkxhcmdlIGZpbGUgc3VwcG9ydCwgYnV0IG5vIHdheSB0byBmdGVsbC4iCisjZW5kaWYKK30KKworCitzdGF0aWMgUHlPYmplY3QgKgorZmlsZV9zZWVrKFB5RmlsZU9iamVjdCAqZiwgUHlPYmplY3QgKmFyZ3MpCit7CisgICAgaW50IHdoZW5jZTsKKyAgICBpbnQgcmV0OworICAgIFB5X29mZl90IG9mZnNldDsKKyAgICBQeU9iamVjdCAqb2Zmb2JqLCAqb2ZmX2luZGV4OworCisgICAgaWYgKGYtPmZfZnAgPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIGVycl9jbG9zZWQoKTsKKyAgICBkcm9wX3JlYWRhaGVhZChmKTsKKyAgICB3aGVuY2UgPSAwOworICAgIGlmICghUHlBcmdfUGFyc2VUdXBsZShhcmdzLCAiT3xpOnNlZWsiLCAmb2Zmb2JqLCAmd2hlbmNlKSkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgb2ZmX2luZGV4ID0gUHlOdW1iZXJfSW5kZXgob2Zmb2JqKTsKKyAgICBpZiAoIW9mZl9pbmRleCkgeworICAgICAgICBpZiAoIVB5RmxvYXRfQ2hlY2sob2Zmb2JqKSkKKyAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgICAgICAvKiBEZXByZWNhdGVkIGluIDIuNiAqLworICAgICAgICBQeUVycl9DbGVhcigpOworICAgICAgICBpZiAoUHlFcnJfV2FybkV4KFB5RXhjX0RlcHJlY2F0aW9uV2FybmluZywKKyAgICAgICAgICAgICAgICAgICAgICAgICAiaW50ZWdlciBhcmd1bWVudCBleHBlY3RlZCwgZ290IGZsb2F0IiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAxKSA8IDApCisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgb2ZmX2luZGV4ID0gb2Zmb2JqOworICAgICAgICBQeV9JTkNSRUYob2Zmb2JqKTsKKyAgICB9CisjaWYgIWRlZmluZWQoSEFWRV9MQVJHRUZJTEVfU1VQUE9SVCkKKyAgICBvZmZzZXQgPSBQeUludF9Bc0xvbmcob2ZmX2luZGV4KTsKKyNlbHNlCisgICAgb2Zmc2V0ID0gUHlMb25nX0NoZWNrKG9mZl9pbmRleCkgPworICAgICAgICBQeUxvbmdfQXNMb25nTG9uZyhvZmZfaW5kZXgpIDogUHlJbnRfQXNMb25nKG9mZl9pbmRleCk7CisjZW5kaWYKKyAgICBQeV9ERUNSRUYob2ZmX2luZGV4KTsKKyAgICBpZiAoUHlFcnJfT2NjdXJyZWQoKSkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisKKyAgICBGSUxFX0JFR0lOX0FMTE9XX1RIUkVBRFMoZikKKyAgICBlcnJubyA9IDA7CisgICAgcmV0ID0gX3BvcnRhYmxlX2ZzZWVrKGYtPmZfZnAsIG9mZnNldCwgd2hlbmNlKTsKKyAgICBGSUxFX0VORF9BTExPV19USFJFQURTKGYpCisKKyAgICBpZiAocmV0ICE9IDApIHsKKyAgICAgICAgUHlFcnJfU2V0RnJvbUVycm5vKFB5RXhjX0lPRXJyb3IpOworICAgICAgICBjbGVhcmVycihmLT5mX2ZwKTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIGYtPmZfc2tpcG5leHRsZiA9IDA7CisgICAgUHlfSU5DUkVGKFB5X05vbmUpOworICAgIHJldHVybiBQeV9Ob25lOworfQorCisKKyNpZmRlZiBIQVZFX0ZUUlVOQ0FURQorc3RhdGljIFB5T2JqZWN0ICoKK2ZpbGVfdHJ1bmNhdGUoUHlGaWxlT2JqZWN0ICpmLCBQeU9iamVjdCAqYXJncykKK3sKKyAgICBQeV9vZmZfdCBuZXdzaXplOworICAgIFB5T2JqZWN0ICpuZXdzaXplb2JqID0gTlVMTDsKKyAgICBQeV9vZmZfdCBpbml0aWFscG9zOworICAgIGludCByZXQ7CisKKyAgICBpZiAoZi0+Zl9mcCA9PSBOVUxMKQorICAgICAgICByZXR1cm4gZXJyX2Nsb3NlZCgpOworICAgIGlmICghZi0+d3JpdGFibGUpCisgICAgICAgIHJldHVybiBlcnJfbW9kZSgid3JpdGluZyIpOworICAgIGlmICghUHlBcmdfVW5wYWNrVHVwbGUoYXJncywgInRydW5jYXRlIiwgMCwgMSwgJm5ld3NpemVvYmopKQorICAgICAgICByZXR1cm4gTlVMTDsKKworICAgIC8qIEdldCBjdXJyZW50IGZpbGUgcG9zaXRpb24uICBJZiB0aGUgZmlsZSBoYXBwZW5zIHRvIGJlIG9wZW4gZm9yCisgICAgICogdXBkYXRlIGFuZCB0aGUgbGFzdCBvcGVyYXRpb24gd2FzIGFuIGlucHV0IG9wZXJhdGlvbiwgQyBkb2Vzbid0CisgICAgICogZGVmaW5lIHdoYXQgdGhlIGxhdGVyIGZmbHVzaCgpIHdpbGwgZG8sIGJ1dCB3ZSBwcm9taXNlIHRydW5jYXRlKCkKKyAgICAgKiB3b24ndCBjaGFuZ2UgdGhlIGN1cnJlbnQgcG9zaXRpb24gKGFuZCBmZmx1c2goKSAqZG9lcyogY2hhbmdlIGl0CisgICAgICogdGhlbiBhdCBsZWFzdCBvbiBXaW5kb3dzKS4gIFRoZSBlYXNpZXN0IHRoaW5nIGlzIHRvIGNhcHR1cmUKKyAgICAgKiBjdXJyZW50IHBvcyBub3cgYW5kIHNlZWsgYmFjayB0byBpdCBhdCB0aGUgZW5kLgorICAgICAqLworICAgIEZJTEVfQkVHSU5fQUxMT1dfVEhSRUFEUyhmKQorICAgIGVycm5vID0gMDsKKyAgICBpbml0aWFscG9zID0gX3BvcnRhYmxlX2Z0ZWxsKGYtPmZfZnApOworICAgIEZJTEVfRU5EX0FMTE9XX1RIUkVBRFMoZikKKyAgICBpZiAoaW5pdGlhbHBvcyA9PSAtMSkKKyAgICAgICAgZ290byBvbmlvZXJyb3I7CisKKyAgICAvKiBTZXQgbmV3c2l6ZSB0byBjdXJyZW50IHBvc3Rpb24gaWYgbmV3c2l6ZW9iaiBOVUxMLCBlbHNlIHRvIHRoZQorICAgICAqIHNwZWNpZmllZCB2YWx1ZS4KKyAgICAgKi8KKyAgICBpZiAobmV3c2l6ZW9iaiAhPSBOVUxMKSB7CisjaWYgIWRlZmluZWQoSEFWRV9MQVJHRUZJTEVfU1VQUE9SVCkKKyAgICAgICAgbmV3c2l6ZSA9IFB5SW50X0FzTG9uZyhuZXdzaXplb2JqKTsKKyNlbHNlCisgICAgICAgIG5ld3NpemUgPSBQeUxvbmdfQ2hlY2sobmV3c2l6ZW9iaikgPworICAgICAgICAgICAgICAgICAgICAgICAgUHlMb25nX0FzTG9uZ0xvbmcobmV3c2l6ZW9iaikgOgorICAgICAgICAgICAgICAgIFB5SW50X0FzTG9uZyhuZXdzaXplb2JqKTsKKyNlbmRpZgorICAgICAgICBpZiAoUHlFcnJfT2NjdXJyZWQoKSkKKyAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICBlbHNlIC8qIGRlZmF1bHQgdG8gY3VycmVudCBwb3NpdGlvbiAqLworICAgICAgICBuZXdzaXplID0gaW5pdGlhbHBvczsKKworICAgIC8qIEZsdXNoIHRoZSBzdHJlYW0uICBXZSdyZSBtaXhpbmcgc3RyZWFtLWxldmVsIEkvTyB3aXRoIGxvd2VyLWxldmVsCisgICAgICogSS9PLCBhbmQgYSBmbHVzaCBtYXkgYmUgbmVjZXNzYXJ5IHRvIHN5bmNoIGJvdGggcGxhdGZvcm0gdmlld3MKKyAgICAgKiBvZiB0aGUgY3VycmVudCBmaWxlIHN0YXRlLgorICAgICAqLworICAgIEZJTEVfQkVHSU5fQUxMT1dfVEhSRUFEUyhmKQorICAgIGVycm5vID0gMDsKKyAgICByZXQgPSBmZmx1c2goZi0+Zl9mcCk7CisgICAgRklMRV9FTkRfQUxMT1dfVEhSRUFEUyhmKQorICAgIGlmIChyZXQgIT0gMCkKKyAgICAgICAgZ290byBvbmlvZXJyb3I7CisKKyNpZmRlZiBNU19XSU5ET1dTCisgICAgLyogTVMgX2Noc2l6ZSBkb2Vzbid0IHdvcmsgaWYgbmV3c2l6ZSBkb2Vzbid0IGZpdCBpbiAzMiBiaXRzLAorICAgICAgIHNvIGRvbid0IGV2ZW4gdHJ5IHVzaW5nIGl0LiAqLworICAgIHsKKyAgICAgICAgSEFORExFIGhGaWxlOworCisgICAgICAgIC8qIEhhdmUgdG8gbW92ZSBjdXJyZW50IHBvcyB0byBkZXNpcmVkIGVuZHBvaW50IG9uIFdpbmRvd3MuICovCisgICAgICAgIEZJTEVfQkVHSU5fQUxMT1dfVEhSRUFEUyhmKQorICAgICAgICBlcnJubyA9IDA7CisgICAgICAgIHJldCA9IF9wb3J0YWJsZV9mc2VlayhmLT5mX2ZwLCBuZXdzaXplLCBTRUVLX1NFVCkgIT0gMDsKKyAgICAgICAgRklMRV9FTkRfQUxMT1dfVEhSRUFEUyhmKQorICAgICAgICBpZiAocmV0KQorICAgICAgICAgICAgZ290byBvbmlvZXJyb3I7CisKKyAgICAgICAgLyogVHJ1bmNhdGUuICBOb3RlIHRoYXQgdGhpcyBtYXkgZ3JvdyB0aGUgZmlsZSEgKi8KKyAgICAgICAgRklMRV9CRUdJTl9BTExPV19USFJFQURTKGYpCisgICAgICAgIGVycm5vID0gMDsKKyAgICAgICAgaEZpbGUgPSAoSEFORExFKV9nZXRfb3NmaGFuZGxlKGZpbGVubyhmLT5mX2ZwKSk7CisgICAgICAgIHJldCA9IGhGaWxlID09IChIQU5ETEUpLTE7CisgICAgICAgIGlmIChyZXQgPT0gMCkgeworICAgICAgICAgICAgcmV0ID0gU2V0RW5kT2ZGaWxlKGhGaWxlKSA9PSAwOworICAgICAgICAgICAgaWYgKHJldCkKKyAgICAgICAgICAgICAgICBlcnJubyA9IEVBQ0NFUzsKKyAgICAgICAgfQorICAgICAgICBGSUxFX0VORF9BTExPV19USFJFQURTKGYpCisgICAgICAgIGlmIChyZXQpCisgICAgICAgICAgICBnb3RvIG9uaW9lcnJvcjsKKyAgICB9CisjZWxzZQorICAgIEZJTEVfQkVHSU5fQUxMT1dfVEhSRUFEUyhmKQorICAgIGVycm5vID0gMDsKKyAgICByZXQgPSBmdHJ1bmNhdGUoZmlsZW5vKGYtPmZfZnApLCBuZXdzaXplKTsKKyAgICBGSUxFX0VORF9BTExPV19USFJFQURTKGYpCisgICAgaWYgKHJldCAhPSAwKQorICAgICAgICBnb3RvIG9uaW9lcnJvcjsKKyNlbmRpZiAvKiAhTVNfV0lORE9XUyAqLworCisgICAgLyogUmVzdG9yZSBvcmlnaW5hbCBmaWxlIHBvc2l0aW9uLiAqLworICAgIEZJTEVfQkVHSU5fQUxMT1dfVEhSRUFEUyhmKQorICAgIGVycm5vID0gMDsKKyAgICByZXQgPSBfcG9ydGFibGVfZnNlZWsoZi0+Zl9mcCwgaW5pdGlhbHBvcywgU0VFS19TRVQpICE9IDA7CisgICAgRklMRV9FTkRfQUxMT1dfVEhSRUFEUyhmKQorICAgIGlmIChyZXQpCisgICAgICAgIGdvdG8gb25pb2Vycm9yOworCisgICAgUHlfSU5DUkVGKFB5X05vbmUpOworICAgIHJldHVybiBQeV9Ob25lOworCitvbmlvZXJyb3I6CisgICAgUHlFcnJfU2V0RnJvbUVycm5vKFB5RXhjX0lPRXJyb3IpOworICAgIGNsZWFyZXJyKGYtPmZfZnApOworICAgIHJldHVybiBOVUxMOworfQorI2VuZGlmIC8qIEhBVkVfRlRSVU5DQVRFICovCisKK3N0YXRpYyBQeU9iamVjdCAqCitmaWxlX3RlbGwoUHlGaWxlT2JqZWN0ICpmKQoreworICAgIFB5X29mZl90IHBvczsKKworICAgIGlmIChmLT5mX2ZwID09IE5VTEwpCisgICAgICAgIHJldHVybiBlcnJfY2xvc2VkKCk7CisgICAgRklMRV9CRUdJTl9BTExPV19USFJFQURTKGYpCisgICAgZXJybm8gPSAwOworICAgIHBvcyA9IF9wb3J0YWJsZV9mdGVsbChmLT5mX2ZwKTsKKyAgICBGSUxFX0VORF9BTExPV19USFJFQURTKGYpCisKKyAgICBpZiAocG9zID09IC0xKSB7CisgICAgICAgIFB5RXJyX1NldEZyb21FcnJubyhQeUV4Y19JT0Vycm9yKTsKKyAgICAgICAgY2xlYXJlcnIoZi0+Zl9mcCk7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICBpZiAoZi0+Zl9za2lwbmV4dGxmKSB7CisgICAgICAgIGludCBjOworICAgICAgICBjID0gR0VUQyhmLT5mX2ZwKTsKKyAgICAgICAgaWYgKGMgPT0gJ1xuJykgeworICAgICAgICAgICAgZi0+Zl9uZXdsaW5ldHlwZXMgfD0gTkVXTElORV9DUkxGOworICAgICAgICAgICAgcG9zKys7CisgICAgICAgICAgICBmLT5mX3NraXBuZXh0bGYgPSAwOworICAgICAgICB9IGVsc2UgaWYgKGMgIT0gRU9GKSB1bmdldGMoYywgZi0+Zl9mcCk7CisgICAgfQorI2lmICFkZWZpbmVkKEhBVkVfTEFSR0VGSUxFX1NVUFBPUlQpCisgICAgcmV0dXJuIFB5SW50X0Zyb21Mb25nKHBvcyk7CisjZWxzZQorICAgIHJldHVybiBQeUxvbmdfRnJvbUxvbmdMb25nKHBvcyk7CisjZW5kaWYKK30KKworc3RhdGljIFB5T2JqZWN0ICoKK2ZpbGVfZmlsZW5vKFB5RmlsZU9iamVjdCAqZikKK3sKKyAgICBpZiAoZi0+Zl9mcCA9PSBOVUxMKQorICAgICAgICByZXR1cm4gZXJyX2Nsb3NlZCgpOworICAgIHJldHVybiBQeUludF9Gcm9tTG9uZygobG9uZykgZmlsZW5vKGYtPmZfZnApKTsKK30KKworc3RhdGljIFB5T2JqZWN0ICoKK2ZpbGVfZmx1c2goUHlGaWxlT2JqZWN0ICpmKQoreworICAgIGludCByZXM7CisKKyAgICBpZiAoZi0+Zl9mcCA9PSBOVUxMKQorICAgICAgICByZXR1cm4gZXJyX2Nsb3NlZCgpOworICAgIEZJTEVfQkVHSU5fQUxMT1dfVEhSRUFEUyhmKQorICAgIGVycm5vID0gMDsKKyAgICByZXMgPSBmZmx1c2goZi0+Zl9mcCk7CisgICAgRklMRV9FTkRfQUxMT1dfVEhSRUFEUyhmKQorICAgIGlmIChyZXMgIT0gMCkgeworICAgICAgICBQeUVycl9TZXRGcm9tRXJybm8oUHlFeGNfSU9FcnJvcik7CisgICAgICAgIGNsZWFyZXJyKGYtPmZfZnApOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgUHlfSU5DUkVGKFB5X05vbmUpOworICAgIHJldHVybiBQeV9Ob25lOworfQorCitzdGF0aWMgUHlPYmplY3QgKgorZmlsZV9pc2F0dHkoUHlGaWxlT2JqZWN0ICpmKQoreworICAgIGxvbmcgcmVzOworICAgIGlmIChmLT5mX2ZwID09IE5VTEwpCisgICAgICAgIHJldHVybiBlcnJfY2xvc2VkKCk7CisgICAgRklMRV9CRUdJTl9BTExPV19USFJFQURTKGYpCisgICAgcmVzID0gaXNhdHR5KChpbnQpZmlsZW5vKGYtPmZfZnApKTsKKyAgICBGSUxFX0VORF9BTExPV19USFJFQURTKGYpCisgICAgcmV0dXJuIFB5Qm9vbF9Gcm9tTG9uZyhyZXMpOworfQorCisKKyNpZiBCVUZTSVogPCA4MTkyCisjZGVmaW5lIFNNQUxMQ0hVTksgODE5MgorI2Vsc2UKKyNkZWZpbmUgU01BTExDSFVOSyBCVUZTSVoKKyNlbmRpZgorCitzdGF0aWMgc2l6ZV90CituZXdfYnVmZmVyc2l6ZShQeUZpbGVPYmplY3QgKmYsIHNpemVfdCBjdXJyZW50c2l6ZSkKK3sKKyNpZmRlZiBIQVZFX0ZTVEFUCisgICAgb2ZmX3QgcG9zLCBlbmQ7CisgICAgc3RydWN0IHN0YXQgc3Q7CisgICAgaWYgKGZzdGF0KGZpbGVubyhmLT5mX2ZwKSwgJnN0KSA9PSAwKSB7CisgICAgICAgIGVuZCA9IHN0LnN0X3NpemU7CisgICAgICAgIC8qIFRoZSBmb2xsb3dpbmcgaXMgbm90IGEgYnVnOiB3ZSByZWFsbHkgbmVlZCB0byBjYWxsIGxzZWVrKCkKKyAgICAgICAgICAgKmFuZCogZnRlbGwoKS4gIFRoZSByZWFzb24gaXMgdGhhdCBzb21lIHN0ZGlvIGxpYnJhcmllcworICAgICAgICAgICBtaXN0YWtlbmx5IGZsdXNoIHRoZWlyIGJ1ZmZlciB3aGVuIGZ0ZWxsKCkgaXMgY2FsbGVkIGFuZAorICAgICAgICAgICB0aGUgbHNlZWsoKSBjYWxsIGl0IG1ha2VzIGZhaWxzLCB0aGVyZWJ5IHRocm93aW5nIGF3YXkKKyAgICAgICAgICAgZGF0YSB0aGF0IGNhbm5vdCBiZSByZWNvdmVyZWQgaW4gYW55IHdheS4gIFRvIGF2b2lkIHRoaXMsCisgICAgICAgICAgIHdlIGZpcnN0IHRlc3QgbHNlZWsoKSwgYW5kIG9ubHkgY2FsbCBmdGVsbCgpIGlmIGxzZWVrKCkKKyAgICAgICAgICAgd29ya3MuICBXZSBjYW4ndCB1c2UgdGhlIGxzZWVrKCkgdmFsdWUgZWl0aGVyLCBiZWNhdXNlIHdlCisgICAgICAgICAgIG5lZWQgdG8gdGFrZSB0aGUgYW1vdW50IG9mIGJ1ZmZlcmVkIGRhdGEgaW50byBhY2NvdW50LgorICAgICAgICAgICAoWWV0IGFub3RoZXIgcmVhc29uIHdoeSBzdGRpbyBzdGlua3MuIDotKSAqLworICAgICAgICBwb3MgPSBsc2VlayhmaWxlbm8oZi0+Zl9mcCksIDBMLCBTRUVLX0NVUik7CisgICAgICAgIGlmIChwb3MgPj0gMCkgeworICAgICAgICAgICAgcG9zID0gZnRlbGwoZi0+Zl9mcCk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKHBvcyA8IDApCisgICAgICAgICAgICBjbGVhcmVycihmLT5mX2ZwKTsKKyAgICAgICAgaWYgKGVuZCA+IHBvcyAmJiBwb3MgPj0gMCkKKyAgICAgICAgICAgIHJldHVybiBjdXJyZW50c2l6ZSArIGVuZCAtIHBvcyArIDE7CisgICAgICAgIC8qIEFkZCAxIHNvIGlmIHRoZSBmaWxlIHdlcmUgdG8gZ3JvdyB3ZSdkIG5vdGljZS4gKi8KKyAgICB9CisjZW5kaWYKKyAgICAvKiBFeHBhbmQgdGhlIGJ1ZmZlciBieSBhbiBhbW91bnQgcHJvcG9ydGlvbmFsIHRvIHRoZSBjdXJyZW50IHNpemUsCisgICAgICAgZ2l2aW5nIHVzIGFtb3J0aXplZCBsaW5lYXItdGltZSBiZWhhdmlvci4gVXNlIGEgbGVzcy10aGFuLWRvdWJsZQorICAgICAgIGdyb3d0aCBmYWN0b3IgdG8gYXZvaWQgZXhjZXNzaXZlIGFsbG9jYXRpb24uICovCisgICAgcmV0dXJuIGN1cnJlbnRzaXplICsgKGN1cnJlbnRzaXplID4+IDMpICsgNjsKK30KKworI2lmIGRlZmluZWQoRVdPVUxEQkxPQ0spICYmIGRlZmluZWQoRUFHQUlOKSAmJiBFV09VTERCTE9DSyAhPSBFQUdBSU4KKyNkZWZpbmUgQkxPQ0tFRF9FUlJOTyh4KSAoKHgpID09IEVXT1VMREJMT0NLIHx8ICh4KSA9PSBFQUdBSU4pCisjZWxzZQorI2lmZGVmIEVXT1VMREJMT0NLCisjZGVmaW5lIEJMT0NLRURfRVJSTk8oeCkgKCh4KSA9PSBFV09VTERCTE9DSykKKyNlbHNlCisjaWZkZWYgRUFHQUlOCisjZGVmaW5lIEJMT0NLRURfRVJSTk8oeCkgKCh4KSA9PSBFQUdBSU4pCisjZWxzZQorI2RlZmluZSBCTE9DS0VEX0VSUk5PKHgpIDAKKyNlbmRpZgorI2VuZGlmCisjZW5kaWYKKworc3RhdGljIFB5T2JqZWN0ICoKK2ZpbGVfcmVhZChQeUZpbGVPYmplY3QgKmYsIFB5T2JqZWN0ICphcmdzKQoreworICAgIGxvbmcgYnl0ZXNyZXF1ZXN0ZWQgPSAtMTsKKyAgICBzaXplX3QgYnl0ZXNyZWFkLCBidWZmZXJzaXplLCBjaHVua3NpemU7CisgICAgUHlPYmplY3QgKnY7CisKKyAgICBpZiAoZi0+Zl9mcCA9PSBOVUxMKQorICAgICAgICByZXR1cm4gZXJyX2Nsb3NlZCgpOworICAgIGlmICghZi0+cmVhZGFibGUpCisgICAgICAgIHJldHVybiBlcnJfbW9kZSgicmVhZGluZyIpOworICAgIC8qIHJlZnVzZSB0byBtaXggd2l0aCBmLm5leHQoKSAqLworICAgIGlmIChmLT5mX2J1ZiAhPSBOVUxMICYmCisgICAgICAgIChmLT5mX2J1ZmVuZCAtIGYtPmZfYnVmcHRyKSA+IDAgJiYKKyAgICAgICAgZi0+Zl9idWZbMF0gIT0gJ1wwJykKKyAgICAgICAgcmV0dXJuIGVycl9pdGVyYnVmZmVyZWQoKTsKKyAgICBpZiAoIVB5QXJnX1BhcnNlVHVwbGUoYXJncywgInxsOnJlYWQiLCAmYnl0ZXNyZXF1ZXN0ZWQpKQorICAgICAgICByZXR1cm4gTlVMTDsKKyAgICBpZiAoYnl0ZXNyZXF1ZXN0ZWQgPCAwKQorICAgICAgICBidWZmZXJzaXplID0gbmV3X2J1ZmZlcnNpemUoZiwgKHNpemVfdCkwKTsKKyAgICBlbHNlCisgICAgICAgIGJ1ZmZlcnNpemUgPSBieXRlc3JlcXVlc3RlZDsKKyAgICBpZiAoYnVmZmVyc2l6ZSA+IFBZX1NTSVpFX1RfTUFYKSB7CisgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19PdmVyZmxvd0Vycm9yLAorICAgICJyZXF1ZXN0ZWQgbnVtYmVyIG9mIGJ5dGVzIGlzIG1vcmUgdGhhbiBhIFB5dGhvbiBzdHJpbmcgY2FuIGhvbGQiKTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIHYgPSBQeVN0cmluZ19Gcm9tU3RyaW5nQW5kU2l6ZSgoY2hhciAqKU5VTEwsIGJ1ZmZlcnNpemUpOworICAgIGlmICh2ID09IE5VTEwpCisgICAgICAgIHJldHVybiBOVUxMOworICAgIGJ5dGVzcmVhZCA9IDA7CisgICAgZm9yICg7OykgeworICAgICAgICBpbnQgaW50ZXJydXB0ZWQ7CisgICAgICAgIEZJTEVfQkVHSU5fQUxMT1dfVEhSRUFEUyhmKQorICAgICAgICBlcnJubyA9IDA7CisgICAgICAgIGNodW5rc2l6ZSA9IFB5X1VuaXZlcnNhbE5ld2xpbmVGcmVhZChCVUYodikgKyBieXRlc3JlYWQsCisgICAgICAgICAgICAgICAgICBidWZmZXJzaXplIC0gYnl0ZXNyZWFkLCBmLT5mX2ZwLCAoUHlPYmplY3QgKilmKTsKKyAgICAgICAgaW50ZXJydXB0ZWQgPSBmZXJyb3IoZi0+Zl9mcCkgJiYgZXJybm8gPT0gRUlOVFI7CisgICAgICAgIEZJTEVfRU5EX0FMTE9XX1RIUkVBRFMoZikKKyAgICAgICAgaWYgKGludGVycnVwdGVkKSB7CisgICAgICAgICAgICBjbGVhcmVycihmLT5mX2ZwKTsKKyAgICAgICAgICAgIGlmIChQeUVycl9DaGVja1NpZ25hbHMoKSkgeworICAgICAgICAgICAgICAgIFB5X0RFQ1JFRih2KTsKKyAgICAgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBpZiAoY2h1bmtzaXplID09IDApIHsKKyAgICAgICAgICAgIGlmIChpbnRlcnJ1cHRlZCkKKyAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgIGlmICghZmVycm9yKGYtPmZfZnApKQorICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgY2xlYXJlcnIoZi0+Zl9mcCk7CisgICAgICAgICAgICAvKiBXaGVuIGluIG5vbi1ibG9ja2luZyBtb2RlLCBkYXRhIHNob3VsZG4ndAorICAgICAgICAgICAgICogYmUgZGlzY2FyZGVkIGlmIGEgYmxvY2tpbmcgc2lnbmFsIHdhcworICAgICAgICAgICAgICogcmVjZWl2ZWQuIFRoYXQgd2lsbCBhbHNvIGhhcHBlbiBpZgorICAgICAgICAgICAgICogY2h1bmtzaXplICE9IDAsIGJ1dCBieXRlc3JlYWQgPCBidWZmZXJzaXplLiAqLworICAgICAgICAgICAgaWYgKGJ5dGVzcmVhZCA+IDAgJiYgQkxPQ0tFRF9FUlJOTyhlcnJubykpCisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICBQeUVycl9TZXRGcm9tRXJybm8oUHlFeGNfSU9FcnJvcik7CisgICAgICAgICAgICBQeV9ERUNSRUYodik7CisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgfQorICAgICAgICBieXRlc3JlYWQgKz0gY2h1bmtzaXplOworICAgICAgICBpZiAoYnl0ZXNyZWFkIDwgYnVmZmVyc2l6ZSAmJiAhaW50ZXJydXB0ZWQpIHsKKyAgICAgICAgICAgIGNsZWFyZXJyKGYtPmZfZnApOworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGJ5dGVzcmVxdWVzdGVkIDwgMCkgeworICAgICAgICAgICAgYnVmZmVyc2l6ZSA9IG5ld19idWZmZXJzaXplKGYsIGJ1ZmZlcnNpemUpOworICAgICAgICAgICAgaWYgKF9QeVN0cmluZ19SZXNpemUoJnYsIGJ1ZmZlcnNpemUpIDwgMCkKKyAgICAgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIC8qIEdvdCB3aGF0IHdhcyByZXF1ZXN0ZWQuICovCisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgfQorICAgIH0KKyAgICBpZiAoYnl0ZXNyZWFkICE9IGJ1ZmZlcnNpemUgJiYgX1B5U3RyaW5nX1Jlc2l6ZSgmdiwgYnl0ZXNyZWFkKSkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgcmV0dXJuIHY7Cit9CisKK3N0YXRpYyBQeU9iamVjdCAqCitmaWxlX3JlYWRpbnRvKFB5RmlsZU9iamVjdCAqZiwgUHlPYmplY3QgKmFyZ3MpCit7CisgICAgY2hhciAqcHRyOworICAgIFB5X3NzaXplX3QgbnRvZG87CisgICAgUHlfc3NpemVfdCBuZG9uZSwgbm5vdzsKKyAgICBQeV9idWZmZXIgcGJ1ZjsKKworICAgIGlmIChmLT5mX2ZwID09IE5VTEwpCisgICAgICAgIHJldHVybiBlcnJfY2xvc2VkKCk7CisgICAgaWYgKCFmLT5yZWFkYWJsZSkKKyAgICAgICAgcmV0dXJuIGVycl9tb2RlKCJyZWFkaW5nIik7CisgICAgLyogcmVmdXNlIHRvIG1peCB3aXRoIGYubmV4dCgpICovCisgICAgaWYgKGYtPmZfYnVmICE9IE5VTEwgJiYKKyAgICAgICAgKGYtPmZfYnVmZW5kIC0gZi0+Zl9idWZwdHIpID4gMCAmJgorICAgICAgICBmLT5mX2J1ZlswXSAhPSAnXDAnKQorICAgICAgICByZXR1cm4gZXJyX2l0ZXJidWZmZXJlZCgpOworICAgIGlmICghUHlBcmdfUGFyc2VUdXBsZShhcmdzLCAidyoiLCAmcGJ1ZikpCisgICAgICAgIHJldHVybiBOVUxMOworICAgIHB0ciA9IHBidWYuYnVmOworICAgIG50b2RvID0gcGJ1Zi5sZW47CisgICAgbmRvbmUgPSAwOworICAgIHdoaWxlIChudG9kbyA+IDApIHsKKyAgICAgICAgaW50IGludGVycnVwdGVkOworICAgICAgICBGSUxFX0JFR0lOX0FMTE9XX1RIUkVBRFMoZikKKyAgICAgICAgZXJybm8gPSAwOworICAgICAgICBubm93ID0gUHlfVW5pdmVyc2FsTmV3bGluZUZyZWFkKHB0cituZG9uZSwgbnRvZG8sIGYtPmZfZnAsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKFB5T2JqZWN0ICopZik7CisgICAgICAgIGludGVycnVwdGVkID0gZmVycm9yKGYtPmZfZnApICYmIGVycm5vID09IEVJTlRSOworICAgICAgICBGSUxFX0VORF9BTExPV19USFJFQURTKGYpCisgICAgICAgIGlmIChpbnRlcnJ1cHRlZCkgeworICAgICAgICAgICAgY2xlYXJlcnIoZi0+Zl9mcCk7CisgICAgICAgICAgICBpZiAoUHlFcnJfQ2hlY2tTaWduYWxzKCkpIHsKKyAgICAgICAgICAgICAgICBQeUJ1ZmZlcl9SZWxlYXNlKCZwYnVmKTsKKyAgICAgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBpZiAobm5vdyA9PSAwKSB7CisgICAgICAgICAgICBpZiAoaW50ZXJydXB0ZWQpCisgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICBpZiAoIWZlcnJvcihmLT5mX2ZwKSkKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIFB5RXJyX1NldEZyb21FcnJubyhQeUV4Y19JT0Vycm9yKTsKKyAgICAgICAgICAgIGNsZWFyZXJyKGYtPmZfZnApOworICAgICAgICAgICAgUHlCdWZmZXJfUmVsZWFzZSgmcGJ1Zik7CisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgfQorICAgICAgICBuZG9uZSArPSBubm93OworICAgICAgICBudG9kbyAtPSBubm93OworICAgIH0KKyAgICBQeUJ1ZmZlcl9SZWxlYXNlKCZwYnVmKTsKKyAgICByZXR1cm4gUHlJbnRfRnJvbVNzaXplX3QobmRvbmUpOworfQorCisvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKK1JvdXRpbmUgdG8gZ2V0IG5leHQgbGluZSB1c2luZyBwbGF0Zm9ybSBmZ2V0cygpLgorCitVbmRlciBNU1ZDIDY6CisKKysgTVMgdGhyZWFkc2FmZSBnZXRjIGlzIHZlcnkgc2xvdyAobXVsdGlwbGUgbGF5ZXJzIG9mIGZ1bmN0aW9uIGNhbGxzIGJlZm9yZSsKKyAgYWZ0ZXIgZWFjaCBjaGFyYWN0ZXIsIHRvIGxvY2srdW5sb2NrIHRoZSBzdHJlYW0pLgorKyBUaGUgc3RyZWFtLWxvY2tpbmcgZnVuY3Rpb25zIGFyZSBNUy1pbnRlcm5hbCAtLSBjYW4ndCBhY2Nlc3MgdGhlbSBmcm9tIHVzZXIKKyAgY29kZS4KKysgVGhlcmUncyBub3RoaW5nIFRpbSBjb3VsZCBmaW5kIGluIHRoZSBNUyBDIG9yIHBsYXRmb3JtIFNESyBsaWJyYXJpZXMgdGhhdAorICBjYW4gd29ybSBhcm91bmQgdGhpcy4KKysgTVMgZmdldHMgbG9ja3MvdW5sb2NrcyBvbmx5IG9uY2UgcGVyIGxpbmU7IGl0J3MgdGhlIG9ubHkgaG9vayB3ZSBoYXZlLgorCitTbyB3ZSB1c2UgZmdldHMgZm9yIHNwZWVkKCEpLCBkZXNwaXRlIHRoYXQgaXQncyBwYWluZnVsLgorCitNUyByZWFsbG9jIGlzIGFsc28gc2xvdy4KKworUmVwb3J0cyBmcm9tIG90aGVyIHBsYXRmb3JtcyBvbiB0aGlzIG1ldGhvZCB2cyBnZXRjX3VubG9ja2VkICh3aGljaCBNUyBkb2Vzbid0CitoYXZlKToKKyAgICBMaW51eCAgICAgICAgICAgICAgIGEgd2FzaAorICAgIFNvbGFyaXMgICAgICAgICAgICAgYSB3YXNoCisgICAgVHJ1NjQgVW5peCAgICAgICAgICBnZXRsaW5lX3ZpYV9mZ2V0cyBzaWduaWZpY2FudGx5IGZhc3RlcgorCitDQVVUSU9OOiAgVGhlIEMgc3RkIGlzbid0IGNsZWFyIGFib3V0IHRoaXM6ICBpbiB0aG9zZSBjYXNlcyB3aGVyZSBmZ2V0cword3JpdGVzIHNvbWV0aGluZyBpbnRvIHRoZSBidWZmZXIsIGNhbiBpdCB3cml0ZSBpbnRvIGFueSBwb3NpdGlvbiBiZXlvbmQgdGhlCityZXF1aXJlZCB0cmFpbGluZyBudWxsIGJ5dGU/ICBNU1ZDIDYgZmdldHMgZG9lcyBub3QsIGFuZCBubyBwbGF0Zm9ybSBpcyAoeWV0KQora25vd24gb24gd2hpY2ggaXQgZG9lczsgYW5kIGl0IHdvdWxkIGJlIGEgc3RyYW5nZSB3YXkgdG8gY29kZSBmZ2V0cy4gU3RpbGwsCitnZXRsaW5lX3ZpYV9mZ2V0cyBtYXkgbm90IHdvcmsgY29ycmVjdGx5IGlmIGl0IGRvZXMuICBUaGUgc3RkIHRlc3QKK3Rlc3RfYnVmaW8ucHkgc2hvdWxkIGZhaWwgaWYgcGxhdGZvcm0gZmdldHMoKSByb3V0aW5lbHkgd3JpdGVzIGJleW9uZCB0aGUKK3RyYWlsaW5nIG51bGwgYnl0ZS4gICNkZWZpbmUgRE9OVF9VU0VfRkdFVFNfSU5fR0VUTElORSB0byBkaXNhYmxlIHRoaXMgY29kZS4KKyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLworCisvKiBVc2UgdGhpcyByb3V0aW5lIGlmIHRvbGQgdG8sIG9yIGJ5IGRlZmF1bHQgb24gbm9uLWdldF91bmxvY2tlZCgpCisgKiBwbGF0Zm9ybXMgdW5sZXNzIHRvbGQgbm90IHRvLiAgWWlrZXMhICBMZXQncyBzcGVsbCB0aGF0IG91dDoKKyAqIE9uIGEgcGxhdGZvcm0gd2l0aCBnZXRjX3VubG9ja2VkKCk6CisgKiAgICAgQnkgZGVmYXVsdCwgdXNlIGdldGNfdW5sb2NrZWQoKS4KKyAqICAgICBJZiB5b3Ugd2FudCB0byB1c2UgZmdldHMoKSBpbnN0ZWFkLCAjZGVmaW5lIFVTRV9GR0VUU19JTl9HRVRMSU5FLgorICogT24gYSBwbGF0Zm9ybSB3aXRob3V0IGdldGNfdW5sb2NrZWQoKToKKyAqICAgICBCeSBkZWZhdWx0LCB1c2UgZmdldHMoKS4KKyAqICAgICBJZiB5b3UgZG9uJ3Qgd2FudCB0byB1c2UgZmdldHMoKSwgI2RlZmluZSBET05UX1VTRV9GR0VUU19JTl9HRVRMSU5FLgorICovCisjaWYgIWRlZmluZWQoVVNFX0ZHRVRTX0lOX0dFVExJTkUpICYmICFkZWZpbmVkKEhBVkVfR0VUQ19VTkxPQ0tFRCkKKyNkZWZpbmUgVVNFX0ZHRVRTX0lOX0dFVExJTkUKKyNlbmRpZgorCisjaWYgZGVmaW5lZChET05UX1VTRV9GR0VUU19JTl9HRVRMSU5FKSAmJiBkZWZpbmVkKFVTRV9GR0VUU19JTl9HRVRMSU5FKQorI3VuZGVmIFVTRV9GR0VUU19JTl9HRVRMSU5FCisjZW5kaWYKKworI2lmZGVmIFVTRV9GR0VUU19JTl9HRVRMSU5FCitzdGF0aWMgUHlPYmplY3QqCitnZXRsaW5lX3ZpYV9mZ2V0cyhQeUZpbGVPYmplY3QgKmYsIEZJTEUgKmZwKQoreworLyogSU5JVEJVRlNJWkUgaXMgdGhlIG1heGltdW0gbGluZSBsZW5ndGggdGhhdCBsZXRzIHVzIGdldCBhd2F5IHdpdGggdGhlIGZhc3QKKyAqIG5vLXJlYWxsb2MsIG9uZS1mZ2V0cygpLWNhbGwgcGF0aC4gIEJvb3N0aW5nIGl0IGlzbid0IGZyZWUsIGJlY2F1c2Ugd2UgaGF2ZQorICogdG8gZmlsbCB0aGlzIG11Y2ggb2YgdGhlIGJ1ZmZlciB3aXRoIGEga25vd24gdmFsdWUgaW4gb3JkZXIgdG8gZmlndXJlIG91dAorICogaG93IG11Y2ggb2YgdGhlIGJ1ZmZlciBmZ2V0cygpIG92ZXJ3cml0ZXMuICBTbyBpZiBJTklUQlVGU0laRSBpcyBsYXJnZXIKKyAqIHRoYW4gIm1vc3QiIGxpbmVzLCB3ZSB3YXN0ZSB0aW1lIGZpbGxpbmcgdW51c2VkIGJ1ZmZlciBzbG90cy4gIDEwMCBpcworICogc3VyZWx5IGFkZXF1YXRlIGZvciBtb3N0IHBlb3BsZXMnIGVtYWlsIGFyY2hpdmVzLCBjaGV3aW5nIG92ZXIgc291cmNlIGNvZGUsCisgKiBldGMgLS0gInJlZ3VsYXIgb2xkIHRleHQgZmlsZXMiLgorICogTUFYQlVGU0laRSBpcyB0aGUgbWF4aW11bSBsaW5lIGxlbmd0aCB0aGF0IGxldHMgdXMgZ2V0IGF3YXkgd2l0aCB0aGUgbGVzcworICogZmFzdCAoYnV0IHN0aWxsIHppcHB5KSBuby1yZWFsbG9jLCB0d28tZmdldHMoKS1jYWxsIHBhdGguICBTZWUgYWJvdmUgZm9yCisgKiBjYXV0aW9ucyBhYm91dCBib29zdGluZyB0aGF0LiAgMzAwIHdhcyBjaG9zZW4gYmVjYXVzZSB0aGUgd29yc3QgcmVhbC1saWZlCisgKiB0ZXh0LWNydW5jaGluZyBqb2IgcmVwb3J0ZWQgb24gUHl0aG9uLURldiB3YXMgYSBtYWlsLWxvZyBjcmF3bGVyIHdoZXJlIG92ZXIKKyAqIGhhbGYgdGhlIGxpbmVzIHdlcmUgMjU0IGNoYXJzLgorICovCisjZGVmaW5lIElOSVRCVUZTSVpFIDEwMAorI2RlZmluZSBNQVhCVUZTSVpFIDMwMAorICAgIGNoYXIqIHA7ICAgICAgICAgICAgLyogdGVtcCAqLworICAgIGNoYXIgYnVmW01BWEJVRlNJWkVdOworICAgIFB5T2JqZWN0KiB2OyAgICAgICAgLyogdGhlIHN0cmluZyBvYmplY3QgcmVzdWx0ICovCisgICAgY2hhciogcHZmcmVlOyAgICAgICAvKiBhZGRyZXNzIG9mIG5leHQgZnJlZSBzbG90ICovCisgICAgY2hhciogcHZlbmQ7ICAgIC8qIGFkZHJlc3Mgb25lIGJleW9uZCBsYXN0IGZyZWUgc2xvdCAqLworICAgIHNpemVfdCBuZnJlZTsgICAgICAgLyogIyBvZiBmcmVlIGJ1ZmZlciBzbG90czsgcHZlbmQtcHZmcmVlICovCisgICAgc2l6ZV90IHRvdGFsX3Zfc2l6ZTsgIC8qIHRvdGFsICMgb2Ygc2xvdHMgaW4gYnVmZmVyICovCisgICAgc2l6ZV90IGluY3JlbWVudDsgICAgICAgICAgIC8qIGFtb3VudCB0byBpbmNyZW1lbnQgdGhlIGJ1ZmZlciAqLworICAgIHNpemVfdCBwcmV2X3Zfc2l6ZTsKKworICAgIC8qIE9wdGltaXplIGZvciBub3JtYWwgY2FzZTogIGF2b2lkIF9QeVN0cmluZ19SZXNpemUgaWYgYXQgYWxsCisgICAgICogcG9zc2libGUgdmlhIGZpcnN0IHJlYWRpbmcgaW50byBzdGFjayBidWZmZXIgImJ1ZiIuCisgICAgICovCisgICAgdG90YWxfdl9zaXplID0gSU5JVEJVRlNJWkU7ICAgICAgICAgLyogc3RhcnQgc21hbGwgYW5kIHByYXkgKi8KKyAgICBwdmZyZWUgPSBidWY7CisgICAgZm9yICg7OykgeworICAgICAgICBGSUxFX0JFR0lOX0FMTE9XX1RIUkVBRFMoZikKKyAgICAgICAgcHZlbmQgPSBidWYgKyB0b3RhbF92X3NpemU7CisgICAgICAgIG5mcmVlID0gcHZlbmQgLSBwdmZyZWU7CisgICAgICAgIG1lbXNldChwdmZyZWUsICdcbicsIG5mcmVlKTsKKyAgICAgICAgYXNzZXJ0KG5mcmVlIDwgSU5UX01BWCk7IC8qIFNob3VsZCBiZSBhdG1vc3QgTUFYQlVGU0laRSAqLworICAgICAgICBwID0gZmdldHMocHZmcmVlLCAoaW50KW5mcmVlLCBmcCk7CisgICAgICAgIEZJTEVfRU5EX0FMTE9XX1RIUkVBRFMoZikKKworICAgICAgICBpZiAocCA9PSBOVUxMKSB7CisgICAgICAgICAgICBjbGVhcmVycihmcCk7CisgICAgICAgICAgICBpZiAoUHlFcnJfQ2hlY2tTaWduYWxzKCkpCisgICAgICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgICAgICAgICB2ID0gUHlTdHJpbmdfRnJvbVN0cmluZ0FuZFNpemUoYnVmLCBwdmZyZWUgLSBidWYpOworICAgICAgICAgICAgcmV0dXJuIHY7CisgICAgICAgIH0KKyAgICAgICAgLyogZmdldHMgcmVhZCAqc29tZXRoaW5nKiAqLworICAgICAgICBwID0gbWVtY2hyKHB2ZnJlZSwgJ1xuJywgbmZyZWUpOworICAgICAgICBpZiAocCAhPSBOVUxMKSB7CisgICAgICAgICAgICAvKiBEaWQgdGhlIFxuIGNvbWUgZnJvbSBmZ2V0cyBvciBmcm9tIHVzPworICAgICAgICAgICAgICogU2luY2UgZmdldHMgc3RvcHMgYXQgdGhlIGZpcnN0IFxuLCBhbmQgdGhlbiB3cml0ZXMKKyAgICAgICAgICAgICAqIFwwLCBpZiBpdCdzIGZyb20gZmdldHMgYSBcMCBtdXN0IGJlIG5leHQuICBCdXQgaWYKKyAgICAgICAgICAgICAqIHRoYXQncyBzbywgaXQgY291bGQgbm90IGhhdmUgY29tZSBmcm9tIHVzLCBzaW5jZQorICAgICAgICAgICAgICogdGhlIFxuJ3Mgd2UgZmlsbGVkIHRoZSBidWZmZXIgd2l0aCBoYXZlIG9ubHkgbW9yZQorICAgICAgICAgICAgICogXG4ncyB0byB0aGUgcmlnaHQuCisgICAgICAgICAgICAgKi8KKyAgICAgICAgICAgIGlmIChwKzEgPCBwdmVuZCAmJiAqKHArMSkgPT0gJ1wwJykgeworICAgICAgICAgICAgICAgIC8qIEl0J3MgZnJvbSBmZ2V0czogIHdlIHdpbiEgIEluIHBhcnRpY3VsYXIsCisgICAgICAgICAgICAgICAgICogd2UgaGF2ZW4ndCBkb25lIGFueSBtYWxsb2NzIHlldCwgYW5kIGNhbgorICAgICAgICAgICAgICAgICAqIGJ1aWxkIHRoZSBmaW5hbCByZXN1bHQgb24gdGhlIGZpcnN0IHRyeS4KKyAgICAgICAgICAgICAgICAgKi8KKyAgICAgICAgICAgICAgICArK3A7ICAgICAgICAgICAgICAgICAgICAvKiBpbmNsdWRlIFxuIGZyb20gZmdldHMgKi8KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGVsc2UgeworICAgICAgICAgICAgICAgIC8qIE11c3QgYmUgZnJvbSB1czogIGZnZXRzIGRpZG4ndCBmaWxsIHRoZQorICAgICAgICAgICAgICAgICAqIGJ1ZmZlciBhbmQgZGlkbid0IGZpbmQgYSBuZXdsaW5lLCBzbyBpdAorICAgICAgICAgICAgICAgICAqIG11c3QgYmUgdGhlIGxhc3QgYW5kIG5ld2xpbmUtZnJlZSBsaW5lIG9mCisgICAgICAgICAgICAgICAgICogdGhlIGZpbGUuCisgICAgICAgICAgICAgICAgICovCisgICAgICAgICAgICAgICAgYXNzZXJ0KHAgPiBwdmZyZWUgJiYgKihwLTEpID09ICdcMCcpOworICAgICAgICAgICAgICAgIC0tcDsgICAgICAgICAgICAgICAgICAgIC8qIGRvbid0IGluY2x1ZGUgXDAgZnJvbSBmZ2V0cyAqLworICAgICAgICAgICAgfQorICAgICAgICAgICAgdiA9IFB5U3RyaW5nX0Zyb21TdHJpbmdBbmRTaXplKGJ1ZiwgcCAtIGJ1Zik7CisgICAgICAgICAgICByZXR1cm4gdjsKKyAgICAgICAgfQorICAgICAgICAvKiB5dWNrOiAgZmdldHMgb3Zlcndyb3RlIGFsbCB0aGUgbmV3bGluZXMsIGkuZS4gdGhlIGVudGlyZQorICAgICAgICAgKiBidWZmZXIuICBTbyB0aGlzIGxpbmUgaXNuJ3Qgb3ZlciB5ZXQsIG9yIG1heWJlIGl0IGlzIGJ1dAorICAgICAgICAgKiB3ZSdyZSBleGFjdGx5IGF0IEVPRi4gIElmIHdlIGhhdmVuJ3QgYWxyZWFkeSwgdHJ5IHVzaW5nIHRoZQorICAgICAgICAgKiByZXN0IG9mIHRoZSBzdGFjayBidWZmZXIuCisgICAgICAgICAqLworICAgICAgICBhc3NlcnQoKihwdmVuZC0xKSA9PSAnXDAnKTsKKyAgICAgICAgaWYgKHB2ZnJlZSA9PSBidWYpIHsKKyAgICAgICAgICAgIHB2ZnJlZSA9IHB2ZW5kIC0gMTsgICAgICAgICAgICAgICAgIC8qIG92ZXJ3cml0ZSB0cmFpbGluZyBudWxsICovCisgICAgICAgICAgICB0b3RhbF92X3NpemUgPSBNQVhCVUZTSVpFOworICAgICAgICB9CisgICAgICAgIGVsc2UKKyAgICAgICAgICAgIGJyZWFrOworICAgIH0KKworICAgIC8qIFRoZSBzdGFjayBidWZmZXIgaXNuJ3QgYmlnIGVub3VnaDsgbWFsbG9jIGEgc3RyaW5nIG9iamVjdCBhbmQgcmVhZAorICAgICAqIGludG8gaXRzIGJ1ZmZlci4KKyAgICAgKi8KKyAgICB0b3RhbF92X3NpemUgPSBNQVhCVUZTSVpFIDw8IDE7CisgICAgdiA9IFB5U3RyaW5nX0Zyb21TdHJpbmdBbmRTaXplKChjaGFyKilOVUxMLCAoaW50KXRvdGFsX3Zfc2l6ZSk7CisgICAgaWYgKHYgPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIHY7CisgICAgLyogY29weSBvdmVyIGV2ZXJ5dGhpbmcgZXhjZXB0IHRoZSBsYXN0IG51bGwgYnl0ZSAqLworICAgIG1lbWNweShCVUYodiksIGJ1ZiwgTUFYQlVGU0laRS0xKTsKKyAgICBwdmZyZWUgPSBCVUYodikgKyBNQVhCVUZTSVpFIC0gMTsKKworICAgIC8qIEtlZXAgcmVhZGluZyBzdHVmZiBpbnRvIHY7IGlmIGl0IGV2ZXIgZW5kcyBzdWNjZXNzZnVsbHksIGJyZWFrCisgICAgICogYWZ0ZXIgc2V0dGluZyBwIG9uZSBiZXlvbmQgdGhlIGVuZCBvZiB0aGUgbGluZS4gIFRoZSBjb2RlIGhlcmUgaXMKKyAgICAgKiB2ZXJ5IG11Y2ggbGlrZSB0aGUgY29kZSBhYm92ZSwgZXhjZXB0IHJlYWRzIGludG8gdidzIGJ1ZmZlcjsgc2VlCisgICAgICogdGhlIGNvZGUgYWJvdmUgZm9yIGRldGFpbGVkIGNvbW1lbnRzIGFib3V0IHRoZSBsb2dpYy4KKyAgICAgKi8KKyAgICBmb3IgKDs7KSB7CisgICAgICAgIEZJTEVfQkVHSU5fQUxMT1dfVEhSRUFEUyhmKQorICAgICAgICBwdmVuZCA9IEJVRih2KSArIHRvdGFsX3Zfc2l6ZTsKKyAgICAgICAgbmZyZWUgPSBwdmVuZCAtIHB2ZnJlZTsKKyAgICAgICAgbWVtc2V0KHB2ZnJlZSwgJ1xuJywgbmZyZWUpOworICAgICAgICBhc3NlcnQobmZyZWUgPCBJTlRfTUFYKTsKKyAgICAgICAgcCA9IGZnZXRzKHB2ZnJlZSwgKGludCluZnJlZSwgZnApOworICAgICAgICBGSUxFX0VORF9BTExPV19USFJFQURTKGYpCisKKyAgICAgICAgaWYgKHAgPT0gTlVMTCkgeworICAgICAgICAgICAgY2xlYXJlcnIoZnApOworICAgICAgICAgICAgaWYgKFB5RXJyX0NoZWNrU2lnbmFscygpKSB7CisgICAgICAgICAgICAgICAgUHlfREVDUkVGKHYpOworICAgICAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgICAgICAgICAgfQorICAgICAgICAgICAgcCA9IHB2ZnJlZTsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisgICAgICAgIHAgPSBtZW1jaHIocHZmcmVlLCAnXG4nLCBuZnJlZSk7CisgICAgICAgIGlmIChwICE9IE5VTEwpIHsKKyAgICAgICAgICAgIGlmIChwKzEgPCBwdmVuZCAmJiAqKHArMSkgPT0gJ1wwJykgeworICAgICAgICAgICAgICAgIC8qIFxuIGNhbWUgZnJvbSBmZ2V0cyAqLworICAgICAgICAgICAgICAgICsrcDsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIC8qIFxuIGNhbWUgZnJvbSB1czsgbGFzdCBsaW5lIG9mIGZpbGUsIG5vIG5ld2xpbmUgKi8KKyAgICAgICAgICAgIGFzc2VydChwID4gcHZmcmVlICYmICoocC0xKSA9PSAnXDAnKTsKKyAgICAgICAgICAgIC0tcDsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisgICAgICAgIC8qIGV4cGFuZCBidWZmZXIgYW5kIHRyeSBhZ2FpbiAqLworICAgICAgICBhc3NlcnQoKihwdmVuZC0xKSA9PSAnXDAnKTsKKyAgICAgICAgaW5jcmVtZW50ID0gdG90YWxfdl9zaXplID4+IDI7ICAgICAgICAgIC8qIG1pbGQgZXhwb25lbnRpYWwgZ3Jvd3RoICovCisgICAgICAgIHByZXZfdl9zaXplID0gdG90YWxfdl9zaXplOworICAgICAgICB0b3RhbF92X3NpemUgKz0gaW5jcmVtZW50OworICAgICAgICAvKiBjaGVjayBmb3Igb3ZlcmZsb3cgKi8KKyAgICAgICAgaWYgKHRvdGFsX3Zfc2l6ZSA8PSBwcmV2X3Zfc2l6ZSB8fAorICAgICAgICAgICAgdG90YWxfdl9zaXplID4gUFlfU1NJWkVfVF9NQVgpIHsKKyAgICAgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19PdmVyZmxvd0Vycm9yLAorICAgICAgICAgICAgICAgICJsaW5lIGlzIGxvbmdlciB0aGFuIGEgUHl0aG9uIHN0cmluZyBjYW4gaG9sZCIpOworICAgICAgICAgICAgUHlfREVDUkVGKHYpOworICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgICAgIH0KKyAgICAgICAgaWYgKF9QeVN0cmluZ19SZXNpemUoJnYsIChpbnQpdG90YWxfdl9zaXplKSA8IDApCisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgLyogb3ZlcndyaXRlIHRoZSB0cmFpbGluZyBudWxsIGJ5dGUgKi8KKyAgICAgICAgcHZmcmVlID0gQlVGKHYpICsgKHByZXZfdl9zaXplIC0gMSk7CisgICAgfQorICAgIGlmIChCVUYodikgKyB0b3RhbF92X3NpemUgIT0gcCAmJiBfUHlTdHJpbmdfUmVzaXplKCZ2LCBwIC0gQlVGKHYpKSkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgcmV0dXJuIHY7CisjdW5kZWYgSU5JVEJVRlNJWkUKKyN1bmRlZiBNQVhCVUZTSVpFCit9CisjZW5kaWYgIC8qIGlmZGVmIFVTRV9GR0VUU19JTl9HRVRMSU5FICovCisKKy8qIEludGVybmFsIHJvdXRpbmUgdG8gZ2V0IGEgbGluZS4KKyAgIFNpemUgYXJndW1lbnQgaW50ZXJwcmV0YXRpb246CisgICA+IDA6IG1heCBsZW5ndGg7CisgICA8PSAwOiByZWFkIGFyYml0cmFyeSBsaW5lCisqLworCitzdGF0aWMgUHlPYmplY3QgKgorZ2V0X2xpbmUoUHlGaWxlT2JqZWN0ICpmLCBpbnQgbikKK3sKKyAgICBGSUxFICpmcCA9IGYtPmZfZnA7CisgICAgaW50IGM7CisgICAgY2hhciAqYnVmLCAqZW5kOworICAgIHNpemVfdCB0b3RhbF92X3NpemU7ICAgICAgICAvKiB0b3RhbCAjIG9mIHNsb3RzIGluIGJ1ZmZlciAqLworICAgIHNpemVfdCB1c2VkX3Zfc2l6ZTsgICAgICAgICAvKiAjIHVzZWQgc2xvdHMgaW4gYnVmZmVyICovCisgICAgc2l6ZV90IGluY3JlbWVudDsgICAgICAgLyogYW1vdW50IHRvIGluY3JlbWVudCB0aGUgYnVmZmVyICovCisgICAgUHlPYmplY3QgKnY7CisgICAgaW50IG5ld2xpbmV0eXBlcyA9IGYtPmZfbmV3bGluZXR5cGVzOworICAgIGludCBza2lwbmV4dGxmID0gZi0+Zl9za2lwbmV4dGxmOworICAgIGludCB1bml2X25ld2xpbmUgPSBmLT5mX3VuaXZfbmV3bGluZTsKKworI2lmIGRlZmluZWQoVVNFX0ZHRVRTX0lOX0dFVExJTkUpCisgICAgaWYgKG4gPD0gMCAmJiAhdW5pdl9uZXdsaW5lICkKKyAgICAgICAgcmV0dXJuIGdldGxpbmVfdmlhX2ZnZXRzKGYsIGZwKTsKKyNlbmRpZgorICAgIHRvdGFsX3Zfc2l6ZSA9IG4gPiAwID8gbiA6IDEwMDsKKyAgICB2ID0gUHlTdHJpbmdfRnJvbVN0cmluZ0FuZFNpemUoKGNoYXIgKilOVUxMLCB0b3RhbF92X3NpemUpOworICAgIGlmICh2ID09IE5VTEwpCisgICAgICAgIHJldHVybiBOVUxMOworICAgIGJ1ZiA9IEJVRih2KTsKKyAgICBlbmQgPSBidWYgKyB0b3RhbF92X3NpemU7CisKKyAgICBmb3IgKDs7KSB7CisgICAgICAgIEZJTEVfQkVHSU5fQUxMT1dfVEhSRUFEUyhmKQorICAgICAgICBGTE9DS0ZJTEUoZnApOworICAgICAgICBpZiAodW5pdl9uZXdsaW5lKSB7CisgICAgICAgICAgICBjID0gJ3gnOyAvKiBTaHV0IHVwIGdjYyB3YXJuaW5nICovCisgICAgICAgICAgICB3aGlsZSAoIGJ1ZiAhPSBlbmQgJiYgKGMgPSBHRVRDKGZwKSkgIT0gRU9GICkgeworICAgICAgICAgICAgICAgIGlmIChza2lwbmV4dGxmICkgeworICAgICAgICAgICAgICAgICAgICBza2lwbmV4dGxmID0gMDsKKyAgICAgICAgICAgICAgICAgICAgaWYgKGMgPT0gJ1xuJykgeworICAgICAgICAgICAgICAgICAgICAgICAgLyogU2VlaW5nIGEgXG4gaGVyZSB3aXRoCisgICAgICAgICAgICAgICAgICAgICAgICAgKiBza2lwbmV4dGxmIHRydWUgbWVhbnMgd2UKKyAgICAgICAgICAgICAgICAgICAgICAgICAqIHNhdyBhIFxyIGJlZm9yZS4KKyAgICAgICAgICAgICAgICAgICAgICAgICAqLworICAgICAgICAgICAgICAgICAgICAgICAgbmV3bGluZXR5cGVzIHw9IE5FV0xJTkVfQ1JMRjsKKyAgICAgICAgICAgICAgICAgICAgICAgIGMgPSBHRVRDKGZwKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjID09IEVPRikgYnJlYWs7CisgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgICAgICBuZXdsaW5ldHlwZXMgfD0gTkVXTElORV9DUjsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBpZiAoYyA9PSAnXHInKSB7CisgICAgICAgICAgICAgICAgICAgIHNraXBuZXh0bGYgPSAxOworICAgICAgICAgICAgICAgICAgICBjID0gJ1xuJzsKKyAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKCBjID09ICdcbicpCisgICAgICAgICAgICAgICAgICAgIG5ld2xpbmV0eXBlcyB8PSBORVdMSU5FX0xGOworICAgICAgICAgICAgICAgICpidWYrKyA9IGM7CisgICAgICAgICAgICAgICAgaWYgKGMgPT0gJ1xuJykgYnJlYWs7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoYyA9PSBFT0YpIHsKKyAgICAgICAgICAgICAgICBpZiAoZmVycm9yKGZwKSAmJiBlcnJubyA9PSBFSU5UUikgeworICAgICAgICAgICAgICAgICAgICBGVU5MT0NLRklMRShmcCk7CisgICAgICAgICAgICAgICAgICAgIEZJTEVfQUJPUlRfQUxMT1dfVEhSRUFEUyhmKQorICAgICAgICAgICAgICAgICAgICBmLT5mX25ld2xpbmV0eXBlcyA9IG5ld2xpbmV0eXBlczsKKyAgICAgICAgICAgICAgICAgICAgZi0+Zl9za2lwbmV4dGxmID0gc2tpcG5leHRsZjsKKworICAgICAgICAgICAgICAgICAgICBpZiAoUHlFcnJfQ2hlY2tTaWduYWxzKCkpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIFB5X0RFQ1JFRih2KTsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIC8qIFdlIGV4ZWN1dGVkIFB5dGhvbiBzaWduYWwgaGFuZGxlcnMgYW5kIGdvdCBubyBleGNlcHRpb24uCisgICAgICAgICAgICAgICAgICAgICAqIE5vdyBiYWNrIHRvIHJlYWRpbmcgdGhlIGxpbmUgd2hlcmUgd2UgbGVmdCBvZmYuICovCisgICAgICAgICAgICAgICAgICAgIGNsZWFyZXJyKGZwKTsKKyAgICAgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGlmIChza2lwbmV4dGxmKQorICAgICAgICAgICAgICAgICAgICBuZXdsaW5ldHlwZXMgfD0gTkVXTElORV9DUjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIC8qIElmIG5vdCB1bml2ZXJzYWwgbmV3bGluZXMgdXNlIHRoZSBub3JtYWwgbG9vcCAqLworICAgICAgICB3aGlsZSAoKGMgPSBHRVRDKGZwKSkgIT0gRU9GICYmCisgICAgICAgICAgICAgICAoKmJ1ZisrID0gYykgIT0gJ1xuJyAmJgorICAgICAgICAgICAgYnVmICE9IGVuZCkKKyAgICAgICAgICAgIDsKKyAgICAgICAgRlVOTE9DS0ZJTEUoZnApOworICAgICAgICBGSUxFX0VORF9BTExPV19USFJFQURTKGYpCisgICAgICAgIGYtPmZfbmV3bGluZXR5cGVzID0gbmV3bGluZXR5cGVzOworICAgICAgICBmLT5mX3NraXBuZXh0bGYgPSBza2lwbmV4dGxmOworICAgICAgICBpZiAoYyA9PSAnXG4nKQorICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIGlmIChjID09IEVPRikgeworICAgICAgICAgICAgaWYgKGZlcnJvcihmcCkpIHsKKyAgICAgICAgICAgICAgICBpZiAoZXJybm8gPT0gRUlOVFIpIHsKKyAgICAgICAgICAgICAgICAgICAgaWYgKFB5RXJyX0NoZWNrU2lnbmFscygpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBQeV9ERUNSRUYodik7CisgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAvKiBXZSBleGVjdXRlZCBQeXRob24gc2lnbmFsIGhhbmRsZXJzIGFuZCBnb3Qgbm8gZXhjZXB0aW9uLgorICAgICAgICAgICAgICAgICAgICAgKiBOb3cgYmFjayB0byByZWFkaW5nIHRoZSBsaW5lIHdoZXJlIHdlIGxlZnQgb2ZmLiAqLworICAgICAgICAgICAgICAgICAgICBjbGVhcmVycihmcCk7CisgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBQeUVycl9TZXRGcm9tRXJybm8oUHlFeGNfSU9FcnJvcik7CisgICAgICAgICAgICAgICAgY2xlYXJlcnIoZnApOworICAgICAgICAgICAgICAgIFB5X0RFQ1JFRih2KTsKKyAgICAgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGNsZWFyZXJyKGZwKTsKKyAgICAgICAgICAgIGlmIChQeUVycl9DaGVja1NpZ25hbHMoKSkgeworICAgICAgICAgICAgICAgIFB5X0RFQ1JFRih2KTsKKyAgICAgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisgICAgICAgIC8qIE11c3QgYmUgYmVjYXVzZSBidWYgPT0gZW5kICovCisgICAgICAgIGlmIChuID4gMCkKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICB1c2VkX3Zfc2l6ZSA9IHRvdGFsX3Zfc2l6ZTsKKyAgICAgICAgaW5jcmVtZW50ID0gdG90YWxfdl9zaXplID4+IDI7IC8qIG1pbGQgZXhwb25lbnRpYWwgZ3Jvd3RoICovCisgICAgICAgIHRvdGFsX3Zfc2l6ZSArPSBpbmNyZW1lbnQ7CisgICAgICAgIGlmICh0b3RhbF92X3NpemUgPiBQWV9TU0laRV9UX01BWCkgeworICAgICAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX092ZXJmbG93RXJyb3IsCisgICAgICAgICAgICAgICAgImxpbmUgaXMgbG9uZ2VyIHRoYW4gYSBQeXRob24gc3RyaW5nIGNhbiBob2xkIik7CisgICAgICAgICAgICBQeV9ERUNSRUYodik7CisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgfQorICAgICAgICBpZiAoX1B5U3RyaW5nX1Jlc2l6ZSgmdiwgdG90YWxfdl9zaXplKSA8IDApCisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgYnVmID0gQlVGKHYpICsgdXNlZF92X3NpemU7CisgICAgICAgIGVuZCA9IEJVRih2KSArIHRvdGFsX3Zfc2l6ZTsKKyAgICB9CisKKyAgICB1c2VkX3Zfc2l6ZSA9IGJ1ZiAtIEJVRih2KTsKKyAgICBpZiAodXNlZF92X3NpemUgIT0gdG90YWxfdl9zaXplICYmIF9QeVN0cmluZ19SZXNpemUoJnYsIHVzZWRfdl9zaXplKSkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgcmV0dXJuIHY7Cit9CisKKy8qIEV4dGVybmFsIEMgaW50ZXJmYWNlICovCisKK1B5T2JqZWN0ICoKK1B5RmlsZV9HZXRMaW5lKFB5T2JqZWN0ICpmLCBpbnQgbikKK3sKKyAgICBQeU9iamVjdCAqcmVzdWx0OworCisgICAgaWYgKGYgPT0gTlVMTCkgeworICAgICAgICBQeUVycl9CYWRJbnRlcm5hbENhbGwoKTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorCisgICAgaWYgKFB5RmlsZV9DaGVjayhmKSkgeworICAgICAgICBQeUZpbGVPYmplY3QgKmZvID0gKFB5RmlsZU9iamVjdCAqKWY7CisgICAgICAgIGlmIChmby0+Zl9mcCA9PSBOVUxMKQorICAgICAgICAgICAgcmV0dXJuIGVycl9jbG9zZWQoKTsKKyAgICAgICAgaWYgKCFmby0+cmVhZGFibGUpCisgICAgICAgICAgICByZXR1cm4gZXJyX21vZGUoInJlYWRpbmciKTsKKyAgICAgICAgLyogcmVmdXNlIHRvIG1peCB3aXRoIGYubmV4dCgpICovCisgICAgICAgIGlmIChmby0+Zl9idWYgIT0gTlVMTCAmJgorICAgICAgICAgICAgKGZvLT5mX2J1ZmVuZCAtIGZvLT5mX2J1ZnB0cikgPiAwICYmCisgICAgICAgICAgICBmby0+Zl9idWZbMF0gIT0gJ1wwJykKKyAgICAgICAgICAgIHJldHVybiBlcnJfaXRlcmJ1ZmZlcmVkKCk7CisgICAgICAgIHJlc3VsdCA9IGdldF9saW5lKGZvLCBuKTsKKyAgICB9CisgICAgZWxzZSB7CisgICAgICAgIFB5T2JqZWN0ICpyZWFkZXI7CisgICAgICAgIFB5T2JqZWN0ICphcmdzOworCisgICAgICAgIHJlYWRlciA9IFB5T2JqZWN0X0dldEF0dHJTdHJpbmcoZiwgInJlYWRsaW5lIik7CisgICAgICAgIGlmIChyZWFkZXIgPT0gTlVMTCkKKyAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgICAgICBpZiAobiA8PSAwKQorICAgICAgICAgICAgYXJncyA9IFB5VHVwbGVfTmV3KDApOworICAgICAgICBlbHNlCisgICAgICAgICAgICBhcmdzID0gUHlfQnVpbGRWYWx1ZSgiKGkpIiwgbik7CisgICAgICAgIGlmIChhcmdzID09IE5VTEwpIHsKKyAgICAgICAgICAgIFB5X0RFQ1JFRihyZWFkZXIpOworICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgICAgIH0KKyAgICAgICAgcmVzdWx0ID0gUHlFdmFsX0NhbGxPYmplY3QocmVhZGVyLCBhcmdzKTsKKyAgICAgICAgUHlfREVDUkVGKHJlYWRlcik7CisgICAgICAgIFB5X0RFQ1JFRihhcmdzKTsKKyAgICAgICAgaWYgKHJlc3VsdCAhPSBOVUxMICYmICFQeVN0cmluZ19DaGVjayhyZXN1bHQpICYmCisgICAgICAgICAgICAhUHlVbmljb2RlX0NoZWNrKHJlc3VsdCkpIHsKKyAgICAgICAgICAgIFB5X0RFQ1JFRihyZXN1bHQpOworICAgICAgICAgICAgcmVzdWx0ID0gTlVMTDsKKyAgICAgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19UeXBlRXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAgICJvYmplY3QucmVhZGxpbmUoKSByZXR1cm5lZCBub24tc3RyaW5nIik7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBpZiAobiA8IDAgJiYgcmVzdWx0ICE9IE5VTEwgJiYgUHlTdHJpbmdfQ2hlY2socmVzdWx0KSkgeworICAgICAgICBjaGFyICpzID0gUHlTdHJpbmdfQVNfU1RSSU5HKHJlc3VsdCk7CisgICAgICAgIFB5X3NzaXplX3QgbGVuID0gUHlTdHJpbmdfR0VUX1NJWkUocmVzdWx0KTsKKyAgICAgICAgaWYgKGxlbiA9PSAwKSB7CisgICAgICAgICAgICBQeV9ERUNSRUYocmVzdWx0KTsKKyAgICAgICAgICAgIHJlc3VsdCA9IE5VTEw7CisgICAgICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfRU9GRXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkVPRiB3aGVuIHJlYWRpbmcgYSBsaW5lIik7CisgICAgICAgIH0KKyAgICAgICAgZWxzZSBpZiAoc1tsZW4tMV0gPT0gJ1xuJykgeworICAgICAgICAgICAgaWYgKHJlc3VsdC0+b2JfcmVmY250ID09IDEpIHsKKyAgICAgICAgICAgICAgICBpZiAoX1B5U3RyaW5nX1Jlc2l6ZSgmcmVzdWx0LCBsZW4tMSkpCisgICAgICAgICAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgICAgICAgICAgfQorICAgICAgICAgICAgZWxzZSB7CisgICAgICAgICAgICAgICAgUHlPYmplY3QgKnY7CisgICAgICAgICAgICAgICAgdiA9IFB5U3RyaW5nX0Zyb21TdHJpbmdBbmRTaXplKHMsIGxlbi0xKTsKKyAgICAgICAgICAgICAgICBQeV9ERUNSRUYocmVzdWx0KTsKKyAgICAgICAgICAgICAgICByZXN1bHQgPSB2OworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorI2lmZGVmIFB5X1VTSU5HX1VOSUNPREUKKyAgICBpZiAobiA8IDAgJiYgcmVzdWx0ICE9IE5VTEwgJiYgUHlVbmljb2RlX0NoZWNrKHJlc3VsdCkpIHsKKyAgICAgICAgUHlfVU5JQ09ERSAqcyA9IFB5VW5pY29kZV9BU19VTklDT0RFKHJlc3VsdCk7CisgICAgICAgIFB5X3NzaXplX3QgbGVuID0gUHlVbmljb2RlX0dFVF9TSVpFKHJlc3VsdCk7CisgICAgICAgIGlmIChsZW4gPT0gMCkgeworICAgICAgICAgICAgUHlfREVDUkVGKHJlc3VsdCk7CisgICAgICAgICAgICByZXN1bHQgPSBOVUxMOworICAgICAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX0VPRkVycm9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICJFT0Ygd2hlbiByZWFkaW5nIGEgbGluZSIpOworICAgICAgICB9CisgICAgICAgIGVsc2UgaWYgKHNbbGVuLTFdID09ICdcbicpIHsKKyAgICAgICAgICAgIGlmIChyZXN1bHQtPm9iX3JlZmNudCA9PSAxKQorICAgICAgICAgICAgICAgIFB5VW5pY29kZV9SZXNpemUoJnJlc3VsdCwgbGVuLTEpOworICAgICAgICAgICAgZWxzZSB7CisgICAgICAgICAgICAgICAgUHlPYmplY3QgKnY7CisgICAgICAgICAgICAgICAgdiA9IFB5VW5pY29kZV9Gcm9tVW5pY29kZShzLCBsZW4tMSk7CisgICAgICAgICAgICAgICAgUHlfREVDUkVGKHJlc3VsdCk7CisgICAgICAgICAgICAgICAgcmVzdWx0ID0gdjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKyNlbmRpZgorICAgIHJldHVybiByZXN1bHQ7Cit9CisKKy8qIFB5dGhvbiBtZXRob2QgKi8KKworc3RhdGljIFB5T2JqZWN0ICoKK2ZpbGVfcmVhZGxpbmUoUHlGaWxlT2JqZWN0ICpmLCBQeU9iamVjdCAqYXJncykKK3sKKyAgICBpbnQgbiA9IC0xOworCisgICAgaWYgKGYtPmZfZnAgPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIGVycl9jbG9zZWQoKTsKKyAgICBpZiAoIWYtPnJlYWRhYmxlKQorICAgICAgICByZXR1cm4gZXJyX21vZGUoInJlYWRpbmciKTsKKyAgICAvKiByZWZ1c2UgdG8gbWl4IHdpdGggZi5uZXh0KCkgKi8KKyAgICBpZiAoZi0+Zl9idWYgIT0gTlVMTCAmJgorICAgICAgICAoZi0+Zl9idWZlbmQgLSBmLT5mX2J1ZnB0cikgPiAwICYmCisgICAgICAgIGYtPmZfYnVmWzBdICE9ICdcMCcpCisgICAgICAgIHJldHVybiBlcnJfaXRlcmJ1ZmZlcmVkKCk7CisgICAgaWYgKCFQeUFyZ19QYXJzZVR1cGxlKGFyZ3MsICJ8aTpyZWFkbGluZSIsICZuKSkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgaWYgKG4gPT0gMCkKKyAgICAgICAgcmV0dXJuIFB5U3RyaW5nX0Zyb21TdHJpbmcoIiIpOworICAgIGlmIChuIDwgMCkKKyAgICAgICAgbiA9IDA7CisgICAgcmV0dXJuIGdldF9saW5lKGYsIG4pOworfQorCitzdGF0aWMgUHlPYmplY3QgKgorZmlsZV9yZWFkbGluZXMoUHlGaWxlT2JqZWN0ICpmLCBQeU9iamVjdCAqYXJncykKK3sKKyAgICBsb25nIHNpemVoaW50ID0gMDsKKyAgICBQeU9iamVjdCAqbGlzdCA9IE5VTEw7CisgICAgUHlPYmplY3QgKmxpbmU7CisgICAgY2hhciBzbWFsbF9idWZmZXJbU01BTExDSFVOS107CisgICAgY2hhciAqYnVmZmVyID0gc21hbGxfYnVmZmVyOworICAgIHNpemVfdCBidWZmZXJzaXplID0gU01BTExDSFVOSzsKKyAgICBQeU9iamVjdCAqYmlnX2J1ZmZlciA9IE5VTEw7CisgICAgc2l6ZV90IG5maWxsZWQgPSAwOworICAgIHNpemVfdCBucmVhZDsKKyAgICBzaXplX3QgdG90YWxyZWFkID0gMDsKKyAgICBjaGFyICpwLCAqcSwgKmVuZDsKKyAgICBpbnQgZXJyOworICAgIGludCBzaG9ydHJlYWQgPSAwOyAgLyogYm9vbCwgZGlkIHRoZSBwcmV2aW91cyByZWFkIGNvbWUgdXAgc2hvcnQ/ICovCisKKyAgICBpZiAoZi0+Zl9mcCA9PSBOVUxMKQorICAgICAgICByZXR1cm4gZXJyX2Nsb3NlZCgpOworICAgIGlmICghZi0+cmVhZGFibGUpCisgICAgICAgIHJldHVybiBlcnJfbW9kZSgicmVhZGluZyIpOworICAgIC8qIHJlZnVzZSB0byBtaXggd2l0aCBmLm5leHQoKSAqLworICAgIGlmIChmLT5mX2J1ZiAhPSBOVUxMICYmCisgICAgICAgIChmLT5mX2J1ZmVuZCAtIGYtPmZfYnVmcHRyKSA+IDAgJiYKKyAgICAgICAgZi0+Zl9idWZbMF0gIT0gJ1wwJykKKyAgICAgICAgcmV0dXJuIGVycl9pdGVyYnVmZmVyZWQoKTsKKyAgICBpZiAoIVB5QXJnX1BhcnNlVHVwbGUoYXJncywgInxsOnJlYWRsaW5lcyIsICZzaXplaGludCkpCisgICAgICAgIHJldHVybiBOVUxMOworICAgIGlmICgobGlzdCA9IFB5TGlzdF9OZXcoMCkpID09IE5VTEwpCisgICAgICAgIHJldHVybiBOVUxMOworICAgIGZvciAoOzspIHsKKyAgICAgICAgaWYgKHNob3J0cmVhZCkKKyAgICAgICAgICAgIG5yZWFkID0gMDsKKyAgICAgICAgZWxzZSB7CisgICAgICAgICAgICBGSUxFX0JFR0lOX0FMTE9XX1RIUkVBRFMoZikKKyAgICAgICAgICAgIGVycm5vID0gMDsKKyAgICAgICAgICAgIG5yZWFkID0gUHlfVW5pdmVyc2FsTmV3bGluZUZyZWFkKGJ1ZmZlcituZmlsbGVkLAorICAgICAgICAgICAgICAgIGJ1ZmZlcnNpemUtbmZpbGxlZCwgZi0+Zl9mcCwgKFB5T2JqZWN0ICopZik7CisgICAgICAgICAgICBGSUxFX0VORF9BTExPV19USFJFQURTKGYpCisgICAgICAgICAgICBzaG9ydHJlYWQgPSAobnJlYWQgPCBidWZmZXJzaXplLW5maWxsZWQpOworICAgICAgICB9CisgICAgICAgIGlmIChucmVhZCA9PSAwKSB7CisgICAgICAgICAgICBzaXplaGludCA9IDA7CisgICAgICAgICAgICBpZiAoIWZlcnJvcihmLT5mX2ZwKSkKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIGlmIChlcnJubyA9PSBFSU5UUikgeworICAgICAgICAgICAgICAgIGlmIChQeUVycl9DaGVja1NpZ25hbHMoKSkgeworICAgICAgICAgICAgICAgICAgICBnb3RvIGVycm9yOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBjbGVhcmVycihmLT5mX2ZwKTsKKyAgICAgICAgICAgICAgICBzaG9ydHJlYWQgPSAwOworICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgfQorICAgICAgICAgICAgUHlFcnJfU2V0RnJvbUVycm5vKFB5RXhjX0lPRXJyb3IpOworICAgICAgICAgICAgY2xlYXJlcnIoZi0+Zl9mcCk7CisgICAgICAgICAgICBnb3RvIGVycm9yOworICAgICAgICB9CisgICAgICAgIHRvdGFscmVhZCArPSBucmVhZDsKKyAgICAgICAgcCA9IChjaGFyICopbWVtY2hyKGJ1ZmZlcituZmlsbGVkLCAnXG4nLCBucmVhZCk7CisgICAgICAgIGlmIChwID09IE5VTEwpIHsKKyAgICAgICAgICAgIC8qIE5lZWQgYSBsYXJnZXIgYnVmZmVyIHRvIGZpdCB0aGlzIGxpbmUgKi8KKyAgICAgICAgICAgIG5maWxsZWQgKz0gbnJlYWQ7CisgICAgICAgICAgICBidWZmZXJzaXplICo9IDI7CisgICAgICAgICAgICBpZiAoYnVmZmVyc2l6ZSA+IFBZX1NTSVpFX1RfTUFYKSB7CisgICAgICAgICAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX092ZXJmbG93RXJyb3IsCisgICAgICAgICAgICAgICAgImxpbmUgaXMgbG9uZ2VyIHRoYW4gYSBQeXRob24gc3RyaW5nIGNhbiBob2xkIik7CisgICAgICAgICAgICAgICAgZ290byBlcnJvcjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChiaWdfYnVmZmVyID09IE5VTEwpIHsKKyAgICAgICAgICAgICAgICAvKiBDcmVhdGUgdGhlIGJpZyBidWZmZXIgKi8KKyAgICAgICAgICAgICAgICBiaWdfYnVmZmVyID0gUHlTdHJpbmdfRnJvbVN0cmluZ0FuZFNpemUoCisgICAgICAgICAgICAgICAgICAgIE5VTEwsIGJ1ZmZlcnNpemUpOworICAgICAgICAgICAgICAgIGlmIChiaWdfYnVmZmVyID09IE5VTEwpCisgICAgICAgICAgICAgICAgICAgIGdvdG8gZXJyb3I7CisgICAgICAgICAgICAgICAgYnVmZmVyID0gUHlTdHJpbmdfQVNfU1RSSU5HKGJpZ19idWZmZXIpOworICAgICAgICAgICAgICAgIG1lbWNweShidWZmZXIsIHNtYWxsX2J1ZmZlciwgbmZpbGxlZCk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBlbHNlIHsKKyAgICAgICAgICAgICAgICAvKiBHcm93IHRoZSBiaWcgYnVmZmVyICovCisgICAgICAgICAgICAgICAgaWYgKCBfUHlTdHJpbmdfUmVzaXplKCZiaWdfYnVmZmVyLCBidWZmZXJzaXplKSA8IDAgKQorICAgICAgICAgICAgICAgICAgICBnb3RvIGVycm9yOworICAgICAgICAgICAgICAgIGJ1ZmZlciA9IFB5U3RyaW5nX0FTX1NUUklORyhiaWdfYnVmZmVyKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICB9CisgICAgICAgIGVuZCA9IGJ1ZmZlcituZmlsbGVkK25yZWFkOworICAgICAgICBxID0gYnVmZmVyOworICAgICAgICBkbyB7CisgICAgICAgICAgICAvKiBQcm9jZXNzIGNvbXBsZXRlIGxpbmVzICovCisgICAgICAgICAgICBwKys7CisgICAgICAgICAgICBsaW5lID0gUHlTdHJpbmdfRnJvbVN0cmluZ0FuZFNpemUocSwgcC1xKTsKKyAgICAgICAgICAgIGlmIChsaW5lID09IE5VTEwpCisgICAgICAgICAgICAgICAgZ290byBlcnJvcjsKKyAgICAgICAgICAgIGVyciA9IFB5TGlzdF9BcHBlbmQobGlzdCwgbGluZSk7CisgICAgICAgICAgICBQeV9ERUNSRUYobGluZSk7CisgICAgICAgICAgICBpZiAoZXJyICE9IDApCisgICAgICAgICAgICAgICAgZ290byBlcnJvcjsKKyAgICAgICAgICAgIHEgPSBwOworICAgICAgICAgICAgcCA9IChjaGFyICopbWVtY2hyKHEsICdcbicsIGVuZC1xKTsKKyAgICAgICAgfSB3aGlsZSAocCAhPSBOVUxMKTsKKyAgICAgICAgLyogTW92ZSB0aGUgcmVtYWluaW5nIGluY29tcGxldGUgbGluZSB0byB0aGUgc3RhcnQgKi8KKyAgICAgICAgbmZpbGxlZCA9IGVuZC1xOworICAgICAgICBtZW1tb3ZlKGJ1ZmZlciwgcSwgbmZpbGxlZCk7CisgICAgICAgIGlmIChzaXplaGludCA+IDApCisgICAgICAgICAgICBpZiAodG90YWxyZWFkID49IChzaXplX3Qpc2l6ZWhpbnQpCisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgfQorICAgIGlmIChuZmlsbGVkICE9IDApIHsKKyAgICAgICAgLyogUGFydGlhbCBsYXN0IGxpbmUgKi8KKyAgICAgICAgbGluZSA9IFB5U3RyaW5nX0Zyb21TdHJpbmdBbmRTaXplKGJ1ZmZlciwgbmZpbGxlZCk7CisgICAgICAgIGlmIChsaW5lID09IE5VTEwpCisgICAgICAgICAgICBnb3RvIGVycm9yOworICAgICAgICBpZiAoc2l6ZWhpbnQgPiAwKSB7CisgICAgICAgICAgICAvKiBOZWVkIHRvIGNvbXBsZXRlIHRoZSBsYXN0IGxpbmUgKi8KKyAgICAgICAgICAgIFB5T2JqZWN0ICpyZXN0ID0gZ2V0X2xpbmUoZiwgMCk7CisgICAgICAgICAgICBpZiAocmVzdCA9PSBOVUxMKSB7CisgICAgICAgICAgICAgICAgUHlfREVDUkVGKGxpbmUpOworICAgICAgICAgICAgICAgIGdvdG8gZXJyb3I7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBQeVN0cmluZ19Db25jYXQoJmxpbmUsIHJlc3QpOworICAgICAgICAgICAgUHlfREVDUkVGKHJlc3QpOworICAgICAgICAgICAgaWYgKGxpbmUgPT0gTlVMTCkKKyAgICAgICAgICAgICAgICBnb3RvIGVycm9yOworICAgICAgICB9CisgICAgICAgIGVyciA9IFB5TGlzdF9BcHBlbmQobGlzdCwgbGluZSk7CisgICAgICAgIFB5X0RFQ1JFRihsaW5lKTsKKyAgICAgICAgaWYgKGVyciAhPSAwKQorICAgICAgICAgICAgZ290byBlcnJvcjsKKyAgICB9CisKK2NsZWFudXA6CisgICAgUHlfWERFQ1JFRihiaWdfYnVmZmVyKTsKKyAgICByZXR1cm4gbGlzdDsKKworZXJyb3I6CisgICAgUHlfQ0xFQVIobGlzdCk7CisgICAgZ290byBjbGVhbnVwOworfQorCitzdGF0aWMgUHlPYmplY3QgKgorZmlsZV93cml0ZShQeUZpbGVPYmplY3QgKmYsIFB5T2JqZWN0ICphcmdzKQoreworICAgIFB5X2J1ZmZlciBwYnVmOworICAgIGNvbnN0IGNoYXIgKnM7CisgICAgUHlfc3NpemVfdCBuLCBuMjsKKyAgICBQeU9iamVjdCAqZW5jb2RlZCA9IE5VTEw7CisKKyAgICBpZiAoZi0+Zl9mcCA9PSBOVUxMKQorICAgICAgICByZXR1cm4gZXJyX2Nsb3NlZCgpOworICAgIGlmICghZi0+d3JpdGFibGUpCisgICAgICAgIHJldHVybiBlcnJfbW9kZSgid3JpdGluZyIpOworICAgIGlmIChmLT5mX2JpbmFyeSkgeworICAgICAgICBpZiAoIVB5QXJnX1BhcnNlVHVwbGUoYXJncywgInMqIiwgJnBidWYpKQorICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgICAgIHMgPSBwYnVmLmJ1ZjsKKyAgICAgICAgbiA9IHBidWYubGVuOworICAgIH0KKyAgICBlbHNlIHsKKyAgICAgICAgUHlPYmplY3QgKnRleHQ7CisgICAgICAgIGlmICghUHlBcmdfUGFyc2VUdXBsZShhcmdzLCAiTyIsICZ0ZXh0KSkKKyAgICAgICAgICAgIHJldHVybiBOVUxMOworCisgICAgICAgIGlmIChQeVN0cmluZ19DaGVjayh0ZXh0KSkgeworICAgICAgICAgICAgcyA9IFB5U3RyaW5nX0FTX1NUUklORyh0ZXh0KTsKKyAgICAgICAgICAgIG4gPSBQeVN0cmluZ19HRVRfU0laRSh0ZXh0KTsKKyNpZmRlZiBQeV9VU0lOR19VTklDT0RFCisgICAgICAgIH0gZWxzZSBpZiAoUHlVbmljb2RlX0NoZWNrKHRleHQpKSB7CisgICAgICAgICAgICBjb25zdCBjaGFyICplbmNvZGluZywgKmVycm9yczsKKyAgICAgICAgICAgIGlmIChmLT5mX2VuY29kaW5nICE9IFB5X05vbmUpCisgICAgICAgICAgICAgICAgZW5jb2RpbmcgPSBQeVN0cmluZ19BU19TVFJJTkcoZi0+Zl9lbmNvZGluZyk7CisgICAgICAgICAgICBlbHNlCisgICAgICAgICAgICAgICAgZW5jb2RpbmcgPSBQeVVuaWNvZGVfR2V0RGVmYXVsdEVuY29kaW5nKCk7CisgICAgICAgICAgICBpZiAoZi0+Zl9lcnJvcnMgIT0gUHlfTm9uZSkKKyAgICAgICAgICAgICAgICBlcnJvcnMgPSBQeVN0cmluZ19BU19TVFJJTkcoZi0+Zl9lcnJvcnMpOworICAgICAgICAgICAgZWxzZQorICAgICAgICAgICAgICAgIGVycm9ycyA9ICJzdHJpY3QiOworICAgICAgICAgICAgZW5jb2RlZCA9IFB5VW5pY29kZV9Bc0VuY29kZWRTdHJpbmcodGV4dCwgZW5jb2RpbmcsIGVycm9ycyk7CisgICAgICAgICAgICBpZiAoZW5jb2RlZCA9PSBOVUxMKQorICAgICAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgICAgICAgICAgcyA9IFB5U3RyaW5nX0FTX1NUUklORyhlbmNvZGVkKTsKKyAgICAgICAgICAgIG4gPSBQeVN0cmluZ19HRVRfU0laRShlbmNvZGVkKTsKKyNlbmRpZgorICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgaWYgKFB5T2JqZWN0X0FzQ2hhckJ1ZmZlcih0ZXh0LCAmcywgJm4pKQorICAgICAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgICAgICB9CisgICAgfQorICAgIGYtPmZfc29mdHNwYWNlID0gMDsKKyAgICBGSUxFX0JFR0lOX0FMTE9XX1RIUkVBRFMoZikKKyAgICBlcnJubyA9IDA7CisgICAgbjIgPSBmd3JpdGUocywgMSwgbiwgZi0+Zl9mcCk7CisgICAgRklMRV9FTkRfQUxMT1dfVEhSRUFEUyhmKQorICAgIFB5X1hERUNSRUYoZW5jb2RlZCk7CisgICAgaWYgKGYtPmZfYmluYXJ5KQorICAgICAgICBQeUJ1ZmZlcl9SZWxlYXNlKCZwYnVmKTsKKyAgICBpZiAobjIgIT0gbikgeworICAgICAgICBQeUVycl9TZXRGcm9tRXJybm8oUHlFeGNfSU9FcnJvcik7CisgICAgICAgIGNsZWFyZXJyKGYtPmZfZnApOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgUHlfSU5DUkVGKFB5X05vbmUpOworICAgIHJldHVybiBQeV9Ob25lOworfQorCitzdGF0aWMgUHlPYmplY3QgKgorZmlsZV93cml0ZWxpbmVzKFB5RmlsZU9iamVjdCAqZiwgUHlPYmplY3QgKnNlcSkKK3sKKyNkZWZpbmUgQ0hVTktTSVpFIDEwMDAKKyAgICBQeU9iamVjdCAqbGlzdCwgKmxpbmU7CisgICAgUHlPYmplY3QgKml0OyAgICAgICAvKiBpdGVyKHNlcSkgKi8KKyAgICBQeU9iamVjdCAqcmVzdWx0OworICAgIGludCBpbmRleCwgaXNsaXN0OworICAgIFB5X3NzaXplX3QgaSwgaiwgbndyaXR0ZW4sIGxlbjsKKworICAgIGFzc2VydChzZXEgIT0gTlVMTCk7CisgICAgaWYgKGYtPmZfZnAgPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIGVycl9jbG9zZWQoKTsKKyAgICBpZiAoIWYtPndyaXRhYmxlKQorICAgICAgICByZXR1cm4gZXJyX21vZGUoIndyaXRpbmciKTsKKworICAgIHJlc3VsdCA9IE5VTEw7CisgICAgbGlzdCA9IE5VTEw7CisgICAgaXNsaXN0ID0gUHlMaXN0X0NoZWNrKHNlcSk7CisgICAgaWYgIChpc2xpc3QpCisgICAgICAgIGl0ID0gTlVMTDsKKyAgICBlbHNlIHsKKyAgICAgICAgaXQgPSBQeU9iamVjdF9HZXRJdGVyKHNlcSk7CisgICAgICAgIGlmIChpdCA9PSBOVUxMKSB7CisgICAgICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfVHlwZUVycm9yLAorICAgICAgICAgICAgICAgICJ3cml0ZWxpbmVzKCkgcmVxdWlyZXMgYW4gaXRlcmFibGUgYXJndW1lbnQiKTsKKyAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgICAgICB9CisgICAgICAgIC8qIEZyb20gaGVyZSBvbiwgZmFpbCBieSBnb2luZyB0byBlcnJvciwgdG8gcmVjbGFpbSAiaXQiLiAqLworICAgICAgICBsaXN0ID0gUHlMaXN0X05ldyhDSFVOS1NJWkUpOworICAgICAgICBpZiAobGlzdCA9PSBOVUxMKQorICAgICAgICAgICAgZ290byBlcnJvcjsKKyAgICB9CisKKyAgICAvKiBTdHJhdGVneTogc2x1cnAgQ0hVTktTSVpFIGxpbmVzIGludG8gYSBwcml2YXRlIGxpc3QsCisgICAgICAgY2hlY2tpbmcgdGhhdCB0aGV5IGFyZSBhbGwgc3RyaW5ncywgdGhlbiB3cml0ZSB0aGF0IGxpc3QKKyAgICAgICB3aXRob3V0IGhvbGRpbmcgdGhlIGludGVycHJldGVyIGxvY2ssIHRoZW4gY29tZSBiYWNrIGZvciBtb3JlLiAqLworICAgIGZvciAoaW5kZXggPSAwOyA7IGluZGV4ICs9IENIVU5LU0laRSkgeworICAgICAgICBpZiAoaXNsaXN0KSB7CisgICAgICAgICAgICBQeV9YREVDUkVGKGxpc3QpOworICAgICAgICAgICAgbGlzdCA9IFB5TGlzdF9HZXRTbGljZShzZXEsIGluZGV4LCBpbmRleCtDSFVOS1NJWkUpOworICAgICAgICAgICAgaWYgKGxpc3QgPT0gTlVMTCkKKyAgICAgICAgICAgICAgICBnb3RvIGVycm9yOworICAgICAgICAgICAgaiA9IFB5TGlzdF9HRVRfU0laRShsaXN0KTsKKyAgICAgICAgfQorICAgICAgICBlbHNlIHsKKyAgICAgICAgICAgIGZvciAoaiA9IDA7IGogPCBDSFVOS1NJWkU7IGorKykgeworICAgICAgICAgICAgICAgIGxpbmUgPSBQeUl0ZXJfTmV4dChpdCk7CisgICAgICAgICAgICAgICAgaWYgKGxpbmUgPT0gTlVMTCkgeworICAgICAgICAgICAgICAgICAgICBpZiAoUHlFcnJfT2NjdXJyZWQoKSkKKyAgICAgICAgICAgICAgICAgICAgICAgIGdvdG8gZXJyb3I7CisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBQeUxpc3RfU2V0SXRlbShsaXN0LCBqLCBsaW5lKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIC8qIFRoZSBpdGVyYXRvciBtaWdodCBoYXZlIGNsb3NlZCB0aGUgZmlsZSBvbiB1cy4gKi8KKyAgICAgICAgICAgIGlmIChmLT5mX2ZwID09IE5VTEwpIHsKKyAgICAgICAgICAgICAgICBlcnJfY2xvc2VkKCk7CisgICAgICAgICAgICAgICAgZ290byBlcnJvcjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBpZiAoaiA9PSAwKQorICAgICAgICAgICAgYnJlYWs7CisKKyAgICAgICAgLyogQ2hlY2sgdGhhdCBhbGwgZW50cmllcyBhcmUgaW5kZWVkIHN0cmluZ3MuIElmIG5vdCwKKyAgICAgICAgICAgYXBwbHkgdGhlIHNhbWUgcnVsZXMgYXMgZm9yIGZpbGUud3JpdGUoKSBhbmQKKyAgICAgICAgICAgY29udmVydCB0aGUgcmVzdWx0cyB0byBzdHJpbmdzLiBUaGlzIGlzIHNsb3csIGJ1dAorICAgICAgICAgICBzZWVtcyB0byBiZSB0aGUgb25seSB3YXkgc2luY2UgYWxsIGNvbnZlcnNpb24gQVBJcworICAgICAgICAgICBjb3VsZCBwb3RlbnRpYWxseSBleGVjdXRlIFB5dGhvbiBjb2RlLiAqLworICAgICAgICBmb3IgKGkgPSAwOyBpIDwgajsgaSsrKSB7CisgICAgICAgICAgICBQeU9iamVjdCAqdiA9IFB5TGlzdF9HRVRfSVRFTShsaXN0LCBpKTsKKyAgICAgICAgICAgIGlmICghUHlTdHJpbmdfQ2hlY2sodikpIHsKKyAgICAgICAgICAgICAgICBjb25zdCBjaGFyICpidWZmZXI7CisgICAgICAgICAgICAgICAgaWYgKCgoZi0+Zl9iaW5hcnkgJiYKKyAgICAgICAgICAgICAgICAgICAgICBQeU9iamVjdF9Bc1JlYWRCdWZmZXIodiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgKGNvbnN0IHZvaWQqKikmYnVmZmVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZsZW4pKSB8fAorICAgICAgICAgICAgICAgICAgICAgUHlPYmplY3RfQXNDaGFyQnVmZmVyKHYsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJmJ1ZmZlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmbGVuKSkpIHsKKyAgICAgICAgICAgICAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1R5cGVFcnJvciwKKyAgICAgICAgICAgICJ3cml0ZWxpbmVzKCkgYXJndW1lbnQgbXVzdCBiZSBhIHNlcXVlbmNlIG9mIHN0cmluZ3MiKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBnb3RvIGVycm9yOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBsaW5lID0gUHlTdHJpbmdfRnJvbVN0cmluZ0FuZFNpemUoYnVmZmVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZW4pOworICAgICAgICAgICAgICAgIGlmIChsaW5lID09IE5VTEwpCisgICAgICAgICAgICAgICAgICAgIGdvdG8gZXJyb3I7CisgICAgICAgICAgICAgICAgUHlfREVDUkVGKHYpOworICAgICAgICAgICAgICAgIFB5TGlzdF9TRVRfSVRFTShsaXN0LCBpLCBsaW5lKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIC8qIFNpbmNlIHdlIGFyZSByZWxlYXNpbmcgdGhlIGdsb2JhbCBsb2NrLCB0aGUKKyAgICAgICAgICAgZm9sbG93aW5nIGNvZGUgbWF5ICpub3QqIGV4ZWN1dGUgUHl0aG9uIGNvZGUuICovCisgICAgICAgIGYtPmZfc29mdHNwYWNlID0gMDsKKyAgICAgICAgRklMRV9CRUdJTl9BTExPV19USFJFQURTKGYpCisgICAgICAgIGVycm5vID0gMDsKKyAgICAgICAgZm9yIChpID0gMDsgaSA8IGo7IGkrKykgeworICAgICAgICAgICAgbGluZSA9IFB5TGlzdF9HRVRfSVRFTShsaXN0LCBpKTsKKyAgICAgICAgICAgIGxlbiA9IFB5U3RyaW5nX0dFVF9TSVpFKGxpbmUpOworICAgICAgICAgICAgbndyaXR0ZW4gPSBmd3JpdGUoUHlTdHJpbmdfQVNfU1RSSU5HKGxpbmUpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMSwgbGVuLCBmLT5mX2ZwKTsKKyAgICAgICAgICAgIGlmIChud3JpdHRlbiAhPSBsZW4pIHsKKyAgICAgICAgICAgICAgICBGSUxFX0FCT1JUX0FMTE9XX1RIUkVBRFMoZikKKyAgICAgICAgICAgICAgICBQeUVycl9TZXRGcm9tRXJybm8oUHlFeGNfSU9FcnJvcik7CisgICAgICAgICAgICAgICAgY2xlYXJlcnIoZi0+Zl9mcCk7CisgICAgICAgICAgICAgICAgZ290byBlcnJvcjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBGSUxFX0VORF9BTExPV19USFJFQURTKGYpCisKKyAgICAgICAgaWYgKGogPCBDSFVOS1NJWkUpCisgICAgICAgICAgICBicmVhazsKKyAgICB9CisKKyAgICBQeV9JTkNSRUYoUHlfTm9uZSk7CisgICAgcmVzdWx0ID0gUHlfTm9uZTsKKyAgZXJyb3I6CisgICAgUHlfWERFQ1JFRihsaXN0KTsKKyAgICBQeV9YREVDUkVGKGl0KTsKKyAgICByZXR1cm4gcmVzdWx0OworI3VuZGVmIENIVU5LU0laRQorfQorCitzdGF0aWMgUHlPYmplY3QgKgorZmlsZV9zZWxmKFB5RmlsZU9iamVjdCAqZikKK3sKKyAgICBpZiAoZi0+Zl9mcCA9PSBOVUxMKQorICAgICAgICByZXR1cm4gZXJyX2Nsb3NlZCgpOworICAgIFB5X0lOQ1JFRihmKTsKKyAgICByZXR1cm4gKFB5T2JqZWN0ICopZjsKK30KKworc3RhdGljIFB5T2JqZWN0ICoKK2ZpbGVfeHJlYWRsaW5lcyhQeUZpbGVPYmplY3QgKmYpCit7CisgICAgaWYgKFB5RXJyX1dhcm5QeTNrKCJmLnhyZWFkbGluZXMoKSBub3Qgc3VwcG9ydGVkIGluIDMueCwgIgorICAgICAgICAgICAgICAgICAgICAgICAidHJ5ICdmb3IgbGluZSBpbiBmJyBpbnN0ZWFkIiwgMSkgPCAwKQorICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICByZXR1cm4gZmlsZV9zZWxmKGYpOworfQorCitzdGF0aWMgUHlPYmplY3QgKgorZmlsZV9leGl0KFB5T2JqZWN0ICpmLCBQeU9iamVjdCAqYXJncykKK3sKKyAgICBQeU9iamVjdCAqcmV0ID0gUHlPYmplY3RfQ2FsbE1ldGhvZChmLCAiY2xvc2UiLCBOVUxMKTsKKyAgICBpZiAoIXJldCkKKyAgICAgICAgLyogSWYgZXJyb3Igb2NjdXJyZWQsIHBhc3MgdGhyb3VnaCAqLworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICBQeV9ERUNSRUYocmV0KTsKKyAgICAvKiBXZSBjYW5ub3QgcmV0dXJuIHRoZSByZXN1bHQgb2YgY2xvc2Ugc2luY2UgYSB0cnVlCisgICAgICogdmFsdWUgd2lsbCBiZSBpbnRlcnByZXRlZCBhcyAieWVzLCBzd2FsbG93IHRoZQorICAgICAqIGV4Y2VwdGlvbiBpZiBvbmUgd2FzIHJhaXNlZCBpbnNpZGUgdGhlIHdpdGggYmxvY2siLiAqLworICAgIFB5X1JFVFVSTl9OT05FOworfQorCitQeURvY19TVFJWQVIocmVhZGxpbmVfZG9jLAorInJlYWRsaW5lKFtzaXplXSkgLT4gbmV4dCBsaW5lIGZyb20gdGhlIGZpbGUsIGFzIGEgc3RyaW5nLlxuIgorIlxuIgorIlJldGFpbiBuZXdsaW5lLiAgQSBub24tbmVnYXRpdmUgc2l6ZSBhcmd1bWVudCBsaW1pdHMgdGhlIG1heGltdW1cbiIKKyJudW1iZXIgb2YgYnl0ZXMgdG8gcmV0dXJuIChhbiBpbmNvbXBsZXRlIGxpbmUgbWF5IGJlIHJldHVybmVkIHRoZW4pLlxuIgorIlJldHVybiBhbiBlbXB0eSBzdHJpbmcgYXQgRU9GLiIpOworCitQeURvY19TVFJWQVIocmVhZF9kb2MsCisicmVhZChbc2l6ZV0pIC0+IHJlYWQgYXQgbW9zdCBzaXplIGJ5dGVzLCByZXR1cm5lZCBhcyBhIHN0cmluZy5cbiIKKyJcbiIKKyJJZiB0aGUgc2l6ZSBhcmd1bWVudCBpcyBuZWdhdGl2ZSBvciBvbWl0dGVkLCByZWFkIHVudGlsIEVPRiBpcyByZWFjaGVkLlxuIgorIk5vdGljZSB0aGF0IHdoZW4gaW4gbm9uLWJsb2NraW5nIG1vZGUsIGxlc3MgZGF0YSB0aGFuIHdoYXQgd2FzIHJlcXVlc3RlZFxuIgorIm1heSBiZSByZXR1cm5lZCwgZXZlbiBpZiBubyBzaXplIHBhcmFtZXRlciB3YXMgZ2l2ZW4uIik7CisKK1B5RG9jX1NUUlZBUih3cml0ZV9kb2MsCisid3JpdGUoc3RyKSAtPiBOb25lLiAgV3JpdGUgc3RyaW5nIHN0ciB0byBmaWxlLlxuIgorIlxuIgorIk5vdGUgdGhhdCBkdWUgdG8gYnVmZmVyaW5nLCBmbHVzaCgpIG9yIGNsb3NlKCkgbWF5IGJlIG5lZWRlZCBiZWZvcmVcbiIKKyJ0aGUgZmlsZSBvbiBkaXNrIHJlZmxlY3RzIHRoZSBkYXRhIHdyaXR0ZW4uIik7CisKK1B5RG9jX1NUUlZBUihmaWxlbm9fZG9jLAorImZpbGVubygpIC0+IGludGVnZXIgXCJmaWxlIGRlc2NyaXB0b3JcIi5cbiIKKyJcbiIKKyJUaGlzIGlzIG5lZWRlZCBmb3IgbG93ZXItbGV2ZWwgZmlsZSBpbnRlcmZhY2VzLCBzdWNoIG9zLnJlYWQoKS4iKTsKKworUHlEb2NfU1RSVkFSKHNlZWtfZG9jLAorInNlZWsob2Zmc2V0Wywgd2hlbmNlXSkgLT4gTm9uZS4gIE1vdmUgdG8gbmV3IGZpbGUgcG9zaXRpb24uXG4iCisiXG4iCisiQXJndW1lbnQgb2Zmc2V0IGlzIGEgYnl0ZSBjb3VudC4gIE9wdGlvbmFsIGFyZ3VtZW50IHdoZW5jZSBkZWZhdWx0cyB0b1xuIgorIjAgKG9mZnNldCBmcm9tIHN0YXJ0IG9mIGZpbGUsIG9mZnNldCBzaG91bGQgYmUgPj0gMCk7IG90aGVyIHZhbHVlcyBhcmUgMVxuIgorIihtb3ZlIHJlbGF0aXZlIHRvIGN1cnJlbnQgcG9zaXRpb24sIHBvc2l0aXZlIG9yIG5lZ2F0aXZlKSwgYW5kIDIgKG1vdmVcbiIKKyJyZWxhdGl2ZSB0byBlbmQgb2YgZmlsZSwgdXN1YWxseSBuZWdhdGl2ZSwgYWx0aG91Z2ggbWFueSBwbGF0Zm9ybXMgYWxsb3dcbiIKKyJzZWVraW5nIGJleW9uZCB0aGUgZW5kIG9mIGEgZmlsZSkuICBJZiB0aGUgZmlsZSBpcyBvcGVuZWQgaW4gdGV4dCBtb2RlLFxuIgorIm9ubHkgb2Zmc2V0cyByZXR1cm5lZCBieSB0ZWxsKCkgYXJlIGxlZ2FsLiAgVXNlIG9mIG90aGVyIG9mZnNldHMgY2F1c2VzXG4iCisidW5kZWZpbmVkIGJlaGF2aW9yLiIKKyJcbiIKKyJOb3RlIHRoYXQgbm90IGFsbCBmaWxlIG9iamVjdHMgYXJlIHNlZWthYmxlLiIpOworCisjaWZkZWYgSEFWRV9GVFJVTkNBVEUKK1B5RG9jX1NUUlZBUih0cnVuY2F0ZV9kb2MsCisidHJ1bmNhdGUoW3NpemVdKSAtPiBOb25lLiAgVHJ1bmNhdGUgdGhlIGZpbGUgdG8gYXQgbW9zdCBzaXplIGJ5dGVzLlxuIgorIlxuIgorIlNpemUgZGVmYXVsdHMgdG8gdGhlIGN1cnJlbnQgZmlsZSBwb3NpdGlvbiwgYXMgcmV0dXJuZWQgYnkgdGVsbCgpLiIpOworI2VuZGlmCisKK1B5RG9jX1NUUlZBUih0ZWxsX2RvYywKKyJ0ZWxsKCkgLT4gY3VycmVudCBmaWxlIHBvc2l0aW9uLCBhbiBpbnRlZ2VyIChtYXkgYmUgYSBsb25nIGludGVnZXIpLiIpOworCitQeURvY19TVFJWQVIocmVhZGludG9fZG9jLAorInJlYWRpbnRvKCkgLT4gVW5kb2N1bWVudGVkLiAgRG9uJ3QgdXNlIHRoaXM7IGl0IG1heSBnbyBhd2F5LiIpOworCitQeURvY19TVFJWQVIocmVhZGxpbmVzX2RvYywKKyJyZWFkbGluZXMoW3NpemVdKSAtPiBsaXN0IG9mIHN0cmluZ3MsIGVhY2ggYSBsaW5lIGZyb20gdGhlIGZpbGUuXG4iCisiXG4iCisiQ2FsbCByZWFkbGluZSgpIHJlcGVhdGVkbHkgYW5kIHJldHVybiBhIGxpc3Qgb2YgdGhlIGxpbmVzIHNvIHJlYWQuXG4iCisiVGhlIG9wdGlvbmFsIHNpemUgYXJndW1lbnQsIGlmIGdpdmVuLCBpcyBhbiBhcHByb3hpbWF0ZSBib3VuZCBvbiB0aGVcbiIKKyJ0b3RhbCBudW1iZXIgb2YgYnl0ZXMgaW4gdGhlIGxpbmVzIHJldHVybmVkLiIpOworCitQeURvY19TVFJWQVIoeHJlYWRsaW5lc19kb2MsCisieHJlYWRsaW5lcygpIC0+IHJldHVybnMgc2VsZi5cbiIKKyJcbiIKKyJGb3IgYmFja3dhcmQgY29tcGF0aWJpbGl0eS4gRmlsZSBvYmplY3RzIG5vdyBpbmNsdWRlIHRoZSBwZXJmb3JtYW5jZVxuIgorIm9wdGltaXphdGlvbnMgcHJldmlvdXNseSBpbXBsZW1lbnRlZCBpbiB0aGUgeHJlYWRsaW5lcyBtb2R1bGUuIik7CisKK1B5RG9jX1NUUlZBUih3cml0ZWxpbmVzX2RvYywKKyJ3cml0ZWxpbmVzKHNlcXVlbmNlX29mX3N0cmluZ3MpIC0+IE5vbmUuICBXcml0ZSB0aGUgc3RyaW5ncyB0byB0aGUgZmlsZS5cbiIKKyJcbiIKKyJOb3RlIHRoYXQgbmV3bGluZXMgYXJlIG5vdCBhZGRlZC4gIFRoZSBzZXF1ZW5jZSBjYW4gYmUgYW55IGl0ZXJhYmxlIG9iamVjdFxuIgorInByb2R1Y2luZyBzdHJpbmdzLiBUaGlzIGlzIGVxdWl2YWxlbnQgdG8gY2FsbGluZyB3cml0ZSgpIGZvciBlYWNoIHN0cmluZy4iKTsKKworUHlEb2NfU1RSVkFSKGZsdXNoX2RvYywKKyJmbHVzaCgpIC0+IE5vbmUuICBGbHVzaCB0aGUgaW50ZXJuYWwgSS9PIGJ1ZmZlci4iKTsKKworUHlEb2NfU1RSVkFSKGNsb3NlX2RvYywKKyJjbG9zZSgpIC0+IE5vbmUgb3IgKHBlcmhhcHMpIGFuIGludGVnZXIuICBDbG9zZSB0aGUgZmlsZS5cbiIKKyJcbiIKKyJTZXRzIGRhdGEgYXR0cmlidXRlIC5jbG9zZWQgdG8gVHJ1ZS4gIEEgY2xvc2VkIGZpbGUgY2Fubm90IGJlIHVzZWQgZm9yXG4iCisiZnVydGhlciBJL08gb3BlcmF0aW9ucy4gIGNsb3NlKCkgbWF5IGJlIGNhbGxlZCBtb3JlIHRoYW4gb25jZSB3aXRob3V0XG4iCisiZXJyb3IuICBTb21lIGtpbmRzIG9mIGZpbGUgb2JqZWN0cyAoZm9yIGV4YW1wbGUsIG9wZW5lZCBieSBwb3BlbigpKVxuIgorIm1heSByZXR1cm4gYW4gZXhpdCBzdGF0dXMgdXBvbiBjbG9zaW5nLiIpOworCitQeURvY19TVFJWQVIoaXNhdHR5X2RvYywKKyJpc2F0dHkoKSAtPiB0cnVlIG9yIGZhbHNlLiAgVHJ1ZSBpZiB0aGUgZmlsZSBpcyBjb25uZWN0ZWQgdG8gYSB0dHkgZGV2aWNlLiIpOworCitQeURvY19TVFJWQVIoZW50ZXJfZG9jLAorICAgICAgICAgICAgICJfX2VudGVyX18oKSAtPiBzZWxmLiIpOworCitQeURvY19TVFJWQVIoZXhpdF9kb2MsCisgICAgICAgICAgICAgIl9fZXhpdF9fKCpleGNpbmZvKSAtPiBOb25lLiAgQ2xvc2VzIHRoZSBmaWxlLiIpOworCitzdGF0aWMgUHlNZXRob2REZWYgZmlsZV9tZXRob2RzW10gPSB7CisgICAgeyJyZWFkbGluZSIsICAoUHlDRnVuY3Rpb24pZmlsZV9yZWFkbGluZSwgTUVUSF9WQVJBUkdTLCByZWFkbGluZV9kb2N9LAorICAgIHsicmVhZCIsICAgICAgKFB5Q0Z1bmN0aW9uKWZpbGVfcmVhZCwgICAgIE1FVEhfVkFSQVJHUywgcmVhZF9kb2N9LAorICAgIHsid3JpdGUiLCAgICAgKFB5Q0Z1bmN0aW9uKWZpbGVfd3JpdGUsICAgIE1FVEhfVkFSQVJHUywgd3JpdGVfZG9jfSwKKyAgICB7ImZpbGVubyIsICAgIChQeUNGdW5jdGlvbilmaWxlX2ZpbGVubywgICBNRVRIX05PQVJHUywgIGZpbGVub19kb2N9LAorICAgIHsic2VlayIsICAgICAgKFB5Q0Z1bmN0aW9uKWZpbGVfc2VlaywgICAgIE1FVEhfVkFSQVJHUywgc2Vla19kb2N9LAorI2lmZGVmIEhBVkVfRlRSVU5DQVRFCisgICAgeyJ0cnVuY2F0ZSIsICAoUHlDRnVuY3Rpb24pZmlsZV90cnVuY2F0ZSwgTUVUSF9WQVJBUkdTLCB0cnVuY2F0ZV9kb2N9LAorI2VuZGlmCisgICAgeyJ0ZWxsIiwgICAgICAoUHlDRnVuY3Rpb24pZmlsZV90ZWxsLCAgICAgTUVUSF9OT0FSR1MsICB0ZWxsX2RvY30sCisgICAgeyJyZWFkaW50byIsICAoUHlDRnVuY3Rpb24pZmlsZV9yZWFkaW50bywgTUVUSF9WQVJBUkdTLCByZWFkaW50b19kb2N9LAorICAgIHsicmVhZGxpbmVzIiwgKFB5Q0Z1bmN0aW9uKWZpbGVfcmVhZGxpbmVzLCBNRVRIX1ZBUkFSR1MsIHJlYWRsaW5lc19kb2N9LAorICAgIHsieHJlYWRsaW5lcyIsKFB5Q0Z1bmN0aW9uKWZpbGVfeHJlYWRsaW5lcywgTUVUSF9OT0FSR1MsIHhyZWFkbGluZXNfZG9jfSwKKyAgICB7IndyaXRlbGluZXMiLChQeUNGdW5jdGlvbilmaWxlX3dyaXRlbGluZXMsIE1FVEhfTywgICAgIHdyaXRlbGluZXNfZG9jfSwKKyAgICB7ImZsdXNoIiwgICAgIChQeUNGdW5jdGlvbilmaWxlX2ZsdXNoLCAgICBNRVRIX05PQVJHUywgIGZsdXNoX2RvY30sCisgICAgeyJjbG9zZSIsICAgICAoUHlDRnVuY3Rpb24pZmlsZV9jbG9zZSwgICAgTUVUSF9OT0FSR1MsICBjbG9zZV9kb2N9LAorICAgIHsiaXNhdHR5IiwgICAgKFB5Q0Z1bmN0aW9uKWZpbGVfaXNhdHR5LCAgIE1FVEhfTk9BUkdTLCAgaXNhdHR5X2RvY30sCisgICAgeyJfX2VudGVyX18iLCAoUHlDRnVuY3Rpb24pZmlsZV9zZWxmLCAgICAgTUVUSF9OT0FSR1MsICBlbnRlcl9kb2N9LAorICAgIHsiX19leGl0X18iLCAgKFB5Q0Z1bmN0aW9uKWZpbGVfZXhpdCwgICAgIE1FVEhfVkFSQVJHUywgZXhpdF9kb2N9LAorICAgIHtOVUxMLCAgICAgICAgICAgIE5VTEx9ICAgICAgICAgICAgIC8qIHNlbnRpbmVsICovCit9OworCisjZGVmaW5lIE9GRih4KSBvZmZzZXRvZihQeUZpbGVPYmplY3QsIHgpCisKK3N0YXRpYyBQeU1lbWJlckRlZiBmaWxlX21lbWJlcmxpc3RbXSA9IHsKKyAgICB7Im1vZGUiLCAgICAgICAgICAgIFRfT0JKRUNULCAgICAgICBPRkYoZl9tb2RlKSwgICAgUk8sCisgICAgICJmaWxlIG1vZGUgKCdyJywgJ1UnLCAndycsICdhJywgcG9zc2libHkgd2l0aCAnYicgb3IgJysnIGFkZGVkKSJ9LAorICAgIHsibmFtZSIsICAgICAgICAgICAgVF9PQkpFQ1QsICAgICAgIE9GRihmX25hbWUpLCAgICBSTywKKyAgICAgImZpbGUgbmFtZSJ9LAorICAgIHsiZW5jb2RpbmciLCAgICAgICAgVF9PQkpFQ1QsICAgICAgIE9GRihmX2VuY29kaW5nKSwgICAgICAgIFJPLAorICAgICAiZmlsZSBlbmNvZGluZyJ9LAorICAgIHsiZXJyb3JzIiwgICAgICAgICAgVF9PQkpFQ1QsICAgICAgIE9GRihmX2Vycm9ycyksICBSTywKKyAgICAgIlVuaWNvZGUgZXJyb3IgaGFuZGxlciJ9LAorICAgIC8qIGdldGF0dHIoZiwgImNsb3NlZCIpIGlzIGltcGxlbWVudGVkIHdpdGhvdXQgdGhpcyB0YWJsZSAqLworICAgIHtOVUxMfSAgICAgIC8qIFNlbnRpbmVsICovCit9OworCitzdGF0aWMgUHlPYmplY3QgKgorZ2V0X2Nsb3NlZChQeUZpbGVPYmplY3QgKmYsIHZvaWQgKmNsb3N1cmUpCit7CisgICAgcmV0dXJuIFB5Qm9vbF9Gcm9tTG9uZygobG9uZykoZi0+Zl9mcCA9PSAwKSk7Cit9CitzdGF0aWMgUHlPYmplY3QgKgorZ2V0X25ld2xpbmVzKFB5RmlsZU9iamVjdCAqZiwgdm9pZCAqY2xvc3VyZSkKK3sKKyAgICBzd2l0Y2ggKGYtPmZfbmV3bGluZXR5cGVzKSB7CisgICAgY2FzZSBORVdMSU5FX1VOS05PV046CisgICAgICAgIFB5X0lOQ1JFRihQeV9Ob25lKTsKKyAgICAgICAgcmV0dXJuIFB5X05vbmU7CisgICAgY2FzZSBORVdMSU5FX0NSOgorICAgICAgICByZXR1cm4gUHlTdHJpbmdfRnJvbVN0cmluZygiXHIiKTsKKyAgICBjYXNlIE5FV0xJTkVfTEY6CisgICAgICAgIHJldHVybiBQeVN0cmluZ19Gcm9tU3RyaW5nKCJcbiIpOworICAgIGNhc2UgTkVXTElORV9DUnxORVdMSU5FX0xGOgorICAgICAgICByZXR1cm4gUHlfQnVpbGRWYWx1ZSgiKHNzKSIsICJcciIsICJcbiIpOworICAgIGNhc2UgTkVXTElORV9DUkxGOgorICAgICAgICByZXR1cm4gUHlTdHJpbmdfRnJvbVN0cmluZygiXHJcbiIpOworICAgIGNhc2UgTkVXTElORV9DUnxORVdMSU5FX0NSTEY6CisgICAgICAgIHJldHVybiBQeV9CdWlsZFZhbHVlKCIoc3MpIiwgIlxyIiwgIlxyXG4iKTsKKyAgICBjYXNlIE5FV0xJTkVfTEZ8TkVXTElORV9DUkxGOgorICAgICAgICByZXR1cm4gUHlfQnVpbGRWYWx1ZSgiKHNzKSIsICJcbiIsICJcclxuIik7CisgICAgY2FzZSBORVdMSU5FX0NSfE5FV0xJTkVfTEZ8TkVXTElORV9DUkxGOgorICAgICAgICByZXR1cm4gUHlfQnVpbGRWYWx1ZSgiKHNzcykiLCAiXHIiLCAiXG4iLCAiXHJcbiIpOworICAgIGRlZmF1bHQ6CisgICAgICAgIFB5RXJyX0Zvcm1hdChQeUV4Y19TeXN0ZW1FcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICJVbmtub3duIG5ld2xpbmVzIHZhbHVlIDB4JXhcbiIsCisgICAgICAgICAgICAgICAgICAgICBmLT5mX25ld2xpbmV0eXBlcyk7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KK30KKworc3RhdGljIFB5T2JqZWN0ICoKK2dldF9zb2Z0c3BhY2UoUHlGaWxlT2JqZWN0ICpmLCB2b2lkICpjbG9zdXJlKQoreworICAgIGlmIChQeUVycl9XYXJuUHkzaygiZmlsZS5zb2Z0c3BhY2Ugbm90IHN1cHBvcnRlZCBpbiAzLngiLCAxKSA8IDApCisgICAgICAgIHJldHVybiBOVUxMOworICAgIHJldHVybiBQeUludF9Gcm9tTG9uZyhmLT5mX3NvZnRzcGFjZSk7Cit9CisKK3N0YXRpYyBpbnQKK3NldF9zb2Z0c3BhY2UoUHlGaWxlT2JqZWN0ICpmLCBQeU9iamVjdCAqdmFsdWUpCit7CisgICAgaW50IG5ldzsKKyAgICBpZiAoUHlFcnJfV2FyblB5M2soImZpbGUuc29mdHNwYWNlIG5vdCBzdXBwb3J0ZWQgaW4gMy54IiwgMSkgPCAwKQorICAgICAgICByZXR1cm4gLTE7CisKKyAgICBpZiAodmFsdWUgPT0gTlVMTCkgeworICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfVHlwZUVycm9yLAorICAgICAgICAgICAgICAgICAgICAgICAgImNhbid0IGRlbGV0ZSBzb2Z0c3BhY2UgYXR0cmlidXRlIik7CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisKKyAgICBuZXcgPSBQeUludF9Bc0xvbmcodmFsdWUpOworICAgIGlmIChuZXcgPT0gLTEgJiYgUHlFcnJfT2NjdXJyZWQoKSkKKyAgICAgICAgcmV0dXJuIC0xOworICAgIGYtPmZfc29mdHNwYWNlID0gbmV3OworICAgIHJldHVybiAwOworfQorCitzdGF0aWMgUHlHZXRTZXREZWYgZmlsZV9nZXRzZXRsaXN0W10gPSB7CisgICAgeyJjbG9zZWQiLCAoZ2V0dGVyKWdldF9jbG9zZWQsIE5VTEwsICJUcnVlIGlmIHRoZSBmaWxlIGlzIGNsb3NlZCJ9LAorICAgIHsibmV3bGluZXMiLCAoZ2V0dGVyKWdldF9uZXdsaW5lcywgTlVMTCwKKyAgICAgImVuZC1vZi1saW5lIGNvbnZlbnRpb24gdXNlZCBpbiB0aGlzIGZpbGUifSwKKyAgICB7InNvZnRzcGFjZSIsIChnZXR0ZXIpZ2V0X3NvZnRzcGFjZSwgKHNldHRlcilzZXRfc29mdHNwYWNlLAorICAgICAiZmxhZyBpbmRpY2F0aW5nIHRoYXQgYSBzcGFjZSBuZWVkcyB0byBiZSBwcmludGVkOyB1c2VkIGJ5IHByaW50In0sCisgICAgezB9LAorfTsKKworc3RhdGljIHZvaWQKK2Ryb3BfcmVhZGFoZWFkKFB5RmlsZU9iamVjdCAqZikKK3sKKyAgICBpZiAoZi0+Zl9idWYgIT0gTlVMTCkgeworICAgICAgICBQeU1lbV9GcmVlKGYtPmZfYnVmKTsKKyAgICAgICAgZi0+Zl9idWYgPSBOVUxMOworICAgIH0KK30KKworLyogTWFrZSBzdXJlIHRoYXQgZmlsZSBoYXMgYSByZWFkYWhlYWQgYnVmZmVyIHdpdGggYXQgbGVhc3Qgb25lIGJ5dGUKKyAgICh1bmxlc3MgYXQgRU9GKSBhbmQgbm8gbW9yZSB0aGFuIGJ1ZnNpemUuICBSZXR1cm5zIG5lZ2F0aXZlIHZhbHVlIG9uCisgICBlcnJvciwgd2lsbCBzZXQgTWVtb3J5RXJyb3IgaWYgYnVmc2l6ZSBieXRlcyBjYW5ub3QgYmUgYWxsb2NhdGVkLiAqLworc3RhdGljIGludAorcmVhZGFoZWFkKFB5RmlsZU9iamVjdCAqZiwgaW50IGJ1ZnNpemUpCit7CisgICAgUHlfc3NpemVfdCBjaHVua3NpemU7CisKKyAgICBpZiAoZi0+Zl9idWYgIT0gTlVMTCkgeworICAgICAgICBpZiggKGYtPmZfYnVmZW5kIC0gZi0+Zl9idWZwdHIpID49IDEpCisgICAgICAgICAgICByZXR1cm4gMDsKKyAgICAgICAgZWxzZQorICAgICAgICAgICAgZHJvcF9yZWFkYWhlYWQoZik7CisgICAgfQorICAgIGlmICgoZi0+Zl9idWYgPSAoY2hhciAqKVB5TWVtX01hbGxvYyhidWZzaXplKSkgPT0gTlVMTCkgeworICAgICAgICBQeUVycl9Ob01lbW9yeSgpOworICAgICAgICByZXR1cm4gLTE7CisgICAgfQorICAgIEZJTEVfQkVHSU5fQUxMT1dfVEhSRUFEUyhmKQorICAgIGVycm5vID0gMDsKKyAgICBjaHVua3NpemUgPSBQeV9Vbml2ZXJzYWxOZXdsaW5lRnJlYWQoCisgICAgICAgIGYtPmZfYnVmLCBidWZzaXplLCBmLT5mX2ZwLCAoUHlPYmplY3QgKilmKTsKKyAgICBGSUxFX0VORF9BTExPV19USFJFQURTKGYpCisgICAgaWYgKGNodW5rc2l6ZSA9PSAwKSB7CisgICAgICAgIGlmIChmZXJyb3IoZi0+Zl9mcCkpIHsKKyAgICAgICAgICAgIFB5RXJyX1NldEZyb21FcnJubyhQeUV4Y19JT0Vycm9yKTsKKyAgICAgICAgICAgIGNsZWFyZXJyKGYtPmZfZnApOworICAgICAgICAgICAgZHJvcF9yZWFkYWhlYWQoZik7CisgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgIH0KKyAgICB9CisgICAgZi0+Zl9idWZwdHIgPSBmLT5mX2J1ZjsKKyAgICBmLT5mX2J1ZmVuZCA9IGYtPmZfYnVmICsgY2h1bmtzaXplOworICAgIHJldHVybiAwOworfQorCisvKiBVc2VkIGJ5IGZpbGVfaXRlcm5leHQuICBUaGUgcmV0dXJuZWQgc3RyaW5nIHdpbGwgc3RhcnQgd2l0aCAnc2tpcCcKKyAgIHVuaW5pdGlhbGl6ZWQgYnl0ZXMgZm9sbG93ZWQgYnkgdGhlIHJlbWFpbmRlciBvZiB0aGUgbGluZS4gRG9uJ3QgYmUKKyAgIGhvcnJpZmllZCBieSB0aGUgcmVjdXJzaXZlIGNhbGw6IG1heGltdW0gcmVjdXJzaW9uIGRlcHRoIGlzIGxpbWl0ZWQgYnkKKyAgIGxvZ2FyaXRobWljIGJ1ZmZlciBncm93dGggdG8gYWJvdXQgNTAgZXZlbiB3aGVuIHJlYWRpbmcgYSAxZ2IgbGluZS4gKi8KKworc3RhdGljIFB5U3RyaW5nT2JqZWN0ICoKK3JlYWRhaGVhZF9nZXRfbGluZV9za2lwKFB5RmlsZU9iamVjdCAqZiwgaW50IHNraXAsIGludCBidWZzaXplKQoreworICAgIFB5U3RyaW5nT2JqZWN0KiBzOworICAgIGNoYXIgKmJ1ZnB0cjsKKyAgICBjaGFyICpidWY7CisgICAgUHlfc3NpemVfdCBsZW47CisKKyAgICBpZiAoZi0+Zl9idWYgPT0gTlVMTCkKKyAgICAgICAgaWYgKHJlYWRhaGVhZChmLCBidWZzaXplKSA8IDApCisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKworICAgIGxlbiA9IGYtPmZfYnVmZW5kIC0gZi0+Zl9idWZwdHI7CisgICAgaWYgKGxlbiA9PSAwKQorICAgICAgICByZXR1cm4gKFB5U3RyaW5nT2JqZWN0ICopCisgICAgICAgICAgICBQeVN0cmluZ19Gcm9tU3RyaW5nQW5kU2l6ZShOVUxMLCBza2lwKTsKKyAgICBidWZwdHIgPSAoY2hhciAqKW1lbWNocihmLT5mX2J1ZnB0ciwgJ1xuJywgbGVuKTsKKyAgICBpZiAoYnVmcHRyICE9IE5VTEwpIHsKKyAgICAgICAgYnVmcHRyKys7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIENvdW50IHRoZSAnXG4nICovCisgICAgICAgIGxlbiA9IGJ1ZnB0ciAtIGYtPmZfYnVmcHRyOworICAgICAgICBzID0gKFB5U3RyaW5nT2JqZWN0ICopCisgICAgICAgICAgICBQeVN0cmluZ19Gcm9tU3RyaW5nQW5kU2l6ZShOVUxMLCBza2lwK2xlbik7CisgICAgICAgIGlmIChzID09IE5VTEwpCisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgbWVtY3B5KFB5U3RyaW5nX0FTX1NUUklORyhzKStza2lwLCBmLT5mX2J1ZnB0ciwgbGVuKTsKKyAgICAgICAgZi0+Zl9idWZwdHIgPSBidWZwdHI7CisgICAgICAgIGlmIChidWZwdHIgPT0gZi0+Zl9idWZlbmQpCisgICAgICAgICAgICBkcm9wX3JlYWRhaGVhZChmKTsKKyAgICB9IGVsc2UgeworICAgICAgICBidWZwdHIgPSBmLT5mX2J1ZnB0cjsKKyAgICAgICAgYnVmID0gZi0+Zl9idWY7CisgICAgICAgIGYtPmZfYnVmID0gTlVMTDsgICAgICAgICAgICAgICAgLyogRm9yY2UgbmV3IHJlYWRhaGVhZCBidWZmZXIgKi8KKyAgICAgICAgYXNzZXJ0KHNraXArbGVuIDwgSU5UX01BWCk7CisgICAgICAgIHMgPSByZWFkYWhlYWRfZ2V0X2xpbmVfc2tpcCgKKyAgICAgICAgICAgIGYsIChpbnQpKHNraXArbGVuKSwgYnVmc2l6ZSArIChidWZzaXplPj4yKSApOworICAgICAgICBpZiAocyA9PSBOVUxMKSB7CisgICAgICAgICAgICBQeU1lbV9GcmVlKGJ1Zik7CisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgfQorICAgICAgICBtZW1jcHkoUHlTdHJpbmdfQVNfU1RSSU5HKHMpK3NraXAsIGJ1ZnB0ciwgbGVuKTsKKyAgICAgICAgUHlNZW1fRnJlZShidWYpOworICAgIH0KKyAgICByZXR1cm4gczsKK30KKworLyogQSBsYXJnZXIgYnVmZmVyIHNpemUgbWF5IGFjdHVhbGx5IGRlY3JlYXNlIHBlcmZvcm1hbmNlLiAqLworI2RlZmluZSBSRUFEQUhFQURfQlVGU0laRSA4MTkyCisKK3N0YXRpYyBQeU9iamVjdCAqCitmaWxlX2l0ZXJuZXh0KFB5RmlsZU9iamVjdCAqZikKK3sKKyAgICBQeVN0cmluZ09iamVjdCogbDsKKworICAgIGlmIChmLT5mX2ZwID09IE5VTEwpCisgICAgICAgIHJldHVybiBlcnJfY2xvc2VkKCk7CisgICAgaWYgKCFmLT5yZWFkYWJsZSkKKyAgICAgICAgcmV0dXJuIGVycl9tb2RlKCJyZWFkaW5nIik7CisKKyAgICBsID0gcmVhZGFoZWFkX2dldF9saW5lX3NraXAoZiwgMCwgUkVBREFIRUFEX0JVRlNJWkUpOworICAgIGlmIChsID09IE5VTEwgfHwgUHlTdHJpbmdfR0VUX1NJWkUobCkgPT0gMCkgeworICAgICAgICBQeV9YREVDUkVGKGwpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgcmV0dXJuIChQeU9iamVjdCAqKWw7Cit9CisKKworc3RhdGljIFB5T2JqZWN0ICoKK2ZpbGVfbmV3KFB5VHlwZU9iamVjdCAqdHlwZSwgUHlPYmplY3QgKmFyZ3MsIFB5T2JqZWN0ICprd2RzKQoreworICAgIFB5T2JqZWN0ICpzZWxmOworICAgIHN0YXRpYyBQeU9iamVjdCAqbm90X3lldF9zdHJpbmc7CisKKyAgICBhc3NlcnQodHlwZSAhPSBOVUxMICYmIHR5cGUtPnRwX2FsbG9jICE9IE5VTEwpOworCisgICAgaWYgKG5vdF95ZXRfc3RyaW5nID09IE5VTEwpIHsKKyAgICAgICAgbm90X3lldF9zdHJpbmcgPSBQeVN0cmluZ19JbnRlcm5Gcm9tU3RyaW5nKCI8dW5pbml0aWFsaXplZCBmaWxlPiIpOworICAgICAgICBpZiAobm90X3lldF9zdHJpbmcgPT0gTlVMTCkKKyAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKworICAgIHNlbGYgPSB0eXBlLT50cF9hbGxvYyh0eXBlLCAwKTsKKyAgICBpZiAoc2VsZiAhPSBOVUxMKSB7CisgICAgICAgIC8qIEFsd2F5cyBmaWxsIGluIHRoZSBuYW1lIGFuZCBtb2RlLCBzbyB0aGF0IG5vYm9keSBlbHNlCisgICAgICAgICAgIG5lZWRzIHRvIHNwZWNpYWwtY2FzZSBOVUxMcyB0aGVyZS4gKi8KKyAgICAgICAgUHlfSU5DUkVGKG5vdF95ZXRfc3RyaW5nKTsKKyAgICAgICAgKChQeUZpbGVPYmplY3QgKilzZWxmKS0+Zl9uYW1lID0gbm90X3lldF9zdHJpbmc7CisgICAgICAgIFB5X0lOQ1JFRihub3RfeWV0X3N0cmluZyk7CisgICAgICAgICgoUHlGaWxlT2JqZWN0ICopc2VsZiktPmZfbW9kZSA9IG5vdF95ZXRfc3RyaW5nOworICAgICAgICBQeV9JTkNSRUYoUHlfTm9uZSk7CisgICAgICAgICgoUHlGaWxlT2JqZWN0ICopc2VsZiktPmZfZW5jb2RpbmcgPSBQeV9Ob25lOworICAgICAgICBQeV9JTkNSRUYoUHlfTm9uZSk7CisgICAgICAgICgoUHlGaWxlT2JqZWN0ICopc2VsZiktPmZfZXJyb3JzID0gUHlfTm9uZTsKKyAgICAgICAgKChQeUZpbGVPYmplY3QgKilzZWxmKS0+d2Vha3JlZmxpc3QgPSBOVUxMOworICAgICAgICAoKFB5RmlsZU9iamVjdCAqKXNlbGYpLT51bmxvY2tlZF9jb3VudCA9IDA7CisgICAgfQorICAgIHJldHVybiBzZWxmOworfQorCitzdGF0aWMgaW50CitmaWxlX2luaXQoUHlPYmplY3QgKnNlbGYsIFB5T2JqZWN0ICphcmdzLCBQeU9iamVjdCAqa3dkcykKK3sKKyAgICBQeUZpbGVPYmplY3QgKmZvc2VsZiA9IChQeUZpbGVPYmplY3QgKilzZWxmOworICAgIGludCByZXQgPSAwOworICAgIHN0YXRpYyBjaGFyICprd2xpc3RbXSA9IHsibmFtZSIsICJtb2RlIiwgImJ1ZmZlcmluZyIsIDB9OworICAgIGNoYXIgKm5hbWUgPSBOVUxMOworICAgIGNoYXIgKm1vZGUgPSAiciI7CisgICAgaW50IGJ1ZnNpemUgPSAtMTsKKyAgICBpbnQgd2lkZWFyZ3VtZW50ID0gMDsKKyNpZmRlZiBNU19XSU5ET1dTCisgICAgUHlPYmplY3QgKnBvOworI2VuZGlmCisKKyAgICBhc3NlcnQoUHlGaWxlX0NoZWNrKHNlbGYpKTsKKyAgICBpZiAoZm9zZWxmLT5mX2ZwICE9IE5VTEwpIHsKKyAgICAgICAgLyogSGF2ZSB0byBjbG9zZSB0aGUgZXhpc3RpbmcgZmlsZSBmaXJzdC4gKi8KKyAgICAgICAgUHlPYmplY3QgKmNsb3NlcmVzdWx0ID0gZmlsZV9jbG9zZShmb3NlbGYpOworICAgICAgICBpZiAoY2xvc2VyZXN1bHQgPT0gTlVMTCkKKyAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgUHlfREVDUkVGKGNsb3NlcmVzdWx0KTsKKyAgICB9CisKKyNpZmRlZiBNU19XSU5ET1dTCisgICAgaWYgKFB5QXJnX1BhcnNlVHVwbGVBbmRLZXl3b3JkcyhhcmdzLCBrd2RzLCAiVXxzaTpmaWxlIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGt3bGlzdCwgJnBvLCAmbW9kZSwgJmJ1ZnNpemUpKSB7CisgICAgICAgIHdpZGVhcmd1bWVudCA9IDE7CisgICAgICAgIGlmIChmaWxsX2ZpbGVfZmllbGRzKGZvc2VsZiwgTlVMTCwgcG8sIG1vZGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZjbG9zZSkgPT0gTlVMTCkKKyAgICAgICAgICAgIGdvdG8gRXJyb3I7CisgICAgfSBlbHNlIHsKKyAgICAgICAgLyogRHJvcCB0aGUgYXJndW1lbnQgcGFyc2luZyBlcnJvciBhcyBuYXJyb3cKKyAgICAgICAgICAgc3RyaW5ncyBhcmUgYWxzbyB2YWxpZC4gKi8KKyAgICAgICAgUHlFcnJfQ2xlYXIoKTsKKyAgICB9CisjZW5kaWYKKworICAgIGlmICghd2lkZWFyZ3VtZW50KSB7CisgICAgICAgIFB5T2JqZWN0ICpvX25hbWU7CisKKyAgICAgICAgaWYgKCFQeUFyZ19QYXJzZVR1cGxlQW5kS2V5d29yZHMoYXJncywga3dkcywgImV0fHNpOmZpbGUiLCBrd2xpc3QsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFB5X0ZpbGVTeXN0ZW1EZWZhdWx0RW5jb2RpbmcsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZuYW1lLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmbW9kZSwgJmJ1ZnNpemUpKQorICAgICAgICAgICAgcmV0dXJuIC0xOworCisgICAgICAgIC8qIFdlIHBhcnNlIGFnYWluIHRvIGdldCB0aGUgbmFtZSBhcyBhIFB5T2JqZWN0ICovCisgICAgICAgIGlmICghUHlBcmdfUGFyc2VUdXBsZUFuZEtleXdvcmRzKGFyZ3MsIGt3ZHMsICJPfHNpOmZpbGUiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBrd2xpc3QsICZvX25hbWUsICZtb2RlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmYnVmc2l6ZSkpCisgICAgICAgICAgICBnb3RvIEVycm9yOworCisgICAgICAgIGlmIChmaWxsX2ZpbGVfZmllbGRzKGZvc2VsZiwgTlVMTCwgb19uYW1lLCBtb2RlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmY2xvc2UpID09IE5VTEwpCisgICAgICAgICAgICBnb3RvIEVycm9yOworICAgIH0KKyAgICBpZiAob3Blbl90aGVfZmlsZShmb3NlbGYsIG5hbWUsIG1vZGUpID09IE5VTEwpCisgICAgICAgIGdvdG8gRXJyb3I7CisgICAgZm9zZWxmLT5mX3NldGJ1ZiA9IE5VTEw7CisgICAgUHlGaWxlX1NldEJ1ZlNpemUoc2VsZiwgYnVmc2l6ZSk7CisgICAgZ290byBEb25lOworCitFcnJvcjoKKyAgICByZXQgPSAtMTsKKyAgICAvKiBmYWxsIHRocm91Z2ggKi8KK0RvbmU6CisgICAgUHlNZW1fRnJlZShuYW1lKTsgLyogZnJlZSB0aGUgZW5jb2RlZCBzdHJpbmcgKi8KKyAgICByZXR1cm4gcmV0OworfQorCitQeURvY19WQVIoZmlsZV9kb2MpID0KK1B5RG9jX1NUUigKKyJmaWxlKG5hbWVbLCBtb2RlWywgYnVmZmVyaW5nXV0pIC0+IGZpbGUgb2JqZWN0XG4iCisiXG4iCisiT3BlbiBhIGZpbGUuICBUaGUgbW9kZSBjYW4gYmUgJ3InLCAndycgb3IgJ2EnIGZvciByZWFkaW5nIChkZWZhdWx0KSxcbiIKKyJ3cml0aW5nIG9yIGFwcGVuZGluZy4gIFRoZSBmaWxlIHdpbGwgYmUgY3JlYXRlZCBpZiBpdCBkb2Vzbid0IGV4aXN0XG4iCisid2hlbiBvcGVuZWQgZm9yIHdyaXRpbmcgb3IgYXBwZW5kaW5nOyBpdCB3aWxsIGJlIHRydW5jYXRlZCB3aGVuXG4iCisib3BlbmVkIGZvciB3cml0aW5nLiAgQWRkIGEgJ2InIHRvIHRoZSBtb2RlIGZvciBiaW5hcnkgZmlsZXMuXG4iCisiQWRkIGEgJysnIHRvIHRoZSBtb2RlIHRvIGFsbG93IHNpbXVsdGFuZW91cyByZWFkaW5nIGFuZCB3cml0aW5nLlxuIgorIklmIHRoZSBidWZmZXJpbmcgYXJndW1lbnQgaXMgZ2l2ZW4sIDAgbWVhbnMgdW5idWZmZXJlZCwgMSBtZWFucyBsaW5lXG4iCisiYnVmZmVyZWQsIGFuZCBsYXJnZXIgbnVtYmVycyBzcGVjaWZ5IHRoZSBidWZmZXIgc2l6ZS4gIFRoZSBwcmVmZXJyZWQgd2F5XG4iCisidG8gb3BlbiBhIGZpbGUgaXMgd2l0aCB0aGUgYnVpbHRpbiBvcGVuKCkgZnVuY3Rpb24uXG4iCispCitQeURvY19TVFIoCisiQWRkIGEgJ1UnIHRvIG1vZGUgdG8gb3BlbiB0aGUgZmlsZSBmb3IgaW5wdXQgd2l0aCB1bml2ZXJzYWwgbmV3bGluZVxuIgorInN1cHBvcnQuICBBbnkgbGluZSBlbmRpbmcgaW4gdGhlIGlucHV0IGZpbGUgd2lsbCBiZSBzZWVuIGFzIGEgJ1xcbidcbiIKKyJpbiBQeXRob24uICBBbHNvLCBhIGZpbGUgc28gb3BlbmVkIGdhaW5zIHRoZSBhdHRyaWJ1dGUgJ25ld2xpbmVzJztcbiIKKyJ0aGUgdmFsdWUgZm9yIHRoaXMgYXR0cmlidXRlIGlzIG9uZSBvZiBOb25lIChubyBuZXdsaW5lIHJlYWQgeWV0KSxcbiIKKyInXFxyJywgJ1xcbicsICdcXHJcXG4nIG9yIGEgdHVwbGUgY29udGFpbmluZyBhbGwgdGhlIG5ld2xpbmUgdHlwZXMgc2Vlbi5cbiIKKyJcbiIKKyInVScgY2Fubm90IGJlIGNvbWJpbmVkIHdpdGggJ3cnIG9yICcrJyBtb2RlLlxuIgorKTsKKworUHlUeXBlT2JqZWN0IFB5RmlsZV9UeXBlID0geworICAgIFB5VmFyT2JqZWN0X0hFQURfSU5JVCgmUHlUeXBlX1R5cGUsIDApCisgICAgImZpbGUiLAorICAgIHNpemVvZihQeUZpbGVPYmplY3QpLAorICAgIDAsCisgICAgKGRlc3RydWN0b3IpZmlsZV9kZWFsbG9jLCAgICAgICAgICAgICAgICAgICAvKiB0cF9kZWFsbG9jICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9wcmludCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZ2V0YXR0ciAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfc2V0YXR0ciAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfY29tcGFyZSAqLworICAgIChyZXByZnVuYylmaWxlX3JlcHIsICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfcmVwciAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfYXNfbnVtYmVyICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9hc19zZXF1ZW5jZSAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfYXNfbWFwcGluZyAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfaGFzaCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfY2FsbCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfc3RyICovCisgICAgUHlPYmplY3RfR2VuZXJpY0dldEF0dHIsICAgICAgICAgICAgICAgICAgICAvKiB0cF9nZXRhdHRybyAqLworICAgIC8qIHNvZnRzcGFjZSBpcyB3cml0YWJsZTogIHdlIG11c3Qgc3VwcGx5IHRwX3NldGF0dHJvICovCisgICAgUHlPYmplY3RfR2VuZXJpY1NldEF0dHIsICAgICAgICAgICAgICAgICAgICAvKiB0cF9zZXRhdHRybyAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfYXNfYnVmZmVyICovCisgICAgUHlfVFBGTEFHU19ERUZBVUxUIHwgUHlfVFBGTEFHU19CQVNFVFlQRSB8IFB5X1RQRkxBR1NfSEFWRV9XRUFLUkVGUywgLyogdHBfZmxhZ3MgKi8KKyAgICBmaWxlX2RvYywgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2RvYyAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfdHJhdmVyc2UgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2NsZWFyICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9yaWNoY29tcGFyZSAqLworICAgIG9mZnNldG9mKFB5RmlsZU9iamVjdCwgd2Vha3JlZmxpc3QpLCAgICAgICAgLyogdHBfd2Vha2xpc3RvZmZzZXQgKi8KKyAgICAoZ2V0aXRlcmZ1bmMpZmlsZV9zZWxmLCAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2l0ZXIgKi8KKyAgICAoaXRlcm5leHRmdW5jKWZpbGVfaXRlcm5leHQsICAgICAgICAgICAgICAgIC8qIHRwX2l0ZXJuZXh0ICovCisgICAgZmlsZV9tZXRob2RzLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9tZXRob2RzICovCisgICAgZmlsZV9tZW1iZXJsaXN0LCAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9tZW1iZXJzICovCisgICAgZmlsZV9nZXRzZXRsaXN0LCAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9nZXRzZXQgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2Jhc2UgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2RpY3QgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2Rlc2NyX2dldCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZGVzY3Jfc2V0ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9kaWN0b2Zmc2V0ICovCisgICAgZmlsZV9pbml0LCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9pbml0ICovCisgICAgUHlUeXBlX0dlbmVyaWNBbGxvYywgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9hbGxvYyAqLworICAgIGZpbGVfbmV3LCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfbmV3ICovCisgICAgUHlPYmplY3RfRGVsLCAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2ZyZWUgKi8KK307CisKKy8qIEludGVyZmFjZSBmb3IgdGhlICdzb2Z0IHNwYWNlJyBiZXR3ZWVuIHByaW50IGl0ZW1zLiAqLworCitpbnQKK1B5RmlsZV9Tb2Z0U3BhY2UoUHlPYmplY3QgKmYsIGludCBuZXdmbGFnKQoreworICAgIGxvbmcgb2xkZmxhZyA9IDA7CisgICAgaWYgKGYgPT0gTlVMTCkgeworICAgICAgICAvKiBEbyBub3RoaW5nICovCisgICAgfQorICAgIGVsc2UgaWYgKFB5RmlsZV9DaGVjayhmKSkgeworICAgICAgICBvbGRmbGFnID0gKChQeUZpbGVPYmplY3QgKilmKS0+Zl9zb2Z0c3BhY2U7CisgICAgICAgICgoUHlGaWxlT2JqZWN0ICopZiktPmZfc29mdHNwYWNlID0gbmV3ZmxhZzsKKyAgICB9CisgICAgZWxzZSB7CisgICAgICAgIFB5T2JqZWN0ICp2OworICAgICAgICB2ID0gUHlPYmplY3RfR2V0QXR0clN0cmluZyhmLCAic29mdHNwYWNlIik7CisgICAgICAgIGlmICh2ID09IE5VTEwpCisgICAgICAgICAgICBQeUVycl9DbGVhcigpOworICAgICAgICBlbHNlIHsKKyAgICAgICAgICAgIGlmIChQeUludF9DaGVjayh2KSkKKyAgICAgICAgICAgICAgICBvbGRmbGFnID0gUHlJbnRfQXNMb25nKHYpOworICAgICAgICAgICAgYXNzZXJ0KG9sZGZsYWcgPCBJTlRfTUFYKTsKKyAgICAgICAgICAgIFB5X0RFQ1JFRih2KTsKKyAgICAgICAgfQorICAgICAgICB2ID0gUHlJbnRfRnJvbUxvbmcoKGxvbmcpbmV3ZmxhZyk7CisgICAgICAgIGlmICh2ID09IE5VTEwpCisgICAgICAgICAgICBQeUVycl9DbGVhcigpOworICAgICAgICBlbHNlIHsKKyAgICAgICAgICAgIGlmIChQeU9iamVjdF9TZXRBdHRyU3RyaW5nKGYsICJzb2Z0c3BhY2UiLCB2KSAhPSAwKQorICAgICAgICAgICAgICAgIFB5RXJyX0NsZWFyKCk7CisgICAgICAgICAgICBQeV9ERUNSRUYodik7CisgICAgICAgIH0KKyAgICB9CisgICAgcmV0dXJuIChpbnQpb2xkZmxhZzsKK30KKworLyogSW50ZXJmYWNlcyB0byB3cml0ZSBvYmplY3RzL3N0cmluZ3MgdG8gZmlsZS1saWtlIG9iamVjdHMgKi8KKworaW50CitQeUZpbGVfV3JpdGVPYmplY3QoUHlPYmplY3QgKnYsIFB5T2JqZWN0ICpmLCBpbnQgZmxhZ3MpCit7CisgICAgUHlPYmplY3QgKndyaXRlciwgKnZhbHVlLCAqYXJncywgKnJlc3VsdDsKKyAgICBpZiAoZiA9PSBOVUxMKSB7CisgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19UeXBlRXJyb3IsICJ3cml0ZW9iamVjdCB3aXRoIE5VTEwgZmlsZSIpOworICAgICAgICByZXR1cm4gLTE7CisgICAgfQorICAgIGVsc2UgaWYgKFB5RmlsZV9DaGVjayhmKSkgeworICAgICAgICBQeUZpbGVPYmplY3QgKmZvYmogPSAoUHlGaWxlT2JqZWN0ICopIGY7CisjaWZkZWYgUHlfVVNJTkdfVU5JQ09ERQorICAgICAgICBQeU9iamVjdCAqZW5jID0gZm9iai0+Zl9lbmNvZGluZzsKKyAgICAgICAgaW50IHJlc3VsdDsKKyNlbmRpZgorICAgICAgICBpZiAoZm9iai0+Zl9mcCA9PSBOVUxMKSB7CisgICAgICAgICAgICBlcnJfY2xvc2VkKCk7CisgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgIH0KKyNpZmRlZiBQeV9VU0lOR19VTklDT0RFCisgICAgICAgIGlmICgoZmxhZ3MgJiBQeV9QUklOVF9SQVcpICYmCisgICAgICAgICAgICBQeVVuaWNvZGVfQ2hlY2sodikgJiYgZW5jICE9IFB5X05vbmUpIHsKKyAgICAgICAgICAgIGNoYXIgKmNlbmMgPSBQeVN0cmluZ19BU19TVFJJTkcoZW5jKTsKKyAgICAgICAgICAgIGNoYXIgKmVycm9ycyA9IGZvYmotPmZfZXJyb3JzID09IFB5X05vbmUgPworICAgICAgICAgICAgICAic3RyaWN0IiA6IFB5U3RyaW5nX0FTX1NUUklORyhmb2JqLT5mX2Vycm9ycyk7CisgICAgICAgICAgICB2YWx1ZSA9IFB5VW5pY29kZV9Bc0VuY29kZWRTdHJpbmcodiwgY2VuYywgZXJyb3JzKTsKKyAgICAgICAgICAgIGlmICh2YWx1ZSA9PSBOVUxMKQorICAgICAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIHZhbHVlID0gdjsKKyAgICAgICAgICAgIFB5X0lOQ1JFRih2YWx1ZSk7CisgICAgICAgIH0KKyAgICAgICAgcmVzdWx0ID0gZmlsZV9QeU9iamVjdF9QcmludCh2YWx1ZSwgZm9iaiwgZmxhZ3MpOworICAgICAgICBQeV9ERUNSRUYodmFsdWUpOworICAgICAgICByZXR1cm4gcmVzdWx0OworI2Vsc2UKKyAgICAgICAgcmV0dXJuIGZpbGVfUHlPYmplY3RfUHJpbnQodiwgZm9iaiwgZmxhZ3MpOworI2VuZGlmCisgICAgfQorICAgIHdyaXRlciA9IFB5T2JqZWN0X0dldEF0dHJTdHJpbmcoZiwgIndyaXRlIik7CisgICAgaWYgKHdyaXRlciA9PSBOVUxMKQorICAgICAgICByZXR1cm4gLTE7CisgICAgaWYgKGZsYWdzICYgUHlfUFJJTlRfUkFXKSB7CisgICAgICAgIGlmIChQeVVuaWNvZGVfQ2hlY2sodikpIHsKKyAgICAgICAgICAgIHZhbHVlID0gdjsKKyAgICAgICAgICAgIFB5X0lOQ1JFRih2YWx1ZSk7CisgICAgICAgIH0gZWxzZQorICAgICAgICAgICAgdmFsdWUgPSBQeU9iamVjdF9TdHIodik7CisgICAgfQorICAgIGVsc2UKKyAgICAgICAgdmFsdWUgPSBQeU9iamVjdF9SZXByKHYpOworICAgIGlmICh2YWx1ZSA9PSBOVUxMKSB7CisgICAgICAgIFB5X0RFQ1JFRih3cml0ZXIpOworICAgICAgICByZXR1cm4gLTE7CisgICAgfQorICAgIGFyZ3MgPSBQeVR1cGxlX1BhY2soMSwgdmFsdWUpOworICAgIGlmIChhcmdzID09IE5VTEwpIHsKKyAgICAgICAgUHlfREVDUkVGKHZhbHVlKTsKKyAgICAgICAgUHlfREVDUkVGKHdyaXRlcik7CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisgICAgcmVzdWx0ID0gUHlFdmFsX0NhbGxPYmplY3Qod3JpdGVyLCBhcmdzKTsKKyAgICBQeV9ERUNSRUYoYXJncyk7CisgICAgUHlfREVDUkVGKHZhbHVlKTsKKyAgICBQeV9ERUNSRUYod3JpdGVyKTsKKyAgICBpZiAocmVzdWx0ID09IE5VTEwpCisgICAgICAgIHJldHVybiAtMTsKKyAgICBQeV9ERUNSRUYocmVzdWx0KTsKKyAgICByZXR1cm4gMDsKK30KKworaW50CitQeUZpbGVfV3JpdGVTdHJpbmcoY29uc3QgY2hhciAqcywgUHlPYmplY3QgKmYpCit7CisKKyAgICBpZiAoZiA9PSBOVUxMKSB7CisgICAgICAgIC8qIFNob3VsZCBiZSBjYXVzZWQgYnkgYSBwcmUtZXhpc3RpbmcgZXJyb3IgKi8KKyAgICAgICAgaWYgKCFQeUVycl9PY2N1cnJlZCgpKQorICAgICAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1N5c3RlbUVycm9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICJudWxsIGZpbGUgZm9yIFB5RmlsZV9Xcml0ZVN0cmluZyIpOworICAgICAgICByZXR1cm4gLTE7CisgICAgfQorICAgIGVsc2UgaWYgKFB5RmlsZV9DaGVjayhmKSkgeworICAgICAgICBQeUZpbGVPYmplY3QgKmZvYmogPSAoUHlGaWxlT2JqZWN0ICopIGY7CisgICAgICAgIEZJTEUgKmZwID0gUHlGaWxlX0FzRmlsZShmKTsKKyAgICAgICAgaWYgKGZwID09IE5VTEwpIHsKKyAgICAgICAgICAgIGVycl9jbG9zZWQoKTsKKyAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgfQorICAgICAgICBGSUxFX0JFR0lOX0FMTE9XX1RIUkVBRFMoZm9iaikKKyAgICAgICAgZnB1dHMocywgZnApOworICAgICAgICBGSUxFX0VORF9BTExPV19USFJFQURTKGZvYmopCisgICAgICAgIHJldHVybiAwOworICAgIH0KKyAgICBlbHNlIGlmICghUHlFcnJfT2NjdXJyZWQoKSkgeworICAgICAgICBQeU9iamVjdCAqdiA9IFB5U3RyaW5nX0Zyb21TdHJpbmcocyk7CisgICAgICAgIGludCBlcnI7CisgICAgICAgIGlmICh2ID09IE5VTEwpCisgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgIGVyciA9IFB5RmlsZV9Xcml0ZU9iamVjdCh2LCBmLCBQeV9QUklOVF9SQVcpOworICAgICAgICBQeV9ERUNSRUYodik7CisgICAgICAgIHJldHVybiBlcnI7CisgICAgfQorICAgIGVsc2UKKyAgICAgICAgcmV0dXJuIC0xOworfQorCisvKiBUcnkgdG8gZ2V0IGEgZmlsZS1kZXNjcmlwdG9yIGZyb20gYSBQeXRob24gb2JqZWN0LiAgSWYgdGhlIG9iamVjdAorICAgaXMgYW4gaW50ZWdlciBvciBsb25nIGludGVnZXIsIGl0cyB2YWx1ZSBpcyByZXR1cm5lZC4gIElmIG5vdCwgdGhlCisgICBvYmplY3QncyBmaWxlbm8oKSBtZXRob2QgaXMgY2FsbGVkIGlmIGl0IGV4aXN0czsgdGhlIG1ldGhvZCBtdXN0IHJldHVybgorICAgYW4gaW50ZWdlciBvciBsb25nIGludGVnZXIsIHdoaWNoIGlzIHJldHVybmVkIGFzIHRoZSBmaWxlIGRlc2NyaXB0b3IgdmFsdWUuCisgICAtMSBpcyByZXR1cm5lZCBvbiBmYWlsdXJlLgorKi8KKworaW50IFB5T2JqZWN0X0FzRmlsZURlc2NyaXB0b3IoUHlPYmplY3QgKm8pCit7CisgICAgaW50IGZkOworICAgIFB5T2JqZWN0ICptZXRoOworCisgICAgaWYgKFB5SW50X0NoZWNrKG8pKSB7CisgICAgICAgIGZkID0gX1B5SW50X0FzSW50KG8pOworICAgIH0KKyAgICBlbHNlIGlmIChQeUxvbmdfQ2hlY2sobykpIHsKKyAgICAgICAgZmQgPSBfUHlMb25nX0FzSW50KG8pOworICAgIH0KKyAgICBlbHNlIGlmICgobWV0aCA9IFB5T2JqZWN0X0dldEF0dHJTdHJpbmcobywgImZpbGVubyIpKSAhPSBOVUxMKQorICAgIHsKKyAgICAgICAgUHlPYmplY3QgKmZubyA9IFB5RXZhbF9DYWxsT2JqZWN0KG1ldGgsIE5VTEwpOworICAgICAgICBQeV9ERUNSRUYobWV0aCk7CisgICAgICAgIGlmIChmbm8gPT0gTlVMTCkKKyAgICAgICAgICAgIHJldHVybiAtMTsKKworICAgICAgICBpZiAoUHlJbnRfQ2hlY2soZm5vKSkgeworICAgICAgICAgICAgZmQgPSBfUHlJbnRfQXNJbnQoZm5vKTsKKyAgICAgICAgICAgIFB5X0RFQ1JFRihmbm8pOworICAgICAgICB9CisgICAgICAgIGVsc2UgaWYgKFB5TG9uZ19DaGVjayhmbm8pKSB7CisgICAgICAgICAgICBmZCA9IF9QeUxvbmdfQXNJbnQoZm5vKTsKKyAgICAgICAgICAgIFB5X0RFQ1JFRihmbm8pOworICAgICAgICB9CisgICAgICAgIGVsc2UgeworICAgICAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1R5cGVFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZmlsZW5vKCkgcmV0dXJuZWQgYSBub24taW50ZWdlciIpOworICAgICAgICAgICAgUHlfREVDUkVGKGZubyk7CisgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgIH0KKyAgICB9CisgICAgZWxzZSB7CisgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19UeXBlRXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAgICAiYXJndW1lbnQgbXVzdCBiZSBhbiBpbnQsIG9yIGhhdmUgYSBmaWxlbm8oKSBtZXRob2QuIik7CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisKKyAgICBpZiAoZmQgPCAwKSB7CisgICAgICAgIFB5RXJyX0Zvcm1hdChQeUV4Y19WYWx1ZUVycm9yLAorICAgICAgICAgICAgICAgICAgICAgImZpbGUgZGVzY3JpcHRvciBjYW5ub3QgYmUgYSBuZWdhdGl2ZSBpbnRlZ2VyICglaSkiLAorICAgICAgICAgICAgICAgICAgICAgZmQpOworICAgICAgICByZXR1cm4gLTE7CisgICAgfQorICAgIHJldHVybiBmZDsKK30KKworLyogRnJvbSBoZXJlIG9uIHdlIG5lZWQgYWNjZXNzIHRvIHRoZSByZWFsIGZnZXRzIGFuZCBmcmVhZCAqLworI3VuZGVmIGZnZXRzCisjdW5kZWYgZnJlYWQKKworLyoKKyoqIFB5X1VuaXZlcnNhbE5ld2xpbmVGZ2V0cyBpcyBhbiBmZ2V0cyB2YXJpYXRpb24gdGhhdCB1bmRlcnN0YW5kcworKiogYWxsIG9mIFxyLCBcbiBhbmQgXHJcbiBjb252ZW50aW9ucy4KKyoqIFRoZSBzdHJlYW0gc2hvdWxkIGJlIG9wZW5lZCBpbiBiaW5hcnkgbW9kZS4KKyoqIElmIGZvYmogaXMgTlVMTCB0aGUgcm91dGluZSBhbHdheXMgZG9lcyBuZXdsaW5lIGNvbnZlcnNpb24sIGFuZAorKiogaXQgbWF5IHBlZWsgb25lIGNoYXIgYWhlYWQgdG8gZ29iYmxlIHRoZSBzZWNvbmQgY2hhciBpbiBcclxuLgorKiogSWYgZm9iaiBpcyBub24tTlVMTCBpdCBtdXN0IGJlIGEgUHlGaWxlT2JqZWN0LiBJbiB0aGlzIGNhc2UgdGhlcmUKKyoqIGlzIG5vIHJlYWRhaGVhZCBidXQgaW4gc3RlYWQgYSBmbGFnIGlzIHVzZWQgdG8gc2tpcCBhIGZvbGxvd2luZworKiogXG4gb24gdGhlIG5leHQgcmVhZC4gQWxzbywgaWYgdGhlIGZpbGUgaXMgb3BlbiBpbiBiaW5hcnkgbW9kZQorKiogdGhlIHdob2xlIGNvbnZlcnNpb24gaXMgc2tpcHBlZC4gRmluYWxseSwgdGhlIHJvdXRpbmUga2VlcHMgdHJhY2sgb2YKKyoqIHRoZSBkaWZmZXJlbnQgdHlwZXMgb2YgbmV3bGluZXMgc2Vlbi4KKyoqIE5vdGUgdGhhdCB3ZSBuZWVkIG5vIGVycm9yIGhhbmRsaW5nOiBmZ2V0cygpIHRyZWF0cyBlcnJvciBhbmQgZW9mCisqKiBpZGVudGljYWxseS4KKyovCitjaGFyICoKK1B5X1VuaXZlcnNhbE5ld2xpbmVGZ2V0cyhjaGFyICpidWYsIGludCBuLCBGSUxFICpzdHJlYW0sIFB5T2JqZWN0ICpmb2JqKQoreworICAgIGNoYXIgKnAgPSBidWY7CisgICAgaW50IGM7CisgICAgaW50IG5ld2xpbmV0eXBlcyA9IDA7CisgICAgaW50IHNraXBuZXh0bGYgPSAwOworICAgIGludCB1bml2X25ld2xpbmUgPSAxOworCisgICAgaWYgKGZvYmopIHsKKyAgICAgICAgaWYgKCFQeUZpbGVfQ2hlY2soZm9iaikpIHsKKyAgICAgICAgICAgIGVycm5vID0gRU5YSU87ICAgICAgICAgICAgICAvKiBXaGF0IGNhbiB5b3UgZG8uLi4gKi8KKyAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgICAgICB9CisgICAgICAgIHVuaXZfbmV3bGluZSA9ICgoUHlGaWxlT2JqZWN0ICopZm9iaiktPmZfdW5pdl9uZXdsaW5lOworICAgICAgICBpZiAoICF1bml2X25ld2xpbmUgKQorICAgICAgICAgICAgcmV0dXJuIGZnZXRzKGJ1Ziwgbiwgc3RyZWFtKTsKKyAgICAgICAgbmV3bGluZXR5cGVzID0gKChQeUZpbGVPYmplY3QgKilmb2JqKS0+Zl9uZXdsaW5ldHlwZXM7CisgICAgICAgIHNraXBuZXh0bGYgPSAoKFB5RmlsZU9iamVjdCAqKWZvYmopLT5mX3NraXBuZXh0bGY7CisgICAgfQorICAgIEZMT0NLRklMRShzdHJlYW0pOworICAgIGMgPSAneCc7IC8qIFNodXQgdXAgZ2NjIHdhcm5pbmcgKi8KKyAgICB3aGlsZSAoLS1uID4gMCAmJiAoYyA9IEdFVEMoc3RyZWFtKSkgIT0gRU9GICkgeworICAgICAgICBpZiAoc2tpcG5leHRsZiApIHsKKyAgICAgICAgICAgIHNraXBuZXh0bGYgPSAwOworICAgICAgICAgICAgaWYgKGMgPT0gJ1xuJykgeworICAgICAgICAgICAgICAgIC8qIFNlZWluZyBhIFxuIGhlcmUgd2l0aCBza2lwbmV4dGxmIHRydWUKKyAgICAgICAgICAgICAgICAqKiBtZWFucyB3ZSBzYXcgYSBcciBiZWZvcmUuCisgICAgICAgICAgICAgICAgKi8KKyAgICAgICAgICAgICAgICBuZXdsaW5ldHlwZXMgfD0gTkVXTElORV9DUkxGOworICAgICAgICAgICAgICAgIGMgPSBHRVRDKHN0cmVhbSk7CisgICAgICAgICAgICAgICAgaWYgKGMgPT0gRU9GKSBicmVhazsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgLyoKKyAgICAgICAgICAgICAgICAqKiBOb3RlIHRoYXQgYyA9PSBFT0YgYWxzbyBicmluZ3MgdXMgaGVyZSwKKyAgICAgICAgICAgICAgICAqKiBzbyB3ZSdyZSBva2F5IGlmIHRoZSBsYXN0IGNoYXIgaW4gdGhlIGZpbGUKKyAgICAgICAgICAgICAgICAqKiBpcyBhIENSLgorICAgICAgICAgICAgICAgICovCisgICAgICAgICAgICAgICAgbmV3bGluZXR5cGVzIHw9IE5FV0xJTkVfQ1I7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgaWYgKGMgPT0gJ1xyJykgeworICAgICAgICAgICAgLyogQSBcciBpcyB0cmFuc2xhdGVkIGludG8gYSBcbiwgYW5kIHdlIHNraXAKKyAgICAgICAgICAgICoqIGFuIGFkamFjZW50IFxuLCBpZiBhbnkuIFdlIGRvbid0IHNldCB0aGUKKyAgICAgICAgICAgICoqIG5ld2xpbmV0eXBlcyBmbGFnIHVudGlsIHdlJ3ZlIHNlZW4gdGhlIG5leHQgY2hhci4KKyAgICAgICAgICAgICovCisgICAgICAgICAgICBza2lwbmV4dGxmID0gMTsKKyAgICAgICAgICAgIGMgPSAnXG4nOworICAgICAgICB9IGVsc2UgaWYgKCBjID09ICdcbicpIHsKKyAgICAgICAgICAgIG5ld2xpbmV0eXBlcyB8PSBORVdMSU5FX0xGOworICAgICAgICB9CisgICAgICAgICpwKysgPSBjOworICAgICAgICBpZiAoYyA9PSAnXG4nKSBicmVhazsKKyAgICB9CisgICAgaWYgKCBjID09IEVPRiAmJiBza2lwbmV4dGxmICkKKyAgICAgICAgbmV3bGluZXR5cGVzIHw9IE5FV0xJTkVfQ1I7CisgICAgRlVOTE9DS0ZJTEUoc3RyZWFtKTsKKyAgICAqcCA9ICdcMCc7CisgICAgaWYgKGZvYmopIHsKKyAgICAgICAgKChQeUZpbGVPYmplY3QgKilmb2JqKS0+Zl9uZXdsaW5ldHlwZXMgPSBuZXdsaW5ldHlwZXM7CisgICAgICAgICgoUHlGaWxlT2JqZWN0ICopZm9iaiktPmZfc2tpcG5leHRsZiA9IHNraXBuZXh0bGY7CisgICAgfSBlbHNlIGlmICggc2tpcG5leHRsZiApIHsKKyAgICAgICAgLyogSWYgd2UgaGF2ZSBubyBmaWxlIG9iamVjdCB3ZSBjYW5ub3Qgc2F2ZSB0aGUKKyAgICAgICAgKiogc2tpcG5leHRsZiBmbGFnLiBXZSBoYXZlIHRvIHJlYWRhaGVhZCwgd2hpY2gKKyAgICAgICAgKiogd2lsbCBjYXVzZSBhIHBhdXNlIGlmIHdlJ3JlIHJlYWRpbmcgZnJvbSBhbgorICAgICAgICAqKiBpbnRlcmFjdGl2ZSBzdHJlYW0sIGJ1dCB0aGF0IGlzIHZlcnkgdW5saWtlbHkKKyAgICAgICAgKiogdW5sZXNzIHdlJ3JlIGRvaW5nIHNvbWV0aGluZyBzaWxseSBsaWtlCisgICAgICAgICoqIGV4ZWNmaWxlKCIvZGV2L3R0eSIpLgorICAgICAgICAqLworICAgICAgICBjID0gR0VUQyhzdHJlYW0pOworICAgICAgICBpZiAoIGMgIT0gJ1xuJyApCisgICAgICAgICAgICB1bmdldGMoYywgc3RyZWFtKTsKKyAgICB9CisgICAgaWYgKHAgPT0gYnVmKQorICAgICAgICByZXR1cm4gTlVMTDsKKyAgICByZXR1cm4gYnVmOworfQorCisvKgorKiogUHlfVW5pdmVyc2FsTmV3bGluZUZyZWFkIGlzIGFuIGZyZWFkIHZhcmlhdGlvbiB0aGF0IHVuZGVyc3RhbmRzCisqKiBhbGwgb2YgXHIsIFxuIGFuZCBcclxuIGNvbnZlbnRpb25zLgorKiogVGhlIHN0cmVhbSBzaG91bGQgYmUgb3BlbmVkIGluIGJpbmFyeSBtb2RlLgorKiogZm9iaiBtdXN0IGJlIGEgUHlGaWxlT2JqZWN0LiBJbiB0aGlzIGNhc2UgdGhlcmUKKyoqIGlzIG5vIHJlYWRhaGVhZCBidXQgaW4gc3RlYWQgYSBmbGFnIGlzIHVzZWQgdG8gc2tpcCBhIGZvbGxvd2luZworKiogXG4gb24gdGhlIG5leHQgcmVhZC4gQWxzbywgaWYgdGhlIGZpbGUgaXMgb3BlbiBpbiBiaW5hcnkgbW9kZQorKiogdGhlIHdob2xlIGNvbnZlcnNpb24gaXMgc2tpcHBlZC4gRmluYWxseSwgdGhlIHJvdXRpbmUga2VlcHMgdHJhY2sgb2YKKyoqIHRoZSBkaWZmZXJlbnQgdHlwZXMgb2YgbmV3bGluZXMgc2Vlbi4KKyovCitzaXplX3QKK1B5X1VuaXZlcnNhbE5ld2xpbmVGcmVhZChjaGFyICpidWYsIHNpemVfdCBuLAorICAgICAgICAgICAgICAgICAgICAgICAgIEZJTEUgKnN0cmVhbSwgUHlPYmplY3QgKmZvYmopCit7CisgICAgY2hhciAqZHN0ID0gYnVmOworICAgIFB5RmlsZU9iamVjdCAqZiA9IChQeUZpbGVPYmplY3QgKilmb2JqOworICAgIGludCBuZXdsaW5ldHlwZXMsIHNraXBuZXh0bGY7CisKKyAgICBhc3NlcnQoYnVmICE9IE5VTEwpOworICAgIGFzc2VydChzdHJlYW0gIT0gTlVMTCk7CisKKyAgICBpZiAoIWZvYmogfHwgIVB5RmlsZV9DaGVjayhmb2JqKSkgeworICAgICAgICBlcnJubyA9IEVOWElPOyAgICAgICAgICAvKiBXaGF0IGNhbiB5b3UgZG8uLi4gKi8KKyAgICAgICAgcmV0dXJuIDA7CisgICAgfQorICAgIGlmICghZi0+Zl91bml2X25ld2xpbmUpCisgICAgICAgIHJldHVybiBmcmVhZChidWYsIDEsIG4sIHN0cmVhbSk7CisgICAgbmV3bGluZXR5cGVzID0gZi0+Zl9uZXdsaW5ldHlwZXM7CisgICAgc2tpcG5leHRsZiA9IGYtPmZfc2tpcG5leHRsZjsKKyAgICAvKiBJbnZhcmlhbnQ6ICBuIGlzIHRoZSBudW1iZXIgb2YgYnl0ZXMgcmVtYWluaW5nIHRvIGJlIGZpbGxlZAorICAgICAqIGluIHRoZSBidWZmZXIuCisgICAgICovCisgICAgd2hpbGUgKG4pIHsKKyAgICAgICAgc2l6ZV90IG5yZWFkOworICAgICAgICBpbnQgc2hvcnRyZWFkOworICAgICAgICBjaGFyICpzcmMgPSBkc3Q7CisKKyAgICAgICAgbnJlYWQgPSBmcmVhZChkc3QsIDEsIG4sIHN0cmVhbSk7CisgICAgICAgIGFzc2VydChucmVhZCA8PSBuKTsKKyAgICAgICAgaWYgKG5yZWFkID09IDApCisgICAgICAgICAgICBicmVhazsKKworICAgICAgICBuIC09IG5yZWFkOyAvKiBhc3N1bWluZyAxIGJ5dGUgb3V0IGZvciBlYWNoIGluOyB3aWxsIGFkanVzdCAqLworICAgICAgICBzaG9ydHJlYWQgPSBuICE9IDA7ICAgICAgICAgICAgIC8qIHRydWUgaWZmIEVPRiBvciBlcnJvciAqLworICAgICAgICB3aGlsZSAobnJlYWQtLSkgeworICAgICAgICAgICAgY2hhciBjID0gKnNyYysrOworICAgICAgICAgICAgaWYgKGMgPT0gJ1xyJykgeworICAgICAgICAgICAgICAgIC8qIFNhdmUgYXMgTEYgYW5kIHNldCBmbGFnIHRvIHNraXAgbmV4dCBMRi4gKi8KKyAgICAgICAgICAgICAgICAqZHN0KysgPSAnXG4nOworICAgICAgICAgICAgICAgIHNraXBuZXh0bGYgPSAxOworICAgICAgICAgICAgfQorICAgICAgICAgICAgZWxzZSBpZiAoc2tpcG5leHRsZiAmJiBjID09ICdcbicpIHsKKyAgICAgICAgICAgICAgICAvKiBTa2lwIExGLCBhbmQgcmVtZW1iZXIgd2Ugc2F3IENSIExGLiAqLworICAgICAgICAgICAgICAgIHNraXBuZXh0bGYgPSAwOworICAgICAgICAgICAgICAgIG5ld2xpbmV0eXBlcyB8PSBORVdMSU5FX0NSTEY7CisgICAgICAgICAgICAgICAgKytuOworICAgICAgICAgICAgfQorICAgICAgICAgICAgZWxzZSB7CisgICAgICAgICAgICAgICAgLyogTm9ybWFsIGNoYXIgdG8gYmUgc3RvcmVkIGluIGJ1ZmZlci4gIEFsc28KKyAgICAgICAgICAgICAgICAgKiB1cGRhdGUgdGhlIG5ld2xpbmV0eXBlcyBmbGFnIGlmIGVpdGhlciB0aGlzCisgICAgICAgICAgICAgICAgICogaXMgYW4gTEYgb3IgdGhlIHByZXZpb3VzIGNoYXIgd2FzIGEgQ1IuCisgICAgICAgICAgICAgICAgICovCisgICAgICAgICAgICAgICAgaWYgKGMgPT0gJ1xuJykKKyAgICAgICAgICAgICAgICAgICAgbmV3bGluZXR5cGVzIHw9IE5FV0xJTkVfTEY7CisgICAgICAgICAgICAgICAgZWxzZSBpZiAoc2tpcG5leHRsZikKKyAgICAgICAgICAgICAgICAgICAgbmV3bGluZXR5cGVzIHw9IE5FV0xJTkVfQ1I7CisgICAgICAgICAgICAgICAgKmRzdCsrID0gYzsKKyAgICAgICAgICAgICAgICBza2lwbmV4dGxmID0gMDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBpZiAoc2hvcnRyZWFkKSB7CisgICAgICAgICAgICAvKiBJZiB0aGlzIGlzIEVPRiwgdXBkYXRlIHR5cGUgZmxhZ3MuICovCisgICAgICAgICAgICBpZiAoc2tpcG5leHRsZiAmJiBmZW9mKHN0cmVhbSkpCisgICAgICAgICAgICAgICAgbmV3bGluZXR5cGVzIHw9IE5FV0xJTkVfQ1I7CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgfQorICAgIH0KKyAgICBmLT5mX25ld2xpbmV0eXBlcyA9IG5ld2xpbmV0eXBlczsKKyAgICBmLT5mX3NraXBuZXh0bGYgPSBza2lwbmV4dGxmOworICAgIHJldHVybiBkc3QgLSBidWY7Cit9CisKKyNpZmRlZiBfX2NwbHVzcGx1cworfQorI2VuZGlmCmRpZmYgLS1naXQgYS9QeXRob24tMi43LjUvT2JqZWN0cy9mbG9hdG9iamVjdC5jIGIvUHl0aG9uLTIuNy41L09iamVjdHMvZmxvYXRvYmplY3QuYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iYTg2N2VmCi0tLSAvZGV2L251bGwKKysrIGIvUHl0aG9uLTIuNy41L09iamVjdHMvZmxvYXRvYmplY3QuYwpAQCAtMCwwICsxLDI3MDcgQEAKKworLyogRmxvYXQgb2JqZWN0IGltcGxlbWVudGF0aW9uICovCisKKy8qIFhYWCBUaGVyZSBzaG91bGQgYmUgb3ZlcmZsb3cgY2hlY2tzIGhlcmUsIGJ1dCBpdCdzIGhhcmQgdG8gY2hlY2sKKyAgIGZvciBhbnkga2luZCBvZiBmbG9hdCBleGNlcHRpb24gd2l0aG91dCBsb3NpbmcgcG9ydGFiaWxpdHkuICovCisKKyNpbmNsdWRlICJQeXRob24uaCIKKyNpbmNsdWRlICJzdHJ1Y3RzZXEuaCIKKworI2luY2x1ZGUgPGN0eXBlLmg+CisjaW5jbHVkZSA8ZmxvYXQuaD4KKworI3VuZGVmIE1BWAorI3VuZGVmIE1JTgorI2RlZmluZSBNQVgoeCwgeSkgKCh4KSA8ICh5KSA/ICh5KSA6ICh4KSkKKyNkZWZpbmUgTUlOKHgsIHkpICgoeCkgPCAoeSkgPyAoeCkgOiAoeSkpCisKKyNpZmRlZiBfT1NGX1NPVVJDRQorLyogT1NGMSA1LjEgZG9lc24ndCBtYWtlIHRoaXMgYXZhaWxhYmxlIHdpdGggWE9QRU5fU09VUkNFX0VYVEVOREVEIGRlZmluZWQgKi8KK2V4dGVybiBpbnQgZmluaXRlKGRvdWJsZSk7CisjZW5kaWYKKworLyogU3BlY2lhbCBmcmVlIGxpc3QgLS0gc2VlIGNvbW1lbnRzIGZvciBzYW1lIGNvZGUgaW4gaW50b2JqZWN0LmMuICovCisjZGVmaW5lIEJMT0NLX1NJWkUgICAgICAxMDAwICAgIC8qIDFLIGxlc3MgdHlwaWNhbCBtYWxsb2Mgb3ZlcmhlYWQgKi8KKyNkZWZpbmUgQkhFQURfU0laRSAgICAgIDggICAgICAgLyogRW5vdWdoIGZvciBhIDY0LWJpdCBwb2ludGVyICovCisjZGVmaW5lIE5fRkxPQVRPQkpFQ1RTICAoKEJMT0NLX1NJWkUgLSBCSEVBRF9TSVpFKSAvIHNpemVvZihQeUZsb2F0T2JqZWN0KSkKKworc3RydWN0IF9mbG9hdGJsb2NrIHsKKyAgICBzdHJ1Y3QgX2Zsb2F0YmxvY2sgKm5leHQ7CisgICAgUHlGbG9hdE9iamVjdCBvYmplY3RzW05fRkxPQVRPQkpFQ1RTXTsKK307CisKK3R5cGVkZWYgc3RydWN0IF9mbG9hdGJsb2NrIFB5RmxvYXRCbG9jazsKKworc3RhdGljIFB5RmxvYXRCbG9jayAqYmxvY2tfbGlzdCA9IE5VTEw7CitzdGF0aWMgUHlGbG9hdE9iamVjdCAqZnJlZV9saXN0ID0gTlVMTDsKKworc3RhdGljIFB5RmxvYXRPYmplY3QgKgorZmlsbF9mcmVlX2xpc3Qodm9pZCkKK3sKKyAgICBQeUZsb2F0T2JqZWN0ICpwLCAqcTsKKyAgICAvKiBYWFggRmxvYXQgYmxvY2tzIGVzY2FwZSB0aGUgb2JqZWN0IGhlYXAuIFVzZSBQeU9iamVjdF9NQUxMT0MgPz8/ICovCisgICAgcCA9IChQeUZsb2F0T2JqZWN0ICopIFB5TWVtX01BTExPQyhzaXplb2YoUHlGbG9hdEJsb2NrKSk7CisgICAgaWYgKHAgPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIChQeUZsb2F0T2JqZWN0ICopIFB5RXJyX05vTWVtb3J5KCk7CisgICAgKChQeUZsb2F0QmxvY2sgKilwKS0+bmV4dCA9IGJsb2NrX2xpc3Q7CisgICAgYmxvY2tfbGlzdCA9IChQeUZsb2F0QmxvY2sgKilwOworICAgIHAgPSAmKChQeUZsb2F0QmxvY2sgKilwKS0+b2JqZWN0c1swXTsKKyAgICBxID0gcCArIE5fRkxPQVRPQkpFQ1RTOworICAgIHdoaWxlICgtLXEgPiBwKQorICAgICAgICBQeV9UWVBFKHEpID0gKHN0cnVjdCBfdHlwZW9iamVjdCAqKShxLTEpOworICAgIFB5X1RZUEUocSkgPSBOVUxMOworICAgIHJldHVybiBwICsgTl9GTE9BVE9CSkVDVFMgLSAxOworfQorCitkb3VibGUKK1B5RmxvYXRfR2V0TWF4KHZvaWQpCit7CisgICAgcmV0dXJuIERCTF9NQVg7Cit9CisKK2RvdWJsZQorUHlGbG9hdF9HZXRNaW4odm9pZCkKK3sKKyAgICByZXR1cm4gREJMX01JTjsKK30KKworc3RhdGljIFB5VHlwZU9iamVjdCBGbG9hdEluZm9UeXBlID0gezAsIDAsIDAsIDAsIDAsIDB9OworCitQeURvY19TVFJWQVIoZmxvYXRpbmZvX19kb2NfXywKKyJzeXMuZmxvYXRfaW5mb1xuXAorXG5cCitBIHN0cnVjdHNlcSBob2xkaW5nIGluZm9ybWF0aW9uIGFib3V0IHRoZSBmbG9hdCB0eXBlLiBJdCBjb250YWlucyBsb3cgbGV2ZWxcblwKK2luZm9ybWF0aW9uIGFib3V0IHRoZSBwcmVjaXNpb24gYW5kIGludGVybmFsIHJlcHJlc2VudGF0aW9uLiBQbGVhc2Ugc3R1ZHlcblwKK3lvdXIgc3lzdGVtJ3MgOmZpbGU6YGZsb2F0LmhgIGZvciBtb3JlIGluZm9ybWF0aW9uLiIpOworCitzdGF0aWMgUHlTdHJ1Y3RTZXF1ZW5jZV9GaWVsZCBmbG9hdGluZm9fZmllbGRzW10gPSB7CisgICAgeyJtYXgiLCAgICAgICAgICAgICAiREJMX01BWCAtLSBtYXhpbXVtIHJlcHJlc2VudGFibGUgZmluaXRlIGZsb2F0In0sCisgICAgeyJtYXhfZXhwIiwgICAgICAgICAiREJMX01BWF9FWFAgLS0gbWF4aW11bSBpbnQgZSBzdWNoIHRoYXQgcmFkaXgqKihlLTEpICIKKyAgICAgICAgICAgICAgICAgICAgImlzIHJlcHJlc2VudGFibGUifSwKKyAgICB7Im1heF8xMF9leHAiLCAgICAgICJEQkxfTUFYXzEwX0VYUCAtLSBtYXhpbXVtIGludCBlIHN1Y2ggdGhhdCAxMCoqZSAiCisgICAgICAgICAgICAgICAgICAgICJpcyByZXByZXNlbnRhYmxlIn0sCisgICAgeyJtaW4iLCAgICAgICAgICAgICAiREJMX01JTiAtLSBNaW5pbXVtIHBvc2l0aXZlIG5vcm1hbGl6ZXIgZmxvYXQifSwKKyAgICB7Im1pbl9leHAiLCAgICAgICAgICJEQkxfTUlOX0VYUCAtLSBtaW5pbXVtIGludCBlIHN1Y2ggdGhhdCByYWRpeCoqKGUtMSkgIgorICAgICAgICAgICAgICAgICAgICAiaXMgYSBub3JtYWxpemVkIGZsb2F0In0sCisgICAgeyJtaW5fMTBfZXhwIiwgICAgICAiREJMX01JTl8xMF9FWFAgLS0gbWluaW11bSBpbnQgZSBzdWNoIHRoYXQgMTAqKmUgaXMgIgorICAgICAgICAgICAgICAgICAgICAiYSBub3JtYWxpemVkIn0sCisgICAgeyJkaWciLCAgICAgICAgICAgICAiREJMX0RJRyAtLSBkaWdpdHMifSwKKyAgICB7Im1hbnRfZGlnIiwgICAgICAgICJEQkxfTUFOVF9ESUcgLS0gbWFudGlzc2EgZGlnaXRzIn0sCisgICAgeyJlcHNpbG9uIiwgICAgICAgICAiREJMX0VQU0lMT04gLS0gRGlmZmVyZW5jZSBiZXR3ZWVuIDEgYW5kIHRoZSBuZXh0ICIKKyAgICAgICAgICAgICAgICAgICAgInJlcHJlc2VudGFibGUgZmxvYXQifSwKKyAgICB7InJhZGl4IiwgICAgICAgICAgICJGTFRfUkFESVggLS0gcmFkaXggb2YgZXhwb25lbnQifSwKKyAgICB7InJvdW5kcyIsICAgICAgICAgICJGTFRfUk9VTkRTIC0tIGFkZGl0aW9uIHJvdW5kcyJ9LAorICAgIHswfQorfTsKKworc3RhdGljIFB5U3RydWN0U2VxdWVuY2VfRGVzYyBmbG9hdGluZm9fZGVzYyA9IHsKKyAgICAic3lzLmZsb2F0X2luZm8iLCAgICAgICAgICAgLyogbmFtZSAqLworICAgIGZsb2F0aW5mb19fZG9jX18sICAgICAgICAgICAvKiBkb2MgKi8KKyAgICBmbG9hdGluZm9fZmllbGRzLCAgICAgICAgICAgLyogZmllbGRzICovCisgICAgMTEKK307CisKK1B5T2JqZWN0ICoKK1B5RmxvYXRfR2V0SW5mbyh2b2lkKQoreworICAgIFB5T2JqZWN0KiBmbG9hdGluZm87CisgICAgaW50IHBvcyA9IDA7CisKKyAgICBmbG9hdGluZm8gPSBQeVN0cnVjdFNlcXVlbmNlX05ldygmRmxvYXRJbmZvVHlwZSk7CisgICAgaWYgKGZsb2F0aW5mbyA9PSBOVUxMKSB7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKworI2RlZmluZSBTZXRJbnRGbGFnKGZsYWcpIFwKKyAgICBQeVN0cnVjdFNlcXVlbmNlX1NFVF9JVEVNKGZsb2F0aW5mbywgcG9zKyssIFB5SW50X0Zyb21Mb25nKGZsYWcpKQorI2RlZmluZSBTZXREYmxGbGFnKGZsYWcpIFwKKyAgICBQeVN0cnVjdFNlcXVlbmNlX1NFVF9JVEVNKGZsb2F0aW5mbywgcG9zKyssIFB5RmxvYXRfRnJvbURvdWJsZShmbGFnKSkKKworICAgIFNldERibEZsYWcoREJMX01BWCk7CisgICAgU2V0SW50RmxhZyhEQkxfTUFYX0VYUCk7CisgICAgU2V0SW50RmxhZyhEQkxfTUFYXzEwX0VYUCk7CisgICAgU2V0RGJsRmxhZyhEQkxfTUlOKTsKKyAgICBTZXRJbnRGbGFnKERCTF9NSU5fRVhQKTsKKyAgICBTZXRJbnRGbGFnKERCTF9NSU5fMTBfRVhQKTsKKyAgICBTZXRJbnRGbGFnKERCTF9ESUcpOworICAgIFNldEludEZsYWcoREJMX01BTlRfRElHKTsKKyAgICBTZXREYmxGbGFnKERCTF9FUFNJTE9OKTsKKyAgICBTZXRJbnRGbGFnKEZMVF9SQURJWCk7CisgICAgU2V0SW50RmxhZyhGTFRfUk9VTkRTKTsKKyN1bmRlZiBTZXRJbnRGbGFnCisjdW5kZWYgU2V0RGJsRmxhZworCisgICAgaWYgKFB5RXJyX09jY3VycmVkKCkpIHsKKyAgICAgICAgUHlfQ0xFQVIoZmxvYXRpbmZvKTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIHJldHVybiBmbG9hdGluZm87Cit9CisKK1B5T2JqZWN0ICoKK1B5RmxvYXRfRnJvbURvdWJsZShkb3VibGUgZnZhbCkKK3sKKyAgICByZWdpc3RlciBQeUZsb2F0T2JqZWN0ICpvcDsKKyAgICBpZiAoZnJlZV9saXN0ID09IE5VTEwpIHsKKyAgICAgICAgaWYgKChmcmVlX2xpc3QgPSBmaWxsX2ZyZWVfbGlzdCgpKSA9PSBOVUxMKQorICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIC8qIElubGluZSBQeU9iamVjdF9OZXcgKi8KKyAgICBvcCA9IGZyZWVfbGlzdDsKKyAgICBmcmVlX2xpc3QgPSAoUHlGbG9hdE9iamVjdCAqKVB5X1RZUEUob3ApOworICAgIFB5T2JqZWN0X0lOSVQob3AsICZQeUZsb2F0X1R5cGUpOworICAgIG9wLT5vYl9mdmFsID0gZnZhbDsKKyAgICByZXR1cm4gKFB5T2JqZWN0ICopIG9wOworfQorCisvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKK1JFRF9GTEFHIDIyLVNlcC0yMDAwIHRpbQorUHlGbG9hdF9Gcm9tU3RyaW5nJ3MgcGVuZCBhcmd1bWVudCBpcyBicmFpbmRlYWQuICBQcmlvciB0byB0aGlzIFJFRF9GTEFHLAorCisxLiAgSWYgdiB3YXMgYSByZWd1bGFyIHN0cmluZywgKnBlbmQgd2FzIHNldCB0byBwb2ludCB0byBpdHMgdGVybWluYXRpbmcKKyAgICBudWxsIGJ5dGUuICBUaGF0J3MgdXNlbGVzcyAodGhlIGNhbGxlciBjYW4gZmluZCB0aGF0IHdpdGhvdXQgYW55CisgICAgaGVscCBmcm9tIHRoaXMgZnVuY3Rpb24hKS4KKworMi4gIElmIHYgd2FzIGEgVW5pY29kZSBzdHJpbmcsIG9yIGFuIG9iamVjdCBjb252ZXJ0aWJsZSB0byBhIGNoYXJhY3RlcgorICAgIGJ1ZmZlciwgKnBlbmQgd2FzIHNldCB0byBwb2ludCBpbnRvIHN0YWNrIHRyYXNoICh0aGUgYXV0byB0ZW1wCisgICAgdmVjdG9yIGhvbGRpbmcgdGhlIGNoYXJhY3RlciBidWZmZXIpLiAgVGhhdCB3YXMgZG93bnJpZ2h0IGRhbmdlcm91cy4KKworU2luY2Ugd2UgY2FuJ3QgY2hhbmdlIHRoZSBpbnRlcmZhY2Ugb2YgYSBwdWJsaWMgQVBJIGZ1bmN0aW9uLCBwZW5kIGlzCitzdGlsbCBzdXBwb3J0ZWQgYnV0IG5vdyAqb2ZmaWNpYWxseSogdXNlbGVzczogIGlmIHBlbmQgaXMgbm90IE5VTEwsCisqcGVuZCBpcyBzZXQgdG8gTlVMTC4KKyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLworUHlPYmplY3QgKgorUHlGbG9hdF9Gcm9tU3RyaW5nKFB5T2JqZWN0ICp2LCBjaGFyICoqcGVuZCkKK3sKKyAgICBjb25zdCBjaGFyICpzLCAqbGFzdCwgKmVuZDsKKyAgICBkb3VibGUgeDsKKyAgICBjaGFyIGJ1ZmZlclsyNTZdOyAvKiBmb3IgZXJyb3JzICovCisjaWZkZWYgUHlfVVNJTkdfVU5JQ09ERQorICAgIGNoYXIgKnNfYnVmZmVyID0gTlVMTDsKKyNlbmRpZgorICAgIFB5X3NzaXplX3QgbGVuOworICAgIFB5T2JqZWN0ICpyZXN1bHQgPSBOVUxMOworCisgICAgaWYgKHBlbmQpCisgICAgICAgICpwZW5kID0gTlVMTDsKKyAgICBpZiAoUHlTdHJpbmdfQ2hlY2sodikpIHsKKyAgICAgICAgcyA9IFB5U3RyaW5nX0FTX1NUUklORyh2KTsKKyAgICAgICAgbGVuID0gUHlTdHJpbmdfR0VUX1NJWkUodik7CisgICAgfQorI2lmZGVmIFB5X1VTSU5HX1VOSUNPREUKKyAgICBlbHNlIGlmIChQeVVuaWNvZGVfQ2hlY2sodikpIHsKKyAgICAgICAgc19idWZmZXIgPSAoY2hhciAqKVB5TWVtX01BTExPQyhQeVVuaWNvZGVfR0VUX1NJWkUodikrMSk7CisgICAgICAgIGlmIChzX2J1ZmZlciA9PSBOVUxMKQorICAgICAgICAgICAgcmV0dXJuIFB5RXJyX05vTWVtb3J5KCk7CisgICAgICAgIGlmIChQeVVuaWNvZGVfRW5jb2RlRGVjaW1hbChQeVVuaWNvZGVfQVNfVU5JQ09ERSh2KSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFB5VW5pY29kZV9HRVRfU0laRSh2KSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNfYnVmZmVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCkpCisgICAgICAgICAgICBnb3RvIGVycm9yOworICAgICAgICBzID0gc19idWZmZXI7CisgICAgICAgIGxlbiA9IHN0cmxlbihzKTsKKyAgICB9CisjZW5kaWYKKyAgICBlbHNlIGlmIChQeU9iamVjdF9Bc0NoYXJCdWZmZXIodiwgJnMsICZsZW4pKSB7CisgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19UeXBlRXJyb3IsCisgICAgICAgICAgICAiZmxvYXQoKSBhcmd1bWVudCBtdXN0IGJlIGEgc3RyaW5nIG9yIGEgbnVtYmVyIik7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICBsYXN0ID0gcyArIGxlbjsKKworICAgIHdoaWxlIChQeV9JU1NQQUNFKCpzKSkKKyAgICAgICAgcysrOworICAgIC8qIFdlIGRvbid0IGNhcmUgYWJvdXQgb3ZlcmZsb3cgb3IgdW5kZXJmbG93LiAgSWYgdGhlIHBsYXRmb3JtCisgICAgICogc3VwcG9ydHMgdGhlbSwgaW5maW5pdGllcyBhbmQgc2lnbmVkIHplcm9lcyAob24gdW5kZXJmbG93KSBhcmUKKyAgICAgKiBmaW5lLiAqLworICAgIHggPSBQeU9TX3N0cmluZ190b19kb3VibGUocywgKGNoYXIgKiopJmVuZCwgTlVMTCk7CisgICAgaWYgKHggPT0gLTEuMCAmJiBQeUVycl9PY2N1cnJlZCgpKQorICAgICAgICBnb3RvIGVycm9yOworICAgIHdoaWxlIChQeV9JU1NQQUNFKCplbmQpKQorICAgICAgICBlbmQrKzsKKyAgICBpZiAoZW5kID09IGxhc3QpCisgICAgICAgIHJlc3VsdCA9IFB5RmxvYXRfRnJvbURvdWJsZSh4KTsKKyAgICBlbHNlIHsKKyAgICAgICAgUHlPU19zbnByaW50ZihidWZmZXIsIHNpemVvZihidWZmZXIpLAorICAgICAgICAgICAgICAgICAgICAgICJpbnZhbGlkIGxpdGVyYWwgZm9yIGZsb2F0KCk6ICUuMjAwcyIsIHMpOworICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfVmFsdWVFcnJvciwgYnVmZmVyKTsKKyAgICAgICAgcmVzdWx0ID0gTlVMTDsKKyAgICB9CisKKyAgZXJyb3I6CisjaWZkZWYgUHlfVVNJTkdfVU5JQ09ERQorICAgIGlmIChzX2J1ZmZlcikKKyAgICAgICAgUHlNZW1fRlJFRShzX2J1ZmZlcik7CisjZW5kaWYKKyAgICByZXR1cm4gcmVzdWx0OworfQorCitzdGF0aWMgdm9pZAorZmxvYXRfZGVhbGxvYyhQeUZsb2F0T2JqZWN0ICpvcCkKK3sKKyAgICBpZiAoUHlGbG9hdF9DaGVja0V4YWN0KG9wKSkgeworICAgICAgICBQeV9UWVBFKG9wKSA9IChzdHJ1Y3QgX3R5cGVvYmplY3QgKilmcmVlX2xpc3Q7CisgICAgICAgIGZyZWVfbGlzdCA9IG9wOworICAgIH0KKyAgICBlbHNlCisgICAgICAgIFB5X1RZUEUob3ApLT50cF9mcmVlKChQeU9iamVjdCAqKW9wKTsKK30KKworZG91YmxlCitQeUZsb2F0X0FzRG91YmxlKFB5T2JqZWN0ICpvcCkKK3sKKyAgICBQeU51bWJlck1ldGhvZHMgKm5iOworICAgIFB5RmxvYXRPYmplY3QgKmZvOworICAgIGRvdWJsZSB2YWw7CisKKyAgICBpZiAob3AgJiYgUHlGbG9hdF9DaGVjayhvcCkpCisgICAgICAgIHJldHVybiBQeUZsb2F0X0FTX0RPVUJMRSgoUHlGbG9hdE9iamVjdCopIG9wKTsKKworICAgIGlmIChvcCA9PSBOVUxMKSB7CisgICAgICAgIFB5RXJyX0JhZEFyZ3VtZW50KCk7CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisKKyAgICBpZiAoKG5iID0gUHlfVFlQRShvcCktPnRwX2FzX251bWJlcikgPT0gTlVMTCB8fCBuYi0+bmJfZmxvYXQgPT0gTlVMTCkgeworICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfVHlwZUVycm9yLCAiYSBmbG9hdCBpcyByZXF1aXJlZCIpOworICAgICAgICByZXR1cm4gLTE7CisgICAgfQorCisgICAgZm8gPSAoUHlGbG9hdE9iamVjdCopICgqbmItPm5iX2Zsb2F0KSAob3ApOworICAgIGlmIChmbyA9PSBOVUxMKQorICAgICAgICByZXR1cm4gLTE7CisgICAgaWYgKCFQeUZsb2F0X0NoZWNrKGZvKSkgeworICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfVHlwZUVycm9yLAorICAgICAgICAgICAgICAgICAgICAgICAgIm5iX2Zsb2F0IHNob3VsZCByZXR1cm4gZmxvYXQgb2JqZWN0Iik7CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisKKyAgICB2YWwgPSBQeUZsb2F0X0FTX0RPVUJMRShmbyk7CisgICAgUHlfREVDUkVGKGZvKTsKKworICAgIHJldHVybiB2YWw7Cit9CisKKy8qIE1ldGhvZHMgKi8KKworLyogTWFjcm8gYW5kIGhlbHBlciB0aGF0IGNvbnZlcnQgUHlPYmplY3Qgb2JqIHRvIGEgQyBkb3VibGUgYW5kIHN0b3JlCisgICB0aGUgdmFsdWUgaW4gZGJsOyB0aGlzIHJlcGxhY2VzIHRoZSBmdW5jdGlvbmFsaXR5IG9mIHRoZSBjb2VyY2lvbgorICAgc2xvdCBmdW5jdGlvbi4gIElmIGNvbnZlcnNpb24gdG8gZG91YmxlIHJhaXNlcyBhbiBleGNlcHRpb24sIG9iaiBpcworICAgc2V0IHRvIE5VTEwsIGFuZCB0aGUgZnVuY3Rpb24gaW52b2tpbmcgdGhpcyBtYWNybyByZXR1cm5zIE5VTEwuICBJZgorICAgb2JqIGlzIG5vdCBvZiBmbG9hdCwgaW50IG9yIGxvbmcgdHlwZSwgUHlfTm90SW1wbGVtZW50ZWQgaXMgaW5jcmVmJ2VkLAorICAgc3RvcmVkIGluIG9iaiwgYW5kIHJldHVybmVkIGZyb20gdGhlIGZ1bmN0aW9uIGludm9raW5nIHRoaXMgbWFjcm8uCisqLworI2RlZmluZSBDT05WRVJUX1RPX0RPVUJMRShvYmosIGRibCkgICAgICAgICAgICAgICAgICAgICBcCisgICAgaWYgKFB5RmxvYXRfQ2hlY2sob2JqKSkgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgZGJsID0gUHlGbG9hdF9BU19ET1VCTEUob2JqKTsgICAgICAgICAgICAgICAgICAgXAorICAgIGVsc2UgaWYgKGNvbnZlcnRfdG9fZG91YmxlKCYob2JqKSwgJihkYmwpKSA8IDApICAgICBcCisgICAgICAgIHJldHVybiBvYmo7CisKK3N0YXRpYyBpbnQKK2NvbnZlcnRfdG9fZG91YmxlKFB5T2JqZWN0ICoqdiwgZG91YmxlICpkYmwpCit7CisgICAgcmVnaXN0ZXIgUHlPYmplY3QgKm9iaiA9ICp2OworCisgICAgaWYgKFB5SW50X0NoZWNrKG9iaikpIHsKKyAgICAgICAgKmRibCA9IChkb3VibGUpUHlJbnRfQVNfTE9ORyhvYmopOworICAgIH0KKyAgICBlbHNlIGlmIChQeUxvbmdfQ2hlY2sob2JqKSkgeworICAgICAgICAqZGJsID0gUHlMb25nX0FzRG91YmxlKG9iaik7CisgICAgICAgIGlmICgqZGJsID09IC0xLjAgJiYgUHlFcnJfT2NjdXJyZWQoKSkgeworICAgICAgICAgICAgKnYgPSBOVUxMOworICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICB9CisgICAgfQorICAgIGVsc2UgeworICAgICAgICBQeV9JTkNSRUYoUHlfTm90SW1wbGVtZW50ZWQpOworICAgICAgICAqdiA9IFB5X05vdEltcGxlbWVudGVkOworICAgICAgICByZXR1cm4gLTE7CisgICAgfQorICAgIHJldHVybiAwOworfQorCisvKiBYWFggUHlGbG9hdF9Bc1N0cmluZyBhbmQgUHlGbG9hdF9Bc1JlcHJTdHJpbmcgYXJlIGRlcHJlY2F0ZWQ6CisgICBYWFggdGhleSBwYXNzIGEgY2hhciBidWZmZXIgd2l0aG91dCBwYXNzaW5nIGEgbGVuZ3RoLgorKi8KK3ZvaWQKK1B5RmxvYXRfQXNTdHJpbmcoY2hhciAqYnVmLCBQeUZsb2F0T2JqZWN0ICp2KQoreworICAgIGNoYXIgKnRtcCA9IFB5T1NfZG91YmxlX3RvX3N0cmluZyh2LT5vYl9mdmFsLCAnZycsCisgICAgICAgICAgICAgICAgICAgIFB5RmxvYXRfU1RSX1BSRUNJU0lPTiwKKyAgICAgICAgICAgICAgICAgICAgUHlfRFRTRl9BRERfRE9UXzAsIE5VTEwpOworICAgIHN0cmNweShidWYsIHRtcCk7CisgICAgUHlNZW1fRnJlZSh0bXApOworfQorCit2b2lkCitQeUZsb2F0X0FzUmVwclN0cmluZyhjaGFyICpidWYsIFB5RmxvYXRPYmplY3QgKnYpCit7CisgICAgY2hhciAqIHRtcCA9IFB5T1NfZG91YmxlX3RvX3N0cmluZyh2LT5vYl9mdmFsLCAncicsIDAsCisgICAgICAgICAgICAgICAgICAgIFB5X0RUU0ZfQUREX0RPVF8wLCBOVUxMKTsKKyAgICBzdHJjcHkoYnVmLCB0bXApOworICAgIFB5TWVtX0ZyZWUodG1wKTsKK30KKworLyogQVJHU1VTRUQgKi8KK3N0YXRpYyBpbnQKK2Zsb2F0X3ByaW50KFB5RmxvYXRPYmplY3QgKnYsIEZJTEUgKmZwLCBpbnQgZmxhZ3MpCit7CisgICAgY2hhciAqYnVmOworICAgIGlmIChmbGFncyAmIFB5X1BSSU5UX1JBVykKKyAgICAgICAgYnVmID0gUHlPU19kb3VibGVfdG9fc3RyaW5nKHYtPm9iX2Z2YWwsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAnZycsIFB5RmxvYXRfU1RSX1BSRUNJU0lPTiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFB5X0RUU0ZfQUREX0RPVF8wLCBOVUxMKTsKKyAgICBlbHNlCisgICAgICAgIGJ1ZiA9IFB5T1NfZG91YmxlX3RvX3N0cmluZyh2LT5vYl9mdmFsLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICdyJywgMCwgUHlfRFRTRl9BRERfRE9UXzAsIE5VTEwpOworICAgIFB5X0JFR0lOX0FMTE9XX1RIUkVBRFMKKyAgICBmcHV0cyhidWYsIGZwKTsKKyAgICBQeV9FTkRfQUxMT1dfVEhSRUFEUworICAgIFB5TWVtX0ZyZWUoYnVmKTsKKyAgICByZXR1cm4gMDsKK30KKworc3RhdGljIFB5T2JqZWN0ICoKK2Zsb2F0X3N0cl9vcl9yZXByKFB5RmxvYXRPYmplY3QgKnYsIGludCBwcmVjaXNpb24sIGNoYXIgZm9ybWF0X2NvZGUpCit7CisgICAgUHlPYmplY3QgKnJlc3VsdDsKKyAgICBjaGFyICpidWYgPSBQeU9TX2RvdWJsZV90b19zdHJpbmcoUHlGbG9hdF9BU19ET1VCTEUodiksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9ybWF0X2NvZGUsIHByZWNpc2lvbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQeV9EVFNGX0FERF9ET1RfMCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOVUxMKTsKKyAgICBpZiAoIWJ1ZikKKyAgICAgICAgcmV0dXJuIFB5RXJyX05vTWVtb3J5KCk7CisgICAgcmVzdWx0ID0gUHlTdHJpbmdfRnJvbVN0cmluZyhidWYpOworICAgIFB5TWVtX0ZyZWUoYnVmKTsKKyAgICByZXR1cm4gcmVzdWx0OworfQorCitzdGF0aWMgUHlPYmplY3QgKgorZmxvYXRfcmVwcihQeUZsb2F0T2JqZWN0ICp2KQoreworICAgIHJldHVybiBmbG9hdF9zdHJfb3JfcmVwcih2LCAwLCAncicpOworfQorCitzdGF0aWMgUHlPYmplY3QgKgorZmxvYXRfc3RyKFB5RmxvYXRPYmplY3QgKnYpCit7CisgICAgcmV0dXJuIGZsb2F0X3N0cl9vcl9yZXByKHYsIFB5RmxvYXRfU1RSX1BSRUNJU0lPTiwgJ2cnKTsKK30KKworLyogQ29tcGFyaXNvbiBpcyBwcmV0dHkgbXVjaCBhIG5pZ2h0bWFyZS4gIFdoZW4gY29tcGFyaW5nIGZsb2F0IHRvIGZsb2F0LAorICogd2UgZG8gaXQgYXMgc3RyYWlnaHRmb3J3YXJkbHkgKGFuZCBsb25nLXdpbmRlZGx5KSBhcyBjb25jZWl2YWJsZSwgc28KKyAqIHRoYXQsIGUuZy4sIFB5dGhvbiB4ID09IHkgZGVsaXZlcnMgdGhlIHNhbWUgcmVzdWx0IGFzIHRoZSBwbGF0Zm9ybQorICogQyB4ID09IHkgd2hlbiB4IGFuZC9vciB5IGlzIGEgTmFOLgorICogV2hlbiBtaXhpbmcgZmxvYXQgd2l0aCBhbiBpbnRlZ2VyIHR5cGUsIHRoZXJlJ3Mgbm8gZ29vZCAqdW5pZm9ybSogYXBwcm9hY2guCisgKiBDb252ZXJ0aW5nIHRoZSBkb3VibGUgdG8gYW4gaW50ZWdlciBvYnZpb3VzbHkgZG9lc24ndCB3b3JrLCBzaW5jZSB3ZQorICogbWF5IGxvc2UgaW5mbyBmcm9tIGZyYWN0aW9uYWwgYml0cy4gIENvbnZlcnRpbmcgdGhlIGludGVnZXIgdG8gYSBkb3VibGUKKyAqIGFsc28gaGFzIHR3byBmYWlsdXJlIG1vZGVzOiAgKDEpIGEgbG9uZyBpbnQgbWF5IHRyaWdnZXIgb3ZlcmZsb3cgKHRvbworICogbGFyZ2UgdG8gZml0IGluIHRoZSBkeW5hbWljIHJhbmdlIG9mIGEgQyBkb3VibGUpOyAoMikgZXZlbiBhIEMgbG9uZyBtYXkgaGF2ZQorICogbW9yZSBiaXRzIHRoYW4gZml0IGluIGEgQyBkb3VibGUgKGUuZy4sIG9uIGEgYSA2NC1iaXQgYm94IGxvbmcgbWF5IGhhdmUKKyAqIDYzIGJpdHMgb2YgcHJlY2lzaW9uLCBidXQgYSBDIGRvdWJsZSBwcm9iYWJseSBoYXMgb25seSA1MyksIGFuZCB0aGVuCisgKiB3ZSBjYW4gZmFsc2VseSBjbGFpbSBlcXVhbGl0eSB3aGVuIGxvdy1vcmRlciBpbnRlZ2VyIGJpdHMgYXJlIGxvc3QgYnkKKyAqIGNvZXJjaW9uIHRvIGRvdWJsZS4gIFNvIHRoaXMgcGFydCBpcyBwYWluZnVsIHRvby4KKyAqLworCitzdGF0aWMgUHlPYmplY3QqCitmbG9hdF9yaWNoY29tcGFyZShQeU9iamVjdCAqdiwgUHlPYmplY3QgKncsIGludCBvcCkKK3sKKyAgICBkb3VibGUgaSwgajsKKyAgICBpbnQgciA9IDA7CisKKyAgICBhc3NlcnQoUHlGbG9hdF9DaGVjayh2KSk7CisgICAgaSA9IFB5RmxvYXRfQVNfRE9VQkxFKHYpOworCisgICAgLyogU3dpdGNoIG9uIHRoZSB0eXBlIG9mIHcuICBTZXQgaSBhbmQgaiB0byBkb3VibGVzIHRvIGJlIGNvbXBhcmVkLAorICAgICAqIGFuZCBvcCB0byB0aGUgcmljaGNvbXAgdG8gdXNlLgorICAgICAqLworICAgIGlmIChQeUZsb2F0X0NoZWNrKHcpKQorICAgICAgICBqID0gUHlGbG9hdF9BU19ET1VCTEUodyk7CisKKyAgICBlbHNlIGlmICghUHlfSVNfRklOSVRFKGkpKSB7CisgICAgICAgIGlmIChQeUludF9DaGVjayh3KSB8fCBQeUxvbmdfQ2hlY2sodykpCisgICAgICAgICAgICAvKiBJZiBpIGlzIGFuIGluZmluaXR5LCBpdHMgbWFnbml0dWRlIGV4Y2VlZHMgYW55CisgICAgICAgICAgICAgKiBmaW5pdGUgaW50ZWdlciwgc28gaXQgZG9lc24ndCBtYXR0ZXIgd2hpY2ggaW50IHdlCisgICAgICAgICAgICAgKiBjb21wYXJlIGkgd2l0aC4gIElmIGkgaXMgYSBOYU4sIHNpbWlsYXJseS4KKyAgICAgICAgICAgICAqLworICAgICAgICAgICAgaiA9IDAuMDsKKyAgICAgICAgZWxzZQorICAgICAgICAgICAgZ290byBVbmltcGxlbWVudGVkOworICAgIH0KKworICAgIGVsc2UgaWYgKFB5SW50X0NoZWNrKHcpKSB7CisgICAgICAgIGxvbmcgamogPSBQeUludF9BU19MT05HKHcpOworICAgICAgICAvKiBJbiB0aGUgd29yc3QgcmVhbGlzdGljIGNhc2UgSSBjYW4gaW1hZ2luZSwgQyBkb3VibGUgaXMgYQorICAgICAgICAgKiBDcmF5IHNpbmdsZSB3aXRoIDQ4IGJpdHMgb2YgcHJlY2lzaW9uLCBhbmQgbG9uZyBoYXMgNjQKKyAgICAgICAgICogYml0cy4KKyAgICAgICAgICovCisjaWYgU0laRU9GX0xPTkcgPiA2CisgICAgICAgIHVuc2lnbmVkIGxvbmcgYWJzID0gKHVuc2lnbmVkIGxvbmcpKGpqIDwgMCA/IC1qaiA6IGpqKTsKKyAgICAgICAgaWYgKGFicyA+PiA0OCkgeworICAgICAgICAgICAgLyogTmVlZHMgbW9yZSB0aGFuIDQ4IGJpdHMuICBNYWtlIGl0IHRha2UgdGhlCisgICAgICAgICAgICAgKiBQeUxvbmcgcGF0aC4KKyAgICAgICAgICAgICAqLworICAgICAgICAgICAgUHlPYmplY3QgKnJlc3VsdDsKKyAgICAgICAgICAgIFB5T2JqZWN0ICp3dyA9IFB5TG9uZ19Gcm9tTG9uZyhqaik7CisKKyAgICAgICAgICAgIGlmICh3dyA9PSBOVUxMKQorICAgICAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgICAgICAgICAgcmVzdWx0ID0gZmxvYXRfcmljaGNvbXBhcmUodiwgd3csIG9wKTsKKyAgICAgICAgICAgIFB5X0RFQ1JFRih3dyk7CisgICAgICAgICAgICByZXR1cm4gcmVzdWx0OworICAgICAgICB9CisjZW5kaWYKKyAgICAgICAgaiA9IChkb3VibGUpamo7CisgICAgICAgIGFzc2VydCgobG9uZylqID09IGpqKTsKKyAgICB9CisKKyAgICBlbHNlIGlmIChQeUxvbmdfQ2hlY2sodykpIHsKKyAgICAgICAgaW50IHZzaWduID0gaSA9PSAwLjAgPyAwIDogaSA8IDAuMCA/IC0xIDogMTsKKyAgICAgICAgaW50IHdzaWduID0gX1B5TG9uZ19TaWduKHcpOworICAgICAgICBzaXplX3QgbmJpdHM7CisgICAgICAgIGludCBleHBvbmVudDsKKworICAgICAgICBpZiAodnNpZ24gIT0gd3NpZ24pIHsKKyAgICAgICAgICAgIC8qIE1hZ25pdHVkZXMgYXJlIGlycmVsZXZhbnQgLS0gdGhlIHNpZ25zIGFsb25lCisgICAgICAgICAgICAgKiBkZXRlcm1pbmUgdGhlIG91dGNvbWUuCisgICAgICAgICAgICAgKi8KKyAgICAgICAgICAgIGkgPSAoZG91YmxlKXZzaWduOworICAgICAgICAgICAgaiA9IChkb3VibGUpd3NpZ247CisgICAgICAgICAgICBnb3RvIENvbXBhcmU7CisgICAgICAgIH0KKyAgICAgICAgLyogVGhlIHNpZ25zIGFyZSB0aGUgc2FtZS4gKi8KKyAgICAgICAgLyogQ29udmVydCB3IHRvIGEgZG91YmxlIGlmIGl0IGZpdHMuICBJbiBwYXJ0aWN1bGFyLCAwIGZpdHMuICovCisgICAgICAgIG5iaXRzID0gX1B5TG9uZ19OdW1CaXRzKHcpOworICAgICAgICBpZiAobmJpdHMgPT0gKHNpemVfdCktMSAmJiBQeUVycl9PY2N1cnJlZCgpKSB7CisgICAgICAgICAgICAvKiBUaGlzIGxvbmcgaXMgc28gbGFyZ2UgdGhhdCBzaXplX3QgaXNuJ3QgYmlnIGVub3VnaAorICAgICAgICAgICAgICogdG8gaG9sZCB0aGUgIyBvZiBiaXRzLiAgUmVwbGFjZSB3aXRoIGxpdHRsZSBkb3VibGVzCisgICAgICAgICAgICAgKiB0aGF0IGdpdmUgdGhlIHNhbWUgb3V0Y29tZSAtLSB3IGlzIHNvIGxhcmdlIHRoYXQKKyAgICAgICAgICAgICAqIGl0cyBtYWduaXR1ZGUgbXVzdCBleGNlZWQgdGhlIG1hZ25pdHVkZSBvZiBhbnkKKyAgICAgICAgICAgICAqIGZpbml0ZSBmbG9hdC4KKyAgICAgICAgICAgICAqLworICAgICAgICAgICAgUHlFcnJfQ2xlYXIoKTsKKyAgICAgICAgICAgIGkgPSAoZG91YmxlKXZzaWduOworICAgICAgICAgICAgYXNzZXJ0KHdzaWduICE9IDApOworICAgICAgICAgICAgaiA9IHdzaWduICogMi4wOworICAgICAgICAgICAgZ290byBDb21wYXJlOworICAgICAgICB9CisgICAgICAgIGlmIChuYml0cyA8PSA0OCkgeworICAgICAgICAgICAgaiA9IFB5TG9uZ19Bc0RvdWJsZSh3KTsKKyAgICAgICAgICAgIC8qIEl0J3MgaW1wb3NzaWJsZSB0aGF0IDw9IDQ4IGJpdHMgb3ZlcmZsb3dlZC4gKi8KKyAgICAgICAgICAgIGFzc2VydChqICE9IC0xLjAgfHwgISBQeUVycl9PY2N1cnJlZCgpKTsKKyAgICAgICAgICAgIGdvdG8gQ29tcGFyZTsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnQod3NpZ24gIT0gMCk7IC8qIGVsc2UgbmJpdHMgd2FzIDAgKi8KKyAgICAgICAgYXNzZXJ0KHZzaWduICE9IDApOyAvKiBpZiB2c2lnbiB3ZXJlIDAsIHRoZW4gc2luY2Ugd3NpZ24gaXMKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKiBub3QgMCwgd2Ugd291bGQgaGF2ZSB0YWtlbiB0aGUKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKiB2c2lnbiAhPSB3c2lnbiBicmFuY2ggYXQgdGhlIHN0YXJ0ICovCisgICAgICAgIC8qIFdlIHdhbnQgdG8gd29yayB3aXRoIG5vbi1uZWdhdGl2ZSBudW1iZXJzLiAqLworICAgICAgICBpZiAodnNpZ24gPCAwKSB7CisgICAgICAgICAgICAvKiAiTXVsdGlwbHkgYm90aCBzaWRlcyIgYnkgLTE7IHRoaXMgYWxzbyBzd2FwcyB0aGUKKyAgICAgICAgICAgICAqIGNvbXBhcmF0b3IuCisgICAgICAgICAgICAgKi8KKyAgICAgICAgICAgIGkgPSAtaTsKKyAgICAgICAgICAgIG9wID0gX1B5X1N3YXBwZWRPcFtvcF07CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0KGkgPiAwLjApOworICAgICAgICAodm9pZCkgZnJleHAoaSwgJmV4cG9uZW50KTsKKyAgICAgICAgLyogZXhwb25lbnQgaXMgdGhlICMgb2YgYml0cyBpbiB2IGJlZm9yZSB0aGUgcmFkaXggcG9pbnQ7CisgICAgICAgICAqIHdlIGtub3cgdGhhdCBuYml0cyAodGhlICMgb2YgYml0cyBpbiB3KSA+IDQ4IGF0IHRoaXMgcG9pbnQKKyAgICAgICAgICovCisgICAgICAgIGlmIChleHBvbmVudCA8IDAgfHwgKHNpemVfdClleHBvbmVudCA8IG5iaXRzKSB7CisgICAgICAgICAgICBpID0gMS4wOworICAgICAgICAgICAgaiA9IDIuMDsKKyAgICAgICAgICAgIGdvdG8gQ29tcGFyZTsKKyAgICAgICAgfQorICAgICAgICBpZiAoKHNpemVfdClleHBvbmVudCA+IG5iaXRzKSB7CisgICAgICAgICAgICBpID0gMi4wOworICAgICAgICAgICAgaiA9IDEuMDsKKyAgICAgICAgICAgIGdvdG8gQ29tcGFyZTsKKyAgICAgICAgfQorICAgICAgICAvKiB2IGFuZCB3IGhhdmUgdGhlIHNhbWUgbnVtYmVyIG9mIGJpdHMgYmVmb3JlIHRoZSByYWRpeAorICAgICAgICAgKiBwb2ludC4gIENvbnN0cnVjdCB0d28gbG9uZ3MgdGhhdCBoYXZlIHRoZSBzYW1lIGNvbXBhcmlzb24KKyAgICAgICAgICogb3V0Y29tZS4KKyAgICAgICAgICovCisgICAgICAgIHsKKyAgICAgICAgICAgIGRvdWJsZSBmcmFjcGFydDsKKyAgICAgICAgICAgIGRvdWJsZSBpbnRwYXJ0OworICAgICAgICAgICAgUHlPYmplY3QgKnJlc3VsdCA9IE5VTEw7CisgICAgICAgICAgICBQeU9iamVjdCAqb25lID0gTlVMTDsKKyAgICAgICAgICAgIFB5T2JqZWN0ICp2diA9IE5VTEw7CisgICAgICAgICAgICBQeU9iamVjdCAqd3cgPSB3OworCisgICAgICAgICAgICBpZiAod3NpZ24gPCAwKSB7CisgICAgICAgICAgICAgICAgd3cgPSBQeU51bWJlcl9OZWdhdGl2ZSh3KTsKKyAgICAgICAgICAgICAgICBpZiAod3cgPT0gTlVMTCkKKyAgICAgICAgICAgICAgICAgICAgZ290byBFcnJvcjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGVsc2UKKyAgICAgICAgICAgICAgICBQeV9JTkNSRUYod3cpOworCisgICAgICAgICAgICBmcmFjcGFydCA9IG1vZGYoaSwgJmludHBhcnQpOworICAgICAgICAgICAgdnYgPSBQeUxvbmdfRnJvbURvdWJsZShpbnRwYXJ0KTsKKyAgICAgICAgICAgIGlmICh2diA9PSBOVUxMKQorICAgICAgICAgICAgICAgIGdvdG8gRXJyb3I7CisKKyAgICAgICAgICAgIGlmIChmcmFjcGFydCAhPSAwLjApIHsKKyAgICAgICAgICAgICAgICAvKiBTaGlmdCBsZWZ0LCBhbmQgb3IgYSAxIGJpdCBpbnRvIHZ2CisgICAgICAgICAgICAgICAgICogdG8gcmVwcmVzZW50IHRoZSBsb3N0IGZyYWN0aW9uLgorICAgICAgICAgICAgICAgICAqLworICAgICAgICAgICAgICAgIFB5T2JqZWN0ICp0ZW1wOworCisgICAgICAgICAgICAgICAgb25lID0gUHlJbnRfRnJvbUxvbmcoMSk7CisgICAgICAgICAgICAgICAgaWYgKG9uZSA9PSBOVUxMKQorICAgICAgICAgICAgICAgICAgICBnb3RvIEVycm9yOworCisgICAgICAgICAgICAgICAgdGVtcCA9IFB5TnVtYmVyX0xzaGlmdCh3dywgb25lKTsKKyAgICAgICAgICAgICAgICBpZiAodGVtcCA9PSBOVUxMKQorICAgICAgICAgICAgICAgICAgICBnb3RvIEVycm9yOworICAgICAgICAgICAgICAgIFB5X0RFQ1JFRih3dyk7CisgICAgICAgICAgICAgICAgd3cgPSB0ZW1wOworCisgICAgICAgICAgICAgICAgdGVtcCA9IFB5TnVtYmVyX0xzaGlmdCh2diwgb25lKTsKKyAgICAgICAgICAgICAgICBpZiAodGVtcCA9PSBOVUxMKQorICAgICAgICAgICAgICAgICAgICBnb3RvIEVycm9yOworICAgICAgICAgICAgICAgIFB5X0RFQ1JFRih2dik7CisgICAgICAgICAgICAgICAgdnYgPSB0ZW1wOworCisgICAgICAgICAgICAgICAgdGVtcCA9IFB5TnVtYmVyX09yKHZ2LCBvbmUpOworICAgICAgICAgICAgICAgIGlmICh0ZW1wID09IE5VTEwpCisgICAgICAgICAgICAgICAgICAgIGdvdG8gRXJyb3I7CisgICAgICAgICAgICAgICAgUHlfREVDUkVGKHZ2KTsKKyAgICAgICAgICAgICAgICB2diA9IHRlbXA7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHIgPSBQeU9iamVjdF9SaWNoQ29tcGFyZUJvb2wodnYsIHd3LCBvcCk7CisgICAgICAgICAgICBpZiAociA8IDApCisgICAgICAgICAgICAgICAgZ290byBFcnJvcjsKKyAgICAgICAgICAgIHJlc3VsdCA9IFB5Qm9vbF9Gcm9tTG9uZyhyKTsKKyAgICAgICAgIEVycm9yOgorICAgICAgICAgICAgUHlfWERFQ1JFRih2dik7CisgICAgICAgICAgICBQeV9YREVDUkVGKHd3KTsKKyAgICAgICAgICAgIFB5X1hERUNSRUYob25lKTsKKyAgICAgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgICAgIH0KKyAgICB9IC8qIGVsc2UgaWYgKFB5TG9uZ19DaGVjayh3KSkgKi8KKworICAgIGVsc2UgICAgICAgIC8qIHcgaXNuJ3QgZmxvYXQsIGludCwgb3IgbG9uZyAqLworICAgICAgICBnb3RvIFVuaW1wbGVtZW50ZWQ7CisKKyBDb21wYXJlOgorICAgIFB5RlBFX1NUQVJUX1BST1RFQ1QoInJpY2hjb21wYXJlIiwgcmV0dXJuIE5VTEwpCisgICAgc3dpdGNoIChvcCkgeworICAgIGNhc2UgUHlfRVE6CisgICAgICAgIHIgPSBpID09IGo7CisgICAgICAgIGJyZWFrOworICAgIGNhc2UgUHlfTkU6CisgICAgICAgIHIgPSBpICE9IGo7CisgICAgICAgIGJyZWFrOworICAgIGNhc2UgUHlfTEU6CisgICAgICAgIHIgPSBpIDw9IGo7CisgICAgICAgIGJyZWFrOworICAgIGNhc2UgUHlfR0U6CisgICAgICAgIHIgPSBpID49IGo7CisgICAgICAgIGJyZWFrOworICAgIGNhc2UgUHlfTFQ6CisgICAgICAgIHIgPSBpIDwgajsKKyAgICAgICAgYnJlYWs7CisgICAgY2FzZSBQeV9HVDoKKyAgICAgICAgciA9IGkgPiBqOworICAgICAgICBicmVhazsKKyAgICB9CisgICAgUHlGUEVfRU5EX1BST1RFQ1QocikKKyAgICByZXR1cm4gUHlCb29sX0Zyb21Mb25nKHIpOworCisgVW5pbXBsZW1lbnRlZDoKKyAgICBQeV9JTkNSRUYoUHlfTm90SW1wbGVtZW50ZWQpOworICAgIHJldHVybiBQeV9Ob3RJbXBsZW1lbnRlZDsKK30KKworc3RhdGljIGxvbmcKK2Zsb2F0X2hhc2goUHlGbG9hdE9iamVjdCAqdikKK3sKKyAgICByZXR1cm4gX1B5X0hhc2hEb3VibGUodi0+b2JfZnZhbCk7Cit9CisKK3N0YXRpYyBQeU9iamVjdCAqCitmbG9hdF9hZGQoUHlPYmplY3QgKnYsIFB5T2JqZWN0ICp3KQoreworICAgIGRvdWJsZSBhLGI7CisgICAgQ09OVkVSVF9UT19ET1VCTEUodiwgYSk7CisgICAgQ09OVkVSVF9UT19ET1VCTEUodywgYik7CisgICAgUHlGUEVfU1RBUlRfUFJPVEVDVCgiYWRkIiwgcmV0dXJuIDApCisgICAgYSA9IGEgKyBiOworICAgIFB5RlBFX0VORF9QUk9URUNUKGEpCisgICAgcmV0dXJuIFB5RmxvYXRfRnJvbURvdWJsZShhKTsKK30KKworc3RhdGljIFB5T2JqZWN0ICoKK2Zsb2F0X3N1YihQeU9iamVjdCAqdiwgUHlPYmplY3QgKncpCit7CisgICAgZG91YmxlIGEsYjsKKyAgICBDT05WRVJUX1RPX0RPVUJMRSh2LCBhKTsKKyAgICBDT05WRVJUX1RPX0RPVUJMRSh3LCBiKTsKKyAgICBQeUZQRV9TVEFSVF9QUk9URUNUKCJzdWJ0cmFjdCIsIHJldHVybiAwKQorICAgIGEgPSBhIC0gYjsKKyAgICBQeUZQRV9FTkRfUFJPVEVDVChhKQorICAgIHJldHVybiBQeUZsb2F0X0Zyb21Eb3VibGUoYSk7Cit9CisKK3N0YXRpYyBQeU9iamVjdCAqCitmbG9hdF9tdWwoUHlPYmplY3QgKnYsIFB5T2JqZWN0ICp3KQoreworICAgIGRvdWJsZSBhLGI7CisgICAgQ09OVkVSVF9UT19ET1VCTEUodiwgYSk7CisgICAgQ09OVkVSVF9UT19ET1VCTEUodywgYik7CisgICAgUHlGUEVfU1RBUlRfUFJPVEVDVCgibXVsdGlwbHkiLCByZXR1cm4gMCkKKyAgICBhID0gYSAqIGI7CisgICAgUHlGUEVfRU5EX1BST1RFQ1QoYSkKKyAgICByZXR1cm4gUHlGbG9hdF9Gcm9tRG91YmxlKGEpOworfQorCitzdGF0aWMgUHlPYmplY3QgKgorZmxvYXRfZGl2KFB5T2JqZWN0ICp2LCBQeU9iamVjdCAqdykKK3sKKyAgICBkb3VibGUgYSxiOworICAgIENPTlZFUlRfVE9fRE9VQkxFKHYsIGEpOworICAgIENPTlZFUlRfVE9fRE9VQkxFKHcsIGIpOworI2lmZGVmIFB5X05BTgorICAgIGlmIChiID09IDAuMCkgeworICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfWmVyb0RpdmlzaW9uRXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAgICAiZmxvYXQgZGl2aXNpb24gYnkgemVybyIpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisjZW5kaWYKKyAgICBQeUZQRV9TVEFSVF9QUk9URUNUKCJkaXZpZGUiLCByZXR1cm4gMCkKKyAgICBhID0gYSAvIGI7CisgICAgUHlGUEVfRU5EX1BST1RFQ1QoYSkKKyAgICByZXR1cm4gUHlGbG9hdF9Gcm9tRG91YmxlKGEpOworfQorCitzdGF0aWMgUHlPYmplY3QgKgorZmxvYXRfY2xhc3NpY19kaXYoUHlPYmplY3QgKnYsIFB5T2JqZWN0ICp3KQoreworICAgIGRvdWJsZSBhLGI7CisgICAgQ09OVkVSVF9UT19ET1VCTEUodiwgYSk7CisgICAgQ09OVkVSVF9UT19ET1VCTEUodywgYik7CisgICAgaWYgKFB5X0RpdmlzaW9uV2FybmluZ0ZsYWcgPj0gMiAmJgorICAgICAgICBQeUVycl9XYXJuKFB5RXhjX0RlcHJlY2F0aW9uV2FybmluZywgImNsYXNzaWMgZmxvYXQgZGl2aXNpb24iKSA8IDApCisgICAgICAgIHJldHVybiBOVUxMOworI2lmZGVmIFB5X05BTgorICAgIGlmIChiID09IDAuMCkgeworICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfWmVyb0RpdmlzaW9uRXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAgICAiZmxvYXQgZGl2aXNpb24gYnkgemVybyIpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisjZW5kaWYKKyAgICBQeUZQRV9TVEFSVF9QUk9URUNUKCJkaXZpZGUiLCByZXR1cm4gMCkKKyAgICBhID0gYSAvIGI7CisgICAgUHlGUEVfRU5EX1BST1RFQ1QoYSkKKyAgICByZXR1cm4gUHlGbG9hdF9Gcm9tRG91YmxlKGEpOworfQorCitzdGF0aWMgUHlPYmplY3QgKgorZmxvYXRfcmVtKFB5T2JqZWN0ICp2LCBQeU9iamVjdCAqdykKK3sKKyAgICBkb3VibGUgdngsIHd4OworICAgIGRvdWJsZSBtb2Q7CisgICAgQ09OVkVSVF9UT19ET1VCTEUodiwgdngpOworICAgIENPTlZFUlRfVE9fRE9VQkxFKHcsIHd4KTsKKyNpZmRlZiBQeV9OQU4KKyAgICBpZiAod3ggPT0gMC4wKSB7CisgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19aZXJvRGl2aXNpb25FcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICJmbG9hdCBtb2R1bG8iKTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorI2VuZGlmCisgICAgUHlGUEVfU1RBUlRfUFJPVEVDVCgibW9kdWxvIiwgcmV0dXJuIDApCisgICAgbW9kID0gZm1vZCh2eCwgd3gpOworICAgIGlmIChtb2QpIHsKKyAgICAgICAgLyogZW5zdXJlIHRoZSByZW1haW5kZXIgaGFzIHRoZSBzYW1lIHNpZ24gYXMgdGhlIGRlbm9taW5hdG9yICovCisgICAgICAgIGlmICgod3ggPCAwKSAhPSAobW9kIDwgMCkpIHsKKyAgICAgICAgICAgIG1vZCArPSB3eDsKKyAgICAgICAgfQorICAgIH0KKyAgICBlbHNlIHsKKyAgICAgICAgLyogdGhlIHJlbWFpbmRlciBpcyB6ZXJvLCBhbmQgaW4gdGhlIHByZXNlbmNlIG9mIHNpZ25lZCB6ZXJvZXMKKyAgICAgICAgICAgZm1vZCByZXR1cm5zIGRpZmZlcmVudCByZXN1bHRzIGFjcm9zcyBwbGF0Zm9ybXM7IGVuc3VyZQorICAgICAgICAgICBpdCBoYXMgdGhlIHNhbWUgc2lnbiBhcyB0aGUgZGVub21pbmF0b3I7IHdlJ2QgbGlrZSB0byBkbworICAgICAgICAgICAibW9kID0gd3ggKiAwLjAiLCBidXQgdGhhdCBtYXkgZ2V0IG9wdGltaXplZCBhd2F5ICovCisgICAgICAgIG1vZCAqPSBtb2Q7ICAvKiBoaWRlICJtb2QgPSArMCIgZnJvbSBvcHRpbWl6ZXIgKi8KKyAgICAgICAgaWYgKHd4IDwgMC4wKQorICAgICAgICAgICAgbW9kID0gLW1vZDsKKyAgICB9CisgICAgUHlGUEVfRU5EX1BST1RFQ1QobW9kKQorICAgIHJldHVybiBQeUZsb2F0X0Zyb21Eb3VibGUobW9kKTsKK30KKworc3RhdGljIFB5T2JqZWN0ICoKK2Zsb2F0X2Rpdm1vZChQeU9iamVjdCAqdiwgUHlPYmplY3QgKncpCit7CisgICAgZG91YmxlIHZ4LCB3eDsKKyAgICBkb3VibGUgZGl2LCBtb2QsIGZsb29yZGl2OworICAgIENPTlZFUlRfVE9fRE9VQkxFKHYsIHZ4KTsKKyAgICBDT05WRVJUX1RPX0RPVUJMRSh3LCB3eCk7CisgICAgaWYgKHd4ID09IDAuMCkgeworICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfWmVyb0RpdmlzaW9uRXJyb3IsICJmbG9hdCBkaXZtb2QoKSIpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgUHlGUEVfU1RBUlRfUFJPVEVDVCgiZGl2bW9kIiwgcmV0dXJuIDApCisgICAgbW9kID0gZm1vZCh2eCwgd3gpOworICAgIC8qIGZtb2QgaXMgdHlwaWNhbGx5IGV4YWN0LCBzbyB2eC1tb2QgaXMgKm1hdGhlbWF0aWNhbGx5KiBhbgorICAgICAgIGV4YWN0IG11bHRpcGxlIG9mIHd4LiAgQnV0IHRoaXMgaXMgZnAgYXJpdGhtZXRpYywgYW5kIGZwCisgICAgICAgdnggLSBtb2QgaXMgYW4gYXBwcm94aW1hdGlvbjsgdGhlIHJlc3VsdCBpcyB0aGF0IGRpdiBtYXkKKyAgICAgICBub3QgYmUgYW4gZXhhY3QgaW50ZWdyYWwgdmFsdWUgYWZ0ZXIgdGhlIGRpdmlzaW9uLCBhbHRob3VnaAorICAgICAgIGl0IHdpbGwgYWx3YXlzIGJlIHZlcnkgY2xvc2UgdG8gb25lLgorICAgICovCisgICAgZGl2ID0gKHZ4IC0gbW9kKSAvIHd4OworICAgIGlmIChtb2QpIHsKKyAgICAgICAgLyogZW5zdXJlIHRoZSByZW1haW5kZXIgaGFzIHRoZSBzYW1lIHNpZ24gYXMgdGhlIGRlbm9taW5hdG9yICovCisgICAgICAgIGlmICgod3ggPCAwKSAhPSAobW9kIDwgMCkpIHsKKyAgICAgICAgICAgIG1vZCArPSB3eDsKKyAgICAgICAgICAgIGRpdiAtPSAxLjA7CisgICAgICAgIH0KKyAgICB9CisgICAgZWxzZSB7CisgICAgICAgIC8qIHRoZSByZW1haW5kZXIgaXMgemVybywgYW5kIGluIHRoZSBwcmVzZW5jZSBvZiBzaWduZWQgemVyb2VzCisgICAgICAgICAgIGZtb2QgcmV0dXJucyBkaWZmZXJlbnQgcmVzdWx0cyBhY3Jvc3MgcGxhdGZvcm1zOyBlbnN1cmUKKyAgICAgICAgICAgaXQgaGFzIHRoZSBzYW1lIHNpZ24gYXMgdGhlIGRlbm9taW5hdG9yOyB3ZSdkIGxpa2UgdG8gZG8KKyAgICAgICAgICAgIm1vZCA9IHd4ICogMC4wIiwgYnV0IHRoYXQgbWF5IGdldCBvcHRpbWl6ZWQgYXdheSAqLworICAgICAgICBtb2QgKj0gbW9kOyAgLyogaGlkZSAibW9kID0gKzAiIGZyb20gb3B0aW1pemVyICovCisgICAgICAgIGlmICh3eCA8IDAuMCkKKyAgICAgICAgICAgIG1vZCA9IC1tb2Q7CisgICAgfQorICAgIC8qIHNuYXAgcXVvdGllbnQgdG8gbmVhcmVzdCBpbnRlZ3JhbCB2YWx1ZSAqLworICAgIGlmIChkaXYpIHsKKyAgICAgICAgZmxvb3JkaXYgPSBmbG9vcihkaXYpOworICAgICAgICBpZiAoZGl2IC0gZmxvb3JkaXYgPiAwLjUpCisgICAgICAgICAgICBmbG9vcmRpdiArPSAxLjA7CisgICAgfQorICAgIGVsc2UgeworICAgICAgICAvKiBkaXYgaXMgemVybyAtIGdldCB0aGUgc2FtZSBzaWduIGFzIHRoZSB0cnVlIHF1b3RpZW50ICovCisgICAgICAgIGRpdiAqPSBkaXY7ICAgICAgICAgICAgIC8qIGhpZGUgImRpdiA9ICswIiBmcm9tIG9wdGltaXplcnMgKi8KKyAgICAgICAgZmxvb3JkaXYgPSBkaXYgKiB2eCAvIHd4OyAvKiB6ZXJvIHcvIHNpZ24gb2Ygdngvd3ggKi8KKyAgICB9CisgICAgUHlGUEVfRU5EX1BST1RFQ1QoZmxvb3JkaXYpCisgICAgcmV0dXJuIFB5X0J1aWxkVmFsdWUoIihkZCkiLCBmbG9vcmRpdiwgbW9kKTsKK30KKworc3RhdGljIFB5T2JqZWN0ICoKK2Zsb2F0X2Zsb29yX2RpdihQeU9iamVjdCAqdiwgUHlPYmplY3QgKncpCit7CisgICAgUHlPYmplY3QgKnQsICpyOworCisgICAgdCA9IGZsb2F0X2Rpdm1vZCh2LCB3KTsKKyAgICBpZiAodCA9PSBOVUxMIHx8IHQgPT0gUHlfTm90SW1wbGVtZW50ZWQpCisgICAgICAgIHJldHVybiB0OworICAgIGFzc2VydChQeVR1cGxlX0NoZWNrRXhhY3QodCkpOworICAgIHIgPSBQeVR1cGxlX0dFVF9JVEVNKHQsIDApOworICAgIFB5X0lOQ1JFRihyKTsKKyAgICBQeV9ERUNSRUYodCk7CisgICAgcmV0dXJuIHI7Cit9CisKKy8qIGRldGVybWluZSB3aGV0aGVyIHggaXMgYW4gb2RkIGludGVnZXIgb3Igbm90OyAgYXNzdW1lcyB0aGF0CisgICB4IGlzIG5vdCBhbiBpbmZpbml0eSBvciBuYW4uICovCisjZGVmaW5lIERPVUJMRV9JU19PRERfSU5URUdFUih4KSAoZm1vZChmYWJzKHgpLCAyLjApID09IDEuMCkKKworc3RhdGljIFB5T2JqZWN0ICoKK2Zsb2F0X3BvdyhQeU9iamVjdCAqdiwgUHlPYmplY3QgKncsIFB5T2JqZWN0ICp6KQoreworICAgIGRvdWJsZSBpdiwgaXcsIGl4OworICAgIGludCBuZWdhdGVfcmVzdWx0ID0gMDsKKworICAgIGlmICgoUHlPYmplY3QgKil6ICE9IFB5X05vbmUpIHsKKyAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1R5cGVFcnJvciwgInBvdygpIDNyZCBhcmd1bWVudCBub3QgIgorICAgICAgICAgICAgImFsbG93ZWQgdW5sZXNzIGFsbCBhcmd1bWVudHMgYXJlIGludGVnZXJzIik7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKworICAgIENPTlZFUlRfVE9fRE9VQkxFKHYsIGl2KTsKKyAgICBDT05WRVJUX1RPX0RPVUJMRSh3LCBpdyk7CisKKyAgICAvKiBTb3J0IG91dCBzcGVjaWFsIGNhc2VzIGhlcmUgaW5zdGVhZCBvZiByZWx5aW5nIG9uIHBvdygpICovCisgICAgaWYgKGl3ID09IDApIHsgICAgICAgICAgICAgIC8qIHYqKjAgaXMgMSwgZXZlbiAwKiowICovCisgICAgICAgIHJldHVybiBQeUZsb2F0X0Zyb21Eb3VibGUoMS4wKTsKKyAgICB9CisgICAgaWYgKFB5X0lTX05BTihpdikpIHsgICAgICAgIC8qIG5hbioqdyA9IG5hbiwgdW5sZXNzIHcgPT0gMCAqLworICAgICAgICByZXR1cm4gUHlGbG9hdF9Gcm9tRG91YmxlKGl2KTsKKyAgICB9CisgICAgaWYgKFB5X0lTX05BTihpdykpIHsgICAgICAgIC8qIHYqKm5hbiA9IG5hbiwgdW5sZXNzIHYgPT0gMTsgMSoqbmFuID0gMSAqLworICAgICAgICByZXR1cm4gUHlGbG9hdF9Gcm9tRG91YmxlKGl2ID09IDEuMCA/IDEuMCA6IGl3KTsKKyAgICB9CisgICAgaWYgKFB5X0lTX0lORklOSVRZKGl3KSkgeworICAgICAgICAvKiB2KippbmYgaXM6IDAuMCBpZiBhYnModikgPCAxOyAxLjAgaWYgYWJzKHYpID09IDE7IGluZiBpZgorICAgICAgICAgKiAgICAgYWJzKHYpID4gMSAoaW5jbHVkaW5nIGNhc2Ugd2hlcmUgdiBpbmZpbml0ZSkKKyAgICAgICAgICoKKyAgICAgICAgICogdioqLWluZiBpczogaW5mIGlmIGFicyh2KSA8IDE7IDEuMCBpZiBhYnModikgPT0gMTsgMC4wIGlmCisgICAgICAgICAqICAgICBhYnModikgPiAxIChpbmNsdWRpbmcgY2FzZSB3aGVyZSB2IGluZmluaXRlKQorICAgICAgICAgKi8KKyAgICAgICAgaXYgPSBmYWJzKGl2KTsKKyAgICAgICAgaWYgKGl2ID09IDEuMCkKKyAgICAgICAgICAgIHJldHVybiBQeUZsb2F0X0Zyb21Eb3VibGUoMS4wKTsKKyAgICAgICAgZWxzZSBpZiAoKGl3ID4gMC4wKSA9PSAoaXYgPiAxLjApKQorICAgICAgICAgICAgcmV0dXJuIFB5RmxvYXRfRnJvbURvdWJsZShmYWJzKGl3KSk7IC8qIHJldHVybiBpbmYgKi8KKyAgICAgICAgZWxzZQorICAgICAgICAgICAgcmV0dXJuIFB5RmxvYXRfRnJvbURvdWJsZSgwLjApOworICAgIH0KKyAgICBpZiAoUHlfSVNfSU5GSU5JVFkoaXYpKSB7CisgICAgICAgIC8qICgrLWluZikqKncgaXM6IGluZiBmb3IgdyBwb3NpdGl2ZSwgMCBmb3IgdyBuZWdhdGl2ZTsgaW4KKyAgICAgICAgICogICAgIGJvdGggY2FzZXMsIHdlIG5lZWQgdG8gYWRkIHRoZSBhcHByb3ByaWF0ZSBzaWduIGlmIHcgaXMKKyAgICAgICAgICogICAgIGFuIG9kZCBpbnRlZ2VyLgorICAgICAgICAgKi8KKyAgICAgICAgaW50IGl3X2lzX29kZCA9IERPVUJMRV9JU19PRERfSU5URUdFUihpdyk7CisgICAgICAgIGlmIChpdyA+IDAuMCkKKyAgICAgICAgICAgIHJldHVybiBQeUZsb2F0X0Zyb21Eb3VibGUoaXdfaXNfb2RkID8gaXYgOiBmYWJzKGl2KSk7CisgICAgICAgIGVsc2UKKyAgICAgICAgICAgIHJldHVybiBQeUZsb2F0X0Zyb21Eb3VibGUoaXdfaXNfb2RkID8KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29weXNpZ24oMC4wLCBpdikgOiAwLjApOworICAgIH0KKyAgICBpZiAoaXYgPT0gMC4wKSB7ICAvKiAwKip3IGlzOiAwIGZvciB3IHBvc2l0aXZlLCAxIGZvciB3IHplcm8KKyAgICAgICAgICAgICAgICAgICAgICAgICAoYWxyZWFkeSBkZWFsdCB3aXRoIGFib3ZlKSwgYW5kIGFuIGVycm9yCisgICAgICAgICAgICAgICAgICAgICAgICAgaWYgdyBpcyBuZWdhdGl2ZS4gKi8KKyAgICAgICAgaW50IGl3X2lzX29kZCA9IERPVUJMRV9JU19PRERfSU5URUdFUihpdyk7CisgICAgICAgIGlmIChpdyA8IDAuMCkgeworICAgICAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1plcm9EaXZpc2lvbkVycm9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICIwLjAgY2Fubm90IGJlIHJhaXNlZCB0byBhICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAibmVnYXRpdmUgcG93ZXIiKTsKKyAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgICAgICB9CisgICAgICAgIC8qIHVzZSBjb3JyZWN0IHNpZ24gaWYgaXcgaXMgb2RkICovCisgICAgICAgIHJldHVybiBQeUZsb2F0X0Zyb21Eb3VibGUoaXdfaXNfb2RkID8gaXYgOiAwLjApOworICAgIH0KKworICAgIGlmIChpdiA8IDAuMCkgeworICAgICAgICAvKiBXaGV0aGVyIHRoaXMgaXMgYW4gZXJyb3IgaXMgYSBtZXNzLCBhbmQgYnVtcHMgaW50byBsaWJtCisgICAgICAgICAqIGJ1Z3Mgc28gd2UgaGF2ZSB0byBmaWd1cmUgaXQgb3V0IG91cnNlbHZlcy4KKyAgICAgICAgICovCisgICAgICAgIGlmIChpdyAhPSBmbG9vcihpdykpIHsKKyAgICAgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19WYWx1ZUVycm9yLCAibmVnYXRpdmUgbnVtYmVyICIKKyAgICAgICAgICAgICAgICAiY2Fubm90IGJlIHJhaXNlZCB0byBhIGZyYWN0aW9uYWwgcG93ZXIiKTsKKyAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgICAgICB9CisgICAgICAgIC8qIGl3IGlzIGFuIGV4YWN0IGludGVnZXIsIGFsYmVpdCBwZXJoYXBzIGEgdmVyeSBsYXJnZQorICAgICAgICAgKiBvbmUuICBSZXBsYWNlIGl2IGJ5IGl0cyBhYnNvbHV0ZSB2YWx1ZSBhbmQgcmVtZW1iZXIKKyAgICAgICAgICogdG8gbmVnYXRlIHRoZSBwb3cgcmVzdWx0IGlmIGl3IGlzIG9kZC4KKyAgICAgICAgICovCisgICAgICAgIGl2ID0gLWl2OworICAgICAgICBuZWdhdGVfcmVzdWx0ID0gRE9VQkxFX0lTX09ERF9JTlRFR0VSKGl3KTsKKyAgICB9CisKKyAgICBpZiAoaXYgPT0gMS4wKSB7IC8qIDEqKncgaXMgMSwgZXZlbiAxKippbmYgYW5kIDEqKm5hbiAqLworICAgICAgICAvKiAoLTEpICoqIGxhcmdlX2ludGVnZXIgYWxzbyBlbmRzIHVwIGhlcmUuICBIZXJlJ3MgYW4KKyAgICAgICAgICogZXh0cmFjdCBmcm9tIHRoZSBjb21tZW50cyBmb3IgdGhlIHByZXZpb3VzCisgICAgICAgICAqIGltcGxlbWVudGF0aW9uIGV4cGxhaW5pbmcgd2h5IHRoaXMgc3BlY2lhbCBjYXNlIGlzCisgICAgICAgICAqIG5lY2Vzc2FyeToKKyAgICAgICAgICoKKyAgICAgICAgICogLTEgcmFpc2VkIHRvIGFuIGV4YWN0IGludGVnZXIgc2hvdWxkIG5ldmVyIGJlIGV4Y2VwdGlvbmFsLgorICAgICAgICAgKiBBbGFzLCBzb21lIGxpYm1zIChjaGllZmx5IGdsaWJjIGFzIG9mIGVhcmx5IDIwMDMpIHJldHVybgorICAgICAgICAgKiBOYU4gYW5kIHNldCBFRE9NIG9uIHBvdygtMSwgbGFyZ2VfaW50KSBpZiB0aGUgaW50IGRvZXNuJ3QKKyAgICAgICAgICogaGFwcGVuIHRvIGJlIHJlcHJlc2VudGFibGUgaW4gYSAqQyogaW50ZWdlci4gIFRoYXQncyBhCisgICAgICAgICAqIGJ1Zy4KKyAgICAgICAgICovCisgICAgICAgIHJldHVybiBQeUZsb2F0X0Zyb21Eb3VibGUobmVnYXRlX3Jlc3VsdCA/IC0xLjAgOiAxLjApOworICAgIH0KKworICAgIC8qIE5vdyBpdiBhbmQgaXcgYXJlIGZpbml0ZSwgaXcgaXMgbm9uemVybywgYW5kIGl2IGlzCisgICAgICogcG9zaXRpdmUgYW5kIG5vdCBlcXVhbCB0byAxLjAuICBXZSBmaW5hbGx5IGFsbG93CisgICAgICogdGhlIHBsYXRmb3JtIHBvdyB0byBzdGVwIGluIGFuZCBkbyB0aGUgcmVzdC4KKyAgICAgKi8KKyAgICBlcnJubyA9IDA7CisgICAgUHlGUEVfU1RBUlRfUFJPVEVDVCgicG93IiwgcmV0dXJuIE5VTEwpCisgICAgaXggPSBwb3coaXYsIGl3KTsKKyAgICBQeUZQRV9FTkRfUFJPVEVDVChpeCkKKyAgICBQeV9BREpVU1RfRVJBTkdFMShpeCk7CisgICAgaWYgKG5lZ2F0ZV9yZXN1bHQpCisgICAgICAgIGl4ID0gLWl4OworCisgICAgaWYgKGVycm5vICE9IDApIHsKKyAgICAgICAgLyogV2UgZG9uJ3QgZXhwZWN0IGFueSBlcnJubyB2YWx1ZSBvdGhlciB0aGFuIEVSQU5HRSwgYnV0CisgICAgICAgICAqIHRoZSByYW5nZSBvZiBsaWJtIGJ1Z3MgYXBwZWFycyB1bmJvdW5kZWQuCisgICAgICAgICAqLworICAgICAgICBQeUVycl9TZXRGcm9tRXJybm8oZXJybm8gPT0gRVJBTkdFID8gUHlFeGNfT3ZlcmZsb3dFcnJvciA6CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFB5RXhjX1ZhbHVlRXJyb3IpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgcmV0dXJuIFB5RmxvYXRfRnJvbURvdWJsZShpeCk7Cit9CisKKyN1bmRlZiBET1VCTEVfSVNfT0REX0lOVEVHRVIKKworc3RhdGljIFB5T2JqZWN0ICoKK2Zsb2F0X25lZyhQeUZsb2F0T2JqZWN0ICp2KQoreworICAgIHJldHVybiBQeUZsb2F0X0Zyb21Eb3VibGUoLXYtPm9iX2Z2YWwpOworfQorCitzdGF0aWMgUHlPYmplY3QgKgorZmxvYXRfYWJzKFB5RmxvYXRPYmplY3QgKnYpCit7CisgICAgcmV0dXJuIFB5RmxvYXRfRnJvbURvdWJsZShmYWJzKHYtPm9iX2Z2YWwpKTsKK30KKworc3RhdGljIGludAorZmxvYXRfbm9uemVybyhQeUZsb2F0T2JqZWN0ICp2KQoreworICAgIHJldHVybiB2LT5vYl9mdmFsICE9IDAuMDsKK30KKworc3RhdGljIGludAorZmxvYXRfY29lcmNlKFB5T2JqZWN0ICoqcHYsIFB5T2JqZWN0ICoqcHcpCit7CisgICAgaWYgKFB5SW50X0NoZWNrKCpwdykpIHsKKyAgICAgICAgbG9uZyB4ID0gUHlJbnRfQXNMb25nKCpwdyk7CisgICAgICAgICpwdyA9IFB5RmxvYXRfRnJvbURvdWJsZSgoZG91YmxlKXgpOworICAgICAgICBQeV9JTkNSRUYoKnB2KTsKKyAgICAgICAgcmV0dXJuIDA7CisgICAgfQorICAgIGVsc2UgaWYgKFB5TG9uZ19DaGVjaygqcHcpKSB7CisgICAgICAgIGRvdWJsZSB4ID0gUHlMb25nX0FzRG91YmxlKCpwdyk7CisgICAgICAgIGlmICh4ID09IC0xLjAgJiYgUHlFcnJfT2NjdXJyZWQoKSkKKyAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgKnB3ID0gUHlGbG9hdF9Gcm9tRG91YmxlKHgpOworICAgICAgICBQeV9JTkNSRUYoKnB2KTsKKyAgICAgICAgcmV0dXJuIDA7CisgICAgfQorICAgIGVsc2UgaWYgKFB5RmxvYXRfQ2hlY2soKnB3KSkgeworICAgICAgICBQeV9JTkNSRUYoKnB2KTsKKyAgICAgICAgUHlfSU5DUkVGKCpwdyk7CisgICAgICAgIHJldHVybiAwOworICAgIH0KKyAgICByZXR1cm4gMTsgLyogQ2FuJ3QgZG8gaXQgKi8KK30KKworc3RhdGljIFB5T2JqZWN0ICoKK2Zsb2F0X2lzX2ludGVnZXIoUHlPYmplY3QgKnYpCit7CisgICAgZG91YmxlIHggPSBQeUZsb2F0X0FzRG91YmxlKHYpOworICAgIFB5T2JqZWN0ICpvOworCisgICAgaWYgKHggPT0gLTEuMCAmJiBQeUVycl9PY2N1cnJlZCgpKQorICAgICAgICByZXR1cm4gTlVMTDsKKyAgICBpZiAoIVB5X0lTX0ZJTklURSh4KSkKKyAgICAgICAgUHlfUkVUVVJOX0ZBTFNFOworICAgIGVycm5vID0gMDsKKyAgICBQeUZQRV9TVEFSVF9QUk9URUNUKCJpc19pbnRlZ2VyIiwgcmV0dXJuIE5VTEwpCisgICAgbyA9IChmbG9vcih4KSA9PSB4KSA/IFB5X1RydWUgOiBQeV9GYWxzZTsKKyAgICBQeUZQRV9FTkRfUFJPVEVDVCh4KQorICAgIGlmIChlcnJubyAhPSAwKSB7CisgICAgICAgIFB5RXJyX1NldEZyb21FcnJubyhlcnJubyA9PSBFUkFOR0UgPyBQeUV4Y19PdmVyZmxvd0Vycm9yIDoKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHlFeGNfVmFsdWVFcnJvcik7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICBQeV9JTkNSRUYobyk7CisgICAgcmV0dXJuIG87Cit9CisKKyNpZiAwCitzdGF0aWMgUHlPYmplY3QgKgorZmxvYXRfaXNfaW5mKFB5T2JqZWN0ICp2KQoreworICAgIGRvdWJsZSB4ID0gUHlGbG9hdF9Bc0RvdWJsZSh2KTsKKyAgICBpZiAoeCA9PSAtMS4wICYmIFB5RXJyX09jY3VycmVkKCkpCisgICAgICAgIHJldHVybiBOVUxMOworICAgIHJldHVybiBQeUJvb2xfRnJvbUxvbmcoKGxvbmcpUHlfSVNfSU5GSU5JVFkoeCkpOworfQorCitzdGF0aWMgUHlPYmplY3QgKgorZmxvYXRfaXNfbmFuKFB5T2JqZWN0ICp2KQoreworICAgIGRvdWJsZSB4ID0gUHlGbG9hdF9Bc0RvdWJsZSh2KTsKKyAgICBpZiAoeCA9PSAtMS4wICYmIFB5RXJyX09jY3VycmVkKCkpCisgICAgICAgIHJldHVybiBOVUxMOworICAgIHJldHVybiBQeUJvb2xfRnJvbUxvbmcoKGxvbmcpUHlfSVNfTkFOKHgpKTsKK30KKworc3RhdGljIFB5T2JqZWN0ICoKK2Zsb2F0X2lzX2Zpbml0ZShQeU9iamVjdCAqdikKK3sKKyAgICBkb3VibGUgeCA9IFB5RmxvYXRfQXNEb3VibGUodik7CisgICAgaWYgKHggPT0gLTEuMCAmJiBQeUVycl9PY2N1cnJlZCgpKQorICAgICAgICByZXR1cm4gTlVMTDsKKyAgICByZXR1cm4gUHlCb29sX0Zyb21Mb25nKChsb25nKVB5X0lTX0ZJTklURSh4KSk7Cit9CisjZW5kaWYKKworc3RhdGljIFB5T2JqZWN0ICoKK2Zsb2F0X3RydW5jKFB5T2JqZWN0ICp2KQoreworICAgIGRvdWJsZSB4ID0gUHlGbG9hdF9Bc0RvdWJsZSh2KTsKKyAgICBkb3VibGUgd2hvbGVwYXJ0OyAgICAgICAgICAgLyogaW50ZWdyYWwgcG9ydGlvbiBvZiB4LCByb3VuZGVkIHRvd2FyZCAwICovCisKKyAgICAodm9pZCltb2RmKHgsICZ3aG9sZXBhcnQpOworICAgIC8qIFRyeSB0byBnZXQgb3V0IGNoZWFwIGlmIHRoaXMgZml0cyBpbiBhIFB5dGhvbiBpbnQuICBUaGUgYXR0ZW1wdAorICAgICAqIHRvIGNhc3QgdG8gbG9uZyBtdXN0IGJlIHByb3RlY3RlZCwgYXMgQyBkb2Vzbid0IGRlZmluZSB3aGF0CisgICAgICogaGFwcGVucyBpZiB0aGUgZG91YmxlIGlzIHRvbyBiaWcgdG8gZml0IGluIGEgbG9uZy4gIFNvbWUgcmFyZQorICAgICAqIHN5c3RlbXMgcmFpc2UgYW4gZXhjZXB0aW9uIHRoZW4gKFJJU0NPUyB3YXMgbWVudGlvbmVkIGFzIG9uZSwKKyAgICAgKiBhbmQgc29tZW9uZSB1c2luZyBhIG5vbi1kZWZhdWx0IG9wdGlvbiBvbiBTdW4gYWxzbyBidW1wZWQgaW50bworICAgICAqIHRoYXQpLiAgTm90ZSB0aGF0IGNoZWNraW5nIGZvciA8PSBMT05HX01BWCBpcyB1bnNhZmU6IGlmIGEgbG9uZworICAgICAqIGhhcyBtb3JlIGJpdHMgb2YgcHJlY2lzaW9uIHRoYW4gYSBkb3VibGUsIGNhc3RpbmcgTE9OR19NQVggdG8KKyAgICAgKiBkb3VibGUgbWF5IHlpZWxkIGFuIGFwcHJveGltYXRpb24sIGFuZCBpZiB0aGF0J3Mgcm91bmRlZCB1cCwKKyAgICAgKiB0aGVuLCBlLmcuLCB3aG9sZXBhcnQ9TE9OR19NQVgrMSB3b3VsZCB5aWVsZCB0cnVlIGZyb20gdGhlIEMKKyAgICAgKiBleHByZXNzaW9uIHdob2xlcGFydDw9TE9OR19NQVgsIGRlc3BpdGUgdGhhdCB3aG9sZXBhcnQgaXMKKyAgICAgKiBhY3R1YWxseSBncmVhdGVyIHRoYW4gTE9OR19NQVguICBIb3dldmVyLCBhc3N1bWluZyBhIHR3bydzIGNvbXBsZW1lbnQKKyAgICAgKiBtYWNoaW5lIHdpdGggbm8gdHJhcCByZXByZXNlbnRhdGlvbiwgTE9OR19NSU4gd2lsbCBiZSBhIHBvd2VyIG9mIDIgKGFuZAorICAgICAqIGhlbmNlIGV4YWN0bHkgcmVwcmVzZW50YWJsZSBhcyBhIGRvdWJsZSksIGFuZCBMT05HX01BWCA9IC0xLUxPTkdfTUlOLCBzbworICAgICAqIHRoZSBjb21wYXJpc29ucyB3aXRoIChkb3VibGUpTE9OR19NSU4gYmVsb3cgc2hvdWxkIGJlIHNhZmUuCisgICAgICovCisgICAgaWYgKChkb3VibGUpTE9OR19NSU4gPD0gd2hvbGVwYXJ0ICYmIHdob2xlcGFydCA8IC0oZG91YmxlKUxPTkdfTUlOKSB7CisgICAgICAgIGNvbnN0IGxvbmcgYXNsb25nID0gKGxvbmcpd2hvbGVwYXJ0OworICAgICAgICByZXR1cm4gUHlJbnRfRnJvbUxvbmcoYXNsb25nKTsKKyAgICB9CisgICAgcmV0dXJuIFB5TG9uZ19Gcm9tRG91YmxlKHdob2xlcGFydCk7Cit9CisKK3N0YXRpYyBQeU9iamVjdCAqCitmbG9hdF9sb25nKFB5T2JqZWN0ICp2KQoreworICAgIGRvdWJsZSB4ID0gUHlGbG9hdF9Bc0RvdWJsZSh2KTsKKyAgICByZXR1cm4gUHlMb25nX0Zyb21Eb3VibGUoeCk7Cit9CisKKy8qIF9QeV9kb3VibGVfcm91bmQ6IHJvdW5kcyBhIGZpbml0ZSBub256ZXJvIGRvdWJsZSB0byB0aGUgY2xvc2VzdCBtdWx0aXBsZSBvZgorICAgMTAqKi1uZGlnaXRzOyBoZXJlIG5kaWdpdHMgaXMgd2l0aGluIHJlYXNvbmFibGUgYm91bmRzICh0eXBpY2FsbHksIC0zMDggPD0KKyAgIG5kaWdpdHMgPD0gMzIzKS4gIFJldHVybnMgYSBQeXRob24gZmxvYXQsIG9yIHNldHMgYSBQeXRob24gZXJyb3IgYW5kCisgICByZXR1cm5zIE5VTEwgb24gZmFpbHVyZSAoT3ZlcmZsb3dFcnJvciBhbmQgbWVtb3J5IGVycm9ycyBhcmUgcG9zc2libGUpLiAqLworCisjaWZuZGVmIFBZX05PX1NIT1JUX0ZMT0FUX1JFUFIKKy8qIHZlcnNpb24gb2YgX1B5X2RvdWJsZV9yb3VuZCB0aGF0IHVzZXMgdGhlIGNvcnJlY3RseS1yb3VuZGVkIHN0cmluZzwtPmRvdWJsZQorICAgY29udmVyc2lvbnMgZnJvbSBQeXRob24vZHRvYS5jICovCisKKy8qIEZJVkVfUE9XX0xJTUlUIGlzIHRoZSBsYXJnZXN0IGsgc3VjaCB0aGF0IDUqKmsgaXMgZXhhY3RseSByZXByZXNlbnRhYmxlIGFzCisgICBhIGRvdWJsZS4gIFNpbmNlIHdlJ3JlIHVzaW5nIHRoZSBjb2RlIGluIFB5dGhvbi9kdG9hLmMsIGl0IHNob3VsZCBiZSBzYWZlCisgICB0byBhc3N1bWUgdGhhdCBDIGRvdWJsZXMgYXJlIElFRUUgNzU0IGJpbmFyeTY0IGZvcm1hdC4gIFRvIGJlIG9uIHRoZSBzYWZlCisgICBzaWRlLCB3ZSBjaGVjayB0aGlzLiAqLworI2lmIERCTF9NQU5UX0RJRyA9PSA1MworI2RlZmluZSBGSVZFX1BPV19MSU1JVCAyMgorI2Vsc2UKKyNlcnJvciAiQyBkb3VibGVzIGRvIG5vdCBhcHBlYXIgdG8gYmUgSUVFRSA3NTQgYmluYXJ5NjQgZm9ybWF0IgorI2VuZGlmCisKK1B5T2JqZWN0ICoKK19QeV9kb3VibGVfcm91bmQoZG91YmxlIHgsIGludCBuZGlnaXRzKSB7CisKKyAgICBkb3VibGUgcm91bmRlZCwgbTsKKyAgICBQeV9zc2l6ZV90IGJ1ZmxlbiwgbXlidWZsZW49MTAwOworICAgIGNoYXIgKmJ1ZiwgKmJ1Zl9lbmQsIHNob3J0YnVmWzEwMF0sICpteWJ1Zj1zaG9ydGJ1ZjsKKyAgICBpbnQgZGVjcHQsIHNpZ24sIHZhbCwgaGFsZndheV9jYXNlOworICAgIFB5T2JqZWN0ICpyZXN1bHQgPSBOVUxMOworICAgIF9QeV9TRVRfNTNCSVRfUFJFQ0lTSU9OX0hFQURFUjsKKworICAgIC8qIEVhc3kgcGF0aCBmb3IgdGhlIGNvbW1vbiBjYXNlIG5kaWdpdHMgPT0gMC4gKi8KKyAgICBpZiAobmRpZ2l0cyA9PSAwKSB7CisgICAgICAgIHJvdW5kZWQgPSByb3VuZCh4KTsKKyAgICAgICAgaWYgKGZhYnMocm91bmRlZCAtIHgpID09IDAuNSkKKyAgICAgICAgICAgIC8qIGhhbGZ3YXkgYmV0d2VlbiB0d28gaW50ZWdlcnM7IHVzZSByb3VuZC1hd2F5LWZyb20temVybyAqLworICAgICAgICAgICAgcm91bmRlZCA9IHggKyAoeCA+IDAuMCA/IDAuNSA6IC0wLjUpOworICAgICAgICByZXR1cm4gUHlGbG9hdF9Gcm9tRG91YmxlKHJvdW5kZWQpOworICAgIH0KKworICAgIC8qIFRoZSBiYXNpYyBpZGVhIGlzIHZlcnkgc2ltcGxlOiBjb252ZXJ0IGFuZCByb3VuZCB0aGUgZG91YmxlIHRvIGEKKyAgICAgICBkZWNpbWFsIHN0cmluZyB1c2luZyBfUHlfZGdfZHRvYSwgdGhlbiBjb252ZXJ0IHRoYXQgZGVjaW1hbCBzdHJpbmcKKyAgICAgICBiYWNrIHRvIGEgZG91YmxlIHdpdGggX1B5X2RnX3N0cnRvZC4gIFRoZXJlJ3Mgb25lIG1pbm9yIGRpZmZpY3VsdHk6CisgICAgICAgUHl0aG9uIDIueCBleHBlY3RzIHJvdW5kIHRvIGRvIHJvdW5kLWhhbGYtYXdheS1mcm9tLXplcm8sIHdoaWxlCisgICAgICAgX1B5X2RnX2R0b2EgZG9lcyByb3VuZC1oYWxmLXRvLWV2ZW4uICBTbyB3ZSBuZWVkIHNvbWUgd2F5IHRvIGRldGVjdAorICAgICAgIGFuZCBjb3JyZWN0IHRoZSBoYWxmd2F5IGNhc2VzLgorCisgICAgICAgRGV0ZWN0aW9uOiBhIGhhbGZ3YXkgdmFsdWUgaGFzIHRoZSBmb3JtIGsgKiAwLjUgKiAxMCoqLW5kaWdpdHMgZm9yCisgICAgICAgc29tZSBvZGQgaW50ZWdlciBrLiAgT3IgaW4gb3RoZXIgd29yZHMsIGEgcmF0aW9uYWwgbnVtYmVyIHggaXMKKyAgICAgICBleGFjdGx5IGhhbGZ3YXkgYmV0d2VlbiB0d28gbXVsdGlwbGVzIG9mIDEwKiotbmRpZ2l0cyBpZiBpdHMKKyAgICAgICAyLXZhbHVhdGlvbiBpcyBleGFjdGx5IC1uZGlnaXRzLTEgYW5kIGl0cyA1LXZhbHVhdGlvbiBpcyBhdCBsZWFzdAorICAgICAgIC1uZGlnaXRzLiAgRm9yIG5kaWdpdHMgPj0gMCB0aGUgbGF0dGVyIGNvbmRpdGlvbiBpcyBhdXRvbWF0aWNhbGx5CisgICAgICAgc2F0aXNmaWVkIGZvciBhIGJpbmFyeSBmbG9hdCB4LCBzaW5jZSBhbnkgc3VjaCBmbG9hdCBoYXMKKyAgICAgICBub25uZWdhdGl2ZSA1LXZhbHVhdGlvbi4gIEZvciAwID4gbmRpZ2l0cyA+PSAtMjIsIHggbmVlZHMgdG8gYmUgYW4KKyAgICAgICBpbnRlZ3JhbCBtdWx0aXBsZSBvZiA1KiotbmRpZ2l0czsgd2UgY2FuIGNoZWNrIHRoaXMgdXNpbmcgZm1vZC4KKyAgICAgICBGb3IgLTIyID4gbmRpZ2l0cywgdGhlcmUgYXJlIG5vIGhhbGZ3YXkgY2FzZXM6IDUqKjIzIHRha2VzIDU0IGJpdHMKKyAgICAgICB0byByZXByZXNlbnQgZXhhY3RseSwgc28gYW55IG9kZCBtdWx0aXBsZSBvZiAwLjUgKiAxMCoqbiBmb3IgbiA+PQorICAgICAgIDIzIHRha2VzIGF0IGxlYXN0IDU0IGJpdHMgb2YgcHJlY2lzaW9uIHRvIHJlcHJlc2VudCBleGFjdGx5LgorCisgICAgICAgQ29ycmVjdGlvbjogYSBzaW1wbGUgc3RyYXRlZ3kgZm9yIGRlYWxpbmcgd2l0aCBoYWxmd2F5IGNhc2VzIGlzIHRvCisgICAgICAgKGZvciB0aGUgaGFsZndheSBjYXNlcyBvbmx5KSBjYWxsIF9QeV9kZ19kdG9hIHdpdGggYW4gYXJndW1lbnQgb2YKKyAgICAgICBuZGlnaXRzKzEgaW5zdGVhZCBvZiBuZGlnaXRzICh0aHVzIGRvaW5nIGFuIGV4YWN0IGNvbnZlcnNpb24gdG8KKyAgICAgICBkZWNpbWFsKSwgcm91bmQgdGhlIHJlc3VsdGluZyBzdHJpbmcgbWFudWFsbHksIGFuZCB0aGVuIGNvbnZlcnQKKyAgICAgICBiYWNrIHVzaW5nIF9QeV9kZ19zdHJ0b2QuCisgICAgKi8KKworICAgIC8qIG5hbnMsIGluZmluaXRpZXMgYW5kIHplcm9zIHNob3VsZCBoYXZlIGFscmVhZHkgYmVlbiBkZWFsdAorICAgICAgIHdpdGggYnkgdGhlIGNhbGxlciAoaW4gdGhpcyBjYXNlLCBidWlsdGluX3JvdW5kKSAqLworICAgIGFzc2VydChQeV9JU19GSU5JVEUoeCkgJiYgeCAhPSAwLjApOworCisgICAgLyogZmluZCAyLXZhbHVhdGlvbiB2YWwgb2YgeCAqLworICAgIG0gPSBmcmV4cCh4LCAmdmFsKTsKKyAgICB3aGlsZSAobSAhPSBmbG9vcihtKSkgeworICAgICAgICBtICo9IDIuMDsKKyAgICAgICAgdmFsLS07CisgICAgfQorCisgICAgLyogZGV0ZXJtaW5lIHdoZXRoZXIgdGhpcyBpcyBhIGhhbGZ3YXkgY2FzZSAqLworICAgIGlmICh2YWwgPT0gLW5kaWdpdHMtMSkgeworICAgICAgICBpZiAobmRpZ2l0cyA+PSAwKQorICAgICAgICAgICAgaGFsZndheV9jYXNlID0gMTsKKyAgICAgICAgZWxzZSBpZiAobmRpZ2l0cyA+PSAtRklWRV9QT1dfTElNSVQpIHsKKyAgICAgICAgICAgIGRvdWJsZSBmaXZlX3BvdyA9IDEuMDsKKyAgICAgICAgICAgIGludCBpOworICAgICAgICAgICAgZm9yIChpPTA7IGkgPCAtbmRpZ2l0czsgaSsrKQorICAgICAgICAgICAgICAgIGZpdmVfcG93ICo9IDUuMDsKKyAgICAgICAgICAgIGhhbGZ3YXlfY2FzZSA9IGZtb2QoeCwgZml2ZV9wb3cpID09IDAuMDsKKyAgICAgICAgfQorICAgICAgICBlbHNlCisgICAgICAgICAgICBoYWxmd2F5X2Nhc2UgPSAwOworICAgIH0KKyAgICBlbHNlCisgICAgICAgIGhhbGZ3YXlfY2FzZSA9IDA7CisKKyAgICAvKiByb3VuZCB0byBhIGRlY2ltYWwgc3RyaW5nOyB1c2UgYW4gZXh0cmEgcGxhY2UgZm9yIGhhbGZ3YXkgY2FzZSAqLworICAgIF9QeV9TRVRfNTNCSVRfUFJFQ0lTSU9OX1NUQVJUOworICAgIGJ1ZiA9IF9QeV9kZ19kdG9hKHgsIDMsIG5kaWdpdHMraGFsZndheV9jYXNlLCAmZGVjcHQsICZzaWduLCAmYnVmX2VuZCk7CisgICAgX1B5X1NFVF81M0JJVF9QUkVDSVNJT05fRU5EOworICAgIGlmIChidWYgPT0gTlVMTCkgeworICAgICAgICBQeUVycl9Ob01lbW9yeSgpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgYnVmbGVuID0gYnVmX2VuZCAtIGJ1ZjsKKworICAgIC8qIGluIGhhbGZ3YXkgY2FzZSwgZG8gdGhlIHJvdW5kLWhhbGYtYXdheS1mcm9tLXplcm8gbWFudWFsbHkgKi8KKyAgICBpZiAoaGFsZndheV9jYXNlKSB7CisgICAgICAgIGludCBpLCBjYXJyeTsKKyAgICAgICAgLyogc2FuaXR5IGNoZWNrOiBfUHlfZGdfZHRvYSBzaG91bGQgbm90IGhhdmUgc3RyaXBwZWQKKyAgICAgICAgICAgYW55IHplcm9zIGZyb20gdGhlIHJlc3VsdDogdGhlcmUgc2hvdWxkIGJlIGV4YWN0bHkKKyAgICAgICAgICAgbmRpZ2l0cysxIHBsYWNlcyBmb2xsb3dpbmcgdGhlIGRlY2ltYWwgcG9pbnQsIGFuZAorICAgICAgICAgICB0aGUgbGFzdCBkaWdpdCBpbiB0aGUgYnVmZmVyIHNob3VsZCBiZSBhICc1Jy4qLworICAgICAgICBhc3NlcnQoYnVmbGVuIC0gZGVjcHQgPT0gbmRpZ2l0cysxKTsKKyAgICAgICAgYXNzZXJ0KGJ1ZltidWZsZW4tMV0gPT0gJzUnKTsKKworICAgICAgICAvKiBpbmNyZW1lbnQgYW5kIHNoaWZ0IHJpZ2h0IGF0IHRoZSBzYW1lIHRpbWUuICovCisgICAgICAgIGRlY3B0ICs9IDE7CisgICAgICAgIGNhcnJ5ID0gMTsKKyAgICAgICAgZm9yIChpPWJ1Zmxlbi0xOyBpLS0gPiAwOykgeworICAgICAgICAgICAgY2FycnkgKz0gYnVmW2ldIC0gJzAnOworICAgICAgICAgICAgYnVmW2krMV0gPSBjYXJyeSAlIDEwICsgJzAnOworICAgICAgICAgICAgY2FycnkgLz0gMTA7CisgICAgICAgIH0KKyAgICAgICAgYnVmWzBdID0gY2FycnkgKyAnMCc7CisgICAgfQorCisgICAgLyogR2V0IG5ldyBidWZmZXIgaWYgc2hvcnRidWYgaXMgdG9vIHNtYWxsLiAgU3BhY2UgbmVlZGVkIDw9IGJ1Zl9lbmQgLQorICAgICAgIGJ1ZiArIDg6ICgxIGV4dHJhIGZvciAnMCcsIDEgZm9yIHNpZ24sIDUgZm9yIGV4cCwgMSBmb3IgJ1wwJykuICovCisgICAgaWYgKGJ1ZmxlbiArIDggPiBteWJ1ZmxlbikgeworICAgICAgICBteWJ1ZmxlbiA9IGJ1Zmxlbis4OworICAgICAgICBteWJ1ZiA9IChjaGFyICopUHlNZW1fTWFsbG9jKG15YnVmbGVuKTsKKyAgICAgICAgaWYgKG15YnVmID09IE5VTEwpIHsKKyAgICAgICAgICAgIFB5RXJyX05vTWVtb3J5KCk7CisgICAgICAgICAgICBnb3RvIGV4aXQ7CisgICAgICAgIH0KKyAgICB9CisgICAgLyogY29weSBidWYgdG8gbXlidWYsIGFkZGluZyBleHBvbmVudCwgc2lnbiBhbmQgbGVhZGluZyAwICovCisgICAgUHlPU19zbnByaW50ZihteWJ1ZiwgbXlidWZsZW4sICIlczAlc2UlZCIsIChzaWduID8gIi0iIDogIiIpLAorICAgICAgICAgICAgICAgICAgYnVmLCBkZWNwdCAtIChpbnQpYnVmbGVuKTsKKworICAgIC8qIGFuZCBjb252ZXJ0IHRoZSByZXN1bHRpbmcgc3RyaW5nIGJhY2sgdG8gYSBkb3VibGUgKi8KKyAgICBlcnJubyA9IDA7CisgICAgX1B5X1NFVF81M0JJVF9QUkVDSVNJT05fU1RBUlQ7CisgICAgcm91bmRlZCA9IF9QeV9kZ19zdHJ0b2QobXlidWYsIE5VTEwpOworICAgIF9QeV9TRVRfNTNCSVRfUFJFQ0lTSU9OX0VORDsKKyAgICBpZiAoZXJybm8gPT0gRVJBTkdFICYmIGZhYnMocm91bmRlZCkgPj0gMS4pCisgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19PdmVyZmxvd0Vycm9yLAorICAgICAgICAgICAgICAgICAgICAgICAgInJvdW5kZWQgdmFsdWUgdG9vIGxhcmdlIHRvIHJlcHJlc2VudCIpOworICAgIGVsc2UKKyAgICAgICAgcmVzdWx0ID0gUHlGbG9hdF9Gcm9tRG91YmxlKHJvdW5kZWQpOworCisgICAgLyogZG9uZSBjb21wdXRpbmcgdmFsdWU7ICBub3cgY2xlYW4gdXAgKi8KKyAgICBpZiAobXlidWYgIT0gc2hvcnRidWYpCisgICAgICAgIFB5TWVtX0ZyZWUobXlidWYpOworICBleGl0OgorICAgIF9QeV9kZ19mcmVlZHRvYShidWYpOworICAgIHJldHVybiByZXN1bHQ7Cit9CisKKyN1bmRlZiBGSVZFX1BPV19MSU1JVAorCisjZWxzZSAvKiBQWV9OT19TSE9SVF9GTE9BVF9SRVBSICovCisKKy8qIGZhbGxiYWNrIHZlcnNpb24sIHRvIGJlIHVzZWQgd2hlbiBjb3JyZWN0bHkgcm91bmRlZCBiaW5hcnk8LT5kZWNpbWFsCisgICBjb252ZXJzaW9ucyBhcmVuJ3QgYXZhaWxhYmxlICovCisKK1B5T2JqZWN0ICoKK19QeV9kb3VibGVfcm91bmQoZG91YmxlIHgsIGludCBuZGlnaXRzKSB7CisgICAgZG91YmxlIHBvdzEsIHBvdzIsIHksIHo7CisgICAgaWYgKG5kaWdpdHMgPj0gMCkgeworICAgICAgICBpZiAobmRpZ2l0cyA+IDIyKSB7CisgICAgICAgICAgICAvKiBwb3cxIGFuZCBwb3cyIGFyZSBlYWNoIHNhZmUgZnJvbSBvdmVyZmxvdywgYnV0CisgICAgICAgICAgICAgICBwb3cxKnBvdzIgfj0gcG93KDEwLjAsIG5kaWdpdHMpIG1pZ2h0IG92ZXJmbG93ICovCisgICAgICAgICAgICBwb3cxID0gcG93KDEwLjAsIChkb3VibGUpKG5kaWdpdHMtMjIpKTsKKyAgICAgICAgICAgIHBvdzIgPSAxZTIyOworICAgICAgICB9CisgICAgICAgIGVsc2UgeworICAgICAgICAgICAgcG93MSA9IHBvdygxMC4wLCAoZG91YmxlKW5kaWdpdHMpOworICAgICAgICAgICAgcG93MiA9IDEuMDsKKyAgICAgICAgfQorICAgICAgICB5ID0gKHgqcG93MSkqcG93MjsKKyAgICAgICAgLyogaWYgeSBvdmVyZmxvd3MsIHRoZW4gcm91bmRlZCB2YWx1ZSBpcyBleGFjdGx5IHggKi8KKyAgICAgICAgaWYgKCFQeV9JU19GSU5JVEUoeSkpCisgICAgICAgICAgICByZXR1cm4gUHlGbG9hdF9Gcm9tRG91YmxlKHgpOworICAgIH0KKyAgICBlbHNlIHsKKyAgICAgICAgcG93MSA9IHBvdygxMC4wLCAoZG91YmxlKS1uZGlnaXRzKTsKKyAgICAgICAgcG93MiA9IDEuMDsgLyogdW51c2VkOyBzaWxlbmNlcyBhIGdjYyBjb21waWxlciB3YXJuaW5nICovCisgICAgICAgIHkgPSB4IC8gcG93MTsKKyAgICB9CisKKyAgICB6ID0gcm91bmQoeSk7CisgICAgaWYgKGZhYnMoeS16KSA9PSAwLjUpCisgICAgICAgIC8qIGhhbGZ3YXkgYmV0d2VlbiB0d28gaW50ZWdlcnM7IHVzZSByb3VuZC1hd2F5LWZyb20temVybyAqLworICAgICAgICB6ID0geSArIGNvcHlzaWduKDAuNSwgeSk7CisKKyAgICBpZiAobmRpZ2l0cyA+PSAwKQorICAgICAgICB6ID0gKHogLyBwb3cyKSAvIHBvdzE7CisgICAgZWxzZQorICAgICAgICB6ICo9IHBvdzE7CisKKyAgICAvKiBpZiBjb21wdXRhdGlvbiByZXN1bHRlZCBpbiBvdmVyZmxvdywgcmFpc2UgT3ZlcmZsb3dFcnJvciAqLworICAgIGlmICghUHlfSVNfRklOSVRFKHopKSB7CisgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19PdmVyZmxvd0Vycm9yLAorICAgICAgICAgICAgICAgICAgICAgICAgIm92ZXJmbG93IG9jY3VycmVkIGR1cmluZyByb3VuZCIpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisKKyAgICByZXR1cm4gUHlGbG9hdF9Gcm9tRG91YmxlKHopOworfQorCisjZW5kaWYgLyogUFlfTk9fU0hPUlRfRkxPQVRfUkVQUiAqLworCitzdGF0aWMgUHlPYmplY3QgKgorZmxvYXRfZmxvYXQoUHlPYmplY3QgKnYpCit7CisgICAgaWYgKFB5RmxvYXRfQ2hlY2tFeGFjdCh2KSkKKyAgICAgICAgUHlfSU5DUkVGKHYpOworICAgIGVsc2UKKyAgICAgICAgdiA9IFB5RmxvYXRfRnJvbURvdWJsZSgoKFB5RmxvYXRPYmplY3QgKil2KS0+b2JfZnZhbCk7CisgICAgcmV0dXJuIHY7Cit9CisKKy8qIHR1cm4gQVNDSUkgaGV4IGNoYXJhY3RlcnMgaW50byBpbnRlZ2VyIHZhbHVlcyBhbmQgdmljZSB2ZXJzYSAqLworCitzdGF0aWMgY2hhcgorY2hhcl9mcm9tX2hleChpbnQgeCkKK3sKKyAgICBhc3NlcnQoMCA8PSB4ICYmIHggPCAxNik7CisgICAgcmV0dXJuICIwMTIzNDU2Nzg5YWJjZGVmIlt4XTsKK30KKworc3RhdGljIGludAoraGV4X2Zyb21fY2hhcihjaGFyIGMpIHsKKyAgICBpbnQgeDsKKyAgICBzd2l0Y2goYykgeworICAgIGNhc2UgJzAnOgorICAgICAgICB4ID0gMDsKKyAgICAgICAgYnJlYWs7CisgICAgY2FzZSAnMSc6CisgICAgICAgIHggPSAxOworICAgICAgICBicmVhazsKKyAgICBjYXNlICcyJzoKKyAgICAgICAgeCA9IDI7CisgICAgICAgIGJyZWFrOworICAgIGNhc2UgJzMnOgorICAgICAgICB4ID0gMzsKKyAgICAgICAgYnJlYWs7CisgICAgY2FzZSAnNCc6CisgICAgICAgIHggPSA0OworICAgICAgICBicmVhazsKKyAgICBjYXNlICc1JzoKKyAgICAgICAgeCA9IDU7CisgICAgICAgIGJyZWFrOworICAgIGNhc2UgJzYnOgorICAgICAgICB4ID0gNjsKKyAgICAgICAgYnJlYWs7CisgICAgY2FzZSAnNyc6CisgICAgICAgIHggPSA3OworICAgICAgICBicmVhazsKKyAgICBjYXNlICc4JzoKKyAgICAgICAgeCA9IDg7CisgICAgICAgIGJyZWFrOworICAgIGNhc2UgJzknOgorICAgICAgICB4ID0gOTsKKyAgICAgICAgYnJlYWs7CisgICAgY2FzZSAnYSc6CisgICAgY2FzZSAnQSc6CisgICAgICAgIHggPSAxMDsKKyAgICAgICAgYnJlYWs7CisgICAgY2FzZSAnYic6CisgICAgY2FzZSAnQic6CisgICAgICAgIHggPSAxMTsKKyAgICAgICAgYnJlYWs7CisgICAgY2FzZSAnYyc6CisgICAgY2FzZSAnQyc6CisgICAgICAgIHggPSAxMjsKKyAgICAgICAgYnJlYWs7CisgICAgY2FzZSAnZCc6CisgICAgY2FzZSAnRCc6CisgICAgICAgIHggPSAxMzsKKyAgICAgICAgYnJlYWs7CisgICAgY2FzZSAnZSc6CisgICAgY2FzZSAnRSc6CisgICAgICAgIHggPSAxNDsKKyAgICAgICAgYnJlYWs7CisgICAgY2FzZSAnZic6CisgICAgY2FzZSAnRic6CisgICAgICAgIHggPSAxNTsKKyAgICAgICAgYnJlYWs7CisgICAgZGVmYXVsdDoKKyAgICAgICAgeCA9IC0xOworICAgICAgICBicmVhazsKKyAgICB9CisgICAgcmV0dXJuIHg7Cit9CisKKy8qIGNvbnZlcnQgYSBmbG9hdCB0byBhIGhleGFkZWNpbWFsIHN0cmluZyAqLworCisvKiBUT0hFWF9OQklUUyBpcyBEQkxfTUFOVF9ESUcgcm91bmRlZCB1cCB0byB0aGUgbmV4dCBpbnRlZ2VyCisgICBvZiB0aGUgZm9ybSA0aysxLiAqLworI2RlZmluZSBUT0hFWF9OQklUUyBEQkxfTUFOVF9ESUcgKyAzIC0gKERCTF9NQU5UX0RJRysyKSU0CisKK3N0YXRpYyBQeU9iamVjdCAqCitmbG9hdF9oZXgoUHlPYmplY3QgKnYpCit7CisgICAgZG91YmxlIHgsIG07CisgICAgaW50IGUsIHNoaWZ0LCBpLCBzaSwgZXNpZ247CisgICAgLyogU3BhY2UgZm9yIDErKFRPSEVYX05CSVRTLTEpLzQgZGlnaXRzLCBhIGRlY2ltYWwgcG9pbnQsIGFuZCB0aGUKKyAgICAgICB0cmFpbGluZyBOVUwgYnl0ZS4gKi8KKyAgICBjaGFyIHNbKFRPSEVYX05CSVRTLTEpLzQrM107CisKKyAgICBDT05WRVJUX1RPX0RPVUJMRSh2LCB4KTsKKworICAgIGlmIChQeV9JU19OQU4oeCkgfHwgUHlfSVNfSU5GSU5JVFkoeCkpCisgICAgICAgIHJldHVybiBmbG9hdF9zdHIoKFB5RmxvYXRPYmplY3QgKil2KTsKKworICAgIGlmICh4ID09IDAuMCkgeworICAgICAgICBpZiAoY29weXNpZ24oMS4wLCB4KSA9PSAtMS4wKQorICAgICAgICAgICAgcmV0dXJuIFB5U3RyaW5nX0Zyb21TdHJpbmcoIi0weDAuMHArMCIpOworICAgICAgICBlbHNlCisgICAgICAgICAgICByZXR1cm4gUHlTdHJpbmdfRnJvbVN0cmluZygiMHgwLjBwKzAiKTsKKyAgICB9CisKKyAgICBtID0gZnJleHAoZmFicyh4KSwgJmUpOworICAgIHNoaWZ0ID0gMSAtIE1BWChEQkxfTUlOX0VYUCAtIGUsIDApOworICAgIG0gPSBsZGV4cChtLCBzaGlmdCk7CisgICAgZSAtPSBzaGlmdDsKKworICAgIHNpID0gMDsKKyAgICBzW3NpXSA9IGNoYXJfZnJvbV9oZXgoKGludCltKTsKKyAgICBzaSsrOworICAgIG0gLT0gKGludCltOworICAgIHNbc2ldID0gJy4nOworICAgIHNpKys7CisgICAgZm9yIChpPTA7IGkgPCAoVE9IRVhfTkJJVFMtMSkvNDsgaSsrKSB7CisgICAgICAgIG0gKj0gMTYuMDsKKyAgICAgICAgc1tzaV0gPSBjaGFyX2Zyb21faGV4KChpbnQpbSk7CisgICAgICAgIHNpKys7CisgICAgICAgIG0gLT0gKGludCltOworICAgIH0KKyAgICBzW3NpXSA9ICdcMCc7CisKKyAgICBpZiAoZSA8IDApIHsKKyAgICAgICAgZXNpZ24gPSAoaW50KSctJzsKKyAgICAgICAgZSA9IC1lOworICAgIH0KKyAgICBlbHNlCisgICAgICAgIGVzaWduID0gKGludCknKyc7CisKKyAgICBpZiAoeCA8IDAuMCkKKyAgICAgICAgcmV0dXJuIFB5U3RyaW5nX0Zyb21Gb3JtYXQoIi0weCVzcCVjJWQiLCBzLCBlc2lnbiwgZSk7CisgICAgZWxzZQorICAgICAgICByZXR1cm4gUHlTdHJpbmdfRnJvbUZvcm1hdCgiMHglc3AlYyVkIiwgcywgZXNpZ24sIGUpOworfQorCitQeURvY19TVFJWQVIoZmxvYXRfaGV4X2RvYywKKyJmbG9hdC5oZXgoKSAtPiBzdHJpbmdcblwKK1xuXAorUmV0dXJuIGEgaGV4YWRlY2ltYWwgcmVwcmVzZW50YXRpb24gb2YgYSBmbG9hdGluZy1wb2ludCBudW1iZXIuXG5cCis+Pj4gKC0wLjEpLmhleCgpXG5cCisnLTB4MS45OTk5OTk5OTk5OTlhcC00J1xuXAorPj4+IDMuMTQxNTkuaGV4KClcblwKKycweDEuOTIxZjlmMDFiODY2ZXArMSciKTsKKworLyogQ2FzZS1pbnNlbnNpdGl2ZSBsb2NhbGUtaW5kZXBlbmRlbnQgc3RyaW5nIG1hdGNoIHVzZWQgZm9yIG5hbiBhbmQgaW5mCisgICBkZXRlY3Rpb24uIHQgc2hvdWxkIGJlIGxvd2VyLWNhc2UgYW5kIG51bGwtdGVybWluYXRlZC4gIFJldHVybiBhIG5vbnplcm8KKyAgIHJlc3VsdCBpZiB0aGUgZmlyc3Qgc3RybGVuKHQpIGNoYXJhY3RlcnMgb2YgcyBtYXRjaCB0IGFuZCAwIG90aGVyd2lzZS4gKi8KKworc3RhdGljIGludAorY2FzZV9pbnNlbnNpdGl2ZV9tYXRjaChjb25zdCBjaGFyICpzLCBjb25zdCBjaGFyICp0KQoreworICAgIHdoaWxlKCp0ICYmIFB5X1RPTE9XRVIoKnMpID09ICp0KSB7CisgICAgICAgIHMrKzsKKyAgICAgICAgdCsrOworICAgIH0KKyAgICByZXR1cm4gKnQgPyAwIDogMTsKK30KKworLyogQ29udmVydCBhIGhleGFkZWNpbWFsIHN0cmluZyB0byBhIGZsb2F0LiAqLworCitzdGF0aWMgUHlPYmplY3QgKgorZmxvYXRfZnJvbWhleChQeU9iamVjdCAqY2xzLCBQeU9iamVjdCAqYXJnKQoreworICAgIFB5T2JqZWN0ICpyZXN1bHRfYXNfZmxvYXQsICpyZXN1bHQ7CisgICAgZG91YmxlIHg7CisgICAgbG9uZyBleHAsIHRvcF9leHAsIGxzYiwga2V5X2RpZ2l0OworICAgIGNoYXIgKnMsICpjb2VmZl9zdGFydCwgKnNfc3RvcmUsICpjb2VmZl9lbmQsICpleHBfc3RhcnQsICpzX2VuZDsKKyAgICBpbnQgaGFsZl9lcHMsIGRpZ2l0LCByb3VuZF91cCwgc2lnbj0xOworICAgIFB5X3NzaXplX3QgbGVuZ3RoLCBuZGlnaXRzLCBmZGlnaXRzLCBpOworCisgICAgLyoKKyAgICAgKiBGb3IgdGhlIHNha2Ugb2Ygc2ltcGxpY2l0eSBhbmQgY29ycmVjdG5lc3MsIHdlIGltcG9zZSBhbiBhcnRpZmljaWFsCisgICAgICogbGltaXQgb24gbmRpZ2l0cywgdGhlIHRvdGFsIG51bWJlciBvZiBoZXggZGlnaXRzIGluIHRoZSBjb2VmZmljaWVudAorICAgICAqIFRoZSBsaW1pdCBpcyBjaG9zZW4gdG8gZW5zdXJlIHRoYXQsIHdyaXRpbmcgZXhwIGZvciB0aGUgZXhwb25lbnQsCisgICAgICoKKyAgICAgKiAgICgxKSBpZiBleHAgPiBMT05HX01BWC8yIHRoZW4gdGhlIHZhbHVlIG9mIHRoZSBoZXggc3RyaW5nIGlzCisgICAgICogICBndWFyYW50ZWVkIHRvIG92ZXJmbG93IChwcm92aWRlZCBpdCdzIG5vbnplcm8pCisgICAgICoKKyAgICAgKiAgICgyKSBpZiBleHAgPCBMT05HX01JTi8yIHRoZW4gdGhlIHZhbHVlIG9mIHRoZSBoZXggc3RyaW5nIGlzCisgICAgICogICBndWFyYW50ZWVkIHRvIHVuZGVyZmxvdyB0byAwLgorICAgICAqCisgICAgICogICAoMykgaWYgTE9OR19NSU4vMiA8PSBleHAgPD0gTE9OR19NQVgvMiB0aGVuIHRoZXJlJ3Mgbm8gZGFuZ2VyIG9mCisgICAgICogICBvdmVyZmxvdyBpbiB0aGUgY2FsY3VsYXRpb24gb2YgZXhwIGFuZCB0b3BfZXhwIGJlbG93LgorICAgICAqCisgICAgICogTW9yZSBzcGVjaWZpY2FsbHksIG5kaWdpdHMgaXMgYXNzdW1lZCB0byBzYXRpc2Z5IHRoZSBmb2xsb3dpbmcKKyAgICAgKiBpbmVxdWFsaXRpZXM6CisgICAgICoKKyAgICAgKiAgIDQqbmRpZ2l0cyA8PSBEQkxfTUlOX0VYUCAtIERCTF9NQU5UX0RJRyAtIExPTkdfTUlOLzIKKyAgICAgKiAgIDQqbmRpZ2l0cyA8PSBMT05HX01BWC8yICsgMSAtIERCTF9NQVhfRVhQCisgICAgICoKKyAgICAgKiBJZiBlaXRoZXIgb2YgdGhlc2UgaW5lcXVhbGl0aWVzIGlzIG5vdCBzYXRpc2ZpZWQsIGEgVmFsdWVFcnJvciBpcworICAgICAqIHJhaXNlZC4gIE90aGVyd2lzZSwgd3JpdGUgeCBmb3IgdGhlIHZhbHVlIG9mIHRoZSBoZXggc3RyaW5nLCBhbmQKKyAgICAgKiBhc3N1bWUgeCBpcyBub256ZXJvLiAgVGhlbgorICAgICAqCisgICAgICogICAyKiooZXhwLTQqbmRpZ2l0cykgPD0gfHh8IDwgMioqKGV4cCs0Km5kaWdpdHMpLgorICAgICAqCisgICAgICogTm93IGlmIGV4cCA+IExPTkdfTUFYLzIgdGhlbjoKKyAgICAgKgorICAgICAqICAgZXhwIC0gNCpuZGlnaXRzID49IExPTkdfTUFYLzIgKyAxIC0gKExPTkdfTUFYLzIgKyAxIC0gREJMX01BWF9FWFApCisgICAgICogICAgICAgICAgICAgICAgICAgID0gREJMX01BWF9FWFAKKyAgICAgKgorICAgICAqIHNvIHx4fCA+PSAyKipEQkxfTUFYX0VYUCwgd2hpY2ggaXMgdG9vIGxhcmdlIHRvIGJlIHN0b3JlZCBpbiBDCisgICAgICogZG91YmxlLCBzbyBvdmVyZmxvd3MuICBJZiBleHAgPCBMT05HX01JTi8yLCB0aGVuCisgICAgICoKKyAgICAgKiAgIGV4cCArIDQqbmRpZ2l0cyA8PSBMT05HX01JTi8yIC0gMSArICgKKyAgICAgKiAgICAgICAgICAgICAgICAgICAgICBEQkxfTUlOX0VYUCAtIERCTF9NQU5UX0RJRyAtIExPTkdfTUlOLzIpCisgICAgICogICAgICAgICAgICAgICAgICAgID0gREJMX01JTl9FWFAgLSBEQkxfTUFOVF9ESUcgLSAxCisgICAgICoKKyAgICAgKiBhbmQgc28gfHh8IDwgMioqKERCTF9NSU5fRVhQLURCTF9NQU5UX0RJRy0xKSwgaGVuY2UgdW5kZXJmbG93cyB0byAwCisgICAgICogd2hlbiBjb252ZXJ0ZWQgdG8gYSBDIGRvdWJsZS4KKyAgICAgKgorICAgICAqIEl0J3MgZWFzeSB0byBzaG93IHRoYXQgaWYgTE9OR19NSU4vMiA8PSBleHAgPD0gTE9OR19NQVgvMiB0aGVuIGJvdGgKKyAgICAgKiBleHArNCpuZGlnaXRzIGFuZCBleHAtNCpuZGlnaXRzIGFyZSB3aXRoaW4gdGhlIHJhbmdlIG9mIGEgbG9uZy4KKyAgICAgKi8KKworICAgIGlmIChQeVN0cmluZ19Bc1N0cmluZ0FuZFNpemUoYXJnLCAmcywgJmxlbmd0aCkpCisgICAgICAgIHJldHVybiBOVUxMOworICAgIHNfZW5kID0gcyArIGxlbmd0aDsKKworICAgIC8qKioqKioqKioqKioqKioqKioqKgorICAgICAqIFBhcnNlIHRoZSBzdHJpbmcgKgorICAgICAqKioqKioqKioqKioqKioqKioqKi8KKworICAgIC8qIGxlYWRpbmcgd2hpdGVzcGFjZSBhbmQgb3B0aW9uYWwgc2lnbiAqLworICAgIHdoaWxlIChQeV9JU1NQQUNFKCpzKSkKKyAgICAgICAgcysrOworICAgIGlmICgqcyA9PSAnLScpIHsKKyAgICAgICAgcysrOworICAgICAgICBzaWduID0gLTE7CisgICAgfQorICAgIGVsc2UgaWYgKCpzID09ICcrJykKKyAgICAgICAgcysrOworCisgICAgLyogaW5maW5pdGllcyBhbmQgbmFucyAqLworICAgIGlmICgqcyA9PSAnaScgfHwgKnMgPT0gJ0knKSB7CisgICAgICAgIGlmICghY2FzZV9pbnNlbnNpdGl2ZV9tYXRjaChzKzEsICJuZiIpKQorICAgICAgICAgICAgZ290byBwYXJzZV9lcnJvcjsKKyAgICAgICAgcyArPSAzOworICAgICAgICB4ID0gUHlfSFVHRV9WQUw7CisgICAgICAgIGlmIChjYXNlX2luc2Vuc2l0aXZlX21hdGNoKHMsICJpbml0eSIpKQorICAgICAgICAgICAgcyArPSA1OworICAgICAgICBnb3RvIGZpbmlzaGVkOworICAgIH0KKyAgICBpZiAoKnMgPT0gJ24nIHx8ICpzID09ICdOJykgeworICAgICAgICBpZiAoIWNhc2VfaW5zZW5zaXRpdmVfbWF0Y2gocysxLCAiYW4iKSkKKyAgICAgICAgICAgIGdvdG8gcGFyc2VfZXJyb3I7CisgICAgICAgIHMgKz0gMzsKKyAgICAgICAgeCA9IFB5X05BTjsKKyAgICAgICAgZ290byBmaW5pc2hlZDsKKyAgICB9CisKKyAgICAvKiBbMHhdICovCisgICAgc19zdG9yZSA9IHM7CisgICAgaWYgKCpzID09ICcwJykgeworICAgICAgICBzKys7CisgICAgICAgIGlmICgqcyA9PSAneCcgfHwgKnMgPT0gJ1gnKQorICAgICAgICAgICAgcysrOworICAgICAgICBlbHNlCisgICAgICAgICAgICBzID0gc19zdG9yZTsKKyAgICB9CisKKyAgICAvKiBjb2VmZmljaWVudDogPGludGVnZXI+IFsuIDxmcmFjdGlvbj5dICovCisgICAgY29lZmZfc3RhcnQgPSBzOworICAgIHdoaWxlIChoZXhfZnJvbV9jaGFyKCpzKSA+PSAwKQorICAgICAgICBzKys7CisgICAgc19zdG9yZSA9IHM7CisgICAgaWYgKCpzID09ICcuJykgeworICAgICAgICBzKys7CisgICAgICAgIHdoaWxlIChoZXhfZnJvbV9jaGFyKCpzKSA+PSAwKQorICAgICAgICAgICAgcysrOworICAgICAgICBjb2VmZl9lbmQgPSBzLTE7CisgICAgfQorICAgIGVsc2UKKyAgICAgICAgY29lZmZfZW5kID0gczsKKworICAgIC8qIG5kaWdpdHMgPSB0b3RhbCAjIG9mIGhleCBkaWdpdHM7IGZkaWdpdHMgPSAjIGFmdGVyIHBvaW50ICovCisgICAgbmRpZ2l0cyA9IGNvZWZmX2VuZCAtIGNvZWZmX3N0YXJ0OworICAgIGZkaWdpdHMgPSBjb2VmZl9lbmQgLSBzX3N0b3JlOworICAgIGlmIChuZGlnaXRzID09IDApCisgICAgICAgIGdvdG8gcGFyc2VfZXJyb3I7CisgICAgaWYgKG5kaWdpdHMgPiBNSU4oREJMX01JTl9FWFAgLSBEQkxfTUFOVF9ESUcgLSBMT05HX01JTi8yLAorICAgICAgICAgICAgICAgICAgICAgIExPTkdfTUFYLzIgKyAxIC0gREJMX01BWF9FWFApLzQpCisgICAgICAgIGdvdG8gaW5zYW5lX2xlbmd0aF9lcnJvcjsKKworICAgIC8qIFtwIDxleHBvbmVudD5dICovCisgICAgaWYgKCpzID09ICdwJyB8fCAqcyA9PSAnUCcpIHsKKyAgICAgICAgcysrOworICAgICAgICBleHBfc3RhcnQgPSBzOworICAgICAgICBpZiAoKnMgPT0gJy0nIHx8ICpzID09ICcrJykKKyAgICAgICAgICAgIHMrKzsKKyAgICAgICAgaWYgKCEoJzAnIDw9ICpzICYmICpzIDw9ICc5JykpCisgICAgICAgICAgICBnb3RvIHBhcnNlX2Vycm9yOworICAgICAgICBzKys7CisgICAgICAgIHdoaWxlICgnMCcgPD0gKnMgJiYgKnMgPD0gJzknKQorICAgICAgICAgICAgcysrOworICAgICAgICBleHAgPSBzdHJ0b2woZXhwX3N0YXJ0LCBOVUxMLCAxMCk7CisgICAgfQorICAgIGVsc2UKKyAgICAgICAgZXhwID0gMDsKKworLyogZm9yIDAgPD0gaiA8IG5kaWdpdHMsIEhFWF9ESUdJVChqKSBnaXZlcyB0aGUganRoIG1vc3Qgc2lnbmlmaWNhbnQgZGlnaXQgKi8KKyNkZWZpbmUgSEVYX0RJR0lUKGopIGhleF9mcm9tX2NoYXIoKigoaikgPCBmZGlnaXRzID8gICAgICAgICAgICBcCisgICAgICAgICAgICAgICAgICAgICBjb2VmZl9lbmQtKGopIDogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgICAgICAgICAgICAgICBjb2VmZl9lbmQtMS0oaikpKQorCisgICAgLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKKyAgICAgKiBDb21wdXRlIHJvdW5kZWQgdmFsdWUgb2YgdGhlIGhleCBzdHJpbmcgKgorICAgICAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLworCisgICAgLyogRGlzY2FyZCBsZWFkaW5nIHplcm9zLCBhbmQgY2F0Y2ggZXh0cmVtZSBvdmVyZmxvdyBhbmQgdW5kZXJmbG93ICovCisgICAgd2hpbGUgKG5kaWdpdHMgPiAwICYmIEhFWF9ESUdJVChuZGlnaXRzLTEpID09IDApCisgICAgICAgIG5kaWdpdHMtLTsKKyAgICBpZiAobmRpZ2l0cyA9PSAwIHx8IGV4cCA8IExPTkdfTUlOLzIpIHsKKyAgICAgICAgeCA9IDAuMDsKKyAgICAgICAgZ290byBmaW5pc2hlZDsKKyAgICB9CisgICAgaWYgKGV4cCA+IExPTkdfTUFYLzIpCisgICAgICAgIGdvdG8gb3ZlcmZsb3dfZXJyb3I7CisKKyAgICAvKiBBZGp1c3QgZXhwb25lbnQgZm9yIGZyYWN0aW9uYWwgcGFydC4gKi8KKyAgICBleHAgPSBleHAgLSA0KigobG9uZylmZGlnaXRzKTsKKworICAgIC8qIHRvcF9leHAgPSAxIG1vcmUgdGhhbiBleHBvbmVudCBvZiBtb3N0IHNpZy4gYml0IG9mIGNvZWZmaWNpZW50ICovCisgICAgdG9wX2V4cCA9IGV4cCArIDQqKChsb25nKW5kaWdpdHMgLSAxKTsKKyAgICBmb3IgKGRpZ2l0ID0gSEVYX0RJR0lUKG5kaWdpdHMtMSk7IGRpZ2l0ICE9IDA7IGRpZ2l0IC89IDIpCisgICAgICAgIHRvcF9leHArKzsKKworICAgIC8qIGNhdGNoIGFsbW9zdCBhbGwgbm9uZXh0cmVtZSBjYXNlcyBvZiBvdmVyZmxvdyBhbmQgdW5kZXJmbG93IGhlcmUgKi8KKyAgICBpZiAodG9wX2V4cCA8IERCTF9NSU5fRVhQIC0gREJMX01BTlRfRElHKSB7CisgICAgICAgIHggPSAwLjA7CisgICAgICAgIGdvdG8gZmluaXNoZWQ7CisgICAgfQorICAgIGlmICh0b3BfZXhwID4gREJMX01BWF9FWFApCisgICAgICAgIGdvdG8gb3ZlcmZsb3dfZXJyb3I7CisKKyAgICAvKiBsc2IgPSBleHBvbmVudCBvZiBsZWFzdCBzaWduaWZpY2FudCBiaXQgb2YgdGhlICpyb3VuZGVkKiB2YWx1ZS4KKyAgICAgICBUaGlzIGlzIHRvcF9leHAgLSBEQkxfTUFOVF9ESUcgdW5sZXNzIHJlc3VsdCBpcyBzdWJub3JtYWwuICovCisgICAgbHNiID0gTUFYKHRvcF9leHAsIChsb25nKURCTF9NSU5fRVhQKSAtIERCTF9NQU5UX0RJRzsKKworICAgIHggPSAwLjA7CisgICAgaWYgKGV4cCA+PSBsc2IpIHsKKyAgICAgICAgLyogbm8gcm91bmRpbmcgcmVxdWlyZWQgKi8KKyAgICAgICAgZm9yIChpID0gbmRpZ2l0cy0xOyBpID49IDA7IGktLSkKKyAgICAgICAgICAgIHggPSAxNi4wKnggKyBIRVhfRElHSVQoaSk7CisgICAgICAgIHggPSBsZGV4cCh4LCAoaW50KShleHApKTsKKyAgICAgICAgZ290byBmaW5pc2hlZDsKKyAgICB9CisgICAgLyogcm91bmRpbmcgcmVxdWlyZWQuICBrZXlfZGlnaXQgaXMgdGhlIGluZGV4IG9mIHRoZSBoZXggZGlnaXQKKyAgICAgICBjb250YWluaW5nIHRoZSBmaXJzdCBiaXQgdG8gYmUgcm91bmRlZCBhd2F5LiAqLworICAgIGhhbGZfZXBzID0gMSA8PCAoaW50KSgobHNiIC0gZXhwIC0gMSkgJSA0KTsKKyAgICBrZXlfZGlnaXQgPSAobHNiIC0gZXhwIC0gMSkgLyA0OworICAgIGZvciAoaSA9IG5kaWdpdHMtMTsgaSA+IGtleV9kaWdpdDsgaS0tKQorICAgICAgICB4ID0gMTYuMCp4ICsgSEVYX0RJR0lUKGkpOworICAgIGRpZ2l0ID0gSEVYX0RJR0lUKGtleV9kaWdpdCk7CisgICAgeCA9IDE2LjAqeCArIChkb3VibGUpKGRpZ2l0ICYgKDE2LTIqaGFsZl9lcHMpKTsKKworICAgIC8qIHJvdW5kLWhhbGYtZXZlbjogcm91bmQgdXAgaWYgYml0IGxzYi0xIGlzIDEgYW5kIGF0IGxlYXN0IG9uZSBvZgorICAgICAgIGJpdHMgbHNiLCBsc2ItMiwgbHNiLTMsIGxzYi00LCAuLi4gaXMgMS4gKi8KKyAgICBpZiAoKGRpZ2l0ICYgaGFsZl9lcHMpICE9IDApIHsKKyAgICAgICAgcm91bmRfdXAgPSAwOworICAgICAgICBpZiAoKGRpZ2l0ICYgKDMqaGFsZl9lcHMtMSkpICE9IDAgfHwKKyAgICAgICAgICAgIChoYWxmX2VwcyA9PSA4ICYmIChIRVhfRElHSVQoa2V5X2RpZ2l0KzEpICYgMSkgIT0gMCkpCisgICAgICAgICAgICByb3VuZF91cCA9IDE7CisgICAgICAgIGVsc2UKKyAgICAgICAgICAgIGZvciAoaSA9IGtleV9kaWdpdC0xOyBpID49IDA7IGktLSkKKyAgICAgICAgICAgICAgICBpZiAoSEVYX0RJR0lUKGkpICE9IDApIHsKKyAgICAgICAgICAgICAgICAgICAgcm91bmRfdXAgPSAxOworICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgIGlmIChyb3VuZF91cCA9PSAxKSB7CisgICAgICAgICAgICB4ICs9IDIqaGFsZl9lcHM7CisgICAgICAgICAgICBpZiAodG9wX2V4cCA9PSBEQkxfTUFYX0VYUCAmJgorICAgICAgICAgICAgICAgIHggPT0gbGRleHAoKGRvdWJsZSkoMipoYWxmX2VwcyksIERCTF9NQU5UX0RJRykpCisgICAgICAgICAgICAgICAgLyogb3ZlcmZsb3cgY29ybmVyIGNhc2U6IHByZS1yb3VuZGVkIHZhbHVlIDwKKyAgICAgICAgICAgICAgICAgICAyKipEQkxfTUFYX0VYUDsgcm91bmRlZD0yKipEQkxfTUFYX0VYUC4gKi8KKyAgICAgICAgICAgICAgICBnb3RvIG92ZXJmbG93X2Vycm9yOworICAgICAgICB9CisgICAgfQorICAgIHggPSBsZGV4cCh4LCAoaW50KShleHArNCprZXlfZGlnaXQpKTsKKworICBmaW5pc2hlZDoKKyAgICAvKiBvcHRpb25hbCB0cmFpbGluZyB3aGl0ZXNwYWNlIGxlYWRpbmcgdG8gdGhlIGVuZCBvZiB0aGUgc3RyaW5nICovCisgICAgd2hpbGUgKFB5X0lTU1BBQ0UoKnMpKQorICAgICAgICBzKys7CisgICAgaWYgKHMgIT0gc19lbmQpCisgICAgICAgIGdvdG8gcGFyc2VfZXJyb3I7CisgICAgcmVzdWx0X2FzX2Zsb2F0ID0gUHlfQnVpbGRWYWx1ZSgiKGQpIiwgc2lnbiAqIHgpOworICAgIGlmIChyZXN1bHRfYXNfZmxvYXQgPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgcmVzdWx0ID0gUHlPYmplY3RfQ2FsbE9iamVjdChjbHMsIHJlc3VsdF9hc19mbG9hdCk7CisgICAgUHlfREVDUkVGKHJlc3VsdF9hc19mbG9hdCk7CisgICAgcmV0dXJuIHJlc3VsdDsKKworICBvdmVyZmxvd19lcnJvcjoKKyAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfT3ZlcmZsb3dFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgImhleGFkZWNpbWFsIHZhbHVlIHRvbyBsYXJnZSB0byByZXByZXNlbnQgYXMgYSBmbG9hdCIpOworICAgIHJldHVybiBOVUxMOworCisgIHBhcnNlX2Vycm9yOgorICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19WYWx1ZUVycm9yLAorICAgICAgICAgICAgICAgICAgICAiaW52YWxpZCBoZXhhZGVjaW1hbCBmbG9hdGluZy1wb2ludCBzdHJpbmciKTsKKyAgICByZXR1cm4gTlVMTDsKKworICBpbnNhbmVfbGVuZ3RoX2Vycm9yOgorICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19WYWx1ZUVycm9yLAorICAgICAgICAgICAgICAgICAgICAiaGV4YWRlY2ltYWwgc3RyaW5nIHRvbyBsb25nIHRvIGNvbnZlcnQiKTsKKyAgICByZXR1cm4gTlVMTDsKK30KKworUHlEb2NfU1RSVkFSKGZsb2F0X2Zyb21oZXhfZG9jLAorImZsb2F0LmZyb21oZXgoc3RyaW5nKSAtPiBmbG9hdFxuXAorXG5cCitDcmVhdGUgYSBmbG9hdGluZy1wb2ludCBudW1iZXIgZnJvbSBhIGhleGFkZWNpbWFsIHN0cmluZy5cblwKKz4+PiBmbG9hdC5mcm9taGV4KCcweDEuZmZmZnAxMCcpXG5cCisyMDQ3Ljk4NDM3NVxuXAorPj4+IGZsb2F0LmZyb21oZXgoJy0weDFwLTEwNzQnKVxuXAorLTQuOTQwNjU2NDU4NDEyNDY1NGUtMzI0Iik7CisKKworc3RhdGljIFB5T2JqZWN0ICoKK2Zsb2F0X2FzX2ludGVnZXJfcmF0aW8oUHlPYmplY3QgKnYsIFB5T2JqZWN0ICp1bnVzZWQpCit7CisgICAgZG91YmxlIHNlbGY7CisgICAgZG91YmxlIGZsb2F0X3BhcnQ7CisgICAgaW50IGV4cG9uZW50OworICAgIGludCBpOworCisgICAgUHlPYmplY3QgKnByZXY7CisgICAgUHlPYmplY3QgKnB5X2V4cG9uZW50ID0gTlVMTDsKKyAgICBQeU9iamVjdCAqbnVtZXJhdG9yID0gTlVMTDsKKyAgICBQeU9iamVjdCAqZGVub21pbmF0b3IgPSBOVUxMOworICAgIFB5T2JqZWN0ICpyZXN1bHRfcGFpciA9IE5VTEw7CisgICAgUHlOdW1iZXJNZXRob2RzICpsb25nX21ldGhvZHMgPSBQeUxvbmdfVHlwZS50cF9hc19udW1iZXI7CisKKyNkZWZpbmUgSU5QTEFDRV9VUERBVEUob2JqLCBjYWxsKSBcCisgICAgcHJldiA9IG9iajsgXAorICAgIG9iaiA9IGNhbGw7IFwKKyAgICBQeV9ERUNSRUYocHJldik7IFwKKworICAgIENPTlZFUlRfVE9fRE9VQkxFKHYsIHNlbGYpOworCisgICAgaWYgKFB5X0lTX0lORklOSVRZKHNlbGYpKSB7CisgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfT3ZlcmZsb3dFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICAiQ2Fubm90IHBhc3MgaW5maW5pdHkgdG8gZmxvYXQuYXNfaW50ZWdlcl9yYXRpby4iKTsKKyAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyNpZmRlZiBQeV9OQU4KKyAgICBpZiAoUHlfSVNfTkFOKHNlbGYpKSB7CisgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfVmFsdWVFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICAiQ2Fubm90IHBhc3MgTmFOIHRvIGZsb2F0LmFzX2ludGVnZXJfcmF0aW8uIik7CisgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisjZW5kaWYKKworICAgIFB5RlBFX1NUQVJUX1BST1RFQ1QoImFzX2ludGVnZXJfcmF0aW8iLCBnb3RvIGVycm9yKTsKKyAgICBmbG9hdF9wYXJ0ID0gZnJleHAoc2VsZiwgJmV4cG9uZW50KTsgICAgICAgIC8qIHNlbGYgPT0gZmxvYXRfcGFydCAqIDIqKmV4cG9uZW50IGV4YWN0bHkgKi8KKyAgICBQeUZQRV9FTkRfUFJPVEVDVChmbG9hdF9wYXJ0KTsKKworICAgIGZvciAoaT0wOyBpPDMwMCAmJiBmbG9hdF9wYXJ0ICE9IGZsb29yKGZsb2F0X3BhcnQpIDsgaSsrKSB7CisgICAgICAgIGZsb2F0X3BhcnQgKj0gMi4wOworICAgICAgICBleHBvbmVudC0tOworICAgIH0KKyAgICAvKiBzZWxmID09IGZsb2F0X3BhcnQgKiAyKipleHBvbmVudCBleGFjdGx5IGFuZCBmbG9hdF9wYXJ0IGlzIGludGVncmFsLgorICAgICAgIElmIEZMVF9SQURJWCAhPSAyLCB0aGUgMzAwIHN0ZXBzIG1heSBsZWF2ZSBhIHRpbnkgZnJhY3Rpb25hbCBwYXJ0CisgICAgICAgdG8gYmUgdHJ1bmNhdGVkIGJ5IFB5TG9uZ19Gcm9tRG91YmxlKCkuICovCisKKyAgICBudW1lcmF0b3IgPSBQeUxvbmdfRnJvbURvdWJsZShmbG9hdF9wYXJ0KTsKKyAgICBpZiAobnVtZXJhdG9yID09IE5VTEwpIGdvdG8gZXJyb3I7CisKKyAgICAvKiBmb2xkIGluIDIqKmV4cG9uZW50ICovCisgICAgZGVub21pbmF0b3IgPSBQeUxvbmdfRnJvbUxvbmcoMSk7CisgICAgcHlfZXhwb25lbnQgPSBQeUxvbmdfRnJvbUxvbmcobGFicygobG9uZylleHBvbmVudCkpOworICAgIGlmIChweV9leHBvbmVudCA9PSBOVUxMKSBnb3RvIGVycm9yOworICAgIElOUExBQ0VfVVBEQVRFKHB5X2V4cG9uZW50LAorICAgICAgICAgICAgICAgICAgIGxvbmdfbWV0aG9kcy0+bmJfbHNoaWZ0KGRlbm9taW5hdG9yLCBweV9leHBvbmVudCkpOworICAgIGlmIChweV9leHBvbmVudCA9PSBOVUxMKSBnb3RvIGVycm9yOworICAgIGlmIChleHBvbmVudCA+IDApIHsKKyAgICAgICAgSU5QTEFDRV9VUERBVEUobnVtZXJhdG9yLAorICAgICAgICAgICAgICAgICAgICAgICBsb25nX21ldGhvZHMtPm5iX211bHRpcGx5KG51bWVyYXRvciwgcHlfZXhwb25lbnQpKTsKKyAgICAgICAgaWYgKG51bWVyYXRvciA9PSBOVUxMKSBnb3RvIGVycm9yOworICAgIH0KKyAgICBlbHNlIHsKKyAgICAgICAgUHlfREVDUkVGKGRlbm9taW5hdG9yKTsKKyAgICAgICAgZGVub21pbmF0b3IgPSBweV9leHBvbmVudDsKKyAgICAgICAgcHlfZXhwb25lbnQgPSBOVUxMOworICAgIH0KKworICAgIC8qIFJldHVybnMgaW50cyBpbnN0ZWFkIG9mIGxvbmdzIHdoZXJlIHBvc3NpYmxlICovCisgICAgSU5QTEFDRV9VUERBVEUobnVtZXJhdG9yLCBQeU51bWJlcl9JbnQobnVtZXJhdG9yKSk7CisgICAgaWYgKG51bWVyYXRvciA9PSBOVUxMKSBnb3RvIGVycm9yOworICAgIElOUExBQ0VfVVBEQVRFKGRlbm9taW5hdG9yLCBQeU51bWJlcl9JbnQoZGVub21pbmF0b3IpKTsKKyAgICBpZiAoZGVub21pbmF0b3IgPT0gTlVMTCkgZ290byBlcnJvcjsKKworICAgIHJlc3VsdF9wYWlyID0gUHlUdXBsZV9QYWNrKDIsIG51bWVyYXRvciwgZGVub21pbmF0b3IpOworCisjdW5kZWYgSU5QTEFDRV9VUERBVEUKK2Vycm9yOgorICAgIFB5X1hERUNSRUYocHlfZXhwb25lbnQpOworICAgIFB5X1hERUNSRUYoZGVub21pbmF0b3IpOworICAgIFB5X1hERUNSRUYobnVtZXJhdG9yKTsKKyAgICByZXR1cm4gcmVzdWx0X3BhaXI7Cit9CisKK1B5RG9jX1NUUlZBUihmbG9hdF9hc19pbnRlZ2VyX3JhdGlvX2RvYywKKyJmbG9hdC5hc19pbnRlZ2VyX3JhdGlvKCkgLT4gKGludCwgaW50KVxuIgorIlxuIgorIlJldHVybnMgYSBwYWlyIG9mIGludGVnZXJzLCB3aG9zZSByYXRpbyBpcyBleGFjdGx5IGVxdWFsIHRvIHRoZSBvcmlnaW5hbFxuIgorImZsb2F0IGFuZCB3aXRoIGEgcG9zaXRpdmUgZGVub21pbmF0b3IuXG4iCisiUmFpc2VzIE92ZXJmbG93RXJyb3Igb24gaW5maW5pdGllcyBhbmQgYSBWYWx1ZUVycm9yIG9uIE5hTnMuXG4iCisiXG4iCisiPj4+ICgxMC4wKS5hc19pbnRlZ2VyX3JhdGlvKClcbiIKKyIoMTAsIDEpXG4iCisiPj4+ICgwLjApLmFzX2ludGVnZXJfcmF0aW8oKVxuIgorIigwLCAxKVxuIgorIj4+PiAoLS4yNSkuYXNfaW50ZWdlcl9yYXRpbygpXG4iCisiKC0xLCA0KSIpOworCisKK3N0YXRpYyBQeU9iamVjdCAqCitmbG9hdF9zdWJ0eXBlX25ldyhQeVR5cGVPYmplY3QgKnR5cGUsIFB5T2JqZWN0ICphcmdzLCBQeU9iamVjdCAqa3dkcyk7CisKK3N0YXRpYyBQeU9iamVjdCAqCitmbG9hdF9uZXcoUHlUeXBlT2JqZWN0ICp0eXBlLCBQeU9iamVjdCAqYXJncywgUHlPYmplY3QgKmt3ZHMpCit7CisgICAgUHlPYmplY3QgKnggPSBQeV9GYWxzZTsgLyogSW50ZWdlciB6ZXJvICovCisgICAgc3RhdGljIGNoYXIgKmt3bGlzdFtdID0geyJ4IiwgMH07CisKKyAgICBpZiAodHlwZSAhPSAmUHlGbG9hdF9UeXBlKQorICAgICAgICByZXR1cm4gZmxvYXRfc3VidHlwZV9uZXcodHlwZSwgYXJncywga3dkcyk7IC8qIFdpbXAgb3V0ICovCisgICAgaWYgKCFQeUFyZ19QYXJzZVR1cGxlQW5kS2V5d29yZHMoYXJncywga3dkcywgInxPOmZsb2F0Iiwga3dsaXN0LCAmeCkpCisgICAgICAgIHJldHVybiBOVUxMOworICAgIC8qIElmIGl0J3MgYSBzdHJpbmcsIGJ1dCBub3QgYSBzdHJpbmcgc3ViY2xhc3MsIHVzZQorICAgICAgIFB5RmxvYXRfRnJvbVN0cmluZy4gKi8KKyAgICBpZiAoUHlTdHJpbmdfQ2hlY2tFeGFjdCh4KSkKKyAgICAgICAgcmV0dXJuIFB5RmxvYXRfRnJvbVN0cmluZyh4LCBOVUxMKTsKKyAgICByZXR1cm4gUHlOdW1iZXJfRmxvYXQoeCk7Cit9CisKKy8qIFdpbXB5LCBzbG93IGFwcHJvYWNoIHRvIHRwX25ldyBjYWxscyBmb3Igc3VidHlwZXMgb2YgZmxvYXQ6CisgICBmaXJzdCBjcmVhdGUgYSByZWd1bGFyIGZsb2F0IGZyb20gd2hhdGV2ZXIgYXJndW1lbnRzIHdlIGdvdCwKKyAgIHRoZW4gYWxsb2NhdGUgYSBzdWJ0eXBlIGluc3RhbmNlIGFuZCBpbml0aWFsaXplIGl0cyBvYl9mdmFsCisgICBmcm9tIHRoZSByZWd1bGFyIGZsb2F0LiAgVGhlIHJlZ3VsYXIgZmxvYXQgaXMgdGhlbiB0aHJvd24gYXdheS4KKyovCitzdGF0aWMgUHlPYmplY3QgKgorZmxvYXRfc3VidHlwZV9uZXcoUHlUeXBlT2JqZWN0ICp0eXBlLCBQeU9iamVjdCAqYXJncywgUHlPYmplY3QgKmt3ZHMpCit7CisgICAgUHlPYmplY3QgKnRtcCwgKm5ld29iajsKKworICAgIGFzc2VydChQeVR5cGVfSXNTdWJ0eXBlKHR5cGUsICZQeUZsb2F0X1R5cGUpKTsKKyAgICB0bXAgPSBmbG9hdF9uZXcoJlB5RmxvYXRfVHlwZSwgYXJncywga3dkcyk7CisgICAgaWYgKHRtcCA9PSBOVUxMKQorICAgICAgICByZXR1cm4gTlVMTDsKKyAgICBhc3NlcnQoUHlGbG9hdF9DaGVja0V4YWN0KHRtcCkpOworICAgIG5ld29iaiA9IHR5cGUtPnRwX2FsbG9jKHR5cGUsIDApOworICAgIGlmIChuZXdvYmogPT0gTlVMTCkgeworICAgICAgICBQeV9ERUNSRUYodG1wKTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgICgoUHlGbG9hdE9iamVjdCAqKW5ld29iaiktPm9iX2Z2YWwgPSAoKFB5RmxvYXRPYmplY3QgKil0bXApLT5vYl9mdmFsOworICAgIFB5X0RFQ1JFRih0bXApOworICAgIHJldHVybiBuZXdvYmo7Cit9CisKK3N0YXRpYyBQeU9iamVjdCAqCitmbG9hdF9nZXRuZXdhcmdzKFB5RmxvYXRPYmplY3QgKnYpCit7CisgICAgcmV0dXJuIFB5X0J1aWxkVmFsdWUoIihkKSIsIHYtPm9iX2Z2YWwpOworfQorCisvKiB0aGlzIGlzIGZvciB0aGUgYmVuZWZpdCBvZiB0aGUgcGFjay91bnBhY2sgcm91dGluZXMgYmVsb3cgKi8KKwordHlwZWRlZiBlbnVtIHsKKyAgICB1bmtub3duX2Zvcm1hdCwgaWVlZV9iaWdfZW5kaWFuX2Zvcm1hdCwgaWVlZV9saXR0bGVfZW5kaWFuX2Zvcm1hdAorfSBmbG9hdF9mb3JtYXRfdHlwZTsKKworc3RhdGljIGZsb2F0X2Zvcm1hdF90eXBlIGRvdWJsZV9mb3JtYXQsIGZsb2F0X2Zvcm1hdDsKK3N0YXRpYyBmbG9hdF9mb3JtYXRfdHlwZSBkZXRlY3RlZF9kb3VibGVfZm9ybWF0LCBkZXRlY3RlZF9mbG9hdF9mb3JtYXQ7CisKK3N0YXRpYyBQeU9iamVjdCAqCitmbG9hdF9nZXRmb3JtYXQoUHlUeXBlT2JqZWN0ICp2LCBQeU9iamVjdCogYXJnKQoreworICAgIGNoYXIqIHM7CisgICAgZmxvYXRfZm9ybWF0X3R5cGUgcjsKKworICAgIGlmICghUHlTdHJpbmdfQ2hlY2soYXJnKSkgeworICAgICAgICBQeUVycl9Gb3JtYXQoUHlFeGNfVHlwZUVycm9yLAorICAgICAgICAgIl9fZ2V0Zm9ybWF0X18oKSBhcmd1bWVudCBtdXN0IGJlIHN0cmluZywgbm90ICUuNTAwcyIsCisgICAgICAgICAgICAgICAgICAgICAgICAgUHlfVFlQRShhcmcpLT50cF9uYW1lKTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIHMgPSBQeVN0cmluZ19BU19TVFJJTkcoYXJnKTsKKyAgICBpZiAoc3RyY21wKHMsICJkb3VibGUiKSA9PSAwKSB7CisgICAgICAgIHIgPSBkb3VibGVfZm9ybWF0OworICAgIH0KKyAgICBlbHNlIGlmIChzdHJjbXAocywgImZsb2F0IikgPT0gMCkgeworICAgICAgICByID0gZmxvYXRfZm9ybWF0OworICAgIH0KKyAgICBlbHNlIHsKKyAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1ZhbHVlRXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAgICAiX19nZXRmb3JtYXRfXygpIGFyZ3VtZW50IDEgbXVzdCBiZSAiCisgICAgICAgICAgICAgICAgICAgICAgICAiJ2RvdWJsZScgb3IgJ2Zsb2F0JyIpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisKKyAgICBzd2l0Y2ggKHIpIHsKKyAgICBjYXNlIHVua25vd25fZm9ybWF0OgorICAgICAgICByZXR1cm4gUHlTdHJpbmdfRnJvbVN0cmluZygidW5rbm93biIpOworICAgIGNhc2UgaWVlZV9saXR0bGVfZW5kaWFuX2Zvcm1hdDoKKyAgICAgICAgcmV0dXJuIFB5U3RyaW5nX0Zyb21TdHJpbmcoIklFRUUsIGxpdHRsZS1lbmRpYW4iKTsKKyAgICBjYXNlIGllZWVfYmlnX2VuZGlhbl9mb3JtYXQ6CisgICAgICAgIHJldHVybiBQeVN0cmluZ19Gcm9tU3RyaW5nKCJJRUVFLCBiaWctZW5kaWFuIik7CisgICAgZGVmYXVsdDoKKyAgICAgICAgUHlfRmF0YWxFcnJvcigiaW5zYW5lIGZsb2F0X2Zvcm1hdCBvciBkb3VibGVfZm9ybWF0Iik7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KK30KKworUHlEb2NfU1RSVkFSKGZsb2F0X2dldGZvcm1hdF9kb2MsCisiZmxvYXQuX19nZXRmb3JtYXRfXyh0eXBlc3RyKSAtPiBzdHJpbmdcbiIKKyJcbiIKKyJZb3UgcHJvYmFibHkgZG9uJ3Qgd2FudCB0byB1c2UgdGhpcyBmdW5jdGlvbi4gIEl0IGV4aXN0cyBtYWlubHkgdG8gYmVcbiIKKyJ1c2VkIGluIFB5dGhvbidzIHRlc3Qgc3VpdGUuXG4iCisiXG4iCisidHlwZXN0ciBtdXN0IGJlICdkb3VibGUnIG9yICdmbG9hdCcuICBUaGlzIGZ1bmN0aW9uIHJldHVybnMgd2hpY2hldmVyIG9mXG4iCisiJ3Vua25vd24nLCAnSUVFRSwgYmlnLWVuZGlhbicgb3IgJ0lFRUUsIGxpdHRsZS1lbmRpYW4nIGJlc3QgZGVzY3JpYmVzIHRoZVxuIgorImZvcm1hdCBvZiBmbG9hdGluZyBwb2ludCBudW1iZXJzIHVzZWQgYnkgdGhlIEMgdHlwZSBuYW1lZCBieSB0eXBlc3RyLiIpOworCitzdGF0aWMgUHlPYmplY3QgKgorZmxvYXRfc2V0Zm9ybWF0KFB5VHlwZU9iamVjdCAqdiwgUHlPYmplY3QqIGFyZ3MpCit7CisgICAgY2hhciogdHlwZXN0cjsKKyAgICBjaGFyKiBmb3JtYXQ7CisgICAgZmxvYXRfZm9ybWF0X3R5cGUgZjsKKyAgICBmbG9hdF9mb3JtYXRfdHlwZSBkZXRlY3RlZDsKKyAgICBmbG9hdF9mb3JtYXRfdHlwZSAqcDsKKworICAgIGlmICghUHlBcmdfUGFyc2VUdXBsZShhcmdzLCAic3M6X19zZXRmb3JtYXRfXyIsICZ0eXBlc3RyLCAmZm9ybWF0KSkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisKKyAgICBpZiAoc3RyY21wKHR5cGVzdHIsICJkb3VibGUiKSA9PSAwKSB7CisgICAgICAgIHAgPSAmZG91YmxlX2Zvcm1hdDsKKyAgICAgICAgZGV0ZWN0ZWQgPSBkZXRlY3RlZF9kb3VibGVfZm9ybWF0OworICAgIH0KKyAgICBlbHNlIGlmIChzdHJjbXAodHlwZXN0ciwgImZsb2F0IikgPT0gMCkgeworICAgICAgICBwID0gJmZsb2F0X2Zvcm1hdDsKKyAgICAgICAgZGV0ZWN0ZWQgPSBkZXRlY3RlZF9mbG9hdF9mb3JtYXQ7CisgICAgfQorICAgIGVsc2UgeworICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfVmFsdWVFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICJfX3NldGZvcm1hdF9fKCkgYXJndW1lbnQgMSBtdXN0ICIKKyAgICAgICAgICAgICAgICAgICAgICAgICJiZSAnZG91YmxlJyBvciAnZmxvYXQnIik7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKworICAgIGlmIChzdHJjbXAoZm9ybWF0LCAidW5rbm93biIpID09IDApIHsKKyAgICAgICAgZiA9IHVua25vd25fZm9ybWF0OworICAgIH0KKyAgICBlbHNlIGlmIChzdHJjbXAoZm9ybWF0LCAiSUVFRSwgbGl0dGxlLWVuZGlhbiIpID09IDApIHsKKyAgICAgICAgZiA9IGllZWVfbGl0dGxlX2VuZGlhbl9mb3JtYXQ7CisgICAgfQorICAgIGVsc2UgaWYgKHN0cmNtcChmb3JtYXQsICJJRUVFLCBiaWctZW5kaWFuIikgPT0gMCkgeworICAgICAgICBmID0gaWVlZV9iaWdfZW5kaWFuX2Zvcm1hdDsKKyAgICB9CisgICAgZWxzZSB7CisgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19WYWx1ZUVycm9yLAorICAgICAgICAgICAgICAgICAgICAgICAgIl9fc2V0Zm9ybWF0X18oKSBhcmd1bWVudCAyIG11c3QgYmUgIgorICAgICAgICAgICAgICAgICAgICAgICAgIid1bmtub3duJywgJ0lFRUUsIGxpdHRsZS1lbmRpYW4nIG9yICIKKyAgICAgICAgICAgICAgICAgICAgICAgICInSUVFRSwgYmlnLWVuZGlhbiciKTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisKKyAgICB9CisKKyAgICBpZiAoZiAhPSB1bmtub3duX2Zvcm1hdCAmJiBmICE9IGRldGVjdGVkKSB7CisgICAgICAgIFB5RXJyX0Zvcm1hdChQeUV4Y19WYWx1ZUVycm9yLAorICAgICAgICAgICAgICAgICAgICAgImNhbiBvbmx5IHNldCAlcyBmb3JtYXQgdG8gJ3Vua25vd24nIG9yIHRoZSAiCisgICAgICAgICAgICAgICAgICAgICAiZGV0ZWN0ZWQgcGxhdGZvcm0gdmFsdWUiLCB0eXBlc3RyKTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorCisgICAgKnAgPSBmOworICAgIFB5X1JFVFVSTl9OT05FOworfQorCitQeURvY19TVFJWQVIoZmxvYXRfc2V0Zm9ybWF0X2RvYywKKyJmbG9hdC5fX3NldGZvcm1hdF9fKHR5cGVzdHIsIGZtdCkgLT4gTm9uZVxuIgorIlxuIgorIllvdSBwcm9iYWJseSBkb24ndCB3YW50IHRvIHVzZSB0aGlzIGZ1bmN0aW9uLiAgSXQgZXhpc3RzIG1haW5seSB0byBiZVxuIgorInVzZWQgaW4gUHl0aG9uJ3MgdGVzdCBzdWl0ZS5cbiIKKyJcbiIKKyJ0eXBlc3RyIG11c3QgYmUgJ2RvdWJsZScgb3IgJ2Zsb2F0Jy4gIGZtdCBtdXN0IGJlIG9uZSBvZiAndW5rbm93bicsXG4iCisiJ0lFRUUsIGJpZy1lbmRpYW4nIG9yICdJRUVFLCBsaXR0bGUtZW5kaWFuJywgYW5kIGluIGFkZGl0aW9uIGNhbiBvbmx5IGJlXG4iCisib25lIG9mIHRoZSBsYXR0ZXIgdHdvIGlmIGl0IGFwcGVhcnMgdG8gbWF0Y2ggdGhlIHVuZGVybHlpbmcgQyByZWFsaXR5LlxuIgorIlxuIgorIk92ZXJyaWRlcyB0aGUgYXV0b21hdGljIGRldGVybWluYXRpb24gb2YgQy1sZXZlbCBmbG9hdGluZyBwb2ludCB0eXBlLlxuIgorIlRoaXMgYWZmZWN0cyBob3cgZmxvYXRzIGFyZSBjb252ZXJ0ZWQgdG8gYW5kIGZyb20gYmluYXJ5IHN0cmluZ3MuIik7CisKK3N0YXRpYyBQeU9iamVjdCAqCitmbG9hdF9nZXR6ZXJvKFB5T2JqZWN0ICp2LCB2b2lkICpjbG9zdXJlKQoreworICAgIHJldHVybiBQeUZsb2F0X0Zyb21Eb3VibGUoMC4wKTsKK30KKworc3RhdGljIFB5T2JqZWN0ICoKK2Zsb2F0X19mb3JtYXRfXyhQeU9iamVjdCAqc2VsZiwgUHlPYmplY3QgKmFyZ3MpCit7CisgICAgUHlPYmplY3QgKmZvcm1hdF9zcGVjOworCisgICAgaWYgKCFQeUFyZ19QYXJzZVR1cGxlKGFyZ3MsICJPOl9fZm9ybWF0X18iLCAmZm9ybWF0X3NwZWMpKQorICAgICAgICByZXR1cm4gTlVMTDsKKyAgICBpZiAoUHlCeXRlc19DaGVjayhmb3JtYXRfc3BlYykpCisgICAgICAgIHJldHVybiBfUHlGbG9hdF9Gb3JtYXRBZHZhbmNlZChzZWxmLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHlCeXRlc19BU19TVFJJTkcoZm9ybWF0X3NwZWMpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHlCeXRlc19HRVRfU0laRShmb3JtYXRfc3BlYykpOworICAgIGlmIChQeVVuaWNvZGVfQ2hlY2soZm9ybWF0X3NwZWMpKSB7CisgICAgICAgIC8qIENvbnZlcnQgZm9ybWF0X3NwZWMgdG8gYSBzdHIgKi8KKyAgICAgICAgUHlPYmplY3QgKnJlc3VsdDsKKyAgICAgICAgUHlPYmplY3QgKnN0cl9zcGVjID0gUHlPYmplY3RfU3RyKGZvcm1hdF9zcGVjKTsKKworICAgICAgICBpZiAoc3RyX3NwZWMgPT0gTlVMTCkKKyAgICAgICAgICAgIHJldHVybiBOVUxMOworCisgICAgICAgIHJlc3VsdCA9IF9QeUZsb2F0X0Zvcm1hdEFkdmFuY2VkKHNlbGYsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFB5Qnl0ZXNfQVNfU1RSSU5HKHN0cl9zcGVjKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHlCeXRlc19HRVRfU0laRShzdHJfc3BlYykpOworCisgICAgICAgIFB5X0RFQ1JFRihzdHJfc3BlYyk7CisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19UeXBlRXJyb3IsICJfX2Zvcm1hdF9fIHJlcXVpcmVzIHN0ciBvciB1bmljb2RlIik7CisgICAgcmV0dXJuIE5VTEw7Cit9CisKK1B5RG9jX1NUUlZBUihmbG9hdF9fZm9ybWF0X19kb2MsCisiZmxvYXQuX19mb3JtYXRfXyhmb3JtYXRfc3BlYykgLT4gc3RyaW5nXG4iCisiXG4iCisiRm9ybWF0cyB0aGUgZmxvYXQgYWNjb3JkaW5nIHRvIGZvcm1hdF9zcGVjLiIpOworCisKK3N0YXRpYyBQeU1ldGhvZERlZiBmbG9hdF9tZXRob2RzW10gPSB7CisgICAgeyJjb25qdWdhdGUiLCAgICAgICAoUHlDRnVuY3Rpb24pZmxvYXRfZmxvYXQsICAgICAgIE1FVEhfTk9BUkdTLAorICAgICAiUmV0dXJucyBzZWxmLCB0aGUgY29tcGxleCBjb25qdWdhdGUgb2YgYW55IGZsb2F0LiJ9LAorICAgIHsiX190cnVuY19fIiwgICAgICAgKFB5Q0Z1bmN0aW9uKWZsb2F0X3RydW5jLCBNRVRIX05PQVJHUywKKyAgICAgIlJldHVybnMgdGhlIEludGVncmFsIGNsb3Nlc3QgdG8geCBiZXR3ZWVuIDAgYW5kIHguIn0sCisgICAgeyJhc19pbnRlZ2VyX3JhdGlvIiwgKFB5Q0Z1bmN0aW9uKWZsb2F0X2FzX2ludGVnZXJfcmF0aW8sIE1FVEhfTk9BUkdTLAorICAgICBmbG9hdF9hc19pbnRlZ2VyX3JhdGlvX2RvY30sCisgICAgeyJmcm9taGV4IiwgKFB5Q0Z1bmN0aW9uKWZsb2F0X2Zyb21oZXgsCisgICAgIE1FVEhfT3xNRVRIX0NMQVNTLCBmbG9hdF9mcm9taGV4X2RvY30sCisgICAgeyJoZXgiLCAoUHlDRnVuY3Rpb24pZmxvYXRfaGV4LAorICAgICBNRVRIX05PQVJHUywgZmxvYXRfaGV4X2RvY30sCisgICAgeyJpc19pbnRlZ2VyIiwgICAgICAoUHlDRnVuY3Rpb24pZmxvYXRfaXNfaW50ZWdlciwgIE1FVEhfTk9BUkdTLAorICAgICAiUmV0dXJucyBUcnVlIGlmIHRoZSBmbG9hdCBpcyBhbiBpbnRlZ2VyLiJ9LAorI2lmIDAKKyAgICB7ImlzX2luZiIsICAgICAgICAgIChQeUNGdW5jdGlvbilmbG9hdF9pc19pbmYsICAgICAgTUVUSF9OT0FSR1MsCisgICAgICJSZXR1cm5zIFRydWUgaWYgdGhlIGZsb2F0IGlzIHBvc2l0aXZlIG9yIG5lZ2F0aXZlIGluZmluaXRlLiJ9LAorICAgIHsiaXNfZmluaXRlIiwgICAgICAgKFB5Q0Z1bmN0aW9uKWZsb2F0X2lzX2Zpbml0ZSwgICBNRVRIX05PQVJHUywKKyAgICAgIlJldHVybnMgVHJ1ZSBpZiB0aGUgZmxvYXQgaXMgZmluaXRlLCBuZWl0aGVyIGluZmluaXRlIG5vciBOYU4uIn0sCisgICAgeyJpc19uYW4iLCAgICAgICAgICAoUHlDRnVuY3Rpb24pZmxvYXRfaXNfbmFuLCAgICAgIE1FVEhfTk9BUkdTLAorICAgICAiUmV0dXJucyBUcnVlIGlmIHRoZSBmbG9hdCBpcyBub3QgYSBudW1iZXIgKE5hTikuIn0sCisjZW5kaWYKKyAgICB7Il9fZ2V0bmV3YXJnc19fIiwgICAgICAgICAgKFB5Q0Z1bmN0aW9uKWZsb2F0X2dldG5ld2FyZ3MsICBNRVRIX05PQVJHU30sCisgICAgeyJfX2dldGZvcm1hdF9fIiwgICAgICAgICAgIChQeUNGdW5jdGlvbilmbG9hdF9nZXRmb3JtYXQsCisgICAgIE1FVEhfT3xNRVRIX0NMQVNTLCAgICAgICAgICAgICAgICAgZmxvYXRfZ2V0Zm9ybWF0X2RvY30sCisgICAgeyJfX3NldGZvcm1hdF9fIiwgICAgICAgICAgIChQeUNGdW5jdGlvbilmbG9hdF9zZXRmb3JtYXQsCisgICAgIE1FVEhfVkFSQVJHU3xNRVRIX0NMQVNTLCAgICAgICAgICAgZmxvYXRfc2V0Zm9ybWF0X2RvY30sCisgICAgeyJfX2Zvcm1hdF9fIiwgICAgICAgICAgKFB5Q0Z1bmN0aW9uKWZsb2F0X19mb3JtYXRfXywKKyAgICAgTUVUSF9WQVJBUkdTLCAgICAgICAgICAgICAgICAgIGZsb2F0X19mb3JtYXRfX2RvY30sCisgICAge05VTEwsICAgICAgICAgICAgICBOVUxMfSAgICAgICAgICAgLyogc2VudGluZWwgKi8KK307CisKK3N0YXRpYyBQeUdldFNldERlZiBmbG9hdF9nZXRzZXRbXSA9IHsKKyAgICB7InJlYWwiLAorICAgICAoZ2V0dGVyKWZsb2F0X2Zsb2F0LCAoc2V0dGVyKU5VTEwsCisgICAgICJ0aGUgcmVhbCBwYXJ0IG9mIGEgY29tcGxleCBudW1iZXIiLAorICAgICBOVUxMfSwKKyAgICB7ImltYWciLAorICAgICAoZ2V0dGVyKWZsb2F0X2dldHplcm8sIChzZXR0ZXIpTlVMTCwKKyAgICAgInRoZSBpbWFnaW5hcnkgcGFydCBvZiBhIGNvbXBsZXggbnVtYmVyIiwKKyAgICAgTlVMTH0sCisgICAge05VTEx9ICAvKiBTZW50aW5lbCAqLworfTsKKworUHlEb2NfU1RSVkFSKGZsb2F0X2RvYywKKyJmbG9hdCh4KSAtPiBmbG9hdGluZyBwb2ludCBudW1iZXJcblwKK1xuXAorQ29udmVydCBhIHN0cmluZyBvciBudW1iZXIgdG8gYSBmbG9hdGluZyBwb2ludCBudW1iZXIsIGlmIHBvc3NpYmxlLiIpOworCisKK3N0YXRpYyBQeU51bWJlck1ldGhvZHMgZmxvYXRfYXNfbnVtYmVyID0geworICAgIGZsb2F0X2FkZCwgICAgICAgICAgLypuYl9hZGQqLworICAgIGZsb2F0X3N1YiwgICAgICAgICAgLypuYl9zdWJ0cmFjdCovCisgICAgZmxvYXRfbXVsLCAgICAgICAgICAvKm5iX211bHRpcGx5Ki8KKyAgICBmbG9hdF9jbGFzc2ljX2RpdiwgLypuYl9kaXZpZGUqLworICAgIGZsb2F0X3JlbSwgICAgICAgICAgLypuYl9yZW1haW5kZXIqLworICAgIGZsb2F0X2Rpdm1vZCwgICAgICAgLypuYl9kaXZtb2QqLworICAgIGZsb2F0X3BvdywgICAgICAgICAgLypuYl9wb3dlciovCisgICAgKHVuYXJ5ZnVuYylmbG9hdF9uZWcsIC8qbmJfbmVnYXRpdmUqLworICAgICh1bmFyeWZ1bmMpZmxvYXRfZmxvYXQsIC8qbmJfcG9zaXRpdmUqLworICAgICh1bmFyeWZ1bmMpZmxvYXRfYWJzLCAvKm5iX2Fic29sdXRlKi8KKyAgICAoaW5xdWlyeSlmbG9hdF9ub256ZXJvLCAvKm5iX25vbnplcm8qLworICAgIDAsICAgICAgICAgICAgICAgICAgLypuYl9pbnZlcnQqLworICAgIDAsICAgICAgICAgICAgICAgICAgLypuYl9sc2hpZnQqLworICAgIDAsICAgICAgICAgICAgICAgICAgLypuYl9yc2hpZnQqLworICAgIDAsICAgICAgICAgICAgICAgICAgLypuYl9hbmQqLworICAgIDAsICAgICAgICAgICAgICAgICAgLypuYl94b3IqLworICAgIDAsICAgICAgICAgICAgICAgICAgLypuYl9vciovCisgICAgZmxvYXRfY29lcmNlLCAgICAgICAvKm5iX2NvZXJjZSovCisgICAgZmxvYXRfdHJ1bmMsICAgICAgICAvKm5iX2ludCovCisgICAgZmxvYXRfbG9uZywgICAgICAgICAvKm5iX2xvbmcqLworICAgIGZsb2F0X2Zsb2F0LCAgICAgICAgLypuYl9mbG9hdCovCisgICAgMCwgICAgICAgICAgICAgICAgICAvKiBuYl9vY3QgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgIC8qIG5iX2hleCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgLyogbmJfaW5wbGFjZV9hZGQgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgIC8qIG5iX2lucGxhY2Vfc3VidHJhY3QgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgIC8qIG5iX2lucGxhY2VfbXVsdGlwbHkgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgIC8qIG5iX2lucGxhY2VfZGl2aWRlICovCisgICAgMCwgICAgICAgICAgICAgICAgICAvKiBuYl9pbnBsYWNlX3JlbWFpbmRlciAqLworICAgIDAsICAgICAgICAgICAgICAgICAgLyogbmJfaW5wbGFjZV9wb3dlciAqLworICAgIDAsICAgICAgICAgICAgICAgICAgLyogbmJfaW5wbGFjZV9sc2hpZnQgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgIC8qIG5iX2lucGxhY2VfcnNoaWZ0ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAvKiBuYl9pbnBsYWNlX2FuZCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgLyogbmJfaW5wbGFjZV94b3IgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgIC8qIG5iX2lucGxhY2Vfb3IgKi8KKyAgICBmbG9hdF9mbG9vcl9kaXYsIC8qIG5iX2Zsb29yX2RpdmlkZSAqLworICAgIGZsb2F0X2RpdiwgICAgICAgICAgLyogbmJfdHJ1ZV9kaXZpZGUgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgIC8qIG5iX2lucGxhY2VfZmxvb3JfZGl2aWRlICovCisgICAgMCwgICAgICAgICAgICAgICAgICAvKiBuYl9pbnBsYWNlX3RydWVfZGl2aWRlICovCit9OworCitQeVR5cGVPYmplY3QgUHlGbG9hdF9UeXBlID0geworICAgIFB5VmFyT2JqZWN0X0hFQURfSU5JVCgmUHlUeXBlX1R5cGUsIDApCisgICAgImZsb2F0IiwKKyAgICBzaXplb2YoUHlGbG9hdE9iamVjdCksCisgICAgMCwKKyAgICAoZGVzdHJ1Y3RvcilmbG9hdF9kZWFsbG9jLCAgICAgICAgICAgICAgICAgIC8qIHRwX2RlYWxsb2MgKi8KKyAgICAocHJpbnRmdW5jKWZsb2F0X3ByaW50LCAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3ByaW50ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9nZXRhdHRyICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9zZXRhdHRyICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9jb21wYXJlICovCisgICAgKHJlcHJmdW5jKWZsb2F0X3JlcHIsICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9yZXByICovCisgICAgJmZsb2F0X2FzX251bWJlciwgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9hc19udW1iZXIgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2FzX3NlcXVlbmNlICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9hc19tYXBwaW5nICovCisgICAgKGhhc2hmdW5jKWZsb2F0X2hhc2gsICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9oYXNoICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9jYWxsICovCisgICAgKHJlcHJmdW5jKWZsb2F0X3N0ciwgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9zdHIgKi8KKyAgICBQeU9iamVjdF9HZW5lcmljR2V0QXR0ciwgICAgICAgICAgICAgICAgICAgIC8qIHRwX2dldGF0dHJvICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9zZXRhdHRybyAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfYXNfYnVmZmVyICovCisgICAgUHlfVFBGTEFHU19ERUZBVUxUIHwgUHlfVFBGTEFHU19DSEVDS1RZUEVTIHwKKyAgICAgICAgUHlfVFBGTEFHU19CQVNFVFlQRSwgICAgICAgICAgICAgICAgICAgIC8qIHRwX2ZsYWdzICovCisgICAgZmxvYXRfZG9jLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9kb2MgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3RyYXZlcnNlICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9jbGVhciAqLworICAgIGZsb2F0X3JpY2hjb21wYXJlLCAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfcmljaGNvbXBhcmUgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3dlYWtsaXN0b2Zmc2V0ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9pdGVyICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9pdGVybmV4dCAqLworICAgIGZsb2F0X21ldGhvZHMsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfbWV0aG9kcyAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfbWVtYmVycyAqLworICAgIGZsb2F0X2dldHNldCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZ2V0c2V0ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9iYXNlICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9kaWN0ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9kZXNjcl9nZXQgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2Rlc2NyX3NldCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZGljdG9mZnNldCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfaW5pdCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfYWxsb2MgKi8KKyAgICBmbG9hdF9uZXcsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX25ldyAqLworfTsKKwordm9pZAorX1B5RmxvYXRfSW5pdCh2b2lkKQoreworICAgIC8qIFdlIGF0dGVtcHQgdG8gZGV0ZXJtaW5lIGlmIHRoaXMgbWFjaGluZSBpcyB1c2luZyBJRUVFCisgICAgICAgZmxvYXRpbmcgcG9pbnQgZm9ybWF0cyBieSBwZWVyaW5nIGF0IHRoZSBiaXRzIG9mIHNvbWUKKyAgICAgICBjYXJlZnVsbHkgY2hvc2VuIHZhbHVlcy4gIElmIGl0IGxvb2tzIGxpa2Ugd2UgYXJlIG9uIGFuCisgICAgICAgSUVFRSBwbGF0Zm9ybSwgdGhlIGZsb2F0IHBhY2tpbmcvdW5wYWNraW5nIHJvdXRpbmVzIGNhbgorICAgICAgIGp1c3QgY29weSBiaXRzLCBpZiBub3QgdGhleSByZXNvcnQgdG8gYXJpdGhtZXRpYyAmIHNoaWZ0cworICAgICAgIGFuZCBtYXNrcy4gIFRoZSBzaGlmdHMgJiBtYXNrcyBhcHByb2FjaCB3b3JrcyBvbiBhbGwgZmluaXRlCisgICAgICAgdmFsdWVzLCBidXQgd2hhdCBoYXBwZW5zIHRvIGluZmluaXRpZXMsIE5hTnMgYW5kIHNpZ25lZAorICAgICAgIHplcm9lcyBvbiBwYWNraW5nIGlzIGFuIGFjY2lkZW50LCBhbmQgYXR0ZW1wdGluZyB0byB1bnBhY2sKKyAgICAgICBhIE5hTiBvciBhbiBpbmZpbml0eSB3aWxsIHJhaXNlIGFuIGV4Y2VwdGlvbi4KKworICAgICAgIE5vdGUgdGhhdCBpZiB3ZSdyZSBvbiBzb21lIHdoYWNrZWQtb3V0IHBsYXRmb3JtIHdoaWNoIHVzZXMKKyAgICAgICBJRUVFIGZvcm1hdHMgYnV0IGlzbid0IHN0cmljdGx5IGxpdHRsZS1lbmRpYW4gb3IgYmlnLQorICAgICAgIGVuZGlhbiwgd2Ugd2lsbCBmYWxsIGJhY2sgdG8gdGhlIHBvcnRhYmxlIHNoaWZ0cyAmIG1hc2tzCisgICAgICAgbWV0aG9kLiAqLworCisjaWYgU0laRU9GX0RPVUJMRSA9PSA4CisgICAgeworICAgICAgICBkb3VibGUgeCA9IDkwMDYxMDQwNzE4MzI1ODEuMDsKKyAgICAgICAgaWYgKG1lbWNtcCgmeCwgIlx4NDNceDNmXHhmZlx4MDFceDAyXHgwM1x4MDRceDA1IiwgOCkgPT0gMCkKKyAgICAgICAgICAgIGRldGVjdGVkX2RvdWJsZV9mb3JtYXQgPSBpZWVlX2JpZ19lbmRpYW5fZm9ybWF0OworICAgICAgICBlbHNlIGlmIChtZW1jbXAoJngsICJceDA1XHgwNFx4MDNceDAyXHgwMVx4ZmZceDNmXHg0MyIsIDgpID09IDApCisgICAgICAgICAgICBkZXRlY3RlZF9kb3VibGVfZm9ybWF0ID0gaWVlZV9saXR0bGVfZW5kaWFuX2Zvcm1hdDsKKyAgICAgICAgZWxzZQorICAgICAgICAgICAgZGV0ZWN0ZWRfZG91YmxlX2Zvcm1hdCA9IHVua25vd25fZm9ybWF0OworICAgIH0KKyNlbHNlCisgICAgZGV0ZWN0ZWRfZG91YmxlX2Zvcm1hdCA9IHVua25vd25fZm9ybWF0OworI2VuZGlmCisKKyNpZiBTSVpFT0ZfRkxPQVQgPT0gNAorICAgIHsKKyAgICAgICAgZmxvYXQgeSA9IDE2NzExOTM4LjA7CisgICAgICAgIGlmIChtZW1jbXAoJnksICJceDRiXHg3Zlx4MDFceDAyIiwgNCkgPT0gMCkKKyAgICAgICAgICAgIGRldGVjdGVkX2Zsb2F0X2Zvcm1hdCA9IGllZWVfYmlnX2VuZGlhbl9mb3JtYXQ7CisgICAgICAgIGVsc2UgaWYgKG1lbWNtcCgmeSwgIlx4MDJceDAxXHg3Zlx4NGIiLCA0KSA9PSAwKQorICAgICAgICAgICAgZGV0ZWN0ZWRfZmxvYXRfZm9ybWF0ID0gaWVlZV9saXR0bGVfZW5kaWFuX2Zvcm1hdDsKKyAgICAgICAgZWxzZQorICAgICAgICAgICAgZGV0ZWN0ZWRfZmxvYXRfZm9ybWF0ID0gdW5rbm93bl9mb3JtYXQ7CisgICAgfQorI2Vsc2UKKyAgICBkZXRlY3RlZF9mbG9hdF9mb3JtYXQgPSB1bmtub3duX2Zvcm1hdDsKKyNlbmRpZgorCisgICAgZG91YmxlX2Zvcm1hdCA9IGRldGVjdGVkX2RvdWJsZV9mb3JtYXQ7CisgICAgZmxvYXRfZm9ybWF0ID0gZGV0ZWN0ZWRfZmxvYXRfZm9ybWF0OworCisgICAgLyogSW5pdCBmbG9hdCBpbmZvICovCisgICAgaWYgKEZsb2F0SW5mb1R5cGUudHBfbmFtZSA9PSAwKQorICAgICAgICBQeVN0cnVjdFNlcXVlbmNlX0luaXRUeXBlKCZGbG9hdEluZm9UeXBlLCAmZmxvYXRpbmZvX2Rlc2MpOworfQorCitpbnQKK1B5RmxvYXRfQ2xlYXJGcmVlTGlzdCh2b2lkKQoreworICAgIFB5RmxvYXRPYmplY3QgKnA7CisgICAgUHlGbG9hdEJsb2NrICpsaXN0LCAqbmV4dDsKKyAgICBpbnQgaTsKKyAgICBpbnQgdTsgICAgICAgICAgICAgICAgICAgICAgLyogcmVtYWluaW5nIHVuZnJlZWQgaW50cyBwZXIgYmxvY2sgKi8KKyAgICBpbnQgZnJlZWxpc3Rfc2l6ZSA9IDA7CisKKyAgICBsaXN0ID0gYmxvY2tfbGlzdDsKKyAgICBibG9ja19saXN0ID0gTlVMTDsKKyAgICBmcmVlX2xpc3QgPSBOVUxMOworICAgIHdoaWxlIChsaXN0ICE9IE5VTEwpIHsKKyAgICAgICAgdSA9IDA7CisgICAgICAgIGZvciAoaSA9IDAsIHAgPSAmbGlzdC0+b2JqZWN0c1swXTsKKyAgICAgICAgICAgICBpIDwgTl9GTE9BVE9CSkVDVFM7CisgICAgICAgICAgICAgaSsrLCBwKyspIHsKKyAgICAgICAgICAgIGlmIChQeUZsb2F0X0NoZWNrRXhhY3QocCkgJiYgUHlfUkVGQ05UKHApICE9IDApCisgICAgICAgICAgICAgICAgdSsrOworICAgICAgICB9CisgICAgICAgIG5leHQgPSBsaXN0LT5uZXh0OworICAgICAgICBpZiAodSkgeworICAgICAgICAgICAgbGlzdC0+bmV4dCA9IGJsb2NrX2xpc3Q7CisgICAgICAgICAgICBibG9ja19saXN0ID0gbGlzdDsKKyAgICAgICAgICAgIGZvciAoaSA9IDAsIHAgPSAmbGlzdC0+b2JqZWN0c1swXTsKKyAgICAgICAgICAgICAgICAgaSA8IE5fRkxPQVRPQkpFQ1RTOworICAgICAgICAgICAgICAgICBpKyssIHArKykgeworICAgICAgICAgICAgICAgIGlmICghUHlGbG9hdF9DaGVja0V4YWN0KHApIHx8CisgICAgICAgICAgICAgICAgICAgIFB5X1JFRkNOVChwKSA9PSAwKSB7CisgICAgICAgICAgICAgICAgICAgIFB5X1RZUEUocCkgPSAoc3RydWN0IF90eXBlb2JqZWN0ICopCisgICAgICAgICAgICAgICAgICAgICAgICBmcmVlX2xpc3Q7CisgICAgICAgICAgICAgICAgICAgIGZyZWVfbGlzdCA9IHA7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGVsc2UgeworICAgICAgICAgICAgUHlNZW1fRlJFRShsaXN0KTsKKyAgICAgICAgfQorICAgICAgICBmcmVlbGlzdF9zaXplICs9IHU7CisgICAgICAgIGxpc3QgPSBuZXh0OworICAgIH0KKyAgICByZXR1cm4gZnJlZWxpc3Rfc2l6ZTsKK30KKwordm9pZAorUHlGbG9hdF9GaW5pKHZvaWQpCit7CisgICAgUHlGbG9hdE9iamVjdCAqcDsKKyAgICBQeUZsb2F0QmxvY2sgKmxpc3Q7CisgICAgaW50IGk7CisgICAgaW50IHU7ICAgICAgICAgICAgICAgICAgICAgIC8qIHRvdGFsIHVuZnJlZWQgZmxvYXRzIHBlciBibG9jayAqLworCisgICAgdSA9IFB5RmxvYXRfQ2xlYXJGcmVlTGlzdCgpOworCisgICAgaWYgKCFQeV9WZXJib3NlRmxhZykKKyAgICAgICAgcmV0dXJuOworICAgIGZwcmludGYoc3RkZXJyLCAiIyBjbGVhbnVwIGZsb2F0cyIpOworICAgIGlmICghdSkgeworICAgICAgICBmcHJpbnRmKHN0ZGVyciwgIlxuIik7CisgICAgfQorICAgIGVsc2UgeworICAgICAgICBmcHJpbnRmKHN0ZGVyciwKKyAgICAgICAgICAgICI6ICVkIHVuZnJlZWQgZmxvYXQlc1xuIiwKKyAgICAgICAgICAgIHUsIHUgPT0gMSA/ICIiIDogInMiKTsKKyAgICB9CisgICAgaWYgKFB5X1ZlcmJvc2VGbGFnID4gMSkgeworICAgICAgICBsaXN0ID0gYmxvY2tfbGlzdDsKKyAgICAgICAgd2hpbGUgKGxpc3QgIT0gTlVMTCkgeworICAgICAgICAgICAgZm9yIChpID0gMCwgcCA9ICZsaXN0LT5vYmplY3RzWzBdOworICAgICAgICAgICAgICAgICBpIDwgTl9GTE9BVE9CSkVDVFM7CisgICAgICAgICAgICAgICAgIGkrKywgcCsrKSB7CisgICAgICAgICAgICAgICAgaWYgKFB5RmxvYXRfQ2hlY2tFeGFjdChwKSAmJgorICAgICAgICAgICAgICAgICAgICBQeV9SRUZDTlQocCkgIT0gMCkgeworICAgICAgICAgICAgICAgICAgICBjaGFyICpidWYgPSBQeU9TX2RvdWJsZV90b19zdHJpbmcoCisgICAgICAgICAgICAgICAgICAgICAgICBQeUZsb2F0X0FTX0RPVUJMRShwKSwgJ3InLAorICAgICAgICAgICAgICAgICAgICAgICAgMCwgMCwgTlVMTCk7CisgICAgICAgICAgICAgICAgICAgIGlmIChidWYpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIC8qIFhYWCh0d291dGVycykgY2FzdAorICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVmY291bnQgdG8gbG9uZworICAgICAgICAgICAgICAgICAgICAgICAgICAgdW50aWwgJXpkIGlzCisgICAgICAgICAgICAgICAgICAgICAgICAgICB1bml2ZXJzYWxseQorICAgICAgICAgICAgICAgICAgICAgICAgICAgYXZhaWxhYmxlCisgICAgICAgICAgICAgICAgICAgICAgICAqLworICAgICAgICAgICAgICAgICAgICAgICAgZnByaW50ZihzdGRlcnIsCisgICAgICAgICAgICAgICAgICIjICAgPGZsb2F0IGF0ICVwLCByZWZjbnQ9JWxkLCB2YWw9JXM+XG4iLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcCwgKGxvbmcpUHlfUkVGQ05UKHApLCBidWYpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHlNZW1fRnJlZShidWYpOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICBsaXN0ID0gbGlzdC0+bmV4dDsKKyAgICAgICAgfQorICAgIH0KK30KKworLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCisgKiBfUHlGbG9hdF97UGFjayxVbnBhY2t9ezQsOH0uICBTZWUgZmxvYXRvYmplY3QuaC4KKyAqLworaW50CitfUHlGbG9hdF9QYWNrNChkb3VibGUgeCwgdW5zaWduZWQgY2hhciAqcCwgaW50IGxlKQoreworICAgIGlmIChmbG9hdF9mb3JtYXQgPT0gdW5rbm93bl9mb3JtYXQpIHsKKyAgICAgICAgdW5zaWduZWQgY2hhciBzaWduOworICAgICAgICBpbnQgZTsKKyAgICAgICAgZG91YmxlIGY7CisgICAgICAgIHVuc2lnbmVkIGludCBmYml0czsKKyAgICAgICAgaW50IGluY3IgPSAxOworCisgICAgICAgIGlmIChsZSkgeworICAgICAgICAgICAgcCArPSAzOworICAgICAgICAgICAgaW5jciA9IC0xOworICAgICAgICB9CisKKyAgICAgICAgaWYgKHggPCAwKSB7CisgICAgICAgICAgICBzaWduID0gMTsKKyAgICAgICAgICAgIHggPSAteDsKKyAgICAgICAgfQorICAgICAgICBlbHNlCisgICAgICAgICAgICBzaWduID0gMDsKKworICAgICAgICBmID0gZnJleHAoeCwgJmUpOworCisgICAgICAgIC8qIE5vcm1hbGl6ZSBmIHRvIGJlIGluIHRoZSByYW5nZSBbMS4wLCAyLjApICovCisgICAgICAgIGlmICgwLjUgPD0gZiAmJiBmIDwgMS4wKSB7CisgICAgICAgICAgICBmICo9IDIuMDsKKyAgICAgICAgICAgIGUtLTsKKyAgICAgICAgfQorICAgICAgICBlbHNlIGlmIChmID09IDAuMCkKKyAgICAgICAgICAgIGUgPSAwOworICAgICAgICBlbHNlIHsKKyAgICAgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19TeXN0ZW1FcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZnJleHAoKSByZXN1bHQgb3V0IG9mIHJhbmdlIik7CisgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgIH0KKworICAgICAgICBpZiAoZSA+PSAxMjgpCisgICAgICAgICAgICBnb3RvIE92ZXJmbG93OworICAgICAgICBlbHNlIGlmIChlIDwgLTEyNikgeworICAgICAgICAgICAgLyogR3JhZHVhbCB1bmRlcmZsb3cgKi8KKyAgICAgICAgICAgIGYgPSBsZGV4cChmLCAxMjYgKyBlKTsKKyAgICAgICAgICAgIGUgPSAwOworICAgICAgICB9CisgICAgICAgIGVsc2UgaWYgKCEoZSA9PSAwICYmIGYgPT0gMC4wKSkgeworICAgICAgICAgICAgZSArPSAxMjc7CisgICAgICAgICAgICBmIC09IDEuMDsgLyogR2V0IHJpZCBvZiBsZWFkaW5nIDEgKi8KKyAgICAgICAgfQorCisgICAgICAgIGYgKj0gODM4ODYwOC4wOyAvKiAyKioyMyAqLworICAgICAgICBmYml0cyA9ICh1bnNpZ25lZCBpbnQpKGYgKyAwLjUpOyAvKiBSb3VuZCAqLworICAgICAgICBhc3NlcnQoZmJpdHMgPD0gODM4ODYwOCk7CisgICAgICAgIGlmIChmYml0cyA+PiAyMykgeworICAgICAgICAgICAgLyogVGhlIGNhcnJ5IHByb3BhZ2F0ZWQgb3V0IG9mIGEgc3RyaW5nIG9mIDIzIDEgYml0cy4gKi8KKyAgICAgICAgICAgIGZiaXRzID0gMDsKKyAgICAgICAgICAgICsrZTsKKyAgICAgICAgICAgIGlmIChlID49IDI1NSkKKyAgICAgICAgICAgICAgICBnb3RvIE92ZXJmbG93OworICAgICAgICB9CisKKyAgICAgICAgLyogRmlyc3QgYnl0ZSAqLworICAgICAgICAqcCA9IChzaWduIDw8IDcpIHwgKGUgPj4gMSk7CisgICAgICAgIHAgKz0gaW5jcjsKKworICAgICAgICAvKiBTZWNvbmQgYnl0ZSAqLworICAgICAgICAqcCA9IChjaGFyKSAoKChlICYgMSkgPDwgNykgfCAoZmJpdHMgPj4gMTYpKTsKKyAgICAgICAgcCArPSBpbmNyOworCisgICAgICAgIC8qIFRoaXJkIGJ5dGUgKi8KKyAgICAgICAgKnAgPSAoZmJpdHMgPj4gOCkgJiAweEZGOworICAgICAgICBwICs9IGluY3I7CisKKyAgICAgICAgLyogRm91cnRoIGJ5dGUgKi8KKyAgICAgICAgKnAgPSBmYml0cyAmIDB4RkY7CisKKyAgICAgICAgLyogRG9uZSAqLworICAgICAgICByZXR1cm4gMDsKKworICAgIH0KKyAgICBlbHNlIHsKKyAgICAgICAgZmxvYXQgeSA9IChmbG9hdCl4OworICAgICAgICBjb25zdCBjaGFyICpzID0gKGNoYXIqKSZ5OworICAgICAgICBpbnQgaSwgaW5jciA9IDE7CisKKyAgICAgICAgaWYgKFB5X0lTX0lORklOSVRZKHkpICYmICFQeV9JU19JTkZJTklUWSh4KSkKKyAgICAgICAgICAgIGdvdG8gT3ZlcmZsb3c7CisKKyAgICAgICAgaWYgKChmbG9hdF9mb3JtYXQgPT0gaWVlZV9saXR0bGVfZW5kaWFuX2Zvcm1hdCAmJiAhbGUpCisgICAgICAgICAgICB8fCAoZmxvYXRfZm9ybWF0ID09IGllZWVfYmlnX2VuZGlhbl9mb3JtYXQgJiYgbGUpKSB7CisgICAgICAgICAgICBwICs9IDM7CisgICAgICAgICAgICBpbmNyID0gLTE7CisgICAgICAgIH0KKworICAgICAgICBmb3IgKGkgPSAwOyBpIDwgNDsgaSsrKSB7CisgICAgICAgICAgICAqcCA9ICpzKys7CisgICAgICAgICAgICBwICs9IGluY3I7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIDA7CisgICAgfQorICBPdmVyZmxvdzoKKyAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfT3ZlcmZsb3dFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgImZsb2F0IHRvbyBsYXJnZSB0byBwYWNrIHdpdGggZiBmb3JtYXQiKTsKKyAgICByZXR1cm4gLTE7Cit9CisKK2ludAorX1B5RmxvYXRfUGFjazgoZG91YmxlIHgsIHVuc2lnbmVkIGNoYXIgKnAsIGludCBsZSkKK3sKKyAgICBpZiAoZG91YmxlX2Zvcm1hdCA9PSB1bmtub3duX2Zvcm1hdCkgeworICAgICAgICB1bnNpZ25lZCBjaGFyIHNpZ247CisgICAgICAgIGludCBlOworICAgICAgICBkb3VibGUgZjsKKyAgICAgICAgdW5zaWduZWQgaW50IGZoaSwgZmxvOworICAgICAgICBpbnQgaW5jciA9IDE7CisKKyAgICAgICAgaWYgKGxlKSB7CisgICAgICAgICAgICBwICs9IDc7CisgICAgICAgICAgICBpbmNyID0gLTE7CisgICAgICAgIH0KKworICAgICAgICBpZiAoeCA8IDApIHsKKyAgICAgICAgICAgIHNpZ24gPSAxOworICAgICAgICAgICAgeCA9IC14OworICAgICAgICB9CisgICAgICAgIGVsc2UKKyAgICAgICAgICAgIHNpZ24gPSAwOworCisgICAgICAgIGYgPSBmcmV4cCh4LCAmZSk7CisKKyAgICAgICAgLyogTm9ybWFsaXplIGYgdG8gYmUgaW4gdGhlIHJhbmdlIFsxLjAsIDIuMCkgKi8KKyAgICAgICAgaWYgKDAuNSA8PSBmICYmIGYgPCAxLjApIHsKKyAgICAgICAgICAgIGYgKj0gMi4wOworICAgICAgICAgICAgZS0tOworICAgICAgICB9CisgICAgICAgIGVsc2UgaWYgKGYgPT0gMC4wKQorICAgICAgICAgICAgZSA9IDA7CisgICAgICAgIGVsc2UgeworICAgICAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1N5c3RlbUVycm9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICJmcmV4cCgpIHJlc3VsdCBvdXQgb2YgcmFuZ2UiKTsKKyAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChlID49IDEwMjQpCisgICAgICAgICAgICBnb3RvIE92ZXJmbG93OworICAgICAgICBlbHNlIGlmIChlIDwgLTEwMjIpIHsKKyAgICAgICAgICAgIC8qIEdyYWR1YWwgdW5kZXJmbG93ICovCisgICAgICAgICAgICBmID0gbGRleHAoZiwgMTAyMiArIGUpOworICAgICAgICAgICAgZSA9IDA7CisgICAgICAgIH0KKyAgICAgICAgZWxzZSBpZiAoIShlID09IDAgJiYgZiA9PSAwLjApKSB7CisgICAgICAgICAgICBlICs9IDEwMjM7CisgICAgICAgICAgICBmIC09IDEuMDsgLyogR2V0IHJpZCBvZiBsZWFkaW5nIDEgKi8KKyAgICAgICAgfQorCisgICAgICAgIC8qIGZoaSByZWNlaXZlcyB0aGUgaGlnaCAyOCBiaXRzOyBmbG8gdGhlIGxvdyAyNCBiaXRzICg9PSA1MiBiaXRzKSAqLworICAgICAgICBmICo9IDI2ODQzNTQ1Ni4wOyAvKiAyKioyOCAqLworICAgICAgICBmaGkgPSAodW5zaWduZWQgaW50KWY7IC8qIFRydW5jYXRlICovCisgICAgICAgIGFzc2VydChmaGkgPCAyNjg0MzU0NTYpOworCisgICAgICAgIGYgLT0gKGRvdWJsZSlmaGk7CisgICAgICAgIGYgKj0gMTY3NzcyMTYuMDsgLyogMioqMjQgKi8KKyAgICAgICAgZmxvID0gKHVuc2lnbmVkIGludCkoZiArIDAuNSk7IC8qIFJvdW5kICovCisgICAgICAgIGFzc2VydChmbG8gPD0gMTY3NzcyMTYpOworICAgICAgICBpZiAoZmxvID4+IDI0KSB7CisgICAgICAgICAgICAvKiBUaGUgY2FycnkgcHJvcGFnYXRlZCBvdXQgb2YgYSBzdHJpbmcgb2YgMjQgMSBiaXRzLiAqLworICAgICAgICAgICAgZmxvID0gMDsKKyAgICAgICAgICAgICsrZmhpOworICAgICAgICAgICAgaWYgKGZoaSA+PiAyOCkgeworICAgICAgICAgICAgICAgIC8qIEFuZCBpdCBhbHNvIHByb2dhZ2F0ZWQgb3V0IG9mIHRoZSBuZXh0IDI4IGJpdHMuICovCisgICAgICAgICAgICAgICAgZmhpID0gMDsKKyAgICAgICAgICAgICAgICArK2U7CisgICAgICAgICAgICAgICAgaWYgKGUgPj0gMjA0NykKKyAgICAgICAgICAgICAgICAgICAgZ290byBPdmVyZmxvdzsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIC8qIEZpcnN0IGJ5dGUgKi8KKyAgICAgICAgKnAgPSAoc2lnbiA8PCA3KSB8IChlID4+IDQpOworICAgICAgICBwICs9IGluY3I7CisKKyAgICAgICAgLyogU2Vjb25kIGJ5dGUgKi8KKyAgICAgICAgKnAgPSAodW5zaWduZWQgY2hhcikgKCgoZSAmIDB4RikgPDwgNCkgfCAoZmhpID4+IDI0KSk7CisgICAgICAgIHAgKz0gaW5jcjsKKworICAgICAgICAvKiBUaGlyZCBieXRlICovCisgICAgICAgICpwID0gKGZoaSA+PiAxNikgJiAweEZGOworICAgICAgICBwICs9IGluY3I7CisKKyAgICAgICAgLyogRm91cnRoIGJ5dGUgKi8KKyAgICAgICAgKnAgPSAoZmhpID4+IDgpICYgMHhGRjsKKyAgICAgICAgcCArPSBpbmNyOworCisgICAgICAgIC8qIEZpZnRoIGJ5dGUgKi8KKyAgICAgICAgKnAgPSBmaGkgJiAweEZGOworICAgICAgICBwICs9IGluY3I7CisKKyAgICAgICAgLyogU2l4dGggYnl0ZSAqLworICAgICAgICAqcCA9IChmbG8gPj4gMTYpICYgMHhGRjsKKyAgICAgICAgcCArPSBpbmNyOworCisgICAgICAgIC8qIFNldmVudGggYnl0ZSAqLworICAgICAgICAqcCA9IChmbG8gPj4gOCkgJiAweEZGOworICAgICAgICBwICs9IGluY3I7CisKKyAgICAgICAgLyogRWlnaHRoIGJ5dGUgKi8KKyAgICAgICAgKnAgPSBmbG8gJiAweEZGOworICAgICAgICAvKiBwICs9IGluY3I7IFVubmVlZGVkIChmb3Igbm93KSAqLworCisgICAgICAgIC8qIERvbmUgKi8KKyAgICAgICAgcmV0dXJuIDA7CisKKyAgICAgIE92ZXJmbG93OgorICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfT3ZlcmZsb3dFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICJmbG9hdCB0b28gbGFyZ2UgdG8gcGFjayB3aXRoIGQgZm9ybWF0Iik7CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisgICAgZWxzZSB7CisgICAgICAgIGNvbnN0IGNoYXIgKnMgPSAoY2hhciopJng7CisgICAgICAgIGludCBpLCBpbmNyID0gMTsKKworICAgICAgICBpZiAoKGRvdWJsZV9mb3JtYXQgPT0gaWVlZV9saXR0bGVfZW5kaWFuX2Zvcm1hdCAmJiAhbGUpCisgICAgICAgICAgICB8fCAoZG91YmxlX2Zvcm1hdCA9PSBpZWVlX2JpZ19lbmRpYW5fZm9ybWF0ICYmIGxlKSkgeworICAgICAgICAgICAgcCArPSA3OworICAgICAgICAgICAgaW5jciA9IC0xOworICAgICAgICB9CisKKyAgICAgICAgZm9yIChpID0gMDsgaSA8IDg7IGkrKykgeworICAgICAgICAgICAgKnAgPSAqcysrOworICAgICAgICAgICAgcCArPSBpbmNyOworICAgICAgICB9CisgICAgICAgIHJldHVybiAwOworICAgIH0KK30KKworZG91YmxlCitfUHlGbG9hdF9VbnBhY2s0KGNvbnN0IHVuc2lnbmVkIGNoYXIgKnAsIGludCBsZSkKK3sKKyAgICBpZiAoZmxvYXRfZm9ybWF0ID09IHVua25vd25fZm9ybWF0KSB7CisgICAgICAgIHVuc2lnbmVkIGNoYXIgc2lnbjsKKyAgICAgICAgaW50IGU7CisgICAgICAgIHVuc2lnbmVkIGludCBmOworICAgICAgICBkb3VibGUgeDsKKyAgICAgICAgaW50IGluY3IgPSAxOworCisgICAgICAgIGlmIChsZSkgeworICAgICAgICAgICAgcCArPSAzOworICAgICAgICAgICAgaW5jciA9IC0xOworICAgICAgICB9CisKKyAgICAgICAgLyogRmlyc3QgYnl0ZSAqLworICAgICAgICBzaWduID0gKCpwID4+IDcpICYgMTsKKyAgICAgICAgZSA9ICgqcCAmIDB4N0YpIDw8IDE7CisgICAgICAgIHAgKz0gaW5jcjsKKworICAgICAgICAvKiBTZWNvbmQgYnl0ZSAqLworICAgICAgICBlIHw9ICgqcCA+PiA3KSAmIDE7CisgICAgICAgIGYgPSAoKnAgJiAweDdGKSA8PCAxNjsKKyAgICAgICAgcCArPSBpbmNyOworCisgICAgICAgIGlmIChlID09IDI1NSkgeworICAgICAgICAgICAgUHlFcnJfU2V0U3RyaW5nKAorICAgICAgICAgICAgICAgIFB5RXhjX1ZhbHVlRXJyb3IsCisgICAgICAgICAgICAgICAgImNhbid0IHVucGFjayBJRUVFIDc1NCBzcGVjaWFsIHZhbHVlICIKKyAgICAgICAgICAgICAgICAib24gbm9uLUlFRUUgcGxhdGZvcm0iKTsKKyAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgfQorCisgICAgICAgIC8qIFRoaXJkIGJ5dGUgKi8KKyAgICAgICAgZiB8PSAqcCA8PCA4OworICAgICAgICBwICs9IGluY3I7CisKKyAgICAgICAgLyogRm91cnRoIGJ5dGUgKi8KKyAgICAgICAgZiB8PSAqcDsKKworICAgICAgICB4ID0gKGRvdWJsZSlmIC8gODM4ODYwOC4wOworCisgICAgICAgIC8qIFhYWCBUaGlzIHNhZGx5IGlnbm9yZXMgSW5mL05hTiBpc3N1ZXMgKi8KKyAgICAgICAgaWYgKGUgPT0gMCkKKyAgICAgICAgICAgIGUgPSAtMTI2OworICAgICAgICBlbHNlIHsKKyAgICAgICAgICAgIHggKz0gMS4wOworICAgICAgICAgICAgZSAtPSAxMjc7CisgICAgICAgIH0KKyAgICAgICAgeCA9IGxkZXhwKHgsIGUpOworCisgICAgICAgIGlmIChzaWduKQorICAgICAgICAgICAgeCA9IC14OworCisgICAgICAgIHJldHVybiB4OworICAgIH0KKyAgICBlbHNlIHsKKyAgICAgICAgZmxvYXQgeDsKKworICAgICAgICBpZiAoKGZsb2F0X2Zvcm1hdCA9PSBpZWVlX2xpdHRsZV9lbmRpYW5fZm9ybWF0ICYmICFsZSkKKyAgICAgICAgICAgIHx8IChmbG9hdF9mb3JtYXQgPT0gaWVlZV9iaWdfZW5kaWFuX2Zvcm1hdCAmJiBsZSkpIHsKKyAgICAgICAgICAgIGNoYXIgYnVmWzRdOworICAgICAgICAgICAgY2hhciAqZCA9ICZidWZbM107CisgICAgICAgICAgICBpbnQgaTsKKworICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IDQ7IGkrKykgeworICAgICAgICAgICAgICAgICpkLS0gPSAqcCsrOworICAgICAgICAgICAgfQorICAgICAgICAgICAgbWVtY3B5KCZ4LCBidWYsIDQpOworICAgICAgICB9CisgICAgICAgIGVsc2UgeworICAgICAgICAgICAgbWVtY3B5KCZ4LCBwLCA0KTsKKyAgICAgICAgfQorCisgICAgICAgIHJldHVybiB4OworICAgIH0KK30KKworZG91YmxlCitfUHlGbG9hdF9VbnBhY2s4KGNvbnN0IHVuc2lnbmVkIGNoYXIgKnAsIGludCBsZSkKK3sKKyAgICBpZiAoZG91YmxlX2Zvcm1hdCA9PSB1bmtub3duX2Zvcm1hdCkgeworICAgICAgICB1bnNpZ25lZCBjaGFyIHNpZ247CisgICAgICAgIGludCBlOworICAgICAgICB1bnNpZ25lZCBpbnQgZmhpLCBmbG87CisgICAgICAgIGRvdWJsZSB4OworICAgICAgICBpbnQgaW5jciA9IDE7CisKKyAgICAgICAgaWYgKGxlKSB7CisgICAgICAgICAgICBwICs9IDc7CisgICAgICAgICAgICBpbmNyID0gLTE7CisgICAgICAgIH0KKworICAgICAgICAvKiBGaXJzdCBieXRlICovCisgICAgICAgIHNpZ24gPSAoKnAgPj4gNykgJiAxOworICAgICAgICBlID0gKCpwICYgMHg3RikgPDwgNDsKKworICAgICAgICBwICs9IGluY3I7CisKKyAgICAgICAgLyogU2Vjb25kIGJ5dGUgKi8KKyAgICAgICAgZSB8PSAoKnAgPj4gNCkgJiAweEY7CisgICAgICAgIGZoaSA9ICgqcCAmIDB4RikgPDwgMjQ7CisgICAgICAgIHAgKz0gaW5jcjsKKworICAgICAgICBpZiAoZSA9PSAyMDQ3KSB7CisgICAgICAgICAgICBQeUVycl9TZXRTdHJpbmcoCisgICAgICAgICAgICAgICAgUHlFeGNfVmFsdWVFcnJvciwKKyAgICAgICAgICAgICAgICAiY2FuJ3QgdW5wYWNrIElFRUUgNzU0IHNwZWNpYWwgdmFsdWUgIgorICAgICAgICAgICAgICAgICJvbiBub24tSUVFRSBwbGF0Zm9ybSIpOworICAgICAgICAgICAgcmV0dXJuIC0xLjA7CisgICAgICAgIH0KKworICAgICAgICAvKiBUaGlyZCBieXRlICovCisgICAgICAgIGZoaSB8PSAqcCA8PCAxNjsKKyAgICAgICAgcCArPSBpbmNyOworCisgICAgICAgIC8qIEZvdXJ0aCBieXRlICovCisgICAgICAgIGZoaSB8PSAqcCAgPDwgODsKKyAgICAgICAgcCArPSBpbmNyOworCisgICAgICAgIC8qIEZpZnRoIGJ5dGUgKi8KKyAgICAgICAgZmhpIHw9ICpwOworICAgICAgICBwICs9IGluY3I7CisKKyAgICAgICAgLyogU2l4dGggYnl0ZSAqLworICAgICAgICBmbG8gPSAqcCA8PCAxNjsKKyAgICAgICAgcCArPSBpbmNyOworCisgICAgICAgIC8qIFNldmVudGggYnl0ZSAqLworICAgICAgICBmbG8gfD0gKnAgPDwgODsKKyAgICAgICAgcCArPSBpbmNyOworCisgICAgICAgIC8qIEVpZ2h0aCBieXRlICovCisgICAgICAgIGZsbyB8PSAqcDsKKworICAgICAgICB4ID0gKGRvdWJsZSlmaGkgKyAoZG91YmxlKWZsbyAvIDE2Nzc3MjE2LjA7IC8qIDIqKjI0ICovCisgICAgICAgIHggLz0gMjY4NDM1NDU2LjA7IC8qIDIqKjI4ICovCisKKyAgICAgICAgaWYgKGUgPT0gMCkKKyAgICAgICAgICAgIGUgPSAtMTAyMjsKKyAgICAgICAgZWxzZSB7CisgICAgICAgICAgICB4ICs9IDEuMDsKKyAgICAgICAgICAgIGUgLT0gMTAyMzsKKyAgICAgICAgfQorICAgICAgICB4ID0gbGRleHAoeCwgZSk7CisKKyAgICAgICAgaWYgKHNpZ24pCisgICAgICAgICAgICB4ID0gLXg7CisKKyAgICAgICAgcmV0dXJuIHg7CisgICAgfQorICAgIGVsc2UgeworICAgICAgICBkb3VibGUgeDsKKworICAgICAgICBpZiAoKGRvdWJsZV9mb3JtYXQgPT0gaWVlZV9saXR0bGVfZW5kaWFuX2Zvcm1hdCAmJiAhbGUpCisgICAgICAgICAgICB8fCAoZG91YmxlX2Zvcm1hdCA9PSBpZWVlX2JpZ19lbmRpYW5fZm9ybWF0ICYmIGxlKSkgeworICAgICAgICAgICAgY2hhciBidWZbOF07CisgICAgICAgICAgICBjaGFyICpkID0gJmJ1Zls3XTsKKyAgICAgICAgICAgIGludCBpOworCisgICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgODsgaSsrKSB7CisgICAgICAgICAgICAgICAgKmQtLSA9ICpwKys7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBtZW1jcHkoJngsIGJ1ZiwgOCk7CisgICAgICAgIH0KKyAgICAgICAgZWxzZSB7CisgICAgICAgICAgICBtZW1jcHkoJngsIHAsIDgpOworICAgICAgICB9CisKKyAgICAgICAgcmV0dXJuIHg7CisgICAgfQorfQpkaWZmIC0tZ2l0IGEvUHl0aG9uLTIuNy41L09iamVjdHMvZnJhbWVvYmplY3QuYyBiL1B5dGhvbi0yLjcuNS9PYmplY3RzL2ZyYW1lb2JqZWN0LmMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZjllNGEwZQotLS0gL2Rldi9udWxsCisrKyBiL1B5dGhvbi0yLjcuNS9PYmplY3RzL2ZyYW1lb2JqZWN0LmMKQEAgLTAsMCArMSw5ODQgQEAKKy8qIEZyYW1lIG9iamVjdCBpbXBsZW1lbnRhdGlvbiAqLworCisjaW5jbHVkZSAiUHl0aG9uLmgiCisKKyNpbmNsdWRlICJjb2RlLmgiCisjaW5jbHVkZSAiZnJhbWVvYmplY3QuaCIKKyNpbmNsdWRlICJvcGNvZGUuaCIKKyNpbmNsdWRlICJzdHJ1Y3RtZW1iZXIuaCIKKworI3VuZGVmIE1JTgorI3VuZGVmIE1BWAorI2RlZmluZSBNSU4oYSwgYikgKChhKSA8IChiKSA/IChhKSA6IChiKSkKKyNkZWZpbmUgTUFYKGEsIGIpICgoYSkgPiAoYikgPyAoYSkgOiAoYikpCisKKyNkZWZpbmUgT0ZGKHgpIG9mZnNldG9mKFB5RnJhbWVPYmplY3QsIHgpCisKK3N0YXRpYyBQeU1lbWJlckRlZiBmcmFtZV9tZW1iZXJsaXN0W10gPSB7CisgICAgeyJmX2JhY2siLCAgICAgICAgICBUX09CSkVDVCwgICAgICAgT0ZGKGZfYmFjayksICAgIFJPfSwKKyAgICB7ImZfY29kZSIsICAgICAgICAgIFRfT0JKRUNULCAgICAgICBPRkYoZl9jb2RlKSwgICAgUk99LAorICAgIHsiZl9idWlsdGlucyIsICAgICAgVF9PQkpFQ1QsICAgICAgIE9GRihmX2J1aWx0aW5zKSxST30sCisgICAgeyJmX2dsb2JhbHMiLCAgICAgICBUX09CSkVDVCwgICAgICAgT0ZGKGZfZ2xvYmFscyksIFJPfSwKKyAgICB7ImZfbGFzdGkiLCAgICAgICAgIFRfSU5ULCAgICAgICAgICBPRkYoZl9sYXN0aSksICAgUk99LAorICAgIHtOVUxMfSAgICAgIC8qIFNlbnRpbmVsICovCit9OworCisjZGVmaW5lIFdBUk5fR0VUX1NFVChOQU1FKSBcCitzdGF0aWMgUHlPYmplY3QgKiBmcmFtZV9nZXRfICMjIE5BTUUoUHlGcmFtZU9iamVjdCAqZikgeyBcCisgICAgaWYgKFB5RXJyX1dhcm5QeTNrKCNOQU1FICIgaGFzIGJlZW4gcmVtb3ZlZCBpbiAzLngiLCAyKSA8IDApIFwKKyAgICAgICAgcmV0dXJuIE5VTEw7IFwKKyAgICBpZiAoZi0+TkFNRSkgeyBcCisgICAgICAgIFB5X0lOQ1JFRihmLT5OQU1FKTsgXAorICAgICAgICByZXR1cm4gZi0+TkFNRTsgXAorICAgIH0gXAorICAgIFB5X1JFVFVSTl9OT05FOyAgICAgXAorfSBcCitzdGF0aWMgaW50IGZyYW1lX3NldF8gIyMgTkFNRShQeUZyYW1lT2JqZWN0ICpmLCBQeU9iamVjdCAqbmV3KSB7IFwKKyAgICBpZiAoUHlFcnJfV2FyblB5M2soI05BTUUgIiBoYXMgYmVlbiByZW1vdmVkIGluIDMueCIsIDIpIDwgMCkgXAorICAgICAgICByZXR1cm4gLTE7IFwKKyAgICBpZiAoZi0+TkFNRSkgeyBcCisgICAgICAgIFB5X0NMRUFSKGYtPk5BTUUpOyBcCisgICAgfSBcCisgICAgaWYgKG5ldyA9PSBQeV9Ob25lKSBcCisgICAgICAgIG5ldyA9IE5VTEw7IFwKKyAgICBQeV9YSU5DUkVGKG5ldyk7IFwKKyAgICBmLT5OQU1FID0gbmV3OyBcCisgICAgcmV0dXJuIDA7IFwKK30KKworCitXQVJOX0dFVF9TRVQoZl9leGNfdHJhY2ViYWNrKQorV0FSTl9HRVRfU0VUKGZfZXhjX3R5cGUpCitXQVJOX0dFVF9TRVQoZl9leGNfdmFsdWUpCisKKworc3RhdGljIFB5T2JqZWN0ICoKK2ZyYW1lX2dldGxvY2FscyhQeUZyYW1lT2JqZWN0ICpmLCB2b2lkICpjbG9zdXJlKQoreworICAgIFB5RnJhbWVfRmFzdFRvTG9jYWxzKGYpOworICAgIFB5X0lOQ1JFRihmLT5mX2xvY2Fscyk7CisgICAgcmV0dXJuIGYtPmZfbG9jYWxzOworfQorCitpbnQKK1B5RnJhbWVfR2V0TGluZU51bWJlcihQeUZyYW1lT2JqZWN0ICpmKQoreworICAgIGlmIChmLT5mX3RyYWNlKQorICAgICAgICByZXR1cm4gZi0+Zl9saW5lbm87CisgICAgZWxzZQorICAgICAgICByZXR1cm4gUHlDb2RlX0FkZHIyTGluZShmLT5mX2NvZGUsIGYtPmZfbGFzdGkpOworfQorCitzdGF0aWMgUHlPYmplY3QgKgorZnJhbWVfZ2V0bGluZW5vKFB5RnJhbWVPYmplY3QgKmYsIHZvaWQgKmNsb3N1cmUpCit7CisgICAgcmV0dXJuIFB5SW50X0Zyb21Mb25nKFB5RnJhbWVfR2V0TGluZU51bWJlcihmKSk7Cit9CisKKy8qIFNldHRlciBmb3IgZl9saW5lbm8gLSB5b3UgY2FuIHNldCBmX2xpbmVubyBmcm9tIHdpdGhpbiBhIHRyYWNlIGZ1bmN0aW9uIGluCisgKiBvcmRlciB0byBqdW1wIHRvIGEgZ2l2ZW4gbGluZSBvZiBjb2RlLCBzdWJqZWN0IHRvIHNvbWUgcmVzdHJpY3Rpb25zLiAgTW9zdAorICogbGluZXMgYXJlIE9LIHRvIGp1bXAgdG8gYmVjYXVzZSB0aGV5IGRvbid0IG1ha2UgYW55IGFzc3VtcHRpb25zIGFib3V0IHRoZQorICogc3RhdGUgb2YgdGhlIHN0YWNrIChvYnZpb3VzIGJlY2F1c2UgeW91IGNvdWxkIHJlbW92ZSB0aGUgbGluZSBhbmQgdGhlIGNvZGUKKyAqIHdvdWxkIHN0aWxsIHdvcmsgd2l0aG91dCBhbnkgc3RhY2sgZXJyb3JzKSwgYnV0IHRoZXJlIGFyZSBzb21lIGNvbnN0cnVjdHMKKyAqIHRoYXQgbGltaXQganVtcGluZzoKKyAqCisgKiAgbyBMaW5lcyB3aXRoIGFuICdleGNlcHQnIHN0YXRlbWVudCBvbiB0aGVtIGNhbid0IGJlIGp1bXBlZCB0bywgYmVjYXVzZQorICogICAgdGhleSBleHBlY3QgYW4gZXhjZXB0aW9uIHRvIGJlIG9uIHRoZSB0b3Agb2YgdGhlIHN0YWNrLgorICogIG8gTGluZXMgdGhhdCBsaXZlIGluIGEgJ2ZpbmFsbHknIGJsb2NrIGNhbid0IGJlIGp1bXBlZCBmcm9tIG9yIHRvLCBzaW5jZQorICogICAgdGhlIEVORF9GSU5BTExZIGV4cGVjdHMgdG8gY2xlYW4gdXAgdGhlIHN0YWNrIGFmdGVyIHRoZSAndHJ5JyBibG9jay4KKyAqICBvICd0cnknLydmb3InLyd3aGlsZScgYmxvY2tzIGNhbid0IGJlIGp1bXBlZCBpbnRvIGJlY2F1c2UgdGhlIGJsb2Nrc3RhY2sKKyAqICAgIG5lZWRzIHRvIGJlIHNldCB1cCBiZWZvcmUgdGhlaXIgY29kZSBydW5zLCBhbmQgZm9yICdmb3InIGxvb3BzIHRoZQorICogICAgaXRlcmF0b3IgbmVlZHMgdG8gYmUgb24gdGhlIHN0YWNrLgorICovCitzdGF0aWMgaW50CitmcmFtZV9zZXRsaW5lbm8oUHlGcmFtZU9iamVjdCAqZiwgUHlPYmplY3QqIHBfbmV3X2xpbmVubykKK3sKKyAgICBpbnQgbmV3X2xpbmVubyA9IDA7ICAgICAgICAgICAgICAgICAvKiBUaGUgbmV3IHZhbHVlIG9mIGZfbGluZW5vICovCisgICAgaW50IG5ld19sYXN0aSA9IDA7ICAgICAgICAgICAgICAgICAgLyogVGhlIG5ldyB2YWx1ZSBvZiBmX2xhc3RpICovCisgICAgaW50IG5ld19pYmxvY2sgPSAwOyAgICAgICAgICAgICAgICAgLyogVGhlIG5ldyB2YWx1ZSBvZiBmX2libG9jayAqLworICAgIHVuc2lnbmVkIGNoYXIgKmNvZGUgPSBOVUxMOyAgICAgICAgIC8qIFRoZSBieXRlY29kZSBmb3IgdGhlIGZyYW1lLi4uICovCisgICAgUHlfc3NpemVfdCBjb2RlX2xlbiA9IDA7ICAgICAgICAgICAgLyogLi4uYW5kIGl0cyBsZW5ndGggKi8KKyAgICB1bnNpZ25lZCBjaGFyICpsbm90YWIgPSBOVUxMOyAgICAgICAvKiBJdGVyYXRpbmcgb3ZlciBjb19sbm90YWIgKi8KKyAgICBQeV9zc2l6ZV90IGxub3RhYl9sZW4gPSAwOyAgICAgICAgICAvKiAoZGl0dG8pICovCisgICAgaW50IG9mZnNldCA9IDA7ICAgICAgICAgICAgICAgICAgICAgLyogKGRpdHRvKSAqLworICAgIGludCBsaW5lID0gMDsgICAgICAgICAgICAgICAgICAgICAgIC8qIChkaXR0bykgKi8KKyAgICBpbnQgYWRkciA9IDA7ICAgICAgICAgICAgICAgICAgICAgICAvKiAoZGl0dG8pICovCisgICAgaW50IG1pbl9hZGRyID0gMDsgICAgICAgICAgICAgICAgICAgLyogU2Nhbm5pbmcgdGhlIFNFVFVQcyBhbmQgUE9QcyAqLworICAgIGludCBtYXhfYWRkciA9IDA7ICAgICAgICAgICAgICAgICAgIC8qIChkaXR0bykgKi8KKyAgICBpbnQgZGVsdGFfaWJsb2NrID0gMDsgICAgICAgICAgICAgICAvKiAoZGl0dG8pICovCisgICAgaW50IG1pbl9kZWx0YV9pYmxvY2sgPSAwOyAgICAgICAgICAgLyogKGRpdHRvKSAqLworICAgIGludCBtaW5faWJsb2NrID0gMDsgICAgICAgICAgICAgICAgIC8qIChkaXR0bykgKi8KKyAgICBpbnQgZl9sYXN0aV9zZXR1cF9hZGRyID0gMDsgICAgICAgICAvKiBQb2xpY2luZyBuby1qdW1wLWludG8tZmluYWxseSAqLworICAgIGludCBuZXdfbGFzdGlfc2V0dXBfYWRkciA9IDA7ICAgICAgIC8qIChkaXR0bykgKi8KKyAgICBpbnQgYmxvY2tzdGFja1tDT19NQVhCTE9DS1NdOyAgICAgICAvKiBXYWxraW5nIHRoZSAnZmluYWxseScgYmxvY2tzICovCisgICAgaW50IGluX2ZpbmFsbHlbQ09fTUFYQkxPQ0tTXTsgICAgICAgLyogKGRpdHRvKSAqLworICAgIGludCBibG9ja3N0YWNrX3RvcCA9IDA7ICAgICAgICAgICAgIC8qIChkaXR0bykgKi8KKyAgICB1bnNpZ25lZCBjaGFyIHNldHVwX29wID0gMDsgICAgICAgICAvKiAoZGl0dG8pICovCisKKyAgICAvKiBmX2xpbmVubyBtdXN0IGJlIGFuIGludGVnZXIuICovCisgICAgaWYgKCFQeUludF9DaGVjayhwX25ld19saW5lbm8pKSB7CisgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19WYWx1ZUVycm9yLAorICAgICAgICAgICAgICAgICAgICAgICAgImxpbmVubyBtdXN0IGJlIGFuIGludGVnZXIiKTsKKyAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKworICAgIC8qIFlvdSBjYW4gb25seSBkbyB0aGlzIGZyb20gd2l0aGluIGEgdHJhY2UgZnVuY3Rpb24sIG5vdCB2aWEKKyAgICAgKiBfZ2V0ZnJhbWUgb3Igc2ltaWxhciBoYWNrZXJ5LiAqLworICAgIGlmICghZi0+Zl90cmFjZSkKKyAgICB7CisgICAgICAgIFB5RXJyX0Zvcm1hdChQeUV4Y19WYWx1ZUVycm9yLAorICAgICAgICAgICAgICAgICAgICAgImZfbGluZW5vIGNhbiBvbmx5IGJlIHNldCBieSBhIgorICAgICAgICAgICAgICAgICAgICAgIiBsaW5lIHRyYWNlIGZ1bmN0aW9uIik7CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisKKyAgICAvKiBGYWlsIGlmIHRoZSBsaW5lIGNvbWVzIGJlZm9yZSB0aGUgc3RhcnQgb2YgdGhlIGNvZGUgYmxvY2suICovCisgICAgbmV3X2xpbmVubyA9IChpbnQpIFB5SW50X0FzTG9uZyhwX25ld19saW5lbm8pOworICAgIGlmIChuZXdfbGluZW5vIDwgZi0+Zl9jb2RlLT5jb19maXJzdGxpbmVubykgeworICAgICAgICBQeUVycl9Gb3JtYXQoUHlFeGNfVmFsdWVFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICJsaW5lICVkIGNvbWVzIGJlZm9yZSB0aGUgY3VycmVudCBjb2RlIGJsb2NrIiwKKyAgICAgICAgICAgICAgICAgICAgIG5ld19saW5lbm8pOworICAgICAgICByZXR1cm4gLTE7CisgICAgfQorICAgIGVsc2UgaWYgKG5ld19saW5lbm8gPT0gZi0+Zl9jb2RlLT5jb19maXJzdGxpbmVubykgeworICAgICAgICBuZXdfbGFzdGkgPSAwOworICAgICAgICBuZXdfbGluZW5vID0gZi0+Zl9jb2RlLT5jb19maXJzdGxpbmVubzsKKyAgICB9CisgICAgZWxzZSB7CisgICAgICAgIC8qIEZpbmQgdGhlIGJ5dGVjb2RlIG9mZnNldCBmb3IgdGhlIHN0YXJ0IG9mIHRoZSBnaXZlbgorICAgICAgICAgKiBsaW5lLCBvciB0aGUgZmlyc3QgY29kZS1vd25pbmcgbGluZSBhZnRlciBpdC4gKi8KKyAgICAgICAgY2hhciAqdG1wOworICAgICAgICBQeVN0cmluZ19Bc1N0cmluZ0FuZFNpemUoZi0+Zl9jb2RlLT5jb19sbm90YWIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmdG1wLCAmbG5vdGFiX2xlbik7CisgICAgICAgIGxub3RhYiA9ICh1bnNpZ25lZCBjaGFyICopIHRtcDsKKyAgICAgICAgYWRkciA9IDA7CisgICAgICAgIGxpbmUgPSBmLT5mX2NvZGUtPmNvX2ZpcnN0bGluZW5vOworICAgICAgICBuZXdfbGFzdGkgPSAtMTsKKyAgICAgICAgZm9yIChvZmZzZXQgPSAwOyBvZmZzZXQgPCBsbm90YWJfbGVuOyBvZmZzZXQgKz0gMikgeworICAgICAgICAgICAgYWRkciArPSBsbm90YWJbb2Zmc2V0XTsKKyAgICAgICAgICAgIGxpbmUgKz0gbG5vdGFiW29mZnNldCsxXTsKKyAgICAgICAgICAgIGlmIChsaW5lID49IG5ld19saW5lbm8pIHsKKyAgICAgICAgICAgICAgICBuZXdfbGFzdGkgPSBhZGRyOworICAgICAgICAgICAgICAgIG5ld19saW5lbm8gPSBsaW5lOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyogSWYgd2UgZGlkbid0IHJlYWNoIHRoZSByZXF1ZXN0ZWQgbGluZSwgcmV0dXJuIGFuIGVycm9yLiAqLworICAgIGlmIChuZXdfbGFzdGkgPT0gLTEpIHsKKyAgICAgICAgUHlFcnJfRm9ybWF0KFB5RXhjX1ZhbHVlRXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAibGluZSAlZCBjb21lcyBhZnRlciB0aGUgY3VycmVudCBjb2RlIGJsb2NrIiwKKyAgICAgICAgICAgICAgICAgICAgIG5ld19saW5lbm8pOworICAgICAgICByZXR1cm4gLTE7CisgICAgfQorCisgICAgLyogV2UncmUgbm93IHJlYWR5IHRvIGxvb2sgYXQgdGhlIGJ5dGVjb2RlLiAqLworICAgIFB5U3RyaW5nX0FzU3RyaW5nQW5kU2l6ZShmLT5mX2NvZGUtPmNvX2NvZGUsIChjaGFyICoqKSZjb2RlLCAmY29kZV9sZW4pOworICAgIG1pbl9hZGRyID0gTUlOKG5ld19sYXN0aSwgZi0+Zl9sYXN0aSk7CisgICAgbWF4X2FkZHIgPSBNQVgobmV3X2xhc3RpLCBmLT5mX2xhc3RpKTsKKworICAgIC8qIFlvdSBjYW4ndCBqdW1wIG9udG8gYSBsaW5lIHdpdGggYW4gJ2V4Y2VwdCcgc3RhdGVtZW50IG9uIGl0IC0KKyAgICAgKiB0aGV5IGV4cGVjdCB0byBoYXZlIGFuIGV4Y2VwdGlvbiBvbiB0aGUgdG9wIG9mIHRoZSBzdGFjaywgd2hpY2gKKyAgICAgKiB3b24ndCBiZSB0cnVlIGlmIHlvdSBqdW1wIHRvIHRoZW0uICBUaGV5IGFsd2F5cyBzdGFydCB3aXRoIGNvZGUKKyAgICAgKiB0aGF0IGVpdGhlciBwb3BzIHRoZSBleGNlcHRpb24gdXNpbmcgUE9QX1RPUCAocGxhaW4gJ2V4Y2VwdDonCisgICAgICogbGluZXMgZG8gdGhpcykgb3IgZHVwbGljYXRlcyB0aGUgZXhjZXB0aW9uIG9uIHRoZSBzdGFjayB1c2luZworICAgICAqIERVUF9UT1AgKGlmIHRoZXJlJ3MgYW4gZXhjZXB0aW9uIHR5cGUgc3BlY2lmaWVkKS4gIFNlZSBjb21waWxlLmMsCisgICAgICogJ2NvbV90cnlfZXhjZXB0JyBmb3IgdGhlIGZ1bGwgZGV0YWlscy4gIFRoZXJlIGFyZW4ndCBhbnkgb3RoZXIKKyAgICAgKiBjYXNlcyAoQUZBSUspIHdoZXJlIGEgbGluZSdzIGNvZGUgY2FuIHN0YXJ0IHdpdGggRFVQX1RPUCBvcgorICAgICAqIFBPUF9UT1AsIGJ1dCBpZiBhbnkgZXZlciBhcHBlYXIsIHRoZXknbGwgYmUgc3ViamVjdCB0byB0aGUgc2FtZQorICAgICAqIHJlc3RyaWN0aW9uIChidXQgd2l0aCBhIGRpZmZlcmVudCBlcnJvciBtZXNzYWdlKS4gKi8KKyAgICBpZiAoY29kZVtuZXdfbGFzdGldID09IERVUF9UT1AgfHwgY29kZVtuZXdfbGFzdGldID09IFBPUF9UT1ApIHsKKyAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1ZhbHVlRXJyb3IsCisgICAgICAgICAgICAiY2FuJ3QganVtcCB0byAnZXhjZXB0JyBsaW5lIGFzIHRoZXJlJ3Mgbm8gZXhjZXB0aW9uIik7CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisKKyAgICAvKiBZb3UgY2FuJ3QganVtcCBpbnRvIG9yIG91dCBvZiBhICdmaW5hbGx5JyBibG9jayBiZWNhdXNlIHRoZSAndHJ5JworICAgICAqIGJsb2NrIGxlYXZlcyBzb21ldGhpbmcgb24gdGhlIHN0YWNrIGZvciB0aGUgRU5EX0ZJTkFMTFkgdG8gY2xlYW4KKyAgICAgKiB1cC4gICAgICBTbyB3ZSB3YWxrIHRoZSBieXRlY29kZSwgbWFpbnRhaW5pbmcgYSBzaW11bGF0ZWQgYmxvY2tzdGFjay4KKyAgICAgKiBXaGVuIHdlIHJlYWNoIHRoZSBvbGQgb3IgbmV3IGFkZHJlc3MgYW5kIGl0J3MgaW4gYSAnZmluYWxseScgYmxvY2sKKyAgICAgKiB3ZSBub3RlIHRoZSBhZGRyZXNzIG9mIHRoZSBjb3JyZXNwb25kaW5nIFNFVFVQX0ZJTkFMTFkuICBUaGUganVtcAorICAgICAqIGlzIG9ubHkgbGVnYWwgaWYgbmVpdGhlciBhZGRyZXNzIGlzIGluIGEgJ2ZpbmFsbHknIGJsb2NrIG9yCisgICAgICogdGhleSdyZSBib3RoIGluIHRoZSBzYW1lIG9uZS4gICdibG9ja3N0YWNrJyBpcyBhIHN0YWNrIG9mIHRoZQorICAgICAqIGJ5dGVjb2RlIGFkZHJlc3NlcyBvZiB0aGUgU0VUVVBfWCBvcGNvZGVzLCBhbmQgJ2luX2ZpbmFsbHknIHRyYWNrcworICAgICAqIHdoZXRoZXIgd2UncmUgaW4gYSAnZmluYWxseScgYmxvY2sgYXQgZWFjaCBibG9ja3N0YWNrIGxldmVsLiAqLworICAgIGZfbGFzdGlfc2V0dXBfYWRkciA9IC0xOworICAgIG5ld19sYXN0aV9zZXR1cF9hZGRyID0gLTE7CisgICAgbWVtc2V0KGJsb2Nrc3RhY2ssICdcMCcsIHNpemVvZihibG9ja3N0YWNrKSk7CisgICAgbWVtc2V0KGluX2ZpbmFsbHksICdcMCcsIHNpemVvZihpbl9maW5hbGx5KSk7CisgICAgYmxvY2tzdGFja190b3AgPSAwOworICAgIGZvciAoYWRkciA9IDA7IGFkZHIgPCBjb2RlX2xlbjsgYWRkcisrKSB7CisgICAgICAgIHVuc2lnbmVkIGNoYXIgb3AgPSBjb2RlW2FkZHJdOworICAgICAgICBzd2l0Y2ggKG9wKSB7CisgICAgICAgIGNhc2UgU0VUVVBfTE9PUDoKKyAgICAgICAgY2FzZSBTRVRVUF9FWENFUFQ6CisgICAgICAgIGNhc2UgU0VUVVBfRklOQUxMWToKKyAgICAgICAgY2FzZSBTRVRVUF9XSVRIOgorICAgICAgICAgICAgYmxvY2tzdGFja1tibG9ja3N0YWNrX3RvcCsrXSA9IGFkZHI7CisgICAgICAgICAgICBpbl9maW5hbGx5W2Jsb2Nrc3RhY2tfdG9wLTFdID0gMDsKKyAgICAgICAgICAgIGJyZWFrOworCisgICAgICAgIGNhc2UgUE9QX0JMT0NLOgorICAgICAgICAgICAgYXNzZXJ0KGJsb2Nrc3RhY2tfdG9wID4gMCk7CisgICAgICAgICAgICBzZXR1cF9vcCA9IGNvZGVbYmxvY2tzdGFja1tibG9ja3N0YWNrX3RvcC0xXV07CisgICAgICAgICAgICBpZiAoc2V0dXBfb3AgPT0gU0VUVVBfRklOQUxMWSB8fCBzZXR1cF9vcCA9PSBTRVRVUF9XSVRIKSB7CisgICAgICAgICAgICAgICAgaW5fZmluYWxseVtibG9ja3N0YWNrX3RvcC0xXSA9IDE7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBlbHNlIHsKKyAgICAgICAgICAgICAgICBibG9ja3N0YWNrX3RvcC0tOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYnJlYWs7CisKKyAgICAgICAgY2FzZSBFTkRfRklOQUxMWToKKyAgICAgICAgICAgIC8qIElnbm9yZSBFTkRfRklOQUxMWXMgZm9yIFNFVFVQX0VYQ0VQVHMgLSB0aGV5IGV4aXN0CisgICAgICAgICAgICAgKiBpbiB0aGUgYnl0ZWNvZGUgYnV0IGRvbid0IGNvcnJlc3BvbmQgdG8gYW4gYWN0dWFsCisgICAgICAgICAgICAgKiAnZmluYWxseScgYmxvY2suICAoSWYgYmxvY2tzdGFja190b3AgaXMgMCwgd2UgbXVzdAorICAgICAgICAgICAgICogYmUgc2VlaW5nIHN1Y2ggYW4gRU5EX0ZJTkFMTFkuKSAqLworICAgICAgICAgICAgaWYgKGJsb2Nrc3RhY2tfdG9wID4gMCkgeworICAgICAgICAgICAgICAgIHNldHVwX29wID0gY29kZVtibG9ja3N0YWNrW2Jsb2Nrc3RhY2tfdG9wLTFdXTsKKyAgICAgICAgICAgICAgICBpZiAoc2V0dXBfb3AgPT0gU0VUVVBfRklOQUxMWSB8fCBzZXR1cF9vcCA9PSBTRVRVUF9XSVRIKSB7CisgICAgICAgICAgICAgICAgICAgIGJsb2Nrc3RhY2tfdG9wLS07CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKworICAgICAgICAvKiBGb3IgdGhlIGFkZHJlc3NlcyB3ZSdyZSBpbnRlcmVzdGVkIGluLCBzZWUgd2hldGhlciB0aGV5J3JlCisgICAgICAgICAqIHdpdGhpbiBhICdmaW5hbGx5JyBibG9jayBhbmQgaWYgc28sIHJlbWVtYmVyIHRoZSBhZGRyZXNzCisgICAgICAgICAqIG9mIHRoZSBTRVRVUF9GSU5BTExZLiAqLworICAgICAgICBpZiAoYWRkciA9PSBuZXdfbGFzdGkgfHwgYWRkciA9PSBmLT5mX2xhc3RpKSB7CisgICAgICAgICAgICBpbnQgaSA9IDA7CisgICAgICAgICAgICBpbnQgc2V0dXBfYWRkciA9IC0xOworICAgICAgICAgICAgZm9yIChpID0gYmxvY2tzdGFja190b3AtMTsgaSA+PSAwOyBpLS0pIHsKKyAgICAgICAgICAgICAgICBpZiAoaW5fZmluYWxseVtpXSkgeworICAgICAgICAgICAgICAgICAgICBzZXR1cF9hZGRyID0gYmxvY2tzdGFja1tpXTsKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorCisgICAgICAgICAgICBpZiAoc2V0dXBfYWRkciAhPSAtMSkgeworICAgICAgICAgICAgICAgIGlmIChhZGRyID09IG5ld19sYXN0aSkgeworICAgICAgICAgICAgICAgICAgICBuZXdfbGFzdGlfc2V0dXBfYWRkciA9IHNldHVwX2FkZHI7CisgICAgICAgICAgICAgICAgfQorCisgICAgICAgICAgICAgICAgaWYgKGFkZHIgPT0gZi0+Zl9sYXN0aSkgeworICAgICAgICAgICAgICAgICAgICBmX2xhc3RpX3NldHVwX2FkZHIgPSBzZXR1cF9hZGRyOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIGlmIChvcCA+PSBIQVZFX0FSR1VNRU5UKSB7CisgICAgICAgICAgICBhZGRyICs9IDI7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKiBWZXJpZnkgdGhhdCB0aGUgYmxvY2tzdGFjayB0cmFja2luZyBjb2RlIGRpZG4ndCBnZXQgbG9zdC4gKi8KKyAgICBhc3NlcnQoYmxvY2tzdGFja190b3AgPT0gMCk7CisKKyAgICAvKiBBZnRlciBhbGwgdGhhdCwgYXJlIHdlIGp1bXBpbmcgaW50byAvIG91dCBvZiBhICdmaW5hbGx5JyBibG9jaz8gKi8KKyAgICBpZiAobmV3X2xhc3RpX3NldHVwX2FkZHIgIT0gZl9sYXN0aV9zZXR1cF9hZGRyKSB7CisgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19WYWx1ZUVycm9yLAorICAgICAgICAgICAgICAgICAgICAiY2FuJ3QganVtcCBpbnRvIG9yIG91dCBvZiBhICdmaW5hbGx5JyBibG9jayIpOworICAgICAgICByZXR1cm4gLTE7CisgICAgfQorCisKKyAgICAvKiBQb2xpY2UgYmxvY2stanVtcGluZyAoeW91IGNhbid0IGp1bXAgaW50byB0aGUgbWlkZGxlIG9mIGEgYmxvY2spCisgICAgICogYW5kIGVuc3VyZSB0aGF0IHRoZSBibG9ja3N0YWNrIGZpbmlzaGVzIHVwIGluIGEgc2Vuc2libGUgc3RhdGUgKGJ5CisgICAgICogcG9wcGluZyBhbnkgYmxvY2tzIHdlJ3JlIGp1bXBpbmcgb3V0IG9mKS4gIFdlIGxvb2sgYXQgYWxsIHRoZQorICAgICAqIGJsb2Nrc3RhY2sgb3BlcmF0aW9ucyBiZXR3ZWVuIHRoZSBjdXJyZW50IHBvc2l0aW9uIGFuZCB0aGUgbmV3CisgICAgICogb25lLCBhbmQga2VlcCB0cmFjayBvZiBob3cgbWFueSBibG9ja3Mgd2UgZHJvcCBvdXQgb2Ygb24gdGhlIHdheS4KKyAgICAgKiBCeSBhbHNvIGtlZXBpbmcgdHJhY2sgb2YgdGhlIGxvd2VzdCBibG9ja3N0YWNrIHBvc2l0aW9uIHdlIHNlZSwgd2UKKyAgICAgKiBjYW4gdGVsbCB3aGV0aGVyIHRoZSBqdW1wIGdvZXMgaW50byBhbnkgYmxvY2tzIHdpdGhvdXQgY29taW5nIG91dAorICAgICAqIGFnYWluIC0gaW4gdGhhdCBjYXNlIHdlIHJhaXNlIGFuIGV4Y2VwdGlvbiBiZWxvdy4gKi8KKyAgICBkZWx0YV9pYmxvY2sgPSAwOworICAgIGZvciAoYWRkciA9IG1pbl9hZGRyOyBhZGRyIDwgbWF4X2FkZHI7IGFkZHIrKykgeworICAgICAgICB1bnNpZ25lZCBjaGFyIG9wID0gY29kZVthZGRyXTsKKyAgICAgICAgc3dpdGNoIChvcCkgeworICAgICAgICBjYXNlIFNFVFVQX0xPT1A6CisgICAgICAgIGNhc2UgU0VUVVBfRVhDRVBUOgorICAgICAgICBjYXNlIFNFVFVQX0ZJTkFMTFk6CisgICAgICAgIGNhc2UgU0VUVVBfV0lUSDoKKyAgICAgICAgICAgIGRlbHRhX2libG9jaysrOworICAgICAgICAgICAgYnJlYWs7CisKKyAgICAgICAgY2FzZSBQT1BfQkxPQ0s6CisgICAgICAgICAgICBkZWx0YV9pYmxvY2stLTsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisKKyAgICAgICAgbWluX2RlbHRhX2libG9jayA9IE1JTihtaW5fZGVsdGFfaWJsb2NrLCBkZWx0YV9pYmxvY2spOworCisgICAgICAgIGlmIChvcCA+PSBIQVZFX0FSR1VNRU5UKSB7CisgICAgICAgICAgICBhZGRyICs9IDI7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKiBEZXJpdmUgdGhlIGFic29sdXRlIGlibG9jayB2YWx1ZXMgZnJvbSB0aGUgZGVsdGFzLiAqLworICAgIG1pbl9pYmxvY2sgPSBmLT5mX2libG9jayArIG1pbl9kZWx0YV9pYmxvY2s7CisgICAgaWYgKG5ld19sYXN0aSA+IGYtPmZfbGFzdGkpIHsKKyAgICAgICAgLyogRm9yd2FyZHMganVtcC4gKi8KKyAgICAgICAgbmV3X2libG9jayA9IGYtPmZfaWJsb2NrICsgZGVsdGFfaWJsb2NrOworICAgIH0KKyAgICBlbHNlIHsKKyAgICAgICAgLyogQmFja3dhcmRzIGp1bXAuICovCisgICAgICAgIG5ld19pYmxvY2sgPSBmLT5mX2libG9jayAtIGRlbHRhX2libG9jazsKKyAgICB9CisKKyAgICAvKiBBcmUgd2UganVtcGluZyBpbnRvIGEgYmxvY2s/ICovCisgICAgaWYgKG5ld19pYmxvY2sgPiBtaW5faWJsb2NrKSB7CisgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19WYWx1ZUVycm9yLAorICAgICAgICAgICAgICAgICAgICAgICAgImNhbid0IGp1bXAgaW50byB0aGUgbWlkZGxlIG9mIGEgYmxvY2siKTsKKyAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKworICAgIC8qIFBvcCBhbnkgYmxvY2tzIHRoYXQgd2UncmUganVtcGluZyBvdXQgb2YuICovCisgICAgd2hpbGUgKGYtPmZfaWJsb2NrID4gbmV3X2libG9jaykgeworICAgICAgICBQeVRyeUJsb2NrICpiID0gJmYtPmZfYmxvY2tzdGFja1stLWYtPmZfaWJsb2NrXTsKKyAgICAgICAgd2hpbGUgKChmLT5mX3N0YWNrdG9wIC0gZi0+Zl92YWx1ZXN0YWNrKSA+IGItPmJfbGV2ZWwpIHsKKyAgICAgICAgICAgIFB5T2JqZWN0ICp2ID0gKCotLWYtPmZfc3RhY2t0b3ApOworICAgICAgICAgICAgUHlfREVDUkVGKHYpOworICAgICAgICB9CisgICAgfQorCisgICAgLyogRmluYWxseSBzZXQgdGhlIG5ldyBmX2xpbmVubyBhbmQgZl9sYXN0aSBhbmQgcmV0dXJuIE9LLiAqLworICAgIGYtPmZfbGluZW5vID0gbmV3X2xpbmVubzsKKyAgICBmLT5mX2xhc3RpID0gbmV3X2xhc3RpOworICAgIHJldHVybiAwOworfQorCitzdGF0aWMgUHlPYmplY3QgKgorZnJhbWVfZ2V0dHJhY2UoUHlGcmFtZU9iamVjdCAqZiwgdm9pZCAqY2xvc3VyZSkKK3sKKyAgICBQeU9iamVjdCogdHJhY2UgPSBmLT5mX3RyYWNlOworCisgICAgaWYgKHRyYWNlID09IE5VTEwpCisgICAgICAgIHRyYWNlID0gUHlfTm9uZTsKKworICAgIFB5X0lOQ1JFRih0cmFjZSk7CisKKyAgICByZXR1cm4gdHJhY2U7Cit9CisKK3N0YXRpYyBpbnQKK2ZyYW1lX3NldHRyYWNlKFB5RnJhbWVPYmplY3QgKmYsIFB5T2JqZWN0KiB2LCB2b2lkICpjbG9zdXJlKQoreworICAgIFB5T2JqZWN0KiBvbGRfdmFsdWU7CisKKyAgICAvKiBXZSByZWx5IG9uIGZfbGluZW5vIGJlaW5nIGFjY3VyYXRlIHdoZW4gZl90cmFjZSBpcyBzZXQuICovCisgICAgZi0+Zl9saW5lbm8gPSBQeUZyYW1lX0dldExpbmVOdW1iZXIoZik7CisKKyAgICBvbGRfdmFsdWUgPSBmLT5mX3RyYWNlOworICAgIFB5X1hJTkNSRUYodik7CisgICAgZi0+Zl90cmFjZSA9IHY7CisgICAgUHlfWERFQ1JFRihvbGRfdmFsdWUpOworCisgICAgcmV0dXJuIDA7Cit9CisKK3N0YXRpYyBQeU9iamVjdCAqCitmcmFtZV9nZXRyZXN0cmljdGVkKFB5RnJhbWVPYmplY3QgKmYsIHZvaWQgKmNsb3N1cmUpCit7CisgICAgcmV0dXJuIFB5Qm9vbF9Gcm9tTG9uZyhQeUZyYW1lX0lzUmVzdHJpY3RlZChmKSk7Cit9CisKK3N0YXRpYyBQeUdldFNldERlZiBmcmFtZV9nZXRzZXRsaXN0W10gPSB7CisgICAgeyJmX2xvY2FscyIsICAgICAgICAoZ2V0dGVyKWZyYW1lX2dldGxvY2FscywgTlVMTCwgTlVMTH0sCisgICAgeyJmX2xpbmVubyIsICAgICAgICAoZ2V0dGVyKWZyYW1lX2dldGxpbmVubywKKyAgICAgICAgICAgICAgICAgICAgKHNldHRlcilmcmFtZV9zZXRsaW5lbm8sIE5VTEx9LAorICAgIHsiZl90cmFjZSIsICAgICAgICAgKGdldHRlcilmcmFtZV9nZXR0cmFjZSwgKHNldHRlcilmcmFtZV9zZXR0cmFjZSwgTlVMTH0sCisgICAgeyJmX3Jlc3RyaWN0ZWQiLChnZXR0ZXIpZnJhbWVfZ2V0cmVzdHJpY3RlZCxOVUxMLCBOVUxMfSwKKyAgICB7ImZfZXhjX3RyYWNlYmFjayIsIChnZXR0ZXIpZnJhbWVfZ2V0X2ZfZXhjX3RyYWNlYmFjaywKKyAgICAgICAgICAgICAgICAgICAgKHNldHRlcilmcmFtZV9zZXRfZl9leGNfdHJhY2ViYWNrLCBOVUxMfSwKKyAgICB7ImZfZXhjX3R5cGUiLCAgKGdldHRlcilmcmFtZV9nZXRfZl9leGNfdHlwZSwKKyAgICAgICAgICAgICAgICAgICAgKHNldHRlcilmcmFtZV9zZXRfZl9leGNfdHlwZSwgTlVMTH0sCisgICAgeyJmX2V4Y192YWx1ZSIsIChnZXR0ZXIpZnJhbWVfZ2V0X2ZfZXhjX3ZhbHVlLAorICAgICAgICAgICAgICAgICAgICAoc2V0dGVyKWZyYW1lX3NldF9mX2V4Y192YWx1ZSwgTlVMTH0sCisgICAgezB9Cit9OworCisvKiBTdGFjayBmcmFtZXMgYXJlIGFsbG9jYXRlZCBhbmQgZGVhbGxvY2F0ZWQgYXQgYSBjb25zaWRlcmFibGUgcmF0ZS4KKyAgIEluIGFuIGF0dGVtcHQgdG8gaW1wcm92ZSB0aGUgc3BlZWQgb2YgZnVuY3Rpb24gY2FsbHMsIHdlOgorCisgICAxLiBIb2xkIGEgc2luZ2xlICJ6b21iaWUiIGZyYW1lIG9uIGVhY2ggY29kZSBvYmplY3QuIFRoaXMgcmV0YWlucworICAgdGhlIGFsbG9jYXRlZCBhbmQgaW5pdGlhbGlzZWQgZnJhbWUgb2JqZWN0IGZyb20gYW4gaW52b2NhdGlvbiBvZgorICAgdGhlIGNvZGUgb2JqZWN0LiBUaGUgem9tYmllIGlzIHJlYW5pbWF0ZWQgdGhlIG5leHQgdGltZSB3ZSBuZWVkIGEKKyAgIGZyYW1lIG9iamVjdCBmb3IgdGhhdCBjb2RlIG9iamVjdC4gRG9pbmcgdGhpcyBzYXZlcyB0aGUgbWFsbG9jLworICAgcmVhbGxvYyByZXF1aXJlZCB3aGVuIHVzaW5nIGEgZnJlZV9saXN0IGZyYW1lIHRoYXQgaXNuJ3QgdGhlCisgICBjb3JyZWN0IHNpemUuIEl0IGFsc28gc2F2ZXMgc29tZSBmaWVsZCBpbml0aWFsaXNhdGlvbi4KKworICAgSW4gem9tYmllIG1vZGUsIG5vIGZpZWxkIG9mIFB5RnJhbWVPYmplY3QgaG9sZHMgYSByZWZlcmVuY2UsIGJ1dAorICAgdGhlIGZvbGxvd2luZyBmaWVsZHMgYXJlIHN0aWxsIHZhbGlkOgorCisgICAgICogb2JfdHlwZSwgb2Jfc2l6ZSwgZl9jb2RlLCBmX3ZhbHVlc3RhY2s7CisKKyAgICAgKiBmX2xvY2FscywgZl90cmFjZSwKKyAgICAgICBmX2V4Y190eXBlLCBmX2V4Y192YWx1ZSwgZl9leGNfdHJhY2ViYWNrIGFyZSBOVUxMOworCisgICAgICogZl9sb2NhbHNwbHVzIGRvZXMgbm90IHJlcXVpcmUgcmUtYWxsb2NhdGlvbiBhbmQKKyAgICAgICB0aGUgbG9jYWwgdmFyaWFibGVzIGluIGZfbG9jYWxzcGx1cyBhcmUgTlVMTC4KKworICAgMi4gV2UgYWxzbyBtYWludGFpbiBhIHNlcGFyYXRlIGZyZWUgbGlzdCBvZiBzdGFjayBmcmFtZXMgKGp1c3QgbGlrZQorICAgaW50ZWdlcnMgYXJlIGFsbG9jYXRlZCBpbiBhIHNwZWNpYWwgd2F5IC0tIHNlZSBpbnRvYmplY3QuYykuICBXaGVuCisgICBhIHN0YWNrIGZyYW1lIGlzIG9uIHRoZSBmcmVlIGxpc3QsIG9ubHkgdGhlIGZvbGxvd2luZyBtZW1iZXJzIGhhdmUKKyAgIGEgbWVhbmluZzoKKyAgICBvYl90eXBlICAgICAgICAgICAgID09ICZGcmFtZXR5cGUKKyAgICBmX2JhY2sgICAgICAgICAgICAgIG5leHQgaXRlbSBvbiBmcmVlIGxpc3QsIG9yIE5VTEwKKyAgICBmX3N0YWNrc2l6ZSAgICAgICAgIHNpemUgb2YgdmFsdWUgc3RhY2sKKyAgICBvYl9zaXplICAgICAgICAgICAgIHNpemUgb2YgbG9jYWxzcGx1cworICAgTm90ZSB0aGF0IHRoZSB2YWx1ZSBhbmQgYmxvY2sgc3RhY2tzIGFyZSBwcmVzZXJ2ZWQgLS0gdGhpcyBjYW4gc2F2ZQorICAgYW5vdGhlciBtYWxsb2MoKSBjYWxsIG9yIHR3byAoYW5kIHR3byBmcmVlKCkgY2FsbHMgYXMgd2VsbCEpLgorICAgQWxzbyBub3RlIHRoYXQsIHVubGlrZSBmb3IgaW50ZWdlcnMsIGVhY2ggZnJhbWUgb2JqZWN0IGlzIGEKKyAgIG1hbGxvYydlZCBvYmplY3QgaW4gaXRzIG93biByaWdodCAtLSBpdCBpcyBvbmx5IHRoZSBhY3R1YWwgY2FsbHMgdG8KKyAgIG1hbGxvYygpIHRoYXQgd2UgYXJlIHRyeWluZyB0byBzYXZlIGhlcmUsIG5vdCB0aGUgYWRtaW5pc3RyYXRpb24uCisgICBBZnRlciBhbGwsIHdoaWxlIGEgdHlwaWNhbCBwcm9ncmFtIG1heSBtYWtlIG1pbGxpb25zIG9mIGNhbGxzLCBhCisgICBjYWxsIGRlcHRoIG9mIG1vcmUgdGhhbiAyMCBvciAzMCBpcyBwcm9iYWJseSBhbHJlYWR5IGV4Y2VwdGlvbmFsCisgICB1bmxlc3MgdGhlIHByb2dyYW0gY29udGFpbnMgcnVuLWF3YXkgcmVjdXJzaW9uLiAgSSBob3BlLgorCisgICBMYXRlciwgUHlGcmFtZV9NQVhGUkVFTElTVCB3YXMgYWRkZWQgdG8gYm91bmQgdGhlICMgb2YgZnJhbWVzIHNhdmVkIG9uCisgICBmcmVlX2xpc3QuICBFbHNlIHByb2dyYW1zIGNyZWF0aW5nIGxvdHMgb2YgY3ljbGljIHRyYXNoIGludm9sdmluZworICAgZnJhbWVzIGNvdWxkIHByb3Zva2UgZnJlZV9saXN0IGludG8gZ3Jvd2luZyB3aXRob3V0IGJvdW5kLgorKi8KKworc3RhdGljIFB5RnJhbWVPYmplY3QgKmZyZWVfbGlzdCA9IE5VTEw7CitzdGF0aWMgaW50IG51bWZyZWUgPSAwOyAgICAgICAgIC8qIG51bWJlciBvZiBmcmFtZXMgY3VycmVudGx5IGluIGZyZWVfbGlzdCAqLworLyogbWF4IHZhbHVlIGZvciBudW1mcmVlICovCisjZGVmaW5lIFB5RnJhbWVfTUFYRlJFRUxJU1QgMjAwCisKK3N0YXRpYyB2b2lkCitmcmFtZV9kZWFsbG9jKFB5RnJhbWVPYmplY3QgKmYpCit7CisgICAgUHlPYmplY3QgKipwLCAqKnZhbHVlc3RhY2s7CisgICAgUHlDb2RlT2JqZWN0ICpjbzsKKworICAgIFB5T2JqZWN0X0dDX1VuVHJhY2soZik7CisgICAgUHlfVFJBU0hDQU5fU0FGRV9CRUdJTihmKQorICAgIC8qIEtpbGwgYWxsIGxvY2FsIHZhcmlhYmxlcyAqLworICAgIHZhbHVlc3RhY2sgPSBmLT5mX3ZhbHVlc3RhY2s7CisgICAgZm9yIChwID0gZi0+Zl9sb2NhbHNwbHVzOyBwIDwgdmFsdWVzdGFjazsgcCsrKQorICAgICAgICBQeV9DTEVBUigqcCk7CisKKyAgICAvKiBGcmVlIHN0YWNrICovCisgICAgaWYgKGYtPmZfc3RhY2t0b3AgIT0gTlVMTCkgeworICAgICAgICBmb3IgKHAgPSB2YWx1ZXN0YWNrOyBwIDwgZi0+Zl9zdGFja3RvcDsgcCsrKQorICAgICAgICAgICAgUHlfWERFQ1JFRigqcCk7CisgICAgfQorCisgICAgUHlfWERFQ1JFRihmLT5mX2JhY2spOworICAgIFB5X0RFQ1JFRihmLT5mX2J1aWx0aW5zKTsKKyAgICBQeV9ERUNSRUYoZi0+Zl9nbG9iYWxzKTsKKyAgICBQeV9DTEVBUihmLT5mX2xvY2Fscyk7CisgICAgUHlfQ0xFQVIoZi0+Zl90cmFjZSk7CisgICAgUHlfQ0xFQVIoZi0+Zl9leGNfdHlwZSk7CisgICAgUHlfQ0xFQVIoZi0+Zl9leGNfdmFsdWUpOworICAgIFB5X0NMRUFSKGYtPmZfZXhjX3RyYWNlYmFjayk7CisKKyAgICBjbyA9IGYtPmZfY29kZTsKKyAgICBpZiAoY28tPmNvX3pvbWJpZWZyYW1lID09IE5VTEwpCisgICAgICAgIGNvLT5jb196b21iaWVmcmFtZSA9IGY7CisgICAgZWxzZSBpZiAobnVtZnJlZSA8IFB5RnJhbWVfTUFYRlJFRUxJU1QpIHsKKyAgICAgICAgKytudW1mcmVlOworICAgICAgICBmLT5mX2JhY2sgPSBmcmVlX2xpc3Q7CisgICAgICAgIGZyZWVfbGlzdCA9IGY7CisgICAgfQorICAgIGVsc2UKKyAgICAgICAgUHlPYmplY3RfR0NfRGVsKGYpOworCisgICAgUHlfREVDUkVGKGNvKTsKKyAgICBQeV9UUkFTSENBTl9TQUZFX0VORChmKQorfQorCitzdGF0aWMgaW50CitmcmFtZV90cmF2ZXJzZShQeUZyYW1lT2JqZWN0ICpmLCB2aXNpdHByb2MgdmlzaXQsIHZvaWQgKmFyZykKK3sKKyAgICBQeU9iamVjdCAqKmZhc3Rsb2NhbHMsICoqcDsKKyAgICBpbnQgaSwgc2xvdHM7CisKKyAgICBQeV9WSVNJVChmLT5mX2JhY2spOworICAgIFB5X1ZJU0lUKGYtPmZfY29kZSk7CisgICAgUHlfVklTSVQoZi0+Zl9idWlsdGlucyk7CisgICAgUHlfVklTSVQoZi0+Zl9nbG9iYWxzKTsKKyAgICBQeV9WSVNJVChmLT5mX2xvY2Fscyk7CisgICAgUHlfVklTSVQoZi0+Zl90cmFjZSk7CisgICAgUHlfVklTSVQoZi0+Zl9leGNfdHlwZSk7CisgICAgUHlfVklTSVQoZi0+Zl9leGNfdmFsdWUpOworICAgIFB5X1ZJU0lUKGYtPmZfZXhjX3RyYWNlYmFjayk7CisKKyAgICAvKiBsb2NhbHMgKi8KKyAgICBzbG90cyA9IGYtPmZfY29kZS0+Y29fbmxvY2FscyArIFB5VHVwbGVfR0VUX1NJWkUoZi0+Zl9jb2RlLT5jb19jZWxsdmFycykgKyBQeVR1cGxlX0dFVF9TSVpFKGYtPmZfY29kZS0+Y29fZnJlZXZhcnMpOworICAgIGZhc3Rsb2NhbHMgPSBmLT5mX2xvY2Fsc3BsdXM7CisgICAgZm9yIChpID0gc2xvdHM7IC0taSA+PSAwOyArK2Zhc3Rsb2NhbHMpCisgICAgICAgIFB5X1ZJU0lUKCpmYXN0bG9jYWxzKTsKKworICAgIC8qIHN0YWNrICovCisgICAgaWYgKGYtPmZfc3RhY2t0b3AgIT0gTlVMTCkgeworICAgICAgICBmb3IgKHAgPSBmLT5mX3ZhbHVlc3RhY2s7IHAgPCBmLT5mX3N0YWNrdG9wOyBwKyspCisgICAgICAgICAgICBQeV9WSVNJVCgqcCk7CisgICAgfQorICAgIHJldHVybiAwOworfQorCitzdGF0aWMgdm9pZAorZnJhbWVfY2xlYXIoUHlGcmFtZU9iamVjdCAqZikKK3sKKyAgICBQeU9iamVjdCAqKmZhc3Rsb2NhbHMsICoqcCwgKipvbGR0b3A7CisgICAgaW50IGksIHNsb3RzOworCisgICAgLyogQmVmb3JlIGFueXRoaW5nIGVsc2UsIG1ha2Ugc3VyZSB0aGF0IHRoaXMgZnJhbWUgaXMgY2xlYXJseSBtYXJrZWQKKyAgICAgKiBhcyBiZWluZyBkZWZ1bmN0ISAgRWxzZSwgZS5nLiwgYSBnZW5lcmF0b3IgcmVhY2hhYmxlIGZyb20gdGhpcworICAgICAqIGZyYW1lIG1heSBhbHNvIHBvaW50IHRvIHRoaXMgZnJhbWUsIGJlbGlldmUgaXRzZWxmIHRvIHN0aWxsIGJlCisgICAgICogYWN0aXZlLCBhbmQgdHJ5IGNsZWFuaW5nIHVwIHRoaXMgZnJhbWUgYWdhaW4uCisgICAgICovCisgICAgb2xkdG9wID0gZi0+Zl9zdGFja3RvcDsKKyAgICBmLT5mX3N0YWNrdG9wID0gTlVMTDsKKworICAgIFB5X0NMRUFSKGYtPmZfZXhjX3R5cGUpOworICAgIFB5X0NMRUFSKGYtPmZfZXhjX3ZhbHVlKTsKKyAgICBQeV9DTEVBUihmLT5mX2V4Y190cmFjZWJhY2spOworICAgIFB5X0NMRUFSKGYtPmZfdHJhY2UpOworCisgICAgLyogbG9jYWxzICovCisgICAgc2xvdHMgPSBmLT5mX2NvZGUtPmNvX25sb2NhbHMgKyBQeVR1cGxlX0dFVF9TSVpFKGYtPmZfY29kZS0+Y29fY2VsbHZhcnMpICsgUHlUdXBsZV9HRVRfU0laRShmLT5mX2NvZGUtPmNvX2ZyZWV2YXJzKTsKKyAgICBmYXN0bG9jYWxzID0gZi0+Zl9sb2NhbHNwbHVzOworICAgIGZvciAoaSA9IHNsb3RzOyAtLWkgPj0gMDsgKytmYXN0bG9jYWxzKQorICAgICAgICBQeV9DTEVBUigqZmFzdGxvY2Fscyk7CisKKyAgICAvKiBzdGFjayAqLworICAgIGlmIChvbGR0b3AgIT0gTlVMTCkgeworICAgICAgICBmb3IgKHAgPSBmLT5mX3ZhbHVlc3RhY2s7IHAgPCBvbGR0b3A7IHArKykKKyAgICAgICAgICAgIFB5X0NMRUFSKCpwKTsKKyAgICB9Cit9CisKK3N0YXRpYyBQeU9iamVjdCAqCitmcmFtZV9zaXplb2YoUHlGcmFtZU9iamVjdCAqZikKK3sKKyAgICBQeV9zc2l6ZV90IHJlcywgZXh0cmFzLCBuY2VsbHMsIG5mcmVlczsKKworICAgIG5jZWxscyA9IFB5VHVwbGVfR0VUX1NJWkUoZi0+Zl9jb2RlLT5jb19jZWxsdmFycyk7CisgICAgbmZyZWVzID0gUHlUdXBsZV9HRVRfU0laRShmLT5mX2NvZGUtPmNvX2ZyZWV2YXJzKTsKKyAgICBleHRyYXMgPSBmLT5mX2NvZGUtPmNvX3N0YWNrc2l6ZSArIGYtPmZfY29kZS0+Y29fbmxvY2FscyArCisgICAgICAgICAgICAgbmNlbGxzICsgbmZyZWVzOworICAgIC8qIHN1YnRyYWN0IG9uZSBhcyBpdCBpcyBhbHJlYWR5IGluY2x1ZGVkIGluIFB5RnJhbWVPYmplY3QgKi8KKyAgICByZXMgPSBzaXplb2YoUHlGcmFtZU9iamVjdCkgKyAoZXh0cmFzLTEpICogc2l6ZW9mKFB5T2JqZWN0ICopOworCisgICAgcmV0dXJuIFB5SW50X0Zyb21Tc2l6ZV90KHJlcyk7Cit9CisKK1B5RG9jX1NUUlZBUihzaXplb2ZfX2RvY19fLAorIkYuX19zaXplb2ZfXygpIC0+IHNpemUgb2YgRiBpbiBtZW1vcnksIGluIGJ5dGVzIik7CisKK3N0YXRpYyBQeU1ldGhvZERlZiBmcmFtZV9tZXRob2RzW10gPSB7CisgICAgeyJfX3NpemVvZl9fIiwgICAgICAoUHlDRnVuY3Rpb24pZnJhbWVfc2l6ZW9mLCAgICAgIE1FVEhfTk9BUkdTLAorICAgICBzaXplb2ZfX2RvY19ffSwKKyAgICB7TlVMTCwgICAgICAgICAgICAgIE5VTEx9ICAgLyogc2VudGluZWwgKi8KK307CisKK1B5VHlwZU9iamVjdCBQeUZyYW1lX1R5cGUgPSB7CisgICAgUHlWYXJPYmplY3RfSEVBRF9JTklUKCZQeVR5cGVfVHlwZSwgMCkKKyAgICAiZnJhbWUiLAorICAgIHNpemVvZihQeUZyYW1lT2JqZWN0KSwKKyAgICBzaXplb2YoUHlPYmplY3QgKiksCisgICAgKGRlc3RydWN0b3IpZnJhbWVfZGVhbGxvYywgICAgICAgICAgICAgICAgICAvKiB0cF9kZWFsbG9jICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9wcmludCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZ2V0YXR0ciAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfc2V0YXR0ciAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfY29tcGFyZSAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfcmVwciAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfYXNfbnVtYmVyICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9hc19zZXF1ZW5jZSAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfYXNfbWFwcGluZyAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfaGFzaCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfY2FsbCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfc3RyICovCisgICAgUHlPYmplY3RfR2VuZXJpY0dldEF0dHIsICAgICAgICAgICAgICAgICAgICAvKiB0cF9nZXRhdHRybyAqLworICAgIFB5T2JqZWN0X0dlbmVyaWNTZXRBdHRyLCAgICAgICAgICAgICAgICAgICAgLyogdHBfc2V0YXR0cm8gKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2FzX2J1ZmZlciAqLworICAgIFB5X1RQRkxBR1NfREVGQVVMVCB8IFB5X1RQRkxBR1NfSEFWRV9HQywvKiB0cF9mbGFncyAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZG9jICovCisgICAgKHRyYXZlcnNlcHJvYylmcmFtZV90cmF2ZXJzZSwgICAgICAgICAgICAgICAvKiB0cF90cmF2ZXJzZSAqLworICAgIChpbnF1aXJ5KWZyYW1lX2NsZWFyLCAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfY2xlYXIgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3JpY2hjb21wYXJlICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF93ZWFrbGlzdG9mZnNldCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfaXRlciAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfaXRlcm5leHQgKi8KKyAgICBmcmFtZV9tZXRob2RzLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX21ldGhvZHMgKi8KKyAgICBmcmFtZV9tZW1iZXJsaXN0LCAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX21lbWJlcnMgKi8KKyAgICBmcmFtZV9nZXRzZXRsaXN0LCAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2dldHNldCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfYmFzZSAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZGljdCAqLworfTsKKworc3RhdGljIFB5T2JqZWN0ICpidWlsdGluX29iamVjdDsKKworaW50IF9QeUZyYW1lX0luaXQoKQoreworICAgIGJ1aWx0aW5fb2JqZWN0ID0gUHlTdHJpbmdfSW50ZXJuRnJvbVN0cmluZygiX19idWlsdGluc19fIik7CisgICAgaWYgKGJ1aWx0aW5fb2JqZWN0ID09IE5VTEwpCisgICAgICAgIHJldHVybiAwOworICAgIHJldHVybiAxOworfQorCitQeUZyYW1lT2JqZWN0ICoKK1B5RnJhbWVfTmV3KFB5VGhyZWFkU3RhdGUgKnRzdGF0ZSwgUHlDb2RlT2JqZWN0ICpjb2RlLCBQeU9iamVjdCAqZ2xvYmFscywKKyAgICAgICAgICAgIFB5T2JqZWN0ICpsb2NhbHMpCit7CisgICAgUHlGcmFtZU9iamVjdCAqYmFjayA9IHRzdGF0ZS0+ZnJhbWU7CisgICAgUHlGcmFtZU9iamVjdCAqZjsKKyAgICBQeU9iamVjdCAqYnVpbHRpbnM7CisgICAgUHlfc3NpemVfdCBpOworCisjaWZkZWYgUHlfREVCVUcKKyAgICBpZiAoY29kZSA9PSBOVUxMIHx8IGdsb2JhbHMgPT0gTlVMTCB8fCAhUHlEaWN0X0NoZWNrKGdsb2JhbHMpIHx8CisgICAgICAgIChsb2NhbHMgIT0gTlVMTCAmJiAhUHlNYXBwaW5nX0NoZWNrKGxvY2FscykpKSB7CisgICAgICAgIFB5RXJyX0JhZEludGVybmFsQ2FsbCgpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisjZW5kaWYKKyAgICBpZiAoYmFjayA9PSBOVUxMIHx8IGJhY2stPmZfZ2xvYmFscyAhPSBnbG9iYWxzKSB7CisgICAgICAgIGJ1aWx0aW5zID0gUHlEaWN0X0dldEl0ZW0oZ2xvYmFscywgYnVpbHRpbl9vYmplY3QpOworICAgICAgICBpZiAoYnVpbHRpbnMpIHsKKyAgICAgICAgICAgIGlmIChQeU1vZHVsZV9DaGVjayhidWlsdGlucykpIHsKKyAgICAgICAgICAgICAgICBidWlsdGlucyA9IFB5TW9kdWxlX0dldERpY3QoYnVpbHRpbnMpOworICAgICAgICAgICAgICAgIGFzc2VydCghYnVpbHRpbnMgfHwgUHlEaWN0X0NoZWNrKGJ1aWx0aW5zKSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBlbHNlIGlmICghUHlEaWN0X0NoZWNrKGJ1aWx0aW5zKSkKKyAgICAgICAgICAgICAgICBidWlsdGlucyA9IE5VTEw7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGJ1aWx0aW5zID09IE5VTEwpIHsKKyAgICAgICAgICAgIC8qIE5vIGJ1aWx0aW5zISAgICAgICAgICAgICAgTWFrZSB1cCBhIG1pbmltYWwgb25lCisgICAgICAgICAgICAgICBHaXZlIHRoZW0gJ05vbmUnLCBhdCBsZWFzdC4gKi8KKyAgICAgICAgICAgIGJ1aWx0aW5zID0gUHlEaWN0X05ldygpOworICAgICAgICAgICAgaWYgKGJ1aWx0aW5zID09IE5VTEwgfHwKKyAgICAgICAgICAgICAgICBQeURpY3RfU2V0SXRlbVN0cmluZygKKyAgICAgICAgICAgICAgICAgICAgYnVpbHRpbnMsICJOb25lIiwgUHlfTm9uZSkgPCAwKQorICAgICAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgICAgICB9CisgICAgICAgIGVsc2UKKyAgICAgICAgICAgIFB5X0lOQ1JFRihidWlsdGlucyk7CisKKyAgICB9CisgICAgZWxzZSB7CisgICAgICAgIC8qIElmIHdlIHNoYXJlIHRoZSBnbG9iYWxzLCB3ZSBzaGFyZSB0aGUgYnVpbHRpbnMuCisgICAgICAgICAgIFNhdmUgYSBsb29rdXAgYW5kIGEgY2FsbC4gKi8KKyAgICAgICAgYnVpbHRpbnMgPSBiYWNrLT5mX2J1aWx0aW5zOworICAgICAgICBhc3NlcnQoYnVpbHRpbnMgIT0gTlVMTCAmJiBQeURpY3RfQ2hlY2soYnVpbHRpbnMpKTsKKyAgICAgICAgUHlfSU5DUkVGKGJ1aWx0aW5zKTsKKyAgICB9CisgICAgaWYgKGNvZGUtPmNvX3pvbWJpZWZyYW1lICE9IE5VTEwpIHsKKyAgICAgICAgZiA9IGNvZGUtPmNvX3pvbWJpZWZyYW1lOworICAgICAgICBjb2RlLT5jb196b21iaWVmcmFtZSA9IE5VTEw7CisgICAgICAgIF9QeV9OZXdSZWZlcmVuY2UoKFB5T2JqZWN0ICopZik7CisgICAgICAgIGFzc2VydChmLT5mX2NvZGUgPT0gY29kZSk7CisgICAgfQorICAgIGVsc2UgeworICAgICAgICBQeV9zc2l6ZV90IGV4dHJhcywgbmNlbGxzLCBuZnJlZXM7CisgICAgICAgIG5jZWxscyA9IFB5VHVwbGVfR0VUX1NJWkUoY29kZS0+Y29fY2VsbHZhcnMpOworICAgICAgICBuZnJlZXMgPSBQeVR1cGxlX0dFVF9TSVpFKGNvZGUtPmNvX2ZyZWV2YXJzKTsKKyAgICAgICAgZXh0cmFzID0gY29kZS0+Y29fc3RhY2tzaXplICsgY29kZS0+Y29fbmxvY2FscyArIG5jZWxscyArCisgICAgICAgICAgICBuZnJlZXM7CisgICAgICAgIGlmIChmcmVlX2xpc3QgPT0gTlVMTCkgeworICAgICAgICAgICAgZiA9IFB5T2JqZWN0X0dDX05ld1ZhcihQeUZyYW1lT2JqZWN0LCAmUHlGcmFtZV9UeXBlLAorICAgICAgICAgICAgZXh0cmFzKTsKKyAgICAgICAgICAgIGlmIChmID09IE5VTEwpIHsKKyAgICAgICAgICAgICAgICBQeV9ERUNSRUYoYnVpbHRpbnMpOworICAgICAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGVsc2UgeworICAgICAgICAgICAgYXNzZXJ0KG51bWZyZWUgPiAwKTsKKyAgICAgICAgICAgIC0tbnVtZnJlZTsKKyAgICAgICAgICAgIGYgPSBmcmVlX2xpc3Q7CisgICAgICAgICAgICBmcmVlX2xpc3QgPSBmcmVlX2xpc3QtPmZfYmFjazsKKyAgICAgICAgICAgIGlmIChQeV9TSVpFKGYpIDwgZXh0cmFzKSB7CisgICAgICAgICAgICAgICAgZiA9IFB5T2JqZWN0X0dDX1Jlc2l6ZShQeUZyYW1lT2JqZWN0LCBmLCBleHRyYXMpOworICAgICAgICAgICAgICAgIGlmIChmID09IE5VTEwpIHsKKyAgICAgICAgICAgICAgICAgICAgUHlfREVDUkVGKGJ1aWx0aW5zKTsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgX1B5X05ld1JlZmVyZW5jZSgoUHlPYmplY3QgKilmKTsKKyAgICAgICAgfQorCisgICAgICAgIGYtPmZfY29kZSA9IGNvZGU7CisgICAgICAgIGV4dHJhcyA9IGNvZGUtPmNvX25sb2NhbHMgKyBuY2VsbHMgKyBuZnJlZXM7CisgICAgICAgIGYtPmZfdmFsdWVzdGFjayA9IGYtPmZfbG9jYWxzcGx1cyArIGV4dHJhczsKKyAgICAgICAgZm9yIChpPTA7IGk8ZXh0cmFzOyBpKyspCisgICAgICAgICAgICBmLT5mX2xvY2Fsc3BsdXNbaV0gPSBOVUxMOworICAgICAgICBmLT5mX2xvY2FscyA9IE5VTEw7CisgICAgICAgIGYtPmZfdHJhY2UgPSBOVUxMOworICAgICAgICBmLT5mX2V4Y190eXBlID0gZi0+Zl9leGNfdmFsdWUgPSBmLT5mX2V4Y190cmFjZWJhY2sgPSBOVUxMOworICAgIH0KKyAgICBmLT5mX3N0YWNrdG9wID0gZi0+Zl92YWx1ZXN0YWNrOworICAgIGYtPmZfYnVpbHRpbnMgPSBidWlsdGluczsKKyAgICBQeV9YSU5DUkVGKGJhY2spOworICAgIGYtPmZfYmFjayA9IGJhY2s7CisgICAgUHlfSU5DUkVGKGNvZGUpOworICAgIFB5X0lOQ1JFRihnbG9iYWxzKTsKKyAgICBmLT5mX2dsb2JhbHMgPSBnbG9iYWxzOworICAgIC8qIE1vc3QgZnVuY3Rpb25zIGhhdmUgQ09fTkVXTE9DQUxTIGFuZCBDT19PUFRJTUlaRUQgc2V0LiAqLworICAgIGlmICgoY29kZS0+Y29fZmxhZ3MgJiAoQ09fTkVXTE9DQUxTIHwgQ09fT1BUSU1JWkVEKSkgPT0KKyAgICAgICAgKENPX05FV0xPQ0FMUyB8IENPX09QVElNSVpFRCkpCisgICAgICAgIDsgLyogZl9sb2NhbHMgPSBOVUxMOyB3aWxsIGJlIHNldCBieSBQeUZyYW1lX0Zhc3RUb0xvY2FscygpICovCisgICAgZWxzZSBpZiAoY29kZS0+Y29fZmxhZ3MgJiBDT19ORVdMT0NBTFMpIHsKKyAgICAgICAgbG9jYWxzID0gUHlEaWN0X05ldygpOworICAgICAgICBpZiAobG9jYWxzID09IE5VTEwpIHsKKyAgICAgICAgICAgIFB5X0RFQ1JFRihmKTsKKyAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgICAgICB9CisgICAgICAgIGYtPmZfbG9jYWxzID0gbG9jYWxzOworICAgIH0KKyAgICBlbHNlIHsKKyAgICAgICAgaWYgKGxvY2FscyA9PSBOVUxMKQorICAgICAgICAgICAgbG9jYWxzID0gZ2xvYmFsczsKKyAgICAgICAgUHlfSU5DUkVGKGxvY2Fscyk7CisgICAgICAgIGYtPmZfbG9jYWxzID0gbG9jYWxzOworICAgIH0KKyAgICBmLT5mX3RzdGF0ZSA9IHRzdGF0ZTsKKworICAgIGYtPmZfbGFzdGkgPSAtMTsKKyAgICBmLT5mX2xpbmVubyA9IGNvZGUtPmNvX2ZpcnN0bGluZW5vOworICAgIGYtPmZfaWJsb2NrID0gMDsKKworICAgIF9QeU9iamVjdF9HQ19UUkFDSyhmKTsKKyAgICByZXR1cm4gZjsKK30KKworLyogQmxvY2sgbWFuYWdlbWVudCAqLworCit2b2lkCitQeUZyYW1lX0Jsb2NrU2V0dXAoUHlGcmFtZU9iamVjdCAqZiwgaW50IHR5cGUsIGludCBoYW5kbGVyLCBpbnQgbGV2ZWwpCit7CisgICAgUHlUcnlCbG9jayAqYjsKKyAgICBpZiAoZi0+Zl9pYmxvY2sgPj0gQ09fTUFYQkxPQ0tTKQorICAgICAgICBQeV9GYXRhbEVycm9yKCJYWFggYmxvY2sgc3RhY2sgb3ZlcmZsb3ciKTsKKyAgICBiID0gJmYtPmZfYmxvY2tzdGFja1tmLT5mX2libG9jaysrXTsKKyAgICBiLT5iX3R5cGUgPSB0eXBlOworICAgIGItPmJfbGV2ZWwgPSBsZXZlbDsKKyAgICBiLT5iX2hhbmRsZXIgPSBoYW5kbGVyOworfQorCitQeVRyeUJsb2NrICoKK1B5RnJhbWVfQmxvY2tQb3AoUHlGcmFtZU9iamVjdCAqZikKK3sKKyAgICBQeVRyeUJsb2NrICpiOworICAgIGlmIChmLT5mX2libG9jayA8PSAwKQorICAgICAgICBQeV9GYXRhbEVycm9yKCJYWFggYmxvY2sgc3RhY2sgdW5kZXJmbG93Iik7CisgICAgYiA9ICZmLT5mX2Jsb2Nrc3RhY2tbLS1mLT5mX2libG9ja107CisgICAgcmV0dXJuIGI7Cit9CisKKy8qIENvbnZlcnQgYmV0d2VlbiAiZmFzdCIgdmVyc2lvbiBvZiBsb2NhbHMgYW5kIGRpY3Rpb25hcnkgdmVyc2lvbi4KKworICAgbWFwIGFuZCB2YWx1ZXMgYXJlIGlucHV0IGFyZ3VtZW50cy4gIG1hcCBpcyBhIHR1cGxlIG9mIHN0cmluZ3MuCisgICB2YWx1ZXMgaXMgYW4gYXJyYXkgb2YgUHlPYmplY3QqLiAgQXQgaW5kZXggaSwgbWFwW2ldIGlzIHRoZSBuYW1lIG9mCisgICB0aGUgdmFyaWFibGUgd2l0aCB2YWx1ZSB2YWx1ZXNbaV0uICBUaGUgZnVuY3Rpb24gY29waWVzIHRoZSBmaXJzdAorICAgbm1hcCB2YXJpYWJsZSBmcm9tIG1hcC92YWx1ZXMgaW50byBkaWN0LiAgSWYgdmFsdWVzW2ldIGlzIE5VTEwsCisgICB0aGUgdmFyaWFibGUgaXMgZGVsZXRlZCBmcm9tIGRpY3QuCisKKyAgIElmIGRlcmVmIGlzIHRydWUsIHRoZW4gdGhlIHZhbHVlcyBiZWluZyBjb3BpZWQgYXJlIGNlbGwgdmFyaWFibGVzCisgICBhbmQgdGhlIHZhbHVlIGlzIGV4dHJhY3RlZCBmcm9tIHRoZSBjZWxsIHZhcmlhYmxlIGJlZm9yZSBiZWluZyBwdXQKKyAgIGluIGRpY3QuCisKKyAgIEV4Y2VwdGlvbnMgcmFpc2VkIHdoaWxlIG1vZGlmeWluZyB0aGUgZGljdCBhcmUgc2lsZW50bHkgaWdub3JlZCwKKyAgIGJlY2F1c2UgdGhlcmUgaXMgbm8gZ29vZCB3YXkgdG8gcmVwb3J0IHRoZW0uCisgKi8KKworc3RhdGljIHZvaWQKK21hcF90b19kaWN0KFB5T2JqZWN0ICptYXAsIFB5X3NzaXplX3Qgbm1hcCwgUHlPYmplY3QgKmRpY3QsIFB5T2JqZWN0ICoqdmFsdWVzLAorICAgICAgICAgICAgaW50IGRlcmVmKQoreworICAgIFB5X3NzaXplX3QgajsKKyAgICBhc3NlcnQoUHlUdXBsZV9DaGVjayhtYXApKTsKKyAgICBhc3NlcnQoUHlEaWN0X0NoZWNrKGRpY3QpKTsKKyAgICBhc3NlcnQoUHlUdXBsZV9TaXplKG1hcCkgPj0gbm1hcCk7CisgICAgZm9yIChqID0gbm1hcDsgLS1qID49IDA7ICkgeworICAgICAgICBQeU9iamVjdCAqa2V5ID0gUHlUdXBsZV9HRVRfSVRFTShtYXAsIGopOworICAgICAgICBQeU9iamVjdCAqdmFsdWUgPSB2YWx1ZXNbal07CisgICAgICAgIGFzc2VydChQeVN0cmluZ19DaGVjayhrZXkpKTsKKyAgICAgICAgaWYgKGRlcmVmKSB7CisgICAgICAgICAgICBhc3NlcnQoUHlDZWxsX0NoZWNrKHZhbHVlKSk7CisgICAgICAgICAgICB2YWx1ZSA9IFB5Q2VsbF9HRVQodmFsdWUpOworICAgICAgICB9CisgICAgICAgIGlmICh2YWx1ZSA9PSBOVUxMKSB7CisgICAgICAgICAgICBpZiAoUHlPYmplY3RfRGVsSXRlbShkaWN0LCBrZXkpICE9IDApCisgICAgICAgICAgICAgICAgUHlFcnJfQ2xlYXIoKTsKKyAgICAgICAgfQorICAgICAgICBlbHNlIHsKKyAgICAgICAgICAgIGlmIChQeU9iamVjdF9TZXRJdGVtKGRpY3QsIGtleSwgdmFsdWUpICE9IDApCisgICAgICAgICAgICAgICAgUHlFcnJfQ2xlYXIoKTsKKyAgICAgICAgfQorICAgIH0KK30KKworLyogQ29weSB2YWx1ZXMgZnJvbSB0aGUgImxvY2FscyIgZGljdCBpbnRvIHRoZSBmYXN0IGxvY2Fscy4KKworICAgZGljdCBpcyBhbiBpbnB1dCBhcmd1bWVudCBjb250YWluaW5nIHN0cmluZyBrZXlzIHJlcHJlc2VudGluZworICAgdmFyaWFibGVzIG5hbWVzIGFuZCBhcmJpdHJhcnkgUHlPYmplY3QqIGFzIHZhbHVlcy4KKworICAgbWFwIGFuZCB2YWx1ZXMgYXJlIGlucHV0IGFyZ3VtZW50cy4gIG1hcCBpcyBhIHR1cGxlIG9mIHN0cmluZ3MuCisgICB2YWx1ZXMgaXMgYW4gYXJyYXkgb2YgUHlPYmplY3QqLiAgQXQgaW5kZXggaSwgbWFwW2ldIGlzIHRoZSBuYW1lIG9mCisgICB0aGUgdmFyaWFibGUgd2l0aCB2YWx1ZSB2YWx1ZXNbaV0uICBUaGUgZnVuY3Rpb24gY29waWVzIHRoZSBmaXJzdAorICAgbm1hcCB2YXJpYWJsZSBmcm9tIG1hcC92YWx1ZXMgaW50byBkaWN0LiAgSWYgdmFsdWVzW2ldIGlzIE5VTEwsCisgICB0aGUgdmFyaWFibGUgaXMgZGVsZXRlZCBmcm9tIGRpY3QuCisKKyAgIElmIGRlcmVmIGlzIHRydWUsIHRoZW4gdGhlIHZhbHVlcyBiZWluZyBjb3BpZWQgYXJlIGNlbGwgdmFyaWFibGVzCisgICBhbmQgdGhlIHZhbHVlIGlzIGV4dHJhY3RlZCBmcm9tIHRoZSBjZWxsIHZhcmlhYmxlIGJlZm9yZSBiZWluZyBwdXQKKyAgIGluIGRpY3QuICBJZiBjbGVhciBpcyB0cnVlLCB0aGVuIHZhcmlhYmxlcyBpbiBtYXAgYnV0IG5vdCBpbiBkaWN0CisgICBhcmUgc2V0IHRvIE5VTEwgaW4gbWFwOyBpZiBjbGVhciBpcyBmYWxzZSwgdmFyaWFibGVzIG1pc3NpbmcgaW4KKyAgIGRpY3QgYXJlIGlnbm9yZWQuCisKKyAgIEV4Y2VwdGlvbnMgcmFpc2VkIHdoaWxlIG1vZGlmeWluZyB0aGUgZGljdCBhcmUgc2lsZW50bHkgaWdub3JlZCwKKyAgIGJlY2F1c2UgdGhlcmUgaXMgbm8gZ29vZCB3YXkgdG8gcmVwb3J0IHRoZW0uCisqLworCitzdGF0aWMgdm9pZAorZGljdF90b19tYXAoUHlPYmplY3QgKm1hcCwgUHlfc3NpemVfdCBubWFwLCBQeU9iamVjdCAqZGljdCwgUHlPYmplY3QgKip2YWx1ZXMsCisgICAgICAgICAgICBpbnQgZGVyZWYsIGludCBjbGVhcikKK3sKKyAgICBQeV9zc2l6ZV90IGo7CisgICAgYXNzZXJ0KFB5VHVwbGVfQ2hlY2sobWFwKSk7CisgICAgYXNzZXJ0KFB5RGljdF9DaGVjayhkaWN0KSk7CisgICAgYXNzZXJ0KFB5VHVwbGVfU2l6ZShtYXApID49IG5tYXApOworICAgIGZvciAoaiA9IG5tYXA7IC0taiA+PSAwOyApIHsKKyAgICAgICAgUHlPYmplY3QgKmtleSA9IFB5VHVwbGVfR0VUX0lURU0obWFwLCBqKTsKKyAgICAgICAgUHlPYmplY3QgKnZhbHVlID0gUHlPYmplY3RfR2V0SXRlbShkaWN0LCBrZXkpOworICAgICAgICBhc3NlcnQoUHlTdHJpbmdfQ2hlY2soa2V5KSk7CisgICAgICAgIC8qIFdlIG9ubHkgY2FyZSBhYm91dCBOVUxMcyBpZiBjbGVhciBpcyB0cnVlLiAqLworICAgICAgICBpZiAodmFsdWUgPT0gTlVMTCkgeworICAgICAgICAgICAgUHlFcnJfQ2xlYXIoKTsKKyAgICAgICAgICAgIGlmICghY2xlYXIpCisgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGRlcmVmKSB7CisgICAgICAgICAgICBhc3NlcnQoUHlDZWxsX0NoZWNrKHZhbHVlc1tqXSkpOworICAgICAgICAgICAgaWYgKFB5Q2VsbF9HRVQodmFsdWVzW2pdKSAhPSB2YWx1ZSkgeworICAgICAgICAgICAgICAgIGlmIChQeUNlbGxfU2V0KHZhbHVlc1tqXSwgdmFsdWUpIDwgMCkKKyAgICAgICAgICAgICAgICAgICAgUHlFcnJfQ2xlYXIoKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlIGlmICh2YWx1ZXNbal0gIT0gdmFsdWUpIHsKKyAgICAgICAgICAgIFB5X1hJTkNSRUYodmFsdWUpOworICAgICAgICAgICAgUHlfWERFQ1JFRih2YWx1ZXNbal0pOworICAgICAgICAgICAgdmFsdWVzW2pdID0gdmFsdWU7CisgICAgICAgIH0KKyAgICAgICAgUHlfWERFQ1JFRih2YWx1ZSk7CisgICAgfQorfQorCit2b2lkCitQeUZyYW1lX0Zhc3RUb0xvY2FscyhQeUZyYW1lT2JqZWN0ICpmKQoreworICAgIC8qIE1lcmdlIGZhc3QgbG9jYWxzIGludG8gZi0+Zl9sb2NhbHMgKi8KKyAgICBQeU9iamVjdCAqbG9jYWxzLCAqbWFwOworICAgIFB5T2JqZWN0ICoqZmFzdDsKKyAgICBQeU9iamVjdCAqZXJyb3JfdHlwZSwgKmVycm9yX3ZhbHVlLCAqZXJyb3JfdHJhY2ViYWNrOworICAgIFB5Q29kZU9iamVjdCAqY287CisgICAgUHlfc3NpemVfdCBqOworICAgIGludCBuY2VsbHMsIG5mcmVldmFyczsKKyAgICBpZiAoZiA9PSBOVUxMKQorICAgICAgICByZXR1cm47CisgICAgbG9jYWxzID0gZi0+Zl9sb2NhbHM7CisgICAgaWYgKGxvY2FscyA9PSBOVUxMKSB7CisgICAgICAgIGxvY2FscyA9IGYtPmZfbG9jYWxzID0gUHlEaWN0X05ldygpOworICAgICAgICBpZiAobG9jYWxzID09IE5VTEwpIHsKKyAgICAgICAgICAgIFB5RXJyX0NsZWFyKCk7IC8qIENhbid0IHJlcG9ydCBpdCA6LSggKi8KKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgIH0KKyAgICBjbyA9IGYtPmZfY29kZTsKKyAgICBtYXAgPSBjby0+Y29fdmFybmFtZXM7CisgICAgaWYgKCFQeVR1cGxlX0NoZWNrKG1hcCkpCisgICAgICAgIHJldHVybjsKKyAgICBQeUVycl9GZXRjaCgmZXJyb3JfdHlwZSwgJmVycm9yX3ZhbHVlLCAmZXJyb3JfdHJhY2ViYWNrKTsKKyAgICBmYXN0ID0gZi0+Zl9sb2NhbHNwbHVzOworICAgIGogPSBQeVR1cGxlX0dFVF9TSVpFKG1hcCk7CisgICAgaWYgKGogPiBjby0+Y29fbmxvY2FscykKKyAgICAgICAgaiA9IGNvLT5jb19ubG9jYWxzOworICAgIGlmIChjby0+Y29fbmxvY2FscykKKyAgICAgICAgbWFwX3RvX2RpY3QobWFwLCBqLCBsb2NhbHMsIGZhc3QsIDApOworICAgIG5jZWxscyA9IFB5VHVwbGVfR0VUX1NJWkUoY28tPmNvX2NlbGx2YXJzKTsKKyAgICBuZnJlZXZhcnMgPSBQeVR1cGxlX0dFVF9TSVpFKGNvLT5jb19mcmVldmFycyk7CisgICAgaWYgKG5jZWxscyB8fCBuZnJlZXZhcnMpIHsKKyAgICAgICAgbWFwX3RvX2RpY3QoY28tPmNvX2NlbGx2YXJzLCBuY2VsbHMsCisgICAgICAgICAgICAgICAgICAgIGxvY2FscywgZmFzdCArIGNvLT5jb19ubG9jYWxzLCAxKTsKKyAgICAgICAgLyogSWYgdGhlIG5hbWVzcGFjZSBpcyB1bm9wdGltaXplZCwgdGhlbiBvbmUgb2YgdGhlCisgICAgICAgICAgIGZvbGxvd2luZyBjYXNlcyBhcHBsaWVzOgorICAgICAgICAgICAxLiBJdCBkb2VzIG5vdCBjb250YWluIGZyZWUgdmFyaWFibGVzLCBiZWNhdXNlIGl0CisgICAgICAgICAgICAgIHVzZXMgaW1wb3J0ICogb3IgaXMgYSB0b3AtbGV2ZWwgbmFtZXNwYWNlLgorICAgICAgICAgICAyLiBJdCBpcyBhIGNsYXNzIG5hbWVzcGFjZS4KKyAgICAgICAgICAgV2UgZG9uJ3Qgd2FudCB0byBhY2NpZGVudGFsbHkgY29weSBmcmVlIHZhcmlhYmxlcworICAgICAgICAgICBpbnRvIHRoZSBsb2NhbHMgZGljdCB1c2VkIGJ5IHRoZSBjbGFzcy4KKyAgICAgICAgKi8KKyAgICAgICAgaWYgKGNvLT5jb19mbGFncyAmIENPX09QVElNSVpFRCkgeworICAgICAgICAgICAgbWFwX3RvX2RpY3QoY28tPmNvX2ZyZWV2YXJzLCBuZnJlZXZhcnMsCisgICAgICAgICAgICAgICAgICAgICAgICBsb2NhbHMsIGZhc3QgKyBjby0+Y29fbmxvY2FscyArIG5jZWxscywgMSk7CisgICAgICAgIH0KKyAgICB9CisgICAgUHlFcnJfUmVzdG9yZShlcnJvcl90eXBlLCBlcnJvcl92YWx1ZSwgZXJyb3JfdHJhY2ViYWNrKTsKK30KKwordm9pZAorUHlGcmFtZV9Mb2NhbHNUb0Zhc3QoUHlGcmFtZU9iamVjdCAqZiwgaW50IGNsZWFyKQoreworICAgIC8qIE1lcmdlIGYtPmZfbG9jYWxzIGludG8gZmFzdCBsb2NhbHMgKi8KKyAgICBQeU9iamVjdCAqbG9jYWxzLCAqbWFwOworICAgIFB5T2JqZWN0ICoqZmFzdDsKKyAgICBQeU9iamVjdCAqZXJyb3JfdHlwZSwgKmVycm9yX3ZhbHVlLCAqZXJyb3JfdHJhY2ViYWNrOworICAgIFB5Q29kZU9iamVjdCAqY287CisgICAgUHlfc3NpemVfdCBqOworICAgIGludCBuY2VsbHMsIG5mcmVldmFyczsKKyAgICBpZiAoZiA9PSBOVUxMKQorICAgICAgICByZXR1cm47CisgICAgbG9jYWxzID0gZi0+Zl9sb2NhbHM7CisgICAgY28gPSBmLT5mX2NvZGU7CisgICAgbWFwID0gY28tPmNvX3Zhcm5hbWVzOworICAgIGlmIChsb2NhbHMgPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuOworICAgIGlmICghUHlUdXBsZV9DaGVjayhtYXApKQorICAgICAgICByZXR1cm47CisgICAgUHlFcnJfRmV0Y2goJmVycm9yX3R5cGUsICZlcnJvcl92YWx1ZSwgJmVycm9yX3RyYWNlYmFjayk7CisgICAgZmFzdCA9IGYtPmZfbG9jYWxzcGx1czsKKyAgICBqID0gUHlUdXBsZV9HRVRfU0laRShtYXApOworICAgIGlmIChqID4gY28tPmNvX25sb2NhbHMpCisgICAgICAgIGogPSBjby0+Y29fbmxvY2FsczsKKyAgICBpZiAoY28tPmNvX25sb2NhbHMpCisgICAgICAgIGRpY3RfdG9fbWFwKGNvLT5jb192YXJuYW1lcywgaiwgbG9jYWxzLCBmYXN0LCAwLCBjbGVhcik7CisgICAgbmNlbGxzID0gUHlUdXBsZV9HRVRfU0laRShjby0+Y29fY2VsbHZhcnMpOworICAgIG5mcmVldmFycyA9IFB5VHVwbGVfR0VUX1NJWkUoY28tPmNvX2ZyZWV2YXJzKTsKKyAgICBpZiAobmNlbGxzIHx8IG5mcmVldmFycykgeworICAgICAgICBkaWN0X3RvX21hcChjby0+Y29fY2VsbHZhcnMsIG5jZWxscywKKyAgICAgICAgICAgICAgICAgICAgbG9jYWxzLCBmYXN0ICsgY28tPmNvX25sb2NhbHMsIDEsIGNsZWFyKTsKKyAgICAgICAgLyogU2FtZSB0ZXN0IGFzIGluIFB5RnJhbWVfRmFzdFRvTG9jYWxzKCkgYWJvdmUuICovCisgICAgICAgIGlmIChjby0+Y29fZmxhZ3MgJiBDT19PUFRJTUlaRUQpIHsKKyAgICAgICAgICAgIGRpY3RfdG9fbWFwKGNvLT5jb19mcmVldmFycywgbmZyZWV2YXJzLAorICAgICAgICAgICAgICAgIGxvY2FscywgZmFzdCArIGNvLT5jb19ubG9jYWxzICsgbmNlbGxzLCAxLAorICAgICAgICAgICAgICAgIGNsZWFyKTsKKyAgICAgICAgfQorICAgIH0KKyAgICBQeUVycl9SZXN0b3JlKGVycm9yX3R5cGUsIGVycm9yX3ZhbHVlLCBlcnJvcl90cmFjZWJhY2spOworfQorCisvKiBDbGVhciBvdXQgdGhlIGZyZWUgbGlzdCAqLworaW50CitQeUZyYW1lX0NsZWFyRnJlZUxpc3Qodm9pZCkKK3sKKyAgICBpbnQgZnJlZWxpc3Rfc2l6ZSA9IG51bWZyZWU7CisKKyAgICB3aGlsZSAoZnJlZV9saXN0ICE9IE5VTEwpIHsKKyAgICAgICAgUHlGcmFtZU9iamVjdCAqZiA9IGZyZWVfbGlzdDsKKyAgICAgICAgZnJlZV9saXN0ID0gZnJlZV9saXN0LT5mX2JhY2s7CisgICAgICAgIFB5T2JqZWN0X0dDX0RlbChmKTsKKyAgICAgICAgLS1udW1mcmVlOworICAgIH0KKyAgICBhc3NlcnQobnVtZnJlZSA9PSAwKTsKKyAgICByZXR1cm4gZnJlZWxpc3Rfc2l6ZTsKK30KKwordm9pZAorUHlGcmFtZV9GaW5pKHZvaWQpCit7CisgICAgKHZvaWQpUHlGcmFtZV9DbGVhckZyZWVMaXN0KCk7CisgICAgUHlfWERFQ1JFRihidWlsdGluX29iamVjdCk7CisgICAgYnVpbHRpbl9vYmplY3QgPSBOVUxMOworfQpkaWZmIC0tZ2l0IGEvUHl0aG9uLTIuNy41L09iamVjdHMvZnVuY29iamVjdC5jIGIvUHl0aG9uLTIuNy41L09iamVjdHMvZnVuY29iamVjdC5jCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjUxYjZjOWQKLS0tIC9kZXYvbnVsbAorKysgYi9QeXRob24tMi43LjUvT2JqZWN0cy9mdW5jb2JqZWN0LmMKQEAgLTAsMCArMSw4OTUgQEAKKworLyogRnVuY3Rpb24gb2JqZWN0IGltcGxlbWVudGF0aW9uICovCisKKyNpbmNsdWRlICJQeXRob24uaCIKKyNpbmNsdWRlICJjb2RlLmgiCisjaW5jbHVkZSAiZXZhbC5oIgorI2luY2x1ZGUgInN0cnVjdG1lbWJlci5oIgorCitQeU9iamVjdCAqCitQeUZ1bmN0aW9uX05ldyhQeU9iamVjdCAqY29kZSwgUHlPYmplY3QgKmdsb2JhbHMpCit7CisgICAgUHlGdW5jdGlvbk9iamVjdCAqb3AgPSBQeU9iamVjdF9HQ19OZXcoUHlGdW5jdGlvbk9iamVjdCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmUHlGdW5jdGlvbl9UeXBlKTsKKyAgICBzdGF0aWMgUHlPYmplY3QgKl9fbmFtZV9fID0gMDsKKyAgICBpZiAob3AgIT0gTlVMTCkgeworICAgICAgICBQeU9iamVjdCAqZG9jOworICAgICAgICBQeU9iamVjdCAqY29uc3RzOworICAgICAgICBQeU9iamVjdCAqbW9kdWxlOworICAgICAgICBvcC0+ZnVuY193ZWFrcmVmbGlzdCA9IE5VTEw7CisgICAgICAgIFB5X0lOQ1JFRihjb2RlKTsKKyAgICAgICAgb3AtPmZ1bmNfY29kZSA9IGNvZGU7CisgICAgICAgIFB5X0lOQ1JFRihnbG9iYWxzKTsKKyAgICAgICAgb3AtPmZ1bmNfZ2xvYmFscyA9IGdsb2JhbHM7CisgICAgICAgIG9wLT5mdW5jX25hbWUgPSAoKFB5Q29kZU9iamVjdCAqKWNvZGUpLT5jb19uYW1lOworICAgICAgICBQeV9JTkNSRUYob3AtPmZ1bmNfbmFtZSk7CisgICAgICAgIG9wLT5mdW5jX2RlZmF1bHRzID0gTlVMTDsgLyogTm8gZGVmYXVsdCBhcmd1bWVudHMgKi8KKyAgICAgICAgb3AtPmZ1bmNfY2xvc3VyZSA9IE5VTEw7CisgICAgICAgIGNvbnN0cyA9ICgoUHlDb2RlT2JqZWN0ICopY29kZSktPmNvX2NvbnN0czsKKyAgICAgICAgaWYgKFB5VHVwbGVfU2l6ZShjb25zdHMpID49IDEpIHsKKyAgICAgICAgICAgIGRvYyA9IFB5VHVwbGVfR2V0SXRlbShjb25zdHMsIDApOworICAgICAgICAgICAgaWYgKCFQeVN0cmluZ19DaGVjayhkb2MpICYmICFQeVVuaWNvZGVfQ2hlY2soZG9jKSkKKyAgICAgICAgICAgICAgICBkb2MgPSBQeV9Ob25lOworICAgICAgICB9CisgICAgICAgIGVsc2UKKyAgICAgICAgICAgIGRvYyA9IFB5X05vbmU7CisgICAgICAgIFB5X0lOQ1JFRihkb2MpOworICAgICAgICBvcC0+ZnVuY19kb2MgPSBkb2M7CisgICAgICAgIG9wLT5mdW5jX2RpY3QgPSBOVUxMOworICAgICAgICBvcC0+ZnVuY19tb2R1bGUgPSBOVUxMOworCisgICAgICAgIC8qIF9fbW9kdWxlX186IElmIG1vZHVsZSBuYW1lIGlzIGluIGdsb2JhbHMsIHVzZSBpdC4KKyAgICAgICAgICAgT3RoZXJ3aXNlLCB1c2UgTm9uZS4KKyAgICAgICAgKi8KKyAgICAgICAgaWYgKCFfX25hbWVfXykgeworICAgICAgICAgICAgX19uYW1lX18gPSBQeVN0cmluZ19JbnRlcm5Gcm9tU3RyaW5nKCJfX25hbWVfXyIpOworICAgICAgICAgICAgaWYgKCFfX25hbWVfXykgeworICAgICAgICAgICAgICAgIFB5X0RFQ1JFRihvcCk7CisgICAgICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgbW9kdWxlID0gUHlEaWN0X0dldEl0ZW0oZ2xvYmFscywgX19uYW1lX18pOworICAgICAgICBpZiAobW9kdWxlKSB7CisgICAgICAgICAgICBQeV9JTkNSRUYobW9kdWxlKTsKKyAgICAgICAgICAgIG9wLT5mdW5jX21vZHVsZSA9IG1vZHVsZTsKKyAgICAgICAgfQorICAgIH0KKyAgICBlbHNlCisgICAgICAgIHJldHVybiBOVUxMOworICAgIF9QeU9iamVjdF9HQ19UUkFDSyhvcCk7CisgICAgcmV0dXJuIChQeU9iamVjdCAqKW9wOworfQorCitQeU9iamVjdCAqCitQeUZ1bmN0aW9uX0dldENvZGUoUHlPYmplY3QgKm9wKQoreworICAgIGlmICghUHlGdW5jdGlvbl9DaGVjayhvcCkpIHsKKyAgICAgICAgUHlFcnJfQmFkSW50ZXJuYWxDYWxsKCk7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICByZXR1cm4gKChQeUZ1bmN0aW9uT2JqZWN0ICopIG9wKSAtPiBmdW5jX2NvZGU7Cit9CisKK1B5T2JqZWN0ICoKK1B5RnVuY3Rpb25fR2V0R2xvYmFscyhQeU9iamVjdCAqb3ApCit7CisgICAgaWYgKCFQeUZ1bmN0aW9uX0NoZWNrKG9wKSkgeworICAgICAgICBQeUVycl9CYWRJbnRlcm5hbENhbGwoKTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIHJldHVybiAoKFB5RnVuY3Rpb25PYmplY3QgKikgb3ApIC0+IGZ1bmNfZ2xvYmFsczsKK30KKworUHlPYmplY3QgKgorUHlGdW5jdGlvbl9HZXRNb2R1bGUoUHlPYmplY3QgKm9wKQoreworICAgIGlmICghUHlGdW5jdGlvbl9DaGVjayhvcCkpIHsKKyAgICAgICAgUHlFcnJfQmFkSW50ZXJuYWxDYWxsKCk7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICByZXR1cm4gKChQeUZ1bmN0aW9uT2JqZWN0ICopIG9wKSAtPiBmdW5jX21vZHVsZTsKK30KKworUHlPYmplY3QgKgorUHlGdW5jdGlvbl9HZXREZWZhdWx0cyhQeU9iamVjdCAqb3ApCit7CisgICAgaWYgKCFQeUZ1bmN0aW9uX0NoZWNrKG9wKSkgeworICAgICAgICBQeUVycl9CYWRJbnRlcm5hbENhbGwoKTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIHJldHVybiAoKFB5RnVuY3Rpb25PYmplY3QgKikgb3ApIC0+IGZ1bmNfZGVmYXVsdHM7Cit9CisKK2ludAorUHlGdW5jdGlvbl9TZXREZWZhdWx0cyhQeU9iamVjdCAqb3AsIFB5T2JqZWN0ICpkZWZhdWx0cykKK3sKKyAgICBpZiAoIVB5RnVuY3Rpb25fQ2hlY2sob3ApKSB7CisgICAgICAgIFB5RXJyX0JhZEludGVybmFsQ2FsbCgpOworICAgICAgICByZXR1cm4gLTE7CisgICAgfQorICAgIGlmIChkZWZhdWx0cyA9PSBQeV9Ob25lKQorICAgICAgICBkZWZhdWx0cyA9IE5VTEw7CisgICAgZWxzZSBpZiAoZGVmYXVsdHMgJiYgUHlUdXBsZV9DaGVjayhkZWZhdWx0cykpIHsKKyAgICAgICAgUHlfSU5DUkVGKGRlZmF1bHRzKTsKKyAgICB9CisgICAgZWxzZSB7CisgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19TeXN0ZW1FcnJvciwgIm5vbi10dXBsZSBkZWZhdWx0IGFyZ3MiKTsKKyAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKyAgICBQeV9YREVDUkVGKCgoUHlGdW5jdGlvbk9iamVjdCAqKSBvcCkgLT4gZnVuY19kZWZhdWx0cyk7CisgICAgKChQeUZ1bmN0aW9uT2JqZWN0ICopIG9wKSAtPiBmdW5jX2RlZmF1bHRzID0gZGVmYXVsdHM7CisgICAgcmV0dXJuIDA7Cit9CisKK1B5T2JqZWN0ICoKK1B5RnVuY3Rpb25fR2V0Q2xvc3VyZShQeU9iamVjdCAqb3ApCit7CisgICAgaWYgKCFQeUZ1bmN0aW9uX0NoZWNrKG9wKSkgeworICAgICAgICBQeUVycl9CYWRJbnRlcm5hbENhbGwoKTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIHJldHVybiAoKFB5RnVuY3Rpb25PYmplY3QgKikgb3ApIC0+IGZ1bmNfY2xvc3VyZTsKK30KKworaW50CitQeUZ1bmN0aW9uX1NldENsb3N1cmUoUHlPYmplY3QgKm9wLCBQeU9iamVjdCAqY2xvc3VyZSkKK3sKKyAgICBpZiAoIVB5RnVuY3Rpb25fQ2hlY2sob3ApKSB7CisgICAgICAgIFB5RXJyX0JhZEludGVybmFsQ2FsbCgpOworICAgICAgICByZXR1cm4gLTE7CisgICAgfQorICAgIGlmIChjbG9zdXJlID09IFB5X05vbmUpCisgICAgICAgIGNsb3N1cmUgPSBOVUxMOworICAgIGVsc2UgaWYgKFB5VHVwbGVfQ2hlY2soY2xvc3VyZSkpIHsKKyAgICAgICAgUHlfSU5DUkVGKGNsb3N1cmUpOworICAgIH0KKyAgICBlbHNlIHsKKyAgICAgICAgUHlFcnJfRm9ybWF0KFB5RXhjX1N5c3RlbUVycm9yLAorICAgICAgICAgICAgICAgICAgICAgImV4cGVjdGVkIHR1cGxlIGZvciBjbG9zdXJlLCBnb3QgJyUuMTAwcyciLAorICAgICAgICAgICAgICAgICAgICAgY2xvc3VyZS0+b2JfdHlwZS0+dHBfbmFtZSk7CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisgICAgUHlfWERFQ1JFRigoKFB5RnVuY3Rpb25PYmplY3QgKikgb3ApIC0+IGZ1bmNfY2xvc3VyZSk7CisgICAgKChQeUZ1bmN0aW9uT2JqZWN0ICopIG9wKSAtPiBmdW5jX2Nsb3N1cmUgPSBjbG9zdXJlOworICAgIHJldHVybiAwOworfQorCisvKiBNZXRob2RzICovCisKKyNkZWZpbmUgT0ZGKHgpIG9mZnNldG9mKFB5RnVuY3Rpb25PYmplY3QsIHgpCisKK3N0YXRpYyBQeU1lbWJlckRlZiBmdW5jX21lbWJlcmxpc3RbXSA9IHsKKyAgICB7ImZ1bmNfY2xvc3VyZSIsICBUX09CSkVDVCwgICAgIE9GRihmdW5jX2Nsb3N1cmUpLAorICAgICBSRVNUUklDVEVEfFJFQURPTkxZfSwKKyAgICB7Il9fY2xvc3VyZV9fIiwgIFRfT0JKRUNULCAgICAgIE9GRihmdW5jX2Nsb3N1cmUpLAorICAgICBSRVNUUklDVEVEfFJFQURPTkxZfSwKKyAgICB7ImZ1bmNfZG9jIiwgICAgICBUX09CSkVDVCwgICAgIE9GRihmdW5jX2RvYyksIFBZX1dSSVRFX1JFU1RSSUNURUR9LAorICAgIHsiX19kb2NfXyIsICAgICAgIFRfT0JKRUNULCAgICAgT0ZGKGZ1bmNfZG9jKSwgUFlfV1JJVEVfUkVTVFJJQ1RFRH0sCisgICAgeyJmdW5jX2dsb2JhbHMiLCAgVF9PQkpFQ1QsICAgICBPRkYoZnVuY19nbG9iYWxzKSwKKyAgICAgUkVTVFJJQ1RFRHxSRUFET05MWX0sCisgICAgeyJfX2dsb2JhbHNfXyIsICBUX09CSkVDVCwgICAgICBPRkYoZnVuY19nbG9iYWxzKSwKKyAgICAgUkVTVFJJQ1RFRHxSRUFET05MWX0sCisgICAgeyJfX21vZHVsZV9fIiwgICAgVF9PQkpFQ1QsICAgICBPRkYoZnVuY19tb2R1bGUpLCBQWV9XUklURV9SRVNUUklDVEVEfSwKKyAgICB7TlVMTH0gIC8qIFNlbnRpbmVsICovCit9OworCitzdGF0aWMgaW50CityZXN0cmljdGVkKHZvaWQpCit7CisgICAgaWYgKCFQeUV2YWxfR2V0UmVzdHJpY3RlZCgpKQorICAgICAgICByZXR1cm4gMDsKKyAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfUnVudGltZUVycm9yLAorICAgICAgICAiZnVuY3Rpb24gYXR0cmlidXRlcyBub3QgYWNjZXNzaWJsZSBpbiByZXN0cmljdGVkIG1vZGUiKTsKKyAgICByZXR1cm4gMTsKK30KKworc3RhdGljIFB5T2JqZWN0ICoKK2Z1bmNfZ2V0X2RpY3QoUHlGdW5jdGlvbk9iamVjdCAqb3ApCit7CisgICAgaWYgKHJlc3RyaWN0ZWQoKSkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgaWYgKG9wLT5mdW5jX2RpY3QgPT0gTlVMTCkgeworICAgICAgICBvcC0+ZnVuY19kaWN0ID0gUHlEaWN0X05ldygpOworICAgICAgICBpZiAob3AtPmZ1bmNfZGljdCA9PSBOVUxMKQorICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIFB5X0lOQ1JFRihvcC0+ZnVuY19kaWN0KTsKKyAgICByZXR1cm4gb3AtPmZ1bmNfZGljdDsKK30KKworc3RhdGljIGludAorZnVuY19zZXRfZGljdChQeUZ1bmN0aW9uT2JqZWN0ICpvcCwgUHlPYmplY3QgKnZhbHVlKQoreworICAgIFB5T2JqZWN0ICp0bXA7CisKKyAgICBpZiAocmVzdHJpY3RlZCgpKQorICAgICAgICByZXR1cm4gLTE7CisgICAgLyogSXQgaXMgaWxsZWdhbCB0byBkZWwgZi5mdW5jX2RpY3QgKi8KKyAgICBpZiAodmFsdWUgPT0gTlVMTCkgeworICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfVHlwZUVycm9yLAorICAgICAgICAgICAgICAgICAgICAgICAgImZ1bmN0aW9uJ3MgZGljdGlvbmFyeSBtYXkgbm90IGJlIGRlbGV0ZWQiKTsKKyAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKyAgICAvKiBDYW4gb25seSBzZXQgZnVuY19kaWN0IHRvIGEgZGljdGlvbmFyeSAqLworICAgIGlmICghUHlEaWN0X0NoZWNrKHZhbHVlKSkgeworICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfVHlwZUVycm9yLAorICAgICAgICAgICAgICAgICAgICAgICAgInNldHRpbmcgZnVuY3Rpb24ncyBkaWN0aW9uYXJ5IHRvIGEgbm9uLWRpY3QiKTsKKyAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKyAgICB0bXAgPSBvcC0+ZnVuY19kaWN0OworICAgIFB5X0lOQ1JFRih2YWx1ZSk7CisgICAgb3AtPmZ1bmNfZGljdCA9IHZhbHVlOworICAgIFB5X1hERUNSRUYodG1wKTsKKyAgICByZXR1cm4gMDsKK30KKworc3RhdGljIFB5T2JqZWN0ICoKK2Z1bmNfZ2V0X2NvZGUoUHlGdW5jdGlvbk9iamVjdCAqb3ApCit7CisgICAgaWYgKHJlc3RyaWN0ZWQoKSkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgUHlfSU5DUkVGKG9wLT5mdW5jX2NvZGUpOworICAgIHJldHVybiBvcC0+ZnVuY19jb2RlOworfQorCitzdGF0aWMgaW50CitmdW5jX3NldF9jb2RlKFB5RnVuY3Rpb25PYmplY3QgKm9wLCBQeU9iamVjdCAqdmFsdWUpCit7CisgICAgUHlPYmplY3QgKnRtcDsKKyAgICBQeV9zc2l6ZV90IG5mcmVlLCBuY2xvc3VyZTsKKworICAgIGlmIChyZXN0cmljdGVkKCkpCisgICAgICAgIHJldHVybiAtMTsKKyAgICAvKiBOb3QgbGVnYWwgdG8gZGVsIGYuZnVuY19jb2RlIG9yIHRvIHNldCBpdCB0byBhbnl0aGluZworICAgICAqIG90aGVyIHRoYW4gYSBjb2RlIG9iamVjdC4gKi8KKyAgICBpZiAodmFsdWUgPT0gTlVMTCB8fCAhUHlDb2RlX0NoZWNrKHZhbHVlKSkgeworICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfVHlwZUVycm9yLAorICAgICAgICAgICAgICAgICAgICAgICAgIl9fY29kZV9fIG11c3QgYmUgc2V0IHRvIGEgY29kZSBvYmplY3QiKTsKKyAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKyAgICBuZnJlZSA9IFB5Q29kZV9HZXROdW1GcmVlKChQeUNvZGVPYmplY3QgKil2YWx1ZSk7CisgICAgbmNsb3N1cmUgPSAob3AtPmZ1bmNfY2xvc3VyZSA9PSBOVUxMID8gMCA6CisgICAgICAgICAgICBQeVR1cGxlX0dFVF9TSVpFKG9wLT5mdW5jX2Nsb3N1cmUpKTsKKyAgICBpZiAobmNsb3N1cmUgIT0gbmZyZWUpIHsKKyAgICAgICAgUHlFcnJfRm9ybWF0KFB5RXhjX1ZhbHVlRXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAiJXMoKSByZXF1aXJlcyBhIGNvZGUgb2JqZWN0IHdpdGggJXpkIGZyZWUgdmFycywiCisgICAgICAgICAgICAgICAgICAgICAiIG5vdCAlemQiLAorICAgICAgICAgICAgICAgICAgICAgUHlTdHJpbmdfQXNTdHJpbmcob3AtPmZ1bmNfbmFtZSksCisgICAgICAgICAgICAgICAgICAgICBuY2xvc3VyZSwgbmZyZWUpOworICAgICAgICByZXR1cm4gLTE7CisgICAgfQorICAgIHRtcCA9IG9wLT5mdW5jX2NvZGU7CisgICAgUHlfSU5DUkVGKHZhbHVlKTsKKyAgICBvcC0+ZnVuY19jb2RlID0gdmFsdWU7CisgICAgUHlfREVDUkVGKHRtcCk7CisgICAgcmV0dXJuIDA7Cit9CisKK3N0YXRpYyBQeU9iamVjdCAqCitmdW5jX2dldF9uYW1lKFB5RnVuY3Rpb25PYmplY3QgKm9wKQoreworICAgIFB5X0lOQ1JFRihvcC0+ZnVuY19uYW1lKTsKKyAgICByZXR1cm4gb3AtPmZ1bmNfbmFtZTsKK30KKworc3RhdGljIGludAorZnVuY19zZXRfbmFtZShQeUZ1bmN0aW9uT2JqZWN0ICpvcCwgUHlPYmplY3QgKnZhbHVlKQoreworICAgIFB5T2JqZWN0ICp0bXA7CisKKyAgICBpZiAocmVzdHJpY3RlZCgpKQorICAgICAgICByZXR1cm4gLTE7CisgICAgLyogTm90IGxlZ2FsIHRvIGRlbCBmLmZ1bmNfbmFtZSBvciB0byBzZXQgaXQgdG8gYW55dGhpbmcKKyAgICAgKiBvdGhlciB0aGFuIGEgc3RyaW5nIG9iamVjdC4gKi8KKyAgICBpZiAodmFsdWUgPT0gTlVMTCB8fCAhUHlTdHJpbmdfQ2hlY2sodmFsdWUpKSB7CisgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19UeXBlRXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAgICAiX19uYW1lX18gbXVzdCBiZSBzZXQgdG8gYSBzdHJpbmcgb2JqZWN0Iik7CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisgICAgdG1wID0gb3AtPmZ1bmNfbmFtZTsKKyAgICBQeV9JTkNSRUYodmFsdWUpOworICAgIG9wLT5mdW5jX25hbWUgPSB2YWx1ZTsKKyAgICBQeV9ERUNSRUYodG1wKTsKKyAgICByZXR1cm4gMDsKK30KKworc3RhdGljIFB5T2JqZWN0ICoKK2Z1bmNfZ2V0X2RlZmF1bHRzKFB5RnVuY3Rpb25PYmplY3QgKm9wKQoreworICAgIGlmIChyZXN0cmljdGVkKCkpCisgICAgICAgIHJldHVybiBOVUxMOworICAgIGlmIChvcC0+ZnVuY19kZWZhdWx0cyA9PSBOVUxMKSB7CisgICAgICAgIFB5X0lOQ1JFRihQeV9Ob25lKTsKKyAgICAgICAgcmV0dXJuIFB5X05vbmU7CisgICAgfQorICAgIFB5X0lOQ1JFRihvcC0+ZnVuY19kZWZhdWx0cyk7CisgICAgcmV0dXJuIG9wLT5mdW5jX2RlZmF1bHRzOworfQorCitzdGF0aWMgaW50CitmdW5jX3NldF9kZWZhdWx0cyhQeUZ1bmN0aW9uT2JqZWN0ICpvcCwgUHlPYmplY3QgKnZhbHVlKQoreworICAgIFB5T2JqZWN0ICp0bXA7CisKKyAgICBpZiAocmVzdHJpY3RlZCgpKQorICAgICAgICByZXR1cm4gLTE7CisgICAgLyogTGVnYWwgdG8gZGVsIGYuZnVuY19kZWZhdWx0cy4KKyAgICAgKiBDYW4gb25seSBzZXQgZnVuY19kZWZhdWx0cyB0byBOVUxMIG9yIGEgdHVwbGUuICovCisgICAgaWYgKHZhbHVlID09IFB5X05vbmUpCisgICAgICAgIHZhbHVlID0gTlVMTDsKKyAgICBpZiAodmFsdWUgIT0gTlVMTCAmJiAhUHlUdXBsZV9DaGVjayh2YWx1ZSkpIHsKKyAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1R5cGVFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICJfX2RlZmF1bHRzX18gbXVzdCBiZSBzZXQgdG8gYSB0dXBsZSBvYmplY3QiKTsKKyAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKyAgICB0bXAgPSBvcC0+ZnVuY19kZWZhdWx0czsKKyAgICBQeV9YSU5DUkVGKHZhbHVlKTsKKyAgICBvcC0+ZnVuY19kZWZhdWx0cyA9IHZhbHVlOworICAgIFB5X1hERUNSRUYodG1wKTsKKyAgICByZXR1cm4gMDsKK30KKworc3RhdGljIFB5R2V0U2V0RGVmIGZ1bmNfZ2V0c2V0bGlzdFtdID0geworICAgIHsiZnVuY19jb2RlIiwgKGdldHRlcilmdW5jX2dldF9jb2RlLCAoc2V0dGVyKWZ1bmNfc2V0X2NvZGV9LAorICAgIHsiX19jb2RlX18iLCAoZ2V0dGVyKWZ1bmNfZ2V0X2NvZGUsIChzZXR0ZXIpZnVuY19zZXRfY29kZX0sCisgICAgeyJmdW5jX2RlZmF1bHRzIiwgKGdldHRlcilmdW5jX2dldF9kZWZhdWx0cywKKyAgICAgKHNldHRlcilmdW5jX3NldF9kZWZhdWx0c30sCisgICAgeyJfX2RlZmF1bHRzX18iLCAoZ2V0dGVyKWZ1bmNfZ2V0X2RlZmF1bHRzLAorICAgICAoc2V0dGVyKWZ1bmNfc2V0X2RlZmF1bHRzfSwKKyAgICB7ImZ1bmNfZGljdCIsIChnZXR0ZXIpZnVuY19nZXRfZGljdCwgKHNldHRlcilmdW5jX3NldF9kaWN0fSwKKyAgICB7Il9fZGljdF9fIiwgKGdldHRlcilmdW5jX2dldF9kaWN0LCAoc2V0dGVyKWZ1bmNfc2V0X2RpY3R9LAorICAgIHsiZnVuY19uYW1lIiwgKGdldHRlcilmdW5jX2dldF9uYW1lLCAoc2V0dGVyKWZ1bmNfc2V0X25hbWV9LAorICAgIHsiX19uYW1lX18iLCAoZ2V0dGVyKWZ1bmNfZ2V0X25hbWUsIChzZXR0ZXIpZnVuY19zZXRfbmFtZX0sCisgICAge05VTEx9IC8qIFNlbnRpbmVsICovCit9OworCitQeURvY19TVFJWQVIoZnVuY19kb2MsCisiZnVuY3Rpb24oY29kZSwgZ2xvYmFsc1ssIG5hbWVbLCBhcmdkZWZzWywgY2xvc3VyZV1dXSlcblwKK1xuXAorQ3JlYXRlIGEgZnVuY3Rpb24gb2JqZWN0IGZyb20gYSBjb2RlIG9iamVjdCBhbmQgYSBkaWN0aW9uYXJ5LlxuXAorVGhlIG9wdGlvbmFsIG5hbWUgc3RyaW5nIG92ZXJyaWRlcyB0aGUgbmFtZSBmcm9tIHRoZSBjb2RlIG9iamVjdC5cblwKK1RoZSBvcHRpb25hbCBhcmdkZWZzIHR1cGxlIHNwZWNpZmllcyB0aGUgZGVmYXVsdCBhcmd1bWVudCB2YWx1ZXMuXG5cCitUaGUgb3B0aW9uYWwgY2xvc3VyZSB0dXBsZSBzdXBwbGllcyB0aGUgYmluZGluZ3MgZm9yIGZyZWUgdmFyaWFibGVzLiIpOworCisvKiBmdW5jX25ldygpIG1haW50YWlucyB0aGUgZm9sbG93aW5nIGludmFyaWFudHMgZm9yIGNsb3N1cmVzLiAgVGhlCisgICBjbG9zdXJlIG11c3QgY29ycmVzcG9uZCB0byB0aGUgZnJlZSB2YXJpYWJsZXMgb2YgdGhlIGNvZGUgb2JqZWN0LgorCisgICBpZiBsZW4oY29kZS5jb19mcmVldmFycykgPT0gMDoKKyAgICAgICBjbG9zdXJlID0gTlVMTAorICAgZWxzZToKKyAgICAgICBsZW4oY2xvc3VyZSkgPT0gbGVuKGNvZGUuY29fZnJlZXZhcnMpCisgICBmb3IgZXZlcnkgZWx0IGluIGNsb3N1cmUsIHR5cGUoZWx0KSA9PSBjZWxsCisqLworCitzdGF0aWMgUHlPYmplY3QgKgorZnVuY19uZXcoUHlUeXBlT2JqZWN0KiB0eXBlLCBQeU9iamVjdCogYXJncywgUHlPYmplY3QqIGt3KQoreworICAgIFB5Q29kZU9iamVjdCAqY29kZTsKKyAgICBQeU9iamVjdCAqZ2xvYmFsczsKKyAgICBQeU9iamVjdCAqbmFtZSA9IFB5X05vbmU7CisgICAgUHlPYmplY3QgKmRlZmF1bHRzID0gUHlfTm9uZTsKKyAgICBQeU9iamVjdCAqY2xvc3VyZSA9IFB5X05vbmU7CisgICAgUHlGdW5jdGlvbk9iamVjdCAqbmV3ZnVuYzsKKyAgICBQeV9zc2l6ZV90IG5mcmVlLCBuY2xvc3VyZTsKKyAgICBzdGF0aWMgY2hhciAqa3dsaXN0W10gPSB7ImNvZGUiLCAiZ2xvYmFscyIsICJuYW1lIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImFyZ2RlZnMiLCAiY2xvc3VyZSIsIDB9OworCisgICAgaWYgKCFQeUFyZ19QYXJzZVR1cGxlQW5kS2V5d29yZHMoYXJncywga3csICJPIU8hfE9PTzpmdW5jdGlvbiIsCisgICAgICAgICAgICAgICAgICAgICAgICAgIGt3bGlzdCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgJlB5Q29kZV9UeXBlLCAmY29kZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgJlB5RGljdF9UeXBlLCAmZ2xvYmFscywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgJm5hbWUsICZkZWZhdWx0cywgJmNsb3N1cmUpKQorICAgICAgICByZXR1cm4gTlVMTDsKKyAgICBpZiAobmFtZSAhPSBQeV9Ob25lICYmICFQeVN0cmluZ19DaGVjayhuYW1lKSkgeworICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfVHlwZUVycm9yLAorICAgICAgICAgICAgICAgICAgICAgICAgImFyZyAzIChuYW1lKSBtdXN0IGJlIE5vbmUgb3Igc3RyaW5nIik7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICBpZiAoZGVmYXVsdHMgIT0gUHlfTm9uZSAmJiAhUHlUdXBsZV9DaGVjayhkZWZhdWx0cykpIHsKKyAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1R5cGVFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICJhcmcgNCAoZGVmYXVsdHMpIG11c3QgYmUgTm9uZSBvciB0dXBsZSIpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgbmZyZWUgPSBQeVR1cGxlX0dFVF9TSVpFKGNvZGUtPmNvX2ZyZWV2YXJzKTsKKyAgICBpZiAoIVB5VHVwbGVfQ2hlY2soY2xvc3VyZSkpIHsKKyAgICAgICAgaWYgKG5mcmVlICYmIGNsb3N1cmUgPT0gUHlfTm9uZSkgeworICAgICAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1R5cGVFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAiYXJnIDUgKGNsb3N1cmUpIG11c3QgYmUgdHVwbGUiKTsKKyAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgICAgICB9CisgICAgICAgIGVsc2UgaWYgKGNsb3N1cmUgIT0gUHlfTm9uZSkgeworICAgICAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1R5cGVFcnJvciwKKyAgICAgICAgICAgICAgICAiYXJnIDUgKGNsb3N1cmUpIG11c3QgYmUgTm9uZSBvciB0dXBsZSIpOworICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKiBjaGVjayB0aGF0IHRoZSBjbG9zdXJlIGlzIHdlbGwtZm9ybWVkICovCisgICAgbmNsb3N1cmUgPSBjbG9zdXJlID09IFB5X05vbmUgPyAwIDogUHlUdXBsZV9HRVRfU0laRShjbG9zdXJlKTsKKyAgICBpZiAobmZyZWUgIT0gbmNsb3N1cmUpCisgICAgICAgIHJldHVybiBQeUVycl9Gb3JtYXQoUHlFeGNfVmFsdWVFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAiJXMgcmVxdWlyZXMgY2xvc3VyZSBvZiBsZW5ndGggJXpkLCBub3QgJXpkIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBQeVN0cmluZ19BU19TVFJJTkcoY29kZS0+Y29fbmFtZSksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmZyZWUsIG5jbG9zdXJlKTsKKyAgICBpZiAobmNsb3N1cmUpIHsKKyAgICAgICAgUHlfc3NpemVfdCBpOworICAgICAgICBmb3IgKGkgPSAwOyBpIDwgbmNsb3N1cmU7IGkrKykgeworICAgICAgICAgICAgUHlPYmplY3QgKm8gPSBQeVR1cGxlX0dFVF9JVEVNKGNsb3N1cmUsIGkpOworICAgICAgICAgICAgaWYgKCFQeUNlbGxfQ2hlY2sobykpIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gUHlFcnJfRm9ybWF0KFB5RXhjX1R5cGVFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgImFyZyA1IChjbG9zdXJlKSBleHBlY3RlZCBjZWxsLCBmb3VuZCAlcyIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvLT5vYl90eXBlLT50cF9uYW1lKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIG5ld2Z1bmMgPSAoUHlGdW5jdGlvbk9iamVjdCAqKVB5RnVuY3Rpb25fTmV3KChQeU9iamVjdCAqKWNvZGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2xvYmFscyk7CisgICAgaWYgKG5ld2Z1bmMgPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisKKyAgICBpZiAobmFtZSAhPSBQeV9Ob25lKSB7CisgICAgICAgIFB5X0lOQ1JFRihuYW1lKTsKKyAgICAgICAgUHlfREVDUkVGKG5ld2Z1bmMtPmZ1bmNfbmFtZSk7CisgICAgICAgIG5ld2Z1bmMtPmZ1bmNfbmFtZSA9IG5hbWU7CisgICAgfQorICAgIGlmIChkZWZhdWx0cyAhPSBQeV9Ob25lKSB7CisgICAgICAgIFB5X0lOQ1JFRihkZWZhdWx0cyk7CisgICAgICAgIG5ld2Z1bmMtPmZ1bmNfZGVmYXVsdHMgID0gZGVmYXVsdHM7CisgICAgfQorICAgIGlmIChjbG9zdXJlICE9IFB5X05vbmUpIHsKKyAgICAgICAgUHlfSU5DUkVGKGNsb3N1cmUpOworICAgICAgICBuZXdmdW5jLT5mdW5jX2Nsb3N1cmUgPSBjbG9zdXJlOworICAgIH0KKworICAgIHJldHVybiAoUHlPYmplY3QgKiluZXdmdW5jOworfQorCitzdGF0aWMgdm9pZAorZnVuY19kZWFsbG9jKFB5RnVuY3Rpb25PYmplY3QgKm9wKQoreworICAgIF9QeU9iamVjdF9HQ19VTlRSQUNLKG9wKTsKKyAgICBpZiAob3AtPmZ1bmNfd2Vha3JlZmxpc3QgIT0gTlVMTCkKKyAgICAgICAgUHlPYmplY3RfQ2xlYXJXZWFrUmVmcygoUHlPYmplY3QgKikgb3ApOworICAgIFB5X0RFQ1JFRihvcC0+ZnVuY19jb2RlKTsKKyAgICBQeV9ERUNSRUYob3AtPmZ1bmNfZ2xvYmFscyk7CisgICAgUHlfWERFQ1JFRihvcC0+ZnVuY19tb2R1bGUpOworICAgIFB5X0RFQ1JFRihvcC0+ZnVuY19uYW1lKTsKKyAgICBQeV9YREVDUkVGKG9wLT5mdW5jX2RlZmF1bHRzKTsKKyAgICBQeV9YREVDUkVGKG9wLT5mdW5jX2RvYyk7CisgICAgUHlfWERFQ1JFRihvcC0+ZnVuY19kaWN0KTsKKyAgICBQeV9YREVDUkVGKG9wLT5mdW5jX2Nsb3N1cmUpOworICAgIFB5T2JqZWN0X0dDX0RlbChvcCk7Cit9CisKK3N0YXRpYyBQeU9iamVjdCoKK2Z1bmNfcmVwcihQeUZ1bmN0aW9uT2JqZWN0ICpvcCkKK3sKKyAgICByZXR1cm4gUHlTdHJpbmdfRnJvbUZvcm1hdCgiPGZ1bmN0aW9uICVzIGF0ICVwPiIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHlTdHJpbmdfQXNTdHJpbmcob3AtPmZ1bmNfbmFtZSksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3ApOworfQorCitzdGF0aWMgaW50CitmdW5jX3RyYXZlcnNlKFB5RnVuY3Rpb25PYmplY3QgKmYsIHZpc2l0cHJvYyB2aXNpdCwgdm9pZCAqYXJnKQoreworICAgIFB5X1ZJU0lUKGYtPmZ1bmNfY29kZSk7CisgICAgUHlfVklTSVQoZi0+ZnVuY19nbG9iYWxzKTsKKyAgICBQeV9WSVNJVChmLT5mdW5jX21vZHVsZSk7CisgICAgUHlfVklTSVQoZi0+ZnVuY19kZWZhdWx0cyk7CisgICAgUHlfVklTSVQoZi0+ZnVuY19kb2MpOworICAgIFB5X1ZJU0lUKGYtPmZ1bmNfbmFtZSk7CisgICAgUHlfVklTSVQoZi0+ZnVuY19kaWN0KTsKKyAgICBQeV9WSVNJVChmLT5mdW5jX2Nsb3N1cmUpOworICAgIHJldHVybiAwOworfQorCitzdGF0aWMgUHlPYmplY3QgKgorZnVuY3Rpb25fY2FsbChQeU9iamVjdCAqZnVuYywgUHlPYmplY3QgKmFyZywgUHlPYmplY3QgKmt3KQoreworICAgIFB5T2JqZWN0ICpyZXN1bHQ7CisgICAgUHlPYmplY3QgKmFyZ2RlZnM7CisgICAgUHlPYmplY3QgKmt3dHVwbGUgPSBOVUxMOworICAgIFB5T2JqZWN0ICoqZCwgKiprOworICAgIFB5X3NzaXplX3QgbmssIG5kOworCisgICAgYXJnZGVmcyA9IFB5RnVuY3Rpb25fR0VUX0RFRkFVTFRTKGZ1bmMpOworICAgIGlmIChhcmdkZWZzICE9IE5VTEwgJiYgUHlUdXBsZV9DaGVjayhhcmdkZWZzKSkgeworICAgICAgICBkID0gJlB5VHVwbGVfR0VUX0lURU0oKFB5VHVwbGVPYmplY3QgKilhcmdkZWZzLCAwKTsKKyAgICAgICAgbmQgPSBQeVR1cGxlX0dFVF9TSVpFKGFyZ2RlZnMpOworICAgIH0KKyAgICBlbHNlIHsKKyAgICAgICAgZCA9IE5VTEw7CisgICAgICAgIG5kID0gMDsKKyAgICB9CisKKyAgICBpZiAoa3cgIT0gTlVMTCAmJiBQeURpY3RfQ2hlY2soa3cpKSB7CisgICAgICAgIFB5X3NzaXplX3QgcG9zLCBpOworICAgICAgICBuayA9IFB5RGljdF9TaXplKGt3KTsKKyAgICAgICAga3d0dXBsZSA9IFB5VHVwbGVfTmV3KDIqbmspOworICAgICAgICBpZiAoa3d0dXBsZSA9PSBOVUxMKQorICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgICAgIGsgPSAmUHlUdXBsZV9HRVRfSVRFTShrd3R1cGxlLCAwKTsKKyAgICAgICAgcG9zID0gaSA9IDA7CisgICAgICAgIHdoaWxlIChQeURpY3RfTmV4dChrdywgJnBvcywgJmtbaV0sICZrW2krMV0pKSB7CisgICAgICAgICAgICBQeV9JTkNSRUYoa1tpXSk7CisgICAgICAgICAgICBQeV9JTkNSRUYoa1tpKzFdKTsKKyAgICAgICAgICAgIGkgKz0gMjsKKyAgICAgICAgfQorICAgICAgICBuayA9IGkvMjsKKyAgICB9CisgICAgZWxzZSB7CisgICAgICAgIGsgPSBOVUxMOworICAgICAgICBuayA9IDA7CisgICAgfQorCisgICAgcmVzdWx0ID0gUHlFdmFsX0V2YWxDb2RlRXgoCisgICAgICAgIChQeUNvZGVPYmplY3QgKilQeUZ1bmN0aW9uX0dFVF9DT0RFKGZ1bmMpLAorICAgICAgICBQeUZ1bmN0aW9uX0dFVF9HTE9CQUxTKGZ1bmMpLCAoUHlPYmplY3QgKilOVUxMLAorICAgICAgICAmUHlUdXBsZV9HRVRfSVRFTShhcmcsIDApLCBQeVR1cGxlX0dFVF9TSVpFKGFyZyksCisgICAgICAgIGssIG5rLCBkLCBuZCwKKyAgICAgICAgUHlGdW5jdGlvbl9HRVRfQ0xPU1VSRShmdW5jKSk7CisKKyAgICBQeV9YREVDUkVGKGt3dHVwbGUpOworCisgICAgcmV0dXJuIHJlc3VsdDsKK30KKworLyogQmluZCBhIGZ1bmN0aW9uIHRvIGFuIG9iamVjdCAqLworc3RhdGljIFB5T2JqZWN0ICoKK2Z1bmNfZGVzY3JfZ2V0KFB5T2JqZWN0ICpmdW5jLCBQeU9iamVjdCAqb2JqLCBQeU9iamVjdCAqdHlwZSkKK3sKKyAgICBpZiAob2JqID09IFB5X05vbmUpCisgICAgICAgIG9iaiA9IE5VTEw7CisgICAgcmV0dXJuIFB5TWV0aG9kX05ldyhmdW5jLCBvYmosIHR5cGUpOworfQorCitQeVR5cGVPYmplY3QgUHlGdW5jdGlvbl9UeXBlID0geworICAgIFB5VmFyT2JqZWN0X0hFQURfSU5JVCgmUHlUeXBlX1R5cGUsIDApCisgICAgImZ1bmN0aW9uIiwKKyAgICBzaXplb2YoUHlGdW5jdGlvbk9iamVjdCksCisgICAgMCwKKyAgICAoZGVzdHJ1Y3RvcilmdW5jX2RlYWxsb2MsICAgICAgICAgICAgICAgICAgIC8qIHRwX2RlYWxsb2MgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3ByaW50ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9nZXRhdHRyICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9zZXRhdHRyICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9jb21wYXJlICovCisgICAgKHJlcHJmdW5jKWZ1bmNfcmVwciwgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9yZXByICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9hc19udW1iZXIgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2FzX3NlcXVlbmNlICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9hc19tYXBwaW5nICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9oYXNoICovCisgICAgZnVuY3Rpb25fY2FsbCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9jYWxsICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9zdHIgKi8KKyAgICBQeU9iamVjdF9HZW5lcmljR2V0QXR0ciwgICAgICAgICAgICAgICAgICAgIC8qIHRwX2dldGF0dHJvICovCisgICAgUHlPYmplY3RfR2VuZXJpY1NldEF0dHIsICAgICAgICAgICAgICAgICAgICAvKiB0cF9zZXRhdHRybyAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfYXNfYnVmZmVyICovCisgICAgUHlfVFBGTEFHU19ERUZBVUxUIHwgUHlfVFBGTEFHU19IQVZFX0dDLC8qIHRwX2ZsYWdzICovCisgICAgZnVuY19kb2MsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9kb2MgKi8KKyAgICAodHJhdmVyc2Vwcm9jKWZ1bmNfdHJhdmVyc2UsICAgICAgICAgICAgICAgIC8qIHRwX3RyYXZlcnNlICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9jbGVhciAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfcmljaGNvbXBhcmUgKi8KKyAgICBvZmZzZXRvZihQeUZ1bmN0aW9uT2JqZWN0LCBmdW5jX3dlYWtyZWZsaXN0KSwgLyogdHBfd2Vha2xpc3RvZmZzZXQgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2l0ZXIgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2l0ZXJuZXh0ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9tZXRob2RzICovCisgICAgZnVuY19tZW1iZXJsaXN0LCAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9tZW1iZXJzICovCisgICAgZnVuY19nZXRzZXRsaXN0LCAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9nZXRzZXQgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2Jhc2UgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2RpY3QgKi8KKyAgICBmdW5jX2Rlc2NyX2dldCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2Rlc2NyX2dldCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZGVzY3Jfc2V0ICovCisgICAgb2Zmc2V0b2YoUHlGdW5jdGlvbk9iamVjdCwgZnVuY19kaWN0KSwgICAgICAvKiB0cF9kaWN0b2Zmc2V0ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9pbml0ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9hbGxvYyAqLworICAgIGZ1bmNfbmV3LCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfbmV3ICovCit9OworCisKKy8qIENsYXNzIG1ldGhvZCBvYmplY3QgKi8KKworLyogQSBjbGFzcyBtZXRob2QgcmVjZWl2ZXMgdGhlIGNsYXNzIGFzIGltcGxpY2l0IGZpcnN0IGFyZ3VtZW50LAorICAganVzdCBsaWtlIGFuIGluc3RhbmNlIG1ldGhvZCByZWNlaXZlcyB0aGUgaW5zdGFuY2UuCisgICBUbyBkZWNsYXJlIGEgY2xhc3MgbWV0aG9kLCB1c2UgdGhpcyBpZGlvbToKKworICAgICBjbGFzcyBDOgorICAgICBkZWYgZihjbHMsIGFyZzEsIGFyZzIsIC4uLik6IC4uLgorICAgICBmID0gY2xhc3NtZXRob2QoZikKKworICAgSXQgY2FuIGJlIGNhbGxlZCBlaXRoZXIgb24gdGhlIGNsYXNzIChlLmcuIEMuZigpKSBvciBvbiBhbiBpbnN0YW5jZQorICAgKGUuZy4gQygpLmYoKSk7IHRoZSBpbnN0YW5jZSBpcyBpZ25vcmVkIGV4Y2VwdCBmb3IgaXRzIGNsYXNzLgorICAgSWYgYSBjbGFzcyBtZXRob2QgaXMgY2FsbGVkIGZvciBhIGRlcml2ZWQgY2xhc3MsIHRoZSBkZXJpdmVkIGNsYXNzCisgICBvYmplY3QgaXMgcGFzc2VkIGFzIHRoZSBpbXBsaWVkIGZpcnN0IGFyZ3VtZW50LgorCisgICBDbGFzcyBtZXRob2RzIGFyZSBkaWZmZXJlbnQgdGhhbiBDKysgb3IgSmF2YSBzdGF0aWMgbWV0aG9kcy4KKyAgIElmIHlvdSB3YW50IHRob3NlLCBzZWUgc3RhdGljIG1ldGhvZHMgYmVsb3cuCisqLworCit0eXBlZGVmIHN0cnVjdCB7CisgICAgUHlPYmplY3RfSEVBRAorICAgIFB5T2JqZWN0ICpjbV9jYWxsYWJsZTsKK30gY2xhc3NtZXRob2Q7CisKK3N0YXRpYyB2b2lkCitjbV9kZWFsbG9jKGNsYXNzbWV0aG9kICpjbSkKK3sKKyAgICBfUHlPYmplY3RfR0NfVU5UUkFDSygoUHlPYmplY3QgKiljbSk7CisgICAgUHlfWERFQ1JFRihjbS0+Y21fY2FsbGFibGUpOworICAgIFB5X1RZUEUoY20pLT50cF9mcmVlKChQeU9iamVjdCAqKWNtKTsKK30KKworc3RhdGljIGludAorY21fdHJhdmVyc2UoY2xhc3NtZXRob2QgKmNtLCB2aXNpdHByb2MgdmlzaXQsIHZvaWQgKmFyZykKK3sKKyAgICBQeV9WSVNJVChjbS0+Y21fY2FsbGFibGUpOworICAgIHJldHVybiAwOworfQorCitzdGF0aWMgaW50CitjbV9jbGVhcihjbGFzc21ldGhvZCAqY20pCit7CisgICAgUHlfQ0xFQVIoY20tPmNtX2NhbGxhYmxlKTsKKyAgICByZXR1cm4gMDsKK30KKworCitzdGF0aWMgUHlPYmplY3QgKgorY21fZGVzY3JfZ2V0KFB5T2JqZWN0ICpzZWxmLCBQeU9iamVjdCAqb2JqLCBQeU9iamVjdCAqdHlwZSkKK3sKKyAgICBjbGFzc21ldGhvZCAqY20gPSAoY2xhc3NtZXRob2QgKilzZWxmOworCisgICAgaWYgKGNtLT5jbV9jYWxsYWJsZSA9PSBOVUxMKSB7CisgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19SdW50aW1lRXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAgICAidW5pbml0aWFsaXplZCBjbGFzc21ldGhvZCBvYmplY3QiKTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIGlmICh0eXBlID09IE5VTEwpCisgICAgICAgIHR5cGUgPSAoUHlPYmplY3QgKikoUHlfVFlQRShvYmopKTsKKyAgICByZXR1cm4gUHlNZXRob2RfTmV3KGNtLT5jbV9jYWxsYWJsZSwKKyAgICAgICAgICAgICAgICAgICAgICAgIHR5cGUsIChQeU9iamVjdCAqKShQeV9UWVBFKHR5cGUpKSk7Cit9CisKK3N0YXRpYyBpbnQKK2NtX2luaXQoUHlPYmplY3QgKnNlbGYsIFB5T2JqZWN0ICphcmdzLCBQeU9iamVjdCAqa3dkcykKK3sKKyAgICBjbGFzc21ldGhvZCAqY20gPSAoY2xhc3NtZXRob2QgKilzZWxmOworICAgIFB5T2JqZWN0ICpjYWxsYWJsZTsKKworICAgIGlmICghUHlBcmdfVW5wYWNrVHVwbGUoYXJncywgImNsYXNzbWV0aG9kIiwgMSwgMSwgJmNhbGxhYmxlKSkKKyAgICAgICAgcmV0dXJuIC0xOworICAgIGlmICghX1B5QXJnX05vS2V5d29yZHMoImNsYXNzbWV0aG9kIiwga3dkcykpCisgICAgICAgIHJldHVybiAtMTsKKyAgICBQeV9JTkNSRUYoY2FsbGFibGUpOworICAgIGNtLT5jbV9jYWxsYWJsZSA9IGNhbGxhYmxlOworICAgIHJldHVybiAwOworfQorCitzdGF0aWMgUHlNZW1iZXJEZWYgY21fbWVtYmVybGlzdFtdID0geworICAgIHsiX19mdW5jX18iLCBUX09CSkVDVCwgb2Zmc2V0b2YoY2xhc3NtZXRob2QsIGNtX2NhbGxhYmxlKSwgUkVBRE9OTFl9LAorICAgIHtOVUxMfSAgLyogU2VudGluZWwgKi8KK307CisKK1B5RG9jX1NUUlZBUihjbGFzc21ldGhvZF9kb2MsCisiY2xhc3NtZXRob2QoZnVuY3Rpb24pIC0+IG1ldGhvZFxuXAorXG5cCitDb252ZXJ0IGEgZnVuY3Rpb24gdG8gYmUgYSBjbGFzcyBtZXRob2QuXG5cCitcblwKK0EgY2xhc3MgbWV0aG9kIHJlY2VpdmVzIHRoZSBjbGFzcyBhcyBpbXBsaWNpdCBmaXJzdCBhcmd1bWVudCxcblwKK2p1c3QgbGlrZSBhbiBpbnN0YW5jZSBtZXRob2QgcmVjZWl2ZXMgdGhlIGluc3RhbmNlLlxuXAorVG8gZGVjbGFyZSBhIGNsYXNzIG1ldGhvZCwgdXNlIHRoaXMgaWRpb206XG5cCitcblwKKyAgY2xhc3MgQzpcblwKKyAgICAgIGRlZiBmKGNscywgYXJnMSwgYXJnMiwgLi4uKTogLi4uXG5cCisgICAgICBmID0gY2xhc3NtZXRob2QoZilcblwKK1xuXAorSXQgY2FuIGJlIGNhbGxlZCBlaXRoZXIgb24gdGhlIGNsYXNzIChlLmcuIEMuZigpKSBvciBvbiBhbiBpbnN0YW5jZVxuXAorKGUuZy4gQygpLmYoKSkuICBUaGUgaW5zdGFuY2UgaXMgaWdub3JlZCBleGNlcHQgZm9yIGl0cyBjbGFzcy5cblwKK0lmIGEgY2xhc3MgbWV0aG9kIGlzIGNhbGxlZCBmb3IgYSBkZXJpdmVkIGNsYXNzLCB0aGUgZGVyaXZlZCBjbGFzc1xuXAorb2JqZWN0IGlzIHBhc3NlZCBhcyB0aGUgaW1wbGllZCBmaXJzdCBhcmd1bWVudC5cblwKK1xuXAorQ2xhc3MgbWV0aG9kcyBhcmUgZGlmZmVyZW50IHRoYW4gQysrIG9yIEphdmEgc3RhdGljIG1ldGhvZHMuXG5cCitJZiB5b3Ugd2FudCB0aG9zZSwgc2VlIHRoZSBzdGF0aWNtZXRob2QgYnVpbHRpbi4iKTsKKworUHlUeXBlT2JqZWN0IFB5Q2xhc3NNZXRob2RfVHlwZSA9IHsKKyAgICBQeVZhck9iamVjdF9IRUFEX0lOSVQoJlB5VHlwZV9UeXBlLCAwKQorICAgICJjbGFzc21ldGhvZCIsCisgICAgc2l6ZW9mKGNsYXNzbWV0aG9kKSwKKyAgICAwLAorICAgIChkZXN0cnVjdG9yKWNtX2RlYWxsb2MsICAgICAgICAgICAgICAgICAgICAgLyogdHBfZGVhbGxvYyAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfcHJpbnQgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2dldGF0dHIgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3NldGF0dHIgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2NvbXBhcmUgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3JlcHIgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2FzX251bWJlciAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfYXNfc2VxdWVuY2UgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2FzX21hcHBpbmcgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2hhc2ggKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2NhbGwgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3N0ciAqLworICAgIFB5T2JqZWN0X0dlbmVyaWNHZXRBdHRyLCAgICAgICAgICAgICAgICAgICAgLyogdHBfZ2V0YXR0cm8gKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3NldGF0dHJvICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9hc19idWZmZXIgKi8KKyAgICBQeV9UUEZMQUdTX0RFRkFVTFQgfCBQeV9UUEZMQUdTX0JBU0VUWVBFIHwgUHlfVFBGTEFHU19IQVZFX0dDLAorICAgIGNsYXNzbWV0aG9kX2RvYywgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZG9jICovCisgICAgKHRyYXZlcnNlcHJvYyljbV90cmF2ZXJzZSwgICAgICAgICAgICAgICAgICAvKiB0cF90cmF2ZXJzZSAqLworICAgIChpbnF1aXJ5KWNtX2NsZWFyLCAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfY2xlYXIgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3JpY2hjb21wYXJlICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF93ZWFrbGlzdG9mZnNldCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfaXRlciAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfaXRlcm5leHQgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX21ldGhvZHMgKi8KKyAgICBjbV9tZW1iZXJsaXN0LCAgICAgICAgICAgICAgLyogdHBfbWVtYmVycyAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZ2V0c2V0ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9iYXNlICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9kaWN0ICovCisgICAgY21fZGVzY3JfZ2V0LCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9kZXNjcl9nZXQgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2Rlc2NyX3NldCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZGljdG9mZnNldCAqLworICAgIGNtX2luaXQsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfaW5pdCAqLworICAgIFB5VHlwZV9HZW5lcmljQWxsb2MsICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfYWxsb2MgKi8KKyAgICBQeVR5cGVfR2VuZXJpY05ldywgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX25ldyAqLworICAgIFB5T2JqZWN0X0dDX0RlbCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZnJlZSAqLworfTsKKworUHlPYmplY3QgKgorUHlDbGFzc01ldGhvZF9OZXcoUHlPYmplY3QgKmNhbGxhYmxlKQoreworICAgIGNsYXNzbWV0aG9kICpjbSA9IChjbGFzc21ldGhvZCAqKQorICAgICAgICBQeVR5cGVfR2VuZXJpY0FsbG9jKCZQeUNsYXNzTWV0aG9kX1R5cGUsIDApOworICAgIGlmIChjbSAhPSBOVUxMKSB7CisgICAgICAgIFB5X0lOQ1JFRihjYWxsYWJsZSk7CisgICAgICAgIGNtLT5jbV9jYWxsYWJsZSA9IGNhbGxhYmxlOworICAgIH0KKyAgICByZXR1cm4gKFB5T2JqZWN0ICopY207Cit9CisKKworLyogU3RhdGljIG1ldGhvZCBvYmplY3QgKi8KKworLyogQSBzdGF0aWMgbWV0aG9kIGRvZXMgbm90IHJlY2VpdmUgYW4gaW1wbGljaXQgZmlyc3QgYXJndW1lbnQuCisgICBUbyBkZWNsYXJlIGEgc3RhdGljIG1ldGhvZCwgdXNlIHRoaXMgaWRpb206CisKKyAgICAgY2xhc3MgQzoKKyAgICAgZGVmIGYoYXJnMSwgYXJnMiwgLi4uKTogLi4uCisgICAgIGYgPSBzdGF0aWNtZXRob2QoZikKKworICAgSXQgY2FuIGJlIGNhbGxlZCBlaXRoZXIgb24gdGhlIGNsYXNzIChlLmcuIEMuZigpKSBvciBvbiBhbiBpbnN0YW5jZQorICAgKGUuZy4gQygpLmYoKSk7IHRoZSBpbnN0YW5jZSBpcyBpZ25vcmVkIGV4Y2VwdCBmb3IgaXRzIGNsYXNzLgorCisgICBTdGF0aWMgbWV0aG9kcyBpbiBQeXRob24gYXJlIHNpbWlsYXIgdG8gdGhvc2UgZm91bmQgaW4gSmF2YSBvciBDKysuCisgICBGb3IgYSBtb3JlIGFkdmFuY2VkIGNvbmNlcHQsIHNlZSBjbGFzcyBtZXRob2RzIGFib3ZlLgorKi8KKwordHlwZWRlZiBzdHJ1Y3QgeworICAgIFB5T2JqZWN0X0hFQUQKKyAgICBQeU9iamVjdCAqc21fY2FsbGFibGU7Cit9IHN0YXRpY21ldGhvZDsKKworc3RhdGljIHZvaWQKK3NtX2RlYWxsb2Moc3RhdGljbWV0aG9kICpzbSkKK3sKKyAgICBfUHlPYmplY3RfR0NfVU5UUkFDSygoUHlPYmplY3QgKilzbSk7CisgICAgUHlfWERFQ1JFRihzbS0+c21fY2FsbGFibGUpOworICAgIFB5X1RZUEUoc20pLT50cF9mcmVlKChQeU9iamVjdCAqKXNtKTsKK30KKworc3RhdGljIGludAorc21fdHJhdmVyc2Uoc3RhdGljbWV0aG9kICpzbSwgdmlzaXRwcm9jIHZpc2l0LCB2b2lkICphcmcpCit7CisgICAgUHlfVklTSVQoc20tPnNtX2NhbGxhYmxlKTsKKyAgICByZXR1cm4gMDsKK30KKworc3RhdGljIGludAorc21fY2xlYXIoc3RhdGljbWV0aG9kICpzbSkKK3sKKyAgICBQeV9DTEVBUihzbS0+c21fY2FsbGFibGUpOworICAgIHJldHVybiAwOworfQorCitzdGF0aWMgUHlPYmplY3QgKgorc21fZGVzY3JfZ2V0KFB5T2JqZWN0ICpzZWxmLCBQeU9iamVjdCAqb2JqLCBQeU9iamVjdCAqdHlwZSkKK3sKKyAgICBzdGF0aWNtZXRob2QgKnNtID0gKHN0YXRpY21ldGhvZCAqKXNlbGY7CisKKyAgICBpZiAoc20tPnNtX2NhbGxhYmxlID09IE5VTEwpIHsKKyAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1J1bnRpbWVFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICJ1bmluaXRpYWxpemVkIHN0YXRpY21ldGhvZCBvYmplY3QiKTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIFB5X0lOQ1JFRihzbS0+c21fY2FsbGFibGUpOworICAgIHJldHVybiBzbS0+c21fY2FsbGFibGU7Cit9CisKK3N0YXRpYyBpbnQKK3NtX2luaXQoUHlPYmplY3QgKnNlbGYsIFB5T2JqZWN0ICphcmdzLCBQeU9iamVjdCAqa3dkcykKK3sKKyAgICBzdGF0aWNtZXRob2QgKnNtID0gKHN0YXRpY21ldGhvZCAqKXNlbGY7CisgICAgUHlPYmplY3QgKmNhbGxhYmxlOworCisgICAgaWYgKCFQeUFyZ19VbnBhY2tUdXBsZShhcmdzLCAic3RhdGljbWV0aG9kIiwgMSwgMSwgJmNhbGxhYmxlKSkKKyAgICAgICAgcmV0dXJuIC0xOworICAgIGlmICghX1B5QXJnX05vS2V5d29yZHMoInN0YXRpY21ldGhvZCIsIGt3ZHMpKQorICAgICAgICByZXR1cm4gLTE7CisgICAgUHlfSU5DUkVGKGNhbGxhYmxlKTsKKyAgICBzbS0+c21fY2FsbGFibGUgPSBjYWxsYWJsZTsKKyAgICByZXR1cm4gMDsKK30KKworc3RhdGljIFB5TWVtYmVyRGVmIHNtX21lbWJlcmxpc3RbXSA9IHsKKyAgICB7Il9fZnVuY19fIiwgVF9PQkpFQ1QsIG9mZnNldG9mKHN0YXRpY21ldGhvZCwgc21fY2FsbGFibGUpLCBSRUFET05MWX0sCisgICAge05VTEx9ICAvKiBTZW50aW5lbCAqLworfTsKKworUHlEb2NfU1RSVkFSKHN0YXRpY21ldGhvZF9kb2MsCisic3RhdGljbWV0aG9kKGZ1bmN0aW9uKSAtPiBtZXRob2RcblwKK1xuXAorQ29udmVydCBhIGZ1bmN0aW9uIHRvIGJlIGEgc3RhdGljIG1ldGhvZC5cblwKK1xuXAorQSBzdGF0aWMgbWV0aG9kIGRvZXMgbm90IHJlY2VpdmUgYW4gaW1wbGljaXQgZmlyc3QgYXJndW1lbnQuXG5cCitUbyBkZWNsYXJlIGEgc3RhdGljIG1ldGhvZCwgdXNlIHRoaXMgaWRpb206XG5cCitcblwKKyAgICAgY2xhc3MgQzpcblwKKyAgICAgZGVmIGYoYXJnMSwgYXJnMiwgLi4uKTogLi4uXG5cCisgICAgIGYgPSBzdGF0aWNtZXRob2QoZilcblwKK1xuXAorSXQgY2FuIGJlIGNhbGxlZCBlaXRoZXIgb24gdGhlIGNsYXNzIChlLmcuIEMuZigpKSBvciBvbiBhbiBpbnN0YW5jZVxuXAorKGUuZy4gQygpLmYoKSkuICBUaGUgaW5zdGFuY2UgaXMgaWdub3JlZCBleGNlcHQgZm9yIGl0cyBjbGFzcy5cblwKK1xuXAorU3RhdGljIG1ldGhvZHMgaW4gUHl0aG9uIGFyZSBzaW1pbGFyIHRvIHRob3NlIGZvdW5kIGluIEphdmEgb3IgQysrLlxuXAorRm9yIGEgbW9yZSBhZHZhbmNlZCBjb25jZXB0LCBzZWUgdGhlIGNsYXNzbWV0aG9kIGJ1aWx0aW4uIik7CisKK1B5VHlwZU9iamVjdCBQeVN0YXRpY01ldGhvZF9UeXBlID0geworICAgIFB5VmFyT2JqZWN0X0hFQURfSU5JVCgmUHlUeXBlX1R5cGUsIDApCisgICAgInN0YXRpY21ldGhvZCIsCisgICAgc2l6ZW9mKHN0YXRpY21ldGhvZCksCisgICAgMCwKKyAgICAoZGVzdHJ1Y3RvcilzbV9kZWFsbG9jLCAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2RlYWxsb2MgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3ByaW50ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9nZXRhdHRyICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9zZXRhdHRyICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9jb21wYXJlICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9yZXByICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9hc19udW1iZXIgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2FzX3NlcXVlbmNlICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9hc19tYXBwaW5nICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9oYXNoICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9jYWxsICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9zdHIgKi8KKyAgICBQeU9iamVjdF9HZW5lcmljR2V0QXR0ciwgICAgICAgICAgICAgICAgICAgIC8qIHRwX2dldGF0dHJvICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9zZXRhdHRybyAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfYXNfYnVmZmVyICovCisgICAgUHlfVFBGTEFHU19ERUZBVUxUIHwgUHlfVFBGTEFHU19CQVNFVFlQRSB8IFB5X1RQRkxBR1NfSEFWRV9HQywKKyAgICBzdGF0aWNtZXRob2RfZG9jLCAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2RvYyAqLworICAgICh0cmF2ZXJzZXByb2Mpc21fdHJhdmVyc2UsICAgICAgICAgICAgICAgICAgLyogdHBfdHJhdmVyc2UgKi8KKyAgICAoaW5xdWlyeSlzbV9jbGVhciwgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2NsZWFyICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9yaWNoY29tcGFyZSAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfd2Vha2xpc3RvZmZzZXQgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2l0ZXIgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2l0ZXJuZXh0ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9tZXRob2RzICovCisgICAgc21fbWVtYmVybGlzdCwgICAgICAgICAgICAgIC8qIHRwX21lbWJlcnMgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2dldHNldCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfYmFzZSAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZGljdCAqLworICAgIHNtX2Rlc2NyX2dldCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZGVzY3JfZ2V0ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9kZXNjcl9zZXQgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2RpY3RvZmZzZXQgKi8KKyAgICBzbV9pbml0LCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2luaXQgKi8KKyAgICBQeVR5cGVfR2VuZXJpY0FsbG9jLCAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2FsbG9jICovCisgICAgUHlUeXBlX0dlbmVyaWNOZXcsICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9uZXcgKi8KKyAgICBQeU9iamVjdF9HQ19EZWwsICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2ZyZWUgKi8KK307CisKK1B5T2JqZWN0ICoKK1B5U3RhdGljTWV0aG9kX05ldyhQeU9iamVjdCAqY2FsbGFibGUpCit7CisgICAgc3RhdGljbWV0aG9kICpzbSA9IChzdGF0aWNtZXRob2QgKikKKyAgICAgICAgUHlUeXBlX0dlbmVyaWNBbGxvYygmUHlTdGF0aWNNZXRob2RfVHlwZSwgMCk7CisgICAgaWYgKHNtICE9IE5VTEwpIHsKKyAgICAgICAgUHlfSU5DUkVGKGNhbGxhYmxlKTsKKyAgICAgICAgc20tPnNtX2NhbGxhYmxlID0gY2FsbGFibGU7CisgICAgfQorICAgIHJldHVybiAoUHlPYmplY3QgKilzbTsKK30KZGlmZiAtLWdpdCBhL1B5dGhvbi0yLjcuNS9PYmplY3RzL2dlbm9iamVjdC5jIGIvUHl0aG9uLTIuNy41L09iamVjdHMvZ2Vub2JqZWN0LmMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzQxZjY2MAotLS0gL2Rldi9udWxsCisrKyBiL1B5dGhvbi0yLjcuNS9PYmplY3RzL2dlbm9iamVjdC5jCkBAIC0wLDAgKzEsNDE0IEBACisvKiBHZW5lcmF0b3Igb2JqZWN0IGltcGxlbWVudGF0aW9uICovCisKKyNpbmNsdWRlICJQeXRob24uaCIKKyNpbmNsdWRlICJmcmFtZW9iamVjdC5oIgorI2luY2x1ZGUgImdlbm9iamVjdC5oIgorI2luY2x1ZGUgImNldmFsLmgiCisjaW5jbHVkZSAic3RydWN0bWVtYmVyLmgiCisjaW5jbHVkZSAib3Bjb2RlLmgiCisKK3N0YXRpYyBpbnQKK2dlbl90cmF2ZXJzZShQeUdlbk9iamVjdCAqZ2VuLCB2aXNpdHByb2MgdmlzaXQsIHZvaWQgKmFyZykKK3sKKyAgICBQeV9WSVNJVCgoUHlPYmplY3QgKilnZW4tPmdpX2ZyYW1lKTsKKyAgICBQeV9WSVNJVChnZW4tPmdpX2NvZGUpOworICAgIHJldHVybiAwOworfQorCitzdGF0aWMgdm9pZAorZ2VuX2RlYWxsb2MoUHlHZW5PYmplY3QgKmdlbikKK3sKKyAgICBQeU9iamVjdCAqc2VsZiA9IChQeU9iamVjdCAqKSBnZW47CisKKyAgICBfUHlPYmplY3RfR0NfVU5UUkFDSyhnZW4pOworCisgICAgaWYgKGdlbi0+Z2lfd2Vha3JlZmxpc3QgIT0gTlVMTCkKKyAgICAgICAgUHlPYmplY3RfQ2xlYXJXZWFrUmVmcyhzZWxmKTsKKworICAgIF9QeU9iamVjdF9HQ19UUkFDSyhzZWxmKTsKKworICAgIGlmIChnZW4tPmdpX2ZyYW1lICE9IE5VTEwgJiYgZ2VuLT5naV9mcmFtZS0+Zl9zdGFja3RvcCAhPSBOVUxMKSB7CisgICAgICAgIC8qIEdlbmVyYXRvciBpcyBwYXVzZWQsIHNvIHdlIG5lZWQgdG8gY2xvc2UgKi8KKyAgICAgICAgUHlfVFlQRShnZW4pLT50cF9kZWwoc2VsZik7CisgICAgICAgIGlmIChzZWxmLT5vYl9yZWZjbnQgPiAwKQorICAgICAgICAgICAgcmV0dXJuOyAgICAgICAgICAgICAgICAgICAgIC8qIHJlc3VycmVjdGVkLiAgOiggKi8KKyAgICB9CisKKyAgICBfUHlPYmplY3RfR0NfVU5UUkFDSyhzZWxmKTsKKyAgICBQeV9DTEVBUihnZW4tPmdpX2ZyYW1lKTsKKyAgICBQeV9DTEVBUihnZW4tPmdpX2NvZGUpOworICAgIFB5T2JqZWN0X0dDX0RlbChnZW4pOworfQorCisKK3N0YXRpYyBQeU9iamVjdCAqCitnZW5fc2VuZF9leChQeUdlbk9iamVjdCAqZ2VuLCBQeU9iamVjdCAqYXJnLCBpbnQgZXhjKQoreworICAgIFB5VGhyZWFkU3RhdGUgKnRzdGF0ZSA9IFB5VGhyZWFkU3RhdGVfR0VUKCk7CisgICAgUHlGcmFtZU9iamVjdCAqZiA9IGdlbi0+Z2lfZnJhbWU7CisgICAgUHlPYmplY3QgKnJlc3VsdDsKKworICAgIGlmIChnZW4tPmdpX3J1bm5pbmcpIHsKKyAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1ZhbHVlRXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAgICAiZ2VuZXJhdG9yIGFscmVhZHkgZXhlY3V0aW5nIik7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICBpZiAoZj09TlVMTCB8fCBmLT5mX3N0YWNrdG9wID09IE5VTEwpIHsKKyAgICAgICAgLyogT25seSBzZXQgZXhjZXB0aW9uIGlmIGNhbGxlZCBmcm9tIHNlbmQoKSAqLworICAgICAgICBpZiAoYXJnICYmICFleGMpCisgICAgICAgICAgICBQeUVycl9TZXROb25lKFB5RXhjX1N0b3BJdGVyYXRpb24pOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisKKyAgICBpZiAoZi0+Zl9sYXN0aSA9PSAtMSkgeworICAgICAgICBpZiAoYXJnICYmIGFyZyAhPSBQeV9Ob25lKSB7CisgICAgICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfVHlwZUVycm9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICJjYW4ndCBzZW5kIG5vbi1Ob25lIHZhbHVlIHRvIGEgIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICJqdXN0LXN0YXJ0ZWQgZ2VuZXJhdG9yIik7CisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgfQorICAgIH0gZWxzZSB7CisgICAgICAgIC8qIFB1c2ggYXJnIG9udG8gdGhlIGZyYW1lJ3MgdmFsdWUgc3RhY2sgKi8KKyAgICAgICAgcmVzdWx0ID0gYXJnID8gYXJnIDogUHlfTm9uZTsKKyAgICAgICAgUHlfSU5DUkVGKHJlc3VsdCk7CisgICAgICAgICooZi0+Zl9zdGFja3RvcCsrKSA9IHJlc3VsdDsKKyAgICB9CisKKyAgICAvKiBHZW5lcmF0b3JzIGFsd2F5cyByZXR1cm4gdG8gdGhlaXIgbW9zdCByZWNlbnQgY2FsbGVyLCBub3QKKyAgICAgKiBuZWNlc3NhcmlseSB0aGVpciBjcmVhdG9yLiAqLworICAgIFB5X1hJTkNSRUYodHN0YXRlLT5mcmFtZSk7CisgICAgYXNzZXJ0KGYtPmZfYmFjayA9PSBOVUxMKTsKKyAgICBmLT5mX2JhY2sgPSB0c3RhdGUtPmZyYW1lOworCisgICAgZ2VuLT5naV9ydW5uaW5nID0gMTsKKyAgICByZXN1bHQgPSBQeUV2YWxfRXZhbEZyYW1lRXgoZiwgZXhjKTsKKyAgICBnZW4tPmdpX3J1bm5pbmcgPSAwOworCisgICAgLyogRG9uJ3Qga2VlcCB0aGUgcmVmZXJlbmNlIHRvIGZfYmFjayBhbnkgbG9uZ2VyIHRoYW4gbmVjZXNzYXJ5LiAgSXQKKyAgICAgKiBtYXkga2VlcCBhIGNoYWluIG9mIGZyYW1lcyBhbGl2ZSBvciBpdCBjb3VsZCBjcmVhdGUgYSByZWZlcmVuY2UKKyAgICAgKiBjeWNsZS4gKi8KKyAgICBhc3NlcnQoZi0+Zl9iYWNrID09IHRzdGF0ZS0+ZnJhbWUpOworICAgIFB5X0NMRUFSKGYtPmZfYmFjayk7CisKKyAgICAvKiBJZiB0aGUgZ2VuZXJhdG9yIGp1c3QgcmV0dXJuZWQgKGFzIG9wcG9zZWQgdG8geWllbGRpbmcpLCBzaWduYWwKKyAgICAgKiB0aGF0IHRoZSBnZW5lcmF0b3IgaXMgZXhoYXVzdGVkLiAqLworICAgIGlmIChyZXN1bHQgPT0gUHlfTm9uZSAmJiBmLT5mX3N0YWNrdG9wID09IE5VTEwpIHsKKyAgICAgICAgUHlfREVDUkVGKHJlc3VsdCk7CisgICAgICAgIHJlc3VsdCA9IE5VTEw7CisgICAgICAgIC8qIFNldCBleGNlcHRpb24gaWYgbm90IGNhbGxlZCBieSBnZW5faXRlcm5leHQoKSAqLworICAgICAgICBpZiAoYXJnKQorICAgICAgICAgICAgUHlFcnJfU2V0Tm9uZShQeUV4Y19TdG9wSXRlcmF0aW9uKTsKKyAgICB9CisKKyAgICBpZiAoIXJlc3VsdCB8fCBmLT5mX3N0YWNrdG9wID09IE5VTEwpIHsKKyAgICAgICAgLyogZ2VuZXJhdG9yIGNhbid0IGJlIHJlcnVuLCBzbyByZWxlYXNlIHRoZSBmcmFtZSAqLworICAgICAgICBQeV9ERUNSRUYoZik7CisgICAgICAgIGdlbi0+Z2lfZnJhbWUgPSBOVUxMOworICAgIH0KKworICAgIHJldHVybiByZXN1bHQ7Cit9CisKK1B5RG9jX1NUUlZBUihzZW5kX2RvYywKKyJzZW5kKGFyZykgLT4gc2VuZCAnYXJnJyBpbnRvIGdlbmVyYXRvcixcblwKK3JldHVybiBuZXh0IHlpZWxkZWQgdmFsdWUgb3IgcmFpc2UgU3RvcEl0ZXJhdGlvbi4iKTsKKworc3RhdGljIFB5T2JqZWN0ICoKK2dlbl9zZW5kKFB5R2VuT2JqZWN0ICpnZW4sIFB5T2JqZWN0ICphcmcpCit7CisgICAgcmV0dXJuIGdlbl9zZW5kX2V4KGdlbiwgYXJnLCAwKTsKK30KKworUHlEb2NfU1RSVkFSKGNsb3NlX2RvYywKKyJjbG9zZSgpIC0+IHJhaXNlIEdlbmVyYXRvckV4aXQgaW5zaWRlIGdlbmVyYXRvci4iKTsKKworc3RhdGljIFB5T2JqZWN0ICoKK2dlbl9jbG9zZShQeUdlbk9iamVjdCAqZ2VuLCBQeU9iamVjdCAqYXJncykKK3sKKyAgICBQeU9iamVjdCAqcmV0dmFsOworICAgIFB5RXJyX1NldE5vbmUoUHlFeGNfR2VuZXJhdG9yRXhpdCk7CisgICAgcmV0dmFsID0gZ2VuX3NlbmRfZXgoZ2VuLCBQeV9Ob25lLCAxKTsKKyAgICBpZiAocmV0dmFsKSB7CisgICAgICAgIFB5X0RFQ1JFRihyZXR2YWwpOworICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfUnVudGltZUVycm9yLAorICAgICAgICAgICAgICAgICAgICAgICAgImdlbmVyYXRvciBpZ25vcmVkIEdlbmVyYXRvckV4aXQiKTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIGlmIChQeUVycl9FeGNlcHRpb25NYXRjaGVzKFB5RXhjX1N0b3BJdGVyYXRpb24pCisgICAgICAgIHx8IFB5RXJyX0V4Y2VwdGlvbk1hdGNoZXMoUHlFeGNfR2VuZXJhdG9yRXhpdCkpCisgICAgeworICAgICAgICBQeUVycl9DbGVhcigpOyAgICAgICAgICAvKiBpZ25vcmUgdGhlc2UgZXJyb3JzICovCisgICAgICAgIFB5X0lOQ1JFRihQeV9Ob25lKTsKKyAgICAgICAgcmV0dXJuIFB5X05vbmU7CisgICAgfQorICAgIHJldHVybiBOVUxMOworfQorCitzdGF0aWMgdm9pZAorZ2VuX2RlbChQeU9iamVjdCAqc2VsZikKK3sKKyAgICBQeU9iamVjdCAqcmVzOworICAgIFB5T2JqZWN0ICplcnJvcl90eXBlLCAqZXJyb3JfdmFsdWUsICplcnJvcl90cmFjZWJhY2s7CisgICAgUHlHZW5PYmplY3QgKmdlbiA9IChQeUdlbk9iamVjdCAqKXNlbGY7CisKKyAgICBpZiAoZ2VuLT5naV9mcmFtZSA9PSBOVUxMIHx8IGdlbi0+Z2lfZnJhbWUtPmZfc3RhY2t0b3AgPT0gTlVMTCkKKyAgICAgICAgLyogR2VuZXJhdG9yIGlzbid0IHBhdXNlZCwgc28gbm8gbmVlZCB0byBjbG9zZSAqLworICAgICAgICByZXR1cm47CisKKyAgICAvKiBUZW1wb3JhcmlseSByZXN1cnJlY3QgdGhlIG9iamVjdC4gKi8KKyAgICBhc3NlcnQoc2VsZi0+b2JfcmVmY250ID09IDApOworICAgIHNlbGYtPm9iX3JlZmNudCA9IDE7CisKKyAgICAvKiBTYXZlIHRoZSBjdXJyZW50IGV4Y2VwdGlvbiwgaWYgYW55LiAqLworICAgIFB5RXJyX0ZldGNoKCZlcnJvcl90eXBlLCAmZXJyb3JfdmFsdWUsICZlcnJvcl90cmFjZWJhY2spOworCisgICAgcmVzID0gZ2VuX2Nsb3NlKGdlbiwgTlVMTCk7CisKKyAgICBpZiAocmVzID09IE5VTEwpCisgICAgICAgIFB5RXJyX1dyaXRlVW5yYWlzYWJsZShzZWxmKTsKKyAgICBlbHNlCisgICAgICAgIFB5X0RFQ1JFRihyZXMpOworCisgICAgLyogUmVzdG9yZSB0aGUgc2F2ZWQgZXhjZXB0aW9uLiAqLworICAgIFB5RXJyX1Jlc3RvcmUoZXJyb3JfdHlwZSwgZXJyb3JfdmFsdWUsIGVycm9yX3RyYWNlYmFjayk7CisKKyAgICAvKiBVbmRvIHRoZSB0ZW1wb3JhcnkgcmVzdXJyZWN0aW9uOyBjYW4ndCB1c2UgREVDUkVGIGhlcmUsIGl0IHdvdWxkCisgICAgICogY2F1c2UgYSByZWN1cnNpdmUgY2FsbC4KKyAgICAgKi8KKyAgICBhc3NlcnQoc2VsZi0+b2JfcmVmY250ID4gMCk7CisgICAgaWYgKC0tc2VsZi0+b2JfcmVmY250ID09IDApCisgICAgICAgIHJldHVybjsgLyogdGhpcyBpcyB0aGUgbm9ybWFsIHBhdGggb3V0ICovCisKKyAgICAvKiBjbG9zZSgpIHJlc3VycmVjdGVkIGl0ISAgTWFrZSBpdCBsb29rIGxpa2UgdGhlIG9yaWdpbmFsIFB5X0RFQ1JFRgorICAgICAqIG5ldmVyIGhhcHBlbmVkLgorICAgICAqLworICAgIHsKKyAgICAgICAgUHlfc3NpemVfdCByZWZjbnQgPSBzZWxmLT5vYl9yZWZjbnQ7CisgICAgICAgIF9QeV9OZXdSZWZlcmVuY2Uoc2VsZik7CisgICAgICAgIHNlbGYtPm9iX3JlZmNudCA9IHJlZmNudDsKKyAgICB9CisgICAgYXNzZXJ0KFB5VHlwZV9JU19HQyhzZWxmLT5vYl90eXBlKSAmJgorICAgICAgICAgICBfUHlfQVNfR0Moc2VsZiktPmdjLmdjX3JlZnMgIT0gX1B5R0NfUkVGU19VTlRSQUNLRUQpOworCisgICAgLyogSWYgUHlfUkVGX0RFQlVHLCBfUHlfTmV3UmVmZXJlbmNlIGJ1bXBlZCBfUHlfUmVmVG90YWwsIHNvCisgICAgICogd2UgbmVlZCB0byB1bmRvIHRoYXQuICovCisgICAgX1B5X0RFQ19SRUZUT1RBTDsKKyAgICAvKiBJZiBQeV9UUkFDRV9SRUZTLCBfUHlfTmV3UmVmZXJlbmNlIHJlLWFkZGVkIHNlbGYgdG8gdGhlIG9iamVjdAorICAgICAqIGNoYWluLCBzbyBubyBtb3JlIHRvIGRvIHRoZXJlLgorICAgICAqIElmIENPVU5UX0FMTE9DUywgdGhlIG9yaWdpbmFsIGRlY3JlZiBidW1wZWQgdHBfZnJlZXMsIGFuZAorICAgICAqIF9QeV9OZXdSZWZlcmVuY2UgYnVtcGVkIHRwX2FsbG9jczogIGJvdGggb2YgdGhvc2UgbmVlZCB0byBiZQorICAgICAqIHVuZG9uZS4KKyAgICAgKi8KKyNpZmRlZiBDT1VOVF9BTExPQ1MKKyAgICAtLXNlbGYtPm9iX3R5cGUtPnRwX2ZyZWVzOworICAgIC0tc2VsZi0+b2JfdHlwZS0+dHBfYWxsb2NzOworI2VuZGlmCit9CisKKworCitQeURvY19TVFJWQVIodGhyb3dfZG9jLAorInRocm93KHR5cFssdmFsWyx0Yl1dKSAtPiByYWlzZSBleGNlcHRpb24gaW4gZ2VuZXJhdG9yLFxuXAorcmV0dXJuIG5leHQgeWllbGRlZCB2YWx1ZSBvciByYWlzZSBTdG9wSXRlcmF0aW9uLiIpOworCitzdGF0aWMgUHlPYmplY3QgKgorZ2VuX3Rocm93KFB5R2VuT2JqZWN0ICpnZW4sIFB5T2JqZWN0ICphcmdzKQoreworICAgIFB5T2JqZWN0ICp0eXA7CisgICAgUHlPYmplY3QgKnRiID0gTlVMTDsKKyAgICBQeU9iamVjdCAqdmFsID0gTlVMTDsKKworICAgIGlmICghUHlBcmdfVW5wYWNrVHVwbGUoYXJncywgInRocm93IiwgMSwgMywgJnR5cCwgJnZhbCwgJnRiKSkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisKKyAgICAvKiBGaXJzdCwgY2hlY2sgdGhlIHRyYWNlYmFjayBhcmd1bWVudCwgcmVwbGFjaW5nIE5vbmUgd2l0aAorICAgICAgIE5VTEwuICovCisgICAgaWYgKHRiID09IFB5X05vbmUpCisgICAgICAgIHRiID0gTlVMTDsKKyAgICBlbHNlIGlmICh0YiAhPSBOVUxMICYmICFQeVRyYWNlQmFja19DaGVjayh0YikpIHsKKyAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1R5cGVFcnJvciwKKyAgICAgICAgICAgICJ0aHJvdygpIHRoaXJkIGFyZ3VtZW50IG11c3QgYmUgYSB0cmFjZWJhY2sgb2JqZWN0Iik7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKworICAgIFB5X0lOQ1JFRih0eXApOworICAgIFB5X1hJTkNSRUYodmFsKTsKKyAgICBQeV9YSU5DUkVGKHRiKTsKKworICAgIGlmIChQeUV4Y2VwdGlvbkNsYXNzX0NoZWNrKHR5cCkpIHsKKyAgICAgICAgUHlFcnJfTm9ybWFsaXplRXhjZXB0aW9uKCZ0eXAsICZ2YWwsICZ0Yik7CisgICAgfQorCisgICAgZWxzZSBpZiAoUHlFeGNlcHRpb25JbnN0YW5jZV9DaGVjayh0eXApKSB7CisgICAgICAgIC8qIFJhaXNpbmcgYW4gaW5zdGFuY2UuICBUaGUgdmFsdWUgc2hvdWxkIGJlIGEgZHVtbXkuICovCisgICAgICAgIGlmICh2YWwgJiYgdmFsICE9IFB5X05vbmUpIHsKKyAgICAgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19UeXBlRXJyb3IsCisgICAgICAgICAgICAgICJpbnN0YW5jZSBleGNlcHRpb24gbWF5IG5vdCBoYXZlIGEgc2VwYXJhdGUgdmFsdWUiKTsKKyAgICAgICAgICAgIGdvdG8gZmFpbGVkX3Rocm93OworICAgICAgICB9CisgICAgICAgIGVsc2UgeworICAgICAgICAgICAgLyogTm9ybWFsaXplIHRvIHJhaXNlIDxjbGFzcz4sIDxpbnN0YW5jZT4gKi8KKyAgICAgICAgICAgIFB5X1hERUNSRUYodmFsKTsKKyAgICAgICAgICAgIHZhbCA9IHR5cDsKKyAgICAgICAgICAgIHR5cCA9IFB5RXhjZXB0aW9uSW5zdGFuY2VfQ2xhc3ModHlwKTsKKyAgICAgICAgICAgIFB5X0lOQ1JFRih0eXApOworICAgICAgICB9CisgICAgfQorICAgIGVsc2UgeworICAgICAgICAvKiBOb3Qgc29tZXRoaW5nIHlvdSBjYW4gcmFpc2UuICB0aHJvdygpIGZhaWxzLiAqLworICAgICAgICBQeUVycl9Gb3JtYXQoUHlFeGNfVHlwZUVycm9yLAorICAgICAgICAgICAgICAgICAgICAgImV4Y2VwdGlvbnMgbXVzdCBiZSBjbGFzc2VzLCBvciBpbnN0YW5jZXMsIG5vdCAlcyIsCisgICAgICAgICAgICAgICAgICAgICB0eXAtPm9iX3R5cGUtPnRwX25hbWUpOworICAgICAgICAgICAgZ290byBmYWlsZWRfdGhyb3c7CisgICAgfQorCisgICAgUHlFcnJfUmVzdG9yZSh0eXAsIHZhbCwgdGIpOworICAgIHJldHVybiBnZW5fc2VuZF9leChnZW4sIFB5X05vbmUsIDEpOworCitmYWlsZWRfdGhyb3c6CisgICAgLyogRGlkbid0IHVzZSBvdXIgYXJndW1lbnRzLCBzbyByZXN0b3JlIHRoZWlyIG9yaWdpbmFsIHJlZmNvdW50cyAqLworICAgIFB5X0RFQ1JFRih0eXApOworICAgIFB5X1hERUNSRUYodmFsKTsKKyAgICBQeV9YREVDUkVGKHRiKTsKKyAgICByZXR1cm4gTlVMTDsKK30KKworCitzdGF0aWMgUHlPYmplY3QgKgorZ2VuX2l0ZXJuZXh0KFB5R2VuT2JqZWN0ICpnZW4pCit7CisgICAgcmV0dXJuIGdlbl9zZW5kX2V4KGdlbiwgTlVMTCwgMCk7Cit9CisKKworc3RhdGljIFB5T2JqZWN0ICoKK2dlbl9yZXByKFB5R2VuT2JqZWN0ICpnZW4pCit7CisgICAgY2hhciAqY29kZV9uYW1lOworICAgIGNvZGVfbmFtZSA9IFB5U3RyaW5nX0FzU3RyaW5nKCgoUHlDb2RlT2JqZWN0ICopZ2VuLT5naV9jb2RlKS0+Y29fbmFtZSk7CisgICAgaWYgKGNvZGVfbmFtZSA9PSBOVUxMKQorICAgICAgICByZXR1cm4gTlVMTDsKKyAgICByZXR1cm4gUHlTdHJpbmdfRnJvbUZvcm1hdCgiPGdlbmVyYXRvciBvYmplY3QgJS4yMDBzIGF0ICVwPiIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29kZV9uYW1lLCBnZW4pOworfQorCisKK3N0YXRpYyBQeU9iamVjdCAqCitnZW5fZ2V0X25hbWUoUHlHZW5PYmplY3QgKmdlbikKK3sKKyAgICBQeU9iamVjdCAqbmFtZSA9ICgoUHlDb2RlT2JqZWN0ICopZ2VuLT5naV9jb2RlKS0+Y29fbmFtZTsKKyAgICBQeV9JTkNSRUYobmFtZSk7CisgICAgcmV0dXJuIG5hbWU7Cit9CisKKworUHlEb2NfU1RSVkFSKGdlbl9fbmFtZV9fZG9jX18sCisiUmV0dXJuIHRoZSBuYW1lIG9mIHRoZSBnZW5lcmF0b3IncyBhc3NvY2lhdGVkIGNvZGUgb2JqZWN0LiIpOworCitzdGF0aWMgUHlHZXRTZXREZWYgZ2VuX2dldHNldGxpc3RbXSA9IHsKKyAgICB7Il9fbmFtZV9fIiwgKGdldHRlcilnZW5fZ2V0X25hbWUsIE5VTEwsIGdlbl9fbmFtZV9fZG9jX199LAorICAgIHtOVUxMfQorfTsKKworCitzdGF0aWMgUHlNZW1iZXJEZWYgZ2VuX21lbWJlcmxpc3RbXSA9IHsKKyAgICB7ImdpX2ZyYW1lIiwgICAgICAgIFRfT0JKRUNULCBvZmZzZXRvZihQeUdlbk9iamVjdCwgZ2lfZnJhbWUpLCAgICAgIFJPfSwKKyAgICB7ImdpX3J1bm5pbmciLCAgICAgIFRfSU5ULCAgICBvZmZzZXRvZihQeUdlbk9iamVjdCwgZ2lfcnVubmluZyksICAgIFJPfSwKKyAgICB7ImdpX2NvZGUiLCAgICAgVF9PQkpFQ1QsIG9mZnNldG9mKFB5R2VuT2JqZWN0LCBnaV9jb2RlKSwgIFJPfSwKKyAgICB7TlVMTH0gICAgICAvKiBTZW50aW5lbCAqLworfTsKKworc3RhdGljIFB5TWV0aG9kRGVmIGdlbl9tZXRob2RzW10gPSB7CisgICAgeyJzZW5kIiwoUHlDRnVuY3Rpb24pZ2VuX3NlbmQsIE1FVEhfTywgc2VuZF9kb2N9LAorICAgIHsidGhyb3ciLChQeUNGdW5jdGlvbilnZW5fdGhyb3csIE1FVEhfVkFSQVJHUywgdGhyb3dfZG9jfSwKKyAgICB7ImNsb3NlIiwoUHlDRnVuY3Rpb24pZ2VuX2Nsb3NlLCBNRVRIX05PQVJHUywgY2xvc2VfZG9jfSwKKyAgICB7TlVMTCwgTlVMTH0gICAgICAgIC8qIFNlbnRpbmVsICovCit9OworCitQeVR5cGVPYmplY3QgUHlHZW5fVHlwZSA9IHsKKyAgICBQeVZhck9iamVjdF9IRUFEX0lOSVQoJlB5VHlwZV9UeXBlLCAwKQorICAgICJnZW5lcmF0b3IiLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfbmFtZSAqLworICAgIHNpemVvZihQeUdlbk9iamVjdCksICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfYmFzaWNzaXplICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9pdGVtc2l6ZSAqLworICAgIC8qIG1ldGhvZHMgKi8KKyAgICAoZGVzdHJ1Y3RvcilnZW5fZGVhbGxvYywgICAgICAgICAgICAgICAgICAgIC8qIHRwX2RlYWxsb2MgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3ByaW50ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9nZXRhdHRyICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9zZXRhdHRyICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9jb21wYXJlICovCisgICAgKHJlcHJmdW5jKWdlbl9yZXByLCAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9yZXByICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9hc19udW1iZXIgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2FzX3NlcXVlbmNlICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9hc19tYXBwaW5nICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9oYXNoICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9jYWxsICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9zdHIgKi8KKyAgICBQeU9iamVjdF9HZW5lcmljR2V0QXR0ciwgICAgICAgICAgICAgICAgICAgIC8qIHRwX2dldGF0dHJvICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9zZXRhdHRybyAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfYXNfYnVmZmVyICovCisgICAgUHlfVFBGTEFHU19ERUZBVUxUIHwgUHlfVFBGTEFHU19IQVZFX0dDLC8qIHRwX2ZsYWdzICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9kb2MgKi8KKyAgICAodHJhdmVyc2Vwcm9jKWdlbl90cmF2ZXJzZSwgICAgICAgICAgICAgICAgIC8qIHRwX3RyYXZlcnNlICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9jbGVhciAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfcmljaGNvbXBhcmUgKi8KKyAgICBvZmZzZXRvZihQeUdlbk9iamVjdCwgZ2lfd2Vha3JlZmxpc3QpLCAgICAgIC8qIHRwX3dlYWtsaXN0b2Zmc2V0ICovCisgICAgUHlPYmplY3RfU2VsZkl0ZXIsICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9pdGVyICovCisgICAgKGl0ZXJuZXh0ZnVuYylnZW5faXRlcm5leHQsICAgICAgICAgICAgICAgICAvKiB0cF9pdGVybmV4dCAqLworICAgIGdlbl9tZXRob2RzLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfbWV0aG9kcyAqLworICAgIGdlbl9tZW1iZXJsaXN0LCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfbWVtYmVycyAqLworICAgIGdlbl9nZXRzZXRsaXN0LCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZ2V0c2V0ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9iYXNlICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9kaWN0ICovCisKKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2Rlc2NyX2dldCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZGVzY3Jfc2V0ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9kaWN0b2Zmc2V0ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9pbml0ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9hbGxvYyAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfbmV3ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9mcmVlICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9pc19nYyAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfYmFzZXMgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX21ybyAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfY2FjaGUgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3N1YmNsYXNzZXMgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3dlYWtsaXN0ICovCisgICAgZ2VuX2RlbCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9kZWwgKi8KK307CisKK1B5T2JqZWN0ICoKK1B5R2VuX05ldyhQeUZyYW1lT2JqZWN0ICpmKQoreworICAgIFB5R2VuT2JqZWN0ICpnZW4gPSBQeU9iamVjdF9HQ19OZXcoUHlHZW5PYmplY3QsICZQeUdlbl9UeXBlKTsKKyAgICBpZiAoZ2VuID09IE5VTEwpIHsKKyAgICAgICAgUHlfREVDUkVGKGYpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgZ2VuLT5naV9mcmFtZSA9IGY7CisgICAgUHlfSU5DUkVGKGYtPmZfY29kZSk7CisgICAgZ2VuLT5naV9jb2RlID0gKFB5T2JqZWN0ICopKGYtPmZfY29kZSk7CisgICAgZ2VuLT5naV9ydW5uaW5nID0gMDsKKyAgICBnZW4tPmdpX3dlYWtyZWZsaXN0ID0gTlVMTDsKKyAgICBfUHlPYmplY3RfR0NfVFJBQ0soZ2VuKTsKKyAgICByZXR1cm4gKFB5T2JqZWN0ICopZ2VuOworfQorCitpbnQKK1B5R2VuX05lZWRzRmluYWxpemluZyhQeUdlbk9iamVjdCAqZ2VuKQoreworICAgIGludCBpOworICAgIFB5RnJhbWVPYmplY3QgKmYgPSBnZW4tPmdpX2ZyYW1lOworCisgICAgaWYgKGYgPT0gTlVMTCB8fCBmLT5mX3N0YWNrdG9wID09IE5VTEwgfHwgZi0+Zl9pYmxvY2sgPD0gMCkKKyAgICAgICAgcmV0dXJuIDA7IC8qIG5vIGZyYW1lIG9yIGVtcHR5IGJsb2Nrc3RhY2sgPT0gbm8gZmluYWxpemF0aW9uICovCisKKyAgICAvKiBBbnkgYmxvY2sgdHlwZSBiZXNpZGVzIGEgbG9vcCByZXF1aXJlcyBjbGVhbnVwLiAqLworICAgIGkgPSBmLT5mX2libG9jazsKKyAgICB3aGlsZSAoLS1pID49IDApIHsKKyAgICAgICAgaWYgKGYtPmZfYmxvY2tzdGFja1tpXS5iX3R5cGUgIT0gU0VUVVBfTE9PUCkKKyAgICAgICAgICAgIHJldHVybiAxOworICAgIH0KKworICAgIC8qIE5vIGJsb2NrcyBleGNlcHQgbG9vcHMsIGl0J3Mgc2FmZSB0byBza2lwIGZpbmFsaXphdGlvbi4gKi8KKyAgICByZXR1cm4gMDsKK30KZGlmZiAtLWdpdCBhL1B5dGhvbi0yLjcuNS9PYmplY3RzL2ludG9iamVjdC5jIGIvUHl0aG9uLTIuNy41L09iamVjdHMvaW50b2JqZWN0LmMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjgxODJmOQotLS0gL2Rldi9udWxsCisrKyBiL1B5dGhvbi0yLjcuNS9PYmplY3RzL2ludG9iamVjdC5jCkBAIC0wLDAgKzEsMTU4MSBAQAorCisvKiBJbnRlZ2VyIG9iamVjdCBpbXBsZW1lbnRhdGlvbiAqLworCisjaW5jbHVkZSAiUHl0aG9uLmgiCisjaW5jbHVkZSA8Y3R5cGUuaD4KKyNpbmNsdWRlIDxmbG9hdC5oPgorCitzdGF0aWMgUHlPYmplY3QgKmludF9pbnQoUHlJbnRPYmplY3QgKnYpOworCitsb25nCitQeUludF9HZXRNYXgodm9pZCkKK3sKKyAgICByZXR1cm4gTE9OR19NQVg7ICAgICAgICAgICAgLyogVG8gaW5pdGlhbGl6ZSBzeXMubWF4aW50ICovCit9CisKKy8qIEludGVnZXJzIGFyZSBxdWl0ZSBub3JtYWwgb2JqZWN0cywgdG8gbWFrZSBvYmplY3QgaGFuZGxpbmcgdW5pZm9ybS4KKyAgIChVc2luZyBvZGQgcG9pbnRlcnMgdG8gcmVwcmVzZW50IGludGVnZXJzIHdvdWxkIHNhdmUgbXVjaCBzcGFjZQorICAgYnV0IHJlcXVpcmUgZXh0cmEgY2hlY2tzIGZvciB0aGlzIHNwZWNpYWwgY2FzZSB0aHJvdWdob3V0IHRoZSBjb2RlLikKKyAgIFNpbmNlIGEgdHlwaWNhbCBQeXRob24gcHJvZ3JhbSBzcGVuZHMgbXVjaCBvZiBpdHMgdGltZSBhbGxvY2F0aW5nCisgICBhbmQgZGVhbGxvY2F0aW5nIGludGVnZXJzLCB0aGVzZSBvcGVyYXRpb25zIHNob3VsZCBiZSB2ZXJ5IGZhc3QuCisgICBUaGVyZWZvcmUgd2UgdXNlIGEgZGVkaWNhdGVkIGFsbG9jYXRpb24gc2NoZW1lIHdpdGggYSBtdWNoIGxvd2VyCisgICBvdmVyaGVhZCAoaW4gc3BhY2UgYW5kIHRpbWUpIHRoYW4gc3RyYWlnaHQgbWFsbG9jKCk6IGEgc2ltcGxlCisgICBkZWRpY2F0ZWQgZnJlZSBsaXN0LCBmaWxsZWQgd2hlbiBuZWNlc3Nhcnkgd2l0aCBtZW1vcnkgZnJvbSBtYWxsb2MoKS4KKworICAgYmxvY2tfbGlzdCBpcyBhIHNpbmdseS1saW5rZWQgbGlzdCBvZiBhbGwgUHlJbnRCbG9ja3MgZXZlciBhbGxvY2F0ZWQsCisgICBsaW5rZWQgdmlhIHRoZWlyIG5leHQgbWVtYmVycy4gIFB5SW50QmxvY2tzIGFyZSBuZXZlciByZXR1cm5lZCB0byB0aGUKKyAgIHN5c3RlbSBiZWZvcmUgc2h1dGRvd24gKFB5SW50X0ZpbmkpLgorCisgICBmcmVlX2xpc3QgaXMgYSBzaW5nbHktbGlua2VkIGxpc3Qgb2YgYXZhaWxhYmxlIFB5SW50T2JqZWN0cywgbGlua2VkCisgICB2aWEgYWJ1c2Ugb2YgdGhlaXIgb2JfdHlwZSBtZW1iZXJzLgorKi8KKworI2RlZmluZSBCTE9DS19TSVpFICAgICAgMTAwMCAgICAvKiAxSyBsZXNzIHR5cGljYWwgbWFsbG9jIG92ZXJoZWFkICovCisjZGVmaW5lIEJIRUFEX1NJWkUgICAgICA4ICAgICAgIC8qIEVub3VnaCBmb3IgYSA2NC1iaXQgcG9pbnRlciAqLworI2RlZmluZSBOX0lOVE9CSkVDVFMgICAgKChCTE9DS19TSVpFIC0gQkhFQURfU0laRSkgLyBzaXplb2YoUHlJbnRPYmplY3QpKQorCitzdHJ1Y3QgX2ludGJsb2NrIHsKKyAgICBzdHJ1Y3QgX2ludGJsb2NrICpuZXh0OworICAgIFB5SW50T2JqZWN0IG9iamVjdHNbTl9JTlRPQkpFQ1RTXTsKK307CisKK3R5cGVkZWYgc3RydWN0IF9pbnRibG9jayBQeUludEJsb2NrOworCitzdGF0aWMgUHlJbnRCbG9jayAqYmxvY2tfbGlzdCA9IE5VTEw7CitzdGF0aWMgUHlJbnRPYmplY3QgKmZyZWVfbGlzdCA9IE5VTEw7CisKK3N0YXRpYyBQeUludE9iamVjdCAqCitmaWxsX2ZyZWVfbGlzdCh2b2lkKQoreworICAgIFB5SW50T2JqZWN0ICpwLCAqcTsKKyAgICAvKiBQeXRob24ncyBvYmplY3QgYWxsb2NhdG9yIGlzbid0IGFwcHJvcHJpYXRlIGZvciBsYXJnZSBibG9ja3MuICovCisgICAgcCA9IChQeUludE9iamVjdCAqKSBQeU1lbV9NQUxMT0Moc2l6ZW9mKFB5SW50QmxvY2spKTsKKyAgICBpZiAocCA9PSBOVUxMKQorICAgICAgICByZXR1cm4gKFB5SW50T2JqZWN0ICopIFB5RXJyX05vTWVtb3J5KCk7CisgICAgKChQeUludEJsb2NrICopcCktPm5leHQgPSBibG9ja19saXN0OworICAgIGJsb2NrX2xpc3QgPSAoUHlJbnRCbG9jayAqKXA7CisgICAgLyogTGluayB0aGUgaW50IG9iamVjdHMgdG9nZXRoZXIsIGZyb20gcmVhciB0byBmcm9udCwgdGhlbiByZXR1cm4KKyAgICAgICB0aGUgYWRkcmVzcyBvZiB0aGUgbGFzdCBpbnQgb2JqZWN0IGluIHRoZSBibG9jay4gKi8KKyAgICBwID0gJigoUHlJbnRCbG9jayAqKXApLT5vYmplY3RzWzBdOworICAgIHEgPSBwICsgTl9JTlRPQkpFQ1RTOworICAgIHdoaWxlICgtLXEgPiBwKQorICAgICAgICBQeV9UWVBFKHEpID0gKHN0cnVjdCBfdHlwZW9iamVjdCAqKShxLTEpOworICAgIFB5X1RZUEUocSkgPSBOVUxMOworICAgIHJldHVybiBwICsgTl9JTlRPQkpFQ1RTIC0gMTsKK30KKworI2lmbmRlZiBOU01BTExQT1NJTlRTCisjZGVmaW5lIE5TTUFMTFBPU0lOVFMgICAgICAgICAgIDI1NworI2VuZGlmCisjaWZuZGVmIE5TTUFMTE5FR0lOVFMKKyNkZWZpbmUgTlNNQUxMTkVHSU5UUyAgICAgICAgICAgNQorI2VuZGlmCisjaWYgTlNNQUxMTkVHSU5UUyArIE5TTUFMTFBPU0lOVFMgPiAwCisvKiBSZWZlcmVuY2VzIHRvIHNtYWxsIGludGVnZXJzIGFyZSBzYXZlZCBpbiB0aGlzIGFycmF5IHNvIHRoYXQgdGhleQorICAgY2FuIGJlIHNoYXJlZC4KKyAgIFRoZSBpbnRlZ2VycyB0aGF0IGFyZSBzYXZlZCBhcmUgdGhvc2UgaW4gdGhlIHJhbmdlCisgICAtTlNNQUxMTkVHSU5UUyAoaW5jbHVzaXZlKSB0byBOU01BTExQT1NJTlRTIChub3QgaW5jbHVzaXZlKS4KKyovCitzdGF0aWMgUHlJbnRPYmplY3QgKnNtYWxsX2ludHNbTlNNQUxMTkVHSU5UUyArIE5TTUFMTFBPU0lOVFNdOworI2VuZGlmCisjaWZkZWYgQ09VTlRfQUxMT0NTCitQeV9zc2l6ZV90IHF1aWNrX2ludF9hbGxvY3M7CitQeV9zc2l6ZV90IHF1aWNrX25lZ19pbnRfYWxsb2NzOworI2VuZGlmCisKK1B5T2JqZWN0ICoKK1B5SW50X0Zyb21Mb25nKGxvbmcgaXZhbCkKK3sKKyAgICByZWdpc3RlciBQeUludE9iamVjdCAqdjsKKyNpZiBOU01BTExORUdJTlRTICsgTlNNQUxMUE9TSU5UUyA+IDAKKyAgICBpZiAoLU5TTUFMTE5FR0lOVFMgPD0gaXZhbCAmJiBpdmFsIDwgTlNNQUxMUE9TSU5UUykgeworICAgICAgICB2ID0gc21hbGxfaW50c1tpdmFsICsgTlNNQUxMTkVHSU5UU107CisgICAgICAgIFB5X0lOQ1JFRih2KTsKKyNpZmRlZiBDT1VOVF9BTExPQ1MKKyAgICAgICAgaWYgKGl2YWwgPj0gMCkKKyAgICAgICAgICAgIHF1aWNrX2ludF9hbGxvY3MrKzsKKyAgICAgICAgZWxzZQorICAgICAgICAgICAgcXVpY2tfbmVnX2ludF9hbGxvY3MrKzsKKyNlbmRpZgorICAgICAgICByZXR1cm4gKFB5T2JqZWN0ICopIHY7CisgICAgfQorI2VuZGlmCisgICAgaWYgKGZyZWVfbGlzdCA9PSBOVUxMKSB7CisgICAgICAgIGlmICgoZnJlZV9saXN0ID0gZmlsbF9mcmVlX2xpc3QoKSkgPT0gTlVMTCkKKyAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICAvKiBJbmxpbmUgUHlPYmplY3RfTmV3ICovCisgICAgdiA9IGZyZWVfbGlzdDsKKyAgICBmcmVlX2xpc3QgPSAoUHlJbnRPYmplY3QgKilQeV9UWVBFKHYpOworICAgIFB5T2JqZWN0X0lOSVQodiwgJlB5SW50X1R5cGUpOworICAgIHYtPm9iX2l2YWwgPSBpdmFsOworICAgIHJldHVybiAoUHlPYmplY3QgKikgdjsKK30KKworUHlPYmplY3QgKgorUHlJbnRfRnJvbVNpemVfdChzaXplX3QgaXZhbCkKK3sKKyAgICBpZiAoaXZhbCA8PSBMT05HX01BWCkKKyAgICAgICAgcmV0dXJuIFB5SW50X0Zyb21Mb25nKChsb25nKWl2YWwpOworICAgIHJldHVybiBfUHlMb25nX0Zyb21TaXplX3QoaXZhbCk7Cit9CisKK1B5T2JqZWN0ICoKK1B5SW50X0Zyb21Tc2l6ZV90KFB5X3NzaXplX3QgaXZhbCkKK3sKKyAgICBpZiAoaXZhbCA+PSBMT05HX01JTiAmJiBpdmFsIDw9IExPTkdfTUFYKQorICAgICAgICByZXR1cm4gUHlJbnRfRnJvbUxvbmcoKGxvbmcpaXZhbCk7CisgICAgcmV0dXJuIF9QeUxvbmdfRnJvbVNzaXplX3QoaXZhbCk7Cit9CisKK3N0YXRpYyB2b2lkCitpbnRfZGVhbGxvYyhQeUludE9iamVjdCAqdikKK3sKKyAgICBpZiAoUHlJbnRfQ2hlY2tFeGFjdCh2KSkgeworICAgICAgICBQeV9UWVBFKHYpID0gKHN0cnVjdCBfdHlwZW9iamVjdCAqKWZyZWVfbGlzdDsKKyAgICAgICAgZnJlZV9saXN0ID0gdjsKKyAgICB9CisgICAgZWxzZQorICAgICAgICBQeV9UWVBFKHYpLT50cF9mcmVlKChQeU9iamVjdCAqKXYpOworfQorCitzdGF0aWMgdm9pZAoraW50X2ZyZWUoUHlJbnRPYmplY3QgKnYpCit7CisgICAgUHlfVFlQRSh2KSA9IChzdHJ1Y3QgX3R5cGVvYmplY3QgKilmcmVlX2xpc3Q7CisgICAgZnJlZV9saXN0ID0gdjsKK30KKworbG9uZworUHlJbnRfQXNMb25nKHJlZ2lzdGVyIFB5T2JqZWN0ICpvcCkKK3sKKyAgICBQeU51bWJlck1ldGhvZHMgKm5iOworICAgIFB5SW50T2JqZWN0ICppbzsKKyAgICBsb25nIHZhbDsKKworICAgIGlmIChvcCAmJiBQeUludF9DaGVjayhvcCkpCisgICAgICAgIHJldHVybiBQeUludF9BU19MT05HKChQeUludE9iamVjdCopIG9wKTsKKworICAgIGlmIChvcCA9PSBOVUxMIHx8IChuYiA9IFB5X1RZUEUob3ApLT50cF9hc19udW1iZXIpID09IE5VTEwgfHwKKyAgICAgICAgbmItPm5iX2ludCA9PSBOVUxMKSB7CisgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19UeXBlRXJyb3IsICJhbiBpbnRlZ2VyIGlzIHJlcXVpcmVkIik7CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisKKyAgICBpbyA9IChQeUludE9iamVjdCopICgqbmItPm5iX2ludCkgKG9wKTsKKyAgICBpZiAoaW8gPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIC0xOworICAgIGlmICghUHlJbnRfQ2hlY2soaW8pKSB7CisgICAgICAgIGlmIChQeUxvbmdfQ2hlY2soaW8pKSB7CisgICAgICAgICAgICAvKiBnb3QgYSBsb25nPyA9PiByZXRyeSBpbnQgY29udmVyc2lvbiAqLworICAgICAgICAgICAgdmFsID0gUHlMb25nX0FzTG9uZygoUHlPYmplY3QgKilpbyk7CisgICAgICAgICAgICBQeV9ERUNSRUYoaW8pOworICAgICAgICAgICAgaWYgKCh2YWwgPT0gLTEpICYmIFB5RXJyX09jY3VycmVkKCkpCisgICAgICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICAgICAgcmV0dXJuIHZhbDsKKyAgICAgICAgfQorICAgICAgICBlbHNlCisgICAgICAgIHsKKyAgICAgICAgICAgIFB5X0RFQ1JFRihpbyk7CisgICAgICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfVHlwZUVycm9yLAorICAgICAgICAgICAgICAgICAgICAgICAgIl9faW50X18gbWV0aG9kIHNob3VsZCByZXR1cm4gYW4gaW50ZWdlciIpOworICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICB9CisgICAgfQorCisgICAgdmFsID0gUHlJbnRfQVNfTE9ORyhpbyk7CisgICAgUHlfREVDUkVGKGlvKTsKKworICAgIHJldHVybiB2YWw7Cit9CisKK2ludAorX1B5SW50X0FzSW50KFB5T2JqZWN0ICpvYmopCit7CisgICAgbG9uZyByZXN1bHQgPSBQeUludF9Bc0xvbmcob2JqKTsKKyAgICBpZiAocmVzdWx0ID09IC0xICYmIFB5RXJyX09jY3VycmVkKCkpCisgICAgICAgIHJldHVybiAtMTsKKyAgICBpZiAocmVzdWx0ID4gSU5UX01BWCB8fCByZXN1bHQgPCBJTlRfTUlOKSB7CisgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19PdmVyZmxvd0Vycm9yLAorICAgICAgICAgICAgICAgICAgICAgICAgIlB5dGhvbiBpbnQgdG9vIGxhcmdlIHRvIGNvbnZlcnQgdG8gQyBpbnQiKTsKKyAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKyAgICByZXR1cm4gKGludClyZXN1bHQ7Cit9CisKK1B5X3NzaXplX3QKK1B5SW50X0FzU3NpemVfdChyZWdpc3RlciBQeU9iamVjdCAqb3ApCit7CisjaWYgU0laRU9GX1NJWkVfVCAhPSBTSVpFT0ZfTE9ORworICAgIFB5TnVtYmVyTWV0aG9kcyAqbmI7CisgICAgUHlJbnRPYmplY3QgKmlvOworICAgIFB5X3NzaXplX3QgdmFsOworI2VuZGlmCisKKyAgICBpZiAob3AgPT0gTlVMTCkgeworICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfVHlwZUVycm9yLCAiYW4gaW50ZWdlciBpcyByZXF1aXJlZCIpOworICAgICAgICByZXR1cm4gLTE7CisgICAgfQorCisgICAgaWYgKFB5SW50X0NoZWNrKG9wKSkKKyAgICAgICAgcmV0dXJuIFB5SW50X0FTX0xPTkcoKFB5SW50T2JqZWN0Kikgb3ApOworICAgIGlmIChQeUxvbmdfQ2hlY2sob3ApKQorICAgICAgICByZXR1cm4gX1B5TG9uZ19Bc1NzaXplX3Qob3ApOworI2lmIFNJWkVPRl9TSVpFX1QgPT0gU0laRU9GX0xPTkcKKyAgICByZXR1cm4gUHlJbnRfQXNMb25nKG9wKTsKKyNlbHNlCisKKyAgICBpZiAoKG5iID0gUHlfVFlQRShvcCktPnRwX2FzX251bWJlcikgPT0gTlVMTCB8fAorICAgICAgICAobmItPm5iX2ludCA9PSBOVUxMICYmIG5iLT5uYl9sb25nID09IDApKSB7CisgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19UeXBlRXJyb3IsICJhbiBpbnRlZ2VyIGlzIHJlcXVpcmVkIik7CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisKKyAgICBpZiAobmItPm5iX2xvbmcgIT0gMCkKKyAgICAgICAgaW8gPSAoUHlJbnRPYmplY3QqKSAoKm5iLT5uYl9sb25nKSAob3ApOworICAgIGVsc2UKKyAgICAgICAgaW8gPSAoUHlJbnRPYmplY3QqKSAoKm5iLT5uYl9pbnQpIChvcCk7CisgICAgaWYgKGlvID09IE5VTEwpCisgICAgICAgIHJldHVybiAtMTsKKyAgICBpZiAoIVB5SW50X0NoZWNrKGlvKSkgeworICAgICAgICBpZiAoUHlMb25nX0NoZWNrKGlvKSkgeworICAgICAgICAgICAgLyogZ290IGEgbG9uZz8gPT4gcmV0cnkgaW50IGNvbnZlcnNpb24gKi8KKyAgICAgICAgICAgIHZhbCA9IF9QeUxvbmdfQXNTc2l6ZV90KChQeU9iamVjdCAqKWlvKTsKKyAgICAgICAgICAgIFB5X0RFQ1JFRihpbyk7CisgICAgICAgICAgICBpZiAoKHZhbCA9PSAtMSkgJiYgUHlFcnJfT2NjdXJyZWQoKSkKKyAgICAgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgICAgICByZXR1cm4gdmFsOworICAgICAgICB9CisgICAgICAgIGVsc2UKKyAgICAgICAgeworICAgICAgICAgICAgUHlfREVDUkVGKGlvKTsKKyAgICAgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19UeXBlRXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAgICAiX19pbnRfXyBtZXRob2Qgc2hvdWxkIHJldHVybiBhbiBpbnRlZ2VyIik7CisgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgIH0KKyAgICB9CisKKyAgICB2YWwgPSBQeUludF9BU19MT05HKGlvKTsKKyAgICBQeV9ERUNSRUYoaW8pOworCisgICAgcmV0dXJuIHZhbDsKKyNlbmRpZgorfQorCit1bnNpZ25lZCBsb25nCitQeUludF9Bc1Vuc2lnbmVkTG9uZ01hc2socmVnaXN0ZXIgUHlPYmplY3QgKm9wKQoreworICAgIFB5TnVtYmVyTWV0aG9kcyAqbmI7CisgICAgUHlJbnRPYmplY3QgKmlvOworICAgIHVuc2lnbmVkIGxvbmcgdmFsOworCisgICAgaWYgKG9wICYmIFB5SW50X0NoZWNrKG9wKSkKKyAgICAgICAgcmV0dXJuIFB5SW50X0FTX0xPTkcoKFB5SW50T2JqZWN0Kikgb3ApOworICAgIGlmIChvcCAmJiBQeUxvbmdfQ2hlY2sob3ApKQorICAgICAgICByZXR1cm4gUHlMb25nX0FzVW5zaWduZWRMb25nTWFzayhvcCk7CisKKyAgICBpZiAob3AgPT0gTlVMTCB8fCAobmIgPSBQeV9UWVBFKG9wKS0+dHBfYXNfbnVtYmVyKSA9PSBOVUxMIHx8CisgICAgICAgIG5iLT5uYl9pbnQgPT0gTlVMTCkgeworICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfVHlwZUVycm9yLCAiYW4gaW50ZWdlciBpcyByZXF1aXJlZCIpOworICAgICAgICByZXR1cm4gKHVuc2lnbmVkIGxvbmcpLTE7CisgICAgfQorCisgICAgaW8gPSAoUHlJbnRPYmplY3QqKSAoKm5iLT5uYl9pbnQpIChvcCk7CisgICAgaWYgKGlvID09IE5VTEwpCisgICAgICAgIHJldHVybiAodW5zaWduZWQgbG9uZyktMTsKKyAgICBpZiAoIVB5SW50X0NoZWNrKGlvKSkgeworICAgICAgICBpZiAoUHlMb25nX0NoZWNrKGlvKSkgeworICAgICAgICAgICAgdmFsID0gUHlMb25nX0FzVW5zaWduZWRMb25nTWFzaygoUHlPYmplY3QgKilpbyk7CisgICAgICAgICAgICBQeV9ERUNSRUYoaW8pOworICAgICAgICAgICAgaWYgKFB5RXJyX09jY3VycmVkKCkpCisgICAgICAgICAgICAgICAgcmV0dXJuICh1bnNpZ25lZCBsb25nKS0xOworICAgICAgICAgICAgcmV0dXJuIHZhbDsKKyAgICAgICAgfQorICAgICAgICBlbHNlCisgICAgICAgIHsKKyAgICAgICAgICAgIFB5X0RFQ1JFRihpbyk7CisgICAgICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfVHlwZUVycm9yLAorICAgICAgICAgICAgICAgICAgICAgICAgIl9faW50X18gbWV0aG9kIHNob3VsZCByZXR1cm4gYW4gaW50ZWdlciIpOworICAgICAgICAgICAgcmV0dXJuICh1bnNpZ25lZCBsb25nKS0xOworICAgICAgICB9CisgICAgfQorCisgICAgdmFsID0gUHlJbnRfQVNfTE9ORyhpbyk7CisgICAgUHlfREVDUkVGKGlvKTsKKworICAgIHJldHVybiB2YWw7Cit9CisKKyNpZmRlZiBIQVZFX0xPTkdfTE9ORwordW5zaWduZWQgUFlfTE9OR19MT05HCitQeUludF9Bc1Vuc2lnbmVkTG9uZ0xvbmdNYXNrKHJlZ2lzdGVyIFB5T2JqZWN0ICpvcCkKK3sKKyAgICBQeU51bWJlck1ldGhvZHMgKm5iOworICAgIFB5SW50T2JqZWN0ICppbzsKKyAgICB1bnNpZ25lZCBQWV9MT05HX0xPTkcgdmFsOworCisgICAgaWYgKG9wICYmIFB5SW50X0NoZWNrKG9wKSkKKyAgICAgICAgcmV0dXJuIFB5SW50X0FTX0xPTkcoKFB5SW50T2JqZWN0Kikgb3ApOworICAgIGlmIChvcCAmJiBQeUxvbmdfQ2hlY2sob3ApKQorICAgICAgICByZXR1cm4gUHlMb25nX0FzVW5zaWduZWRMb25nTG9uZ01hc2sob3ApOworCisgICAgaWYgKG9wID09IE5VTEwgfHwgKG5iID0gUHlfVFlQRShvcCktPnRwX2FzX251bWJlcikgPT0gTlVMTCB8fAorICAgICAgICBuYi0+bmJfaW50ID09IE5VTEwpIHsKKyAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1R5cGVFcnJvciwgImFuIGludGVnZXIgaXMgcmVxdWlyZWQiKTsKKyAgICAgICAgcmV0dXJuICh1bnNpZ25lZCBQWV9MT05HX0xPTkcpLTE7CisgICAgfQorCisgICAgaW8gPSAoUHlJbnRPYmplY3QqKSAoKm5iLT5uYl9pbnQpIChvcCk7CisgICAgaWYgKGlvID09IE5VTEwpCisgICAgICAgIHJldHVybiAodW5zaWduZWQgUFlfTE9OR19MT05HKS0xOworICAgIGlmICghUHlJbnRfQ2hlY2soaW8pKSB7CisgICAgICAgIGlmIChQeUxvbmdfQ2hlY2soaW8pKSB7CisgICAgICAgICAgICB2YWwgPSBQeUxvbmdfQXNVbnNpZ25lZExvbmdMb25nTWFzaygoUHlPYmplY3QgKilpbyk7CisgICAgICAgICAgICBQeV9ERUNSRUYoaW8pOworICAgICAgICAgICAgaWYgKFB5RXJyX09jY3VycmVkKCkpCisgICAgICAgICAgICAgICAgcmV0dXJuICh1bnNpZ25lZCBQWV9MT05HX0xPTkcpLTE7CisgICAgICAgICAgICByZXR1cm4gdmFsOworICAgICAgICB9CisgICAgICAgIGVsc2UKKyAgICAgICAgeworICAgICAgICAgICAgUHlfREVDUkVGKGlvKTsKKyAgICAgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19UeXBlRXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAgICAiX19pbnRfXyBtZXRob2Qgc2hvdWxkIHJldHVybiBhbiBpbnRlZ2VyIik7CisgICAgICAgICAgICByZXR1cm4gKHVuc2lnbmVkIFBZX0xPTkdfTE9ORyktMTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHZhbCA9IFB5SW50X0FTX0xPTkcoaW8pOworICAgIFB5X0RFQ1JFRihpbyk7CisKKyAgICByZXR1cm4gdmFsOworfQorI2VuZGlmCisKK1B5T2JqZWN0ICoKK1B5SW50X0Zyb21TdHJpbmcoY2hhciAqcywgY2hhciAqKnBlbmQsIGludCBiYXNlKQoreworICAgIGNoYXIgKmVuZDsKKyAgICBsb25nIHg7CisgICAgUHlfc3NpemVfdCBzbGVuOworICAgIFB5T2JqZWN0ICpzb2JqLCAqc3JlcHI7CisKKyAgICBpZiAoKGJhc2UgIT0gMCAmJiBiYXNlIDwgMikgfHwgYmFzZSA+IDM2KSB7CisgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19WYWx1ZUVycm9yLAorICAgICAgICAgICAgICAgICAgICAgICAgImludCgpIGJhc2UgbXVzdCBiZSA+PSAyIGFuZCA8PSAzNiIpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisKKyAgICB3aGlsZSAoKnMgJiYgaXNzcGFjZShQeV9DSEFSTUFTSygqcykpKQorICAgICAgICBzKys7CisgICAgZXJybm8gPSAwOworICAgIGlmIChiYXNlID09IDAgJiYgc1swXSA9PSAnMCcpIHsKKyAgICAgICAgeCA9IChsb25nKSBQeU9TX3N0cnRvdWwocywgJmVuZCwgYmFzZSk7CisgICAgICAgIGlmICh4IDwgMCkKKyAgICAgICAgICAgIHJldHVybiBQeUxvbmdfRnJvbVN0cmluZyhzLCBwZW5kLCBiYXNlKTsKKyAgICB9CisgICAgZWxzZQorICAgICAgICB4ID0gUHlPU19zdHJ0b2wocywgJmVuZCwgYmFzZSk7CisgICAgaWYgKGVuZCA9PSBzIHx8ICFpc2FsbnVtKFB5X0NIQVJNQVNLKGVuZFstMV0pKSkKKyAgICAgICAgZ290byBiYWQ7CisgICAgd2hpbGUgKCplbmQgJiYgaXNzcGFjZShQeV9DSEFSTUFTSygqZW5kKSkpCisgICAgICAgIGVuZCsrOworICAgIGlmICgqZW5kICE9ICdcMCcpIHsKKyAgYmFkOgorICAgICAgICBzbGVuID0gc3RybGVuKHMpIDwgMjAwID8gc3RybGVuKHMpIDogMjAwOworICAgICAgICBzb2JqID0gUHlTdHJpbmdfRnJvbVN0cmluZ0FuZFNpemUocywgc2xlbik7CisgICAgICAgIGlmIChzb2JqID09IE5VTEwpCisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgc3JlcHIgPSBQeU9iamVjdF9SZXByKHNvYmopOworICAgICAgICBQeV9ERUNSRUYoc29iaik7CisgICAgICAgIGlmIChzcmVwciA9PSBOVUxMKQorICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgICAgIFB5RXJyX0Zvcm1hdChQeUV4Y19WYWx1ZUVycm9yLAorICAgICAgICAgICAgICAgICAgICAgImludmFsaWQgbGl0ZXJhbCBmb3IgaW50KCkgd2l0aCBiYXNlICVkOiAlcyIsCisgICAgICAgICAgICAgICAgICAgICBiYXNlLCBQeVN0cmluZ19BU19TVFJJTkcoc3JlcHIpKTsKKyAgICAgICAgUHlfREVDUkVGKHNyZXByKTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIGVsc2UgaWYgKGVycm5vICE9IDApCisgICAgICAgIHJldHVybiBQeUxvbmdfRnJvbVN0cmluZyhzLCBwZW5kLCBiYXNlKTsKKyAgICBpZiAocGVuZCkKKyAgICAgICAgKnBlbmQgPSBlbmQ7CisgICAgcmV0dXJuIFB5SW50X0Zyb21Mb25nKHgpOworfQorCisjaWZkZWYgUHlfVVNJTkdfVU5JQ09ERQorUHlPYmplY3QgKgorUHlJbnRfRnJvbVVuaWNvZGUoUHlfVU5JQ09ERSAqcywgUHlfc3NpemVfdCBsZW5ndGgsIGludCBiYXNlKQoreworICAgIFB5T2JqZWN0ICpyZXN1bHQ7CisgICAgY2hhciAqYnVmZmVyID0gKGNoYXIgKilQeU1lbV9NQUxMT0MobGVuZ3RoKzEpOworCisgICAgaWYgKGJ1ZmZlciA9PSBOVUxMKQorICAgICAgICByZXR1cm4gUHlFcnJfTm9NZW1vcnkoKTsKKworICAgIGlmIChQeVVuaWNvZGVfRW5jb2RlRGVjaW1hbChzLCBsZW5ndGgsIGJ1ZmZlciwgTlVMTCkpIHsKKyAgICAgICAgUHlNZW1fRlJFRShidWZmZXIpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgcmVzdWx0ID0gUHlJbnRfRnJvbVN0cmluZyhidWZmZXIsIE5VTEwsIGJhc2UpOworICAgIFB5TWVtX0ZSRUUoYnVmZmVyKTsKKyAgICByZXR1cm4gcmVzdWx0OworfQorI2VuZGlmCisKKy8qIE1ldGhvZHMgKi8KKworLyogSW50ZWdlcnMgYXJlIHNlZW4gYXMgdGhlICJzbWFsbGVzdCIgb2YgYWxsIG51bWVyaWMgdHlwZXMgYW5kIHRodXMKKyAgIGRvbid0IGhhdmUgYW55IGtub3dsZWRnZSBhYm91dCBjb252ZXJzaW9uIG9mIG90aGVyIHR5cGVzIHRvCisgICBpbnRlZ2Vycy4gKi8KKworI2RlZmluZSBDT05WRVJUX1RPX0xPTkcob2JqLCBsbmcpICAgICAgICAgICAgICAgXAorICAgIGlmIChQeUludF9DaGVjayhvYmopKSB7ICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICBsbmcgPSBQeUludF9BU19MT05HKG9iaik7ICAgICAgICAgICAgICAgXAorICAgIH0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIGVsc2UgeyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICBQeV9JTkNSRUYoUHlfTm90SW1wbGVtZW50ZWQpOyAgICAgICAgICAgXAorICAgICAgICByZXR1cm4gUHlfTm90SW1wbGVtZW50ZWQ7ICAgICAgICAgICAgICAgXAorICAgIH0KKworLyogQVJHU1VTRUQgKi8KK3N0YXRpYyBpbnQKK2ludF9wcmludChQeUludE9iamVjdCAqdiwgRklMRSAqZnAsIGludCBmbGFncykKKyAgICAgLyogZmxhZ3MgLS0gbm90IHVzZWQgYnV0IHJlcXVpcmVkIGJ5IGludGVyZmFjZSAqLworeworICAgIGxvbmcgaW50X3ZhbCA9IHYtPm9iX2l2YWw7CisgICAgUHlfQkVHSU5fQUxMT1dfVEhSRUFEUworICAgIGZwcmludGYoZnAsICIlbGQiLCBpbnRfdmFsKTsKKyAgICBQeV9FTkRfQUxMT1dfVEhSRUFEUworICAgIHJldHVybiAwOworfQorCitzdGF0aWMgaW50CitpbnRfY29tcGFyZShQeUludE9iamVjdCAqdiwgUHlJbnRPYmplY3QgKncpCit7CisgICAgcmVnaXN0ZXIgbG9uZyBpID0gdi0+b2JfaXZhbDsKKyAgICByZWdpc3RlciBsb25nIGogPSB3LT5vYl9pdmFsOworICAgIHJldHVybiAoaSA8IGopID8gLTEgOiAoaSA+IGopID8gMSA6IDA7Cit9CisKK3N0YXRpYyBsb25nCitpbnRfaGFzaChQeUludE9iamVjdCAqdikKK3sKKyAgICAvKiBYWFggSWYgdGhpcyBpcyBjaGFuZ2VkLCB5b3UgYWxzbyBuZWVkIHRvIGNoYW5nZSB0aGUgd2F5CisgICAgICAgUHl0aG9uJ3MgbG9uZywgZmxvYXQgYW5kIGNvbXBsZXggdHlwZXMgYXJlIGhhc2hlZC4gKi8KKyAgICBsb25nIHggPSB2IC0+IG9iX2l2YWw7CisgICAgaWYgKHggPT0gLTEpCisgICAgICAgIHggPSAtMjsKKyAgICByZXR1cm4geDsKK30KKworc3RhdGljIFB5T2JqZWN0ICoKK2ludF9hZGQoUHlJbnRPYmplY3QgKnYsIFB5SW50T2JqZWN0ICp3KQoreworICAgIHJlZ2lzdGVyIGxvbmcgYSwgYiwgeDsKKyAgICBDT05WRVJUX1RPX0xPTkcodiwgYSk7CisgICAgQ09OVkVSVF9UT19MT05HKHcsIGIpOworICAgIC8qIGNhc3RzIGluIHRoZSBsaW5lIGJlbG93IGF2b2lkIHVuZGVmaW5lZCBiZWhhdmlvdXIgb24gb3ZlcmZsb3cgKi8KKyAgICB4ID0gKGxvbmcpKCh1bnNpZ25lZCBsb25nKWEgKyBiKTsKKyAgICBpZiAoKHheYSkgPj0gMCB8fCAoeF5iKSA+PSAwKQorICAgICAgICByZXR1cm4gUHlJbnRfRnJvbUxvbmcoeCk7CisgICAgcmV0dXJuIFB5TG9uZ19UeXBlLnRwX2FzX251bWJlci0+bmJfYWRkKChQeU9iamVjdCAqKXYsIChQeU9iamVjdCAqKXcpOworfQorCitzdGF0aWMgUHlPYmplY3QgKgoraW50X3N1YihQeUludE9iamVjdCAqdiwgUHlJbnRPYmplY3QgKncpCit7CisgICAgcmVnaXN0ZXIgbG9uZyBhLCBiLCB4OworICAgIENPTlZFUlRfVE9fTE9ORyh2LCBhKTsKKyAgICBDT05WRVJUX1RPX0xPTkcodywgYik7CisgICAgLyogY2FzdHMgaW4gdGhlIGxpbmUgYmVsb3cgYXZvaWQgdW5kZWZpbmVkIGJlaGF2aW91ciBvbiBvdmVyZmxvdyAqLworICAgIHggPSAobG9uZykoKHVuc2lnbmVkIGxvbmcpYSAtIGIpOworICAgIGlmICgoeF5hKSA+PSAwIHx8ICh4Xn5iKSA+PSAwKQorICAgICAgICByZXR1cm4gUHlJbnRfRnJvbUxvbmcoeCk7CisgICAgcmV0dXJuIFB5TG9uZ19UeXBlLnRwX2FzX251bWJlci0+bmJfc3VidHJhY3QoKFB5T2JqZWN0ICopdiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoUHlPYmplY3QgKil3KTsKK30KKworLyoKK0ludGVnZXIgb3ZlcmZsb3cgY2hlY2tpbmcgZm9yICogaXMgcGFpbmZ1bDogIFB5dGhvbiB0cmllZCBhIGNvdXBsZSB3YXlzLCBidXQKK3RoZXkgZGlkbid0IHdvcmsgb24gYWxsIHBsYXRmb3Jtcywgb3IgZmFpbGVkIGluIGVuZGNhc2VzIChhIHByb2R1Y3Qgb2YKKy1zeXMubWF4aW50LTEgaGFzIGJlZW4gYSBwYXJ0aWN1bGFyIHBhaW4pLgorCitIZXJlJ3MgYW5vdGhlciB3YXk6CisKK1RoZSBuYXRpdmUgbG9uZyBwcm9kdWN0IHgqeSBpcyBlaXRoZXIgZXhhY3RseSByaWdodCBvciAqd2F5KiBvZmYsIGJlaW5nCitqdXN0IHRoZSBsYXN0IG4gYml0cyBvZiB0aGUgdHJ1ZSBwcm9kdWN0LCB3aGVyZSBuIGlzIHRoZSBudW1iZXIgb2YgYml0cworaW4gYSBsb25nICh0aGUgZGVsaXZlcmVkIHByb2R1Y3QgaXMgdGhlIHRydWUgcHJvZHVjdCBwbHVzIGkqMioqbiBmb3IKK3NvbWUgaW50ZWdlciBpKS4KKworVGhlIG5hdGl2ZSBkb3VibGUgcHJvZHVjdCAoZG91YmxlKXggKiAoZG91YmxlKXkgaXMgc3ViamVjdCB0byB0aHJlZQorcm91bmRpbmcgZXJyb3JzOiAgb24gYSBzaXplb2YobG9uZyk9PTggYm94LCBlYWNoIGNhc3QgdG8gZG91YmxlIGNhbiBsb3NlCitpbmZvLCBhbmQgZXZlbiBvbiBhIHNpemVvZihsb25nKT09NCBib3gsIHRoZSBtdWx0aXBsaWNhdGlvbiBjYW4gbG9zZSBpbmZvLgorQnV0LCB1bmxpa2UgdGhlIG5hdGl2ZSBsb25nIHByb2R1Y3QsIGl0J3Mgbm90IGluICpyYW5nZSogdHJvdWJsZTogIGV2ZW4KK2lmIHNpemVvZihsb25nKT09MzIgKDI1Ni1iaXQgbG9uZ3MpLCB0aGUgcHJvZHVjdCBlYXNpbHkgZml0cyBpbiB0aGUKK2R5bmFtaWMgcmFuZ2Ugb2YgYSBkb3VibGUuICBTbyB0aGUgbGVhZGluZyA1MCAob3Igc28pIGJpdHMgb2YgdGhlIGRvdWJsZQorcHJvZHVjdCBhcmUgY29ycmVjdC4KKworV2UgY2hlY2sgdGhlc2UgdHdvIHdheXMgYWdhaW5zdCBlYWNoIG90aGVyLCBhbmQgZGVjbGFyZSB2aWN0b3J5IGlmIHRoZXkncmUKK2FwcHJveGltYXRlbHkgdGhlIHNhbWUuICBFbHNlLCBiZWNhdXNlIHRoZSBuYXRpdmUgbG9uZyBwcm9kdWN0IGlzIHRoZSBvbmx5CitvbmUgdGhhdCBjYW4gbG9zZSBjYXRhc3Ryb3BoaWMgYW1vdW50cyBvZiBpbmZvcm1hdGlvbiwgaXQncyB0aGUgbmF0aXZlIGxvbmcKK3Byb2R1Y3QgdGhhdCBtdXN0IGhhdmUgb3ZlcmZsb3dlZC4KKyovCisKK3N0YXRpYyBQeU9iamVjdCAqCitpbnRfbXVsKFB5T2JqZWN0ICp2LCBQeU9iamVjdCAqdykKK3sKKyAgICBsb25nIGEsIGI7CisgICAgbG9uZyBsb25ncHJvZDsgICAgICAgICAgICAgICAgICAgICAgLyogYSpiIGluIG5hdGl2ZSBsb25nIGFyaXRobWV0aWMgKi8KKyAgICBkb3VibGUgZG91YmxlZF9sb25ncHJvZDsgICAgICAgICAgICAvKiAoZG91YmxlKWxvbmdwcm9kICovCisgICAgZG91YmxlIGRvdWJsZXByb2Q7ICAgICAgICAgICAgICAgICAgLyogKGRvdWJsZSlhICogKGRvdWJsZSliICovCisKKyAgICBDT05WRVJUX1RPX0xPTkcodiwgYSk7CisgICAgQ09OVkVSVF9UT19MT05HKHcsIGIpOworICAgIC8qIGNhc3RzIGluIHRoZSBuZXh0IGxpbmUgYXZvaWQgdW5kZWZpbmVkIGJlaGF2aW91ciBvbiBvdmVyZmxvdyAqLworICAgIGxvbmdwcm9kID0gKGxvbmcpKCh1bnNpZ25lZCBsb25nKWEgKiBiKTsKKyAgICBkb3VibGVwcm9kID0gKGRvdWJsZSlhICogKGRvdWJsZSliOworICAgIGRvdWJsZWRfbG9uZ3Byb2QgPSAoZG91YmxlKWxvbmdwcm9kOworCisgICAgLyogRmFzdCBwYXRoIGZvciBub3JtYWwgY2FzZTogIHNtYWxsIG11bHRpcGxpY2FuZHMsIGFuZCBubyBpbmZvCisgICAgICAgaXMgbG9zdCBpbiBlaXRoZXIgbWV0aG9kLiAqLworICAgIGlmIChkb3VibGVkX2xvbmdwcm9kID09IGRvdWJsZXByb2QpCisgICAgICAgIHJldHVybiBQeUludF9Gcm9tTG9uZyhsb25ncHJvZCk7CisKKyAgICAvKiBTb21lYm9keSBzb21ld2hlcmUgbG9zdCBpbmZvLiAgQ2xvc2UgZW5vdWdoLCBvciB3YXkgb2ZmPyAgTm90ZQorICAgICAgIHRoYXQgYSAhPSAwIGFuZCBiICE9IDAgKGVsc2UgZG91YmxlZF9sb25ncHJvZCA9PSBkb3VibGVwcm9kID09IDApLgorICAgICAgIFRoZSBkaWZmZXJlbmNlIGVpdGhlciBpcyBvciBpc24ndCBzaWduaWZpY2FudCBjb21wYXJlZCB0byB0aGUKKyAgICAgICB0cnVlIHZhbHVlIChvZiB3aGljaCBkb3VibGVwcm9kIGlzIGEgZ29vZCBhcHByb3hpbWF0aW9uKS4KKyAgICAqLworICAgIHsKKyAgICAgICAgY29uc3QgZG91YmxlIGRpZmYgPSBkb3VibGVkX2xvbmdwcm9kIC0gZG91YmxlcHJvZDsKKyAgICAgICAgY29uc3QgZG91YmxlIGFic2RpZmYgPSBkaWZmID49IDAuMCA/IGRpZmYgOiAtZGlmZjsKKyAgICAgICAgY29uc3QgZG91YmxlIGFic3Byb2QgPSBkb3VibGVwcm9kID49IDAuMCA/IGRvdWJsZXByb2QgOgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLWRvdWJsZXByb2Q7CisgICAgICAgIC8qIGFic2RpZmYvYWJzcHJvZCA8PSAxLzMyIGlmZgorICAgICAgICAgICAzMiAqIGFic2RpZmYgPD0gYWJzcHJvZCAtLSA1IGdvb2QgYml0cyBpcyAiY2xvc2UgZW5vdWdoIiAqLworICAgICAgICBpZiAoMzIuMCAqIGFic2RpZmYgPD0gYWJzcHJvZCkKKyAgICAgICAgICAgIHJldHVybiBQeUludF9Gcm9tTG9uZyhsb25ncHJvZCk7CisgICAgICAgIGVsc2UKKyAgICAgICAgICAgIHJldHVybiBQeUxvbmdfVHlwZS50cF9hc19udW1iZXItPm5iX211bHRpcGx5KHYsIHcpOworICAgIH0KK30KKworLyogSW50ZWdlciBvdmVyZmxvdyBjaGVja2luZyBmb3IgdW5hcnkgbmVnYXRpb246IG9uIGEgMidzLWNvbXBsZW1lbnQKKyAqIGJveCwgLXggb3ZlcmZsb3dzIGlmZiB4IGlzIHRoZSBtb3N0IG5lZ2F0aXZlIGxvbmcuICBJbiB0aGlzIGNhc2Ugd2UKKyAqIGdldCAteCA9PSB4LiAgSG93ZXZlciwgLXggaXMgdW5kZWZpbmVkIChieSBDKSBpZiB4IC9pcy8gdGhlIG1vc3QKKyAqIG5lZ2F0aXZlIGxvbmcgKGl0J3MgYSBzaWduZWQgb3ZlcmZsb3cgY2FzZSksIGFuZCBzb21lIGNvbXBpbGVycyBjYXJlLgorICogU28gd2UgY2FzdCB4IHRvIHVuc2lnbmVkIGxvbmcgZmlyc3QuICBIb3dldmVyLCB0aGVuIG90aGVyIGNvbXBpbGVycworICogd2FybiBhYm91dCBhcHBseWluZyB1bmFyeSBtaW51cyB0byBhbiB1bnNpZ25lZCBvcGVyYW5kLiAgSGVuY2UgdGhlCisgKiB3ZWlyZCAiMC0iLgorICovCisjZGVmaW5lIFVOQVJZX05FR19XT1VMRF9PVkVSRkxPVyh4KSAgICAgXAorICAgICgoeCkgPCAwICYmICh1bnNpZ25lZCBsb25nKSh4KSA9PSAwLSh1bnNpZ25lZCBsb25nKSh4KSkKKworLyogUmV0dXJuIHR5cGUgb2YgaV9kaXZtb2QgKi8KK2VudW0gZGl2bW9kX3Jlc3VsdCB7CisgICAgRElWTU9EX09LLCAgICAgICAgICAgICAgICAgIC8qIENvcnJlY3QgcmVzdWx0ICovCisgICAgRElWTU9EX09WRVJGTE9XLCAgICAgICAgICAgIC8qIE92ZXJmbG93LCB0cnkgYWdhaW4gdXNpbmcgbG9uZ3MgKi8KKyAgICBESVZNT0RfRVJST1IgICAgICAgICAgICAgICAgLyogRXhjZXB0aW9uIHJhaXNlZCAqLworfTsKKworc3RhdGljIGVudW0gZGl2bW9kX3Jlc3VsdAoraV9kaXZtb2QocmVnaXN0ZXIgbG9uZyB4LCByZWdpc3RlciBsb25nIHksCisgICAgICAgICBsb25nICpwX3hkaXZ5LCBsb25nICpwX3htb2R5KQoreworICAgIGxvbmcgeGRpdnksIHhtb2R5OworCisgICAgaWYgKHkgPT0gMCkgeworICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfWmVyb0RpdmlzaW9uRXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAgICAiaW50ZWdlciBkaXZpc2lvbiBvciBtb2R1bG8gYnkgemVybyIpOworICAgICAgICByZXR1cm4gRElWTU9EX0VSUk9SOworICAgIH0KKyAgICAvKiAoLXN5cy5tYXhpbnQtMSkvLTEgaXMgdGhlIG9ubHkgb3ZlcmZsb3cgY2FzZS4gKi8KKyAgICBpZiAoeSA9PSAtMSAmJiBVTkFSWV9ORUdfV09VTERfT1ZFUkZMT1coeCkpCisgICAgICAgIHJldHVybiBESVZNT0RfT1ZFUkZMT1c7CisgICAgeGRpdnkgPSB4IC8geTsKKyAgICAvKiB4ZGl2KnkgY2FuIG92ZXJmbG93IG9uIHBsYXRmb3JtcyB3aGVyZSB4L3kgZ2l2ZXMgZmxvb3IoeC95KQorICAgICAqIGZvciB4IGFuZCB5IHdpdGggZGlmZmVyaW5nIHNpZ25zLiAoVGhpcyBpcyB1bnVzdWFsCisgICAgICogYmVoYXZpb3VyLCBhbmQgQzk5IHByb2hpYml0cyBpdCwgYnV0IGl0J3MgYWxsb3dlZCBieSBDODk7CisgICAgICogZm9yIGFuIGV4YW1wbGUgb2Ygb3ZlcmZsb3csIHRha2UgeCA9IExPTkdfTUlOLCB5ID0gNSBvciB4ID0KKyAgICAgKiBMT05HX01BWCwgeSA9IC01LikgIEhvd2V2ZXIsIHggLSB4ZGl2eSp5IGlzIGFsd2F5cworICAgICAqIHJlcHJlc2VudGFibGUgYXMgYSBsb25nLCBzaW5jZSBpdCBsaWVzIHN0cmljdGx5IGJldHdlZW4KKyAgICAgKiAtYWJzKHkpIGFuZCBhYnMoeSkuICBXZSBhZGQgY2FzdHMgdG8gYXZvaWQgaW50ZXJtZWRpYXRlCisgICAgICogb3ZlcmZsb3cuCisgICAgICovCisgICAgeG1vZHkgPSAobG9uZykoeCAtICh1bnNpZ25lZCBsb25nKXhkaXZ5ICogeSk7CisgICAgLyogSWYgdGhlIHNpZ25zIG9mIHggYW5kIHkgZGlmZmVyLCBhbmQgdGhlIHJlbWFpbmRlciBpcyBub24tMCwKKyAgICAgKiBDODkgZG9lc24ndCBkZWZpbmUgd2hldGhlciB4ZGl2eSBpcyBub3cgdGhlIGZsb29yIG9yIHRoZQorICAgICAqIGNlaWxpbmcgb2YgdGhlIGluZmluaXRlbHkgcHJlY2lzZSBxdW90aWVudC4gIFdlIHdhbnQgdGhlIGZsb29yLAorICAgICAqIGFuZCB3ZSBoYXZlIGl0IGlmZiB0aGUgcmVtYWluZGVyJ3Mgc2lnbiBtYXRjaGVzIHkncy4KKyAgICAgKi8KKyAgICBpZiAoeG1vZHkgJiYgKCh5IF4geG1vZHkpIDwgMCkgLyogaS5lLiBhbmQgc2lnbnMgZGlmZmVyICovKSB7CisgICAgICAgIHhtb2R5ICs9IHk7CisgICAgICAgIC0teGRpdnk7CisgICAgICAgIGFzc2VydCh4bW9keSAmJiAoKHkgXiB4bW9keSkgPj0gMCkpOworICAgIH0KKyAgICAqcF94ZGl2eSA9IHhkaXZ5OworICAgICpwX3htb2R5ID0geG1vZHk7CisgICAgcmV0dXJuIERJVk1PRF9PSzsKK30KKworc3RhdGljIFB5T2JqZWN0ICoKK2ludF9kaXYoUHlJbnRPYmplY3QgKngsIFB5SW50T2JqZWN0ICp5KQoreworICAgIGxvbmcgeGksIHlpOworICAgIGxvbmcgZCwgbTsKKyAgICBDT05WRVJUX1RPX0xPTkcoeCwgeGkpOworICAgIENPTlZFUlRfVE9fTE9ORyh5LCB5aSk7CisgICAgc3dpdGNoIChpX2Rpdm1vZCh4aSwgeWksICZkLCAmbSkpIHsKKyAgICBjYXNlIERJVk1PRF9PSzoKKyAgICAgICAgcmV0dXJuIFB5SW50X0Zyb21Mb25nKGQpOworICAgIGNhc2UgRElWTU9EX09WRVJGTE9XOgorICAgICAgICByZXR1cm4gUHlMb25nX1R5cGUudHBfYXNfbnVtYmVyLT5uYl9kaXZpZGUoKFB5T2JqZWN0ICopeCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChQeU9iamVjdCAqKXkpOworICAgIGRlZmF1bHQ6CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KK30KKworc3RhdGljIFB5T2JqZWN0ICoKK2ludF9jbGFzc2ljX2RpdihQeUludE9iamVjdCAqeCwgUHlJbnRPYmplY3QgKnkpCit7CisgICAgbG9uZyB4aSwgeWk7CisgICAgbG9uZyBkLCBtOworICAgIENPTlZFUlRfVE9fTE9ORyh4LCB4aSk7CisgICAgQ09OVkVSVF9UT19MT05HKHksIHlpKTsKKyAgICBpZiAoUHlfRGl2aXNpb25XYXJuaW5nRmxhZyAmJgorICAgICAgICBQeUVycl9XYXJuKFB5RXhjX0RlcHJlY2F0aW9uV2FybmluZywgImNsYXNzaWMgaW50IGRpdmlzaW9uIikgPCAwKQorICAgICAgICByZXR1cm4gTlVMTDsKKyAgICBzd2l0Y2ggKGlfZGl2bW9kKHhpLCB5aSwgJmQsICZtKSkgeworICAgIGNhc2UgRElWTU9EX09LOgorICAgICAgICByZXR1cm4gUHlJbnRfRnJvbUxvbmcoZCk7CisgICAgY2FzZSBESVZNT0RfT1ZFUkZMT1c6CisgICAgICAgIHJldHVybiBQeUxvbmdfVHlwZS50cF9hc19udW1iZXItPm5iX2RpdmlkZSgoUHlPYmplY3QgKil4LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKFB5T2JqZWN0ICopeSk7CisgICAgZGVmYXVsdDoKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorfQorCitzdGF0aWMgUHlPYmplY3QgKgoraW50X3RydWVfZGl2aWRlKFB5SW50T2JqZWN0ICp4LCBQeUludE9iamVjdCAqeSkKK3sKKyAgICBsb25nIHhpLCB5aTsKKyAgICAvKiBJZiB0aGV5IGFyZW4ndCBib3RoIGludHMsIGdpdmUgc29tZW9uZSBlbHNlIGEgY2hhbmNlLiAgSW4KKyAgICAgICBwYXJ0aWN1bGFyLCB0aGlzIGxldHMgaW50L2xvbmcgZ2V0IGhhbmRsZWQgYnkgbG9uZ3MsIHdoaWNoCisgICAgICAgdW5kZXJmbG93cyB0byAwIGdyYWNlZnVsbHkgaWYgdGhlIGxvbmcgaXMgdG9vIGJpZyB0byBjb252ZXJ0CisgICAgICAgdG8gZmxvYXQuICovCisgICAgQ09OVkVSVF9UT19MT05HKHgsIHhpKTsKKyAgICBDT05WRVJUX1RPX0xPTkcoeSwgeWkpOworICAgIGlmICh5aSA9PSAwKSB7CisgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19aZXJvRGl2aXNpb25FcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICJkaXZpc2lvbiBieSB6ZXJvIik7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICBpZiAoeGkgPT0gMCkKKyAgICAgICAgcmV0dXJuIFB5RmxvYXRfRnJvbURvdWJsZSh5aSA8IDAgPyAtMC4wIDogMC4wKTsKKworI2RlZmluZSBXSURUSF9PRl9VTE9ORyAoQ0hBUl9CSVQqU0laRU9GX0xPTkcpCisjaWYgREJMX01BTlRfRElHIDwgV0lEVEhfT0ZfVUxPTkcKKyAgICBpZiAoKHhpID49IDAgPyAwVUwgKyB4aSA6IDBVTCAtIHhpKSA+PiBEQkxfTUFOVF9ESUcgfHwKKyAgICAgICAgKHlpID49IDAgPyAwVUwgKyB5aSA6IDBVTCAtIHlpKSA+PiBEQkxfTUFOVF9ESUcpCisgICAgICAgIC8qIExhcmdlIHggb3IgeS4gIFVzZSBsb25nIGludGVnZXIgYXJpdGhtZXRpYy4gKi8KKyAgICAgICAgcmV0dXJuIFB5TG9uZ19UeXBlLnRwX2FzX251bWJlci0+bmJfdHJ1ZV9kaXZpZGUoCisgICAgICAgICAgICAoUHlPYmplY3QgKil4LCAoUHlPYmplY3QgKil5KTsKKyAgICBlbHNlCisjZW5kaWYKKyAgICAgICAgLyogQm90aCBpbnRzIGNhbiBiZSBleGFjdGx5IHJlcHJlc2VudGVkIGFzIGRvdWJsZXMuICBEbyBhCisgICAgICAgICAgIGZsb2F0aW5nLXBvaW50IGRpdmlzaW9uLiAqLworICAgICAgICByZXR1cm4gUHlGbG9hdF9Gcm9tRG91YmxlKChkb3VibGUpeGkgLyAoZG91YmxlKXlpKTsKK30KKworc3RhdGljIFB5T2JqZWN0ICoKK2ludF9tb2QoUHlJbnRPYmplY3QgKngsIFB5SW50T2JqZWN0ICp5KQoreworICAgIGxvbmcgeGksIHlpOworICAgIGxvbmcgZCwgbTsKKyAgICBDT05WRVJUX1RPX0xPTkcoeCwgeGkpOworICAgIENPTlZFUlRfVE9fTE9ORyh5LCB5aSk7CisgICAgc3dpdGNoIChpX2Rpdm1vZCh4aSwgeWksICZkLCAmbSkpIHsKKyAgICBjYXNlIERJVk1PRF9PSzoKKyAgICAgICAgcmV0dXJuIFB5SW50X0Zyb21Mb25nKG0pOworICAgIGNhc2UgRElWTU9EX09WRVJGTE9XOgorICAgICAgICByZXR1cm4gUHlMb25nX1R5cGUudHBfYXNfbnVtYmVyLT5uYl9yZW1haW5kZXIoKFB5T2JqZWN0ICopeCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChQeU9iamVjdCAqKXkpOworICAgIGRlZmF1bHQ6CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KK30KKworc3RhdGljIFB5T2JqZWN0ICoKK2ludF9kaXZtb2QoUHlJbnRPYmplY3QgKngsIFB5SW50T2JqZWN0ICp5KQoreworICAgIGxvbmcgeGksIHlpOworICAgIGxvbmcgZCwgbTsKKyAgICBDT05WRVJUX1RPX0xPTkcoeCwgeGkpOworICAgIENPTlZFUlRfVE9fTE9ORyh5LCB5aSk7CisgICAgc3dpdGNoIChpX2Rpdm1vZCh4aSwgeWksICZkLCAmbSkpIHsKKyAgICBjYXNlIERJVk1PRF9PSzoKKyAgICAgICAgcmV0dXJuIFB5X0J1aWxkVmFsdWUoIihsbCkiLCBkLCBtKTsKKyAgICBjYXNlIERJVk1PRF9PVkVSRkxPVzoKKyAgICAgICAgcmV0dXJuIFB5TG9uZ19UeXBlLnRwX2FzX251bWJlci0+bmJfZGl2bW9kKChQeU9iamVjdCAqKXgsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoUHlPYmplY3QgKil5KTsKKyAgICBkZWZhdWx0OgorICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9Cit9CisKK3N0YXRpYyBQeU9iamVjdCAqCitpbnRfcG93KFB5SW50T2JqZWN0ICp2LCBQeUludE9iamVjdCAqdywgUHlJbnRPYmplY3QgKnopCit7CisgICAgcmVnaXN0ZXIgbG9uZyBpdiwgaXcsIGl6PTAsIGl4LCB0ZW1wLCBwcmV2OworICAgIENPTlZFUlRfVE9fTE9ORyh2LCBpdik7CisgICAgQ09OVkVSVF9UT19MT05HKHcsIGl3KTsKKyAgICBpZiAoaXcgPCAwKSB7CisgICAgICAgIGlmICgoUHlPYmplY3QgKil6ICE9IFB5X05vbmUpIHsKKyAgICAgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19UeXBlRXJyb3IsICJwb3coKSAybmQgYXJndW1lbnQgIgorICAgICAgICAgICAgICAgICAiY2Fubm90IGJlIG5lZ2F0aXZlIHdoZW4gM3JkIGFyZ3VtZW50IHNwZWNpZmllZCIpOworICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgICAgIH0KKyAgICAgICAgLyogUmV0dXJuIGEgZmxvYXQuICBUaGlzIHdvcmtzIGJlY2F1c2Ugd2Uga25vdyB0aGF0CisgICAgICAgICAgIHRoaXMgY2FsbHMgZmxvYXRfcG93KCkgd2hpY2ggY29udmVydHMgaXRzCisgICAgICAgICAgIGFyZ3VtZW50cyB0byBkb3VibGUuICovCisgICAgICAgIHJldHVybiBQeUZsb2F0X1R5cGUudHBfYXNfbnVtYmVyLT5uYl9wb3dlcigKKyAgICAgICAgICAgIChQeU9iamVjdCAqKXYsIChQeU9iamVjdCAqKXcsIChQeU9iamVjdCAqKXopOworICAgIH0KKyAgICBpZiAoKFB5T2JqZWN0ICopeiAhPSBQeV9Ob25lKSB7CisgICAgICAgIENPTlZFUlRfVE9fTE9ORyh6LCBpeik7CisgICAgICAgIGlmIChpeiA9PSAwKSB7CisgICAgICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfVmFsdWVFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAicG93KCkgM3JkIGFyZ3VtZW50IGNhbm5vdCBiZSAwIik7CisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgfQorICAgIH0KKyAgICAvKgorICAgICAqIFhYWDogVGhlIG9yaWdpbmFsIGV4cG9uZW50aWF0aW9uIGNvZGUgc3RvcHBlZCBsb29waW5nCisgICAgICogd2hlbiB0ZW1wIGhpdCB6ZXJvOyB0aGlzIGNvZGUgd2lsbCBjb250aW51ZSBvbndhcmRzCisgICAgICogdW5uZWNlc3NhcmlseSwgYnV0IGF0IGxlYXN0IGl0IHdvbid0IGNhdXNlIGFueSBlcnJvcnMuCisgICAgICogSG9wZWZ1bGx5IHRoZSBzcGVlZCBpbXByb3ZlbWVudCBmcm9tIHRoZSBmYXN0IGV4cG9uZW50aWF0aW9uCisgICAgICogd2lsbCBjb21wZW5zYXRlIGZvciB0aGUgc2xpZ2h0IGluZWZmaWNpZW5jeS4KKyAgICAgKiBYWFg6IEJldHRlciBoYW5kbGluZyBvZiBvdmVyZmxvd3MgaXMgZGVzcGVyYXRlbHkgbmVlZGVkLgorICAgICAqLworICAgIHRlbXAgPSBpdjsKKyAgICBpeCA9IDE7CisgICAgd2hpbGUgKGl3ID4gMCkgeworICAgICAgICBwcmV2ID0gaXg7ICAgICAgICAgICAgICAvKiBTYXZlIHZhbHVlIGZvciBvdmVyZmxvdyBjaGVjayAqLworICAgICAgICBpZiAoaXcgJiAxKSB7CisgICAgICAgICAgICAvKgorICAgICAgICAgICAgICogVGhlICh1bnNpZ25lZCBsb25nKSBjYXN0IGJlbG93IGVuc3VyZXMgdGhhdCB0aGUgbXVsdGlwbGljYXRpb24KKyAgICAgICAgICAgICAqIGlzIGludGVycHJldGVkIGFzIGFuIHVuc2lnbmVkIG9wZXJhdGlvbiByYXRoZXIgdGhhbiBhIHNpZ25lZCBvbmUKKyAgICAgICAgICAgICAqIChDOTkgNi4zLjEuOHAxKSwgdGh1cyBhdm9pZGluZyB0aGUgcGVyaWxzIG9mIHVuZGVmaW5lZCBiZWhhdmlvdXIKKyAgICAgICAgICAgICAqIGZyb20gc2lnbmVkIGFyaXRobWV0aWMgb3ZlcmZsb3cgKEM5OSA2LjVwNSkuICBTZWUgaXNzdWUgIzEyOTczLgorICAgICAgICAgICAgICovCisgICAgICAgICAgICBpeCA9ICh1bnNpZ25lZCBsb25nKWl4ICogdGVtcDsKKyAgICAgICAgICAgIGlmICh0ZW1wID09IDApCisgICAgICAgICAgICAgICAgYnJlYWs7IC8qIEF2b2lkIGl4IC8gMCAqLworICAgICAgICAgICAgaWYgKGl4IC8gdGVtcCAhPSBwcmV2KSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIFB5TG9uZ19UeXBlLnRwX2FzX251bWJlci0+bmJfcG93ZXIoCisgICAgICAgICAgICAgICAgICAgIChQeU9iamVjdCAqKXYsCisgICAgICAgICAgICAgICAgICAgIChQeU9iamVjdCAqKXcsCisgICAgICAgICAgICAgICAgICAgIChQeU9iamVjdCAqKXopOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGl3ID4+PSAxOyAgICAgICAgICAgICAgIC8qIFNoaWZ0IGV4cG9uZW50IGRvd24gYnkgMSBiaXQgKi8KKyAgICAgICAgaWYgKGl3PT0wKSBicmVhazsKKyAgICAgICAgcHJldiA9IHRlbXA7CisgICAgICAgIHRlbXAgPSAodW5zaWduZWQgbG9uZyl0ZW1wICogdGVtcDsgIC8qIFNxdWFyZSB0aGUgdmFsdWUgb2YgdGVtcCAqLworICAgICAgICBpZiAocHJldiAhPSAwICYmIHRlbXAgLyBwcmV2ICE9IHByZXYpIHsKKyAgICAgICAgICAgIHJldHVybiBQeUxvbmdfVHlwZS50cF9hc19udW1iZXItPm5iX3Bvd2VyKAorICAgICAgICAgICAgICAgIChQeU9iamVjdCAqKXYsIChQeU9iamVjdCAqKXcsIChQeU9iamVjdCAqKXopOworICAgICAgICB9CisgICAgICAgIGlmIChpeikgeworICAgICAgICAgICAgLyogSWYgd2UgZGlkIGEgbXVsdGlwbGljYXRpb24sIHBlcmZvcm0gYSBtb2R1bG8gKi8KKyAgICAgICAgICAgIGl4ID0gaXggJSBpejsKKyAgICAgICAgICAgIHRlbXAgPSB0ZW1wICUgaXo7CisgICAgICAgIH0KKyAgICB9CisgICAgaWYgKGl6KSB7CisgICAgICAgIGxvbmcgZGl2LCBtb2Q7CisgICAgICAgIHN3aXRjaCAoaV9kaXZtb2QoaXgsIGl6LCAmZGl2LCAmbW9kKSkgeworICAgICAgICBjYXNlIERJVk1PRF9PSzoKKyAgICAgICAgICAgIGl4ID0gbW9kOworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIGNhc2UgRElWTU9EX09WRVJGTE9XOgorICAgICAgICAgICAgcmV0dXJuIFB5TG9uZ19UeXBlLnRwX2FzX251bWJlci0+bmJfcG93ZXIoCisgICAgICAgICAgICAgICAgKFB5T2JqZWN0ICopdiwgKFB5T2JqZWN0ICopdywgKFB5T2JqZWN0ICopeik7CisgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgfQorICAgIH0KKyAgICByZXR1cm4gUHlJbnRfRnJvbUxvbmcoaXgpOworfQorCitzdGF0aWMgUHlPYmplY3QgKgoraW50X25lZyhQeUludE9iamVjdCAqdikKK3sKKyAgICByZWdpc3RlciBsb25nIGE7CisgICAgYSA9IHYtPm9iX2l2YWw7CisgICAgLyogY2hlY2sgZm9yIG92ZXJmbG93ICovCisgICAgaWYgKFVOQVJZX05FR19XT1VMRF9PVkVSRkxPVyhhKSkgeworICAgICAgICBQeU9iamVjdCAqbyA9IFB5TG9uZ19Gcm9tTG9uZyhhKTsKKyAgICAgICAgaWYgKG8gIT0gTlVMTCkgeworICAgICAgICAgICAgUHlPYmplY3QgKnJlc3VsdCA9IFB5TnVtYmVyX05lZ2F0aXZlKG8pOworICAgICAgICAgICAgUHlfREVDUkVGKG8pOworICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgcmV0dXJuIFB5SW50X0Zyb21Mb25nKC1hKTsKK30KKworc3RhdGljIFB5T2JqZWN0ICoKK2ludF9hYnMoUHlJbnRPYmplY3QgKnYpCit7CisgICAgaWYgKHYtPm9iX2l2YWwgPj0gMCkKKyAgICAgICAgcmV0dXJuIGludF9pbnQodik7CisgICAgZWxzZQorICAgICAgICByZXR1cm4gaW50X25lZyh2KTsKK30KKworc3RhdGljIGludAoraW50X25vbnplcm8oUHlJbnRPYmplY3QgKnYpCit7CisgICAgcmV0dXJuIHYtPm9iX2l2YWwgIT0gMDsKK30KKworc3RhdGljIFB5T2JqZWN0ICoKK2ludF9pbnZlcnQoUHlJbnRPYmplY3QgKnYpCit7CisgICAgcmV0dXJuIFB5SW50X0Zyb21Mb25nKH52LT5vYl9pdmFsKTsKK30KKworc3RhdGljIFB5T2JqZWN0ICoKK2ludF9sc2hpZnQoUHlJbnRPYmplY3QgKnYsIFB5SW50T2JqZWN0ICp3KQoreworICAgIGxvbmcgYSwgYiwgYzsKKyAgICBQeU9iamVjdCAqdnYsICp3dywgKnJlc3VsdDsKKworICAgIENPTlZFUlRfVE9fTE9ORyh2LCBhKTsKKyAgICBDT05WRVJUX1RPX0xPTkcodywgYik7CisgICAgaWYgKGIgPCAwKSB7CisgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19WYWx1ZUVycm9yLCAibmVnYXRpdmUgc2hpZnQgY291bnQiKTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIGlmIChhID09IDAgfHwgYiA9PSAwKQorICAgICAgICByZXR1cm4gaW50X2ludCh2KTsKKyAgICBpZiAoYiA+PSBMT05HX0JJVCkgeworICAgICAgICB2diA9IFB5TG9uZ19Gcm9tTG9uZyhQeUludF9BU19MT05HKHYpKTsKKyAgICAgICAgaWYgKHZ2ID09IE5VTEwpCisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgd3cgPSBQeUxvbmdfRnJvbUxvbmcoUHlJbnRfQVNfTE9ORyh3KSk7CisgICAgICAgIGlmICh3dyA9PSBOVUxMKSB7CisgICAgICAgICAgICBQeV9ERUNSRUYodnYpOworICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgICAgIH0KKyAgICAgICAgcmVzdWx0ID0gUHlOdW1iZXJfTHNoaWZ0KHZ2LCB3dyk7CisgICAgICAgIFB5X0RFQ1JFRih2dik7CisgICAgICAgIFB5X0RFQ1JFRih3dyk7CisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorICAgIGMgPSBhIDw8IGI7CisgICAgaWYgKGEgIT0gUHlfQVJJVEhNRVRJQ19SSUdIVF9TSElGVChsb25nLCBjLCBiKSkgeworICAgICAgICB2diA9IFB5TG9uZ19Gcm9tTG9uZyhQeUludF9BU19MT05HKHYpKTsKKyAgICAgICAgaWYgKHZ2ID09IE5VTEwpCisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgd3cgPSBQeUxvbmdfRnJvbUxvbmcoUHlJbnRfQVNfTE9ORyh3KSk7CisgICAgICAgIGlmICh3dyA9PSBOVUxMKSB7CisgICAgICAgICAgICBQeV9ERUNSRUYodnYpOworICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgICAgIH0KKyAgICAgICAgcmVzdWx0ID0gUHlOdW1iZXJfTHNoaWZ0KHZ2LCB3dyk7CisgICAgICAgIFB5X0RFQ1JFRih2dik7CisgICAgICAgIFB5X0RFQ1JFRih3dyk7CisgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgfQorICAgIHJldHVybiBQeUludF9Gcm9tTG9uZyhjKTsKK30KKworc3RhdGljIFB5T2JqZWN0ICoKK2ludF9yc2hpZnQoUHlJbnRPYmplY3QgKnYsIFB5SW50T2JqZWN0ICp3KQoreworICAgIHJlZ2lzdGVyIGxvbmcgYSwgYjsKKyAgICBDT05WRVJUX1RPX0xPTkcodiwgYSk7CisgICAgQ09OVkVSVF9UT19MT05HKHcsIGIpOworICAgIGlmIChiIDwgMCkgeworICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfVmFsdWVFcnJvciwgIm5lZ2F0aXZlIHNoaWZ0IGNvdW50Iik7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICBpZiAoYSA9PSAwIHx8IGIgPT0gMCkKKyAgICAgICAgcmV0dXJuIGludF9pbnQodik7CisgICAgaWYgKGIgPj0gTE9OR19CSVQpIHsKKyAgICAgICAgaWYgKGEgPCAwKQorICAgICAgICAgICAgYSA9IC0xOworICAgICAgICBlbHNlCisgICAgICAgICAgICBhID0gMDsKKyAgICB9CisgICAgZWxzZSB7CisgICAgICAgIGEgPSBQeV9BUklUSE1FVElDX1JJR0hUX1NISUZUKGxvbmcsIGEsIGIpOworICAgIH0KKyAgICByZXR1cm4gUHlJbnRfRnJvbUxvbmcoYSk7Cit9CisKK3N0YXRpYyBQeU9iamVjdCAqCitpbnRfYW5kKFB5SW50T2JqZWN0ICp2LCBQeUludE9iamVjdCAqdykKK3sKKyAgICByZWdpc3RlciBsb25nIGEsIGI7CisgICAgQ09OVkVSVF9UT19MT05HKHYsIGEpOworICAgIENPTlZFUlRfVE9fTE9ORyh3LCBiKTsKKyAgICByZXR1cm4gUHlJbnRfRnJvbUxvbmcoYSAmIGIpOworfQorCitzdGF0aWMgUHlPYmplY3QgKgoraW50X3hvcihQeUludE9iamVjdCAqdiwgUHlJbnRPYmplY3QgKncpCit7CisgICAgcmVnaXN0ZXIgbG9uZyBhLCBiOworICAgIENPTlZFUlRfVE9fTE9ORyh2LCBhKTsKKyAgICBDT05WRVJUX1RPX0xPTkcodywgYik7CisgICAgcmV0dXJuIFB5SW50X0Zyb21Mb25nKGEgXiBiKTsKK30KKworc3RhdGljIFB5T2JqZWN0ICoKK2ludF9vcihQeUludE9iamVjdCAqdiwgUHlJbnRPYmplY3QgKncpCit7CisgICAgcmVnaXN0ZXIgbG9uZyBhLCBiOworICAgIENPTlZFUlRfVE9fTE9ORyh2LCBhKTsKKyAgICBDT05WRVJUX1RPX0xPTkcodywgYik7CisgICAgcmV0dXJuIFB5SW50X0Zyb21Mb25nKGEgfCBiKTsKK30KKworc3RhdGljIGludAoraW50X2NvZXJjZShQeU9iamVjdCAqKnB2LCBQeU9iamVjdCAqKnB3KQoreworICAgIGlmIChQeUludF9DaGVjaygqcHcpKSB7CisgICAgICAgIFB5X0lOQ1JFRigqcHYpOworICAgICAgICBQeV9JTkNSRUYoKnB3KTsKKyAgICAgICAgcmV0dXJuIDA7CisgICAgfQorICAgIHJldHVybiAxOyAvKiBDYW4ndCBkbyBpdCAqLworfQorCitzdGF0aWMgUHlPYmplY3QgKgoraW50X2ludChQeUludE9iamVjdCAqdikKK3sKKyAgICBpZiAoUHlJbnRfQ2hlY2tFeGFjdCh2KSkKKyAgICAgICAgUHlfSU5DUkVGKHYpOworICAgIGVsc2UKKyAgICAgICAgdiA9IChQeUludE9iamVjdCAqKVB5SW50X0Zyb21Mb25nKHYtPm9iX2l2YWwpOworICAgIHJldHVybiAoUHlPYmplY3QgKil2OworfQorCitzdGF0aWMgUHlPYmplY3QgKgoraW50X2xvbmcoUHlJbnRPYmplY3QgKnYpCit7CisgICAgcmV0dXJuIFB5TG9uZ19Gcm9tTG9uZygodiAtPiBvYl9pdmFsKSk7Cit9CisKK3N0YXRpYyBjb25zdCB1bnNpZ25lZCBjaGFyIEJpdExlbmd0aFRhYmxlWzMyXSA9IHsKKyAgICAwLCAxLCAyLCAyLCAzLCAzLCAzLCAzLCA0LCA0LCA0LCA0LCA0LCA0LCA0LCA0LAorICAgIDUsIDUsIDUsIDUsIDUsIDUsIDUsIDUsIDUsIDUsIDUsIDUsIDUsIDUsIDUsIDUKK307CisKK3N0YXRpYyBpbnQKK2JpdHNfaW5fdWxvbmcodW5zaWduZWQgbG9uZyBkKQoreworICAgIGludCBkX2JpdHMgPSAwOworICAgIHdoaWxlIChkID49IDMyKSB7CisgICAgICAgIGRfYml0cyArPSA2OworICAgICAgICBkID4+PSA2OworICAgIH0KKyAgICBkX2JpdHMgKz0gKGludClCaXRMZW5ndGhUYWJsZVtkXTsKKyAgICByZXR1cm4gZF9iaXRzOworfQorCisjaWYgOCpTSVpFT0ZfTE9ORy0xIDw9IERCTF9NQU5UX0RJRworLyogRXZlcnkgUHl0aG9uIGludCBjYW4gYmUgZXhhY3RseSByZXByZXNlbnRlZCBhcyBhIGZsb2F0LiAqLworCitzdGF0aWMgUHlPYmplY3QgKgoraW50X2Zsb2F0KFB5SW50T2JqZWN0ICp2KQoreworICAgIHJldHVybiBQeUZsb2F0X0Zyb21Eb3VibGUoKGRvdWJsZSkodiAtPiBvYl9pdmFsKSk7Cit9CisKKyNlbHNlCisvKiBIZXJlIG5vdCBhbGwgUHl0aG9uIGludHMgYXJlIGV4YWN0bHkgcmVwcmVzZW50YWJsZSBhcyBmbG9hdHMsIHNvIHdlIG1heQorICAgaGF2ZSB0byByb3VuZC4gIFdlIGRvIHRoaXMgbWFudWFsbHksIHNpbmNlIHRoZSBDIHN0YW5kYXJkcyBkb24ndCBzcGVjaWZ5CisgICB3aGV0aGVyIGNvbnZlcnRpbmcgYW4gaW50ZWdlciB0byBhIGZsb2F0IHJvdW5kcyB1cCBvciBkb3duICovCisKK3N0YXRpYyBQeU9iamVjdCAqCitpbnRfZmxvYXQoUHlJbnRPYmplY3QgKnYpCit7CisgICAgdW5zaWduZWQgbG9uZyBhYnNfaXZhbCwgbHNiOworICAgIGludCByb3VuZF91cDsKKworICAgIGlmICh2LT5vYl9pdmFsIDwgMCkKKyAgICAgICAgYWJzX2l2YWwgPSAwVS0odW5zaWduZWQgbG9uZyl2LT5vYl9pdmFsOworICAgIGVsc2UKKyAgICAgICAgYWJzX2l2YWwgPSAodW5zaWduZWQgbG9uZyl2LT5vYl9pdmFsOworICAgIGlmIChhYnNfaXZhbCA8ICgxTCA8PCBEQkxfTUFOVF9ESUcpKQorICAgICAgICAvKiBzbWFsbCBpbnRlZ2VyOyAgbm8gbmVlZCB0byByb3VuZCAqLworICAgICAgICByZXR1cm4gUHlGbG9hdF9Gcm9tRG91YmxlKChkb3VibGUpdi0+b2JfaXZhbCk7CisKKyAgICAvKiBSb3VuZCBhYnNfaXZhbCB0byBNQU5UX0RJRyBzaWduaWZpY2FudCBiaXRzLCB1c2luZyB0aGUKKyAgICAgICByb3VuZC1oYWxmLXRvLWV2ZW4gcnVsZS4gIGFic19pdmFsICYgbHNiIHBpY2tzIG91dCB0aGUgJ3JvdW5kaW5nJworICAgICAgIGJpdDogdGhlIGZpcnN0IGJpdCBhZnRlciB0aGUgbW9zdCBzaWduaWZpY2FudCBNQU5UX0RJRyBiaXRzIG9mCisgICAgICAgYWJzX2l2YWwuICBXZSByb3VuZCB1cCBpZiB0aGlzIGJpdCBpcyBzZXQsIHByb3ZpZGVkIHRoYXQgZWl0aGVyOgorCisgICAgICAgICAoMSkgYWJzX2l2YWwgaXNuJ3QgZXhhY3RseSBoYWxmd2F5IGJldHdlZW4gdHdvIGZsb2F0cywgaW4gd2hpY2gKKyAgICAgICAgIGNhc2UgYXQgbGVhc3Qgb25lIG9mIHRoZSBiaXRzIGZvbGxvd2luZyB0aGUgcm91bmRpbmcgYml0IG11c3QgYmUKKyAgICAgICAgIHNldDsgaS5lLiwgYWJzX2l2YWwgJiBsc2ItMSAhPSAwLCBvcjoKKworICAgICAgICAgKDIpIHRoZSByZXN1bHRpbmcgcm91bmRlZCB2YWx1ZSBoYXMgbGVhc3Qgc2lnbmlmaWNhbnQgYml0IDA7IG9yCisgICAgICAgICBpbiBvdGhlciB3b3JkcyB0aGUgYml0IGFib3ZlIHRoZSByb3VuZGluZyBiaXQgaXMgc2V0ICh0aGlzIGlzIHRoZQorICAgICAgICAgJ3RvLWV2ZW4nIGJpdCBvZiByb3VuZC1oYWxmLXRvLWV2ZW4pOyBpLmUuLCBhYnNfaXZhbCAmIDIqbHNiICE9IDAKKworICAgICAgIFRoZSBjb25kaXRpb24gIigxKSBvciAoMikiIGVxdWF0ZXMgdG8gYWJzX2l2YWwgJiAzKmxzYi0xICE9IDAuICovCisKKyAgICBsc2IgPSAxTCA8PCAoYml0c19pbl91bG9uZyhhYnNfaXZhbCktREJMX01BTlRfRElHLTEpOworICAgIHJvdW5kX3VwID0gKGFic19pdmFsICYgbHNiKSAmJiAoYWJzX2l2YWwgJiAoMypsc2ItMSkpOworICAgIGFic19pdmFsICY9IC0yKmxzYjsKKyAgICBpZiAocm91bmRfdXApCisgICAgICAgIGFic19pdmFsICs9IDIqbHNiOworICAgIHJldHVybiBQeUZsb2F0X0Zyb21Eb3VibGUodi0+b2JfaXZhbCA8IDAgPworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLShkb3VibGUpYWJzX2l2YWwgOgorICAgICAgICAgICAgICAgICAgKGRvdWJsZSlhYnNfaXZhbCk7Cit9CisKKyNlbmRpZgorCitzdGF0aWMgUHlPYmplY3QgKgoraW50X29jdChQeUludE9iamVjdCAqdikKK3sKKyAgICByZXR1cm4gX1B5SW50X0Zvcm1hdCh2LCA4LCAwKTsKK30KKworc3RhdGljIFB5T2JqZWN0ICoKK2ludF9oZXgoUHlJbnRPYmplY3QgKnYpCit7CisgICAgcmV0dXJuIF9QeUludF9Gb3JtYXQodiwgMTYsIDApOworfQorCitzdGF0aWMgUHlPYmplY3QgKgoraW50X3N1YnR5cGVfbmV3KFB5VHlwZU9iamVjdCAqdHlwZSwgUHlPYmplY3QgKmFyZ3MsIFB5T2JqZWN0ICprd2RzKTsKKworc3RhdGljIFB5T2JqZWN0ICoKK2ludF9uZXcoUHlUeXBlT2JqZWN0ICp0eXBlLCBQeU9iamVjdCAqYXJncywgUHlPYmplY3QgKmt3ZHMpCit7CisgICAgUHlPYmplY3QgKnggPSBOVUxMOworICAgIGludCBiYXNlID0gLTkwOTsKKyAgICBzdGF0aWMgY2hhciAqa3dsaXN0W10gPSB7IngiLCAiYmFzZSIsIDB9OworCisgICAgaWYgKHR5cGUgIT0gJlB5SW50X1R5cGUpCisgICAgICAgIHJldHVybiBpbnRfc3VidHlwZV9uZXcodHlwZSwgYXJncywga3dkcyk7IC8qIFdpbXAgb3V0ICovCisgICAgaWYgKCFQeUFyZ19QYXJzZVR1cGxlQW5kS2V5d29yZHMoYXJncywga3dkcywgInxPaTppbnQiLCBrd2xpc3QsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJngsICZiYXNlKSkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgaWYgKHggPT0gTlVMTCkgeworICAgICAgICBpZiAoYmFzZSAhPSAtOTA5KSB7CisgICAgICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfVHlwZUVycm9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICJpbnQoKSBtaXNzaW5nIHN0cmluZyBhcmd1bWVudCIpOworICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIFB5SW50X0Zyb21Mb25nKDBMKTsKKyAgICB9CisgICAgaWYgKGJhc2UgPT0gLTkwOSkKKyAgICAgICAgcmV0dXJuIFB5TnVtYmVyX0ludCh4KTsKKyAgICBpZiAoUHlTdHJpbmdfQ2hlY2soeCkpIHsKKyAgICAgICAgLyogU2luY2UgUHlJbnRfRnJvbVN0cmluZyBkb2Vzbid0IGhhdmUgYSBsZW5ndGggcGFyYW1ldGVyLAorICAgICAgICAgKiBjaGVjayBoZXJlIGZvciBwb3NzaWJsZSBOVUxzIGluIHRoZSBzdHJpbmcuICovCisgICAgICAgIGNoYXIgKnN0cmluZyA9IFB5U3RyaW5nX0FTX1NUUklORyh4KTsKKyAgICAgICAgaWYgKHN0cmxlbihzdHJpbmcpICE9IFB5U3RyaW5nX1NpemUoeCkpIHsKKyAgICAgICAgICAgIC8qIGNyZWF0ZSBhIHJlcHIoKSBvZiB0aGUgaW5wdXQgc3RyaW5nLAorICAgICAgICAgICAgICoganVzdCBsaWtlIFB5SW50X0Zyb21TdHJpbmcgZG9lcyAqLworICAgICAgICAgICAgUHlPYmplY3QgKnNyZXByOworICAgICAgICAgICAgc3JlcHIgPSBQeU9iamVjdF9SZXByKHgpOworICAgICAgICAgICAgaWYgKHNyZXByID09IE5VTEwpCisgICAgICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgICAgICAgICBQeUVycl9Gb3JtYXQoUHlFeGNfVmFsdWVFcnJvciwKKyAgICAgICAgICAgICAgICAgImludmFsaWQgbGl0ZXJhbCBmb3IgaW50KCkgd2l0aCBiYXNlICVkOiAlcyIsCisgICAgICAgICAgICAgICAgIGJhc2UsIFB5U3RyaW5nX0FTX1NUUklORyhzcmVwcikpOworICAgICAgICAgICAgUHlfREVDUkVGKHNyZXByKTsKKyAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgICAgICB9CisgICAgICAgIHJldHVybiBQeUludF9Gcm9tU3RyaW5nKHN0cmluZywgTlVMTCwgYmFzZSk7CisgICAgfQorI2lmZGVmIFB5X1VTSU5HX1VOSUNPREUKKyAgICBpZiAoUHlVbmljb2RlX0NoZWNrKHgpKQorICAgICAgICByZXR1cm4gUHlJbnRfRnJvbVVuaWNvZGUoUHlVbmljb2RlX0FTX1VOSUNPREUoeCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQeVVuaWNvZGVfR0VUX1NJWkUoeCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiYXNlKTsKKyNlbmRpZgorICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19UeXBlRXJyb3IsCisgICAgICAgICAgICAgICAgICAgICJpbnQoKSBjYW4ndCBjb252ZXJ0IG5vbi1zdHJpbmcgd2l0aCBleHBsaWNpdCBiYXNlIik7CisgICAgcmV0dXJuIE5VTEw7Cit9CisKKy8qIFdpbXB5LCBzbG93IGFwcHJvYWNoIHRvIHRwX25ldyBjYWxscyBmb3Igc3VidHlwZXMgb2YgaW50OgorICAgZmlyc3QgY3JlYXRlIGEgcmVndWxhciBpbnQgZnJvbSB3aGF0ZXZlciBhcmd1bWVudHMgd2UgZ290LAorICAgdGhlbiBhbGxvY2F0ZSBhIHN1YnR5cGUgaW5zdGFuY2UgYW5kIGluaXRpYWxpemUgaXRzIG9iX2l2YWwKKyAgIGZyb20gdGhlIHJlZ3VsYXIgaW50LiAgVGhlIHJlZ3VsYXIgaW50IGlzIHRoZW4gdGhyb3duIGF3YXkuCisqLworc3RhdGljIFB5T2JqZWN0ICoKK2ludF9zdWJ0eXBlX25ldyhQeVR5cGVPYmplY3QgKnR5cGUsIFB5T2JqZWN0ICphcmdzLCBQeU9iamVjdCAqa3dkcykKK3sKKyAgICBQeU9iamVjdCAqdG1wLCAqbmV3b2JqOworICAgIGxvbmcgaXZhbDsKKworICAgIGFzc2VydChQeVR5cGVfSXNTdWJ0eXBlKHR5cGUsICZQeUludF9UeXBlKSk7CisgICAgdG1wID0gaW50X25ldygmUHlJbnRfVHlwZSwgYXJncywga3dkcyk7CisgICAgaWYgKHRtcCA9PSBOVUxMKQorICAgICAgICByZXR1cm4gTlVMTDsKKyAgICBpZiAoIVB5SW50X0NoZWNrKHRtcCkpIHsKKyAgICAgICAgaXZhbCA9IFB5TG9uZ19Bc0xvbmcodG1wKTsKKyAgICAgICAgaWYgKGl2YWwgPT0gLTEgJiYgUHlFcnJfT2NjdXJyZWQoKSkgeworICAgICAgICAgICAgUHlfREVDUkVGKHRtcCk7CisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgfQorICAgIH0gZWxzZSB7CisgICAgICAgIGl2YWwgPSAoKFB5SW50T2JqZWN0ICopdG1wKS0+b2JfaXZhbDsKKyAgICB9CisKKyAgICBuZXdvYmogPSB0eXBlLT50cF9hbGxvYyh0eXBlLCAwKTsKKyAgICBpZiAobmV3b2JqID09IE5VTEwpIHsKKyAgICAgICAgUHlfREVDUkVGKHRtcCk7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICAoKFB5SW50T2JqZWN0ICopbmV3b2JqKS0+b2JfaXZhbCA9IGl2YWw7CisgICAgUHlfREVDUkVGKHRtcCk7CisgICAgcmV0dXJuIG5ld29iajsKK30KKworc3RhdGljIFB5T2JqZWN0ICoKK2ludF9nZXRuZXdhcmdzKFB5SW50T2JqZWN0ICp2KQoreworICAgIHJldHVybiBQeV9CdWlsZFZhbHVlKCIobCkiLCB2LT5vYl9pdmFsKTsKK30KKworc3RhdGljIFB5T2JqZWN0ICoKK2ludF9nZXQwKFB5SW50T2JqZWN0ICp2LCB2b2lkICpjb250ZXh0KSB7CisgICAgcmV0dXJuIFB5SW50X0Zyb21Mb25nKDBMKTsKK30KKworc3RhdGljIFB5T2JqZWN0ICoKK2ludF9nZXQxKFB5SW50T2JqZWN0ICp2LCB2b2lkICpjb250ZXh0KSB7CisgICAgcmV0dXJuIFB5SW50X0Zyb21Mb25nKDFMKTsKK30KKworLyogQ29udmVydCBhbiBpbnRlZ2VyIHRvIGEgZGVjaW1hbCBzdHJpbmcuICBPbiBtYW55IHBsYXRmb3JtcywgdGhpcworICAgd2lsbCBiZSBzaWduaWZpY2FudGx5IGZhc3RlciB0aGFuIHRoZSBnZW5lcmFsIGFyYml0cmFyeS1iYXNlCisgICBjb252ZXJzaW9uIG1hY2hpbmVyeSBpbiBfUHlJbnRfRm9ybWF0LCB0aGFua3MgdG8gb3B0aW1pemF0aW9uCisgICBvcHBvcnR1bml0aWVzIG9mZmVyZWQgYnkgZGl2aXNpb24gYnkgYSBjb21waWxlLXRpbWUgY29uc3RhbnQuICovCitzdGF0aWMgUHlPYmplY3QgKgoraW50X3RvX2RlY2ltYWxfc3RyaW5nKFB5SW50T2JqZWN0ICp2KSB7CisgICAgY2hhciBidWZbc2l6ZW9mKGxvbmcpKkNIQVJfQklULzMrNl0sICpwLCAqYnVmZW5kOworICAgIGxvbmcgbiA9IHYtPm9iX2l2YWw7CisgICAgdW5zaWduZWQgbG9uZyBhYnNuOworICAgIHAgPSBidWZlbmQgPSBidWYgKyBzaXplb2YoYnVmKTsKKyAgICBhYnNuID0gbiA8IDAgPyAwVUwgLSBuIDogbjsKKyAgICBkbyB7CisgICAgICAgICotLXAgPSAnMCcgKyAoY2hhcikoYWJzbiAlIDEwKTsKKyAgICAgICAgYWJzbiAvPSAxMDsKKyAgICB9IHdoaWxlIChhYnNuKTsKKyAgICBpZiAobiA8IDApCisgICAgICAgICotLXAgPSAnLSc7CisgICAgcmV0dXJuIFB5U3RyaW5nX0Zyb21TdHJpbmdBbmRTaXplKHAsIGJ1ZmVuZCAtIHApOworfQorCisvKiBDb252ZXJ0IGFuIGludGVnZXIgdG8gdGhlIGdpdmVuIGJhc2UuICBSZXR1cm5zIGEgc3RyaW5nLgorICAgSWYgYmFzZSBpcyAyLCA4IG9yIDE2LCBhZGQgdGhlIHByb3BlciBwcmVmaXggJzBiJywgJzBvJyBvciAnMHgnLgorICAgSWYgbmV3c3R5bGUgaXMgemVybywgdGhlbiB1c2UgdGhlIHByZS0yLjYgYmVoYXZpb3Igb2Ygb2N0YWwgaGF2aW5nCisgICBhIGxlYWRpbmcgIjAiICovCitQeUFQSV9GVU5DKFB5T2JqZWN0KikKK19QeUludF9Gb3JtYXQoUHlJbnRPYmplY3QgKnYsIGludCBiYXNlLCBpbnQgbmV3c3R5bGUpCit7CisgICAgLyogVGhlcmUgYXJlIG5vIGRvdWJ0IG1hbnksIG1hbnkgd2F5cyB0byBvcHRpbWl6ZSB0aGlzLCB1c2luZyBjb2RlCisgICAgICAgc2ltaWxhciB0byBfUHlMb25nX0Zvcm1hdCAqLworICAgIGxvbmcgbiA9IHYtPm9iX2l2YWw7CisgICAgaW50ICBuZWdhdGl2ZSA9IG4gPCAwOworICAgIGludCBpc196ZXJvID0gbiA9PSAwOworCisgICAgLyogRm9yIHRoZSByZWFzb25pbmcgYmVoaW5kIHRoaXMgc2l6ZSwgc2VlCisgICAgICAgaHR0cDovL2MtZmFxLmNvbS9taXNjL2hleGlvLmh0bWwuIFRoZW4sIGFkZCBhIGZldyBieXRlcyBmb3IKKyAgICAgICB0aGUgcG9zc2libGUgc2lnbiBhbmQgcHJlZml4ICIwW2JveF0iICovCisgICAgY2hhciBidWZbc2l6ZW9mKG4pKkNIQVJfQklUKzZdOworCisgICAgLyogU3RhcnQgYnkgcG9pbnRpbmcgdG8gdGhlIGVuZCBvZiB0aGUgYnVmZmVyLiAgV2UgZmlsbCBpbiBmcm9tCisgICAgICAgdGhlIGJhY2sgZm9yd2FyZC4gKi8KKyAgICBjaGFyKiBwID0gJmJ1ZltzaXplb2YoYnVmKV07CisKKyAgICBhc3NlcnQoYmFzZSA+PSAyICYmIGJhc2UgPD0gMzYpOworCisgICAgLyogU3BlY2lhbCBjYXNlIGJhc2UgMTAsIGZvciBzcGVlZCAqLworICAgIGlmIChiYXNlID09IDEwKQorICAgICAgICByZXR1cm4gaW50X3RvX2RlY2ltYWxfc3RyaW5nKHYpOworCisgICAgZG8geworICAgICAgICAvKiBJJ2QgdXNlIGlfZGl2bW9kLCBleGNlcHQgaXQgZG9lc24ndCBwcm9kdWNlIHRoZSByZXN1bHRzCisgICAgICAgICAgIEkgd2FudCB3aGVuIG4gaXMgbmVnYXRpdmUuICBTbyBqdXN0IGR1cGxpY2F0ZSB0aGUgc2FsaWVudAorICAgICAgICAgICBwYXJ0IGhlcmUuICovCisgICAgICAgIGxvbmcgZGl2ID0gbiAvIGJhc2U7CisgICAgICAgIGxvbmcgbW9kID0gbiAtIGRpdiAqIGJhc2U7CisKKyAgICAgICAgLyogY29udmVydCBhYnMobW9kKSB0byB0aGUgcmlnaHQgY2hhcmFjdGVyIGluIFswLTksIGEtel0gKi8KKyAgICAgICAgY2hhciBjZGlnaXQgPSAoY2hhcikobW9kIDwgMCA/IC1tb2QgOiBtb2QpOworICAgICAgICBjZGlnaXQgKz0gKGNkaWdpdCA8IDEwKSA/ICcwJyA6ICdhJy0xMDsKKyAgICAgICAgKi0tcCA9IGNkaWdpdDsKKworICAgICAgICBuID0gZGl2OworICAgIH0gd2hpbGUobik7CisKKyAgICBpZiAoYmFzZSA9PSAyKSB7CisgICAgICAgICotLXAgPSAnYic7CisgICAgICAgICotLXAgPSAnMCc7CisgICAgfQorICAgIGVsc2UgaWYgKGJhc2UgPT0gOCkgeworICAgICAgICBpZiAobmV3c3R5bGUpIHsKKyAgICAgICAgICAgICotLXAgPSAnbyc7CisgICAgICAgICAgICAqLS1wID0gJzAnOworICAgICAgICB9CisgICAgICAgIGVsc2UKKyAgICAgICAgICAgIGlmICghaXNfemVybykKKyAgICAgICAgICAgICAgICAqLS1wID0gJzAnOworICAgIH0KKyAgICBlbHNlIGlmIChiYXNlID09IDE2KSB7CisgICAgICAgICotLXAgPSAneCc7CisgICAgICAgICotLXAgPSAnMCc7CisgICAgfQorICAgIGVsc2UgeworICAgICAgICAqLS1wID0gJyMnOworICAgICAgICAqLS1wID0gJzAnICsgYmFzZSUxMDsKKyAgICAgICAgaWYgKGJhc2UgPiAxMCkKKyAgICAgICAgICAgICotLXAgPSAnMCcgKyBiYXNlLzEwOworICAgIH0KKyAgICBpZiAobmVnYXRpdmUpCisgICAgICAgICotLXAgPSAnLSc7CisKKyAgICByZXR1cm4gUHlTdHJpbmdfRnJvbVN0cmluZ0FuZFNpemUocCwgJmJ1ZltzaXplb2YoYnVmKV0gLSBwKTsKK30KKworc3RhdGljIFB5T2JqZWN0ICoKK2ludF9fZm9ybWF0X18oUHlPYmplY3QgKnNlbGYsIFB5T2JqZWN0ICphcmdzKQoreworICAgIFB5T2JqZWN0ICpmb3JtYXRfc3BlYzsKKworICAgIGlmICghUHlBcmdfUGFyc2VUdXBsZShhcmdzLCAiTzpfX2Zvcm1hdF9fIiwgJmZvcm1hdF9zcGVjKSkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgaWYgKFB5Qnl0ZXNfQ2hlY2soZm9ybWF0X3NwZWMpKQorICAgICAgICByZXR1cm4gX1B5SW50X0Zvcm1hdEFkdmFuY2VkKHNlbGYsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHlCeXRlc19BU19TVFJJTkcoZm9ybWF0X3NwZWMpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFB5Qnl0ZXNfR0VUX1NJWkUoZm9ybWF0X3NwZWMpKTsKKyAgICBpZiAoUHlVbmljb2RlX0NoZWNrKGZvcm1hdF9zcGVjKSkgeworICAgICAgICAvKiBDb252ZXJ0IGZvcm1hdF9zcGVjIHRvIGEgc3RyICovCisgICAgICAgIFB5T2JqZWN0ICpyZXN1bHQ7CisgICAgICAgIFB5T2JqZWN0ICpzdHJfc3BlYyA9IFB5T2JqZWN0X1N0cihmb3JtYXRfc3BlYyk7CisKKyAgICAgICAgaWYgKHN0cl9zcGVjID09IE5VTEwpCisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKworICAgICAgICByZXN1bHQgPSBfUHlJbnRfRm9ybWF0QWR2YW5jZWQoc2VsZiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFB5Qnl0ZXNfQVNfU1RSSU5HKHN0cl9zcGVjKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFB5Qnl0ZXNfR0VUX1NJWkUoc3RyX3NwZWMpKTsKKworICAgICAgICBQeV9ERUNSRUYoc3RyX3NwZWMpOworICAgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKyAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfVHlwZUVycm9yLCAiX19mb3JtYXRfXyByZXF1aXJlcyBzdHIgb3IgdW5pY29kZSIpOworICAgIHJldHVybiBOVUxMOworfQorCitzdGF0aWMgUHlPYmplY3QgKgoraW50X2JpdF9sZW5ndGgoUHlJbnRPYmplY3QgKnYpCit7CisgICAgdW5zaWduZWQgbG9uZyBuOworCisgICAgaWYgKHYtPm9iX2l2YWwgPCAwKQorICAgICAgICAvKiBhdm9pZCB1bmRlZmluZWQgYmVoYXZpb3VyIHdoZW4gdi0+b2JfaXZhbCA9PSAtTE9OR19NQVgtMSAqLworICAgICAgICBuID0gMFUtKHVuc2lnbmVkIGxvbmcpdi0+b2JfaXZhbDsKKyAgICBlbHNlCisgICAgICAgIG4gPSAodW5zaWduZWQgbG9uZyl2LT5vYl9pdmFsOworCisgICAgcmV0dXJuIFB5SW50X0Zyb21Mb25nKGJpdHNfaW5fdWxvbmcobikpOworfQorCitQeURvY19TVFJWQVIoaW50X2JpdF9sZW5ndGhfZG9jLAorImludC5iaXRfbGVuZ3RoKCkgLT4gaW50XG5cCitcblwKK051bWJlciBvZiBiaXRzIG5lY2Vzc2FyeSB0byByZXByZXNlbnQgc2VsZiBpbiBiaW5hcnkuXG5cCis+Pj4gYmluKDM3KVxuXAorJzBiMTAwMTAxJ1xuXAorPj4+ICgzNykuYml0X2xlbmd0aCgpXG5cCis2Iik7CisKKyNpZiAwCitzdGF0aWMgUHlPYmplY3QgKgoraW50X2lzX2Zpbml0ZShQeU9iamVjdCAqdikKK3sKKyAgICBQeV9SRVRVUk5fVFJVRTsKK30KKyNlbmRpZgorCitzdGF0aWMgUHlNZXRob2REZWYgaW50X21ldGhvZHNbXSA9IHsKKyAgICB7ImNvbmp1Z2F0ZSIsICAgICAgIChQeUNGdW5jdGlvbilpbnRfaW50LCAgIE1FVEhfTk9BUkdTLAorICAgICAiUmV0dXJucyBzZWxmLCB0aGUgY29tcGxleCBjb25qdWdhdGUgb2YgYW55IGludC4ifSwKKyAgICB7ImJpdF9sZW5ndGgiLCAoUHlDRnVuY3Rpb24paW50X2JpdF9sZW5ndGgsIE1FVEhfTk9BUkdTLAorICAgICBpbnRfYml0X2xlbmd0aF9kb2N9LAorI2lmIDAKKyAgICB7ImlzX2Zpbml0ZSIsICAgICAgIChQeUNGdW5jdGlvbilpbnRfaXNfZmluaXRlLCAgICAgTUVUSF9OT0FSR1MsCisgICAgICJSZXR1cm5zIGFsd2F5cyBUcnVlLiJ9LAorI2VuZGlmCisgICAgeyJfX3RydW5jX18iLCAgICAgICAoUHlDRnVuY3Rpb24paW50X2ludCwgICBNRVRIX05PQVJHUywKKyAgICAgIlRydW5jYXRpbmcgYW4gSW50ZWdyYWwgcmV0dXJucyBpdHNlbGYuIn0sCisgICAgeyJfX2dldG5ld2FyZ3NfXyIsICAgICAgICAgIChQeUNGdW5jdGlvbilpbnRfZ2V0bmV3YXJncywgICAgTUVUSF9OT0FSR1N9LAorICAgIHsiX19mb3JtYXRfXyIsIChQeUNGdW5jdGlvbilpbnRfX2Zvcm1hdF9fLCBNRVRIX1ZBUkFSR1N9LAorICAgIHtOVUxMLCAgICAgICAgICAgICAgTlVMTH0gICAgICAgICAgIC8qIHNlbnRpbmVsICovCit9OworCitzdGF0aWMgUHlHZXRTZXREZWYgaW50X2dldHNldFtdID0geworICAgIHsicmVhbCIsCisgICAgIChnZXR0ZXIpaW50X2ludCwgKHNldHRlcilOVUxMLAorICAgICAidGhlIHJlYWwgcGFydCBvZiBhIGNvbXBsZXggbnVtYmVyIiwKKyAgICAgTlVMTH0sCisgICAgeyJpbWFnIiwKKyAgICAgKGdldHRlcilpbnRfZ2V0MCwgKHNldHRlcilOVUxMLAorICAgICAidGhlIGltYWdpbmFyeSBwYXJ0IG9mIGEgY29tcGxleCBudW1iZXIiLAorICAgICBOVUxMfSwKKyAgICB7Im51bWVyYXRvciIsCisgICAgIChnZXR0ZXIpaW50X2ludCwgKHNldHRlcilOVUxMLAorICAgICAidGhlIG51bWVyYXRvciBvZiBhIHJhdGlvbmFsIG51bWJlciBpbiBsb3dlc3QgdGVybXMiLAorICAgICBOVUxMfSwKKyAgICB7ImRlbm9taW5hdG9yIiwKKyAgICAgKGdldHRlcilpbnRfZ2V0MSwgKHNldHRlcilOVUxMLAorICAgICAidGhlIGRlbm9taW5hdG9yIG9mIGEgcmF0aW9uYWwgbnVtYmVyIGluIGxvd2VzdCB0ZXJtcyIsCisgICAgIE5VTEx9LAorICAgIHtOVUxMfSAgLyogU2VudGluZWwgKi8KK307CisKK1B5RG9jX1NUUlZBUihpbnRfZG9jLAorImludCh4PTApIC0+IGludCBvciBsb25nXG5cCitpbnQoeCwgYmFzZT0xMCkgLT4gaW50IG9yIGxvbmdcblwKK1xuXAorQ29udmVydCBhIG51bWJlciBvciBzdHJpbmcgdG8gYW4gaW50ZWdlciwgb3IgcmV0dXJuIDAgaWYgbm8gYXJndW1lbnRzXG5cCithcmUgZ2l2ZW4uICBJZiB4IGlzIGZsb2F0aW5nIHBvaW50LCB0aGUgY29udmVyc2lvbiB0cnVuY2F0ZXMgdG93YXJkcyB6ZXJvLlxuXAorSWYgeCBpcyBvdXRzaWRlIHRoZSBpbnRlZ2VyIHJhbmdlLCB0aGUgZnVuY3Rpb24gcmV0dXJucyBhIGxvbmcgaW5zdGVhZC5cblwKK1xuXAorSWYgeCBpcyBub3QgYSBudW1iZXIgb3IgaWYgYmFzZSBpcyBnaXZlbiwgdGhlbiB4IG11c3QgYmUgYSBzdHJpbmcgb3JcblwKK1VuaWNvZGUgb2JqZWN0IHJlcHJlc2VudGluZyBhbiBpbnRlZ2VyIGxpdGVyYWwgaW4gdGhlIGdpdmVuIGJhc2UuICBUaGVcblwKK2xpdGVyYWwgY2FuIGJlIHByZWNlZGVkIGJ5ICcrJyBvciAnLScgYW5kIGJlIHN1cnJvdW5kZWQgYnkgd2hpdGVzcGFjZS5cblwKK1RoZSBiYXNlIGRlZmF1bHRzIHRvIDEwLiAgVmFsaWQgYmFzZXMgYXJlIDAgYW5kIDItMzYuICBCYXNlIDAgbWVhbnMgdG9cblwKK2ludGVycHJldCB0aGUgYmFzZSBmcm9tIHRoZSBzdHJpbmcgYXMgYW4gaW50ZWdlciBsaXRlcmFsLlxuXAorPj4+IGludCgnMGIxMDAnLCBiYXNlPTApXG5cCis0Iik7CisKK3N0YXRpYyBQeU51bWJlck1ldGhvZHMgaW50X2FzX251bWJlciA9IHsKKyAgICAoYmluYXJ5ZnVuYylpbnRfYWRkLCAgICAgICAgLypuYl9hZGQqLworICAgIChiaW5hcnlmdW5jKWludF9zdWIsICAgICAgICAvKm5iX3N1YnRyYWN0Ki8KKyAgICAoYmluYXJ5ZnVuYylpbnRfbXVsLCAgICAgICAgLypuYl9tdWx0aXBseSovCisgICAgKGJpbmFyeWZ1bmMpaW50X2NsYXNzaWNfZGl2LCAvKm5iX2RpdmlkZSovCisgICAgKGJpbmFyeWZ1bmMpaW50X21vZCwgICAgICAgIC8qbmJfcmVtYWluZGVyKi8KKyAgICAoYmluYXJ5ZnVuYylpbnRfZGl2bW9kLCAgICAgLypuYl9kaXZtb2QqLworICAgICh0ZXJuYXJ5ZnVuYylpbnRfcG93LCAgICAgICAvKm5iX3Bvd2VyKi8KKyAgICAodW5hcnlmdW5jKWludF9uZWcsICAgICAgICAgLypuYl9uZWdhdGl2ZSovCisgICAgKHVuYXJ5ZnVuYylpbnRfaW50LCAgICAgICAgIC8qbmJfcG9zaXRpdmUqLworICAgICh1bmFyeWZ1bmMpaW50X2FicywgICAgICAgICAvKm5iX2Fic29sdXRlKi8KKyAgICAoaW5xdWlyeSlpbnRfbm9uemVybywgICAgICAgLypuYl9ub256ZXJvKi8KKyAgICAodW5hcnlmdW5jKWludF9pbnZlcnQsICAgICAgLypuYl9pbnZlcnQqLworICAgIChiaW5hcnlmdW5jKWludF9sc2hpZnQsICAgICAvKm5iX2xzaGlmdCovCisgICAgKGJpbmFyeWZ1bmMpaW50X3JzaGlmdCwgICAgIC8qbmJfcnNoaWZ0Ki8KKyAgICAoYmluYXJ5ZnVuYylpbnRfYW5kLCAgICAgICAgLypuYl9hbmQqLworICAgIChiaW5hcnlmdW5jKWludF94b3IsICAgICAgICAvKm5iX3hvciovCisgICAgKGJpbmFyeWZ1bmMpaW50X29yLCAgICAgICAgIC8qbmJfb3IqLworICAgIGludF9jb2VyY2UsICAgICAgICAgICAgICAgICAvKm5iX2NvZXJjZSovCisgICAgKHVuYXJ5ZnVuYylpbnRfaW50LCAgICAgICAgIC8qbmJfaW50Ki8KKyAgICAodW5hcnlmdW5jKWludF9sb25nLCAgICAgICAgLypuYl9sb25nKi8KKyAgICAodW5hcnlmdW5jKWludF9mbG9hdCwgICAgICAgLypuYl9mbG9hdCovCisgICAgKHVuYXJ5ZnVuYylpbnRfb2N0LCAgICAgICAgIC8qbmJfb2N0Ki8KKyAgICAodW5hcnlmdW5jKWludF9oZXgsICAgICAgICAgLypuYl9oZXgqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAvKm5iX2lucGxhY2VfYWRkKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgLypuYl9pbnBsYWNlX3N1YnRyYWN0Ki8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgLypuYl9pbnBsYWNlX211bHRpcGx5Ki8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgLypuYl9pbnBsYWNlX2RpdmlkZSovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgIC8qbmJfaW5wbGFjZV9yZW1haW5kZXIqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAvKm5iX2lucGxhY2VfcG93ZXIqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAvKm5iX2lucGxhY2VfbHNoaWZ0Ki8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgLypuYl9pbnBsYWNlX3JzaGlmdCovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgIC8qbmJfaW5wbGFjZV9hbmQqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAvKm5iX2lucGxhY2VfeG9yKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgLypuYl9pbnBsYWNlX29yKi8KKyAgICAoYmluYXJ5ZnVuYylpbnRfZGl2LCAgICAgICAgLyogbmJfZmxvb3JfZGl2aWRlICovCisgICAgKGJpbmFyeWZ1bmMpaW50X3RydWVfZGl2aWRlLCAvKiBuYl90cnVlX2RpdmlkZSAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBuYl9pbnBsYWNlX2Zsb29yX2RpdmlkZSAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBuYl9pbnBsYWNlX3RydWVfZGl2aWRlICovCisgICAgKHVuYXJ5ZnVuYylpbnRfaW50LCAgICAgICAgIC8qIG5iX2luZGV4ICovCit9OworCitQeVR5cGVPYmplY3QgUHlJbnRfVHlwZSA9IHsKKyAgICBQeVZhck9iamVjdF9IRUFEX0lOSVQoJlB5VHlwZV9UeXBlLCAwKQorICAgICJpbnQiLAorICAgIHNpemVvZihQeUludE9iamVjdCksCisgICAgMCwKKyAgICAoZGVzdHJ1Y3RvcilpbnRfZGVhbGxvYywgICAgICAgICAgICAgICAgICAgIC8qIHRwX2RlYWxsb2MgKi8KKyAgICAocHJpbnRmdW5jKWludF9wcmludCwgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3ByaW50ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9nZXRhdHRyICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9zZXRhdHRyICovCisgICAgKGNtcGZ1bmMpaW50X2NvbXBhcmUsICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9jb21wYXJlICovCisgICAgKHJlcHJmdW5jKWludF90b19kZWNpbWFsX3N0cmluZywgICAgICAgICAgICAvKiB0cF9yZXByICovCisgICAgJmludF9hc19udW1iZXIsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9hc19udW1iZXIgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2FzX3NlcXVlbmNlICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9hc19tYXBwaW5nICovCisgICAgKGhhc2hmdW5jKWludF9oYXNoLCAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9oYXNoICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9jYWxsICovCisgICAgKHJlcHJmdW5jKWludF90b19kZWNpbWFsX3N0cmluZywgICAgICAgICAgICAvKiB0cF9zdHIgKi8KKyAgICBQeU9iamVjdF9HZW5lcmljR2V0QXR0ciwgICAgICAgICAgICAgICAgICAgIC8qIHRwX2dldGF0dHJvICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9zZXRhdHRybyAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfYXNfYnVmZmVyICovCisgICAgUHlfVFBGTEFHU19ERUZBVUxUIHwgUHlfVFBGTEFHU19DSEVDS1RZUEVTIHwKKyAgICAgICAgUHlfVFBGTEFHU19CQVNFVFlQRSB8IFB5X1RQRkxBR1NfSU5UX1NVQkNMQVNTLCAgICAgICAgICAvKiB0cF9mbGFncyAqLworICAgIGludF9kb2MsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZG9jICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF90cmF2ZXJzZSAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfY2xlYXIgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3JpY2hjb21wYXJlICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF93ZWFrbGlzdG9mZnNldCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfaXRlciAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfaXRlcm5leHQgKi8KKyAgICBpbnRfbWV0aG9kcywgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX21ldGhvZHMgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX21lbWJlcnMgKi8KKyAgICBpbnRfZ2V0c2V0LCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2dldHNldCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfYmFzZSAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZGljdCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZGVzY3JfZ2V0ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9kZXNjcl9zZXQgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2RpY3RvZmZzZXQgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2luaXQgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2FsbG9jICovCisgICAgaW50X25ldywgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9uZXcgKi8KKyAgICAoZnJlZWZ1bmMpaW50X2ZyZWUsICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2ZyZWUgKi8KK307CisKK2ludAorX1B5SW50X0luaXQodm9pZCkKK3sKKyAgICBQeUludE9iamVjdCAqdjsKKyAgICBpbnQgaXZhbDsKKyNpZiBOU01BTExORUdJTlRTICsgTlNNQUxMUE9TSU5UUyA+IDAKKyAgICBmb3IgKGl2YWwgPSAtTlNNQUxMTkVHSU5UUzsgaXZhbCA8IE5TTUFMTFBPU0lOVFM7IGl2YWwrKykgeworICAgICAgICAgIGlmICghZnJlZV9saXN0ICYmIChmcmVlX2xpc3QgPSBmaWxsX2ZyZWVfbGlzdCgpKSA9PSBOVUxMKQorICAgICAgICAgICAgICAgICAgICByZXR1cm4gMDsKKyAgICAgICAgLyogUHlPYmplY3RfTmV3IGlzIGlubGluZWQgKi8KKyAgICAgICAgdiA9IGZyZWVfbGlzdDsKKyAgICAgICAgZnJlZV9saXN0ID0gKFB5SW50T2JqZWN0ICopUHlfVFlQRSh2KTsKKyAgICAgICAgUHlPYmplY3RfSU5JVCh2LCAmUHlJbnRfVHlwZSk7CisgICAgICAgIHYtPm9iX2l2YWwgPSBpdmFsOworICAgICAgICBzbWFsbF9pbnRzW2l2YWwgKyBOU01BTExORUdJTlRTXSA9IHY7CisgICAgfQorI2VuZGlmCisgICAgcmV0dXJuIDE7Cit9CisKK2ludAorUHlJbnRfQ2xlYXJGcmVlTGlzdCh2b2lkKQoreworICAgIFB5SW50T2JqZWN0ICpwOworICAgIFB5SW50QmxvY2sgKmxpc3QsICpuZXh0OworICAgIGludCBpOworICAgIGludCB1OyAgICAgICAgICAgICAgICAgICAgICAvKiByZW1haW5pbmcgdW5mcmVlZCBpbnRzIHBlciBibG9jayAqLworICAgIGludCBmcmVlbGlzdF9zaXplID0gMDsKKworICAgIGxpc3QgPSBibG9ja19saXN0OworICAgIGJsb2NrX2xpc3QgPSBOVUxMOworICAgIGZyZWVfbGlzdCA9IE5VTEw7CisgICAgd2hpbGUgKGxpc3QgIT0gTlVMTCkgeworICAgICAgICB1ID0gMDsKKyAgICAgICAgZm9yIChpID0gMCwgcCA9ICZsaXN0LT5vYmplY3RzWzBdOworICAgICAgICAgICAgIGkgPCBOX0lOVE9CSkVDVFM7CisgICAgICAgICAgICAgaSsrLCBwKyspIHsKKyAgICAgICAgICAgIGlmIChQeUludF9DaGVja0V4YWN0KHApICYmIHAtPm9iX3JlZmNudCAhPSAwKQorICAgICAgICAgICAgICAgIHUrKzsKKyAgICAgICAgfQorICAgICAgICBuZXh0ID0gbGlzdC0+bmV4dDsKKyAgICAgICAgaWYgKHUpIHsKKyAgICAgICAgICAgIGxpc3QtPm5leHQgPSBibG9ja19saXN0OworICAgICAgICAgICAgYmxvY2tfbGlzdCA9IGxpc3Q7CisgICAgICAgICAgICBmb3IgKGkgPSAwLCBwID0gJmxpc3QtPm9iamVjdHNbMF07CisgICAgICAgICAgICAgICAgIGkgPCBOX0lOVE9CSkVDVFM7CisgICAgICAgICAgICAgICAgIGkrKywgcCsrKSB7CisgICAgICAgICAgICAgICAgaWYgKCFQeUludF9DaGVja0V4YWN0KHApIHx8CisgICAgICAgICAgICAgICAgICAgIHAtPm9iX3JlZmNudCA9PSAwKSB7CisgICAgICAgICAgICAgICAgICAgIFB5X1RZUEUocCkgPSAoc3RydWN0IF90eXBlb2JqZWN0ICopCisgICAgICAgICAgICAgICAgICAgICAgICBmcmVlX2xpc3Q7CisgICAgICAgICAgICAgICAgICAgIGZyZWVfbGlzdCA9IHA7CisgICAgICAgICAgICAgICAgfQorI2lmIE5TTUFMTE5FR0lOVFMgKyBOU01BTExQT1NJTlRTID4gMAorICAgICAgICAgICAgICAgIGVsc2UgaWYgKC1OU01BTExORUdJTlRTIDw9IHAtPm9iX2l2YWwgJiYKKyAgICAgICAgICAgICAgICAgICAgICAgICBwLT5vYl9pdmFsIDwgTlNNQUxMUE9TSU5UUyAmJgorICAgICAgICAgICAgICAgICAgICAgICAgIHNtYWxsX2ludHNbcC0+b2JfaXZhbCArCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOU01BTExORUdJTlRTXSA9PSBOVUxMKSB7CisgICAgICAgICAgICAgICAgICAgIFB5X0lOQ1JFRihwKTsKKyAgICAgICAgICAgICAgICAgICAgc21hbGxfaW50c1twLT5vYl9pdmFsICsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOU01BTExORUdJTlRTXSA9IHA7CisgICAgICAgICAgICAgICAgfQorI2VuZGlmCisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgZWxzZSB7CisgICAgICAgICAgICBQeU1lbV9GUkVFKGxpc3QpOworICAgICAgICB9CisgICAgICAgIGZyZWVsaXN0X3NpemUgKz0gdTsKKyAgICAgICAgbGlzdCA9IG5leHQ7CisgICAgfQorCisgICAgcmV0dXJuIGZyZWVsaXN0X3NpemU7Cit9CisKK3ZvaWQKK1B5SW50X0Zpbmkodm9pZCkKK3sKKyAgICBQeUludE9iamVjdCAqcDsKKyAgICBQeUludEJsb2NrICpsaXN0OworICAgIGludCBpOworICAgIGludCB1OyAgICAgICAgICAgICAgICAgICAgICAvKiB0b3RhbCB1bmZyZWVkIGludHMgcGVyIGJsb2NrICovCisKKyNpZiBOU01BTExORUdJTlRTICsgTlNNQUxMUE9TSU5UUyA+IDAKKyAgICBQeUludE9iamVjdCAqKnE7CisKKyAgICBpID0gTlNNQUxMTkVHSU5UUyArIE5TTUFMTFBPU0lOVFM7CisgICAgcSA9IHNtYWxsX2ludHM7CisgICAgd2hpbGUgKC0taSA+PSAwKSB7CisgICAgICAgIFB5X1hERUNSRUYoKnEpOworICAgICAgICAqcSsrID0gTlVMTDsKKyAgICB9CisjZW5kaWYKKyAgICB1ID0gUHlJbnRfQ2xlYXJGcmVlTGlzdCgpOworICAgIGlmICghUHlfVmVyYm9zZUZsYWcpCisgICAgICAgIHJldHVybjsKKyAgICBmcHJpbnRmKHN0ZGVyciwgIiMgY2xlYW51cCBpbnRzIik7CisgICAgaWYgKCF1KSB7CisgICAgICAgIGZwcmludGYoc3RkZXJyLCAiXG4iKTsKKyAgICB9CisgICAgZWxzZSB7CisgICAgICAgIGZwcmludGYoc3RkZXJyLAorICAgICAgICAgICAgIjogJWQgdW5mcmVlZCBpbnQlc1xuIiwKKyAgICAgICAgICAgIHUsIHUgPT0gMSA/ICIiIDogInMiKTsKKyAgICB9CisgICAgaWYgKFB5X1ZlcmJvc2VGbGFnID4gMSkgeworICAgICAgICBsaXN0ID0gYmxvY2tfbGlzdDsKKyAgICAgICAgd2hpbGUgKGxpc3QgIT0gTlVMTCkgeworICAgICAgICAgICAgZm9yIChpID0gMCwgcCA9ICZsaXN0LT5vYmplY3RzWzBdOworICAgICAgICAgICAgICAgICBpIDwgTl9JTlRPQkpFQ1RTOworICAgICAgICAgICAgICAgICBpKyssIHArKykgeworICAgICAgICAgICAgICAgIGlmIChQeUludF9DaGVja0V4YWN0KHApICYmIHAtPm9iX3JlZmNudCAhPSAwKQorICAgICAgICAgICAgICAgICAgICAvKiBYWFgodHdvdXRlcnMpIGNhc3QgcmVmY291bnQgdG8KKyAgICAgICAgICAgICAgICAgICAgICAgbG9uZyB1bnRpbCAlemQgaXMgdW5pdmVyc2FsbHkKKyAgICAgICAgICAgICAgICAgICAgICAgYXZhaWxhYmxlCisgICAgICAgICAgICAgICAgICAgICAqLworICAgICAgICAgICAgICAgICAgICBmcHJpbnRmKHN0ZGVyciwKKyAgICAgICAgICAgICAgICAiIyAgIDxpbnQgYXQgJXAsIHJlZmNudD0lbGQsIHZhbD0lbGQ+XG4iLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwLCAobG9uZylwLT5vYl9yZWZjbnQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHAtPm9iX2l2YWwpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgbGlzdCA9IGxpc3QtPm5leHQ7CisgICAgICAgIH0KKyAgICB9Cit9CmRpZmYgLS1naXQgYS9QeXRob24tMi43LjUvT2JqZWN0cy9pdGVyb2JqZWN0LmMgYi9QeXRob24tMi43LjUvT2JqZWN0cy9pdGVyb2JqZWN0LmMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNWE5YTJkZAotLS0gL2Rldi9udWxsCisrKyBiL1B5dGhvbi0yLjcuNS9PYmplY3RzL2l0ZXJvYmplY3QuYwpAQCAtMCwwICsxLDIzMCBAQAorLyogSXRlcmF0b3Igb2JqZWN0cyAqLworCisjaW5jbHVkZSAiUHl0aG9uLmgiCisKK3R5cGVkZWYgc3RydWN0IHsKKyAgICBQeU9iamVjdF9IRUFECisgICAgbG9uZyAgICAgIGl0X2luZGV4OworICAgIFB5T2JqZWN0ICppdF9zZXE7IC8qIFNldCB0byBOVUxMIHdoZW4gaXRlcmF0b3IgaXMgZXhoYXVzdGVkICovCit9IHNlcWl0ZXJvYmplY3Q7CisKK1B5T2JqZWN0ICoKK1B5U2VxSXRlcl9OZXcoUHlPYmplY3QgKnNlcSkKK3sKKyAgICBzZXFpdGVyb2JqZWN0ICppdDsKKworICAgIGlmICghUHlTZXF1ZW5jZV9DaGVjayhzZXEpKSB7CisgICAgICAgIFB5RXJyX0JhZEludGVybmFsQ2FsbCgpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgaXQgPSBQeU9iamVjdF9HQ19OZXcoc2VxaXRlcm9iamVjdCwgJlB5U2VxSXRlcl9UeXBlKTsKKyAgICBpZiAoaXQgPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgaXQtPml0X2luZGV4ID0gMDsKKyAgICBQeV9JTkNSRUYoc2VxKTsKKyAgICBpdC0+aXRfc2VxID0gc2VxOworICAgIF9QeU9iamVjdF9HQ19UUkFDSyhpdCk7CisgICAgcmV0dXJuIChQeU9iamVjdCAqKWl0OworfQorCitzdGF0aWMgdm9pZAoraXRlcl9kZWFsbG9jKHNlcWl0ZXJvYmplY3QgKml0KQoreworICAgIF9QeU9iamVjdF9HQ19VTlRSQUNLKGl0KTsKKyAgICBQeV9YREVDUkVGKGl0LT5pdF9zZXEpOworICAgIFB5T2JqZWN0X0dDX0RlbChpdCk7Cit9CisKK3N0YXRpYyBpbnQKK2l0ZXJfdHJhdmVyc2Uoc2VxaXRlcm9iamVjdCAqaXQsIHZpc2l0cHJvYyB2aXNpdCwgdm9pZCAqYXJnKQoreworICAgIFB5X1ZJU0lUKGl0LT5pdF9zZXEpOworICAgIHJldHVybiAwOworfQorCitzdGF0aWMgUHlPYmplY3QgKgoraXRlcl9pdGVybmV4dChQeU9iamVjdCAqaXRlcmF0b3IpCit7CisgICAgc2VxaXRlcm9iamVjdCAqaXQ7CisgICAgUHlPYmplY3QgKnNlcTsKKyAgICBQeU9iamVjdCAqcmVzdWx0OworCisgICAgYXNzZXJ0KFB5U2VxSXRlcl9DaGVjayhpdGVyYXRvcikpOworICAgIGl0ID0gKHNlcWl0ZXJvYmplY3QgKilpdGVyYXRvcjsKKyAgICBzZXEgPSBpdC0+aXRfc2VxOworICAgIGlmIChzZXEgPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisKKyAgICByZXN1bHQgPSBQeVNlcXVlbmNlX0dldEl0ZW0oc2VxLCBpdC0+aXRfaW5kZXgpOworICAgIGlmIChyZXN1bHQgIT0gTlVMTCkgeworICAgICAgICBpdC0+aXRfaW5kZXgrKzsKKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisgICAgaWYgKFB5RXJyX0V4Y2VwdGlvbk1hdGNoZXMoUHlFeGNfSW5kZXhFcnJvcikgfHwKKyAgICAgICAgUHlFcnJfRXhjZXB0aW9uTWF0Y2hlcyhQeUV4Y19TdG9wSXRlcmF0aW9uKSkKKyAgICB7CisgICAgICAgIFB5RXJyX0NsZWFyKCk7CisgICAgICAgIFB5X0RFQ1JFRihzZXEpOworICAgICAgICBpdC0+aXRfc2VxID0gTlVMTDsKKyAgICB9CisgICAgcmV0dXJuIE5VTEw7Cit9CisKK3N0YXRpYyBQeU9iamVjdCAqCitpdGVyX2xlbihzZXFpdGVyb2JqZWN0ICppdCkKK3sKKyAgICBQeV9zc2l6ZV90IHNlcXNpemUsIGxlbjsKKworICAgIGlmIChpdC0+aXRfc2VxKSB7CisgICAgICAgIHNlcXNpemUgPSBQeVNlcXVlbmNlX1NpemUoaXQtPml0X3NlcSk7CisgICAgICAgIGlmIChzZXFzaXplID09IC0xKQorICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgICAgIGxlbiA9IHNlcXNpemUgLSBpdC0+aXRfaW5kZXg7CisgICAgICAgIGlmIChsZW4gPj0gMCkKKyAgICAgICAgICAgIHJldHVybiBQeUludF9Gcm9tU3NpemVfdChsZW4pOworICAgIH0KKyAgICByZXR1cm4gUHlJbnRfRnJvbUxvbmcoMCk7Cit9CisKK1B5RG9jX1NUUlZBUihsZW5ndGhfaGludF9kb2MsICJQcml2YXRlIG1ldGhvZCByZXR1cm5pbmcgYW4gZXN0aW1hdGUgb2YgbGVuKGxpc3QoaXQpKS4iKTsKKworc3RhdGljIFB5TWV0aG9kRGVmIHNlcWl0ZXJfbWV0aG9kc1tdID0geworICAgIHsiX19sZW5ndGhfaGludF9fIiwgKFB5Q0Z1bmN0aW9uKWl0ZXJfbGVuLCBNRVRIX05PQVJHUywgbGVuZ3RoX2hpbnRfZG9jfSwKKyAgICB7TlVMTCwgICAgICAgICAgICAgIE5VTEx9ICAgICAgICAgICAvKiBzZW50aW5lbCAqLworfTsKKworUHlUeXBlT2JqZWN0IFB5U2VxSXRlcl9UeXBlID0geworICAgIFB5VmFyT2JqZWN0X0hFQURfSU5JVCgmUHlUeXBlX1R5cGUsIDApCisgICAgIml0ZXJhdG9yIiwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9uYW1lICovCisgICAgc2l6ZW9mKHNlcWl0ZXJvYmplY3QpLCAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9iYXNpY3NpemUgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2l0ZW1zaXplICovCisgICAgLyogbWV0aG9kcyAqLworICAgIChkZXN0cnVjdG9yKWl0ZXJfZGVhbGxvYywgICAgICAgICAgICAgICAgICAgLyogdHBfZGVhbGxvYyAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfcHJpbnQgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2dldGF0dHIgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3NldGF0dHIgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2NvbXBhcmUgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3JlcHIgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2FzX251bWJlciAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfYXNfc2VxdWVuY2UgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2FzX21hcHBpbmcgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2hhc2ggKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2NhbGwgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3N0ciAqLworICAgIFB5T2JqZWN0X0dlbmVyaWNHZXRBdHRyLCAgICAgICAgICAgICAgICAgICAgLyogdHBfZ2V0YXR0cm8gKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3NldGF0dHJvICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9hc19idWZmZXIgKi8KKyAgICBQeV9UUEZMQUdTX0RFRkFVTFQgfCBQeV9UUEZMQUdTX0hBVkVfR0MsLyogdHBfZmxhZ3MgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2RvYyAqLworICAgICh0cmF2ZXJzZXByb2MpaXRlcl90cmF2ZXJzZSwgICAgICAgICAgICAgICAgLyogdHBfdHJhdmVyc2UgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2NsZWFyICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9yaWNoY29tcGFyZSAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfd2Vha2xpc3RvZmZzZXQgKi8KKyAgICBQeU9iamVjdF9TZWxmSXRlciwgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2l0ZXIgKi8KKyAgICBpdGVyX2l0ZXJuZXh0LCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2l0ZXJuZXh0ICovCisgICAgc2VxaXRlcl9tZXRob2RzLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9tZXRob2RzICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9tZW1iZXJzICovCit9OworCisvKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLworCit0eXBlZGVmIHN0cnVjdCB7CisgICAgUHlPYmplY3RfSEVBRAorICAgIFB5T2JqZWN0ICppdF9jYWxsYWJsZTsgLyogU2V0IHRvIE5VTEwgd2hlbiBpdGVyYXRvciBpcyBleGhhdXN0ZWQgKi8KKyAgICBQeU9iamVjdCAqaXRfc2VudGluZWw7IC8qIFNldCB0byBOVUxMIHdoZW4gaXRlcmF0b3IgaXMgZXhoYXVzdGVkICovCit9IGNhbGxpdGVyb2JqZWN0OworCitQeU9iamVjdCAqCitQeUNhbGxJdGVyX05ldyhQeU9iamVjdCAqY2FsbGFibGUsIFB5T2JqZWN0ICpzZW50aW5lbCkKK3sKKyAgICBjYWxsaXRlcm9iamVjdCAqaXQ7CisgICAgaXQgPSBQeU9iamVjdF9HQ19OZXcoY2FsbGl0ZXJvYmplY3QsICZQeUNhbGxJdGVyX1R5cGUpOworICAgIGlmIChpdCA9PSBOVUxMKQorICAgICAgICByZXR1cm4gTlVMTDsKKyAgICBQeV9JTkNSRUYoY2FsbGFibGUpOworICAgIGl0LT5pdF9jYWxsYWJsZSA9IGNhbGxhYmxlOworICAgIFB5X0lOQ1JFRihzZW50aW5lbCk7CisgICAgaXQtPml0X3NlbnRpbmVsID0gc2VudGluZWw7CisgICAgX1B5T2JqZWN0X0dDX1RSQUNLKGl0KTsKKyAgICByZXR1cm4gKFB5T2JqZWN0ICopaXQ7Cit9CitzdGF0aWMgdm9pZAorY2FsbGl0ZXJfZGVhbGxvYyhjYWxsaXRlcm9iamVjdCAqaXQpCit7CisgICAgX1B5T2JqZWN0X0dDX1VOVFJBQ0soaXQpOworICAgIFB5X1hERUNSRUYoaXQtPml0X2NhbGxhYmxlKTsKKyAgICBQeV9YREVDUkVGKGl0LT5pdF9zZW50aW5lbCk7CisgICAgUHlPYmplY3RfR0NfRGVsKGl0KTsKK30KKworc3RhdGljIGludAorY2FsbGl0ZXJfdHJhdmVyc2UoY2FsbGl0ZXJvYmplY3QgKml0LCB2aXNpdHByb2MgdmlzaXQsIHZvaWQgKmFyZykKK3sKKyAgICBQeV9WSVNJVChpdC0+aXRfY2FsbGFibGUpOworICAgIFB5X1ZJU0lUKGl0LT5pdF9zZW50aW5lbCk7CisgICAgcmV0dXJuIDA7Cit9CisKK3N0YXRpYyBQeU9iamVjdCAqCitjYWxsaXRlcl9pdGVybmV4dChjYWxsaXRlcm9iamVjdCAqaXQpCit7CisgICAgaWYgKGl0LT5pdF9jYWxsYWJsZSAhPSBOVUxMKSB7CisgICAgICAgIFB5T2JqZWN0ICphcmdzID0gUHlUdXBsZV9OZXcoMCk7CisgICAgICAgIFB5T2JqZWN0ICpyZXN1bHQ7CisgICAgICAgIGlmIChhcmdzID09IE5VTEwpCisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgcmVzdWx0ID0gUHlPYmplY3RfQ2FsbChpdC0+aXRfY2FsbGFibGUsIGFyZ3MsIE5VTEwpOworICAgICAgICBQeV9ERUNSRUYoYXJncyk7CisgICAgICAgIGlmIChyZXN1bHQgIT0gTlVMTCkgeworICAgICAgICAgICAgaW50IG9rOworICAgICAgICAgICAgb2sgPSBQeU9iamVjdF9SaWNoQ29tcGFyZUJvb2wocmVzdWx0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXQtPml0X3NlbnRpbmVsLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHlfRVEpOworICAgICAgICAgICAgaWYgKG9rID09IDApCisgICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDsgLyogQ29tbW9uIGNhc2UsIGZhc3QgcGF0aCAqLworICAgICAgICAgICAgUHlfREVDUkVGKHJlc3VsdCk7CisgICAgICAgICAgICBpZiAob2sgPiAwKSB7CisgICAgICAgICAgICAgICAgUHlfQ0xFQVIoaXQtPml0X2NhbGxhYmxlKTsKKyAgICAgICAgICAgICAgICBQeV9DTEVBUihpdC0+aXRfc2VudGluZWwpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGVsc2UgaWYgKFB5RXJyX0V4Y2VwdGlvbk1hdGNoZXMoUHlFeGNfU3RvcEl0ZXJhdGlvbikpIHsKKyAgICAgICAgICAgIFB5RXJyX0NsZWFyKCk7CisgICAgICAgICAgICBQeV9DTEVBUihpdC0+aXRfY2FsbGFibGUpOworICAgICAgICAgICAgUHlfQ0xFQVIoaXQtPml0X3NlbnRpbmVsKTsKKyAgICAgICAgfQorICAgIH0KKyAgICByZXR1cm4gTlVMTDsKK30KKworUHlUeXBlT2JqZWN0IFB5Q2FsbEl0ZXJfVHlwZSA9IHsKKyAgICBQeVZhck9iamVjdF9IRUFEX0lOSVQoJlB5VHlwZV9UeXBlLCAwKQorICAgICJjYWxsYWJsZS1pdGVyYXRvciIsICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfbmFtZSAqLworICAgIHNpemVvZihjYWxsaXRlcm9iamVjdCksICAgICAgICAgICAgICAgICAgICAgLyogdHBfYmFzaWNzaXplICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9pdGVtc2l6ZSAqLworICAgIC8qIG1ldGhvZHMgKi8KKyAgICAoZGVzdHJ1Y3RvciljYWxsaXRlcl9kZWFsbG9jLCAgICAgICAgICAgICAgIC8qIHRwX2RlYWxsb2MgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3ByaW50ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9nZXRhdHRyICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9zZXRhdHRyICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9jb21wYXJlICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9yZXByICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9hc19udW1iZXIgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2FzX3NlcXVlbmNlICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9hc19tYXBwaW5nICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9oYXNoICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9jYWxsICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9zdHIgKi8KKyAgICBQeU9iamVjdF9HZW5lcmljR2V0QXR0ciwgICAgICAgICAgICAgICAgICAgIC8qIHRwX2dldGF0dHJvICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9zZXRhdHRybyAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfYXNfYnVmZmVyICovCisgICAgUHlfVFBGTEFHU19ERUZBVUxUIHwgUHlfVFBGTEFHU19IQVZFX0dDLC8qIHRwX2ZsYWdzICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9kb2MgKi8KKyAgICAodHJhdmVyc2Vwcm9jKWNhbGxpdGVyX3RyYXZlcnNlLCAgICAgICAgICAgIC8qIHRwX3RyYXZlcnNlICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9jbGVhciAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfcmljaGNvbXBhcmUgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3dlYWtsaXN0b2Zmc2V0ICovCisgICAgUHlPYmplY3RfU2VsZkl0ZXIsICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9pdGVyICovCisgICAgKGl0ZXJuZXh0ZnVuYyljYWxsaXRlcl9pdGVybmV4dCwgICAgICAgICAgICAvKiB0cF9pdGVybmV4dCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfbWV0aG9kcyAqLworfTsKZGlmZiAtLWdpdCBhL1B5dGhvbi0yLjcuNS9PYmplY3RzL2xpc3RvYmplY3QuYyBiL1B5dGhvbi0yLjcuNS9PYmplY3RzL2xpc3RvYmplY3QuYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5mNzUzNjQzCi0tLSAvZGV2L251bGwKKysrIGIvUHl0aG9uLTIuNy41L09iamVjdHMvbGlzdG9iamVjdC5jCkBAIC0wLDAgKzEsMzA0NCBAQAorLyogTGlzdCBvYmplY3QgaW1wbGVtZW50YXRpb24gKi8KKworI2luY2x1ZGUgIlB5dGhvbi5oIgorCisjaWZkZWYgU1REQ19IRUFERVJTCisjaW5jbHVkZSA8c3RkZGVmLmg+CisjZWxzZQorI2luY2x1ZGUgPHN5cy90eXBlcy5oPiAgICAgICAgICAvKiBGb3Igc2l6ZV90ICovCisjZW5kaWYKKworLyogRW5zdXJlIG9iX2l0ZW0gaGFzIHJvb20gZm9yIGF0IGxlYXN0IG5ld3NpemUgZWxlbWVudHMsIGFuZCBzZXQKKyAqIG9iX3NpemUgdG8gbmV3c2l6ZS4gIElmIG5ld3NpemUgPiBvYl9zaXplIG9uIGVudHJ5LCB0aGUgY29udGVudAorICogb2YgdGhlIG5ldyBzbG90cyBhdCBleGl0IGlzIHVuZGVmaW5lZCBoZWFwIHRyYXNoOyBpdCdzIHRoZSBjYWxsZXIncworICogcmVzcG9uc2liaWxpdHkgdG8gb3ZlcndyaXRlIHRoZW0gd2l0aCBzYW5lIHZhbHVlcy4KKyAqIFRoZSBudW1iZXIgb2YgYWxsb2NhdGVkIGVsZW1lbnRzIG1heSBncm93LCBzaHJpbmssIG9yIHN0YXkgdGhlIHNhbWUuCisgKiBGYWlsdXJlIGlzIGltcG9zc2libGUgaWYgbmV3c2l6ZSA8PSBzZWxmLmFsbG9jYXRlZCBvbiBlbnRyeSwgYWx0aG91Z2gKKyAqIHRoYXQgcGFydGx5IHJlbGllcyBvbiBhbiBhc3N1bXB0aW9uIHRoYXQgdGhlIHN5c3RlbSByZWFsbG9jKCkgbmV2ZXIKKyAqIGZhaWxzIHdoZW4gcGFzc2VkIGEgbnVtYmVyIG9mIGJ5dGVzIDw9IHRoZSBudW1iZXIgb2YgYnl0ZXMgbGFzdAorICogYWxsb2NhdGVkICh0aGUgQyBzdGFuZGFyZCBkb2Vzbid0IGd1YXJhbnRlZSB0aGlzLCBidXQgaXQncyBoYXJkIHRvCisgKiBpbWFnaW5lIGEgcmVhbGxvYyBpbXBsZW1lbnRhdGlvbiB3aGVyZSBpdCB3b3VsZG4ndCBiZSB0cnVlKS4KKyAqIE5vdGUgdGhhdCBzZWxmLT5vYl9pdGVtIG1heSBjaGFuZ2UsIGFuZCBldmVuIGlmIG5ld3NpemUgaXMgbGVzcworICogdGhhbiBvYl9zaXplIG9uIGVudHJ5LgorICovCitzdGF0aWMgaW50CitsaXN0X3Jlc2l6ZShQeUxpc3RPYmplY3QgKnNlbGYsIFB5X3NzaXplX3QgbmV3c2l6ZSkKK3sKKyAgICBQeU9iamVjdCAqKml0ZW1zOworICAgIHNpemVfdCBuZXdfYWxsb2NhdGVkOworICAgIFB5X3NzaXplX3QgYWxsb2NhdGVkID0gc2VsZi0+YWxsb2NhdGVkOworCisgICAgLyogQnlwYXNzIHJlYWxsb2MoKSB3aGVuIGEgcHJldmlvdXMgb3ZlcmFsbG9jYXRpb24gaXMgbGFyZ2UgZW5vdWdoCisgICAgICAgdG8gYWNjb21tb2RhdGUgdGhlIG5ld3NpemUuICBJZiB0aGUgbmV3c2l6ZSBmYWxscyBsb3dlciB0aGFuIGhhbGYKKyAgICAgICB0aGUgYWxsb2NhdGVkIHNpemUsIHRoZW4gcHJvY2VlZCB3aXRoIHRoZSByZWFsbG9jKCkgdG8gc2hyaW5rIHRoZSBsaXN0LgorICAgICovCisgICAgaWYgKGFsbG9jYXRlZCA+PSBuZXdzaXplICYmIG5ld3NpemUgPj0gKGFsbG9jYXRlZCA+PiAxKSkgeworICAgICAgICBhc3NlcnQoc2VsZi0+b2JfaXRlbSAhPSBOVUxMIHx8IG5ld3NpemUgPT0gMCk7CisgICAgICAgIFB5X1NJWkUoc2VsZikgPSBuZXdzaXplOworICAgICAgICByZXR1cm4gMDsKKyAgICB9CisKKyAgICAvKiBUaGlzIG92ZXItYWxsb2NhdGVzIHByb3BvcnRpb25hbCB0byB0aGUgbGlzdCBzaXplLCBtYWtpbmcgcm9vbQorICAgICAqIGZvciBhZGRpdGlvbmFsIGdyb3d0aC4gIFRoZSBvdmVyLWFsbG9jYXRpb24gaXMgbWlsZCwgYnV0IGlzCisgICAgICogZW5vdWdoIHRvIGdpdmUgbGluZWFyLXRpbWUgYW1vcnRpemVkIGJlaGF2aW9yIG92ZXIgYSBsb25nCisgICAgICogc2VxdWVuY2Ugb2YgYXBwZW5kcygpIGluIHRoZSBwcmVzZW5jZSBvZiBhIHBvb3JseS1wZXJmb3JtaW5nCisgICAgICogc3lzdGVtIHJlYWxsb2MoKS4KKyAgICAgKiBUaGUgZ3Jvd3RoIHBhdHRlcm4gaXM6ICAwLCA0LCA4LCAxNiwgMjUsIDM1LCA0NiwgNTgsIDcyLCA4OCwgLi4uCisgICAgICovCisgICAgbmV3X2FsbG9jYXRlZCA9IChuZXdzaXplID4+IDMpICsgKG5ld3NpemUgPCA5ID8gMyA6IDYpOworCisgICAgLyogY2hlY2sgZm9yIGludGVnZXIgb3ZlcmZsb3cgKi8KKyAgICBpZiAobmV3X2FsbG9jYXRlZCA+IFBZX1NJWkVfTUFYIC0gbmV3c2l6ZSkgeworICAgICAgICBQeUVycl9Ob01lbW9yeSgpOworICAgICAgICByZXR1cm4gLTE7CisgICAgfSBlbHNlIHsKKyAgICAgICAgbmV3X2FsbG9jYXRlZCArPSBuZXdzaXplOworICAgIH0KKworICAgIGlmIChuZXdzaXplID09IDApCisgICAgICAgIG5ld19hbGxvY2F0ZWQgPSAwOworICAgIGl0ZW1zID0gc2VsZi0+b2JfaXRlbTsKKyAgICBpZiAobmV3X2FsbG9jYXRlZCA8PSAoUFlfU0laRV9NQVggLyBzaXplb2YoUHlPYmplY3QgKikpKQorICAgICAgICBQeU1lbV9SRVNJWkUoaXRlbXMsIFB5T2JqZWN0ICosIG5ld19hbGxvY2F0ZWQpOworICAgIGVsc2UKKyAgICAgICAgaXRlbXMgPSBOVUxMOworICAgIGlmIChpdGVtcyA9PSBOVUxMKSB7CisgICAgICAgIFB5RXJyX05vTWVtb3J5KCk7CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisgICAgc2VsZi0+b2JfaXRlbSA9IGl0ZW1zOworICAgIFB5X1NJWkUoc2VsZikgPSBuZXdzaXplOworICAgIHNlbGYtPmFsbG9jYXRlZCA9IG5ld19hbGxvY2F0ZWQ7CisgICAgcmV0dXJuIDA7Cit9CisKKy8qIERlYnVnIHN0YXRpc3RpYyB0byBjb21wYXJlIGFsbG9jYXRpb25zIHdpdGggcmV1c2UgdGhyb3VnaCB0aGUgZnJlZSBsaXN0ICovCisjdW5kZWYgU0hPV19BTExPQ19DT1VOVAorI2lmZGVmIFNIT1dfQUxMT0NfQ09VTlQKK3N0YXRpYyBzaXplX3QgY291bnRfYWxsb2MgPSAwOworc3RhdGljIHNpemVfdCBjb3VudF9yZXVzZSA9IDA7CisKK3N0YXRpYyB2b2lkCitzaG93X2FsbG9jKHZvaWQpCit7CisgICAgZnByaW50ZihzdGRlcnIsICJMaXN0IGFsbG9jYXRpb25zOiAlIiBQWV9GT1JNQVRfU0laRV9UICJkXG4iLAorICAgICAgICBjb3VudF9hbGxvYyk7CisgICAgZnByaW50ZihzdGRlcnIsICJMaXN0IHJldXNlIHRocm91Z2ggZnJlZWxpc3Q6ICUiIFBZX0ZPUk1BVF9TSVpFX1QKKyAgICAgICAgImRcbiIsIGNvdW50X3JldXNlKTsKKyAgICBmcHJpbnRmKHN0ZGVyciwgIiUuMmYlJSByZXVzZSByYXRlXG5cbiIsCisgICAgICAgICgxMDAuMCpjb3VudF9yZXVzZS8oY291bnRfYWxsb2MrY291bnRfcmV1c2UpKSk7Cit9CisjZW5kaWYKKworLyogRW1wdHkgbGlzdCByZXVzZSBzY2hlbWUgdG8gc2F2ZSBjYWxscyB0byBtYWxsb2MgYW5kIGZyZWUgKi8KKyNpZm5kZWYgUHlMaXN0X01BWEZSRUVMSVNUCisjZGVmaW5lIFB5TGlzdF9NQVhGUkVFTElTVCA4MAorI2VuZGlmCitzdGF0aWMgUHlMaXN0T2JqZWN0ICpmcmVlX2xpc3RbUHlMaXN0X01BWEZSRUVMSVNUXTsKK3N0YXRpYyBpbnQgbnVtZnJlZSA9IDA7CisKK3ZvaWQKK1B5TGlzdF9GaW5pKHZvaWQpCit7CisgICAgUHlMaXN0T2JqZWN0ICpvcDsKKworICAgIHdoaWxlIChudW1mcmVlKSB7CisgICAgICAgIG9wID0gZnJlZV9saXN0Wy0tbnVtZnJlZV07CisgICAgICAgIGFzc2VydChQeUxpc3RfQ2hlY2tFeGFjdChvcCkpOworICAgICAgICBQeU9iamVjdF9HQ19EZWwob3ApOworICAgIH0KK30KKworUHlPYmplY3QgKgorUHlMaXN0X05ldyhQeV9zc2l6ZV90IHNpemUpCit7CisgICAgUHlMaXN0T2JqZWN0ICpvcDsKKyAgICBzaXplX3QgbmJ5dGVzOworI2lmZGVmIFNIT1dfQUxMT0NfQ09VTlQKKyAgICBzdGF0aWMgaW50IGluaXRpYWxpemVkID0gMDsKKyAgICBpZiAoIWluaXRpYWxpemVkKSB7CisgICAgICAgIFB5X0F0RXhpdChzaG93X2FsbG9jKTsKKyAgICAgICAgaW5pdGlhbGl6ZWQgPSAxOworICAgIH0KKyNlbmRpZgorCisgICAgaWYgKHNpemUgPCAwKSB7CisgICAgICAgIFB5RXJyX0JhZEludGVybmFsQ2FsbCgpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgLyogQ2hlY2sgZm9yIG92ZXJmbG93IHdpdGhvdXQgYW4gYWN0dWFsIG92ZXJmbG93LAorICAgICAqICB3aGljaCBjYW4gY2F1c2UgY29tcGlsZXIgdG8gb3B0aW1pc2Ugb3V0ICovCisgICAgaWYgKChzaXplX3Qpc2l6ZSA+IFBZX1NJWkVfTUFYIC8gc2l6ZW9mKFB5T2JqZWN0ICopKQorICAgICAgICByZXR1cm4gUHlFcnJfTm9NZW1vcnkoKTsKKyAgICBuYnl0ZXMgPSBzaXplICogc2l6ZW9mKFB5T2JqZWN0ICopOworICAgIGlmIChudW1mcmVlKSB7CisgICAgICAgIG51bWZyZWUtLTsKKyAgICAgICAgb3AgPSBmcmVlX2xpc3RbbnVtZnJlZV07CisgICAgICAgIF9QeV9OZXdSZWZlcmVuY2UoKFB5T2JqZWN0ICopb3ApOworI2lmZGVmIFNIT1dfQUxMT0NfQ09VTlQKKyAgICAgICAgY291bnRfcmV1c2UrKzsKKyNlbmRpZgorICAgIH0gZWxzZSB7CisgICAgICAgIG9wID0gUHlPYmplY3RfR0NfTmV3KFB5TGlzdE9iamVjdCwgJlB5TGlzdF9UeXBlKTsKKyAgICAgICAgaWYgKG9wID09IE5VTEwpCisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyNpZmRlZiBTSE9XX0FMTE9DX0NPVU5UCisgICAgICAgIGNvdW50X2FsbG9jKys7CisjZW5kaWYKKyAgICB9CisgICAgaWYgKHNpemUgPD0gMCkKKyAgICAgICAgb3AtPm9iX2l0ZW0gPSBOVUxMOworICAgIGVsc2UgeworICAgICAgICBvcC0+b2JfaXRlbSA9IChQeU9iamVjdCAqKikgUHlNZW1fTUFMTE9DKG5ieXRlcyk7CisgICAgICAgIGlmIChvcC0+b2JfaXRlbSA9PSBOVUxMKSB7CisgICAgICAgICAgICBQeV9ERUNSRUYob3ApOworICAgICAgICAgICAgcmV0dXJuIFB5RXJyX05vTWVtb3J5KCk7CisgICAgICAgIH0KKyAgICAgICAgbWVtc2V0KG9wLT5vYl9pdGVtLCAwLCBuYnl0ZXMpOworICAgIH0KKyAgICBQeV9TSVpFKG9wKSA9IHNpemU7CisgICAgb3AtPmFsbG9jYXRlZCA9IHNpemU7CisgICAgX1B5T2JqZWN0X0dDX1RSQUNLKG9wKTsKKyAgICByZXR1cm4gKFB5T2JqZWN0ICopIG9wOworfQorCitQeV9zc2l6ZV90CitQeUxpc3RfU2l6ZShQeU9iamVjdCAqb3ApCit7CisgICAgaWYgKCFQeUxpc3RfQ2hlY2sob3ApKSB7CisgICAgICAgIFB5RXJyX0JhZEludGVybmFsQ2FsbCgpOworICAgICAgICByZXR1cm4gLTE7CisgICAgfQorICAgIGVsc2UKKyAgICAgICAgcmV0dXJuIFB5X1NJWkUob3ApOworfQorCitzdGF0aWMgUHlPYmplY3QgKmluZGV4ZXJyID0gTlVMTDsKKworUHlPYmplY3QgKgorUHlMaXN0X0dldEl0ZW0oUHlPYmplY3QgKm9wLCBQeV9zc2l6ZV90IGkpCit7CisgICAgaWYgKCFQeUxpc3RfQ2hlY2sob3ApKSB7CisgICAgICAgIFB5RXJyX0JhZEludGVybmFsQ2FsbCgpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgaWYgKGkgPCAwIHx8IGkgPj0gUHlfU0laRShvcCkpIHsKKyAgICAgICAgaWYgKGluZGV4ZXJyID09IE5VTEwpIHsKKyAgICAgICAgICAgIGluZGV4ZXJyID0gUHlTdHJpbmdfRnJvbVN0cmluZygKKyAgICAgICAgICAgICAgICAibGlzdCBpbmRleCBvdXQgb2YgcmFuZ2UiKTsKKyAgICAgICAgICAgIGlmIChpbmRleGVyciA9PSBOVUxMKQorICAgICAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgICAgICB9CisgICAgICAgIFB5RXJyX1NldE9iamVjdChQeUV4Y19JbmRleEVycm9yLCBpbmRleGVycik7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICByZXR1cm4gKChQeUxpc3RPYmplY3QgKilvcCkgLT4gb2JfaXRlbVtpXTsKK30KKworaW50CitQeUxpc3RfU2V0SXRlbShyZWdpc3RlciBQeU9iamVjdCAqb3AsIHJlZ2lzdGVyIFB5X3NzaXplX3QgaSwKKyAgICAgICAgICAgICAgIHJlZ2lzdGVyIFB5T2JqZWN0ICpuZXdpdGVtKQoreworICAgIHJlZ2lzdGVyIFB5T2JqZWN0ICpvbGRpdGVtOworICAgIHJlZ2lzdGVyIFB5T2JqZWN0ICoqcDsKKyAgICBpZiAoIVB5TGlzdF9DaGVjayhvcCkpIHsKKyAgICAgICAgUHlfWERFQ1JFRihuZXdpdGVtKTsKKyAgICAgICAgUHlFcnJfQmFkSW50ZXJuYWxDYWxsKCk7CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisgICAgaWYgKGkgPCAwIHx8IGkgPj0gUHlfU0laRShvcCkpIHsKKyAgICAgICAgUHlfWERFQ1JFRihuZXdpdGVtKTsKKyAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX0luZGV4RXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAgICAibGlzdCBhc3NpZ25tZW50IGluZGV4IG91dCBvZiByYW5nZSIpOworICAgICAgICByZXR1cm4gLTE7CisgICAgfQorICAgIHAgPSAoKFB5TGlzdE9iamVjdCAqKW9wKSAtPiBvYl9pdGVtICsgaTsKKyAgICBvbGRpdGVtID0gKnA7CisgICAgKnAgPSBuZXdpdGVtOworICAgIFB5X1hERUNSRUYob2xkaXRlbSk7CisgICAgcmV0dXJuIDA7Cit9CisKK3N0YXRpYyBpbnQKK2luczEoUHlMaXN0T2JqZWN0ICpzZWxmLCBQeV9zc2l6ZV90IHdoZXJlLCBQeU9iamVjdCAqdikKK3sKKyAgICBQeV9zc2l6ZV90IGksIG4gPSBQeV9TSVpFKHNlbGYpOworICAgIFB5T2JqZWN0ICoqaXRlbXM7CisgICAgaWYgKHYgPT0gTlVMTCkgeworICAgICAgICBQeUVycl9CYWRJbnRlcm5hbENhbGwoKTsKKyAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKyAgICBpZiAobiA9PSBQWV9TU0laRV9UX01BWCkgeworICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfT3ZlcmZsb3dFcnJvciwKKyAgICAgICAgICAgICJjYW5ub3QgYWRkIG1vcmUgb2JqZWN0cyB0byBsaXN0Iik7CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisKKyAgICBpZiAobGlzdF9yZXNpemUoc2VsZiwgbisxKSA9PSAtMSkKKyAgICAgICAgcmV0dXJuIC0xOworCisgICAgaWYgKHdoZXJlIDwgMCkgeworICAgICAgICB3aGVyZSArPSBuOworICAgICAgICBpZiAod2hlcmUgPCAwKQorICAgICAgICAgICAgd2hlcmUgPSAwOworICAgIH0KKyAgICBpZiAod2hlcmUgPiBuKQorICAgICAgICB3aGVyZSA9IG47CisgICAgaXRlbXMgPSBzZWxmLT5vYl9pdGVtOworICAgIGZvciAoaSA9IG47IC0taSA+PSB3aGVyZTsgKQorICAgICAgICBpdGVtc1tpKzFdID0gaXRlbXNbaV07CisgICAgUHlfSU5DUkVGKHYpOworICAgIGl0ZW1zW3doZXJlXSA9IHY7CisgICAgcmV0dXJuIDA7Cit9CisKK2ludAorUHlMaXN0X0luc2VydChQeU9iamVjdCAqb3AsIFB5X3NzaXplX3Qgd2hlcmUsIFB5T2JqZWN0ICpuZXdpdGVtKQoreworICAgIGlmICghUHlMaXN0X0NoZWNrKG9wKSkgeworICAgICAgICBQeUVycl9CYWRJbnRlcm5hbENhbGwoKTsKKyAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKyAgICByZXR1cm4gaW5zMSgoUHlMaXN0T2JqZWN0ICopb3AsIHdoZXJlLCBuZXdpdGVtKTsKK30KKworc3RhdGljIGludAorYXBwMShQeUxpc3RPYmplY3QgKnNlbGYsIFB5T2JqZWN0ICp2KQoreworICAgIFB5X3NzaXplX3QgbiA9IFB5TGlzdF9HRVRfU0laRShzZWxmKTsKKworICAgIGFzc2VydCAodiAhPSBOVUxMKTsKKyAgICBpZiAobiA9PSBQWV9TU0laRV9UX01BWCkgeworICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfT3ZlcmZsb3dFcnJvciwKKyAgICAgICAgICAgICJjYW5ub3QgYWRkIG1vcmUgb2JqZWN0cyB0byBsaXN0Iik7CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisKKyAgICBpZiAobGlzdF9yZXNpemUoc2VsZiwgbisxKSA9PSAtMSkKKyAgICAgICAgcmV0dXJuIC0xOworCisgICAgUHlfSU5DUkVGKHYpOworICAgIFB5TGlzdF9TRVRfSVRFTShzZWxmLCBuLCB2KTsKKyAgICByZXR1cm4gMDsKK30KKworaW50CitQeUxpc3RfQXBwZW5kKFB5T2JqZWN0ICpvcCwgUHlPYmplY3QgKm5ld2l0ZW0pCit7CisgICAgaWYgKFB5TGlzdF9DaGVjayhvcCkgJiYgKG5ld2l0ZW0gIT0gTlVMTCkpCisgICAgICAgIHJldHVybiBhcHAxKChQeUxpc3RPYmplY3QgKilvcCwgbmV3aXRlbSk7CisgICAgUHlFcnJfQmFkSW50ZXJuYWxDYWxsKCk7CisgICAgcmV0dXJuIC0xOworfQorCisvKiBNZXRob2RzICovCisKK3N0YXRpYyB2b2lkCitsaXN0X2RlYWxsb2MoUHlMaXN0T2JqZWN0ICpvcCkKK3sKKyAgICBQeV9zc2l6ZV90IGk7CisgICAgUHlPYmplY3RfR0NfVW5UcmFjayhvcCk7CisgICAgUHlfVFJBU0hDQU5fU0FGRV9CRUdJTihvcCkKKyAgICBpZiAob3AtPm9iX2l0ZW0gIT0gTlVMTCkgeworICAgICAgICAvKiBEbyBpdCBiYWNrd2FyZHMsIGZvciBDaHJpc3RpYW4gVGlzbWVyLgorICAgICAgICAgICBUaGVyZSdzIGEgc2ltcGxlIHRlc3QgY2FzZSB3aGVyZSBzb21laG93IHRoaXMgcmVkdWNlcworICAgICAgICAgICB0aHJhc2hpbmcgd2hlbiBhICp2ZXJ5KiBsYXJnZSBsaXN0IGlzIGNyZWF0ZWQgYW5kCisgICAgICAgICAgIGltbWVkaWF0ZWx5IGRlbGV0ZWQuICovCisgICAgICAgIGkgPSBQeV9TSVpFKG9wKTsKKyAgICAgICAgd2hpbGUgKC0taSA+PSAwKSB7CisgICAgICAgICAgICBQeV9YREVDUkVGKG9wLT5vYl9pdGVtW2ldKTsKKyAgICAgICAgfQorICAgICAgICBQeU1lbV9GUkVFKG9wLT5vYl9pdGVtKTsKKyAgICB9CisgICAgaWYgKG51bWZyZWUgPCBQeUxpc3RfTUFYRlJFRUxJU1QgJiYgUHlMaXN0X0NoZWNrRXhhY3Qob3ApKQorICAgICAgICBmcmVlX2xpc3RbbnVtZnJlZSsrXSA9IG9wOworICAgIGVsc2UKKyAgICAgICAgUHlfVFlQRShvcCktPnRwX2ZyZWUoKFB5T2JqZWN0ICopb3ApOworICAgIFB5X1RSQVNIQ0FOX1NBRkVfRU5EKG9wKQorfQorCitzdGF0aWMgaW50CitsaXN0X3ByaW50KFB5TGlzdE9iamVjdCAqb3AsIEZJTEUgKmZwLCBpbnQgZmxhZ3MpCit7CisgICAgaW50IHJjOworICAgIFB5X3NzaXplX3QgaTsKKyAgICBQeU9iamVjdCAqaXRlbTsKKworICAgIHJjID0gUHlfUmVwckVudGVyKChQeU9iamVjdCopb3ApOworICAgIGlmIChyYyAhPSAwKSB7CisgICAgICAgIGlmIChyYyA8IDApCisgICAgICAgICAgICByZXR1cm4gcmM7CisgICAgICAgIFB5X0JFR0lOX0FMTE9XX1RIUkVBRFMKKyAgICAgICAgZnByaW50ZihmcCwgIlsuLi5dIik7CisgICAgICAgIFB5X0VORF9BTExPV19USFJFQURTCisgICAgICAgIHJldHVybiAwOworICAgIH0KKyAgICBQeV9CRUdJTl9BTExPV19USFJFQURTCisgICAgZnByaW50ZihmcCwgIlsiKTsKKyAgICBQeV9FTkRfQUxMT1dfVEhSRUFEUworICAgIGZvciAoaSA9IDA7IGkgPCBQeV9TSVpFKG9wKTsgaSsrKSB7CisgICAgICAgIGl0ZW0gPSBvcC0+b2JfaXRlbVtpXTsKKyAgICAgICAgUHlfSU5DUkVGKGl0ZW0pOworICAgICAgICBpZiAoaSA+IDApIHsKKyAgICAgICAgICAgIFB5X0JFR0lOX0FMTE9XX1RIUkVBRFMKKyAgICAgICAgICAgIGZwcmludGYoZnAsICIsICIpOworICAgICAgICAgICAgUHlfRU5EX0FMTE9XX1RIUkVBRFMKKyAgICAgICAgfQorICAgICAgICBpZiAoUHlPYmplY3RfUHJpbnQoaXRlbSwgZnAsIDApICE9IDApIHsKKyAgICAgICAgICAgIFB5X0RFQ1JFRihpdGVtKTsKKyAgICAgICAgICAgIFB5X1JlcHJMZWF2ZSgoUHlPYmplY3QgKilvcCk7CisgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgIH0KKyAgICAgICAgUHlfREVDUkVGKGl0ZW0pOworICAgIH0KKyAgICBQeV9CRUdJTl9BTExPV19USFJFQURTCisgICAgZnByaW50ZihmcCwgIl0iKTsKKyAgICBQeV9FTkRfQUxMT1dfVEhSRUFEUworICAgIFB5X1JlcHJMZWF2ZSgoUHlPYmplY3QgKilvcCk7CisgICAgcmV0dXJuIDA7Cit9CisKK3N0YXRpYyBQeU9iamVjdCAqCitsaXN0X3JlcHIoUHlMaXN0T2JqZWN0ICp2KQoreworICAgIFB5X3NzaXplX3QgaTsKKyAgICBQeU9iamVjdCAqcywgKnRlbXA7CisgICAgUHlPYmplY3QgKnBpZWNlcyA9IE5VTEwsICpyZXN1bHQgPSBOVUxMOworCisgICAgaSA9IFB5X1JlcHJFbnRlcigoUHlPYmplY3QqKXYpOworICAgIGlmIChpICE9IDApIHsKKyAgICAgICAgcmV0dXJuIGkgPiAwID8gUHlTdHJpbmdfRnJvbVN0cmluZygiWy4uLl0iKSA6IE5VTEw7CisgICAgfQorCisgICAgaWYgKFB5X1NJWkUodikgPT0gMCkgeworICAgICAgICByZXN1bHQgPSBQeVN0cmluZ19Gcm9tU3RyaW5nKCJbXSIpOworICAgICAgICBnb3RvIERvbmU7CisgICAgfQorCisgICAgcGllY2VzID0gUHlMaXN0X05ldygwKTsKKyAgICBpZiAocGllY2VzID09IE5VTEwpCisgICAgICAgIGdvdG8gRG9uZTsKKworICAgIC8qIERvIHJlcHIoKSBvbiBlYWNoIGVsZW1lbnQuICBOb3RlIHRoYXQgdGhpcyBtYXkgbXV0YXRlIHRoZSBsaXN0LAorICAgICAgIHNvIG11c3QgcmVmZXRjaCB0aGUgbGlzdCBzaXplIG9uIGVhY2ggaXRlcmF0aW9uLiAqLworICAgIGZvciAoaSA9IDA7IGkgPCBQeV9TSVpFKHYpOyArK2kpIHsKKyAgICAgICAgaW50IHN0YXR1czsKKyAgICAgICAgaWYgKFB5X0VudGVyUmVjdXJzaXZlQ2FsbCgiIHdoaWxlIGdldHRpbmcgdGhlIHJlcHIgb2YgYSBsaXN0IikpCisgICAgICAgICAgICBnb3RvIERvbmU7CisgICAgICAgIHMgPSBQeU9iamVjdF9SZXByKHYtPm9iX2l0ZW1baV0pOworICAgICAgICBQeV9MZWF2ZVJlY3Vyc2l2ZUNhbGwoKTsKKyAgICAgICAgaWYgKHMgPT0gTlVMTCkKKyAgICAgICAgICAgIGdvdG8gRG9uZTsKKyAgICAgICAgc3RhdHVzID0gUHlMaXN0X0FwcGVuZChwaWVjZXMsIHMpOworICAgICAgICBQeV9ERUNSRUYocyk7ICAvKiBhcHBlbmQgY3JlYXRlZCBhIG5ldyByZWYgKi8KKyAgICAgICAgaWYgKHN0YXR1cyA8IDApCisgICAgICAgICAgICBnb3RvIERvbmU7CisgICAgfQorCisgICAgLyogQWRkICJbXSIgZGVjb3JhdGlvbnMgdG8gdGhlIGZpcnN0IGFuZCBsYXN0IGl0ZW1zLiAqLworICAgIGFzc2VydChQeUxpc3RfR0VUX1NJWkUocGllY2VzKSA+IDApOworICAgIHMgPSBQeVN0cmluZ19Gcm9tU3RyaW5nKCJbIik7CisgICAgaWYgKHMgPT0gTlVMTCkKKyAgICAgICAgZ290byBEb25lOworICAgIHRlbXAgPSBQeUxpc3RfR0VUX0lURU0ocGllY2VzLCAwKTsKKyAgICBQeVN0cmluZ19Db25jYXRBbmREZWwoJnMsIHRlbXApOworICAgIFB5TGlzdF9TRVRfSVRFTShwaWVjZXMsIDAsIHMpOworICAgIGlmIChzID09IE5VTEwpCisgICAgICAgIGdvdG8gRG9uZTsKKworICAgIHMgPSBQeVN0cmluZ19Gcm9tU3RyaW5nKCJdIik7CisgICAgaWYgKHMgPT0gTlVMTCkKKyAgICAgICAgZ290byBEb25lOworICAgIHRlbXAgPSBQeUxpc3RfR0VUX0lURU0ocGllY2VzLCBQeUxpc3RfR0VUX1NJWkUocGllY2VzKSAtIDEpOworICAgIFB5U3RyaW5nX0NvbmNhdEFuZERlbCgmdGVtcCwgcyk7CisgICAgUHlMaXN0X1NFVF9JVEVNKHBpZWNlcywgUHlMaXN0X0dFVF9TSVpFKHBpZWNlcykgLSAxLCB0ZW1wKTsKKyAgICBpZiAodGVtcCA9PSBOVUxMKQorICAgICAgICBnb3RvIERvbmU7CisKKyAgICAvKiBQYXN0ZSB0aGVtIGFsbCB0b2dldGhlciB3aXRoICIsICIgYmV0d2Vlbi4gKi8KKyAgICBzID0gUHlTdHJpbmdfRnJvbVN0cmluZygiLCAiKTsKKyAgICBpZiAocyA9PSBOVUxMKQorICAgICAgICBnb3RvIERvbmU7CisgICAgcmVzdWx0ID0gX1B5U3RyaW5nX0pvaW4ocywgcGllY2VzKTsKKyAgICBQeV9ERUNSRUYocyk7CisKK0RvbmU6CisgICAgUHlfWERFQ1JFRihwaWVjZXMpOworICAgIFB5X1JlcHJMZWF2ZSgoUHlPYmplY3QgKil2KTsKKyAgICByZXR1cm4gcmVzdWx0OworfQorCitzdGF0aWMgUHlfc3NpemVfdAorbGlzdF9sZW5ndGgoUHlMaXN0T2JqZWN0ICphKQoreworICAgIHJldHVybiBQeV9TSVpFKGEpOworfQorCitzdGF0aWMgaW50CitsaXN0X2NvbnRhaW5zKFB5TGlzdE9iamVjdCAqYSwgUHlPYmplY3QgKmVsKQoreworICAgIFB5X3NzaXplX3QgaTsKKyAgICBpbnQgY21wOworCisgICAgZm9yIChpID0gMCwgY21wID0gMCA7IGNtcCA9PSAwICYmIGkgPCBQeV9TSVpFKGEpOyArK2kpCisgICAgICAgIGNtcCA9IFB5T2JqZWN0X1JpY2hDb21wYXJlQm9vbChlbCwgUHlMaXN0X0dFVF9JVEVNKGEsIGkpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFB5X0VRKTsKKyAgICByZXR1cm4gY21wOworfQorCitzdGF0aWMgUHlPYmplY3QgKgorbGlzdF9pdGVtKFB5TGlzdE9iamVjdCAqYSwgUHlfc3NpemVfdCBpKQoreworICAgIGlmIChpIDwgMCB8fCBpID49IFB5X1NJWkUoYSkpIHsKKyAgICAgICAgaWYgKGluZGV4ZXJyID09IE5VTEwpIHsKKyAgICAgICAgICAgIGluZGV4ZXJyID0gUHlTdHJpbmdfRnJvbVN0cmluZygKKyAgICAgICAgICAgICAgICAibGlzdCBpbmRleCBvdXQgb2YgcmFuZ2UiKTsKKyAgICAgICAgICAgIGlmIChpbmRleGVyciA9PSBOVUxMKQorICAgICAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgICAgICB9CisgICAgICAgIFB5RXJyX1NldE9iamVjdChQeUV4Y19JbmRleEVycm9yLCBpbmRleGVycik7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICBQeV9JTkNSRUYoYS0+b2JfaXRlbVtpXSk7CisgICAgcmV0dXJuIGEtPm9iX2l0ZW1baV07Cit9CisKK3N0YXRpYyBQeU9iamVjdCAqCitsaXN0X3NsaWNlKFB5TGlzdE9iamVjdCAqYSwgUHlfc3NpemVfdCBpbG93LCBQeV9zc2l6ZV90IGloaWdoKQoreworICAgIFB5TGlzdE9iamVjdCAqbnA7CisgICAgUHlPYmplY3QgKipzcmMsICoqZGVzdDsKKyAgICBQeV9zc2l6ZV90IGksIGxlbjsKKyAgICBpZiAoaWxvdyA8IDApCisgICAgICAgIGlsb3cgPSAwOworICAgIGVsc2UgaWYgKGlsb3cgPiBQeV9TSVpFKGEpKQorICAgICAgICBpbG93ID0gUHlfU0laRShhKTsKKyAgICBpZiAoaWhpZ2ggPCBpbG93KQorICAgICAgICBpaGlnaCA9IGlsb3c7CisgICAgZWxzZSBpZiAoaWhpZ2ggPiBQeV9TSVpFKGEpKQorICAgICAgICBpaGlnaCA9IFB5X1NJWkUoYSk7CisgICAgbGVuID0gaWhpZ2ggLSBpbG93OworICAgIG5wID0gKFB5TGlzdE9iamVjdCAqKSBQeUxpc3RfTmV3KGxlbik7CisgICAgaWYgKG5wID09IE5VTEwpCisgICAgICAgIHJldHVybiBOVUxMOworCisgICAgc3JjID0gYS0+b2JfaXRlbSArIGlsb3c7CisgICAgZGVzdCA9IG5wLT5vYl9pdGVtOworICAgIGZvciAoaSA9IDA7IGkgPCBsZW47IGkrKykgeworICAgICAgICBQeU9iamVjdCAqdiA9IHNyY1tpXTsKKyAgICAgICAgUHlfSU5DUkVGKHYpOworICAgICAgICBkZXN0W2ldID0gdjsKKyAgICB9CisgICAgcmV0dXJuIChQeU9iamVjdCAqKW5wOworfQorCitQeU9iamVjdCAqCitQeUxpc3RfR2V0U2xpY2UoUHlPYmplY3QgKmEsIFB5X3NzaXplX3QgaWxvdywgUHlfc3NpemVfdCBpaGlnaCkKK3sKKyAgICBpZiAoIVB5TGlzdF9DaGVjayhhKSkgeworICAgICAgICBQeUVycl9CYWRJbnRlcm5hbENhbGwoKTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIHJldHVybiBsaXN0X3NsaWNlKChQeUxpc3RPYmplY3QgKilhLCBpbG93LCBpaGlnaCk7Cit9CisKK3N0YXRpYyBQeU9iamVjdCAqCitsaXN0X2NvbmNhdChQeUxpc3RPYmplY3QgKmEsIFB5T2JqZWN0ICpiYikKK3sKKyAgICBQeV9zc2l6ZV90IHNpemU7CisgICAgUHlfc3NpemVfdCBpOworICAgIFB5T2JqZWN0ICoqc3JjLCAqKmRlc3Q7CisgICAgUHlMaXN0T2JqZWN0ICpucDsKKyAgICBpZiAoIVB5TGlzdF9DaGVjayhiYikpIHsKKyAgICAgICAgUHlFcnJfRm9ybWF0KFB5RXhjX1R5cGVFcnJvciwKKyAgICAgICAgICAgICAgICAgICJjYW4gb25seSBjb25jYXRlbmF0ZSBsaXN0IChub3QgXCIlLjIwMHNcIikgdG8gbGlzdCIsCisgICAgICAgICAgICAgICAgICBiYi0+b2JfdHlwZS0+dHBfbmFtZSk7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyNkZWZpbmUgYiAoKFB5TGlzdE9iamVjdCAqKWJiKQorICAgIHNpemUgPSBQeV9TSVpFKGEpICsgUHlfU0laRShiKTsKKyAgICBpZiAoc2l6ZSA8IDApCisgICAgICAgIHJldHVybiBQeUVycl9Ob01lbW9yeSgpOworICAgIG5wID0gKFB5TGlzdE9iamVjdCAqKSBQeUxpc3RfTmV3KHNpemUpOworICAgIGlmIChucCA9PSBOVUxMKSB7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICBzcmMgPSBhLT5vYl9pdGVtOworICAgIGRlc3QgPSBucC0+b2JfaXRlbTsKKyAgICBmb3IgKGkgPSAwOyBpIDwgUHlfU0laRShhKTsgaSsrKSB7CisgICAgICAgIFB5T2JqZWN0ICp2ID0gc3JjW2ldOworICAgICAgICBQeV9JTkNSRUYodik7CisgICAgICAgIGRlc3RbaV0gPSB2OworICAgIH0KKyAgICBzcmMgPSBiLT5vYl9pdGVtOworICAgIGRlc3QgPSBucC0+b2JfaXRlbSArIFB5X1NJWkUoYSk7CisgICAgZm9yIChpID0gMDsgaSA8IFB5X1NJWkUoYik7IGkrKykgeworICAgICAgICBQeU9iamVjdCAqdiA9IHNyY1tpXTsKKyAgICAgICAgUHlfSU5DUkVGKHYpOworICAgICAgICBkZXN0W2ldID0gdjsKKyAgICB9CisgICAgcmV0dXJuIChQeU9iamVjdCAqKW5wOworI3VuZGVmIGIKK30KKworc3RhdGljIFB5T2JqZWN0ICoKK2xpc3RfcmVwZWF0KFB5TGlzdE9iamVjdCAqYSwgUHlfc3NpemVfdCBuKQoreworICAgIFB5X3NzaXplX3QgaSwgajsKKyAgICBQeV9zc2l6ZV90IHNpemU7CisgICAgUHlMaXN0T2JqZWN0ICpucDsKKyAgICBQeU9iamVjdCAqKnAsICoqaXRlbXM7CisgICAgUHlPYmplY3QgKmVsZW07CisgICAgaWYgKG4gPCAwKQorICAgICAgICBuID0gMDsKKyAgICBpZiAobiA+IDAgJiYgUHlfU0laRShhKSA+IFBZX1NTSVpFX1RfTUFYIC8gbikKKyAgICAgICAgcmV0dXJuIFB5RXJyX05vTWVtb3J5KCk7CisgICAgc2l6ZSA9IFB5X1NJWkUoYSkgKiBuOworICAgIGlmIChzaXplID09IDApCisgICAgICAgIHJldHVybiBQeUxpc3RfTmV3KDApOworICAgIG5wID0gKFB5TGlzdE9iamVjdCAqKSBQeUxpc3RfTmV3KHNpemUpOworICAgIGlmIChucCA9PSBOVUxMKQorICAgICAgICByZXR1cm4gTlVMTDsKKworICAgIGl0ZW1zID0gbnAtPm9iX2l0ZW07CisgICAgaWYgKFB5X1NJWkUoYSkgPT0gMSkgeworICAgICAgICBlbGVtID0gYS0+b2JfaXRlbVswXTsKKyAgICAgICAgZm9yIChpID0gMDsgaSA8IG47IGkrKykgeworICAgICAgICAgICAgaXRlbXNbaV0gPSBlbGVtOworICAgICAgICAgICAgUHlfSU5DUkVGKGVsZW0pOworICAgICAgICB9CisgICAgICAgIHJldHVybiAoUHlPYmplY3QgKikgbnA7CisgICAgfQorICAgIHAgPSBucC0+b2JfaXRlbTsKKyAgICBpdGVtcyA9IGEtPm9iX2l0ZW07CisgICAgZm9yIChpID0gMDsgaSA8IG47IGkrKykgeworICAgICAgICBmb3IgKGogPSAwOyBqIDwgUHlfU0laRShhKTsgaisrKSB7CisgICAgICAgICAgICAqcCA9IGl0ZW1zW2pdOworICAgICAgICAgICAgUHlfSU5DUkVGKCpwKTsKKyAgICAgICAgICAgIHArKzsKKyAgICAgICAgfQorICAgIH0KKyAgICByZXR1cm4gKFB5T2JqZWN0ICopIG5wOworfQorCitzdGF0aWMgaW50CitsaXN0X2NsZWFyKFB5TGlzdE9iamVjdCAqYSkKK3sKKyAgICBQeV9zc2l6ZV90IGk7CisgICAgUHlPYmplY3QgKippdGVtID0gYS0+b2JfaXRlbTsKKyAgICBpZiAoaXRlbSAhPSBOVUxMKSB7CisgICAgICAgIC8qIEJlY2F1c2UgWERFQ1JFRiBjYW4gcmVjdXJzaXZlbHkgaW52b2tlIG9wZXJhdGlvbnMgb24KKyAgICAgICAgICAgdGhpcyBsaXN0LCB3ZSBtYWtlIGl0IGVtcHR5IGZpcnN0LiAqLworICAgICAgICBpID0gUHlfU0laRShhKTsKKyAgICAgICAgUHlfU0laRShhKSA9IDA7CisgICAgICAgIGEtPm9iX2l0ZW0gPSBOVUxMOworICAgICAgICBhLT5hbGxvY2F0ZWQgPSAwOworICAgICAgICB3aGlsZSAoLS1pID49IDApIHsKKyAgICAgICAgICAgIFB5X1hERUNSRUYoaXRlbVtpXSk7CisgICAgICAgIH0KKyAgICAgICAgUHlNZW1fRlJFRShpdGVtKTsKKyAgICB9CisgICAgLyogTmV2ZXIgZmFpbHM7IHRoZSByZXR1cm4gdmFsdWUgY2FuIGJlIGlnbm9yZWQuCisgICAgICAgTm90ZSB0aGF0IHRoZXJlIGlzIG5vIGd1YXJhbnRlZSB0aGF0IHRoZSBsaXN0IGlzIGFjdHVhbGx5IGVtcHR5CisgICAgICAgYXQgdGhpcyBwb2ludCwgYmVjYXVzZSBYREVDUkVGIG1heSBoYXZlIHBvcHVsYXRlZCBpdCBhZ2FpbiEgKi8KKyAgICByZXR1cm4gMDsKK30KKworLyogYVtpbG93OmloaWdoXSA9IHYgaWYgdiAhPSBOVUxMLgorICogZGVsIGFbaWxvdzppaGlnaF0gaWYgdiA9PSBOVUxMLgorICoKKyAqIFNwZWNpYWwgc3BlZWQgZ2ltbWljazogIHdoZW4gdiBpcyBOVUxMIGFuZCBpaGlnaCAtIGlsb3cgPD0gOCwgaXQncworICogZ3VhcmFudGVlZCB0aGUgY2FsbCBjYW5ub3QgZmFpbC4KKyAqLworc3RhdGljIGludAorbGlzdF9hc3Nfc2xpY2UoUHlMaXN0T2JqZWN0ICphLCBQeV9zc2l6ZV90IGlsb3csIFB5X3NzaXplX3QgaWhpZ2gsIFB5T2JqZWN0ICp2KQoreworICAgIC8qIEJlY2F1c2UgW1hdREVDUkVGIGNhbiByZWN1cnNpdmVseSBpbnZva2UgbGlzdCBvcGVyYXRpb25zIG9uCisgICAgICAgdGhpcyBsaXN0LCB3ZSBtdXN0IHBvc3Rwb25lIGFsbCBbWF1ERUNSRUYgYWN0aXZpdHkgdW50aWwKKyAgICAgICBhZnRlciB0aGUgbGlzdCBpcyBiYWNrIGluIGl0cyBjYW5vbmljYWwgc2hhcGUuICBUaGVyZWZvcmUKKyAgICAgICB3ZSBtdXN0IGFsbG9jYXRlIGFuIGFkZGl0aW9uYWwgYXJyYXksICdyZWN5Y2xlJywgaW50byB3aGljaAorICAgICAgIHdlIHRlbXBvcmFyaWx5IGNvcHkgdGhlIGl0ZW1zIHRoYXQgYXJlIGRlbGV0ZWQgZnJvbSB0aGUKKyAgICAgICBsaXN0LiA6LSggKi8KKyAgICBQeU9iamVjdCAqcmVjeWNsZV9vbl9zdGFja1s4XTsKKyAgICBQeU9iamVjdCAqKnJlY3ljbGUgPSByZWN5Y2xlX29uX3N0YWNrOyAvKiB3aWxsIGFsbG9jYXRlIG1vcmUgaWYgbmVlZGVkICovCisgICAgUHlPYmplY3QgKippdGVtOworICAgIFB5T2JqZWN0ICoqdml0ZW0gPSBOVUxMOworICAgIFB5T2JqZWN0ICp2X2FzX1NGID0gTlVMTDsgLyogUHlTZXF1ZW5jZV9GYXN0KHYpICovCisgICAgUHlfc3NpemVfdCBuOyAvKiAjIG9mIGVsZW1lbnRzIGluIHJlcGxhY2VtZW50IGxpc3QgKi8KKyAgICBQeV9zc2l6ZV90IG5vcmlnOyAvKiAjIG9mIGVsZW1lbnRzIGluIGxpc3QgZ2V0dGluZyByZXBsYWNlZCAqLworICAgIFB5X3NzaXplX3QgZDsgLyogQ2hhbmdlIGluIHNpemUgKi8KKyAgICBQeV9zc2l6ZV90IGs7CisgICAgc2l6ZV90IHM7CisgICAgaW50IHJlc3VsdCA9IC0xOyAgICAgICAgICAgIC8qIGd1aWx0eSB1bnRpbCBwcm92ZWQgaW5ub2NlbnQgKi8KKyNkZWZpbmUgYiAoKFB5TGlzdE9iamVjdCAqKXYpCisgICAgaWYgKHYgPT0gTlVMTCkKKyAgICAgICAgbiA9IDA7CisgICAgZWxzZSB7CisgICAgICAgIGlmIChhID09IGIpIHsKKyAgICAgICAgICAgIC8qIFNwZWNpYWwgY2FzZSAiYVtpOmpdID0gYSIgLS0gY29weSBiIGZpcnN0ICovCisgICAgICAgICAgICB2ID0gbGlzdF9zbGljZShiLCAwLCBQeV9TSVpFKGIpKTsKKyAgICAgICAgICAgIGlmICh2ID09IE5VTEwpCisgICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICAgICAgICAgIHJlc3VsdCA9IGxpc3RfYXNzX3NsaWNlKGEsIGlsb3csIGloaWdoLCB2KTsKKyAgICAgICAgICAgIFB5X0RFQ1JFRih2KTsKKyAgICAgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgICAgIH0KKyAgICAgICAgdl9hc19TRiA9IFB5U2VxdWVuY2VfRmFzdCh2LCAiY2FuIG9ubHkgYXNzaWduIGFuIGl0ZXJhYmxlIik7CisgICAgICAgIGlmKHZfYXNfU0YgPT0gTlVMTCkKKyAgICAgICAgICAgIGdvdG8gRXJyb3I7CisgICAgICAgIG4gPSBQeVNlcXVlbmNlX0Zhc3RfR0VUX1NJWkUodl9hc19TRik7CisgICAgICAgIHZpdGVtID0gUHlTZXF1ZW5jZV9GYXN0X0lURU1TKHZfYXNfU0YpOworICAgIH0KKyAgICBpZiAoaWxvdyA8IDApCisgICAgICAgIGlsb3cgPSAwOworICAgIGVsc2UgaWYgKGlsb3cgPiBQeV9TSVpFKGEpKQorICAgICAgICBpbG93ID0gUHlfU0laRShhKTsKKworICAgIGlmIChpaGlnaCA8IGlsb3cpCisgICAgICAgIGloaWdoID0gaWxvdzsKKyAgICBlbHNlIGlmIChpaGlnaCA+IFB5X1NJWkUoYSkpCisgICAgICAgIGloaWdoID0gUHlfU0laRShhKTsKKworICAgIG5vcmlnID0gaWhpZ2ggLSBpbG93OworICAgIGFzc2VydChub3JpZyA+PSAwKTsKKyAgICBkID0gbiAtIG5vcmlnOworICAgIGlmIChQeV9TSVpFKGEpICsgZCA9PSAwKSB7CisgICAgICAgIFB5X1hERUNSRUYodl9hc19TRik7CisgICAgICAgIHJldHVybiBsaXN0X2NsZWFyKGEpOworICAgIH0KKyAgICBpdGVtID0gYS0+b2JfaXRlbTsKKyAgICAvKiByZWN5Y2xlIHRoZSBpdGVtcyB0aGF0IHdlIGFyZSBhYm91dCB0byByZW1vdmUgKi8KKyAgICBzID0gbm9yaWcgKiBzaXplb2YoUHlPYmplY3QgKik7CisgICAgaWYgKHMgPiBzaXplb2YocmVjeWNsZV9vbl9zdGFjaykpIHsKKyAgICAgICAgcmVjeWNsZSA9IChQeU9iamVjdCAqKilQeU1lbV9NQUxMT0Mocyk7CisgICAgICAgIGlmIChyZWN5Y2xlID09IE5VTEwpIHsKKyAgICAgICAgICAgIFB5RXJyX05vTWVtb3J5KCk7CisgICAgICAgICAgICBnb3RvIEVycm9yOworICAgICAgICB9CisgICAgfQorICAgIG1lbWNweShyZWN5Y2xlLCAmaXRlbVtpbG93XSwgcyk7CisKKyAgICBpZiAoZCA8IDApIHsgLyogRGVsZXRlIC1kIGl0ZW1zICovCisgICAgICAgIG1lbW1vdmUoJml0ZW1baWhpZ2grZF0sICZpdGVtW2loaWdoXSwKKyAgICAgICAgICAgIChQeV9TSVpFKGEpIC0gaWhpZ2gpKnNpemVvZihQeU9iamVjdCAqKSk7CisgICAgICAgIGxpc3RfcmVzaXplKGEsIFB5X1NJWkUoYSkgKyBkKTsKKyAgICAgICAgaXRlbSA9IGEtPm9iX2l0ZW07CisgICAgfQorICAgIGVsc2UgaWYgKGQgPiAwKSB7IC8qIEluc2VydCBkIGl0ZW1zICovCisgICAgICAgIGsgPSBQeV9TSVpFKGEpOworICAgICAgICBpZiAobGlzdF9yZXNpemUoYSwgaytkKSA8IDApCisgICAgICAgICAgICBnb3RvIEVycm9yOworICAgICAgICBpdGVtID0gYS0+b2JfaXRlbTsKKyAgICAgICAgbWVtbW92ZSgmaXRlbVtpaGlnaCtkXSwgJml0ZW1baWhpZ2hdLAorICAgICAgICAgICAgKGsgLSBpaGlnaCkqc2l6ZW9mKFB5T2JqZWN0ICopKTsKKyAgICB9CisgICAgZm9yIChrID0gMDsgayA8IG47IGsrKywgaWxvdysrKSB7CisgICAgICAgIFB5T2JqZWN0ICp3ID0gdml0ZW1ba107CisgICAgICAgIFB5X1hJTkNSRUYodyk7CisgICAgICAgIGl0ZW1baWxvd10gPSB3OworICAgIH0KKyAgICBmb3IgKGsgPSBub3JpZyAtIDE7IGsgPj0gMDsgLS1rKQorICAgICAgICBQeV9YREVDUkVGKHJlY3ljbGVba10pOworICAgIHJlc3VsdCA9IDA7CisgRXJyb3I6CisgICAgaWYgKHJlY3ljbGUgIT0gcmVjeWNsZV9vbl9zdGFjaykKKyAgICAgICAgUHlNZW1fRlJFRShyZWN5Y2xlKTsKKyAgICBQeV9YREVDUkVGKHZfYXNfU0YpOworICAgIHJldHVybiByZXN1bHQ7CisjdW5kZWYgYgorfQorCitpbnQKK1B5TGlzdF9TZXRTbGljZShQeU9iamVjdCAqYSwgUHlfc3NpemVfdCBpbG93LCBQeV9zc2l6ZV90IGloaWdoLCBQeU9iamVjdCAqdikKK3sKKyAgICBpZiAoIVB5TGlzdF9DaGVjayhhKSkgeworICAgICAgICBQeUVycl9CYWRJbnRlcm5hbENhbGwoKTsKKyAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKyAgICByZXR1cm4gbGlzdF9hc3Nfc2xpY2UoKFB5TGlzdE9iamVjdCAqKWEsIGlsb3csIGloaWdoLCB2KTsKK30KKworc3RhdGljIFB5T2JqZWN0ICoKK2xpc3RfaW5wbGFjZV9yZXBlYXQoUHlMaXN0T2JqZWN0ICpzZWxmLCBQeV9zc2l6ZV90IG4pCit7CisgICAgUHlPYmplY3QgKippdGVtczsKKyAgICBQeV9zc2l6ZV90IHNpemUsIGksIGosIHA7CisKKworICAgIHNpemUgPSBQeUxpc3RfR0VUX1NJWkUoc2VsZik7CisgICAgaWYgKHNpemUgPT0gMCB8fCBuID09IDEpIHsKKyAgICAgICAgUHlfSU5DUkVGKHNlbGYpOworICAgICAgICByZXR1cm4gKFB5T2JqZWN0ICopc2VsZjsKKyAgICB9CisKKyAgICBpZiAobiA8IDEpIHsKKyAgICAgICAgKHZvaWQpbGlzdF9jbGVhcihzZWxmKTsKKyAgICAgICAgUHlfSU5DUkVGKHNlbGYpOworICAgICAgICByZXR1cm4gKFB5T2JqZWN0ICopc2VsZjsKKyAgICB9CisKKyAgICBpZiAoc2l6ZSA+IFBZX1NTSVpFX1RfTUFYIC8gbikgeworICAgICAgICByZXR1cm4gUHlFcnJfTm9NZW1vcnkoKTsKKyAgICB9CisKKyAgICBpZiAobGlzdF9yZXNpemUoc2VsZiwgc2l6ZSpuKSA9PSAtMSkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisKKyAgICBwID0gc2l6ZTsKKyAgICBpdGVtcyA9IHNlbGYtPm9iX2l0ZW07CisgICAgZm9yIChpID0gMTsgaSA8IG47IGkrKykgeyAvKiBTdGFydCBjb3VudGluZyBhdCAxLCBub3QgMCAqLworICAgICAgICBmb3IgKGogPSAwOyBqIDwgc2l6ZTsgaisrKSB7CisgICAgICAgICAgICBQeU9iamVjdCAqbyA9IGl0ZW1zW2pdOworICAgICAgICAgICAgUHlfSU5DUkVGKG8pOworICAgICAgICAgICAgaXRlbXNbcCsrXSA9IG87CisgICAgICAgIH0KKyAgICB9CisgICAgUHlfSU5DUkVGKHNlbGYpOworICAgIHJldHVybiAoUHlPYmplY3QgKilzZWxmOworfQorCitzdGF0aWMgaW50CitsaXN0X2Fzc19pdGVtKFB5TGlzdE9iamVjdCAqYSwgUHlfc3NpemVfdCBpLCBQeU9iamVjdCAqdikKK3sKKyAgICBQeU9iamVjdCAqb2xkX3ZhbHVlOworICAgIGlmIChpIDwgMCB8fCBpID49IFB5X1NJWkUoYSkpIHsKKyAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX0luZGV4RXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAgICAibGlzdCBhc3NpZ25tZW50IGluZGV4IG91dCBvZiByYW5nZSIpOworICAgICAgICByZXR1cm4gLTE7CisgICAgfQorICAgIGlmICh2ID09IE5VTEwpCisgICAgICAgIHJldHVybiBsaXN0X2Fzc19zbGljZShhLCBpLCBpKzEsIHYpOworICAgIFB5X0lOQ1JFRih2KTsKKyAgICBvbGRfdmFsdWUgPSBhLT5vYl9pdGVtW2ldOworICAgIGEtPm9iX2l0ZW1baV0gPSB2OworICAgIFB5X0RFQ1JFRihvbGRfdmFsdWUpOworICAgIHJldHVybiAwOworfQorCitzdGF0aWMgUHlPYmplY3QgKgorbGlzdGluc2VydChQeUxpc3RPYmplY3QgKnNlbGYsIFB5T2JqZWN0ICphcmdzKQoreworICAgIFB5X3NzaXplX3QgaTsKKyAgICBQeU9iamVjdCAqdjsKKyAgICBpZiAoIVB5QXJnX1BhcnNlVHVwbGUoYXJncywgIm5POmluc2VydCIsICZpLCAmdikpCisgICAgICAgIHJldHVybiBOVUxMOworICAgIGlmIChpbnMxKHNlbGYsIGksIHYpID09IDApCisgICAgICAgIFB5X1JFVFVSTl9OT05FOworICAgIHJldHVybiBOVUxMOworfQorCitzdGF0aWMgUHlPYmplY3QgKgorbGlzdGFwcGVuZChQeUxpc3RPYmplY3QgKnNlbGYsIFB5T2JqZWN0ICp2KQoreworICAgIGlmIChhcHAxKHNlbGYsIHYpID09IDApCisgICAgICAgIFB5X1JFVFVSTl9OT05FOworICAgIHJldHVybiBOVUxMOworfQorCitzdGF0aWMgUHlPYmplY3QgKgorbGlzdGV4dGVuZChQeUxpc3RPYmplY3QgKnNlbGYsIFB5T2JqZWN0ICpiKQoreworICAgIFB5T2JqZWN0ICppdDsgICAgICAvKiBpdGVyKHYpICovCisgICAgUHlfc3NpemVfdCBtOyAgICAgICAgICAgICAgICAgIC8qIHNpemUgb2Ygc2VsZiAqLworICAgIFB5X3NzaXplX3QgbjsgICAgICAgICAgICAgICAgICAvKiBndWVzcyBmb3Igc2l6ZSBvZiBiICovCisgICAgUHlfc3NpemVfdCBtbjsgICAgICAgICAgICAgICAgIC8qIG0gKyBuICovCisgICAgUHlfc3NpemVfdCBpOworICAgIFB5T2JqZWN0ICooKml0ZXJuZXh0KShQeU9iamVjdCAqKTsKKworICAgIC8qIFNwZWNpYWwgY2FzZXM6CisgICAgICAgMSkgbGlzdHMgYW5kIHR1cGxlcyB3aGljaCBjYW4gdXNlIFB5U2VxdWVuY2VfRmFzdCBvcHMKKyAgICAgICAyKSBleHRlbmRpbmcgc2VsZiB0byBzZWxmIHJlcXVpcmVzIG1ha2luZyBhIGNvcHkgZmlyc3QKKyAgICAqLworICAgIGlmIChQeUxpc3RfQ2hlY2tFeGFjdChiKSB8fCBQeVR1cGxlX0NoZWNrRXhhY3QoYikgfHwgKFB5T2JqZWN0ICopc2VsZiA9PSBiKSB7CisgICAgICAgIFB5T2JqZWN0ICoqc3JjLCAqKmRlc3Q7CisgICAgICAgIGIgPSBQeVNlcXVlbmNlX0Zhc3QoYiwgImFyZ3VtZW50IG11c3QgYmUgaXRlcmFibGUiKTsKKyAgICAgICAgaWYgKCFiKQorICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgICAgIG4gPSBQeVNlcXVlbmNlX0Zhc3RfR0VUX1NJWkUoYik7CisgICAgICAgIGlmIChuID09IDApIHsKKyAgICAgICAgICAgIC8qIHNob3J0IGNpcmN1aXQgd2hlbiBiIGlzIGVtcHR5ICovCisgICAgICAgICAgICBQeV9ERUNSRUYoYik7CisgICAgICAgICAgICBQeV9SRVRVUk5fTk9ORTsKKyAgICAgICAgfQorICAgICAgICBtID0gUHlfU0laRShzZWxmKTsKKyAgICAgICAgaWYgKGxpc3RfcmVzaXplKHNlbGYsIG0gKyBuKSA9PSAtMSkgeworICAgICAgICAgICAgUHlfREVDUkVGKGIpOworICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgICAgIH0KKyAgICAgICAgLyogbm90ZSB0aGF0IHdlIG1heSBzdGlsbCBoYXZlIHNlbGYgPT0gYiBoZXJlIGZvciB0aGUKKyAgICAgICAgICogc2l0dWF0aW9uIGEuZXh0ZW5kKGEpLCBidXQgdGhlIGZvbGxvd2luZyBjb2RlIHdvcmtzCisgICAgICAgICAqIGluIHRoYXQgY2FzZSB0b28uICBKdXN0IG1ha2Ugc3VyZSB0byByZXNpemUgc2VsZgorICAgICAgICAgKiBiZWZvcmUgY2FsbGluZyBQeVNlcXVlbmNlX0Zhc3RfSVRFTVMuCisgICAgICAgICAqLworICAgICAgICAvKiBwb3B1bGF0ZSB0aGUgZW5kIG9mIHNlbGYgd2l0aCBiJ3MgaXRlbXMgKi8KKyAgICAgICAgc3JjID0gUHlTZXF1ZW5jZV9GYXN0X0lURU1TKGIpOworICAgICAgICBkZXN0ID0gc2VsZi0+b2JfaXRlbSArIG07CisgICAgICAgIGZvciAoaSA9IDA7IGkgPCBuOyBpKyspIHsKKyAgICAgICAgICAgIFB5T2JqZWN0ICpvID0gc3JjW2ldOworICAgICAgICAgICAgUHlfSU5DUkVGKG8pOworICAgICAgICAgICAgZGVzdFtpXSA9IG87CisgICAgICAgIH0KKyAgICAgICAgUHlfREVDUkVGKGIpOworICAgICAgICBQeV9SRVRVUk5fTk9ORTsKKyAgICB9CisKKyAgICBpdCA9IFB5T2JqZWN0X0dldEl0ZXIoYik7CisgICAgaWYgKGl0ID09IE5VTEwpCisgICAgICAgIHJldHVybiBOVUxMOworICAgIGl0ZXJuZXh0ID0gKml0LT5vYl90eXBlLT50cF9pdGVybmV4dDsKKworICAgIC8qIEd1ZXNzIGEgcmVzdWx0IGxpc3Qgc2l6ZS4gKi8KKyAgICBuID0gX1B5T2JqZWN0X0xlbmd0aEhpbnQoYiwgOCk7CisgICAgaWYgKG4gPT0gLTEpIHsKKyAgICAgICAgUHlfREVDUkVGKGl0KTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIG0gPSBQeV9TSVpFKHNlbGYpOworICAgIG1uID0gbSArIG47CisgICAgaWYgKG1uID49IG0pIHsKKyAgICAgICAgLyogTWFrZSByb29tLiAqLworICAgICAgICBpZiAobGlzdF9yZXNpemUoc2VsZiwgbW4pID09IC0xKQorICAgICAgICAgICAgZ290byBlcnJvcjsKKyAgICAgICAgLyogTWFrZSB0aGUgbGlzdCBzYW5lIGFnYWluLiAqLworICAgICAgICBQeV9TSVpFKHNlbGYpID0gbTsKKyAgICB9CisgICAgLyogRWxzZSBtICsgbiBvdmVyZmxvd2VkOyBvbiB0aGUgY2hhbmNlIHRoYXQgbiBsaWVkLCBhbmQgdGhlcmUgcmVhbGx5CisgICAgICogaXMgZW5vdWdoIHJvb20sIGlnbm9yZSBpdC4gIElmIG4gd2FzIHRlbGxpbmcgdGhlIHRydXRoLCB3ZSdsbAorICAgICAqIGV2ZW50dWFsbHkgcnVuIG91dCBvZiBtZW1vcnkgZHVyaW5nIHRoZSBsb29wLgorICAgICAqLworCisgICAgLyogUnVuIGl0ZXJhdG9yIHRvIGV4aGF1c3Rpb24uICovCisgICAgZm9yICg7OykgeworICAgICAgICBQeU9iamVjdCAqaXRlbSA9IGl0ZXJuZXh0KGl0KTsKKyAgICAgICAgaWYgKGl0ZW0gPT0gTlVMTCkgeworICAgICAgICAgICAgaWYgKFB5RXJyX09jY3VycmVkKCkpIHsKKyAgICAgICAgICAgICAgICBpZiAoUHlFcnJfRXhjZXB0aW9uTWF0Y2hlcyhQeUV4Y19TdG9wSXRlcmF0aW9uKSkKKyAgICAgICAgICAgICAgICAgICAgUHlFcnJfQ2xlYXIoKTsKKyAgICAgICAgICAgICAgICBlbHNlCisgICAgICAgICAgICAgICAgICAgIGdvdG8gZXJyb3I7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgfQorICAgICAgICBpZiAoUHlfU0laRShzZWxmKSA8IHNlbGYtPmFsbG9jYXRlZCkgeworICAgICAgICAgICAgLyogc3RlYWxzIHJlZiAqLworICAgICAgICAgICAgUHlMaXN0X1NFVF9JVEVNKHNlbGYsIFB5X1NJWkUoc2VsZiksIGl0ZW0pOworICAgICAgICAgICAgKytQeV9TSVpFKHNlbGYpOworICAgICAgICB9CisgICAgICAgIGVsc2UgeworICAgICAgICAgICAgaW50IHN0YXR1cyA9IGFwcDEoc2VsZiwgaXRlbSk7CisgICAgICAgICAgICBQeV9ERUNSRUYoaXRlbSk7ICAvKiBhcHBlbmQgY3JlYXRlcyBhIG5ldyByZWYgKi8KKyAgICAgICAgICAgIGlmIChzdGF0dXMgPCAwKQorICAgICAgICAgICAgICAgIGdvdG8gZXJyb3I7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKiBDdXQgYmFjayByZXN1bHQgbGlzdCBpZiBpbml0aWFsIGd1ZXNzIHdhcyB0b28gbGFyZ2UuICovCisgICAgaWYgKFB5X1NJWkUoc2VsZikgPCBzZWxmLT5hbGxvY2F0ZWQpCisgICAgICAgIGxpc3RfcmVzaXplKHNlbGYsIFB5X1NJWkUoc2VsZikpOyAgLyogc2hyaW5raW5nIGNhbid0IGZhaWwgKi8KKworICAgIFB5X0RFQ1JFRihpdCk7CisgICAgUHlfUkVUVVJOX05PTkU7CisKKyAgZXJyb3I6CisgICAgUHlfREVDUkVGKGl0KTsKKyAgICByZXR1cm4gTlVMTDsKK30KKworUHlPYmplY3QgKgorX1B5TGlzdF9FeHRlbmQoUHlMaXN0T2JqZWN0ICpzZWxmLCBQeU9iamVjdCAqYikKK3sKKyAgICByZXR1cm4gbGlzdGV4dGVuZChzZWxmLCBiKTsKK30KKworc3RhdGljIFB5T2JqZWN0ICoKK2xpc3RfaW5wbGFjZV9jb25jYXQoUHlMaXN0T2JqZWN0ICpzZWxmLCBQeU9iamVjdCAqb3RoZXIpCit7CisgICAgUHlPYmplY3QgKnJlc3VsdDsKKworICAgIHJlc3VsdCA9IGxpc3RleHRlbmQoc2VsZiwgb3RoZXIpOworICAgIGlmIChyZXN1bHQgPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICBQeV9ERUNSRUYocmVzdWx0KTsKKyAgICBQeV9JTkNSRUYoc2VsZik7CisgICAgcmV0dXJuIChQeU9iamVjdCAqKXNlbGY7Cit9CisKK3N0YXRpYyBQeU9iamVjdCAqCitsaXN0cG9wKFB5TGlzdE9iamVjdCAqc2VsZiwgUHlPYmplY3QgKmFyZ3MpCit7CisgICAgUHlfc3NpemVfdCBpID0gLTE7CisgICAgUHlPYmplY3QgKnY7CisgICAgaW50IHN0YXR1czsKKworICAgIGlmICghUHlBcmdfUGFyc2VUdXBsZShhcmdzLCAifG46cG9wIiwgJmkpKQorICAgICAgICByZXR1cm4gTlVMTDsKKworICAgIGlmIChQeV9TSVpFKHNlbGYpID09IDApIHsKKyAgICAgICAgLyogU3BlY2lhbC1jYXNlIG1vc3QgY29tbW9uIGZhaWx1cmUgY2F1c2UgKi8KKyAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX0luZGV4RXJyb3IsICJwb3AgZnJvbSBlbXB0eSBsaXN0Iik7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICBpZiAoaSA8IDApCisgICAgICAgIGkgKz0gUHlfU0laRShzZWxmKTsKKyAgICBpZiAoaSA8IDAgfHwgaSA+PSBQeV9TSVpFKHNlbGYpKSB7CisgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19JbmRleEVycm9yLCAicG9wIGluZGV4IG91dCBvZiByYW5nZSIpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgdiA9IHNlbGYtPm9iX2l0ZW1baV07CisgICAgaWYgKGkgPT0gUHlfU0laRShzZWxmKSAtIDEpIHsKKyAgICAgICAgc3RhdHVzID0gbGlzdF9yZXNpemUoc2VsZiwgUHlfU0laRShzZWxmKSAtIDEpOworICAgICAgICBhc3NlcnQoc3RhdHVzID49IDApOworICAgICAgICByZXR1cm4gdjsgLyogYW5kIHYgbm93IG93bnMgdGhlIHJlZmVyZW5jZSB0aGUgbGlzdCBoYWQgKi8KKyAgICB9CisgICAgUHlfSU5DUkVGKHYpOworICAgIHN0YXR1cyA9IGxpc3RfYXNzX3NsaWNlKHNlbGYsIGksIGkrMSwgKFB5T2JqZWN0ICopTlVMTCk7CisgICAgYXNzZXJ0KHN0YXR1cyA+PSAwKTsKKyAgICAvKiBVc2Ugc3RhdHVzLCBzbyB0aGF0IGluIGEgcmVsZWFzZSBidWlsZCBjb21waWxlcnMgZG9uJ3QKKyAgICAgKiBjb21wbGFpbiBhYm91dCB0aGUgdW51c2VkIG5hbWUuCisgICAgICovCisgICAgKHZvaWQpIHN0YXR1czsKKworICAgIHJldHVybiB2OworfQorCisvKiBSZXZlcnNlIGEgc2xpY2Ugb2YgYSBsaXN0IGluIHBsYWNlLCBmcm9tIGxvIHVwIHRvIChleGNsdXNpdmUpIGhpLiAqLworc3RhdGljIHZvaWQKK3JldmVyc2Vfc2xpY2UoUHlPYmplY3QgKipsbywgUHlPYmplY3QgKipoaSkKK3sKKyAgICBhc3NlcnQobG8gJiYgaGkpOworCisgICAgLS1oaTsKKyAgICB3aGlsZSAobG8gPCBoaSkgeworICAgICAgICBQeU9iamVjdCAqdCA9ICpsbzsKKyAgICAgICAgKmxvID0gKmhpOworICAgICAgICAqaGkgPSB0OworICAgICAgICArK2xvOworICAgICAgICAtLWhpOworICAgIH0KK30KKworLyogTG90cyBvZiBjb2RlIGZvciBhbiBhZGFwdGl2ZSwgc3RhYmxlLCBuYXR1cmFsIG1lcmdlc29ydC4gIFRoZXJlIGFyZSBtYW55CisgKiBwaWVjZXMgdG8gdGhpcyBhbGdvcml0aG07IHJlYWQgbGlzdHNvcnQudHh0IGZvciBvdmVydmlld3MgYW5kIGRldGFpbHMuCisgKi8KKworLyogQ29tcGFyaXNvbiBmdW5jdGlvbi4gIFRha2VzIGNhcmUgb2YgY2FsbGluZyBhIHVzZXItc3VwcGxpZWQKKyAqIGNvbXBhcmlzb24gZnVuY3Rpb24gKGFueSBjYWxsYWJsZSBQeXRob24gb2JqZWN0KSwgd2hpY2ggbXVzdCBub3QgYmUKKyAqIE5VTEwgKHVzZSB0aGUgSVNMVCBtYWNybyBpZiB5b3UgZG9uJ3Qga25vdywgb3IgY2FsbCBQeU9iamVjdF9SaWNoQ29tcGFyZUJvb2wKKyAqIHdpdGggUHlfTFQgaWYgeW91IGtub3cgaXQncyBOVUxMKS4KKyAqIFJldHVybnMgLTEgb24gZXJyb3IsIDEgaWYgeCA8IHksIDAgaWYgeCA+PSB5LgorICovCitzdGF0aWMgaW50Citpc2x0KFB5T2JqZWN0ICp4LCBQeU9iamVjdCAqeSwgUHlPYmplY3QgKmNvbXBhcmUpCit7CisgICAgUHlPYmplY3QgKnJlczsKKyAgICBQeU9iamVjdCAqYXJnczsKKyAgICBQeV9zc2l6ZV90IGk7CisKKyAgICBhc3NlcnQoY29tcGFyZSAhPSBOVUxMKTsKKyAgICAvKiBDYWxsIHRoZSB1c2VyJ3MgY29tcGFyaXNvbiBmdW5jdGlvbiBhbmQgdHJhbnNsYXRlIHRoZSAzLXdheQorICAgICAqIHJlc3VsdCBpbnRvIHRydWUgb3IgZmFsc2UgKG9yIGVycm9yKS4KKyAgICAgKi8KKyAgICBhcmdzID0gUHlUdXBsZV9OZXcoMik7CisgICAgaWYgKGFyZ3MgPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIC0xOworICAgIFB5X0lOQ1JFRih4KTsKKyAgICBQeV9JTkNSRUYoeSk7CisgICAgUHlUdXBsZV9TRVRfSVRFTShhcmdzLCAwLCB4KTsKKyAgICBQeVR1cGxlX1NFVF9JVEVNKGFyZ3MsIDEsIHkpOworICAgIHJlcyA9IFB5T2JqZWN0X0NhbGwoY29tcGFyZSwgYXJncywgTlVMTCk7CisgICAgUHlfREVDUkVGKGFyZ3MpOworICAgIGlmIChyZXMgPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIC0xOworICAgIGlmICghUHlJbnRfQ2hlY2socmVzKSkgeworICAgICAgICBQeUVycl9Gb3JtYXQoUHlFeGNfVHlwZUVycm9yLAorICAgICAgICAgICAgICAgICAgICAgImNvbXBhcmlzb24gZnVuY3Rpb24gbXVzdCByZXR1cm4gaW50LCBub3QgJS4yMDBzIiwKKyAgICAgICAgICAgICAgICAgICAgIHJlcy0+b2JfdHlwZS0+dHBfbmFtZSk7CisgICAgICAgIFB5X0RFQ1JFRihyZXMpOworICAgICAgICByZXR1cm4gLTE7CisgICAgfQorICAgIGkgPSBQeUludF9Bc0xvbmcocmVzKTsKKyAgICBQeV9ERUNSRUYocmVzKTsKKyAgICByZXR1cm4gaSA8IDA7Cit9CisKKy8qIElmIENPTVBBUkUgaXMgTlVMTCwgY2FsbHMgUHlPYmplY3RfUmljaENvbXBhcmVCb29sIHdpdGggUHlfTFQsIGVsc2UgY2FsbHMKKyAqIGlzbHQuICBUaGlzIGF2b2lkcyBhIGxheWVyIG9mIGZ1bmN0aW9uIGNhbGwgaW4gdGhlIHVzdWFsIGNhc2UsIGFuZAorICogc29ydGluZyBkb2VzIG1hbnkgY29tcGFyaXNvbnMuCisgKiBSZXR1cm5zIC0xIG9uIGVycm9yLCAxIGlmIHggPCB5LCAwIGlmIHggPj0geS4KKyAqLworI2RlZmluZSBJU0xUKFgsIFksIENPTVBBUkUpICgoQ09NUEFSRSkgPT0gTlVMTCA/ICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgICAgICAgICBQeU9iamVjdF9SaWNoQ29tcGFyZUJvb2woWCwgWSwgUHlfTFQpIDogICAgICAgICAgICAgICAgXAorICAgICAgICAgICAgICAgICBpc2x0KFgsIFksIENPTVBBUkUpKQorCisvKiBDb21wYXJlIFggdG8gWSB2aWEgIjwiLiAgR290byAiZmFpbCIgaWYgdGhlIGNvbXBhcmlzb24gcmFpc2VzIGFuCisgICBlcnJvci4gIEVsc2UgImsiIGlzIHNldCB0byB0cnVlIGlmZiBYPFksIGFuZCBhbiAiaWYgKGspIiBibG9jayBpcworICAgc3RhcnRlZC4gIEl0IG1ha2VzIG1vcmUgc2Vuc2UgaW4gY29udGV4dCA8d2luaz4uICBYIGFuZCBZIGFyZSBQeU9iamVjdCpzLgorKi8KKyNkZWZpbmUgSUZMVChYLCBZKSBpZiAoKGsgPSBJU0xUKFgsIFksIGNvbXBhcmUpKSA8IDApIGdvdG8gZmFpbDsgIFwKKyAgICAgICAgICAgaWYgKGspCisKKy8qIGJpbmFyeXNvcnQgaXMgdGhlIGJlc3QgbWV0aG9kIGZvciBzb3J0aW5nIHNtYWxsIGFycmF5czogaXQgZG9lcworICAgZmV3IGNvbXBhcmVzLCBidXQgY2FuIGRvIGRhdGEgbW92ZW1lbnQgcXVhZHJhdGljIGluIHRoZSBudW1iZXIgb2YKKyAgIGVsZW1lbnRzLgorICAgW2xvLCBoaSkgaXMgYSBjb250aWd1b3VzIHNsaWNlIG9mIGEgbGlzdCwgYW5kIGlzIHNvcnRlZCB2aWEKKyAgIGJpbmFyeSBpbnNlcnRpb24uICBUaGlzIHNvcnQgaXMgc3RhYmxlLgorICAgT24gZW50cnksIG11c3QgaGF2ZSBsbyA8PSBzdGFydCA8PSBoaSwgYW5kIHRoYXQgW2xvLCBzdGFydCkgaXMgYWxyZWFkeQorICAgc29ydGVkIChwYXNzIHN0YXJ0ID09IGxvIGlmIHlvdSBkb24ndCBrbm93ISkuCisgICBJZiBpc2x0KCkgY29tcGxhaW5zIHJldHVybiAtMSwgZWxzZSAwLgorICAgRXZlbiBpbiBjYXNlIG9mIGVycm9yLCB0aGUgb3V0cHV0IHNsaWNlIHdpbGwgYmUgc29tZSBwZXJtdXRhdGlvbiBvZgorICAgdGhlIGlucHV0IChub3RoaW5nIGlzIGxvc3Qgb3IgZHVwbGljYXRlZCkuCisqLworc3RhdGljIGludAorYmluYXJ5c29ydChQeU9iamVjdCAqKmxvLCBQeU9iamVjdCAqKmhpLCBQeU9iamVjdCAqKnN0YXJ0LCBQeU9iamVjdCAqY29tcGFyZSkKKyAgICAgLyogY29tcGFyZSAtLSBjb21wYXJpc29uIGZ1bmN0aW9uIG9iamVjdCwgb3IgTlVMTCBmb3IgZGVmYXVsdCAqLworeworICAgIHJlZ2lzdGVyIFB5X3NzaXplX3QgazsKKyAgICByZWdpc3RlciBQeU9iamVjdCAqKmwsICoqcCwgKipyOworICAgIHJlZ2lzdGVyIFB5T2JqZWN0ICpwaXZvdDsKKworICAgIGFzc2VydChsbyA8PSBzdGFydCAmJiBzdGFydCA8PSBoaSk7CisgICAgLyogYXNzZXJ0IFtsbywgc3RhcnQpIGlzIHNvcnRlZCAqLworICAgIGlmIChsbyA9PSBzdGFydCkKKyAgICAgICAgKytzdGFydDsKKyAgICBmb3IgKDsgc3RhcnQgPCBoaTsgKytzdGFydCkgeworICAgICAgICAvKiBzZXQgbCB0byB3aGVyZSAqc3RhcnQgYmVsb25ncyAqLworICAgICAgICBsID0gbG87CisgICAgICAgIHIgPSBzdGFydDsKKyAgICAgICAgcGl2b3QgPSAqcjsKKyAgICAgICAgLyogSW52YXJpYW50czoKKyAgICAgICAgICogcGl2b3QgPj0gYWxsIGluIFtsbywgbCkuCisgICAgICAgICAqIHBpdm90ICA8IGFsbCBpbiBbciwgc3RhcnQpLgorICAgICAgICAgKiBUaGUgc2Vjb25kIGlzIHZhY3VvdXNseSB0cnVlIGF0IHRoZSBzdGFydC4KKyAgICAgICAgICovCisgICAgICAgIGFzc2VydChsIDwgcik7CisgICAgICAgIGRvIHsKKyAgICAgICAgICAgIHAgPSBsICsgKChyIC0gbCkgPj4gMSk7CisgICAgICAgICAgICBJRkxUKHBpdm90LCAqcCkKKyAgICAgICAgICAgICAgICByID0gcDsKKyAgICAgICAgICAgIGVsc2UKKyAgICAgICAgICAgICAgICBsID0gcCsxOworICAgICAgICB9IHdoaWxlIChsIDwgcik7CisgICAgICAgIGFzc2VydChsID09IHIpOworICAgICAgICAvKiBUaGUgaW52YXJpYW50cyBzdGlsbCBob2xkLCBzbyBwaXZvdCA+PSBhbGwgaW4gW2xvLCBsKSBhbmQKKyAgICAgICAgICAgcGl2b3QgPCBhbGwgaW4gW2wsIHN0YXJ0KSwgc28gcGl2b3QgYmVsb25ncyBhdCBsLiAgTm90ZQorICAgICAgICAgICB0aGF0IGlmIHRoZXJlIGFyZSBlbGVtZW50cyBlcXVhbCB0byBwaXZvdCwgbCBwb2ludHMgdG8gdGhlCisgICAgICAgICAgIGZpcnN0IHNsb3QgYWZ0ZXIgdGhlbSAtLSB0aGF0J3Mgd2h5IHRoaXMgc29ydCBpcyBzdGFibGUuCisgICAgICAgICAgIFNsaWRlIG92ZXIgdG8gbWFrZSByb29tLgorICAgICAgICAgICBDYXV0aW9uOiB1c2luZyBtZW1tb3ZlIGlzIG11Y2ggc2xvd2VyIHVuZGVyIE1TVkMgNTsKKyAgICAgICAgICAgd2UncmUgbm90IHVzdWFsbHkgbW92aW5nIG1hbnkgc2xvdHMuICovCisgICAgICAgIGZvciAocCA9IHN0YXJ0OyBwID4gbDsgLS1wKQorICAgICAgICAgICAgKnAgPSAqKHAtMSk7CisgICAgICAgICpsID0gcGl2b3Q7CisgICAgfQorICAgIHJldHVybiAwOworCisgZmFpbDoKKyAgICByZXR1cm4gLTE7Cit9CisKKy8qCitSZXR1cm4gdGhlIGxlbmd0aCBvZiB0aGUgcnVuIGJlZ2lubmluZyBhdCBsbywgaW4gdGhlIHNsaWNlIFtsbywgaGkpLiAgbG8gPCBoaQoraXMgcmVxdWlyZWQgb24gZW50cnkuICAiQSBydW4iIGlzIHRoZSBsb25nZXN0IGFzY2VuZGluZyBzZXF1ZW5jZSwgd2l0aAorCisgICAgbG9bMF0gPD0gbG9bMV0gPD0gbG9bMl0gPD0gLi4uCisKK29yIHRoZSBsb25nZXN0IGRlc2NlbmRpbmcgc2VxdWVuY2UsIHdpdGgKKworICAgIGxvWzBdID4gbG9bMV0gPiBsb1syXSA+IC4uLgorCitCb29sZWFuICpkZXNjZW5kaW5nIGlzIHNldCB0byAwIGluIHRoZSBmb3JtZXIgY2FzZSwgb3IgdG8gMSBpbiB0aGUgbGF0dGVyLgorRm9yIGl0cyBpbnRlbmRlZCB1c2UgaW4gYSBzdGFibGUgbWVyZ2Vzb3J0LCB0aGUgc3RyaWN0bmVzcyBvZiB0aGUgZGVmbiBvZgorImRlc2NlbmRpbmciIGlzIG5lZWRlZCBzbyB0aGF0IHRoZSBjYWxsZXIgY2FuIHNhZmVseSByZXZlcnNlIGEgZGVzY2VuZGluZworc2VxdWVuY2Ugd2l0aG91dCB2aW9sYXRpbmcgc3RhYmlsaXR5IChzdHJpY3QgPiBlbnN1cmVzIHRoZXJlIGFyZSBubyBlcXVhbAorZWxlbWVudHMgdG8gZ2V0IG91dCBvZiBvcmRlcikuCisKK1JldHVybnMgLTEgaW4gY2FzZSBvZiBlcnJvci4KKyovCitzdGF0aWMgUHlfc3NpemVfdAorY291bnRfcnVuKFB5T2JqZWN0ICoqbG8sIFB5T2JqZWN0ICoqaGksIFB5T2JqZWN0ICpjb21wYXJlLCBpbnQgKmRlc2NlbmRpbmcpCit7CisgICAgUHlfc3NpemVfdCBrOworICAgIFB5X3NzaXplX3QgbjsKKworICAgIGFzc2VydChsbyA8IGhpKTsKKyAgICAqZGVzY2VuZGluZyA9IDA7CisgICAgKytsbzsKKyAgICBpZiAobG8gPT0gaGkpCisgICAgICAgIHJldHVybiAxOworCisgICAgbiA9IDI7CisgICAgSUZMVCgqbG8sICoobG8tMSkpIHsKKyAgICAgICAgKmRlc2NlbmRpbmcgPSAxOworICAgICAgICBmb3IgKGxvID0gbG8rMTsgbG8gPCBoaTsgKytsbywgKytuKSB7CisgICAgICAgICAgICBJRkxUKCpsbywgKihsby0xKSkKKyAgICAgICAgICAgICAgICA7CisgICAgICAgICAgICBlbHNlCisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKyAgICB9CisgICAgZWxzZSB7CisgICAgICAgIGZvciAobG8gPSBsbysxOyBsbyA8IGhpOyArK2xvLCArK24pIHsKKyAgICAgICAgICAgIElGTFQoKmxvLCAqKGxvLTEpKQorICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisgICAgfQorCisgICAgcmV0dXJuIG47CitmYWlsOgorICAgIHJldHVybiAtMTsKK30KKworLyoKK0xvY2F0ZSB0aGUgcHJvcGVyIHBvc2l0aW9uIG9mIGtleSBpbiBhIHNvcnRlZCB2ZWN0b3I7IGlmIHRoZSB2ZWN0b3IgY29udGFpbnMKK2FuIGVsZW1lbnQgZXF1YWwgdG8ga2V5LCByZXR1cm4gdGhlIHBvc2l0aW9uIGltbWVkaWF0ZWx5IHRvIHRoZSBsZWZ0IG9mCit0aGUgbGVmdG1vc3QgZXF1YWwgZWxlbWVudC4gIFtnYWxsb3BfcmlnaHQoKSBkb2VzIHRoZSBzYW1lIGV4Y2VwdCByZXR1cm5zCit0aGUgcG9zaXRpb24gdG8gdGhlIHJpZ2h0IG9mIHRoZSByaWdodG1vc3QgZXF1YWwgZWxlbWVudCAoaWYgYW55KS5dCisKKyJhIiBpcyBhIHNvcnRlZCB2ZWN0b3Igd2l0aCBuIGVsZW1lbnRzLCBzdGFydGluZyBhdCBhWzBdLiAgbiBtdXN0IGJlID4gMC4KKworImhpbnQiIGlzIGFuIGluZGV4IGF0IHdoaWNoIHRvIGJlZ2luIHRoZSBzZWFyY2gsIDAgPD0gaGludCA8IG4uICBUaGUgY2xvc2VyCitoaW50IGlzIHRvIHRoZSBmaW5hbCByZXN1bHQsIHRoZSBmYXN0ZXIgdGhpcyBydW5zLgorCitUaGUgcmV0dXJuIHZhbHVlIGlzIHRoZSBpbnQgayBpbiAwLi5uIHN1Y2ggdGhhdAorCisgICAgYVtrLTFdIDwga2V5IDw9IGFba10KKworcHJldGVuZGluZyB0aGF0ICooYS0xKSBpcyBtaW51cyBpbmZpbml0eSBhbmQgYVtuXSBpcyBwbHVzIGluZmluaXR5LiAgSU9XLAora2V5IGJlbG9uZ3MgYXQgaW5kZXggazsgb3IsIElPVywgdGhlIGZpcnN0IGsgZWxlbWVudHMgb2YgYSBzaG91bGQgcHJlY2VkZQora2V5LCBhbmQgdGhlIGxhc3Qgbi1rIHNob3VsZCBmb2xsb3cga2V5LgorCitSZXR1cm5zIC0xIG9uIGVycm9yLiAgU2VlIGxpc3Rzb3J0LnR4dCBmb3IgaW5mbyBvbiB0aGUgbWV0aG9kLgorKi8KK3N0YXRpYyBQeV9zc2l6ZV90CitnYWxsb3BfbGVmdChQeU9iamVjdCAqa2V5LCBQeU9iamVjdCAqKmEsIFB5X3NzaXplX3QgbiwgUHlfc3NpemVfdCBoaW50LCBQeU9iamVjdCAqY29tcGFyZSkKK3sKKyAgICBQeV9zc2l6ZV90IG9mczsKKyAgICBQeV9zc2l6ZV90IGxhc3RvZnM7CisgICAgUHlfc3NpemVfdCBrOworCisgICAgYXNzZXJ0KGtleSAmJiBhICYmIG4gPiAwICYmIGhpbnQgPj0gMCAmJiBoaW50IDwgbik7CisKKyAgICBhICs9IGhpbnQ7CisgICAgbGFzdG9mcyA9IDA7CisgICAgb2ZzID0gMTsKKyAgICBJRkxUKCphLCBrZXkpIHsKKyAgICAgICAgLyogYVtoaW50XSA8IGtleSAtLSBnYWxsb3AgcmlnaHQsIHVudGlsCisgICAgICAgICAqIGFbaGludCArIGxhc3RvZnNdIDwga2V5IDw9IGFbaGludCArIG9mc10KKyAgICAgICAgICovCisgICAgICAgIGNvbnN0IFB5X3NzaXplX3QgbWF4b2ZzID0gbiAtIGhpbnQ7ICAgICAgICAgICAgIC8qICZhW24tMV0gaXMgaGlnaGVzdCAqLworICAgICAgICB3aGlsZSAob2ZzIDwgbWF4b2ZzKSB7CisgICAgICAgICAgICBJRkxUKGFbb2ZzXSwga2V5KSB7CisgICAgICAgICAgICAgICAgbGFzdG9mcyA9IG9mczsKKyAgICAgICAgICAgICAgICBvZnMgPSAob2ZzIDw8IDEpICsgMTsKKyAgICAgICAgICAgICAgICBpZiAob2ZzIDw9IDApICAgICAgICAgICAgICAgICAgIC8qIGludCBvdmVyZmxvdyAqLworICAgICAgICAgICAgICAgICAgICBvZnMgPSBtYXhvZnM7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBlbHNlICAgICAgICAgICAgICAgIC8qIGtleSA8PSBhW2hpbnQgKyBvZnNdICovCisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKyAgICAgICAgaWYgKG9mcyA+IG1heG9mcykKKyAgICAgICAgICAgIG9mcyA9IG1heG9mczsKKyAgICAgICAgLyogVHJhbnNsYXRlIGJhY2sgdG8gb2Zmc2V0cyByZWxhdGl2ZSB0byAmYVswXS4gKi8KKyAgICAgICAgbGFzdG9mcyArPSBoaW50OworICAgICAgICBvZnMgKz0gaGludDsKKyAgICB9CisgICAgZWxzZSB7CisgICAgICAgIC8qIGtleSA8PSBhW2hpbnRdIC0tIGdhbGxvcCBsZWZ0LCB1bnRpbAorICAgICAgICAgKiBhW2hpbnQgLSBvZnNdIDwga2V5IDw9IGFbaGludCAtIGxhc3RvZnNdCisgICAgICAgICAqLworICAgICAgICBjb25zdCBQeV9zc2l6ZV90IG1heG9mcyA9IGhpbnQgKyAxOyAgICAgICAgICAgICAvKiAmYVswXSBpcyBsb3dlc3QgKi8KKyAgICAgICAgd2hpbGUgKG9mcyA8IG1heG9mcykgeworICAgICAgICAgICAgSUZMVCgqKGEtb2ZzKSwga2V5KQorICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgLyoga2V5IDw9IGFbaGludCAtIG9mc10gKi8KKyAgICAgICAgICAgIGxhc3RvZnMgPSBvZnM7CisgICAgICAgICAgICBvZnMgPSAob2ZzIDw8IDEpICsgMTsKKyAgICAgICAgICAgIGlmIChvZnMgPD0gMCkgICAgICAgICAgICAgICAvKiBpbnQgb3ZlcmZsb3cgKi8KKyAgICAgICAgICAgICAgICBvZnMgPSBtYXhvZnM7CisgICAgICAgIH0KKyAgICAgICAgaWYgKG9mcyA+IG1heG9mcykKKyAgICAgICAgICAgIG9mcyA9IG1heG9mczsKKyAgICAgICAgLyogVHJhbnNsYXRlIGJhY2sgdG8gcG9zaXRpdmUgb2Zmc2V0cyByZWxhdGl2ZSB0byAmYVswXS4gKi8KKyAgICAgICAgayA9IGxhc3RvZnM7CisgICAgICAgIGxhc3RvZnMgPSBoaW50IC0gb2ZzOworICAgICAgICBvZnMgPSBoaW50IC0gazsKKyAgICB9CisgICAgYSAtPSBoaW50OworCisgICAgYXNzZXJ0KC0xIDw9IGxhc3RvZnMgJiYgbGFzdG9mcyA8IG9mcyAmJiBvZnMgPD0gbik7CisgICAgLyogTm93IGFbbGFzdG9mc10gPCBrZXkgPD0gYVtvZnNdLCBzbyBrZXkgYmVsb25ncyBzb21ld2hlcmUgdG8gdGhlCisgICAgICogcmlnaHQgb2YgbGFzdG9mcyBidXQgbm8gZmFydGhlciByaWdodCB0aGFuIG9mcy4gIERvIGEgYmluYXJ5CisgICAgICogc2VhcmNoLCB3aXRoIGludmFyaWFudCBhW2xhc3RvZnMtMV0gPCBrZXkgPD0gYVtvZnNdLgorICAgICAqLworICAgICsrbGFzdG9mczsKKyAgICB3aGlsZSAobGFzdG9mcyA8IG9mcykgeworICAgICAgICBQeV9zc2l6ZV90IG0gPSBsYXN0b2ZzICsgKChvZnMgLSBsYXN0b2ZzKSA+PiAxKTsKKworICAgICAgICBJRkxUKGFbbV0sIGtleSkKKyAgICAgICAgICAgIGxhc3RvZnMgPSBtKzE7ICAgICAgICAgICAgICAvKiBhW21dIDwga2V5ICovCisgICAgICAgIGVsc2UKKyAgICAgICAgICAgIG9mcyA9IG07ICAgICAgICAgICAgICAgICAgICAvKiBrZXkgPD0gYVttXSAqLworICAgIH0KKyAgICBhc3NlcnQobGFzdG9mcyA9PSBvZnMpOyAgICAgICAgICAgICAvKiBzbyBhW29mcy0xXSA8IGtleSA8PSBhW29mc10gKi8KKyAgICByZXR1cm4gb2ZzOworCitmYWlsOgorICAgIHJldHVybiAtMTsKK30KKworLyoKK0V4YWN0bHkgbGlrZSBnYWxsb3BfbGVmdCgpLCBleGNlcHQgdGhhdCBpZiBrZXkgYWxyZWFkeSBleGlzdHMgaW4gYVswOm5dLAorZmluZHMgdGhlIHBvc2l0aW9uIGltbWVkaWF0ZWx5IHRvIHRoZSByaWdodCBvZiB0aGUgcmlnaHRtb3N0IGVxdWFsIHZhbHVlLgorCitUaGUgcmV0dXJuIHZhbHVlIGlzIHRoZSBpbnQgayBpbiAwLi5uIHN1Y2ggdGhhdAorCisgICAgYVtrLTFdIDw9IGtleSA8IGFba10KKworb3IgLTEgaWYgZXJyb3IuCisKK1RoZSBjb2RlIGR1cGxpY2F0aW9uIGlzIG1hc3NpdmUsIGJ1dCB0aGlzIGlzIGVub3VnaCBkaWZmZXJlbnQgZ2l2ZW4gdGhhdAord2UncmUgc3RpY2tpbmcgdG8gIjwiIGNvbXBhcmlzb25zIHRoYXQgaXQncyBtdWNoIGhhcmRlciB0byBmb2xsb3cgaWYKK3dyaXR0ZW4gYXMgb25lIHJvdXRpbmUgd2l0aCB5ZXQgYW5vdGhlciAibGVmdCBvciByaWdodD8iIGZsYWcuCisqLworc3RhdGljIFB5X3NzaXplX3QKK2dhbGxvcF9yaWdodChQeU9iamVjdCAqa2V5LCBQeU9iamVjdCAqKmEsIFB5X3NzaXplX3QgbiwgUHlfc3NpemVfdCBoaW50LCBQeU9iamVjdCAqY29tcGFyZSkKK3sKKyAgICBQeV9zc2l6ZV90IG9mczsKKyAgICBQeV9zc2l6ZV90IGxhc3RvZnM7CisgICAgUHlfc3NpemVfdCBrOworCisgICAgYXNzZXJ0KGtleSAmJiBhICYmIG4gPiAwICYmIGhpbnQgPj0gMCAmJiBoaW50IDwgbik7CisKKyAgICBhICs9IGhpbnQ7CisgICAgbGFzdG9mcyA9IDA7CisgICAgb2ZzID0gMTsKKyAgICBJRkxUKGtleSwgKmEpIHsKKyAgICAgICAgLyoga2V5IDwgYVtoaW50XSAtLSBnYWxsb3AgbGVmdCwgdW50aWwKKyAgICAgICAgICogYVtoaW50IC0gb2ZzXSA8PSBrZXkgPCBhW2hpbnQgLSBsYXN0b2ZzXQorICAgICAgICAgKi8KKyAgICAgICAgY29uc3QgUHlfc3NpemVfdCBtYXhvZnMgPSBoaW50ICsgMTsgICAgICAgICAgICAgLyogJmFbMF0gaXMgbG93ZXN0ICovCisgICAgICAgIHdoaWxlIChvZnMgPCBtYXhvZnMpIHsKKyAgICAgICAgICAgIElGTFQoa2V5LCAqKGEtb2ZzKSkgeworICAgICAgICAgICAgICAgIGxhc3RvZnMgPSBvZnM7CisgICAgICAgICAgICAgICAgb2ZzID0gKG9mcyA8PCAxKSArIDE7CisgICAgICAgICAgICAgICAgaWYgKG9mcyA8PSAwKSAgICAgICAgICAgICAgICAgICAvKiBpbnQgb3ZlcmZsb3cgKi8KKyAgICAgICAgICAgICAgICAgICAgb2ZzID0gbWF4b2ZzOworICAgICAgICAgICAgfQorICAgICAgICAgICAgZWxzZSAgICAgICAgICAgICAgICAvKiBhW2hpbnQgLSBvZnNdIDw9IGtleSAqLworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisgICAgICAgIGlmIChvZnMgPiBtYXhvZnMpCisgICAgICAgICAgICBvZnMgPSBtYXhvZnM7CisgICAgICAgIC8qIFRyYW5zbGF0ZSBiYWNrIHRvIHBvc2l0aXZlIG9mZnNldHMgcmVsYXRpdmUgdG8gJmFbMF0uICovCisgICAgICAgIGsgPSBsYXN0b2ZzOworICAgICAgICBsYXN0b2ZzID0gaGludCAtIG9mczsKKyAgICAgICAgb2ZzID0gaGludCAtIGs7CisgICAgfQorICAgIGVsc2UgeworICAgICAgICAvKiBhW2hpbnRdIDw9IGtleSAtLSBnYWxsb3AgcmlnaHQsIHVudGlsCisgICAgICAgICAqIGFbaGludCArIGxhc3RvZnNdIDw9IGtleSA8IGFbaGludCArIG9mc10KKyAgICAgICAgKi8KKyAgICAgICAgY29uc3QgUHlfc3NpemVfdCBtYXhvZnMgPSBuIC0gaGludDsgICAgICAgICAgICAgLyogJmFbbi0xXSBpcyBoaWdoZXN0ICovCisgICAgICAgIHdoaWxlIChvZnMgPCBtYXhvZnMpIHsKKyAgICAgICAgICAgIElGTFQoa2V5LCBhW29mc10pCisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAvKiBhW2hpbnQgKyBvZnNdIDw9IGtleSAqLworICAgICAgICAgICAgbGFzdG9mcyA9IG9mczsKKyAgICAgICAgICAgIG9mcyA9IChvZnMgPDwgMSkgKyAxOworICAgICAgICAgICAgaWYgKG9mcyA8PSAwKSAgICAgICAgICAgICAgIC8qIGludCBvdmVyZmxvdyAqLworICAgICAgICAgICAgICAgIG9mcyA9IG1heG9mczsKKyAgICAgICAgfQorICAgICAgICBpZiAob2ZzID4gbWF4b2ZzKQorICAgICAgICAgICAgb2ZzID0gbWF4b2ZzOworICAgICAgICAvKiBUcmFuc2xhdGUgYmFjayB0byBvZmZzZXRzIHJlbGF0aXZlIHRvICZhWzBdLiAqLworICAgICAgICBsYXN0b2ZzICs9IGhpbnQ7CisgICAgICAgIG9mcyArPSBoaW50OworICAgIH0KKyAgICBhIC09IGhpbnQ7CisKKyAgICBhc3NlcnQoLTEgPD0gbGFzdG9mcyAmJiBsYXN0b2ZzIDwgb2ZzICYmIG9mcyA8PSBuKTsKKyAgICAvKiBOb3cgYVtsYXN0b2ZzXSA8PSBrZXkgPCBhW29mc10sIHNvIGtleSBiZWxvbmdzIHNvbWV3aGVyZSB0byB0aGUKKyAgICAgKiByaWdodCBvZiBsYXN0b2ZzIGJ1dCBubyBmYXJ0aGVyIHJpZ2h0IHRoYW4gb2ZzLiAgRG8gYSBiaW5hcnkKKyAgICAgKiBzZWFyY2gsIHdpdGggaW52YXJpYW50IGFbbGFzdG9mcy0xXSA8PSBrZXkgPCBhW29mc10uCisgICAgICovCisgICAgKytsYXN0b2ZzOworICAgIHdoaWxlIChsYXN0b2ZzIDwgb2ZzKSB7CisgICAgICAgIFB5X3NzaXplX3QgbSA9IGxhc3RvZnMgKyAoKG9mcyAtIGxhc3RvZnMpID4+IDEpOworCisgICAgICAgIElGTFQoa2V5LCBhW21dKQorICAgICAgICAgICAgb2ZzID0gbTsgICAgICAgICAgICAgICAgICAgIC8qIGtleSA8IGFbbV0gKi8KKyAgICAgICAgZWxzZQorICAgICAgICAgICAgbGFzdG9mcyA9IG0rMTsgICAgICAgICAgICAgIC8qIGFbbV0gPD0ga2V5ICovCisgICAgfQorICAgIGFzc2VydChsYXN0b2ZzID09IG9mcyk7ICAgICAgICAgICAgIC8qIHNvIGFbb2ZzLTFdIDw9IGtleSA8IGFbb2ZzXSAqLworICAgIHJldHVybiBvZnM7CisKK2ZhaWw6CisgICAgcmV0dXJuIC0xOworfQorCisvKiBUaGUgbWF4aW11bSBudW1iZXIgb2YgZW50cmllcyBpbiBhIE1lcmdlU3RhdGUncyBwZW5kaW5nLXJ1bnMgc3RhY2suCisgKiBUaGlzIGlzIGVub3VnaCB0byBzb3J0IGFycmF5cyBvZiBzaXplIHVwIHRvIGFib3V0CisgKiAgICAgMzIgKiBwaGkgKiogTUFYX01FUkdFX1BFTkRJTkcKKyAqIHdoZXJlIHBoaSB+PSAxLjYxOC4gIDg1IGlzIHJpZGljdWxvdXNseWxhcmdlIGVub3VnaCwgZ29vZCBmb3IgYW4gYXJyYXkKKyAqIHdpdGggMioqNjQgZWxlbWVudHMuCisgKi8KKyNkZWZpbmUgTUFYX01FUkdFX1BFTkRJTkcgODUKKworLyogV2hlbiB3ZSBnZXQgaW50byBnYWxsb3BpbmcgbW9kZSwgd2Ugc3RheSB0aGVyZSB1bnRpbCBib3RoIHJ1bnMgd2luIGxlc3MKKyAqIG9mdGVuIHRoYW4gTUlOX0dBTExPUCBjb25zZWN1dGl2ZSB0aW1lcy4gIFNlZSBsaXN0c29ydC50eHQgZm9yIG1vcmUgaW5mby4KKyAqLworI2RlZmluZSBNSU5fR0FMTE9QIDcKKworLyogQXZvaWQgbWFsbG9jIGZvciBzbWFsbCB0ZW1wIGFycmF5cy4gKi8KKyNkZWZpbmUgTUVSR0VTVEFURV9URU1QX1NJWkUgMjU2CisKKy8qIE9uZSBNZXJnZVN0YXRlIGV4aXN0cyBvbiB0aGUgc3RhY2sgcGVyIGludm9jYXRpb24gb2YgbWVyZ2Vzb3J0LiAgSXQncyBqdXN0CisgKiBhIGNvbnZlbmllbnQgd2F5IHRvIHBhc3Mgc3RhdGUgYXJvdW5kIGFtb25nIHRoZSBoZWxwZXIgZnVuY3Rpb25zLgorICovCitzdHJ1Y3Qgc19zbGljZSB7CisgICAgUHlPYmplY3QgKipiYXNlOworICAgIFB5X3NzaXplX3QgbGVuOworfTsKKwordHlwZWRlZiBzdHJ1Y3Qgc19NZXJnZVN0YXRlIHsKKyAgICAvKiBUaGUgdXNlci1zdXBwbGllZCBjb21wYXJpc29uIGZ1bmN0aW9uLiBvciBOVUxMIGlmIG5vbmUgZ2l2ZW4uICovCisgICAgUHlPYmplY3QgKmNvbXBhcmU7CisKKyAgICAvKiBUaGlzIGNvbnRyb2xzIHdoZW4gd2UgZ2V0ICppbnRvKiBnYWxsb3BpbmcgbW9kZS4gIEl0J3MgaW5pdGlhbGl6ZWQKKyAgICAgKiB0byBNSU5fR0FMTE9QLiAgbWVyZ2VfbG8gYW5kIG1lcmdlX2hpIHRlbmQgdG8gbnVkZ2UgaXQgaGlnaGVyIGZvcgorICAgICAqIHJhbmRvbSBkYXRhLCBhbmQgbG93ZXIgZm9yIGhpZ2hseSBzdHJ1Y3R1cmVkIGRhdGEuCisgICAgICovCisgICAgUHlfc3NpemVfdCBtaW5fZ2FsbG9wOworCisgICAgLyogJ2EnIGlzIHRlbXAgc3RvcmFnZSB0byBoZWxwIHdpdGggbWVyZ2VzLiAgSXQgY29udGFpbnMgcm9vbSBmb3IKKyAgICAgKiBhbGxvY2VkIGVudHJpZXMuCisgICAgICovCisgICAgUHlPYmplY3QgKiphOyAgICAgICAvKiBtYXkgcG9pbnQgdG8gdGVtcGFycmF5IGJlbG93ICovCisgICAgUHlfc3NpemVfdCBhbGxvY2VkOworCisgICAgLyogQSBzdGFjayBvZiBuIHBlbmRpbmcgcnVucyB5ZXQgdG8gYmUgbWVyZ2VkLiAgUnVuICNpIHN0YXJ0cyBhdAorICAgICAqIGFkZHJlc3MgYmFzZVtpXSBhbmQgZXh0ZW5kcyBmb3IgbGVuW2ldIGVsZW1lbnRzLiAgSXQncyBhbHdheXMKKyAgICAgKiB0cnVlIChzbyBsb25nIGFzIHRoZSBpbmRpY2VzIGFyZSBpbiBib3VuZHMpIHRoYXQKKyAgICAgKgorICAgICAqICAgICBwZW5kaW5nW2ldLmJhc2UgKyBwZW5kaW5nW2ldLmxlbiA9PSBwZW5kaW5nW2krMV0uYmFzZQorICAgICAqCisgICAgICogc28gd2UgY291bGQgY3V0IHRoZSBzdG9yYWdlIGZvciB0aGlzLCBidXQgaXQncyBhIG1pbm9yIGFtb3VudCwKKyAgICAgKiBhbmQga2VlcGluZyBhbGwgdGhlIGluZm8gZXhwbGljaXQgc2ltcGxpZmllcyB0aGUgY29kZS4KKyAgICAgKi8KKyAgICBpbnQgbjsKKyAgICBzdHJ1Y3Qgc19zbGljZSBwZW5kaW5nW01BWF9NRVJHRV9QRU5ESU5HXTsKKworICAgIC8qICdhJyBwb2ludHMgdG8gdGhpcyB3aGVuIHBvc3NpYmxlLCByYXRoZXIgdGhhbiBtdWNrIHdpdGggbWFsbG9jLiAqLworICAgIFB5T2JqZWN0ICp0ZW1wYXJyYXlbTUVSR0VTVEFURV9URU1QX1NJWkVdOworfSBNZXJnZVN0YXRlOworCisvKiBDb25jZXB0dWFsbHkgYSBNZXJnZVN0YXRlJ3MgY29uc3RydWN0b3IuICovCitzdGF0aWMgdm9pZAorbWVyZ2VfaW5pdChNZXJnZVN0YXRlICptcywgUHlPYmplY3QgKmNvbXBhcmUpCit7CisgICAgYXNzZXJ0KG1zICE9IE5VTEwpOworICAgIG1zLT5jb21wYXJlID0gY29tcGFyZTsKKyAgICBtcy0+YSA9IG1zLT50ZW1wYXJyYXk7CisgICAgbXMtPmFsbG9jZWQgPSBNRVJHRVNUQVRFX1RFTVBfU0laRTsKKyAgICBtcy0+biA9IDA7CisgICAgbXMtPm1pbl9nYWxsb3AgPSBNSU5fR0FMTE9QOworfQorCisvKiBGcmVlIGFsbCB0aGUgdGVtcCBtZW1vcnkgb3duZWQgYnkgdGhlIE1lcmdlU3RhdGUuICBUaGlzIG11c3QgYmUgY2FsbGVkCisgKiB3aGVuIHlvdSdyZSBkb25lIHdpdGggYSBNZXJnZVN0YXRlLCBhbmQgbWF5IGJlIGNhbGxlZCBiZWZvcmUgdGhlbiBpZgorICogeW91IHdhbnQgdG8gZnJlZSB0aGUgdGVtcCBtZW1vcnkgZWFybHkuCisgKi8KK3N0YXRpYyB2b2lkCittZXJnZV9mcmVlbWVtKE1lcmdlU3RhdGUgKm1zKQoreworICAgIGFzc2VydChtcyAhPSBOVUxMKTsKKyAgICBpZiAobXMtPmEgIT0gbXMtPnRlbXBhcnJheSkKKyAgICAgICAgUHlNZW1fRnJlZShtcy0+YSk7CisgICAgbXMtPmEgPSBtcy0+dGVtcGFycmF5OworICAgIG1zLT5hbGxvY2VkID0gTUVSR0VTVEFURV9URU1QX1NJWkU7Cit9CisKKy8qIEVuc3VyZSBlbm91Z2ggdGVtcCBtZW1vcnkgZm9yICduZWVkJyBhcnJheSBzbG90cyBpcyBhdmFpbGFibGUuCisgKiBSZXR1cm5zIDAgb24gc3VjY2VzcyBhbmQgLTEgaWYgdGhlIG1lbW9yeSBjYW4ndCBiZSBnb3R0ZW4uCisgKi8KK3N0YXRpYyBpbnQKK21lcmdlX2dldG1lbShNZXJnZVN0YXRlICptcywgUHlfc3NpemVfdCBuZWVkKQoreworICAgIGFzc2VydChtcyAhPSBOVUxMKTsKKyAgICBpZiAobmVlZCA8PSBtcy0+YWxsb2NlZCkKKyAgICAgICAgcmV0dXJuIDA7CisgICAgLyogRG9uJ3QgcmVhbGxvYyEgIFRoYXQgY2FuIGNvc3QgY3ljbGVzIHRvIGNvcHkgdGhlIG9sZCBkYXRhLCBidXQKKyAgICAgKiB3ZSBkb24ndCBjYXJlIHdoYXQncyBpbiB0aGUgYmxvY2suCisgICAgICovCisgICAgbWVyZ2VfZnJlZW1lbShtcyk7CisgICAgaWYgKChzaXplX3QpbmVlZCA+IFBZX1NTSVpFX1RfTUFYIC8gc2l6ZW9mKFB5T2JqZWN0KikpIHsKKyAgICAgICAgUHlFcnJfTm9NZW1vcnkoKTsKKyAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKyAgICBtcy0+YSA9IChQeU9iamVjdCAqKilQeU1lbV9NYWxsb2MobmVlZCAqIHNpemVvZihQeU9iamVjdCopKTsKKyAgICBpZiAobXMtPmEpIHsKKyAgICAgICAgbXMtPmFsbG9jZWQgPSBuZWVkOworICAgICAgICByZXR1cm4gMDsKKyAgICB9CisgICAgUHlFcnJfTm9NZW1vcnkoKTsKKyAgICBtZXJnZV9mcmVlbWVtKG1zKTsgICAgICAgICAgLyogcmVzZXQgdG8gc2FuZSBzdGF0ZSAqLworICAgIHJldHVybiAtMTsKK30KKyNkZWZpbmUgTUVSR0VfR0VUTUVNKE1TLCBORUVEKSAoKE5FRUQpIDw9IChNUyktPmFsbG9jZWQgPyAwIDogICBcCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1lcmdlX2dldG1lbShNUywgTkVFRCkpCisKKy8qIE1lcmdlIHRoZSBuYSBlbGVtZW50cyBzdGFydGluZyBhdCBwYSB3aXRoIHRoZSBuYiBlbGVtZW50cyBzdGFydGluZyBhdCBwYgorICogaW4gYSBzdGFibGUgd2F5LCBpbi1wbGFjZS4gIG5hIGFuZCBuYiBtdXN0IGJlID4gMCwgYW5kIHBhICsgbmEgPT0gcGIuCisgKiBNdXN0IGFsc28gaGF2ZSB0aGF0ICpwYiA8ICpwYSwgdGhhdCBwYVtuYS0xXSBiZWxvbmdzIGF0IHRoZSBlbmQgb2YgdGhlCisgKiBtZXJnZSwgYW5kIHNob3VsZCBoYXZlIG5hIDw9IG5iLiAgU2VlIGxpc3Rzb3J0LnR4dCBmb3IgbW9yZSBpbmZvLgorICogUmV0dXJuIDAgaWYgc3VjY2Vzc2Z1bCwgLTEgaWYgZXJyb3IuCisgKi8KK3N0YXRpYyBQeV9zc2l6ZV90CittZXJnZV9sbyhNZXJnZVN0YXRlICptcywgUHlPYmplY3QgKipwYSwgUHlfc3NpemVfdCBuYSwKKyAgICAgICAgICAgICAgICAgICAgICAgICBQeU9iamVjdCAqKnBiLCBQeV9zc2l6ZV90IG5iKQoreworICAgIFB5X3NzaXplX3QgazsKKyAgICBQeU9iamVjdCAqY29tcGFyZTsKKyAgICBQeU9iamVjdCAqKmRlc3Q7CisgICAgaW50IHJlc3VsdCA9IC0xOyAgICAgICAgICAgIC8qIGd1aWx0eSB1bnRpbCBwcm92ZWQgaW5ub2NlbnQgKi8KKyAgICBQeV9zc2l6ZV90IG1pbl9nYWxsb3A7CisKKyAgICBhc3NlcnQobXMgJiYgcGEgJiYgcGIgJiYgbmEgPiAwICYmIG5iID4gMCAmJiBwYSArIG5hID09IHBiKTsKKyAgICBpZiAoTUVSR0VfR0VUTUVNKG1zLCBuYSkgPCAwKQorICAgICAgICByZXR1cm4gLTE7CisgICAgbWVtY3B5KG1zLT5hLCBwYSwgbmEgKiBzaXplb2YoUHlPYmplY3QqKSk7CisgICAgZGVzdCA9IHBhOworICAgIHBhID0gbXMtPmE7CisKKyAgICAqZGVzdCsrID0gKnBiKys7CisgICAgLS1uYjsKKyAgICBpZiAobmIgPT0gMCkKKyAgICAgICAgZ290byBTdWNjZWVkOworICAgIGlmIChuYSA9PSAxKQorICAgICAgICBnb3RvIENvcHlCOworCisgICAgbWluX2dhbGxvcCA9IG1zLT5taW5fZ2FsbG9wOworICAgIGNvbXBhcmUgPSBtcy0+Y29tcGFyZTsKKyAgICBmb3IgKDs7KSB7CisgICAgICAgIFB5X3NzaXplX3QgYWNvdW50ID0gMDsgICAgICAgICAgLyogIyBvZiB0aW1lcyBBIHdvbiBpbiBhIHJvdyAqLworICAgICAgICBQeV9zc2l6ZV90IGJjb3VudCA9IDA7ICAgICAgICAgIC8qICMgb2YgdGltZXMgQiB3b24gaW4gYSByb3cgKi8KKworICAgICAgICAvKiBEbyB0aGUgc3RyYWlnaHRmb3J3YXJkIHRoaW5nIHVudGlsIChpZiBldmVyKSBvbmUgcnVuCisgICAgICAgICAqIGFwcGVhcnMgdG8gd2luIGNvbnNpc3RlbnRseS4KKyAgICAgICAgICovCisgICAgICAgIGZvciAoOzspIHsKKyAgICAgICAgICAgIGFzc2VydChuYSA+IDEgJiYgbmIgPiAwKTsKKyAgICAgICAgICAgIGsgPSBJU0xUKCpwYiwgKnBhLCBjb21wYXJlKTsKKyAgICAgICAgICAgIGlmIChrKSB7CisgICAgICAgICAgICAgICAgaWYgKGsgPCAwKQorICAgICAgICAgICAgICAgICAgICBnb3RvIEZhaWw7CisgICAgICAgICAgICAgICAgKmRlc3QrKyA9ICpwYisrOworICAgICAgICAgICAgICAgICsrYmNvdW50OworICAgICAgICAgICAgICAgIGFjb3VudCA9IDA7CisgICAgICAgICAgICAgICAgLS1uYjsKKyAgICAgICAgICAgICAgICBpZiAobmIgPT0gMCkKKyAgICAgICAgICAgICAgICAgICAgZ290byBTdWNjZWVkOworICAgICAgICAgICAgICAgIGlmIChiY291bnQgPj0gbWluX2dhbGxvcCkKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBlbHNlIHsKKyAgICAgICAgICAgICAgICAqZGVzdCsrID0gKnBhKys7CisgICAgICAgICAgICAgICAgKythY291bnQ7CisgICAgICAgICAgICAgICAgYmNvdW50ID0gMDsKKyAgICAgICAgICAgICAgICAtLW5hOworICAgICAgICAgICAgICAgIGlmIChuYSA9PSAxKQorICAgICAgICAgICAgICAgICAgICBnb3RvIENvcHlCOworICAgICAgICAgICAgICAgIGlmIChhY291bnQgPj0gbWluX2dhbGxvcCkKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICAvKiBPbmUgcnVuIGlzIHdpbm5pbmcgc28gY29uc2lzdGVudGx5IHRoYXQgZ2FsbG9waW5nIG1heQorICAgICAgICAgKiBiZSBhIGh1Z2Ugd2luLiAgU28gdHJ5IHRoYXQsIGFuZCBjb250aW51ZSBnYWxsb3BpbmcgdW50aWwKKyAgICAgICAgICogKGlmIGV2ZXIpIG5laXRoZXIgcnVuIGFwcGVhcnMgdG8gYmUgd2lubmluZyBjb25zaXN0ZW50bHkKKyAgICAgICAgICogYW55bW9yZS4KKyAgICAgICAgICovCisgICAgICAgICsrbWluX2dhbGxvcDsKKyAgICAgICAgZG8geworICAgICAgICAgICAgYXNzZXJ0KG5hID4gMSAmJiBuYiA+IDApOworICAgICAgICAgICAgbWluX2dhbGxvcCAtPSBtaW5fZ2FsbG9wID4gMTsKKyAgICAgICAgICAgIG1zLT5taW5fZ2FsbG9wID0gbWluX2dhbGxvcDsKKyAgICAgICAgICAgIGsgPSBnYWxsb3BfcmlnaHQoKnBiLCBwYSwgbmEsIDAsIGNvbXBhcmUpOworICAgICAgICAgICAgYWNvdW50ID0gazsKKyAgICAgICAgICAgIGlmIChrKSB7CisgICAgICAgICAgICAgICAgaWYgKGsgPCAwKQorICAgICAgICAgICAgICAgICAgICBnb3RvIEZhaWw7CisgICAgICAgICAgICAgICAgbWVtY3B5KGRlc3QsIHBhLCBrICogc2l6ZW9mKFB5T2JqZWN0ICopKTsKKyAgICAgICAgICAgICAgICBkZXN0ICs9IGs7CisgICAgICAgICAgICAgICAgcGEgKz0gazsKKyAgICAgICAgICAgICAgICBuYSAtPSBrOworICAgICAgICAgICAgICAgIGlmIChuYSA9PSAxKQorICAgICAgICAgICAgICAgICAgICBnb3RvIENvcHlCOworICAgICAgICAgICAgICAgIC8qIG5hPT0wIGlzIGltcG9zc2libGUgbm93IGlmIHRoZSBjb21wYXJpc29uCisgICAgICAgICAgICAgICAgICogZnVuY3Rpb24gaXMgY29uc2lzdGVudCwgYnV0IHdlIGNhbid0IGFzc3VtZQorICAgICAgICAgICAgICAgICAqIHRoYXQgaXQgaXMuCisgICAgICAgICAgICAgICAgICovCisgICAgICAgICAgICAgICAgaWYgKG5hID09IDApCisgICAgICAgICAgICAgICAgICAgIGdvdG8gU3VjY2VlZDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgICpkZXN0KysgPSAqcGIrKzsKKyAgICAgICAgICAgIC0tbmI7CisgICAgICAgICAgICBpZiAobmIgPT0gMCkKKyAgICAgICAgICAgICAgICBnb3RvIFN1Y2NlZWQ7CisKKyAgICAgICAgICAgIGsgPSBnYWxsb3BfbGVmdCgqcGEsIHBiLCBuYiwgMCwgY29tcGFyZSk7CisgICAgICAgICAgICBiY291bnQgPSBrOworICAgICAgICAgICAgaWYgKGspIHsKKyAgICAgICAgICAgICAgICBpZiAoayA8IDApCisgICAgICAgICAgICAgICAgICAgIGdvdG8gRmFpbDsKKyAgICAgICAgICAgICAgICBtZW1tb3ZlKGRlc3QsIHBiLCBrICogc2l6ZW9mKFB5T2JqZWN0ICopKTsKKyAgICAgICAgICAgICAgICBkZXN0ICs9IGs7CisgICAgICAgICAgICAgICAgcGIgKz0gazsKKyAgICAgICAgICAgICAgICBuYiAtPSBrOworICAgICAgICAgICAgICAgIGlmIChuYiA9PSAwKQorICAgICAgICAgICAgICAgICAgICBnb3RvIFN1Y2NlZWQ7CisgICAgICAgICAgICB9CisgICAgICAgICAgICAqZGVzdCsrID0gKnBhKys7CisgICAgICAgICAgICAtLW5hOworICAgICAgICAgICAgaWYgKG5hID09IDEpCisgICAgICAgICAgICAgICAgZ290byBDb3B5QjsKKyAgICAgICAgfSB3aGlsZSAoYWNvdW50ID49IE1JTl9HQUxMT1AgfHwgYmNvdW50ID49IE1JTl9HQUxMT1ApOworICAgICAgICArK21pbl9nYWxsb3A7ICAgICAgICAgICAvKiBwZW5hbGl6ZSBpdCBmb3IgbGVhdmluZyBnYWxsb3BpbmcgbW9kZSAqLworICAgICAgICBtcy0+bWluX2dhbGxvcCA9IG1pbl9nYWxsb3A7CisgICAgfQorU3VjY2VlZDoKKyAgICByZXN1bHQgPSAwOworRmFpbDoKKyAgICBpZiAobmEpCisgICAgICAgIG1lbWNweShkZXN0LCBwYSwgbmEgKiBzaXplb2YoUHlPYmplY3QqKSk7CisgICAgcmV0dXJuIHJlc3VsdDsKK0NvcHlCOgorICAgIGFzc2VydChuYSA9PSAxICYmIG5iID4gMCk7CisgICAgLyogVGhlIGxhc3QgZWxlbWVudCBvZiBwYSBiZWxvbmdzIGF0IHRoZSBlbmQgb2YgdGhlIG1lcmdlLiAqLworICAgIG1lbW1vdmUoZGVzdCwgcGIsIG5iICogc2l6ZW9mKFB5T2JqZWN0ICopKTsKKyAgICBkZXN0W25iXSA9ICpwYTsKKyAgICByZXR1cm4gMDsKK30KKworLyogTWVyZ2UgdGhlIG5hIGVsZW1lbnRzIHN0YXJ0aW5nIGF0IHBhIHdpdGggdGhlIG5iIGVsZW1lbnRzIHN0YXJ0aW5nIGF0IHBiCisgKiBpbiBhIHN0YWJsZSB3YXksIGluLXBsYWNlLiAgbmEgYW5kIG5iIG11c3QgYmUgPiAwLCBhbmQgcGEgKyBuYSA9PSBwYi4KKyAqIE11c3QgYWxzbyBoYXZlIHRoYXQgKnBiIDwgKnBhLCB0aGF0IHBhW25hLTFdIGJlbG9uZ3MgYXQgdGhlIGVuZCBvZiB0aGUKKyAqIG1lcmdlLCBhbmQgc2hvdWxkIGhhdmUgbmEgPj0gbmIuICBTZWUgbGlzdHNvcnQudHh0IGZvciBtb3JlIGluZm8uCisgKiBSZXR1cm4gMCBpZiBzdWNjZXNzZnVsLCAtMSBpZiBlcnJvci4KKyAqLworc3RhdGljIFB5X3NzaXplX3QKK21lcmdlX2hpKE1lcmdlU3RhdGUgKm1zLCBQeU9iamVjdCAqKnBhLCBQeV9zc2l6ZV90IG5hLCBQeU9iamVjdCAqKnBiLCBQeV9zc2l6ZV90IG5iKQoreworICAgIFB5X3NzaXplX3QgazsKKyAgICBQeU9iamVjdCAqY29tcGFyZTsKKyAgICBQeU9iamVjdCAqKmRlc3Q7CisgICAgaW50IHJlc3VsdCA9IC0xOyAgICAgICAgICAgIC8qIGd1aWx0eSB1bnRpbCBwcm92ZWQgaW5ub2NlbnQgKi8KKyAgICBQeU9iamVjdCAqKmJhc2VhOworICAgIFB5T2JqZWN0ICoqYmFzZWI7CisgICAgUHlfc3NpemVfdCBtaW5fZ2FsbG9wOworCisgICAgYXNzZXJ0KG1zICYmIHBhICYmIHBiICYmIG5hID4gMCAmJiBuYiA+IDAgJiYgcGEgKyBuYSA9PSBwYik7CisgICAgaWYgKE1FUkdFX0dFVE1FTShtcywgbmIpIDwgMCkKKyAgICAgICAgcmV0dXJuIC0xOworICAgIGRlc3QgPSBwYiArIG5iIC0gMTsKKyAgICBtZW1jcHkobXMtPmEsIHBiLCBuYiAqIHNpemVvZihQeU9iamVjdCopKTsKKyAgICBiYXNlYSA9IHBhOworICAgIGJhc2ViID0gbXMtPmE7CisgICAgcGIgPSBtcy0+YSArIG5iIC0gMTsKKyAgICBwYSArPSBuYSAtIDE7CisKKyAgICAqZGVzdC0tID0gKnBhLS07CisgICAgLS1uYTsKKyAgICBpZiAobmEgPT0gMCkKKyAgICAgICAgZ290byBTdWNjZWVkOworICAgIGlmIChuYiA9PSAxKQorICAgICAgICBnb3RvIENvcHlBOworCisgICAgbWluX2dhbGxvcCA9IG1zLT5taW5fZ2FsbG9wOworICAgIGNvbXBhcmUgPSBtcy0+Y29tcGFyZTsKKyAgICBmb3IgKDs7KSB7CisgICAgICAgIFB5X3NzaXplX3QgYWNvdW50ID0gMDsgICAgICAgICAgLyogIyBvZiB0aW1lcyBBIHdvbiBpbiBhIHJvdyAqLworICAgICAgICBQeV9zc2l6ZV90IGJjb3VudCA9IDA7ICAgICAgICAgIC8qICMgb2YgdGltZXMgQiB3b24gaW4gYSByb3cgKi8KKworICAgICAgICAvKiBEbyB0aGUgc3RyYWlnaHRmb3J3YXJkIHRoaW5nIHVudGlsIChpZiBldmVyKSBvbmUgcnVuCisgICAgICAgICAqIGFwcGVhcnMgdG8gd2luIGNvbnNpc3RlbnRseS4KKyAgICAgICAgICovCisgICAgICAgIGZvciAoOzspIHsKKyAgICAgICAgICAgIGFzc2VydChuYSA+IDAgJiYgbmIgPiAxKTsKKyAgICAgICAgICAgIGsgPSBJU0xUKCpwYiwgKnBhLCBjb21wYXJlKTsKKyAgICAgICAgICAgIGlmIChrKSB7CisgICAgICAgICAgICAgICAgaWYgKGsgPCAwKQorICAgICAgICAgICAgICAgICAgICBnb3RvIEZhaWw7CisgICAgICAgICAgICAgICAgKmRlc3QtLSA9ICpwYS0tOworICAgICAgICAgICAgICAgICsrYWNvdW50OworICAgICAgICAgICAgICAgIGJjb3VudCA9IDA7CisgICAgICAgICAgICAgICAgLS1uYTsKKyAgICAgICAgICAgICAgICBpZiAobmEgPT0gMCkKKyAgICAgICAgICAgICAgICAgICAgZ290byBTdWNjZWVkOworICAgICAgICAgICAgICAgIGlmIChhY291bnQgPj0gbWluX2dhbGxvcCkKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBlbHNlIHsKKyAgICAgICAgICAgICAgICAqZGVzdC0tID0gKnBiLS07CisgICAgICAgICAgICAgICAgKytiY291bnQ7CisgICAgICAgICAgICAgICAgYWNvdW50ID0gMDsKKyAgICAgICAgICAgICAgICAtLW5iOworICAgICAgICAgICAgICAgIGlmIChuYiA9PSAxKQorICAgICAgICAgICAgICAgICAgICBnb3RvIENvcHlBOworICAgICAgICAgICAgICAgIGlmIChiY291bnQgPj0gbWluX2dhbGxvcCkKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKworICAgICAgICAvKiBPbmUgcnVuIGlzIHdpbm5pbmcgc28gY29uc2lzdGVudGx5IHRoYXQgZ2FsbG9waW5nIG1heQorICAgICAgICAgKiBiZSBhIGh1Z2Ugd2luLiAgU28gdHJ5IHRoYXQsIGFuZCBjb250aW51ZSBnYWxsb3BpbmcgdW50aWwKKyAgICAgICAgICogKGlmIGV2ZXIpIG5laXRoZXIgcnVuIGFwcGVhcnMgdG8gYmUgd2lubmluZyBjb25zaXN0ZW50bHkKKyAgICAgICAgICogYW55bW9yZS4KKyAgICAgICAgICovCisgICAgICAgICsrbWluX2dhbGxvcDsKKyAgICAgICAgZG8geworICAgICAgICAgICAgYXNzZXJ0KG5hID4gMCAmJiBuYiA+IDEpOworICAgICAgICAgICAgbWluX2dhbGxvcCAtPSBtaW5fZ2FsbG9wID4gMTsKKyAgICAgICAgICAgIG1zLT5taW5fZ2FsbG9wID0gbWluX2dhbGxvcDsKKyAgICAgICAgICAgIGsgPSBnYWxsb3BfcmlnaHQoKnBiLCBiYXNlYSwgbmEsIG5hLTEsIGNvbXBhcmUpOworICAgICAgICAgICAgaWYgKGsgPCAwKQorICAgICAgICAgICAgICAgIGdvdG8gRmFpbDsKKyAgICAgICAgICAgIGsgPSBuYSAtIGs7CisgICAgICAgICAgICBhY291bnQgPSBrOworICAgICAgICAgICAgaWYgKGspIHsKKyAgICAgICAgICAgICAgICBkZXN0IC09IGs7CisgICAgICAgICAgICAgICAgcGEgLT0gazsKKyAgICAgICAgICAgICAgICBtZW1tb3ZlKGRlc3QrMSwgcGErMSwgayAqIHNpemVvZihQeU9iamVjdCAqKSk7CisgICAgICAgICAgICAgICAgbmEgLT0gazsKKyAgICAgICAgICAgICAgICBpZiAobmEgPT0gMCkKKyAgICAgICAgICAgICAgICAgICAgZ290byBTdWNjZWVkOworICAgICAgICAgICAgfQorICAgICAgICAgICAgKmRlc3QtLSA9ICpwYi0tOworICAgICAgICAgICAgLS1uYjsKKyAgICAgICAgICAgIGlmIChuYiA9PSAxKQorICAgICAgICAgICAgICAgIGdvdG8gQ29weUE7CisKKyAgICAgICAgICAgIGsgPSBnYWxsb3BfbGVmdCgqcGEsIGJhc2ViLCBuYiwgbmItMSwgY29tcGFyZSk7CisgICAgICAgICAgICBpZiAoayA8IDApCisgICAgICAgICAgICAgICAgZ290byBGYWlsOworICAgICAgICAgICAgayA9IG5iIC0gazsKKyAgICAgICAgICAgIGJjb3VudCA9IGs7CisgICAgICAgICAgICBpZiAoaykgeworICAgICAgICAgICAgICAgIGRlc3QgLT0gazsKKyAgICAgICAgICAgICAgICBwYiAtPSBrOworICAgICAgICAgICAgICAgIG1lbWNweShkZXN0KzEsIHBiKzEsIGsgKiBzaXplb2YoUHlPYmplY3QgKikpOworICAgICAgICAgICAgICAgIG5iIC09IGs7CisgICAgICAgICAgICAgICAgaWYgKG5iID09IDEpCisgICAgICAgICAgICAgICAgICAgIGdvdG8gQ29weUE7CisgICAgICAgICAgICAgICAgLyogbmI9PTAgaXMgaW1wb3NzaWJsZSBub3cgaWYgdGhlIGNvbXBhcmlzb24KKyAgICAgICAgICAgICAgICAgKiBmdW5jdGlvbiBpcyBjb25zaXN0ZW50LCBidXQgd2UgY2FuJ3QgYXNzdW1lCisgICAgICAgICAgICAgICAgICogdGhhdCBpdCBpcy4KKyAgICAgICAgICAgICAgICAgKi8KKyAgICAgICAgICAgICAgICBpZiAobmIgPT0gMCkKKyAgICAgICAgICAgICAgICAgICAgZ290byBTdWNjZWVkOworICAgICAgICAgICAgfQorICAgICAgICAgICAgKmRlc3QtLSA9ICpwYS0tOworICAgICAgICAgICAgLS1uYTsKKyAgICAgICAgICAgIGlmIChuYSA9PSAwKQorICAgICAgICAgICAgICAgIGdvdG8gU3VjY2VlZDsKKyAgICAgICAgfSB3aGlsZSAoYWNvdW50ID49IE1JTl9HQUxMT1AgfHwgYmNvdW50ID49IE1JTl9HQUxMT1ApOworICAgICAgICArK21pbl9nYWxsb3A7ICAgICAgICAgICAvKiBwZW5hbGl6ZSBpdCBmb3IgbGVhdmluZyBnYWxsb3BpbmcgbW9kZSAqLworICAgICAgICBtcy0+bWluX2dhbGxvcCA9IG1pbl9nYWxsb3A7CisgICAgfQorU3VjY2VlZDoKKyAgICByZXN1bHQgPSAwOworRmFpbDoKKyAgICBpZiAobmIpCisgICAgICAgIG1lbWNweShkZXN0LShuYi0xKSwgYmFzZWIsIG5iICogc2l6ZW9mKFB5T2JqZWN0KikpOworICAgIHJldHVybiByZXN1bHQ7CitDb3B5QToKKyAgICBhc3NlcnQobmIgPT0gMSAmJiBuYSA+IDApOworICAgIC8qIFRoZSBmaXJzdCBlbGVtZW50IG9mIHBiIGJlbG9uZ3MgYXQgdGhlIGZyb250IG9mIHRoZSBtZXJnZS4gKi8KKyAgICBkZXN0IC09IG5hOworICAgIHBhIC09IG5hOworICAgIG1lbW1vdmUoZGVzdCsxLCBwYSsxLCBuYSAqIHNpemVvZihQeU9iamVjdCAqKSk7CisgICAgKmRlc3QgPSAqcGI7CisgICAgcmV0dXJuIDA7Cit9CisKKy8qIE1lcmdlIHRoZSB0d28gcnVucyBhdCBzdGFjayBpbmRpY2VzIGkgYW5kIGkrMS4KKyAqIFJldHVybnMgMCBvbiBzdWNjZXNzLCAtMSBvbiBlcnJvci4KKyAqLworc3RhdGljIFB5X3NzaXplX3QKK21lcmdlX2F0KE1lcmdlU3RhdGUgKm1zLCBQeV9zc2l6ZV90IGkpCit7CisgICAgUHlPYmplY3QgKipwYSwgKipwYjsKKyAgICBQeV9zc2l6ZV90IG5hLCBuYjsKKyAgICBQeV9zc2l6ZV90IGs7CisgICAgUHlPYmplY3QgKmNvbXBhcmU7CisKKyAgICBhc3NlcnQobXMgIT0gTlVMTCk7CisgICAgYXNzZXJ0KG1zLT5uID49IDIpOworICAgIGFzc2VydChpID49IDApOworICAgIGFzc2VydChpID09IG1zLT5uIC0gMiB8fCBpID09IG1zLT5uIC0gMyk7CisKKyAgICBwYSA9IG1zLT5wZW5kaW5nW2ldLmJhc2U7CisgICAgbmEgPSBtcy0+cGVuZGluZ1tpXS5sZW47CisgICAgcGIgPSBtcy0+cGVuZGluZ1tpKzFdLmJhc2U7CisgICAgbmIgPSBtcy0+cGVuZGluZ1tpKzFdLmxlbjsKKyAgICBhc3NlcnQobmEgPiAwICYmIG5iID4gMCk7CisgICAgYXNzZXJ0KHBhICsgbmEgPT0gcGIpOworCisgICAgLyogUmVjb3JkIHRoZSBsZW5ndGggb2YgdGhlIGNvbWJpbmVkIHJ1bnM7IGlmIGkgaXMgdGhlIDNyZC1sYXN0CisgICAgICogcnVuIG5vdywgYWxzbyBzbGlkZSBvdmVyIHRoZSBsYXN0IHJ1biAod2hpY2ggaXNuJ3QgaW52b2x2ZWQKKyAgICAgKiBpbiB0aGlzIG1lcmdlKS4gIFRoZSBjdXJyZW50IHJ1biBpKzEgZ29lcyBhd2F5IGluIGFueSBjYXNlLgorICAgICAqLworICAgIG1zLT5wZW5kaW5nW2ldLmxlbiA9IG5hICsgbmI7CisgICAgaWYgKGkgPT0gbXMtPm4gLSAzKQorICAgICAgICBtcy0+cGVuZGluZ1tpKzFdID0gbXMtPnBlbmRpbmdbaSsyXTsKKyAgICAtLW1zLT5uOworCisgICAgLyogV2hlcmUgZG9lcyBiIHN0YXJ0IGluIGE/ICBFbGVtZW50cyBpbiBhIGJlZm9yZSB0aGF0IGNhbiBiZQorICAgICAqIGlnbm9yZWQgKGFscmVhZHkgaW4gcGxhY2UpLgorICAgICAqLworICAgIGNvbXBhcmUgPSBtcy0+Y29tcGFyZTsKKyAgICBrID0gZ2FsbG9wX3JpZ2h0KCpwYiwgcGEsIG5hLCAwLCBjb21wYXJlKTsKKyAgICBpZiAoayA8IDApCisgICAgICAgIHJldHVybiAtMTsKKyAgICBwYSArPSBrOworICAgIG5hIC09IGs7CisgICAgaWYgKG5hID09IDApCisgICAgICAgIHJldHVybiAwOworCisgICAgLyogV2hlcmUgZG9lcyBhIGVuZCBpbiBiPyAgRWxlbWVudHMgaW4gYiBhZnRlciB0aGF0IGNhbiBiZQorICAgICAqIGlnbm9yZWQgKGFscmVhZHkgaW4gcGxhY2UpLgorICAgICAqLworICAgIG5iID0gZ2FsbG9wX2xlZnQocGFbbmEtMV0sIHBiLCBuYiwgbmItMSwgY29tcGFyZSk7CisgICAgaWYgKG5iIDw9IDApCisgICAgICAgIHJldHVybiBuYjsKKworICAgIC8qIE1lcmdlIHdoYXQgcmVtYWlucyBvZiB0aGUgcnVucywgdXNpbmcgYSB0ZW1wIGFycmF5IHdpdGgKKyAgICAgKiBtaW4obmEsIG5iKSBlbGVtZW50cy4KKyAgICAgKi8KKyAgICBpZiAobmEgPD0gbmIpCisgICAgICAgIHJldHVybiBtZXJnZV9sbyhtcywgcGEsIG5hLCBwYiwgbmIpOworICAgIGVsc2UKKyAgICAgICAgcmV0dXJuIG1lcmdlX2hpKG1zLCBwYSwgbmEsIHBiLCBuYik7Cit9CisKKy8qIEV4YW1pbmUgdGhlIHN0YWNrIG9mIHJ1bnMgd2FpdGluZyB0byBiZSBtZXJnZWQsIG1lcmdpbmcgYWRqYWNlbnQgcnVucworICogdW50aWwgdGhlIHN0YWNrIGludmFyaWFudHMgYXJlIHJlLWVzdGFibGlzaGVkOgorICoKKyAqIDEuIGxlblstM10gPiBsZW5bLTJdICsgbGVuWy0xXQorICogMi4gbGVuWy0yXSA+IGxlblstMV0KKyAqCisgKiBTZWUgbGlzdHNvcnQudHh0IGZvciBtb3JlIGluZm8uCisgKgorICogUmV0dXJucyAwIG9uIHN1Y2Nlc3MsIC0xIG9uIGVycm9yLgorICovCitzdGF0aWMgaW50CittZXJnZV9jb2xsYXBzZShNZXJnZVN0YXRlICptcykKK3sKKyAgICBzdHJ1Y3Qgc19zbGljZSAqcCA9IG1zLT5wZW5kaW5nOworCisgICAgYXNzZXJ0KG1zKTsKKyAgICB3aGlsZSAobXMtPm4gPiAxKSB7CisgICAgICAgIFB5X3NzaXplX3QgbiA9IG1zLT5uIC0gMjsKKyAgICAgICAgaWYgKG4gPiAwICYmIHBbbi0xXS5sZW4gPD0gcFtuXS5sZW4gKyBwW24rMV0ubGVuKSB7CisgICAgICAgICAgICBpZiAocFtuLTFdLmxlbiA8IHBbbisxXS5sZW4pCisgICAgICAgICAgICAgICAgLS1uOworICAgICAgICAgICAgaWYgKG1lcmdlX2F0KG1zLCBuKSA8IDApCisgICAgICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICB9CisgICAgICAgIGVsc2UgaWYgKHBbbl0ubGVuIDw9IHBbbisxXS5sZW4pIHsKKyAgICAgICAgICAgICAgICAgaWYgKG1lcmdlX2F0KG1zLCBuKSA8IDApCisgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgIH0KKyAgICAgICAgZWxzZQorICAgICAgICAgICAgYnJlYWs7CisgICAgfQorICAgIHJldHVybiAwOworfQorCisvKiBSZWdhcmRsZXNzIG9mIGludmFyaWFudHMsIG1lcmdlIGFsbCBydW5zIG9uIHRoZSBzdGFjayB1bnRpbCBvbmx5IG9uZQorICogcmVtYWlucy4gIFRoaXMgaXMgdXNlZCBhdCB0aGUgZW5kIG9mIHRoZSBtZXJnZXNvcnQuCisgKgorICogUmV0dXJucyAwIG9uIHN1Y2Nlc3MsIC0xIG9uIGVycm9yLgorICovCitzdGF0aWMgaW50CittZXJnZV9mb3JjZV9jb2xsYXBzZShNZXJnZVN0YXRlICptcykKK3sKKyAgICBzdHJ1Y3Qgc19zbGljZSAqcCA9IG1zLT5wZW5kaW5nOworCisgICAgYXNzZXJ0KG1zKTsKKyAgICB3aGlsZSAobXMtPm4gPiAxKSB7CisgICAgICAgIFB5X3NzaXplX3QgbiA9IG1zLT5uIC0gMjsKKyAgICAgICAgaWYgKG4gPiAwICYmIHBbbi0xXS5sZW4gPCBwW24rMV0ubGVuKQorICAgICAgICAgICAgLS1uOworICAgICAgICBpZiAobWVyZ2VfYXQobXMsIG4pIDwgMCkKKyAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisgICAgcmV0dXJuIDA7Cit9CisKKy8qIENvbXB1dGUgYSBnb29kIHZhbHVlIGZvciB0aGUgbWluaW11bSBydW4gbGVuZ3RoOyBuYXR1cmFsIHJ1bnMgc2hvcnRlcgorICogdGhhbiB0aGlzIGFyZSBib29zdGVkIGFydGlmaWNpYWxseSB2aWEgYmluYXJ5IGluc2VydGlvbi4KKyAqCisgKiBJZiBuIDwgNjQsIHJldHVybiBuIChpdCdzIHRvbyBzbWFsbCB0byBib3RoZXIgd2l0aCBmYW5jeSBzdHVmZikuCisgKiBFbHNlIGlmIG4gaXMgYW4gZXhhY3QgcG93ZXIgb2YgMiwgcmV0dXJuIDMyLgorICogRWxzZSByZXR1cm4gYW4gaW50IGssIDMyIDw9IGsgPD0gNjQsIHN1Y2ggdGhhdCBuL2sgaXMgY2xvc2UgdG8sIGJ1dAorICogc3RyaWN0bHkgbGVzcyB0aGFuLCBhbiBleGFjdCBwb3dlciBvZiAyLgorICoKKyAqIFNlZSBsaXN0c29ydC50eHQgZm9yIG1vcmUgaW5mby4KKyAqLworc3RhdGljIFB5X3NzaXplX3QKK21lcmdlX2NvbXB1dGVfbWlucnVuKFB5X3NzaXplX3QgbikKK3sKKyAgICBQeV9zc2l6ZV90IHIgPSAwOyAgICAgICAgICAgLyogYmVjb21lcyAxIGlmIGFueSAxIGJpdHMgYXJlIHNoaWZ0ZWQgb2ZmICovCisKKyAgICBhc3NlcnQobiA+PSAwKTsKKyAgICB3aGlsZSAobiA+PSA2NCkgeworICAgICAgICByIHw9IG4gJiAxOworICAgICAgICBuID4+PSAxOworICAgIH0KKyAgICByZXR1cm4gbiArIHI7Cit9CisKKy8qIFNwZWNpYWwgd3JhcHBlciB0byBzdXBwb3J0IHN0YWJsZSBzb3J0aW5nIHVzaW5nIHRoZSBkZWNvcmF0ZS1zb3J0LXVuZGVjb3JhdGUKKyAgIHBhdHRlcm4uICBIb2xkcyBhIGtleSB3aGljaCBpcyB1c2VkIGZvciBjb21wYXJpc29ucyBhbmQgdGhlIG9yaWdpbmFsIHJlY29yZAorICAgd2hpY2ggaXMgcmV0dXJuZWQgZHVyaW5nIHRoZSB1bmRlY29yYXRlIHBoYXNlLiAgQnkgZXhwb3Npbmcgb25seSB0aGUga2V5CisgICBkdXJpbmcgY29tcGFyaXNvbnMsIHRoZSB1bmRlcmx5aW5nIHNvcnQgc3RhYmlsaXR5IGNoYXJhY3RlcmlzdGljcyBhcmUgbGVmdAorICAgdW5jaGFuZ2VkLiAgQWxzbywgaWYgYSBjdXN0b20gY29tcGFyaXNvbiBmdW5jdGlvbiBpcyB1c2VkLCBpdCB3aWxsIG9ubHkgc2VlCisgICB0aGUga2V5IGluc3RlYWQgb2YgYSBmdWxsIHJlY29yZC4gKi8KKwordHlwZWRlZiBzdHJ1Y3QgeworICAgIFB5T2JqZWN0X0hFQUQKKyAgICBQeU9iamVjdCAqa2V5OworICAgIFB5T2JqZWN0ICp2YWx1ZTsKK30gc29ydHdyYXBwZXJvYmplY3Q7CisKK1B5RG9jX1NUUlZBUihzb3J0d3JhcHBlcl9kb2MsICJPYmplY3Qgd3JhcHBlciB3aXRoIGEgY3VzdG9tIHNvcnQga2V5LiIpOworc3RhdGljIFB5T2JqZWN0ICoKK3NvcnR3cmFwcGVyX3JpY2hjb21wYXJlKHNvcnR3cmFwcGVyb2JqZWN0ICosIHNvcnR3cmFwcGVyb2JqZWN0ICosIGludCk7CitzdGF0aWMgdm9pZAorc29ydHdyYXBwZXJfZGVhbGxvYyhzb3J0d3JhcHBlcm9iamVjdCAqKTsKKworc3RhdGljIFB5VHlwZU9iamVjdCBzb3J0d3JhcHBlcl90eXBlID0geworICAgIFB5VmFyT2JqZWN0X0hFQURfSU5JVCgmUHlUeXBlX1R5cGUsIDApCisgICAgInNvcnR3cmFwcGVyIiwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9uYW1lICovCisgICAgc2l6ZW9mKHNvcnR3cmFwcGVyb2JqZWN0KSwgICAgICAgICAgICAgICAgICAvKiB0cF9iYXNpY3NpemUgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2l0ZW1zaXplICovCisgICAgLyogbWV0aG9kcyAqLworICAgIChkZXN0cnVjdG9yKXNvcnR3cmFwcGVyX2RlYWxsb2MsICAgICAgICAgICAgLyogdHBfZGVhbGxvYyAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfcHJpbnQgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2dldGF0dHIgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3NldGF0dHIgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2NvbXBhcmUgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3JlcHIgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2FzX251bWJlciAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfYXNfc2VxdWVuY2UgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2FzX21hcHBpbmcgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2hhc2ggKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2NhbGwgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3N0ciAqLworICAgIFB5T2JqZWN0X0dlbmVyaWNHZXRBdHRyLCAgICAgICAgICAgICAgICAgICAgLyogdHBfZ2V0YXR0cm8gKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3NldGF0dHJvICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9hc19idWZmZXIgKi8KKyAgICBQeV9UUEZMQUdTX0RFRkFVTFQgfAorICAgIFB5X1RQRkxBR1NfSEFWRV9SSUNIQ09NUEFSRSwgICAgICAgICAgICAgICAgLyogdHBfZmxhZ3MgKi8KKyAgICBzb3J0d3JhcHBlcl9kb2MsICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2RvYyAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfdHJhdmVyc2UgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2NsZWFyICovCisgICAgKHJpY2hjbXBmdW5jKXNvcnR3cmFwcGVyX3JpY2hjb21wYXJlLCAgICAgICAvKiB0cF9yaWNoY29tcGFyZSAqLworfTsKKworCitzdGF0aWMgUHlPYmplY3QgKgorc29ydHdyYXBwZXJfcmljaGNvbXBhcmUoc29ydHdyYXBwZXJvYmplY3QgKmEsIHNvcnR3cmFwcGVyb2JqZWN0ICpiLCBpbnQgb3ApCit7CisgICAgaWYgKCFQeU9iamVjdF9UeXBlQ2hlY2soYiwgJnNvcnR3cmFwcGVyX3R5cGUpKSB7CisgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19UeXBlRXJyb3IsCisgICAgICAgICAgICAiZXhwZWN0ZWQgYSBzb3J0d3JhcHBlcm9iamVjdCIpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgcmV0dXJuIFB5T2JqZWN0X1JpY2hDb21wYXJlKGEtPmtleSwgYi0+a2V5LCBvcCk7Cit9CisKK3N0YXRpYyB2b2lkCitzb3J0d3JhcHBlcl9kZWFsbG9jKHNvcnR3cmFwcGVyb2JqZWN0ICpzbykKK3sKKyAgICBQeV9YREVDUkVGKHNvLT5rZXkpOworICAgIFB5X1hERUNSRUYoc28tPnZhbHVlKTsKKyAgICBQeU9iamVjdF9EZWwoc28pOworfQorCisvKiBSZXR1cm5zIGEgbmV3IHJlZmVyZW5jZSB0byBhIHNvcnR3cmFwcGVyLgorICAgQ29uc3VtZXMgdGhlIHJlZmVyZW5jZXMgdG8gdGhlIHR3byB1bmRlcmx5aW5nIG9iamVjdHMuICovCisKK3N0YXRpYyBQeU9iamVjdCAqCitidWlsZF9zb3J0d3JhcHBlcihQeU9iamVjdCAqa2V5LCBQeU9iamVjdCAqdmFsdWUpCit7CisgICAgc29ydHdyYXBwZXJvYmplY3QgKnNvOworCisgICAgc28gPSBQeU9iamVjdF9OZXcoc29ydHdyYXBwZXJvYmplY3QsICZzb3J0d3JhcHBlcl90eXBlKTsKKyAgICBpZiAoc28gPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgc28tPmtleSA9IGtleTsKKyAgICBzby0+dmFsdWUgPSB2YWx1ZTsKKyAgICByZXR1cm4gKFB5T2JqZWN0ICopc287Cit9CisKKy8qIFJldHVybnMgYSBuZXcgcmVmZXJlbmNlIHRvIHRoZSB2YWx1ZSB1bmRlcmx5aW5nIHRoZSB3cmFwcGVyLiAqLworc3RhdGljIFB5T2JqZWN0ICoKK3NvcnR3cmFwcGVyX2dldHZhbHVlKFB5T2JqZWN0ICpzbykKK3sKKyAgICBQeU9iamVjdCAqdmFsdWU7CisKKyAgICBpZiAoIVB5T2JqZWN0X1R5cGVDaGVjayhzbywgJnNvcnR3cmFwcGVyX3R5cGUpKSB7CisgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19UeXBlRXJyb3IsCisgICAgICAgICAgICAiZXhwZWN0ZWQgYSBzb3J0d3JhcHBlcm9iamVjdCIpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgdmFsdWUgPSAoKHNvcnR3cmFwcGVyb2JqZWN0ICopc28pLT52YWx1ZTsKKyAgICBQeV9JTkNSRUYodmFsdWUpOworICAgIHJldHVybiB2YWx1ZTsKK30KKworLyogV3JhcHBlciBmb3IgdXNlciBzcGVjaWZpZWQgY21wIGZ1bmN0aW9ucyBpbiBjb21iaW5hdGlvbiB3aXRoIGEKKyAgIHNwZWNpZmllZCBrZXkgZnVuY3Rpb24uICBNYWtlcyBzdXJlIHRoZSBjbXAgZnVuY3Rpb24gaXMgcHJlc2VudGVkCisgICB3aXRoIHRoZSBhY3R1YWwga2V5IGluc3RlYWQgb2YgdGhlIHNvcnR3cmFwcGVyICovCisKK3R5cGVkZWYgc3RydWN0IHsKKyAgICBQeU9iamVjdF9IRUFECisgICAgUHlPYmplY3QgKmZ1bmM7Cit9IGNtcHdyYXBwZXJvYmplY3Q7CisKK3N0YXRpYyB2b2lkCitjbXB3cmFwcGVyX2RlYWxsb2MoY21wd3JhcHBlcm9iamVjdCAqY28pCit7CisgICAgUHlfWERFQ1JFRihjby0+ZnVuYyk7CisgICAgUHlPYmplY3RfRGVsKGNvKTsKK30KKworc3RhdGljIFB5T2JqZWN0ICoKK2NtcHdyYXBwZXJfY2FsbChjbXB3cmFwcGVyb2JqZWN0ICpjbywgUHlPYmplY3QgKmFyZ3MsIFB5T2JqZWN0ICprd2RzKQoreworICAgIFB5T2JqZWN0ICp4LCAqeSwgKnh4LCAqeXk7CisKKyAgICBpZiAoIVB5QXJnX1VucGFja1R1cGxlKGFyZ3MsICIiLCAyLCAyLCAmeCwgJnkpKQorICAgICAgICByZXR1cm4gTlVMTDsKKyAgICBpZiAoIVB5T2JqZWN0X1R5cGVDaGVjayh4LCAmc29ydHdyYXBwZXJfdHlwZSkgfHwKKyAgICAgICAgIVB5T2JqZWN0X1R5cGVDaGVjayh5LCAmc29ydHdyYXBwZXJfdHlwZSkpIHsKKyAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1R5cGVFcnJvciwKKyAgICAgICAgICAgICJleHBlY3RlZCBhIHNvcnR3cmFwcGVyb2JqZWN0Iik7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICB4eCA9ICgoc29ydHdyYXBwZXJvYmplY3QgKil4KS0+a2V5OworICAgIHl5ID0gKChzb3J0d3JhcHBlcm9iamVjdCAqKXkpLT5rZXk7CisgICAgcmV0dXJuIFB5T2JqZWN0X0NhbGxGdW5jdGlvbk9iakFyZ3MoY28tPmZ1bmMsIHh4LCB5eSwgTlVMTCk7Cit9CisKK1B5RG9jX1NUUlZBUihjbXB3cmFwcGVyX2RvYywgImNtcCgpIHdyYXBwZXIgZm9yIHNvcnQgd2l0aCBjdXN0b20ga2V5cy4iKTsKKworc3RhdGljIFB5VHlwZU9iamVjdCBjbXB3cmFwcGVyX3R5cGUgPSB7CisgICAgUHlWYXJPYmplY3RfSEVBRF9JTklUKCZQeVR5cGVfVHlwZSwgMCkKKyAgICAiY21wd3JhcHBlciIsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX25hbWUgKi8KKyAgICBzaXplb2YoY21wd3JhcHBlcm9iamVjdCksICAgICAgICAgICAgICAgICAgIC8qIHRwX2Jhc2ljc2l6ZSAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfaXRlbXNpemUgKi8KKyAgICAvKiBtZXRob2RzICovCisgICAgKGRlc3RydWN0b3IpY21wd3JhcHBlcl9kZWFsbG9jLCAgICAgICAgICAgICAvKiB0cF9kZWFsbG9jICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9wcmludCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZ2V0YXR0ciAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfc2V0YXR0ciAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfY29tcGFyZSAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfcmVwciAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfYXNfbnVtYmVyICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9hc19zZXF1ZW5jZSAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfYXNfbWFwcGluZyAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfaGFzaCAqLworICAgICh0ZXJuYXJ5ZnVuYyljbXB3cmFwcGVyX2NhbGwsICAgICAgICAgICAgICAgLyogdHBfY2FsbCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfc3RyICovCisgICAgUHlPYmplY3RfR2VuZXJpY0dldEF0dHIsICAgICAgICAgICAgICAgICAgICAvKiB0cF9nZXRhdHRybyAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfc2V0YXR0cm8gKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2FzX2J1ZmZlciAqLworICAgIFB5X1RQRkxBR1NfREVGQVVMVCwgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZmxhZ3MgKi8KKyAgICBjbXB3cmFwcGVyX2RvYywgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2RvYyAqLworfTsKKworc3RhdGljIFB5T2JqZWN0ICoKK2J1aWxkX2NtcHdyYXBwZXIoUHlPYmplY3QgKmNtcGZ1bmMpCit7CisgICAgY21wd3JhcHBlcm9iamVjdCAqY287CisKKyAgICBjbyA9IFB5T2JqZWN0X05ldyhjbXB3cmFwcGVyb2JqZWN0LCAmY21wd3JhcHBlcl90eXBlKTsKKyAgICBpZiAoY28gPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgUHlfSU5DUkVGKGNtcGZ1bmMpOworICAgIGNvLT5mdW5jID0gY21wZnVuYzsKKyAgICByZXR1cm4gKFB5T2JqZWN0ICopY287Cit9CisKKy8qIEFuIGFkYXB0aXZlLCBzdGFibGUsIG5hdHVyYWwgbWVyZ2Vzb3J0LiAgU2VlIGxpc3Rzb3J0LnR4dC4KKyAqIFJldHVybnMgUHlfTm9uZSBvbiBzdWNjZXNzLCBOVUxMIG9uIGVycm9yLiAgRXZlbiBpbiBjYXNlIG9mIGVycm9yLCB0aGUKKyAqIGxpc3Qgd2lsbCBiZSBzb21lIHBlcm11dGF0aW9uIG9mIGl0cyBpbnB1dCBzdGF0ZSAobm90aGluZyBpcyBsb3N0IG9yCisgKiBkdXBsaWNhdGVkKS4KKyAqLworc3RhdGljIFB5T2JqZWN0ICoKK2xpc3Rzb3J0KFB5TGlzdE9iamVjdCAqc2VsZiwgUHlPYmplY3QgKmFyZ3MsIFB5T2JqZWN0ICprd2RzKQoreworICAgIE1lcmdlU3RhdGUgbXM7CisgICAgUHlPYmplY3QgKipsbywgKipoaTsKKyAgICBQeV9zc2l6ZV90IG5yZW1haW5pbmc7CisgICAgUHlfc3NpemVfdCBtaW5ydW47CisgICAgUHlfc3NpemVfdCBzYXZlZF9vYl9zaXplLCBzYXZlZF9hbGxvY2F0ZWQ7CisgICAgUHlPYmplY3QgKipzYXZlZF9vYl9pdGVtOworICAgIFB5T2JqZWN0ICoqZmluYWxfb2JfaXRlbTsKKyAgICBQeU9iamVjdCAqY29tcGFyZSA9IE5VTEw7CisgICAgUHlPYmplY3QgKnJlc3VsdCA9IE5VTEw7ICAgICAgICAgICAgLyogZ3VpbHR5IHVudGlsIHByb3ZlZCBpbm5vY2VudCAqLworICAgIGludCByZXZlcnNlID0gMDsKKyAgICBQeU9iamVjdCAqa2V5ZnVuYyA9IE5VTEw7CisgICAgUHlfc3NpemVfdCBpOworICAgIFB5T2JqZWN0ICprZXksICp2YWx1ZSwgKmt2cGFpcjsKKyAgICBzdGF0aWMgY2hhciAqa3dsaXN0W10gPSB7ImNtcCIsICJrZXkiLCAicmV2ZXJzZSIsIDB9OworCisgICAgYXNzZXJ0KHNlbGYgIT0gTlVMTCk7CisgICAgYXNzZXJ0IChQeUxpc3RfQ2hlY2soc2VsZikpOworICAgIGlmIChhcmdzICE9IE5VTEwpIHsKKyAgICAgICAgaWYgKCFQeUFyZ19QYXJzZVR1cGxlQW5kS2V5d29yZHMoYXJncywga3dkcywgInxPT2k6c29ydCIsCisgICAgICAgICAgICBrd2xpc3QsICZjb21wYXJlLCAma2V5ZnVuYywgJnJldmVyc2UpKQorICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIGlmIChjb21wYXJlID09IFB5X05vbmUpCisgICAgICAgIGNvbXBhcmUgPSBOVUxMOworICAgIGlmIChjb21wYXJlICE9IE5VTEwgJiYKKyAgICAgICAgUHlFcnJfV2FyblB5M2soInRoZSBjbXAgYXJndW1lbnQgaXMgbm90IHN1cHBvcnRlZCBpbiAzLngiLCAxKSA8IDApCisgICAgICAgIHJldHVybiBOVUxMOworICAgIGlmIChrZXlmdW5jID09IFB5X05vbmUpCisgICAgICAgIGtleWZ1bmMgPSBOVUxMOworICAgIGlmIChjb21wYXJlICE9IE5VTEwgJiYga2V5ZnVuYyAhPSBOVUxMKSB7CisgICAgICAgIGNvbXBhcmUgPSBidWlsZF9jbXB3cmFwcGVyKGNvbXBhcmUpOworICAgICAgICBpZiAoY29tcGFyZSA9PSBOVUxMKQorICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfSBlbHNlCisgICAgICAgIFB5X1hJTkNSRUYoY29tcGFyZSk7CisKKyAgICAvKiBUaGUgbGlzdCBpcyB0ZW1wb3JhcmlseSBtYWRlIGVtcHR5LCBzbyB0aGF0IG11dGF0aW9ucyBwZXJmb3JtZWQKKyAgICAgKiBieSBjb21wYXJpc29uIGZ1bmN0aW9ucyBjYW4ndCBhZmZlY3QgdGhlIHNsaWNlIG9mIG1lbW9yeSB3ZSdyZQorICAgICAqIHNvcnRpbmcgKGFsbG93aW5nIG11dGF0aW9ucyBkdXJpbmcgc29ydGluZyBpcyBhIGNvcmUtZHVtcAorICAgICAqIGZhY3RvcnksIHNpbmNlIG9iX2l0ZW0gbWF5IGNoYW5nZSkuCisgICAgICovCisgICAgc2F2ZWRfb2Jfc2l6ZSA9IFB5X1NJWkUoc2VsZik7CisgICAgc2F2ZWRfb2JfaXRlbSA9IHNlbGYtPm9iX2l0ZW07CisgICAgc2F2ZWRfYWxsb2NhdGVkID0gc2VsZi0+YWxsb2NhdGVkOworICAgIFB5X1NJWkUoc2VsZikgPSAwOworICAgIHNlbGYtPm9iX2l0ZW0gPSBOVUxMOworICAgIHNlbGYtPmFsbG9jYXRlZCA9IC0xOyAvKiBhbnkgb3BlcmF0aW9uIHdpbGwgcmVzZXQgaXQgdG8gPj0gMCAqLworCisgICAgaWYgKGtleWZ1bmMgIT0gTlVMTCkgeworICAgICAgICBmb3IgKGk9MCA7IGkgPCBzYXZlZF9vYl9zaXplIDsgaSsrKSB7CisgICAgICAgICAgICB2YWx1ZSA9IHNhdmVkX29iX2l0ZW1baV07CisgICAgICAgICAgICBrZXkgPSBQeU9iamVjdF9DYWxsRnVuY3Rpb25PYmpBcmdzKGtleWZ1bmMsIHZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOVUxMKTsKKyAgICAgICAgICAgIGlmIChrZXkgPT0gTlVMTCkgeworICAgICAgICAgICAgICAgIGZvciAoaT1pLTEgOyBpPj0wIDsgaS0tKSB7CisgICAgICAgICAgICAgICAgICAgIGt2cGFpciA9IHNhdmVkX29iX2l0ZW1baV07CisgICAgICAgICAgICAgICAgICAgIHZhbHVlID0gc29ydHdyYXBwZXJfZ2V0dmFsdWUoa3ZwYWlyKTsKKyAgICAgICAgICAgICAgICAgICAgc2F2ZWRfb2JfaXRlbVtpXSA9IHZhbHVlOworICAgICAgICAgICAgICAgICAgICBQeV9ERUNSRUYoa3ZwYWlyKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgZ290byBkc3VfZmFpbDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGt2cGFpciA9IGJ1aWxkX3NvcnR3cmFwcGVyKGtleSwgdmFsdWUpOworICAgICAgICAgICAgaWYgKGt2cGFpciA9PSBOVUxMKQorICAgICAgICAgICAgICAgIGdvdG8gZHN1X2ZhaWw7CisgICAgICAgICAgICBzYXZlZF9vYl9pdGVtW2ldID0ga3ZwYWlyOworICAgICAgICB9CisgICAgfQorCisgICAgLyogUmV2ZXJzZSBzb3J0IHN0YWJpbGl0eSBhY2hpZXZlZCBieSBpbml0aWFsbHkgcmV2ZXJzaW5nIHRoZSBsaXN0LAorICAgIGFwcGx5aW5nIGEgc3RhYmxlIGZvcndhcmQgc29ydCwgdGhlbiByZXZlcnNpbmcgdGhlIGZpbmFsIHJlc3VsdC4gKi8KKyAgICBpZiAocmV2ZXJzZSAmJiBzYXZlZF9vYl9zaXplID4gMSkKKyAgICAgICAgcmV2ZXJzZV9zbGljZShzYXZlZF9vYl9pdGVtLCBzYXZlZF9vYl9pdGVtICsgc2F2ZWRfb2Jfc2l6ZSk7CisKKyAgICBtZXJnZV9pbml0KCZtcywgY29tcGFyZSk7CisKKyAgICBucmVtYWluaW5nID0gc2F2ZWRfb2Jfc2l6ZTsKKyAgICBpZiAobnJlbWFpbmluZyA8IDIpCisgICAgICAgIGdvdG8gc3VjY2VlZDsKKworICAgIC8qIE1hcmNoIG92ZXIgdGhlIGFycmF5IG9uY2UsIGxlZnQgdG8gcmlnaHQsIGZpbmRpbmcgbmF0dXJhbCBydW5zLAorICAgICAqIGFuZCBleHRlbmRpbmcgc2hvcnQgbmF0dXJhbCBydW5zIHRvIG1pbnJ1biBlbGVtZW50cy4KKyAgICAgKi8KKyAgICBsbyA9IHNhdmVkX29iX2l0ZW07CisgICAgaGkgPSBsbyArIG5yZW1haW5pbmc7CisgICAgbWlucnVuID0gbWVyZ2VfY29tcHV0ZV9taW5ydW4obnJlbWFpbmluZyk7CisgICAgZG8geworICAgICAgICBpbnQgZGVzY2VuZGluZzsKKyAgICAgICAgUHlfc3NpemVfdCBuOworCisgICAgICAgIC8qIElkZW50aWZ5IG5leHQgcnVuLiAqLworICAgICAgICBuID0gY291bnRfcnVuKGxvLCBoaSwgY29tcGFyZSwgJmRlc2NlbmRpbmcpOworICAgICAgICBpZiAobiA8IDApCisgICAgICAgICAgICBnb3RvIGZhaWw7CisgICAgICAgIGlmIChkZXNjZW5kaW5nKQorICAgICAgICAgICAgcmV2ZXJzZV9zbGljZShsbywgbG8gKyBuKTsKKyAgICAgICAgLyogSWYgc2hvcnQsIGV4dGVuZCB0byBtaW4obWlucnVuLCBucmVtYWluaW5nKS4gKi8KKyAgICAgICAgaWYgKG4gPCBtaW5ydW4pIHsKKyAgICAgICAgICAgIGNvbnN0IFB5X3NzaXplX3QgZm9yY2UgPSBucmVtYWluaW5nIDw9IG1pbnJ1biA/CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBucmVtYWluaW5nIDogbWlucnVuOworICAgICAgICAgICAgaWYgKGJpbmFyeXNvcnQobG8sIGxvICsgZm9yY2UsIGxvICsgbiwgY29tcGFyZSkgPCAwKQorICAgICAgICAgICAgICAgIGdvdG8gZmFpbDsKKyAgICAgICAgICAgIG4gPSBmb3JjZTsKKyAgICAgICAgfQorICAgICAgICAvKiBQdXNoIHJ1biBvbnRvIHBlbmRpbmctcnVucyBzdGFjaywgYW5kIG1heWJlIG1lcmdlLiAqLworICAgICAgICBhc3NlcnQobXMubiA8IE1BWF9NRVJHRV9QRU5ESU5HKTsKKyAgICAgICAgbXMucGVuZGluZ1ttcy5uXS5iYXNlID0gbG87CisgICAgICAgIG1zLnBlbmRpbmdbbXMubl0ubGVuID0gbjsKKyAgICAgICAgKyttcy5uOworICAgICAgICBpZiAobWVyZ2VfY29sbGFwc2UoJm1zKSA8IDApCisgICAgICAgICAgICBnb3RvIGZhaWw7CisgICAgICAgIC8qIEFkdmFuY2UgdG8gZmluZCBuZXh0IHJ1bi4gKi8KKyAgICAgICAgbG8gKz0gbjsKKyAgICAgICAgbnJlbWFpbmluZyAtPSBuOworICAgIH0gd2hpbGUgKG5yZW1haW5pbmcpOworICAgIGFzc2VydChsbyA9PSBoaSk7CisKKyAgICBpZiAobWVyZ2VfZm9yY2VfY29sbGFwc2UoJm1zKSA8IDApCisgICAgICAgIGdvdG8gZmFpbDsKKyAgICBhc3NlcnQobXMubiA9PSAxKTsKKyAgICBhc3NlcnQobXMucGVuZGluZ1swXS5iYXNlID09IHNhdmVkX29iX2l0ZW0pOworICAgIGFzc2VydChtcy5wZW5kaW5nWzBdLmxlbiA9PSBzYXZlZF9vYl9zaXplKTsKKworc3VjY2VlZDoKKyAgICByZXN1bHQgPSBQeV9Ob25lOworZmFpbDoKKyAgICBpZiAoa2V5ZnVuYyAhPSBOVUxMKSB7CisgICAgICAgIGZvciAoaT0wIDsgaSA8IHNhdmVkX29iX3NpemUgOyBpKyspIHsKKyAgICAgICAgICAgIGt2cGFpciA9IHNhdmVkX29iX2l0ZW1baV07CisgICAgICAgICAgICB2YWx1ZSA9IHNvcnR3cmFwcGVyX2dldHZhbHVlKGt2cGFpcik7CisgICAgICAgICAgICBzYXZlZF9vYl9pdGVtW2ldID0gdmFsdWU7CisgICAgICAgICAgICBQeV9ERUNSRUYoa3ZwYWlyKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIGlmIChzZWxmLT5hbGxvY2F0ZWQgIT0gLTEgJiYgcmVzdWx0ICE9IE5VTEwpIHsKKyAgICAgICAgLyogVGhlIHVzZXIgbXVja2VkIHdpdGggdGhlIGxpc3QgZHVyaW5nIHRoZSBzb3J0LAorICAgICAgICAgKiBhbmQgd2UgZG9uJ3QgYWxyZWFkeSBoYXZlIGFub3RoZXIgZXJyb3IgdG8gcmVwb3J0LgorICAgICAgICAgKi8KKyAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1ZhbHVlRXJyb3IsICJsaXN0IG1vZGlmaWVkIGR1cmluZyBzb3J0Iik7CisgICAgICAgIHJlc3VsdCA9IE5VTEw7CisgICAgfQorCisgICAgaWYgKHJldmVyc2UgJiYgc2F2ZWRfb2Jfc2l6ZSA+IDEpCisgICAgICAgIHJldmVyc2Vfc2xpY2Uoc2F2ZWRfb2JfaXRlbSwgc2F2ZWRfb2JfaXRlbSArIHNhdmVkX29iX3NpemUpOworCisgICAgbWVyZ2VfZnJlZW1lbSgmbXMpOworCitkc3VfZmFpbDoKKyAgICBmaW5hbF9vYl9pdGVtID0gc2VsZi0+b2JfaXRlbTsKKyAgICBpID0gUHlfU0laRShzZWxmKTsKKyAgICBQeV9TSVpFKHNlbGYpID0gc2F2ZWRfb2Jfc2l6ZTsKKyAgICBzZWxmLT5vYl9pdGVtID0gc2F2ZWRfb2JfaXRlbTsKKyAgICBzZWxmLT5hbGxvY2F0ZWQgPSBzYXZlZF9hbGxvY2F0ZWQ7CisgICAgaWYgKGZpbmFsX29iX2l0ZW0gIT0gTlVMTCkgeworICAgICAgICAvKiB3ZSBjYW5ub3QgdXNlIGxpc3RfY2xlYXIoKSBmb3IgdGhpcyBiZWNhdXNlIGl0IGRvZXMgbm90CisgICAgICAgICAgIGd1YXJhbnRlZSB0aGF0IHRoZSBsaXN0IGlzIHJlYWxseSBlbXB0eSB3aGVuIGl0IHJldHVybnMgKi8KKyAgICAgICAgd2hpbGUgKC0taSA+PSAwKSB7CisgICAgICAgICAgICBQeV9YREVDUkVGKGZpbmFsX29iX2l0ZW1baV0pOworICAgICAgICB9CisgICAgICAgIFB5TWVtX0ZSRUUoZmluYWxfb2JfaXRlbSk7CisgICAgfQorICAgIFB5X1hERUNSRUYoY29tcGFyZSk7CisgICAgUHlfWElOQ1JFRihyZXN1bHQpOworICAgIHJldHVybiByZXN1bHQ7Cit9CisjdW5kZWYgSUZMVAorI3VuZGVmIElTTFQKKworaW50CitQeUxpc3RfU29ydChQeU9iamVjdCAqdikKK3sKKyAgICBpZiAodiA9PSBOVUxMIHx8ICFQeUxpc3RfQ2hlY2sodikpIHsKKyAgICAgICAgUHlFcnJfQmFkSW50ZXJuYWxDYWxsKCk7CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisgICAgdiA9IGxpc3Rzb3J0KChQeUxpc3RPYmplY3QgKil2LCAoUHlPYmplY3QgKilOVUxMLCAoUHlPYmplY3QgKilOVUxMKTsKKyAgICBpZiAodiA9PSBOVUxMKQorICAgICAgICByZXR1cm4gLTE7CisgICAgUHlfREVDUkVGKHYpOworICAgIHJldHVybiAwOworfQorCitzdGF0aWMgUHlPYmplY3QgKgorbGlzdHJldmVyc2UoUHlMaXN0T2JqZWN0ICpzZWxmKQoreworICAgIGlmIChQeV9TSVpFKHNlbGYpID4gMSkKKyAgICAgICAgcmV2ZXJzZV9zbGljZShzZWxmLT5vYl9pdGVtLCBzZWxmLT5vYl9pdGVtICsgUHlfU0laRShzZWxmKSk7CisgICAgUHlfUkVUVVJOX05PTkU7Cit9CisKK2ludAorUHlMaXN0X1JldmVyc2UoUHlPYmplY3QgKnYpCit7CisgICAgUHlMaXN0T2JqZWN0ICpzZWxmID0gKFB5TGlzdE9iamVjdCAqKXY7CisKKyAgICBpZiAodiA9PSBOVUxMIHx8ICFQeUxpc3RfQ2hlY2sodikpIHsKKyAgICAgICAgUHlFcnJfQmFkSW50ZXJuYWxDYWxsKCk7CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisgICAgaWYgKFB5X1NJWkUoc2VsZikgPiAxKQorICAgICAgICByZXZlcnNlX3NsaWNlKHNlbGYtPm9iX2l0ZW0sIHNlbGYtPm9iX2l0ZW0gKyBQeV9TSVpFKHNlbGYpKTsKKyAgICByZXR1cm4gMDsKK30KKworUHlPYmplY3QgKgorUHlMaXN0X0FzVHVwbGUoUHlPYmplY3QgKnYpCit7CisgICAgUHlPYmplY3QgKnc7CisgICAgUHlPYmplY3QgKipwLCAqKnE7CisgICAgUHlfc3NpemVfdCBuOworICAgIGlmICh2ID09IE5VTEwgfHwgIVB5TGlzdF9DaGVjayh2KSkgeworICAgICAgICBQeUVycl9CYWRJbnRlcm5hbENhbGwoKTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIG4gPSBQeV9TSVpFKHYpOworICAgIHcgPSBQeVR1cGxlX05ldyhuKTsKKyAgICBpZiAodyA9PSBOVUxMKQorICAgICAgICByZXR1cm4gTlVMTDsKKyAgICBwID0gKChQeVR1cGxlT2JqZWN0ICopdyktPm9iX2l0ZW07CisgICAgcSA9ICgoUHlMaXN0T2JqZWN0ICopdiktPm9iX2l0ZW07CisgICAgd2hpbGUgKC0tbiA+PSAwKSB7CisgICAgICAgIFB5X0lOQ1JFRigqcSk7CisgICAgICAgICpwID0gKnE7CisgICAgICAgIHArKzsKKyAgICAgICAgcSsrOworICAgIH0KKyAgICByZXR1cm4gdzsKK30KKworc3RhdGljIFB5T2JqZWN0ICoKK2xpc3RpbmRleChQeUxpc3RPYmplY3QgKnNlbGYsIFB5T2JqZWN0ICphcmdzKQoreworICAgIFB5X3NzaXplX3QgaSwgc3RhcnQ9MCwgc3RvcD1QeV9TSVpFKHNlbGYpOworICAgIFB5T2JqZWN0ICp2LCAqZm9ybWF0X3R1cGxlLCAqZXJyX3N0cmluZzsKKyAgICBzdGF0aWMgUHlPYmplY3QgKmVycl9mb3JtYXQgPSBOVUxMOworCisgICAgaWYgKCFQeUFyZ19QYXJzZVR1cGxlKGFyZ3MsICJPfE8mTyY6aW5kZXgiLCAmdiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX1B5RXZhbF9TbGljZUluZGV4LCAmc3RhcnQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9QeUV2YWxfU2xpY2VJbmRleCwgJnN0b3ApKQorICAgICAgICByZXR1cm4gTlVMTDsKKyAgICBpZiAoc3RhcnQgPCAwKSB7CisgICAgICAgIHN0YXJ0ICs9IFB5X1NJWkUoc2VsZik7CisgICAgICAgIGlmIChzdGFydCA8IDApCisgICAgICAgICAgICBzdGFydCA9IDA7CisgICAgfQorICAgIGlmIChzdG9wIDwgMCkgeworICAgICAgICBzdG9wICs9IFB5X1NJWkUoc2VsZik7CisgICAgICAgIGlmIChzdG9wIDwgMCkKKyAgICAgICAgICAgIHN0b3AgPSAwOworICAgIH0KKyAgICBmb3IgKGkgPSBzdGFydDsgaSA8IHN0b3AgJiYgaSA8IFB5X1NJWkUoc2VsZik7IGkrKykgeworICAgICAgICBpbnQgY21wID0gUHlPYmplY3RfUmljaENvbXBhcmVCb29sKHNlbGYtPm9iX2l0ZW1baV0sIHYsIFB5X0VRKTsKKyAgICAgICAgaWYgKGNtcCA+IDApCisgICAgICAgICAgICByZXR1cm4gUHlJbnRfRnJvbVNzaXplX3QoaSk7CisgICAgICAgIGVsc2UgaWYgKGNtcCA8IDApCisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgaWYgKGVycl9mb3JtYXQgPT0gTlVMTCkgeworICAgICAgICBlcnJfZm9ybWF0ID0gUHlTdHJpbmdfRnJvbVN0cmluZygiJXIgaXMgbm90IGluIGxpc3QiKTsKKyAgICAgICAgaWYgKGVycl9mb3JtYXQgPT0gTlVMTCkKKyAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICBmb3JtYXRfdHVwbGUgPSBQeVR1cGxlX1BhY2soMSwgdik7CisgICAgaWYgKGZvcm1hdF90dXBsZSA9PSBOVUxMKQorICAgICAgICByZXR1cm4gTlVMTDsKKyAgICBlcnJfc3RyaW5nID0gUHlTdHJpbmdfRm9ybWF0KGVycl9mb3JtYXQsIGZvcm1hdF90dXBsZSk7CisgICAgUHlfREVDUkVGKGZvcm1hdF90dXBsZSk7CisgICAgaWYgKGVycl9zdHJpbmcgPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgUHlFcnJfU2V0T2JqZWN0KFB5RXhjX1ZhbHVlRXJyb3IsIGVycl9zdHJpbmcpOworICAgIFB5X0RFQ1JFRihlcnJfc3RyaW5nKTsKKyAgICByZXR1cm4gTlVMTDsKK30KKworc3RhdGljIFB5T2JqZWN0ICoKK2xpc3Rjb3VudChQeUxpc3RPYmplY3QgKnNlbGYsIFB5T2JqZWN0ICp2KQoreworICAgIFB5X3NzaXplX3QgY291bnQgPSAwOworICAgIFB5X3NzaXplX3QgaTsKKworICAgIGZvciAoaSA9IDA7IGkgPCBQeV9TSVpFKHNlbGYpOyBpKyspIHsKKyAgICAgICAgaW50IGNtcCA9IFB5T2JqZWN0X1JpY2hDb21wYXJlQm9vbChzZWxmLT5vYl9pdGVtW2ldLCB2LCBQeV9FUSk7CisgICAgICAgIGlmIChjbXAgPiAwKQorICAgICAgICAgICAgY291bnQrKzsKKyAgICAgICAgZWxzZSBpZiAoY21wIDwgMCkKKyAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICByZXR1cm4gUHlJbnRfRnJvbVNzaXplX3QoY291bnQpOworfQorCitzdGF0aWMgUHlPYmplY3QgKgorbGlzdHJlbW92ZShQeUxpc3RPYmplY3QgKnNlbGYsIFB5T2JqZWN0ICp2KQoreworICAgIFB5X3NzaXplX3QgaTsKKworICAgIGZvciAoaSA9IDA7IGkgPCBQeV9TSVpFKHNlbGYpOyBpKyspIHsKKyAgICAgICAgaW50IGNtcCA9IFB5T2JqZWN0X1JpY2hDb21wYXJlQm9vbChzZWxmLT5vYl9pdGVtW2ldLCB2LCBQeV9FUSk7CisgICAgICAgIGlmIChjbXAgPiAwKSB7CisgICAgICAgICAgICBpZiAobGlzdF9hc3Nfc2xpY2Uoc2VsZiwgaSwgaSsxLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChQeU9iamVjdCAqKU5VTEwpID09IDApCisgICAgICAgICAgICAgICAgUHlfUkVUVVJOX05PTkU7CisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgfQorICAgICAgICBlbHNlIGlmIChjbXAgPCAwKQorICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19WYWx1ZUVycm9yLCAibGlzdC5yZW1vdmUoeCk6IHggbm90IGluIGxpc3QiKTsKKyAgICByZXR1cm4gTlVMTDsKK30KKworc3RhdGljIGludAorbGlzdF90cmF2ZXJzZShQeUxpc3RPYmplY3QgKm8sIHZpc2l0cHJvYyB2aXNpdCwgdm9pZCAqYXJnKQoreworICAgIFB5X3NzaXplX3QgaTsKKworICAgIGZvciAoaSA9IFB5X1NJWkUobyk7IC0taSA+PSAwOyApCisgICAgICAgIFB5X1ZJU0lUKG8tPm9iX2l0ZW1baV0pOworICAgIHJldHVybiAwOworfQorCitzdGF0aWMgUHlPYmplY3QgKgorbGlzdF9yaWNoY29tcGFyZShQeU9iamVjdCAqdiwgUHlPYmplY3QgKncsIGludCBvcCkKK3sKKyAgICBQeUxpc3RPYmplY3QgKnZsLCAqd2w7CisgICAgUHlfc3NpemVfdCBpOworCisgICAgaWYgKCFQeUxpc3RfQ2hlY2sodikgfHwgIVB5TGlzdF9DaGVjayh3KSkgeworICAgICAgICBQeV9JTkNSRUYoUHlfTm90SW1wbGVtZW50ZWQpOworICAgICAgICByZXR1cm4gUHlfTm90SW1wbGVtZW50ZWQ7CisgICAgfQorCisgICAgdmwgPSAoUHlMaXN0T2JqZWN0ICopdjsKKyAgICB3bCA9IChQeUxpc3RPYmplY3QgKil3OworCisgICAgaWYgKFB5X1NJWkUodmwpICE9IFB5X1NJWkUod2wpICYmIChvcCA9PSBQeV9FUSB8fCBvcCA9PSBQeV9ORSkpIHsKKyAgICAgICAgLyogU2hvcnRjdXQ6IGlmIHRoZSBsZW5ndGhzIGRpZmZlciwgdGhlIGxpc3RzIGRpZmZlciAqLworICAgICAgICBQeU9iamVjdCAqcmVzOworICAgICAgICBpZiAob3AgPT0gUHlfRVEpCisgICAgICAgICAgICByZXMgPSBQeV9GYWxzZTsKKyAgICAgICAgZWxzZQorICAgICAgICAgICAgcmVzID0gUHlfVHJ1ZTsKKyAgICAgICAgUHlfSU5DUkVGKHJlcyk7CisgICAgICAgIHJldHVybiByZXM7CisgICAgfQorCisgICAgLyogU2VhcmNoIGZvciB0aGUgZmlyc3QgaW5kZXggd2hlcmUgaXRlbXMgYXJlIGRpZmZlcmVudCAqLworICAgIGZvciAoaSA9IDA7IGkgPCBQeV9TSVpFKHZsKSAmJiBpIDwgUHlfU0laRSh3bCk7IGkrKykgeworICAgICAgICBpbnQgayA9IFB5T2JqZWN0X1JpY2hDb21wYXJlQm9vbCh2bC0+b2JfaXRlbVtpXSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2wtPm9iX2l0ZW1baV0sIFB5X0VRKTsKKyAgICAgICAgaWYgKGsgPCAwKQorICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgICAgIGlmICghaykKKyAgICAgICAgICAgIGJyZWFrOworICAgIH0KKworICAgIGlmIChpID49IFB5X1NJWkUodmwpIHx8IGkgPj0gUHlfU0laRSh3bCkpIHsKKyAgICAgICAgLyogTm8gbW9yZSBpdGVtcyB0byBjb21wYXJlIC0tIGNvbXBhcmUgc2l6ZXMgKi8KKyAgICAgICAgUHlfc3NpemVfdCB2cyA9IFB5X1NJWkUodmwpOworICAgICAgICBQeV9zc2l6ZV90IHdzID0gUHlfU0laRSh3bCk7CisgICAgICAgIGludCBjbXA7CisgICAgICAgIFB5T2JqZWN0ICpyZXM7CisgICAgICAgIHN3aXRjaCAob3ApIHsKKyAgICAgICAgY2FzZSBQeV9MVDogY21wID0gdnMgPCAgd3M7IGJyZWFrOworICAgICAgICBjYXNlIFB5X0xFOiBjbXAgPSB2cyA8PSB3czsgYnJlYWs7CisgICAgICAgIGNhc2UgUHlfRVE6IGNtcCA9IHZzID09IHdzOyBicmVhazsKKyAgICAgICAgY2FzZSBQeV9ORTogY21wID0gdnMgIT0gd3M7IGJyZWFrOworICAgICAgICBjYXNlIFB5X0dUOiBjbXAgPSB2cyA+ICB3czsgYnJlYWs7CisgICAgICAgIGNhc2UgUHlfR0U6IGNtcCA9IHZzID49IHdzOyBicmVhazsKKyAgICAgICAgZGVmYXVsdDogcmV0dXJuIE5VTEw7IC8qIGNhbm5vdCBoYXBwZW4gKi8KKyAgICAgICAgfQorICAgICAgICBpZiAoY21wKQorICAgICAgICAgICAgcmVzID0gUHlfVHJ1ZTsKKyAgICAgICAgZWxzZQorICAgICAgICAgICAgcmVzID0gUHlfRmFsc2U7CisgICAgICAgIFB5X0lOQ1JFRihyZXMpOworICAgICAgICByZXR1cm4gcmVzOworICAgIH0KKworICAgIC8qIFdlIGhhdmUgYW4gaXRlbSB0aGF0IGRpZmZlcnMgLS0gc2hvcnRjdXRzIGZvciBFUS9ORSAqLworICAgIGlmIChvcCA9PSBQeV9FUSkgeworICAgICAgICBQeV9JTkNSRUYoUHlfRmFsc2UpOworICAgICAgICByZXR1cm4gUHlfRmFsc2U7CisgICAgfQorICAgIGlmIChvcCA9PSBQeV9ORSkgeworICAgICAgICBQeV9JTkNSRUYoUHlfVHJ1ZSk7CisgICAgICAgIHJldHVybiBQeV9UcnVlOworICAgIH0KKworICAgIC8qIENvbXBhcmUgdGhlIGZpbmFsIGl0ZW0gYWdhaW4gdXNpbmcgdGhlIHByb3BlciBvcGVyYXRvciAqLworICAgIHJldHVybiBQeU9iamVjdF9SaWNoQ29tcGFyZSh2bC0+b2JfaXRlbVtpXSwgd2wtPm9iX2l0ZW1baV0sIG9wKTsKK30KKworc3RhdGljIGludAorbGlzdF9pbml0KFB5TGlzdE9iamVjdCAqc2VsZiwgUHlPYmplY3QgKmFyZ3MsIFB5T2JqZWN0ICprdykKK3sKKyAgICBQeU9iamVjdCAqYXJnID0gTlVMTDsKKyAgICBzdGF0aWMgY2hhciAqa3dsaXN0W10gPSB7InNlcXVlbmNlIiwgMH07CisKKyAgICBpZiAoIVB5QXJnX1BhcnNlVHVwbGVBbmRLZXl3b3JkcyhhcmdzLCBrdywgInxPOmxpc3QiLCBrd2xpc3QsICZhcmcpKQorICAgICAgICByZXR1cm4gLTE7CisKKyAgICAvKiBWZXJpZnkgbGlzdCBpbnZhcmlhbnRzIGVzdGFibGlzaGVkIGJ5IFB5VHlwZV9HZW5lcmljQWxsb2MoKSAqLworICAgIGFzc2VydCgwIDw9IFB5X1NJWkUoc2VsZikpOworICAgIGFzc2VydChQeV9TSVpFKHNlbGYpIDw9IHNlbGYtPmFsbG9jYXRlZCB8fCBzZWxmLT5hbGxvY2F0ZWQgPT0gLTEpOworICAgIGFzc2VydChzZWxmLT5vYl9pdGVtICE9IE5VTEwgfHwKKyAgICAgICAgICAgc2VsZi0+YWxsb2NhdGVkID09IDAgfHwgc2VsZi0+YWxsb2NhdGVkID09IC0xKTsKKworICAgIC8qIEVtcHR5IHByZXZpb3VzIGNvbnRlbnRzICovCisgICAgaWYgKHNlbGYtPm9iX2l0ZW0gIT0gTlVMTCkgeworICAgICAgICAodm9pZClsaXN0X2NsZWFyKHNlbGYpOworICAgIH0KKyAgICBpZiAoYXJnICE9IE5VTEwpIHsKKyAgICAgICAgUHlPYmplY3QgKnJ2ID0gbGlzdGV4dGVuZChzZWxmLCBhcmcpOworICAgICAgICBpZiAocnYgPT0gTlVMTCkKKyAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgUHlfREVDUkVGKHJ2KTsKKyAgICB9CisgICAgcmV0dXJuIDA7Cit9CisKK3N0YXRpYyBQeU9iamVjdCAqCitsaXN0X3NpemVvZihQeUxpc3RPYmplY3QgKnNlbGYpCit7CisgICAgUHlfc3NpemVfdCByZXM7CisKKyAgICByZXMgPSBzaXplb2YoUHlMaXN0T2JqZWN0KSArIHNlbGYtPmFsbG9jYXRlZCAqIHNpemVvZih2b2lkKik7CisgICAgcmV0dXJuIFB5SW50X0Zyb21Tc2l6ZV90KHJlcyk7Cit9CisKK3N0YXRpYyBQeU9iamVjdCAqbGlzdF9pdGVyKFB5T2JqZWN0ICpzZXEpOworc3RhdGljIFB5T2JqZWN0ICpsaXN0X3JldmVyc2VkKFB5TGlzdE9iamVjdCogc2VxLCBQeU9iamVjdCogdW51c2VkKTsKKworUHlEb2NfU1RSVkFSKGdldGl0ZW1fZG9jLAorInguX19nZXRpdGVtX18oeSkgPD09PiB4W3ldIik7CitQeURvY19TVFJWQVIocmV2ZXJzZWRfZG9jLAorIkwuX19yZXZlcnNlZF9fKCkgLS0gcmV0dXJuIGEgcmV2ZXJzZSBpdGVyYXRvciBvdmVyIHRoZSBsaXN0Iik7CitQeURvY19TVFJWQVIoc2l6ZW9mX2RvYywKKyJMLl9fc2l6ZW9mX18oKSAtLSBzaXplIG9mIEwgaW4gbWVtb3J5LCBpbiBieXRlcyIpOworUHlEb2NfU1RSVkFSKGFwcGVuZF9kb2MsCisiTC5hcHBlbmQob2JqZWN0KSAtLSBhcHBlbmQgb2JqZWN0IHRvIGVuZCIpOworUHlEb2NfU1RSVkFSKGV4dGVuZF9kb2MsCisiTC5leHRlbmQoaXRlcmFibGUpIC0tIGV4dGVuZCBsaXN0IGJ5IGFwcGVuZGluZyBlbGVtZW50cyBmcm9tIHRoZSBpdGVyYWJsZSIpOworUHlEb2NfU1RSVkFSKGluc2VydF9kb2MsCisiTC5pbnNlcnQoaW5kZXgsIG9iamVjdCkgLS0gaW5zZXJ0IG9iamVjdCBiZWZvcmUgaW5kZXgiKTsKK1B5RG9jX1NUUlZBUihwb3BfZG9jLAorIkwucG9wKFtpbmRleF0pIC0+IGl0ZW0gLS0gcmVtb3ZlIGFuZCByZXR1cm4gaXRlbSBhdCBpbmRleCAoZGVmYXVsdCBsYXN0KS5cbiIKKyJSYWlzZXMgSW5kZXhFcnJvciBpZiBsaXN0IGlzIGVtcHR5IG9yIGluZGV4IGlzIG91dCBvZiByYW5nZS4iKTsKK1B5RG9jX1NUUlZBUihyZW1vdmVfZG9jLAorIkwucmVtb3ZlKHZhbHVlKSAtLSByZW1vdmUgZmlyc3Qgb2NjdXJyZW5jZSBvZiB2YWx1ZS5cbiIKKyJSYWlzZXMgVmFsdWVFcnJvciBpZiB0aGUgdmFsdWUgaXMgbm90IHByZXNlbnQuIik7CitQeURvY19TVFJWQVIoaW5kZXhfZG9jLAorIkwuaW5kZXgodmFsdWUsIFtzdGFydCwgW3N0b3BdXSkgLT4gaW50ZWdlciAtLSByZXR1cm4gZmlyc3QgaW5kZXggb2YgdmFsdWUuXG4iCisiUmFpc2VzIFZhbHVlRXJyb3IgaWYgdGhlIHZhbHVlIGlzIG5vdCBwcmVzZW50LiIpOworUHlEb2NfU1RSVkFSKGNvdW50X2RvYywKKyJMLmNvdW50KHZhbHVlKSAtPiBpbnRlZ2VyIC0tIHJldHVybiBudW1iZXIgb2Ygb2NjdXJyZW5jZXMgb2YgdmFsdWUiKTsKK1B5RG9jX1NUUlZBUihyZXZlcnNlX2RvYywKKyJMLnJldmVyc2UoKSAtLSByZXZlcnNlICpJTiBQTEFDRSoiKTsKK1B5RG9jX1NUUlZBUihzb3J0X2RvYywKKyJMLnNvcnQoY21wPU5vbmUsIGtleT1Ob25lLCByZXZlcnNlPUZhbHNlKSAtLSBzdGFibGUgc29ydCAqSU4gUExBQ0UqO1xuXAorY21wKHgsIHkpIC0+IC0xLCAwLCAxIik7CisKK3N0YXRpYyBQeU9iamVjdCAqbGlzdF9zdWJzY3JpcHQoUHlMaXN0T2JqZWN0KiwgUHlPYmplY3QqKTsKKworc3RhdGljIFB5TWV0aG9kRGVmIGxpc3RfbWV0aG9kc1tdID0geworICAgIHsiX19nZXRpdGVtX18iLCAoUHlDRnVuY3Rpb24pbGlzdF9zdWJzY3JpcHQsIE1FVEhfT3xNRVRIX0NPRVhJU1QsIGdldGl0ZW1fZG9jfSwKKyAgICB7Il9fcmV2ZXJzZWRfXyIsKFB5Q0Z1bmN0aW9uKWxpc3RfcmV2ZXJzZWQsIE1FVEhfTk9BUkdTLCByZXZlcnNlZF9kb2N9LAorICAgIHsiX19zaXplb2ZfXyIsICAoUHlDRnVuY3Rpb24pbGlzdF9zaXplb2YsIE1FVEhfTk9BUkdTLCBzaXplb2ZfZG9jfSwKKyAgICB7ImFwcGVuZCIsICAgICAgICAgIChQeUNGdW5jdGlvbilsaXN0YXBwZW5kLCAgTUVUSF9PLCBhcHBlbmRfZG9jfSwKKyAgICB7Imluc2VydCIsICAgICAgICAgIChQeUNGdW5jdGlvbilsaXN0aW5zZXJ0LCAgTUVUSF9WQVJBUkdTLCBpbnNlcnRfZG9jfSwKKyAgICB7ImV4dGVuZCIsICAgICAgKFB5Q0Z1bmN0aW9uKWxpc3RleHRlbmQsICBNRVRIX08sIGV4dGVuZF9kb2N9LAorICAgIHsicG9wIiwgICAgICAgICAgICAgKFB5Q0Z1bmN0aW9uKWxpc3Rwb3AsICAgICBNRVRIX1ZBUkFSR1MsIHBvcF9kb2N9LAorICAgIHsicmVtb3ZlIiwgICAgICAgICAgKFB5Q0Z1bmN0aW9uKWxpc3RyZW1vdmUsICBNRVRIX08sIHJlbW92ZV9kb2N9LAorICAgIHsiaW5kZXgiLCAgICAgICAgICAgKFB5Q0Z1bmN0aW9uKWxpc3RpbmRleCwgICBNRVRIX1ZBUkFSR1MsIGluZGV4X2RvY30sCisgICAgeyJjb3VudCIsICAgICAgICAgICAoUHlDRnVuY3Rpb24pbGlzdGNvdW50LCAgIE1FVEhfTywgY291bnRfZG9jfSwKKyAgICB7InJldmVyc2UiLCAgICAgICAgIChQeUNGdW5jdGlvbilsaXN0cmV2ZXJzZSwgTUVUSF9OT0FSR1MsIHJldmVyc2VfZG9jfSwKKyAgICB7InNvcnQiLCAgICAgICAgICAgIChQeUNGdW5jdGlvbilsaXN0c29ydCwgICAgTUVUSF9WQVJBUkdTIHwgTUVUSF9LRVlXT1JEUywgc29ydF9kb2N9LAorICAgIHtOVUxMLCAgICAgICAgICAgICAgTlVMTH0gICAgICAgICAgIC8qIHNlbnRpbmVsICovCit9OworCitzdGF0aWMgUHlTZXF1ZW5jZU1ldGhvZHMgbGlzdF9hc19zZXF1ZW5jZSA9IHsKKyAgICAobGVuZnVuYylsaXN0X2xlbmd0aCwgICAgICAgICAgICAgICAgICAgICAgIC8qIHNxX2xlbmd0aCAqLworICAgIChiaW5hcnlmdW5jKWxpc3RfY29uY2F0LCAgICAgICAgICAgICAgICAgICAgLyogc3FfY29uY2F0ICovCisgICAgKHNzaXplYXJnZnVuYylsaXN0X3JlcGVhdCwgICAgICAgICAgICAgICAgICAvKiBzcV9yZXBlYXQgKi8KKyAgICAoc3NpemVhcmdmdW5jKWxpc3RfaXRlbSwgICAgICAgICAgICAgICAgICAgIC8qIHNxX2l0ZW0gKi8KKyAgICAoc3NpemVzc2l6ZWFyZ2Z1bmMpbGlzdF9zbGljZSwgICAgICAgICAgICAgIC8qIHNxX3NsaWNlICovCisgICAgKHNzaXplb2JqYXJncHJvYylsaXN0X2Fzc19pdGVtLCAgICAgICAgICAgICAvKiBzcV9hc3NfaXRlbSAqLworICAgIChzc2l6ZXNzaXplb2JqYXJncHJvYylsaXN0X2Fzc19zbGljZSwgICAgICAgLyogc3FfYXNzX3NsaWNlICovCisgICAgKG9iam9ianByb2MpbGlzdF9jb250YWlucywgICAgICAgICAgICAgICAgICAvKiBzcV9jb250YWlucyAqLworICAgIChiaW5hcnlmdW5jKWxpc3RfaW5wbGFjZV9jb25jYXQsICAgICAgICAgICAgLyogc3FfaW5wbGFjZV9jb25jYXQgKi8KKyAgICAoc3NpemVhcmdmdW5jKWxpc3RfaW5wbGFjZV9yZXBlYXQsICAgICAgICAgIC8qIHNxX2lucGxhY2VfcmVwZWF0ICovCit9OworCitQeURvY19TVFJWQVIobGlzdF9kb2MsCisibGlzdCgpIC0+IG5ldyBlbXB0eSBsaXN0XG4iCisibGlzdChpdGVyYWJsZSkgLT4gbmV3IGxpc3QgaW5pdGlhbGl6ZWQgZnJvbSBpdGVyYWJsZSdzIGl0ZW1zIik7CisKKworc3RhdGljIFB5T2JqZWN0ICoKK2xpc3Rfc3Vic2NyaXB0KFB5TGlzdE9iamVjdCogc2VsZiwgUHlPYmplY3QqIGl0ZW0pCit7CisgICAgaWYgKFB5SW5kZXhfQ2hlY2soaXRlbSkpIHsKKyAgICAgICAgUHlfc3NpemVfdCBpOworICAgICAgICBpID0gUHlOdW1iZXJfQXNTc2l6ZV90KGl0ZW0sIFB5RXhjX0luZGV4RXJyb3IpOworICAgICAgICBpZiAoaSA9PSAtMSAmJiBQeUVycl9PY2N1cnJlZCgpKQorICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgICAgIGlmIChpIDwgMCkKKyAgICAgICAgICAgIGkgKz0gUHlMaXN0X0dFVF9TSVpFKHNlbGYpOworICAgICAgICByZXR1cm4gbGlzdF9pdGVtKHNlbGYsIGkpOworICAgIH0KKyAgICBlbHNlIGlmIChQeVNsaWNlX0NoZWNrKGl0ZW0pKSB7CisgICAgICAgIFB5X3NzaXplX3Qgc3RhcnQsIHN0b3AsIHN0ZXAsIHNsaWNlbGVuZ3RoLCBjdXIsIGk7CisgICAgICAgIFB5T2JqZWN0KiByZXN1bHQ7CisgICAgICAgIFB5T2JqZWN0KiBpdDsKKyAgICAgICAgUHlPYmplY3QgKipzcmMsICoqZGVzdDsKKworICAgICAgICBpZiAoUHlTbGljZV9HZXRJbmRpY2VzRXgoKFB5U2xpY2VPYmplY3QqKWl0ZW0sIFB5X1NJWkUoc2VsZiksCisgICAgICAgICAgICAgICAgICAgICAgICAgJnN0YXJ0LCAmc3RvcCwgJnN0ZXAsICZzbGljZWxlbmd0aCkgPCAwKSB7CisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChzbGljZWxlbmd0aCA8PSAwKSB7CisgICAgICAgICAgICByZXR1cm4gUHlMaXN0X05ldygwKTsKKyAgICAgICAgfQorICAgICAgICBlbHNlIGlmIChzdGVwID09IDEpIHsKKyAgICAgICAgICAgIHJldHVybiBsaXN0X3NsaWNlKHNlbGYsIHN0YXJ0LCBzdG9wKTsKKyAgICAgICAgfQorICAgICAgICBlbHNlIHsKKyAgICAgICAgICAgIHJlc3VsdCA9IFB5TGlzdF9OZXcoc2xpY2VsZW5ndGgpOworICAgICAgICAgICAgaWYgKCFyZXN1bHQpIHJldHVybiBOVUxMOworCisgICAgICAgICAgICBzcmMgPSBzZWxmLT5vYl9pdGVtOworICAgICAgICAgICAgZGVzdCA9ICgoUHlMaXN0T2JqZWN0ICopcmVzdWx0KS0+b2JfaXRlbTsKKyAgICAgICAgICAgIGZvciAoY3VyID0gc3RhcnQsIGkgPSAwOyBpIDwgc2xpY2VsZW5ndGg7CisgICAgICAgICAgICAgICAgIGN1ciArPSBzdGVwLCBpKyspIHsKKyAgICAgICAgICAgICAgICBpdCA9IHNyY1tjdXJdOworICAgICAgICAgICAgICAgIFB5X0lOQ1JFRihpdCk7CisgICAgICAgICAgICAgICAgZGVzdFtpXSA9IGl0OworICAgICAgICAgICAgfQorCisgICAgICAgICAgICByZXR1cm4gcmVzdWx0OworICAgICAgICB9CisgICAgfQorICAgIGVsc2UgeworICAgICAgICBQeUVycl9Gb3JtYXQoUHlFeGNfVHlwZUVycm9yLAorICAgICAgICAgICAgICAgICAgICAgImxpc3QgaW5kaWNlcyBtdXN0IGJlIGludGVnZXJzLCBub3QgJS4yMDBzIiwKKyAgICAgICAgICAgICAgICAgICAgIGl0ZW0tPm9iX3R5cGUtPnRwX25hbWUpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9Cit9CisKK3N0YXRpYyBpbnQKK2xpc3RfYXNzX3N1YnNjcmlwdChQeUxpc3RPYmplY3QqIHNlbGYsIFB5T2JqZWN0KiBpdGVtLCBQeU9iamVjdCogdmFsdWUpCit7CisgICAgaWYgKFB5SW5kZXhfQ2hlY2soaXRlbSkpIHsKKyAgICAgICAgUHlfc3NpemVfdCBpID0gUHlOdW1iZXJfQXNTc2l6ZV90KGl0ZW0sIFB5RXhjX0luZGV4RXJyb3IpOworICAgICAgICBpZiAoaSA9PSAtMSAmJiBQeUVycl9PY2N1cnJlZCgpKQorICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICBpZiAoaSA8IDApCisgICAgICAgICAgICBpICs9IFB5TGlzdF9HRVRfU0laRShzZWxmKTsKKyAgICAgICAgcmV0dXJuIGxpc3RfYXNzX2l0ZW0oc2VsZiwgaSwgdmFsdWUpOworICAgIH0KKyAgICBlbHNlIGlmIChQeVNsaWNlX0NoZWNrKGl0ZW0pKSB7CisgICAgICAgIFB5X3NzaXplX3Qgc3RhcnQsIHN0b3AsIHN0ZXAsIHNsaWNlbGVuZ3RoOworCisgICAgICAgIGlmIChQeVNsaWNlX0dldEluZGljZXNFeCgoUHlTbGljZU9iamVjdCopaXRlbSwgUHlfU0laRShzZWxmKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAmc3RhcnQsICZzdG9wLCAmc3RlcCwgJnNsaWNlbGVuZ3RoKSA8IDApIHsKKyAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChzdGVwID09IDEpCisgICAgICAgICAgICByZXR1cm4gbGlzdF9hc3Nfc2xpY2Uoc2VsZiwgc3RhcnQsIHN0b3AsIHZhbHVlKTsKKworICAgICAgICAvKiBNYWtlIHN1cmUgc1s1OjJdID0gWy4uXSBpbnNlcnRzIGF0IHRoZSByaWdodCBwbGFjZToKKyAgICAgICAgICAgYmVmb3JlIDUsIG5vdCBiZWZvcmUgMi4gKi8KKyAgICAgICAgaWYgKChzdGVwIDwgMCAmJiBzdGFydCA8IHN0b3ApIHx8CisgICAgICAgICAgICAoc3RlcCA+IDAgJiYgc3RhcnQgPiBzdG9wKSkKKyAgICAgICAgICAgIHN0b3AgPSBzdGFydDsKKworICAgICAgICBpZiAodmFsdWUgPT0gTlVMTCkgeworICAgICAgICAgICAgLyogZGVsZXRlIHNsaWNlICovCisgICAgICAgICAgICBQeU9iamVjdCAqKmdhcmJhZ2U7CisgICAgICAgICAgICBzaXplX3QgY3VyOworICAgICAgICAgICAgUHlfc3NpemVfdCBpOworCisgICAgICAgICAgICBpZiAoc2xpY2VsZW5ndGggPD0gMCkKKyAgICAgICAgICAgICAgICByZXR1cm4gMDsKKworICAgICAgICAgICAgaWYgKHN0ZXAgPCAwKSB7CisgICAgICAgICAgICAgICAgc3RvcCA9IHN0YXJ0ICsgMTsKKyAgICAgICAgICAgICAgICBzdGFydCA9IHN0b3AgKyBzdGVwKihzbGljZWxlbmd0aCAtIDEpIC0gMTsKKyAgICAgICAgICAgICAgICBzdGVwID0gLXN0ZXA7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGFzc2VydCgoc2l6ZV90KXNsaWNlbGVuZ3RoIDw9CisgICAgICAgICAgICAgICAgICAgUFlfU0laRV9NQVggLyBzaXplb2YoUHlPYmplY3QqKSk7CisKKyAgICAgICAgICAgIGdhcmJhZ2UgPSAoUHlPYmplY3QqKikKKyAgICAgICAgICAgICAgICBQeU1lbV9NQUxMT0Moc2xpY2VsZW5ndGgqc2l6ZW9mKFB5T2JqZWN0KikpOworICAgICAgICAgICAgaWYgKCFnYXJiYWdlKSB7CisgICAgICAgICAgICAgICAgUHlFcnJfTm9NZW1vcnkoKTsKKyAgICAgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIC8qIGRyYXdpbmcgcGljdHVyZXMgbWlnaHQgaGVscCB1bmRlcnN0YW5kIHRoZXNlIGZvcgorICAgICAgICAgICAgICAgbG9vcHMuIEJhc2ljYWxseSwgd2UgbWVtbW92ZSB0aGUgcGFydHMgb2YgdGhlCisgICAgICAgICAgICAgICBsaXN0IHRoYXQgYXJlICpub3QqIHBhcnQgb2YgdGhlIHNsaWNlOiBzdGVwLTEKKyAgICAgICAgICAgICAgIGl0ZW1zIGZvciBlYWNoIGl0ZW0gdGhhdCBpcyBwYXJ0IG9mIHRoZSBzbGljZSwKKyAgICAgICAgICAgICAgIGFuZCB0aGVuIHRhaWwgZW5kIG9mIHRoZSBsaXN0IHRoYXQgd2FzIG5vdAorICAgICAgICAgICAgICAgY292ZXJlZCBieSB0aGUgc2xpY2UgKi8KKyAgICAgICAgICAgIGZvciAoY3VyID0gc3RhcnQsIGkgPSAwOworICAgICAgICAgICAgICAgICBjdXIgPCAoc2l6ZV90KXN0b3A7CisgICAgICAgICAgICAgICAgIGN1ciArPSBzdGVwLCBpKyspIHsKKyAgICAgICAgICAgICAgICBQeV9zc2l6ZV90IGxpbSA9IHN0ZXAgLSAxOworCisgICAgICAgICAgICAgICAgZ2FyYmFnZVtpXSA9IFB5TGlzdF9HRVRfSVRFTShzZWxmLCBjdXIpOworCisgICAgICAgICAgICAgICAgaWYgKGN1ciArIHN0ZXAgPj0gKHNpemVfdClQeV9TSVpFKHNlbGYpKSB7CisgICAgICAgICAgICAgICAgICAgIGxpbSA9IFB5X1NJWkUoc2VsZikgLSBjdXIgLSAxOworICAgICAgICAgICAgICAgIH0KKworICAgICAgICAgICAgICAgIG1lbW1vdmUoc2VsZi0+b2JfaXRlbSArIGN1ciAtIGksCisgICAgICAgICAgICAgICAgICAgIHNlbGYtPm9iX2l0ZW0gKyBjdXIgKyAxLAorICAgICAgICAgICAgICAgICAgICBsaW0gKiBzaXplb2YoUHlPYmplY3QgKikpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgY3VyID0gc3RhcnQgKyBzbGljZWxlbmd0aCpzdGVwOworICAgICAgICAgICAgaWYgKGN1ciA8IChzaXplX3QpUHlfU0laRShzZWxmKSkgeworICAgICAgICAgICAgICAgIG1lbW1vdmUoc2VsZi0+b2JfaXRlbSArIGN1ciAtIHNsaWNlbGVuZ3RoLAorICAgICAgICAgICAgICAgICAgICBzZWxmLT5vYl9pdGVtICsgY3VyLAorICAgICAgICAgICAgICAgICAgICAoUHlfU0laRShzZWxmKSAtIGN1cikgKgorICAgICAgICAgICAgICAgICAgICAgc2l6ZW9mKFB5T2JqZWN0ICopKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgUHlfU0laRShzZWxmKSAtPSBzbGljZWxlbmd0aDsKKyAgICAgICAgICAgIGxpc3RfcmVzaXplKHNlbGYsIFB5X1NJWkUoc2VsZikpOworCisgICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgc2xpY2VsZW5ndGg7IGkrKykgeworICAgICAgICAgICAgICAgIFB5X0RFQ1JFRihnYXJiYWdlW2ldKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIFB5TWVtX0ZSRUUoZ2FyYmFnZSk7CisKKyAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICB9CisgICAgICAgIGVsc2UgeworICAgICAgICAgICAgLyogYXNzaWduIHNsaWNlICovCisgICAgICAgICAgICBQeU9iamVjdCAqaW5zLCAqc2VxOworICAgICAgICAgICAgUHlPYmplY3QgKipnYXJiYWdlLCAqKnNlcWl0ZW1zLCAqKnNlbGZpdGVtczsKKyAgICAgICAgICAgIFB5X3NzaXplX3QgY3VyLCBpOworCisgICAgICAgICAgICAvKiBwcm90ZWN0IGFnYWluc3QgYVs6Oi0xXSA9IGEgKi8KKyAgICAgICAgICAgIGlmIChzZWxmID09IChQeUxpc3RPYmplY3QqKXZhbHVlKSB7CisgICAgICAgICAgICAgICAgc2VxID0gbGlzdF9zbGljZSgoUHlMaXN0T2JqZWN0Kil2YWx1ZSwgMCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHlMaXN0X0dFVF9TSVpFKHZhbHVlKSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBlbHNlIHsKKyAgICAgICAgICAgICAgICBzZXEgPSBQeVNlcXVlbmNlX0Zhc3QodmFsdWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJtdXN0IGFzc2lnbiBpdGVyYWJsZSAiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0byBleHRlbmRlZCBzbGljZSIpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKCFzZXEpCisgICAgICAgICAgICAgICAgcmV0dXJuIC0xOworCisgICAgICAgICAgICBpZiAoUHlTZXF1ZW5jZV9GYXN0X0dFVF9TSVpFKHNlcSkgIT0gc2xpY2VsZW5ndGgpIHsKKyAgICAgICAgICAgICAgICBQeUVycl9Gb3JtYXQoUHlFeGNfVmFsdWVFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgImF0dGVtcHQgdG8gYXNzaWduIHNlcXVlbmNlIG9mICIKKyAgICAgICAgICAgICAgICAgICAgInNpemUgJXpkIHRvIGV4dGVuZGVkIHNsaWNlIG9mICIKKyAgICAgICAgICAgICAgICAgICAgInNpemUgJXpkIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICBQeVNlcXVlbmNlX0Zhc3RfR0VUX1NJWkUoc2VxKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICBzbGljZWxlbmd0aCk7CisgICAgICAgICAgICAgICAgUHlfREVDUkVGKHNlcSk7CisgICAgICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBpZiAoIXNsaWNlbGVuZ3RoKSB7CisgICAgICAgICAgICAgICAgUHlfREVDUkVGKHNlcSk7CisgICAgICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGdhcmJhZ2UgPSAoUHlPYmplY3QqKikKKyAgICAgICAgICAgICAgICBQeU1lbV9NQUxMT0Moc2xpY2VsZW5ndGgqc2l6ZW9mKFB5T2JqZWN0KikpOworICAgICAgICAgICAgaWYgKCFnYXJiYWdlKSB7CisgICAgICAgICAgICAgICAgUHlfREVDUkVGKHNlcSk7CisgICAgICAgICAgICAgICAgUHlFcnJfTm9NZW1vcnkoKTsKKyAgICAgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIHNlbGZpdGVtcyA9IHNlbGYtPm9iX2l0ZW07CisgICAgICAgICAgICBzZXFpdGVtcyA9IFB5U2VxdWVuY2VfRmFzdF9JVEVNUyhzZXEpOworICAgICAgICAgICAgZm9yIChjdXIgPSBzdGFydCwgaSA9IDA7IGkgPCBzbGljZWxlbmd0aDsKKyAgICAgICAgICAgICAgICAgY3VyICs9IHN0ZXAsIGkrKykgeworICAgICAgICAgICAgICAgIGdhcmJhZ2VbaV0gPSBzZWxmaXRlbXNbY3VyXTsKKyAgICAgICAgICAgICAgICBpbnMgPSBzZXFpdGVtc1tpXTsKKyAgICAgICAgICAgICAgICBQeV9JTkNSRUYoaW5zKTsKKyAgICAgICAgICAgICAgICBzZWxmaXRlbXNbY3VyXSA9IGluczsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IHNsaWNlbGVuZ3RoOyBpKyspIHsKKyAgICAgICAgICAgICAgICBQeV9ERUNSRUYoZ2FyYmFnZVtpXSk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIFB5TWVtX0ZSRUUoZ2FyYmFnZSk7CisgICAgICAgICAgICBQeV9ERUNSRUYoc2VxKTsKKworICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgIH0KKyAgICB9CisgICAgZWxzZSB7CisgICAgICAgIFB5RXJyX0Zvcm1hdChQeUV4Y19UeXBlRXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAibGlzdCBpbmRpY2VzIG11c3QgYmUgaW50ZWdlcnMsIG5vdCAlLjIwMHMiLAorICAgICAgICAgICAgICAgICAgICAgaXRlbS0+b2JfdHlwZS0+dHBfbmFtZSk7CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9Cit9CisKK3N0YXRpYyBQeU1hcHBpbmdNZXRob2RzIGxpc3RfYXNfbWFwcGluZyA9IHsKKyAgICAobGVuZnVuYylsaXN0X2xlbmd0aCwKKyAgICAoYmluYXJ5ZnVuYylsaXN0X3N1YnNjcmlwdCwKKyAgICAob2Jqb2JqYXJncHJvYylsaXN0X2Fzc19zdWJzY3JpcHQKK307CisKK1B5VHlwZU9iamVjdCBQeUxpc3RfVHlwZSA9IHsKKyAgICBQeVZhck9iamVjdF9IRUFEX0lOSVQoJlB5VHlwZV9UeXBlLCAwKQorICAgICJsaXN0IiwKKyAgICBzaXplb2YoUHlMaXN0T2JqZWN0KSwKKyAgICAwLAorICAgIChkZXN0cnVjdG9yKWxpc3RfZGVhbGxvYywgICAgICAgICAgICAgICAgICAgLyogdHBfZGVhbGxvYyAqLworICAgIChwcmludGZ1bmMpbGlzdF9wcmludCwgICAgICAgICAgICAgICAgICAgICAgLyogdHBfcHJpbnQgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2dldGF0dHIgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3NldGF0dHIgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2NvbXBhcmUgKi8KKyAgICAocmVwcmZ1bmMpbGlzdF9yZXByLCAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3JlcHIgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2FzX251bWJlciAqLworICAgICZsaXN0X2FzX3NlcXVlbmNlLCAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfYXNfc2VxdWVuY2UgKi8KKyAgICAmbGlzdF9hc19tYXBwaW5nLCAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2FzX21hcHBpbmcgKi8KKyAgICAoaGFzaGZ1bmMpUHlPYmplY3RfSGFzaE5vdEltcGxlbWVudGVkLCAgICAgIC8qIHRwX2hhc2ggKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2NhbGwgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3N0ciAqLworICAgIFB5T2JqZWN0X0dlbmVyaWNHZXRBdHRyLCAgICAgICAgICAgICAgICAgICAgLyogdHBfZ2V0YXR0cm8gKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3NldGF0dHJvICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9hc19idWZmZXIgKi8KKyAgICBQeV9UUEZMQUdTX0RFRkFVTFQgfCBQeV9UUEZMQUdTX0hBVkVfR0MgfAorICAgICAgICBQeV9UUEZMQUdTX0JBU0VUWVBFIHwgUHlfVFBGTEFHU19MSVNUX1NVQkNMQVNTLCAgICAgICAgIC8qIHRwX2ZsYWdzICovCisgICAgbGlzdF9kb2MsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9kb2MgKi8KKyAgICAodHJhdmVyc2Vwcm9jKWxpc3RfdHJhdmVyc2UsICAgICAgICAgICAgICAgIC8qIHRwX3RyYXZlcnNlICovCisgICAgKGlucXVpcnkpbGlzdF9jbGVhciwgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9jbGVhciAqLworICAgIGxpc3RfcmljaGNvbXBhcmUsICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfcmljaGNvbXBhcmUgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3dlYWtsaXN0b2Zmc2V0ICovCisgICAgbGlzdF9pdGVyLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9pdGVyICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9pdGVybmV4dCAqLworICAgIGxpc3RfbWV0aG9kcywgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfbWV0aG9kcyAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfbWVtYmVycyAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZ2V0c2V0ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9iYXNlICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9kaWN0ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9kZXNjcl9nZXQgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2Rlc2NyX3NldCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZGljdG9mZnNldCAqLworICAgIChpbml0cHJvYylsaXN0X2luaXQsICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfaW5pdCAqLworICAgIFB5VHlwZV9HZW5lcmljQWxsb2MsICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfYWxsb2MgKi8KKyAgICBQeVR5cGVfR2VuZXJpY05ldywgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX25ldyAqLworICAgIFB5T2JqZWN0X0dDX0RlbCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZnJlZSAqLworfTsKKworCisvKioqKioqKioqKioqKioqKioqKioqKiogTGlzdCBJdGVyYXRvciAqKioqKioqKioqKioqKioqKioqKioqKioqKi8KKwordHlwZWRlZiBzdHJ1Y3QgeworICAgIFB5T2JqZWN0X0hFQUQKKyAgICBsb25nIGl0X2luZGV4OworICAgIFB5TGlzdE9iamVjdCAqaXRfc2VxOyAvKiBTZXQgdG8gTlVMTCB3aGVuIGl0ZXJhdG9yIGlzIGV4aGF1c3RlZCAqLworfSBsaXN0aXRlcm9iamVjdDsKKworc3RhdGljIFB5T2JqZWN0ICpsaXN0X2l0ZXIoUHlPYmplY3QgKik7CitzdGF0aWMgdm9pZCBsaXN0aXRlcl9kZWFsbG9jKGxpc3RpdGVyb2JqZWN0ICopOworc3RhdGljIGludCBsaXN0aXRlcl90cmF2ZXJzZShsaXN0aXRlcm9iamVjdCAqLCB2aXNpdHByb2MsIHZvaWQgKik7CitzdGF0aWMgUHlPYmplY3QgKmxpc3RpdGVyX25leHQobGlzdGl0ZXJvYmplY3QgKik7CitzdGF0aWMgUHlPYmplY3QgKmxpc3RpdGVyX2xlbihsaXN0aXRlcm9iamVjdCAqKTsKKworUHlEb2NfU1RSVkFSKGxlbmd0aF9oaW50X2RvYywgIlByaXZhdGUgbWV0aG9kIHJldHVybmluZyBhbiBlc3RpbWF0ZSBvZiBsZW4obGlzdChpdCkpLiIpOworCitzdGF0aWMgUHlNZXRob2REZWYgbGlzdGl0ZXJfbWV0aG9kc1tdID0geworICAgIHsiX19sZW5ndGhfaGludF9fIiwgKFB5Q0Z1bmN0aW9uKWxpc3RpdGVyX2xlbiwgTUVUSF9OT0FSR1MsIGxlbmd0aF9oaW50X2RvY30sCisgICAge05VTEwsICAgICAgICAgICAgICBOVUxMfSAgICAgICAgICAgLyogc2VudGluZWwgKi8KK307CisKK1B5VHlwZU9iamVjdCBQeUxpc3RJdGVyX1R5cGUgPSB7CisgICAgUHlWYXJPYmplY3RfSEVBRF9JTklUKCZQeVR5cGVfVHlwZSwgMCkKKyAgICAibGlzdGl0ZXJhdG9yIiwgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX25hbWUgKi8KKyAgICBzaXplb2YobGlzdGl0ZXJvYmplY3QpLCAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2Jhc2ljc2l6ZSAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfaXRlbXNpemUgKi8KKyAgICAvKiBtZXRob2RzICovCisgICAgKGRlc3RydWN0b3IpbGlzdGl0ZXJfZGVhbGxvYywgICAgICAgICAgICAgICAvKiB0cF9kZWFsbG9jICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9wcmludCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZ2V0YXR0ciAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfc2V0YXR0ciAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfY29tcGFyZSAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfcmVwciAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfYXNfbnVtYmVyICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9hc19zZXF1ZW5jZSAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfYXNfbWFwcGluZyAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfaGFzaCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfY2FsbCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfc3RyICovCisgICAgUHlPYmplY3RfR2VuZXJpY0dldEF0dHIsICAgICAgICAgICAgICAgICAgICAvKiB0cF9nZXRhdHRybyAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfc2V0YXR0cm8gKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2FzX2J1ZmZlciAqLworICAgIFB5X1RQRkxBR1NfREVGQVVMVCB8IFB5X1RQRkxBR1NfSEFWRV9HQywvKiB0cF9mbGFncyAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZG9jICovCisgICAgKHRyYXZlcnNlcHJvYylsaXN0aXRlcl90cmF2ZXJzZSwgICAgICAgICAgICAvKiB0cF90cmF2ZXJzZSAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfY2xlYXIgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3JpY2hjb21wYXJlICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF93ZWFrbGlzdG9mZnNldCAqLworICAgIFB5T2JqZWN0X1NlbGZJdGVyLCAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfaXRlciAqLworICAgIChpdGVybmV4dGZ1bmMpbGlzdGl0ZXJfbmV4dCwgICAgICAgICAgICAgICAgLyogdHBfaXRlcm5leHQgKi8KKyAgICBsaXN0aXRlcl9tZXRob2RzLCAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX21ldGhvZHMgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX21lbWJlcnMgKi8KK307CisKKworc3RhdGljIFB5T2JqZWN0ICoKK2xpc3RfaXRlcihQeU9iamVjdCAqc2VxKQoreworICAgIGxpc3RpdGVyb2JqZWN0ICppdDsKKworICAgIGlmICghUHlMaXN0X0NoZWNrKHNlcSkpIHsKKyAgICAgICAgUHlFcnJfQmFkSW50ZXJuYWxDYWxsKCk7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICBpdCA9IFB5T2JqZWN0X0dDX05ldyhsaXN0aXRlcm9iamVjdCwgJlB5TGlzdEl0ZXJfVHlwZSk7CisgICAgaWYgKGl0ID09IE5VTEwpCisgICAgICAgIHJldHVybiBOVUxMOworICAgIGl0LT5pdF9pbmRleCA9IDA7CisgICAgUHlfSU5DUkVGKHNlcSk7CisgICAgaXQtPml0X3NlcSA9IChQeUxpc3RPYmplY3QgKilzZXE7CisgICAgX1B5T2JqZWN0X0dDX1RSQUNLKGl0KTsKKyAgICByZXR1cm4gKFB5T2JqZWN0ICopaXQ7Cit9CisKK3N0YXRpYyB2b2lkCitsaXN0aXRlcl9kZWFsbG9jKGxpc3RpdGVyb2JqZWN0ICppdCkKK3sKKyAgICBfUHlPYmplY3RfR0NfVU5UUkFDSyhpdCk7CisgICAgUHlfWERFQ1JFRihpdC0+aXRfc2VxKTsKKyAgICBQeU9iamVjdF9HQ19EZWwoaXQpOworfQorCitzdGF0aWMgaW50CitsaXN0aXRlcl90cmF2ZXJzZShsaXN0aXRlcm9iamVjdCAqaXQsIHZpc2l0cHJvYyB2aXNpdCwgdm9pZCAqYXJnKQoreworICAgIFB5X1ZJU0lUKGl0LT5pdF9zZXEpOworICAgIHJldHVybiAwOworfQorCitzdGF0aWMgUHlPYmplY3QgKgorbGlzdGl0ZXJfbmV4dChsaXN0aXRlcm9iamVjdCAqaXQpCit7CisgICAgUHlMaXN0T2JqZWN0ICpzZXE7CisgICAgUHlPYmplY3QgKml0ZW07CisKKyAgICBhc3NlcnQoaXQgIT0gTlVMTCk7CisgICAgc2VxID0gaXQtPml0X3NlcTsKKyAgICBpZiAoc2VxID09IE5VTEwpCisgICAgICAgIHJldHVybiBOVUxMOworICAgIGFzc2VydChQeUxpc3RfQ2hlY2soc2VxKSk7CisKKyAgICBpZiAoaXQtPml0X2luZGV4IDwgUHlMaXN0X0dFVF9TSVpFKHNlcSkpIHsKKyAgICAgICAgaXRlbSA9IFB5TGlzdF9HRVRfSVRFTShzZXEsIGl0LT5pdF9pbmRleCk7CisgICAgICAgICsraXQtPml0X2luZGV4OworICAgICAgICBQeV9JTkNSRUYoaXRlbSk7CisgICAgICAgIHJldHVybiBpdGVtOworICAgIH0KKworICAgIFB5X0RFQ1JFRihzZXEpOworICAgIGl0LT5pdF9zZXEgPSBOVUxMOworICAgIHJldHVybiBOVUxMOworfQorCitzdGF0aWMgUHlPYmplY3QgKgorbGlzdGl0ZXJfbGVuKGxpc3RpdGVyb2JqZWN0ICppdCkKK3sKKyAgICBQeV9zc2l6ZV90IGxlbjsKKyAgICBpZiAoaXQtPml0X3NlcSkgeworICAgICAgICBsZW4gPSBQeUxpc3RfR0VUX1NJWkUoaXQtPml0X3NlcSkgLSBpdC0+aXRfaW5kZXg7CisgICAgICAgIGlmIChsZW4gPj0gMCkKKyAgICAgICAgICAgIHJldHVybiBQeUludF9Gcm9tU3NpemVfdChsZW4pOworICAgIH0KKyAgICByZXR1cm4gUHlJbnRfRnJvbUxvbmcoMCk7Cit9CisvKioqKioqKioqKioqKioqKioqKioqKiogTGlzdCBSZXZlcnNlIEl0ZXJhdG9yICoqKioqKioqKioqKioqKioqKioqKioqKioqLworCit0eXBlZGVmIHN0cnVjdCB7CisgICAgUHlPYmplY3RfSEVBRAorICAgIFB5X3NzaXplX3QgaXRfaW5kZXg7CisgICAgUHlMaXN0T2JqZWN0ICppdF9zZXE7IC8qIFNldCB0byBOVUxMIHdoZW4gaXRlcmF0b3IgaXMgZXhoYXVzdGVkICovCit9IGxpc3RyZXZpdGVyb2JqZWN0OworCitzdGF0aWMgUHlPYmplY3QgKmxpc3RfcmV2ZXJzZWQoUHlMaXN0T2JqZWN0ICosIFB5T2JqZWN0ICopOworc3RhdGljIHZvaWQgbGlzdHJldml0ZXJfZGVhbGxvYyhsaXN0cmV2aXRlcm9iamVjdCAqKTsKK3N0YXRpYyBpbnQgbGlzdHJldml0ZXJfdHJhdmVyc2UobGlzdHJldml0ZXJvYmplY3QgKiwgdmlzaXRwcm9jLCB2b2lkICopOworc3RhdGljIFB5T2JqZWN0ICpsaXN0cmV2aXRlcl9uZXh0KGxpc3RyZXZpdGVyb2JqZWN0ICopOworc3RhdGljIFB5T2JqZWN0ICpsaXN0cmV2aXRlcl9sZW4obGlzdHJldml0ZXJvYmplY3QgKik7CisKK3N0YXRpYyBQeU1ldGhvZERlZiBsaXN0cmV2aXRlcl9tZXRob2RzW10gPSB7CisgICAgeyJfX2xlbmd0aF9oaW50X18iLCAoUHlDRnVuY3Rpb24pbGlzdHJldml0ZXJfbGVuLCBNRVRIX05PQVJHUywgbGVuZ3RoX2hpbnRfZG9jfSwKKyAgICB7TlVMTCwgICAgICAgICAgICAgIE5VTEx9ICAgICAgICAgICAvKiBzZW50aW5lbCAqLworfTsKKworUHlUeXBlT2JqZWN0IFB5TGlzdFJldkl0ZXJfVHlwZSA9IHsKKyAgICBQeVZhck9iamVjdF9IRUFEX0lOSVQoJlB5VHlwZV9UeXBlLCAwKQorICAgICJsaXN0cmV2ZXJzZWl0ZXJhdG9yIiwgICAgICAgICAgICAgICAgICAgICAgLyogdHBfbmFtZSAqLworICAgIHNpemVvZihsaXN0cmV2aXRlcm9iamVjdCksICAgICAgICAgICAgICAgICAgLyogdHBfYmFzaWNzaXplICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9pdGVtc2l6ZSAqLworICAgIC8qIG1ldGhvZHMgKi8KKyAgICAoZGVzdHJ1Y3RvcilsaXN0cmV2aXRlcl9kZWFsbG9jLCAgICAgICAgICAgIC8qIHRwX2RlYWxsb2MgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3ByaW50ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9nZXRhdHRyICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9zZXRhdHRyICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9jb21wYXJlICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9yZXByICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9hc19udW1iZXIgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2FzX3NlcXVlbmNlICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9hc19tYXBwaW5nICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9oYXNoICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9jYWxsICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9zdHIgKi8KKyAgICBQeU9iamVjdF9HZW5lcmljR2V0QXR0ciwgICAgICAgICAgICAgICAgICAgIC8qIHRwX2dldGF0dHJvICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9zZXRhdHRybyAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfYXNfYnVmZmVyICovCisgICAgUHlfVFBGTEFHU19ERUZBVUxUIHwgUHlfVFBGTEFHU19IQVZFX0dDLC8qIHRwX2ZsYWdzICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9kb2MgKi8KKyAgICAodHJhdmVyc2Vwcm9jKWxpc3RyZXZpdGVyX3RyYXZlcnNlLCAgICAgICAgIC8qIHRwX3RyYXZlcnNlICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9jbGVhciAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfcmljaGNvbXBhcmUgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3dlYWtsaXN0b2Zmc2V0ICovCisgICAgUHlPYmplY3RfU2VsZkl0ZXIsICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9pdGVyICovCisgICAgKGl0ZXJuZXh0ZnVuYylsaXN0cmV2aXRlcl9uZXh0LCAgICAgICAgICAgICAvKiB0cF9pdGVybmV4dCAqLworICAgIGxpc3RyZXZpdGVyX21ldGhvZHMsICAgICAgICAgICAgICAgIC8qIHRwX21ldGhvZHMgKi8KKyAgICAwLAorfTsKKworc3RhdGljIFB5T2JqZWN0ICoKK2xpc3RfcmV2ZXJzZWQoUHlMaXN0T2JqZWN0ICpzZXEsIFB5T2JqZWN0ICp1bnVzZWQpCit7CisgICAgbGlzdHJldml0ZXJvYmplY3QgKml0OworCisgICAgaXQgPSBQeU9iamVjdF9HQ19OZXcobGlzdHJldml0ZXJvYmplY3QsICZQeUxpc3RSZXZJdGVyX1R5cGUpOworICAgIGlmIChpdCA9PSBOVUxMKQorICAgICAgICByZXR1cm4gTlVMTDsKKyAgICBhc3NlcnQoUHlMaXN0X0NoZWNrKHNlcSkpOworICAgIGl0LT5pdF9pbmRleCA9IFB5TGlzdF9HRVRfU0laRShzZXEpIC0gMTsKKyAgICBQeV9JTkNSRUYoc2VxKTsKKyAgICBpdC0+aXRfc2VxID0gc2VxOworICAgIFB5T2JqZWN0X0dDX1RyYWNrKGl0KTsKKyAgICByZXR1cm4gKFB5T2JqZWN0ICopaXQ7Cit9CisKK3N0YXRpYyB2b2lkCitsaXN0cmV2aXRlcl9kZWFsbG9jKGxpc3RyZXZpdGVyb2JqZWN0ICppdCkKK3sKKyAgICBQeU9iamVjdF9HQ19VblRyYWNrKGl0KTsKKyAgICBQeV9YREVDUkVGKGl0LT5pdF9zZXEpOworICAgIFB5T2JqZWN0X0dDX0RlbChpdCk7Cit9CisKK3N0YXRpYyBpbnQKK2xpc3RyZXZpdGVyX3RyYXZlcnNlKGxpc3RyZXZpdGVyb2JqZWN0ICppdCwgdmlzaXRwcm9jIHZpc2l0LCB2b2lkICphcmcpCit7CisgICAgUHlfVklTSVQoaXQtPml0X3NlcSk7CisgICAgcmV0dXJuIDA7Cit9CisKK3N0YXRpYyBQeU9iamVjdCAqCitsaXN0cmV2aXRlcl9uZXh0KGxpc3RyZXZpdGVyb2JqZWN0ICppdCkKK3sKKyAgICBQeU9iamVjdCAqaXRlbTsKKyAgICBQeV9zc2l6ZV90IGluZGV4ID0gaXQtPml0X2luZGV4OworICAgIFB5TGlzdE9iamVjdCAqc2VxID0gaXQtPml0X3NlcTsKKworICAgIGlmIChpbmRleD49MCAmJiBpbmRleCA8IFB5TGlzdF9HRVRfU0laRShzZXEpKSB7CisgICAgICAgIGl0ZW0gPSBQeUxpc3RfR0VUX0lURU0oc2VxLCBpbmRleCk7CisgICAgICAgIGl0LT5pdF9pbmRleC0tOworICAgICAgICBQeV9JTkNSRUYoaXRlbSk7CisgICAgICAgIHJldHVybiBpdGVtOworICAgIH0KKyAgICBpdC0+aXRfaW5kZXggPSAtMTsKKyAgICBpZiAoc2VxICE9IE5VTEwpIHsKKyAgICAgICAgaXQtPml0X3NlcSA9IE5VTEw7CisgICAgICAgIFB5X0RFQ1JFRihzZXEpOworICAgIH0KKyAgICByZXR1cm4gTlVMTDsKK30KKworc3RhdGljIFB5T2JqZWN0ICoKK2xpc3RyZXZpdGVyX2xlbihsaXN0cmV2aXRlcm9iamVjdCAqaXQpCit7CisgICAgUHlfc3NpemVfdCBsZW4gPSBpdC0+aXRfaW5kZXggKyAxOworICAgIGlmIChpdC0+aXRfc2VxID09IE5VTEwgfHwgUHlMaXN0X0dFVF9TSVpFKGl0LT5pdF9zZXEpIDwgbGVuKQorICAgICAgICBsZW4gPSAwOworICAgIHJldHVybiBQeUxvbmdfRnJvbVNzaXplX3QobGVuKTsKK30KZGlmZiAtLWdpdCBhL1B5dGhvbi0yLjcuNS9PYmplY3RzL2xpc3Rzb3J0LnR4dCBiL1B5dGhvbi0yLjcuNS9PYmplY3RzL2xpc3Rzb3J0LnR4dApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zMWE1NDQ1Ci0tLSAvZGV2L251bGwKKysrIGIvUHl0aG9uLTIuNy41L09iamVjdHMvbGlzdHNvcnQudHh0CkBAIC0wLDAgKzEsNjc3IEBACitJbnRybworLS0tLS0KK1RoaXMgZGVzY3JpYmVzIGFuIGFkYXB0aXZlLCBzdGFibGUsIG5hdHVyYWwgbWVyZ2Vzb3J0LCBtb2Rlc3RseSBjYWxsZWQKK3RpbXNvcnQgKGhleSwgSSBlYXJuZWQgaXQgPHdpbms+KS4gIEl0IGhhcyBzdXBlcm5hdHVyYWwgcGVyZm9ybWFuY2Ugb24gbWFueQora2luZHMgb2YgcGFydGlhbGx5IG9yZGVyZWQgYXJyYXlzIChsZXNzIHRoYW4gbGcoTiEpIGNvbXBhcmlzb25zIG5lZWRlZCwgYW5kCithcyBmZXcgYXMgTi0xKSwgeWV0IGFzIGZhc3QgYXMgUHl0aG9uJ3MgcHJldmlvdXMgaGlnaGx5IHR1bmVkIHNhbXBsZXNvcnQKK2h5YnJpZCBvbiByYW5kb20gYXJyYXlzLgorCitJbiBhIG51dHNoZWxsLCB0aGUgbWFpbiByb3V0aW5lIG1hcmNoZXMgb3ZlciB0aGUgYXJyYXkgb25jZSwgbGVmdCB0byByaWdodCwKK2FsdGVybmF0ZWx5IGlkZW50aWZ5aW5nIHRoZSBuZXh0IHJ1biwgdGhlbiBtZXJnaW5nIGl0IGludG8gdGhlIHByZXZpb3VzCitydW5zICJpbnRlbGxpZ2VudGx5Ii4gIEV2ZXJ5dGhpbmcgZWxzZSBpcyBjb21wbGljYXRpb24gZm9yIHNwZWVkLCBhbmQgc29tZQoraGFyZC13b24gbWVhc3VyZSBvZiBtZW1vcnkgZWZmaWNpZW5jeS4KKworCitDb21wYXJpc29uIHdpdGggUHl0aG9uJ3MgU2FtcGxlc29ydCBIeWJyaWQKKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorKyB0aW1zb3J0IGNhbiByZXF1aXJlIGEgdGVtcCBhcnJheSBjb250YWluaW5nIGFzIG1hbnkgYXMgTi8vMiBwb2ludGVycywKKyAgd2hpY2ggbWVhbnMgYXMgbWFueSBhcyAyKk4gZXh0cmEgYnl0ZXMgb24gMzItYml0IGJveGVzLiAgSXQgY2FuIGJlCisgIGV4cGVjdGVkIHRvIHJlcXVpcmUgYSB0ZW1wIGFycmF5IHRoaXMgbGFyZ2Ugd2hlbiBzb3J0aW5nIHJhbmRvbSBkYXRhOyBvbgorICBkYXRhIHdpdGggc2lnbmlmaWNhbnQgc3RydWN0dXJlLCBpdCBtYXkgZ2V0IGF3YXkgd2l0aG91dCB1c2luZyBhbnkgZXh0cmEKKyAgaGVhcCBtZW1vcnkuICBUaGlzIGFwcGVhcnMgdG8gYmUgdGhlIHN0cm9uZ2VzdCBhcmd1bWVudCBhZ2FpbnN0IGl0LCBidXQKKyAgY29tcGFyZWQgdG8gdGhlIHNpemUgb2YgYW4gb2JqZWN0LCAyIHRlbXAgYnl0ZXMgd29yc3QtY2FzZSAoYWxzbyBleHBlY3RlZC0KKyAgY2FzZSBmb3IgcmFuZG9tIGRhdGEpIGRvZXNuJ3Qgc2NhcmUgbWUgbXVjaC4KKworICBJdCB0dXJucyBvdXQgdGhhdCBQZXJsIGlzIG1vdmluZyB0byBhIHN0YWJsZSBtZXJnZXNvcnQsIGFuZCB0aGUgY29kZSBmb3IKKyAgdGhhdCBhcHBlYXJzIGFsd2F5cyB0byByZXF1aXJlIGEgdGVtcCBhcnJheSB3aXRoIHJvb20gZm9yIGF0IGxlYXN0IE4KKyAgcG9pbnRlcnMuIChOb3RlIHRoYXQgSSB3b3VsZG4ndCB3YW50IHRvIGRvIHRoYXQgZXZlbiBpZiBzcGFjZSB3ZXJlbid0IGFuCisgIGlzc3VlOyBJIGJlbGlldmUgaXRzIGVmZm9ydHMgYXQgbWVtb3J5IGZydWdhbGl0eSBhbHNvIHNhdmUgdGltc29ydAorICBzaWduaWZpY2FudCBwb2ludGVyLWNvcHlpbmcgY29zdHMsIGFuZCBhbGxvdyBpdCB0byBoYXZlIGEgc21hbGxlciB3b3JraW5nCisgIHNldC4pCisKKysgQWNyb3NzIGFib3V0IGZvdXIgaG91cnMgb2YgZ2VuZXJhdGluZyByYW5kb20gYXJyYXlzLCBhbmQgc29ydGluZyB0aGVtCisgIHVuZGVyIGJvdGggbWV0aG9kcywgc2FtcGxlc29ydCByZXF1aXJlZCBhYm91dCAxLjUlIG1vcmUgY29tcGFyaXNvbnMKKyAgKHRoZSBwcm9ncmFtIGlzIGF0IHRoZSBlbmQgb2YgdGhpcyBmaWxlKS4KKworKyBJbiByZWFsIGxpZmUsIHRoaXMgbWF5IGJlIGZhc3RlciBvciBzbG93ZXIgb24gcmFuZG9tIGFycmF5cyB0aGFuCisgIHNhbXBsZXNvcnQgd2FzLCBkZXBlbmRpbmcgb24gcGxhdGZvcm0gcXVpcmtzLiAgU2luY2UgaXQgZG9lcyBmZXdlcgorICBjb21wYXJpc29ucyBvbiBhdmVyYWdlLCBpdCBjYW4gYmUgZXhwZWN0ZWQgdG8gZG8gYmV0dGVyIHRoZSBtb3JlCisgIGV4cGVuc2l2ZSBhIGNvbXBhcmlzb24gZnVuY3Rpb24gaXMuICBPVE9ILCBpdCBkb2VzIG1vcmUgZGF0YSBtb3ZlbWVudAorICAocG9pbnRlciBjb3B5aW5nKSB0aGFuIHNhbXBsZXNvcnQsIGFuZCB0aGF0IG1heSBuZWdhdGUgaXRzIHNtYWxsCisgIGNvbXBhcmlzb24gYWR2YW50YWdlIChkZXBlbmRpbmcgb24gcGxhdGZvcm0gcXVpcmtzKSB1bmxlc3MgY29tcGFyaXNvbgorICBpcyB2ZXJ5IGV4cGVuc2l2ZS4KKworKyBPbiBhcnJheXMgd2l0aCBtYW55IGtpbmRzIG9mIHByZS1leGlzdGluZyBvcmRlciwgdGhpcyBibG93cyBzYW1wbGVzb3J0IG91dAorICBvZiB0aGUgd2F0ZXIuICBJdCdzIHNpZ25pZmljYW50bHkgZmFzdGVyIHRoYW4gc2FtcGxlc29ydCBldmVuIG9uIHNvbWUKKyAgY2FzZXMgc2FtcGxlc29ydCB3YXMgc3BlY2lhbC1jYXNpbmcgdGhlIHNub3Qgb3V0IG9mLiAgSSBiZWxpZXZlIHRoYXQgbGlzdHMKKyAgdmVyeSBvZnRlbiBkbyBoYXZlIGV4cGxvaXRhYmxlIHBhcnRpYWwgb3JkZXIgaW4gcmVhbCBsaWZlLCBhbmQgdGhpcyBpcyB0aGUKKyAgc3Ryb25nZXN0IGFyZ3VtZW50IGluIGZhdm9yIG9mIHRpbXNvcnQgKGluZGVlZCwgc2FtcGxlc29ydCdzIHNwZWNpYWwgY2FzZXMKKyAgZm9yIGV4dHJlbWUgcGFydGlhbCBvcmRlciBhcmUgYXBwcmVjaWF0ZWQgYnkgcmVhbCB1c2VycywgYW5kIHRpbXNvcnQgZ29lcworICBtdWNoIGRlZXBlciB0aGFuIHRob3NlLCBpbiBwYXJ0aWN1bGFyIG5hdHVyYWxseSBjb3ZlcmluZyBldmVyeSBjYXNlIHdoZXJlCisgIHNvbWVvbmUgaGFzIHN1Z2dlc3RlZCAiYW5kIGl0IHdvdWxkIGJlIGNvb2wgaWYgbGlzdC5zb3J0KCkgaGFkIGEgc3BlY2lhbAorICBjYXNlIGZvciB0aGlzIHRvbyAuLi4gYW5kIGZvciB0aGF0IC4uLiIpLgorCisrIEhlcmUgYXJlIGV4YWN0IGNvbXBhcmlzb24gY291bnRzIGFjcm9zcyBhbGwgdGhlIHRlc3RzIGluIHNvcnRwZXJmLnB5LAorICB3aGVuIHJ1biB3aXRoIGFyZ3VtZW50cyAiMTUgMjAgMSIuCisKKyAgQ29sdW1uIEtleToKKyAgICAgICpzb3J0OiByYW5kb20gZGF0YQorICAgICAgXHNvcnQ6IGRlc2NlbmRpbmcgZGF0YQorICAgICAgL3NvcnQ6IGFzY2VuZGluZyBkYXRhCisgICAgICAzc29ydDogYXNjZW5kaW5nLCB0aGVuIDMgcmFuZG9tIGV4Y2hhbmdlcworICAgICAgK3NvcnQ6IGFzY2VuZGluZywgdGhlbiAxMCByYW5kb20gYXQgdGhlIGVuZAorICAgICAgfnNvcnQ6IG1hbnkgZHVwbGljYXRlcworICAgICAgPXNvcnQ6IGFsbCBlcXVhbAorICAgICAgIXNvcnQ6IHdvcnN0IGNhc2Ugc2NlbmFyaW8KKworICBGaXJzdCB0aGUgdHJpdmlhbCBjYXNlcywgdHJpdmlhbCBmb3Igc2FtcGxlc29ydCBiZWNhdXNlIGl0IHNwZWNpYWwtY2FzZWQKKyAgdGhlbSwgYW5kIHRyaXZpYWwgZm9yIHRpbXNvcnQgYmVjYXVzZSBpdCBuYXR1cmFsbHkgd29ya3Mgb24gcnVucy4gIFdpdGhpbgorICBhbiAibiIgYmxvY2ssIHRoZSBmaXJzdCBsaW5lIGdpdmVzIHRoZSAjIG9mIGNvbXBhcmVzIGRvbmUgYnkgc2FtcGxlc29ydCwKKyAgdGhlIHNlY29uZCBsaW5lIGJ5IHRpbXNvcnQsIGFuZCB0aGUgdGhpcmQgbGluZSBpcyB0aGUgcGVyY2VudGFnZSBieQorICB3aGljaCB0aGUgc2FtcGxlc29ydCBjb3VudCBleGNlZWRzIHRoZSB0aW1zb3J0IGNvdW50OgorCisgICAgICBuICAgXHNvcnQgICAvc29ydCAgID1zb3J0CistLS0tLS0tICAtLS0tLS0gIC0tLS0tLSAgLS0tLS0tCisgIDMyNzY4ICAgMzI3NjggICAzMjc2NyAgIDMyNzY3ICBzYW1wbGVzb3J0CisgICAgICAgICAgMzI3NjcgICAzMjc2NyAgIDMyNzY3ICB0aW1zb3J0CisgICAgICAgICAgMC4wMCUgICAwLjAwJSAgIDAuMDAlICAoc2FtcGxlc29ydCAtIHRpbXNvcnQpIC8gdGltc29ydAorCisgIDY1NTM2ICAgNjU1MzYgICA2NTUzNSAgIDY1NTM1CisgICAgICAgICAgNjU1MzUgICA2NTUzNSAgIDY1NTM1CisgICAgICAgICAgMC4wMCUgICAwLjAwJSAgIDAuMDAlCisKKyAxMzEwNzIgIDEzMTA3MiAgMTMxMDcxICAxMzEwNzEKKyAgICAgICAgIDEzMTA3MSAgMTMxMDcxICAxMzEwNzEKKyAgICAgICAgICAwLjAwJSAgIDAuMDAlICAgMC4wMCUKKworIDI2MjE0NCAgMjYyMTQ0ICAyNjIxNDMgIDI2MjE0MworICAgICAgICAgMjYyMTQzICAyNjIxNDMgIDI2MjE0MworICAgICAgICAgIDAuMDAlICAgMC4wMCUgICAwLjAwJQorCisgNTI0Mjg4ICA1MjQyODggIDUyNDI4NyAgNTI0Mjg3CisgICAgICAgICA1MjQyODcgIDUyNDI4NyAgNTI0Mjg3CisgICAgICAgICAgMC4wMCUgICAwLjAwJSAgIDAuMDAlCisKKzEwNDg1NzYgMTA0ODU3NiAxMDQ4NTc1IDEwNDg1NzUKKyAgICAgICAgMTA0ODU3NSAxMDQ4NTc1IDEwNDg1NzUKKyAgICAgICAgICAwLjAwJSAgIDAuMDAlICAgMC4wMCUKKworICBUaGUgYWxnb3JpdGhtcyBhcmUgZWZmZWN0aXZlbHkgaWRlbnRpY2FsIGluIHRoZXNlIGNhc2VzLCBleGNlcHQgdGhhdAorICB0aW1zb3J0IGRvZXMgb25lIGxlc3MgY29tcGFyZSBpbiBcc29ydC4KKworICBOb3cgZm9yIHRoZSBtb3JlIGludGVyZXN0aW5nIGNhc2VzLiAgbGcobiEpIGlzIHRoZSBpbmZvcm1hdGlvbi10aGVvcmV0aWMKKyAgbGltaXQgZm9yIHRoZSBiZXN0IGFueSBjb21wYXJpc29uLWJhc2VkIHNvcnRpbmcgYWxnb3JpdGhtIGNhbiBkbyBvbgorICBhdmVyYWdlIChhY3Jvc3MgYWxsIHBlcm11dGF0aW9ucykuICBXaGVuIGEgbWV0aG9kIGdldHMgc2lnbmlmaWNhbnRseQorICBiZWxvdyB0aGF0LCBpdCdzIGVpdGhlciBhc3Ryb25vbWljYWxseSBsdWNreSwgb3IgaXMgZmluZGluZyBleHBsb2l0YWJsZQorICBzdHJ1Y3R1cmUgaW4gdGhlIGRhdGEuCisKKyAgICAgIG4gICBsZyhuISkgICAgKnNvcnQgICAgM3NvcnQgICAgICtzb3J0ICAgJXNvcnQgICAgfnNvcnQgICAgICFzb3J0CistLS0tLS0tICAtLS0tLS0tICAgLS0tLS0tICAgLS0tLS0tLSAgLS0tLS0tLSAgLS0tLS0tICAtLS0tLS0tICAtLS0tLS0tLQorICAzMjc2OCAgIDQ0NDI1NSAgIDQ1MzA5NiAgIDQ1MzYxNCAgICAzMjkwOCAgIDQ1Mjg3MSAgIDEzMDQ5MSAgICA0NjkxNDEgb2xkCisgICAgICAgICAgICAgICAgICAgNDQ4ODg1ICAgIDMzMDE2ICAgIDMzMDA3ICAgIDUwNDI2ICAgMTgyMDgzICAgICA2NTUzNCBuZXcKKyAgICAgICAgICAgICAgICAgICAgMC45NCUgMTI3My45MiUgICAtMC4zMCUgIDc5OC4wOSUgIC0yOC4zMyUgICA2MTUuODclICVjaCBmcm9tIG5ldworCisgIDY1NTM2ICAgOTU0MDM3ICAgOTcyNjk5ICAgOTgxOTQwICAgIDY1Njg2ICAgOTczMTA0ICAgMjYwMDI5ICAgMTAwNDYwNworICAgICAgICAgICAgICAgICAgIDk2Mjk5MSAgICA2NTgyMSAgICA2NTgwOCAgIDEwMTY2NyAgIDM2NDM0MSAgICAxMzEwNzAKKyAgICAgICAgICAgICAgICAgICAgMS4wMSUgMTM5MS44MyUgICAtMC4xOSUgIDg1Ny4xNSUgIC0yOC42MyUgICA2NjYuNDclCisKKyAxMzEwNzIgIDIwMzkxMzcgIDIxMDE4ODEgIDIwOTE0OTEgICAxMzEyMzIgIDIwOTI4OTQgICA1NTQ3OTAgICAyMTYxMzc5CisgICAgICAgICAgICAgICAgICAyMDU3NTMzICAgMTMxNDEwICAgMTMxMzYxICAgMjA2MTkzICAgNzI4ODcxICAgIDI2MjE0MgorICAgICAgICAgICAgICAgICAgICAyLjE2JSAxNDkxLjU4JSAgIC0wLjEwJSAgOTE1LjAyJSAgLTIzLjg4JSAgIDcyNC41MSUKKworIDI2MjE0NCAgNDM0MDQwOSAgNDQ2NDQ2MCAgNDQwMzIzMyAgIDI2MjMxNCAgNDQ0NTg4NCAgMTEwNzg0MiAgIDQ1ODQ1NjAKKyAgICAgICAgICAgICAgICAgIDQzNzc0MDIgICAyNjI0MzcgICAyNjI0NTkgICA0MTYzNDcgIDE0NTc5NDUgICAgNTI0Mjg2CisgICAgICAgICAgICAgICAgICAgIDEuOTklIDE1NzcuODIlICAgLTAuMDYlICA5NjcuODMlICAtMjQuMDElICAgNzc0LjQ0JQorCisgNTI0Mjg4ICA5MjA1MDk2ICA5NDUzMzU2ICA5NDA4NDYzICAgNTI0NDY4ICA5NDQxOTMwICAyMjE4NTc3ICAgOTY5MjAxNQorICAgICAgICAgICAgICAgICAgOTI3ODczNCAgIDUyNDU4MCAgIDUyNDYzMyAgIDgzNzk0NyAgMjkxNjEwNyAgIDEwNDg1NzQKKyAgICAgICAgICAgICAgICAgICAxLjg4JSAgMTY5My41MiUgICAtMC4wMyUgMTAyNi43OSUgIC0yMy45MiUgICA4MjQuMzAlCisKKzEwNDg1NzYgMTk0NTg3NTYgMTk5NTAyNzIgMTk4Mzg1ODggIDEwNDg3NjYgMTk5MTIxMzQgIDQ0MzA2NDkgIDIwNDM0MjEyCisgICAgICAgICAgICAgICAgIDE5NjA2MDI4ICAxMDQ4OTU4ICAxMDQ4OTQxICAxNjk0ODk2ICA1ODMyNDQ1ICAgMjA5NzE1MAorICAgICAgICAgICAgICAgICAgICAxLjc2JSAxNzkxLjI3JSAgIC0wLjAyJSAxMDc0LjgzJSAgLTI0LjAzJSAgIDg3NC4zOCUKKworICBEaXNjdXNzaW9uIG9mIGNhc2VzOgorCisgICpzb3J0OiAgVGhlcmUncyBubyBzdHJ1Y3R1cmUgaW4gcmFuZG9tIGRhdGEgdG8gZXhwbG9pdCwgc28gdGhlIHRoZW9yZXRpY2FsCisgIGxpbWl0IGlzIGxnKG4hKS4gIEJvdGggbWV0aG9kcyBnZXQgY2xvc2UgdG8gdGhhdCwgYW5kIHRpbXNvcnQgaXMgaHVnZ2luZworICBpdCAoaW5kZWVkLCBpbiBhICptYXJnaW5hbCogc2Vuc2UsIGl0J3MgYSBzcGVjdGFjdWxhciBpbXByb3ZlbWVudCAtLQorICB0aGVyZSdzIG9ubHkgYWJvdXQgMSUgbGVmdCBiZWZvcmUgaGl0dGluZyB0aGUgd2FsbCwgYW5kIHRpbXNvcnQga25vd3MKKyAgZGFybmVkIHdlbGwgaXQncyBkb2luZyBjb21wYXJlcyB0aGF0IHdvbid0IHBheSBvbiByYW5kb20gZGF0YSAtLSBidXQgc28KKyAgZG9lcyB0aGUgc2FtcGxlc29ydCBoeWJyaWQpLiAgRm9yIGNvbnRyYXN0LCBIb2FyZSdzIG9yaWdpbmFsIHJhbmRvbS1waXZvdAorICBxdWlja3NvcnQgZG9lcyBhYm91dCAzOSUgbW9yZSBjb21wYXJlcyB0aGFuIHRoZSBsaW1pdCwgYW5kIHRoZSBtZWRpYW4tb2YtMworICB2YXJpYW50IGFib3V0IDE5JSBtb3JlLgorCisgIDNzb3J0LCAlc29ydCwgYW5kICFzb3J0OiAgTm8gY29udGVzdDsgdGhlcmUncyBzdHJ1Y3R1cmUgaW4gdGhpcyBkYXRhLCBidXQKKyAgbm90IG9mIHRoZSBzcGVjaWZpYyBraW5kcyBzYW1wbGVzb3J0IHNwZWNpYWwtY2FzZXMuICBOb3RlIHRoYXQgc3RydWN0dXJlCisgIGluICFzb3J0IHdhc24ndCBwdXQgdGhlcmUgb24gcHVycG9zZSAtLSBpdCB3YXMgY3JhZnRlZCBhcyBhIHdvcnN0IGNhc2UgZm9yCisgIGEgcHJldmlvdXMgcXVpY2tzb3J0IGltcGxlbWVudGF0aW9uLiAgVGhhdCB0aW1zb3J0IG5haWxzIGl0IGNhbWUgYXMgYQorICBzdXJwcmlzZSB0byBtZSAoYWx0aG91Z2ggaXQncyBvYnZpb3VzIGluIHJldHJvc3BlY3QpLgorCisgICtzb3J0OiAgc2FtcGxlc29ydCBzcGVjaWFsLWNhc2VzIHRoaXMgZGF0YSwgYW5kIGRvZXMgYSBmZXcgbGVzcyBjb21wYXJlcworICB0aGFuIHRpbXNvcnQuICBIb3dldmVyLCB0aW1zb3J0IHJ1bnMgdGhpcyBjYXNlIHNpZ25pZmljYW50bHkgZmFzdGVyIG9uIGFsbAorICBib3hlcyB3ZSBoYXZlIHRpbWluZ3MgZm9yLCBiZWNhdXNlIHRpbXNvcnQgaXMgaW4gdGhlIGJ1c2luZXNzIG9mIG1lcmdpbmcKKyAgcnVucyBlZmZpY2llbnRseSwgd2hpbGUgc2FtcGxlc29ydCBkb2VzIG11Y2ggbW9yZSBkYXRhIG1vdmVtZW50IGluIHRoaXMKKyAgKGZvciBpdCkgc3BlY2lhbCBjYXNlLgorCisgIH5zb3J0OiAgc2FtcGxlc29ydCdzIHNwZWNpYWwgY2FzZXMgZm9yIGxhcmdlIG1hc3NlcyBvZiBlcXVhbCBlbGVtZW50cyBhcmUKKyAgZXh0cmVtZWx5IGVmZmVjdGl2ZSBvbiB+c29ydCdzIHNwZWNpZmljIGRhdGEgcGF0dGVybiwgYW5kIHRpbXNvcnQganVzdAorICBpc24ndCBnb2luZyB0byBnZXQgY2xvc2UgdG8gdGhhdCwgZGVzcGl0ZSB0aGF0IGl0J3MgY2xlYXJseSBnZXR0aW5nIGEKKyAgZ3JlYXQgZGVhbCBvZiBiZW5lZml0IG91dCBvZiB0aGUgZHVwbGljYXRlcyAodGhlICMgb2YgY29tcGFyZXMgaXMgbXVjaCBsZXNzCisgIHRoYW4gbGcobiEpKS4gIH5zb3J0IGhhcyBhIHBlcmZlY3RseSB1bmlmb3JtIGRpc3RyaWJ1dGlvbiBvZiBqdXN0IDQKKyAgZGlzdGluY3QgdmFsdWVzLCBhbmQgYXMgdGhlIGRpc3RyaWJ1dGlvbiBnZXRzIG1vcmUgc2tld2VkLCBzYW1wbGVzb3J0J3MKKyAgZXF1YWwtZWxlbWVudCBnaW1taWNrcyBiZWNvbWUgbGVzcyBlZmZlY3RpdmUsIHdoaWxlIHRpbXNvcnQncyBhZGFwdGl2ZQorICBzdHJhdGVnaWVzIGZpbmQgbW9yZSB0byBleHBsb2l0OyBpbiBhIGRhdGFiYXNlIHN1cHBsaWVkIGJ5IEtldmluIEFsdGlzLCBhCisgIHNvcnQgb24gaXRzIGhpZ2hseSBza2V3ZWQgIm9uIHdoaWNoIHN0b2NrIGV4Y2hhbmdlIGRvZXMgdGhpcyBjb21wYW55J3MKKyAgc3RvY2sgdHJhZGU/IiBmaWVsZCByYW4gb3ZlciB0d2ljZSBhcyBmYXN0IHVuZGVyIHRpbXNvcnQuCisKKyAgSG93ZXZlciwgZGVzcGl0ZSB0aGF0IHRpbXNvcnQgZG9lcyBtYW55IG1vcmUgY29tcGFyaXNvbnMgb24gfnNvcnQsIGFuZAorICB0aGF0IG9uIHNldmVyYWwgcGxhdGZvcm1zIH5zb3J0IHJ1bnMgaGlnaGx5IHNpZ25pZmljYW50bHkgc2xvd2VyIHVuZGVyCisgIHRpbXNvcnQsIG9uIG90aGVyIHBsYXRmb3JtcyB+c29ydCBydW5zIGhpZ2hseSBzaWduaWZpY2FudGx5IGZhc3RlciB1bmRlcgorICB0aW1zb3J0LiAgTm8gb3RoZXIga2luZCBvZiBkYXRhIGhhcyBzaG93biB0aGlzIHdpbGQgeC1wbGF0Zm9ybSBiZWhhdmlvciwKKyAgYW5kIHdlIGRvbid0IGhhdmUgYW4gZXhwbGFuYXRpb24gZm9yIGl0LiAgVGhlIG9ubHkgdGhpbmcgSSBjYW4gdGhpbmsgb2YKKyAgdGhhdCBjb3VsZCB0cmFuc2Zvcm0gd2hhdCAic2hvdWxkIGJlIiBoaWdobHkgc2lnbmlmaWNhbnQgc2xvd2Rvd25zIGludG8KKyAgaGlnaGx5IHNpZ25pZmljYW50IHNwZWVkdXBzIG9uIHNvbWUgYm94ZXMgYXJlIGNhdGFzdHJvcGhpYyBjYWNoZSBlZmZlY3RzCisgIGluIHNhbXBsZXNvcnQuCisKKyAgQnV0IHRpbXNvcnQgInNob3VsZCBiZSIgc2xvd2VyIHRoYW4gc2FtcGxlc29ydCBvbiB+c29ydCwgc28gaXQncyBoYXJkCisgIHRvIGNvdW50IHRoYXQgaXQgaXNuJ3Qgb24gc29tZSBib3hlcyBhcyBhIHN0cmlrZSBhZ2FpbnN0IGl0IDx3aW5rPi4KKworKyBIZXJlJ3MgdGhlIGhpZ2h3YXRlciBtYXJrIGZvciB0aGUgbnVtYmVyIG9mIGhlYXAtYmFzZWQgdGVtcCBzbG90cyAoNAorICBieXRlcyBlYWNoIG9uIHRoaXMgYm94KSBuZWVkZWQgYnkgZWFjaCB0ZXN0LCBhZ2FpbiB3aXRoIGFyZ3VtZW50cworICAiMTUgMjAgMSI6CisKKyAgIDIqKmkgICpzb3J0IFxzb3J0IC9zb3J0ICAzc29ydCAgK3NvcnQgICVzb3J0ICB+c29ydCAgPXNvcnQgICFzb3J0CisgIDMyNzY4ICAxNjM4NCAgICAgMCAgICAgMCAgIDYyNTYgICAgICAwICAxMDgyMSAgMTIyODggICAgICAwICAxNjM4MworICA2NTUzNiAgMzI3NjYgICAgIDAgICAgIDAgIDIxNjUyICAgICAgMCAgMzEyNzYgIDI0NTc2ICAgICAgMCAgMzI3NjcKKyAxMzEwNzIgIDY1NTM0ICAgICAwICAgICAwICAxNzI1OCAgICAgIDAgIDU4MTEyICA0OTE1MiAgICAgIDAgIDY1NTM1CisgMjYyMTQ0IDEzMTA3MiAgICAgMCAgICAgMCAgMzU2NjAgICAgICAwIDEyMzU2MSAgOTgzMDQgICAgICAwIDEzMTA3MQorIDUyNDI4OCAyNjIxNDIgICAgIDAgICAgIDAgIDMxMzAyICAgICAgMCAyMTIwNTcgMTk2NjA4ICAgICAgMCAyNjIxNDMKKzEwNDg1NzYgNTI0Mjg2ICAgICAwICAgICAwIDMxMjQzOCAgICAgIDAgNDg0OTQyIDM5MzIxNiAgICAgIDAgNTI0Mjg3CisKKyAgRGlzY3Vzc2lvbjogIFRoZSB0ZXN0cyB0aGF0IGVuZCB1cCBkb2luZyAoY2xvc2UgdG8pIHBlcmZlY3RseSBiYWxhbmNlZAorICBtZXJnZXMgKCpzb3J0LCAhc29ydCkgbmVlZCBhbGwgTi8vMiB0ZW1wIHNsb3RzIChvciBhbG1vc3QgYWxsKS4gIH5zb3J0CisgIGFsc28gZW5kcyB1cCBkb2luZyBiYWxhbmNlZCBtZXJnZXMsIGJ1dCBzeXN0ZW1hdGljYWxseSBiZW5lZml0cyBhIGxvdCBmcm9tCisgIHRoZSBwcmVsaW1pbmFyeSBwcmUtbWVyZ2Ugc2VhcmNoZXMgZGVzY3JpYmVkIHVuZGVyICJNZXJnZSBNZW1vcnkiIGxhdGVyLgorICAlc29ydCBhcHByb2FjaGVzIGhhdmluZyBhIGJhbGFuY2VkIG1lcmdlIGF0IHRoZSBlbmQgYmVjYXVzZSB0aGUgcmFuZG9tCisgIHNlbGVjdGlvbiBvZiBlbGVtZW50cyB0byByZXBsYWNlIGlzIGV4cGVjdGVkIHRvIHByb2R1Y2UgYW4gb3V0LW9mLW9yZGVyCisgIGVsZW1lbnQgbmVhciB0aGUgbWlkcG9pbnQuICBcc29ydCwgL3NvcnQsID1zb3J0IGFyZSB0aGUgdHJpdmlhbCBvbmUtcnVuCisgIGNhc2VzLCBuZWVkaW5nIG5vIG1lcmdpbmcgYXQgYWxsLiAgK3NvcnQgZW5kcyB1cCBoYXZpbmcgb25lIHZlcnkgbG9uZyBydW4KKyAgYW5kIG9uZSB2ZXJ5IHNob3J0LCBhbmQgc28gZ2V0cyBhbGwgdGhlIHRlbXAgc3BhY2UgaXQgbmVlZHMgZnJvbSB0aGUgc21hbGwKKyAgdGVtcGFycmF5IG1lbWJlciBvZiB0aGUgTWVyZ2VTdGF0ZSBzdHJ1Y3QgKG5vdGUgdGhhdCB0aGUgc2FtZSB3b3VsZCBiZQorICB0cnVlIGlmIHRoZSBuZXcgcmFuZG9tIGVsZW1lbnRzIHdlcmUgcHJlZml4ZWQgdG8gdGhlIHNvcnRlZCBsaXN0IGluc3RlYWQsCisgIGJ1dCBub3QgaWYgdGhleSBhcHBlYXJlZCAiaW4gdGhlIG1pZGRsZSIpLiAgM3NvcnQgYXBwcm9hY2hlcyBOLy8zIHRlbXAKKyAgc2xvdHMgdHdpY2UsIGJ1dCB0aGUgcnVuIGxlbmd0aHMgdGhhdCByZW1haW4gYWZ0ZXIgMyByYW5kb20gZXhjaGFuZ2VzCisgIGNsZWFybHkgaGFzIHZlcnkgaGlnaCB2YXJpYW5jZS4KKworCitBIGRldGFpbGVkIGRlc2NyaXB0aW9uIG9mIHRpbXNvcnQgZm9sbG93cy4KKworUnVucworLS0tLQorY291bnRfcnVuKCkgcmV0dXJucyB0aGUgIyBvZiBlbGVtZW50cyBpbiB0aGUgbmV4dCBydW4uICBBIHJ1biBpcyBlaXRoZXIKKyJhc2NlbmRpbmciLCB3aGljaCBtZWFucyBub24tZGVjcmVhc2luZzoKKworICAgIGEwIDw9IGExIDw9IGEyIDw9IC4uLgorCitvciAiZGVzY2VuZGluZyIsIHdoaWNoIG1lYW5zIHN0cmljdGx5IGRlY3JlYXNpbmc6CisKKyAgICBhMCA+IGExID4gYTIgPiAuLi4KKworTm90ZSB0aGF0IGEgcnVuIGlzIGFsd2F5cyBhdCBsZWFzdCAyIGxvbmcsIHVubGVzcyB3ZSBzdGFydCBhdCB0aGUgYXJyYXkncworbGFzdCBlbGVtZW50LgorCitUaGUgZGVmaW5pdGlvbiBvZiBkZXNjZW5kaW5nIGlzIHN0cmljdCwgYmVjYXVzZSB0aGUgbWFpbiByb3V0aW5lIHJldmVyc2VzCithIGRlc2NlbmRpbmcgcnVuIGluLXBsYWNlLCB0cmFuc2Zvcm1pbmcgYSBkZXNjZW5kaW5nIHJ1biBpbnRvIGFuIGFzY2VuZGluZworcnVuLiAgUmV2ZXJzYWwgaXMgZG9uZSB2aWEgdGhlIG9idmlvdXMgZmFzdCAic3dhcCBlbGVtZW50cyBzdGFydGluZyBhdCBlYWNoCitlbmQsIGFuZCBjb252ZXJnZSBhdCB0aGUgbWlkZGxlIiBtZXRob2QsIGFuZCB0aGF0IGNhbiB2aW9sYXRlIHN0YWJpbGl0eSBpZgordGhlIHNsaWNlIGNvbnRhaW5zIGFueSBlcXVhbCBlbGVtZW50cy4gIFVzaW5nIGEgc3RyaWN0IGRlZmluaXRpb24gb2YKK2Rlc2NlbmRpbmcgZW5zdXJlcyB0aGF0IGEgZGVzY2VuZGluZyBydW4gY29udGFpbnMgZGlzdGluY3QgZWxlbWVudHMuCisKK0lmIGFuIGFycmF5IGlzIHJhbmRvbSwgaXQncyB2ZXJ5IHVubGlrZWx5IHdlJ2xsIHNlZSBsb25nIHJ1bnMuICBJZiBhIG5hdHVyYWwKK3J1biBjb250YWlucyBsZXNzIHRoYW4gbWlucnVuIGVsZW1lbnRzIChzZWUgbmV4dCBzZWN0aW9uKSwgdGhlIG1haW4gbG9vcAorYXJ0aWZpY2lhbGx5IGJvb3N0cyBpdCB0byBtaW5ydW4gZWxlbWVudHMsIHZpYSBhIHN0YWJsZSBiaW5hcnkgaW5zZXJ0aW9uIHNvcnQKK2FwcGxpZWQgdG8gdGhlIHJpZ2h0IG51bWJlciBvZiBhcnJheSBlbGVtZW50cyBmb2xsb3dpbmcgdGhlIHNob3J0IG5hdHVyYWwKK3J1bi4gIEluIGEgcmFuZG9tIGFycmF5LCAqYWxsKiBydW5zIGFyZSBsaWtlbHkgdG8gYmUgbWlucnVuIGxvbmcgYXMgYQorcmVzdWx0LiAgVGhpcyBoYXMgdHdvIHByaW1hcnkgZ29vZCBlZmZlY3RzOgorCisxLiBSYW5kb20gZGF0YSBzdHJvbmdseSB0ZW5kcyB0aGVuIHRvd2FyZCBwZXJmZWN0bHkgYmFsYW5jZWQgKGJvdGggcnVucyBoYXZlCisgICB0aGUgc2FtZSBsZW5ndGgpIG1lcmdlcywgd2hpY2ggaXMgdGhlIG1vc3QgZWZmaWNpZW50IHdheSB0byBwcm9jZWVkIHdoZW4KKyAgIGRhdGEgaXMgcmFuZG9tLgorCisyLiBCZWNhdXNlIHJ1bnMgYXJlIG5ldmVyIHZlcnkgc2hvcnQsIHRoZSByZXN0IG9mIHRoZSBjb2RlIGRvZXNuJ3QgbWFrZQorICAgaGVyb2ljIGVmZm9ydHMgdG8gc2hhdmUgYSBmZXcgY3ljbGVzIG9mZiBwZXItbWVyZ2Ugb3ZlcmhlYWRzLiAgRm9yCisgICBleGFtcGxlLCByZWFzb25hYmxlIHVzZSBvZiBmdW5jdGlvbiBjYWxscyBpcyBtYWRlLCByYXRoZXIgdGhhbiB0cnlpbmcgdG8KKyAgIGlubGluZSBldmVyeXRoaW5nLiAgU2luY2UgdGhlcmUgYXJlIG5vIG1vcmUgdGhhbiBOL21pbnJ1biBydW5zIHRvIGJlZ2luCisgICB3aXRoLCBhIGZldyAiZXh0cmEiIGZ1bmN0aW9uIGNhbGxzIHBlciBtZXJnZSBpcyBiYXJlbHkgbWVhc3VyYWJsZS4KKworCitDb21wdXRpbmcgbWlucnVuCistLS0tLS0tLS0tLS0tLS0tCitJZiBOIDwgNjQsIG1pbnJ1biBpcyBOLiAgSU9XLCBiaW5hcnkgaW5zZXJ0aW9uIHNvcnQgaXMgdXNlZCBmb3IgdGhlIHdob2xlCithcnJheSB0aGVuOyBpdCdzIGhhcmQgdG8gYmVhdCB0aGF0IGdpdmVuIHRoZSBvdmVyaGVhZHMgb2YgdHJ5aW5nIHNvbWV0aGluZworZmFuY2llci4KKworV2hlbiBOIGlzIGEgcG93ZXIgb2YgMiwgdGVzdGluZyBvbiByYW5kb20gZGF0YSBzaG93ZWQgdGhhdCBtaW5ydW4gdmFsdWVzIG9mCisxNiwgMzIsIDY0IGFuZCAxMjggd29ya2VkIGFib3V0IGVxdWFsbHkgd2VsbC4gIEF0IDI1NiB0aGUgZGF0YS1tb3ZlbWVudCBjb3N0CitpbiBiaW5hcnkgaW5zZXJ0aW9uIHNvcnQgY2xlYXJseSBodXJ0LCBhbmQgYXQgOCB0aGUgaW5jcmVhc2UgaW4gdGhlIG51bWJlcgorb2YgZnVuY3Rpb24gY2FsbHMgY2xlYXJseSBodXJ0LiAgUGlja2luZyAqc29tZSogcG93ZXIgb2YgMiBpcyBpbXBvcnRhbnQKK2hlcmUsIHNvIHRoYXQgdGhlIG1lcmdlcyBlbmQgdXAgcGVyZmVjdGx5IGJhbGFuY2VkIChzZWUgbmV4dCBzZWN0aW9uKS4gIFdlCitwaWNrIDMyIGFzIGEgZ29vZCB2YWx1ZSBpbiB0aGUgc3dlZXQgcmFuZ2U7IHBpY2tpbmcgYSB2YWx1ZSBhdCB0aGUgbG93IGVuZAorYWxsb3dzIHRoZSBhZGFwdGl2ZSBnaW1taWNrcyBtb3JlIG9wcG9ydHVuaXR5IHRvIGV4cGxvaXQgc2hvcnRlciBuYXR1cmFsCitydW5zLgorCitCZWNhdXNlIHNvcnRwZXJmLnB5IG9ubHkgdHJpZXMgcG93ZXJzIG9mIDIsIGl0IHRvb2sgYSBsb25nIHRpbWUgdG8gbm90aWNlCit0aGF0IDMyIGlzbid0IGEgZ29vZCBjaG9pY2UgZm9yIHRoZSBnZW5lcmFsIGNhc2UhICBDb25zaWRlciBOPTIxMTI6CisKKz4+PiBkaXZtb2QoMjExMiwgMzIpCisoNjYsIDApCis+Pj4KKworSWYgdGhlIGRhdGEgaXMgcmFuZG9tbHkgb3JkZXJlZCwgd2UncmUgdmVyeSBsaWtlbHkgdG8gZW5kIHVwIHdpdGggNjYgcnVucworZWFjaCBvZiBsZW5ndGggMzIuICBUaGUgZmlyc3QgNjQgb2YgdGhlc2UgdHJpZ2dlciBhIHNlcXVlbmNlIG9mIHBlcmZlY3RseQorYmFsYW5jZWQgbWVyZ2VzIChzZWUgbmV4dCBzZWN0aW9uKSwgbGVhdmluZyBydW5zIG9mIGxlbmd0aHMgMjA0OCBhbmQgNjQgdG8KK21lcmdlIGF0IHRoZSBlbmQuICBUaGUgYWRhcHRpdmUgZ2ltbWlja3MgY2FuIGRvIHRoYXQgd2l0aCBmZXdlciB0aGFuIDIwNDgrNjQKK2NvbXBhcmVzLCBidXQgaXQncyBzdGlsbCBtb3JlIGNvbXBhcmVzIHRoYW4gbmVjZXNzYXJ5LCBhbmQtLSBtZXJnZXNvcnQncworYnVnYWJvbyByZWxhdGl2ZSB0byBzYW1wbGVzb3J0IC0tYSBsb3QgbW9yZSBkYXRhIG1vdmVtZW50IChPKE4pIGNvcGllcyBqdXN0Cit0byBnZXQgNjQgZWxlbWVudHMgaW50byBwbGFjZSkuCisKK0lmIHdlIHRha2UgbWlucnVuPTMzIGluIHRoaXMgY2FzZSwgdGhlbiB3ZSdyZSB2ZXJ5IGxpa2VseSB0byBlbmQgdXAgd2l0aCA2NAorcnVucyBlYWNoIG9mIGxlbmd0aCAzMywgYW5kIHRoZW4gYWxsIG1lcmdlcyBhcmUgcGVyZmVjdGx5IGJhbGFuY2VkLiAgQmV0dGVyIQorCitXaGF0IHdlIHdhbnQgdG8gYXZvaWQgaXMgcGlja2luZyBtaW5ydW4gc3VjaCB0aGF0IGluCisKKyAgICBxLCByID0gZGl2bW9kKE4sIG1pbnJ1bikKKworcSBpcyBhIHBvd2VyIG9mIDIgYW5kIHI+MCAodGhlbiB0aGUgbGFzdCBtZXJnZSBvbmx5IGdldHMgciBlbGVtZW50cyBpbnRvCitwbGFjZSwgYW5kIHIgPCBtaW5ydW4gaXMgc21hbGwgY29tcGFyZWQgdG8gTiksIG9yIHEgYSBsaXR0bGUgbGFyZ2VyIHRoYW4gYQorcG93ZXIgb2YgMiByZWdhcmRsZXNzIG9mIHIgKHRoZW4gd2UndmUgZ290IGEgY2FzZSBzaW1pbGFyIHRvICIyMTEyIiwgYWdhaW4KK2xlYXZpbmcgdG9vIGxpdHRsZSB3b3JrIGZvciB0aGUgbGFzdCBtZXJnZSB0byBkbykuCisKK0luc3RlYWQgd2UgcGljayBhIG1pbnJ1biBpbiByYW5nZSgzMiwgNjUpIHN1Y2ggdGhhdCBOL21pbnJ1biBpcyBleGFjdGx5IGEKK3Bvd2VyIG9mIDIsIG9yIGlmIHRoYXQgaXNuJ3QgcG9zc2libGUsIGlzIGNsb3NlIHRvLCBidXQgc3RyaWN0bHkgbGVzcyB0aGFuLAorYSBwb3dlciBvZiAyLiAgVGhpcyBpcyBlYXNpZXIgdG8gZG8gdGhhbiBpdCBtYXkgc291bmQ6ICB0YWtlIHRoZSBmaXJzdCA2CitiaXRzIG9mIE4sIGFuZCBhZGQgMSBpZiBhbnkgb2YgdGhlIHJlbWFpbmluZyBiaXRzIGFyZSBzZXQuICBJbiBmYWN0LCB0aGF0CitydWxlIGNvdmVycyBldmVyeSBjYXNlIGluIHRoaXMgc2VjdGlvbiwgaW5jbHVkaW5nIHNtYWxsIE4gYW5kIGV4YWN0IHBvd2Vycworb2YgMjsgbWVyZ2VfY29tcHV0ZV9taW5ydW4oKSBpcyBhIGRlY2VwdGl2ZWx5IHNpbXBsZSBmdW5jdGlvbi4KKworCitUaGUgTWVyZ2UgUGF0dGVybgorLS0tLS0tLS0tLS0tLS0tLS0KK0luIG9yZGVyIHRvIGV4cGxvaXQgcmVndWxhcml0aWVzIGluIHRoZSBkYXRhLCB3ZSdyZSBtZXJnaW5nIG9uIG5hdHVyYWwKK3J1biBsZW5ndGhzLCBhbmQgdGhleSBjYW4gYmVjb21lIHdpbGRseSB1bmJhbGFuY2VkLiAgVGhhdCdzIGEgR29vZCBUaGluZworZm9yIHRoaXMgc29ydCEgIEl0IG1lYW5zIHdlIGhhdmUgdG8gZmluZCBhIHdheSB0byBtYW5hZ2UgYW4gYXNzb3J0bWVudCBvZgorcG90ZW50aWFsbHkgdmVyeSBkaWZmZXJlbnQgcnVuIGxlbmd0aHMsIHRob3VnaC4KKworU3RhYmlsaXR5IGNvbnN0cmFpbnMgcGVybWlzc2libGUgbWVyZ2luZyBwYXR0ZXJucy4gIEZvciBleGFtcGxlLCBpZiB3ZSBoYXZlCiszIGNvbnNlY3V0aXZlIHJ1bnMgb2YgbGVuZ3RocworCisgICAgQToxMDAwMCAgQjoyMDAwMCAgQzoxMDAwMAorCit3ZSBkYXJlIG5vdCBtZXJnZSBBIHdpdGggQyBmaXJzdCwgYmVjYXVzZSBpZiBBLCBCIGFuZCBDIGhhcHBlbiB0byBjb250YWluCithIGNvbW1vbiBlbGVtZW50LCBpdCB3b3VsZCBnZXQgb3V0IG9mIG9yZGVyIHdydCBpdHMgb2NjdXJyZW5jZShzKSBpbiBCLiAgVGhlCittZXJnaW5nIG11c3QgYmUgZG9uZSBhcyAoQStCKStDIG9yIEErKEIrQykgaW5zdGVhZC4KKworU28gbWVyZ2luZyBpcyBhbHdheXMgZG9uZSBvbiB0d28gY29uc2VjdXRpdmUgcnVucyBhdCBhIHRpbWUsIGFuZCBpbi1wbGFjZSwKK2FsdGhvdWdoIHRoaXMgbWF5IHJlcXVpcmUgc29tZSB0ZW1wIG1lbW9yeSAobW9yZSBvbiB0aGF0IGxhdGVyKS4KKworV2hlbiBhIHJ1biBpcyBpZGVudGlmaWVkLCBpdHMgYmFzZSBhZGRyZXNzIGFuZCBsZW5ndGggYXJlIHB1c2hlZCBvbiBhIHN0YWNrCitpbiB0aGUgTWVyZ2VTdGF0ZSBzdHJ1Y3QuICBtZXJnZV9jb2xsYXBzZSgpIGlzIHRoZW4gY2FsbGVkIHRvIHNlZSB3aGV0aGVyIGl0CitzaG91bGQgbWVyZ2UgaXQgd2l0aCBwcmVjZWRpbmcgcnVuKHMpLiAgV2Ugd291bGQgbGlrZSB0byBkZWxheSBtZXJnaW5nIGFzCitsb25nIGFzIHBvc3NpYmxlIGluIG9yZGVyIHRvIGV4cGxvaXQgcGF0dGVybnMgdGhhdCBtYXkgY29tZSB1cCBsYXRlciwgYnV0IHdlCitsaWtlIGV2ZW4gbW9yZSB0byBkbyBtZXJnaW5nIGFzIHNvb24gYXMgcG9zc2libGUgdG8gZXhwbG9pdCB0aGF0IHRoZSBydW4ganVzdAorZm91bmQgaXMgc3RpbGwgaGlnaCBpbiB0aGUgbWVtb3J5IGhpZXJhcmNoeS4gIFdlIGFsc28gY2FuJ3QgZGVsYXkgbWVyZ2luZworInRvbyBsb25nIiBiZWNhdXNlIGl0IGNvbnN1bWVzIG1lbW9yeSB0byByZW1lbWJlciB0aGUgcnVucyB0aGF0IGFyZSBzdGlsbAordW5tZXJnZWQsIGFuZCB0aGUgc3RhY2sgaGFzIGEgZml4ZWQgc2l6ZS4KKworV2hhdCB0dXJuZWQgb3V0IHRvIGJlIGEgZ29vZCBjb21wcm9taXNlIG1haW50YWlucyB0d28gaW52YXJpYW50cyBvbiB0aGUKK3N0YWNrIGVudHJpZXMsIHdoZXJlIEEsIEIgYW5kIEMgYXJlIHRoZSBsZW5ndGhzIG9mIHRoZSB0aHJlZSByaWdobW9zdCBub3QteWV0CittZXJnZWQgc2xpY2VzOgorCisxLiAgQSA+IEIrQworMi4gIEIgPiBDCisKK05vdGUgdGhhdCwgYnkgaW5kdWN0aW9uLCAjMiBpbXBsaWVzIHRoZSBsZW5ndGhzIG9mIHBlbmRpbmcgcnVucyBmb3JtIGEKK2RlY3JlYXNpbmcgc2VxdWVuY2UuICAjMSBpbXBsaWVzIHRoYXQsIHJlYWRpbmcgdGhlIGxlbmd0aHMgcmlnaHQgdG8gbGVmdCwKK3RoZSBwZW5kaW5nLXJ1biBsZW5ndGhzIGdyb3cgYXQgbGVhc3QgYXMgZmFzdCBhcyB0aGUgRmlib25hY2NpIG51bWJlcnMuCitUaGVyZWZvcmUgdGhlIHN0YWNrIGNhbiBuZXZlciBncm93IGxhcmdlciB0aGFuIGFib3V0IGxvZ19iYXNlX3BoaShOKSBlbnRyaWVzLAord2hlcmUgcGhpID0gKDErc3FydCg1KSkvMiB+PSAxLjYxOC4gIFRodXMgYSBzbWFsbCAjIG9mIHN0YWNrIHNsb3RzIHN1ZmZpY2UKK2ZvciB2ZXJ5IGxhcmdlIGFycmF5cy4KKworSWYgQSA8PSBCK0MsIHRoZSBzbWFsbGVyIG9mIEEgYW5kIEMgaXMgbWVyZ2VkIHdpdGggQiAodGllcyBmYXZvciBDLCBmb3IgdGhlCitmcmVzaG5lc3MtaW4tY2FjaGUgcmVhc29uKSwgYW5kIHRoZSBuZXcgcnVuIHJlcGxhY2VzIHRoZSBBLEIgb3IgQixDIGVudHJpZXM7CitlLmcuLCBpZiB0aGUgbGFzdCAzIGVudHJpZXMgYXJlCisKKyAgICBBOjMwICBCOjIwICBDOjEwCisKK3RoZW4gQiBpcyBtZXJnZWQgd2l0aCBDLCBsZWF2aW5nCisKKyAgICBBOjMwICBCQzozMAorCitvbiB0aGUgc3RhY2suICBPciBpZiB0aGV5IHdlcmUKKworICAgIEE6NTAwICBCOjQwMDogIEM6MTAwMAorCit0aGVuIEEgaXMgbWVyZ2VkIHdpdGggQiwgbGVhdmluZworCisgICAgQUI6OTAwICBDOjEwMDAKKworb24gdGhlIHN0YWNrLgorCitJbiBib3RoIGV4YW1wbGVzLCB0aGUgc3RhY2sgY29uZmlndXJhdGlvbiBhZnRlciB0aGUgbWVyZ2Ugc3RpbGwgdmlvbGF0ZXMKK2ludmFyaWFudCAjMiwgYW5kIG1lcmdlX2NvbGxhcHNlKCkgZ29lcyBvbiB0byBjb250aW51ZSBtZXJnaW5nIHJ1bnMgdW50aWwKK2JvdGggaW52YXJpYW50cyBhcmUgc2F0aXNmaWVkLiAgQXMgYW4gZXh0cmVtZSBjYXNlLCBzdXBwb3NlIHdlIGRpZG4ndCBkbyB0aGUKK21pbnJ1biBnaW1taWNrLCBhbmQgbmF0dXJhbCBydW5zIHdlcmUgb2YgbGVuZ3RocyAxMjgsIDY0LCAzMiwgMTYsIDgsIDQsIDIsCithbmQgMi4gIE5vdGhpbmcgd291bGQgZ2V0IG1lcmdlZCB1bnRpbCB0aGUgZmluYWwgMiB3YXMgc2VlbiwgYW5kIHRoYXQgd291bGQKK3RyaWdnZXIgNyBwZXJmZWN0bHkgYmFsYW5jZWQgbWVyZ2VzLgorCitUaGUgdGhydXN0IG9mIHRoZXNlIHJ1bGVzIHdoZW4gdGhleSB0cmlnZ2VyIG1lcmdpbmcgaXMgdG8gYmFsYW5jZSB0aGUgcnVuCitsZW5ndGhzIGFzIGNsb3NlbHkgYXMgcG9zc2libGUsIHdoaWxlIGtlZXBpbmcgYSBsb3cgYm91bmQgb24gdGhlIG51bWJlciBvZgorcnVucyB3ZSBoYXZlIHRvIHJlbWVtYmVyLiAgVGhpcyBpcyBtYXhpbWFsbHkgZWZmZWN0aXZlIGZvciByYW5kb20gZGF0YSwKK3doZXJlIGFsbCBydW5zIGFyZSBsaWtlbHkgdG8gYmUgb2YgKGFydGlmaWNpYWxseSBmb3JjZWQpIGxlbmd0aCBtaW5ydW4sIGFuZAordGhlbiB3ZSBnZXQgYSBzZXF1ZW5jZSBvZiBwZXJmZWN0bHkgYmFsYW5jZWQgbWVyZ2VzICh3aXRoLCBwZXJoYXBzLCBzb21lCitvZGRiYWxscyBhdCB0aGUgZW5kKS4KKworT1RPSCwgb25lIHJlYXNvbiB0aGlzIHNvcnQgaXMgc28gZ29vZCBmb3IgcGFydGx5IG9yZGVyZWQgZGF0YSBoYXMgdG8gZG8KK3dpdGggd2lsZGx5IHVuYmFsYW5jZWQgcnVuIGxlbmd0aHMuCisKKworTWVyZ2UgTWVtb3J5CistLS0tLS0tLS0tLS0KK01lcmdpbmcgYWRqYWNlbnQgcnVucyBvZiBsZW5ndGhzIEEgYW5kIEIgaW4tcGxhY2UgaXMgdmVyeSBkaWZmaWN1bHQuCitUaGVvcmV0aWNhbCBjb25zdHJ1Y3Rpb25zIGFyZSBrbm93biB0aGF0IGNhbiBkbyBpdCwgYnV0IHRoZXkncmUgdG9vIGRpZmZpY3VsdAorYW5kIHNsb3cgZm9yIHByYWN0aWNhbCB1c2UuICBCdXQgaWYgd2UgaGF2ZSB0ZW1wIG1lbW9yeSBlcXVhbCB0byBtaW4oQSwgQiksCitpdCdzIGVhc3kuCisKK0lmIEEgaXMgc21hbGxlciAoZnVuY3Rpb24gbWVyZ2VfbG8pLCBjb3B5IEEgdG8gYSB0ZW1wIGFycmF5LCBsZWF2ZSBCIGFsb25lLAorYW5kIHRoZW4gd2UgY2FuIGRvIHRoZSBvYnZpb3VzIG1lcmdlIGFsZ29yaXRobSBsZWZ0IHRvIHJpZ2h0LCBmcm9tIHRoZSB0ZW1wCithcmVhIGFuZCBCLCBzdGFydGluZyB0aGUgc3RvcmVzIGludG8gd2hlcmUgQSB1c2VkIHRvIGxpdmUuICBUaGVyZSdzIGFsd2F5cyBhCitmcmVlIGFyZWEgaW4gdGhlIG9yaWdpbmFsIGFyZWEgY29tcHJpc2luZyBhIG51bWJlciBvZiBlbGVtZW50cyBlcXVhbCB0byB0aGUKK251bWJlciBub3QgeWV0IG1lcmdlZCBmcm9tIHRoZSB0ZW1wIGFycmF5ICh0cml2aWFsbHkgdHJ1ZSBhdCB0aGUgc3RhcnQ7Citwcm9jZWVkIGJ5IGluZHVjdGlvbikuICBUaGUgb25seSB0cmlja3kgYml0IGlzIHRoYXQgaWYgYSBjb21wYXJpc29uIHJhaXNlcyBhbgorZXhjZXB0aW9uLCB3ZSBoYXZlIHRvIHJlbWVtYmVyIHRvIGNvcHkgdGhlIHJlbWFpbmluZyBlbGVtZW50cyBiYWNrIGluIGZyb20KK3RoZSB0ZW1wIGFyZWEsIGxlc3QgdGhlIGFycmF5IGVuZCB1cCB3aXRoIGR1cGxpY2F0ZSBlbnRyaWVzIGZyb20gQi4gIEJ1dAordGhhdCdzIGV4YWN0bHkgdGhlIHNhbWUgdGhpbmcgd2UgbmVlZCB0byBkbyBpZiB3ZSByZWFjaCB0aGUgZW5kIG9mIEIgZmlyc3QsCitzbyB0aGUgZXhpdCBjb2RlIGlzIHBsZWFzYW50bHkgY29tbW9uIHRvIGJvdGggdGhlIG5vcm1hbCBhbmQgZXJyb3IgY2FzZXMuCisKK0lmIEIgaXMgc21hbGxlciAoZnVuY3Rpb24gbWVyZ2VfaGksIHdoaWNoIGlzIG1lcmdlX2xvJ3MgIm1pcnJvciBpbWFnZSIpLAorbXVjaCB0aGUgc2FtZSwgZXhjZXB0IHRoYXQgd2UgbmVlZCB0byBtZXJnZSByaWdodCB0byBsZWZ0LCBjb3B5aW5nIEIgaW50byBhCit0ZW1wIGFycmF5IGFuZCBzdGFydGluZyB0aGUgc3RvcmVzIGF0IHRoZSByaWdodCBlbmQgb2Ygd2hlcmUgQiB1c2VkIHRvIGxpdmUuCisKK0EgcmVmaW5lbWVudDogIFdoZW4gd2UncmUgYWJvdXQgdG8gbWVyZ2UgYWRqYWNlbnQgcnVucyBBIGFuZCBCLCB3ZSBmaXJzdCBkbworYSBmb3JtIG9mIGJpbmFyeSBzZWFyY2ggKG1vcmUgb24gdGhhdCBsYXRlcikgdG8gc2VlIHdoZXJlIEJbMF0gc2hvdWxkIGVuZCB1cAoraW4gQS4gIEVsZW1lbnRzIGluIEEgcHJlY2VkaW5nIHRoYXQgcG9pbnQgYXJlIGFscmVhZHkgaW4gdGhlaXIgZmluYWwKK3Bvc2l0aW9ucywgZWZmZWN0aXZlbHkgc2hyaW5raW5nIHRoZSBzaXplIG9mIEEuICBMaWtld2lzZSB3ZSBhbHNvIHNlYXJjaCB0bworc2VlIHdoZXJlIEFbLTFdIHNob3VsZCBlbmQgdXAgaW4gQiwgYW5kIGVsZW1lbnRzIG9mIEIgYWZ0ZXIgdGhhdCBwb2ludCBjYW4KK2Fsc28gYmUgaWdub3JlZC4gIFRoaXMgY3V0cyB0aGUgYW1vdW50IG9mIHRlbXAgbWVtb3J5IG5lZWRlZCBieSB0aGUgc2FtZQorYW1vdW50LgorCitUaGVzZSBwcmVsaW1pbmFyeSBzZWFyY2hlcyBtYXkgbm90IHBheSBvZmYsIGFuZCBjYW4gYmUgZXhwZWN0ZWQgKm5vdCogdG8KK3JlcGF5IHRoZWlyIGNvc3QgaWYgdGhlIGRhdGEgaXMgcmFuZG9tLiAgQnV0IHRoZXkgY2FuIHdpbiBodWdlIGluIGFsbCBvZgordGltZSwgY29weWluZywgYW5kIG1lbW9yeSBzYXZpbmdzIHdoZW4gdGhleSBkbyBwYXksIHNvIHRoaXMgaXMgb25lIG9mIHRoZQorInBlci1tZXJnZSBvdmVyaGVhZHMiIG1lbnRpb25lZCBhYm92ZSB0aGF0IHdlJ3JlIGhhcHB5IHRvIGVuZHVyZSBiZWNhdXNlCit0aGVyZSBpcyBhdCBtb3N0IG9uZSB2ZXJ5IHNob3J0IHJ1bi4gIEl0J3MgZ2VuZXJhbGx5IHRydWUgaW4gdGhpcyBhbGdvcml0aG0KK3RoYXQgd2UncmUgd2lsbGluZyB0byBnYW1ibGUgYSBsaXR0bGUgdG8gd2luIGEgbG90LCBldmVuIHRob3VnaCB0aGUgbmV0CitleHBlY3RhdGlvbiBpcyBuZWdhdGl2ZSBmb3IgcmFuZG9tIGRhdGEuCisKKworTWVyZ2UgQWxnb3JpdGhtcworLS0tLS0tLS0tLS0tLS0tLQorbWVyZ2VfbG8oKSBhbmQgbWVyZ2VfaGkoKSBhcmUgd2hlcmUgdGhlIGJ1bGsgb2YgdGhlIHRpbWUgaXMgc3BlbnQuICBtZXJnZV9sbworZGVhbHMgd2l0aCBydW5zIHdoZXJlIEEgPD0gQiwgYW5kIG1lcmdlX2hpIHdoZXJlIEEgPiBCLiAgVGhleSBkb24ndCBrbm93Cit3aGV0aGVyIHRoZSBkYXRhIGlzIGNsdXN0ZXJlZCBvciB1bmlmb3JtLCBidXQgYSBsb3ZlbHkgdGhpbmcgYWJvdXQgbWVyZ2luZworaXMgdGhhdCBtYW55IGtpbmRzIG9mIGNsdXN0ZXJpbmcgInJldmVhbCB0aGVtc2VsdmVzIiBieSBob3cgbWFueSB0aW1lcyBpbiBhCityb3cgdGhlIHdpbm5pbmcgbWVyZ2UgZWxlbWVudCBjb21lcyBmcm9tIHRoZSBzYW1lIHJ1bi4gIFdlJ2xsIG9ubHkgZGlzY3VzcworbWVyZ2VfbG8gaGVyZTsgbWVyZ2VfaGkgaXMgZXhhY3RseSBhbmFsb2dvdXMuCisKK01lcmdpbmcgYmVnaW5zIGluIHRoZSB1c3VhbCwgb2J2aW91cyB3YXksIGNvbXBhcmluZyB0aGUgZmlyc3QgZWxlbWVudCBvZiBBCit0byB0aGUgZmlyc3Qgb2YgQiwgYW5kIG1vdmluZyBCWzBdIHRvIHRoZSBtZXJnZSBhcmVhIGlmIGl0J3MgbGVzcyB0aGFuIEFbMF0sCitlbHNlIG1vdmluZyBBWzBdIHRvIHRoZSBtZXJnZSBhcmVhLiAgQ2FsbCB0aGF0IHRoZSAib25lIHBhaXIgYXQgYSB0aW1lIgorbW9kZS4gIFRoZSBvbmx5IHR3aXN0IGhlcmUgaXMga2VlcGluZyB0cmFjayBvZiBob3cgbWFueSB0aW1lcyBpbiBhIHJvdyAidGhlCit3aW5uZXIiIGNvbWVzIGZyb20gdGhlIHNhbWUgcnVuLgorCitJZiB0aGF0IGNvdW50IHJlYWNoZXMgTUlOX0dBTExPUCwgd2Ugc3dpdGNoIHRvICJnYWxsb3BpbmcgbW9kZSIuICBIZXJlCit3ZSAqc2VhcmNoKiBCIGZvciB3aGVyZSBBWzBdIGJlbG9uZ3MsIGFuZCBtb3ZlIG92ZXIgYWxsIHRoZSBCJ3MgYmVmb3JlCit0aGF0IHBvaW50IGluIG9uZSBjaHVuayB0byB0aGUgbWVyZ2UgYXJlYSwgdGhlbiBtb3ZlIEFbMF0gdG8gdGhlIG1lcmdlCithcmVhLiAgVGhlbiB3ZSBzZWFyY2ggQSBmb3Igd2hlcmUgQlswXSBiZWxvbmdzLCBhbmQgc2ltaWxhcmx5IG1vdmUgYQorc2xpY2Ugb2YgQSBpbiBvbmUgY2h1bmsuICBUaGVuIGJhY2sgdG8gc2VhcmNoaW5nIEIgZm9yIHdoZXJlIEFbMF0gYmVsb25ncywKK2V0Yy4gIFdlIHN0YXkgaW4gZ2FsbG9waW5nIG1vZGUgdW50aWwgYm90aCBzZWFyY2hlcyBmaW5kIHNsaWNlcyB0byBjb3B5CitsZXNzIHRoYW4gTUlOX0dBTExPUCBlbGVtZW50cyBsb25nLCBhdCB3aGljaCBwb2ludCB3ZSBnbyBiYWNrIHRvIG9uZS1wYWlyLQorYXQtYS10aW1lIG1vZGUuCisKK0EgcmVmaW5lbWVudDogIFRoZSBNZXJnZVN0YXRlIHN0cnVjdCBjb250YWlucyB0aGUgdmFsdWUgb2YgbWluX2dhbGxvcCB0aGF0Citjb250cm9scyB3aGVuIHdlIGVudGVyIGdhbGxvcGluZyBtb2RlLCBpbml0aWFsaXplZCB0byBNSU5fR0FMTE9QLgorbWVyZ2VfbG8oKSBhbmQgbWVyZ2VfaGkoKSBhZGp1c3QgdGhpcyBoaWdoZXIgd2hlbiBnYWxsb3BpbmcgaXNuJ3QgcGF5aW5nCitvZmYsIGFuZCBsb3dlciB3aGVuIGl0IGlzLgorCisKK0dhbGxvcGluZworLS0tLS0tLS0tCitTdGlsbCB3aXRob3V0IGxvc3Mgb2YgZ2VuZXJhbGl0eSwgYXNzdW1lIEEgaXMgdGhlIHNob3J0ZXIgcnVuLiAgSW4gZ2FsbG9waW5nCittb2RlLCB3ZSBmaXJzdCBsb29rIGZvciBBWzBdIGluIEIuICBXZSBkbyB0aGlzIHZpYSAiZ2FsbG9waW5nIiwgY29tcGFyaW5nCitBWzBdIGluIHR1cm4gdG8gQlswXSwgQlsxXSwgQlszXSwgQls3XSwgLi4uLCBCWzIqKmogLSAxXSwgLi4uLCB1bnRpbCBmaW5kaW5nCit0aGUgayBzdWNoIHRoYXQgQlsyKiooay0xKSAtIDFdIDwgQVswXSA8PSBCWzIqKmsgLSAxXS4gIFRoaXMgdGFrZXMgYXQgbW9zdAorcm91Z2hseSBsZyhCKSBjb21wYXJpc29ucywgYW5kLCB1bmxpa2UgYSBzdHJhaWdodCBiaW5hcnkgc2VhcmNoLCBmYXZvcnMKK2ZpbmRpbmcgdGhlIHJpZ2h0IHNwb3QgZWFybHkgaW4gQiAobW9yZSBvbiB0aGF0IGxhdGVyKS4KKworQWZ0ZXIgZmluZGluZyBzdWNoIGEgaywgdGhlIHJlZ2lvbiBvZiB1bmNlcnRhaW50eSBpcyByZWR1Y2VkIHRvIDIqKihrLTEpIC0gMQorY29uc2VjdXRpdmUgZWxlbWVudHMsIGFuZCBhIHN0cmFpZ2h0IGJpbmFyeSBzZWFyY2ggcmVxdWlyZXMgZXhhY3RseSBrLTEKK2FkZGl0aW9uYWwgY29tcGFyaXNvbnMgdG8gbmFpbCBpdC4gIFRoZW4gd2UgY29weSBhbGwgdGhlIEIncyB1cCB0byB0aGF0Citwb2ludCBpbiBvbmUgY2h1bmssIGFuZCB0aGVuIGNvcHkgQVswXS4gIE5vdGUgdGhhdCBubyBtYXR0ZXIgd2hlcmUgQVswXQorYmVsb25ncyBpbiBCLCB0aGUgY29tYmluYXRpb24gb2YgZ2FsbG9waW5nICsgYmluYXJ5IHNlYXJjaCBmaW5kcyBpdCBpbiBubworbW9yZSB0aGFuIGFib3V0IDIqbGcoQikgY29tcGFyaXNvbnMuCisKK0lmIHdlIGRpZCBhIHN0cmFpZ2h0IGJpbmFyeSBzZWFyY2gsIHdlIGNvdWxkIGZpbmQgaXQgaW4gbm8gbW9yZSB0aGFuCitjZWlsaW5nKGxnKEIrMSkpIGNvbXBhcmlzb25zIC0tIGJ1dCBzdHJhaWdodCBiaW5hcnkgc2VhcmNoIHRha2VzIHRoYXQgbWFueQorY29tcGFyaXNvbnMgbm8gbWF0dGVyIHdoZXJlIEFbMF0gYmVsb25ncy4gIFN0cmFpZ2h0IGJpbmFyeSBzZWFyY2ggdGh1cyBsb3NlcwordG8gZ2FsbG9waW5nIHVubGVzcyB0aGUgcnVuIGlzIHF1aXRlIGxvbmcsIGFuZCB3ZSBzaW1wbHkgY2FuJ3QgZ3Vlc3MKK3doZXRoZXIgaXQgaXMgaW4gYWR2YW5jZS4KKworSWYgZGF0YSBpcyByYW5kb20gYW5kIHJ1bnMgaGF2ZSB0aGUgc2FtZSBsZW5ndGgsIEFbMF0gYmVsb25ncyBhdCBCWzBdIGhhbGYKK3RoZSB0aW1lLCBhdCBCWzFdIGEgcXVhcnRlciBvZiB0aGUgdGltZSwgYW5kIHNvIG9uOiAgYSBjb25zZWN1dGl2ZSB3aW5uaW5nCitzdWItcnVuIGluIEIgb2YgbGVuZ3RoIGsgb2NjdXJzIHdpdGggcHJvYmFiaWxpdHkgMS8yKiooaysxKS4gIFNvIGxvbmcKK3dpbm5pbmcgc3ViLXJ1bnMgYXJlIGV4dHJlbWVseSB1bmxpa2VseSBpbiByYW5kb20gZGF0YSwgYW5kIGd1ZXNzaW5nIHRoYXQgYQord2lubmluZyBzdWItcnVuIGlzIGdvaW5nIHRvIGJlIGxvbmcgaXMgYSBkYW5nZXJvdXMgZ2FtZS4KKworT1RPSCwgaWYgZGF0YSBpcyBsb3BzaWRlZCBvciBsdW1weSBvciBjb250YWlucyBtYW55IGR1cGxpY2F0ZXMsIGxvbmcKK3N0cmV0Y2hlcyBvZiB3aW5uaW5nIHN1Yi1ydW5zIGFyZSB2ZXJ5IGxpa2VseSwgYW5kIGN1dHRpbmcgdGhlIG51bWJlciBvZgorY29tcGFyaXNvbnMgbmVlZGVkIHRvIGZpbmQgb25lIGZyb20gTyhCKSB0byBPKGxvZyBCKSBpcyBhIGh1Z2Ugd2luLgorCitHYWxsb3BpbmcgY29tcHJvbWlzZXMgYnkgZ2V0dGluZyBvdXQgZmFzdCBpZiB0aGVyZSBpc24ndCBhIGxvbmcgd2lubmluZworc3ViLXJ1biwgeWV0IGZpbmRpbmcgc3VjaCB2ZXJ5IGVmZmljaWVudGx5IHdoZW4gdGhleSBleGlzdC4KKworSSBmaXJzdCBsZWFybmVkIGFib3V0IHRoZSBnYWxsb3Bpbmcgc3RyYXRlZ3kgaW4gYSByZWxhdGVkIGNvbnRleHQ7IHNlZToKKworICAgICJBZGFwdGl2ZSBTZXQgSW50ZXJzZWN0aW9ucywgVW5pb25zLCBhbmQgRGlmZmVyZW5jZXMiICgyMDAwKQorICAgIEVyaWsgRC4gRGVtYWluZSwgQWxlamFuZHJvIEzzcGV6LU9ydGl6LCBKLiBJYW4gTXVucm8KKworYW5kIGl0cyBmb2xsb3d1cChzKS4gIEFuIGVhcmxpZXIgcGFwZXIgY2FsbGVkIHRoZSBzYW1lIHN0cmF0ZWd5CisiZXhwb25lbnRpYWwgc2VhcmNoIjoKKworICAgIk9wdGltaXN0aWMgU29ydGluZyBhbmQgSW5mb3JtYXRpb24gVGhlb3JldGljIENvbXBsZXhpdHkiCisgICBQZXRlciBNY0lscm95CisgICBTT0RBIChGb3VydGggQW5udWFsIEFDTS1TSUFNIFN5bXBvc2l1bSBvbiBEaXNjcmV0ZSBBbGdvcml0aG1zKSwgcHAKKyAgIDQ2Ny00NzQsIEF1c3RpbiwgVGV4YXMsIDI1LTI3IEphbnVhcnkgMTk5My4KKworYW5kIGl0IHByb2JhYmx5IGRhdGVzIGJhY2sgdG8gYW4gZWFybGllciBwYXBlciBieSBCZW50bGV5IGFuZCBZYW8uICBUaGUKK01jSWxyb3kgcGFwZXIgaW4gcGFydGljdWxhciBoYXMgZ29vZCBhbmFseXNpcyBvZiBhIG1lcmdlc29ydCB0aGF0J3MKK3Byb2JhYmx5IHN0cm9uZ2x5IHJlbGF0ZWQgdG8gdGhpcyBvbmUgaW4gaXRzIGdhbGxvcGluZyBzdHJhdGVneS4KKworCitHYWxsb3Bpbmcgd2l0aCBhIEJyb2tlbiBMZWcKKy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorU28gd2h5IGRvbid0IHdlIGFsd2F5cyBnYWxsb3A/ICBCZWNhdXNlIGl0IGNhbiBsb3NlLCBvbiB0d28gY291bnRzOgorCisxLiBXaGlsZSB3ZSdyZSB3aWxsaW5nIHRvIGVuZHVyZSBzbWFsbCBwZXItbWVyZ2Ugb3ZlcmhlYWRzLCBwZXItY29tcGFyaXNvbgorICAgb3ZlcmhlYWRzIGFyZSBhIGRpZmZlcmVudCBzdG9yeS4gIENhbGxpbmcgWWV0IEFub3RoZXIgRnVuY3Rpb24gcGVyCisgICBjb21wYXJpc29uIGlzIGV4cGVuc2l2ZSwgYW5kIGdhbGxvcF9sZWZ0KCkgYW5kIGdhbGxvcF9yaWdodCgpIGFyZQorICAgdG9vIGxvbmctd2luZGVkIGZvciBzYW5lIGlubGluaW5nLgorCisyLiBHYWxsb3BpbmcgY2FuLS0gYWxhcyAtLXJlcXVpcmUgbW9yZSBjb21wYXJpc29ucyB0aGFuIGxpbmVhciBvbmUtYXQtdGltZQorICAgc2VhcmNoLCBkZXBlbmRpbmcgb24gdGhlIGRhdGEuCisKKyMyIHJlcXVpcmVzIGRldGFpbHMuICBJZiBBWzBdIGJlbG9uZ3MgYmVmb3JlIEJbMF0sIGdhbGxvcGluZyByZXF1aXJlcyAxCitjb21wYXJlIHRvIGRldGVybWluZSB0aGF0LCBzYW1lIGFzIGxpbmVhciBzZWFyY2gsIGV4Y2VwdCBpdCBjb3N0cyBtb3JlCit0byBjYWxsIHRoZSBnYWxsb3AgZnVuY3Rpb24uICBJZiBBWzBdIGJlbG9uZ3MgcmlnaHQgYmVmb3JlIEJbMV0sIGdhbGxvcGluZworcmVxdWlyZXMgMiBjb21wYXJlcywgYWdhaW4gc2FtZSBhcyBsaW5lYXIgc2VhcmNoLiAgT24gdGhlIHRoaXJkIGNvbXBhcmUsCitnYWxsb3BpbmcgY2hlY2tzIEFbMF0gYWdhaW5zdCBCWzNdLCBhbmQgaWYgaXQncyA8PSwgcmVxdWlyZXMgb25lIG1vcmUKK2NvbXBhcmUgdG8gZGV0ZXJtaW5lIHdoZXRoZXIgQVswXSBiZWxvbmdzIGF0IEJbMl0gb3IgQlszXS4gIFRoYXQncyBhIHRvdGFsCitvZiA0IGNvbXBhcmVzLCBidXQgaWYgQVswXSBkb2VzIGJlbG9uZyBhdCBCWzJdLCBsaW5lYXIgc2VhcmNoIHdvdWxkIGhhdmUKK2Rpc2NvdmVyZWQgdGhhdCBpbiBvbmx5IDMgY29tcGFyZXMsIGFuZCB0aGF0J3MgYSBodWdlIGxvc3MhICBSZWFsbHkuICBJdCdzCithbiBpbmNyZWFzZSBvZiAzMyUgaW4gdGhlIG51bWJlciBvZiBjb21wYXJlcyBuZWVkZWQsIGFuZCBjb21wYXJpc29ucyBhcmUKK2V4cGVuc2l2ZSBpbiBQeXRob24uCisKK2luZGV4IGluIEIgd2hlcmUgICAgIyBjb21wYXJlcyBsaW5lYXIgICMgZ2FsbG9wICAjIGJpbmFyeSAgZ2FsbG9wCitBWzBdIGJlbG9uZ3MgICAgICAgIHNlYXJjaCBuZWVkcyAgICAgICBjb21wYXJlcyAgY29tcGFyZXMgIHRvdGFsCistLS0tLS0tLS0tLS0tLS0tICAgIC0tLS0tLS0tLS0tLS0tLS0tICAtLS0tLS0tLSAgLS0tLS0tLS0gIC0tLS0tLQorICAgICAgICAgICAgICAgMCAgICAgICAgICAgICAgICAgICAgMSAgICAgICAgIDEgICAgICAgICAwICAgICAgIDEKKworICAgICAgICAgICAgICAgMSAgICAgICAgICAgICAgICAgICAgMiAgICAgICAgIDIgICAgICAgICAwICAgICAgIDIKKworICAgICAgICAgICAgICAgMiAgICAgICAgICAgICAgICAgICAgMyAgICAgICAgIDMgICAgICAgICAxICAgICAgIDQKKyAgICAgICAgICAgICAgIDMgICAgICAgICAgICAgICAgICAgIDQgICAgICAgICAzICAgICAgICAgMSAgICAgICA0CisKKyAgICAgICAgICAgICAgIDQgICAgICAgICAgICAgICAgICAgIDUgICAgICAgICA0ICAgICAgICAgMiAgICAgICA2CisgICAgICAgICAgICAgICA1ICAgICAgICAgICAgICAgICAgICA2ICAgICAgICAgNCAgICAgICAgIDIgICAgICAgNgorICAgICAgICAgICAgICAgNiAgICAgICAgICAgICAgICAgICAgNyAgICAgICAgIDQgICAgICAgICAyICAgICAgIDYKKyAgICAgICAgICAgICAgIDcgICAgICAgICAgICAgICAgICAgIDggICAgICAgICA0ICAgICAgICAgMiAgICAgICA2CisKKyAgICAgICAgICAgICAgIDggICAgICAgICAgICAgICAgICAgIDkgICAgICAgICA1ICAgICAgICAgMyAgICAgICA4CisgICAgICAgICAgICAgICA5ICAgICAgICAgICAgICAgICAgIDEwICAgICAgICAgNSAgICAgICAgIDMgICAgICAgOAorICAgICAgICAgICAgICAxMCAgICAgICAgICAgICAgICAgICAxMSAgICAgICAgIDUgICAgICAgICAzICAgICAgIDgKKyAgICAgICAgICAgICAgMTEgICAgICAgICAgICAgICAgICAgMTIgICAgICAgICA1ICAgICAgICAgMyAgICAgICA4CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLi4uCisKK0luIGdlbmVyYWwsIGlmIEFbMF0gYmVsb25ncyBhdCBCW2ldLCBsaW5lYXIgc2VhcmNoIHJlcXVpcmVzIGkrMSBjb21wYXJpc29ucwordG8gZGV0ZXJtaW5lIHRoYXQsIGFuZCBnYWxsb3BpbmcgYSB0b3RhbCBvZiAyKmZsb29yKGxnKGkpKSsyIGNvbXBhcmlzb25zLgorVGhlIGFkdmFudGFnZSBvZiBnYWxsb3BpbmcgaXMgdW5ib3VuZGVkIGFzIGkgZ3Jvd3MsIGJ1dCBpdCBkb2Vzbid0IHdpbiBhdAorYWxsIHVudGlsIGk9Ni4gIEJlZm9yZSB0aGVuLCBpdCBsb3NlcyB0d2ljZSAoYXQgaT0yIGFuZCBpPTQpLCBhbmQgdGllcworYXQgdGhlIG90aGVyIHZhbHVlcy4gIEF0IGFuZCBhZnRlciBpPTYsIGdhbGxvcGluZyBhbHdheXMgd2lucy4KKworV2UgY2FuJ3QgZ3Vlc3MgaW4gYWR2YW5jZSB3aGVuIGl0J3MgZ29pbmcgdG8gd2luLCB0aG91Z2gsIHNvIHdlIGRvIG9uZSBwYWlyCithdCBhIHRpbWUgdW50aWwgdGhlIGV2aWRlbmNlIHNlZW1zIHN0cm9uZyB0aGF0IGdhbGxvcGluZyBtYXkgcGF5LiAgTUlOX0dBTExPUAoraXMgNywgYW5kIHRoYXQncyBwcmV0dHkgc3Ryb25nIGV2aWRlbmNlLiAgSG93ZXZlciwgaWYgdGhlIGRhdGEgaXMgcmFuZG9tLCBpdAorc2ltcGx5IHdpbGwgdHJpZ2dlciBnYWxsb3BpbmcgbW9kZSBwdXJlbHkgYnkgbHVjayBldmVyeSBub3cgYW5kIGFnYWluLCBhbmQKK2l0J3MgcXVpdGUgbGlrZWx5IHRvIGhpdCBvbmUgb2YgdGhlIGxvc2luZyBjYXNlcyBuZXh0LiAgT24gdGhlIG90aGVyIGhhbmQsCitpbiBjYXNlcyBsaWtlIH5zb3J0LCBnYWxsb3BpbmcgYWx3YXlzIHBheXMsIGFuZCBNSU5fR0FMTE9QIGlzIGxhcmdlciB0aGFuIGl0Cisic2hvdWxkIGJlIiB0aGVuLiAgU28gdGhlIE1lcmdlU3RhdGUgc3RydWN0IGtlZXBzIGEgbWluX2dhbGxvcCB2YXJpYWJsZQordGhhdCBtZXJnZV9sbyBhbmQgbWVyZ2VfaGkgYWRqdXN0OiAgdGhlIGxvbmdlciB3ZSBzdGF5IGluIGdhbGxvcGluZyBtb2RlLAordGhlIHNtYWxsZXIgbWluX2dhbGxvcCBnZXRzLCBtYWtpbmcgaXQgZWFzaWVyIHRvIHRyYW5zaXRpb24gYmFjayB0bworZ2FsbG9waW5nIG1vZGUgKGlmIHdlIGV2ZXIgbGVhdmUgaXQgaW4gdGhlIGN1cnJlbnQgbWVyZ2UsIGFuZCBhdCB0aGUKK3N0YXJ0IG9mIHRoZSBuZXh0IG1lcmdlKS4gIEJ1dCB3aGVuZXZlciB0aGUgZ2FsbG9wIGxvb3AgZG9lc24ndCBwYXksCittaW5fZ2FsbG9wIGlzIGluY3JlYXNlZCBieSBvbmUsIG1ha2luZyBpdCBoYXJkZXIgdG8gdHJhbnNpdGlvbiBiYWNrCit0byBnYWxsb3BpbmcgbW9kZSAoYW5kIGFnYWluIGJvdGggd2l0aGluIGEgbWVyZ2UgYW5kIGFjcm9zcyBtZXJnZXMpLiAgRm9yCityYW5kb20gZGF0YSwgdGhpcyBhbGwgYnV0IGVsaW1pbmF0ZXMgdGhlIGdhbGxvcCBwZW5hbHR5OiAgbWluX2dhbGxvcCBncm93cworbGFyZ2UgZW5vdWdoIHRoYXQgd2UgYWxtb3N0IG5ldmVyIGdldCBpbnRvIGdhbGxvcGluZyBtb2RlLiAgQW5kIGZvciBjYXNlcworbGlrZSB+c29ydCwgbWluX2dhbGxvcCBjYW4gZmFsbCB0byBhcyBsb3cgYXMgMS4gIFRoaXMgc2VlbXMgdG8gd29yayB3ZWxsLAorYnV0IGluIGFsbCBpdCdzIGEgbWlub3IgaW1wcm92ZW1lbnQgb3ZlciB1c2luZyBhIGZpeGVkIE1JTl9HQUxMT1AgdmFsdWUuCisKKworR2FsbG9waW5nIENvbXBsaWNhdGlvbgorLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorVGhlIGRlc2NyaXB0aW9uIGFib3ZlIHdhcyBmb3IgbWVyZ2VfbG8uICBtZXJnZV9oaSBoYXMgdG8gbWVyZ2UgImZyb20gdGhlCitvdGhlciBlbmQiLCBhbmQgcmVhbGx5IG5lZWRzIHRvIGdhbGxvcCBzdGFydGluZyBhdCB0aGUgbGFzdCBlbGVtZW50IGluIGEgcnVuCitpbnN0ZWFkIG9mIHRoZSBmaXJzdC4gIEdhbGxvcGluZyBmcm9tIHRoZSBmaXJzdCBzdGlsbCB3b3JrcywgYnV0IGRvZXMgbW9yZQorY29tcGFyaXNvbnMgdGhhbiBpdCBzaG91bGQgKHRoaXMgaXMgc2lnbmlmaWNhbnQgLS0gSSB0aW1lZCBpdCBib3RoIHdheXMpLgorRm9yIHRoaXMgcmVhc29uLCB0aGUgZ2FsbG9wX2xlZnQoKSBhbmQgZ2FsbG9wX3JpZ2h0KCkgZnVuY3Rpb25zIGhhdmUgYQorImhpbnQiIGFyZ3VtZW50LCB3aGljaCBpcyB0aGUgaW5kZXggYXQgd2hpY2ggZ2FsbG9waW5nIHNob3VsZCBiZWdpbi4gIFNvCitnYWxsb3BpbmcgY2FuIGFjdHVhbGx5IHN0YXJ0IGF0IGFueSBpbmRleCwgYW5kIHByb2NlZWQgYXQgb2Zmc2V0cyBvZiAxLCAzLAorNywgMTUsIC4uLiBvciAtMSwgLTMsIC03LCAtMTUsIC4uLiBmcm9tIHRoZSBzdGFydGluZyBpbmRleC4KKworSW4gdGhlIGNvZGUgYXMgSSB0eXBlIGl0J3MgYWx3YXlzIGNhbGxlZCB3aXRoIGVpdGhlciAwIG9yIG4tMSAod2hlcmUgbiBpcwordGhlICMgb2YgZWxlbWVudHMgaW4gYSBydW4pLiAgSXQncyB0ZW1wdGluZyB0byB0cnkgdG8gZG8gc29tZXRoaW5nIGZhbmNpZXIsCittZWxkaW5nIGdhbGxvcGluZyB3aXRoIHNvbWUgZm9ybSBvZiBpbnRlcnBvbGF0aW9uIHNlYXJjaDsgZm9yIGV4YW1wbGUsIGlmCit3ZSdyZSBtZXJnaW5nIGEgcnVuIG9mIGxlbmd0aCAxIHdpdGggYSBydW4gb2YgbGVuZ3RoIDEwMDAwLCBpbmRleCA1MDAwIGlzCitwcm9iYWJseSBhIGJldHRlciBndWVzcyBhdCB0aGUgZmluYWwgcmVzdWx0IHRoYW4gZWl0aGVyIDAgb3IgOTk5OS4gIEJ1dAoraXQncyB1bmNsZWFyIGhvdyB0byBnZW5lcmFsaXplIHRoYXQgaW50dWl0aW9uIHVzZWZ1bGx5LCBhbmQgbWVyZ2luZyBvZgord2lsZGx5IHVuYmFsYW5jZWQgcnVucyBhbHJlYWR5IGVuam95cyBleGNlbGxlbnQgcGVyZm9ybWFuY2UuCisKK35zb3J0IGlzIGEgZ29vZCBleGFtcGxlIG9mIHdoZW4gYmFsYW5jZWQgcnVucyBjb3VsZCBiZW5lZml0IGZyb20gYSBiZXR0ZXIKK2hpbnQgdmFsdWU6ICB0byB0aGUgZXh0ZW50IHBvc3NpYmxlLCB0aGlzIHdvdWxkIGxpa2UgdG8gdXNlIGEgc3RhcnRpbmcKK29mZnNldCBlcXVhbCB0byB0aGUgcHJldmlvdXMgdmFsdWUgb2YgYWNvdW50L2Jjb3VudC4gIERvaW5nIHNvIHNhdmVzIGFib3V0CisxMCUgb2YgdGhlIGNvbXBhcmVzIGluIH5zb3J0LiAgSG93ZXZlciwgZG9pbmcgc28gaXMgYWxzbyBhIG1peGVkIGJhZywKK2h1cnRpbmcgb3RoZXIgY2FzZXMuCisKKworQ29tcGFyaW5nIEF2ZXJhZ2UgIyBvZiBDb21wYXJlcyBvbiBSYW5kb20gQXJyYXlzCistLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KK1tOT1RFOiAgVGhpcyB3YXMgZG9uZSB3aGVuIHRoZSBuZXcgYWxnb3JpdGhtIHVzZWQgYWJvdXQgMC4xJSBtb3JlIGNvbXBhcmVzCisgb24gcmFuZG9tIGRhdGEgdGhhbiBkb2VzIGl0cyBjdXJyZW50IGluY2FybmF0aW9uLl0KKworSGVyZSBsaXN0LnNvcnQoKSBpcyBzYW1wbGVzb3J0LCBhbmQgbGlzdC5tc29ydCgpIHRoaXMgc29ydDoKKworIiIiCitpbXBvcnQgcmFuZG9tCitmcm9tIHRpbWUgaW1wb3J0IGNsb2NrIGFzIG5vdworCitkZWYgZmlsbChuKToKKyAgICBmcm9tIHJhbmRvbSBpbXBvcnQgcmFuZG9tCisgICAgcmV0dXJuIFtyYW5kb20oKSBmb3IgaSBpbiB4cmFuZ2UobildCisKK2RlZiBteWNtcCh4LCB5KToKKyAgICBnbG9iYWwgbmNtcAorICAgIG5jbXAgKz0gMQorICAgIHJldHVybiBjbXAoeCwgeSkKKworZGVmIHRpbWVpdCh2YWx1ZXMsIG1ldGhvZCk6CisgICAgZ2xvYmFsIG5jbXAKKyAgICBYID0gdmFsdWVzWzpdCisgICAgYm91bmQgPSBnZXRhdHRyKFgsIG1ldGhvZCkKKyAgICBuY21wID0gMAorICAgIHQxID0gbm93KCkKKyAgICBib3VuZChteWNtcCkKKyAgICB0MiA9IG5vdygpCisgICAgcmV0dXJuIHQyLXQxLCBuY21wCisKK2Zvcm1hdCA9ICIlNXMgICU5LjJmICAlMTFkIgorZjIgICAgID0gIiU1cyAgJTkuMmYgICUxMS4yZiIKKworZGVmIGRyaXZlKCk6CisgICAgY291bnQgPSBzc3QgPSBzc2NtcCA9IG1zdCA9IG1zY21wID0gbmVsdHMgPSAwCisgICAgd2hpbGUgVHJ1ZToKKyAgICAgICAgbiA9IHJhbmRvbS5yYW5kcmFuZ2UoMTAwMDAwKQorICAgICAgICBuZWx0cyArPSBuCisgICAgICAgIHggPSBmaWxsKG4pCisKKyAgICAgICAgdCwgYyA9IHRpbWVpdCh4LCAnc29ydCcpCisgICAgICAgIHNzdCArPSB0CisgICAgICAgIHNzY21wICs9IGMKKworICAgICAgICB0LCBjID0gdGltZWl0KHgsICdtc29ydCcpCisgICAgICAgIG1zdCArPSB0CisgICAgICAgIG1zY21wICs9IGMKKworICAgICAgICBjb3VudCArPSAxCisgICAgICAgIGlmIGNvdW50ICUgMTA6CisgICAgICAgICAgICBjb250aW51ZQorCisgICAgICAgIHByaW50ICJjb3VudCIsIGNvdW50LCAibmVsdHMiLCBuZWx0cworICAgICAgICBwcmludCBmb3JtYXQgJSAoInNvcnQiLCAgc3N0LCBzc2NtcCkKKyAgICAgICAgcHJpbnQgZm9ybWF0ICUgKCJtc29ydCIsIG1zdCwgbXNjbXApCisgICAgICAgIHByaW50IGYyICAgICAlICgiIiwgKHNzdC1tc3QpKjFlMi9tc3QsIChzc2NtcC1tc2NtcCkqMWUyL21zY21wKQorCitkcml2ZSgpCisiIiIKKworSSByYW4gdGhpcyBvbiBXaW5kb3dzIGFuZCBrZXB0IHVzaW5nIHRoZSBjb21wdXRlciBsaWdodGx5IHdoaWxlIGl0IHdhcworcnVubmluZy4gIHRpbWUuY2xvY2soKSBpcyB3YWxsLWNsb2NrIHRpbWUgb24gV2luZG93cywgd2l0aCBiZXR0ZXIgdGhhbgorbWljcm9zZWNvbmQgcmVzb2x1dGlvbi4gIHNhbXBsZXNvcnQgc3RhcnRlZCB3aXRoIGEgMS41MiUgIy1vZi1jb21wYXJpc29ucworZGlzYWR2YW50YWdlLCBmZWxsIHF1aWNrbHkgdG8gMS40OCUsIGFuZCB0aGVuIGZsdWN0dWF0ZWQgd2l0aGluIHRoYXQgc21hbGwKK3JhbmdlLiAgSGVyZSdzIHRoZSBsYXN0IGNodW5rIG9mIG91dHB1dCBiZWZvcmUgSSBraWxsZWQgdGhlIGpvYjoKKworY291bnQgMjYzMCBuZWx0cyAxMzA5MDY1NDMKKyBzb3J0ICAgIDYxMTAuODAgICAxOTM3ODg3NTczCittc29ydCAgICA2MDAyLjc4ICAgMTkwOTM4OTM4MQorICAgICAgICAgICAgMS44MCAgICAgICAgIDEuNDkKKworV2UndmUgZG9uZSBuZWFybHkgMiBiaWxsaW9uIGNvbXBhcmlzb25zIGFwaWVjZSBhdCBQeXRob24gc3BlZWQgdGhlcmUsIGFuZAordGhhdCdzIGVub3VnaCA8d2luaz4uCisKK0ZvciByYW5kb20gYXJyYXlzIG9mIHNpemUgMiAoeWVzLCB0aGVyZSBhcmUgb25seSAyIGludGVyZXN0aW5nIG9uZXMpLAorc2FtcGxlc29ydCBoYXMgYSA1MCUoISkgY29tcGFyaXNvbiBkaXNhZHZhbnRhZ2UuICBUaGlzIGlzIGEgY29uc2VxdWVuY2Ugb2YKK3NhbXBsZXNvcnQgc3BlY2lhbC1jYXNpbmcgYXQgbW9zdCBvbmUgYXNjZW5kaW5nIHJ1biBhdCB0aGUgc3RhcnQsIHRoZW4KK2ZhbGxpbmcgYmFjayB0byB0aGUgZ2VuZXJhbCBjYXNlIGlmIGl0IGRvZXNuJ3QgZmluZCBhbiBhc2NlbmRpbmcgcnVuCitpbW1lZGlhdGVseS4gIFRoZSBjb25zZXF1ZW5jZSBpcyB0aGF0IGl0IGVuZHMgdXAgdXNpbmcgdHdvIGNvbXBhcmVzIHRvIHNvcnQKK1syLCAxXS4gIEdyYXRpZnlpbmdseSwgdGltc29ydCBkb2Vzbid0IGRvIGFueSBzcGVjaWFsLWNhc2luZywgc28gaGFkIHRvIGJlCit0YXVnaHQgaG93IHRvIGRlYWwgd2l0aCBtaXh0dXJlcyBvZiBhc2NlbmRpbmcgYW5kIGRlc2NlbmRpbmcgcnVucworZWZmaWNpZW50bHkgaW4gYWxsIGNhc2VzLgpkaWZmIC0tZ2l0IGEvUHl0aG9uLTIuNy41L09iamVjdHMvbG5vdGFiX25vdGVzLnR4dCBiL1B5dGhvbi0yLjcuNS9PYmplY3RzL2xub3RhYl9ub3Rlcy50eHQKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZDI0N2VkZAotLS0gL2Rldi9udWxsCisrKyBiL1B5dGhvbi0yLjcuNS9PYmplY3RzL2xub3RhYl9ub3Rlcy50eHQKQEAgLTAsMCArMSwxMjQgQEAKK0FsbCBhYm91dCBjb19sbm90YWIsIHRoZSBsaW5lIG51bWJlciB0YWJsZS4KKworQ29kZSBvYmplY3RzIHN0b3JlIGEgZmllbGQgbmFtZWQgY29fbG5vdGFiLiAgVGhpcyBpcyBhbiBhcnJheSBvZiB1bnNpZ25lZCBieXRlcworZGlzZ3Vpc2VkIGFzIGEgUHl0aG9uIHN0cmluZy4gIEl0IGlzIHVzZWQgdG8gbWFwIGJ5dGVjb2RlIG9mZnNldHMgdG8gc291cmNlIGNvZGUKK2xpbmUgI3MgZm9yIHRyYWNlYmFja3MgYW5kIHRvIGlkZW50aWZ5IGxpbmUgbnVtYmVyIGJvdW5kYXJpZXMgZm9yIGxpbmUgdHJhY2luZy4KKworVGhlIGFycmF5IGlzIGNvbmNlcHR1YWxseSBhIGNvbXByZXNzZWQgbGlzdCBvZgorICAgIChieXRlY29kZSBvZmZzZXQgaW5jcmVtZW50LCBsaW5lIG51bWJlciBpbmNyZW1lbnQpCitwYWlycy4gIFRoZSBkZXRhaWxzIGFyZSBpbXBvcnRhbnQgYW5kIGRlbGljYXRlLCBiZXN0IGlsbHVzdHJhdGVkIGJ5IGV4YW1wbGU6CisKKyAgICBieXRlIGNvZGUgb2Zmc2V0ICAgIHNvdXJjZSBjb2RlIGxpbmUgbnVtYmVyCisgICAgICAgIDAJCSAgICAxCisgICAgICAgIDYJCSAgICAyCisgICAgICAgNTAJCSAgICA3CisgICAgICAzNTAgICAgICAgICAgICAgICAgIDMwNworICAgICAgMzYxICAgICAgICAgICAgICAgICAzMDgKKworSW5zdGVhZCBvZiBzdG9yaW5nIHRoZXNlIG51bWJlcnMgbGl0ZXJhbGx5LCB3ZSBjb21wcmVzcyB0aGUgbGlzdCBieSBzdG9yaW5nIG9ubHkKK3RoZSBpbmNyZW1lbnRzIGZyb20gb25lIHJvdyB0byB0aGUgbmV4dC4gIENvbmNlcHR1YWxseSwgdGhlIHN0b3JlZCBsaXN0IG1pZ2h0Citsb29rIGxpa2U6CisKKyAgICAwLCAxLCAgNiwgMSwgIDQ0LCA1LCAgMzAwLCAzMDAsICAxMSwgMQorCitUaGUgYWJvdmUgZG9lc24ndCByZWFsbHkgd29yaywgYnV0IGl0J3MgYSBzdGFydC4gTm90ZSB0aGF0IGFuIHVuc2lnbmVkIGJ5dGUKK2Nhbid0IGhvbGQgbmVnYXRpdmUgdmFsdWVzLCBvciB2YWx1ZXMgbGFyZ2VyIHRoYW4gMjU1LCBhbmQgdGhlIGFib3ZlIGV4YW1wbGUKK2NvbnRhaW5zIHR3byBzdWNoIHZhbHVlcy4gU28gd2UgbWFrZSB0d28gdHdlYWtzOgorCisgKGEpIHRoZXJlJ3MgYSBkZWVwIGFzc3VtcHRpb24gdGhhdCBieXRlIGNvZGUgb2Zmc2V0cyBhbmQgdGhlaXIgY29ycmVzcG9uZGluZworIGxpbmUgI3MgYm90aCBpbmNyZWFzZSBtb25vdG9uaWNhbGx5LCBhbmQKKyAoYikgaWYgYXQgbGVhc3Qgb25lIGNvbHVtbiBqdW1wcyBieSBtb3JlIHRoYW4gMjU1IGZyb20gb25lIHJvdyB0byB0aGUgbmV4dCwKKyBtb3JlIHRoYW4gb25lIHBhaXIgaXMgd3JpdHRlbiB0byB0aGUgdGFibGUuIEluIGNhc2UgI2IsIHRoZXJlJ3Mgbm8gd2F5IHRvIGtub3cKKyBmcm9tIGxvb2tpbmcgYXQgdGhlIHRhYmxlIGxhdGVyIGhvdyBtYW55IHdlcmUgd3JpdHRlbi4gIFRoYXQncyB0aGUgZGVsaWNhdGUKKyBwYXJ0LiAgQSB1c2VyIG9mIGNvX2xub3RhYiBkZXNpcmluZyB0byBmaW5kIHRoZSBzb3VyY2UgbGluZSBudW1iZXIKKyBjb3JyZXNwb25kaW5nIHRvIGEgYnl0ZWNvZGUgYWRkcmVzcyBBIHNob3VsZCBkbyBzb21ldGhpbmcgbGlrZSB0aGlzCisKKyAgICBsaW5lbm8gPSBhZGRyID0gMAorICAgIGZvciBhZGRyX2luY3IsIGxpbmVfaW5jciBpbiBjb19sbm90YWI6CisgICAgICAgIGFkZHIgKz0gYWRkcl9pbmNyCisgICAgICAgIGlmIGFkZHIgPiBBOgorICAgICAgICAgICAgcmV0dXJuIGxpbmVubworICAgICAgICBsaW5lbm8gKz0gbGluZV9pbmNyCisKKyhJbiBDLCB0aGlzIGlzIGltcGxlbWVudGVkIGJ5IFB5Q29kZV9BZGRyMkxpbmUoKS4pICBJbiBvcmRlciBmb3IgdGhpcyB0byB3b3JrLAord2hlbiB0aGUgYWRkciBmaWVsZCBpbmNyZW1lbnRzIGJ5IG1vcmUgdGhhbiAyNTUsIHRoZSBsaW5lICMgaW5jcmVtZW50IGluIGVhY2gKK3BhaXIgZ2VuZXJhdGVkIG11c3QgYmUgMCB1bnRpbCB0aGUgcmVtYWluaW5nIGFkZHIgaW5jcmVtZW50IGlzIDwgMjU2LiAgU28sIGluCit0aGUgZXhhbXBsZSBhYm92ZSwgYXNzZW1ibGVfbG5vdGFiIGluIGNvbXBpbGUuYyBzaG91bGQgbm90IChhcyB3YXMgYWN0dWFsbHkgZG9uZQordW50aWwgMi4yKSBleHBhbmQgMzAwLCAzMDAgdG8KKyAgICAyNTUsIDI1NSwgNDUsIDQ1LAorYnV0IHRvCisgICAgMjU1LCAwLCA0NSwgMjU1LCAwLCA0NS4KKworVGhlIGFib3ZlIGlzIHN1ZmZpY2llbnQgdG8gcmVjb25zdHJ1Y3QgbGluZSBudW1iZXJzIGZvciB0cmFjZWJhY2tzLCBidXQgbm90IGZvcgorbGluZSB0cmFjaW5nLiAgVHJhY2luZyBpcyBoYW5kbGVkIGJ5IFB5Q29kZV9DaGVja0xpbmVOdW1iZXIoKSBpbiBjb2Rlb2JqZWN0LmMKK2FuZCBtYXliZV9jYWxsX2xpbmVfdHJhY2UoKSBpbiBjZXZhbC5jLgorCisqKiogVHJhY2luZyAqKioKKworVG8gYSBmaXJzdCBhcHByb3hpbWF0aW9uLCB3ZSB3YW50IHRvIGNhbGwgdGhlIHRyYWNpbmcgZnVuY3Rpb24gd2hlbiB0aGUgbGluZQorbnVtYmVyIG9mIHRoZSBjdXJyZW50IGluc3RydWN0aW9uIGNoYW5nZXMuICBSZS1jb21wdXRpbmcgdGhlIGN1cnJlbnQgbGluZSBmb3IKK2V2ZXJ5IGluc3RydWN0aW9uIGlzIGEgbGl0dGxlIHNsb3csIHRob3VnaCwgc28gZWFjaCB0aW1lIHdlIGNvbXB1dGUgdGhlIGxpbmUKK251bWJlciB3ZSBzYXZlIHRoZSBieXRlY29kZSBpbmRpY2VzIHdoZXJlIGl0J3MgdmFsaWQ6CisKKyAgICAgKmluc3RyX2xiIDw9IGZyYW1lLT5mX2xhc3RpIDwgKmluc3RyX3ViCisKK2lzIHRydWUgc28gbG9uZyBhcyBleGVjdXRpb24gZG9lcyBub3QgY2hhbmdlIGxpbmVzLiAgVGhhdCBpcywgKmluc3RyX2xiIGhvbGRzCit0aGUgZmlyc3QgYnl0ZWNvZGUgaW5kZXggb2YgdGhlIGN1cnJlbnQgbGluZSwgYW5kICppbnN0cl91YiBob2xkcyB0aGUgZmlyc3QKK2J5dGVjb2RlIGluZGV4IG9mIHRoZSBuZXh0IGxpbmUuICBBcyBsb25nIGFzIHRoZSBhYm92ZSBleHByZXNzaW9uIGlzIHRydWUsCittYXliZV9jYWxsX2xpbmVfdHJhY2UoKSBkb2VzIG5vdCBuZWVkIHRvIGNhbGwgUHlDb2RlX0NoZWNrTGluZU51bWJlcigpLiAgTm90ZQordGhhdCB0aGUgc2FtZSBsaW5lIG1heSBhcHBlYXIgbXVsdGlwbGUgdGltZXMgaW4gdGhlIGxub3RhYiwgZWl0aGVyIGJlY2F1c2UgdGhlCitieXRlY29kZSBqdW1wZWQgbW9yZSB0aGFuIDI1NSBpbmRpY2VzIGJldHdlZW4gbGluZSBudW1iZXIgY2hhbmdlcyBvciBiZWNhdXNlCit0aGUgY29tcGlsZXIgaW5zZXJ0ZWQgdGhlIHNhbWUgbGluZSB0d2ljZS4gIEV2ZW4gaW4gdGhhdCBjYXNlLCAqaW5zdHJfdWIgaG9sZHMKK3RoZSBmaXJzdCBpbmRleCBvZiB0aGUgbmV4dCBsaW5lLgorCitIb3dldmVyLCB3ZSBkb24ndCAqYWx3YXlzKiB3YW50IHRvIGNhbGwgdGhlIGxpbmUgdHJhY2UgZnVuY3Rpb24gd2hlbiB0aGUgYWJvdmUKK3Rlc3QgZmFpbHMuCisKK0NvbnNpZGVyIHRoaXMgY29kZToKKworMTogZGVmIGYoYSk6CisyOiAgICB3aGlsZSBhOgorMzogICAgICAgcHJpbnQgMSwKKzQ6ICAgICAgIGJyZWFrCis1OiAgICBlbHNlOgorNjogICAgICAgcHJpbnQgMiwKKword2hpY2ggY29tcGlsZXMgdG8gdGhpczoKKworICAyICAgICAgICAgICAwIFNFVFVQX0xPT1AgICAgICAgICAgICAgIDE5ICh0byAyMikKKyAgICAgICAgPj4gICAgMyBMT0FEX0ZBU1QgICAgICAgICAgICAgICAgMCAoYSkKKyAgICAgICAgICAgICAgNiBQT1BfSlVNUF9JRl9GQUxTRSAgICAgICAxNworCisgIDMgICAgICAgICAgIDkgTE9BRF9DT05TVCAgICAgICAgICAgICAgIDEgKDEpCisgICAgICAgICAgICAgMTIgUFJJTlRfSVRFTSAgICAgICAgICAKKworICA0ICAgICAgICAgIDEzIEJSRUFLX0xPT1AgICAgICAgICAgCisgICAgICAgICAgICAgMTQgSlVNUF9BQlNPTFVURSAgICAgICAgICAgIDMKKyAgICAgICAgPj4gICAxNyBQT1BfQkxPQ0sgICAgICAgICAgIAorCisgIDYgICAgICAgICAgMTggTE9BRF9DT05TVCAgICAgICAgICAgICAgIDIgKDIpCisgICAgICAgICAgICAgMjEgUFJJTlRfSVRFTSAgICAgICAgICAKKyAgICAgICAgPj4gICAyMiBMT0FEX0NPTlNUICAgICAgICAgICAgICAgMCAoTm9uZSkKKyAgICAgICAgICAgICAyNSBSRVRVUk5fVkFMVUUgICAgICAgIAorCitJZiAnYScgaXMgZmFsc2UsIGV4ZWN1dGlvbiB3aWxsIGp1bXAgdG8gdGhlIFBPUF9CTE9DSyBpbnN0cnVjdGlvbiBhdCBvZmZzZXQgMTcKK2FuZCB0aGUgY29fbG5vdGFiIHdpbGwgY2xhaW0gdGhhdCBleGVjdXRpb24gaGFzIG1vdmVkIHRvIGxpbmUgNCwgd2hpY2ggaXMgd3JvbmcuCitJbiB0aGlzIGNhc2UsIHdlIGNvdWxkIGluc3RlYWQgYXNzb2NpYXRlIHRoZSBQT1BfQkxPQ0sgd2l0aCBsaW5lIDUsIGJ1dCB0aGF0Cit3b3VsZCBicmVhayBqdW1wcyBhcm91bmQgbG9vcHMgd2l0aG91dCBlbHNlIGNsYXVzZXMuCisKK1dlIGZpeCB0aGlzIGJ5IG9ubHkgY2FsbGluZyB0aGUgbGluZSB0cmFjZSBmdW5jdGlvbiBmb3IgYSBmb3J3YXJkIGp1bXAgaWYgdGhlCitjb19sbm90YWIgaW5kaWNhdGVzIHdlIGhhdmUganVtcGVkIHRvIHRoZSAqc3RhcnQqIG9mIGEgbGluZSwgaS5lLiBpZiB0aGUgY3VycmVudAoraW5zdHJ1Y3Rpb24gb2Zmc2V0IG1hdGNoZXMgdGhlIG9mZnNldCBnaXZlbiBmb3IgdGhlIHN0YXJ0IG9mIGEgbGluZSBieSB0aGUKK2NvX2xub3RhYi4gIEZvciBiYWNrd2FyZCBqdW1wcywgaG93ZXZlciwgd2UgYWx3YXlzIGNhbGwgdGhlIGxpbmUgdHJhY2UgZnVuY3Rpb24sCit3aGljaCBsZXRzIGEgZGVidWdnZXIgc3RvcCBvbiBldmVyeSBldmFsdWF0aW9uIG9mIGEgbG9vcCBndWFyZCAod2hpY2ggdXN1YWxseQord29uJ3QgYmUgdGhlIGZpcnN0IG9wY29kZSBpbiBhIGxpbmUpLgorCitXaHkgZG8gd2Ugc2V0IGZfbGluZW5vIHdoZW4gdHJhY2luZywgYW5kIG9ubHkganVzdCBiZWZvcmUgY2FsbGluZyB0aGUgdHJhY2UKK2Z1bmN0aW9uPyAgV2VsbCwgY29uc2lkZXIgdGhlIGNvZGUgYWJvdmUgd2hlbiAnYScgaXMgdHJ1ZS4gIElmIHN0ZXBwaW5nIHRocm91Z2gKK3RoaXMgd2l0aCAnbicgaW4gcGRiLCB5b3Ugd291bGQgc3RvcCBhdCBsaW5lIDEgd2l0aCBhICJjYWxsIiB0eXBlIGV2ZW50LCB0aGVuCitsaW5lIGV2ZW50cyBvbiBsaW5lcyAyLCAzLCBhbmQgNCwgdGhlbiBhICJyZXR1cm4iIHR5cGUgZXZlbnQgLS0gYnV0IGJlY2F1c2UgdGhlCitjb2RlIGZvciB0aGUgcmV0dXJuIGFjdHVhbGx5IGZhbGxzIGluIHRoZSByYW5nZSBvZiB0aGUgImxpbmUgNiIgb3Bjb2RlcywgeW91Cit3b3VsZCBiZSBzaG93biBsaW5lIDYgZHVyaW5nIHRoaXMgZXZlbnQuICBUaGlzIGlzIGEgY2hhbmdlIGZyb20gdGhlIGJlaGF2aW91ciBpbgorMi4yIGFuZCBiZWZvcmUsIGFuZCBJJ3ZlIGZvdW5kIGl0IGNvbmZ1c2luZyBpbiBwcmFjdGljZS4gIEJ5IHNldHRpbmcgYW5kIHVzaW5nCitmX2xpbmVubyB3aGVuIHRyYWNpbmcsIG9uZSBjYW4gcmVwb3J0IGEgbGluZSBudW1iZXIgZGlmZmVyZW50IGZyb20gdGhhdAorc3VnZ2VzdGVkIGJ5IGZfbGFzdGkgb24gdGhpcyBvbmUgb2NjYXNpb24gd2hlcmUgaXQncyBkZXNpcmFibGUuCmRpZmYgLS1naXQgYS9QeXRob24tMi43LjUvT2JqZWN0cy9sb25nb2JqZWN0LmMgYi9QeXRob24tMi43LjUvT2JqZWN0cy9sb25nb2JqZWN0LmMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZmI3NDBkYwotLS0gL2Rldi9udWxsCisrKyBiL1B5dGhvbi0yLjcuNS9PYmplY3RzL2xvbmdvYmplY3QuYwpAQCAtMCwwICsxLDQzOTUgQEAKKy8qIExvbmcgKGFyYml0cmFyeSBwcmVjaXNpb24pIGludGVnZXIgb2JqZWN0IGltcGxlbWVudGF0aW9uICovCisKKy8qIFhYWCBUaGUgZnVuY3Rpb25hbCBvcmdhbml6YXRpb24gb2YgdGhpcyBmaWxlIGlzIHRlcnJpYmxlICovCisKKyNpbmNsdWRlICJQeXRob24uaCIKKyNpbmNsdWRlICJsb25naW50cmVwci5oIgorI2luY2x1ZGUgInN0cnVjdHNlcS5oIgorCisjaW5jbHVkZSA8ZmxvYXQuaD4KKyNpbmNsdWRlIDxjdHlwZS5oPgorI2luY2x1ZGUgPHN0ZGRlZi5oPgorCisvKiBGb3IgbG9uZyBtdWx0aXBsaWNhdGlvbiwgdXNlIHRoZSBPKE4qKjIpIHNjaG9vbCBhbGdvcml0aG0gdW5sZXNzCisgKiBib3RoIG9wZXJhbmRzIGNvbnRhaW4gbW9yZSB0aGFuIEtBUkFUU1VCQV9DVVRPRkYgZGlnaXRzICh0aGlzCisgKiBiZWluZyBhbiBpbnRlcm5hbCBQeXRob24gbG9uZyBkaWdpdCwgaW4gYmFzZSBQeUxvbmdfQkFTRSkuCisgKi8KKyNkZWZpbmUgS0FSQVRTVUJBX0NVVE9GRiA3MAorI2RlZmluZSBLQVJBVFNVQkFfU1FVQVJFX0NVVE9GRiAoMiAqIEtBUkFUU1VCQV9DVVRPRkYpCisKKy8qIEZvciBleHBvbmVudGlhdGlvbiwgdXNlIHRoZSBiaW5hcnkgbGVmdC10by1yaWdodCBhbGdvcml0aG0KKyAqIHVubGVzcyB0aGUgZXhwb25lbnQgY29udGFpbnMgbW9yZSB0aGFuIEZJVkVBUllfQ1VUT0ZGIGRpZ2l0cy4KKyAqIEluIHRoYXQgY2FzZSwgZG8gNSBiaXRzIGF0IGEgdGltZS4gIFRoZSBwb3RlbnRpYWwgZHJhd2JhY2sgaXMgdGhhdAorICogYSB0YWJsZSBvZiAyKio1IGludGVybWVkaWF0ZSByZXN1bHRzIGlzIGNvbXB1dGVkLgorICovCisjZGVmaW5lIEZJVkVBUllfQ1VUT0ZGIDgKKworI2RlZmluZSBBQlMoeCkgKCh4KSA8IDAgPyAtKHgpIDogKHgpKQorCisjdW5kZWYgTUlOCisjdW5kZWYgTUFYCisjZGVmaW5lIE1BWCh4LCB5KSAoKHgpIDwgKHkpID8gKHkpIDogKHgpKQorI2RlZmluZSBNSU4oeCwgeSkgKCh4KSA+ICh5KSA/ICh5KSA6ICh4KSkKKworI2RlZmluZSBTSUdDSEVDSyhQeVRyeUJsb2NrKSAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgZG8geyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgaWYgKC0tX1B5X1RpY2tlciA8IDApIHsgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgICAgX1B5X1RpY2tlciA9IF9QeV9DaGVja0ludGVydmFsOyAgICAgICAgICAgICBcCisgICAgICAgICAgICBpZiAoUHlFcnJfQ2hlY2tTaWduYWxzKCkpIFB5VHJ5QmxvY2sgICAgICAgIFwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gICAgICAgICAgICAgXAorICAgIH0gd2hpbGUoMCkKKworLyogTm9ybWFsaXplIChyZW1vdmUgbGVhZGluZyB6ZXJvcyBmcm9tKSBhIGxvbmcgaW50IG9iamVjdC4KKyAgIERvZXNuJ3QgYXR0ZW1wdCB0byBmcmVlIHRoZSBzdG9yYWdlLS1pbiBtb3N0IGNhc2VzLCBkdWUgdG8gdGhlIG5hdHVyZQorICAgb2YgdGhlIGFsZ29yaXRobXMgdXNlZCwgdGhpcyBjb3VsZCBzYXZlIGF0IG1vc3QgYmUgb25lIHdvcmQgYW55d2F5LiAqLworCitzdGF0aWMgUHlMb25nT2JqZWN0ICoKK2xvbmdfbm9ybWFsaXplKHJlZ2lzdGVyIFB5TG9uZ09iamVjdCAqdikKK3sKKyAgICBQeV9zc2l6ZV90IGogPSBBQlMoUHlfU0laRSh2KSk7CisgICAgUHlfc3NpemVfdCBpID0gajsKKworICAgIHdoaWxlIChpID4gMCAmJiB2LT5vYl9kaWdpdFtpLTFdID09IDApCisgICAgICAgIC0taTsKKyAgICBpZiAoaSAhPSBqKQorICAgICAgICBQeV9TSVpFKHYpID0gKFB5X1NJWkUodikgPCAwKSA/IC0oaSkgOiBpOworICAgIHJldHVybiB2OworfQorCisvKiBBbGxvY2F0ZSBhIG5ldyBsb25nIGludCBvYmplY3Qgd2l0aCBzaXplIGRpZ2l0cy4KKyAgIFJldHVybiBOVUxMIGFuZCBzZXQgZXhjZXB0aW9uIGlmIHdlIHJ1biBvdXQgb2YgbWVtb3J5LiAqLworCisjZGVmaW5lIE1BWF9MT05HX0RJR0lUUyBcCisgICAgKChQWV9TU0laRV9UX01BWCAtIG9mZnNldG9mKFB5TG9uZ09iamVjdCwgb2JfZGlnaXQpKS9zaXplb2YoZGlnaXQpKQorCitQeUxvbmdPYmplY3QgKgorX1B5TG9uZ19OZXcoUHlfc3NpemVfdCBzaXplKQoreworICAgIGlmIChzaXplID4gKFB5X3NzaXplX3QpTUFYX0xPTkdfRElHSVRTKSB7CisgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19PdmVyZmxvd0Vycm9yLAorICAgICAgICAgICAgICAgICAgICAgICAgInRvbyBtYW55IGRpZ2l0cyBpbiBpbnRlZ2VyIik7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICAvKiBjb3Zlcml0eVthbXBlcnNhbmRfaW5fc2l6ZV0gKi8KKyAgICAvKiBYWFgobm5vcndpdHopOiBQeU9iamVjdF9ORVdfVkFSIC8gX1B5T2JqZWN0X1ZBUl9TSVpFIG5lZWQgdG8gZGV0ZWN0CisgICAgICAgb3ZlcmZsb3cgKi8KKyAgICByZXR1cm4gUHlPYmplY3RfTkVXX1ZBUihQeUxvbmdPYmplY3QsICZQeUxvbmdfVHlwZSwgc2l6ZSk7Cit9CisKK1B5T2JqZWN0ICoKK19QeUxvbmdfQ29weShQeUxvbmdPYmplY3QgKnNyYykKK3sKKyAgICBQeUxvbmdPYmplY3QgKnJlc3VsdDsKKyAgICBQeV9zc2l6ZV90IGk7CisKKyAgICBhc3NlcnQoc3JjICE9IE5VTEwpOworICAgIGkgPSBzcmMtPm9iX3NpemU7CisgICAgaWYgKGkgPCAwKQorICAgICAgICBpID0gLShpKTsKKyAgICByZXN1bHQgPSBfUHlMb25nX05ldyhpKTsKKyAgICBpZiAocmVzdWx0ICE9IE5VTEwpIHsKKyAgICAgICAgcmVzdWx0LT5vYl9zaXplID0gc3JjLT5vYl9zaXplOworICAgICAgICB3aGlsZSAoLS1pID49IDApCisgICAgICAgICAgICByZXN1bHQtPm9iX2RpZ2l0W2ldID0gc3JjLT5vYl9kaWdpdFtpXTsKKyAgICB9CisgICAgcmV0dXJuIChQeU9iamVjdCAqKXJlc3VsdDsKK30KKworLyogQ3JlYXRlIGEgbmV3IGxvbmcgaW50IG9iamVjdCBmcm9tIGEgQyBsb25nIGludCAqLworCitQeU9iamVjdCAqCitQeUxvbmdfRnJvbUxvbmcobG9uZyBpdmFsKQoreworICAgIFB5TG9uZ09iamVjdCAqdjsKKyAgICB1bnNpZ25lZCBsb25nIGFic19pdmFsOworICAgIHVuc2lnbmVkIGxvbmcgdDsgIC8qIHVuc2lnbmVkIHNvID4+IGRvZXNuJ3QgcHJvcGFnYXRlIHNpZ24gYml0ICovCisgICAgaW50IG5kaWdpdHMgPSAwOworICAgIGludCBuZWdhdGl2ZSA9IDA7CisKKyAgICBpZiAoaXZhbCA8IDApIHsKKyAgICAgICAgLyogaWYgTE9OR19NSU4gPT0gLUxPTkdfTUFYLTEgKHRydWUgb24gbW9zdCBwbGF0Zm9ybXMpIHRoZW4KKyAgICAgICAgICAgQU5TSSBDIHNheXMgdGhhdCB0aGUgcmVzdWx0IG9mIC1pdmFsIGlzIHVuZGVmaW5lZCB3aGVuIGl2YWwKKyAgICAgICAgICAgPT0gTE9OR19NSU4uICBIZW5jZSB0aGUgZm9sbG93aW5nIHdvcmthcm91bmQuICovCisgICAgICAgIGFic19pdmFsID0gKHVuc2lnbmVkIGxvbmcpKC0xLWl2YWwpICsgMTsKKyAgICAgICAgbmVnYXRpdmUgPSAxOworICAgIH0KKyAgICBlbHNlIHsKKyAgICAgICAgYWJzX2l2YWwgPSAodW5zaWduZWQgbG9uZylpdmFsOworICAgIH0KKworICAgIC8qIENvdW50IHRoZSBudW1iZXIgb2YgUHl0aG9uIGRpZ2l0cy4KKyAgICAgICBXZSB1c2VkIHRvIHBpY2sgNSAoImJpZyBlbm91Z2ggZm9yIGFueXRoaW5nIiksIGJ1dCB0aGF0J3MgYQorICAgICAgIHdhc3RlIG9mIHRpbWUgYW5kIHNwYWNlIGdpdmVuIHRoYXQgNSoxNSA9IDc1IGJpdHMgYXJlIHJhcmVseQorICAgICAgIG5lZWRlZC4gKi8KKyAgICB0ID0gYWJzX2l2YWw7CisgICAgd2hpbGUgKHQpIHsKKyAgICAgICAgKytuZGlnaXRzOworICAgICAgICB0ID4+PSBQeUxvbmdfU0hJRlQ7CisgICAgfQorICAgIHYgPSBfUHlMb25nX05ldyhuZGlnaXRzKTsKKyAgICBpZiAodiAhPSBOVUxMKSB7CisgICAgICAgIGRpZ2l0ICpwID0gdi0+b2JfZGlnaXQ7CisgICAgICAgIHYtPm9iX3NpemUgPSBuZWdhdGl2ZSA/IC1uZGlnaXRzIDogbmRpZ2l0czsKKyAgICAgICAgdCA9IGFic19pdmFsOworICAgICAgICB3aGlsZSAodCkgeworICAgICAgICAgICAgKnArKyA9IChkaWdpdCkodCAmIFB5TG9uZ19NQVNLKTsKKyAgICAgICAgICAgIHQgPj49IFB5TG9uZ19TSElGVDsKKyAgICAgICAgfQorICAgIH0KKyAgICByZXR1cm4gKFB5T2JqZWN0ICopdjsKK30KKworLyogQ3JlYXRlIGEgbmV3IGxvbmcgaW50IG9iamVjdCBmcm9tIGEgQyB1bnNpZ25lZCBsb25nIGludCAqLworCitQeU9iamVjdCAqCitQeUxvbmdfRnJvbVVuc2lnbmVkTG9uZyh1bnNpZ25lZCBsb25nIGl2YWwpCit7CisgICAgUHlMb25nT2JqZWN0ICp2OworICAgIHVuc2lnbmVkIGxvbmcgdDsKKyAgICBpbnQgbmRpZ2l0cyA9IDA7CisKKyAgICAvKiBDb3VudCB0aGUgbnVtYmVyIG9mIFB5dGhvbiBkaWdpdHMuICovCisgICAgdCA9ICh1bnNpZ25lZCBsb25nKWl2YWw7CisgICAgd2hpbGUgKHQpIHsKKyAgICAgICAgKytuZGlnaXRzOworICAgICAgICB0ID4+PSBQeUxvbmdfU0hJRlQ7CisgICAgfQorICAgIHYgPSBfUHlMb25nX05ldyhuZGlnaXRzKTsKKyAgICBpZiAodiAhPSBOVUxMKSB7CisgICAgICAgIGRpZ2l0ICpwID0gdi0+b2JfZGlnaXQ7CisgICAgICAgIFB5X1NJWkUodikgPSBuZGlnaXRzOworICAgICAgICB3aGlsZSAoaXZhbCkgeworICAgICAgICAgICAgKnArKyA9IChkaWdpdCkoaXZhbCAmIFB5TG9uZ19NQVNLKTsKKyAgICAgICAgICAgIGl2YWwgPj49IFB5TG9uZ19TSElGVDsKKyAgICAgICAgfQorICAgIH0KKyAgICByZXR1cm4gKFB5T2JqZWN0ICopdjsKK30KKworLyogQ3JlYXRlIGEgbmV3IGxvbmcgaW50IG9iamVjdCBmcm9tIGEgQyBkb3VibGUgKi8KKworUHlPYmplY3QgKgorUHlMb25nX0Zyb21Eb3VibGUoZG91YmxlIGR2YWwpCit7CisgICAgUHlMb25nT2JqZWN0ICp2OworICAgIGRvdWJsZSBmcmFjOworICAgIGludCBpLCBuZGlnLCBleHBvLCBuZWc7CisgICAgbmVnID0gMDsKKyAgICBpZiAoUHlfSVNfSU5GSU5JVFkoZHZhbCkpIHsKKyAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX092ZXJmbG93RXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAgICAiY2Fubm90IGNvbnZlcnQgZmxvYXQgaW5maW5pdHkgdG8gaW50ZWdlciIpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgaWYgKFB5X0lTX05BTihkdmFsKSkgeworICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfVmFsdWVFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICJjYW5ub3QgY29udmVydCBmbG9hdCBOYU4gdG8gaW50ZWdlciIpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgaWYgKGR2YWwgPCAwLjApIHsKKyAgICAgICAgbmVnID0gMTsKKyAgICAgICAgZHZhbCA9IC1kdmFsOworICAgIH0KKyAgICBmcmFjID0gZnJleHAoZHZhbCwgJmV4cG8pOyAvKiBkdmFsID0gZnJhYyoyKipleHBvOyAwLjAgPD0gZnJhYyA8IDEuMCAqLworICAgIGlmIChleHBvIDw9IDApCisgICAgICAgIHJldHVybiBQeUxvbmdfRnJvbUxvbmcoMEwpOworICAgIG5kaWcgPSAoZXhwby0xKSAvIFB5TG9uZ19TSElGVCArIDE7IC8qIE51bWJlciBvZiAnZGlnaXRzJyBpbiByZXN1bHQgKi8KKyAgICB2ID0gX1B5TG9uZ19OZXcobmRpZyk7CisgICAgaWYgKHYgPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgZnJhYyA9IGxkZXhwKGZyYWMsIChleHBvLTEpICUgUHlMb25nX1NISUZUICsgMSk7CisgICAgZm9yIChpID0gbmRpZzsgLS1pID49IDA7ICkgeworICAgICAgICBkaWdpdCBiaXRzID0gKGRpZ2l0KWZyYWM7CisgICAgICAgIHYtPm9iX2RpZ2l0W2ldID0gYml0czsKKyAgICAgICAgZnJhYyA9IGZyYWMgLSAoZG91YmxlKWJpdHM7CisgICAgICAgIGZyYWMgPSBsZGV4cChmcmFjLCBQeUxvbmdfU0hJRlQpOworICAgIH0KKyAgICBpZiAobmVnKQorICAgICAgICBQeV9TSVpFKHYpID0gLShQeV9TSVpFKHYpKTsKKyAgICByZXR1cm4gKFB5T2JqZWN0ICopdjsKK30KKworLyogQ2hlY2tpbmcgZm9yIG92ZXJmbG93IGluIFB5TG9uZ19Bc0xvbmcgaXMgYSBQSVRBIHNpbmNlIEMgZG9lc24ndCBkZWZpbmUKKyAqIGFueXRoaW5nIGFib3V0IHdoYXQgaGFwcGVucyB3aGVuIGEgc2lnbmVkIGludGVnZXIgb3BlcmF0aW9uIG92ZXJmbG93cywKKyAqIGFuZCBzb21lIGNvbXBpbGVycyB0aGluayB0aGV5J3JlIGRvaW5nIHlvdSBhIGZhdm9yIGJ5IGJlaW5nICJjbGV2ZXIiCisgKiB0aGVuLiAgVGhlIGJpdCBwYXR0ZXJuIGZvciB0aGUgbGFyZ2VzdCBwb3N0aXZlIHNpZ25lZCBsb25nIGlzCisgKiAodW5zaWduZWQgbG9uZylMT05HX01BWCwgYW5kIGZvciB0aGUgc21hbGxlc3QgbmVnYXRpdmUgc2lnbmVkIGxvbmcKKyAqIGl0IGlzIGFicyhMT05HX01JTiksIHdoaWNoIHdlIGNvdWxkIHdyaXRlIC0odW5zaWduZWQgbG9uZylMT05HX01JTi4KKyAqIEhvd2V2ZXIsIHNvbWUgb3RoZXIgY29tcGlsZXJzIHdhcm4gYWJvdXQgYXBwbHlpbmcgdW5hcnkgbWludXMgdG8gYW4KKyAqIHVuc2lnbmVkIG9wZXJhbmQuICBIZW5jZSB0aGUgd2VpcmQgIjAtIi4KKyAqLworI2RlZmluZSBQWV9BQlNfTE9OR19NSU4gICAgICAgICAoMC0odW5zaWduZWQgbG9uZylMT05HX01JTikKKyNkZWZpbmUgUFlfQUJTX1NTSVpFX1RfTUlOICAgICAgKDAtKHNpemVfdClQWV9TU0laRV9UX01JTikKKworLyogR2V0IGEgQyBsb25nIGludCBmcm9tIGEgUHl0aG9uIGxvbmcgb3IgUHl0aG9uIGludCBvYmplY3QuCisgICBPbiBvdmVyZmxvdywgcmV0dXJucyAtMSBhbmQgc2V0cyAqb3ZlcmZsb3cgdG8gMSBvciAtMSBkZXBlbmRpbmcKKyAgIG9uIHRoZSBzaWduIG9mIHRoZSByZXN1bHQuICBPdGhlcndpc2UgKm92ZXJmbG93IGlzIDAuCisKKyAgIEZvciBvdGhlciBlcnJvcnMgKGUuZy4sIHR5cGUgZXJyb3IpLCByZXR1cm5zIC0xIGFuZCBzZXRzIGFuIGVycm9yCisgICBjb25kaXRpb24uCisqLworCitsb25nCitQeUxvbmdfQXNMb25nQW5kT3ZlcmZsb3coUHlPYmplY3QgKnZ2LCBpbnQgKm92ZXJmbG93KQoreworICAgIC8qIFRoaXMgdmVyc2lvbiBieSBUaW0gUGV0ZXJzICovCisgICAgcmVnaXN0ZXIgUHlMb25nT2JqZWN0ICp2OworICAgIHVuc2lnbmVkIGxvbmcgeCwgcHJldjsKKyAgICBsb25nIHJlczsKKyAgICBQeV9zc2l6ZV90IGk7CisgICAgaW50IHNpZ247CisgICAgaW50IGRvX2RlY3JlZiA9IDA7IC8qIGlmIG5iX2ludCB3YXMgY2FsbGVkICovCisKKyAgICAqb3ZlcmZsb3cgPSAwOworICAgIGlmICh2diA9PSBOVUxMKSB7CisgICAgICAgIFB5RXJyX0JhZEludGVybmFsQ2FsbCgpOworICAgICAgICByZXR1cm4gLTE7CisgICAgfQorCisgICAgaWYoUHlJbnRfQ2hlY2sodnYpKQorICAgICAgICByZXR1cm4gUHlJbnRfQXNMb25nKHZ2KTsKKworICAgIGlmICghUHlMb25nX0NoZWNrKHZ2KSkgeworICAgICAgICBQeU51bWJlck1ldGhvZHMgKm5iOworICAgICAgICBuYiA9IHZ2LT5vYl90eXBlLT50cF9hc19udW1iZXI7CisgICAgICAgIGlmIChuYiA9PSBOVUxMIHx8IG5iLT5uYl9pbnQgPT0gTlVMTCkgeworICAgICAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1R5cGVFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAiYW4gaW50ZWdlciBpcyByZXF1aXJlZCIpOworICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICB9CisgICAgICAgIHZ2ID0gKCpuYi0+bmJfaW50KSAodnYpOworICAgICAgICBpZiAodnYgPT0gTlVMTCkKKyAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgZG9fZGVjcmVmID0gMTsKKyAgICAgICAgaWYoUHlJbnRfQ2hlY2sodnYpKSB7CisgICAgICAgICAgICByZXMgPSBQeUludF9Bc0xvbmcodnYpOworICAgICAgICAgICAgZ290byBleGl0OworICAgICAgICB9CisgICAgICAgIGlmICghUHlMb25nX0NoZWNrKHZ2KSkgeworICAgICAgICAgICAgUHlfREVDUkVGKHZ2KTsKKyAgICAgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19UeXBlRXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIm5iX2ludCBzaG91bGQgcmV0dXJuIGludCBvYmplY3QiKTsKKyAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHJlcyA9IC0xOworICAgIHYgPSAoUHlMb25nT2JqZWN0ICopdnY7CisgICAgaSA9IFB5X1NJWkUodik7CisKKyAgICBzd2l0Y2ggKGkpIHsKKyAgICBjYXNlIC0xOgorICAgICAgICByZXMgPSAtKHNkaWdpdCl2LT5vYl9kaWdpdFswXTsKKyAgICAgICAgYnJlYWs7CisgICAgY2FzZSAwOgorICAgICAgICByZXMgPSAwOworICAgICAgICBicmVhazsKKyAgICBjYXNlIDE6CisgICAgICAgIHJlcyA9IHYtPm9iX2RpZ2l0WzBdOworICAgICAgICBicmVhazsKKyAgICBkZWZhdWx0OgorICAgICAgICBzaWduID0gMTsKKyAgICAgICAgeCA9IDA7CisgICAgICAgIGlmIChpIDwgMCkgeworICAgICAgICAgICAgc2lnbiA9IC0xOworICAgICAgICAgICAgaSA9IC0oaSk7CisgICAgICAgIH0KKyAgICAgICAgd2hpbGUgKC0taSA+PSAwKSB7CisgICAgICAgICAgICBwcmV2ID0geDsKKyAgICAgICAgICAgIHggPSAoeCA8PCBQeUxvbmdfU0hJRlQpICsgdi0+b2JfZGlnaXRbaV07CisgICAgICAgICAgICBpZiAoKHggPj4gUHlMb25nX1NISUZUKSAhPSBwcmV2KSB7CisgICAgICAgICAgICAgICAgKm92ZXJmbG93ID0gc2lnbjsKKyAgICAgICAgICAgICAgICBnb3RvIGV4aXQ7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgLyogSGF2ZW4ndCBsb3N0IGFueSBiaXRzLCBidXQgY2FzdGluZyB0byBsb25nIHJlcXVpcmVzIGV4dHJhCisgICAgICAgICAqIGNhcmUgKHNlZSBjb21tZW50IGFib3ZlKS4KKyAgICAgICAgICovCisgICAgICAgIGlmICh4IDw9ICh1bnNpZ25lZCBsb25nKUxPTkdfTUFYKSB7CisgICAgICAgICAgICByZXMgPSAobG9uZyl4ICogc2lnbjsKKyAgICAgICAgfQorICAgICAgICBlbHNlIGlmIChzaWduIDwgMCAmJiB4ID09IFBZX0FCU19MT05HX01JTikgeworICAgICAgICAgICAgcmVzID0gTE9OR19NSU47CisgICAgICAgIH0KKyAgICAgICAgZWxzZSB7CisgICAgICAgICAgICAqb3ZlcmZsb3cgPSBzaWduOworICAgICAgICAgICAgLyogcmVzIGlzIGFscmVhZHkgc2V0IHRvIC0xICovCisgICAgICAgIH0KKyAgICB9CisgIGV4aXQ6CisgICAgaWYgKGRvX2RlY3JlZikgeworICAgICAgICBQeV9ERUNSRUYodnYpOworICAgIH0KKyAgICByZXR1cm4gcmVzOworfQorCisvKiBHZXQgYSBDIGxvbmcgaW50IGZyb20gYSBsb25nIGludCBvYmplY3QuCisgICBSZXR1cm5zIC0xIGFuZCBzZXRzIGFuIGVycm9yIGNvbmRpdGlvbiBpZiBvdmVyZmxvdyBvY2N1cnMuICovCisKK2xvbmcKK1B5TG9uZ19Bc0xvbmcoUHlPYmplY3QgKm9iaikKK3sKKyAgICBpbnQgb3ZlcmZsb3c7CisgICAgbG9uZyByZXN1bHQgPSBQeUxvbmdfQXNMb25nQW5kT3ZlcmZsb3cob2JqLCAmb3ZlcmZsb3cpOworICAgIGlmIChvdmVyZmxvdykgeworICAgICAgICAvKiBYWFg6IGNvdWxkIGJlIGN1dGUgYW5kIGdpdmUgYSBkaWZmZXJlbnQKKyAgICAgICAgICAgbWVzc2FnZSBmb3Igb3ZlcmZsb3cgPT0gLTEgKi8KKyAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX092ZXJmbG93RXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAgICAiUHl0aG9uIGludCB0b28gbGFyZ2UgdG8gY29udmVydCB0byBDIGxvbmciKTsKKyAgICB9CisgICAgcmV0dXJuIHJlc3VsdDsKK30KKworLyogR2V0IGEgQyBpbnQgZnJvbSBhIGxvbmcgaW50IG9iamVjdCBvciBhbnkgb2JqZWN0IHRoYXQgaGFzIGFuIF9faW50X18KKyAgIG1ldGhvZC4gIFJldHVybiAtMSBhbmQgc2V0IGFuIGVycm9yIGlmIG92ZXJmbG93IG9jY3Vycy4gKi8KKworaW50CitfUHlMb25nX0FzSW50KFB5T2JqZWN0ICpvYmopCit7CisgICAgaW50IG92ZXJmbG93OworICAgIGxvbmcgcmVzdWx0ID0gUHlMb25nX0FzTG9uZ0FuZE92ZXJmbG93KG9iaiwgJm92ZXJmbG93KTsKKyAgICBpZiAob3ZlcmZsb3cgfHwgcmVzdWx0ID4gSU5UX01BWCB8fCByZXN1bHQgPCBJTlRfTUlOKSB7CisgICAgICAgIC8qIFhYWDogY291bGQgYmUgY3V0ZSBhbmQgZ2l2ZSBhIGRpZmZlcmVudAorICAgICAgICAgICBtZXNzYWdlIGZvciBvdmVyZmxvdyA9PSAtMSAqLworICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfT3ZlcmZsb3dFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICJQeXRob24gaW50IHRvbyBsYXJnZSB0byBjb252ZXJ0IHRvIEMgaW50Iik7CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisgICAgcmV0dXJuIChpbnQpcmVzdWx0OworfQorCisvKiBHZXQgYSBQeV9zc2l6ZV90IGZyb20gYSBsb25nIGludCBvYmplY3QuCisgICBSZXR1cm5zIC0xIGFuZCBzZXRzIGFuIGVycm9yIGNvbmRpdGlvbiBpZiBvdmVyZmxvdyBvY2N1cnMuICovCisKK1B5X3NzaXplX3QKK1B5TG9uZ19Bc1NzaXplX3QoUHlPYmplY3QgKnZ2KSB7CisgICAgcmVnaXN0ZXIgUHlMb25nT2JqZWN0ICp2OworICAgIHNpemVfdCB4LCBwcmV2OworICAgIFB5X3NzaXplX3QgaTsKKyAgICBpbnQgc2lnbjsKKworICAgIGlmICh2diA9PSBOVUxMIHx8ICFQeUxvbmdfQ2hlY2sodnYpKSB7CisgICAgICAgIFB5RXJyX0JhZEludGVybmFsQ2FsbCgpOworICAgICAgICByZXR1cm4gLTE7CisgICAgfQorICAgIHYgPSAoUHlMb25nT2JqZWN0ICopdnY7CisgICAgaSA9IHYtPm9iX3NpemU7CisgICAgc2lnbiA9IDE7CisgICAgeCA9IDA7CisgICAgaWYgKGkgPCAwKSB7CisgICAgICAgIHNpZ24gPSAtMTsKKyAgICAgICAgaSA9IC0oaSk7CisgICAgfQorICAgIHdoaWxlICgtLWkgPj0gMCkgeworICAgICAgICBwcmV2ID0geDsKKyAgICAgICAgeCA9ICh4IDw8IFB5TG9uZ19TSElGVCkgfCB2LT5vYl9kaWdpdFtpXTsKKyAgICAgICAgaWYgKCh4ID4+IFB5TG9uZ19TSElGVCkgIT0gcHJldikKKyAgICAgICAgICAgIGdvdG8gb3ZlcmZsb3c7CisgICAgfQorICAgIC8qIEhhdmVuJ3QgbG9zdCBhbnkgYml0cywgYnV0IGNhc3RpbmcgdG8gYSBzaWduZWQgdHlwZSByZXF1aXJlcworICAgICAqIGV4dHJhIGNhcmUgKHNlZSBjb21tZW50IGFib3ZlKS4KKyAgICAgKi8KKyAgICBpZiAoeCA8PSAoc2l6ZV90KVBZX1NTSVpFX1RfTUFYKSB7CisgICAgICAgIHJldHVybiAoUHlfc3NpemVfdCl4ICogc2lnbjsKKyAgICB9CisgICAgZWxzZSBpZiAoc2lnbiA8IDAgJiYgeCA9PSBQWV9BQlNfU1NJWkVfVF9NSU4pIHsKKyAgICAgICAgcmV0dXJuIFBZX1NTSVpFX1RfTUlOOworICAgIH0KKyAgICAvKiBlbHNlIG92ZXJmbG93ICovCisKKyAgb3ZlcmZsb3c6CisgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX092ZXJmbG93RXJyb3IsCisgICAgICAgICAgICAgICAgICAgICJsb25nIGludCB0b28gbGFyZ2UgdG8gY29udmVydCB0byBpbnQiKTsKKyAgICByZXR1cm4gLTE7Cit9CisKKy8qIEdldCBhIEMgdW5zaWduZWQgbG9uZyBpbnQgZnJvbSBhIGxvbmcgaW50IG9iamVjdC4KKyAgIFJldHVybnMgLTEgYW5kIHNldHMgYW4gZXJyb3IgY29uZGl0aW9uIGlmIG92ZXJmbG93IG9jY3Vycy4gKi8KKwordW5zaWduZWQgbG9uZworUHlMb25nX0FzVW5zaWduZWRMb25nKFB5T2JqZWN0ICp2dikKK3sKKyAgICByZWdpc3RlciBQeUxvbmdPYmplY3QgKnY7CisgICAgdW5zaWduZWQgbG9uZyB4LCBwcmV2OworICAgIFB5X3NzaXplX3QgaTsKKworICAgIGlmICh2diA9PSBOVUxMIHx8ICFQeUxvbmdfQ2hlY2sodnYpKSB7CisgICAgICAgIGlmICh2diAhPSBOVUxMICYmIFB5SW50X0NoZWNrKHZ2KSkgeworICAgICAgICAgICAgbG9uZyB2YWwgPSBQeUludF9Bc0xvbmcodnYpOworICAgICAgICAgICAgaWYgKHZhbCA8IDApIHsKKyAgICAgICAgICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfT3ZlcmZsb3dFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImNhbid0IGNvbnZlcnQgbmVnYXRpdmUgdmFsdWUgIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidG8gdW5zaWduZWQgbG9uZyIpOworICAgICAgICAgICAgICAgIHJldHVybiAodW5zaWduZWQgbG9uZykgLTE7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXR1cm4gdmFsOworICAgICAgICB9CisgICAgICAgIFB5RXJyX0JhZEludGVybmFsQ2FsbCgpOworICAgICAgICByZXR1cm4gKHVuc2lnbmVkIGxvbmcpIC0xOworICAgIH0KKyAgICB2ID0gKFB5TG9uZ09iamVjdCAqKXZ2OworICAgIGkgPSBQeV9TSVpFKHYpOworICAgIHggPSAwOworICAgIGlmIChpIDwgMCkgeworICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfT3ZlcmZsb3dFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICJjYW4ndCBjb252ZXJ0IG5lZ2F0aXZlIHZhbHVlIHRvIHVuc2lnbmVkIGxvbmciKTsKKyAgICAgICAgcmV0dXJuICh1bnNpZ25lZCBsb25nKSAtMTsKKyAgICB9CisgICAgd2hpbGUgKC0taSA+PSAwKSB7CisgICAgICAgIHByZXYgPSB4OworICAgICAgICB4ID0gKHggPDwgUHlMb25nX1NISUZUKSB8IHYtPm9iX2RpZ2l0W2ldOworICAgICAgICBpZiAoKHggPj4gUHlMb25nX1NISUZUKSAhPSBwcmV2KSB7CisgICAgICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfT3ZlcmZsb3dFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAibG9uZyBpbnQgdG9vIGxhcmdlIHRvIGNvbnZlcnQiKTsKKyAgICAgICAgICAgIHJldHVybiAodW5zaWduZWQgbG9uZykgLTE7CisgICAgICAgIH0KKyAgICB9CisgICAgcmV0dXJuIHg7Cit9CisKKy8qIEdldCBhIEMgdW5zaWduZWQgbG9uZyBpbnQgZnJvbSBhIGxvbmcgaW50IG9iamVjdCwgaWdub3JpbmcgdGhlIGhpZ2ggYml0cy4KKyAgIFJldHVybnMgLTEgYW5kIHNldHMgYW4gZXJyb3IgY29uZGl0aW9uIGlmIGFuIGVycm9yIG9jY3Vycy4gKi8KKwordW5zaWduZWQgbG9uZworUHlMb25nX0FzVW5zaWduZWRMb25nTWFzayhQeU9iamVjdCAqdnYpCit7CisgICAgcmVnaXN0ZXIgUHlMb25nT2JqZWN0ICp2OworICAgIHVuc2lnbmVkIGxvbmcgeDsKKyAgICBQeV9zc2l6ZV90IGk7CisgICAgaW50IHNpZ247CisKKyAgICBpZiAodnYgPT0gTlVMTCB8fCAhUHlMb25nX0NoZWNrKHZ2KSkgeworICAgICAgICBpZiAodnYgIT0gTlVMTCAmJiBQeUludF9DaGVjayh2dikpCisgICAgICAgICAgICByZXR1cm4gUHlJbnRfQXNVbnNpZ25lZExvbmdNYXNrKHZ2KTsKKyAgICAgICAgUHlFcnJfQmFkSW50ZXJuYWxDYWxsKCk7CisgICAgICAgIHJldHVybiAodW5zaWduZWQgbG9uZykgLTE7CisgICAgfQorICAgIHYgPSAoUHlMb25nT2JqZWN0ICopdnY7CisgICAgaSA9IHYtPm9iX3NpemU7CisgICAgc2lnbiA9IDE7CisgICAgeCA9IDA7CisgICAgaWYgKGkgPCAwKSB7CisgICAgICAgIHNpZ24gPSAtMTsKKyAgICAgICAgaSA9IC1pOworICAgIH0KKyAgICB3aGlsZSAoLS1pID49IDApIHsKKyAgICAgICAgeCA9ICh4IDw8IFB5TG9uZ19TSElGVCkgfCB2LT5vYl9kaWdpdFtpXTsKKyAgICB9CisgICAgcmV0dXJuIHggKiBzaWduOworfQorCitpbnQKK19QeUxvbmdfU2lnbihQeU9iamVjdCAqdnYpCit7CisgICAgUHlMb25nT2JqZWN0ICp2ID0gKFB5TG9uZ09iamVjdCAqKXZ2OworCisgICAgYXNzZXJ0KHYgIT0gTlVMTCk7CisgICAgYXNzZXJ0KFB5TG9uZ19DaGVjayh2KSk7CisKKyAgICByZXR1cm4gUHlfU0laRSh2KSA9PSAwID8gMCA6IChQeV9TSVpFKHYpIDwgMCA/IC0xIDogMSk7Cit9CisKK3NpemVfdAorX1B5TG9uZ19OdW1CaXRzKFB5T2JqZWN0ICp2dikKK3sKKyAgICBQeUxvbmdPYmplY3QgKnYgPSAoUHlMb25nT2JqZWN0ICopdnY7CisgICAgc2l6ZV90IHJlc3VsdCA9IDA7CisgICAgUHlfc3NpemVfdCBuZGlnaXRzOworCisgICAgYXNzZXJ0KHYgIT0gTlVMTCk7CisgICAgYXNzZXJ0KFB5TG9uZ19DaGVjayh2KSk7CisgICAgbmRpZ2l0cyA9IEFCUyhQeV9TSVpFKHYpKTsKKyAgICBhc3NlcnQobmRpZ2l0cyA9PSAwIHx8IHYtPm9iX2RpZ2l0W25kaWdpdHMgLSAxXSAhPSAwKTsKKyAgICBpZiAobmRpZ2l0cyA+IDApIHsKKyAgICAgICAgZGlnaXQgbXNkID0gdi0+b2JfZGlnaXRbbmRpZ2l0cyAtIDFdOworCisgICAgICAgIHJlc3VsdCA9IChuZGlnaXRzIC0gMSkgKiBQeUxvbmdfU0hJRlQ7CisgICAgICAgIGlmIChyZXN1bHQgLyBQeUxvbmdfU0hJRlQgIT0gKHNpemVfdCkobmRpZ2l0cyAtIDEpKQorICAgICAgICAgICAgZ290byBPdmVyZmxvdzsKKyAgICAgICAgZG8geworICAgICAgICAgICAgKytyZXN1bHQ7CisgICAgICAgICAgICBpZiAocmVzdWx0ID09IDApCisgICAgICAgICAgICAgICAgZ290byBPdmVyZmxvdzsKKyAgICAgICAgICAgIG1zZCA+Pj0gMTsKKyAgICAgICAgfSB3aGlsZSAobXNkKTsKKyAgICB9CisgICAgcmV0dXJuIHJlc3VsdDsKKworICBPdmVyZmxvdzoKKyAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfT3ZlcmZsb3dFcnJvciwgImxvbmcgaGFzIHRvbyBtYW55IGJpdHMgIgorICAgICAgICAgICAgICAgICAgICAidG8gZXhwcmVzcyBpbiBhIHBsYXRmb3JtIHNpemVfdCIpOworICAgIHJldHVybiAoc2l6ZV90KS0xOworfQorCitQeU9iamVjdCAqCitfUHlMb25nX0Zyb21CeXRlQXJyYXkoY29uc3QgdW5zaWduZWQgY2hhciogYnl0ZXMsIHNpemVfdCBuLAorICAgICAgICAgICAgICAgICAgICAgIGludCBsaXR0bGVfZW5kaWFuLCBpbnQgaXNfc2lnbmVkKQoreworICAgIGNvbnN0IHVuc2lnbmVkIGNoYXIqIHBzdGFydGJ5dGU7ICAgIC8qIExTQiBvZiBieXRlcyAqLworICAgIGludCBpbmNyOyAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIGRpcmVjdGlvbiB0byBtb3ZlIHBzdGFydGJ5dGUgKi8KKyAgICBjb25zdCB1bnNpZ25lZCBjaGFyKiBwZW5kYnl0ZTsgICAgICAvKiBNU0Igb2YgYnl0ZXMgKi8KKyAgICBzaXplX3QgbnVtc2lnbmlmaWNhbnRieXRlczsgICAgICAgICAvKiBudW1iZXIgb2YgYnl0ZXMgdGhhdCBtYXR0ZXIgKi8KKyAgICBQeV9zc2l6ZV90IG5kaWdpdHM7ICAgICAgICAgICAgICAgICAvKiBudW1iZXIgb2YgUHl0aG9uIGxvbmcgZGlnaXRzICovCisgICAgUHlMb25nT2JqZWN0KiB2OyAgICAgICAgICAgICAgICAgICAgLyogcmVzdWx0ICovCisgICAgUHlfc3NpemVfdCBpZGlnaXQgPSAwOyAgICAgICAgICAgICAgLyogbmV4dCBmcmVlIGluZGV4IGluIHYtPm9iX2RpZ2l0ICovCisKKyAgICBpZiAobiA9PSAwKQorICAgICAgICByZXR1cm4gUHlMb25nX0Zyb21Mb25nKDBMKTsKKworICAgIGlmIChsaXR0bGVfZW5kaWFuKSB7CisgICAgICAgIHBzdGFydGJ5dGUgPSBieXRlczsKKyAgICAgICAgcGVuZGJ5dGUgPSBieXRlcyArIG4gLSAxOworICAgICAgICBpbmNyID0gMTsKKyAgICB9CisgICAgZWxzZSB7CisgICAgICAgIHBzdGFydGJ5dGUgPSBieXRlcyArIG4gLSAxOworICAgICAgICBwZW5kYnl0ZSA9IGJ5dGVzOworICAgICAgICBpbmNyID0gLTE7CisgICAgfQorCisgICAgaWYgKGlzX3NpZ25lZCkKKyAgICAgICAgaXNfc2lnbmVkID0gKnBlbmRieXRlID49IDB4ODA7CisKKyAgICAvKiBDb21wdXRlIG51bXNpZ25pZmljYW50Ynl0ZXMuICBUaGlzIGNvbnNpc3RzIG9mIGZpbmRpbmcgdGhlIG1vc3QKKyAgICAgICBzaWduaWZpY2FudCBieXRlLiAgTGVhZGluZyAwIGJ5dGVzIGFyZSBpbnNpZ25pZmljYW50IGlmIHRoZSBudW1iZXIKKyAgICAgICBpcyBwb3NpdGl2ZSwgYW5kIGxlYWRpbmcgMHhmZiBieXRlcyBpZiBuZWdhdGl2ZS4gKi8KKyAgICB7CisgICAgICAgIHNpemVfdCBpOworICAgICAgICBjb25zdCB1bnNpZ25lZCBjaGFyKiBwID0gcGVuZGJ5dGU7CisgICAgICAgIGNvbnN0IGludCBwaW5jciA9IC1pbmNyOyAgLyogc2VhcmNoIE1TQiB0byBMU0IgKi8KKyAgICAgICAgY29uc3QgdW5zaWduZWQgY2hhciBpbnNpZ25maWNhbnQgPSBpc19zaWduZWQgPyAweGZmIDogMHgwMDsKKworICAgICAgICBmb3IgKGkgPSAwOyBpIDwgbjsgKytpLCBwICs9IHBpbmNyKSB7CisgICAgICAgICAgICBpZiAoKnAgIT0gaW5zaWduZmljYW50KQorICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisgICAgICAgIG51bXNpZ25pZmljYW50Ynl0ZXMgPSBuIC0gaTsKKyAgICAgICAgLyogMidzLWNvbXAgaXMgYSBiaXQgdHJpY2t5IGhlcmUsIGUuZy4gMHhmZjAwID09IC0weDAxMDAsIHNvCisgICAgICAgICAgIGFjdHVhbGx5IGhhcyAyIHNpZ25pZmljYW50IGJ5dGVzLiAgT1RPSCwgMHhmZjAwMDEgPT0KKyAgICAgICAgICAgLTB4MDBmZmZmLCBzbyB3ZSB3b3VsZG4ndCAqbmVlZCogdG8gYnVtcCBpdCB0aGVyZTsgYnV0IHdlCisgICAgICAgICAgIGRvIGZvciAweGZmZmYgPSAtMHgwMDAxLiAgVG8gYmUgc2FmZSB3aXRob3V0IGJvdGhlcmluZyB0bworICAgICAgICAgICBjaGVjayBldmVyeSBjYXNlLCBidW1wIGl0IHJlZ2FyZGxlc3MuICovCisgICAgICAgIGlmIChpc19zaWduZWQgJiYgbnVtc2lnbmlmaWNhbnRieXRlcyA8IG4pCisgICAgICAgICAgICArK251bXNpZ25pZmljYW50Ynl0ZXM7CisgICAgfQorCisgICAgLyogSG93IG1hbnkgUHl0aG9uIGxvbmcgZGlnaXRzIGRvIHdlIG5lZWQ/ICBXZSBoYXZlCisgICAgICAgOCpudW1zaWduaWZpY2FudGJ5dGVzIGJpdHMsIGFuZCBlYWNoIFB5dGhvbiBsb25nIGRpZ2l0IGhhcworICAgICAgIFB5TG9uZ19TSElGVCBiaXRzLCBzbyBpdCdzIHRoZSBjZWlsaW5nIG9mIHRoZSBxdW90aWVudC4gKi8KKyAgICAvKiBjYXRjaCBvdmVyZmxvdyBiZWZvcmUgaXQgaGFwcGVucyAqLworICAgIGlmIChudW1zaWduaWZpY2FudGJ5dGVzID4gKFBZX1NTSVpFX1RfTUFYIC0gUHlMb25nX1NISUZUKSAvIDgpIHsKKyAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX092ZXJmbG93RXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAgICAiYnl0ZSBhcnJheSB0b28gbG9uZyB0byBjb252ZXJ0IHRvIGludCIpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgbmRpZ2l0cyA9IChudW1zaWduaWZpY2FudGJ5dGVzICogOCArIFB5TG9uZ19TSElGVCAtIDEpIC8gUHlMb25nX1NISUZUOworICAgIHYgPSBfUHlMb25nX05ldyhuZGlnaXRzKTsKKyAgICBpZiAodiA9PSBOVUxMKQorICAgICAgICByZXR1cm4gTlVMTDsKKworICAgIC8qIENvcHkgdGhlIGJpdHMgb3Zlci4gIFRoZSB0cmlja3kgcGFydHMgYXJlIGNvbXB1dGluZyAyJ3MtY29tcCBvbgorICAgICAgIHRoZSBmbHkgZm9yIHNpZ25lZCBudW1iZXJzLCBhbmQgZGVhbGluZyB3aXRoIHRoZSBtaXNtYXRjaCBiZXR3ZWVuCisgICAgICAgOC1iaXQgYnl0ZXMgYW5kIChwcm9iYWJseSkgMTUtYml0IFB5dGhvbiBkaWdpdHMuKi8KKyAgICB7CisgICAgICAgIHNpemVfdCBpOworICAgICAgICB0d29kaWdpdHMgY2FycnkgPSAxOyAgICAgICAgICAgICAgICAgICAgLyogZm9yIDIncy1jb21wIGNhbGN1bGF0aW9uICovCisgICAgICAgIHR3b2RpZ2l0cyBhY2N1bSA9IDA7ICAgICAgICAgICAgICAgICAgICAvKiBzbGlkaW5nIHJlZ2lzdGVyICovCisgICAgICAgIHVuc2lnbmVkIGludCBhY2N1bWJpdHMgPSAwOyAgICAgICAgICAgICAvKiBudW1iZXIgb2YgYml0cyBpbiBhY2N1bSAqLworICAgICAgICBjb25zdCB1bnNpZ25lZCBjaGFyKiBwID0gcHN0YXJ0Ynl0ZTsKKworICAgICAgICBmb3IgKGkgPSAwOyBpIDwgbnVtc2lnbmlmaWNhbnRieXRlczsgKytpLCBwICs9IGluY3IpIHsKKyAgICAgICAgICAgIHR3b2RpZ2l0cyB0aGlzYnl0ZSA9ICpwOworICAgICAgICAgICAgLyogQ29tcHV0ZSBjb3JyZWN0aW9uIGZvciAyJ3MgY29tcCwgaWYgbmVlZGVkLiAqLworICAgICAgICAgICAgaWYgKGlzX3NpZ25lZCkgeworICAgICAgICAgICAgICAgIHRoaXNieXRlID0gKDB4ZmYgXiB0aGlzYnl0ZSkgKyBjYXJyeTsKKyAgICAgICAgICAgICAgICBjYXJyeSA9IHRoaXNieXRlID4+IDg7CisgICAgICAgICAgICAgICAgdGhpc2J5dGUgJj0gMHhmZjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIC8qIEJlY2F1c2Ugd2UncmUgZ29pbmcgTFNCIHRvIE1TQiwgdGhpc2J5dGUgaXMKKyAgICAgICAgICAgICAgIG1vcmUgc2lnbmlmaWNhbnQgdGhhbiB3aGF0J3MgYWxyZWFkeSBpbiBhY2N1bSwKKyAgICAgICAgICAgICAgIHNvIG5lZWRzIHRvIGJlIHByZXBlbmRlZCB0byBhY2N1bS4gKi8KKyAgICAgICAgICAgIGFjY3VtIHw9ICh0d29kaWdpdHMpdGhpc2J5dGUgPDwgYWNjdW1iaXRzOworICAgICAgICAgICAgYWNjdW1iaXRzICs9IDg7CisgICAgICAgICAgICBpZiAoYWNjdW1iaXRzID49IFB5TG9uZ19TSElGVCkgeworICAgICAgICAgICAgICAgIC8qIFRoZXJlJ3MgZW5vdWdoIHRvIGZpbGwgYSBQeXRob24gZGlnaXQuICovCisgICAgICAgICAgICAgICAgYXNzZXJ0KGlkaWdpdCA8IG5kaWdpdHMpOworICAgICAgICAgICAgICAgIHYtPm9iX2RpZ2l0W2lkaWdpdF0gPSAoZGlnaXQpKGFjY3VtICYgUHlMb25nX01BU0spOworICAgICAgICAgICAgICAgICsraWRpZ2l0OworICAgICAgICAgICAgICAgIGFjY3VtID4+PSBQeUxvbmdfU0hJRlQ7CisgICAgICAgICAgICAgICAgYWNjdW1iaXRzIC09IFB5TG9uZ19TSElGVDsKKyAgICAgICAgICAgICAgICBhc3NlcnQoYWNjdW1iaXRzIDwgUHlMb25nX1NISUZUKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBhc3NlcnQoYWNjdW1iaXRzIDwgUHlMb25nX1NISUZUKTsKKyAgICAgICAgaWYgKGFjY3VtYml0cykgeworICAgICAgICAgICAgYXNzZXJ0KGlkaWdpdCA8IG5kaWdpdHMpOworICAgICAgICAgICAgdi0+b2JfZGlnaXRbaWRpZ2l0XSA9IChkaWdpdClhY2N1bTsKKyAgICAgICAgICAgICsraWRpZ2l0OworICAgICAgICB9CisgICAgfQorCisgICAgUHlfU0laRSh2KSA9IGlzX3NpZ25lZCA/IC1pZGlnaXQgOiBpZGlnaXQ7CisgICAgcmV0dXJuIChQeU9iamVjdCAqKWxvbmdfbm9ybWFsaXplKHYpOworfQorCitpbnQKK19QeUxvbmdfQXNCeXRlQXJyYXkoUHlMb25nT2JqZWN0KiB2LAorICAgICAgICAgICAgICAgICAgICB1bnNpZ25lZCBjaGFyKiBieXRlcywgc2l6ZV90IG4sCisgICAgICAgICAgICAgICAgICAgIGludCBsaXR0bGVfZW5kaWFuLCBpbnQgaXNfc2lnbmVkKQoreworICAgIFB5X3NzaXplX3QgaTsgICAgICAgICAgICAgICAvKiBpbmRleCBpbnRvIHYtPm9iX2RpZ2l0ICovCisgICAgUHlfc3NpemVfdCBuZGlnaXRzOyAgICAgICAgIC8qIHx2LT5vYl9zaXplfCAqLworICAgIHR3b2RpZ2l0cyBhY2N1bTsgICAgICAgICAgICAvKiBzbGlkaW5nIHJlZ2lzdGVyICovCisgICAgdW5zaWduZWQgaW50IGFjY3VtYml0czsgICAgIC8qICMgYml0cyBpbiBhY2N1bSAqLworICAgIGludCBkb190d29zX2NvbXA7ICAgICAgICAgICAvKiBzdG9yZSAyJ3MtY29tcD8gIGlzX3NpZ25lZCBhbmQgdiA8IDAgKi8KKyAgICBkaWdpdCBjYXJyeTsgICAgICAgICAgICAgICAgLyogZm9yIGNvbXB1dGluZyAyJ3MtY29tcCAqLworICAgIHNpemVfdCBqOyAgICAgICAgICAgICAgICAgICAvKiAjIGJ5dGVzIGZpbGxlZCAqLworICAgIHVuc2lnbmVkIGNoYXIqIHA7ICAgICAgICAgICAvKiBwb2ludGVyIHRvIG5leHQgYnl0ZSBpbiBieXRlcyAqLworICAgIGludCBwaW5jcjsgICAgICAgICAgICAgICAgICAvKiBkaXJlY3Rpb24gdG8gbW92ZSBwICovCisKKyAgICBhc3NlcnQodiAhPSBOVUxMICYmIFB5TG9uZ19DaGVjayh2KSk7CisKKyAgICBpZiAoUHlfU0laRSh2KSA8IDApIHsKKyAgICAgICAgbmRpZ2l0cyA9IC0oUHlfU0laRSh2KSk7CisgICAgICAgIGlmICghaXNfc2lnbmVkKSB7CisgICAgICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfT3ZlcmZsb3dFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAiY2FuJ3QgY29udmVydCBuZWdhdGl2ZSBsb25nIHRvIHVuc2lnbmVkIik7CisgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgIH0KKyAgICAgICAgZG9fdHdvc19jb21wID0gMTsKKyAgICB9CisgICAgZWxzZSB7CisgICAgICAgIG5kaWdpdHMgPSBQeV9TSVpFKHYpOworICAgICAgICBkb190d29zX2NvbXAgPSAwOworICAgIH0KKworICAgIGlmIChsaXR0bGVfZW5kaWFuKSB7CisgICAgICAgIHAgPSBieXRlczsKKyAgICAgICAgcGluY3IgPSAxOworICAgIH0KKyAgICBlbHNlIHsKKyAgICAgICAgcCA9IGJ5dGVzICsgbiAtIDE7CisgICAgICAgIHBpbmNyID0gLTE7CisgICAgfQorCisgICAgLyogQ29weSBvdmVyIGFsbCB0aGUgUHl0aG9uIGRpZ2l0cy4KKyAgICAgICBJdCdzIGNydWNpYWwgdGhhdCBldmVyeSBQeXRob24gZGlnaXQgZXhjZXB0IGZvciB0aGUgTVNEIGNvbnRyaWJ1dGUKKyAgICAgICBleGFjdGx5IFB5TG9uZ19TSElGVCBiaXRzIHRvIHRoZSB0b3RhbCwgc28gZmlyc3QgYXNzZXJ0IHRoYXQgdGhlIGxvbmcgaXMKKyAgICAgICBub3JtYWxpemVkLiAqLworICAgIGFzc2VydChuZGlnaXRzID09IDAgfHwgdi0+b2JfZGlnaXRbbmRpZ2l0cyAtIDFdICE9IDApOworICAgIGogPSAwOworICAgIGFjY3VtID0gMDsKKyAgICBhY2N1bWJpdHMgPSAwOworICAgIGNhcnJ5ID0gZG9fdHdvc19jb21wID8gMSA6IDA7CisgICAgZm9yIChpID0gMDsgaSA8IG5kaWdpdHM7ICsraSkgeworICAgICAgICBkaWdpdCB0aGlzZGlnaXQgPSB2LT5vYl9kaWdpdFtpXTsKKyAgICAgICAgaWYgKGRvX3R3b3NfY29tcCkgeworICAgICAgICAgICAgdGhpc2RpZ2l0ID0gKHRoaXNkaWdpdCBeIFB5TG9uZ19NQVNLKSArIGNhcnJ5OworICAgICAgICAgICAgY2FycnkgPSB0aGlzZGlnaXQgPj4gUHlMb25nX1NISUZUOworICAgICAgICAgICAgdGhpc2RpZ2l0ICY9IFB5TG9uZ19NQVNLOworICAgICAgICB9CisgICAgICAgIC8qIEJlY2F1c2Ugd2UncmUgZ29pbmcgTFNCIHRvIE1TQiwgdGhpc2RpZ2l0IGlzIG1vcmUKKyAgICAgICAgICAgc2lnbmlmaWNhbnQgdGhhbiB3aGF0J3MgYWxyZWFkeSBpbiBhY2N1bSwgc28gbmVlZHMgdG8gYmUKKyAgICAgICAgICAgcHJlcGVuZGVkIHRvIGFjY3VtLiAqLworICAgICAgICBhY2N1bSB8PSAodHdvZGlnaXRzKXRoaXNkaWdpdCA8PCBhY2N1bWJpdHM7CisKKyAgICAgICAgLyogVGhlIG1vc3Qtc2lnbmlmaWNhbnQgZGlnaXQgbWF5IGJlIChwcm9iYWJseSBpcykgYXQgbGVhc3QKKyAgICAgICAgICAgcGFydGx5IGVtcHR5LiAqLworICAgICAgICBpZiAoaSA9PSBuZGlnaXRzIC0gMSkgeworICAgICAgICAgICAgLyogQ291bnQgIyBvZiBzaWduIGJpdHMgLS0gdGhleSBuZWVkbid0IGJlIHN0b3JlZCwKKyAgICAgICAgICAgICAqIGFsdGhvdWdoIGZvciBzaWduZWQgY29udmVyc2lvbiB3ZSBuZWVkIGxhdGVyIHRvCisgICAgICAgICAgICAgKiBtYWtlIHN1cmUgYXQgbGVhc3Qgb25lIHNpZ24gYml0IGdldHMgc3RvcmVkLiAqLworICAgICAgICAgICAgZGlnaXQgcyA9IGRvX3R3b3NfY29tcCA/IHRoaXNkaWdpdCBeIFB5TG9uZ19NQVNLIDogdGhpc2RpZ2l0OworICAgICAgICAgICAgd2hpbGUgKHMgIT0gMCkgeworICAgICAgICAgICAgICAgIHMgPj49IDE7CisgICAgICAgICAgICAgICAgYWNjdW1iaXRzKys7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgZWxzZQorICAgICAgICAgICAgYWNjdW1iaXRzICs9IFB5TG9uZ19TSElGVDsKKworICAgICAgICAvKiBTdG9yZSBhcyBtYW55IGJ5dGVzIGFzIHBvc3NpYmxlLiAqLworICAgICAgICB3aGlsZSAoYWNjdW1iaXRzID49IDgpIHsKKyAgICAgICAgICAgIGlmIChqID49IG4pCisgICAgICAgICAgICAgICAgZ290byBPdmVyZmxvdzsKKyAgICAgICAgICAgICsrajsKKyAgICAgICAgICAgICpwID0gKHVuc2lnbmVkIGNoYXIpKGFjY3VtICYgMHhmZik7CisgICAgICAgICAgICBwICs9IHBpbmNyOworICAgICAgICAgICAgYWNjdW1iaXRzIC09IDg7CisgICAgICAgICAgICBhY2N1bSA+Pj0gODsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qIFN0b3JlIHRoZSBzdHJhZ2dsZXIgKGlmIGFueSkuICovCisgICAgYXNzZXJ0KGFjY3VtYml0cyA8IDgpOworICAgIGFzc2VydChjYXJyeSA9PSAwKTsgIC8qIGVsc2UgZG9fdHdvc19jb21wIGFuZCAqZXZlcnkqIGRpZ2l0IHdhcyAwICovCisgICAgaWYgKGFjY3VtYml0cyA+IDApIHsKKyAgICAgICAgaWYgKGogPj0gbikKKyAgICAgICAgICAgIGdvdG8gT3ZlcmZsb3c7CisgICAgICAgICsrajsKKyAgICAgICAgaWYgKGRvX3R3b3NfY29tcCkgeworICAgICAgICAgICAgLyogRmlsbCBsZWFkaW5nIGJpdHMgb2YgdGhlIGJ5dGUgd2l0aCBzaWduIGJpdHMKKyAgICAgICAgICAgICAgIChhcHByb3ByaWF0ZWx5IHByZXRlbmRpbmcgdGhhdCB0aGUgbG9uZyBoYWQgYW4KKyAgICAgICAgICAgICAgIGluZmluaXRlIHN1cHBseSBvZiBzaWduIGJpdHMpLiAqLworICAgICAgICAgICAgYWNjdW0gfD0gKH4odHdvZGlnaXRzKTApIDw8IGFjY3VtYml0czsKKyAgICAgICAgfQorICAgICAgICAqcCA9ICh1bnNpZ25lZCBjaGFyKShhY2N1bSAmIDB4ZmYpOworICAgICAgICBwICs9IHBpbmNyOworICAgIH0KKyAgICBlbHNlIGlmIChqID09IG4gJiYgbiA+IDAgJiYgaXNfc2lnbmVkKSB7CisgICAgICAgIC8qIFRoZSBtYWluIGxvb3AgZmlsbGVkIHRoZSBieXRlIGFycmF5IGV4YWN0bHksIHNvIHRoZSBjb2RlCisgICAgICAgICAgIGp1c3QgYWJvdmUgZGlkbid0IGdldCB0byBlbnN1cmUgdGhlcmUncyBhIHNpZ24gYml0LCBhbmQgdGhlCisgICAgICAgICAgIGxvb3AgYmVsb3cgd291bGRuJ3QgYWRkIG9uZSBlaXRoZXIuICBNYWtlIHN1cmUgYSBzaWduIGJpdAorICAgICAgICAgICBleGlzdHMuICovCisgICAgICAgIHVuc2lnbmVkIGNoYXIgbXNiID0gKihwIC0gcGluY3IpOworICAgICAgICBpbnQgc2lnbl9iaXRfc2V0ID0gbXNiID49IDB4ODA7CisgICAgICAgIGFzc2VydChhY2N1bWJpdHMgPT0gMCk7CisgICAgICAgIGlmIChzaWduX2JpdF9zZXQgPT0gZG9fdHdvc19jb21wKQorICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgIGVsc2UKKyAgICAgICAgICAgIGdvdG8gT3ZlcmZsb3c7CisgICAgfQorCisgICAgLyogRmlsbCByZW1haW5pbmcgYnl0ZXMgd2l0aCBjb3BpZXMgb2YgdGhlIHNpZ24gYml0LiAqLworICAgIHsKKyAgICAgICAgdW5zaWduZWQgY2hhciBzaWduYnl0ZSA9IGRvX3R3b3NfY29tcCA/IDB4ZmZVIDogMFU7CisgICAgICAgIGZvciAoIDsgaiA8IG47ICsraiwgcCArPSBwaW5jcikKKyAgICAgICAgICAgICpwID0gc2lnbmJ5dGU7CisgICAgfQorCisgICAgcmV0dXJuIDA7CisKKyAgT3ZlcmZsb3c6CisgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX092ZXJmbG93RXJyb3IsICJsb25nIHRvbyBiaWcgdG8gY29udmVydCIpOworICAgIHJldHVybiAtMTsKKworfQorCisvKiBDcmVhdGUgYSBuZXcgbG9uZyAob3IgaW50KSBvYmplY3QgZnJvbSBhIEMgcG9pbnRlciAqLworCitQeU9iamVjdCAqCitQeUxvbmdfRnJvbVZvaWRQdHIodm9pZCAqcCkKK3sKKyNpZiBTSVpFT0ZfVk9JRF9QIDw9IFNJWkVPRl9MT05HCisgICAgaWYgKChsb25nKXAgPCAwKQorICAgICAgICByZXR1cm4gUHlMb25nX0Zyb21VbnNpZ25lZExvbmcoKHVuc2lnbmVkIGxvbmcpcCk7CisgICAgcmV0dXJuIFB5SW50X0Zyb21Mb25nKChsb25nKXApOworI2Vsc2UKKworI2lmbmRlZiBIQVZFX0xPTkdfTE9ORworIyAgIGVycm9yICJQeUxvbmdfRnJvbVZvaWRQdHI6IHNpemVvZih2b2lkKikgPiBzaXplb2YobG9uZyksIGJ1dCBubyBsb25nIGxvbmciCisjZW5kaWYKKyNpZiBTSVpFT0ZfTE9OR19MT05HIDwgU0laRU9GX1ZPSURfUAorIyAgIGVycm9yICJQeUxvbmdfRnJvbVZvaWRQdHI6IHNpemVvZihQWV9MT05HX0xPTkcpIDwgc2l6ZW9mKHZvaWQqKSIKKyNlbmRpZgorICAgIC8qIG9wdGltaXplIG51bGwgcG9pbnRlcnMgKi8KKyAgICBpZiAocCA9PSBOVUxMKQorICAgICAgICByZXR1cm4gUHlJbnRfRnJvbUxvbmcoMCk7CisgICAgcmV0dXJuIFB5TG9uZ19Gcm9tVW5zaWduZWRMb25nTG9uZygodW5zaWduZWQgUFlfTE9OR19MT05HKXApOworCisjZW5kaWYgLyogU0laRU9GX1ZPSURfUCA8PSBTSVpFT0ZfTE9ORyAqLworfQorCisvKiBHZXQgYSBDIHBvaW50ZXIgZnJvbSBhIGxvbmcgb2JqZWN0IChvciBhbiBpbnQgb2JqZWN0IGluIHNvbWUgY2FzZXMpICovCisKK3ZvaWQgKgorUHlMb25nX0FzVm9pZFB0cihQeU9iamVjdCAqdnYpCit7CisgICAgLyogVGhpcyBmdW5jdGlvbiB3aWxsIGFsbG93IGludCBvciBsb25nIG9iamVjdHMuIElmIHZ2IGlzIG5laXRoZXIsCisgICAgICAgdGhlbiB0aGUgUHlMb25nX0FzTG9uZyooKSBmdW5jdGlvbnMgd2lsbCByYWlzZSB0aGUgZXhjZXB0aW9uOgorICAgICAgIFB5RXhjX1N5c3RlbUVycm9yLCAiYmFkIGFyZ3VtZW50IHRvIGludGVybmFsIGZ1bmN0aW9uIgorICAgICovCisjaWYgU0laRU9GX1ZPSURfUCA8PSBTSVpFT0ZfTE9ORworICAgIGxvbmcgeDsKKworICAgIGlmIChQeUludF9DaGVjayh2dikpCisgICAgICAgIHggPSBQeUludF9BU19MT05HKHZ2KTsKKyAgICBlbHNlIGlmIChQeUxvbmdfQ2hlY2sodnYpICYmIF9QeUxvbmdfU2lnbih2dikgPCAwKQorICAgICAgICB4ID0gUHlMb25nX0FzTG9uZyh2dik7CisgICAgZWxzZQorICAgICAgICB4ID0gUHlMb25nX0FzVW5zaWduZWRMb25nKHZ2KTsKKyNlbHNlCisKKyNpZm5kZWYgSEFWRV9MT05HX0xPTkcKKyMgICBlcnJvciAiUHlMb25nX0FzVm9pZFB0cjogc2l6ZW9mKHZvaWQqKSA+IHNpemVvZihsb25nKSwgYnV0IG5vIGxvbmcgbG9uZyIKKyNlbmRpZgorI2lmIFNJWkVPRl9MT05HX0xPTkcgPCBTSVpFT0ZfVk9JRF9QCisjICAgZXJyb3IgIlB5TG9uZ19Bc1ZvaWRQdHI6IHNpemVvZihQWV9MT05HX0xPTkcpIDwgc2l6ZW9mKHZvaWQqKSIKKyNlbmRpZgorICAgIFBZX0xPTkdfTE9ORyB4OworCisgICAgaWYgKFB5SW50X0NoZWNrKHZ2KSkKKyAgICAgICAgeCA9IFB5SW50X0FTX0xPTkcodnYpOworICAgIGVsc2UgaWYgKFB5TG9uZ19DaGVjayh2dikgJiYgX1B5TG9uZ19TaWduKHZ2KSA8IDApCisgICAgICAgIHggPSBQeUxvbmdfQXNMb25nTG9uZyh2dik7CisgICAgZWxzZQorICAgICAgICB4ID0gUHlMb25nX0FzVW5zaWduZWRMb25nTG9uZyh2dik7CisKKyNlbmRpZiAvKiBTSVpFT0ZfVk9JRF9QIDw9IFNJWkVPRl9MT05HICovCisKKyAgICBpZiAoeCA9PSAtMSAmJiBQeUVycl9PY2N1cnJlZCgpKQorICAgICAgICByZXR1cm4gTlVMTDsKKyAgICByZXR1cm4gKHZvaWQgKil4OworfQorCisjaWZkZWYgSEFWRV9MT05HX0xPTkcKKworLyogSW5pdGlhbCBQWV9MT05HX0xPTkcgc3VwcG9ydCBieSBDaHJpcyBIZXJib3J0aCAoY2hyaXNoQHFueC5jb20pLCBsYXRlcgorICogcmV3cml0dGVuIHRvIHVzZSB0aGUgbmV3ZXIgUHlMb25nX3tBcyxGcm9tfUJ5dGVBcnJheSBBUEkuCisgKi8KKworI2RlZmluZSBJU19MSVRUTEVfRU5ESUFOIChpbnQpKih1bnNpZ25lZCBjaGFyKikmb25lCisjZGVmaW5lIFBZX0FCU19MTE9OR19NSU4gKDAtKHVuc2lnbmVkIFBZX0xPTkdfTE9ORylQWV9MTE9OR19NSU4pCisKKy8qIENyZWF0ZSBhIG5ldyBsb25nIGludCBvYmplY3QgZnJvbSBhIEMgUFlfTE9OR19MT05HIGludC4gKi8KKworUHlPYmplY3QgKgorUHlMb25nX0Zyb21Mb25nTG9uZyhQWV9MT05HX0xPTkcgaXZhbCkKK3sKKyAgICBQeUxvbmdPYmplY3QgKnY7CisgICAgdW5zaWduZWQgUFlfTE9OR19MT05HIGFic19pdmFsOworICAgIHVuc2lnbmVkIFBZX0xPTkdfTE9ORyB0OyAgLyogdW5zaWduZWQgc28gPj4gZG9lc24ndCBwcm9wYWdhdGUgc2lnbiBiaXQgKi8KKyAgICBpbnQgbmRpZ2l0cyA9IDA7CisgICAgaW50IG5lZ2F0aXZlID0gMDsKKworICAgIGlmIChpdmFsIDwgMCkgeworICAgICAgICAvKiBhdm9pZCBzaWduZWQgb3ZlcmZsb3cgb24gbmVnYXRpb247ICBzZWUgY29tbWVudHMKKyAgICAgICAgICAgaW4gUHlMb25nX0Zyb21Mb25nIGFib3ZlLiAqLworICAgICAgICBhYnNfaXZhbCA9ICh1bnNpZ25lZCBQWV9MT05HX0xPTkcpKC0xLWl2YWwpICsgMTsKKyAgICAgICAgbmVnYXRpdmUgPSAxOworICAgIH0KKyAgICBlbHNlIHsKKyAgICAgICAgYWJzX2l2YWwgPSAodW5zaWduZWQgUFlfTE9OR19MT05HKWl2YWw7CisgICAgfQorCisgICAgLyogQ291bnQgdGhlIG51bWJlciBvZiBQeXRob24gZGlnaXRzLgorICAgICAgIFdlIHVzZWQgdG8gcGljayA1ICgiYmlnIGVub3VnaCBmb3IgYW55dGhpbmciKSwgYnV0IHRoYXQncyBhCisgICAgICAgd2FzdGUgb2YgdGltZSBhbmQgc3BhY2UgZ2l2ZW4gdGhhdCA1KjE1ID0gNzUgYml0cyBhcmUgcmFyZWx5CisgICAgICAgbmVlZGVkLiAqLworICAgIHQgPSBhYnNfaXZhbDsKKyAgICB3aGlsZSAodCkgeworICAgICAgICArK25kaWdpdHM7CisgICAgICAgIHQgPj49IFB5TG9uZ19TSElGVDsKKyAgICB9CisgICAgdiA9IF9QeUxvbmdfTmV3KG5kaWdpdHMpOworICAgIGlmICh2ICE9IE5VTEwpIHsKKyAgICAgICAgZGlnaXQgKnAgPSB2LT5vYl9kaWdpdDsKKyAgICAgICAgUHlfU0laRSh2KSA9IG5lZ2F0aXZlID8gLW5kaWdpdHMgOiBuZGlnaXRzOworICAgICAgICB0ID0gYWJzX2l2YWw7CisgICAgICAgIHdoaWxlICh0KSB7CisgICAgICAgICAgICAqcCsrID0gKGRpZ2l0KSh0ICYgUHlMb25nX01BU0spOworICAgICAgICAgICAgdCA+Pj0gUHlMb25nX1NISUZUOworICAgICAgICB9CisgICAgfQorICAgIHJldHVybiAoUHlPYmplY3QgKil2OworfQorCisvKiBDcmVhdGUgYSBuZXcgbG9uZyBpbnQgb2JqZWN0IGZyb20gYSBDIHVuc2lnbmVkIFBZX0xPTkdfTE9ORyBpbnQuICovCisKK1B5T2JqZWN0ICoKK1B5TG9uZ19Gcm9tVW5zaWduZWRMb25nTG9uZyh1bnNpZ25lZCBQWV9MT05HX0xPTkcgaXZhbCkKK3sKKyAgICBQeUxvbmdPYmplY3QgKnY7CisgICAgdW5zaWduZWQgUFlfTE9OR19MT05HIHQ7CisgICAgaW50IG5kaWdpdHMgPSAwOworCisgICAgLyogQ291bnQgdGhlIG51bWJlciBvZiBQeXRob24gZGlnaXRzLiAqLworICAgIHQgPSAodW5zaWduZWQgUFlfTE9OR19MT05HKWl2YWw7CisgICAgd2hpbGUgKHQpIHsKKyAgICAgICAgKytuZGlnaXRzOworICAgICAgICB0ID4+PSBQeUxvbmdfU0hJRlQ7CisgICAgfQorICAgIHYgPSBfUHlMb25nX05ldyhuZGlnaXRzKTsKKyAgICBpZiAodiAhPSBOVUxMKSB7CisgICAgICAgIGRpZ2l0ICpwID0gdi0+b2JfZGlnaXQ7CisgICAgICAgIFB5X1NJWkUodikgPSBuZGlnaXRzOworICAgICAgICB3aGlsZSAoaXZhbCkgeworICAgICAgICAgICAgKnArKyA9IChkaWdpdCkoaXZhbCAmIFB5TG9uZ19NQVNLKTsKKyAgICAgICAgICAgIGl2YWwgPj49IFB5TG9uZ19TSElGVDsKKyAgICAgICAgfQorICAgIH0KKyAgICByZXR1cm4gKFB5T2JqZWN0ICopdjsKK30KKworLyogQ3JlYXRlIGEgbmV3IGxvbmcgaW50IG9iamVjdCBmcm9tIGEgQyBQeV9zc2l6ZV90LiAqLworCitQeU9iamVjdCAqCitQeUxvbmdfRnJvbVNzaXplX3QoUHlfc3NpemVfdCBpdmFsKQoreworICAgIFB5X3NzaXplX3QgYnl0ZXMgPSBpdmFsOworICAgIGludCBvbmUgPSAxOworICAgIHJldHVybiBfUHlMb25nX0Zyb21CeXRlQXJyYXkoKHVuc2lnbmVkIGNoYXIgKikmYnl0ZXMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTSVpFT0ZfU0laRV9ULCBJU19MSVRUTEVfRU5ESUFOLCAxKTsKK30KKworLyogQ3JlYXRlIGEgbmV3IGxvbmcgaW50IG9iamVjdCBmcm9tIGEgQyBzaXplX3QuICovCisKK1B5T2JqZWN0ICoKK1B5TG9uZ19Gcm9tU2l6ZV90KHNpemVfdCBpdmFsKQoreworICAgIHNpemVfdCBieXRlcyA9IGl2YWw7CisgICAgaW50IG9uZSA9IDE7CisgICAgcmV0dXJuIF9QeUxvbmdfRnJvbUJ5dGVBcnJheSgodW5zaWduZWQgY2hhciAqKSZieXRlcywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNJWkVPRl9TSVpFX1QsIElTX0xJVFRMRV9FTkRJQU4sIDApOworfQorCisvKiBHZXQgYSBDIFBZX0xPTkdfTE9ORyBpbnQgZnJvbSBhIGxvbmcgaW50IG9iamVjdC4KKyAgIFJldHVybiAtMSBhbmQgc2V0IGFuIGVycm9yIGlmIG92ZXJmbG93IG9jY3Vycy4gKi8KKworUFlfTE9OR19MT05HCitQeUxvbmdfQXNMb25nTG9uZyhQeU9iamVjdCAqdnYpCit7CisgICAgUFlfTE9OR19MT05HIGJ5dGVzOworICAgIGludCBvbmUgPSAxOworICAgIGludCByZXM7CisKKyAgICBpZiAodnYgPT0gTlVMTCkgeworICAgICAgICBQeUVycl9CYWRJbnRlcm5hbENhbGwoKTsKKyAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKyAgICBpZiAoIVB5TG9uZ19DaGVjayh2dikpIHsKKyAgICAgICAgUHlOdW1iZXJNZXRob2RzICpuYjsKKyAgICAgICAgUHlPYmplY3QgKmlvOworICAgICAgICBpZiAoUHlJbnRfQ2hlY2sodnYpKQorICAgICAgICAgICAgcmV0dXJuIChQWV9MT05HX0xPTkcpUHlJbnRfQXNMb25nKHZ2KTsKKyAgICAgICAgaWYgKChuYiA9IHZ2LT5vYl90eXBlLT50cF9hc19udW1iZXIpID09IE5VTEwgfHwKKyAgICAgICAgICAgIG5iLT5uYl9pbnQgPT0gTlVMTCkgeworICAgICAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1R5cGVFcnJvciwgImFuIGludGVnZXIgaXMgcmVxdWlyZWQiKTsKKyAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgfQorICAgICAgICBpbyA9ICgqbmItPm5iX2ludCkgKHZ2KTsKKyAgICAgICAgaWYgKGlvID09IE5VTEwpCisgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgIGlmIChQeUludF9DaGVjayhpbykpIHsKKyAgICAgICAgICAgIGJ5dGVzID0gUHlJbnRfQXNMb25nKGlvKTsKKyAgICAgICAgICAgIFB5X0RFQ1JFRihpbyk7CisgICAgICAgICAgICByZXR1cm4gYnl0ZXM7CisgICAgICAgIH0KKyAgICAgICAgaWYgKFB5TG9uZ19DaGVjayhpbykpIHsKKyAgICAgICAgICAgIGJ5dGVzID0gUHlMb25nX0FzTG9uZ0xvbmcoaW8pOworICAgICAgICAgICAgUHlfREVDUkVGKGlvKTsKKyAgICAgICAgICAgIHJldHVybiBieXRlczsKKyAgICAgICAgfQorICAgICAgICBQeV9ERUNSRUYoaW8pOworICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfVHlwZUVycm9yLCAiaW50ZWdlciBjb252ZXJzaW9uIGZhaWxlZCIpOworICAgICAgICByZXR1cm4gLTE7CisgICAgfQorCisgICAgcmVzID0gX1B5TG9uZ19Bc0J5dGVBcnJheSgoUHlMb25nT2JqZWN0ICopdnYsICh1bnNpZ25lZCBjaGFyICopJmJ5dGVzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU0laRU9GX0xPTkdfTE9ORywgSVNfTElUVExFX0VORElBTiwgMSk7CisKKyAgICAvKiBQbGFuIDkgY2FuJ3QgaGFuZGxlIFBZX0xPTkdfTE9ORyBpbiA/IDogZXhwcmVzc2lvbnMgKi8KKyAgICBpZiAocmVzIDwgMCkKKyAgICAgICAgcmV0dXJuIChQWV9MT05HX0xPTkcpLTE7CisgICAgZWxzZQorICAgICAgICByZXR1cm4gYnl0ZXM7Cit9CisKKy8qIEdldCBhIEMgdW5zaWduZWQgUFlfTE9OR19MT05HIGludCBmcm9tIGEgbG9uZyBpbnQgb2JqZWN0LgorICAgUmV0dXJuIC0xIGFuZCBzZXQgYW4gZXJyb3IgaWYgb3ZlcmZsb3cgb2NjdXJzLiAqLworCit1bnNpZ25lZCBQWV9MT05HX0xPTkcKK1B5TG9uZ19Bc1Vuc2lnbmVkTG9uZ0xvbmcoUHlPYmplY3QgKnZ2KQoreworICAgIHVuc2lnbmVkIFBZX0xPTkdfTE9ORyBieXRlczsKKyAgICBpbnQgb25lID0gMTsKKyAgICBpbnQgcmVzOworCisgICAgaWYgKHZ2ID09IE5VTEwgfHwgIVB5TG9uZ19DaGVjayh2dikpIHsKKyAgICAgICAgUHlFcnJfQmFkSW50ZXJuYWxDYWxsKCk7CisgICAgICAgIHJldHVybiAodW5zaWduZWQgUFlfTE9OR19MT05HKS0xOworICAgIH0KKworICAgIHJlcyA9IF9QeUxvbmdfQXNCeXRlQXJyYXkoKFB5TG9uZ09iamVjdCAqKXZ2LCAodW5zaWduZWQgY2hhciAqKSZieXRlcywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNJWkVPRl9MT05HX0xPTkcsIElTX0xJVFRMRV9FTkRJQU4sIDApOworCisgICAgLyogUGxhbiA5IGNhbid0IGhhbmRsZSBQWV9MT05HX0xPTkcgaW4gPyA6IGV4cHJlc3Npb25zICovCisgICAgaWYgKHJlcyA8IDApCisgICAgICAgIHJldHVybiAodW5zaWduZWQgUFlfTE9OR19MT05HKXJlczsKKyAgICBlbHNlCisgICAgICAgIHJldHVybiBieXRlczsKK30KKworLyogR2V0IGEgQyB1bnNpZ25lZCBsb25nIGludCBmcm9tIGEgbG9uZyBpbnQgb2JqZWN0LCBpZ25vcmluZyB0aGUgaGlnaCBiaXRzLgorICAgUmV0dXJucyAtMSBhbmQgc2V0cyBhbiBlcnJvciBjb25kaXRpb24gaWYgYW4gZXJyb3Igb2NjdXJzLiAqLworCit1bnNpZ25lZCBQWV9MT05HX0xPTkcKK1B5TG9uZ19Bc1Vuc2lnbmVkTG9uZ0xvbmdNYXNrKFB5T2JqZWN0ICp2dikKK3sKKyAgICByZWdpc3RlciBQeUxvbmdPYmplY3QgKnY7CisgICAgdW5zaWduZWQgUFlfTE9OR19MT05HIHg7CisgICAgUHlfc3NpemVfdCBpOworICAgIGludCBzaWduOworCisgICAgaWYgKHZ2ID09IE5VTEwgfHwgIVB5TG9uZ19DaGVjayh2dikpIHsKKyAgICAgICAgUHlFcnJfQmFkSW50ZXJuYWxDYWxsKCk7CisgICAgICAgIHJldHVybiAodW5zaWduZWQgbG9uZykgLTE7CisgICAgfQorICAgIHYgPSAoUHlMb25nT2JqZWN0ICopdnY7CisgICAgaSA9IHYtPm9iX3NpemU7CisgICAgc2lnbiA9IDE7CisgICAgeCA9IDA7CisgICAgaWYgKGkgPCAwKSB7CisgICAgICAgIHNpZ24gPSAtMTsKKyAgICAgICAgaSA9IC1pOworICAgIH0KKyAgICB3aGlsZSAoLS1pID49IDApIHsKKyAgICAgICAgeCA9ICh4IDw8IFB5TG9uZ19TSElGVCkgfCB2LT5vYl9kaWdpdFtpXTsKKyAgICB9CisgICAgcmV0dXJuIHggKiBzaWduOworfQorCisvKiBHZXQgYSBDIGxvbmcgbG9uZyBpbnQgZnJvbSBhIFB5dGhvbiBsb25nIG9yIFB5dGhvbiBpbnQgb2JqZWN0LgorICAgT24gb3ZlcmZsb3csIHJldHVybnMgLTEgYW5kIHNldHMgKm92ZXJmbG93IHRvIDEgb3IgLTEgZGVwZW5kaW5nCisgICBvbiB0aGUgc2lnbiBvZiB0aGUgcmVzdWx0LiAgT3RoZXJ3aXNlICpvdmVyZmxvdyBpcyAwLgorCisgICBGb3Igb3RoZXIgZXJyb3JzIChlLmcuLCB0eXBlIGVycm9yKSwgcmV0dXJucyAtMSBhbmQgc2V0cyBhbiBlcnJvcgorICAgY29uZGl0aW9uLgorKi8KKworUFlfTE9OR19MT05HCitQeUxvbmdfQXNMb25nTG9uZ0FuZE92ZXJmbG93KFB5T2JqZWN0ICp2diwgaW50ICpvdmVyZmxvdykKK3sKKyAgICAvKiBUaGlzIHZlcnNpb24gYnkgVGltIFBldGVycyAqLworICAgIHJlZ2lzdGVyIFB5TG9uZ09iamVjdCAqdjsKKyAgICB1bnNpZ25lZCBQWV9MT05HX0xPTkcgeCwgcHJldjsKKyAgICBQWV9MT05HX0xPTkcgcmVzOworICAgIFB5X3NzaXplX3QgaTsKKyAgICBpbnQgc2lnbjsKKyAgICBpbnQgZG9fZGVjcmVmID0gMDsgLyogaWYgbmJfaW50IHdhcyBjYWxsZWQgKi8KKworICAgICpvdmVyZmxvdyA9IDA7CisgICAgaWYgKHZ2ID09IE5VTEwpIHsKKyAgICAgICAgUHlFcnJfQmFkSW50ZXJuYWxDYWxsKCk7CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisKKyAgICBpZiAoUHlJbnRfQ2hlY2sodnYpKQorICAgICAgICByZXR1cm4gUHlJbnRfQXNMb25nKHZ2KTsKKworICAgIGlmICghUHlMb25nX0NoZWNrKHZ2KSkgeworICAgICAgICBQeU51bWJlck1ldGhvZHMgKm5iOworICAgICAgICBuYiA9IHZ2LT5vYl90eXBlLT50cF9hc19udW1iZXI7CisgICAgICAgIGlmIChuYiA9PSBOVUxMIHx8IG5iLT5uYl9pbnQgPT0gTlVMTCkgeworICAgICAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1R5cGVFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAiYW4gaW50ZWdlciBpcyByZXF1aXJlZCIpOworICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICB9CisgICAgICAgIHZ2ID0gKCpuYi0+bmJfaW50KSAodnYpOworICAgICAgICBpZiAodnYgPT0gTlVMTCkKKyAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgZG9fZGVjcmVmID0gMTsKKyAgICAgICAgaWYoUHlJbnRfQ2hlY2sodnYpKSB7CisgICAgICAgICAgICByZXMgPSBQeUludF9Bc0xvbmcodnYpOworICAgICAgICAgICAgZ290byBleGl0OworICAgICAgICB9CisgICAgICAgIGlmICghUHlMb25nX0NoZWNrKHZ2KSkgeworICAgICAgICAgICAgUHlfREVDUkVGKHZ2KTsKKyAgICAgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19UeXBlRXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIm5iX2ludCBzaG91bGQgcmV0dXJuIGludCBvYmplY3QiKTsKKyAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHJlcyA9IC0xOworICAgIHYgPSAoUHlMb25nT2JqZWN0ICopdnY7CisgICAgaSA9IFB5X1NJWkUodik7CisKKyAgICBzd2l0Y2ggKGkpIHsKKyAgICBjYXNlIC0xOgorICAgICAgICByZXMgPSAtKHNkaWdpdCl2LT5vYl9kaWdpdFswXTsKKyAgICAgICAgYnJlYWs7CisgICAgY2FzZSAwOgorICAgICAgICByZXMgPSAwOworICAgICAgICBicmVhazsKKyAgICBjYXNlIDE6CisgICAgICAgIHJlcyA9IHYtPm9iX2RpZ2l0WzBdOworICAgICAgICBicmVhazsKKyAgICBkZWZhdWx0OgorICAgICAgICBzaWduID0gMTsKKyAgICAgICAgeCA9IDA7CisgICAgICAgIGlmIChpIDwgMCkgeworICAgICAgICAgICAgc2lnbiA9IC0xOworICAgICAgICAgICAgaSA9IC0oaSk7CisgICAgICAgIH0KKyAgICAgICAgd2hpbGUgKC0taSA+PSAwKSB7CisgICAgICAgICAgICBwcmV2ID0geDsKKyAgICAgICAgICAgIHggPSAoeCA8PCBQeUxvbmdfU0hJRlQpICsgdi0+b2JfZGlnaXRbaV07CisgICAgICAgICAgICBpZiAoKHggPj4gUHlMb25nX1NISUZUKSAhPSBwcmV2KSB7CisgICAgICAgICAgICAgICAgKm92ZXJmbG93ID0gc2lnbjsKKyAgICAgICAgICAgICAgICBnb3RvIGV4aXQ7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgLyogSGF2ZW4ndCBsb3N0IGFueSBiaXRzLCBidXQgY2FzdGluZyB0byBsb25nIHJlcXVpcmVzIGV4dHJhCisgICAgICAgICAqIGNhcmUgKHNlZSBjb21tZW50IGFib3ZlKS4KKyAgICAgICAgICovCisgICAgICAgIGlmICh4IDw9ICh1bnNpZ25lZCBQWV9MT05HX0xPTkcpUFlfTExPTkdfTUFYKSB7CisgICAgICAgICAgICByZXMgPSAoUFlfTE9OR19MT05HKXggKiBzaWduOworICAgICAgICB9CisgICAgICAgIGVsc2UgaWYgKHNpZ24gPCAwICYmIHggPT0gUFlfQUJTX0xMT05HX01JTikgeworICAgICAgICAgICAgcmVzID0gUFlfTExPTkdfTUlOOworICAgICAgICB9CisgICAgICAgIGVsc2UgeworICAgICAgICAgICAgKm92ZXJmbG93ID0gc2lnbjsKKyAgICAgICAgICAgIC8qIHJlcyBpcyBhbHJlYWR5IHNldCB0byAtMSAqLworICAgICAgICB9CisgICAgfQorICBleGl0OgorICAgIGlmIChkb19kZWNyZWYpIHsKKyAgICAgICAgUHlfREVDUkVGKHZ2KTsKKyAgICB9CisgICAgcmV0dXJuIHJlczsKK30KKworI3VuZGVmIElTX0xJVFRMRV9FTkRJQU4KKworI2VuZGlmIC8qIEhBVkVfTE9OR19MT05HICovCisKKworc3RhdGljIGludAorY29udmVydF9iaW5vcChQeU9iamVjdCAqdiwgUHlPYmplY3QgKncsIFB5TG9uZ09iamVjdCAqKmEsIFB5TG9uZ09iamVjdCAqKmIpIHsKKyAgICBpZiAoUHlMb25nX0NoZWNrKHYpKSB7CisgICAgICAgICphID0gKFB5TG9uZ09iamVjdCAqKSB2OworICAgICAgICBQeV9JTkNSRUYodik7CisgICAgfQorICAgIGVsc2UgaWYgKFB5SW50X0NoZWNrKHYpKSB7CisgICAgICAgICphID0gKFB5TG9uZ09iamVjdCAqKSBQeUxvbmdfRnJvbUxvbmcoUHlJbnRfQVNfTE9ORyh2KSk7CisgICAgfQorICAgIGVsc2UgeworICAgICAgICByZXR1cm4gMDsKKyAgICB9CisgICAgaWYgKFB5TG9uZ19DaGVjayh3KSkgeworICAgICAgICAqYiA9IChQeUxvbmdPYmplY3QgKikgdzsKKyAgICAgICAgUHlfSU5DUkVGKHcpOworICAgIH0KKyAgICBlbHNlIGlmIChQeUludF9DaGVjayh3KSkgeworICAgICAgICAqYiA9IChQeUxvbmdPYmplY3QgKikgUHlMb25nX0Zyb21Mb25nKFB5SW50X0FTX0xPTkcodykpOworICAgIH0KKyAgICBlbHNlIHsKKyAgICAgICAgUHlfREVDUkVGKCphKTsKKyAgICAgICAgcmV0dXJuIDA7CisgICAgfQorICAgIHJldHVybiAxOworfQorCisjZGVmaW5lIENPTlZFUlRfQklOT1AodiwgdywgYSwgYikgICAgICAgICAgICAgICBcCisgICAgZG8geyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgIGlmICghY29udmVydF9iaW5vcCh2LCB3LCBhLCBiKSkgeyAgICAgICBcCisgICAgICAgICAgICBQeV9JTkNSRUYoUHlfTm90SW1wbGVtZW50ZWQpOyAgICAgICBcCisgICAgICAgICAgICByZXR1cm4gUHlfTm90SW1wbGVtZW50ZWQ7ICAgICAgICAgICBcCisgICAgICAgIH0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgfSB3aGlsZSgwKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisKKy8qIGJpdHNfaW5fZGlnaXQoZCkgcmV0dXJucyB0aGUgdW5pcXVlIGludGVnZXIgayBzdWNoIHRoYXQgMioqKGstMSkgPD0gZCA8CisgICAyKiprIGlmIGQgaXMgbm9uemVybywgZWxzZSAwLiAqLworCitzdGF0aWMgY29uc3QgdW5zaWduZWQgY2hhciBCaXRMZW5ndGhUYWJsZVszMl0gPSB7CisgICAgMCwgMSwgMiwgMiwgMywgMywgMywgMywgNCwgNCwgNCwgNCwgNCwgNCwgNCwgNCwKKyAgICA1LCA1LCA1LCA1LCA1LCA1LCA1LCA1LCA1LCA1LCA1LCA1LCA1LCA1LCA1LCA1Cit9OworCitzdGF0aWMgaW50CitiaXRzX2luX2RpZ2l0KGRpZ2l0IGQpCit7CisgICAgaW50IGRfYml0cyA9IDA7CisgICAgd2hpbGUgKGQgPj0gMzIpIHsKKyAgICAgICAgZF9iaXRzICs9IDY7CisgICAgICAgIGQgPj49IDY7CisgICAgfQorICAgIGRfYml0cyArPSAoaW50KUJpdExlbmd0aFRhYmxlW2RdOworICAgIHJldHVybiBkX2JpdHM7Cit9CisKKy8qIHhbMDptXSBhbmQgeVswOm5dIGFyZSBkaWdpdCB2ZWN0b3JzLCBMU0QgZmlyc3QsIG0gPj0gbiByZXF1aXJlZC4gIHhbMDpuXQorICogaXMgbW9kaWZpZWQgaW4gcGxhY2UsIGJ5IGFkZGluZyB5IHRvIGl0LiAgQ2FycmllcyBhcmUgcHJvcGFnYXRlZCBhcyBmYXIgYXMKKyAqIHhbbS0xXSwgYW5kIHRoZSByZW1haW5pbmcgY2FycnkgKDAgb3IgMSkgaXMgcmV0dXJuZWQuCisgKi8KK3N0YXRpYyBkaWdpdAordl9pYWRkKGRpZ2l0ICp4LCBQeV9zc2l6ZV90IG0sIGRpZ2l0ICp5LCBQeV9zc2l6ZV90IG4pCit7CisgICAgUHlfc3NpemVfdCBpOworICAgIGRpZ2l0IGNhcnJ5ID0gMDsKKworICAgIGFzc2VydChtID49IG4pOworICAgIGZvciAoaSA9IDA7IGkgPCBuOyArK2kpIHsKKyAgICAgICAgY2FycnkgKz0geFtpXSArIHlbaV07CisgICAgICAgIHhbaV0gPSBjYXJyeSAmIFB5TG9uZ19NQVNLOworICAgICAgICBjYXJyeSA+Pj0gUHlMb25nX1NISUZUOworICAgICAgICBhc3NlcnQoKGNhcnJ5ICYgMSkgPT0gY2FycnkpOworICAgIH0KKyAgICBmb3IgKDsgY2FycnkgJiYgaSA8IG07ICsraSkgeworICAgICAgICBjYXJyeSArPSB4W2ldOworICAgICAgICB4W2ldID0gY2FycnkgJiBQeUxvbmdfTUFTSzsKKyAgICAgICAgY2FycnkgPj49IFB5TG9uZ19TSElGVDsKKyAgICAgICAgYXNzZXJ0KChjYXJyeSAmIDEpID09IGNhcnJ5KTsKKyAgICB9CisgICAgcmV0dXJuIGNhcnJ5OworfQorCisvKiB4WzA6bV0gYW5kIHlbMDpuXSBhcmUgZGlnaXQgdmVjdG9ycywgTFNEIGZpcnN0LCBtID49IG4gcmVxdWlyZWQuICB4WzA6bl0KKyAqIGlzIG1vZGlmaWVkIGluIHBsYWNlLCBieSBzdWJ0cmFjdGluZyB5IGZyb20gaXQuICBCb3Jyb3dzIGFyZSBwcm9wYWdhdGVkIGFzCisgKiBmYXIgYXMgeFttLTFdLCBhbmQgdGhlIHJlbWFpbmluZyBib3Jyb3cgKDAgb3IgMSkgaXMgcmV0dXJuZWQuCisgKi8KK3N0YXRpYyBkaWdpdAordl9pc3ViKGRpZ2l0ICp4LCBQeV9zc2l6ZV90IG0sIGRpZ2l0ICp5LCBQeV9zc2l6ZV90IG4pCit7CisgICAgUHlfc3NpemVfdCBpOworICAgIGRpZ2l0IGJvcnJvdyA9IDA7CisKKyAgICBhc3NlcnQobSA+PSBuKTsKKyAgICBmb3IgKGkgPSAwOyBpIDwgbjsgKytpKSB7CisgICAgICAgIGJvcnJvdyA9IHhbaV0gLSB5W2ldIC0gYm9ycm93OworICAgICAgICB4W2ldID0gYm9ycm93ICYgUHlMb25nX01BU0s7CisgICAgICAgIGJvcnJvdyA+Pj0gUHlMb25nX1NISUZUOworICAgICAgICBib3Jyb3cgJj0gMTsgICAgICAgICAgICAvKiBrZWVwIG9ubHkgMSBzaWduIGJpdCAqLworICAgIH0KKyAgICBmb3IgKDsgYm9ycm93ICYmIGkgPCBtOyArK2kpIHsKKyAgICAgICAgYm9ycm93ID0geFtpXSAtIGJvcnJvdzsKKyAgICAgICAgeFtpXSA9IGJvcnJvdyAmIFB5TG9uZ19NQVNLOworICAgICAgICBib3Jyb3cgPj49IFB5TG9uZ19TSElGVDsKKyAgICAgICAgYm9ycm93ICY9IDE7CisgICAgfQorICAgIHJldHVybiBib3Jyb3c7Cit9CisKKy8qIFNoaWZ0IGRpZ2l0IHZlY3RvciBhWzA6bV0gZCBiaXRzIGxlZnQsIHdpdGggMCA8PSBkIDwgUHlMb25nX1NISUZULiAgUHV0CisgKiByZXN1bHQgaW4gelswOm1dLCBhbmQgcmV0dXJuIHRoZSBkIGJpdHMgc2hpZnRlZCBvdXQgb2YgdGhlIHRvcC4KKyAqLworc3RhdGljIGRpZ2l0Cit2X2xzaGlmdChkaWdpdCAqeiwgZGlnaXQgKmEsIFB5X3NzaXplX3QgbSwgaW50IGQpCit7CisgICAgUHlfc3NpemVfdCBpOworICAgIGRpZ2l0IGNhcnJ5ID0gMDsKKworICAgIGFzc2VydCgwIDw9IGQgJiYgZCA8IFB5TG9uZ19TSElGVCk7CisgICAgZm9yIChpPTA7IGkgPCBtOyBpKyspIHsKKyAgICAgICAgdHdvZGlnaXRzIGFjYyA9ICh0d29kaWdpdHMpYVtpXSA8PCBkIHwgY2Fycnk7CisgICAgICAgIHpbaV0gPSAoZGlnaXQpYWNjICYgUHlMb25nX01BU0s7CisgICAgICAgIGNhcnJ5ID0gKGRpZ2l0KShhY2MgPj4gUHlMb25nX1NISUZUKTsKKyAgICB9CisgICAgcmV0dXJuIGNhcnJ5OworfQorCisvKiBTaGlmdCBkaWdpdCB2ZWN0b3IgYVswOm1dIGQgYml0cyByaWdodCwgd2l0aCAwIDw9IGQgPCBQeUxvbmdfU0hJRlQuICBQdXQKKyAqIHJlc3VsdCBpbiB6WzA6bV0sIGFuZCByZXR1cm4gdGhlIGQgYml0cyBzaGlmdGVkIG91dCBvZiB0aGUgYm90dG9tLgorICovCitzdGF0aWMgZGlnaXQKK3ZfcnNoaWZ0KGRpZ2l0ICp6LCBkaWdpdCAqYSwgUHlfc3NpemVfdCBtLCBpbnQgZCkKK3sKKyAgICBQeV9zc2l6ZV90IGk7CisgICAgZGlnaXQgY2FycnkgPSAwOworICAgIGRpZ2l0IG1hc2sgPSAoKGRpZ2l0KTEgPDwgZCkgLSAxVTsKKworICAgIGFzc2VydCgwIDw9IGQgJiYgZCA8IFB5TG9uZ19TSElGVCk7CisgICAgZm9yIChpPW07IGktLSA+IDA7KSB7CisgICAgICAgIHR3b2RpZ2l0cyBhY2MgPSAodHdvZGlnaXRzKWNhcnJ5IDw8IFB5TG9uZ19TSElGVCB8IGFbaV07CisgICAgICAgIGNhcnJ5ID0gKGRpZ2l0KWFjYyAmIG1hc2s7CisgICAgICAgIHpbaV0gPSAoZGlnaXQpKGFjYyA+PiBkKTsKKyAgICB9CisgICAgcmV0dXJuIGNhcnJ5OworfQorCisvKiBEaXZpZGUgbG9uZyBwaW4sIHcvIHNpemUgZGlnaXRzLCBieSBub24temVybyBkaWdpdCBuLCBzdG9yaW5nIHF1b3RpZW50CisgICBpbiBwb3V0LCBhbmQgcmV0dXJuaW5nIHRoZSByZW1haW5kZXIuICBwaW4gYW5kIHBvdXQgcG9pbnQgYXQgdGhlIExTRC4KKyAgIEl0J3MgT0sgZm9yIHBpbiA9PSBwb3V0IG9uIGVudHJ5LCB3aGljaCBzYXZlcyBvb2RsZXMgb2YgbWFsbG9jcy9mcmVlcyBpbgorICAgX1B5TG9uZ19Gb3JtYXQsIGJ1dCB0aGF0IHNob3VsZCBiZSBkb25lIHdpdGggZ3JlYXQgY2FyZSBzaW5jZSBsb25ncyBhcmUKKyAgIGltbXV0YWJsZS4gKi8KKworc3RhdGljIGRpZ2l0CitpbnBsYWNlX2RpdnJlbTEoZGlnaXQgKnBvdXQsIGRpZ2l0ICpwaW4sIFB5X3NzaXplX3Qgc2l6ZSwgZGlnaXQgbikKK3sKKyAgICB0d29kaWdpdHMgcmVtID0gMDsKKworICAgIGFzc2VydChuID4gMCAmJiBuIDw9IFB5TG9uZ19NQVNLKTsKKyAgICBwaW4gKz0gc2l6ZTsKKyAgICBwb3V0ICs9IHNpemU7CisgICAgd2hpbGUgKC0tc2l6ZSA+PSAwKSB7CisgICAgICAgIGRpZ2l0IGhpOworICAgICAgICByZW0gPSAocmVtIDw8IFB5TG9uZ19TSElGVCkgfCAqLS1waW47CisgICAgICAgICotLXBvdXQgPSBoaSA9IChkaWdpdCkocmVtIC8gbik7CisgICAgICAgIHJlbSAtPSAodHdvZGlnaXRzKWhpICogbjsKKyAgICB9CisgICAgcmV0dXJuIChkaWdpdClyZW07Cit9CisKKy8qIERpdmlkZSBhIGxvbmcgaW50ZWdlciBieSBhIGRpZ2l0LCByZXR1cm5pbmcgYm90aCB0aGUgcXVvdGllbnQKKyAgIChhcyBmdW5jdGlvbiByZXN1bHQpIGFuZCB0aGUgcmVtYWluZGVyICh0aHJvdWdoICpwcmVtKS4KKyAgIFRoZSBzaWduIG9mIGEgaXMgaWdub3JlZDsgbiBzaG91bGQgbm90IGJlIHplcm8uICovCisKK3N0YXRpYyBQeUxvbmdPYmplY3QgKgorZGl2cmVtMShQeUxvbmdPYmplY3QgKmEsIGRpZ2l0IG4sIGRpZ2l0ICpwcmVtKQoreworICAgIGNvbnN0IFB5X3NzaXplX3Qgc2l6ZSA9IEFCUyhQeV9TSVpFKGEpKTsKKyAgICBQeUxvbmdPYmplY3QgKno7CisKKyAgICBhc3NlcnQobiA+IDAgJiYgbiA8PSBQeUxvbmdfTUFTSyk7CisgICAgeiA9IF9QeUxvbmdfTmV3KHNpemUpOworICAgIGlmICh6ID09IE5VTEwpCisgICAgICAgIHJldHVybiBOVUxMOworICAgICpwcmVtID0gaW5wbGFjZV9kaXZyZW0xKHotPm9iX2RpZ2l0LCBhLT5vYl9kaWdpdCwgc2l6ZSwgbik7CisgICAgcmV0dXJuIGxvbmdfbm9ybWFsaXplKHopOworfQorCisvKiBDb252ZXJ0IGEgbG9uZyBpbnRlZ2VyIHRvIGEgYmFzZSAxMCBzdHJpbmcuICBSZXR1cm5zIGEgbmV3IG5vbi1zaGFyZWQKKyAgIHN0cmluZy4gIChSZXR1cm4gdmFsdWUgaXMgbm9uLXNoYXJlZCBzbyB0aGF0IGNhbGxlcnMgY2FuIG1vZGlmeSB0aGUKKyAgIHJldHVybmVkIHZhbHVlIGlmIG5lY2Vzc2FyeS4pICovCisKK3N0YXRpYyBQeU9iamVjdCAqCitsb25nX3RvX2RlY2ltYWxfc3RyaW5nKFB5T2JqZWN0ICphYSwgaW50IGFkZEwpCit7CisgICAgUHlMb25nT2JqZWN0ICpzY3JhdGNoLCAqYTsKKyAgICBQeU9iamVjdCAqc3RyOworICAgIFB5X3NzaXplX3Qgc2l6ZSwgc3RybGVuLCBzaXplX2EsIGksIGo7CisgICAgZGlnaXQgKnBvdXQsICpwaW4sIHJlbSwgdGVucG93OworICAgIGNoYXIgKnA7CisgICAgaW50IG5lZ2F0aXZlOworCisgICAgYSA9IChQeUxvbmdPYmplY3QgKilhYTsKKyAgICBpZiAoYSA9PSBOVUxMIHx8ICFQeUxvbmdfQ2hlY2soYSkpIHsKKyAgICAgICAgUHlFcnJfQmFkSW50ZXJuYWxDYWxsKCk7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICBzaXplX2EgPSBBQlMoUHlfU0laRShhKSk7CisgICAgbmVnYXRpdmUgPSBQeV9TSVpFKGEpIDwgMDsKKworICAgIC8qIHF1aWNrIGFuZCBkaXJ0eSB1cHBlciBib3VuZCBmb3IgdGhlIG51bWJlciBvZiBkaWdpdHMKKyAgICAgICByZXF1aXJlZCB0byBleHByZXNzIGEgaW4gYmFzZSBfUHlMb25nX0RFQ0lNQUxfQkFTRToKKworICAgICAgICAgI2RpZ2l0cyA9IDEgKyBmbG9vcihsb2cyKGEpIC8gbG9nMihfUHlMb25nX0RFQ0lNQUxfQkFTRSkpCisKKyAgICAgICBCdXQgbG9nMihhKSA8IHNpemVfYSAqIFB5TG9uZ19TSElGVCwgYW5kCisgICAgICAgbG9nMihfUHlMb25nX0RFQ0lNQUxfQkFTRSkgPSBsb2cyKDEwKSAqIF9QeUxvbmdfREVDSU1BTF9TSElGVAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID4gMyAqIF9QeUxvbmdfREVDSU1BTF9TSElGVAorICAgICovCisgICAgaWYgKHNpemVfYSA+IFBZX1NTSVpFX1RfTUFYIC8gUHlMb25nX1NISUZUKSB7CisgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19PdmVyZmxvd0Vycm9yLAorICAgICAgICAgICAgICAgICAgICAgICAgImxvbmcgaXMgdG9vIGxhcmdlIHRvIGZvcm1hdCIpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgLyogdGhlIGV4cHJlc3Npb24gc2l6ZV9hICogUHlMb25nX1NISUZUIGlzIG5vdyBzYWZlIGZyb20gb3ZlcmZsb3cgKi8KKyAgICBzaXplID0gMSArIHNpemVfYSAqIFB5TG9uZ19TSElGVCAvICgzICogX1B5TG9uZ19ERUNJTUFMX1NISUZUKTsKKyAgICBzY3JhdGNoID0gX1B5TG9uZ19OZXcoc2l6ZSk7CisgICAgaWYgKHNjcmF0Y2ggPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisKKyAgICAvKiBjb252ZXJ0IGFycmF5IG9mIGJhc2UgX1B5TG9uZ19CQVNFIGRpZ2l0cyBpbiBwaW4gdG8gYW4gYXJyYXkgb2YKKyAgICAgICBiYXNlIF9QeUxvbmdfREVDSU1BTF9CQVNFIGRpZ2l0cyBpbiBwb3V0LCBmb2xsb3dpbmcgS251dGggKFRBT0NQLAorICAgICAgIFZvbHVtZSAyICgzcmQgZWRuKSwgc2VjdGlvbiA0LjQsIE1ldGhvZCAxYikuICovCisgICAgcGluID0gYS0+b2JfZGlnaXQ7CisgICAgcG91dCA9IHNjcmF0Y2gtPm9iX2RpZ2l0OworICAgIHNpemUgPSAwOworICAgIGZvciAoaSA9IHNpemVfYTsgLS1pID49IDA7ICkgeworICAgICAgICBkaWdpdCBoaSA9IHBpbltpXTsKKyAgICAgICAgZm9yIChqID0gMDsgaiA8IHNpemU7IGorKykgeworICAgICAgICAgICAgdHdvZGlnaXRzIHogPSAodHdvZGlnaXRzKXBvdXRbal0gPDwgUHlMb25nX1NISUZUIHwgaGk7CisgICAgICAgICAgICBoaSA9IChkaWdpdCkoeiAvIF9QeUxvbmdfREVDSU1BTF9CQVNFKTsKKyAgICAgICAgICAgIHBvdXRbal0gPSAoZGlnaXQpKHogLSAodHdvZGlnaXRzKWhpICoKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9QeUxvbmdfREVDSU1BTF9CQVNFKTsKKyAgICAgICAgfQorICAgICAgICB3aGlsZSAoaGkpIHsKKyAgICAgICAgICAgIHBvdXRbc2l6ZSsrXSA9IGhpICUgX1B5TG9uZ19ERUNJTUFMX0JBU0U7CisgICAgICAgICAgICBoaSAvPSBfUHlMb25nX0RFQ0lNQUxfQkFTRTsKKyAgICAgICAgfQorICAgICAgICAvKiBjaGVjayBmb3Iga2V5Ym9hcmQgaW50ZXJydXB0ICovCisgICAgICAgIFNJR0NIRUNLKHsKKyAgICAgICAgICAgICAgICBQeV9ERUNSRUYoc2NyYXRjaCk7CisgICAgICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgICAgICAgICB9KTsKKyAgICB9CisgICAgLyogcG91dCBzaG91bGQgaGF2ZSBhdCBsZWFzdCBvbmUgZGlnaXQsIHNvIHRoYXQgdGhlIGNhc2Ugd2hlbiBhID0gMAorICAgICAgIHdvcmtzIGNvcnJlY3RseSAqLworICAgIGlmIChzaXplID09IDApCisgICAgICAgIHBvdXRbc2l6ZSsrXSA9IDA7CisKKyAgICAvKiBjYWxjdWxhdGUgZXhhY3QgbGVuZ3RoIG9mIG91dHB1dCBzdHJpbmcsIGFuZCBhbGxvY2F0ZSAqLworICAgIHN0cmxlbiA9IChhZGRMICE9IDApICsgbmVnYXRpdmUgKworICAgICAgICAxICsgKHNpemUgLSAxKSAqIF9QeUxvbmdfREVDSU1BTF9TSElGVDsKKyAgICB0ZW5wb3cgPSAxMDsKKyAgICByZW0gPSBwb3V0W3NpemUtMV07CisgICAgd2hpbGUgKHJlbSA+PSB0ZW5wb3cpIHsKKyAgICAgICAgdGVucG93ICo9IDEwOworICAgICAgICBzdHJsZW4rKzsKKyAgICB9CisgICAgc3RyID0gUHlTdHJpbmdfRnJvbVN0cmluZ0FuZFNpemUoTlVMTCwgc3RybGVuKTsKKyAgICBpZiAoc3RyID09IE5VTEwpIHsKKyAgICAgICAgUHlfREVDUkVGKHNjcmF0Y2gpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisKKyAgICAvKiBmaWxsIHRoZSBzdHJpbmcgcmlnaHQtdG8tbGVmdCAqLworICAgIHAgPSBQeVN0cmluZ19BU19TVFJJTkcoc3RyKSArIHN0cmxlbjsKKyAgICAqcCA9ICdcMCc7CisgICAgaWYgKGFkZEwpCisgICAgICAgICotLXAgPSAnTCc7CisgICAgLyogcG91dFswXSB0aHJvdWdoIHBvdXRbc2l6ZS0yXSBjb250cmlidXRlIGV4YWN0bHkKKyAgICAgICBfUHlMb25nX0RFQ0lNQUxfU0hJRlQgZGlnaXRzIGVhY2ggKi8KKyAgICBmb3IgKGk9MDsgaSA8IHNpemUgLSAxOyBpKyspIHsKKyAgICAgICAgcmVtID0gcG91dFtpXTsKKyAgICAgICAgZm9yIChqID0gMDsgaiA8IF9QeUxvbmdfREVDSU1BTF9TSElGVDsgaisrKSB7CisgICAgICAgICAgICAqLS1wID0gJzAnICsgcmVtICUgMTA7CisgICAgICAgICAgICByZW0gLz0gMTA7CisgICAgICAgIH0KKyAgICB9CisgICAgLyogcG91dFtzaXplLTFdOiBhbHdheXMgcHJvZHVjZSBhdCBsZWFzdCBvbmUgZGVjaW1hbCBkaWdpdCAqLworICAgIHJlbSA9IHBvdXRbaV07CisgICAgZG8geworICAgICAgICAqLS1wID0gJzAnICsgcmVtICUgMTA7CisgICAgICAgIHJlbSAvPSAxMDsKKyAgICB9IHdoaWxlIChyZW0gIT0gMCk7CisKKyAgICAvKiBhbmQgc2lnbiAqLworICAgIGlmIChuZWdhdGl2ZSkKKyAgICAgICAgKi0tcCA9ICctJzsKKworICAgIC8qIGNoZWNrIHdlJ3ZlIGNvdW50ZWQgY29ycmVjdGx5ICovCisgICAgYXNzZXJ0KHAgPT0gUHlTdHJpbmdfQVNfU1RSSU5HKHN0cikpOworICAgIFB5X0RFQ1JFRihzY3JhdGNoKTsKKyAgICByZXR1cm4gKFB5T2JqZWN0ICopc3RyOworfQorCisvKiBDb252ZXJ0IHRoZSBsb25nIHRvIGEgc3RyaW5nIG9iamVjdCB3aXRoIGdpdmVuIGJhc2UsCisgICBhcHBlbmRpbmcgYSBiYXNlIHByZWZpeCBvZiAwW2JveF0gaWYgYmFzZSBpcyAyLCA4IG9yIDE2LgorICAgQWRkIGEgdHJhaWxpbmcgIkwiIGlmIGFkZEwgaXMgbm9uLXplcm8uCisgICBJZiBuZXdzdHlsZSBpcyB6ZXJvLCB0aGVuIHVzZSB0aGUgcHJlLTIuNiBiZWhhdmlvciBvZiBvY3RhbCBoYXZpbmcKKyAgIGEgbGVhZGluZyAiMCIsIGluc3RlYWQgb2YgdGhlIHByZWZpeCAiMG8iICovCitQeUFQSV9GVU5DKFB5T2JqZWN0ICopCitfUHlMb25nX0Zvcm1hdChQeU9iamVjdCAqYWEsIGludCBiYXNlLCBpbnQgYWRkTCwgaW50IG5ld3N0eWxlKQoreworICAgIHJlZ2lzdGVyIFB5TG9uZ09iamVjdCAqYSA9IChQeUxvbmdPYmplY3QgKilhYTsKKyAgICBQeVN0cmluZ09iamVjdCAqc3RyOworICAgIFB5X3NzaXplX3QgaSwgc3o7CisgICAgUHlfc3NpemVfdCBzaXplX2E7CisgICAgY2hhciAqcDsKKyAgICBpbnQgYml0czsKKyAgICBjaGFyIHNpZ24gPSAnXDAnOworCisgICAgaWYgKGJhc2UgPT0gMTApCisgICAgICAgIHJldHVybiBsb25nX3RvX2RlY2ltYWxfc3RyaW5nKChQeU9iamVjdCAqKWEsIGFkZEwpOworCisgICAgaWYgKGEgPT0gTlVMTCB8fCAhUHlMb25nX0NoZWNrKGEpKSB7CisgICAgICAgIFB5RXJyX0JhZEludGVybmFsQ2FsbCgpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgYXNzZXJ0KGJhc2UgPj0gMiAmJiBiYXNlIDw9IDM2KTsKKyAgICBzaXplX2EgPSBBQlMoUHlfU0laRShhKSk7CisKKyAgICAvKiBDb21wdXRlIGEgcm91Z2ggdXBwZXIgYm91bmQgZm9yIHRoZSBsZW5ndGggb2YgdGhlIHN0cmluZyAqLworICAgIGkgPSBiYXNlOworICAgIGJpdHMgPSAwOworICAgIHdoaWxlIChpID4gMSkgeworICAgICAgICArK2JpdHM7CisgICAgICAgIGkgPj49IDE7CisgICAgfQorICAgIGkgPSA1ICsgKGFkZEwgPyAxIDogMCk7CisgICAgLyogZW5zdXJlIHdlIGRvbid0IGdldCBzaWduZWQgb3ZlcmZsb3cgaW4gc3ogY2FsY3VsYXRpb24gKi8KKyAgICBpZiAoc2l6ZV9hID4gKFBZX1NTSVpFX1RfTUFYIC0gaSkgLyBQeUxvbmdfU0hJRlQpIHsKKyAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX092ZXJmbG93RXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAgICAibG9uZyBpcyB0b28gbGFyZ2UgdG8gZm9ybWF0Iik7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICBzeiA9IGkgKyAxICsgKHNpemVfYSAqIFB5TG9uZ19TSElGVCAtIDEpIC8gYml0czsKKyAgICBhc3NlcnQoc3ogPj0gMCk7CisgICAgc3RyID0gKFB5U3RyaW5nT2JqZWN0ICopIFB5U3RyaW5nX0Zyb21TdHJpbmdBbmRTaXplKChjaGFyICopMCwgc3opOworICAgIGlmIChzdHIgPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgcCA9IFB5U3RyaW5nX0FTX1NUUklORyhzdHIpICsgc3o7CisgICAgKnAgPSAnXDAnOworICAgIGlmIChhZGRMKQorICAgICAgICAqLS1wID0gJ0wnOworICAgIGlmIChhLT5vYl9zaXplIDwgMCkKKyAgICAgICAgc2lnbiA9ICctJzsKKworICAgIGlmIChhLT5vYl9zaXplID09IDApIHsKKyAgICAgICAgKi0tcCA9ICcwJzsKKyAgICB9CisgICAgZWxzZSBpZiAoKGJhc2UgJiAoYmFzZSAtIDEpKSA9PSAwKSB7CisgICAgICAgIC8qIEpSSDogc3BlY2lhbCBjYXNlIGZvciBwb3dlci1vZi0yIGJhc2VzICovCisgICAgICAgIHR3b2RpZ2l0cyBhY2N1bSA9IDA7CisgICAgICAgIGludCBhY2N1bWJpdHMgPSAwOyAgICAgICAgICAgICAgLyogIyBvZiBiaXRzIGluIGFjY3VtICovCisgICAgICAgIGludCBiYXNlYml0cyA9IDE7ICAgICAgICAgICAgICAgLyogIyBvZiBiaXRzIGluIGJhc2UtMSAqLworICAgICAgICBpID0gYmFzZTsKKyAgICAgICAgd2hpbGUgKChpID4+PSAxKSA+IDEpCisgICAgICAgICAgICArK2Jhc2ViaXRzOworCisgICAgICAgIGZvciAoaSA9IDA7IGkgPCBzaXplX2E7ICsraSkgeworICAgICAgICAgICAgYWNjdW0gfD0gKHR3b2RpZ2l0cylhLT5vYl9kaWdpdFtpXSA8PCBhY2N1bWJpdHM7CisgICAgICAgICAgICBhY2N1bWJpdHMgKz0gUHlMb25nX1NISUZUOworICAgICAgICAgICAgYXNzZXJ0KGFjY3VtYml0cyA+PSBiYXNlYml0cyk7CisgICAgICAgICAgICBkbyB7CisgICAgICAgICAgICAgICAgY2hhciBjZGlnaXQgPSAoY2hhcikoYWNjdW0gJiAoYmFzZSAtIDEpKTsKKyAgICAgICAgICAgICAgICBjZGlnaXQgKz0gKGNkaWdpdCA8IDEwKSA/ICcwJyA6ICdhJy0xMDsKKyAgICAgICAgICAgICAgICBhc3NlcnQocCA+IFB5U3RyaW5nX0FTX1NUUklORyhzdHIpKTsKKyAgICAgICAgICAgICAgICAqLS1wID0gY2RpZ2l0OworICAgICAgICAgICAgICAgIGFjY3VtYml0cyAtPSBiYXNlYml0czsKKyAgICAgICAgICAgICAgICBhY2N1bSA+Pj0gYmFzZWJpdHM7CisgICAgICAgICAgICB9IHdoaWxlIChpIDwgc2l6ZV9hLTEgPyBhY2N1bWJpdHMgPj0gYmFzZWJpdHMgOiBhY2N1bSA+IDApOworICAgICAgICB9CisgICAgfQorICAgIGVsc2UgeworICAgICAgICAvKiBOb3QgMCwgYW5kIGJhc2Ugbm90IGEgcG93ZXIgb2YgMi4gIERpdmlkZSByZXBlYXRlZGx5IGJ5CisgICAgICAgICAgIGJhc2UsIGJ1dCBmb3Igc3BlZWQgdXNlIHRoZSBoaWdoZXN0IHBvd2VyIG9mIGJhc2UgdGhhdAorICAgICAgICAgICBmaXRzIGluIGEgZGlnaXQuICovCisgICAgICAgIFB5X3NzaXplX3Qgc2l6ZSA9IHNpemVfYTsKKyAgICAgICAgZGlnaXQgKnBpbiA9IGEtPm9iX2RpZ2l0OworICAgICAgICBQeUxvbmdPYmplY3QgKnNjcmF0Y2g7CisgICAgICAgIC8qIHBvd2Jhc3cgPC0gbGFyZ2VzdCBwb3dlciBvZiBiYXNlIHRoYXQgZml0cyBpbiBhIGRpZ2l0LiAqLworICAgICAgICBkaWdpdCBwb3diYXNlID0gYmFzZTsgIC8qIHBvd2Jhc2UgPT0gYmFzZSAqKiBwb3dlciAqLworICAgICAgICBpbnQgcG93ZXIgPSAxOworICAgICAgICBmb3IgKDs7KSB7CisgICAgICAgICAgICB0d29kaWdpdHMgbmV3cG93ID0gcG93YmFzZSAqICh0d29kaWdpdHMpYmFzZTsKKyAgICAgICAgICAgIGlmIChuZXdwb3cgPj4gUHlMb25nX1NISUZUKQorICAgICAgICAgICAgICAgIC8qIGRvZXNuJ3QgZml0IGluIGEgZGlnaXQgKi8KKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIHBvd2Jhc2UgPSAoZGlnaXQpbmV3cG93OworICAgICAgICAgICAgKytwb3dlcjsKKyAgICAgICAgfQorCisgICAgICAgIC8qIEdldCBhIHNjcmF0Y2ggYXJlYSBmb3IgcmVwZWF0ZWQgZGl2aXNpb24uICovCisgICAgICAgIHNjcmF0Y2ggPSBfUHlMb25nX05ldyhzaXplKTsKKyAgICAgICAgaWYgKHNjcmF0Y2ggPT0gTlVMTCkgeworICAgICAgICAgICAgUHlfREVDUkVGKHN0cik7CisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgfQorCisgICAgICAgIC8qIFJlcGVhdGVkbHkgZGl2aWRlIGJ5IHBvd2Jhc2UuICovCisgICAgICAgIGRvIHsKKyAgICAgICAgICAgIGludCBudG9zdG9yZSA9IHBvd2VyOworICAgICAgICAgICAgZGlnaXQgcmVtID0gaW5wbGFjZV9kaXZyZW0xKHNjcmF0Y2gtPm9iX2RpZ2l0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBpbiwgc2l6ZSwgcG93YmFzZSk7CisgICAgICAgICAgICBwaW4gPSBzY3JhdGNoLT5vYl9kaWdpdDsgLyogbm8gbmVlZCB0byB1c2UgYSBhZ2FpbiAqLworICAgICAgICAgICAgaWYgKHBpbltzaXplIC0gMV0gPT0gMCkKKyAgICAgICAgICAgICAgICAtLXNpemU7CisgICAgICAgICAgICBTSUdDSEVDSyh7CisgICAgICAgICAgICAgICAgICAgIFB5X0RFQ1JFRihzY3JhdGNoKTsKKyAgICAgICAgICAgICAgICAgICAgUHlfREVDUkVGKHN0cik7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgICAgICAgICAgICAgIH0pOworCisgICAgICAgICAgICAvKiBCcmVhayByZW0gaW50byBkaWdpdHMuICovCisgICAgICAgICAgICBhc3NlcnQobnRvc3RvcmUgPiAwKTsKKyAgICAgICAgICAgIGRvIHsKKyAgICAgICAgICAgICAgICBkaWdpdCBuZXh0cmVtID0gKGRpZ2l0KShyZW0gLyBiYXNlKTsKKyAgICAgICAgICAgICAgICBjaGFyIGMgPSAoY2hhcikocmVtIC0gbmV4dHJlbSAqIGJhc2UpOworICAgICAgICAgICAgICAgIGFzc2VydChwID4gUHlTdHJpbmdfQVNfU1RSSU5HKHN0cikpOworICAgICAgICAgICAgICAgIGMgKz0gKGMgPCAxMCkgPyAnMCcgOiAnYSctMTA7CisgICAgICAgICAgICAgICAgKi0tcCA9IGM7CisgICAgICAgICAgICAgICAgcmVtID0gbmV4dHJlbTsKKyAgICAgICAgICAgICAgICAtLW50b3N0b3JlOworICAgICAgICAgICAgICAgIC8qIFRlcm1pbmF0aW9uIGlzIGEgYml0IGRlbGljYXRlOiAgbXVzdCBub3QKKyAgICAgICAgICAgICAgICAgICBzdG9yZSBsZWFkaW5nIHplcm9lcywgc28gbXVzdCBnZXQgb3V0IGlmCisgICAgICAgICAgICAgICAgICAgcmVtYWluaW5nIHF1b3RpZW50IGFuZCByZW0gYXJlIGJvdGggMC4gKi8KKyAgICAgICAgICAgIH0gd2hpbGUgKG50b3N0b3JlICYmIChzaXplIHx8IHJlbSkpOworICAgICAgICB9IHdoaWxlIChzaXplICE9IDApOworICAgICAgICBQeV9ERUNSRUYoc2NyYXRjaCk7CisgICAgfQorCisgICAgaWYgKGJhc2UgPT0gMikgeworICAgICAgICAqLS1wID0gJ2InOworICAgICAgICAqLS1wID0gJzAnOworICAgIH0KKyAgICBlbHNlIGlmIChiYXNlID09IDgpIHsKKyAgICAgICAgaWYgKG5ld3N0eWxlKSB7CisgICAgICAgICAgICAqLS1wID0gJ28nOworICAgICAgICAgICAgKi0tcCA9ICcwJzsKKyAgICAgICAgfQorICAgICAgICBlbHNlCisgICAgICAgICAgICBpZiAoc2l6ZV9hICE9IDApCisgICAgICAgICAgICAgICAgKi0tcCA9ICcwJzsKKyAgICB9CisgICAgZWxzZSBpZiAoYmFzZSA9PSAxNikgeworICAgICAgICAqLS1wID0gJ3gnOworICAgICAgICAqLS1wID0gJzAnOworICAgIH0KKyAgICBlbHNlIGlmIChiYXNlICE9IDEwKSB7CisgICAgICAgICotLXAgPSAnIyc7CisgICAgICAgICotLXAgPSAnMCcgKyBiYXNlJTEwOworICAgICAgICBpZiAoYmFzZSA+IDEwKQorICAgICAgICAgICAgKi0tcCA9ICcwJyArIGJhc2UvMTA7CisgICAgfQorICAgIGlmIChzaWduKQorICAgICAgICAqLS1wID0gc2lnbjsKKyAgICBpZiAocCAhPSBQeVN0cmluZ19BU19TVFJJTkcoc3RyKSkgeworICAgICAgICBjaGFyICpxID0gUHlTdHJpbmdfQVNfU1RSSU5HKHN0cik7CisgICAgICAgIGFzc2VydChwID4gcSk7CisgICAgICAgIGRvIHsKKyAgICAgICAgfSB3aGlsZSAoKCpxKysgPSAqcCsrKSAhPSAnXDAnKTsKKyAgICAgICAgcS0tOworICAgICAgICBfUHlTdHJpbmdfUmVzaXplKChQeU9iamVjdCAqKikmc3RyLAorICAgICAgICAgICAgICAgICAgICAgICAgIChQeV9zc2l6ZV90KSAocSAtIFB5U3RyaW5nX0FTX1NUUklORyhzdHIpKSk7CisgICAgfQorICAgIHJldHVybiAoUHlPYmplY3QgKilzdHI7Cit9CisKKy8qIFRhYmxlIG9mIGRpZ2l0IHZhbHVlcyBmb3IgOC1iaXQgc3RyaW5nIC0+IGludGVnZXIgY29udmVyc2lvbi4KKyAqICcwJyBtYXBzIHRvIDAsIC4uLiwgJzknIG1hcHMgdG8gOS4KKyAqICdhJyBhbmQgJ0EnIG1hcCB0byAxMCwgLi4uLCAneicgYW5kICdaJyBtYXAgdG8gMzUuCisgKiBBbGwgb3RoZXIgaW5kaWNlcyBtYXAgdG8gMzcuCisgKiBOb3RlIHRoYXQgd2hlbiBjb252ZXJ0aW5nIGEgYmFzZSBCIHN0cmluZywgYSBjaGFyIGMgaXMgYSBsZWdpdGltYXRlCisgKiBiYXNlIEIgZGlnaXQgaWZmIF9QeUxvbmdfRGlnaXRWYWx1ZVtQeV9DSEFSTUFTSyhjKV0gPCBCLgorICovCitpbnQgX1B5TG9uZ19EaWdpdFZhbHVlWzI1Nl0gPSB7CisgICAgMzcsIDM3LCAzNywgMzcsIDM3LCAzNywgMzcsIDM3LCAzNywgMzcsIDM3LCAzNywgMzcsIDM3LCAzNywgMzcsCisgICAgMzcsIDM3LCAzNywgMzcsIDM3LCAzNywgMzcsIDM3LCAzNywgMzcsIDM3LCAzNywgMzcsIDM3LCAzNywgMzcsCisgICAgMzcsIDM3LCAzNywgMzcsIDM3LCAzNywgMzcsIDM3LCAzNywgMzcsIDM3LCAzNywgMzcsIDM3LCAzNywgMzcsCisgICAgMCwgIDEsICAyLCAgMywgIDQsICA1LCAgNiwgIDcsICA4LCAgOSwgIDM3LCAzNywgMzcsIDM3LCAzNywgMzcsCisgICAgMzcsIDEwLCAxMSwgMTIsIDEzLCAxNCwgMTUsIDE2LCAxNywgMTgsIDE5LCAyMCwgMjEsIDIyLCAyMywgMjQsCisgICAgMjUsIDI2LCAyNywgMjgsIDI5LCAzMCwgMzEsIDMyLCAzMywgMzQsIDM1LCAzNywgMzcsIDM3LCAzNywgMzcsCisgICAgMzcsIDEwLCAxMSwgMTIsIDEzLCAxNCwgMTUsIDE2LCAxNywgMTgsIDE5LCAyMCwgMjEsIDIyLCAyMywgMjQsCisgICAgMjUsIDI2LCAyNywgMjgsIDI5LCAzMCwgMzEsIDMyLCAzMywgMzQsIDM1LCAzNywgMzcsIDM3LCAzNywgMzcsCisgICAgMzcsIDM3LCAzNywgMzcsIDM3LCAzNywgMzcsIDM3LCAzNywgMzcsIDM3LCAzNywgMzcsIDM3LCAzNywgMzcsCisgICAgMzcsIDM3LCAzNywgMzcsIDM3LCAzNywgMzcsIDM3LCAzNywgMzcsIDM3LCAzNywgMzcsIDM3LCAzNywgMzcsCisgICAgMzcsIDM3LCAzNywgMzcsIDM3LCAzNywgMzcsIDM3LCAzNywgMzcsIDM3LCAzNywgMzcsIDM3LCAzNywgMzcsCisgICAgMzcsIDM3LCAzNywgMzcsIDM3LCAzNywgMzcsIDM3LCAzNywgMzcsIDM3LCAzNywgMzcsIDM3LCAzNywgMzcsCisgICAgMzcsIDM3LCAzNywgMzcsIDM3LCAzNywgMzcsIDM3LCAzNywgMzcsIDM3LCAzNywgMzcsIDM3LCAzNywgMzcsCisgICAgMzcsIDM3LCAzNywgMzcsIDM3LCAzNywgMzcsIDM3LCAzNywgMzcsIDM3LCAzNywgMzcsIDM3LCAzNywgMzcsCisgICAgMzcsIDM3LCAzNywgMzcsIDM3LCAzNywgMzcsIDM3LCAzNywgMzcsIDM3LCAzNywgMzcsIDM3LCAzNywgMzcsCisgICAgMzcsIDM3LCAzNywgMzcsIDM3LCAzNywgMzcsIDM3LCAzNywgMzcsIDM3LCAzNywgMzcsIDM3LCAzNywgMzcsCit9OworCisvKiAqc3RyIHBvaW50cyB0byB0aGUgZmlyc3QgZGlnaXQgaW4gYSBzdHJpbmcgb2YgYmFzZSBgYmFzZWAgZGlnaXRzLiAgYmFzZQorICogaXMgYSBwb3dlciBvZiAyICgyLCA0LCA4LCAxNiwgb3IgMzIpLiAgKnN0ciBpcyBzZXQgdG8gcG9pbnQgdG8gdGhlIGZpcnN0CisgKiBub24tZGlnaXQgKHdoaWNoIG1heSBiZSAqc3RyISkuICBBIG5vcm1hbGl6ZWQgbG9uZyBpcyByZXR1cm5lZC4KKyAqIFRoZSBwb2ludCB0byB0aGlzIHJvdXRpbmUgaXMgdGhhdCBpdCB0YWtlcyB0aW1lIGxpbmVhciBpbiB0aGUgbnVtYmVyIG9mCisgKiBzdHJpbmcgY2hhcmFjdGVycy4KKyAqLworc3RhdGljIFB5TG9uZ09iamVjdCAqCitsb25nX2Zyb21fYmluYXJ5X2Jhc2UoY2hhciAqKnN0ciwgaW50IGJhc2UpCit7CisgICAgY2hhciAqcCA9ICpzdHI7CisgICAgY2hhciAqc3RhcnQgPSBwOworICAgIGludCBiaXRzX3Blcl9jaGFyOworICAgIFB5X3NzaXplX3QgbjsKKyAgICBQeUxvbmdPYmplY3QgKno7CisgICAgdHdvZGlnaXRzIGFjY3VtOworICAgIGludCBiaXRzX2luX2FjY3VtOworICAgIGRpZ2l0ICpwZGlnaXQ7CisKKyAgICBhc3NlcnQoYmFzZSA+PSAyICYmIGJhc2UgPD0gMzIgJiYgKGJhc2UgJiAoYmFzZSAtIDEpKSA9PSAwKTsKKyAgICBuID0gYmFzZTsKKyAgICBmb3IgKGJpdHNfcGVyX2NoYXIgPSAtMTsgbjsgKytiaXRzX3Blcl9jaGFyKQorICAgICAgICBuID4+PSAxOworICAgIC8qIG4gPC0gdG90YWwgIyBvZiBiaXRzIG5lZWRlZCwgd2hpbGUgc2V0dGluZyBwIHRvIGVuZC1vZi1zdHJpbmcgKi8KKyAgICB3aGlsZSAoX1B5TG9uZ19EaWdpdFZhbHVlW1B5X0NIQVJNQVNLKCpwKV0gPCBiYXNlKQorICAgICAgICArK3A7CisgICAgKnN0ciA9IHA7CisgICAgLyogbiA8LSAjIG9mIFB5dGhvbiBkaWdpdHMgbmVlZGVkLCA9IGNlaWxpbmcobi9QeUxvbmdfU0hJRlQpLiAqLworICAgIG4gPSAocCAtIHN0YXJ0KSAqIGJpdHNfcGVyX2NoYXIgKyBQeUxvbmdfU0hJRlQgLSAxOworICAgIGlmIChuIC8gYml0c19wZXJfY2hhciA8IHAgLSBzdGFydCkgeworICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfVmFsdWVFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICJsb25nIHN0cmluZyB0b28gbGFyZ2UgdG8gY29udmVydCIpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgbiA9IG4gLyBQeUxvbmdfU0hJRlQ7CisgICAgeiA9IF9QeUxvbmdfTmV3KG4pOworICAgIGlmICh6ID09IE5VTEwpCisgICAgICAgIHJldHVybiBOVUxMOworICAgIC8qIFJlYWQgc3RyaW5nIGZyb20gcmlnaHQsIGFuZCBmaWxsIGluIGxvbmcgZnJvbSBsZWZ0OyBpLmUuLAorICAgICAqIGZyb20gbGVhc3QgdG8gbW9zdCBzaWduaWZpY2FudCBpbiBib3RoLgorICAgICAqLworICAgIGFjY3VtID0gMDsKKyAgICBiaXRzX2luX2FjY3VtID0gMDsKKyAgICBwZGlnaXQgPSB6LT5vYl9kaWdpdDsKKyAgICB3aGlsZSAoLS1wID49IHN0YXJ0KSB7CisgICAgICAgIGludCBrID0gX1B5TG9uZ19EaWdpdFZhbHVlW1B5X0NIQVJNQVNLKCpwKV07CisgICAgICAgIGFzc2VydChrID49IDAgJiYgayA8IGJhc2UpOworICAgICAgICBhY2N1bSB8PSAodHdvZGlnaXRzKWsgPDwgYml0c19pbl9hY2N1bTsKKyAgICAgICAgYml0c19pbl9hY2N1bSArPSBiaXRzX3Blcl9jaGFyOworICAgICAgICBpZiAoYml0c19pbl9hY2N1bSA+PSBQeUxvbmdfU0hJRlQpIHsKKyAgICAgICAgICAgICpwZGlnaXQrKyA9IChkaWdpdCkoYWNjdW0gJiBQeUxvbmdfTUFTSyk7CisgICAgICAgICAgICBhc3NlcnQocGRpZ2l0IC0gei0+b2JfZGlnaXQgPD0gbik7CisgICAgICAgICAgICBhY2N1bSA+Pj0gUHlMb25nX1NISUZUOworICAgICAgICAgICAgYml0c19pbl9hY2N1bSAtPSBQeUxvbmdfU0hJRlQ7CisgICAgICAgICAgICBhc3NlcnQoYml0c19pbl9hY2N1bSA8IFB5TG9uZ19TSElGVCk7CisgICAgICAgIH0KKyAgICB9CisgICAgaWYgKGJpdHNfaW5fYWNjdW0pIHsKKyAgICAgICAgYXNzZXJ0KGJpdHNfaW5fYWNjdW0gPD0gUHlMb25nX1NISUZUKTsKKyAgICAgICAgKnBkaWdpdCsrID0gKGRpZ2l0KWFjY3VtOworICAgICAgICBhc3NlcnQocGRpZ2l0IC0gei0+b2JfZGlnaXQgPD0gbik7CisgICAgfQorICAgIHdoaWxlIChwZGlnaXQgLSB6LT5vYl9kaWdpdCA8IG4pCisgICAgICAgICpwZGlnaXQrKyA9IDA7CisgICAgcmV0dXJuIGxvbmdfbm9ybWFsaXplKHopOworfQorCitQeU9iamVjdCAqCitQeUxvbmdfRnJvbVN0cmluZyhjaGFyICpzdHIsIGNoYXIgKipwZW5kLCBpbnQgYmFzZSkKK3sKKyAgICBpbnQgc2lnbiA9IDE7CisgICAgY2hhciAqc3RhcnQsICpvcmlnX3N0ciA9IHN0cjsKKyAgICBQeUxvbmdPYmplY3QgKno7CisgICAgUHlPYmplY3QgKnN0cm9iaiwgKnN0cnJlcHI7CisgICAgUHlfc3NpemVfdCBzbGVuOworCisgICAgaWYgKChiYXNlICE9IDAgJiYgYmFzZSA8IDIpIHx8IGJhc2UgPiAzNikgeworICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfVmFsdWVFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICJsb25nKCkgYXJnIDIgbXVzdCBiZSA+PSAyIGFuZCA8PSAzNiIpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgd2hpbGUgKCpzdHIgIT0gJ1wwJyAmJiBpc3NwYWNlKFB5X0NIQVJNQVNLKCpzdHIpKSkKKyAgICAgICAgc3RyKys7CisgICAgaWYgKCpzdHIgPT0gJysnKQorICAgICAgICArK3N0cjsKKyAgICBlbHNlIGlmICgqc3RyID09ICctJykgeworICAgICAgICArK3N0cjsKKyAgICAgICAgc2lnbiA9IC0xOworICAgIH0KKyAgICB3aGlsZSAoKnN0ciAhPSAnXDAnICYmIGlzc3BhY2UoUHlfQ0hBUk1BU0soKnN0cikpKQorICAgICAgICBzdHIrKzsKKyAgICBpZiAoYmFzZSA9PSAwKSB7CisgICAgICAgIC8qIE5vIGJhc2UgZ2l2ZW4uICBEZWR1Y2UgdGhlIGJhc2UgZnJvbSB0aGUgY29udGVudHMKKyAgICAgICAgICAgb2YgdGhlIHN0cmluZyAqLworICAgICAgICBpZiAoc3RyWzBdICE9ICcwJykKKyAgICAgICAgICAgIGJhc2UgPSAxMDsKKyAgICAgICAgZWxzZSBpZiAoc3RyWzFdID09ICd4JyB8fCBzdHJbMV0gPT0gJ1gnKQorICAgICAgICAgICAgYmFzZSA9IDE2OworICAgICAgICBlbHNlIGlmIChzdHJbMV0gPT0gJ28nIHx8IHN0clsxXSA9PSAnTycpCisgICAgICAgICAgICBiYXNlID0gODsKKyAgICAgICAgZWxzZSBpZiAoc3RyWzFdID09ICdiJyB8fCBzdHJbMV0gPT0gJ0InKQorICAgICAgICAgICAgYmFzZSA9IDI7CisgICAgICAgIGVsc2UKKyAgICAgICAgICAgIC8qICJvbGQiIChDLXN0eWxlKSBvY3RhbCBsaXRlcmFsLCBzdGlsbCB2YWxpZCBpbgorICAgICAgICAgICAgICAgMi54LCBhbHRob3VnaCBpbGxlZ2FsIGluIDMueCAqLworICAgICAgICAgICAgYmFzZSA9IDg7CisgICAgfQorICAgIC8qIFdoZXRoZXIgb3Igbm90IHdlIHdlcmUgZGVkdWNpbmcgdGhlIGJhc2UsIHNraXAgbGVhZGluZyBjaGFycworICAgICAgIGFzIG5lZWRlZCAqLworICAgIGlmIChzdHJbMF0gPT0gJzAnICYmCisgICAgICAgICgoYmFzZSA9PSAxNiAmJiAoc3RyWzFdID09ICd4JyB8fCBzdHJbMV0gPT0gJ1gnKSkgfHwKKyAgICAgICAgIChiYXNlID09IDggICYmIChzdHJbMV0gPT0gJ28nIHx8IHN0clsxXSA9PSAnTycpKSB8fAorICAgICAgICAgKGJhc2UgPT0gMiAgJiYgKHN0clsxXSA9PSAnYicgfHwgc3RyWzFdID09ICdCJykpKSkKKyAgICAgICAgc3RyICs9IDI7CisKKyAgICBzdGFydCA9IHN0cjsKKyAgICBpZiAoKGJhc2UgJiAoYmFzZSAtIDEpKSA9PSAwKQorICAgICAgICB6ID0gbG9uZ19mcm9tX2JpbmFyeV9iYXNlKCZzdHIsIGJhc2UpOworICAgIGVsc2UgeworLyoqKgorQmluYXJ5IGJhc2VzIGNhbiBiZSBjb252ZXJ0ZWQgaW4gdGltZSBsaW5lYXIgaW4gdGhlIG51bWJlciBvZiBkaWdpdHMsIGJlY2F1c2UKK1B5dGhvbidzIHJlcHJlc2VudGF0aW9uIGJhc2UgaXMgYmluYXJ5LiAgT3RoZXIgYmFzZXMgKGluY2x1ZGluZyBkZWNpbWFsISkgdXNlCit0aGUgc2ltcGxlIHF1YWRyYXRpYy10aW1lIGFsZ29yaXRobSBiZWxvdywgY29tcGxpY2F0ZWQgYnkgc29tZSBzcGVlZCB0cmlja3MuCisKK0ZpcnN0IHNvbWUgbWF0aDogIHRoZSBsYXJnZXN0IGludGVnZXIgdGhhdCBjYW4gYmUgZXhwcmVzc2VkIGluIE4gYmFzZS1CIGRpZ2l0cworaXMgQioqTi0xLiAgQ29uc2VxdWVudGx5LCBpZiB3ZSBoYXZlIGFuIE4tZGlnaXQgaW5wdXQgaW4gYmFzZSBCLCB0aGUgd29yc3QtCitjYXNlIG51bWJlciBvZiBQeXRob24gZGlnaXRzIG5lZWRlZCB0byBob2xkIGl0IGlzIHRoZSBzbWFsbGVzdCBpbnRlZ2VyIG4gcy50LgorCisgICAgUHlMb25nX0JBU0UqKm4tMSA+PSBCKipOLTEgIFtvciwgYWRkaW5nIDEgdG8gYm90aCBzaWRlc10KKyAgICBQeUxvbmdfQkFTRSoqbiA+PSBCKipOICAgICAgW3Rha2luZyBsb2dzIHRvIGJhc2UgUHlMb25nX0JBU0VdCisgICAgbiA+PSBsb2coQioqTikvbG9nKFB5TG9uZ19CQVNFKSA9IE4gKiBsb2coQikvbG9nKFB5TG9uZ19CQVNFKQorCitUaGUgc3RhdGljIGFycmF5IGxvZ19iYXNlX1B5TG9uZ19CQVNFW2Jhc2VdID09IGxvZyhiYXNlKS9sb2coUHlMb25nX0JBU0UpIHNvCit3ZSBjYW4gY29tcHV0ZSB0aGlzIHF1aWNrbHkuICBBIFB5dGhvbiBsb25nIHdpdGggdGhhdCBtdWNoIHNwYWNlIGlzIHJlc2VydmVkCituZWFyIHRoZSBzdGFydCwgYW5kIHRoZSByZXN1bHQgaXMgY29tcHV0ZWQgaW50byBpdC4KKworVGhlIGlucHV0IHN0cmluZyBpcyBhY3R1YWxseSB0cmVhdGVkIGFzIGJlaW5nIGluIGJhc2UgYmFzZSoqaSAoaS5lLiwgaSBkaWdpdHMKK2FyZSBwcm9jZXNzZWQgYXQgYSB0aW1lKSwgd2hlcmUgdHdvIG1vcmUgc3RhdGljIGFycmF5cyBob2xkOgorCisgICAgY29udndpZHRoX2Jhc2VbYmFzZV0gPSB0aGUgbGFyZ2VzdCBpbnRlZ2VyIGkgc3VjaCB0aGF0CisgICAgICAgICAgICAgICAgICAgICAgICAgICBiYXNlKippIDw9IFB5TG9uZ19CQVNFCisgICAgY29udm11bHRtYXhfYmFzZVtiYXNlXSA9IGJhc2UgKiogY29udndpZHRoX2Jhc2VbYmFzZV0KKworVGhlIGZpcnN0IG9mIHRoZXNlIGlzIHRoZSBsYXJnZXN0IGkgc3VjaCB0aGF0IGkgY29uc2VjdXRpdmUgaW5wdXQgZGlnaXRzCittdXN0IGZpdCBpbiBhIHNpbmdsZSBQeXRob24gZGlnaXQuICBUaGUgc2Vjb25kIGlzIGVmZmVjdGl2ZWx5IHRoZSBpbnB1dAorYmFzZSB3ZSdyZSByZWFsbHkgdXNpbmcuCisKK1ZpZXdpbmcgdGhlIGlucHV0IGFzIGEgc2VxdWVuY2UgPGMwLCBjMSwgLi4uLCBjX24tMT4gb2YgZGlnaXRzIGluIGJhc2UKK2NvbnZtdWx0bWF4X2Jhc2VbYmFzZV0sIHRoZSByZXN1bHQgaXMgInNpbXBseSIKKworICAgKCgoYzAqQiArIGMxKSpCICsgYzIpKkIgKyBjMykqQiArIC4uLiApKSkgKyBjX24tMQorCit3aGVyZSBCID0gY29udm11bHRtYXhfYmFzZVtiYXNlXS4KKworRXJyb3IgYW5hbHlzaXM6ICBhcyBhYm92ZSwgdGhlIG51bWJlciBvZiBQeXRob24gZGlnaXRzIGBuYCBuZWVkZWQgaXMgd29yc3QtCitjYXNlCisKKyAgICBuID49IE4gKiBsb2coQikvbG9nKFB5TG9uZ19CQVNFKQorCit3aGVyZSBgTmAgaXMgdGhlIG51bWJlciBvZiBpbnB1dCBkaWdpdHMgaW4gYmFzZSBgQmAuICBUaGlzIGlzIGNvbXB1dGVkIHZpYQorCisgICAgc2l6ZV96ID0gKFB5X3NzaXplX3QpKChzY2FuIC0gc3RyKSAqIGxvZ19iYXNlX1B5TG9uZ19CQVNFW2Jhc2VdKSArIDE7CisKK2JlbG93LiAgVHdvIG51bWVyaWMgY29uY2VybnMgYXJlIGhvdyBtdWNoIHNwYWNlIHRoaXMgY2FuIHdhc3RlLCBhbmQgd2hldGhlcgordGhlIGNvbXB1dGVkIHJlc3VsdCBjYW4gYmUgdG9vIHNtYWxsLiAgVG8gYmUgY29uY3JldGUsIGFzc3VtZSBQeUxvbmdfQkFTRSA9CisyKioxNSwgd2hpY2ggaXMgdGhlIGRlZmF1bHQgKGFuZCBpdCdzIHVubGlrZWx5IGFueW9uZSBjaGFuZ2VzIHRoYXQpLgorCitXYXN0ZSBpc24ndCBhIHByb2JsZW06IHByb3ZpZGVkIHRoZSBmaXJzdCBpbnB1dCBkaWdpdCBpc24ndCAwLCB0aGUgZGlmZmVyZW5jZQorYmV0d2VlbiB0aGUgd29yc3QtY2FzZSBpbnB1dCB3aXRoIE4gZGlnaXRzIGFuZCB0aGUgc21hbGxlc3QgaW5wdXQgd2l0aCBOCitkaWdpdHMgaXMgYWJvdXQgYSBmYWN0b3Igb2YgQiwgYnV0IEIgaXMgc21hbGwgY29tcGFyZWQgdG8gUHlMb25nX0JBU0Ugc28gYXQKK21vc3Qgb25lIGFsbG9jYXRlZCBQeXRob24gZGlnaXQgY2FuIHJlbWFpbiB1bnVzZWQgb24gdGhhdCBjb3VudC4gIElmCitOKmxvZyhCKS9sb2coUHlMb25nX0JBU0UpIGlzIG1hdGhlbWF0aWNhbGx5IGFuIGV4YWN0IGludGVnZXIsIHRoZW4gdHJ1bmNhdGluZwordGhhdCBhbmQgYWRkaW5nIDEgcmV0dXJucyBhIHJlc3VsdCAxIGxhcmdlciB0aGFuIG5lY2Vzc2FyeS4gIEhvd2V2ZXIsIHRoYXQKK2Nhbid0IGhhcHBlbjogd2hlbmV2ZXIgQiBpcyBhIHBvd2VyIG9mIDIsIGxvbmdfZnJvbV9iaW5hcnlfYmFzZSgpIGlzIGNhbGxlZAoraW5zdGVhZCwgYW5kIGl0J3MgaW1wb3NzaWJsZSBmb3IgQioqaSB0byBiZSBhbiBpbnRlZ2VyIHBvd2VyIG9mIDIqKjE1IHdoZW4gQgoraXMgbm90IGEgcG93ZXIgb2YgMiAoaS5lLiwgaXQncyBpbXBvc3NpYmxlIGZvciBOKmxvZyhCKS9sb2coUHlMb25nX0JBU0UpIHRvIGJlCithbiBleGFjdCBpbnRlZ2VyIHdoZW4gQiBpcyBub3QgYSBwb3dlciBvZiAyLCBzaW5jZSBCKippIGhhcyBhIHByaW1lIGZhY3Rvcgorb3RoZXIgdGhhbiAyIGluIHRoYXQgY2FzZSwgYnV0ICgyKioxNSkqKmoncyBvbmx5IHByaW1lIGZhY3RvciBpcyAyKS4KKworVGhlIGNvbXB1dGVkIHJlc3VsdCBjYW4gYmUgdG9vIHNtYWxsIGlmIHRoZSB0cnVlIHZhbHVlIG9mCitOKmxvZyhCKS9sb2coUHlMb25nX0JBU0UpIGlzIGEgbGl0dGxlIGJpdCBsYXJnZXIgdGhhbiBhbiBleGFjdCBpbnRlZ2VyLCBidXQKK2R1ZSB0byByb3VuZG9mZiBlcnJvcnMgKGluIGNvbXB1dGluZyBsb2coQiksIGxvZyhQeUxvbmdfQkFTRSksIHRoZWlyIHF1b3RpZW50LAorYW5kL29yIG11bHRpcGx5aW5nIHRoYXQgYnkgTikgeWllbGRzIGEgbnVtZXJpYyByZXN1bHQgYSBsaXR0bGUgbGVzcyB0aGFuIHRoYXQKK2ludGVnZXIuICBVbmZvcnR1bmF0ZWx5LCAiaG93IGNsb3NlIGNhbiBhIHRyYW5zY2VuZGVudGFsIGZ1bmN0aW9uIGdldCB0byBhbgoraW50ZWdlciBvdmVyIHNvbWUgcmFuZ2U/IiAgcXVlc3Rpb25zIGFyZSBnZW5lcmFsbHkgdGhlb3JldGljYWxseSBpbnRyYWN0YWJsZS4KK0NvbXB1dGVyIGFuYWx5c2lzIHZpYSBjb250aW51ZWQgZnJhY3Rpb25zIGlzIHByYWN0aWNhbDogZXhwYW5kCitsb2coQikvbG9nKFB5TG9uZ19CQVNFKSB2aWEgY29udGludWVkIGZyYWN0aW9ucywgZ2l2aW5nIGEgc2VxdWVuY2UgaS9qIG9mICJ0aGUKK2Jlc3QiIHJhdGlvbmFsIGFwcHJveGltYXRpb25zLiAgVGhlbiBqKmxvZyhCKS9sb2coUHlMb25nX0JBU0UpIGlzCithcHByb3hpbWF0ZWx5IGVxdWFsIHRvICh0aGUgaW50ZWdlcikgaS4gIFRoaXMgc2hvd3MgdGhhdCB3ZSBjYW4gZ2V0IHZlcnkgY2xvc2UKK3RvIGJlaW5nIGluIHRyb3VibGUsIGJ1dCB2ZXJ5IHJhcmVseS4gIEZvciBleGFtcGxlLCA3NjU3MyBpcyBhIGRlbm9taW5hdG9yIGluCitvbmUgb2YgdGhlIGNvbnRpbnVlZC1mcmFjdGlvbiBhcHByb3hpbWF0aW9ucyB0byBsb2coMTApL2xvZygyKioxNSksIGFuZAoraW5kZWVkOgorCisgICAgPj4+IGxvZygxMCkvbG9nKDIqKjE1KSo3NjU3MworICAgIDE2OTU4LjAwMDAwMDY1NDAwMworCitpcyB2ZXJ5IGNsb3NlIHRvIGFuIGludGVnZXIuICBJZiB3ZSB3ZXJlIHdvcmtpbmcgd2l0aCBJRUVFIHNpbmdsZS1wcmVjaXNpb24sCityb3VuZGluZyBlcnJvcnMgY291bGQga2lsbCB1cy4gIEZpbmRpbmcgd29yc3QgY2FzZXMgaW4gSUVFRSBkb3VibGUtcHJlY2lzaW9uCityZXF1aXJlcyBiZXR0ZXItdGhhbi1kb3VibGUtcHJlY2lzaW9uIGxvZygpIGZ1bmN0aW9ucywgYW5kIFRpbSBkaWRuJ3QgYm90aGVyLgorSW5zdGVhZCB0aGUgY29kZSBjaGVja3MgdG8gc2VlIHdoZXRoZXIgdGhlIGFsbG9jYXRlZCBzcGFjZSBpcyBlbm91Z2ggYXMgZWFjaAorbmV3IFB5dGhvbiBkaWdpdCBpcyBhZGRlZCwgYW5kIGNvcGllcyB0aGUgd2hvbGUgdGhpbmcgdG8gYSBsYXJnZXIgbG9uZyBpZiBub3QuCitUaGlzIHNob3VsZCBoYXBwZW4gZXh0cmVtZWx5IHJhcmVseSwgYW5kIGluIGZhY3QgSSBkb24ndCBoYXZlIGEgdGVzdCBjYXNlCit0aGF0IHRyaWdnZXJzIGl0KCEpLiAgSW5zdGVhZCB0aGUgY29kZSB3YXMgdGVzdGVkIGJ5IGFydGlmaWNpYWxseSBhbGxvY2F0aW5nCitqdXN0IDEgZGlnaXQgYXQgdGhlIHN0YXJ0LCBzbyB0aGF0IHRoZSBjb3B5aW5nIGNvZGUgd2FzIGV4ZXJjaXNlZCBmb3IgZXZlcnkKK2RpZ2l0IGJleW9uZCB0aGUgZmlyc3QuCisqKiovCisgICAgICAgIHJlZ2lzdGVyIHR3b2RpZ2l0cyBjOyAgICAgICAgICAgLyogY3VycmVudCBpbnB1dCBjaGFyYWN0ZXIgKi8KKyAgICAgICAgUHlfc3NpemVfdCBzaXplX3o7CisgICAgICAgIGludCBpOworICAgICAgICBpbnQgY29udndpZHRoOworICAgICAgICB0d29kaWdpdHMgY29udm11bHRtYXgsIGNvbnZtdWx0OworICAgICAgICBkaWdpdCAqcHosICpwenN0b3A7CisgICAgICAgIGNoYXIqIHNjYW47CisKKyAgICAgICAgc3RhdGljIGRvdWJsZSBsb2dfYmFzZV9QeUxvbmdfQkFTRVszN10gPSB7MC4wZTAsfTsKKyAgICAgICAgc3RhdGljIGludCBjb252d2lkdGhfYmFzZVszN10gPSB7MCx9OworICAgICAgICBzdGF0aWMgdHdvZGlnaXRzIGNvbnZtdWx0bWF4X2Jhc2VbMzddID0gezAsfTsKKworICAgICAgICBpZiAobG9nX2Jhc2VfUHlMb25nX0JBU0VbYmFzZV0gPT0gMC4wKSB7CisgICAgICAgICAgICB0d29kaWdpdHMgY29udm1heCA9IGJhc2U7CisgICAgICAgICAgICBpbnQgaSA9IDE7CisKKyAgICAgICAgICAgIGxvZ19iYXNlX1B5TG9uZ19CQVNFW2Jhc2VdID0gKGxvZygoZG91YmxlKWJhc2UpIC8KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvZygoZG91YmxlKVB5TG9uZ19CQVNFKSk7CisgICAgICAgICAgICBmb3IgKDs7KSB7CisgICAgICAgICAgICAgICAgdHdvZGlnaXRzIG5leHQgPSBjb252bWF4ICogYmFzZTsKKyAgICAgICAgICAgICAgICBpZiAobmV4dCA+IFB5TG9uZ19CQVNFKQorICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICBjb252bWF4ID0gbmV4dDsKKyAgICAgICAgICAgICAgICArK2k7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBjb252bXVsdG1heF9iYXNlW2Jhc2VdID0gY29udm1heDsKKyAgICAgICAgICAgIGFzc2VydChpID4gMCk7CisgICAgICAgICAgICBjb252d2lkdGhfYmFzZVtiYXNlXSA9IGk7CisgICAgICAgIH0KKworICAgICAgICAvKiBGaW5kIGxlbmd0aCBvZiB0aGUgc3RyaW5nIG9mIG51bWVyaWMgY2hhcmFjdGVycy4gKi8KKyAgICAgICAgc2NhbiA9IHN0cjsKKyAgICAgICAgd2hpbGUgKF9QeUxvbmdfRGlnaXRWYWx1ZVtQeV9DSEFSTUFTSygqc2NhbildIDwgYmFzZSkKKyAgICAgICAgICAgICsrc2NhbjsKKworICAgICAgICAvKiBDcmVhdGUgYSBsb25nIG9iamVjdCB0aGF0IGNhbiBjb250YWluIHRoZSBsYXJnZXN0IHBvc3NpYmxlCisgICAgICAgICAqIGludGVnZXIgd2l0aCB0aGlzIGJhc2UgYW5kIGxlbmd0aC4gIE5vdGUgdGhhdCB0aGVyZSdzIG5vCisgICAgICAgICAqIG5lZWQgdG8gaW5pdGlhbGl6ZSB6LT5vYl9kaWdpdCAtLSBubyBzbG90IGlzIHJlYWQgdXAgYmVmb3JlCisgICAgICAgICAqIGJlaW5nIHN0b3JlZCBpbnRvLgorICAgICAgICAgKi8KKyAgICAgICAgc2l6ZV96ID0gKFB5X3NzaXplX3QpKChzY2FuIC0gc3RyKSAqIGxvZ19iYXNlX1B5TG9uZ19CQVNFW2Jhc2VdKSArIDE7CisgICAgICAgIC8qIFVuY29tbWVudCBuZXh0IGxpbmUgdG8gdGVzdCBleGNlZWRpbmdseSByYXJlIGNvcHkgY29kZSAqLworICAgICAgICAvKiBzaXplX3ogPSAxOyAqLworICAgICAgICBhc3NlcnQoc2l6ZV96ID4gMCk7CisgICAgICAgIHogPSBfUHlMb25nX05ldyhzaXplX3opOworICAgICAgICBpZiAoeiA9PSBOVUxMKQorICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgICAgIFB5X1NJWkUoeikgPSAwOworCisgICAgICAgIC8qIGBjb252d2lkdGhgIGNvbnNlY3V0aXZlIGlucHV0IGRpZ2l0cyBhcmUgdHJlYXRlZCBhcyBhIHNpbmdsZQorICAgICAgICAgKiBkaWdpdCBpbiBiYXNlIGBjb252bXVsdG1heGAuCisgICAgICAgICAqLworICAgICAgICBjb252d2lkdGggPSBjb252d2lkdGhfYmFzZVtiYXNlXTsKKyAgICAgICAgY29udm11bHRtYXggPSBjb252bXVsdG1heF9iYXNlW2Jhc2VdOworCisgICAgICAgIC8qIFdvcmsgOy0pICovCisgICAgICAgIHdoaWxlIChzdHIgPCBzY2FuKSB7CisgICAgICAgICAgICAvKiBncmFiIHVwIHRvIGNvbnZ3aWR0aCBkaWdpdHMgZnJvbSB0aGUgaW5wdXQgc3RyaW5nICovCisgICAgICAgICAgICBjID0gKGRpZ2l0KV9QeUxvbmdfRGlnaXRWYWx1ZVtQeV9DSEFSTUFTSygqc3RyKyspXTsKKyAgICAgICAgICAgIGZvciAoaSA9IDE7IGkgPCBjb252d2lkdGggJiYgc3RyICE9IHNjYW47ICsraSwgKytzdHIpIHsKKyAgICAgICAgICAgICAgICBjID0gKHR3b2RpZ2l0cykoYyAqICBiYXNlICsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX1B5TG9uZ19EaWdpdFZhbHVlW1B5X0NIQVJNQVNLKCpzdHIpXSk7CisgICAgICAgICAgICAgICAgYXNzZXJ0KGMgPCBQeUxvbmdfQkFTRSk7CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGNvbnZtdWx0ID0gY29udm11bHRtYXg7CisgICAgICAgICAgICAvKiBDYWxjdWxhdGUgdGhlIHNoaWZ0IG9ubHkgaWYgd2UgY291bGRuJ3QgZ2V0CisgICAgICAgICAgICAgKiBjb252d2lkdGggZGlnaXRzLgorICAgICAgICAgICAgICovCisgICAgICAgICAgICBpZiAoaSAhPSBjb252d2lkdGgpIHsKKyAgICAgICAgICAgICAgICBjb252bXVsdCA9IGJhc2U7CisgICAgICAgICAgICAgICAgZm9yICggOyBpID4gMTsgLS1pKQorICAgICAgICAgICAgICAgICAgICBjb252bXVsdCAqPSBiYXNlOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICAvKiBNdWx0aXBseSB6IGJ5IGNvbnZtdWx0LCBhbmQgYWRkIGMuICovCisgICAgICAgICAgICBweiA9IHotPm9iX2RpZ2l0OworICAgICAgICAgICAgcHpzdG9wID0gcHogKyBQeV9TSVpFKHopOworICAgICAgICAgICAgZm9yICg7IHB6IDwgcHpzdG9wOyArK3B6KSB7CisgICAgICAgICAgICAgICAgYyArPSAodHdvZGlnaXRzKSpweiAqIGNvbnZtdWx0OworICAgICAgICAgICAgICAgICpweiA9IChkaWdpdCkoYyAmIFB5TG9uZ19NQVNLKTsKKyAgICAgICAgICAgICAgICBjID4+PSBQeUxvbmdfU0hJRlQ7CisgICAgICAgICAgICB9CisgICAgICAgICAgICAvKiBjYXJyeSBvZmYgdGhlIGN1cnJlbnQgZW5kPyAqLworICAgICAgICAgICAgaWYgKGMpIHsKKyAgICAgICAgICAgICAgICBhc3NlcnQoYyA8IFB5TG9uZ19CQVNFKTsKKyAgICAgICAgICAgICAgICBpZiAoUHlfU0laRSh6KSA8IHNpemVfeikgeworICAgICAgICAgICAgICAgICAgICAqcHogPSAoZGlnaXQpYzsKKyAgICAgICAgICAgICAgICAgICAgKytQeV9TSVpFKHopOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgUHlMb25nT2JqZWN0ICp0bXA7CisgICAgICAgICAgICAgICAgICAgIC8qIEV4dHJlbWVseSByYXJlLiAgR2V0IG1vcmUgc3BhY2UuICovCisgICAgICAgICAgICAgICAgICAgIGFzc2VydChQeV9TSVpFKHopID09IHNpemVfeik7CisgICAgICAgICAgICAgICAgICAgIHRtcCA9IF9QeUxvbmdfTmV3KHNpemVfeiArIDEpOworICAgICAgICAgICAgICAgICAgICBpZiAodG1wID09IE5VTEwpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIFB5X0RFQ1JFRih6KTsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIG1lbWNweSh0bXAtPm9iX2RpZ2l0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgei0+b2JfZGlnaXQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplb2YoZGlnaXQpICogc2l6ZV96KTsKKyAgICAgICAgICAgICAgICAgICAgUHlfREVDUkVGKHopOworICAgICAgICAgICAgICAgICAgICB6ID0gdG1wOworICAgICAgICAgICAgICAgICAgICB6LT5vYl9kaWdpdFtzaXplX3pdID0gKGRpZ2l0KWM7CisgICAgICAgICAgICAgICAgICAgICsrc2l6ZV96OworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKyAgICBpZiAoeiA9PSBOVUxMKQorICAgICAgICByZXR1cm4gTlVMTDsKKyAgICBpZiAoc3RyID09IHN0YXJ0KQorICAgICAgICBnb3RvIG9uRXJyb3I7CisgICAgaWYgKHNpZ24gPCAwKQorICAgICAgICBQeV9TSVpFKHopID0gLShQeV9TSVpFKHopKTsKKyAgICBpZiAoKnN0ciA9PSAnTCcgfHwgKnN0ciA9PSAnbCcpCisgICAgICAgIHN0cisrOworICAgIHdoaWxlICgqc3RyICYmIGlzc3BhY2UoUHlfQ0hBUk1BU0soKnN0cikpKQorICAgICAgICBzdHIrKzsKKyAgICBpZiAoKnN0ciAhPSAnXDAnKQorICAgICAgICBnb3RvIG9uRXJyb3I7CisgICAgaWYgKHBlbmQpCisgICAgICAgICpwZW5kID0gc3RyOworICAgIHJldHVybiAoUHlPYmplY3QgKikgejsKKworICBvbkVycm9yOgorICAgIFB5X1hERUNSRUYoeik7CisgICAgc2xlbiA9IHN0cmxlbihvcmlnX3N0cikgPCAyMDAgPyBzdHJsZW4ob3JpZ19zdHIpIDogMjAwOworICAgIHN0cm9iaiA9IFB5U3RyaW5nX0Zyb21TdHJpbmdBbmRTaXplKG9yaWdfc3RyLCBzbGVuKTsKKyAgICBpZiAoc3Ryb2JqID09IE5VTEwpCisgICAgICAgIHJldHVybiBOVUxMOworICAgIHN0cnJlcHIgPSBQeU9iamVjdF9SZXByKHN0cm9iaik7CisgICAgUHlfREVDUkVGKHN0cm9iaik7CisgICAgaWYgKHN0cnJlcHIgPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgUHlFcnJfRm9ybWF0KFB5RXhjX1ZhbHVlRXJyb3IsCisgICAgICAgICAgICAgICAgICJpbnZhbGlkIGxpdGVyYWwgZm9yIGxvbmcoKSB3aXRoIGJhc2UgJWQ6ICVzIiwKKyAgICAgICAgICAgICAgICAgYmFzZSwgUHlTdHJpbmdfQVNfU1RSSU5HKHN0cnJlcHIpKTsKKyAgICBQeV9ERUNSRUYoc3RycmVwcik7CisgICAgcmV0dXJuIE5VTEw7Cit9CisKKyNpZmRlZiBQeV9VU0lOR19VTklDT0RFCitQeU9iamVjdCAqCitQeUxvbmdfRnJvbVVuaWNvZGUoUHlfVU5JQ09ERSAqdSwgUHlfc3NpemVfdCBsZW5ndGgsIGludCBiYXNlKQoreworICAgIFB5T2JqZWN0ICpyZXN1bHQ7CisgICAgY2hhciAqYnVmZmVyID0gKGNoYXIgKilQeU1lbV9NQUxMT0MobGVuZ3RoKzEpOworCisgICAgaWYgKGJ1ZmZlciA9PSBOVUxMKQorICAgICAgICByZXR1cm4gTlVMTDsKKworICAgIGlmIChQeVVuaWNvZGVfRW5jb2RlRGVjaW1hbCh1LCBsZW5ndGgsIGJ1ZmZlciwgTlVMTCkpIHsKKyAgICAgICAgUHlNZW1fRlJFRShidWZmZXIpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgcmVzdWx0ID0gUHlMb25nX0Zyb21TdHJpbmcoYnVmZmVyLCBOVUxMLCBiYXNlKTsKKyAgICBQeU1lbV9GUkVFKGJ1ZmZlcik7CisgICAgcmV0dXJuIHJlc3VsdDsKK30KKyNlbmRpZgorCisvKiBmb3J3YXJkICovCitzdGF0aWMgUHlMb25nT2JqZWN0ICp4X2RpdnJlbQorICAgIChQeUxvbmdPYmplY3QgKiwgUHlMb25nT2JqZWN0ICosIFB5TG9uZ09iamVjdCAqKik7CitzdGF0aWMgUHlPYmplY3QgKmxvbmdfbG9uZyhQeU9iamVjdCAqdik7CisKKy8qIExvbmcgZGl2aXNpb24gd2l0aCByZW1haW5kZXIsIHRvcC1sZXZlbCByb3V0aW5lICovCisKK3N0YXRpYyBpbnQKK2xvbmdfZGl2cmVtKFB5TG9uZ09iamVjdCAqYSwgUHlMb25nT2JqZWN0ICpiLAorICAgICAgICAgICAgUHlMb25nT2JqZWN0ICoqcGRpdiwgUHlMb25nT2JqZWN0ICoqcHJlbSkKK3sKKyAgICBQeV9zc2l6ZV90IHNpemVfYSA9IEFCUyhQeV9TSVpFKGEpKSwgc2l6ZV9iID0gQUJTKFB5X1NJWkUoYikpOworICAgIFB5TG9uZ09iamVjdCAqejsKKworICAgIGlmIChzaXplX2IgPT0gMCkgeworICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfWmVyb0RpdmlzaW9uRXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAgICAibG9uZyBkaXZpc2lvbiBvciBtb2R1bG8gYnkgemVybyIpOworICAgICAgICByZXR1cm4gLTE7CisgICAgfQorICAgIGlmIChzaXplX2EgPCBzaXplX2IgfHwKKyAgICAgICAgKHNpemVfYSA9PSBzaXplX2IgJiYKKyAgICAgICAgIGEtPm9iX2RpZ2l0W3NpemVfYS0xXSA8IGItPm9iX2RpZ2l0W3NpemVfYi0xXSkpIHsKKyAgICAgICAgLyogfGF8IDwgfGJ8LiAqLworICAgICAgICAqcGRpdiA9IF9QeUxvbmdfTmV3KDApOworICAgICAgICBpZiAoKnBkaXYgPT0gTlVMTCkKKyAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgUHlfSU5DUkVGKGEpOworICAgICAgICAqcHJlbSA9IChQeUxvbmdPYmplY3QgKikgYTsKKyAgICAgICAgcmV0dXJuIDA7CisgICAgfQorICAgIGlmIChzaXplX2IgPT0gMSkgeworICAgICAgICBkaWdpdCByZW0gPSAwOworICAgICAgICB6ID0gZGl2cmVtMShhLCBiLT5vYl9kaWdpdFswXSwgJnJlbSk7CisgICAgICAgIGlmICh6ID09IE5VTEwpCisgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgICpwcmVtID0gKFB5TG9uZ09iamVjdCAqKSBQeUxvbmdfRnJvbUxvbmcoKGxvbmcpcmVtKTsKKyAgICAgICAgaWYgKCpwcmVtID09IE5VTEwpIHsKKyAgICAgICAgICAgIFB5X0RFQ1JFRih6KTsKKyAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgfQorICAgIH0KKyAgICBlbHNlIHsKKyAgICAgICAgeiA9IHhfZGl2cmVtKGEsIGIsIHByZW0pOworICAgICAgICBpZiAoeiA9PSBOVUxMKQorICAgICAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKyAgICAvKiBTZXQgdGhlIHNpZ25zLgorICAgICAgIFRoZSBxdW90aWVudCB6IGhhcyB0aGUgc2lnbiBvZiBhKmI7CisgICAgICAgdGhlIHJlbWFpbmRlciByIGhhcyB0aGUgc2lnbiBvZiBhLAorICAgICAgIHNvIGEgPSBiKnogKyByLiAqLworICAgIGlmICgoYS0+b2Jfc2l6ZSA8IDApICE9IChiLT5vYl9zaXplIDwgMCkpCisgICAgICAgIHotPm9iX3NpemUgPSAtKHotPm9iX3NpemUpOworICAgIGlmIChhLT5vYl9zaXplIDwgMCAmJiAoKnByZW0pLT5vYl9zaXplICE9IDApCisgICAgICAgICgqcHJlbSktPm9iX3NpemUgPSAtKCgqcHJlbSktPm9iX3NpemUpOworICAgICpwZGl2ID0gejsKKyAgICByZXR1cm4gMDsKK30KKworLyogVW5zaWduZWQgbG9uZyBkaXZpc2lvbiB3aXRoIHJlbWFpbmRlciAtLSB0aGUgYWxnb3JpdGhtLiAgVGhlIGFyZ3VtZW50cyB2MQorICAgYW5kIHcxIHNob3VsZCBzYXRpc2Z5IDIgPD0gQUJTKFB5X1NJWkUodzEpKSA8PSBBQlMoUHlfU0laRSh2MSkpLiAqLworCitzdGF0aWMgUHlMb25nT2JqZWN0ICoKK3hfZGl2cmVtKFB5TG9uZ09iamVjdCAqdjEsIFB5TG9uZ09iamVjdCAqdzEsIFB5TG9uZ09iamVjdCAqKnByZW0pCit7CisgICAgUHlMb25nT2JqZWN0ICp2LCAqdywgKmE7CisgICAgUHlfc3NpemVfdCBpLCBrLCBzaXplX3YsIHNpemVfdzsKKyAgICBpbnQgZDsKKyAgICBkaWdpdCB3bTEsIHdtMiwgY2FycnksIHEsIHIsIHZ0b3AsICp2MCwgKnZrLCAqdzAsICphazsKKyAgICB0d29kaWdpdHMgdnY7CisgICAgc2RpZ2l0IHpoaTsKKyAgICBzdHdvZGlnaXRzIHo7CisKKyAgICAvKiBXZSBmb2xsb3cgS251dGggW1RoZSBBcnQgb2YgQ29tcHV0ZXIgUHJvZ3JhbW1pbmcsIFZvbC4gMiAoM3JkCisgICAgICAgZWRuLiksIHNlY3Rpb24gNC4zLjEsIEFsZ29yaXRobSBEXSwgZXhjZXB0IHRoYXQgd2UgZG9uJ3QgZXhwbGljaXRseQorICAgICAgIGhhbmRsZSB0aGUgc3BlY2lhbCBjYXNlIHdoZW4gdGhlIGluaXRpYWwgZXN0aW1hdGUgcSBmb3IgYSBxdW90aWVudAorICAgICAgIGRpZ2l0IGlzID49IFB5TG9uZ19CQVNFOiB0aGUgbWF4IHZhbHVlIGZvciBxIGlzIFB5TG9uZ19CQVNFKzEsIGFuZAorICAgICAgIHRoYXQgd29uJ3Qgb3ZlcmZsb3cgYSBkaWdpdC4gKi8KKworICAgIC8qIGFsbG9jYXRlIHNwYWNlOyB3IHdpbGwgYWxzbyBiZSB1c2VkIHRvIGhvbGQgdGhlIGZpbmFsIHJlbWFpbmRlciAqLworICAgIHNpemVfdiA9IEFCUyhQeV9TSVpFKHYxKSk7CisgICAgc2l6ZV93ID0gQUJTKFB5X1NJWkUodzEpKTsKKyAgICBhc3NlcnQoc2l6ZV92ID49IHNpemVfdyAmJiBzaXplX3cgPj0gMik7IC8qIEFzc2VydCBjaGVja3MgYnkgZGl2KCkgKi8KKyAgICB2ID0gX1B5TG9uZ19OZXcoc2l6ZV92KzEpOworICAgIGlmICh2ID09IE5VTEwpIHsKKyAgICAgICAgKnByZW0gPSBOVUxMOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgdyA9IF9QeUxvbmdfTmV3KHNpemVfdyk7CisgICAgaWYgKHcgPT0gTlVMTCkgeworICAgICAgICBQeV9ERUNSRUYodik7CisgICAgICAgICpwcmVtID0gTlVMTDsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorCisgICAgLyogbm9ybWFsaXplOiBzaGlmdCB3MSBsZWZ0IHNvIHRoYXQgaXRzIHRvcCBkaWdpdCBpcyA+PSBQeUxvbmdfQkFTRS8yLgorICAgICAgIHNoaWZ0IHYxIGxlZnQgYnkgdGhlIHNhbWUgYW1vdW50LiAgUmVzdWx0cyBnbyBpbnRvIHcgYW5kIHYuICovCisgICAgZCA9IFB5TG9uZ19TSElGVCAtIGJpdHNfaW5fZGlnaXQodzEtPm9iX2RpZ2l0W3NpemVfdy0xXSk7CisgICAgY2FycnkgPSB2X2xzaGlmdCh3LT5vYl9kaWdpdCwgdzEtPm9iX2RpZ2l0LCBzaXplX3csIGQpOworICAgIGFzc2VydChjYXJyeSA9PSAwKTsKKyAgICBjYXJyeSA9IHZfbHNoaWZ0KHYtPm9iX2RpZ2l0LCB2MS0+b2JfZGlnaXQsIHNpemVfdiwgZCk7CisgICAgaWYgKGNhcnJ5ICE9IDAgfHwgdi0+b2JfZGlnaXRbc2l6ZV92LTFdID49IHctPm9iX2RpZ2l0W3NpemVfdy0xXSkgeworICAgICAgICB2LT5vYl9kaWdpdFtzaXplX3ZdID0gY2Fycnk7CisgICAgICAgIHNpemVfdisrOworICAgIH0KKworICAgIC8qIE5vdyB2LT5vYl9kaWdpdFtzaXplX3YtMV0gPCB3LT5vYl9kaWdpdFtzaXplX3ctMV0sIHNvIHF1b3RpZW50IGhhcworICAgICAgIGF0IG1vc3QgKGFuZCB1c3VhbGx5IGV4YWN0bHkpIGsgPSBzaXplX3YgLSBzaXplX3cgZGlnaXRzLiAqLworICAgIGsgPSBzaXplX3YgLSBzaXplX3c7CisgICAgYXNzZXJ0KGsgPj0gMCk7CisgICAgYSA9IF9QeUxvbmdfTmV3KGspOworICAgIGlmIChhID09IE5VTEwpIHsKKyAgICAgICAgUHlfREVDUkVGKHcpOworICAgICAgICBQeV9ERUNSRUYodik7CisgICAgICAgICpwcmVtID0gTlVMTDsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIHYwID0gdi0+b2JfZGlnaXQ7CisgICAgdzAgPSB3LT5vYl9kaWdpdDsKKyAgICB3bTEgPSB3MFtzaXplX3ctMV07CisgICAgd20yID0gdzBbc2l6ZV93LTJdOworICAgIGZvciAodmsgPSB2MCtrLCBhayA9IGEtPm9iX2RpZ2l0ICsgazsgdmstLSA+IHYwOykgeworICAgICAgICAvKiBpbm5lciBsb29wOiBkaXZpZGUgdmtbMDpzaXplX3crMV0gYnkgdzBbMDpzaXplX3ddLCBnaXZpbmcKKyAgICAgICAgICAgc2luZ2xlLWRpZ2l0IHF1b3RpZW50IHEsIHJlbWFpbmRlciBpbiB2a1swOnNpemVfd10uICovCisKKyAgICAgICAgU0lHQ0hFQ0soeworICAgICAgICAgICAgICAgIFB5X0RFQ1JFRihhKTsKKyAgICAgICAgICAgICAgICBQeV9ERUNSRUYodyk7CisgICAgICAgICAgICAgICAgUHlfREVDUkVGKHYpOworICAgICAgICAgICAgICAgICpwcmVtID0gTlVMTDsKKyAgICAgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgICAgIH0pOworCisgICAgICAgIC8qIGVzdGltYXRlIHF1b3RpZW50IGRpZ2l0IHE7IG1heSBvdmVyZXN0aW1hdGUgYnkgMSAocmFyZSkgKi8KKyAgICAgICAgdnRvcCA9IHZrW3NpemVfd107CisgICAgICAgIGFzc2VydCh2dG9wIDw9IHdtMSk7CisgICAgICAgIHZ2ID0gKCh0d29kaWdpdHMpdnRvcCA8PCBQeUxvbmdfU0hJRlQpIHwgdmtbc2l6ZV93LTFdOworICAgICAgICBxID0gKGRpZ2l0KSh2diAvIHdtMSk7CisgICAgICAgIHIgPSAoZGlnaXQpKHZ2IC0gKHR3b2RpZ2l0cyl3bTEgKiBxKTsgLyogciA9IHZ2ICUgd20xICovCisgICAgICAgIHdoaWxlICgodHdvZGlnaXRzKXdtMiAqIHEgPiAoKCh0d29kaWdpdHMpciA8PCBQeUxvbmdfU0hJRlQpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCB2a1tzaXplX3ctMl0pKSB7CisgICAgICAgICAgICAtLXE7CisgICAgICAgICAgICByICs9IHdtMTsKKyAgICAgICAgICAgIGlmIChyID49IFB5TG9uZ19CQVNFKQorICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisgICAgICAgIGFzc2VydChxIDw9IFB5TG9uZ19CQVNFKTsKKworICAgICAgICAvKiBzdWJ0cmFjdCBxKncwWzA6c2l6ZV93XSBmcm9tIHZrWzA6c2l6ZV93KzFdICovCisgICAgICAgIHpoaSA9IDA7CisgICAgICAgIGZvciAoaSA9IDA7IGkgPCBzaXplX3c7ICsraSkgeworICAgICAgICAgICAgLyogaW52YXJpYW50czogLVB5TG9uZ19CQVNFIDw9IC1xIDw9IHpoaSA8PSAwOworICAgICAgICAgICAgICAgLVB5TG9uZ19CQVNFICogcSA8PSB6IDwgUHlMb25nX0JBU0UgKi8KKyAgICAgICAgICAgIHogPSAoc2RpZ2l0KXZrW2ldICsgemhpIC0KKyAgICAgICAgICAgICAgICAoc3R3b2RpZ2l0cylxICogKHN0d29kaWdpdHMpdzBbaV07CisgICAgICAgICAgICB2a1tpXSA9IChkaWdpdCl6ICYgUHlMb25nX01BU0s7CisgICAgICAgICAgICB6aGkgPSAoc2RpZ2l0KVB5X0FSSVRITUVUSUNfUklHSFRfU0hJRlQoc3R3b2RpZ2l0cywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB6LCBQeUxvbmdfU0hJRlQpOworICAgICAgICB9CisKKyAgICAgICAgLyogYWRkIHcgYmFjayBpZiBxIHdhcyB0b28gbGFyZ2UgKHRoaXMgYnJhbmNoIHRha2VuIHJhcmVseSkgKi8KKyAgICAgICAgYXNzZXJ0KChzZGlnaXQpdnRvcCArIHpoaSA9PSAtMSB8fCAoc2RpZ2l0KXZ0b3AgKyB6aGkgPT0gMCk7CisgICAgICAgIGlmICgoc2RpZ2l0KXZ0b3AgKyB6aGkgPCAwKSB7CisgICAgICAgICAgICBjYXJyeSA9IDA7CisgICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgc2l6ZV93OyArK2kpIHsKKyAgICAgICAgICAgICAgICBjYXJyeSArPSB2a1tpXSArIHcwW2ldOworICAgICAgICAgICAgICAgIHZrW2ldID0gY2FycnkgJiBQeUxvbmdfTUFTSzsKKyAgICAgICAgICAgICAgICBjYXJyeSA+Pj0gUHlMb25nX1NISUZUOworICAgICAgICAgICAgfQorICAgICAgICAgICAgLS1xOworICAgICAgICB9CisKKyAgICAgICAgLyogc3RvcmUgcXVvdGllbnQgZGlnaXQgKi8KKyAgICAgICAgYXNzZXJ0KHEgPCBQeUxvbmdfQkFTRSk7CisgICAgICAgICotLWFrID0gcTsKKyAgICB9CisKKyAgICAvKiB1bnNoaWZ0IHJlbWFpbmRlcjsgd2UgcmV1c2UgdyB0byBzdG9yZSB0aGUgcmVzdWx0ICovCisgICAgY2FycnkgPSB2X3JzaGlmdCh3MCwgdjAsIHNpemVfdywgZCk7CisgICAgYXNzZXJ0KGNhcnJ5PT0wKTsKKyAgICBQeV9ERUNSRUYodik7CisKKyAgICAqcHJlbSA9IGxvbmdfbm9ybWFsaXplKHcpOworICAgIHJldHVybiBsb25nX25vcm1hbGl6ZShhKTsKK30KKworLyogRm9yIGEgbm9uemVybyBQeUxvbmcgYSwgZXhwcmVzcyBhIGluIHRoZSBmb3JtIHggKiAyKiplLCB3aXRoIDAuNSA8PQorICAgYWJzKHgpIDwgMS4wIGFuZCBlID49IDA7IHJldHVybiB4IGFuZCBwdXQgZSBpbiAqZS4gIEhlcmUgeCBpcworICAgcm91bmRlZCB0byBEQkxfTUFOVF9ESUcgc2lnbmlmaWNhbnQgYml0cyB1c2luZyByb3VuZC1oYWxmLXRvLWV2ZW4uCisgICBJZiBhID09IDAsIHJldHVybiAwLjAgYW5kIHNldCAqZSA9IDAuICBJZiB0aGUgcmVzdWx0aW5nIGV4cG9uZW50CisgICBlIGlzIGxhcmdlciB0aGFuIFBZX1NTSVpFX1RfTUFYLCByYWlzZSBPdmVyZmxvd0Vycm9yIGFuZCByZXR1cm4KKyAgIC0xLjAuICovCisKKy8qIGF0dGVtcHQgdG8gZGVmaW5lIDIuMCoqREJMX01BTlRfRElHIGFzIGEgY29tcGlsZS10aW1lIGNvbnN0YW50ICovCisjaWYgREJMX01BTlRfRElHID09IDUzCisjZGVmaW5lIEVYUDJfREJMX01BTlRfRElHIDkwMDcxOTkyNTQ3NDA5OTIuMAorI2Vsc2UKKyNkZWZpbmUgRVhQMl9EQkxfTUFOVF9ESUcgKGxkZXhwKDEuMCwgREJMX01BTlRfRElHKSkKKyNlbmRpZgorCitkb3VibGUKK19QeUxvbmdfRnJleHAoUHlMb25nT2JqZWN0ICphLCBQeV9zc2l6ZV90ICplKQoreworICAgIFB5X3NzaXplX3QgYV9zaXplLCBhX2JpdHMsIHNoaWZ0X2RpZ2l0cywgc2hpZnRfYml0cywgeF9zaXplOworICAgIC8qIFNlZSBiZWxvdyBmb3Igd2h5IHhfZGlnaXRzIGlzIGFsd2F5cyBsYXJnZSBlbm91Z2guICovCisgICAgZGlnaXQgcmVtLCB4X2RpZ2l0c1syICsgKERCTF9NQU5UX0RJRyArIDEpIC8gUHlMb25nX1NISUZUXTsKKyAgICBkb3VibGUgZHg7CisgICAgLyogQ29ycmVjdGlvbiB0ZXJtIGZvciByb3VuZC1oYWxmLXRvLWV2ZW4gcm91bmRpbmcuICBGb3IgYSBkaWdpdCB4LAorICAgICAgICJ4ICsgaGFsZl9ldmVuX2NvcnJlY3Rpb25beCAmIDddIiBnaXZlcyB4IHJvdW5kZWQgdG8gdGhlIG5lYXJlc3QKKyAgICAgICBtdWx0aXBsZSBvZiA0LCByb3VuZGluZyB0aWVzIHRvIGEgbXVsdGlwbGUgb2YgOC4gKi8KKyAgICBzdGF0aWMgY29uc3QgaW50IGhhbGZfZXZlbl9jb3JyZWN0aW9uWzhdID0gezAsIC0xLCAtMiwgMSwgMCwgLTEsIDIsIDF9OworCisgICAgYV9zaXplID0gQUJTKFB5X1NJWkUoYSkpOworICAgIGlmIChhX3NpemUgPT0gMCkgeworICAgICAgICAvKiBTcGVjaWFsIGNhc2UgZm9yIDA6IHNpZ25pZmljYW5kIDAuMCwgZXhwb25lbnQgMC4gKi8KKyAgICAgICAgKmUgPSAwOworICAgICAgICByZXR1cm4gMC4wOworICAgIH0KKyAgICBhX2JpdHMgPSBiaXRzX2luX2RpZ2l0KGEtPm9iX2RpZ2l0W2Ffc2l6ZS0xXSk7CisgICAgLyogVGhlIGZvbGxvd2luZyBpcyBhbiBvdmVyZmxvdy1mcmVlIHZlcnNpb24gb2YgdGhlIGNoZWNrCisgICAgICAgImlmICgoYV9zaXplIC0gMSkgKiBQeUxvbmdfU0hJRlQgKyBhX2JpdHMgPiBQWV9TU0laRV9UX01BWCkgLi4uIiAqLworICAgIGlmIChhX3NpemUgPj0gKFBZX1NTSVpFX1RfTUFYIC0gMSkgLyBQeUxvbmdfU0hJRlQgKyAxICYmCisgICAgICAgIChhX3NpemUgPiAoUFlfU1NJWkVfVF9NQVggLSAxKSAvIFB5TG9uZ19TSElGVCArIDEgfHwKKyAgICAgICAgIGFfYml0cyA+IChQWV9TU0laRV9UX01BWCAtIDEpICUgUHlMb25nX1NISUZUICsgMSkpCisgICAgICAgIGdvdG8gb3ZlcmZsb3c7CisgICAgYV9iaXRzID0gKGFfc2l6ZSAtIDEpICogUHlMb25nX1NISUZUICsgYV9iaXRzOworCisgICAgLyogU2hpZnQgdGhlIGZpcnN0IERCTF9NQU5UX0RJRyArIDIgYml0cyBvZiBhIGludG8geF9kaWdpdHNbMDp4X3NpemVdCisgICAgICAgKHNoaWZ0aW5nIGxlZnQgaWYgYV9iaXRzIDw9IERCTF9NQU5UX0RJRyArIDIpLgorCisgICAgICAgTnVtYmVyIG9mIGRpZ2l0cyBuZWVkZWQgZm9yIHJlc3VsdDogd3JpdGUgLy8gZm9yIGZsb29yIGRpdmlzaW9uLgorICAgICAgIFRoZW4gaWYgc2hpZnRpbmcgbGVmdCwgd2UgZW5kIHVwIHVzaW5nCisKKyAgICAgICAgIDEgKyBhX3NpemUgKyAoREJMX01BTlRfRElHICsgMiAtIGFfYml0cykgLy8gUHlMb25nX1NISUZUCisKKyAgICAgICBkaWdpdHMuICBJZiBzaGlmdGluZyByaWdodCwgd2UgdXNlCisKKyAgICAgICAgIGFfc2l6ZSAtIChhX2JpdHMgLSBEQkxfTUFOVF9ESUcgLSAyKSAvLyBQeUxvbmdfU0hJRlQKKworICAgICAgIGRpZ2l0cy4gIFVzaW5nIGFfc2l6ZSA9IDEgKyAoYV9iaXRzIC0gMSkgLy8gUHlMb25nX1NISUZUIGFsb25nIHdpdGgKKyAgICAgICB0aGUgaW5lcXVhbGl0aWVzCisKKyAgICAgICAgIG0gLy8gUHlMb25nX1NISUZUICsgbiAvLyBQeUxvbmdfU0hJRlQgPD0gKG0gKyBuKSAvLyBQeUxvbmdfU0hJRlQKKyAgICAgICAgIG0gLy8gUHlMb25nX1NISUZUIC0gbiAvLyBQeUxvbmdfU0hJRlQgPD0KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDEgKyAobSAtIG4gLSAxKSAvLyBQeUxvbmdfU0hJRlQsCisKKyAgICAgICB2YWxpZCBmb3IgYW55IGludGVnZXJzIG0gYW5kIG4sIHdlIGZpbmQgdGhhdCB4X3NpemUgc2F0aXNmaWVzCisKKyAgICAgICAgIHhfc2l6ZSA8PSAyICsgKERCTF9NQU5UX0RJRyArIDEpIC8vIFB5TG9uZ19TSElGVAorCisgICAgICAgaW4gYm90aCBjYXNlcy4KKyAgICAqLworICAgIGlmIChhX2JpdHMgPD0gREJMX01BTlRfRElHICsgMikgeworICAgICAgICBzaGlmdF9kaWdpdHMgPSAoREJMX01BTlRfRElHICsgMiAtIGFfYml0cykgLyBQeUxvbmdfU0hJRlQ7CisgICAgICAgIHNoaWZ0X2JpdHMgPSAoREJMX01BTlRfRElHICsgMiAtIGFfYml0cykgJSBQeUxvbmdfU0hJRlQ7CisgICAgICAgIHhfc2l6ZSA9IDA7CisgICAgICAgIHdoaWxlICh4X3NpemUgPCBzaGlmdF9kaWdpdHMpCisgICAgICAgICAgICB4X2RpZ2l0c1t4X3NpemUrK10gPSAwOworICAgICAgICByZW0gPSB2X2xzaGlmdCh4X2RpZ2l0cyArIHhfc2l6ZSwgYS0+b2JfZGlnaXQsIGFfc2l6ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgKGludClzaGlmdF9iaXRzKTsKKyAgICAgICAgeF9zaXplICs9IGFfc2l6ZTsKKyAgICAgICAgeF9kaWdpdHNbeF9zaXplKytdID0gcmVtOworICAgIH0KKyAgICBlbHNlIHsKKyAgICAgICAgc2hpZnRfZGlnaXRzID0gKGFfYml0cyAtIERCTF9NQU5UX0RJRyAtIDIpIC8gUHlMb25nX1NISUZUOworICAgICAgICBzaGlmdF9iaXRzID0gKGFfYml0cyAtIERCTF9NQU5UX0RJRyAtIDIpICUgUHlMb25nX1NISUZUOworICAgICAgICByZW0gPSB2X3JzaGlmdCh4X2RpZ2l0cywgYS0+b2JfZGlnaXQgKyBzaGlmdF9kaWdpdHMsCisgICAgICAgICAgICAgICAgICAgICAgIGFfc2l6ZSAtIHNoaWZ0X2RpZ2l0cywgKGludClzaGlmdF9iaXRzKTsKKyAgICAgICAgeF9zaXplID0gYV9zaXplIC0gc2hpZnRfZGlnaXRzOworICAgICAgICAvKiBGb3IgY29ycmVjdCByb3VuZGluZyBiZWxvdywgd2UgbmVlZCB0aGUgbGVhc3Qgc2lnbmlmaWNhbnQKKyAgICAgICAgICAgYml0IG9mIHggdG8gYmUgJ3N0aWNreScgZm9yIHRoaXMgc2hpZnQ6IGlmIGFueSBvZiB0aGUgYml0cworICAgICAgICAgICBzaGlmdGVkIG91dCB3YXMgbm9uemVybywgd2Ugc2V0IHRoZSBsZWFzdCBzaWduaWZpY2FudCBiaXQKKyAgICAgICAgICAgb2YgeC4gKi8KKyAgICAgICAgaWYgKHJlbSkKKyAgICAgICAgICAgIHhfZGlnaXRzWzBdIHw9IDE7CisgICAgICAgIGVsc2UKKyAgICAgICAgICAgIHdoaWxlIChzaGlmdF9kaWdpdHMgPiAwKQorICAgICAgICAgICAgICAgIGlmIChhLT5vYl9kaWdpdFstLXNoaWZ0X2RpZ2l0c10pIHsKKyAgICAgICAgICAgICAgICAgICAgeF9kaWdpdHNbMF0gfD0gMTsKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgfQorICAgIH0KKyAgICBhc3NlcnQoMSA8PSB4X3NpemUgJiYKKyAgICAgICAgICAgeF9zaXplIDw9IChQeV9zc2l6ZV90KShzaXplb2YoeF9kaWdpdHMpL3NpemVvZihkaWdpdCkpKTsKKworICAgIC8qIFJvdW5kLCBhbmQgY29udmVydCB0byBkb3VibGUuICovCisgICAgeF9kaWdpdHNbMF0gKz0gaGFsZl9ldmVuX2NvcnJlY3Rpb25beF9kaWdpdHNbMF0gJiA3XTsKKyAgICBkeCA9IHhfZGlnaXRzWy0teF9zaXplXTsKKyAgICB3aGlsZSAoeF9zaXplID4gMCkKKyAgICAgICAgZHggPSBkeCAqIFB5TG9uZ19CQVNFICsgeF9kaWdpdHNbLS14X3NpemVdOworCisgICAgLyogUmVzY2FsZTsgIG1ha2UgY29ycmVjdGlvbiBpZiByZXN1bHQgaXMgMS4wLiAqLworICAgIGR4IC89IDQuMCAqIEVYUDJfREJMX01BTlRfRElHOworICAgIGlmIChkeCA9PSAxLjApIHsKKyAgICAgICAgaWYgKGFfYml0cyA9PSBQWV9TU0laRV9UX01BWCkKKyAgICAgICAgICAgIGdvdG8gb3ZlcmZsb3c7CisgICAgICAgIGR4ID0gMC41OworICAgICAgICBhX2JpdHMgKz0gMTsKKyAgICB9CisKKyAgICAqZSA9IGFfYml0czsKKyAgICByZXR1cm4gUHlfU0laRShhKSA8IDAgPyAtZHggOiBkeDsKKworICBvdmVyZmxvdzoKKyAgICAvKiBleHBvbmVudCA+IFBZX1NTSVpFX1RfTUFYICovCisgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX092ZXJmbG93RXJyb3IsCisgICAgICAgICAgICAgICAgICAgICJodWdlIGludGVnZXI6IG51bWJlciBvZiBiaXRzIG92ZXJmbG93cyBhIFB5X3NzaXplX3QiKTsKKyAgICAqZSA9IDA7CisgICAgcmV0dXJuIC0xLjA7Cit9CisKKy8qIEdldCBhIEMgZG91YmxlIGZyb20gYSBsb25nIGludCBvYmplY3QuICBSb3VuZHMgdG8gdGhlIG5lYXJlc3QgZG91YmxlLAorICAgdXNpbmcgdGhlIHJvdW5kLWhhbGYtdG8tZXZlbiBydWxlIGluIHRoZSBjYXNlIG9mIGEgdGllLiAqLworCitkb3VibGUKK1B5TG9uZ19Bc0RvdWJsZShQeU9iamVjdCAqdikKK3sKKyAgICBQeV9zc2l6ZV90IGV4cG9uZW50OworICAgIGRvdWJsZSB4OworCisgICAgaWYgKHYgPT0gTlVMTCB8fCAhUHlMb25nX0NoZWNrKHYpKSB7CisgICAgICAgIFB5RXJyX0JhZEludGVybmFsQ2FsbCgpOworICAgICAgICByZXR1cm4gLTEuMDsKKyAgICB9CisgICAgeCA9IF9QeUxvbmdfRnJleHAoKFB5TG9uZ09iamVjdCAqKXYsICZleHBvbmVudCk7CisgICAgaWYgKCh4ID09IC0xLjAgJiYgUHlFcnJfT2NjdXJyZWQoKSkgfHwgZXhwb25lbnQgPiBEQkxfTUFYX0VYUCkgeworICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfT3ZlcmZsb3dFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICJsb25nIGludCB0b28gbGFyZ2UgdG8gY29udmVydCB0byBmbG9hdCIpOworICAgICAgICByZXR1cm4gLTEuMDsKKyAgICB9CisgICAgcmV0dXJuIGxkZXhwKHgsIChpbnQpZXhwb25lbnQpOworfQorCisvKiBNZXRob2RzICovCisKK3N0YXRpYyB2b2lkCitsb25nX2RlYWxsb2MoUHlPYmplY3QgKnYpCit7CisgICAgUHlfVFlQRSh2KS0+dHBfZnJlZSh2KTsKK30KKworc3RhdGljIFB5T2JqZWN0ICoKK2xvbmdfcmVwcihQeU9iamVjdCAqdikKK3sKKyAgICByZXR1cm4gX1B5TG9uZ19Gb3JtYXQodiwgMTAsIDEsIDApOworfQorCitzdGF0aWMgUHlPYmplY3QgKgorbG9uZ19zdHIoUHlPYmplY3QgKnYpCit7CisgICAgcmV0dXJuIF9QeUxvbmdfRm9ybWF0KHYsIDEwLCAwLCAwKTsKK30KKworc3RhdGljIGludAorbG9uZ19jb21wYXJlKFB5TG9uZ09iamVjdCAqYSwgUHlMb25nT2JqZWN0ICpiKQoreworICAgIFB5X3NzaXplX3Qgc2lnbjsKKworICAgIGlmIChQeV9TSVpFKGEpICE9IFB5X1NJWkUoYikpIHsKKyAgICAgICAgc2lnbiA9IFB5X1NJWkUoYSkgLSBQeV9TSVpFKGIpOworICAgIH0KKyAgICBlbHNlIHsKKyAgICAgICAgUHlfc3NpemVfdCBpID0gQUJTKFB5X1NJWkUoYSkpOworICAgICAgICB3aGlsZSAoLS1pID49IDAgJiYgYS0+b2JfZGlnaXRbaV0gPT0gYi0+b2JfZGlnaXRbaV0pCisgICAgICAgICAgICA7CisgICAgICAgIGlmIChpIDwgMCkKKyAgICAgICAgICAgIHNpZ24gPSAwOworICAgICAgICBlbHNlIHsKKyAgICAgICAgICAgIHNpZ24gPSAoc2RpZ2l0KWEtPm9iX2RpZ2l0W2ldIC0gKHNkaWdpdCliLT5vYl9kaWdpdFtpXTsKKyAgICAgICAgICAgIGlmIChQeV9TSVpFKGEpIDwgMCkKKyAgICAgICAgICAgICAgICBzaWduID0gLXNpZ247CisgICAgICAgIH0KKyAgICB9CisgICAgcmV0dXJuIHNpZ24gPCAwID8gLTEgOiBzaWduID4gMCA/IDEgOiAwOworfQorCitzdGF0aWMgbG9uZworbG9uZ19oYXNoKFB5TG9uZ09iamVjdCAqdikKK3sKKyAgICB1bnNpZ25lZCBsb25nIHg7CisgICAgUHlfc3NpemVfdCBpOworICAgIGludCBzaWduOworCisgICAgLyogVGhpcyBpcyBkZXNpZ25lZCBzbyB0aGF0IFB5dGhvbiBpbnRzIGFuZCBsb25ncyB3aXRoIHRoZQorICAgICAgIHNhbWUgdmFsdWUgaGFzaCB0byB0aGUgc2FtZSB2YWx1ZSwgb3RoZXJ3aXNlIGNvbXBhcmlzb25zCisgICAgICAgb2YgbWFwcGluZyBrZXlzIHdpbGwgdHVybiBvdXQgd2VpcmQgKi8KKyAgICBpID0gdi0+b2Jfc2l6ZTsKKyAgICBzaWduID0gMTsKKyAgICB4ID0gMDsKKyAgICBpZiAoaSA8IDApIHsKKyAgICAgICAgc2lnbiA9IC0xOworICAgICAgICBpID0gLShpKTsKKyAgICB9CisgICAgLyogVGhlIGZvbGxvd2luZyBsb29wIHByb2R1Y2VzIGEgQyB1bnNpZ25lZCBsb25nIHggc3VjaCB0aGF0IHggaXMKKyAgICAgICBjb25ncnVlbnQgdG8gdGhlIGFic29sdXRlIHZhbHVlIG9mIHYgbW9kdWxvIFVMT05HX01BWC4gIFRoZQorICAgICAgIHJlc3VsdGluZyB4IGlzIG5vbnplcm8gaWYgYW5kIG9ubHkgaWYgdiBpcy4gKi8KKyAgICB3aGlsZSAoLS1pID49IDApIHsKKyAgICAgICAgLyogRm9yY2UgYSBuYXRpdmUgbG9uZyAjLWJpdHMgKDMyIG9yIDY0KSBjaXJjdWxhciBzaGlmdCAqLworICAgICAgICB4ID0gKHggPj4gKDgqU0laRU9GX0xPTkctUHlMb25nX1NISUZUKSkgfCAoeCA8PCBQeUxvbmdfU0hJRlQpOworICAgICAgICB4ICs9IHYtPm9iX2RpZ2l0W2ldOworICAgICAgICAvKiBJZiB0aGUgYWRkaXRpb24gYWJvdmUgb3ZlcmZsb3dlZCB3ZSBjb21wZW5zYXRlIGJ5CisgICAgICAgICAgIGluY3JlbWVudGluZy4gIFRoaXMgcHJlc2VydmVzIHRoZSB2YWx1ZSBtb2R1bG8KKyAgICAgICAgICAgVUxPTkdfTUFYLiAqLworICAgICAgICBpZiAoeCA8IHYtPm9iX2RpZ2l0W2ldKQorICAgICAgICAgICAgeCsrOworICAgIH0KKyAgICB4ID0geCAqIHNpZ247CisgICAgaWYgKHggPT0gKHVuc2lnbmVkIGxvbmcpLTEpCisgICAgICAgIHggPSAodW5zaWduZWQgbG9uZyktMjsKKyAgICByZXR1cm4gKGxvbmcpeDsKK30KKworCisvKiBBZGQgdGhlIGFic29sdXRlIHZhbHVlcyBvZiB0d28gbG9uZyBpbnRlZ2Vycy4gKi8KKworc3RhdGljIFB5TG9uZ09iamVjdCAqCit4X2FkZChQeUxvbmdPYmplY3QgKmEsIFB5TG9uZ09iamVjdCAqYikKK3sKKyAgICBQeV9zc2l6ZV90IHNpemVfYSA9IEFCUyhQeV9TSVpFKGEpKSwgc2l6ZV9iID0gQUJTKFB5X1NJWkUoYikpOworICAgIFB5TG9uZ09iamVjdCAqejsKKyAgICBQeV9zc2l6ZV90IGk7CisgICAgZGlnaXQgY2FycnkgPSAwOworCisgICAgLyogRW5zdXJlIGEgaXMgdGhlIGxhcmdlciBvZiB0aGUgdHdvOiAqLworICAgIGlmIChzaXplX2EgPCBzaXplX2IpIHsKKyAgICAgICAgeyBQeUxvbmdPYmplY3QgKnRlbXAgPSBhOyBhID0gYjsgYiA9IHRlbXA7IH0KKyAgICAgICAgeyBQeV9zc2l6ZV90IHNpemVfdGVtcCA9IHNpemVfYTsKKyAgICAgICAgICAgIHNpemVfYSA9IHNpemVfYjsKKyAgICAgICAgICAgIHNpemVfYiA9IHNpemVfdGVtcDsgfQorICAgIH0KKyAgICB6ID0gX1B5TG9uZ19OZXcoc2l6ZV9hKzEpOworICAgIGlmICh6ID09IE5VTEwpCisgICAgICAgIHJldHVybiBOVUxMOworICAgIGZvciAoaSA9IDA7IGkgPCBzaXplX2I7ICsraSkgeworICAgICAgICBjYXJyeSArPSBhLT5vYl9kaWdpdFtpXSArIGItPm9iX2RpZ2l0W2ldOworICAgICAgICB6LT5vYl9kaWdpdFtpXSA9IGNhcnJ5ICYgUHlMb25nX01BU0s7CisgICAgICAgIGNhcnJ5ID4+PSBQeUxvbmdfU0hJRlQ7CisgICAgfQorICAgIGZvciAoOyBpIDwgc2l6ZV9hOyArK2kpIHsKKyAgICAgICAgY2FycnkgKz0gYS0+b2JfZGlnaXRbaV07CisgICAgICAgIHotPm9iX2RpZ2l0W2ldID0gY2FycnkgJiBQeUxvbmdfTUFTSzsKKyAgICAgICAgY2FycnkgPj49IFB5TG9uZ19TSElGVDsKKyAgICB9CisgICAgei0+b2JfZGlnaXRbaV0gPSBjYXJyeTsKKyAgICByZXR1cm4gbG9uZ19ub3JtYWxpemUoeik7Cit9CisKKy8qIFN1YnRyYWN0IHRoZSBhYnNvbHV0ZSB2YWx1ZXMgb2YgdHdvIGludGVnZXJzLiAqLworCitzdGF0aWMgUHlMb25nT2JqZWN0ICoKK3hfc3ViKFB5TG9uZ09iamVjdCAqYSwgUHlMb25nT2JqZWN0ICpiKQoreworICAgIFB5X3NzaXplX3Qgc2l6ZV9hID0gQUJTKFB5X1NJWkUoYSkpLCBzaXplX2IgPSBBQlMoUHlfU0laRShiKSk7CisgICAgUHlMb25nT2JqZWN0ICp6OworICAgIFB5X3NzaXplX3QgaTsKKyAgICBpbnQgc2lnbiA9IDE7CisgICAgZGlnaXQgYm9ycm93ID0gMDsKKworICAgIC8qIEVuc3VyZSBhIGlzIHRoZSBsYXJnZXIgb2YgdGhlIHR3bzogKi8KKyAgICBpZiAoc2l6ZV9hIDwgc2l6ZV9iKSB7CisgICAgICAgIHNpZ24gPSAtMTsKKyAgICAgICAgeyBQeUxvbmdPYmplY3QgKnRlbXAgPSBhOyBhID0gYjsgYiA9IHRlbXA7IH0KKyAgICAgICAgeyBQeV9zc2l6ZV90IHNpemVfdGVtcCA9IHNpemVfYTsKKyAgICAgICAgICAgIHNpemVfYSA9IHNpemVfYjsKKyAgICAgICAgICAgIHNpemVfYiA9IHNpemVfdGVtcDsgfQorICAgIH0KKyAgICBlbHNlIGlmIChzaXplX2EgPT0gc2l6ZV9iKSB7CisgICAgICAgIC8qIEZpbmQgaGlnaGVzdCBkaWdpdCB3aGVyZSBhIGFuZCBiIGRpZmZlcjogKi8KKyAgICAgICAgaSA9IHNpemVfYTsKKyAgICAgICAgd2hpbGUgKC0taSA+PSAwICYmIGEtPm9iX2RpZ2l0W2ldID09IGItPm9iX2RpZ2l0W2ldKQorICAgICAgICAgICAgOworICAgICAgICBpZiAoaSA8IDApCisgICAgICAgICAgICByZXR1cm4gX1B5TG9uZ19OZXcoMCk7CisgICAgICAgIGlmIChhLT5vYl9kaWdpdFtpXSA8IGItPm9iX2RpZ2l0W2ldKSB7CisgICAgICAgICAgICBzaWduID0gLTE7CisgICAgICAgICAgICB7IFB5TG9uZ09iamVjdCAqdGVtcCA9IGE7IGEgPSBiOyBiID0gdGVtcDsgfQorICAgICAgICB9CisgICAgICAgIHNpemVfYSA9IHNpemVfYiA9IGkrMTsKKyAgICB9CisgICAgeiA9IF9QeUxvbmdfTmV3KHNpemVfYSk7CisgICAgaWYgKHogPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgZm9yIChpID0gMDsgaSA8IHNpemVfYjsgKytpKSB7CisgICAgICAgIC8qIFRoZSBmb2xsb3dpbmcgYXNzdW1lcyB1bnNpZ25lZCBhcml0aG1ldGljCisgICAgICAgICAgIHdvcmtzIG1vZHVsZSAyKipOIGZvciBzb21lIE4+UHlMb25nX1NISUZULiAqLworICAgICAgICBib3Jyb3cgPSBhLT5vYl9kaWdpdFtpXSAtIGItPm9iX2RpZ2l0W2ldIC0gYm9ycm93OworICAgICAgICB6LT5vYl9kaWdpdFtpXSA9IGJvcnJvdyAmIFB5TG9uZ19NQVNLOworICAgICAgICBib3Jyb3cgPj49IFB5TG9uZ19TSElGVDsKKyAgICAgICAgYm9ycm93ICY9IDE7IC8qIEtlZXAgb25seSBvbmUgc2lnbiBiaXQgKi8KKyAgICB9CisgICAgZm9yICg7IGkgPCBzaXplX2E7ICsraSkgeworICAgICAgICBib3Jyb3cgPSBhLT5vYl9kaWdpdFtpXSAtIGJvcnJvdzsKKyAgICAgICAgei0+b2JfZGlnaXRbaV0gPSBib3Jyb3cgJiBQeUxvbmdfTUFTSzsKKyAgICAgICAgYm9ycm93ID4+PSBQeUxvbmdfU0hJRlQ7CisgICAgICAgIGJvcnJvdyAmPSAxOyAvKiBLZWVwIG9ubHkgb25lIHNpZ24gYml0ICovCisgICAgfQorICAgIGFzc2VydChib3Jyb3cgPT0gMCk7CisgICAgaWYgKHNpZ24gPCAwKQorICAgICAgICB6LT5vYl9zaXplID0gLSh6LT5vYl9zaXplKTsKKyAgICByZXR1cm4gbG9uZ19ub3JtYWxpemUoeik7Cit9CisKK3N0YXRpYyBQeU9iamVjdCAqCitsb25nX2FkZChQeUxvbmdPYmplY3QgKnYsIFB5TG9uZ09iamVjdCAqdykKK3sKKyAgICBQeUxvbmdPYmplY3QgKmEsICpiLCAqejsKKworICAgIENPTlZFUlRfQklOT1AoKFB5T2JqZWN0ICopdiwgKFB5T2JqZWN0ICopdywgJmEsICZiKTsKKworICAgIGlmIChhLT5vYl9zaXplIDwgMCkgeworICAgICAgICBpZiAoYi0+b2Jfc2l6ZSA8IDApIHsKKyAgICAgICAgICAgIHogPSB4X2FkZChhLCBiKTsKKyAgICAgICAgICAgIGlmICh6ICE9IE5VTEwgJiYgei0+b2Jfc2l6ZSAhPSAwKQorICAgICAgICAgICAgICAgIHotPm9iX3NpemUgPSAtKHotPm9iX3NpemUpOworICAgICAgICB9CisgICAgICAgIGVsc2UKKyAgICAgICAgICAgIHogPSB4X3N1YihiLCBhKTsKKyAgICB9CisgICAgZWxzZSB7CisgICAgICAgIGlmIChiLT5vYl9zaXplIDwgMCkKKyAgICAgICAgICAgIHogPSB4X3N1YihhLCBiKTsKKyAgICAgICAgZWxzZQorICAgICAgICAgICAgeiA9IHhfYWRkKGEsIGIpOworICAgIH0KKyAgICBQeV9ERUNSRUYoYSk7CisgICAgUHlfREVDUkVGKGIpOworICAgIHJldHVybiAoUHlPYmplY3QgKil6OworfQorCitzdGF0aWMgUHlPYmplY3QgKgorbG9uZ19zdWIoUHlMb25nT2JqZWN0ICp2LCBQeUxvbmdPYmplY3QgKncpCit7CisgICAgUHlMb25nT2JqZWN0ICphLCAqYiwgKno7CisKKyAgICBDT05WRVJUX0JJTk9QKChQeU9iamVjdCAqKXYsIChQeU9iamVjdCAqKXcsICZhLCAmYik7CisKKyAgICBpZiAoYS0+b2Jfc2l6ZSA8IDApIHsKKyAgICAgICAgaWYgKGItPm9iX3NpemUgPCAwKQorICAgICAgICAgICAgeiA9IHhfc3ViKGEsIGIpOworICAgICAgICBlbHNlCisgICAgICAgICAgICB6ID0geF9hZGQoYSwgYik7CisgICAgICAgIGlmICh6ICE9IE5VTEwgJiYgei0+b2Jfc2l6ZSAhPSAwKQorICAgICAgICAgICAgei0+b2Jfc2l6ZSA9IC0oei0+b2Jfc2l6ZSk7CisgICAgfQorICAgIGVsc2UgeworICAgICAgICBpZiAoYi0+b2Jfc2l6ZSA8IDApCisgICAgICAgICAgICB6ID0geF9hZGQoYSwgYik7CisgICAgICAgIGVsc2UKKyAgICAgICAgICAgIHogPSB4X3N1YihhLCBiKTsKKyAgICB9CisgICAgUHlfREVDUkVGKGEpOworICAgIFB5X0RFQ1JFRihiKTsKKyAgICByZXR1cm4gKFB5T2JqZWN0ICopejsKK30KKworLyogR3JhZGUgc2Nob29sIG11bHRpcGxpY2F0aW9uLCBpZ25vcmluZyB0aGUgc2lnbnMuCisgKiBSZXR1cm5zIHRoZSBhYnNvbHV0ZSB2YWx1ZSBvZiB0aGUgcHJvZHVjdCwgb3IgTlVMTCBpZiBlcnJvci4KKyAqLworc3RhdGljIFB5TG9uZ09iamVjdCAqCit4X211bChQeUxvbmdPYmplY3QgKmEsIFB5TG9uZ09iamVjdCAqYikKK3sKKyAgICBQeUxvbmdPYmplY3QgKno7CisgICAgUHlfc3NpemVfdCBzaXplX2EgPSBBQlMoUHlfU0laRShhKSk7CisgICAgUHlfc3NpemVfdCBzaXplX2IgPSBBQlMoUHlfU0laRShiKSk7CisgICAgUHlfc3NpemVfdCBpOworCisgICAgeiA9IF9QeUxvbmdfTmV3KHNpemVfYSArIHNpemVfYik7CisgICAgaWYgKHogPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisKKyAgICBtZW1zZXQoei0+b2JfZGlnaXQsIDAsIFB5X1NJWkUoeikgKiBzaXplb2YoZGlnaXQpKTsKKyAgICBpZiAoYSA9PSBiKSB7CisgICAgICAgIC8qIEVmZmljaWVudCBzcXVhcmluZyBwZXIgSEFDLCBBbGdvcml0aG0gMTQuMTY6CisgICAgICAgICAqIGh0dHA6Ly93d3cuY2Fjci5tYXRoLnV3YXRlcmxvby5jYS9oYWMvYWJvdXQvY2hhcDE0LnBkZgorICAgICAgICAgKiBHaXZlcyBzbGlnaHRseSBsZXNzIHRoYW4gYSAyeCBzcGVlZHVwIHdoZW4gYSA9PSBiLAorICAgICAgICAgKiB2aWEgZXhwbG9pdGluZyB0aGF0IGVhY2ggZW50cnkgaW4gdGhlIG11bHRpcGxpY2F0aW9uCisgICAgICAgICAqIHB5cmFtaWQgYXBwZWFycyB0d2ljZSAoZXhjZXB0IGZvciB0aGUgc2l6ZV9hIHNxdWFyZXMpLgorICAgICAgICAgKi8KKyAgICAgICAgZm9yIChpID0gMDsgaSA8IHNpemVfYTsgKytpKSB7CisgICAgICAgICAgICB0d29kaWdpdHMgY2Fycnk7CisgICAgICAgICAgICB0d29kaWdpdHMgZiA9IGEtPm9iX2RpZ2l0W2ldOworICAgICAgICAgICAgZGlnaXQgKnB6ID0gei0+b2JfZGlnaXQgKyAoaSA8PCAxKTsKKyAgICAgICAgICAgIGRpZ2l0ICpwYSA9IGEtPm9iX2RpZ2l0ICsgaSArIDE7CisgICAgICAgICAgICBkaWdpdCAqcGFlbmQgPSBhLT5vYl9kaWdpdCArIHNpemVfYTsKKworICAgICAgICAgICAgU0lHQ0hFQ0soeworICAgICAgICAgICAgICAgICAgICBQeV9ERUNSRUYoeik7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgICAgICAgICAgICAgIH0pOworCisgICAgICAgICAgICBjYXJyeSA9ICpweiArIGYgKiBmOworICAgICAgICAgICAgKnB6KysgPSAoZGlnaXQpKGNhcnJ5ICYgUHlMb25nX01BU0spOworICAgICAgICAgICAgY2FycnkgPj49IFB5TG9uZ19TSElGVDsKKyAgICAgICAgICAgIGFzc2VydChjYXJyeSA8PSBQeUxvbmdfTUFTSyk7CisKKyAgICAgICAgICAgIC8qIE5vdyBmIGlzIGFkZGVkIGluIHR3aWNlIGluIGVhY2ggY29sdW1uIG9mIHRoZQorICAgICAgICAgICAgICogcHlyYW1pZCBpdCBhcHBlYXJzLiAgU2FtZSBhcyBhZGRpbmcgZjw8MSBvbmNlLgorICAgICAgICAgICAgICovCisgICAgICAgICAgICBmIDw8PSAxOworICAgICAgICAgICAgd2hpbGUgKHBhIDwgcGFlbmQpIHsKKyAgICAgICAgICAgICAgICBjYXJyeSArPSAqcHogKyAqcGErKyAqIGY7CisgICAgICAgICAgICAgICAgKnB6KysgPSAoZGlnaXQpKGNhcnJ5ICYgUHlMb25nX01BU0spOworICAgICAgICAgICAgICAgIGNhcnJ5ID4+PSBQeUxvbmdfU0hJRlQ7CisgICAgICAgICAgICAgICAgYXNzZXJ0KGNhcnJ5IDw9IChQeUxvbmdfTUFTSyA8PCAxKSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoY2FycnkpIHsKKyAgICAgICAgICAgICAgICBjYXJyeSArPSAqcHo7CisgICAgICAgICAgICAgICAgKnB6KysgPSAoZGlnaXQpKGNhcnJ5ICYgUHlMb25nX01BU0spOworICAgICAgICAgICAgICAgIGNhcnJ5ID4+PSBQeUxvbmdfU0hJRlQ7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoY2FycnkpCisgICAgICAgICAgICAgICAgKnB6ICs9IChkaWdpdCkoY2FycnkgJiBQeUxvbmdfTUFTSyk7CisgICAgICAgICAgICBhc3NlcnQoKGNhcnJ5ID4+IFB5TG9uZ19TSElGVCkgPT0gMCk7CisgICAgICAgIH0KKyAgICB9CisgICAgZWxzZSB7ICAgICAgLyogYSBpcyBub3QgdGhlIHNhbWUgYXMgYiAtLSBncmFkZXNjaG9vbCBsb25nIG11bHQgKi8KKyAgICAgICAgZm9yIChpID0gMDsgaSA8IHNpemVfYTsgKytpKSB7CisgICAgICAgICAgICB0d29kaWdpdHMgY2FycnkgPSAwOworICAgICAgICAgICAgdHdvZGlnaXRzIGYgPSBhLT5vYl9kaWdpdFtpXTsKKyAgICAgICAgICAgIGRpZ2l0ICpweiA9IHotPm9iX2RpZ2l0ICsgaTsKKyAgICAgICAgICAgIGRpZ2l0ICpwYiA9IGItPm9iX2RpZ2l0OworICAgICAgICAgICAgZGlnaXQgKnBiZW5kID0gYi0+b2JfZGlnaXQgKyBzaXplX2I7CisKKyAgICAgICAgICAgIFNJR0NIRUNLKHsKKyAgICAgICAgICAgICAgICAgICAgUHlfREVDUkVGKHopOworICAgICAgICAgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgICAgICAgICB9KTsKKworICAgICAgICAgICAgd2hpbGUgKHBiIDwgcGJlbmQpIHsKKyAgICAgICAgICAgICAgICBjYXJyeSArPSAqcHogKyAqcGIrKyAqIGY7CisgICAgICAgICAgICAgICAgKnB6KysgPSAoZGlnaXQpKGNhcnJ5ICYgUHlMb25nX01BU0spOworICAgICAgICAgICAgICAgIGNhcnJ5ID4+PSBQeUxvbmdfU0hJRlQ7CisgICAgICAgICAgICAgICAgYXNzZXJ0KGNhcnJ5IDw9IFB5TG9uZ19NQVNLKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChjYXJyeSkKKyAgICAgICAgICAgICAgICAqcHogKz0gKGRpZ2l0KShjYXJyeSAmIFB5TG9uZ19NQVNLKTsKKyAgICAgICAgICAgIGFzc2VydCgoY2FycnkgPj4gUHlMb25nX1NISUZUKSA9PSAwKTsKKyAgICAgICAgfQorICAgIH0KKyAgICByZXR1cm4gbG9uZ19ub3JtYWxpemUoeik7Cit9CisKKy8qIEEgaGVscGVyIGZvciBLYXJhdHN1YmEgbXVsdGlwbGljYXRpb24gKGtfbXVsKS4KKyAgIFRha2VzIGEgbG9uZyAibiIgYW5kIGFuIGludGVnZXIgInNpemUiIHJlcHJlc2VudGluZyB0aGUgcGxhY2UgdG8KKyAgIHNwbGl0LCBhbmQgc2V0cyBsb3cgYW5kIGhpZ2ggc3VjaCB0aGF0IGFicyhuKSA9PSAoaGlnaCA8PCBzaXplKSArIGxvdywKKyAgIHZpZXdpbmcgdGhlIHNoaWZ0IGFzIGJlaW5nIGJ5IGRpZ2l0cy4gIFRoZSBzaWduIGJpdCBpcyBpZ25vcmVkLCBhbmQKKyAgIHRoZSByZXR1cm4gdmFsdWVzIGFyZSA+PSAwLgorICAgUmV0dXJucyAwIG9uIHN1Y2Nlc3MsIC0xIG9uIGZhaWx1cmUuCisqLworc3RhdGljIGludAora211bF9zcGxpdChQeUxvbmdPYmplY3QgKm4sCisgICAgICAgICAgIFB5X3NzaXplX3Qgc2l6ZSwKKyAgICAgICAgICAgUHlMb25nT2JqZWN0ICoqaGlnaCwKKyAgICAgICAgICAgUHlMb25nT2JqZWN0ICoqbG93KQoreworICAgIFB5TG9uZ09iamVjdCAqaGksICpsbzsKKyAgICBQeV9zc2l6ZV90IHNpemVfbG8sIHNpemVfaGk7CisgICAgY29uc3QgUHlfc3NpemVfdCBzaXplX24gPSBBQlMoUHlfU0laRShuKSk7CisKKyAgICBzaXplX2xvID0gTUlOKHNpemVfbiwgc2l6ZSk7CisgICAgc2l6ZV9oaSA9IHNpemVfbiAtIHNpemVfbG87CisKKyAgICBpZiAoKGhpID0gX1B5TG9uZ19OZXcoc2l6ZV9oaSkpID09IE5VTEwpCisgICAgICAgIHJldHVybiAtMTsKKyAgICBpZiAoKGxvID0gX1B5TG9uZ19OZXcoc2l6ZV9sbykpID09IE5VTEwpIHsKKyAgICAgICAgUHlfREVDUkVGKGhpKTsKKyAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKworICAgIG1lbWNweShsby0+b2JfZGlnaXQsIG4tPm9iX2RpZ2l0LCBzaXplX2xvICogc2l6ZW9mKGRpZ2l0KSk7CisgICAgbWVtY3B5KGhpLT5vYl9kaWdpdCwgbi0+b2JfZGlnaXQgKyBzaXplX2xvLCBzaXplX2hpICogc2l6ZW9mKGRpZ2l0KSk7CisKKyAgICAqaGlnaCA9IGxvbmdfbm9ybWFsaXplKGhpKTsKKyAgICAqbG93ID0gbG9uZ19ub3JtYWxpemUobG8pOworICAgIHJldHVybiAwOworfQorCitzdGF0aWMgUHlMb25nT2JqZWN0ICprX2xvcHNpZGVkX211bChQeUxvbmdPYmplY3QgKmEsIFB5TG9uZ09iamVjdCAqYik7CisKKy8qIEthcmF0c3ViYSBtdWx0aXBsaWNhdGlvbi4gIElnbm9yZXMgdGhlIGlucHV0IHNpZ25zLCBhbmQgcmV0dXJucyB0aGUKKyAqIGFic29sdXRlIHZhbHVlIG9mIHRoZSBwcm9kdWN0IChvciBOVUxMIGlmIGVycm9yKS4KKyAqIFNlZSBLbnV0aCBWb2wuIDIgQ2hhcHRlciA0LjMuMyAoUHAuIDI5NC0yOTUpLgorICovCitzdGF0aWMgUHlMb25nT2JqZWN0ICoKK2tfbXVsKFB5TG9uZ09iamVjdCAqYSwgUHlMb25nT2JqZWN0ICpiKQoreworICAgIFB5X3NzaXplX3QgYXNpemUgPSBBQlMoUHlfU0laRShhKSk7CisgICAgUHlfc3NpemVfdCBic2l6ZSA9IEFCUyhQeV9TSVpFKGIpKTsKKyAgICBQeUxvbmdPYmplY3QgKmFoID0gTlVMTDsKKyAgICBQeUxvbmdPYmplY3QgKmFsID0gTlVMTDsKKyAgICBQeUxvbmdPYmplY3QgKmJoID0gTlVMTDsKKyAgICBQeUxvbmdPYmplY3QgKmJsID0gTlVMTDsKKyAgICBQeUxvbmdPYmplY3QgKnJldCA9IE5VTEw7CisgICAgUHlMb25nT2JqZWN0ICp0MSwgKnQyLCAqdDM7CisgICAgUHlfc3NpemVfdCBzaGlmdDsgICAgICAgICAgIC8qIHRoZSBudW1iZXIgb2YgZGlnaXRzIHdlIHNwbGl0IG9mZiAqLworICAgIFB5X3NzaXplX3QgaTsKKworICAgIC8qIChhaCpYK2FsKShiaCpYK2JsKSA9IGFoKmJoKlgqWCArIChhaCpibCArIGFsKmJoKSpYICsgYWwqYmwKKyAgICAgKiBMZXQgayA9IChhaCthbCkqKGJoK2JsKSA9IGFoKmJsICsgYWwqYmggICsgYWgqYmggKyBhbCpibAorICAgICAqIFRoZW4gdGhlIG9yaWdpbmFsIHByb2R1Y3QgaXMKKyAgICAgKiAgICAgYWgqYmgqWCpYICsgKGsgLSBhaCpiaCAtIGFsKmJsKSpYICsgYWwqYmwKKyAgICAgKiBCeSBwaWNraW5nIFggdG8gYmUgYSBwb3dlciBvZiAyLCAiKlgiIGlzIGp1c3Qgc2hpZnRpbmcsIGFuZCBpdCdzCisgICAgICogYmVlbiByZWR1Y2VkIHRvIDMgbXVsdGlwbGllcyBvbiBudW1iZXJzIGhhbGYgdGhlIHNpemUuCisgICAgICovCisKKyAgICAvKiBXZSB3YW50IHRvIHNwbGl0IGJhc2VkIG9uIHRoZSBsYXJnZXIgbnVtYmVyOyBmaWRkbGUgc28gdGhhdCBiCisgICAgICogaXMgbGFyZ2VzdC4KKyAgICAgKi8KKyAgICBpZiAoYXNpemUgPiBic2l6ZSkgeworICAgICAgICB0MSA9IGE7CisgICAgICAgIGEgPSBiOworICAgICAgICBiID0gdDE7CisKKyAgICAgICAgaSA9IGFzaXplOworICAgICAgICBhc2l6ZSA9IGJzaXplOworICAgICAgICBic2l6ZSA9IGk7CisgICAgfQorCisgICAgLyogVXNlIGdyYWRlc2Nob29sIG1hdGggd2hlbiBlaXRoZXIgbnVtYmVyIGlzIHRvbyBzbWFsbC4gKi8KKyAgICBpID0gYSA9PSBiID8gS0FSQVRTVUJBX1NRVUFSRV9DVVRPRkYgOiBLQVJBVFNVQkFfQ1VUT0ZGOworICAgIGlmIChhc2l6ZSA8PSBpKSB7CisgICAgICAgIGlmIChhc2l6ZSA9PSAwKQorICAgICAgICAgICAgcmV0dXJuIF9QeUxvbmdfTmV3KDApOworICAgICAgICBlbHNlCisgICAgICAgICAgICByZXR1cm4geF9tdWwoYSwgYik7CisgICAgfQorCisgICAgLyogSWYgYSBpcyBzbWFsbCBjb21wYXJlZCB0byBiLCBzcGxpdHRpbmcgb24gYiBnaXZlcyBhIGRlZ2VuZXJhdGUKKyAgICAgKiBjYXNlIHdpdGggYWg9PTAsIGFuZCBLYXJhdHN1YmEgbWF5IGJlIChldmVuIG11Y2gpIGxlc3MgZWZmaWNpZW50CisgICAgICogdGhhbiAiZ3JhZGUgc2Nob29sIiB0aGVuLiAgSG93ZXZlciwgd2UgY2FuIHN0aWxsIHdpbiwgYnkgdmlld2luZworICAgICAqIGIgYXMgYSBzdHJpbmcgb2YgImJpZyBkaWdpdHMiLCBlYWNoIG9mIHdpZHRoIGEtPm9iX3NpemUuICBUaGF0CisgICAgICogbGVhZHMgdG8gYSBzZXF1ZW5jZSBvZiBiYWxhbmNlZCBjYWxscyB0byBrX211bC4KKyAgICAgKi8KKyAgICBpZiAoMiAqIGFzaXplIDw9IGJzaXplKQorICAgICAgICByZXR1cm4ga19sb3BzaWRlZF9tdWwoYSwgYik7CisKKyAgICAvKiBTcGxpdCBhICYgYiBpbnRvIGhpICYgbG8gcGllY2VzLiAqLworICAgIHNoaWZ0ID0gYnNpemUgPj4gMTsKKyAgICBpZiAoa211bF9zcGxpdChhLCBzaGlmdCwgJmFoLCAmYWwpIDwgMCkgZ290byBmYWlsOworICAgIGFzc2VydChQeV9TSVpFKGFoKSA+IDApOyAgICAgICAgICAgIC8qIHRoZSBzcGxpdCBpc24ndCBkZWdlbmVyYXRlICovCisKKyAgICBpZiAoYSA9PSBiKSB7CisgICAgICAgIGJoID0gYWg7CisgICAgICAgIGJsID0gYWw7CisgICAgICAgIFB5X0lOQ1JFRihiaCk7CisgICAgICAgIFB5X0lOQ1JFRihibCk7CisgICAgfQorICAgIGVsc2UgaWYgKGttdWxfc3BsaXQoYiwgc2hpZnQsICZiaCwgJmJsKSA8IDApIGdvdG8gZmFpbDsKKworICAgIC8qIFRoZSBwbGFuOgorICAgICAqIDEuIEFsbG9jYXRlIHJlc3VsdCBzcGFjZSAoYXNpemUgKyBic2l6ZSBkaWdpdHM6ICB0aGF0J3MgYWx3YXlzCisgICAgICogICAgZW5vdWdoKS4KKyAgICAgKiAyLiBDb21wdXRlIGFoKmJoLCBhbmQgY29weSBpbnRvIHJlc3VsdCBhdCAyKnNoaWZ0LgorICAgICAqIDMuIENvbXB1dGUgYWwqYmwsIGFuZCBjb3B5IGludG8gcmVzdWx0IGF0IDAuICBOb3RlIHRoYXQgdGhpcworICAgICAqICAgIGNhbid0IG92ZXJsYXAgd2l0aCAjMi4KKyAgICAgKiA0LiBTdWJ0cmFjdCBhbCpibCBmcm9tIHRoZSByZXN1bHQsIHN0YXJ0aW5nIGF0IHNoaWZ0LiAgVGhpcyBtYXkKKyAgICAgKiAgICB1bmRlcmZsb3cgKGJvcnJvdyBvdXQgb2YgdGhlIGhpZ2ggZGlnaXQpLCBidXQgd2UgZG9uJ3QgY2FyZToKKyAgICAgKiAgICB3ZSdyZSBlZmZlY3RpdmVseSBkb2luZyB1bnNpZ25lZCBhcml0aG1ldGljIG1vZAorICAgICAqICAgIFB5TG9uZ19CQVNFKiooc2l6ZWEgKyBzaXplYiksIGFuZCBzbyBsb25nIGFzIHRoZSAqZmluYWwqIHJlc3VsdCBmaXRzLAorICAgICAqICAgIGJvcnJvd3MgYW5kIGNhcnJpZXMgb3V0IG9mIHRoZSBoaWdoIGRpZ2l0IGNhbiBiZSBpZ25vcmVkLgorICAgICAqIDUuIFN1YnRyYWN0IGFoKmJoIGZyb20gdGhlIHJlc3VsdCwgc3RhcnRpbmcgYXQgc2hpZnQuCisgICAgICogNi4gQ29tcHV0ZSAoYWgrYWwpKihiaCtibCksIGFuZCBhZGQgaXQgaW50byB0aGUgcmVzdWx0IHN0YXJ0aW5nCisgICAgICogICAgYXQgc2hpZnQuCisgICAgICovCisKKyAgICAvKiAxLiBBbGxvY2F0ZSByZXN1bHQgc3BhY2UuICovCisgICAgcmV0ID0gX1B5TG9uZ19OZXcoYXNpemUgKyBic2l6ZSk7CisgICAgaWYgKHJldCA9PSBOVUxMKSBnb3RvIGZhaWw7CisjaWZkZWYgUHlfREVCVUcKKyAgICAvKiBGaWxsIHdpdGggdHJhc2gsIHRvIGNhdGNoIHJlZmVyZW5jZSB0byB1bmluaXRpYWxpemVkIGRpZ2l0cy4gKi8KKyAgICBtZW1zZXQocmV0LT5vYl9kaWdpdCwgMHhERiwgUHlfU0laRShyZXQpICogc2l6ZW9mKGRpZ2l0KSk7CisjZW5kaWYKKworICAgIC8qIDIuIHQxIDwtIGFoKmJoLCBhbmQgY29weSBpbnRvIGhpZ2ggZGlnaXRzIG9mIHJlc3VsdC4gKi8KKyAgICBpZiAoKHQxID0ga19tdWwoYWgsIGJoKSkgPT0gTlVMTCkgZ290byBmYWlsOworICAgIGFzc2VydChQeV9TSVpFKHQxKSA+PSAwKTsKKyAgICBhc3NlcnQoMipzaGlmdCArIFB5X1NJWkUodDEpIDw9IFB5X1NJWkUocmV0KSk7CisgICAgbWVtY3B5KHJldC0+b2JfZGlnaXQgKyAyKnNoaWZ0LCB0MS0+b2JfZGlnaXQsCisgICAgICAgICAgIFB5X1NJWkUodDEpICogc2l6ZW9mKGRpZ2l0KSk7CisKKyAgICAvKiBaZXJvLW91dCB0aGUgZGlnaXRzIGhpZ2hlciB0aGFuIHRoZSBhaCpiaCBjb3B5LiAqLworICAgIGkgPSBQeV9TSVpFKHJldCkgLSAyKnNoaWZ0IC0gUHlfU0laRSh0MSk7CisgICAgaWYgKGkpCisgICAgICAgIG1lbXNldChyZXQtPm9iX2RpZ2l0ICsgMipzaGlmdCArIFB5X1NJWkUodDEpLCAwLAorICAgICAgICAgICAgICAgaSAqIHNpemVvZihkaWdpdCkpOworCisgICAgLyogMy4gdDIgPC0gYWwqYmwsIGFuZCBjb3B5IGludG8gdGhlIGxvdyBkaWdpdHMuICovCisgICAgaWYgKCh0MiA9IGtfbXVsKGFsLCBibCkpID09IE5VTEwpIHsKKyAgICAgICAgUHlfREVDUkVGKHQxKTsKKyAgICAgICAgZ290byBmYWlsOworICAgIH0KKyAgICBhc3NlcnQoUHlfU0laRSh0MikgPj0gMCk7CisgICAgYXNzZXJ0KFB5X1NJWkUodDIpIDw9IDIqc2hpZnQpOyAvKiBubyBvdmVybGFwIHdpdGggaGlnaCBkaWdpdHMgKi8KKyAgICBtZW1jcHkocmV0LT5vYl9kaWdpdCwgdDItPm9iX2RpZ2l0LCBQeV9TSVpFKHQyKSAqIHNpemVvZihkaWdpdCkpOworCisgICAgLyogWmVybyBvdXQgcmVtYWluaW5nIGRpZ2l0cy4gKi8KKyAgICBpID0gMipzaGlmdCAtIFB5X1NJWkUodDIpOyAgICAgICAgICAvKiBudW1iZXIgb2YgdW5pbml0aWFsaXplZCBkaWdpdHMgKi8KKyAgICBpZiAoaSkKKyAgICAgICAgbWVtc2V0KHJldC0+b2JfZGlnaXQgKyBQeV9TSVpFKHQyKSwgMCwgaSAqIHNpemVvZihkaWdpdCkpOworCisgICAgLyogNCAmIDUuIFN1YnRyYWN0IGFoKmJoICh0MSkgYW5kIGFsKmJsICh0MikuICBXZSBkbyBhbCpibCBmaXJzdAorICAgICAqIGJlY2F1c2UgaXQncyBmcmVzaGVyIGluIGNhY2hlLgorICAgICAqLworICAgIGkgPSBQeV9TSVpFKHJldCkgLSBzaGlmdDsgIC8qICMgZGlnaXRzIGFmdGVyIHNoaWZ0ICovCisgICAgKHZvaWQpdl9pc3ViKHJldC0+b2JfZGlnaXQgKyBzaGlmdCwgaSwgdDItPm9iX2RpZ2l0LCBQeV9TSVpFKHQyKSk7CisgICAgUHlfREVDUkVGKHQyKTsKKworICAgICh2b2lkKXZfaXN1YihyZXQtPm9iX2RpZ2l0ICsgc2hpZnQsIGksIHQxLT5vYl9kaWdpdCwgUHlfU0laRSh0MSkpOworICAgIFB5X0RFQ1JFRih0MSk7CisKKyAgICAvKiA2LiB0MyA8LSAoYWgrYWwpKGJoK2JsKSwgYW5kIGFkZCBpbnRvIHJlc3VsdC4gKi8KKyAgICBpZiAoKHQxID0geF9hZGQoYWgsIGFsKSkgPT0gTlVMTCkgZ290byBmYWlsOworICAgIFB5X0RFQ1JFRihhaCk7CisgICAgUHlfREVDUkVGKGFsKTsKKyAgICBhaCA9IGFsID0gTlVMTDsKKworICAgIGlmIChhID09IGIpIHsKKyAgICAgICAgdDIgPSB0MTsKKyAgICAgICAgUHlfSU5DUkVGKHQyKTsKKyAgICB9CisgICAgZWxzZSBpZiAoKHQyID0geF9hZGQoYmgsIGJsKSkgPT0gTlVMTCkgeworICAgICAgICBQeV9ERUNSRUYodDEpOworICAgICAgICBnb3RvIGZhaWw7CisgICAgfQorICAgIFB5X0RFQ1JFRihiaCk7CisgICAgUHlfREVDUkVGKGJsKTsKKyAgICBiaCA9IGJsID0gTlVMTDsKKworICAgIHQzID0ga19tdWwodDEsIHQyKTsKKyAgICBQeV9ERUNSRUYodDEpOworICAgIFB5X0RFQ1JFRih0Mik7CisgICAgaWYgKHQzID09IE5VTEwpIGdvdG8gZmFpbDsKKyAgICBhc3NlcnQoUHlfU0laRSh0MykgPj0gMCk7CisKKyAgICAvKiBBZGQgdDMuICBJdCdzIG5vdCBvYnZpb3VzIHdoeSB3ZSBjYW4ndCBydW4gb3V0IG9mIHJvb20gaGVyZS4KKyAgICAgKiBTZWUgdGhlICgqKSBjb21tZW50IGFmdGVyIHRoaXMgZnVuY3Rpb24uCisgICAgICovCisgICAgKHZvaWQpdl9pYWRkKHJldC0+b2JfZGlnaXQgKyBzaGlmdCwgaSwgdDMtPm9iX2RpZ2l0LCBQeV9TSVpFKHQzKSk7CisgICAgUHlfREVDUkVGKHQzKTsKKworICAgIHJldHVybiBsb25nX25vcm1hbGl6ZShyZXQpOworCisgIGZhaWw6CisgICAgUHlfWERFQ1JFRihyZXQpOworICAgIFB5X1hERUNSRUYoYWgpOworICAgIFB5X1hERUNSRUYoYWwpOworICAgIFB5X1hERUNSRUYoYmgpOworICAgIFB5X1hERUNSRUYoYmwpOworICAgIHJldHVybiBOVUxMOworfQorCisvKiAoKikgV2h5IGFkZGluZyB0MyBjYW4ndCAicnVuIG91dCBvZiByb29tIiBhYm92ZS4KKworTGV0IGYoeCkgbWVhbiB0aGUgZmxvb3Igb2YgeCBhbmQgYyh4KSBtZWFuIHRoZSBjZWlsaW5nIG9mIHguICBTb21lIGZhY3RzCit0byBzdGFydCB3aXRoOgorCisxLiBGb3IgYW55IGludGVnZXIgaSwgaSA9IGMoaS8yKSArIGYoaS8yKS4gIEluIHBhcnRpY3VsYXIsCisgICBic2l6ZSA9IGMoYnNpemUvMikgKyBmKGJzaXplLzIpLgorMi4gc2hpZnQgPSBmKGJzaXplLzIpCiszLiBhc2l6ZSA8PSBic2l6ZQorNC4gU2luY2Ugd2UgY2FsbCBrX2xvcHNpZGVkX211bCBpZiBhc2l6ZSoyIDw9IGJzaXplLCBhc2l6ZSoyID4gYnNpemUgaW4gdGhpcworICAgcm91dGluZSwgc28gYXNpemUgPiBic2l6ZS8yID49IGYoYnNpemUvMikgaW4gdGhpcyByb3V0aW5lLgorCitXZSBhbGxvY2F0ZWQgYXNpemUgKyBic2l6ZSByZXN1bHQgZGlnaXRzLCBhbmQgYWRkIHQzIGludG8gdGhlbSBhdCBhbiBvZmZzZXQKK29mIHNoaWZ0LiAgVGhpcyBsZWF2ZXMgYXNpemUrYnNpemUtc2hpZnQgYWxsb2NhdGVkIGRpZ2l0IHBvc2l0aW9ucyBmb3IgdDMKK3RvIGZpdCBpbnRvLCA9IChieSAjMSBhbmQgIzIpIGFzaXplICsgZihic2l6ZS8yKSArIGMoYnNpemUvMikgLSBmKGJzaXplLzIpID0KK2FzaXplICsgYyhic2l6ZS8yKSBhdmFpbGFibGUgZGlnaXQgcG9zaXRpb25zLgorCitiaCBoYXMgYyhic2l6ZS8yKSBkaWdpdHMsIGFuZCBibCBhdCBtb3N0IGYoc2l6ZS8yKSBkaWdpdHMuICBTbyBiaCtobCBoYXMKK2F0IG1vc3QgYyhic2l6ZS8yKSBkaWdpdHMgKyAxIGJpdC4KKworSWYgYXNpemUgPT0gYnNpemUsIGFoIGhhcyBjKGJzaXplLzIpIGRpZ2l0cywgZWxzZSBhaCBoYXMgYXQgbW9zdCBmKGJzaXplLzIpCitkaWdpdHMsIGFuZCBhbCBoYXMgYXQgbW9zdCBmKGJzaXplLzIpIGRpZ2l0cyBpbiBhbnkgY2FzZS4gIFNvIGFoK2FsIGhhcyBhdAorbW9zdCAoYXNpemUgPT0gYnNpemUgPyBjKGJzaXplLzIpIDogZihic2l6ZS8yKSkgZGlnaXRzICsgMSBiaXQuCisKK1RoZSBwcm9kdWN0IChhaCthbCkqKGJoK2JsKSB0aGVyZWZvcmUgaGFzIGF0IG1vc3QKKworICAgIGMoYnNpemUvMikgKyAoYXNpemUgPT0gYnNpemUgPyBjKGJzaXplLzIpIDogZihic2l6ZS8yKSkgZGlnaXRzICsgMiBiaXRzCisKK2FuZCB3ZSBoYXZlIGFzaXplICsgYyhic2l6ZS8yKSBhdmFpbGFibGUgZGlnaXQgcG9zaXRpb25zLiAgV2UgbmVlZCB0byBzaG93Cit0aGlzIGlzIGFsd2F5cyBlbm91Z2guICBBbiBpbnN0YW5jZSBvZiBjKGJzaXplLzIpIGNhbmNlbHMgb3V0IGluIGJvdGgsIHNvCit0aGUgcXVlc3Rpb24gcmVkdWNlcyB0byB3aGV0aGVyIGFzaXplIGRpZ2l0cyBpcyBlbm91Z2ggdG8gaG9sZAorKGFzaXplID09IGJzaXplID8gYyhic2l6ZS8yKSA6IGYoYnNpemUvMikpIGRpZ2l0cyArIDIgYml0cy4gIElmIGFzaXplIDwgYnNpemUsCit0aGVuIHdlJ3JlIGFza2luZyB3aGV0aGVyIGFzaXplIGRpZ2l0cyA+PSBmKGJzaXplLzIpIGRpZ2l0cyArIDIgYml0cy4gIEJ5ICM0LAorYXNpemUgaXMgYXQgbGVhc3QgZihic2l6ZS8yKSsxIGRpZ2l0cywgc28gdGhpcyBpbiB0dXJuIHJlZHVjZXMgdG8gd2hldGhlciAxCitkaWdpdCBpcyBlbm91Z2ggdG8gaG9sZCAyIGJpdHMuICBUaGlzIGlzIHNvIHNpbmNlIFB5TG9uZ19TSElGVD0xNSA+PSAyLiAgSWYKK2FzaXplID09IGJzaXplLCB0aGVuIHdlJ3JlIGFza2luZyB3aGV0aGVyIGJzaXplIGRpZ2l0cyBpcyBlbm91Z2ggdG8gaG9sZAorYyhic2l6ZS8yKSBkaWdpdHMgKyAyIGJpdHMsIG9yIGVxdWl2YWxlbnRseSAoYnkgIzEpIHdoZXRoZXIgZihic2l6ZS8yKSBkaWdpdHMKK2lzIGVub3VnaCB0byBob2xkIDIgYml0cy4gIFRoaXMgaXMgc28gaWYgYnNpemUgPj0gMiwgd2hpY2ggaG9sZHMgYmVjYXVzZQorYnNpemUgPj0gS0FSQVRTVUJBX0NVVE9GRiA+PSAyLgorCitOb3RlIHRoYXQgc2luY2UgdGhlcmUncyBhbHdheXMgZW5vdWdoIHJvb20gZm9yIChhaCthbCkqKGJoK2JsKSwgYW5kIHRoYXQncworY2xlYXJseSA+PSBlYWNoIG9mIGFoKmJoIGFuZCBhbCpibCwgdGhlcmUncyBhbHdheXMgZW5vdWdoIHJvb20gdG8gc3VidHJhY3QKK2FoKmJoIGFuZCBhbCpibCB0b28uCisqLworCisvKiBiIGhhcyBhdCBsZWFzdCB0d2ljZSB0aGUgZGlnaXRzIG9mIGEsIGFuZCBhIGlzIGJpZyBlbm91Z2ggdGhhdCBLYXJhdHN1YmEKKyAqIHdvdWxkIHBheSBvZmYgKmlmKiB0aGUgaW5wdXRzIGhhZCBiYWxhbmNlZCBzaXplcy4gIFZpZXcgYiBhcyBhIHNlcXVlbmNlCisgKiBvZiBzbGljZXMsIGVhY2ggd2l0aCBhLT5vYl9zaXplIGRpZ2l0cywgYW5kIG11bHRpcGx5IHRoZSBzbGljZXMgYnkgYSwKKyAqIG9uZSBhdCBhIHRpbWUuICBUaGlzIGdpdmVzIGtfbXVsIGJhbGFuY2VkIGlucHV0cyB0byB3b3JrIHdpdGgsIGFuZCBpcworICogYWxzbyBjYWNoZS1mcmllbmRseSAod2UgY29tcHV0ZSBvbmUgZG91YmxlLXdpZHRoIHNsaWNlIG9mIHRoZSByZXN1bHQKKyAqIGF0IGEgdGltZSwgdGhlbiBtb3ZlIG9uLCBuZXZlciBiYWNrdHJhY2tpbmcgZXhjZXB0IGZvciB0aGUgaGVscGZ1bAorICogc2luZ2xlLXdpZHRoIHNsaWNlIG92ZXJsYXAgYmV0d2VlbiBzdWNjZXNzaXZlIHBhcnRpYWwgc3VtcykuCisgKi8KK3N0YXRpYyBQeUxvbmdPYmplY3QgKgora19sb3BzaWRlZF9tdWwoUHlMb25nT2JqZWN0ICphLCBQeUxvbmdPYmplY3QgKmIpCit7CisgICAgY29uc3QgUHlfc3NpemVfdCBhc2l6ZSA9IEFCUyhQeV9TSVpFKGEpKTsKKyAgICBQeV9zc2l6ZV90IGJzaXplID0gQUJTKFB5X1NJWkUoYikpOworICAgIFB5X3NzaXplX3QgbmJkb25lOyAgICAgICAgICAvKiAjIG9mIGIgZGlnaXRzIGFscmVhZHkgbXVsdGlwbGllZCAqLworICAgIFB5TG9uZ09iamVjdCAqcmV0OworICAgIFB5TG9uZ09iamVjdCAqYnNsaWNlID0gTlVMTDsKKworICAgIGFzc2VydChhc2l6ZSA+IEtBUkFUU1VCQV9DVVRPRkYpOworICAgIGFzc2VydCgyICogYXNpemUgPD0gYnNpemUpOworCisgICAgLyogQWxsb2NhdGUgcmVzdWx0IHNwYWNlLCBhbmQgemVybyBpdCBvdXQuICovCisgICAgcmV0ID0gX1B5TG9uZ19OZXcoYXNpemUgKyBic2l6ZSk7CisgICAgaWYgKHJldCA9PSBOVUxMKQorICAgICAgICByZXR1cm4gTlVMTDsKKyAgICBtZW1zZXQocmV0LT5vYl9kaWdpdCwgMCwgUHlfU0laRShyZXQpICogc2l6ZW9mKGRpZ2l0KSk7CisKKyAgICAvKiBTdWNjZXNzaXZlIHNsaWNlcyBvZiBiIGFyZSBjb3BpZWQgaW50byBic2xpY2UuICovCisgICAgYnNsaWNlID0gX1B5TG9uZ19OZXcoYXNpemUpOworICAgIGlmIChic2xpY2UgPT0gTlVMTCkKKyAgICAgICAgZ290byBmYWlsOworCisgICAgbmJkb25lID0gMDsKKyAgICB3aGlsZSAoYnNpemUgPiAwKSB7CisgICAgICAgIFB5TG9uZ09iamVjdCAqcHJvZHVjdDsKKyAgICAgICAgY29uc3QgUHlfc3NpemVfdCBuYnRvdXNlID0gTUlOKGJzaXplLCBhc2l6ZSk7CisKKyAgICAgICAgLyogTXVsdGlwbHkgdGhlIG5leHQgc2xpY2Ugb2YgYiBieSBhLiAqLworICAgICAgICBtZW1jcHkoYnNsaWNlLT5vYl9kaWdpdCwgYi0+b2JfZGlnaXQgKyBuYmRvbmUsCisgICAgICAgICAgICAgICBuYnRvdXNlICogc2l6ZW9mKGRpZ2l0KSk7CisgICAgICAgIFB5X1NJWkUoYnNsaWNlKSA9IG5idG91c2U7CisgICAgICAgIHByb2R1Y3QgPSBrX211bChhLCBic2xpY2UpOworICAgICAgICBpZiAocHJvZHVjdCA9PSBOVUxMKQorICAgICAgICAgICAgZ290byBmYWlsOworCisgICAgICAgIC8qIEFkZCBpbnRvIHJlc3VsdC4gKi8KKyAgICAgICAgKHZvaWQpdl9pYWRkKHJldC0+b2JfZGlnaXQgKyBuYmRvbmUsIFB5X1NJWkUocmV0KSAtIG5iZG9uZSwKKyAgICAgICAgICAgICAgICAgICAgIHByb2R1Y3QtPm9iX2RpZ2l0LCBQeV9TSVpFKHByb2R1Y3QpKTsKKyAgICAgICAgUHlfREVDUkVGKHByb2R1Y3QpOworCisgICAgICAgIGJzaXplIC09IG5idG91c2U7CisgICAgICAgIG5iZG9uZSArPSBuYnRvdXNlOworICAgIH0KKworICAgIFB5X0RFQ1JFRihic2xpY2UpOworICAgIHJldHVybiBsb25nX25vcm1hbGl6ZShyZXQpOworCisgIGZhaWw6CisgICAgUHlfREVDUkVGKHJldCk7CisgICAgUHlfWERFQ1JFRihic2xpY2UpOworICAgIHJldHVybiBOVUxMOworfQorCitzdGF0aWMgUHlPYmplY3QgKgorbG9uZ19tdWwoUHlMb25nT2JqZWN0ICp2LCBQeUxvbmdPYmplY3QgKncpCit7CisgICAgUHlMb25nT2JqZWN0ICphLCAqYiwgKno7CisKKyAgICBpZiAoIWNvbnZlcnRfYmlub3AoKFB5T2JqZWN0ICopdiwgKFB5T2JqZWN0ICopdywgJmEsICZiKSkgeworICAgICAgICBQeV9JTkNSRUYoUHlfTm90SW1wbGVtZW50ZWQpOworICAgICAgICByZXR1cm4gUHlfTm90SW1wbGVtZW50ZWQ7CisgICAgfQorCisgICAgeiA9IGtfbXVsKGEsIGIpOworICAgIC8qIE5lZ2F0ZSBpZiBleGFjdGx5IG9uZSBvZiB0aGUgaW5wdXRzIGlzIG5lZ2F0aXZlLiAqLworICAgIGlmICgoKGEtPm9iX3NpemUgXiBiLT5vYl9zaXplKSA8IDApICYmIHopCisgICAgICAgIHotPm9iX3NpemUgPSAtKHotPm9iX3NpemUpOworICAgIFB5X0RFQ1JFRihhKTsKKyAgICBQeV9ERUNSRUYoYik7CisgICAgcmV0dXJuIChQeU9iamVjdCAqKXo7Cit9CisKKy8qIFRoZSAvIGFuZCAlIG9wZXJhdG9ycyBhcmUgbm93IGRlZmluZWQgaW4gdGVybXMgb2YgZGl2bW9kKCkuCisgICBUaGUgZXhwcmVzc2lvbiBhIG1vZCBiIGhhcyB0aGUgdmFsdWUgYSAtIGIqZmxvb3IoYS9iKS4KKyAgIFRoZSBsb25nX2RpdnJlbSBmdW5jdGlvbiBnaXZlcyB0aGUgcmVtYWluZGVyIGFmdGVyIGRpdmlzaW9uIG9mCisgICB8YXwgYnkgfGJ8LCB3aXRoIHRoZSBzaWduIG9mIGEuICBUaGlzIGlzIGFsc28gZXhwcmVzc2VkCisgICBhcyBhIC0gYip0cnVuYyhhL2IpLCBpZiB0cnVuYyB0cnVuY2F0ZXMgdG93YXJkcyB6ZXJvLgorICAgU29tZSBleGFtcGxlczoKKyAgICAgYSAgICAgICAgICAgYiAgICAgIGEgcmVtIGIgICAgICAgICBhIG1vZCBiCisgICAgIDEzICAgICAgICAgIDEwICAgICAgMyAgICAgICAgICAgICAgIDMKKyAgICAtMTMgICAgICAgICAgMTAgICAgIC0zICAgICAgICAgICAgICAgNworICAgICAxMyAgICAgICAgIC0xMCAgICAgIDMgICAgICAgICAgICAgIC03CisgICAgLTEzICAgICAgICAgLTEwICAgICAtMyAgICAgICAgICAgICAgLTMKKyAgIFNvLCB0byBnZXQgZnJvbSByZW0gdG8gbW9kLCB3ZSBoYXZlIHRvIGFkZCBiIGlmIGEgYW5kIGIKKyAgIGhhdmUgZGlmZmVyZW50IHNpZ25zLiAgV2UgdGhlbiBzdWJ0cmFjdCBvbmUgZnJvbSB0aGUgJ2RpdicKKyAgIHBhcnQgb2YgdGhlIG91dGNvbWUgdG8ga2VlcCB0aGUgaW52YXJpYW50IGludGFjdC4gKi8KKworLyogQ29tcHV0ZQorICogICAgICpwZGl2LCAqcG1vZCA9IGRpdm1vZCh2LCB3KQorICogTlVMTCBjYW4gYmUgcGFzc2VkIGZvciBwZGl2IG9yIHBtb2QsIGluIHdoaWNoIGNhc2UgdGhhdCBwYXJ0IG9mCisgKiB0aGUgcmVzdWx0IGlzIHNpbXBseSB0aHJvd24gYXdheS4gIFRoZSBjYWxsZXIgb3ducyBhIHJlZmVyZW5jZSB0bworICogZWFjaCBvZiB0aGVzZSBpdCByZXF1ZXN0cyAoZG9lcyBub3QgcGFzcyBOVUxMIGZvcikuCisgKi8KK3N0YXRpYyBpbnQKK2xfZGl2bW9kKFB5TG9uZ09iamVjdCAqdiwgUHlMb25nT2JqZWN0ICp3LAorICAgICAgICAgUHlMb25nT2JqZWN0ICoqcGRpdiwgUHlMb25nT2JqZWN0ICoqcG1vZCkKK3sKKyAgICBQeUxvbmdPYmplY3QgKmRpdiwgKm1vZDsKKworICAgIGlmIChsb25nX2RpdnJlbSh2LCB3LCAmZGl2LCAmbW9kKSA8IDApCisgICAgICAgIHJldHVybiAtMTsKKyAgICBpZiAoKFB5X1NJWkUobW9kKSA8IDAgJiYgUHlfU0laRSh3KSA+IDApIHx8CisgICAgICAgIChQeV9TSVpFKG1vZCkgPiAwICYmIFB5X1NJWkUodykgPCAwKSkgeworICAgICAgICBQeUxvbmdPYmplY3QgKnRlbXA7CisgICAgICAgIFB5TG9uZ09iamVjdCAqb25lOworICAgICAgICB0ZW1wID0gKFB5TG9uZ09iamVjdCAqKSBsb25nX2FkZChtb2QsIHcpOworICAgICAgICBQeV9ERUNSRUYobW9kKTsKKyAgICAgICAgbW9kID0gdGVtcDsKKyAgICAgICAgaWYgKG1vZCA9PSBOVUxMKSB7CisgICAgICAgICAgICBQeV9ERUNSRUYoZGl2KTsKKyAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgfQorICAgICAgICBvbmUgPSAoUHlMb25nT2JqZWN0ICopIFB5TG9uZ19Gcm9tTG9uZygxTCk7CisgICAgICAgIGlmIChvbmUgPT0gTlVMTCB8fAorICAgICAgICAgICAgKHRlbXAgPSAoUHlMb25nT2JqZWN0ICopIGxvbmdfc3ViKGRpdiwgb25lKSkgPT0gTlVMTCkgeworICAgICAgICAgICAgUHlfREVDUkVGKG1vZCk7CisgICAgICAgICAgICBQeV9ERUNSRUYoZGl2KTsKKyAgICAgICAgICAgIFB5X1hERUNSRUYob25lKTsKKyAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgfQorICAgICAgICBQeV9ERUNSRUYob25lKTsKKyAgICAgICAgUHlfREVDUkVGKGRpdik7CisgICAgICAgIGRpdiA9IHRlbXA7CisgICAgfQorICAgIGlmIChwZGl2ICE9IE5VTEwpCisgICAgICAgICpwZGl2ID0gZGl2OworICAgIGVsc2UKKyAgICAgICAgUHlfREVDUkVGKGRpdik7CisKKyAgICBpZiAocG1vZCAhPSBOVUxMKQorICAgICAgICAqcG1vZCA9IG1vZDsKKyAgICBlbHNlCisgICAgICAgIFB5X0RFQ1JFRihtb2QpOworCisgICAgcmV0dXJuIDA7Cit9CisKK3N0YXRpYyBQeU9iamVjdCAqCitsb25nX2RpdihQeU9iamVjdCAqdiwgUHlPYmplY3QgKncpCit7CisgICAgUHlMb25nT2JqZWN0ICphLCAqYiwgKmRpdjsKKworICAgIENPTlZFUlRfQklOT1AodiwgdywgJmEsICZiKTsKKyAgICBpZiAobF9kaXZtb2QoYSwgYiwgJmRpdiwgTlVMTCkgPCAwKQorICAgICAgICBkaXYgPSBOVUxMOworICAgIFB5X0RFQ1JFRihhKTsKKyAgICBQeV9ERUNSRUYoYik7CisgICAgcmV0dXJuIChQeU9iamVjdCAqKWRpdjsKK30KKworc3RhdGljIFB5T2JqZWN0ICoKK2xvbmdfY2xhc3NpY19kaXYoUHlPYmplY3QgKnYsIFB5T2JqZWN0ICp3KQoreworICAgIFB5TG9uZ09iamVjdCAqYSwgKmIsICpkaXY7CisKKyAgICBDT05WRVJUX0JJTk9QKHYsIHcsICZhLCAmYik7CisgICAgaWYgKFB5X0RpdmlzaW9uV2FybmluZ0ZsYWcgJiYKKyAgICAgICAgUHlFcnJfV2FybihQeUV4Y19EZXByZWNhdGlvbldhcm5pbmcsICJjbGFzc2ljIGxvbmcgZGl2aXNpb24iKSA8IDApCisgICAgICAgIGRpdiA9IE5VTEw7CisgICAgZWxzZSBpZiAobF9kaXZtb2QoYSwgYiwgJmRpdiwgTlVMTCkgPCAwKQorICAgICAgICBkaXYgPSBOVUxMOworICAgIFB5X0RFQ1JFRihhKTsKKyAgICBQeV9ERUNSRUYoYik7CisgICAgcmV0dXJuIChQeU9iamVjdCAqKWRpdjsKK30KKworLyogUHlMb25nL1B5TG9uZyAtPiBmbG9hdCwgd2l0aCBjb3JyZWN0bHkgcm91bmRlZCByZXN1bHQuICovCisKKyNkZWZpbmUgTUFOVF9ESUdfRElHSVRTIChEQkxfTUFOVF9ESUcgLyBQeUxvbmdfU0hJRlQpCisjZGVmaW5lIE1BTlRfRElHX0JJVFMgKERCTF9NQU5UX0RJRyAlIFB5TG9uZ19TSElGVCkKKworc3RhdGljIFB5T2JqZWN0ICoKK2xvbmdfdHJ1ZV9kaXZpZGUoUHlPYmplY3QgKnYsIFB5T2JqZWN0ICp3KQoreworICAgIFB5TG9uZ09iamVjdCAqYSwgKmIsICp4OworICAgIFB5X3NzaXplX3QgYV9zaXplLCBiX3NpemUsIHNoaWZ0LCBleHRyYV9iaXRzLCBkaWZmLCB4X3NpemUsIHhfYml0czsKKyAgICBkaWdpdCBtYXNrLCBsb3c7CisgICAgaW50IGluZXhhY3QsIG5lZ2F0ZSwgYV9pc19zbWFsbCwgYl9pc19zbWFsbDsKKyAgICBkb3VibGUgZHgsIHJlc3VsdDsKKworICAgIENPTlZFUlRfQklOT1AodiwgdywgJmEsICZiKTsKKworICAgIC8qCisgICAgICAgTWV0aG9kIGluIGEgbnV0c2hlbGw6CisKKyAgICAgICAgIDAuIHJlZHVjZSB0byBjYXNlIGEsIGIgPiAwOyBmaWx0ZXIgb3V0IG9idmlvdXMgdW5kZXJmbG93L292ZXJmbG93CisgICAgICAgICAxLiBjaG9vc2UgYSBzdWl0YWJsZSBpbnRlZ2VyICdzaGlmdCcKKyAgICAgICAgIDIuIHVzZSBpbnRlZ2VyIGFyaXRobWV0aWMgdG8gY29tcHV0ZSB4ID0gZmxvb3IoMioqLXNoaWZ0KmEvYikKKyAgICAgICAgIDMuIGFkanVzdCB4IGZvciBjb3JyZWN0IHJvdW5kaW5nCisgICAgICAgICA0LiBjb252ZXJ0IHggdG8gYSBkb3VibGUgZHggd2l0aCB0aGUgc2FtZSB2YWx1ZQorICAgICAgICAgNS4gcmV0dXJuIGxkZXhwKGR4LCBzaGlmdCkuCisKKyAgICAgICBJbiBtb3JlIGRldGFpbDoKKworICAgICAgIDAuIEZvciBhbnkgYSwgYS8wIHJhaXNlcyBaZXJvRGl2aXNpb25FcnJvcjsgZm9yIG5vbnplcm8gYiwgMC9iCisgICAgICAgcmV0dXJucyBlaXRoZXIgMC4wIG9yIC0wLjAsIGRlcGVuZGluZyBvbiB0aGUgc2lnbiBvZiBiLiAgRm9yIGEgYW5kCisgICAgICAgYiBib3RoIG5vbnplcm8sIGlnbm9yZSBzaWducyBvZiBhIGFuZCBiLCBhbmQgYWRkIHRoZSBzaWduIGJhY2sgaW4KKyAgICAgICBhdCB0aGUgZW5kLiAgTm93IHdyaXRlIGFfYml0cyBhbmQgYl9iaXRzIGZvciB0aGUgYml0IGxlbmd0aHMgb2YgYQorICAgICAgIGFuZCBiIHJlc3BlY3RpdmVseSAodGhhdCBpcywgYV9iaXRzID0gMSArIGZsb29yKGxvZ18yKGEpKTsgbGlrZXdpc2UKKyAgICAgICBmb3IgYikuICBUaGVuCisKKyAgICAgICAgICAyKiooYV9iaXRzIC0gYl9iaXRzIC0gMSkgPCBhL2IgPCAyKiooYV9iaXRzIC0gYl9iaXRzICsgMSkuCisKKyAgICAgICBTbyBpZiBhX2JpdHMgLSBiX2JpdHMgPiBEQkxfTUFYX0VYUCB0aGVuIGEvYiA+IDIqKkRCTF9NQVhfRVhQIGFuZAorICAgICAgIHNvIG92ZXJmbG93cy4gIFNpbWlsYXJseSwgaWYgYV9iaXRzIC0gYl9iaXRzIDwgREJMX01JTl9FWFAgLQorICAgICAgIERCTF9NQU5UX0RJRyAtIDEgdGhlbiBhL2IgdW5kZXJmbG93cyB0byAwLiAgV2l0aCB0aGVzZSBjYXNlcyBvdXQgb2YKKyAgICAgICB0aGUgd2F5LCB3ZSBjYW4gYXNzdW1lIHRoYXQKKworICAgICAgICAgIERCTF9NSU5fRVhQIC0gREJMX01BTlRfRElHIC0gMSA8PSBhX2JpdHMgLSBiX2JpdHMgPD0gREJMX01BWF9FWFAuCisKKyAgICAgICAxLiBUaGUgaW50ZWdlciAnc2hpZnQnIGlzIGNob3NlbiBzbyB0aGF0IHggaGFzIHRoZSByaWdodCBudW1iZXIgb2YKKyAgICAgICBiaXRzIGZvciBhIGRvdWJsZSwgcGx1cyB0d28gb3IgdGhyZWUgZXh0cmEgYml0cyB0aGF0IHdpbGwgYmUgdXNlZAorICAgICAgIGluIHRoZSByb3VuZGluZyBkZWNpc2lvbnMuICBXcml0aW5nIGFfYml0cyBhbmQgYl9iaXRzIGZvciB0aGUKKyAgICAgICBudW1iZXIgb2Ygc2lnbmlmaWNhbnQgYml0cyBpbiBhIGFuZCBiIHJlc3BlY3RpdmVseSwgYQorICAgICAgIHN0cmFpZ2h0Zm9yd2FyZCBmb3JtdWxhIGZvciBzaGlmdCBpczoKKworICAgICAgICAgIHNoaWZ0ID0gYV9iaXRzIC0gYl9iaXRzIC0gREJMX01BTlRfRElHIC0gMgorCisgICAgICAgVGhpcyBpcyBmaW5lIGluIHRoZSB1c3VhbCBjYXNlLCBidXQgaWYgYS9iIGlzIHNtYWxsZXIgdGhhbiB0aGUKKyAgICAgICBzbWFsbGVzdCBub3JtYWwgZmxvYXQgdGhlbiBpdCBjYW4gbGVhZCB0byBkb3VibGUgcm91bmRpbmcgb24gYW4KKyAgICAgICBJRUVFIDc1NCBwbGF0Zm9ybSwgZ2l2aW5nIGluY29ycmVjdGx5IHJvdW5kZWQgcmVzdWx0cy4gIFNvIHdlCisgICAgICAgYWRqdXN0IHRoZSBmb3JtdWxhIHNsaWdodGx5LiAgVGhlIGFjdHVhbCBmb3JtdWxhIHVzZWQgaXM6CisKKyAgICAgICAgICAgc2hpZnQgPSBNQVgoYV9iaXRzIC0gYl9iaXRzLCBEQkxfTUlOX0VYUCkgLSBEQkxfTUFOVF9ESUcgLSAyCisKKyAgICAgICAyLiBUaGUgcXVhbnRpdHkgeCBpcyBjb21wdXRlZCBieSBmaXJzdCBzaGlmdGluZyBhIChsZWZ0IC1zaGlmdCBiaXRzCisgICAgICAgaWYgc2hpZnQgPD0gMCwgcmlnaHQgc2hpZnQgYml0cyBpZiBzaGlmdCA+IDApIGFuZCB0aGVuIGRpdmlkaW5nIGJ5CisgICAgICAgYi4gIEZvciBib3RoIHRoZSBzaGlmdCBhbmQgdGhlIGRpdmlzaW9uLCB3ZSBrZWVwIHRyYWNrIG9mIHdoZXRoZXIKKyAgICAgICB0aGUgcmVzdWx0IGlzIGluZXhhY3QsIGluIGEgZmxhZyAnaW5leGFjdCc7IHRoaXMgaW5mb3JtYXRpb24gaXMKKyAgICAgICBuZWVkZWQgYXQgdGhlIHJvdW5kaW5nIHN0YWdlLgorCisgICAgICAgV2l0aCB0aGUgY2hvaWNlIG9mIHNoaWZ0IGFib3ZlLCB0b2dldGhlciB3aXRoIG91ciBhc3N1bXB0aW9uIHRoYXQKKyAgICAgICBhX2JpdHMgLSBiX2JpdHMgPj0gREJMX01JTl9FWFAgLSBEQkxfTUFOVF9ESUcgLSAxLCBpdCBmb2xsb3dzCisgICAgICAgdGhhdCB4ID49IDEuCisKKyAgICAgICAzLiBOb3cgeCAqIDIqKnNoaWZ0IDw9IGEvYiA8ICh4KzEpICogMioqc2hpZnQuICBXZSB3YW50IHRvIHJlcGxhY2UKKyAgICAgICB0aGlzIHdpdGggYW4gZXhhY3RseSByZXByZXNlbnRhYmxlIGZsb2F0IG9mIHRoZSBmb3JtCisKKyAgICAgICAgICByb3VuZCh4LzIqKmV4dHJhX2JpdHMpICogMioqKGV4dHJhX2JpdHMrc2hpZnQpLgorCisgICAgICAgRm9yIGZsb2F0IHJlcHJlc2VudGFiaWxpdHksIHdlIG5lZWQgeC8yKipleHRyYV9iaXRzIDwKKyAgICAgICAyKipEQkxfTUFOVF9ESUcgYW5kIGV4dHJhX2JpdHMgKyBzaGlmdCA+PSBEQkxfTUlOX0VYUCAtCisgICAgICAgREJMX01BTlRfRElHLiAgVGhpcyB0cmFuc2xhdGVzIHRvIHRoZSBjb25kaXRpb246CisKKyAgICAgICAgICBleHRyYV9iaXRzID49IE1BWCh4X2JpdHMsIERCTF9NSU5fRVhQIC0gc2hpZnQpIC0gREJMX01BTlRfRElHCisKKyAgICAgICBUbyByb3VuZCwgd2UganVzdCBtb2RpZnkgdGhlIGJvdHRvbSBkaWdpdCBvZiB4IGluLXBsYWNlOyB0aGlzIGNhbgorICAgICAgIGVuZCB1cCBnaXZpbmcgYSBkaWdpdCB3aXRoIHZhbHVlID4gUHlMT05HX01BU0ssIGJ1dCB0aGF0J3Mgbm90IGEKKyAgICAgICBwcm9ibGVtIHNpbmNlIGRpZ2l0cyBjYW4gaG9sZCB2YWx1ZXMgdXAgdG8gMipQeUxPTkdfTUFTSysxLgorCisgICAgICAgV2l0aCB0aGUgb3JpZ2luYWwgY2hvaWNlcyBmb3Igc2hpZnQgYWJvdmUsIGV4dHJhX2JpdHMgd2lsbCBhbHdheXMKKyAgICAgICBiZSAyIG9yIDMuICBUaGVuIHJvdW5kaW5nIHVuZGVyIHRoZSByb3VuZC1oYWxmLXRvLWV2ZW4gcnVsZSwgd2UKKyAgICAgICByb3VuZCB1cCBpZmYgdGhlIG1vc3Qgc2lnbmlmaWNhbnQgb2YgdGhlIGV4dHJhIGJpdHMgaXMgMSwgYW5kCisgICAgICAgZWl0aGVyOiAoYSkgdGhlIGNvbXB1dGF0aW9uIG9mIHggaW4gc3RlcCAyIGhhZCBhbiBpbmV4YWN0IHJlc3VsdCwKKyAgICAgICBvciAoYikgYXQgbGVhc3Qgb25lIG90aGVyIG9mIHRoZSBleHRyYSBiaXRzIGlzIDEsIG9yIChjKSB0aGUgbGVhc3QKKyAgICAgICBzaWduaWZpY2FudCBiaXQgb2YgeCAoYWJvdmUgdGhvc2UgdG8gYmUgcm91bmRlZCkgaXMgMS4KKworICAgICAgIDQuIENvbnZlcnNpb24gdG8gYSBkb3VibGUgaXMgc3RyYWlnaHRmb3J3YXJkOyBhbGwgZmxvYXRpbmctcG9pbnQKKyAgICAgICBvcGVyYXRpb25zIGludm9sdmVkIGluIHRoZSBjb252ZXJzaW9uIGFyZSBleGFjdCwgc28gdGhlcmUncyBubworICAgICAgIGRhbmdlciBvZiByb3VuZGluZyBlcnJvcnMuCisKKyAgICAgICA1LiBVc2UgbGRleHAoeCwgc2hpZnQpIHRvIGNvbXB1dGUgeCoyKipzaGlmdCwgdGhlIGZpbmFsIHJlc3VsdC4KKyAgICAgICBUaGUgcmVzdWx0IHdpbGwgYWx3YXlzIGJlIGV4YWN0bHkgcmVwcmVzZW50YWJsZSBhcyBhIGRvdWJsZSwgZXhjZXB0CisgICAgICAgaW4gdGhlIGNhc2UgdGhhdCBpdCBvdmVyZmxvd3MuICBUbyBhdm9pZCBkZXBlbmRlbmNlIG9uIHRoZSBleGFjdAorICAgICAgIGJlaGF2aW91ciBvZiBsZGV4cCBvbiBvdmVyZmxvdywgd2UgY2hlY2sgZm9yIG92ZXJmbG93IGJlZm9yZQorICAgICAgIGFwcGx5aW5nIGxkZXhwLiAgVGhlIHJlc3VsdCBvZiBsZGV4cCBpcyBhZGp1c3RlZCBmb3Igc2lnbiBiZWZvcmUKKyAgICAgICByZXR1cm5pbmcuCisgICAgKi8KKworICAgIC8qIFJlZHVjZSB0byBjYXNlIHdoZXJlIGEgYW5kIGIgYXJlIGJvdGggcG9zaXRpdmUuICovCisgICAgYV9zaXplID0gQUJTKFB5X1NJWkUoYSkpOworICAgIGJfc2l6ZSA9IEFCUyhQeV9TSVpFKGIpKTsKKyAgICBuZWdhdGUgPSAoUHlfU0laRShhKSA8IDApIF4gKFB5X1NJWkUoYikgPCAwKTsKKyAgICBpZiAoYl9zaXplID09IDApIHsKKyAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1plcm9EaXZpc2lvbkVycm9yLAorICAgICAgICAgICAgICAgICAgICAgICAgImRpdmlzaW9uIGJ5IHplcm8iKTsKKyAgICAgICAgZ290byBlcnJvcjsKKyAgICB9CisgICAgaWYgKGFfc2l6ZSA9PSAwKQorICAgICAgICBnb3RvIHVuZGVyZmxvd19vcl96ZXJvOworCisgICAgLyogRmFzdCBwYXRoIGZvciBhIGFuZCBiIHNtYWxsIChleGFjdGx5IHJlcHJlc2VudGFibGUgaW4gYSBkb3VibGUpLgorICAgICAgIFJlbGllcyBvbiBmbG9hdGluZy1wb2ludCBkaXZpc2lvbiBiZWluZyBjb3JyZWN0bHkgcm91bmRlZDsgcmVzdWx0cworICAgICAgIG1heSBiZSBzdWJqZWN0IHRvIGRvdWJsZSByb3VuZGluZyBvbiB4ODYgbWFjaGluZXMgdGhhdCBvcGVyYXRlIHdpdGgKKyAgICAgICB0aGUgeDg3IEZQVSBzZXQgdG8gNjQtYml0IHByZWNpc2lvbi4gKi8KKyAgICBhX2lzX3NtYWxsID0gYV9zaXplIDw9IE1BTlRfRElHX0RJR0lUUyB8fAorICAgICAgICAoYV9zaXplID09IE1BTlRfRElHX0RJR0lUUysxICYmCisgICAgICAgICBhLT5vYl9kaWdpdFtNQU5UX0RJR19ESUdJVFNdID4+IE1BTlRfRElHX0JJVFMgPT0gMCk7CisgICAgYl9pc19zbWFsbCA9IGJfc2l6ZSA8PSBNQU5UX0RJR19ESUdJVFMgfHwKKyAgICAgICAgKGJfc2l6ZSA9PSBNQU5UX0RJR19ESUdJVFMrMSAmJgorICAgICAgICAgYi0+b2JfZGlnaXRbTUFOVF9ESUdfRElHSVRTXSA+PiBNQU5UX0RJR19CSVRTID09IDApOworICAgIGlmIChhX2lzX3NtYWxsICYmIGJfaXNfc21hbGwpIHsKKyAgICAgICAgZG91YmxlIGRhLCBkYjsKKyAgICAgICAgZGEgPSBhLT5vYl9kaWdpdFstLWFfc2l6ZV07CisgICAgICAgIHdoaWxlIChhX3NpemUgPiAwKQorICAgICAgICAgICAgZGEgPSBkYSAqIFB5TG9uZ19CQVNFICsgYS0+b2JfZGlnaXRbLS1hX3NpemVdOworICAgICAgICBkYiA9IGItPm9iX2RpZ2l0Wy0tYl9zaXplXTsKKyAgICAgICAgd2hpbGUgKGJfc2l6ZSA+IDApCisgICAgICAgICAgICBkYiA9IGRiICogUHlMb25nX0JBU0UgKyBiLT5vYl9kaWdpdFstLWJfc2l6ZV07CisgICAgICAgIHJlc3VsdCA9IGRhIC8gZGI7CisgICAgICAgIGdvdG8gc3VjY2VzczsKKyAgICB9CisKKyAgICAvKiBDYXRjaCBvYnZpb3VzIGNhc2VzIG9mIHVuZGVyZmxvdyBhbmQgb3ZlcmZsb3cgKi8KKyAgICBkaWZmID0gYV9zaXplIC0gYl9zaXplOworICAgIGlmIChkaWZmID4gUFlfU1NJWkVfVF9NQVgvUHlMb25nX1NISUZUIC0gMSkKKyAgICAgICAgLyogRXh0cmVtZSBvdmVyZmxvdyAqLworICAgICAgICBnb3RvIG92ZXJmbG93OworICAgIGVsc2UgaWYgKGRpZmYgPCAxIC0gUFlfU1NJWkVfVF9NQVgvUHlMb25nX1NISUZUKQorICAgICAgICAvKiBFeHRyZW1lIHVuZGVyZmxvdyAqLworICAgICAgICBnb3RvIHVuZGVyZmxvd19vcl96ZXJvOworICAgIC8qIE5leHQgbGluZSBpcyBub3cgc2FmZSBmcm9tIG92ZXJmbG93aW5nIGEgUHlfc3NpemVfdCAqLworICAgIGRpZmYgPSBkaWZmICogUHlMb25nX1NISUZUICsgYml0c19pbl9kaWdpdChhLT5vYl9kaWdpdFthX3NpemUgLSAxXSkgLQorICAgICAgICBiaXRzX2luX2RpZ2l0KGItPm9iX2RpZ2l0W2Jfc2l6ZSAtIDFdKTsKKyAgICAvKiBOb3cgZGlmZiA9IGFfYml0cyAtIGJfYml0cy4gKi8KKyAgICBpZiAoZGlmZiA+IERCTF9NQVhfRVhQKQorICAgICAgICBnb3RvIG92ZXJmbG93OworICAgIGVsc2UgaWYgKGRpZmYgPCBEQkxfTUlOX0VYUCAtIERCTF9NQU5UX0RJRyAtIDEpCisgICAgICAgIGdvdG8gdW5kZXJmbG93X29yX3plcm87CisKKyAgICAvKiBDaG9vc2UgdmFsdWUgZm9yIHNoaWZ0OyBzZWUgY29tbWVudHMgZm9yIHN0ZXAgMSBhYm92ZS4gKi8KKyAgICBzaGlmdCA9IE1BWChkaWZmLCBEQkxfTUlOX0VYUCkgLSBEQkxfTUFOVF9ESUcgLSAyOworCisgICAgaW5leGFjdCA9IDA7CisKKyAgICAvKiB4ID0gYWJzKGEgKiAyKiotc2hpZnQpICovCisgICAgaWYgKHNoaWZ0IDw9IDApIHsKKyAgICAgICAgUHlfc3NpemVfdCBpLCBzaGlmdF9kaWdpdHMgPSAtc2hpZnQgLyBQeUxvbmdfU0hJRlQ7CisgICAgICAgIGRpZ2l0IHJlbTsKKyAgICAgICAgLyogeCA9IGEgPDwgLXNoaWZ0ICovCisgICAgICAgIGlmIChhX3NpemUgPj0gUFlfU1NJWkVfVF9NQVggLSAxIC0gc2hpZnRfZGlnaXRzKSB7CisgICAgICAgICAgICAvKiBJbiBwcmFjdGljZSwgaXQncyBwcm9iYWJseSBpbXBvc3NpYmxlIHRvIGVuZCB1cAorICAgICAgICAgICAgICAgaGVyZS4gIEJvdGggYSBhbmQgYiB3b3VsZCBoYXZlIHRvIGJlIGVub3Jtb3VzLAorICAgICAgICAgICAgICAgdXNpbmcgY2xvc2UgdG8gU0laRV9UX01BWCBieXRlcyBvZiBtZW1vcnkgZWFjaC4gKi8KKyAgICAgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19PdmVyZmxvd0Vycm9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICJpbnRlcm1lZGlhdGUgb3ZlcmZsb3cgZHVyaW5nIGRpdmlzaW9uIik7CisgICAgICAgICAgICBnb3RvIGVycm9yOworICAgICAgICB9CisgICAgICAgIHggPSBfUHlMb25nX05ldyhhX3NpemUgKyBzaGlmdF9kaWdpdHMgKyAxKTsKKyAgICAgICAgaWYgKHggPT0gTlVMTCkKKyAgICAgICAgICAgIGdvdG8gZXJyb3I7CisgICAgICAgIGZvciAoaSA9IDA7IGkgPCBzaGlmdF9kaWdpdHM7IGkrKykKKyAgICAgICAgICAgIHgtPm9iX2RpZ2l0W2ldID0gMDsKKyAgICAgICAgcmVtID0gdl9sc2hpZnQoeC0+b2JfZGlnaXQgKyBzaGlmdF9kaWdpdHMsIGEtPm9iX2RpZ2l0LAorICAgICAgICAgICAgICAgICAgICAgICBhX3NpemUsIC1zaGlmdCAlIFB5TG9uZ19TSElGVCk7CisgICAgICAgIHgtPm9iX2RpZ2l0W2Ffc2l6ZSArIHNoaWZ0X2RpZ2l0c10gPSByZW07CisgICAgfQorICAgIGVsc2UgeworICAgICAgICBQeV9zc2l6ZV90IHNoaWZ0X2RpZ2l0cyA9IHNoaWZ0IC8gUHlMb25nX1NISUZUOworICAgICAgICBkaWdpdCByZW07CisgICAgICAgIC8qIHggPSBhID4+IHNoaWZ0ICovCisgICAgICAgIGFzc2VydChhX3NpemUgPj0gc2hpZnRfZGlnaXRzKTsKKyAgICAgICAgeCA9IF9QeUxvbmdfTmV3KGFfc2l6ZSAtIHNoaWZ0X2RpZ2l0cyk7CisgICAgICAgIGlmICh4ID09IE5VTEwpCisgICAgICAgICAgICBnb3RvIGVycm9yOworICAgICAgICByZW0gPSB2X3JzaGlmdCh4LT5vYl9kaWdpdCwgYS0+b2JfZGlnaXQgKyBzaGlmdF9kaWdpdHMsCisgICAgICAgICAgICAgICAgICAgICAgIGFfc2l6ZSAtIHNoaWZ0X2RpZ2l0cywgc2hpZnQgJSBQeUxvbmdfU0hJRlQpOworICAgICAgICAvKiBzZXQgaW5leGFjdCBpZiBhbnkgb2YgdGhlIGJpdHMgc2hpZnRlZCBvdXQgaXMgbm9uemVybyAqLworICAgICAgICBpZiAocmVtKQorICAgICAgICAgICAgaW5leGFjdCA9IDE7CisgICAgICAgIHdoaWxlICghaW5leGFjdCAmJiBzaGlmdF9kaWdpdHMgPiAwKQorICAgICAgICAgICAgaWYgKGEtPm9iX2RpZ2l0Wy0tc2hpZnRfZGlnaXRzXSkKKyAgICAgICAgICAgICAgICBpbmV4YWN0ID0gMTsKKyAgICB9CisgICAgbG9uZ19ub3JtYWxpemUoeCk7CisgICAgeF9zaXplID0gUHlfU0laRSh4KTsKKworICAgIC8qIHggLy89IGIuIElmIHRoZSByZW1haW5kZXIgaXMgbm9uemVybywgc2V0IGluZXhhY3QuICBXZSBvd24gdGhlIG9ubHkKKyAgICAgICByZWZlcmVuY2UgdG8geCwgc28gaXQncyBzYWZlIHRvIG1vZGlmeSBpdCBpbi1wbGFjZS4gKi8KKyAgICBpZiAoYl9zaXplID09IDEpIHsKKyAgICAgICAgZGlnaXQgcmVtID0gaW5wbGFjZV9kaXZyZW0xKHgtPm9iX2RpZ2l0LCB4LT5vYl9kaWdpdCwgeF9zaXplLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYi0+b2JfZGlnaXRbMF0pOworICAgICAgICBsb25nX25vcm1hbGl6ZSh4KTsKKyAgICAgICAgaWYgKHJlbSkKKyAgICAgICAgICAgIGluZXhhY3QgPSAxOworICAgIH0KKyAgICBlbHNlIHsKKyAgICAgICAgUHlMb25nT2JqZWN0ICpkaXYsICpyZW07CisgICAgICAgIGRpdiA9IHhfZGl2cmVtKHgsIGIsICZyZW0pOworICAgICAgICBQeV9ERUNSRUYoeCk7CisgICAgICAgIHggPSBkaXY7CisgICAgICAgIGlmICh4ID09IE5VTEwpCisgICAgICAgICAgICBnb3RvIGVycm9yOworICAgICAgICBpZiAoUHlfU0laRShyZW0pKQorICAgICAgICAgICAgaW5leGFjdCA9IDE7CisgICAgICAgIFB5X0RFQ1JFRihyZW0pOworICAgIH0KKyAgICB4X3NpemUgPSBBQlMoUHlfU0laRSh4KSk7CisgICAgYXNzZXJ0KHhfc2l6ZSA+IDApOyAvKiByZXN1bHQgb2YgZGl2aXNpb24gaXMgbmV2ZXIgemVybyAqLworICAgIHhfYml0cyA9ICh4X3NpemUtMSkqUHlMb25nX1NISUZUK2JpdHNfaW5fZGlnaXQoeC0+b2JfZGlnaXRbeF9zaXplLTFdKTsKKworICAgIC8qIFRoZSBudW1iZXIgb2YgZXh0cmEgYml0cyB0aGF0IGhhdmUgdG8gYmUgcm91bmRlZCBhd2F5LiAqLworICAgIGV4dHJhX2JpdHMgPSBNQVgoeF9iaXRzLCBEQkxfTUlOX0VYUCAtIHNoaWZ0KSAtIERCTF9NQU5UX0RJRzsKKyAgICBhc3NlcnQoZXh0cmFfYml0cyA9PSAyIHx8IGV4dHJhX2JpdHMgPT0gMyk7CisKKyAgICAvKiBSb3VuZCBieSBkaXJlY3RseSBtb2RpZnlpbmcgdGhlIGxvdyBkaWdpdCBvZiB4LiAqLworICAgIG1hc2sgPSAoZGlnaXQpMSA8PCAoZXh0cmFfYml0cyAtIDEpOworICAgIGxvdyA9IHgtPm9iX2RpZ2l0WzBdIHwgaW5leGFjdDsKKyAgICBpZiAobG93ICYgbWFzayAmJiBsb3cgJiAoMyptYXNrLTEpKQorICAgICAgICBsb3cgKz0gbWFzazsKKyAgICB4LT5vYl9kaWdpdFswXSA9IGxvdyAmIH4obWFzay0xVSk7CisKKyAgICAvKiBDb252ZXJ0IHggdG8gYSBkb3VibGUgZHg7IHRoZSBjb252ZXJzaW9uIGlzIGV4YWN0LiAqLworICAgIGR4ID0geC0+b2JfZGlnaXRbLS14X3NpemVdOworICAgIHdoaWxlICh4X3NpemUgPiAwKQorICAgICAgICBkeCA9IGR4ICogUHlMb25nX0JBU0UgKyB4LT5vYl9kaWdpdFstLXhfc2l6ZV07CisgICAgUHlfREVDUkVGKHgpOworCisgICAgLyogQ2hlY2sgd2hldGhlciBsZGV4cCByZXN1bHQgd2lsbCBvdmVyZmxvdyBhIGRvdWJsZS4gKi8KKyAgICBpZiAoc2hpZnQgKyB4X2JpdHMgPj0gREJMX01BWF9FWFAgJiYKKyAgICAgICAgKHNoaWZ0ICsgeF9iaXRzID4gREJMX01BWF9FWFAgfHwgZHggPT0gbGRleHAoMS4wLCAoaW50KXhfYml0cykpKQorICAgICAgICBnb3RvIG92ZXJmbG93OworICAgIHJlc3VsdCA9IGxkZXhwKGR4LCAoaW50KXNoaWZ0KTsKKworICBzdWNjZXNzOgorICAgIFB5X0RFQ1JFRihhKTsKKyAgICBQeV9ERUNSRUYoYik7CisgICAgcmV0dXJuIFB5RmxvYXRfRnJvbURvdWJsZShuZWdhdGUgPyAtcmVzdWx0IDogcmVzdWx0KTsKKworICB1bmRlcmZsb3dfb3JfemVybzoKKyAgICBQeV9ERUNSRUYoYSk7CisgICAgUHlfREVDUkVGKGIpOworICAgIHJldHVybiBQeUZsb2F0X0Zyb21Eb3VibGUobmVnYXRlID8gLTAuMCA6IDAuMCk7CisKKyAgb3ZlcmZsb3c6CisgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX092ZXJmbG93RXJyb3IsCisgICAgICAgICAgICAgICAgICAgICJpbnRlZ2VyIGRpdmlzaW9uIHJlc3VsdCB0b28gbGFyZ2UgZm9yIGEgZmxvYXQiKTsKKyAgZXJyb3I6CisgICAgUHlfREVDUkVGKGEpOworICAgIFB5X0RFQ1JFRihiKTsKKyAgICByZXR1cm4gTlVMTDsKK30KKworc3RhdGljIFB5T2JqZWN0ICoKK2xvbmdfbW9kKFB5T2JqZWN0ICp2LCBQeU9iamVjdCAqdykKK3sKKyAgICBQeUxvbmdPYmplY3QgKmEsICpiLCAqbW9kOworCisgICAgQ09OVkVSVF9CSU5PUCh2LCB3LCAmYSwgJmIpOworCisgICAgaWYgKGxfZGl2bW9kKGEsIGIsIE5VTEwsICZtb2QpIDwgMCkKKyAgICAgICAgbW9kID0gTlVMTDsKKyAgICBQeV9ERUNSRUYoYSk7CisgICAgUHlfREVDUkVGKGIpOworICAgIHJldHVybiAoUHlPYmplY3QgKiltb2Q7Cit9CisKK3N0YXRpYyBQeU9iamVjdCAqCitsb25nX2Rpdm1vZChQeU9iamVjdCAqdiwgUHlPYmplY3QgKncpCit7CisgICAgUHlMb25nT2JqZWN0ICphLCAqYiwgKmRpdiwgKm1vZDsKKyAgICBQeU9iamVjdCAqejsKKworICAgIENPTlZFUlRfQklOT1AodiwgdywgJmEsICZiKTsKKworICAgIGlmIChsX2Rpdm1vZChhLCBiLCAmZGl2LCAmbW9kKSA8IDApIHsKKyAgICAgICAgUHlfREVDUkVGKGEpOworICAgICAgICBQeV9ERUNSRUYoYik7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICB6ID0gUHlUdXBsZV9OZXcoMik7CisgICAgaWYgKHogIT0gTlVMTCkgeworICAgICAgICBQeVR1cGxlX1NldEl0ZW0oeiwgMCwgKFB5T2JqZWN0ICopIGRpdik7CisgICAgICAgIFB5VHVwbGVfU2V0SXRlbSh6LCAxLCAoUHlPYmplY3QgKikgbW9kKTsKKyAgICB9CisgICAgZWxzZSB7CisgICAgICAgIFB5X0RFQ1JFRihkaXYpOworICAgICAgICBQeV9ERUNSRUYobW9kKTsKKyAgICB9CisgICAgUHlfREVDUkVGKGEpOworICAgIFB5X0RFQ1JFRihiKTsKKyAgICByZXR1cm4gejsKK30KKworLyogcG93KHYsIHcsIHgpICovCitzdGF0aWMgUHlPYmplY3QgKgorbG9uZ19wb3coUHlPYmplY3QgKnYsIFB5T2JqZWN0ICp3LCBQeU9iamVjdCAqeCkKK3sKKyAgICBQeUxvbmdPYmplY3QgKmEsICpiLCAqYzsgLyogYSxiLGMgPSB2LHcseCAqLworICAgIGludCBuZWdhdGl2ZU91dHB1dCA9IDA7ICAvKiBpZiB4PDAgcmV0dXJuIG5lZ2F0aXZlIG91dHB1dCAqLworCisgICAgUHlMb25nT2JqZWN0ICp6ID0gTlVMTDsgIC8qIGFjY3VtdWxhdGVkIHJlc3VsdCAqLworICAgIFB5X3NzaXplX3QgaSwgaiwgazsgICAgICAgICAgICAgLyogY291bnRlcnMgKi8KKyAgICBQeUxvbmdPYmplY3QgKnRlbXAgPSBOVUxMOworCisgICAgLyogNS1hcnkgdmFsdWVzLiAgSWYgdGhlIGV4cG9uZW50IGlzIGxhcmdlIGVub3VnaCwgdGFibGUgaXMKKyAgICAgKiBwcmVjb21wdXRlZCBzbyB0aGF0IHRhYmxlW2ldID09IGEqKmkgJSBjIGZvciBpIGluIHJhbmdlKDMyKS4KKyAgICAgKi8KKyAgICBQeUxvbmdPYmplY3QgKnRhYmxlWzMyXSA9IHswLDAsMCwwLDAsMCwwLDAsMCwwLDAsMCwwLDAsMCwwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAsMCwwLDAsMCwwLDAsMCwwLDAsMCwwLDAsMCwwLDB9OworCisgICAgLyogYSwgYiwgYyA9IHYsIHcsIHggKi8KKyAgICBDT05WRVJUX0JJTk9QKHYsIHcsICZhLCAmYik7CisgICAgaWYgKFB5TG9uZ19DaGVjayh4KSkgeworICAgICAgICBjID0gKFB5TG9uZ09iamVjdCAqKXg7CisgICAgICAgIFB5X0lOQ1JFRih4KTsKKyAgICB9CisgICAgZWxzZSBpZiAoUHlJbnRfQ2hlY2soeCkpIHsKKyAgICAgICAgYyA9IChQeUxvbmdPYmplY3QgKilQeUxvbmdfRnJvbUxvbmcoUHlJbnRfQVNfTE9ORyh4KSk7CisgICAgICAgIGlmIChjID09IE5VTEwpCisgICAgICAgICAgICBnb3RvIEVycm9yOworICAgIH0KKyAgICBlbHNlIGlmICh4ID09IFB5X05vbmUpCisgICAgICAgIGMgPSBOVUxMOworICAgIGVsc2UgeworICAgICAgICBQeV9ERUNSRUYoYSk7CisgICAgICAgIFB5X0RFQ1JFRihiKTsKKyAgICAgICAgUHlfSU5DUkVGKFB5X05vdEltcGxlbWVudGVkKTsKKyAgICAgICAgcmV0dXJuIFB5X05vdEltcGxlbWVudGVkOworICAgIH0KKworICAgIGlmIChQeV9TSVpFKGIpIDwgMCkgeyAgLyogaWYgZXhwb25lbnQgaXMgbmVnYXRpdmUgKi8KKyAgICAgICAgaWYgKGMpIHsKKyAgICAgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19UeXBlRXJyb3IsICJwb3coKSAybmQgYXJndW1lbnQgIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICJjYW5ub3QgYmUgbmVnYXRpdmUgd2hlbiAzcmQgYXJndW1lbnQgc3BlY2lmaWVkIik7CisgICAgICAgICAgICBnb3RvIEVycm9yOworICAgICAgICB9CisgICAgICAgIGVsc2UgeworICAgICAgICAgICAgLyogZWxzZSByZXR1cm4gYSBmbG9hdC4gIFRoaXMgd29ya3MgYmVjYXVzZSB3ZSBrbm93CisgICAgICAgICAgICAgICB0aGF0IHRoaXMgY2FsbHMgZmxvYXRfcG93KCkgd2hpY2ggY29udmVydHMgaXRzCisgICAgICAgICAgICAgICBhcmd1bWVudHMgdG8gZG91YmxlLiAqLworICAgICAgICAgICAgUHlfREVDUkVGKGEpOworICAgICAgICAgICAgUHlfREVDUkVGKGIpOworICAgICAgICAgICAgcmV0dXJuIFB5RmxvYXRfVHlwZS50cF9hc19udW1iZXItPm5iX3Bvd2VyKHYsIHcsIHgpOworICAgICAgICB9CisgICAgfQorCisgICAgaWYgKGMpIHsKKyAgICAgICAgLyogaWYgbW9kdWx1cyA9PSAwOgorICAgICAgICAgICAgICAgcmFpc2UgVmFsdWVFcnJvcigpICovCisgICAgICAgIGlmIChQeV9TSVpFKGMpID09IDApIHsKKyAgICAgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19WYWx1ZUVycm9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICJwb3coKSAzcmQgYXJndW1lbnQgY2Fubm90IGJlIDAiKTsKKyAgICAgICAgICAgIGdvdG8gRXJyb3I7CisgICAgICAgIH0KKworICAgICAgICAvKiBpZiBtb2R1bHVzIDwgMDoKKyAgICAgICAgICAgICAgIG5lZ2F0aXZlT3V0cHV0ID0gVHJ1ZQorICAgICAgICAgICAgICAgbW9kdWx1cyA9IC1tb2R1bHVzICovCisgICAgICAgIGlmIChQeV9TSVpFKGMpIDwgMCkgeworICAgICAgICAgICAgbmVnYXRpdmVPdXRwdXQgPSAxOworICAgICAgICAgICAgdGVtcCA9IChQeUxvbmdPYmplY3QgKilfUHlMb25nX0NvcHkoYyk7CisgICAgICAgICAgICBpZiAodGVtcCA9PSBOVUxMKQorICAgICAgICAgICAgICAgIGdvdG8gRXJyb3I7CisgICAgICAgICAgICBQeV9ERUNSRUYoYyk7CisgICAgICAgICAgICBjID0gdGVtcDsKKyAgICAgICAgICAgIHRlbXAgPSBOVUxMOworICAgICAgICAgICAgYy0+b2Jfc2l6ZSA9IC0gYy0+b2Jfc2l6ZTsKKyAgICAgICAgfQorCisgICAgICAgIC8qIGlmIG1vZHVsdXMgPT0gMToKKyAgICAgICAgICAgICAgIHJldHVybiAwICovCisgICAgICAgIGlmICgoUHlfU0laRShjKSA9PSAxKSAmJiAoYy0+b2JfZGlnaXRbMF0gPT0gMSkpIHsKKyAgICAgICAgICAgIHogPSAoUHlMb25nT2JqZWN0ICopUHlMb25nX0Zyb21Mb25nKDBMKTsKKyAgICAgICAgICAgIGdvdG8gRG9uZTsKKyAgICAgICAgfQorCisgICAgICAgIC8qIGlmIGJhc2UgPCAwOgorICAgICAgICAgICAgICAgYmFzZSA9IGJhc2UgJSBtb2R1bHVzCisgICAgICAgICAgIEhhdmluZyB0aGUgYmFzZSBwb3NpdGl2ZSBqdXN0IG1ha2VzIHRoaW5ncyBlYXNpZXIuICovCisgICAgICAgIGlmIChQeV9TSVpFKGEpIDwgMCkgeworICAgICAgICAgICAgaWYgKGxfZGl2bW9kKGEsIGMsIE5VTEwsICZ0ZW1wKSA8IDApCisgICAgICAgICAgICAgICAgZ290byBFcnJvcjsKKyAgICAgICAgICAgIFB5X0RFQ1JFRihhKTsKKyAgICAgICAgICAgIGEgPSB0ZW1wOworICAgICAgICAgICAgdGVtcCA9IE5VTEw7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKiBBdCB0aGlzIHBvaW50IGEsIGIsIGFuZCBjIGFyZSBndWFyYW50ZWVkIG5vbi1uZWdhdGl2ZSBVTkxFU1MKKyAgICAgICBjIGlzIE5VTEwsIGluIHdoaWNoIGNhc2UgYSBtYXkgYmUgbmVnYXRpdmUuICovCisKKyAgICB6ID0gKFB5TG9uZ09iamVjdCAqKVB5TG9uZ19Gcm9tTG9uZygxTCk7CisgICAgaWYgKHogPT0gTlVMTCkKKyAgICAgICAgZ290byBFcnJvcjsKKworICAgIC8qIFBlcmZvcm0gYSBtb2R1bGFyIHJlZHVjdGlvbiwgWCA9IFggJSBjLCBidXQgbGVhdmUgWCBhbG9uZSBpZiBjCisgICAgICogaXMgTlVMTC4KKyAgICAgKi8KKyNkZWZpbmUgUkVEVUNFKFgpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIGRvIHsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgIGlmIChjICE9IE5VTEwpIHsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICAgIGlmIChsX2Rpdm1vZChYLCBjLCBOVUxMLCAmdGVtcCkgPCAwKSAgICAgICAgXAorICAgICAgICAgICAgICAgIGdvdG8gRXJyb3I7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgICAgICBQeV9YREVDUkVGKFgpOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICAgIFggPSB0ZW1wOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgICAgdGVtcCA9IE5VTEw7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgIH0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICB9IHdoaWxlKDApCisKKyAgICAvKiBNdWx0aXBseSB0d28gdmFsdWVzLCB0aGVuIHJlZHVjZSB0aGUgcmVzdWx0OgorICAgICAgIHJlc3VsdCA9IFgqWSAlIGMuICBJZiBjIGlzIE5VTEwsIHNraXAgdGhlIG1vZC4gKi8KKyNkZWZpbmUgTVVMVChYLCBZLCByZXN1bHQpICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICBkbyB7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgdGVtcCA9IChQeUxvbmdPYmplY3QgKilsb25nX211bChYLCBZKTsgIFwKKyAgICAgICAgaWYgKHRlbXAgPT0gTlVMTCkgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICAgIGdvdG8gRXJyb3I7ICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgUHlfWERFQ1JFRihyZXN1bHQpOyAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgcmVzdWx0ID0gdGVtcDsgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgdGVtcCA9IE5VTEw7ICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgUkVEVUNFKHJlc3VsdCk7ICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICB9IHdoaWxlKDApCisKKyAgICBpZiAoUHlfU0laRShiKSA8PSBGSVZFQVJZX0NVVE9GRikgeworICAgICAgICAvKiBMZWZ0LXRvLXJpZ2h0IGJpbmFyeSBleHBvbmVudGlhdGlvbiAoSEFDIEFsZ29yaXRobSAxNC43OSkgKi8KKyAgICAgICAgLyogaHR0cDovL3d3dy5jYWNyLm1hdGgudXdhdGVybG9vLmNhL2hhYy9hYm91dC9jaGFwMTQucGRmICAgICovCisgICAgICAgIGZvciAoaSA9IFB5X1NJWkUoYikgLSAxOyBpID49IDA7IC0taSkgeworICAgICAgICAgICAgZGlnaXQgYmkgPSBiLT5vYl9kaWdpdFtpXTsKKworICAgICAgICAgICAgZm9yIChqID0gKGRpZ2l0KTEgPDwgKFB5TG9uZ19TSElGVC0xKTsgaiAhPSAwOyBqID4+PSAxKSB7CisgICAgICAgICAgICAgICAgTVVMVCh6LCB6LCB6KTsKKyAgICAgICAgICAgICAgICBpZiAoYmkgJiBqKQorICAgICAgICAgICAgICAgICAgICBNVUxUKHosIGEsIHopOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorICAgIGVsc2UgeworICAgICAgICAvKiBMZWZ0LXRvLXJpZ2h0IDUtYXJ5IGV4cG9uZW50aWF0aW9uIChIQUMgQWxnb3JpdGhtIDE0LjgyKSAqLworICAgICAgICBQeV9JTkNSRUYoeik7ICAgICAgICAgICAvKiBzdGlsbCBob2xkcyAxTCAqLworICAgICAgICB0YWJsZVswXSA9IHo7CisgICAgICAgIGZvciAoaSA9IDE7IGkgPCAzMjsgKytpKQorICAgICAgICAgICAgTVVMVCh0YWJsZVtpLTFdLCBhLCB0YWJsZVtpXSk7CisKKyAgICAgICAgZm9yIChpID0gUHlfU0laRShiKSAtIDE7IGkgPj0gMDsgLS1pKSB7CisgICAgICAgICAgICBjb25zdCBkaWdpdCBiaSA9IGItPm9iX2RpZ2l0W2ldOworCisgICAgICAgICAgICBmb3IgKGogPSBQeUxvbmdfU0hJRlQgLSA1OyBqID49IDA7IGogLT0gNSkgeworICAgICAgICAgICAgICAgIGNvbnN0IGludCBpbmRleCA9IChiaSA+PiBqKSAmIDB4MWY7CisgICAgICAgICAgICAgICAgZm9yIChrID0gMDsgayA8IDU7ICsraykKKyAgICAgICAgICAgICAgICAgICAgTVVMVCh6LCB6LCB6KTsKKyAgICAgICAgICAgICAgICBpZiAoaW5kZXgpCisgICAgICAgICAgICAgICAgICAgIE1VTFQoeiwgdGFibGVbaW5kZXhdLCB6KTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIGlmIChuZWdhdGl2ZU91dHB1dCAmJiAoUHlfU0laRSh6KSAhPSAwKSkgeworICAgICAgICB0ZW1wID0gKFB5TG9uZ09iamVjdCAqKWxvbmdfc3ViKHosIGMpOworICAgICAgICBpZiAodGVtcCA9PSBOVUxMKQorICAgICAgICAgICAgZ290byBFcnJvcjsKKyAgICAgICAgUHlfREVDUkVGKHopOworICAgICAgICB6ID0gdGVtcDsKKyAgICAgICAgdGVtcCA9IE5VTEw7CisgICAgfQorICAgIGdvdG8gRG9uZTsKKworICBFcnJvcjoKKyAgICBpZiAoeiAhPSBOVUxMKSB7CisgICAgICAgIFB5X0RFQ1JFRih6KTsKKyAgICAgICAgeiA9IE5VTEw7CisgICAgfQorICAgIC8qIGZhbGwgdGhyb3VnaCAqLworICBEb25lOgorICAgIGlmIChQeV9TSVpFKGIpID4gRklWRUFSWV9DVVRPRkYpIHsKKyAgICAgICAgZm9yIChpID0gMDsgaSA8IDMyOyArK2kpCisgICAgICAgICAgICBQeV9YREVDUkVGKHRhYmxlW2ldKTsKKyAgICB9CisgICAgUHlfREVDUkVGKGEpOworICAgIFB5X0RFQ1JFRihiKTsKKyAgICBQeV9YREVDUkVGKGMpOworICAgIFB5X1hERUNSRUYodGVtcCk7CisgICAgcmV0dXJuIChQeU9iamVjdCAqKXo7Cit9CisKK3N0YXRpYyBQeU9iamVjdCAqCitsb25nX2ludmVydChQeUxvbmdPYmplY3QgKnYpCit7CisgICAgLyogSW1wbGVtZW50IH54IGFzIC0oeCsxKSAqLworICAgIFB5TG9uZ09iamVjdCAqeDsKKyAgICBQeUxvbmdPYmplY3QgKnc7CisgICAgdyA9IChQeUxvbmdPYmplY3QgKilQeUxvbmdfRnJvbUxvbmcoMUwpOworICAgIGlmICh3ID09IE5VTEwpCisgICAgICAgIHJldHVybiBOVUxMOworICAgIHggPSAoUHlMb25nT2JqZWN0ICopIGxvbmdfYWRkKHYsIHcpOworICAgIFB5X0RFQ1JFRih3KTsKKyAgICBpZiAoeCA9PSBOVUxMKQorICAgICAgICByZXR1cm4gTlVMTDsKKyAgICBQeV9TSVpFKHgpID0gLShQeV9TSVpFKHgpKTsKKyAgICByZXR1cm4gKFB5T2JqZWN0ICopeDsKK30KKworc3RhdGljIFB5T2JqZWN0ICoKK2xvbmdfbmVnKFB5TG9uZ09iamVjdCAqdikKK3sKKyAgICBQeUxvbmdPYmplY3QgKno7CisgICAgaWYgKHYtPm9iX3NpemUgPT0gMCAmJiBQeUxvbmdfQ2hlY2tFeGFjdCh2KSkgeworICAgICAgICAvKiAtMCA9PSAwICovCisgICAgICAgIFB5X0lOQ1JFRih2KTsKKyAgICAgICAgcmV0dXJuIChQeU9iamVjdCAqKSB2OworICAgIH0KKyAgICB6ID0gKFB5TG9uZ09iamVjdCAqKV9QeUxvbmdfQ29weSh2KTsKKyAgICBpZiAoeiAhPSBOVUxMKQorICAgICAgICB6LT5vYl9zaXplID0gLSh2LT5vYl9zaXplKTsKKyAgICByZXR1cm4gKFB5T2JqZWN0ICopejsKK30KKworc3RhdGljIFB5T2JqZWN0ICoKK2xvbmdfYWJzKFB5TG9uZ09iamVjdCAqdikKK3sKKyAgICBpZiAodi0+b2Jfc2l6ZSA8IDApCisgICAgICAgIHJldHVybiBsb25nX25lZyh2KTsKKyAgICBlbHNlCisgICAgICAgIHJldHVybiBsb25nX2xvbmcoKFB5T2JqZWN0ICopdik7Cit9CisKK3N0YXRpYyBpbnQKK2xvbmdfbm9uemVybyhQeUxvbmdPYmplY3QgKnYpCit7CisgICAgcmV0dXJuIFB5X1NJWkUodikgIT0gMDsKK30KKworc3RhdGljIFB5T2JqZWN0ICoKK2xvbmdfcnNoaWZ0KFB5TG9uZ09iamVjdCAqdiwgUHlMb25nT2JqZWN0ICp3KQoreworICAgIFB5TG9uZ09iamVjdCAqYSwgKmI7CisgICAgUHlMb25nT2JqZWN0ICp6ID0gTlVMTDsKKyAgICBQeV9zc2l6ZV90IHNoaWZ0YnksIG5ld3NpemUsIHdvcmRzaGlmdCwgbG9zaGlmdCwgaGlzaGlmdCwgaSwgajsKKyAgICBkaWdpdCBsb21hc2ssIGhpbWFzazsKKworICAgIENPTlZFUlRfQklOT1AoKFB5T2JqZWN0ICopdiwgKFB5T2JqZWN0ICopdywgJmEsICZiKTsKKworICAgIGlmIChQeV9TSVpFKGEpIDwgMCkgeworICAgICAgICAvKiBSaWdodCBzaGlmdGluZyBuZWdhdGl2ZSBudW1iZXJzIGlzIGhhcmRlciAqLworICAgICAgICBQeUxvbmdPYmplY3QgKmExLCAqYTI7CisgICAgICAgIGExID0gKFB5TG9uZ09iamVjdCAqKSBsb25nX2ludmVydChhKTsKKyAgICAgICAgaWYgKGExID09IE5VTEwpCisgICAgICAgICAgICBnb3RvIHJzaGlmdF9lcnJvcjsKKyAgICAgICAgYTIgPSAoUHlMb25nT2JqZWN0ICopIGxvbmdfcnNoaWZ0KGExLCBiKTsKKyAgICAgICAgUHlfREVDUkVGKGExKTsKKyAgICAgICAgaWYgKGEyID09IE5VTEwpCisgICAgICAgICAgICBnb3RvIHJzaGlmdF9lcnJvcjsKKyAgICAgICAgeiA9IChQeUxvbmdPYmplY3QgKikgbG9uZ19pbnZlcnQoYTIpOworICAgICAgICBQeV9ERUNSRUYoYTIpOworICAgIH0KKyAgICBlbHNlIHsKKyAgICAgICAgc2hpZnRieSA9IFB5TG9uZ19Bc1NzaXplX3QoKFB5T2JqZWN0ICopYik7CisgICAgICAgIGlmIChzaGlmdGJ5ID09IC0xTCAmJiBQeUVycl9PY2N1cnJlZCgpKQorICAgICAgICAgICAgZ290byByc2hpZnRfZXJyb3I7CisgICAgICAgIGlmIChzaGlmdGJ5IDwgMCkgeworICAgICAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1ZhbHVlRXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIm5lZ2F0aXZlIHNoaWZ0IGNvdW50Iik7CisgICAgICAgICAgICBnb3RvIHJzaGlmdF9lcnJvcjsKKyAgICAgICAgfQorICAgICAgICB3b3Jkc2hpZnQgPSBzaGlmdGJ5IC8gUHlMb25nX1NISUZUOworICAgICAgICBuZXdzaXplID0gQUJTKFB5X1NJWkUoYSkpIC0gd29yZHNoaWZ0OworICAgICAgICBpZiAobmV3c2l6ZSA8PSAwKSB7CisgICAgICAgICAgICB6ID0gX1B5TG9uZ19OZXcoMCk7CisgICAgICAgICAgICBQeV9ERUNSRUYoYSk7CisgICAgICAgICAgICBQeV9ERUNSRUYoYik7CisgICAgICAgICAgICByZXR1cm4gKFB5T2JqZWN0ICopejsKKyAgICAgICAgfQorICAgICAgICBsb3NoaWZ0ID0gc2hpZnRieSAlIFB5TG9uZ19TSElGVDsKKyAgICAgICAgaGlzaGlmdCA9IFB5TG9uZ19TSElGVCAtIGxvc2hpZnQ7CisgICAgICAgIGxvbWFzayA9ICgoZGlnaXQpMSA8PCBoaXNoaWZ0KSAtIDE7CisgICAgICAgIGhpbWFzayA9IFB5TG9uZ19NQVNLIF4gbG9tYXNrOworICAgICAgICB6ID0gX1B5TG9uZ19OZXcobmV3c2l6ZSk7CisgICAgICAgIGlmICh6ID09IE5VTEwpCisgICAgICAgICAgICBnb3RvIHJzaGlmdF9lcnJvcjsKKyAgICAgICAgaWYgKFB5X1NJWkUoYSkgPCAwKQorICAgICAgICAgICAgUHlfU0laRSh6KSA9IC0oUHlfU0laRSh6KSk7CisgICAgICAgIGZvciAoaSA9IDAsIGogPSB3b3Jkc2hpZnQ7IGkgPCBuZXdzaXplOyBpKyssIGorKykgeworICAgICAgICAgICAgei0+b2JfZGlnaXRbaV0gPSAoYS0+b2JfZGlnaXRbal0gPj4gbG9zaGlmdCkgJiBsb21hc2s7CisgICAgICAgICAgICBpZiAoaSsxIDwgbmV3c2l6ZSkKKyAgICAgICAgICAgICAgICB6LT5vYl9kaWdpdFtpXSB8PSAoYS0+b2JfZGlnaXRbaisxXSA8PCBoaXNoaWZ0KSAmIGhpbWFzazsKKyAgICAgICAgfQorICAgICAgICB6ID0gbG9uZ19ub3JtYWxpemUoeik7CisgICAgfQorICByc2hpZnRfZXJyb3I6CisgICAgUHlfREVDUkVGKGEpOworICAgIFB5X0RFQ1JFRihiKTsKKyAgICByZXR1cm4gKFB5T2JqZWN0ICopIHo7CisKK30KKworc3RhdGljIFB5T2JqZWN0ICoKK2xvbmdfbHNoaWZ0KFB5T2JqZWN0ICp2LCBQeU9iamVjdCAqdykKK3sKKyAgICAvKiBUaGlzIHZlcnNpb24gZHVlIHRvIFRpbSBQZXRlcnMgKi8KKyAgICBQeUxvbmdPYmplY3QgKmEsICpiOworICAgIFB5TG9uZ09iamVjdCAqeiA9IE5VTEw7CisgICAgUHlfc3NpemVfdCBzaGlmdGJ5LCBvbGRzaXplLCBuZXdzaXplLCB3b3Jkc2hpZnQsIHJlbXNoaWZ0LCBpLCBqOworICAgIHR3b2RpZ2l0cyBhY2N1bTsKKworICAgIENPTlZFUlRfQklOT1AodiwgdywgJmEsICZiKTsKKworICAgIHNoaWZ0YnkgPSBQeUxvbmdfQXNTc2l6ZV90KChQeU9iamVjdCAqKWIpOworICAgIGlmIChzaGlmdGJ5ID09IC0xTCAmJiBQeUVycl9PY2N1cnJlZCgpKQorICAgICAgICBnb3RvIGxzaGlmdF9lcnJvcjsKKyAgICBpZiAoc2hpZnRieSA8IDApIHsKKyAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1ZhbHVlRXJyb3IsICJuZWdhdGl2ZSBzaGlmdCBjb3VudCIpOworICAgICAgICBnb3RvIGxzaGlmdF9lcnJvcjsKKyAgICB9CisgICAgLyogd29yZHNoaWZ0LCByZW1zaGlmdCA9IGRpdm1vZChzaGlmdGJ5LCBQeUxvbmdfU0hJRlQpICovCisgICAgd29yZHNoaWZ0ID0gc2hpZnRieSAvIFB5TG9uZ19TSElGVDsKKyAgICByZW1zaGlmdCAgPSBzaGlmdGJ5IC0gd29yZHNoaWZ0ICogUHlMb25nX1NISUZUOworCisgICAgb2xkc2l6ZSA9IEFCUyhhLT5vYl9zaXplKTsKKyAgICBuZXdzaXplID0gb2xkc2l6ZSArIHdvcmRzaGlmdDsKKyAgICBpZiAocmVtc2hpZnQpCisgICAgICAgICsrbmV3c2l6ZTsKKyAgICB6ID0gX1B5TG9uZ19OZXcobmV3c2l6ZSk7CisgICAgaWYgKHogPT0gTlVMTCkKKyAgICAgICAgZ290byBsc2hpZnRfZXJyb3I7CisgICAgaWYgKGEtPm9iX3NpemUgPCAwKQorICAgICAgICB6LT5vYl9zaXplID0gLSh6LT5vYl9zaXplKTsKKyAgICBmb3IgKGkgPSAwOyBpIDwgd29yZHNoaWZ0OyBpKyspCisgICAgICAgIHotPm9iX2RpZ2l0W2ldID0gMDsKKyAgICBhY2N1bSA9IDA7CisgICAgZm9yIChpID0gd29yZHNoaWZ0LCBqID0gMDsgaiA8IG9sZHNpemU7IGkrKywgaisrKSB7CisgICAgICAgIGFjY3VtIHw9ICh0d29kaWdpdHMpYS0+b2JfZGlnaXRbal0gPDwgcmVtc2hpZnQ7CisgICAgICAgIHotPm9iX2RpZ2l0W2ldID0gKGRpZ2l0KShhY2N1bSAmIFB5TG9uZ19NQVNLKTsKKyAgICAgICAgYWNjdW0gPj49IFB5TG9uZ19TSElGVDsKKyAgICB9CisgICAgaWYgKHJlbXNoaWZ0KQorICAgICAgICB6LT5vYl9kaWdpdFtuZXdzaXplLTFdID0gKGRpZ2l0KWFjY3VtOworICAgIGVsc2UKKyAgICAgICAgYXNzZXJ0KCFhY2N1bSk7CisgICAgeiA9IGxvbmdfbm9ybWFsaXplKHopOworICBsc2hpZnRfZXJyb3I6CisgICAgUHlfREVDUkVGKGEpOworICAgIFB5X0RFQ1JFRihiKTsKKyAgICByZXR1cm4gKFB5T2JqZWN0ICopIHo7Cit9CisKKy8qIENvbXB1dGUgdHdvJ3MgY29tcGxlbWVudCBvZiBkaWdpdCB2ZWN0b3IgYVswOm1dLCB3cml0aW5nIHJlc3VsdCB0bworICAgelswOm1dLiAgVGhlIGRpZ2l0IHZlY3RvciBhIG5lZWQgbm90IGJlIG5vcm1hbGl6ZWQsIGJ1dCBzaG91bGQgbm90CisgICBiZSBlbnRpcmVseSB6ZXJvLiAgYSBhbmQgeiBtYXkgcG9pbnQgdG8gdGhlIHNhbWUgZGlnaXQgdmVjdG9yLiAqLworCitzdGF0aWMgdm9pZAordl9jb21wbGVtZW50KGRpZ2l0ICp6LCBkaWdpdCAqYSwgUHlfc3NpemVfdCBtKQoreworICAgIFB5X3NzaXplX3QgaTsKKyAgICBkaWdpdCBjYXJyeSA9IDE7CisgICAgZm9yIChpID0gMDsgaSA8IG07ICsraSkgeworICAgICAgICBjYXJyeSArPSBhW2ldIF4gUHlMb25nX01BU0s7CisgICAgICAgIHpbaV0gPSBjYXJyeSAmIFB5TG9uZ19NQVNLOworICAgICAgICBjYXJyeSA+Pj0gUHlMb25nX1NISUZUOworICAgIH0KKyAgICBhc3NlcnQoY2FycnkgPT0gMCk7Cit9CisKKy8qIEJpdHdpc2UgYW5kL3hvci9vciBvcGVyYXRpb25zICovCisKK3N0YXRpYyBQeU9iamVjdCAqCitsb25nX2JpdHdpc2UoUHlMb25nT2JqZWN0ICphLAorICAgICAgICAgICAgIGludCBvcCwgIC8qICcmJywgJ3wnLCAnXicgKi8KKyAgICAgICAgICAgICBQeUxvbmdPYmplY3QgKmIpCit7CisgICAgaW50IG5lZ2EsIG5lZ2IsIG5lZ3o7CisgICAgUHlfc3NpemVfdCBzaXplX2EsIHNpemVfYiwgc2l6ZV96LCBpOworICAgIFB5TG9uZ09iamVjdCAqejsKKworICAgIC8qIEJpdHdpc2Ugb3BlcmF0aW9ucyBmb3IgbmVnYXRpdmUgbnVtYmVycyBvcGVyYXRlIGFzIHRob3VnaAorICAgICAgIG9uIGEgdHdvJ3MgY29tcGxlbWVudCByZXByZXNlbnRhdGlvbi4gIFNvIGNvbnZlcnQgYXJndW1lbnRzCisgICAgICAgZnJvbSBzaWduLW1hZ25pdHVkZSB0byB0d28ncyBjb21wbGVtZW50LCBhbmQgY29udmVydCB0aGUKKyAgICAgICByZXN1bHQgYmFjayB0byBzaWduLW1hZ25pdHVkZSBhdCB0aGUgZW5kLiAqLworCisgICAgLyogSWYgYSBpcyBuZWdhdGl2ZSwgcmVwbGFjZSBpdCBieSBpdHMgdHdvJ3MgY29tcGxlbWVudC4gKi8KKyAgICBzaXplX2EgPSBBQlMoUHlfU0laRShhKSk7CisgICAgbmVnYSA9IFB5X1NJWkUoYSkgPCAwOworICAgIGlmIChuZWdhKSB7CisgICAgICAgIHogPSBfUHlMb25nX05ldyhzaXplX2EpOworICAgICAgICBpZiAoeiA9PSBOVUxMKQorICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgICAgIHZfY29tcGxlbWVudCh6LT5vYl9kaWdpdCwgYS0+b2JfZGlnaXQsIHNpemVfYSk7CisgICAgICAgIGEgPSB6OworICAgIH0KKyAgICBlbHNlCisgICAgICAgIC8qIEtlZXAgcmVmZXJlbmNlIGNvdW50IGNvbnNpc3RlbnQuICovCisgICAgICAgIFB5X0lOQ1JFRihhKTsKKworICAgIC8qIFNhbWUgZm9yIGIuICovCisgICAgc2l6ZV9iID0gQUJTKFB5X1NJWkUoYikpOworICAgIG5lZ2IgPSBQeV9TSVpFKGIpIDwgMDsKKyAgICBpZiAobmVnYikgeworICAgICAgICB6ID0gX1B5TG9uZ19OZXcoc2l6ZV9iKTsKKyAgICAgICAgaWYgKHogPT0gTlVMTCkgeworICAgICAgICAgICAgUHlfREVDUkVGKGEpOworICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgICAgIH0KKyAgICAgICAgdl9jb21wbGVtZW50KHotPm9iX2RpZ2l0LCBiLT5vYl9kaWdpdCwgc2l6ZV9iKTsKKyAgICAgICAgYiA9IHo7CisgICAgfQorICAgIGVsc2UKKyAgICAgICAgUHlfSU5DUkVGKGIpOworCisgICAgLyogU3dhcCBhIGFuZCBiIGlmIG5lY2Vzc2FyeSB0byBlbnN1cmUgc2l6ZV9hID49IHNpemVfYi4gKi8KKyAgICBpZiAoc2l6ZV9hIDwgc2l6ZV9iKSB7CisgICAgICAgIHogPSBhOyBhID0gYjsgYiA9IHo7CisgICAgICAgIHNpemVfeiA9IHNpemVfYTsgc2l6ZV9hID0gc2l6ZV9iOyBzaXplX2IgPSBzaXplX3o7CisgICAgICAgIG5lZ3ogPSBuZWdhOyBuZWdhID0gbmVnYjsgbmVnYiA9IG5lZ3o7CisgICAgfQorCisgICAgLyogSlJIOiBUaGUgb3JpZ2luYWwgbG9naWMgaGVyZSB3YXMgdG8gYWxsb2NhdGUgdGhlIHJlc3VsdCB2YWx1ZSAoeikKKyAgICAgICBhcyB0aGUgbG9uZ2VyIG9mIHRoZSB0d28gb3BlcmFuZHMuICBIb3dldmVyLCB0aGVyZSBhcmUgc29tZSBjYXNlcworICAgICAgIHdoZXJlIHRoZSByZXN1bHQgaXMgZ3VhcmFudGVlZCB0byBiZSBzaG9ydGVyIHRoYW4gdGhhdDogQU5EIG9mIHR3bworICAgICAgIHBvc2l0aXZlcywgT1Igb2YgdHdvIG5lZ2F0aXZlczogdXNlIHRoZSBzaG9ydGVyIG51bWJlci4gIEFORCB3aXRoCisgICAgICAgbWl4ZWQgc2lnbnM6IHVzZSB0aGUgcG9zaXRpdmUgbnVtYmVyLiAgT1Igd2l0aCBtaXhlZCBzaWduczogdXNlIHRoZQorICAgICAgIG5lZ2F0aXZlIG51bWJlci4KKyAgICAqLworICAgIHN3aXRjaCAob3ApIHsKKyAgICBjYXNlICdeJzoKKyAgICAgICAgbmVneiA9IG5lZ2EgXiBuZWdiOworICAgICAgICBzaXplX3ogPSBzaXplX2E7CisgICAgICAgIGJyZWFrOworICAgIGNhc2UgJyYnOgorICAgICAgICBuZWd6ID0gbmVnYSAmIG5lZ2I7CisgICAgICAgIHNpemVfeiA9IG5lZ2IgPyBzaXplX2EgOiBzaXplX2I7CisgICAgICAgIGJyZWFrOworICAgIGNhc2UgJ3wnOgorICAgICAgICBuZWd6ID0gbmVnYSB8IG5lZ2I7CisgICAgICAgIHNpemVfeiA9IG5lZ2IgPyBzaXplX2IgOiBzaXplX2E7CisgICAgICAgIGJyZWFrOworICAgIGRlZmF1bHQ6CisgICAgICAgIFB5RXJyX0JhZEFyZ3VtZW50KCk7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKworICAgIC8qIFdlIGFsbG93IGFuIGV4dHJhIGRpZ2l0IGlmIHogaXMgbmVnYXRpdmUsIHRvIG1ha2Ugc3VyZSB0aGF0CisgICAgICAgdGhlIGZpbmFsIHR3bydzIGNvbXBsZW1lbnQgb2YgeiBkb2Vzbid0IG92ZXJmbG93LiAqLworICAgIHogPSBfUHlMb25nX05ldyhzaXplX3ogKyBuZWd6KTsKKyAgICBpZiAoeiA9PSBOVUxMKSB7CisgICAgICAgIFB5X0RFQ1JFRihhKTsKKyAgICAgICAgUHlfREVDUkVGKGIpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisKKyAgICAvKiBDb21wdXRlIGRpZ2l0cyBmb3Igb3ZlcmxhcCBvZiBhIGFuZCBiLiAqLworICAgIHN3aXRjaChvcCkgeworICAgIGNhc2UgJyYnOgorICAgICAgICBmb3IgKGkgPSAwOyBpIDwgc2l6ZV9iOyArK2kpCisgICAgICAgICAgICB6LT5vYl9kaWdpdFtpXSA9IGEtPm9iX2RpZ2l0W2ldICYgYi0+b2JfZGlnaXRbaV07CisgICAgICAgIGJyZWFrOworICAgIGNhc2UgJ3wnOgorICAgICAgICBmb3IgKGkgPSAwOyBpIDwgc2l6ZV9iOyArK2kpCisgICAgICAgICAgICB6LT5vYl9kaWdpdFtpXSA9IGEtPm9iX2RpZ2l0W2ldIHwgYi0+b2JfZGlnaXRbaV07CisgICAgICAgIGJyZWFrOworICAgIGNhc2UgJ14nOgorICAgICAgICBmb3IgKGkgPSAwOyBpIDwgc2l6ZV9iOyArK2kpCisgICAgICAgICAgICB6LT5vYl9kaWdpdFtpXSA9IGEtPm9iX2RpZ2l0W2ldIF4gYi0+b2JfZGlnaXRbaV07CisgICAgICAgIGJyZWFrOworICAgIGRlZmF1bHQ6CisgICAgICAgIFB5RXJyX0JhZEFyZ3VtZW50KCk7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKworICAgIC8qIENvcHkgYW55IHJlbWFpbmluZyBkaWdpdHMgb2YgYSwgaW52ZXJ0aW5nIGlmIG5lY2Vzc2FyeS4gKi8KKyAgICBpZiAob3AgPT0gJ14nICYmIG5lZ2IpCisgICAgICAgIGZvciAoOyBpIDwgc2l6ZV96OyArK2kpCisgICAgICAgICAgICB6LT5vYl9kaWdpdFtpXSA9IGEtPm9iX2RpZ2l0W2ldIF4gUHlMb25nX01BU0s7CisgICAgZWxzZSBpZiAoaSA8IHNpemVfeikKKyAgICAgICAgbWVtY3B5KCZ6LT5vYl9kaWdpdFtpXSwgJmEtPm9iX2RpZ2l0W2ldLAorICAgICAgICAgICAgICAgKHNpemVfei1pKSpzaXplb2YoZGlnaXQpKTsKKworICAgIC8qIENvbXBsZW1lbnQgcmVzdWx0IGlmIG5lZ2F0aXZlLiAqLworICAgIGlmIChuZWd6KSB7CisgICAgICAgIFB5X1NJWkUoeikgPSAtKFB5X1NJWkUoeikpOworICAgICAgICB6LT5vYl9kaWdpdFtzaXplX3pdID0gUHlMb25nX01BU0s7CisgICAgICAgIHZfY29tcGxlbWVudCh6LT5vYl9kaWdpdCwgei0+b2JfZGlnaXQsIHNpemVfeisxKTsKKyAgICB9CisKKyAgICBQeV9ERUNSRUYoYSk7CisgICAgUHlfREVDUkVGKGIpOworICAgIHJldHVybiAoUHlPYmplY3QgKilsb25nX25vcm1hbGl6ZSh6KTsKK30KKworc3RhdGljIFB5T2JqZWN0ICoKK2xvbmdfYW5kKFB5T2JqZWN0ICp2LCBQeU9iamVjdCAqdykKK3sKKyAgICBQeUxvbmdPYmplY3QgKmEsICpiOworICAgIFB5T2JqZWN0ICpjOworICAgIENPTlZFUlRfQklOT1AodiwgdywgJmEsICZiKTsKKyAgICBjID0gbG9uZ19iaXR3aXNlKGEsICcmJywgYik7CisgICAgUHlfREVDUkVGKGEpOworICAgIFB5X0RFQ1JFRihiKTsKKyAgICByZXR1cm4gYzsKK30KKworc3RhdGljIFB5T2JqZWN0ICoKK2xvbmdfeG9yKFB5T2JqZWN0ICp2LCBQeU9iamVjdCAqdykKK3sKKyAgICBQeUxvbmdPYmplY3QgKmEsICpiOworICAgIFB5T2JqZWN0ICpjOworICAgIENPTlZFUlRfQklOT1AodiwgdywgJmEsICZiKTsKKyAgICBjID0gbG9uZ19iaXR3aXNlKGEsICdeJywgYik7CisgICAgUHlfREVDUkVGKGEpOworICAgIFB5X0RFQ1JFRihiKTsKKyAgICByZXR1cm4gYzsKK30KKworc3RhdGljIFB5T2JqZWN0ICoKK2xvbmdfb3IoUHlPYmplY3QgKnYsIFB5T2JqZWN0ICp3KQoreworICAgIFB5TG9uZ09iamVjdCAqYSwgKmI7CisgICAgUHlPYmplY3QgKmM7CisgICAgQ09OVkVSVF9CSU5PUCh2LCB3LCAmYSwgJmIpOworICAgIGMgPSBsb25nX2JpdHdpc2UoYSwgJ3wnLCBiKTsKKyAgICBQeV9ERUNSRUYoYSk7CisgICAgUHlfREVDUkVGKGIpOworICAgIHJldHVybiBjOworfQorCitzdGF0aWMgaW50Citsb25nX2NvZXJjZShQeU9iamVjdCAqKnB2LCBQeU9iamVjdCAqKnB3KQoreworICAgIGlmIChQeUludF9DaGVjaygqcHcpKSB7CisgICAgICAgICpwdyA9IFB5TG9uZ19Gcm9tTG9uZyhQeUludF9BU19MT05HKCpwdykpOworICAgICAgICBpZiAoKnB3ID09IE5VTEwpCisgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgIFB5X0lOQ1JFRigqcHYpOworICAgICAgICByZXR1cm4gMDsKKyAgICB9CisgICAgZWxzZSBpZiAoUHlMb25nX0NoZWNrKCpwdykpIHsKKyAgICAgICAgUHlfSU5DUkVGKCpwdik7CisgICAgICAgIFB5X0lOQ1JFRigqcHcpOworICAgICAgICByZXR1cm4gMDsKKyAgICB9CisgICAgcmV0dXJuIDE7IC8qIENhbid0IGRvIGl0ICovCit9CisKK3N0YXRpYyBQeU9iamVjdCAqCitsb25nX2xvbmcoUHlPYmplY3QgKnYpCit7CisgICAgaWYgKFB5TG9uZ19DaGVja0V4YWN0KHYpKQorICAgICAgICBQeV9JTkNSRUYodik7CisgICAgZWxzZQorICAgICAgICB2ID0gX1B5TG9uZ19Db3B5KChQeUxvbmdPYmplY3QgKil2KTsKKyAgICByZXR1cm4gdjsKK30KKworc3RhdGljIFB5T2JqZWN0ICoKK2xvbmdfaW50KFB5T2JqZWN0ICp2KQoreworICAgIGxvbmcgeDsKKyAgICB4ID0gUHlMb25nX0FzTG9uZyh2KTsKKyAgICBpZiAoUHlFcnJfT2NjdXJyZWQoKSkgeworICAgICAgICBpZiAoUHlFcnJfRXhjZXB0aW9uTWF0Y2hlcyhQeUV4Y19PdmVyZmxvd0Vycm9yKSkgeworICAgICAgICAgICAgUHlFcnJfQ2xlYXIoKTsKKyAgICAgICAgICAgIGlmIChQeUxvbmdfQ2hlY2tFeGFjdCh2KSkgeworICAgICAgICAgICAgICAgIFB5X0lOQ1JFRih2KTsKKyAgICAgICAgICAgICAgICByZXR1cm4gdjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGVsc2UKKyAgICAgICAgICAgICAgICByZXR1cm4gX1B5TG9uZ19Db3B5KChQeUxvbmdPYmplY3QgKil2KTsKKyAgICAgICAgfQorICAgICAgICBlbHNlCisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgcmV0dXJuIFB5SW50X0Zyb21Mb25nKHgpOworfQorCitzdGF0aWMgUHlPYmplY3QgKgorbG9uZ19mbG9hdChQeU9iamVjdCAqdikKK3sKKyAgICBkb3VibGUgcmVzdWx0OworICAgIHJlc3VsdCA9IFB5TG9uZ19Bc0RvdWJsZSh2KTsKKyAgICBpZiAocmVzdWx0ID09IC0xLjAgJiYgUHlFcnJfT2NjdXJyZWQoKSkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgcmV0dXJuIFB5RmxvYXRfRnJvbURvdWJsZShyZXN1bHQpOworfQorCitzdGF0aWMgUHlPYmplY3QgKgorbG9uZ19vY3QoUHlPYmplY3QgKnYpCit7CisgICAgcmV0dXJuIF9QeUxvbmdfRm9ybWF0KHYsIDgsIDEsIDApOworfQorCitzdGF0aWMgUHlPYmplY3QgKgorbG9uZ19oZXgoUHlPYmplY3QgKnYpCit7CisgICAgcmV0dXJuIF9QeUxvbmdfRm9ybWF0KHYsIDE2LCAxLCAwKTsKK30KKworc3RhdGljIFB5T2JqZWN0ICoKK2xvbmdfc3VidHlwZV9uZXcoUHlUeXBlT2JqZWN0ICp0eXBlLCBQeU9iamVjdCAqYXJncywgUHlPYmplY3QgKmt3ZHMpOworCitzdGF0aWMgUHlPYmplY3QgKgorbG9uZ19uZXcoUHlUeXBlT2JqZWN0ICp0eXBlLCBQeU9iamVjdCAqYXJncywgUHlPYmplY3QgKmt3ZHMpCit7CisgICAgUHlPYmplY3QgKnggPSBOVUxMOworICAgIGludCBiYXNlID0gLTkwOTsgICAgICAgICAgICAgICAgICAgICAgICAgLyogdW5saWtlbHkhICovCisgICAgc3RhdGljIGNoYXIgKmt3bGlzdFtdID0geyJ4IiwgImJhc2UiLCAwfTsKKworICAgIGlmICh0eXBlICE9ICZQeUxvbmdfVHlwZSkKKyAgICAgICAgcmV0dXJuIGxvbmdfc3VidHlwZV9uZXcodHlwZSwgYXJncywga3dkcyk7IC8qIFdpbXAgb3V0ICovCisgICAgaWYgKCFQeUFyZ19QYXJzZVR1cGxlQW5kS2V5d29yZHMoYXJncywga3dkcywgInxPaTpsb25nIiwga3dsaXN0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZ4LCAmYmFzZSkpCisgICAgICAgIHJldHVybiBOVUxMOworICAgIGlmICh4ID09IE5VTEwpIHsKKyAgICAgICAgaWYgKGJhc2UgIT0gLTkwOSkgeworICAgICAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1R5cGVFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAibG9uZygpIG1pc3Npbmcgc3RyaW5nIGFyZ3VtZW50Iik7CisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gUHlMb25nX0Zyb21Mb25nKDBMKTsKKyAgICB9CisgICAgaWYgKGJhc2UgPT0gLTkwOSkKKyAgICAgICAgcmV0dXJuIFB5TnVtYmVyX0xvbmcoeCk7CisgICAgZWxzZSBpZiAoUHlTdHJpbmdfQ2hlY2soeCkpIHsKKyAgICAgICAgLyogU2luY2UgUHlMb25nX0Zyb21TdHJpbmcgZG9lc24ndCBoYXZlIGEgbGVuZ3RoIHBhcmFtZXRlciwKKyAgICAgICAgICogY2hlY2sgaGVyZSBmb3IgcG9zc2libGUgTlVMcyBpbiB0aGUgc3RyaW5nLiAqLworICAgICAgICBjaGFyICpzdHJpbmcgPSBQeVN0cmluZ19BU19TVFJJTkcoeCk7CisgICAgICAgIGlmIChzdHJsZW4oc3RyaW5nKSAhPSAoc2l6ZV90KVB5U3RyaW5nX1NpemUoeCkpIHsKKyAgICAgICAgICAgIC8qIGNyZWF0ZSBhIHJlcHIoKSBvZiB0aGUgaW5wdXQgc3RyaW5nLAorICAgICAgICAgICAgICoganVzdCBsaWtlIFB5TG9uZ19Gcm9tU3RyaW5nIGRvZXMuICovCisgICAgICAgICAgICBQeU9iamVjdCAqc3JlcHI7CisgICAgICAgICAgICBzcmVwciA9IFB5T2JqZWN0X1JlcHIoeCk7CisgICAgICAgICAgICBpZiAoc3JlcHIgPT0gTlVMTCkKKyAgICAgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgICAgIFB5RXJyX0Zvcm1hdChQeUV4Y19WYWx1ZUVycm9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICJpbnZhbGlkIGxpdGVyYWwgZm9yIGxvbmcoKSB3aXRoIGJhc2UgJWQ6ICVzIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICBiYXNlLCBQeVN0cmluZ19BU19TVFJJTkcoc3JlcHIpKTsKKyAgICAgICAgICAgIFB5X0RFQ1JFRihzcmVwcik7CisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gUHlMb25nX0Zyb21TdHJpbmcoUHlTdHJpbmdfQVNfU1RSSU5HKHgpLCBOVUxMLCBiYXNlKTsKKyAgICB9CisjaWZkZWYgUHlfVVNJTkdfVU5JQ09ERQorICAgIGVsc2UgaWYgKFB5VW5pY29kZV9DaGVjayh4KSkKKyAgICAgICAgcmV0dXJuIFB5TG9uZ19Gcm9tVW5pY29kZShQeVVuaWNvZGVfQVNfVU5JQ09ERSh4KSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQeVVuaWNvZGVfR0VUX1NJWkUoeCksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYmFzZSk7CisjZW5kaWYKKyAgICBlbHNlIHsKKyAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1R5cGVFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICJsb25nKCkgY2FuJ3QgY29udmVydCBub24tc3RyaW5nIHdpdGggZXhwbGljaXQgYmFzZSIpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9Cit9CisKKy8qIFdpbXB5LCBzbG93IGFwcHJvYWNoIHRvIHRwX25ldyBjYWxscyBmb3Igc3VidHlwZXMgb2YgbG9uZzoKKyAgIGZpcnN0IGNyZWF0ZSBhIHJlZ3VsYXIgbG9uZyBmcm9tIHdoYXRldmVyIGFyZ3VtZW50cyB3ZSBnb3QsCisgICB0aGVuIGFsbG9jYXRlIGEgc3VidHlwZSBpbnN0YW5jZSBhbmQgaW5pdGlhbGl6ZSBpdCBmcm9tCisgICB0aGUgcmVndWxhciBsb25nLiAgVGhlIHJlZ3VsYXIgbG9uZyBpcyB0aGVuIHRocm93biBhd2F5LgorKi8KK3N0YXRpYyBQeU9iamVjdCAqCitsb25nX3N1YnR5cGVfbmV3KFB5VHlwZU9iamVjdCAqdHlwZSwgUHlPYmplY3QgKmFyZ3MsIFB5T2JqZWN0ICprd2RzKQoreworICAgIFB5TG9uZ09iamVjdCAqdG1wLCAqbmV3b2JqOworICAgIFB5X3NzaXplX3QgaSwgbjsKKworICAgIGFzc2VydChQeVR5cGVfSXNTdWJ0eXBlKHR5cGUsICZQeUxvbmdfVHlwZSkpOworICAgIHRtcCA9IChQeUxvbmdPYmplY3QgKilsb25nX25ldygmUHlMb25nX1R5cGUsIGFyZ3MsIGt3ZHMpOworICAgIGlmICh0bXAgPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgYXNzZXJ0KFB5TG9uZ19DaGVja0V4YWN0KHRtcCkpOworICAgIG4gPSBQeV9TSVpFKHRtcCk7CisgICAgaWYgKG4gPCAwKQorICAgICAgICBuID0gLW47CisgICAgbmV3b2JqID0gKFB5TG9uZ09iamVjdCAqKXR5cGUtPnRwX2FsbG9jKHR5cGUsIG4pOworICAgIGlmIChuZXdvYmogPT0gTlVMTCkgeworICAgICAgICBQeV9ERUNSRUYodG1wKTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIGFzc2VydChQeUxvbmdfQ2hlY2sobmV3b2JqKSk7CisgICAgUHlfU0laRShuZXdvYmopID0gUHlfU0laRSh0bXApOworICAgIGZvciAoaSA9IDA7IGkgPCBuOyBpKyspCisgICAgICAgIG5ld29iai0+b2JfZGlnaXRbaV0gPSB0bXAtPm9iX2RpZ2l0W2ldOworICAgIFB5X0RFQ1JFRih0bXApOworICAgIHJldHVybiAoUHlPYmplY3QgKiluZXdvYmo7Cit9CisKK3N0YXRpYyBQeU9iamVjdCAqCitsb25nX2dldG5ld2FyZ3MoUHlMb25nT2JqZWN0ICp2KQoreworICAgIHJldHVybiBQeV9CdWlsZFZhbHVlKCIoTikiLCBfUHlMb25nX0NvcHkodikpOworfQorCitzdGF0aWMgUHlPYmplY3QgKgorbG9uZ19nZXQwKFB5TG9uZ09iamVjdCAqdiwgdm9pZCAqY29udGV4dCkgeworICAgIHJldHVybiBQeUxvbmdfRnJvbUxvbmcoMEwpOworfQorCitzdGF0aWMgUHlPYmplY3QgKgorbG9uZ19nZXQxKFB5TG9uZ09iamVjdCAqdiwgdm9pZCAqY29udGV4dCkgeworICAgIHJldHVybiBQeUxvbmdfRnJvbUxvbmcoMUwpOworfQorCitzdGF0aWMgUHlPYmplY3QgKgorbG9uZ19fZm9ybWF0X18oUHlPYmplY3QgKnNlbGYsIFB5T2JqZWN0ICphcmdzKQoreworICAgIFB5T2JqZWN0ICpmb3JtYXRfc3BlYzsKKworICAgIGlmICghUHlBcmdfUGFyc2VUdXBsZShhcmdzLCAiTzpfX2Zvcm1hdF9fIiwgJmZvcm1hdF9zcGVjKSkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgaWYgKFB5Qnl0ZXNfQ2hlY2soZm9ybWF0X3NwZWMpKQorICAgICAgICByZXR1cm4gX1B5TG9uZ19Gb3JtYXRBZHZhbmNlZChzZWxmLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQeUJ5dGVzX0FTX1NUUklORyhmb3JtYXRfc3BlYyksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFB5Qnl0ZXNfR0VUX1NJWkUoZm9ybWF0X3NwZWMpKTsKKyAgICBpZiAoUHlVbmljb2RlX0NoZWNrKGZvcm1hdF9zcGVjKSkgeworICAgICAgICAvKiBDb252ZXJ0IGZvcm1hdF9zcGVjIHRvIGEgc3RyICovCisgICAgICAgIFB5T2JqZWN0ICpyZXN1bHQ7CisgICAgICAgIFB5T2JqZWN0ICpzdHJfc3BlYyA9IFB5T2JqZWN0X1N0cihmb3JtYXRfc3BlYyk7CisKKyAgICAgICAgaWYgKHN0cl9zcGVjID09IE5VTEwpCisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKworICAgICAgICByZXN1bHQgPSBfUHlMb25nX0Zvcm1hdEFkdmFuY2VkKHNlbGYsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHlCeXRlc19BU19TVFJJTkcoc3RyX3NwZWMpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFB5Qnl0ZXNfR0VUX1NJWkUoc3RyX3NwZWMpKTsKKworICAgICAgICBQeV9ERUNSRUYoc3RyX3NwZWMpOworICAgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKyAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfVHlwZUVycm9yLCAiX19mb3JtYXRfXyByZXF1aXJlcyBzdHIgb3IgdW5pY29kZSIpOworICAgIHJldHVybiBOVUxMOworfQorCitzdGF0aWMgUHlPYmplY3QgKgorbG9uZ19zaXplb2YoUHlMb25nT2JqZWN0ICp2KQoreworICAgIFB5X3NzaXplX3QgcmVzOworCisgICAgcmVzID0gdi0+b2JfdHlwZS0+dHBfYmFzaWNzaXplICsgQUJTKFB5X1NJWkUodikpKnNpemVvZihkaWdpdCk7CisgICAgcmV0dXJuIFB5SW50X0Zyb21Tc2l6ZV90KHJlcyk7Cit9CisKK3N0YXRpYyBQeU9iamVjdCAqCitsb25nX2JpdF9sZW5ndGgoUHlMb25nT2JqZWN0ICp2KQoreworICAgIFB5TG9uZ09iamVjdCAqcmVzdWx0LCAqeCwgKnk7CisgICAgUHlfc3NpemVfdCBuZGlnaXRzLCBtc2RfYml0cyA9IDA7CisgICAgZGlnaXQgbXNkOworCisgICAgYXNzZXJ0KHYgIT0gTlVMTCk7CisgICAgYXNzZXJ0KFB5TG9uZ19DaGVjayh2KSk7CisKKyAgICBuZGlnaXRzID0gQUJTKFB5X1NJWkUodikpOworICAgIGlmIChuZGlnaXRzID09IDApCisgICAgICAgIHJldHVybiBQeUludF9Gcm9tTG9uZygwKTsKKworICAgIG1zZCA9IHYtPm9iX2RpZ2l0W25kaWdpdHMtMV07CisgICAgd2hpbGUgKG1zZCA+PSAzMikgeworICAgICAgICBtc2RfYml0cyArPSA2OworICAgICAgICBtc2QgPj49IDY7CisgICAgfQorICAgIG1zZF9iaXRzICs9IChsb25nKShCaXRMZW5ndGhUYWJsZVttc2RdKTsKKworICAgIGlmIChuZGlnaXRzIDw9IFBZX1NTSVpFX1RfTUFYL1B5TG9uZ19TSElGVCkKKyAgICAgICAgcmV0dXJuIFB5SW50X0Zyb21Tc2l6ZV90KChuZGlnaXRzLTEpKlB5TG9uZ19TSElGVCArIG1zZF9iaXRzKTsKKworICAgIC8qIGV4cHJlc3Npb24gYWJvdmUgbWF5IG92ZXJmbG93OyB1c2UgUHl0aG9uIGludGVnZXJzIGluc3RlYWQgKi8KKyAgICByZXN1bHQgPSAoUHlMb25nT2JqZWN0ICopUHlMb25nX0Zyb21Tc2l6ZV90KG5kaWdpdHMgLSAxKTsKKyAgICBpZiAocmVzdWx0ID09IE5VTEwpCisgICAgICAgIHJldHVybiBOVUxMOworICAgIHggPSAoUHlMb25nT2JqZWN0ICopUHlMb25nX0Zyb21Mb25nKFB5TG9uZ19TSElGVCk7CisgICAgaWYgKHggPT0gTlVMTCkKKyAgICAgICAgZ290byBlcnJvcjsKKyAgICB5ID0gKFB5TG9uZ09iamVjdCAqKWxvbmdfbXVsKHJlc3VsdCwgeCk7CisgICAgUHlfREVDUkVGKHgpOworICAgIGlmICh5ID09IE5VTEwpCisgICAgICAgIGdvdG8gZXJyb3I7CisgICAgUHlfREVDUkVGKHJlc3VsdCk7CisgICAgcmVzdWx0ID0geTsKKworICAgIHggPSAoUHlMb25nT2JqZWN0ICopUHlMb25nX0Zyb21Mb25nKChsb25nKW1zZF9iaXRzKTsKKyAgICBpZiAoeCA9PSBOVUxMKQorICAgICAgICBnb3RvIGVycm9yOworICAgIHkgPSAoUHlMb25nT2JqZWN0ICopbG9uZ19hZGQocmVzdWx0LCB4KTsKKyAgICBQeV9ERUNSRUYoeCk7CisgICAgaWYgKHkgPT0gTlVMTCkKKyAgICAgICAgZ290byBlcnJvcjsKKyAgICBQeV9ERUNSRUYocmVzdWx0KTsKKyAgICByZXN1bHQgPSB5OworCisgICAgcmV0dXJuIChQeU9iamVjdCAqKXJlc3VsdDsKKworICBlcnJvcjoKKyAgICBQeV9ERUNSRUYocmVzdWx0KTsKKyAgICByZXR1cm4gTlVMTDsKK30KKworUHlEb2NfU1RSVkFSKGxvbmdfYml0X2xlbmd0aF9kb2MsCisibG9uZy5iaXRfbGVuZ3RoKCkgLT4gaW50IG9yIGxvbmdcblwKK1xuXAorTnVtYmVyIG9mIGJpdHMgbmVjZXNzYXJ5IHRvIHJlcHJlc2VudCBzZWxmIGluIGJpbmFyeS5cblwKKz4+PiBiaW4oMzdMKVxuXAorJzBiMTAwMTAxJ1xuXAorPj4+ICgzN0wpLmJpdF9sZW5ndGgoKVxuXAorNiIpOworCisjaWYgMAorc3RhdGljIFB5T2JqZWN0ICoKK2xvbmdfaXNfZmluaXRlKFB5T2JqZWN0ICp2KQoreworICAgIFB5X1JFVFVSTl9UUlVFOworfQorI2VuZGlmCisKK3N0YXRpYyBQeU1ldGhvZERlZiBsb25nX21ldGhvZHNbXSA9IHsKKyAgICB7ImNvbmp1Z2F0ZSIsICAgICAgIChQeUNGdW5jdGlvbilsb25nX2xvbmcsIE1FVEhfTk9BUkdTLAorICAgICAiUmV0dXJucyBzZWxmLCB0aGUgY29tcGxleCBjb25qdWdhdGUgb2YgYW55IGxvbmcuIn0sCisgICAgeyJiaXRfbGVuZ3RoIiwgICAgICAoUHlDRnVuY3Rpb24pbG9uZ19iaXRfbGVuZ3RoLCBNRVRIX05PQVJHUywKKyAgICAgbG9uZ19iaXRfbGVuZ3RoX2RvY30sCisjaWYgMAorICAgIHsiaXNfZmluaXRlIiwgICAgICAgKFB5Q0Z1bmN0aW9uKWxvbmdfaXNfZmluaXRlLCAgICBNRVRIX05PQVJHUywKKyAgICAgIlJldHVybnMgYWx3YXlzIFRydWUuIn0sCisjZW5kaWYKKyAgICB7Il9fdHJ1bmNfXyIsICAgICAgIChQeUNGdW5jdGlvbilsb25nX2xvbmcsIE1FVEhfTk9BUkdTLAorICAgICAiVHJ1bmNhdGluZyBhbiBJbnRlZ3JhbCByZXR1cm5zIGl0c2VsZi4ifSwKKyAgICB7Il9fZ2V0bmV3YXJnc19fIiwgICAgICAgICAgKFB5Q0Z1bmN0aW9uKWxvbmdfZ2V0bmV3YXJncywgICBNRVRIX05PQVJHU30sCisgICAgeyJfX2Zvcm1hdF9fIiwgKFB5Q0Z1bmN0aW9uKWxvbmdfX2Zvcm1hdF9fLCBNRVRIX1ZBUkFSR1N9LAorICAgIHsiX19zaXplb2ZfXyIsICAgICAgKFB5Q0Z1bmN0aW9uKWxvbmdfc2l6ZW9mLCBNRVRIX05PQVJHUywKKyAgICAgIlJldHVybnMgc2l6ZSBpbiBtZW1vcnksIGluIGJ5dGVzIn0sCisgICAge05VTEwsICAgICAgICAgICAgICBOVUxMfSAgICAgICAgICAgLyogc2VudGluZWwgKi8KK307CisKK3N0YXRpYyBQeUdldFNldERlZiBsb25nX2dldHNldFtdID0geworICAgIHsicmVhbCIsCisgICAgIChnZXR0ZXIpbG9uZ19sb25nLCAoc2V0dGVyKU5VTEwsCisgICAgICJ0aGUgcmVhbCBwYXJ0IG9mIGEgY29tcGxleCBudW1iZXIiLAorICAgICBOVUxMfSwKKyAgICB7ImltYWciLAorICAgICAoZ2V0dGVyKWxvbmdfZ2V0MCwgKHNldHRlcilOVUxMLAorICAgICAidGhlIGltYWdpbmFyeSBwYXJ0IG9mIGEgY29tcGxleCBudW1iZXIiLAorICAgICBOVUxMfSwKKyAgICB7Im51bWVyYXRvciIsCisgICAgIChnZXR0ZXIpbG9uZ19sb25nLCAoc2V0dGVyKU5VTEwsCisgICAgICJ0aGUgbnVtZXJhdG9yIG9mIGEgcmF0aW9uYWwgbnVtYmVyIGluIGxvd2VzdCB0ZXJtcyIsCisgICAgIE5VTEx9LAorICAgIHsiZGVub21pbmF0b3IiLAorICAgICAoZ2V0dGVyKWxvbmdfZ2V0MSwgKHNldHRlcilOVUxMLAorICAgICAidGhlIGRlbm9taW5hdG9yIG9mIGEgcmF0aW9uYWwgbnVtYmVyIGluIGxvd2VzdCB0ZXJtcyIsCisgICAgIE5VTEx9LAorICAgIHtOVUxMfSAgLyogU2VudGluZWwgKi8KK307CisKK1B5RG9jX1NUUlZBUihsb25nX2RvYywKKyJsb25nKHg9MCkgLT4gbG9uZ1xuXAorbG9uZyh4LCBiYXNlPTEwKSAtPiBsb25nXG5cCitcblwKK0NvbnZlcnQgYSBudW1iZXIgb3Igc3RyaW5nIHRvIGEgbG9uZyBpbnRlZ2VyLCBvciByZXR1cm4gMEwgaWYgbm8gYXJndW1lbnRzXG5cCithcmUgZ2l2ZW4uICBJZiB4IGlzIGZsb2F0aW5nIHBvaW50LCB0aGUgY29udmVyc2lvbiB0cnVuY2F0ZXMgdG93YXJkcyB6ZXJvLlxuXAorXG5cCitJZiB4IGlzIG5vdCBhIG51bWJlciBvciBpZiBiYXNlIGlzIGdpdmVuLCB0aGVuIHggbXVzdCBiZSBhIHN0cmluZyBvclxuXAorVW5pY29kZSBvYmplY3QgcmVwcmVzZW50aW5nIGFuIGludGVnZXIgbGl0ZXJhbCBpbiB0aGUgZ2l2ZW4gYmFzZS4gIFRoZVxuXAorbGl0ZXJhbCBjYW4gYmUgcHJlY2VkZWQgYnkgJysnIG9yICctJyBhbmQgYmUgc3Vycm91bmRlZCBieSB3aGl0ZXNwYWNlLlxuXAorVGhlIGJhc2UgZGVmYXVsdHMgdG8gMTAuICBWYWxpZCBiYXNlcyBhcmUgMCBhbmQgMi0zNi4gIEJhc2UgMCBtZWFucyB0b1xuXAoraW50ZXJwcmV0IHRoZSBiYXNlIGZyb20gdGhlIHN0cmluZyBhcyBhbiBpbnRlZ2VyIGxpdGVyYWwuXG5cCis+Pj4gaW50KCcwYjEwMCcsIGJhc2U9MClcblwKKzRMIik7CisKK3N0YXRpYyBQeU51bWJlck1ldGhvZHMgbG9uZ19hc19udW1iZXIgPSB7CisgICAgKGJpbmFyeWZ1bmMpbG9uZ19hZGQsICAgICAgIC8qbmJfYWRkKi8KKyAgICAoYmluYXJ5ZnVuYylsb25nX3N1YiwgICAgICAgLypuYl9zdWJ0cmFjdCovCisgICAgKGJpbmFyeWZ1bmMpbG9uZ19tdWwsICAgICAgIC8qbmJfbXVsdGlwbHkqLworICAgIGxvbmdfY2xhc3NpY19kaXYsICAgICAgICAgICAvKm5iX2RpdmlkZSovCisgICAgbG9uZ19tb2QsICAgICAgICAgICAgICAgICAgIC8qbmJfcmVtYWluZGVyKi8KKyAgICBsb25nX2Rpdm1vZCwgICAgICAgICAgICAgICAgLypuYl9kaXZtb2QqLworICAgIGxvbmdfcG93LCAgICAgICAgICAgICAgICAgICAvKm5iX3Bvd2VyKi8KKyAgICAodW5hcnlmdW5jKWxvbmdfbmVnLCAgICAgICAgLypuYl9uZWdhdGl2ZSovCisgICAgKHVuYXJ5ZnVuYylsb25nX2xvbmcsICAgICAgIC8qdHBfcG9zaXRpdmUqLworICAgICh1bmFyeWZ1bmMpbG9uZ19hYnMsICAgICAgICAvKnRwX2Fic29sdXRlKi8KKyAgICAoaW5xdWlyeSlsb25nX25vbnplcm8sICAgICAgLyp0cF9ub256ZXJvKi8KKyAgICAodW5hcnlmdW5jKWxvbmdfaW52ZXJ0LCAgICAgLypuYl9pbnZlcnQqLworICAgIGxvbmdfbHNoaWZ0LCAgICAgICAgICAgICAgICAvKm5iX2xzaGlmdCovCisgICAgKGJpbmFyeWZ1bmMpbG9uZ19yc2hpZnQsICAgIC8qbmJfcnNoaWZ0Ki8KKyAgICBsb25nX2FuZCwgICAgICAgICAgICAgICAgICAgLypuYl9hbmQqLworICAgIGxvbmdfeG9yLCAgICAgICAgICAgICAgICAgICAvKm5iX3hvciovCisgICAgbG9uZ19vciwgICAgICAgICAgICAgICAgICAgIC8qbmJfb3IqLworICAgIGxvbmdfY29lcmNlLCAgICAgICAgICAgICAgICAvKm5iX2NvZXJjZSovCisgICAgbG9uZ19pbnQsICAgICAgICAgICAgICAgICAgIC8qbmJfaW50Ki8KKyAgICBsb25nX2xvbmcsICAgICAgICAgICAgICAgICAgLypuYl9sb25nKi8KKyAgICBsb25nX2Zsb2F0LCAgICAgICAgICAgICAgICAgLypuYl9mbG9hdCovCisgICAgbG9uZ19vY3QsICAgICAgICAgICAgICAgICAgIC8qbmJfb2N0Ki8KKyAgICBsb25nX2hleCwgICAgICAgICAgICAgICAgICAgLypuYl9oZXgqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBuYl9pbnBsYWNlX2FkZCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBuYl9pbnBsYWNlX3N1YnRyYWN0ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIG5iX2lucGxhY2VfbXVsdGlwbHkgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgLyogbmJfaW5wbGFjZV9kaXZpZGUgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgLyogbmJfaW5wbGFjZV9yZW1haW5kZXIgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgLyogbmJfaW5wbGFjZV9wb3dlciAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBuYl9pbnBsYWNlX2xzaGlmdCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBuYl9pbnBsYWNlX3JzaGlmdCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBuYl9pbnBsYWNlX2FuZCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBuYl9pbnBsYWNlX3hvciAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBuYl9pbnBsYWNlX29yICovCisgICAgbG9uZ19kaXYsICAgICAgICAgICAgICAgICAgIC8qIG5iX2Zsb29yX2RpdmlkZSAqLworICAgIGxvbmdfdHJ1ZV9kaXZpZGUsICAgICAgICAgICAvKiBuYl90cnVlX2RpdmlkZSAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBuYl9pbnBsYWNlX2Zsb29yX2RpdmlkZSAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBuYl9pbnBsYWNlX3RydWVfZGl2aWRlICovCisgICAgbG9uZ19sb25nLCAgICAgICAgICAgICAgICAgIC8qIG5iX2luZGV4ICovCit9OworCitQeVR5cGVPYmplY3QgUHlMb25nX1R5cGUgPSB7CisgICAgUHlPYmplY3RfSEVBRF9JTklUKCZQeVR5cGVfVHlwZSkKKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIG9iX3NpemUgKi8KKyAgICAibG9uZyIsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX25hbWUgKi8KKyAgICBvZmZzZXRvZihQeUxvbmdPYmplY3QsIG9iX2RpZ2l0KSwgICAgICAgICAgIC8qIHRwX2Jhc2ljc2l6ZSAqLworICAgIHNpemVvZihkaWdpdCksICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfaXRlbXNpemUgKi8KKyAgICBsb25nX2RlYWxsb2MsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2RlYWxsb2MgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3ByaW50ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9nZXRhdHRyICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9zZXRhdHRyICovCisgICAgKGNtcGZ1bmMpbG9uZ19jb21wYXJlLCAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9jb21wYXJlICovCisgICAgbG9uZ19yZXByLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9yZXByICovCisgICAgJmxvbmdfYXNfbnVtYmVyLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9hc19udW1iZXIgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2FzX3NlcXVlbmNlICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9hc19tYXBwaW5nICovCisgICAgKGhhc2hmdW5jKWxvbmdfaGFzaCwgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9oYXNoICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9jYWxsICovCisgICAgbG9uZ19zdHIsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9zdHIgKi8KKyAgICBQeU9iamVjdF9HZW5lcmljR2V0QXR0ciwgICAgICAgICAgICAgICAgICAgIC8qIHRwX2dldGF0dHJvICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9zZXRhdHRybyAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfYXNfYnVmZmVyICovCisgICAgUHlfVFBGTEFHU19ERUZBVUxUIHwgUHlfVFBGTEFHU19DSEVDS1RZUEVTIHwKKyAgICAgICAgUHlfVFBGTEFHU19CQVNFVFlQRSB8IFB5X1RQRkxBR1NfTE9OR19TVUJDTEFTUywgLyogdHBfZmxhZ3MgKi8KKyAgICBsb25nX2RvYywgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2RvYyAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfdHJhdmVyc2UgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2NsZWFyICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9yaWNoY29tcGFyZSAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfd2Vha2xpc3RvZmZzZXQgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2l0ZXIgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2l0ZXJuZXh0ICovCisgICAgbG9uZ19tZXRob2RzLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9tZXRob2RzICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9tZW1iZXJzICovCisgICAgbG9uZ19nZXRzZXQsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9nZXRzZXQgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2Jhc2UgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2RpY3QgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2Rlc2NyX2dldCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZGVzY3Jfc2V0ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9kaWN0b2Zmc2V0ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9pbml0ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9hbGxvYyAqLworICAgIGxvbmdfbmV3LCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfbmV3ICovCisgICAgUHlPYmplY3RfRGVsLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9mcmVlICovCit9OworCitzdGF0aWMgUHlUeXBlT2JqZWN0IExvbmdfSW5mb1R5cGU7CisKK1B5RG9jX1NUUlZBUihsb25nX2luZm9fX2RvY19fLAorInN5cy5sb25nX2luZm9cblwKK1xuXAorQSBzdHJ1Y3Qgc2VxdWVuY2UgdGhhdCBob2xkcyBpbmZvcm1hdGlvbiBhYm91dCBQeXRob24nc1xuXAoraW50ZXJuYWwgcmVwcmVzZW50YXRpb24gb2YgaW50ZWdlcnMuICBUaGUgYXR0cmlidXRlcyBhcmUgcmVhZCBvbmx5LiIpOworCitzdGF0aWMgUHlTdHJ1Y3RTZXF1ZW5jZV9GaWVsZCBsb25nX2luZm9fZmllbGRzW10gPSB7CisgICAgeyJiaXRzX3Blcl9kaWdpdCIsICJzaXplIG9mIGEgZGlnaXQgaW4gYml0cyJ9LAorICAgIHsic2l6ZW9mX2RpZ2l0IiwgInNpemUgaW4gYnl0ZXMgb2YgdGhlIEMgdHlwZSB1c2VkIHRvIHJlcHJlc2VudCBhIGRpZ2l0In0sCisgICAge05VTEwsIE5VTEx9Cit9OworCitzdGF0aWMgUHlTdHJ1Y3RTZXF1ZW5jZV9EZXNjIGxvbmdfaW5mb19kZXNjID0geworICAgICJzeXMubG9uZ19pbmZvIiwgICAvKiBuYW1lICovCisgICAgbG9uZ19pbmZvX19kb2NfXywgIC8qIGRvYyAqLworICAgIGxvbmdfaW5mb19maWVsZHMsICAvKiBmaWVsZHMgKi8KKyAgICAyICAgICAgICAgICAgICAgICAgLyogbnVtYmVyIG9mIGZpZWxkcyAqLworfTsKKworUHlPYmplY3QgKgorUHlMb25nX0dldEluZm8odm9pZCkKK3sKKyAgICBQeU9iamVjdCogbG9uZ19pbmZvOworICAgIGludCBmaWVsZCA9IDA7CisgICAgbG9uZ19pbmZvID0gUHlTdHJ1Y3RTZXF1ZW5jZV9OZXcoJkxvbmdfSW5mb1R5cGUpOworICAgIGlmIChsb25nX2luZm8gPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgUHlTdHJ1Y3RTZXF1ZW5jZV9TRVRfSVRFTShsb25nX2luZm8sIGZpZWxkKyssCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQeUludF9Gcm9tTG9uZyhQeUxvbmdfU0hJRlQpKTsKKyAgICBQeVN0cnVjdFNlcXVlbmNlX1NFVF9JVEVNKGxvbmdfaW5mbywgZmllbGQrKywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFB5SW50X0Zyb21Mb25nKHNpemVvZihkaWdpdCkpKTsKKyAgICBpZiAoUHlFcnJfT2NjdXJyZWQoKSkgeworICAgICAgICBQeV9DTEVBUihsb25nX2luZm8pOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgcmV0dXJuIGxvbmdfaW5mbzsKK30KKworaW50CitfUHlMb25nX0luaXQodm9pZCkKK3sKKyAgICAvKiBpbml0aWFsaXplIGxvbmdfaW5mbyAqLworICAgIGlmIChMb25nX0luZm9UeXBlLnRwX25hbWUgPT0gMCkKKyAgICAgICAgUHlTdHJ1Y3RTZXF1ZW5jZV9Jbml0VHlwZSgmTG9uZ19JbmZvVHlwZSwgJmxvbmdfaW5mb19kZXNjKTsKKyAgICByZXR1cm4gMTsKK30KZGlmZiAtLWdpdCBhL1B5dGhvbi0yLjcuNS9PYmplY3RzL21lbW9yeW9iamVjdC5jIGIvUHl0aG9uLTIuNy41L09iamVjdHMvbWVtb3J5b2JqZWN0LmMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMmJhYzI2NgotLS0gL2Rldi9udWxsCisrKyBiL1B5dGhvbi0yLjcuNS9PYmplY3RzL21lbW9yeW9iamVjdC5jCkBAIC0wLDAgKzEsODQyIEBACisKKy8qIE1lbW9yeXZpZXcgb2JqZWN0IGltcGxlbWVudGF0aW9uICovCisKKyNpbmNsdWRlICJQeXRob24uaCIKKworc3RhdGljIFB5X3NzaXplX3QKK2dldF9zaGFwZTAoUHlfYnVmZmVyICpidWYpCit7CisgICAgaWYgKGJ1Zi0+c2hhcGUgIT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIGJ1Zi0+c2hhcGVbMF07CisgICAgaWYgKGJ1Zi0+bmRpbSA9PSAwKQorICAgICAgICByZXR1cm4gMTsKKyAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfVHlwZUVycm9yLAorICAgICAgICAiZXhwb3J0ZWQgYnVmZmVyIGRvZXMgbm90IGhhdmUgYW55IHNoYXBlIGluZm9ybWF0aW9uIGFzc29jaWF0ZWQgIgorICAgICAgICAidG8gaXQiKTsKKyAgICByZXR1cm4gLTE7Cit9CisKK3N0YXRpYyB2b2lkCitkdXBfYnVmZmVyKFB5X2J1ZmZlciAqZGVzdCwgUHlfYnVmZmVyICpzcmMpCit7CisgICAgKmRlc3QgPSAqc3JjOworICAgIGlmIChzcmMtPm5kaW0gPT0gMSAmJiBzcmMtPnNoYXBlICE9IE5VTEwpIHsKKyAgICAgICAgZGVzdC0+c2hhcGUgPSAmKGRlc3QtPnNtYWxsdGFibGVbMF0pOworICAgICAgICBkZXN0LT5zaGFwZVswXSA9IGdldF9zaGFwZTAoc3JjKTsKKyAgICB9CisgICAgaWYgKHNyYy0+bmRpbSA9PSAxICYmIHNyYy0+c3RyaWRlcyAhPSBOVUxMKSB7CisgICAgICAgIGRlc3QtPnN0cmlkZXMgPSAmKGRlc3QtPnNtYWxsdGFibGVbMV0pOworICAgICAgICBkZXN0LT5zdHJpZGVzWzBdID0gc3JjLT5zdHJpZGVzWzBdOworICAgIH0KK30KKworc3RhdGljIGludAorbWVtb3J5X2dldGJ1ZihQeU1lbW9yeVZpZXdPYmplY3QgKnNlbGYsIFB5X2J1ZmZlciAqdmlldywgaW50IGZsYWdzKQoreworICAgIGludCByZXMgPSAwOworICAgIGlmIChzZWxmLT52aWV3Lm9iaiAhPSBOVUxMKQorICAgICAgICByZXMgPSBQeU9iamVjdF9HZXRCdWZmZXIoc2VsZi0+dmlldy5vYmosIHZpZXcsIGZsYWdzKTsKKyAgICBpZiAodmlldykKKyAgICAgICAgZHVwX2J1ZmZlcih2aWV3LCAmc2VsZi0+dmlldyk7CisgICAgcmV0dXJuIHJlczsKK30KKworc3RhdGljIHZvaWQKK21lbW9yeV9yZWxlYXNlYnVmKFB5TWVtb3J5Vmlld09iamVjdCAqc2VsZiwgUHlfYnVmZmVyICp2aWV3KQoreworICAgIFB5QnVmZmVyX1JlbGVhc2Uodmlldyk7Cit9CisKK1B5RG9jX1NUUlZBUihtZW1vcnlfZG9jLAorIm1lbW9yeXZpZXcob2JqZWN0KVxuXAorXG5cCitDcmVhdGUgYSBuZXcgbWVtb3J5dmlldyBvYmplY3Qgd2hpY2ggcmVmZXJlbmNlcyB0aGUgZ2l2ZW4gb2JqZWN0LiIpOworCitQeU9iamVjdCAqCitQeU1lbW9yeVZpZXdfRnJvbUJ1ZmZlcihQeV9idWZmZXIgKmluZm8pCit7CisgICAgUHlNZW1vcnlWaWV3T2JqZWN0ICptdmlldzsKKworICAgIG12aWV3ID0gKFB5TWVtb3J5Vmlld09iamVjdCAqKQorICAgICAgICBQeU9iamVjdF9HQ19OZXcoUHlNZW1vcnlWaWV3T2JqZWN0LCAmUHlNZW1vcnlWaWV3X1R5cGUpOworICAgIGlmIChtdmlldyA9PSBOVUxMKQorICAgICAgICByZXR1cm4gTlVMTDsKKyAgICBtdmlldy0+YmFzZSA9IE5VTEw7CisgICAgZHVwX2J1ZmZlcigmbXZpZXctPnZpZXcsIGluZm8pOworICAgIC8qIE5PVEU6IG12aWV3LT52aWV3Lm9iaiBzaG91bGQgYWxyZWFkeSBoYXZlIGJlZW4gaW5jcmVmJ2VkIGFzCisgICAgICAgcGFydCBvZiBQeUJ1ZmZlcl9GaWxsSW5mbygpLiAqLworICAgIF9QeU9iamVjdF9HQ19UUkFDSyhtdmlldyk7CisgICAgcmV0dXJuIChQeU9iamVjdCAqKW12aWV3OworfQorCitQeU9iamVjdCAqCitQeU1lbW9yeVZpZXdfRnJvbU9iamVjdChQeU9iamVjdCAqYmFzZSkKK3sKKyAgICBQeU1lbW9yeVZpZXdPYmplY3QgKm12aWV3OworICAgIFB5X2J1ZmZlciB2aWV3OworCisgICAgaWYgKCFQeU9iamVjdF9DaGVja0J1ZmZlcihiYXNlKSkgeworICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfVHlwZUVycm9yLAorICAgICAgICAgICAgImNhbm5vdCBtYWtlIG1lbW9yeSB2aWV3IGJlY2F1c2Ugb2JqZWN0IGRvZXMgIgorICAgICAgICAgICAgIm5vdCBoYXZlIHRoZSBidWZmZXIgaW50ZXJmYWNlIik7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKworICAgIGlmIChQeU9iamVjdF9HZXRCdWZmZXIoYmFzZSwgJnZpZXcsIFB5QlVGX0ZVTExfUk8pIDwgMCkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisKKyAgICBtdmlldyA9IChQeU1lbW9yeVZpZXdPYmplY3QgKilQeU1lbW9yeVZpZXdfRnJvbUJ1ZmZlcigmdmlldyk7CisgICAgaWYgKG12aWV3ID09IE5VTEwpIHsKKyAgICAgICAgUHlCdWZmZXJfUmVsZWFzZSgmdmlldyk7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKworICAgIG12aWV3LT5iYXNlID0gYmFzZTsKKyAgICBQeV9JTkNSRUYoYmFzZSk7CisgICAgcmV0dXJuIChQeU9iamVjdCAqKW12aWV3OworfQorCitzdGF0aWMgUHlPYmplY3QgKgorbWVtb3J5X25ldyhQeVR5cGVPYmplY3QgKnN1YnR5cGUsIFB5T2JqZWN0ICphcmdzLCBQeU9iamVjdCAqa3dkcykKK3sKKyAgICBQeU9iamVjdCAqb2JqOworICAgIHN0YXRpYyBjaGFyICprd2xpc3RbXSA9IHsib2JqZWN0IiwgMH07CisKKyAgICBpZiAoIVB5QXJnX1BhcnNlVHVwbGVBbmRLZXl3b3JkcyhhcmdzLCBrd2RzLCAiTzptZW1vcnl2aWV3Iiwga3dsaXN0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZvYmopKSB7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKworICAgIHJldHVybiBQeU1lbW9yeVZpZXdfRnJvbU9iamVjdChvYmopOworfQorCisKK3N0YXRpYyB2b2lkCitfc3RyaWRlZF9jb3B5X25kKGNoYXIgKmRlc3QsIGNoYXIgKnNyYywgaW50IG5kLCBQeV9zc2l6ZV90ICpzaGFwZSwKKyAgICAgICAgICAgICAgICAgUHlfc3NpemVfdCAqc3RyaWRlcywgUHlfc3NpemVfdCBpdGVtc2l6ZSwgY2hhciBmb3J0KQoreworICAgIGludCBrOworICAgIFB5X3NzaXplX3Qgb3V0c3RyaWRlOworCisgICAgaWYgKG5kPT0wKSB7CisgICAgICAgIG1lbWNweShkZXN0LCBzcmMsIGl0ZW1zaXplKTsKKyAgICB9CisgICAgZWxzZSBpZiAobmQgPT0gMSkgeworICAgICAgICBmb3IgKGsgPSAwOyBrPHNoYXBlWzBdOyBrKyspIHsKKyAgICAgICAgICAgIG1lbWNweShkZXN0LCBzcmMsIGl0ZW1zaXplKTsKKyAgICAgICAgICAgIGRlc3QgKz0gaXRlbXNpemU7CisgICAgICAgICAgICBzcmMgKz0gc3RyaWRlc1swXTsKKyAgICAgICAgfQorICAgIH0KKyAgICBlbHNlIHsKKyAgICAgICAgaWYgKGZvcnQgPT0gJ0YnKSB7CisgICAgICAgICAgICAvKiBDb3B5IGZpcnN0IGRpbWVuc2lvbiBmaXJzdCwKKyAgICAgICAgICAgICAgIHNlY29uZCBkaW1lbnNpb24gc2Vjb25kLCBldGMuLi4KKyAgICAgICAgICAgICAgIFNldCB1cCB0aGUgcmVjdXJzaXZlIGxvb3AgYmFja3dhcmRzIHNvIHRoYXQgZmluYWwKKyAgICAgICAgICAgICAgIGRpbWVuc2lvbiBpcyBhY3R1YWxseSBjb3BpZWQgbGFzdC4KKyAgICAgICAgICAgICovCisgICAgICAgICAgICBvdXRzdHJpZGUgPSBpdGVtc2l6ZTsKKyAgICAgICAgICAgIGZvciAoaz0xOyBrPG5kLTE7aysrKSB7CisgICAgICAgICAgICAgICAgb3V0c3RyaWRlICo9IHNoYXBlW2tdOworICAgICAgICAgICAgfQorICAgICAgICAgICAgZm9yIChrPTA7IGs8c2hhcGVbbmQtMV07IGsrKykgeworICAgICAgICAgICAgICAgIF9zdHJpZGVkX2NvcHlfbmQoZGVzdCwgc3JjLCBuZC0xLCBzaGFwZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmlkZXMsIGl0ZW1zaXplLCBmb3J0KTsKKyAgICAgICAgICAgICAgICBkZXN0ICs9IG91dHN0cmlkZTsKKyAgICAgICAgICAgICAgICBzcmMgKz0gc3RyaWRlc1tuZC0xXTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIGVsc2UgeworICAgICAgICAgICAgLyogQ29weSBsYXN0IGRpbWVuc2lvbiBmaXJzdCwKKyAgICAgICAgICAgICAgIHNlY29uZC10by1sYXN0IGRpbWVuc2lvbiBzZWNvbmQsIGV0Yy4KKyAgICAgICAgICAgICAgIFNldCB1cCB0aGUgcmVjdXJzaW9uIHNvIHRoYXQgdGhlCisgICAgICAgICAgICAgICBmaXJzdCBkaW1lbnNpb24gaXMgY29waWVkIGxhc3QKKyAgICAgICAgICAgICovCisgICAgICAgICAgICBvdXRzdHJpZGUgPSBpdGVtc2l6ZTsKKyAgICAgICAgICAgIGZvciAoaz0xOyBrIDwgbmQ7IGsrKykgeworICAgICAgICAgICAgICAgIG91dHN0cmlkZSAqPSBzaGFwZVtrXTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGZvciAoaz0wOyBrPHNoYXBlWzBdOyBrKyspIHsKKyAgICAgICAgICAgICAgICBfc3RyaWRlZF9jb3B5X25kKGRlc3QsIHNyYywgbmQtMSwgc2hhcGUrMSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmlkZXMrMSwgaXRlbXNpemUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3J0KTsKKyAgICAgICAgICAgICAgICBkZXN0ICs9IG91dHN0cmlkZTsKKyAgICAgICAgICAgICAgICBzcmMgKz0gc3RyaWRlc1swXTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKyAgICByZXR1cm47Cit9CisKK3N0YXRpYyBpbnQKK19pbmRpcmVjdF9jb3B5X25kKGNoYXIgKmRlc3QsIFB5X2J1ZmZlciAqdmlldywgY2hhciBmb3J0KQoreworICAgIFB5X3NzaXplX3QgKmluZGljZXM7CisgICAgaW50IGs7CisgICAgUHlfc3NpemVfdCBlbGVtZW50czsKKyAgICBjaGFyICpwdHI7CisgICAgdm9pZCAoKmZ1bmMpKGludCwgUHlfc3NpemVfdCAqLCBjb25zdCBQeV9zc2l6ZV90ICopOworCisgICAgaWYgKHZpZXctPm5kaW0gPiBQWV9TU0laRV9UX01BWCAvIHNpemVvZihQeV9zc2l6ZV90KSkgeworICAgICAgICBQeUVycl9Ob01lbW9yeSgpOworICAgICAgICByZXR1cm4gLTE7CisgICAgfQorCisgICAgaW5kaWNlcyA9IChQeV9zc2l6ZV90ICopUHlNZW1fTWFsbG9jKHNpemVvZihQeV9zc2l6ZV90KSp2aWV3LT5uZGltKTsKKyAgICBpZiAoaW5kaWNlcyA9PSBOVUxMKSB7CisgICAgICAgIFB5RXJyX05vTWVtb3J5KCk7CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisgICAgZm9yIChrPTA7IGs8dmlldy0+bmRpbTtrKyspIHsKKyAgICAgICAgaW5kaWNlc1trXSA9IDA7CisgICAgfQorCisgICAgZWxlbWVudHMgPSAxOworICAgIGZvciAoaz0wOyBrPHZpZXctPm5kaW07IGsrKykgeworICAgICAgICBlbGVtZW50cyAqPSB2aWV3LT5zaGFwZVtrXTsKKyAgICB9CisgICAgaWYgKGZvcnQgPT0gJ0YnKSB7CisgICAgICAgIGZ1bmMgPSBfUHlfYWRkX29uZV90b19pbmRleF9GOworICAgIH0KKyAgICBlbHNlIHsKKyAgICAgICAgZnVuYyA9IF9QeV9hZGRfb25lX3RvX2luZGV4X0M7CisgICAgfQorICAgIHdoaWxlIChlbGVtZW50cy0tKSB7CisgICAgICAgIGZ1bmModmlldy0+bmRpbSwgaW5kaWNlcywgdmlldy0+c2hhcGUpOworICAgICAgICBwdHIgPSBQeUJ1ZmZlcl9HZXRQb2ludGVyKHZpZXcsIGluZGljZXMpOworICAgICAgICBtZW1jcHkoZGVzdCwgcHRyLCB2aWV3LT5pdGVtc2l6ZSk7CisgICAgICAgIGRlc3QgKz0gdmlldy0+aXRlbXNpemU7CisgICAgfQorCisgICAgUHlNZW1fRnJlZShpbmRpY2VzKTsKKyAgICByZXR1cm4gMDsKK30KKworLyoKKyAgIEdldCBhIHRoZSBkYXRhIGZyb20gYW4gb2JqZWN0IGFzIGEgY29udGlndW91cyBjaHVuayBvZiBtZW1vcnkgKGluCisgICBlaXRoZXIgJ0MnIG9yICdGJ29ydHJhbiBvcmRlcikgZXZlbiBpZiBpdCBtZWFucyBjb3B5aW5nIGl0IGludG8gYQorICAgc2VwYXJhdGUgbWVtb3J5IGFyZWEuCisKKyAgIFJldHVybnMgYSBuZXcgcmVmZXJlbmNlIHRvIGEgTWVtb3J5IHZpZXcgb2JqZWN0LiAgSWYgbm8gY29weSBpcyBuZWVkZWQsCisgICB0aGUgbWVtb3J5IHZpZXcgb2JqZWN0IHBvaW50cyB0byB0aGUgb3JpZ2luYWwgbWVtb3J5IGFuZCBob2xkcyBhCisgICBsb2NrIG9uIHRoZSBvcmlnaW5hbC4gIElmIGEgY29weSBpcyBuZWVkZWQsIHRoZW4gdGhlIG1lbW9yeSB2aWV3IG9iamVjdAorICAgcG9pbnRzIHRvIGEgYnJhbmQtbmV3IEJ5dGVzIG9iamVjdCAoYW5kIGhvbGRzIGEgbWVtb3J5IGxvY2sgb24gaXQpLgorCisgICBidWZmZXJ0eXBlCisKKyAgIFB5QlVGX1JFQUQgIGJ1ZmZlciBvbmx5IG5lZWRzIHRvIGJlIHJlYWQtb25seQorICAgUHlCVUZfV1JJVEUgYnVmZmVyIG5lZWRzIHRvIGJlIHdyaXRhYmxlIChnaXZlIGVycm9yIGlmIG5vdCBjb250aWd1b3VzKQorICAgUHlCVUZfU0hBRE9XIGJ1ZmZlciBuZWVkcyB0byBiZSB3cml0YWJsZSBzbyBzaGFkb3cgaXQgd2l0aAorICAgICAgICAgICAgICAgIGEgY29udGlndW91cyBidWZmZXIgaWYgaXQgaXMgbm90LiBUaGUgdmlldyB3aWxsIHBvaW50IHRvCisgICAgICAgICAgICAgICAgdGhlIHNoYWRvdyBidWZmZXIgd2hpY2ggY2FuIGJlIHdyaXR0ZW4gdG8gYW5kIHRoZW4KKyAgICAgICAgICAgICAgICB3aWxsIGJlIGNvcGllZCBiYWNrIGludG8gdGhlIG90aGVyIGJ1ZmZlciB3aGVuIHRoZSBtZW1vcnkKKyAgICAgICAgICAgICAgICB2aWV3IGlzIGRlLWFsbG9jYXRlZC4gIFdoaWxlIHRoZSBzaGFkb3cgYnVmZmVyIGlzCisgICAgICAgICAgICAgICAgYmVpbmcgdXNlZCwgaXQgd2lsbCBoYXZlIGFuIGV4Y2x1c2l2ZSB3cml0ZSBsb2NrIG9uCisgICAgICAgICAgICAgICAgdGhlIG9yaWdpbmFsIGJ1ZmZlci4KKyAqLworCitQeU9iamVjdCAqCitQeU1lbW9yeVZpZXdfR2V0Q29udGlndW91cyhQeU9iamVjdCAqb2JqLCBpbnQgYnVmZmVydHlwZSwgY2hhciBmb3J0KQoreworICAgIFB5TWVtb3J5Vmlld09iamVjdCAqbWVtOworICAgIFB5T2JqZWN0ICpieXRlczsKKyAgICBQeV9idWZmZXIgKnZpZXc7CisgICAgaW50IGZsYWdzOworICAgIGNoYXIgKmRlc3Q7CisKKyAgICBpZiAoIVB5T2JqZWN0X0NoZWNrQnVmZmVyKG9iaikpIHsKKyAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1R5cGVFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICJvYmplY3QgZG9lcyBub3QgaGF2ZSB0aGUgYnVmZmVyIGludGVyZmFjZSIpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisKKyAgICBtZW0gPSBQeU9iamVjdF9HQ19OZXcoUHlNZW1vcnlWaWV3T2JqZWN0LCAmUHlNZW1vcnlWaWV3X1R5cGUpOworICAgIGlmIChtZW0gPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisKKyAgICB2aWV3ID0gJm1lbS0+dmlldzsKKyAgICBmbGFncyA9IFB5QlVGX0ZVTExfUk87CisgICAgc3dpdGNoKGJ1ZmZlcnR5cGUpIHsKKyAgICBjYXNlIFB5QlVGX1dSSVRFOgorICAgICAgICBmbGFncyA9IFB5QlVGX0ZVTEw7CisgICAgICAgIGJyZWFrOworICAgIH0KKworICAgIGlmIChQeU9iamVjdF9HZXRCdWZmZXIob2JqLCB2aWV3LCBmbGFncykgIT0gMCkgeworICAgICAgICBQeV9ERUNSRUYobWVtKTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorCisgICAgaWYgKFB5QnVmZmVyX0lzQ29udGlndW91cyh2aWV3LCBmb3J0KSkgeworICAgICAgICAvKiBubyBjb3B5IG5lZWRlZCAqLworICAgICAgICBQeV9JTkNSRUYob2JqKTsKKyAgICAgICAgbWVtLT5iYXNlID0gb2JqOworICAgICAgICBfUHlPYmplY3RfR0NfVFJBQ0sobWVtKTsKKyAgICAgICAgcmV0dXJuIChQeU9iamVjdCAqKW1lbTsKKyAgICB9CisgICAgLyogb3RoZXJ3aXNlIGEgY29weSBpcyBuZWVkZWQgKi8KKyAgICBpZiAoYnVmZmVydHlwZSA9PSBQeUJVRl9XUklURSkgeworICAgICAgICBQeV9ERUNSRUYobWVtKTsKKyAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX0J1ZmZlckVycm9yLAorICAgICAgICAgICAgICAgICAgICAgICAgIndyaXRhYmxlIGNvbnRpZ3VvdXMgYnVmZmVyIHJlcXVlc3RlZCAiCisgICAgICAgICAgICAgICAgICAgICAgICAiZm9yIGEgbm9uLWNvbnRpZ3VvdXNvYmplY3QuIik7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICBieXRlcyA9IFB5Qnl0ZXNfRnJvbVN0cmluZ0FuZFNpemUoTlVMTCwgdmlldy0+bGVuKTsKKyAgICBpZiAoYnl0ZXMgPT0gTlVMTCkgeworICAgICAgICBQeV9ERUNSRUYobWVtKTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIGRlc3QgPSBQeUJ5dGVzX0FTX1NUUklORyhieXRlcyk7CisgICAgLyogZGlmZmVyZW50IGNvcHlpbmcgc3RyYXRlZ3kgZGVwZW5kaW5nIG9uIHdoZXRoZXIKKyAgICAgICBvciBub3QgYW55IHBvaW50ZXIgZGUtcmVmZXJlbmNpbmcgaXMgbmVlZGVkCisgICAgKi8KKyAgICAvKiBzdHJpZGVkIG9yIGluLWRpcmVjdCBjb3B5ICovCisgICAgaWYgKHZpZXctPnN1Ym9mZnNldHM9PU5VTEwpIHsKKyAgICAgICAgX3N0cmlkZWRfY29weV9uZChkZXN0LCB2aWV3LT5idWYsIHZpZXctPm5kaW0sIHZpZXctPnNoYXBlLAorICAgICAgICAgICAgICAgICAgICAgICAgIHZpZXctPnN0cmlkZXMsIHZpZXctPml0ZW1zaXplLCBmb3J0KTsKKyAgICB9CisgICAgZWxzZSB7CisgICAgICAgIGlmIChfaW5kaXJlY3RfY29weV9uZChkZXN0LCB2aWV3LCBmb3J0KSA8IDApIHsKKyAgICAgICAgICAgIFB5X0RFQ1JFRihieXRlcyk7CisgICAgICAgICAgICBQeV9ERUNSRUYobWVtKTsKKyAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgICAgICB9CisgICAgfQorICAgIGlmIChidWZmZXJ0eXBlID09IFB5QlVGX1NIQURPVykgeworICAgICAgICAvKiByZXR1cm4gYSBzaGFkb3dlZCBtZW1vcnktdmlldyBvYmplY3QgKi8KKyAgICAgICAgdmlldy0+YnVmID0gZGVzdDsKKyAgICAgICAgbWVtLT5iYXNlID0gUHlUdXBsZV9QYWNrKDIsIG9iaiwgYnl0ZXMpOworICAgICAgICBQeV9ERUNSRUYoYnl0ZXMpOworICAgICAgICBpZiAobWVtLT5iYXNlID09IE5VTEwpIHsKKyAgICAgICAgICAgIFB5X0RFQ1JFRihtZW0pOworICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgICAgIH0KKyAgICB9CisgICAgZWxzZSB7CisgICAgICAgIFB5QnVmZmVyX1JlbGVhc2Uodmlldyk7ICAvKiBYWFggPyAqLworICAgICAgICAvKiBzdGVhbCB0aGUgcmVmZXJlbmNlICovCisgICAgICAgIG1lbS0+YmFzZSA9IGJ5dGVzOworICAgIH0KKyAgICBfUHlPYmplY3RfR0NfVFJBQ0sobWVtKTsKKyAgICByZXR1cm4gKFB5T2JqZWN0ICopbWVtOworfQorCisKK3N0YXRpYyBQeU9iamVjdCAqCittZW1vcnlfZm9ybWF0X2dldChQeU1lbW9yeVZpZXdPYmplY3QgKnNlbGYpCit7CisgICAgcmV0dXJuIFB5U3RyaW5nX0Zyb21TdHJpbmcoc2VsZi0+dmlldy5mb3JtYXQpOworfQorCitzdGF0aWMgUHlPYmplY3QgKgorbWVtb3J5X2l0ZW1zaXplX2dldChQeU1lbW9yeVZpZXdPYmplY3QgKnNlbGYpCit7CisgICAgcmV0dXJuIFB5TG9uZ19Gcm9tU3NpemVfdChzZWxmLT52aWV3Lml0ZW1zaXplKTsKK30KKworc3RhdGljIFB5T2JqZWN0ICoKK19JbnRUdXBsZUZyb21Tc2l6ZXQoaW50IGxlbiwgUHlfc3NpemVfdCAqdmFscykKK3sKKyAgICBpbnQgaTsKKyAgICBQeU9iamVjdCAqbzsKKyAgICBQeU9iamVjdCAqaW50VHVwbGU7CisKKyAgICBpZiAodmFscyA9PSBOVUxMKSB7CisgICAgICAgIFB5X0lOQ1JFRihQeV9Ob25lKTsKKyAgICAgICAgcmV0dXJuIFB5X05vbmU7CisgICAgfQorICAgIGludFR1cGxlID0gUHlUdXBsZV9OZXcobGVuKTsKKyAgICBpZiAoIWludFR1cGxlKSByZXR1cm4gTlVMTDsKKyAgICBmb3IoaT0wOyBpPGxlbjsgaSsrKSB7CisgICAgICAgIG8gPSBQeUxvbmdfRnJvbVNzaXplX3QodmFsc1tpXSk7CisgICAgICAgIGlmICghbykgeworICAgICAgICAgICAgUHlfREVDUkVGKGludFR1cGxlKTsKKyAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgICAgICB9CisgICAgICAgIFB5VHVwbGVfU0VUX0lURU0oaW50VHVwbGUsIGksIG8pOworICAgIH0KKyAgICByZXR1cm4gaW50VHVwbGU7Cit9CisKK3N0YXRpYyBQeU9iamVjdCAqCittZW1vcnlfc2hhcGVfZ2V0KFB5TWVtb3J5Vmlld09iamVjdCAqc2VsZikKK3sKKyAgICByZXR1cm4gX0ludFR1cGxlRnJvbVNzaXpldChzZWxmLT52aWV3Lm5kaW0sIHNlbGYtPnZpZXcuc2hhcGUpOworfQorCitzdGF0aWMgUHlPYmplY3QgKgorbWVtb3J5X3N0cmlkZXNfZ2V0KFB5TWVtb3J5Vmlld09iamVjdCAqc2VsZikKK3sKKyAgICByZXR1cm4gX0ludFR1cGxlRnJvbVNzaXpldChzZWxmLT52aWV3Lm5kaW0sIHNlbGYtPnZpZXcuc3RyaWRlcyk7Cit9CisKK3N0YXRpYyBQeU9iamVjdCAqCittZW1vcnlfc3Vib2Zmc2V0c19nZXQoUHlNZW1vcnlWaWV3T2JqZWN0ICpzZWxmKQoreworICAgIHJldHVybiBfSW50VHVwbGVGcm9tU3NpemV0KHNlbGYtPnZpZXcubmRpbSwgc2VsZi0+dmlldy5zdWJvZmZzZXRzKTsKK30KKworc3RhdGljIFB5T2JqZWN0ICoKK21lbW9yeV9yZWFkb25seV9nZXQoUHlNZW1vcnlWaWV3T2JqZWN0ICpzZWxmKQoreworICAgIHJldHVybiBQeUJvb2xfRnJvbUxvbmcoc2VsZi0+dmlldy5yZWFkb25seSk7Cit9CisKK3N0YXRpYyBQeU9iamVjdCAqCittZW1vcnlfbmRpbV9nZXQoUHlNZW1vcnlWaWV3T2JqZWN0ICpzZWxmKQoreworICAgIHJldHVybiBQeUxvbmdfRnJvbUxvbmcoc2VsZi0+dmlldy5uZGltKTsKK30KKworc3RhdGljIFB5R2V0U2V0RGVmIG1lbW9yeV9nZXRzZXRsaXN0W10gPXsKKyAgICB7ImZvcm1hdCIsICAgICAgICAgIChnZXR0ZXIpbWVtb3J5X2Zvcm1hdF9nZXQsICAgICAgTlVMTCwgTlVMTH0sCisgICAgeyJpdGVtc2l6ZSIsICAgICAgICAoZ2V0dGVyKW1lbW9yeV9pdGVtc2l6ZV9nZXQsICAgIE5VTEwsIE5VTEx9LAorICAgIHsic2hhcGUiLCAgICAgICAgICAgKGdldHRlciltZW1vcnlfc2hhcGVfZ2V0LCAgICAgICBOVUxMLCBOVUxMfSwKKyAgICB7InN0cmlkZXMiLCAgICAgICAgIChnZXR0ZXIpbWVtb3J5X3N0cmlkZXNfZ2V0LCAgICAgTlVMTCwgTlVMTH0sCisgICAgeyJzdWJvZmZzZXRzIiwgICAgICAoZ2V0dGVyKW1lbW9yeV9zdWJvZmZzZXRzX2dldCwgIE5VTEwsIE5VTEx9LAorICAgIHsicmVhZG9ubHkiLCAgICAgICAgKGdldHRlciltZW1vcnlfcmVhZG9ubHlfZ2V0LCAgICBOVUxMLCBOVUxMfSwKKyAgICB7Im5kaW0iLCAgICAgICAgICAgIChnZXR0ZXIpbWVtb3J5X25kaW1fZ2V0LCAgICAgICAgTlVMTCwgTlVMTH0sCisgICAge05VTEwsIE5VTEwsIE5VTEwsIE5VTEx9LAorfTsKKworCitzdGF0aWMgUHlPYmplY3QgKgorbWVtb3J5X3RvYnl0ZXMoUHlNZW1vcnlWaWV3T2JqZWN0ICpzZWxmLCBQeU9iamVjdCAqbm9hcmdzKQoreworICAgIFB5X2J1ZmZlciB2aWV3OworICAgIFB5T2JqZWN0ICpyZXM7CisKKyAgICBpZiAoUHlPYmplY3RfR2V0QnVmZmVyKChQeU9iamVjdCAqKXNlbGYsICZ2aWV3LCBQeUJVRl9TSU1QTEUpIDwgMCkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisKKyAgICByZXMgPSBQeUJ5dGVzX0Zyb21TdHJpbmdBbmRTaXplKE5VTEwsIHZpZXcubGVuKTsKKyAgICBQeUJ1ZmZlcl9Ub0NvbnRpZ3VvdXMoUHlCeXRlc19BU19TVFJJTkcocmVzKSwgJnZpZXcsIHZpZXcubGVuLCAnQycpOworICAgIFB5QnVmZmVyX1JlbGVhc2UoJnZpZXcpOworICAgIHJldHVybiByZXM7Cit9CisKKy8qIFRPRE86IHJld3JpdGUgdGhpcyBmdW5jdGlvbiB1c2luZyB0aGUgc3RydWN0IG1vZHVsZSB0byB1bnBhY2sKKyAgIGVhY2ggYnVmZmVyIGl0ZW0gKi8KKworc3RhdGljIFB5T2JqZWN0ICoKK21lbW9yeV90b2xpc3QoUHlNZW1vcnlWaWV3T2JqZWN0ICptZW0sIFB5T2JqZWN0ICpub2FyZ3MpCit7CisgICAgUHlfYnVmZmVyICp2aWV3ID0gJihtZW0tPnZpZXcpOworICAgIFB5X3NzaXplX3QgaTsKKyAgICBQeU9iamVjdCAqcmVzLCAqaXRlbTsKKyAgICBjaGFyICpidWY7CisKKyAgICBpZiAoc3RyY21wKHZpZXctPmZvcm1hdCwgIkIiKSB8fCB2aWV3LT5pdGVtc2l6ZSAhPSAxKSB7CisgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19Ob3RJbXBsZW1lbnRlZEVycm9yLCAKKyAgICAgICAgICAgICAgICAidG9saXN0KCkgb25seSBzdXBwb3J0cyBieXRlIHZpZXdzIik7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICBpZiAodmlldy0+bmRpbSAhPSAxKSB7CisgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19Ob3RJbXBsZW1lbnRlZEVycm9yLCAKKyAgICAgICAgICAgICAgICAidG9saXN0KCkgb25seSBzdXBwb3J0cyBvbmUtZGltZW5zaW9uYWwgb2JqZWN0cyIpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgcmVzID0gUHlMaXN0X05ldyh2aWV3LT5sZW4pOworICAgIGlmIChyZXMgPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgYnVmID0gdmlldy0+YnVmOworICAgIGZvciAoaSA9IDA7IGkgPCB2aWV3LT5sZW47IGkrKykgeworICAgICAgICBpdGVtID0gUHlJbnRfRnJvbUxvbmcoKHVuc2lnbmVkIGNoYXIpICpidWYpOworICAgICAgICBpZiAoaXRlbSA9PSBOVUxMKSB7CisgICAgICAgICAgICBQeV9ERUNSRUYocmVzKTsKKyAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgICAgICB9CisgICAgICAgIFB5TGlzdF9TRVRfSVRFTShyZXMsIGksIGl0ZW0pOworICAgICAgICBidWYrKzsKKyAgICB9CisgICAgcmV0dXJuIHJlczsKK30KKworc3RhdGljIFB5TWV0aG9kRGVmIG1lbW9yeV9tZXRob2RzW10gPSB7CisgICAgeyJ0b2J5dGVzIiwgKFB5Q0Z1bmN0aW9uKW1lbW9yeV90b2J5dGVzLCBNRVRIX05PQVJHUywgTlVMTH0sCisgICAgeyJ0b2xpc3QiLCAoUHlDRnVuY3Rpb24pbWVtb3J5X3RvbGlzdCwgTUVUSF9OT0FSR1MsIE5VTEx9LAorICAgIHtOVUxMLCAgICAgICAgICBOVUxMfSAgICAgICAgICAgLyogc2VudGluZWwgKi8KK307CisKKworc3RhdGljIHZvaWQKK21lbW9yeV9kZWFsbG9jKFB5TWVtb3J5Vmlld09iamVjdCAqc2VsZikKK3sKKyAgICBfUHlPYmplY3RfR0NfVU5UUkFDSyhzZWxmKTsKKyAgICBpZiAoc2VsZi0+dmlldy5vYmogIT0gTlVMTCkgeworICAgICAgICBpZiAoc2VsZi0+YmFzZSAmJiBQeVR1cGxlX0NoZWNrKHNlbGYtPmJhc2UpKSB7CisgICAgICAgICAgICAvKiBTcGVjaWFsIGNhc2Ugd2hlbiBmaXJzdCBlbGVtZW50IGlzIGdlbmVyaWMgb2JqZWN0CisgICAgICAgICAgICAgICB3aXRoIGJ1ZmZlciBpbnRlcmZhY2UgYW5kIHRoZSBzZWNvbmQgZWxlbWVudCBpcyBhCisgICAgICAgICAgICAgICBjb250aWd1b3VzICJzaGFkb3ciIHRoYXQgbXVzdCBiZSBjb3BpZWQgYmFjayBpbnRvCisgICAgICAgICAgICAgICB0aGUgZGF0YSBhcmVheSBvZiB0aGUgZmlyc3QgdHVwbGUgZWxlbWVudCBiZWZvcmUKKyAgICAgICAgICAgICAgIHJlbGVhc2luZyB0aGUgYnVmZmVyIG9uIHRoZSBmaXJzdCBlbGVtZW50LgorICAgICAgICAgICAgKi8KKworICAgICAgICAgICAgUHlPYmplY3RfQ29weURhdGEoUHlUdXBsZV9HRVRfSVRFTShzZWxmLT5iYXNlLDApLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHlUdXBsZV9HRVRfSVRFTShzZWxmLT5iYXNlLDEpKTsKKworICAgICAgICAgICAgLyogVGhlIHZpZXcgbWVtYmVyIHNob3VsZCBoYXZlIHJlYWRvbmx5ID09IC0xIGluCisgICAgICAgICAgICAgICB0aGlzIGluc3RhbmNlIGluZGljYXRpbmcgdGhhdCB0aGUgbWVtb3J5IGNhbgorICAgICAgICAgICAgICAgYmUgImxvY2tlZCIgYW5kIHdhcyBsb2NrZWQgYW5kIHdpbGwgYmUgdW5sb2NrZWQKKyAgICAgICAgICAgICAgIGFnYWluIGFmdGVyIHRoaXMgY2FsbC4KKyAgICAgICAgICAgICovCisgICAgICAgICAgICBQeUJ1ZmZlcl9SZWxlYXNlKCYoc2VsZi0+dmlldykpOworICAgICAgICB9CisgICAgICAgIGVsc2UgeworICAgICAgICAgICAgUHlCdWZmZXJfUmVsZWFzZSgmKHNlbGYtPnZpZXcpKTsKKyAgICAgICAgfQorICAgICAgICBQeV9DTEVBUihzZWxmLT5iYXNlKTsKKyAgICB9CisgICAgUHlPYmplY3RfR0NfRGVsKHNlbGYpOworfQorCitzdGF0aWMgUHlPYmplY3QgKgorbWVtb3J5X3JlcHIoUHlNZW1vcnlWaWV3T2JqZWN0ICpzZWxmKQoreworICAgIHJldHVybiBQeVN0cmluZ19Gcm9tRm9ybWF0KCI8bWVtb3J5IGF0ICVwPiIsIHNlbGYpOworfQorCisvKiBTZXF1ZW5jZSBtZXRob2RzICovCitzdGF0aWMgUHlfc3NpemVfdAorbWVtb3J5X2xlbmd0aChQeU1lbW9yeVZpZXdPYmplY3QgKnNlbGYpCit7CisgICAgcmV0dXJuIGdldF9zaGFwZTAoJnNlbGYtPnZpZXcpOworfQorCisvKiBBbHRlcm5hdGUgdmVyc2lvbiBvZiBtZW1vcnlfc3ViY3JpcHQgdGhhdCBvbmx5IGFjY2VwdHMgaW5kaWNlcy4KKyAgIFVzZWQgYnkgUHlTZXFJdGVyX05ldygpLgorKi8KK3N0YXRpYyBQeU9iamVjdCAqCittZW1vcnlfaXRlbShQeU1lbW9yeVZpZXdPYmplY3QgKnNlbGYsIFB5X3NzaXplX3QgcmVzdWx0KQoreworICAgIFB5X2J1ZmZlciAqdmlldyA9ICYoc2VsZi0+dmlldyk7CisKKyAgICBpZiAodmlldy0+bmRpbSA9PSAwKSB7CisgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19JbmRleEVycm9yLAorICAgICAgICAgICAgICAgICAgICAgICAgImludmFsaWQgaW5kZXhpbmcgb2YgMC1kaW0gbWVtb3J5Iik7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICBpZiAodmlldy0+bmRpbSA9PSAxKSB7CisgICAgICAgIC8qIFJldHVybiBhIGJ5dGVzIG9iamVjdCAqLworICAgICAgICBjaGFyICpwdHI7CisgICAgICAgIHB0ciA9IChjaGFyICopdmlldy0+YnVmOworICAgICAgICBpZiAocmVzdWx0IDwgMCkgeworICAgICAgICAgICAgcmVzdWx0ICs9IGdldF9zaGFwZTAodmlldyk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKChyZXN1bHQgPCAwKSB8fCAocmVzdWx0ID49IGdldF9zaGFwZTAodmlldykpKSB7CisgICAgICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfSW5kZXhFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImluZGV4IG91dCBvZiBib3VuZHMiKTsKKyAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgICAgICB9CisgICAgICAgIGlmICh2aWV3LT5zdHJpZGVzID09IE5VTEwpCisgICAgICAgICAgICBwdHIgKz0gdmlldy0+aXRlbXNpemUgKiByZXN1bHQ7CisgICAgICAgIGVsc2UKKyAgICAgICAgICAgIHB0ciArPSB2aWV3LT5zdHJpZGVzWzBdICogcmVzdWx0OworICAgICAgICBpZiAodmlldy0+c3Vib2Zmc2V0cyAhPSBOVUxMICYmCisgICAgICAgICAgICB2aWV3LT5zdWJvZmZzZXRzWzBdID49IDApIHsKKyAgICAgICAgICAgIHB0ciA9ICooKGNoYXIgKiopcHRyKSArIHZpZXctPnN1Ym9mZnNldHNbMF07CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIFB5Qnl0ZXNfRnJvbVN0cmluZ0FuZFNpemUocHRyLCB2aWV3LT5pdGVtc2l6ZSk7CisgICAgfSBlbHNlIHsKKyAgICAgICAgLyogUmV0dXJuIGEgbmV3IG1lbW9yeS12aWV3IG9iamVjdCAqLworICAgICAgICBQeV9idWZmZXIgbmV3dmlldzsKKyAgICAgICAgbWVtc2V0KCZuZXd2aWV3LCAwLCBzaXplb2YobmV3dmlldykpOworICAgICAgICAvKiBYWFg6ICBUaGlzIG5lZWRzIHRvIGJlIGZpeGVkIHNvIGl0IGFjdHVhbGx5IHJldHVybnMgYSBzdWItdmlldyAqLworICAgICAgICByZXR1cm4gUHlNZW1vcnlWaWV3X0Zyb21CdWZmZXIoJm5ld3ZpZXcpOworICAgIH0KK30KKworLyoKKyAgbWVtW29ial0gcmV0dXJucyBhIGJ5dGVzIG9iamVjdCBob2xkaW5nIHRoZSBkYXRhIGZvciBvbmUgZWxlbWVudCBpZgorICAgICAgICAgICBvYmogZnVsbHkgaW5kZXhlcyB0aGUgbWVtb3J5IHZpZXcgb3IgYW5vdGhlciBtZW1vcnktdmlldyBvYmplY3QKKyAgICAgICAgICAgaWYgaXQgZG9lcyBub3QuCisKKyAgICAgICAgICAgMC1kIG1lbW9yeS12aWV3IG9iamVjdHMgY2FuIGJlIHJlZmVyZW5jZWQgdXNpbmcgLi4uIG9yICgpIGJ1dAorICAgICAgICAgICBub3Qgd2l0aCBhbnl0aGluZyBlbHNlLgorICovCitzdGF0aWMgUHlPYmplY3QgKgorbWVtb3J5X3N1YnNjcmlwdChQeU1lbW9yeVZpZXdPYmplY3QgKnNlbGYsIFB5T2JqZWN0ICprZXkpCit7CisgICAgUHlfYnVmZmVyICp2aWV3OworICAgIHZpZXcgPSAmKHNlbGYtPnZpZXcpOworICAgIAorICAgIGlmICh2aWV3LT5uZGltID09IDApIHsKKyAgICAgICAgaWYgKGtleSA9PSBQeV9FbGxpcHNpcyB8fAorICAgICAgICAgICAgKFB5VHVwbGVfQ2hlY2soa2V5KSAmJiBQeVR1cGxlX0dFVF9TSVpFKGtleSk9PTApKSB7CisgICAgICAgICAgICBQeV9JTkNSRUYoc2VsZik7CisgICAgICAgICAgICByZXR1cm4gKFB5T2JqZWN0ICopc2VsZjsKKyAgICAgICAgfQorICAgICAgICBlbHNlIHsKKyAgICAgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19JbmRleEVycm9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiaW52YWxpZCBpbmRleGluZyBvZiAwLWRpbSBtZW1vcnkiKTsKKyAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgICAgICB9CisgICAgfQorICAgIGlmIChQeUluZGV4X0NoZWNrKGtleSkpIHsKKyAgICAgICAgUHlfc3NpemVfdCByZXN1bHQ7CisgICAgICAgIHJlc3VsdCA9IFB5TnVtYmVyX0FzU3NpemVfdChrZXksIE5VTEwpOworICAgICAgICBpZiAocmVzdWx0ID09IC0xICYmIFB5RXJyX09jY3VycmVkKCkpCisgICAgICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgICAgIHJldHVybiBtZW1vcnlfaXRlbShzZWxmLCByZXN1bHQpOworICAgIH0KKyAgICBlbHNlIGlmIChQeVNsaWNlX0NoZWNrKGtleSkpIHsKKyAgICAgICAgUHlfc3NpemVfdCBzdGFydCwgc3RvcCwgc3RlcCwgc2xpY2VsZW5ndGg7CisKKyAgICAgICAgaWYgKFB5U2xpY2VfR2V0SW5kaWNlc0V4KChQeVNsaWNlT2JqZWN0KilrZXksIGdldF9zaGFwZTAodmlldyksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmc3RhcnQsICZzdG9wLCAmc3RlcCwgJnNsaWNlbGVuZ3RoKSA8IDApIHsKKyAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgICAgICB9CisgICAgCisgICAgICAgIGlmIChzdGVwID09IDEgJiYgdmlldy0+bmRpbSA9PSAxKSB7CisgICAgICAgICAgICBQeV9idWZmZXIgbmV3dmlldzsKKyAgICAgICAgICAgIHZvaWQgKm5ld2J1ZiA9IChjaGFyICopIHZpZXctPmJ1ZgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKyBzdGFydCAqIHZpZXctPml0ZW1zaXplOworICAgICAgICAgICAgaW50IG5ld2ZsYWdzID0gdmlldy0+cmVhZG9ubHkKKyAgICAgICAgICAgICAgICAgICAgPyBQeUJVRl9DT05USUdfUk8gOiBQeUJVRl9DT05USUc7CisgICAgCisgICAgICAgICAgICAvKiBYWFggVGhlcmUgc2hvdWxkIGJlIGFuIEFQSSB0byBjcmVhdGUgYSBzdWJidWZmZXIgKi8KKyAgICAgICAgICAgIGlmICh2aWV3LT5vYmogIT0gTlVMTCkgeworICAgICAgICAgICAgICAgIGlmIChQeU9iamVjdF9HZXRCdWZmZXIodmlldy0+b2JqLCAmbmV3dmlldywgbmV3ZmxhZ3MpID09IC0xKQorICAgICAgICAgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGVsc2UgeworICAgICAgICAgICAgICAgIG5ld3ZpZXcgPSAqdmlldzsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIG5ld3ZpZXcuYnVmID0gbmV3YnVmOworICAgICAgICAgICAgbmV3dmlldy5sZW4gPSBzbGljZWxlbmd0aCAqIG5ld3ZpZXcuaXRlbXNpemU7CisgICAgICAgICAgICBuZXd2aWV3LmZvcm1hdCA9IHZpZXctPmZvcm1hdDsKKyAgICAgICAgICAgIG5ld3ZpZXcuc2hhcGUgPSAmKG5ld3ZpZXcuc21hbGx0YWJsZVswXSk7CisgICAgICAgICAgICBuZXd2aWV3LnNoYXBlWzBdID0gc2xpY2VsZW5ndGg7CisgICAgICAgICAgICBuZXd2aWV3LnN0cmlkZXMgPSAmKG5ld3ZpZXcuaXRlbXNpemUpOworICAgICAgICAgICAgcmV0dXJuIFB5TWVtb3J5Vmlld19Gcm9tQnVmZmVyKCZuZXd2aWV3KTsKKyAgICAgICAgfQorICAgICAgICBQeUVycl9TZXROb25lKFB5RXhjX05vdEltcGxlbWVudGVkRXJyb3IpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgUHlFcnJfRm9ybWF0KFB5RXhjX1R5cGVFcnJvciwKKyAgICAgICAgImNhbm5vdCBpbmRleCBtZW1vcnkgdXNpbmcgXCIlLjIwMHNcIiIsIAorICAgICAgICBrZXktPm9iX3R5cGUtPnRwX25hbWUpOworICAgIHJldHVybiBOVUxMOworfQorCisKKy8qIE5lZWQgdG8gc3VwcG9ydCBhc3NpZ25pbmcgbWVtb3J5IGlmIHdlIGNhbiAqLworc3RhdGljIGludAorbWVtb3J5X2Fzc19zdWIoUHlNZW1vcnlWaWV3T2JqZWN0ICpzZWxmLCBQeU9iamVjdCAqa2V5LCBQeU9iamVjdCAqdmFsdWUpCit7CisgICAgUHlfc3NpemVfdCBzdGFydCwgbGVuLCBieXRlbGVuOworICAgIFB5X2J1ZmZlciBzcmN2aWV3OworICAgIFB5X2J1ZmZlciAqdmlldyA9ICYoc2VsZi0+dmlldyk7CisgICAgY2hhciAqc3JjYnVmLCAqZGVzdGJ1ZjsKKworICAgIGlmICh2aWV3LT5yZWFkb25seSkgeworICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfVHlwZUVycm9yLAorICAgICAgICAgICAgImNhbm5vdCBtb2RpZnkgcmVhZC1vbmx5IG1lbW9yeSIpOworICAgICAgICByZXR1cm4gLTE7CisgICAgfQorICAgIGlmICh2YWx1ZSA9PSBOVUxMKSB7CisgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19UeXBlRXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAgICAiY2Fubm90IGRlbGV0ZSBtZW1vcnkiKTsKKyAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKyAgICBpZiAodmlldy0+bmRpbSAhPSAxKSB7CisgICAgICAgIFB5RXJyX1NldE5vbmUoUHlFeGNfTm90SW1wbGVtZW50ZWRFcnJvcik7CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisgICAgaWYgKFB5SW5kZXhfQ2hlY2soa2V5KSkgeworICAgICAgICBzdGFydCA9IFB5TnVtYmVyX0FzU3NpemVfdChrZXksIE5VTEwpOworICAgICAgICBpZiAoc3RhcnQgPT0gLTEgJiYgUHlFcnJfT2NjdXJyZWQoKSkKKyAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgaWYgKHN0YXJ0IDwgMCkgeworICAgICAgICAgICAgc3RhcnQgKz0gZ2V0X3NoYXBlMCh2aWV3KTsKKyAgICAgICAgfQorICAgICAgICBpZiAoKHN0YXJ0IDwgMCkgfHwgKHN0YXJ0ID49IGdldF9zaGFwZTAodmlldykpKSB7CisgICAgICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfSW5kZXhFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAiaW5kZXggb3V0IG9mIGJvdW5kcyIpOworICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICB9CisgICAgICAgIGxlbiA9IDE7CisgICAgfQorICAgIGVsc2UgaWYgKFB5U2xpY2VfQ2hlY2soa2V5KSkgeworICAgICAgICBQeV9zc2l6ZV90IHN0b3AsIHN0ZXA7CisKKyAgICAgICAgaWYgKFB5U2xpY2VfR2V0SW5kaWNlc0V4KChQeVNsaWNlT2JqZWN0KilrZXksIGdldF9zaGFwZTAodmlldyksCisgICAgICAgICAgICAgICAgICAgICAgICAgJnN0YXJ0LCAmc3RvcCwgJnN0ZXAsICZsZW4pIDwgMCkgeworICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICB9CisgICAgICAgIGlmIChzdGVwICE9IDEpIHsKKyAgICAgICAgICAgIFB5RXJyX1NldE5vbmUoUHlFeGNfTm90SW1wbGVtZW50ZWRFcnJvcik7CisgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgIH0KKyAgICB9CisgICAgZWxzZSB7CisgICAgICAgIFB5RXJyX0Zvcm1hdChQeUV4Y19UeXBlRXJyb3IsCisgICAgICAgICAgICAiY2Fubm90IGluZGV4IG1lbW9yeSB1c2luZyBcIiUuMjAwc1wiIiwgCisgICAgICAgICAgICBrZXktPm9iX3R5cGUtPnRwX25hbWUpOworICAgICAgICByZXR1cm4gLTE7CisgICAgfQorICAgIGlmIChQeU9iamVjdF9HZXRCdWZmZXIodmFsdWUsICZzcmN2aWV3LCBQeUJVRl9DT05USUdfUk8pID09IC0xKSB7CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisgICAgLyogWFhYIHNob3VsZCB3ZSBhbGxvdyBhc3NpZ25tZW50IG9mIGRpZmZlcmVudCBpdGVtIHNpemVzCisgICAgICAgYXMgbG9uZyBhcyB0aGUgYnl0ZSBsZW5ndGggaXMgdGhlIHNhbWU/CisgICAgICAgKGUuZy4gYXNzaWduIDIgc2hvcnRzIHRvIGEgNC1ieXRlIHNsaWNlKSAqLworICAgIGlmIChzcmN2aWV3Lml0ZW1zaXplICE9IHZpZXctPml0ZW1zaXplKSB7CisgICAgICAgIFB5RXJyX0Zvcm1hdChQeUV4Y19UeXBlRXJyb3IsCisgICAgICAgICAgICAibWlzbWF0Y2hpbmcgaXRlbSBzaXplcyBmb3IgXCIlLjIwMHNcIiBhbmQgXCIlLjIwMHNcIiIsIAorICAgICAgICAgICAgdmlldy0+b2JqLT5vYl90eXBlLT50cF9uYW1lLCBzcmN2aWV3Lm9iai0+b2JfdHlwZS0+dHBfbmFtZSk7CisgICAgICAgIGdvdG8gX2Vycm9yOworICAgIH0KKyAgICBieXRlbGVuID0gbGVuICogdmlldy0+aXRlbXNpemU7CisgICAgaWYgKGJ5dGVsZW4gIT0gc3Jjdmlldy5sZW4pIHsKKyAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1ZhbHVlRXJyb3IsCisgICAgICAgICAgICAiY2Fubm90IG1vZGlmeSBzaXplIG9mIG1lbW9yeXZpZXcgb2JqZWN0Iik7CisgICAgICAgIGdvdG8gX2Vycm9yOworICAgIH0KKyAgICAvKiBEbyB0aGUgYWN0dWFsIGNvcHkgKi8KKyAgICBkZXN0YnVmID0gKGNoYXIgKikgdmlldy0+YnVmICsgc3RhcnQgKiB2aWV3LT5pdGVtc2l6ZTsKKyAgICBzcmNidWYgPSAoY2hhciAqKSBzcmN2aWV3LmJ1ZjsKKyAgICBpZiAoZGVzdGJ1ZiArIGJ5dGVsZW4gPCBzcmNidWYgfHwgc3JjYnVmICsgYnl0ZWxlbiA8IGRlc3RidWYpCisgICAgICAgIC8qIE5vIG92ZXJsYXBwaW5nICovCisgICAgICAgIG1lbWNweShkZXN0YnVmLCBzcmNidWYsIGJ5dGVsZW4pOworICAgIGVsc2UKKyAgICAgICAgbWVtbW92ZShkZXN0YnVmLCBzcmNidWYsIGJ5dGVsZW4pOworCisgICAgUHlCdWZmZXJfUmVsZWFzZSgmc3Jjdmlldyk7CisgICAgcmV0dXJuIDA7CisKK19lcnJvcjoKKyAgICBQeUJ1ZmZlcl9SZWxlYXNlKCZzcmN2aWV3KTsKKyAgICByZXR1cm4gLTE7Cit9CisKK3N0YXRpYyBQeU9iamVjdCAqCittZW1vcnlfcmljaGNvbXBhcmUoUHlPYmplY3QgKnYsIFB5T2JqZWN0ICp3LCBpbnQgb3ApCit7CisgICAgUHlfYnVmZmVyIHZ2LCB3dzsKKyAgICBpbnQgZXF1YWwgPSAwOworICAgIFB5T2JqZWN0ICpyZXM7CisKKyAgICB2di5vYmogPSBOVUxMOworICAgIHd3Lm9iaiA9IE5VTEw7CisgICAgaWYgKG9wICE9IFB5X0VRICYmIG9wICE9IFB5X05FKQorICAgICAgICBnb3RvIF9ub3RpbXBsOworICAgIGlmIChQeU9iamVjdF9HZXRCdWZmZXIodiwgJnZ2LCBQeUJVRl9DT05USUdfUk8pID09IC0xKSB7CisgICAgICAgIFB5RXJyX0NsZWFyKCk7CisgICAgICAgIGdvdG8gX25vdGltcGw7CisgICAgfQorICAgIGlmIChQeU9iamVjdF9HZXRCdWZmZXIodywgJnd3LCBQeUJVRl9DT05USUdfUk8pID09IC0xKSB7CisgICAgICAgIFB5RXJyX0NsZWFyKCk7CisgICAgICAgIGdvdG8gX25vdGltcGw7CisgICAgfQorCisgICAgaWYgKHZ2Lml0ZW1zaXplICE9IHd3Lml0ZW1zaXplIHx8IHZ2LmxlbiAhPSB3dy5sZW4pCisgICAgICAgIGdvdG8gX2VuZDsKKworICAgIGVxdWFsID0gIW1lbWNtcCh2di5idWYsIHd3LmJ1ZiwgdnYubGVuKTsKKworX2VuZDoKKyAgICBQeUJ1ZmZlcl9SZWxlYXNlKCZ2dik7CisgICAgUHlCdWZmZXJfUmVsZWFzZSgmd3cpOworICAgIGlmICgoZXF1YWwgJiYgb3AgPT0gUHlfRVEpIHx8ICghZXF1YWwgJiYgb3AgPT0gUHlfTkUpKQorICAgICAgICByZXMgPSBQeV9UcnVlOworICAgIGVsc2UKKyAgICAgICAgcmVzID0gUHlfRmFsc2U7CisgICAgUHlfSU5DUkVGKHJlcyk7CisgICAgcmV0dXJuIHJlczsKKworX25vdGltcGw6CisgICAgUHlCdWZmZXJfUmVsZWFzZSgmdnYpOworICAgIFB5QnVmZmVyX1JlbGVhc2UoJnd3KTsKKyAgICBQeV9JTkNSRUYoUHlfTm90SW1wbGVtZW50ZWQpOworICAgIHJldHVybiBQeV9Ob3RJbXBsZW1lbnRlZDsKK30KKworCitzdGF0aWMgaW50CittZW1vcnlfdHJhdmVyc2UoUHlNZW1vcnlWaWV3T2JqZWN0ICpzZWxmLCB2aXNpdHByb2MgdmlzaXQsIHZvaWQgKmFyZykKK3sKKyAgICBpZiAoc2VsZi0+YmFzZSAhPSBOVUxMKQorICAgICAgICBQeV9WSVNJVChzZWxmLT5iYXNlKTsKKyAgICBpZiAoc2VsZi0+dmlldy5vYmogIT0gTlVMTCkKKyAgICAgICAgUHlfVklTSVQoc2VsZi0+dmlldy5vYmopOworICAgIHJldHVybiAwOworfQorCitzdGF0aWMgaW50CittZW1vcnlfY2xlYXIoUHlNZW1vcnlWaWV3T2JqZWN0ICpzZWxmKQoreworICAgIFB5X0NMRUFSKHNlbGYtPmJhc2UpOworICAgIFB5QnVmZmVyX1JlbGVhc2UoJnNlbGYtPnZpZXcpOworICAgIHJldHVybiAwOworfQorCisKKy8qIEFzIG1hcHBpbmcgKi8KK3N0YXRpYyBQeU1hcHBpbmdNZXRob2RzIG1lbW9yeV9hc19tYXBwaW5nID0geworICAgIChsZW5mdW5jKW1lbW9yeV9sZW5ndGgsICAgICAgICAgICAgICAgLyogbXBfbGVuZ3RoICovCisgICAgKGJpbmFyeWZ1bmMpbWVtb3J5X3N1YnNjcmlwdCwgICAgICAgICAvKiBtcF9zdWJzY3JpcHQgKi8KKyAgICAob2Jqb2JqYXJncHJvYyltZW1vcnlfYXNzX3N1YiwgICAgICAgIC8qIG1wX2Fzc19zdWJzY3JpcHQgKi8KK307CisKK3N0YXRpYyBQeVNlcXVlbmNlTWV0aG9kcyBtZW1vcnlfYXNfc2VxdWVuY2UgPSB7CisJMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogc3FfbGVuZ3RoICovCisJMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogc3FfY29uY2F0ICovCisJMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogc3FfcmVwZWF0ICovCisJKHNzaXplYXJnZnVuYyltZW1vcnlfaXRlbSwgICAgICAgICAgLyogc3FfaXRlbSAqLworfTsKKworLyogQnVmZmVyIG1ldGhvZHMgKi8KK3N0YXRpYyBQeUJ1ZmZlclByb2NzIG1lbW9yeV9hc19idWZmZXIgPSB7CisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBiZl9nZXRyZWFkYnVmZmVyICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBiZl9nZXR3cml0ZWJ1ZmZlciAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogYmZfZ2V0c2VnY291bnQgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIGJmX2dldGNoYXJidWZmZXIgKi8KKyAgICAoZ2V0YnVmZmVycHJvYyltZW1vcnlfZ2V0YnVmLCAgICAgICAgIC8qIGJmX2dldGJ1ZmZlciAqLworICAgIChyZWxlYXNlYnVmZmVycHJvYyltZW1vcnlfcmVsZWFzZWJ1ZiwgLyogYmZfcmVsZWFzZWJ1ZmZlciAqLworfTsKKworCitQeVR5cGVPYmplY3QgUHlNZW1vcnlWaWV3X1R5cGUgPSB7CisgICAgUHlWYXJPYmplY3RfSEVBRF9JTklUKCZQeVR5cGVfVHlwZSwgMCkKKyAgICAibWVtb3J5dmlldyIsCisgICAgc2l6ZW9mKFB5TWVtb3J5Vmlld09iamVjdCksCisgICAgMCwKKyAgICAoZGVzdHJ1Y3RvciltZW1vcnlfZGVhbGxvYywgICAgICAgICAgICAgICAvKiB0cF9kZWFsbG9jICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfcHJpbnQgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9nZXRhdHRyICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfc2V0YXR0ciAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2NvbXBhcmUgKi8KKyAgICAocmVwcmZ1bmMpbWVtb3J5X3JlcHIsICAgICAgICAgICAgICAgICAgICAvKiB0cF9yZXByICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfYXNfbnVtYmVyICovCisgICAgJm1lbW9yeV9hc19zZXF1ZW5jZSwgICAgICAgICAgICAgICAgICAgICAgLyogdHBfYXNfc2VxdWVuY2UgKi8KKyAgICAmbWVtb3J5X2FzX21hcHBpbmcsICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9hc19tYXBwaW5nICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfaGFzaCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2NhbGwgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9zdHIgKi8KKyAgICBQeU9iamVjdF9HZW5lcmljR2V0QXR0ciwgICAgICAgICAgICAgICAgICAvKiB0cF9nZXRhdHRybyAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3NldGF0dHJvICovCisgICAgJm1lbW9yeV9hc19idWZmZXIsICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfYXNfYnVmZmVyICovCisgICAgUHlfVFBGTEFHU19ERUZBVUxUIHwgUHlfVFBGTEFHU19IQVZFX0dDIHwKKyAgICAgICAgUHlfVFBGTEFHU19IQVZFX05FV0JVRkZFUiwgICAgICAgICAgICAvKiB0cF9mbGFncyAqLworICAgIG1lbW9yeV9kb2MsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2RvYyAqLworICAgICh0cmF2ZXJzZXByb2MpbWVtb3J5X3RyYXZlcnNlLCAgICAgICAgICAgIC8qIHRwX3RyYXZlcnNlICovCisgICAgKGlucXVpcnkpbWVtb3J5X2NsZWFyLCAgICAgICAgICAgICAgICAgICAgLyogdHBfY2xlYXIgKi8KKyAgICBtZW1vcnlfcmljaGNvbXBhcmUsICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9yaWNoY29tcGFyZSAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3dlYWtsaXN0b2Zmc2V0ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfaXRlciAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2l0ZXJuZXh0ICovCisgICAgbWVtb3J5X21ldGhvZHMsICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfbWV0aG9kcyAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX21lbWJlcnMgKi8KKyAgICBtZW1vcnlfZ2V0c2V0bGlzdCwgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9nZXRzZXQgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9iYXNlICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZGljdCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2Rlc2NyX2dldCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2Rlc2NyX3NldCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2RpY3RvZmZzZXQgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9pbml0ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfYWxsb2MgKi8KKyAgICBtZW1vcnlfbmV3LCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9uZXcgKi8KK307CmRpZmYgLS1naXQgYS9QeXRob24tMi43LjUvT2JqZWN0cy9tZXRob2RvYmplY3QuYyBiL1B5dGhvbi0yLjcuNS9PYmplY3RzL21ldGhvZG9iamVjdC5jCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjBiNjBjYTMKLS0tIC9kZXYvbnVsbAorKysgYi9QeXRob24tMi43LjUvT2JqZWN0cy9tZXRob2RvYmplY3QuYwpAQCAtMCwwICsxLDQyNyBAQAorCisvKiBNZXRob2Qgb2JqZWN0IGltcGxlbWVudGF0aW9uICovCisKKyNpbmNsdWRlICJQeXRob24uaCIKKyNpbmNsdWRlICJzdHJ1Y3RtZW1iZXIuaCIKKworLyogRnJlZSBsaXN0IGZvciBtZXRob2Qgb2JqZWN0cyB0byBzYWZlIG1hbGxvYy9mcmVlIG92ZXJoZWFkCisgKiBUaGUgbV9zZWxmIGVsZW1lbnQgaXMgdXNlZCB0byBjaGFpbiB0aGUgb2JqZWN0cy4KKyAqLworc3RhdGljIFB5Q0Z1bmN0aW9uT2JqZWN0ICpmcmVlX2xpc3QgPSBOVUxMOworc3RhdGljIGludCBudW1mcmVlID0gMDsKKyNpZm5kZWYgUHlDRnVuY3Rpb25fTUFYRlJFRUxJU1QKKyNkZWZpbmUgUHlDRnVuY3Rpb25fTUFYRlJFRUxJU1QgMjU2CisjZW5kaWYKKworUHlPYmplY3QgKgorUHlDRnVuY3Rpb25fTmV3RXgoUHlNZXRob2REZWYgKm1sLCBQeU9iamVjdCAqc2VsZiwgUHlPYmplY3QgKm1vZHVsZSkKK3sKKyAgICBQeUNGdW5jdGlvbk9iamVjdCAqb3A7CisgICAgb3AgPSBmcmVlX2xpc3Q7CisgICAgaWYgKG9wICE9IE5VTEwpIHsKKyAgICAgICAgZnJlZV9saXN0ID0gKFB5Q0Z1bmN0aW9uT2JqZWN0ICopKG9wLT5tX3NlbGYpOworICAgICAgICBQeU9iamVjdF9JTklUKG9wLCAmUHlDRnVuY3Rpb25fVHlwZSk7CisgICAgICAgIG51bWZyZWUtLTsKKyAgICB9CisgICAgZWxzZSB7CisgICAgICAgIG9wID0gUHlPYmplY3RfR0NfTmV3KFB5Q0Z1bmN0aW9uT2JqZWN0LCAmUHlDRnVuY3Rpb25fVHlwZSk7CisgICAgICAgIGlmIChvcCA9PSBOVUxMKQorICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIG9wLT5tX21sID0gbWw7CisgICAgUHlfWElOQ1JFRihzZWxmKTsKKyAgICBvcC0+bV9zZWxmID0gc2VsZjsKKyAgICBQeV9YSU5DUkVGKG1vZHVsZSk7CisgICAgb3AtPm1fbW9kdWxlID0gbW9kdWxlOworICAgIF9QeU9iamVjdF9HQ19UUkFDSyhvcCk7CisgICAgcmV0dXJuIChQeU9iamVjdCAqKW9wOworfQorCitQeUNGdW5jdGlvbgorUHlDRnVuY3Rpb25fR2V0RnVuY3Rpb24oUHlPYmplY3QgKm9wKQoreworICAgIGlmICghUHlDRnVuY3Rpb25fQ2hlY2sob3ApKSB7CisgICAgICAgIFB5RXJyX0JhZEludGVybmFsQ2FsbCgpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgcmV0dXJuICgoUHlDRnVuY3Rpb25PYmplY3QgKilvcCkgLT4gbV9tbCAtPiBtbF9tZXRoOworfQorCitQeU9iamVjdCAqCitQeUNGdW5jdGlvbl9HZXRTZWxmKFB5T2JqZWN0ICpvcCkKK3sKKyAgICBpZiAoIVB5Q0Z1bmN0aW9uX0NoZWNrKG9wKSkgeworICAgICAgICBQeUVycl9CYWRJbnRlcm5hbENhbGwoKTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIHJldHVybiAoKFB5Q0Z1bmN0aW9uT2JqZWN0ICopb3ApIC0+IG1fc2VsZjsKK30KKworaW50CitQeUNGdW5jdGlvbl9HZXRGbGFncyhQeU9iamVjdCAqb3ApCit7CisgICAgaWYgKCFQeUNGdW5jdGlvbl9DaGVjayhvcCkpIHsKKyAgICAgICAgUHlFcnJfQmFkSW50ZXJuYWxDYWxsKCk7CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisgICAgcmV0dXJuICgoUHlDRnVuY3Rpb25PYmplY3QgKilvcCkgLT4gbV9tbCAtPiBtbF9mbGFnczsKK30KKworUHlPYmplY3QgKgorUHlDRnVuY3Rpb25fQ2FsbChQeU9iamVjdCAqZnVuYywgUHlPYmplY3QgKmFyZywgUHlPYmplY3QgKmt3KQoreworICAgIFB5Q0Z1bmN0aW9uT2JqZWN0KiBmID0gKFB5Q0Z1bmN0aW9uT2JqZWN0KilmdW5jOworICAgIFB5Q0Z1bmN0aW9uIG1ldGggPSBQeUNGdW5jdGlvbl9HRVRfRlVOQ1RJT04oZnVuYyk7CisgICAgUHlPYmplY3QgKnNlbGYgPSBQeUNGdW5jdGlvbl9HRVRfU0VMRihmdW5jKTsKKyAgICBQeV9zc2l6ZV90IHNpemU7CisKKyAgICBzd2l0Y2ggKFB5Q0Z1bmN0aW9uX0dFVF9GTEFHUyhmdW5jKSAmIH4oTUVUSF9DTEFTUyB8IE1FVEhfU1RBVElDIHwgTUVUSF9DT0VYSVNUKSkgeworICAgIGNhc2UgTUVUSF9WQVJBUkdTOgorICAgICAgICBpZiAoa3cgPT0gTlVMTCB8fCBQeURpY3RfU2l6ZShrdykgPT0gMCkKKyAgICAgICAgICAgIHJldHVybiAoKm1ldGgpKHNlbGYsIGFyZyk7CisgICAgICAgIGJyZWFrOworICAgIGNhc2UgTUVUSF9WQVJBUkdTIHwgTUVUSF9LRVlXT1JEUzoKKyAgICBjYXNlIE1FVEhfT0xEQVJHUyB8IE1FVEhfS0VZV09SRFM6CisgICAgICAgIHJldHVybiAoKihQeUNGdW5jdGlvbldpdGhLZXl3b3JkcyltZXRoKShzZWxmLCBhcmcsIGt3KTsKKyAgICBjYXNlIE1FVEhfTk9BUkdTOgorICAgICAgICBpZiAoa3cgPT0gTlVMTCB8fCBQeURpY3RfU2l6ZShrdykgPT0gMCkgeworICAgICAgICAgICAgc2l6ZSA9IFB5VHVwbGVfR0VUX1NJWkUoYXJnKTsKKyAgICAgICAgICAgIGlmIChzaXplID09IDApCisgICAgICAgICAgICAgICAgcmV0dXJuICgqbWV0aCkoc2VsZiwgTlVMTCk7CisgICAgICAgICAgICBQeUVycl9Gb3JtYXQoUHlFeGNfVHlwZUVycm9yLAorICAgICAgICAgICAgICAgICIlLjIwMHMoKSB0YWtlcyBubyBhcmd1bWVudHMgKCV6ZCBnaXZlbikiLAorICAgICAgICAgICAgICAgIGYtPm1fbWwtPm1sX25hbWUsIHNpemUpOworICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgICAgIH0KKyAgICAgICAgYnJlYWs7CisgICAgY2FzZSBNRVRIX086CisgICAgICAgIGlmIChrdyA9PSBOVUxMIHx8IFB5RGljdF9TaXplKGt3KSA9PSAwKSB7CisgICAgICAgICAgICBzaXplID0gUHlUdXBsZV9HRVRfU0laRShhcmcpOworICAgICAgICAgICAgaWYgKHNpemUgPT0gMSkKKyAgICAgICAgICAgICAgICByZXR1cm4gKCptZXRoKShzZWxmLCBQeVR1cGxlX0dFVF9JVEVNKGFyZywgMCkpOworICAgICAgICAgICAgUHlFcnJfRm9ybWF0KFB5RXhjX1R5cGVFcnJvciwKKyAgICAgICAgICAgICAgICAiJS4yMDBzKCkgdGFrZXMgZXhhY3RseSBvbmUgYXJndW1lbnQgKCV6ZCBnaXZlbikiLAorICAgICAgICAgICAgICAgIGYtPm1fbWwtPm1sX25hbWUsIHNpemUpOworICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgICAgIH0KKyAgICAgICAgYnJlYWs7CisgICAgY2FzZSBNRVRIX09MREFSR1M6CisgICAgICAgIC8qIHRoZSByZWFsbHkgb2xkIHN0eWxlICovCisgICAgICAgIGlmIChrdyA9PSBOVUxMIHx8IFB5RGljdF9TaXplKGt3KSA9PSAwKSB7CisgICAgICAgICAgICBzaXplID0gUHlUdXBsZV9HRVRfU0laRShhcmcpOworICAgICAgICAgICAgaWYgKHNpemUgPT0gMSkKKyAgICAgICAgICAgICAgICBhcmcgPSBQeVR1cGxlX0dFVF9JVEVNKGFyZywgMCk7CisgICAgICAgICAgICBlbHNlIGlmIChzaXplID09IDApCisgICAgICAgICAgICAgICAgYXJnID0gTlVMTDsKKyAgICAgICAgICAgIHJldHVybiAoKm1ldGgpKHNlbGYsIGFyZyk7CisgICAgICAgIH0KKyAgICAgICAgYnJlYWs7CisgICAgZGVmYXVsdDoKKyAgICAgICAgUHlFcnJfQmFkSW50ZXJuYWxDYWxsKCk7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICBQeUVycl9Gb3JtYXQoUHlFeGNfVHlwZUVycm9yLCAiJS4yMDBzKCkgdGFrZXMgbm8ga2V5d29yZCBhcmd1bWVudHMiLAorICAgICAgICAgICAgICAgICBmLT5tX21sLT5tbF9uYW1lKTsKKyAgICByZXR1cm4gTlVMTDsKK30KKworLyogTWV0aG9kcyAodGhlIHN0YW5kYXJkIGJ1aWx0LWluIG1ldGhvZHMsIHRoYXQgaXMpICovCisKK3N0YXRpYyB2b2lkCittZXRoX2RlYWxsb2MoUHlDRnVuY3Rpb25PYmplY3QgKm0pCit7CisgICAgX1B5T2JqZWN0X0dDX1VOVFJBQ0sobSk7CisgICAgUHlfWERFQ1JFRihtLT5tX3NlbGYpOworICAgIFB5X1hERUNSRUYobS0+bV9tb2R1bGUpOworICAgIGlmIChudW1mcmVlIDwgUHlDRnVuY3Rpb25fTUFYRlJFRUxJU1QpIHsKKyAgICAgICAgbS0+bV9zZWxmID0gKFB5T2JqZWN0ICopZnJlZV9saXN0OworICAgICAgICBmcmVlX2xpc3QgPSBtOworICAgICAgICBudW1mcmVlKys7CisgICAgfQorICAgIGVsc2UgeworICAgICAgICBQeU9iamVjdF9HQ19EZWwobSk7CisgICAgfQorfQorCitzdGF0aWMgUHlPYmplY3QgKgorbWV0aF9nZXRfX2RvY19fKFB5Q0Z1bmN0aW9uT2JqZWN0ICptLCB2b2lkICpjbG9zdXJlKQoreworICAgIGNvbnN0IGNoYXIgKmRvYyA9IG0tPm1fbWwtPm1sX2RvYzsKKworICAgIGlmIChkb2MgIT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIFB5U3RyaW5nX0Zyb21TdHJpbmcoZG9jKTsKKyAgICBQeV9JTkNSRUYoUHlfTm9uZSk7CisgICAgcmV0dXJuIFB5X05vbmU7Cit9CisKK3N0YXRpYyBQeU9iamVjdCAqCittZXRoX2dldF9fbmFtZV9fKFB5Q0Z1bmN0aW9uT2JqZWN0ICptLCB2b2lkICpjbG9zdXJlKQoreworICAgIHJldHVybiBQeVN0cmluZ19Gcm9tU3RyaW5nKG0tPm1fbWwtPm1sX25hbWUpOworfQorCitzdGF0aWMgaW50CittZXRoX3RyYXZlcnNlKFB5Q0Z1bmN0aW9uT2JqZWN0ICptLCB2aXNpdHByb2MgdmlzaXQsIHZvaWQgKmFyZykKK3sKKyAgICBQeV9WSVNJVChtLT5tX3NlbGYpOworICAgIFB5X1ZJU0lUKG0tPm1fbW9kdWxlKTsKKyAgICByZXR1cm4gMDsKK30KKworc3RhdGljIFB5T2JqZWN0ICoKK21ldGhfZ2V0X19zZWxmX18oUHlDRnVuY3Rpb25PYmplY3QgKm0sIHZvaWQgKmNsb3N1cmUpCit7CisgICAgUHlPYmplY3QgKnNlbGY7CisgICAgaWYgKFB5RXZhbF9HZXRSZXN0cmljdGVkKCkpIHsKKyAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1J1bnRpbWVFcnJvciwKKyAgICAgICAgICAgICJtZXRob2QuX19zZWxmX18gbm90IGFjY2Vzc2libGUgaW4gcmVzdHJpY3RlZCBtb2RlIik7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICBzZWxmID0gbS0+bV9zZWxmOworICAgIGlmIChzZWxmID09IE5VTEwpCisgICAgICAgIHNlbGYgPSBQeV9Ob25lOworICAgIFB5X0lOQ1JFRihzZWxmKTsKKyAgICByZXR1cm4gc2VsZjsKK30KKworc3RhdGljIFB5R2V0U2V0RGVmIG1ldGhfZ2V0c2V0cyBbXSA9IHsKKyAgICB7Il9fZG9jX18iLCAgKGdldHRlciltZXRoX2dldF9fZG9jX18sICBOVUxMLCBOVUxMfSwKKyAgICB7Il9fbmFtZV9fIiwgKGdldHRlciltZXRoX2dldF9fbmFtZV9fLCBOVUxMLCBOVUxMfSwKKyAgICB7Il9fc2VsZl9fIiwgKGdldHRlciltZXRoX2dldF9fc2VsZl9fLCBOVUxMLCBOVUxMfSwKKyAgICB7MH0KK307CisKKyNkZWZpbmUgT0ZGKHgpIG9mZnNldG9mKFB5Q0Z1bmN0aW9uT2JqZWN0LCB4KQorCitzdGF0aWMgUHlNZW1iZXJEZWYgbWV0aF9tZW1iZXJzW10gPSB7CisgICAgeyJfX21vZHVsZV9fIiwgICAgVF9PQkpFQ1QsICAgICBPRkYobV9tb2R1bGUpLCBQWV9XUklURV9SRVNUUklDVEVEfSwKKyAgICB7TlVMTH0KK307CisKK3N0YXRpYyBQeU9iamVjdCAqCittZXRoX3JlcHIoUHlDRnVuY3Rpb25PYmplY3QgKm0pCit7CisgICAgaWYgKG0tPm1fc2VsZiA9PSBOVUxMKQorICAgICAgICByZXR1cm4gUHlTdHJpbmdfRnJvbUZvcm1hdCgiPGJ1aWx0LWluIGZ1bmN0aW9uICVzPiIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG0tPm1fbWwtPm1sX25hbWUpOworICAgIHJldHVybiBQeVN0cmluZ19Gcm9tRm9ybWF0KCI8YnVpbHQtaW4gbWV0aG9kICVzIG9mICVzIG9iamVjdCBhdCAlcD4iLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG0tPm1fbWwtPm1sX25hbWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbS0+bV9zZWxmLT5vYl90eXBlLT50cF9uYW1lLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG0tPm1fc2VsZik7Cit9CisKK3N0YXRpYyBpbnQKK21ldGhfY29tcGFyZShQeUNGdW5jdGlvbk9iamVjdCAqYSwgUHlDRnVuY3Rpb25PYmplY3QgKmIpCit7CisgICAgaWYgKGEtPm1fc2VsZiAhPSBiLT5tX3NlbGYpCisgICAgICAgIHJldHVybiAoYS0+bV9zZWxmIDwgYi0+bV9zZWxmKSA/IC0xIDogMTsKKyAgICBpZiAoYS0+bV9tbC0+bWxfbWV0aCA9PSBiLT5tX21sLT5tbF9tZXRoKQorICAgICAgICByZXR1cm4gMDsKKyAgICBpZiAoc3RyY21wKGEtPm1fbWwtPm1sX25hbWUsIGItPm1fbWwtPm1sX25hbWUpIDwgMCkKKyAgICAgICAgcmV0dXJuIC0xOworICAgIGVsc2UKKyAgICAgICAgcmV0dXJuIDE7Cit9CisKK3N0YXRpYyBQeU9iamVjdCAqCittZXRoX3JpY2hjb21wYXJlKFB5T2JqZWN0ICpzZWxmLCBQeU9iamVjdCAqb3RoZXIsIGludCBvcCkKK3sKKyAgICBQeUNGdW5jdGlvbk9iamVjdCAqYSwgKmI7CisgICAgUHlPYmplY3QgKnJlczsKKyAgICBpbnQgZXE7CisKKyAgICBpZiAob3AgIT0gUHlfRVEgJiYgb3AgIT0gUHlfTkUpIHsKKyAgICAgICAgLyogUHkzSyB3YXJuaW5nIGlmIGNvbXBhcmlzb24gaXNuJ3QgPT0gb3IgIT0uICAqLworICAgICAgICBpZiAoUHlFcnJfV2FyblB5M2soImJ1aWx0aW5fZnVuY3Rpb25fb3JfbWV0aG9kIG9yZGVyICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICJjb21wYXJpc29ucyBub3Qgc3VwcG9ydGVkIGluIDMueCIsIDEpIDwgMCkgeworICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgICAgIH0KKworICAgICAgICBQeV9JTkNSRUYoUHlfTm90SW1wbGVtZW50ZWQpOworICAgICAgICByZXR1cm4gUHlfTm90SW1wbGVtZW50ZWQ7CisgICAgfQorICAgIGVsc2UgaWYgKCFQeUNGdW5jdGlvbl9DaGVjayhzZWxmKSB8fCAhUHlDRnVuY3Rpb25fQ2hlY2sob3RoZXIpKSB7CisgICAgICAgIFB5X0lOQ1JFRihQeV9Ob3RJbXBsZW1lbnRlZCk7CisgICAgICAgIHJldHVybiBQeV9Ob3RJbXBsZW1lbnRlZDsKKyAgICB9CisgICAgYSA9IChQeUNGdW5jdGlvbk9iamVjdCAqKXNlbGY7CisgICAgYiA9IChQeUNGdW5jdGlvbk9iamVjdCAqKW90aGVyOworICAgIGVxID0gYS0+bV9zZWxmID09IGItPm1fc2VsZjsKKyAgICBpZiAoZXEpCisgICAgICAgIGVxID0gYS0+bV9tbC0+bWxfbWV0aCA9PSBiLT5tX21sLT5tbF9tZXRoOworICAgIGlmIChvcCA9PSBQeV9FUSkKKyAgICAgICAgcmVzID0gZXEgPyBQeV9UcnVlIDogUHlfRmFsc2U7CisgICAgZWxzZQorICAgICAgICByZXMgPSBlcSA/IFB5X0ZhbHNlIDogUHlfVHJ1ZTsKKyAgICBQeV9JTkNSRUYocmVzKTsKKyAgICByZXR1cm4gcmVzOworfQorCitzdGF0aWMgbG9uZworbWV0aF9oYXNoKFB5Q0Z1bmN0aW9uT2JqZWN0ICphKQoreworICAgIGxvbmcgeCx5OworICAgIGlmIChhLT5tX3NlbGYgPT0gTlVMTCkKKyAgICAgICAgeCA9IDA7CisgICAgZWxzZSB7CisgICAgICAgIHggPSBQeU9iamVjdF9IYXNoKGEtPm1fc2VsZik7CisgICAgICAgIGlmICh4ID09IC0xKQorICAgICAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKyAgICB5ID0gX1B5X0hhc2hQb2ludGVyKCh2b2lkKikoYS0+bV9tbC0+bWxfbWV0aCkpOworICAgIGlmICh5ID09IC0xKQorICAgICAgICByZXR1cm4gLTE7CisgICAgeCBePSB5OworICAgIGlmICh4ID09IC0xKQorICAgICAgICB4ID0gLTI7CisgICAgcmV0dXJuIHg7Cit9CisKKworUHlUeXBlT2JqZWN0IFB5Q0Z1bmN0aW9uX1R5cGUgPSB7CisgICAgUHlWYXJPYmplY3RfSEVBRF9JTklUKCZQeVR5cGVfVHlwZSwgMCkKKyAgICAiYnVpbHRpbl9mdW5jdGlvbl9vcl9tZXRob2QiLAorICAgIHNpemVvZihQeUNGdW5jdGlvbk9iamVjdCksCisgICAgMCwKKyAgICAoZGVzdHJ1Y3RvciltZXRoX2RlYWxsb2MsICAgICAgICAgICAgICAgICAgIC8qIHRwX2RlYWxsb2MgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3ByaW50ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9nZXRhdHRyICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9zZXRhdHRyICovCisgICAgKGNtcGZ1bmMpbWV0aF9jb21wYXJlLCAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9jb21wYXJlICovCisgICAgKHJlcHJmdW5jKW1ldGhfcmVwciwgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9yZXByICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9hc19udW1iZXIgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2FzX3NlcXVlbmNlICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9hc19tYXBwaW5nICovCisgICAgKGhhc2hmdW5jKW1ldGhfaGFzaCwgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9oYXNoICovCisgICAgUHlDRnVuY3Rpb25fQ2FsbCwgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9jYWxsICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9zdHIgKi8KKyAgICBQeU9iamVjdF9HZW5lcmljR2V0QXR0ciwgICAgICAgICAgICAgICAgICAgIC8qIHRwX2dldGF0dHJvICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9zZXRhdHRybyAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfYXNfYnVmZmVyICovCisgICAgUHlfVFBGTEFHU19ERUZBVUxUIHwgUHlfVFBGTEFHU19IQVZFX0dDLC8qIHRwX2ZsYWdzICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9kb2MgKi8KKyAgICAodHJhdmVyc2Vwcm9jKW1ldGhfdHJhdmVyc2UsICAgICAgICAgICAgICAgIC8qIHRwX3RyYXZlcnNlICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9jbGVhciAqLworICAgIG1ldGhfcmljaGNvbXBhcmUsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3JpY2hjb21wYXJlICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF93ZWFrbGlzdG9mZnNldCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfaXRlciAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfaXRlcm5leHQgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX21ldGhvZHMgKi8KKyAgICBtZXRoX21lbWJlcnMsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX21lbWJlcnMgKi8KKyAgICBtZXRoX2dldHNldHMsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2dldHNldCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfYmFzZSAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZGljdCAqLworfTsKKworLyogTGlzdCBhbGwgbWV0aG9kcyBpbiBhIGNoYWluIC0tIGhlbHBlciBmb3IgZmluZG1ldGhvZGluY2hhaW4gKi8KKworc3RhdGljIFB5T2JqZWN0ICoKK2xpc3RtZXRob2RjaGFpbihQeU1ldGhvZENoYWluICpjaGFpbikKK3sKKyAgICBQeU1ldGhvZENoYWluICpjOworICAgIFB5TWV0aG9kRGVmICptbDsKKyAgICBpbnQgaSwgbjsKKyAgICBQeU9iamVjdCAqdjsKKworICAgIG4gPSAwOworICAgIGZvciAoYyA9IGNoYWluOyBjICE9IE5VTEw7IGMgPSBjLT5saW5rKSB7CisgICAgICAgIGZvciAobWwgPSBjLT5tZXRob2RzOyBtbC0+bWxfbmFtZSAhPSBOVUxMOyBtbCsrKQorICAgICAgICAgICAgbisrOworICAgIH0KKyAgICB2ID0gUHlMaXN0X05ldyhuKTsKKyAgICBpZiAodiA9PSBOVUxMKQorICAgICAgICByZXR1cm4gTlVMTDsKKyAgICBpID0gMDsKKyAgICBmb3IgKGMgPSBjaGFpbjsgYyAhPSBOVUxMOyBjID0gYy0+bGluaykgeworICAgICAgICBmb3IgKG1sID0gYy0+bWV0aG9kczsgbWwtPm1sX25hbWUgIT0gTlVMTDsgbWwrKykgeworICAgICAgICAgICAgUHlMaXN0X1NldEl0ZW0odiwgaSwgUHlTdHJpbmdfRnJvbVN0cmluZyhtbC0+bWxfbmFtZSkpOworICAgICAgICAgICAgaSsrOworICAgICAgICB9CisgICAgfQorICAgIGlmIChQeUVycl9PY2N1cnJlZCgpKSB7CisgICAgICAgIFB5X0RFQ1JFRih2KTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIFB5TGlzdF9Tb3J0KHYpOworICAgIHJldHVybiB2OworfQorCisvKiBGaW5kIGEgbWV0aG9kIGluIGEgbWV0aG9kIGNoYWluICovCisKK1B5T2JqZWN0ICoKK1B5X0ZpbmRNZXRob2RJbkNoYWluKFB5TWV0aG9kQ2hhaW4gKmNoYWluLCBQeU9iamVjdCAqc2VsZiwgY29uc3QgY2hhciAqbmFtZSkKK3sKKyAgICBpZiAobmFtZVswXSA9PSAnXycgJiYgbmFtZVsxXSA9PSAnXycpIHsKKyAgICAgICAgaWYgKHN0cmNtcChuYW1lLCAiX19tZXRob2RzX18iKSA9PSAwKSB7CisgICAgICAgICAgICBpZiAoUHlFcnJfV2FyblB5M2soIl9fbWV0aG9kc19fIG5vdCBzdXBwb3J0ZWQgaW4gMy54IiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAxKSA8IDApCisgICAgICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgICAgICAgICByZXR1cm4gbGlzdG1ldGhvZGNoYWluKGNoYWluKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoc3RyY21wKG5hbWUsICJfX2RvY19fIikgPT0gMCkgeworICAgICAgICAgICAgY29uc3QgY2hhciAqZG9jID0gc2VsZi0+b2JfdHlwZS0+dHBfZG9jOworICAgICAgICAgICAgaWYgKGRvYyAhPSBOVUxMKQorICAgICAgICAgICAgICAgIHJldHVybiBQeVN0cmluZ19Gcm9tU3RyaW5nKGRvYyk7CisgICAgICAgIH0KKyAgICB9CisgICAgd2hpbGUgKGNoYWluICE9IE5VTEwpIHsKKyAgICAgICAgUHlNZXRob2REZWYgKm1sID0gY2hhaW4tPm1ldGhvZHM7CisgICAgICAgIGZvciAoOyBtbC0+bWxfbmFtZSAhPSBOVUxMOyBtbCsrKSB7CisgICAgICAgICAgICBpZiAobmFtZVswXSA9PSBtbC0+bWxfbmFtZVswXSAmJgorICAgICAgICAgICAgICAgIHN0cmNtcChuYW1lKzEsIG1sLT5tbF9uYW1lKzEpID09IDApCisgICAgICAgICAgICAgICAgLyogWFhYICovCisgICAgICAgICAgICAgICAgcmV0dXJuIFB5Q0Z1bmN0aW9uX05ldyhtbCwgc2VsZik7CisgICAgICAgIH0KKyAgICAgICAgY2hhaW4gPSBjaGFpbi0+bGluazsKKyAgICB9CisgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX0F0dHJpYnV0ZUVycm9yLCBuYW1lKTsKKyAgICByZXR1cm4gTlVMTDsKK30KKworLyogRmluZCBhIG1ldGhvZCBpbiBhIHNpbmdsZSBtZXRob2QgbGlzdCAqLworCitQeU9iamVjdCAqCitQeV9GaW5kTWV0aG9kKFB5TWV0aG9kRGVmICptZXRob2RzLCBQeU9iamVjdCAqc2VsZiwgY29uc3QgY2hhciAqbmFtZSkKK3sKKyAgICBQeU1ldGhvZENoYWluIGNoYWluOworICAgIGNoYWluLm1ldGhvZHMgPSBtZXRob2RzOworICAgIGNoYWluLmxpbmsgPSBOVUxMOworICAgIHJldHVybiBQeV9GaW5kTWV0aG9kSW5DaGFpbigmY2hhaW4sIHNlbGYsIG5hbWUpOworfQorCisvKiBDbGVhciBvdXQgdGhlIGZyZWUgbGlzdCAqLworCitpbnQKK1B5Q0Z1bmN0aW9uX0NsZWFyRnJlZUxpc3Qodm9pZCkKK3sKKyAgICBpbnQgZnJlZWxpc3Rfc2l6ZSA9IG51bWZyZWU7CisKKyAgICB3aGlsZSAoZnJlZV9saXN0KSB7CisgICAgICAgIFB5Q0Z1bmN0aW9uT2JqZWN0ICp2ID0gZnJlZV9saXN0OworICAgICAgICBmcmVlX2xpc3QgPSAoUHlDRnVuY3Rpb25PYmplY3QgKikodi0+bV9zZWxmKTsKKyAgICAgICAgUHlPYmplY3RfR0NfRGVsKHYpOworICAgICAgICBudW1mcmVlLS07CisgICAgfQorICAgIGFzc2VydChudW1mcmVlID09IDApOworICAgIHJldHVybiBmcmVlbGlzdF9zaXplOworfQorCit2b2lkCitQeUNGdW5jdGlvbl9GaW5pKHZvaWQpCit7CisgICAgKHZvaWQpUHlDRnVuY3Rpb25fQ2xlYXJGcmVlTGlzdCgpOworfQorCisvKiBQeUNGdW5jdGlvbl9OZXcoKSBpcyBub3cganVzdCBhIG1hY3JvIHRoYXQgY2FsbHMgUHlDRnVuY3Rpb25fTmV3RXgoKSwKKyAgIGJ1dCBpdCdzIHBhcnQgb2YgdGhlIEFQSSBzbyB3ZSBuZWVkIHRvIGtlZXAgYSBmdW5jdGlvbiBhcm91bmQgdGhhdAorICAgZXhpc3RpbmcgQyBleHRlbnNpb25zIGNhbiBjYWxsLgorKi8KKworI3VuZGVmIFB5Q0Z1bmN0aW9uX05ldworUHlBUElfRlVOQyhQeU9iamVjdCAqKSBQeUNGdW5jdGlvbl9OZXcoUHlNZXRob2REZWYgKiwgUHlPYmplY3QgKik7CisKK1B5T2JqZWN0ICoKK1B5Q0Z1bmN0aW9uX05ldyhQeU1ldGhvZERlZiAqbWwsIFB5T2JqZWN0ICpzZWxmKQoreworICAgIHJldHVybiBQeUNGdW5jdGlvbl9OZXdFeChtbCwgc2VsZiwgTlVMTCk7Cit9CmRpZmYgLS1naXQgYS9QeXRob24tMi43LjUvT2JqZWN0cy9tb2R1bGVvYmplY3QuYyBiL1B5dGhvbi0yLjcuNS9PYmplY3RzL21vZHVsZW9iamVjdC5jCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjA4ZTk3NDAKLS0tIC9kZXYvbnVsbAorKysgYi9QeXRob24tMi43LjUvT2JqZWN0cy9tb2R1bGVvYmplY3QuYwpAQCAtMCwwICsxLDI2MCBAQAorCisvKiBNb2R1bGUgb2JqZWN0IGltcGxlbWVudGF0aW9uICovCisKKyNpbmNsdWRlICJQeXRob24uaCIKKyNpbmNsdWRlICJzdHJ1Y3RtZW1iZXIuaCIKKwordHlwZWRlZiBzdHJ1Y3QgeworICAgIFB5T2JqZWN0X0hFQUQKKyAgICBQeU9iamVjdCAqbWRfZGljdDsKK30gUHlNb2R1bGVPYmplY3Q7CisKK3N0YXRpYyBQeU1lbWJlckRlZiBtb2R1bGVfbWVtYmVyc1tdID0geworICAgIHsiX19kaWN0X18iLCBUX09CSkVDVCwgb2Zmc2V0b2YoUHlNb2R1bGVPYmplY3QsIG1kX2RpY3QpLCBSRUFET05MWX0sCisgICAgezB9Cit9OworCitQeU9iamVjdCAqCitQeU1vZHVsZV9OZXcoY29uc3QgY2hhciAqbmFtZSkKK3sKKyAgICBQeU1vZHVsZU9iamVjdCAqbTsKKyAgICBQeU9iamVjdCAqbmFtZW9iajsKKyAgICBtID0gUHlPYmplY3RfR0NfTmV3KFB5TW9kdWxlT2JqZWN0LCAmUHlNb2R1bGVfVHlwZSk7CisgICAgaWYgKG0gPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgbmFtZW9iaiA9IFB5U3RyaW5nX0Zyb21TdHJpbmcobmFtZSk7CisgICAgbS0+bWRfZGljdCA9IFB5RGljdF9OZXcoKTsKKyAgICBpZiAobS0+bWRfZGljdCA9PSBOVUxMIHx8IG5hbWVvYmogPT0gTlVMTCkKKyAgICAgICAgZ290byBmYWlsOworICAgIGlmIChQeURpY3RfU2V0SXRlbVN0cmluZyhtLT5tZF9kaWN0LCAiX19uYW1lX18iLCBuYW1lb2JqKSAhPSAwKQorICAgICAgICBnb3RvIGZhaWw7CisgICAgaWYgKFB5RGljdF9TZXRJdGVtU3RyaW5nKG0tPm1kX2RpY3QsICJfX2RvY19fIiwgUHlfTm9uZSkgIT0gMCkKKyAgICAgICAgZ290byBmYWlsOworICAgIGlmIChQeURpY3RfU2V0SXRlbVN0cmluZyhtLT5tZF9kaWN0LCAiX19wYWNrYWdlX18iLCBQeV9Ob25lKSAhPSAwKQorICAgICAgICBnb3RvIGZhaWw7CisgICAgUHlfREVDUkVGKG5hbWVvYmopOworICAgIFB5T2JqZWN0X0dDX1RyYWNrKG0pOworICAgIHJldHVybiAoUHlPYmplY3QgKiltOworCisgZmFpbDoKKyAgICBQeV9YREVDUkVGKG5hbWVvYmopOworICAgIFB5X0RFQ1JFRihtKTsKKyAgICByZXR1cm4gTlVMTDsKK30KKworUHlPYmplY3QgKgorUHlNb2R1bGVfR2V0RGljdChQeU9iamVjdCAqbSkKK3sKKyAgICBQeU9iamVjdCAqZDsKKyAgICBpZiAoIVB5TW9kdWxlX0NoZWNrKG0pKSB7CisgICAgICAgIFB5RXJyX0JhZEludGVybmFsQ2FsbCgpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgZCA9ICgoUHlNb2R1bGVPYmplY3QgKiltKSAtPiBtZF9kaWN0OworICAgIGlmIChkID09IE5VTEwpCisgICAgICAgICgoUHlNb2R1bGVPYmplY3QgKiltKSAtPiBtZF9kaWN0ID0gZCA9IFB5RGljdF9OZXcoKTsKKyAgICByZXR1cm4gZDsKK30KKworY2hhciAqCitQeU1vZHVsZV9HZXROYW1lKFB5T2JqZWN0ICptKQoreworICAgIFB5T2JqZWN0ICpkOworICAgIFB5T2JqZWN0ICpuYW1lb2JqOworICAgIGlmICghUHlNb2R1bGVfQ2hlY2sobSkpIHsKKyAgICAgICAgUHlFcnJfQmFkQXJndW1lbnQoKTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIGQgPSAoKFB5TW9kdWxlT2JqZWN0ICopbSktPm1kX2RpY3Q7CisgICAgaWYgKGQgPT0gTlVMTCB8fAorICAgICAgICAobmFtZW9iaiA9IFB5RGljdF9HZXRJdGVtU3RyaW5nKGQsICJfX25hbWVfXyIpKSA9PSBOVUxMIHx8CisgICAgICAgICFQeVN0cmluZ19DaGVjayhuYW1lb2JqKSkKKyAgICB7CisgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19TeXN0ZW1FcnJvciwgIm5hbWVsZXNzIG1vZHVsZSIpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgcmV0dXJuIFB5U3RyaW5nX0FzU3RyaW5nKG5hbWVvYmopOworfQorCitjaGFyICoKK1B5TW9kdWxlX0dldEZpbGVuYW1lKFB5T2JqZWN0ICptKQoreworICAgIFB5T2JqZWN0ICpkOworICAgIFB5T2JqZWN0ICpmaWxlb2JqOworICAgIGlmICghUHlNb2R1bGVfQ2hlY2sobSkpIHsKKyAgICAgICAgUHlFcnJfQmFkQXJndW1lbnQoKTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIGQgPSAoKFB5TW9kdWxlT2JqZWN0ICopbSktPm1kX2RpY3Q7CisgICAgaWYgKGQgPT0gTlVMTCB8fAorICAgICAgICAoZmlsZW9iaiA9IFB5RGljdF9HZXRJdGVtU3RyaW5nKGQsICJfX2ZpbGVfXyIpKSA9PSBOVUxMIHx8CisgICAgICAgICFQeVN0cmluZ19DaGVjayhmaWxlb2JqKSkKKyAgICB7CisgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19TeXN0ZW1FcnJvciwgIm1vZHVsZSBmaWxlbmFtZSBtaXNzaW5nIik7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICByZXR1cm4gUHlTdHJpbmdfQXNTdHJpbmcoZmlsZW9iaik7Cit9CisKK3ZvaWQKK19QeU1vZHVsZV9DbGVhcihQeU9iamVjdCAqbSkKK3sKKyAgICAvKiBUbyBtYWtlIHRoZSBleGVjdXRpb24gb3JkZXIgb2YgZGVzdHJ1Y3RvcnMgZm9yIGdsb2JhbAorICAgICAgIG9iamVjdHMgYSBiaXQgbW9yZSBwcmVkaWN0YWJsZSwgd2UgZmlyc3QgemFwIGFsbCBvYmplY3RzCisgICAgICAgd2hvc2UgbmFtZSBzdGFydHMgd2l0aCBhIHNpbmdsZSB1bmRlcnNjb3JlLCBiZWZvcmUgd2UgY2xlYXIKKyAgICAgICB0aGUgZW50aXJlIGRpY3Rpb25hcnkuICBXZSB6YXAgdGhlbSBieSByZXBsYWNpbmcgdGhlbSB3aXRoCisgICAgICAgTm9uZSwgcmF0aGVyIHRoYW4gZGVsZXRpbmcgdGhlbSBmcm9tIHRoZSBkaWN0aW9uYXJ5LCB0bworICAgICAgIGF2b2lkIHJlaGFzaGluZyB0aGUgZGljdGlvbmFyeSAodG8gc29tZSBleHRlbnQpLiAqLworCisgICAgUHlfc3NpemVfdCBwb3M7CisgICAgUHlPYmplY3QgKmtleSwgKnZhbHVlOworICAgIFB5T2JqZWN0ICpkOworCisgICAgZCA9ICgoUHlNb2R1bGVPYmplY3QgKiltKS0+bWRfZGljdDsKKyAgICBpZiAoZCA9PSBOVUxMKQorICAgICAgICByZXR1cm47CisKKyAgICAvKiBGaXJzdCwgY2xlYXIgb25seSBuYW1lcyBzdGFydGluZyB3aXRoIGEgc2luZ2xlIHVuZGVyc2NvcmUgKi8KKyAgICBwb3MgPSAwOworICAgIHdoaWxlIChQeURpY3RfTmV4dChkLCAmcG9zLCAma2V5LCAmdmFsdWUpKSB7CisgICAgICAgIGlmICh2YWx1ZSAhPSBQeV9Ob25lICYmIFB5U3RyaW5nX0NoZWNrKGtleSkpIHsKKyAgICAgICAgICAgIGNoYXIgKnMgPSBQeVN0cmluZ19Bc1N0cmluZyhrZXkpOworICAgICAgICAgICAgaWYgKHNbMF0gPT0gJ18nICYmIHNbMV0gIT0gJ18nKSB7CisgICAgICAgICAgICAgICAgaWYgKFB5X1ZlcmJvc2VGbGFnID4gMSkKKyAgICAgICAgICAgICAgICAgICAgUHlTeXNfV3JpdGVTdGRlcnIoIiMgICBjbGVhclsxXSAlc1xuIiwgcyk7CisgICAgICAgICAgICAgICAgUHlEaWN0X1NldEl0ZW0oZCwga2V5LCBQeV9Ob25lKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qIE5leHQsIGNsZWFyIGFsbCBuYW1lcyBleGNlcHQgZm9yIF9fYnVpbHRpbnNfXyAqLworICAgIHBvcyA9IDA7CisgICAgd2hpbGUgKFB5RGljdF9OZXh0KGQsICZwb3MsICZrZXksICZ2YWx1ZSkpIHsKKyAgICAgICAgaWYgKHZhbHVlICE9IFB5X05vbmUgJiYgUHlTdHJpbmdfQ2hlY2soa2V5KSkgeworICAgICAgICAgICAgY2hhciAqcyA9IFB5U3RyaW5nX0FzU3RyaW5nKGtleSk7CisgICAgICAgICAgICBpZiAoc1swXSAhPSAnXycgfHwgc3RyY21wKHMsICJfX2J1aWx0aW5zX18iKSAhPSAwKSB7CisgICAgICAgICAgICAgICAgaWYgKFB5X1ZlcmJvc2VGbGFnID4gMSkKKyAgICAgICAgICAgICAgICAgICAgUHlTeXNfV3JpdGVTdGRlcnIoIiMgICBjbGVhclsyXSAlc1xuIiwgcyk7CisgICAgICAgICAgICAgICAgUHlEaWN0X1NldEl0ZW0oZCwga2V5LCBQeV9Ob25lKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIC8qIE5vdGU6IHdlIGxlYXZlIF9fYnVpbHRpbnNfXyBpbiBwbGFjZSwgc28gdGhhdCBkZXN0cnVjdG9ycworICAgICAgIG9mIG5vbi1nbG9iYWwgb2JqZWN0cyBkZWZpbmVkIGluIHRoaXMgbW9kdWxlIGNhbiBzdGlsbCB1c2UKKyAgICAgICBidWlsdGlucywgaW4gcGFydGljdWxhcmx5ICdOb25lJy4gKi8KKworfQorCisvKiBNZXRob2RzICovCisKK3N0YXRpYyBpbnQKK21vZHVsZV9pbml0KFB5TW9kdWxlT2JqZWN0ICptLCBQeU9iamVjdCAqYXJncywgUHlPYmplY3QgKmt3ZHMpCit7CisgICAgc3RhdGljIGNoYXIgKmt3bGlzdFtdID0geyJuYW1lIiwgImRvYyIsIE5VTEx9OworICAgIFB5T2JqZWN0ICpkaWN0LCAqbmFtZSA9IFB5X05vbmUsICpkb2MgPSBQeV9Ob25lOworICAgIGlmICghUHlBcmdfUGFyc2VUdXBsZUFuZEtleXdvcmRzKGFyZ3MsIGt3ZHMsICJTfE86bW9kdWxlLl9faW5pdF9fIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBrd2xpc3QsICZuYW1lLCAmZG9jKSkKKyAgICAgICAgcmV0dXJuIC0xOworICAgIGRpY3QgPSBtLT5tZF9kaWN0OworICAgIGlmIChkaWN0ID09IE5VTEwpIHsKKyAgICAgICAgZGljdCA9IFB5RGljdF9OZXcoKTsKKyAgICAgICAgaWYgKGRpY3QgPT0gTlVMTCkKKyAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgbS0+bWRfZGljdCA9IGRpY3Q7CisgICAgfQorICAgIGlmIChQeURpY3RfU2V0SXRlbVN0cmluZyhkaWN0LCAiX19uYW1lX18iLCBuYW1lKSA8IDApCisgICAgICAgIHJldHVybiAtMTsKKyAgICBpZiAoUHlEaWN0X1NldEl0ZW1TdHJpbmcoZGljdCwgIl9fZG9jX18iLCBkb2MpIDwgMCkKKyAgICAgICAgcmV0dXJuIC0xOworICAgIHJldHVybiAwOworfQorCitzdGF0aWMgdm9pZAorbW9kdWxlX2RlYWxsb2MoUHlNb2R1bGVPYmplY3QgKm0pCit7CisgICAgUHlPYmplY3RfR0NfVW5UcmFjayhtKTsKKyAgICBpZiAobS0+bWRfZGljdCAhPSBOVUxMKSB7CisgICAgICAgIF9QeU1vZHVsZV9DbGVhcigoUHlPYmplY3QgKiltKTsKKyAgICAgICAgUHlfREVDUkVGKG0tPm1kX2RpY3QpOworICAgIH0KKyAgICBQeV9UWVBFKG0pLT50cF9mcmVlKChQeU9iamVjdCAqKW0pOworfQorCitzdGF0aWMgUHlPYmplY3QgKgorbW9kdWxlX3JlcHIoUHlNb2R1bGVPYmplY3QgKm0pCit7CisgICAgY2hhciAqbmFtZTsKKyAgICBjaGFyICpmaWxlbmFtZTsKKworICAgIG5hbWUgPSBQeU1vZHVsZV9HZXROYW1lKChQeU9iamVjdCAqKW0pOworICAgIGlmIChuYW1lID09IE5VTEwpIHsKKyAgICAgICAgUHlFcnJfQ2xlYXIoKTsKKyAgICAgICAgbmFtZSA9ICI/IjsKKyAgICB9CisgICAgZmlsZW5hbWUgPSBQeU1vZHVsZV9HZXRGaWxlbmFtZSgoUHlPYmplY3QgKiltKTsKKyAgICBpZiAoZmlsZW5hbWUgPT0gTlVMTCkgeworICAgICAgICBQeUVycl9DbGVhcigpOworICAgICAgICByZXR1cm4gUHlTdHJpbmdfRnJvbUZvcm1hdCgiPG1vZHVsZSAnJXMnIChidWlsdC1pbik+IiwgbmFtZSk7CisgICAgfQorICAgIHJldHVybiBQeVN0cmluZ19Gcm9tRm9ybWF0KCI8bW9kdWxlICclcycgZnJvbSAnJXMnPiIsIG5hbWUsIGZpbGVuYW1lKTsKK30KKworLyogV2Ugb25seSBuZWVkIGEgdHJhdmVyc2UgZnVuY3Rpb24sIG5vIGNsZWFyIGZ1bmN0aW9uOiBJZiB0aGUgbW9kdWxlCisgICBpcyBpbiBhIGN5Y2xlLCBtZF9kaWN0IHdpbGwgYmUgY2xlYXJlZCBhcyB3ZWxsLCB3aGljaCB3aWxsIGJyZWFrCisgICB0aGUgY3ljbGUuICovCitzdGF0aWMgaW50Cittb2R1bGVfdHJhdmVyc2UoUHlNb2R1bGVPYmplY3QgKm0sIHZpc2l0cHJvYyB2aXNpdCwgdm9pZCAqYXJnKQoreworICAgIFB5X1ZJU0lUKG0tPm1kX2RpY3QpOworICAgIHJldHVybiAwOworfQorCitQeURvY19TVFJWQVIobW9kdWxlX2RvYywKKyJtb2R1bGUobmFtZVssIGRvY10pXG5cCitcblwKK0NyZWF0ZSBhIG1vZHVsZSBvYmplY3QuXG5cCitUaGUgbmFtZSBtdXN0IGJlIGEgc3RyaW5nOyB0aGUgb3B0aW9uYWwgZG9jIGFyZ3VtZW50IGNhbiBoYXZlIGFueSB0eXBlLiIpOworCitQeVR5cGVPYmplY3QgUHlNb2R1bGVfVHlwZSA9IHsKKyAgICBQeVZhck9iamVjdF9IRUFEX0lOSVQoJlB5VHlwZV9UeXBlLCAwKQorICAgICJtb2R1bGUiLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfbmFtZSAqLworICAgIHNpemVvZihQeU1vZHVsZU9iamVjdCksICAgICAgICAgICAgICAgICAgICAgLyogdHBfc2l6ZSAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfaXRlbXNpemUgKi8KKyAgICAoZGVzdHJ1Y3Rvciltb2R1bGVfZGVhbGxvYywgICAgICAgICAgICAgICAgIC8qIHRwX2RlYWxsb2MgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3ByaW50ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9nZXRhdHRyICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9zZXRhdHRyICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9jb21wYXJlICovCisgICAgKHJlcHJmdW5jKW1vZHVsZV9yZXByLCAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9yZXByICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9hc19udW1iZXIgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2FzX3NlcXVlbmNlICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9hc19tYXBwaW5nICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9oYXNoICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9jYWxsICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9zdHIgKi8KKyAgICBQeU9iamVjdF9HZW5lcmljR2V0QXR0ciwgICAgICAgICAgICAgICAgICAgIC8qIHRwX2dldGF0dHJvICovCisgICAgUHlPYmplY3RfR2VuZXJpY1NldEF0dHIsICAgICAgICAgICAgICAgICAgICAvKiB0cF9zZXRhdHRybyAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfYXNfYnVmZmVyICovCisgICAgUHlfVFBGTEFHU19ERUZBVUxUIHwgUHlfVFBGTEFHU19IQVZFX0dDIHwKKyAgICAgICAgUHlfVFBGTEFHU19CQVNFVFlQRSwgICAgICAgICAgICAgICAgICAgIC8qIHRwX2ZsYWdzICovCisgICAgbW9kdWxlX2RvYywgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9kb2MgKi8KKyAgICAodHJhdmVyc2Vwcm9jKW1vZHVsZV90cmF2ZXJzZSwgICAgICAgICAgICAgIC8qIHRwX3RyYXZlcnNlICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9jbGVhciAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfcmljaGNvbXBhcmUgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3dlYWtsaXN0b2Zmc2V0ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9pdGVyICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9pdGVybmV4dCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfbWV0aG9kcyAqLworICAgIG1vZHVsZV9tZW1iZXJzLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfbWVtYmVycyAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZ2V0c2V0ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9iYXNlICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9kaWN0ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9kZXNjcl9nZXQgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2Rlc2NyX3NldCAqLworICAgIG9mZnNldG9mKFB5TW9kdWxlT2JqZWN0LCBtZF9kaWN0KSwgICAgICAgICAgLyogdHBfZGljdG9mZnNldCAqLworICAgIChpbml0cHJvYyltb2R1bGVfaW5pdCwgICAgICAgICAgICAgICAgICAgICAgLyogdHBfaW5pdCAqLworICAgIFB5VHlwZV9HZW5lcmljQWxsb2MsICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfYWxsb2MgKi8KKyAgICBQeVR5cGVfR2VuZXJpY05ldywgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX25ldyAqLworICAgIFB5T2JqZWN0X0dDX0RlbCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZnJlZSAqLworfTsKZGlmZiAtLWdpdCBhL1B5dGhvbi0yLjcuNS9PYmplY3RzL29iamVjdC5jIGIvUHl0aG9uLTIuNy41L09iamVjdHMvb2JqZWN0LmMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMTRmNGU5ZgotLS0gL2Rldi9udWxsCisrKyBiL1B5dGhvbi0yLjcuNS9PYmplY3RzL29iamVjdC5jCkBAIC0wLDAgKzEsMjUxMyBAQAorCisvKiBHZW5lcmljIG9iamVjdCBvcGVyYXRpb25zOyBhbmQgaW1wbGVtZW50YXRpb24gb2YgTm9uZSAoTm9PYmplY3QpICovCisKKyNpbmNsdWRlICJQeXRob24uaCIKKyNpbmNsdWRlICJmcmFtZW9iamVjdC5oIgorCisjaWZkZWYgX19jcGx1c3BsdXMKK2V4dGVybiAiQyIgeworI2VuZGlmCisKKyNpZmRlZiBQeV9SRUZfREVCVUcKK1B5X3NzaXplX3QgX1B5X1JlZlRvdGFsOworCitQeV9zc2l6ZV90CitfUHlfR2V0UmVmVG90YWwodm9pZCkKK3sKKyAgICBQeU9iamVjdCAqbzsKKyAgICBQeV9zc2l6ZV90IHRvdGFsID0gX1B5X1JlZlRvdGFsOworICAgIC8qIGlnbm9yZSB0aGUgcmVmZXJlbmNlcyB0byB0aGUgZHVtbXkgb2JqZWN0IG9mIHRoZSBkaWN0cyBhbmQgc2V0cworICAgICAgIGJlY2F1c2UgdGhleSBhcmUgbm90IHJlbGlhYmxlIGFuZCBub3QgdXNlZnVsIChub3cgdGhhdCB0aGUKKyAgICAgICBoYXNoIHRhYmxlIGNvZGUgaXMgd2VsbC10ZXN0ZWQpICovCisgICAgbyA9IF9QeURpY3RfRHVtbXkoKTsKKyAgICBpZiAobyAhPSBOVUxMKQorICAgICAgICB0b3RhbCAtPSBvLT5vYl9yZWZjbnQ7CisgICAgbyA9IF9QeVNldF9EdW1teSgpOworICAgIGlmIChvICE9IE5VTEwpCisgICAgICAgIHRvdGFsIC09IG8tPm9iX3JlZmNudDsKKyAgICByZXR1cm4gdG90YWw7Cit9CisjZW5kaWYgLyogUHlfUkVGX0RFQlVHICovCisKK2ludCBQeV9EaXZpc2lvbldhcm5pbmdGbGFnOworaW50IFB5X1B5M2tXYXJuaW5nRmxhZzsKKworLyogT2JqZWN0IGFsbG9jYXRpb24gcm91dGluZXMgdXNlZCBieSBORVdPQkogYW5kIE5FV1ZBUk9CSiBtYWNyb3MuCisgICBUaGVzZSBhcmUgdXNlZCBieSB0aGUgaW5kaXZpZHVhbCByb3V0aW5lcyBmb3Igb2JqZWN0IGNyZWF0aW9uLgorICAgRG8gbm90IGNhbGwgdGhlbSBvdGhlcndpc2UsIHRoZXkgZG8gbm90IGluaXRpYWxpemUgdGhlIG9iamVjdCEgKi8KKworI2lmZGVmIFB5X1RSQUNFX1JFRlMKKy8qIEhlYWQgb2YgY2lyY3VsYXIgZG91Ymx5LWxpbmtlZCBsaXN0IG9mIGFsbCBvYmplY3RzLiAgVGhlc2UgYXJlIGxpbmtlZAorICogdG9nZXRoZXIgdmlhIHRoZSBfb2JfcHJldiBhbmQgX29iX25leHQgbWVtYmVycyBvZiBhIFB5T2JqZWN0LCB3aGljaAorICogZXhpc3Qgb25seSBpbiBhIFB5X1RSQUNFX1JFRlMgYnVpbGQuCisgKi8KK3N0YXRpYyBQeU9iamVjdCByZWZjaGFpbiA9IHsmcmVmY2hhaW4sICZyZWZjaGFpbn07CisKKy8qIEluc2VydCBvcCBhdCB0aGUgZnJvbnQgb2YgdGhlIGxpc3Qgb2YgYWxsIG9iamVjdHMuICBJZiBmb3JjZSBpcyB0cnVlLAorICogb3AgaXMgYWRkZWQgZXZlbiBpZiBfb2JfcHJldiBhbmQgX29iX25leHQgYXJlIG5vbi1OVUxMIGFscmVhZHkuICBJZgorICogZm9yY2UgaXMgZmFsc2UgYW1kIF9vYl9wcmV2IG9yIF9vYl9uZXh0IGFyZSBub24tTlVMTCwgZG8gbm90aGluZy4KKyAqIGZvcmNlIHNob3VsZCBiZSB0cnVlIGlmIGFuZCBvbmx5IGlmIG9wIHBvaW50cyB0byBmcmVzaGx5IGFsbG9jYXRlZCwKKyAqIHVuaW5pdGlhbGl6ZWQgbWVtb3J5LCBvciB5b3UndmUgdW5saW5rZWQgb3AgZnJvbSB0aGUgbGlzdCBhbmQgYXJlCisgKiByZWxpbmtpbmcgaXQgaW50byB0aGUgZnJvbnQuCisgKiBOb3RlIHRoYXQgb2JqZWN0cyBhcmUgbm9ybWFsbHkgYWRkZWQgdG8gdGhlIGxpc3QgdmlhIF9QeV9OZXdSZWZlcmVuY2UsCisgKiB3aGljaCBpcyBjYWxsZWQgYnkgUHlPYmplY3RfSW5pdC4gIE5vdCBhbGwgb2JqZWN0cyBhcmUgaW5pdGlhbGl6ZWQgdGhhdAorICogd2F5LCB0aG91Z2g7IGV4Y2VwdGlvbnMgaW5jbHVkZSBzdGF0aWNhbGx5IGFsbG9jYXRlZCB0eXBlIG9iamVjdHMsIGFuZAorICogc3RhdGljYWxseSBhbGxvY2F0ZWQgc2luZ2xldG9ucyAobGlrZSBQeV9UcnVlIGFuZCBQeV9Ob25lKS4KKyAqLwordm9pZAorX1B5X0FkZFRvQWxsT2JqZWN0cyhQeU9iamVjdCAqb3AsIGludCBmb3JjZSkKK3sKKyNpZmRlZiAgUHlfREVCVUcKKyAgICBpZiAoIWZvcmNlKSB7CisgICAgICAgIC8qIElmIGl0J3MgaW5pdGlhbGl6ZWQgbWVtb3J5LCBvcCBtdXN0IGJlIGluIG9yIG91dCBvZgorICAgICAgICAgKiB0aGUgbGlzdCB1bmFtYmlndW91c2x5LgorICAgICAgICAgKi8KKyAgICAgICAgYXNzZXJ0KChvcC0+X29iX3ByZXYgPT0gTlVMTCkgPT0gKG9wLT5fb2JfbmV4dCA9PSBOVUxMKSk7CisgICAgfQorI2VuZGlmCisgICAgaWYgKGZvcmNlIHx8IG9wLT5fb2JfcHJldiA9PSBOVUxMKSB7CisgICAgICAgIG9wLT5fb2JfbmV4dCA9IHJlZmNoYWluLl9vYl9uZXh0OworICAgICAgICBvcC0+X29iX3ByZXYgPSAmcmVmY2hhaW47CisgICAgICAgIHJlZmNoYWluLl9vYl9uZXh0LT5fb2JfcHJldiA9IG9wOworICAgICAgICByZWZjaGFpbi5fb2JfbmV4dCA9IG9wOworICAgIH0KK30KKyNlbmRpZiAgLyogUHlfVFJBQ0VfUkVGUyAqLworCisjaWZkZWYgQ09VTlRfQUxMT0NTCitzdGF0aWMgUHlUeXBlT2JqZWN0ICp0eXBlX2xpc3Q7CisvKiBBbGwgdHlwZXMgYXJlIGFkZGVkIHRvIHR5cGVfbGlzdCwgYXQgbGVhc3Qgd2hlbgorICAgdGhleSBnZXQgb25lIG9iamVjdCBjcmVhdGVkLiBUaGF0IG1ha2VzIHRoZW0KKyAgIGltbW9ydGFsLCB3aGljaCB1bmZvcnR1bmF0ZWx5IGNvbnRyaWJ1dGVzIHRvCisgICBnYXJiYWdlIGl0c2VsZi4gSWYgdW5saXN0X3R5cGVzX3dpdGhvdXRfb2JqZWN0cworICAgaXMgc2V0LCB0aGV5IHdpbGwgYmUgcmVtb3ZlZCBmcm9tIHRoZSB0eXBlX2xpc3QKKyAgIG9uY2UgdGhlIGxhc3Qgb2JqZWN0IGlzIGRlYWxsb2NhdGVkLiAqLworc3RhdGljIGludCB1bmxpc3RfdHlwZXNfd2l0aG91dF9vYmplY3RzOworZXh0ZXJuIFB5X3NzaXplX3QgdHVwbGVfemVyb19hbGxvY3MsIGZhc3RfdHVwbGVfYWxsb2NzOworZXh0ZXJuIFB5X3NzaXplX3QgcXVpY2tfaW50X2FsbG9jcywgcXVpY2tfbmVnX2ludF9hbGxvY3M7CitleHRlcm4gUHlfc3NpemVfdCBudWxsX3N0cmluZ3MsIG9uZV9zdHJpbmdzOwordm9pZAorZHVtcF9jb3VudHMoRklMRSogZikKK3sKKyAgICBQeVR5cGVPYmplY3QgKnRwOworCisgICAgZm9yICh0cCA9IHR5cGVfbGlzdDsgdHA7IHRwID0gdHAtPnRwX25leHQpCisgICAgICAgIGZwcmludGYoZiwgIiVzIGFsbG9jJ2Q6ICUiIFBZX0ZPUk1BVF9TSVpFX1QgImQsICIKKyAgICAgICAgICAgICJmcmVlZDogJSIgUFlfRk9STUFUX1NJWkVfVCAiZCwgIgorICAgICAgICAgICAgIm1heCBpbiB1c2U6ICUiIFBZX0ZPUk1BVF9TSVpFX1QgImRcbiIsCisgICAgICAgICAgICB0cC0+dHBfbmFtZSwgdHAtPnRwX2FsbG9jcywgdHAtPnRwX2ZyZWVzLAorICAgICAgICAgICAgdHAtPnRwX21heGFsbG9jKTsKKyAgICBmcHJpbnRmKGYsICJmYXN0IHR1cGxlIGFsbG9jczogJSIgUFlfRk9STUFUX1NJWkVfVCAiZCwgIgorICAgICAgICAiZW1wdHk6ICUiIFBZX0ZPUk1BVF9TSVpFX1QgImRcbiIsCisgICAgICAgIGZhc3RfdHVwbGVfYWxsb2NzLCB0dXBsZV96ZXJvX2FsbG9jcyk7CisgICAgZnByaW50ZihmLCAiZmFzdCBpbnQgYWxsb2NzOiBwb3M6ICUiIFBZX0ZPUk1BVF9TSVpFX1QgImQsICIKKyAgICAgICAgIm5lZzogJSIgUFlfRk9STUFUX1NJWkVfVCAiZFxuIiwKKyAgICAgICAgcXVpY2tfaW50X2FsbG9jcywgcXVpY2tfbmVnX2ludF9hbGxvY3MpOworICAgIGZwcmludGYoZiwgIm51bGwgc3RyaW5nczogJSIgUFlfRk9STUFUX1NJWkVfVCAiZCwgIgorICAgICAgICAiMS1zdHJpbmdzOiAlIiBQWV9GT1JNQVRfU0laRV9UICJkXG4iLAorICAgICAgICBudWxsX3N0cmluZ3MsIG9uZV9zdHJpbmdzKTsKK30KKworUHlPYmplY3QgKgorZ2V0X2NvdW50cyh2b2lkKQoreworICAgIFB5VHlwZU9iamVjdCAqdHA7CisgICAgUHlPYmplY3QgKnJlc3VsdDsKKyAgICBQeU9iamVjdCAqdjsKKworICAgIHJlc3VsdCA9IFB5TGlzdF9OZXcoMCk7CisgICAgaWYgKHJlc3VsdCA9PSBOVUxMKQorICAgICAgICByZXR1cm4gTlVMTDsKKyAgICBmb3IgKHRwID0gdHlwZV9saXN0OyB0cDsgdHAgPSB0cC0+dHBfbmV4dCkgeworICAgICAgICB2ID0gUHlfQnVpbGRWYWx1ZSgiKHNubm4pIiwgdHAtPnRwX25hbWUsIHRwLT50cF9hbGxvY3MsCisgICAgICAgICAgICAgICAgICAgICAgICAgIHRwLT50cF9mcmVlcywgdHAtPnRwX21heGFsbG9jKTsKKyAgICAgICAgaWYgKHYgPT0gTlVMTCkgeworICAgICAgICAgICAgUHlfREVDUkVGKHJlc3VsdCk7CisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgfQorICAgICAgICBpZiAoUHlMaXN0X0FwcGVuZChyZXN1bHQsIHYpIDwgMCkgeworICAgICAgICAgICAgUHlfREVDUkVGKHYpOworICAgICAgICAgICAgUHlfREVDUkVGKHJlc3VsdCk7CisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgfQorICAgICAgICBQeV9ERUNSRUYodik7CisgICAgfQorICAgIHJldHVybiByZXN1bHQ7Cit9CisKK3ZvaWQKK2luY19jb3VudChQeVR5cGVPYmplY3QgKnRwKQoreworICAgIGlmICh0cC0+dHBfbmV4dCA9PSBOVUxMICYmIHRwLT50cF9wcmV2ID09IE5VTEwpIHsKKyAgICAgICAgLyogZmlyc3QgdGltZTsgaW5zZXJ0IGluIGxpbmtlZCBsaXN0ICovCisgICAgICAgIGlmICh0cC0+dHBfbmV4dCAhPSBOVUxMKSAvKiBzYW5pdHkgY2hlY2sgKi8KKyAgICAgICAgICAgIFB5X0ZhdGFsRXJyb3IoIlhYWCBpbmNfY291bnQgc2FuaXR5IGNoZWNrIik7CisgICAgICAgIGlmICh0eXBlX2xpc3QpCisgICAgICAgICAgICB0eXBlX2xpc3QtPnRwX3ByZXYgPSB0cDsKKyAgICAgICAgdHAtPnRwX25leHQgPSB0eXBlX2xpc3Q7CisgICAgICAgIC8qIE5vdGUgdGhhdCBhcyBvZiBQeXRob24gMi4yLCBoZWFwLWFsbG9jYXRlZCB0eXBlIG9iamVjdHMKKyAgICAgICAgICogY2FuIGdvIGF3YXksIGJ1dCB0aGlzIGNvZGUgcmVxdWlyZXMgdGhhdCB0aGV5IHN0YXkgYWxpdmUKKyAgICAgICAgICogdW50aWwgcHJvZ3JhbSBleGl0LiAgVGhhdCdzIHdoeSB3ZSdyZSBjYXJlZnVsIHdpdGgKKyAgICAgICAgICogcmVmY291bnRzIGhlcmUuICB0eXBlX2xpc3QgZ2V0cyBhIG5ldyByZWZlcmVuY2UgdG8gdHAsCisgICAgICAgICAqIHdoaWxlIG93bmVyc2hpcCBvZiB0aGUgcmVmZXJlbmNlIHR5cGVfbGlzdCB1c2VkIHRvIGhvbGQKKyAgICAgICAgICogKGlmIGFueSkgd2FzIHRyYW5zZmVycmVkIHRvIHRwLT50cF9uZXh0IGluIHRoZSBsaW5lIGFib3ZlLgorICAgICAgICAgKiB0cCBpcyB0aHVzIGVmZmVjdGl2ZWx5IGltbW9ydGFsIGFmdGVyIHRoaXMuCisgICAgICAgICAqLworICAgICAgICBQeV9JTkNSRUYodHApOworICAgICAgICB0eXBlX2xpc3QgPSB0cDsKKyNpZmRlZiBQeV9UUkFDRV9SRUZTCisgICAgICAgIC8qIEFsc28gaW5zZXJ0IGluIHRoZSBkb3VibHktbGlua2VkIGxpc3Qgb2YgYWxsIG9iamVjdHMsCisgICAgICAgICAqIGlmIG5vdCBhbHJlYWR5IHRoZXJlLgorICAgICAgICAgKi8KKyAgICAgICAgX1B5X0FkZFRvQWxsT2JqZWN0cygoUHlPYmplY3QgKil0cCwgMCk7CisjZW5kaWYKKyAgICB9CisgICAgdHAtPnRwX2FsbG9jcysrOworICAgIGlmICh0cC0+dHBfYWxsb2NzIC0gdHAtPnRwX2ZyZWVzID4gdHAtPnRwX21heGFsbG9jKQorICAgICAgICB0cC0+dHBfbWF4YWxsb2MgPSB0cC0+dHBfYWxsb2NzIC0gdHAtPnRwX2ZyZWVzOworfQorCit2b2lkIGRlY19jb3VudChQeVR5cGVPYmplY3QgKnRwKQoreworICAgIHRwLT50cF9mcmVlcysrOworICAgIGlmICh1bmxpc3RfdHlwZXNfd2l0aG91dF9vYmplY3RzICYmCisgICAgICAgIHRwLT50cF9hbGxvY3MgPT0gdHAtPnRwX2ZyZWVzKSB7CisgICAgICAgIC8qIHVubGluayB0aGUgdHlwZSBmcm9tIHR5cGVfbGlzdCAqLworICAgICAgICBpZiAodHAtPnRwX3ByZXYpCisgICAgICAgICAgICB0cC0+dHBfcHJldi0+dHBfbmV4dCA9IHRwLT50cF9uZXh0OworICAgICAgICBlbHNlCisgICAgICAgICAgICB0eXBlX2xpc3QgPSB0cC0+dHBfbmV4dDsKKyAgICAgICAgaWYgKHRwLT50cF9uZXh0KQorICAgICAgICAgICAgdHAtPnRwX25leHQtPnRwX3ByZXYgPSB0cC0+dHBfcHJldjsKKyAgICAgICAgdHAtPnRwX25leHQgPSB0cC0+dHBfcHJldiA9IE5VTEw7CisgICAgICAgIFB5X0RFQ1JFRih0cCk7CisgICAgfQorfQorCisjZW5kaWYKKworI2lmZGVmIFB5X1JFRl9ERUJVRworLyogTG9nIGEgZmF0YWwgZXJyb3I7IGRvZXNuJ3QgcmV0dXJuLiAqLwordm9pZAorX1B5X05lZ2F0aXZlUmVmY291bnQoY29uc3QgY2hhciAqZm5hbWUsIGludCBsaW5lbm8sIFB5T2JqZWN0ICpvcCkKK3sKKyAgICBjaGFyIGJ1ZlszMDBdOworCisgICAgUHlPU19zbnByaW50ZihidWYsIHNpemVvZihidWYpLAorICAgICAgICAgICAgICAgICAgIiVzOiVpIG9iamVjdCBhdCAlcCBoYXMgbmVnYXRpdmUgcmVmIGNvdW50ICIKKyAgICAgICAgICAgICAgICAgICIlIiBQWV9GT1JNQVRfU0laRV9UICJkIiwKKyAgICAgICAgICAgICAgICAgIGZuYW1lLCBsaW5lbm8sIG9wLCBvcC0+b2JfcmVmY250KTsKKyAgICBQeV9GYXRhbEVycm9yKGJ1Zik7Cit9CisKKyNlbmRpZiAvKiBQeV9SRUZfREVCVUcgKi8KKwordm9pZAorUHlfSW5jUmVmKFB5T2JqZWN0ICpvKQoreworICAgIFB5X1hJTkNSRUYobyk7Cit9CisKK3ZvaWQKK1B5X0RlY1JlZihQeU9iamVjdCAqbykKK3sKKyAgICBQeV9YREVDUkVGKG8pOworfQorCitQeU9iamVjdCAqCitQeU9iamVjdF9Jbml0KFB5T2JqZWN0ICpvcCwgUHlUeXBlT2JqZWN0ICp0cCkKK3sKKyAgICBpZiAob3AgPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIFB5RXJyX05vTWVtb3J5KCk7CisgICAgLyogQW55IGNoYW5nZXMgc2hvdWxkIGJlIHJlZmxlY3RlZCBpbiBQeU9iamVjdF9JTklUIChvYmppbXBsLmgpICovCisgICAgUHlfVFlQRShvcCkgPSB0cDsKKyAgICBfUHlfTmV3UmVmZXJlbmNlKG9wKTsKKyAgICByZXR1cm4gb3A7Cit9CisKK1B5VmFyT2JqZWN0ICoKK1B5T2JqZWN0X0luaXRWYXIoUHlWYXJPYmplY3QgKm9wLCBQeVR5cGVPYmplY3QgKnRwLCBQeV9zc2l6ZV90IHNpemUpCit7CisgICAgaWYgKG9wID09IE5VTEwpCisgICAgICAgIHJldHVybiAoUHlWYXJPYmplY3QgKikgUHlFcnJfTm9NZW1vcnkoKTsKKyAgICAvKiBBbnkgY2hhbmdlcyBzaG91bGQgYmUgcmVmbGVjdGVkIGluIFB5T2JqZWN0X0lOSVRfVkFSICovCisgICAgb3AtPm9iX3NpemUgPSBzaXplOworICAgIFB5X1RZUEUob3ApID0gdHA7CisgICAgX1B5X05ld1JlZmVyZW5jZSgoUHlPYmplY3QgKilvcCk7CisgICAgcmV0dXJuIG9wOworfQorCitQeU9iamVjdCAqCitfUHlPYmplY3RfTmV3KFB5VHlwZU9iamVjdCAqdHApCit7CisgICAgUHlPYmplY3QgKm9wOworICAgIG9wID0gKFB5T2JqZWN0ICopIFB5T2JqZWN0X01BTExPQyhfUHlPYmplY3RfU0laRSh0cCkpOworICAgIGlmIChvcCA9PSBOVUxMKQorICAgICAgICByZXR1cm4gUHlFcnJfTm9NZW1vcnkoKTsKKyAgICByZXR1cm4gUHlPYmplY3RfSU5JVChvcCwgdHApOworfQorCitQeVZhck9iamVjdCAqCitfUHlPYmplY3RfTmV3VmFyKFB5VHlwZU9iamVjdCAqdHAsIFB5X3NzaXplX3Qgbml0ZW1zKQoreworICAgIFB5VmFyT2JqZWN0ICpvcDsKKyAgICBjb25zdCBzaXplX3Qgc2l6ZSA9IF9QeU9iamVjdF9WQVJfU0laRSh0cCwgbml0ZW1zKTsKKyAgICBvcCA9IChQeVZhck9iamVjdCAqKSBQeU9iamVjdF9NQUxMT0Moc2l6ZSk7CisgICAgaWYgKG9wID09IE5VTEwpCisgICAgICAgIHJldHVybiAoUHlWYXJPYmplY3QgKilQeUVycl9Ob01lbW9yeSgpOworICAgIHJldHVybiBQeU9iamVjdF9JTklUX1ZBUihvcCwgdHAsIG5pdGVtcyk7Cit9CisKKy8qIGZvciBiaW5hcnkgY29tcGF0aWJpbGl0eSB3aXRoIDIuMiAqLworI3VuZGVmIF9QeU9iamVjdF9EZWwKK3ZvaWQKK19QeU9iamVjdF9EZWwoUHlPYmplY3QgKm9wKQoreworICAgIFB5T2JqZWN0X0ZSRUUob3ApOworfQorCisvKiBJbXBsZW1lbnRhdGlvbiBvZiBQeU9iamVjdF9QcmludCB3aXRoIHJlY3Vyc2lvbiBjaGVja2luZyAqLworc3RhdGljIGludAoraW50ZXJuYWxfcHJpbnQoUHlPYmplY3QgKm9wLCBGSUxFICpmcCwgaW50IGZsYWdzLCBpbnQgbmVzdGluZykKK3sKKyAgICBpbnQgcmV0ID0gMDsKKyAgICBpZiAobmVzdGluZyA+IDEwKSB7CisgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19SdW50aW1lRXJyb3IsICJwcmludCByZWN1cnNpb24iKTsKKyAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKyAgICBpZiAoUHlFcnJfQ2hlY2tTaWduYWxzKCkpCisgICAgICAgIHJldHVybiAtMTsKKyNpZmRlZiBVU0VfU1RBQ0tDSEVDSworICAgIGlmIChQeU9TX0NoZWNrU3RhY2soKSkgeworICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfTWVtb3J5RXJyb3IsICJzdGFjayBvdmVyZmxvdyIpOworICAgICAgICByZXR1cm4gLTE7CisgICAgfQorI2VuZGlmCisgICAgY2xlYXJlcnIoZnApOyAvKiBDbGVhciBhbnkgcHJldmlvdXMgZXJyb3IgY29uZGl0aW9uICovCisgICAgaWYgKG9wID09IE5VTEwpIHsKKyAgICAgICAgUHlfQkVHSU5fQUxMT1dfVEhSRUFEUworICAgICAgICBmcHJpbnRmKGZwLCAiPG5pbD4iKTsKKyAgICAgICAgUHlfRU5EX0FMTE9XX1RIUkVBRFMKKyAgICB9CisgICAgZWxzZSB7CisgICAgICAgIGlmIChvcC0+b2JfcmVmY250IDw9IDApCisgICAgICAgICAgICAvKiBYWFgodHdvdXRlcnMpIGNhc3QgcmVmY291bnQgdG8gbG9uZyB1bnRpbCAlemQgaXMKKyAgICAgICAgICAgICAgIHVuaXZlcnNhbGx5IGF2YWlsYWJsZSAqLworICAgICAgICAgICAgUHlfQkVHSU5fQUxMT1dfVEhSRUFEUworICAgICAgICAgICAgZnByaW50ZihmcCwgIjxyZWZjbnQgJWxkIGF0ICVwPiIsCisgICAgICAgICAgICAgICAgKGxvbmcpb3AtPm9iX3JlZmNudCwgb3ApOworICAgICAgICAgICAgUHlfRU5EX0FMTE9XX1RIUkVBRFMKKyAgICAgICAgZWxzZSBpZiAoUHlfVFlQRShvcCktPnRwX3ByaW50ID09IE5VTEwpIHsKKyAgICAgICAgICAgIFB5T2JqZWN0ICpzOworICAgICAgICAgICAgaWYgKGZsYWdzICYgUHlfUFJJTlRfUkFXKQorICAgICAgICAgICAgICAgIHMgPSBQeU9iamVjdF9TdHIob3ApOworICAgICAgICAgICAgZWxzZQorICAgICAgICAgICAgICAgIHMgPSBQeU9iamVjdF9SZXByKG9wKTsKKyAgICAgICAgICAgIGlmIChzID09IE5VTEwpCisgICAgICAgICAgICAgICAgcmV0ID0gLTE7CisgICAgICAgICAgICBlbHNlIHsKKyAgICAgICAgICAgICAgICByZXQgPSBpbnRlcm5hbF9wcmludChzLCBmcCwgUHlfUFJJTlRfUkFXLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5lc3RpbmcrMSk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBQeV9YREVDUkVGKHMpOworICAgICAgICB9CisgICAgICAgIGVsc2UKKyAgICAgICAgICAgIHJldCA9ICgqUHlfVFlQRShvcCktPnRwX3ByaW50KShvcCwgZnAsIGZsYWdzKTsKKyAgICB9CisgICAgaWYgKHJldCA9PSAwKSB7CisgICAgICAgIGlmIChmZXJyb3IoZnApKSB7CisgICAgICAgICAgICBQeUVycl9TZXRGcm9tRXJybm8oUHlFeGNfSU9FcnJvcik7CisgICAgICAgICAgICBjbGVhcmVycihmcCk7CisgICAgICAgICAgICByZXQgPSAtMTsKKyAgICAgICAgfQorICAgIH0KKyAgICByZXR1cm4gcmV0OworfQorCitpbnQKK1B5T2JqZWN0X1ByaW50KFB5T2JqZWN0ICpvcCwgRklMRSAqZnAsIGludCBmbGFncykKK3sKKyAgICByZXR1cm4gaW50ZXJuYWxfcHJpbnQob3AsIGZwLCBmbGFncywgMCk7Cit9CisKKworLyogRm9yIGRlYnVnZ2luZyBjb252ZW5pZW5jZS4gIFNlZSBNaXNjL2dkYmluaXQgZm9yIHNvbWUgdXNlZnVsIGdkYiBob29rcyAqLwordm9pZCBfUHlPYmplY3RfRHVtcChQeU9iamVjdCogb3ApCit7CisgICAgaWYgKG9wID09IE5VTEwpCisgICAgICAgIGZwcmludGYoc3RkZXJyLCAiTlVMTFxuIik7CisgICAgZWxzZSB7CisjaWZkZWYgV0lUSF9USFJFQUQKKyAgICAgICAgUHlHSUxTdGF0ZV9TVEFURSBnaWw7CisjZW5kaWYKKyAgICAgICAgZnByaW50ZihzdGRlcnIsICJvYmplY3QgIDogIik7CisjaWZkZWYgV0lUSF9USFJFQUQKKyAgICAgICAgZ2lsID0gUHlHSUxTdGF0ZV9FbnN1cmUoKTsKKyNlbmRpZgorICAgICAgICAodm9pZClQeU9iamVjdF9QcmludChvcCwgc3RkZXJyLCAwKTsKKyNpZmRlZiBXSVRIX1RIUkVBRAorICAgICAgICBQeUdJTFN0YXRlX1JlbGVhc2UoZ2lsKTsKKyNlbmRpZgorICAgICAgICAvKiBYWFgodHdvdXRlcnMpIGNhc3QgcmVmY291bnQgdG8gbG9uZyB1bnRpbCAlemQgaXMKKyAgICAgICAgICAgdW5pdmVyc2FsbHkgYXZhaWxhYmxlICovCisgICAgICAgIGZwcmludGYoc3RkZXJyLCAiXG4iCisgICAgICAgICAgICAidHlwZSAgICA6ICVzXG4iCisgICAgICAgICAgICAicmVmY291bnQ6ICVsZFxuIgorICAgICAgICAgICAgImFkZHJlc3MgOiAlcFxuIiwKKyAgICAgICAgICAgIFB5X1RZUEUob3ApPT1OVUxMID8gIk5VTEwiIDogUHlfVFlQRShvcCktPnRwX25hbWUsCisgICAgICAgICAgICAobG9uZylvcC0+b2JfcmVmY250LAorICAgICAgICAgICAgb3ApOworICAgIH0KK30KKworUHlPYmplY3QgKgorUHlPYmplY3RfUmVwcihQeU9iamVjdCAqdikKK3sKKyAgICBpZiAoUHlFcnJfQ2hlY2tTaWduYWxzKCkpCisgICAgICAgIHJldHVybiBOVUxMOworI2lmZGVmIFVTRV9TVEFDS0NIRUNLCisgICAgaWYgKFB5T1NfQ2hlY2tTdGFjaygpKSB7CisgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19NZW1vcnlFcnJvciwgInN0YWNrIG92ZXJmbG93Iik7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyNlbmRpZgorICAgIGlmICh2ID09IE5VTEwpCisgICAgICAgIHJldHVybiBQeVN0cmluZ19Gcm9tU3RyaW5nKCI8TlVMTD4iKTsKKyAgICBlbHNlIGlmIChQeV9UWVBFKHYpLT50cF9yZXByID09IE5VTEwpCisgICAgICAgIHJldHVybiBQeVN0cmluZ19Gcm9tRm9ybWF0KCI8JXMgb2JqZWN0IGF0ICVwPiIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFB5X1RZUEUodiktPnRwX25hbWUsIHYpOworICAgIGVsc2UgeworICAgICAgICBQeU9iamVjdCAqcmVzOworICAgICAgICByZXMgPSAoKlB5X1RZUEUodiktPnRwX3JlcHIpKHYpOworICAgICAgICBpZiAocmVzID09IE5VTEwpCisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyNpZmRlZiBQeV9VU0lOR19VTklDT0RFCisgICAgICAgIGlmIChQeVVuaWNvZGVfQ2hlY2socmVzKSkgeworICAgICAgICAgICAgUHlPYmplY3QqIHN0cjsKKyAgICAgICAgICAgIHN0ciA9IFB5VW5pY29kZV9Bc0VuY29kZWRTdHJpbmcocmVzLCBOVUxMLCBOVUxMKTsKKyAgICAgICAgICAgIFB5X0RFQ1JFRihyZXMpOworICAgICAgICAgICAgaWYgKHN0cikKKyAgICAgICAgICAgICAgICByZXMgPSBzdHI7CisgICAgICAgICAgICBlbHNlCisgICAgICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgICAgIH0KKyNlbmRpZgorICAgICAgICBpZiAoIVB5U3RyaW5nX0NoZWNrKHJlcykpIHsKKyAgICAgICAgICAgIFB5RXJyX0Zvcm1hdChQeUV4Y19UeXBlRXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgIl9fcmVwcl9fIHJldHVybmVkIG5vbi1zdHJpbmcgKHR5cGUgJS4yMDBzKSIsCisgICAgICAgICAgICAgICAgICAgICAgICAgUHlfVFlQRShyZXMpLT50cF9uYW1lKTsKKyAgICAgICAgICAgIFB5X0RFQ1JFRihyZXMpOworICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHJlczsKKyAgICB9Cit9CisKK1B5T2JqZWN0ICoKK19QeU9iamVjdF9TdHIoUHlPYmplY3QgKnYpCit7CisgICAgUHlPYmplY3QgKnJlczsKKyAgICBpbnQgdHlwZV9vazsKKyAgICBpZiAodiA9PSBOVUxMKQorICAgICAgICByZXR1cm4gUHlTdHJpbmdfRnJvbVN0cmluZygiPE5VTEw+Iik7CisgICAgaWYgKFB5U3RyaW5nX0NoZWNrRXhhY3QodikpIHsKKyAgICAgICAgUHlfSU5DUkVGKHYpOworICAgICAgICByZXR1cm4gdjsKKyAgICB9CisjaWZkZWYgUHlfVVNJTkdfVU5JQ09ERQorICAgIGlmIChQeVVuaWNvZGVfQ2hlY2tFeGFjdCh2KSkgeworICAgICAgICBQeV9JTkNSRUYodik7CisgICAgICAgIHJldHVybiB2OworICAgIH0KKyNlbmRpZgorICAgIGlmIChQeV9UWVBFKHYpLT50cF9zdHIgPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIFB5T2JqZWN0X1JlcHIodik7CisKKyAgICAvKiBJdCBpcyBwb3NzaWJsZSBmb3IgYSB0eXBlIHRvIGhhdmUgYSB0cF9zdHIgcmVwcmVzZW50YXRpb24gdGhhdCBsb29wcworICAgICAgIGluZmluaXRlbHkuICovCisgICAgaWYgKFB5X0VudGVyUmVjdXJzaXZlQ2FsbCgiIHdoaWxlIGdldHRpbmcgdGhlIHN0ciBvZiBhbiBvYmplY3QiKSkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgcmVzID0gKCpQeV9UWVBFKHYpLT50cF9zdHIpKHYpOworICAgIFB5X0xlYXZlUmVjdXJzaXZlQ2FsbCgpOworICAgIGlmIChyZXMgPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgdHlwZV9vayA9IFB5U3RyaW5nX0NoZWNrKHJlcyk7CisjaWZkZWYgUHlfVVNJTkdfVU5JQ09ERQorICAgIHR5cGVfb2sgPSB0eXBlX29rIHx8IFB5VW5pY29kZV9DaGVjayhyZXMpOworI2VuZGlmCisgICAgaWYgKCF0eXBlX29rKSB7CisgICAgICAgIFB5RXJyX0Zvcm1hdChQeUV4Y19UeXBlRXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAiX19zdHJfXyByZXR1cm5lZCBub24tc3RyaW5nICh0eXBlICUuMjAwcykiLAorICAgICAgICAgICAgICAgICAgICAgUHlfVFlQRShyZXMpLT50cF9uYW1lKTsKKyAgICAgICAgUHlfREVDUkVGKHJlcyk7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICByZXR1cm4gcmVzOworfQorCitQeU9iamVjdCAqCitQeU9iamVjdF9TdHIoUHlPYmplY3QgKnYpCit7CisgICAgUHlPYmplY3QgKnJlcyA9IF9QeU9iamVjdF9TdHIodik7CisgICAgaWYgKHJlcyA9PSBOVUxMKQorICAgICAgICByZXR1cm4gTlVMTDsKKyNpZmRlZiBQeV9VU0lOR19VTklDT0RFCisgICAgaWYgKFB5VW5pY29kZV9DaGVjayhyZXMpKSB7CisgICAgICAgIFB5T2JqZWN0KiBzdHI7CisgICAgICAgIHN0ciA9IFB5VW5pY29kZV9Bc0VuY29kZWRTdHJpbmcocmVzLCBOVUxMLCBOVUxMKTsKKyAgICAgICAgUHlfREVDUkVGKHJlcyk7CisgICAgICAgIGlmIChzdHIpCisgICAgICAgICAgICByZXMgPSBzdHI7CisgICAgICAgIGVsc2UKKyAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyNlbmRpZgorICAgIGFzc2VydChQeVN0cmluZ19DaGVjayhyZXMpKTsKKyAgICByZXR1cm4gcmVzOworfQorCisjaWZkZWYgUHlfVVNJTkdfVU5JQ09ERQorUHlPYmplY3QgKgorUHlPYmplY3RfVW5pY29kZShQeU9iamVjdCAqdikKK3sKKyAgICBQeU9iamVjdCAqcmVzOworICAgIFB5T2JqZWN0ICpmdW5jOworICAgIFB5T2JqZWN0ICpzdHI7CisgICAgaW50IHVuaWNvZGVfbWV0aG9kX2ZvdW5kID0gMDsKKyAgICBzdGF0aWMgUHlPYmplY3QgKnVuaWNvZGVzdHIgPSBOVUxMOworCisgICAgaWYgKHYgPT0gTlVMTCkgeworICAgICAgICByZXMgPSBQeVN0cmluZ19Gcm9tU3RyaW5nKCI8TlVMTD4iKTsKKyAgICAgICAgaWYgKHJlcyA9PSBOVUxMKQorICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgICAgIHN0ciA9IFB5VW5pY29kZV9Gcm9tRW5jb2RlZE9iamVjdChyZXMsIE5VTEwsICJzdHJpY3QiKTsKKyAgICAgICAgUHlfREVDUkVGKHJlcyk7CisgICAgICAgIHJldHVybiBzdHI7CisgICAgfSBlbHNlIGlmIChQeVVuaWNvZGVfQ2hlY2tFeGFjdCh2KSkgeworICAgICAgICBQeV9JTkNSRUYodik7CisgICAgICAgIHJldHVybiB2OworICAgIH0KKworICAgIGlmIChQeUluc3RhbmNlX0NoZWNrKHYpKSB7CisgICAgICAgIC8qIFdlJ3JlIGFuIGluc3RhbmNlIG9mIGEgY2xhc3NpYyBjbGFzcyAqLworICAgICAgICAvKiBUcnkgX191bmljb2RlX18gZnJvbSB0aGUgaW5zdGFuY2UgLS0gYWxhcyB3ZSBoYXZlIG5vIHR5cGUgKi8KKyAgICAgICAgaWYgKCF1bmljb2Rlc3RyKSB7CisgICAgICAgICAgICB1bmljb2Rlc3RyID0gUHlTdHJpbmdfSW50ZXJuRnJvbVN0cmluZygiX191bmljb2RlX18iKTsKKyAgICAgICAgICAgIGlmICghdW5pY29kZXN0cikKKyAgICAgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgfQorICAgICAgICBmdW5jID0gUHlPYmplY3RfR2V0QXR0cih2LCB1bmljb2Rlc3RyKTsKKyAgICAgICAgaWYgKGZ1bmMgIT0gTlVMTCkgeworICAgICAgICAgICAgdW5pY29kZV9tZXRob2RfZm91bmQgPSAxOworICAgICAgICAgICAgcmVzID0gUHlPYmplY3RfQ2FsbEZ1bmN0aW9uT2JqQXJncyhmdW5jLCBOVUxMKTsKKyAgICAgICAgICAgIFB5X0RFQ1JFRihmdW5jKTsKKyAgICAgICAgfQorICAgICAgICBlbHNlIHsKKyAgICAgICAgICAgIFB5RXJyX0NsZWFyKCk7CisgICAgICAgIH0KKyAgICB9CisgICAgZWxzZSB7CisgICAgICAgIC8qIE5vdCBhIGNsYXNzaWMgY2xhc3MgaW5zdGFuY2UsIHRyeSBfX3VuaWNvZGVfXy4gKi8KKyAgICAgICAgZnVuYyA9IF9QeU9iamVjdF9Mb29rdXBTcGVjaWFsKHYsICJfX3VuaWNvZGVfXyIsICZ1bmljb2Rlc3RyKTsKKyAgICAgICAgaWYgKGZ1bmMgIT0gTlVMTCkgeworICAgICAgICAgICAgdW5pY29kZV9tZXRob2RfZm91bmQgPSAxOworICAgICAgICAgICAgcmVzID0gUHlPYmplY3RfQ2FsbEZ1bmN0aW9uT2JqQXJncyhmdW5jLCBOVUxMKTsKKyAgICAgICAgICAgIFB5X0RFQ1JFRihmdW5jKTsKKyAgICAgICAgfQorICAgICAgICBlbHNlIGlmIChQeUVycl9PY2N1cnJlZCgpKQorICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorCisgICAgLyogRGlkbid0IGZpbmQgX191bmljb2RlX18gKi8KKyAgICBpZiAoIXVuaWNvZGVfbWV0aG9kX2ZvdW5kKSB7CisgICAgICAgIGlmIChQeVVuaWNvZGVfQ2hlY2sodikpIHsKKyAgICAgICAgICAgIC8qIEZvciBhIFVuaWNvZGUgc3VidHlwZSB0aGF0J3MgZGlkbid0IG92ZXJ3cml0ZSBfX3VuaWNvZGVfXywKKyAgICAgICAgICAgICAgIHJldHVybiBhIHRydWUgVW5pY29kZSBvYmplY3Qgd2l0aCB0aGUgc2FtZSBkYXRhLiAqLworICAgICAgICAgICAgcmV0dXJuIFB5VW5pY29kZV9Gcm9tVW5pY29kZShQeVVuaWNvZGVfQVNfVU5JQ09ERSh2KSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHlVbmljb2RlX0dFVF9TSVpFKHYpKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoUHlTdHJpbmdfQ2hlY2tFeGFjdCh2KSkgeworICAgICAgICAgICAgUHlfSU5DUkVGKHYpOworICAgICAgICAgICAgcmVzID0gdjsKKyAgICAgICAgfQorICAgICAgICBlbHNlIHsKKyAgICAgICAgICAgIGlmIChQeV9UWVBFKHYpLT50cF9zdHIgIT0gTlVMTCkKKyAgICAgICAgICAgICAgICByZXMgPSAoKlB5X1RZUEUodiktPnRwX3N0cikodik7CisgICAgICAgICAgICBlbHNlCisgICAgICAgICAgICAgICAgcmVzID0gUHlPYmplY3RfUmVwcih2KTsKKyAgICAgICAgfQorICAgIH0KKworICAgIGlmIChyZXMgPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgaWYgKCFQeVVuaWNvZGVfQ2hlY2socmVzKSkgeworICAgICAgICBzdHIgPSBQeVVuaWNvZGVfRnJvbUVuY29kZWRPYmplY3QocmVzLCBOVUxMLCAic3RyaWN0Iik7CisgICAgICAgIFB5X0RFQ1JFRihyZXMpOworICAgICAgICByZXMgPSBzdHI7CisgICAgfQorICAgIHJldHVybiByZXM7Cit9CisjZW5kaWYKKworCisvKiBIZWxwZXIgdG8gd2FybiBhYm91dCBkZXByZWNhdGVkIHRwX2NvbXBhcmUgcmV0dXJuIHZhbHVlcy4gIFJldHVybjoKKyAgIC0yIGZvciBhbiBleGNlcHRpb247CisgICAtMSBpZiB2IDwgIHc7CisgICAgMCBpZiB2ID09IHc7CisgICAgMSBpZiB2ICA+IHcuCisgICAoVGhpcyBmdW5jdGlvbiBjYW5ub3QgcmV0dXJuIDIuKQorKi8KK3N0YXRpYyBpbnQKK2FkanVzdF90cF9jb21wYXJlKGludCBjKQoreworICAgIGlmIChQeUVycl9PY2N1cnJlZCgpKSB7CisgICAgICAgIGlmIChjICE9IC0xICYmIGMgIT0gLTIpIHsKKyAgICAgICAgICAgIFB5T2JqZWN0ICp0LCAqdiwgKnRiOworICAgICAgICAgICAgUHlFcnJfRmV0Y2goJnQsICZ2LCAmdGIpOworICAgICAgICAgICAgaWYgKFB5RXJyX1dhcm4oUHlFeGNfUnVudGltZVdhcm5pbmcsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAidHBfY29tcGFyZSBkaWRuJ3QgcmV0dXJuIC0xIG9yIC0yICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICJmb3IgZXhjZXB0aW9uIikgPCAwKSB7CisgICAgICAgICAgICAgICAgUHlfWERFQ1JFRih0KTsKKyAgICAgICAgICAgICAgICBQeV9YREVDUkVGKHYpOworICAgICAgICAgICAgICAgIFB5X1hERUNSRUYodGIpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgZWxzZQorICAgICAgICAgICAgICAgIFB5RXJyX1Jlc3RvcmUodCwgdiwgdGIpOworICAgICAgICB9CisgICAgICAgIHJldHVybiAtMjsKKyAgICB9CisgICAgZWxzZSBpZiAoYyA8IC0xIHx8IGMgPiAxKSB7CisgICAgICAgIGlmIChQeUVycl9XYXJuKFB5RXhjX1J1bnRpbWVXYXJuaW5nLAorICAgICAgICAgICAgICAgICAgICAgICAidHBfY29tcGFyZSBkaWRuJ3QgcmV0dXJuIC0xLCAwIG9yIDEiKSA8IDApCisgICAgICAgICAgICByZXR1cm4gLTI7CisgICAgICAgIGVsc2UKKyAgICAgICAgICAgIHJldHVybiBjIDwgLTEgPyAtMSA6IDE7CisgICAgfQorICAgIGVsc2UgeworICAgICAgICBhc3NlcnQoYyA+PSAtMSAmJiBjIDw9IDEpOworICAgICAgICByZXR1cm4gYzsKKyAgICB9Cit9CisKKworLyogTWFjcm8gdG8gZ2V0IHRoZSB0cF9yaWNoY29tcGFyZSBmaWVsZCBvZiBhIHR5cGUgaWYgZGVmaW5lZCAqLworI2RlZmluZSBSSUNIQ09NUEFSRSh0KSAoUHlUeXBlX0hhc0ZlYXR1cmUoKHQpLCBQeV9UUEZMQUdTX0hBVkVfUklDSENPTVBBUkUpIFwKKyAgICAgICAgICAgICA/ICh0KS0+dHBfcmljaGNvbXBhcmUgOiBOVUxMKQorCisvKiBNYXAgcmljaCBjb21wYXJpc29uIG9wZXJhdG9ycyB0byB0aGVpciBzd2FwcGVkIHZlcnNpb24sIGUuZy4gTFQgLS0+IEdUICovCitpbnQgX1B5X1N3YXBwZWRPcFtdID0ge1B5X0dULCBQeV9HRSwgUHlfRVEsIFB5X05FLCBQeV9MVCwgUHlfTEV9OworCisvKiBUcnkgYSBnZW51aW5lIHJpY2ggY29tcGFyaXNvbiwgcmV0dXJuaW5nIGFuIG9iamVjdC4gIFJldHVybjoKKyAgIE5VTEwgZm9yIGV4Y2VwdGlvbjsKKyAgIE5vdEltcGxlbWVudGVkIGlmIHRoaXMgcGFydGljdWxhciByaWNoIGNvbXBhcmlzb24gaXMgbm90IGltcGxlbWVudGVkIG9yCisgICAgIHVuZGVmaW5lZDsKKyAgIHNvbWUgb2JqZWN0IG5vdCBlcXVhbCB0byBOb3RJbXBsZW1lbnRlZCBpZiBpdCBpcyBpbXBsZW1lbnRlZAorICAgICAodGhpcyBsYXR0ZXIgb2JqZWN0IG1heSBub3QgYmUgYSBCb29sZWFuKS4KKyovCitzdGF0aWMgUHlPYmplY3QgKgordHJ5X3JpY2hfY29tcGFyZShQeU9iamVjdCAqdiwgUHlPYmplY3QgKncsIGludCBvcCkKK3sKKyAgICByaWNoY21wZnVuYyBmOworICAgIFB5T2JqZWN0ICpyZXM7CisKKyAgICBpZiAodi0+b2JfdHlwZSAhPSB3LT5vYl90eXBlICYmCisgICAgICAgIFB5VHlwZV9Jc1N1YnR5cGUody0+b2JfdHlwZSwgdi0+b2JfdHlwZSkgJiYKKyAgICAgICAgKGYgPSBSSUNIQ09NUEFSRSh3LT5vYl90eXBlKSkgIT0gTlVMTCkgeworICAgICAgICByZXMgPSAoKmYpKHcsIHYsIF9QeV9Td2FwcGVkT3Bbb3BdKTsKKyAgICAgICAgaWYgKHJlcyAhPSBQeV9Ob3RJbXBsZW1lbnRlZCkKKyAgICAgICAgICAgIHJldHVybiByZXM7CisgICAgICAgIFB5X0RFQ1JFRihyZXMpOworICAgIH0KKyAgICBpZiAoKGYgPSBSSUNIQ09NUEFSRSh2LT5vYl90eXBlKSkgIT0gTlVMTCkgeworICAgICAgICByZXMgPSAoKmYpKHYsIHcsIG9wKTsKKyAgICAgICAgaWYgKHJlcyAhPSBQeV9Ob3RJbXBsZW1lbnRlZCkKKyAgICAgICAgICAgIHJldHVybiByZXM7CisgICAgICAgIFB5X0RFQ1JFRihyZXMpOworICAgIH0KKyAgICBpZiAoKGYgPSBSSUNIQ09NUEFSRSh3LT5vYl90eXBlKSkgIT0gTlVMTCkgeworICAgICAgICByZXR1cm4gKCpmKSh3LCB2LCBfUHlfU3dhcHBlZE9wW29wXSk7CisgICAgfQorICAgIHJlcyA9IFB5X05vdEltcGxlbWVudGVkOworICAgIFB5X0lOQ1JFRihyZXMpOworICAgIHJldHVybiByZXM7Cit9CisKKy8qIFRyeSBhIGdlbnVpbmUgcmljaCBjb21wYXJpc29uLCByZXR1cm5pbmcgYW4gaW50LiAgUmV0dXJuOgorICAgLTEgZm9yIGV4Y2VwdGlvbiAoaW5jbHVkaW5nIHRoZSBjYXNlIHdoZXJlIHRyeV9yaWNoX2NvbXBhcmUoKSByZXR1cm5zIGFuCisgICAgICBvYmplY3QgdGhhdCdzIG5vdCBhIEJvb2xlYW4pOworICAgIDAgaWYgdGhlIG91dGNvbWUgaXMgZmFsc2U7CisgICAgMSBpZiB0aGUgb3V0Y29tZSBpcyB0cnVlOworICAgIDIgaWYgdGhpcyBwYXJ0aWN1bGFyIHJpY2ggY29tcGFyaXNvbiBpcyBub3QgaW1wbGVtZW50ZWQgb3IgdW5kZWZpbmVkLgorKi8KK3N0YXRpYyBpbnQKK3RyeV9yaWNoX2NvbXBhcmVfYm9vbChQeU9iamVjdCAqdiwgUHlPYmplY3QgKncsIGludCBvcCkKK3sKKyAgICBQeU9iamVjdCAqcmVzOworICAgIGludCBvazsKKworICAgIGlmIChSSUNIQ09NUEFSRSh2LT5vYl90eXBlKSA9PSBOVUxMICYmIFJJQ0hDT01QQVJFKHctPm9iX3R5cGUpID09IE5VTEwpCisgICAgICAgIHJldHVybiAyOyAvKiBTaG9ydGN1dCwgYXZvaWQgSU5DUkVGK0RFQ1JFRiAqLworICAgIHJlcyA9IHRyeV9yaWNoX2NvbXBhcmUodiwgdywgb3ApOworICAgIGlmIChyZXMgPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIC0xOworICAgIGlmIChyZXMgPT0gUHlfTm90SW1wbGVtZW50ZWQpIHsKKyAgICAgICAgUHlfREVDUkVGKHJlcyk7CisgICAgICAgIHJldHVybiAyOworICAgIH0KKyAgICBvayA9IFB5T2JqZWN0X0lzVHJ1ZShyZXMpOworICAgIFB5X0RFQ1JFRihyZXMpOworICAgIHJldHVybiBvazsKK30KKworLyogVHJ5IHJpY2ggY29tcGFyaXNvbnMgdG8gZGV0ZXJtaW5lIGEgMy13YXkgY29tcGFyaXNvbi4gIFJldHVybjoKKyAgIC0yIGZvciBhbiBleGNlcHRpb247CisgICAtMSBpZiB2ICA8IHc7CisgICAgMCBpZiB2ID09IHc7CisgICAgMSBpZiB2ICA+IHc7CisgICAgMiBpZiB0aGlzIHBhcnRpY3VsYXIgcmljaCBjb21wYXJpc29uIGlzIG5vdCBpbXBsZW1lbnRlZCBvciB1bmRlZmluZWQuCisqLworc3RhdGljIGludAordHJ5X3JpY2hfdG9fM3dheV9jb21wYXJlKFB5T2JqZWN0ICp2LCBQeU9iamVjdCAqdykKK3sKKyAgICBzdGF0aWMgc3RydWN0IHsgaW50IG9wOyBpbnQgb3V0Y29tZTsgfSB0cmllc1szXSA9IHsKKyAgICAgICAgLyogVHJ5IHRoaXMgb3BlcmF0b3IsIGFuZCBpZiBpdCBpcyB0cnVlLCB1c2UgdGhpcyBvdXRjb21lOiAqLworICAgICAgICB7UHlfRVEsIDB9LAorICAgICAgICB7UHlfTFQsIC0xfSwKKyAgICAgICAge1B5X0dULCAxfSwKKyAgICB9OworICAgIGludCBpOworCisgICAgaWYgKFJJQ0hDT01QQVJFKHYtPm9iX3R5cGUpID09IE5VTEwgJiYgUklDSENPTVBBUkUody0+b2JfdHlwZSkgPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIDI7IC8qIFNob3J0Y3V0ICovCisKKyAgICBmb3IgKGkgPSAwOyBpIDwgMzsgaSsrKSB7CisgICAgICAgIHN3aXRjaCAodHJ5X3JpY2hfY29tcGFyZV9ib29sKHYsIHcsIHRyaWVzW2ldLm9wKSkgeworICAgICAgICBjYXNlIC0xOgorICAgICAgICAgICAgcmV0dXJuIC0yOworICAgICAgICBjYXNlIDE6CisgICAgICAgICAgICByZXR1cm4gdHJpZXNbaV0ub3V0Y29tZTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHJldHVybiAyOworfQorCisvKiBUcnkgYSAzLXdheSBjb21wYXJpc29uLCByZXR1cm5pbmcgYW4gaW50LiAgUmV0dXJuOgorICAgLTIgZm9yIGFuIGV4Y2VwdGlvbjsKKyAgIC0xIGlmIHYgPCAgdzsKKyAgICAwIGlmIHYgPT0gdzsKKyAgICAxIGlmIHYgID4gdzsKKyAgICAyIGlmIHRoaXMgcGFydGljdWxhciAzLXdheSBjb21wYXJpc29uIGlzIG5vdCBpbXBsZW1lbnRlZCBvciB1bmRlZmluZWQuCisqLworc3RhdGljIGludAordHJ5XzN3YXlfY29tcGFyZShQeU9iamVjdCAqdiwgUHlPYmplY3QgKncpCit7CisgICAgaW50IGM7CisgICAgY21wZnVuYyBmOworCisgICAgLyogQ29tcGFyaXNvbnMgaW52b2x2aW5nIGluc3RhbmNlcyBhcmUgZ2l2ZW4gdG8gaW5zdGFuY2VfY29tcGFyZSwKKyAgICAgICB3aGljaCBoYXMgdGhlIHNhbWUgcmV0dXJuIGNvbnZlbnRpb25zIGFzIHRoaXMgZnVuY3Rpb24uICovCisKKyAgICBmID0gdi0+b2JfdHlwZS0+dHBfY29tcGFyZTsKKyAgICBpZiAoUHlJbnN0YW5jZV9DaGVjayh2KSkKKyAgICAgICAgcmV0dXJuICgqZikodiwgdyk7CisgICAgaWYgKFB5SW5zdGFuY2VfQ2hlY2sodykpCisgICAgICAgIHJldHVybiAoKnctPm9iX3R5cGUtPnRwX2NvbXBhcmUpKHYsIHcpOworCisgICAgLyogSWYgYm90aCBoYXZlIHRoZSBzYW1lIChub24tTlVMTCkgdHBfY29tcGFyZSwgdXNlIGl0LiAqLworICAgIGlmIChmICE9IE5VTEwgJiYgZiA9PSB3LT5vYl90eXBlLT50cF9jb21wYXJlKSB7CisgICAgICAgIGMgPSAoKmYpKHYsIHcpOworICAgICAgICByZXR1cm4gYWRqdXN0X3RwX2NvbXBhcmUoYyk7CisgICAgfQorCisgICAgLyogSWYgZWl0aGVyIHRwX2NvbXBhcmUgaXMgX1B5T2JqZWN0X1Nsb3RDb21wYXJlLCB0aGF0J3Mgc2FmZS4gKi8KKyAgICBpZiAoZiA9PSBfUHlPYmplY3RfU2xvdENvbXBhcmUgfHwKKyAgICAgICAgdy0+b2JfdHlwZS0+dHBfY29tcGFyZSA9PSBfUHlPYmplY3RfU2xvdENvbXBhcmUpCisgICAgICAgIHJldHVybiBfUHlPYmplY3RfU2xvdENvbXBhcmUodiwgdyk7CisKKyAgICAvKiBJZiB3ZSdyZSBoZXJlLCB2IGFuZCB3LAorICAgICAgICBhKSBhcmUgbm90IGluc3RhbmNlczsKKyAgICAgICAgYikgaGF2ZSBkaWZmZXJlbnQgdHlwZXMgb3IgYSB0eXBlIHdpdGhvdXQgdHBfY29tcGFyZTsgYW5kCisgICAgICAgIGMpIGRvbid0IGhhdmUgYSB1c2VyLWRlZmluZWQgdHBfY29tcGFyZS4KKyAgICAgICB0cF9jb21wYXJlIGltcGxlbWVudGF0aW9ucyBpbiBDIGFzc3VtZSB0aGF0IGJvdGggYXJndW1lbnRzCisgICAgICAgaGF2ZSB0aGVpciB0eXBlLCBzbyB3ZSBnaXZlIHVwIGlmIHRoZSBjb2VyY2lvbiBmYWlscyBvciBpZgorICAgICAgIGl0IHlpZWxkcyB0eXBlcyB3aGljaCBhcmUgc3RpbGwgaW5jb21wYXRpYmxlICh3aGljaCBjYW4KKyAgICAgICBoYXBwZW4gd2l0aCBhIHVzZXItZGVmaW5lZCBuYl9jb2VyY2UpLgorICAgICovCisgICAgYyA9IFB5TnVtYmVyX0NvZXJjZUV4KCZ2LCAmdyk7CisgICAgaWYgKGMgPCAwKQorICAgICAgICByZXR1cm4gLTI7CisgICAgaWYgKGMgPiAwKQorICAgICAgICByZXR1cm4gMjsKKyAgICBmID0gdi0+b2JfdHlwZS0+dHBfY29tcGFyZTsKKyAgICBpZiAoZiAhPSBOVUxMICYmIGYgPT0gdy0+b2JfdHlwZS0+dHBfY29tcGFyZSkgeworICAgICAgICBjID0gKCpmKSh2LCB3KTsKKyAgICAgICAgUHlfREVDUkVGKHYpOworICAgICAgICBQeV9ERUNSRUYodyk7CisgICAgICAgIHJldHVybiBhZGp1c3RfdHBfY29tcGFyZShjKTsKKyAgICB9CisKKyAgICAvKiBObyBjb21wYXJpc29uIGRlZmluZWQgKi8KKyAgICBQeV9ERUNSRUYodik7CisgICAgUHlfREVDUkVGKHcpOworICAgIHJldHVybiAyOworfQorCisvKiBGaW5hbCBmYWxsYmFjayAzLXdheSBjb21wYXJpc29uLCByZXR1cm5pbmcgYW4gaW50LiAgUmV0dXJuOgorICAgLTIgaWYgYW4gZXJyb3Igb2NjdXJyZWQ7CisgICAtMSBpZiB2IDwgIHc7CisgICAgMCBpZiB2ID09IHc7CisgICAgMSBpZiB2ID4gIHcuCisqLworc3RhdGljIGludAorZGVmYXVsdF8zd2F5X2NvbXBhcmUoUHlPYmplY3QgKnYsIFB5T2JqZWN0ICp3KQoreworICAgIGludCBjOworICAgIGNvbnN0IGNoYXIgKnZuYW1lLCAqd25hbWU7CisKKyAgICBpZiAodi0+b2JfdHlwZSA9PSB3LT5vYl90eXBlKSB7CisgICAgICAgIC8qIFdoZW4gY29tcGFyaW5nIHRoZXNlIHBvaW50ZXJzLCB0aGV5IG11c3QgYmUgY2FzdCB0bworICAgICAgICAgKiBpbnRlZ2VyIHR5cGVzIChpLmUuIFB5X3VpbnRwdHJfdCwgb3VyIHNwZWxsaW5nIG9mIEM5WCdzCisgICAgICAgICAqIHVpbnRwdHJfdCkuICBBTlNJIHNwZWNpZmllcyB0aGF0IHBvaW50ZXIgY29tcGFyZXMgb3RoZXIKKyAgICAgICAgICogdGhhbiA9PSBhbmQgIT0gdG8gbm9uLXJlbGF0ZWQgc3RydWN0dXJlcyBhcmUgdW5kZWZpbmVkLgorICAgICAgICAgKi8KKyAgICAgICAgUHlfdWludHB0cl90IHZ2ID0gKFB5X3VpbnRwdHJfdCl2OworICAgICAgICBQeV91aW50cHRyX3Qgd3cgPSAoUHlfdWludHB0cl90KXc7CisgICAgICAgIHJldHVybiAodnYgPCB3dykgPyAtMSA6ICh2diA+IHd3KSA/IDEgOiAwOworICAgIH0KKworICAgIC8qIE5vbmUgaXMgc21hbGxlciB0aGFuIGFueXRoaW5nICovCisgICAgaWYgKHYgPT0gUHlfTm9uZSkKKyAgICAgICAgcmV0dXJuIC0xOworICAgIGlmICh3ID09IFB5X05vbmUpCisgICAgICAgIHJldHVybiAxOworCisgICAgLyogZGlmZmVyZW50IHR5cGU6IGNvbXBhcmUgdHlwZSBuYW1lczsgbnVtYmVycyBhcmUgc21hbGxlciAqLworICAgIGlmIChQeU51bWJlcl9DaGVjayh2KSkKKyAgICAgICAgdm5hbWUgPSAiIjsKKyAgICBlbHNlCisgICAgICAgIHZuYW1lID0gdi0+b2JfdHlwZS0+dHBfbmFtZTsKKyAgICBpZiAoUHlOdW1iZXJfQ2hlY2sodykpCisgICAgICAgIHduYW1lID0gIiI7CisgICAgZWxzZQorICAgICAgICB3bmFtZSA9IHctPm9iX3R5cGUtPnRwX25hbWU7CisgICAgYyA9IHN0cmNtcCh2bmFtZSwgd25hbWUpOworICAgIGlmIChjIDwgMCkKKyAgICAgICAgcmV0dXJuIC0xOworICAgIGlmIChjID4gMCkKKyAgICAgICAgcmV0dXJuIDE7CisgICAgLyogU2FtZSB0eXBlIG5hbWUsIG9yIChtb3JlIGxpa2VseSkgaW5jb21wYXJhYmxlIG51bWVyaWMgdHlwZXMgKi8KKyAgICByZXR1cm4gKChQeV91aW50cHRyX3QpKHYtPm9iX3R5cGUpIDwgKAorICAgICAgICBQeV91aW50cHRyX3QpKHctPm9iX3R5cGUpKSA/IC0xIDogMTsKK30KKworLyogRG8gYSAzLXdheSBjb21wYXJpc29uLCBieSBob29rIG9yIGJ5IGNyb29rLiAgUmV0dXJuOgorICAgLTIgZm9yIGFuIGV4Y2VwdGlvbiAoYnV0IHNlZSBiZWxvdyk7CisgICAtMSBpZiB2IDwgIHc7CisgICAgMCBpZiB2ID09IHc7CisgICAgMSBpZiB2ID4gIHc7CisgICBCVVQ6IGlmIHRoZSBvYmplY3QgaW1wbGVtZW50cyBhIHRwX2NvbXBhcmUgZnVuY3Rpb24sIGl0IHJldHVybnMKKyAgIHdoYXRldmVyIHRoaXMgZnVuY3Rpb24gcmV0dXJucyAod2hldGhlciB3aXRoIGFuIGV4Y2VwdGlvbiBvciBub3QpLgorKi8KK3N0YXRpYyBpbnQKK2RvX2NtcChQeU9iamVjdCAqdiwgUHlPYmplY3QgKncpCit7CisgICAgaW50IGM7CisgICAgY21wZnVuYyBmOworCisgICAgaWYgKHYtPm9iX3R5cGUgPT0gdy0+b2JfdHlwZQorICAgICAgICAmJiAoZiA9IHYtPm9iX3R5cGUtPnRwX2NvbXBhcmUpICE9IE5VTEwpIHsKKyAgICAgICAgYyA9ICgqZikodiwgdyk7CisgICAgICAgIGlmIChQeUluc3RhbmNlX0NoZWNrKHYpKSB7CisgICAgICAgICAgICAvKiBJbnN0YW5jZSB0cF9jb21wYXJlIGhhcyBhIGRpZmZlcmVudCBzaWduYXR1cmUuCisgICAgICAgICAgICAgICBCdXQgaWYgaXQgcmV0dXJucyB1bmRlZmluZWQgd2UgZmFsbCB0aHJvdWdoLiAqLworICAgICAgICAgICAgaWYgKGMgIT0gMikKKyAgICAgICAgICAgICAgICByZXR1cm4gYzsKKyAgICAgICAgICAgIC8qIEVsc2UgZmFsbCB0aHJvdWdoIHRvIHRyeV9yaWNoX3RvXzN3YXlfY29tcGFyZSgpICovCisgICAgICAgIH0KKyAgICAgICAgZWxzZQorICAgICAgICAgICAgcmV0dXJuIGFkanVzdF90cF9jb21wYXJlKGMpOworICAgIH0KKyAgICAvKiBXZSBvbmx5IGdldCBoZXJlIGlmIG9uZSBvZiB0aGUgZm9sbG93aW5nIGlzIHRydWU6CisgICAgICAgYSkgdiBhbmQgdyBoYXZlIGRpZmZlcmVudCB0eXBlcworICAgICAgIGIpIHYgYW5kIHcgaGF2ZSB0aGUgc2FtZSB0eXBlLCB3aGljaCBkb2Vzbid0IGhhdmUgdHBfY29tcGFyZQorICAgICAgIGMpIHYgYW5kIHcgYXJlIGluc3RhbmNlcywgYW5kIGVpdGhlciBfX2NtcF9fIGlzIG5vdCBkZWZpbmVkIG9yCisgICAgICAgICAgX19jbXBfXyByZXR1cm5zIE5vdEltcGxlbWVudGVkCisgICAgKi8KKyAgICBjID0gdHJ5X3JpY2hfdG9fM3dheV9jb21wYXJlKHYsIHcpOworICAgIGlmIChjIDwgMikKKyAgICAgICAgcmV0dXJuIGM7CisgICAgYyA9IHRyeV8zd2F5X2NvbXBhcmUodiwgdyk7CisgICAgaWYgKGMgPCAyKQorICAgICAgICByZXR1cm4gYzsKKyAgICByZXR1cm4gZGVmYXVsdF8zd2F5X2NvbXBhcmUodiwgdyk7Cit9CisKKy8qIENvbXBhcmUgdiB0byB3LiAgUmV0dXJuCisgICAtMSBpZiB2IDwgIHcgb3IgZXhjZXB0aW9uIChQeUVycl9PY2N1cnJlZCgpIHRydWUgaW4gbGF0dGVyIGNhc2UpLgorICAgIDAgaWYgdiA9PSB3LgorICAgIDEgaWYgdiA+IHcuCisgICBYWFggVGhlIGRvY3MgKEMgQVBJIG1hbnVhbCkgc2F5IHRoZSByZXR1cm4gdmFsdWUgaXMgdW5kZWZpbmVkIGluIGNhc2UKKyAgIFhYWCBvZiBlcnJvci4KKyovCitpbnQKK1B5T2JqZWN0X0NvbXBhcmUoUHlPYmplY3QgKnYsIFB5T2JqZWN0ICp3KQoreworICAgIGludCByZXN1bHQ7CisKKyAgICBpZiAodiA9PSBOVUxMIHx8IHcgPT0gTlVMTCkgeworICAgICAgICBQeUVycl9CYWRJbnRlcm5hbENhbGwoKTsKKyAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKyAgICBpZiAodiA9PSB3KQorICAgICAgICByZXR1cm4gMDsKKyAgICBpZiAoUHlfRW50ZXJSZWN1cnNpdmVDYWxsKCIgaW4gY21wIikpCisgICAgICAgIHJldHVybiAtMTsKKyAgICByZXN1bHQgPSBkb19jbXAodiwgdyk7CisgICAgUHlfTGVhdmVSZWN1cnNpdmVDYWxsKCk7CisgICAgcmV0dXJuIHJlc3VsdCA8IDAgPyAtMSA6IHJlc3VsdDsKK30KKworLyogUmV0dXJuIChuZXcgcmVmZXJlbmNlIHRvKSBQeV9UcnVlIG9yIFB5X0ZhbHNlLiAqLworc3RhdGljIFB5T2JqZWN0ICoKK2NvbnZlcnRfM3dheV90b19vYmplY3QoaW50IG9wLCBpbnQgYykKK3sKKyAgICBQeU9iamVjdCAqcmVzdWx0OworICAgIHN3aXRjaCAob3ApIHsKKyAgICBjYXNlIFB5X0xUOiBjID0gYyA8ICAwOyBicmVhazsKKyAgICBjYXNlIFB5X0xFOiBjID0gYyA8PSAwOyBicmVhazsKKyAgICBjYXNlIFB5X0VROiBjID0gYyA9PSAwOyBicmVhazsKKyAgICBjYXNlIFB5X05FOiBjID0gYyAhPSAwOyBicmVhazsKKyAgICBjYXNlIFB5X0dUOiBjID0gYyA+ICAwOyBicmVhazsKKyAgICBjYXNlIFB5X0dFOiBjID0gYyA+PSAwOyBicmVhazsKKyAgICB9CisgICAgcmVzdWx0ID0gYyA/IFB5X1RydWUgOiBQeV9GYWxzZTsKKyAgICBQeV9JTkNSRUYocmVzdWx0KTsKKyAgICByZXR1cm4gcmVzdWx0OworfQorCisvKiBXZSB3YW50IGEgcmljaCBjb21wYXJpc29uIGJ1dCBkb24ndCBoYXZlIG9uZS4gIFRyeSBhIDMtd2F5IGNtcCBpbnN0ZWFkLgorICAgUmV0dXJuCisgICBOVUxMICAgICAgaWYgZXJyb3IKKyAgIFB5X1RydWUgICBpZiB2IG9wIHcKKyAgIFB5X0ZhbHNlICBpZiBub3QgKHYgb3AgdykKKyovCitzdGF0aWMgUHlPYmplY3QgKgordHJ5XzN3YXlfdG9fcmljaF9jb21wYXJlKFB5T2JqZWN0ICp2LCBQeU9iamVjdCAqdywgaW50IG9wKQoreworICAgIGludCBjOworCisgICAgYyA9IHRyeV8zd2F5X2NvbXBhcmUodiwgdyk7CisgICAgaWYgKGMgPj0gMikgeworCisgICAgICAgIC8qIFB5M0sgd2FybmluZyBpZiB0eXBlcyBhcmUgbm90IGVxdWFsIGFuZCBjb21wYXJpc29uIGlzbid0ID09IG9yICE9ICAqLworICAgICAgICBpZiAoUHlfUHkza1dhcm5pbmdGbGFnICYmCisgICAgICAgICAgICB2LT5vYl90eXBlICE9IHctPm9iX3R5cGUgJiYgb3AgIT0gUHlfRVEgJiYgb3AgIT0gUHlfTkUgJiYKKyAgICAgICAgICAgIFB5RXJyX1dhcm5FeChQeUV4Y19EZXByZWNhdGlvbldhcm5pbmcsCisgICAgICAgICAgICAgICAgICAgICAgICJjb21wYXJpbmcgdW5lcXVhbCB0eXBlcyBub3Qgc3VwcG9ydGVkICIKKyAgICAgICAgICAgICAgICAgICAgICAgImluIDMueCIsIDEpIDwgMCkgeworICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgICAgIH0KKworICAgICAgICBjID0gZGVmYXVsdF8zd2F5X2NvbXBhcmUodiwgdyk7CisgICAgfQorICAgIGlmIChjIDw9IC0yKQorICAgICAgICByZXR1cm4gTlVMTDsKKyAgICByZXR1cm4gY29udmVydF8zd2F5X3RvX29iamVjdChvcCwgYyk7Cit9CisKKy8qIERvIHJpY2ggY29tcGFyaXNvbiBvbiB2IGFuZCB3LiAgUmV0dXJuCisgICBOVUxMICAgICAgaWYgZXJyb3IKKyAgIEVsc2UgYSBuZXcgcmVmZXJlbmNlIHRvIGFuIG9iamVjdCBvdGhlciB0aGFuIFB5X05vdEltcGxlbWVudGVkLCB1c3VhbGx5KD8pOgorICAgUHlfVHJ1ZSAgIGlmIHYgb3AgdworICAgUHlfRmFsc2UgIGlmIG5vdCAodiBvcCB3KQorKi8KK3N0YXRpYyBQeU9iamVjdCAqCitkb19yaWNoY21wKFB5T2JqZWN0ICp2LCBQeU9iamVjdCAqdywgaW50IG9wKQoreworICAgIFB5T2JqZWN0ICpyZXM7CisKKyAgICByZXMgPSB0cnlfcmljaF9jb21wYXJlKHYsIHcsIG9wKTsKKyAgICBpZiAocmVzICE9IFB5X05vdEltcGxlbWVudGVkKQorICAgICAgICByZXR1cm4gcmVzOworICAgIFB5X0RFQ1JFRihyZXMpOworCisgICAgcmV0dXJuIHRyeV8zd2F5X3RvX3JpY2hfY29tcGFyZSh2LCB3LCBvcCk7Cit9CisKKy8qIFJldHVybjoKKyAgIE5VTEwgZm9yIGV4Y2VwdGlvbjsKKyAgIHNvbWUgb2JqZWN0IG5vdCBlcXVhbCB0byBOb3RJbXBsZW1lbnRlZCBpZiBpdCBpcyBpbXBsZW1lbnRlZAorICAgICAodGhpcyBsYXR0ZXIgb2JqZWN0IG1heSBub3QgYmUgYSBCb29sZWFuKS4KKyovCitQeU9iamVjdCAqCitQeU9iamVjdF9SaWNoQ29tcGFyZShQeU9iamVjdCAqdiwgUHlPYmplY3QgKncsIGludCBvcCkKK3sKKyAgICBQeU9iamVjdCAqcmVzOworCisgICAgYXNzZXJ0KFB5X0xUIDw9IG9wICYmIG9wIDw9IFB5X0dFKTsKKyAgICBpZiAoUHlfRW50ZXJSZWN1cnNpdmVDYWxsKCIgaW4gY21wIikpCisgICAgICAgIHJldHVybiBOVUxMOworCisgICAgLyogSWYgdGhlIHR5cGVzIGFyZSBlcXVhbCwgYW5kIG5vdCBvbGQtc3R5bGUgaW5zdGFuY2VzLCB0cnkgdG8KKyAgICAgICBnZXQgb3V0IGNoZWFwIChkb24ndCBib3RoZXIgd2l0aCBjb2VyY2lvbnMgZXRjLikuICovCisgICAgaWYgKHYtPm9iX3R5cGUgPT0gdy0+b2JfdHlwZSAmJiAhUHlJbnN0YW5jZV9DaGVjayh2KSkgeworICAgICAgICBjbXBmdW5jIGZjbXA7CisgICAgICAgIHJpY2hjbXBmdW5jIGZyaWNoID0gUklDSENPTVBBUkUodi0+b2JfdHlwZSk7CisgICAgICAgIC8qIElmIHRoZSB0eXBlIGhhcyByaWNoY21wLCB0cnkgaXQgZmlyc3QuICB0cnlfcmljaF9jb21wYXJlCisgICAgICAgICAgIHRyaWVzIGl0IHR3by1zaWRlZCwgd2hpY2ggaXMgbm90IG5lZWRlZCBzaW5jZSB3ZSd2ZSBhCisgICAgICAgICAgIHNpbmdsZSB0eXBlIG9ubHkuICovCisgICAgICAgIGlmIChmcmljaCAhPSBOVUxMKSB7CisgICAgICAgICAgICByZXMgPSAoKmZyaWNoKSh2LCB3LCBvcCk7CisgICAgICAgICAgICBpZiAocmVzICE9IFB5X05vdEltcGxlbWVudGVkKQorICAgICAgICAgICAgICAgIGdvdG8gRG9uZTsKKyAgICAgICAgICAgIFB5X0RFQ1JFRihyZXMpOworICAgICAgICB9CisgICAgICAgIC8qIE5vIHJpY2hjbXAsIG9yIHRoaXMgcGFydGljdWxhciByaWNobXAgbm90IGltcGxlbWVudGVkLgorICAgICAgICAgICBUcnkgMy13YXkgY21wLiAqLworICAgICAgICBmY21wID0gdi0+b2JfdHlwZS0+dHBfY29tcGFyZTsKKyAgICAgICAgaWYgKGZjbXAgIT0gTlVMTCkgeworICAgICAgICAgICAgaW50IGMgPSAoKmZjbXApKHYsIHcpOworICAgICAgICAgICAgYyA9IGFkanVzdF90cF9jb21wYXJlKGMpOworICAgICAgICAgICAgaWYgKGMgPT0gLTIpIHsKKyAgICAgICAgICAgICAgICByZXMgPSBOVUxMOworICAgICAgICAgICAgICAgIGdvdG8gRG9uZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJlcyA9IGNvbnZlcnRfM3dheV90b19vYmplY3Qob3AsIGMpOworICAgICAgICAgICAgZ290byBEb25lOworICAgICAgICB9CisgICAgfQorCisgICAgLyogRmFzdCBwYXRoIG5vdCB0YWtlbiwgb3IgY291bGRuJ3QgZGVsaXZlciBhIHVzZWZ1bCByZXN1bHQuICovCisgICAgcmVzID0gZG9fcmljaGNtcCh2LCB3LCBvcCk7CitEb25lOgorICAgIFB5X0xlYXZlUmVjdXJzaXZlQ2FsbCgpOworICAgIHJldHVybiByZXM7Cit9CisKKy8qIFJldHVybiAtMSBpZiBlcnJvcjsgMSBpZiB2IG9wIHc7IDAgaWYgbm90ICh2IG9wIHcpLiAqLworaW50CitQeU9iamVjdF9SaWNoQ29tcGFyZUJvb2woUHlPYmplY3QgKnYsIFB5T2JqZWN0ICp3LCBpbnQgb3ApCit7CisgICAgUHlPYmplY3QgKnJlczsKKyAgICBpbnQgb2s7CisKKyAgICAvKiBRdWljayByZXN1bHQgd2hlbiBvYmplY3RzIGFyZSB0aGUgc2FtZS4KKyAgICAgICBHdWFyYW50ZWVzIHRoYXQgaWRlbnRpdHkgaW1wbGllcyBlcXVhbGl0eS4gKi8KKyAgICBpZiAodiA9PSB3KSB7CisgICAgICAgIGlmIChvcCA9PSBQeV9FUSkKKyAgICAgICAgICAgIHJldHVybiAxOworICAgICAgICBlbHNlIGlmIChvcCA9PSBQeV9ORSkKKyAgICAgICAgICAgIHJldHVybiAwOworICAgIH0KKworICAgIHJlcyA9IFB5T2JqZWN0X1JpY2hDb21wYXJlKHYsIHcsIG9wKTsKKyAgICBpZiAocmVzID09IE5VTEwpCisgICAgICAgIHJldHVybiAtMTsKKyAgICBpZiAoUHlCb29sX0NoZWNrKHJlcykpCisgICAgICAgIG9rID0gKHJlcyA9PSBQeV9UcnVlKTsKKyAgICBlbHNlCisgICAgICAgIG9rID0gUHlPYmplY3RfSXNUcnVlKHJlcyk7CisgICAgUHlfREVDUkVGKHJlcyk7CisgICAgcmV0dXJuIG9rOworfQorCisvKiBTZXQgb2YgaGFzaCB1dGlsaXR5IGZ1bmN0aW9ucyB0byBoZWxwIG1haW50YWluaW5nIHRoZSBpbnZhcmlhbnQgdGhhdAorICAgIGlmIGE9PWIgdGhlbiBoYXNoKGEpPT1oYXNoKGIpCisKKyAgIEFsbCB0aGUgdXRpbGl0eSBmdW5jdGlvbnMgKF9QeV9IYXNoKigpKSByZXR1cm4gIi0xIiB0byBzaWduaWZ5IGFuIGVycm9yLgorKi8KKworbG9uZworX1B5X0hhc2hEb3VibGUoZG91YmxlIHYpCit7CisgICAgZG91YmxlIGludHBhcnQsIGZyYWN0cGFydDsKKyAgICBpbnQgZXhwbzsKKyAgICBsb25nIGhpcGFydDsKKyAgICBsb25nIHg7ICAgICAgICAgICAgIC8qIHRoZSBmaW5hbCBoYXNoIHZhbHVlICovCisgICAgLyogVGhpcyBpcyBkZXNpZ25lZCBzbyB0aGF0IFB5dGhvbiBudW1iZXJzIG9mIGRpZmZlcmVudCB0eXBlcworICAgICAqIHRoYXQgY29tcGFyZSBlcXVhbCBoYXNoIHRvIHRoZSBzYW1lIHZhbHVlOyBvdGhlcndpc2UgY29tcGFyaXNvbnMKKyAgICAgKiBvZiBtYXBwaW5nIGtleXMgd2lsbCB0dXJuIG91dCB3ZWlyZC4KKyAgICAgKi8KKworICAgIGlmICghUHlfSVNfRklOSVRFKHYpKSB7CisgICAgICAgIGlmIChQeV9JU19JTkZJTklUWSh2KSkKKyAgICAgICAgICAgIHJldHVybiB2IDwgMCA/IC0yNzE4MjggOiAzMTQxNTk7CisgICAgICAgIGVsc2UKKyAgICAgICAgICAgIHJldHVybiAwOworICAgIH0KKyAgICBmcmFjdHBhcnQgPSBtb2RmKHYsICZpbnRwYXJ0KTsKKyAgICBpZiAoZnJhY3RwYXJ0ID09IDAuMCkgeworICAgICAgICAvKiBUaGlzIG11c3QgcmV0dXJuIHRoZSBzYW1lIGhhc2ggYXMgYW4gZXF1YWwgaW50IG9yIGxvbmcuICovCisgICAgICAgIGlmIChpbnRwYXJ0ID4gTE9OR19NQVgvMiB8fCAtaW50cGFydCA+IExPTkdfTUFYLzIpIHsKKyAgICAgICAgICAgIC8qIENvbnZlcnQgdG8gbG9uZyBhbmQgdXNlIGl0cyBoYXNoLiAqLworICAgICAgICAgICAgUHlPYmplY3QgKnBsb25nOyAgICAgICAgICAgICAgICAgICAgLyogY29udmVydGVkIHRvIFB5dGhvbiBsb25nICovCisgICAgICAgICAgICBwbG9uZyA9IFB5TG9uZ19Gcm9tRG91YmxlKHYpOworICAgICAgICAgICAgaWYgKHBsb25nID09IE5VTEwpCisgICAgICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICAgICAgeCA9IFB5T2JqZWN0X0hhc2gocGxvbmcpOworICAgICAgICAgICAgUHlfREVDUkVGKHBsb25nKTsKKyAgICAgICAgICAgIHJldHVybiB4OworICAgICAgICB9CisgICAgICAgIC8qIEZpdHMgaW4gYSBDIGxvbmcgPT0gYSBQeXRob24gaW50LCBzbyBpcyBpdHMgb3duIGhhc2guICovCisgICAgICAgIHggPSAobG9uZylpbnRwYXJ0OworICAgICAgICBpZiAoeCA9PSAtMSkKKyAgICAgICAgICAgIHggPSAtMjsKKyAgICAgICAgcmV0dXJuIHg7CisgICAgfQorICAgIC8qIFRoZSBmcmFjdGlvbmFsIHBhcnQgaXMgbm9uLXplcm8sIHNvIHdlIGRvbid0IGhhdmUgdG8gd29ycnkgYWJvdXQKKyAgICAgKiBtYWtpbmcgdGhpcyBtYXRjaCB0aGUgaGFzaCBvZiBzb21lIG90aGVyIHR5cGUuCisgICAgICogVXNlIGZyZXhwIHRvIGdldCBhdCB0aGUgYml0cyBpbiB0aGUgZG91YmxlLgorICAgICAqIFNpbmNlIHRoZSBWQVggRCBkb3VibGUgZm9ybWF0IGhhcyA1NiBtYW50aXNzYSBiaXRzLCB3aGljaCBpcyB0aGUKKyAgICAgKiBtb3N0IG9mIGFueSBkb3VibGUgZm9ybWF0IGluIHVzZSwgZWFjaCBvZiB0aGVzZSBwYXJ0cyBtYXkgaGF2ZSBhcworICAgICAqIG1hbnkgYXMgKGJ1dCBubyBtb3JlIHRoYW4pIDU2IHNpZ25pZmljYW50IGJpdHMuCisgICAgICogU28sIGFzc3VtaW5nIHNpemVvZihsb25nKSA+PSA0LCBlYWNoIHBhcnQgY2FuIGJlIGJyb2tlbiBpbnRvIHR3bworICAgICAqIGxvbmdzOyBmcmV4cCBhbmQgbXVsdGlwbGljYXRpb24gYXJlIHVzZWQgdG8gZG8gdGhhdC4KKyAgICAgKiBBbHNvLCBzaW5jZSB0aGUgQ3JheSBkb3VibGUgZm9ybWF0IGhhcyAxNSBleHBvbmVudCBiaXRzLCB3aGljaCBpcworICAgICAqIHRoZSBtb3N0IG9mIGFueSBkb3VibGUgZm9ybWF0IGluIHVzZSwgc2hpZnRpbmcgdGhlIGV4cG9uZW50IGZpZWxkCisgICAgICogbGVmdCBieSAxNSB3b24ndCBvdmVyZmxvdyBhIGxvbmcgKGFnYWluIGFzc3VtaW5nIHNpemVvZihsb25nKSA+PSA0KS4KKyAgICAgKi8KKyAgICB2ID0gZnJleHAodiwgJmV4cG8pOworICAgIHYgKj0gMjE0NzQ4MzY0OC4wOyAgICAgICAgICAvKiAyKiozMSAqLworICAgIGhpcGFydCA9IChsb25nKXY7ICAgICAgICAgICAvKiB0YWtlIHRoZSB0b3AgMzIgYml0cyAqLworICAgIHYgPSAodiAtIChkb3VibGUpaGlwYXJ0KSAqIDIxNDc0ODM2NDguMDsgLyogZ2V0IHRoZSBuZXh0IDMyIGJpdHMgKi8KKyAgICB4ID0gaGlwYXJ0ICsgKGxvbmcpdiArIChleHBvIDw8IDE1KTsKKyAgICBpZiAoeCA9PSAtMSkKKyAgICAgICAgeCA9IC0yOworICAgIHJldHVybiB4OworfQorCitsb25nCitfUHlfSGFzaFBvaW50ZXIodm9pZCAqcCkKK3sKKyAgICBsb25nIHg7CisgICAgc2l6ZV90IHkgPSAoc2l6ZV90KXA7CisgICAgLyogYm90dG9tIDMgb3IgNCBiaXRzIGFyZSBsaWtlbHkgdG8gYmUgMDsgcm90YXRlIHkgYnkgNCB0byBhdm9pZAorICAgICAgIGV4Y2Vzc2l2ZSBoYXNoIGNvbGxpc2lvbnMgZm9yIGRpY3RzIGFuZCBzZXRzICovCisgICAgeSA9ICh5ID4+IDQpIHwgKHkgPDwgKDggKiBTSVpFT0ZfVk9JRF9QIC0gNCkpOworICAgIHggPSAobG9uZyl5OworICAgIGlmICh4ID09IC0xKQorICAgICAgICB4ID0gLTI7CisgICAgcmV0dXJuIHg7Cit9CisKK2xvbmcKK1B5T2JqZWN0X0hhc2hOb3RJbXBsZW1lbnRlZChQeU9iamVjdCAqc2VsZikKK3sKKyAgICBQeUVycl9Gb3JtYXQoUHlFeGNfVHlwZUVycm9yLCAidW5oYXNoYWJsZSB0eXBlOiAnJS4yMDBzJyIsCisgICAgICAgICAgICAgICAgIHNlbGYtPm9iX3R5cGUtPnRwX25hbWUpOworICAgIHJldHVybiAtMTsKK30KKworX1B5X0hhc2hTZWNyZXRfdCBfUHlfSGFzaFNlY3JldDsKKworbG9uZworUHlPYmplY3RfSGFzaChQeU9iamVjdCAqdikKK3sKKyAgICBQeVR5cGVPYmplY3QgKnRwID0gdi0+b2JfdHlwZTsKKyAgICBpZiAodHAtPnRwX2hhc2ggIT0gTlVMTCkKKyAgICAgICAgcmV0dXJuICgqdHAtPnRwX2hhc2gpKHYpOworICAgIC8qIFRvIGtlZXAgdG8gdGhlIGdlbmVyYWwgcHJhY3RpY2UgdGhhdCBpbmhlcml0aW5nCisgICAgICogc29sZWx5IGZyb20gb2JqZWN0IGluIEMgY29kZSBzaG91bGQgd29yayB3aXRob3V0CisgICAgICogYW4gZXhwbGljaXQgY2FsbCB0byBQeVR5cGVfUmVhZHksIHdlIGltcGxpY2l0bHkgY2FsbAorICAgICAqIFB5VHlwZV9SZWFkeSBoZXJlIGFuZCB0aGVuIGNoZWNrIHRoZSB0cF9oYXNoIHNsb3QgYWdhaW4KKyAgICAgKi8KKyAgICBpZiAodHAtPnRwX2RpY3QgPT0gTlVMTCkgeworICAgICAgICBpZiAoUHlUeXBlX1JlYWR5KHRwKSA8IDApCisgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgIGlmICh0cC0+dHBfaGFzaCAhPSBOVUxMKQorICAgICAgICAgICAgcmV0dXJuICgqdHAtPnRwX2hhc2gpKHYpOworICAgIH0KKyAgICBpZiAodHAtPnRwX2NvbXBhcmUgPT0gTlVMTCAmJiBSSUNIQ09NUEFSRSh0cCkgPT0gTlVMTCkgeworICAgICAgICByZXR1cm4gX1B5X0hhc2hQb2ludGVyKHYpOyAvKiBVc2UgYWRkcmVzcyBhcyBoYXNoIHZhbHVlICovCisgICAgfQorICAgIC8qIElmIHRoZXJlJ3MgYSBjbXAgYnV0IG5vIGhhc2ggZGVmaW5lZCwgdGhlIG9iamVjdCBjYW4ndCBiZSBoYXNoZWQgKi8KKyAgICByZXR1cm4gUHlPYmplY3RfSGFzaE5vdEltcGxlbWVudGVkKHYpOworfQorCitQeU9iamVjdCAqCitQeU9iamVjdF9HZXRBdHRyU3RyaW5nKFB5T2JqZWN0ICp2LCBjb25zdCBjaGFyICpuYW1lKQoreworICAgIFB5T2JqZWN0ICp3LCAqcmVzOworCisgICAgaWYgKFB5X1RZUEUodiktPnRwX2dldGF0dHIgIT0gTlVMTCkKKyAgICAgICAgcmV0dXJuICgqUHlfVFlQRSh2KS0+dHBfZ2V0YXR0cikodiwgKGNoYXIqKW5hbWUpOworICAgIHcgPSBQeVN0cmluZ19JbnRlcm5Gcm9tU3RyaW5nKG5hbWUpOworICAgIGlmICh3ID09IE5VTEwpCisgICAgICAgIHJldHVybiBOVUxMOworICAgIHJlcyA9IFB5T2JqZWN0X0dldEF0dHIodiwgdyk7CisgICAgUHlfWERFQ1JFRih3KTsKKyAgICByZXR1cm4gcmVzOworfQorCitpbnQKK1B5T2JqZWN0X0hhc0F0dHJTdHJpbmcoUHlPYmplY3QgKnYsIGNvbnN0IGNoYXIgKm5hbWUpCit7CisgICAgUHlPYmplY3QgKnJlcyA9IFB5T2JqZWN0X0dldEF0dHJTdHJpbmcodiwgbmFtZSk7CisgICAgaWYgKHJlcyAhPSBOVUxMKSB7CisgICAgICAgIFB5X0RFQ1JFRihyZXMpOworICAgICAgICByZXR1cm4gMTsKKyAgICB9CisgICAgUHlFcnJfQ2xlYXIoKTsKKyAgICByZXR1cm4gMDsKK30KKworaW50CitQeU9iamVjdF9TZXRBdHRyU3RyaW5nKFB5T2JqZWN0ICp2LCBjb25zdCBjaGFyICpuYW1lLCBQeU9iamVjdCAqdykKK3sKKyAgICBQeU9iamVjdCAqczsKKyAgICBpbnQgcmVzOworCisgICAgaWYgKFB5X1RZUEUodiktPnRwX3NldGF0dHIgIT0gTlVMTCkKKyAgICAgICAgcmV0dXJuICgqUHlfVFlQRSh2KS0+dHBfc2V0YXR0cikodiwgKGNoYXIqKW5hbWUsIHcpOworICAgIHMgPSBQeVN0cmluZ19JbnRlcm5Gcm9tU3RyaW5nKG5hbWUpOworICAgIGlmIChzID09IE5VTEwpCisgICAgICAgIHJldHVybiAtMTsKKyAgICByZXMgPSBQeU9iamVjdF9TZXRBdHRyKHYsIHMsIHcpOworICAgIFB5X1hERUNSRUYocyk7CisgICAgcmV0dXJuIHJlczsKK30KKworUHlPYmplY3QgKgorUHlPYmplY3RfR2V0QXR0cihQeU9iamVjdCAqdiwgUHlPYmplY3QgKm5hbWUpCit7CisgICAgUHlUeXBlT2JqZWN0ICp0cCA9IFB5X1RZUEUodik7CisKKyAgICBpZiAoIVB5U3RyaW5nX0NoZWNrKG5hbWUpKSB7CisjaWZkZWYgUHlfVVNJTkdfVU5JQ09ERQorICAgICAgICAvKiBUaGUgVW5pY29kZSB0byBzdHJpbmcgY29udmVyc2lvbiBpcyBkb25lIGhlcmUgYmVjYXVzZSB0aGUKKyAgICAgICAgICAgZXhpc3RpbmcgdHBfZ2V0YXR0cm8gc2xvdHMgZXhwZWN0IGEgc3RyaW5nIG9iamVjdCBhcyBuYW1lCisgICAgICAgICAgIGFuZCB3ZSB3b3VsZG4ndCB3YW50IHRvIGJyZWFrIHRob3NlLiAqLworICAgICAgICBpZiAoUHlVbmljb2RlX0NoZWNrKG5hbWUpKSB7CisgICAgICAgICAgICBuYW1lID0gX1B5VW5pY29kZV9Bc0RlZmF1bHRFbmNvZGVkU3RyaW5nKG5hbWUsIE5VTEwpOworICAgICAgICAgICAgaWYgKG5hbWUgPT0gTlVMTCkKKyAgICAgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgfQorICAgICAgICBlbHNlCisjZW5kaWYKKyAgICAgICAgeworICAgICAgICAgICAgUHlFcnJfRm9ybWF0KFB5RXhjX1R5cGVFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAiYXR0cmlidXRlIG5hbWUgbXVzdCBiZSBzdHJpbmcsIG5vdCAnJS4yMDBzJyIsCisgICAgICAgICAgICAgICAgICAgICAgICAgUHlfVFlQRShuYW1lKS0+dHBfbmFtZSk7CisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgfQorICAgIH0KKyAgICBpZiAodHAtPnRwX2dldGF0dHJvICE9IE5VTEwpCisgICAgICAgIHJldHVybiAoKnRwLT50cF9nZXRhdHRybykodiwgbmFtZSk7CisgICAgaWYgKHRwLT50cF9nZXRhdHRyICE9IE5VTEwpCisgICAgICAgIHJldHVybiAoKnRwLT50cF9nZXRhdHRyKSh2LCBQeVN0cmluZ19BU19TVFJJTkcobmFtZSkpOworICAgIFB5RXJyX0Zvcm1hdChQeUV4Y19BdHRyaWJ1dGVFcnJvciwKKyAgICAgICAgICAgICAgICAgIiclLjUwcycgb2JqZWN0IGhhcyBubyBhdHRyaWJ1dGUgJyUuNDAwcyciLAorICAgICAgICAgICAgICAgICB0cC0+dHBfbmFtZSwgUHlTdHJpbmdfQVNfU1RSSU5HKG5hbWUpKTsKKyAgICByZXR1cm4gTlVMTDsKK30KKworaW50CitQeU9iamVjdF9IYXNBdHRyKFB5T2JqZWN0ICp2LCBQeU9iamVjdCAqbmFtZSkKK3sKKyAgICBQeU9iamVjdCAqcmVzID0gUHlPYmplY3RfR2V0QXR0cih2LCBuYW1lKTsKKyAgICBpZiAocmVzICE9IE5VTEwpIHsKKyAgICAgICAgUHlfREVDUkVGKHJlcyk7CisgICAgICAgIHJldHVybiAxOworICAgIH0KKyAgICBQeUVycl9DbGVhcigpOworICAgIHJldHVybiAwOworfQorCitpbnQKK1B5T2JqZWN0X1NldEF0dHIoUHlPYmplY3QgKnYsIFB5T2JqZWN0ICpuYW1lLCBQeU9iamVjdCAqdmFsdWUpCit7CisgICAgUHlUeXBlT2JqZWN0ICp0cCA9IFB5X1RZUEUodik7CisgICAgaW50IGVycjsKKworICAgIGlmICghUHlTdHJpbmdfQ2hlY2sobmFtZSkpeworI2lmZGVmIFB5X1VTSU5HX1VOSUNPREUKKyAgICAgICAgLyogVGhlIFVuaWNvZGUgdG8gc3RyaW5nIGNvbnZlcnNpb24gaXMgZG9uZSBoZXJlIGJlY2F1c2UgdGhlCisgICAgICAgICAgIGV4aXN0aW5nIHRwX3NldGF0dHJvIHNsb3RzIGV4cGVjdCBhIHN0cmluZyBvYmplY3QgYXMgbmFtZQorICAgICAgICAgICBhbmQgd2Ugd291bGRuJ3Qgd2FudCB0byBicmVhayB0aG9zZS4gKi8KKyAgICAgICAgaWYgKFB5VW5pY29kZV9DaGVjayhuYW1lKSkgeworICAgICAgICAgICAgbmFtZSA9IFB5VW5pY29kZV9Bc0VuY29kZWRTdHJpbmcobmFtZSwgTlVMTCwgTlVMTCk7CisgICAgICAgICAgICBpZiAobmFtZSA9PSBOVUxMKQorICAgICAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgfQorICAgICAgICBlbHNlCisjZW5kaWYKKyAgICAgICAgeworICAgICAgICAgICAgUHlFcnJfRm9ybWF0KFB5RXhjX1R5cGVFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAiYXR0cmlidXRlIG5hbWUgbXVzdCBiZSBzdHJpbmcsIG5vdCAnJS4yMDBzJyIsCisgICAgICAgICAgICAgICAgICAgICAgICAgUHlfVFlQRShuYW1lKS0+dHBfbmFtZSk7CisgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgIH0KKyAgICB9CisgICAgZWxzZQorICAgICAgICBQeV9JTkNSRUYobmFtZSk7CisKKyAgICBQeVN0cmluZ19JbnRlcm5JblBsYWNlKCZuYW1lKTsKKyAgICBpZiAodHAtPnRwX3NldGF0dHJvICE9IE5VTEwpIHsKKyAgICAgICAgZXJyID0gKCp0cC0+dHBfc2V0YXR0cm8pKHYsIG5hbWUsIHZhbHVlKTsKKyAgICAgICAgUHlfREVDUkVGKG5hbWUpOworICAgICAgICByZXR1cm4gZXJyOworICAgIH0KKyAgICBpZiAodHAtPnRwX3NldGF0dHIgIT0gTlVMTCkgeworICAgICAgICBlcnIgPSAoKnRwLT50cF9zZXRhdHRyKSh2LCBQeVN0cmluZ19BU19TVFJJTkcobmFtZSksIHZhbHVlKTsKKyAgICAgICAgUHlfREVDUkVGKG5hbWUpOworICAgICAgICByZXR1cm4gZXJyOworICAgIH0KKyAgICBQeV9ERUNSRUYobmFtZSk7CisgICAgaWYgKHRwLT50cF9nZXRhdHRyID09IE5VTEwgJiYgdHAtPnRwX2dldGF0dHJvID09IE5VTEwpCisgICAgICAgIFB5RXJyX0Zvcm1hdChQeUV4Y19UeXBlRXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAiJyUuMTAwcycgb2JqZWN0IGhhcyBubyBhdHRyaWJ1dGVzICIKKyAgICAgICAgICAgICAgICAgICAgICIoJXMgLiUuMTAwcykiLAorICAgICAgICAgICAgICAgICAgICAgdHAtPnRwX25hbWUsCisgICAgICAgICAgICAgICAgICAgICB2YWx1ZT09TlVMTCA/ICJkZWwiIDogImFzc2lnbiB0byIsCisgICAgICAgICAgICAgICAgICAgICBQeVN0cmluZ19BU19TVFJJTkcobmFtZSkpOworICAgIGVsc2UKKyAgICAgICAgUHlFcnJfRm9ybWF0KFB5RXhjX1R5cGVFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICInJS4xMDBzJyBvYmplY3QgaGFzIG9ubHkgcmVhZC1vbmx5IGF0dHJpYnV0ZXMgIgorICAgICAgICAgICAgICAgICAgICAgIiglcyAuJS4xMDBzKSIsCisgICAgICAgICAgICAgICAgICAgICB0cC0+dHBfbmFtZSwKKyAgICAgICAgICAgICAgICAgICAgIHZhbHVlPT1OVUxMID8gImRlbCIgOiAiYXNzaWduIHRvIiwKKyAgICAgICAgICAgICAgICAgICAgIFB5U3RyaW5nX0FTX1NUUklORyhuYW1lKSk7CisgICAgcmV0dXJuIC0xOworfQorCisvKiBIZWxwZXIgdG8gZ2V0IGEgcG9pbnRlciB0byBhbiBvYmplY3QncyBfX2RpY3RfXyBzbG90LCBpZiBhbnkgKi8KKworUHlPYmplY3QgKioKK19QeU9iamVjdF9HZXREaWN0UHRyKFB5T2JqZWN0ICpvYmopCit7CisgICAgUHlfc3NpemVfdCBkaWN0b2Zmc2V0OworICAgIFB5VHlwZU9iamVjdCAqdHAgPSBQeV9UWVBFKG9iaik7CisKKyAgICBpZiAoISh0cC0+dHBfZmxhZ3MgJiBQeV9UUEZMQUdTX0hBVkVfQ0xBU1MpKQorICAgICAgICByZXR1cm4gTlVMTDsKKyAgICBkaWN0b2Zmc2V0ID0gdHAtPnRwX2RpY3RvZmZzZXQ7CisgICAgaWYgKGRpY3RvZmZzZXQgPT0gMCkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgaWYgKGRpY3RvZmZzZXQgPCAwKSB7CisgICAgICAgIFB5X3NzaXplX3QgdHNpemU7CisgICAgICAgIHNpemVfdCBzaXplOworCisgICAgICAgIHRzaXplID0gKChQeVZhck9iamVjdCAqKW9iaiktPm9iX3NpemU7CisgICAgICAgIGlmICh0c2l6ZSA8IDApCisgICAgICAgICAgICB0c2l6ZSA9IC10c2l6ZTsKKyAgICAgICAgc2l6ZSA9IF9QeU9iamVjdF9WQVJfU0laRSh0cCwgdHNpemUpOworCisgICAgICAgIGRpY3RvZmZzZXQgKz0gKGxvbmcpc2l6ZTsKKyAgICAgICAgYXNzZXJ0KGRpY3RvZmZzZXQgPiAwKTsKKyAgICAgICAgYXNzZXJ0KGRpY3RvZmZzZXQgJSBTSVpFT0ZfVk9JRF9QID09IDApOworICAgIH0KKyAgICByZXR1cm4gKFB5T2JqZWN0ICoqKSAoKGNoYXIgKilvYmogKyBkaWN0b2Zmc2V0KTsKK30KKworUHlPYmplY3QgKgorUHlPYmplY3RfU2VsZkl0ZXIoUHlPYmplY3QgKm9iaikKK3sKKyAgICBQeV9JTkNSRUYob2JqKTsKKyAgICByZXR1cm4gb2JqOworfQorCisvKiBIZWxwZXIgdXNlZCB3aGVuIHRoZSBfX25leHRfXyBtZXRob2QgaXMgcmVtb3ZlZCBmcm9tIGEgdHlwZToKKyAgIHRwX2l0ZXJuZXh0IGlzIG5ldmVyIE5VTEwgYW5kIGNhbiBiZSBzYWZlbHkgY2FsbGVkIHdpdGhvdXQgY2hlY2tpbmcKKyAgIG9uIGV2ZXJ5IGl0ZXJhdGlvbi4KKyAqLworCitQeU9iamVjdCAqCitfUHlPYmplY3RfTmV4dE5vdEltcGxlbWVudGVkKFB5T2JqZWN0ICpzZWxmKQoreworICAgIFB5RXJyX0Zvcm1hdChQeUV4Y19UeXBlRXJyb3IsCisgICAgICAgICAgICAgICAgICInJS4yMDBzJyBvYmplY3QgaXMgbm90IGl0ZXJhYmxlIiwKKyAgICAgICAgICAgICAgICAgUHlfVFlQRShzZWxmKS0+dHBfbmFtZSk7CisgICAgcmV0dXJuIE5VTEw7Cit9CisKKy8qIEdlbmVyaWMgR2V0QXR0ciBmdW5jdGlvbnMgLSBwdXQgdGhlc2UgaW4geW91ciB0cF9bZ3NdZXRhdHRybyBzbG90ICovCisKK1B5T2JqZWN0ICoKK19QeU9iamVjdF9HZW5lcmljR2V0QXR0cldpdGhEaWN0KFB5T2JqZWN0ICpvYmosIFB5T2JqZWN0ICpuYW1lLCBQeU9iamVjdCAqZGljdCkKK3sKKyAgICBQeVR5cGVPYmplY3QgKnRwID0gUHlfVFlQRShvYmopOworICAgIFB5T2JqZWN0ICpkZXNjciA9IE5VTEw7CisgICAgUHlPYmplY3QgKnJlcyA9IE5VTEw7CisgICAgZGVzY3JnZXRmdW5jIGY7CisgICAgUHlfc3NpemVfdCBkaWN0b2Zmc2V0OworICAgIFB5T2JqZWN0ICoqZGljdHB0cjsKKworICAgIGlmICghUHlTdHJpbmdfQ2hlY2sobmFtZSkpeworI2lmZGVmIFB5X1VTSU5HX1VOSUNPREUKKyAgICAgICAgLyogVGhlIFVuaWNvZGUgdG8gc3RyaW5nIGNvbnZlcnNpb24gaXMgZG9uZSBoZXJlIGJlY2F1c2UgdGhlCisgICAgICAgICAgIGV4aXN0aW5nIHRwX3NldGF0dHJvIHNsb3RzIGV4cGVjdCBhIHN0cmluZyBvYmplY3QgYXMgbmFtZQorICAgICAgICAgICBhbmQgd2Ugd291bGRuJ3Qgd2FudCB0byBicmVhayB0aG9zZS4gKi8KKyAgICAgICAgaWYgKFB5VW5pY29kZV9DaGVjayhuYW1lKSkgeworICAgICAgICAgICAgbmFtZSA9IFB5VW5pY29kZV9Bc0VuY29kZWRTdHJpbmcobmFtZSwgTlVMTCwgTlVMTCk7CisgICAgICAgICAgICBpZiAobmFtZSA9PSBOVUxMKQorICAgICAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgICAgICB9CisgICAgICAgIGVsc2UKKyNlbmRpZgorICAgICAgICB7CisgICAgICAgICAgICBQeUVycl9Gb3JtYXQoUHlFeGNfVHlwZUVycm9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICJhdHRyaWJ1dGUgbmFtZSBtdXN0IGJlIHN0cmluZywgbm90ICclLjIwMHMnIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICBQeV9UWVBFKG5hbWUpLT50cF9uYW1lKTsKKyAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgICAgICB9CisgICAgfQorICAgIGVsc2UKKyAgICAgICAgUHlfSU5DUkVGKG5hbWUpOworCisgICAgaWYgKHRwLT50cF9kaWN0ID09IE5VTEwpIHsKKyAgICAgICAgaWYgKFB5VHlwZV9SZWFkeSh0cCkgPCAwKQorICAgICAgICAgICAgZ290byBkb25lOworICAgIH0KKworI2lmIDAgLyogWFhYIHRoaXMgaXMgbm90IHF1aXRlIF9QeVR5cGVfTG9va3VwIGFueW1vcmUgKi8KKyAgICAvKiBJbmxpbmUgX1B5VHlwZV9Mb29rdXAgKi8KKyAgICB7CisgICAgICAgIFB5X3NzaXplX3QgaSwgbjsKKyAgICAgICAgUHlPYmplY3QgKm1ybywgKmJhc2UsICpkaWN0OworCisgICAgICAgIC8qIExvb2sgaW4gdHBfZGljdCBvZiB0eXBlcyBpbiBNUk8gKi8KKyAgICAgICAgbXJvID0gdHAtPnRwX21ybzsKKyAgICAgICAgYXNzZXJ0KG1ybyAhPSBOVUxMKTsKKyAgICAgICAgYXNzZXJ0KFB5VHVwbGVfQ2hlY2sobXJvKSk7CisgICAgICAgIG4gPSBQeVR1cGxlX0dFVF9TSVpFKG1ybyk7CisgICAgICAgIGZvciAoaSA9IDA7IGkgPCBuOyBpKyspIHsKKyAgICAgICAgICAgIGJhc2UgPSBQeVR1cGxlX0dFVF9JVEVNKG1ybywgaSk7CisgICAgICAgICAgICBpZiAoUHlDbGFzc19DaGVjayhiYXNlKSkKKyAgICAgICAgICAgICAgICBkaWN0ID0gKChQeUNsYXNzT2JqZWN0ICopYmFzZSktPmNsX2RpY3Q7CisgICAgICAgICAgICBlbHNlIHsKKyAgICAgICAgICAgICAgICBhc3NlcnQoUHlUeXBlX0NoZWNrKGJhc2UpKTsKKyAgICAgICAgICAgICAgICBkaWN0ID0gKChQeVR5cGVPYmplY3QgKiliYXNlKS0+dHBfZGljdDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGFzc2VydChkaWN0ICYmIFB5RGljdF9DaGVjayhkaWN0KSk7CisgICAgICAgICAgICBkZXNjciA9IFB5RGljdF9HZXRJdGVtKGRpY3QsIG5hbWUpOworICAgICAgICAgICAgaWYgKGRlc2NyICE9IE5VTEwpCisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKyAgICB9CisjZWxzZQorICAgIGRlc2NyID0gX1B5VHlwZV9Mb29rdXAodHAsIG5hbWUpOworI2VuZGlmCisKKyAgICBQeV9YSU5DUkVGKGRlc2NyKTsKKworICAgIGYgPSBOVUxMOworICAgIGlmIChkZXNjciAhPSBOVUxMICYmCisgICAgICAgIFB5VHlwZV9IYXNGZWF0dXJlKGRlc2NyLT5vYl90eXBlLCBQeV9UUEZMQUdTX0hBVkVfQ0xBU1MpKSB7CisgICAgICAgIGYgPSBkZXNjci0+b2JfdHlwZS0+dHBfZGVzY3JfZ2V0OworICAgICAgICBpZiAoZiAhPSBOVUxMICYmIFB5RGVzY3JfSXNEYXRhKGRlc2NyKSkgeworICAgICAgICAgICAgcmVzID0gZihkZXNjciwgb2JqLCAoUHlPYmplY3QgKilvYmotPm9iX3R5cGUpOworICAgICAgICAgICAgUHlfREVDUkVGKGRlc2NyKTsKKyAgICAgICAgICAgIGdvdG8gZG9uZTsKKyAgICAgICAgfQorICAgIH0KKworICAgIGlmIChkaWN0ID09IE5VTEwpIHsKKyAgICAgICAgLyogSW5saW5lIF9QeU9iamVjdF9HZXREaWN0UHRyICovCisgICAgICAgIGRpY3RvZmZzZXQgPSB0cC0+dHBfZGljdG9mZnNldDsKKyAgICAgICAgaWYgKGRpY3RvZmZzZXQgIT0gMCkgeworICAgICAgICAgICAgaWYgKGRpY3RvZmZzZXQgPCAwKSB7CisgICAgICAgICAgICAgICAgUHlfc3NpemVfdCB0c2l6ZTsKKyAgICAgICAgICAgICAgICBzaXplX3Qgc2l6ZTsKKworICAgICAgICAgICAgICAgIHRzaXplID0gKChQeVZhck9iamVjdCAqKW9iaiktPm9iX3NpemU7CisgICAgICAgICAgICAgICAgaWYgKHRzaXplIDwgMCkKKyAgICAgICAgICAgICAgICAgICAgdHNpemUgPSAtdHNpemU7CisgICAgICAgICAgICAgICAgc2l6ZSA9IF9QeU9iamVjdF9WQVJfU0laRSh0cCwgdHNpemUpOworCisgICAgICAgICAgICAgICAgZGljdG9mZnNldCArPSAobG9uZylzaXplOworICAgICAgICAgICAgICAgIGFzc2VydChkaWN0b2Zmc2V0ID4gMCk7CisgICAgICAgICAgICAgICAgYXNzZXJ0KGRpY3RvZmZzZXQgJSBTSVpFT0ZfVk9JRF9QID09IDApOworICAgICAgICAgICAgfQorICAgICAgICAgICAgZGljdHB0ciA9IChQeU9iamVjdCAqKikgKChjaGFyICopb2JqICsgZGljdG9mZnNldCk7CisgICAgICAgICAgICBkaWN0ID0gKmRpY3RwdHI7CisgICAgICAgIH0KKyAgICB9CisgICAgaWYgKGRpY3QgIT0gTlVMTCkgeworICAgICAgICBQeV9JTkNSRUYoZGljdCk7CisgICAgICAgIHJlcyA9IFB5RGljdF9HZXRJdGVtKGRpY3QsIG5hbWUpOworICAgICAgICBpZiAocmVzICE9IE5VTEwpIHsKKyAgICAgICAgICAgIFB5X0lOQ1JFRihyZXMpOworICAgICAgICAgICAgUHlfWERFQ1JFRihkZXNjcik7CisgICAgICAgICAgICBQeV9ERUNSRUYoZGljdCk7CisgICAgICAgICAgICBnb3RvIGRvbmU7CisgICAgICAgIH0KKyAgICAgICAgUHlfREVDUkVGKGRpY3QpOworICAgIH0KKworICAgIGlmIChmICE9IE5VTEwpIHsKKyAgICAgICAgcmVzID0gZihkZXNjciwgb2JqLCAoUHlPYmplY3QgKilQeV9UWVBFKG9iaikpOworICAgICAgICBQeV9ERUNSRUYoZGVzY3IpOworICAgICAgICBnb3RvIGRvbmU7CisgICAgfQorCisgICAgaWYgKGRlc2NyICE9IE5VTEwpIHsKKyAgICAgICAgcmVzID0gZGVzY3I7CisgICAgICAgIC8qIGRlc2NyIHdhcyBhbHJlYWR5IGluY3JlZmVkIGFib3ZlICovCisgICAgICAgIGdvdG8gZG9uZTsKKyAgICB9CisKKyAgICBQeUVycl9Gb3JtYXQoUHlFeGNfQXR0cmlidXRlRXJyb3IsCisgICAgICAgICAgICAgICAgICInJS41MHMnIG9iamVjdCBoYXMgbm8gYXR0cmlidXRlICclLjQwMHMnIiwKKyAgICAgICAgICAgICAgICAgdHAtPnRwX25hbWUsIFB5U3RyaW5nX0FTX1NUUklORyhuYW1lKSk7CisgIGRvbmU6CisgICAgUHlfREVDUkVGKG5hbWUpOworICAgIHJldHVybiByZXM7Cit9CisKK1B5T2JqZWN0ICoKK1B5T2JqZWN0X0dlbmVyaWNHZXRBdHRyKFB5T2JqZWN0ICpvYmosIFB5T2JqZWN0ICpuYW1lKQoreworICAgIHJldHVybiBfUHlPYmplY3RfR2VuZXJpY0dldEF0dHJXaXRoRGljdChvYmosIG5hbWUsIE5VTEwpOworfQorCitpbnQKK19QeU9iamVjdF9HZW5lcmljU2V0QXR0cldpdGhEaWN0KFB5T2JqZWN0ICpvYmosIFB5T2JqZWN0ICpuYW1lLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHlPYmplY3QgKnZhbHVlLCBQeU9iamVjdCAqZGljdCkKK3sKKyAgICBQeVR5cGVPYmplY3QgKnRwID0gUHlfVFlQRShvYmopOworICAgIFB5T2JqZWN0ICpkZXNjcjsKKyAgICBkZXNjcnNldGZ1bmMgZjsKKyAgICBQeU9iamVjdCAqKmRpY3RwdHI7CisgICAgaW50IHJlcyA9IC0xOworCisgICAgaWYgKCFQeVN0cmluZ19DaGVjayhuYW1lKSl7CisjaWZkZWYgUHlfVVNJTkdfVU5JQ09ERQorICAgICAgICAvKiBUaGUgVW5pY29kZSB0byBzdHJpbmcgY29udmVyc2lvbiBpcyBkb25lIGhlcmUgYmVjYXVzZSB0aGUKKyAgICAgICAgICAgZXhpc3RpbmcgdHBfc2V0YXR0cm8gc2xvdHMgZXhwZWN0IGEgc3RyaW5nIG9iamVjdCBhcyBuYW1lCisgICAgICAgICAgIGFuZCB3ZSB3b3VsZG4ndCB3YW50IHRvIGJyZWFrIHRob3NlLiAqLworICAgICAgICBpZiAoUHlVbmljb2RlX0NoZWNrKG5hbWUpKSB7CisgICAgICAgICAgICBuYW1lID0gUHlVbmljb2RlX0FzRW5jb2RlZFN0cmluZyhuYW1lLCBOVUxMLCBOVUxMKTsKKyAgICAgICAgICAgIGlmIChuYW1lID09IE5VTEwpCisgICAgICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICB9CisgICAgICAgIGVsc2UKKyNlbmRpZgorICAgICAgICB7CisgICAgICAgICAgICBQeUVycl9Gb3JtYXQoUHlFeGNfVHlwZUVycm9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICJhdHRyaWJ1dGUgbmFtZSBtdXN0IGJlIHN0cmluZywgbm90ICclLjIwMHMnIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICBQeV9UWVBFKG5hbWUpLT50cF9uYW1lKTsKKyAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgfQorICAgIH0KKyAgICBlbHNlCisgICAgICAgIFB5X0lOQ1JFRihuYW1lKTsKKworICAgIGlmICh0cC0+dHBfZGljdCA9PSBOVUxMKSB7CisgICAgICAgIGlmIChQeVR5cGVfUmVhZHkodHApIDwgMCkKKyAgICAgICAgICAgIGdvdG8gZG9uZTsKKyAgICB9CisKKyAgICBkZXNjciA9IF9QeVR5cGVfTG9va3VwKHRwLCBuYW1lKTsKKyAgICBmID0gTlVMTDsKKyAgICBpZiAoZGVzY3IgIT0gTlVMTCAmJgorICAgICAgICBQeVR5cGVfSGFzRmVhdHVyZShkZXNjci0+b2JfdHlwZSwgUHlfVFBGTEFHU19IQVZFX0NMQVNTKSkgeworICAgICAgICBmID0gZGVzY3ItPm9iX3R5cGUtPnRwX2Rlc2NyX3NldDsKKyAgICAgICAgaWYgKGYgIT0gTlVMTCAmJiBQeURlc2NyX0lzRGF0YShkZXNjcikpIHsKKyAgICAgICAgICAgIHJlcyA9IGYoZGVzY3IsIG9iaiwgdmFsdWUpOworICAgICAgICAgICAgZ290byBkb25lOworICAgICAgICB9CisgICAgfQorCisgICAgaWYgKGRpY3QgPT0gTlVMTCkgeworICAgICAgICBkaWN0cHRyID0gX1B5T2JqZWN0X0dldERpY3RQdHIob2JqKTsKKyAgICAgICAgaWYgKGRpY3RwdHIgIT0gTlVMTCkgeworICAgICAgICAgICAgZGljdCA9ICpkaWN0cHRyOworICAgICAgICAgICAgaWYgKGRpY3QgPT0gTlVMTCAmJiB2YWx1ZSAhPSBOVUxMKSB7CisgICAgICAgICAgICAgICAgZGljdCA9IFB5RGljdF9OZXcoKTsKKyAgICAgICAgICAgICAgICBpZiAoZGljdCA9PSBOVUxMKQorICAgICAgICAgICAgICAgICAgICBnb3RvIGRvbmU7CisgICAgICAgICAgICAgICAgKmRpY3RwdHIgPSBkaWN0OworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorICAgIGlmIChkaWN0ICE9IE5VTEwpIHsKKyAgICAgICAgUHlfSU5DUkVGKGRpY3QpOworICAgICAgICBpZiAodmFsdWUgPT0gTlVMTCkKKyAgICAgICAgICAgIHJlcyA9IFB5RGljdF9EZWxJdGVtKGRpY3QsIG5hbWUpOworICAgICAgICBlbHNlCisgICAgICAgICAgICByZXMgPSBQeURpY3RfU2V0SXRlbShkaWN0LCBuYW1lLCB2YWx1ZSk7CisgICAgICAgIGlmIChyZXMgPCAwICYmIFB5RXJyX0V4Y2VwdGlvbk1hdGNoZXMoUHlFeGNfS2V5RXJyb3IpKQorICAgICAgICAgICAgUHlFcnJfU2V0T2JqZWN0KFB5RXhjX0F0dHJpYnV0ZUVycm9yLCBuYW1lKTsKKyAgICAgICAgUHlfREVDUkVGKGRpY3QpOworICAgICAgICBnb3RvIGRvbmU7CisgICAgfQorCisgICAgaWYgKGYgIT0gTlVMTCkgeworICAgICAgICByZXMgPSBmKGRlc2NyLCBvYmosIHZhbHVlKTsKKyAgICAgICAgZ290byBkb25lOworICAgIH0KKworICAgIGlmIChkZXNjciA9PSBOVUxMKSB7CisgICAgICAgIFB5RXJyX0Zvcm1hdChQeUV4Y19BdHRyaWJ1dGVFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICInJS4xMDBzJyBvYmplY3QgaGFzIG5vIGF0dHJpYnV0ZSAnJS4yMDBzJyIsCisgICAgICAgICAgICAgICAgICAgICB0cC0+dHBfbmFtZSwgUHlTdHJpbmdfQVNfU1RSSU5HKG5hbWUpKTsKKyAgICAgICAgZ290byBkb25lOworICAgIH0KKworICAgIFB5RXJyX0Zvcm1hdChQeUV4Y19BdHRyaWJ1dGVFcnJvciwKKyAgICAgICAgICAgICAgICAgIiclLjUwcycgb2JqZWN0IGF0dHJpYnV0ZSAnJS40MDBzJyBpcyByZWFkLW9ubHkiLAorICAgICAgICAgICAgICAgICB0cC0+dHBfbmFtZSwgUHlTdHJpbmdfQVNfU1RSSU5HKG5hbWUpKTsKKyAgZG9uZToKKyAgICBQeV9ERUNSRUYobmFtZSk7CisgICAgcmV0dXJuIHJlczsKK30KKworaW50CitQeU9iamVjdF9HZW5lcmljU2V0QXR0cihQeU9iamVjdCAqb2JqLCBQeU9iamVjdCAqbmFtZSwgUHlPYmplY3QgKnZhbHVlKQoreworICAgIHJldHVybiBfUHlPYmplY3RfR2VuZXJpY1NldEF0dHJXaXRoRGljdChvYmosIG5hbWUsIHZhbHVlLCBOVUxMKTsKK30KKworCisvKiBUZXN0IGEgdmFsdWUgdXNlZCBhcyBjb25kaXRpb24sIGUuZy4sIGluIGEgZm9yIG9yIGlmIHN0YXRlbWVudC4KKyAgIFJldHVybiAtMSBpZiBhbiBlcnJvciBvY2N1cnJlZCAqLworCitpbnQKK1B5T2JqZWN0X0lzVHJ1ZShQeU9iamVjdCAqdikKK3sKKyAgICBQeV9zc2l6ZV90IHJlczsKKyAgICBpZiAodiA9PSBQeV9UcnVlKQorICAgICAgICByZXR1cm4gMTsKKyAgICBpZiAodiA9PSBQeV9GYWxzZSkKKyAgICAgICAgcmV0dXJuIDA7CisgICAgaWYgKHYgPT0gUHlfTm9uZSkKKyAgICAgICAgcmV0dXJuIDA7CisgICAgZWxzZSBpZiAodi0+b2JfdHlwZS0+dHBfYXNfbnVtYmVyICE9IE5VTEwgJiYKKyAgICAgICAgICAgICB2LT5vYl90eXBlLT50cF9hc19udW1iZXItPm5iX25vbnplcm8gIT0gTlVMTCkKKyAgICAgICAgcmVzID0gKCp2LT5vYl90eXBlLT50cF9hc19udW1iZXItPm5iX25vbnplcm8pKHYpOworICAgIGVsc2UgaWYgKHYtPm9iX3R5cGUtPnRwX2FzX21hcHBpbmcgIT0gTlVMTCAmJgorICAgICAgICAgICAgIHYtPm9iX3R5cGUtPnRwX2FzX21hcHBpbmctPm1wX2xlbmd0aCAhPSBOVUxMKQorICAgICAgICByZXMgPSAoKnYtPm9iX3R5cGUtPnRwX2FzX21hcHBpbmctPm1wX2xlbmd0aCkodik7CisgICAgZWxzZSBpZiAodi0+b2JfdHlwZS0+dHBfYXNfc2VxdWVuY2UgIT0gTlVMTCAmJgorICAgICAgICAgICAgIHYtPm9iX3R5cGUtPnRwX2FzX3NlcXVlbmNlLT5zcV9sZW5ndGggIT0gTlVMTCkKKyAgICAgICAgcmVzID0gKCp2LT5vYl90eXBlLT50cF9hc19zZXF1ZW5jZS0+c3FfbGVuZ3RoKSh2KTsKKyAgICBlbHNlCisgICAgICAgIHJldHVybiAxOworICAgIC8qIGlmIGl0IGlzIG5lZ2F0aXZlLCBpdCBzaG91bGQgYmUgZWl0aGVyIC0xIG9yIC0yICovCisgICAgcmV0dXJuIChyZXMgPiAwKSA/IDEgOiBQeV9TQUZFX0RPV05DQVNUKHJlcywgUHlfc3NpemVfdCwgaW50KTsKK30KKworLyogZXF1aXZhbGVudCBvZiAnbm90IHYnCisgICBSZXR1cm4gLTEgaWYgYW4gZXJyb3Igb2NjdXJyZWQgKi8KKworaW50CitQeU9iamVjdF9Ob3QoUHlPYmplY3QgKnYpCit7CisgICAgaW50IHJlczsKKyAgICByZXMgPSBQeU9iamVjdF9Jc1RydWUodik7CisgICAgaWYgKHJlcyA8IDApCisgICAgICAgIHJldHVybiByZXM7CisgICAgcmV0dXJuIHJlcyA9PSAwOworfQorCisvKiBDb2VyY2UgdHdvIG51bWVyaWMgdHlwZXMgdG8gdGhlICJsYXJnZXIiIG9uZS4KKyAgIEluY3JlbWVudCB0aGUgcmVmZXJlbmNlIGNvdW50IG9uIGVhY2ggYXJndW1lbnQuCisgICBSZXR1cm4gdmFsdWU6CisgICAtMSBpZiBhbiBlcnJvciBvY2N1cnJlZDsKKyAgIDAgaWYgdGhlIGNvZXJjaW9uIHN1Y2NlZWRlZCAoYW5kIHRoZW4gdGhlIHJlZmVyZW5jZSBjb3VudHMgYXJlIGluY3JlYXNlZCk7CisgICAxIGlmIG5vIGNvZXJjaW9uIGlzIHBvc3NpYmxlIChhbmQgbm8gZXJyb3IgaXMgcmFpc2VkKS4KKyovCitpbnQKK1B5TnVtYmVyX0NvZXJjZUV4KFB5T2JqZWN0ICoqcHYsIFB5T2JqZWN0ICoqcHcpCit7CisgICAgcmVnaXN0ZXIgUHlPYmplY3QgKnYgPSAqcHY7CisgICAgcmVnaXN0ZXIgUHlPYmplY3QgKncgPSAqcHc7CisgICAgaW50IHJlczsKKworICAgIC8qIFNob3J0Y3V0IG9ubHkgZm9yIG9sZC1zdHlsZSB0eXBlcyAqLworICAgIGlmICh2LT5vYl90eXBlID09IHctPm9iX3R5cGUgJiYKKyAgICAgICAgIVB5VHlwZV9IYXNGZWF0dXJlKHYtPm9iX3R5cGUsIFB5X1RQRkxBR1NfQ0hFQ0tUWVBFUykpCisgICAgeworICAgICAgICBQeV9JTkNSRUYodik7CisgICAgICAgIFB5X0lOQ1JFRih3KTsKKyAgICAgICAgcmV0dXJuIDA7CisgICAgfQorICAgIGlmICh2LT5vYl90eXBlLT50cF9hc19udW1iZXIgJiYgdi0+b2JfdHlwZS0+dHBfYXNfbnVtYmVyLT5uYl9jb2VyY2UpIHsKKyAgICAgICAgcmVzID0gKCp2LT5vYl90eXBlLT50cF9hc19udW1iZXItPm5iX2NvZXJjZSkocHYsIHB3KTsKKyAgICAgICAgaWYgKHJlcyA8PSAwKQorICAgICAgICAgICAgcmV0dXJuIHJlczsKKyAgICB9CisgICAgaWYgKHctPm9iX3R5cGUtPnRwX2FzX251bWJlciAmJiB3LT5vYl90eXBlLT50cF9hc19udW1iZXItPm5iX2NvZXJjZSkgeworICAgICAgICByZXMgPSAoKnctPm9iX3R5cGUtPnRwX2FzX251bWJlci0+bmJfY29lcmNlKShwdywgcHYpOworICAgICAgICBpZiAocmVzIDw9IDApCisgICAgICAgICAgICByZXR1cm4gcmVzOworICAgIH0KKyAgICByZXR1cm4gMTsKK30KKworLyogQ29lcmNlIHR3byBudW1lcmljIHR5cGVzIHRvIHRoZSAibGFyZ2VyIiBvbmUuCisgICBJbmNyZW1lbnQgdGhlIHJlZmVyZW5jZSBjb3VudCBvbiBlYWNoIGFyZ3VtZW50LgorICAgUmV0dXJuIC0xIGFuZCByYWlzZSBhbiBleGNlcHRpb24gaWYgbm8gY29lcmNpb24gaXMgcG9zc2libGUKKyAgIChhbmQgdGhlbiBubyByZWZlcmVuY2UgY291bnQgaXMgaW5jcmVtZW50ZWQpLgorKi8KK2ludAorUHlOdW1iZXJfQ29lcmNlKFB5T2JqZWN0ICoqcHYsIFB5T2JqZWN0ICoqcHcpCit7CisgICAgaW50IGVyciA9IFB5TnVtYmVyX0NvZXJjZUV4KHB2LCBwdyk7CisgICAgaWYgKGVyciA8PSAwKQorICAgICAgICByZXR1cm4gZXJyOworICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19UeXBlRXJyb3IsICJudW1iZXIgY29lcmNpb24gZmFpbGVkIik7CisgICAgcmV0dXJuIC0xOworfQorCisKKy8qIFRlc3Qgd2hldGhlciBhbiBvYmplY3QgY2FuIGJlIGNhbGxlZCAqLworCitpbnQKK1B5Q2FsbGFibGVfQ2hlY2soUHlPYmplY3QgKngpCit7CisgICAgaWYgKHggPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIDA7CisgICAgaWYgKFB5SW5zdGFuY2VfQ2hlY2soeCkpIHsKKyAgICAgICAgUHlPYmplY3QgKmNhbGwgPSBQeU9iamVjdF9HZXRBdHRyU3RyaW5nKHgsICJfX2NhbGxfXyIpOworICAgICAgICBpZiAoY2FsbCA9PSBOVUxMKSB7CisgICAgICAgICAgICBQeUVycl9DbGVhcigpOworICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgIH0KKyAgICAgICAgLyogQ291bGQgdGVzdCByZWN1cnNpdmVseSBidXQgZG9uJ3QsIGZvciBmZWFyIG9mIGVuZGxlc3MKKyAgICAgICAgICAgcmVjdXJzaW9uIGlmIHNvbWUgam9rZXIgc2V0cyBzZWxmLl9fY2FsbF9fID0gc2VsZiAqLworICAgICAgICBQeV9ERUNSRUYoY2FsbCk7CisgICAgICAgIHJldHVybiAxOworICAgIH0KKyAgICBlbHNlIHsKKyAgICAgICAgcmV0dXJuIHgtPm9iX3R5cGUtPnRwX2NhbGwgIT0gTlVMTDsKKyAgICB9Cit9CisKKy8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gUHlPYmplY3RfRGlyKCkgaGVscGVycyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCisKKy8qIEhlbHBlciBmb3IgUHlPYmplY3RfRGlyLgorICAgTWVyZ2UgdGhlIF9fZGljdF9fIG9mIGFjbGFzcyBpbnRvIGRpY3QsIGFuZCByZWN1cnNpdmVseSBhbHNvIGFsbAorICAgdGhlIF9fZGljdF9fcyBvZiBhY2xhc3MncyBiYXNlIGNsYXNzZXMuICBUaGUgb3JkZXIgb2YgbWVyZ2luZyBpc24ndAorICAgZGVmaW5lZCwgYXMgaXQncyBleHBlY3RlZCB0aGF0IG9ubHkgdGhlIGZpbmFsIHNldCBvZiBkaWN0IGtleXMgaXMKKyAgIGludGVyZXN0aW5nLgorICAgUmV0dXJuIDAgb24gc3VjY2VzcywgLTEgb24gZXJyb3IuCisqLworCitzdGF0aWMgaW50CittZXJnZV9jbGFzc19kaWN0KFB5T2JqZWN0KiBkaWN0LCBQeU9iamVjdCogYWNsYXNzKQoreworICAgIFB5T2JqZWN0ICpjbGFzc2RpY3Q7CisgICAgUHlPYmplY3QgKmJhc2VzOworCisgICAgYXNzZXJ0KFB5RGljdF9DaGVjayhkaWN0KSk7CisgICAgYXNzZXJ0KGFjbGFzcyk7CisKKyAgICAvKiBNZXJnZSBpbiB0aGUgdHlwZSdzIGRpY3QgKGlmIGFueSkuICovCisgICAgY2xhc3NkaWN0ID0gUHlPYmplY3RfR2V0QXR0clN0cmluZyhhY2xhc3MsICJfX2RpY3RfXyIpOworICAgIGlmIChjbGFzc2RpY3QgPT0gTlVMTCkKKyAgICAgICAgUHlFcnJfQ2xlYXIoKTsKKyAgICBlbHNlIHsKKyAgICAgICAgaW50IHN0YXR1cyA9IFB5RGljdF9VcGRhdGUoZGljdCwgY2xhc3NkaWN0KTsKKyAgICAgICAgUHlfREVDUkVGKGNsYXNzZGljdCk7CisgICAgICAgIGlmIChzdGF0dXMgPCAwKQorICAgICAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKworICAgIC8qIFJlY3Vyc2l2ZWx5IG1lcmdlIGluIHRoZSBiYXNlIHR5cGVzJyAoaWYgYW55KSBkaWN0cy4gKi8KKyAgICBiYXNlcyA9IFB5T2JqZWN0X0dldEF0dHJTdHJpbmcoYWNsYXNzLCAiX19iYXNlc19fIik7CisgICAgaWYgKGJhc2VzID09IE5VTEwpCisgICAgICAgIFB5RXJyX0NsZWFyKCk7CisgICAgZWxzZSB7CisgICAgICAgIC8qIFdlIGhhdmUgbm8gZ3VhcmFudGVlIHRoYXQgYmFzZXMgaXMgYSByZWFsIHR1cGxlICovCisgICAgICAgIFB5X3NzaXplX3QgaSwgbjsKKyAgICAgICAgbiA9IFB5U2VxdWVuY2VfU2l6ZShiYXNlcyk7IC8qIFRoaXMgYmV0dGVyIGJlIHJpZ2h0ICovCisgICAgICAgIGlmIChuIDwgMCkKKyAgICAgICAgICAgIFB5RXJyX0NsZWFyKCk7CisgICAgICAgIGVsc2UgeworICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IG47IGkrKykgeworICAgICAgICAgICAgICAgIGludCBzdGF0dXM7CisgICAgICAgICAgICAgICAgUHlPYmplY3QgKmJhc2UgPSBQeVNlcXVlbmNlX0dldEl0ZW0oYmFzZXMsIGkpOworICAgICAgICAgICAgICAgIGlmIChiYXNlID09IE5VTEwpIHsKKyAgICAgICAgICAgICAgICAgICAgUHlfREVDUkVGKGJhc2VzKTsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBzdGF0dXMgPSBtZXJnZV9jbGFzc19kaWN0KGRpY3QsIGJhc2UpOworICAgICAgICAgICAgICAgIFB5X0RFQ1JFRihiYXNlKTsKKyAgICAgICAgICAgICAgICBpZiAoc3RhdHVzIDwgMCkgeworICAgICAgICAgICAgICAgICAgICBQeV9ERUNSRUYoYmFzZXMpOworICAgICAgICAgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIFB5X0RFQ1JFRihiYXNlcyk7CisgICAgfQorICAgIHJldHVybiAwOworfQorCisvKiBIZWxwZXIgZm9yIFB5T2JqZWN0X0Rpci4KKyAgIElmIG9iaiBoYXMgYW4gYXR0ciBuYW1lZCBhdHRybmFtZSB0aGF0J3MgYSBsaXN0LCBtZXJnZSBpdHMgc3RyaW5nCisgICBlbGVtZW50cyBpbnRvIGtleXMgb2YgZGljdC4KKyAgIFJldHVybiAwIG9uIHN1Y2Nlc3MsIC0xIG9uIGVycm9yLiAgRXJyb3JzIGR1ZSB0byBub3QgZmluZGluZyB0aGUgYXR0ciwKKyAgIG9yIHRoZSBhdHRyIG5vdCBiZWluZyBhIGxpc3QsIGFyZSBzdXBwcmVzc2VkLgorKi8KKworc3RhdGljIGludAorbWVyZ2VfbGlzdF9hdHRyKFB5T2JqZWN0KiBkaWN0LCBQeU9iamVjdCogb2JqLCBjb25zdCBjaGFyICphdHRybmFtZSkKK3sKKyAgICBQeU9iamVjdCAqbGlzdDsKKyAgICBpbnQgcmVzdWx0ID0gMDsKKworICAgIGFzc2VydChQeURpY3RfQ2hlY2soZGljdCkpOworICAgIGFzc2VydChvYmopOworICAgIGFzc2VydChhdHRybmFtZSk7CisKKyAgICBsaXN0ID0gUHlPYmplY3RfR2V0QXR0clN0cmluZyhvYmosIGF0dHJuYW1lKTsKKyAgICBpZiAobGlzdCA9PSBOVUxMKQorICAgICAgICBQeUVycl9DbGVhcigpOworCisgICAgZWxzZSBpZiAoUHlMaXN0X0NoZWNrKGxpc3QpKSB7CisgICAgICAgIGludCBpOworICAgICAgICBmb3IgKGkgPSAwOyBpIDwgUHlMaXN0X0dFVF9TSVpFKGxpc3QpOyArK2kpIHsKKyAgICAgICAgICAgIFB5T2JqZWN0ICppdGVtID0gUHlMaXN0X0dFVF9JVEVNKGxpc3QsIGkpOworICAgICAgICAgICAgaWYgKFB5U3RyaW5nX0NoZWNrKGl0ZW0pKSB7CisgICAgICAgICAgICAgICAgcmVzdWx0ID0gUHlEaWN0X1NldEl0ZW0oZGljdCwgaXRlbSwgUHlfTm9uZSk7CisgICAgICAgICAgICAgICAgaWYgKHJlc3VsdCA8IDApCisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGlmIChQeV9QeTNrV2FybmluZ0ZsYWcgJiYKKyAgICAgICAgICAgIChzdHJjbXAoYXR0cm5hbWUsICJfX21lbWJlcnNfXyIpID09IDAgfHwKKyAgICAgICAgICAgICBzdHJjbXAoYXR0cm5hbWUsICJfX21ldGhvZHNfXyIpID09IDApKSB7CisgICAgICAgICAgICBpZiAoUHlFcnJfV2FybkV4KFB5RXhjX0RlcHJlY2F0aW9uV2FybmluZywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICJfX21lbWJlcnNfXyBhbmQgX19tZXRob2RzX18gbm90ICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICJzdXBwb3J0ZWQgaW4gMy54IiwgMSkgPCAwKSB7CisgICAgICAgICAgICAgICAgUHlfWERFQ1JFRihsaXN0KTsKKyAgICAgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBQeV9YREVDUkVGKGxpc3QpOworICAgIHJldHVybiByZXN1bHQ7Cit9CisKKy8qIEhlbHBlciBmb3IgUHlPYmplY3RfRGlyIHdpdGhvdXQgYXJndW1lbnRzOiByZXR1cm5zIHRoZSBsb2NhbCBzY29wZS4gKi8KK3N0YXRpYyBQeU9iamVjdCAqCitfZGlyX2xvY2Fscyh2b2lkKQoreworICAgIFB5T2JqZWN0ICpuYW1lczsKKyAgICBQeU9iamVjdCAqbG9jYWxzID0gUHlFdmFsX0dldExvY2FscygpOworCisgICAgaWYgKGxvY2FscyA9PSBOVUxMKSB7CisgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19TeXN0ZW1FcnJvciwgImZyYW1lIGRvZXMgbm90IGV4aXN0Iik7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKworICAgIG5hbWVzID0gUHlNYXBwaW5nX0tleXMobG9jYWxzKTsKKyAgICBpZiAoIW5hbWVzKQorICAgICAgICByZXR1cm4gTlVMTDsKKyAgICBpZiAoIVB5TGlzdF9DaGVjayhuYW1lcykpIHsKKyAgICAgICAgUHlFcnJfRm9ybWF0KFB5RXhjX1R5cGVFcnJvciwKKyAgICAgICAgICAgICJkaXIoKTogZXhwZWN0ZWQga2V5cygpIG9mIGxvY2FscyB0byBiZSBhIGxpc3QsICIKKyAgICAgICAgICAgICJub3QgJyUuMjAwcyciLCBQeV9UWVBFKG5hbWVzKS0+dHBfbmFtZSk7CisgICAgICAgIFB5X0RFQ1JFRihuYW1lcyk7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICAvKiB0aGUgbG9jYWxzIGRvbid0IG5lZWQgdG8gYmUgREVDUkVGJ2QgKi8KKyAgICByZXR1cm4gbmFtZXM7Cit9CisKKy8qIEhlbHBlciBmb3IgUHlPYmplY3RfRGlyIG9mIHR5cGUgb2JqZWN0czogcmV0dXJucyBfX2RpY3RfXyBhbmQgX19iYXNlc19fLgorICAgV2UgZGVsaWJlcmF0ZWx5IGRvbid0IHN1Y2sgdXAgaXRzIF9fY2xhc3NfXywgYXMgbWV0aG9kcyBiZWxvbmdpbmcgdG8gdGhlCisgICBtZXRhY2xhc3Mgd291bGQgcHJvYmFibHkgYmUgbW9yZSBjb25mdXNpbmcgdGhhbiBoZWxwZnVsLgorKi8KK3N0YXRpYyBQeU9iamVjdCAqCitfc3BlY2lhbGl6ZWRfZGlyX3R5cGUoUHlPYmplY3QgKm9iaikKK3sKKyAgICBQeU9iamVjdCAqcmVzdWx0ID0gTlVMTDsKKyAgICBQeU9iamVjdCAqZGljdCA9IFB5RGljdF9OZXcoKTsKKworICAgIGlmIChkaWN0ICE9IE5VTEwgJiYgbWVyZ2VfY2xhc3NfZGljdChkaWN0LCBvYmopID09IDApCisgICAgICAgIHJlc3VsdCA9IFB5RGljdF9LZXlzKGRpY3QpOworCisgICAgUHlfWERFQ1JFRihkaWN0KTsKKyAgICByZXR1cm4gcmVzdWx0OworfQorCisvKiBIZWxwZXIgZm9yIFB5T2JqZWN0X0RpciBvZiBtb2R1bGUgb2JqZWN0czogcmV0dXJucyB0aGUgbW9kdWxlJ3MgX19kaWN0X18uICovCitzdGF0aWMgUHlPYmplY3QgKgorX3NwZWNpYWxpemVkX2Rpcl9tb2R1bGUoUHlPYmplY3QgKm9iaikKK3sKKyAgICBQeU9iamVjdCAqcmVzdWx0ID0gTlVMTDsKKyAgICBQeU9iamVjdCAqZGljdCA9IFB5T2JqZWN0X0dldEF0dHJTdHJpbmcob2JqLCAiX19kaWN0X18iKTsKKworICAgIGlmIChkaWN0ICE9IE5VTEwpIHsKKyAgICAgICAgaWYgKFB5RGljdF9DaGVjayhkaWN0KSkKKyAgICAgICAgICAgIHJlc3VsdCA9IFB5RGljdF9LZXlzKGRpY3QpOworICAgICAgICBlbHNlIHsKKyAgICAgICAgICAgIGNoYXIgKm5hbWUgPSBQeU1vZHVsZV9HZXROYW1lKG9iaik7CisgICAgICAgICAgICBpZiAobmFtZSkKKyAgICAgICAgICAgICAgICBQeUVycl9Gb3JtYXQoUHlFeGNfVHlwZUVycm9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiJS4yMDBzLl9fZGljdF9fIGlzIG5vdCBhIGRpY3Rpb25hcnkiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIFB5X1hERUNSRUYoZGljdCk7CisgICAgcmV0dXJuIHJlc3VsdDsKK30KKworLyogSGVscGVyIGZvciBQeU9iamVjdF9EaXIgb2YgZ2VuZXJpYyBvYmplY3RzOiByZXR1cm5zIF9fZGljdF9fLCBfX2NsYXNzX18sCisgICBhbmQgcmVjdXJzaXZlbHkgdXAgdGhlIF9fY2xhc3NfXy5fX2Jhc2VzX18gY2hhaW4uCisqLworc3RhdGljIFB5T2JqZWN0ICoKK19nZW5lcmljX2RpcihQeU9iamVjdCAqb2JqKQoreworICAgIFB5T2JqZWN0ICpyZXN1bHQgPSBOVUxMOworICAgIFB5T2JqZWN0ICpkaWN0ID0gTlVMTDsKKyAgICBQeU9iamVjdCAqaXRzY2xhc3MgPSBOVUxMOworCisgICAgLyogR2V0IF9fZGljdF9fICh3aGljaCBtYXkgb3IgbWF5IG5vdCBiZSBhIHJlYWwgZGljdC4uLikgKi8KKyAgICBkaWN0ID0gUHlPYmplY3RfR2V0QXR0clN0cmluZyhvYmosICJfX2RpY3RfXyIpOworICAgIGlmIChkaWN0ID09IE5VTEwpIHsKKyAgICAgICAgUHlFcnJfQ2xlYXIoKTsKKyAgICAgICAgZGljdCA9IFB5RGljdF9OZXcoKTsKKyAgICB9CisgICAgZWxzZSBpZiAoIVB5RGljdF9DaGVjayhkaWN0KSkgeworICAgICAgICBQeV9ERUNSRUYoZGljdCk7CisgICAgICAgIGRpY3QgPSBQeURpY3RfTmV3KCk7CisgICAgfQorICAgIGVsc2UgeworICAgICAgICAvKiBDb3B5IF9fZGljdF9fIHRvIGF2b2lkIG11dGF0aW5nIGl0LiAqLworICAgICAgICBQeU9iamVjdCAqdGVtcCA9IFB5RGljdF9Db3B5KGRpY3QpOworICAgICAgICBQeV9ERUNSRUYoZGljdCk7CisgICAgICAgIGRpY3QgPSB0ZW1wOworICAgIH0KKworICAgIGlmIChkaWN0ID09IE5VTEwpCisgICAgICAgIGdvdG8gZXJyb3I7CisKKyAgICAvKiBNZXJnZSBpbiBfX21lbWJlcnNfXyBhbmQgX19tZXRob2RzX18gKGlmIGFueSkuCisgICAgICogVGhpcyBpcyByZW1vdmVkIGluIFB5dGhvbiAzMDAwLiAqLworICAgIGlmIChtZXJnZV9saXN0X2F0dHIoZGljdCwgb2JqLCAiX19tZW1iZXJzX18iKSA8IDApCisgICAgICAgIGdvdG8gZXJyb3I7CisgICAgaWYgKG1lcmdlX2xpc3RfYXR0cihkaWN0LCBvYmosICJfX21ldGhvZHNfXyIpIDwgMCkKKyAgICAgICAgZ290byBlcnJvcjsKKworICAgIC8qIE1lcmdlIGluIGF0dHJzIHJlYWNoYWJsZSBmcm9tIGl0cyBjbGFzcy4gKi8KKyAgICBpdHNjbGFzcyA9IFB5T2JqZWN0X0dldEF0dHJTdHJpbmcob2JqLCAiX19jbGFzc19fIik7CisgICAgaWYgKGl0c2NsYXNzID09IE5VTEwpCisgICAgICAgIC8qIFhYWCh0b21lcik6IFBlcmhhcHMgZmFsbCBiYWNrIHRvIG9iai0+b2JfdHlwZSBpZiBubworICAgICAgICAgICAgICAgICAgICAgICBfX2NsYXNzX18gZXhpc3RzPyAqLworICAgICAgICBQeUVycl9DbGVhcigpOworICAgIGVsc2UgeworICAgICAgICBpZiAobWVyZ2VfY2xhc3NfZGljdChkaWN0LCBpdHNjbGFzcykgIT0gMCkKKyAgICAgICAgICAgIGdvdG8gZXJyb3I7CisgICAgfQorCisgICAgcmVzdWx0ID0gUHlEaWN0X0tleXMoZGljdCk7CisgICAgLyogZmFsbCB0aHJvdWdoICovCitlcnJvcjoKKyAgICBQeV9YREVDUkVGKGl0c2NsYXNzKTsKKyAgICBQeV9YREVDUkVGKGRpY3QpOworICAgIHJldHVybiByZXN1bHQ7Cit9CisKKy8qIEhlbHBlciBmb3IgUHlPYmplY3RfRGlyOiBvYmplY3QgaW50cm9zcGVjdGlvbi4KKyAgIFRoaXMgY2FsbHMgb25lIG9mIHRoZSBhYm92ZSBzcGVjaWFsaXplZCB2ZXJzaW9ucyBpZiBubyBfX2Rpcl9fIG1ldGhvZAorICAgZXhpc3RzLiAqLworc3RhdGljIFB5T2JqZWN0ICoKK19kaXJfb2JqZWN0KFB5T2JqZWN0ICpvYmopCit7CisgICAgUHlPYmplY3QgKnJlc3VsdCA9IE5VTEw7CisgICAgc3RhdGljIFB5T2JqZWN0ICpkaXJfc3RyID0gTlVMTDsKKyAgICBQeU9iamVjdCAqZGlyZnVuYzsKKworICAgIGFzc2VydChvYmopOworICAgIGlmIChQeUluc3RhbmNlX0NoZWNrKG9iaikpIHsKKyAgICAgICAgZGlyZnVuYyA9IFB5T2JqZWN0X0dldEF0dHJTdHJpbmcob2JqLCAiX19kaXJfXyIpOworICAgICAgICBpZiAoZGlyZnVuYyA9PSBOVUxMKSB7CisgICAgICAgICAgICBpZiAoUHlFcnJfRXhjZXB0aW9uTWF0Y2hlcyhQeUV4Y19BdHRyaWJ1dGVFcnJvcikpCisgICAgICAgICAgICAgICAgUHlFcnJfQ2xlYXIoKTsKKyAgICAgICAgICAgIGVsc2UKKyAgICAgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgfQorICAgIH0KKyAgICBlbHNlIHsKKyAgICAgICAgZGlyZnVuYyA9IF9QeU9iamVjdF9Mb29rdXBTcGVjaWFsKG9iaiwgIl9fZGlyX18iLCAmZGlyX3N0cik7CisgICAgICAgIGlmIChQeUVycl9PY2N1cnJlZCgpKQorICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIGlmIChkaXJmdW5jID09IE5VTEwpIHsKKyAgICAgICAgLyogdXNlIGRlZmF1bHQgaW1wbGVtZW50YXRpb24gKi8KKyAgICAgICAgaWYgKFB5TW9kdWxlX0NoZWNrKG9iaikpCisgICAgICAgICAgICByZXN1bHQgPSBfc3BlY2lhbGl6ZWRfZGlyX21vZHVsZShvYmopOworICAgICAgICBlbHNlIGlmIChQeVR5cGVfQ2hlY2sob2JqKSB8fCBQeUNsYXNzX0NoZWNrKG9iaikpCisgICAgICAgICAgICByZXN1bHQgPSBfc3BlY2lhbGl6ZWRfZGlyX3R5cGUob2JqKTsKKyAgICAgICAgZWxzZQorICAgICAgICAgICAgcmVzdWx0ID0gX2dlbmVyaWNfZGlyKG9iaik7CisgICAgfQorICAgIGVsc2UgeworICAgICAgICAvKiB1c2UgX19kaXJfXyAqLworICAgICAgICByZXN1bHQgPSBQeU9iamVjdF9DYWxsRnVuY3Rpb25PYmpBcmdzKGRpcmZ1bmMsIE5VTEwpOworICAgICAgICBQeV9ERUNSRUYoZGlyZnVuYyk7CisgICAgICAgIGlmIChyZXN1bHQgPT0gTlVMTCkKKyAgICAgICAgICAgIHJldHVybiBOVUxMOworCisgICAgICAgIC8qIHJlc3VsdCBtdXN0IGJlIGEgbGlzdCAqLworICAgICAgICAvKiBYWFgoZ2JyYW5kbCk6IGNvdWxkIGFsc28gY2hlY2sgaWYgYWxsIGl0ZW1zIGFyZSBzdHJpbmdzICovCisgICAgICAgIGlmICghUHlMaXN0X0NoZWNrKHJlc3VsdCkpIHsKKyAgICAgICAgICAgIFB5RXJyX0Zvcm1hdChQeUV4Y19UeXBlRXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgIl9fZGlyX18oKSBtdXN0IHJldHVybiBhIGxpc3QsIG5vdCAlLjIwMHMiLAorICAgICAgICAgICAgICAgICAgICAgICAgIFB5X1RZUEUocmVzdWx0KS0+dHBfbmFtZSk7CisgICAgICAgICAgICBQeV9ERUNSRUYocmVzdWx0KTsKKyAgICAgICAgICAgIHJlc3VsdCA9IE5VTEw7CisgICAgICAgIH0KKyAgICB9CisKKyAgICByZXR1cm4gcmVzdWx0OworfQorCisvKiBJbXBsZW1lbnRhdGlvbiBvZiBkaXIoKSAtLSBpZiBvYmogaXMgTlVMTCwgcmV0dXJucyB0aGUgbmFtZXMgaW4gdGhlIGN1cnJlbnQKKyAgIChsb2NhbCkgc2NvcGUuICBPdGhlcndpc2UsIHBlcmZvcm1zIGludHJvc3BlY3Rpb24gb2YgdGhlIG9iamVjdDogcmV0dXJucyBhCisgICBzb3J0ZWQgbGlzdCBvZiBhdHRyaWJ1dGUgbmFtZXMgKHN1cHBvc2VkbHkpIGFjY2Vzc2libGUgZnJvbSB0aGUgb2JqZWN0CisqLworUHlPYmplY3QgKgorUHlPYmplY3RfRGlyKFB5T2JqZWN0ICpvYmopCit7CisgICAgUHlPYmplY3QgKiByZXN1bHQ7CisKKyAgICBpZiAob2JqID09IE5VTEwpCisgICAgICAgIC8qIG5vIG9iamVjdCAtLSBpbnRyb3NwZWN0IHRoZSBsb2NhbHMgKi8KKyAgICAgICAgcmVzdWx0ID0gX2Rpcl9sb2NhbHMoKTsKKyAgICBlbHNlCisgICAgICAgIC8qIG9iamVjdCAtLSBpbnRyb3NwZWN0IHRoZSBvYmplY3QgKi8KKyAgICAgICAgcmVzdWx0ID0gX2Rpcl9vYmplY3Qob2JqKTsKKworICAgIGFzc2VydChyZXN1bHQgPT0gTlVMTCB8fCBQeUxpc3RfQ2hlY2socmVzdWx0KSk7CisKKyAgICBpZiAocmVzdWx0ICE9IE5VTEwgJiYgUHlMaXN0X1NvcnQocmVzdWx0KSAhPSAwKSB7CisgICAgICAgIC8qIHNvcnRpbmcgdGhlIGxpc3QgZmFpbGVkICovCisgICAgICAgIFB5X0RFQ1JFRihyZXN1bHQpOworICAgICAgICByZXN1bHQgPSBOVUxMOworICAgIH0KKworICAgIHJldHVybiByZXN1bHQ7Cit9CisKKy8qCitOb09iamVjdCBpcyB1c2FibGUgYXMgYSBub24tTlVMTCB1bmRlZmluZWQgdmFsdWUsIHVzZWQgYnkgdGhlIG1hY3JvIE5vbmUuCitUaGVyZSBpcyAoYW5kIHNob3VsZCBiZSEpIG5vIHdheSB0byBjcmVhdGUgb3RoZXIgb2JqZWN0cyBvZiB0aGlzIHR5cGUsCitzbyB0aGVyZSBpcyBleGFjdGx5IG9uZSAod2hpY2ggaXMgaW5kZXN0cnVjdGlibGUsIGJ5IHRoZSB3YXkpLgorKFhYWCBUaGlzIHR5cGUgYW5kIHRoZSB0eXBlIG9mIE5vdEltcGxlbWVudGVkIGJlbG93IHNob3VsZCBiZSB1bmlmaWVkLikKKyovCisKKy8qIEFSR1NVU0VEICovCitzdGF0aWMgUHlPYmplY3QgKgorbm9uZV9yZXByKFB5T2JqZWN0ICpvcCkKK3sKKyAgICByZXR1cm4gUHlTdHJpbmdfRnJvbVN0cmluZygiTm9uZSIpOworfQorCisvKiBBUkdVU0VEICovCitzdGF0aWMgdm9pZAorbm9uZV9kZWFsbG9jKFB5T2JqZWN0KiBpZ25vcmUpCit7CisgICAgLyogVGhpcyBzaG91bGQgbmV2ZXIgZ2V0IGNhbGxlZCwgYnV0IHdlIGFsc28gZG9uJ3Qgd2FudCB0byBTRUdWIGlmCisgICAgICogd2UgYWNjaWRlbnRhbGx5IGRlY3JlZiBOb25lIG91dCBvZiBleGlzdGVuY2UuCisgICAgICovCisgICAgUHlfRmF0YWxFcnJvcigiZGVhbGxvY2F0aW5nIE5vbmUiKTsKK30KKworCitzdGF0aWMgUHlUeXBlT2JqZWN0IFB5Tm9uZV9UeXBlID0geworICAgIFB5VmFyT2JqZWN0X0hFQURfSU5JVCgmUHlUeXBlX1R5cGUsIDApCisgICAgIk5vbmVUeXBlIiwKKyAgICAwLAorICAgIDAsCisgICAgbm9uZV9kZWFsbG9jLCAgICAgICAvKnRwX2RlYWxsb2MqLyAvKm5ldmVyIGNhbGxlZCovCisgICAgMCwgICAgICAgICAgICAgICAgICAvKnRwX3ByaW50Ki8KKyAgICAwLCAgICAgICAgICAgICAgICAgIC8qdHBfZ2V0YXR0ciovCisgICAgMCwgICAgICAgICAgICAgICAgICAvKnRwX3NldGF0dHIqLworICAgIDAsICAgICAgICAgICAgICAgICAgLyp0cF9jb21wYXJlKi8KKyAgICBub25lX3JlcHIsICAgICAgICAgIC8qdHBfcmVwciovCisgICAgMCwgICAgICAgICAgICAgICAgICAvKnRwX2FzX251bWJlciovCisgICAgMCwgICAgICAgICAgICAgICAgICAvKnRwX2FzX3NlcXVlbmNlKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgIC8qdHBfYXNfbWFwcGluZyovCisgICAgKGhhc2hmdW5jKV9QeV9IYXNoUG9pbnRlciwgLyp0cF9oYXNoICovCit9OworCitQeU9iamVjdCBfUHlfTm9uZVN0cnVjdCA9IHsKKyAgX1B5T2JqZWN0X0VYVFJBX0lOSVQKKyAgMSwgJlB5Tm9uZV9UeXBlCit9OworCisvKiBOb3RJbXBsZW1lbnRlZCBpcyBhbiBvYmplY3QgdGhhdCBjYW4gYmUgdXNlZCB0byBzaWduYWwgdGhhdCBhbgorICAgb3BlcmF0aW9uIGlzIG5vdCBpbXBsZW1lbnRlZCBmb3IgdGhlIGdpdmVuIHR5cGUgY29tYmluYXRpb24uICovCisKK3N0YXRpYyBQeU9iamVjdCAqCitOb3RJbXBsZW1lbnRlZF9yZXByKFB5T2JqZWN0ICpvcCkKK3sKKyAgICByZXR1cm4gUHlTdHJpbmdfRnJvbVN0cmluZygiTm90SW1wbGVtZW50ZWQiKTsKK30KKworc3RhdGljIFB5VHlwZU9iamVjdCBQeU5vdEltcGxlbWVudGVkX1R5cGUgPSB7CisgICAgUHlWYXJPYmplY3RfSEVBRF9JTklUKCZQeVR5cGVfVHlwZSwgMCkKKyAgICAiTm90SW1wbGVtZW50ZWRUeXBlIiwKKyAgICAwLAorICAgIDAsCisgICAgbm9uZV9kZWFsbG9jLCAgICAgICAvKnRwX2RlYWxsb2MqLyAvKm5ldmVyIGNhbGxlZCovCisgICAgMCwgICAgICAgICAgICAgICAgICAvKnRwX3ByaW50Ki8KKyAgICAwLCAgICAgICAgICAgICAgICAgIC8qdHBfZ2V0YXR0ciovCisgICAgMCwgICAgICAgICAgICAgICAgICAvKnRwX3NldGF0dHIqLworICAgIDAsICAgICAgICAgICAgICAgICAgLyp0cF9jb21wYXJlKi8KKyAgICBOb3RJbXBsZW1lbnRlZF9yZXByLCAvKnRwX3JlcHIqLworICAgIDAsICAgICAgICAgICAgICAgICAgLyp0cF9hc19udW1iZXIqLworICAgIDAsICAgICAgICAgICAgICAgICAgLyp0cF9hc19zZXF1ZW5jZSovCisgICAgMCwgICAgICAgICAgICAgICAgICAvKnRwX2FzX21hcHBpbmcqLworICAgIDAsICAgICAgICAgICAgICAgICAgLyp0cF9oYXNoICovCit9OworCitQeU9iamVjdCBfUHlfTm90SW1wbGVtZW50ZWRTdHJ1Y3QgPSB7CisgICAgX1B5T2JqZWN0X0VYVFJBX0lOSVQKKyAgICAxLCAmUHlOb3RJbXBsZW1lbnRlZF9UeXBlCit9OworCit2b2lkCitfUHlfUmVhZHlUeXBlcyh2b2lkKQoreworICAgIGlmIChQeVR5cGVfUmVhZHkoJlB5VHlwZV9UeXBlKSA8IDApCisgICAgICAgIFB5X0ZhdGFsRXJyb3IoIkNhbid0IGluaXRpYWxpemUgdHlwZSB0eXBlIik7CisKKyAgICBpZiAoUHlUeXBlX1JlYWR5KCZfUHlXZWFrcmVmX1JlZlR5cGUpIDwgMCkKKyAgICAgICAgUHlfRmF0YWxFcnJvcigiQ2FuJ3QgaW5pdGlhbGl6ZSB3ZWFrcmVmIHR5cGUiKTsKKworICAgIGlmIChQeVR5cGVfUmVhZHkoJl9QeVdlYWtyZWZfQ2FsbGFibGVQcm94eVR5cGUpIDwgMCkKKyAgICAgICAgUHlfRmF0YWxFcnJvcigiQ2FuJ3QgaW5pdGlhbGl6ZSBjYWxsYWJsZSB3ZWFrcmVmIHByb3h5IHR5cGUiKTsKKworICAgIGlmIChQeVR5cGVfUmVhZHkoJl9QeVdlYWtyZWZfUHJveHlUeXBlKSA8IDApCisgICAgICAgIFB5X0ZhdGFsRXJyb3IoIkNhbid0IGluaXRpYWxpemUgd2Vha3JlZiBwcm94eSB0eXBlIik7CisKKyAgICBpZiAoUHlUeXBlX1JlYWR5KCZQeUJvb2xfVHlwZSkgPCAwKQorICAgICAgICBQeV9GYXRhbEVycm9yKCJDYW4ndCBpbml0aWFsaXplIGJvb2wgdHlwZSIpOworCisgICAgaWYgKFB5VHlwZV9SZWFkeSgmUHlTdHJpbmdfVHlwZSkgPCAwKQorICAgICAgICBQeV9GYXRhbEVycm9yKCJDYW4ndCBpbml0aWFsaXplIHN0ciB0eXBlIik7CisKKyAgICBpZiAoUHlUeXBlX1JlYWR5KCZQeUJ5dGVBcnJheV9UeXBlKSA8IDApCisgICAgICAgIFB5X0ZhdGFsRXJyb3IoIkNhbid0IGluaXRpYWxpemUgYnl0ZWFycmF5IHR5cGUiKTsKKworICAgIGlmIChQeVR5cGVfUmVhZHkoJlB5TGlzdF9UeXBlKSA8IDApCisgICAgICAgIFB5X0ZhdGFsRXJyb3IoIkNhbid0IGluaXRpYWxpemUgbGlzdCB0eXBlIik7CisKKyAgICBpZiAoUHlUeXBlX1JlYWR5KCZQeU5vbmVfVHlwZSkgPCAwKQorICAgICAgICBQeV9GYXRhbEVycm9yKCJDYW4ndCBpbml0aWFsaXplIE5vbmUgdHlwZSIpOworCisgICAgaWYgKFB5VHlwZV9SZWFkeSgmUHlOb3RJbXBsZW1lbnRlZF9UeXBlKSA8IDApCisgICAgICAgIFB5X0ZhdGFsRXJyb3IoIkNhbid0IGluaXRpYWxpemUgTm90SW1wbGVtZW50ZWQgdHlwZSIpOworCisgICAgaWYgKFB5VHlwZV9SZWFkeSgmUHlUcmFjZUJhY2tfVHlwZSkgPCAwKQorICAgICAgICBQeV9GYXRhbEVycm9yKCJDYW4ndCBpbml0aWFsaXplIHRyYWNlYmFjayB0eXBlIik7CisKKyAgICBpZiAoUHlUeXBlX1JlYWR5KCZQeVN1cGVyX1R5cGUpIDwgMCkKKyAgICAgICAgUHlfRmF0YWxFcnJvcigiQ2FuJ3QgaW5pdGlhbGl6ZSBzdXBlciB0eXBlIik7CisKKyAgICBpZiAoUHlUeXBlX1JlYWR5KCZQeUJhc2VPYmplY3RfVHlwZSkgPCAwKQorICAgICAgICBQeV9GYXRhbEVycm9yKCJDYW4ndCBpbml0aWFsaXplIG9iamVjdCB0eXBlIik7CisKKyAgICBpZiAoUHlUeXBlX1JlYWR5KCZQeVJhbmdlX1R5cGUpIDwgMCkKKyAgICAgICAgUHlfRmF0YWxFcnJvcigiQ2FuJ3QgaW5pdGlhbGl6ZSB4cmFuZ2UgdHlwZSIpOworCisgICAgaWYgKFB5VHlwZV9SZWFkeSgmUHlEaWN0X1R5cGUpIDwgMCkKKyAgICAgICAgUHlfRmF0YWxFcnJvcigiQ2FuJ3QgaW5pdGlhbGl6ZSBkaWN0IHR5cGUiKTsKKworICAgIGlmIChQeVR5cGVfUmVhZHkoJlB5U2V0X1R5cGUpIDwgMCkKKyAgICAgICAgUHlfRmF0YWxFcnJvcigiQ2FuJ3QgaW5pdGlhbGl6ZSBzZXQgdHlwZSIpOworCisjaWZkZWYgUHlfVVNJTkdfVU5JQ09ERQorICAgIGlmIChQeVR5cGVfUmVhZHkoJlB5VW5pY29kZV9UeXBlKSA8IDApCisgICAgICAgIFB5X0ZhdGFsRXJyb3IoIkNhbid0IGluaXRpYWxpemUgdW5pY29kZSB0eXBlIik7CisjZW5kaWYKKworICAgIGlmIChQeVR5cGVfUmVhZHkoJlB5U2xpY2VfVHlwZSkgPCAwKQorICAgICAgICBQeV9GYXRhbEVycm9yKCJDYW4ndCBpbml0aWFsaXplIHNsaWNlIHR5cGUiKTsKKworICAgIGlmIChQeVR5cGVfUmVhZHkoJlB5U3RhdGljTWV0aG9kX1R5cGUpIDwgMCkKKyAgICAgICAgUHlfRmF0YWxFcnJvcigiQ2FuJ3QgaW5pdGlhbGl6ZSBzdGF0aWMgbWV0aG9kIHR5cGUiKTsKKworI2lmbmRlZiBXSVRIT1VUX0NPTVBMRVgKKyAgICBpZiAoUHlUeXBlX1JlYWR5KCZQeUNvbXBsZXhfVHlwZSkgPCAwKQorICAgICAgICBQeV9GYXRhbEVycm9yKCJDYW4ndCBpbml0aWFsaXplIGNvbXBsZXggdHlwZSIpOworI2VuZGlmCisKKyAgICBpZiAoUHlUeXBlX1JlYWR5KCZQeUZsb2F0X1R5cGUpIDwgMCkKKyAgICAgICAgUHlfRmF0YWxFcnJvcigiQ2FuJ3QgaW5pdGlhbGl6ZSBmbG9hdCB0eXBlIik7CisKKyAgICBpZiAoUHlUeXBlX1JlYWR5KCZQeUJ1ZmZlcl9UeXBlKSA8IDApCisgICAgICAgIFB5X0ZhdGFsRXJyb3IoIkNhbid0IGluaXRpYWxpemUgYnVmZmVyIHR5cGUiKTsKKworICAgIGlmIChQeVR5cGVfUmVhZHkoJlB5TG9uZ19UeXBlKSA8IDApCisgICAgICAgIFB5X0ZhdGFsRXJyb3IoIkNhbid0IGluaXRpYWxpemUgbG9uZyB0eXBlIik7CisKKyAgICBpZiAoUHlUeXBlX1JlYWR5KCZQeUludF9UeXBlKSA8IDApCisgICAgICAgIFB5X0ZhdGFsRXJyb3IoIkNhbid0IGluaXRpYWxpemUgaW50IHR5cGUiKTsKKworICAgIGlmIChQeVR5cGVfUmVhZHkoJlB5RnJvemVuU2V0X1R5cGUpIDwgMCkKKyAgICAgICAgUHlfRmF0YWxFcnJvcigiQ2FuJ3QgaW5pdGlhbGl6ZSBmcm96ZW5zZXQgdHlwZSIpOworCisgICAgaWYgKFB5VHlwZV9SZWFkeSgmUHlQcm9wZXJ0eV9UeXBlKSA8IDApCisgICAgICAgIFB5X0ZhdGFsRXJyb3IoIkNhbid0IGluaXRpYWxpemUgcHJvcGVydHkgdHlwZSIpOworCisgICAgaWYgKFB5VHlwZV9SZWFkeSgmUHlNZW1vcnlWaWV3X1R5cGUpIDwgMCkKKyAgICAgICAgUHlfRmF0YWxFcnJvcigiQ2FuJ3QgaW5pdGlhbGl6ZSBtZW1vcnl2aWV3IHR5cGUiKTsKKworICAgIGlmIChQeVR5cGVfUmVhZHkoJlB5VHVwbGVfVHlwZSkgPCAwKQorICAgICAgICBQeV9GYXRhbEVycm9yKCJDYW4ndCBpbml0aWFsaXplIHR1cGxlIHR5cGUiKTsKKworICAgIGlmIChQeVR5cGVfUmVhZHkoJlB5RW51bV9UeXBlKSA8IDApCisgICAgICAgIFB5X0ZhdGFsRXJyb3IoIkNhbid0IGluaXRpYWxpemUgZW51bWVyYXRlIHR5cGUiKTsKKworICAgIGlmIChQeVR5cGVfUmVhZHkoJlB5UmV2ZXJzZWRfVHlwZSkgPCAwKQorICAgICAgICBQeV9GYXRhbEVycm9yKCJDYW4ndCBpbml0aWFsaXplIHJldmVyc2VkIHR5cGUiKTsKKworICAgIGlmIChQeVR5cGVfUmVhZHkoJlB5Q29kZV9UeXBlKSA8IDApCisgICAgICAgIFB5X0ZhdGFsRXJyb3IoIkNhbid0IGluaXRpYWxpemUgY29kZSB0eXBlIik7CisKKyAgICBpZiAoUHlUeXBlX1JlYWR5KCZQeUZyYW1lX1R5cGUpIDwgMCkKKyAgICAgICAgUHlfRmF0YWxFcnJvcigiQ2FuJ3QgaW5pdGlhbGl6ZSBmcmFtZSB0eXBlIik7CisKKyAgICBpZiAoUHlUeXBlX1JlYWR5KCZQeUNGdW5jdGlvbl9UeXBlKSA8IDApCisgICAgICAgIFB5X0ZhdGFsRXJyb3IoIkNhbid0IGluaXRpYWxpemUgYnVpbHRpbiBmdW5jdGlvbiB0eXBlIik7CisKKyAgICBpZiAoUHlUeXBlX1JlYWR5KCZQeU1ldGhvZF9UeXBlKSA8IDApCisgICAgICAgIFB5X0ZhdGFsRXJyb3IoIkNhbid0IGluaXRpYWxpemUgbWV0aG9kIHR5cGUiKTsKKworICAgIGlmIChQeVR5cGVfUmVhZHkoJlB5RnVuY3Rpb25fVHlwZSkgPCAwKQorICAgICAgICBQeV9GYXRhbEVycm9yKCJDYW4ndCBpbml0aWFsaXplIGZ1bmN0aW9uIHR5cGUiKTsKKworICAgIGlmIChQeVR5cGVfUmVhZHkoJlB5Q2xhc3NfVHlwZSkgPCAwKQorICAgICAgICBQeV9GYXRhbEVycm9yKCJDYW4ndCBpbml0aWFsaXplIGNsYXNzIHR5cGUiKTsKKworICAgIGlmIChQeVR5cGVfUmVhZHkoJlB5RGljdFByb3h5X1R5cGUpIDwgMCkKKyAgICAgICAgUHlfRmF0YWxFcnJvcigiQ2FuJ3QgaW5pdGlhbGl6ZSBkaWN0IHByb3h5IHR5cGUiKTsKKworICAgIGlmIChQeVR5cGVfUmVhZHkoJlB5R2VuX1R5cGUpIDwgMCkKKyAgICAgICAgUHlfRmF0YWxFcnJvcigiQ2FuJ3QgaW5pdGlhbGl6ZSBnZW5lcmF0b3IgdHlwZSIpOworCisgICAgaWYgKFB5VHlwZV9SZWFkeSgmUHlHZXRTZXREZXNjcl9UeXBlKSA8IDApCisgICAgICAgIFB5X0ZhdGFsRXJyb3IoIkNhbid0IGluaXRpYWxpemUgZ2V0LXNldCBkZXNjcmlwdG9yIHR5cGUiKTsKKworICAgIGlmIChQeVR5cGVfUmVhZHkoJlB5V3JhcHBlckRlc2NyX1R5cGUpIDwgMCkKKyAgICAgICAgUHlfRmF0YWxFcnJvcigiQ2FuJ3QgaW5pdGlhbGl6ZSB3cmFwcGVyIHR5cGUiKTsKKworICAgIGlmIChQeVR5cGVfUmVhZHkoJlB5SW5zdGFuY2VfVHlwZSkgPCAwKQorICAgICAgICBQeV9GYXRhbEVycm9yKCJDYW4ndCBpbml0aWFsaXplIGluc3RhbmNlIHR5cGUiKTsKKworICAgIGlmIChQeVR5cGVfUmVhZHkoJlB5RWxsaXBzaXNfVHlwZSkgPCAwKQorICAgICAgICBQeV9GYXRhbEVycm9yKCJDYW4ndCBpbml0aWFsaXplIGVsbGlwc2lzIHR5cGUiKTsKKworICAgIGlmIChQeVR5cGVfUmVhZHkoJlB5TWVtYmVyRGVzY3JfVHlwZSkgPCAwKQorICAgICAgICBQeV9GYXRhbEVycm9yKCJDYW4ndCBpbml0aWFsaXplIG1lbWJlciBkZXNjcmlwdG9yIHR5cGUiKTsKKworICAgIGlmIChQeVR5cGVfUmVhZHkoJlB5RmlsZV9UeXBlKSA8IDApCisgICAgICAgIFB5X0ZhdGFsRXJyb3IoIkNhbid0IGluaXRpYWxpemUgZmlsZSB0eXBlIik7CisKKyAgICBpZiAoUHlUeXBlX1JlYWR5KCZQeUNhcHN1bGVfVHlwZSkgPCAwKQorICAgICAgICBQeV9GYXRhbEVycm9yKCJDYW4ndCBpbml0aWFsaXplIGNhcHN1bGUgdHlwZSIpOworCisgICAgaWYgKFB5VHlwZV9SZWFkeSgmUHlDZWxsX1R5cGUpIDwgMCkKKyAgICAgICAgUHlfRmF0YWxFcnJvcigiQ2FuJ3QgaW5pdGlhbGl6ZSBjZWxsIHR5cGUiKTsKKworICAgIGlmIChQeVR5cGVfUmVhZHkoJlB5Q2FsbEl0ZXJfVHlwZSkgPCAwKQorICAgICAgICBQeV9GYXRhbEVycm9yKCJDYW4ndCBpbml0aWFsaXplIGNhbGwgaXRlciB0eXBlIik7CisKKyAgICBpZiAoUHlUeXBlX1JlYWR5KCZQeVNlcUl0ZXJfVHlwZSkgPCAwKQorICAgICAgICBQeV9GYXRhbEVycm9yKCJDYW4ndCBpbml0aWFsaXplIHNlcXVlbmNlIGl0ZXJhdG9yIHR5cGUiKTsKK30KKworCisjaWZkZWYgUHlfVFJBQ0VfUkVGUworCit2b2lkCitfUHlfTmV3UmVmZXJlbmNlKFB5T2JqZWN0ICpvcCkKK3sKKyAgICBfUHlfSU5DX1JFRlRPVEFMOworICAgIG9wLT5vYl9yZWZjbnQgPSAxOworICAgIF9QeV9BZGRUb0FsbE9iamVjdHMob3AsIDEpOworICAgIF9QeV9JTkNfVFBBTExPQ1Mob3ApOworfQorCit2b2lkCitfUHlfRm9yZ2V0UmVmZXJlbmNlKHJlZ2lzdGVyIFB5T2JqZWN0ICpvcCkKK3sKKyNpZmRlZiBTTE9XX1VOUkVGX0NIRUNLCisgICAgcmVnaXN0ZXIgUHlPYmplY3QgKnA7CisjZW5kaWYKKyAgICBpZiAob3AtPm9iX3JlZmNudCA8IDApCisgICAgICAgIFB5X0ZhdGFsRXJyb3IoIlVOUkVGIG5lZ2F0aXZlIHJlZmNudCIpOworICAgIGlmIChvcCA9PSAmcmVmY2hhaW4gfHwKKyAgICAgICAgb3AtPl9vYl9wcmV2LT5fb2JfbmV4dCAhPSBvcCB8fCBvcC0+X29iX25leHQtPl9vYl9wcmV2ICE9IG9wKQorICAgICAgICBQeV9GYXRhbEVycm9yKCJVTlJFRiBpbnZhbGlkIG9iamVjdCIpOworI2lmZGVmIFNMT1dfVU5SRUZfQ0hFQ0sKKyAgICBmb3IgKHAgPSByZWZjaGFpbi5fb2JfbmV4dDsgcCAhPSAmcmVmY2hhaW47IHAgPSBwLT5fb2JfbmV4dCkgeworICAgICAgICBpZiAocCA9PSBvcCkKKyAgICAgICAgICAgIGJyZWFrOworICAgIH0KKyAgICBpZiAocCA9PSAmcmVmY2hhaW4pIC8qIE5vdCBmb3VuZCAqLworICAgICAgICBQeV9GYXRhbEVycm9yKCJVTlJFRiB1bmtub3duIG9iamVjdCIpOworI2VuZGlmCisgICAgb3AtPl9vYl9uZXh0LT5fb2JfcHJldiA9IG9wLT5fb2JfcHJldjsKKyAgICBvcC0+X29iX3ByZXYtPl9vYl9uZXh0ID0gb3AtPl9vYl9uZXh0OworICAgIG9wLT5fb2JfbmV4dCA9IG9wLT5fb2JfcHJldiA9IE5VTEw7CisgICAgX1B5X0lOQ19UUEZSRUVTKG9wKTsKK30KKwordm9pZAorX1B5X0RlYWxsb2MoUHlPYmplY3QgKm9wKQoreworICAgIGRlc3RydWN0b3IgZGVhbGxvYyA9IFB5X1RZUEUob3ApLT50cF9kZWFsbG9jOworICAgIF9QeV9Gb3JnZXRSZWZlcmVuY2Uob3ApOworICAgICgqZGVhbGxvYykob3ApOworfQorCisvKiBQcmludCBhbGwgbGl2ZSBvYmplY3RzLiAgQmVjYXVzZSBQeU9iamVjdF9QcmludCBpcyBjYWxsZWQsIHRoZQorICogaW50ZXJwcmV0ZXIgbXVzdCBiZSBpbiBhIGhlYWx0aHkgc3RhdGUuCisgKi8KK3ZvaWQKK19QeV9QcmludFJlZmVyZW5jZXMoRklMRSAqZnApCit7CisgICAgUHlPYmplY3QgKm9wOworICAgIGZwcmludGYoZnAsICJSZW1haW5pbmcgb2JqZWN0czpcbiIpOworICAgIGZvciAob3AgPSByZWZjaGFpbi5fb2JfbmV4dDsgb3AgIT0gJnJlZmNoYWluOyBvcCA9IG9wLT5fb2JfbmV4dCkgeworICAgICAgICBmcHJpbnRmKGZwLCAiJXAgWyUiIFBZX0ZPUk1BVF9TSVpFX1QgImRdICIsIG9wLCBvcC0+b2JfcmVmY250KTsKKyAgICAgICAgaWYgKFB5T2JqZWN0X1ByaW50KG9wLCBmcCwgMCkgIT0gMCkKKyAgICAgICAgICAgIFB5RXJyX0NsZWFyKCk7CisgICAgICAgIHB1dGMoJ1xuJywgZnApOworICAgIH0KK30KKworLyogUHJpbnQgdGhlIGFkZHJlc3NlcyBvZiBhbGwgbGl2ZSBvYmplY3RzLiAgVW5saWtlIF9QeV9QcmludFJlZmVyZW5jZXMsIHRoaXMKKyAqIGRvZXNuJ3QgbWFrZSBhbnkgY2FsbHMgdG8gdGhlIFB5dGhvbiBDIEFQSSwgc28gaXMgYWx3YXlzIHNhZmUgdG8gY2FsbC4KKyAqLwordm9pZAorX1B5X1ByaW50UmVmZXJlbmNlQWRkcmVzc2VzKEZJTEUgKmZwKQoreworICAgIFB5T2JqZWN0ICpvcDsKKyAgICBmcHJpbnRmKGZwLCAiUmVtYWluaW5nIG9iamVjdCBhZGRyZXNzZXM6XG4iKTsKKyAgICBmb3IgKG9wID0gcmVmY2hhaW4uX29iX25leHQ7IG9wICE9ICZyZWZjaGFpbjsgb3AgPSBvcC0+X29iX25leHQpCisgICAgICAgIGZwcmludGYoZnAsICIlcCBbJSIgUFlfRk9STUFUX1NJWkVfVCAiZF0gJXNcbiIsIG9wLAorICAgICAgICAgICAgb3AtPm9iX3JlZmNudCwgUHlfVFlQRShvcCktPnRwX25hbWUpOworfQorCitQeU9iamVjdCAqCitfUHlfR2V0T2JqZWN0cyhQeU9iamVjdCAqc2VsZiwgUHlPYmplY3QgKmFyZ3MpCit7CisgICAgaW50IGksIG47CisgICAgUHlPYmplY3QgKnQgPSBOVUxMOworICAgIFB5T2JqZWN0ICpyZXMsICpvcDsKKworICAgIGlmICghUHlBcmdfUGFyc2VUdXBsZShhcmdzLCAiaXxPIiwgJm4sICZ0KSkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgb3AgPSByZWZjaGFpbi5fb2JfbmV4dDsKKyAgICByZXMgPSBQeUxpc3RfTmV3KDApOworICAgIGlmIChyZXMgPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgZm9yIChpID0gMDsgKG4gPT0gMCB8fCBpIDwgbikgJiYgb3AgIT0gJnJlZmNoYWluOyBpKyspIHsKKyAgICAgICAgd2hpbGUgKG9wID09IHNlbGYgfHwgb3AgPT0gYXJncyB8fCBvcCA9PSByZXMgfHwgb3AgPT0gdCB8fAorICAgICAgICAgICAgICAgKHQgIT0gTlVMTCAmJiBQeV9UWVBFKG9wKSAhPSAoUHlUeXBlT2JqZWN0ICopIHQpKSB7CisgICAgICAgICAgICBvcCA9IG9wLT5fb2JfbmV4dDsKKyAgICAgICAgICAgIGlmIChvcCA9PSAmcmVmY2hhaW4pCisgICAgICAgICAgICAgICAgcmV0dXJuIHJlczsKKyAgICAgICAgfQorICAgICAgICBpZiAoUHlMaXN0X0FwcGVuZChyZXMsIG9wKSA8IDApIHsKKyAgICAgICAgICAgIFB5X0RFQ1JFRihyZXMpOworICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgICAgIH0KKyAgICAgICAgb3AgPSBvcC0+X29iX25leHQ7CisgICAgfQorICAgIHJldHVybiByZXM7Cit9CisKKyNlbmRpZgorCisKKy8qIEhhY2sgdG8gZm9yY2UgbG9hZGluZyBvZiBjYXBzdWxlLm8gKi8KK1B5VHlwZU9iamVjdCAqX1B5X2NhcHN1bGVfaGFjayA9ICZQeUNhcHN1bGVfVHlwZTsKKworCisvKiBIYWNrIHRvIGZvcmNlIGxvYWRpbmcgb2YgY29iamVjdC5vICovCitQeVR5cGVPYmplY3QgKl9QeV9jb2JqZWN0X2hhY2sgPSAmUHlDT2JqZWN0X1R5cGU7CisKKworLyogSGFjayB0byBmb3JjZSBsb2FkaW5nIG9mIGFic3RyYWN0Lm8gKi8KK1B5X3NzaXplX3QgKCpfUHlfYWJzdHJhY3RfaGFjaykoUHlPYmplY3QgKikgPSBQeU9iamVjdF9TaXplOworCisKKy8qIFB5dGhvbidzIG1hbGxvYyB3cmFwcGVycyAoc2VlIHB5bWVtLmgpICovCisKK3ZvaWQgKgorUHlNZW1fTWFsbG9jKHNpemVfdCBuYnl0ZXMpCit7CisgICAgcmV0dXJuIFB5TWVtX01BTExPQyhuYnl0ZXMpOworfQorCit2b2lkICoKK1B5TWVtX1JlYWxsb2Modm9pZCAqcCwgc2l6ZV90IG5ieXRlcykKK3sKKyAgICByZXR1cm4gUHlNZW1fUkVBTExPQyhwLCBuYnl0ZXMpOworfQorCit2b2lkCitQeU1lbV9GcmVlKHZvaWQgKnApCit7CisgICAgUHlNZW1fRlJFRShwKTsKK30KKworCisvKiBUaGVzZSBtZXRob2RzIGFyZSB1c2VkIHRvIGNvbnRyb2wgaW5maW5pdGUgcmVjdXJzaW9uIGluIHJlcHIsIHN0ciwgcHJpbnQsCisgICBldGMuICBDb250YWluZXIgb2JqZWN0cyB0aGF0IG1heSByZWN1cnNpdmVseSBjb250YWluIHRoZW1zZWx2ZXMsCisgICBlLmcuIGJ1aWx0aW4gZGljdGlvbmFyaWVzIGFuZCBsaXN0cywgc2hvdWxkIHVzZWQgUHlfUmVwckVudGVyKCkgYW5kCisgICBQeV9SZXByTGVhdmUoKSB0byBhdm9pZCBpbmZpbml0ZSByZWN1cnNpb24uCisKKyAgIFB5X1JlcHJFbnRlcigpIHJldHVybnMgMCB0aGUgZmlyc3QgdGltZSBpdCBpcyBjYWxsZWQgZm9yIGEgcGFydGljdWxhcgorICAgb2JqZWN0IGFuZCAxIGV2ZXJ5IHRpbWUgdGhlcmVhZnRlci4gIEl0IHJldHVybnMgLTEgaWYgYW4gZXhjZXB0aW9uCisgICBvY2N1cnJlZC4gIFB5X1JlcHJMZWF2ZSgpIGhhcyBubyByZXR1cm4gdmFsdWUuCisKKyAgIFNlZSBkaWN0b2JqZWN0LmMgYW5kIGxpc3RvYmplY3QuYyBmb3IgZXhhbXBsZXMgb2YgdXNlLgorKi8KKworI2RlZmluZSBLRVkgIlB5X1JlcHIiCisKK2ludAorUHlfUmVwckVudGVyKFB5T2JqZWN0ICpvYmopCit7CisgICAgUHlPYmplY3QgKmRpY3Q7CisgICAgUHlPYmplY3QgKmxpc3Q7CisgICAgUHlfc3NpemVfdCBpOworCisgICAgZGljdCA9IFB5VGhyZWFkU3RhdGVfR2V0RGljdCgpOworICAgIGlmIChkaWN0ID09IE5VTEwpCisgICAgICAgIHJldHVybiAwOworICAgIGxpc3QgPSBQeURpY3RfR2V0SXRlbVN0cmluZyhkaWN0LCBLRVkpOworICAgIGlmIChsaXN0ID09IE5VTEwpIHsKKyAgICAgICAgbGlzdCA9IFB5TGlzdF9OZXcoMCk7CisgICAgICAgIGlmIChsaXN0ID09IE5VTEwpCisgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgIGlmIChQeURpY3RfU2V0SXRlbVN0cmluZyhkaWN0LCBLRVksIGxpc3QpIDwgMCkKKyAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgUHlfREVDUkVGKGxpc3QpOworICAgIH0KKyAgICBpID0gUHlMaXN0X0dFVF9TSVpFKGxpc3QpOworICAgIHdoaWxlICgtLWkgPj0gMCkgeworICAgICAgICBpZiAoUHlMaXN0X0dFVF9JVEVNKGxpc3QsIGkpID09IG9iaikKKyAgICAgICAgICAgIHJldHVybiAxOworICAgIH0KKyAgICBQeUxpc3RfQXBwZW5kKGxpc3QsIG9iaik7CisgICAgcmV0dXJuIDA7Cit9CisKK3ZvaWQKK1B5X1JlcHJMZWF2ZShQeU9iamVjdCAqb2JqKQoreworICAgIFB5T2JqZWN0ICpkaWN0OworICAgIFB5T2JqZWN0ICpsaXN0OworICAgIFB5X3NzaXplX3QgaTsKKworICAgIGRpY3QgPSBQeVRocmVhZFN0YXRlX0dldERpY3QoKTsKKyAgICBpZiAoZGljdCA9PSBOVUxMKQorICAgICAgICByZXR1cm47CisgICAgbGlzdCA9IFB5RGljdF9HZXRJdGVtU3RyaW5nKGRpY3QsIEtFWSk7CisgICAgaWYgKGxpc3QgPT0gTlVMTCB8fCAhUHlMaXN0X0NoZWNrKGxpc3QpKQorICAgICAgICByZXR1cm47CisgICAgaSA9IFB5TGlzdF9HRVRfU0laRShsaXN0KTsKKyAgICAvKiBDb3VudCBiYWNrd2FyZHMgYmVjYXVzZSB3ZSBhbHdheXMgZXhwZWN0IG9iaiB0byBiZSBsaXN0Wy0xXSAqLworICAgIHdoaWxlICgtLWkgPj0gMCkgeworICAgICAgICBpZiAoUHlMaXN0X0dFVF9JVEVNKGxpc3QsIGkpID09IG9iaikgeworICAgICAgICAgICAgUHlMaXN0X1NldFNsaWNlKGxpc3QsIGksIGkgKyAxLCBOVUxMKTsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisgICAgfQorfQorCisvKiBUcmFzaGNhbiBzdXBwb3J0LiAqLworCisvKiBDdXJyZW50IGNhbGwtc3RhY2sgZGVwdGggb2YgdHBfZGVhbGxvYyBjYWxscy4gKi8KK2ludCBfUHlUcmFzaF9kZWxldGVfbmVzdGluZyA9IDA7CisKKy8qIExpc3Qgb2Ygb2JqZWN0cyB0aGF0IHN0aWxsIG5lZWQgdG8gYmUgY2xlYW5lZCB1cCwgc2luZ2x5IGxpbmtlZCB2aWEgdGhlaXIKKyAqIGdjIGhlYWRlcnMnIGdjX3ByZXYgcG9pbnRlcnMuCisgKi8KK1B5T2JqZWN0ICpfUHlUcmFzaF9kZWxldGVfbGF0ZXIgPSBOVUxMOworCisvKiBBZGQgb3AgdG8gdGhlIF9QeVRyYXNoX2RlbGV0ZV9sYXRlciBsaXN0LiAgQ2FsbGVkIHdoZW4gdGhlIGN1cnJlbnQKKyAqIGNhbGwtc3RhY2sgZGVwdGggZ2V0cyBsYXJnZS4gIG9wIG11c3QgYmUgYSBjdXJyZW50bHkgdW50cmFja2VkIGdjJ2VkCisgKiBvYmplY3QsIHdpdGggcmVmY291bnQgMC4gIFB5X0RFQ1JFRiBtdXN0IGFscmVhZHkgaGF2ZSBiZWVuIGNhbGxlZCBvbiBpdC4KKyAqLwordm9pZAorX1B5VHJhc2hfZGVwb3NpdF9vYmplY3QoUHlPYmplY3QgKm9wKQoreworICAgIGFzc2VydChQeU9iamVjdF9JU19HQyhvcCkpOworICAgIGFzc2VydChfUHlfQVNfR0Mob3ApLT5nYy5nY19yZWZzID09IF9QeUdDX1JFRlNfVU5UUkFDS0VEKTsKKyAgICBhc3NlcnQob3AtPm9iX3JlZmNudCA9PSAwKTsKKyAgICBfUHlfQVNfR0Mob3ApLT5nYy5nY19wcmV2ID0gKFB5R0NfSGVhZCAqKV9QeVRyYXNoX2RlbGV0ZV9sYXRlcjsKKyAgICBfUHlUcmFzaF9kZWxldGVfbGF0ZXIgPSBvcDsKK30KKworLyogVGhlIGVxdWl2YWxlbnQgQVBJLCB1c2luZyBwZXItdGhyZWFkIHN0YXRlIHJlY3Vyc2lvbiBpbmZvICovCit2b2lkCitfUHlUcmFzaF90aHJlYWRfZGVwb3NpdF9vYmplY3QoUHlPYmplY3QgKm9wKQoreworICAgIFB5VGhyZWFkU3RhdGUgKnRzdGF0ZSA9IFB5VGhyZWFkU3RhdGVfR0VUKCk7CisgICAgYXNzZXJ0KFB5T2JqZWN0X0lTX0dDKG9wKSk7CisgICAgYXNzZXJ0KF9QeV9BU19HQyhvcCktPmdjLmdjX3JlZnMgPT0gX1B5R0NfUkVGU19VTlRSQUNLRUQpOworICAgIGFzc2VydChvcC0+b2JfcmVmY250ID09IDApOworICAgIF9QeV9BU19HQyhvcCktPmdjLmdjX3ByZXYgPSAoUHlHQ19IZWFkICopIHRzdGF0ZS0+dHJhc2hfZGVsZXRlX2xhdGVyOworICAgIHRzdGF0ZS0+dHJhc2hfZGVsZXRlX2xhdGVyID0gb3A7Cit9CisKKy8qIERlYWxsb2NjYXRlIGFsbCB0aGUgb2JqZWN0cyBpbiB0aGUgX1B5VHJhc2hfZGVsZXRlX2xhdGVyIGxpc3QuICBDYWxsZWQgd2hlbgorICogdGhlIGNhbGwtc3RhY2sgdW53aW5kcyBhZ2Fpbi4KKyAqLwordm9pZAorX1B5VHJhc2hfZGVzdHJveV9jaGFpbih2b2lkKQoreworICAgIHdoaWxlIChfUHlUcmFzaF9kZWxldGVfbGF0ZXIpIHsKKyAgICAgICAgUHlPYmplY3QgKm9wID0gX1B5VHJhc2hfZGVsZXRlX2xhdGVyOworICAgICAgICBkZXN0cnVjdG9yIGRlYWxsb2MgPSBQeV9UWVBFKG9wKS0+dHBfZGVhbGxvYzsKKworICAgICAgICBfUHlUcmFzaF9kZWxldGVfbGF0ZXIgPQorICAgICAgICAgICAgKFB5T2JqZWN0KikgX1B5X0FTX0dDKG9wKS0+Z2MuZ2NfcHJldjsKKworICAgICAgICAvKiBDYWxsIHRoZSBkZWFsbG9jYXRvciBkaXJlY3RseS4gIFRoaXMgdXNlZCB0byB0cnkgdG8KKyAgICAgICAgICogZm9vbCBQeV9ERUNSRUYgaW50byBjYWxsaW5nIGl0IGluZGlyZWN0bHksIGJ1dAorICAgICAgICAgKiBQeV9ERUNSRUYgd2FzIGFscmVhZHkgY2FsbGVkIG9uIHRoaXMgb2JqZWN0LCBhbmQgaW4KKyAgICAgICAgICogYXNzb3J0ZWQgbm9uLXJlbGVhc2UgYnVpbGRzIGNhbGxpbmcgUHlfREVDUkVGIGFnYWluIGVuZHMKKyAgICAgICAgICogdXAgZGlzdG9ydGluZyBhbGxvY2F0aW9uIHN0YXRpc3RpY3MuCisgICAgICAgICAqLworICAgICAgICBhc3NlcnQob3AtPm9iX3JlZmNudCA9PSAwKTsKKyAgICAgICAgKytfUHlUcmFzaF9kZWxldGVfbmVzdGluZzsKKyAgICAgICAgKCpkZWFsbG9jKShvcCk7CisgICAgICAgIC0tX1B5VHJhc2hfZGVsZXRlX25lc3Rpbmc7CisgICAgfQorfQorCisvKiBUaGUgZXF1aXZhbGVudCBBUEksIHVzaW5nIHBlci10aHJlYWQgc3RhdGUgcmVjdXJzaW9uIGluZm8gKi8KK3ZvaWQKK19QeVRyYXNoX3RocmVhZF9kZXN0cm95X2NoYWluKHZvaWQpCit7CisgICAgUHlUaHJlYWRTdGF0ZSAqdHN0YXRlID0gUHlUaHJlYWRTdGF0ZV9HRVQoKTsKKyAgICB3aGlsZSAodHN0YXRlLT50cmFzaF9kZWxldGVfbGF0ZXIpIHsKKyAgICAgICAgUHlPYmplY3QgKm9wID0gdHN0YXRlLT50cmFzaF9kZWxldGVfbGF0ZXI7CisgICAgICAgIGRlc3RydWN0b3IgZGVhbGxvYyA9IFB5X1RZUEUob3ApLT50cF9kZWFsbG9jOworCisgICAgICAgIHRzdGF0ZS0+dHJhc2hfZGVsZXRlX2xhdGVyID0KKyAgICAgICAgICAgIChQeU9iamVjdCopIF9QeV9BU19HQyhvcCktPmdjLmdjX3ByZXY7CisKKyAgICAgICAgLyogQ2FsbCB0aGUgZGVhbGxvY2F0b3IgZGlyZWN0bHkuICBUaGlzIHVzZWQgdG8gdHJ5IHRvCisgICAgICAgICAqIGZvb2wgUHlfREVDUkVGIGludG8gY2FsbGluZyBpdCBpbmRpcmVjdGx5LCBidXQKKyAgICAgICAgICogUHlfREVDUkVGIHdhcyBhbHJlYWR5IGNhbGxlZCBvbiB0aGlzIG9iamVjdCwgYW5kIGluCisgICAgICAgICAqIGFzc29ydGVkIG5vbi1yZWxlYXNlIGJ1aWxkcyBjYWxsaW5nIFB5X0RFQ1JFRiBhZ2FpbiBlbmRzCisgICAgICAgICAqIHVwIGRpc3RvcnRpbmcgYWxsb2NhdGlvbiBzdGF0aXN0aWNzLgorICAgICAgICAgKi8KKyAgICAgICAgYXNzZXJ0KG9wLT5vYl9yZWZjbnQgPT0gMCk7CisgICAgICAgICsrdHN0YXRlLT50cmFzaF9kZWxldGVfbmVzdGluZzsKKyAgICAgICAgKCpkZWFsbG9jKShvcCk7CisgICAgICAgIC0tdHN0YXRlLT50cmFzaF9kZWxldGVfbmVzdGluZzsKKyAgICB9Cit9CisKKyNpZmRlZiBfX2NwbHVzcGx1cworfQorI2VuZGlmCmRpZmYgLS1naXQgYS9QeXRob24tMi43LjUvT2JqZWN0cy9vYm1hbGxvYy5jIGIvUHl0aG9uLTIuNy41L09iamVjdHMvb2JtYWxsb2MuYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4zOGViYzM3Ci0tLSAvZGV2L251bGwKKysrIGIvUHl0aG9uLTIuNy41L09iamVjdHMvb2JtYWxsb2MuYwpAQCAtMCwwICsxLDE4ODggQEAKKyNpbmNsdWRlICJQeXRob24uaCIKKworI2lmZGVmIFdJVEhfUFlNQUxMT0MKKworI2lmZGVmIFdJVEhfVkFMR1JJTkQKKyNpbmNsdWRlIDx2YWxncmluZC92YWxncmluZC5oPgorCisvKiBJZiB3ZSdyZSB1c2luZyBHQ0MsIHVzZSBfX2J1aWx0aW5fZXhwZWN0KCkgdG8gcmVkdWNlIG92ZXJoZWFkIG9mCisgICB0aGUgdmFsZ3JpbmQgY2hlY2tzICovCisjaWYgZGVmaW5lZChfX0dOVUNfXykgJiYgKF9fR05VQ19fID4gMikgJiYgZGVmaW5lZChfX09QVElNSVpFX18pCisjICBkZWZpbmUgVU5MSUtFTFkodmFsdWUpIF9fYnVpbHRpbl9leHBlY3QoKHZhbHVlKSwgMCkKKyNlbHNlCisjICBkZWZpbmUgVU5MSUtFTFkodmFsdWUpICh2YWx1ZSkKKyNlbmRpZgorCisvKiAtMSBpbmRpY2F0ZXMgdGhhdCB3ZSBoYXZlbid0IGNoZWNrZWQgdGhhdCB3ZSdyZSBydW5uaW5nIG9uIHZhbGdyaW5kIHlldC4gKi8KK3N0YXRpYyBpbnQgcnVubmluZ19vbl92YWxncmluZCA9IC0xOworI2VuZGlmCisKKy8qIEFuIG9iamVjdCBhbGxvY2F0b3IgZm9yIFB5dGhvbi4KKworICAgSGVyZSBpcyBhbiBpbnRyb2R1Y3Rpb24gdG8gdGhlIGxheWVycyBvZiB0aGUgUHl0aG9uIG1lbW9yeSBhcmNoaXRlY3R1cmUsCisgICBzaG93aW5nIHdoZXJlIHRoZSBvYmplY3QgYWxsb2NhdG9yIGlzIGFjdHVhbGx5IHVzZWQgKGxheWVyICsyKSwgSXQgaXMKKyAgIGNhbGxlZCBmb3IgZXZlcnkgb2JqZWN0IGFsbG9jYXRpb24gYW5kIGRlYWxsb2NhdGlvbiAoUHlPYmplY3RfTmV3L0RlbCksCisgICB1bmxlc3MgdGhlIG9iamVjdC1zcGVjaWZpYyBhbGxvY2F0b3JzIGltcGxlbWVudCBhIHByb3ByaWV0YXJ5IGFsbG9jYXRpb24KKyAgIHNjaGVtZSAoZXguOiBpbnRzIHVzZSBhIHNpbXBsZSBmcmVlIGxpc3QpLiBUaGlzIGlzIGFsc28gdGhlIHBsYWNlIHdoZXJlCisgICB0aGUgY3ljbGljIGdhcmJhZ2UgY29sbGVjdG9yIG9wZXJhdGVzIHNlbGVjdGl2ZWx5IG9uIGNvbnRhaW5lciBvYmplY3RzLgorCisKKyAgICBPYmplY3Qtc3BlY2lmaWMgYWxsb2NhdG9ycworICAgIF9fX19fICAgX19fX19fICAgX19fX19fICAgICAgIF9fX19fX19fCisgICBbIGludCBdIFsgZGljdCBdIFsgbGlzdCBdIC4uLiBbIHN0cmluZyBdICAgICAgIFB5dGhvbiBjb3JlICAgICAgICAgfAorKzMgfCA8LS0tLS0gT2JqZWN0LXNwZWNpZmljIG1lbW9yeSAtLS0tLT4gfCA8LS0gTm9uLW9iamVjdCBtZW1vcnkgLS0+IHwKKyAgICBfX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fICAgICAgIHwgICAgICAgICAgICAgICAgICAgICAgICAgICB8CisgICBbICAgUHl0aG9uJ3Mgb2JqZWN0IGFsbG9jYXRvciAgIF0gICAgICB8ICAgICAgICAgICAgICAgICAgICAgICAgICAgfAorKzIgfCAjIyMjIyMjIE9iamVjdCBtZW1vcnkgIyMjIyMjIyB8IDwtLS0tLS0gSW50ZXJuYWwgYnVmZmVycyAtLS0tLS0+IHwKKyAgICBfX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fXyAgICB8CisgICBbICAgICAgICAgIFB5dGhvbidzIHJhdyBtZW1vcnkgYWxsb2NhdG9yIChQeU1lbV8gQVBJKSAgICAgICAgICBdICAgfAorKzEgfCA8LS0tLS0gUHl0aG9uIG1lbW9yeSAodW5kZXIgUHlNZW0gbWFuYWdlcidzIGNvbnRyb2wpIC0tLS0tLT4gfCAgIHwKKyAgICBfX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX18KKyAgIFsgICAgVW5kZXJseWluZyBnZW5lcmFsLXB1cnBvc2UgYWxsb2NhdG9yIChleDogQyBsaWJyYXJ5IG1hbGxvYykgICBdCisgMCB8IDwtLS0tLS0gVmlydHVhbCBtZW1vcnkgYWxsb2NhdGVkIGZvciB0aGUgcHl0aG9uIHByb2Nlc3MgLS0tLS0tLT4gfAorCisgICA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CisgICAgX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX18KKyAgIFsgICAgICAgICAgICAgICAgT1Mtc3BlY2lmaWMgVmlydHVhbCBNZW1vcnkgTWFuYWdlciAoVk1NKSAgICAgICAgICAgICAgIF0KKy0xIHwgPC0tLSBLZXJuZWwgZHluYW1pYyBzdG9yYWdlIGFsbG9jYXRpb24gJiBtYW5hZ2VtZW50IChwYWdlLWJhc2VkKSAtLS0+IHwKKyAgICBfX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fICAgX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fXworICAgWyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBdIFsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXQorLTIgfCA8LS0gUGh5c2ljYWwgbWVtb3J5OiBST00vUkFNIC0tPiB8IHwgPC0tIFNlY29uZGFyeSBzdG9yYWdlIChzd2FwKSAtLT4gfAorCisqLworLyo9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSovCisKKy8qIEEgZmFzdCwgc3BlY2lhbC1wdXJwb3NlIG1lbW9yeSBhbGxvY2F0b3IgZm9yIHNtYWxsIGJsb2NrcywgdG8gYmUgdXNlZAorICAgb24gdG9wIG9mIGEgZ2VuZXJhbC1wdXJwb3NlIG1hbGxvYyAtLSBoZWF2aWx5IGJhc2VkIG9uIHByZXZpb3VzIGFydC4gKi8KKworLyogVmxhZGltaXIgTWFyYW5nb3pvdiAtLSBBdWd1c3QgMjAwMCAqLworCisvKgorICogIk1lbW9yeSBtYW5hZ2VtZW50IGlzIHdoZXJlIHRoZSBydWJiZXIgbWVldHMgdGhlIHJvYWQgLS0gaWYgd2UgZG8gdGhlIHdyb25nCisgKiB0aGluZyBhdCBhbnkgbGV2ZWwsIHRoZSByZXN1bHRzIHdpbGwgbm90IGJlIGdvb2QuIEFuZCBpZiB3ZSBkb24ndCBtYWtlIHRoZQorICogbGV2ZWxzIHdvcmsgd2VsbCB0b2dldGhlciwgd2UgYXJlIGluIHNlcmlvdXMgdHJvdWJsZS4iICgxKQorICoKKyAqICgxKSBQYXVsIFIuIFdpbHNvbiwgTWFyayBTLiBKb2huc3RvbmUsIE1pY2hhZWwgTmVlbHksIGFuZCBEYXZpZCBCb2xlcywKKyAqICAgICJEeW5hbWljIFN0b3JhZ2UgQWxsb2NhdGlvbjogQSBTdXJ2ZXkgYW5kIENyaXRpY2FsIFJldmlldyIsCisgKiAgICBpbiBQcm9jLiAxOTk1IEludCdsLiBXb3Jrc2hvcCBvbiBNZW1vcnkgTWFuYWdlbWVudCwgU2VwdGVtYmVyIDE5OTUuCisgKi8KKworLyogI3VuZGVmIFdJVEhfTUVNT1JZX0xJTUlUUyAqLyAgICAgICAgIC8qIGRpc2FibGUgbWVtIGxpbWl0IGNoZWNrcyAgKi8KKworLyo9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSovCisKKy8qCisgKiBBbGxvY2F0aW9uIHN0cmF0ZWd5IGFic3RyYWN0OgorICoKKyAqIEZvciBzbWFsbCByZXF1ZXN0cywgdGhlIGFsbG9jYXRvciBzdWItYWxsb2NhdGVzIDxCaWc+IGJsb2NrcyBvZiBtZW1vcnkuCisgKiBSZXF1ZXN0cyBncmVhdGVyIHRoYW4gMjU2IGJ5dGVzIGFyZSByb3V0ZWQgdG8gdGhlIHN5c3RlbSdzIGFsbG9jYXRvci4KKyAqCisgKiBTbWFsbCByZXF1ZXN0cyBhcmUgZ3JvdXBlZCBpbiBzaXplIGNsYXNzZXMgc3BhY2VkIDggYnl0ZXMgYXBhcnQsIGR1ZQorICogdG8gdGhlIHJlcXVpcmVkIHZhbGlkIGFsaWdubWVudCBvZiB0aGUgcmV0dXJuZWQgYWRkcmVzcy4gUmVxdWVzdHMgb2YKKyAqIGEgcGFydGljdWxhciBzaXplIGFyZSBzZXJ2aWNlZCBmcm9tIG1lbW9yeSBwb29scyBvZiA0SyAob25lIFZNTSBwYWdlKS4KKyAqIFBvb2xzIGFyZSBmcmFnbWVudGVkIG9uIGRlbWFuZCBhbmQgY29udGFpbiBmcmVlIGxpc3RzIG9mIGJsb2NrcyBvZiBvbmUKKyAqIHBhcnRpY3VsYXIgc2l6ZSBjbGFzcy4gSW4gb3RoZXIgd29yZHMsIHRoZXJlIGlzIGEgZml4ZWQtc2l6ZSBhbGxvY2F0b3IKKyAqIGZvciBlYWNoIHNpemUgY2xhc3MuIEZyZWUgcG9vbHMgYXJlIHNoYXJlZCBieSB0aGUgZGlmZmVyZW50IGFsbG9jYXRvcnMKKyAqIHRodXMgbWluaW1pemluZyB0aGUgc3BhY2UgcmVzZXJ2ZWQgZm9yIGEgcGFydGljdWxhciBzaXplIGNsYXNzLgorICoKKyAqIFRoaXMgYWxsb2NhdGlvbiBzdHJhdGVneSBpcyBhIHZhcmlhbnQgb2Ygd2hhdCBpcyBrbm93biBhcyAic2ltcGxlCisgKiBzZWdyZWdhdGVkIHN0b3JhZ2UgYmFzZWQgb24gYXJyYXkgb2YgZnJlZSBsaXN0cyIuIFRoZSBtYWluIGRyYXdiYWNrIG9mCisgKiBzaW1wbGUgc2VncmVnYXRlZCBzdG9yYWdlIGlzIHRoYXQgd2UgbWlnaHQgZW5kIHVwIHdpdGggbG90IG9mIHJlc2VydmVkCisgKiBtZW1vcnkgZm9yIHRoZSBkaWZmZXJlbnQgZnJlZSBsaXN0cywgd2hpY2ggZGVnZW5lcmF0ZSBpbiB0aW1lLiBUbyBhdm9pZAorICogdGhpcywgd2UgcGFydGl0aW9uIGVhY2ggZnJlZSBsaXN0IGluIHBvb2xzIGFuZCB3ZSBzaGFyZSBkeW5hbWljYWxseSB0aGUKKyAqIHJlc2VydmVkIHNwYWNlIGJldHdlZW4gYWxsIGZyZWUgbGlzdHMuIFRoaXMgdGVjaG5pcXVlIGlzIHF1aXRlIGVmZmljaWVudAorICogZm9yIG1lbW9yeSBpbnRlbnNpdmUgcHJvZ3JhbXMgd2hpY2ggYWxsb2NhdGUgbWFpbmx5IHNtYWxsLXNpemVkIGJsb2Nrcy4KKyAqCisgKiBGb3Igc21hbGwgcmVxdWVzdHMgd2UgaGF2ZSB0aGUgZm9sbG93aW5nIHRhYmxlOgorICoKKyAqIFJlcXVlc3QgaW4gYnl0ZXMgICAgIFNpemUgb2YgYWxsb2NhdGVkIGJsb2NrICAgICAgU2l6ZSBjbGFzcyBpZHgKKyAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKyAqICAgICAgICAxLTggICAgICAgICAgICAgICAgICAgICA4ICAgICAgICAgICAgICAgICAgICAgICAwCisgKiAgICAgICAgOS0xNiAgICAgICAgICAgICAgICAgICAxNiAgICAgICAgICAgICAgICAgICAgICAgMQorICogICAgICAgMTctMjQgICAgICAgICAgICAgICAgICAgMjQgICAgICAgICAgICAgICAgICAgICAgIDIKKyAqICAgICAgIDI1LTMyICAgICAgICAgICAgICAgICAgIDMyICAgICAgICAgICAgICAgICAgICAgICAzCisgKiAgICAgICAzMy00MCAgICAgICAgICAgICAgICAgICA0MCAgICAgICAgICAgICAgICAgICAgICAgNAorICogICAgICAgNDEtNDggICAgICAgICAgICAgICAgICAgNDggICAgICAgICAgICAgICAgICAgICAgIDUKKyAqICAgICAgIDQ5LTU2ICAgICAgICAgICAgICAgICAgIDU2ICAgICAgICAgICAgICAgICAgICAgICA2CisgKiAgICAgICA1Ny02NCAgICAgICAgICAgICAgICAgICA2NCAgICAgICAgICAgICAgICAgICAgICAgNworICogICAgICAgNjUtNzIgICAgICAgICAgICAgICAgICAgNzIgICAgICAgICAgICAgICAgICAgICAgIDgKKyAqICAgICAgICAuLi4gICAgICAgICAgICAgICAgICAgLi4uICAgICAgICAgICAgICAgICAgICAgLi4uCisgKiAgICAgIDI0MS0yNDggICAgICAgICAgICAgICAgIDI0OCAgICAgICAgICAgICAgICAgICAgICAzMAorICogICAgICAyNDktMjU2ICAgICAgICAgICAgICAgICAyNTYgICAgICAgICAgICAgICAgICAgICAgMzEKKyAqCisgKiAgICAgIDAsIDI1NyBhbmQgdXA6IHJvdXRlZCB0byB0aGUgdW5kZXJseWluZyBhbGxvY2F0b3IuCisgKi8KKworLyo9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSovCisKKy8qCisgKiAtLSBNYWluIHR1bmFibGUgc2V0dGluZ3Mgc2VjdGlvbiAtLQorICovCisKKy8qCisgKiBBbGlnbm1lbnQgb2YgYWRkcmVzc2VzIHJldHVybmVkIHRvIHRoZSB1c2VyLiA4LWJ5dGVzIGFsaWdubWVudCB3b3JrcworICogb24gbW9zdCBjdXJyZW50IGFyY2hpdGVjdHVyZXMgKHdpdGggMzItYml0IG9yIDY0LWJpdCBhZGRyZXNzIGJ1c3NlcykuCisgKiBUaGUgYWxpZ25tZW50IHZhbHVlIGlzIGFsc28gdXNlZCBmb3IgZ3JvdXBpbmcgc21hbGwgcmVxdWVzdHMgaW4gc2l6ZQorICogY2xhc3NlcyBzcGFjZWQgQUxJR05NRU5UIGJ5dGVzIGFwYXJ0LgorICoKKyAqIFlvdSBzaG91bGRuJ3QgY2hhbmdlIHRoaXMgdW5sZXNzIHlvdSBrbm93IHdoYXQgeW91IGFyZSBkb2luZy4KKyAqLworI2RlZmluZSBBTElHTk1FTlQgICAgICAgICAgICAgICA4ICAgICAgICAgICAgICAgLyogbXVzdCBiZSAyXk4gKi8KKyNkZWZpbmUgQUxJR05NRU5UX1NISUZUICAgICAgICAgMworI2RlZmluZSBBTElHTk1FTlRfTUFTSyAgICAgICAgICAoQUxJR05NRU5UIC0gMSkKKworLyogUmV0dXJuIHRoZSBudW1iZXIgb2YgYnl0ZXMgaW4gc2l6ZSBjbGFzcyBJLCBhcyBhIHVpbnQuICovCisjZGVmaW5lIElOREVYMlNJWkUoSSkgKCgodWludCkoSSkgKyAxKSA8PCBBTElHTk1FTlRfU0hJRlQpCisKKy8qCisgKiBNYXggc2l6ZSB0aHJlc2hvbGQgYmVsb3cgd2hpY2ggbWFsbG9jIHJlcXVlc3RzIGFyZSBjb25zaWRlcmVkIHRvIGJlCisgKiBzbWFsbCBlbm91Z2ggaW4gb3JkZXIgdG8gdXNlIHByZWFsbG9jYXRlZCBtZW1vcnkgcG9vbHMuIFlvdSBjYW4gdHVuZQorICogdGhpcyB2YWx1ZSBhY2NvcmRpbmcgdG8geW91ciBhcHBsaWNhdGlvbiBiZWhhdmlvdXIgYW5kIG1lbW9yeSBuZWVkcy4KKyAqCisgKiBUaGUgZm9sbG93aW5nIGludmFyaWFudHMgbXVzdCBob2xkOgorICogICAgICAxKSBBTElHTk1FTlQgPD0gU01BTExfUkVRVUVTVF9USFJFU0hPTEQgPD0gMjU2CisgKiAgICAgIDIpIFNNQUxMX1JFUVVFU1RfVEhSRVNIT0xEIGlzIGV2ZW5seSBkaXZpc2libGUgYnkgQUxJR05NRU5UCisgKgorICogQWx0aG91Z2ggbm90IHJlcXVpcmVkLCBmb3IgYmV0dGVyIHBlcmZvcm1hbmNlIGFuZCBzcGFjZSBlZmZpY2llbmN5LAorICogaXQgaXMgcmVjb21tZW5kZWQgdGhhdCBTTUFMTF9SRVFVRVNUX1RIUkVTSE9MRCBpcyBzZXQgdG8gYSBwb3dlciBvZiAyLgorICovCisjZGVmaW5lIFNNQUxMX1JFUVVFU1RfVEhSRVNIT0xEIDI1NgorI2RlZmluZSBOQl9TTUFMTF9TSVpFX0NMQVNTRVMgICAoU01BTExfUkVRVUVTVF9USFJFU0hPTEQgLyBBTElHTk1FTlQpCisKKy8qCisgKiBUaGUgc3lzdGVtJ3MgVk1NIHBhZ2Ugc2l6ZSBjYW4gYmUgb2J0YWluZWQgb24gbW9zdCB1bmljZXMgd2l0aCBhCisgKiBnZXRwYWdlc2l6ZSgpIGNhbGwgb3IgZGVkdWNlZCBmcm9tIHZhcmlvdXMgaGVhZGVyIGZpbGVzLiBUbyBtYWtlCisgKiB0aGluZ3Mgc2ltcGxlciwgd2UgYXNzdW1lIHRoYXQgaXQgaXMgNEssIHdoaWNoIGlzIE9LIGZvciBtb3N0IHN5c3RlbXMuCisgKiBJdCBpcyBwcm9iYWJseSBiZXR0ZXIgaWYgdGhpcyBpcyB0aGUgbmF0aXZlIHBhZ2Ugc2l6ZSwgYnV0IGl0IGRvZXNuJ3QKKyAqIGhhdmUgdG8gYmUuICBJbiB0aGVvcnksIGlmIFNZU1RFTV9QQUdFX1NJWkUgaXMgbGFyZ2VyIHRoYW4gdGhlIG5hdGl2ZSBwYWdlCisgKiBzaXplLCB0aGVuIGBQT09MX0FERFIocCktPmFyZW5haW5kZXgnIGNvdWxkIHJhcmVseSBjYXVzZSBhIHNlZ21lbnRhdGlvbgorICogdmlvbGF0aW9uIGZhdWx0LiAgNEsgaXMgYXBwYXJlbnRseSBPSyBmb3IgYWxsIHRoZSBwbGF0Zm9ybXMgdGhhdCBweXRob24KKyAqIGN1cnJlbnRseSB0YXJnZXRzLgorICovCisjZGVmaW5lIFNZU1RFTV9QQUdFX1NJWkUgICAgICAgICg0ICogMTAyNCkKKyNkZWZpbmUgU1lTVEVNX1BBR0VfU0laRV9NQVNLICAgKFNZU1RFTV9QQUdFX1NJWkUgLSAxKQorCisvKgorICogTWF4aW11bSBhbW91bnQgb2YgbWVtb3J5IG1hbmFnZWQgYnkgdGhlIGFsbG9jYXRvciBmb3Igc21hbGwgcmVxdWVzdHMuCisgKi8KKyNpZmRlZiBXSVRIX01FTU9SWV9MSU1JVFMKKyNpZm5kZWYgU01BTExfTUVNT1JZX0xJTUlUCisjZGVmaW5lIFNNQUxMX01FTU9SWV9MSU1JVCAgICAgICg2NCAqIDEwMjQgKiAxMDI0KSAgICAgIC8qIDY0IE1CIC0tIG1vcmU/ICovCisjZW5kaWYKKyNlbmRpZgorCisvKgorICogVGhlIGFsbG9jYXRvciBzdWItYWxsb2NhdGVzIDxCaWc+IGJsb2NrcyBvZiBtZW1vcnkgKGNhbGxlZCBhcmVuYXMpIGFsaWduZWQKKyAqIG9uIGEgcGFnZSBib3VuZGFyeS4gVGhpcyBpcyBhIHJlc2VydmVkIHZpcnR1YWwgYWRkcmVzcyBzcGFjZSBmb3IgdGhlCisgKiBjdXJyZW50IHByb2Nlc3MgKG9idGFpbmVkIHRocm91Z2ggYSBtYWxsb2MgY2FsbCkuIEluIG5vIHdheSB0aGlzIG1lYW5zCisgKiB0aGF0IHRoZSBtZW1vcnkgYXJlbmFzIHdpbGwgYmUgdXNlZCBlbnRpcmVseS4gQSBtYWxsb2MoPEJpZz4pIGlzIHVzdWFsbHkKKyAqIGFuIGFkZHJlc3MgcmFuZ2UgcmVzZXJ2YXRpb24gZm9yIDxCaWc+IGJ5dGVzLCB1bmxlc3MgYWxsIHBhZ2VzIHdpdGhpbiB0aGlzCisgKiBzcGFjZSBhcmUgcmVmZXJlbmNlZCBzdWJzZXF1ZW50bHkuIFNvIG1hbGxvYydpbmcgYmlnIGJsb2NrcyBhbmQgbm90IHVzaW5nCisgKiB0aGVtIGRvZXMgbm90IG1lYW4gIndhc3RpbmcgbWVtb3J5Ii4gSXQncyBhbiBhZGRyZXNzYWJsZSByYW5nZSB3YXN0YWdlLi4uCisgKgorICogVGhlcmVmb3JlLCBhbGxvY2F0aW5nIGFyZW5hcyB3aXRoIG1hbGxvYyBpcyBub3Qgb3B0aW1hbCwgYmVjYXVzZSB0aGVyZSBpcworICogc29tZSBhZGRyZXNzIHNwYWNlIHdhc3RhZ2UsIGJ1dCB0aGlzIGlzIHRoZSBtb3N0IHBvcnRhYmxlIHdheSB0byByZXF1ZXN0CisgKiBtZW1vcnkgZnJvbSB0aGUgc3lzdGVtIGFjcm9zcyB2YXJpb3VzIHBsYXRmb3Jtcy4KKyAqLworI2RlZmluZSBBUkVOQV9TSVpFICAgICAgICAgICAgICAoMjU2IDw8IDEwKSAgICAgLyogMjU2S0IgKi8KKworI2lmZGVmIFdJVEhfTUVNT1JZX0xJTUlUUworI2RlZmluZSBNQVhfQVJFTkFTICAgICAgICAgICAgICAoU01BTExfTUVNT1JZX0xJTUlUIC8gQVJFTkFfU0laRSkKKyNlbmRpZgorCisvKgorICogU2l6ZSBvZiB0aGUgcG9vbHMgdXNlZCBmb3Igc21hbGwgYmxvY2tzLiBTaG91bGQgYmUgYSBwb3dlciBvZiAyLAorICogYmV0d2VlbiAxSyBhbmQgU1lTVEVNX1BBR0VfU0laRSwgdGhhdCBpczogMWssIDJrLCA0ay4KKyAqLworI2RlZmluZSBQT09MX1NJWkUgICAgICAgICAgICAgICBTWVNURU1fUEFHRV9TSVpFICAgICAgICAvKiBtdXN0IGJlIDJeTiAqLworI2RlZmluZSBQT09MX1NJWkVfTUFTSyAgICAgICAgICBTWVNURU1fUEFHRV9TSVpFX01BU0sKKworLyoKKyAqIC0tIEVuZCBvZiB0dW5hYmxlIHNldHRpbmdzIHNlY3Rpb24gLS0KKyAqLworCisvKj09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ki8KKworLyoKKyAqIExvY2tpbmcKKyAqCisgKiBUbyByZWR1Y2UgbG9jayBjb250ZW50aW9uLCBpdCB3b3VsZCBwcm9iYWJseSBiZSBiZXR0ZXIgdG8gcmVmaW5lIHRoZQorICogY3J1ZGUgZnVuY3Rpb24gbG9ja2luZyB3aXRoIHBlciBzaXplIGNsYXNzIGxvY2tpbmcuIEknbSBub3QgcG9zaXRpdmUKKyAqIGhvd2V2ZXIsIHdoZXRoZXIgaXQncyB3b3J0aCBzd2l0Y2hpbmcgdG8gc3VjaCBsb2NraW5nIHBvbGljeSBiZWNhdXNlCisgKiBvZiB0aGUgcGVyZm9ybWFuY2UgcGVuYWx0eSBpdCBtaWdodCBpbnRyb2R1Y2UuCisgKgorICogVGhlIGZvbGxvd2luZyBtYWNyb3MgZGVzY3JpYmUgdGhlIHNpbXBsZXN0IChzaG91bGQgYWxzbyBiZSB0aGUgZmFzdGVzdCkKKyAqIGxvY2sgb2JqZWN0IG9uIGEgcGFydGljdWxhciBwbGF0Zm9ybSBhbmQgdGhlIGluaXQvZmluaS9sb2NrL3VubG9jaworICogb3BlcmF0aW9ucyBvbiBpdC4gVGhlIGxvY2tzIGRlZmluZWQgaGVyZSBhcmUgbm90IGV4cGVjdGVkIHRvIGJlIHJlY3Vyc2l2ZQorICogYmVjYXVzZSBpdCBpcyBhc3N1bWVkIHRoYXQgdGhleSB3aWxsIGFsd2F5cyBiZSBjYWxsZWQgaW4gdGhlIG9yZGVyOgorICogSU5JVCwgW0xPQ0ssIFVOTE9DS10qLCBGSU5JLgorICovCisKKy8qCisgKiBQeXRob24ncyB0aHJlYWRzIGFyZSBzZXJpYWxpemVkLCBzbyBvYmplY3QgbWFsbG9jIGxvY2tpbmcgaXMgZGlzYWJsZWQuCisgKi8KKyNkZWZpbmUgU0lNUExFTE9DS19ERUNMKGxvY2spICAgLyogc2ltcGxlIGxvY2sgZGVjbGFyYXRpb24gICAgICAgICAgICAgICovCisjZGVmaW5lIFNJTVBMRUxPQ0tfSU5JVChsb2NrKSAgIC8qIGFsbG9jYXRlIChpZiBuZWVkZWQpIGFuZCBpbml0aWFsaXplICAqLworI2RlZmluZSBTSU1QTEVMT0NLX0ZJTkkobG9jaykgICAvKiBmcmVlL2Rlc3Ryb3kgYW4gZXhpc3RpbmcgbG9jayAgICAgICAgKi8KKyNkZWZpbmUgU0lNUExFTE9DS19MT0NLKGxvY2spICAgLyogYWNxdWlyZSByZWxlYXNlZCBsb2NrICovCisjZGVmaW5lIFNJTVBMRUxPQ0tfVU5MT0NLKGxvY2spIC8qIHJlbGVhc2UgYWNxdWlyZWQgbG9jayAqLworCisvKgorICogQmFzaWMgdHlwZXMKKyAqIEkgZG9uJ3QgY2FyZSBpZiB0aGVzZSBhcmUgZGVmaW5lZCBpbiA8c3lzL3R5cGVzLmg+IG9yIGVsc2V3aGVyZS4gQXhpb20uCisgKi8KKyN1bmRlZiAgdWNoYXIKKyNkZWZpbmUgdWNoYXIgICB1bnNpZ25lZCBjaGFyICAgLyogYXNzdW1pbmcgPT0gOCBiaXRzICAqLworCisjdW5kZWYgIHVpbnQKKyNkZWZpbmUgdWludCAgICB1bnNpZ25lZCBpbnQgICAgLyogYXNzdW1pbmcgPj0gMTYgYml0cyAqLworCisjdW5kZWYgIHVsb25nCisjZGVmaW5lIHVsb25nICAgdW5zaWduZWQgbG9uZyAgIC8qIGFzc3VtaW5nID49IDMyIGJpdHMgKi8KKworI3VuZGVmIHVwdHIKKyNkZWZpbmUgdXB0ciAgICBQeV91aW50cHRyX3QKKworLyogV2hlbiB5b3Ugc2F5IG1lbW9yeSwgbXkgbWluZCByZWFzb25zIGluIHRlcm1zIG9mIChwb2ludGVycyB0bykgYmxvY2tzICovCit0eXBlZGVmIHVjaGFyIGJsb2NrOworCisvKiBQb29sIGZvciBzbWFsbCBibG9ja3MuICovCitzdHJ1Y3QgcG9vbF9oZWFkZXIgeworICAgIHVuaW9uIHsgYmxvY2sgKl9wYWRkaW5nOworICAgICAgICAgICAgdWludCBjb3VudDsgfSByZWY7ICAgICAgICAgIC8qIG51bWJlciBvZiBhbGxvY2F0ZWQgYmxvY2tzICAgICovCisgICAgYmxvY2sgKmZyZWVibG9jazsgICAgICAgICAgICAgICAgICAgLyogcG9vbCdzIGZyZWUgbGlzdCBoZWFkICAgICAgICAgKi8KKyAgICBzdHJ1Y3QgcG9vbF9oZWFkZXIgKm5leHRwb29sOyAgICAgICAvKiBuZXh0IHBvb2wgb2YgdGhpcyBzaXplIGNsYXNzICAqLworICAgIHN0cnVjdCBwb29sX2hlYWRlciAqcHJldnBvb2w7ICAgICAgIC8qIHByZXZpb3VzIHBvb2wgICAgICAgIiIgICAgICAgICovCisgICAgdWludCBhcmVuYWluZGV4OyAgICAgICAgICAgICAgICAgICAgLyogaW5kZXggaW50byBhcmVuYXMgb2YgYmFzZSBhZHIgKi8KKyAgICB1aW50IHN6aWR4OyAgICAgICAgICAgICAgICAgICAgICAgICAvKiBibG9jayBzaXplIGNsYXNzIGluZGV4ICAgICAgICAqLworICAgIHVpbnQgbmV4dG9mZnNldDsgICAgICAgICAgICAgICAgICAgIC8qIGJ5dGVzIHRvIHZpcmdpbiBibG9jayAgICAgICAgICovCisgICAgdWludCBtYXhuZXh0b2Zmc2V0OyAgICAgICAgICAgICAgICAgLyogbGFyZ2VzdCB2YWxpZCBuZXh0b2Zmc2V0ICAgICAgKi8KK307CisKK3R5cGVkZWYgc3RydWN0IHBvb2xfaGVhZGVyICpwb29scDsKKworLyogUmVjb3JkIGtlZXBpbmcgZm9yIGFyZW5hcy4gKi8KK3N0cnVjdCBhcmVuYV9vYmplY3QgeworICAgIC8qIFRoZSBhZGRyZXNzIG9mIHRoZSBhcmVuYSwgYXMgcmV0dXJuZWQgYnkgbWFsbG9jLiAgTm90ZSB0aGF0IDAKKyAgICAgKiB3aWxsIG5ldmVyIGJlIHJldHVybmVkIGJ5IGEgc3VjY2Vzc2Z1bCBtYWxsb2MsIGFuZCBpcyB1c2VkCisgICAgICogaGVyZSB0byBtYXJrIGFuIGFyZW5hX29iamVjdCB0aGF0IGRvZXNuJ3QgY29ycmVzcG9uZCB0byBhbgorICAgICAqIGFsbG9jYXRlZCBhcmVuYS4KKyAgICAgKi8KKyAgICB1cHRyIGFkZHJlc3M7CisKKyAgICAvKiBQb29sLWFsaWduZWQgcG9pbnRlciB0byB0aGUgbmV4dCBwb29sIHRvIGJlIGNhcnZlZCBvZmYuICovCisgICAgYmxvY2sqIHBvb2xfYWRkcmVzczsKKworICAgIC8qIFRoZSBudW1iZXIgb2YgYXZhaWxhYmxlIHBvb2xzIGluIHRoZSBhcmVuYTogIGZyZWUgcG9vbHMgKyBuZXZlci0KKyAgICAgKiBhbGxvY2F0ZWQgcG9vbHMuCisgICAgICovCisgICAgdWludCBuZnJlZXBvb2xzOworCisgICAgLyogVGhlIHRvdGFsIG51bWJlciBvZiBwb29scyBpbiB0aGUgYXJlbmEsIHdoZXRoZXIgb3Igbm90IGF2YWlsYWJsZS4gKi8KKyAgICB1aW50IG50b3RhbHBvb2xzOworCisgICAgLyogU2luZ2x5LWxpbmtlZCBsaXN0IG9mIGF2YWlsYWJsZSBwb29scy4gKi8KKyAgICBzdHJ1Y3QgcG9vbF9oZWFkZXIqIGZyZWVwb29sczsKKworICAgIC8qIFdoZW5ldmVyIHRoaXMgYXJlbmFfb2JqZWN0IGlzIG5vdCBhc3NvY2lhdGVkIHdpdGggYW4gYWxsb2NhdGVkCisgICAgICogYXJlbmEsIHRoZSBuZXh0YXJlbmEgbWVtYmVyIGlzIHVzZWQgdG8gbGluayBhbGwgdW5hc3NvY2lhdGVkCisgICAgICogYXJlbmFfb2JqZWN0cyBpbiB0aGUgc2luZ2x5LWxpbmtlZCBgdW51c2VkX2FyZW5hX29iamVjdHNgIGxpc3QuCisgICAgICogVGhlIHByZXZhcmVuYSBtZW1iZXIgaXMgdW51c2VkIGluIHRoaXMgY2FzZS4KKyAgICAgKgorICAgICAqIFdoZW4gdGhpcyBhcmVuYV9vYmplY3QgaXMgYXNzb2NpYXRlZCB3aXRoIGFuIGFsbG9jYXRlZCBhcmVuYQorICAgICAqIHdpdGggYXQgbGVhc3Qgb25lIGF2YWlsYWJsZSBwb29sLCBib3RoIG1lbWJlcnMgYXJlIHVzZWQgaW4gdGhlCisgICAgICogZG91Ymx5LWxpbmtlZCBgdXNhYmxlX2FyZW5hc2AgbGlzdCwgd2hpY2ggaXMgbWFpbnRhaW5lZCBpbgorICAgICAqIGluY3JlYXNpbmcgb3JkZXIgb2YgYG5mcmVlcG9vbHNgIHZhbHVlcy4KKyAgICAgKgorICAgICAqIEVsc2UgdGhpcyBhcmVuYV9vYmplY3QgaXMgYXNzb2NpYXRlZCB3aXRoIGFuIGFsbG9jYXRlZCBhcmVuYQorICAgICAqIGFsbCBvZiB3aG9zZSBwb29scyBhcmUgaW4gdXNlLiAgYG5leHRhcmVuYWAgYW5kIGBwcmV2YXJlbmFgCisgICAgICogYXJlIGJvdGggbWVhbmluZ2xlc3MgaW4gdGhpcyBjYXNlLgorICAgICAqLworICAgIHN0cnVjdCBhcmVuYV9vYmplY3QqIG5leHRhcmVuYTsKKyAgICBzdHJ1Y3QgYXJlbmFfb2JqZWN0KiBwcmV2YXJlbmE7Cit9OworCisjdW5kZWYgIFJPVU5EVVAKKyNkZWZpbmUgUk9VTkRVUCh4KSAgICAgICAgICAgICAgKCgoeCkgKyBBTElHTk1FTlRfTUFTSykgJiB+QUxJR05NRU5UX01BU0spCisjZGVmaW5lIFBPT0xfT1ZFUkhFQUQgICAgICAgICAgIFJPVU5EVVAoc2l6ZW9mKHN0cnVjdCBwb29sX2hlYWRlcikpCisKKyNkZWZpbmUgRFVNTVlfU0laRV9JRFggICAgICAgICAgMHhmZmZmICAvKiBzaXplIGNsYXNzIG9mIG5ld2x5IGNhY2hlZCBwb29scyAqLworCisvKiBSb3VuZCBwb2ludGVyIFAgZG93biB0byB0aGUgY2xvc2VzdCBwb29sLWFsaWduZWQgYWRkcmVzcyA8PSBQLCBhcyBhIHBvb2xwICovCisjZGVmaW5lIFBPT0xfQUREUihQKSAoKHBvb2xwKSgodXB0cikoUCkgJiB+KHVwdHIpUE9PTF9TSVpFX01BU0spKQorCisvKiBSZXR1cm4gdG90YWwgbnVtYmVyIG9mIGJsb2NrcyBpbiBwb29sIG9mIHNpemUgaW5kZXggSSwgYXMgYSB1aW50LiAqLworI2RlZmluZSBOVU1CTE9DS1MoSSkgKCh1aW50KShQT09MX1NJWkUgLSBQT09MX09WRVJIRUFEKSAvIElOREVYMlNJWkUoSSkpCisKKy8qPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0qLworCisvKgorICogVGhpcyBtYWxsb2MgbG9jaworICovCitTSU1QTEVMT0NLX0RFQ0woX21hbGxvY19sb2NrKQorI2RlZmluZSBMT0NLKCkgICAgICAgICAgU0lNUExFTE9DS19MT0NLKF9tYWxsb2NfbG9jaykKKyNkZWZpbmUgVU5MT0NLKCkgICAgICAgIFNJTVBMRUxPQ0tfVU5MT0NLKF9tYWxsb2NfbG9jaykKKyNkZWZpbmUgTE9DS19JTklUKCkgICAgIFNJTVBMRUxPQ0tfSU5JVChfbWFsbG9jX2xvY2spCisjZGVmaW5lIExPQ0tfRklOSSgpICAgICBTSU1QTEVMT0NLX0ZJTkkoX21hbGxvY19sb2NrKQorCisvKgorICogUG9vbCB0YWJsZSAtLSBoZWFkZWQsIGNpcmN1bGFyLCBkb3VibHktbGlua2VkIGxpc3RzIG9mIHBhcnRpYWxseSB1c2VkIHBvb2xzLgorCitUaGlzIGlzIGludm9sdmVkLiAgRm9yIGFuIGluZGV4IGksIHVzZWRwb29sc1tpK2ldIGlzIHRoZSBoZWFkZXIgZm9yIGEgbGlzdCBvZgorYWxsIHBhcnRpYWxseSB1c2VkIHBvb2xzIGhvbGRpbmcgc21hbGwgYmxvY2tzIHdpdGggInNpemUgY2xhc3MgaWR4IiBpLiBTbwordXNlZHBvb2xzWzBdIGNvcnJlc3BvbmRzIHRvIGJsb2NrcyBvZiBzaXplIDgsIHVzZWRwb29sc1syXSB0byBibG9ja3Mgb2Ygc2l6ZQorMTYsIGFuZCBzbyBvbjogIGluZGV4IDIqaSA8LT4gYmxvY2tzIG9mIHNpemUgKGkrMSk8PEFMSUdOTUVOVF9TSElGVC4KKworUG9vbHMgYXJlIGNhcnZlZCBvZmYgYW4gYXJlbmEncyBoaWdod2F0ZXIgbWFyayAoYW4gYXJlbmFfb2JqZWN0J3MgcG9vbF9hZGRyZXNzCittZW1iZXIpIGFzIG5lZWRlZC4gIE9uY2UgY2FydmVkIG9mZiwgYSBwb29sIGlzIGluIG9uZSBvZiB0aHJlZSBzdGF0ZXMgZm9yZXZlcgorYWZ0ZXI6CisKK3VzZWQgPT0gcGFydGlhbGx5IHVzZWQsIG5laXRoZXIgZW1wdHkgbm9yIGZ1bGwKKyAgICBBdCBsZWFzdCBvbmUgYmxvY2sgaW4gdGhlIHBvb2wgaXMgY3VycmVudGx5IGFsbG9jYXRlZCwgYW5kIGF0IGxlYXN0IG9uZQorICAgIGJsb2NrIGluIHRoZSBwb29sIGlzIG5vdCBjdXJyZW50bHkgYWxsb2NhdGVkIChub3RlIHRoaXMgaW1wbGllcyBhIHBvb2wKKyAgICBoYXMgcm9vbSBmb3IgYXQgbGVhc3QgdHdvIGJsb2NrcykuCisgICAgVGhpcyBpcyBhIHBvb2wncyBpbml0aWFsIHN0YXRlLCBhcyBhIHBvb2wgaXMgY3JlYXRlZCBvbmx5IHdoZW4gbWFsbG9jCisgICAgbmVlZHMgc3BhY2UuCisgICAgVGhlIHBvb2wgaG9sZHMgYmxvY2tzIG9mIGEgZml4ZWQgc2l6ZSwgYW5kIGlzIGluIHRoZSBjaXJjdWxhciBsaXN0IGhlYWRlZAorICAgIGF0IHVzZWRwb29sc1tpXSAoc2VlIGFib3ZlKS4gIEl0J3MgbGlua2VkIHRvIHRoZSBvdGhlciB1c2VkIHBvb2xzIG9mIHRoZQorICAgIHNhbWUgc2l6ZSBjbGFzcyB2aWEgdGhlIHBvb2xfaGVhZGVyJ3MgbmV4dHBvb2wgYW5kIHByZXZwb29sIG1lbWJlcnMuCisgICAgSWYgYWxsIGJ1dCBvbmUgYmxvY2sgaXMgY3VycmVudGx5IGFsbG9jYXRlZCwgYSBtYWxsb2MgY2FuIGNhdXNlIGEKKyAgICB0cmFuc2l0aW9uIHRvIHRoZSBmdWxsIHN0YXRlLiAgSWYgYWxsIGJ1dCBvbmUgYmxvY2sgaXMgbm90IGN1cnJlbnRseQorICAgIGFsbG9jYXRlZCwgYSBmcmVlIGNhbiBjYXVzZSBhIHRyYW5zaXRpb24gdG8gdGhlIGVtcHR5IHN0YXRlLgorCitmdWxsID09IGFsbCB0aGUgcG9vbCdzIGJsb2NrcyBhcmUgY3VycmVudGx5IGFsbG9jYXRlZAorICAgIE9uIHRyYW5zaXRpb24gdG8gZnVsbCwgYSBwb29sIGlzIHVubGlua2VkIGZyb20gaXRzIHVzZWRwb29sc1tdIGxpc3QuCisgICAgSXQncyBub3QgbGlua2VkIHRvIGZyb20gYW55dGhpbmcgdGhlbiBhbnltb3JlLCBhbmQgaXRzIG5leHRwb29sIGFuZAorICAgIHByZXZwb29sIG1lbWJlcnMgYXJlIG1lYW5pbmdsZXNzIHVudGlsIGl0IHRyYW5zaXRpb25zIGJhY2sgdG8gdXNlZC4KKyAgICBBIGZyZWUgb2YgYSBibG9jayBpbiBhIGZ1bGwgcG9vbCBwdXRzIHRoZSBwb29sIGJhY2sgaW4gdGhlIHVzZWQgc3RhdGUuCisgICAgVGhlbiBpdCdzIGxpbmtlZCBpbiBhdCB0aGUgZnJvbnQgb2YgdGhlIGFwcHJvcHJpYXRlIHVzZWRwb29sc1tdIGxpc3QsIHNvCisgICAgdGhhdCB0aGUgbmV4dCBhbGxvY2F0aW9uIGZvciBpdHMgc2l6ZSBjbGFzcyB3aWxsIHJldXNlIHRoZSBmcmVlZCBibG9jay4KKworZW1wdHkgPT0gYWxsIHRoZSBwb29sJ3MgYmxvY2tzIGFyZSBjdXJyZW50bHkgYXZhaWxhYmxlIGZvciBhbGxvY2F0aW9uCisgICAgT24gdHJhbnNpdGlvbiB0byBlbXB0eSwgYSBwb29sIGlzIHVubGlua2VkIGZyb20gaXRzIHVzZWRwb29sc1tdIGxpc3QsCisgICAgYW5kIGxpbmtlZCB0byB0aGUgZnJvbnQgb2YgaXRzIGFyZW5hX29iamVjdCdzIHNpbmdseS1saW5rZWQgZnJlZXBvb2xzIGxpc3QsCisgICAgdmlhIGl0cyBuZXh0cG9vbCBtZW1iZXIuICBUaGUgcHJldnBvb2wgbWVtYmVyIGhhcyBubyBtZWFuaW5nIGluIHRoaXMgY2FzZS4KKyAgICBFbXB0eSBwb29scyBoYXZlIG5vIGluaGVyZW50IHNpemUgY2xhc3M6ICB0aGUgbmV4dCB0aW1lIGEgbWFsbG9jIGZpbmRzCisgICAgYW4gZW1wdHkgbGlzdCBpbiB1c2VkcG9vbHNbXSwgaXQgdGFrZXMgdGhlIGZpcnN0IHBvb2wgb2ZmIG9mIGZyZWVwb29scy4KKyAgICBJZiB0aGUgc2l6ZSBjbGFzcyBuZWVkZWQgaGFwcGVucyB0byBiZSB0aGUgc2FtZSBhcyB0aGUgc2l6ZSBjbGFzcyB0aGUgcG9vbAorICAgIGxhc3QgaGFkLCBzb21lIHBvb2wgaW5pdGlhbGl6YXRpb24gY2FuIGJlIHNraXBwZWQuCisKKworQmxvY2sgTWFuYWdlbWVudAorCitCbG9ja3Mgd2l0aGluIHBvb2xzIGFyZSBhZ2FpbiBjYXJ2ZWQgb3V0IGFzIG5lZWRlZC4gIHBvb2wtPmZyZWVibG9jayBwb2ludHMgdG8KK3RoZSBzdGFydCBvZiBhIHNpbmdseS1saW5rZWQgbGlzdCBvZiBmcmVlIGJsb2NrcyB3aXRoaW4gdGhlIHBvb2wuICBXaGVuIGEKK2Jsb2NrIGlzIGZyZWVkLCBpdCdzIGluc2VydGVkIGF0IHRoZSBmcm9udCBvZiBpdHMgcG9vbCdzIGZyZWVibG9jayBsaXN0LiAgTm90ZQordGhhdCB0aGUgYXZhaWxhYmxlIGJsb2NrcyBpbiBhIHBvb2wgYXJlICpub3QqIGxpbmtlZCBhbGwgdG9nZXRoZXIgd2hlbiBhIHBvb2wKK2lzIGluaXRpYWxpemVkLiAgSW5zdGVhZCBvbmx5ICJ0aGUgZmlyc3QgdHdvIiAobG93ZXN0IGFkZHJlc3NlcykgYmxvY2tzIGFyZQorc2V0IHVwLCByZXR1cm5pbmcgdGhlIGZpcnN0IHN1Y2ggYmxvY2ssIGFuZCBzZXR0aW5nIHBvb2wtPmZyZWVibG9jayB0byBhCitvbmUtYmxvY2sgbGlzdCBob2xkaW5nIHRoZSBzZWNvbmQgc3VjaCBibG9jay4gIFRoaXMgaXMgY29uc2lzdGVudCB3aXRoIHRoYXQKK3B5bWFsbG9jIHN0cml2ZXMgYXQgYWxsIGxldmVscyAoYXJlbmEsIHBvb2wsIGFuZCBibG9jaykgbmV2ZXIgdG8gdG91Y2ggYSBwaWVjZQorb2YgbWVtb3J5IHVudGlsIGl0J3MgYWN0dWFsbHkgbmVlZGVkLgorCitTbyBsb25nIGFzIGEgcG9vbCBpcyBpbiB0aGUgdXNlZCBzdGF0ZSwgd2UncmUgY2VydGFpbiB0aGVyZSAqaXMqIGEgYmxvY2sKK2F2YWlsYWJsZSBmb3IgYWxsb2NhdGluZywgYW5kIHBvb2wtPmZyZWVibG9jayBpcyBub3QgTlVMTC4gIElmIHBvb2wtPmZyZWVibG9jaworcG9pbnRzIHRvIHRoZSBlbmQgb2YgdGhlIGZyZWUgbGlzdCBiZWZvcmUgd2UndmUgY2FydmVkIHRoZSBlbnRpcmUgcG9vbCBpbnRvCitibG9ja3MsIHRoYXQgbWVhbnMgd2Ugc2ltcGx5IGhhdmVuJ3QgeWV0IGdvdHRlbiB0byBvbmUgb2YgdGhlIGhpZ2hlci1hZGRyZXNzCitibG9ja3MuICBUaGUgb2Zmc2V0IGZyb20gdGhlIHBvb2xfaGVhZGVyIHRvIHRoZSBzdGFydCBvZiAidGhlIG5leHQiIHZpcmdpbgorYmxvY2sgaXMgc3RvcmVkIGluIHRoZSBwb29sX2hlYWRlciBuZXh0b2Zmc2V0IG1lbWJlciwgYW5kIHRoZSBsYXJnZXN0IHZhbHVlCitvZiBuZXh0b2Zmc2V0IHRoYXQgbWFrZXMgc2Vuc2UgaXMgc3RvcmVkIGluIHRoZSBtYXhuZXh0b2Zmc2V0IG1lbWJlciB3aGVuIGEKK3Bvb2wgaXMgaW5pdGlhbGl6ZWQuICBBbGwgdGhlIGJsb2NrcyBpbiBhIHBvb2wgaGF2ZSBiZWVuIHBhc3NlZCBvdXQgYXQgbGVhc3QKK29uY2Ugd2hlbiBhbmQgb25seSB3aGVuIG5leHRvZmZzZXQgPiBtYXhuZXh0b2Zmc2V0LgorCisKK01ham9yIG9ic2N1cml0eTogIFdoaWxlIHRoZSB1c2VkcG9vbHMgdmVjdG9yIGlzIGRlY2xhcmVkIHRvIGhhdmUgcG9vbHAKK2VudHJpZXMsIGl0IGRvZXNuJ3QgcmVhbGx5LiAgSXQgcmVhbGx5IGNvbnRhaW5zIHR3byBwb2ludGVycyBwZXIgKGNvbmNlcHR1YWwpCitwb29scCBlbnRyeSwgdGhlIG5leHRwb29sIGFuZCBwcmV2cG9vbCBtZW1iZXJzIG9mIGEgcG9vbF9oZWFkZXIuICBUaGUKK2V4Y3J1Y2lhdGluZyBpbml0aWFsaXphdGlvbiBjb2RlIGJlbG93IGZvb2xzIEMgc28gdGhhdAorCisgICAgdXNlZHBvb2xbaStpXQorCisiYWN0cyBsaWtlIiBhIGdlbnVpbmUgcG9vbHAsIGJ1dCBvbmx5IHNvIGxvbmcgYXMgeW91IG9ubHkgcmVmZXJlbmNlIGl0cworbmV4dHBvb2wgYW5kIHByZXZwb29sIG1lbWJlcnMuICBUaGUgIi0gMipzaXplb2YoYmxvY2sgKikiIGdpYmJlcmlzaCBpcworY29tcGVuc2F0aW5nIGZvciB0aGF0IGEgcG9vbF9oZWFkZXIncyBuZXh0cG9vbCBhbmQgcHJldnBvb2wgbWVtYmVycworaW1tZWRpYXRlbHkgZm9sbG93IGEgcG9vbF9oZWFkZXIncyBmaXJzdCB0d28gbWVtYmVyczoKKworICAgIHVuaW9uIHsgYmxvY2sgKl9wYWRkaW5nOworICAgICAgICAgICAgdWludCBjb3VudDsgfSByZWY7CisgICAgYmxvY2sgKmZyZWVibG9jazsKKworZWFjaCBvZiB3aGljaCBjb25zdW1lIHNpemVvZihibG9jayAqKSBieXRlcy4gIFNvIHdoYXQgdXNlZHBvb2xzW2kraV0gcmVhbGx5Citjb250YWlucyBpcyBhIGZ1ZGdlZC11cCBwb2ludGVyIHAgc3VjaCB0aGF0ICppZiogQyBiZWxpZXZlcyBpdCdzIGEgcG9vbHAKK3BvaW50ZXIsIHRoZW4gcC0+bmV4dHBvb2wgYW5kIHAtPnByZXZwb29sIGFyZSBib3RoIHAgKG1lYW5pbmcgdGhhdCB0aGUgaGVhZGVkCitjaXJjdWxhciBsaXN0IGlzIGVtcHR5KS4KKworSXQncyB1bmNsZWFyIHdoeSB0aGUgdXNlZHBvb2xzIHNldHVwIGlzIHNvIGNvbnZvbHV0ZWQuICBJdCBjb3VsZCBiZSB0bworbWluaW1pemUgdGhlIGFtb3VudCBvZiBjYWNoZSByZXF1aXJlZCB0byBob2xkIHRoaXMgaGVhdmlseS1yZWZlcmVuY2VkIHRhYmxlCisod2hpY2ggb25seSAqbmVlZHMqIHRoZSB0d28gaW50ZXJwb29sIHBvaW50ZXIgbWVtYmVycyBvZiBhIHBvb2xfaGVhZGVyKS4gT1RPSCwKK3JlZmVyZW5jaW5nIGNvZGUgaGFzIHRvIHJlbWVtYmVyIHRvICJkb3VibGUgdGhlIGluZGV4IiBhbmQgZG9pbmcgc28gaXNuJ3QKK2ZyZWUsIHVzZWRwb29sc1swXSBpc24ndCBhIHN0cmljdGx5IGxlZ2FsIHBvaW50ZXIsIGFuZCB3ZSdyZSBjcnVjaWFsbHkgcmVseWluZworb24gdGhhdCBDIGRvZXNuJ3QgaW5zZXJ0IGFueSBwYWRkaW5nIGFueXdoZXJlIGluIGEgcG9vbF9oZWFkZXIgYXQgb3IgYmVmb3JlCit0aGUgcHJldnBvb2wgbWVtYmVyLgorKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiAqLworCisjZGVmaW5lIFBUQSh4KSAgKChwb29scCApKCh1Y2hhciAqKSYodXNlZHBvb2xzWzIqKHgpXSkgLSAyKnNpemVvZihibG9jayAqKSkpCisjZGVmaW5lIFBUKHgpICAgUFRBKHgpLCBQVEEoeCkKKworc3RhdGljIHBvb2xwIHVzZWRwb29sc1syICogKChOQl9TTUFMTF9TSVpFX0NMQVNTRVMgKyA3KSAvIDgpICogOF0gPSB7CisgICAgUFQoMCksIFBUKDEpLCBQVCgyKSwgUFQoMyksIFBUKDQpLCBQVCg1KSwgUFQoNiksIFBUKDcpCisjaWYgTkJfU01BTExfU0laRV9DTEFTU0VTID4gOAorICAgICwgUFQoOCksIFBUKDkpLCBQVCgxMCksIFBUKDExKSwgUFQoMTIpLCBQVCgxMyksIFBUKDE0KSwgUFQoMTUpCisjaWYgTkJfU01BTExfU0laRV9DTEFTU0VTID4gMTYKKyAgICAsIFBUKDE2KSwgUFQoMTcpLCBQVCgxOCksIFBUKDE5KSwgUFQoMjApLCBQVCgyMSksIFBUKDIyKSwgUFQoMjMpCisjaWYgTkJfU01BTExfU0laRV9DTEFTU0VTID4gMjQKKyAgICAsIFBUKDI0KSwgUFQoMjUpLCBQVCgyNiksIFBUKDI3KSwgUFQoMjgpLCBQVCgyOSksIFBUKDMwKSwgUFQoMzEpCisjaWYgTkJfU01BTExfU0laRV9DTEFTU0VTID4gMzIKKyAgICAsIFBUKDMyKSwgUFQoMzMpLCBQVCgzNCksIFBUKDM1KSwgUFQoMzYpLCBQVCgzNyksIFBUKDM4KSwgUFQoMzkpCisjaWYgTkJfU01BTExfU0laRV9DTEFTU0VTID4gNDAKKyAgICAsIFBUKDQwKSwgUFQoNDEpLCBQVCg0MiksIFBUKDQzKSwgUFQoNDQpLCBQVCg0NSksIFBUKDQ2KSwgUFQoNDcpCisjaWYgTkJfU01BTExfU0laRV9DTEFTU0VTID4gNDgKKyAgICAsIFBUKDQ4KSwgUFQoNDkpLCBQVCg1MCksIFBUKDUxKSwgUFQoNTIpLCBQVCg1MyksIFBUKDU0KSwgUFQoNTUpCisjaWYgTkJfU01BTExfU0laRV9DTEFTU0VTID4gNTYKKyAgICAsIFBUKDU2KSwgUFQoNTcpLCBQVCg1OCksIFBUKDU5KSwgUFQoNjApLCBQVCg2MSksIFBUKDYyKSwgUFQoNjMpCisjZW5kaWYgLyogTkJfU01BTExfU0laRV9DTEFTU0VTID4gNTYgKi8KKyNlbmRpZiAvKiBOQl9TTUFMTF9TSVpFX0NMQVNTRVMgPiA0OCAqLworI2VuZGlmIC8qIE5CX1NNQUxMX1NJWkVfQ0xBU1NFUyA+IDQwICovCisjZW5kaWYgLyogTkJfU01BTExfU0laRV9DTEFTU0VTID4gMzIgKi8KKyNlbmRpZiAvKiBOQl9TTUFMTF9TSVpFX0NMQVNTRVMgPiAyNCAqLworI2VuZGlmIC8qIE5CX1NNQUxMX1NJWkVfQ0xBU1NFUyA+IDE2ICovCisjZW5kaWYgLyogTkJfU01BTExfU0laRV9DTEFTU0VTID4gIDggKi8KK307CisKKy8qPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KK0FyZW5hIG1hbmFnZW1lbnQuCisKK2BhcmVuYXNgIGlzIGEgdmVjdG9yIG9mIGFyZW5hX29iamVjdHMuICBJdCBjb250YWlucyBtYXhhcmVuYXMgZW50cmllcywgc29tZSBvZgord2hpY2ggbWF5IG5vdCBiZSBjdXJyZW50bHkgdXNlZCAoPT0gdGhleSdyZSBhcmVuYV9vYmplY3RzIHRoYXQgYXJlbid0CitjdXJyZW50bHkgYXNzb2NpYXRlZCB3aXRoIGFuIGFsbG9jYXRlZCBhcmVuYSkuICBOb3RlIHRoYXQgYXJlbmFzIHByb3BlciBhcmUKK3NlcGFyYXRlbHkgbWFsbG9jJ2VkLgorCitQcmlvciB0byBQeXRob24gMi41LCBhcmVuYXMgd2VyZSBuZXZlciBmcmVlKCknZWQuICBTdGFydGluZyB3aXRoIFB5dGhvbiAyLjUsCit3ZSBkbyB0cnkgdG8gZnJlZSgpIGFyZW5hcywgYW5kIHVzZSBzb21lIG1pbGQgaGV1cmlzdGljIHN0cmF0ZWdpZXMgdG8gaW5jcmVhc2UKK3RoZSBsaWtlbGlob29kIHRoYXQgYXJlbmFzIGV2ZW50dWFsbHkgY2FuIGJlIGZyZWVkLgorCit1bnVzZWRfYXJlbmFfb2JqZWN0cworCisgICAgVGhpcyBpcyBhIHNpbmdseS1saW5rZWQgbGlzdCBvZiB0aGUgYXJlbmFfb2JqZWN0cyB0aGF0IGFyZSBjdXJyZW50bHkgbm90CisgICAgYmVpbmcgdXNlZCAobm8gYXJlbmEgaXMgYXNzb2NpYXRlZCB3aXRoIHRoZW0pLiAgT2JqZWN0cyBhcmUgdGFrZW4gb2ZmIHRoZQorICAgIGhlYWQgb2YgdGhlIGxpc3QgaW4gbmV3X2FyZW5hKCksIGFuZCBhcmUgcHVzaGVkIG9uIHRoZSBoZWFkIG9mIHRoZSBsaXN0IGluCisgICAgUHlPYmplY3RfRnJlZSgpIHdoZW4gdGhlIGFyZW5hIGlzIGVtcHR5LiAgS2V5IGludmFyaWFudDogIGFuIGFyZW5hX29iamVjdAorICAgIGlzIG9uIHRoaXMgbGlzdCBpZiBhbmQgb25seSBpZiBpdHMgLmFkZHJlc3MgbWVtYmVyIGlzIDAuCisKK3VzYWJsZV9hcmVuYXMKKworICAgIFRoaXMgaXMgYSBkb3VibHktbGlua2VkIGxpc3Qgb2YgdGhlIGFyZW5hX29iamVjdHMgYXNzb2NpYXRlZCB3aXRoIGFyZW5hcworICAgIHRoYXQgaGF2ZSBwb29scyBhdmFpbGFibGUuICBUaGVzZSBwb29scyBhcmUgZWl0aGVyIHdhaXRpbmcgdG8gYmUgcmV1c2VkLAorICAgIG9yIGhhdmUgbm90IGJlZW4gdXNlZCBiZWZvcmUuICBUaGUgbGlzdCBpcyBzb3J0ZWQgdG8gaGF2ZSB0aGUgbW9zdC0KKyAgICBhbGxvY2F0ZWQgYXJlbmFzIGZpcnN0IChhc2NlbmRpbmcgb3JkZXIgYmFzZWQgb24gdGhlIG5mcmVlcG9vbHMgbWVtYmVyKS4KKyAgICBUaGlzIG1lYW5zIHRoYXQgdGhlIG5leHQgYWxsb2NhdGlvbiB3aWxsIGNvbWUgZnJvbSBhIGhlYXZpbHkgdXNlZCBhcmVuYSwKKyAgICB3aGljaCBnaXZlcyB0aGUgbmVhcmx5IGVtcHR5IGFyZW5hcyBhIGNoYW5jZSB0byBiZSByZXR1cm5lZCB0byB0aGUgc3lzdGVtLgorICAgIEluIG15IHVuc2NpZW50aWZpYyB0ZXN0cyB0aGlzIGRyYW1hdGljYWxseSBpbXByb3ZlZCB0aGUgbnVtYmVyIG9mIGFyZW5hcworICAgIHRoYXQgY291bGQgYmUgZnJlZWQuCisKK05vdGUgdGhhdCBhbiBhcmVuYV9vYmplY3QgYXNzb2NpYXRlZCB3aXRoIGFuIGFyZW5hIGFsbCBvZiB3aG9zZSBwb29scyBhcmUKK2N1cnJlbnRseSBpbiB1c2UgaXNuJ3Qgb24gZWl0aGVyIGxpc3QuCisqLworCisvKiBBcnJheSBvZiBvYmplY3RzIHVzZWQgdG8gdHJhY2sgY2h1bmtzIG9mIG1lbW9yeSAoYXJlbmFzKS4gKi8KK3N0YXRpYyBzdHJ1Y3QgYXJlbmFfb2JqZWN0KiBhcmVuYXMgPSBOVUxMOworLyogTnVtYmVyIG9mIHNsb3RzIGN1cnJlbnRseSBhbGxvY2F0ZWQgaW4gdGhlIGBhcmVuYXNgIHZlY3Rvci4gKi8KK3N0YXRpYyB1aW50IG1heGFyZW5hcyA9IDA7CisKKy8qIFRoZSBoZWFkIG9mIHRoZSBzaW5nbHktbGlua2VkLCBOVUxMLXRlcm1pbmF0ZWQgbGlzdCBvZiBhdmFpbGFibGUKKyAqIGFyZW5hX29iamVjdHMuCisgKi8KK3N0YXRpYyBzdHJ1Y3QgYXJlbmFfb2JqZWN0KiB1bnVzZWRfYXJlbmFfb2JqZWN0cyA9IE5VTEw7CisKKy8qIFRoZSBoZWFkIG9mIHRoZSBkb3VibHktbGlua2VkLCBOVUxMLXRlcm1pbmF0ZWQgYXQgZWFjaCBlbmQsIGxpc3Qgb2YKKyAqIGFyZW5hX29iamVjdHMgYXNzb2NpYXRlZCB3aXRoIGFyZW5hcyB0aGF0IGhhdmUgcG9vbHMgYXZhaWxhYmxlLgorICovCitzdGF0aWMgc3RydWN0IGFyZW5hX29iamVjdCogdXNhYmxlX2FyZW5hcyA9IE5VTEw7CisKKy8qIEhvdyBtYW55IGFyZW5hX29iamVjdHMgZG8gd2UgaW5pdGlhbGx5IGFsbG9jYXRlPworICogMTYgPSBjYW4gYWxsb2NhdGUgMTYgYXJlbmFzID0gMTYgKiBBUkVOQV9TSVpFID0gNE1CIGJlZm9yZSBncm93aW5nIHRoZQorICogYGFyZW5hc2AgdmVjdG9yLgorICovCisjZGVmaW5lIElOSVRJQUxfQVJFTkFfT0JKRUNUUyAxNgorCisvKiBOdW1iZXIgb2YgYXJlbmFzIGFsbG9jYXRlZCB0aGF0IGhhdmVuJ3QgYmVlbiBmcmVlKCknZC4gKi8KK3N0YXRpYyBzaXplX3QgbmFyZW5hc19jdXJyZW50bHlfYWxsb2NhdGVkID0gMDsKKworI2lmZGVmIFBZTUFMTE9DX0RFQlVHCisvKiBUb3RhbCBudW1iZXIgb2YgdGltZXMgbWFsbG9jKCkgY2FsbGVkIHRvIGFsbG9jYXRlIGFuIGFyZW5hLiAqLworc3RhdGljIHNpemVfdCBudGltZXNfYXJlbmFfYWxsb2NhdGVkID0gMDsKKy8qIEhpZ2ggd2F0ZXIgbWFyayAobWF4IHZhbHVlIGV2ZXIgc2VlbikgZm9yIG5hcmVuYXNfY3VycmVudGx5X2FsbG9jYXRlZC4gKi8KK3N0YXRpYyBzaXplX3QgbmFyZW5hc19oaWdod2F0ZXIgPSAwOworI2VuZGlmCisKKy8qIEFsbG9jYXRlIGEgbmV3IGFyZW5hLiAgSWYgd2UgcnVuIG91dCBvZiBtZW1vcnksIHJldHVybiBOVUxMLiAgRWxzZQorICogYWxsb2NhdGUgYSBuZXcgYXJlbmEsIGFuZCByZXR1cm4gdGhlIGFkZHJlc3Mgb2YgYW4gYXJlbmFfb2JqZWN0CisgKiBkZXNjcmliaW5nIHRoZSBuZXcgYXJlbmEuICBJdCdzIGV4cGVjdGVkIHRoYXQgdGhlIGNhbGxlciB3aWxsIHNldAorICogYHVzYWJsZV9hcmVuYXNgIHRvIHRoZSByZXR1cm4gdmFsdWUuCisgKi8KK3N0YXRpYyBzdHJ1Y3QgYXJlbmFfb2JqZWN0KgorbmV3X2FyZW5hKHZvaWQpCit7CisgICAgc3RydWN0IGFyZW5hX29iamVjdCogYXJlbmFvYmo7CisgICAgdWludCBleGNlc3M7ICAgICAgICAvKiBudW1iZXIgb2YgYnl0ZXMgYWJvdmUgcG9vbCBhbGlnbm1lbnQgKi8KKworI2lmZGVmIFBZTUFMTE9DX0RFQlVHCisgICAgaWYgKFB5X0dFVEVOVigiUFlUSE9OTUFMTE9DU1RBVFMiKSkKKyAgICAgICAgX1B5T2JqZWN0X0RlYnVnTWFsbG9jU3RhdHMoKTsKKyNlbmRpZgorICAgIGlmICh1bnVzZWRfYXJlbmFfb2JqZWN0cyA9PSBOVUxMKSB7CisgICAgICAgIHVpbnQgaTsKKyAgICAgICAgdWludCBudW1hcmVuYXM7CisgICAgICAgIHNpemVfdCBuYnl0ZXM7CisKKyAgICAgICAgLyogRG91YmxlIHRoZSBudW1iZXIgb2YgYXJlbmEgb2JqZWN0cyBvbiBlYWNoIGFsbG9jYXRpb24uCisgICAgICAgICAqIE5vdGUgdGhhdCBpdCdzIHBvc3NpYmxlIGZvciBgbnVtYXJlbmFzYCB0byBvdmVyZmxvdy4KKyAgICAgICAgICovCisgICAgICAgIG51bWFyZW5hcyA9IG1heGFyZW5hcyA/IG1heGFyZW5hcyA8PCAxIDogSU5JVElBTF9BUkVOQV9PQkpFQ1RTOworICAgICAgICBpZiAobnVtYXJlbmFzIDw9IG1heGFyZW5hcykKKyAgICAgICAgICAgIHJldHVybiBOVUxMOyAgICAgICAgICAgICAgICAvKiBvdmVyZmxvdyAqLworI2lmIFNJWkVPRl9TSVpFX1QgPD0gU0laRU9GX0lOVAorICAgICAgICBpZiAobnVtYXJlbmFzID4gUFlfU0laRV9NQVggLyBzaXplb2YoKmFyZW5hcykpCisgICAgICAgICAgICByZXR1cm4gTlVMTDsgICAgICAgICAgICAgICAgLyogb3ZlcmZsb3cgKi8KKyNlbmRpZgorICAgICAgICBuYnl0ZXMgPSBudW1hcmVuYXMgKiBzaXplb2YoKmFyZW5hcyk7CisgICAgICAgIGFyZW5hb2JqID0gKHN0cnVjdCBhcmVuYV9vYmplY3QgKilyZWFsbG9jKGFyZW5hcywgbmJ5dGVzKTsKKyAgICAgICAgaWYgKGFyZW5hb2JqID09IE5VTEwpCisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgYXJlbmFzID0gYXJlbmFvYmo7CisKKyAgICAgICAgLyogV2UgbWlnaHQgbmVlZCB0byBmaXggcG9pbnRlcnMgdGhhdCB3ZXJlIGNvcGllZC4gIEhvd2V2ZXIsCisgICAgICAgICAqIG5ld19hcmVuYSBvbmx5IGdldHMgY2FsbGVkIHdoZW4gYWxsIHRoZSBwYWdlcyBpbiB0aGUKKyAgICAgICAgICogcHJldmlvdXMgYXJlbmFzIGFyZSBmdWxsLiAgVGh1cywgdGhlcmUgYXJlICpubyogcG9pbnRlcnMKKyAgICAgICAgICogaW50byB0aGUgb2xkIGFycmF5LiBUaHVzLCB3ZSBkb24ndCBoYXZlIHRvIHdvcnJ5IGFib3V0CisgICAgICAgICAqIGludmFsaWQgcG9pbnRlcnMuICBKdXN0IHRvIGJlIHN1cmUsIHNvbWUgYXNzZXJ0czoKKyAgICAgICAgICovCisgICAgICAgIGFzc2VydCh1c2FibGVfYXJlbmFzID09IE5VTEwpOworICAgICAgICBhc3NlcnQodW51c2VkX2FyZW5hX29iamVjdHMgPT0gTlVMTCk7CisKKyAgICAgICAgLyogUHV0IHRoZSBuZXcgYXJlbmFzIG9uIHRoZSB1bnVzZWRfYXJlbmFfb2JqZWN0cyBsaXN0LiAqLworICAgICAgICBmb3IgKGkgPSBtYXhhcmVuYXM7IGkgPCBudW1hcmVuYXM7ICsraSkgeworICAgICAgICAgICAgYXJlbmFzW2ldLmFkZHJlc3MgPSAwOyAgICAgICAgICAgICAgLyogbWFyayBhcyB1bmFzc29jaWF0ZWQgKi8KKyAgICAgICAgICAgIGFyZW5hc1tpXS5uZXh0YXJlbmEgPSBpIDwgbnVtYXJlbmFzIC0gMSA/CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZhcmVuYXNbaSsxXSA6IE5VTEw7CisgICAgICAgIH0KKworICAgICAgICAvKiBVcGRhdGUgZ2xvYmFscy4gKi8KKyAgICAgICAgdW51c2VkX2FyZW5hX29iamVjdHMgPSAmYXJlbmFzW21heGFyZW5hc107CisgICAgICAgIG1heGFyZW5hcyA9IG51bWFyZW5hczsKKyAgICB9CisKKyAgICAvKiBUYWtlIHRoZSBuZXh0IGF2YWlsYWJsZSBhcmVuYSBvYmplY3Qgb2ZmIHRoZSBoZWFkIG9mIHRoZSBsaXN0LiAqLworICAgIGFzc2VydCh1bnVzZWRfYXJlbmFfb2JqZWN0cyAhPSBOVUxMKTsKKyAgICBhcmVuYW9iaiA9IHVudXNlZF9hcmVuYV9vYmplY3RzOworICAgIHVudXNlZF9hcmVuYV9vYmplY3RzID0gYXJlbmFvYmotPm5leHRhcmVuYTsKKyAgICBhc3NlcnQoYXJlbmFvYmotPmFkZHJlc3MgPT0gMCk7CisgICAgYXJlbmFvYmotPmFkZHJlc3MgPSAodXB0ciltYWxsb2MoQVJFTkFfU0laRSk7CisgICAgaWYgKGFyZW5hb2JqLT5hZGRyZXNzID09IDApIHsKKyAgICAgICAgLyogVGhlIGFsbG9jYXRpb24gZmFpbGVkOiByZXR1cm4gTlVMTCBhZnRlciBwdXR0aW5nIHRoZQorICAgICAgICAgKiBhcmVuYW9iaiBiYWNrLgorICAgICAgICAgKi8KKyAgICAgICAgYXJlbmFvYmotPm5leHRhcmVuYSA9IHVudXNlZF9hcmVuYV9vYmplY3RzOworICAgICAgICB1bnVzZWRfYXJlbmFfb2JqZWN0cyA9IGFyZW5hb2JqOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisKKyAgICArK25hcmVuYXNfY3VycmVudGx5X2FsbG9jYXRlZDsKKyNpZmRlZiBQWU1BTExPQ19ERUJVRworICAgICsrbnRpbWVzX2FyZW5hX2FsbG9jYXRlZDsKKyAgICBpZiAobmFyZW5hc19jdXJyZW50bHlfYWxsb2NhdGVkID4gbmFyZW5hc19oaWdod2F0ZXIpCisgICAgICAgIG5hcmVuYXNfaGlnaHdhdGVyID0gbmFyZW5hc19jdXJyZW50bHlfYWxsb2NhdGVkOworI2VuZGlmCisgICAgYXJlbmFvYmotPmZyZWVwb29scyA9IE5VTEw7CisgICAgLyogcG9vbF9hZGRyZXNzIDwtIGZpcnN0IHBvb2wtYWxpZ25lZCBhZGRyZXNzIGluIHRoZSBhcmVuYQorICAgICAgIG5mcmVlcG9vbHMgPC0gbnVtYmVyIG9mIHdob2xlIHBvb2xzIHRoYXQgZml0IGFmdGVyIGFsaWdubWVudCAqLworICAgIGFyZW5hb2JqLT5wb29sX2FkZHJlc3MgPSAoYmxvY2sqKWFyZW5hb2JqLT5hZGRyZXNzOworICAgIGFyZW5hb2JqLT5uZnJlZXBvb2xzID0gQVJFTkFfU0laRSAvIFBPT0xfU0laRTsKKyAgICBhc3NlcnQoUE9PTF9TSVpFICogYXJlbmFvYmotPm5mcmVlcG9vbHMgPT0gQVJFTkFfU0laRSk7CisgICAgZXhjZXNzID0gKHVpbnQpKGFyZW5hb2JqLT5hZGRyZXNzICYgUE9PTF9TSVpFX01BU0spOworICAgIGlmIChleGNlc3MgIT0gMCkgeworICAgICAgICAtLWFyZW5hb2JqLT5uZnJlZXBvb2xzOworICAgICAgICBhcmVuYW9iai0+cG9vbF9hZGRyZXNzICs9IFBPT0xfU0laRSAtIGV4Y2VzczsKKyAgICB9CisgICAgYXJlbmFvYmotPm50b3RhbHBvb2xzID0gYXJlbmFvYmotPm5mcmVlcG9vbHM7CisKKyAgICByZXR1cm4gYXJlbmFvYmo7Cit9CisKKy8qCitQeV9BRERSRVNTX0lOX1JBTkdFKFAsIFBPT0wpCisKK1JldHVybiB0cnVlIGlmIGFuZCBvbmx5IGlmIFAgaXMgYW4gYWRkcmVzcyB0aGF0IHdhcyBhbGxvY2F0ZWQgYnkgcHltYWxsb2MuCitQT09MIG11c3QgYmUgdGhlIHBvb2wgYWRkcmVzcyBhc3NvY2lhdGVkIHdpdGggUCwgaS5lLiwgUE9PTCA9IFBPT0xfQUREUihQKQorKHRoZSBjYWxsZXIgaXMgYXNrZWQgdG8gY29tcHV0ZSB0aGlzIGJlY2F1c2UgdGhlIG1hY3JvIGV4cGFuZHMgUE9PTCBtb3JlIHRoYW4KK29uY2UsIGFuZCBmb3IgZWZmaWNpZW5jeSBpdCdzIGJlc3QgZm9yIHRoZSBjYWxsZXIgdG8gYXNzaWduIFBPT0xfQUREUihQKSB0byBhCit2YXJpYWJsZSBhbmQgcGFzcyB0aGUgbGF0dGVyIHRvIHRoZSBtYWNybzsgYmVjYXVzZSBQeV9BRERSRVNTX0lOX1JBTkdFIGlzCitjYWxsZWQgb24gZXZlcnkgYWxsb2MvcmVhbGxvYy9mcmVlLCBtaWNyby1lZmZpY2llbmN5IGlzIGltcG9ydGFudCBoZXJlKS4KKworVHJpY2t5OiAgTGV0IEIgYmUgdGhlIGFyZW5hIGJhc2UgYWRkcmVzcyBhc3NvY2lhdGVkIHdpdGggdGhlIHBvb2wsIEIgPQorYXJlbmFzWyhQT09MKS0+YXJlbmFpbmRleF0uYWRkcmVzcy4gIFRoZW4gUCBiZWxvbmdzIHRvIHRoZSBhcmVuYSBpZiBhbmQgb25seSBpZgorCisgICAgQiA8PSBQIDwgQiArIEFSRU5BX1NJWkUKKworU3VidHJhY3RpbmcgQiB0aHJvdWdob3V0LCB0aGlzIGlzIHRydWUgaWZmCisKKyAgICAwIDw9IFAtQiA8IEFSRU5BX1NJWkUKKworQnkgdXNpbmcgdW5zaWduZWQgYXJpdGhtZXRpYywgdGhlICIwIDw9IiBoYWxmIG9mIHRoZSB0ZXN0IGNhbiBiZSBza2lwcGVkLgorCitPYnNjdXJlOiAgQSBQeU1lbSAiZnJlZSBtZW1vcnkiIGZ1bmN0aW9uIGNhbiBjYWxsIHRoZSBweW1hbGxvYyBmcmVlIG9yIHJlYWxsb2MKK2JlZm9yZSB0aGUgZmlyc3QgYXJlbmEgaGFzIGJlZW4gYWxsb2NhdGVkLiAgYGFyZW5hc2AgaXMgc3RpbGwgTlVMTCBpbiB0aGF0CitjYXNlLiAgV2UncmUgcmVseWluZyBvbiB0aGF0IG1heGFyZW5hcyBpcyBhbHNvIDAgaW4gdGhhdCBjYXNlLCBzbyB0aGF0CisoUE9PTCktPmFyZW5haW5kZXggPCBtYXhhcmVuYXMgIG11c3QgYmUgZmFsc2UsIHNhdmluZyB1cyBmcm9tIHRyeWluZyB0byBpbmRleAoraW50byBhIE5VTEwgYXJlbmFzLgorCitEZXRhaWxzOiAgZ2l2ZW4gUCBhbmQgUE9PTCwgdGhlIGFyZW5hX29iamVjdCBjb3JyZXNwb25kaW5nIHRvIFAgaXMgQU8gPQorYXJlbmFzWyhQT09MKS0+YXJlbmFpbmRleF0uICBTdXBwb3NlIG9ibWFsbG9jIGNvbnRyb2xzIFAuICBUaGVuIChiYXJyaW5nIHdpbGQKK3N0b3JlcywgZXRjKSwgUE9PTCBpcyB0aGUgY29ycmVjdCBhZGRyZXNzIG9mIFAncyBwb29sLCBBTy5hZGRyZXNzIGlzIHRoZQorY29ycmVjdCBiYXNlIGFkZHJlc3Mgb2YgdGhlIHBvb2wncyBhcmVuYSwgYW5kIFAgbXVzdCBiZSB3aXRoaW4gQVJFTkFfU0laRSBvZgorQU8uYWRkcmVzcy4gIEluIGFkZGl0aW9uLCBBTy5hZGRyZXNzIGlzIG5vdCAwIChubyBhcmVuYSBjYW4gc3RhcnQgYXQgYWRkcmVzcyAwCisoTlVMTCkpLiAgVGhlcmVmb3JlIFB5X0FERFJFU1NfSU5fUkFOR0UgY29ycmVjdGx5IHJlcG9ydHMgdGhhdCBvYm1hbGxvYworY29udHJvbHMgUC4KKworTm93IHN1cHBvc2Ugb2JtYWxsb2MgZG9lcyBub3QgY29udHJvbCBQIChlLmcuLCBQIHdhcyBvYnRhaW5lZCB2aWEgYSBkaXJlY3QKK2NhbGwgdG8gdGhlIHN5c3RlbSBtYWxsb2MoKSBvciByZWFsbG9jKCkpLiAgKFBPT0wpLT5hcmVuYWluZGV4IG1heSBiZSBhbnl0aGluZworaW4gdGhpcyBjYXNlIC0tIGl0IG1heSBldmVuIGJlIHVuaW5pdGlhbGl6ZWQgdHJhc2guICBJZiB0aGUgdHJhc2ggYXJlbmFpbmRleAoraXMgPj0gbWF4YXJlbmFzLCB0aGUgbWFjcm8gY29ycmVjdGx5IGNvbmNsdWRlcyBhdCBvbmNlIHRoYXQgb2JtYWxsb2MgZG9lc24ndAorY29udHJvbCBQLgorCitFbHNlIGFyZW5haW5kZXggaXMgPCBtYXhhcmVuYSwgYW5kIEFPIGlzIHJlYWQgdXAuICBJZiBBTyBjb3JyZXNwb25kcyB0byBhbgorYWxsb2NhdGVkIGFyZW5hLCBvYm1hbGxvYyBjb250cm9scyBhbGwgdGhlIG1lbW9yeSBpbiBzbGljZSBBTy5hZGRyZXNzIDoKK0FPLmFkZHJlc3MrQVJFTkFfU0laRS4gIEJ5IGNhc2UgYXNzdW1wdGlvbiwgUCBpcyBub3QgY29udHJvbGxlZCBieSBvYm1hbGxvYywKK3NvIFAgZG9lc24ndCBsaWUgaW4gdGhhdCBzbGljZSwgc28gdGhlIG1hY3JvIGNvcnJlY3RseSByZXBvcnRzIHRoYXQgUCBpcyBub3QKK2NvbnRyb2xsZWQgYnkgb2JtYWxsb2MuCisKK0ZpbmFsbHksIGlmIFAgaXMgbm90IGNvbnRyb2xsZWQgYnkgb2JtYWxsb2MgYW5kIEFPIGNvcnJlc3BvbmRzIHRvIGFuIHVudXNlZAorYXJlbmFfb2JqZWN0IChvbmUgbm90IGN1cnJlbnRseSBhc3NvY2lhdGVkIHdpdGggYW4gYWxsb2NhdGVkIGFyZW5hKSwKK0FPLmFkZHJlc3MgaXMgMCwgYW5kIHRoZSBzZWNvbmQgdGVzdCBpbiB0aGUgbWFjcm8gcmVkdWNlcyB0bzoKKworICAgIFAgPCBBUkVOQV9TSVpFCisKK0lmIFAgPj0gQVJFTkFfU0laRSAoZXh0cmVtZWx5IGxpa2VseSksIHRoZSBtYWNybyBhZ2FpbiBjb3JyZWN0bHkgY29uY2x1ZGVzCit0aGF0IFAgaXMgbm90IGNvbnRyb2xsZWQgYnkgb2JtYWxsb2MuICBIb3dldmVyLCBpZiBQIDwgQVJFTkFfU0laRSwgdGhpcyBwYXJ0CitvZiB0aGUgdGVzdCBzdGlsbCBwYXNzZXMsIGFuZCB0aGUgdGhpcmQgY2xhdXNlIChBTy5hZGRyZXNzICE9IDApIGlzIG5lY2Vzc2FyeQordG8gZ2V0IHRoZSBjb3JyZWN0IHJlc3VsdDogIEFPLmFkZHJlc3MgaXMgMCBpbiB0aGlzIGNhc2UsIHNvIHRoZSBtYWNybworY29ycmVjdGx5IHJlcG9ydHMgdGhhdCBQIGlzIG5vdCBjb250cm9sbGVkIGJ5IG9ibWFsbG9jIChkZXNwaXRlIHRoYXQgUCBsaWVzIGluCitzbGljZSBBTy5hZGRyZXNzIDogQU8uYWRkcmVzcyArIEFSRU5BX1NJWkUpLgorCitOb3RlOiAgVGhlIHRoaXJkIChBTy5hZGRyZXNzICE9IDApIGNsYXVzZSB3YXMgYWRkZWQgaW4gUHl0aG9uIDIuNS4gIEJlZm9yZQorMi41LCBhcmVuYXMgd2VyZSBuZXZlciBmcmVlKCknZWQsIGFuZCBhbiBhcmVuYWluZGV4IDwgbWF4YXJlbmEgYWx3YXlzCitjb3JyZXNwb25kZWQgdG8gYSBjdXJyZW50bHktYWxsb2NhdGVkIGFyZW5hLCBzbyB0aGUgIlAgaXMgbm90IGNvbnRyb2xsZWQgYnkKK29ibWFsbG9jLCBBTyBjb3JyZXNwb25kcyB0byBhbiB1bnVzZWQgYXJlbmFfb2JqZWN0LCBhbmQgUCA8IEFSRU5BX1NJWkUiIGNhc2UKK3dhcyBpbXBvc3NpYmxlLgorCitOb3RlIHRoYXQgdGhlIGxvZ2ljIGlzIGV4Y3J1Y2lhdGluZywgYW5kIHJlYWRpbmcgdXAgcG9zc2libHkgdW5pbml0aWFsaXplZAorbWVtb3J5IHdoZW4gUCBpcyBub3QgY29udHJvbGxlZCBieSBvYm1hbGxvYyAodG8gZ2V0IGF0IChQT09MKS0+YXJlbmFpbmRleCkKK2NyZWF0ZXMgcHJvYmxlbXMgZm9yIHNvbWUgbWVtb3J5IGRlYnVnZ2Vycy4gIFRoZSBvdmVyd2hlbG1pbmcgYWR2YW50YWdlIGlzCit0aGF0IHRoaXMgdGVzdCBkZXRlcm1pbmVzIHdoZXRoZXIgYW4gYXJiaXRyYXJ5IGFkZHJlc3MgaXMgY29udHJvbGxlZCBieQorb2JtYWxsb2MgaW4gYSBzbWFsbCBjb25zdGFudCB0aW1lLCBpbmRlcGVuZGVudCBvZiB0aGUgbnVtYmVyIG9mIGFyZW5hcworb2JtYWxsb2MgY29udHJvbHMuICBTaW5jZSB0aGlzIHRlc3QgaXMgbmVlZGVkIGF0IGV2ZXJ5IGVudHJ5IHBvaW50LCBpdCdzCitleHRyZW1lbHkgZGVzaXJhYmxlIHRoYXQgaXQgYmUgdGhpcyBmYXN0LgorCitTaW5jZSBQeV9BRERSRVNTX0lOX1JBTkdFIG1heSBiZSByZWFkaW5nIGZyb20gbWVtb3J5IHdoaWNoIHdhcyBub3QgYWxsb2NhdGVkCitieSBQeXRob24sIGl0IGlzIGltcG9ydGFudCB0aGF0IChQT09MKS0+YXJlbmFpbmRleCBpcyByZWFkIG9ubHkgb25jZSwgYXMKK2Fub3RoZXIgdGhyZWFkIG1heSBiZSBjb25jdXJyZW50bHkgbW9kaWZ5aW5nIHRoZSB2YWx1ZSB3aXRob3V0IGhvbGRpbmcgdGhlCitHSUwuICBUbyBhY2NvbXBsaXNoIHRoaXMsIHRoZSBhcmVuYWluZGV4X3RlbXAgdmFyaWFibGUgaXMgdXNlZCB0byBzdG9yZQorKFBPT0wpLT5hcmVuYWluZGV4IGZvciB0aGUgZHVyYXRpb24gb2YgdGhlIFB5X0FERFJFU1NfSU5fUkFOR0UgbWFjcm8ncworZXhlY3V0aW9uLiAgVGhlIGNhbGxlciBvZiB0aGUgbWFjcm8gaXMgcmVzcG9uc2libGUgZm9yIGRlY2xhcmluZyB0aGlzCit2YXJpYWJsZS4KKyovCisjZGVmaW5lIFB5X0FERFJFU1NfSU5fUkFOR0UoUCwgUE9PTCkgICAgICAgICAgICAgICAgICAgIFwKKyAgICAoKGFyZW5haW5kZXhfdGVtcCA9IChQT09MKS0+YXJlbmFpbmRleCkgPCBtYXhhcmVuYXMgJiYgICAgICAgICAgICAgIFwKKyAgICAgKHVwdHIpKFApIC0gYXJlbmFzW2FyZW5haW5kZXhfdGVtcF0uYWRkcmVzcyA8ICh1cHRyKUFSRU5BX1NJWkUgJiYgXAorICAgICBhcmVuYXNbYXJlbmFpbmRleF90ZW1wXS5hZGRyZXNzICE9IDApCisKKworLyogVGhpcyBpcyBvbmx5IHVzZWZ1bCB3aGVuIHJ1bm5pbmcgbWVtb3J5IGRlYnVnZ2VycyBzdWNoIGFzCisgKiBQdXJpZnkgb3IgVmFsZ3JpbmQuICBVbmNvbW1lbnQgdG8gdXNlLgorICoKKyNkZWZpbmUgUHlfVVNJTkdfTUVNT1JZX0RFQlVHR0VSCisgKi8KKworI2lmZGVmIFB5X1VTSU5HX01FTU9SWV9ERUJVR0dFUgorCisvKiBQeV9BRERSRVNTX0lOX1JBTkdFIG1heSBhY2Nlc3MgdW5pbml0aWFsaXplZCBtZW1vcnkgYnkgZGVzaWduCisgKiBUaGlzIGxlYWRzIHRvIHRob3VzYW5kcyBvZiBzcHVyaW91cyB3YXJuaW5ncyB3aGVuIHVzaW5nCisgKiBQdXJpZnkgb3IgVmFsZ3JpbmQuICBCeSBtYWtpbmcgYSBmdW5jdGlvbiwgd2UgY2FuIGVhc2lseQorICogc3VwcHJlc3MgdGhlIHVuaW5pdGlhbGl6ZWQgbWVtb3J5IHJlYWRzIGluIHRoaXMgb25lIGZ1bmN0aW9uLgorICogU28gd2Ugd29uJ3QgaWdub3JlIHJlYWwgZXJyb3JzIGVsc2V3aGVyZS4KKyAqCisgKiBEaXNhYmxlIHRoZSBtYWNybyBhbmQgdXNlIGEgZnVuY3Rpb24uCisgKi8KKworI3VuZGVmIFB5X0FERFJFU1NfSU5fUkFOR0UKKworI2lmIGRlZmluZWQoX19HTlVDX18pICYmICgoX19HTlVDX18gPT0gMykgJiYgKF9fR05VQ19NSU5PUl9fID49IDEpIHx8IFwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgKF9fR05VQ19fID49IDQpKQorI2RlZmluZSBQeV9OT19JTkxJTkUgX19hdHRyaWJ1dGVfXygoX19ub2lubGluZV9fKSkKKyNlbHNlCisjZGVmaW5lIFB5X05PX0lOTElORQorI2VuZGlmCisKKy8qIERvbid0IG1ha2Ugc3RhdGljLCB0byB0cnkgdG8gZW5zdXJlIHRoaXMgaXNuJ3QgaW5saW5lZC4gKi8KK2ludCBQeV9BRERSRVNTX0lOX1JBTkdFKHZvaWQgKlAsIHBvb2xwIHBvb2wpIFB5X05PX0lOTElORTsKKyN1bmRlZiBQeV9OT19JTkxJTkUKKyNlbmRpZgorCisvKj09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ki8KKworLyogbWFsbG9jLiAgTm90ZSB0aGF0IG5ieXRlcz09MCB0cmllcyB0byByZXR1cm4gYSBub24tTlVMTCBwb2ludGVyLCBkaXN0aW5jdAorICogZnJvbSBhbGwgb3RoZXIgY3VycmVudGx5IGxpdmUgcG9pbnRlcnMuICBUaGlzIG1heSBub3QgYmUgcG9zc2libGUuCisgKi8KKworLyoKKyAqIFRoZSBiYXNpYyBibG9ja3MgYXJlIG9yZGVyZWQgYnkgZGVjcmVhc2luZyBleGVjdXRpb24gZnJlcXVlbmN5LAorICogd2hpY2ggbWluaW1pemVzIHRoZSBudW1iZXIgb2YganVtcHMgaW4gdGhlIG1vc3QgY29tbW9uIGNhc2VzLAorICogaW1wcm92ZXMgYnJhbmNoaW5nIHByZWRpY3Rpb24gYW5kIGluc3RydWN0aW9uIHNjaGVkdWxpbmcgKHNtYWxsCisgKiBibG9jayBhbGxvY2F0aW9ucyB0eXBpY2FsbHkgcmVzdWx0IGluIGEgY291cGxlIG9mIGluc3RydWN0aW9ucykuCisgKiBVbmxlc3MgdGhlIG9wdGltaXplciByZW9yZGVycyBldmVyeXRoaW5nLCBiZWluZyB0b28gc21hcnQuLi4KKyAqLworCisjdW5kZWYgUHlPYmplY3RfTWFsbG9jCit2b2lkICoKK1B5T2JqZWN0X01hbGxvYyhzaXplX3QgbmJ5dGVzKQoreworICAgIGJsb2NrICpicDsKKyAgICBwb29scCBwb29sOworICAgIHBvb2xwIG5leHQ7CisgICAgdWludCBzaXplOworCisjaWZkZWYgV0lUSF9WQUxHUklORAorICAgIGlmIChVTkxJS0VMWShydW5uaW5nX29uX3ZhbGdyaW5kID09IC0xKSkKKyAgICAgICAgcnVubmluZ19vbl92YWxncmluZCA9IFJVTk5JTkdfT05fVkFMR1JJTkQ7CisgICAgaWYgKFVOTElLRUxZKHJ1bm5pbmdfb25fdmFsZ3JpbmQpKQorICAgICAgICBnb3RvIHJlZGlyZWN0OworI2VuZGlmCisKKyAgICAvKgorICAgICAqIExpbWl0IG91cnNlbHZlcyB0byBQWV9TU0laRV9UX01BWCBieXRlcyB0byBwcmV2ZW50IHNlY3VyaXR5IGhvbGVzLgorICAgICAqIE1vc3QgcHl0aG9uIGludGVybmFscyBibGluZGx5IHVzZSBhIHNpZ25lZCBQeV9zc2l6ZV90IHRvIHRyYWNrCisgICAgICogdGhpbmdzIHdpdGhvdXQgY2hlY2tpbmcgZm9yIG92ZXJmbG93cyBvciBuZWdhdGl2ZXMuCisgICAgICogQXMgc2l6ZV90IGlzIHVuc2lnbmVkLCBjaGVja2luZyBmb3IgbmJ5dGVzIDwgMCBpcyBub3QgcmVxdWlyZWQuCisgICAgICovCisgICAgaWYgKG5ieXRlcyA+IFBZX1NTSVpFX1RfTUFYKQorICAgICAgICByZXR1cm4gTlVMTDsKKworICAgIC8qCisgICAgICogVGhpcyBpbXBsaWNpdGx5IHJlZGlyZWN0cyBtYWxsb2MoMCkuCisgICAgICovCisgICAgaWYgKChuYnl0ZXMgLSAxKSA8IFNNQUxMX1JFUVVFU1RfVEhSRVNIT0xEKSB7CisgICAgICAgIExPQ0soKTsKKyAgICAgICAgLyoKKyAgICAgICAgICogTW9zdCBmcmVxdWVudCBwYXRocyBmaXJzdAorICAgICAgICAgKi8KKyAgICAgICAgc2l6ZSA9ICh1aW50KShuYnl0ZXMgLSAxKSA+PiBBTElHTk1FTlRfU0hJRlQ7CisgICAgICAgIHBvb2wgPSB1c2VkcG9vbHNbc2l6ZSArIHNpemVdOworICAgICAgICBpZiAocG9vbCAhPSBwb29sLT5uZXh0cG9vbCkgeworICAgICAgICAgICAgLyoKKyAgICAgICAgICAgICAqIFRoZXJlIGlzIGEgdXNlZCBwb29sIGZvciB0aGlzIHNpemUgY2xhc3MuCisgICAgICAgICAgICAgKiBQaWNrIHVwIHRoZSBoZWFkIGJsb2NrIG9mIGl0cyBmcmVlIGxpc3QuCisgICAgICAgICAgICAgKi8KKyAgICAgICAgICAgICsrcG9vbC0+cmVmLmNvdW50OworICAgICAgICAgICAgYnAgPSBwb29sLT5mcmVlYmxvY2s7CisgICAgICAgICAgICBhc3NlcnQoYnAgIT0gTlVMTCk7CisgICAgICAgICAgICBpZiAoKHBvb2wtPmZyZWVibG9jayA9ICooYmxvY2sgKiopYnApICE9IE5VTEwpIHsKKyAgICAgICAgICAgICAgICBVTkxPQ0soKTsKKyAgICAgICAgICAgICAgICByZXR1cm4gKHZvaWQgKilicDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIC8qCisgICAgICAgICAgICAgKiBSZWFjaGVkIHRoZSBlbmQgb2YgdGhlIGZyZWUgbGlzdCwgdHJ5IHRvIGV4dGVuZCBpdC4KKyAgICAgICAgICAgICAqLworICAgICAgICAgICAgaWYgKHBvb2wtPm5leHRvZmZzZXQgPD0gcG9vbC0+bWF4bmV4dG9mZnNldCkgeworICAgICAgICAgICAgICAgIC8qIFRoZXJlIGlzIHJvb20gZm9yIGFub3RoZXIgYmxvY2suICovCisgICAgICAgICAgICAgICAgcG9vbC0+ZnJlZWJsb2NrID0gKGJsb2NrKilwb29sICsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwb29sLT5uZXh0b2Zmc2V0OworICAgICAgICAgICAgICAgIHBvb2wtPm5leHRvZmZzZXQgKz0gSU5ERVgyU0laRShzaXplKTsKKyAgICAgICAgICAgICAgICAqKGJsb2NrICoqKShwb29sLT5mcmVlYmxvY2spID0gTlVMTDsKKyAgICAgICAgICAgICAgICBVTkxPQ0soKTsKKyAgICAgICAgICAgICAgICByZXR1cm4gKHZvaWQgKilicDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIC8qIFBvb2wgaXMgZnVsbCwgdW5saW5rIGZyb20gdXNlZCBwb29scy4gKi8KKyAgICAgICAgICAgIG5leHQgPSBwb29sLT5uZXh0cG9vbDsKKyAgICAgICAgICAgIHBvb2wgPSBwb29sLT5wcmV2cG9vbDsKKyAgICAgICAgICAgIG5leHQtPnByZXZwb29sID0gcG9vbDsKKyAgICAgICAgICAgIHBvb2wtPm5leHRwb29sID0gbmV4dDsKKyAgICAgICAgICAgIFVOTE9DSygpOworICAgICAgICAgICAgcmV0dXJuICh2b2lkICopYnA7CisgICAgICAgIH0KKworICAgICAgICAvKiBUaGVyZSBpc24ndCBhIHBvb2wgb2YgdGhlIHJpZ2h0IHNpemUgY2xhc3MgaW1tZWRpYXRlbHkKKyAgICAgICAgICogYXZhaWxhYmxlOiAgdXNlIGEgZnJlZSBwb29sLgorICAgICAgICAgKi8KKyAgICAgICAgaWYgKHVzYWJsZV9hcmVuYXMgPT0gTlVMTCkgeworICAgICAgICAgICAgLyogTm8gYXJlbmEgaGFzIGEgZnJlZSBwb29sOiAgYWxsb2NhdGUgYSBuZXcgYXJlbmEuICovCisjaWZkZWYgV0lUSF9NRU1PUllfTElNSVRTCisgICAgICAgICAgICBpZiAobmFyZW5hc19jdXJyZW50bHlfYWxsb2NhdGVkID49IE1BWF9BUkVOQVMpIHsKKyAgICAgICAgICAgICAgICBVTkxPQ0soKTsKKyAgICAgICAgICAgICAgICBnb3RvIHJlZGlyZWN0OworICAgICAgICAgICAgfQorI2VuZGlmCisgICAgICAgICAgICB1c2FibGVfYXJlbmFzID0gbmV3X2FyZW5hKCk7CisgICAgICAgICAgICBpZiAodXNhYmxlX2FyZW5hcyA9PSBOVUxMKSB7CisgICAgICAgICAgICAgICAgVU5MT0NLKCk7CisgICAgICAgICAgICAgICAgZ290byByZWRpcmVjdDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHVzYWJsZV9hcmVuYXMtPm5leHRhcmVuYSA9CisgICAgICAgICAgICAgICAgdXNhYmxlX2FyZW5hcy0+cHJldmFyZW5hID0gTlVMTDsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnQodXNhYmxlX2FyZW5hcy0+YWRkcmVzcyAhPSAwKTsKKworICAgICAgICAvKiBUcnkgdG8gZ2V0IGEgY2FjaGVkIGZyZWUgcG9vbC4gKi8KKyAgICAgICAgcG9vbCA9IHVzYWJsZV9hcmVuYXMtPmZyZWVwb29sczsKKyAgICAgICAgaWYgKHBvb2wgIT0gTlVMTCkgeworICAgICAgICAgICAgLyogVW5saW5rIGZyb20gY2FjaGVkIHBvb2xzLiAqLworICAgICAgICAgICAgdXNhYmxlX2FyZW5hcy0+ZnJlZXBvb2xzID0gcG9vbC0+bmV4dHBvb2w7CisKKyAgICAgICAgICAgIC8qIFRoaXMgYXJlbmEgYWxyZWFkeSBoYWQgdGhlIHNtYWxsZXN0IG5mcmVlcG9vbHMKKyAgICAgICAgICAgICAqIHZhbHVlLCBzbyBkZWNyZWFzaW5nIG5mcmVlcG9vbHMgZG9lc24ndCBjaGFuZ2UKKyAgICAgICAgICAgICAqIHRoYXQsIGFuZCB3ZSBkb24ndCBuZWVkIHRvIHJlYXJyYW5nZSB0aGUKKyAgICAgICAgICAgICAqIHVzYWJsZV9hcmVuYXMgbGlzdC4gIEhvd2V2ZXIsIGlmIHRoZSBhcmVuYSBoYXMKKyAgICAgICAgICAgICAqIGJlY29tZSB3aG9sbHkgYWxsb2NhdGVkLCB3ZSBuZWVkIHRvIHJlbW92ZSBpdHMKKyAgICAgICAgICAgICAqIGFyZW5hX29iamVjdCBmcm9tIHVzYWJsZV9hcmVuYXMuCisgICAgICAgICAgICAgKi8KKyAgICAgICAgICAgIC0tdXNhYmxlX2FyZW5hcy0+bmZyZWVwb29sczsKKyAgICAgICAgICAgIGlmICh1c2FibGVfYXJlbmFzLT5uZnJlZXBvb2xzID09IDApIHsKKyAgICAgICAgICAgICAgICAvKiBXaG9sbHkgYWxsb2NhdGVkOiAgcmVtb3ZlLiAqLworICAgICAgICAgICAgICAgIGFzc2VydCh1c2FibGVfYXJlbmFzLT5mcmVlcG9vbHMgPT0gTlVMTCk7CisgICAgICAgICAgICAgICAgYXNzZXJ0KHVzYWJsZV9hcmVuYXMtPm5leHRhcmVuYSA9PSBOVUxMIHx8CisgICAgICAgICAgICAgICAgICAgICAgIHVzYWJsZV9hcmVuYXMtPm5leHRhcmVuYS0+cHJldmFyZW5hID09CisgICAgICAgICAgICAgICAgICAgICAgIHVzYWJsZV9hcmVuYXMpOworCisgICAgICAgICAgICAgICAgdXNhYmxlX2FyZW5hcyA9IHVzYWJsZV9hcmVuYXMtPm5leHRhcmVuYTsKKyAgICAgICAgICAgICAgICBpZiAodXNhYmxlX2FyZW5hcyAhPSBOVUxMKSB7CisgICAgICAgICAgICAgICAgICAgIHVzYWJsZV9hcmVuYXMtPnByZXZhcmVuYSA9IE5VTEw7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydCh1c2FibGVfYXJlbmFzLT5hZGRyZXNzICE9IDApOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGVsc2UgeworICAgICAgICAgICAgICAgIC8qIG5mcmVlcG9vbHMgPiAwOiAgaXQgbXVzdCBiZSB0aGF0IGZyZWVwb29scworICAgICAgICAgICAgICAgICAqIGlzbid0IE5VTEwsIG9yIHRoYXQgd2UgaGF2ZW4ndCB5ZXQgY2FydmVkCisgICAgICAgICAgICAgICAgICogb2ZmIGFsbCB0aGUgYXJlbmEncyBwb29scyBmb3IgdGhlIGZpcnN0CisgICAgICAgICAgICAgICAgICogdGltZS4KKyAgICAgICAgICAgICAgICAgKi8KKyAgICAgICAgICAgICAgICBhc3NlcnQodXNhYmxlX2FyZW5hcy0+ZnJlZXBvb2xzICE9IE5VTEwgfHwKKyAgICAgICAgICAgICAgICAgICAgICAgdXNhYmxlX2FyZW5hcy0+cG9vbF9hZGRyZXNzIDw9CisgICAgICAgICAgICAgICAgICAgICAgIChibG9jayopdXNhYmxlX2FyZW5hcy0+YWRkcmVzcyArCisgICAgICAgICAgICAgICAgICAgICAgICAgICBBUkVOQV9TSVpFIC0gUE9PTF9TSVpFKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgaW5pdF9wb29sOgorICAgICAgICAgICAgLyogRnJvbnRsaW5rIHRvIHVzZWQgcG9vbHMuICovCisgICAgICAgICAgICBuZXh0ID0gdXNlZHBvb2xzW3NpemUgKyBzaXplXTsgLyogPT0gcHJldiAqLworICAgICAgICAgICAgcG9vbC0+bmV4dHBvb2wgPSBuZXh0OworICAgICAgICAgICAgcG9vbC0+cHJldnBvb2wgPSBuZXh0OworICAgICAgICAgICAgbmV4dC0+bmV4dHBvb2wgPSBwb29sOworICAgICAgICAgICAgbmV4dC0+cHJldnBvb2wgPSBwb29sOworICAgICAgICAgICAgcG9vbC0+cmVmLmNvdW50ID0gMTsKKyAgICAgICAgICAgIGlmIChwb29sLT5zemlkeCA9PSBzaXplKSB7CisgICAgICAgICAgICAgICAgLyogTHVja2lseSwgdGhpcyBwb29sIGxhc3QgY29udGFpbmVkIGJsb2NrcworICAgICAgICAgICAgICAgICAqIG9mIHRoZSBzYW1lIHNpemUgY2xhc3MsIHNvIGl0cyBoZWFkZXIKKyAgICAgICAgICAgICAgICAgKiBhbmQgZnJlZSBsaXN0IGFyZSBhbHJlYWR5IGluaXRpYWxpemVkLgorICAgICAgICAgICAgICAgICAqLworICAgICAgICAgICAgICAgIGJwID0gcG9vbC0+ZnJlZWJsb2NrOworICAgICAgICAgICAgICAgIHBvb2wtPmZyZWVibG9jayA9ICooYmxvY2sgKiopYnA7CisgICAgICAgICAgICAgICAgVU5MT0NLKCk7CisgICAgICAgICAgICAgICAgcmV0dXJuICh2b2lkICopYnA7CisgICAgICAgICAgICB9CisgICAgICAgICAgICAvKgorICAgICAgICAgICAgICogSW5pdGlhbGl6ZSB0aGUgcG9vbCBoZWFkZXIsIHNldCB1cCB0aGUgZnJlZSBsaXN0IHRvCisgICAgICAgICAgICAgKiBjb250YWluIGp1c3QgdGhlIHNlY29uZCBibG9jaywgYW5kIHJldHVybiB0aGUgZmlyc3QKKyAgICAgICAgICAgICAqIGJsb2NrLgorICAgICAgICAgICAgICovCisgICAgICAgICAgICBwb29sLT5zemlkeCA9IHNpemU7CisgICAgICAgICAgICBzaXplID0gSU5ERVgyU0laRShzaXplKTsKKyAgICAgICAgICAgIGJwID0gKGJsb2NrICopcG9vbCArIFBPT0xfT1ZFUkhFQUQ7CisgICAgICAgICAgICBwb29sLT5uZXh0b2Zmc2V0ID0gUE9PTF9PVkVSSEVBRCArIChzaXplIDw8IDEpOworICAgICAgICAgICAgcG9vbC0+bWF4bmV4dG9mZnNldCA9IFBPT0xfU0laRSAtIHNpemU7CisgICAgICAgICAgICBwb29sLT5mcmVlYmxvY2sgPSBicCArIHNpemU7CisgICAgICAgICAgICAqKGJsb2NrICoqKShwb29sLT5mcmVlYmxvY2spID0gTlVMTDsKKyAgICAgICAgICAgIFVOTE9DSygpOworICAgICAgICAgICAgcmV0dXJuICh2b2lkICopYnA7CisgICAgICAgIH0KKworICAgICAgICAvKiBDYXJ2ZSBvZmYgYSBuZXcgcG9vbC4gKi8KKyAgICAgICAgYXNzZXJ0KHVzYWJsZV9hcmVuYXMtPm5mcmVlcG9vbHMgPiAwKTsKKyAgICAgICAgYXNzZXJ0KHVzYWJsZV9hcmVuYXMtPmZyZWVwb29scyA9PSBOVUxMKTsKKyAgICAgICAgcG9vbCA9IChwb29scCl1c2FibGVfYXJlbmFzLT5wb29sX2FkZHJlc3M7CisgICAgICAgIGFzc2VydCgoYmxvY2sqKXBvb2wgPD0gKGJsb2NrKil1c2FibGVfYXJlbmFzLT5hZGRyZXNzICsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBUkVOQV9TSVpFIC0gUE9PTF9TSVpFKTsKKyAgICAgICAgcG9vbC0+YXJlbmFpbmRleCA9IHVzYWJsZV9hcmVuYXMgLSBhcmVuYXM7CisgICAgICAgIGFzc2VydCgmYXJlbmFzW3Bvb2wtPmFyZW5haW5kZXhdID09IHVzYWJsZV9hcmVuYXMpOworICAgICAgICBwb29sLT5zemlkeCA9IERVTU1ZX1NJWkVfSURYOworICAgICAgICB1c2FibGVfYXJlbmFzLT5wb29sX2FkZHJlc3MgKz0gUE9PTF9TSVpFOworICAgICAgICAtLXVzYWJsZV9hcmVuYXMtPm5mcmVlcG9vbHM7CisKKyAgICAgICAgaWYgKHVzYWJsZV9hcmVuYXMtPm5mcmVlcG9vbHMgPT0gMCkgeworICAgICAgICAgICAgYXNzZXJ0KHVzYWJsZV9hcmVuYXMtPm5leHRhcmVuYSA9PSBOVUxMIHx8CisgICAgICAgICAgICAgICAgICAgdXNhYmxlX2FyZW5hcy0+bmV4dGFyZW5hLT5wcmV2YXJlbmEgPT0KKyAgICAgICAgICAgICAgICAgICB1c2FibGVfYXJlbmFzKTsKKyAgICAgICAgICAgIC8qIFVubGluayB0aGUgYXJlbmE6ICBpdCBpcyBjb21wbGV0ZWx5IGFsbG9jYXRlZC4gKi8KKyAgICAgICAgICAgIHVzYWJsZV9hcmVuYXMgPSB1c2FibGVfYXJlbmFzLT5uZXh0YXJlbmE7CisgICAgICAgICAgICBpZiAodXNhYmxlX2FyZW5hcyAhPSBOVUxMKSB7CisgICAgICAgICAgICAgICAgdXNhYmxlX2FyZW5hcy0+cHJldmFyZW5hID0gTlVMTDsKKyAgICAgICAgICAgICAgICBhc3NlcnQodXNhYmxlX2FyZW5hcy0+YWRkcmVzcyAhPSAwKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgICAgIGdvdG8gaW5pdF9wb29sOworICAgIH0KKworICAgIC8qIFRoZSBzbWFsbCBibG9jayBhbGxvY2F0b3IgZW5kcyBoZXJlLiAqLworCityZWRpcmVjdDoKKyAgICAvKiBSZWRpcmVjdCB0aGUgb3JpZ2luYWwgcmVxdWVzdCB0byB0aGUgdW5kZXJseWluZyAobGliYykgYWxsb2NhdG9yLgorICAgICAqIFdlIGp1bXAgaGVyZSBvbiBiaWdnZXIgcmVxdWVzdHMsIG9uIGVycm9yIGluIHRoZSBjb2RlIGFib3ZlIChhcyBhCisgICAgICogbGFzdCBjaGFuY2UgdG8gc2VydmUgdGhlIHJlcXVlc3QpIG9yIHdoZW4gdGhlIG1heCBtZW1vcnkgbGltaXQKKyAgICAgKiBoYXMgYmVlbiByZWFjaGVkLgorICAgICAqLworICAgIGlmIChuYnl0ZXMgPT0gMCkKKyAgICAgICAgbmJ5dGVzID0gMTsKKyAgICByZXR1cm4gKHZvaWQgKiltYWxsb2MobmJ5dGVzKTsKK30KKworLyogZnJlZSAqLworCisjdW5kZWYgUHlPYmplY3RfRnJlZQordm9pZAorUHlPYmplY3RfRnJlZSh2b2lkICpwKQoreworICAgIHBvb2xwIHBvb2w7CisgICAgYmxvY2sgKmxhc3RmcmVlOworICAgIHBvb2xwIG5leHQsIHByZXY7CisgICAgdWludCBzaXplOworI2lmbmRlZiBQeV9VU0lOR19NRU1PUllfREVCVUdHRVIKKyAgICB1aW50IGFyZW5haW5kZXhfdGVtcDsKKyNlbmRpZgorCisgICAgaWYgKHAgPT0gTlVMTCkgICAgICAvKiBmcmVlKE5VTEwpIGhhcyBubyBlZmZlY3QgKi8KKyAgICAgICAgcmV0dXJuOworCisjaWZkZWYgV0lUSF9WQUxHUklORAorICAgIGlmIChVTkxJS0VMWShydW5uaW5nX29uX3ZhbGdyaW5kID4gMCkpCisgICAgICAgIGdvdG8gcmVkaXJlY3Q7CisjZW5kaWYKKworICAgIHBvb2wgPSBQT09MX0FERFIocCk7CisgICAgaWYgKFB5X0FERFJFU1NfSU5fUkFOR0UocCwgcG9vbCkpIHsKKyAgICAgICAgLyogV2UgYWxsb2NhdGVkIHRoaXMgYWRkcmVzcy4gKi8KKyAgICAgICAgTE9DSygpOworICAgICAgICAvKiBMaW5rIHAgdG8gdGhlIHN0YXJ0IG9mIHRoZSBwb29sJ3MgZnJlZWJsb2NrIGxpc3QuICBTaW5jZQorICAgICAgICAgKiB0aGUgcG9vbCBoYWQgYXQgbGVhc3QgdGhlIHAgYmxvY2sgb3V0c3RhbmRpbmcsIHRoZSBwb29sCisgICAgICAgICAqIHdhc24ndCBlbXB0eSAoc28gaXQncyBhbHJlYWR5IGluIGEgdXNlZHBvb2xzW10gbGlzdCwgb3IKKyAgICAgICAgICogd2FzIGZ1bGwgYW5kIGlzIGluIG5vIGxpc3QgLS0gaXQncyBub3QgaW4gdGhlIGZyZWVibG9ja3MKKyAgICAgICAgICogbGlzdCBpbiBhbnkgY2FzZSkuCisgICAgICAgICAqLworICAgICAgICBhc3NlcnQocG9vbC0+cmVmLmNvdW50ID4gMCk7ICAgICAgICAgICAgLyogZWxzZSBpdCB3YXMgZW1wdHkgKi8KKyAgICAgICAgKihibG9jayAqKilwID0gbGFzdGZyZWUgPSBwb29sLT5mcmVlYmxvY2s7CisgICAgICAgIHBvb2wtPmZyZWVibG9jayA9IChibG9jayAqKXA7CisgICAgICAgIGlmIChsYXN0ZnJlZSkgeworICAgICAgICAgICAgc3RydWN0IGFyZW5hX29iamVjdCogYW87CisgICAgICAgICAgICB1aW50IG5mOyAgLyogYW8tPm5mcmVlcG9vbHMgKi8KKworICAgICAgICAgICAgLyogZnJlZWJsb2NrIHdhc24ndCBOVUxMLCBzbyB0aGUgcG9vbCB3YXNuJ3QgZnVsbCwKKyAgICAgICAgICAgICAqIGFuZCB0aGUgcG9vbCBpcyBpbiBhIHVzZWRwb29sc1tdIGxpc3QuCisgICAgICAgICAgICAgKi8KKyAgICAgICAgICAgIGlmICgtLXBvb2wtPnJlZi5jb3VudCAhPSAwKSB7CisgICAgICAgICAgICAgICAgLyogcG9vbCBpc24ndCBlbXB0eTogIGxlYXZlIGl0IGluIHVzZWRwb29scyAqLworICAgICAgICAgICAgICAgIFVOTE9DSygpOworICAgICAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIC8qIFBvb2wgaXMgbm93IGVtcHR5OiAgdW5saW5rIGZyb20gdXNlZHBvb2xzLCBhbmQKKyAgICAgICAgICAgICAqIGxpbmsgdG8gdGhlIGZyb250IG9mIGZyZWVwb29scy4gIFRoaXMgZW5zdXJlcyB0aGF0CisgICAgICAgICAgICAgKiBwcmV2aW91c2x5IGZyZWVkIHBvb2xzIHdpbGwgYmUgYWxsb2NhdGVkIGxhdGVyCisgICAgICAgICAgICAgKiAoYmVpbmcgbm90IHJlZmVyZW5jZWQsIHRoZXkgYXJlIHBlcmhhcHMgcGFnZWQgb3V0KS4KKyAgICAgICAgICAgICAqLworICAgICAgICAgICAgbmV4dCA9IHBvb2wtPm5leHRwb29sOworICAgICAgICAgICAgcHJldiA9IHBvb2wtPnByZXZwb29sOworICAgICAgICAgICAgbmV4dC0+cHJldnBvb2wgPSBwcmV2OworICAgICAgICAgICAgcHJldi0+bmV4dHBvb2wgPSBuZXh0OworCisgICAgICAgICAgICAvKiBMaW5rIHRoZSBwb29sIHRvIGZyZWVwb29scy4gIFRoaXMgaXMgYSBzaW5nbHktbGlua2VkCisgICAgICAgICAgICAgKiBsaXN0LCBhbmQgcG9vbC0+cHJldnBvb2wgaXNuJ3QgdXNlZCB0aGVyZS4KKyAgICAgICAgICAgICAqLworICAgICAgICAgICAgYW8gPSAmYXJlbmFzW3Bvb2wtPmFyZW5haW5kZXhdOworICAgICAgICAgICAgcG9vbC0+bmV4dHBvb2wgPSBhby0+ZnJlZXBvb2xzOworICAgICAgICAgICAgYW8tPmZyZWVwb29scyA9IHBvb2w7CisgICAgICAgICAgICBuZiA9ICsrYW8tPm5mcmVlcG9vbHM7CisKKyAgICAgICAgICAgIC8qIEFsbCB0aGUgcmVzdCBpcyBhcmVuYSBtYW5hZ2VtZW50LiAgV2UganVzdCBmcmVlZAorICAgICAgICAgICAgICogYSBwb29sLCBhbmQgdGhlcmUgYXJlIDQgY2FzZXMgZm9yIGFyZW5hIG1nbXQ6CisgICAgICAgICAgICAgKiAxLiBJZiBhbGwgdGhlIHBvb2xzIGFyZSBmcmVlLCByZXR1cm4gdGhlIGFyZW5hIHRvCisgICAgICAgICAgICAgKiAgICB0aGUgc3lzdGVtIGZyZWUoKS4KKyAgICAgICAgICAgICAqIDIuIElmIHRoaXMgaXMgdGhlIG9ubHkgZnJlZSBwb29sIGluIHRoZSBhcmVuYSwKKyAgICAgICAgICAgICAqICAgIGFkZCB0aGUgYXJlbmEgYmFjayB0byB0aGUgYHVzYWJsZV9hcmVuYXNgIGxpc3QuCisgICAgICAgICAgICAgKiAzLiBJZiB0aGUgIm5leHQiIGFyZW5hIGhhcyBhIHNtYWxsZXIgY291bnQgb2YgZnJlZQorICAgICAgICAgICAgICogICAgcG9vbHMsIHdlIGhhdmUgdG8gInNsaWRlIHRoaXMgYXJlbmEgcmlnaHQiIHRvCisgICAgICAgICAgICAgKiAgICByZXN0b3JlIHRoYXQgdXNhYmxlX2FyZW5hcyBpcyBzb3J0ZWQgaW4gb3JkZXIgb2YKKyAgICAgICAgICAgICAqICAgIG5mcmVlcG9vbHMuCisgICAgICAgICAgICAgKiA0LiBFbHNlIHRoZXJlJ3Mgbm90aGluZyBtb3JlIHRvIGRvLgorICAgICAgICAgICAgICovCisgICAgICAgICAgICBpZiAobmYgPT0gYW8tPm50b3RhbHBvb2xzKSB7CisgICAgICAgICAgICAgICAgLyogQ2FzZSAxLiAgRmlyc3QgdW5saW5rIGFvIGZyb20gdXNhYmxlX2FyZW5hcy4KKyAgICAgICAgICAgICAgICAgKi8KKyAgICAgICAgICAgICAgICBhc3NlcnQoYW8tPnByZXZhcmVuYSA9PSBOVUxMIHx8CisgICAgICAgICAgICAgICAgICAgICAgIGFvLT5wcmV2YXJlbmEtPmFkZHJlc3MgIT0gMCk7CisgICAgICAgICAgICAgICAgYXNzZXJ0KGFvIC0+bmV4dGFyZW5hID09IE5VTEwgfHwKKyAgICAgICAgICAgICAgICAgICAgICAgYW8tPm5leHRhcmVuYS0+YWRkcmVzcyAhPSAwKTsKKworICAgICAgICAgICAgICAgIC8qIEZpeCB0aGUgcG9pbnRlciBpbiB0aGUgcHJldmFyZW5hLCBvciB0aGUKKyAgICAgICAgICAgICAgICAgKiB1c2FibGVfYXJlbmFzIHBvaW50ZXIuCisgICAgICAgICAgICAgICAgICovCisgICAgICAgICAgICAgICAgaWYgKGFvLT5wcmV2YXJlbmEgPT0gTlVMTCkgeworICAgICAgICAgICAgICAgICAgICB1c2FibGVfYXJlbmFzID0gYW8tPm5leHRhcmVuYTsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0KHVzYWJsZV9hcmVuYXMgPT0gTlVMTCB8fAorICAgICAgICAgICAgICAgICAgICAgICAgICAgdXNhYmxlX2FyZW5hcy0+YWRkcmVzcyAhPSAwKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIGFzc2VydChhby0+cHJldmFyZW5hLT5uZXh0YXJlbmEgPT0gYW8pOworICAgICAgICAgICAgICAgICAgICBhby0+cHJldmFyZW5hLT5uZXh0YXJlbmEgPQorICAgICAgICAgICAgICAgICAgICAgICAgYW8tPm5leHRhcmVuYTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgLyogRml4IHRoZSBwb2ludGVyIGluIHRoZSBuZXh0YXJlbmEuICovCisgICAgICAgICAgICAgICAgaWYgKGFvLT5uZXh0YXJlbmEgIT0gTlVMTCkgeworICAgICAgICAgICAgICAgICAgICBhc3NlcnQoYW8tPm5leHRhcmVuYS0+cHJldmFyZW5hID09IGFvKTsKKyAgICAgICAgICAgICAgICAgICAgYW8tPm5leHRhcmVuYS0+cHJldmFyZW5hID0KKyAgICAgICAgICAgICAgICAgICAgICAgIGFvLT5wcmV2YXJlbmE7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIC8qIFJlY29yZCB0aGF0IHRoaXMgYXJlbmFfb2JqZWN0IHNsb3QgaXMKKyAgICAgICAgICAgICAgICAgKiBhdmFpbGFibGUgdG8gYmUgcmV1c2VkLgorICAgICAgICAgICAgICAgICAqLworICAgICAgICAgICAgICAgIGFvLT5uZXh0YXJlbmEgPSB1bnVzZWRfYXJlbmFfb2JqZWN0czsKKyAgICAgICAgICAgICAgICB1bnVzZWRfYXJlbmFfb2JqZWN0cyA9IGFvOworCisgICAgICAgICAgICAgICAgLyogRnJlZSB0aGUgZW50aXJlIGFyZW5hLiAqLworICAgICAgICAgICAgICAgIGZyZWUoKHZvaWQgKilhby0+YWRkcmVzcyk7CisgICAgICAgICAgICAgICAgYW8tPmFkZHJlc3MgPSAwOyAgICAgICAgICAgICAgICAgICAgICAgIC8qIG1hcmsgdW5hc3NvY2lhdGVkICovCisgICAgICAgICAgICAgICAgLS1uYXJlbmFzX2N1cnJlbnRseV9hbGxvY2F0ZWQ7CisKKyAgICAgICAgICAgICAgICBVTkxPQ0soKTsKKyAgICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAobmYgPT0gMSkgeworICAgICAgICAgICAgICAgIC8qIENhc2UgMi4gIFB1dCBhbyBhdCB0aGUgaGVhZCBvZgorICAgICAgICAgICAgICAgICAqIHVzYWJsZV9hcmVuYXMuICBOb3RlIHRoYXQgYmVjYXVzZQorICAgICAgICAgICAgICAgICAqIGFvLT5uZnJlZXBvb2xzIHdhcyAwIGJlZm9yZSwgYW8gaXNuJ3QKKyAgICAgICAgICAgICAgICAgKiBjdXJyZW50bHkgb24gdGhlIHVzYWJsZV9hcmVuYXMgbGlzdC4KKyAgICAgICAgICAgICAgICAgKi8KKyAgICAgICAgICAgICAgICBhby0+bmV4dGFyZW5hID0gdXNhYmxlX2FyZW5hczsKKyAgICAgICAgICAgICAgICBhby0+cHJldmFyZW5hID0gTlVMTDsKKyAgICAgICAgICAgICAgICBpZiAodXNhYmxlX2FyZW5hcykKKyAgICAgICAgICAgICAgICAgICAgdXNhYmxlX2FyZW5hcy0+cHJldmFyZW5hID0gYW87CisgICAgICAgICAgICAgICAgdXNhYmxlX2FyZW5hcyA9IGFvOworICAgICAgICAgICAgICAgIGFzc2VydCh1c2FibGVfYXJlbmFzLT5hZGRyZXNzICE9IDApOworCisgICAgICAgICAgICAgICAgVU5MT0NLKCk7CisgICAgICAgICAgICAgICAgcmV0dXJuOworICAgICAgICAgICAgfQorICAgICAgICAgICAgLyogSWYgdGhpcyBhcmVuYSBpcyBub3cgb3V0IG9mIG9yZGVyLCB3ZSBuZWVkIHRvIGtlZXAKKyAgICAgICAgICAgICAqIHRoZSBsaXN0IHNvcnRlZC4gIFRoZSBsaXN0IGlzIGtlcHQgc29ydGVkIHNvIHRoYXQKKyAgICAgICAgICAgICAqIHRoZSAibW9zdCBmdWxsIiBhcmVuYXMgYXJlIHVzZWQgZmlyc3QsIHdoaWNoIGFsbG93cworICAgICAgICAgICAgICogdGhlIG5lYXJseSBlbXB0eSBhcmVuYXMgdG8gYmUgY29tcGxldGVseSBmcmVlZC4gIEluCisgICAgICAgICAgICAgKiBhIGZldyB1bi1zY2llbnRpZmljIHRlc3RzLCBpdCBzZWVtcyBsaWtlIHRoaXMKKyAgICAgICAgICAgICAqIGFwcHJvYWNoIGFsbG93ZWQgYSBsb3QgbW9yZSBtZW1vcnkgdG8gYmUgZnJlZWQuCisgICAgICAgICAgICAgKi8KKyAgICAgICAgICAgIGlmIChhby0+bmV4dGFyZW5hID09IE5VTEwgfHwKKyAgICAgICAgICAgICAgICAgICAgICAgICBuZiA8PSBhby0+bmV4dGFyZW5hLT5uZnJlZXBvb2xzKSB7CisgICAgICAgICAgICAgICAgLyogQ2FzZSA0LiAgTm90aGluZyB0byBkby4gKi8KKyAgICAgICAgICAgICAgICBVTkxPQ0soKTsKKyAgICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICB9CisgICAgICAgICAgICAvKiBDYXNlIDM6ICBXZSBoYXZlIHRvIG1vdmUgdGhlIGFyZW5hIHRvd2FyZHMgdGhlIGVuZAorICAgICAgICAgICAgICogb2YgdGhlIGxpc3QsIGJlY2F1c2UgaXQgaGFzIG1vcmUgZnJlZSBwb29scyB0aGFuCisgICAgICAgICAgICAgKiB0aGUgYXJlbmEgdG8gaXRzIHJpZ2h0LgorICAgICAgICAgICAgICogRmlyc3QgdW5saW5rIGFvIGZyb20gdXNhYmxlX2FyZW5hcy4KKyAgICAgICAgICAgICAqLworICAgICAgICAgICAgaWYgKGFvLT5wcmV2YXJlbmEgIT0gTlVMTCkgeworICAgICAgICAgICAgICAgIC8qIGFvIGlzbid0IGF0IHRoZSBoZWFkIG9mIHRoZSBsaXN0ICovCisgICAgICAgICAgICAgICAgYXNzZXJ0KGFvLT5wcmV2YXJlbmEtPm5leHRhcmVuYSA9PSBhbyk7CisgICAgICAgICAgICAgICAgYW8tPnByZXZhcmVuYS0+bmV4dGFyZW5hID0gYW8tPm5leHRhcmVuYTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGVsc2UgeworICAgICAgICAgICAgICAgIC8qIGFvIGlzIGF0IHRoZSBoZWFkIG9mIHRoZSBsaXN0ICovCisgICAgICAgICAgICAgICAgYXNzZXJ0KHVzYWJsZV9hcmVuYXMgPT0gYW8pOworICAgICAgICAgICAgICAgIHVzYWJsZV9hcmVuYXMgPSBhby0+bmV4dGFyZW5hOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYW8tPm5leHRhcmVuYS0+cHJldmFyZW5hID0gYW8tPnByZXZhcmVuYTsKKworICAgICAgICAgICAgLyogTG9jYXRlIHRoZSBuZXcgaW5zZXJ0aW9uIHBvaW50IGJ5IGl0ZXJhdGluZyBvdmVyCisgICAgICAgICAgICAgKiB0aGUgbGlzdCwgdXNpbmcgb3VyIG5leHRhcmVuYSBwb2ludGVyLgorICAgICAgICAgICAgICovCisgICAgICAgICAgICB3aGlsZSAoYW8tPm5leHRhcmVuYSAhPSBOVUxMICYmCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmYgPiBhby0+bmV4dGFyZW5hLT5uZnJlZXBvb2xzKSB7CisgICAgICAgICAgICAgICAgYW8tPnByZXZhcmVuYSA9IGFvLT5uZXh0YXJlbmE7CisgICAgICAgICAgICAgICAgYW8tPm5leHRhcmVuYSA9IGFvLT5uZXh0YXJlbmEtPm5leHRhcmVuYTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgLyogSW5zZXJ0IGFvIGF0IHRoaXMgcG9pbnQuICovCisgICAgICAgICAgICBhc3NlcnQoYW8tPm5leHRhcmVuYSA9PSBOVUxMIHx8CisgICAgICAgICAgICAgICAgYW8tPnByZXZhcmVuYSA9PSBhby0+bmV4dGFyZW5hLT5wcmV2YXJlbmEpOworICAgICAgICAgICAgYXNzZXJ0KGFvLT5wcmV2YXJlbmEtPm5leHRhcmVuYSA9PSBhby0+bmV4dGFyZW5hKTsKKworICAgICAgICAgICAgYW8tPnByZXZhcmVuYS0+bmV4dGFyZW5hID0gYW87CisgICAgICAgICAgICBpZiAoYW8tPm5leHRhcmVuYSAhPSBOVUxMKQorICAgICAgICAgICAgICAgIGFvLT5uZXh0YXJlbmEtPnByZXZhcmVuYSA9IGFvOworCisgICAgICAgICAgICAvKiBWZXJpZnkgdGhhdCB0aGUgc3dhcHMgd29ya2VkLiAqLworICAgICAgICAgICAgYXNzZXJ0KGFvLT5uZXh0YXJlbmEgPT0gTlVMTCB8fAorICAgICAgICAgICAgICAgICAgICAgIG5mIDw9IGFvLT5uZXh0YXJlbmEtPm5mcmVlcG9vbHMpOworICAgICAgICAgICAgYXNzZXJ0KGFvLT5wcmV2YXJlbmEgPT0gTlVMTCB8fAorICAgICAgICAgICAgICAgICAgICAgIG5mID4gYW8tPnByZXZhcmVuYS0+bmZyZWVwb29scyk7CisgICAgICAgICAgICBhc3NlcnQoYW8tPm5leHRhcmVuYSA9PSBOVUxMIHx8CisgICAgICAgICAgICAgICAgYW8tPm5leHRhcmVuYS0+cHJldmFyZW5hID09IGFvKTsKKyAgICAgICAgICAgIGFzc2VydCgodXNhYmxlX2FyZW5hcyA9PSBhbyAmJgorICAgICAgICAgICAgICAgIGFvLT5wcmV2YXJlbmEgPT0gTlVMTCkgfHwKKyAgICAgICAgICAgICAgICBhby0+cHJldmFyZW5hLT5uZXh0YXJlbmEgPT0gYW8pOworCisgICAgICAgICAgICBVTkxPQ0soKTsKKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgICAgICAvKiBQb29sIHdhcyBmdWxsLCBzbyBkb2Vzbid0IGN1cnJlbnRseSBsaXZlIGluIGFueSBsaXN0OgorICAgICAgICAgKiBsaW5rIGl0IHRvIHRoZSBmcm9udCBvZiB0aGUgYXBwcm9wcmlhdGUgdXNlZHBvb2xzW10gbGlzdC4KKyAgICAgICAgICogVGhpcyBtaW1pY3MgTFJVIHBvb2wgdXNhZ2UgZm9yIG5ldyBhbGxvY2F0aW9ucyBhbmQKKyAgICAgICAgICogdGFyZ2V0cyBvcHRpbWFsIGZpbGxpbmcgd2hlbiBzZXZlcmFsIHBvb2xzIGNvbnRhaW4KKyAgICAgICAgICogYmxvY2tzIG9mIHRoZSBzYW1lIHNpemUgY2xhc3MuCisgICAgICAgICAqLworICAgICAgICAtLXBvb2wtPnJlZi5jb3VudDsKKyAgICAgICAgYXNzZXJ0KHBvb2wtPnJlZi5jb3VudCA+IDApOyAgICAgICAgICAgIC8qIGVsc2UgdGhlIHBvb2wgaXMgZW1wdHkgKi8KKyAgICAgICAgc2l6ZSA9IHBvb2wtPnN6aWR4OworICAgICAgICBuZXh0ID0gdXNlZHBvb2xzW3NpemUgKyBzaXplXTsKKyAgICAgICAgcHJldiA9IG5leHQtPnByZXZwb29sOworICAgICAgICAvKiBpbnNlcnQgcG9vbCBiZWZvcmUgbmV4dDogICBwcmV2IDwtPiBwb29sIDwtPiBuZXh0ICovCisgICAgICAgIHBvb2wtPm5leHRwb29sID0gbmV4dDsKKyAgICAgICAgcG9vbC0+cHJldnBvb2wgPSBwcmV2OworICAgICAgICBuZXh0LT5wcmV2cG9vbCA9IHBvb2w7CisgICAgICAgIHByZXYtPm5leHRwb29sID0gcG9vbDsKKyAgICAgICAgVU5MT0NLKCk7CisgICAgICAgIHJldHVybjsKKyAgICB9CisKKyNpZmRlZiBXSVRIX1ZBTEdSSU5ECityZWRpcmVjdDoKKyNlbmRpZgorICAgIC8qIFdlIGRpZG4ndCBhbGxvY2F0ZSB0aGlzIGFkZHJlc3MuICovCisgICAgZnJlZShwKTsKK30KKworLyogcmVhbGxvYy4gIElmIHAgaXMgTlVMTCwgdGhpcyBhY3RzIGxpa2UgbWFsbG9jKG5ieXRlcykuICBFbHNlIGlmIG5ieXRlcz09MCwKKyAqIHRoZW4gYXMgdGhlIFB5dGhvbiBkb2NzIHByb21pc2UsIHdlIGRvIG5vdCB0cmVhdCB0aGlzIGxpa2UgZnJlZShwKSwgYW5kCisgKiByZXR1cm4gYSBub24tTlVMTCByZXN1bHQuCisgKi8KKworI3VuZGVmIFB5T2JqZWN0X1JlYWxsb2MKK3ZvaWQgKgorUHlPYmplY3RfUmVhbGxvYyh2b2lkICpwLCBzaXplX3QgbmJ5dGVzKQoreworICAgIHZvaWQgKmJwOworICAgIHBvb2xwIHBvb2w7CisgICAgc2l6ZV90IHNpemU7CisjaWZuZGVmIFB5X1VTSU5HX01FTU9SWV9ERUJVR0dFUgorICAgIHVpbnQgYXJlbmFpbmRleF90ZW1wOworI2VuZGlmCisKKyAgICBpZiAocCA9PSBOVUxMKQorICAgICAgICByZXR1cm4gUHlPYmplY3RfTWFsbG9jKG5ieXRlcyk7CisKKyAgICAvKgorICAgICAqIExpbWl0IG91cnNlbHZlcyB0byBQWV9TU0laRV9UX01BWCBieXRlcyB0byBwcmV2ZW50IHNlY3VyaXR5IGhvbGVzLgorICAgICAqIE1vc3QgcHl0aG9uIGludGVybmFscyBibGluZGx5IHVzZSBhIHNpZ25lZCBQeV9zc2l6ZV90IHRvIHRyYWNrCisgICAgICogdGhpbmdzIHdpdGhvdXQgY2hlY2tpbmcgZm9yIG92ZXJmbG93cyBvciBuZWdhdGl2ZXMuCisgICAgICogQXMgc2l6ZV90IGlzIHVuc2lnbmVkLCBjaGVja2luZyBmb3IgbmJ5dGVzIDwgMCBpcyBub3QgcmVxdWlyZWQuCisgICAgICovCisgICAgaWYgKG5ieXRlcyA+IFBZX1NTSVpFX1RfTUFYKQorICAgICAgICByZXR1cm4gTlVMTDsKKworI2lmZGVmIFdJVEhfVkFMR1JJTkQKKyAgICAvKiBUcmVhdCBydW5uaW5nX29uX3ZhbGdyaW5kID09IC0xIHRoZSBzYW1lIGFzIDAgKi8KKyAgICBpZiAoVU5MSUtFTFkocnVubmluZ19vbl92YWxncmluZCA+IDApKQorICAgICAgICBnb3RvIHJlZGlyZWN0OworI2VuZGlmCisKKyAgICBwb29sID0gUE9PTF9BRERSKHApOworICAgIGlmIChQeV9BRERSRVNTX0lOX1JBTkdFKHAsIHBvb2wpKSB7CisgICAgICAgIC8qIFdlJ3JlIGluIGNoYXJnZSBvZiB0aGlzIGJsb2NrICovCisgICAgICAgIHNpemUgPSBJTkRFWDJTSVpFKHBvb2wtPnN6aWR4KTsKKyAgICAgICAgaWYgKG5ieXRlcyA8PSBzaXplKSB7CisgICAgICAgICAgICAvKiBUaGUgYmxvY2sgaXMgc3RheWluZyB0aGUgc2FtZSBvciBzaHJpbmtpbmcuICBJZgorICAgICAgICAgICAgICogaXQncyBzaHJpbmtpbmcsIHRoZXJlJ3MgYSB0cmFkZW9mZjogIGl0IGNvc3RzCisgICAgICAgICAgICAgKiBjeWNsZXMgdG8gY29weSB0aGUgYmxvY2sgdG8gYSBzbWFsbGVyIHNpemUgY2xhc3MsCisgICAgICAgICAgICAgKiBidXQgaXQgd2FzdGVzIG1lbW9yeSBub3QgdG8gY29weSBpdC4gIFRoZQorICAgICAgICAgICAgICogY29tcHJvbWlzZSBoZXJlIGlzIHRvIGNvcHkgb24gc2hyaW5rIG9ubHkgaWYgYXQKKyAgICAgICAgICAgICAqIGxlYXN0IDI1JSBvZiBzaXplIGNhbiBiZSBzaGF2ZWQgb2ZmLgorICAgICAgICAgICAgICovCisgICAgICAgICAgICBpZiAoNCAqIG5ieXRlcyA+IDMgKiBzaXplKSB7CisgICAgICAgICAgICAgICAgLyogSXQncyB0aGUgc2FtZSwKKyAgICAgICAgICAgICAgICAgKiBvciBzaHJpbmtpbmcgYW5kIG5ldy9vbGQgPiAzLzQuCisgICAgICAgICAgICAgICAgICovCisgICAgICAgICAgICAgICAgcmV0dXJuIHA7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBzaXplID0gbmJ5dGVzOworICAgICAgICB9CisgICAgICAgIGJwID0gUHlPYmplY3RfTWFsbG9jKG5ieXRlcyk7CisgICAgICAgIGlmIChicCAhPSBOVUxMKSB7CisgICAgICAgICAgICBtZW1jcHkoYnAsIHAsIHNpemUpOworICAgICAgICAgICAgUHlPYmplY3RfRnJlZShwKTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gYnA7CisgICAgfQorI2lmZGVmIFdJVEhfVkFMR1JJTkQKKyByZWRpcmVjdDoKKyNlbmRpZgorICAgIC8qIFdlJ3JlIG5vdCBtYW5hZ2luZyB0aGlzIGJsb2NrLiAgSWYgbmJ5dGVzIDw9CisgICAgICogU01BTExfUkVRVUVTVF9USFJFU0hPTEQsIGl0J3MgdGVtcHRpbmcgdG8gdHJ5IHRvIHRha2Ugb3ZlciB0aGlzCisgICAgICogYmxvY2suICBIb3dldmVyLCBpZiB3ZSBkbywgd2UgbmVlZCB0byBjb3B5IHRoZSB2YWxpZCBkYXRhIGZyb20KKyAgICAgKiB0aGUgQy1tYW5hZ2VkIGJsb2NrIHRvIG9uZSBvZiBvdXIgYmxvY2tzLCBhbmQgdGhlcmUncyBubyBwb3J0YWJsZQorICAgICAqIHdheSB0byBrbm93IGhvdyBtdWNoIG9mIHRoZSBtZW1vcnkgc3BhY2Ugc3RhcnRpbmcgYXQgcCBpcyB2YWxpZC4KKyAgICAgKiBBcyBidWcgMTE4NTg4MyBwb2ludGVkIG91dCB0aGUgaGFyZCB3YXksIGl0J3MgcG9zc2libGUgdGhhdCB0aGUKKyAgICAgKiBDLW1hbmFnZWQgYmxvY2sgaXMgImF0IHRoZSBlbmQiIG9mIGFsbG9jYXRlZCBWTSBzcGFjZSwgc28gdGhhdAorICAgICAqIGEgbWVtb3J5IGZhdWx0IGNhbiBvY2N1ciBpZiB3ZSB0cnkgdG8gY29weSBuYnl0ZXMgYnl0ZXMgc3RhcnRpbmcKKyAgICAgKiBhdCBwLiAgSW5zdGVhZCB3ZSBwdW50OiAgbGV0IEMgY29udGludWUgdG8gbWFuYWdlIHRoaXMgYmxvY2suCisgICAgICovCisgICAgaWYgKG5ieXRlcykKKyAgICAgICAgcmV0dXJuIHJlYWxsb2MocCwgbmJ5dGVzKTsKKyAgICAvKiBDIGRvZXNuJ3QgZGVmaW5lIHRoZSByZXN1bHQgb2YgcmVhbGxvYyhwLCAwKSAoaXQgbWF5IG9yIG1heSBub3QKKyAgICAgKiByZXR1cm4gTlVMTCB0aGVuKSwgYnV0IFB5dGhvbidzIGRvY3MgcHJvbWlzZSB0aGF0IG5ieXRlcz09MCBuZXZlcgorICAgICAqIHJldHVybnMgTlVMTC4gIFdlIGRvbid0IHBhc3MgMCB0byByZWFsbG9jKCksIHRvIGF2b2lkIHRoYXQgZW5kY2FzZQorICAgICAqIHRvIGJlZ2luIHdpdGguICBFdmVuIHRoZW4sIHdlIGNhbid0IGJlIHN1cmUgdGhhdCByZWFsbG9jKCkgd29uJ3QKKyAgICAgKiByZXR1cm4gTlVMTC4KKyAgICAgKi8KKyAgICBicCA9IHJlYWxsb2MocCwgMSk7CisgICAgcmV0dXJuIGJwID8gYnAgOiBwOworfQorCisjZWxzZSAgIC8qICEgV0lUSF9QWU1BTExPQyAqLworCisvKj09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ki8KKy8qIHB5bWFsbG9jIG5vdCBlbmFibGVkOiAgUmVkaXJlY3QgdGhlIGVudHJ5IHBvaW50cyB0byBtYWxsb2MuICBUaGVzZSB3aWxsCisgKiBvbmx5IGJlIHVzZWQgYnkgZXh0ZW5zaW9ucyB0aGF0IGFyZSBjb21waWxlZCB3aXRoIHB5bWFsbG9jIGVuYWJsZWQuICovCisKK3ZvaWQgKgorUHlPYmplY3RfTWFsbG9jKHNpemVfdCBuKQoreworICAgIHJldHVybiBQeU1lbV9NQUxMT0Mobik7Cit9CisKK3ZvaWQgKgorUHlPYmplY3RfUmVhbGxvYyh2b2lkICpwLCBzaXplX3QgbikKK3sKKyAgICByZXR1cm4gUHlNZW1fUkVBTExPQyhwLCBuKTsKK30KKwordm9pZAorUHlPYmplY3RfRnJlZSh2b2lkICpwKQoreworICAgIFB5TWVtX0ZSRUUocCk7Cit9CisjZW5kaWYgLyogV0lUSF9QWU1BTExPQyAqLworCisjaWZkZWYgUFlNQUxMT0NfREVCVUcKKy8qPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0qLworLyogQSB4LXBsYXRmb3JtIGRlYnVnZ2luZyBhbGxvY2F0b3IuICBUaGlzIGRvZXNuJ3QgbWFuYWdlIG1lbW9yeSBkaXJlY3RseSwKKyAqIGl0IHdyYXBzIGEgcmVhbCBhbGxvY2F0b3IsIGFkZGluZyBleHRyYSBkZWJ1Z2dpbmcgaW5mbyB0byB0aGUgbWVtb3J5IGJsb2Nrcy4KKyAqLworCisvKiBTcGVjaWFsIGJ5dGVzIGJyb2FkY2FzdCBpbnRvIGRlYnVnIG1lbW9yeSBibG9ja3MgYXQgYXBwcm9wcmlhdGUgdGltZXMuCisgKiBTdHJpbmdzIG9mIHRoZXNlIGFyZSB1bmxpa2VseSB0byBiZSB2YWxpZCBhZGRyZXNzZXMsIGZsb2F0cywgaW50cyBvcgorICogNy1iaXQgQVNDSUkuCisgKi8KKyN1bmRlZiBDTEVBTkJZVEUKKyN1bmRlZiBERUFEQllURQorI3VuZGVmIEZPUkJJRERFTkJZVEUKKyNkZWZpbmUgQ0xFQU5CWVRFICAgICAgMHhDQiAgICAvKiBjbGVhbiAobmV3bHkgYWxsb2NhdGVkKSBtZW1vcnkgKi8KKyNkZWZpbmUgREVBREJZVEUgICAgICAgMHhEQiAgICAvKiBkZWFkIChuZXdseSBmcmVlZCkgbWVtb3J5ICovCisjZGVmaW5lIEZPUkJJRERFTkJZVEUgIDB4RkIgICAgLyogdW50b3VjaGFibGUgYnl0ZXMgYXQgZWFjaCBlbmQgb2YgYSBibG9jayAqLworCisvKiBXZSB0YWcgZWFjaCBibG9jayB3aXRoIGFuIEFQSSBJRCBpbiBvcmRlciB0byB0YWcgQVBJIHZpb2xhdGlvbnMgKi8KKyNkZWZpbmUgX1BZTUFMTE9DX01FTV9JRCAnbScgICAvKiB0aGUgUHlNZW1fTWFsbG9jKCkgQVBJICovCisjZGVmaW5lIF9QWU1BTExPQ19PQkpfSUQgJ28nICAgLyogVGhlIFB5T2JqZWN0X01hbGxvYygpIEFQSSAqLworCitzdGF0aWMgc2l6ZV90IHNlcmlhbG5vID0gMDsgICAgIC8qIGluY3JlbWVudGVkIG9uIGVhY2ggZGVidWcge20scmV9YWxsb2MgKi8KKworLyogc2VyaWFsbm8gaXMgYWx3YXlzIGluY3JlbWVudGVkIHZpYSBjYWxsaW5nIHRoaXMgcm91dGluZS4gIFRoZSBwb2ludCBpcworICogdG8gc3VwcGx5IGEgc2luZ2xlIHBsYWNlIHRvIHNldCBhIGJyZWFrcG9pbnQuCisgKi8KK3N0YXRpYyB2b2lkCitidW1wc2VyaWFsbm8odm9pZCkKK3sKKyAgICArK3NlcmlhbG5vOworfQorCisjZGVmaW5lIFNTVCBTSVpFT0ZfU0laRV9UCisKKy8qIFJlYWQgc2l6ZW9mKHNpemVfdCkgYnl0ZXMgYXQgcCBhcyBhIGJpZy1lbmRpYW4gc2l6ZV90LiAqLworc3RhdGljIHNpemVfdAorcmVhZF9zaXplX3QoY29uc3Qgdm9pZCAqcCkKK3sKKyAgICBjb25zdCB1Y2hhciAqcSA9IChjb25zdCB1Y2hhciAqKXA7CisgICAgc2l6ZV90IHJlc3VsdCA9ICpxKys7CisgICAgaW50IGk7CisKKyAgICBmb3IgKGkgPSBTU1Q7IC0taSA+IDA7ICsrcSkKKyAgICAgICAgcmVzdWx0ID0gKHJlc3VsdCA8PCA4KSB8ICpxOworICAgIHJldHVybiByZXN1bHQ7Cit9CisKKy8qIFdyaXRlIG4gYXMgYSBiaWctZW5kaWFuIHNpemVfdCwgTVNCIGF0IGFkZHJlc3MgcCwgTFNCIGF0CisgKiBwICsgc2l6ZW9mKHNpemVfdCkgLSAxLgorICovCitzdGF0aWMgdm9pZAord3JpdGVfc2l6ZV90KHZvaWQgKnAsIHNpemVfdCBuKQoreworICAgIHVjaGFyICpxID0gKHVjaGFyICopcCArIFNTVCAtIDE7CisgICAgaW50IGk7CisKKyAgICBmb3IgKGkgPSBTU1Q7IC0taSA+PSAwOyAtLXEpIHsKKyAgICAgICAgKnEgPSAodWNoYXIpKG4gJiAweGZmKTsKKyAgICAgICAgbiA+Pj0gODsKKyAgICB9Cit9CisKKyNpZmRlZiBQeV9ERUJVRworLyogSXMgdGFyZ2V0IGluIHRoZSBsaXN0PyAgVGhlIGxpc3QgaXMgdHJhdmVyc2VkIHZpYSB0aGUgbmV4dHBvb2wgcG9pbnRlcnMuCisgKiBUaGUgbGlzdCBtYXkgYmUgTlVMTC10ZXJtaW5hdGVkLCBvciBjaXJjdWxhci4gIFJldHVybiAxIGlmIHRhcmdldCBpcyBpbgorICogbGlzdCwgZWxzZSAwLgorICovCitzdGF0aWMgaW50Citwb29sX2lzX2luX2xpc3QoY29uc3QgcG9vbHAgdGFyZ2V0LCBwb29scCBsaXN0KQoreworICAgIHBvb2xwIG9yaWdsaXN0ID0gbGlzdDsKKyAgICBhc3NlcnQodGFyZ2V0ICE9IE5VTEwpOworICAgIGlmIChsaXN0ID09IE5VTEwpCisgICAgICAgIHJldHVybiAwOworICAgIGRvIHsKKyAgICAgICAgaWYgKHRhcmdldCA9PSBsaXN0KQorICAgICAgICAgICAgcmV0dXJuIDE7CisgICAgICAgIGxpc3QgPSBsaXN0LT5uZXh0cG9vbDsKKyAgICB9IHdoaWxlIChsaXN0ICE9IE5VTEwgJiYgbGlzdCAhPSBvcmlnbGlzdCk7CisgICAgcmV0dXJuIDA7Cit9CisKKyNlbHNlCisjZGVmaW5lIHBvb2xfaXNfaW5fbGlzdChYLCBZKSAxCisKKyNlbmRpZiAgLyogUHlfREVCVUcgKi8KKworLyogTGV0IFMgPSBzaXplb2Yoc2l6ZV90KS4gIFRoZSBkZWJ1ZyBtYWxsb2MgYXNrcyBmb3IgNCpTIGV4dHJhIGJ5dGVzIGFuZAorICAgZmlsbHMgdGhlbSB3aXRoIHVzZWZ1bCBzdHVmZiwgaGVyZSBjYWxsaW5nIHRoZSB1bmRlcmx5aW5nIG1hbGxvYydzIHJlc3VsdCBwOgorCitwWzA6IFNdCisgICAgTnVtYmVyIG9mIGJ5dGVzIG9yaWdpbmFsbHkgYXNrZWQgZm9yLiAgVGhpcyBpcyBhIHNpemVfdCwgYmlnLWVuZGlhbiAoZWFzaWVyCisgICAgdG8gcmVhZCBpbiBhIG1lbW9yeSBkdW1wKS4KK3BbUzogMipTXQorICAgIENvcGllcyBvZiBGT1JCSURERU5CWVRFLiAgVXNlZCB0byBjYXRjaCB1bmRlci0gd3JpdGVzIGFuZCByZWFkcy4KK3BbMipTOiAyKlMrbl0KKyAgICBUaGUgcmVxdWVzdGVkIG1lbW9yeSwgZmlsbGVkIHdpdGggY29waWVzIG9mIENMRUFOQllURS4KKyAgICBVc2VkIHRvIGNhdGNoIHJlZmVyZW5jZSB0byB1bmluaXRpYWxpemVkIG1lbW9yeS4KKyAgICAmcFsyKlNdIGlzIHJldHVybmVkLiAgTm90ZSB0aGF0IHRoaXMgaXMgOC1ieXRlIGFsaWduZWQgaWYgcHltYWxsb2MKKyAgICBoYW5kbGVkIHRoZSByZXF1ZXN0IGl0c2VsZi4KK3BbMipTK246IDIqUytuK1NdCisgICAgQ29waWVzIG9mIEZPUkJJRERFTkJZVEUuICBVc2VkIHRvIGNhdGNoIG92ZXItIHdyaXRlcyBhbmQgcmVhZHMuCitwWzIqUytuK1M6IDIqUytuKzIqU10KKyAgICBBIHNlcmlhbCBudW1iZXIsIGluY3JlbWVudGVkIGJ5IDEgb24gZWFjaCBjYWxsIHRvIF9QeU9iamVjdF9EZWJ1Z01hbGxvYworICAgIGFuZCBfUHlPYmplY3RfRGVidWdSZWFsbG9jLgorICAgIFRoaXMgaXMgYSBiaWctZW5kaWFuIHNpemVfdC4KKyAgICBJZiAiYmFkIG1lbW9yeSIgaXMgZGV0ZWN0ZWQgbGF0ZXIsIHRoZSBzZXJpYWwgbnVtYmVyIGdpdmVzIGFuCisgICAgZXhjZWxsZW50IHdheSB0byBzZXQgYSBicmVha3BvaW50IG9uIHRoZSBuZXh0IHJ1biwgdG8gY2FwdHVyZSB0aGUKKyAgICBpbnN0YW50IGF0IHdoaWNoIHRoaXMgYmxvY2sgd2FzIHBhc3NlZCBvdXQuCisqLworCisvKiBkZWJ1ZyByZXBsYWNlbWVudHMgZm9yIHRoZSBQeU1lbV8qIG1lbW9yeSBBUEkgKi8KK3ZvaWQgKgorX1B5TWVtX0RlYnVnTWFsbG9jKHNpemVfdCBuYnl0ZXMpCit7CisgICAgcmV0dXJuIF9QeU9iamVjdF9EZWJ1Z01hbGxvY0FwaShfUFlNQUxMT0NfTUVNX0lELCBuYnl0ZXMpOworfQordm9pZCAqCitfUHlNZW1fRGVidWdSZWFsbG9jKHZvaWQgKnAsIHNpemVfdCBuYnl0ZXMpCit7CisgICAgcmV0dXJuIF9QeU9iamVjdF9EZWJ1Z1JlYWxsb2NBcGkoX1BZTUFMTE9DX01FTV9JRCwgcCwgbmJ5dGVzKTsKK30KK3ZvaWQKK19QeU1lbV9EZWJ1Z0ZyZWUodm9pZCAqcCkKK3sKKyAgICBfUHlPYmplY3RfRGVidWdGcmVlQXBpKF9QWU1BTExPQ19NRU1fSUQsIHApOworfQorCisvKiBkZWJ1ZyByZXBsYWNlbWVudHMgZm9yIHRoZSBQeU9iamVjdF8qIG1lbW9yeSBBUEkgKi8KK3ZvaWQgKgorX1B5T2JqZWN0X0RlYnVnTWFsbG9jKHNpemVfdCBuYnl0ZXMpCit7CisgICAgcmV0dXJuIF9QeU9iamVjdF9EZWJ1Z01hbGxvY0FwaShfUFlNQUxMT0NfT0JKX0lELCBuYnl0ZXMpOworfQordm9pZCAqCitfUHlPYmplY3RfRGVidWdSZWFsbG9jKHZvaWQgKnAsIHNpemVfdCBuYnl0ZXMpCit7CisgICAgcmV0dXJuIF9QeU9iamVjdF9EZWJ1Z1JlYWxsb2NBcGkoX1BZTUFMTE9DX09CSl9JRCwgcCwgbmJ5dGVzKTsKK30KK3ZvaWQKK19QeU9iamVjdF9EZWJ1Z0ZyZWUodm9pZCAqcCkKK3sKKyAgICBfUHlPYmplY3RfRGVidWdGcmVlQXBpKF9QWU1BTExPQ19PQkpfSUQsIHApOworfQordm9pZAorX1B5T2JqZWN0X0RlYnVnQ2hlY2tBZGRyZXNzKGNvbnN0IHZvaWQgKnApCit7CisgICAgX1B5T2JqZWN0X0RlYnVnQ2hlY2tBZGRyZXNzQXBpKF9QWU1BTExPQ19PQkpfSUQsIHApOworfQorCisKKy8qIGdlbmVyaWMgZGVidWcgbWVtb3J5IGFwaSwgd2l0aCBhbiAiaWQiIHRvIGlkZW50aWZ5IHRoZSBBUEkgaW4gdXNlICovCit2b2lkICoKK19QeU9iamVjdF9EZWJ1Z01hbGxvY0FwaShjaGFyIGlkLCBzaXplX3QgbmJ5dGVzKQoreworICAgIHVjaGFyICpwOyAgICAgICAgICAgLyogYmFzZSBhZGRyZXNzIG9mIG1hbGxvYydlZCBibG9jayAqLworICAgIHVjaGFyICp0YWlsOyAgICAgICAgLyogcCArIDIqU1NUICsgbmJ5dGVzID09IHBvaW50ZXIgdG8gdGFpbCBwYWQgYnl0ZXMgKi8KKyAgICBzaXplX3QgdG90YWw7ICAgICAgIC8qIG5ieXRlcyArIDQqU1NUICovCisKKyAgICBidW1wc2VyaWFsbm8oKTsKKyAgICB0b3RhbCA9IG5ieXRlcyArIDQqU1NUOworICAgIGlmICh0b3RhbCA8IG5ieXRlcykKKyAgICAgICAgLyogb3ZlcmZsb3c6ICBjYW4ndCByZXByZXNlbnQgdG90YWwgYXMgYSBzaXplX3QgKi8KKyAgICAgICAgcmV0dXJuIE5VTEw7CisKKyAgICBwID0gKHVjaGFyICopUHlPYmplY3RfTWFsbG9jKHRvdGFsKTsKKyAgICBpZiAocCA9PSBOVUxMKQorICAgICAgICByZXR1cm4gTlVMTDsKKworICAgIC8qIGF0IHAsIHdyaXRlIHNpemUgKFNTVCBieXRlcyksIGlkICgxIGJ5dGUpLCBwYWQgKFNTVC0xIGJ5dGVzKSAqLworICAgIHdyaXRlX3NpemVfdChwLCBuYnl0ZXMpOworICAgIHBbU1NUXSA9ICh1Y2hhcilpZDsKKyAgICBtZW1zZXQocCArIFNTVCArIDEgLCBGT1JCSURERU5CWVRFLCBTU1QtMSk7CisKKyAgICBpZiAobmJ5dGVzID4gMCkKKyAgICAgICAgbWVtc2V0KHAgKyAyKlNTVCwgQ0xFQU5CWVRFLCBuYnl0ZXMpOworCisgICAgLyogYXQgdGFpbCwgd3JpdGUgcGFkIChTU1QgYnl0ZXMpIGFuZCBzZXJpYWxubyAoU1NUIGJ5dGVzKSAqLworICAgIHRhaWwgPSBwICsgMipTU1QgKyBuYnl0ZXM7CisgICAgbWVtc2V0KHRhaWwsIEZPUkJJRERFTkJZVEUsIFNTVCk7CisgICAgd3JpdGVfc2l6ZV90KHRhaWwgKyBTU1QsIHNlcmlhbG5vKTsKKworICAgIHJldHVybiBwICsgMipTU1Q7Cit9CisKKy8qIFRoZSBkZWJ1ZyBmcmVlIGZpcnN0IGNoZWNrcyB0aGUgMipTU1QgYnl0ZXMgb24gZWFjaCBlbmQgZm9yIHNhbml0eSAoaW4KKyAgIHBhcnRpY3VsYXIsIHRoYXQgdGhlIEZPUkJJRERFTkJZVEVzIHdpdGggdGhlIGFwaSBJRCBhcmUgc3RpbGwgaW50YWN0KS4KKyAgIFRoZW4gZmlsbHMgdGhlIG9yaWdpbmFsIGJ5dGVzIHdpdGggREVBREJZVEUuCisgICBUaGVuIGNhbGxzIHRoZSB1bmRlcmx5aW5nIGZyZWUuCisqLwordm9pZAorX1B5T2JqZWN0X0RlYnVnRnJlZUFwaShjaGFyIGFwaSwgdm9pZCAqcCkKK3sKKyAgICB1Y2hhciAqcSA9ICh1Y2hhciAqKXAgLSAyKlNTVDsgIC8qIGFkZHJlc3MgcmV0dXJuZWQgZnJvbSBtYWxsb2MgKi8KKyAgICBzaXplX3QgbmJ5dGVzOworCisgICAgaWYgKHAgPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuOworICAgIF9QeU9iamVjdF9EZWJ1Z0NoZWNrQWRkcmVzc0FwaShhcGksIHApOworICAgIG5ieXRlcyA9IHJlYWRfc2l6ZV90KHEpOworICAgIG5ieXRlcyArPSA0KlNTVDsKKyAgICBpZiAobmJ5dGVzID4gMCkKKyAgICAgICAgbWVtc2V0KHEsIERFQURCWVRFLCBuYnl0ZXMpOworICAgIFB5T2JqZWN0X0ZyZWUocSk7Cit9CisKK3ZvaWQgKgorX1B5T2JqZWN0X0RlYnVnUmVhbGxvY0FwaShjaGFyIGFwaSwgdm9pZCAqcCwgc2l6ZV90IG5ieXRlcykKK3sKKyAgICB1Y2hhciAqcSA9ICh1Y2hhciAqKXA7CisgICAgdWNoYXIgKnRhaWw7CisgICAgc2l6ZV90IHRvdGFsOyAgICAgICAvKiBuYnl0ZXMgKyA0KlNTVCAqLworICAgIHNpemVfdCBvcmlnaW5hbF9uYnl0ZXM7CisgICAgaW50IGk7CisKKyAgICBpZiAocCA9PSBOVUxMKQorICAgICAgICByZXR1cm4gX1B5T2JqZWN0X0RlYnVnTWFsbG9jQXBpKGFwaSwgbmJ5dGVzKTsKKworICAgIF9QeU9iamVjdF9EZWJ1Z0NoZWNrQWRkcmVzc0FwaShhcGksIHApOworICAgIGJ1bXBzZXJpYWxubygpOworICAgIG9yaWdpbmFsX25ieXRlcyA9IHJlYWRfc2l6ZV90KHEgLSAyKlNTVCk7CisgICAgdG90YWwgPSBuYnl0ZXMgKyA0KlNTVDsKKyAgICBpZiAodG90YWwgPCBuYnl0ZXMpCisgICAgICAgIC8qIG92ZXJmbG93OiAgY2FuJ3QgcmVwcmVzZW50IHRvdGFsIGFzIGEgc2l6ZV90ICovCisgICAgICAgIHJldHVybiBOVUxMOworCisgICAgaWYgKG5ieXRlcyA8IG9yaWdpbmFsX25ieXRlcykgeworICAgICAgICAvKiBzaHJpbmtpbmc6ICBtYXJrIG9sZCBleHRyYSBtZW1vcnkgZGVhZCAqLworICAgICAgICBtZW1zZXQocSArIG5ieXRlcywgREVBREJZVEUsIG9yaWdpbmFsX25ieXRlcyAtIG5ieXRlcyArIDIqU1NUKTsKKyAgICB9CisKKyAgICAvKiBSZXNpemUgYW5kIGFkZCBkZWNvcmF0aW9ucy4gV2UgbWF5IGdldCBhIG5ldyBwb2ludGVyIGhlcmUsIGluIHdoaWNoCisgICAgICogY2FzZSB3ZSBkaWRuJ3QgZ2V0IHRoZSBjaGFuY2UgdG8gbWFyayB0aGUgb2xkIG1lbW9yeSB3aXRoIERFQURCWVRFLAorICAgICAqIGJ1dCB3ZSBsaXZlIHdpdGggdGhhdC4KKyAgICAgKi8KKyAgICBxID0gKHVjaGFyICopUHlPYmplY3RfUmVhbGxvYyhxIC0gMipTU1QsIHRvdGFsKTsKKyAgICBpZiAocSA9PSBOVUxMKQorICAgICAgICByZXR1cm4gTlVMTDsKKworICAgIHdyaXRlX3NpemVfdChxLCBuYnl0ZXMpOworICAgIGFzc2VydChxW1NTVF0gPT0gKHVjaGFyKWFwaSk7CisgICAgZm9yIChpID0gMTsgaSA8IFNTVDsgKytpKQorICAgICAgICBhc3NlcnQocVtTU1QgKyBpXSA9PSBGT1JCSURERU5CWVRFKTsKKyAgICBxICs9IDIqU1NUOworICAgIHRhaWwgPSBxICsgbmJ5dGVzOworICAgIG1lbXNldCh0YWlsLCBGT1JCSURERU5CWVRFLCBTU1QpOworICAgIHdyaXRlX3NpemVfdCh0YWlsICsgU1NULCBzZXJpYWxubyk7CisKKyAgICBpZiAobmJ5dGVzID4gb3JpZ2luYWxfbmJ5dGVzKSB7CisgICAgICAgIC8qIGdyb3dpbmc6ICBtYXJrIG5ldyBleHRyYSBtZW1vcnkgY2xlYW4gKi8KKyAgICAgICAgbWVtc2V0KHEgKyBvcmlnaW5hbF9uYnl0ZXMsIENMRUFOQllURSwKKyAgICAgICAgICAgICAgIG5ieXRlcyAtIG9yaWdpbmFsX25ieXRlcyk7CisgICAgfQorCisgICAgcmV0dXJuIHE7Cit9CisKKy8qIENoZWNrIHRoZSBmb3JiaWRkZW4gYnl0ZXMgb24gYm90aCBlbmRzIG9mIHRoZSBtZW1vcnkgYWxsb2NhdGVkIGZvciBwLgorICogSWYgYW55dGhpbmcgaXMgd3JvbmcsIHByaW50IGluZm8gdG8gc3RkZXJyIHZpYSBfUHlPYmplY3RfRGVidWdEdW1wQWRkcmVzcywKKyAqIGFuZCBjYWxsIFB5X0ZhdGFsRXJyb3IgdG8ga2lsbCB0aGUgcHJvZ3JhbS4KKyAqIFRoZSBBUEkgaWQsIGlzIGFsc28gY2hlY2tlZC4KKyAqLworIHZvaWQKK19QeU9iamVjdF9EZWJ1Z0NoZWNrQWRkcmVzc0FwaShjaGFyIGFwaSwgY29uc3Qgdm9pZCAqcCkKK3sKKyAgICBjb25zdCB1Y2hhciAqcSA9IChjb25zdCB1Y2hhciAqKXA7CisgICAgY2hhciBtc2didWZbNjRdOworICAgIGNoYXIgKm1zZzsKKyAgICBzaXplX3QgbmJ5dGVzOworICAgIGNvbnN0IHVjaGFyICp0YWlsOworICAgIGludCBpOworICAgIGNoYXIgaWQ7CisKKyAgICBpZiAocCA9PSBOVUxMKSB7CisgICAgICAgIG1zZyA9ICJkaWRuJ3QgZXhwZWN0IGEgTlVMTCBwb2ludGVyIjsKKyAgICAgICAgZ290byBlcnJvcjsKKyAgICB9CisKKyAgICAvKiBDaGVjayB0aGUgQVBJIGlkICovCisgICAgaWQgPSAoY2hhcilxWy1TU1RdOworICAgIGlmIChpZCAhPSBhcGkpIHsKKyAgICAgICAgbXNnID0gbXNnYnVmOworICAgICAgICBzbnByaW50Zihtc2csIHNpemVvZihtc2didWYpLCAiYmFkIElEOiBBbGxvY2F0ZWQgdXNpbmcgQVBJICclYycsIHZlcmlmaWVkIHVzaW5nIEFQSSAnJWMnIiwgaWQsIGFwaSk7CisgICAgICAgIG1zZ2J1ZltzaXplb2YobXNnYnVmKS0xXSA9IDA7CisgICAgICAgIGdvdG8gZXJyb3I7CisgICAgfQorCisgICAgLyogQ2hlY2sgdGhlIHN0dWZmIGF0IHRoZSBzdGFydCBvZiBwIGZpcnN0OiAgaWYgdGhlcmUncyB1bmRlcndyaXRlCisgICAgICogY29ycnVwdGlvbiwgdGhlIG51bWJlci1vZi1ieXRlcyBmaWVsZCBtYXkgYmUgbnV0cywgYW5kIGNoZWNraW5nCisgICAgICogdGhlIHRhaWwgY291bGQgbGVhZCB0byBhIHNlZ2ZhdWx0IHRoZW4uCisgICAgICovCisgICAgZm9yIChpID0gU1NULTE7IGkgPj0gMTsgLS1pKSB7CisgICAgICAgIGlmICgqKHEtaSkgIT0gRk9SQklEREVOQllURSkgeworICAgICAgICAgICAgbXNnID0gImJhZCBsZWFkaW5nIHBhZCBieXRlIjsKKyAgICAgICAgICAgIGdvdG8gZXJyb3I7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBuYnl0ZXMgPSByZWFkX3NpemVfdChxIC0gMipTU1QpOworICAgIHRhaWwgPSBxICsgbmJ5dGVzOworICAgIGZvciAoaSA9IDA7IGkgPCBTU1Q7ICsraSkgeworICAgICAgICBpZiAodGFpbFtpXSAhPSBGT1JCSURERU5CWVRFKSB7CisgICAgICAgICAgICBtc2cgPSAiYmFkIHRyYWlsaW5nIHBhZCBieXRlIjsKKyAgICAgICAgICAgIGdvdG8gZXJyb3I7CisgICAgICAgIH0KKyAgICB9CisKKyAgICByZXR1cm47CisKK2Vycm9yOgorICAgIF9QeU9iamVjdF9EZWJ1Z0R1bXBBZGRyZXNzKHApOworICAgIFB5X0ZhdGFsRXJyb3IobXNnKTsKK30KKworLyogRGlzcGxheSBpbmZvIHRvIHN0ZGVyciBhYm91dCB0aGUgbWVtb3J5IGJsb2NrIGF0IHAuICovCit2b2lkCitfUHlPYmplY3RfRGVidWdEdW1wQWRkcmVzcyhjb25zdCB2b2lkICpwKQoreworICAgIGNvbnN0IHVjaGFyICpxID0gKGNvbnN0IHVjaGFyICopcDsKKyAgICBjb25zdCB1Y2hhciAqdGFpbDsKKyAgICBzaXplX3QgbmJ5dGVzLCBzZXJpYWw7CisgICAgaW50IGk7CisgICAgaW50IG9rOworICAgIGNoYXIgaWQ7CisKKyAgICBmcHJpbnRmKHN0ZGVyciwgIkRlYnVnIG1lbW9yeSBibG9jayBhdCBhZGRyZXNzIHA9JXA6IiwgcCk7CisgICAgaWYgKHAgPT0gTlVMTCkgeworICAgICAgICBmcHJpbnRmKHN0ZGVyciwgIlxuIik7CisgICAgICAgIHJldHVybjsKKyAgICB9CisgICAgaWQgPSAoY2hhcilxWy1TU1RdOworICAgIGZwcmludGYoc3RkZXJyLCAiIEFQSSAnJWMnXG4iLCBpZCk7CisKKyAgICBuYnl0ZXMgPSByZWFkX3NpemVfdChxIC0gMipTU1QpOworICAgIGZwcmludGYoc3RkZXJyLCAiICAgICUiIFBZX0ZPUk1BVF9TSVpFX1QgInUgYnl0ZXMgb3JpZ2luYWxseSAiCisgICAgICAgICAgICAgICAgICAgICJyZXF1ZXN0ZWRcbiIsIG5ieXRlcyk7CisKKyAgICAvKiBJbiBjYXNlIHRoaXMgaXMgbnV0cywgY2hlY2sgdGhlIGxlYWRpbmcgcGFkIGJ5dGVzIGZpcnN0LiAqLworICAgIGZwcmludGYoc3RkZXJyLCAiICAgIFRoZSAlZCBwYWQgYnl0ZXMgYXQgcC0lZCBhcmUgIiwgU1NULTEsIFNTVC0xKTsKKyAgICBvayA9IDE7CisgICAgZm9yIChpID0gMTsgaSA8PSBTU1QtMTsgKytpKSB7CisgICAgICAgIGlmICgqKHEtaSkgIT0gRk9SQklEREVOQllURSkgeworICAgICAgICAgICAgb2sgPSAwOworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKyAgICB9CisgICAgaWYgKG9rKQorICAgICAgICBmcHV0cygiRk9SQklEREVOQllURSwgYXMgZXhwZWN0ZWQuXG4iLCBzdGRlcnIpOworICAgIGVsc2UgeworICAgICAgICBmcHJpbnRmKHN0ZGVyciwgIm5vdCBhbGwgRk9SQklEREVOQllURSAoMHglMDJ4KTpcbiIsCisgICAgICAgICAgICBGT1JCSURERU5CWVRFKTsKKyAgICAgICAgZm9yIChpID0gU1NULTE7IGkgPj0gMTsgLS1pKSB7CisgICAgICAgICAgICBjb25zdCB1Y2hhciBieXRlID0gKihxLWkpOworICAgICAgICAgICAgZnByaW50ZihzdGRlcnIsICIgICAgICAgIGF0IHAtJWQ6IDB4JTAyeCIsIGksIGJ5dGUpOworICAgICAgICAgICAgaWYgKGJ5dGUgIT0gRk9SQklEREVOQllURSkKKyAgICAgICAgICAgICAgICBmcHV0cygiICoqKiBPVUNIIiwgc3RkZXJyKTsKKyAgICAgICAgICAgIGZwdXRjKCdcbicsIHN0ZGVycik7CisgICAgICAgIH0KKworICAgICAgICBmcHV0cygiICAgIEJlY2F1c2UgbWVtb3J5IGlzIGNvcnJ1cHRlZCBhdCB0aGUgc3RhcnQsIHRoZSAiCisgICAgICAgICAgICAgICJjb3VudCBvZiBieXRlcyByZXF1ZXN0ZWRcbiIKKyAgICAgICAgICAgICAgIiAgICAgICBtYXkgYmUgYm9ndXMsIGFuZCBjaGVja2luZyB0aGUgdHJhaWxpbmcgcGFkICIKKyAgICAgICAgICAgICAgImJ5dGVzIG1heSBzZWdmYXVsdC5cbiIsIHN0ZGVycik7CisgICAgfQorCisgICAgdGFpbCA9IHEgKyBuYnl0ZXM7CisgICAgZnByaW50ZihzdGRlcnIsICIgICAgVGhlICVkIHBhZCBieXRlcyBhdCB0YWlsPSVwIGFyZSAiLCBTU1QsIHRhaWwpOworICAgIG9rID0gMTsKKyAgICBmb3IgKGkgPSAwOyBpIDwgU1NUOyArK2kpIHsKKyAgICAgICAgaWYgKHRhaWxbaV0gIT0gRk9SQklEREVOQllURSkgeworICAgICAgICAgICAgb2sgPSAwOworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKyAgICB9CisgICAgaWYgKG9rKQorICAgICAgICBmcHV0cygiRk9SQklEREVOQllURSwgYXMgZXhwZWN0ZWQuXG4iLCBzdGRlcnIpOworICAgIGVsc2UgeworICAgICAgICBmcHJpbnRmKHN0ZGVyciwgIm5vdCBhbGwgRk9SQklEREVOQllURSAoMHglMDJ4KTpcbiIsCisgICAgICAgICAgICAgICAgRk9SQklEREVOQllURSk7CisgICAgICAgIGZvciAoaSA9IDA7IGkgPCBTU1Q7ICsraSkgeworICAgICAgICAgICAgY29uc3QgdWNoYXIgYnl0ZSA9IHRhaWxbaV07CisgICAgICAgICAgICBmcHJpbnRmKHN0ZGVyciwgIiAgICAgICAgYXQgdGFpbCslZDogMHglMDJ4IiwKKyAgICAgICAgICAgICAgICAgICAgaSwgYnl0ZSk7CisgICAgICAgICAgICBpZiAoYnl0ZSAhPSBGT1JCSURERU5CWVRFKQorICAgICAgICAgICAgICAgIGZwdXRzKCIgKioqIE9VQ0giLCBzdGRlcnIpOworICAgICAgICAgICAgZnB1dGMoJ1xuJywgc3RkZXJyKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHNlcmlhbCA9IHJlYWRfc2l6ZV90KHRhaWwgKyBTU1QpOworICAgIGZwcmludGYoc3RkZXJyLCAiICAgIFRoZSBibG9jayB3YXMgbWFkZSBieSBjYWxsICMlIiBQWV9GT1JNQVRfU0laRV9UCisgICAgICAgICAgICAgICAgICAgICJ1IHRvIGRlYnVnIG1hbGxvYy9yZWFsbG9jLlxuIiwgc2VyaWFsKTsKKworICAgIGlmIChuYnl0ZXMgPiAwKSB7CisgICAgICAgIGkgPSAwOworICAgICAgICBmcHV0cygiICAgIERhdGEgYXQgcDoiLCBzdGRlcnIpOworICAgICAgICAvKiBwcmludCB1cCB0byA4IGJ5dGVzIGF0IHRoZSBzdGFydCAqLworICAgICAgICB3aGlsZSAocSA8IHRhaWwgJiYgaSA8IDgpIHsKKyAgICAgICAgICAgIGZwcmludGYoc3RkZXJyLCAiICUwMngiLCAqcSk7CisgICAgICAgICAgICArK2k7CisgICAgICAgICAgICArK3E7CisgICAgICAgIH0KKyAgICAgICAgLyogYW5kIHVwIHRvIDggYXQgdGhlIGVuZCAqLworICAgICAgICBpZiAocSA8IHRhaWwpIHsKKyAgICAgICAgICAgIGlmICh0YWlsIC0gcSA+IDgpIHsKKyAgICAgICAgICAgICAgICBmcHV0cygiIC4uLiIsIHN0ZGVycik7CisgICAgICAgICAgICAgICAgcSA9IHRhaWwgLSA4OworICAgICAgICAgICAgfQorICAgICAgICAgICAgd2hpbGUgKHEgPCB0YWlsKSB7CisgICAgICAgICAgICAgICAgZnByaW50ZihzdGRlcnIsICIgJTAyeCIsICpxKTsKKyAgICAgICAgICAgICAgICArK3E7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgZnB1dGMoJ1xuJywgc3RkZXJyKTsKKyAgICB9Cit9CisKK3N0YXRpYyBzaXplX3QKK3ByaW50b25lKGNvbnN0IGNoYXIqIG1zZywgc2l6ZV90IHZhbHVlKQoreworICAgIGludCBpLCBrOworICAgIGNoYXIgYnVmWzEwMF07CisgICAgc2l6ZV90IG9yaWd2YWx1ZSA9IHZhbHVlOworCisgICAgZnB1dHMobXNnLCBzdGRlcnIpOworICAgIGZvciAoaSA9IChpbnQpc3RybGVuKG1zZyk7IGkgPCAzNTsgKytpKQorICAgICAgICBmcHV0YygnICcsIHN0ZGVycik7CisgICAgZnB1dGMoJz0nLCBzdGRlcnIpOworCisgICAgLyogV3JpdGUgdGhlIHZhbHVlIHdpdGggY29tbWFzLiAqLworICAgIGkgPSAyMjsKKyAgICBidWZbaS0tXSA9ICdcMCc7CisgICAgYnVmW2ktLV0gPSAnXG4nOworICAgIGsgPSAzOworICAgIGRvIHsKKyAgICAgICAgc2l6ZV90IG5leHR2YWx1ZSA9IHZhbHVlIC8gMTA7CisgICAgICAgIHVuc2lnbmVkIGludCBkaWdpdCA9ICh1bnNpZ25lZCBpbnQpKHZhbHVlIC0gbmV4dHZhbHVlICogMTApOworICAgICAgICB2YWx1ZSA9IG5leHR2YWx1ZTsKKyAgICAgICAgYnVmW2ktLV0gPSAoY2hhcikoZGlnaXQgKyAnMCcpOworICAgICAgICAtLWs7CisgICAgICAgIGlmIChrID09IDAgJiYgdmFsdWUgJiYgaSA+PSAwKSB7CisgICAgICAgICAgICBrID0gMzsKKyAgICAgICAgICAgIGJ1ZltpLS1dID0gJywnOworICAgICAgICB9CisgICAgfSB3aGlsZSAodmFsdWUgJiYgaSA+PSAwKTsKKworICAgIHdoaWxlIChpID49IDApCisgICAgICAgIGJ1ZltpLS1dID0gJyAnOworICAgIGZwdXRzKGJ1Ziwgc3RkZXJyKTsKKworICAgIHJldHVybiBvcmlndmFsdWU7Cit9CisKKy8qIFByaW50IHN1bW1hcnkgaW5mbyB0byBzdGRlcnIgYWJvdXQgdGhlIHN0YXRlIG9mIHB5bWFsbG9jJ3Mgc3RydWN0dXJlcy4KKyAqIEluIFB5X0RFQlVHIG1vZGUsIGFsc28gcGVyZm9ybSBzb21lIGV4cGVuc2l2ZSBpbnRlcm5hbCBjb25zaXN0ZW5jeQorICogY2hlY2tzLgorICovCit2b2lkCitfUHlPYmplY3RfRGVidWdNYWxsb2NTdGF0cyh2b2lkKQoreworICAgIHVpbnQgaTsKKyAgICBjb25zdCB1aW50IG51bWNsYXNzZXMgPSBTTUFMTF9SRVFVRVNUX1RIUkVTSE9MRCA+PiBBTElHTk1FTlRfU0hJRlQ7CisgICAgLyogIyBvZiBwb29scywgYWxsb2NhdGVkIGJsb2NrcywgYW5kIGZyZWUgYmxvY2tzIHBlciBjbGFzcyBpbmRleCAqLworICAgIHNpemVfdCBudW1wb29sc1tTTUFMTF9SRVFVRVNUX1RIUkVTSE9MRCA+PiBBTElHTk1FTlRfU0hJRlRdOworICAgIHNpemVfdCBudW1ibG9ja3NbU01BTExfUkVRVUVTVF9USFJFU0hPTEQgPj4gQUxJR05NRU5UX1NISUZUXTsKKyAgICBzaXplX3QgbnVtZnJlZWJsb2Nrc1tTTUFMTF9SRVFVRVNUX1RIUkVTSE9MRCA+PiBBTElHTk1FTlRfU0hJRlRdOworICAgIC8qIHRvdGFsICMgb2YgYWxsb2NhdGVkIGJ5dGVzIGluIHVzZWQgYW5kIGZ1bGwgcG9vbHMgKi8KKyAgICBzaXplX3QgYWxsb2NhdGVkX2J5dGVzID0gMDsKKyAgICAvKiB0b3RhbCAjIG9mIGF2YWlsYWJsZSBieXRlcyBpbiB1c2VkIHBvb2xzICovCisgICAgc2l6ZV90IGF2YWlsYWJsZV9ieXRlcyA9IDA7CisgICAgLyogIyBvZiBmcmVlIHBvb2xzICsgcG9vbHMgbm90IHlldCBjYXJ2ZWQgb3V0IG9mIGN1cnJlbnQgYXJlbmEgKi8KKyAgICB1aW50IG51bWZyZWVwb29scyA9IDA7CisgICAgLyogIyBvZiBieXRlcyBmb3IgYXJlbmEgYWxpZ25tZW50IHBhZGRpbmcgKi8KKyAgICBzaXplX3QgYXJlbmFfYWxpZ25tZW50ID0gMDsKKyAgICAvKiAjIG9mIGJ5dGVzIGluIHVzZWQgYW5kIGZ1bGwgcG9vbHMgdXNlZCBmb3IgcG9vbF9oZWFkZXJzICovCisgICAgc2l6ZV90IHBvb2xfaGVhZGVyX2J5dGVzID0gMDsKKyAgICAvKiAjIG9mIGJ5dGVzIGluIHVzZWQgYW5kIGZ1bGwgcG9vbHMgd2FzdGVkIGR1ZSB0byBxdWFudGl6YXRpb24sCisgICAgICogaS5lLiB0aGUgbmVjZXNzYXJpbHkgbGVmdG92ZXIgc3BhY2UgYXQgdGhlIGVuZHMgb2YgdXNlZCBhbmQKKyAgICAgKiBmdWxsIHBvb2xzLgorICAgICAqLworICAgIHNpemVfdCBxdWFudGl6YXRpb24gPSAwOworICAgIC8qICMgb2YgYXJlbmFzIGFjdHVhbGx5IGFsbG9jYXRlZC4gKi8KKyAgICBzaXplX3QgbmFyZW5hcyA9IDA7CisgICAgLyogcnVubmluZyB0b3RhbCAtLSBzaG91bGQgZXF1YWwgbmFyZW5hcyAqIEFSRU5BX1NJWkUgKi8KKyAgICBzaXplX3QgdG90YWw7CisgICAgY2hhciBidWZbMTI4XTsKKworICAgIGZwcmludGYoc3RkZXJyLCAiU21hbGwgYmxvY2sgdGhyZXNob2xkID0gJWQsIGluICV1IHNpemUgY2xhc3Nlcy5cbiIsCisgICAgICAgICAgICBTTUFMTF9SRVFVRVNUX1RIUkVTSE9MRCwgbnVtY2xhc3Nlcyk7CisKKyAgICBmb3IgKGkgPSAwOyBpIDwgbnVtY2xhc3NlczsgKytpKQorICAgICAgICBudW1wb29sc1tpXSA9IG51bWJsb2Nrc1tpXSA9IG51bWZyZWVibG9ja3NbaV0gPSAwOworCisgICAgLyogQmVjYXVzZSBmdWxsIHBvb2xzIGFyZW4ndCBsaW5rZWQgdG8gZnJvbSBhbnl0aGluZywgaXQncyBlYXNpZXN0CisgICAgICogdG8gbWFyY2ggb3ZlciBhbGwgdGhlIGFyZW5hcy4gIElmIHdlJ3JlIGx1Y2t5LCBtb3N0IG9mIHRoZSBtZW1vcnkKKyAgICAgKiB3aWxsIGJlIGxpdmluZyBpbiBmdWxsIHBvb2xzIC0tIHdvdWxkIGJlIGEgc2hhbWUgdG8gbWlzcyB0aGVtLgorICAgICAqLworICAgIGZvciAoaSA9IDA7IGkgPCBtYXhhcmVuYXM7ICsraSkgeworICAgICAgICB1aW50IGo7CisgICAgICAgIHVwdHIgYmFzZSA9IGFyZW5hc1tpXS5hZGRyZXNzOworCisgICAgICAgIC8qIFNraXAgYXJlbmFzIHdoaWNoIGFyZSBub3QgYWxsb2NhdGVkLiAqLworICAgICAgICBpZiAoYXJlbmFzW2ldLmFkZHJlc3MgPT0gKHVwdHIpTlVMTCkKKyAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICBuYXJlbmFzICs9IDE7CisKKyAgICAgICAgbnVtZnJlZXBvb2xzICs9IGFyZW5hc1tpXS5uZnJlZXBvb2xzOworCisgICAgICAgIC8qIHJvdW5kIHVwIHRvIHBvb2wgYWxpZ25tZW50ICovCisgICAgICAgIGlmIChiYXNlICYgKHVwdHIpUE9PTF9TSVpFX01BU0spIHsKKyAgICAgICAgICAgIGFyZW5hX2FsaWdubWVudCArPSBQT09MX1NJWkU7CisgICAgICAgICAgICBiYXNlICY9IH4odXB0cilQT09MX1NJWkVfTUFTSzsKKyAgICAgICAgICAgIGJhc2UgKz0gUE9PTF9TSVpFOworICAgICAgICB9CisKKyAgICAgICAgLyogdmlzaXQgZXZlcnkgcG9vbCBpbiB0aGUgYXJlbmEgKi8KKyAgICAgICAgYXNzZXJ0KGJhc2UgPD0gKHVwdHIpIGFyZW5hc1tpXS5wb29sX2FkZHJlc3MpOworICAgICAgICBmb3IgKGogPSAwOworICAgICAgICAgICAgICAgICAgICBiYXNlIDwgKHVwdHIpIGFyZW5hc1tpXS5wb29sX2FkZHJlc3M7CisgICAgICAgICAgICAgICAgICAgICsraiwgYmFzZSArPSBQT09MX1NJWkUpIHsKKyAgICAgICAgICAgIHBvb2xwIHAgPSAocG9vbHApYmFzZTsKKyAgICAgICAgICAgIGNvbnN0IHVpbnQgc3ogPSBwLT5zemlkeDsKKyAgICAgICAgICAgIHVpbnQgZnJlZWJsb2NrczsKKworICAgICAgICAgICAgaWYgKHAtPnJlZi5jb3VudCA9PSAwKSB7CisgICAgICAgICAgICAgICAgLyogY3VycmVudGx5IHVudXNlZCAqLworICAgICAgICAgICAgICAgIGFzc2VydChwb29sX2lzX2luX2xpc3QocCwgYXJlbmFzW2ldLmZyZWVwb29scykpOworICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgfQorICAgICAgICAgICAgKytudW1wb29sc1tzel07CisgICAgICAgICAgICBudW1ibG9ja3Nbc3pdICs9IHAtPnJlZi5jb3VudDsKKyAgICAgICAgICAgIGZyZWVibG9ja3MgPSBOVU1CTE9DS1Moc3opIC0gcC0+cmVmLmNvdW50OworICAgICAgICAgICAgbnVtZnJlZWJsb2Nrc1tzel0gKz0gZnJlZWJsb2NrczsKKyNpZmRlZiBQeV9ERUJVRworICAgICAgICAgICAgaWYgKGZyZWVibG9ja3MgPiAwKQorICAgICAgICAgICAgICAgIGFzc2VydChwb29sX2lzX2luX2xpc3QocCwgdXNlZHBvb2xzW3N6ICsgc3pdKSk7CisjZW5kaWYKKyAgICAgICAgfQorICAgIH0KKyAgICBhc3NlcnQobmFyZW5hcyA9PSBuYXJlbmFzX2N1cnJlbnRseV9hbGxvY2F0ZWQpOworCisgICAgZnB1dGMoJ1xuJywgc3RkZXJyKTsKKyAgICBmcHV0cygiY2xhc3MgICBzaXplICAgbnVtIHBvb2xzICAgYmxvY2tzIGluIHVzZSAgYXZhaWwgYmxvY2tzXG4iCisgICAgICAgICAgIi0tLS0tICAgLS0tLSAgIC0tLS0tLS0tLSAgIC0tLS0tLS0tLS0tLS0gIC0tLS0tLS0tLS0tLVxuIiwKKyAgICAgICAgICBzdGRlcnIpOworCisgICAgZm9yIChpID0gMDsgaSA8IG51bWNsYXNzZXM7ICsraSkgeworICAgICAgICBzaXplX3QgcCA9IG51bXBvb2xzW2ldOworICAgICAgICBzaXplX3QgYiA9IG51bWJsb2Nrc1tpXTsKKyAgICAgICAgc2l6ZV90IGYgPSBudW1mcmVlYmxvY2tzW2ldOworICAgICAgICB1aW50IHNpemUgPSBJTkRFWDJTSVpFKGkpOworICAgICAgICBpZiAocCA9PSAwKSB7CisgICAgICAgICAgICBhc3NlcnQoYiA9PSAwICYmIGYgPT0gMCk7CisgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgfQorICAgICAgICBmcHJpbnRmKHN0ZGVyciwgIiU1dSAlNnUgIgorICAgICAgICAgICAgICAgICAgICAgICAgIiUxMSIgUFlfRk9STUFUX1NJWkVfVCAidSAiCisgICAgICAgICAgICAgICAgICAgICAgICAiJTE1IiBQWV9GT1JNQVRfU0laRV9UICJ1ICIKKyAgICAgICAgICAgICAgICAgICAgICAgICIlMTMiIFBZX0ZPUk1BVF9TSVpFX1QgInVcbiIsCisgICAgICAgICAgICAgICAgaSwgc2l6ZSwgcCwgYiwgZik7CisgICAgICAgIGFsbG9jYXRlZF9ieXRlcyArPSBiICogc2l6ZTsKKyAgICAgICAgYXZhaWxhYmxlX2J5dGVzICs9IGYgKiBzaXplOworICAgICAgICBwb29sX2hlYWRlcl9ieXRlcyArPSBwICogUE9PTF9PVkVSSEVBRDsKKyAgICAgICAgcXVhbnRpemF0aW9uICs9IHAgKiAoKFBPT0xfU0laRSAtIFBPT0xfT1ZFUkhFQUQpICUgc2l6ZSk7CisgICAgfQorICAgIGZwdXRjKCdcbicsIHN0ZGVycik7CisgICAgKHZvaWQpcHJpbnRvbmUoIiMgdGltZXMgb2JqZWN0IG1hbGxvYyBjYWxsZWQiLCBzZXJpYWxubyk7CisKKyAgICAodm9pZClwcmludG9uZSgiIyBhcmVuYXMgYWxsb2NhdGVkIHRvdGFsIiwgbnRpbWVzX2FyZW5hX2FsbG9jYXRlZCk7CisgICAgKHZvaWQpcHJpbnRvbmUoIiMgYXJlbmFzIHJlY2xhaW1lZCIsIG50aW1lc19hcmVuYV9hbGxvY2F0ZWQgLSBuYXJlbmFzKTsKKyAgICAodm9pZClwcmludG9uZSgiIyBhcmVuYXMgaGlnaHdhdGVyIG1hcmsiLCBuYXJlbmFzX2hpZ2h3YXRlcik7CisgICAgKHZvaWQpcHJpbnRvbmUoIiMgYXJlbmFzIGFsbG9jYXRlZCBjdXJyZW50IiwgbmFyZW5hcyk7CisKKyAgICBQeU9TX3NucHJpbnRmKGJ1Ziwgc2l6ZW9mKGJ1ZiksCisgICAgICAgICIlIiBQWV9GT1JNQVRfU0laRV9UICJ1IGFyZW5hcyAqICVkIGJ5dGVzL2FyZW5hIiwKKyAgICAgICAgbmFyZW5hcywgQVJFTkFfU0laRSk7CisgICAgKHZvaWQpcHJpbnRvbmUoYnVmLCBuYXJlbmFzICogQVJFTkFfU0laRSk7CisKKyAgICBmcHV0YygnXG4nLCBzdGRlcnIpOworCisgICAgdG90YWwgPSBwcmludG9uZSgiIyBieXRlcyBpbiBhbGxvY2F0ZWQgYmxvY2tzIiwgYWxsb2NhdGVkX2J5dGVzKTsKKyAgICB0b3RhbCArPSBwcmludG9uZSgiIyBieXRlcyBpbiBhdmFpbGFibGUgYmxvY2tzIiwgYXZhaWxhYmxlX2J5dGVzKTsKKworICAgIFB5T1Nfc25wcmludGYoYnVmLCBzaXplb2YoYnVmKSwKKyAgICAgICAgIiV1IHVudXNlZCBwb29scyAqICVkIGJ5dGVzIiwgbnVtZnJlZXBvb2xzLCBQT09MX1NJWkUpOworICAgIHRvdGFsICs9IHByaW50b25lKGJ1ZiwgKHNpemVfdCludW1mcmVlcG9vbHMgKiBQT09MX1NJWkUpOworCisgICAgdG90YWwgKz0gcHJpbnRvbmUoIiMgYnl0ZXMgbG9zdCB0byBwb29sIGhlYWRlcnMiLCBwb29sX2hlYWRlcl9ieXRlcyk7CisgICAgdG90YWwgKz0gcHJpbnRvbmUoIiMgYnl0ZXMgbG9zdCB0byBxdWFudGl6YXRpb24iLCBxdWFudGl6YXRpb24pOworICAgIHRvdGFsICs9IHByaW50b25lKCIjIGJ5dGVzIGxvc3QgdG8gYXJlbmEgYWxpZ25tZW50IiwgYXJlbmFfYWxpZ25tZW50KTsKKyAgICAodm9pZClwcmludG9uZSgiVG90YWwiLCB0b3RhbCk7Cit9CisKKyNlbmRpZiAgLyogUFlNQUxMT0NfREVCVUcgKi8KKworI2lmZGVmIFB5X1VTSU5HX01FTU9SWV9ERUJVR0dFUgorLyogTWFrZSB0aGlzIGZ1bmN0aW9uIGxhc3Qgc28gZ2NjIHdvbid0IGlubGluZSBpdCBzaW5jZSB0aGUgZGVmaW5pdGlvbiBpcworICogYWZ0ZXIgdGhlIHJlZmVyZW5jZS4KKyAqLworaW50CitQeV9BRERSRVNTX0lOX1JBTkdFKHZvaWQgKlAsIHBvb2xwIHBvb2wpCit7CisgICAgdWludCBhcmVuYWluZGV4X3RlbXAgPSBwb29sLT5hcmVuYWluZGV4OworCisgICAgcmV0dXJuIGFyZW5haW5kZXhfdGVtcCA8IG1heGFyZW5hcyAmJgorICAgICAgICAgICAodXB0cilQIC0gYXJlbmFzW2FyZW5haW5kZXhfdGVtcF0uYWRkcmVzcyA8ICh1cHRyKUFSRU5BX1NJWkUgJiYKKyAgICAgICAgICAgYXJlbmFzW2FyZW5haW5kZXhfdGVtcF0uYWRkcmVzcyAhPSAwOworfQorI2VuZGlmCmRpZmYgLS1naXQgYS9QeXRob24tMi43LjUvT2JqZWN0cy9yYW5nZW9iamVjdC5jIGIvUHl0aG9uLTIuNy41L09iamVjdHMvcmFuZ2VvYmplY3QuYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41MjAzZjQwCi0tLSAvZGV2L251bGwKKysrIGIvUHl0aG9uLTIuNy41L09iamVjdHMvcmFuZ2VvYmplY3QuYwpAQCAtMCwwICsxLDM0NyBAQAorLyogUmFuZ2Ugb2JqZWN0IGltcGxlbWVudGF0aW9uICovCisKKyNpbmNsdWRlICJQeXRob24uaCIKKwordHlwZWRlZiBzdHJ1Y3QgeworICAgIFB5T2JqZWN0X0hFQUQKKyAgICBsb25nICAgICAgICBzdGFydDsKKyAgICBsb25nICAgICAgICBzdGVwOworICAgIGxvbmcgICAgICAgIGxlbjsKK30gcmFuZ2VvYmplY3Q7CisKKy8qIFJldHVybiBudW1iZXIgb2YgaXRlbXMgaW4gcmFuZ2UgKGxvLCBoaSwgc3RlcCkuICBzdGVwICE9IDAKKyAqIHJlcXVpcmVkLiAgVGhlIHJlc3VsdCBhbHdheXMgZml0cyBpbiBhbiB1bnNpZ25lZCBsb25nLgorICovCitzdGF0aWMgdW5zaWduZWQgbG9uZworZ2V0X2xlbl9vZl9yYW5nZShsb25nIGxvLCBsb25nIGhpLCBsb25nIHN0ZXApCit7CisgICAgLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorICAgIElmIHN0ZXAgPiAwIGFuZCBsbyA+PSBoaSwgb3Igc3RlcCA8IDAgYW5kIGxvIDw9IGhpLCB0aGUgcmFuZ2UgaXMgZW1wdHkuCisgICAgRWxzZSBmb3Igc3RlcCA+IDAsIGlmIG4gdmFsdWVzIGFyZSBpbiB0aGUgcmFuZ2UsIHRoZSBsYXN0IG9uZSBpcworICAgIGxvICsgKG4tMSkqc3RlcCwgd2hpY2ggbXVzdCBiZSA8PSBoaS0xLiAgUmVhcnJhbmdpbmcsCisgICAgbiA8PSAoaGkgLSBsbyAtIDEpL3N0ZXAgKyAxLCBzbyB0YWtpbmcgdGhlIGZsb29yIG9mIHRoZSBSSFMgZ2l2ZXMKKyAgICB0aGUgcHJvcGVyIHZhbHVlLiAgU2luY2UgbG8gPCBoaSBpbiB0aGlzIGNhc2UsIGhpLWxvLTEgPj0gMCwgc28KKyAgICB0aGUgUkhTIGlzIG5vbi1uZWdhdGl2ZSBhbmQgc28gdHJ1bmNhdGlvbiBpcyB0aGUgc2FtZSBhcyB0aGUKKyAgICBmbG9vci4gIExldHRpbmcgTSBiZSB0aGUgbGFyZ2VzdCBwb3NpdGl2ZSBsb25nLCB0aGUgd29yc3QgY2FzZQorICAgIGZvciB0aGUgUkhTIG51bWVyYXRvciBpcyBoaT1NLCBsbz0tTS0xLCBhbmQgdGhlbgorICAgIGhpLWxvLTEgPSBNLSgtTS0xKS0xID0gMipNLiAgVGhlcmVmb3JlIHVuc2lnbmVkIGxvbmcgaGFzIGVub3VnaAorICAgIHByZWNpc2lvbiB0byBjb21wdXRlIHRoZSBSSFMgZXhhY3RseS4gIFRoZSBhbmFseXNpcyBmb3Igc3RlcCA8IDAKKyAgICBpcyBzaW1pbGFyLgorICAgIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCisgICAgYXNzZXJ0KHN0ZXAgIT0gMCk7CisgICAgaWYgKHN0ZXAgPiAwICYmIGxvIDwgaGkpCisgICAgcmV0dXJuIDFVTCArIChoaSAtIDFVTCAtIGxvKSAvIHN0ZXA7CisgICAgZWxzZSBpZiAoc3RlcCA8IDAgJiYgbG8gPiBoaSkKKyAgICByZXR1cm4gMVVMICsgKGxvIC0gMVVMIC0gaGkpIC8gKDBVTCAtIHN0ZXApOworICAgIGVsc2UKKyAgICByZXR1cm4gMFVMOworfQorCisvKiBSZXR1cm4gYSBzdG9wIHZhbHVlIHN1aXRhYmxlIGZvciByZWNvbnN0cnVjdGluZyB0aGUgeHJhbmdlIGZyb20KKyAqIGEgKHN0YXJ0LCBzdG9wLCBzdGVwKSB0cmlwbGUuICBVc2VkIGluIHJhbmdlX3JlcHIgYW5kIHJhbmdlX3JlZHVjZS4KKyAqIENvbXB1dGVzIHN0YXJ0ICsgbGVuICogc3RlcCwgY2xpcHBlZCB0byB0aGUgcmFuZ2UgW0xPTkdfTUlOLCBMT05HX01BWF0uCisgKi8KK3N0YXRpYyBsb25nCitnZXRfc3RvcF9mb3JfcmFuZ2UocmFuZ2VvYmplY3QgKnIpCit7CisgICAgbG9uZyBsYXN0OworCisgICAgaWYgKHItPmxlbiA9PSAwKQorICAgICAgICByZXR1cm4gci0+c3RhcnQ7CisKKyAgICAvKiBUaGUgdHJpY2t5IGJpdCBpcyBhdm9pZGluZyBvdmVyZmxvdy4gIFdlIGZpcnN0IGNvbXB1dGUgdGhlIGxhc3QgZW50cnkgaW4KKyAgICAgICB0aGUgeHJhbmdlLCBzdGFydCArIChsZW4gLSAxKSAqIHN0ZXAsIHdoaWNoIGlzIGd1YXJhbnRlZWQgdG8gbGllIHdpdGhpbgorICAgICAgIHRoZSByYW5nZSBvZiBhIGxvbmcsIGFuZCB0aGVuIGFkZCBzdGVwIHRvIGl0LiAgU2VlIHRoZSByYW5nZV9yZXZlcnNlCisgICAgICAgY29tbWVudHMgZm9yIGFuIGV4cGxhbmF0aW9uIG9mIHRoZSBjYXN0cyBiZWxvdy4KKyAgICAqLworICAgIGxhc3QgPSAobG9uZykoci0+c3RhcnQgKyAodW5zaWduZWQgbG9uZykoci0+bGVuIC0gMSkgKiByLT5zdGVwKTsKKyAgICBpZiAoci0+c3RlcCA+IDApCisgICAgICAgIHJldHVybiBsYXN0ID4gTE9OR19NQVggLSByLT5zdGVwID8gTE9OR19NQVggOiBsYXN0ICsgci0+c3RlcDsKKyAgICBlbHNlCisgICAgICAgIHJldHVybiBsYXN0IDwgTE9OR19NSU4gLSByLT5zdGVwID8gTE9OR19NSU4gOiBsYXN0ICsgci0+c3RlcDsKK30KKworc3RhdGljIFB5T2JqZWN0ICoKK3JhbmdlX25ldyhQeVR5cGVPYmplY3QgKnR5cGUsIFB5T2JqZWN0ICphcmdzLCBQeU9iamVjdCAqa3cpCit7CisgICAgcmFuZ2VvYmplY3QgKm9iajsKKyAgICBsb25nIGlsb3cgPSAwLCBpaGlnaCA9IDAsIGlzdGVwID0gMTsKKyAgICB1bnNpZ25lZCBsb25nIG47CisKKyAgICBpZiAoIV9QeUFyZ19Ob0tleXdvcmRzKCJ4cmFuZ2UoKSIsIGt3KSkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisKKyAgICBpZiAoUHlUdXBsZV9TaXplKGFyZ3MpIDw9IDEpIHsKKyAgICAgICAgaWYgKCFQeUFyZ19QYXJzZVR1cGxlKGFyZ3MsCisgICAgICAgICAgICAgICAgICAgICAgICAibDt4cmFuZ2UoKSByZXF1aXJlcyAxLTMgaW50IGFyZ3VtZW50cyIsCisgICAgICAgICAgICAgICAgICAgICAgICAmaWhpZ2gpKQorICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIGVsc2UgeworICAgICAgICBpZiAoIVB5QXJnX1BhcnNlVHVwbGUoYXJncywKKyAgICAgICAgICAgICAgICAgICAgICAgICJsbHxsO3hyYW5nZSgpIHJlcXVpcmVzIDEtMyBpbnQgYXJndW1lbnRzIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICZpbG93LCAmaWhpZ2gsICZpc3RlcCkpCisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgaWYgKGlzdGVwID09IDApIHsKKyAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1ZhbHVlRXJyb3IsICJ4cmFuZ2UoKSBhcmcgMyBtdXN0IG5vdCBiZSB6ZXJvIik7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICBuID0gZ2V0X2xlbl9vZl9yYW5nZShpbG93LCBpaGlnaCwgaXN0ZXApOworICAgIGlmIChuID4gKHVuc2lnbmVkIGxvbmcpTE9OR19NQVggfHwgKGxvbmcpbiA+IFBZX1NTSVpFX1RfTUFYKSB7CisgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19PdmVyZmxvd0Vycm9yLAorICAgICAgICAgICAgICAgICAgICAgICAgInhyYW5nZSgpIHJlc3VsdCBoYXMgdG9vIG1hbnkgaXRlbXMiKTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorCisgICAgb2JqID0gUHlPYmplY3RfTmV3KHJhbmdlb2JqZWN0LCAmUHlSYW5nZV9UeXBlKTsKKyAgICBpZiAob2JqID09IE5VTEwpCisgICAgICAgIHJldHVybiBOVUxMOworICAgIG9iai0+c3RhcnQgPSBpbG93OworICAgIG9iai0+bGVuICAgPSAobG9uZyluOworICAgIG9iai0+c3RlcCAgPSBpc3RlcDsKKyAgICByZXR1cm4gKFB5T2JqZWN0ICopIG9iajsKK30KKworUHlEb2NfU1RSVkFSKHJhbmdlX2RvYywKKyJ4cmFuZ2Uoc3RvcCkgLT4geHJhbmdlIG9iamVjdFxuXAoreHJhbmdlKHN0YXJ0LCBzdG9wWywgc3RlcF0pIC0+IHhyYW5nZSBvYmplY3RcblwKK1xuXAorTGlrZSByYW5nZSgpLCBidXQgaW5zdGVhZCBvZiByZXR1cm5pbmcgYSBsaXN0LCByZXR1cm5zIGFuIG9iamVjdCB0aGF0XG5cCitnZW5lcmF0ZXMgdGhlIG51bWJlcnMgaW4gdGhlIHJhbmdlIG9uIGRlbWFuZC4gIEZvciBsb29waW5nLCB0aGlzIGlzIFxuXAorc2xpZ2h0bHkgZmFzdGVyIHRoYW4gcmFuZ2UoKSBhbmQgbW9yZSBtZW1vcnkgZWZmaWNpZW50LiIpOworCitzdGF0aWMgUHlPYmplY3QgKgorcmFuZ2VfaXRlbShyYW5nZW9iamVjdCAqciwgUHlfc3NpemVfdCBpKQoreworICAgIGlmIChpIDwgMCB8fCBpID49IHItPmxlbikgeworICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfSW5kZXhFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICJ4cmFuZ2Ugb2JqZWN0IGluZGV4IG91dCBvZiByYW5nZSIpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgLyogZG8gY2FsY3VsYXRpb24gZW50aXJlbHkgdXNpbmcgdW5zaWduZWQgbG9uZ3MsIHRvIGF2b2lkCisgICAgICAgdW5kZWZpbmVkIGJlaGF2aW91ciBkdWUgdG8gc2lnbmVkIG92ZXJmbG93LiAqLworICAgIHJldHVybiBQeUludF9Gcm9tTG9uZygobG9uZykoci0+c3RhcnQgKyAodW5zaWduZWQgbG9uZylpICogci0+c3RlcCkpOworfQorCitzdGF0aWMgUHlfc3NpemVfdAorcmFuZ2VfbGVuZ3RoKHJhbmdlb2JqZWN0ICpyKQoreworICAgIHJldHVybiAoUHlfc3NpemVfdCkoci0+bGVuKTsKK30KKworc3RhdGljIFB5T2JqZWN0ICoKK3JhbmdlX3JlcHIocmFuZ2VvYmplY3QgKnIpCit7CisgICAgUHlPYmplY3QgKnJ0bjsKKworICAgIGlmIChyLT5zdGFydCA9PSAwICYmIHItPnN0ZXAgPT0gMSkKKyAgICAgICAgcnRuID0gUHlTdHJpbmdfRnJvbUZvcm1hdCgieHJhbmdlKCVsZCkiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdldF9zdG9wX2Zvcl9yYW5nZShyKSk7CisKKyAgICBlbHNlIGlmIChyLT5zdGVwID09IDEpCisgICAgICAgIHJ0biA9IFB5U3RyaW5nX0Zyb21Gb3JtYXQoInhyYW5nZSglbGQsICVsZCkiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHItPnN0YXJ0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdldF9zdG9wX2Zvcl9yYW5nZShyKSk7CisKKyAgICBlbHNlCisgICAgICAgIHJ0biA9IFB5U3RyaW5nX0Zyb21Gb3JtYXQoInhyYW5nZSglbGQsICVsZCwgJWxkKSIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgci0+c3RhcnQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2V0X3N0b3BfZm9yX3JhbmdlKHIpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHItPnN0ZXApOworICAgIHJldHVybiBydG47Cit9CisKKy8qIFBpY2tsaW5nIHN1cHBvcnQgKi8KK3N0YXRpYyBQeU9iamVjdCAqCityYW5nZV9yZWR1Y2UocmFuZ2VvYmplY3QgKnIsIFB5T2JqZWN0ICphcmdzKQoreworICAgIHJldHVybiBQeV9CdWlsZFZhbHVlKCIoTyhsbGwpKSIsIFB5X1RZUEUociksCisgICAgICAgICAgICAgICAgICAgICAgICAgci0+c3RhcnQsCisgICAgICAgICAgICAgICAgICAgICAgICAgZ2V0X3N0b3BfZm9yX3JhbmdlKHIpLAorICAgICAgICAgICAgICAgICAgICAgICAgIHItPnN0ZXApOworfQorCitzdGF0aWMgUHlTZXF1ZW5jZU1ldGhvZHMgcmFuZ2VfYXNfc2VxdWVuY2UgPSB7CisgICAgKGxlbmZ1bmMpcmFuZ2VfbGVuZ3RoLCAgICAgIC8qIHNxX2xlbmd0aCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBzcV9jb25jYXQgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgLyogc3FfcmVwZWF0ICovCisgICAgKHNzaXplYXJnZnVuYylyYW5nZV9pdGVtLCAvKiBzcV9pdGVtICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHNxX3NsaWNlICovCit9OworCitzdGF0aWMgUHlPYmplY3QgKiByYW5nZV9pdGVyKFB5T2JqZWN0ICpzZXEpOworc3RhdGljIFB5T2JqZWN0ICogcmFuZ2VfcmV2ZXJzZShQeU9iamVjdCAqc2VxKTsKKworUHlEb2NfU1RSVkFSKHJldmVyc2VfZG9jLAorIlJldHVybnMgYSByZXZlcnNlIGl0ZXJhdG9yLiIpOworCitzdGF0aWMgUHlNZXRob2REZWYgcmFuZ2VfbWV0aG9kc1tdID0geworICAgIHsiX19yZXZlcnNlZF9fIiwgICAgICAgICAgICAoUHlDRnVuY3Rpb24pcmFuZ2VfcmV2ZXJzZSwgTUVUSF9OT0FSR1MsIHJldmVyc2VfZG9jfSwKKyAgICB7Il9fcmVkdWNlX18iLCAgICAgICAgICAgICAgKFB5Q0Z1bmN0aW9uKXJhbmdlX3JlZHVjZSwgTUVUSF9WQVJBUkdTfSwKKyAgICB7TlVMTCwgICAgICAgICAgICAgIE5VTEx9ICAgICAgICAgICAvKiBzZW50aW5lbCAqLworfTsKKworUHlUeXBlT2JqZWN0IFB5UmFuZ2VfVHlwZSA9IHsKKyAgICBQeU9iamVjdF9IRUFEX0lOSVQoJlB5VHlwZV9UeXBlKQorICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBOdW1iZXIgb2YgaXRlbXMgZm9yIHZhcm9iamVjdCAqLworICAgICJ4cmFuZ2UiLCAgICAgICAgICAgICAgICAgICAvKiBOYW1lIG9mIHRoaXMgdHlwZSAqLworICAgIHNpemVvZihyYW5nZW9iamVjdCksICAgICAgICAvKiBCYXNpYyBvYmplY3Qgc2l6ZSAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBJdGVtIHNpemUgZm9yIHZhcm9iamVjdCAqLworICAgIChkZXN0cnVjdG9yKVB5T2JqZWN0X0RlbCwgLyogdHBfZGVhbGxvYyAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9wcmludCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9nZXRhdHRyICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3NldGF0dHIgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfY29tcGFyZSAqLworICAgIChyZXByZnVuYylyYW5nZV9yZXByLCAgICAgICAvKiB0cF9yZXByICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2FzX251bWJlciAqLworICAgICZyYW5nZV9hc19zZXF1ZW5jZSwgICAgICAgICAvKiB0cF9hc19zZXF1ZW5jZSAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9hc19tYXBwaW5nICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2hhc2ggKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfY2FsbCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9zdHIgKi8KKyAgICBQeU9iamVjdF9HZW5lcmljR2V0QXR0ciwgIC8qIHRwX2dldGF0dHJvICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3NldGF0dHJvICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2FzX2J1ZmZlciAqLworICAgIFB5X1RQRkxBR1NfREVGQVVMVCwgICAgICAgICAvKiB0cF9mbGFncyAqLworICAgIHJhbmdlX2RvYywgICAgICAgICAgICAgICAgICAvKiB0cF9kb2MgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfdHJhdmVyc2UgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfY2xlYXIgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfcmljaGNvbXBhcmUgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfd2Vha2xpc3RvZmZzZXQgKi8KKyAgICByYW5nZV9pdGVyLCAgICAgICAgICAgICAgICAgLyogdHBfaXRlciAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9pdGVybmV4dCAqLworICAgIHJhbmdlX21ldGhvZHMsICAgICAgICAgICAgICAvKiB0cF9tZXRob2RzICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX21lbWJlcnMgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZ2V0c2V0ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2Jhc2UgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZGljdCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9kZXNjcl9nZXQgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZGVzY3Jfc2V0ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2RpY3RvZmZzZXQgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfaW5pdCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9hbGxvYyAqLworICAgIHJhbmdlX25ldywgICAgICAgICAgICAgICAgICAvKiB0cF9uZXcgKi8KK307CisKKy8qKioqKioqKioqKioqKioqKioqKioqKiBYcmFuZ2UgSXRlcmF0b3IgKioqKioqKioqKioqKioqKioqKioqKioqKiovCisKK3R5cGVkZWYgc3RydWN0IHsKKyAgICBQeU9iamVjdF9IRUFECisgICAgbG9uZyAgICAgICAgaW5kZXg7CisgICAgbG9uZyAgICAgICAgc3RhcnQ7CisgICAgbG9uZyAgICAgICAgc3RlcDsKKyAgICBsb25nICAgICAgICBsZW47Cit9IHJhbmdlaXRlcm9iamVjdDsKKworc3RhdGljIFB5T2JqZWN0ICoKK3JhbmdlaXRlcl9uZXh0KHJhbmdlaXRlcm9iamVjdCAqcikKK3sKKyAgICBpZiAoci0+aW5kZXggPCByLT5sZW4pCisgICAgICAgIHJldHVybiBQeUludF9Gcm9tTG9uZyhyLT5zdGFydCArIChyLT5pbmRleCsrKSAqIHItPnN0ZXApOworICAgIHJldHVybiBOVUxMOworfQorCitzdGF0aWMgUHlPYmplY3QgKgorcmFuZ2VpdGVyX2xlbihyYW5nZWl0ZXJvYmplY3QgKnIpCit7CisgICAgcmV0dXJuIFB5SW50X0Zyb21Mb25nKHItPmxlbiAtIHItPmluZGV4KTsKK30KKworUHlEb2NfU1RSVkFSKGxlbmd0aF9oaW50X2RvYywgIlByaXZhdGUgbWV0aG9kIHJldHVybmluZyBhbiBlc3RpbWF0ZSBvZiBsZW4obGlzdChpdCkpLiIpOworCitzdGF0aWMgUHlNZXRob2REZWYgcmFuZ2VpdGVyX21ldGhvZHNbXSA9IHsKKyAgICB7Il9fbGVuZ3RoX2hpbnRfXyIsIChQeUNGdW5jdGlvbilyYW5nZWl0ZXJfbGVuLCBNRVRIX05PQVJHUywgbGVuZ3RoX2hpbnRfZG9jfSwKKyAgICB7TlVMTCwgICAgICAgICAgICAgIE5VTEx9ICAgICAgICAgICAvKiBzZW50aW5lbCAqLworfTsKKworc3RhdGljIFB5VHlwZU9iamVjdCBQeXJhbmdlaXRlcl9UeXBlID0geworICAgIFB5T2JqZWN0X0hFQURfSU5JVCgmUHlUeXBlX1R5cGUpCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIG9iX3NpemUgKi8KKyAgICAicmFuZ2VpdGVyYXRvciIsICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfbmFtZSAqLworICAgIHNpemVvZihyYW5nZWl0ZXJvYmplY3QpLCAgICAgICAgICAgICAgICAvKiB0cF9iYXNpY3NpemUgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfaXRlbXNpemUgKi8KKyAgICAvKiBtZXRob2RzICovCisgICAgKGRlc3RydWN0b3IpUHlPYmplY3RfRGVsLCAgICAgICAgICAgICAgICAgICAvKiB0cF9kZWFsbG9jICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3ByaW50ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2dldGF0dHIgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfc2V0YXR0ciAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9jb21wYXJlICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3JlcHIgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfYXNfbnVtYmVyICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9hc19zZXF1ZW5jZSAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9hc19tYXBwaW5nICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2hhc2ggKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfY2FsbCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9zdHIgKi8KKyAgICBQeU9iamVjdF9HZW5lcmljR2V0QXR0ciwgICAgICAgICAgICAgICAgLyogdHBfZ2V0YXR0cm8gKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfc2V0YXR0cm8gKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfYXNfYnVmZmVyICovCisgICAgUHlfVFBGTEFHU19ERUZBVUxULCAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9mbGFncyAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9kb2MgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3RyYXZlcnNlICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2NsZWFyICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3JpY2hjb21wYXJlICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3dlYWtsaXN0b2Zmc2V0ICovCisgICAgUHlPYmplY3RfU2VsZkl0ZXIsICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9pdGVyICovCisgICAgKGl0ZXJuZXh0ZnVuYylyYW5nZWl0ZXJfbmV4dCwgICAgICAgICAgICAgICAvKiB0cF9pdGVybmV4dCAqLworICAgIHJhbmdlaXRlcl9tZXRob2RzLCAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfbWV0aG9kcyAqLworICAgIDAsCit9OworCitzdGF0aWMgUHlPYmplY3QgKgorcmFuZ2VfaXRlcihQeU9iamVjdCAqc2VxKQoreworICAgIHJhbmdlaXRlcm9iamVjdCAqaXQ7CisKKyAgICBpZiAoIVB5UmFuZ2VfQ2hlY2soc2VxKSkgeworICAgICAgICBQeUVycl9CYWRJbnRlcm5hbENhbGwoKTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIGl0ID0gUHlPYmplY3RfTmV3KHJhbmdlaXRlcm9iamVjdCwgJlB5cmFuZ2VpdGVyX1R5cGUpOworICAgIGlmIChpdCA9PSBOVUxMKQorICAgICAgICByZXR1cm4gTlVMTDsKKyAgICBpdC0+aW5kZXggPSAwOworICAgIGl0LT5zdGFydCA9ICgocmFuZ2VvYmplY3QgKilzZXEpLT5zdGFydDsKKyAgICBpdC0+c3RlcCA9ICgocmFuZ2VvYmplY3QgKilzZXEpLT5zdGVwOworICAgIGl0LT5sZW4gPSAoKHJhbmdlb2JqZWN0ICopc2VxKS0+bGVuOworICAgIHJldHVybiAoUHlPYmplY3QgKilpdDsKK30KKworc3RhdGljIFB5T2JqZWN0ICoKK3JhbmdlX3JldmVyc2UoUHlPYmplY3QgKnNlcSkKK3sKKyAgICByYW5nZWl0ZXJvYmplY3QgKml0OworICAgIGxvbmcgc3RhcnQsIHN0ZXAsIGxlbjsKKworICAgIGlmICghUHlSYW5nZV9DaGVjayhzZXEpKSB7CisgICAgICAgIFB5RXJyX0JhZEludGVybmFsQ2FsbCgpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgaXQgPSBQeU9iamVjdF9OZXcocmFuZ2VpdGVyb2JqZWN0LCAmUHlyYW5nZWl0ZXJfVHlwZSk7CisgICAgaWYgKGl0ID09IE5VTEwpCisgICAgICAgIHJldHVybiBOVUxMOworCisgICAgc3RhcnQgPSAoKHJhbmdlb2JqZWN0ICopc2VxKS0+c3RhcnQ7CisgICAgc3RlcCA9ICgocmFuZ2VvYmplY3QgKilzZXEpLT5zdGVwOworICAgIGxlbiA9ICgocmFuZ2VvYmplY3QgKilzZXEpLT5sZW47CisKKyAgICBpdC0+aW5kZXggPSAwOworICAgIGl0LT5sZW4gPSBsZW47CisgICAgLyogdGhlIGNhc3RzIGJlbG93IGd1YXJkIGFnYWluc3Qgc2lnbmVkIG92ZXJmbG93IGJ5IHR1cm5pbmcgaXQKKyAgICAgICBpbnRvIHVuc2lnbmVkIG92ZXJmbG93IGluc3RlYWQuICBUaGUgY29ycmVjdG5lc3Mgb2YgdGhpcworICAgICAgIGNvZGUgc3RpbGwgZGVwZW5kcyBvbiBjb252ZXJzaW9uIGZyb20gdW5zaWduZWQgbG9uZyB0byBsb25nCisgICAgICAgd3JhcHBpbmcgbW9kdWxvIFVMT05HX01BWCsxLCB3aGljaCBpc24ndCBndWFyYW50ZWVkIChzZWUKKyAgICAgICBDOTkgNi4zLjEuM3AzKSBidXQgc2VlbXMgdG8gaG9sZCBpbiBwcmFjdGljZSBmb3IgYWxsCisgICAgICAgcGxhdGZvcm1zIHdlJ3JlIGxpa2VseSB0byBtZWV0LgorCisgICAgICAgSWYgc3RlcCA9PSBMT05HX01JTiB0aGVuIHdlIHN0aWxsIGVuZCB1cCB3aXRoIExPTkdfTUlOCisgICAgICAgYWZ0ZXIgbmVnYXRpb247IGJ1dCB0aGlzIHdvcmtzIG91dCwgc2luY2Ugd2UndmUgc3RpbGwgZ290CisgICAgICAgdGhlIGNvcnJlY3QgdmFsdWUgbW9kdWxvIFVMT05HX01BWCsxLCBhbmQgdGhlIHJhbmdlX2l0ZW0KKyAgICAgICBjYWxjdWxhdGlvbiBpcyBhbHNvIGRvbmUgbW9kdWxvIFVMT05HX01BWCsxLgorICAgICovCisgICAgaXQtPnN0YXJ0ID0gKGxvbmcpKHN0YXJ0ICsgKHVuc2lnbmVkIGxvbmcpKGxlbi0xKSAqIHN0ZXApOworICAgIGl0LT5zdGVwID0gKGxvbmcpKDBVTC1zdGVwKTsKKworICAgIHJldHVybiAoUHlPYmplY3QgKilpdDsKK30KZGlmZiAtLWdpdCBhL1B5dGhvbi0yLjcuNS9PYmplY3RzL3NldG9iamVjdC5jIGIvUHl0aG9uLTIuNy41L09iamVjdHMvc2V0b2JqZWN0LmMKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYWYxY2UxNgotLS0gL2Rldi9udWxsCisrKyBiL1B5dGhvbi0yLjcuNS9PYmplY3RzL3NldG9iamVjdC5jCkBAIC0wLDAgKzEsMjUxOSBAQAorCisvKiBzZXQgb2JqZWN0IGltcGxlbWVudGF0aW9uCisgICBXcml0dGVuIGFuZCBtYWludGFpbmVkIGJ5IFJheW1vbmQgRC4gSGV0dGluZ2VyIDxweXRob25AcmNuLmNvbT4KKyAgIERlcml2ZWQgZnJvbSBMaWIvc2V0cy5weSBhbmQgT2JqZWN0cy9kaWN0b2JqZWN0LmMuCisKKyAgIENvcHlyaWdodCAoYykgMjAwMy0yMDA3IFB5dGhvbiBTb2Z0d2FyZSBGb3VuZGF0aW9uLgorICAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KKyovCisKKyNpbmNsdWRlICJQeXRob24uaCIKKyNpbmNsdWRlICJzdHJ1Y3RtZW1iZXIuaCIKKworLyogU2V0IGEga2V5IGVycm9yIHdpdGggdGhlIHNwZWNpZmllZCBhcmd1bWVudCwgd3JhcHBpbmcgaXQgaW4gYQorICogdHVwbGUgYXV0b21hdGljYWxseSBzbyB0aGF0IHR1cGxlIGtleXMgYXJlIG5vdCB1bnBhY2tlZCBhcyB0aGUKKyAqIGV4Y2VwdGlvbiBhcmd1bWVudHMuICovCitzdGF0aWMgdm9pZAorc2V0X2tleV9lcnJvcihQeU9iamVjdCAqYXJnKQoreworICAgIFB5T2JqZWN0ICp0dXA7CisgICAgdHVwID0gUHlUdXBsZV9QYWNrKDEsIGFyZyk7CisgICAgaWYgKCF0dXApCisgICAgICAgIHJldHVybjsgLyogY2FsbGVyIHdpbGwgZXhwZWN0IGVycm9yIHRvIGJlIHNldCBhbnl3YXkgKi8KKyAgICBQeUVycl9TZXRPYmplY3QoUHlFeGNfS2V5RXJyb3IsIHR1cCk7CisgICAgUHlfREVDUkVGKHR1cCk7Cit9CisKKy8qIFRoaXMgbXVzdCBiZSA+PSAxLiAqLworI2RlZmluZSBQRVJUVVJCX1NISUZUIDUKKworLyogT2JqZWN0IHVzZWQgYXMgZHVtbXkga2V5IHRvIGZpbGwgZGVsZXRlZCBlbnRyaWVzICovCitzdGF0aWMgUHlPYmplY3QgKmR1bW15ID0gTlVMTDsgLyogSW5pdGlhbGl6ZWQgYnkgZmlyc3QgY2FsbCB0byBtYWtlX25ld19zZXQoKSAqLworCisjaWZkZWYgUHlfUkVGX0RFQlVHCitQeU9iamVjdCAqCitfUHlTZXRfRHVtbXkodm9pZCkKK3sKKyAgICByZXR1cm4gZHVtbXk7Cit9CisjZW5kaWYKKworI2RlZmluZSBJTklUX05PTlpFUk9fU0VUX1NMT1RTKHNvKSBkbyB7ICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAoc28pLT50YWJsZSA9IChzbyktPnNtYWxsdGFibGU7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgKHNvKS0+bWFzayA9IFB5U2V0X01JTlNJWkUgLSAxOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIChzbyktPmhhc2ggPSAtMTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICB9IHdoaWxlKDApCisKKyNkZWZpbmUgRU1QVFlfVE9fTUlOU0laRShzbykgZG8geyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgbWVtc2V0KChzbyktPnNtYWxsdGFibGUsIDAsIHNpemVvZigoc28pLT5zbWFsbHRhYmxlKSk7ICAgICAgXAorICAgIChzbyktPnVzZWQgPSAoc28pLT5maWxsID0gMDsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICBJTklUX05PTlpFUk9fU0VUX1NMT1RTKHNvKTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgfSB3aGlsZSgwKQorCisvKiBSZXVzZSBzY2hlbWUgdG8gc2F2ZSBjYWxscyB0byBtYWxsb2MsIGZyZWUsIGFuZCBtZW1zZXQgKi8KKyNpZm5kZWYgUHlTZXRfTUFYRlJFRUxJU1QKKyNkZWZpbmUgUHlTZXRfTUFYRlJFRUxJU1QgODAKKyNlbmRpZgorc3RhdGljIFB5U2V0T2JqZWN0ICpmcmVlX2xpc3RbUHlTZXRfTUFYRlJFRUxJU1RdOworc3RhdGljIGludCBudW1mcmVlID0gMDsKKworLyoKK1RoZSBiYXNpYyBsb29rdXAgZnVuY3Rpb24gdXNlZCBieSBhbGwgb3BlcmF0aW9ucy4KK1RoaXMgaXMgYmFzZWQgb24gQWxnb3JpdGhtIEQgZnJvbSBLbnV0aCBWb2wuIDMsIFNlYy4gNi40LgorT3BlbiBhZGRyZXNzaW5nIGlzIHByZWZlcnJlZCBvdmVyIGNoYWluaW5nIHNpbmNlIHRoZSBsaW5rIG92ZXJoZWFkIGZvcgorY2hhaW5pbmcgd291bGQgYmUgc3Vic3RhbnRpYWwgKDEwMCUgd2l0aCB0eXBpY2FsIG1hbGxvYyBvdmVyaGVhZCkuCisKK1RoZSBpbml0aWFsIHByb2JlIGluZGV4IGlzIGNvbXB1dGVkIGFzIGhhc2ggbW9kIHRoZSB0YWJsZSBzaXplLiBTdWJzZXF1ZW50Citwcm9iZSBpbmRpY2VzIGFyZSBjb21wdXRlZCBhcyBleHBsYWluZWQgaW4gT2JqZWN0cy9kaWN0b2JqZWN0LmMuCisKK0FsbCBhcml0aG1ldGljIG9uIGhhc2ggc2hvdWxkIGlnbm9yZSBvdmVyZmxvdy4KKworVW5saWtlIHRoZSBkaWN0aW9uYXJ5IGltcGxlbWVudGF0aW9uLCB0aGUgbG9va2tleSBmdW5jdGlvbnMgY2FuIHJldHVybgorTlVMTCBpZiB0aGUgcmljaCBjb21wYXJpc29uIHJldHVybnMgYW4gZXJyb3IuCisqLworCitzdGF0aWMgc2V0ZW50cnkgKgorc2V0X2xvb2trZXkoUHlTZXRPYmplY3QgKnNvLCBQeU9iamVjdCAqa2V5LCByZWdpc3RlciBsb25nIGhhc2gpCit7CisgICAgcmVnaXN0ZXIgUHlfc3NpemVfdCBpOworICAgIHJlZ2lzdGVyIHNpemVfdCBwZXJ0dXJiOworICAgIHJlZ2lzdGVyIHNldGVudHJ5ICpmcmVlc2xvdDsKKyAgICByZWdpc3RlciBzaXplX3QgbWFzayA9IHNvLT5tYXNrOworICAgIHNldGVudHJ5ICp0YWJsZSA9IHNvLT50YWJsZTsKKyAgICByZWdpc3RlciBzZXRlbnRyeSAqZW50cnk7CisgICAgcmVnaXN0ZXIgaW50IGNtcDsKKyAgICBQeU9iamVjdCAqc3RhcnRrZXk7CisKKyAgICBpID0gaGFzaCAmIG1hc2s7CisgICAgZW50cnkgPSAmdGFibGVbaV07CisgICAgaWYgKGVudHJ5LT5rZXkgPT0gTlVMTCB8fCBlbnRyeS0+a2V5ID09IGtleSkKKyAgICAgICAgcmV0dXJuIGVudHJ5OworCisgICAgaWYgKGVudHJ5LT5rZXkgPT0gZHVtbXkpCisgICAgICAgIGZyZWVzbG90ID0gZW50cnk7CisgICAgZWxzZSB7CisgICAgICAgIGlmIChlbnRyeS0+aGFzaCA9PSBoYXNoKSB7CisgICAgICAgICAgICBzdGFydGtleSA9IGVudHJ5LT5rZXk7CisgICAgICAgICAgICBQeV9JTkNSRUYoc3RhcnRrZXkpOworICAgICAgICAgICAgY21wID0gUHlPYmplY3RfUmljaENvbXBhcmVCb29sKHN0YXJ0a2V5LCBrZXksIFB5X0VRKTsKKyAgICAgICAgICAgIFB5X0RFQ1JFRihzdGFydGtleSk7CisgICAgICAgICAgICBpZiAoY21wIDwgMCkKKyAgICAgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgICAgIGlmICh0YWJsZSA9PSBzby0+dGFibGUgJiYgZW50cnktPmtleSA9PSBzdGFydGtleSkgeworICAgICAgICAgICAgICAgIGlmIChjbXAgPiAwKQorICAgICAgICAgICAgICAgICAgICByZXR1cm4gZW50cnk7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBlbHNlIHsKKyAgICAgICAgICAgICAgICAvKiBUaGUgY29tcGFyZSBkaWQgbWFqb3IgbmFzdHkgc3R1ZmYgdG8gdGhlCisgICAgICAgICAgICAgICAgICogc2V0OiAgc3RhcnQgb3Zlci4KKyAgICAgICAgICAgICAgICAgKi8KKyAgICAgICAgICAgICAgICByZXR1cm4gc2V0X2xvb2trZXkoc28sIGtleSwgaGFzaCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgZnJlZXNsb3QgPSBOVUxMOworICAgIH0KKworICAgIC8qIEluIHRoZSBsb29wLCBrZXkgPT0gZHVtbXkgaXMgYnkgZmFyIChmYWN0b3Igb2YgMTAwcykgdGhlCisgICAgICAgbGVhc3QgbGlrZWx5IG91dGNvbWUsIHNvIHRlc3QgZm9yIHRoYXQgbGFzdC4gKi8KKyAgICBmb3IgKHBlcnR1cmIgPSBoYXNoOyA7IHBlcnR1cmIgPj49IFBFUlRVUkJfU0hJRlQpIHsKKyAgICAgICAgaSA9IChpIDw8IDIpICsgaSArIHBlcnR1cmIgKyAxOworICAgICAgICBlbnRyeSA9ICZ0YWJsZVtpICYgbWFza107CisgICAgICAgIGlmIChlbnRyeS0+a2V5ID09IE5VTEwpIHsKKyAgICAgICAgICAgIGlmIChmcmVlc2xvdCAhPSBOVUxMKQorICAgICAgICAgICAgICAgIGVudHJ5ID0gZnJlZXNsb3Q7CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgfQorICAgICAgICBpZiAoZW50cnktPmtleSA9PSBrZXkpCisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgaWYgKGVudHJ5LT5oYXNoID09IGhhc2ggJiYgZW50cnktPmtleSAhPSBkdW1teSkgeworICAgICAgICAgICAgc3RhcnRrZXkgPSBlbnRyeS0+a2V5OworICAgICAgICAgICAgUHlfSU5DUkVGKHN0YXJ0a2V5KTsKKyAgICAgICAgICAgIGNtcCA9IFB5T2JqZWN0X1JpY2hDb21wYXJlQm9vbChzdGFydGtleSwga2V5LCBQeV9FUSk7CisgICAgICAgICAgICBQeV9ERUNSRUYoc3RhcnRrZXkpOworICAgICAgICAgICAgaWYgKGNtcCA8IDApCisgICAgICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgICAgICAgICBpZiAodGFibGUgPT0gc28tPnRhYmxlICYmIGVudHJ5LT5rZXkgPT0gc3RhcnRrZXkpIHsKKyAgICAgICAgICAgICAgICBpZiAoY21wID4gMCkKKyAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBlbHNlIHsKKyAgICAgICAgICAgICAgICAvKiBUaGUgY29tcGFyZSBkaWQgbWFqb3IgbmFzdHkgc3R1ZmYgdG8gdGhlCisgICAgICAgICAgICAgICAgICogc2V0OiAgc3RhcnQgb3Zlci4KKyAgICAgICAgICAgICAgICAgKi8KKyAgICAgICAgICAgICAgICByZXR1cm4gc2V0X2xvb2trZXkoc28sIGtleSwgaGFzaCk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgZWxzZSBpZiAoZW50cnktPmtleSA9PSBkdW1teSAmJiBmcmVlc2xvdCA9PSBOVUxMKQorICAgICAgICAgICAgZnJlZXNsb3QgPSBlbnRyeTsKKyAgICB9CisgICAgcmV0dXJuIGVudHJ5OworfQorCisvKgorICogSGFja2VkIHVwIHZlcnNpb24gb2Ygc2V0X2xvb2trZXkgd2hpY2ggY2FuIGFzc3VtZSBrZXlzIGFyZSBhbHdheXMgc3RyaW5nczsKKyAqIFRoaXMgbWVhbnMgd2UgY2FuIGFsd2F5cyB1c2UgX1B5U3RyaW5nX0VxIGRpcmVjdGx5IGFuZCBub3QgaGF2ZSB0byBjaGVjayB0bworICogc2VlIGlmIHRoZSBjb21wYXJpc29uIGFsdGVyZWQgdGhlIHRhYmxlLgorICovCitzdGF0aWMgc2V0ZW50cnkgKgorc2V0X2xvb2trZXlfc3RyaW5nKFB5U2V0T2JqZWN0ICpzbywgUHlPYmplY3QgKmtleSwgcmVnaXN0ZXIgbG9uZyBoYXNoKQoreworICAgIHJlZ2lzdGVyIFB5X3NzaXplX3QgaTsKKyAgICByZWdpc3RlciBzaXplX3QgcGVydHVyYjsKKyAgICByZWdpc3RlciBzZXRlbnRyeSAqZnJlZXNsb3Q7CisgICAgcmVnaXN0ZXIgc2l6ZV90IG1hc2sgPSBzby0+bWFzazsKKyAgICBzZXRlbnRyeSAqdGFibGUgPSBzby0+dGFibGU7CisgICAgcmVnaXN0ZXIgc2V0ZW50cnkgKmVudHJ5OworCisgICAgLyogTWFrZSBzdXJlIHRoaXMgZnVuY3Rpb24gZG9lc24ndCBoYXZlIHRvIGhhbmRsZSBub24tc3RyaW5nIGtleXMsCisgICAgICAgaW5jbHVkaW5nIHN1YmNsYXNzZXMgb2Ygc3RyOyBlLmcuLCBvbmUgcmVhc29uIHRvIHN1YmNsYXNzCisgICAgICAgc3RyaW5ncyBpcyB0byBvdmVycmlkZSBfX2VxX18sIGFuZCBmb3Igc3BlZWQgd2UgZG9uJ3QgY2F0ZXIgdG8KKyAgICAgICB0aGF0IGhlcmUuICovCisgICAgaWYgKCFQeVN0cmluZ19DaGVja0V4YWN0KGtleSkpIHsKKyAgICAgICAgc28tPmxvb2t1cCA9IHNldF9sb29ra2V5OworICAgICAgICByZXR1cm4gc2V0X2xvb2trZXkoc28sIGtleSwgaGFzaCk7CisgICAgfQorICAgIGkgPSBoYXNoICYgbWFzazsKKyAgICBlbnRyeSA9ICZ0YWJsZVtpXTsKKyAgICBpZiAoZW50cnktPmtleSA9PSBOVUxMIHx8IGVudHJ5LT5rZXkgPT0ga2V5KQorICAgICAgICByZXR1cm4gZW50cnk7CisgICAgaWYgKGVudHJ5LT5rZXkgPT0gZHVtbXkpCisgICAgICAgIGZyZWVzbG90ID0gZW50cnk7CisgICAgZWxzZSB7CisgICAgICAgIGlmIChlbnRyeS0+aGFzaCA9PSBoYXNoICYmIF9QeVN0cmluZ19FcShlbnRyeS0+a2V5LCBrZXkpKQorICAgICAgICAgICAgcmV0dXJuIGVudHJ5OworICAgICAgICBmcmVlc2xvdCA9IE5VTEw7CisgICAgfQorCisgICAgLyogSW4gdGhlIGxvb3AsIGtleSA9PSBkdW1teSBpcyBieSBmYXIgKGZhY3RvciBvZiAxMDBzKSB0aGUKKyAgICAgICBsZWFzdCBsaWtlbHkgb3V0Y29tZSwgc28gdGVzdCBmb3IgdGhhdCBsYXN0LiAqLworICAgIGZvciAocGVydHVyYiA9IGhhc2g7IDsgcGVydHVyYiA+Pj0gUEVSVFVSQl9TSElGVCkgeworICAgICAgICBpID0gKGkgPDwgMikgKyBpICsgcGVydHVyYiArIDE7CisgICAgICAgIGVudHJ5ID0gJnRhYmxlW2kgJiBtYXNrXTsKKyAgICAgICAgaWYgKGVudHJ5LT5rZXkgPT0gTlVMTCkKKyAgICAgICAgICAgIHJldHVybiBmcmVlc2xvdCA9PSBOVUxMID8gZW50cnkgOiBmcmVlc2xvdDsKKyAgICAgICAgaWYgKGVudHJ5LT5rZXkgPT0ga2V5CisgICAgICAgICAgICB8fCAoZW50cnktPmhhc2ggPT0gaGFzaAorICAgICAgICAgICAgJiYgZW50cnktPmtleSAhPSBkdW1teQorICAgICAgICAgICAgJiYgX1B5U3RyaW5nX0VxKGVudHJ5LT5rZXksIGtleSkpKQorICAgICAgICAgICAgcmV0dXJuIGVudHJ5OworICAgICAgICBpZiAoZW50cnktPmtleSA9PSBkdW1teSAmJiBmcmVlc2xvdCA9PSBOVUxMKQorICAgICAgICAgICAgZnJlZXNsb3QgPSBlbnRyeTsKKyAgICB9CisgICAgYXNzZXJ0KDApOyAgICAgICAgICAvKiBOT1QgUkVBQ0hFRCAqLworICAgIHJldHVybiAwOworfQorCisvKgorSW50ZXJuYWwgcm91dGluZSB0byBpbnNlcnQgYSBuZXcga2V5IGludG8gdGhlIHRhYmxlLgorVXNlZCBieSB0aGUgcHVibGljIGluc2VydCByb3V0aW5lLgorRWF0cyBhIHJlZmVyZW5jZSB0byBrZXkuCisqLworc3RhdGljIGludAorc2V0X2luc2VydF9rZXkocmVnaXN0ZXIgUHlTZXRPYmplY3QgKnNvLCBQeU9iamVjdCAqa2V5LCBsb25nIGhhc2gpCit7CisgICAgcmVnaXN0ZXIgc2V0ZW50cnkgKmVudHJ5OworICAgIHR5cGVkZWYgc2V0ZW50cnkgKigqbG9va3VwZnVuYykoUHlTZXRPYmplY3QgKiwgUHlPYmplY3QgKiwgbG9uZyk7CisKKyAgICBhc3NlcnQoc28tPmxvb2t1cCAhPSBOVUxMKTsKKyAgICBlbnRyeSA9IHNvLT5sb29rdXAoc28sIGtleSwgaGFzaCk7CisgICAgaWYgKGVudHJ5ID09IE5VTEwpCisgICAgICAgIHJldHVybiAtMTsKKyAgICBpZiAoZW50cnktPmtleSA9PSBOVUxMKSB7CisgICAgICAgIC8qIFVOVVNFRCAqLworICAgICAgICBzby0+ZmlsbCsrOworICAgICAgICBlbnRyeS0+a2V5ID0ga2V5OworICAgICAgICBlbnRyeS0+aGFzaCA9IGhhc2g7CisgICAgICAgIHNvLT51c2VkKys7CisgICAgfSBlbHNlIGlmIChlbnRyeS0+a2V5ID09IGR1bW15KSB7CisgICAgICAgIC8qIERVTU1ZICovCisgICAgICAgIGVudHJ5LT5rZXkgPSBrZXk7CisgICAgICAgIGVudHJ5LT5oYXNoID0gaGFzaDsKKyAgICAgICAgc28tPnVzZWQrKzsKKyAgICAgICAgUHlfREVDUkVGKGR1bW15KTsKKyAgICB9IGVsc2UgeworICAgICAgICAvKiBBQ1RJVkUgKi8KKyAgICAgICAgUHlfREVDUkVGKGtleSk7CisgICAgfQorICAgIHJldHVybiAwOworfQorCisvKgorSW50ZXJuYWwgcm91dGluZSB1c2VkIGJ5IHNldF90YWJsZV9yZXNpemUoKSB0byBpbnNlcnQgYW4gaXRlbSB3aGljaCBpcwora25vd24gdG8gYmUgYWJzZW50IGZyb20gdGhlIHNldC4gIFRoaXMgcm91dGluZSBhbHNvIGFzc3VtZXMgdGhhdAordGhlIHNldCBjb250YWlucyBubyBkZWxldGVkIGVudHJpZXMuICBCZXNpZGVzIHRoZSBwZXJmb3JtYW5jZSBiZW5lZml0LAordXNpbmcgc2V0X2luc2VydF9jbGVhbigpIGluIHNldF90YWJsZV9yZXNpemUoKSBpcyBkYW5nZXJvdXMgKFNGIGJ1ZyAjMTQ1NjIwOSkuCitOb3RlIHRoYXQgbm8gcmVmY291bnRzIGFyZSBjaGFuZ2VkIGJ5IHRoaXMgcm91dGluZTsgaWYgbmVlZGVkLCB0aGUgY2FsbGVyCitpcyByZXNwb25zaWJsZSBmb3IgaW5jcmVmJ2luZyBga2V5YC4KKyovCitzdGF0aWMgdm9pZAorc2V0X2luc2VydF9jbGVhbihyZWdpc3RlciBQeVNldE9iamVjdCAqc28sIFB5T2JqZWN0ICprZXksIGxvbmcgaGFzaCkKK3sKKyAgICByZWdpc3RlciBzaXplX3QgaTsKKyAgICByZWdpc3RlciBzaXplX3QgcGVydHVyYjsKKyAgICByZWdpc3RlciBzaXplX3QgbWFzayA9IChzaXplX3Qpc28tPm1hc2s7CisgICAgc2V0ZW50cnkgKnRhYmxlID0gc28tPnRhYmxlOworICAgIHJlZ2lzdGVyIHNldGVudHJ5ICplbnRyeTsKKworICAgIGkgPSBoYXNoICYgbWFzazsKKyAgICBlbnRyeSA9ICZ0YWJsZVtpXTsKKyAgICBmb3IgKHBlcnR1cmIgPSBoYXNoOyBlbnRyeS0+a2V5ICE9IE5VTEw7IHBlcnR1cmIgPj49IFBFUlRVUkJfU0hJRlQpIHsKKyAgICAgICAgaSA9IChpIDw8IDIpICsgaSArIHBlcnR1cmIgKyAxOworICAgICAgICBlbnRyeSA9ICZ0YWJsZVtpICYgbWFza107CisgICAgfQorICAgIHNvLT5maWxsKys7CisgICAgZW50cnktPmtleSA9IGtleTsKKyAgICBlbnRyeS0+aGFzaCA9IGhhc2g7CisgICAgc28tPnVzZWQrKzsKK30KKworLyoKK1Jlc3RydWN0dXJlIHRoZSB0YWJsZSBieSBhbGxvY2F0aW5nIGEgbmV3IHRhYmxlIGFuZCByZWluc2VydGluZyBhbGwKK2tleXMgYWdhaW4uICBXaGVuIGVudHJpZXMgaGF2ZSBiZWVuIGRlbGV0ZWQsIHRoZSBuZXcgdGFibGUgbWF5CithY3R1YWxseSBiZSBzbWFsbGVyIHRoYW4gdGhlIG9sZCBvbmUuCisqLworc3RhdGljIGludAorc2V0X3RhYmxlX3Jlc2l6ZShQeVNldE9iamVjdCAqc28sIFB5X3NzaXplX3QgbWludXNlZCkKK3sKKyAgICBQeV9zc2l6ZV90IG5ld3NpemU7CisgICAgc2V0ZW50cnkgKm9sZHRhYmxlLCAqbmV3dGFibGUsICplbnRyeTsKKyAgICBQeV9zc2l6ZV90IGk7CisgICAgaW50IGlzX29sZHRhYmxlX21hbGxvY2VkOworICAgIHNldGVudHJ5IHNtYWxsX2NvcHlbUHlTZXRfTUlOU0laRV07CisKKyAgICBhc3NlcnQobWludXNlZCA+PSAwKTsKKworICAgIC8qIEZpbmQgdGhlIHNtYWxsZXN0IHRhYmxlIHNpemUgPiBtaW51c2VkLiAqLworICAgIGZvciAobmV3c2l6ZSA9IFB5U2V0X01JTlNJWkU7CisgICAgICAgICBuZXdzaXplIDw9IG1pbnVzZWQgJiYgbmV3c2l6ZSA+IDA7CisgICAgICAgICBuZXdzaXplIDw8PSAxKQorICAgICAgICA7CisgICAgaWYgKG5ld3NpemUgPD0gMCkgeworICAgICAgICBQeUVycl9Ob01lbW9yeSgpOworICAgICAgICByZXR1cm4gLTE7CisgICAgfQorCisgICAgLyogR2V0IHNwYWNlIGZvciBhIG5ldyB0YWJsZS4gKi8KKyAgICBvbGR0YWJsZSA9IHNvLT50YWJsZTsKKyAgICBhc3NlcnQob2xkdGFibGUgIT0gTlVMTCk7CisgICAgaXNfb2xkdGFibGVfbWFsbG9jZWQgPSBvbGR0YWJsZSAhPSBzby0+c21hbGx0YWJsZTsKKworICAgIGlmIChuZXdzaXplID09IFB5U2V0X01JTlNJWkUpIHsKKyAgICAgICAgLyogQSBsYXJnZSB0YWJsZSBpcyBzaHJpbmtpbmcsIG9yIHdlIGNhbid0IGdldCBhbnkgc21hbGxlci4gKi8KKyAgICAgICAgbmV3dGFibGUgPSBzby0+c21hbGx0YWJsZTsKKyAgICAgICAgaWYgKG5ld3RhYmxlID09IG9sZHRhYmxlKSB7CisgICAgICAgICAgICBpZiAoc28tPmZpbGwgPT0gc28tPnVzZWQpIHsKKyAgICAgICAgICAgICAgICAvKiBObyBkdW1taWVzLCBzbyBubyBwb2ludCBkb2luZyBhbnl0aGluZy4gKi8KKyAgICAgICAgICAgICAgICByZXR1cm4gMDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIC8qIFdlJ3JlIG5vdCBnb2luZyB0byByZXNpemUgaXQsIGJ1dCByZWJ1aWxkIHRoZQorICAgICAgICAgICAgICAgdGFibGUgYW55d2F5IHRvIHB1cmdlIG9sZCBkdW1teSBlbnRyaWVzLgorICAgICAgICAgICAgICAgU3VidGxlOiAgVGhpcyBpcyAqbmVjZXNzYXJ5KiBpZiBmaWxsPT1zaXplLAorICAgICAgICAgICAgICAgYXMgc2V0X2xvb2trZXkgbmVlZHMgYXQgbGVhc3Qgb25lIHZpcmdpbiBzbG90IHRvCisgICAgICAgICAgICAgICB0ZXJtaW5hdGUgZmFpbGluZyBzZWFyY2hlcy4gIElmIGZpbGwgPCBzaXplLCBpdCdzCisgICAgICAgICAgICAgICBtZXJlbHkgZGVzaXJhYmxlLCBhcyBkdW1taWVzIHNsb3cgc2VhcmNoZXMuICovCisgICAgICAgICAgICBhc3NlcnQoc28tPmZpbGwgPiBzby0+dXNlZCk7CisgICAgICAgICAgICBtZW1jcHkoc21hbGxfY29weSwgb2xkdGFibGUsIHNpemVvZihzbWFsbF9jb3B5KSk7CisgICAgICAgICAgICBvbGR0YWJsZSA9IHNtYWxsX2NvcHk7CisgICAgICAgIH0KKyAgICB9CisgICAgZWxzZSB7CisgICAgICAgIG5ld3RhYmxlID0gUHlNZW1fTkVXKHNldGVudHJ5LCBuZXdzaXplKTsKKyAgICAgICAgaWYgKG5ld3RhYmxlID09IE5VTEwpIHsKKyAgICAgICAgICAgIFB5RXJyX05vTWVtb3J5KCk7CisgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKiBNYWtlIHRoZSBzZXQgZW1wdHksIHVzaW5nIHRoZSBuZXcgdGFibGUuICovCisgICAgYXNzZXJ0KG5ld3RhYmxlICE9IG9sZHRhYmxlKTsKKyAgICBzby0+dGFibGUgPSBuZXd0YWJsZTsKKyAgICBzby0+bWFzayA9IG5ld3NpemUgLSAxOworICAgIG1lbXNldChuZXd0YWJsZSwgMCwgc2l6ZW9mKHNldGVudHJ5KSAqIG5ld3NpemUpOworICAgIHNvLT51c2VkID0gMDsKKyAgICBpID0gc28tPmZpbGw7CisgICAgc28tPmZpbGwgPSAwOworCisgICAgLyogQ29weSB0aGUgZGF0YSBvdmVyOyB0aGlzIGlzIHJlZmNvdW50LW5ldXRyYWwgZm9yIGFjdGl2ZSBlbnRyaWVzOworICAgICAgIGR1bW15IGVudHJpZXMgYXJlbid0IGNvcGllZCBvdmVyLCBvZiBjb3Vyc2UgKi8KKyAgICBmb3IgKGVudHJ5ID0gb2xkdGFibGU7IGkgPiAwOyBlbnRyeSsrKSB7CisgICAgICAgIGlmIChlbnRyeS0+a2V5ID09IE5VTEwpIHsKKyAgICAgICAgICAgIC8qIFVOVVNFRCAqLworICAgICAgICAgICAgOworICAgICAgICB9IGVsc2UgaWYgKGVudHJ5LT5rZXkgPT0gZHVtbXkpIHsKKyAgICAgICAgICAgIC8qIERVTU1ZICovCisgICAgICAgICAgICAtLWk7CisgICAgICAgICAgICBhc3NlcnQoZW50cnktPmtleSA9PSBkdW1teSk7CisgICAgICAgICAgICBQeV9ERUNSRUYoZW50cnktPmtleSk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAvKiBBQ1RJVkUgKi8KKyAgICAgICAgICAgIC0taTsKKyAgICAgICAgICAgIHNldF9pbnNlcnRfY2xlYW4oc28sIGVudHJ5LT5rZXksIGVudHJ5LT5oYXNoKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIGlmIChpc19vbGR0YWJsZV9tYWxsb2NlZCkKKyAgICAgICAgUHlNZW1fREVMKG9sZHRhYmxlKTsKKyAgICByZXR1cm4gMDsKK30KKworLyogQ0FVVElPTjogc2V0X2FkZF9rZXkvZW50cnkoKSBtdXN0IGd1YXJhbnRlZSBpdCB3b24ndCByZXNpemUgdGhlIHRhYmxlICovCisKK3N0YXRpYyBpbnQKK3NldF9hZGRfZW50cnkocmVnaXN0ZXIgUHlTZXRPYmplY3QgKnNvLCBzZXRlbnRyeSAqZW50cnkpCit7CisgICAgcmVnaXN0ZXIgUHlfc3NpemVfdCBuX3VzZWQ7CisgICAgUHlPYmplY3QgKmtleSA9IGVudHJ5LT5rZXk7CisgICAgbG9uZyBoYXNoID0gZW50cnktPmhhc2g7CisKKyAgICBhc3NlcnQoc28tPmZpbGwgPD0gc28tPm1hc2spOyAgLyogYXQgbGVhc3Qgb25lIGVtcHR5IHNsb3QgKi8KKyAgICBuX3VzZWQgPSBzby0+dXNlZDsKKyAgICBQeV9JTkNSRUYoa2V5KTsKKyAgICBpZiAoc2V0X2luc2VydF9rZXkoc28sIGtleSwgaGFzaCkgPT0gLTEpIHsKKyAgICAgICAgUHlfREVDUkVGKGtleSk7CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisgICAgaWYgKCEoc28tPnVzZWQgPiBuX3VzZWQgJiYgc28tPmZpbGwqMyA+PSAoc28tPm1hc2srMSkqMikpCisgICAgICAgIHJldHVybiAwOworICAgIHJldHVybiBzZXRfdGFibGVfcmVzaXplKHNvLCBzby0+dXNlZD41MDAwMCA/IHNvLT51c2VkKjIgOiBzby0+dXNlZCo0KTsKK30KKworc3RhdGljIGludAorc2V0X2FkZF9rZXkocmVnaXN0ZXIgUHlTZXRPYmplY3QgKnNvLCBQeU9iamVjdCAqa2V5KQoreworICAgIHJlZ2lzdGVyIGxvbmcgaGFzaDsKKyAgICByZWdpc3RlciBQeV9zc2l6ZV90IG5fdXNlZDsKKworICAgIGlmICghUHlTdHJpbmdfQ2hlY2tFeGFjdChrZXkpIHx8CisgICAgICAgIChoYXNoID0gKChQeVN0cmluZ09iamVjdCAqKSBrZXkpLT5vYl9zaGFzaCkgPT0gLTEpIHsKKyAgICAgICAgaGFzaCA9IFB5T2JqZWN0X0hhc2goa2V5KTsKKyAgICAgICAgaWYgKGhhc2ggPT0gLTEpCisgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgfQorICAgIGFzc2VydChzby0+ZmlsbCA8PSBzby0+bWFzayk7ICAvKiBhdCBsZWFzdCBvbmUgZW1wdHkgc2xvdCAqLworICAgIG5fdXNlZCA9IHNvLT51c2VkOworICAgIFB5X0lOQ1JFRihrZXkpOworICAgIGlmIChzZXRfaW5zZXJ0X2tleShzbywga2V5LCBoYXNoKSA9PSAtMSkgeworICAgICAgICBQeV9ERUNSRUYoa2V5KTsKKyAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKyAgICBpZiAoIShzby0+dXNlZCA+IG5fdXNlZCAmJiBzby0+ZmlsbCozID49IChzby0+bWFzaysxKSoyKSkKKyAgICAgICAgcmV0dXJuIDA7CisgICAgcmV0dXJuIHNldF90YWJsZV9yZXNpemUoc28sIHNvLT51c2VkPjUwMDAwID8gc28tPnVzZWQqMiA6IHNvLT51c2VkKjQpOworfQorCisjZGVmaW5lIERJU0NBUkRfTk9URk9VTkQgMAorI2RlZmluZSBESVNDQVJEX0ZPVU5EIDEKKworc3RhdGljIGludAorc2V0X2Rpc2NhcmRfZW50cnkoUHlTZXRPYmplY3QgKnNvLCBzZXRlbnRyeSAqb2xkZW50cnkpCit7ICAgICAgIHJlZ2lzdGVyIHNldGVudHJ5ICplbnRyeTsKKyAgICBQeU9iamVjdCAqb2xkX2tleTsKKworICAgIGVudHJ5ID0gKHNvLT5sb29rdXApKHNvLCBvbGRlbnRyeS0+a2V5LCBvbGRlbnRyeS0+aGFzaCk7CisgICAgaWYgKGVudHJ5ID09IE5VTEwpCisgICAgICAgIHJldHVybiAtMTsKKyAgICBpZiAoZW50cnktPmtleSA9PSBOVUxMICB8fCAgZW50cnktPmtleSA9PSBkdW1teSkKKyAgICAgICAgcmV0dXJuIERJU0NBUkRfTk9URk9VTkQ7CisgICAgb2xkX2tleSA9IGVudHJ5LT5rZXk7CisgICAgUHlfSU5DUkVGKGR1bW15KTsKKyAgICBlbnRyeS0+a2V5ID0gZHVtbXk7CisgICAgc28tPnVzZWQtLTsKKyAgICBQeV9ERUNSRUYob2xkX2tleSk7CisgICAgcmV0dXJuIERJU0NBUkRfRk9VTkQ7Cit9CisKK3N0YXRpYyBpbnQKK3NldF9kaXNjYXJkX2tleShQeVNldE9iamVjdCAqc28sIFB5T2JqZWN0ICprZXkpCit7CisgICAgcmVnaXN0ZXIgbG9uZyBoYXNoOworICAgIHJlZ2lzdGVyIHNldGVudHJ5ICplbnRyeTsKKyAgICBQeU9iamVjdCAqb2xkX2tleTsKKworICAgIGFzc2VydCAoUHlBbnlTZXRfQ2hlY2soc28pKTsKKyAgICBpZiAoIVB5U3RyaW5nX0NoZWNrRXhhY3Qoa2V5KSB8fAorICAgICAgICAoaGFzaCA9ICgoUHlTdHJpbmdPYmplY3QgKikga2V5KS0+b2Jfc2hhc2gpID09IC0xKSB7CisgICAgICAgIGhhc2ggPSBQeU9iamVjdF9IYXNoKGtleSk7CisgICAgICAgIGlmIChoYXNoID09IC0xKQorICAgICAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKyAgICBlbnRyeSA9IChzby0+bG9va3VwKShzbywga2V5LCBoYXNoKTsKKyAgICBpZiAoZW50cnkgPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIC0xOworICAgIGlmIChlbnRyeS0+a2V5ID09IE5VTEwgIHx8ICBlbnRyeS0+a2V5ID09IGR1bW15KQorICAgICAgICByZXR1cm4gRElTQ0FSRF9OT1RGT1VORDsKKyAgICBvbGRfa2V5ID0gZW50cnktPmtleTsKKyAgICBQeV9JTkNSRUYoZHVtbXkpOworICAgIGVudHJ5LT5rZXkgPSBkdW1teTsKKyAgICBzby0+dXNlZC0tOworICAgIFB5X0RFQ1JFRihvbGRfa2V5KTsKKyAgICByZXR1cm4gRElTQ0FSRF9GT1VORDsKK30KKworc3RhdGljIGludAorc2V0X2NsZWFyX2ludGVybmFsKFB5U2V0T2JqZWN0ICpzbykKK3sKKyAgICBzZXRlbnRyeSAqZW50cnksICp0YWJsZTsKKyAgICBpbnQgdGFibGVfaXNfbWFsbG9jZWQ7CisgICAgUHlfc3NpemVfdCBmaWxsOworICAgIHNldGVudHJ5IHNtYWxsX2NvcHlbUHlTZXRfTUlOU0laRV07CisjaWZkZWYgUHlfREVCVUcKKyAgICBQeV9zc2l6ZV90IGksIG47CisgICAgYXNzZXJ0IChQeUFueVNldF9DaGVjayhzbykpOworCisgICAgbiA9IHNvLT5tYXNrICsgMTsKKyAgICBpID0gMDsKKyNlbmRpZgorCisgICAgdGFibGUgPSBzby0+dGFibGU7CisgICAgYXNzZXJ0KHRhYmxlICE9IE5VTEwpOworICAgIHRhYmxlX2lzX21hbGxvY2VkID0gdGFibGUgIT0gc28tPnNtYWxsdGFibGU7CisKKyAgICAvKiBUaGlzIGlzIGRlbGljYXRlLiAgRHVyaW5nIHRoZSBwcm9jZXNzIG9mIGNsZWFyaW5nIHRoZSBzZXQsCisgICAgICogZGVjcmVmcyBjYW4gY2F1c2UgdGhlIHNldCB0byBtdXRhdGUuICBUbyBhdm9pZCBmYXRhbCBjb25mdXNpb24KKyAgICAgKiAodm9pY2Ugb2YgZXhwZXJpZW5jZSksIHdlIGhhdmUgdG8gbWFrZSB0aGUgc2V0IGVtcHR5IGJlZm9yZQorICAgICAqIGNsZWFyaW5nIHRoZSBzbG90cywgYW5kIG5ldmVyIHJlZmVyIHRvIGFueXRoaW5nIHZpYSBzby0+cmVmIHdoaWxlCisgICAgICogY2xlYXJpbmcuCisgICAgICovCisgICAgZmlsbCA9IHNvLT5maWxsOworICAgIGlmICh0YWJsZV9pc19tYWxsb2NlZCkKKyAgICAgICAgRU1QVFlfVE9fTUlOU0laRShzbyk7CisKKyAgICBlbHNlIGlmIChmaWxsID4gMCkgeworICAgICAgICAvKiBJdCdzIGEgc21hbGwgdGFibGUgd2l0aCBzb21ldGhpbmcgdGhhdCBuZWVkcyB0byBiZSBjbGVhcmVkLgorICAgICAgICAgKiBBZnJhaWQgdGhlIG9ubHkgc2FmZSB3YXkgaXMgdG8gY29weSB0aGUgc2V0IGVudHJpZXMgaW50bworICAgICAgICAgKiBhbm90aGVyIHNtYWxsIHRhYmxlIGZpcnN0LgorICAgICAgICAgKi8KKyAgICAgICAgbWVtY3B5KHNtYWxsX2NvcHksIHRhYmxlLCBzaXplb2Yoc21hbGxfY29weSkpOworICAgICAgICB0YWJsZSA9IHNtYWxsX2NvcHk7CisgICAgICAgIEVNUFRZX1RPX01JTlNJWkUoc28pOworICAgIH0KKyAgICAvKiBlbHNlIGl0J3MgYSBzbWFsbCB0YWJsZSB0aGF0J3MgYWxyZWFkeSBlbXB0eSAqLworCisgICAgLyogTm93IHdlIGNhbiBmaW5hbGx5IGNsZWFyIHRoaW5ncy4gIElmIEMgaGFkIHJlZmNvdW50cywgd2UgY291bGQKKyAgICAgKiBhc3NlcnQgdGhhdCB0aGUgcmVmY291bnQgb24gdGFibGUgaXMgMSBub3csIGkuZS4gdGhhdCB0aGlzIGZ1bmN0aW9uCisgICAgICogaGFzIHVuaXF1ZSBhY2Nlc3MgdG8gaXQsIHNvIGRlY3JlZiBzaWRlLWVmZmVjdHMgY2FuJ3QgYWx0ZXIgaXQuCisgICAgICovCisgICAgZm9yIChlbnRyeSA9IHRhYmxlOyBmaWxsID4gMDsgKytlbnRyeSkgeworI2lmZGVmIFB5X0RFQlVHCisgICAgICAgIGFzc2VydChpIDwgbik7CisgICAgICAgICsraTsKKyNlbmRpZgorICAgICAgICBpZiAoZW50cnktPmtleSkgeworICAgICAgICAgICAgLS1maWxsOworICAgICAgICAgICAgUHlfREVDUkVGKGVudHJ5LT5rZXkpOworICAgICAgICB9CisjaWZkZWYgUHlfREVCVUcKKyAgICAgICAgZWxzZQorICAgICAgICAgICAgYXNzZXJ0KGVudHJ5LT5rZXkgPT0gTlVMTCk7CisjZW5kaWYKKyAgICB9CisKKyAgICBpZiAodGFibGVfaXNfbWFsbG9jZWQpCisgICAgICAgIFB5TWVtX0RFTCh0YWJsZSk7CisgICAgcmV0dXJuIDA7Cit9CisKKy8qCisgKiBJdGVyYXRlIG92ZXIgYSBzZXQgdGFibGUuICBVc2UgbGlrZSBzbzoKKyAqCisgKiAgICAgUHlfc3NpemVfdCBwb3M7CisgKiAgICAgc2V0ZW50cnkgKmVudHJ5OworICogICAgIHBvcyA9IDA7ICAgIyBpbXBvcnRhbnQhICBwb3Mgc2hvdWxkIG5vdCBvdGhlcndpc2UgYmUgY2hhbmdlZCBieSB5b3UKKyAqICAgICB3aGlsZSAoc2V0X25leHQoeW91cnNldCwgJnBvcywgJmVudHJ5KSkgeworICogICAgICAgICAgICAgIFJlZmVyIHRvIGJvcnJvd2VkIHJlZmVyZW5jZSBpbiBlbnRyeS0+a2V5LgorICogICAgIH0KKyAqCisgKiBDQVVUSU9OOiAgSW4gZ2VuZXJhbCwgaXQgaXNuJ3Qgc2FmZSB0byB1c2Ugc2V0X25leHQgaW4gYSBsb29wIHRoYXQKKyAqIG11dGF0ZXMgdGhlIHRhYmxlLgorICovCitzdGF0aWMgaW50CitzZXRfbmV4dChQeVNldE9iamVjdCAqc28sIFB5X3NzaXplX3QgKnBvc19wdHIsIHNldGVudHJ5ICoqZW50cnlfcHRyKQoreworICAgIFB5X3NzaXplX3QgaTsKKyAgICBQeV9zc2l6ZV90IG1hc2s7CisgICAgcmVnaXN0ZXIgc2V0ZW50cnkgKnRhYmxlOworCisgICAgYXNzZXJ0IChQeUFueVNldF9DaGVjayhzbykpOworICAgIGkgPSAqcG9zX3B0cjsKKyAgICBhc3NlcnQoaSA+PSAwKTsKKyAgICB0YWJsZSA9IHNvLT50YWJsZTsKKyAgICBtYXNrID0gc28tPm1hc2s7CisgICAgd2hpbGUgKGkgPD0gbWFzayAmJiAodGFibGVbaV0ua2V5ID09IE5VTEwgfHwgdGFibGVbaV0ua2V5ID09IGR1bW15KSkKKyAgICAgICAgaSsrOworICAgICpwb3NfcHRyID0gaSsxOworICAgIGlmIChpID4gbWFzaykKKyAgICAgICAgcmV0dXJuIDA7CisgICAgYXNzZXJ0KHRhYmxlW2ldLmtleSAhPSBOVUxMKTsKKyAgICAqZW50cnlfcHRyID0gJnRhYmxlW2ldOworICAgIHJldHVybiAxOworfQorCitzdGF0aWMgdm9pZAorc2V0X2RlYWxsb2MoUHlTZXRPYmplY3QgKnNvKQoreworICAgIHJlZ2lzdGVyIHNldGVudHJ5ICplbnRyeTsKKyAgICBQeV9zc2l6ZV90IGZpbGwgPSBzby0+ZmlsbDsKKyAgICBQeU9iamVjdF9HQ19VblRyYWNrKHNvKTsKKyAgICBQeV9UUkFTSENBTl9TQUZFX0JFR0lOKHNvKQorICAgIGlmIChzby0+d2Vha3JlZmxpc3QgIT0gTlVMTCkKKyAgICAgICAgUHlPYmplY3RfQ2xlYXJXZWFrUmVmcygoUHlPYmplY3QgKikgc28pOworCisgICAgZm9yIChlbnRyeSA9IHNvLT50YWJsZTsgZmlsbCA+IDA7IGVudHJ5KyspIHsKKyAgICAgICAgaWYgKGVudHJ5LT5rZXkpIHsKKyAgICAgICAgICAgIC0tZmlsbDsKKyAgICAgICAgICAgIFB5X0RFQ1JFRihlbnRyeS0+a2V5KTsKKyAgICAgICAgfQorICAgIH0KKyAgICBpZiAoc28tPnRhYmxlICE9IHNvLT5zbWFsbHRhYmxlKQorICAgICAgICBQeU1lbV9ERUwoc28tPnRhYmxlKTsKKyAgICBpZiAobnVtZnJlZSA8IFB5U2V0X01BWEZSRUVMSVNUICYmIFB5QW55U2V0X0NoZWNrRXhhY3Qoc28pKQorICAgICAgICBmcmVlX2xpc3RbbnVtZnJlZSsrXSA9IHNvOworICAgIGVsc2UKKyAgICAgICAgUHlfVFlQRShzbyktPnRwX2ZyZWUoc28pOworICAgIFB5X1RSQVNIQ0FOX1NBRkVfRU5EKHNvKQorfQorCitzdGF0aWMgaW50CitzZXRfdHBfcHJpbnQoUHlTZXRPYmplY3QgKnNvLCBGSUxFICpmcCwgaW50IGZsYWdzKQoreworICAgIHNldGVudHJ5ICplbnRyeTsKKyAgICBQeV9zc2l6ZV90IHBvcz0wOworICAgIGNoYXIgKmVtaXQgPSAiIjsgICAgICAgICAgICAvKiBObyBzZXBhcmF0b3IgZW1pdHRlZCBvbiBmaXJzdCBwYXNzICovCisgICAgY2hhciAqc2VwYXJhdG9yID0gIiwgIjsKKyAgICBpbnQgc3RhdHVzID0gUHlfUmVwckVudGVyKChQeU9iamVjdCopc28pOworCisgICAgaWYgKHN0YXR1cyAhPSAwKSB7CisgICAgICAgIGlmIChzdGF0dXMgPCAwKQorICAgICAgICAgICAgcmV0dXJuIHN0YXR1czsKKyAgICAgICAgUHlfQkVHSU5fQUxMT1dfVEhSRUFEUworICAgICAgICBmcHJpbnRmKGZwLCAiJXMoLi4uKSIsIHNvLT5vYl90eXBlLT50cF9uYW1lKTsKKyAgICAgICAgUHlfRU5EX0FMTE9XX1RIUkVBRFMKKyAgICAgICAgcmV0dXJuIDA7CisgICAgfQorCisgICAgUHlfQkVHSU5fQUxMT1dfVEhSRUFEUworICAgIGZwcmludGYoZnAsICIlcyhbIiwgc28tPm9iX3R5cGUtPnRwX25hbWUpOworICAgIFB5X0VORF9BTExPV19USFJFQURTCisgICAgd2hpbGUgKHNldF9uZXh0KHNvLCAmcG9zLCAmZW50cnkpKSB7CisgICAgICAgIFB5X0JFR0lOX0FMTE9XX1RIUkVBRFMKKyAgICAgICAgZnB1dHMoZW1pdCwgZnApOworICAgICAgICBQeV9FTkRfQUxMT1dfVEhSRUFEUworICAgICAgICBlbWl0ID0gc2VwYXJhdG9yOworICAgICAgICBpZiAoUHlPYmplY3RfUHJpbnQoZW50cnktPmtleSwgZnAsIDApICE9IDApIHsKKyAgICAgICAgICAgIFB5X1JlcHJMZWF2ZSgoUHlPYmplY3QqKXNvKTsKKyAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgfQorICAgIH0KKyAgICBQeV9CRUdJTl9BTExPV19USFJFQURTCisgICAgZnB1dHMoIl0pIiwgZnApOworICAgIFB5X0VORF9BTExPV19USFJFQURTCisgICAgUHlfUmVwckxlYXZlKChQeU9iamVjdCopc28pOworICAgIHJldHVybiAwOworfQorCitzdGF0aWMgUHlPYmplY3QgKgorc2V0X3JlcHIoUHlTZXRPYmplY3QgKnNvKQoreworICAgIFB5T2JqZWN0ICprZXlzLCAqcmVzdWx0PU5VTEwsICpsaXN0cmVwcjsKKyAgICBpbnQgc3RhdHVzID0gUHlfUmVwckVudGVyKChQeU9iamVjdCopc28pOworCisgICAgaWYgKHN0YXR1cyAhPSAwKSB7CisgICAgICAgIGlmIChzdGF0dXMgPCAwKQorICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgICAgIHJldHVybiBQeVN0cmluZ19Gcm9tRm9ybWF0KCIlcyguLi4pIiwgc28tPm9iX3R5cGUtPnRwX25hbWUpOworICAgIH0KKworICAgIGtleXMgPSBQeVNlcXVlbmNlX0xpc3QoKFB5T2JqZWN0ICopc28pOworICAgIGlmIChrZXlzID09IE5VTEwpCisgICAgICAgIGdvdG8gZG9uZTsKKyAgICBsaXN0cmVwciA9IFB5T2JqZWN0X1JlcHIoa2V5cyk7CisgICAgUHlfREVDUkVGKGtleXMpOworICAgIGlmIChsaXN0cmVwciA9PSBOVUxMKQorICAgICAgICBnb3RvIGRvbmU7CisKKyAgICByZXN1bHQgPSBQeVN0cmluZ19Gcm9tRm9ybWF0KCIlcyglcykiLCBzby0+b2JfdHlwZS0+dHBfbmFtZSwKKyAgICAgICAgUHlTdHJpbmdfQVNfU1RSSU5HKGxpc3RyZXByKSk7CisgICAgUHlfREVDUkVGKGxpc3RyZXByKTsKK2RvbmU6CisgICAgUHlfUmVwckxlYXZlKChQeU9iamVjdCopc28pOworICAgIHJldHVybiByZXN1bHQ7Cit9CisKK3N0YXRpYyBQeV9zc2l6ZV90CitzZXRfbGVuKFB5T2JqZWN0ICpzbykKK3sKKyAgICByZXR1cm4gKChQeVNldE9iamVjdCAqKXNvKS0+dXNlZDsKK30KKworc3RhdGljIGludAorc2V0X21lcmdlKFB5U2V0T2JqZWN0ICpzbywgUHlPYmplY3QgKm90aGVyc2V0KQoreworICAgIFB5U2V0T2JqZWN0ICpvdGhlcjsKKyAgICBQeU9iamVjdCAqa2V5OworICAgIGxvbmcgaGFzaDsKKyAgICByZWdpc3RlciBQeV9zc2l6ZV90IGk7CisgICAgcmVnaXN0ZXIgc2V0ZW50cnkgKmVudHJ5OworCisgICAgYXNzZXJ0IChQeUFueVNldF9DaGVjayhzbykpOworICAgIGFzc2VydCAoUHlBbnlTZXRfQ2hlY2sob3RoZXJzZXQpKTsKKworICAgIG90aGVyID0gKFB5U2V0T2JqZWN0KilvdGhlcnNldDsKKyAgICBpZiAob3RoZXIgPT0gc28gfHwgb3RoZXItPnVzZWQgPT0gMCkKKyAgICAgICAgLyogYS51cGRhdGUoYSkgb3IgYS51cGRhdGUoe30pOyBub3RoaW5nIHRvIGRvICovCisgICAgICAgIHJldHVybiAwOworICAgIC8qIERvIG9uZSBiaWcgcmVzaXplIGF0IHRoZSBzdGFydCwgcmF0aGVyIHRoYW4KKyAgICAgKiBpbmNyZW1lbnRhbGx5IHJlc2l6aW5nIGFzIHdlIGluc2VydCBuZXcga2V5cy4gIEV4cGVjdAorICAgICAqIHRoYXQgdGhlcmUgd2lsbCBiZSBubyAob3IgZmV3KSBvdmVybGFwcGluZyBrZXlzLgorICAgICAqLworICAgIGlmICgoc28tPmZpbGwgKyBvdGhlci0+dXNlZCkqMyA+PSAoc28tPm1hc2srMSkqMikgeworICAgICAgIGlmIChzZXRfdGFibGVfcmVzaXplKHNvLCAoc28tPnVzZWQgKyBvdGhlci0+dXNlZCkqMikgIT0gMCkKKyAgICAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKyAgICBmb3IgKGkgPSAwOyBpIDw9IG90aGVyLT5tYXNrOyBpKyspIHsKKyAgICAgICAgZW50cnkgPSAmb3RoZXItPnRhYmxlW2ldOworICAgICAgICBrZXkgPSBlbnRyeS0+a2V5OworICAgICAgICBoYXNoID0gZW50cnktPmhhc2g7CisgICAgICAgIGlmIChrZXkgIT0gTlVMTCAmJgorICAgICAgICAgICAga2V5ICE9IGR1bW15KSB7CisgICAgICAgICAgICBQeV9JTkNSRUYoa2V5KTsKKyAgICAgICAgICAgIGlmIChzZXRfaW5zZXJ0X2tleShzbywga2V5LCBoYXNoKSA9PSAtMSkgeworICAgICAgICAgICAgICAgIFB5X0RFQ1JFRihrZXkpOworICAgICAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKyAgICByZXR1cm4gMDsKK30KKworc3RhdGljIGludAorc2V0X2NvbnRhaW5zX2tleShQeVNldE9iamVjdCAqc28sIFB5T2JqZWN0ICprZXkpCit7CisgICAgbG9uZyBoYXNoOworICAgIHNldGVudHJ5ICplbnRyeTsKKworICAgIGlmICghUHlTdHJpbmdfQ2hlY2tFeGFjdChrZXkpIHx8CisgICAgICAgIChoYXNoID0gKChQeVN0cmluZ09iamVjdCAqKSBrZXkpLT5vYl9zaGFzaCkgPT0gLTEpIHsKKyAgICAgICAgaGFzaCA9IFB5T2JqZWN0X0hhc2goa2V5KTsKKyAgICAgICAgaWYgKGhhc2ggPT0gLTEpCisgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgfQorICAgIGVudHJ5ID0gKHNvLT5sb29rdXApKHNvLCBrZXksIGhhc2gpOworICAgIGlmIChlbnRyeSA9PSBOVUxMKQorICAgICAgICByZXR1cm4gLTE7CisgICAga2V5ID0gZW50cnktPmtleTsKKyAgICByZXR1cm4ga2V5ICE9IE5VTEwgJiYga2V5ICE9IGR1bW15OworfQorCitzdGF0aWMgaW50CitzZXRfY29udGFpbnNfZW50cnkoUHlTZXRPYmplY3QgKnNvLCBzZXRlbnRyeSAqZW50cnkpCit7CisgICAgUHlPYmplY3QgKmtleTsKKyAgICBzZXRlbnRyeSAqbHVfZW50cnk7CisKKyAgICBsdV9lbnRyeSA9IChzby0+bG9va3VwKShzbywgZW50cnktPmtleSwgZW50cnktPmhhc2gpOworICAgIGlmIChsdV9lbnRyeSA9PSBOVUxMKQorICAgICAgICByZXR1cm4gLTE7CisgICAga2V5ID0gbHVfZW50cnktPmtleTsKKyAgICByZXR1cm4ga2V5ICE9IE5VTEwgJiYga2V5ICE9IGR1bW15OworfQorCitzdGF0aWMgUHlPYmplY3QgKgorc2V0X3BvcChQeVNldE9iamVjdCAqc28pCit7CisgICAgcmVnaXN0ZXIgUHlfc3NpemVfdCBpID0gMDsKKyAgICByZWdpc3RlciBzZXRlbnRyeSAqZW50cnk7CisgICAgUHlPYmplY3QgKmtleTsKKworICAgIGFzc2VydCAoUHlBbnlTZXRfQ2hlY2soc28pKTsKKyAgICBpZiAoc28tPnVzZWQgPT0gMCkgeworICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfS2V5RXJyb3IsICJwb3AgZnJvbSBhbiBlbXB0eSBzZXQiKTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorCisgICAgLyogU2V0IGVudHJ5IHRvICJ0aGUgZmlyc3QiIHVudXNlZCBvciBkdW1teSBzZXQgZW50cnkuICBXZSBhYnVzZQorICAgICAqIHRoZSBoYXNoIGZpZWxkIG9mIHNsb3QgMCB0byBob2xkIGEgc2VhcmNoIGZpbmdlcjoKKyAgICAgKiBJZiBzbG90IDAgaGFzIGEgdmFsdWUsIHVzZSBzbG90IDAuCisgICAgICogRWxzZSBzbG90IDAgaXMgYmVpbmcgdXNlZCB0byBob2xkIGEgc2VhcmNoIGZpbmdlciwKKyAgICAgKiBhbmQgd2UgdXNlIGl0cyBoYXNoIHZhbHVlIGFzIHRoZSBmaXJzdCBpbmRleCB0byBsb29rLgorICAgICAqLworICAgIGVudHJ5ID0gJnNvLT50YWJsZVswXTsKKyAgICBpZiAoZW50cnktPmtleSA9PSBOVUxMIHx8IGVudHJ5LT5rZXkgPT0gZHVtbXkpIHsKKyAgICAgICAgaSA9IGVudHJ5LT5oYXNoOworICAgICAgICAvKiBUaGUgaGFzaCBmaWVsZCBtYXkgYmUgYSByZWFsIGhhc2ggdmFsdWUsIG9yIGl0IG1heSBiZSBhCisgICAgICAgICAqIGxlZ2l0IHNlYXJjaCBmaW5nZXIsIG9yIGl0IG1heSBiZSBhIG9uY2UtbGVnaXQgc2VhcmNoCisgICAgICAgICAqIGZpbmdlciB0aGF0J3Mgb3V0IG9mIGJvdW5kcyBub3cgYmVjYXVzZSBpdCB3cmFwcGVkIGFyb3VuZAorICAgICAgICAgKiBvciB0aGUgdGFibGUgc2hydW5rIC0tIHNpbXBseSBtYWtlIHN1cmUgaXQncyBpbiBib3VuZHMgbm93LgorICAgICAgICAgKi8KKyAgICAgICAgaWYgKGkgPiBzby0+bWFzayB8fCBpIDwgMSkKKyAgICAgICAgICAgIGkgPSAxOyAgICAgICAgICAgICAgLyogc2tpcCBzbG90IDAgKi8KKyAgICAgICAgd2hpbGUgKChlbnRyeSA9ICZzby0+dGFibGVbaV0pLT5rZXkgPT0gTlVMTCB8fCBlbnRyeS0+a2V5PT1kdW1teSkgeworICAgICAgICAgICAgaSsrOworICAgICAgICAgICAgaWYgKGkgPiBzby0+bWFzaykKKyAgICAgICAgICAgICAgICBpID0gMTsKKyAgICAgICAgfQorICAgIH0KKyAgICBrZXkgPSBlbnRyeS0+a2V5OworICAgIFB5X0lOQ1JFRihkdW1teSk7CisgICAgZW50cnktPmtleSA9IGR1bW15OworICAgIHNvLT51c2VkLS07CisgICAgc28tPnRhYmxlWzBdLmhhc2ggPSBpICsgMTsgIC8qIG5leHQgcGxhY2UgdG8gc3RhcnQgKi8KKyAgICByZXR1cm4ga2V5OworfQorCitQeURvY19TVFJWQVIocG9wX2RvYywgIlJlbW92ZSBhbmQgcmV0dXJuIGFuIGFyYml0cmFyeSBzZXQgZWxlbWVudC5cblwKK1JhaXNlcyBLZXlFcnJvciBpZiB0aGUgc2V0IGlzIGVtcHR5LiIpOworCitzdGF0aWMgaW50CitzZXRfdHJhdmVyc2UoUHlTZXRPYmplY3QgKnNvLCB2aXNpdHByb2MgdmlzaXQsIHZvaWQgKmFyZykKK3sKKyAgICBQeV9zc2l6ZV90IHBvcyA9IDA7CisgICAgc2V0ZW50cnkgKmVudHJ5OworCisgICAgd2hpbGUgKHNldF9uZXh0KHNvLCAmcG9zLCAmZW50cnkpKQorICAgICAgICBQeV9WSVNJVChlbnRyeS0+a2V5KTsKKyAgICByZXR1cm4gMDsKK30KKworc3RhdGljIGxvbmcKK2Zyb3plbnNldF9oYXNoKFB5T2JqZWN0ICpzZWxmKQoreworICAgIFB5U2V0T2JqZWN0ICpzbyA9IChQeVNldE9iamVjdCAqKXNlbGY7CisgICAgbG9uZyBoLCBoYXNoID0gMTkyNzg2ODIzN0w7CisgICAgc2V0ZW50cnkgKmVudHJ5OworICAgIFB5X3NzaXplX3QgcG9zID0gMDsKKworICAgIGlmIChzby0+aGFzaCAhPSAtMSkKKyAgICAgICAgcmV0dXJuIHNvLT5oYXNoOworCisgICAgaGFzaCAqPSBQeVNldF9HRVRfU0laRShzZWxmKSArIDE7CisgICAgd2hpbGUgKHNldF9uZXh0KHNvLCAmcG9zLCAmZW50cnkpKSB7CisgICAgICAgIC8qIFdvcmsgdG8gaW5jcmVhc2UgdGhlIGJpdCBkaXNwZXJzaW9uIGZvciBjbG9zZWx5IHNwYWNlZCBoYXNoCisgICAgICAgICAgIHZhbHVlcy4gIFRoZSBpcyBpbXBvcnRhbnQgYmVjYXVzZSBzb21lIHVzZSBjYXNlcyBoYXZlIG1hbnkKKyAgICAgICAgICAgY29tYmluYXRpb25zIG9mIGEgc21hbGwgbnVtYmVyIG9mIGVsZW1lbnRzIHdpdGggbmVhcmJ5CisgICAgICAgICAgIGhhc2hlcyBzbyB0aGF0IG1hbnkgZGlzdGluY3QgY29tYmluYXRpb25zIGNvbGxhcHNlIHRvIG9ubHkKKyAgICAgICAgICAgYSBoYW5kZnVsIG9mIGRpc3RpbmN0IGhhc2ggdmFsdWVzLiAqLworICAgICAgICBoID0gZW50cnktPmhhc2g7CisgICAgICAgIGhhc2ggXj0gKGggXiAoaCA8PCAxNikgXiA4OTg2OTc0N0wpICAqIDM2NDQ3OTgxNjd1OworICAgIH0KKyAgICBoYXNoID0gaGFzaCAqIDY5MDY5TCArIDkwNzEzMzkyM0w7CisgICAgaWYgKGhhc2ggPT0gLTEpCisgICAgICAgIGhhc2ggPSA1OTA5MjM3MTNMOworICAgIHNvLT5oYXNoID0gaGFzaDsKKyAgICByZXR1cm4gaGFzaDsKK30KKworLyoqKioqIFNldCBpdGVyYXRvciB0eXBlICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLworCit0eXBlZGVmIHN0cnVjdCB7CisgICAgUHlPYmplY3RfSEVBRAorICAgIFB5U2V0T2JqZWN0ICpzaV9zZXQ7IC8qIFNldCB0byBOVUxMIHdoZW4gaXRlcmF0b3IgaXMgZXhoYXVzdGVkICovCisgICAgUHlfc3NpemVfdCBzaV91c2VkOworICAgIFB5X3NzaXplX3Qgc2lfcG9zOworICAgIFB5X3NzaXplX3QgbGVuOworfSBzZXRpdGVyb2JqZWN0OworCitzdGF0aWMgdm9pZAorc2V0aXRlcl9kZWFsbG9jKHNldGl0ZXJvYmplY3QgKnNpKQoreworICAgIFB5X1hERUNSRUYoc2ktPnNpX3NldCk7CisgICAgUHlPYmplY3RfR0NfRGVsKHNpKTsKK30KKworc3RhdGljIGludAorc2V0aXRlcl90cmF2ZXJzZShzZXRpdGVyb2JqZWN0ICpzaSwgdmlzaXRwcm9jIHZpc2l0LCB2b2lkICphcmcpCit7CisgICAgUHlfVklTSVQoc2ktPnNpX3NldCk7CisgICAgcmV0dXJuIDA7Cit9CisKK3N0YXRpYyBQeU9iamVjdCAqCitzZXRpdGVyX2xlbihzZXRpdGVyb2JqZWN0ICpzaSkKK3sKKyAgICBQeV9zc2l6ZV90IGxlbiA9IDA7CisgICAgaWYgKHNpLT5zaV9zZXQgIT0gTlVMTCAmJiBzaS0+c2lfdXNlZCA9PSBzaS0+c2lfc2V0LT51c2VkKQorICAgICAgICBsZW4gPSBzaS0+bGVuOworICAgIHJldHVybiBQeUludF9Gcm9tTG9uZyhsZW4pOworfQorCitQeURvY19TVFJWQVIobGVuZ3RoX2hpbnRfZG9jLCAiUHJpdmF0ZSBtZXRob2QgcmV0dXJuaW5nIGFuIGVzdGltYXRlIG9mIGxlbihsaXN0KGl0KSkuIik7CisKK3N0YXRpYyBQeU1ldGhvZERlZiBzZXRpdGVyX21ldGhvZHNbXSA9IHsKKyAgICB7Il9fbGVuZ3RoX2hpbnRfXyIsIChQeUNGdW5jdGlvbilzZXRpdGVyX2xlbiwgTUVUSF9OT0FSR1MsIGxlbmd0aF9oaW50X2RvY30sCisgICAge05VTEwsICAgICAgICAgICAgICBOVUxMfSAgICAgICAgICAgLyogc2VudGluZWwgKi8KK307CisKK3N0YXRpYyBQeU9iamVjdCAqc2V0aXRlcl9pdGVybmV4dChzZXRpdGVyb2JqZWN0ICpzaSkKK3sKKyAgICBQeU9iamVjdCAqa2V5OworICAgIHJlZ2lzdGVyIFB5X3NzaXplX3QgaSwgbWFzazsKKyAgICByZWdpc3RlciBzZXRlbnRyeSAqZW50cnk7CisgICAgUHlTZXRPYmplY3QgKnNvID0gc2ktPnNpX3NldDsKKworICAgIGlmIChzbyA9PSBOVUxMKQorICAgICAgICByZXR1cm4gTlVMTDsKKyAgICBhc3NlcnQgKFB5QW55U2V0X0NoZWNrKHNvKSk7CisKKyAgICBpZiAoc2ktPnNpX3VzZWQgIT0gc28tPnVzZWQpIHsKKyAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1J1bnRpbWVFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICJTZXQgY2hhbmdlZCBzaXplIGR1cmluZyBpdGVyYXRpb24iKTsKKyAgICAgICAgc2ktPnNpX3VzZWQgPSAtMTsgLyogTWFrZSB0aGlzIHN0YXRlIHN0aWNreSAqLworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisKKyAgICBpID0gc2ktPnNpX3BvczsKKyAgICBhc3NlcnQoaT49MCk7CisgICAgZW50cnkgPSBzby0+dGFibGU7CisgICAgbWFzayA9IHNvLT5tYXNrOworICAgIHdoaWxlIChpIDw9IG1hc2sgJiYgKGVudHJ5W2ldLmtleSA9PSBOVUxMIHx8IGVudHJ5W2ldLmtleSA9PSBkdW1teSkpCisgICAgICAgIGkrKzsKKyAgICBzaS0+c2lfcG9zID0gaSsxOworICAgIGlmIChpID4gbWFzaykKKyAgICAgICAgZ290byBmYWlsOworICAgIHNpLT5sZW4tLTsKKyAgICBrZXkgPSBlbnRyeVtpXS5rZXk7CisgICAgUHlfSU5DUkVGKGtleSk7CisgICAgcmV0dXJuIGtleTsKKworZmFpbDoKKyAgICBQeV9ERUNSRUYoc28pOworICAgIHNpLT5zaV9zZXQgPSBOVUxMOworICAgIHJldHVybiBOVUxMOworfQorCitzdGF0aWMgUHlUeXBlT2JqZWN0IFB5U2V0SXRlcl9UeXBlID0geworICAgIFB5VmFyT2JqZWN0X0hFQURfSU5JVCgmUHlUeXBlX1R5cGUsIDApCisgICAgInNldGl0ZXJhdG9yIiwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9uYW1lICovCisgICAgc2l6ZW9mKHNldGl0ZXJvYmplY3QpLCAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9iYXNpY3NpemUgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2l0ZW1zaXplICovCisgICAgLyogbWV0aG9kcyAqLworICAgIChkZXN0cnVjdG9yKXNldGl0ZXJfZGVhbGxvYywgICAgICAgICAgICAgICAgLyogdHBfZGVhbGxvYyAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfcHJpbnQgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2dldGF0dHIgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3NldGF0dHIgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2NvbXBhcmUgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3JlcHIgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2FzX251bWJlciAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfYXNfc2VxdWVuY2UgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2FzX21hcHBpbmcgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2hhc2ggKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2NhbGwgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3N0ciAqLworICAgIFB5T2JqZWN0X0dlbmVyaWNHZXRBdHRyLCAgICAgICAgICAgICAgICAgICAgLyogdHBfZ2V0YXR0cm8gKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3NldGF0dHJvICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9hc19idWZmZXIgKi8KKyAgICBQeV9UUEZMQUdTX0RFRkFVTFQgfCBQeV9UUEZMQUdTX0hBVkVfR0MsLyogdHBfZmxhZ3MgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2RvYyAqLworICAgICh0cmF2ZXJzZXByb2Mpc2V0aXRlcl90cmF2ZXJzZSwgICAgICAgICAgICAgLyogdHBfdHJhdmVyc2UgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2NsZWFyICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9yaWNoY29tcGFyZSAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfd2Vha2xpc3RvZmZzZXQgKi8KKyAgICBQeU9iamVjdF9TZWxmSXRlciwgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2l0ZXIgKi8KKyAgICAoaXRlcm5leHRmdW5jKXNldGl0ZXJfaXRlcm5leHQsICAgICAgICAgICAgIC8qIHRwX2l0ZXJuZXh0ICovCisgICAgc2V0aXRlcl9tZXRob2RzLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9tZXRob2RzICovCisgICAgMCwKK307CisKK3N0YXRpYyBQeU9iamVjdCAqCitzZXRfaXRlcihQeVNldE9iamVjdCAqc28pCit7CisgICAgc2V0aXRlcm9iamVjdCAqc2kgPSBQeU9iamVjdF9HQ19OZXcoc2V0aXRlcm9iamVjdCwgJlB5U2V0SXRlcl9UeXBlKTsKKyAgICBpZiAoc2kgPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgUHlfSU5DUkVGKHNvKTsKKyAgICBzaS0+c2lfc2V0ID0gc287CisgICAgc2ktPnNpX3VzZWQgPSBzby0+dXNlZDsKKyAgICBzaS0+c2lfcG9zID0gMDsKKyAgICBzaS0+bGVuID0gc28tPnVzZWQ7CisgICAgX1B5T2JqZWN0X0dDX1RSQUNLKHNpKTsKKyAgICByZXR1cm4gKFB5T2JqZWN0ICopc2k7Cit9CisKK3N0YXRpYyBpbnQKK3NldF91cGRhdGVfaW50ZXJuYWwoUHlTZXRPYmplY3QgKnNvLCBQeU9iamVjdCAqb3RoZXIpCit7CisgICAgUHlPYmplY3QgKmtleSwgKml0OworCisgICAgaWYgKFB5QW55U2V0X0NoZWNrKG90aGVyKSkKKyAgICAgICAgcmV0dXJuIHNldF9tZXJnZShzbywgb3RoZXIpOworCisgICAgaWYgKFB5RGljdF9DaGVja0V4YWN0KG90aGVyKSkgeworICAgICAgICBQeU9iamVjdCAqdmFsdWU7CisgICAgICAgIFB5X3NzaXplX3QgcG9zID0gMDsKKyAgICAgICAgbG9uZyBoYXNoOworICAgICAgICBQeV9zc2l6ZV90IGRpY3RzaXplID0gUHlEaWN0X1NpemUob3RoZXIpOworCisgICAgICAgIC8qIERvIG9uZSBiaWcgcmVzaXplIGF0IHRoZSBzdGFydCwgcmF0aGVyIHRoYW4KKyAgICAgICAgKiBpbmNyZW1lbnRhbGx5IHJlc2l6aW5nIGFzIHdlIGluc2VydCBuZXcga2V5cy4gIEV4cGVjdAorICAgICAgICAqIHRoYXQgdGhlcmUgd2lsbCBiZSBubyAob3IgZmV3KSBvdmVybGFwcGluZyBrZXlzLgorICAgICAgICAqLworICAgICAgICBpZiAoZGljdHNpemUgPT0gLTEpCisgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgIGlmICgoc28tPmZpbGwgKyBkaWN0c2l6ZSkqMyA+PSAoc28tPm1hc2srMSkqMikgeworICAgICAgICAgICAgaWYgKHNldF90YWJsZV9yZXNpemUoc28sIChzby0+dXNlZCArIGRpY3RzaXplKSoyKSAhPSAwKQorICAgICAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgfQorICAgICAgICB3aGlsZSAoX1B5RGljdF9OZXh0KG90aGVyLCAmcG9zLCAma2V5LCAmdmFsdWUsICZoYXNoKSkgeworICAgICAgICAgICAgc2V0ZW50cnkgYW5fZW50cnk7CisKKyAgICAgICAgICAgIGFuX2VudHJ5Lmhhc2ggPSBoYXNoOworICAgICAgICAgICAgYW5fZW50cnkua2V5ID0ga2V5OworICAgICAgICAgICAgaWYgKHNldF9hZGRfZW50cnkoc28sICZhbl9lbnRyeSkgPT0gLTEpCisgICAgICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICB9CisgICAgICAgIHJldHVybiAwOworICAgIH0KKworICAgIGl0ID0gUHlPYmplY3RfR2V0SXRlcihvdGhlcik7CisgICAgaWYgKGl0ID09IE5VTEwpCisgICAgICAgIHJldHVybiAtMTsKKworICAgIHdoaWxlICgoa2V5ID0gUHlJdGVyX05leHQoaXQpKSAhPSBOVUxMKSB7CisgICAgICAgIGlmIChzZXRfYWRkX2tleShzbywga2V5KSA9PSAtMSkgeworICAgICAgICAgICAgUHlfREVDUkVGKGl0KTsKKyAgICAgICAgICAgIFB5X0RFQ1JFRihrZXkpOworICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICB9CisgICAgICAgIFB5X0RFQ1JFRihrZXkpOworICAgIH0KKyAgICBQeV9ERUNSRUYoaXQpOworICAgIGlmIChQeUVycl9PY2N1cnJlZCgpKQorICAgICAgICByZXR1cm4gLTE7CisgICAgcmV0dXJuIDA7Cit9CisKK3N0YXRpYyBQeU9iamVjdCAqCitzZXRfdXBkYXRlKFB5U2V0T2JqZWN0ICpzbywgUHlPYmplY3QgKmFyZ3MpCit7CisgICAgUHlfc3NpemVfdCBpOworCisgICAgZm9yIChpPTAgOyBpPFB5VHVwbGVfR0VUX1NJWkUoYXJncykgOyBpKyspIHsKKyAgICAgICAgUHlPYmplY3QgKm90aGVyID0gUHlUdXBsZV9HRVRfSVRFTShhcmdzLCBpKTsKKyAgICAgICAgaWYgKHNldF91cGRhdGVfaW50ZXJuYWwoc28sIG90aGVyKSA9PSAtMSkKKyAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICBQeV9SRVRVUk5fTk9ORTsKK30KKworUHlEb2NfU1RSVkFSKHVwZGF0ZV9kb2MsCisiVXBkYXRlIGEgc2V0IHdpdGggdGhlIHVuaW9uIG9mIGl0c2VsZiBhbmQgb3RoZXJzLiIpOworCitzdGF0aWMgUHlPYmplY3QgKgorbWFrZV9uZXdfc2V0KFB5VHlwZU9iamVjdCAqdHlwZSwgUHlPYmplY3QgKml0ZXJhYmxlKQoreworICAgIHJlZ2lzdGVyIFB5U2V0T2JqZWN0ICpzbyA9IE5VTEw7CisKKyAgICBpZiAoZHVtbXkgPT0gTlVMTCkgeyAvKiBBdXRvLWluaXRpYWxpemUgZHVtbXkgKi8KKyAgICAgICAgZHVtbXkgPSBQeVN0cmluZ19Gcm9tU3RyaW5nKCI8ZHVtbXkga2V5PiIpOworICAgICAgICBpZiAoZHVtbXkgPT0gTlVMTCkKKyAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKworICAgIC8qIGNyZWF0ZSBQeVNldE9iamVjdCBzdHJ1Y3R1cmUgKi8KKyAgICBpZiAobnVtZnJlZSAmJgorICAgICAgICAodHlwZSA9PSAmUHlTZXRfVHlwZSAgfHwgIHR5cGUgPT0gJlB5RnJvemVuU2V0X1R5cGUpKSB7CisgICAgICAgIHNvID0gZnJlZV9saXN0Wy0tbnVtZnJlZV07CisgICAgICAgIGFzc2VydCAoc28gIT0gTlVMTCAmJiBQeUFueVNldF9DaGVja0V4YWN0KHNvKSk7CisgICAgICAgIFB5X1RZUEUoc28pID0gdHlwZTsKKyAgICAgICAgX1B5X05ld1JlZmVyZW5jZSgoUHlPYmplY3QgKilzbyk7CisgICAgICAgIEVNUFRZX1RPX01JTlNJWkUoc28pOworICAgICAgICBQeU9iamVjdF9HQ19UcmFjayhzbyk7CisgICAgfSBlbHNlIHsKKyAgICAgICAgc28gPSAoUHlTZXRPYmplY3QgKil0eXBlLT50cF9hbGxvYyh0eXBlLCAwKTsKKyAgICAgICAgaWYgKHNvID09IE5VTEwpCisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgLyogdHBfYWxsb2MgaGFzIGFscmVhZHkgemVyb2VkIHRoZSBzdHJ1Y3R1cmUgKi8KKyAgICAgICAgYXNzZXJ0KHNvLT50YWJsZSA9PSBOVUxMICYmIHNvLT5maWxsID09IDAgJiYgc28tPnVzZWQgPT0gMCk7CisgICAgICAgIElOSVRfTk9OWkVST19TRVRfU0xPVFMoc28pOworICAgIH0KKworICAgIHNvLT5sb29rdXAgPSBzZXRfbG9va2tleV9zdHJpbmc7CisgICAgc28tPndlYWtyZWZsaXN0ID0gTlVMTDsKKworICAgIGlmIChpdGVyYWJsZSAhPSBOVUxMKSB7CisgICAgICAgIGlmIChzZXRfdXBkYXRlX2ludGVybmFsKHNvLCBpdGVyYWJsZSkgPT0gLTEpIHsKKyAgICAgICAgICAgIFB5X0RFQ1JFRihzbyk7CisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgfQorICAgIH0KKworICAgIHJldHVybiAoUHlPYmplY3QgKilzbzsKK30KKworLyogVGhlIGVtcHR5IGZyb3plbnNldCBpcyBhIHNpbmdsZXRvbiAqLworc3RhdGljIFB5T2JqZWN0ICplbXB0eWZyb3plbnNldCA9IE5VTEw7CisKK3N0YXRpYyBQeU9iamVjdCAqCitmcm96ZW5zZXRfbmV3KFB5VHlwZU9iamVjdCAqdHlwZSwgUHlPYmplY3QgKmFyZ3MsIFB5T2JqZWN0ICprd2RzKQoreworICAgIFB5T2JqZWN0ICppdGVyYWJsZSA9IE5VTEwsICpyZXN1bHQ7CisKKyAgICBpZiAodHlwZSA9PSAmUHlGcm96ZW5TZXRfVHlwZSAmJiAhX1B5QXJnX05vS2V5d29yZHMoImZyb3plbnNldCgpIiwga3dkcykpCisgICAgICAgIHJldHVybiBOVUxMOworCisgICAgaWYgKCFQeUFyZ19VbnBhY2tUdXBsZShhcmdzLCB0eXBlLT50cF9uYW1lLCAwLCAxLCAmaXRlcmFibGUpKQorICAgICAgICByZXR1cm4gTlVMTDsKKworICAgIGlmICh0eXBlICE9ICZQeUZyb3plblNldF9UeXBlKQorICAgICAgICByZXR1cm4gbWFrZV9uZXdfc2V0KHR5cGUsIGl0ZXJhYmxlKTsKKworICAgIGlmIChpdGVyYWJsZSAhPSBOVUxMKSB7CisgICAgICAgIC8qIGZyb3plbnNldChmKSBpcyBpZGVtcG90ZW50ICovCisgICAgICAgIGlmIChQeUZyb3plblNldF9DaGVja0V4YWN0KGl0ZXJhYmxlKSkgeworICAgICAgICAgICAgUHlfSU5DUkVGKGl0ZXJhYmxlKTsKKyAgICAgICAgICAgIHJldHVybiBpdGVyYWJsZTsKKyAgICAgICAgfQorICAgICAgICByZXN1bHQgPSBtYWtlX25ld19zZXQodHlwZSwgaXRlcmFibGUpOworICAgICAgICBpZiAocmVzdWx0ID09IE5VTEwgfHwgUHlTZXRfR0VUX1NJWkUocmVzdWx0KSkKKyAgICAgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgICAgIFB5X0RFQ1JFRihyZXN1bHQpOworICAgIH0KKyAgICAvKiBUaGUgZW1wdHkgZnJvemVuc2V0IGlzIGEgc2luZ2xldG9uICovCisgICAgaWYgKGVtcHR5ZnJvemVuc2V0ID09IE5VTEwpCisgICAgICAgIGVtcHR5ZnJvemVuc2V0ID0gbWFrZV9uZXdfc2V0KHR5cGUsIE5VTEwpOworICAgIFB5X1hJTkNSRUYoZW1wdHlmcm96ZW5zZXQpOworICAgIHJldHVybiBlbXB0eWZyb3plbnNldDsKK30KKwordm9pZAorUHlTZXRfRmluaSh2b2lkKQoreworICAgIFB5U2V0T2JqZWN0ICpzbzsKKworICAgIHdoaWxlIChudW1mcmVlKSB7CisgICAgICAgIG51bWZyZWUtLTsKKyAgICAgICAgc28gPSBmcmVlX2xpc3RbbnVtZnJlZV07CisgICAgICAgIFB5T2JqZWN0X0dDX0RlbChzbyk7CisgICAgfQorICAgIFB5X0NMRUFSKGR1bW15KTsKKyAgICBQeV9DTEVBUihlbXB0eWZyb3plbnNldCk7Cit9CisKK3N0YXRpYyBQeU9iamVjdCAqCitzZXRfbmV3KFB5VHlwZU9iamVjdCAqdHlwZSwgUHlPYmplY3QgKmFyZ3MsIFB5T2JqZWN0ICprd2RzKQoreworICAgIGlmICh0eXBlID09ICZQeVNldF9UeXBlICYmICFfUHlBcmdfTm9LZXl3b3Jkcygic2V0KCkiLCBrd2RzKSkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisKKyAgICByZXR1cm4gbWFrZV9uZXdfc2V0KHR5cGUsIE5VTEwpOworfQorCisvKiBzZXRfc3dhcF9ib2RpZXMoKSBzd2l0Y2hlcyB0aGUgY29udGVudHMgb2YgYW55IHR3byBzZXRzIGJ5IG1vdmluZyB0aGVpcgorICAgaW50ZXJuYWwgZGF0YSBwb2ludGVycyBhbmQsIGlmIG5lZWRlZCwgY29weWluZyB0aGUgaW50ZXJuYWwgc21hbGx0YWJsZXMuCisgICBTZW1hbnRpY2FsbHkgZXF1aXZhbGVudCB0bzoKKworICAgICB0PXNldChhKTsgYS5jbGVhcigpOyBhLnVwZGF0ZShiKTsgYi5jbGVhcigpOyBiLnVwZGF0ZSh0KTsgZGVsIHQKKworICAgVGhlIGZ1bmN0aW9uIGFsd2F5cyBzdWNjZWVkcyBhbmQgaXQgbGVhdmVzIGJvdGggb2JqZWN0cyBpbiBhIHN0YWJsZSBzdGF0ZS4KKyAgIFVzZWZ1bCBmb3IgY3JlYXRpbmcgdGVtcG9yYXJ5IGZyb3plbnNldHMgZnJvbSBzZXRzIGZvciBtZW1iZXJzaGlwIHRlc3RpbmcKKyAgIGluIF9fY29udGFpbnNfXygpLCBkaXNjYXJkKCksIGFuZCByZW1vdmUoKS4gIEFsc28gdXNlZnVsIGZvciBvcGVyYXRpb25zCisgICB0aGF0IHVwZGF0ZSBpbi1wbGFjZSAoYnkgYWxsb3dpbmcgYW4gaW50ZXJtZWRpYXRlIHJlc3VsdCB0byBiZSBzd2FwcGVkCisgICBpbnRvIG9uZSBvZiB0aGUgb3JpZ2luYWwgaW5wdXRzKS4KKyovCisKK3N0YXRpYyB2b2lkCitzZXRfc3dhcF9ib2RpZXMoUHlTZXRPYmplY3QgKmEsIFB5U2V0T2JqZWN0ICpiKQoreworICAgIFB5X3NzaXplX3QgdDsKKyAgICBzZXRlbnRyeSAqdTsKKyAgICBzZXRlbnRyeSAqKCpmKShQeVNldE9iamVjdCAqc28sIFB5T2JqZWN0ICprZXksIGxvbmcgaGFzaCk7CisgICAgc2V0ZW50cnkgdGFiW1B5U2V0X01JTlNJWkVdOworICAgIGxvbmcgaDsKKworICAgIHQgPSBhLT5maWxsOyAgICAgYS0+ZmlsbCAgID0gYi0+ZmlsbDsgICAgICAgIGItPmZpbGwgID0gdDsKKyAgICB0ID0gYS0+dXNlZDsgICAgIGEtPnVzZWQgICA9IGItPnVzZWQ7ICAgICAgICBiLT51c2VkICA9IHQ7CisgICAgdCA9IGEtPm1hc2s7ICAgICBhLT5tYXNrICAgPSBiLT5tYXNrOyAgICAgICAgYi0+bWFzayAgPSB0OworCisgICAgdSA9IGEtPnRhYmxlOworICAgIGlmIChhLT50YWJsZSA9PSBhLT5zbWFsbHRhYmxlKQorICAgICAgICB1ID0gYi0+c21hbGx0YWJsZTsKKyAgICBhLT50YWJsZSAgPSBiLT50YWJsZTsKKyAgICBpZiAoYi0+dGFibGUgPT0gYi0+c21hbGx0YWJsZSkKKyAgICAgICAgYS0+dGFibGUgPSBhLT5zbWFsbHRhYmxlOworICAgIGItPnRhYmxlID0gdTsKKworICAgIGYgPSBhLT5sb29rdXA7ICAgYS0+bG9va3VwID0gYi0+bG9va3VwOyAgICAgIGItPmxvb2t1cCA9IGY7CisKKyAgICBpZiAoYS0+dGFibGUgPT0gYS0+c21hbGx0YWJsZSB8fCBiLT50YWJsZSA9PSBiLT5zbWFsbHRhYmxlKSB7CisgICAgICAgIG1lbWNweSh0YWIsIGEtPnNtYWxsdGFibGUsIHNpemVvZih0YWIpKTsKKyAgICAgICAgbWVtY3B5KGEtPnNtYWxsdGFibGUsIGItPnNtYWxsdGFibGUsIHNpemVvZih0YWIpKTsKKyAgICAgICAgbWVtY3B5KGItPnNtYWxsdGFibGUsIHRhYiwgc2l6ZW9mKHRhYikpOworICAgIH0KKworICAgIGlmIChQeVR5cGVfSXNTdWJ0eXBlKFB5X1RZUEUoYSksICZQeUZyb3plblNldF9UeXBlKSAgJiYKKyAgICAgICAgUHlUeXBlX0lzU3VidHlwZShQeV9UWVBFKGIpLCAmUHlGcm96ZW5TZXRfVHlwZSkpIHsKKyAgICAgICAgaCA9IGEtPmhhc2g7ICAgICBhLT5oYXNoID0gYi0+aGFzaDsgIGItPmhhc2ggPSBoOworICAgIH0gZWxzZSB7CisgICAgICAgIGEtPmhhc2ggPSAtMTsKKyAgICAgICAgYi0+aGFzaCA9IC0xOworICAgIH0KK30KKworc3RhdGljIFB5T2JqZWN0ICoKK3NldF9jb3B5KFB5U2V0T2JqZWN0ICpzbykKK3sKKyAgICByZXR1cm4gbWFrZV9uZXdfc2V0KFB5X1RZUEUoc28pLCAoUHlPYmplY3QgKilzbyk7Cit9CisKK3N0YXRpYyBQeU9iamVjdCAqCitmcm96ZW5zZXRfY29weShQeVNldE9iamVjdCAqc28pCit7CisgICAgaWYgKFB5RnJvemVuU2V0X0NoZWNrRXhhY3Qoc28pKSB7CisgICAgICAgIFB5X0lOQ1JFRihzbyk7CisgICAgICAgIHJldHVybiAoUHlPYmplY3QgKilzbzsKKyAgICB9CisgICAgcmV0dXJuIHNldF9jb3B5KHNvKTsKK30KKworUHlEb2NfU1RSVkFSKGNvcHlfZG9jLCAiUmV0dXJuIGEgc2hhbGxvdyBjb3B5IG9mIGEgc2V0LiIpOworCitzdGF0aWMgUHlPYmplY3QgKgorc2V0X2NsZWFyKFB5U2V0T2JqZWN0ICpzbykKK3sKKyAgICBzZXRfY2xlYXJfaW50ZXJuYWwoc28pOworICAgIFB5X1JFVFVSTl9OT05FOworfQorCitQeURvY19TVFJWQVIoY2xlYXJfZG9jLCAiUmVtb3ZlIGFsbCBlbGVtZW50cyBmcm9tIHRoaXMgc2V0LiIpOworCitzdGF0aWMgUHlPYmplY3QgKgorc2V0X3VuaW9uKFB5U2V0T2JqZWN0ICpzbywgUHlPYmplY3QgKmFyZ3MpCit7CisgICAgUHlTZXRPYmplY3QgKnJlc3VsdDsKKyAgICBQeU9iamVjdCAqb3RoZXI7CisgICAgUHlfc3NpemVfdCBpOworCisgICAgcmVzdWx0ID0gKFB5U2V0T2JqZWN0ICopc2V0X2NvcHkoc28pOworICAgIGlmIChyZXN1bHQgPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisKKyAgICBmb3IgKGk9MCA7IGk8UHlUdXBsZV9HRVRfU0laRShhcmdzKSA7IGkrKykgeworICAgICAgICBvdGhlciA9IFB5VHVwbGVfR0VUX0lURU0oYXJncywgaSk7CisgICAgICAgIGlmICgoUHlPYmplY3QgKilzbyA9PSBvdGhlcikKKyAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICBpZiAoc2V0X3VwZGF0ZV9pbnRlcm5hbChyZXN1bHQsIG90aGVyKSA9PSAtMSkgeworICAgICAgICAgICAgUHlfREVDUkVGKHJlc3VsdCk7CisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgfQorICAgIH0KKyAgICByZXR1cm4gKFB5T2JqZWN0ICopcmVzdWx0OworfQorCitQeURvY19TVFJWQVIodW5pb25fZG9jLAorICJSZXR1cm4gdGhlIHVuaW9uIG9mIHNldHMgYXMgYSBuZXcgc2V0LlxuXAorXG5cCisoaS5lLiBhbGwgZWxlbWVudHMgdGhhdCBhcmUgaW4gZWl0aGVyIHNldC4pIik7CisKK3N0YXRpYyBQeU9iamVjdCAqCitzZXRfb3IoUHlTZXRPYmplY3QgKnNvLCBQeU9iamVjdCAqb3RoZXIpCit7CisgICAgUHlTZXRPYmplY3QgKnJlc3VsdDsKKworICAgIGlmICghUHlBbnlTZXRfQ2hlY2soc28pIHx8ICFQeUFueVNldF9DaGVjayhvdGhlcikpIHsKKyAgICAgICAgUHlfSU5DUkVGKFB5X05vdEltcGxlbWVudGVkKTsKKyAgICAgICAgcmV0dXJuIFB5X05vdEltcGxlbWVudGVkOworICAgIH0KKworICAgIHJlc3VsdCA9IChQeVNldE9iamVjdCAqKXNldF9jb3B5KHNvKTsKKyAgICBpZiAocmVzdWx0ID09IE5VTEwpCisgICAgICAgIHJldHVybiBOVUxMOworICAgIGlmICgoUHlPYmplY3QgKilzbyA9PSBvdGhlcikKKyAgICAgICAgcmV0dXJuIChQeU9iamVjdCAqKXJlc3VsdDsKKyAgICBpZiAoc2V0X3VwZGF0ZV9pbnRlcm5hbChyZXN1bHQsIG90aGVyKSA9PSAtMSkgeworICAgICAgICBQeV9ERUNSRUYocmVzdWx0KTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIHJldHVybiAoUHlPYmplY3QgKilyZXN1bHQ7Cit9CisKK3N0YXRpYyBQeU9iamVjdCAqCitzZXRfaW9yKFB5U2V0T2JqZWN0ICpzbywgUHlPYmplY3QgKm90aGVyKQoreworICAgIGlmICghUHlBbnlTZXRfQ2hlY2sob3RoZXIpKSB7CisgICAgICAgIFB5X0lOQ1JFRihQeV9Ob3RJbXBsZW1lbnRlZCk7CisgICAgICAgIHJldHVybiBQeV9Ob3RJbXBsZW1lbnRlZDsKKyAgICB9CisgICAgaWYgKHNldF91cGRhdGVfaW50ZXJuYWwoc28sIG90aGVyKSA9PSAtMSkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgUHlfSU5DUkVGKHNvKTsKKyAgICByZXR1cm4gKFB5T2JqZWN0ICopc287Cit9CisKK3N0YXRpYyBQeU9iamVjdCAqCitzZXRfaW50ZXJzZWN0aW9uKFB5U2V0T2JqZWN0ICpzbywgUHlPYmplY3QgKm90aGVyKQoreworICAgIFB5U2V0T2JqZWN0ICpyZXN1bHQ7CisgICAgUHlPYmplY3QgKmtleSwgKml0LCAqdG1wOworCisgICAgaWYgKChQeU9iamVjdCAqKXNvID09IG90aGVyKQorICAgICAgICByZXR1cm4gc2V0X2NvcHkoc28pOworCisgICAgcmVzdWx0ID0gKFB5U2V0T2JqZWN0ICopbWFrZV9uZXdfc2V0KFB5X1RZUEUoc28pLCBOVUxMKTsKKyAgICBpZiAocmVzdWx0ID09IE5VTEwpCisgICAgICAgIHJldHVybiBOVUxMOworCisgICAgaWYgKFB5QW55U2V0X0NoZWNrKG90aGVyKSkgeworICAgICAgICBQeV9zc2l6ZV90IHBvcyA9IDA7CisgICAgICAgIHNldGVudHJ5ICplbnRyeTsKKworICAgICAgICBpZiAoUHlTZXRfR0VUX1NJWkUob3RoZXIpID4gUHlTZXRfR0VUX1NJWkUoc28pKSB7CisgICAgICAgICAgICB0bXAgPSAoUHlPYmplY3QgKilzbzsKKyAgICAgICAgICAgIHNvID0gKFB5U2V0T2JqZWN0ICopb3RoZXI7CisgICAgICAgICAgICBvdGhlciA9IHRtcDsKKyAgICAgICAgfQorCisgICAgICAgIHdoaWxlIChzZXRfbmV4dCgoUHlTZXRPYmplY3QgKilvdGhlciwgJnBvcywgJmVudHJ5KSkgeworICAgICAgICAgICAgaW50IHJ2ID0gc2V0X2NvbnRhaW5zX2VudHJ5KHNvLCBlbnRyeSk7CisgICAgICAgICAgICBpZiAocnYgPT0gLTEpIHsKKyAgICAgICAgICAgICAgICBQeV9ERUNSRUYocmVzdWx0KTsKKyAgICAgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChydikgeworICAgICAgICAgICAgICAgIGlmIChzZXRfYWRkX2VudHJ5KHJlc3VsdCwgZW50cnkpID09IC0xKSB7CisgICAgICAgICAgICAgICAgICAgIFB5X0RFQ1JFRihyZXN1bHQpOworICAgICAgICAgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIChQeU9iamVjdCAqKXJlc3VsdDsKKyAgICB9CisKKyAgICBpdCA9IFB5T2JqZWN0X0dldEl0ZXIob3RoZXIpOworICAgIGlmIChpdCA9PSBOVUxMKSB7CisgICAgICAgIFB5X0RFQ1JFRihyZXN1bHQpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisKKyAgICB3aGlsZSAoKGtleSA9IFB5SXRlcl9OZXh0KGl0KSkgIT0gTlVMTCkgeworICAgICAgICBpbnQgcnY7CisgICAgICAgIHNldGVudHJ5IGVudHJ5OworICAgICAgICBsb25nIGhhc2ggPSBQeU9iamVjdF9IYXNoKGtleSk7CisKKyAgICAgICAgaWYgKGhhc2ggPT0gLTEpIHsKKyAgICAgICAgICAgIFB5X0RFQ1JFRihpdCk7CisgICAgICAgICAgICBQeV9ERUNSRUYocmVzdWx0KTsKKyAgICAgICAgICAgIFB5X0RFQ1JFRihrZXkpOworICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgICAgIH0KKyAgICAgICAgZW50cnkuaGFzaCA9IGhhc2g7CisgICAgICAgIGVudHJ5LmtleSA9IGtleTsKKyAgICAgICAgcnYgPSBzZXRfY29udGFpbnNfZW50cnkoc28sICZlbnRyeSk7CisgICAgICAgIGlmIChydiA9PSAtMSkgeworICAgICAgICAgICAgUHlfREVDUkVGKGl0KTsKKyAgICAgICAgICAgIFB5X0RFQ1JFRihyZXN1bHQpOworICAgICAgICAgICAgUHlfREVDUkVGKGtleSk7CisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgfQorICAgICAgICBpZiAocnYpIHsKKyAgICAgICAgICAgIGlmIChzZXRfYWRkX2VudHJ5KHJlc3VsdCwgJmVudHJ5KSA9PSAtMSkgeworICAgICAgICAgICAgICAgIFB5X0RFQ1JFRihpdCk7CisgICAgICAgICAgICAgICAgUHlfREVDUkVGKHJlc3VsdCk7CisgICAgICAgICAgICAgICAgUHlfREVDUkVGKGtleSk7CisgICAgICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgUHlfREVDUkVGKGtleSk7CisgICAgfQorICAgIFB5X0RFQ1JFRihpdCk7CisgICAgaWYgKFB5RXJyX09jY3VycmVkKCkpIHsKKyAgICAgICAgUHlfREVDUkVGKHJlc3VsdCk7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICByZXR1cm4gKFB5T2JqZWN0ICopcmVzdWx0OworfQorCitzdGF0aWMgUHlPYmplY3QgKgorc2V0X2ludGVyc2VjdGlvbl9tdWx0aShQeVNldE9iamVjdCAqc28sIFB5T2JqZWN0ICphcmdzKQoreworICAgIFB5X3NzaXplX3QgaTsKKyAgICBQeU9iamVjdCAqcmVzdWx0ID0gKFB5T2JqZWN0ICopc287CisKKyAgICBpZiAoUHlUdXBsZV9HRVRfU0laRShhcmdzKSA9PSAwKQorICAgICAgICByZXR1cm4gc2V0X2NvcHkoc28pOworCisgICAgUHlfSU5DUkVGKHNvKTsKKyAgICBmb3IgKGk9MCA7IGk8UHlUdXBsZV9HRVRfU0laRShhcmdzKSA7IGkrKykgeworICAgICAgICBQeU9iamVjdCAqb3RoZXIgPSBQeVR1cGxlX0dFVF9JVEVNKGFyZ3MsIGkpOworICAgICAgICBQeU9iamVjdCAqbmV3cmVzdWx0ID0gc2V0X2ludGVyc2VjdGlvbigoUHlTZXRPYmplY3QgKilyZXN1bHQsIG90aGVyKTsKKyAgICAgICAgaWYgKG5ld3Jlc3VsdCA9PSBOVUxMKSB7CisgICAgICAgICAgICBQeV9ERUNSRUYocmVzdWx0KTsKKyAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgICAgICB9CisgICAgICAgIFB5X0RFQ1JFRihyZXN1bHQpOworICAgICAgICByZXN1bHQgPSBuZXdyZXN1bHQ7CisgICAgfQorICAgIHJldHVybiByZXN1bHQ7Cit9CisKK1B5RG9jX1NUUlZBUihpbnRlcnNlY3Rpb25fZG9jLAorIlJldHVybiB0aGUgaW50ZXJzZWN0aW9uIG9mIHR3byBvciBtb3JlIHNldHMgYXMgYSBuZXcgc2V0LlxuXAorXG5cCisoaS5lLiBlbGVtZW50cyB0aGF0IGFyZSBjb21tb24gdG8gYWxsIG9mIHRoZSBzZXRzLikiKTsKKworc3RhdGljIFB5T2JqZWN0ICoKK3NldF9pbnRlcnNlY3Rpb25fdXBkYXRlKFB5U2V0T2JqZWN0ICpzbywgUHlPYmplY3QgKm90aGVyKQoreworICAgIFB5T2JqZWN0ICp0bXA7CisKKyAgICB0bXAgPSBzZXRfaW50ZXJzZWN0aW9uKHNvLCBvdGhlcik7CisgICAgaWYgKHRtcCA9PSBOVUxMKQorICAgICAgICByZXR1cm4gTlVMTDsKKyAgICBzZXRfc3dhcF9ib2RpZXMoc28sIChQeVNldE9iamVjdCAqKXRtcCk7CisgICAgUHlfREVDUkVGKHRtcCk7CisgICAgUHlfUkVUVVJOX05PTkU7Cit9CisKK3N0YXRpYyBQeU9iamVjdCAqCitzZXRfaW50ZXJzZWN0aW9uX3VwZGF0ZV9tdWx0aShQeVNldE9iamVjdCAqc28sIFB5T2JqZWN0ICphcmdzKQoreworICAgIFB5T2JqZWN0ICp0bXA7CisKKyAgICB0bXAgPSBzZXRfaW50ZXJzZWN0aW9uX211bHRpKHNvLCBhcmdzKTsKKyAgICBpZiAodG1wID09IE5VTEwpCisgICAgICAgIHJldHVybiBOVUxMOworICAgIHNldF9zd2FwX2JvZGllcyhzbywgKFB5U2V0T2JqZWN0ICopdG1wKTsKKyAgICBQeV9ERUNSRUYodG1wKTsKKyAgICBQeV9SRVRVUk5fTk9ORTsKK30KKworUHlEb2NfU1RSVkFSKGludGVyc2VjdGlvbl91cGRhdGVfZG9jLAorIlVwZGF0ZSBhIHNldCB3aXRoIHRoZSBpbnRlcnNlY3Rpb24gb2YgaXRzZWxmIGFuZCBhbm90aGVyLiIpOworCitzdGF0aWMgUHlPYmplY3QgKgorc2V0X2FuZChQeVNldE9iamVjdCAqc28sIFB5T2JqZWN0ICpvdGhlcikKK3sKKyAgICBpZiAoIVB5QW55U2V0X0NoZWNrKHNvKSB8fCAhUHlBbnlTZXRfQ2hlY2sob3RoZXIpKSB7CisgICAgICAgIFB5X0lOQ1JFRihQeV9Ob3RJbXBsZW1lbnRlZCk7CisgICAgICAgIHJldHVybiBQeV9Ob3RJbXBsZW1lbnRlZDsKKyAgICB9CisgICAgcmV0dXJuIHNldF9pbnRlcnNlY3Rpb24oc28sIG90aGVyKTsKK30KKworc3RhdGljIFB5T2JqZWN0ICoKK3NldF9pYW5kKFB5U2V0T2JqZWN0ICpzbywgUHlPYmplY3QgKm90aGVyKQoreworICAgIFB5T2JqZWN0ICpyZXN1bHQ7CisKKyAgICBpZiAoIVB5QW55U2V0X0NoZWNrKG90aGVyKSkgeworICAgICAgICBQeV9JTkNSRUYoUHlfTm90SW1wbGVtZW50ZWQpOworICAgICAgICByZXR1cm4gUHlfTm90SW1wbGVtZW50ZWQ7CisgICAgfQorICAgIHJlc3VsdCA9IHNldF9pbnRlcnNlY3Rpb25fdXBkYXRlKHNvLCBvdGhlcik7CisgICAgaWYgKHJlc3VsdCA9PSBOVUxMKQorICAgICAgICByZXR1cm4gTlVMTDsKKyAgICBQeV9ERUNSRUYocmVzdWx0KTsKKyAgICBQeV9JTkNSRUYoc28pOworICAgIHJldHVybiAoUHlPYmplY3QgKilzbzsKK30KKworc3RhdGljIFB5T2JqZWN0ICoKK3NldF9pc2Rpc2pvaW50KFB5U2V0T2JqZWN0ICpzbywgUHlPYmplY3QgKm90aGVyKQoreworICAgIFB5T2JqZWN0ICprZXksICppdCwgKnRtcDsKKworICAgIGlmICgoUHlPYmplY3QgKilzbyA9PSBvdGhlcikgeworICAgICAgICBpZiAoUHlTZXRfR0VUX1NJWkUoc28pID09IDApCisgICAgICAgICAgICBQeV9SRVRVUk5fVFJVRTsKKyAgICAgICAgZWxzZQorICAgICAgICAgICAgUHlfUkVUVVJOX0ZBTFNFOworICAgIH0KKworICAgIGlmIChQeUFueVNldF9DaGVja0V4YWN0KG90aGVyKSkgeworICAgICAgICBQeV9zc2l6ZV90IHBvcyA9IDA7CisgICAgICAgIHNldGVudHJ5ICplbnRyeTsKKworICAgICAgICBpZiAoUHlTZXRfR0VUX1NJWkUob3RoZXIpID4gUHlTZXRfR0VUX1NJWkUoc28pKSB7CisgICAgICAgICAgICB0bXAgPSAoUHlPYmplY3QgKilzbzsKKyAgICAgICAgICAgIHNvID0gKFB5U2V0T2JqZWN0ICopb3RoZXI7CisgICAgICAgICAgICBvdGhlciA9IHRtcDsKKyAgICAgICAgfQorICAgICAgICB3aGlsZSAoc2V0X25leHQoKFB5U2V0T2JqZWN0ICopb3RoZXIsICZwb3MsICZlbnRyeSkpIHsKKyAgICAgICAgICAgIGludCBydiA9IHNldF9jb250YWluc19lbnRyeShzbywgZW50cnkpOworICAgICAgICAgICAgaWYgKHJ2ID09IC0xKQorICAgICAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgICAgICAgICAgaWYgKHJ2KQorICAgICAgICAgICAgICAgIFB5X1JFVFVSTl9GQUxTRTsKKyAgICAgICAgfQorICAgICAgICBQeV9SRVRVUk5fVFJVRTsKKyAgICB9CisKKyAgICBpdCA9IFB5T2JqZWN0X0dldEl0ZXIob3RoZXIpOworICAgIGlmIChpdCA9PSBOVUxMKQorICAgICAgICByZXR1cm4gTlVMTDsKKworICAgIHdoaWxlICgoa2V5ID0gUHlJdGVyX05leHQoaXQpKSAhPSBOVUxMKSB7CisgICAgICAgIGludCBydjsKKyAgICAgICAgc2V0ZW50cnkgZW50cnk7CisgICAgICAgIGxvbmcgaGFzaCA9IFB5T2JqZWN0X0hhc2goa2V5KTsKKworICAgICAgICBpZiAoaGFzaCA9PSAtMSkgeworICAgICAgICAgICAgUHlfREVDUkVGKGtleSk7CisgICAgICAgICAgICBQeV9ERUNSRUYoaXQpOworICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgICAgIH0KKyAgICAgICAgZW50cnkuaGFzaCA9IGhhc2g7CisgICAgICAgIGVudHJ5LmtleSA9IGtleTsKKyAgICAgICAgcnYgPSBzZXRfY29udGFpbnNfZW50cnkoc28sICZlbnRyeSk7CisgICAgICAgIFB5X0RFQ1JFRihrZXkpOworICAgICAgICBpZiAocnYgPT0gLTEpIHsKKyAgICAgICAgICAgIFB5X0RFQ1JFRihpdCk7CisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgfQorICAgICAgICBpZiAocnYpIHsKKyAgICAgICAgICAgIFB5X0RFQ1JFRihpdCk7CisgICAgICAgICAgICBQeV9SRVRVUk5fRkFMU0U7CisgICAgICAgIH0KKyAgICB9CisgICAgUHlfREVDUkVGKGl0KTsKKyAgICBpZiAoUHlFcnJfT2NjdXJyZWQoKSkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgUHlfUkVUVVJOX1RSVUU7Cit9CisKK1B5RG9jX1NUUlZBUihpc2Rpc2pvaW50X2RvYywKKyJSZXR1cm4gVHJ1ZSBpZiB0d28gc2V0cyBoYXZlIGEgbnVsbCBpbnRlcnNlY3Rpb24uIik7CisKK3N0YXRpYyBpbnQKK3NldF9kaWZmZXJlbmNlX3VwZGF0ZV9pbnRlcm5hbChQeVNldE9iamVjdCAqc28sIFB5T2JqZWN0ICpvdGhlcikKK3sKKyAgICBpZiAoKFB5T2JqZWN0ICopc28gPT0gb3RoZXIpCisgICAgICAgIHJldHVybiBzZXRfY2xlYXJfaW50ZXJuYWwoc28pOworCisgICAgaWYgKFB5QW55U2V0X0NoZWNrKG90aGVyKSkgeworICAgICAgICBzZXRlbnRyeSAqZW50cnk7CisgICAgICAgIFB5X3NzaXplX3QgcG9zID0gMDsKKworICAgICAgICB3aGlsZSAoc2V0X25leHQoKFB5U2V0T2JqZWN0ICopb3RoZXIsICZwb3MsICZlbnRyeSkpCisgICAgICAgICAgICBpZiAoc2V0X2Rpc2NhcmRfZW50cnkoc28sIGVudHJ5KSA9PSAtMSkKKyAgICAgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgfSBlbHNlIHsKKyAgICAgICAgUHlPYmplY3QgKmtleSwgKml0OworICAgICAgICBpdCA9IFB5T2JqZWN0X0dldEl0ZXIob3RoZXIpOworICAgICAgICBpZiAoaXQgPT0gTlVMTCkKKyAgICAgICAgICAgIHJldHVybiAtMTsKKworICAgICAgICB3aGlsZSAoKGtleSA9IFB5SXRlcl9OZXh0KGl0KSkgIT0gTlVMTCkgeworICAgICAgICAgICAgaWYgKHNldF9kaXNjYXJkX2tleShzbywga2V5KSA9PSAtMSkgeworICAgICAgICAgICAgICAgIFB5X0RFQ1JFRihpdCk7CisgICAgICAgICAgICAgICAgUHlfREVDUkVGKGtleSk7CisgICAgICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICAgICAgfQorICAgICAgICAgICAgUHlfREVDUkVGKGtleSk7CisgICAgICAgIH0KKyAgICAgICAgUHlfREVDUkVGKGl0KTsKKyAgICAgICAgaWYgKFB5RXJyX09jY3VycmVkKCkpCisgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgfQorICAgIC8qIElmIG1vcmUgdGhhbiAxLzUgYXJlIGR1bW1pZXMsIHRoZW4gcmVzaXplIHRoZW0gYXdheS4gKi8KKyAgICBpZiAoKHNvLT5maWxsIC0gc28tPnVzZWQpICogNSA8IHNvLT5tYXNrKQorICAgICAgICByZXR1cm4gMDsKKyAgICByZXR1cm4gc2V0X3RhYmxlX3Jlc2l6ZShzbywgc28tPnVzZWQ+NTAwMDAgPyBzby0+dXNlZCoyIDogc28tPnVzZWQqNCk7Cit9CisKK3N0YXRpYyBQeU9iamVjdCAqCitzZXRfZGlmZmVyZW5jZV91cGRhdGUoUHlTZXRPYmplY3QgKnNvLCBQeU9iamVjdCAqYXJncykKK3sKKyAgICBQeV9zc2l6ZV90IGk7CisKKyAgICBmb3IgKGk9MCA7IGk8UHlUdXBsZV9HRVRfU0laRShhcmdzKSA7IGkrKykgeworICAgICAgICBQeU9iamVjdCAqb3RoZXIgPSBQeVR1cGxlX0dFVF9JVEVNKGFyZ3MsIGkpOworICAgICAgICBpZiAoc2V0X2RpZmZlcmVuY2VfdXBkYXRlX2ludGVybmFsKHNvLCBvdGhlcikgPT0gLTEpCisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgUHlfUkVUVVJOX05PTkU7Cit9CisKK1B5RG9jX1NUUlZBUihkaWZmZXJlbmNlX3VwZGF0ZV9kb2MsCisiUmVtb3ZlIGFsbCBlbGVtZW50cyBvZiBhbm90aGVyIHNldCBmcm9tIHRoaXMgc2V0LiIpOworCitzdGF0aWMgUHlPYmplY3QgKgorc2V0X2RpZmZlcmVuY2UoUHlTZXRPYmplY3QgKnNvLCBQeU9iamVjdCAqb3RoZXIpCit7CisgICAgUHlPYmplY3QgKnJlc3VsdDsKKyAgICBzZXRlbnRyeSAqZW50cnk7CisgICAgUHlfc3NpemVfdCBwb3MgPSAwOworCisgICAgaWYgKCFQeUFueVNldF9DaGVjayhvdGhlcikgICYmICFQeURpY3RfQ2hlY2tFeGFjdChvdGhlcikpIHsKKyAgICAgICAgcmVzdWx0ID0gc2V0X2NvcHkoc28pOworICAgICAgICBpZiAocmVzdWx0ID09IE5VTEwpCisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgaWYgKHNldF9kaWZmZXJlbmNlX3VwZGF0ZV9pbnRlcm5hbCgoUHlTZXRPYmplY3QgKilyZXN1bHQsIG90aGVyKSAhPSAtMSkKKyAgICAgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgICAgIFB5X0RFQ1JFRihyZXN1bHQpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisKKyAgICByZXN1bHQgPSBtYWtlX25ld19zZXQoUHlfVFlQRShzbyksIE5VTEwpOworICAgIGlmIChyZXN1bHQgPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisKKyAgICBpZiAoUHlEaWN0X0NoZWNrRXhhY3Qob3RoZXIpKSB7CisgICAgICAgIHdoaWxlIChzZXRfbmV4dChzbywgJnBvcywgJmVudHJ5KSkgeworICAgICAgICAgICAgc2V0ZW50cnkgZW50cnljb3B5OworICAgICAgICAgICAgZW50cnljb3B5Lmhhc2ggPSBlbnRyeS0+aGFzaDsKKyAgICAgICAgICAgIGVudHJ5Y29weS5rZXkgPSBlbnRyeS0+a2V5OworICAgICAgICAgICAgaWYgKCFfUHlEaWN0X0NvbnRhaW5zKG90aGVyLCBlbnRyeS0+a2V5LCBlbnRyeS0+aGFzaCkpIHsKKyAgICAgICAgICAgICAgICBpZiAoc2V0X2FkZF9lbnRyeSgoUHlTZXRPYmplY3QgKilyZXN1bHQsICZlbnRyeWNvcHkpID09IC0xKSB7CisgICAgICAgICAgICAgICAgICAgIFB5X0RFQ1JFRihyZXN1bHQpOworICAgICAgICAgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisKKyAgICB3aGlsZSAoc2V0X25leHQoc28sICZwb3MsICZlbnRyeSkpIHsKKyAgICAgICAgaW50IHJ2ID0gc2V0X2NvbnRhaW5zX2VudHJ5KChQeVNldE9iamVjdCAqKW90aGVyLCBlbnRyeSk7CisgICAgICAgIGlmIChydiA9PSAtMSkgeworICAgICAgICAgICAgUHlfREVDUkVGKHJlc3VsdCk7CisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgfQorICAgICAgICBpZiAoIXJ2KSB7CisgICAgICAgICAgICBpZiAoc2V0X2FkZF9lbnRyeSgoUHlTZXRPYmplY3QgKilyZXN1bHQsIGVudHJ5KSA9PSAtMSkgeworICAgICAgICAgICAgICAgIFB5X0RFQ1JFRihyZXN1bHQpOworICAgICAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorICAgIHJldHVybiByZXN1bHQ7Cit9CisKK3N0YXRpYyBQeU9iamVjdCAqCitzZXRfZGlmZmVyZW5jZV9tdWx0aShQeVNldE9iamVjdCAqc28sIFB5T2JqZWN0ICphcmdzKQoreworICAgIFB5X3NzaXplX3QgaTsKKyAgICBQeU9iamVjdCAqcmVzdWx0LCAqb3RoZXI7CisKKyAgICBpZiAoUHlUdXBsZV9HRVRfU0laRShhcmdzKSA9PSAwKQorICAgICAgICByZXR1cm4gc2V0X2NvcHkoc28pOworCisgICAgb3RoZXIgPSBQeVR1cGxlX0dFVF9JVEVNKGFyZ3MsIDApOworICAgIHJlc3VsdCA9IHNldF9kaWZmZXJlbmNlKHNvLCBvdGhlcik7CisgICAgaWYgKHJlc3VsdCA9PSBOVUxMKQorICAgICAgICByZXR1cm4gTlVMTDsKKworICAgIGZvciAoaT0xIDsgaTxQeVR1cGxlX0dFVF9TSVpFKGFyZ3MpIDsgaSsrKSB7CisgICAgICAgIG90aGVyID0gUHlUdXBsZV9HRVRfSVRFTShhcmdzLCBpKTsKKyAgICAgICAgaWYgKHNldF9kaWZmZXJlbmNlX3VwZGF0ZV9pbnRlcm5hbCgoUHlTZXRPYmplY3QgKilyZXN1bHQsIG90aGVyKSA9PSAtMSkgeworICAgICAgICAgICAgUHlfREVDUkVGKHJlc3VsdCk7CisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgfQorICAgIH0KKyAgICByZXR1cm4gcmVzdWx0OworfQorCitQeURvY19TVFJWQVIoZGlmZmVyZW5jZV9kb2MsCisiUmV0dXJuIHRoZSBkaWZmZXJlbmNlIG9mIHR3byBvciBtb3JlIHNldHMgYXMgYSBuZXcgc2V0LlxuXAorXG5cCisoaS5lLiBhbGwgZWxlbWVudHMgdGhhdCBhcmUgaW4gdGhpcyBzZXQgYnV0IG5vdCB0aGUgb3RoZXJzLikiKTsKK3N0YXRpYyBQeU9iamVjdCAqCitzZXRfc3ViKFB5U2V0T2JqZWN0ICpzbywgUHlPYmplY3QgKm90aGVyKQoreworICAgIGlmICghUHlBbnlTZXRfQ2hlY2soc28pIHx8ICFQeUFueVNldF9DaGVjayhvdGhlcikpIHsKKyAgICAgICAgUHlfSU5DUkVGKFB5X05vdEltcGxlbWVudGVkKTsKKyAgICAgICAgcmV0dXJuIFB5X05vdEltcGxlbWVudGVkOworICAgIH0KKyAgICByZXR1cm4gc2V0X2RpZmZlcmVuY2Uoc28sIG90aGVyKTsKK30KKworc3RhdGljIFB5T2JqZWN0ICoKK3NldF9pc3ViKFB5U2V0T2JqZWN0ICpzbywgUHlPYmplY3QgKm90aGVyKQoreworICAgIGlmICghUHlBbnlTZXRfQ2hlY2sob3RoZXIpKSB7CisgICAgICAgIFB5X0lOQ1JFRihQeV9Ob3RJbXBsZW1lbnRlZCk7CisgICAgICAgIHJldHVybiBQeV9Ob3RJbXBsZW1lbnRlZDsKKyAgICB9CisgICAgaWYgKHNldF9kaWZmZXJlbmNlX3VwZGF0ZV9pbnRlcm5hbChzbywgb3RoZXIpID09IC0xKQorICAgICAgICByZXR1cm4gTlVMTDsKKyAgICBQeV9JTkNSRUYoc28pOworICAgIHJldHVybiAoUHlPYmplY3QgKilzbzsKK30KKworc3RhdGljIFB5T2JqZWN0ICoKK3NldF9zeW1tZXRyaWNfZGlmZmVyZW5jZV91cGRhdGUoUHlTZXRPYmplY3QgKnNvLCBQeU9iamVjdCAqb3RoZXIpCit7CisgICAgUHlTZXRPYmplY3QgKm90aGVyc2V0OworICAgIFB5T2JqZWN0ICprZXk7CisgICAgUHlfc3NpemVfdCBwb3MgPSAwOworICAgIHNldGVudHJ5ICplbnRyeTsKKworICAgIGlmICgoUHlPYmplY3QgKilzbyA9PSBvdGhlcikKKyAgICAgICAgcmV0dXJuIHNldF9jbGVhcihzbyk7CisKKyAgICBpZiAoUHlEaWN0X0NoZWNrRXhhY3Qob3RoZXIpKSB7CisgICAgICAgIFB5T2JqZWN0ICp2YWx1ZTsKKyAgICAgICAgaW50IHJ2OworICAgICAgICBsb25nIGhhc2g7CisgICAgICAgIHdoaWxlIChfUHlEaWN0X05leHQob3RoZXIsICZwb3MsICZrZXksICZ2YWx1ZSwgJmhhc2gpKSB7CisgICAgICAgICAgICBzZXRlbnRyeSBhbl9lbnRyeTsKKworICAgICAgICAgICAgUHlfSU5DUkVGKGtleSk7CisgICAgICAgICAgICBhbl9lbnRyeS5oYXNoID0gaGFzaDsKKyAgICAgICAgICAgIGFuX2VudHJ5LmtleSA9IGtleTsKKworICAgICAgICAgICAgcnYgPSBzZXRfZGlzY2FyZF9lbnRyeShzbywgJmFuX2VudHJ5KTsKKyAgICAgICAgICAgIGlmIChydiA9PSAtMSkgeworICAgICAgICAgICAgICAgIFB5X0RFQ1JFRihrZXkpOworICAgICAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKHJ2ID09IERJU0NBUkRfTk9URk9VTkQpIHsKKyAgICAgICAgICAgICAgICBpZiAoc2V0X2FkZF9lbnRyeShzbywgJmFuX2VudHJ5KSA9PSAtMSkgeworICAgICAgICAgICAgICAgICAgICBQeV9ERUNSRUYoa2V5KTsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgUHlfREVDUkVGKGtleSk7CisgICAgICAgIH0KKyAgICAgICAgUHlfUkVUVVJOX05PTkU7CisgICAgfQorCisgICAgaWYgKFB5QW55U2V0X0NoZWNrKG90aGVyKSkgeworICAgICAgICBQeV9JTkNSRUYob3RoZXIpOworICAgICAgICBvdGhlcnNldCA9IChQeVNldE9iamVjdCAqKW90aGVyOworICAgIH0gZWxzZSB7CisgICAgICAgIG90aGVyc2V0ID0gKFB5U2V0T2JqZWN0ICopbWFrZV9uZXdfc2V0KFB5X1RZUEUoc28pLCBvdGhlcik7CisgICAgICAgIGlmIChvdGhlcnNldCA9PSBOVUxMKQorICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorCisgICAgd2hpbGUgKHNldF9uZXh0KG90aGVyc2V0LCAmcG9zLCAmZW50cnkpKSB7CisgICAgICAgIGludCBydiA9IHNldF9kaXNjYXJkX2VudHJ5KHNvLCBlbnRyeSk7CisgICAgICAgIGlmIChydiA9PSAtMSkgeworICAgICAgICAgICAgUHlfREVDUkVGKG90aGVyc2V0KTsKKyAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgICAgICB9CisgICAgICAgIGlmIChydiA9PSBESVNDQVJEX05PVEZPVU5EKSB7CisgICAgICAgICAgICBpZiAoc2V0X2FkZF9lbnRyeShzbywgZW50cnkpID09IC0xKSB7CisgICAgICAgICAgICAgICAgUHlfREVDUkVGKG90aGVyc2V0KTsKKyAgICAgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKyAgICBQeV9ERUNSRUYob3RoZXJzZXQpOworICAgIFB5X1JFVFVSTl9OT05FOworfQorCitQeURvY19TVFJWQVIoc3ltbWV0cmljX2RpZmZlcmVuY2VfdXBkYXRlX2RvYywKKyJVcGRhdGUgYSBzZXQgd2l0aCB0aGUgc3ltbWV0cmljIGRpZmZlcmVuY2Ugb2YgaXRzZWxmIGFuZCBhbm90aGVyLiIpOworCitzdGF0aWMgUHlPYmplY3QgKgorc2V0X3N5bW1ldHJpY19kaWZmZXJlbmNlKFB5U2V0T2JqZWN0ICpzbywgUHlPYmplY3QgKm90aGVyKQoreworICAgIFB5T2JqZWN0ICpydjsKKyAgICBQeVNldE9iamVjdCAqb3RoZXJzZXQ7CisKKyAgICBvdGhlcnNldCA9IChQeVNldE9iamVjdCAqKW1ha2VfbmV3X3NldChQeV9UWVBFKHNvKSwgb3RoZXIpOworICAgIGlmIChvdGhlcnNldCA9PSBOVUxMKQorICAgICAgICByZXR1cm4gTlVMTDsKKyAgICBydiA9IHNldF9zeW1tZXRyaWNfZGlmZmVyZW5jZV91cGRhdGUob3RoZXJzZXQsIChQeU9iamVjdCAqKXNvKTsKKyAgICBpZiAocnYgPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgUHlfREVDUkVGKHJ2KTsKKyAgICByZXR1cm4gKFB5T2JqZWN0ICopb3RoZXJzZXQ7Cit9CisKK1B5RG9jX1NUUlZBUihzeW1tZXRyaWNfZGlmZmVyZW5jZV9kb2MsCisiUmV0dXJuIHRoZSBzeW1tZXRyaWMgZGlmZmVyZW5jZSBvZiB0d28gc2V0cyBhcyBhIG5ldyBzZXQuXG5cCitcblwKKyhpLmUuIGFsbCBlbGVtZW50cyB0aGF0IGFyZSBpbiBleGFjdGx5IG9uZSBvZiB0aGUgc2V0cy4pIik7CisKK3N0YXRpYyBQeU9iamVjdCAqCitzZXRfeG9yKFB5U2V0T2JqZWN0ICpzbywgUHlPYmplY3QgKm90aGVyKQoreworICAgIGlmICghUHlBbnlTZXRfQ2hlY2soc28pIHx8ICFQeUFueVNldF9DaGVjayhvdGhlcikpIHsKKyAgICAgICAgUHlfSU5DUkVGKFB5X05vdEltcGxlbWVudGVkKTsKKyAgICAgICAgcmV0dXJuIFB5X05vdEltcGxlbWVudGVkOworICAgIH0KKyAgICByZXR1cm4gc2V0X3N5bW1ldHJpY19kaWZmZXJlbmNlKHNvLCBvdGhlcik7Cit9CisKK3N0YXRpYyBQeU9iamVjdCAqCitzZXRfaXhvcihQeVNldE9iamVjdCAqc28sIFB5T2JqZWN0ICpvdGhlcikKK3sKKyAgICBQeU9iamVjdCAqcmVzdWx0OworCisgICAgaWYgKCFQeUFueVNldF9DaGVjayhvdGhlcikpIHsKKyAgICAgICAgUHlfSU5DUkVGKFB5X05vdEltcGxlbWVudGVkKTsKKyAgICAgICAgcmV0dXJuIFB5X05vdEltcGxlbWVudGVkOworICAgIH0KKyAgICByZXN1bHQgPSBzZXRfc3ltbWV0cmljX2RpZmZlcmVuY2VfdXBkYXRlKHNvLCBvdGhlcik7CisgICAgaWYgKHJlc3VsdCA9PSBOVUxMKQorICAgICAgICByZXR1cm4gTlVMTDsKKyAgICBQeV9ERUNSRUYocmVzdWx0KTsKKyAgICBQeV9JTkNSRUYoc28pOworICAgIHJldHVybiAoUHlPYmplY3QgKilzbzsKK30KKworc3RhdGljIFB5T2JqZWN0ICoKK3NldF9pc3N1YnNldChQeVNldE9iamVjdCAqc28sIFB5T2JqZWN0ICpvdGhlcikKK3sKKyAgICBzZXRlbnRyeSAqZW50cnk7CisgICAgUHlfc3NpemVfdCBwb3MgPSAwOworCisgICAgaWYgKCFQeUFueVNldF9DaGVjayhvdGhlcikpIHsKKyAgICAgICAgUHlPYmplY3QgKnRtcCwgKnJlc3VsdDsKKyAgICAgICAgdG1wID0gbWFrZV9uZXdfc2V0KCZQeVNldF9UeXBlLCBvdGhlcik7CisgICAgICAgIGlmICh0bXAgPT0gTlVMTCkKKyAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgICAgICByZXN1bHQgPSBzZXRfaXNzdWJzZXQoc28sIHRtcCk7CisgICAgICAgIFB5X0RFQ1JFRih0bXApOworICAgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKyAgICBpZiAoUHlTZXRfR0VUX1NJWkUoc28pID4gUHlTZXRfR0VUX1NJWkUob3RoZXIpKQorICAgICAgICBQeV9SRVRVUk5fRkFMU0U7CisKKyAgICB3aGlsZSAoc2V0X25leHQoc28sICZwb3MsICZlbnRyeSkpIHsKKyAgICAgICAgaW50IHJ2ID0gc2V0X2NvbnRhaW5zX2VudHJ5KChQeVNldE9iamVjdCAqKW90aGVyLCBlbnRyeSk7CisgICAgICAgIGlmIChydiA9PSAtMSkKKyAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgICAgICBpZiAoIXJ2KQorICAgICAgICAgICAgUHlfUkVUVVJOX0ZBTFNFOworICAgIH0KKyAgICBQeV9SRVRVUk5fVFJVRTsKK30KKworUHlEb2NfU1RSVkFSKGlzc3Vic2V0X2RvYywgIlJlcG9ydCB3aGV0aGVyIGFub3RoZXIgc2V0IGNvbnRhaW5zIHRoaXMgc2V0LiIpOworCitzdGF0aWMgUHlPYmplY3QgKgorc2V0X2lzc3VwZXJzZXQoUHlTZXRPYmplY3QgKnNvLCBQeU9iamVjdCAqb3RoZXIpCit7CisgICAgUHlPYmplY3QgKnRtcCwgKnJlc3VsdDsKKworICAgIGlmICghUHlBbnlTZXRfQ2hlY2sob3RoZXIpKSB7CisgICAgICAgIHRtcCA9IG1ha2VfbmV3X3NldCgmUHlTZXRfVHlwZSwgb3RoZXIpOworICAgICAgICBpZiAodG1wID09IE5VTEwpCisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgcmVzdWx0ID0gc2V0X2lzc3VwZXJzZXQoc28sIHRtcCk7CisgICAgICAgIFB5X0RFQ1JFRih0bXApOworICAgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KKyAgICByZXR1cm4gc2V0X2lzc3Vic2V0KChQeVNldE9iamVjdCAqKW90aGVyLCAoUHlPYmplY3QgKilzbyk7Cit9CisKK1B5RG9jX1NUUlZBUihpc3N1cGVyc2V0X2RvYywgIlJlcG9ydCB3aGV0aGVyIHRoaXMgc2V0IGNvbnRhaW5zIGFub3RoZXIgc2V0LiIpOworCitzdGF0aWMgUHlPYmplY3QgKgorc2V0X3JpY2hjb21wYXJlKFB5U2V0T2JqZWN0ICp2LCBQeU9iamVjdCAqdywgaW50IG9wKQoreworICAgIFB5T2JqZWN0ICpyMSwgKnIyOworCisgICAgaWYoIVB5QW55U2V0X0NoZWNrKHcpKSB7CisgICAgICAgIGlmIChvcCA9PSBQeV9FUSkKKyAgICAgICAgICAgIFB5X1JFVFVSTl9GQUxTRTsKKyAgICAgICAgaWYgKG9wID09IFB5X05FKQorICAgICAgICAgICAgUHlfUkVUVVJOX1RSVUU7CisgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19UeXBlRXJyb3IsICJjYW4gb25seSBjb21wYXJlIHRvIGEgc2V0Iik7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICBzd2l0Y2ggKG9wKSB7CisgICAgY2FzZSBQeV9FUToKKyAgICAgICAgaWYgKFB5U2V0X0dFVF9TSVpFKHYpICE9IFB5U2V0X0dFVF9TSVpFKHcpKQorICAgICAgICAgICAgUHlfUkVUVVJOX0ZBTFNFOworICAgICAgICBpZiAodi0+aGFzaCAhPSAtMSAgJiYKKyAgICAgICAgICAgICgoUHlTZXRPYmplY3QgKil3KS0+aGFzaCAhPSAtMSAmJgorICAgICAgICAgICAgdi0+aGFzaCAhPSAoKFB5U2V0T2JqZWN0ICopdyktPmhhc2gpCisgICAgICAgICAgICBQeV9SRVRVUk5fRkFMU0U7CisgICAgICAgIHJldHVybiBzZXRfaXNzdWJzZXQodiwgdyk7CisgICAgY2FzZSBQeV9ORToKKyAgICAgICAgcjEgPSBzZXRfcmljaGNvbXBhcmUodiwgdywgUHlfRVEpOworICAgICAgICBpZiAocjEgPT0gTlVMTCkKKyAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgICAgICByMiA9IFB5Qm9vbF9Gcm9tTG9uZyhQeU9iamVjdF9Ob3QocjEpKTsKKyAgICAgICAgUHlfREVDUkVGKHIxKTsKKyAgICAgICAgcmV0dXJuIHIyOworICAgIGNhc2UgUHlfTEU6CisgICAgICAgIHJldHVybiBzZXRfaXNzdWJzZXQodiwgdyk7CisgICAgY2FzZSBQeV9HRToKKyAgICAgICAgcmV0dXJuIHNldF9pc3N1cGVyc2V0KHYsIHcpOworICAgIGNhc2UgUHlfTFQ6CisgICAgICAgIGlmIChQeVNldF9HRVRfU0laRSh2KSA+PSBQeVNldF9HRVRfU0laRSh3KSkKKyAgICAgICAgICAgIFB5X1JFVFVSTl9GQUxTRTsKKyAgICAgICAgcmV0dXJuIHNldF9pc3N1YnNldCh2LCB3KTsKKyAgICBjYXNlIFB5X0dUOgorICAgICAgICBpZiAoUHlTZXRfR0VUX1NJWkUodikgPD0gUHlTZXRfR0VUX1NJWkUodykpCisgICAgICAgICAgICBQeV9SRVRVUk5fRkFMU0U7CisgICAgICAgIHJldHVybiBzZXRfaXNzdXBlcnNldCh2LCB3KTsKKyAgICB9CisgICAgUHlfSU5DUkVGKFB5X05vdEltcGxlbWVudGVkKTsKKyAgICByZXR1cm4gUHlfTm90SW1wbGVtZW50ZWQ7Cit9CisKK3N0YXRpYyBpbnQKK3NldF9ub2NtcChQeU9iamVjdCAqc2VsZiwgUHlPYmplY3QgKm90aGVyKQoreworICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19UeXBlRXJyb3IsICJjYW5ub3QgY29tcGFyZSBzZXRzIHVzaW5nIGNtcCgpIik7CisgICAgcmV0dXJuIC0xOworfQorCitzdGF0aWMgUHlPYmplY3QgKgorc2V0X2FkZChQeVNldE9iamVjdCAqc28sIFB5T2JqZWN0ICprZXkpCit7CisgICAgaWYgKHNldF9hZGRfa2V5KHNvLCBrZXkpID09IC0xKQorICAgICAgICByZXR1cm4gTlVMTDsKKyAgICBQeV9SRVRVUk5fTk9ORTsKK30KKworUHlEb2NfU1RSVkFSKGFkZF9kb2MsCisiQWRkIGFuIGVsZW1lbnQgdG8gYSBzZXQuXG5cCitcblwKK1RoaXMgaGFzIG5vIGVmZmVjdCBpZiB0aGUgZWxlbWVudCBpcyBhbHJlYWR5IHByZXNlbnQuIik7CisKK3N0YXRpYyBpbnQKK3NldF9jb250YWlucyhQeVNldE9iamVjdCAqc28sIFB5T2JqZWN0ICprZXkpCit7CisgICAgUHlPYmplY3QgKnRtcGtleTsKKyAgICBpbnQgcnY7CisKKyAgICBydiA9IHNldF9jb250YWluc19rZXkoc28sIGtleSk7CisgICAgaWYgKHJ2ID09IC0xKSB7CisgICAgICAgIGlmICghUHlTZXRfQ2hlY2soa2V5KSB8fCAhUHlFcnJfRXhjZXB0aW9uTWF0Y2hlcyhQeUV4Y19UeXBlRXJyb3IpKQorICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICBQeUVycl9DbGVhcigpOworICAgICAgICB0bXBrZXkgPSBtYWtlX25ld19zZXQoJlB5RnJvemVuU2V0X1R5cGUsIGtleSk7CisgICAgICAgIGlmICh0bXBrZXkgPT0gTlVMTCkKKyAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgcnYgPSBzZXRfY29udGFpbnNfa2V5KHNvLCB0bXBrZXkpOworICAgICAgICBQeV9ERUNSRUYodG1wa2V5KTsKKyAgICB9CisgICAgcmV0dXJuIHJ2OworfQorCitzdGF0aWMgUHlPYmplY3QgKgorc2V0X2RpcmVjdF9jb250YWlucyhQeVNldE9iamVjdCAqc28sIFB5T2JqZWN0ICprZXkpCit7CisgICAgbG9uZyByZXN1bHQ7CisKKyAgICByZXN1bHQgPSBzZXRfY29udGFpbnMoc28sIGtleSk7CisgICAgaWYgKHJlc3VsdCA9PSAtMSkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgcmV0dXJuIFB5Qm9vbF9Gcm9tTG9uZyhyZXN1bHQpOworfQorCitQeURvY19TVFJWQVIoY29udGFpbnNfZG9jLCAieC5fX2NvbnRhaW5zX18oeSkgPD09PiB5IGluIHguIik7CisKK3N0YXRpYyBQeU9iamVjdCAqCitzZXRfcmVtb3ZlKFB5U2V0T2JqZWN0ICpzbywgUHlPYmplY3QgKmtleSkKK3sKKyAgICBQeU9iamVjdCAqdG1wa2V5OworICAgIGludCBydjsKKworICAgIHJ2ID0gc2V0X2Rpc2NhcmRfa2V5KHNvLCBrZXkpOworICAgIGlmIChydiA9PSAtMSkgeworICAgICAgICBpZiAoIVB5U2V0X0NoZWNrKGtleSkgfHwgIVB5RXJyX0V4Y2VwdGlvbk1hdGNoZXMoUHlFeGNfVHlwZUVycm9yKSkKKyAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgICAgICBQeUVycl9DbGVhcigpOworICAgICAgICB0bXBrZXkgPSBtYWtlX25ld19zZXQoJlB5RnJvemVuU2V0X1R5cGUsIGtleSk7CisgICAgICAgIGlmICh0bXBrZXkgPT0gTlVMTCkKKyAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgICAgICBydiA9IHNldF9kaXNjYXJkX2tleShzbywgdG1wa2V5KTsKKyAgICAgICAgUHlfREVDUkVGKHRtcGtleSk7CisgICAgICAgIGlmIChydiA9PSAtMSkKKyAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKworICAgIGlmIChydiA9PSBESVNDQVJEX05PVEZPVU5EKSB7CisgICAgICAgIHNldF9rZXlfZXJyb3Ioa2V5KTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIFB5X1JFVFVSTl9OT05FOworfQorCitQeURvY19TVFJWQVIocmVtb3ZlX2RvYywKKyJSZW1vdmUgYW4gZWxlbWVudCBmcm9tIGEgc2V0OyBpdCBtdXN0IGJlIGEgbWVtYmVyLlxuXAorXG5cCitJZiB0aGUgZWxlbWVudCBpcyBub3QgYSBtZW1iZXIsIHJhaXNlIGEgS2V5RXJyb3IuIik7CisKK3N0YXRpYyBQeU9iamVjdCAqCitzZXRfZGlzY2FyZChQeVNldE9iamVjdCAqc28sIFB5T2JqZWN0ICprZXkpCit7CisgICAgUHlPYmplY3QgKnRtcGtleTsKKyAgICBpbnQgcnY7CisKKyAgICBydiA9IHNldF9kaXNjYXJkX2tleShzbywga2V5KTsKKyAgICBpZiAocnYgPT0gLTEpIHsKKyAgICAgICAgaWYgKCFQeVNldF9DaGVjayhrZXkpIHx8ICFQeUVycl9FeGNlcHRpb25NYXRjaGVzKFB5RXhjX1R5cGVFcnJvcikpCisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgUHlFcnJfQ2xlYXIoKTsKKyAgICAgICAgdG1wa2V5ID0gbWFrZV9uZXdfc2V0KCZQeUZyb3plblNldF9UeXBlLCBrZXkpOworICAgICAgICBpZiAodG1wa2V5ID09IE5VTEwpCisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgcnYgPSBzZXRfZGlzY2FyZF9rZXkoc28sIHRtcGtleSk7CisgICAgICAgIFB5X0RFQ1JFRih0bXBrZXkpOworICAgICAgICBpZiAocnYgPT0gLTEpCisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgUHlfUkVUVVJOX05PTkU7Cit9CisKK1B5RG9jX1NUUlZBUihkaXNjYXJkX2RvYywKKyJSZW1vdmUgYW4gZWxlbWVudCBmcm9tIGEgc2V0IGlmIGl0IGlzIGEgbWVtYmVyLlxuXAorXG5cCitJZiB0aGUgZWxlbWVudCBpcyBub3QgYSBtZW1iZXIsIGRvIG5vdGhpbmcuIik7CisKK3N0YXRpYyBQeU9iamVjdCAqCitzZXRfcmVkdWNlKFB5U2V0T2JqZWN0ICpzbykKK3sKKyAgICBQeU9iamVjdCAqa2V5cz1OVUxMLCAqYXJncz1OVUxMLCAqcmVzdWx0PU5VTEwsICpkaWN0PU5VTEw7CisKKyAgICBrZXlzID0gUHlTZXF1ZW5jZV9MaXN0KChQeU9iamVjdCAqKXNvKTsKKyAgICBpZiAoa2V5cyA9PSBOVUxMKQorICAgICAgICBnb3RvIGRvbmU7CisgICAgYXJncyA9IFB5VHVwbGVfUGFjaygxLCBrZXlzKTsKKyAgICBpZiAoYXJncyA9PSBOVUxMKQorICAgICAgICBnb3RvIGRvbmU7CisgICAgZGljdCA9IFB5T2JqZWN0X0dldEF0dHJTdHJpbmcoKFB5T2JqZWN0ICopc28sICJfX2RpY3RfXyIpOworICAgIGlmIChkaWN0ID09IE5VTEwpIHsKKyAgICAgICAgUHlFcnJfQ2xlYXIoKTsKKyAgICAgICAgZGljdCA9IFB5X05vbmU7CisgICAgICAgIFB5X0lOQ1JFRihkaWN0KTsKKyAgICB9CisgICAgcmVzdWx0ID0gUHlUdXBsZV9QYWNrKDMsIFB5X1RZUEUoc28pLCBhcmdzLCBkaWN0KTsKK2RvbmU6CisgICAgUHlfWERFQ1JFRihhcmdzKTsKKyAgICBQeV9YREVDUkVGKGtleXMpOworICAgIFB5X1hERUNSRUYoZGljdCk7CisgICAgcmV0dXJuIHJlc3VsdDsKK30KKworUHlEb2NfU1RSVkFSKHJlZHVjZV9kb2MsICJSZXR1cm4gc3RhdGUgaW5mb3JtYXRpb24gZm9yIHBpY2tsaW5nLiIpOworCitzdGF0aWMgUHlPYmplY3QgKgorc2V0X3NpemVvZihQeVNldE9iamVjdCAqc28pCit7CisgICAgUHlfc3NpemVfdCByZXM7CisKKyAgICByZXMgPSBzaXplb2YoUHlTZXRPYmplY3QpOworICAgIGlmIChzby0+dGFibGUgIT0gc28tPnNtYWxsdGFibGUpCisgICAgICAgIHJlcyA9IHJlcyArIChzby0+bWFzayArIDEpICogc2l6ZW9mKHNldGVudHJ5KTsKKyAgICByZXR1cm4gUHlJbnRfRnJvbVNzaXplX3QocmVzKTsKK30KKworUHlEb2NfU1RSVkFSKHNpemVvZl9kb2MsICJTLl9fc2l6ZW9mX18oKSAtPiBzaXplIG9mIFMgaW4gbWVtb3J5LCBpbiBieXRlcyIpOworc3RhdGljIGludAorc2V0X2luaXQoUHlTZXRPYmplY3QgKnNlbGYsIFB5T2JqZWN0ICphcmdzLCBQeU9iamVjdCAqa3dkcykKK3sKKyAgICBQeU9iamVjdCAqaXRlcmFibGUgPSBOVUxMOworCisgICAgaWYgKCFQeUFueVNldF9DaGVjayhzZWxmKSkKKyAgICAgICAgcmV0dXJuIC0xOworICAgIGlmIChQeVNldF9DaGVjayhzZWxmKSAmJiAhX1B5QXJnX05vS2V5d29yZHMoInNldCgpIiwga3dkcykpCisgICAgICAgIHJldHVybiAtMTsKKyAgICBpZiAoIVB5QXJnX1VucGFja1R1cGxlKGFyZ3MsIFB5X1RZUEUoc2VsZiktPnRwX25hbWUsIDAsIDEsICZpdGVyYWJsZSkpCisgICAgICAgIHJldHVybiAtMTsKKyAgICBzZXRfY2xlYXJfaW50ZXJuYWwoc2VsZik7CisgICAgc2VsZi0+aGFzaCA9IC0xOworICAgIGlmIChpdGVyYWJsZSA9PSBOVUxMKQorICAgICAgICByZXR1cm4gMDsKKyAgICByZXR1cm4gc2V0X3VwZGF0ZV9pbnRlcm5hbChzZWxmLCBpdGVyYWJsZSk7Cit9CisKK3N0YXRpYyBQeVNlcXVlbmNlTWV0aG9kcyBzZXRfYXNfc2VxdWVuY2UgPSB7CisgICAgc2V0X2xlbiwgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogc3FfbGVuZ3RoICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogc3FfY29uY2F0ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogc3FfcmVwZWF0ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogc3FfaXRlbSAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHNxX3NsaWNlICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogc3FfYXNzX2l0ZW0gKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBzcV9hc3Nfc2xpY2UgKi8KKyAgICAob2Jqb2JqcHJvYylzZXRfY29udGFpbnMsICAgICAgICAgICAvKiBzcV9jb250YWlucyAqLworfTsKKworLyogc2V0IG9iamVjdCAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KKworI2lmZGVmIFB5X0RFQlVHCitzdGF0aWMgUHlPYmplY3QgKnRlc3RfY19hcGkoUHlTZXRPYmplY3QgKnNvKTsKKworUHlEb2NfU1RSVkFSKHRlc3RfY19hcGlfZG9jLCAiRXhlcmNpc2VzIEMgQVBJLiAgUmV0dXJucyBUcnVlLlxuXAorQWxsIGlzIHdlbGwgaWYgYXNzZXJ0aW9ucyBkb24ndCBmYWlsLiIpOworI2VuZGlmCisKK3N0YXRpYyBQeU1ldGhvZERlZiBzZXRfbWV0aG9kc1tdID0geworICAgIHsiYWRkIiwgICAgICAgICAgICAgKFB5Q0Z1bmN0aW9uKXNldF9hZGQsICAgICAgICAgICBNRVRIX08sCisgICAgIGFkZF9kb2N9LAorICAgIHsiY2xlYXIiLCAgICAgICAgICAgKFB5Q0Z1bmN0aW9uKXNldF9jbGVhciwgICAgICAgICBNRVRIX05PQVJHUywKKyAgICAgY2xlYXJfZG9jfSwKKyAgICB7Il9fY29udGFpbnNfXyIsKFB5Q0Z1bmN0aW9uKXNldF9kaXJlY3RfY29udGFpbnMsICAgICAgICAgICBNRVRIX08gfCBNRVRIX0NPRVhJU1QsCisgICAgIGNvbnRhaW5zX2RvY30sCisgICAgeyJjb3B5IiwgICAgICAgICAgICAoUHlDRnVuY3Rpb24pc2V0X2NvcHksICAgICAgICAgIE1FVEhfTk9BUkdTLAorICAgICBjb3B5X2RvY30sCisgICAgeyJkaXNjYXJkIiwgICAgICAgICAoUHlDRnVuY3Rpb24pc2V0X2Rpc2NhcmQsICAgICAgIE1FVEhfTywKKyAgICAgZGlzY2FyZF9kb2N9LAorICAgIHsiZGlmZmVyZW5jZSIsICAgICAgKFB5Q0Z1bmN0aW9uKXNldF9kaWZmZXJlbmNlX211bHRpLCAgICAgIE1FVEhfVkFSQVJHUywKKyAgICAgZGlmZmVyZW5jZV9kb2N9LAorICAgIHsiZGlmZmVyZW5jZV91cGRhdGUiLCAgICAgICAoUHlDRnVuY3Rpb24pc2V0X2RpZmZlcmVuY2VfdXBkYXRlLCAgICAgTUVUSF9WQVJBUkdTLAorICAgICBkaWZmZXJlbmNlX3VwZGF0ZV9kb2N9LAorICAgIHsiaW50ZXJzZWN0aW9uIiwoUHlDRnVuY3Rpb24pc2V0X2ludGVyc2VjdGlvbl9tdWx0aSwgICAgICAgIE1FVEhfVkFSQVJHUywKKyAgICAgaW50ZXJzZWN0aW9uX2RvY30sCisgICAgeyJpbnRlcnNlY3Rpb25fdXBkYXRlIiwoUHlDRnVuY3Rpb24pc2V0X2ludGVyc2VjdGlvbl91cGRhdGVfbXVsdGksICAgICAgICAgIE1FVEhfVkFSQVJHUywKKyAgICAgaW50ZXJzZWN0aW9uX3VwZGF0ZV9kb2N9LAorICAgIHsiaXNkaXNqb2ludCIsICAgICAgKFB5Q0Z1bmN0aW9uKXNldF9pc2Rpc2pvaW50LCAgICBNRVRIX08sCisgICAgIGlzZGlzam9pbnRfZG9jfSwKKyAgICB7Imlzc3Vic2V0IiwgICAgICAgIChQeUNGdW5jdGlvbilzZXRfaXNzdWJzZXQsICAgICAgTUVUSF9PLAorICAgICBpc3N1YnNldF9kb2N9LAorICAgIHsiaXNzdXBlcnNldCIsICAgICAgKFB5Q0Z1bmN0aW9uKXNldF9pc3N1cGVyc2V0LCAgICBNRVRIX08sCisgICAgIGlzc3VwZXJzZXRfZG9jfSwKKyAgICB7InBvcCIsICAgICAgICAgICAgIChQeUNGdW5jdGlvbilzZXRfcG9wLCAgICAgICAgICAgTUVUSF9OT0FSR1MsCisgICAgIHBvcF9kb2N9LAorICAgIHsiX19yZWR1Y2VfXyIsICAgICAgKFB5Q0Z1bmN0aW9uKXNldF9yZWR1Y2UsICAgICAgICBNRVRIX05PQVJHUywKKyAgICAgcmVkdWNlX2RvY30sCisgICAgeyJyZW1vdmUiLCAgICAgICAgICAoUHlDRnVuY3Rpb24pc2V0X3JlbW92ZSwgICAgICAgIE1FVEhfTywKKyAgICAgcmVtb3ZlX2RvY30sCisgICAgeyJfX3NpemVvZl9fIiwgICAgICAoUHlDRnVuY3Rpb24pc2V0X3NpemVvZiwgICAgICAgIE1FVEhfTk9BUkdTLAorICAgICBzaXplb2ZfZG9jfSwKKyAgICB7InN5bW1ldHJpY19kaWZmZXJlbmNlIiwoUHlDRnVuY3Rpb24pc2V0X3N5bW1ldHJpY19kaWZmZXJlbmNlLCAgICAgIE1FVEhfTywKKyAgICAgc3ltbWV0cmljX2RpZmZlcmVuY2VfZG9jfSwKKyAgICB7InN5bW1ldHJpY19kaWZmZXJlbmNlX3VwZGF0ZSIsKFB5Q0Z1bmN0aW9uKXNldF9zeW1tZXRyaWNfZGlmZmVyZW5jZV91cGRhdGUsICAgICAgICBNRVRIX08sCisgICAgIHN5bW1ldHJpY19kaWZmZXJlbmNlX3VwZGF0ZV9kb2N9LAorI2lmZGVmIFB5X0RFQlVHCisgICAgeyJ0ZXN0X2NfYXBpIiwgICAgICAoUHlDRnVuY3Rpb24pdGVzdF9jX2FwaSwgICAgICAgIE1FVEhfTk9BUkdTLAorICAgICB0ZXN0X2NfYXBpX2RvY30sCisjZW5kaWYKKyAgICB7InVuaW9uIiwgICAgICAgICAgIChQeUNGdW5jdGlvbilzZXRfdW5pb24sICAgICAgICAgTUVUSF9WQVJBUkdTLAorICAgICB1bmlvbl9kb2N9LAorICAgIHsidXBkYXRlIiwgICAgICAgICAgKFB5Q0Z1bmN0aW9uKXNldF91cGRhdGUsICAgICAgICBNRVRIX1ZBUkFSR1MsCisgICAgIHVwZGF0ZV9kb2N9LAorICAgIHtOVUxMLCAgICAgICAgICAgICAgTlVMTH0gICAvKiBzZW50aW5lbCAqLworfTsKKworc3RhdGljIFB5TnVtYmVyTWV0aG9kcyBzZXRfYXNfbnVtYmVyID0geworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qbmJfYWRkKi8KKyAgICAoYmluYXJ5ZnVuYylzZXRfc3ViLCAgICAgICAgICAgICAgICAvKm5iX3N1YnRyYWN0Ki8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKm5iX211bHRpcGx5Ki8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKm5iX2RpdmlkZSovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLypuYl9yZW1haW5kZXIqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qbmJfZGl2bW9kKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKm5iX3Bvd2VyKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKm5iX25lZ2F0aXZlKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKm5iX3Bvc2l0aXZlKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKm5iX2Fic29sdXRlKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKm5iX25vbnplcm8qLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qbmJfaW52ZXJ0Ki8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKm5iX2xzaGlmdCovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLypuYl9yc2hpZnQqLworICAgIChiaW5hcnlmdW5jKXNldF9hbmQsICAgICAgICAgICAgICAgIC8qbmJfYW5kKi8KKyAgICAoYmluYXJ5ZnVuYylzZXRfeG9yLCAgICAgICAgICAgICAgICAvKm5iX3hvciovCisgICAgKGJpbmFyeWZ1bmMpc2V0X29yLCAgICAgICAgICAgICAgICAgLypuYl9vciovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLypuYl9jb2VyY2UqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qbmJfaW50Ki8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKm5iX2xvbmcqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qbmJfZmxvYXQqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qbmJfb2N0Ki8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKm5iX2hleCovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLypuYl9pbnBsYWNlX2FkZCovCisgICAgKGJpbmFyeWZ1bmMpc2V0X2lzdWIsICAgICAgICAgICAgICAgLypuYl9pbnBsYWNlX3N1YnRyYWN0Ki8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKm5iX2lucGxhY2VfbXVsdGlwbHkqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qbmJfaW5wbGFjZV9kaXZpZGUqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qbmJfaW5wbGFjZV9yZW1haW5kZXIqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qbmJfaW5wbGFjZV9wb3dlciovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLypuYl9pbnBsYWNlX2xzaGlmdCovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLypuYl9pbnBsYWNlX3JzaGlmdCovCisgICAgKGJpbmFyeWZ1bmMpc2V0X2lhbmQsICAgICAgICAgICAgICAgLypuYl9pbnBsYWNlX2FuZCovCisgICAgKGJpbmFyeWZ1bmMpc2V0X2l4b3IsICAgICAgICAgICAgICAgLypuYl9pbnBsYWNlX3hvciovCisgICAgKGJpbmFyeWZ1bmMpc2V0X2lvciwgICAgICAgICAgICAgICAgLypuYl9pbnBsYWNlX29yKi8KK307CisKK1B5RG9jX1NUUlZBUihzZXRfZG9jLAorInNldCgpIC0+IG5ldyBlbXB0eSBzZXQgb2JqZWN0XG5cCitzZXQoaXRlcmFibGUpIC0+IG5ldyBzZXQgb2JqZWN0XG5cCitcblwKK0J1aWxkIGFuIHVub3JkZXJlZCBjb2xsZWN0aW9uIG9mIHVuaXF1ZSBlbGVtZW50cy4iKTsKKworUHlUeXBlT2JqZWN0IFB5U2V0X1R5cGUgPSB7CisgICAgUHlWYXJPYmplY3RfSEVBRF9JTklUKCZQeVR5cGVfVHlwZSwgMCkKKyAgICAic2V0IiwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9uYW1lICovCisgICAgc2l6ZW9mKFB5U2V0T2JqZWN0KSwgICAgICAgICAgICAgICAgLyogdHBfYmFzaWNzaXplICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfaXRlbXNpemUgKi8KKyAgICAvKiBtZXRob2RzICovCisgICAgKGRlc3RydWN0b3Ipc2V0X2RlYWxsb2MsICAgICAgICAgICAgLyogdHBfZGVhbGxvYyAqLworICAgIChwcmludGZ1bmMpc2V0X3RwX3ByaW50LCAgICAgICAgICAgIC8qIHRwX3ByaW50ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZ2V0YXR0ciAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3NldGF0dHIgKi8KKyAgICBzZXRfbm9jbXAsICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9jb21wYXJlICovCisgICAgKHJlcHJmdW5jKXNldF9yZXByLCAgICAgICAgICAgICAgICAgLyogdHBfcmVwciAqLworICAgICZzZXRfYXNfbnVtYmVyLCAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2FzX251bWJlciAqLworICAgICZzZXRfYXNfc2VxdWVuY2UsICAgICAgICAgICAgICAgICAgIC8qIHRwX2FzX3NlcXVlbmNlICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfYXNfbWFwcGluZyAqLworICAgIChoYXNoZnVuYylQeU9iamVjdF9IYXNoTm90SW1wbGVtZW50ZWQsICAgICAgLyogdHBfaGFzaCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2NhbGwgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9zdHIgKi8KKyAgICBQeU9iamVjdF9HZW5lcmljR2V0QXR0ciwgICAgICAgICAgICAvKiB0cF9nZXRhdHRybyAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3NldGF0dHJvICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfYXNfYnVmZmVyICovCisgICAgUHlfVFBGTEFHU19ERUZBVUxUIHwgUHlfVFBGTEFHU19IQVZFX0dDIHwgUHlfVFBGTEFHU19DSEVDS1RZUEVTIHwKKyAgICAgICAgUHlfVFBGTEFHU19CQVNFVFlQRSwgICAgICAgICAgICAvKiB0cF9mbGFncyAqLworICAgIHNldF9kb2MsICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2RvYyAqLworICAgICh0cmF2ZXJzZXByb2Mpc2V0X3RyYXZlcnNlLCAgICAgICAgIC8qIHRwX3RyYXZlcnNlICovCisgICAgKGlucXVpcnkpc2V0X2NsZWFyX2ludGVybmFsLCAgICAgICAgLyogdHBfY2xlYXIgKi8KKyAgICAocmljaGNtcGZ1bmMpc2V0X3JpY2hjb21wYXJlLCAgICAgICAvKiB0cF9yaWNoY29tcGFyZSAqLworICAgIG9mZnNldG9mKFB5U2V0T2JqZWN0LCB3ZWFrcmVmbGlzdCksICAgICAgICAgLyogdHBfd2Vha2xpc3RvZmZzZXQgKi8KKyAgICAoZ2V0aXRlcmZ1bmMpc2V0X2l0ZXIsICAgICAgLyogdHBfaXRlciAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2l0ZXJuZXh0ICovCisgICAgc2V0X21ldGhvZHMsICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfbWV0aG9kcyAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX21lbWJlcnMgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9nZXRzZXQgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9iYXNlICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZGljdCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2Rlc2NyX2dldCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2Rlc2NyX3NldCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2RpY3RvZmZzZXQgKi8KKyAgICAoaW5pdHByb2Mpc2V0X2luaXQsICAgICAgICAgICAgICAgICAvKiB0cF9pbml0ICovCisgICAgUHlUeXBlX0dlbmVyaWNBbGxvYywgICAgICAgICAgICAgICAgLyogdHBfYWxsb2MgKi8KKyAgICBzZXRfbmV3LCAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9uZXcgKi8KKyAgICBQeU9iamVjdF9HQ19EZWwsICAgICAgICAgICAgICAgICAgICAvKiB0cF9mcmVlICovCit9OworCisvKiBmcm96ZW5zZXQgb2JqZWN0ICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLworCisKK3N0YXRpYyBQeU1ldGhvZERlZiBmcm96ZW5zZXRfbWV0aG9kc1tdID0geworICAgIHsiX19jb250YWluc19fIiwoUHlDRnVuY3Rpb24pc2V0X2RpcmVjdF9jb250YWlucywgICAgICAgICAgIE1FVEhfTyB8IE1FVEhfQ09FWElTVCwKKyAgICAgY29udGFpbnNfZG9jfSwKKyAgICB7ImNvcHkiLCAgICAgICAgICAgIChQeUNGdW5jdGlvbilmcm96ZW5zZXRfY29weSwgICAgTUVUSF9OT0FSR1MsCisgICAgIGNvcHlfZG9jfSwKKyAgICB7ImRpZmZlcmVuY2UiLCAgICAgIChQeUNGdW5jdGlvbilzZXRfZGlmZmVyZW5jZV9tdWx0aSwgICAgICBNRVRIX1ZBUkFSR1MsCisgICAgIGRpZmZlcmVuY2VfZG9jfSwKKyAgICB7ImludGVyc2VjdGlvbiIsKFB5Q0Z1bmN0aW9uKXNldF9pbnRlcnNlY3Rpb25fbXVsdGksICAgICAgICBNRVRIX1ZBUkFSR1MsCisgICAgIGludGVyc2VjdGlvbl9kb2N9LAorICAgIHsiaXNkaXNqb2ludCIsICAgICAgKFB5Q0Z1bmN0aW9uKXNldF9pc2Rpc2pvaW50LCAgICBNRVRIX08sCisgICAgIGlzZGlzam9pbnRfZG9jfSwKKyAgICB7Imlzc3Vic2V0IiwgICAgICAgIChQeUNGdW5jdGlvbilzZXRfaXNzdWJzZXQsICAgICAgTUVUSF9PLAorICAgICBpc3N1YnNldF9kb2N9LAorICAgIHsiaXNzdXBlcnNldCIsICAgICAgKFB5Q0Z1bmN0aW9uKXNldF9pc3N1cGVyc2V0LCAgICBNRVRIX08sCisgICAgIGlzc3VwZXJzZXRfZG9jfSwKKyAgICB7Il9fcmVkdWNlX18iLCAgICAgIChQeUNGdW5jdGlvbilzZXRfcmVkdWNlLCAgICAgICAgTUVUSF9OT0FSR1MsCisgICAgIHJlZHVjZV9kb2N9LAorICAgIHsiX19zaXplb2ZfXyIsICAgICAgKFB5Q0Z1bmN0aW9uKXNldF9zaXplb2YsICAgICAgICBNRVRIX05PQVJHUywKKyAgICAgc2l6ZW9mX2RvY30sCisgICAgeyJzeW1tZXRyaWNfZGlmZmVyZW5jZSIsKFB5Q0Z1bmN0aW9uKXNldF9zeW1tZXRyaWNfZGlmZmVyZW5jZSwgICAgICBNRVRIX08sCisgICAgIHN5bW1ldHJpY19kaWZmZXJlbmNlX2RvY30sCisgICAgeyJ1bmlvbiIsICAgICAgICAgICAoUHlDRnVuY3Rpb24pc2V0X3VuaW9uLCAgICAgICAgIE1FVEhfVkFSQVJHUywKKyAgICAgdW5pb25fZG9jfSwKKyAgICB7TlVMTCwgICAgICAgICAgICAgIE5VTEx9ICAgLyogc2VudGluZWwgKi8KK307CisKK3N0YXRpYyBQeU51bWJlck1ldGhvZHMgZnJvemVuc2V0X2FzX251bWJlciA9IHsKKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKm5iX2FkZCovCisgICAgKGJpbmFyeWZ1bmMpc2V0X3N1YiwgICAgICAgICAgICAgICAgLypuYl9zdWJ0cmFjdCovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLypuYl9tdWx0aXBseSovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLypuYl9kaXZpZGUqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qbmJfcmVtYWluZGVyKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKm5iX2Rpdm1vZCovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLypuYl9wb3dlciovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLypuYl9uZWdhdGl2ZSovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLypuYl9wb3NpdGl2ZSovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLypuYl9hYnNvbHV0ZSovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLypuYl9ub256ZXJvKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKm5iX2ludmVydCovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLypuYl9sc2hpZnQqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qbmJfcnNoaWZ0Ki8KKyAgICAoYmluYXJ5ZnVuYylzZXRfYW5kLCAgICAgICAgICAgICAgICAvKm5iX2FuZCovCisgICAgKGJpbmFyeWZ1bmMpc2V0X3hvciwgICAgICAgICAgICAgICAgLypuYl94b3IqLworICAgIChiaW5hcnlmdW5jKXNldF9vciwgICAgICAgICAgICAgICAgIC8qbmJfb3IqLworfTsKKworUHlEb2NfU1RSVkFSKGZyb3plbnNldF9kb2MsCisiZnJvemVuc2V0KCkgLT4gZW1wdHkgZnJvemVuc2V0IG9iamVjdFxuXAorZnJvemVuc2V0KGl0ZXJhYmxlKSAtPiBmcm96ZW5zZXQgb2JqZWN0XG5cCitcblwKK0J1aWxkIGFuIGltbXV0YWJsZSB1bm9yZGVyZWQgY29sbGVjdGlvbiBvZiB1bmlxdWUgZWxlbWVudHMuIik7CisKK1B5VHlwZU9iamVjdCBQeUZyb3plblNldF9UeXBlID0geworICAgIFB5VmFyT2JqZWN0X0hFQURfSU5JVCgmUHlUeXBlX1R5cGUsIDApCisgICAgImZyb3plbnNldCIsICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfbmFtZSAqLworICAgIHNpemVvZihQeVNldE9iamVjdCksICAgICAgICAgICAgICAgIC8qIHRwX2Jhc2ljc2l6ZSAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2l0ZW1zaXplICovCisgICAgLyogbWV0aG9kcyAqLworICAgIChkZXN0cnVjdG9yKXNldF9kZWFsbG9jLCAgICAgICAgICAgIC8qIHRwX2RlYWxsb2MgKi8KKyAgICAocHJpbnRmdW5jKXNldF90cF9wcmludCwgICAgICAgICAgICAvKiB0cF9wcmludCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2dldGF0dHIgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9zZXRhdHRyICovCisgICAgc2V0X25vY21wLCAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfY29tcGFyZSAqLworICAgIChyZXByZnVuYylzZXRfcmVwciwgICAgICAgICAgICAgICAgIC8qIHRwX3JlcHIgKi8KKyAgICAmZnJvemVuc2V0X2FzX251bWJlciwgICAgICAgICAgICAgICAvKiB0cF9hc19udW1iZXIgKi8KKyAgICAmc2V0X2FzX3NlcXVlbmNlLCAgICAgICAgICAgICAgICAgICAvKiB0cF9hc19zZXF1ZW5jZSAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2FzX21hcHBpbmcgKi8KKyAgICBmcm96ZW5zZXRfaGFzaCwgICAgICAgICAgICAgICAgICAgICAvKiB0cF9oYXNoICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfY2FsbCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3N0ciAqLworICAgIFB5T2JqZWN0X0dlbmVyaWNHZXRBdHRyLCAgICAgICAgICAgIC8qIHRwX2dldGF0dHJvICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfc2V0YXR0cm8gKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9hc19idWZmZXIgKi8KKyAgICBQeV9UUEZMQUdTX0RFRkFVTFQgfCBQeV9UUEZMQUdTX0hBVkVfR0MgfCBQeV9UUEZMQUdTX0NIRUNLVFlQRVMgfAorICAgICAgICBQeV9UUEZMQUdTX0JBU0VUWVBFLCAgICAgICAgICAgIC8qIHRwX2ZsYWdzICovCisgICAgZnJvemVuc2V0X2RvYywgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZG9jICovCisgICAgKHRyYXZlcnNlcHJvYylzZXRfdHJhdmVyc2UsICAgICAgICAgLyogdHBfdHJhdmVyc2UgKi8KKyAgICAoaW5xdWlyeSlzZXRfY2xlYXJfaW50ZXJuYWwsICAgICAgICAvKiB0cF9jbGVhciAqLworICAgIChyaWNoY21wZnVuYylzZXRfcmljaGNvbXBhcmUsICAgICAgIC8qIHRwX3JpY2hjb21wYXJlICovCisgICAgb2Zmc2V0b2YoUHlTZXRPYmplY3QsIHdlYWtyZWZsaXN0KSwgICAgICAgICAvKiB0cF93ZWFrbGlzdG9mZnNldCAqLworICAgIChnZXRpdGVyZnVuYylzZXRfaXRlciwgICAgICAgICAgICAgIC8qIHRwX2l0ZXIgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9pdGVybmV4dCAqLworICAgIGZyb3plbnNldF9tZXRob2RzLCAgICAgICAgICAgICAgICAgIC8qIHRwX21ldGhvZHMgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9tZW1iZXJzICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZ2V0c2V0ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfYmFzZSAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2RpY3QgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9kZXNjcl9nZXQgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9kZXNjcl9zZXQgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9kaWN0b2Zmc2V0ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfaW5pdCAqLworICAgIFB5VHlwZV9HZW5lcmljQWxsb2MsICAgICAgICAgICAgICAgIC8qIHRwX2FsbG9jICovCisgICAgZnJvemVuc2V0X25ldywgICAgICAgICAgICAgICAgICAgICAgLyogdHBfbmV3ICovCisgICAgUHlPYmplY3RfR0NfRGVsLCAgICAgICAgICAgICAgICAgICAgLyogdHBfZnJlZSAqLworfTsKKworCisvKioqKiogQyBBUEkgZnVuY3Rpb25zICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCisKK1B5T2JqZWN0ICoKK1B5U2V0X05ldyhQeU9iamVjdCAqaXRlcmFibGUpCit7CisgICAgcmV0dXJuIG1ha2VfbmV3X3NldCgmUHlTZXRfVHlwZSwgaXRlcmFibGUpOworfQorCitQeU9iamVjdCAqCitQeUZyb3plblNldF9OZXcoUHlPYmplY3QgKml0ZXJhYmxlKQoreworICAgIHJldHVybiBtYWtlX25ld19zZXQoJlB5RnJvemVuU2V0X1R5cGUsIGl0ZXJhYmxlKTsKK30KKworUHlfc3NpemVfdAorUHlTZXRfU2l6ZShQeU9iamVjdCAqYW55c2V0KQoreworICAgIGlmICghUHlBbnlTZXRfQ2hlY2soYW55c2V0KSkgeworICAgICAgICBQeUVycl9CYWRJbnRlcm5hbENhbGwoKTsKKyAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKyAgICByZXR1cm4gUHlTZXRfR0VUX1NJWkUoYW55c2V0KTsKK30KKworaW50CitQeVNldF9DbGVhcihQeU9iamVjdCAqc2V0KQoreworICAgIGlmICghUHlTZXRfQ2hlY2soc2V0KSkgeworICAgICAgICBQeUVycl9CYWRJbnRlcm5hbENhbGwoKTsKKyAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKyAgICByZXR1cm4gc2V0X2NsZWFyX2ludGVybmFsKChQeVNldE9iamVjdCAqKXNldCk7Cit9CisKK2ludAorUHlTZXRfQ29udGFpbnMoUHlPYmplY3QgKmFueXNldCwgUHlPYmplY3QgKmtleSkKK3sKKyAgICBpZiAoIVB5QW55U2V0X0NoZWNrKGFueXNldCkpIHsKKyAgICAgICAgUHlFcnJfQmFkSW50ZXJuYWxDYWxsKCk7CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisgICAgcmV0dXJuIHNldF9jb250YWluc19rZXkoKFB5U2V0T2JqZWN0ICopYW55c2V0LCBrZXkpOworfQorCitpbnQKK1B5U2V0X0Rpc2NhcmQoUHlPYmplY3QgKnNldCwgUHlPYmplY3QgKmtleSkKK3sKKyAgICBpZiAoIVB5U2V0X0NoZWNrKHNldCkpIHsKKyAgICAgICAgUHlFcnJfQmFkSW50ZXJuYWxDYWxsKCk7CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisgICAgcmV0dXJuIHNldF9kaXNjYXJkX2tleSgoUHlTZXRPYmplY3QgKilzZXQsIGtleSk7Cit9CisKK2ludAorUHlTZXRfQWRkKFB5T2JqZWN0ICphbnlzZXQsIFB5T2JqZWN0ICprZXkpCit7CisgICAgaWYgKCFQeVNldF9DaGVjayhhbnlzZXQpICYmCisgICAgICAgICghUHlGcm96ZW5TZXRfQ2hlY2soYW55c2V0KSB8fCBQeV9SRUZDTlQoYW55c2V0KSAhPSAxKSkgeworICAgICAgICBQeUVycl9CYWRJbnRlcm5hbENhbGwoKTsKKyAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKyAgICByZXR1cm4gc2V0X2FkZF9rZXkoKFB5U2V0T2JqZWN0ICopYW55c2V0LCBrZXkpOworfQorCitpbnQKK19QeVNldF9OZXh0KFB5T2JqZWN0ICpzZXQsIFB5X3NzaXplX3QgKnBvcywgUHlPYmplY3QgKiprZXkpCit7CisgICAgc2V0ZW50cnkgKmVudHJ5X3B0cjsKKworICAgIGlmICghUHlBbnlTZXRfQ2hlY2soc2V0KSkgeworICAgICAgICBQeUVycl9CYWRJbnRlcm5hbENhbGwoKTsKKyAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKyAgICBpZiAoc2V0X25leHQoKFB5U2V0T2JqZWN0ICopc2V0LCBwb3MsICZlbnRyeV9wdHIpID09IDApCisgICAgICAgIHJldHVybiAwOworICAgICprZXkgPSBlbnRyeV9wdHItPmtleTsKKyAgICByZXR1cm4gMTsKK30KKworaW50CitfUHlTZXRfTmV4dEVudHJ5KFB5T2JqZWN0ICpzZXQsIFB5X3NzaXplX3QgKnBvcywgUHlPYmplY3QgKiprZXksIGxvbmcgKmhhc2gpCit7CisgICAgc2V0ZW50cnkgKmVudHJ5OworCisgICAgaWYgKCFQeUFueVNldF9DaGVjayhzZXQpKSB7CisgICAgICAgIFB5RXJyX0JhZEludGVybmFsQ2FsbCgpOworICAgICAgICByZXR1cm4gLTE7CisgICAgfQorICAgIGlmIChzZXRfbmV4dCgoUHlTZXRPYmplY3QgKilzZXQsIHBvcywgJmVudHJ5KSA9PSAwKQorICAgICAgICByZXR1cm4gMDsKKyAgICAqa2V5ID0gZW50cnktPmtleTsKKyAgICAqaGFzaCA9IGVudHJ5LT5oYXNoOworICAgIHJldHVybiAxOworfQorCitQeU9iamVjdCAqCitQeVNldF9Qb3AoUHlPYmplY3QgKnNldCkKK3sKKyAgICBpZiAoIVB5U2V0X0NoZWNrKHNldCkpIHsKKyAgICAgICAgUHlFcnJfQmFkSW50ZXJuYWxDYWxsKCk7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICByZXR1cm4gc2V0X3BvcCgoUHlTZXRPYmplY3QgKilzZXQpOworfQorCitpbnQKK19QeVNldF9VcGRhdGUoUHlPYmplY3QgKnNldCwgUHlPYmplY3QgKml0ZXJhYmxlKQoreworICAgIGlmICghUHlTZXRfQ2hlY2soc2V0KSkgeworICAgICAgICBQeUVycl9CYWRJbnRlcm5hbENhbGwoKTsKKyAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKyAgICByZXR1cm4gc2V0X3VwZGF0ZV9pbnRlcm5hbCgoUHlTZXRPYmplY3QgKilzZXQsIGl0ZXJhYmxlKTsKK30KKworI2lmZGVmIFB5X0RFQlVHCisKKy8qIFRlc3QgY29kZSB0byBiZSBjYWxsZWQgd2l0aCBhbnkgdGhyZWUgZWxlbWVudCBzZXQuCisgICBSZXR1cm5zIFRydWUgYW5kIG9yaWdpbmFsIHNldCBpcyByZXN0b3JlZC4gKi8KKworI2RlZmluZSBhc3NlcnRSYWlzZXMoY2FsbF9yZXR1cm5fdmFsdWUsIGV4Y2VwdGlvbikgICAgICAgICAgICAgIFwKKyAgICBkbyB7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgIGFzc2VydChjYWxsX3JldHVybl92YWx1ZSk7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICBhc3NlcnQoUHlFcnJfRXhjZXB0aW9uTWF0Y2hlcyhleGNlcHRpb24pKTsgICAgICAgICAgICAgIFwKKyAgICAgICAgUHlFcnJfQ2xlYXIoKTsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgfSB3aGlsZSgwKQorCitzdGF0aWMgUHlPYmplY3QgKgordGVzdF9jX2FwaShQeVNldE9iamVjdCAqc28pCit7CisgICAgUHlfc3NpemVfdCBjb3VudDsKKyAgICBjaGFyICpzOworICAgIFB5X3NzaXplX3QgaTsKKyAgICBQeU9iamVjdCAqZWxlbT1OVUxMLCAqZHVwPU5VTEwsICp0LCAqZiwgKmR1cDIsICp4OworICAgIFB5T2JqZWN0ICpvYiA9IChQeU9iamVjdCAqKXNvOworICAgIFB5T2JqZWN0ICpzdHI7CisKKyAgICAvKiBWZXJpZnkgcHJlY29uZGl0aW9ucyAqLworICAgIGFzc2VydChQeUFueVNldF9DaGVjayhvYikpOworICAgIGFzc2VydChQeUFueVNldF9DaGVja0V4YWN0KG9iKSk7CisgICAgYXNzZXJ0KCFQeUZyb3plblNldF9DaGVja0V4YWN0KG9iKSk7CisKKyAgICAvKiBzby5jbGVhcigpOyBzbyB8PSBzZXQoImFiYyIpOyAqLworICAgIHN0ciA9IFB5U3RyaW5nX0Zyb21TdHJpbmcoImFiYyIpOworICAgIGlmIChzdHIgPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgc2V0X2NsZWFyX2ludGVybmFsKHNvKTsKKyAgICBpZiAoc2V0X3VwZGF0ZV9pbnRlcm5hbChzbywgc3RyKSA9PSAtMSkgeworICAgICAgICBQeV9ERUNSRUYoc3RyKTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIFB5X0RFQ1JFRihzdHIpOworCisgICAgLyogRXhlcmNpc2UgdHlwZS9zaXplIGNoZWNrcyAqLworICAgIGFzc2VydChQeVNldF9TaXplKG9iKSA9PSAzKTsKKyAgICBhc3NlcnQoUHlTZXRfR0VUX1NJWkUob2IpID09IDMpOworCisgICAgLyogUmFpc2UgVHlwZUVycm9yIGZvciBub24taXRlcmFibGUgY29uc3RydWN0b3IgYXJndW1lbnRzICovCisgICAgYXNzZXJ0UmFpc2VzKFB5U2V0X05ldyhQeV9Ob25lKSA9PSBOVUxMLCBQeUV4Y19UeXBlRXJyb3IpOworICAgIGFzc2VydFJhaXNlcyhQeUZyb3plblNldF9OZXcoUHlfTm9uZSkgPT0gTlVMTCwgUHlFeGNfVHlwZUVycm9yKTsKKworICAgIC8qIFJhaXNlIFR5cGVFcnJvciBmb3IgdW5oYXNoYWJsZSBrZXkgKi8KKyAgICBkdXAgPSBQeVNldF9OZXcob2IpOworICAgIGFzc2VydFJhaXNlcyhQeVNldF9EaXNjYXJkKG9iLCBkdXApID09IC0xLCBQeUV4Y19UeXBlRXJyb3IpOworICAgIGFzc2VydFJhaXNlcyhQeVNldF9Db250YWlucyhvYiwgZHVwKSA9PSAtMSwgUHlFeGNfVHlwZUVycm9yKTsKKyAgICBhc3NlcnRSYWlzZXMoUHlTZXRfQWRkKG9iLCBkdXApID09IC0xLCBQeUV4Y19UeXBlRXJyb3IpOworCisgICAgLyogRXhlcmNpc2Ugc3VjY2Vzc2Z1bCBwb3AsIGNvbnRhaW5zLCBhZGQsIGFuZCBkaXNjYXJkICovCisgICAgZWxlbSA9IFB5U2V0X1BvcChvYik7CisgICAgYXNzZXJ0KFB5U2V0X0NvbnRhaW5zKG9iLCBlbGVtKSA9PSAwKTsKKyAgICBhc3NlcnQoUHlTZXRfR0VUX1NJWkUob2IpID09IDIpOworICAgIGFzc2VydChQeVNldF9BZGQob2IsIGVsZW0pID09IDApOworICAgIGFzc2VydChQeVNldF9Db250YWlucyhvYiwgZWxlbSkgPT0gMSk7CisgICAgYXNzZXJ0KFB5U2V0X0dFVF9TSVpFKG9iKSA9PSAzKTsKKyAgICBhc3NlcnQoUHlTZXRfRGlzY2FyZChvYiwgZWxlbSkgPT0gMSk7CisgICAgYXNzZXJ0KFB5U2V0X0dFVF9TSVpFKG9iKSA9PSAyKTsKKyAgICBhc3NlcnQoUHlTZXRfRGlzY2FyZChvYiwgZWxlbSkgPT0gMCk7CisgICAgYXNzZXJ0KFB5U2V0X0dFVF9TSVpFKG9iKSA9PSAyKTsKKworICAgIC8qIEV4ZXJjaXNlIGNsZWFyICovCisgICAgZHVwMiA9IFB5U2V0X05ldyhkdXApOworICAgIGFzc2VydChQeVNldF9DbGVhcihkdXAyKSA9PSAwKTsKKyAgICBhc3NlcnQoUHlTZXRfU2l6ZShkdXAyKSA9PSAwKTsKKyAgICBQeV9ERUNSRUYoZHVwMik7CisKKyAgICAvKiBSYWlzZSBTeXN0ZW1FcnJvciBvbiBjbGVhciBvciB1cGRhdGUgb2YgZnJvemVuIHNldCAqLworICAgIGYgPSBQeUZyb3plblNldF9OZXcoZHVwKTsKKyAgICBhc3NlcnRSYWlzZXMoUHlTZXRfQ2xlYXIoZikgPT0gLTEsIFB5RXhjX1N5c3RlbUVycm9yKTsKKyAgICBhc3NlcnRSYWlzZXMoX1B5U2V0X1VwZGF0ZShmLCBkdXApID09IC0xLCBQeUV4Y19TeXN0ZW1FcnJvcik7CisgICAgYXNzZXJ0KFB5U2V0X0FkZChmLCBlbGVtKSA9PSAwKTsKKyAgICBQeV9JTkNSRUYoZik7CisgICAgYXNzZXJ0UmFpc2VzKFB5U2V0X0FkZChmLCBlbGVtKSA9PSAtMSwgUHlFeGNfU3lzdGVtRXJyb3IpOworICAgIFB5X0RFQ1JFRihmKTsKKyAgICBQeV9ERUNSRUYoZik7CisKKyAgICAvKiBFeGVyY2lzZSBkaXJlY3QgaXRlcmF0aW9uICovCisgICAgaSA9IDAsIGNvdW50ID0gMDsKKyAgICB3aGlsZSAoX1B5U2V0X05leHQoKFB5T2JqZWN0ICopZHVwLCAmaSwgJngpKSB7CisgICAgICAgIHMgPSBQeVN0cmluZ19Bc1N0cmluZyh4KTsKKyAgICAgICAgYXNzZXJ0KHMgJiYgKHNbMF0gPT0gJ2EnIHx8IHNbMF0gPT0gJ2InIHx8IHNbMF0gPT0gJ2MnKSk7CisgICAgICAgIGNvdW50Kys7CisgICAgfQorICAgIGFzc2VydChjb3VudCA9PSAzKTsKKworICAgIC8qIEV4ZXJjaXNlIHVwZGF0ZXMgKi8KKyAgICBkdXAyID0gUHlTZXRfTmV3KE5VTEwpOworICAgIGFzc2VydChfUHlTZXRfVXBkYXRlKGR1cDIsIGR1cCkgPT0gMCk7CisgICAgYXNzZXJ0KFB5U2V0X1NpemUoZHVwMikgPT0gMyk7CisgICAgYXNzZXJ0KF9QeVNldF9VcGRhdGUoZHVwMiwgZHVwKSA9PSAwKTsKKyAgICBhc3NlcnQoUHlTZXRfU2l6ZShkdXAyKSA9PSAzKTsKKyAgICBQeV9ERUNSRUYoZHVwMik7CisKKyAgICAvKiBSYWlzZSBTeXN0ZW1FcnJvciB3aGVuIHNlbGYgYXJndW1lbnQgaXMgbm90IGEgc2V0IG9yIGZyb3plbnNldC4gKi8KKyAgICB0ID0gUHlUdXBsZV9OZXcoMCk7CisgICAgYXNzZXJ0UmFpc2VzKFB5U2V0X1NpemUodCkgPT0gLTEsIFB5RXhjX1N5c3RlbUVycm9yKTsKKyAgICBhc3NlcnRSYWlzZXMoUHlTZXRfQ29udGFpbnModCwgZWxlbSkgPT0gLTEsIFB5RXhjX1N5c3RlbUVycm9yKTsKKyAgICBQeV9ERUNSRUYodCk7CisKKyAgICAvKiBSYWlzZSBTeXN0ZW1FcnJvciB3aGVuIHNlbGYgYXJndW1lbnQgaXMgbm90IGEgc2V0LiAqLworICAgIGYgPSBQeUZyb3plblNldF9OZXcoZHVwKTsKKyAgICBhc3NlcnQoUHlTZXRfU2l6ZShmKSA9PSAzKTsKKyAgICBhc3NlcnQoUHlGcm96ZW5TZXRfQ2hlY2tFeGFjdChmKSk7CisgICAgYXNzZXJ0UmFpc2VzKFB5U2V0X0Rpc2NhcmQoZiwgZWxlbSkgPT0gLTEsIFB5RXhjX1N5c3RlbUVycm9yKTsKKyAgICBhc3NlcnRSYWlzZXMoUHlTZXRfUG9wKGYpID09IE5VTEwsIFB5RXhjX1N5c3RlbUVycm9yKTsKKyAgICBQeV9ERUNSRUYoZik7CisKKyAgICAvKiBSYWlzZSBLZXlFcnJvciB3aGVuIHBvcHBpbmcgZnJvbSBhbiBlbXB0eSBzZXQgKi8KKyAgICBhc3NlcnQoUHlOdW1iZXJfSW5QbGFjZVN1YnRyYWN0KG9iLCBvYikgPT0gb2IpOworICAgIFB5X0RFQ1JFRihvYik7CisgICAgYXNzZXJ0KFB5U2V0X0dFVF9TSVpFKG9iKSA9PSAwKTsKKyAgICBhc3NlcnRSYWlzZXMoUHlTZXRfUG9wKG9iKSA9PSBOVUxMLCBQeUV4Y19LZXlFcnJvcik7CisKKyAgICAvKiBSZXN0b3JlIHRoZSBzZXQgZnJvbSB0aGUgY29weSB1c2luZyB0aGUgUHlOdW1iZXIgQVBJICovCisgICAgYXNzZXJ0KFB5TnVtYmVyX0luUGxhY2VPcihvYiwgZHVwKSA9PSBvYik7CisgICAgUHlfREVDUkVGKG9iKTsKKworICAgIC8qIFZlcmlmeSBjb25zdHJ1Y3RvcnMgYWNjZXB0IE5VTEwgYXJndW1lbnRzICovCisgICAgZiA9IFB5U2V0X05ldyhOVUxMKTsKKyAgICBhc3NlcnQoZiAhPSBOVUxMKTsKKyAgICBhc3NlcnQoUHlTZXRfR0VUX1NJWkUoZikgPT0gMCk7CisgICAgUHlfREVDUkVGKGYpOworICAgIGYgPSBQeUZyb3plblNldF9OZXcoTlVMTCk7CisgICAgYXNzZXJ0KGYgIT0gTlVMTCk7CisgICAgYXNzZXJ0KFB5RnJvemVuU2V0X0NoZWNrRXhhY3QoZikpOworICAgIGFzc2VydChQeVNldF9HRVRfU0laRShmKSA9PSAwKTsKKyAgICBQeV9ERUNSRUYoZik7CisKKyAgICBQeV9ERUNSRUYoZWxlbSk7CisgICAgUHlfREVDUkVGKGR1cCk7CisgICAgUHlfUkVUVVJOX1RSVUU7Cit9CisKKyN1bmRlZiBhc3NlcnRSYWlzZXMKKworI2VuZGlmCmRpZmYgLS1naXQgYS9QeXRob24tMi43LjUvT2JqZWN0cy9zbGljZW9iamVjdC5jIGIvUHl0aG9uLTIuNy41L09iamVjdHMvc2xpY2VvYmplY3QuYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43NjdhNTBhCi0tLSAvZGV2L251bGwKKysrIGIvUHl0aG9uLTIuNy41L09iamVjdHMvc2xpY2VvYmplY3QuYwpAQCAtMCwwICsxLDM2MiBAQAorLyoKK1dyaXR0ZW4gYnkgSmltIEh1Z3VuaW4gYW5kIENocmlzIENoYXNlLgorCitUaGlzIGluY2x1ZGVzIGJvdGggdGhlIHNpbmd1bGFyIGVsbGlwc2lzIG9iamVjdCBhbmQgc2xpY2Ugb2JqZWN0cy4KKworR3VpZG8sIGZlZWwgZnJlZSB0byBkbyB3aGF0ZXZlciB5b3Ugd2FudCBpbiB0aGUgd2F5IG9mIGNvcHlyaWdodHMKK2ZvciB0aGlzIGZpbGUuCisqLworCisvKgorUHlfRWxsaXBzaXMgZW5jb2RlcyB0aGUgJy4uLicgcnViYmVyIGluZGV4IHRva2VuLiBJdCBpcyBzaW1pbGFyIHRvCit0aGUgUHlfTm9uZVN0cnVjdCBpbiB0aGF0IHRoZXJlIGlzIG5vIHdheSB0byBjcmVhdGUgb3RoZXIgb2JqZWN0cyBvZgordGhpcyB0eXBlIGFuZCB0aGVyZSBpcyBleGFjdGx5IG9uZSBpbiBleGlzdGVuY2UuCisqLworCisjaW5jbHVkZSAiUHl0aG9uLmgiCisjaW5jbHVkZSAic3RydWN0bWVtYmVyLmgiCisKK3N0YXRpYyBQeU9iamVjdCAqCitlbGxpcHNpc19yZXByKFB5T2JqZWN0ICpvcCkKK3sKKyAgICByZXR1cm4gUHlTdHJpbmdfRnJvbVN0cmluZygiRWxsaXBzaXMiKTsKK30KKworUHlUeXBlT2JqZWN0IFB5RWxsaXBzaXNfVHlwZSA9IHsKKyAgICBQeVZhck9iamVjdF9IRUFEX0lOSVQoJlB5VHlwZV9UeXBlLCAwKQorICAgICJlbGxpcHNpcyIsICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX25hbWUgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9iYXNpY3NpemUgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9pdGVtc2l6ZSAqLworICAgIDAsIC8qbmV2ZXIgY2FsbGVkKi8gICAgICAgICAgICAgICAgIC8qIHRwX2RlYWxsb2MgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9wcmludCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2dldGF0dHIgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9zZXRhdHRyICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfY29tcGFyZSAqLworICAgIGVsbGlwc2lzX3JlcHIsICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3JlcHIgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9hc19udW1iZXIgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9hc19zZXF1ZW5jZSAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2FzX21hcHBpbmcgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9oYXNoICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfY2FsbCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3N0ciAqLworICAgIFB5T2JqZWN0X0dlbmVyaWNHZXRBdHRyLCAgICAgICAgICAgIC8qIHRwX2dldGF0dHJvICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfc2V0YXR0cm8gKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9hc19idWZmZXIgKi8KKyAgICBQeV9UUEZMQUdTX0RFRkFVTFQsICAgICAgICAgICAgICAgICAvKiB0cF9mbGFncyAqLworfTsKKworUHlPYmplY3QgX1B5X0VsbGlwc2lzT2JqZWN0ID0geworICAgIF9QeU9iamVjdF9FWFRSQV9JTklUCisgICAgMSwgJlB5RWxsaXBzaXNfVHlwZQorfTsKKworCisvKiBTbGljZSBvYmplY3QgaW1wbGVtZW50YXRpb24KKworICAgc3RhcnQsIHN0b3AsIGFuZCBzdGVwIGFyZSBweXRob24gb2JqZWN0cyB3aXRoIE5vbmUgaW5kaWNhdGluZyBubworICAgaW5kZXggaXMgcHJlc2VudC4KKyovCisKK1B5T2JqZWN0ICoKK1B5U2xpY2VfTmV3KFB5T2JqZWN0ICpzdGFydCwgUHlPYmplY3QgKnN0b3AsIFB5T2JqZWN0ICpzdGVwKQoreworICAgIFB5U2xpY2VPYmplY3QgKm9iaiA9IFB5T2JqZWN0X05ldyhQeVNsaWNlT2JqZWN0LCAmUHlTbGljZV9UeXBlKTsKKworICAgIGlmIChvYmogPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisKKyAgICBpZiAoc3RlcCA9PSBOVUxMKSBzdGVwID0gUHlfTm9uZTsKKyAgICBQeV9JTkNSRUYoc3RlcCk7CisgICAgaWYgKHN0YXJ0ID09IE5VTEwpIHN0YXJ0ID0gUHlfTm9uZTsKKyAgICBQeV9JTkNSRUYoc3RhcnQpOworICAgIGlmIChzdG9wID09IE5VTEwpIHN0b3AgPSBQeV9Ob25lOworICAgIFB5X0lOQ1JFRihzdG9wKTsKKworICAgIG9iai0+c3RlcCA9IHN0ZXA7CisgICAgb2JqLT5zdGFydCA9IHN0YXJ0OworICAgIG9iai0+c3RvcCA9IHN0b3A7CisKKyAgICByZXR1cm4gKFB5T2JqZWN0ICopIG9iajsKK30KKworUHlPYmplY3QgKgorX1B5U2xpY2VfRnJvbUluZGljZXMoUHlfc3NpemVfdCBpc3RhcnQsIFB5X3NzaXplX3QgaXN0b3ApCit7CisgICAgUHlPYmplY3QgKnN0YXJ0LCAqZW5kLCAqc2xpY2U7CisgICAgc3RhcnQgPSBQeUludF9Gcm9tU3NpemVfdChpc3RhcnQpOworICAgIGlmICghc3RhcnQpCisgICAgICAgIHJldHVybiBOVUxMOworICAgIGVuZCA9IFB5SW50X0Zyb21Tc2l6ZV90KGlzdG9wKTsKKyAgICBpZiAoIWVuZCkgeworICAgICAgICBQeV9ERUNSRUYoc3RhcnQpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisKKyAgICBzbGljZSA9IFB5U2xpY2VfTmV3KHN0YXJ0LCBlbmQsIE5VTEwpOworICAgIFB5X0RFQ1JFRihzdGFydCk7CisgICAgUHlfREVDUkVGKGVuZCk7CisgICAgcmV0dXJuIHNsaWNlOworfQorCitpbnQKK1B5U2xpY2VfR2V0SW5kaWNlcyhQeVNsaWNlT2JqZWN0ICpyLCBQeV9zc2l6ZV90IGxlbmd0aCwKKyAgICAgICAgICAgICAgICAgICBQeV9zc2l6ZV90ICpzdGFydCwgUHlfc3NpemVfdCAqc3RvcCwgUHlfc3NpemVfdCAqc3RlcCkKK3sKKyAgICAvKiBYWFggc3VwcG9ydCBsb25nIGludHMgKi8KKyAgICBpZiAoci0+c3RlcCA9PSBQeV9Ob25lKSB7CisgICAgICAgICpzdGVwID0gMTsKKyAgICB9IGVsc2UgeworICAgICAgICBpZiAoIVB5SW50X0NoZWNrKHItPnN0ZXApICYmICFQeUxvbmdfQ2hlY2soci0+c3RlcCkpIHJldHVybiAtMTsKKyAgICAgICAgKnN0ZXAgPSBQeUludF9Bc1NzaXplX3Qoci0+c3RlcCk7CisgICAgfQorICAgIGlmIChyLT5zdGFydCA9PSBQeV9Ob25lKSB7CisgICAgICAgICpzdGFydCA9ICpzdGVwIDwgMCA/IGxlbmd0aC0xIDogMDsKKyAgICB9IGVsc2UgeworICAgICAgICBpZiAoIVB5SW50X0NoZWNrKHItPnN0YXJ0KSAmJiAhUHlMb25nX0NoZWNrKHItPnN0ZXApKSByZXR1cm4gLTE7CisgICAgICAgICpzdGFydCA9IFB5SW50X0FzU3NpemVfdChyLT5zdGFydCk7CisgICAgICAgIGlmICgqc3RhcnQgPCAwKSAqc3RhcnQgKz0gbGVuZ3RoOworICAgIH0KKyAgICBpZiAoci0+c3RvcCA9PSBQeV9Ob25lKSB7CisgICAgICAgICpzdG9wID0gKnN0ZXAgPCAwID8gLTEgOiBsZW5ndGg7CisgICAgfSBlbHNlIHsKKyAgICAgICAgaWYgKCFQeUludF9DaGVjayhyLT5zdG9wKSAmJiAhUHlMb25nX0NoZWNrKHItPnN0ZXApKSByZXR1cm4gLTE7CisgICAgICAgICpzdG9wID0gUHlJbnRfQXNTc2l6ZV90KHItPnN0b3ApOworICAgICAgICBpZiAoKnN0b3AgPCAwKSAqc3RvcCArPSBsZW5ndGg7CisgICAgfQorICAgIGlmICgqc3RvcCA+IGxlbmd0aCkgcmV0dXJuIC0xOworICAgIGlmICgqc3RhcnQgPj0gbGVuZ3RoKSByZXR1cm4gLTE7CisgICAgaWYgKCpzdGVwID09IDApIHJldHVybiAtMTsKKyAgICByZXR1cm4gMDsKK30KKworaW50CitQeVNsaWNlX0dldEluZGljZXNFeChQeVNsaWNlT2JqZWN0ICpyLCBQeV9zc2l6ZV90IGxlbmd0aCwKKyAgICAgICAgICAgICAgICAgICAgIFB5X3NzaXplX3QgKnN0YXJ0LCBQeV9zc2l6ZV90ICpzdG9wLCBQeV9zc2l6ZV90ICpzdGVwLCBQeV9zc2l6ZV90ICpzbGljZWxlbmd0aCkKK3sKKyAgICAvKiB0aGlzIGlzIGhhcmRlciB0byBnZXQgcmlnaHQgdGhhbiB5b3UgbWlnaHQgdGhpbmsgKi8KKworICAgIFB5X3NzaXplX3QgZGVmc3RhcnQsIGRlZnN0b3A7CisKKyAgICBpZiAoci0+c3RlcCA9PSBQeV9Ob25lKSB7CisgICAgICAgICpzdGVwID0gMTsKKyAgICB9CisgICAgZWxzZSB7CisgICAgICAgIGlmICghX1B5RXZhbF9TbGljZUluZGV4KHItPnN0ZXAsIHN0ZXApKSByZXR1cm4gLTE7CisgICAgICAgIGlmICgqc3RlcCA9PSAwKSB7CisgICAgICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfVmFsdWVFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAic2xpY2Ugc3RlcCBjYW5ub3QgYmUgemVybyIpOworICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICB9CisgICAgfQorCisgICAgZGVmc3RhcnQgPSAqc3RlcCA8IDAgPyBsZW5ndGgtMSA6IDA7CisgICAgZGVmc3RvcCA9ICpzdGVwIDwgMCA/IC0xIDogbGVuZ3RoOworCisgICAgaWYgKHItPnN0YXJ0ID09IFB5X05vbmUpIHsKKyAgICAgICAgKnN0YXJ0ID0gZGVmc3RhcnQ7CisgICAgfQorICAgIGVsc2UgeworICAgICAgICBpZiAoIV9QeUV2YWxfU2xpY2VJbmRleChyLT5zdGFydCwgc3RhcnQpKSByZXR1cm4gLTE7CisgICAgICAgIGlmICgqc3RhcnQgPCAwKSAqc3RhcnQgKz0gbGVuZ3RoOworICAgICAgICBpZiAoKnN0YXJ0IDwgMCkgKnN0YXJ0ID0gKCpzdGVwIDwgMCkgPyAtMSA6IDA7CisgICAgICAgIGlmICgqc3RhcnQgPj0gbGVuZ3RoKQorICAgICAgICAgICAgKnN0YXJ0ID0gKCpzdGVwIDwgMCkgPyBsZW5ndGggLSAxIDogbGVuZ3RoOworICAgIH0KKworICAgIGlmIChyLT5zdG9wID09IFB5X05vbmUpIHsKKyAgICAgICAgKnN0b3AgPSBkZWZzdG9wOworICAgIH0KKyAgICBlbHNlIHsKKyAgICAgICAgaWYgKCFfUHlFdmFsX1NsaWNlSW5kZXgoci0+c3RvcCwgc3RvcCkpIHJldHVybiAtMTsKKyAgICAgICAgaWYgKCpzdG9wIDwgMCkgKnN0b3AgKz0gbGVuZ3RoOworICAgICAgICBpZiAoKnN0b3AgPCAwKSAqc3RvcCA9ICgqc3RlcCA8IDApID8gLTEgOiAwOworICAgICAgICBpZiAoKnN0b3AgPj0gbGVuZ3RoKQorICAgICAgICAgICAgKnN0b3AgPSAoKnN0ZXAgPCAwKSA/IGxlbmd0aCAtIDEgOiBsZW5ndGg7CisgICAgfQorCisgICAgaWYgKCgqc3RlcCA8IDAgJiYgKnN0b3AgPj0gKnN0YXJ0KQorICAgICAgICB8fCAoKnN0ZXAgPiAwICYmICpzdGFydCA+PSAqc3RvcCkpIHsKKyAgICAgICAgKnNsaWNlbGVuZ3RoID0gMDsKKyAgICB9CisgICAgZWxzZSBpZiAoKnN0ZXAgPCAwKSB7CisgICAgICAgICpzbGljZWxlbmd0aCA9ICgqc3RvcC0qc3RhcnQrMSkvKCpzdGVwKSsxOworICAgIH0KKyAgICBlbHNlIHsKKyAgICAgICAgKnNsaWNlbGVuZ3RoID0gKCpzdG9wLSpzdGFydC0xKS8oKnN0ZXApKzE7CisgICAgfQorCisgICAgcmV0dXJuIDA7Cit9CisKK3N0YXRpYyBQeU9iamVjdCAqCitzbGljZV9uZXcoUHlUeXBlT2JqZWN0ICp0eXBlLCBQeU9iamVjdCAqYXJncywgUHlPYmplY3QgKmt3KQoreworICAgIFB5T2JqZWN0ICpzdGFydCwgKnN0b3AsICpzdGVwOworCisgICAgc3RhcnQgPSBzdG9wID0gc3RlcCA9IE5VTEw7CisKKyAgICBpZiAoIV9QeUFyZ19Ob0tleXdvcmRzKCJzbGljZSgpIiwga3cpKQorICAgICAgICByZXR1cm4gTlVMTDsKKworICAgIGlmICghUHlBcmdfVW5wYWNrVHVwbGUoYXJncywgInNsaWNlIiwgMSwgMywgJnN0YXJ0LCAmc3RvcCwgJnN0ZXApKQorICAgICAgICByZXR1cm4gTlVMTDsKKworICAgIC8qIFRoaXMgc3dhcHBpbmcgb2Ygc3RvcCBhbmQgc3RhcnQgaXMgdG8gbWFpbnRhaW4gc2ltaWxhcml0eSB3aXRoCisgICAgICAgcmFuZ2UoKS4gKi8KKyAgICBpZiAoc3RvcCA9PSBOVUxMKSB7CisgICAgICAgIHN0b3AgPSBzdGFydDsKKyAgICAgICAgc3RhcnQgPSBOVUxMOworICAgIH0KKyAgICByZXR1cm4gUHlTbGljZV9OZXcoc3RhcnQsIHN0b3AsIHN0ZXApOworfQorCitQeURvY19TVFJWQVIoc2xpY2VfZG9jLAorInNsaWNlKHN0b3ApXG5cCitzbGljZShzdGFydCwgc3RvcFssIHN0ZXBdKVxuXAorXG5cCitDcmVhdGUgYSBzbGljZSBvYmplY3QuICBUaGlzIGlzIHVzZWQgZm9yIGV4dGVuZGVkIHNsaWNpbmcgKGUuZy4gYVswOjEwOjJdKS4iKTsKKworc3RhdGljIHZvaWQKK3NsaWNlX2RlYWxsb2MoUHlTbGljZU9iamVjdCAqcikKK3sKKyAgICBQeV9ERUNSRUYoci0+c3RlcCk7CisgICAgUHlfREVDUkVGKHItPnN0YXJ0KTsKKyAgICBQeV9ERUNSRUYoci0+c3RvcCk7CisgICAgUHlPYmplY3RfRGVsKHIpOworfQorCitzdGF0aWMgUHlPYmplY3QgKgorc2xpY2VfcmVwcihQeVNsaWNlT2JqZWN0ICpyKQoreworICAgIFB5T2JqZWN0ICpzLCAqY29tbWE7CisKKyAgICBzID0gUHlTdHJpbmdfRnJvbVN0cmluZygic2xpY2UoIik7CisgICAgY29tbWEgPSBQeVN0cmluZ19Gcm9tU3RyaW5nKCIsICIpOworICAgIFB5U3RyaW5nX0NvbmNhdEFuZERlbCgmcywgUHlPYmplY3RfUmVwcihyLT5zdGFydCkpOworICAgIFB5U3RyaW5nX0NvbmNhdCgmcywgY29tbWEpOworICAgIFB5U3RyaW5nX0NvbmNhdEFuZERlbCgmcywgUHlPYmplY3RfUmVwcihyLT5zdG9wKSk7CisgICAgUHlTdHJpbmdfQ29uY2F0KCZzLCBjb21tYSk7CisgICAgUHlTdHJpbmdfQ29uY2F0QW5kRGVsKCZzLCBQeU9iamVjdF9SZXByKHItPnN0ZXApKTsKKyAgICBQeVN0cmluZ19Db25jYXRBbmREZWwoJnMsIFB5U3RyaW5nX0Zyb21TdHJpbmcoIikiKSk7CisgICAgUHlfREVDUkVGKGNvbW1hKTsKKyAgICByZXR1cm4gczsKK30KKworc3RhdGljIFB5TWVtYmVyRGVmIHNsaWNlX21lbWJlcnNbXSA9IHsKKyAgICB7InN0YXJ0IiwgVF9PQkpFQ1QsIG9mZnNldG9mKFB5U2xpY2VPYmplY3QsIHN0YXJ0KSwgUkVBRE9OTFl9LAorICAgIHsic3RvcCIsIFRfT0JKRUNULCBvZmZzZXRvZihQeVNsaWNlT2JqZWN0LCBzdG9wKSwgUkVBRE9OTFl9LAorICAgIHsic3RlcCIsIFRfT0JKRUNULCBvZmZzZXRvZihQeVNsaWNlT2JqZWN0LCBzdGVwKSwgUkVBRE9OTFl9LAorICAgIHswfQorfTsKKworc3RhdGljIFB5T2JqZWN0Kgorc2xpY2VfaW5kaWNlcyhQeVNsaWNlT2JqZWN0KiBzZWxmLCBQeU9iamVjdCogbGVuKQoreworICAgIFB5X3NzaXplX3QgaWxlbiwgc3RhcnQsIHN0b3AsIHN0ZXAsIHNsaWNlbGVuZ3RoOworCisgICAgaWxlbiA9IFB5TnVtYmVyX0FzU3NpemVfdChsZW4sIFB5RXhjX092ZXJmbG93RXJyb3IpOworCisgICAgaWYgKGlsZW4gPT0gLTEgJiYgUHlFcnJfT2NjdXJyZWQoKSkgeworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisKKyAgICBpZiAoUHlTbGljZV9HZXRJbmRpY2VzRXgoc2VsZiwgaWxlbiwgJnN0YXJ0LCAmc3RvcCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnN0ZXAsICZzbGljZWxlbmd0aCkgPCAwKSB7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKworICAgIHJldHVybiBQeV9CdWlsZFZhbHVlKCIobm5uKSIsIHN0YXJ0LCBzdG9wLCBzdGVwKTsKK30KKworUHlEb2NfU1RSVkFSKHNsaWNlX2luZGljZXNfZG9jLAorIlMuaW5kaWNlcyhsZW4pIC0+IChzdGFydCwgc3RvcCwgc3RyaWRlKVxuXAorXG5cCitBc3N1bWluZyBhIHNlcXVlbmNlIG9mIGxlbmd0aCBsZW4sIGNhbGN1bGF0ZSB0aGUgc3RhcnQgYW5kIHN0b3BcblwKK2luZGljZXMsIGFuZCB0aGUgc3RyaWRlIGxlbmd0aCBvZiB0aGUgZXh0ZW5kZWQgc2xpY2UgZGVzY3JpYmVkIGJ5XG5cCitTLiBPdXQgb2YgYm91bmRzIGluZGljZXMgYXJlIGNsaXBwZWQgaW4gYSBtYW5uZXIgY29uc2lzdGVudCB3aXRoIHRoZVxuXAoraGFuZGxpbmcgb2Ygbm9ybWFsIHNsaWNlcy4iKTsKKworc3RhdGljIFB5T2JqZWN0ICoKK3NsaWNlX3JlZHVjZShQeVNsaWNlT2JqZWN0KiBzZWxmKQoreworICAgIHJldHVybiBQeV9CdWlsZFZhbHVlKCJPKE9PTykiLCBQeV9UWVBFKHNlbGYpLCBzZWxmLT5zdGFydCwgc2VsZi0+c3RvcCwgc2VsZi0+c3RlcCk7Cit9CisKK1B5RG9jX1NUUlZBUihyZWR1Y2VfZG9jLCAiUmV0dXJuIHN0YXRlIGluZm9ybWF0aW9uIGZvciBwaWNrbGluZy4iKTsKKworc3RhdGljIFB5TWV0aG9kRGVmIHNsaWNlX21ldGhvZHNbXSA9IHsKKyAgICB7ImluZGljZXMiLCAgICAgICAgIChQeUNGdW5jdGlvbilzbGljZV9pbmRpY2VzLAorICAgICBNRVRIX08sICAgICAgICAgICAgc2xpY2VfaW5kaWNlc19kb2N9LAorICAgIHsiX19yZWR1Y2VfXyIsICAgICAgKFB5Q0Z1bmN0aW9uKXNsaWNlX3JlZHVjZSwKKyAgICAgTUVUSF9OT0FSR1MsICAgICAgIHJlZHVjZV9kb2N9LAorICAgIHtOVUxMLCBOVUxMfQorfTsKKworc3RhdGljIGludAorc2xpY2VfY29tcGFyZShQeVNsaWNlT2JqZWN0ICp2LCBQeVNsaWNlT2JqZWN0ICp3KQoreworICAgIGludCByZXN1bHQgPSAwOworCisgICAgaWYgKHYgPT0gdykKKyAgICAgICAgcmV0dXJuIDA7CisKKyAgICBpZiAoUHlPYmplY3RfQ21wKHYtPnN0YXJ0LCB3LT5zdGFydCwgJnJlc3VsdCkgPCAwKQorICAgICAgICByZXR1cm4gLTI7CisgICAgaWYgKHJlc3VsdCAhPSAwKQorICAgICAgICByZXR1cm4gcmVzdWx0OworICAgIGlmIChQeU9iamVjdF9DbXAodi0+c3RvcCwgdy0+c3RvcCwgJnJlc3VsdCkgPCAwKQorICAgICAgICByZXR1cm4gLTI7CisgICAgaWYgKHJlc3VsdCAhPSAwKQorICAgICAgICByZXR1cm4gcmVzdWx0OworICAgIGlmIChQeU9iamVjdF9DbXAodi0+c3RlcCwgdy0+c3RlcCwgJnJlc3VsdCkgPCAwKQorICAgICAgICByZXR1cm4gLTI7CisgICAgcmV0dXJuIHJlc3VsdDsKK30KKworc3RhdGljIGxvbmcKK3NsaWNlX2hhc2goUHlTbGljZU9iamVjdCAqdikKK3sKKyAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfVHlwZUVycm9yLCAidW5oYXNoYWJsZSB0eXBlIik7CisgICAgcmV0dXJuIC0xTDsKK30KKworUHlUeXBlT2JqZWN0IFB5U2xpY2VfVHlwZSA9IHsKKyAgICBQeVZhck9iamVjdF9IRUFEX0lOSVQoJlB5VHlwZV9UeXBlLCAwKQorICAgICJzbGljZSIsICAgICAgICAgICAgICAgICAgICAvKiBOYW1lIG9mIHRoaXMgdHlwZSAqLworICAgIHNpemVvZihQeVNsaWNlT2JqZWN0KSwgICAgICAvKiBCYXNpYyBvYmplY3Qgc2l6ZSAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBJdGVtIHNpemUgZm9yIHZhcm9iamVjdCAqLworICAgIChkZXN0cnVjdG9yKXNsaWNlX2RlYWxsb2MsICAgICAgICAgICAgICAgICAgLyogdHBfZGVhbGxvYyAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfcHJpbnQgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2dldGF0dHIgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3NldGF0dHIgKi8KKyAgICAoY21wZnVuYylzbGljZV9jb21wYXJlLCAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2NvbXBhcmUgKi8KKyAgICAocmVwcmZ1bmMpc2xpY2VfcmVwciwgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3JlcHIgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2FzX251bWJlciAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfYXNfc2VxdWVuY2UgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2FzX21hcHBpbmcgKi8KKyAgICAoaGFzaGZ1bmMpc2xpY2VfaGFzaCwgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2hhc2ggKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2NhbGwgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3N0ciAqLworICAgIFB5T2JqZWN0X0dlbmVyaWNHZXRBdHRyLCAgICAgICAgICAgICAgICAgICAgLyogdHBfZ2V0YXR0cm8gKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3NldGF0dHJvICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9hc19idWZmZXIgKi8KKyAgICBQeV9UUEZMQUdTX0RFRkFVTFQsICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2ZsYWdzICovCisgICAgc2xpY2VfZG9jLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9kb2MgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3RyYXZlcnNlICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9jbGVhciAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfcmljaGNvbXBhcmUgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3dlYWtsaXN0b2Zmc2V0ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9pdGVyICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9pdGVybmV4dCAqLworICAgIHNsaWNlX21ldGhvZHMsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfbWV0aG9kcyAqLworICAgIHNsaWNlX21lbWJlcnMsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfbWVtYmVycyAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZ2V0c2V0ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9iYXNlICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9kaWN0ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9kZXNjcl9nZXQgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2Rlc2NyX3NldCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZGljdG9mZnNldCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfaW5pdCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfYWxsb2MgKi8KKyAgICBzbGljZV9uZXcsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX25ldyAqLworfTsKZGlmZiAtLWdpdCBhL1B5dGhvbi0yLjcuNS9PYmplY3RzL3N0cmluZ2xpYi9SRUFETUUudHh0IGIvUHl0aG9uLTIuNy41L09iamVjdHMvc3RyaW5nbGliL1JFQURNRS50eHQKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYWI1MDZkNgotLS0gL2Rldi9udWxsCisrKyBiL1B5dGhvbi0yLjcuNS9PYmplY3RzL3N0cmluZ2xpYi9SRUFETUUudHh0CkBAIC0wLDAgKzEsNDAgQEAKK2JpdHMgc2hhcmVkIGJ5IHRoZSBzdHJpbmdvYmplY3QgYW5kIHVuaWNvZGVvYmplY3QgaW1wbGVtZW50YXRpb25zIChhbmQKK3Bvc3NpYmx5IG90aGVyIG1vZHVsZXMsIGluIGEgbm90IHRvbyBkaXN0YW50IGZ1dHVyZSkuCisKK3RoZSBzdHVmZiBpbiBoZXJlIGlzIGluY2x1ZGVkIGludG8gcmVsZXZhbnQgcGxhY2VzOyBzZWUgdGhlIGluZGl2aWR1YWwKK3NvdXJjZSBmaWxlcyBmb3IgZGV0YWlscy4KKworLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KK3RoZSBmb2xsb3dpbmcgZGVmaW5lcyB1c2VkIGJ5IHRoZSBkaWZmZXJlbnQgbW9kdWxlczoKKworU1RSSU5HTElCX0NIQVIKKworICAgIHRoZSB0eXBlIHVzZWQgdG8gaG9sZCBhIGNoYXJhY3RlciAoY2hhciBvciBQeV9VTklDT0RFKQorCitTVFJJTkdMSUJfRU1QVFkKKworICAgIGEgUHlPYmplY3QgcmVwcmVzZW50aW5nIHRoZSBlbXB0eSBzdHJpbmcsIG9ubHkgdG8gYmUgdXNlZCBpZgorICAgIFNUUklOR0xJQl9NVVRBQkxFIGlzIDAKKworUHlfc3NpemVfdCBTVFJJTkdMSUJfTEVOKFB5T2JqZWN0KikKKworICAgIHJldHVybnMgdGhlIGxlbmd0aCBvZiB0aGUgZ2l2ZW4gc3RyaW5nIG9iamVjdCAod2hpY2ggbXVzdCBiZSBvZiB0aGUKKyAgICByaWdodCB0eXBlKQorCitQeU9iamVjdCogU1RSSU5HTElCX05FVyhTVFJJTkdMSUJfQ0hBUiosIFB5X3NzaXplX3QpCisKKyAgICBjcmVhdGVzIGEgbmV3IHN0cmluZyBvYmplY3QKKworU1RSSU5HTElCX0NIQVIqIFNUUklOR0xJQl9TVFIoUHlPYmplY3QqKQorCisgICAgcmV0dXJucyB0aGUgcG9pbnRlciB0byB0aGUgY2hhcmFjdGVyIGRhdGEgZm9yIHRoZSBnaXZlbiBzdHJpbmcKKyAgICBvYmplY3QgKHdoaWNoIG11c3QgYmUgb2YgdGhlIHJpZ2h0IHR5cGUpCisKK2ludCBTVFJJTkdMSUJfQ0hFQ0tfRVhBQ1QoUHlPYmplY3QgKikKKworICAgIHJldHVybnMgdHJ1ZSBpZiB0aGUgb2JqZWN0IGlzIGFuIGluc3RhbmNlIG9mIG91ciB0eXBlLCBub3QgYSBzdWJjbGFzcworCitTVFJJTkdMSUJfTVVUQUJMRQorCisgICAgbXVzdCBiZSAwIG9yIDEgdG8gdGVsbCB0aGUgY3BwIG1hY3JvcyBpbiBzdHJpbmdsaWIgY29kZSBpZiB0aGUgb2JqZWN0CisgICAgYmVpbmcgb3BlcmF0ZWQgb24gaXMgbXV0YWJsZSBvciBub3QKZGlmZiAtLWdpdCBhL1B5dGhvbi0yLjcuNS9PYmplY3RzL3N0cmluZ2xpYi9jb3VudC5oIGIvUHl0aG9uLTIuNy41L09iamVjdHMvc3RyaW5nbGliL2NvdW50LmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZGUzNGY5NgotLS0gL2Rldi9udWxsCisrKyBiL1B5dGhvbi0yLjcuNS9PYmplY3RzL3N0cmluZ2xpYi9jb3VudC5oCkBAIC0wLDAgKzEsMzAgQEAKKy8qIHN0cmluZ2xpYjogY291bnQgaW1wbGVtZW50YXRpb24gKi8KKworI2lmbmRlZiBTVFJJTkdMSUJfQ09VTlRfSAorI2RlZmluZSBTVFJJTkdMSUJfQ09VTlRfSAorCisjaWZuZGVmIFNUUklOR0xJQl9GQVNUU0VBUkNIX0gKKyNlcnJvciBtdXN0IGluY2x1ZGUgInN0cmluZ2xpYi9mYXN0c2VhcmNoLmgiIGJlZm9yZSBpbmNsdWRpbmcgdGhpcyBtb2R1bGUKKyNlbmRpZgorCitQeV9MT0NBTF9JTkxJTkUoUHlfc3NpemVfdCkKK3N0cmluZ2xpYl9jb3VudChjb25zdCBTVFJJTkdMSUJfQ0hBUiogc3RyLCBQeV9zc2l6ZV90IHN0cl9sZW4sCisgICAgICAgICAgICAgICAgY29uc3QgU1RSSU5HTElCX0NIQVIqIHN1YiwgUHlfc3NpemVfdCBzdWJfbGVuLAorICAgICAgICAgICAgICAgIFB5X3NzaXplX3QgbWF4Y291bnQpCit7CisgICAgUHlfc3NpemVfdCBjb3VudDsKKworICAgIGlmIChzdHJfbGVuIDwgMCkKKyAgICAgICAgcmV0dXJuIDA7IC8qIHN0YXJ0ID4gbGVuKHN0cikgKi8KKyAgICBpZiAoc3ViX2xlbiA9PSAwKQorICAgICAgICByZXR1cm4gKHN0cl9sZW4gPCBtYXhjb3VudCkgPyBzdHJfbGVuICsgMSA6IG1heGNvdW50OworCisgICAgY291bnQgPSBmYXN0c2VhcmNoKHN0ciwgc3RyX2xlbiwgc3ViLCBzdWJfbGVuLCBtYXhjb3VudCwgRkFTVF9DT1VOVCk7CisKKyAgICBpZiAoY291bnQgPCAwKQorICAgICAgICByZXR1cm4gMDsgLyogbm8gbWF0Y2ggKi8KKworICAgIHJldHVybiBjb3VudDsKK30KKworI2VuZGlmCmRpZmYgLS1naXQgYS9QeXRob24tMi43LjUvT2JqZWN0cy9zdHJpbmdsaWIvY3R5cGUuaCBiL1B5dGhvbi0yLjcuNS9PYmplY3RzL3N0cmluZ2xpYi9jdHlwZS5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjczOWNmM2QKLS0tIC9kZXYvbnVsbAorKysgYi9QeXRob24tMi43LjUvT2JqZWN0cy9zdHJpbmdsaWIvY3R5cGUuaApAQCAtMCwwICsxLDEwOSBAQAorLyogTk9URTogdGhpcyBBUEkgaXMgLU9OTFktIGZvciB1c2Ugd2l0aCBzaW5nbGUgYnl0ZSBjaGFyYWN0ZXIgc3RyaW5ncy4gKi8KKy8qIERvIG5vdCB1c2UgaXQgd2l0aCBVbmljb2RlLiAqLworCisjaW5jbHVkZSAiYnl0ZXNfbWV0aG9kcy5oIgorCitzdGF0aWMgUHlPYmplY3QqCitzdHJpbmdsaWJfaXNzcGFjZShQeU9iamVjdCAqc2VsZikKK3sKKyAgICByZXR1cm4gX1B5X2J5dGVzX2lzc3BhY2UoU1RSSU5HTElCX1NUUihzZWxmKSwgU1RSSU5HTElCX0xFTihzZWxmKSk7Cit9CisKK3N0YXRpYyBQeU9iamVjdCoKK3N0cmluZ2xpYl9pc2FscGhhKFB5T2JqZWN0ICpzZWxmKQoreworICAgIHJldHVybiBfUHlfYnl0ZXNfaXNhbHBoYShTVFJJTkdMSUJfU1RSKHNlbGYpLCBTVFJJTkdMSUJfTEVOKHNlbGYpKTsKK30KKworc3RhdGljIFB5T2JqZWN0Kgorc3RyaW5nbGliX2lzYWxudW0oUHlPYmplY3QgKnNlbGYpCit7CisgICAgcmV0dXJuIF9QeV9ieXRlc19pc2FsbnVtKFNUUklOR0xJQl9TVFIoc2VsZiksIFNUUklOR0xJQl9MRU4oc2VsZikpOworfQorCitzdGF0aWMgUHlPYmplY3QqCitzdHJpbmdsaWJfaXNkaWdpdChQeU9iamVjdCAqc2VsZikKK3sKKyAgICByZXR1cm4gX1B5X2J5dGVzX2lzZGlnaXQoU1RSSU5HTElCX1NUUihzZWxmKSwgU1RSSU5HTElCX0xFTihzZWxmKSk7Cit9CisKK3N0YXRpYyBQeU9iamVjdCoKK3N0cmluZ2xpYl9pc2xvd2VyKFB5T2JqZWN0ICpzZWxmKQoreworICAgIHJldHVybiBfUHlfYnl0ZXNfaXNsb3dlcihTVFJJTkdMSUJfU1RSKHNlbGYpLCBTVFJJTkdMSUJfTEVOKHNlbGYpKTsKK30KKworc3RhdGljIFB5T2JqZWN0Kgorc3RyaW5nbGliX2lzdXBwZXIoUHlPYmplY3QgKnNlbGYpCit7CisgICAgcmV0dXJuIF9QeV9ieXRlc19pc3VwcGVyKFNUUklOR0xJQl9TVFIoc2VsZiksIFNUUklOR0xJQl9MRU4oc2VsZikpOworfQorCitzdGF0aWMgUHlPYmplY3QqCitzdHJpbmdsaWJfaXN0aXRsZShQeU9iamVjdCAqc2VsZikKK3sKKyAgICByZXR1cm4gX1B5X2J5dGVzX2lzdGl0bGUoU1RSSU5HTElCX1NUUihzZWxmKSwgU1RSSU5HTElCX0xFTihzZWxmKSk7Cit9CisKKworLyogZnVuY3Rpb25zIHRoYXQgcmV0dXJuIGEgbmV3IG9iamVjdCBwYXJ0aWFsbHkgdHJhbnNsYXRlZCBieSBjdHlwZSBmdW5jczogKi8KKworc3RhdGljIFB5T2JqZWN0Kgorc3RyaW5nbGliX2xvd2VyKFB5T2JqZWN0ICpzZWxmKQoreworICAgIFB5T2JqZWN0KiBuZXdvYmo7CisgICAgbmV3b2JqID0gU1RSSU5HTElCX05FVyhOVUxMLCBTVFJJTkdMSUJfTEVOKHNlbGYpKTsKKyAgICBpZiAoIW5ld29iaikKKyAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgIF9QeV9ieXRlc19sb3dlcihTVFJJTkdMSUJfU1RSKG5ld29iaiksIFNUUklOR0xJQl9TVFIoc2VsZiksCisgICAgICAgICAgICAgICAgIFNUUklOR0xJQl9MRU4oc2VsZikpOworICAgIHJldHVybiBuZXdvYmo7Cit9CisKK3N0YXRpYyBQeU9iamVjdCoKK3N0cmluZ2xpYl91cHBlcihQeU9iamVjdCAqc2VsZikKK3sKKyAgICBQeU9iamVjdCogbmV3b2JqOworICAgIG5ld29iaiA9IFNUUklOR0xJQl9ORVcoTlVMTCwgU1RSSU5HTElCX0xFTihzZWxmKSk7CisgICAgaWYgKCFuZXdvYmopCisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICBfUHlfYnl0ZXNfdXBwZXIoU1RSSU5HTElCX1NUUihuZXdvYmopLCBTVFJJTkdMSUJfU1RSKHNlbGYpLAorICAgICAgICAgICAgICAgICBTVFJJTkdMSUJfTEVOKHNlbGYpKTsKKyAgICByZXR1cm4gbmV3b2JqOworfQorCitzdGF0aWMgUHlPYmplY3QqCitzdHJpbmdsaWJfdGl0bGUoUHlPYmplY3QgKnNlbGYpCit7CisgICAgUHlPYmplY3QqIG5ld29iajsKKyAgICBuZXdvYmogPSBTVFJJTkdMSUJfTkVXKE5VTEwsIFNUUklOR0xJQl9MRU4oc2VsZikpOworICAgIGlmICghbmV3b2JqKQorICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgX1B5X2J5dGVzX3RpdGxlKFNUUklOR0xJQl9TVFIobmV3b2JqKSwgU1RSSU5HTElCX1NUUihzZWxmKSwKKyAgICAgICAgICAgICAgICAgU1RSSU5HTElCX0xFTihzZWxmKSk7CisgICAgcmV0dXJuIG5ld29iajsKK30KKworc3RhdGljIFB5T2JqZWN0Kgorc3RyaW5nbGliX2NhcGl0YWxpemUoUHlPYmplY3QgKnNlbGYpCit7CisgICAgUHlPYmplY3QqIG5ld29iajsKKyAgICBuZXdvYmogPSBTVFJJTkdMSUJfTkVXKE5VTEwsIFNUUklOR0xJQl9MRU4oc2VsZikpOworICAgIGlmICghbmV3b2JqKQorICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgX1B5X2J5dGVzX2NhcGl0YWxpemUoU1RSSU5HTElCX1NUUihuZXdvYmopLCBTVFJJTkdMSUJfU1RSKHNlbGYpLAorICAgICAgICAgICAgICAgICAgICAgIFNUUklOR0xJQl9MRU4oc2VsZikpOworICAgIHJldHVybiBuZXdvYmo7Cit9CisKK3N0YXRpYyBQeU9iamVjdCoKK3N0cmluZ2xpYl9zd2FwY2FzZShQeU9iamVjdCAqc2VsZikKK3sKKyAgICBQeU9iamVjdCogbmV3b2JqOworICAgIG5ld29iaiA9IFNUUklOR0xJQl9ORVcoTlVMTCwgU1RSSU5HTElCX0xFTihzZWxmKSk7CisgICAgaWYgKCFuZXdvYmopCisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICBfUHlfYnl0ZXNfc3dhcGNhc2UoU1RSSU5HTElCX1NUUihuZXdvYmopLCBTVFJJTkdMSUJfU1RSKHNlbGYpLAorICAgICAgICAgICAgICAgICAgICBTVFJJTkdMSUJfTEVOKHNlbGYpKTsKKyAgICByZXR1cm4gbmV3b2JqOworfQpkaWZmIC0tZ2l0IGEvUHl0aG9uLTIuNy41L09iamVjdHMvc3RyaW5nbGliL2Zhc3RzZWFyY2guaCBiL1B5dGhvbi0yLjcuNS9PYmplY3RzL3N0cmluZ2xpYi9mYXN0c2VhcmNoLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZTIzMWM1OAotLS0gL2Rldi9udWxsCisrKyBiL1B5dGhvbi0yLjcuNS9PYmplY3RzL3N0cmluZ2xpYi9mYXN0c2VhcmNoLmgKQEAgLTAsMCArMSwxNjAgQEAKKy8qIHN0cmluZ2xpYjogZmFzdHNlYXJjaCBpbXBsZW1lbnRhdGlvbiAqLworCisjaWZuZGVmIFNUUklOR0xJQl9GQVNUU0VBUkNIX0gKKyNkZWZpbmUgU1RSSU5HTElCX0ZBU1RTRUFSQ0hfSAorCisvKiBmYXN0IHNlYXJjaC9jb3VudCBpbXBsZW1lbnRhdGlvbiwgYmFzZWQgb24gYSBtaXggYmV0d2VlbiBib3llci0KKyAgIG1vb3JlIGFuZCBob3JzcG9vbCwgd2l0aCBhIGZldyBtb3JlIGJlbGxzIGFuZCB3aGlzdGxlcyBvbiB0aGUgdG9wLgorICAgZm9yIHNvbWUgbW9yZSBiYWNrZ3JvdW5kLCBzZWU6IGh0dHA6Ly9lZmZib3Qub3JnL3pvbmUvc3RyaW5nbGliLmh0bSAqLworCisvKiBub3RlOiBmYXN0c2VhcmNoIG1heSBhY2Nlc3Mgc1tuXSwgd2hpY2ggaXNuJ3QgYSBwcm9ibGVtIHdoZW4gdXNpbmcKKyAgIFB5dGhvbidzIG9yZGluYXJ5IHN0cmluZyB0eXBlcywgYnV0IG1heSBjYXVzZSBwcm9ibGVtcyBpZiB5b3UncmUKKyAgIHVzaW5nIHRoaXMgY29kZSBpbiBvdGhlciBjb250ZXh0cy4gIGFsc28sIHRoZSBjb3VudCBtb2RlIHJldHVybnMgLTEKKyAgIGlmIHRoZXJlIGNhbm5vdCBwb3NzaWJsZSBiZSBhIG1hdGNoIGluIHRoZSB0YXJnZXQgc3RyaW5nLCBhbmQgMCBpZgorICAgaXQgaGFzIGFjdHVhbGx5IGNoZWNrZWQgZm9yIG1hdGNoZXMsIGJ1dCBkaWRuJ3QgZmluZCBhbnkuICBjYWxsZXJzCisgICBiZXdhcmUhICovCisKKyNkZWZpbmUgRkFTVF9DT1VOVCAwCisjZGVmaW5lIEZBU1RfU0VBUkNIIDEKKyNkZWZpbmUgRkFTVF9SU0VBUkNIIDIKKworI2lmIExPTkdfQklUID49IDEyOAorI2RlZmluZSBTVFJJTkdMSUJfQkxPT01fV0lEVEggMTI4CisjZWxpZiBMT05HX0JJVCA+PSA2NAorI2RlZmluZSBTVFJJTkdMSUJfQkxPT01fV0lEVEggNjQKKyNlbGlmIExPTkdfQklUID49IDMyCisjZGVmaW5lIFNUUklOR0xJQl9CTE9PTV9XSURUSCAzMgorI2Vsc2UKKyNlcnJvciAiTE9OR19CSVQgaXMgc21hbGxlciB0aGFuIDMyIgorI2VuZGlmCisKKyNkZWZpbmUgU1RSSU5HTElCX0JMT09NX0FERChtYXNrLCBjaCkgXAorICAgICgobWFzayB8PSAoMVVMIDw8ICgoY2gpICYgKFNUUklOR0xJQl9CTE9PTV9XSURUSCAtMSkpKSkpCisjZGVmaW5lIFNUUklOR0xJQl9CTE9PTShtYXNrLCBjaCkgICAgIFwKKyAgICAoKG1hc2sgJiAgKDFVTCA8PCAoKGNoKSAmIChTVFJJTkdMSUJfQkxPT01fV0lEVEggLTEpKSkpKQorCitQeV9MT0NBTF9JTkxJTkUoUHlfc3NpemVfdCkKK2Zhc3RzZWFyY2goY29uc3QgU1RSSU5HTElCX0NIQVIqIHMsIFB5X3NzaXplX3QgbiwKKyAgICAgICAgICAgY29uc3QgU1RSSU5HTElCX0NIQVIqIHAsIFB5X3NzaXplX3QgbSwKKyAgICAgICAgICAgUHlfc3NpemVfdCBtYXhjb3VudCwgaW50IG1vZGUpCit7CisgICAgdW5zaWduZWQgbG9uZyBtYXNrOworICAgIFB5X3NzaXplX3Qgc2tpcCwgY291bnQgPSAwOworICAgIFB5X3NzaXplX3QgaSwgaiwgbWxhc3QsIHc7CisKKyAgICB3ID0gbiAtIG07CisKKyAgICBpZiAodyA8IDAgfHwgKG1vZGUgPT0gRkFTVF9DT1VOVCAmJiBtYXhjb3VudCA9PSAwKSkKKyAgICAgICAgcmV0dXJuIC0xOworCisgICAgLyogbG9vayBmb3Igc3BlY2lhbCBjYXNlcyAqLworICAgIGlmIChtIDw9IDEpIHsKKyAgICAgICAgaWYgKG0gPD0gMCkKKyAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgLyogdXNlIHNwZWNpYWwgY2FzZSBmb3IgMS1jaGFyYWN0ZXIgc3RyaW5ncyAqLworICAgICAgICBpZiAobW9kZSA9PSBGQVNUX0NPVU5UKSB7CisgICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgbjsgaSsrKQorICAgICAgICAgICAgICAgIGlmIChzW2ldID09IHBbMF0pIHsKKyAgICAgICAgICAgICAgICAgICAgY291bnQrKzsKKyAgICAgICAgICAgICAgICAgICAgaWYgKGNvdW50ID09IG1heGNvdW50KQorICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIG1heGNvdW50OworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHJldHVybiBjb3VudDsKKyAgICAgICAgfSBlbHNlIGlmIChtb2RlID09IEZBU1RfU0VBUkNIKSB7CisgICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgbjsgaSsrKQorICAgICAgICAgICAgICAgIGlmIChzW2ldID09IHBbMF0pCisgICAgICAgICAgICAgICAgICAgIHJldHVybiBpOworICAgICAgICB9IGVsc2UgeyAgICAvKiBGQVNUX1JTRUFSQ0ggKi8KKyAgICAgICAgICAgIGZvciAoaSA9IG4gLSAxOyBpID4gLTE7IGktLSkKKyAgICAgICAgICAgICAgICBpZiAoc1tpXSA9PSBwWzBdKQorICAgICAgICAgICAgICAgICAgICByZXR1cm4gaTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gLTE7CisgICAgfQorCisgICAgbWxhc3QgPSBtIC0gMTsKKyAgICBza2lwID0gbWxhc3QgLSAxOworICAgIG1hc2sgPSAwOworCisgICAgaWYgKG1vZGUgIT0gRkFTVF9SU0VBUkNIKSB7CisKKyAgICAgICAgLyogY3JlYXRlIGNvbXByZXNzZWQgYm95ZXItbW9vcmUgZGVsdGEgMSB0YWJsZSAqLworCisgICAgICAgIC8qIHByb2Nlc3MgcGF0dGVybls6LTFdICovCisgICAgICAgIGZvciAoaSA9IDA7IGkgPCBtbGFzdDsgaSsrKSB7CisgICAgICAgICAgICBTVFJJTkdMSUJfQkxPT01fQUREKG1hc2ssIHBbaV0pOworICAgICAgICAgICAgaWYgKHBbaV0gPT0gcFttbGFzdF0pCisgICAgICAgICAgICAgICAgc2tpcCA9IG1sYXN0IC0gaSAtIDE7CisgICAgICAgIH0KKyAgICAgICAgLyogcHJvY2VzcyBwYXR0ZXJuWy0xXSBvdXRzaWRlIHRoZSBsb29wICovCisgICAgICAgIFNUUklOR0xJQl9CTE9PTV9BREQobWFzaywgcFttbGFzdF0pOworCisgICAgICAgIGZvciAoaSA9IDA7IGkgPD0gdzsgaSsrKSB7CisgICAgICAgICAgICAvKiBub3RlOiB1c2luZyBtbGFzdCBpbiB0aGUgc2tpcCBwYXRoIHNsb3dzIHRoaW5ncyBkb3duIG9uIHg4NiAqLworICAgICAgICAgICAgaWYgKHNbaSttLTFdID09IHBbbS0xXSkgeworICAgICAgICAgICAgICAgIC8qIGNhbmRpZGF0ZSBtYXRjaCAqLworICAgICAgICAgICAgICAgIGZvciAoaiA9IDA7IGogPCBtbGFzdDsgaisrKQorICAgICAgICAgICAgICAgICAgICBpZiAoc1tpK2pdICE9IHBbal0pCisgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICBpZiAoaiA9PSBtbGFzdCkgeworICAgICAgICAgICAgICAgICAgICAvKiBnb3QgYSBtYXRjaCEgKi8KKyAgICAgICAgICAgICAgICAgICAgaWYgKG1vZGUgIT0gRkFTVF9DT1VOVCkKKyAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBpOworICAgICAgICAgICAgICAgICAgICBjb3VudCsrOworICAgICAgICAgICAgICAgICAgICBpZiAoY291bnQgPT0gbWF4Y291bnQpCisgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbWF4Y291bnQ7CisgICAgICAgICAgICAgICAgICAgIGkgPSBpICsgbWxhc3Q7CisgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAvKiBtaXNzOiBjaGVjayBpZiBuZXh0IGNoYXJhY3RlciBpcyBwYXJ0IG9mIHBhdHRlcm4gKi8KKyAgICAgICAgICAgICAgICBpZiAoIVNUUklOR0xJQl9CTE9PTShtYXNrLCBzW2krbV0pKQorICAgICAgICAgICAgICAgICAgICBpID0gaSArIG07CisgICAgICAgICAgICAgICAgZWxzZQorICAgICAgICAgICAgICAgICAgICBpID0gaSArIHNraXA7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgIC8qIHNraXA6IGNoZWNrIGlmIG5leHQgY2hhcmFjdGVyIGlzIHBhcnQgb2YgcGF0dGVybiAqLworICAgICAgICAgICAgICAgIGlmICghU1RSSU5HTElCX0JMT09NKG1hc2ssIHNbaSttXSkpCisgICAgICAgICAgICAgICAgICAgIGkgPSBpICsgbTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0gZWxzZSB7ICAgIC8qIEZBU1RfUlNFQVJDSCAqLworCisgICAgICAgIC8qIGNyZWF0ZSBjb21wcmVzc2VkIGJveWVyLW1vb3JlIGRlbHRhIDEgdGFibGUgKi8KKworICAgICAgICAvKiBwcm9jZXNzIHBhdHRlcm5bMF0gb3V0c2lkZSB0aGUgbG9vcCAqLworICAgICAgICBTVFJJTkdMSUJfQkxPT01fQUREKG1hc2ssIHBbMF0pOworICAgICAgICAvKiBwcm9jZXNzIHBhdHRlcm5bOjA6LTFdICovCisgICAgICAgIGZvciAoaSA9IG1sYXN0OyBpID4gMDsgaS0tKSB7CisgICAgICAgICAgICBTVFJJTkdMSUJfQkxPT01fQUREKG1hc2ssIHBbaV0pOworICAgICAgICAgICAgaWYgKHBbaV0gPT0gcFswXSkKKyAgICAgICAgICAgICAgICBza2lwID0gaSAtIDE7CisgICAgICAgIH0KKworICAgICAgICBmb3IgKGkgPSB3OyBpID49IDA7IGktLSkgeworICAgICAgICAgICAgaWYgKHNbaV0gPT0gcFswXSkgeworICAgICAgICAgICAgICAgIC8qIGNhbmRpZGF0ZSBtYXRjaCAqLworICAgICAgICAgICAgICAgIGZvciAoaiA9IG1sYXN0OyBqID4gMDsgai0tKQorICAgICAgICAgICAgICAgICAgICBpZiAoc1tpK2pdICE9IHBbal0pCisgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICBpZiAoaiA9PSAwKQorICAgICAgICAgICAgICAgICAgICAvKiBnb3QgYSBtYXRjaCEgKi8KKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGk7CisgICAgICAgICAgICAgICAgLyogbWlzczogY2hlY2sgaWYgcHJldmlvdXMgY2hhcmFjdGVyIGlzIHBhcnQgb2YgcGF0dGVybiAqLworICAgICAgICAgICAgICAgIGlmIChpID4gMCAmJiAhU1RSSU5HTElCX0JMT09NKG1hc2ssIHNbaS0xXSkpCisgICAgICAgICAgICAgICAgICAgIGkgPSBpIC0gbTsKKyAgICAgICAgICAgICAgICBlbHNlCisgICAgICAgICAgICAgICAgICAgIGkgPSBpIC0gc2tpcDsKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgLyogc2tpcDogY2hlY2sgaWYgcHJldmlvdXMgY2hhcmFjdGVyIGlzIHBhcnQgb2YgcGF0dGVybiAqLworICAgICAgICAgICAgICAgIGlmIChpID4gMCAmJiAhU1RSSU5HTElCX0JMT09NKG1hc2ssIHNbaS0xXSkpCisgICAgICAgICAgICAgICAgICAgIGkgPSBpIC0gbTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKworICAgIGlmIChtb2RlICE9IEZBU1RfQ09VTlQpCisgICAgICAgIHJldHVybiAtMTsKKyAgICByZXR1cm4gY291bnQ7Cit9CisKKyNlbmRpZgpkaWZmIC0tZ2l0IGEvUHl0aG9uLTIuNy41L09iamVjdHMvc3RyaW5nbGliL2ZpbmQuaCBiL1B5dGhvbi0yLjcuNS9PYmplY3RzL3N0cmluZ2xpYi9maW5kLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uY2U2MTVkYwotLS0gL2Rldi9udWxsCisrKyBiL1B5dGhvbi0yLjcuNS9PYmplY3RzL3N0cmluZ2xpYi9maW5kLmgKQEAgLTAsMCArMSwxNzUgQEAKKy8qIHN0cmluZ2xpYjogZmluZC9pbmRleCBpbXBsZW1lbnRhdGlvbiAqLworCisjaWZuZGVmIFNUUklOR0xJQl9GSU5EX0gKKyNkZWZpbmUgU1RSSU5HTElCX0ZJTkRfSAorCisjaWZuZGVmIFNUUklOR0xJQl9GQVNUU0VBUkNIX0gKKyNlcnJvciBtdXN0IGluY2x1ZGUgInN0cmluZ2xpYi9mYXN0c2VhcmNoLmgiIGJlZm9yZSBpbmNsdWRpbmcgdGhpcyBtb2R1bGUKKyNlbmRpZgorCitQeV9MT0NBTF9JTkxJTkUoUHlfc3NpemVfdCkKK3N0cmluZ2xpYl9maW5kKGNvbnN0IFNUUklOR0xJQl9DSEFSKiBzdHIsIFB5X3NzaXplX3Qgc3RyX2xlbiwKKyAgICAgICAgICAgICAgIGNvbnN0IFNUUklOR0xJQl9DSEFSKiBzdWIsIFB5X3NzaXplX3Qgc3ViX2xlbiwKKyAgICAgICAgICAgICAgIFB5X3NzaXplX3Qgb2Zmc2V0KQoreworICAgIFB5X3NzaXplX3QgcG9zOworCisgICAgaWYgKHN0cl9sZW4gPCAwKQorICAgICAgICByZXR1cm4gLTE7CisgICAgaWYgKHN1Yl9sZW4gPT0gMCkKKyAgICAgICAgcmV0dXJuIG9mZnNldDsKKworICAgIHBvcyA9IGZhc3RzZWFyY2goc3RyLCBzdHJfbGVuLCBzdWIsIHN1Yl9sZW4sIC0xLCBGQVNUX1NFQVJDSCk7CisKKyAgICBpZiAocG9zID49IDApCisgICAgICAgIHBvcyArPSBvZmZzZXQ7CisKKyAgICByZXR1cm4gcG9zOworfQorCitQeV9MT0NBTF9JTkxJTkUoUHlfc3NpemVfdCkKK3N0cmluZ2xpYl9yZmluZChjb25zdCBTVFJJTkdMSUJfQ0hBUiogc3RyLCBQeV9zc2l6ZV90IHN0cl9sZW4sCisgICAgICAgICAgICAgICAgY29uc3QgU1RSSU5HTElCX0NIQVIqIHN1YiwgUHlfc3NpemVfdCBzdWJfbGVuLAorICAgICAgICAgICAgICAgIFB5X3NzaXplX3Qgb2Zmc2V0KQoreworICAgIFB5X3NzaXplX3QgcG9zOworCisgICAgaWYgKHN0cl9sZW4gPCAwKQorICAgICAgICByZXR1cm4gLTE7CisgICAgaWYgKHN1Yl9sZW4gPT0gMCkKKyAgICAgICAgcmV0dXJuIHN0cl9sZW4gKyBvZmZzZXQ7CisKKyAgICBwb3MgPSBmYXN0c2VhcmNoKHN0ciwgc3RyX2xlbiwgc3ViLCBzdWJfbGVuLCAtMSwgRkFTVF9SU0VBUkNIKTsKKworICAgIGlmIChwb3MgPj0gMCkKKyAgICAgICAgcG9zICs9IG9mZnNldDsKKworICAgIHJldHVybiBwb3M7Cit9CisKKy8qIGhlbHBlciBtYWNybyB0byBmaXh1cCBzdGFydC9lbmQgc2xpY2UgdmFsdWVzICovCisjZGVmaW5lIEFESlVTVF9JTkRJQ0VTKHN0YXJ0LCBlbmQsIGxlbikgICAgICAgICBcCisgICAgaWYgKGVuZCA+IGxlbikgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgIGVuZCA9IGxlbjsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgZWxzZSBpZiAoZW5kIDwgMCkgeyAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgIGVuZCArPSBsZW47ICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgIGlmIChlbmQgPCAwKSAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgICAgICBlbmQgPSAwOyAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgfSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgaWYgKHN0YXJ0IDwgMCkgeyAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgIHN0YXJ0ICs9IGxlbjsgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgIGlmIChzdGFydCA8IDApICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgICAgICBzdGFydCA9IDA7ICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgfQorCitQeV9MT0NBTF9JTkxJTkUoUHlfc3NpemVfdCkKK3N0cmluZ2xpYl9maW5kX3NsaWNlKGNvbnN0IFNUUklOR0xJQl9DSEFSKiBzdHIsIFB5X3NzaXplX3Qgc3RyX2xlbiwKKyAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFNUUklOR0xJQl9DSEFSKiBzdWIsIFB5X3NzaXplX3Qgc3ViX2xlbiwKKyAgICAgICAgICAgICAgICAgICAgIFB5X3NzaXplX3Qgc3RhcnQsIFB5X3NzaXplX3QgZW5kKQoreworICAgIEFESlVTVF9JTkRJQ0VTKHN0YXJ0LCBlbmQsIHN0cl9sZW4pOworICAgIHJldHVybiBzdHJpbmdsaWJfZmluZChzdHIgKyBzdGFydCwgZW5kIC0gc3RhcnQsIHN1Yiwgc3ViX2xlbiwgc3RhcnQpOworfQorCitQeV9MT0NBTF9JTkxJTkUoUHlfc3NpemVfdCkKK3N0cmluZ2xpYl9yZmluZF9zbGljZShjb25zdCBTVFJJTkdMSUJfQ0hBUiogc3RyLCBQeV9zc2l6ZV90IHN0cl9sZW4sCisgICAgICAgICAgICAgICAgICAgICAgY29uc3QgU1RSSU5HTElCX0NIQVIqIHN1YiwgUHlfc3NpemVfdCBzdWJfbGVuLAorICAgICAgICAgICAgICAgICAgICAgIFB5X3NzaXplX3Qgc3RhcnQsIFB5X3NzaXplX3QgZW5kKQoreworICAgIEFESlVTVF9JTkRJQ0VTKHN0YXJ0LCBlbmQsIHN0cl9sZW4pOworICAgIHJldHVybiBzdHJpbmdsaWJfcmZpbmQoc3RyICsgc3RhcnQsIGVuZCAtIHN0YXJ0LCBzdWIsIHN1Yl9sZW4sIHN0YXJ0KTsKK30KKworI2lmZGVmIFNUUklOR0xJQl9XQU5UX0NPTlRBSU5TX09CSgorCitQeV9MT0NBTF9JTkxJTkUoaW50KQorc3RyaW5nbGliX2NvbnRhaW5zX29iaihQeU9iamVjdCogc3RyLCBQeU9iamVjdCogc3ViKQoreworICAgIHJldHVybiBzdHJpbmdsaWJfZmluZCgKKyAgICAgICAgU1RSSU5HTElCX1NUUihzdHIpLCBTVFJJTkdMSUJfTEVOKHN0ciksCisgICAgICAgIFNUUklOR0xJQl9TVFIoc3ViKSwgU1RSSU5HTElCX0xFTihzdWIpLCAwCisgICAgICAgICkgIT0gLTE7Cit9CisKKyNlbmRpZiAvKiBTVFJJTkdMSUJfV0FOVF9DT05UQUlOU19PQkogKi8KKworLyoKK1RoaXMgZnVuY3Rpb24gaXMgYSBoZWxwZXIgZm9yIHRoZSAiZmluZCIgZmFtaWx5IChmaW5kLCByZmluZCwgaW5kZXgsCityaW5kZXgpIGFuZCBmb3IgY291bnQsIHN0YXJ0c3dpdGggYW5kIGVuZHN3aXRoLCBiZWNhdXNlIHRoZXkgYWxsIGhhdmUKK3RoZSBzYW1lIGJlaGF2aW91ciBmb3IgdGhlIGFyZ3VtZW50cy4KKworSXQgZG9lcyBub3QgdG91Y2ggdGhlIHZhcmlhYmxlcyByZWNlaXZlZCB1bnRpbCBpdCBrbm93cyBldmVyeXRoaW5nIAoraXMgb2suCisqLworCisjZGVmaW5lIEZPUk1BVF9CVUZGRVJfU0laRSA1MAorCitQeV9MT0NBTF9JTkxJTkUoaW50KQorc3RyaW5nbGliX3BhcnNlX2FyZ3NfZmluZHMoY29uc3QgY2hhciAqIGZ1bmN0aW9uX25hbWUsIFB5T2JqZWN0ICphcmdzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgUHlPYmplY3QgKipzdWJvYmosCisgICAgICAgICAgICAgICAgICAgICAgICAgICBQeV9zc2l6ZV90ICpzdGFydCwgUHlfc3NpemVfdCAqZW5kKQoreworICAgIFB5T2JqZWN0ICp0bXBfc3Vib2JqOworICAgIFB5X3NzaXplX3QgdG1wX3N0YXJ0ID0gMDsKKyAgICBQeV9zc2l6ZV90IHRtcF9lbmQgPSBQWV9TU0laRV9UX01BWDsKKyAgICBQeU9iamVjdCAqb2JqX3N0YXJ0PVB5X05vbmUsICpvYmpfZW5kPVB5X05vbmU7CisgICAgY2hhciBmb3JtYXRbRk9STUFUX0JVRkZFUl9TSVpFXSA9ICJPfE9POiI7CisgICAgc2l6ZV90IGxlbiA9IHN0cmxlbihmb3JtYXQpOworCisgICAgc3RybmNweShmb3JtYXQgKyBsZW4sIGZ1bmN0aW9uX25hbWUsIEZPUk1BVF9CVUZGRVJfU0laRSAtIGxlbiAtIDEpOworICAgIGZvcm1hdFtGT1JNQVRfQlVGRkVSX1NJWkUgLSAxXSA9ICdcMCc7CisKKyAgICBpZiAoIVB5QXJnX1BhcnNlVHVwbGUoYXJncywgZm9ybWF0LCAmdG1wX3N1Ym9iaiwgJm9ial9zdGFydCwgJm9ial9lbmQpKQorICAgICAgICByZXR1cm4gMDsKKworICAgIC8qIFRvIHN1cHBvcnQgTm9uZSBpbiAic3RhcnQiIGFuZCAiZW5kIiBhcmd1bWVudHMsIG1lYW5pbmcKKyAgICAgICB0aGUgc2FtZSBhcyBpZiB0aGV5IHdlcmUgbm90IHBhc3NlZC4KKyAgICAqLworICAgIGlmIChvYmpfc3RhcnQgIT0gUHlfTm9uZSkKKyAgICAgICAgaWYgKCFfUHlFdmFsX1NsaWNlSW5kZXgob2JqX3N0YXJ0LCAmdG1wX3N0YXJ0KSkKKyAgICAgICAgICAgIHJldHVybiAwOworICAgIGlmIChvYmpfZW5kICE9IFB5X05vbmUpCisgICAgICAgIGlmICghX1B5RXZhbF9TbGljZUluZGV4KG9ial9lbmQsICZ0bXBfZW5kKSkKKyAgICAgICAgICAgIHJldHVybiAwOworCisgICAgKnN0YXJ0ID0gdG1wX3N0YXJ0OworICAgICplbmQgPSB0bXBfZW5kOworICAgICpzdWJvYmogPSB0bXBfc3Vib2JqOworICAgIHJldHVybiAxOworfQorCisjdW5kZWYgRk9STUFUX0JVRkZFUl9TSVpFCisKKyNpZiBTVFJJTkdMSUJfSVNfVU5JQ09ERQorCisvKgorV3JhcHMgc3RyaW5nbGliX3BhcnNlX2FyZ3NfZmluZHMoKSBhbmQgYWRkaXRpb25hbGx5IGVuc3VyZXMgdGhhdCB0aGUKK2ZpcnN0IGFyZ3VtZW50IGlzIGEgdW5pY29kZSBvYmplY3QuCisKK05vdGUgdGhhdCB3ZSByZWNlaXZlIGEgcG9pbnRlciB0byB0aGUgcG9pbnRlciBvZiB0aGUgc3Vic3RyaW5nIG9iamVjdCwKK3NvIHdoZW4gd2UgY3JlYXRlIHRoYXQgb2JqZWN0IGluIHRoaXMgZnVuY3Rpb24gd2UgZG9uJ3QgREVDUkVGIGl0LAorYmVjYXVzZSBpdCBjb250aW51ZXMgbGl2aW5nIGluIHRoZSBjYWxsZXIgZnVuY3Rpb25zICh0aG9zZSBmdW5jdGlvbnMsIAorYWZ0ZXIgZmluaXNoaW5nIHVzaW5nIHRoZSBzdWJzdHJpbmcsIG11c3QgREVDUkVGIGl0KS4KKyovCisKK1B5X0xPQ0FMX0lOTElORShpbnQpCitzdHJpbmdsaWJfcGFyc2VfYXJnc19maW5kc191bmljb2RlKGNvbnN0IGNoYXIgKiBmdW5jdGlvbl9uYW1lLCBQeU9iamVjdCAqYXJncywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHlVbmljb2RlT2JqZWN0ICoqc3Vic3RyaW5nLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQeV9zc2l6ZV90ICpzdGFydCwgUHlfc3NpemVfdCAqZW5kKQoreworICAgIFB5T2JqZWN0ICp0bXBfc3Vic3RyaW5nOworCisgICAgaWYoc3RyaW5nbGliX3BhcnNlX2FyZ3NfZmluZHMoZnVuY3Rpb25fbmFtZSwgYXJncywgJnRtcF9zdWJzdHJpbmcsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhcnQsIGVuZCkpIHsKKyAgICAgICAgdG1wX3N1YnN0cmluZyA9IFB5VW5pY29kZV9Gcm9tT2JqZWN0KHRtcF9zdWJzdHJpbmcpOworICAgICAgICBpZiAoIXRtcF9zdWJzdHJpbmcpCisgICAgICAgICAgICByZXR1cm4gMDsKKyAgICAgICAgKnN1YnN0cmluZyA9IChQeVVuaWNvZGVPYmplY3QgKil0bXBfc3Vic3RyaW5nOworICAgICAgICByZXR1cm4gMTsKKyAgICB9CisgICAgcmV0dXJuIDA7Cit9CisKKyNlbmRpZiAvKiBTVFJJTkdMSUJfSVNfVU5JQ09ERSAqLworCisjZW5kaWYgLyogU1RSSU5HTElCX0ZJTkRfSCAqLwpkaWZmIC0tZ2l0IGEvUHl0aG9uLTIuNy41L09iamVjdHMvc3RyaW5nbGliL2Zvcm1hdHRlci5oIGIvUHl0aG9uLTIuNy41L09iamVjdHMvc3RyaW5nbGliL2Zvcm1hdHRlci5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjZiMjgyMjQKLS0tIC9kZXYvbnVsbAorKysgYi9QeXRob24tMi43LjUvT2JqZWN0cy9zdHJpbmdsaWIvZm9ybWF0dGVyLmgKQEAgLTAsMCArMSwxNTI5IEBACisvKiBpbXBsZW1lbnRzIHRoZSBzdHJpbmcsIGxvbmcsIGFuZCBmbG9hdCBmb3JtYXR0ZXJzLiAgdGhhdCBpcywKKyAgIHN0cmluZy5fX2Zvcm1hdF9fLCBldGMuICovCisKKyNpbmNsdWRlIDxsb2NhbGUuaD4KKworLyogQmVmb3JlIGluY2x1ZGluZyB0aGlzLCB5b3UgbXVzdCBpbmNsdWRlIGVpdGhlcjoKKyAgIHN0cmluZ2xpYi91bmljb2RlZGVmcy5oCisgICBzdHJpbmdsaWIvc3RyaW5nZGVmcy5oCisKKyAgIEFsc28sIHlvdSBzaG91bGQgZGVmaW5lIHRoZSBuYW1lczoKKyAgIEZPUk1BVF9TVFJJTkcKKyAgIEZPUk1BVF9MT05HCisgICBGT1JNQVRfRkxPQVQKKyAgIEZPUk1BVF9DT01QTEVYCisgICB0byBiZSB3aGF0ZXZlciB5b3Ugd2FudCB0aGUgcHVibGljIG5hbWVzIG9mIHRoZXNlIGZ1bmN0aW9ucyB0bworICAgYmUuICBUaGVzZSBhcmUgdGhlIG9ubHkgbm9uLXN0YXRpYyBmdW5jdGlvbnMgZGVmaW5lZCBoZXJlLgorKi8KKworLyogUmFpc2VzIGFuIGV4Y2VwdGlvbiBhYm91dCBhbiB1bmtub3duIHByZXNlbnRhdGlvbiB0eXBlIGZvciB0aGlzCisgKiB0eXBlLiAqLworCitzdGF0aWMgdm9pZAordW5rbm93bl9wcmVzZW50YXRpb25fdHlwZShTVFJJTkdMSUJfQ0hBUiBwcmVzZW50YXRpb25fdHlwZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciogdHlwZV9uYW1lKQoreworI2lmIFNUUklOR0xJQl9JU19VTklDT0RFCisgICAgLyogSWYgU1RSSU5HTElCX0NIQVIgaXMgUHlfVU5JQ09ERSwgJWMgbWlnaHQgYmUgb3V0LW9mLXJhbmdlLAorICAgICAgIGhlbmNlIHRoZSB0d28gY2FzZXMuIElmIGl0IGlzIGNoYXIsIGdjYyBjb21wbGFpbnMgdGhhdCB0aGUKKyAgICAgICBjb25kaXRpb24gYmVsb3cgaXMgYWx3YXlzIHRydWUsIGhlbmNlIHRoZSBpZmRlZi4gKi8KKyAgICBpZiAocHJlc2VudGF0aW9uX3R5cGUgPiAzMiAmJiBwcmVzZW50YXRpb25fdHlwZSA8IDEyOCkKKyNlbmRpZgorICAgICAgICBQeUVycl9Gb3JtYXQoUHlFeGNfVmFsdWVFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICJVbmtub3duIGZvcm1hdCBjb2RlICclYycgIgorICAgICAgICAgICAgICAgICAgICAgImZvciBvYmplY3Qgb2YgdHlwZSAnJS4yMDBzJyIsCisgICAgICAgICAgICAgICAgICAgICAoY2hhcilwcmVzZW50YXRpb25fdHlwZSwKKyAgICAgICAgICAgICAgICAgICAgIHR5cGVfbmFtZSk7CisjaWYgU1RSSU5HTElCX0lTX1VOSUNPREUKKyAgICBlbHNlCisgICAgICAgIFB5RXJyX0Zvcm1hdChQeUV4Y19WYWx1ZUVycm9yLAorICAgICAgICAgICAgICAgICAgICAgIlVua25vd24gZm9ybWF0IGNvZGUgJ1xceCV4JyAiCisgICAgICAgICAgICAgICAgICAgICAiZm9yIG9iamVjdCBvZiB0eXBlICclLjIwMHMnIiwKKyAgICAgICAgICAgICAgICAgICAgICh1bnNpZ25lZCBpbnQpcHJlc2VudGF0aW9uX3R5cGUsCisgICAgICAgICAgICAgICAgICAgICB0eXBlX25hbWUpOworI2VuZGlmCit9CisKK3N0YXRpYyB2b2lkCitpbnZhbGlkX2NvbW1hX3R5cGUoU1RSSU5HTElCX0NIQVIgcHJlc2VudGF0aW9uX3R5cGUpCit7CisjaWYgU1RSSU5HTElCX0lTX1VOSUNPREUKKyAgICAvKiBTZWUgY29tbWVudCBpbiB1bmtub3duX3ByZXNlbnRhdGlvbl90eXBlICovCisgICAgaWYgKHByZXNlbnRhdGlvbl90eXBlID4gMzIgJiYgcHJlc2VudGF0aW9uX3R5cGUgPCAxMjgpCisjZW5kaWYKKyAgICAgICAgUHlFcnJfRm9ybWF0KFB5RXhjX1ZhbHVlRXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAiQ2Fubm90IHNwZWNpZnkgJywnIHdpdGggJyVjJy4iLAorICAgICAgICAgICAgICAgICAgICAgKGNoYXIpcHJlc2VudGF0aW9uX3R5cGUpOworI2lmIFNUUklOR0xJQl9JU19VTklDT0RFCisgICAgZWxzZQorICAgICAgICBQeUVycl9Gb3JtYXQoUHlFeGNfVmFsdWVFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICJDYW5ub3Qgc3BlY2lmeSAnLCcgd2l0aCAnXFx4JXgnLiIsCisgICAgICAgICAgICAgICAgICAgICAodW5zaWduZWQgaW50KXByZXNlbnRhdGlvbl90eXBlKTsKKyNlbmRpZgorfQorCisvKgorICAgIGdldF9pbnRlZ2VyIGNvbnN1bWVzIDAgb3IgbW9yZSBkZWNpbWFsIGRpZ2l0IGNoYXJhY3RlcnMgZnJvbSBhbgorICAgIGlucHV0IHN0cmluZywgdXBkYXRlcyAqcmVzdWx0IHdpdGggdGhlIGNvcnJlc3BvbmRpbmcgcG9zaXRpdmUKKyAgICBpbnRlZ2VyLCBhbmQgcmV0dXJucyB0aGUgbnVtYmVyIG9mIGRpZ2l0cyBjb25zdW1lZC4KKworICAgIHJldHVybnMgLTEgb24gZXJyb3IuCisqLworc3RhdGljIGludAorZ2V0X2ludGVnZXIoU1RSSU5HTElCX0NIQVIgKipwdHIsIFNUUklOR0xJQl9DSEFSICplbmQsCisgICAgICAgICAgICAgICAgICBQeV9zc2l6ZV90ICpyZXN1bHQpCit7CisgICAgUHlfc3NpemVfdCBhY2N1bXVsYXRvciwgZGlnaXR2YWw7CisgICAgaW50IG51bWRpZ2l0czsKKyAgICBhY2N1bXVsYXRvciA9IG51bWRpZ2l0cyA9IDA7CisgICAgZm9yICg7OygqcHRyKSsrLCBudW1kaWdpdHMrKykgeworICAgICAgICBpZiAoKnB0ciA+PSBlbmQpCisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgZGlnaXR2YWwgPSBTVFJJTkdMSUJfVE9ERUNJTUFMKCoqcHRyKTsKKyAgICAgICAgaWYgKGRpZ2l0dmFsIDwgMCkKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICAvKgorICAgICAgICAgICBEZXRlY3QgcG9zc2libGUgb3ZlcmZsb3cgYmVmb3JlIGl0IGhhcHBlbnM6CisKKyAgICAgICAgICAgICAgYWNjdW11bGF0b3IgKiAxMCArIGRpZ2l0dmFsID4gUFlfU1NJWkVfVF9NQVggaWYgYW5kIG9ubHkgaWYKKyAgICAgICAgICAgICAgYWNjdW11bGF0b3IgPiAoUFlfU1NJWkVfVF9NQVggLSBkaWdpdHZhbCkgLyAxMC4KKyAgICAgICAgKi8KKyAgICAgICAgaWYgKGFjY3VtdWxhdG9yID4gKFBZX1NTSVpFX1RfTUFYIC0gZGlnaXR2YWwpIC8gMTApIHsKKyAgICAgICAgICAgIFB5RXJyX0Zvcm1hdChQeUV4Y19WYWx1ZUVycm9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICJUb28gbWFueSBkZWNpbWFsIGRpZ2l0cyBpbiBmb3JtYXQgc3RyaW5nIik7CisgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgIH0KKyAgICAgICAgYWNjdW11bGF0b3IgPSBhY2N1bXVsYXRvciAqIDEwICsgZGlnaXR2YWw7CisgICAgfQorICAgICpyZXN1bHQgPSBhY2N1bXVsYXRvcjsKKyAgICByZXR1cm4gbnVtZGlnaXRzOworfQorCisvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLworLyoqKioqKioqKioqIHN0YW5kYXJkIGZvcm1hdCBzcGVjaWZpZXIgcGFyc2luZyAqKioqKioqKioqKioqKioqKioqKioqKioqKi8KKy8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCisKKy8qIHJldHVybnMgdHJ1ZSBpZiB0aGlzIGNoYXJhY3RlciBpcyBhIHNwZWNpZmllciBhbGlnbm1lbnQgdG9rZW4gKi8KK1B5X0xPQ0FMX0lOTElORShpbnQpCitpc19hbGlnbm1lbnRfdG9rZW4oU1RSSU5HTElCX0NIQVIgYykKK3sKKyAgICBzd2l0Y2ggKGMpIHsKKyAgICBjYXNlICc8JzogY2FzZSAnPic6IGNhc2UgJz0nOiBjYXNlICdeJzoKKyAgICAgICAgcmV0dXJuIDE7CisgICAgZGVmYXVsdDoKKyAgICAgICAgcmV0dXJuIDA7CisgICAgfQorfQorCisvKiByZXR1cm5zIHRydWUgaWYgdGhpcyBjaGFyYWN0ZXIgaXMgYSBzaWduIGVsZW1lbnQgKi8KK1B5X0xPQ0FMX0lOTElORShpbnQpCitpc19zaWduX2VsZW1lbnQoU1RSSU5HTElCX0NIQVIgYykKK3sKKyAgICBzd2l0Y2ggKGMpIHsKKyAgICBjYXNlICcgJzogY2FzZSAnKyc6IGNhc2UgJy0nOgorICAgICAgICByZXR1cm4gMTsKKyAgICBkZWZhdWx0OgorICAgICAgICByZXR1cm4gMDsKKyAgICB9Cit9CisKKwordHlwZWRlZiBzdHJ1Y3QgeworICAgIFNUUklOR0xJQl9DSEFSIGZpbGxfY2hhcjsKKyAgICBTVFJJTkdMSUJfQ0hBUiBhbGlnbjsKKyAgICBpbnQgYWx0ZXJuYXRlOworICAgIFNUUklOR0xJQl9DSEFSIHNpZ247CisgICAgUHlfc3NpemVfdCB3aWR0aDsKKyAgICBpbnQgdGhvdXNhbmRzX3NlcGFyYXRvcnM7CisgICAgUHlfc3NpemVfdCBwcmVjaXNpb247CisgICAgU1RSSU5HTElCX0NIQVIgdHlwZTsKK30gSW50ZXJuYWxGb3JtYXRTcGVjOworCisKKyNpZiAwCisvKiBPY2Nhc3Npb25hbGx5IHVzZWZ1bCBmb3IgZGVidWdnaW5nLiBTaG91bGQgbm9ybWFsbHkgYmUgY29tbWVudGVkIG91dC4gKi8KK3N0YXRpYyB2b2lkCitERUJVR19QUklOVF9GT1JNQVRfU1BFQyhJbnRlcm5hbEZvcm1hdFNwZWMgKmZvcm1hdCkKK3sKKyAgICBwcmludGYoImludGVybmFsIGZvcm1hdCBzcGVjOiBmaWxsX2NoYXIgJWRcbiIsIGZvcm1hdC0+ZmlsbF9jaGFyKTsKKyAgICBwcmludGYoImludGVybmFsIGZvcm1hdCBzcGVjOiBhbGlnbiAlZFxuIiwgZm9ybWF0LT5hbGlnbik7CisgICAgcHJpbnRmKCJpbnRlcm5hbCBmb3JtYXQgc3BlYzogYWx0ZXJuYXRlICVkXG4iLCBmb3JtYXQtPmFsdGVybmF0ZSk7CisgICAgcHJpbnRmKCJpbnRlcm5hbCBmb3JtYXQgc3BlYzogc2lnbiAlZFxuIiwgZm9ybWF0LT5zaWduKTsKKyAgICBwcmludGYoImludGVybmFsIGZvcm1hdCBzcGVjOiB3aWR0aCAlemRcbiIsIGZvcm1hdC0+d2lkdGgpOworICAgIHByaW50ZigiaW50ZXJuYWwgZm9ybWF0IHNwZWM6IHRob3VzYW5kc19zZXBhcmF0b3JzICVkXG4iLAorICAgICAgICAgICBmb3JtYXQtPnRob3VzYW5kc19zZXBhcmF0b3JzKTsKKyAgICBwcmludGYoImludGVybmFsIGZvcm1hdCBzcGVjOiBwcmVjaXNpb24gJXpkXG4iLCBmb3JtYXQtPnByZWNpc2lvbik7CisgICAgcHJpbnRmKCJpbnRlcm5hbCBmb3JtYXQgc3BlYzogdHlwZSAlY1xuIiwgZm9ybWF0LT50eXBlKTsKKyAgICBwcmludGYoIlxuIik7Cit9CisjZW5kaWYKKworCisvKgorICBwdHIgcG9pbnRzIHRvIHRoZSBzdGFydCBvZiB0aGUgZm9ybWF0X3NwZWMsIGVuZCBwb2ludHMganVzdCBwYXN0IGl0cyBlbmQuCisgIGZpbGxzIGluIGZvcm1hdCB3aXRoIHRoZSBwYXJzZWQgaW5mb3JtYXRpb24uCisgIHJldHVybnMgMSBvbiBzdWNjZXNzLCAwIG9uIGZhaWx1cmUuCisgIGlmIGZhaWx1cmUsIHNldHMgdGhlIGV4Y2VwdGlvbgorKi8KK3N0YXRpYyBpbnQKK3BhcnNlX2ludGVybmFsX3JlbmRlcl9mb3JtYXRfc3BlYyhTVFJJTkdMSUJfQ0hBUiAqZm9ybWF0X3NwZWMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHlfc3NpemVfdCBmb3JtYXRfc3BlY19sZW4sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSW50ZXJuYWxGb3JtYXRTcGVjICpmb3JtYXQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hhciBkZWZhdWx0X3R5cGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hhciBkZWZhdWx0X2FsaWduKQoreworICAgIFNUUklOR0xJQl9DSEFSICpwdHIgPSBmb3JtYXRfc3BlYzsKKyAgICBTVFJJTkdMSUJfQ0hBUiAqZW5kID0gZm9ybWF0X3NwZWMgKyBmb3JtYXRfc3BlY19sZW47CisKKyAgICAvKiBlbmQtcHRyIGlzIHVzZWQgdGhyb3VnaG91dCB0aGlzIGNvZGUgdG8gc3BlY2lmeSB0aGUgbGVuZ3RoIG9mCisgICAgICAgdGhlIGlucHV0IHN0cmluZyAqLworCisgICAgUHlfc3NpemVfdCBjb25zdW1lZDsKKyAgICBpbnQgYWxpZ25fc3BlY2lmaWVkID0gMDsKKworICAgIGZvcm1hdC0+ZmlsbF9jaGFyID0gJ1wwJzsKKyAgICBmb3JtYXQtPmFsaWduID0gZGVmYXVsdF9hbGlnbjsKKyAgICBmb3JtYXQtPmFsdGVybmF0ZSA9IDA7CisgICAgZm9ybWF0LT5zaWduID0gJ1wwJzsKKyAgICBmb3JtYXQtPndpZHRoID0gLTE7CisgICAgZm9ybWF0LT50aG91c2FuZHNfc2VwYXJhdG9ycyA9IDA7CisgICAgZm9ybWF0LT5wcmVjaXNpb24gPSAtMTsKKyAgICBmb3JtYXQtPnR5cGUgPSBkZWZhdWx0X3R5cGU7CisKKyAgICAvKiBJZiB0aGUgc2Vjb25kIGNoYXIgaXMgYW4gYWxpZ25tZW50IHRva2VuLAorICAgICAgIHRoZW4gcGFyc2UgdGhlIGZpbGwgY2hhciAqLworICAgIGlmIChlbmQtcHRyID49IDIgJiYgaXNfYWxpZ25tZW50X3Rva2VuKHB0clsxXSkpIHsKKyAgICAgICAgZm9ybWF0LT5hbGlnbiA9IHB0clsxXTsKKyAgICAgICAgZm9ybWF0LT5maWxsX2NoYXIgPSBwdHJbMF07CisgICAgICAgIGFsaWduX3NwZWNpZmllZCA9IDE7CisgICAgICAgIHB0ciArPSAyOworICAgIH0KKyAgICBlbHNlIGlmIChlbmQtcHRyID49IDEgJiYgaXNfYWxpZ25tZW50X3Rva2VuKHB0clswXSkpIHsKKyAgICAgICAgZm9ybWF0LT5hbGlnbiA9IHB0clswXTsKKyAgICAgICAgYWxpZ25fc3BlY2lmaWVkID0gMTsKKyAgICAgICAgKytwdHI7CisgICAgfQorCisgICAgLyogUGFyc2UgdGhlIHZhcmlvdXMgc2lnbiBvcHRpb25zICovCisgICAgaWYgKGVuZC1wdHIgPj0gMSAmJiBpc19zaWduX2VsZW1lbnQocHRyWzBdKSkgeworICAgICAgICBmb3JtYXQtPnNpZ24gPSBwdHJbMF07CisgICAgICAgICsrcHRyOworICAgIH0KKworICAgIC8qIElmIHRoZSBuZXh0IGNoYXJhY3RlciBpcyAjLCB3ZSdyZSBpbiBhbHRlcm5hdGUgbW9kZS4gIFRoaXMgb25seQorICAgICAgIGFwcGxpZXMgdG8gaW50ZWdlcnMuICovCisgICAgaWYgKGVuZC1wdHIgPj0gMSAmJiBwdHJbMF0gPT0gJyMnKSB7CisgICAgICAgIGZvcm1hdC0+YWx0ZXJuYXRlID0gMTsKKyAgICAgICAgKytwdHI7CisgICAgfQorCisgICAgLyogVGhlIHNwZWNpYWwgY2FzZSBmb3IgMC1wYWRkaW5nIChiYWNrd2FyZHMgY29tcGF0KSAqLworICAgIGlmIChmb3JtYXQtPmZpbGxfY2hhciA9PSAnXDAnICYmIGVuZC1wdHIgPj0gMSAmJiBwdHJbMF0gPT0gJzAnKSB7CisgICAgICAgIGZvcm1hdC0+ZmlsbF9jaGFyID0gJzAnOworICAgICAgICBpZiAoIWFsaWduX3NwZWNpZmllZCkgeworICAgICAgICAgICAgZm9ybWF0LT5hbGlnbiA9ICc9JzsKKyAgICAgICAgfQorICAgICAgICArK3B0cjsKKyAgICB9CisKKyAgICBjb25zdW1lZCA9IGdldF9pbnRlZ2VyKCZwdHIsIGVuZCwgJmZvcm1hdC0+d2lkdGgpOworICAgIGlmIChjb25zdW1lZCA9PSAtMSkKKyAgICAgICAgLyogT3ZlcmZsb3cgZXJyb3IuIEV4Y2VwdGlvbiBhbHJlYWR5IHNldC4gKi8KKyAgICAgICAgcmV0dXJuIDA7CisKKyAgICAvKiBJZiBjb25zdW1lZCBpcyAwLCB3ZSBkaWRuJ3QgY29uc3VtZSBhbnkgY2hhcmFjdGVycyBmb3IgdGhlCisgICAgICAgd2lkdGguIEluIHRoYXQgY2FzZSwgcmVzZXQgdGhlIHdpZHRoIHRvIC0xLCBiZWNhdXNlCisgICAgICAgZ2V0X2ludGVnZXIoKSB3aWxsIGhhdmUgc2V0IGl0IHRvIHplcm8uIC0xIGlzIGhvdyB3ZSByZWNvcmQKKyAgICAgICB0aGF0IHRoZSB3aWR0aCB3YXNuJ3Qgc3BlY2lmaWVkLiAqLworICAgIGlmIChjb25zdW1lZCA9PSAwKQorICAgICAgICBmb3JtYXQtPndpZHRoID0gLTE7CisKKyAgICAvKiBDb21tYSBzaWduaWZpZXMgYWRkIHRob3VzYW5kcyBzZXBhcmF0b3JzICovCisgICAgaWYgKGVuZC1wdHIgJiYgcHRyWzBdID09ICcsJykgeworICAgICAgICBmb3JtYXQtPnRob3VzYW5kc19zZXBhcmF0b3JzID0gMTsKKyAgICAgICAgKytwdHI7CisgICAgfQorCisgICAgLyogUGFyc2UgZmllbGQgcHJlY2lzaW9uICovCisgICAgaWYgKGVuZC1wdHIgJiYgcHRyWzBdID09ICcuJykgeworICAgICAgICArK3B0cjsKKworICAgICAgICBjb25zdW1lZCA9IGdldF9pbnRlZ2VyKCZwdHIsIGVuZCwgJmZvcm1hdC0+cHJlY2lzaW9uKTsKKyAgICAgICAgaWYgKGNvbnN1bWVkID09IC0xKQorICAgICAgICAgICAgLyogT3ZlcmZsb3cgZXJyb3IuIEV4Y2VwdGlvbiBhbHJlYWR5IHNldC4gKi8KKyAgICAgICAgICAgIHJldHVybiAwOworCisgICAgICAgIC8qIE5vdCBoYXZpbmcgYSBwcmVjaXNpb24gYWZ0ZXIgYSBkb3QgaXMgYW4gZXJyb3IuICovCisgICAgICAgIGlmIChjb25zdW1lZCA9PSAwKSB7CisgICAgICAgICAgICBQeUVycl9Gb3JtYXQoUHlFeGNfVmFsdWVFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAiRm9ybWF0IHNwZWNpZmllciBtaXNzaW5nIHByZWNpc2lvbiIpOworICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgIH0KKworICAgIH0KKworICAgIC8qIEZpbmFsbHksIHBhcnNlIHRoZSB0eXBlIGZpZWxkLiAqLworCisgICAgaWYgKGVuZC1wdHIgPiAxKSB7CisgICAgICAgIC8qIE1vcmUgdGhhbiBvbmUgY2hhciByZW1haW4sIGludmFsaWQgY29udmVyc2lvbiBzcGVjLiAqLworICAgICAgICBQeUVycl9Gb3JtYXQoUHlFeGNfVmFsdWVFcnJvciwgIkludmFsaWQgY29udmVyc2lvbiBzcGVjaWZpY2F0aW9uIik7CisgICAgICAgIHJldHVybiAwOworICAgIH0KKworICAgIGlmIChlbmQtcHRyID09IDEpIHsKKyAgICAgICAgZm9ybWF0LT50eXBlID0gcHRyWzBdOworICAgICAgICArK3B0cjsKKyAgICB9CisKKyAgICAvKiBEbyBhcyBtdWNoIHZhbGlkYXRpbmcgYXMgd2UgY2FuLCBqdXN0IGJ5IGxvb2tpbmcgYXQgdGhlIGZvcm1hdAorICAgICAgIHNwZWNpZmllci4gIERvIG5vdCB0YWtlIGludG8gYWNjb3VudCB3aGF0IHR5cGUgb2YgZm9ybWF0dGluZworICAgICAgIHdlJ3JlIGRvaW5nIChpbnQsIGZsb2F0LCBzdHJpbmcpLiAqLworCisgICAgaWYgKGZvcm1hdC0+dGhvdXNhbmRzX3NlcGFyYXRvcnMpIHsKKyAgICAgICAgc3dpdGNoIChmb3JtYXQtPnR5cGUpIHsKKyAgICAgICAgY2FzZSAnZCc6CisgICAgICAgIGNhc2UgJ2UnOgorICAgICAgICBjYXNlICdmJzoKKyAgICAgICAgY2FzZSAnZyc6CisgICAgICAgIGNhc2UgJ0UnOgorICAgICAgICBjYXNlICdHJzoKKyAgICAgICAgY2FzZSAnJSc6CisgICAgICAgIGNhc2UgJ0YnOgorICAgICAgICBjYXNlICdcMCc6CisgICAgICAgICAgICAvKiBUaGVzZSBhcmUgYWxsb3dlZC4gU2VlIFBFUCAzNzguKi8KKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICBkZWZhdWx0OgorICAgICAgICAgICAgaW52YWxpZF9jb21tYV90eXBlKGZvcm1hdC0+dHlwZSk7CisgICAgICAgICAgICByZXR1cm4gMDsKKyAgICAgICAgfQorICAgIH0KKworICAgIHJldHVybiAxOworfQorCisvKiBDYWxjdWxhdGUgdGhlIHBhZGRpbmcgbmVlZGVkLiAqLworc3RhdGljIHZvaWQKK2NhbGNfcGFkZGluZyhQeV9zc2l6ZV90IG5jaGFycywgUHlfc3NpemVfdCB3aWR0aCwgU1RSSU5HTElCX0NIQVIgYWxpZ24sCisgICAgICAgICAgICAgUHlfc3NpemVfdCAqbl9scGFkZGluZywgUHlfc3NpemVfdCAqbl9ycGFkZGluZywKKyAgICAgICAgICAgICBQeV9zc2l6ZV90ICpuX3RvdGFsKQoreworICAgIGlmICh3aWR0aCA+PSAwKSB7CisgICAgICAgIGlmIChuY2hhcnMgPiB3aWR0aCkKKyAgICAgICAgICAgICpuX3RvdGFsID0gbmNoYXJzOworICAgICAgICBlbHNlCisgICAgICAgICAgICAqbl90b3RhbCA9IHdpZHRoOworICAgIH0KKyAgICBlbHNlIHsKKyAgICAgICAgLyogbm90IHNwZWNpZmllZCwgdXNlIGFsbCBvZiB0aGUgY2hhcnMgYW5kIG5vIG1vcmUgKi8KKyAgICAgICAgKm5fdG90YWwgPSBuY2hhcnM7CisgICAgfQorCisgICAgLyogRmlndXJlIG91dCBob3cgbXVjaCBsZWFkaW5nIHNwYWNlIHdlIG5lZWQsIGJhc2VkIG9uIHRoZQorICAgICAgIGFsaWduaW5nICovCisgICAgaWYgKGFsaWduID09ICc+JykKKyAgICAgICAgKm5fbHBhZGRpbmcgPSAqbl90b3RhbCAtIG5jaGFyczsKKyAgICBlbHNlIGlmIChhbGlnbiA9PSAnXicpCisgICAgICAgICpuX2xwYWRkaW5nID0gKCpuX3RvdGFsIC0gbmNoYXJzKSAvIDI7CisgICAgZWxzZSBpZiAoYWxpZ24gPT0gJzwnIHx8IGFsaWduID09ICc9JykKKyAgICAgICAgKm5fbHBhZGRpbmcgPSAwOworICAgIGVsc2UgeworICAgICAgICAvKiBXZSBzaG91bGQgbmV2ZXIgaGF2ZSBhbiB1bnNwZWNpZmllZCBhbGlnbm1lbnQuICovCisgICAgICAgICpuX2xwYWRkaW5nID0gMDsKKyAgICAgICAgYXNzZXJ0KDApOworICAgIH0KKworICAgICpuX3JwYWRkaW5nID0gKm5fdG90YWwgLSBuY2hhcnMgLSAqbl9scGFkZGluZzsKK30KKworLyogRG8gdGhlIHBhZGRpbmcsIGFuZCByZXR1cm4gYSBwb2ludGVyIHRvIHdoZXJlIHRoZSBjYWxsZXItc3VwcGxpZWQKKyAgIGNvbnRlbnQgZ29lcy4gKi8KK3N0YXRpYyBTVFJJTkdMSUJfQ0hBUiAqCitmaWxsX3BhZGRpbmcoU1RSSU5HTElCX0NIQVIgKnAsIFB5X3NzaXplX3QgbmNoYXJzLCBTVFJJTkdMSUJfQ0hBUiBmaWxsX2NoYXIsCisgICAgICAgICAgICAgUHlfc3NpemVfdCBuX2xwYWRkaW5nLCBQeV9zc2l6ZV90IG5fcnBhZGRpbmcpCit7CisgICAgLyogUGFkIG9uIGxlZnQuICovCisgICAgaWYgKG5fbHBhZGRpbmcpCisgICAgICAgIFNUUklOR0xJQl9GSUxMKHAsIGZpbGxfY2hhciwgbl9scGFkZGluZyk7CisKKyAgICAvKiBQYWQgb24gcmlnaHQuICovCisgICAgaWYgKG5fcnBhZGRpbmcpCisgICAgICAgIFNUUklOR0xJQl9GSUxMKHAgKyBuY2hhcnMgKyBuX2xwYWRkaW5nLCBmaWxsX2NoYXIsIG5fcnBhZGRpbmcpOworCisgICAgLyogUG9pbnRlciB0byB0aGUgdXNlciBjb250ZW50LiAqLworICAgIHJldHVybiBwICsgbl9scGFkZGluZzsKK30KKworI2lmIGRlZmluZWQgRk9STUFUX0ZMT0FUIHx8IGRlZmluZWQgRk9STUFUX0xPTkcgfHwgZGVmaW5lZCBGT1JNQVRfQ09NUExFWAorLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KKy8qKioqKioqKioqKiBjb21tb24gcm91dGluZXMgZm9yIG51bWVyaWMgZm9ybWF0dGluZyAqKioqKioqKioqKioqKioqKioqKiovCisvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLworCisvKiBMb2NhbGUgdHlwZSBjb2Rlcy4gKi8KKyNkZWZpbmUgTFRfQ1VSUkVOVF9MT0NBTEUgMAorI2RlZmluZSBMVF9ERUZBVUxUX0xPQ0FMRSAxCisjZGVmaW5lIExUX05PX0xPQ0FMRSAyCisKKy8qIExvY2FsZSBpbmZvIG5lZWRlZCBmb3IgZm9ybWF0dGluZyBpbnRlZ2VycyBhbmQgdGhlIHBhcnQgb2YgZmxvYXRzCisgICBiZWZvcmUgYW5kIGluY2x1ZGluZyB0aGUgZGVjaW1hbC4gTm90ZSB0aGF0IGxvY2FsZXMgb25seSBzdXBwb3J0CisgICA4LWJpdCBjaGFycywgbm90IHVuaWNvZGUuICovCit0eXBlZGVmIHN0cnVjdCB7CisgICAgY2hhciAqZGVjaW1hbF9wb2ludDsKKyAgICBjaGFyICp0aG91c2FuZHNfc2VwOworICAgIGNoYXIgKmdyb3VwaW5nOworfSBMb2NhbGVJbmZvOworCisvKiBkZXNjcmliZXMgdGhlIGxheW91dCBmb3IgYW4gaW50ZWdlciwgc2VlIHRoZSBjb21tZW50IGluCisgICBjYWxjX251bWJlcl93aWR0aHMoKSBmb3IgZGV0YWlscyAqLwordHlwZWRlZiBzdHJ1Y3QgeworICAgIFB5X3NzaXplX3Qgbl9scGFkZGluZzsKKyAgICBQeV9zc2l6ZV90IG5fcHJlZml4OworICAgIFB5X3NzaXplX3Qgbl9zcGFkZGluZzsKKyAgICBQeV9zc2l6ZV90IG5fcnBhZGRpbmc7CisgICAgY2hhciBzaWduOworICAgIFB5X3NzaXplX3Qgbl9zaWduOyAgICAgIC8qIG51bWJlciBvZiBkaWdpdHMgbmVlZGVkIGZvciBzaWduICgwLzEpICovCisgICAgUHlfc3NpemVfdCBuX2dyb3VwZWRfZGlnaXRzOyAvKiBTcGFjZSB0YWtlbiB1cCBieSB0aGUgZGlnaXRzLCBpbmNsdWRpbmcKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFueSBncm91cGluZyBjaGFycy4gKi8KKyAgICBQeV9zc2l6ZV90IG5fZGVjaW1hbDsgICAvKiAwIGlmIG9ubHkgYW4gaW50ZWdlciAqLworICAgIFB5X3NzaXplX3Qgbl9yZW1haW5kZXI7IC8qIERpZ2l0cyBpbiBkZWNpbWFsIGFuZC9vciBleHBvbmVudCBwYXJ0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4Y2x1ZGluZyB0aGUgZGVjaW1hbCBpdHNlbGYsIGlmCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJlc2VudC4gKi8KKworICAgIC8qIFRoZXNlIDIgYXJlIG5vdCB0aGUgd2lkdGhzIG9mIGZpZWxkcywgYnV0IGFyZSBuZWVkZWQgYnkKKyAgICAgICBTVFJJTkdMSUJfR1JPVVBJTkcuICovCisgICAgUHlfc3NpemVfdCBuX2RpZ2l0czsgICAgLyogVGhlIG51bWJlciBvZiBkaWdpdHMgYmVmb3JlIGEgZGVjaW1hbAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9yIGV4cG9uZW50LiAqLworICAgIFB5X3NzaXplX3Qgbl9taW5fd2lkdGg7IC8qIFRoZSBtaW5fd2lkdGggd2UgdXNlZCB3aGVuIHdlIGNvbXB1dGVkCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhlIG5fZ3JvdXBlZF9kaWdpdHMgd2lkdGguICovCit9IE51bWJlckZpZWxkV2lkdGhzOworCisKKy8qIEdpdmVuIGEgbnVtYmVyIG9mIHRoZSBmb3JtOgorICAgZGlnaXRzW3JlbWFpbmRlcl0KKyAgIHdoZXJlIHB0ciBwb2ludHMgdG8gdGhlIHN0YXJ0IGFuZCBlbmQgcG9pbnRzIHRvIHRoZSBlbmQsIGZpbmQgd2hlcmUKKyAgICB0aGUgaW50ZWdlciBwYXJ0IGVuZHMuIFRoaXMgY291bGQgYmUgYSBkZWNpbWFsLCBhbiBleHBvbmVudCwgYm90aCwKKyAgICBvciBuZWl0aGVyLgorICAgSWYgYSBkZWNpbWFsIHBvaW50IGlzIHByZXNlbnQsIHNldCAqaGFzX2RlY2ltYWwgYW5kIGluY3JlbWVudAorICAgIHJlbWFpbmRlciBiZXlvbmQgaXQuCisgICBSZXN1bHRzIGFyZSB1bmRlZmluZWQgKGJ1dCBzaG91bGRuJ3QgY3Jhc2gpIGZvciBpbXByb3Blcmx5CisgICAgZm9ybWF0dGVkIHN0cmluZ3MuCisqLworc3RhdGljIHZvaWQKK3BhcnNlX251bWJlcihTVFJJTkdMSUJfQ0hBUiAqcHRyLCBQeV9zc2l6ZV90IGxlbiwKKyAgICAgICAgICAgICBQeV9zc2l6ZV90ICpuX3JlbWFpbmRlciwgaW50ICpoYXNfZGVjaW1hbCkKK3sKKyAgICBTVFJJTkdMSUJfQ0hBUiAqZW5kID0gcHRyICsgbGVuOworICAgIFNUUklOR0xJQl9DSEFSICpyZW1haW5kZXI7CisKKyAgICB3aGlsZSAocHRyPGVuZCAmJiBpc2RpZ2l0KCpwdHIpKQorICAgICAgICArK3B0cjsKKyAgICByZW1haW5kZXIgPSBwdHI7CisKKyAgICAvKiBEb2VzIHJlbWFpbmRlciBzdGFydCB3aXRoIGEgZGVjaW1hbCBwb2ludD8gKi8KKyAgICAqaGFzX2RlY2ltYWwgPSBwdHI8ZW5kICYmICpyZW1haW5kZXIgPT0gJy4nOworCisgICAgLyogU2tpcCB0aGUgZGVjaW1hbCBwb2ludC4gKi8KKyAgICBpZiAoKmhhc19kZWNpbWFsKQorICAgICAgICByZW1haW5kZXIrKzsKKworICAgICpuX3JlbWFpbmRlciA9IGVuZCAtIHJlbWFpbmRlcjsKK30KKworLyogbm90IGFsbCBmaWVsZHMgb2YgZm9ybWF0IGFyZSB1c2VkLiAgZm9yIGV4YW1wbGUsIHByZWNpc2lvbiBpcworICAgdW51c2VkLiAgc2hvdWxkIHRoaXMgdGFrZSBkaXNjcmV0ZSBwYXJhbXMgaW4gb3JkZXIgdG8gYmUgbW9yZSBjbGVhcgorICAgYWJvdXQgd2hhdCBpdCBkb2VzPyAgb3IgaXMgcGFzc2luZyBhIHNpbmdsZSBmb3JtYXQgcGFyYW1ldGVyIGVhc2llcgorICAgYW5kIG1vcmUgZWZmaWNpZW50IGVub3VnaCB0byBqdXN0aWZ5IGEgbGl0dGxlIG9iZnVzY2F0aW9uPyAqLworc3RhdGljIFB5X3NzaXplX3QKK2NhbGNfbnVtYmVyX3dpZHRocyhOdW1iZXJGaWVsZFdpZHRocyAqc3BlYywgUHlfc3NpemVfdCBuX3ByZWZpeCwKKyAgICAgICAgICAgICAgICAgICBTVFJJTkdMSUJfQ0hBUiBzaWduX2NoYXIsIFNUUklOR0xJQl9DSEFSICpudW1iZXIsCisgICAgICAgICAgICAgICAgICAgUHlfc3NpemVfdCBuX251bWJlciwgUHlfc3NpemVfdCBuX3JlbWFpbmRlciwKKyAgICAgICAgICAgICAgICAgICBpbnQgaGFzX2RlY2ltYWwsIGNvbnN0IExvY2FsZUluZm8gKmxvY2FsZSwKKyAgICAgICAgICAgICAgICAgICBjb25zdCBJbnRlcm5hbEZvcm1hdFNwZWMgKmZvcm1hdCkKK3sKKyAgICBQeV9zc2l6ZV90IG5fbm9uX2RpZ2l0X25vbl9wYWRkaW5nOworICAgIFB5X3NzaXplX3Qgbl9wYWRkaW5nOworCisgICAgc3BlYy0+bl9kaWdpdHMgPSBuX251bWJlciAtIG5fcmVtYWluZGVyIC0gKGhhc19kZWNpbWFsPzE6MCk7CisgICAgc3BlYy0+bl9scGFkZGluZyA9IDA7CisgICAgc3BlYy0+bl9wcmVmaXggPSBuX3ByZWZpeDsKKyAgICBzcGVjLT5uX2RlY2ltYWwgPSBoYXNfZGVjaW1hbCA/IHN0cmxlbihsb2NhbGUtPmRlY2ltYWxfcG9pbnQpIDogMDsKKyAgICBzcGVjLT5uX3JlbWFpbmRlciA9IG5fcmVtYWluZGVyOworICAgIHNwZWMtPm5fc3BhZGRpbmcgPSAwOworICAgIHNwZWMtPm5fcnBhZGRpbmcgPSAwOworICAgIHNwZWMtPnNpZ24gPSAnXDAnOworICAgIHNwZWMtPm5fc2lnbiA9IDA7CisKKyAgICAvKiB0aGUgb3V0cHV0IHdpbGwgbG9vayBsaWtlOgorICAgICAgIHwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwKKyAgICAgICB8IDxscGFkZGluZz4gPHNpZ24+IDxwcmVmaXg+IDxzcGFkZGluZz4gPGdyb3VwZWRfZGlnaXRzPiA8ZGVjaW1hbD4gPHJlbWFpbmRlcj4gPHJwYWRkaW5nPiB8CisgICAgICAgfCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfAorCisgICAgICAgc2lnbiBpcyBjb21wdXRlZCBmcm9tIGZvcm1hdC0+c2lnbiBhbmQgdGhlIGFjdHVhbAorICAgICAgIHNpZ24gb2YgdGhlIG51bWJlcgorCisgICAgICAgcHJlZml4IGlzIGdpdmVuIChpdCdzIGZvciB0aGUgJzB4JyBwcmVmaXgpCisKKyAgICAgICBkaWdpdHMgaXMgYWxyZWFkeSBrbm93bgorCisgICAgICAgdGhlIHRvdGFsIHdpZHRoIGlzIGVpdGhlciBnaXZlbiwgb3IgY29tcHV0ZWQgZnJvbSB0aGUKKyAgICAgICBhY3R1YWwgZGlnaXRzCisKKyAgICAgICBvbmx5IG9uZSBvZiBscGFkZGluZywgc3BhZGRpbmcsIGFuZCBycGFkZGluZyBjYW4gYmUgbm9uLXplcm8sCisgICAgICAgYW5kIGl0J3MgY2FsY3VsYXRlZCBmcm9tIHRoZSB3aWR0aCBhbmQgb3RoZXIgZmllbGRzCisgICAgKi8KKworICAgIC8qIGNvbXB1dGUgdGhlIHZhcmlvdXMgcGFydHMgd2UncmUgZ29pbmcgdG8gd3JpdGUgKi8KKyAgICBzd2l0Y2ggKGZvcm1hdC0+c2lnbikgeworICAgIGNhc2UgJysnOgorICAgICAgICAvKiBhbHdheXMgcHV0IGEgKyBvciAtICovCisgICAgICAgIHNwZWMtPm5fc2lnbiA9IDE7CisgICAgICAgIHNwZWMtPnNpZ24gPSAoc2lnbl9jaGFyID09ICctJyA/ICctJyA6ICcrJyk7CisgICAgICAgIGJyZWFrOworICAgIGNhc2UgJyAnOgorICAgICAgICBzcGVjLT5uX3NpZ24gPSAxOworICAgICAgICBzcGVjLT5zaWduID0gKHNpZ25fY2hhciA9PSAnLScgPyAnLScgOiAnICcpOworICAgICAgICBicmVhazsKKyAgICBkZWZhdWx0OgorICAgICAgICAvKiBOb3Qgc3BlY2lmaWVkLCBvciB0aGUgZGVmYXVsdCAoLSkgKi8KKyAgICAgICAgaWYgKHNpZ25fY2hhciA9PSAnLScpIHsKKyAgICAgICAgICAgIHNwZWMtPm5fc2lnbiA9IDE7CisgICAgICAgICAgICBzcGVjLT5zaWduID0gJy0nOworICAgICAgICB9CisgICAgfQorCisgICAgLyogVGhlIG51bWJlciBvZiBjaGFycyB1c2VkIGZvciBub24tZGlnaXRzIGFuZCBub24tcGFkZGluZy4gKi8KKyAgICBuX25vbl9kaWdpdF9ub25fcGFkZGluZyA9IHNwZWMtPm5fc2lnbiArIHNwZWMtPm5fcHJlZml4ICsgc3BlYy0+bl9kZWNpbWFsICsKKyAgICAgICAgc3BlYy0+bl9yZW1haW5kZXI7CisKKyAgICAvKiBtaW5fd2lkdGggY2FuIGdvIG5lZ2F0aXZlLCB0aGF0J3Mgb2theS4gZm9ybWF0LT53aWR0aCA9PSAtMSBtZWFucworICAgICAgIHdlIGRvbid0IGNhcmUuICovCisgICAgaWYgKGZvcm1hdC0+ZmlsbF9jaGFyID09ICcwJyAmJiBmb3JtYXQtPmFsaWduID09ICc9JykKKyAgICAgICAgc3BlYy0+bl9taW5fd2lkdGggPSBmb3JtYXQtPndpZHRoIC0gbl9ub25fZGlnaXRfbm9uX3BhZGRpbmc7CisgICAgZWxzZQorICAgICAgICBzcGVjLT5uX21pbl93aWR0aCA9IDA7CisKKyAgICBpZiAoc3BlYy0+bl9kaWdpdHMgPT0gMCkKKyAgICAgICAgLyogVGhpcyBjYXNlIG9ubHkgb2NjdXJzIHdoZW4gdXNpbmcgJ2MnIGZvcm1hdHRpbmcsIHdlIG5lZWQKKyAgICAgICAgICAgdG8gc3BlY2lhbCBjYXNlIGl0IGJlY2F1c2UgdGhlIGdyb3VwaW5nIGNvZGUgYWx3YXlzIHdhbnRzCisgICAgICAgICAgIHRvIGhhdmUgYXQgbGVhc3Qgb25lIGNoYXJhY3Rlci4gKi8KKyAgICAgICAgc3BlYy0+bl9ncm91cGVkX2RpZ2l0cyA9IDA7CisgICAgZWxzZQorICAgICAgICBzcGVjLT5uX2dyb3VwZWRfZGlnaXRzID0gU1RSSU5HTElCX0dST1VQSU5HKE5VTEwsIDAsIE5VTEwsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3BlYy0+bl9kaWdpdHMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3BlYy0+bl9taW5fd2lkdGgsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9jYWxlLT5ncm91cGluZywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsb2NhbGUtPnRob3VzYW5kc19zZXApOworCisgICAgLyogR2l2ZW4gdGhlIGRlc2lyZWQgd2lkdGggYW5kIHRoZSB0b3RhbCBvZiBkaWdpdCBhbmQgbm9uLWRpZ2l0CisgICAgICAgc3BhY2Ugd2UgY29uc3VtZSwgc2VlIGlmIHdlIG5lZWQgYW55IHBhZGRpbmcuIGZvcm1hdC0+d2lkdGggY2FuCisgICAgICAgYmUgbmVnYXRpdmUgKG1lYW5pbmcgbm8gcGFkZGluZyksIGJ1dCB0aGlzIGNvZGUgc3RpbGwgd29ya3MgaW4KKyAgICAgICB0aGF0IGNhc2UuICovCisgICAgbl9wYWRkaW5nID0gZm9ybWF0LT53aWR0aCAtCisgICAgICAgICAgICAgICAgICAgICAgICAobl9ub25fZGlnaXRfbm9uX3BhZGRpbmcgKyBzcGVjLT5uX2dyb3VwZWRfZGlnaXRzKTsKKyAgICBpZiAobl9wYWRkaW5nID4gMCkgeworICAgICAgICAvKiBTb21lIHBhZGRpbmcgaXMgbmVlZGVkLiBEZXRlcm1pbmUgaWYgaXQncyBsZWZ0LCBzcGFjZSwgb3IgcmlnaHQuICovCisgICAgICAgIHN3aXRjaCAoZm9ybWF0LT5hbGlnbikgeworICAgICAgICBjYXNlICc8JzoKKyAgICAgICAgICAgIHNwZWMtPm5fcnBhZGRpbmcgPSBuX3BhZGRpbmc7CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgY2FzZSAnXic6CisgICAgICAgICAgICBzcGVjLT5uX2xwYWRkaW5nID0gbl9wYWRkaW5nIC8gMjsKKyAgICAgICAgICAgIHNwZWMtPm5fcnBhZGRpbmcgPSBuX3BhZGRpbmcgLSBzcGVjLT5uX2xwYWRkaW5nOworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIGNhc2UgJz0nOgorICAgICAgICAgICAgc3BlYy0+bl9zcGFkZGluZyA9IG5fcGFkZGluZzsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICBjYXNlICc+JzoKKyAgICAgICAgICAgIHNwZWMtPm5fbHBhZGRpbmcgPSBuX3BhZGRpbmc7CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAgIC8qIFNob3VsZG4ndCBnZXQgaGVyZSwgYnV0IHRyZWF0IGl0IGFzICc+JyAqLworICAgICAgICAgICAgc3BlYy0+bl9scGFkZGluZyA9IG5fcGFkZGluZzsKKyAgICAgICAgICAgIGFzc2VydCgwKTsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisgICAgfQorICAgIHJldHVybiBzcGVjLT5uX2xwYWRkaW5nICsgc3BlYy0+bl9zaWduICsgc3BlYy0+bl9wcmVmaXggKworICAgICAgICBzcGVjLT5uX3NwYWRkaW5nICsgc3BlYy0+bl9ncm91cGVkX2RpZ2l0cyArIHNwZWMtPm5fZGVjaW1hbCArCisgICAgICAgIHNwZWMtPm5fcmVtYWluZGVyICsgc3BlYy0+bl9ycGFkZGluZzsKK30KKworLyogRmlsbCBpbiB0aGUgZGlnaXQgcGFydHMgb2YgYSBudW1iZXJzJ3Mgc3RyaW5nIHJlcHJlc2VudGF0aW9uLAorICAgYXMgZGV0ZXJtaW5lZCBpbiBjYWxjX251bWJlcl93aWR0aHMoKS4KKyAgIE5vIGVycm9yIGNoZWNraW5nLCBzaW5jZSB3ZSBrbm93IHRoZSBidWZmZXIgaXMgdGhlIGNvcnJlY3Qgc2l6ZS4gKi8KK3N0YXRpYyB2b2lkCitmaWxsX251bWJlcihTVFJJTkdMSUJfQ0hBUiAqYnVmLCBjb25zdCBOdW1iZXJGaWVsZFdpZHRocyAqc3BlYywKKyAgICAgICAgICAgIFNUUklOR0xJQl9DSEFSICpkaWdpdHMsIFB5X3NzaXplX3Qgbl9kaWdpdHMsCisgICAgICAgICAgICBTVFJJTkdMSUJfQ0hBUiAqcHJlZml4LCBTVFJJTkdMSUJfQ0hBUiBmaWxsX2NoYXIsCisgICAgICAgICAgICBMb2NhbGVJbmZvICpsb2NhbGUsIGludCB0b3VwcGVyKQoreworICAgIC8qIFVzZWQgdG8ga2VlcCB0cmFjayBvZiBkaWdpdHMsIGRlY2ltYWwsIGFuZCByZW1haW5kZXIuICovCisgICAgU1RSSU5HTElCX0NIQVIgKnAgPSBkaWdpdHM7CisKKyNpZm5kZWYgTkRFQlVHCisgICAgUHlfc3NpemVfdCByOworI2VuZGlmCisKKyAgICBpZiAoc3BlYy0+bl9scGFkZGluZykgeworICAgICAgICBTVFJJTkdMSUJfRklMTChidWYsIGZpbGxfY2hhciwgc3BlYy0+bl9scGFkZGluZyk7CisgICAgICAgIGJ1ZiArPSBzcGVjLT5uX2xwYWRkaW5nOworICAgIH0KKyAgICBpZiAoc3BlYy0+bl9zaWduID09IDEpIHsKKyAgICAgICAgKmJ1ZisrID0gc3BlYy0+c2lnbjsKKyAgICB9CisgICAgaWYgKHNwZWMtPm5fcHJlZml4KSB7CisgICAgICAgIG1lbW1vdmUoYnVmLAorICAgICAgICAgICAgICAgIHByZWZpeCwKKyAgICAgICAgICAgICAgICBzcGVjLT5uX3ByZWZpeCAqIHNpemVvZihTVFJJTkdMSUJfQ0hBUikpOworICAgICAgICBpZiAodG91cHBlcikgeworICAgICAgICAgICAgUHlfc3NpemVfdCB0OworICAgICAgICAgICAgZm9yICh0ID0gMDsgdCA8IHNwZWMtPm5fcHJlZml4OyArK3QpCisgICAgICAgICAgICAgICAgYnVmW3RdID0gU1RSSU5HTElCX1RPVVBQRVIoYnVmW3RdKTsKKyAgICAgICAgfQorICAgICAgICBidWYgKz0gc3BlYy0+bl9wcmVmaXg7CisgICAgfQorICAgIGlmIChzcGVjLT5uX3NwYWRkaW5nKSB7CisgICAgICAgIFNUUklOR0xJQl9GSUxMKGJ1ZiwgZmlsbF9jaGFyLCBzcGVjLT5uX3NwYWRkaW5nKTsKKyAgICAgICAgYnVmICs9IHNwZWMtPm5fc3BhZGRpbmc7CisgICAgfQorCisgICAgLyogT25seSBmb3IgdHlwZSAnYycgc3BlY2lhbCBjYXNlLCBpdCBoYXMgbm8gZGlnaXRzLiAqLworICAgIGlmIChzcGVjLT5uX2RpZ2l0cyAhPSAwKSB7CisgICAgICAgIC8qIEZpbGwgdGhlIGRpZ2l0cyB3aXRoIEluc2VydFRob3VzYW5kc0dyb3VwaW5nLiAqLworI2lmbmRlZiBOREVCVUcKKyAgICAgICAgciA9CisjZW5kaWYKKyAgICAgICAgICAgIFNUUklOR0xJQl9HUk9VUElORyhidWYsIHNwZWMtPm5fZ3JvdXBlZF9kaWdpdHMsIGRpZ2l0cywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzcGVjLT5uX2RpZ2l0cywgc3BlYy0+bl9taW5fd2lkdGgsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9jYWxlLT5ncm91cGluZywgbG9jYWxlLT50aG91c2FuZHNfc2VwKTsKKyNpZm5kZWYgTkRFQlVHCisgICAgICAgIGFzc2VydChyID09IHNwZWMtPm5fZ3JvdXBlZF9kaWdpdHMpOworI2VuZGlmCisgICAgICAgIHAgKz0gc3BlYy0+bl9kaWdpdHM7CisgICAgfQorICAgIGlmICh0b3VwcGVyKSB7CisgICAgICAgIFB5X3NzaXplX3QgdDsKKyAgICAgICAgZm9yICh0ID0gMDsgdCA8IHNwZWMtPm5fZ3JvdXBlZF9kaWdpdHM7ICsrdCkKKyAgICAgICAgICAgIGJ1Zlt0XSA9IFNUUklOR0xJQl9UT1VQUEVSKGJ1Zlt0XSk7CisgICAgfQorICAgIGJ1ZiArPSBzcGVjLT5uX2dyb3VwZWRfZGlnaXRzOworCisgICAgaWYgKHNwZWMtPm5fZGVjaW1hbCkgeworICAgICAgICBQeV9zc2l6ZV90IHQ7CisgICAgICAgIGZvciAodCA9IDA7IHQgPCBzcGVjLT5uX2RlY2ltYWw7ICsrdCkKKyAgICAgICAgICAgIGJ1Zlt0XSA9IGxvY2FsZS0+ZGVjaW1hbF9wb2ludFt0XTsKKyAgICAgICAgYnVmICs9IHNwZWMtPm5fZGVjaW1hbDsKKyAgICAgICAgcCArPSAxOworICAgIH0KKworICAgIGlmIChzcGVjLT5uX3JlbWFpbmRlcikgeworICAgICAgICBtZW1jcHkoYnVmLCBwLCBzcGVjLT5uX3JlbWFpbmRlciAqIHNpemVvZihTVFJJTkdMSUJfQ0hBUikpOworICAgICAgICBidWYgKz0gc3BlYy0+bl9yZW1haW5kZXI7CisgICAgICAgIHAgKz0gc3BlYy0+bl9yZW1haW5kZXI7CisgICAgfQorCisgICAgaWYgKHNwZWMtPm5fcnBhZGRpbmcpIHsKKyAgICAgICAgU1RSSU5HTElCX0ZJTEwoYnVmLCBmaWxsX2NoYXIsIHNwZWMtPm5fcnBhZGRpbmcpOworICAgICAgICBidWYgKz0gc3BlYy0+bl9ycGFkZGluZzsKKyAgICB9Cit9CisKK3N0YXRpYyBjaGFyIG5vX2dyb3VwaW5nWzFdID0ge0NIQVJfTUFYfTsKKworLyogRmluZCB0aGUgZGVjaW1hbCBwb2ludCBjaGFyYWN0ZXIocz8pLCB0aG91c2FuZHNfc2VwYXJhdG9yKHM/KSwgYW5kCisgICBncm91cGluZyBkZXNjcmlwdGlvbiwgZWl0aGVyIGZvciB0aGUgY3VycmVudCBsb2NhbGUgaWYgdHlwZSBpcworICAgTFRfQ1VSUkVOVF9MT0NBTEUsIGEgaGFyZC1jb2RlZCBsb2NhbGUgaWYgTFRfREVGQVVMVF9MT0NBTEUsIG9yCisgICBub25lIGlmIExUX05PX0xPQ0FMRS4gKi8KK3N0YXRpYyB2b2lkCitnZXRfbG9jYWxlX2luZm8oaW50IHR5cGUsIExvY2FsZUluZm8gKmxvY2FsZV9pbmZvKQoreworICAgIHN3aXRjaCAodHlwZSkgeworICAgIGNhc2UgTFRfQ1VSUkVOVF9MT0NBTEU6IHsKKyAgICAgICAgc3RydWN0IGxjb252ICpsb2NhbGVfZGF0YSA9IGxvY2FsZWNvbnYoKTsKKyAgICAgICAgbG9jYWxlX2luZm8tPmRlY2ltYWxfcG9pbnQgPSBsb2NhbGVfZGF0YS0+ZGVjaW1hbF9wb2ludDsKKyAgICAgICAgbG9jYWxlX2luZm8tPnRob3VzYW5kc19zZXAgPSBsb2NhbGVfZGF0YS0+dGhvdXNhbmRzX3NlcDsKKyAgICAgICAgbG9jYWxlX2luZm8tPmdyb3VwaW5nID0gbG9jYWxlX2RhdGEtPmdyb3VwaW5nOworICAgICAgICBicmVhazsKKyAgICB9CisgICAgY2FzZSBMVF9ERUZBVUxUX0xPQ0FMRToKKyAgICAgICAgbG9jYWxlX2luZm8tPmRlY2ltYWxfcG9pbnQgPSAiLiI7CisgICAgICAgIGxvY2FsZV9pbmZvLT50aG91c2FuZHNfc2VwID0gIiwiOworICAgICAgICBsb2NhbGVfaW5mby0+Z3JvdXBpbmcgPSAiXDMiOyAvKiBHcm91cCBldmVyeSAzIGNoYXJhY3RlcnMuICBUaGUKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGltcGxpY2l0KSB0cmFpbGluZyAwIG1lYW5zIHJlcGVhdAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbmZpbml0ZWx5LiAqLworICAgICAgICBicmVhazsKKyAgICBjYXNlIExUX05PX0xPQ0FMRToKKyAgICAgICAgbG9jYWxlX2luZm8tPmRlY2ltYWxfcG9pbnQgPSAiLiI7CisgICAgICAgIGxvY2FsZV9pbmZvLT50aG91c2FuZHNfc2VwID0gIiI7CisgICAgICAgIGxvY2FsZV9pbmZvLT5ncm91cGluZyA9IG5vX2dyb3VwaW5nOworICAgICAgICBicmVhazsKKyAgICBkZWZhdWx0OgorICAgICAgICBhc3NlcnQoMCk7CisgICAgfQorfQorCisjZW5kaWYgLyogRk9STUFUX0ZMT0FUIHx8IEZPUk1BVF9MT05HIHx8IEZPUk1BVF9DT01QTEVYICovCisKKy8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCisvKioqKioqKioqKiogc3RyaW5nIGZvcm1hdHRpbmcgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLworLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KKworc3RhdGljIFB5T2JqZWN0ICoKK2Zvcm1hdF9zdHJpbmdfaW50ZXJuYWwoUHlPYmplY3QgKnZhbHVlLCBjb25zdCBJbnRlcm5hbEZvcm1hdFNwZWMgKmZvcm1hdCkKK3sKKyAgICBQeV9zc2l6ZV90IGxwYWQ7CisgICAgUHlfc3NpemVfdCBycGFkOworICAgIFB5X3NzaXplX3QgdG90YWw7CisgICAgU1RSSU5HTElCX0NIQVIgKnA7CisgICAgUHlfc3NpemVfdCBsZW4gPSBTVFJJTkdMSUJfTEVOKHZhbHVlKTsKKyAgICBQeU9iamVjdCAqcmVzdWx0ID0gTlVMTDsKKworICAgIC8qIHNpZ24gaXMgbm90IGFsbG93ZWQgb24gc3RyaW5ncyAqLworICAgIGlmIChmb3JtYXQtPnNpZ24gIT0gJ1wwJykgeworICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfVmFsdWVFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICJTaWduIG5vdCBhbGxvd2VkIGluIHN0cmluZyBmb3JtYXQgc3BlY2lmaWVyIik7CisgICAgICAgIGdvdG8gZG9uZTsKKyAgICB9CisKKyAgICAvKiBhbHRlcm5hdGUgaXMgbm90IGFsbG93ZWQgb24gc3RyaW5ncyAqLworICAgIGlmIChmb3JtYXQtPmFsdGVybmF0ZSkgeworICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfVmFsdWVFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICJBbHRlcm5hdGUgZm9ybSAoIykgbm90IGFsbG93ZWQgaW4gc3RyaW5nIGZvcm1hdCAiCisgICAgICAgICAgICAgICAgICAgICAgICAic3BlY2lmaWVyIik7CisgICAgICAgIGdvdG8gZG9uZTsKKyAgICB9CisKKyAgICAvKiAnPScgYWxpZ25tZW50IG5vdCBhbGxvd2VkIG9uIHN0cmluZ3MgKi8KKyAgICBpZiAoZm9ybWF0LT5hbGlnbiA9PSAnPScpIHsKKyAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1ZhbHVlRXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAgICAiJz0nIGFsaWdubWVudCBub3QgYWxsb3dlZCAiCisgICAgICAgICAgICAgICAgICAgICAgICAiaW4gc3RyaW5nIGZvcm1hdCBzcGVjaWZpZXIiKTsKKyAgICAgICAgZ290byBkb25lOworICAgIH0KKworICAgIC8qIGlmIHByZWNpc2lvbiBpcyBzcGVjaWZpZWQsIG91dHB1dCBubyBtb3JlIHRoYXQgZm9ybWF0LnByZWNpc2lvbgorICAgICAgIGNoYXJhY3RlcnMgKi8KKyAgICBpZiAoZm9ybWF0LT5wcmVjaXNpb24gPj0gMCAmJiBsZW4gPj0gZm9ybWF0LT5wcmVjaXNpb24pIHsKKyAgICAgICAgbGVuID0gZm9ybWF0LT5wcmVjaXNpb247CisgICAgfQorCisgICAgY2FsY19wYWRkaW5nKGxlbiwgZm9ybWF0LT53aWR0aCwgZm9ybWF0LT5hbGlnbiwgJmxwYWQsICZycGFkLCAmdG90YWwpOworCisgICAgLyogYWxsb2NhdGUgdGhlIHJlc3VsdGluZyBzdHJpbmcgKi8KKyAgICByZXN1bHQgPSBTVFJJTkdMSUJfTkVXKE5VTEwsIHRvdGFsKTsKKyAgICBpZiAocmVzdWx0ID09IE5VTEwpCisgICAgICAgIGdvdG8gZG9uZTsKKworICAgIC8qIFdyaXRlIGludG8gdGhhdCBzcGFjZS4gRmlyc3QgdGhlIHBhZGRpbmcuICovCisgICAgcCA9IGZpbGxfcGFkZGluZyhTVFJJTkdMSUJfU1RSKHJlc3VsdCksIGxlbiwKKyAgICAgICAgICAgICAgICAgICAgIGZvcm1hdC0+ZmlsbF9jaGFyPT0nXDAnPycgJzpmb3JtYXQtPmZpbGxfY2hhciwKKyAgICAgICAgICAgICAgICAgICAgIGxwYWQsIHJwYWQpOworCisgICAgLyogVGhlbiB0aGUgc291cmNlIHN0cmluZy4gKi8KKyAgICBtZW1jcHkocCwgU1RSSU5HTElCX1NUUih2YWx1ZSksIGxlbiAqIHNpemVvZihTVFJJTkdMSUJfQ0hBUikpOworCitkb25lOgorICAgIHJldHVybiByZXN1bHQ7Cit9CisKKworLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KKy8qKioqKioqKioqKiBsb25nIGZvcm1hdHRpbmcgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCisvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLworCisjaWYgZGVmaW5lZCBGT1JNQVRfTE9ORyB8fCBkZWZpbmVkIEZPUk1BVF9JTlQKK3R5cGVkZWYgUHlPYmplY3QqCisoKkludE9yTG9uZ1RvU3RyaW5nKShQeU9iamVjdCAqdmFsdWUsIGludCBiYXNlKTsKKworc3RhdGljIFB5T2JqZWN0ICoKK2Zvcm1hdF9pbnRfb3JfbG9uZ19pbnRlcm5hbChQeU9iamVjdCAqdmFsdWUsIGNvbnN0IEludGVybmFsRm9ybWF0U3BlYyAqZm9ybWF0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIEludE9yTG9uZ1RvU3RyaW5nIHRvc3RyaW5nKQoreworICAgIFB5T2JqZWN0ICpyZXN1bHQgPSBOVUxMOworICAgIFB5T2JqZWN0ICp0bXAgPSBOVUxMOworICAgIFNUUklOR0xJQl9DSEFSICpwbnVtZXJpY19jaGFyczsKKyAgICBTVFJJTkdMSUJfQ0hBUiBudW1lcmljX2NoYXI7CisgICAgU1RSSU5HTElCX0NIQVIgc2lnbl9jaGFyID0gJ1wwJzsKKyAgICBQeV9zc2l6ZV90IG5fZGlnaXRzOyAgICAgICAvKiBjb3VudCBvZiBkaWdpdHMgbmVlZCBmcm9tIHRoZSBjb21wdXRlZAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmluZyAqLworICAgIFB5X3NzaXplX3Qgbl9yZW1haW5kZXIgPSAwOyAvKiBVc2VkIG9ubHkgZm9yICdjJyBmb3JtYXR0aW5nLCB3aGljaAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcm9kdWNlcyBub24tZGlnaXRzICovCisgICAgUHlfc3NpemVfdCBuX3ByZWZpeCA9IDA7ICAgLyogQ291bnQgb2YgcHJlZml4IGNoYXJzLCAoZS5nLiwgJzB4JykgKi8KKyAgICBQeV9zc2l6ZV90IG5fdG90YWw7CisgICAgU1RSSU5HTElCX0NIQVIgKnByZWZpeCA9IE5VTEw7CisgICAgTnVtYmVyRmllbGRXaWR0aHMgc3BlYzsKKyAgICBsb25nIHg7CisKKyAgICAvKiBMb2NhbGUgc2V0dGluZ3MsIGVpdGhlciBmcm9tIHRoZSBhY3R1YWwgbG9jYWxlIG9yCisgICAgICAgZnJvbSBhIGhhcmQtY29kZSBwc2V1ZG8tbG9jYWxlICovCisgICAgTG9jYWxlSW5mbyBsb2NhbGU7CisKKyAgICAvKiBubyBwcmVjaXNpb24gYWxsb3dlZCBvbiBpbnRlZ2VycyAqLworICAgIGlmIChmb3JtYXQtPnByZWNpc2lvbiAhPSAtMSkgeworICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfVmFsdWVFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICJQcmVjaXNpb24gbm90IGFsbG93ZWQgaW4gaW50ZWdlciBmb3JtYXQgc3BlY2lmaWVyIik7CisgICAgICAgIGdvdG8gZG9uZTsKKyAgICB9CisKKyAgICAvKiBzcGVjaWFsIGNhc2UgZm9yIGNoYXJhY3RlciBmb3JtYXR0aW5nICovCisgICAgaWYgKGZvcm1hdC0+dHlwZSA9PSAnYycpIHsKKyAgICAgICAgLyogZXJyb3IgdG8gc3BlY2lmeSBhIHNpZ24gKi8KKyAgICAgICAgaWYgKGZvcm1hdC0+c2lnbiAhPSAnXDAnKSB7CisgICAgICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfVmFsdWVFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAiU2lnbiBub3QgYWxsb3dlZCB3aXRoIGludGVnZXIiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiBmb3JtYXQgc3BlY2lmaWVyICdjJyIpOworICAgICAgICAgICAgZ290byBkb25lOworICAgICAgICB9CisKKyAgICAgICAgLyogRXJyb3IgdG8gc3BlY2lmeSBhIGNvbW1hLiAqLworICAgICAgICBpZiAoZm9ybWF0LT50aG91c2FuZHNfc2VwYXJhdG9ycykgeworICAgICAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1ZhbHVlRXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlRob3VzYW5kcyBzZXBhcmF0b3JzIG5vdCBhbGxvd2VkIHdpdGggaW50ZWdlciIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAiIGZvcm1hdCBzcGVjaWZpZXIgJ2MnIik7CisgICAgICAgICAgICBnb3RvIGRvbmU7CisgICAgICAgIH0KKworICAgICAgICAvKiB0YWtlbiBmcm9tIHVuaWNvZGVvYmplY3QuYyBmb3JtYXRjaGFyKCkgKi8KKyAgICAgICAgLyogSW50ZWdlciBpbnB1dCB0cnVuY2F0ZWQgdG8gYSBjaGFyYWN0ZXIgKi8KKy8qIFhYWDogd29uJ3Qgd29yayBmb3IgaW50ICovCisgICAgICAgIHggPSBQeUxvbmdfQXNMb25nKHZhbHVlKTsKKyAgICAgICAgaWYgKHggPT0gLTEgJiYgUHlFcnJfT2NjdXJyZWQoKSkKKyAgICAgICAgICAgIGdvdG8gZG9uZTsKKyNpZmRlZiBQeV9VTklDT0RFX1dJREUKKyAgICAgICAgaWYgKHggPCAwIHx8IHggPiAweDEwZmZmZikgeworICAgICAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX092ZXJmbG93RXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiVjIGFyZyBub3QgaW4gcmFuZ2UoMHgxMTAwMDApICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAiKHdpZGUgUHl0aG9uIGJ1aWxkKSIpOworICAgICAgICAgICAgZ290byBkb25lOworICAgICAgICB9CisjZWxzZQorICAgICAgICBpZiAoeCA8IDAgfHwgeCA+IDB4ZmZmZikgeworICAgICAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX092ZXJmbG93RXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiVjIGFyZyBub3QgaW4gcmFuZ2UoMHgxMDAwMCkgIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICIobmFycm93IFB5dGhvbiBidWlsZCkiKTsKKyAgICAgICAgICAgIGdvdG8gZG9uZTsKKyAgICAgICAgfQorI2VuZGlmCisgICAgICAgIG51bWVyaWNfY2hhciA9IChTVFJJTkdMSUJfQ0hBUil4OworICAgICAgICBwbnVtZXJpY19jaGFycyA9ICZudW1lcmljX2NoYXI7CisgICAgICAgIG5fZGlnaXRzID0gMTsKKworICAgICAgICAvKiBBcyBhIHNvcnQtb2YgaGFjaywgd2UgdGVsbCBjYWxjX251bWJlcl93aWR0aHMgdGhhdCB3ZSBvbmx5CisgICAgICAgICAgIGhhdmUgInJlbWFpbmRlciIgY2hhcmFjdGVycy4gY2FsY19udW1iZXJfd2lkdGhzIHRoaW5rcworICAgICAgICAgICB0aGVzZSBhcmUgY2hhcmFjdGVycyB0aGF0IGRvbid0IGdldCBmb3JtYXR0ZWQsIG9ubHkgY29waWVkCisgICAgICAgICAgIGludG8gdGhlIG91dHB1dCBzdHJpbmcuIFdlIGRvIHRoaXMgZm9yICdjJyBmb3JtYXR0aW5nLAorICAgICAgICAgICBiZWNhdXNlIHRoZSBjaGFyYWN0ZXJzIGFyZSBsaWtlbHkgdG8gYmUgbm9uLWRpZ2l0cy4gKi8KKyAgICAgICAgbl9yZW1haW5kZXIgPSAxOworICAgIH0KKyAgICBlbHNlIHsKKyAgICAgICAgaW50IGJhc2U7CisgICAgICAgIGludCBsZWFkaW5nX2NoYXJzX3RvX3NraXAgPSAwOyAgLyogTnVtYmVyIG9mIGNoYXJhY3RlcnMgYWRkZWQgYnkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQeU51bWJlcl9Ub0Jhc2UgdGhhdCB3ZSB3YW50IHRvCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2tpcCBvdmVyLiAqLworCisgICAgICAgIC8qIENvbXB1dGUgdGhlIGJhc2UgYW5kIGhvdyBtYW55IGNoYXJhY3RlcnMgd2lsbCBiZSBhZGRlZCBieQorICAgICAgICAgICBQeU51bWJlcl9Ub0Jhc2UgKi8KKyAgICAgICAgc3dpdGNoIChmb3JtYXQtPnR5cGUpIHsKKyAgICAgICAgY2FzZSAnYic6CisgICAgICAgICAgICBiYXNlID0gMjsKKyAgICAgICAgICAgIGxlYWRpbmdfY2hhcnNfdG9fc2tpcCA9IDI7IC8qIDBiICovCisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgY2FzZSAnbyc6CisgICAgICAgICAgICBiYXNlID0gODsKKyAgICAgICAgICAgIGxlYWRpbmdfY2hhcnNfdG9fc2tpcCA9IDI7IC8qIDBvICovCisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgY2FzZSAneCc6CisgICAgICAgIGNhc2UgJ1gnOgorICAgICAgICAgICAgYmFzZSA9IDE2OworICAgICAgICAgICAgbGVhZGluZ19jaGFyc190b19za2lwID0gMjsgLyogMHggKi8KKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICBkZWZhdWx0OiAgLyogc2hvdWxkbid0IGJlIG5lZWRlZCwgYnV0IHN0b3BzIGEgY29tcGlsZXIgd2FybmluZyAqLworICAgICAgICBjYXNlICdkJzoKKyAgICAgICAgY2FzZSAnbic6CisgICAgICAgICAgICBiYXNlID0gMTA7CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgfQorCisgICAgICAgIC8qIFRoZSBudW1iZXIgb2YgcHJlZml4IGNoYXJzIGlzIHRoZSBzYW1lIGFzIHRoZSBsZWFkaW5nCisgICAgICAgICAgIGNoYXJzIHRvIHNraXAgKi8KKyAgICAgICAgaWYgKGZvcm1hdC0+YWx0ZXJuYXRlKQorICAgICAgICAgICAgbl9wcmVmaXggPSBsZWFkaW5nX2NoYXJzX3RvX3NraXA7CisKKyAgICAgICAgLyogRG8gdGhlIGhhcmQgcGFydCwgY29udmVydGluZyB0byBhIHN0cmluZyBpbiBhIGdpdmVuIGJhc2UgKi8KKyAgICAgICAgdG1wID0gdG9zdHJpbmcodmFsdWUsIGJhc2UpOworICAgICAgICBpZiAodG1wID09IE5VTEwpCisgICAgICAgICAgICBnb3RvIGRvbmU7CisKKyAgICAgICAgcG51bWVyaWNfY2hhcnMgPSBTVFJJTkdMSUJfU1RSKHRtcCk7CisgICAgICAgIG5fZGlnaXRzID0gU1RSSU5HTElCX0xFTih0bXApOworCisgICAgICAgIHByZWZpeCA9IHBudW1lcmljX2NoYXJzOworCisgICAgICAgIC8qIFJlbWVtYmVyIG5vdCB0byBtb2RpZnkgd2hhdCBwbnVtZXJpY19jaGFycyBwb2ludHMgdG8uICBpdAorICAgICAgICAgICBtaWdodCBiZSBpbnRlcm5lZC4gIE9ubHkgbW9kaWZ5IGl0IGFmdGVyIHdlIGNvcHkgaXQgaW50byBhCisgICAgICAgICAgIG5ld2x5IGFsbG9jYXRlZCBvdXRwdXQgYnVmZmVyLiAqLworCisgICAgICAgIC8qIElzIGEgc2lnbiBjaGFyYWN0ZXIgcHJlc2VudCBpbiB0aGUgb3V0cHV0PyAgSWYgc28sIHJlbWVtYmVyIGl0CisgICAgICAgICAgIGFuZCBza2lwIGl0ICovCisgICAgICAgIGlmIChwbnVtZXJpY19jaGFyc1swXSA9PSAnLScpIHsKKyAgICAgICAgICAgIHNpZ25fY2hhciA9IHBudW1lcmljX2NoYXJzWzBdOworICAgICAgICAgICAgKytwcmVmaXg7CisgICAgICAgICAgICArK2xlYWRpbmdfY2hhcnNfdG9fc2tpcDsKKyAgICAgICAgfQorCisgICAgICAgIC8qIFNraXAgb3ZlciB0aGUgbGVhZGluZyBjaGFycyAoMHgsIDBiLCBldGMuKSAqLworICAgICAgICBuX2RpZ2l0cyAtPSBsZWFkaW5nX2NoYXJzX3RvX3NraXA7CisgICAgICAgIHBudW1lcmljX2NoYXJzICs9IGxlYWRpbmdfY2hhcnNfdG9fc2tpcDsKKyAgICB9CisKKyAgICAvKiBEZXRlcm1pbmUgdGhlIGdyb3VwaW5nLCBzZXBhcmF0b3IsIGFuZCBkZWNpbWFsIHBvaW50LCBpZiBhbnkuICovCisgICAgZ2V0X2xvY2FsZV9pbmZvKGZvcm1hdC0+dHlwZSA9PSAnbicgPyBMVF9DVVJSRU5UX0xPQ0FMRSA6CisgICAgICAgICAgICAgICAgICAgIChmb3JtYXQtPnRob3VzYW5kc19zZXBhcmF0b3JzID8KKyAgICAgICAgICAgICAgICAgICAgIExUX0RFRkFVTFRfTE9DQUxFIDoKKyAgICAgICAgICAgICAgICAgICAgIExUX05PX0xPQ0FMRSksCisgICAgICAgICAgICAgICAgICAgICZsb2NhbGUpOworCisgICAgLyogQ2FsY3VsYXRlIGhvdyBtdWNoIG1lbW9yeSB3ZSdsbCBuZWVkLiAqLworICAgIG5fdG90YWwgPSBjYWxjX251bWJlcl93aWR0aHMoJnNwZWMsIG5fcHJlZml4LCBzaWduX2NoYXIsIHBudW1lcmljX2NoYXJzLAorICAgICAgICAgICAgICAgICAgICAgICBuX2RpZ2l0cywgbl9yZW1haW5kZXIsIDAsICZsb2NhbGUsIGZvcm1hdCk7CisKKyAgICAvKiBBbGxvY2F0ZSB0aGUgbWVtb3J5LiAqLworICAgIHJlc3VsdCA9IFNUUklOR0xJQl9ORVcoTlVMTCwgbl90b3RhbCk7CisgICAgaWYgKCFyZXN1bHQpCisgICAgICAgIGdvdG8gZG9uZTsKKworICAgIC8qIFBvcHVsYXRlIHRoZSBtZW1vcnkuICovCisgICAgZmlsbF9udW1iZXIoU1RSSU5HTElCX1NUUihyZXN1bHQpLCAmc3BlYywgcG51bWVyaWNfY2hhcnMsIG5fZGlnaXRzLAorICAgICAgICAgICAgICAgIHByZWZpeCwgZm9ybWF0LT5maWxsX2NoYXIgPT0gJ1wwJyA/ICcgJyA6IGZvcm1hdC0+ZmlsbF9jaGFyLAorICAgICAgICAgICAgICAgICZsb2NhbGUsIGZvcm1hdC0+dHlwZSA9PSAnWCcpOworCitkb25lOgorICAgIFB5X1hERUNSRUYodG1wKTsKKyAgICByZXR1cm4gcmVzdWx0OworfQorI2VuZGlmIC8qIGRlZmluZWQgRk9STUFUX0xPTkcgfHwgZGVmaW5lZCBGT1JNQVRfSU5UICovCisKKy8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCisvKioqKioqKioqKiogZmxvYXQgZm9ybWF0dGluZyAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLworLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KKworI2lmZGVmIEZPUk1BVF9GTE9BVAorI2lmIFNUUklOR0xJQl9JU19VTklDT0RFCitzdGF0aWMgdm9pZAorc3RydG91bmljb2RlKFB5X1VOSUNPREUgKmJ1ZmZlciwgY29uc3QgY2hhciAqY2hhcmJ1ZmZlciwgUHlfc3NpemVfdCBsZW4pCit7CisgICAgUHlfc3NpemVfdCBpOworICAgIGZvciAoaSA9IDA7IGkgPCBsZW47ICsraSkKKyAgICAgICAgYnVmZmVyW2ldID0gKFB5X1VOSUNPREUpY2hhcmJ1ZmZlcltpXTsKK30KKyNlbmRpZgorCisvKiBtdWNoIG9mIHRoaXMgaXMgdGFrZW4gZnJvbSB1bmljb2Rlb2JqZWN0LmMgKi8KK3N0YXRpYyBQeU9iamVjdCAqCitmb3JtYXRfZmxvYXRfaW50ZXJuYWwoUHlPYmplY3QgKnZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IEludGVybmFsRm9ybWF0U3BlYyAqZm9ybWF0KQoreworICAgIGNoYXIgKmJ1ZiA9IE5VTEw7ICAgICAgIC8qIGJ1ZmZlciByZXR1cm5lZCBmcm9tIFB5T1NfZG91YmxlX3RvX3N0cmluZyAqLworICAgIFB5X3NzaXplX3Qgbl9kaWdpdHM7CisgICAgUHlfc3NpemVfdCBuX3JlbWFpbmRlcjsKKyAgICBQeV9zc2l6ZV90IG5fdG90YWw7CisgICAgaW50IGhhc19kZWNpbWFsOworICAgIGRvdWJsZSB2YWw7CisgICAgUHlfc3NpemVfdCBwcmVjaXNpb24gPSBmb3JtYXQtPnByZWNpc2lvbjsKKyAgICBQeV9zc2l6ZV90IGRlZmF1bHRfcHJlY2lzaW9uID0gNjsKKyAgICBTVFJJTkdMSUJfQ0hBUiB0eXBlID0gZm9ybWF0LT50eXBlOworICAgIGludCBhZGRfcGN0ID0gMDsKKyAgICBTVFJJTkdMSUJfQ0hBUiAqcDsKKyAgICBOdW1iZXJGaWVsZFdpZHRocyBzcGVjOworICAgIGludCBmbGFncyA9IDA7CisgICAgUHlPYmplY3QgKnJlc3VsdCA9IE5VTEw7CisgICAgU1RSSU5HTElCX0NIQVIgc2lnbl9jaGFyID0gJ1wwJzsKKyAgICBpbnQgZmxvYXRfdHlwZTsgLyogVXNlZCB0byBzZWUgaWYgd2UgaGF2ZSBhIG5hbiwgaW5mLCBvciByZWd1bGFyIGZsb2F0LiAqLworCisjaWYgU1RSSU5HTElCX0lTX1VOSUNPREUKKyAgICBQeV9VTklDT0RFICp1bmljb2RlX3RtcCA9IE5VTEw7CisjZW5kaWYKKworICAgIC8qIExvY2FsZSBzZXR0aW5ncywgZWl0aGVyIGZyb20gdGhlIGFjdHVhbCBsb2NhbGUgb3IKKyAgICAgICBmcm9tIGEgaGFyZC1jb2RlIHBzZXVkby1sb2NhbGUgKi8KKyAgICBMb2NhbGVJbmZvIGxvY2FsZTsKKworICAgIC8qIEFsdGVybmF0ZSBpcyBub3QgYWxsb3dlZCBvbiBmbG9hdHMuICovCisgICAgaWYgKGZvcm1hdC0+YWx0ZXJuYXRlKSB7CisgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19WYWx1ZUVycm9yLAorICAgICAgICAgICAgICAgICAgICAgICAgIkFsdGVybmF0ZSBmb3JtICgjKSBub3QgYWxsb3dlZCBpbiBmbG9hdCBmb3JtYXQgIgorICAgICAgICAgICAgICAgICAgICAgICAgInNwZWNpZmllciIpOworICAgICAgICBnb3RvIGRvbmU7CisgICAgfQorCisgICAgaWYgKHR5cGUgPT0gJ1wwJykgeworICAgICAgICAvKiBPbWl0dGVkIHR5cGUgc3BlY2lmaWVyLiBUaGlzIGlzIGxpa2UgJ2cnIGJ1dCB3aXRoIGF0IGxlYXN0IG9uZQorICAgICAgICAgICBkaWdpdCBhZnRlciB0aGUgZGVjaW1hbCBwb2ludCwgYW5kIGRpZmZlcmVudCBkZWZhdWx0IHByZWNpc2lvbi4qLworICAgICAgICB0eXBlID0gJ2cnOworICAgICAgICBkZWZhdWx0X3ByZWNpc2lvbiA9IFB5RmxvYXRfU1RSX1BSRUNJU0lPTjsKKyAgICAgICAgZmxhZ3MgfD0gUHlfRFRTRl9BRERfRE9UXzA7CisgICAgfQorCisgICAgaWYgKHR5cGUgPT0gJ24nKQorICAgICAgICAvKiAnbicgaXMgdGhlIHNhbWUgYXMgJ2cnLCBleGNlcHQgZm9yIHRoZSBsb2NhbGUgdXNlZCB0bworICAgICAgICAgICBmb3JtYXQgdGhlIHJlc3VsdC4gV2UgdGFrZSBjYXJlIG9mIHRoYXQgbGF0ZXIuICovCisgICAgICAgIHR5cGUgPSAnZyc7CisKKyAgICB2YWwgPSBQeUZsb2F0X0FzRG91YmxlKHZhbHVlKTsKKyAgICBpZiAodmFsID09IC0xLjAgJiYgUHlFcnJfT2NjdXJyZWQoKSkKKyAgICAgICAgZ290byBkb25lOworCisgICAgaWYgKHR5cGUgPT0gJyUnKSB7CisgICAgICAgIHR5cGUgPSAnZic7CisgICAgICAgIHZhbCAqPSAxMDA7CisgICAgICAgIGFkZF9wY3QgPSAxOworICAgIH0KKworICAgIGlmIChwcmVjaXNpb24gPCAwKQorICAgICAgICBwcmVjaXNpb24gPSBkZWZhdWx0X3ByZWNpc2lvbjsKKworICAgIC8qIENhc3QgInR5cGUiLCBiZWNhdXNlIGlmIHdlJ3JlIGluIHVuaWNvZGUgd2UgbmVlZCB0byBwYXNzIGEKKyAgICAgICA4LWJpdCBjaGFyLiBUaGlzIGlzIHNhZmUsIGJlY2F1c2Ugd2UndmUgcmVzdHJpY3RlZCB3aGF0ICJ0eXBlIgorICAgICAgIGNhbiBiZS4gKi8KKyAgICBidWYgPSBQeU9TX2RvdWJsZV90b19zdHJpbmcodmFsLCAoY2hhcil0eXBlLCBwcmVjaXNpb24sIGZsYWdzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmZmxvYXRfdHlwZSk7CisgICAgaWYgKGJ1ZiA9PSBOVUxMKQorICAgICAgICBnb3RvIGRvbmU7CisgICAgbl9kaWdpdHMgPSBzdHJsZW4oYnVmKTsKKworICAgIGlmIChhZGRfcGN0KSB7CisgICAgICAgIC8qIFdlIGtub3cgdGhhdCBidWYgaGFzIGEgdHJhaWxpbmcgemVybyAoc2luY2Ugd2UganVzdCBjYWxsZWQKKyAgICAgICAgICAgc3RybGVuKCkgb24gaXQpLCBhbmQgd2UgZG9uJ3QgdXNlIHRoYXQgZmFjdCBhbnkgbW9yZS4gU28gd2UKKyAgICAgICAgICAgY2FuIGp1c3Qgd3JpdGUgb3ZlciB0aGUgdHJhaWxpbmcgemVyby4gKi8KKyAgICAgICAgYnVmW25fZGlnaXRzXSA9ICclJzsKKyAgICAgICAgbl9kaWdpdHMgKz0gMTsKKyAgICB9CisKKyAgICAvKiBTaW5jZSB0aGVyZSBpcyBubyB1bmljb2RlIHZlcnNpb24gb2YgUHlPU19kb3VibGVfdG9fc3RyaW5nLAorICAgICAgIGp1c3QgdXNlIHRoZSA4IGJpdCB2ZXJzaW9uIGFuZCB0aGVuIGNvbnZlcnQgdG8gdW5pY29kZS4gKi8KKyNpZiBTVFJJTkdMSUJfSVNfVU5JQ09ERQorICAgIHVuaWNvZGVfdG1wID0gKFB5X1VOSUNPREUqKVB5TWVtX01hbGxvYygobl9kaWdpdHMpKnNpemVvZihQeV9VTklDT0RFKSk7CisgICAgaWYgKHVuaWNvZGVfdG1wID09IE5VTEwpIHsKKyAgICAgICAgUHlFcnJfTm9NZW1vcnkoKTsKKyAgICAgICAgZ290byBkb25lOworICAgIH0KKyAgICBzdHJ0b3VuaWNvZGUodW5pY29kZV90bXAsIGJ1Ziwgbl9kaWdpdHMpOworICAgIHAgPSB1bmljb2RlX3RtcDsKKyNlbHNlCisgICAgcCA9IGJ1ZjsKKyNlbmRpZgorCisgICAgLyogSXMgYSBzaWduIGNoYXJhY3RlciBwcmVzZW50IGluIHRoZSBvdXRwdXQ/ICBJZiBzbywgcmVtZW1iZXIgaXQKKyAgICAgICBhbmQgc2tpcCBpdCAqLworICAgIGlmICgqcCA9PSAnLScpIHsKKyAgICAgICAgc2lnbl9jaGFyID0gKnA7CisgICAgICAgICsrcDsKKyAgICAgICAgLS1uX2RpZ2l0czsKKyAgICB9CisKKyAgICAvKiBEZXRlcm1pbmUgaWYgd2UgaGF2ZSBhbnkgInJlbWFpbmRlciIgKGFmdGVyIHRoZSBkaWdpdHMsIG1pZ2h0IGluY2x1ZGUKKyAgICAgICBkZWNpbWFsIG9yIGV4cG9uZW50IG9yIGJvdGggKG9yIG5laXRoZXIpKSAqLworICAgIHBhcnNlX251bWJlcihwLCBuX2RpZ2l0cywgJm5fcmVtYWluZGVyLCAmaGFzX2RlY2ltYWwpOworCisgICAgLyogRGV0ZXJtaW5lIHRoZSBncm91cGluZywgc2VwYXJhdG9yLCBhbmQgZGVjaW1hbCBwb2ludCwgaWYgYW55LiAqLworICAgIGdldF9sb2NhbGVfaW5mbyhmb3JtYXQtPnR5cGUgPT0gJ24nID8gTFRfQ1VSUkVOVF9MT0NBTEUgOgorICAgICAgICAgICAgICAgICAgICAoZm9ybWF0LT50aG91c2FuZHNfc2VwYXJhdG9ycyA/CisgICAgICAgICAgICAgICAgICAgICBMVF9ERUZBVUxUX0xPQ0FMRSA6CisgICAgICAgICAgICAgICAgICAgICBMVF9OT19MT0NBTEUpLAorICAgICAgICAgICAgICAgICAgICAmbG9jYWxlKTsKKworICAgIC8qIENhbGN1bGF0ZSBob3cgbXVjaCBtZW1vcnkgd2UnbGwgbmVlZC4gKi8KKyAgICBuX3RvdGFsID0gY2FsY19udW1iZXJfd2lkdGhzKCZzcGVjLCAwLCBzaWduX2NoYXIsIHAsIG5fZGlnaXRzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbl9yZW1haW5kZXIsIGhhc19kZWNpbWFsLCAmbG9jYWxlLCBmb3JtYXQpOworCisgICAgLyogQWxsb2NhdGUgdGhlIG1lbW9yeS4gKi8KKyAgICByZXN1bHQgPSBTVFJJTkdMSUJfTkVXKE5VTEwsIG5fdG90YWwpOworICAgIGlmIChyZXN1bHQgPT0gTlVMTCkKKyAgICAgICAgZ290byBkb25lOworCisgICAgLyogUG9wdWxhdGUgdGhlIG1lbW9yeS4gKi8KKyAgICBmaWxsX251bWJlcihTVFJJTkdMSUJfU1RSKHJlc3VsdCksICZzcGVjLCBwLCBuX2RpZ2l0cywgTlVMTCwKKyAgICAgICAgICAgICAgICBmb3JtYXQtPmZpbGxfY2hhciA9PSAnXDAnID8gJyAnIDogZm9ybWF0LT5maWxsX2NoYXIsICZsb2NhbGUsCisgICAgICAgICAgICAgICAgMCk7CisKK2RvbmU6CisgICAgUHlNZW1fRnJlZShidWYpOworI2lmIFNUUklOR0xJQl9JU19VTklDT0RFCisgICAgUHlNZW1fRnJlZSh1bmljb2RlX3RtcCk7CisjZW5kaWYKKyAgICByZXR1cm4gcmVzdWx0OworfQorI2VuZGlmIC8qIEZPUk1BVF9GTE9BVCAqLworCisvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLworLyoqKioqKioqKioqIGNvbXBsZXggZm9ybWF0dGluZyAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KKy8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCisKKyNpZmRlZiBGT1JNQVRfQ09NUExFWAorCitzdGF0aWMgUHlPYmplY3QgKgorZm9ybWF0X2NvbXBsZXhfaW50ZXJuYWwoUHlPYmplY3QgKnZhbHVlLAorICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgSW50ZXJuYWxGb3JtYXRTcGVjICpmb3JtYXQpCit7CisgICAgZG91YmxlIHJlOworICAgIGRvdWJsZSBpbTsKKyAgICBjaGFyICpyZV9idWYgPSBOVUxMOyAgICAgICAvKiBidWZmZXIgcmV0dXJuZWQgZnJvbSBQeU9TX2RvdWJsZV90b19zdHJpbmcgKi8KKyAgICBjaGFyICppbV9idWYgPSBOVUxMOyAgICAgICAvKiBidWZmZXIgcmV0dXJuZWQgZnJvbSBQeU9TX2RvdWJsZV90b19zdHJpbmcgKi8KKworICAgIEludGVybmFsRm9ybWF0U3BlYyB0bXBfZm9ybWF0ID0gKmZvcm1hdDsKKyAgICBQeV9zc2l6ZV90IG5fcmVfZGlnaXRzOworICAgIFB5X3NzaXplX3Qgbl9pbV9kaWdpdHM7CisgICAgUHlfc3NpemVfdCBuX3JlX3JlbWFpbmRlcjsKKyAgICBQeV9zc2l6ZV90IG5faW1fcmVtYWluZGVyOworICAgIFB5X3NzaXplX3Qgbl9yZV90b3RhbDsKKyAgICBQeV9zc2l6ZV90IG5faW1fdG90YWw7CisgICAgaW50IHJlX2hhc19kZWNpbWFsOworICAgIGludCBpbV9oYXNfZGVjaW1hbDsKKyAgICBQeV9zc2l6ZV90IHByZWNpc2lvbiA9IGZvcm1hdC0+cHJlY2lzaW9uOworICAgIFB5X3NzaXplX3QgZGVmYXVsdF9wcmVjaXNpb24gPSA2OworICAgIFNUUklOR0xJQl9DSEFSIHR5cGUgPSBmb3JtYXQtPnR5cGU7CisgICAgU1RSSU5HTElCX0NIQVIgKnBfcmU7CisgICAgU1RSSU5HTElCX0NIQVIgKnBfaW07CisgICAgTnVtYmVyRmllbGRXaWR0aHMgcmVfc3BlYzsKKyAgICBOdW1iZXJGaWVsZFdpZHRocyBpbV9zcGVjOworICAgIGludCBmbGFncyA9IDA7CisgICAgUHlPYmplY3QgKnJlc3VsdCA9IE5VTEw7CisgICAgU1RSSU5HTElCX0NIQVIgKnA7CisgICAgU1RSSU5HTElCX0NIQVIgcmVfc2lnbl9jaGFyID0gJ1wwJzsKKyAgICBTVFJJTkdMSUJfQ0hBUiBpbV9zaWduX2NoYXIgPSAnXDAnOworICAgIGludCByZV9mbG9hdF90eXBlOyAvKiBVc2VkIHRvIHNlZSBpZiB3ZSBoYXZlIGEgbmFuLCBpbmYsIG9yIHJlZ3VsYXIgZmxvYXQuICovCisgICAgaW50IGltX2Zsb2F0X3R5cGU7CisgICAgaW50IGFkZF9wYXJlbnMgPSAwOworICAgIGludCBza2lwX3JlID0gMDsKKyAgICBQeV9zc2l6ZV90IGxwYWQ7CisgICAgUHlfc3NpemVfdCBycGFkOworICAgIFB5X3NzaXplX3QgdG90YWw7CisKKyNpZiBTVFJJTkdMSUJfSVNfVU5JQ09ERQorICAgIFB5X1VOSUNPREUgKnJlX3VuaWNvZGVfdG1wID0gTlVMTDsKKyAgICBQeV9VTklDT0RFICppbV91bmljb2RlX3RtcCA9IE5VTEw7CisjZW5kaWYKKworICAgIC8qIExvY2FsZSBzZXR0aW5ncywgZWl0aGVyIGZyb20gdGhlIGFjdHVhbCBsb2NhbGUgb3IKKyAgICAgICBmcm9tIGEgaGFyZC1jb2RlIHBzZXVkby1sb2NhbGUgKi8KKyAgICBMb2NhbGVJbmZvIGxvY2FsZTsKKworICAgIC8qIEFsdGVybmF0ZSBpcyBub3QgYWxsb3dlZCBvbiBjb21wbGV4LiAqLworICAgIGlmIChmb3JtYXQtPmFsdGVybmF0ZSkgeworICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfVmFsdWVFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICJBbHRlcm5hdGUgZm9ybSAoIykgbm90IGFsbG93ZWQgaW4gY29tcGxleCBmb3JtYXQgIgorICAgICAgICAgICAgICAgICAgICAgICAgInNwZWNpZmllciIpOworICAgICAgICBnb3RvIGRvbmU7CisgICAgfQorCisgICAgLyogTmVpdGhlciBpcyB6ZXJvIHBhZGluZy4gKi8KKyAgICBpZiAoZm9ybWF0LT5maWxsX2NoYXIgPT0gJzAnKSB7CisgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19WYWx1ZUVycm9yLAorICAgICAgICAgICAgICAgICAgICAgICAgIlplcm8gcGFkZGluZyBpcyBub3QgYWxsb3dlZCBpbiBjb21wbGV4IGZvcm1hdCAiCisgICAgICAgICAgICAgICAgICAgICAgICAic3BlY2lmaWVyIik7CisgICAgICAgIGdvdG8gZG9uZTsKKyAgICB9CisKKyAgICAvKiBOZWl0aGVyIGlzICc9JyBhbGlnbm1lbnQgLiAqLworICAgIGlmIChmb3JtYXQtPmFsaWduID09ICc9JykgeworICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfVmFsdWVFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICInPScgYWxpZ25tZW50IGZsYWcgaXMgbm90IGFsbG93ZWQgaW4gY29tcGxleCBmb3JtYXQgIgorICAgICAgICAgICAgICAgICAgICAgICAgInNwZWNpZmllciIpOworICAgICAgICBnb3RvIGRvbmU7CisgICAgfQorCisgICAgcmUgPSBQeUNvbXBsZXhfUmVhbEFzRG91YmxlKHZhbHVlKTsKKyAgICBpZiAocmUgPT0gLTEuMCAmJiBQeUVycl9PY2N1cnJlZCgpKQorICAgICAgICBnb3RvIGRvbmU7CisgICAgaW0gPSBQeUNvbXBsZXhfSW1hZ0FzRG91YmxlKHZhbHVlKTsKKyAgICBpZiAoaW0gPT0gLTEuMCAmJiBQeUVycl9PY2N1cnJlZCgpKQorICAgICAgICBnb3RvIGRvbmU7CisKKyAgICBpZiAodHlwZSA9PSAnXDAnKSB7CisgICAgICAgIC8qIE9taXR0ZWQgdHlwZSBzcGVjaWZpZXIuIFNob3VsZCBiZSBsaWtlIHN0cihzZWxmKS4gKi8KKyAgICAgICAgdHlwZSA9ICdnJzsKKyAgICAgICAgZGVmYXVsdF9wcmVjaXNpb24gPSBQeUZsb2F0X1NUUl9QUkVDSVNJT047CisgICAgICAgIGlmIChyZSA9PSAwLjAgJiYgY29weXNpZ24oMS4wLCByZSkgPT0gMS4wKQorICAgICAgICAgICAgc2tpcF9yZSA9IDE7CisgICAgICAgIGVsc2UKKyAgICAgICAgICAgIGFkZF9wYXJlbnMgPSAxOworICAgIH0KKworICAgIGlmICh0eXBlID09ICduJykKKyAgICAgICAgLyogJ24nIGlzIHRoZSBzYW1lIGFzICdnJywgZXhjZXB0IGZvciB0aGUgbG9jYWxlIHVzZWQgdG8KKyAgICAgICAgICAgZm9ybWF0IHRoZSByZXN1bHQuIFdlIHRha2UgY2FyZSBvZiB0aGF0IGxhdGVyLiAqLworICAgICAgICB0eXBlID0gJ2cnOworCisgICAgaWYgKHByZWNpc2lvbiA8IDApCisgICAgICAgIHByZWNpc2lvbiA9IGRlZmF1bHRfcHJlY2lzaW9uOworCisgICAgLyogQ2FzdCAidHlwZSIsIGJlY2F1c2UgaWYgd2UncmUgaW4gdW5pY29kZSB3ZSBuZWVkIHRvIHBhc3MgYQorICAgICAgIDgtYml0IGNoYXIuIFRoaXMgaXMgc2FmZSwgYmVjYXVzZSB3ZSd2ZSByZXN0cmljdGVkIHdoYXQgInR5cGUiCisgICAgICAgY2FuIGJlLiAqLworICAgIHJlX2J1ZiA9IFB5T1NfZG91YmxlX3RvX3N0cmluZyhyZSwgKGNoYXIpdHlwZSwgcHJlY2lzaW9uLCBmbGFncywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnJlX2Zsb2F0X3R5cGUpOworICAgIGlmIChyZV9idWYgPT0gTlVMTCkKKyAgICAgICAgZ290byBkb25lOworICAgIGltX2J1ZiA9IFB5T1NfZG91YmxlX3RvX3N0cmluZyhpbSwgKGNoYXIpdHlwZSwgcHJlY2lzaW9uLCBmbGFncywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJmltX2Zsb2F0X3R5cGUpOworICAgIGlmIChpbV9idWYgPT0gTlVMTCkKKyAgICAgICAgZ290byBkb25lOworCisgICAgbl9yZV9kaWdpdHMgPSBzdHJsZW4ocmVfYnVmKTsKKyAgICBuX2ltX2RpZ2l0cyA9IHN0cmxlbihpbV9idWYpOworCisgICAgLyogU2luY2UgdGhlcmUgaXMgbm8gdW5pY29kZSB2ZXJzaW9uIG9mIFB5T1NfZG91YmxlX3RvX3N0cmluZywKKyAgICAgICBqdXN0IHVzZSB0aGUgOCBiaXQgdmVyc2lvbiBhbmQgdGhlbiBjb252ZXJ0IHRvIHVuaWNvZGUuICovCisjaWYgU1RSSU5HTElCX0lTX1VOSUNPREUKKyAgICByZV91bmljb2RlX3RtcCA9IChQeV9VTklDT0RFKilQeU1lbV9NYWxsb2MoKG5fcmVfZGlnaXRzKSpzaXplb2YoUHlfVU5JQ09ERSkpOworICAgIGlmIChyZV91bmljb2RlX3RtcCA9PSBOVUxMKSB7CisgICAgICAgIFB5RXJyX05vTWVtb3J5KCk7CisgICAgICAgIGdvdG8gZG9uZTsKKyAgICB9CisgICAgc3RydG91bmljb2RlKHJlX3VuaWNvZGVfdG1wLCByZV9idWYsIG5fcmVfZGlnaXRzKTsKKyAgICBwX3JlID0gcmVfdW5pY29kZV90bXA7CisKKyAgICBpbV91bmljb2RlX3RtcCA9IChQeV9VTklDT0RFKilQeU1lbV9NYWxsb2MoKG5faW1fZGlnaXRzKSpzaXplb2YoUHlfVU5JQ09ERSkpOworICAgIGlmIChpbV91bmljb2RlX3RtcCA9PSBOVUxMKSB7CisgICAgICAgIFB5RXJyX05vTWVtb3J5KCk7CisgICAgICAgIGdvdG8gZG9uZTsKKyAgICB9CisgICAgc3RydG91bmljb2RlKGltX3VuaWNvZGVfdG1wLCBpbV9idWYsIG5faW1fZGlnaXRzKTsKKyAgICBwX2ltID0gaW1fdW5pY29kZV90bXA7CisjZWxzZQorICAgIHBfcmUgPSByZV9idWY7CisgICAgcF9pbSA9IGltX2J1ZjsKKyNlbmRpZgorCisgICAgLyogSXMgYSBzaWduIGNoYXJhY3RlciBwcmVzZW50IGluIHRoZSBvdXRwdXQ/ICBJZiBzbywgcmVtZW1iZXIgaXQKKyAgICAgICBhbmQgc2tpcCBpdCAqLworICAgIGlmICgqcF9yZSA9PSAnLScpIHsKKyAgICAgICAgcmVfc2lnbl9jaGFyID0gKnBfcmU7CisgICAgICAgICsrcF9yZTsKKyAgICAgICAgLS1uX3JlX2RpZ2l0czsKKyAgICB9CisgICAgaWYgKCpwX2ltID09ICctJykgeworICAgICAgICBpbV9zaWduX2NoYXIgPSAqcF9pbTsKKyAgICAgICAgKytwX2ltOworICAgICAgICAtLW5faW1fZGlnaXRzOworICAgIH0KKworICAgIC8qIERldGVybWluZSBpZiB3ZSBoYXZlIGFueSAicmVtYWluZGVyIiAoYWZ0ZXIgdGhlIGRpZ2l0cywgbWlnaHQgaW5jbHVkZQorICAgICAgIGRlY2ltYWwgb3IgZXhwb25lbnQgb3IgYm90aCAob3IgbmVpdGhlcikpICovCisgICAgcGFyc2VfbnVtYmVyKHBfcmUsIG5fcmVfZGlnaXRzLCAmbl9yZV9yZW1haW5kZXIsICZyZV9oYXNfZGVjaW1hbCk7CisgICAgcGFyc2VfbnVtYmVyKHBfaW0sIG5faW1fZGlnaXRzLCAmbl9pbV9yZW1haW5kZXIsICZpbV9oYXNfZGVjaW1hbCk7CisKKyAgICAvKiBEZXRlcm1pbmUgdGhlIGdyb3VwaW5nLCBzZXBhcmF0b3IsIGFuZCBkZWNpbWFsIHBvaW50LCBpZiBhbnkuICovCisgICAgZ2V0X2xvY2FsZV9pbmZvKGZvcm1hdC0+dHlwZSA9PSAnbicgPyBMVF9DVVJSRU5UX0xPQ0FMRSA6CisgICAgICAgICAgICAgICAgICAgIChmb3JtYXQtPnRob3VzYW5kc19zZXBhcmF0b3JzID8KKyAgICAgICAgICAgICAgICAgICAgIExUX0RFRkFVTFRfTE9DQUxFIDoKKyAgICAgICAgICAgICAgICAgICAgIExUX05PX0xPQ0FMRSksCisgICAgICAgICAgICAgICAgICAgICZsb2NhbGUpOworCisgICAgLyogVHVybiBvZmYgYW55IHBhZGRpbmcuIFdlJ2xsIGRvIGl0IGxhdGVyIGFmdGVyIHdlJ3ZlIGNvbXBvc2VkCisgICAgICAgdGhlIG51bWJlcnMgd2l0aG91dCBwYWRkaW5nLiAqLworICAgIHRtcF9mb3JtYXQuZmlsbF9jaGFyID0gJ1wwJzsKKyAgICB0bXBfZm9ybWF0LmFsaWduID0gJzwnOworICAgIHRtcF9mb3JtYXQud2lkdGggPSAtMTsKKworICAgIC8qIENhbGN1bGF0ZSBob3cgbXVjaCBtZW1vcnkgd2UnbGwgbmVlZC4gKi8KKyAgICBuX3JlX3RvdGFsID0gY2FsY19udW1iZXJfd2lkdGhzKCZyZV9zcGVjLCAwLCByZV9zaWduX2NoYXIsIHBfcmUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuX3JlX2RpZ2l0cywgbl9yZV9yZW1haW5kZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZV9oYXNfZGVjaW1hbCwgJmxvY2FsZSwgJnRtcF9mb3JtYXQpOworCisgICAgLyogU2FtZSBmb3JtYXR0aW5nLCBidXQgYWx3YXlzIGluY2x1ZGUgYSBzaWduLCB1bmxlc3MgdGhlIHJlYWwgcGFydCBpcworICAgICAqIGdvaW5nIHRvIGJlIG9taXR0ZWQsIGluIHdoaWNoIGNhc2Ugd2UgdXNlIHdoYXRldmVyIHNpZ24gY29udmVudGlvbiB3YXMKKyAgICAgKiByZXF1ZXN0ZWQgYnkgdGhlIG9yaWdpbmFsIGZvcm1hdC4gKi8KKyAgICBpZiAoIXNraXBfcmUpCisgICAgICAgIHRtcF9mb3JtYXQuc2lnbiA9ICcrJzsKKyAgICBuX2ltX3RvdGFsID0gY2FsY19udW1iZXJfd2lkdGhzKCZpbV9zcGVjLCAwLCBpbV9zaWduX2NoYXIsIHBfaW0sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuX2ltX2RpZ2l0cywgbl9pbV9yZW1haW5kZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbV9oYXNfZGVjaW1hbCwgJmxvY2FsZSwgJnRtcF9mb3JtYXQpOworCisgICAgaWYgKHNraXBfcmUpCisgICAgICAgIG5fcmVfdG90YWwgPSAwOworCisgICAgLyogQWRkIDEgZm9yIHRoZSAnaicsIGFuZCBvcHRpb25hbGx5IDIgZm9yIHBhcmVucy4gKi8KKyAgICBjYWxjX3BhZGRpbmcobl9yZV90b3RhbCArIG5faW1fdG90YWwgKyAxICsgYWRkX3BhcmVucyAqIDIsCisgICAgICAgICAgICAgICAgIGZvcm1hdC0+d2lkdGgsIGZvcm1hdC0+YWxpZ24sICZscGFkLCAmcnBhZCwgJnRvdGFsKTsKKworICAgIHJlc3VsdCA9IFNUUklOR0xJQl9ORVcoTlVMTCwgdG90YWwpOworICAgIGlmIChyZXN1bHQgPT0gTlVMTCkKKyAgICAgICAgZ290byBkb25lOworCisgICAgLyogUG9wdWxhdGUgdGhlIG1lbW9yeS4gRmlyc3QsIHRoZSBwYWRkaW5nLiAqLworICAgIHAgPSBmaWxsX3BhZGRpbmcoU1RSSU5HTElCX1NUUihyZXN1bHQpLAorICAgICAgICAgICAgICAgICAgICAgbl9yZV90b3RhbCArIG5faW1fdG90YWwgKyAxICsgYWRkX3BhcmVucyAqIDIsCisgICAgICAgICAgICAgICAgICAgICBmb3JtYXQtPmZpbGxfY2hhcj09J1wwJyA/ICcgJyA6IGZvcm1hdC0+ZmlsbF9jaGFyLAorICAgICAgICAgICAgICAgICAgICAgbHBhZCwgcnBhZCk7CisKKyAgICBpZiAoYWRkX3BhcmVucykKKyAgICAgICAgKnArKyA9ICcoJzsKKworICAgIGlmICghc2tpcF9yZSkgeworICAgICAgICBmaWxsX251bWJlcihwLCAmcmVfc3BlYywgcF9yZSwgbl9yZV9kaWdpdHMsIE5VTEwsIDAsICZsb2NhbGUsIDApOworICAgICAgICBwICs9IG5fcmVfdG90YWw7CisgICAgfQorICAgIGZpbGxfbnVtYmVyKHAsICZpbV9zcGVjLCBwX2ltLCBuX2ltX2RpZ2l0cywgTlVMTCwgMCwgJmxvY2FsZSwgMCk7CisgICAgcCArPSBuX2ltX3RvdGFsOworICAgICpwKysgPSAnaic7CisKKyAgICBpZiAoYWRkX3BhcmVucykKKyAgICAgICAgKnArKyA9ICcpJzsKKworZG9uZToKKyAgICBQeU1lbV9GcmVlKHJlX2J1Zik7CisgICAgUHlNZW1fRnJlZShpbV9idWYpOworI2lmIFNUUklOR0xJQl9JU19VTklDT0RFCisgICAgUHlNZW1fRnJlZShyZV91bmljb2RlX3RtcCk7CisgICAgUHlNZW1fRnJlZShpbV91bmljb2RlX3RtcCk7CisjZW5kaWYKKyAgICByZXR1cm4gcmVzdWx0OworfQorI2VuZGlmIC8qIEZPUk1BVF9DT01QTEVYICovCisKKy8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCisvKioqKioqKioqKiogYnVpbHQgaW4gZm9ybWF0dGVycyAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLworLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KK1B5T2JqZWN0ICoKK0ZPUk1BVF9TVFJJTkcoUHlPYmplY3QgKm9iaiwKKyAgICAgICAgICAgICAgU1RSSU5HTElCX0NIQVIgKmZvcm1hdF9zcGVjLAorICAgICAgICAgICAgICBQeV9zc2l6ZV90IGZvcm1hdF9zcGVjX2xlbikKK3sKKyAgICBJbnRlcm5hbEZvcm1hdFNwZWMgZm9ybWF0OworICAgIFB5T2JqZWN0ICpyZXN1bHQgPSBOVUxMOworCisgICAgLyogY2hlY2sgZm9yIHRoZSBzcGVjaWFsIGNhc2Ugb2YgemVybyBsZW5ndGggZm9ybWF0IHNwZWMsIG1ha2UKKyAgICAgICBpdCBlcXVpdmFsZW50IHRvIHN0cihvYmopICovCisgICAgaWYgKGZvcm1hdF9zcGVjX2xlbiA9PSAwKSB7CisgICAgICAgIHJlc3VsdCA9IFNUUklOR0xJQl9UT1NUUihvYmopOworICAgICAgICBnb3RvIGRvbmU7CisgICAgfQorCisgICAgLyogcGFyc2UgdGhlIGZvcm1hdF9zcGVjICovCisgICAgaWYgKCFwYXJzZV9pbnRlcm5hbF9yZW5kZXJfZm9ybWF0X3NwZWMoZm9ybWF0X3NwZWMsIGZvcm1hdF9zcGVjX2xlbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmZm9ybWF0LCAncycsICc8JykpCisgICAgICAgIGdvdG8gZG9uZTsKKworICAgIC8qIHR5cGUgY29udmVyc2lvbj8gKi8KKyAgICBzd2l0Y2ggKGZvcm1hdC50eXBlKSB7CisgICAgY2FzZSAncyc6CisgICAgICAgIC8qIG5vIHR5cGUgY29udmVyc2lvbiBuZWVkZWQsIGFscmVhZHkgYSBzdHJpbmcuICBkbyB0aGUgZm9ybWF0dGluZyAqLworICAgICAgICByZXN1bHQgPSBmb3JtYXRfc3RyaW5nX2ludGVybmFsKG9iaiwgJmZvcm1hdCk7CisgICAgICAgIGJyZWFrOworICAgIGRlZmF1bHQ6CisgICAgICAgIC8qIHVua25vd24gKi8KKyAgICAgICAgdW5rbm93bl9wcmVzZW50YXRpb25fdHlwZShmb3JtYXQudHlwZSwgb2JqLT5vYl90eXBlLT50cF9uYW1lKTsKKyAgICAgICAgZ290byBkb25lOworICAgIH0KKworZG9uZToKKyAgICByZXR1cm4gcmVzdWx0OworfQorCisjaWYgZGVmaW5lZCBGT1JNQVRfTE9ORyB8fCBkZWZpbmVkIEZPUk1BVF9JTlQKK3N0YXRpYyBQeU9iamVjdCoKK2Zvcm1hdF9pbnRfb3JfbG9uZyhQeU9iamVjdCogb2JqLAorICAgICAgICAgICAgICAgICAgIFNUUklOR0xJQl9DSEFSICpmb3JtYXRfc3BlYywKKyAgICAgICAgICAgICAgICAgICBQeV9zc2l6ZV90IGZvcm1hdF9zcGVjX2xlbiwKKyAgICAgICAgICAgICAgICAgICBJbnRPckxvbmdUb1N0cmluZyB0b3N0cmluZykKK3sKKyAgICBQeU9iamVjdCAqcmVzdWx0ID0gTlVMTDsKKyAgICBQeU9iamVjdCAqdG1wID0gTlVMTDsKKyAgICBJbnRlcm5hbEZvcm1hdFNwZWMgZm9ybWF0OworCisgICAgLyogY2hlY2sgZm9yIHRoZSBzcGVjaWFsIGNhc2Ugb2YgemVybyBsZW5ndGggZm9ybWF0IHNwZWMsIG1ha2UKKyAgICAgICBpdCBlcXVpdmFsZW50IHRvIHN0cihvYmopICovCisgICAgaWYgKGZvcm1hdF9zcGVjX2xlbiA9PSAwKSB7CisgICAgICAgIHJlc3VsdCA9IFNUUklOR0xJQl9UT1NUUihvYmopOworICAgICAgICBnb3RvIGRvbmU7CisgICAgfQorCisgICAgLyogcGFyc2UgdGhlIGZvcm1hdF9zcGVjICovCisgICAgaWYgKCFwYXJzZV9pbnRlcm5hbF9yZW5kZXJfZm9ybWF0X3NwZWMoZm9ybWF0X3NwZWMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9ybWF0X3NwZWNfbGVuLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZmb3JtYXQsICdkJywgJz4nKSkKKyAgICAgICAgZ290byBkb25lOworCisgICAgLyogdHlwZSBjb252ZXJzaW9uPyAqLworICAgIHN3aXRjaCAoZm9ybWF0LnR5cGUpIHsKKyAgICBjYXNlICdiJzoKKyAgICBjYXNlICdjJzoKKyAgICBjYXNlICdkJzoKKyAgICBjYXNlICdvJzoKKyAgICBjYXNlICd4JzoKKyAgICBjYXNlICdYJzoKKyAgICBjYXNlICduJzoKKyAgICAgICAgLyogbm8gdHlwZSBjb252ZXJzaW9uIG5lZWRlZCwgYWxyZWFkeSBhbiBpbnQgKG9yIGxvbmcpLiAgZG8KKyAgICAgICAgICAgdGhlIGZvcm1hdHRpbmcgKi8KKyAgICAgICAgICAgIHJlc3VsdCA9IGZvcm1hdF9pbnRfb3JfbG9uZ19pbnRlcm5hbChvYmosICZmb3JtYXQsIHRvc3RyaW5nKTsKKyAgICAgICAgYnJlYWs7CisKKyAgICBjYXNlICdlJzoKKyAgICBjYXNlICdFJzoKKyAgICBjYXNlICdmJzoKKyAgICBjYXNlICdGJzoKKyAgICBjYXNlICdnJzoKKyAgICBjYXNlICdHJzoKKyAgICBjYXNlICclJzoKKyAgICAgICAgLyogY29udmVydCB0byBmbG9hdCAqLworICAgICAgICB0bXAgPSBQeU51bWJlcl9GbG9hdChvYmopOworICAgICAgICBpZiAodG1wID09IE5VTEwpCisgICAgICAgICAgICBnb3RvIGRvbmU7CisgICAgICAgIHJlc3VsdCA9IGZvcm1hdF9mbG9hdF9pbnRlcm5hbCh0bXAsICZmb3JtYXQpOworICAgICAgICBicmVhazsKKworICAgIGRlZmF1bHQ6CisgICAgICAgIC8qIHVua25vd24gKi8KKyAgICAgICAgdW5rbm93bl9wcmVzZW50YXRpb25fdHlwZShmb3JtYXQudHlwZSwgb2JqLT5vYl90eXBlLT50cF9uYW1lKTsKKyAgICAgICAgZ290byBkb25lOworICAgIH0KKworZG9uZToKKyAgICBQeV9YREVDUkVGKHRtcCk7CisgICAgcmV0dXJuIHJlc3VsdDsKK30KKyNlbmRpZiAvKiBGT1JNQVRfTE9ORyB8fCBkZWZpbmVkIEZPUk1BVF9JTlQgKi8KKworI2lmZGVmIEZPUk1BVF9MT05HCisvKiBOZWVkIHRvIGRlZmluZSBsb25nX2Zvcm1hdCBhcyBhIGZ1bmN0aW9uIHRoYXQgd2lsbCBjb252ZXJ0IGEgbG9uZworICAgdG8gYSBzdHJpbmcuICBJbiAzLjAsIF9QeUxvbmdfRm9ybWF0IGhhcyB0aGUgY29ycmVjdCBzaWduYXR1cmUuICBJbgorICAgMi54LCB3ZSBuZWVkIHRvIGZ1ZGdlIGEgZmV3IHBhcmFtZXRlcnMgKi8KKyNpZiBQWV9WRVJTSU9OX0hFWCA+PSAweDAzMDAwMDAwCisjZGVmaW5lIGxvbmdfZm9ybWF0IF9QeUxvbmdfRm9ybWF0CisjZWxzZQorc3RhdGljIFB5T2JqZWN0KgorbG9uZ19mb3JtYXQoUHlPYmplY3QqIHZhbHVlLCBpbnQgYmFzZSkKK3sKKyAgICAvKiBDb252ZXJ0IHRvIGJhc2UsIGRvbid0IGFkZCB0cmFpbGluZyAnTCcsIGFuZCB1c2UgdGhlIG5ldyBvY3RhbAorICAgICAgIGZvcm1hdC4gV2UgYWxyZWFkeSBrbm93IHRoaXMgaXMgYSBsb25nIG9iamVjdCAqLworICAgIGFzc2VydChQeUxvbmdfQ2hlY2sodmFsdWUpKTsKKyAgICAvKiBjb252ZXJ0IHRvIGJhc2UsIGRvbid0IGFkZCAnTCcsIGFuZCB1c2UgdGhlIG5ldyBvY3RhbCBmb3JtYXQgKi8KKyAgICByZXR1cm4gX1B5TG9uZ19Gb3JtYXQodmFsdWUsIGJhc2UsIDAsIDEpOworfQorI2VuZGlmCisKK1B5T2JqZWN0ICoKK0ZPUk1BVF9MT05HKFB5T2JqZWN0ICpvYmosCisgICAgICAgICAgICBTVFJJTkdMSUJfQ0hBUiAqZm9ybWF0X3NwZWMsCisgICAgICAgICAgICBQeV9zc2l6ZV90IGZvcm1hdF9zcGVjX2xlbikKK3sKKyAgICByZXR1cm4gZm9ybWF0X2ludF9vcl9sb25nKG9iaiwgZm9ybWF0X3NwZWMsIGZvcm1hdF9zcGVjX2xlbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvbmdfZm9ybWF0KTsKK30KKyNlbmRpZiAvKiBGT1JNQVRfTE9ORyAqLworCisjaWZkZWYgRk9STUFUX0lOVAorLyogdGhpcyBpcyBvbmx5IHVzZWQgZm9yIDIueCwgbm90IDMuMCAqLworc3RhdGljIFB5T2JqZWN0KgoraW50X2Zvcm1hdChQeU9iamVjdCogdmFsdWUsIGludCBiYXNlKQoreworICAgIC8qIENvbnZlcnQgdG8gYmFzZSwgYW5kIHVzZSB0aGUgbmV3IG9jdGFsIGZvcm1hdC4gV2UgYWxyZWFkeQorICAgICAgIGtub3cgdGhpcyBpcyBhbiBpbnQgb2JqZWN0ICovCisgICAgYXNzZXJ0KFB5SW50X0NoZWNrKHZhbHVlKSk7CisgICAgcmV0dXJuIF9QeUludF9Gb3JtYXQoKFB5SW50T2JqZWN0Kil2YWx1ZSwgYmFzZSwgMSk7Cit9CisKK1B5T2JqZWN0ICoKK0ZPUk1BVF9JTlQoUHlPYmplY3QgKm9iaiwKKyAgICAgICAgICAgU1RSSU5HTElCX0NIQVIgKmZvcm1hdF9zcGVjLAorICAgICAgICAgICBQeV9zc2l6ZV90IGZvcm1hdF9zcGVjX2xlbikKK3sKKyAgICByZXR1cm4gZm9ybWF0X2ludF9vcl9sb25nKG9iaiwgZm9ybWF0X3NwZWMsIGZvcm1hdF9zcGVjX2xlbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludF9mb3JtYXQpOworfQorI2VuZGlmIC8qIEZPUk1BVF9JTlQgKi8KKworI2lmZGVmIEZPUk1BVF9GTE9BVAorUHlPYmplY3QgKgorRk9STUFUX0ZMT0FUKFB5T2JqZWN0ICpvYmosCisgICAgICAgICAgICAgU1RSSU5HTElCX0NIQVIgKmZvcm1hdF9zcGVjLAorICAgICAgICAgICAgIFB5X3NzaXplX3QgZm9ybWF0X3NwZWNfbGVuKQoreworICAgIFB5T2JqZWN0ICpyZXN1bHQgPSBOVUxMOworICAgIEludGVybmFsRm9ybWF0U3BlYyBmb3JtYXQ7CisKKyAgICAvKiBjaGVjayBmb3IgdGhlIHNwZWNpYWwgY2FzZSBvZiB6ZXJvIGxlbmd0aCBmb3JtYXQgc3BlYywgbWFrZQorICAgICAgIGl0IGVxdWl2YWxlbnQgdG8gc3RyKG9iaikgKi8KKyAgICBpZiAoZm9ybWF0X3NwZWNfbGVuID09IDApIHsKKyAgICAgICAgcmVzdWx0ID0gU1RSSU5HTElCX1RPU1RSKG9iaik7CisgICAgICAgIGdvdG8gZG9uZTsKKyAgICB9CisKKyAgICAvKiBwYXJzZSB0aGUgZm9ybWF0X3NwZWMgKi8KKyAgICBpZiAoIXBhcnNlX2ludGVybmFsX3JlbmRlcl9mb3JtYXRfc3BlYyhmb3JtYXRfc3BlYywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3JtYXRfc3BlY19sZW4sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJmZvcm1hdCwgJ1wwJywgJz4nKSkKKyAgICAgICAgZ290byBkb25lOworCisgICAgLyogdHlwZSBjb252ZXJzaW9uPyAqLworICAgIHN3aXRjaCAoZm9ybWF0LnR5cGUpIHsKKyAgICBjYXNlICdcMCc6IC8qIE5vIGZvcm1hdCBjb2RlOiBsaWtlICdnJywgYnV0IHdpdGggYXQgbGVhc3Qgb25lIGRlY2ltYWwuICovCisgICAgY2FzZSAnZSc6CisgICAgY2FzZSAnRSc6CisgICAgY2FzZSAnZic6CisgICAgY2FzZSAnRic6CisgICAgY2FzZSAnZyc6CisgICAgY2FzZSAnRyc6CisgICAgY2FzZSAnbic6CisgICAgY2FzZSAnJSc6CisgICAgICAgIC8qIG5vIGNvbnZlcnNpb24sIGFscmVhZHkgYSBmbG9hdC4gIGRvIHRoZSBmb3JtYXR0aW5nICovCisgICAgICAgIHJlc3VsdCA9IGZvcm1hdF9mbG9hdF9pbnRlcm5hbChvYmosICZmb3JtYXQpOworICAgICAgICBicmVhazsKKworICAgIGRlZmF1bHQ6CisgICAgICAgIC8qIHVua25vd24gKi8KKyAgICAgICAgdW5rbm93bl9wcmVzZW50YXRpb25fdHlwZShmb3JtYXQudHlwZSwgb2JqLT5vYl90eXBlLT50cF9uYW1lKTsKKyAgICAgICAgZ290byBkb25lOworICAgIH0KKworZG9uZToKKyAgICByZXR1cm4gcmVzdWx0OworfQorI2VuZGlmIC8qIEZPUk1BVF9GTE9BVCAqLworCisjaWZkZWYgRk9STUFUX0NPTVBMRVgKK1B5T2JqZWN0ICoKK0ZPUk1BVF9DT01QTEVYKFB5T2JqZWN0ICpvYmosCisgICAgICAgICAgICAgICBTVFJJTkdMSUJfQ0hBUiAqZm9ybWF0X3NwZWMsCisgICAgICAgICAgICAgICBQeV9zc2l6ZV90IGZvcm1hdF9zcGVjX2xlbikKK3sKKyAgICBQeU9iamVjdCAqcmVzdWx0ID0gTlVMTDsKKyAgICBJbnRlcm5hbEZvcm1hdFNwZWMgZm9ybWF0OworCisgICAgLyogY2hlY2sgZm9yIHRoZSBzcGVjaWFsIGNhc2Ugb2YgemVybyBsZW5ndGggZm9ybWF0IHNwZWMsIG1ha2UKKyAgICAgICBpdCBlcXVpdmFsZW50IHRvIHN0cihvYmopICovCisgICAgaWYgKGZvcm1hdF9zcGVjX2xlbiA9PSAwKSB7CisgICAgICAgIHJlc3VsdCA9IFNUUklOR0xJQl9UT1NUUihvYmopOworICAgICAgICBnb3RvIGRvbmU7CisgICAgfQorCisgICAgLyogcGFyc2UgdGhlIGZvcm1hdF9zcGVjICovCisgICAgaWYgKCFwYXJzZV9pbnRlcm5hbF9yZW5kZXJfZm9ybWF0X3NwZWMoZm9ybWF0X3NwZWMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9ybWF0X3NwZWNfbGVuLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZmb3JtYXQsICdcMCcsICc+JykpCisgICAgICAgIGdvdG8gZG9uZTsKKworICAgIC8qIHR5cGUgY29udmVyc2lvbj8gKi8KKyAgICBzd2l0Y2ggKGZvcm1hdC50eXBlKSB7CisgICAgY2FzZSAnXDAnOiAvKiBObyBmb3JtYXQgY29kZTogbGlrZSAnZycsIGJ1dCB3aXRoIGF0IGxlYXN0IG9uZSBkZWNpbWFsLiAqLworICAgIGNhc2UgJ2UnOgorICAgIGNhc2UgJ0UnOgorICAgIGNhc2UgJ2YnOgorICAgIGNhc2UgJ0YnOgorICAgIGNhc2UgJ2cnOgorICAgIGNhc2UgJ0cnOgorICAgIGNhc2UgJ24nOgorICAgICAgICAvKiBubyBjb252ZXJzaW9uLCBhbHJlYWR5IGEgY29tcGxleC4gIGRvIHRoZSBmb3JtYXR0aW5nICovCisgICAgICAgIHJlc3VsdCA9IGZvcm1hdF9jb21wbGV4X2ludGVybmFsKG9iaiwgJmZvcm1hdCk7CisgICAgICAgIGJyZWFrOworCisgICAgZGVmYXVsdDoKKyAgICAgICAgLyogdW5rbm93biAqLworICAgICAgICB1bmtub3duX3ByZXNlbnRhdGlvbl90eXBlKGZvcm1hdC50eXBlLCBvYmotPm9iX3R5cGUtPnRwX25hbWUpOworICAgICAgICBnb3RvIGRvbmU7CisgICAgfQorCitkb25lOgorICAgIHJldHVybiByZXN1bHQ7Cit9CisjZW5kaWYgLyogRk9STUFUX0NPTVBMRVggKi8KZGlmZiAtLWdpdCBhL1B5dGhvbi0yLjcuNS9PYmplY3RzL3N0cmluZ2xpYi9sb2NhbGV1dGlsLmggYi9QeXRob24tMi43LjUvT2JqZWN0cy9zdHJpbmdsaWIvbG9jYWxldXRpbC5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmY1NDgxMzMKLS0tIC9kZXYvbnVsbAorKysgYi9QeXRob24tMi43LjUvT2JqZWN0cy9zdHJpbmdsaWIvbG9jYWxldXRpbC5oCkBAIC0wLDAgKzEsMjEyIEBACisvKiBzdHJpbmdsaWI6IGxvY2FsZSByZWxhdGVkIGhlbHBlcnMgaW1wbGVtZW50YXRpb24gKi8KKworI2lmbmRlZiBTVFJJTkdMSUJfTE9DQUxFVVRJTF9ICisjZGVmaW5lIFNUUklOR0xJQl9MT0NBTEVVVElMX0gKKworI2luY2x1ZGUgPGxvY2FsZS5oPgorCisjZGVmaW5lIE1BWCh4LCB5KSAoKHgpIDwgKHkpID8gKHkpIDogKHgpKQorI2RlZmluZSBNSU4oeCwgeSkgKCh4KSA8ICh5KSA/ICh4KSA6ICh5KSkKKwordHlwZWRlZiBzdHJ1Y3QgeworICAgIGNvbnN0IGNoYXIgKmdyb3VwaW5nOworICAgIGNoYXIgcHJldmlvdXM7CisgICAgUHlfc3NpemVfdCBpOyAvKiBXaGVyZSB3ZSdyZSBjdXJyZW50bHkgcG9pbnRpbmcgaW4gZ3JvdXBpbmcuICovCit9IEdyb3VwR2VuZXJhdG9yOworCitzdGF0aWMgdm9pZAorX0dyb3VwR2VuZXJhdG9yX2luaXQoR3JvdXBHZW5lcmF0b3IgKnNlbGYsIGNvbnN0IGNoYXIgKmdyb3VwaW5nKQoreworICAgIHNlbGYtPmdyb3VwaW5nID0gZ3JvdXBpbmc7CisgICAgc2VsZi0+aSA9IDA7CisgICAgc2VsZi0+cHJldmlvdXMgPSAwOworfQorCisvKiBSZXR1cm5zIHRoZSBuZXh0IGdyb3VwaW5nLCBvciAwIHRvIHNpZ25pZnkgZW5kLiAqLworc3RhdGljIFB5X3NzaXplX3QKK19Hcm91cEdlbmVyYXRvcl9uZXh0KEdyb3VwR2VuZXJhdG9yICpzZWxmKQoreworICAgIC8qIE5vdGUgdGhhdCB3ZSBkb24ndCByZWFsbHkgZG8gbXVjaCBlcnJvciBjaGVja2luZyBoZXJlLiBJZiBhCisgICAgICAgZ3JvdXBpbmcgc3RyaW5nIGNvbnRhaW5zIGp1c3QgQ0hBUl9NQVgsIGZvciBleGFtcGxlLCB0aGVuIGp1c3QKKyAgICAgICB0ZXJtaW5hdGUgdGhlIGdlbmVyYXRvci4gVGhhdCBzaG91bGRuJ3QgaGFwcGVuLCBidXQgYXQgbGVhc3Qgd2UKKyAgICAgICBmYWlsIGdyYWNlZnVsbHkuICovCisgICAgc3dpdGNoIChzZWxmLT5ncm91cGluZ1tzZWxmLT5pXSkgeworICAgIGNhc2UgMDoKKyAgICAgICAgcmV0dXJuIHNlbGYtPnByZXZpb3VzOworICAgIGNhc2UgQ0hBUl9NQVg6CisgICAgICAgIC8qIFN0b3AgdGhlIGdlbmVyYXRvci4gKi8KKyAgICAgICAgcmV0dXJuIDA7CisgICAgZGVmYXVsdDogeworICAgICAgICBjaGFyIGNoID0gc2VsZi0+Z3JvdXBpbmdbc2VsZi0+aV07CisgICAgICAgIHNlbGYtPnByZXZpb3VzID0gY2g7CisgICAgICAgIHNlbGYtPmkrKzsKKyAgICAgICAgcmV0dXJuIChQeV9zc2l6ZV90KWNoOworICAgIH0KKyAgICB9Cit9CisKKy8qIEZpbGwgaW4gc29tZSBkaWdpdHMsIGxlYWRpbmcgemVyb3MsIGFuZCB0aG91c2FuZHMgc2VwYXJhdG9yLiBBbGwKKyAgIGFyZSBvcHRpb25hbCwgZGVwZW5kaW5nIG9uIHdoZW4gd2UncmUgY2FsbGVkLiAqLworc3RhdGljIHZvaWQKK2ZpbGwoU1RSSU5HTElCX0NIQVIgKipkaWdpdHNfZW5kLCBTVFJJTkdMSUJfQ0hBUiAqKmJ1ZmZlcl9lbmQsCisgICAgIFB5X3NzaXplX3Qgbl9jaGFycywgUHlfc3NpemVfdCBuX3plcm9zLCBjb25zdCBjaGFyKiB0aG91c2FuZHNfc2VwLAorICAgICBQeV9zc2l6ZV90IHRob3VzYW5kc19zZXBfbGVuKQoreworI2lmIFNUUklOR0xJQl9JU19VTklDT0RFCisgICAgUHlfc3NpemVfdCBpOworI2VuZGlmCisKKyAgICBpZiAodGhvdXNhbmRzX3NlcCkgeworICAgICAgICAqYnVmZmVyX2VuZCAtPSB0aG91c2FuZHNfc2VwX2xlbjsKKworICAgICAgICAvKiBDb3B5IHRoZSB0aG91c2FuZHNfc2VwIGNoYXJzIGludG8gdGhlIGJ1ZmZlci4gKi8KKyNpZiBTVFJJTkdMSUJfSVNfVU5JQ09ERQorICAgICAgICAvKiBDb252ZXJ0IGZyb20gdGhlIGNoYXIncyBvZiB0aGUgdGhvdXNhbmRzX3NlcCBmcm9tCisgICAgICAgICAgIHRoZSBsb2NhbGUgaW50byB1bmljb2RlLiAqLworICAgICAgICBmb3IgKGkgPSAwOyBpIDwgdGhvdXNhbmRzX3NlcF9sZW47ICsraSkKKyAgICAgICAgICAgICgqYnVmZmVyX2VuZClbaV0gPSB0aG91c2FuZHNfc2VwW2ldOworI2Vsc2UKKyAgICAgICAgLyogTm8gY29udmVyc2lvbiwganVzdCBtZW1jcHkgdGhlIHRob3VzYW5kc19zZXAuICovCisgICAgICAgIG1lbWNweSgqYnVmZmVyX2VuZCwgdGhvdXNhbmRzX3NlcCwgdGhvdXNhbmRzX3NlcF9sZW4pOworI2VuZGlmCisgICAgfQorCisgICAgKmJ1ZmZlcl9lbmQgLT0gbl9jaGFyczsKKyAgICAqZGlnaXRzX2VuZCAtPSBuX2NoYXJzOworICAgIG1lbWNweSgqYnVmZmVyX2VuZCwgKmRpZ2l0c19lbmQsIG5fY2hhcnMgKiBzaXplb2YoU1RSSU5HTElCX0NIQVIpKTsKKworICAgICpidWZmZXJfZW5kIC09IG5femVyb3M7CisgICAgU1RSSU5HTElCX0ZJTEwoKmJ1ZmZlcl9lbmQsICcwJywgbl96ZXJvcyk7Cit9CisKKy8qKgorICogX1B5X0luc2VydFRob3VzYW5kc0dyb3VwaW5nOgorICogQGJ1ZmZlcjogQSBwb2ludGVyIHRvIHRoZSBzdGFydCBvZiBhIHN0cmluZy4KKyAqIEBuX2J1ZmZlcjogTnVtYmVyIG9mIGNoYXJhY3RlcnMgaW4gQGJ1ZmZlci4KKyAqIEBkaWdpdHM6IEEgcG9pbnRlciB0byB0aGUgZGlnaXRzIHdlJ3JlIHJlYWRpbmcgZnJvbS4gSWYgY291bnQKKyAqICAgICAgICAgIGlzIG5vbi1OVUxMLCB0aGlzIGlzIHVudXNlZC4KKyAqIEBuX2RpZ2l0czogVGhlIG51bWJlciBvZiBkaWdpdHMgaW4gdGhlIHN0cmluZywgaW4gd2hpY2ggd2Ugd2FudAorICogICAgICAgICAgICB0byBwdXQgdGhlIGdyb3VwaW5nIGNoYXJzLgorICogQG1pbl93aWR0aDogVGhlIG1pbmltdW0gd2lkdGggb2YgdGhlIGRpZ2l0cyBpbiB0aGUgb3V0cHV0IHN0cmluZy4KKyAqICAgICAgICAgICAgIE91dHB1dCB3aWxsIGJlIHplcm8tcGFkZGVkIG9uIHRoZSBsZWZ0IHRvIGZpbGwuCisgKiBAZ3JvdXBpbmc6IHNlZSBkZWZpbml0aW9uIGluIGxvY2FsZWNvbnYoKS4KKyAqIEB0aG91c2FuZHNfc2VwOiBzZWUgZGVmaW5pdGlvbiBpbiBsb2NhbGVjb252KCkuCisgKgorICogVGhlcmUgYXJlIDIgbW9kZXM6IGNvdW50aW5nIGFuZCBmaWxsaW5nLiBJZiBAYnVmZmVyIGlzIE5VTEwsCisgKiAgd2UgYXJlIGluIGNvdW50aW5nIG1vZGUsIGVsc2UgZmlsbGluZyBtb2RlLgorICogSWYgY291bnRpbmcsIHRoZSByZXF1aXJlZCBidWZmZXIgc2l6ZSBpcyByZXR1cm5lZC4KKyAqIElmIGZpbGxpbmcsIHdlIGtub3cgdGhlIGJ1ZmZlciB3aWxsIGJlIGxhcmdlIGVub3VnaCwgc28gd2UgZG9uJ3QKKyAqICBuZWVkIHRvIHBhc3MgaW4gdGhlIGJ1ZmZlciBzaXplLgorICogSW5zZXJ0cyB0aG91c2FuZCBncm91cGluZyBjaGFyYWN0ZXJzIChhcyBkZWZpbmVkIGJ5IGdyb3VwaW5nIGFuZAorICogIHRob3VzYW5kc19zZXApIGludG8gdGhlIHN0cmluZyBiZXR3ZWVuIGJ1ZmZlciBhbmQgYnVmZmVyK25fZGlnaXRzLgorICoKKyAqIFJldHVybiB2YWx1ZTogMCBvbiBlcnJvciwgZWxzZSAxLiAgTm90ZSB0aGF0IG5vIGVycm9yIGNhbiBvY2N1ciBpZgorICogIGNvdW50IGlzIG5vbi1OVUxMLgorICoKKyAqIFRoaXMgbmFtZSB3b24ndCBiZSB1c2VkLCB0aGUgaW5jbHVkZXIgb2YgdGhpcyBmaWxlIHNob3VsZCBkZWZpbmUKKyAqICBpdCB0byBiZSB0aGUgYWN0dWFsIGZ1bmN0aW9uIG5hbWUsIGJhc2VkIG9uIHVuaWNvZGUgb3Igc3RyaW5nLgorICoKKyAqIEFzIGNsb3NlbHkgYXMgcG9zc2libGUsIHRoaXMgY29kZSBtaW1pY3MgdGhlIGxvZ2ljIGluIGRlY2ltYWwucHkncworICAgIF9pbnNlcnRfdGhvdXNhbmRzX3NlcCgpLgorICoqLworUHlfc3NpemVfdAorX1B5X0luc2VydFRob3VzYW5kc0dyb3VwaW5nKFNUUklOR0xJQl9DSEFSICpidWZmZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHlfc3NpemVfdCBuX2J1ZmZlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBTVFJJTkdMSUJfQ0hBUiAqZGlnaXRzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIFB5X3NzaXplX3Qgbl9kaWdpdHMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHlfc3NpemVfdCBtaW5fd2lkdGgsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciAqZ3JvdXBpbmcsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciAqdGhvdXNhbmRzX3NlcCkKK3sKKyAgICBQeV9zc2l6ZV90IGNvdW50ID0gMDsKKyAgICBQeV9zc2l6ZV90IG5femVyb3M7CisgICAgaW50IGxvb3BfYnJva2VuID0gMDsKKyAgICBpbnQgdXNlX3NlcGFyYXRvciA9IDA7IC8qIEZpcnN0IHRpbWUgdGhyb3VnaCwgZG9uJ3QgYXBwZW5kIHRoZQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VwYXJhdG9yLiBUaGV5IG9ubHkgZ28gYmV0d2VlbgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ3JvdXBzLiAqLworICAgIFNUUklOR0xJQl9DSEFSICpidWZmZXJfZW5kID0gTlVMTDsKKyAgICBTVFJJTkdMSUJfQ0hBUiAqZGlnaXRzX2VuZCA9IE5VTEw7CisgICAgUHlfc3NpemVfdCBsOworICAgIFB5X3NzaXplX3Qgbl9jaGFyczsKKyAgICBQeV9zc2l6ZV90IHRob3VzYW5kc19zZXBfbGVuID0gc3RybGVuKHRob3VzYW5kc19zZXApOworICAgIFB5X3NzaXplX3QgcmVtYWluaW5nID0gbl9kaWdpdHM7IC8qIE51bWJlciBvZiBjaGFycyByZW1haW5pbmcgdG8KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBiZSBsb29rZWQgYXQgKi8KKyAgICAvKiBBIGdlbmVyYXRvciB0aGF0IHJldHVybnMgYWxsIG9mIHRoZSBncm91cGluZyB3aWR0aHMsIHVudGlsIGl0CisgICAgICAgcmV0dXJucyAwLiAqLworICAgIEdyb3VwR2VuZXJhdG9yIGdyb3VwZ2VuOworICAgIF9Hcm91cEdlbmVyYXRvcl9pbml0KCZncm91cGdlbiwgZ3JvdXBpbmcpOworCisgICAgaWYgKGJ1ZmZlcikgeworICAgICAgICBidWZmZXJfZW5kID0gYnVmZmVyICsgbl9idWZmZXI7CisgICAgICAgIGRpZ2l0c19lbmQgPSBkaWdpdHMgKyBuX2RpZ2l0czsKKyAgICB9CisKKyAgICB3aGlsZSAoKGwgPSBfR3JvdXBHZW5lcmF0b3JfbmV4dCgmZ3JvdXBnZW4pKSA+IDApIHsKKyAgICAgICAgbCA9IE1JTihsLCBNQVgoTUFYKHJlbWFpbmluZywgbWluX3dpZHRoKSwgMSkpOworICAgICAgICBuX3plcm9zID0gTUFYKDAsIGwgLSByZW1haW5pbmcpOworICAgICAgICBuX2NoYXJzID0gTUFYKDAsIE1JTihyZW1haW5pbmcsIGwpKTsKKworICAgICAgICAvKiBVc2Ugbl96ZXJvIHplcm8ncyBhbmQgbl9jaGFycyBjaGFycyAqLworCisgICAgICAgIC8qIENvdW50IG9ubHksIGRvbid0IGRvIGFueXRoaW5nLiAqLworICAgICAgICBjb3VudCArPSAodXNlX3NlcGFyYXRvciA/IHRob3VzYW5kc19zZXBfbGVuIDogMCkgKyBuX3plcm9zICsgbl9jaGFyczsKKworICAgICAgICBpZiAoYnVmZmVyKSB7CisgICAgICAgICAgICAvKiBDb3B5IGludG8gdGhlIG91dHB1dCBidWZmZXIuICovCisgICAgICAgICAgICBmaWxsKCZkaWdpdHNfZW5kLCAmYnVmZmVyX2VuZCwgbl9jaGFycywgbl96ZXJvcywKKyAgICAgICAgICAgICAgICAgdXNlX3NlcGFyYXRvciA/IHRob3VzYW5kc19zZXAgOiBOVUxMLCB0aG91c2FuZHNfc2VwX2xlbik7CisgICAgICAgIH0KKworICAgICAgICAvKiBVc2UgYSBzZXBhcmF0b3IgbmV4dCB0aW1lLiAqLworICAgICAgICB1c2Vfc2VwYXJhdG9yID0gMTsKKworICAgICAgICByZW1haW5pbmcgLT0gbl9jaGFyczsKKyAgICAgICAgbWluX3dpZHRoIC09IGw7CisKKyAgICAgICAgaWYgKHJlbWFpbmluZyA8PSAwICYmIG1pbl93aWR0aCA8PSAwKSB7CisgICAgICAgICAgICBsb29wX2Jyb2tlbiA9IDE7CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgfQorICAgICAgICBtaW5fd2lkdGggLT0gdGhvdXNhbmRzX3NlcF9sZW47CisgICAgfQorICAgIGlmICghbG9vcF9icm9rZW4pIHsKKyAgICAgICAgLyogV2UgbGVmdCB0aGUgbG9vcCB3aXRob3V0IHVzaW5nIGEgYnJlYWsgc3RhdGVtZW50LiAqLworCisgICAgICAgIGwgPSBNQVgoTUFYKHJlbWFpbmluZywgbWluX3dpZHRoKSwgMSk7CisgICAgICAgIG5femVyb3MgPSBNQVgoMCwgbCAtIHJlbWFpbmluZyk7CisgICAgICAgIG5fY2hhcnMgPSBNQVgoMCwgTUlOKHJlbWFpbmluZywgbCkpOworCisgICAgICAgIC8qIFVzZSBuX3plcm8gemVybydzIGFuZCBuX2NoYXJzIGNoYXJzICovCisgICAgICAgIGNvdW50ICs9ICh1c2Vfc2VwYXJhdG9yID8gdGhvdXNhbmRzX3NlcF9sZW4gOiAwKSArIG5femVyb3MgKyBuX2NoYXJzOworICAgICAgICBpZiAoYnVmZmVyKSB7CisgICAgICAgICAgICAvKiBDb3B5IGludG8gdGhlIG91dHB1dCBidWZmZXIuICovCisgICAgICAgICAgICBmaWxsKCZkaWdpdHNfZW5kLCAmYnVmZmVyX2VuZCwgbl9jaGFycywgbl96ZXJvcywKKyAgICAgICAgICAgICAgICAgdXNlX3NlcGFyYXRvciA/IHRob3VzYW5kc19zZXAgOiBOVUxMLCB0aG91c2FuZHNfc2VwX2xlbik7CisgICAgICAgIH0KKyAgICB9CisgICAgcmV0dXJuIGNvdW50OworfQorCisvKioKKyAqIF9QeV9JbnNlcnRUaG91c2FuZHNHcm91cGluZ0xvY2FsZToKKyAqIEBidWZmZXI6IEEgcG9pbnRlciB0byB0aGUgc3RhcnQgb2YgYSBzdHJpbmcuCisgKiBAbl9kaWdpdHM6IFRoZSBudW1iZXIgb2YgZGlnaXRzIGluIHRoZSBzdHJpbmcsIGluIHdoaWNoIHdlIHdhbnQKKyAqICAgICAgICAgICAgdG8gcHV0IHRoZSBncm91cGluZyBjaGFycy4KKyAqCisgKiBSZWFkcyB0aGVlIGN1cnJlbnQgbG9jYWxlIGFuZCBjYWxscyBfUHlfSW5zZXJ0VGhvdXNhbmRzR3JvdXBpbmcoKS4KKyAqKi8KK1B5X3NzaXplX3QKK19QeV9JbnNlcnRUaG91c2FuZHNHcm91cGluZ0xvY2FsZShTVFJJTkdMSUJfQ0hBUiAqYnVmZmVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFB5X3NzaXplX3Qgbl9idWZmZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU1RSSU5HTElCX0NIQVIgKmRpZ2l0cywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQeV9zc2l6ZV90IG5fZGlnaXRzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFB5X3NzaXplX3QgbWluX3dpZHRoKQoreworICAgICAgICBzdHJ1Y3QgbGNvbnYgKmxvY2FsZV9kYXRhID0gbG9jYWxlY29udigpOworICAgICAgICBjb25zdCBjaGFyICpncm91cGluZyA9IGxvY2FsZV9kYXRhLT5ncm91cGluZzsKKyAgICAgICAgY29uc3QgY2hhciAqdGhvdXNhbmRzX3NlcCA9IGxvY2FsZV9kYXRhLT50aG91c2FuZHNfc2VwOworCisgICAgICAgIHJldHVybiBfUHlfSW5zZXJ0VGhvdXNhbmRzR3JvdXBpbmcoYnVmZmVyLCBuX2J1ZmZlciwgZGlnaXRzLCBuX2RpZ2l0cywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtaW5fd2lkdGgsIGdyb3VwaW5nLCB0aG91c2FuZHNfc2VwKTsKK30KKyNlbmRpZiAvKiBTVFJJTkdMSUJfTE9DQUxFVVRJTF9IICovCmRpZmYgLS1naXQgYS9QeXRob24tMi43LjUvT2JqZWN0cy9zdHJpbmdsaWIvcGFydGl0aW9uLmggYi9QeXRob24tMi43LjUvT2JqZWN0cy9zdHJpbmdsaWIvcGFydGl0aW9uLmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMDE3MGJkZAotLS0gL2Rldi9udWxsCisrKyBiL1B5dGhvbi0yLjcuNS9PYmplY3RzL3N0cmluZ2xpYi9wYXJ0aXRpb24uaApAQCAtMCwwICsxLDExMCBAQAorLyogc3RyaW5nbGliOiBwYXJ0aXRpb24gaW1wbGVtZW50YXRpb24gKi8KKworI2lmbmRlZiBTVFJJTkdMSUJfUEFSVElUSU9OX0gKKyNkZWZpbmUgU1RSSU5HTElCX1BBUlRJVElPTl9ICisKKyNpZm5kZWYgU1RSSU5HTElCX0ZBU1RTRUFSQ0hfSAorI2Vycm9yIG11c3QgaW5jbHVkZSAic3RyaW5nbGliL2Zhc3RzZWFyY2guaCIgYmVmb3JlIGluY2x1ZGluZyB0aGlzIG1vZHVsZQorI2VuZGlmCisKK1B5X0xPQ0FMX0lOTElORShQeU9iamVjdCopCitzdHJpbmdsaWJfcGFydGl0aW9uKFB5T2JqZWN0KiBzdHJfb2JqLAorICAgICAgICAgICAgICAgICAgICBjb25zdCBTVFJJTkdMSUJfQ0hBUiogc3RyLCBQeV9zc2l6ZV90IHN0cl9sZW4sCisgICAgICAgICAgICAgICAgICAgIFB5T2JqZWN0KiBzZXBfb2JqLAorICAgICAgICAgICAgICAgICAgICBjb25zdCBTVFJJTkdMSUJfQ0hBUiogc2VwLCBQeV9zc2l6ZV90IHNlcF9sZW4pCit7CisgICAgUHlPYmplY3QqIG91dDsKKyAgICBQeV9zc2l6ZV90IHBvczsKKworICAgIGlmIChzZXBfbGVuID09IDApIHsKKyAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1ZhbHVlRXJyb3IsICJlbXB0eSBzZXBhcmF0b3IiKTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorCisgICAgb3V0ID0gUHlUdXBsZV9OZXcoMyk7CisgICAgaWYgKCFvdXQpCisgICAgICAgIHJldHVybiBOVUxMOworCisgICAgcG9zID0gZmFzdHNlYXJjaChzdHIsIHN0cl9sZW4sIHNlcCwgc2VwX2xlbiwgLTEsIEZBU1RfU0VBUkNIKTsKKworICAgIGlmIChwb3MgPCAwKSB7CisjaWYgU1RSSU5HTElCX01VVEFCTEUKKyAgICAgICAgUHlUdXBsZV9TRVRfSVRFTShvdXQsIDAsIFNUUklOR0xJQl9ORVcoc3RyLCBzdHJfbGVuKSk7CisgICAgICAgIFB5VHVwbGVfU0VUX0lURU0ob3V0LCAxLCBTVFJJTkdMSUJfTkVXKE5VTEwsIDApKTsKKyAgICAgICAgUHlUdXBsZV9TRVRfSVRFTShvdXQsIDIsIFNUUklOR0xJQl9ORVcoTlVMTCwgMCkpOworI2Vsc2UKKyAgICAgICAgUHlfSU5DUkVGKHN0cl9vYmopOworICAgICAgICBQeVR1cGxlX1NFVF9JVEVNKG91dCwgMCwgKFB5T2JqZWN0Kikgc3RyX29iaik7CisgICAgICAgIFB5X0lOQ1JFRihTVFJJTkdMSUJfRU1QVFkpOworICAgICAgICBQeVR1cGxlX1NFVF9JVEVNKG91dCwgMSwgKFB5T2JqZWN0KikgU1RSSU5HTElCX0VNUFRZKTsKKyAgICAgICAgUHlfSU5DUkVGKFNUUklOR0xJQl9FTVBUWSk7CisgICAgICAgIFB5VHVwbGVfU0VUX0lURU0ob3V0LCAyLCAoUHlPYmplY3QqKSBTVFJJTkdMSUJfRU1QVFkpOworI2VuZGlmCisgICAgICAgIHJldHVybiBvdXQ7CisgICAgfQorCisgICAgUHlUdXBsZV9TRVRfSVRFTShvdXQsIDAsIFNUUklOR0xJQl9ORVcoc3RyLCBwb3MpKTsKKyAgICBQeV9JTkNSRUYoc2VwX29iaik7CisgICAgUHlUdXBsZV9TRVRfSVRFTShvdXQsIDEsIHNlcF9vYmopOworICAgIHBvcyArPSBzZXBfbGVuOworICAgIFB5VHVwbGVfU0VUX0lURU0ob3V0LCAyLCBTVFJJTkdMSUJfTkVXKHN0ciArIHBvcywgc3RyX2xlbiAtIHBvcykpOworCisgICAgaWYgKFB5RXJyX09jY3VycmVkKCkpIHsKKyAgICAgICAgUHlfREVDUkVGKG91dCk7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKworICAgIHJldHVybiBvdXQ7Cit9CisKK1B5X0xPQ0FMX0lOTElORShQeU9iamVjdCopCitzdHJpbmdsaWJfcnBhcnRpdGlvbihQeU9iamVjdCogc3RyX29iaiwKKyAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFNUUklOR0xJQl9DSEFSKiBzdHIsIFB5X3NzaXplX3Qgc3RyX2xlbiwKKyAgICAgICAgICAgICAgICAgICAgIFB5T2JqZWN0KiBzZXBfb2JqLAorICAgICAgICAgICAgICAgICAgICAgY29uc3QgU1RSSU5HTElCX0NIQVIqIHNlcCwgUHlfc3NpemVfdCBzZXBfbGVuKQoreworICAgIFB5T2JqZWN0KiBvdXQ7CisgICAgUHlfc3NpemVfdCBwb3M7CisKKyAgICBpZiAoc2VwX2xlbiA9PSAwKSB7CisgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19WYWx1ZUVycm9yLCAiZW1wdHkgc2VwYXJhdG9yIik7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKworICAgIG91dCA9IFB5VHVwbGVfTmV3KDMpOworICAgIGlmICghb3V0KQorICAgICAgICByZXR1cm4gTlVMTDsKKworICAgIHBvcyA9IGZhc3RzZWFyY2goc3RyLCBzdHJfbGVuLCBzZXAsIHNlcF9sZW4sIC0xLCBGQVNUX1JTRUFSQ0gpOworCisgICAgaWYgKHBvcyA8IDApIHsKKyNpZiBTVFJJTkdMSUJfTVVUQUJMRQorICAgICAgICBQeVR1cGxlX1NFVF9JVEVNKG91dCwgMCwgU1RSSU5HTElCX05FVyhOVUxMLCAwKSk7CisgICAgICAgIFB5VHVwbGVfU0VUX0lURU0ob3V0LCAxLCBTVFJJTkdMSUJfTkVXKE5VTEwsIDApKTsKKyAgICAgICAgUHlUdXBsZV9TRVRfSVRFTShvdXQsIDIsIFNUUklOR0xJQl9ORVcoc3RyLCBzdHJfbGVuKSk7CisjZWxzZQorICAgICAgICBQeV9JTkNSRUYoU1RSSU5HTElCX0VNUFRZKTsKKyAgICAgICAgUHlUdXBsZV9TRVRfSVRFTShvdXQsIDAsIChQeU9iamVjdCopIFNUUklOR0xJQl9FTVBUWSk7CisgICAgICAgIFB5X0lOQ1JFRihTVFJJTkdMSUJfRU1QVFkpOworICAgICAgICBQeVR1cGxlX1NFVF9JVEVNKG91dCwgMSwgKFB5T2JqZWN0KikgU1RSSU5HTElCX0VNUFRZKTsKKyAgICAgICAgUHlfSU5DUkVGKHN0cl9vYmopOworICAgICAgICBQeVR1cGxlX1NFVF9JVEVNKG91dCwgMiwgKFB5T2JqZWN0Kikgc3RyX29iaik7CisjZW5kaWYKKyAgICAgICAgcmV0dXJuIG91dDsKKyAgICB9CisKKyAgICBQeVR1cGxlX1NFVF9JVEVNKG91dCwgMCwgU1RSSU5HTElCX05FVyhzdHIsIHBvcykpOworICAgIFB5X0lOQ1JFRihzZXBfb2JqKTsKKyAgICBQeVR1cGxlX1NFVF9JVEVNKG91dCwgMSwgc2VwX29iaik7CisgICAgcG9zICs9IHNlcF9sZW47CisgICAgUHlUdXBsZV9TRVRfSVRFTShvdXQsIDIsIFNUUklOR0xJQl9ORVcoc3RyICsgcG9zLCBzdHJfbGVuIC0gcG9zKSk7CisKKyAgICBpZiAoUHlFcnJfT2NjdXJyZWQoKSkgeworICAgICAgICBQeV9ERUNSRUYob3V0KTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorCisgICAgcmV0dXJuIG91dDsKK30KKworI2VuZGlmCmRpZmYgLS1naXQgYS9QeXRob24tMi43LjUvT2JqZWN0cy9zdHJpbmdsaWIvc3BsaXQuaCBiL1B5dGhvbi0yLjcuNS9PYmplY3RzL3N0cmluZ2xpYi9zcGxpdC5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjYwZTc3NjcKLS0tIC9kZXYvbnVsbAorKysgYi9QeXRob24tMi43LjUvT2JqZWN0cy9zdHJpbmdsaWIvc3BsaXQuaApAQCAtMCwwICsxLDM5NCBAQAorLyogc3RyaW5nbGliOiBzcGxpdCBpbXBsZW1lbnRhdGlvbiAqLworCisjaWZuZGVmIFNUUklOR0xJQl9TUExJVF9ICisjZGVmaW5lIFNUUklOR0xJQl9TUExJVF9ICisKKyNpZm5kZWYgU1RSSU5HTElCX0ZBU1RTRUFSQ0hfSAorI2Vycm9yIG11c3QgaW5jbHVkZSAic3RyaW5nbGliL2Zhc3RzZWFyY2guaCIgYmVmb3JlIGluY2x1ZGluZyB0aGlzIG1vZHVsZQorI2VuZGlmCisKKy8qIE92ZXJhbGxvY2F0ZSB0aGUgaW5pdGlhbCBsaXN0IHRvIHJlZHVjZSB0aGUgbnVtYmVyIG9mIHJlYWxsb2NzIGZvciBzbWFsbAorICAgc3BsaXQgc2l6ZXMuICBFZywgIkEgQSBBIEEgQSBBIEEgQSBBIEEiLnNwbGl0KCkgKDEwIGVsZW1lbnRzKSBoYXMgdGhyZWUKKyAgIHJlc2l6ZXMsIHRvIHNpemVzIDQsIDgsIHRoZW4gMTYuICBNb3N0IG9ic2VydmVkIHN0cmluZyBzcGxpdHMgYXJlIGZvciBodW1hbgorICAgdGV4dCAocm91Z2hseSAxMSB3b3JkcyBwZXIgbGluZSkgYW5kIGZpZWxkIGRlbGltaXRlZCBkYXRhICh1c3VhbGx5IDEtMTAKKyAgIGZpZWxkcykuICBGb3IgbGFyZ2Ugc3RyaW5ncyB0aGUgc3BsaXQgYWxnb3JpdGhtcyBhcmUgYmFuZHdpZHRoIGxpbWl0ZWQKKyAgIHNvIGluY3JlYXNpbmcgdGhlIHByZWFsbG9jYXRpb24gbGlrZWx5IHdpbGwgbm90IGltcHJvdmUgdGhpbmdzLiovCisKKyNkZWZpbmUgTUFYX1BSRUFMTE9DIDEyCisKKy8qIDUgc3BsaXRzIGdpdmVzIDYgZWxlbWVudHMgKi8KKyNkZWZpbmUgUFJFQUxMT0NfU0laRShtYXhzcGxpdCkgXAorICAgIChtYXhzcGxpdCA+PSBNQVhfUFJFQUxMT0MgPyBNQVhfUFJFQUxMT0MgOiBtYXhzcGxpdCsxKQorCisjZGVmaW5lIFNQTElUX0FQUEVORChkYXRhLCBsZWZ0LCByaWdodCkgICAgICAgICBcCisgICAgc3ViID0gU1RSSU5HTElCX05FVygoZGF0YSkgKyAobGVmdCksICAgICAgICBcCisgICAgICAgICAgICAgICAgICAgICAgICAocmlnaHQpIC0gKGxlZnQpKTsgICAgICBcCisgICAgaWYgKHN1YiA9PSBOVUxMKSAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgIGdvdG8gb25FcnJvcjsgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgaWYgKFB5TGlzdF9BcHBlbmQobGlzdCwgc3ViKSkgeyAgICAgICAgICAgICBcCisgICAgICAgIFB5X0RFQ1JFRihzdWIpOyAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgIGdvdG8gb25FcnJvcjsgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgfSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgZWxzZSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgIFB5X0RFQ1JFRihzdWIpOworCisjZGVmaW5lIFNQTElUX0FERChkYXRhLCBsZWZ0LCByaWdodCkgeyAgICAgICAgICBcCisgICAgc3ViID0gU1RSSU5HTElCX05FVygoZGF0YSkgKyAobGVmdCksICAgICAgICBcCisgICAgICAgICAgICAgICAgICAgICAgICAocmlnaHQpIC0gKGxlZnQpKTsgICAgICBcCisgICAgaWYgKHN1YiA9PSBOVUxMKSAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgIGdvdG8gb25FcnJvcjsgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgaWYgKGNvdW50IDwgTUFYX1BSRUFMTE9DKSB7ICAgICAgICAgICAgICAgICBcCisgICAgICAgIFB5TGlzdF9TRVRfSVRFTShsaXN0LCBjb3VudCwgc3ViKTsgICAgICBcCisgICAgfSBlbHNlIHsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgIGlmIChQeUxpc3RfQXBwZW5kKGxpc3QsIHN1YikpIHsgICAgICAgICBcCisgICAgICAgICAgICBQeV9ERUNSRUYoc3ViKTsgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgICAgICBnb3RvIG9uRXJyb3I7ICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgIH0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgIGVsc2UgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgICAgICBQeV9ERUNSRUYoc3ViKTsgICAgICAgICAgICAgICAgICAgICBcCisgICAgfSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgY291bnQrKzsgfQorCisKKy8qIEFsd2F5cyBmb3JjZSB0aGUgbGlzdCB0byB0aGUgZXhwZWN0ZWQgc2l6ZS4gKi8KKyNkZWZpbmUgRklYX1BSRUFMTE9DX1NJWkUobGlzdCkgUHlfU0laRShsaXN0KSA9IGNvdW50CisKK1B5X0xPQ0FMX0lOTElORShQeU9iamVjdCAqKQorc3RyaW5nbGliX3NwbGl0X3doaXRlc3BhY2UoUHlPYmplY3QqIHN0cl9vYmosCisgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBTVFJJTkdMSUJfQ0hBUiogc3RyLCBQeV9zc2l6ZV90IHN0cl9sZW4sCisgICAgICAgICAgICAgICAgICAgICAgICAgICBQeV9zc2l6ZV90IG1heGNvdW50KQoreworICAgIFB5X3NzaXplX3QgaSwgaiwgY291bnQ9MDsKKyAgICBQeU9iamVjdCAqbGlzdCA9IFB5TGlzdF9OZXcoUFJFQUxMT0NfU0laRShtYXhjb3VudCkpOworICAgIFB5T2JqZWN0ICpzdWI7CisKKyAgICBpZiAobGlzdCA9PSBOVUxMKQorICAgICAgICByZXR1cm4gTlVMTDsKKworICAgIGkgPSBqID0gMDsKKyAgICB3aGlsZSAobWF4Y291bnQtLSA+IDApIHsKKyAgICAgICAgd2hpbGUgKGkgPCBzdHJfbGVuICYmIFNUUklOR0xJQl9JU1NQQUNFKHN0cltpXSkpCisgICAgICAgICAgICBpKys7CisgICAgICAgIGlmIChpID09IHN0cl9sZW4pIGJyZWFrOworICAgICAgICBqID0gaTsgaSsrOworICAgICAgICB3aGlsZSAoaSA8IHN0cl9sZW4gJiYgIVNUUklOR0xJQl9JU1NQQUNFKHN0cltpXSkpCisgICAgICAgICAgICBpKys7CisjaWZuZGVmIFNUUklOR0xJQl9NVVRBQkxFCisgICAgICAgIGlmIChqID09IDAgJiYgaSA9PSBzdHJfbGVuICYmIFNUUklOR0xJQl9DSEVDS19FWEFDVChzdHJfb2JqKSkgeworICAgICAgICAgICAgLyogTm8gd2hpdGVzcGFjZSBpbiBzdHJfb2JqLCBzbyBqdXN0IHVzZSBpdCBhcyBsaXN0WzBdICovCisgICAgICAgICAgICBQeV9JTkNSRUYoc3RyX29iaik7CisgICAgICAgICAgICBQeUxpc3RfU0VUX0lURU0obGlzdCwgMCwgKFB5T2JqZWN0ICopc3RyX29iaik7CisgICAgICAgICAgICBjb3VudCsrOworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKyNlbmRpZgorICAgICAgICBTUExJVF9BREQoc3RyLCBqLCBpKTsKKyAgICB9CisKKyAgICBpZiAoaSA8IHN0cl9sZW4pIHsKKyAgICAgICAgLyogT25seSBvY2N1cnMgd2hlbiBtYXhjb3VudCB3YXMgcmVhY2hlZCAqLworICAgICAgICAvKiBTa2lwIGFueSByZW1haW5pbmcgd2hpdGVzcGFjZSBhbmQgY29weSB0byBlbmQgb2Ygc3RyaW5nICovCisgICAgICAgIHdoaWxlIChpIDwgc3RyX2xlbiAmJiBTVFJJTkdMSUJfSVNTUEFDRShzdHJbaV0pKQorICAgICAgICAgICAgaSsrOworICAgICAgICBpZiAoaSAhPSBzdHJfbGVuKQorICAgICAgICAgICAgU1BMSVRfQUREKHN0ciwgaSwgc3RyX2xlbik7CisgICAgfQorICAgIEZJWF9QUkVBTExPQ19TSVpFKGxpc3QpOworICAgIHJldHVybiBsaXN0OworCisgIG9uRXJyb3I6CisgICAgUHlfREVDUkVGKGxpc3QpOworICAgIHJldHVybiBOVUxMOworfQorCitQeV9MT0NBTF9JTkxJTkUoUHlPYmplY3QgKikKK3N0cmluZ2xpYl9zcGxpdF9jaGFyKFB5T2JqZWN0KiBzdHJfb2JqLAorICAgICAgICAgICAgICAgICAgICAgY29uc3QgU1RSSU5HTElCX0NIQVIqIHN0ciwgUHlfc3NpemVfdCBzdHJfbGVuLAorICAgICAgICAgICAgICAgICAgICAgY29uc3QgU1RSSU5HTElCX0NIQVIgY2gsCisgICAgICAgICAgICAgICAgICAgICBQeV9zc2l6ZV90IG1heGNvdW50KQoreworICAgIFB5X3NzaXplX3QgaSwgaiwgY291bnQ9MDsKKyAgICBQeU9iamVjdCAqbGlzdCA9IFB5TGlzdF9OZXcoUFJFQUxMT0NfU0laRShtYXhjb3VudCkpOworICAgIFB5T2JqZWN0ICpzdWI7CisKKyAgICBpZiAobGlzdCA9PSBOVUxMKQorICAgICAgICByZXR1cm4gTlVMTDsKKworICAgIGkgPSBqID0gMDsKKyAgICB3aGlsZSAoKGogPCBzdHJfbGVuKSAmJiAobWF4Y291bnQtLSA+IDApKSB7CisgICAgICAgIGZvcig7IGogPCBzdHJfbGVuOyBqKyspIHsKKyAgICAgICAgICAgIC8qIEkgZm91bmQgdGhhdCB1c2luZyBtZW1jaHIgbWFrZXMgbm8gZGlmZmVyZW5jZSAqLworICAgICAgICAgICAgaWYgKHN0cltqXSA9PSBjaCkgeworICAgICAgICAgICAgICAgIFNQTElUX0FERChzdHIsIGksIGopOworICAgICAgICAgICAgICAgIGkgPSBqID0gaiArIDE7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisjaWZuZGVmIFNUUklOR0xJQl9NVVRBQkxFCisgICAgaWYgKGNvdW50ID09IDAgJiYgU1RSSU5HTElCX0NIRUNLX0VYQUNUKHN0cl9vYmopKSB7CisgICAgICAgIC8qIGNoIG5vdCBpbiBzdHJfb2JqLCBzbyBqdXN0IHVzZSBzdHJfb2JqIGFzIGxpc3RbMF0gKi8KKyAgICAgICAgUHlfSU5DUkVGKHN0cl9vYmopOworICAgICAgICBQeUxpc3RfU0VUX0lURU0obGlzdCwgMCwgKFB5T2JqZWN0ICopc3RyX29iaik7CisgICAgICAgIGNvdW50Kys7CisgICAgfSBlbHNlCisjZW5kaWYKKyAgICBpZiAoaSA8PSBzdHJfbGVuKSB7CisgICAgICAgIFNQTElUX0FERChzdHIsIGksIHN0cl9sZW4pOworICAgIH0KKyAgICBGSVhfUFJFQUxMT0NfU0laRShsaXN0KTsKKyAgICByZXR1cm4gbGlzdDsKKworICBvbkVycm9yOgorICAgIFB5X0RFQ1JFRihsaXN0KTsKKyAgICByZXR1cm4gTlVMTDsKK30KKworUHlfTE9DQUxfSU5MSU5FKFB5T2JqZWN0ICopCitzdHJpbmdsaWJfc3BsaXQoUHlPYmplY3QqIHN0cl9vYmosCisgICAgICAgICAgICAgICAgY29uc3QgU1RSSU5HTElCX0NIQVIqIHN0ciwgUHlfc3NpemVfdCBzdHJfbGVuLAorICAgICAgICAgICAgICAgIGNvbnN0IFNUUklOR0xJQl9DSEFSKiBzZXAsIFB5X3NzaXplX3Qgc2VwX2xlbiwKKyAgICAgICAgICAgICAgICBQeV9zc2l6ZV90IG1heGNvdW50KQoreworICAgIFB5X3NzaXplX3QgaSwgaiwgcG9zLCBjb3VudD0wOworICAgIFB5T2JqZWN0ICpsaXN0LCAqc3ViOworCisgICAgaWYgKHNlcF9sZW4gPT0gMCkgeworICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfVmFsdWVFcnJvciwgImVtcHR5IHNlcGFyYXRvciIpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgZWxzZSBpZiAoc2VwX2xlbiA9PSAxKQorICAgICAgICByZXR1cm4gc3RyaW5nbGliX3NwbGl0X2NoYXIoc3RyX29iaiwgc3RyLCBzdHJfbGVuLCBzZXBbMF0sIG1heGNvdW50KTsKKworICAgIGxpc3QgPSBQeUxpc3RfTmV3KFBSRUFMTE9DX1NJWkUobWF4Y291bnQpKTsKKyAgICBpZiAobGlzdCA9PSBOVUxMKQorICAgICAgICByZXR1cm4gTlVMTDsKKworICAgIGkgPSBqID0gMDsKKyAgICB3aGlsZSAobWF4Y291bnQtLSA+IDApIHsKKyAgICAgICAgcG9zID0gZmFzdHNlYXJjaChzdHIraSwgc3RyX2xlbi1pLCBzZXAsIHNlcF9sZW4sIC0xLCBGQVNUX1NFQVJDSCk7CisgICAgICAgIGlmIChwb3MgPCAwKQorICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIGogPSBpICsgcG9zOworICAgICAgICBTUExJVF9BREQoc3RyLCBpLCBqKTsKKyAgICAgICAgaSA9IGogKyBzZXBfbGVuOworICAgIH0KKyNpZm5kZWYgU1RSSU5HTElCX01VVEFCTEUKKyAgICBpZiAoY291bnQgPT0gMCAmJiBTVFJJTkdMSUJfQ0hFQ0tfRVhBQ1Qoc3RyX29iaikpIHsKKyAgICAgICAgLyogTm8gbWF0Y2ggaW4gc3RyX29iaiwgc28ganVzdCB1c2UgaXQgYXMgbGlzdFswXSAqLworICAgICAgICBQeV9JTkNSRUYoc3RyX29iaik7CisgICAgICAgIFB5TGlzdF9TRVRfSVRFTShsaXN0LCAwLCAoUHlPYmplY3QgKilzdHJfb2JqKTsKKyAgICAgICAgY291bnQrKzsKKyAgICB9IGVsc2UKKyNlbmRpZgorICAgIHsKKyAgICAgICAgU1BMSVRfQUREKHN0ciwgaSwgc3RyX2xlbik7CisgICAgfQorICAgIEZJWF9QUkVBTExPQ19TSVpFKGxpc3QpOworICAgIHJldHVybiBsaXN0OworCisgIG9uRXJyb3I6CisgICAgUHlfREVDUkVGKGxpc3QpOworICAgIHJldHVybiBOVUxMOworfQorCitQeV9MT0NBTF9JTkxJTkUoUHlPYmplY3QgKikKK3N0cmluZ2xpYl9yc3BsaXRfd2hpdGVzcGFjZShQeU9iamVjdCogc3RyX29iaiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBTVFJJTkdMSUJfQ0hBUiogc3RyLCBQeV9zc2l6ZV90IHN0cl9sZW4sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHlfc3NpemVfdCBtYXhjb3VudCkKK3sKKyAgICBQeV9zc2l6ZV90IGksIGosIGNvdW50PTA7CisgICAgUHlPYmplY3QgKmxpc3QgPSBQeUxpc3RfTmV3KFBSRUFMTE9DX1NJWkUobWF4Y291bnQpKTsKKyAgICBQeU9iamVjdCAqc3ViOworCisgICAgaWYgKGxpc3QgPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisKKyAgICBpID0gaiA9IHN0cl9sZW4gLSAxOworICAgIHdoaWxlIChtYXhjb3VudC0tID4gMCkgeworICAgICAgICB3aGlsZSAoaSA+PSAwICYmIFNUUklOR0xJQl9JU1NQQUNFKHN0cltpXSkpCisgICAgICAgICAgICBpLS07CisgICAgICAgIGlmIChpIDwgMCkgYnJlYWs7CisgICAgICAgIGogPSBpOyBpLS07CisgICAgICAgIHdoaWxlIChpID49IDAgJiYgIVNUUklOR0xJQl9JU1NQQUNFKHN0cltpXSkpCisgICAgICAgICAgICBpLS07CisjaWZuZGVmIFNUUklOR0xJQl9NVVRBQkxFCisgICAgICAgIGlmIChqID09IHN0cl9sZW4gLSAxICYmIGkgPCAwICYmIFNUUklOR0xJQl9DSEVDS19FWEFDVChzdHJfb2JqKSkgeworICAgICAgICAgICAgLyogTm8gd2hpdGVzcGFjZSBpbiBzdHJfb2JqLCBzbyBqdXN0IHVzZSBpdCBhcyBsaXN0WzBdICovCisgICAgICAgICAgICBQeV9JTkNSRUYoc3RyX29iaik7CisgICAgICAgICAgICBQeUxpc3RfU0VUX0lURU0obGlzdCwgMCwgKFB5T2JqZWN0ICopc3RyX29iaik7CisgICAgICAgICAgICBjb3VudCsrOworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKyNlbmRpZgorICAgICAgICBTUExJVF9BREQoc3RyLCBpICsgMSwgaiArIDEpOworICAgIH0KKworICAgIGlmIChpID49IDApIHsKKyAgICAgICAgLyogT25seSBvY2N1cnMgd2hlbiBtYXhjb3VudCB3YXMgcmVhY2hlZCAqLworICAgICAgICAvKiBTa2lwIGFueSByZW1haW5pbmcgd2hpdGVzcGFjZSBhbmQgY29weSB0byBiZWdpbm5pbmcgb2Ygc3RyaW5nICovCisgICAgICAgIHdoaWxlIChpID49IDAgJiYgU1RSSU5HTElCX0lTU1BBQ0Uoc3RyW2ldKSkKKyAgICAgICAgICAgIGktLTsKKyAgICAgICAgaWYgKGkgPj0gMCkKKyAgICAgICAgICAgIFNQTElUX0FERChzdHIsIDAsIGkgKyAxKTsKKyAgICB9CisgICAgRklYX1BSRUFMTE9DX1NJWkUobGlzdCk7CisgICAgaWYgKFB5TGlzdF9SZXZlcnNlKGxpc3QpIDwgMCkKKyAgICAgICAgZ290byBvbkVycm9yOworICAgIHJldHVybiBsaXN0OworCisgIG9uRXJyb3I6CisgICAgUHlfREVDUkVGKGxpc3QpOworICAgIHJldHVybiBOVUxMOworfQorCitQeV9MT0NBTF9JTkxJTkUoUHlPYmplY3QgKikKK3N0cmluZ2xpYl9yc3BsaXRfY2hhcihQeU9iamVjdCogc3RyX29iaiwKKyAgICAgICAgICAgICAgICAgICAgICBjb25zdCBTVFJJTkdMSUJfQ0hBUiogc3RyLCBQeV9zc2l6ZV90IHN0cl9sZW4sCisgICAgICAgICAgICAgICAgICAgICAgY29uc3QgU1RSSU5HTElCX0NIQVIgY2gsCisgICAgICAgICAgICAgICAgICAgICAgUHlfc3NpemVfdCBtYXhjb3VudCkKK3sKKyAgICBQeV9zc2l6ZV90IGksIGosIGNvdW50PTA7CisgICAgUHlPYmplY3QgKmxpc3QgPSBQeUxpc3RfTmV3KFBSRUFMTE9DX1NJWkUobWF4Y291bnQpKTsKKyAgICBQeU9iamVjdCAqc3ViOworCisgICAgaWYgKGxpc3QgPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisKKyAgICBpID0gaiA9IHN0cl9sZW4gLSAxOworICAgIHdoaWxlICgoaSA+PSAwKSAmJiAobWF4Y291bnQtLSA+IDApKSB7CisgICAgICAgIGZvcig7IGkgPj0gMDsgaS0tKSB7CisgICAgICAgICAgICBpZiAoc3RyW2ldID09IGNoKSB7CisgICAgICAgICAgICAgICAgU1BMSVRfQUREKHN0ciwgaSArIDEsIGogKyAxKTsKKyAgICAgICAgICAgICAgICBqID0gaSA9IGkgLSAxOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorI2lmbmRlZiBTVFJJTkdMSUJfTVVUQUJMRQorICAgIGlmIChjb3VudCA9PSAwICYmIFNUUklOR0xJQl9DSEVDS19FWEFDVChzdHJfb2JqKSkgeworICAgICAgICAvKiBjaCBub3QgaW4gc3RyX29iaiwgc28ganVzdCB1c2Ugc3RyX29iaiBhcyBsaXN0WzBdICovCisgICAgICAgIFB5X0lOQ1JFRihzdHJfb2JqKTsKKyAgICAgICAgUHlMaXN0X1NFVF9JVEVNKGxpc3QsIDAsIChQeU9iamVjdCAqKXN0cl9vYmopOworICAgICAgICBjb3VudCsrOworICAgIH0gZWxzZQorI2VuZGlmCisgICAgaWYgKGogPj0gLTEpIHsKKyAgICAgICAgU1BMSVRfQUREKHN0ciwgMCwgaiArIDEpOworICAgIH0KKyAgICBGSVhfUFJFQUxMT0NfU0laRShsaXN0KTsKKyAgICBpZiAoUHlMaXN0X1JldmVyc2UobGlzdCkgPCAwKQorICAgICAgICBnb3RvIG9uRXJyb3I7CisgICAgcmV0dXJuIGxpc3Q7CisKKyAgb25FcnJvcjoKKyAgICBQeV9ERUNSRUYobGlzdCk7CisgICAgcmV0dXJuIE5VTEw7Cit9CisKK1B5X0xPQ0FMX0lOTElORShQeU9iamVjdCAqKQorc3RyaW5nbGliX3JzcGxpdChQeU9iamVjdCogc3RyX29iaiwKKyAgICAgICAgICAgICAgICAgY29uc3QgU1RSSU5HTElCX0NIQVIqIHN0ciwgUHlfc3NpemVfdCBzdHJfbGVuLAorICAgICAgICAgICAgICAgICBjb25zdCBTVFJJTkdMSUJfQ0hBUiogc2VwLCBQeV9zc2l6ZV90IHNlcF9sZW4sCisgICAgICAgICAgICAgICAgIFB5X3NzaXplX3QgbWF4Y291bnQpCit7CisgICAgUHlfc3NpemVfdCBqLCBwb3MsIGNvdW50PTA7CisgICAgUHlPYmplY3QgKmxpc3QsICpzdWI7CisKKyAgICBpZiAoc2VwX2xlbiA9PSAwKSB7CisgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19WYWx1ZUVycm9yLCAiZW1wdHkgc2VwYXJhdG9yIik7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICBlbHNlIGlmIChzZXBfbGVuID09IDEpCisgICAgICAgIHJldHVybiBzdHJpbmdsaWJfcnNwbGl0X2NoYXIoc3RyX29iaiwgc3RyLCBzdHJfbGVuLCBzZXBbMF0sIG1heGNvdW50KTsKKworICAgIGxpc3QgPSBQeUxpc3RfTmV3KFBSRUFMTE9DX1NJWkUobWF4Y291bnQpKTsKKyAgICBpZiAobGlzdCA9PSBOVUxMKQorICAgICAgICByZXR1cm4gTlVMTDsKKworICAgIGogPSBzdHJfbGVuOworICAgIHdoaWxlIChtYXhjb3VudC0tID4gMCkgeworICAgICAgICBwb3MgPSBmYXN0c2VhcmNoKHN0ciwgaiwgc2VwLCBzZXBfbGVuLCAtMSwgRkFTVF9SU0VBUkNIKTsKKyAgICAgICAgaWYgKHBvcyA8IDApCisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgU1BMSVRfQUREKHN0ciwgcG9zICsgc2VwX2xlbiwgaik7CisgICAgICAgIGogPSBwb3M7CisgICAgfQorI2lmbmRlZiBTVFJJTkdMSUJfTVVUQUJMRQorICAgIGlmIChjb3VudCA9PSAwICYmIFNUUklOR0xJQl9DSEVDS19FWEFDVChzdHJfb2JqKSkgeworICAgICAgICAvKiBObyBtYXRjaCBpbiBzdHJfb2JqLCBzbyBqdXN0IHVzZSBpdCBhcyBsaXN0WzBdICovCisgICAgICAgIFB5X0lOQ1JFRihzdHJfb2JqKTsKKyAgICAgICAgUHlMaXN0X1NFVF9JVEVNKGxpc3QsIDAsIChQeU9iamVjdCAqKXN0cl9vYmopOworICAgICAgICBjb3VudCsrOworICAgIH0gZWxzZQorI2VuZGlmCisgICAgeworICAgICAgICBTUExJVF9BREQoc3RyLCAwLCBqKTsKKyAgICB9CisgICAgRklYX1BSRUFMTE9DX1NJWkUobGlzdCk7CisgICAgaWYgKFB5TGlzdF9SZXZlcnNlKGxpc3QpIDwgMCkKKyAgICAgICAgZ290byBvbkVycm9yOworICAgIHJldHVybiBsaXN0OworCisgIG9uRXJyb3I6CisgICAgUHlfREVDUkVGKGxpc3QpOworICAgIHJldHVybiBOVUxMOworfQorCitQeV9MT0NBTF9JTkxJTkUoUHlPYmplY3QgKikKK3N0cmluZ2xpYl9zcGxpdGxpbmVzKFB5T2JqZWN0KiBzdHJfb2JqLAorICAgICAgICAgICAgICAgICAgICAgY29uc3QgU1RSSU5HTElCX0NIQVIqIHN0ciwgUHlfc3NpemVfdCBzdHJfbGVuLAorICAgICAgICAgICAgICAgICAgICAgaW50IGtlZXBlbmRzKQoreworICAgIC8qIFRoaXMgZG9lcyBub3QgdXNlIHRoZSBwcmVhbGxvY2F0ZWQgbGlzdCBiZWNhdXNlIHNwbGl0bGluZXMgaXMKKyAgICAgICB1c3VhbGx5IHJ1biB3aXRoIGh1bmRyZWRzIG9mIG5ld2xpbmVzLiAgVGhlIG92ZXJoZWFkIG9mCisgICAgICAgc3dpdGNoaW5nIGJldHdlZW4gUHlMaXN0X1NFVF9JVEVNIGFuZCBhcHBlbmQgY2F1c2VzIGFib3V0IGEKKyAgICAgICAyLTMlIHNsb3dkb3duIGZvciB0aGF0IGNvbW1vbiBjYXNlLiAgQSBzbWFydGVyIGltcGxlbWVudGF0aW9uCisgICAgICAgY291bGQgbW92ZSB0aGUgaWYgY2hlY2sgb3V0LCBzbyB0aGUgU0VUX0lURU1zIGFyZSBkb25lIGZpcnN0CisgICAgICAgYW5kIHRoZSBhcHBlbmRzIG9ubHkgZG9uZSB3aGVuIHRoZSBwcmVhbGxvYyBidWZmZXIgaXMgZnVsbC4KKyAgICAgICBUaGF0J3MgdG9vIG11Y2ggd29yayBmb3IgbGl0dGxlIGdhaW4uKi8KKworICAgIHJlZ2lzdGVyIFB5X3NzaXplX3QgaTsKKyAgICByZWdpc3RlciBQeV9zc2l6ZV90IGo7CisgICAgUHlPYmplY3QgKmxpc3QgPSBQeUxpc3RfTmV3KDApOworICAgIFB5T2JqZWN0ICpzdWI7CisKKyAgICBpZiAobGlzdCA9PSBOVUxMKQorICAgICAgICByZXR1cm4gTlVMTDsKKworICAgIGZvciAoaSA9IGogPSAwOyBpIDwgc3RyX2xlbjsgKSB7CisgICAgICAgIFB5X3NzaXplX3QgZW9sOworCisgICAgICAgIC8qIEZpbmQgYSBsaW5lIGFuZCBhcHBlbmQgaXQgKi8KKyAgICAgICAgd2hpbGUgKGkgPCBzdHJfbGVuICYmICFTVFJJTkdMSUJfSVNMSU5FQlJFQUsoc3RyW2ldKSkKKyAgICAgICAgICAgIGkrKzsKKworICAgICAgICAvKiBTa2lwIHRoZSBsaW5lIGJyZWFrIHJlYWRpbmcgQ1JMRiBhcyBvbmUgbGluZSBicmVhayAqLworICAgICAgICBlb2wgPSBpOworICAgICAgICBpZiAoaSA8IHN0cl9sZW4pIHsKKyAgICAgICAgICAgIGlmIChzdHJbaV0gPT0gJ1xyJyAmJiBpICsgMSA8IHN0cl9sZW4gJiYgc3RyW2krMV0gPT0gJ1xuJykKKyAgICAgICAgICAgICAgICBpICs9IDI7CisgICAgICAgICAgICBlbHNlCisgICAgICAgICAgICAgICAgaSsrOworICAgICAgICAgICAgaWYgKGtlZXBlbmRzKQorICAgICAgICAgICAgICAgIGVvbCA9IGk7CisgICAgICAgIH0KKyNpZm5kZWYgU1RSSU5HTElCX01VVEFCTEUKKyAgICAgICAgaWYgKGogPT0gMCAmJiBlb2wgPT0gc3RyX2xlbiAmJiBTVFJJTkdMSUJfQ0hFQ0tfRVhBQ1Qoc3RyX29iaikpIHsKKyAgICAgICAgICAgIC8qIE5vIGxpbmVicmVhayBpbiBzdHJfb2JqLCBzbyBqdXN0IHVzZSBpdCBhcyBsaXN0WzBdICovCisgICAgICAgICAgICBpZiAoUHlMaXN0X0FwcGVuZChsaXN0LCBzdHJfb2JqKSkKKyAgICAgICAgICAgICAgICBnb3RvIG9uRXJyb3I7CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgfQorI2VuZGlmCisgICAgICAgIFNQTElUX0FQUEVORChzdHIsIGosIGVvbCk7CisgICAgICAgIGogPSBpOworICAgIH0KKyAgICByZXR1cm4gbGlzdDsKKworICBvbkVycm9yOgorICAgIFB5X0RFQ1JFRihsaXN0KTsKKyAgICByZXR1cm4gTlVMTDsKK30KKworI2VuZGlmCmRpZmYgLS1naXQgYS9QeXRob24tMi43LjUvT2JqZWN0cy9zdHJpbmdsaWIvc3RyaW5nX2Zvcm1hdC5oIGIvUHl0aG9uLTIuNy41L09iamVjdHMvc3RyaW5nbGliL3N0cmluZ19mb3JtYXQuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45NjVlMWFkCi0tLSAvZGV2L251bGwKKysrIGIvUHl0aG9uLTIuNy41L09iamVjdHMvc3RyaW5nbGliL3N0cmluZ19mb3JtYXQuaApAQCAtMCwwICsxLDEzNjEgQEAKKy8qCisgICAgc3RyaW5nX2Zvcm1hdC5oIC0tIGltcGxlbWVudGF0aW9uIG9mIHN0cmluZy5mb3JtYXQoKS4KKworICAgIEl0IHVzZXMgdGhlIE9iamVjdHMvc3RyaW5nbGliIGNvbnZlbnRpb25zLCBzbyB0aGF0IGl0IGNhbiBiZQorICAgIGNvbXBpbGVkIGZvciBib3RoIHVuaWNvZGUgYW5kIHN0cmluZyBvYmplY3RzLgorKi8KKworCisvKiBEZWZpbmVzIGZvciBQeXRob24gMi42IGNvbXBhdGliaWxpdHkgKi8KKyNpZiBQWV9WRVJTSU9OX0hFWCA8IDB4MDMwMDAwMDAKKyNkZWZpbmUgUHlMb25nX0Zyb21Tc2l6ZV90IF9QeUxvbmdfRnJvbVNzaXplX3QKKyNlbmRpZgorCisvKiBEZWZpbmVzIGZvciBtb3JlIGVmZmljaWVudGx5IHJlYWxsb2NhdGluZyB0aGUgc3RyaW5nIGJ1ZmZlciAqLworI2RlZmluZSBJTklUSUFMX1NJWkVfSU5DUkVNRU5UIDEwMAorI2RlZmluZSBTSVpFX01VTFRJUExJRVIgMgorI2RlZmluZSBNQVhfU0laRV9JTkNSRU1FTlQgIDMyMDAKKworCisvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLworLyoqKioqKioqKioqICAgR2xvYmFsIGRhdGEgc3RydWN0dXJlcyBhbmQgZm9yd2FyZCBkZWNsYXJhdGlvbnMgICoqKioqKioqKi8KKy8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCisKKy8qCisgICBBIFN1YlN0cmluZyBjb25zaXN0cyBvZiB0aGUgY2hhcmFjdGVycyBiZXR3ZWVuIHR3byBzdHJpbmcgb3IKKyAgIHVuaWNvZGUgcG9pbnRlcnMuCisqLwordHlwZWRlZiBzdHJ1Y3QgeworICAgIFNUUklOR0xJQl9DSEFSICpwdHI7CisgICAgU1RSSU5HTElCX0NIQVIgKmVuZDsKK30gU3ViU3RyaW5nOworCisKK3R5cGVkZWYgZW51bSB7CisgICAgQU5TX0lOSVQsCisgICAgQU5TX0FVVE8sCisgICAgQU5TX01BTlVBTAorfSBBdXRvTnVtYmVyU3RhdGU7ICAgLyogS2VlcCB0cmFjayBpZiB3ZSdyZSBhdXRvLW51bWJlcmluZyBmaWVsZHMgKi8KKworLyogS2VlcHMgdHJhY2sgb2Ygb3VyIGF1dG8tbnVtYmVyaW5nIHN0YXRlLCBhbmQgd2hpY2ggbnVtYmVyIGZpZWxkIHdlJ3JlIG9uICovCit0eXBlZGVmIHN0cnVjdCB7CisgICAgQXV0b051bWJlclN0YXRlIGFuX3N0YXRlOworICAgIGludCBhbl9maWVsZF9udW1iZXI7Cit9IEF1dG9OdW1iZXI7CisKKworLyogZm9yd2FyZCBkZWNsYXJhdGlvbiBmb3IgcmVjdXJzaW9uICovCitzdGF0aWMgUHlPYmplY3QgKgorYnVpbGRfc3RyaW5nKFN1YlN0cmluZyAqaW5wdXQsIFB5T2JqZWN0ICphcmdzLCBQeU9iamVjdCAqa3dhcmdzLAorICAgICAgICAgICAgIGludCByZWN1cnNpb25fZGVwdGgsIEF1dG9OdW1iZXIgKmF1dG9fbnVtYmVyKTsKKworCisKKy8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCisvKioqKioqKioqKioqKioqKioqKioqKioqKiogIFV0aWxpdHkgIGZ1bmN0aW9ucyAgKioqKioqKioqKioqKioqKioqKioqKioqLworLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KKworc3RhdGljIHZvaWQKK0F1dG9OdW1iZXJfSW5pdChBdXRvTnVtYmVyICphdXRvX251bWJlcikKK3sKKyAgICBhdXRvX251bWJlci0+YW5fc3RhdGUgPSBBTlNfSU5JVDsKKyAgICBhdXRvX251bWJlci0+YW5fZmllbGRfbnVtYmVyID0gMDsKK30KKworLyogZmlsbCBpbiBhIFN1YlN0cmluZyBmcm9tIGEgcG9pbnRlciBhbmQgbGVuZ3RoICovCitQeV9MT0NBTF9JTkxJTkUodm9pZCkKK1N1YlN0cmluZ19pbml0KFN1YlN0cmluZyAqc3RyLCBTVFJJTkdMSUJfQ0hBUiAqcCwgUHlfc3NpemVfdCBsZW4pCit7CisgICAgc3RyLT5wdHIgPSBwOworICAgIGlmIChwID09IE5VTEwpCisgICAgICAgIHN0ci0+ZW5kID0gTlVMTDsKKyAgICBlbHNlCisgICAgICAgIHN0ci0+ZW5kID0gc3RyLT5wdHIgKyBsZW47Cit9CisKKy8qIHJldHVybiBhIG5ldyBzdHJpbmcuICBpZiBzdHItPnB0ciBpcyBOVUxMLCByZXR1cm4gTm9uZSAqLworUHlfTE9DQUxfSU5MSU5FKFB5T2JqZWN0ICopCitTdWJTdHJpbmdfbmV3X29iamVjdChTdWJTdHJpbmcgKnN0cikKK3sKKyAgICBpZiAoc3RyLT5wdHIgPT0gTlVMTCkgeworICAgICAgICBQeV9JTkNSRUYoUHlfTm9uZSk7CisgICAgICAgIHJldHVybiBQeV9Ob25lOworICAgIH0KKyAgICByZXR1cm4gU1RSSU5HTElCX05FVyhzdHItPnB0ciwgc3RyLT5lbmQgLSBzdHItPnB0cik7Cit9CisKKy8qIHJldHVybiBhIG5ldyBzdHJpbmcuICBpZiBzdHItPnB0ciBpcyBOVUxMLCByZXR1cm4gTm9uZSAqLworUHlfTE9DQUxfSU5MSU5FKFB5T2JqZWN0ICopCitTdWJTdHJpbmdfbmV3X29iamVjdF9vcl9lbXB0eShTdWJTdHJpbmcgKnN0cikKK3sKKyAgICBpZiAoc3RyLT5wdHIgPT0gTlVMTCkgeworICAgICAgICByZXR1cm4gU1RSSU5HTElCX05FVyhOVUxMLCAwKTsKKyAgICB9CisgICAgcmV0dXJuIFNUUklOR0xJQl9ORVcoc3RyLT5wdHIsIHN0ci0+ZW5kIC0gc3RyLT5wdHIpOworfQorCisvKiBSZXR1cm4gMSBpZiBhbiBlcnJvciBoYXMgYmVlbiBkZXRlY3RlZCBzd2l0Y2hpbmcgYmV0d2VlbiBhdXRvbWF0aWMKKyAgIGZpZWxkIG51bWJlcmluZyBhbmQgbWFudWFsIGZpZWxkIHNwZWNpZmljYXRpb24sIGVsc2UgcmV0dXJuIDAuIFNldAorICAgVmFsdWVFcnJvciBvbiBlcnJvci4gKi8KK3N0YXRpYyBpbnQKK2F1dG9udW1iZXJfc3RhdGVfZXJyb3IoQXV0b051bWJlclN0YXRlIHN0YXRlLCBpbnQgZmllbGRfbmFtZV9pc19lbXB0eSkKK3sKKyAgICBpZiAoc3RhdGUgPT0gQU5TX01BTlVBTCkgeworICAgICAgICBpZiAoZmllbGRfbmFtZV9pc19lbXB0eSkgeworICAgICAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1ZhbHVlRXJyb3IsICJjYW5ub3Qgc3dpdGNoIGZyb20gIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICJtYW51YWwgZmllbGQgc3BlY2lmaWNhdGlvbiB0byAiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgImF1dG9tYXRpYyBmaWVsZCBudW1iZXJpbmciKTsKKyAgICAgICAgICAgIHJldHVybiAxOworICAgICAgICB9CisgICAgfQorICAgIGVsc2UgeworICAgICAgICBpZiAoIWZpZWxkX25hbWVfaXNfZW1wdHkpIHsKKyAgICAgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19WYWx1ZUVycm9yLCAiY2Fubm90IHN3aXRjaCBmcm9tICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAiYXV0b21hdGljIGZpZWxkIG51bWJlcmluZyB0byAiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIm1hbnVhbCBmaWVsZCBzcGVjaWZpY2F0aW9uIik7CisgICAgICAgICAgICByZXR1cm4gMTsKKyAgICAgICAgfQorICAgIH0KKyAgICByZXR1cm4gMDsKK30KKworCisvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLworLyoqKioqKioqKioqICAgIE91dHB1dCBzdHJpbmcgbWFuYWdlbWVudCBmdW5jdGlvbnMgICAgICAgKioqKioqKioqKioqKioqKi8KKy8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCisKK3R5cGVkZWYgc3RydWN0IHsKKyAgICBTVFJJTkdMSUJfQ0hBUiAqcHRyOworICAgIFNUUklOR0xJQl9DSEFSICplbmQ7CisgICAgUHlPYmplY3QgKm9iajsKKyAgICBQeV9zc2l6ZV90IHNpemVfaW5jcmVtZW50OworfSBPdXRwdXRTdHJpbmc7CisKKy8qIGluaXRpYWxpemUgYW4gT3V0cHV0U3RyaW5nIG9iamVjdCwgcmVzZXJ2aW5nIHNpemUgY2hhcmFjdGVycyAqLworc3RhdGljIGludAorb3V0cHV0X2luaXRpYWxpemUoT3V0cHV0U3RyaW5nICpvdXRwdXQsIFB5X3NzaXplX3Qgc2l6ZSkKK3sKKyAgICBvdXRwdXQtPm9iaiA9IFNUUklOR0xJQl9ORVcoTlVMTCwgc2l6ZSk7CisgICAgaWYgKG91dHB1dC0+b2JqID09IE5VTEwpCisgICAgICAgIHJldHVybiAwOworCisgICAgb3V0cHV0LT5wdHIgPSBTVFJJTkdMSUJfU1RSKG91dHB1dC0+b2JqKTsKKyAgICBvdXRwdXQtPmVuZCA9IFNUUklOR0xJQl9MRU4ob3V0cHV0LT5vYmopICsgb3V0cHV0LT5wdHI7CisgICAgb3V0cHV0LT5zaXplX2luY3JlbWVudCA9IElOSVRJQUxfU0laRV9JTkNSRU1FTlQ7CisKKyAgICByZXR1cm4gMTsKK30KKworLyoKKyAgICBvdXRwdXRfZXh0ZW5kIHJlYWxsb2NhdGVzIHRoZSBvdXRwdXQgc3RyaW5nIGJ1ZmZlci4KKyAgICBJdCByZXR1cm5zIGEgc3RhdHVzOiAgMCBmb3IgYSBmYWlsZWQgcmVhbGxvY2F0aW9uLAorICAgIDEgZm9yIHN1Y2Nlc3MuCisqLworCitzdGF0aWMgaW50CitvdXRwdXRfZXh0ZW5kKE91dHB1dFN0cmluZyAqb3V0cHV0LCBQeV9zc2l6ZV90IGNvdW50KQoreworICAgIFNUUklOR0xJQl9DSEFSICpzdGFydHB0ciA9IFNUUklOR0xJQl9TVFIob3V0cHV0LT5vYmopOworICAgIFB5X3NzaXplX3QgY3VybGVuID0gb3V0cHV0LT5wdHIgLSBzdGFydHB0cjsKKyAgICBQeV9zc2l6ZV90IG1heGxlbiA9IGN1cmxlbiArIGNvdW50ICsgb3V0cHV0LT5zaXplX2luY3JlbWVudDsKKworICAgIGlmIChTVFJJTkdMSUJfUkVTSVpFKCZvdXRwdXQtPm9iaiwgbWF4bGVuKSA8IDApCisgICAgICAgIHJldHVybiAwOworICAgIHN0YXJ0cHRyID0gU1RSSU5HTElCX1NUUihvdXRwdXQtPm9iaik7CisgICAgb3V0cHV0LT5wdHIgPSBzdGFydHB0ciArIGN1cmxlbjsKKyAgICBvdXRwdXQtPmVuZCA9IHN0YXJ0cHRyICsgbWF4bGVuOworICAgIGlmIChvdXRwdXQtPnNpemVfaW5jcmVtZW50IDwgTUFYX1NJWkVfSU5DUkVNRU5UKQorICAgICAgICBvdXRwdXQtPnNpemVfaW5jcmVtZW50ICo9IFNJWkVfTVVMVElQTElFUjsKKyAgICByZXR1cm4gMTsKK30KKworLyoKKyAgICBvdXRwdXRfZGF0YSBkdW1wcyBjaGFyYWN0ZXJzIGludG8gb3VyIG91dHB1dCBzdHJpbmcKKyAgICBidWZmZXIuCisKKyAgICBJbiBzb21lIGNhc2VzLCBpdCBoYXMgdG8gcmVhbGxvY2F0ZSB0aGUgc3RyaW5nLgorCisgICAgSXQgcmV0dXJucyBhIHN0YXR1czogIDAgZm9yIGEgZmFpbGVkIHJlYWxsb2NhdGlvbiwKKyAgICAxIGZvciBzdWNjZXNzLgorKi8KK3N0YXRpYyBpbnQKK291dHB1dF9kYXRhKE91dHB1dFN0cmluZyAqb3V0cHV0LCBjb25zdCBTVFJJTkdMSUJfQ0hBUiAqcywgUHlfc3NpemVfdCBjb3VudCkKK3sKKyAgICBpZiAoKGNvdW50ID4gb3V0cHV0LT5lbmQgLSBvdXRwdXQtPnB0cikgJiYgIW91dHB1dF9leHRlbmQob3V0cHV0LCBjb3VudCkpCisgICAgICAgIHJldHVybiAwOworICAgIG1lbWNweShvdXRwdXQtPnB0ciwgcywgY291bnQgKiBzaXplb2YoU1RSSU5HTElCX0NIQVIpKTsKKyAgICBvdXRwdXQtPnB0ciArPSBjb3VudDsKKyAgICByZXR1cm4gMTsKK30KKworLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KKy8qKioqKioqKioqKiAgRm9ybWF0IHN0cmluZyBwYXJzaW5nIC0tIGludGVnZXJzIGFuZCBpZGVudGlmaWVycyAqKioqKioqKiovCisvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLworCitzdGF0aWMgUHlfc3NpemVfdAorZ2V0X2ludGVnZXIoY29uc3QgU3ViU3RyaW5nICpzdHIpCit7CisgICAgUHlfc3NpemVfdCBhY2N1bXVsYXRvciA9IDA7CisgICAgUHlfc3NpemVfdCBkaWdpdHZhbDsKKyAgICBTVFJJTkdMSUJfQ0hBUiAqcDsKKworICAgIC8qIGVtcHR5IHN0cmluZyBpcyBhbiBlcnJvciAqLworICAgIGlmIChzdHItPnB0ciA+PSBzdHItPmVuZCkKKyAgICAgICAgcmV0dXJuIC0xOworCisgICAgZm9yIChwID0gc3RyLT5wdHI7IHAgPCBzdHItPmVuZDsgcCsrKSB7CisgICAgICAgIGRpZ2l0dmFsID0gU1RSSU5HTElCX1RPREVDSU1BTCgqcCk7CisgICAgICAgIGlmIChkaWdpdHZhbCA8IDApCisgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgIC8qCisgICAgICAgICAgIERldGVjdCBwb3NzaWJsZSBvdmVyZmxvdyBiZWZvcmUgaXQgaGFwcGVuczoKKworICAgICAgICAgICAgICBhY2N1bXVsYXRvciAqIDEwICsgZGlnaXR2YWwgPiBQWV9TU0laRV9UX01BWCBpZiBhbmQgb25seSBpZgorICAgICAgICAgICAgICBhY2N1bXVsYXRvciA+IChQWV9TU0laRV9UX01BWCAtIGRpZ2l0dmFsKSAvIDEwLgorICAgICAgICAqLworICAgICAgICBpZiAoYWNjdW11bGF0b3IgPiAoUFlfU1NJWkVfVF9NQVggLSBkaWdpdHZhbCkgLyAxMCkgeworICAgICAgICAgICAgUHlFcnJfRm9ybWF0KFB5RXhjX1ZhbHVlRXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgIlRvbyBtYW55IGRlY2ltYWwgZGlnaXRzIGluIGZvcm1hdCBzdHJpbmciKTsKKyAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgfQorICAgICAgICBhY2N1bXVsYXRvciA9IGFjY3VtdWxhdG9yICogMTAgKyBkaWdpdHZhbDsKKyAgICB9CisgICAgcmV0dXJuIGFjY3VtdWxhdG9yOworfQorCisvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLworLyoqKioqKioqIEZ1bmN0aW9ucyB0byBnZXQgZmllbGQgb2JqZWN0cyBhbmQgc3BlY2lmaWNhdGlvbiBzdHJpbmdzICoqKioqKi8KKy8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCisKKy8qIGRvIHRoZSBlcXVpdmFsZW50IG9mIG9iai5uYW1lICovCitzdGF0aWMgUHlPYmplY3QgKgorZ2V0YXR0cihQeU9iamVjdCAqb2JqLCBTdWJTdHJpbmcgKm5hbWUpCit7CisgICAgUHlPYmplY3QgKm5ld29iajsKKyAgICBQeU9iamVjdCAqc3RyID0gU3ViU3RyaW5nX25ld19vYmplY3QobmFtZSk7CisgICAgaWYgKHN0ciA9PSBOVUxMKQorICAgICAgICByZXR1cm4gTlVMTDsKKyAgICBuZXdvYmogPSBQeU9iamVjdF9HZXRBdHRyKG9iaiwgc3RyKTsKKyAgICBQeV9ERUNSRUYoc3RyKTsKKyAgICByZXR1cm4gbmV3b2JqOworfQorCisvKiBkbyB0aGUgZXF1aXZhbGVudCBvZiBvYmpbaWR4XSwgd2hlcmUgb2JqIGlzIGEgc2VxdWVuY2UgKi8KK3N0YXRpYyBQeU9iamVjdCAqCitnZXRpdGVtX3NlcXVlbmNlKFB5T2JqZWN0ICpvYmosIFB5X3NzaXplX3QgaWR4KQoreworICAgIHJldHVybiBQeVNlcXVlbmNlX0dldEl0ZW0ob2JqLCBpZHgpOworfQorCisvKiBkbyB0aGUgZXF1aXZhbGVudCBvZiBvYmpbaWR4XSwgd2hlcmUgb2JqIGlzIG5vdCBhIHNlcXVlbmNlICovCitzdGF0aWMgUHlPYmplY3QgKgorZ2V0aXRlbV9pZHgoUHlPYmplY3QgKm9iaiwgUHlfc3NpemVfdCBpZHgpCit7CisgICAgUHlPYmplY3QgKm5ld29iajsKKyAgICBQeU9iamVjdCAqaWR4X29iaiA9IFB5TG9uZ19Gcm9tU3NpemVfdChpZHgpOworICAgIGlmIChpZHhfb2JqID09IE5VTEwpCisgICAgICAgIHJldHVybiBOVUxMOworICAgIG5ld29iaiA9IFB5T2JqZWN0X0dldEl0ZW0ob2JqLCBpZHhfb2JqKTsKKyAgICBQeV9ERUNSRUYoaWR4X29iaik7CisgICAgcmV0dXJuIG5ld29iajsKK30KKworLyogZG8gdGhlIGVxdWl2YWxlbnQgb2Ygb2JqW25hbWVdICovCitzdGF0aWMgUHlPYmplY3QgKgorZ2V0aXRlbV9zdHIoUHlPYmplY3QgKm9iaiwgU3ViU3RyaW5nICpuYW1lKQoreworICAgIFB5T2JqZWN0ICpuZXdvYmo7CisgICAgUHlPYmplY3QgKnN0ciA9IFN1YlN0cmluZ19uZXdfb2JqZWN0KG5hbWUpOworICAgIGlmIChzdHIgPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgbmV3b2JqID0gUHlPYmplY3RfR2V0SXRlbShvYmosIHN0cik7CisgICAgUHlfREVDUkVGKHN0cik7CisgICAgcmV0dXJuIG5ld29iajsKK30KKwordHlwZWRlZiBzdHJ1Y3QgeworICAgIC8qIHRoZSBlbnRpcmUgc3RyaW5nIHdlJ3JlIHBhcnNpbmcuICB3ZSBhc3N1bWUgdGhhdCBzb21lb25lIGVsc2UKKyAgICAgICBpcyBtYW5hZ2luZyBpdHMgbGlmZXRpbWUsIGFuZCB0aGF0IGl0IHdpbGwgZXhpc3QgZm9yIHRoZQorICAgICAgIGxpZmV0aW1lIG9mIHRoZSBpdGVyYXRvci4gIGNhbiBiZSBlbXB0eSAqLworICAgIFN1YlN0cmluZyBzdHI7CisKKyAgICAvKiBwb2ludGVyIHRvIHdoZXJlIHdlIGFyZSBpbnNpZGUgZmllbGRfbmFtZSAqLworICAgIFNUUklOR0xJQl9DSEFSICpwdHI7Cit9IEZpZWxkTmFtZUl0ZXJhdG9yOworCisKK3N0YXRpYyBpbnQKK0ZpZWxkTmFtZUl0ZXJhdG9yX2luaXQoRmllbGROYW1lSXRlcmF0b3IgKnNlbGYsIFNUUklOR0xJQl9DSEFSICpwdHIsCisgICAgICAgICAgICAgICAgICAgICAgIFB5X3NzaXplX3QgbGVuKQoreworICAgIFN1YlN0cmluZ19pbml0KCZzZWxmLT5zdHIsIHB0ciwgbGVuKTsKKyAgICBzZWxmLT5wdHIgPSBzZWxmLT5zdHIucHRyOworICAgIHJldHVybiAxOworfQorCitzdGF0aWMgaW50CitfRmllbGROYW1lSXRlcmF0b3JfYXR0cihGaWVsZE5hbWVJdGVyYXRvciAqc2VsZiwgU3ViU3RyaW5nICpuYW1lKQoreworICAgIFNUUklOR0xJQl9DSEFSIGM7CisKKyAgICBuYW1lLT5wdHIgPSBzZWxmLT5wdHI7CisKKyAgICAvKiByZXR1cm4gZXZlcnl0aGluZyB1bnRpbCAnLicgb3IgJ1snICovCisgICAgd2hpbGUgKHNlbGYtPnB0ciA8IHNlbGYtPnN0ci5lbmQpIHsKKyAgICAgICAgc3dpdGNoIChjID0gKnNlbGYtPnB0cisrKSB7CisgICAgICAgIGNhc2UgJ1snOgorICAgICAgICBjYXNlICcuJzoKKyAgICAgICAgICAgIC8qIGJhY2t1cCBzbyB0aGF0IHdlIHRoaXMgY2hhcmFjdGVyIHdpbGwgYmUgc2VlbiBuZXh0IHRpbWUgKi8KKyAgICAgICAgICAgIHNlbGYtPnB0ci0tOworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgfQorICAgICAgICBicmVhazsKKyAgICB9CisgICAgLyogZW5kIG9mIHN0cmluZyBpcyBva2F5ICovCisgICAgbmFtZS0+ZW5kID0gc2VsZi0+cHRyOworICAgIHJldHVybiAxOworfQorCitzdGF0aWMgaW50CitfRmllbGROYW1lSXRlcmF0b3JfaXRlbShGaWVsZE5hbWVJdGVyYXRvciAqc2VsZiwgU3ViU3RyaW5nICpuYW1lKQoreworICAgIGludCBicmFja2V0X3NlZW4gPSAwOworICAgIFNUUklOR0xJQl9DSEFSIGM7CisKKyAgICBuYW1lLT5wdHIgPSBzZWxmLT5wdHI7CisKKyAgICAvKiByZXR1cm4gZXZlcnl0aGluZyB1bnRpbCAnXScgKi8KKyAgICB3aGlsZSAoc2VsZi0+cHRyIDwgc2VsZi0+c3RyLmVuZCkgeworICAgICAgICBzd2l0Y2ggKGMgPSAqc2VsZi0+cHRyKyspIHsKKyAgICAgICAgY2FzZSAnXSc6CisgICAgICAgICAgICBicmFja2V0X3NlZW4gPSAxOworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgfQorICAgICAgICBicmVhazsKKyAgICB9CisgICAgLyogbWFrZSBzdXJlIHdlIGVuZGVkIHdpdGggYSAnXScgKi8KKyAgICBpZiAoIWJyYWNrZXRfc2VlbikgeworICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfVmFsdWVFcnJvciwgIk1pc3NpbmcgJ10nIGluIGZvcm1hdCBzdHJpbmciKTsKKyAgICAgICAgcmV0dXJuIDA7CisgICAgfQorCisgICAgLyogZW5kIG9mIHN0cmluZyBpcyBva2F5ICovCisgICAgLyogZG9uJ3QgaW5jbHVkZSB0aGUgJ10nICovCisgICAgbmFtZS0+ZW5kID0gc2VsZi0+cHRyLTE7CisgICAgcmV0dXJuIDE7Cit9CisKKy8qIHJldHVybnMgMCBvbiBlcnJvciwgMSBvbiBub24tZXJyb3IgdGVybWluYXRpb24sIGFuZCAyIGlmIGl0IHJldHVybnMgYSB2YWx1ZSAqLworc3RhdGljIGludAorRmllbGROYW1lSXRlcmF0b3JfbmV4dChGaWVsZE5hbWVJdGVyYXRvciAqc2VsZiwgaW50ICppc19hdHRyaWJ1dGUsCisgICAgICAgICAgICAgICAgICAgICAgIFB5X3NzaXplX3QgKm5hbWVfaWR4LCBTdWJTdHJpbmcgKm5hbWUpCit7CisgICAgLyogY2hlY2sgYXQgZW5kIG9mIGlucHV0ICovCisgICAgaWYgKHNlbGYtPnB0ciA+PSBzZWxmLT5zdHIuZW5kKQorICAgICAgICByZXR1cm4gMTsKKworICAgIHN3aXRjaCAoKnNlbGYtPnB0cisrKSB7CisgICAgY2FzZSAnLic6CisgICAgICAgICppc19hdHRyaWJ1dGUgPSAxOworICAgICAgICBpZiAoX0ZpZWxkTmFtZUl0ZXJhdG9yX2F0dHIoc2VsZiwgbmFtZSkgPT0gMCkKKyAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICAqbmFtZV9pZHggPSAtMTsKKyAgICAgICAgYnJlYWs7CisgICAgY2FzZSAnWyc6CisgICAgICAgICppc19hdHRyaWJ1dGUgPSAwOworICAgICAgICBpZiAoX0ZpZWxkTmFtZUl0ZXJhdG9yX2l0ZW0oc2VsZiwgbmFtZSkgPT0gMCkKKyAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICAqbmFtZV9pZHggPSBnZXRfaW50ZWdlcihuYW1lKTsKKyAgICAgICAgaWYgKCpuYW1lX2lkeCA9PSAtMSAmJiBQeUVycl9PY2N1cnJlZCgpKQorICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgIGJyZWFrOworICAgIGRlZmF1bHQ6CisgICAgICAgIC8qIEludmFsaWQgY2hhcmFjdGVyIGZvbGxvd3MgJ10nICovCisgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19WYWx1ZUVycm9yLCAiT25seSAnLicgb3IgJ1snIG1heSAiCisgICAgICAgICAgICAgICAgICAgICAgICAiZm9sbG93ICddJyBpbiBmb3JtYXQgZmllbGQgc3BlY2lmaWVyIik7CisgICAgICAgIHJldHVybiAwOworICAgIH0KKworICAgIC8qIGVtcHR5IHN0cmluZyBpcyBhbiBlcnJvciAqLworICAgIGlmIChuYW1lLT5wdHIgPT0gbmFtZS0+ZW5kKSB7CisgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19WYWx1ZUVycm9yLCAiRW1wdHkgYXR0cmlidXRlIGluIGZvcm1hdCBzdHJpbmciKTsKKyAgICAgICAgcmV0dXJuIDA7CisgICAgfQorCisgICAgcmV0dXJuIDI7Cit9CisKKworLyogaW5wdXQ6IGZpZWxkX25hbWUKKyAgIG91dHB1dDogJ2ZpcnN0JyBwb2ludHMgdG8gdGhlIHBhcnQgYmVmb3JlIHRoZSBmaXJzdCAnWycgb3IgJy4nCisgICAgICAgICAgICdmaXJzdF9pZHgnIGlzIC0xIGlmICdmaXJzdCcgaXMgbm90IGFuIGludGVnZXIsIG90aGVyd2lzZQorICAgICAgICAgICAgICAgICAgICAgICBpdCdzIHRoZSB2YWx1ZSBvZiBmaXJzdCBjb252ZXJ0ZWQgdG8gYW4gaW50ZWdlcgorICAgICAgICAgICAncmVzdCcgaXMgYW4gaXRlcmF0b3IgdG8gcmV0dXJuIHRoZSByZXN0CisqLworc3RhdGljIGludAorZmllbGRfbmFtZV9zcGxpdChTVFJJTkdMSUJfQ0hBUiAqcHRyLCBQeV9zc2l6ZV90IGxlbiwgU3ViU3RyaW5nICpmaXJzdCwKKyAgICAgICAgICAgICAgICAgUHlfc3NpemVfdCAqZmlyc3RfaWR4LCBGaWVsZE5hbWVJdGVyYXRvciAqcmVzdCwKKyAgICAgICAgICAgICAgICAgQXV0b051bWJlciAqYXV0b19udW1iZXIpCit7CisgICAgU1RSSU5HTElCX0NIQVIgYzsKKyAgICBTVFJJTkdMSUJfQ0hBUiAqcCA9IHB0cjsKKyAgICBTVFJJTkdMSUJfQ0hBUiAqZW5kID0gcHRyICsgbGVuOworICAgIGludCBmaWVsZF9uYW1lX2lzX2VtcHR5OworICAgIGludCB1c2luZ19udW1lcmljX2luZGV4OworCisgICAgLyogZmluZCB0aGUgcGFydCB1cCB1bnRpbCB0aGUgZmlyc3QgJy4nIG9yICdbJyAqLworICAgIHdoaWxlIChwIDwgZW5kKSB7CisgICAgICAgIHN3aXRjaCAoYyA9ICpwKyspIHsKKyAgICAgICAgY2FzZSAnWyc6CisgICAgICAgIGNhc2UgJy4nOgorICAgICAgICAgICAgLyogYmFja3VwIHNvIHRoYXQgd2UgdGhpcyBjaGFyYWN0ZXIgaXMgYXZhaWxhYmxlIHRvIHRoZQorICAgICAgICAgICAgICAgInJlc3QiIGl0ZXJhdG9yICovCisgICAgICAgICAgICBwLS07CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICB9CisgICAgICAgIGJyZWFrOworICAgIH0KKworICAgIC8qIHNldCB1cCB0aGUgcmV0dXJuIHZhbHVlcyAqLworICAgIFN1YlN0cmluZ19pbml0KGZpcnN0LCBwdHIsIHAgLSBwdHIpOworICAgIEZpZWxkTmFtZUl0ZXJhdG9yX2luaXQocmVzdCwgcCwgZW5kIC0gcCk7CisKKyAgICAvKiBzZWUgaWYgImZpcnN0IiBpcyBhbiBpbnRlZ2VyLCBpbiB3aGljaCBjYXNlIGl0J3MgdXNlZCBhcyBhbiBpbmRleCAqLworICAgICpmaXJzdF9pZHggPSBnZXRfaW50ZWdlcihmaXJzdCk7CisgICAgaWYgKCpmaXJzdF9pZHggPT0gLTEgJiYgUHlFcnJfT2NjdXJyZWQoKSkKKyAgICAgICAgcmV0dXJuIDA7CisKKyAgICBmaWVsZF9uYW1lX2lzX2VtcHR5ID0gZmlyc3QtPnB0ciA+PSBmaXJzdC0+ZW5kOworCisgICAgLyogSWYgdGhlIGZpZWxkIG5hbWUgaXMgb21pdHRlZCBvciBpZiB3ZSBoYXZlIGEgbnVtZXJpYyBpbmRleAorICAgICAgIHNwZWNpZmllZCwgdGhlbiB3ZSdyZSBkb2luZyBudW1lcmljIGluZGV4aW5nIGludG8gYXJncy4gKi8KKyAgICB1c2luZ19udW1lcmljX2luZGV4ID0gZmllbGRfbmFtZV9pc19lbXB0eSB8fCAqZmlyc3RfaWR4ICE9IC0xOworCisgICAgLyogV2UgYWx3YXlzIGdldCBoZXJlIGV4YWN0bHkgb25lIHRpbWUgZm9yIGVhY2ggZmllbGQgd2UncmUKKyAgICAgICBwcm9jZXNzaW5nLiBBbmQgd2UgZ2V0IGhlcmUgaW4gZmllbGQgb3JkZXIgKGNvdW50aW5nIGJ5IGxlZnQKKyAgICAgICBicmFjZXMpLiBTbyB0aGlzIGlzIHRoZSBwZXJmZWN0IHBsYWNlIHRvIGhhbmRsZSBhdXRvbWF0aWMgZmllbGQKKyAgICAgICBudW1iZXJpbmcgaWYgdGhlIGZpZWxkIG5hbWUgaXMgb21pdHRlZC4gKi8KKworICAgIC8qIENoZWNrIGlmIHdlIG5lZWQgdG8gZG8gdGhlIGF1dG8tbnVtYmVyaW5nLiBJdCdzIG5vdCBuZWVkZWQgaWYKKyAgICAgICB3ZSdyZSBjYWxsZWQgZnJvbSBzdHJpbmcuRm9ybWF0IHJvdXRpbmVzLCBiZWNhdXNlIGl0J3MgaGFuZGxlZAorICAgICAgIGluIHRoYXQgY2xhc3MgYnkgaXRzZWxmLiAqLworICAgIGlmIChhdXRvX251bWJlcikgeworICAgICAgICAvKiBJbml0aWFsaXplIG91ciBhdXRvIG51bWJlcmluZyBzdGF0ZSBpZiB0aGlzIGlzIHRoZSBmaXJzdAorICAgICAgICAgICB0aW1lIHdlJ3JlIGVpdGhlciBhdXRvLW51bWJlcmluZyBvciBtYW51YWxseSBudW1iZXJpbmcuICovCisgICAgICAgIGlmIChhdXRvX251bWJlci0+YW5fc3RhdGUgPT0gQU5TX0lOSVQgJiYgdXNpbmdfbnVtZXJpY19pbmRleCkKKyAgICAgICAgICAgIGF1dG9fbnVtYmVyLT5hbl9zdGF0ZSA9IGZpZWxkX25hbWVfaXNfZW1wdHkgPworICAgICAgICAgICAgICAgIEFOU19BVVRPIDogQU5TX01BTlVBTDsKKworICAgICAgICAvKiBNYWtlIHN1cmUgb3VyIHN0YXRlIGlzIGNvbnNpc3RlbnQgd2l0aCB3aGF0IHdlJ3JlIGRvaW5nCisgICAgICAgICAgIHRoaXMgdGltZSB0aHJvdWdoLiBPbmx5IGNoZWNrIGlmIHdlJ3JlIHVzaW5nIGEgbnVtZXJpYworICAgICAgICAgICBpbmRleC4gKi8KKyAgICAgICAgaWYgKHVzaW5nX251bWVyaWNfaW5kZXgpCisgICAgICAgICAgICBpZiAoYXV0b251bWJlcl9zdGF0ZV9lcnJvcihhdXRvX251bWJlci0+YW5fc3RhdGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWVsZF9uYW1lX2lzX2VtcHR5KSkKKyAgICAgICAgICAgICAgICByZXR1cm4gMDsKKyAgICAgICAgLyogWmVybyBsZW5ndGggZmllbGQgbWVhbnMgd2Ugd2FudCB0byBkbyBhdXRvLW51bWJlcmluZyBvZiB0aGUKKyAgICAgICAgICAgZmllbGRzLiAqLworICAgICAgICBpZiAoZmllbGRfbmFtZV9pc19lbXB0eSkKKyAgICAgICAgICAgICpmaXJzdF9pZHggPSAoYXV0b19udW1iZXItPmFuX2ZpZWxkX251bWJlcikrKzsKKyAgICB9CisKKyAgICByZXR1cm4gMTsKK30KKworCisvKgorICAgIGdldF9maWVsZF9vYmplY3QgcmV0dXJucyB0aGUgb2JqZWN0IGluc2lkZSB7fSwgYmVmb3JlIHRoZQorICAgIGZvcm1hdF9zcGVjLiAgSXQgaGFuZGxlcyBnZXRpbmRleCBhbmQgZ2V0YXR0ciBsb29rdXBzIGFuZCBjb25zdW1lcworICAgIHRoZSBlbnRpcmUgaW5wdXQgc3RyaW5nLgorKi8KK3N0YXRpYyBQeU9iamVjdCAqCitnZXRfZmllbGRfb2JqZWN0KFN1YlN0cmluZyAqaW5wdXQsIFB5T2JqZWN0ICphcmdzLCBQeU9iamVjdCAqa3dhcmdzLAorICAgICAgICAgICAgICAgICBBdXRvTnVtYmVyICphdXRvX251bWJlcikKK3sKKyAgICBQeU9iamVjdCAqb2JqID0gTlVMTDsKKyAgICBpbnQgb2s7CisgICAgaW50IGlzX2F0dHJpYnV0ZTsKKyAgICBTdWJTdHJpbmcgbmFtZTsKKyAgICBTdWJTdHJpbmcgZmlyc3Q7CisgICAgUHlfc3NpemVfdCBpbmRleDsKKyAgICBGaWVsZE5hbWVJdGVyYXRvciByZXN0OworCisgICAgaWYgKCFmaWVsZF9uYW1lX3NwbGl0KGlucHV0LT5wdHIsIGlucHV0LT5lbmQgLSBpbnB1dC0+cHRyLCAmZmlyc3QsCisgICAgICAgICAgICAgICAgICAgICAgICAgICZpbmRleCwgJnJlc3QsIGF1dG9fbnVtYmVyKSkgeworICAgICAgICBnb3RvIGVycm9yOworICAgIH0KKworICAgIGlmIChpbmRleCA9PSAtMSkgeworICAgICAgICAvKiBsb29rIHVwIGluIGt3YXJncyAqLworICAgICAgICBQeU9iamVjdCAqa2V5ID0gU3ViU3RyaW5nX25ld19vYmplY3QoJmZpcnN0KTsKKyAgICAgICAgaWYgKGtleSA9PSBOVUxMKQorICAgICAgICAgICAgZ290byBlcnJvcjsKKyAgICAgICAgaWYgKChrd2FyZ3MgPT0gTlVMTCkgfHwgKG9iaiA9IFB5RGljdF9HZXRJdGVtKGt3YXJncywga2V5KSkgPT0gTlVMTCkgeworICAgICAgICAgICAgUHlFcnJfU2V0T2JqZWN0KFB5RXhjX0tleUVycm9yLCBrZXkpOworICAgICAgICAgICAgUHlfREVDUkVGKGtleSk7CisgICAgICAgICAgICBnb3RvIGVycm9yOworICAgICAgICB9CisgICAgICAgIFB5X0RFQ1JFRihrZXkpOworICAgICAgICBQeV9JTkNSRUYob2JqKTsKKyAgICB9CisgICAgZWxzZSB7CisgICAgICAgIC8qIGxvb2sgdXAgaW4gYXJncyAqLworICAgICAgICBvYmogPSBQeVNlcXVlbmNlX0dldEl0ZW0oYXJncywgaW5kZXgpOworICAgICAgICBpZiAob2JqID09IE5VTEwpCisgICAgICAgICAgICBnb3RvIGVycm9yOworICAgIH0KKworICAgIC8qIGl0ZXJhdGUgb3ZlciB0aGUgcmVzdCBvZiB0aGUgZmllbGRfbmFtZSAqLworICAgIHdoaWxlICgob2sgPSBGaWVsZE5hbWVJdGVyYXRvcl9uZXh0KCZyZXN0LCAmaXNfYXR0cmlidXRlLCAmaW5kZXgsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJm5hbWUpKSA9PSAyKSB7CisgICAgICAgIFB5T2JqZWN0ICp0bXA7CisKKyAgICAgICAgaWYgKGlzX2F0dHJpYnV0ZSkKKyAgICAgICAgICAgIC8qIGdldGF0dHIgbG9va3VwICIuIiAqLworICAgICAgICAgICAgdG1wID0gZ2V0YXR0cihvYmosICZuYW1lKTsKKyAgICAgICAgZWxzZQorICAgICAgICAgICAgLyogZ2V0aXRlbSBsb29rdXAgIltdIiAqLworICAgICAgICAgICAgaWYgKGluZGV4ID09IC0xKQorICAgICAgICAgICAgICAgIHRtcCA9IGdldGl0ZW1fc3RyKG9iaiwgJm5hbWUpOworICAgICAgICAgICAgZWxzZQorICAgICAgICAgICAgICAgIGlmIChQeVNlcXVlbmNlX0NoZWNrKG9iaikpCisgICAgICAgICAgICAgICAgICAgIHRtcCA9IGdldGl0ZW1fc2VxdWVuY2Uob2JqLCBpbmRleCk7CisgICAgICAgICAgICAgICAgZWxzZQorICAgICAgICAgICAgICAgICAgICAvKiBub3QgYSBzZXF1ZW5jZSAqLworICAgICAgICAgICAgICAgICAgICB0bXAgPSBnZXRpdGVtX2lkeChvYmosIGluZGV4KTsKKyAgICAgICAgaWYgKHRtcCA9PSBOVUxMKQorICAgICAgICAgICAgZ290byBlcnJvcjsKKworICAgICAgICAvKiBhc3NpZ24gdG8gb2JqICovCisgICAgICAgIFB5X0RFQ1JFRihvYmopOworICAgICAgICBvYmogPSB0bXA7CisgICAgfQorICAgIC8qIGVuZCBvZiBpdGVyYXRvciwgdGhpcyBpcyB0aGUgbm9uLWVycm9yIGNhc2UgKi8KKyAgICBpZiAob2sgPT0gMSkKKyAgICAgICAgcmV0dXJuIG9iajsKK2Vycm9yOgorICAgIFB5X1hERUNSRUYob2JqKTsKKyAgICByZXR1cm4gTlVMTDsKK30KKworLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KKy8qKioqKioqKioqKioqKioqKiAgRmllbGQgcmVuZGVyaW5nIGZ1bmN0aW9ucyAgKioqKioqKioqKioqKioqKioqKioqKioqKiovCisvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLworCisvKgorICAgIHJlbmRlcl9maWVsZCgpIGlzIHRoZSBtYWluIGZ1bmN0aW9uIGluIHRoaXMgc2VjdGlvbi4gIEl0IHRha2VzIHRoZQorICAgIGZpZWxkIG9iamVjdCBhbmQgZmllbGQgc3BlY2lmaWNhdGlvbiBzdHJpbmcgZ2VuZXJhdGVkIGJ5CisgICAgZ2V0X2ZpZWxkX2FuZF9zcGVjLCBhbmQgcmVuZGVycyB0aGUgZmllbGQgaW50byB0aGUgb3V0cHV0IHN0cmluZy4KKworICAgIHJlbmRlcl9maWVsZCBjYWxscyBmaWVsZG9iai5fX2Zvcm1hdF9fKGZvcm1hdF9zcGVjKSBtZXRob2QsIGFuZAorICAgIGFwcGVuZHMgdG8gdGhlIG91dHB1dC4KKyovCitzdGF0aWMgaW50CityZW5kZXJfZmllbGQoUHlPYmplY3QgKmZpZWxkb2JqLCBTdWJTdHJpbmcgKmZvcm1hdF9zcGVjLCBPdXRwdXRTdHJpbmcgKm91dHB1dCkKK3sKKyAgICBpbnQgb2sgPSAwOworICAgIFB5T2JqZWN0ICpyZXN1bHQgPSBOVUxMOworICAgIFB5T2JqZWN0ICpmb3JtYXRfc3BlY19vYmplY3QgPSBOVUxMOworICAgIFB5T2JqZWN0ICooKmZvcm1hdHRlcikoUHlPYmplY3QgKiwgU1RSSU5HTElCX0NIQVIgKiwgUHlfc3NpemVfdCkgPSBOVUxMOworICAgIFNUUklOR0xJQl9DSEFSKiBmb3JtYXRfc3BlY19zdGFydCA9IGZvcm1hdF9zcGVjLT5wdHIgPworICAgICAgICAgICAgZm9ybWF0X3NwZWMtPnB0ciA6IE5VTEw7CisgICAgUHlfc3NpemVfdCBmb3JtYXRfc3BlY19sZW4gPSBmb3JtYXRfc3BlYy0+cHRyID8KKyAgICAgICAgICAgIGZvcm1hdF9zcGVjLT5lbmQgLSBmb3JtYXRfc3BlYy0+cHRyIDogMDsKKworICAgIC8qIElmIHdlIGtub3cgdGhlIHR5cGUgZXhhY3RseSwgc2tpcCB0aGUgbG9va3VwIG9mIF9fZm9ybWF0X18gYW5kIGp1c3QKKyAgICAgICBjYWxsIHRoZSBmb3JtYXR0ZXIgZGlyZWN0bHkuICovCisjaWYgU1RSSU5HTElCX0lTX1VOSUNPREUKKyAgICBpZiAoUHlVbmljb2RlX0NoZWNrRXhhY3QoZmllbGRvYmopKQorICAgICAgICBmb3JtYXR0ZXIgPSBfUHlVbmljb2RlX0Zvcm1hdEFkdmFuY2VkOworICAgIC8qIFVuZm9ydHVuYXRlbHksIHRoZXJlJ3MgYSBwcm9ibGVtIHdpdGggY2hlY2tpbmcgZm9yIGludCwgbG9uZywKKyAgICAgICBhbmQgZmxvYXQgaGVyZS4gIElmIHdlJ3JlIGJlaW5nIGluY2x1ZGVkIGFzIHVuaWNvZGUsIHRoZWlyCisgICAgICAgZm9ybWF0dGVycyBleHBlY3Qgc3RyaW5nIGZvcm1hdF9zcGVjIGFyZ3MuICBGb3Igbm93LCBqdXN0IHNraXAKKyAgICAgICB0aGlzIG9wdGltaXphdGlvbiBmb3IgdW5pY29kZS4gIFRoaXMgY291bGQgYmUgZml4ZWQsIGJ1dCBpdCdzIGEKKyAgICAgICBoYXNzbGUuICovCisjZWxzZQorICAgIGlmIChQeVN0cmluZ19DaGVja0V4YWN0KGZpZWxkb2JqKSkKKyAgICAgICAgZm9ybWF0dGVyID0gX1B5Qnl0ZXNfRm9ybWF0QWR2YW5jZWQ7CisgICAgZWxzZSBpZiAoUHlJbnRfQ2hlY2tFeGFjdChmaWVsZG9iaikpCisgICAgICAgIGZvcm1hdHRlciA9X1B5SW50X0Zvcm1hdEFkdmFuY2VkOworICAgIGVsc2UgaWYgKFB5TG9uZ19DaGVja0V4YWN0KGZpZWxkb2JqKSkKKyAgICAgICAgZm9ybWF0dGVyID1fUHlMb25nX0Zvcm1hdEFkdmFuY2VkOworICAgIGVsc2UgaWYgKFB5RmxvYXRfQ2hlY2tFeGFjdChmaWVsZG9iaikpCisgICAgICAgIGZvcm1hdHRlciA9IF9QeUZsb2F0X0Zvcm1hdEFkdmFuY2VkOworI2VuZGlmCisKKyAgICBpZiAoZm9ybWF0dGVyKSB7CisgICAgICAgIC8qIHdlIGtub3cgZXhhY3RseSB3aGljaCBmb3JtYXR0ZXIgd2lsbCBiZSBjYWxsZWQgd2hlbiBfX2Zvcm1hdF9fIGlzCisgICAgICAgICAgIGxvb2tlZCB1cCwgc28gY2FsbCBpdCBkaXJlY3RseSwgaW5zdGVhZC4gKi8KKyAgICAgICAgcmVzdWx0ID0gZm9ybWF0dGVyKGZpZWxkb2JqLCBmb3JtYXRfc3BlY19zdGFydCwgZm9ybWF0X3NwZWNfbGVuKTsKKyAgICB9CisgICAgZWxzZSB7CisgICAgICAgIC8qIFdlIG5lZWQgdG8gY3JlYXRlIGFuIG9iamVjdCBvdXQgb2YgdGhlIHBvaW50ZXJzIHdlIGhhdmUsIGJlY2F1c2UKKyAgICAgICAgICAgX19mb3JtYXRfXyB0YWtlcyBhIHN0cmluZy91bmljb2RlIG9iamVjdCBmb3IgZm9ybWF0X3NwZWMuICovCisgICAgICAgIGZvcm1hdF9zcGVjX29iamVjdCA9IFNUUklOR0xJQl9ORVcoZm9ybWF0X3NwZWNfc3RhcnQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9ybWF0X3NwZWNfbGVuKTsKKyAgICAgICAgaWYgKGZvcm1hdF9zcGVjX29iamVjdCA9PSBOVUxMKQorICAgICAgICAgICAgZ290byBkb25lOworCisgICAgICAgIHJlc3VsdCA9IFB5T2JqZWN0X0Zvcm1hdChmaWVsZG9iaiwgZm9ybWF0X3NwZWNfb2JqZWN0KTsKKyAgICB9CisgICAgaWYgKHJlc3VsdCA9PSBOVUxMKQorICAgICAgICBnb3RvIGRvbmU7CisKKyNpZiBQWV9WRVJTSU9OX0hFWCA+PSAweDAzMDAwMDAwCisgICAgYXNzZXJ0KFB5VW5pY29kZV9DaGVjayhyZXN1bHQpKTsKKyNlbHNlCisgICAgYXNzZXJ0KFB5U3RyaW5nX0NoZWNrKHJlc3VsdCkgfHwgUHlVbmljb2RlX0NoZWNrKHJlc3VsdCkpOworCisgICAgLyogQ29udmVydCByZXN1bHQgdG8gb3VyIHR5cGUuICBXZSBjb3VsZCBiZSBzdHIsIGFuZCByZXN1bHQgY291bGQKKyAgICAgICBiZSB1bmljb2RlICovCisgICAgeworICAgICAgICBQeU9iamVjdCAqdG1wID0gU1RSSU5HTElCX1RPU1RSKHJlc3VsdCk7CisgICAgICAgIGlmICh0bXAgPT0gTlVMTCkKKyAgICAgICAgICAgIGdvdG8gZG9uZTsKKyAgICAgICAgUHlfREVDUkVGKHJlc3VsdCk7CisgICAgICAgIHJlc3VsdCA9IHRtcDsKKyAgICB9CisjZW5kaWYKKworICAgIG9rID0gb3V0cHV0X2RhdGEob3V0cHV0LAorICAgICAgICAgICAgICAgICAgICAgU1RSSU5HTElCX1NUUihyZXN1bHQpLCBTVFJJTkdMSUJfTEVOKHJlc3VsdCkpOworZG9uZToKKyAgICBQeV9YREVDUkVGKGZvcm1hdF9zcGVjX29iamVjdCk7CisgICAgUHlfWERFQ1JFRihyZXN1bHQpOworICAgIHJldHVybiBvazsKK30KKworc3RhdGljIGludAorcGFyc2VfZmllbGQoU3ViU3RyaW5nICpzdHIsIFN1YlN0cmluZyAqZmllbGRfbmFtZSwgU3ViU3RyaW5nICpmb3JtYXRfc3BlYywKKyAgICAgICAgICAgIFNUUklOR0xJQl9DSEFSICpjb252ZXJzaW9uKQoreworICAgIC8qIE5vdGUgdGhpcyBmdW5jdGlvbiB3b3JrcyBpZiB0aGUgZmllbGQgbmFtZSBpcyB6ZXJvIGxlbmd0aCwKKyAgICAgICB3aGljaCBpcyBnb29kLiAgWmVybyBsZW5ndGggZmllbGQgbmFtZXMgYXJlIGhhbmRsZWQgbGF0ZXIsIGluCisgICAgICAgZmllbGRfbmFtZV9zcGxpdC4gKi8KKworICAgIFNUUklOR0xJQl9DSEFSIGMgPSAwOworCisgICAgLyogaW5pdGlhbGl6ZSB0aGVzZSwgYXMgdGhleSBtYXkgYmUgZW1wdHkgKi8KKyAgICAqY29udmVyc2lvbiA9ICdcMCc7CisgICAgU3ViU3RyaW5nX2luaXQoZm9ybWF0X3NwZWMsIE5VTEwsIDApOworCisgICAgLyogU2VhcmNoIGZvciB0aGUgZmllbGQgbmFtZS4gIGl0J3MgdGVybWluYXRlZCBieSB0aGUgZW5kIG9mCisgICAgICAgdGhlIHN0cmluZywgb3IgYSAnOicgb3IgJyEnICovCisgICAgZmllbGRfbmFtZS0+cHRyID0gc3RyLT5wdHI7CisgICAgd2hpbGUgKHN0ci0+cHRyIDwgc3RyLT5lbmQpIHsKKyAgICAgICAgc3dpdGNoIChjID0gKihzdHItPnB0cisrKSkgeworICAgICAgICBjYXNlICc6JzoKKyAgICAgICAgY2FzZSAnISc6CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICB9CisgICAgICAgIGJyZWFrOworICAgIH0KKworICAgIGlmIChjID09ICchJyB8fCBjID09ICc6JykgeworICAgICAgICAvKiB3ZSBoYXZlIGEgZm9ybWF0IHNwZWNpZmllciBhbmQvb3IgYSBjb252ZXJzaW9uICovCisgICAgICAgIC8qIGRvbid0IGluY2x1ZGUgdGhlIGxhc3QgY2hhcmFjdGVyICovCisgICAgICAgIGZpZWxkX25hbWUtPmVuZCA9IHN0ci0+cHRyLTE7CisKKyAgICAgICAgLyogdGhlIGZvcm1hdCBzcGVjaWZpZXIgaXMgdGhlIHJlc3Qgb2YgdGhlIHN0cmluZyAqLworICAgICAgICBmb3JtYXRfc3BlYy0+cHRyID0gc3RyLT5wdHI7CisgICAgICAgIGZvcm1hdF9zcGVjLT5lbmQgPSBzdHItPmVuZDsKKworICAgICAgICAvKiBzZWUgaWYgdGhlcmUncyBhIGNvbnZlcnNpb24gc3BlY2lmaWVyICovCisgICAgICAgIGlmIChjID09ICchJykgeworICAgICAgICAgICAgLyogdGhlcmUgbXVzdCBiZSBhbm90aGVyIGNoYXJhY3RlciBwcmVzZW50ICovCisgICAgICAgICAgICBpZiAoZm9ybWF0X3NwZWMtPnB0ciA+PSBmb3JtYXRfc3BlYy0+ZW5kKSB7CisgICAgICAgICAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1ZhbHVlRXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJlbmQgb2YgZm9ybWF0IHdoaWxlIGxvb2tpbmcgZm9yIGNvbnZlcnNpb24gIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAic3BlY2lmaWVyIik7CisgICAgICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgICAgICB9CisgICAgICAgICAgICAqY29udmVyc2lvbiA9ICooZm9ybWF0X3NwZWMtPnB0cisrKTsKKworICAgICAgICAgICAgLyogaWYgdGhlcmUgaXMgYW5vdGhlciBjaGFyYWN0ZXIsIGl0IG11c3QgYmUgYSBjb2xvbiAqLworICAgICAgICAgICAgaWYgKGZvcm1hdF9zcGVjLT5wdHIgPCBmb3JtYXRfc3BlYy0+ZW5kKSB7CisgICAgICAgICAgICAgICAgYyA9ICooZm9ybWF0X3NwZWMtPnB0cisrKTsKKyAgICAgICAgICAgICAgICBpZiAoYyAhPSAnOicpIHsKKyAgICAgICAgICAgICAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1ZhbHVlRXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZXhwZWN0ZWQgJzonIGFmdGVyIGZvcm1hdCBzcGVjaWZpZXIiKTsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorICAgIGVsc2UKKyAgICAgICAgLyogZW5kIG9mIHN0cmluZywgdGhlcmUncyBubyBmb3JtYXRfc3BlYyBvciBjb252ZXJzaW9uICovCisgICAgICAgIGZpZWxkX25hbWUtPmVuZCA9IHN0ci0+cHRyOworCisgICAgcmV0dXJuIDE7Cit9CisKKy8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCisvKioqKioqKiBPdXRwdXQgc3RyaW5nIGFsbG9jYXRpb24gYW5kIGVzY2FwZS10by1tYXJrdXAgcHJvY2Vzc2luZyAgKioqKioqLworLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KKworLyogTWFya3VwSXRlcmF0b3IgYnJlYWtzIHRoZSBzdHJpbmcgaW50byBwaWVjZXMgb2YgZWl0aGVyIGxpdGVyYWwKKyAgIHRleHQsIG9yIHRoaW5ncyBpbnNpZGUge30gdGhhdCBuZWVkIHRvIGJlIG1hcmtlZCB1cC4gIGl0IGlzCisgICBkZXNpZ25lZCB0byBtYWtlIGl0IGVhc3kgdG8gd3JhcCBhIFB5dGhvbiBpdGVyYXRvciBhcm91bmQgaXQsIGZvcgorICAgdXNlIHdpdGggdGhlIEZvcm1hdHRlciBjbGFzcyAqLworCit0eXBlZGVmIHN0cnVjdCB7CisgICAgU3ViU3RyaW5nIHN0cjsKK30gTWFya3VwSXRlcmF0b3I7CisKK3N0YXRpYyBpbnQKK01hcmt1cEl0ZXJhdG9yX2luaXQoTWFya3VwSXRlcmF0b3IgKnNlbGYsIFNUUklOR0xJQl9DSEFSICpwdHIsIFB5X3NzaXplX3QgbGVuKQoreworICAgIFN1YlN0cmluZ19pbml0KCZzZWxmLT5zdHIsIHB0ciwgbGVuKTsKKyAgICByZXR1cm4gMTsKK30KKworLyogcmV0dXJucyAwIG9uIGVycm9yLCAxIG9uIG5vbi1lcnJvciB0ZXJtaW5hdGlvbiwgYW5kIDIgaWYgaXQgZ290IGEKKyAgIHN0cmluZyAob3Igc29tZXRoaW5nIHRvIGJlIGV4cGFuZGVkKSAqLworc3RhdGljIGludAorTWFya3VwSXRlcmF0b3JfbmV4dChNYXJrdXBJdGVyYXRvciAqc2VsZiwgU3ViU3RyaW5nICpsaXRlcmFsLAorICAgICAgICAgICAgICAgICAgICBpbnQgKmZpZWxkX3ByZXNlbnQsIFN1YlN0cmluZyAqZmllbGRfbmFtZSwKKyAgICAgICAgICAgICAgICAgICAgU3ViU3RyaW5nICpmb3JtYXRfc3BlYywgU1RSSU5HTElCX0NIQVIgKmNvbnZlcnNpb24sCisgICAgICAgICAgICAgICAgICAgIGludCAqZm9ybWF0X3NwZWNfbmVlZHNfZXhwYW5kaW5nKQoreworICAgIGludCBhdF9lbmQ7CisgICAgU1RSSU5HTElCX0NIQVIgYyA9IDA7CisgICAgU1RSSU5HTElCX0NIQVIgKnN0YXJ0OworICAgIGludCBjb3VudDsKKyAgICBQeV9zc2l6ZV90IGxlbjsKKyAgICBpbnQgbWFya3VwX2ZvbGxvd3MgPSAwOworCisgICAgLyogaW5pdGlhbGl6ZSBhbGwgb2YgdGhlIG91dHB1dCB2YXJpYWJsZXMgKi8KKyAgICBTdWJTdHJpbmdfaW5pdChsaXRlcmFsLCBOVUxMLCAwKTsKKyAgICBTdWJTdHJpbmdfaW5pdChmaWVsZF9uYW1lLCBOVUxMLCAwKTsKKyAgICBTdWJTdHJpbmdfaW5pdChmb3JtYXRfc3BlYywgTlVMTCwgMCk7CisgICAgKmNvbnZlcnNpb24gPSAnXDAnOworICAgICpmb3JtYXRfc3BlY19uZWVkc19leHBhbmRpbmcgPSAwOworICAgICpmaWVsZF9wcmVzZW50ID0gMDsKKworICAgIC8qIE5vIG1vcmUgaW5wdXQsIGVuZCBvZiBpdGVyYXRvci4gIFRoaXMgaXMgdGhlIG5vcm1hbCBleGl0CisgICAgICAgcGF0aC4gKi8KKyAgICBpZiAoc2VsZi0+c3RyLnB0ciA+PSBzZWxmLT5zdHIuZW5kKQorICAgICAgICByZXR1cm4gMTsKKworICAgIHN0YXJ0ID0gc2VsZi0+c3RyLnB0cjsKKworICAgIC8qIEZpcnN0IHJlYWQgYW55IGxpdGVyYWwgdGV4dC4gUmVhZCB1bnRpbCB0aGUgZW5kIG9mIHN0cmluZywgYW4KKyAgICAgICBlc2NhcGVkICd7JyBvciAnfScsIG9yIGFuIHVuZXNjYXBlZCAneycuICBJbiBvcmRlciB0byBuZXZlcgorICAgICAgIGFsbG9jYXRlIG1lbW9yeSBhbmQgc28gSSBjYW4ganVzdCBwYXNzIHBvaW50ZXJzIGFyb3VuZCwgaWYKKyAgICAgICB0aGVyZSdzIGFuIGVzY2FwZWQgJ3snIG9yICd9JyB0aGVuIHdlJ2xsIHJldHVybiB0aGUgbGl0ZXJhbAorICAgICAgIGluY2x1ZGluZyB0aGUgYnJhY2UsIGJ1dCBubyBmb3JtYXQgb2JqZWN0LiAgVGhlIG5leHQgdGltZQorICAgICAgIHRocm91Z2gsIHdlJ2xsIHJldHVybiB0aGUgcmVzdCBvZiB0aGUgbGl0ZXJhbCwgc2tpcHBpbmcgcGFzdAorICAgICAgIHRoZSBzZWNvbmQgY29uc2VjdXRpdmUgYnJhY2UuICovCisgICAgd2hpbGUgKHNlbGYtPnN0ci5wdHIgPCBzZWxmLT5zdHIuZW5kKSB7CisgICAgICAgIHN3aXRjaCAoYyA9ICooc2VsZi0+c3RyLnB0cisrKSkgeworICAgICAgICBjYXNlICd7JzoKKyAgICAgICAgY2FzZSAnfSc6CisgICAgICAgICAgICBtYXJrdXBfZm9sbG93cyA9IDE7CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICB9CisgICAgICAgIGJyZWFrOworICAgIH0KKworICAgIGF0X2VuZCA9IHNlbGYtPnN0ci5wdHIgPj0gc2VsZi0+c3RyLmVuZDsKKyAgICBsZW4gPSBzZWxmLT5zdHIucHRyIC0gc3RhcnQ7CisKKyAgICBpZiAoKGMgPT0gJ30nKSAmJiAoYXRfZW5kIHx8IChjICE9ICpzZWxmLT5zdHIucHRyKSkpIHsKKyAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1ZhbHVlRXJyb3IsICJTaW5nbGUgJ30nIGVuY291bnRlcmVkICIKKyAgICAgICAgICAgICAgICAgICAgICAgICJpbiBmb3JtYXQgc3RyaW5nIik7CisgICAgICAgIHJldHVybiAwOworICAgIH0KKyAgICBpZiAoYXRfZW5kICYmIGMgPT0gJ3snKSB7CisgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19WYWx1ZUVycm9yLCAiU2luZ2xlICd7JyBlbmNvdW50ZXJlZCAiCisgICAgICAgICAgICAgICAgICAgICAgICAiaW4gZm9ybWF0IHN0cmluZyIpOworICAgICAgICByZXR1cm4gMDsKKyAgICB9CisgICAgaWYgKCFhdF9lbmQpIHsKKyAgICAgICAgaWYgKGMgPT0gKnNlbGYtPnN0ci5wdHIpIHsKKyAgICAgICAgICAgIC8qIGVzY2FwZWQgfSBvciB7LCBza2lwIGl0IGluIHRoZSBpbnB1dC4gIHRoZXJlIGlzIG5vCisgICAgICAgICAgICAgICBtYXJrdXAgb2JqZWN0IGZvbGxvd2luZyB1cywganVzdCB0aGlzIGxpdGVyYWwgdGV4dCAqLworICAgICAgICAgICAgc2VsZi0+c3RyLnB0cisrOworICAgICAgICAgICAgbWFya3VwX2ZvbGxvd3MgPSAwOworICAgICAgICB9CisgICAgICAgIGVsc2UKKyAgICAgICAgICAgIGxlbi0tOworICAgIH0KKworICAgIC8qIHJlY29yZCB0aGUgbGl0ZXJhbCB0ZXh0ICovCisgICAgbGl0ZXJhbC0+cHRyID0gc3RhcnQ7CisgICAgbGl0ZXJhbC0+ZW5kID0gc3RhcnQgKyBsZW47CisKKyAgICBpZiAoIW1hcmt1cF9mb2xsb3dzKQorICAgICAgICByZXR1cm4gMjsKKworICAgIC8qIHRoaXMgaXMgbWFya3VwLCBmaW5kIHRoZSBlbmQgb2YgdGhlIHN0cmluZyBieSBjb3VudGluZyBuZXN0ZWQKKyAgICAgICBicmFjZXMuICBub3RlIHRoYXQgdGhpcyBwcm9oaWJpdHMgZXNjYXBlZCBicmFjZXMsIHNvIHRoYXQKKyAgICAgICBmb3JtYXRfc3BlY3MgY2Fubm90IGhhdmUgYnJhY2VzIGluIHRoZW0uICovCisgICAgKmZpZWxkX3ByZXNlbnQgPSAxOworICAgIGNvdW50ID0gMTsKKworICAgIHN0YXJ0ID0gc2VsZi0+c3RyLnB0cjsKKworICAgIC8qIHdlIGtub3cgd2UgY2FuJ3QgaGF2ZSBhIHplcm8gbGVuZ3RoIHN0cmluZywgc28gZG9uJ3Qgd29ycnkKKyAgICAgICBhYm91dCB0aGF0IGNhc2UgKi8KKyAgICB3aGlsZSAoc2VsZi0+c3RyLnB0ciA8IHNlbGYtPnN0ci5lbmQpIHsKKyAgICAgICAgc3dpdGNoIChjID0gKihzZWxmLT5zdHIucHRyKyspKSB7CisgICAgICAgIGNhc2UgJ3snOgorICAgICAgICAgICAgLyogdGhlIGZvcm1hdCBzcGVjIG5lZWRzIHRvIGJlIHJlY3Vyc2l2ZWx5IGV4cGFuZGVkLgorICAgICAgICAgICAgICAgdGhpcyBpcyBhbiBvcHRpbWl6YXRpb24sIGFuZCBub3Qgc3RyaWN0bHkgbmVlZGVkICovCisgICAgICAgICAgICAqZm9ybWF0X3NwZWNfbmVlZHNfZXhwYW5kaW5nID0gMTsKKyAgICAgICAgICAgIGNvdW50Kys7CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgY2FzZSAnfSc6CisgICAgICAgICAgICBjb3VudC0tOworICAgICAgICAgICAgaWYgKGNvdW50IDw9IDApIHsKKyAgICAgICAgICAgICAgICAvKiB3ZSdyZSBkb25lLiAgcGFyc2UgYW5kIGdldCBvdXQgKi8KKyAgICAgICAgICAgICAgICBTdWJTdHJpbmcgczsKKworICAgICAgICAgICAgICAgIFN1YlN0cmluZ19pbml0KCZzLCBzdGFydCwgc2VsZi0+c3RyLnB0ciAtIDEgLSBzdGFydCk7CisgICAgICAgICAgICAgICAgaWYgKHBhcnNlX2ZpZWxkKCZzLCBmaWVsZF9uYW1lLCBmb3JtYXRfc3BlYywgY29udmVyc2lvbikgPT0gMCkKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIDA7CisKKyAgICAgICAgICAgICAgICAvKiBzdWNjZXNzICovCisgICAgICAgICAgICAgICAgcmV0dXJuIDI7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qIGVuZCBvZiBzdHJpbmcgd2hpbGUgc2VhcmNoaW5nIGZvciBtYXRjaGluZyAnfScgKi8KKyAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfVmFsdWVFcnJvciwgInVubWF0Y2hlZCAneycgaW4gZm9ybWF0Iik7CisgICAgcmV0dXJuIDA7Cit9CisKKworLyogZG8gdGhlICFyIG9yICFzIGNvbnZlcnNpb24gb24gb2JqICovCitzdGF0aWMgUHlPYmplY3QgKgorZG9fY29udmVyc2lvbihQeU9iamVjdCAqb2JqLCBTVFJJTkdMSUJfQ0hBUiBjb252ZXJzaW9uKQoreworICAgIC8qIFhYWCBpbiBwcmUtMy4wLCBkbyB3ZSBuZWVkIHRvIGNvbnZlcnQgdGhpcyB0byB1bmljb2RlLCBzaW5jZSBpdAorICAgICAgIG1pZ2h0IGhhdmUgcmV0dXJuZWQgYSBzdHJpbmc/ICovCisgICAgc3dpdGNoIChjb252ZXJzaW9uKSB7CisgICAgY2FzZSAncic6CisgICAgICAgIHJldHVybiBQeU9iamVjdF9SZXByKG9iaik7CisgICAgY2FzZSAncyc6CisgICAgICAgIHJldHVybiBTVFJJTkdMSUJfVE9TVFIob2JqKTsKKyAgICBkZWZhdWx0OgorICAgICAgICBpZiAoY29udmVyc2lvbiA+IDMyICYmIGNvbnZlcnNpb24gPCAxMjcpIHsKKyAgICAgICAgICAgICAgICAvKiBJdCdzIHRoZSBBU0NJSSBzdWJyYW5nZTsgY2FzdGluZyB0byBjaGFyIGlzIHNhZmUKKyAgICAgICAgICAgICAgICAgICAoYXNzdW1pbmcgdGhlIGV4ZWN1dGlvbiBjaGFyYWN0ZXIgc2V0IGlzIGFuIEFTQ0lJCisgICAgICAgICAgICAgICAgICAgc3VwZXJzZXQpLiAqLworICAgICAgICAgICAgICAgIFB5RXJyX0Zvcm1hdChQeUV4Y19WYWx1ZUVycm9yLAorICAgICAgICAgICAgICAgICAgICAgIlVua25vd24gY29udmVyc2lvbiBzcGVjaWZpZXIgJWMiLAorICAgICAgICAgICAgICAgICAgICAgKGNoYXIpY29udmVyc2lvbik7CisgICAgICAgIH0gZWxzZQorICAgICAgICAgICAgICAgIFB5RXJyX0Zvcm1hdChQeUV4Y19WYWx1ZUVycm9yLAorICAgICAgICAgICAgICAgICAgICAgIlVua25vd24gY29udmVyc2lvbiBzcGVjaWZpZXIgXFx4JXgiLAorICAgICAgICAgICAgICAgICAgICAgKHVuc2lnbmVkIGludCljb252ZXJzaW9uKTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorfQorCisvKiBnaXZlbjoKKworICAge2ZpZWxkX25hbWUhY29udmVyc2lvbjpmb3JtYXRfc3BlY30KKworICAgY29tcHV0ZSB0aGUgcmVzdWx0IGFuZCB3cml0ZSBpdCB0byBvdXRwdXQuCisgICBmb3JtYXRfc3BlY19uZWVkc19leHBhbmRpbmcgaXMgYW4gb3B0aW1pemF0aW9uLiAgaWYgaXQncyBmYWxzZSwKKyAgIGp1c3Qgb3V0cHV0IHRoZSBzdHJpbmcgZGlyZWN0bHksIG90aGVyd2lzZSByZWN1cnNpdmVseSBleHBhbmQgdGhlCisgICBmb3JtYXRfc3BlYyBzdHJpbmcuCisKKyAgIGZpZWxkX25hbWUgaXMgYWxsb3dlZCB0byBiZSB6ZXJvIGxlbmd0aCwgaW4gd2hpY2ggY2FzZSB3ZQorICAgYXJlIGRvaW5nIGF1dG8gZmllbGQgbnVtYmVyaW5nLgorKi8KKworc3RhdGljIGludAorb3V0cHV0X21hcmt1cChTdWJTdHJpbmcgKmZpZWxkX25hbWUsIFN1YlN0cmluZyAqZm9ybWF0X3NwZWMsCisgICAgICAgICAgICAgIGludCBmb3JtYXRfc3BlY19uZWVkc19leHBhbmRpbmcsIFNUUklOR0xJQl9DSEFSIGNvbnZlcnNpb24sCisgICAgICAgICAgICAgIE91dHB1dFN0cmluZyAqb3V0cHV0LCBQeU9iamVjdCAqYXJncywgUHlPYmplY3QgKmt3YXJncywKKyAgICAgICAgICAgICAgaW50IHJlY3Vyc2lvbl9kZXB0aCwgQXV0b051bWJlciAqYXV0b19udW1iZXIpCit7CisgICAgUHlPYmplY3QgKnRtcCA9IE5VTEw7CisgICAgUHlPYmplY3QgKmZpZWxkb2JqID0gTlVMTDsKKyAgICBTdWJTdHJpbmcgZXhwYW5kZWRfZm9ybWF0X3NwZWM7CisgICAgU3ViU3RyaW5nICphY3R1YWxfZm9ybWF0X3NwZWM7CisgICAgaW50IHJlc3VsdCA9IDA7CisKKyAgICAvKiBjb252ZXJ0IGZpZWxkX25hbWUgdG8gYW4gb2JqZWN0ICovCisgICAgZmllbGRvYmogPSBnZXRfZmllbGRfb2JqZWN0KGZpZWxkX25hbWUsIGFyZ3MsIGt3YXJncywgYXV0b19udW1iZXIpOworICAgIGlmIChmaWVsZG9iaiA9PSBOVUxMKQorICAgICAgICBnb3RvIGRvbmU7CisKKyAgICBpZiAoY29udmVyc2lvbiAhPSAnXDAnKSB7CisgICAgICAgIHRtcCA9IGRvX2NvbnZlcnNpb24oZmllbGRvYmosIGNvbnZlcnNpb24pOworICAgICAgICBpZiAodG1wID09IE5VTEwpCisgICAgICAgICAgICBnb3RvIGRvbmU7CisKKyAgICAgICAgLyogZG8gdGhlIGFzc2lnbm1lbnQsIHRyYW5zZmVycmluZyBvd25lcnNoaXA6IGZpZWxkb2JqID0gdG1wICovCisgICAgICAgIFB5X0RFQ1JFRihmaWVsZG9iaik7CisgICAgICAgIGZpZWxkb2JqID0gdG1wOworICAgICAgICB0bXAgPSBOVUxMOworICAgIH0KKworICAgIC8qIGlmIG5lZWRlZCwgcmVjdXJpdmVseSBjb21wdXRlIHRoZSBmb3JtYXRfc3BlYyAqLworICAgIGlmIChmb3JtYXRfc3BlY19uZWVkc19leHBhbmRpbmcpIHsKKyAgICAgICAgdG1wID0gYnVpbGRfc3RyaW5nKGZvcm1hdF9zcGVjLCBhcmdzLCBrd2FyZ3MsIHJlY3Vyc2lvbl9kZXB0aC0xLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgYXV0b19udW1iZXIpOworICAgICAgICBpZiAodG1wID09IE5VTEwpCisgICAgICAgICAgICBnb3RvIGRvbmU7CisKKyAgICAgICAgLyogbm90ZSB0aGF0IGluIHRoZSBjYXNlIHdlJ3JlIGV4cGFuZGluZyB0aGUgZm9ybWF0IHN0cmluZywKKyAgICAgICAgICAgdG1wIG11c3QgYmUga2VwdCBhcm91bmQgdW50aWwgYWZ0ZXIgdGhlIGNhbGwgdG8KKyAgICAgICAgICAgcmVuZGVyX2ZpZWxkLiAqLworICAgICAgICBTdWJTdHJpbmdfaW5pdCgmZXhwYW5kZWRfZm9ybWF0X3NwZWMsCisgICAgICAgICAgICAgICAgICAgICAgIFNUUklOR0xJQl9TVFIodG1wKSwgU1RSSU5HTElCX0xFTih0bXApKTsKKyAgICAgICAgYWN0dWFsX2Zvcm1hdF9zcGVjID0gJmV4cGFuZGVkX2Zvcm1hdF9zcGVjOworICAgIH0KKyAgICBlbHNlCisgICAgICAgIGFjdHVhbF9mb3JtYXRfc3BlYyA9IGZvcm1hdF9zcGVjOworCisgICAgaWYgKHJlbmRlcl9maWVsZChmaWVsZG9iaiwgYWN0dWFsX2Zvcm1hdF9zcGVjLCBvdXRwdXQpID09IDApCisgICAgICAgIGdvdG8gZG9uZTsKKworICAgIHJlc3VsdCA9IDE7CisKK2RvbmU6CisgICAgUHlfWERFQ1JFRihmaWVsZG9iaik7CisgICAgUHlfWERFQ1JFRih0bXApOworCisgICAgcmV0dXJuIHJlc3VsdDsKK30KKworLyoKKyAgICBkb19tYXJrdXAgaXMgdGhlIHRvcC1sZXZlbCBsb29wIGZvciB0aGUgZm9ybWF0KCkgbWV0aG9kLiAgSXQKKyAgICBzZWFyY2hlcyB0aHJvdWdoIHRoZSBmb3JtYXQgc3RyaW5nIGZvciBlc2NhcGVzIHRvIG1hcmt1cCBjb2RlcywgYW5kCisgICAgY2FsbHMgb3RoZXIgZnVuY3Rpb25zIHRvIG1vdmUgbm9uLW1hcmt1cCB0ZXh0IHRvIHRoZSBvdXRwdXQsCisgICAgYW5kIHRvIHBlcmZvcm0gdGhlIG1hcmt1cCB0byB0aGUgb3V0cHV0LgorKi8KK3N0YXRpYyBpbnQKK2RvX21hcmt1cChTdWJTdHJpbmcgKmlucHV0LCBQeU9iamVjdCAqYXJncywgUHlPYmplY3QgKmt3YXJncywKKyAgICAgICAgICBPdXRwdXRTdHJpbmcgKm91dHB1dCwgaW50IHJlY3Vyc2lvbl9kZXB0aCwgQXV0b051bWJlciAqYXV0b19udW1iZXIpCit7CisgICAgTWFya3VwSXRlcmF0b3IgaXRlcjsKKyAgICBpbnQgZm9ybWF0X3NwZWNfbmVlZHNfZXhwYW5kaW5nOworICAgIGludCByZXN1bHQ7CisgICAgaW50IGZpZWxkX3ByZXNlbnQ7CisgICAgU3ViU3RyaW5nIGxpdGVyYWw7CisgICAgU3ViU3RyaW5nIGZpZWxkX25hbWU7CisgICAgU3ViU3RyaW5nIGZvcm1hdF9zcGVjOworICAgIFNUUklOR0xJQl9DSEFSIGNvbnZlcnNpb247CisKKyAgICBNYXJrdXBJdGVyYXRvcl9pbml0KCZpdGVyLCBpbnB1dC0+cHRyLCBpbnB1dC0+ZW5kIC0gaW5wdXQtPnB0cik7CisgICAgd2hpbGUgKChyZXN1bHQgPSBNYXJrdXBJdGVyYXRvcl9uZXh0KCZpdGVyLCAmbGl0ZXJhbCwgJmZpZWxkX3ByZXNlbnQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZmaWVsZF9uYW1lLCAmZm9ybWF0X3NwZWMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZjb252ZXJzaW9uLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmZm9ybWF0X3NwZWNfbmVlZHNfZXhwYW5kaW5nKSkgPT0gMikgeworICAgICAgICBpZiAoIW91dHB1dF9kYXRhKG91dHB1dCwgbGl0ZXJhbC5wdHIsIGxpdGVyYWwuZW5kIC0gbGl0ZXJhbC5wdHIpKQorICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgIGlmIChmaWVsZF9wcmVzZW50KQorICAgICAgICAgICAgaWYgKCFvdXRwdXRfbWFya3VwKCZmaWVsZF9uYW1lLCAmZm9ybWF0X3NwZWMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZm9ybWF0X3NwZWNfbmVlZHNfZXhwYW5kaW5nLCBjb252ZXJzaW9uLCBvdXRwdXQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJncywga3dhcmdzLCByZWN1cnNpb25fZGVwdGgsIGF1dG9fbnVtYmVyKSkKKyAgICAgICAgICAgICAgICByZXR1cm4gMDsKKyAgICB9CisgICAgcmV0dXJuIHJlc3VsdDsKK30KKworCisvKgorICAgIGJ1aWxkX3N0cmluZyBhbGxvY2F0ZXMgdGhlIG91dHB1dCBzdHJpbmcgYW5kIHRoZW4KKyAgICBjYWxscyBkb19tYXJrdXAgdG8gZG8gdGhlIGhlYXZ5IGxpZnRpbmcuCisqLworc3RhdGljIFB5T2JqZWN0ICoKK2J1aWxkX3N0cmluZyhTdWJTdHJpbmcgKmlucHV0LCBQeU9iamVjdCAqYXJncywgUHlPYmplY3QgKmt3YXJncywKKyAgICAgICAgICAgICBpbnQgcmVjdXJzaW9uX2RlcHRoLCBBdXRvTnVtYmVyICphdXRvX251bWJlcikKK3sKKyAgICBPdXRwdXRTdHJpbmcgb3V0cHV0OworICAgIFB5T2JqZWN0ICpyZXN1bHQgPSBOVUxMOworICAgIFB5X3NzaXplX3QgY291bnQ7CisKKyAgICBvdXRwdXQub2JqID0gTlVMTDsgLyogbmVlZGVkIHNvIGNsZWFudXAgY29kZSBhbHdheXMgd29ya3MgKi8KKworICAgIC8qIGNoZWNrIHRoZSByZWN1cnNpb24gbGV2ZWwgKi8KKyAgICBpZiAocmVjdXJzaW9uX2RlcHRoIDw9IDApIHsKKyAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1ZhbHVlRXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAgICAiTWF4IHN0cmluZyByZWN1cnNpb24gZXhjZWVkZWQiKTsKKyAgICAgICAgZ290byBkb25lOworICAgIH0KKworICAgIC8qIGluaXRpYWwgc2l6ZSBpcyB0aGUgbGVuZ3RoIG9mIHRoZSBmb3JtYXQgc3RyaW5nLCBwbHVzIHRoZSBzaXplCisgICAgICAgaW5jcmVtZW50LiAgc2VlbXMgbGlrZSBhIHJlYXNvbmFibGUgZGVmYXVsdCAqLworICAgIGlmICghb3V0cHV0X2luaXRpYWxpemUoJm91dHB1dCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIGlucHV0LT5lbmQgLSBpbnB1dC0+cHRyICsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIElOSVRJQUxfU0laRV9JTkNSRU1FTlQpKQorICAgICAgICBnb3RvIGRvbmU7CisKKyAgICBpZiAoIWRvX21hcmt1cChpbnB1dCwgYXJncywga3dhcmdzLCAmb3V0cHV0LCByZWN1cnNpb25fZGVwdGgsCisgICAgICAgICAgICAgICAgICAgYXV0b19udW1iZXIpKSB7CisgICAgICAgIGdvdG8gZG9uZTsKKyAgICB9CisKKyAgICBjb3VudCA9IG91dHB1dC5wdHIgLSBTVFJJTkdMSUJfU1RSKG91dHB1dC5vYmopOworICAgIGlmIChTVFJJTkdMSUJfUkVTSVpFKCZvdXRwdXQub2JqLCBjb3VudCkgPCAwKSB7CisgICAgICAgIGdvdG8gZG9uZTsKKyAgICB9CisKKyAgICAvKiB0cmFuc2ZlciBvd25lcnNoaXAgdG8gcmVzdWx0ICovCisgICAgcmVzdWx0ID0gb3V0cHV0Lm9iajsKKyAgICBvdXRwdXQub2JqID0gTlVMTDsKKworZG9uZToKKyAgICBQeV9YREVDUkVGKG91dHB1dC5vYmopOworICAgIHJldHVybiByZXN1bHQ7Cit9CisKKy8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCisvKioqKioqKioqKiogbWFpbiByb3V0aW5lICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLworLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KKworLyogdGhpcyBpcyB0aGUgbWFpbiBlbnRyeSBwb2ludCAqLworc3RhdGljIFB5T2JqZWN0ICoKK2RvX3N0cmluZ19mb3JtYXQoUHlPYmplY3QgKnNlbGYsIFB5T2JqZWN0ICphcmdzLCBQeU9iamVjdCAqa3dhcmdzKQoreworICAgIFN1YlN0cmluZyBpbnB1dDsKKworICAgIC8qIFBFUCAzMTAxIHNheXMgb25seSAyIGxldmVscywgc28gdGhhdAorICAgICAgICJ7MDp7MX19Ii5mb3JtYXQoJ2FiYycsICdzJykgICAgICAgICAgICAjIHdvcmtzCisgICAgICAgInswOnsxOnsyfX19Ii5mb3JtYXQoJ2FiYycsICdzJywgJycpICAgICMgZmFpbHMKKyAgICAqLworICAgIGludCByZWN1cnNpb25fZGVwdGggPSAyOworCisgICAgQXV0b051bWJlciBhdXRvX251bWJlcjsKKworICAgIEF1dG9OdW1iZXJfSW5pdCgmYXV0b19udW1iZXIpOworICAgIFN1YlN0cmluZ19pbml0KCZpbnB1dCwgU1RSSU5HTElCX1NUUihzZWxmKSwgU1RSSU5HTElCX0xFTihzZWxmKSk7CisgICAgcmV0dXJuIGJ1aWxkX3N0cmluZygmaW5wdXQsIGFyZ3MsIGt3YXJncywgcmVjdXJzaW9uX2RlcHRoLCAmYXV0b19udW1iZXIpOworfQorCisKKworLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KKy8qKioqKioqKioqKiBmb3JtYXR0ZXJpdGVyYXRvciAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCisvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLworCisvKiBUaGlzIGlzIHVzZWQgdG8gaW1wbGVtZW50IHN0cmluZy5Gb3JtYXR0ZXIudnBhcnNlKCkuICBJdCBleGlzdHMgc28KKyAgIEZvcm1hdHRlciBjYW4gc2hhcmUgY29kZSB3aXRoIHRoZSBidWlsdCBpbiB1bmljb2RlLmZvcm1hdCgpIG1ldGhvZC4KKyAgIEl0J3MgcmVhbGx5IGp1c3QgYSB3cmFwcGVyIGFyb3VuZCBNYXJrdXBJdGVyYXRvciB0aGF0IGlzIGNhbGxhYmxlCisgICBmcm9tIFB5dGhvbi4gKi8KKwordHlwZWRlZiBzdHJ1Y3QgeworICAgIFB5T2JqZWN0X0hFQUQKKworICAgIFNUUklOR0xJQl9PQkpFQ1QgKnN0cjsKKworICAgIE1hcmt1cEl0ZXJhdG9yIGl0X21hcmt1cDsKK30gZm9ybWF0dGVyaXRlcm9iamVjdDsKKworc3RhdGljIHZvaWQKK2Zvcm1hdHRlcml0ZXJfZGVhbGxvYyhmb3JtYXR0ZXJpdGVyb2JqZWN0ICppdCkKK3sKKyAgICBQeV9YREVDUkVGKGl0LT5zdHIpOworICAgIFB5T2JqZWN0X0ZSRUUoaXQpOworfQorCisvKiByZXR1cm5zIGEgdHVwbGU6CisgICAobGl0ZXJhbCwgZmllbGRfbmFtZSwgZm9ybWF0X3NwZWMsIGNvbnZlcnNpb24pCisKKyAgIGxpdGVyYWwgaXMgYW55IGxpdGVyYWwgdGV4dCB0byBvdXRwdXQuICBtaWdodCBiZSB6ZXJvIGxlbmd0aAorICAgZmllbGRfbmFtZSBpcyB0aGUgc3RyaW5nIGJlZm9yZSB0aGUgJzonLiAgbWlnaHQgYmUgTm9uZQorICAgZm9ybWF0X3NwZWMgaXMgdGhlIHN0cmluZyBhZnRlciB0aGUgJzonLiAgbWliaHQgYmUgTm9uZQorICAgY29udmVyc2lvbiBpcyBlaXRoZXIgTm9uZSwgb3IgdGhlIHN0cmluZyBhZnRlciB0aGUgJyEnCisqLworc3RhdGljIFB5T2JqZWN0ICoKK2Zvcm1hdHRlcml0ZXJfbmV4dChmb3JtYXR0ZXJpdGVyb2JqZWN0ICppdCkKK3sKKyAgICBTdWJTdHJpbmcgbGl0ZXJhbDsKKyAgICBTdWJTdHJpbmcgZmllbGRfbmFtZTsKKyAgICBTdWJTdHJpbmcgZm9ybWF0X3NwZWM7CisgICAgU1RSSU5HTElCX0NIQVIgY29udmVyc2lvbjsKKyAgICBpbnQgZm9ybWF0X3NwZWNfbmVlZHNfZXhwYW5kaW5nOworICAgIGludCBmaWVsZF9wcmVzZW50OworICAgIGludCByZXN1bHQgPSBNYXJrdXBJdGVyYXRvcl9uZXh0KCZpdC0+aXRfbWFya3VwLCAmbGl0ZXJhbCwgJmZpZWxkX3ByZXNlbnQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJmZpZWxkX25hbWUsICZmb3JtYXRfc3BlYywgJmNvbnZlcnNpb24sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJmZvcm1hdF9zcGVjX25lZWRzX2V4cGFuZGluZyk7CisKKyAgICAvKiBhbGwgb2YgdGhlIFN1YlN0cmluZyBvYmplY3RzIHBvaW50IGludG8gaXQtPnN0ciwgc28gbm8KKyAgICAgICBtZW1vcnkgbWFuYWdlbWVudCBuZWVkcyB0byBiZSBkb25lIG9uIHRoZW0gKi8KKyAgICBhc3NlcnQoMCA8PSByZXN1bHQgJiYgcmVzdWx0IDw9IDIpOworICAgIGlmIChyZXN1bHQgPT0gMCB8fCByZXN1bHQgPT0gMSkKKyAgICAgICAgLyogaWYgMCwgZXJyb3IgaGFzIGFscmVhZHkgYmVlbiBzZXQsIGlmIDEsIGl0ZXJhdG9yIGlzIGVtcHR5ICovCisgICAgICAgIHJldHVybiBOVUxMOworICAgIGVsc2UgeworICAgICAgICBQeU9iamVjdCAqbGl0ZXJhbF9zdHIgPSBOVUxMOworICAgICAgICBQeU9iamVjdCAqZmllbGRfbmFtZV9zdHIgPSBOVUxMOworICAgICAgICBQeU9iamVjdCAqZm9ybWF0X3NwZWNfc3RyID0gTlVMTDsKKyAgICAgICAgUHlPYmplY3QgKmNvbnZlcnNpb25fc3RyID0gTlVMTDsKKyAgICAgICAgUHlPYmplY3QgKnR1cGxlID0gTlVMTDsKKworICAgICAgICBsaXRlcmFsX3N0ciA9IFN1YlN0cmluZ19uZXdfb2JqZWN0KCZsaXRlcmFsKTsKKyAgICAgICAgaWYgKGxpdGVyYWxfc3RyID09IE5VTEwpCisgICAgICAgICAgICBnb3RvIGRvbmU7CisKKyAgICAgICAgZmllbGRfbmFtZV9zdHIgPSBTdWJTdHJpbmdfbmV3X29iamVjdCgmZmllbGRfbmFtZSk7CisgICAgICAgIGlmIChmaWVsZF9uYW1lX3N0ciA9PSBOVUxMKQorICAgICAgICAgICAgZ290byBkb25lOworCisgICAgICAgIC8qIGlmIGZpZWxkX25hbWUgaXMgbm9uLXplcm8gbGVuZ3RoLCByZXR1cm4gYSBzdHJpbmcgZm9yCisgICAgICAgICAgIGZvcm1hdF9zcGVjIChldmVuIGlmIHplcm8gbGVuZ3RoKSwgZWxzZSByZXR1cm4gTm9uZSAqLworICAgICAgICBmb3JtYXRfc3BlY19zdHIgPSAoZmllbGRfcHJlc2VudCA/CisgICAgICAgICAgICAgICAgICAgICAgICAgICBTdWJTdHJpbmdfbmV3X29iamVjdF9vcl9lbXB0eSA6CisgICAgICAgICAgICAgICAgICAgICAgICAgICBTdWJTdHJpbmdfbmV3X29iamVjdCkoJmZvcm1hdF9zcGVjKTsKKyAgICAgICAgaWYgKGZvcm1hdF9zcGVjX3N0ciA9PSBOVUxMKQorICAgICAgICAgICAgZ290byBkb25lOworCisgICAgICAgIC8qIGlmIHRoZSBjb252ZXJzaW9uIGlzIG5vdCBzcGVjaWZpZWQsIHJldHVybiBhIE5vbmUsCisgICAgICAgICAgIG90aGVyd2lzZSBjcmVhdGUgYSBvbmUgbGVuZ3RoIHN0cmluZyB3aXRoIHRoZSBjb252ZXJzaW9uCisgICAgICAgICAgIGNoYXJhY3RlciAqLworICAgICAgICBpZiAoY29udmVyc2lvbiA9PSAnXDAnKSB7CisgICAgICAgICAgICBjb252ZXJzaW9uX3N0ciA9IFB5X05vbmU7CisgICAgICAgICAgICBQeV9JTkNSRUYoY29udmVyc2lvbl9zdHIpOworICAgICAgICB9CisgICAgICAgIGVsc2UKKyAgICAgICAgICAgIGNvbnZlcnNpb25fc3RyID0gU1RSSU5HTElCX05FVygmY29udmVyc2lvbiwgMSk7CisgICAgICAgIGlmIChjb252ZXJzaW9uX3N0ciA9PSBOVUxMKQorICAgICAgICAgICAgZ290byBkb25lOworCisgICAgICAgIHR1cGxlID0gUHlUdXBsZV9QYWNrKDQsIGxpdGVyYWxfc3RyLCBmaWVsZF9uYW1lX3N0ciwgZm9ybWF0X3NwZWNfc3RyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb252ZXJzaW9uX3N0cik7CisgICAgZG9uZToKKyAgICAgICAgUHlfWERFQ1JFRihsaXRlcmFsX3N0cik7CisgICAgICAgIFB5X1hERUNSRUYoZmllbGRfbmFtZV9zdHIpOworICAgICAgICBQeV9YREVDUkVGKGZvcm1hdF9zcGVjX3N0cik7CisgICAgICAgIFB5X1hERUNSRUYoY29udmVyc2lvbl9zdHIpOworICAgICAgICByZXR1cm4gdHVwbGU7CisgICAgfQorfQorCitzdGF0aWMgUHlNZXRob2REZWYgZm9ybWF0dGVyaXRlcl9tZXRob2RzW10gPSB7CisgICAge05VTEwsICAgICAgICAgICAgICBOVUxMfSAgICAgICAgICAgLyogc2VudGluZWwgKi8KK307CisKK3N0YXRpYyBQeVR5cGVPYmplY3QgUHlGb3JtYXR0ZXJJdGVyX1R5cGUgPSB7CisgICAgUHlWYXJPYmplY3RfSEVBRF9JTklUKCZQeVR5cGVfVHlwZSwgMCkKKyAgICAiZm9ybWF0dGVyaXRlcmF0b3IiLCAgICAgICAgICAgICAgICAvKiB0cF9uYW1lICovCisgICAgc2l6ZW9mKGZvcm1hdHRlcml0ZXJvYmplY3QpLCAgICAgICAgLyogdHBfYmFzaWNzaXplICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfaXRlbXNpemUgKi8KKyAgICAvKiBtZXRob2RzICovCisgICAgKGRlc3RydWN0b3IpZm9ybWF0dGVyaXRlcl9kZWFsbG9jLCAgLyogdHBfZGVhbGxvYyAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3ByaW50ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZ2V0YXR0ciAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3NldGF0dHIgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9jb21wYXJlICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfcmVwciAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2FzX251bWJlciAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2FzX3NlcXVlbmNlICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfYXNfbWFwcGluZyAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2hhc2ggKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9jYWxsICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfc3RyICovCisgICAgUHlPYmplY3RfR2VuZXJpY0dldEF0dHIsICAgICAgICAgICAgLyogdHBfZ2V0YXR0cm8gKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9zZXRhdHRybyAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2FzX2J1ZmZlciAqLworICAgIFB5X1RQRkxBR1NfREVGQVVMVCwgICAgICAgICAgICAgICAgIC8qIHRwX2ZsYWdzICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZG9jICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfdHJhdmVyc2UgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9jbGVhciAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3JpY2hjb21wYXJlICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfd2Vha2xpc3RvZmZzZXQgKi8KKyAgICBQeU9iamVjdF9TZWxmSXRlciwgICAgICAgICAgICAgICAgICAvKiB0cF9pdGVyICovCisgICAgKGl0ZXJuZXh0ZnVuYylmb3JtYXR0ZXJpdGVyX25leHQsICAgLyogdHBfaXRlcm5leHQgKi8KKyAgICBmb3JtYXR0ZXJpdGVyX21ldGhvZHMsICAgICAgICAgICAgICAvKiB0cF9tZXRob2RzICovCisgICAgMCwKK307CisKKy8qIHVuaWNvZGVfZm9ybWF0dGVyX3BhcnNlciBpcyB1c2VkIHRvIGltcGxlbWVudAorICAgc3RyaW5nLkZvcm1hdHRlci52Zm9ybWF0LiAgaXQgcGFyc2VzIGEgc3RyaW5nIGFuZCByZXR1cm5zIHR1cGxlcworICAgZGVzY3JpYmluZyB0aGUgcGFyc2VkIGVsZW1lbnRzLiAgSXQncyBhIHdyYXBwZXIgYXJvdW5kCisgICBzdHJpbmdsaWIvc3RyaW5nX2Zvcm1hdC5oJ3MgTWFya3VwSXRlcmF0b3IgKi8KK3N0YXRpYyBQeU9iamVjdCAqCitmb3JtYXR0ZXJfcGFyc2VyKFNUUklOR0xJQl9PQkpFQ1QgKnNlbGYpCit7CisgICAgZm9ybWF0dGVyaXRlcm9iamVjdCAqaXQ7CisKKyAgICBpdCA9IFB5T2JqZWN0X05ldyhmb3JtYXR0ZXJpdGVyb2JqZWN0LCAmUHlGb3JtYXR0ZXJJdGVyX1R5cGUpOworICAgIGlmIChpdCA9PSBOVUxMKQorICAgICAgICByZXR1cm4gTlVMTDsKKworICAgIC8qIHRha2Ugb3duZXJzaGlwLCBnaXZlIHRoZSBvYmplY3QgdG8gdGhlIGl0ZXJhdG9yICovCisgICAgUHlfSU5DUkVGKHNlbGYpOworICAgIGl0LT5zdHIgPSBzZWxmOworCisgICAgLyogaW5pdGlhbGl6ZSB0aGUgY29udGFpbmVkIE1hcmt1cEl0ZXJhdG9yICovCisgICAgTWFya3VwSXRlcmF0b3JfaW5pdCgmaXQtPml0X21hcmt1cCwKKyAgICAgICAgICAgICAgICAgICAgICAgIFNUUklOR0xJQl9TVFIoc2VsZiksCisgICAgICAgICAgICAgICAgICAgICAgICBTVFJJTkdMSUJfTEVOKHNlbGYpKTsKKworICAgIHJldHVybiAoUHlPYmplY3QgKilpdDsKK30KKworCisvKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLworLyoqKioqKioqKioqIGZpZWxkbmFtZWl0ZXJhdG9yICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KKy8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCisKKworLyogVGhpcyBpcyB1c2VkIHRvIGltcGxlbWVudCBzdHJpbmcuRm9ybWF0dGVyLnZwYXJzZSgpLiAgSXQgcGFyc2VzIHRoZQorICAgZmllbGQgbmFtZSBpbnRvIGF0dHJpYnV0ZSBhbmQgaXRlbSB2YWx1ZXMuICBJdCdzIGEgUHl0aG9uLWNhbGxhYmxlCisgICB3cmFwcGVyIGFyb3VuZCBGaWVsZE5hbWVJdGVyYXRvciAqLworCit0eXBlZGVmIHN0cnVjdCB7CisgICAgUHlPYmplY3RfSEVBRAorCisgICAgU1RSSU5HTElCX09CSkVDVCAqc3RyOworCisgICAgRmllbGROYW1lSXRlcmF0b3IgaXRfZmllbGQ7Cit9IGZpZWxkbmFtZWl0ZXJvYmplY3Q7CisKK3N0YXRpYyB2b2lkCitmaWVsZG5hbWVpdGVyX2RlYWxsb2MoZmllbGRuYW1laXRlcm9iamVjdCAqaXQpCit7CisgICAgUHlfWERFQ1JFRihpdC0+c3RyKTsKKyAgICBQeU9iamVjdF9GUkVFKGl0KTsKK30KKworLyogcmV0dXJucyBhIHR1cGxlOgorICAgKGlzX2F0dHIsIHZhbHVlKQorICAgaXNfYXR0ciBpcyB0cnVlIGlmIHdlIHVzZWQgYXR0cmlidXRlIHN5bnRheCAoZS5nLiwgJy5mb28nKQorICAgICAgICAgICAgICBmYWxzZSBpZiB3ZSB1c2VkIGluZGV4IHN5bnRheCAoZS5nLiwgJ1tmb29dJykKKyAgIHZhbHVlIGlzIGFuIGludGVnZXIgb3Igc3RyaW5nCisqLworc3RhdGljIFB5T2JqZWN0ICoKK2ZpZWxkbmFtZWl0ZXJfbmV4dChmaWVsZG5hbWVpdGVyb2JqZWN0ICppdCkKK3sKKyAgICBpbnQgcmVzdWx0OworICAgIGludCBpc19hdHRyOworICAgIFB5X3NzaXplX3QgaWR4OworICAgIFN1YlN0cmluZyBuYW1lOworCisgICAgcmVzdWx0ID0gRmllbGROYW1lSXRlcmF0b3JfbmV4dCgmaXQtPml0X2ZpZWxkLCAmaXNfYXR0ciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZpZHgsICZuYW1lKTsKKyAgICBpZiAocmVzdWx0ID09IDAgfHwgcmVzdWx0ID09IDEpCisgICAgICAgIC8qIGlmIDAsIGVycm9yIGhhcyBhbHJlYWR5IGJlZW4gc2V0LCBpZiAxLCBpdGVyYXRvciBpcyBlbXB0eSAqLworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICBlbHNlIHsKKyAgICAgICAgUHlPYmplY3QqIHJlc3VsdCA9IE5VTEw7CisgICAgICAgIFB5T2JqZWN0KiBpc19hdHRyX29iaiA9IE5VTEw7CisgICAgICAgIFB5T2JqZWN0KiBvYmogPSBOVUxMOworCisgICAgICAgIGlzX2F0dHJfb2JqID0gUHlCb29sX0Zyb21Mb25nKGlzX2F0dHIpOworICAgICAgICBpZiAoaXNfYXR0cl9vYmogPT0gTlVMTCkKKyAgICAgICAgICAgIGdvdG8gZG9uZTsKKworICAgICAgICAvKiBlaXRoZXIgYW4gaW50ZWdlciBvciBhIHN0cmluZyAqLworICAgICAgICBpZiAoaWR4ICE9IC0xKQorICAgICAgICAgICAgb2JqID0gUHlMb25nX0Zyb21Tc2l6ZV90KGlkeCk7CisgICAgICAgIGVsc2UKKyAgICAgICAgICAgIG9iaiA9IFN1YlN0cmluZ19uZXdfb2JqZWN0KCZuYW1lKTsKKyAgICAgICAgaWYgKG9iaiA9PSBOVUxMKQorICAgICAgICAgICAgZ290byBkb25lOworCisgICAgICAgIC8qIHJldHVybiBhIHR1cGxlIG9mIHZhbHVlcyAqLworICAgICAgICByZXN1bHQgPSBQeVR1cGxlX1BhY2soMiwgaXNfYXR0cl9vYmosIG9iaik7CisKKyAgICBkb25lOgorICAgICAgICBQeV9YREVDUkVGKGlzX2F0dHJfb2JqKTsKKyAgICAgICAgUHlfWERFQ1JFRihvYmopOworICAgICAgICByZXR1cm4gcmVzdWx0OworICAgIH0KK30KKworc3RhdGljIFB5TWV0aG9kRGVmIGZpZWxkbmFtZWl0ZXJfbWV0aG9kc1tdID0geworICAgIHtOVUxMLCAgICAgICAgICAgICAgTlVMTH0gICAgICAgICAgIC8qIHNlbnRpbmVsICovCit9OworCitzdGF0aWMgUHlUeXBlT2JqZWN0IFB5RmllbGROYW1lSXRlcl9UeXBlID0geworICAgIFB5VmFyT2JqZWN0X0hFQURfSU5JVCgmUHlUeXBlX1R5cGUsIDApCisgICAgImZpZWxkbmFtZWl0ZXJhdG9yIiwgICAgICAgICAgICAgICAgLyogdHBfbmFtZSAqLworICAgIHNpemVvZihmaWVsZG5hbWVpdGVyb2JqZWN0KSwgICAgICAgIC8qIHRwX2Jhc2ljc2l6ZSAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2l0ZW1zaXplICovCisgICAgLyogbWV0aG9kcyAqLworICAgIChkZXN0cnVjdG9yKWZpZWxkbmFtZWl0ZXJfZGVhbGxvYywgIC8qIHRwX2RlYWxsb2MgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9wcmludCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2dldGF0dHIgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9zZXRhdHRyICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfY29tcGFyZSAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3JlcHIgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9hc19udW1iZXIgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9hc19zZXF1ZW5jZSAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2FzX21hcHBpbmcgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9oYXNoICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfY2FsbCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3N0ciAqLworICAgIFB5T2JqZWN0X0dlbmVyaWNHZXRBdHRyLCAgICAgICAgICAgIC8qIHRwX2dldGF0dHJvICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfc2V0YXR0cm8gKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9hc19idWZmZXIgKi8KKyAgICBQeV9UUEZMQUdTX0RFRkFVTFQsICAgICAgICAgICAgICAgICAvKiB0cF9mbGFncyAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2RvYyAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3RyYXZlcnNlICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfY2xlYXIgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9yaWNoY29tcGFyZSAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3dlYWtsaXN0b2Zmc2V0ICovCisgICAgUHlPYmplY3RfU2VsZkl0ZXIsICAgICAgICAgICAgICAgICAgLyogdHBfaXRlciAqLworICAgIChpdGVybmV4dGZ1bmMpZmllbGRuYW1laXRlcl9uZXh0LCAgIC8qIHRwX2l0ZXJuZXh0ICovCisgICAgZmllbGRuYW1laXRlcl9tZXRob2RzLCAgICAgICAgICAgICAgLyogdHBfbWV0aG9kcyAqLworICAgIDB9OworCisvKiB1bmljb2RlX2Zvcm1hdHRlcl9maWVsZF9uYW1lX3NwbGl0IGlzIHVzZWQgdG8gaW1wbGVtZW50CisgICBzdHJpbmcuRm9ybWF0dGVyLnZmb3JtYXQuICBpdCB0YWtlcyBhbiBQRVAgMzEwMSAiZmllbGQgbmFtZSIsIGFuZAorICAgcmV0dXJucyBhIHR1cGxlIG9mIChmaXJzdCwgcmVzdCk6ICJmaXJzdCIsIHRoZSBwYXJ0IGJlZm9yZSB0aGUKKyAgIGZpcnN0ICcuJyBvciAnWyc7IGFuZCAicmVzdCIsIGFuIGl0ZXJhdG9yIGZvciB0aGUgcmVzdCBvZiB0aGUgZmllbGQKKyAgIG5hbWUuICBpdCdzIGEgd3JhcHBlciBhcm91bmQgc3RyaW5nbGliL3N0cmluZ19mb3JtYXQuaCdzCisgICBmaWVsZF9uYW1lX3NwbGl0LiAgVGhlIGl0ZXJhdG9yIGl0IHJldHVybnMgaXMgYQorICAgRmllbGROYW1lSXRlcmF0b3IgKi8KK3N0YXRpYyBQeU9iamVjdCAqCitmb3JtYXR0ZXJfZmllbGRfbmFtZV9zcGxpdChTVFJJTkdMSUJfT0JKRUNUICpzZWxmKQoreworICAgIFN1YlN0cmluZyBmaXJzdDsKKyAgICBQeV9zc2l6ZV90IGZpcnN0X2lkeDsKKyAgICBmaWVsZG5hbWVpdGVyb2JqZWN0ICppdDsKKworICAgIFB5T2JqZWN0ICpmaXJzdF9vYmogPSBOVUxMOworICAgIFB5T2JqZWN0ICpyZXN1bHQgPSBOVUxMOworCisgICAgaXQgPSBQeU9iamVjdF9OZXcoZmllbGRuYW1laXRlcm9iamVjdCwgJlB5RmllbGROYW1lSXRlcl9UeXBlKTsKKyAgICBpZiAoaXQgPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisKKyAgICAvKiB0YWtlIG93bmVyc2hpcCwgZ2l2ZSB0aGUgb2JqZWN0IHRvIHRoZSBpdGVyYXRvci4gIHRoaXMgaXMKKyAgICAgICBqdXN0IHRvIGtlZXAgdGhlIGZpZWxkX25hbWUgYWxpdmUgKi8KKyAgICBQeV9JTkNSRUYoc2VsZik7CisgICAgaXQtPnN0ciA9IHNlbGY7CisKKyAgICAvKiBQYXNzIGluIGF1dG9fbnVtYmVyID0gTlVMTC4gV2UnbGwgcmV0dXJuIGFuIGVtcHR5IHN0cmluZyBmb3IKKyAgICAgICBmaXJzdF9vYmogaW4gdGhhdCBjYXNlLiAqLworICAgIGlmICghZmllbGRfbmFtZV9zcGxpdChTVFJJTkdMSUJfU1RSKHNlbGYpLAorICAgICAgICAgICAgICAgICAgICAgICAgICBTVFJJTkdMSUJfTEVOKHNlbGYpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAmZmlyc3QsICZmaXJzdF9pZHgsICZpdC0+aXRfZmllbGQsIE5VTEwpKQorICAgICAgICBnb3RvIGRvbmU7CisKKyAgICAvKiBmaXJzdCBiZWNvbWVzIGFuIGludGVnZXIsIGlmIHBvc3NpYmxlOyBlbHNlIGEgc3RyaW5nICovCisgICAgaWYgKGZpcnN0X2lkeCAhPSAtMSkKKyAgICAgICAgZmlyc3Rfb2JqID0gUHlMb25nX0Zyb21Tc2l6ZV90KGZpcnN0X2lkeCk7CisgICAgZWxzZQorICAgICAgICAvKiBjb252ZXJ0ICJmaXJzdCIgaW50byBhIHN0cmluZyBvYmplY3QgKi8KKyAgICAgICAgZmlyc3Rfb2JqID0gU3ViU3RyaW5nX25ld19vYmplY3QoJmZpcnN0KTsKKyAgICBpZiAoZmlyc3Rfb2JqID09IE5VTEwpCisgICAgICAgIGdvdG8gZG9uZTsKKworICAgIC8qIHJldHVybiBhIHR1cGxlIG9mIHZhbHVlcyAqLworICAgIHJlc3VsdCA9IFB5VHVwbGVfUGFjaygyLCBmaXJzdF9vYmosIGl0KTsKKworZG9uZToKKyAgICBQeV9YREVDUkVGKGl0KTsKKyAgICBQeV9YREVDUkVGKGZpcnN0X29iaik7CisgICAgcmV0dXJuIHJlc3VsdDsKK30KZGlmZiAtLWdpdCBhL1B5dGhvbi0yLjcuNS9PYmplY3RzL3N0cmluZ2xpYi9zdHJpbmdkZWZzLmggYi9QeXRob24tMi43LjUvT2JqZWN0cy9zdHJpbmdsaWIvc3RyaW5nZGVmcy5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjg0ZTQ2MTYKLS0tIC9kZXYvbnVsbAorKysgYi9QeXRob24tMi43LjUvT2JqZWN0cy9zdHJpbmdsaWIvc3RyaW5nZGVmcy5oCkBAIC0wLDAgKzEsMzMgQEAKKyNpZm5kZWYgU1RSSU5HTElCX1NUUklOR0RFRlNfSAorI2RlZmluZSBTVFJJTkdMSUJfU1RSSU5HREVGU19ICisKKy8qIHRoaXMgaXMgc29ydCBvZiBhIGhhY2suICB0aGVyZSdzIGF0IGxlYXN0IG9uZSBwbGFjZSAoZm9ybWF0dGluZworICAgZmxvYXRzKSB3aGVyZSBzb21lIHN0cmluZ2xpYiBjb2RlIHRha2VzIGEgZGlmZmVyZW50IHBhdGggaWYgaXQncworICAgY29tcGlsZWQgYXMgdW5pY29kZS4gKi8KKyNkZWZpbmUgU1RSSU5HTElCX0lTX1VOSUNPREUgICAgIDAKKworI2RlZmluZSBTVFJJTkdMSUJfT0JKRUNUICAgICAgICAgUHlTdHJpbmdPYmplY3QKKyNkZWZpbmUgU1RSSU5HTElCX0NIQVIgICAgICAgICAgIGNoYXIKKyNkZWZpbmUgU1RSSU5HTElCX1RZUEVfTkFNRSAgICAgICJzdHJpbmciCisjZGVmaW5lIFNUUklOR0xJQl9QQVJTRV9DT0RFICAgICAiUyIKKyNkZWZpbmUgU1RSSU5HTElCX0VNUFRZICAgICAgICAgIG51bGxzdHJpbmcKKyNkZWZpbmUgU1RSSU5HTElCX0lTU1BBQ0UgICAgICAgIFB5X0lTU1BBQ0UKKyNkZWZpbmUgU1RSSU5HTElCX0lTTElORUJSRUFLKHgpICgoeCA9PSAnXG4nKSB8fCAoeCA9PSAnXHInKSkKKyNkZWZpbmUgU1RSSU5HTElCX0lTREVDSU1BTCh4KSAgICgoeCA+PSAnMCcpICYmICh4IDw9ICc5JykpCisjZGVmaW5lIFNUUklOR0xJQl9UT0RFQ0lNQUwoeCkgICAoU1RSSU5HTElCX0lTREVDSU1BTCh4KSA/ICh4IC0gJzAnKSA6IC0xKQorI2RlZmluZSBTVFJJTkdMSUJfVE9VUFBFUiAgICAgICAgUHlfVE9VUFBFUgorI2RlZmluZSBTVFJJTkdMSUJfVE9MT1dFUiAgICAgICAgUHlfVE9MT1dFUgorI2RlZmluZSBTVFJJTkdMSUJfRklMTCAgICAgICAgICAgbWVtc2V0CisjZGVmaW5lIFNUUklOR0xJQl9TVFIgICAgICAgICAgICBQeVN0cmluZ19BU19TVFJJTkcKKyNkZWZpbmUgU1RSSU5HTElCX0xFTiAgICAgICAgICAgIFB5U3RyaW5nX0dFVF9TSVpFCisjZGVmaW5lIFNUUklOR0xJQl9ORVcgICAgICAgICAgICBQeVN0cmluZ19Gcm9tU3RyaW5nQW5kU2l6ZQorI2RlZmluZSBTVFJJTkdMSUJfUkVTSVpFICAgICAgICAgX1B5U3RyaW5nX1Jlc2l6ZQorI2RlZmluZSBTVFJJTkdMSUJfQ0hFQ0sgICAgICAgICAgUHlTdHJpbmdfQ2hlY2sKKyNkZWZpbmUgU1RSSU5HTElCX0NIRUNLX0VYQUNUICAgIFB5U3RyaW5nX0NoZWNrRXhhY3QKKyNkZWZpbmUgU1RSSU5HTElCX1RPU1RSICAgICAgICAgIFB5T2JqZWN0X1N0cgorI2RlZmluZSBTVFJJTkdMSUJfR1JPVVBJTkcgICAgICAgX1B5U3RyaW5nX0luc2VydFRob3VzYW5kc0dyb3VwaW5nCisjZGVmaW5lIFNUUklOR0xJQl9HUk9VUElOR19MT0NBTEUgX1B5U3RyaW5nX0luc2VydFRob3VzYW5kc0dyb3VwaW5nTG9jYWxlCisKKyNkZWZpbmUgU1RSSU5HTElCX1dBTlRfQ09OVEFJTlNfT0JKIDEKKworI2VuZGlmIC8qICFTVFJJTkdMSUJfU1RSSU5HREVGU19IICovCmRpZmYgLS1naXQgYS9QeXRob24tMi43LjUvT2JqZWN0cy9zdHJpbmdsaWIvdHJhbnNtb2dyaWZ5LmggYi9QeXRob24tMi43LjUvT2JqZWN0cy9zdHJpbmdsaWIvdHJhbnNtb2dyaWZ5LmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMWUxMzJlNQotLS0gL2Rldi9udWxsCisrKyBiL1B5dGhvbi0yLjcuNS9PYmplY3RzL3N0cmluZ2xpYi90cmFuc21vZ3JpZnkuaApAQCAtMCwwICsxLDI2NCBAQAorLyogTk9URTogdGhpcyBBUEkgaXMgLU9OTFktIGZvciB1c2Ugd2l0aCBzaW5nbGUgYnl0ZSBjaGFyYWN0ZXIgc3RyaW5ncy4gKi8KKy8qIERvIG5vdCB1c2UgaXQgd2l0aCBVbmljb2RlLiAqLworCisvKiB0aGUgbW9yZSBjb21wbGljYXRlZCBtZXRob2RzLiAgcGFydHMgb2YgdGhlc2Ugc2hvdWxkIGJlIHB1bGxlZCBvdXQgaW50byB0aGUKKyAgIHNoYXJlZCBjb2RlIGluIGJ5dGVzX21ldGhvZHMuYyB0byBjdXQgZG93biBvbiBkdXBsaWNhdGUgY29kZSBibG9hdC4gICovCisKK1B5RG9jX1NUUlZBUihleHBhbmR0YWJzX19kb2NfXywKKyJCLmV4cGFuZHRhYnMoW3RhYnNpemVdKSAtPiBjb3B5IG9mIEJcblwKK1xuXAorUmV0dXJuIGEgY29weSBvZiBCIHdoZXJlIGFsbCB0YWIgY2hhcmFjdGVycyBhcmUgZXhwYW5kZWQgdXNpbmcgc3BhY2VzLlxuXAorSWYgdGFic2l6ZSBpcyBub3QgZ2l2ZW4sIGEgdGFiIHNpemUgb2YgOCBjaGFyYWN0ZXJzIGlzIGFzc3VtZWQuIik7CisKK3N0YXRpYyBQeU9iamVjdCoKK3N0cmluZ2xpYl9leHBhbmR0YWJzKFB5T2JqZWN0ICpzZWxmLCBQeU9iamVjdCAqYXJncykKK3sKKyAgICBjb25zdCBjaGFyICplLCAqcDsKKyAgICBjaGFyICpxOworICAgIHNpemVfdCBpLCBqOworICAgIFB5T2JqZWN0ICp1OworICAgIGludCB0YWJzaXplID0gODsKKyAgICAKKyAgICBpZiAoIVB5QXJnX1BhcnNlVHVwbGUoYXJncywgInxpOmV4cGFuZHRhYnMiLCAmdGFic2l6ZSkpCisgICAgICAgIHJldHVybiBOVUxMOworICAgIAorICAgIC8qIEZpcnN0IHBhc3M6IGRldGVybWluZSBzaXplIG9mIG91dHB1dCBzdHJpbmcgKi8KKyAgICBpID0gaiA9IDA7CisgICAgZSA9IFNUUklOR0xJQl9TVFIoc2VsZikgKyBTVFJJTkdMSUJfTEVOKHNlbGYpOworICAgIGZvciAocCA9IFNUUklOR0xJQl9TVFIoc2VsZik7IHAgPCBlOyBwKyspCisgICAgICAgIGlmICgqcCA9PSAnXHQnKSB7CisgICAgICAgICAgICBpZiAodGFic2l6ZSA+IDApIHsKKyAgICAgICAgICAgICAgICBqICs9IHRhYnNpemUgLSAoaiAlIHRhYnNpemUpOworICAgICAgICAgICAgICAgIGlmIChqID4gUFlfU1NJWkVfVF9NQVgpIHsKKyAgICAgICAgICAgICAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX092ZXJmbG93RXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAicmVzdWx0IGlzIHRvbyBsb25nIik7CisgICAgICAgICAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBlbHNlIHsKKyAgICAgICAgICAgIGorKzsKKyAgICAgICAgICAgIGlmICgqcCA9PSAnXG4nIHx8ICpwID09ICdccicpIHsKKyAgICAgICAgICAgICAgICBpICs9IGo7CisgICAgICAgICAgICAgICAgaiA9IDA7CisgICAgICAgICAgICAgICAgaWYgKGkgPiBQWV9TU0laRV9UX01BWCkgeworICAgICAgICAgICAgICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfT3ZlcmZsb3dFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJyZXN1bHQgaXMgdG9vIGxvbmciKTsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgCisgICAgaWYgKChpICsgaikgPiBQWV9TU0laRV9UX01BWCkgeworICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfT3ZlcmZsb3dFcnJvciwgInJlc3VsdCBpcyB0b28gbG9uZyIpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgCisgICAgLyogU2Vjb25kIHBhc3M6IGNyZWF0ZSBvdXRwdXQgc3RyaW5nIGFuZCBmaWxsIGl0ICovCisgICAgdSA9IFNUUklOR0xJQl9ORVcoTlVMTCwgaSArIGopOworICAgIGlmICghdSkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgCisgICAgaiA9IDA7CisgICAgcSA9IFNUUklOR0xJQl9TVFIodSk7CisgICAgCisgICAgZm9yIChwID0gU1RSSU5HTElCX1NUUihzZWxmKTsgcCA8IGU7IHArKykKKyAgICAgICAgaWYgKCpwID09ICdcdCcpIHsKKyAgICAgICAgICAgIGlmICh0YWJzaXplID4gMCkgeworICAgICAgICAgICAgICAgIGkgPSB0YWJzaXplIC0gKGogJSB0YWJzaXplKTsKKyAgICAgICAgICAgICAgICBqICs9IGk7CisgICAgICAgICAgICAgICAgd2hpbGUgKGktLSkKKyAgICAgICAgICAgICAgICAgICAgKnErKyA9ICcgJzsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBlbHNlIHsKKyAgICAgICAgICAgIGorKzsKKyAgICAgICAgICAgICpxKysgPSAqcDsKKyAgICAgICAgICAgIGlmICgqcCA9PSAnXG4nIHx8ICpwID09ICdccicpCisgICAgICAgICAgICAgICAgaiA9IDA7CisgICAgICAgIH0KKyAgICAKKyAgICByZXR1cm4gdTsKK30KKworUHlfTE9DQUxfSU5MSU5FKFB5T2JqZWN0ICopCitwYWQoUHlPYmplY3QgKnNlbGYsIFB5X3NzaXplX3QgbGVmdCwgUHlfc3NpemVfdCByaWdodCwgY2hhciBmaWxsKQoreworICAgIFB5T2JqZWN0ICp1OworCisgICAgaWYgKGxlZnQgPCAwKQorICAgICAgICBsZWZ0ID0gMDsKKyAgICBpZiAocmlnaHQgPCAwKQorICAgICAgICByaWdodCA9IDA7CisKKyAgICBpZiAobGVmdCA9PSAwICYmIHJpZ2h0ID09IDAgJiYgU1RSSU5HTElCX0NIRUNLX0VYQUNUKHNlbGYpKSB7CisjaWYgU1RSSU5HTElCX01VVEFCTEUKKyAgICAgICAgLyogV2UncmUgZGVmaW5lZCBhcyByZXR1cm5pbmcgYSBjb3B5OyAgSWYgdGhlIG9iamVjdCBpcyBtdXRhYmxlCisgICAgICAgICAqIHRoYXQgbWVhbnMgd2UgbXVzdCBtYWtlIGFuIGlkZW50aWNhbCBjb3B5LiAqLworICAgICAgICByZXR1cm4gU1RSSU5HTElCX05FVyhTVFJJTkdMSUJfU1RSKHNlbGYpLCBTVFJJTkdMSUJfTEVOKHNlbGYpKTsKKyNlbHNlCisgICAgICAgIFB5X0lOQ1JFRihzZWxmKTsKKyAgICAgICAgcmV0dXJuIChQeU9iamVjdCAqKXNlbGY7CisjZW5kaWYgLyogU1RSSU5HTElCX01VVEFCTEUgKi8KKyAgICB9CisKKyAgICB1ID0gU1RSSU5HTElCX05FVyhOVUxMLAorCQkJCSAgIGxlZnQgKyBTVFJJTkdMSUJfTEVOKHNlbGYpICsgcmlnaHQpOworICAgIGlmICh1KSB7CisgICAgICAgIGlmIChsZWZ0KQorICAgICAgICAgICAgbWVtc2V0KFNUUklOR0xJQl9TVFIodSksIGZpbGwsIGxlZnQpOworICAgICAgICBQeV9NRU1DUFkoU1RSSU5HTElCX1NUUih1KSArIGxlZnQsCisJICAgICAgIFNUUklOR0xJQl9TVFIoc2VsZiksCisJICAgICAgIFNUUklOR0xJQl9MRU4oc2VsZikpOworICAgICAgICBpZiAocmlnaHQpCisgICAgICAgICAgICBtZW1zZXQoU1RSSU5HTElCX1NUUih1KSArIGxlZnQgKyBTVFJJTkdMSUJfTEVOKHNlbGYpLAorCQkgICBmaWxsLCByaWdodCk7CisgICAgfQorCisgICAgcmV0dXJuIHU7Cit9CisKK1B5RG9jX1NUUlZBUihsanVzdF9fZG9jX18sCisiQi5sanVzdCh3aWR0aFssIGZpbGxjaGFyXSkgLT4gY29weSBvZiBCXG4iCisiXG4iCisiUmV0dXJuIEIgbGVmdCBqdXN0aWZpZWQgaW4gYSBzdHJpbmcgb2YgbGVuZ3RoIHdpZHRoLiBQYWRkaW5nIGlzXG4iCisiZG9uZSB1c2luZyB0aGUgc3BlY2lmaWVkIGZpbGwgY2hhcmFjdGVyIChkZWZhdWx0IGlzIGEgc3BhY2UpLiIpOworCitzdGF0aWMgUHlPYmplY3QgKgorc3RyaW5nbGliX2xqdXN0KFB5T2JqZWN0ICpzZWxmLCBQeU9iamVjdCAqYXJncykKK3sKKyAgICBQeV9zc2l6ZV90IHdpZHRoOworICAgIGNoYXIgZmlsbGNoYXIgPSAnICc7CisKKyAgICBpZiAoIVB5QXJnX1BhcnNlVHVwbGUoYXJncywgIm58YzpsanVzdCIsICZ3aWR0aCwgJmZpbGxjaGFyKSkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisKKyAgICBpZiAoU1RSSU5HTElCX0xFTihzZWxmKSA+PSB3aWR0aCAmJiBTVFJJTkdMSUJfQ0hFQ0tfRVhBQ1Qoc2VsZikpIHsKKyNpZiBTVFJJTkdMSUJfTVVUQUJMRQorICAgICAgICAvKiBXZSdyZSBkZWZpbmVkIGFzIHJldHVybmluZyBhIGNvcHk7ICBJZiB0aGUgb2JqZWN0IGlzIG11dGFibGUKKyAgICAgICAgICogdGhhdCBtZWFucyB3ZSBtdXN0IG1ha2UgYW4gaWRlbnRpY2FsIGNvcHkuICovCisgICAgICAgIHJldHVybiBTVFJJTkdMSUJfTkVXKFNUUklOR0xJQl9TVFIoc2VsZiksIFNUUklOR0xJQl9MRU4oc2VsZikpOworI2Vsc2UKKyAgICAgICAgUHlfSU5DUkVGKHNlbGYpOworICAgICAgICByZXR1cm4gKFB5T2JqZWN0Kikgc2VsZjsKKyNlbmRpZgorICAgIH0KKworICAgIHJldHVybiBwYWQoc2VsZiwgMCwgd2lkdGggLSBTVFJJTkdMSUJfTEVOKHNlbGYpLCBmaWxsY2hhcik7Cit9CisKKworUHlEb2NfU1RSVkFSKHJqdXN0X19kb2NfXywKKyJCLnJqdXN0KHdpZHRoWywgZmlsbGNoYXJdKSAtPiBjb3B5IG9mIEJcbiIKKyJcbiIKKyJSZXR1cm4gQiByaWdodCBqdXN0aWZpZWQgaW4gYSBzdHJpbmcgb2YgbGVuZ3RoIHdpZHRoLiBQYWRkaW5nIGlzXG4iCisiZG9uZSB1c2luZyB0aGUgc3BlY2lmaWVkIGZpbGwgY2hhcmFjdGVyIChkZWZhdWx0IGlzIGEgc3BhY2UpIik7CisKK3N0YXRpYyBQeU9iamVjdCAqCitzdHJpbmdsaWJfcmp1c3QoUHlPYmplY3QgKnNlbGYsIFB5T2JqZWN0ICphcmdzKQoreworICAgIFB5X3NzaXplX3Qgd2lkdGg7CisgICAgY2hhciBmaWxsY2hhciA9ICcgJzsKKworICAgIGlmICghUHlBcmdfUGFyc2VUdXBsZShhcmdzLCAibnxjOnJqdXN0IiwgJndpZHRoLCAmZmlsbGNoYXIpKQorICAgICAgICByZXR1cm4gTlVMTDsKKworICAgIGlmIChTVFJJTkdMSUJfTEVOKHNlbGYpID49IHdpZHRoICYmIFNUUklOR0xJQl9DSEVDS19FWEFDVChzZWxmKSkgeworI2lmIFNUUklOR0xJQl9NVVRBQkxFCisgICAgICAgIC8qIFdlJ3JlIGRlZmluZWQgYXMgcmV0dXJuaW5nIGEgY29weTsgIElmIHRoZSBvYmplY3QgaXMgbXV0YWJsZQorICAgICAgICAgKiB0aGF0IG1lYW5zIHdlIG11c3QgbWFrZSBhbiBpZGVudGljYWwgY29weS4gKi8KKyAgICAgICAgcmV0dXJuIFNUUklOR0xJQl9ORVcoU1RSSU5HTElCX1NUUihzZWxmKSwgU1RSSU5HTElCX0xFTihzZWxmKSk7CisjZWxzZQorICAgICAgICBQeV9JTkNSRUYoc2VsZik7CisgICAgICAgIHJldHVybiAoUHlPYmplY3QqKSBzZWxmOworI2VuZGlmCisgICAgfQorCisgICAgcmV0dXJuIHBhZChzZWxmLCB3aWR0aCAtIFNUUklOR0xJQl9MRU4oc2VsZiksIDAsIGZpbGxjaGFyKTsKK30KKworCitQeURvY19TVFJWQVIoY2VudGVyX19kb2NfXywKKyJCLmNlbnRlcih3aWR0aFssIGZpbGxjaGFyXSkgLT4gY29weSBvZiBCXG4iCisiXG4iCisiUmV0dXJuIEIgY2VudGVyZWQgaW4gYSBzdHJpbmcgb2YgbGVuZ3RoIHdpZHRoLiAgUGFkZGluZyBpc1xuIgorImRvbmUgdXNpbmcgdGhlIHNwZWNpZmllZCBmaWxsIGNoYXJhY3RlciAoZGVmYXVsdCBpcyBhIHNwYWNlKS4iKTsKKworc3RhdGljIFB5T2JqZWN0ICoKK3N0cmluZ2xpYl9jZW50ZXIoUHlPYmplY3QgKnNlbGYsIFB5T2JqZWN0ICphcmdzKQoreworICAgIFB5X3NzaXplX3QgbWFyZywgbGVmdDsKKyAgICBQeV9zc2l6ZV90IHdpZHRoOworICAgIGNoYXIgZmlsbGNoYXIgPSAnICc7CisKKyAgICBpZiAoIVB5QXJnX1BhcnNlVHVwbGUoYXJncywgIm58YzpjZW50ZXIiLCAmd2lkdGgsICZmaWxsY2hhcikpCisgICAgICAgIHJldHVybiBOVUxMOworCisgICAgaWYgKFNUUklOR0xJQl9MRU4oc2VsZikgPj0gd2lkdGggJiYgU1RSSU5HTElCX0NIRUNLX0VYQUNUKHNlbGYpKSB7CisjaWYgU1RSSU5HTElCX01VVEFCTEUKKyAgICAgICAgLyogV2UncmUgZGVmaW5lZCBhcyByZXR1cm5pbmcgYSBjb3B5OyAgSWYgdGhlIG9iamVjdCBpcyBtdXRhYmxlCisgICAgICAgICAqIHRoYXQgbWVhbnMgd2UgbXVzdCBtYWtlIGFuIGlkZW50aWNhbCBjb3B5LiAqLworICAgICAgICByZXR1cm4gU1RSSU5HTElCX05FVyhTVFJJTkdMSUJfU1RSKHNlbGYpLCBTVFJJTkdMSUJfTEVOKHNlbGYpKTsKKyNlbHNlCisgICAgICAgIFB5X0lOQ1JFRihzZWxmKTsKKyAgICAgICAgcmV0dXJuIChQeU9iamVjdCopIHNlbGY7CisjZW5kaWYKKyAgICB9CisKKyAgICBtYXJnID0gd2lkdGggLSBTVFJJTkdMSUJfTEVOKHNlbGYpOworICAgIGxlZnQgPSBtYXJnIC8gMiArIChtYXJnICYgd2lkdGggJiAxKTsKKworICAgIHJldHVybiBwYWQoc2VsZiwgbGVmdCwgbWFyZyAtIGxlZnQsIGZpbGxjaGFyKTsKK30KKworUHlEb2NfU1RSVkFSKHpmaWxsX19kb2NfXywKKyJCLnpmaWxsKHdpZHRoKSAtPiBjb3B5IG9mIEJcbiIKKyJcbiIKKyJQYWQgYSBudW1lcmljIHN0cmluZyBCIHdpdGggemVyb3Mgb24gdGhlIGxlZnQsIHRvIGZpbGwgYSBmaWVsZFxuIgorIm9mIHRoZSBzcGVjaWZpZWQgd2lkdGguICBCIGlzIG5ldmVyIHRydW5jYXRlZC4iKTsKKworc3RhdGljIFB5T2JqZWN0ICoKK3N0cmluZ2xpYl96ZmlsbChQeU9iamVjdCAqc2VsZiwgUHlPYmplY3QgKmFyZ3MpCit7CisgICAgUHlfc3NpemVfdCBmaWxsOworICAgIFB5T2JqZWN0ICpzOworICAgIGNoYXIgKnA7CisgICAgUHlfc3NpemVfdCB3aWR0aDsKKworICAgIGlmICghUHlBcmdfUGFyc2VUdXBsZShhcmdzLCAibjp6ZmlsbCIsICZ3aWR0aCkpCisgICAgICAgIHJldHVybiBOVUxMOworCisgICAgaWYgKFNUUklOR0xJQl9MRU4oc2VsZikgPj0gd2lkdGgpIHsKKyAgICAgICAgaWYgKFNUUklOR0xJQl9DSEVDS19FWEFDVChzZWxmKSkgeworI2lmIFNUUklOR0xJQl9NVVRBQkxFCisgICAgICAgICAgICAvKiBXZSdyZSBkZWZpbmVkIGFzIHJldHVybmluZyBhIGNvcHk7ICBJZiB0aGUgb2JqZWN0IGlzIG11dGFibGUKKyAgICAgICAgICAgICAqIHRoYXQgbWVhbnMgd2UgbXVzdCBtYWtlIGFuIGlkZW50aWNhbCBjb3B5LiAqLworICAgICAgICAgICAgcmV0dXJuIFNUUklOR0xJQl9ORVcoU1RSSU5HTElCX1NUUihzZWxmKSwgU1RSSU5HTElCX0xFTihzZWxmKSk7CisjZWxzZQorICAgICAgICAgICAgUHlfSU5DUkVGKHNlbGYpOworICAgICAgICAgICAgcmV0dXJuIChQeU9iamVjdCopIHNlbGY7CisjZW5kaWYKKyAgICAgICAgfQorICAgICAgICBlbHNlCisgICAgICAgICAgICByZXR1cm4gU1RSSU5HTElCX05FVygKKyAgICAgICAgICAgICAgICBTVFJJTkdMSUJfU1RSKHNlbGYpLAorICAgICAgICAgICAgICAgIFNUUklOR0xJQl9MRU4oc2VsZikKKyAgICAgICAgICAgICk7CisgICAgfQorCisgICAgZmlsbCA9IHdpZHRoIC0gU1RSSU5HTElCX0xFTihzZWxmKTsKKworICAgIHMgPSBwYWQoc2VsZiwgZmlsbCwgMCwgJzAnKTsKKworICAgIGlmIChzID09IE5VTEwpCisgICAgICAgIHJldHVybiBOVUxMOworCisgICAgcCA9IFNUUklOR0xJQl9TVFIocyk7CisgICAgaWYgKHBbZmlsbF0gPT0gJysnIHx8IHBbZmlsbF0gPT0gJy0nKSB7CisgICAgICAgIC8qIG1vdmUgc2lnbiB0byBiZWdpbm5pbmcgb2Ygc3RyaW5nICovCisgICAgICAgIHBbMF0gPSBwW2ZpbGxdOworICAgICAgICBwW2ZpbGxdID0gJzAnOworICAgIH0KKworICAgIHJldHVybiAoUHlPYmplY3QqKSBzOworfQpkaWZmIC0tZ2l0IGEvUHl0aG9uLTIuNy41L09iamVjdHMvc3RyaW5nbGliL3VuaWNvZGVkZWZzLmggYi9QeXRob24tMi43LjUvT2JqZWN0cy9zdHJpbmdsaWIvdW5pY29kZWRlZnMuaApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5kZDgxNGY2Ci0tLSAvZGV2L251bGwKKysrIGIvUHl0aG9uLTIuNy41L09iamVjdHMvc3RyaW5nbGliL3VuaWNvZGVkZWZzLmgKQEAgLTAsMCArMSwzNyBAQAorI2lmbmRlZiBTVFJJTkdMSUJfVU5JQ09ERURFRlNfSAorI2RlZmluZSBTVFJJTkdMSUJfVU5JQ09ERURFRlNfSAorCisvKiB0aGlzIGlzIHNvcnQgb2YgYSBoYWNrLiAgdGhlcmUncyBhdCBsZWFzdCBvbmUgcGxhY2UgKGZvcm1hdHRpbmcKKyAgIGZsb2F0cykgd2hlcmUgc29tZSBzdHJpbmdsaWIgY29kZSB0YWtlcyBhIGRpZmZlcmVudCBwYXRoIGlmIGl0J3MKKyAgIGNvbXBpbGVkIGFzIHVuaWNvZGUuICovCisjZGVmaW5lIFNUUklOR0xJQl9JU19VTklDT0RFICAgICAxCisKKyNkZWZpbmUgU1RSSU5HTElCX09CSkVDVCAgICAgICAgIFB5VW5pY29kZU9iamVjdAorI2RlZmluZSBTVFJJTkdMSUJfQ0hBUiAgICAgICAgICAgUHlfVU5JQ09ERQorI2RlZmluZSBTVFJJTkdMSUJfVFlQRV9OQU1FICAgICAgInVuaWNvZGUiCisjZGVmaW5lIFNUUklOR0xJQl9QQVJTRV9DT0RFICAgICAiVSIKKyNkZWZpbmUgU1RSSU5HTElCX0VNUFRZICAgICAgICAgIHVuaWNvZGVfZW1wdHkKKyNkZWZpbmUgU1RSSU5HTElCX0lTU1BBQ0UgICAgICAgIFB5X1VOSUNPREVfSVNTUEFDRQorI2RlZmluZSBTVFJJTkdMSUJfSVNMSU5FQlJFQUsgICAgQkxPT01fTElORUJSRUFLCisjZGVmaW5lIFNUUklOR0xJQl9JU0RFQ0lNQUwgICAgICBQeV9VTklDT0RFX0lTREVDSU1BTAorI2RlZmluZSBTVFJJTkdMSUJfVE9ERUNJTUFMICAgICAgUHlfVU5JQ09ERV9UT0RFQ0lNQUwKKyNkZWZpbmUgU1RSSU5HTElCX1RPVVBQRVIgICAgICAgIFB5X1VOSUNPREVfVE9VUFBFUgorI2RlZmluZSBTVFJJTkdMSUJfVE9MT1dFUiAgICAgICAgUHlfVU5JQ09ERV9UT0xPV0VSCisjZGVmaW5lIFNUUklOR0xJQl9GSUxMICAgICAgICAgICBQeV9VTklDT0RFX0ZJTEwKKyNkZWZpbmUgU1RSSU5HTElCX1NUUiAgICAgICAgICAgIFB5VW5pY29kZV9BU19VTklDT0RFCisjZGVmaW5lIFNUUklOR0xJQl9MRU4gICAgICAgICAgICBQeVVuaWNvZGVfR0VUX1NJWkUKKyNkZWZpbmUgU1RSSU5HTElCX05FVyAgICAgICAgICAgIFB5VW5pY29kZV9Gcm9tVW5pY29kZQorI2RlZmluZSBTVFJJTkdMSUJfUkVTSVpFICAgICAgICAgUHlVbmljb2RlX1Jlc2l6ZQorI2RlZmluZSBTVFJJTkdMSUJfQ0hFQ0sgICAgICAgICAgUHlVbmljb2RlX0NoZWNrCisjZGVmaW5lIFNUUklOR0xJQl9DSEVDS19FWEFDVCAgICBQeVVuaWNvZGVfQ2hlY2tFeGFjdAorI2RlZmluZSBTVFJJTkdMSUJfR1JPVVBJTkcgICAgICAgX1B5VW5pY29kZV9JbnNlcnRUaG91c2FuZHNHcm91cGluZworCisjaWYgUFlfVkVSU0lPTl9IRVggPCAweDAzMDAwMDAwCisjZGVmaW5lIFNUUklOR0xJQl9UT1NUUiAgICAgICAgICBQeU9iamVjdF9Vbmljb2RlCisjZWxzZQorI2RlZmluZSBTVFJJTkdMSUJfVE9TVFIgICAgICAgICAgUHlPYmplY3RfU3RyCisjZW5kaWYKKworI2RlZmluZSBTVFJJTkdMSUJfV0FOVF9DT05UQUlOU19PQkogMQorCisjZW5kaWYgLyogIVNUUklOR0xJQl9VTklDT0RFREVGU19IICovCmRpZmYgLS1naXQgYS9QeXRob24tMi43LjUvT2JqZWN0cy9zdHJpbmdvYmplY3QuYyBiL1B5dGhvbi0yLjcuNS9PYmplY3RzL3N0cmluZ29iamVjdC5jCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjEyMDkxOTcKLS0tIC9kZXYvbnVsbAorKysgYi9QeXRob24tMi43LjUvT2JqZWN0cy9zdHJpbmdvYmplY3QuYwpAQCAtMCwwICsxLDQ4NDUgQEAKKy8qIFN0cmluZyAoc3RyL2J5dGVzKSBvYmplY3QgaW1wbGVtZW50YXRpb24gKi8KKworI2RlZmluZSBQWV9TU0laRV9UX0NMRUFOCisKKyNpbmNsdWRlICJQeXRob24uaCIKKyNpbmNsdWRlIDxjdHlwZS5oPgorI2luY2x1ZGUgPHN0ZGRlZi5oPgorCisjaWZkZWYgQ09VTlRfQUxMT0NTCitQeV9zc2l6ZV90IG51bGxfc3RyaW5ncywgb25lX3N0cmluZ3M7CisjZW5kaWYKKworc3RhdGljIFB5U3RyaW5nT2JqZWN0ICpjaGFyYWN0ZXJzW1VDSEFSX01BWCArIDFdOworc3RhdGljIFB5U3RyaW5nT2JqZWN0ICpudWxsc3RyaW5nOworCisvKiBUaGlzIGRpY3Rpb25hcnkgaG9sZHMgYWxsIGludGVybmVkIHN0cmluZ3MuICBOb3RlIHRoYXQgcmVmZXJlbmNlcyB0bworICAgc3RyaW5ncyBpbiB0aGlzIGRpY3Rpb25hcnkgYXJlICpub3QqIGNvdW50ZWQgaW4gdGhlIHN0cmluZydzIG9iX3JlZmNudC4KKyAgIFdoZW4gdGhlIGludGVybmVkIHN0cmluZyByZWFjaGVzIGEgcmVmY250IG9mIDAgdGhlIHN0cmluZyBkZWFsbG9jYXRpb24KKyAgIGZ1bmN0aW9uIHdpbGwgZGVsZXRlIHRoZSByZWZlcmVuY2UgZnJvbSB0aGlzIGRpY3Rpb25hcnkuCisKKyAgIEFub3RoZXIgd2F5IHRvIGxvb2sgYXQgdGhpcyBpcyB0aGF0IHRvIHNheSB0aGF0IHRoZSBhY3R1YWwgcmVmZXJlbmNlCisgICBjb3VudCBvZiBhIHN0cmluZyBpczogIHMtPm9iX3JlZmNudCArIChzLT5vYl9zc3RhdGU/MjowKQorKi8KK3N0YXRpYyBQeU9iamVjdCAqaW50ZXJuZWQ7CisKKy8qIFB5U3RyaW5nT2JqZWN0X1NJWkUgZ2l2ZXMgdGhlIGJhc2ljIHNpemUgb2YgYSBzdHJpbmc7IGFueSBtZW1vcnkgYWxsb2NhdGlvbgorICAgZm9yIGEgc3RyaW5nIG9mIGxlbmd0aCBuIHNob3VsZCByZXF1ZXN0IFB5U3RyaW5nT2JqZWN0X1NJWkUgKyBuIGJ5dGVzLgorCisgICBVc2luZyBQeVN0cmluZ09iamVjdF9TSVpFIGluc3RlYWQgb2Ygc2l6ZW9mKFB5U3RyaW5nT2JqZWN0KSBzYXZlcworICAgMyBieXRlcyBwZXIgc3RyaW5nIGFsbG9jYXRpb24gb24gYSB0eXBpY2FsIHN5c3RlbS4KKyovCisjZGVmaW5lIFB5U3RyaW5nT2JqZWN0X1NJWkUgKG9mZnNldG9mKFB5U3RyaW5nT2JqZWN0LCBvYl9zdmFsKSArIDEpCisKKy8qCisgICBGb3IgUHlTdHJpbmdfRnJvbVN0cmluZygpLCB0aGUgcGFyYW1ldGVyIGBzdHInIHBvaW50cyB0byBhIG51bGwtdGVybWluYXRlZAorICAgc3RyaW5nIGNvbnRhaW5pbmcgZXhhY3RseSBgc2l6ZScgYnl0ZXMuCisKKyAgIEZvciBQeVN0cmluZ19Gcm9tU3RyaW5nQW5kU2l6ZSgpLCB0aGUgcGFyYW1ldGVyIHRoZSBwYXJhbWV0ZXIgYHN0cicgaXMKKyAgIGVpdGhlciBOVUxMIG9yIGVsc2UgcG9pbnRzIHRvIGEgc3RyaW5nIGNvbnRhaW5pbmcgYXQgbGVhc3QgYHNpemUnIGJ5dGVzLgorICAgRm9yIFB5U3RyaW5nX0Zyb21TdHJpbmdBbmRTaXplKCksIHRoZSBzdHJpbmcgaW4gdGhlIGBzdHInIHBhcmFtZXRlciBkb2VzCisgICBub3QgaGF2ZSB0byBiZSBudWxsLXRlcm1pbmF0ZWQuICAoVGhlcmVmb3JlIGl0IGlzIHNhZmUgdG8gY29uc3RydWN0IGEKKyAgIHN1YnN0cmluZyBieSBjYWxsaW5nIGBQeVN0cmluZ19Gcm9tU3RyaW5nQW5kU2l6ZShvcmlnc3RyaW5nLCBzdWJzdHJsZW4pJy4pCisgICBJZiBgc3RyJyBpcyBOVUxMIHRoZW4gUHlTdHJpbmdfRnJvbVN0cmluZ0FuZFNpemUoKSB3aWxsIGFsbG9jYXRlIGBzaXplKzEnCisgICBieXRlcyAoc2V0dGluZyB0aGUgbGFzdCBieXRlIHRvIHRoZSBudWxsIHRlcm1pbmF0aW5nIGNoYXJhY3RlcikgYW5kIHlvdSBjYW4KKyAgIGZpbGwgaW4gdGhlIGRhdGEgeW91cnNlbGYuICBJZiBgc3RyJyBpcyBub24tTlVMTCB0aGVuIHRoZSByZXN1bHRpbmcKKyAgIFB5U3RyaW5nIG9iamVjdCBtdXN0IGJlIHRyZWF0ZWQgYXMgaW1tdXRhYmxlIGFuZCB5b3UgbXVzdCBub3QgZmlsbCBpbiBub3IKKyAgIGFsdGVyIHRoZSBkYXRhIHlvdXJzZWxmLCBzaW5jZSB0aGUgc3RyaW5ncyBtYXkgYmUgc2hhcmVkLgorCisgICBUaGUgUHlPYmplY3QgbWVtYmVyIGBvcC0+b2Jfc2l6ZScsIHdoaWNoIGRlbm90ZXMgdGhlIG51bWJlciBvZiAiZXh0cmEKKyAgIGl0ZW1zIiBpbiBhIHZhcmlhYmxlLXNpemUgb2JqZWN0LCB3aWxsIGNvbnRhaW4gdGhlIG51bWJlciBvZiBieXRlcworICAgYWxsb2NhdGVkIGZvciBzdHJpbmcgZGF0YSwgbm90IGNvdW50aW5nIHRoZSBudWxsIHRlcm1pbmF0aW5nIGNoYXJhY3Rlci4KKyAgIEl0IGlzIHRoZXJlZm9yZSBlcXVhbCB0byB0aGUgYHNpemUnIHBhcmFtZXRlciAoZm9yCisgICBQeVN0cmluZ19Gcm9tU3RyaW5nQW5kU2l6ZSgpKSBvciB0aGUgbGVuZ3RoIG9mIHRoZSBzdHJpbmcgaW4gdGhlIGBzdHInCisgICBwYXJhbWV0ZXIgKGZvciBQeVN0cmluZ19Gcm9tU3RyaW5nKCkpLgorKi8KK1B5T2JqZWN0ICoKK1B5U3RyaW5nX0Zyb21TdHJpbmdBbmRTaXplKGNvbnN0IGNoYXIgKnN0ciwgUHlfc3NpemVfdCBzaXplKQoreworICAgIHJlZ2lzdGVyIFB5U3RyaW5nT2JqZWN0ICpvcDsKKyAgICBpZiAoc2l6ZSA8IDApIHsKKyAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1N5c3RlbUVycm9yLAorICAgICAgICAgICAgIk5lZ2F0aXZlIHNpemUgcGFzc2VkIHRvIFB5U3RyaW5nX0Zyb21TdHJpbmdBbmRTaXplIik7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICBpZiAoc2l6ZSA9PSAwICYmIChvcCA9IG51bGxzdHJpbmcpICE9IE5VTEwpIHsKKyNpZmRlZiBDT1VOVF9BTExPQ1MKKyAgICAgICAgbnVsbF9zdHJpbmdzKys7CisjZW5kaWYKKyAgICAgICAgUHlfSU5DUkVGKG9wKTsKKyAgICAgICAgcmV0dXJuIChQeU9iamVjdCAqKW9wOworICAgIH0KKyAgICBpZiAoc2l6ZSA9PSAxICYmIHN0ciAhPSBOVUxMICYmCisgICAgICAgIChvcCA9IGNoYXJhY3RlcnNbKnN0ciAmIFVDSEFSX01BWF0pICE9IE5VTEwpCisgICAgeworI2lmZGVmIENPVU5UX0FMTE9DUworICAgICAgICBvbmVfc3RyaW5ncysrOworI2VuZGlmCisgICAgICAgIFB5X0lOQ1JFRihvcCk7CisgICAgICAgIHJldHVybiAoUHlPYmplY3QgKilvcDsKKyAgICB9CisKKyAgICBpZiAoc2l6ZSA+IFBZX1NTSVpFX1RfTUFYIC0gUHlTdHJpbmdPYmplY3RfU0laRSkgeworICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfT3ZlcmZsb3dFcnJvciwgInN0cmluZyBpcyB0b28gbGFyZ2UiKTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorCisgICAgLyogSW5saW5lIFB5T2JqZWN0X05ld1ZhciAqLworICAgIG9wID0gKFB5U3RyaW5nT2JqZWN0ICopUHlPYmplY3RfTUFMTE9DKFB5U3RyaW5nT2JqZWN0X1NJWkUgKyBzaXplKTsKKyAgICBpZiAob3AgPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIFB5RXJyX05vTWVtb3J5KCk7CisgICAgUHlPYmplY3RfSU5JVF9WQVIob3AsICZQeVN0cmluZ19UeXBlLCBzaXplKTsKKyAgICBvcC0+b2Jfc2hhc2ggPSAtMTsKKyAgICBvcC0+b2Jfc3N0YXRlID0gU1NUQVRFX05PVF9JTlRFUk5FRDsKKyAgICBpZiAoc3RyICE9IE5VTEwpCisgICAgICAgIFB5X01FTUNQWShvcC0+b2Jfc3ZhbCwgc3RyLCBzaXplKTsKKyAgICBvcC0+b2Jfc3ZhbFtzaXplXSA9ICdcMCc7CisgICAgLyogc2hhcmUgc2hvcnQgc3RyaW5ncyAqLworICAgIGlmIChzaXplID09IDApIHsKKyAgICAgICAgUHlPYmplY3QgKnQgPSAoUHlPYmplY3QgKilvcDsKKyAgICAgICAgUHlTdHJpbmdfSW50ZXJuSW5QbGFjZSgmdCk7CisgICAgICAgIG9wID0gKFB5U3RyaW5nT2JqZWN0ICopdDsKKyAgICAgICAgbnVsbHN0cmluZyA9IG9wOworICAgICAgICBQeV9JTkNSRUYob3ApOworICAgIH0gZWxzZSBpZiAoc2l6ZSA9PSAxICYmIHN0ciAhPSBOVUxMKSB7CisgICAgICAgIFB5T2JqZWN0ICp0ID0gKFB5T2JqZWN0ICopb3A7CisgICAgICAgIFB5U3RyaW5nX0ludGVybkluUGxhY2UoJnQpOworICAgICAgICBvcCA9IChQeVN0cmluZ09iamVjdCAqKXQ7CisgICAgICAgIGNoYXJhY3RlcnNbKnN0ciAmIFVDSEFSX01BWF0gPSBvcDsKKyAgICAgICAgUHlfSU5DUkVGKG9wKTsKKyAgICB9CisgICAgcmV0dXJuIChQeU9iamVjdCAqKSBvcDsKK30KKworUHlPYmplY3QgKgorUHlTdHJpbmdfRnJvbVN0cmluZyhjb25zdCBjaGFyICpzdHIpCit7CisgICAgcmVnaXN0ZXIgc2l6ZV90IHNpemU7CisgICAgcmVnaXN0ZXIgUHlTdHJpbmdPYmplY3QgKm9wOworCisgICAgYXNzZXJ0KHN0ciAhPSBOVUxMKTsKKyAgICBzaXplID0gc3RybGVuKHN0cik7CisgICAgaWYgKHNpemUgPiBQWV9TU0laRV9UX01BWCAtIFB5U3RyaW5nT2JqZWN0X1NJWkUpIHsKKyAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX092ZXJmbG93RXJyb3IsCisgICAgICAgICAgICAic3RyaW5nIGlzIHRvbyBsb25nIGZvciBhIFB5dGhvbiBzdHJpbmciKTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIGlmIChzaXplID09IDAgJiYgKG9wID0gbnVsbHN0cmluZykgIT0gTlVMTCkgeworI2lmZGVmIENPVU5UX0FMTE9DUworICAgICAgICBudWxsX3N0cmluZ3MrKzsKKyNlbmRpZgorICAgICAgICBQeV9JTkNSRUYob3ApOworICAgICAgICByZXR1cm4gKFB5T2JqZWN0ICopb3A7CisgICAgfQorICAgIGlmIChzaXplID09IDEgJiYgKG9wID0gY2hhcmFjdGVyc1sqc3RyICYgVUNIQVJfTUFYXSkgIT0gTlVMTCkgeworI2lmZGVmIENPVU5UX0FMTE9DUworICAgICAgICBvbmVfc3RyaW5ncysrOworI2VuZGlmCisgICAgICAgIFB5X0lOQ1JFRihvcCk7CisgICAgICAgIHJldHVybiAoUHlPYmplY3QgKilvcDsKKyAgICB9CisKKyAgICAvKiBJbmxpbmUgUHlPYmplY3RfTmV3VmFyICovCisgICAgb3AgPSAoUHlTdHJpbmdPYmplY3QgKilQeU9iamVjdF9NQUxMT0MoUHlTdHJpbmdPYmplY3RfU0laRSArIHNpemUpOworICAgIGlmIChvcCA9PSBOVUxMKQorICAgICAgICByZXR1cm4gUHlFcnJfTm9NZW1vcnkoKTsKKyAgICBQeU9iamVjdF9JTklUX1ZBUihvcCwgJlB5U3RyaW5nX1R5cGUsIHNpemUpOworICAgIG9wLT5vYl9zaGFzaCA9IC0xOworICAgIG9wLT5vYl9zc3RhdGUgPSBTU1RBVEVfTk9UX0lOVEVSTkVEOworICAgIFB5X01FTUNQWShvcC0+b2Jfc3ZhbCwgc3RyLCBzaXplKzEpOworICAgIC8qIHNoYXJlIHNob3J0IHN0cmluZ3MgKi8KKyAgICBpZiAoc2l6ZSA9PSAwKSB7CisgICAgICAgIFB5T2JqZWN0ICp0ID0gKFB5T2JqZWN0ICopb3A7CisgICAgICAgIFB5U3RyaW5nX0ludGVybkluUGxhY2UoJnQpOworICAgICAgICBvcCA9IChQeVN0cmluZ09iamVjdCAqKXQ7CisgICAgICAgIG51bGxzdHJpbmcgPSBvcDsKKyAgICAgICAgUHlfSU5DUkVGKG9wKTsKKyAgICB9IGVsc2UgaWYgKHNpemUgPT0gMSkgeworICAgICAgICBQeU9iamVjdCAqdCA9IChQeU9iamVjdCAqKW9wOworICAgICAgICBQeVN0cmluZ19JbnRlcm5JblBsYWNlKCZ0KTsKKyAgICAgICAgb3AgPSAoUHlTdHJpbmdPYmplY3QgKil0OworICAgICAgICBjaGFyYWN0ZXJzWypzdHIgJiBVQ0hBUl9NQVhdID0gb3A7CisgICAgICAgIFB5X0lOQ1JFRihvcCk7CisgICAgfQorICAgIHJldHVybiAoUHlPYmplY3QgKikgb3A7Cit9CisKK1B5T2JqZWN0ICoKK1B5U3RyaW5nX0Zyb21Gb3JtYXRWKGNvbnN0IGNoYXIgKmZvcm1hdCwgdmFfbGlzdCB2YXJncykKK3sKKyAgICB2YV9saXN0IGNvdW50OworICAgIFB5X3NzaXplX3QgbiA9IDA7CisgICAgY29uc3QgY2hhciogZjsKKyAgICBjaGFyICpzOworICAgIFB5T2JqZWN0KiBzdHJpbmc7CisKKyNpZmRlZiBWQV9MSVNUX0lTX0FSUkFZCisgICAgUHlfTUVNQ1BZKGNvdW50LCB2YXJncywgc2l6ZW9mKHZhX2xpc3QpKTsKKyNlbHNlCisjaWZkZWYgIF9fdmFfY29weQorICAgIF9fdmFfY29weShjb3VudCwgdmFyZ3MpOworI2Vsc2UKKyAgICBjb3VudCA9IHZhcmdzOworI2VuZGlmCisjZW5kaWYKKyAgICAvKiBzdGVwIDE6IGZpZ3VyZSBvdXQgaG93IGxhcmdlIGEgYnVmZmVyIHdlIG5lZWQgKi8KKyAgICBmb3IgKGYgPSBmb3JtYXQ7ICpmOyBmKyspIHsKKyAgICAgICAgaWYgKCpmID09ICclJykgeworI2lmZGVmIEhBVkVfTE9OR19MT05HCisgICAgICAgICAgICBpbnQgbG9uZ2xvbmdmbGFnID0gMDsKKyNlbmRpZgorICAgICAgICAgICAgY29uc3QgY2hhciogcCA9IGY7CisgICAgICAgICAgICB3aGlsZSAoKisrZiAmJiAqZiAhPSAnJScgJiYgIWlzYWxwaGEoUHlfQ0hBUk1BU0soKmYpKSkKKyAgICAgICAgICAgICAgICA7CisKKyAgICAgICAgICAgIC8qIHNraXAgdGhlICdsJyBvciAneicgaW4geyVsZCwgJXpkLCAlbHUsICV6dX0gc2luY2UKKyAgICAgICAgICAgICAqIHRoZXkgZG9uJ3QgYWZmZWN0IHRoZSBhbW91bnQgb2Ygc3BhY2Ugd2UgcmVzZXJ2ZS4KKyAgICAgICAgICAgICAqLworICAgICAgICAgICAgaWYgKCpmID09ICdsJykgeworICAgICAgICAgICAgICAgIGlmIChmWzFdID09ICdkJyB8fCBmWzFdID09ICd1JykgeworICAgICAgICAgICAgICAgICAgICArK2Y7CisgICAgICAgICAgICAgICAgfQorI2lmZGVmIEhBVkVfTE9OR19MT05HCisgICAgICAgICAgICAgICAgZWxzZSBpZiAoZlsxXSA9PSAnbCcgJiYKKyAgICAgICAgICAgICAgICAgICAgICAgICAoZlsyXSA9PSAnZCcgfHwgZlsyXSA9PSAndScpKSB7CisgICAgICAgICAgICAgICAgICAgIGxvbmdsb25nZmxhZyA9IDE7CisgICAgICAgICAgICAgICAgICAgIGYgKz0gMjsKKyAgICAgICAgICAgICAgICB9CisjZW5kaWYKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGVsc2UgaWYgKCpmID09ICd6JyAmJiAoZlsxXSA9PSAnZCcgfHwgZlsxXSA9PSAndScpKSB7CisgICAgICAgICAgICAgICAgKytmOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBzd2l0Y2ggKCpmKSB7CisgICAgICAgICAgICBjYXNlICdjJzoKKyAgICAgICAgICAgICAgICAodm9pZCl2YV9hcmcoY291bnQsIGludCk7CisgICAgICAgICAgICAgICAgLyogZmFsbCB0aHJvdWdoLi4uICovCisgICAgICAgICAgICBjYXNlICclJzoKKyAgICAgICAgICAgICAgICBuKys7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICBjYXNlICdkJzogY2FzZSAndSc6IGNhc2UgJ2knOiBjYXNlICd4JzoKKyAgICAgICAgICAgICAgICAodm9pZCkgdmFfYXJnKGNvdW50LCBpbnQpOworI2lmZGVmIEhBVkVfTE9OR19MT05HCisgICAgICAgICAgICAgICAgLyogTmVlZCBhdCBtb3N0CisgICAgICAgICAgICAgICAgICAgY2VpbChsb2cxMCgyNTYpKlNJWkVPRl9MT05HX0xPTkcpIGRpZ2l0cywKKyAgICAgICAgICAgICAgICAgICBwbHVzIDEgZm9yIHRoZSBzaWduLiAgNTMvMjIgaXMgYW4gdXBwZXIKKyAgICAgICAgICAgICAgICAgICBib3VuZCBmb3IgbG9nMTAoMjU2KS4gKi8KKyAgICAgICAgICAgICAgICBpZiAobG9uZ2xvbmdmbGFnKQorICAgICAgICAgICAgICAgICAgICBuICs9IDIgKyAoU0laRU9GX0xPTkdfTE9ORyo1My0xKSAvIDIyOworICAgICAgICAgICAgICAgIGVsc2UKKyNlbmRpZgorICAgICAgICAgICAgICAgICAgICAvKiAyMCBieXRlcyBpcyBlbm91Z2ggdG8gaG9sZCBhIDY0LWJpdAorICAgICAgICAgICAgICAgICAgICAgICBpbnRlZ2VyLiAgRGVjaW1hbCB0YWtlcyB0aGUgbW9zdAorICAgICAgICAgICAgICAgICAgICAgICBzcGFjZS4gIFRoaXMgaXNuJ3QgZW5vdWdoIGZvcgorICAgICAgICAgICAgICAgICAgICAgICBvY3RhbC4gKi8KKyAgICAgICAgICAgICAgICAgICAgbiArPSAyMDsKKworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgY2FzZSAncyc6CisgICAgICAgICAgICAgICAgcyA9IHZhX2FyZyhjb3VudCwgY2hhciopOworICAgICAgICAgICAgICAgIG4gKz0gc3RybGVuKHMpOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgY2FzZSAncCc6CisgICAgICAgICAgICAgICAgKHZvaWQpIHZhX2FyZyhjb3VudCwgaW50KTsKKyAgICAgICAgICAgICAgICAvKiBtYXhpbXVtIDY0LWJpdCBwb2ludGVyIHJlcHJlc2VudGF0aW9uOgorICAgICAgICAgICAgICAgICAqIDB4ZmZmZmZmZmZmZmZmZmZmZgorICAgICAgICAgICAgICAgICAqIHNvIDE5IGNoYXJhY3RlcnMgaXMgZW5vdWdoLgorICAgICAgICAgICAgICAgICAqIFhYWCBJIGNvdW50IDE4IC0tIHdoYXQncyB0aGUgZXh0cmEgZm9yPworICAgICAgICAgICAgICAgICAqLworICAgICAgICAgICAgICAgIG4gKz0gMTk7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICBkZWZhdWx0OgorICAgICAgICAgICAgICAgIC8qIGlmIHdlIHN0dW1ibGUgdXBvbiBhbiB1bmtub3duCisgICAgICAgICAgICAgICAgICAgZm9ybWF0dGluZyBjb2RlLCBjb3B5IHRoZSByZXN0IG9mCisgICAgICAgICAgICAgICAgICAgdGhlIGZvcm1hdCBzdHJpbmcgdG8gdGhlIG91dHB1dAorICAgICAgICAgICAgICAgICAgIHN0cmluZy4gKHdlIGNhbm5vdCBqdXN0IHNraXAgdGhlCisgICAgICAgICAgICAgICAgICAgY29kZSwgc2luY2UgdGhlcmUncyBubyB3YXkgdG8ga25vdworICAgICAgICAgICAgICAgICAgIHdoYXQncyBpbiB0aGUgYXJndW1lbnQgbGlzdCkgKi8KKyAgICAgICAgICAgICAgICBuICs9IHN0cmxlbihwKTsKKyAgICAgICAgICAgICAgICBnb3RvIGV4cGFuZDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlCisgICAgICAgICAgICBuKys7CisgICAgfQorIGV4cGFuZDoKKyAgICAvKiBzdGVwIDI6IGZpbGwgdGhlIGJ1ZmZlciAqLworICAgIC8qIFNpbmNlIHdlJ3ZlIGFuYWx5emVkIGhvdyBtdWNoIHNwYWNlIHdlIG5lZWQgZm9yIHRoZSB3b3JzdCBjYXNlLAorICAgICAgIHVzZSBzcHJpbnRmIGRpcmVjdGx5IGluc3RlYWQgb2YgdGhlIHNsb3dlciBQeU9TX3NucHJpbnRmLiAqLworICAgIHN0cmluZyA9IFB5U3RyaW5nX0Zyb21TdHJpbmdBbmRTaXplKE5VTEwsIG4pOworICAgIGlmICghc3RyaW5nKQorICAgICAgICByZXR1cm4gTlVMTDsKKworICAgIHMgPSBQeVN0cmluZ19Bc1N0cmluZyhzdHJpbmcpOworCisgICAgZm9yIChmID0gZm9ybWF0OyAqZjsgZisrKSB7CisgICAgICAgIGlmICgqZiA9PSAnJScpIHsKKyAgICAgICAgICAgIGNvbnN0IGNoYXIqIHAgPSBmKys7CisgICAgICAgICAgICBQeV9zc2l6ZV90IGk7CisgICAgICAgICAgICBpbnQgbG9uZ2ZsYWcgPSAwOworI2lmZGVmIEhBVkVfTE9OR19MT05HCisgICAgICAgICAgICBpbnQgbG9uZ2xvbmdmbGFnID0gMDsKKyNlbmRpZgorICAgICAgICAgICAgaW50IHNpemVfdGZsYWcgPSAwOworICAgICAgICAgICAgLyogcGFyc2UgdGhlIHdpZHRoLnByZWNpc2lvbiBwYXJ0ICh3ZSdyZSBvbmx5CisgICAgICAgICAgICAgICBpbnRlcmVzdGVkIGluIHRoZSBwcmVjaXNpb24gdmFsdWUsIGlmIGFueSkgKi8KKyAgICAgICAgICAgIG4gPSAwOworICAgICAgICAgICAgd2hpbGUgKGlzZGlnaXQoUHlfQ0hBUk1BU0soKmYpKSkKKyAgICAgICAgICAgICAgICBuID0gKG4qMTApICsgKmYrKyAtICcwJzsKKyAgICAgICAgICAgIGlmICgqZiA9PSAnLicpIHsKKyAgICAgICAgICAgICAgICBmKys7CisgICAgICAgICAgICAgICAgbiA9IDA7CisgICAgICAgICAgICAgICAgd2hpbGUgKGlzZGlnaXQoUHlfQ0hBUk1BU0soKmYpKSkKKyAgICAgICAgICAgICAgICAgICAgbiA9IChuKjEwKSArICpmKysgLSAnMCc7CisgICAgICAgICAgICB9CisgICAgICAgICAgICB3aGlsZSAoKmYgJiYgKmYgIT0gJyUnICYmICFpc2FscGhhKFB5X0NIQVJNQVNLKCpmKSkpCisgICAgICAgICAgICAgICAgZisrOworICAgICAgICAgICAgLyogSGFuZGxlICVsZCwgJWx1LCAlbGxkIGFuZCAlbGx1LiAqLworICAgICAgICAgICAgaWYgKCpmID09ICdsJykgeworICAgICAgICAgICAgICAgIGlmIChmWzFdID09ICdkJyB8fCBmWzFdID09ICd1JykgeworICAgICAgICAgICAgICAgICAgICBsb25nZmxhZyA9IDE7CisgICAgICAgICAgICAgICAgICAgICsrZjsKKyAgICAgICAgICAgICAgICB9CisjaWZkZWYgSEFWRV9MT05HX0xPTkcKKyAgICAgICAgICAgICAgICBlbHNlIGlmIChmWzFdID09ICdsJyAmJgorICAgICAgICAgICAgICAgICAgICAgICAgIChmWzJdID09ICdkJyB8fCBmWzJdID09ICd1JykpIHsKKyAgICAgICAgICAgICAgICAgICAgbG9uZ2xvbmdmbGFnID0gMTsKKyAgICAgICAgICAgICAgICAgICAgZiArPSAyOworICAgICAgICAgICAgICAgIH0KKyNlbmRpZgorICAgICAgICAgICAgfQorICAgICAgICAgICAgLyogaGFuZGxlIHRoZSBzaXplX3QgZmxhZy4gKi8KKyAgICAgICAgICAgIGVsc2UgaWYgKCpmID09ICd6JyAmJiAoZlsxXSA9PSAnZCcgfHwgZlsxXSA9PSAndScpKSB7CisgICAgICAgICAgICAgICAgc2l6ZV90ZmxhZyA9IDE7CisgICAgICAgICAgICAgICAgKytmOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICBzd2l0Y2ggKCpmKSB7CisgICAgICAgICAgICBjYXNlICdjJzoKKyAgICAgICAgICAgICAgICAqcysrID0gdmFfYXJnKHZhcmdzLCBpbnQpOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgY2FzZSAnZCc6CisgICAgICAgICAgICAgICAgaWYgKGxvbmdmbGFnKQorICAgICAgICAgICAgICAgICAgICBzcHJpbnRmKHMsICIlbGQiLCB2YV9hcmcodmFyZ3MsIGxvbmcpKTsKKyNpZmRlZiBIQVZFX0xPTkdfTE9ORworICAgICAgICAgICAgICAgIGVsc2UgaWYgKGxvbmdsb25nZmxhZykKKyAgICAgICAgICAgICAgICAgICAgc3ByaW50ZihzLCAiJSIgUFlfRk9STUFUX0xPTkdfTE9ORyAiZCIsCisgICAgICAgICAgICAgICAgICAgICAgICB2YV9hcmcodmFyZ3MsIFBZX0xPTkdfTE9ORykpOworI2VuZGlmCisgICAgICAgICAgICAgICAgZWxzZSBpZiAoc2l6ZV90ZmxhZykKKyAgICAgICAgICAgICAgICAgICAgc3ByaW50ZihzLCAiJSIgUFlfRk9STUFUX1NJWkVfVCAiZCIsCisgICAgICAgICAgICAgICAgICAgICAgICB2YV9hcmcodmFyZ3MsIFB5X3NzaXplX3QpKTsKKyAgICAgICAgICAgICAgICBlbHNlCisgICAgICAgICAgICAgICAgICAgIHNwcmludGYocywgIiVkIiwgdmFfYXJnKHZhcmdzLCBpbnQpKTsKKyAgICAgICAgICAgICAgICBzICs9IHN0cmxlbihzKTsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIGNhc2UgJ3UnOgorICAgICAgICAgICAgICAgIGlmIChsb25nZmxhZykKKyAgICAgICAgICAgICAgICAgICAgc3ByaW50ZihzLCAiJWx1IiwKKyAgICAgICAgICAgICAgICAgICAgICAgIHZhX2FyZyh2YXJncywgdW5zaWduZWQgbG9uZykpOworI2lmZGVmIEhBVkVfTE9OR19MT05HCisgICAgICAgICAgICAgICAgZWxzZSBpZiAobG9uZ2xvbmdmbGFnKQorICAgICAgICAgICAgICAgICAgICBzcHJpbnRmKHMsICIlIiBQWV9GT1JNQVRfTE9OR19MT05HICJ1IiwKKyAgICAgICAgICAgICAgICAgICAgICAgIHZhX2FyZyh2YXJncywgUFlfTE9OR19MT05HKSk7CisjZW5kaWYKKyAgICAgICAgICAgICAgICBlbHNlIGlmIChzaXplX3RmbGFnKQorICAgICAgICAgICAgICAgICAgICBzcHJpbnRmKHMsICIlIiBQWV9GT1JNQVRfU0laRV9UICJ1IiwKKyAgICAgICAgICAgICAgICAgICAgICAgIHZhX2FyZyh2YXJncywgc2l6ZV90KSk7CisgICAgICAgICAgICAgICAgZWxzZQorICAgICAgICAgICAgICAgICAgICBzcHJpbnRmKHMsICIldSIsCisgICAgICAgICAgICAgICAgICAgICAgICB2YV9hcmcodmFyZ3MsIHVuc2lnbmVkIGludCkpOworICAgICAgICAgICAgICAgIHMgKz0gc3RybGVuKHMpOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgY2FzZSAnaSc6CisgICAgICAgICAgICAgICAgc3ByaW50ZihzLCAiJWkiLCB2YV9hcmcodmFyZ3MsIGludCkpOworICAgICAgICAgICAgICAgIHMgKz0gc3RybGVuKHMpOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgY2FzZSAneCc6CisgICAgICAgICAgICAgICAgc3ByaW50ZihzLCAiJXgiLCB2YV9hcmcodmFyZ3MsIGludCkpOworICAgICAgICAgICAgICAgIHMgKz0gc3RybGVuKHMpOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgY2FzZSAncyc6CisgICAgICAgICAgICAgICAgcCA9IHZhX2FyZyh2YXJncywgY2hhciopOworICAgICAgICAgICAgICAgIGkgPSBzdHJsZW4ocCk7CisgICAgICAgICAgICAgICAgaWYgKG4gPiAwICYmIGkgPiBuKQorICAgICAgICAgICAgICAgICAgICBpID0gbjsKKyAgICAgICAgICAgICAgICBQeV9NRU1DUFkocywgcCwgaSk7CisgICAgICAgICAgICAgICAgcyArPSBpOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgY2FzZSAncCc6CisgICAgICAgICAgICAgICAgc3ByaW50ZihzLCAiJXAiLCB2YV9hcmcodmFyZ3MsIHZvaWQqKSk7CisgICAgICAgICAgICAgICAgLyogJXAgaXMgaWxsLWRlZmluZWQ6ICBlbnN1cmUgbGVhZGluZyAweC4gKi8KKyAgICAgICAgICAgICAgICBpZiAoc1sxXSA9PSAnWCcpCisgICAgICAgICAgICAgICAgICAgIHNbMV0gPSAneCc7CisgICAgICAgICAgICAgICAgZWxzZSBpZiAoc1sxXSAhPSAneCcpIHsKKyAgICAgICAgICAgICAgICAgICAgbWVtbW92ZShzKzIsIHMsIHN0cmxlbihzKSsxKTsKKyAgICAgICAgICAgICAgICAgICAgc1swXSA9ICcwJzsKKyAgICAgICAgICAgICAgICAgICAgc1sxXSA9ICd4JzsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgcyArPSBzdHJsZW4ocyk7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICBjYXNlICclJzoKKyAgICAgICAgICAgICAgICAqcysrID0gJyUnOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAgICAgICBzdHJjcHkocywgcCk7CisgICAgICAgICAgICAgICAgcyArPSBzdHJsZW4ocyk7CisgICAgICAgICAgICAgICAgZ290byBlbmQ7CisgICAgICAgICAgICB9CisgICAgICAgIH0gZWxzZQorICAgICAgICAgICAgKnMrKyA9ICpmOworICAgIH0KKworIGVuZDoKKyAgICBpZiAoX1B5U3RyaW5nX1Jlc2l6ZSgmc3RyaW5nLCBzIC0gUHlTdHJpbmdfQVNfU1RSSU5HKHN0cmluZykpKQorICAgICAgICByZXR1cm4gTlVMTDsKKyAgICByZXR1cm4gc3RyaW5nOworfQorCitQeU9iamVjdCAqCitQeVN0cmluZ19Gcm9tRm9ybWF0KGNvbnN0IGNoYXIgKmZvcm1hdCwgLi4uKQoreworICAgIFB5T2JqZWN0KiByZXQ7CisgICAgdmFfbGlzdCB2YXJnczsKKworI2lmZGVmIEhBVkVfU1REQVJHX1BST1RPVFlQRVMKKyAgICB2YV9zdGFydCh2YXJncywgZm9ybWF0KTsKKyNlbHNlCisgICAgdmFfc3RhcnQodmFyZ3MpOworI2VuZGlmCisgICAgcmV0ID0gUHlTdHJpbmdfRnJvbUZvcm1hdFYoZm9ybWF0LCB2YXJncyk7CisgICAgdmFfZW5kKHZhcmdzKTsKKyAgICByZXR1cm4gcmV0OworfQorCisKK1B5T2JqZWN0ICpQeVN0cmluZ19EZWNvZGUoY29uc3QgY2hhciAqcywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgUHlfc3NpemVfdCBzaXplLAorICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyICplbmNvZGluZywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciAqZXJyb3JzKQoreworICAgIFB5T2JqZWN0ICp2LCAqc3RyOworCisgICAgc3RyID0gUHlTdHJpbmdfRnJvbVN0cmluZ0FuZFNpemUocywgc2l6ZSk7CisgICAgaWYgKHN0ciA9PSBOVUxMKQorICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB2ID0gUHlTdHJpbmdfQXNEZWNvZGVkU3RyaW5nKHN0ciwgZW5jb2RpbmcsIGVycm9ycyk7CisgICAgUHlfREVDUkVGKHN0cik7CisgICAgcmV0dXJuIHY7Cit9CisKK1B5T2JqZWN0ICpQeVN0cmluZ19Bc0RlY29kZWRPYmplY3QoUHlPYmplY3QgKnN0ciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciAqZW5jb2RpbmcsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgKmVycm9ycykKK3sKKyAgICBQeU9iamVjdCAqdjsKKworICAgIGlmICghUHlTdHJpbmdfQ2hlY2soc3RyKSkgeworICAgICAgICBQeUVycl9CYWRBcmd1bWVudCgpOworICAgICAgICBnb3RvIG9uRXJyb3I7CisgICAgfQorCisgICAgaWYgKGVuY29kaW5nID09IE5VTEwpIHsKKyNpZmRlZiBQeV9VU0lOR19VTklDT0RFCisgICAgICAgIGVuY29kaW5nID0gUHlVbmljb2RlX0dldERlZmF1bHRFbmNvZGluZygpOworI2Vsc2UKKyAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1ZhbHVlRXJyb3IsICJubyBlbmNvZGluZyBzcGVjaWZpZWQiKTsKKyAgICAgICAgZ290byBvbkVycm9yOworI2VuZGlmCisgICAgfQorCisgICAgLyogRGVjb2RlIHZpYSB0aGUgY29kZWMgcmVnaXN0cnkgKi8KKyAgICB2ID0gUHlDb2RlY19EZWNvZGUoc3RyLCBlbmNvZGluZywgZXJyb3JzKTsKKyAgICBpZiAodiA9PSBOVUxMKQorICAgICAgICBnb3RvIG9uRXJyb3I7CisKKyAgICByZXR1cm4gdjsKKworIG9uRXJyb3I6CisgICAgcmV0dXJuIE5VTEw7Cit9CisKK1B5T2JqZWN0ICpQeVN0cmluZ19Bc0RlY29kZWRTdHJpbmcoUHlPYmplY3QgKnN0ciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciAqZW5jb2RpbmcsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgKmVycm9ycykKK3sKKyAgICBQeU9iamVjdCAqdjsKKworICAgIHYgPSBQeVN0cmluZ19Bc0RlY29kZWRPYmplY3Qoc3RyLCBlbmNvZGluZywgZXJyb3JzKTsKKyAgICBpZiAodiA9PSBOVUxMKQorICAgICAgICBnb3RvIG9uRXJyb3I7CisKKyNpZmRlZiBQeV9VU0lOR19VTklDT0RFCisgICAgLyogQ29udmVydCBVbmljb2RlIHRvIGEgc3RyaW5nIHVzaW5nIHRoZSBkZWZhdWx0IGVuY29kaW5nICovCisgICAgaWYgKFB5VW5pY29kZV9DaGVjayh2KSkgeworICAgICAgICBQeU9iamVjdCAqdGVtcCA9IHY7CisgICAgICAgIHYgPSBQeVVuaWNvZGVfQXNFbmNvZGVkU3RyaW5nKHYsIE5VTEwsIE5VTEwpOworICAgICAgICBQeV9ERUNSRUYodGVtcCk7CisgICAgICAgIGlmICh2ID09IE5VTEwpCisgICAgICAgICAgICBnb3RvIG9uRXJyb3I7CisgICAgfQorI2VuZGlmCisgICAgaWYgKCFQeVN0cmluZ19DaGVjayh2KSkgeworICAgICAgICBQeUVycl9Gb3JtYXQoUHlFeGNfVHlwZUVycm9yLAorICAgICAgICAgICAgICAgICAgICAgImRlY29kZXIgZGlkIG5vdCByZXR1cm4gYSBzdHJpbmcgb2JqZWN0ICh0eXBlPSUuNDAwcykiLAorICAgICAgICAgICAgICAgICAgICAgUHlfVFlQRSh2KS0+dHBfbmFtZSk7CisgICAgICAgIFB5X0RFQ1JFRih2KTsKKyAgICAgICAgZ290byBvbkVycm9yOworICAgIH0KKworICAgIHJldHVybiB2OworCisgb25FcnJvcjoKKyAgICByZXR1cm4gTlVMTDsKK30KKworUHlPYmplY3QgKlB5U3RyaW5nX0VuY29kZShjb25zdCBjaGFyICpzLAorICAgICAgICAgICAgICAgICAgICAgICAgICBQeV9zc2l6ZV90IHNpemUsCisgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgKmVuY29kaW5nLAorICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyICplcnJvcnMpCit7CisgICAgUHlPYmplY3QgKnYsICpzdHI7CisKKyAgICBzdHIgPSBQeVN0cmluZ19Gcm9tU3RyaW5nQW5kU2l6ZShzLCBzaXplKTsKKyAgICBpZiAoc3RyID09IE5VTEwpCisgICAgICAgIHJldHVybiBOVUxMOworICAgIHYgPSBQeVN0cmluZ19Bc0VuY29kZWRTdHJpbmcoc3RyLCBlbmNvZGluZywgZXJyb3JzKTsKKyAgICBQeV9ERUNSRUYoc3RyKTsKKyAgICByZXR1cm4gdjsKK30KKworUHlPYmplY3QgKlB5U3RyaW5nX0FzRW5jb2RlZE9iamVjdChQeU9iamVjdCAqc3RyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyICplbmNvZGluZywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciAqZXJyb3JzKQoreworICAgIFB5T2JqZWN0ICp2OworCisgICAgaWYgKCFQeVN0cmluZ19DaGVjayhzdHIpKSB7CisgICAgICAgIFB5RXJyX0JhZEFyZ3VtZW50KCk7CisgICAgICAgIGdvdG8gb25FcnJvcjsKKyAgICB9CisKKyAgICBpZiAoZW5jb2RpbmcgPT0gTlVMTCkgeworI2lmZGVmIFB5X1VTSU5HX1VOSUNPREUKKyAgICAgICAgZW5jb2RpbmcgPSBQeVVuaWNvZGVfR2V0RGVmYXVsdEVuY29kaW5nKCk7CisjZWxzZQorICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfVmFsdWVFcnJvciwgIm5vIGVuY29kaW5nIHNwZWNpZmllZCIpOworICAgICAgICBnb3RvIG9uRXJyb3I7CisjZW5kaWYKKyAgICB9CisKKyAgICAvKiBFbmNvZGUgdmlhIHRoZSBjb2RlYyByZWdpc3RyeSAqLworICAgIHYgPSBQeUNvZGVjX0VuY29kZShzdHIsIGVuY29kaW5nLCBlcnJvcnMpOworICAgIGlmICh2ID09IE5VTEwpCisgICAgICAgIGdvdG8gb25FcnJvcjsKKworICAgIHJldHVybiB2OworCisgb25FcnJvcjoKKyAgICByZXR1cm4gTlVMTDsKK30KKworUHlPYmplY3QgKlB5U3RyaW5nX0FzRW5jb2RlZFN0cmluZyhQeU9iamVjdCAqc3RyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyICplbmNvZGluZywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciAqZXJyb3JzKQoreworICAgIFB5T2JqZWN0ICp2OworCisgICAgdiA9IFB5U3RyaW5nX0FzRW5jb2RlZE9iamVjdChzdHIsIGVuY29kaW5nLCBlcnJvcnMpOworICAgIGlmICh2ID09IE5VTEwpCisgICAgICAgIGdvdG8gb25FcnJvcjsKKworI2lmZGVmIFB5X1VTSU5HX1VOSUNPREUKKyAgICAvKiBDb252ZXJ0IFVuaWNvZGUgdG8gYSBzdHJpbmcgdXNpbmcgdGhlIGRlZmF1bHQgZW5jb2RpbmcgKi8KKyAgICBpZiAoUHlVbmljb2RlX0NoZWNrKHYpKSB7CisgICAgICAgIFB5T2JqZWN0ICp0ZW1wID0gdjsKKyAgICAgICAgdiA9IFB5VW5pY29kZV9Bc0VuY29kZWRTdHJpbmcodiwgTlVMTCwgTlVMTCk7CisgICAgICAgIFB5X0RFQ1JFRih0ZW1wKTsKKyAgICAgICAgaWYgKHYgPT0gTlVMTCkKKyAgICAgICAgICAgIGdvdG8gb25FcnJvcjsKKyAgICB9CisjZW5kaWYKKyAgICBpZiAoIVB5U3RyaW5nX0NoZWNrKHYpKSB7CisgICAgICAgIFB5RXJyX0Zvcm1hdChQeUV4Y19UeXBlRXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAiZW5jb2RlciBkaWQgbm90IHJldHVybiBhIHN0cmluZyBvYmplY3QgKHR5cGU9JS40MDBzKSIsCisgICAgICAgICAgICAgICAgICAgICBQeV9UWVBFKHYpLT50cF9uYW1lKTsKKyAgICAgICAgUHlfREVDUkVGKHYpOworICAgICAgICBnb3RvIG9uRXJyb3I7CisgICAgfQorCisgICAgcmV0dXJuIHY7CisKKyBvbkVycm9yOgorICAgIHJldHVybiBOVUxMOworfQorCitzdGF0aWMgdm9pZAorc3RyaW5nX2RlYWxsb2MoUHlPYmplY3QgKm9wKQoreworICAgIHN3aXRjaCAoUHlTdHJpbmdfQ0hFQ0tfSU5URVJORUQob3ApKSB7CisgICAgICAgIGNhc2UgU1NUQVRFX05PVF9JTlRFUk5FRDoKKyAgICAgICAgICAgIGJyZWFrOworCisgICAgICAgIGNhc2UgU1NUQVRFX0lOVEVSTkVEX01PUlRBTDoKKyAgICAgICAgICAgIC8qIHJldml2ZSBkZWFkIG9iamVjdCB0ZW1wb3JhcmlseSBmb3IgRGVsSXRlbSAqLworICAgICAgICAgICAgUHlfUkVGQ05UKG9wKSA9IDM7CisgICAgICAgICAgICBpZiAoUHlEaWN0X0RlbEl0ZW0oaW50ZXJuZWQsIG9wKSAhPSAwKQorICAgICAgICAgICAgICAgIFB5X0ZhdGFsRXJyb3IoCisgICAgICAgICAgICAgICAgICAgICJkZWxldGlvbiBvZiBpbnRlcm5lZCBzdHJpbmcgZmFpbGVkIik7CisgICAgICAgICAgICBicmVhazsKKworICAgICAgICBjYXNlIFNTVEFURV9JTlRFUk5FRF9JTU1PUlRBTDoKKyAgICAgICAgICAgIFB5X0ZhdGFsRXJyb3IoIkltbW9ydGFsIGludGVybmVkIHN0cmluZyBkaWVkLiIpOworCisgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICBQeV9GYXRhbEVycm9yKCJJbmNvbnNpc3RlbnQgaW50ZXJuZWQgc3RyaW5nIHN0YXRlLiIpOworICAgIH0KKyAgICBQeV9UWVBFKG9wKS0+dHBfZnJlZShvcCk7Cit9CisKKy8qIFVuZXNjYXBlIGEgYmFja3NsYXNoLWVzY2FwZWQgc3RyaW5nLiBJZiB1bmljb2RlIGlzIG5vbi16ZXJvLAorICAgdGhlIHN0cmluZyBpcyBhIHUtbGl0ZXJhbC4gSWYgcmVjb2RlX2VuY29kaW5nIGlzIG5vbi16ZXJvLAorICAgdGhlIHN0cmluZyBpcyBVVEYtOCBlbmNvZGVkIGFuZCBzaG91bGQgYmUgcmUtZW5jb2RlZCBpbiB0aGUKKyAgIHNwZWNpZmllZCBlbmNvZGluZy4gICovCisKK1B5T2JqZWN0ICpQeVN0cmluZ19EZWNvZGVFc2NhcGUoY29uc3QgY2hhciAqcywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHlfc3NpemVfdCBsZW4sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgKmVycm9ycywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHlfc3NpemVfdCB1bmljb2RlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyICpyZWNvZGVfZW5jb2RpbmcpCit7CisgICAgaW50IGM7CisgICAgY2hhciAqcCwgKmJ1ZjsKKyAgICBjb25zdCBjaGFyICplbmQ7CisgICAgUHlPYmplY3QgKnY7CisgICAgUHlfc3NpemVfdCBuZXdsZW4gPSByZWNvZGVfZW5jb2RpbmcgPyA0KmxlbjpsZW47CisgICAgdiA9IFB5U3RyaW5nX0Zyb21TdHJpbmdBbmRTaXplKChjaGFyICopTlVMTCwgbmV3bGVuKTsKKyAgICBpZiAodiA9PSBOVUxMKQorICAgICAgICByZXR1cm4gTlVMTDsKKyAgICBwID0gYnVmID0gUHlTdHJpbmdfQXNTdHJpbmcodik7CisgICAgZW5kID0gcyArIGxlbjsKKyAgICB3aGlsZSAocyA8IGVuZCkgeworICAgICAgICBpZiAoKnMgIT0gJ1xcJykgeworICAgICAgICAgIG5vbl9lc2M6CisjaWZkZWYgUHlfVVNJTkdfVU5JQ09ERQorICAgICAgICAgICAgaWYgKHJlY29kZV9lbmNvZGluZyAmJiAoKnMgJiAweDgwKSkgeworICAgICAgICAgICAgICAgIFB5T2JqZWN0ICp1LCAqdzsKKyAgICAgICAgICAgICAgICBjaGFyICpyOworICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIqIHQ7CisgICAgICAgICAgICAgICAgUHlfc3NpemVfdCBybjsKKyAgICAgICAgICAgICAgICB0ID0gczsKKyAgICAgICAgICAgICAgICAvKiBEZWNvZGUgbm9uLUFTQ0lJIGJ5dGVzIGFzIFVURi04LiAqLworICAgICAgICAgICAgICAgIHdoaWxlICh0IDwgZW5kICYmICgqdCAmIDB4ODApKSB0Kys7CisgICAgICAgICAgICAgICAgdSA9IFB5VW5pY29kZV9EZWNvZGVVVEY4KHMsIHQgLSBzLCBlcnJvcnMpOworICAgICAgICAgICAgICAgIGlmKCF1KSBnb3RvIGZhaWxlZDsKKworICAgICAgICAgICAgICAgIC8qIFJlY29kZSB0aGVtIGluIHRhcmdldCBlbmNvZGluZy4gKi8KKyAgICAgICAgICAgICAgICB3ID0gUHlVbmljb2RlX0FzRW5jb2RlZFN0cmluZygKKyAgICAgICAgICAgICAgICAgICAgdSwgcmVjb2RlX2VuY29kaW5nLCBlcnJvcnMpOworICAgICAgICAgICAgICAgIFB5X0RFQ1JFRih1KTsKKyAgICAgICAgICAgICAgICBpZiAoIXcpICAgICAgICAgICAgICAgICBnb3RvIGZhaWxlZDsKKworICAgICAgICAgICAgICAgIC8qIEFwcGVuZCBieXRlcyB0byBvdXRwdXQgYnVmZmVyLiAqLworICAgICAgICAgICAgICAgIGFzc2VydChQeVN0cmluZ19DaGVjayh3KSk7CisgICAgICAgICAgICAgICAgciA9IFB5U3RyaW5nX0FTX1NUUklORyh3KTsKKyAgICAgICAgICAgICAgICBybiA9IFB5U3RyaW5nX0dFVF9TSVpFKHcpOworICAgICAgICAgICAgICAgIFB5X01FTUNQWShwLCByLCBybik7CisgICAgICAgICAgICAgICAgcCArPSBybjsKKyAgICAgICAgICAgICAgICBQeV9ERUNSRUYodyk7CisgICAgICAgICAgICAgICAgcyA9IHQ7CisgICAgICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgICAgICpwKysgPSAqcysrOworICAgICAgICAgICAgfQorI2Vsc2UKKyAgICAgICAgICAgICpwKysgPSAqcysrOworI2VuZGlmCisgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgfQorICAgICAgICBzKys7CisgICAgICAgIGlmIChzPT1lbmQpIHsKKyAgICAgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19WYWx1ZUVycm9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICJUcmFpbGluZyBcXCBpbiBzdHJpbmciKTsKKyAgICAgICAgICAgIGdvdG8gZmFpbGVkOworICAgICAgICB9CisgICAgICAgIHN3aXRjaCAoKnMrKykgeworICAgICAgICAvKiBYWFggVGhpcyBhc3N1bWVzIEFTQ0lJISAqLworICAgICAgICBjYXNlICdcbic6IGJyZWFrOworICAgICAgICBjYXNlICdcXCc6ICpwKysgPSAnXFwnOyBicmVhazsKKyAgICAgICAgY2FzZSAnXCcnOiAqcCsrID0gJ1wnJzsgYnJlYWs7CisgICAgICAgIGNhc2UgJ1wiJzogKnArKyA9ICdcIic7IGJyZWFrOworICAgICAgICBjYXNlICdiJzogKnArKyA9ICdcYic7IGJyZWFrOworICAgICAgICBjYXNlICdmJzogKnArKyA9ICdcMDE0JzsgYnJlYWs7IC8qIEZGICovCisgICAgICAgIGNhc2UgJ3QnOiAqcCsrID0gJ1x0JzsgYnJlYWs7CisgICAgICAgIGNhc2UgJ24nOiAqcCsrID0gJ1xuJzsgYnJlYWs7CisgICAgICAgIGNhc2UgJ3InOiAqcCsrID0gJ1xyJzsgYnJlYWs7CisgICAgICAgIGNhc2UgJ3YnOiAqcCsrID0gJ1wwMTMnOyBicmVhazsgLyogVlQgKi8KKyAgICAgICAgY2FzZSAnYSc6ICpwKysgPSAnXDAwNyc7IGJyZWFrOyAvKiBCRUwsIG5vdCBjbGFzc2ljIEMgKi8KKyAgICAgICAgY2FzZSAnMCc6IGNhc2UgJzEnOiBjYXNlICcyJzogY2FzZSAnMyc6CisgICAgICAgIGNhc2UgJzQnOiBjYXNlICc1JzogY2FzZSAnNic6IGNhc2UgJzcnOgorICAgICAgICAgICAgYyA9IHNbLTFdIC0gJzAnOworICAgICAgICAgICAgaWYgKHMgPCBlbmQgJiYgJzAnIDw9ICpzICYmICpzIDw9ICc3JykgeworICAgICAgICAgICAgICAgIGMgPSAoYzw8MykgKyAqcysrIC0gJzAnOworICAgICAgICAgICAgICAgIGlmIChzIDwgZW5kICYmICcwJyA8PSAqcyAmJiAqcyA8PSAnNycpCisgICAgICAgICAgICAgICAgICAgIGMgPSAoYzw8MykgKyAqcysrIC0gJzAnOworICAgICAgICAgICAgfQorICAgICAgICAgICAgKnArKyA9IGM7CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgY2FzZSAneCc6CisgICAgICAgICAgICBpZiAocysxIDwgZW5kICYmCisgICAgICAgICAgICAgICAgaXN4ZGlnaXQoUHlfQ0hBUk1BU0soc1swXSkpICYmCisgICAgICAgICAgICAgICAgaXN4ZGlnaXQoUHlfQ0hBUk1BU0soc1sxXSkpKQorICAgICAgICAgICAgeworICAgICAgICAgICAgICAgIHVuc2lnbmVkIGludCB4ID0gMDsKKyAgICAgICAgICAgICAgICBjID0gUHlfQ0hBUk1BU0soKnMpOworICAgICAgICAgICAgICAgIHMrKzsKKyAgICAgICAgICAgICAgICBpZiAoaXNkaWdpdChjKSkKKyAgICAgICAgICAgICAgICAgICAgeCA9IGMgLSAnMCc7CisgICAgICAgICAgICAgICAgZWxzZSBpZiAoaXNsb3dlcihjKSkKKyAgICAgICAgICAgICAgICAgICAgeCA9IDEwICsgYyAtICdhJzsKKyAgICAgICAgICAgICAgICBlbHNlCisgICAgICAgICAgICAgICAgICAgIHggPSAxMCArIGMgLSAnQSc7CisgICAgICAgICAgICAgICAgeCA9IHggPDwgNDsKKyAgICAgICAgICAgICAgICBjID0gUHlfQ0hBUk1BU0soKnMpOworICAgICAgICAgICAgICAgIHMrKzsKKyAgICAgICAgICAgICAgICBpZiAoaXNkaWdpdChjKSkKKyAgICAgICAgICAgICAgICAgICAgeCArPSBjIC0gJzAnOworICAgICAgICAgICAgICAgIGVsc2UgaWYgKGlzbG93ZXIoYykpCisgICAgICAgICAgICAgICAgICAgIHggKz0gMTAgKyBjIC0gJ2EnOworICAgICAgICAgICAgICAgIGVsc2UKKyAgICAgICAgICAgICAgICAgICAgeCArPSAxMCArIGMgLSAnQSc7CisgICAgICAgICAgICAgICAgKnArKyA9IHg7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoIWVycm9ycyB8fCBzdHJjbXAoZXJyb3JzLCAic3RyaWN0IikgPT0gMCkgeworICAgICAgICAgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19WYWx1ZUVycm9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiaW52YWxpZCBcXHggZXNjYXBlIik7CisgICAgICAgICAgICAgICAgZ290byBmYWlsZWQ7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoc3RyY21wKGVycm9ycywgInJlcGxhY2UiKSA9PSAwKSB7CisgICAgICAgICAgICAgICAgKnArKyA9ICc/JzsKKyAgICAgICAgICAgIH0gZWxzZSBpZiAoc3RyY21wKGVycm9ycywgImlnbm9yZSIpID09IDApCisgICAgICAgICAgICAgICAgLyogZG8gbm90aGluZyAqLzsKKyAgICAgICAgICAgIGVsc2UgeworICAgICAgICAgICAgICAgIFB5RXJyX0Zvcm1hdChQeUV4Y19WYWx1ZUVycm9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZGVjb2RpbmcgZXJyb3I7ICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInVua25vd24gZXJyb3IgaGFuZGxpbmcgY29kZTogJS40MDBzIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JzKTsKKyAgICAgICAgICAgICAgICBnb3RvIGZhaWxlZDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIC8qIHNraXAgXHggKi8KKyAgICAgICAgICAgIGlmIChzIDwgZW5kICYmIGlzeGRpZ2l0KFB5X0NIQVJNQVNLKHNbMF0pKSkKKyAgICAgICAgICAgICAgICBzKys7IC8qIGFuZCBhIGhleGRpZ2l0ICovCisgICAgICAgICAgICBicmVhazsKKyNpZm5kZWYgUHlfVVNJTkdfVU5JQ09ERQorICAgICAgICBjYXNlICd1JzoKKyAgICAgICAgY2FzZSAnVSc6CisgICAgICAgIGNhc2UgJ04nOgorICAgICAgICAgICAgaWYgKHVuaWNvZGUpIHsKKyAgICAgICAgICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfVmFsdWVFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIlVuaWNvZGUgZXNjYXBlcyBub3QgbGVnYWwgIgorICAgICAgICAgICAgICAgICAgICAgICAgICAid2hlbiBVbmljb2RlIGRpc2FibGVkIik7CisgICAgICAgICAgICAgICAgZ290byBmYWlsZWQ7CisgICAgICAgICAgICB9CisjZW5kaWYKKyAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAgICpwKysgPSAnXFwnOworICAgICAgICAgICAgcy0tOworICAgICAgICAgICAgZ290byBub25fZXNjOyAvKiBhbiBhcmJpdHJhcnkgbnVtYmVyIG9mIHVuZXNjYXBlZAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBVVEYtOCBieXRlcyBtYXkgZm9sbG93LiAqLworICAgICAgICB9CisgICAgfQorICAgIGlmIChwLWJ1ZiA8IG5ld2xlbiAmJiBfUHlTdHJpbmdfUmVzaXplKCZ2LCBwIC0gYnVmKSkKKyAgICAgICAgZ290byBmYWlsZWQ7CisgICAgcmV0dXJuIHY7CisgIGZhaWxlZDoKKyAgICBQeV9ERUNSRUYodik7CisgICAgcmV0dXJuIE5VTEw7Cit9CisKKy8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCisvKiBvYmplY3QgYXBpICovCisKK3N0YXRpYyBQeV9zc2l6ZV90CitzdHJpbmdfZ2V0c2l6ZShyZWdpc3RlciBQeU9iamVjdCAqb3ApCit7CisgICAgY2hhciAqczsKKyAgICBQeV9zc2l6ZV90IGxlbjsKKyAgICBpZiAoUHlTdHJpbmdfQXNTdHJpbmdBbmRTaXplKG9wLCAmcywgJmxlbikpCisgICAgICAgIHJldHVybiAtMTsKKyAgICByZXR1cm4gbGVuOworfQorCitzdGF0aWMgLypjb25zdCovIGNoYXIgKgorc3RyaW5nX2dldGJ1ZmZlcihyZWdpc3RlciBQeU9iamVjdCAqb3ApCit7CisgICAgY2hhciAqczsKKyAgICBQeV9zc2l6ZV90IGxlbjsKKyAgICBpZiAoUHlTdHJpbmdfQXNTdHJpbmdBbmRTaXplKG9wLCAmcywgJmxlbikpCisgICAgICAgIHJldHVybiBOVUxMOworICAgIHJldHVybiBzOworfQorCitQeV9zc2l6ZV90CitQeVN0cmluZ19TaXplKHJlZ2lzdGVyIFB5T2JqZWN0ICpvcCkKK3sKKyAgICBpZiAoIVB5U3RyaW5nX0NoZWNrKG9wKSkKKyAgICAgICAgcmV0dXJuIHN0cmluZ19nZXRzaXplKG9wKTsKKyAgICByZXR1cm4gUHlfU0laRShvcCk7Cit9CisKKy8qY29uc3QqLyBjaGFyICoKK1B5U3RyaW5nX0FzU3RyaW5nKHJlZ2lzdGVyIFB5T2JqZWN0ICpvcCkKK3sKKyAgICBpZiAoIVB5U3RyaW5nX0NoZWNrKG9wKSkKKyAgICAgICAgcmV0dXJuIHN0cmluZ19nZXRidWZmZXIob3ApOworICAgIHJldHVybiAoKFB5U3RyaW5nT2JqZWN0ICopb3ApIC0+IG9iX3N2YWw7Cit9CisKK2ludAorUHlTdHJpbmdfQXNTdHJpbmdBbmRTaXplKHJlZ2lzdGVyIFB5T2JqZWN0ICpvYmosCisgICAgICAgICAgICAgICAgICAgICAgICAgcmVnaXN0ZXIgY2hhciAqKnMsCisgICAgICAgICAgICAgICAgICAgICAgICAgcmVnaXN0ZXIgUHlfc3NpemVfdCAqbGVuKQoreworICAgIGlmIChzID09IE5VTEwpIHsKKyAgICAgICAgUHlFcnJfQmFkSW50ZXJuYWxDYWxsKCk7CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisKKyAgICBpZiAoIVB5U3RyaW5nX0NoZWNrKG9iaikpIHsKKyNpZmRlZiBQeV9VU0lOR19VTklDT0RFCisgICAgICAgIGlmIChQeVVuaWNvZGVfQ2hlY2sob2JqKSkgeworICAgICAgICAgICAgb2JqID0gX1B5VW5pY29kZV9Bc0RlZmF1bHRFbmNvZGVkU3RyaW5nKG9iaiwgTlVMTCk7CisgICAgICAgICAgICBpZiAob2JqID09IE5VTEwpCisgICAgICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICB9CisgICAgICAgIGVsc2UKKyNlbmRpZgorICAgICAgICB7CisgICAgICAgICAgICBQeUVycl9Gb3JtYXQoUHlFeGNfVHlwZUVycm9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICJleHBlY3RlZCBzdHJpbmcgb3IgVW5pY29kZSBvYmplY3QsICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAiJS4yMDBzIGZvdW5kIiwgUHlfVFlQRShvYmopLT50cF9uYW1lKTsKKyAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgfQorICAgIH0KKworICAgICpzID0gUHlTdHJpbmdfQVNfU1RSSU5HKG9iaik7CisgICAgaWYgKGxlbiAhPSBOVUxMKQorICAgICAgICAqbGVuID0gUHlTdHJpbmdfR0VUX1NJWkUob2JqKTsKKyAgICBlbHNlIGlmIChzdHJsZW4oKnMpICE9IChzaXplX3QpUHlTdHJpbmdfR0VUX1NJWkUob2JqKSkgeworICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfVHlwZUVycm9yLAorICAgICAgICAgICAgICAgICAgICAgICAgImV4cGVjdGVkIHN0cmluZyB3aXRob3V0IG51bGwgYnl0ZXMiKTsKKyAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKyAgICByZXR1cm4gMDsKK30KKworLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KKy8qIE1ldGhvZHMgKi8KKworI2luY2x1ZGUgInN0cmluZ2xpYi9zdHJpbmdkZWZzLmgiCisjaW5jbHVkZSAic3RyaW5nbGliL2Zhc3RzZWFyY2guaCIKKworI2luY2x1ZGUgInN0cmluZ2xpYi9jb3VudC5oIgorI2luY2x1ZGUgInN0cmluZ2xpYi9maW5kLmgiCisjaW5jbHVkZSAic3RyaW5nbGliL3BhcnRpdGlvbi5oIgorI2luY2x1ZGUgInN0cmluZ2xpYi9zcGxpdC5oIgorCisjZGVmaW5lIF9QeV9JbnNlcnRUaG91c2FuZHNHcm91cGluZyBfUHlTdHJpbmdfSW5zZXJ0VGhvdXNhbmRzR3JvdXBpbmcKKyNpbmNsdWRlICJzdHJpbmdsaWIvbG9jYWxldXRpbC5oIgorCisKKworc3RhdGljIGludAorc3RyaW5nX3ByaW50KFB5U3RyaW5nT2JqZWN0ICpvcCwgRklMRSAqZnAsIGludCBmbGFncykKK3sKKyAgICBQeV9zc2l6ZV90IGksIHN0cl9sZW47CisgICAgY2hhciBjOworICAgIGludCBxdW90ZTsKKworICAgIC8qIFhYWCBPdWdodCB0byBjaGVjayBmb3IgaW50ZXJydXB0cyB3aGVuIHdyaXRpbmcgbG9uZyBzdHJpbmdzICovCisgICAgaWYgKCEgUHlTdHJpbmdfQ2hlY2tFeGFjdChvcCkpIHsKKyAgICAgICAgaW50IHJldDsKKyAgICAgICAgLyogQSBzdHIgc3ViY2xhc3MgbWF5IGhhdmUgaXRzIG93biBfX3N0cl9fIG1ldGhvZC4gKi8KKyAgICAgICAgb3AgPSAoUHlTdHJpbmdPYmplY3QgKikgUHlPYmplY3RfU3RyKChQeU9iamVjdCAqKW9wKTsKKyAgICAgICAgaWYgKG9wID09IE5VTEwpCisgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgIHJldCA9IHN0cmluZ19wcmludChvcCwgZnAsIGZsYWdzKTsKKyAgICAgICAgUHlfREVDUkVGKG9wKTsKKyAgICAgICAgcmV0dXJuIHJldDsKKyAgICB9CisgICAgaWYgKGZsYWdzICYgUHlfUFJJTlRfUkFXKSB7CisgICAgICAgIGNoYXIgKmRhdGEgPSBvcC0+b2Jfc3ZhbDsKKyAgICAgICAgUHlfc3NpemVfdCBzaXplID0gUHlfU0laRShvcCk7CisgICAgICAgIFB5X0JFR0lOX0FMTE9XX1RIUkVBRFMKKyAgICAgICAgd2hpbGUgKHNpemUgPiBJTlRfTUFYKSB7CisgICAgICAgICAgICAvKiBWZXJ5IGxvbmcgc3RyaW5ncyBjYW5ub3QgYmUgd3JpdHRlbiBhdG9taWNhbGx5LgorICAgICAgICAgICAgICogQnV0IGRvbid0IHdyaXRlIGV4YWN0bHkgSU5UX01BWCBieXRlcyBhdCBhIHRpbWUKKyAgICAgICAgICAgICAqIHRvIGF2b2lkIG1lbW9yeSBhbGlnbWVudCBpc3N1ZXMuCisgICAgICAgICAgICAgKi8KKyAgICAgICAgICAgIGNvbnN0IGludCBjaHVua19zaXplID0gSU5UX01BWCAmIH4weDNGRkY7CisgICAgICAgICAgICBmd3JpdGUoZGF0YSwgMSwgY2h1bmtfc2l6ZSwgZnApOworICAgICAgICAgICAgZGF0YSArPSBjaHVua19zaXplOworICAgICAgICAgICAgc2l6ZSAtPSBjaHVua19zaXplOworICAgICAgICB9CisjaWZkZWYgX19WTVMKKyAgICAgICAgaWYgKHNpemUpIGZ3cml0ZShkYXRhLCAoaW50KXNpemUsIDEsIGZwKTsKKyNlbHNlCisgICAgICAgIGZ3cml0ZShkYXRhLCAxLCAoaW50KXNpemUsIGZwKTsKKyNlbmRpZgorICAgICAgICBQeV9FTkRfQUxMT1dfVEhSRUFEUworICAgICAgICByZXR1cm4gMDsKKyAgICB9CisKKyAgICAvKiBmaWd1cmUgb3V0IHdoaWNoIHF1b3RlIHRvIHVzZTsgc2luZ2xlIGlzIHByZWZlcnJlZCAqLworICAgIHF1b3RlID0gJ1wnJzsKKyAgICBpZiAobWVtY2hyKG9wLT5vYl9zdmFsLCAnXCcnLCBQeV9TSVpFKG9wKSkgJiYKKyAgICAgICAgIW1lbWNocihvcC0+b2Jfc3ZhbCwgJyInLCBQeV9TSVpFKG9wKSkpCisgICAgICAgIHF1b3RlID0gJyInOworCisgICAgc3RyX2xlbiA9IFB5X1NJWkUob3ApOworICAgIFB5X0JFR0lOX0FMTE9XX1RIUkVBRFMKKyAgICBmcHV0YyhxdW90ZSwgZnApOworICAgIGZvciAoaSA9IDA7IGkgPCBzdHJfbGVuOyBpKyspIHsKKyAgICAgICAgLyogU2luY2Ugc3RyaW5ncyBhcmUgaW1tdXRhYmxlIGFuZCB0aGUgY2FsbGVyIHNob3VsZCBoYXZlIGEKKyAgICAgICAgcmVmZXJlbmNlLCBhY2Nlc3NpbmcgdGhlIGludGVyYWwgYnVmZmVyIHNob3VsZCBub3QgYmUgYW4gaXNzdWUKKyAgICAgICAgd2l0aCB0aGUgR0lMIHJlbGVhc2VkLiAqLworICAgICAgICBjID0gb3AtPm9iX3N2YWxbaV07CisgICAgICAgIGlmIChjID09IHF1b3RlIHx8IGMgPT0gJ1xcJykKKyAgICAgICAgICAgIGZwcmludGYoZnAsICJcXCVjIiwgYyk7CisgICAgICAgIGVsc2UgaWYgKGMgPT0gJ1x0JykKKyAgICAgICAgICAgIGZwcmludGYoZnAsICJcXHQiKTsKKyAgICAgICAgZWxzZSBpZiAoYyA9PSAnXG4nKQorICAgICAgICAgICAgZnByaW50ZihmcCwgIlxcbiIpOworICAgICAgICBlbHNlIGlmIChjID09ICdccicpCisgICAgICAgICAgICBmcHJpbnRmKGZwLCAiXFxyIik7CisgICAgICAgIGVsc2UgaWYgKGMgPCAnICcgfHwgYyA+PSAweDdmKQorICAgICAgICAgICAgZnByaW50ZihmcCwgIlxceCUwMngiLCBjICYgMHhmZik7CisgICAgICAgIGVsc2UKKyAgICAgICAgICAgIGZwdXRjKGMsIGZwKTsKKyAgICB9CisgICAgZnB1dGMocXVvdGUsIGZwKTsKKyAgICBQeV9FTkRfQUxMT1dfVEhSRUFEUworICAgIHJldHVybiAwOworfQorCitQeU9iamVjdCAqCitQeVN0cmluZ19SZXByKFB5T2JqZWN0ICpvYmosIGludCBzbWFydHF1b3RlcykKK3sKKyAgICByZWdpc3RlciBQeVN0cmluZ09iamVjdCogb3AgPSAoUHlTdHJpbmdPYmplY3QqKSBvYmo7CisgICAgc2l6ZV90IG5ld3NpemUgPSAyICsgNCAqIFB5X1NJWkUob3ApOworICAgIFB5T2JqZWN0ICp2OworICAgIGlmIChuZXdzaXplID4gUFlfU1NJWkVfVF9NQVggfHwgbmV3c2l6ZSAvIDQgIT0gUHlfU0laRShvcCkpIHsKKyAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX092ZXJmbG93RXJyb3IsCisgICAgICAgICAgICAic3RyaW5nIGlzIHRvbyBsYXJnZSB0byBtYWtlIHJlcHIiKTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIHYgPSBQeVN0cmluZ19Gcm9tU3RyaW5nQW5kU2l6ZSgoY2hhciAqKU5VTEwsIG5ld3NpemUpOworICAgIGlmICh2ID09IE5VTEwpIHsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIGVsc2UgeworICAgICAgICByZWdpc3RlciBQeV9zc2l6ZV90IGk7CisgICAgICAgIHJlZ2lzdGVyIGNoYXIgYzsKKyAgICAgICAgcmVnaXN0ZXIgY2hhciAqcDsKKyAgICAgICAgaW50IHF1b3RlOworCisgICAgICAgIC8qIGZpZ3VyZSBvdXQgd2hpY2ggcXVvdGUgdG8gdXNlOyBzaW5nbGUgaXMgcHJlZmVycmVkICovCisgICAgICAgIHF1b3RlID0gJ1wnJzsKKyAgICAgICAgaWYgKHNtYXJ0cXVvdGVzICYmCisgICAgICAgICAgICBtZW1jaHIob3AtPm9iX3N2YWwsICdcJycsIFB5X1NJWkUob3ApKSAmJgorICAgICAgICAgICAgIW1lbWNocihvcC0+b2Jfc3ZhbCwgJyInLCBQeV9TSVpFKG9wKSkpCisgICAgICAgICAgICBxdW90ZSA9ICciJzsKKworICAgICAgICBwID0gUHlTdHJpbmdfQVNfU1RSSU5HKHYpOworICAgICAgICAqcCsrID0gcXVvdGU7CisgICAgICAgIGZvciAoaSA9IDA7IGkgPCBQeV9TSVpFKG9wKTsgaSsrKSB7CisgICAgICAgICAgICAvKiBUaGVyZSdzIGF0IGxlYXN0IGVub3VnaCByb29tIGZvciBhIGhleCBlc2NhcGUKKyAgICAgICAgICAgICAgIGFuZCBhIGNsb3NpbmcgcXVvdGUuICovCisgICAgICAgICAgICBhc3NlcnQobmV3c2l6ZSAtIChwIC0gUHlTdHJpbmdfQVNfU1RSSU5HKHYpKSA+PSA1KTsKKyAgICAgICAgICAgIGMgPSBvcC0+b2Jfc3ZhbFtpXTsKKyAgICAgICAgICAgIGlmIChjID09IHF1b3RlIHx8IGMgPT0gJ1xcJykKKyAgICAgICAgICAgICAgICAqcCsrID0gJ1xcJywgKnArKyA9IGM7CisgICAgICAgICAgICBlbHNlIGlmIChjID09ICdcdCcpCisgICAgICAgICAgICAgICAgKnArKyA9ICdcXCcsICpwKysgPSAndCc7CisgICAgICAgICAgICBlbHNlIGlmIChjID09ICdcbicpCisgICAgICAgICAgICAgICAgKnArKyA9ICdcXCcsICpwKysgPSAnbic7CisgICAgICAgICAgICBlbHNlIGlmIChjID09ICdccicpCisgICAgICAgICAgICAgICAgKnArKyA9ICdcXCcsICpwKysgPSAncic7CisgICAgICAgICAgICBlbHNlIGlmIChjIDwgJyAnIHx8IGMgPj0gMHg3ZikgeworICAgICAgICAgICAgICAgIC8qIEZvciBwZXJmb3JtYW5jZSwgd2UgZG9uJ3Qgd2FudCB0byBjYWxsCisgICAgICAgICAgICAgICAgICAgUHlPU19zbnByaW50ZiBoZXJlIChleHRyYSBsYXllcnMgb2YKKyAgICAgICAgICAgICAgICAgICBmdW5jdGlvbiBjYWxsKS4gKi8KKyAgICAgICAgICAgICAgICBzcHJpbnRmKHAsICJcXHglMDJ4IiwgYyAmIDB4ZmYpOworICAgICAgICAgICAgICAgIHAgKz0gNDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGVsc2UKKyAgICAgICAgICAgICAgICAqcCsrID0gYzsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnQobmV3c2l6ZSAtIChwIC0gUHlTdHJpbmdfQVNfU1RSSU5HKHYpKSA+PSAxKTsKKyAgICAgICAgKnArKyA9IHF1b3RlOworICAgICAgICAqcCA9ICdcMCc7CisgICAgICAgIGlmIChfUHlTdHJpbmdfUmVzaXplKCZ2LCAocCAtIFB5U3RyaW5nX0FTX1NUUklORyh2KSkpKQorICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgICAgIHJldHVybiB2OworICAgIH0KK30KKworc3RhdGljIFB5T2JqZWN0ICoKK3N0cmluZ19yZXByKFB5T2JqZWN0ICpvcCkKK3sKKyAgICByZXR1cm4gUHlTdHJpbmdfUmVwcihvcCwgMSk7Cit9CisKK3N0YXRpYyBQeU9iamVjdCAqCitzdHJpbmdfc3RyKFB5T2JqZWN0ICpzKQoreworICAgIGFzc2VydChQeVN0cmluZ19DaGVjayhzKSk7CisgICAgaWYgKFB5U3RyaW5nX0NoZWNrRXhhY3QocykpIHsKKyAgICAgICAgUHlfSU5DUkVGKHMpOworICAgICAgICByZXR1cm4gczsKKyAgICB9CisgICAgZWxzZSB7CisgICAgICAgIC8qIFN1YnR5cGUgLS0gcmV0dXJuIGdlbnVpbmUgc3RyaW5nIHdpdGggdGhlIHNhbWUgdmFsdWUuICovCisgICAgICAgIFB5U3RyaW5nT2JqZWN0ICp0ID0gKFB5U3RyaW5nT2JqZWN0ICopIHM7CisgICAgICAgIHJldHVybiBQeVN0cmluZ19Gcm9tU3RyaW5nQW5kU2l6ZSh0LT5vYl9zdmFsLCBQeV9TSVpFKHQpKTsKKyAgICB9Cit9CisKK3N0YXRpYyBQeV9zc2l6ZV90CitzdHJpbmdfbGVuZ3RoKFB5U3RyaW5nT2JqZWN0ICphKQoreworICAgIHJldHVybiBQeV9TSVpFKGEpOworfQorCitzdGF0aWMgUHlPYmplY3QgKgorc3RyaW5nX2NvbmNhdChyZWdpc3RlciBQeVN0cmluZ09iamVjdCAqYSwgcmVnaXN0ZXIgUHlPYmplY3QgKmJiKQoreworICAgIHJlZ2lzdGVyIFB5X3NzaXplX3Qgc2l6ZTsKKyAgICByZWdpc3RlciBQeVN0cmluZ09iamVjdCAqb3A7CisgICAgaWYgKCFQeVN0cmluZ19DaGVjayhiYikpIHsKKyNpZmRlZiBQeV9VU0lOR19VTklDT0RFCisgICAgICAgIGlmIChQeVVuaWNvZGVfQ2hlY2soYmIpKQorICAgICAgICAgICAgcmV0dXJuIFB5VW5pY29kZV9Db25jYXQoKFB5T2JqZWN0ICopYSwgYmIpOworI2VuZGlmCisgICAgICAgIGlmIChQeUJ5dGVBcnJheV9DaGVjayhiYikpCisgICAgICAgICAgICByZXR1cm4gUHlCeXRlQXJyYXlfQ29uY2F0KChQeU9iamVjdCAqKWEsIGJiKTsKKyAgICAgICAgUHlFcnJfRm9ybWF0KFB5RXhjX1R5cGVFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICJjYW5ub3QgY29uY2F0ZW5hdGUgJ3N0cicgYW5kICclLjIwMHMnIG9iamVjdHMiLAorICAgICAgICAgICAgICAgICAgICAgUHlfVFlQRShiYiktPnRwX25hbWUpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisjZGVmaW5lIGIgKChQeVN0cmluZ09iamVjdCAqKWJiKQorICAgIC8qIE9wdGltaXplIGNhc2VzIHdpdGggZW1wdHkgbGVmdCBvciByaWdodCBvcGVyYW5kICovCisgICAgaWYgKChQeV9TSVpFKGEpID09IDAgfHwgUHlfU0laRShiKSA9PSAwKSAmJgorICAgICAgICBQeVN0cmluZ19DaGVja0V4YWN0KGEpICYmIFB5U3RyaW5nX0NoZWNrRXhhY3QoYikpIHsKKyAgICAgICAgaWYgKFB5X1NJWkUoYSkgPT0gMCkgeworICAgICAgICAgICAgUHlfSU5DUkVGKGJiKTsKKyAgICAgICAgICAgIHJldHVybiBiYjsKKyAgICAgICAgfQorICAgICAgICBQeV9JTkNSRUYoYSk7CisgICAgICAgIHJldHVybiAoUHlPYmplY3QgKilhOworICAgIH0KKyAgICBzaXplID0gUHlfU0laRShhKSArIFB5X1NJWkUoYik7CisgICAgLyogQ2hlY2sgdGhhdCBzdHJpbmcgc2l6ZXMgYXJlIG5vdCBuZWdhdGl2ZSwgdG8gcHJldmVudCBhbgorICAgICAgIG92ZXJmbG93IGluIGNhc2VzIHdoZXJlIHdlIGFyZSBwYXNzZWQgaW5jb3JyZWN0bHktY3JlYXRlZAorICAgICAgIHN0cmluZ3Mgd2l0aCBuZWdhdGl2ZSBsZW5ndGhzIChkdWUgdG8gYSBidWcgaW4gb3RoZXIgY29kZSkuCisgICAgKi8KKyAgICBpZiAoUHlfU0laRShhKSA8IDAgfHwgUHlfU0laRShiKSA8IDAgfHwKKyAgICAgICAgUHlfU0laRShhKSA+IFBZX1NTSVpFX1RfTUFYIC0gUHlfU0laRShiKSkgeworICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfT3ZlcmZsb3dFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICJzdHJpbmdzIGFyZSB0b28gbGFyZ2UgdG8gY29uY2F0Iik7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKworICAgIC8qIElubGluZSBQeU9iamVjdF9OZXdWYXIgKi8KKyAgICBpZiAoc2l6ZSA+IFBZX1NTSVpFX1RfTUFYIC0gUHlTdHJpbmdPYmplY3RfU0laRSkgeworICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfT3ZlcmZsb3dFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICJzdHJpbmdzIGFyZSB0b28gbGFyZ2UgdG8gY29uY2F0Iik7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICBvcCA9IChQeVN0cmluZ09iamVjdCAqKVB5T2JqZWN0X01BTExPQyhQeVN0cmluZ09iamVjdF9TSVpFICsgc2l6ZSk7CisgICAgaWYgKG9wID09IE5VTEwpCisgICAgICAgIHJldHVybiBQeUVycl9Ob01lbW9yeSgpOworICAgIFB5T2JqZWN0X0lOSVRfVkFSKG9wLCAmUHlTdHJpbmdfVHlwZSwgc2l6ZSk7CisgICAgb3AtPm9iX3NoYXNoID0gLTE7CisgICAgb3AtPm9iX3NzdGF0ZSA9IFNTVEFURV9OT1RfSU5URVJORUQ7CisgICAgUHlfTUVNQ1BZKG9wLT5vYl9zdmFsLCBhLT5vYl9zdmFsLCBQeV9TSVpFKGEpKTsKKyAgICBQeV9NRU1DUFkob3AtPm9iX3N2YWwgKyBQeV9TSVpFKGEpLCBiLT5vYl9zdmFsLCBQeV9TSVpFKGIpKTsKKyAgICBvcC0+b2Jfc3ZhbFtzaXplXSA9ICdcMCc7CisgICAgcmV0dXJuIChQeU9iamVjdCAqKSBvcDsKKyN1bmRlZiBiCit9CisKK3N0YXRpYyBQeU9iamVjdCAqCitzdHJpbmdfcmVwZWF0KHJlZ2lzdGVyIFB5U3RyaW5nT2JqZWN0ICphLCByZWdpc3RlciBQeV9zc2l6ZV90IG4pCit7CisgICAgcmVnaXN0ZXIgUHlfc3NpemVfdCBpOworICAgIHJlZ2lzdGVyIFB5X3NzaXplX3QgajsKKyAgICByZWdpc3RlciBQeV9zc2l6ZV90IHNpemU7CisgICAgcmVnaXN0ZXIgUHlTdHJpbmdPYmplY3QgKm9wOworICAgIHNpemVfdCBuYnl0ZXM7CisgICAgaWYgKG4gPCAwKQorICAgICAgICBuID0gMDsKKyAgICAvKiB3YXRjaCBvdXQgZm9yIG92ZXJmbG93czogIHRoZSBzaXplIGNhbiBvdmVyZmxvdyBpbnQsCisgICAgICogYW5kIHRoZSAjIG9mIGJ5dGVzIG5lZWRlZCBjYW4gb3ZlcmZsb3cgc2l6ZV90CisgICAgICovCisgICAgc2l6ZSA9IFB5X1NJWkUoYSkgKiBuOworICAgIGlmIChuICYmIHNpemUgLyBuICE9IFB5X1NJWkUoYSkpIHsKKyAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX092ZXJmbG93RXJyb3IsCisgICAgICAgICAgICAicmVwZWF0ZWQgc3RyaW5nIGlzIHRvbyBsb25nIik7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICBpZiAoc2l6ZSA9PSBQeV9TSVpFKGEpICYmIFB5U3RyaW5nX0NoZWNrRXhhY3QoYSkpIHsKKyAgICAgICAgUHlfSU5DUkVGKGEpOworICAgICAgICByZXR1cm4gKFB5T2JqZWN0ICopYTsKKyAgICB9CisgICAgbmJ5dGVzID0gKHNpemVfdClzaXplOworICAgIGlmIChuYnl0ZXMgKyBQeVN0cmluZ09iamVjdF9TSVpFIDw9IG5ieXRlcykgeworICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfT3ZlcmZsb3dFcnJvciwKKyAgICAgICAgICAgICJyZXBlYXRlZCBzdHJpbmcgaXMgdG9vIGxvbmciKTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIG9wID0gKFB5U3RyaW5nT2JqZWN0ICopUHlPYmplY3RfTUFMTE9DKFB5U3RyaW5nT2JqZWN0X1NJWkUgKyBuYnl0ZXMpOworICAgIGlmIChvcCA9PSBOVUxMKQorICAgICAgICByZXR1cm4gUHlFcnJfTm9NZW1vcnkoKTsKKyAgICBQeU9iamVjdF9JTklUX1ZBUihvcCwgJlB5U3RyaW5nX1R5cGUsIHNpemUpOworICAgIG9wLT5vYl9zaGFzaCA9IC0xOworICAgIG9wLT5vYl9zc3RhdGUgPSBTU1RBVEVfTk9UX0lOVEVSTkVEOworICAgIG9wLT5vYl9zdmFsW3NpemVdID0gJ1wwJzsKKyAgICBpZiAoUHlfU0laRShhKSA9PSAxICYmIG4gPiAwKSB7CisgICAgICAgIG1lbXNldChvcC0+b2Jfc3ZhbCwgYS0+b2Jfc3ZhbFswXSAsIG4pOworICAgICAgICByZXR1cm4gKFB5T2JqZWN0ICopIG9wOworICAgIH0KKyAgICBpID0gMDsKKyAgICBpZiAoaSA8IHNpemUpIHsKKyAgICAgICAgUHlfTUVNQ1BZKG9wLT5vYl9zdmFsLCBhLT5vYl9zdmFsLCBQeV9TSVpFKGEpKTsKKyAgICAgICAgaSA9IFB5X1NJWkUoYSk7CisgICAgfQorICAgIHdoaWxlIChpIDwgc2l6ZSkgeworICAgICAgICBqID0gKGkgPD0gc2l6ZS1pKSAgPyAgaSAgOiAgc2l6ZS1pOworICAgICAgICBQeV9NRU1DUFkob3AtPm9iX3N2YWwraSwgb3AtPm9iX3N2YWwsIGopOworICAgICAgICBpICs9IGo7CisgICAgfQorICAgIHJldHVybiAoUHlPYmplY3QgKikgb3A7Cit9CisKKy8qIFN0cmluZyBzbGljZSBhW2k6al0gY29uc2lzdHMgb2YgY2hhcmFjdGVycyBhW2ldIC4uLiBhW2otMV0gKi8KKworc3RhdGljIFB5T2JqZWN0ICoKK3N0cmluZ19zbGljZShyZWdpc3RlciBQeVN0cmluZ09iamVjdCAqYSwgcmVnaXN0ZXIgUHlfc3NpemVfdCBpLAorICAgICAgICAgICAgIHJlZ2lzdGVyIFB5X3NzaXplX3QgaikKKyAgICAgLyogaiAtLSBtYXkgYmUgbmVnYXRpdmUhICovCit7CisgICAgaWYgKGkgPCAwKQorICAgICAgICBpID0gMDsKKyAgICBpZiAoaiA8IDApCisgICAgICAgIGogPSAwOyAvKiBBdm9pZCBzaWduZWQvdW5zaWduZWQgYnVnIGluIG5leHQgbGluZSAqLworICAgIGlmIChqID4gUHlfU0laRShhKSkKKyAgICAgICAgaiA9IFB5X1NJWkUoYSk7CisgICAgaWYgKGkgPT0gMCAmJiBqID09IFB5X1NJWkUoYSkgJiYgUHlTdHJpbmdfQ2hlY2tFeGFjdChhKSkgeworICAgICAgICAvKiBJdCdzIHRoZSBzYW1lIGFzIGEgKi8KKyAgICAgICAgUHlfSU5DUkVGKGEpOworICAgICAgICByZXR1cm4gKFB5T2JqZWN0ICopYTsKKyAgICB9CisgICAgaWYgKGogPCBpKQorICAgICAgICBqID0gaTsKKyAgICByZXR1cm4gUHlTdHJpbmdfRnJvbVN0cmluZ0FuZFNpemUoYS0+b2Jfc3ZhbCArIGksIGotaSk7Cit9CisKK3N0YXRpYyBpbnQKK3N0cmluZ19jb250YWlucyhQeU9iamVjdCAqc3RyX29iaiwgUHlPYmplY3QgKnN1Yl9vYmopCit7CisgICAgaWYgKCFQeVN0cmluZ19DaGVja0V4YWN0KHN1Yl9vYmopKSB7CisjaWZkZWYgUHlfVVNJTkdfVU5JQ09ERQorICAgICAgICBpZiAoUHlVbmljb2RlX0NoZWNrKHN1Yl9vYmopKQorICAgICAgICAgICAgcmV0dXJuIFB5VW5pY29kZV9Db250YWlucyhzdHJfb2JqLCBzdWJfb2JqKTsKKyNlbmRpZgorICAgICAgICBpZiAoIVB5U3RyaW5nX0NoZWNrKHN1Yl9vYmopKSB7CisgICAgICAgICAgICBQeUVycl9Gb3JtYXQoUHlFeGNfVHlwZUVycm9yLAorICAgICAgICAgICAgICAgICInaW4gPHN0cmluZz4nIHJlcXVpcmVzIHN0cmluZyBhcyBsZWZ0IG9wZXJhbmQsICIKKyAgICAgICAgICAgICAgICAibm90ICUuMjAwcyIsIFB5X1RZUEUoc3ViX29iaiktPnRwX25hbWUpOworICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICB9CisgICAgfQorCisgICAgcmV0dXJuIHN0cmluZ2xpYl9jb250YWluc19vYmooc3RyX29iaiwgc3ViX29iaik7Cit9CisKK3N0YXRpYyBQeU9iamVjdCAqCitzdHJpbmdfaXRlbShQeVN0cmluZ09iamVjdCAqYSwgcmVnaXN0ZXIgUHlfc3NpemVfdCBpKQoreworICAgIGNoYXIgcGNoYXI7CisgICAgUHlPYmplY3QgKnY7CisgICAgaWYgKGkgPCAwIHx8IGkgPj0gUHlfU0laRShhKSkgeworICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfSW5kZXhFcnJvciwgInN0cmluZyBpbmRleCBvdXQgb2YgcmFuZ2UiKTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIHBjaGFyID0gYS0+b2Jfc3ZhbFtpXTsKKyAgICB2ID0gKFB5T2JqZWN0ICopY2hhcmFjdGVyc1twY2hhciAmIFVDSEFSX01BWF07CisgICAgaWYgKHYgPT0gTlVMTCkKKyAgICAgICAgdiA9IFB5U3RyaW5nX0Zyb21TdHJpbmdBbmRTaXplKCZwY2hhciwgMSk7CisgICAgZWxzZSB7CisjaWZkZWYgQ09VTlRfQUxMT0NTCisgICAgICAgIG9uZV9zdHJpbmdzKys7CisjZW5kaWYKKyAgICAgICAgUHlfSU5DUkVGKHYpOworICAgIH0KKyAgICByZXR1cm4gdjsKK30KKworc3RhdGljIFB5T2JqZWN0Kgorc3RyaW5nX3JpY2hjb21wYXJlKFB5U3RyaW5nT2JqZWN0ICphLCBQeVN0cmluZ09iamVjdCAqYiwgaW50IG9wKQoreworICAgIGludCBjOworICAgIFB5X3NzaXplX3QgbGVuX2EsIGxlbl9iOworICAgIFB5X3NzaXplX3QgbWluX2xlbjsKKyAgICBQeU9iamVjdCAqcmVzdWx0OworCisgICAgLyogTWFrZSBzdXJlIGJvdGggYXJndW1lbnRzIGFyZSBzdHJpbmdzLiAqLworICAgIGlmICghKFB5U3RyaW5nX0NoZWNrKGEpICYmIFB5U3RyaW5nX0NoZWNrKGIpKSkgeworICAgICAgICByZXN1bHQgPSBQeV9Ob3RJbXBsZW1lbnRlZDsKKyAgICAgICAgZ290byBvdXQ7CisgICAgfQorICAgIGlmIChhID09IGIpIHsKKyAgICAgICAgc3dpdGNoIChvcCkgeworICAgICAgICBjYXNlIFB5X0VROmNhc2UgUHlfTEU6Y2FzZSBQeV9HRToKKyAgICAgICAgICAgIHJlc3VsdCA9IFB5X1RydWU7CisgICAgICAgICAgICBnb3RvIG91dDsKKyAgICAgICAgY2FzZSBQeV9ORTpjYXNlIFB5X0xUOmNhc2UgUHlfR1Q6CisgICAgICAgICAgICByZXN1bHQgPSBQeV9GYWxzZTsKKyAgICAgICAgICAgIGdvdG8gb3V0OworICAgICAgICB9CisgICAgfQorICAgIGlmIChvcCA9PSBQeV9FUSkgeworICAgICAgICAvKiBTdXBwb3J0aW5nIFB5X05FIGhlcmUgYXMgd2VsbCBkb2VzIG5vdCBzYXZlCisgICAgICAgICAgIG11Y2ggdGltZSwgc2luY2UgUHlfTkUgaXMgcmFyZWx5IHVzZWQuICAqLworICAgICAgICBpZiAoUHlfU0laRShhKSA9PSBQeV9TSVpFKGIpCisgICAgICAgICAgICAmJiAoYS0+b2Jfc3ZhbFswXSA9PSBiLT5vYl9zdmFsWzBdCisgICAgICAgICAgICAmJiBtZW1jbXAoYS0+b2Jfc3ZhbCwgYi0+b2Jfc3ZhbCwgUHlfU0laRShhKSkgPT0gMCkpIHsKKyAgICAgICAgICAgIHJlc3VsdCA9IFB5X1RydWU7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICByZXN1bHQgPSBQeV9GYWxzZTsKKyAgICAgICAgfQorICAgICAgICBnb3RvIG91dDsKKyAgICB9CisgICAgbGVuX2EgPSBQeV9TSVpFKGEpOyBsZW5fYiA9IFB5X1NJWkUoYik7CisgICAgbWluX2xlbiA9IChsZW5fYSA8IGxlbl9iKSA/IGxlbl9hIDogbGVuX2I7CisgICAgaWYgKG1pbl9sZW4gPiAwKSB7CisgICAgICAgIGMgPSBQeV9DSEFSTUFTSygqYS0+b2Jfc3ZhbCkgLSBQeV9DSEFSTUFTSygqYi0+b2Jfc3ZhbCk7CisgICAgICAgIGlmIChjPT0wKQorICAgICAgICAgICAgYyA9IG1lbWNtcChhLT5vYl9zdmFsLCBiLT5vYl9zdmFsLCBtaW5fbGVuKTsKKyAgICB9IGVsc2UKKyAgICAgICAgYyA9IDA7CisgICAgaWYgKGMgPT0gMCkKKyAgICAgICAgYyA9IChsZW5fYSA8IGxlbl9iKSA/IC0xIDogKGxlbl9hID4gbGVuX2IpID8gMSA6IDA7CisgICAgc3dpdGNoIChvcCkgeworICAgIGNhc2UgUHlfTFQ6IGMgPSBjIDwgIDA7IGJyZWFrOworICAgIGNhc2UgUHlfTEU6IGMgPSBjIDw9IDA7IGJyZWFrOworICAgIGNhc2UgUHlfRVE6IGFzc2VydCgwKTsgIGJyZWFrOyAvKiB1bnJlYWNoYWJsZSAqLworICAgIGNhc2UgUHlfTkU6IGMgPSBjICE9IDA7IGJyZWFrOworICAgIGNhc2UgUHlfR1Q6IGMgPSBjID4gIDA7IGJyZWFrOworICAgIGNhc2UgUHlfR0U6IGMgPSBjID49IDA7IGJyZWFrOworICAgIGRlZmF1bHQ6CisgICAgICAgIHJlc3VsdCA9IFB5X05vdEltcGxlbWVudGVkOworICAgICAgICBnb3RvIG91dDsKKyAgICB9CisgICAgcmVzdWx0ID0gYyA/IFB5X1RydWUgOiBQeV9GYWxzZTsKKyAgb3V0OgorICAgIFB5X0lOQ1JFRihyZXN1bHQpOworICAgIHJldHVybiByZXN1bHQ7Cit9CisKK2ludAorX1B5U3RyaW5nX0VxKFB5T2JqZWN0ICpvMSwgUHlPYmplY3QgKm8yKQoreworICAgIFB5U3RyaW5nT2JqZWN0ICphID0gKFB5U3RyaW5nT2JqZWN0KikgbzE7CisgICAgUHlTdHJpbmdPYmplY3QgKmIgPSAoUHlTdHJpbmdPYmplY3QqKSBvMjsKKyAgICByZXR1cm4gUHlfU0laRShhKSA9PSBQeV9TSVpFKGIpCisgICAgICAmJiAqYS0+b2Jfc3ZhbCA9PSAqYi0+b2Jfc3ZhbAorICAgICAgJiYgbWVtY21wKGEtPm9iX3N2YWwsIGItPm9iX3N2YWwsIFB5X1NJWkUoYSkpID09IDA7Cit9CisKK3N0YXRpYyBsb25nCitzdHJpbmdfaGFzaChQeVN0cmluZ09iamVjdCAqYSkKK3sKKyAgICByZWdpc3RlciBQeV9zc2l6ZV90IGxlbjsKKyAgICByZWdpc3RlciB1bnNpZ25lZCBjaGFyICpwOworICAgIHJlZ2lzdGVyIGxvbmcgeDsKKworI2lmZGVmIFB5X0RFQlVHCisgICAgYXNzZXJ0KF9QeV9IYXNoU2VjcmV0X0luaXRpYWxpemVkKTsKKyNlbmRpZgorICAgIGlmIChhLT5vYl9zaGFzaCAhPSAtMSkKKyAgICAgICAgcmV0dXJuIGEtPm9iX3NoYXNoOworICAgIGxlbiA9IFB5X1NJWkUoYSk7CisgICAgLyoKKyAgICAgIFdlIG1ha2UgdGhlIGhhc2ggb2YgdGhlIGVtcHR5IHN0cmluZyBiZSAwLCByYXRoZXIgdGhhbiB1c2luZworICAgICAgKHByZWZpeCBeIHN1ZmZpeCksIHNpbmNlIHRoaXMgc2xpZ2h0bHkgb2JmdXNjYXRlcyB0aGUgaGFzaCBzZWNyZXQKKyAgICAqLworICAgIGlmIChsZW4gPT0gMCkgeworICAgICAgICBhLT5vYl9zaGFzaCA9IDA7CisgICAgICAgIHJldHVybiAwOworICAgIH0KKyAgICBwID0gKHVuc2lnbmVkIGNoYXIgKikgYS0+b2Jfc3ZhbDsKKyAgICB4ID0gX1B5X0hhc2hTZWNyZXQucHJlZml4OworICAgIHggXj0gKnAgPDwgNzsKKyAgICB3aGlsZSAoLS1sZW4gPj0gMCkKKyAgICAgICAgeCA9ICgxMDAwMDAzKngpIF4gKnArKzsKKyAgICB4IF49IFB5X1NJWkUoYSk7CisgICAgeCBePSBfUHlfSGFzaFNlY3JldC5zdWZmaXg7CisgICAgaWYgKHggPT0gLTEpCisgICAgICAgIHggPSAtMjsKKyAgICBhLT5vYl9zaGFzaCA9IHg7CisgICAgcmV0dXJuIHg7Cit9CisKK3N0YXRpYyBQeU9iamVjdCoKK3N0cmluZ19zdWJzY3JpcHQoUHlTdHJpbmdPYmplY3QqIHNlbGYsIFB5T2JqZWN0KiBpdGVtKQoreworICAgIGlmIChQeUluZGV4X0NoZWNrKGl0ZW0pKSB7CisgICAgICAgIFB5X3NzaXplX3QgaSA9IFB5TnVtYmVyX0FzU3NpemVfdChpdGVtLCBQeUV4Y19JbmRleEVycm9yKTsKKyAgICAgICAgaWYgKGkgPT0gLTEgJiYgUHlFcnJfT2NjdXJyZWQoKSkKKyAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgICAgICBpZiAoaSA8IDApCisgICAgICAgICAgICBpICs9IFB5U3RyaW5nX0dFVF9TSVpFKHNlbGYpOworICAgICAgICByZXR1cm4gc3RyaW5nX2l0ZW0oc2VsZiwgaSk7CisgICAgfQorICAgIGVsc2UgaWYgKFB5U2xpY2VfQ2hlY2soaXRlbSkpIHsKKyAgICAgICAgUHlfc3NpemVfdCBzdGFydCwgc3RvcCwgc3RlcCwgc2xpY2VsZW5ndGgsIGN1ciwgaTsKKyAgICAgICAgY2hhciogc291cmNlX2J1ZjsKKyAgICAgICAgY2hhciogcmVzdWx0X2J1ZjsKKyAgICAgICAgUHlPYmplY3QqIHJlc3VsdDsKKworICAgICAgICBpZiAoUHlTbGljZV9HZXRJbmRpY2VzRXgoKFB5U2xpY2VPYmplY3QqKWl0ZW0sCisgICAgICAgICAgICAgICAgICAgICAgICAgUHlTdHJpbmdfR0VUX1NJWkUoc2VsZiksCisgICAgICAgICAgICAgICAgICAgICAgICAgJnN0YXJ0LCAmc3RvcCwgJnN0ZXAsICZzbGljZWxlbmd0aCkgPCAwKSB7CisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChzbGljZWxlbmd0aCA8PSAwKSB7CisgICAgICAgICAgICByZXR1cm4gUHlTdHJpbmdfRnJvbVN0cmluZ0FuZFNpemUoIiIsIDApOworICAgICAgICB9CisgICAgICAgIGVsc2UgaWYgKHN0YXJ0ID09IDAgJiYgc3RlcCA9PSAxICYmCisgICAgICAgICAgICAgICAgIHNsaWNlbGVuZ3RoID09IFB5U3RyaW5nX0dFVF9TSVpFKHNlbGYpICYmCisgICAgICAgICAgICAgICAgIFB5U3RyaW5nX0NoZWNrRXhhY3Qoc2VsZikpIHsKKyAgICAgICAgICAgIFB5X0lOQ1JFRihzZWxmKTsKKyAgICAgICAgICAgIHJldHVybiAoUHlPYmplY3QgKilzZWxmOworICAgICAgICB9CisgICAgICAgIGVsc2UgaWYgKHN0ZXAgPT0gMSkgeworICAgICAgICAgICAgcmV0dXJuIFB5U3RyaW5nX0Zyb21TdHJpbmdBbmRTaXplKAorICAgICAgICAgICAgICAgIFB5U3RyaW5nX0FTX1NUUklORyhzZWxmKSArIHN0YXJ0LAorICAgICAgICAgICAgICAgIHNsaWNlbGVuZ3RoKTsKKyAgICAgICAgfQorICAgICAgICBlbHNlIHsKKyAgICAgICAgICAgIHNvdXJjZV9idWYgPSBQeVN0cmluZ19Bc1N0cmluZygoUHlPYmplY3QqKXNlbGYpOworICAgICAgICAgICAgcmVzdWx0X2J1ZiA9IChjaGFyICopUHlNZW1fTWFsbG9jKHNsaWNlbGVuZ3RoKTsKKyAgICAgICAgICAgIGlmIChyZXN1bHRfYnVmID09IE5VTEwpCisgICAgICAgICAgICAgICAgcmV0dXJuIFB5RXJyX05vTWVtb3J5KCk7CisKKyAgICAgICAgICAgIGZvciAoY3VyID0gc3RhcnQsIGkgPSAwOyBpIDwgc2xpY2VsZW5ndGg7CisgICAgICAgICAgICAgICAgIGN1ciArPSBzdGVwLCBpKyspIHsKKyAgICAgICAgICAgICAgICByZXN1bHRfYnVmW2ldID0gc291cmNlX2J1ZltjdXJdOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICByZXN1bHQgPSBQeVN0cmluZ19Gcm9tU3RyaW5nQW5kU2l6ZShyZXN1bHRfYnVmLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2xpY2VsZW5ndGgpOworICAgICAgICAgICAgUHlNZW1fRnJlZShyZXN1bHRfYnVmKTsKKyAgICAgICAgICAgIHJldHVybiByZXN1bHQ7CisgICAgICAgIH0KKyAgICB9CisgICAgZWxzZSB7CisgICAgICAgIFB5RXJyX0Zvcm1hdChQeUV4Y19UeXBlRXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAic3RyaW5nIGluZGljZXMgbXVzdCBiZSBpbnRlZ2Vycywgbm90ICUuMjAwcyIsCisgICAgICAgICAgICAgICAgICAgICBQeV9UWVBFKGl0ZW0pLT50cF9uYW1lKTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorfQorCitzdGF0aWMgUHlfc3NpemVfdAorc3RyaW5nX2J1ZmZlcl9nZXRyZWFkYnVmKFB5U3RyaW5nT2JqZWN0ICpzZWxmLCBQeV9zc2l6ZV90IGluZGV4LCBjb25zdCB2b2lkICoqcHRyKQoreworICAgIGlmICggaW5kZXggIT0gMCApIHsKKyAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1N5c3RlbUVycm9yLAorICAgICAgICAgICAgICAgICAgICAgICAgImFjY2Vzc2luZyBub24tZXhpc3RlbnQgc3RyaW5nIHNlZ21lbnQiKTsKKyAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKyAgICAqcHRyID0gKHZvaWQgKilzZWxmLT5vYl9zdmFsOworICAgIHJldHVybiBQeV9TSVpFKHNlbGYpOworfQorCitzdGF0aWMgUHlfc3NpemVfdAorc3RyaW5nX2J1ZmZlcl9nZXR3cml0ZWJ1ZihQeVN0cmluZ09iamVjdCAqc2VsZiwgUHlfc3NpemVfdCBpbmRleCwgY29uc3Qgdm9pZCAqKnB0cikKK3sKKyAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfVHlwZUVycm9yLAorICAgICAgICAgICAgICAgICAgICAiQ2Fubm90IHVzZSBzdHJpbmcgYXMgbW9kaWZpYWJsZSBidWZmZXIiKTsKKyAgICByZXR1cm4gLTE7Cit9CisKK3N0YXRpYyBQeV9zc2l6ZV90CitzdHJpbmdfYnVmZmVyX2dldHNlZ2NvdW50KFB5U3RyaW5nT2JqZWN0ICpzZWxmLCBQeV9zc2l6ZV90ICpsZW5wKQoreworICAgIGlmICggbGVucCApCisgICAgICAgICpsZW5wID0gUHlfU0laRShzZWxmKTsKKyAgICByZXR1cm4gMTsKK30KKworc3RhdGljIFB5X3NzaXplX3QKK3N0cmluZ19idWZmZXJfZ2V0Y2hhcmJ1ZihQeVN0cmluZ09iamVjdCAqc2VsZiwgUHlfc3NpemVfdCBpbmRleCwgY29uc3QgY2hhciAqKnB0cikKK3sKKyAgICBpZiAoIGluZGV4ICE9IDAgKSB7CisgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19TeXN0ZW1FcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICJhY2Nlc3Npbmcgbm9uLWV4aXN0ZW50IHN0cmluZyBzZWdtZW50Iik7CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisgICAgKnB0ciA9IHNlbGYtPm9iX3N2YWw7CisgICAgcmV0dXJuIFB5X1NJWkUoc2VsZik7Cit9CisKK3N0YXRpYyBpbnQKK3N0cmluZ19idWZmZXJfZ2V0YnVmZmVyKFB5U3RyaW5nT2JqZWN0ICpzZWxmLCBQeV9idWZmZXIgKnZpZXcsIGludCBmbGFncykKK3sKKyAgICByZXR1cm4gUHlCdWZmZXJfRmlsbEluZm8odmlldywgKFB5T2JqZWN0KilzZWxmLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodm9pZCAqKXNlbGYtPm9iX3N2YWwsIFB5X1NJWkUoc2VsZiksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDEsIGZsYWdzKTsKK30KKworc3RhdGljIFB5U2VxdWVuY2VNZXRob2RzIHN0cmluZ19hc19zZXF1ZW5jZSA9IHsKKyAgICAobGVuZnVuYylzdHJpbmdfbGVuZ3RoLCAvKnNxX2xlbmd0aCovCisgICAgKGJpbmFyeWZ1bmMpc3RyaW5nX2NvbmNhdCwgLypzcV9jb25jYXQqLworICAgIChzc2l6ZWFyZ2Z1bmMpc3RyaW5nX3JlcGVhdCwgLypzcV9yZXBlYXQqLworICAgIChzc2l6ZWFyZ2Z1bmMpc3RyaW5nX2l0ZW0sIC8qc3FfaXRlbSovCisgICAgKHNzaXplc3NpemVhcmdmdW5jKXN0cmluZ19zbGljZSwgLypzcV9zbGljZSovCisgICAgMCwgICAgICAgICAgICAgICAgICAvKnNxX2Fzc19pdGVtKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgIC8qc3FfYXNzX3NsaWNlKi8KKyAgICAob2Jqb2JqcHJvYylzdHJpbmdfY29udGFpbnMgLypzcV9jb250YWlucyovCit9OworCitzdGF0aWMgUHlNYXBwaW5nTWV0aG9kcyBzdHJpbmdfYXNfbWFwcGluZyA9IHsKKyAgICAobGVuZnVuYylzdHJpbmdfbGVuZ3RoLAorICAgIChiaW5hcnlmdW5jKXN0cmluZ19zdWJzY3JpcHQsCisgICAgMCwKK307CisKK3N0YXRpYyBQeUJ1ZmZlclByb2NzIHN0cmluZ19hc19idWZmZXIgPSB7CisgICAgKHJlYWRidWZmZXJwcm9jKXN0cmluZ19idWZmZXJfZ2V0cmVhZGJ1ZiwKKyAgICAod3JpdGVidWZmZXJwcm9jKXN0cmluZ19idWZmZXJfZ2V0d3JpdGVidWYsCisgICAgKHNlZ2NvdW50cHJvYylzdHJpbmdfYnVmZmVyX2dldHNlZ2NvdW50LAorICAgIChjaGFyYnVmZmVycHJvYylzdHJpbmdfYnVmZmVyX2dldGNoYXJidWYsCisgICAgKGdldGJ1ZmZlcnByb2Mpc3RyaW5nX2J1ZmZlcl9nZXRidWZmZXIsCisgICAgMCwgLyogWFhYICovCit9OworCisKKworI2RlZmluZSBMRUZUU1RSSVAgMAorI2RlZmluZSBSSUdIVFNUUklQIDEKKyNkZWZpbmUgQk9USFNUUklQIDIKKworLyogQXJyYXlzIGluZGV4ZWQgYnkgYWJvdmUgKi8KK3N0YXRpYyBjb25zdCBjaGFyICpzdHJpcGZvcm1hdFtdID0geyJ8Tzpsc3RyaXAiLCAifE86cnN0cmlwIiwgInxPOnN0cmlwIn07CisKKyNkZWZpbmUgU1RSSVBOQU1FKGkpIChzdHJpcGZvcm1hdFtpXSszKQorCitQeURvY19TVFJWQVIoc3BsaXRfX2RvY19fLAorIlMuc3BsaXQoW3NlcCBbLG1heHNwbGl0XV0pIC0+IGxpc3Qgb2Ygc3RyaW5nc1xuXAorXG5cCitSZXR1cm4gYSBsaXN0IG9mIHRoZSB3b3JkcyBpbiB0aGUgc3RyaW5nIFMsIHVzaW5nIHNlcCBhcyB0aGVcblwKK2RlbGltaXRlciBzdHJpbmcuICBJZiBtYXhzcGxpdCBpcyBnaXZlbiwgYXQgbW9zdCBtYXhzcGxpdFxuXAorc3BsaXRzIGFyZSBkb25lLiBJZiBzZXAgaXMgbm90IHNwZWNpZmllZCBvciBpcyBOb25lLCBhbnlcblwKK3doaXRlc3BhY2Ugc3RyaW5nIGlzIGEgc2VwYXJhdG9yIGFuZCBlbXB0eSBzdHJpbmdzIGFyZSByZW1vdmVkXG5cCitmcm9tIHRoZSByZXN1bHQuIik7CisKK3N0YXRpYyBQeU9iamVjdCAqCitzdHJpbmdfc3BsaXQoUHlTdHJpbmdPYmplY3QgKnNlbGYsIFB5T2JqZWN0ICphcmdzKQoreworICAgIFB5X3NzaXplX3QgbGVuID0gUHlTdHJpbmdfR0VUX1NJWkUoc2VsZiksIG47CisgICAgUHlfc3NpemVfdCBtYXhzcGxpdCA9IC0xOworICAgIGNvbnN0IGNoYXIgKnMgPSBQeVN0cmluZ19BU19TVFJJTkcoc2VsZiksICpzdWI7CisgICAgUHlPYmplY3QgKnN1Ym9iaiA9IFB5X05vbmU7CisKKyAgICBpZiAoIVB5QXJnX1BhcnNlVHVwbGUoYXJncywgInxPbjpzcGxpdCIsICZzdWJvYmosICZtYXhzcGxpdCkpCisgICAgICAgIHJldHVybiBOVUxMOworICAgIGlmIChtYXhzcGxpdCA8IDApCisgICAgICAgIG1heHNwbGl0ID0gUFlfU1NJWkVfVF9NQVg7CisgICAgaWYgKHN1Ym9iaiA9PSBQeV9Ob25lKQorICAgICAgICByZXR1cm4gc3RyaW5nbGliX3NwbGl0X3doaXRlc3BhY2UoKFB5T2JqZWN0Kikgc2VsZiwgcywgbGVuLCBtYXhzcGxpdCk7CisgICAgaWYgKFB5U3RyaW5nX0NoZWNrKHN1Ym9iaikpIHsKKyAgICAgICAgc3ViID0gUHlTdHJpbmdfQVNfU1RSSU5HKHN1Ym9iaik7CisgICAgICAgIG4gPSBQeVN0cmluZ19HRVRfU0laRShzdWJvYmopOworICAgIH0KKyNpZmRlZiBQeV9VU0lOR19VTklDT0RFCisgICAgZWxzZSBpZiAoUHlVbmljb2RlX0NoZWNrKHN1Ym9iaikpCisgICAgICAgIHJldHVybiBQeVVuaWNvZGVfU3BsaXQoKFB5T2JqZWN0ICopc2VsZiwgc3Vib2JqLCBtYXhzcGxpdCk7CisjZW5kaWYKKyAgICBlbHNlIGlmIChQeU9iamVjdF9Bc0NoYXJCdWZmZXIoc3Vib2JqLCAmc3ViLCAmbikpCisgICAgICAgIHJldHVybiBOVUxMOworCisgICAgcmV0dXJuIHN0cmluZ2xpYl9zcGxpdCgoUHlPYmplY3QqKSBzZWxmLCBzLCBsZW4sIHN1YiwgbiwgbWF4c3BsaXQpOworfQorCitQeURvY19TVFJWQVIocGFydGl0aW9uX19kb2NfXywKKyJTLnBhcnRpdGlvbihzZXApIC0+IChoZWFkLCBzZXAsIHRhaWwpXG5cCitcblwKK1NlYXJjaCBmb3IgdGhlIHNlcGFyYXRvciBzZXAgaW4gUywgYW5kIHJldHVybiB0aGUgcGFydCBiZWZvcmUgaXQsXG5cCit0aGUgc2VwYXJhdG9yIGl0c2VsZiwgYW5kIHRoZSBwYXJ0IGFmdGVyIGl0LiAgSWYgdGhlIHNlcGFyYXRvciBpcyBub3RcblwKK2ZvdW5kLCByZXR1cm4gUyBhbmQgdHdvIGVtcHR5IHN0cmluZ3MuIik7CisKK3N0YXRpYyBQeU9iamVjdCAqCitzdHJpbmdfcGFydGl0aW9uKFB5U3RyaW5nT2JqZWN0ICpzZWxmLCBQeU9iamVjdCAqc2VwX29iaikKK3sKKyAgICBjb25zdCBjaGFyICpzZXA7CisgICAgUHlfc3NpemVfdCBzZXBfbGVuOworCisgICAgaWYgKFB5U3RyaW5nX0NoZWNrKHNlcF9vYmopKSB7CisgICAgICAgIHNlcCA9IFB5U3RyaW5nX0FTX1NUUklORyhzZXBfb2JqKTsKKyAgICAgICAgc2VwX2xlbiA9IFB5U3RyaW5nX0dFVF9TSVpFKHNlcF9vYmopOworICAgIH0KKyNpZmRlZiBQeV9VU0lOR19VTklDT0RFCisgICAgZWxzZSBpZiAoUHlVbmljb2RlX0NoZWNrKHNlcF9vYmopKQorICAgICAgICByZXR1cm4gUHlVbmljb2RlX1BhcnRpdGlvbigoUHlPYmplY3QgKikgc2VsZiwgc2VwX29iaik7CisjZW5kaWYKKyAgICBlbHNlIGlmIChQeU9iamVjdF9Bc0NoYXJCdWZmZXIoc2VwX29iaiwgJnNlcCwgJnNlcF9sZW4pKQorICAgICAgICByZXR1cm4gTlVMTDsKKworICAgIHJldHVybiBzdHJpbmdsaWJfcGFydGl0aW9uKAorICAgICAgICAoUHlPYmplY3QqKSBzZWxmLAorICAgICAgICBQeVN0cmluZ19BU19TVFJJTkcoc2VsZiksIFB5U3RyaW5nX0dFVF9TSVpFKHNlbGYpLAorICAgICAgICBzZXBfb2JqLCBzZXAsIHNlcF9sZW4KKyAgICAgICAgKTsKK30KKworUHlEb2NfU1RSVkFSKHJwYXJ0aXRpb25fX2RvY19fLAorIlMucnBhcnRpdGlvbihzZXApIC0+IChoZWFkLCBzZXAsIHRhaWwpXG5cCitcblwKK1NlYXJjaCBmb3IgdGhlIHNlcGFyYXRvciBzZXAgaW4gUywgc3RhcnRpbmcgYXQgdGhlIGVuZCBvZiBTLCBhbmQgcmV0dXJuXG5cCit0aGUgcGFydCBiZWZvcmUgaXQsIHRoZSBzZXBhcmF0b3IgaXRzZWxmLCBhbmQgdGhlIHBhcnQgYWZ0ZXIgaXQuICBJZiB0aGVcblwKK3NlcGFyYXRvciBpcyBub3QgZm91bmQsIHJldHVybiB0d28gZW1wdHkgc3RyaW5ncyBhbmQgUy4iKTsKKworc3RhdGljIFB5T2JqZWN0ICoKK3N0cmluZ19ycGFydGl0aW9uKFB5U3RyaW5nT2JqZWN0ICpzZWxmLCBQeU9iamVjdCAqc2VwX29iaikKK3sKKyAgICBjb25zdCBjaGFyICpzZXA7CisgICAgUHlfc3NpemVfdCBzZXBfbGVuOworCisgICAgaWYgKFB5U3RyaW5nX0NoZWNrKHNlcF9vYmopKSB7CisgICAgICAgIHNlcCA9IFB5U3RyaW5nX0FTX1NUUklORyhzZXBfb2JqKTsKKyAgICAgICAgc2VwX2xlbiA9IFB5U3RyaW5nX0dFVF9TSVpFKHNlcF9vYmopOworICAgIH0KKyNpZmRlZiBQeV9VU0lOR19VTklDT0RFCisgICAgZWxzZSBpZiAoUHlVbmljb2RlX0NoZWNrKHNlcF9vYmopKQorICAgICAgICByZXR1cm4gUHlVbmljb2RlX1JQYXJ0aXRpb24oKFB5T2JqZWN0ICopIHNlbGYsIHNlcF9vYmopOworI2VuZGlmCisgICAgZWxzZSBpZiAoUHlPYmplY3RfQXNDaGFyQnVmZmVyKHNlcF9vYmosICZzZXAsICZzZXBfbGVuKSkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisKKyAgICByZXR1cm4gc3RyaW5nbGliX3JwYXJ0aXRpb24oCisgICAgICAgIChQeU9iamVjdCopIHNlbGYsCisgICAgICAgIFB5U3RyaW5nX0FTX1NUUklORyhzZWxmKSwgUHlTdHJpbmdfR0VUX1NJWkUoc2VsZiksCisgICAgICAgIHNlcF9vYmosIHNlcCwgc2VwX2xlbgorICAgICAgICApOworfQorCitQeURvY19TVFJWQVIocnNwbGl0X19kb2NfXywKKyJTLnJzcGxpdChbc2VwIFssbWF4c3BsaXRdXSkgLT4gbGlzdCBvZiBzdHJpbmdzXG5cCitcblwKK1JldHVybiBhIGxpc3Qgb2YgdGhlIHdvcmRzIGluIHRoZSBzdHJpbmcgUywgdXNpbmcgc2VwIGFzIHRoZVxuXAorZGVsaW1pdGVyIHN0cmluZywgc3RhcnRpbmcgYXQgdGhlIGVuZCBvZiB0aGUgc3RyaW5nIGFuZCB3b3JraW5nXG5cCit0byB0aGUgZnJvbnQuICBJZiBtYXhzcGxpdCBpcyBnaXZlbiwgYXQgbW9zdCBtYXhzcGxpdCBzcGxpdHMgYXJlXG5cCitkb25lLiBJZiBzZXAgaXMgbm90IHNwZWNpZmllZCBvciBpcyBOb25lLCBhbnkgd2hpdGVzcGFjZSBzdHJpbmdcblwKK2lzIGEgc2VwYXJhdG9yLiIpOworCitzdGF0aWMgUHlPYmplY3QgKgorc3RyaW5nX3JzcGxpdChQeVN0cmluZ09iamVjdCAqc2VsZiwgUHlPYmplY3QgKmFyZ3MpCit7CisgICAgUHlfc3NpemVfdCBsZW4gPSBQeVN0cmluZ19HRVRfU0laRShzZWxmKSwgbjsKKyAgICBQeV9zc2l6ZV90IG1heHNwbGl0ID0gLTE7CisgICAgY29uc3QgY2hhciAqcyA9IFB5U3RyaW5nX0FTX1NUUklORyhzZWxmKSwgKnN1YjsKKyAgICBQeU9iamVjdCAqc3Vib2JqID0gUHlfTm9uZTsKKworICAgIGlmICghUHlBcmdfUGFyc2VUdXBsZShhcmdzLCAifE9uOnJzcGxpdCIsICZzdWJvYmosICZtYXhzcGxpdCkpCisgICAgICAgIHJldHVybiBOVUxMOworICAgIGlmIChtYXhzcGxpdCA8IDApCisgICAgICAgIG1heHNwbGl0ID0gUFlfU1NJWkVfVF9NQVg7CisgICAgaWYgKHN1Ym9iaiA9PSBQeV9Ob25lKQorICAgICAgICByZXR1cm4gc3RyaW5nbGliX3JzcGxpdF93aGl0ZXNwYWNlKChQeU9iamVjdCopIHNlbGYsIHMsIGxlbiwgbWF4c3BsaXQpOworICAgIGlmIChQeVN0cmluZ19DaGVjayhzdWJvYmopKSB7CisgICAgICAgIHN1YiA9IFB5U3RyaW5nX0FTX1NUUklORyhzdWJvYmopOworICAgICAgICBuID0gUHlTdHJpbmdfR0VUX1NJWkUoc3Vib2JqKTsKKyAgICB9CisjaWZkZWYgUHlfVVNJTkdfVU5JQ09ERQorICAgIGVsc2UgaWYgKFB5VW5pY29kZV9DaGVjayhzdWJvYmopKQorICAgICAgICByZXR1cm4gUHlVbmljb2RlX1JTcGxpdCgoUHlPYmplY3QgKilzZWxmLCBzdWJvYmosIG1heHNwbGl0KTsKKyNlbmRpZgorICAgIGVsc2UgaWYgKFB5T2JqZWN0X0FzQ2hhckJ1ZmZlcihzdWJvYmosICZzdWIsICZuKSkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisKKyAgICByZXR1cm4gc3RyaW5nbGliX3JzcGxpdCgoUHlPYmplY3QqKSBzZWxmLCBzLCBsZW4sIHN1YiwgbiwgbWF4c3BsaXQpOworfQorCisKK1B5RG9jX1NUUlZBUihqb2luX19kb2NfXywKKyJTLmpvaW4oaXRlcmFibGUpIC0+IHN0cmluZ1xuXAorXG5cCitSZXR1cm4gYSBzdHJpbmcgd2hpY2ggaXMgdGhlIGNvbmNhdGVuYXRpb24gb2YgdGhlIHN0cmluZ3MgaW4gdGhlXG5cCitpdGVyYWJsZS4gIFRoZSBzZXBhcmF0b3IgYmV0d2VlbiBlbGVtZW50cyBpcyBTLiIpOworCitzdGF0aWMgUHlPYmplY3QgKgorc3RyaW5nX2pvaW4oUHlTdHJpbmdPYmplY3QgKnNlbGYsIFB5T2JqZWN0ICpvcmlnKQoreworICAgIGNoYXIgKnNlcCA9IFB5U3RyaW5nX0FTX1NUUklORyhzZWxmKTsKKyAgICBjb25zdCBQeV9zc2l6ZV90IHNlcGxlbiA9IFB5U3RyaW5nX0dFVF9TSVpFKHNlbGYpOworICAgIFB5T2JqZWN0ICpyZXMgPSBOVUxMOworICAgIGNoYXIgKnA7CisgICAgUHlfc3NpemVfdCBzZXFsZW4gPSAwOworICAgIHNpemVfdCBzeiA9IDA7CisgICAgUHlfc3NpemVfdCBpOworICAgIFB5T2JqZWN0ICpzZXEsICppdGVtOworCisgICAgc2VxID0gUHlTZXF1ZW5jZV9GYXN0KG9yaWcsICIiKTsKKyAgICBpZiAoc2VxID09IE5VTEwpIHsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorCisgICAgc2VxbGVuID0gUHlTZXF1ZW5jZV9TaXplKHNlcSk7CisgICAgaWYgKHNlcWxlbiA9PSAwKSB7CisgICAgICAgIFB5X0RFQ1JFRihzZXEpOworICAgICAgICByZXR1cm4gUHlTdHJpbmdfRnJvbVN0cmluZygiIik7CisgICAgfQorICAgIGlmIChzZXFsZW4gPT0gMSkgeworICAgICAgICBpdGVtID0gUHlTZXF1ZW5jZV9GYXN0X0dFVF9JVEVNKHNlcSwgMCk7CisgICAgICAgIGlmIChQeVN0cmluZ19DaGVja0V4YWN0KGl0ZW0pIHx8IFB5VW5pY29kZV9DaGVja0V4YWN0KGl0ZW0pKSB7CisgICAgICAgICAgICBQeV9JTkNSRUYoaXRlbSk7CisgICAgICAgICAgICBQeV9ERUNSRUYoc2VxKTsKKyAgICAgICAgICAgIHJldHVybiBpdGVtOworICAgICAgICB9CisgICAgfQorCisgICAgLyogVGhlcmUgYXJlIGF0IGxlYXN0IHR3byB0aGluZ3MgdG8gam9pbiwgb3IgZWxzZSB3ZSBoYXZlIGEgc3ViY2xhc3MKKyAgICAgKiBvZiB0aGUgYnVpbHRpbiB0eXBlcyBpbiB0aGUgc2VxdWVuY2UuCisgICAgICogRG8gYSBwcmUtcGFzcyB0byBmaWd1cmUgb3V0IHRoZSB0b3RhbCBhbW91bnQgb2Ygc3BhY2Ugd2UnbGwKKyAgICAgKiBuZWVkIChzeiksIHNlZSB3aGV0aGVyIGFueSBhcmd1bWVudCBpcyBhYnN1cmQsIGFuZCBkZWZlciB0bworICAgICAqIHRoZSBVbmljb2RlIGpvaW4gaWYgYXBwcm9wcmlhdGUuCisgICAgICovCisgICAgZm9yIChpID0gMDsgaSA8IHNlcWxlbjsgaSsrKSB7CisgICAgICAgIGNvbnN0IHNpemVfdCBvbGRfc3ogPSBzejsKKyAgICAgICAgaXRlbSA9IFB5U2VxdWVuY2VfRmFzdF9HRVRfSVRFTShzZXEsIGkpOworICAgICAgICBpZiAoIVB5U3RyaW5nX0NoZWNrKGl0ZW0pKXsKKyNpZmRlZiBQeV9VU0lOR19VTklDT0RFCisgICAgICAgICAgICBpZiAoUHlVbmljb2RlX0NoZWNrKGl0ZW0pKSB7CisgICAgICAgICAgICAgICAgLyogRGVmZXIgdG8gVW5pY29kZSBqb2luLgorICAgICAgICAgICAgICAgICAqIENBVVRJT046ICBUaGVyZSdzIG5vIGd1cmFudGVlIHRoYXQgdGhlCisgICAgICAgICAgICAgICAgICogb3JpZ2luYWwgc2VxdWVuY2UgY2FuIGJlIGl0ZXJhdGVkIG92ZXIKKyAgICAgICAgICAgICAgICAgKiBhZ2Fpbiwgc28gd2UgbXVzdCBwYXNzIHNlcSBoZXJlLgorICAgICAgICAgICAgICAgICAqLworICAgICAgICAgICAgICAgIFB5T2JqZWN0ICpyZXN1bHQ7CisgICAgICAgICAgICAgICAgcmVzdWx0ID0gUHlVbmljb2RlX0pvaW4oKFB5T2JqZWN0ICopc2VsZiwgc2VxKTsKKyAgICAgICAgICAgICAgICBQeV9ERUNSRUYoc2VxKTsKKyAgICAgICAgICAgICAgICByZXR1cm4gcmVzdWx0OworICAgICAgICAgICAgfQorI2VuZGlmCisgICAgICAgICAgICBQeUVycl9Gb3JtYXQoUHlFeGNfVHlwZUVycm9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICJzZXF1ZW5jZSBpdGVtICV6ZDogZXhwZWN0ZWQgc3RyaW5nLCIKKyAgICAgICAgICAgICAgICAgICAgICAgICAiICUuODBzIGZvdW5kIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICBpLCBQeV9UWVBFKGl0ZW0pLT50cF9uYW1lKTsKKyAgICAgICAgICAgIFB5X0RFQ1JFRihzZXEpOworICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgICAgIH0KKyAgICAgICAgc3ogKz0gUHlTdHJpbmdfR0VUX1NJWkUoaXRlbSk7CisgICAgICAgIGlmIChpICE9IDApCisgICAgICAgICAgICBzeiArPSBzZXBsZW47CisgICAgICAgIGlmIChzeiA8IG9sZF9zeiB8fCBzeiA+IFBZX1NTSVpFX1RfTUFYKSB7CisgICAgICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfT3ZlcmZsb3dFcnJvciwKKyAgICAgICAgICAgICAgICAiam9pbigpIHJlc3VsdCBpcyB0b28gbG9uZyBmb3IgYSBQeXRob24gc3RyaW5nIik7CisgICAgICAgICAgICBQeV9ERUNSRUYoc2VxKTsKKyAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgICAgICB9CisgICAgfQorCisgICAgLyogQWxsb2NhdGUgcmVzdWx0IHNwYWNlLiAqLworICAgIHJlcyA9IFB5U3RyaW5nX0Zyb21TdHJpbmdBbmRTaXplKChjaGFyKilOVUxMLCBzeik7CisgICAgaWYgKHJlcyA9PSBOVUxMKSB7CisgICAgICAgIFB5X0RFQ1JFRihzZXEpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisKKyAgICAvKiBDYXRlbmF0ZSBldmVyeXRoaW5nLiAqLworICAgIHAgPSBQeVN0cmluZ19BU19TVFJJTkcocmVzKTsKKyAgICBmb3IgKGkgPSAwOyBpIDwgc2VxbGVuOyArK2kpIHsKKyAgICAgICAgc2l6ZV90IG47CisgICAgICAgIGl0ZW0gPSBQeVNlcXVlbmNlX0Zhc3RfR0VUX0lURU0oc2VxLCBpKTsKKyAgICAgICAgbiA9IFB5U3RyaW5nX0dFVF9TSVpFKGl0ZW0pOworICAgICAgICBQeV9NRU1DUFkocCwgUHlTdHJpbmdfQVNfU1RSSU5HKGl0ZW0pLCBuKTsKKyAgICAgICAgcCArPSBuOworICAgICAgICBpZiAoaSA8IHNlcWxlbiAtIDEpIHsKKyAgICAgICAgICAgIFB5X01FTUNQWShwLCBzZXAsIHNlcGxlbik7CisgICAgICAgICAgICBwICs9IHNlcGxlbjsKKyAgICAgICAgfQorICAgIH0KKworICAgIFB5X0RFQ1JFRihzZXEpOworICAgIHJldHVybiByZXM7Cit9CisKK1B5T2JqZWN0ICoKK19QeVN0cmluZ19Kb2luKFB5T2JqZWN0ICpzZXAsIFB5T2JqZWN0ICp4KQoreworICAgIGFzc2VydChzZXAgIT0gTlVMTCAmJiBQeVN0cmluZ19DaGVjayhzZXApKTsKKyAgICBhc3NlcnQoeCAhPSBOVUxMKTsKKyAgICByZXR1cm4gc3RyaW5nX2pvaW4oKFB5U3RyaW5nT2JqZWN0ICopc2VwLCB4KTsKK30KKworLyogaGVscGVyIG1hY3JvIHRvIGZpeHVwIHN0YXJ0L2VuZCBzbGljZSB2YWx1ZXMgKi8KKyNkZWZpbmUgQURKVVNUX0lORElDRVMoc3RhcnQsIGVuZCwgbGVuKSAgICAgICAgIFwKKyAgICBpZiAoZW5kID4gbGVuKSAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICBlbmQgPSBsZW47ICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgZWxzZSBpZiAoZW5kIDwgMCkgeyAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgZW5kICs9IGxlbjsgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICBpZiAoZW5kIDwgMCkgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgIGVuZCA9IDA7ICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIH0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgaWYgKHN0YXJ0IDwgMCkgeyAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgc3RhcnQgKz0gbGVuOyAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICBpZiAoc3RhcnQgPCAwKSAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgIHN0YXJ0ID0gMDsgICAgICAgICAgICAgICAgICAgICAgXAorICAgIH0KKworUHlfTE9DQUxfSU5MSU5FKFB5X3NzaXplX3QpCitzdHJpbmdfZmluZF9pbnRlcm5hbChQeVN0cmluZ09iamVjdCAqc2VsZiwgUHlPYmplY3QgKmFyZ3MsIGludCBkaXIpCit7CisgICAgUHlPYmplY3QgKnN1Ym9iajsKKyAgICBjb25zdCBjaGFyICpzdWI7CisgICAgUHlfc3NpemVfdCBzdWJfbGVuOworICAgIFB5X3NzaXplX3Qgc3RhcnQ9MCwgZW5kPVBZX1NTSVpFX1RfTUFYOworCisgICAgaWYgKCFzdHJpbmdsaWJfcGFyc2VfYXJnc19maW5kcygiZmluZC9yZmluZC9pbmRleC9yaW5kZXgiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYXJncywgJnN1Ym9iaiwgJnN0YXJ0LCAmZW5kKSkKKyAgICAgICAgcmV0dXJuIC0yOworCisgICAgaWYgKFB5U3RyaW5nX0NoZWNrKHN1Ym9iaikpIHsKKyAgICAgICAgc3ViID0gUHlTdHJpbmdfQVNfU1RSSU5HKHN1Ym9iaik7CisgICAgICAgIHN1Yl9sZW4gPSBQeVN0cmluZ19HRVRfU0laRShzdWJvYmopOworICAgIH0KKyNpZmRlZiBQeV9VU0lOR19VTklDT0RFCisgICAgZWxzZSBpZiAoUHlVbmljb2RlX0NoZWNrKHN1Ym9iaikpCisgICAgICAgIHJldHVybiBQeVVuaWNvZGVfRmluZCgKKyAgICAgICAgICAgIChQeU9iamVjdCAqKXNlbGYsIHN1Ym9iaiwgc3RhcnQsIGVuZCwgZGlyKTsKKyNlbmRpZgorICAgIGVsc2UgaWYgKFB5T2JqZWN0X0FzQ2hhckJ1ZmZlcihzdWJvYmosICZzdWIsICZzdWJfbGVuKSkKKyAgICAgICAgLyogWFhYIC0gdGhlICJleHBlY3RlZCBhIGNoYXJhY3RlciBidWZmZXIgb2JqZWN0IiBpcyBwcmV0dHkKKyAgICAgICAgICAgY29uZnVzaW5nIGZvciBhIG5vbi1leHBlcnQuICByZW1hcCB0byBzb21ldGhpbmcgZWxzZSA/ICovCisgICAgICAgIHJldHVybiAtMjsKKworICAgIGlmIChkaXIgPiAwKQorICAgICAgICByZXR1cm4gc3RyaW5nbGliX2ZpbmRfc2xpY2UoCisgICAgICAgICAgICBQeVN0cmluZ19BU19TVFJJTkcoc2VsZiksIFB5U3RyaW5nX0dFVF9TSVpFKHNlbGYpLAorICAgICAgICAgICAgc3ViLCBzdWJfbGVuLCBzdGFydCwgZW5kKTsKKyAgICBlbHNlCisgICAgICAgIHJldHVybiBzdHJpbmdsaWJfcmZpbmRfc2xpY2UoCisgICAgICAgICAgICBQeVN0cmluZ19BU19TVFJJTkcoc2VsZiksIFB5U3RyaW5nX0dFVF9TSVpFKHNlbGYpLAorICAgICAgICAgICAgc3ViLCBzdWJfbGVuLCBzdGFydCwgZW5kKTsKK30KKworCitQeURvY19TVFJWQVIoZmluZF9fZG9jX18sCisiUy5maW5kKHN1YiBbLHN0YXJ0IFssZW5kXV0pIC0+IGludFxuXAorXG5cCitSZXR1cm4gdGhlIGxvd2VzdCBpbmRleCBpbiBTIHdoZXJlIHN1YnN0cmluZyBzdWIgaXMgZm91bmQsXG5cCitzdWNoIHRoYXQgc3ViIGlzIGNvbnRhaW5lZCB3aXRoaW4gU1tzdGFydDplbmRdLiAgT3B0aW9uYWxcblwKK2FyZ3VtZW50cyBzdGFydCBhbmQgZW5kIGFyZSBpbnRlcnByZXRlZCBhcyBpbiBzbGljZSBub3RhdGlvbi5cblwKK1xuXAorUmV0dXJuIC0xIG9uIGZhaWx1cmUuIik7CisKK3N0YXRpYyBQeU9iamVjdCAqCitzdHJpbmdfZmluZChQeVN0cmluZ09iamVjdCAqc2VsZiwgUHlPYmplY3QgKmFyZ3MpCit7CisgICAgUHlfc3NpemVfdCByZXN1bHQgPSBzdHJpbmdfZmluZF9pbnRlcm5hbChzZWxmLCBhcmdzLCArMSk7CisgICAgaWYgKHJlc3VsdCA9PSAtMikKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgcmV0dXJuIFB5SW50X0Zyb21Tc2l6ZV90KHJlc3VsdCk7Cit9CisKKworUHlEb2NfU1RSVkFSKGluZGV4X19kb2NfXywKKyJTLmluZGV4KHN1YiBbLHN0YXJ0IFssZW5kXV0pIC0+IGludFxuXAorXG5cCitMaWtlIFMuZmluZCgpIGJ1dCByYWlzZSBWYWx1ZUVycm9yIHdoZW4gdGhlIHN1YnN0cmluZyBpcyBub3QgZm91bmQuIik7CisKK3N0YXRpYyBQeU9iamVjdCAqCitzdHJpbmdfaW5kZXgoUHlTdHJpbmdPYmplY3QgKnNlbGYsIFB5T2JqZWN0ICphcmdzKQoreworICAgIFB5X3NzaXplX3QgcmVzdWx0ID0gc3RyaW5nX2ZpbmRfaW50ZXJuYWwoc2VsZiwgYXJncywgKzEpOworICAgIGlmIChyZXN1bHQgPT0gLTIpCisgICAgICAgIHJldHVybiBOVUxMOworICAgIGlmIChyZXN1bHQgPT0gLTEpIHsKKyAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1ZhbHVlRXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAgICAic3Vic3RyaW5nIG5vdCBmb3VuZCIpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgcmV0dXJuIFB5SW50X0Zyb21Tc2l6ZV90KHJlc3VsdCk7Cit9CisKKworUHlEb2NfU1RSVkFSKHJmaW5kX19kb2NfXywKKyJTLnJmaW5kKHN1YiBbLHN0YXJ0IFssZW5kXV0pIC0+IGludFxuXAorXG5cCitSZXR1cm4gdGhlIGhpZ2hlc3QgaW5kZXggaW4gUyB3aGVyZSBzdWJzdHJpbmcgc3ViIGlzIGZvdW5kLFxuXAorc3VjaCB0aGF0IHN1YiBpcyBjb250YWluZWQgd2l0aGluIFNbc3RhcnQ6ZW5kXS4gIE9wdGlvbmFsXG5cCithcmd1bWVudHMgc3RhcnQgYW5kIGVuZCBhcmUgaW50ZXJwcmV0ZWQgYXMgaW4gc2xpY2Ugbm90YXRpb24uXG5cCitcblwKK1JldHVybiAtMSBvbiBmYWlsdXJlLiIpOworCitzdGF0aWMgUHlPYmplY3QgKgorc3RyaW5nX3JmaW5kKFB5U3RyaW5nT2JqZWN0ICpzZWxmLCBQeU9iamVjdCAqYXJncykKK3sKKyAgICBQeV9zc2l6ZV90IHJlc3VsdCA9IHN0cmluZ19maW5kX2ludGVybmFsKHNlbGYsIGFyZ3MsIC0xKTsKKyAgICBpZiAocmVzdWx0ID09IC0yKQorICAgICAgICByZXR1cm4gTlVMTDsKKyAgICByZXR1cm4gUHlJbnRfRnJvbVNzaXplX3QocmVzdWx0KTsKK30KKworCitQeURvY19TVFJWQVIocmluZGV4X19kb2NfXywKKyJTLnJpbmRleChzdWIgWyxzdGFydCBbLGVuZF1dKSAtPiBpbnRcblwKK1xuXAorTGlrZSBTLnJmaW5kKCkgYnV0IHJhaXNlIFZhbHVlRXJyb3Igd2hlbiB0aGUgc3Vic3RyaW5nIGlzIG5vdCBmb3VuZC4iKTsKKworc3RhdGljIFB5T2JqZWN0ICoKK3N0cmluZ19yaW5kZXgoUHlTdHJpbmdPYmplY3QgKnNlbGYsIFB5T2JqZWN0ICphcmdzKQoreworICAgIFB5X3NzaXplX3QgcmVzdWx0ID0gc3RyaW5nX2ZpbmRfaW50ZXJuYWwoc2VsZiwgYXJncywgLTEpOworICAgIGlmIChyZXN1bHQgPT0gLTIpCisgICAgICAgIHJldHVybiBOVUxMOworICAgIGlmIChyZXN1bHQgPT0gLTEpIHsKKyAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1ZhbHVlRXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAgICAic3Vic3RyaW5nIG5vdCBmb3VuZCIpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgcmV0dXJuIFB5SW50X0Zyb21Tc2l6ZV90KHJlc3VsdCk7Cit9CisKKworUHlfTE9DQUxfSU5MSU5FKFB5T2JqZWN0ICopCitkb194c3RyaXAoUHlTdHJpbmdPYmplY3QgKnNlbGYsIGludCBzdHJpcHR5cGUsIFB5T2JqZWN0ICpzZXBvYmopCit7CisgICAgY2hhciAqcyA9IFB5U3RyaW5nX0FTX1NUUklORyhzZWxmKTsKKyAgICBQeV9zc2l6ZV90IGxlbiA9IFB5U3RyaW5nX0dFVF9TSVpFKHNlbGYpOworICAgIGNoYXIgKnNlcCA9IFB5U3RyaW5nX0FTX1NUUklORyhzZXBvYmopOworICAgIFB5X3NzaXplX3Qgc2VwbGVuID0gUHlTdHJpbmdfR0VUX1NJWkUoc2Vwb2JqKTsKKyAgICBQeV9zc2l6ZV90IGksIGo7CisKKyAgICBpID0gMDsKKyAgICBpZiAoc3RyaXB0eXBlICE9IFJJR0hUU1RSSVApIHsKKyAgICAgICAgd2hpbGUgKGkgPCBsZW4gJiYgbWVtY2hyKHNlcCwgUHlfQ0hBUk1BU0soc1tpXSksIHNlcGxlbikpIHsKKyAgICAgICAgICAgIGkrKzsKKyAgICAgICAgfQorICAgIH0KKworICAgIGogPSBsZW47CisgICAgaWYgKHN0cmlwdHlwZSAhPSBMRUZUU1RSSVApIHsKKyAgICAgICAgZG8geworICAgICAgICAgICAgai0tOworICAgICAgICB9IHdoaWxlIChqID49IGkgJiYgbWVtY2hyKHNlcCwgUHlfQ0hBUk1BU0soc1tqXSksIHNlcGxlbikpOworICAgICAgICBqKys7CisgICAgfQorCisgICAgaWYgKGkgPT0gMCAmJiBqID09IGxlbiAmJiBQeVN0cmluZ19DaGVja0V4YWN0KHNlbGYpKSB7CisgICAgICAgIFB5X0lOQ1JFRihzZWxmKTsKKyAgICAgICAgcmV0dXJuIChQeU9iamVjdCopc2VsZjsKKyAgICB9CisgICAgZWxzZQorICAgICAgICByZXR1cm4gUHlTdHJpbmdfRnJvbVN0cmluZ0FuZFNpemUocytpLCBqLWkpOworfQorCisKK1B5X0xPQ0FMX0lOTElORShQeU9iamVjdCAqKQorZG9fc3RyaXAoUHlTdHJpbmdPYmplY3QgKnNlbGYsIGludCBzdHJpcHR5cGUpCit7CisgICAgY2hhciAqcyA9IFB5U3RyaW5nX0FTX1NUUklORyhzZWxmKTsKKyAgICBQeV9zc2l6ZV90IGxlbiA9IFB5U3RyaW5nX0dFVF9TSVpFKHNlbGYpLCBpLCBqOworCisgICAgaSA9IDA7CisgICAgaWYgKHN0cmlwdHlwZSAhPSBSSUdIVFNUUklQKSB7CisgICAgICAgIHdoaWxlIChpIDwgbGVuICYmIGlzc3BhY2UoUHlfQ0hBUk1BU0soc1tpXSkpKSB7CisgICAgICAgICAgICBpKys7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBqID0gbGVuOworICAgIGlmIChzdHJpcHR5cGUgIT0gTEVGVFNUUklQKSB7CisgICAgICAgIGRvIHsKKyAgICAgICAgICAgIGotLTsKKyAgICAgICAgfSB3aGlsZSAoaiA+PSBpICYmIGlzc3BhY2UoUHlfQ0hBUk1BU0soc1tqXSkpKTsKKyAgICAgICAgaisrOworICAgIH0KKworICAgIGlmIChpID09IDAgJiYgaiA9PSBsZW4gJiYgUHlTdHJpbmdfQ2hlY2tFeGFjdChzZWxmKSkgeworICAgICAgICBQeV9JTkNSRUYoc2VsZik7CisgICAgICAgIHJldHVybiAoUHlPYmplY3QqKXNlbGY7CisgICAgfQorICAgIGVsc2UKKyAgICAgICAgcmV0dXJuIFB5U3RyaW5nX0Zyb21TdHJpbmdBbmRTaXplKHMraSwgai1pKTsKK30KKworCitQeV9MT0NBTF9JTkxJTkUoUHlPYmplY3QgKikKK2RvX2FyZ3N0cmlwKFB5U3RyaW5nT2JqZWN0ICpzZWxmLCBpbnQgc3RyaXB0eXBlLCBQeU9iamVjdCAqYXJncykKK3sKKyAgICBQeU9iamVjdCAqc2VwID0gTlVMTDsKKworICAgIGlmICghUHlBcmdfUGFyc2VUdXBsZShhcmdzLCAoY2hhciAqKXN0cmlwZm9ybWF0W3N0cmlwdHlwZV0sICZzZXApKQorICAgICAgICByZXR1cm4gTlVMTDsKKworICAgIGlmIChzZXAgIT0gTlVMTCAmJiBzZXAgIT0gUHlfTm9uZSkgeworICAgICAgICBpZiAoUHlTdHJpbmdfQ2hlY2soc2VwKSkKKyAgICAgICAgICAgIHJldHVybiBkb194c3RyaXAoc2VsZiwgc3RyaXB0eXBlLCBzZXApOworI2lmZGVmIFB5X1VTSU5HX1VOSUNPREUKKyAgICAgICAgZWxzZSBpZiAoUHlVbmljb2RlX0NoZWNrKHNlcCkpIHsKKyAgICAgICAgICAgIFB5T2JqZWN0ICp1bmlzZWxmID0gUHlVbmljb2RlX0Zyb21PYmplY3QoKFB5T2JqZWN0ICopc2VsZik7CisgICAgICAgICAgICBQeU9iamVjdCAqcmVzOworICAgICAgICAgICAgaWYgKHVuaXNlbGY9PU5VTEwpCisgICAgICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgICAgICAgICByZXMgPSBfUHlVbmljb2RlX1hTdHJpcCgoUHlVbmljb2RlT2JqZWN0ICopdW5pc2VsZiwKKyAgICAgICAgICAgICAgICBzdHJpcHR5cGUsIHNlcCk7CisgICAgICAgICAgICBQeV9ERUNSRUYodW5pc2VsZik7CisgICAgICAgICAgICByZXR1cm4gcmVzOworICAgICAgICB9CisjZW5kaWYKKyAgICAgICAgUHlFcnJfRm9ybWF0KFB5RXhjX1R5cGVFcnJvciwKKyNpZmRlZiBQeV9VU0lOR19VTklDT0RFCisgICAgICAgICAgICAgICAgICAgICAiJXMgYXJnIG11c3QgYmUgTm9uZSwgc3RyIG9yIHVuaWNvZGUiLAorI2Vsc2UKKyAgICAgICAgICAgICAgICAgICAgICIlcyBhcmcgbXVzdCBiZSBOb25lIG9yIHN0ciIsCisjZW5kaWYKKyAgICAgICAgICAgICAgICAgICAgIFNUUklQTkFNRShzdHJpcHR5cGUpKTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorCisgICAgcmV0dXJuIGRvX3N0cmlwKHNlbGYsIHN0cmlwdHlwZSk7Cit9CisKKworUHlEb2NfU1RSVkFSKHN0cmlwX19kb2NfXywKKyJTLnN0cmlwKFtjaGFyc10pIC0+IHN0cmluZyBvciB1bmljb2RlXG5cCitcblwKK1JldHVybiBhIGNvcHkgb2YgdGhlIHN0cmluZyBTIHdpdGggbGVhZGluZyBhbmQgdHJhaWxpbmdcblwKK3doaXRlc3BhY2UgcmVtb3ZlZC5cblwKK0lmIGNoYXJzIGlzIGdpdmVuIGFuZCBub3QgTm9uZSwgcmVtb3ZlIGNoYXJhY3RlcnMgaW4gY2hhcnMgaW5zdGVhZC5cblwKK0lmIGNoYXJzIGlzIHVuaWNvZGUsIFMgd2lsbCBiZSBjb252ZXJ0ZWQgdG8gdW5pY29kZSBiZWZvcmUgc3RyaXBwaW5nIik7CisKK3N0YXRpYyBQeU9iamVjdCAqCitzdHJpbmdfc3RyaXAoUHlTdHJpbmdPYmplY3QgKnNlbGYsIFB5T2JqZWN0ICphcmdzKQoreworICAgIGlmIChQeVR1cGxlX0dFVF9TSVpFKGFyZ3MpID09IDApCisgICAgICAgIHJldHVybiBkb19zdHJpcChzZWxmLCBCT1RIU1RSSVApOyAvKiBDb21tb24gY2FzZSAqLworICAgIGVsc2UKKyAgICAgICAgcmV0dXJuIGRvX2FyZ3N0cmlwKHNlbGYsIEJPVEhTVFJJUCwgYXJncyk7Cit9CisKKworUHlEb2NfU1RSVkFSKGxzdHJpcF9fZG9jX18sCisiUy5sc3RyaXAoW2NoYXJzXSkgLT4gc3RyaW5nIG9yIHVuaWNvZGVcblwKK1xuXAorUmV0dXJuIGEgY29weSBvZiB0aGUgc3RyaW5nIFMgd2l0aCBsZWFkaW5nIHdoaXRlc3BhY2UgcmVtb3ZlZC5cblwKK0lmIGNoYXJzIGlzIGdpdmVuIGFuZCBub3QgTm9uZSwgcmVtb3ZlIGNoYXJhY3RlcnMgaW4gY2hhcnMgaW5zdGVhZC5cblwKK0lmIGNoYXJzIGlzIHVuaWNvZGUsIFMgd2lsbCBiZSBjb252ZXJ0ZWQgdG8gdW5pY29kZSBiZWZvcmUgc3RyaXBwaW5nIik7CisKK3N0YXRpYyBQeU9iamVjdCAqCitzdHJpbmdfbHN0cmlwKFB5U3RyaW5nT2JqZWN0ICpzZWxmLCBQeU9iamVjdCAqYXJncykKK3sKKyAgICBpZiAoUHlUdXBsZV9HRVRfU0laRShhcmdzKSA9PSAwKQorICAgICAgICByZXR1cm4gZG9fc3RyaXAoc2VsZiwgTEVGVFNUUklQKTsgLyogQ29tbW9uIGNhc2UgKi8KKyAgICBlbHNlCisgICAgICAgIHJldHVybiBkb19hcmdzdHJpcChzZWxmLCBMRUZUU1RSSVAsIGFyZ3MpOworfQorCisKK1B5RG9jX1NUUlZBUihyc3RyaXBfX2RvY19fLAorIlMucnN0cmlwKFtjaGFyc10pIC0+IHN0cmluZyBvciB1bmljb2RlXG5cCitcblwKK1JldHVybiBhIGNvcHkgb2YgdGhlIHN0cmluZyBTIHdpdGggdHJhaWxpbmcgd2hpdGVzcGFjZSByZW1vdmVkLlxuXAorSWYgY2hhcnMgaXMgZ2l2ZW4gYW5kIG5vdCBOb25lLCByZW1vdmUgY2hhcmFjdGVycyBpbiBjaGFycyBpbnN0ZWFkLlxuXAorSWYgY2hhcnMgaXMgdW5pY29kZSwgUyB3aWxsIGJlIGNvbnZlcnRlZCB0byB1bmljb2RlIGJlZm9yZSBzdHJpcHBpbmciKTsKKworc3RhdGljIFB5T2JqZWN0ICoKK3N0cmluZ19yc3RyaXAoUHlTdHJpbmdPYmplY3QgKnNlbGYsIFB5T2JqZWN0ICphcmdzKQoreworICAgIGlmIChQeVR1cGxlX0dFVF9TSVpFKGFyZ3MpID09IDApCisgICAgICAgIHJldHVybiBkb19zdHJpcChzZWxmLCBSSUdIVFNUUklQKTsgLyogQ29tbW9uIGNhc2UgKi8KKyAgICBlbHNlCisgICAgICAgIHJldHVybiBkb19hcmdzdHJpcChzZWxmLCBSSUdIVFNUUklQLCBhcmdzKTsKK30KKworCitQeURvY19TVFJWQVIobG93ZXJfX2RvY19fLAorIlMubG93ZXIoKSAtPiBzdHJpbmdcblwKK1xuXAorUmV0dXJuIGEgY29weSBvZiB0aGUgc3RyaW5nIFMgY29udmVydGVkIHRvIGxvd2VyY2FzZS4iKTsKKworLyogX3RvbG93ZXIgYW5kIF90b3VwcGVyIGFyZSBkZWZpbmVkIGJ5IFNVU3YyLCBidXQgdGhleSdyZSBub3QgSVNPIEMgKi8KKyNpZm5kZWYgX3RvbG93ZXIKKyNkZWZpbmUgX3RvbG93ZXIgdG9sb3dlcgorI2VuZGlmCisKK3N0YXRpYyBQeU9iamVjdCAqCitzdHJpbmdfbG93ZXIoUHlTdHJpbmdPYmplY3QgKnNlbGYpCit7CisgICAgY2hhciAqczsKKyAgICBQeV9zc2l6ZV90IGksIG4gPSBQeVN0cmluZ19HRVRfU0laRShzZWxmKTsKKyAgICBQeU9iamVjdCAqbmV3b2JqOworCisgICAgbmV3b2JqID0gUHlTdHJpbmdfRnJvbVN0cmluZ0FuZFNpemUoTlVMTCwgbik7CisgICAgaWYgKCFuZXdvYmopCisgICAgICAgIHJldHVybiBOVUxMOworCisgICAgcyA9IFB5U3RyaW5nX0FTX1NUUklORyhuZXdvYmopOworCisgICAgUHlfTUVNQ1BZKHMsIFB5U3RyaW5nX0FTX1NUUklORyhzZWxmKSwgbik7CisKKyAgICBmb3IgKGkgPSAwOyBpIDwgbjsgaSsrKSB7CisgICAgICAgIGludCBjID0gUHlfQ0hBUk1BU0soc1tpXSk7CisgICAgICAgIGlmIChpc3VwcGVyKGMpKQorICAgICAgICAgICAgc1tpXSA9IF90b2xvd2VyKGMpOworICAgIH0KKworICAgIHJldHVybiBuZXdvYmo7Cit9CisKK1B5RG9jX1NUUlZBUih1cHBlcl9fZG9jX18sCisiUy51cHBlcigpIC0+IHN0cmluZ1xuXAorXG5cCitSZXR1cm4gYSBjb3B5IG9mIHRoZSBzdHJpbmcgUyBjb252ZXJ0ZWQgdG8gdXBwZXJjYXNlLiIpOworCisjaWZuZGVmIF90b3VwcGVyCisjZGVmaW5lIF90b3VwcGVyIHRvdXBwZXIKKyNlbmRpZgorCitzdGF0aWMgUHlPYmplY3QgKgorc3RyaW5nX3VwcGVyKFB5U3RyaW5nT2JqZWN0ICpzZWxmKQoreworICAgIGNoYXIgKnM7CisgICAgUHlfc3NpemVfdCBpLCBuID0gUHlTdHJpbmdfR0VUX1NJWkUoc2VsZik7CisgICAgUHlPYmplY3QgKm5ld29iajsKKworICAgIG5ld29iaiA9IFB5U3RyaW5nX0Zyb21TdHJpbmdBbmRTaXplKE5VTEwsIG4pOworICAgIGlmICghbmV3b2JqKQorICAgICAgICByZXR1cm4gTlVMTDsKKworICAgIHMgPSBQeVN0cmluZ19BU19TVFJJTkcobmV3b2JqKTsKKworICAgIFB5X01FTUNQWShzLCBQeVN0cmluZ19BU19TVFJJTkcoc2VsZiksIG4pOworCisgICAgZm9yIChpID0gMDsgaSA8IG47IGkrKykgeworICAgICAgICBpbnQgYyA9IFB5X0NIQVJNQVNLKHNbaV0pOworICAgICAgICBpZiAoaXNsb3dlcihjKSkKKyAgICAgICAgICAgIHNbaV0gPSBfdG91cHBlcihjKTsKKyAgICB9CisKKyAgICByZXR1cm4gbmV3b2JqOworfQorCitQeURvY19TVFJWQVIodGl0bGVfX2RvY19fLAorIlMudGl0bGUoKSAtPiBzdHJpbmdcblwKK1xuXAorUmV0dXJuIGEgdGl0bGVjYXNlZCB2ZXJzaW9uIG9mIFMsIGkuZS4gd29yZHMgc3RhcnQgd2l0aCB1cHBlcmNhc2VcblwKK2NoYXJhY3RlcnMsIGFsbCByZW1haW5pbmcgY2FzZWQgY2hhcmFjdGVycyBoYXZlIGxvd2VyY2FzZS4iKTsKKworc3RhdGljIFB5T2JqZWN0Kgorc3RyaW5nX3RpdGxlKFB5U3RyaW5nT2JqZWN0ICpzZWxmKQoreworICAgIGNoYXIgKnMgPSBQeVN0cmluZ19BU19TVFJJTkcoc2VsZiksICpzX25ldzsKKyAgICBQeV9zc2l6ZV90IGksIG4gPSBQeVN0cmluZ19HRVRfU0laRShzZWxmKTsKKyAgICBpbnQgcHJldmlvdXNfaXNfY2FzZWQgPSAwOworICAgIFB5T2JqZWN0ICpuZXdvYmo7CisKKyAgICBuZXdvYmogPSBQeVN0cmluZ19Gcm9tU3RyaW5nQW5kU2l6ZShOVUxMLCBuKTsKKyAgICBpZiAobmV3b2JqID09IE5VTEwpCisgICAgICAgIHJldHVybiBOVUxMOworICAgIHNfbmV3ID0gUHlTdHJpbmdfQXNTdHJpbmcobmV3b2JqKTsKKyAgICBmb3IgKGkgPSAwOyBpIDwgbjsgaSsrKSB7CisgICAgICAgIGludCBjID0gUHlfQ0hBUk1BU0soKnMrKyk7CisgICAgICAgIGlmIChpc2xvd2VyKGMpKSB7CisgICAgICAgICAgICBpZiAoIXByZXZpb3VzX2lzX2Nhc2VkKQorICAgICAgICAgICAgICAgIGMgPSB0b3VwcGVyKGMpOworICAgICAgICAgICAgcHJldmlvdXNfaXNfY2FzZWQgPSAxOworICAgICAgICB9IGVsc2UgaWYgKGlzdXBwZXIoYykpIHsKKyAgICAgICAgICAgIGlmIChwcmV2aW91c19pc19jYXNlZCkKKyAgICAgICAgICAgICAgICBjID0gdG9sb3dlcihjKTsKKyAgICAgICAgICAgIHByZXZpb3VzX2lzX2Nhc2VkID0gMTsKKyAgICAgICAgfSBlbHNlCisgICAgICAgICAgICBwcmV2aW91c19pc19jYXNlZCA9IDA7CisgICAgICAgICpzX25ldysrID0gYzsKKyAgICB9CisgICAgcmV0dXJuIG5ld29iajsKK30KKworUHlEb2NfU1RSVkFSKGNhcGl0YWxpemVfX2RvY19fLAorIlMuY2FwaXRhbGl6ZSgpIC0+IHN0cmluZ1xuXAorXG5cCitSZXR1cm4gYSBjb3B5IG9mIHRoZSBzdHJpbmcgUyB3aXRoIG9ubHkgaXRzIGZpcnN0IGNoYXJhY3RlclxuXAorY2FwaXRhbGl6ZWQuIik7CisKK3N0YXRpYyBQeU9iamVjdCAqCitzdHJpbmdfY2FwaXRhbGl6ZShQeVN0cmluZ09iamVjdCAqc2VsZikKK3sKKyAgICBjaGFyICpzID0gUHlTdHJpbmdfQVNfU1RSSU5HKHNlbGYpLCAqc19uZXc7CisgICAgUHlfc3NpemVfdCBpLCBuID0gUHlTdHJpbmdfR0VUX1NJWkUoc2VsZik7CisgICAgUHlPYmplY3QgKm5ld29iajsKKworICAgIG5ld29iaiA9IFB5U3RyaW5nX0Zyb21TdHJpbmdBbmRTaXplKE5VTEwsIG4pOworICAgIGlmIChuZXdvYmogPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgc19uZXcgPSBQeVN0cmluZ19Bc1N0cmluZyhuZXdvYmopOworICAgIGlmICgwIDwgbikgeworICAgICAgICBpbnQgYyA9IFB5X0NIQVJNQVNLKCpzKyspOworICAgICAgICBpZiAoaXNsb3dlcihjKSkKKyAgICAgICAgICAgICpzX25ldyA9IHRvdXBwZXIoYyk7CisgICAgICAgIGVsc2UKKyAgICAgICAgICAgICpzX25ldyA9IGM7CisgICAgICAgIHNfbmV3Kys7CisgICAgfQorICAgIGZvciAoaSA9IDE7IGkgPCBuOyBpKyspIHsKKyAgICAgICAgaW50IGMgPSBQeV9DSEFSTUFTSygqcysrKTsKKyAgICAgICAgaWYgKGlzdXBwZXIoYykpCisgICAgICAgICAgICAqc19uZXcgPSB0b2xvd2VyKGMpOworICAgICAgICBlbHNlCisgICAgICAgICAgICAqc19uZXcgPSBjOworICAgICAgICBzX25ldysrOworICAgIH0KKyAgICByZXR1cm4gbmV3b2JqOworfQorCisKK1B5RG9jX1NUUlZBUihjb3VudF9fZG9jX18sCisiUy5jb3VudChzdWJbLCBzdGFydFssIGVuZF1dKSAtPiBpbnRcblwKK1xuXAorUmV0dXJuIHRoZSBudW1iZXIgb2Ygbm9uLW92ZXJsYXBwaW5nIG9jY3VycmVuY2VzIG9mIHN1YnN0cmluZyBzdWIgaW5cblwKK3N0cmluZyBTW3N0YXJ0OmVuZF0uICBPcHRpb25hbCBhcmd1bWVudHMgc3RhcnQgYW5kIGVuZCBhcmUgaW50ZXJwcmV0ZWRcblwKK2FzIGluIHNsaWNlIG5vdGF0aW9uLiIpOworCitzdGF0aWMgUHlPYmplY3QgKgorc3RyaW5nX2NvdW50KFB5U3RyaW5nT2JqZWN0ICpzZWxmLCBQeU9iamVjdCAqYXJncykKK3sKKyAgICBQeU9iamVjdCAqc3ViX29iajsKKyAgICBjb25zdCBjaGFyICpzdHIgPSBQeVN0cmluZ19BU19TVFJJTkcoc2VsZiksICpzdWI7CisgICAgUHlfc3NpemVfdCBzdWJfbGVuOworICAgIFB5X3NzaXplX3Qgc3RhcnQgPSAwLCBlbmQgPSBQWV9TU0laRV9UX01BWDsKKworICAgIGlmICghc3RyaW5nbGliX3BhcnNlX2FyZ3NfZmluZHMoImNvdW50IiwgYXJncywgJnN1Yl9vYmosICZzdGFydCwgJmVuZCkpCisgICAgICAgIHJldHVybiBOVUxMOworCisgICAgaWYgKFB5U3RyaW5nX0NoZWNrKHN1Yl9vYmopKSB7CisgICAgICAgIHN1YiA9IFB5U3RyaW5nX0FTX1NUUklORyhzdWJfb2JqKTsKKyAgICAgICAgc3ViX2xlbiA9IFB5U3RyaW5nX0dFVF9TSVpFKHN1Yl9vYmopOworICAgIH0KKyNpZmRlZiBQeV9VU0lOR19VTklDT0RFCisgICAgZWxzZSBpZiAoUHlVbmljb2RlX0NoZWNrKHN1Yl9vYmopKSB7CisgICAgICAgIFB5X3NzaXplX3QgY291bnQ7CisgICAgICAgIGNvdW50ID0gUHlVbmljb2RlX0NvdW50KChQeU9iamVjdCAqKXNlbGYsIHN1Yl9vYmosIHN0YXJ0LCBlbmQpOworICAgICAgICBpZiAoY291bnQgPT0gLTEpCisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgZWxzZQorICAgICAgICAgICAgcmV0dXJuIFB5SW50X0Zyb21Tc2l6ZV90KGNvdW50KTsKKyAgICB9CisjZW5kaWYKKyAgICBlbHNlIGlmIChQeU9iamVjdF9Bc0NoYXJCdWZmZXIoc3ViX29iaiwgJnN1YiwgJnN1Yl9sZW4pKQorICAgICAgICByZXR1cm4gTlVMTDsKKworICAgIEFESlVTVF9JTkRJQ0VTKHN0YXJ0LCBlbmQsIFB5U3RyaW5nX0dFVF9TSVpFKHNlbGYpKTsKKworICAgIHJldHVybiBQeUludF9Gcm9tU3NpemVfdCgKKyAgICAgICAgc3RyaW5nbGliX2NvdW50KHN0ciArIHN0YXJ0LCBlbmQgLSBzdGFydCwgc3ViLCBzdWJfbGVuLCBQWV9TU0laRV9UX01BWCkKKyAgICAgICAgKTsKK30KKworUHlEb2NfU1RSVkFSKHN3YXBjYXNlX19kb2NfXywKKyJTLnN3YXBjYXNlKCkgLT4gc3RyaW5nXG5cCitcblwKK1JldHVybiBhIGNvcHkgb2YgdGhlIHN0cmluZyBTIHdpdGggdXBwZXJjYXNlIGNoYXJhY3RlcnNcblwKK2NvbnZlcnRlZCB0byBsb3dlcmNhc2UgYW5kIHZpY2UgdmVyc2EuIik7CisKK3N0YXRpYyBQeU9iamVjdCAqCitzdHJpbmdfc3dhcGNhc2UoUHlTdHJpbmdPYmplY3QgKnNlbGYpCit7CisgICAgY2hhciAqcyA9IFB5U3RyaW5nX0FTX1NUUklORyhzZWxmKSwgKnNfbmV3OworICAgIFB5X3NzaXplX3QgaSwgbiA9IFB5U3RyaW5nX0dFVF9TSVpFKHNlbGYpOworICAgIFB5T2JqZWN0ICpuZXdvYmo7CisKKyAgICBuZXdvYmogPSBQeVN0cmluZ19Gcm9tU3RyaW5nQW5kU2l6ZShOVUxMLCBuKTsKKyAgICBpZiAobmV3b2JqID09IE5VTEwpCisgICAgICAgIHJldHVybiBOVUxMOworICAgIHNfbmV3ID0gUHlTdHJpbmdfQXNTdHJpbmcobmV3b2JqKTsKKyAgICBmb3IgKGkgPSAwOyBpIDwgbjsgaSsrKSB7CisgICAgICAgIGludCBjID0gUHlfQ0hBUk1BU0soKnMrKyk7CisgICAgICAgIGlmIChpc2xvd2VyKGMpKSB7CisgICAgICAgICAgICAqc19uZXcgPSB0b3VwcGVyKGMpOworICAgICAgICB9CisgICAgICAgIGVsc2UgaWYgKGlzdXBwZXIoYykpIHsKKyAgICAgICAgICAgICpzX25ldyA9IHRvbG93ZXIoYyk7CisgICAgICAgIH0KKyAgICAgICAgZWxzZQorICAgICAgICAgICAgKnNfbmV3ID0gYzsKKyAgICAgICAgc19uZXcrKzsKKyAgICB9CisgICAgcmV0dXJuIG5ld29iajsKK30KKworCitQeURvY19TVFJWQVIodHJhbnNsYXRlX19kb2NfXywKKyJTLnRyYW5zbGF0ZSh0YWJsZSBbLGRlbGV0ZWNoYXJzXSkgLT4gc3RyaW5nXG5cCitcblwKK1JldHVybiBhIGNvcHkgb2YgdGhlIHN0cmluZyBTLCB3aGVyZSBhbGwgY2hhcmFjdGVycyBvY2N1cnJpbmdcblwKK2luIHRoZSBvcHRpb25hbCBhcmd1bWVudCBkZWxldGVjaGFycyBhcmUgcmVtb3ZlZCwgYW5kIHRoZVxuXAorcmVtYWluaW5nIGNoYXJhY3RlcnMgaGF2ZSBiZWVuIG1hcHBlZCB0aHJvdWdoIHRoZSBnaXZlblxuXAordHJhbnNsYXRpb24gdGFibGUsIHdoaWNoIG11c3QgYmUgYSBzdHJpbmcgb2YgbGVuZ3RoIDI1NiBvciBOb25lLlxuXAorSWYgdGhlIHRhYmxlIGFyZ3VtZW50IGlzIE5vbmUsIG5vIHRyYW5zbGF0aW9uIGlzIGFwcGxpZWQgYW5kXG5cCit0aGUgb3BlcmF0aW9uIHNpbXBseSByZW1vdmVzIHRoZSBjaGFyYWN0ZXJzIGluIGRlbGV0ZWNoYXJzLiIpOworCitzdGF0aWMgUHlPYmplY3QgKgorc3RyaW5nX3RyYW5zbGF0ZShQeVN0cmluZ09iamVjdCAqc2VsZiwgUHlPYmplY3QgKmFyZ3MpCit7CisgICAgcmVnaXN0ZXIgY2hhciAqaW5wdXQsICpvdXRwdXQ7CisgICAgY29uc3QgY2hhciAqdGFibGU7CisgICAgcmVnaXN0ZXIgUHlfc3NpemVfdCBpLCBjLCBjaGFuZ2VkID0gMDsKKyAgICBQeU9iamVjdCAqaW5wdXRfb2JqID0gKFB5T2JqZWN0KilzZWxmOworICAgIGNvbnN0IGNoYXIgKm91dHB1dF9zdGFydCwgKmRlbF90YWJsZT1OVUxMOworICAgIFB5X3NzaXplX3QgaW5sZW4sIHRhYmxlbiwgZGVsbGVuID0gMDsKKyAgICBQeU9iamVjdCAqcmVzdWx0OworICAgIGludCB0cmFuc190YWJsZVsyNTZdOworICAgIFB5T2JqZWN0ICp0YWJsZW9iaiwgKmRlbG9iaiA9IE5VTEw7CisKKyAgICBpZiAoIVB5QXJnX1VucGFja1R1cGxlKGFyZ3MsICJ0cmFuc2xhdGUiLCAxLCAyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAmdGFibGVvYmosICZkZWxvYmopKQorICAgICAgICByZXR1cm4gTlVMTDsKKworICAgIGlmIChQeVN0cmluZ19DaGVjayh0YWJsZW9iaikpIHsKKyAgICAgICAgdGFibGUgPSBQeVN0cmluZ19BU19TVFJJTkcodGFibGVvYmopOworICAgICAgICB0YWJsZW4gPSBQeVN0cmluZ19HRVRfU0laRSh0YWJsZW9iaik7CisgICAgfQorICAgIGVsc2UgaWYgKHRhYmxlb2JqID09IFB5X05vbmUpIHsKKyAgICAgICAgdGFibGUgPSBOVUxMOworICAgICAgICB0YWJsZW4gPSAyNTY7CisgICAgfQorI2lmZGVmIFB5X1VTSU5HX1VOSUNPREUKKyAgICBlbHNlIGlmIChQeVVuaWNvZGVfQ2hlY2sodGFibGVvYmopKSB7CisgICAgICAgIC8qIFVuaWNvZGUgLnRyYW5zbGF0ZSgpIGRvZXMgbm90IHN1cHBvcnQgdGhlIGRlbGV0ZWNoYXJzCisgICAgICAgICAgIHBhcmFtZXRlcjsgaW5zdGVhZCBhIG1hcHBpbmcgdG8gTm9uZSB3aWxsIGNhdXNlIGNoYXJhY3RlcnMKKyAgICAgICAgICAgdG8gYmUgZGVsZXRlZC4gKi8KKyAgICAgICAgaWYgKGRlbG9iaiAhPSBOVUxMKSB7CisgICAgICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfVHlwZUVycm9yLAorICAgICAgICAgICAgImRlbGV0aW9ucyBhcmUgaW1wbGVtZW50ZWQgZGlmZmVyZW50bHkgZm9yIHVuaWNvZGUiKTsKKyAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgICAgICB9CisgICAgICAgIHJldHVybiBQeVVuaWNvZGVfVHJhbnNsYXRlKChQeU9iamVjdCAqKXNlbGYsIHRhYmxlb2JqLCBOVUxMKTsKKyAgICB9CisjZW5kaWYKKyAgICBlbHNlIGlmIChQeU9iamVjdF9Bc0NoYXJCdWZmZXIodGFibGVvYmosICZ0YWJsZSwgJnRhYmxlbikpCisgICAgICAgIHJldHVybiBOVUxMOworCisgICAgaWYgKHRhYmxlbiAhPSAyNTYpIHsKKyAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1ZhbHVlRXJyb3IsCisgICAgICAgICAgInRyYW5zbGF0aW9uIHRhYmxlIG11c3QgYmUgMjU2IGNoYXJhY3RlcnMgbG9uZyIpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisKKyAgICBpZiAoZGVsb2JqICE9IE5VTEwpIHsKKyAgICAgICAgaWYgKFB5U3RyaW5nX0NoZWNrKGRlbG9iaikpIHsKKyAgICAgICAgICAgIGRlbF90YWJsZSA9IFB5U3RyaW5nX0FTX1NUUklORyhkZWxvYmopOworICAgICAgICAgICAgZGVsbGVuID0gUHlTdHJpbmdfR0VUX1NJWkUoZGVsb2JqKTsKKyAgICAgICAgfQorI2lmZGVmIFB5X1VTSU5HX1VOSUNPREUKKyAgICAgICAgZWxzZSBpZiAoUHlVbmljb2RlX0NoZWNrKGRlbG9iaikpIHsKKyAgICAgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19UeXBlRXJyb3IsCisgICAgICAgICAgICAiZGVsZXRpb25zIGFyZSBpbXBsZW1lbnRlZCBkaWZmZXJlbnRseSBmb3IgdW5pY29kZSIpOworICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgICAgIH0KKyNlbmRpZgorICAgICAgICBlbHNlIGlmIChQeU9iamVjdF9Bc0NoYXJCdWZmZXIoZGVsb2JqLCAmZGVsX3RhYmxlLCAmZGVsbGVuKSkKKyAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICBlbHNlIHsKKyAgICAgICAgZGVsX3RhYmxlID0gTlVMTDsKKyAgICAgICAgZGVsbGVuID0gMDsKKyAgICB9CisKKyAgICBpbmxlbiA9IFB5U3RyaW5nX0dFVF9TSVpFKGlucHV0X29iaik7CisgICAgcmVzdWx0ID0gUHlTdHJpbmdfRnJvbVN0cmluZ0FuZFNpemUoKGNoYXIgKilOVUxMLCBpbmxlbik7CisgICAgaWYgKHJlc3VsdCA9PSBOVUxMKQorICAgICAgICByZXR1cm4gTlVMTDsKKyAgICBvdXRwdXRfc3RhcnQgPSBvdXRwdXQgPSBQeVN0cmluZ19Bc1N0cmluZyhyZXN1bHQpOworICAgIGlucHV0ID0gUHlTdHJpbmdfQVNfU1RSSU5HKGlucHV0X29iaik7CisKKyAgICBpZiAoZGVsbGVuID09IDAgJiYgdGFibGUgIT0gTlVMTCkgeworICAgICAgICAvKiBJZiBubyBkZWxldGlvbnMgYXJlIHJlcXVpcmVkLCB1c2UgZmFzdGVyIGNvZGUgKi8KKyAgICAgICAgZm9yIChpID0gaW5sZW47IC0taSA+PSAwOyApIHsKKyAgICAgICAgICAgIGMgPSBQeV9DSEFSTUFTSygqaW5wdXQrKyk7CisgICAgICAgICAgICBpZiAoUHlfQ0hBUk1BU0soKCpvdXRwdXQrKyA9IHRhYmxlW2NdKSkgIT0gYykKKyAgICAgICAgICAgICAgICBjaGFuZ2VkID0gMTsKKyAgICAgICAgfQorICAgICAgICBpZiAoY2hhbmdlZCB8fCAhUHlTdHJpbmdfQ2hlY2tFeGFjdChpbnB1dF9vYmopKQorICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICAgICAgUHlfREVDUkVGKHJlc3VsdCk7CisgICAgICAgIFB5X0lOQ1JFRihpbnB1dF9vYmopOworICAgICAgICByZXR1cm4gaW5wdXRfb2JqOworICAgIH0KKworICAgIGlmICh0YWJsZSA9PSBOVUxMKSB7CisgICAgICAgIGZvciAoaSA9IDA7IGkgPCAyNTY7IGkrKykKKyAgICAgICAgICAgIHRyYW5zX3RhYmxlW2ldID0gUHlfQ0hBUk1BU0soaSk7CisgICAgfSBlbHNlIHsKKyAgICAgICAgZm9yIChpID0gMDsgaSA8IDI1NjsgaSsrKQorICAgICAgICAgICAgdHJhbnNfdGFibGVbaV0gPSBQeV9DSEFSTUFTSyh0YWJsZVtpXSk7CisgICAgfQorCisgICAgZm9yIChpID0gMDsgaSA8IGRlbGxlbjsgaSsrKQorICAgICAgICB0cmFuc190YWJsZVsoaW50KSBQeV9DSEFSTUFTSyhkZWxfdGFibGVbaV0pXSA9IC0xOworCisgICAgZm9yIChpID0gaW5sZW47IC0taSA+PSAwOyApIHsKKyAgICAgICAgYyA9IFB5X0NIQVJNQVNLKCppbnB1dCsrKTsKKyAgICAgICAgaWYgKHRyYW5zX3RhYmxlW2NdICE9IC0xKQorICAgICAgICAgICAgaWYgKFB5X0NIQVJNQVNLKCpvdXRwdXQrKyA9IChjaGFyKXRyYW5zX3RhYmxlW2NdKSA9PSBjKQorICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICBjaGFuZ2VkID0gMTsKKyAgICB9CisgICAgaWYgKCFjaGFuZ2VkICYmIFB5U3RyaW5nX0NoZWNrRXhhY3QoaW5wdXRfb2JqKSkgeworICAgICAgICBQeV9ERUNSRUYocmVzdWx0KTsKKyAgICAgICAgUHlfSU5DUkVGKGlucHV0X29iaik7CisgICAgICAgIHJldHVybiBpbnB1dF9vYmo7CisgICAgfQorICAgIC8qIEZpeCB0aGUgc2l6ZSBvZiB0aGUgcmVzdWx0aW5nIHN0cmluZyAqLworICAgIGlmIChpbmxlbiA+IDAgJiYgX1B5U3RyaW5nX1Jlc2l6ZSgmcmVzdWx0LCBvdXRwdXQgLSBvdXRwdXRfc3RhcnQpKQorICAgICAgICByZXR1cm4gTlVMTDsKKyAgICByZXR1cm4gcmVzdWx0OworfQorCisKKy8qIGZpbmQgYW5kIGNvdW50IGNoYXJhY3RlcnMgYW5kIHN1YnN0cmluZ3MgKi8KKworI2RlZmluZSBmaW5kY2hhcih0YXJnZXQsIHRhcmdldF9sZW4sIGMpICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgKChjaGFyICopbWVtY2hyKChjb25zdCB2b2lkICopKHRhcmdldCksIGMsIHRhcmdldF9sZW4pKQorCisvKiBTdHJpbmcgb3BzIG11c3QgcmV0dXJuIGEgc3RyaW5nLiAgKi8KKy8qIElmIHRoZSBvYmplY3QgaXMgc3ViY2xhc3Mgb2Ygc3RyaW5nLCBjcmVhdGUgYSBjb3B5ICovCitQeV9MT0NBTChQeVN0cmluZ09iamVjdCAqKQorcmV0dXJuX3NlbGYoUHlTdHJpbmdPYmplY3QgKnNlbGYpCit7CisgICAgaWYgKFB5U3RyaW5nX0NoZWNrRXhhY3Qoc2VsZikpIHsKKyAgICAgICAgUHlfSU5DUkVGKHNlbGYpOworICAgICAgICByZXR1cm4gc2VsZjsKKyAgICB9CisgICAgcmV0dXJuIChQeVN0cmluZ09iamVjdCAqKVB5U3RyaW5nX0Zyb21TdHJpbmdBbmRTaXplKAorICAgICAgICBQeVN0cmluZ19BU19TVFJJTkcoc2VsZiksCisgICAgICAgIFB5U3RyaW5nX0dFVF9TSVpFKHNlbGYpKTsKK30KKworUHlfTE9DQUxfSU5MSU5FKFB5X3NzaXplX3QpCitjb3VudGNoYXIoY29uc3QgY2hhciAqdGFyZ2V0LCBpbnQgdGFyZ2V0X2xlbiwgY2hhciBjLCBQeV9zc2l6ZV90IG1heGNvdW50KQoreworICAgIFB5X3NzaXplX3QgY291bnQ9MDsKKyAgICBjb25zdCBjaGFyICpzdGFydD10YXJnZXQ7CisgICAgY29uc3QgY2hhciAqZW5kPXRhcmdldCt0YXJnZXRfbGVuOworCisgICAgd2hpbGUgKCAoc3RhcnQ9ZmluZGNoYXIoc3RhcnQsIGVuZC1zdGFydCwgYykpICE9IE5VTEwgKSB7CisgICAgICAgIGNvdW50Kys7CisgICAgICAgIGlmIChjb3VudCA+PSBtYXhjb3VudCkKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICBzdGFydCArPSAxOworICAgIH0KKyAgICByZXR1cm4gY291bnQ7Cit9CisKKworLyogQWxnb3JpdGhtcyBmb3IgZGlmZmVyZW50IGNhc2VzIG9mIHN0cmluZyByZXBsYWNlbWVudCAqLworCisvKiBsZW4oc2VsZik+PTEsIGZyb209IiIsIGxlbih0byk+PTEsIG1heGNvdW50Pj0xICovCitQeV9MT0NBTChQeVN0cmluZ09iamVjdCAqKQorcmVwbGFjZV9pbnRlcmxlYXZlKFB5U3RyaW5nT2JqZWN0ICpzZWxmLAorICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgKnRvX3MsIFB5X3NzaXplX3QgdG9fbGVuLAorICAgICAgICAgICAgICAgICAgIFB5X3NzaXplX3QgbWF4Y291bnQpCit7CisgICAgY2hhciAqc2VsZl9zLCAqcmVzdWx0X3M7CisgICAgUHlfc3NpemVfdCBzZWxmX2xlbiwgcmVzdWx0X2xlbjsKKyAgICBQeV9zc2l6ZV90IGNvdW50LCBpLCBwcm9kdWN0OworICAgIFB5U3RyaW5nT2JqZWN0ICpyZXN1bHQ7CisKKyAgICBzZWxmX2xlbiA9IFB5U3RyaW5nX0dFVF9TSVpFKHNlbGYpOworCisgICAgLyogMSBhdCB0aGUgZW5kIHBsdXMgMSBhZnRlciBldmVyeSBjaGFyYWN0ZXIgKi8KKyAgICBjb3VudCA9IHNlbGZfbGVuKzE7CisgICAgaWYgKG1heGNvdW50IDwgY291bnQpCisgICAgICAgIGNvdW50ID0gbWF4Y291bnQ7CisKKyAgICAvKiBDaGVjayBmb3Igb3ZlcmZsb3cgKi8KKyAgICAvKiAgIHJlc3VsdF9sZW4gPSBjb3VudCAqIHRvX2xlbiArIHNlbGZfbGVuOyAqLworICAgIHByb2R1Y3QgPSBjb3VudCAqIHRvX2xlbjsKKyAgICBpZiAocHJvZHVjdCAvIHRvX2xlbiAhPSBjb3VudCkgeworICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfT3ZlcmZsb3dFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICJyZXBsYWNlIHN0cmluZyBpcyB0b28gbG9uZyIpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgcmVzdWx0X2xlbiA9IHByb2R1Y3QgKyBzZWxmX2xlbjsKKyAgICBpZiAocmVzdWx0X2xlbiA8IDApIHsKKyAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX092ZXJmbG93RXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAgICAicmVwbGFjZSBzdHJpbmcgaXMgdG9vIGxvbmciKTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorCisgICAgaWYgKCEgKHJlc3VsdCA9IChQeVN0cmluZ09iamVjdCAqKQorICAgICAgICAgICAgICAgICAgICAgUHlTdHJpbmdfRnJvbVN0cmluZ0FuZFNpemUoTlVMTCwgcmVzdWx0X2xlbikpICkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisKKyAgICBzZWxmX3MgPSBQeVN0cmluZ19BU19TVFJJTkcoc2VsZik7CisgICAgcmVzdWx0X3MgPSBQeVN0cmluZ19BU19TVFJJTkcocmVzdWx0KTsKKworICAgIC8qIFRPRE86IHNwZWNpYWwgY2FzZSBzaW5nbGUgY2hhcmFjdGVyLCB3aGljaCBkb2Vzbid0IG5lZWQgbWVtY3B5ICovCisKKyAgICAvKiBMYXkgdGhlIGZpcnN0IG9uZSBkb3duIChndWFyYW50ZWVkIHRoaXMgd2lsbCBvY2N1cikgKi8KKyAgICBQeV9NRU1DUFkocmVzdWx0X3MsIHRvX3MsIHRvX2xlbik7CisgICAgcmVzdWx0X3MgKz0gdG9fbGVuOworICAgIGNvdW50IC09IDE7CisKKyAgICBmb3IgKGk9MDsgaTxjb3VudDsgaSsrKSB7CisgICAgICAgICpyZXN1bHRfcysrID0gKnNlbGZfcysrOworICAgICAgICBQeV9NRU1DUFkocmVzdWx0X3MsIHRvX3MsIHRvX2xlbik7CisgICAgICAgIHJlc3VsdF9zICs9IHRvX2xlbjsKKyAgICB9CisKKyAgICAvKiBDb3B5IHRoZSByZXN0IG9mIHRoZSBvcmlnaW5hbCBzdHJpbmcgKi8KKyAgICBQeV9NRU1DUFkocmVzdWx0X3MsIHNlbGZfcywgc2VsZl9sZW4taSk7CisKKyAgICByZXR1cm4gcmVzdWx0OworfQorCisvKiBTcGVjaWFsIGNhc2UgZm9yIGRlbGV0aW5nIGEgc2luZ2xlIGNoYXJhY3RlciAqLworLyogbGVuKHNlbGYpPj0xLCBsZW4oZnJvbSk9PTEsIHRvPSIiLCBtYXhjb3VudD49MSAqLworUHlfTE9DQUwoUHlTdHJpbmdPYmplY3QgKikKK3JlcGxhY2VfZGVsZXRlX3NpbmdsZV9jaGFyYWN0ZXIoUHlTdHJpbmdPYmplY3QgKnNlbGYsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYXIgZnJvbV9jLCBQeV9zc2l6ZV90IG1heGNvdW50KQoreworICAgIGNoYXIgKnNlbGZfcywgKnJlc3VsdF9zOworICAgIGNoYXIgKnN0YXJ0LCAqbmV4dCwgKmVuZDsKKyAgICBQeV9zc2l6ZV90IHNlbGZfbGVuLCByZXN1bHRfbGVuOworICAgIFB5X3NzaXplX3QgY291bnQ7CisgICAgUHlTdHJpbmdPYmplY3QgKnJlc3VsdDsKKworICAgIHNlbGZfbGVuID0gUHlTdHJpbmdfR0VUX1NJWkUoc2VsZik7CisgICAgc2VsZl9zID0gUHlTdHJpbmdfQVNfU1RSSU5HKHNlbGYpOworCisgICAgY291bnQgPSBjb3VudGNoYXIoc2VsZl9zLCBzZWxmX2xlbiwgZnJvbV9jLCBtYXhjb3VudCk7CisgICAgaWYgKGNvdW50ID09IDApIHsKKyAgICAgICAgcmV0dXJuIHJldHVybl9zZWxmKHNlbGYpOworICAgIH0KKworICAgIHJlc3VsdF9sZW4gPSBzZWxmX2xlbiAtIGNvdW50OyAgLyogZnJvbV9sZW4gPT0gMSAqLworICAgIGFzc2VydChyZXN1bHRfbGVuPj0wKTsKKworICAgIGlmICggKHJlc3VsdCA9IChQeVN0cmluZ09iamVjdCAqKQorICAgICAgICAgICAgICAgICAgICBQeVN0cmluZ19Gcm9tU3RyaW5nQW5kU2l6ZShOVUxMLCByZXN1bHRfbGVuKSkgPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgcmVzdWx0X3MgPSBQeVN0cmluZ19BU19TVFJJTkcocmVzdWx0KTsKKworICAgIHN0YXJ0ID0gc2VsZl9zOworICAgIGVuZCA9IHNlbGZfcyArIHNlbGZfbGVuOworICAgIHdoaWxlIChjb3VudC0tID4gMCkgeworICAgICAgICBuZXh0ID0gZmluZGNoYXIoc3RhcnQsIGVuZC1zdGFydCwgZnJvbV9jKTsKKyAgICAgICAgaWYgKG5leHQgPT0gTlVMTCkKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICBQeV9NRU1DUFkocmVzdWx0X3MsIHN0YXJ0LCBuZXh0LXN0YXJ0KTsKKyAgICAgICAgcmVzdWx0X3MgKz0gKG5leHQtc3RhcnQpOworICAgICAgICBzdGFydCA9IG5leHQrMTsKKyAgICB9CisgICAgUHlfTUVNQ1BZKHJlc3VsdF9zLCBzdGFydCwgZW5kLXN0YXJ0KTsKKworICAgIHJldHVybiByZXN1bHQ7Cit9CisKKy8qIGxlbihzZWxmKT49MSwgbGVuKGZyb20pPj0yLCB0bz0iIiwgbWF4Y291bnQ+PTEgKi8KKworUHlfTE9DQUwoUHlTdHJpbmdPYmplY3QgKikKK3JlcGxhY2VfZGVsZXRlX3N1YnN0cmluZyhQeVN0cmluZ09iamVjdCAqc2VsZiwKKyAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyICpmcm9tX3MsIFB5X3NzaXplX3QgZnJvbV9sZW4sCisgICAgICAgICAgICAgICAgICAgICAgICAgUHlfc3NpemVfdCBtYXhjb3VudCkgeworICAgIGNoYXIgKnNlbGZfcywgKnJlc3VsdF9zOworICAgIGNoYXIgKnN0YXJ0LCAqbmV4dCwgKmVuZDsKKyAgICBQeV9zc2l6ZV90IHNlbGZfbGVuLCByZXN1bHRfbGVuOworICAgIFB5X3NzaXplX3QgY291bnQsIG9mZnNldDsKKyAgICBQeVN0cmluZ09iamVjdCAqcmVzdWx0OworCisgICAgc2VsZl9sZW4gPSBQeVN0cmluZ19HRVRfU0laRShzZWxmKTsKKyAgICBzZWxmX3MgPSBQeVN0cmluZ19BU19TVFJJTkcoc2VsZik7CisKKyAgICBjb3VudCA9IHN0cmluZ2xpYl9jb3VudChzZWxmX3MsIHNlbGZfbGVuLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZyb21fcywgZnJvbV9sZW4sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWF4Y291bnQpOworCisgICAgaWYgKGNvdW50ID09IDApIHsKKyAgICAgICAgLyogbm8gbWF0Y2hlcyAqLworICAgICAgICByZXR1cm4gcmV0dXJuX3NlbGYoc2VsZik7CisgICAgfQorCisgICAgcmVzdWx0X2xlbiA9IHNlbGZfbGVuIC0gKGNvdW50ICogZnJvbV9sZW4pOworICAgIGFzc2VydCAocmVzdWx0X2xlbj49MCk7CisKKyAgICBpZiAoIChyZXN1bHQgPSAoUHlTdHJpbmdPYmplY3QgKikKKyAgICAgICAgICBQeVN0cmluZ19Gcm9tU3RyaW5nQW5kU2l6ZShOVUxMLCByZXN1bHRfbGVuKSkgPT0gTlVMTCApCisgICAgICAgIHJldHVybiBOVUxMOworCisgICAgcmVzdWx0X3MgPSBQeVN0cmluZ19BU19TVFJJTkcocmVzdWx0KTsKKworICAgIHN0YXJ0ID0gc2VsZl9zOworICAgIGVuZCA9IHNlbGZfcyArIHNlbGZfbGVuOworICAgIHdoaWxlIChjb3VudC0tID4gMCkgeworICAgICAgICBvZmZzZXQgPSBzdHJpbmdsaWJfZmluZChzdGFydCwgZW5kLXN0YXJ0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmcm9tX3MsIGZyb21fbGVuLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwKTsKKyAgICAgICAgaWYgKG9mZnNldCA9PSAtMSkKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICBuZXh0ID0gc3RhcnQgKyBvZmZzZXQ7CisKKyAgICAgICAgUHlfTUVNQ1BZKHJlc3VsdF9zLCBzdGFydCwgbmV4dC1zdGFydCk7CisKKyAgICAgICAgcmVzdWx0X3MgKz0gKG5leHQtc3RhcnQpOworICAgICAgICBzdGFydCA9IG5leHQrZnJvbV9sZW47CisgICAgfQorICAgIFB5X01FTUNQWShyZXN1bHRfcywgc3RhcnQsIGVuZC1zdGFydCk7CisgICAgcmV0dXJuIHJlc3VsdDsKK30KKworLyogbGVuKHNlbGYpPj0xLCBsZW4oZnJvbSk9PWxlbih0byk9PTEsIG1heGNvdW50Pj0xICovCitQeV9MT0NBTChQeVN0cmluZ09iamVjdCAqKQorcmVwbGFjZV9zaW5nbGVfY2hhcmFjdGVyX2luX3BsYWNlKFB5U3RyaW5nT2JqZWN0ICpzZWxmLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNoYXIgZnJvbV9jLCBjaGFyIHRvX2MsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHlfc3NpemVfdCBtYXhjb3VudCkKK3sKKyAgICBjaGFyICpzZWxmX3MsICpyZXN1bHRfcywgKnN0YXJ0LCAqZW5kLCAqbmV4dDsKKyAgICBQeV9zc2l6ZV90IHNlbGZfbGVuOworICAgIFB5U3RyaW5nT2JqZWN0ICpyZXN1bHQ7CisKKyAgICAvKiBUaGUgcmVzdWx0IHN0cmluZyB3aWxsIGJlIHRoZSBzYW1lIHNpemUgKi8KKyAgICBzZWxmX3MgPSBQeVN0cmluZ19BU19TVFJJTkcoc2VsZik7CisgICAgc2VsZl9sZW4gPSBQeVN0cmluZ19HRVRfU0laRShzZWxmKTsKKworICAgIG5leHQgPSBmaW5kY2hhcihzZWxmX3MsIHNlbGZfbGVuLCBmcm9tX2MpOworCisgICAgaWYgKG5leHQgPT0gTlVMTCkgeworICAgICAgICAvKiBObyBtYXRjaGVzOyByZXR1cm4gdGhlIG9yaWdpbmFsIHN0cmluZyAqLworICAgICAgICByZXR1cm4gcmV0dXJuX3NlbGYoc2VsZik7CisgICAgfQorCisgICAgLyogTmVlZCB0byBtYWtlIGEgbmV3IHN0cmluZyAqLworICAgIHJlc3VsdCA9IChQeVN0cmluZ09iamVjdCAqKSBQeVN0cmluZ19Gcm9tU3RyaW5nQW5kU2l6ZShOVUxMLCBzZWxmX2xlbik7CisgICAgaWYgKHJlc3VsdCA9PSBOVUxMKQorICAgICAgICByZXR1cm4gTlVMTDsKKyAgICByZXN1bHRfcyA9IFB5U3RyaW5nX0FTX1NUUklORyhyZXN1bHQpOworICAgIFB5X01FTUNQWShyZXN1bHRfcywgc2VsZl9zLCBzZWxmX2xlbik7CisKKyAgICAvKiBjaGFuZ2UgZXZlcnl0aGluZyBpbi1wbGFjZSwgc3RhcnRpbmcgd2l0aCB0aGlzIG9uZSAqLworICAgIHN0YXJ0ID0gIHJlc3VsdF9zICsgKG5leHQtc2VsZl9zKTsKKyAgICAqc3RhcnQgPSB0b19jOworICAgIHN0YXJ0Kys7CisgICAgZW5kID0gcmVzdWx0X3MgKyBzZWxmX2xlbjsKKworICAgIHdoaWxlICgtLW1heGNvdW50ID4gMCkgeworICAgICAgICBuZXh0ID0gZmluZGNoYXIoc3RhcnQsIGVuZC1zdGFydCwgZnJvbV9jKTsKKyAgICAgICAgaWYgKG5leHQgPT0gTlVMTCkKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICAqbmV4dCA9IHRvX2M7CisgICAgICAgIHN0YXJ0ID0gbmV4dCsxOworICAgIH0KKworICAgIHJldHVybiByZXN1bHQ7Cit9CisKKy8qIGxlbihzZWxmKT49MSwgbGVuKGZyb20pPT1sZW4odG8pPj0yLCBtYXhjb3VudD49MSAqLworUHlfTE9DQUwoUHlTdHJpbmdPYmplY3QgKikKK3JlcGxhY2Vfc3Vic3RyaW5nX2luX3BsYWNlKFB5U3RyaW5nT2JqZWN0ICpzZWxmLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciAqZnJvbV9zLCBQeV9zc2l6ZV90IGZyb21fbGVuLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciAqdG9fcywgUHlfc3NpemVfdCB0b19sZW4sCisgICAgICAgICAgICAgICAgICAgICAgICAgICBQeV9zc2l6ZV90IG1heGNvdW50KQoreworICAgIGNoYXIgKnJlc3VsdF9zLCAqc3RhcnQsICplbmQ7CisgICAgY2hhciAqc2VsZl9zOworICAgIFB5X3NzaXplX3Qgc2VsZl9sZW4sIG9mZnNldDsKKyAgICBQeVN0cmluZ09iamVjdCAqcmVzdWx0OworCisgICAgLyogVGhlIHJlc3VsdCBzdHJpbmcgd2lsbCBiZSB0aGUgc2FtZSBzaXplICovCisKKyAgICBzZWxmX3MgPSBQeVN0cmluZ19BU19TVFJJTkcoc2VsZik7CisgICAgc2VsZl9sZW4gPSBQeVN0cmluZ19HRVRfU0laRShzZWxmKTsKKworICAgIG9mZnNldCA9IHN0cmluZ2xpYl9maW5kKHNlbGZfcywgc2VsZl9sZW4sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgZnJvbV9zLCBmcm9tX2xlbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAwKTsKKyAgICBpZiAob2Zmc2V0ID09IC0xKSB7CisgICAgICAgIC8qIE5vIG1hdGNoZXM7IHJldHVybiB0aGUgb3JpZ2luYWwgc3RyaW5nICovCisgICAgICAgIHJldHVybiByZXR1cm5fc2VsZihzZWxmKTsKKyAgICB9CisKKyAgICAvKiBOZWVkIHRvIG1ha2UgYSBuZXcgc3RyaW5nICovCisgICAgcmVzdWx0ID0gKFB5U3RyaW5nT2JqZWN0ICopIFB5U3RyaW5nX0Zyb21TdHJpbmdBbmRTaXplKE5VTEwsIHNlbGZfbGVuKTsKKyAgICBpZiAocmVzdWx0ID09IE5VTEwpCisgICAgICAgIHJldHVybiBOVUxMOworICAgIHJlc3VsdF9zID0gUHlTdHJpbmdfQVNfU1RSSU5HKHJlc3VsdCk7CisgICAgUHlfTUVNQ1BZKHJlc3VsdF9zLCBzZWxmX3MsIHNlbGZfbGVuKTsKKworICAgIC8qIGNoYW5nZSBldmVyeXRoaW5nIGluLXBsYWNlLCBzdGFydGluZyB3aXRoIHRoaXMgb25lICovCisgICAgc3RhcnQgPSAgcmVzdWx0X3MgKyBvZmZzZXQ7CisgICAgUHlfTUVNQ1BZKHN0YXJ0LCB0b19zLCBmcm9tX2xlbik7CisgICAgc3RhcnQgKz0gZnJvbV9sZW47CisgICAgZW5kID0gcmVzdWx0X3MgKyBzZWxmX2xlbjsKKworICAgIHdoaWxlICggLS1tYXhjb3VudCA+IDApIHsKKyAgICAgICAgb2Zmc2V0ID0gc3RyaW5nbGliX2ZpbmQoc3RhcnQsIGVuZC1zdGFydCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZnJvbV9zLCBmcm9tX2xlbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCk7CisgICAgICAgIGlmIChvZmZzZXQ9PS0xKQorICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIFB5X01FTUNQWShzdGFydCtvZmZzZXQsIHRvX3MsIGZyb21fbGVuKTsKKyAgICAgICAgc3RhcnQgKz0gb2Zmc2V0K2Zyb21fbGVuOworICAgIH0KKworICAgIHJldHVybiByZXN1bHQ7Cit9CisKKy8qIGxlbihzZWxmKT49MSwgbGVuKGZyb20pPT0xLCBsZW4odG8pPj0yLCBtYXhjb3VudD49MSAqLworUHlfTE9DQUwoUHlTdHJpbmdPYmplY3QgKikKK3JlcGxhY2Vfc2luZ2xlX2NoYXJhY3RlcihQeVN0cmluZ09iamVjdCAqc2VsZiwKKyAgICAgICAgICAgICAgICAgICAgICAgICBjaGFyIGZyb21fYywKKyAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyICp0b19zLCBQeV9zc2l6ZV90IHRvX2xlbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICBQeV9zc2l6ZV90IG1heGNvdW50KQoreworICAgIGNoYXIgKnNlbGZfcywgKnJlc3VsdF9zOworICAgIGNoYXIgKnN0YXJ0LCAqbmV4dCwgKmVuZDsKKyAgICBQeV9zc2l6ZV90IHNlbGZfbGVuLCByZXN1bHRfbGVuOworICAgIFB5X3NzaXplX3QgY291bnQsIHByb2R1Y3Q7CisgICAgUHlTdHJpbmdPYmplY3QgKnJlc3VsdDsKKworICAgIHNlbGZfcyA9IFB5U3RyaW5nX0FTX1NUUklORyhzZWxmKTsKKyAgICBzZWxmX2xlbiA9IFB5U3RyaW5nX0dFVF9TSVpFKHNlbGYpOworCisgICAgY291bnQgPSBjb3VudGNoYXIoc2VsZl9zLCBzZWxmX2xlbiwgZnJvbV9jLCBtYXhjb3VudCk7CisgICAgaWYgKGNvdW50ID09IDApIHsKKyAgICAgICAgLyogbm8gbWF0Y2hlcywgcmV0dXJuIHVuY2hhbmdlZCAqLworICAgICAgICByZXR1cm4gcmV0dXJuX3NlbGYoc2VsZik7CisgICAgfQorCisgICAgLyogdXNlIHRoZSBkaWZmZXJlbmNlIGJldHdlZW4gY3VycmVudCBhbmQgbmV3LCBoZW5jZSB0aGUgIi0xIiAqLworICAgIC8qICAgcmVzdWx0X2xlbiA9IHNlbGZfbGVuICsgY291bnQgKiAodG9fbGVuLTEpICAqLworICAgIHByb2R1Y3QgPSBjb3VudCAqICh0b19sZW4tMSk7CisgICAgaWYgKHByb2R1Y3QgLyAodG9fbGVuLTEpICE9IGNvdW50KSB7CisgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19PdmVyZmxvd0Vycm9yLCAicmVwbGFjZSBzdHJpbmcgaXMgdG9vIGxvbmciKTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIHJlc3VsdF9sZW4gPSBzZWxmX2xlbiArIHByb2R1Y3Q7CisgICAgaWYgKHJlc3VsdF9sZW4gPCAwKSB7CisgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19PdmVyZmxvd0Vycm9yLCAicmVwbGFjZSBzdHJpbmcgaXMgdG9vIGxvbmciKTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorCisgICAgaWYgKCAocmVzdWx0ID0gKFB5U3RyaW5nT2JqZWN0ICopCisgICAgICAgICAgUHlTdHJpbmdfRnJvbVN0cmluZ0FuZFNpemUoTlVMTCwgcmVzdWx0X2xlbikpID09IE5VTEwpCisgICAgICAgIHJldHVybiBOVUxMOworICAgIHJlc3VsdF9zID0gUHlTdHJpbmdfQVNfU1RSSU5HKHJlc3VsdCk7CisKKyAgICBzdGFydCA9IHNlbGZfczsKKyAgICBlbmQgPSBzZWxmX3MgKyBzZWxmX2xlbjsKKyAgICB3aGlsZSAoY291bnQtLSA+IDApIHsKKyAgICAgICAgbmV4dCA9IGZpbmRjaGFyKHN0YXJ0LCBlbmQtc3RhcnQsIGZyb21fYyk7CisgICAgICAgIGlmIChuZXh0ID09IE5VTEwpCisgICAgICAgICAgICBicmVhazsKKworICAgICAgICBpZiAobmV4dCA9PSBzdGFydCkgeworICAgICAgICAgICAgLyogcmVwbGFjZSB3aXRoIHRoZSAndG8nICovCisgICAgICAgICAgICBQeV9NRU1DUFkocmVzdWx0X3MsIHRvX3MsIHRvX2xlbik7CisgICAgICAgICAgICByZXN1bHRfcyArPSB0b19sZW47CisgICAgICAgICAgICBzdGFydCArPSAxOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgLyogY29weSB0aGUgdW5jaGFuZ2VkIG9sZCB0aGVuIHRoZSAndG8nICovCisgICAgICAgICAgICBQeV9NRU1DUFkocmVzdWx0X3MsIHN0YXJ0LCBuZXh0LXN0YXJ0KTsKKyAgICAgICAgICAgIHJlc3VsdF9zICs9IChuZXh0LXN0YXJ0KTsKKyAgICAgICAgICAgIFB5X01FTUNQWShyZXN1bHRfcywgdG9fcywgdG9fbGVuKTsKKyAgICAgICAgICAgIHJlc3VsdF9zICs9IHRvX2xlbjsKKyAgICAgICAgICAgIHN0YXJ0ID0gbmV4dCsxOworICAgICAgICB9CisgICAgfQorICAgIC8qIENvcHkgdGhlIHJlbWFpbmRlciBvZiB0aGUgcmVtYWluaW5nIHN0cmluZyAqLworICAgIFB5X01FTUNQWShyZXN1bHRfcywgc3RhcnQsIGVuZC1zdGFydCk7CisKKyAgICByZXR1cm4gcmVzdWx0OworfQorCisvKiBsZW4oc2VsZik+PTEsIGxlbihmcm9tKT49MiwgbGVuKHRvKT49MiwgbWF4Y291bnQ+PTEgKi8KK1B5X0xPQ0FMKFB5U3RyaW5nT2JqZWN0ICopCityZXBsYWNlX3N1YnN0cmluZyhQeVN0cmluZ09iamVjdCAqc2VsZiwKKyAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgKmZyb21fcywgUHlfc3NpemVfdCBmcm9tX2xlbiwKKyAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgKnRvX3MsIFB5X3NzaXplX3QgdG9fbGVuLAorICAgICAgICAgICAgICAgICAgUHlfc3NpemVfdCBtYXhjb3VudCkgeworICAgIGNoYXIgKnNlbGZfcywgKnJlc3VsdF9zOworICAgIGNoYXIgKnN0YXJ0LCAqbmV4dCwgKmVuZDsKKyAgICBQeV9zc2l6ZV90IHNlbGZfbGVuLCByZXN1bHRfbGVuOworICAgIFB5X3NzaXplX3QgY291bnQsIG9mZnNldCwgcHJvZHVjdDsKKyAgICBQeVN0cmluZ09iamVjdCAqcmVzdWx0OworCisgICAgc2VsZl9zID0gUHlTdHJpbmdfQVNfU1RSSU5HKHNlbGYpOworICAgIHNlbGZfbGVuID0gUHlTdHJpbmdfR0VUX1NJWkUoc2VsZik7CisKKyAgICBjb3VudCA9IHN0cmluZ2xpYl9jb3VudChzZWxmX3MsIHNlbGZfbGVuLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZyb21fcywgZnJvbV9sZW4sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgbWF4Y291bnQpOworCisgICAgaWYgKGNvdW50ID09IDApIHsKKyAgICAgICAgLyogbm8gbWF0Y2hlcywgcmV0dXJuIHVuY2hhbmdlZCAqLworICAgICAgICByZXR1cm4gcmV0dXJuX3NlbGYoc2VsZik7CisgICAgfQorCisgICAgLyogQ2hlY2sgZm9yIG92ZXJmbG93ICovCisgICAgLyogICAgcmVzdWx0X2xlbiA9IHNlbGZfbGVuICsgY291bnQgKiAodG9fbGVuLWZyb21fbGVuKSAqLworICAgIHByb2R1Y3QgPSBjb3VudCAqICh0b19sZW4tZnJvbV9sZW4pOworICAgIGlmIChwcm9kdWN0IC8gKHRvX2xlbi1mcm9tX2xlbikgIT0gY291bnQpIHsKKyAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX092ZXJmbG93RXJyb3IsICJyZXBsYWNlIHN0cmluZyBpcyB0b28gbG9uZyIpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgcmVzdWx0X2xlbiA9IHNlbGZfbGVuICsgcHJvZHVjdDsKKyAgICBpZiAocmVzdWx0X2xlbiA8IDApIHsKKyAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX092ZXJmbG93RXJyb3IsICJyZXBsYWNlIHN0cmluZyBpcyB0b28gbG9uZyIpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisKKyAgICBpZiAoIChyZXN1bHQgPSAoUHlTdHJpbmdPYmplY3QgKikKKyAgICAgICAgICBQeVN0cmluZ19Gcm9tU3RyaW5nQW5kU2l6ZShOVUxMLCByZXN1bHRfbGVuKSkgPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgcmVzdWx0X3MgPSBQeVN0cmluZ19BU19TVFJJTkcocmVzdWx0KTsKKworICAgIHN0YXJ0ID0gc2VsZl9zOworICAgIGVuZCA9IHNlbGZfcyArIHNlbGZfbGVuOworICAgIHdoaWxlIChjb3VudC0tID4gMCkgeworICAgICAgICBvZmZzZXQgPSBzdHJpbmdsaWJfZmluZChzdGFydCwgZW5kLXN0YXJ0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmcm9tX3MsIGZyb21fbGVuLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAwKTsKKyAgICAgICAgaWYgKG9mZnNldCA9PSAtMSkKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICBuZXh0ID0gc3RhcnQrb2Zmc2V0OworICAgICAgICBpZiAobmV4dCA9PSBzdGFydCkgeworICAgICAgICAgICAgLyogcmVwbGFjZSB3aXRoIHRoZSAndG8nICovCisgICAgICAgICAgICBQeV9NRU1DUFkocmVzdWx0X3MsIHRvX3MsIHRvX2xlbik7CisgICAgICAgICAgICByZXN1bHRfcyArPSB0b19sZW47CisgICAgICAgICAgICBzdGFydCArPSBmcm9tX2xlbjsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAgICAgIC8qIGNvcHkgdGhlIHVuY2hhbmdlZCBvbGQgdGhlbiB0aGUgJ3RvJyAqLworICAgICAgICAgICAgUHlfTUVNQ1BZKHJlc3VsdF9zLCBzdGFydCwgbmV4dC1zdGFydCk7CisgICAgICAgICAgICByZXN1bHRfcyArPSAobmV4dC1zdGFydCk7CisgICAgICAgICAgICBQeV9NRU1DUFkocmVzdWx0X3MsIHRvX3MsIHRvX2xlbik7CisgICAgICAgICAgICByZXN1bHRfcyArPSB0b19sZW47CisgICAgICAgICAgICBzdGFydCA9IG5leHQrZnJvbV9sZW47CisgICAgICAgIH0KKyAgICB9CisgICAgLyogQ29weSB0aGUgcmVtYWluZGVyIG9mIHRoZSByZW1haW5pbmcgc3RyaW5nICovCisgICAgUHlfTUVNQ1BZKHJlc3VsdF9zLCBzdGFydCwgZW5kLXN0YXJ0KTsKKworICAgIHJldHVybiByZXN1bHQ7Cit9CisKKworUHlfTE9DQUwoUHlTdHJpbmdPYmplY3QgKikKK3JlcGxhY2UoUHlTdHJpbmdPYmplY3QgKnNlbGYsCisgICAgY29uc3QgY2hhciAqZnJvbV9zLCBQeV9zc2l6ZV90IGZyb21fbGVuLAorICAgIGNvbnN0IGNoYXIgKnRvX3MsIFB5X3NzaXplX3QgdG9fbGVuLAorICAgIFB5X3NzaXplX3QgbWF4Y291bnQpCit7CisgICAgaWYgKG1heGNvdW50IDwgMCkgeworICAgICAgICBtYXhjb3VudCA9IFBZX1NTSVpFX1RfTUFYOworICAgIH0gZWxzZSBpZiAobWF4Y291bnQgPT0gMCB8fCBQeVN0cmluZ19HRVRfU0laRShzZWxmKSA9PSAwKSB7CisgICAgICAgIC8qIG5vdGhpbmcgdG8gZG87IHJldHVybiB0aGUgb3JpZ2luYWwgc3RyaW5nICovCisgICAgICAgIHJldHVybiByZXR1cm5fc2VsZihzZWxmKTsKKyAgICB9CisKKyAgICBpZiAobWF4Y291bnQgPT0gMCB8fAorICAgICAgICAoZnJvbV9sZW4gPT0gMCAmJiB0b19sZW4gPT0gMCkpIHsKKyAgICAgICAgLyogbm90aGluZyB0byBkbzsgcmV0dXJuIHRoZSBvcmlnaW5hbCBzdHJpbmcgKi8KKyAgICAgICAgcmV0dXJuIHJldHVybl9zZWxmKHNlbGYpOworICAgIH0KKworICAgIC8qIEhhbmRsZSB6ZXJvLWxlbmd0aCBzcGVjaWFsIGNhc2VzICovCisKKyAgICBpZiAoZnJvbV9sZW4gPT0gMCkgeworICAgICAgICAvKiBpbnNlcnQgdGhlICd0bycgc3RyaW5nIGV2ZXJ5d2hlcmUuICAgKi8KKyAgICAgICAgLyogICAgPj4+ICJQeXRob24iLnJlcGxhY2UoIiIsICIuIikgICAgICovCisgICAgICAgIC8qICAgICcuUC55LnQuaC5vLm4uJyAgICAgICAgICAgICAgICAgICAqLworICAgICAgICByZXR1cm4gcmVwbGFjZV9pbnRlcmxlYXZlKHNlbGYsIHRvX3MsIHRvX2xlbiwgbWF4Y291bnQpOworICAgIH0KKworICAgIC8qIEV4Y2VwdCBmb3IgIiIucmVwbGFjZSgiIiwgIkEiKSA9PSAiQSIgdGhlcmUgaXMgbm8gd2F5IGJleW9uZCB0aGlzICovCisgICAgLyogcG9pbnQgZm9yIGFuIGVtcHR5IHNlbGYgc3RyaW5nIHRvIGdlbmVyYXRlIGEgbm9uLWVtcHR5IHN0cmluZyAqLworICAgIC8qIFNwZWNpYWwgY2FzZSBzbyB0aGUgcmVtYWluaW5nIGNvZGUgYWx3YXlzIGdldHMgYSBub24tZW1wdHkgc3RyaW5nICovCisgICAgaWYgKFB5U3RyaW5nX0dFVF9TSVpFKHNlbGYpID09IDApIHsKKyAgICAgICAgcmV0dXJuIHJldHVybl9zZWxmKHNlbGYpOworICAgIH0KKworICAgIGlmICh0b19sZW4gPT0gMCkgeworICAgICAgICAvKiBkZWxldGUgYWxsIG9jY3VyYW5jZXMgb2YgJ2Zyb20nIHN0cmluZyAqLworICAgICAgICBpZiAoZnJvbV9sZW4gPT0gMSkgeworICAgICAgICAgICAgcmV0dXJuIHJlcGxhY2VfZGVsZXRlX3NpbmdsZV9jaGFyYWN0ZXIoCisgICAgICAgICAgICAgICAgc2VsZiwgZnJvbV9zWzBdLCBtYXhjb3VudCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICByZXR1cm4gcmVwbGFjZV9kZWxldGVfc3Vic3RyaW5nKHNlbGYsIGZyb21fcywgZnJvbV9sZW4sIG1heGNvdW50KTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qIEhhbmRsZSBzcGVjaWFsIGNhc2Ugd2hlcmUgYm90aCBzdHJpbmdzIGhhdmUgdGhlIHNhbWUgbGVuZ3RoICovCisKKyAgICBpZiAoZnJvbV9sZW4gPT0gdG9fbGVuKSB7CisgICAgICAgIGlmIChmcm9tX2xlbiA9PSAxKSB7CisgICAgICAgICAgICByZXR1cm4gcmVwbGFjZV9zaW5nbGVfY2hhcmFjdGVyX2luX3BsYWNlKAorICAgICAgICAgICAgICAgIHNlbGYsCisgICAgICAgICAgICAgICAgZnJvbV9zWzBdLAorICAgICAgICAgICAgICAgIHRvX3NbMF0sCisgICAgICAgICAgICAgICAgbWF4Y291bnQpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgcmV0dXJuIHJlcGxhY2Vfc3Vic3RyaW5nX2luX3BsYWNlKAorICAgICAgICAgICAgICAgIHNlbGYsIGZyb21fcywgZnJvbV9sZW4sIHRvX3MsIHRvX2xlbiwgbWF4Y291bnQpOworICAgICAgICB9CisgICAgfQorCisgICAgLyogT3RoZXJ3aXNlIHVzZSB0aGUgbW9yZSBnZW5lcmljIGFsZ29yaXRobXMgKi8KKyAgICBpZiAoZnJvbV9sZW4gPT0gMSkgeworICAgICAgICByZXR1cm4gcmVwbGFjZV9zaW5nbGVfY2hhcmFjdGVyKHNlbGYsIGZyb21fc1swXSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b19zLCB0b19sZW4sIG1heGNvdW50KTsKKyAgICB9IGVsc2UgeworICAgICAgICAvKiBsZW4oJ2Zyb20nKT49MiwgbGVuKCd0bycpPj0xICovCisgICAgICAgIHJldHVybiByZXBsYWNlX3N1YnN0cmluZyhzZWxmLCBmcm9tX3MsIGZyb21fbGVuLCB0b19zLCB0b19sZW4sIG1heGNvdW50KTsKKyAgICB9Cit9CisKK1B5RG9jX1NUUlZBUihyZXBsYWNlX19kb2NfXywKKyJTLnJlcGxhY2Uob2xkLCBuZXdbLCBjb3VudF0pIC0+IHN0cmluZ1xuXAorXG5cCitSZXR1cm4gYSBjb3B5IG9mIHN0cmluZyBTIHdpdGggYWxsIG9jY3VycmVuY2VzIG9mIHN1YnN0cmluZ1xuXAorb2xkIHJlcGxhY2VkIGJ5IG5ldy4gIElmIHRoZSBvcHRpb25hbCBhcmd1bWVudCBjb3VudCBpc1xuXAorZ2l2ZW4sIG9ubHkgdGhlIGZpcnN0IGNvdW50IG9jY3VycmVuY2VzIGFyZSByZXBsYWNlZC4iKTsKKworc3RhdGljIFB5T2JqZWN0ICoKK3N0cmluZ19yZXBsYWNlKFB5U3RyaW5nT2JqZWN0ICpzZWxmLCBQeU9iamVjdCAqYXJncykKK3sKKyAgICBQeV9zc2l6ZV90IGNvdW50ID0gLTE7CisgICAgUHlPYmplY3QgKmZyb20sICp0bzsKKyAgICBjb25zdCBjaGFyICpmcm9tX3MsICp0b19zOworICAgIFB5X3NzaXplX3QgZnJvbV9sZW4sIHRvX2xlbjsKKworICAgIGlmICghUHlBcmdfUGFyc2VUdXBsZShhcmdzLCAiT098bjpyZXBsYWNlIiwgJmZyb20sICZ0bywgJmNvdW50KSkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisKKyAgICBpZiAoUHlTdHJpbmdfQ2hlY2soZnJvbSkpIHsKKyAgICAgICAgZnJvbV9zID0gUHlTdHJpbmdfQVNfU1RSSU5HKGZyb20pOworICAgICAgICBmcm9tX2xlbiA9IFB5U3RyaW5nX0dFVF9TSVpFKGZyb20pOworICAgIH0KKyNpZmRlZiBQeV9VU0lOR19VTklDT0RFCisgICAgaWYgKFB5VW5pY29kZV9DaGVjayhmcm9tKSkKKyAgICAgICAgcmV0dXJuIFB5VW5pY29kZV9SZXBsYWNlKChQeU9iamVjdCAqKXNlbGYsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmcm9tLCB0bywgY291bnQpOworI2VuZGlmCisgICAgZWxzZSBpZiAoUHlPYmplY3RfQXNDaGFyQnVmZmVyKGZyb20sICZmcm9tX3MsICZmcm9tX2xlbikpCisgICAgICAgIHJldHVybiBOVUxMOworCisgICAgaWYgKFB5U3RyaW5nX0NoZWNrKHRvKSkgeworICAgICAgICB0b19zID0gUHlTdHJpbmdfQVNfU1RSSU5HKHRvKTsKKyAgICAgICAgdG9fbGVuID0gUHlTdHJpbmdfR0VUX1NJWkUodG8pOworICAgIH0KKyNpZmRlZiBQeV9VU0lOR19VTklDT0RFCisgICAgZWxzZSBpZiAoUHlVbmljb2RlX0NoZWNrKHRvKSkKKyAgICAgICAgcmV0dXJuIFB5VW5pY29kZV9SZXBsYWNlKChQeU9iamVjdCAqKXNlbGYsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmcm9tLCB0bywgY291bnQpOworI2VuZGlmCisgICAgZWxzZSBpZiAoUHlPYmplY3RfQXNDaGFyQnVmZmVyKHRvLCAmdG9fcywgJnRvX2xlbikpCisgICAgICAgIHJldHVybiBOVUxMOworCisgICAgcmV0dXJuIChQeU9iamVjdCAqKXJlcGxhY2UoKFB5U3RyaW5nT2JqZWN0ICopIHNlbGYsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZnJvbV9zLCBmcm9tX2xlbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0b19zLCB0b19sZW4sIGNvdW50KTsKK30KKworLyoqIEVuZCBEQUxLRSAqKi8KKworLyogTWF0Y2hlcyB0aGUgZW5kIChkaXJlY3Rpb24gPj0gMCkgb3Igc3RhcnQgKGRpcmVjdGlvbiA8IDApIG9mIHNlbGYKKyAqIGFnYWluc3Qgc3Vic3RyLCB1c2luZyB0aGUgc3RhcnQgYW5kIGVuZCBhcmd1bWVudHMuIFJldHVybnMKKyAqIC0xIG9uIGVycm9yLCAwIGlmIG5vdCBmb3VuZCBhbmQgMSBpZiBmb3VuZC4KKyAqLworUHlfTE9DQUwoaW50KQorX3N0cmluZ190YWlsbWF0Y2goUHlTdHJpbmdPYmplY3QgKnNlbGYsIFB5T2JqZWN0ICpzdWJzdHIsIFB5X3NzaXplX3Qgc3RhcnQsCisgICAgICAgICAgICAgICAgICBQeV9zc2l6ZV90IGVuZCwgaW50IGRpcmVjdGlvbikKK3sKKyAgICBQeV9zc2l6ZV90IGxlbiA9IFB5U3RyaW5nX0dFVF9TSVpFKHNlbGYpOworICAgIFB5X3NzaXplX3Qgc2xlbjsKKyAgICBjb25zdCBjaGFyKiBzdWI7CisgICAgY29uc3QgY2hhciogc3RyOworCisgICAgaWYgKFB5U3RyaW5nX0NoZWNrKHN1YnN0cikpIHsKKyAgICAgICAgc3ViID0gUHlTdHJpbmdfQVNfU1RSSU5HKHN1YnN0cik7CisgICAgICAgIHNsZW4gPSBQeVN0cmluZ19HRVRfU0laRShzdWJzdHIpOworICAgIH0KKyNpZmRlZiBQeV9VU0lOR19VTklDT0RFCisgICAgZWxzZSBpZiAoUHlVbmljb2RlX0NoZWNrKHN1YnN0cikpCisgICAgICAgIHJldHVybiBQeVVuaWNvZGVfVGFpbG1hdGNoKChQeU9iamVjdCAqKXNlbGYsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1YnN0ciwgc3RhcnQsIGVuZCwgZGlyZWN0aW9uKTsKKyNlbmRpZgorICAgIGVsc2UgaWYgKFB5T2JqZWN0X0FzQ2hhckJ1ZmZlcihzdWJzdHIsICZzdWIsICZzbGVuKSkKKyAgICAgICAgcmV0dXJuIC0xOworICAgIHN0ciA9IFB5U3RyaW5nX0FTX1NUUklORyhzZWxmKTsKKworICAgIEFESlVTVF9JTkRJQ0VTKHN0YXJ0LCBlbmQsIGxlbik7CisKKyAgICBpZiAoZGlyZWN0aW9uIDwgMCkgeworICAgICAgICAvKiBzdGFydHN3aXRoICovCisgICAgICAgIGlmIChzdGFydCtzbGVuID4gbGVuKQorICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgfSBlbHNlIHsKKyAgICAgICAgLyogZW5kc3dpdGggKi8KKyAgICAgICAgaWYgKGVuZC1zdGFydCA8IHNsZW4gfHwgc3RhcnQgPiBsZW4pCisgICAgICAgICAgICByZXR1cm4gMDsKKworICAgICAgICBpZiAoZW5kLXNsZW4gPiBzdGFydCkKKyAgICAgICAgICAgIHN0YXJ0ID0gZW5kIC0gc2xlbjsKKyAgICB9CisgICAgaWYgKGVuZC1zdGFydCA+PSBzbGVuKQorICAgICAgICByZXR1cm4gISBtZW1jbXAoc3RyK3N0YXJ0LCBzdWIsIHNsZW4pOworICAgIHJldHVybiAwOworfQorCisKK1B5RG9jX1NUUlZBUihzdGFydHN3aXRoX19kb2NfXywKKyJTLnN0YXJ0c3dpdGgocHJlZml4Wywgc3RhcnRbLCBlbmRdXSkgLT4gYm9vbFxuXAorXG5cCitSZXR1cm4gVHJ1ZSBpZiBTIHN0YXJ0cyB3aXRoIHRoZSBzcGVjaWZpZWQgcHJlZml4LCBGYWxzZSBvdGhlcndpc2UuXG5cCitXaXRoIG9wdGlvbmFsIHN0YXJ0LCB0ZXN0IFMgYmVnaW5uaW5nIGF0IHRoYXQgcG9zaXRpb24uXG5cCitXaXRoIG9wdGlvbmFsIGVuZCwgc3RvcCBjb21wYXJpbmcgUyBhdCB0aGF0IHBvc2l0aW9uLlxuXAorcHJlZml4IGNhbiBhbHNvIGJlIGEgdHVwbGUgb2Ygc3RyaW5ncyB0byB0cnkuIik7CisKK3N0YXRpYyBQeU9iamVjdCAqCitzdHJpbmdfc3RhcnRzd2l0aChQeVN0cmluZ09iamVjdCAqc2VsZiwgUHlPYmplY3QgKmFyZ3MpCit7CisgICAgUHlfc3NpemVfdCBzdGFydCA9IDA7CisgICAgUHlfc3NpemVfdCBlbmQgPSBQWV9TU0laRV9UX01BWDsKKyAgICBQeU9iamVjdCAqc3Vib2JqOworICAgIGludCByZXN1bHQ7CisKKyAgICBpZiAoIXN0cmluZ2xpYl9wYXJzZV9hcmdzX2ZpbmRzKCJzdGFydHN3aXRoIiwgYXJncywgJnN1Ym9iaiwgJnN0YXJ0LCAmZW5kKSkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgaWYgKFB5VHVwbGVfQ2hlY2soc3Vib2JqKSkgeworICAgICAgICBQeV9zc2l6ZV90IGk7CisgICAgICAgIGZvciAoaSA9IDA7IGkgPCBQeVR1cGxlX0dFVF9TSVpFKHN1Ym9iaik7IGkrKykgeworICAgICAgICAgICAgcmVzdWx0ID0gX3N0cmluZ190YWlsbWF0Y2goc2VsZiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBQeVR1cGxlX0dFVF9JVEVNKHN1Ym9iaiwgaSksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhcnQsIGVuZCwgLTEpOworICAgICAgICAgICAgaWYgKHJlc3VsdCA9PSAtMSkKKyAgICAgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgICAgIGVsc2UgaWYgKHJlc3VsdCkgeworICAgICAgICAgICAgICAgIFB5X1JFVFVSTl9UUlVFOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIFB5X1JFVFVSTl9GQUxTRTsKKyAgICB9CisgICAgcmVzdWx0ID0gX3N0cmluZ190YWlsbWF0Y2goc2VsZiwgc3Vib2JqLCBzdGFydCwgZW5kLCAtMSk7CisgICAgaWYgKHJlc3VsdCA9PSAtMSkgeworICAgICAgICBpZiAoUHlFcnJfRXhjZXB0aW9uTWF0Y2hlcyhQeUV4Y19UeXBlRXJyb3IpKQorICAgICAgICAgICAgUHlFcnJfRm9ybWF0KFB5RXhjX1R5cGVFcnJvciwgInN0YXJ0c3dpdGggZmlyc3QgYXJnIG11c3QgYmUgc3RyLCAiCisgICAgICAgICAgICAgICAgICAgICAgICAgInVuaWNvZGUsIG9yIHR1cGxlLCBub3QgJXMiLCBQeV9UWVBFKHN1Ym9iaiktPnRwX25hbWUpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgZWxzZQorICAgICAgICByZXR1cm4gUHlCb29sX0Zyb21Mb25nKHJlc3VsdCk7Cit9CisKKworUHlEb2NfU1RSVkFSKGVuZHN3aXRoX19kb2NfXywKKyJTLmVuZHN3aXRoKHN1ZmZpeFssIHN0YXJ0WywgZW5kXV0pIC0+IGJvb2xcblwKK1xuXAorUmV0dXJuIFRydWUgaWYgUyBlbmRzIHdpdGggdGhlIHNwZWNpZmllZCBzdWZmaXgsIEZhbHNlIG90aGVyd2lzZS5cblwKK1dpdGggb3B0aW9uYWwgc3RhcnQsIHRlc3QgUyBiZWdpbm5pbmcgYXQgdGhhdCBwb3NpdGlvbi5cblwKK1dpdGggb3B0aW9uYWwgZW5kLCBzdG9wIGNvbXBhcmluZyBTIGF0IHRoYXQgcG9zaXRpb24uXG5cCitzdWZmaXggY2FuIGFsc28gYmUgYSB0dXBsZSBvZiBzdHJpbmdzIHRvIHRyeS4iKTsKKworc3RhdGljIFB5T2JqZWN0ICoKK3N0cmluZ19lbmRzd2l0aChQeVN0cmluZ09iamVjdCAqc2VsZiwgUHlPYmplY3QgKmFyZ3MpCit7CisgICAgUHlfc3NpemVfdCBzdGFydCA9IDA7CisgICAgUHlfc3NpemVfdCBlbmQgPSBQWV9TU0laRV9UX01BWDsKKyAgICBQeU9iamVjdCAqc3Vib2JqOworICAgIGludCByZXN1bHQ7CisKKyAgICBpZiAoIXN0cmluZ2xpYl9wYXJzZV9hcmdzX2ZpbmRzKCJlbmRzd2l0aCIsIGFyZ3MsICZzdWJvYmosICZzdGFydCwgJmVuZCkpCisgICAgICAgIHJldHVybiBOVUxMOworICAgIGlmIChQeVR1cGxlX0NoZWNrKHN1Ym9iaikpIHsKKyAgICAgICAgUHlfc3NpemVfdCBpOworICAgICAgICBmb3IgKGkgPSAwOyBpIDwgUHlUdXBsZV9HRVRfU0laRShzdWJvYmopOyBpKyspIHsKKyAgICAgICAgICAgIHJlc3VsdCA9IF9zdHJpbmdfdGFpbG1hdGNoKHNlbGYsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHlUdXBsZV9HRVRfSVRFTShzdWJvYmosIGkpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXJ0LCBlbmQsICsxKTsKKyAgICAgICAgICAgIGlmIChyZXN1bHQgPT0gLTEpCisgICAgICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgICAgICAgICBlbHNlIGlmIChyZXN1bHQpIHsKKyAgICAgICAgICAgICAgICBQeV9SRVRVUk5fVFJVRTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBQeV9SRVRVUk5fRkFMU0U7CisgICAgfQorICAgIHJlc3VsdCA9IF9zdHJpbmdfdGFpbG1hdGNoKHNlbGYsIHN1Ym9iaiwgc3RhcnQsIGVuZCwgKzEpOworICAgIGlmIChyZXN1bHQgPT0gLTEpIHsKKyAgICAgICAgaWYgKFB5RXJyX0V4Y2VwdGlvbk1hdGNoZXMoUHlFeGNfVHlwZUVycm9yKSkKKyAgICAgICAgICAgIFB5RXJyX0Zvcm1hdChQeUV4Y19UeXBlRXJyb3IsICJlbmRzd2l0aCBmaXJzdCBhcmcgbXVzdCBiZSBzdHIsICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAidW5pY29kZSwgb3IgdHVwbGUsIG5vdCAlcyIsIFB5X1RZUEUoc3Vib2JqKS0+dHBfbmFtZSk7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICBlbHNlCisgICAgICAgIHJldHVybiBQeUJvb2xfRnJvbUxvbmcocmVzdWx0KTsKK30KKworCitQeURvY19TVFJWQVIoZW5jb2RlX19kb2NfXywKKyJTLmVuY29kZShbZW5jb2RpbmdbLGVycm9yc11dKSAtPiBvYmplY3RcblwKK1xuXAorRW5jb2RlcyBTIHVzaW5nIHRoZSBjb2RlYyByZWdpc3RlcmVkIGZvciBlbmNvZGluZy4gZW5jb2RpbmcgZGVmYXVsdHNcblwKK3RvIHRoZSBkZWZhdWx0IGVuY29kaW5nLiBlcnJvcnMgbWF5IGJlIGdpdmVuIHRvIHNldCBhIGRpZmZlcmVudCBlcnJvclxuXAoraGFuZGxpbmcgc2NoZW1lLiBEZWZhdWx0IGlzICdzdHJpY3QnIG1lYW5pbmcgdGhhdCBlbmNvZGluZyBlcnJvcnMgcmFpc2VcblwKK2EgVW5pY29kZUVuY29kZUVycm9yLiBPdGhlciBwb3NzaWJsZSB2YWx1ZXMgYXJlICdpZ25vcmUnLCAncmVwbGFjZScgYW5kXG5cCisneG1sY2hhcnJlZnJlcGxhY2UnIGFzIHdlbGwgYXMgYW55IG90aGVyIG5hbWUgcmVnaXN0ZXJlZCB3aXRoXG5cCitjb2RlY3MucmVnaXN0ZXJfZXJyb3IgdGhhdCBpcyBhYmxlIHRvIGhhbmRsZSBVbmljb2RlRW5jb2RlRXJyb3JzLiIpOworCitzdGF0aWMgUHlPYmplY3QgKgorc3RyaW5nX2VuY29kZShQeVN0cmluZ09iamVjdCAqc2VsZiwgUHlPYmplY3QgKmFyZ3MsIFB5T2JqZWN0ICprd2FyZ3MpCit7CisgICAgc3RhdGljIGNoYXIgKmt3bGlzdFtdID0geyJlbmNvZGluZyIsICJlcnJvcnMiLCAwfTsKKyAgICBjaGFyICplbmNvZGluZyA9IE5VTEw7CisgICAgY2hhciAqZXJyb3JzID0gTlVMTDsKKyAgICBQeU9iamVjdCAqdjsKKworICAgIGlmICghUHlBcmdfUGFyc2VUdXBsZUFuZEtleXdvcmRzKGFyZ3MsIGt3YXJncywgInxzczplbmNvZGUiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGt3bGlzdCwgJmVuY29kaW5nLCAmZXJyb3JzKSkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgdiA9IFB5U3RyaW5nX0FzRW5jb2RlZE9iamVjdCgoUHlPYmplY3QgKilzZWxmLCBlbmNvZGluZywgZXJyb3JzKTsKKyAgICBpZiAodiA9PSBOVUxMKQorICAgICAgICBnb3RvIG9uRXJyb3I7CisgICAgaWYgKCFQeVN0cmluZ19DaGVjayh2KSAmJiAhUHlVbmljb2RlX0NoZWNrKHYpKSB7CisgICAgICAgIFB5RXJyX0Zvcm1hdChQeUV4Y19UeXBlRXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAiZW5jb2RlciBkaWQgbm90IHJldHVybiBhIHN0cmluZy91bmljb2RlIG9iamVjdCAiCisgICAgICAgICAgICAgICAgICAgICAiKHR5cGU9JS40MDBzKSIsCisgICAgICAgICAgICAgICAgICAgICBQeV9UWVBFKHYpLT50cF9uYW1lKTsKKyAgICAgICAgUHlfREVDUkVGKHYpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgcmV0dXJuIHY7CisKKyBvbkVycm9yOgorICAgIHJldHVybiBOVUxMOworfQorCisKK1B5RG9jX1NUUlZBUihkZWNvZGVfX2RvY19fLAorIlMuZGVjb2RlKFtlbmNvZGluZ1ssZXJyb3JzXV0pIC0+IG9iamVjdFxuXAorXG5cCitEZWNvZGVzIFMgdXNpbmcgdGhlIGNvZGVjIHJlZ2lzdGVyZWQgZm9yIGVuY29kaW5nLiBlbmNvZGluZyBkZWZhdWx0c1xuXAordG8gdGhlIGRlZmF1bHQgZW5jb2RpbmcuIGVycm9ycyBtYXkgYmUgZ2l2ZW4gdG8gc2V0IGEgZGlmZmVyZW50IGVycm9yXG5cCitoYW5kbGluZyBzY2hlbWUuIERlZmF1bHQgaXMgJ3N0cmljdCcgbWVhbmluZyB0aGF0IGVuY29kaW5nIGVycm9ycyByYWlzZVxuXAorYSBVbmljb2RlRGVjb2RlRXJyb3IuIE90aGVyIHBvc3NpYmxlIHZhbHVlcyBhcmUgJ2lnbm9yZScgYW5kICdyZXBsYWNlJ1xuXAorYXMgd2VsbCBhcyBhbnkgb3RoZXIgbmFtZSByZWdpc3RlcmVkIHdpdGggY29kZWNzLnJlZ2lzdGVyX2Vycm9yIHRoYXQgaXNcblwKK2FibGUgdG8gaGFuZGxlIFVuaWNvZGVEZWNvZGVFcnJvcnMuIik7CisKK3N0YXRpYyBQeU9iamVjdCAqCitzdHJpbmdfZGVjb2RlKFB5U3RyaW5nT2JqZWN0ICpzZWxmLCBQeU9iamVjdCAqYXJncywgUHlPYmplY3QgKmt3YXJncykKK3sKKyAgICBzdGF0aWMgY2hhciAqa3dsaXN0W10gPSB7ImVuY29kaW5nIiwgImVycm9ycyIsIDB9OworICAgIGNoYXIgKmVuY29kaW5nID0gTlVMTDsKKyAgICBjaGFyICplcnJvcnMgPSBOVUxMOworICAgIFB5T2JqZWN0ICp2OworCisgICAgaWYgKCFQeUFyZ19QYXJzZVR1cGxlQW5kS2V5d29yZHMoYXJncywga3dhcmdzLCAifHNzOmRlY29kZSIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAga3dsaXN0LCAmZW5jb2RpbmcsICZlcnJvcnMpKQorICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB2ID0gUHlTdHJpbmdfQXNEZWNvZGVkT2JqZWN0KChQeU9iamVjdCAqKXNlbGYsIGVuY29kaW5nLCBlcnJvcnMpOworICAgIGlmICh2ID09IE5VTEwpCisgICAgICAgIGdvdG8gb25FcnJvcjsKKyAgICBpZiAoIVB5U3RyaW5nX0NoZWNrKHYpICYmICFQeVVuaWNvZGVfQ2hlY2sodikpIHsKKyAgICAgICAgUHlFcnJfRm9ybWF0KFB5RXhjX1R5cGVFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICJkZWNvZGVyIGRpZCBub3QgcmV0dXJuIGEgc3RyaW5nL3VuaWNvZGUgb2JqZWN0ICIKKyAgICAgICAgICAgICAgICAgICAgICIodHlwZT0lLjQwMHMpIiwKKyAgICAgICAgICAgICAgICAgICAgIFB5X1RZUEUodiktPnRwX25hbWUpOworICAgICAgICBQeV9ERUNSRUYodik7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICByZXR1cm4gdjsKKworIG9uRXJyb3I6CisgICAgcmV0dXJuIE5VTEw7Cit9CisKKworUHlEb2NfU1RSVkFSKGV4cGFuZHRhYnNfX2RvY19fLAorIlMuZXhwYW5kdGFicyhbdGFic2l6ZV0pIC0+IHN0cmluZ1xuXAorXG5cCitSZXR1cm4gYSBjb3B5IG9mIFMgd2hlcmUgYWxsIHRhYiBjaGFyYWN0ZXJzIGFyZSBleHBhbmRlZCB1c2luZyBzcGFjZXMuXG5cCitJZiB0YWJzaXplIGlzIG5vdCBnaXZlbiwgYSB0YWIgc2l6ZSBvZiA4IGNoYXJhY3RlcnMgaXMgYXNzdW1lZC4iKTsKKworc3RhdGljIFB5T2JqZWN0Kgorc3RyaW5nX2V4cGFuZHRhYnMoUHlTdHJpbmdPYmplY3QgKnNlbGYsIFB5T2JqZWN0ICphcmdzKQoreworICAgIGNvbnN0IGNoYXIgKmUsICpwLCAqcWU7CisgICAgY2hhciAqcTsKKyAgICBQeV9zc2l6ZV90IGksIGosIGluY3I7CisgICAgUHlPYmplY3QgKnU7CisgICAgaW50IHRhYnNpemUgPSA4OworCisgICAgaWYgKCFQeUFyZ19QYXJzZVR1cGxlKGFyZ3MsICJ8aTpleHBhbmR0YWJzIiwgJnRhYnNpemUpKQorICAgICAgICByZXR1cm4gTlVMTDsKKworICAgIC8qIEZpcnN0IHBhc3M6IGRldGVybWluZSBzaXplIG9mIG91dHB1dCBzdHJpbmcgKi8KKyAgICBpID0gMDsgLyogY2hhcnMgdXAgdG8gYW5kIGluY2x1ZGluZyBtb3N0IHJlY2VudCBcbiBvciBcciAqLworICAgIGogPSAwOyAvKiBjaGFycyBzaW5jZSBtb3N0IHJlY2VudCBcbiBvciBcciAodXNlIGluIHRhYiBjYWxjdWxhdGlvbnMpICovCisgICAgZSA9IFB5U3RyaW5nX0FTX1NUUklORyhzZWxmKSArIFB5U3RyaW5nX0dFVF9TSVpFKHNlbGYpOyAvKiBlbmQgb2YgaW5wdXQgKi8KKyAgICBmb3IgKHAgPSBQeVN0cmluZ19BU19TVFJJTkcoc2VsZik7IHAgPCBlOyBwKyspCisgICAgaWYgKCpwID09ICdcdCcpIHsKKyAgICAgICAgaWYgKHRhYnNpemUgPiAwKSB7CisgICAgICAgICAgICBpbmNyID0gdGFic2l6ZSAtIChqICUgdGFic2l6ZSk7CisgICAgICAgICAgICBpZiAoaiA+IFBZX1NTSVpFX1RfTUFYIC0gaW5jcikKKyAgICAgICAgICAgICAgICBnb3RvIG92ZXJmbG93MTsKKyAgICAgICAgICAgIGogKz0gaW5jcjsKKyAgICAgICAgfQorICAgIH0KKyAgICBlbHNlIHsKKyAgICAgICAgaWYgKGogPiBQWV9TU0laRV9UX01BWCAtIDEpCisgICAgICAgICAgICBnb3RvIG92ZXJmbG93MTsKKyAgICAgICAgaisrOworICAgICAgICBpZiAoKnAgPT0gJ1xuJyB8fCAqcCA9PSAnXHInKSB7CisgICAgICAgICAgICBpZiAoaSA+IFBZX1NTSVpFX1RfTUFYIC0gaikKKyAgICAgICAgICAgICAgICBnb3RvIG92ZXJmbG93MTsKKyAgICAgICAgICAgIGkgKz0gajsKKyAgICAgICAgICAgIGogPSAwOworICAgICAgICB9CisgICAgfQorCisgICAgaWYgKGkgPiBQWV9TU0laRV9UX01BWCAtIGopCisgICAgICAgIGdvdG8gb3ZlcmZsb3cxOworCisgICAgLyogU2Vjb25kIHBhc3M6IGNyZWF0ZSBvdXRwdXQgc3RyaW5nIGFuZCBmaWxsIGl0ICovCisgICAgdSA9IFB5U3RyaW5nX0Zyb21TdHJpbmdBbmRTaXplKE5VTEwsIGkgKyBqKTsKKyAgICBpZiAoIXUpCisgICAgICAgIHJldHVybiBOVUxMOworCisgICAgaiA9IDA7IC8qIHNhbWUgYXMgaW4gZmlyc3QgcGFzcyAqLworICAgIHEgPSBQeVN0cmluZ19BU19TVFJJTkcodSk7IC8qIG5leHQgb3V0cHV0IGNoYXIgKi8KKyAgICBxZSA9IFB5U3RyaW5nX0FTX1NUUklORyh1KSArIFB5U3RyaW5nX0dFVF9TSVpFKHUpOyAvKiBlbmQgb2Ygb3V0cHV0ICovCisKKyAgICBmb3IgKHAgPSBQeVN0cmluZ19BU19TVFJJTkcoc2VsZik7IHAgPCBlOyBwKyspCisgICAgaWYgKCpwID09ICdcdCcpIHsKKyAgICAgICAgaWYgKHRhYnNpemUgPiAwKSB7CisgICAgICAgICAgICBpID0gdGFic2l6ZSAtIChqICUgdGFic2l6ZSk7CisgICAgICAgICAgICBqICs9IGk7CisgICAgICAgICAgICB3aGlsZSAoaS0tKSB7CisgICAgICAgICAgICAgICAgaWYgKHEgPj0gcWUpCisgICAgICAgICAgICAgICAgICAgIGdvdG8gb3ZlcmZsb3cyOworICAgICAgICAgICAgICAgICpxKysgPSAnICc7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisgICAgZWxzZSB7CisgICAgICAgIGlmIChxID49IHFlKQorICAgICAgICAgICAgZ290byBvdmVyZmxvdzI7CisgICAgICAgICpxKysgPSAqcDsKKyAgICAgICAgaisrOworICAgICAgICBpZiAoKnAgPT0gJ1xuJyB8fCAqcCA9PSAnXHInKQorICAgICAgICAgICAgaiA9IDA7CisgICAgfQorCisgICAgcmV0dXJuIHU7CisKKyAgb3ZlcmZsb3cyOgorICAgIFB5X0RFQ1JFRih1KTsKKyAgb3ZlcmZsb3cxOgorICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19PdmVyZmxvd0Vycm9yLCAibmV3IHN0cmluZyBpcyB0b28gbG9uZyIpOworICAgIHJldHVybiBOVUxMOworfQorCitQeV9MT0NBTF9JTkxJTkUoUHlPYmplY3QgKikKK3BhZChQeVN0cmluZ09iamVjdCAqc2VsZiwgUHlfc3NpemVfdCBsZWZ0LCBQeV9zc2l6ZV90IHJpZ2h0LCBjaGFyIGZpbGwpCit7CisgICAgUHlPYmplY3QgKnU7CisKKyAgICBpZiAobGVmdCA8IDApCisgICAgICAgIGxlZnQgPSAwOworICAgIGlmIChyaWdodCA8IDApCisgICAgICAgIHJpZ2h0ID0gMDsKKworICAgIGlmIChsZWZ0ID09IDAgJiYgcmlnaHQgPT0gMCAmJiBQeVN0cmluZ19DaGVja0V4YWN0KHNlbGYpKSB7CisgICAgICAgIFB5X0lOQ1JFRihzZWxmKTsKKyAgICAgICAgcmV0dXJuIChQeU9iamVjdCAqKXNlbGY7CisgICAgfQorCisgICAgdSA9IFB5U3RyaW5nX0Zyb21TdHJpbmdBbmRTaXplKE5VTEwsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxlZnQgKyBQeVN0cmluZ19HRVRfU0laRShzZWxmKSArIHJpZ2h0KTsKKyAgICBpZiAodSkgeworICAgICAgICBpZiAobGVmdCkKKyAgICAgICAgICAgIG1lbXNldChQeVN0cmluZ19BU19TVFJJTkcodSksIGZpbGwsIGxlZnQpOworICAgICAgICBQeV9NRU1DUFkoUHlTdHJpbmdfQVNfU1RSSU5HKHUpICsgbGVmdCwKKyAgICAgICAgICAgICAgIFB5U3RyaW5nX0FTX1NUUklORyhzZWxmKSwKKyAgICAgICAgICAgICAgIFB5U3RyaW5nX0dFVF9TSVpFKHNlbGYpKTsKKyAgICAgICAgaWYgKHJpZ2h0KQorICAgICAgICAgICAgbWVtc2V0KFB5U3RyaW5nX0FTX1NUUklORyh1KSArIGxlZnQgKyBQeVN0cmluZ19HRVRfU0laRShzZWxmKSwKKyAgICAgICAgICAgICAgIGZpbGwsIHJpZ2h0KTsKKyAgICB9CisKKyAgICByZXR1cm4gdTsKK30KKworUHlEb2NfU1RSVkFSKGxqdXN0X19kb2NfXywKKyJTLmxqdXN0KHdpZHRoWywgZmlsbGNoYXJdKSAtPiBzdHJpbmdcbiIKKyJcbiIKKyJSZXR1cm4gUyBsZWZ0LWp1c3RpZmllZCBpbiBhIHN0cmluZyBvZiBsZW5ndGggd2lkdGguIFBhZGRpbmcgaXNcbiIKKyJkb25lIHVzaW5nIHRoZSBzcGVjaWZpZWQgZmlsbCBjaGFyYWN0ZXIgKGRlZmF1bHQgaXMgYSBzcGFjZSkuIik7CisKK3N0YXRpYyBQeU9iamVjdCAqCitzdHJpbmdfbGp1c3QoUHlTdHJpbmdPYmplY3QgKnNlbGYsIFB5T2JqZWN0ICphcmdzKQoreworICAgIFB5X3NzaXplX3Qgd2lkdGg7CisgICAgY2hhciBmaWxsY2hhciA9ICcgJzsKKworICAgIGlmICghUHlBcmdfUGFyc2VUdXBsZShhcmdzLCAibnxjOmxqdXN0IiwgJndpZHRoLCAmZmlsbGNoYXIpKQorICAgICAgICByZXR1cm4gTlVMTDsKKworICAgIGlmIChQeVN0cmluZ19HRVRfU0laRShzZWxmKSA+PSB3aWR0aCAmJiBQeVN0cmluZ19DaGVja0V4YWN0KHNlbGYpKSB7CisgICAgICAgIFB5X0lOQ1JFRihzZWxmKTsKKyAgICAgICAgcmV0dXJuIChQeU9iamVjdCopIHNlbGY7CisgICAgfQorCisgICAgcmV0dXJuIHBhZChzZWxmLCAwLCB3aWR0aCAtIFB5U3RyaW5nX0dFVF9TSVpFKHNlbGYpLCBmaWxsY2hhcik7Cit9CisKKworUHlEb2NfU1RSVkFSKHJqdXN0X19kb2NfXywKKyJTLnJqdXN0KHdpZHRoWywgZmlsbGNoYXJdKSAtPiBzdHJpbmdcbiIKKyJcbiIKKyJSZXR1cm4gUyByaWdodC1qdXN0aWZpZWQgaW4gYSBzdHJpbmcgb2YgbGVuZ3RoIHdpZHRoLiBQYWRkaW5nIGlzXG4iCisiZG9uZSB1c2luZyB0aGUgc3BlY2lmaWVkIGZpbGwgY2hhcmFjdGVyIChkZWZhdWx0IGlzIGEgc3BhY2UpIik7CisKK3N0YXRpYyBQeU9iamVjdCAqCitzdHJpbmdfcmp1c3QoUHlTdHJpbmdPYmplY3QgKnNlbGYsIFB5T2JqZWN0ICphcmdzKQoreworICAgIFB5X3NzaXplX3Qgd2lkdGg7CisgICAgY2hhciBmaWxsY2hhciA9ICcgJzsKKworICAgIGlmICghUHlBcmdfUGFyc2VUdXBsZShhcmdzLCAibnxjOnJqdXN0IiwgJndpZHRoLCAmZmlsbGNoYXIpKQorICAgICAgICByZXR1cm4gTlVMTDsKKworICAgIGlmIChQeVN0cmluZ19HRVRfU0laRShzZWxmKSA+PSB3aWR0aCAmJiBQeVN0cmluZ19DaGVja0V4YWN0KHNlbGYpKSB7CisgICAgICAgIFB5X0lOQ1JFRihzZWxmKTsKKyAgICAgICAgcmV0dXJuIChQeU9iamVjdCopIHNlbGY7CisgICAgfQorCisgICAgcmV0dXJuIHBhZChzZWxmLCB3aWR0aCAtIFB5U3RyaW5nX0dFVF9TSVpFKHNlbGYpLCAwLCBmaWxsY2hhcik7Cit9CisKKworUHlEb2NfU1RSVkFSKGNlbnRlcl9fZG9jX18sCisiUy5jZW50ZXIod2lkdGhbLCBmaWxsY2hhcl0pIC0+IHN0cmluZ1xuIgorIlxuIgorIlJldHVybiBTIGNlbnRlcmVkIGluIGEgc3RyaW5nIG9mIGxlbmd0aCB3aWR0aC4gUGFkZGluZyBpc1xuIgorImRvbmUgdXNpbmcgdGhlIHNwZWNpZmllZCBmaWxsIGNoYXJhY3RlciAoZGVmYXVsdCBpcyBhIHNwYWNlKSIpOworCitzdGF0aWMgUHlPYmplY3QgKgorc3RyaW5nX2NlbnRlcihQeVN0cmluZ09iamVjdCAqc2VsZiwgUHlPYmplY3QgKmFyZ3MpCit7CisgICAgUHlfc3NpemVfdCBtYXJnLCBsZWZ0OworICAgIFB5X3NzaXplX3Qgd2lkdGg7CisgICAgY2hhciBmaWxsY2hhciA9ICcgJzsKKworICAgIGlmICghUHlBcmdfUGFyc2VUdXBsZShhcmdzLCAibnxjOmNlbnRlciIsICZ3aWR0aCwgJmZpbGxjaGFyKSkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisKKyAgICBpZiAoUHlTdHJpbmdfR0VUX1NJWkUoc2VsZikgPj0gd2lkdGggJiYgUHlTdHJpbmdfQ2hlY2tFeGFjdChzZWxmKSkgeworICAgICAgICBQeV9JTkNSRUYoc2VsZik7CisgICAgICAgIHJldHVybiAoUHlPYmplY3QqKSBzZWxmOworICAgIH0KKworICAgIG1hcmcgPSB3aWR0aCAtIFB5U3RyaW5nX0dFVF9TSVpFKHNlbGYpOworICAgIGxlZnQgPSBtYXJnIC8gMiArIChtYXJnICYgd2lkdGggJiAxKTsKKworICAgIHJldHVybiBwYWQoc2VsZiwgbGVmdCwgbWFyZyAtIGxlZnQsIGZpbGxjaGFyKTsKK30KKworUHlEb2NfU1RSVkFSKHpmaWxsX19kb2NfXywKKyJTLnpmaWxsKHdpZHRoKSAtPiBzdHJpbmdcbiIKKyJcbiIKKyJQYWQgYSBudW1lcmljIHN0cmluZyBTIHdpdGggemVyb3Mgb24gdGhlIGxlZnQsIHRvIGZpbGwgYSBmaWVsZFxuIgorIm9mIHRoZSBzcGVjaWZpZWQgd2lkdGguICBUaGUgc3RyaW5nIFMgaXMgbmV2ZXIgdHJ1bmNhdGVkLiIpOworCitzdGF0aWMgUHlPYmplY3QgKgorc3RyaW5nX3pmaWxsKFB5U3RyaW5nT2JqZWN0ICpzZWxmLCBQeU9iamVjdCAqYXJncykKK3sKKyAgICBQeV9zc2l6ZV90IGZpbGw7CisgICAgUHlPYmplY3QgKnM7CisgICAgY2hhciAqcDsKKyAgICBQeV9zc2l6ZV90IHdpZHRoOworCisgICAgaWYgKCFQeUFyZ19QYXJzZVR1cGxlKGFyZ3MsICJuOnpmaWxsIiwgJndpZHRoKSkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisKKyAgICBpZiAoUHlTdHJpbmdfR0VUX1NJWkUoc2VsZikgPj0gd2lkdGgpIHsKKyAgICAgICAgaWYgKFB5U3RyaW5nX0NoZWNrRXhhY3Qoc2VsZikpIHsKKyAgICAgICAgICAgIFB5X0lOQ1JFRihzZWxmKTsKKyAgICAgICAgICAgIHJldHVybiAoUHlPYmplY3QqKSBzZWxmOworICAgICAgICB9CisgICAgICAgIGVsc2UKKyAgICAgICAgICAgIHJldHVybiBQeVN0cmluZ19Gcm9tU3RyaW5nQW5kU2l6ZSgKKyAgICAgICAgICAgIFB5U3RyaW5nX0FTX1NUUklORyhzZWxmKSwKKyAgICAgICAgICAgIFB5U3RyaW5nX0dFVF9TSVpFKHNlbGYpCisgICAgICAgICAgICApOworICAgIH0KKworICAgIGZpbGwgPSB3aWR0aCAtIFB5U3RyaW5nX0dFVF9TSVpFKHNlbGYpOworCisgICAgcyA9IHBhZChzZWxmLCBmaWxsLCAwLCAnMCcpOworCisgICAgaWYgKHMgPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisKKyAgICBwID0gUHlTdHJpbmdfQVNfU1RSSU5HKHMpOworICAgIGlmIChwW2ZpbGxdID09ICcrJyB8fCBwW2ZpbGxdID09ICctJykgeworICAgICAgICAvKiBtb3ZlIHNpZ24gdG8gYmVnaW5uaW5nIG9mIHN0cmluZyAqLworICAgICAgICBwWzBdID0gcFtmaWxsXTsKKyAgICAgICAgcFtmaWxsXSA9ICcwJzsKKyAgICB9CisKKyAgICByZXR1cm4gKFB5T2JqZWN0KikgczsKK30KKworUHlEb2NfU1RSVkFSKGlzc3BhY2VfX2RvY19fLAorIlMuaXNzcGFjZSgpIC0+IGJvb2xcblwKK1xuXAorUmV0dXJuIFRydWUgaWYgYWxsIGNoYXJhY3RlcnMgaW4gUyBhcmUgd2hpdGVzcGFjZVxuXAorYW5kIHRoZXJlIGlzIGF0IGxlYXN0IG9uZSBjaGFyYWN0ZXIgaW4gUywgRmFsc2Ugb3RoZXJ3aXNlLiIpOworCitzdGF0aWMgUHlPYmplY3QqCitzdHJpbmdfaXNzcGFjZShQeVN0cmluZ09iamVjdCAqc2VsZikKK3sKKyAgICByZWdpc3RlciBjb25zdCB1bnNpZ25lZCBjaGFyICpwCisgICAgICAgID0gKHVuc2lnbmVkIGNoYXIgKikgUHlTdHJpbmdfQVNfU1RSSU5HKHNlbGYpOworICAgIHJlZ2lzdGVyIGNvbnN0IHVuc2lnbmVkIGNoYXIgKmU7CisKKyAgICAvKiBTaG9ydGN1dCBmb3Igc2luZ2xlIGNoYXJhY3RlciBzdHJpbmdzICovCisgICAgaWYgKFB5U3RyaW5nX0dFVF9TSVpFKHNlbGYpID09IDEgJiYKKyAgICAgICAgaXNzcGFjZSgqcCkpCisgICAgICAgIHJldHVybiBQeUJvb2xfRnJvbUxvbmcoMSk7CisKKyAgICAvKiBTcGVjaWFsIGNhc2UgZm9yIGVtcHR5IHN0cmluZ3MgKi8KKyAgICBpZiAoUHlTdHJpbmdfR0VUX1NJWkUoc2VsZikgPT0gMCkKKyAgICAgICAgcmV0dXJuIFB5Qm9vbF9Gcm9tTG9uZygwKTsKKworICAgIGUgPSBwICsgUHlTdHJpbmdfR0VUX1NJWkUoc2VsZik7CisgICAgZm9yICg7IHAgPCBlOyBwKyspIHsKKyAgICAgICAgaWYgKCFpc3NwYWNlKCpwKSkKKyAgICAgICAgICAgIHJldHVybiBQeUJvb2xfRnJvbUxvbmcoMCk7CisgICAgfQorICAgIHJldHVybiBQeUJvb2xfRnJvbUxvbmcoMSk7Cit9CisKKworUHlEb2NfU1RSVkFSKGlzYWxwaGFfX2RvY19fLAorIlMuaXNhbHBoYSgpIC0+IGJvb2xcblwKK1xuXAorUmV0dXJuIFRydWUgaWYgYWxsIGNoYXJhY3RlcnMgaW4gUyBhcmUgYWxwaGFiZXRpY1xuXAorYW5kIHRoZXJlIGlzIGF0IGxlYXN0IG9uZSBjaGFyYWN0ZXIgaW4gUywgRmFsc2Ugb3RoZXJ3aXNlLiIpOworCitzdGF0aWMgUHlPYmplY3QqCitzdHJpbmdfaXNhbHBoYShQeVN0cmluZ09iamVjdCAqc2VsZikKK3sKKyAgICByZWdpc3RlciBjb25zdCB1bnNpZ25lZCBjaGFyICpwCisgICAgICAgID0gKHVuc2lnbmVkIGNoYXIgKikgUHlTdHJpbmdfQVNfU1RSSU5HKHNlbGYpOworICAgIHJlZ2lzdGVyIGNvbnN0IHVuc2lnbmVkIGNoYXIgKmU7CisKKyAgICAvKiBTaG9ydGN1dCBmb3Igc2luZ2xlIGNoYXJhY3RlciBzdHJpbmdzICovCisgICAgaWYgKFB5U3RyaW5nX0dFVF9TSVpFKHNlbGYpID09IDEgJiYKKyAgICAgICAgaXNhbHBoYSgqcCkpCisgICAgICAgIHJldHVybiBQeUJvb2xfRnJvbUxvbmcoMSk7CisKKyAgICAvKiBTcGVjaWFsIGNhc2UgZm9yIGVtcHR5IHN0cmluZ3MgKi8KKyAgICBpZiAoUHlTdHJpbmdfR0VUX1NJWkUoc2VsZikgPT0gMCkKKyAgICAgICAgcmV0dXJuIFB5Qm9vbF9Gcm9tTG9uZygwKTsKKworICAgIGUgPSBwICsgUHlTdHJpbmdfR0VUX1NJWkUoc2VsZik7CisgICAgZm9yICg7IHAgPCBlOyBwKyspIHsKKyAgICAgICAgaWYgKCFpc2FscGhhKCpwKSkKKyAgICAgICAgICAgIHJldHVybiBQeUJvb2xfRnJvbUxvbmcoMCk7CisgICAgfQorICAgIHJldHVybiBQeUJvb2xfRnJvbUxvbmcoMSk7Cit9CisKKworUHlEb2NfU1RSVkFSKGlzYWxudW1fX2RvY19fLAorIlMuaXNhbG51bSgpIC0+IGJvb2xcblwKK1xuXAorUmV0dXJuIFRydWUgaWYgYWxsIGNoYXJhY3RlcnMgaW4gUyBhcmUgYWxwaGFudW1lcmljXG5cCithbmQgdGhlcmUgaXMgYXQgbGVhc3Qgb25lIGNoYXJhY3RlciBpbiBTLCBGYWxzZSBvdGhlcndpc2UuIik7CisKK3N0YXRpYyBQeU9iamVjdCoKK3N0cmluZ19pc2FsbnVtKFB5U3RyaW5nT2JqZWN0ICpzZWxmKQoreworICAgIHJlZ2lzdGVyIGNvbnN0IHVuc2lnbmVkIGNoYXIgKnAKKyAgICAgICAgPSAodW5zaWduZWQgY2hhciAqKSBQeVN0cmluZ19BU19TVFJJTkcoc2VsZik7CisgICAgcmVnaXN0ZXIgY29uc3QgdW5zaWduZWQgY2hhciAqZTsKKworICAgIC8qIFNob3J0Y3V0IGZvciBzaW5nbGUgY2hhcmFjdGVyIHN0cmluZ3MgKi8KKyAgICBpZiAoUHlTdHJpbmdfR0VUX1NJWkUoc2VsZikgPT0gMSAmJgorICAgICAgICBpc2FsbnVtKCpwKSkKKyAgICAgICAgcmV0dXJuIFB5Qm9vbF9Gcm9tTG9uZygxKTsKKworICAgIC8qIFNwZWNpYWwgY2FzZSBmb3IgZW1wdHkgc3RyaW5ncyAqLworICAgIGlmIChQeVN0cmluZ19HRVRfU0laRShzZWxmKSA9PSAwKQorICAgICAgICByZXR1cm4gUHlCb29sX0Zyb21Mb25nKDApOworCisgICAgZSA9IHAgKyBQeVN0cmluZ19HRVRfU0laRShzZWxmKTsKKyAgICBmb3IgKDsgcCA8IGU7IHArKykgeworICAgICAgICBpZiAoIWlzYWxudW0oKnApKQorICAgICAgICAgICAgcmV0dXJuIFB5Qm9vbF9Gcm9tTG9uZygwKTsKKyAgICB9CisgICAgcmV0dXJuIFB5Qm9vbF9Gcm9tTG9uZygxKTsKK30KKworCitQeURvY19TVFJWQVIoaXNkaWdpdF9fZG9jX18sCisiUy5pc2RpZ2l0KCkgLT4gYm9vbFxuXAorXG5cCitSZXR1cm4gVHJ1ZSBpZiBhbGwgY2hhcmFjdGVycyBpbiBTIGFyZSBkaWdpdHNcblwKK2FuZCB0aGVyZSBpcyBhdCBsZWFzdCBvbmUgY2hhcmFjdGVyIGluIFMsIEZhbHNlIG90aGVyd2lzZS4iKTsKKworc3RhdGljIFB5T2JqZWN0Kgorc3RyaW5nX2lzZGlnaXQoUHlTdHJpbmdPYmplY3QgKnNlbGYpCit7CisgICAgcmVnaXN0ZXIgY29uc3QgdW5zaWduZWQgY2hhciAqcAorICAgICAgICA9ICh1bnNpZ25lZCBjaGFyICopIFB5U3RyaW5nX0FTX1NUUklORyhzZWxmKTsKKyAgICByZWdpc3RlciBjb25zdCB1bnNpZ25lZCBjaGFyICplOworCisgICAgLyogU2hvcnRjdXQgZm9yIHNpbmdsZSBjaGFyYWN0ZXIgc3RyaW5ncyAqLworICAgIGlmIChQeVN0cmluZ19HRVRfU0laRShzZWxmKSA9PSAxICYmCisgICAgICAgIGlzZGlnaXQoKnApKQorICAgICAgICByZXR1cm4gUHlCb29sX0Zyb21Mb25nKDEpOworCisgICAgLyogU3BlY2lhbCBjYXNlIGZvciBlbXB0eSBzdHJpbmdzICovCisgICAgaWYgKFB5U3RyaW5nX0dFVF9TSVpFKHNlbGYpID09IDApCisgICAgICAgIHJldHVybiBQeUJvb2xfRnJvbUxvbmcoMCk7CisKKyAgICBlID0gcCArIFB5U3RyaW5nX0dFVF9TSVpFKHNlbGYpOworICAgIGZvciAoOyBwIDwgZTsgcCsrKSB7CisgICAgICAgIGlmICghaXNkaWdpdCgqcCkpCisgICAgICAgICAgICByZXR1cm4gUHlCb29sX0Zyb21Mb25nKDApOworICAgIH0KKyAgICByZXR1cm4gUHlCb29sX0Zyb21Mb25nKDEpOworfQorCisKK1B5RG9jX1NUUlZBUihpc2xvd2VyX19kb2NfXywKKyJTLmlzbG93ZXIoKSAtPiBib29sXG5cCitcblwKK1JldHVybiBUcnVlIGlmIGFsbCBjYXNlZCBjaGFyYWN0ZXJzIGluIFMgYXJlIGxvd2VyY2FzZSBhbmQgdGhlcmUgaXNcblwKK2F0IGxlYXN0IG9uZSBjYXNlZCBjaGFyYWN0ZXIgaW4gUywgRmFsc2Ugb3RoZXJ3aXNlLiIpOworCitzdGF0aWMgUHlPYmplY3QqCitzdHJpbmdfaXNsb3dlcihQeVN0cmluZ09iamVjdCAqc2VsZikKK3sKKyAgICByZWdpc3RlciBjb25zdCB1bnNpZ25lZCBjaGFyICpwCisgICAgICAgID0gKHVuc2lnbmVkIGNoYXIgKikgUHlTdHJpbmdfQVNfU1RSSU5HKHNlbGYpOworICAgIHJlZ2lzdGVyIGNvbnN0IHVuc2lnbmVkIGNoYXIgKmU7CisgICAgaW50IGNhc2VkOworCisgICAgLyogU2hvcnRjdXQgZm9yIHNpbmdsZSBjaGFyYWN0ZXIgc3RyaW5ncyAqLworICAgIGlmIChQeVN0cmluZ19HRVRfU0laRShzZWxmKSA9PSAxKQorICAgICAgICByZXR1cm4gUHlCb29sX0Zyb21Mb25nKGlzbG93ZXIoKnApICE9IDApOworCisgICAgLyogU3BlY2lhbCBjYXNlIGZvciBlbXB0eSBzdHJpbmdzICovCisgICAgaWYgKFB5U3RyaW5nX0dFVF9TSVpFKHNlbGYpID09IDApCisgICAgICAgIHJldHVybiBQeUJvb2xfRnJvbUxvbmcoMCk7CisKKyAgICBlID0gcCArIFB5U3RyaW5nX0dFVF9TSVpFKHNlbGYpOworICAgIGNhc2VkID0gMDsKKyAgICBmb3IgKDsgcCA8IGU7IHArKykgeworICAgICAgICBpZiAoaXN1cHBlcigqcCkpCisgICAgICAgICAgICByZXR1cm4gUHlCb29sX0Zyb21Mb25nKDApOworICAgICAgICBlbHNlIGlmICghY2FzZWQgJiYgaXNsb3dlcigqcCkpCisgICAgICAgICAgICBjYXNlZCA9IDE7CisgICAgfQorICAgIHJldHVybiBQeUJvb2xfRnJvbUxvbmcoY2FzZWQpOworfQorCisKK1B5RG9jX1NUUlZBUihpc3VwcGVyX19kb2NfXywKKyJTLmlzdXBwZXIoKSAtPiBib29sXG5cCitcblwKK1JldHVybiBUcnVlIGlmIGFsbCBjYXNlZCBjaGFyYWN0ZXJzIGluIFMgYXJlIHVwcGVyY2FzZSBhbmQgdGhlcmUgaXNcblwKK2F0IGxlYXN0IG9uZSBjYXNlZCBjaGFyYWN0ZXIgaW4gUywgRmFsc2Ugb3RoZXJ3aXNlLiIpOworCitzdGF0aWMgUHlPYmplY3QqCitzdHJpbmdfaXN1cHBlcihQeVN0cmluZ09iamVjdCAqc2VsZikKK3sKKyAgICByZWdpc3RlciBjb25zdCB1bnNpZ25lZCBjaGFyICpwCisgICAgICAgID0gKHVuc2lnbmVkIGNoYXIgKikgUHlTdHJpbmdfQVNfU1RSSU5HKHNlbGYpOworICAgIHJlZ2lzdGVyIGNvbnN0IHVuc2lnbmVkIGNoYXIgKmU7CisgICAgaW50IGNhc2VkOworCisgICAgLyogU2hvcnRjdXQgZm9yIHNpbmdsZSBjaGFyYWN0ZXIgc3RyaW5ncyAqLworICAgIGlmIChQeVN0cmluZ19HRVRfU0laRShzZWxmKSA9PSAxKQorICAgICAgICByZXR1cm4gUHlCb29sX0Zyb21Mb25nKGlzdXBwZXIoKnApICE9IDApOworCisgICAgLyogU3BlY2lhbCBjYXNlIGZvciBlbXB0eSBzdHJpbmdzICovCisgICAgaWYgKFB5U3RyaW5nX0dFVF9TSVpFKHNlbGYpID09IDApCisgICAgICAgIHJldHVybiBQeUJvb2xfRnJvbUxvbmcoMCk7CisKKyAgICBlID0gcCArIFB5U3RyaW5nX0dFVF9TSVpFKHNlbGYpOworICAgIGNhc2VkID0gMDsKKyAgICBmb3IgKDsgcCA8IGU7IHArKykgeworICAgICAgICBpZiAoaXNsb3dlcigqcCkpCisgICAgICAgICAgICByZXR1cm4gUHlCb29sX0Zyb21Mb25nKDApOworICAgICAgICBlbHNlIGlmICghY2FzZWQgJiYgaXN1cHBlcigqcCkpCisgICAgICAgICAgICBjYXNlZCA9IDE7CisgICAgfQorICAgIHJldHVybiBQeUJvb2xfRnJvbUxvbmcoY2FzZWQpOworfQorCisKK1B5RG9jX1NUUlZBUihpc3RpdGxlX19kb2NfXywKKyJTLmlzdGl0bGUoKSAtPiBib29sXG5cCitcblwKK1JldHVybiBUcnVlIGlmIFMgaXMgYSB0aXRsZWNhc2VkIHN0cmluZyBhbmQgdGhlcmUgaXMgYXQgbGVhc3Qgb25lXG5cCitjaGFyYWN0ZXIgaW4gUywgaS5lLiB1cHBlcmNhc2UgY2hhcmFjdGVycyBtYXkgb25seSBmb2xsb3cgdW5jYXNlZFxuXAorY2hhcmFjdGVycyBhbmQgbG93ZXJjYXNlIGNoYXJhY3RlcnMgb25seSBjYXNlZCBvbmVzLiBSZXR1cm4gRmFsc2VcblwKK290aGVyd2lzZS4iKTsKKworc3RhdGljIFB5T2JqZWN0Kgorc3RyaW5nX2lzdGl0bGUoUHlTdHJpbmdPYmplY3QgKnNlbGYsIFB5T2JqZWN0ICp1bmNhc2VkKQoreworICAgIHJlZ2lzdGVyIGNvbnN0IHVuc2lnbmVkIGNoYXIgKnAKKyAgICAgICAgPSAodW5zaWduZWQgY2hhciAqKSBQeVN0cmluZ19BU19TVFJJTkcoc2VsZik7CisgICAgcmVnaXN0ZXIgY29uc3QgdW5zaWduZWQgY2hhciAqZTsKKyAgICBpbnQgY2FzZWQsIHByZXZpb3VzX2lzX2Nhc2VkOworCisgICAgLyogU2hvcnRjdXQgZm9yIHNpbmdsZSBjaGFyYWN0ZXIgc3RyaW5ncyAqLworICAgIGlmIChQeVN0cmluZ19HRVRfU0laRShzZWxmKSA9PSAxKQorICAgICAgICByZXR1cm4gUHlCb29sX0Zyb21Mb25nKGlzdXBwZXIoKnApICE9IDApOworCisgICAgLyogU3BlY2lhbCBjYXNlIGZvciBlbXB0eSBzdHJpbmdzICovCisgICAgaWYgKFB5U3RyaW5nX0dFVF9TSVpFKHNlbGYpID09IDApCisgICAgICAgIHJldHVybiBQeUJvb2xfRnJvbUxvbmcoMCk7CisKKyAgICBlID0gcCArIFB5U3RyaW5nX0dFVF9TSVpFKHNlbGYpOworICAgIGNhc2VkID0gMDsKKyAgICBwcmV2aW91c19pc19jYXNlZCA9IDA7CisgICAgZm9yICg7IHAgPCBlOyBwKyspIHsKKyAgICAgICAgcmVnaXN0ZXIgY29uc3QgdW5zaWduZWQgY2hhciBjaCA9ICpwOworCisgICAgICAgIGlmIChpc3VwcGVyKGNoKSkgeworICAgICAgICAgICAgaWYgKHByZXZpb3VzX2lzX2Nhc2VkKQorICAgICAgICAgICAgICAgIHJldHVybiBQeUJvb2xfRnJvbUxvbmcoMCk7CisgICAgICAgICAgICBwcmV2aW91c19pc19jYXNlZCA9IDE7CisgICAgICAgICAgICBjYXNlZCA9IDE7CisgICAgICAgIH0KKyAgICAgICAgZWxzZSBpZiAoaXNsb3dlcihjaCkpIHsKKyAgICAgICAgICAgIGlmICghcHJldmlvdXNfaXNfY2FzZWQpCisgICAgICAgICAgICAgICAgcmV0dXJuIFB5Qm9vbF9Gcm9tTG9uZygwKTsKKyAgICAgICAgICAgIHByZXZpb3VzX2lzX2Nhc2VkID0gMTsKKyAgICAgICAgICAgIGNhc2VkID0gMTsKKyAgICAgICAgfQorICAgICAgICBlbHNlCisgICAgICAgICAgICBwcmV2aW91c19pc19jYXNlZCA9IDA7CisgICAgfQorICAgIHJldHVybiBQeUJvb2xfRnJvbUxvbmcoY2FzZWQpOworfQorCisKK1B5RG9jX1NUUlZBUihzcGxpdGxpbmVzX19kb2NfXywKKyJTLnNwbGl0bGluZXMoa2VlcGVuZHM9RmFsc2UpIC0+IGxpc3Qgb2Ygc3RyaW5nc1xuXAorXG5cCitSZXR1cm4gYSBsaXN0IG9mIHRoZSBsaW5lcyBpbiBTLCBicmVha2luZyBhdCBsaW5lIGJvdW5kYXJpZXMuXG5cCitMaW5lIGJyZWFrcyBhcmUgbm90IGluY2x1ZGVkIGluIHRoZSByZXN1bHRpbmcgbGlzdCB1bmxlc3Mga2VlcGVuZHNcblwKK2lzIGdpdmVuIGFuZCB0cnVlLiIpOworCitzdGF0aWMgUHlPYmplY3QqCitzdHJpbmdfc3BsaXRsaW5lcyhQeVN0cmluZ09iamVjdCAqc2VsZiwgUHlPYmplY3QgKmFyZ3MpCit7CisgICAgaW50IGtlZXBlbmRzID0gMDsKKworICAgIGlmICghUHlBcmdfUGFyc2VUdXBsZShhcmdzLCAifGk6c3BsaXRsaW5lcyIsICZrZWVwZW5kcykpCisgICAgICAgIHJldHVybiBOVUxMOworCisgICAgcmV0dXJuIHN0cmluZ2xpYl9zcGxpdGxpbmVzKAorICAgICAgICAoUHlPYmplY3QqKSBzZWxmLCBQeVN0cmluZ19BU19TVFJJTkcoc2VsZiksIFB5U3RyaW5nX0dFVF9TSVpFKHNlbGYpLAorICAgICAgICBrZWVwZW5kcworICAgICk7Cit9CisKK1B5RG9jX1NUUlZBUihzaXplb2ZfX2RvY19fLAorIlMuX19zaXplb2ZfXygpIC0+IHNpemUgb2YgUyBpbiBtZW1vcnksIGluIGJ5dGVzIik7CisKK3N0YXRpYyBQeU9iamVjdCAqCitzdHJpbmdfc2l6ZW9mKFB5U3RyaW5nT2JqZWN0ICp2KQoreworICAgIFB5X3NzaXplX3QgcmVzOworICAgIHJlcyA9IFB5U3RyaW5nT2JqZWN0X1NJWkUgKyBQeVN0cmluZ19HRVRfU0laRSh2KSAqIFB5X1RZUEUodiktPnRwX2l0ZW1zaXplOworICAgIHJldHVybiBQeUludF9Gcm9tU3NpemVfdChyZXMpOworfQorCitzdGF0aWMgUHlPYmplY3QgKgorc3RyaW5nX2dldG5ld2FyZ3MoUHlTdHJpbmdPYmplY3QgKnYpCit7CisgICAgcmV0dXJuIFB5X0J1aWxkVmFsdWUoIihzIykiLCB2LT5vYl9zdmFsLCBQeV9TSVpFKHYpKTsKK30KKworCisjaW5jbHVkZSAic3RyaW5nbGliL3N0cmluZ19mb3JtYXQuaCIKKworUHlEb2NfU1RSVkFSKGZvcm1hdF9fZG9jX18sCisiUy5mb3JtYXQoKmFyZ3MsICoqa3dhcmdzKSAtPiBzdHJpbmdcblwKK1xuXAorUmV0dXJuIGEgZm9ybWF0dGVkIHZlcnNpb24gb2YgUywgdXNpbmcgc3Vic3RpdHV0aW9ucyBmcm9tIGFyZ3MgYW5kIGt3YXJncy5cblwKK1RoZSBzdWJzdGl0dXRpb25zIGFyZSBpZGVudGlmaWVkIGJ5IGJyYWNlcyAoJ3snIGFuZCAnfScpLiIpOworCitzdGF0aWMgUHlPYmplY3QgKgorc3RyaW5nX19mb3JtYXRfXyhQeU9iamVjdCogc2VsZiwgUHlPYmplY3QqIGFyZ3MpCit7CisgICAgUHlPYmplY3QgKmZvcm1hdF9zcGVjOworICAgIFB5T2JqZWN0ICpyZXN1bHQgPSBOVUxMOworICAgIFB5T2JqZWN0ICp0bXAgPSBOVUxMOworCisgICAgLyogSWYgMi54LCBjb252ZXJ0IGZvcm1hdF9zcGVjIHRvIHRoZSBzYW1lIHR5cGUgYXMgdmFsdWUgKi8KKyAgICAvKiBUaGlzIGlzIHRvIGFsbG93IHRoaW5ncyBsaWtlIHUnJy5mb3JtYXQoJycpICovCisgICAgaWYgKCFQeUFyZ19QYXJzZVR1cGxlKGFyZ3MsICJPOl9fZm9ybWF0X18iLCAmZm9ybWF0X3NwZWMpKQorICAgICAgICBnb3RvIGRvbmU7CisgICAgaWYgKCEoUHlTdHJpbmdfQ2hlY2soZm9ybWF0X3NwZWMpIHx8IFB5VW5pY29kZV9DaGVjayhmb3JtYXRfc3BlYykpKSB7CisgICAgICAgIFB5RXJyX0Zvcm1hdChQeUV4Y19UeXBlRXJyb3IsICJfX2Zvcm1hdF9fIGFyZyBtdXN0IGJlIHN0ciAiCisgICAgICAgICAgICAgICAgICAgICAib3IgdW5pY29kZSwgbm90ICVzIiwgUHlfVFlQRShmb3JtYXRfc3BlYyktPnRwX25hbWUpOworICAgICAgICBnb3RvIGRvbmU7CisgICAgfQorICAgIHRtcCA9IFB5T2JqZWN0X1N0cihmb3JtYXRfc3BlYyk7CisgICAgaWYgKHRtcCA9PSBOVUxMKQorICAgICAgICBnb3RvIGRvbmU7CisgICAgZm9ybWF0X3NwZWMgPSB0bXA7CisKKyAgICByZXN1bHQgPSBfUHlCeXRlc19Gb3JtYXRBZHZhbmNlZChzZWxmLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFB5U3RyaW5nX0FTX1NUUklORyhmb3JtYXRfc3BlYyksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHlTdHJpbmdfR0VUX1NJWkUoZm9ybWF0X3NwZWMpKTsKK2RvbmU6CisgICAgUHlfWERFQ1JFRih0bXApOworICAgIHJldHVybiByZXN1bHQ7Cit9CisKK1B5RG9jX1NUUlZBUihwX2Zvcm1hdF9fZG9jX18sCisiUy5fX2Zvcm1hdF9fKGZvcm1hdF9zcGVjKSAtPiBzdHJpbmdcblwKK1xuXAorUmV0dXJuIGEgZm9ybWF0dGVkIHZlcnNpb24gb2YgUyBhcyBkZXNjcmliZWQgYnkgZm9ybWF0X3NwZWMuIik7CisKKworc3RhdGljIFB5TWV0aG9kRGVmCitzdHJpbmdfbWV0aG9kc1tdID0geworICAgIC8qIENvdW50ZXJwYXJ0cyBvZiB0aGUgb2Jzb2xldGUgc3Ryb3Btb2R1bGUgZnVuY3Rpb25zOyBleGNlcHQKKyAgICAgICBzdHJpbmcubWFrZXRyYW5zKCkuICovCisgICAgeyJqb2luIiwgKFB5Q0Z1bmN0aW9uKXN0cmluZ19qb2luLCBNRVRIX08sIGpvaW5fX2RvY19ffSwKKyAgICB7InNwbGl0IiwgKFB5Q0Z1bmN0aW9uKXN0cmluZ19zcGxpdCwgTUVUSF9WQVJBUkdTLCBzcGxpdF9fZG9jX199LAorICAgIHsicnNwbGl0IiwgKFB5Q0Z1bmN0aW9uKXN0cmluZ19yc3BsaXQsIE1FVEhfVkFSQVJHUywgcnNwbGl0X19kb2NfX30sCisgICAgeyJsb3dlciIsIChQeUNGdW5jdGlvbilzdHJpbmdfbG93ZXIsIE1FVEhfTk9BUkdTLCBsb3dlcl9fZG9jX199LAorICAgIHsidXBwZXIiLCAoUHlDRnVuY3Rpb24pc3RyaW5nX3VwcGVyLCBNRVRIX05PQVJHUywgdXBwZXJfX2RvY19ffSwKKyAgICB7ImlzbG93ZXIiLCAoUHlDRnVuY3Rpb24pc3RyaW5nX2lzbG93ZXIsIE1FVEhfTk9BUkdTLCBpc2xvd2VyX19kb2NfX30sCisgICAgeyJpc3VwcGVyIiwgKFB5Q0Z1bmN0aW9uKXN0cmluZ19pc3VwcGVyLCBNRVRIX05PQVJHUywgaXN1cHBlcl9fZG9jX199LAorICAgIHsiaXNzcGFjZSIsIChQeUNGdW5jdGlvbilzdHJpbmdfaXNzcGFjZSwgTUVUSF9OT0FSR1MsIGlzc3BhY2VfX2RvY19ffSwKKyAgICB7ImlzZGlnaXQiLCAoUHlDRnVuY3Rpb24pc3RyaW5nX2lzZGlnaXQsIE1FVEhfTk9BUkdTLCBpc2RpZ2l0X19kb2NfX30sCisgICAgeyJpc3RpdGxlIiwgKFB5Q0Z1bmN0aW9uKXN0cmluZ19pc3RpdGxlLCBNRVRIX05PQVJHUywgaXN0aXRsZV9fZG9jX199LAorICAgIHsiaXNhbHBoYSIsIChQeUNGdW5jdGlvbilzdHJpbmdfaXNhbHBoYSwgTUVUSF9OT0FSR1MsIGlzYWxwaGFfX2RvY19ffSwKKyAgICB7ImlzYWxudW0iLCAoUHlDRnVuY3Rpb24pc3RyaW5nX2lzYWxudW0sIE1FVEhfTk9BUkdTLCBpc2FsbnVtX19kb2NfX30sCisgICAgeyJjYXBpdGFsaXplIiwgKFB5Q0Z1bmN0aW9uKXN0cmluZ19jYXBpdGFsaXplLCBNRVRIX05PQVJHUywKKyAgICAgY2FwaXRhbGl6ZV9fZG9jX199LAorICAgIHsiY291bnQiLCAoUHlDRnVuY3Rpb24pc3RyaW5nX2NvdW50LCBNRVRIX1ZBUkFSR1MsIGNvdW50X19kb2NfX30sCisgICAgeyJlbmRzd2l0aCIsIChQeUNGdW5jdGlvbilzdHJpbmdfZW5kc3dpdGgsIE1FVEhfVkFSQVJHUywKKyAgICAgZW5kc3dpdGhfX2RvY19ffSwKKyAgICB7InBhcnRpdGlvbiIsIChQeUNGdW5jdGlvbilzdHJpbmdfcGFydGl0aW9uLCBNRVRIX08sIHBhcnRpdGlvbl9fZG9jX199LAorICAgIHsiZmluZCIsIChQeUNGdW5jdGlvbilzdHJpbmdfZmluZCwgTUVUSF9WQVJBUkdTLCBmaW5kX19kb2NfX30sCisgICAgeyJpbmRleCIsIChQeUNGdW5jdGlvbilzdHJpbmdfaW5kZXgsIE1FVEhfVkFSQVJHUywgaW5kZXhfX2RvY19ffSwKKyAgICB7ImxzdHJpcCIsIChQeUNGdW5jdGlvbilzdHJpbmdfbHN0cmlwLCBNRVRIX1ZBUkFSR1MsIGxzdHJpcF9fZG9jX199LAorICAgIHsicmVwbGFjZSIsIChQeUNGdW5jdGlvbilzdHJpbmdfcmVwbGFjZSwgTUVUSF9WQVJBUkdTLCByZXBsYWNlX19kb2NfX30sCisgICAgeyJyZmluZCIsIChQeUNGdW5jdGlvbilzdHJpbmdfcmZpbmQsIE1FVEhfVkFSQVJHUywgcmZpbmRfX2RvY19ffSwKKyAgICB7InJpbmRleCIsIChQeUNGdW5jdGlvbilzdHJpbmdfcmluZGV4LCBNRVRIX1ZBUkFSR1MsIHJpbmRleF9fZG9jX199LAorICAgIHsicnN0cmlwIiwgKFB5Q0Z1bmN0aW9uKXN0cmluZ19yc3RyaXAsIE1FVEhfVkFSQVJHUywgcnN0cmlwX19kb2NfX30sCisgICAgeyJycGFydGl0aW9uIiwgKFB5Q0Z1bmN0aW9uKXN0cmluZ19ycGFydGl0aW9uLCBNRVRIX08sCisgICAgIHJwYXJ0aXRpb25fX2RvY19ffSwKKyAgICB7InN0YXJ0c3dpdGgiLCAoUHlDRnVuY3Rpb24pc3RyaW5nX3N0YXJ0c3dpdGgsIE1FVEhfVkFSQVJHUywKKyAgICAgc3RhcnRzd2l0aF9fZG9jX199LAorICAgIHsic3RyaXAiLCAoUHlDRnVuY3Rpb24pc3RyaW5nX3N0cmlwLCBNRVRIX1ZBUkFSR1MsIHN0cmlwX19kb2NfX30sCisgICAgeyJzd2FwY2FzZSIsIChQeUNGdW5jdGlvbilzdHJpbmdfc3dhcGNhc2UsIE1FVEhfTk9BUkdTLAorICAgICBzd2FwY2FzZV9fZG9jX199LAorICAgIHsidHJhbnNsYXRlIiwgKFB5Q0Z1bmN0aW9uKXN0cmluZ190cmFuc2xhdGUsIE1FVEhfVkFSQVJHUywKKyAgICAgdHJhbnNsYXRlX19kb2NfX30sCisgICAgeyJ0aXRsZSIsIChQeUNGdW5jdGlvbilzdHJpbmdfdGl0bGUsIE1FVEhfTk9BUkdTLCB0aXRsZV9fZG9jX199LAorICAgIHsibGp1c3QiLCAoUHlDRnVuY3Rpb24pc3RyaW5nX2xqdXN0LCBNRVRIX1ZBUkFSR1MsIGxqdXN0X19kb2NfX30sCisgICAgeyJyanVzdCIsIChQeUNGdW5jdGlvbilzdHJpbmdfcmp1c3QsIE1FVEhfVkFSQVJHUywgcmp1c3RfX2RvY19ffSwKKyAgICB7ImNlbnRlciIsIChQeUNGdW5jdGlvbilzdHJpbmdfY2VudGVyLCBNRVRIX1ZBUkFSR1MsIGNlbnRlcl9fZG9jX199LAorICAgIHsiemZpbGwiLCAoUHlDRnVuY3Rpb24pc3RyaW5nX3pmaWxsLCBNRVRIX1ZBUkFSR1MsIHpmaWxsX19kb2NfX30sCisgICAgeyJmb3JtYXQiLCAoUHlDRnVuY3Rpb24pIGRvX3N0cmluZ19mb3JtYXQsIE1FVEhfVkFSQVJHUyB8IE1FVEhfS0VZV09SRFMsIGZvcm1hdF9fZG9jX199LAorICAgIHsiX19mb3JtYXRfXyIsIChQeUNGdW5jdGlvbikgc3RyaW5nX19mb3JtYXRfXywgTUVUSF9WQVJBUkdTLCBwX2Zvcm1hdF9fZG9jX199LAorICAgIHsiX2Zvcm1hdHRlcl9maWVsZF9uYW1lX3NwbGl0IiwgKFB5Q0Z1bmN0aW9uKSBmb3JtYXR0ZXJfZmllbGRfbmFtZV9zcGxpdCwgTUVUSF9OT0FSR1N9LAorICAgIHsiX2Zvcm1hdHRlcl9wYXJzZXIiLCAoUHlDRnVuY3Rpb24pIGZvcm1hdHRlcl9wYXJzZXIsIE1FVEhfTk9BUkdTfSwKKyAgICB7ImVuY29kZSIsIChQeUNGdW5jdGlvbilzdHJpbmdfZW5jb2RlLCBNRVRIX1ZBUkFSR1MgfCBNRVRIX0tFWVdPUkRTLCBlbmNvZGVfX2RvY19ffSwKKyAgICB7ImRlY29kZSIsIChQeUNGdW5jdGlvbilzdHJpbmdfZGVjb2RlLCBNRVRIX1ZBUkFSR1MgfCBNRVRIX0tFWVdPUkRTLCBkZWNvZGVfX2RvY19ffSwKKyAgICB7ImV4cGFuZHRhYnMiLCAoUHlDRnVuY3Rpb24pc3RyaW5nX2V4cGFuZHRhYnMsIE1FVEhfVkFSQVJHUywKKyAgICAgZXhwYW5kdGFic19fZG9jX199LAorICAgIHsic3BsaXRsaW5lcyIsIChQeUNGdW5jdGlvbilzdHJpbmdfc3BsaXRsaW5lcywgTUVUSF9WQVJBUkdTLAorICAgICBzcGxpdGxpbmVzX19kb2NfX30sCisgICAgeyJfX3NpemVvZl9fIiwgKFB5Q0Z1bmN0aW9uKXN0cmluZ19zaXplb2YsIE1FVEhfTk9BUkdTLAorICAgICBzaXplb2ZfX2RvY19ffSwKKyAgICB7Il9fZ2V0bmV3YXJnc19fIiwgICAgICAgICAgKFB5Q0Z1bmN0aW9uKXN0cmluZ19nZXRuZXdhcmdzLCBNRVRIX05PQVJHU30sCisgICAge05VTEwsICAgICBOVUxMfSAgICAgICAgICAgICAgICAgICAgICAgICAvKiBzZW50aW5lbCAqLworfTsKKworc3RhdGljIFB5T2JqZWN0ICoKK3N0cl9zdWJ0eXBlX25ldyhQeVR5cGVPYmplY3QgKnR5cGUsIFB5T2JqZWN0ICphcmdzLCBQeU9iamVjdCAqa3dkcyk7CisKK3N0YXRpYyBQeU9iamVjdCAqCitzdHJpbmdfbmV3KFB5VHlwZU9iamVjdCAqdHlwZSwgUHlPYmplY3QgKmFyZ3MsIFB5T2JqZWN0ICprd2RzKQoreworICAgIFB5T2JqZWN0ICp4ID0gTlVMTDsKKyAgICBzdGF0aWMgY2hhciAqa3dsaXN0W10gPSB7Im9iamVjdCIsIDB9OworCisgICAgaWYgKHR5cGUgIT0gJlB5U3RyaW5nX1R5cGUpCisgICAgICAgIHJldHVybiBzdHJfc3VidHlwZV9uZXcodHlwZSwgYXJncywga3dkcyk7CisgICAgaWYgKCFQeUFyZ19QYXJzZVR1cGxlQW5kS2V5d29yZHMoYXJncywga3dkcywgInxPOnN0ciIsIGt3bGlzdCwgJngpKQorICAgICAgICByZXR1cm4gTlVMTDsKKyAgICBpZiAoeCA9PSBOVUxMKQorICAgICAgICByZXR1cm4gUHlTdHJpbmdfRnJvbVN0cmluZygiIik7CisgICAgcmV0dXJuIFB5T2JqZWN0X1N0cih4KTsKK30KKworc3RhdGljIFB5T2JqZWN0ICoKK3N0cl9zdWJ0eXBlX25ldyhQeVR5cGVPYmplY3QgKnR5cGUsIFB5T2JqZWN0ICphcmdzLCBQeU9iamVjdCAqa3dkcykKK3sKKyAgICBQeU9iamVjdCAqdG1wLCAqcG5ldzsKKyAgICBQeV9zc2l6ZV90IG47CisKKyAgICBhc3NlcnQoUHlUeXBlX0lzU3VidHlwZSh0eXBlLCAmUHlTdHJpbmdfVHlwZSkpOworICAgIHRtcCA9IHN0cmluZ19uZXcoJlB5U3RyaW5nX1R5cGUsIGFyZ3MsIGt3ZHMpOworICAgIGlmICh0bXAgPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgYXNzZXJ0KFB5U3RyaW5nX0NoZWNrRXhhY3QodG1wKSk7CisgICAgbiA9IFB5U3RyaW5nX0dFVF9TSVpFKHRtcCk7CisgICAgcG5ldyA9IHR5cGUtPnRwX2FsbG9jKHR5cGUsIG4pOworICAgIGlmIChwbmV3ICE9IE5VTEwpIHsKKyAgICAgICAgUHlfTUVNQ1BZKFB5U3RyaW5nX0FTX1NUUklORyhwbmV3KSwgUHlTdHJpbmdfQVNfU1RSSU5HKHRtcCksIG4rMSk7CisgICAgICAgICgoUHlTdHJpbmdPYmplY3QgKilwbmV3KS0+b2Jfc2hhc2ggPQorICAgICAgICAgICAgKChQeVN0cmluZ09iamVjdCAqKXRtcCktPm9iX3NoYXNoOworICAgICAgICAoKFB5U3RyaW5nT2JqZWN0ICopcG5ldyktPm9iX3NzdGF0ZSA9IFNTVEFURV9OT1RfSU5URVJORUQ7CisgICAgfQorICAgIFB5X0RFQ1JFRih0bXApOworICAgIHJldHVybiBwbmV3OworfQorCitzdGF0aWMgUHlPYmplY3QgKgorYmFzZXN0cmluZ19uZXcoUHlUeXBlT2JqZWN0ICp0eXBlLCBQeU9iamVjdCAqYXJncywgUHlPYmplY3QgKmt3ZHMpCit7CisgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1R5cGVFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgIlRoZSBiYXNlc3RyaW5nIHR5cGUgY2Fubm90IGJlIGluc3RhbnRpYXRlZCIpOworICAgIHJldHVybiBOVUxMOworfQorCitzdGF0aWMgUHlPYmplY3QgKgorc3RyaW5nX21vZChQeU9iamVjdCAqdiwgUHlPYmplY3QgKncpCit7CisgICAgaWYgKCFQeVN0cmluZ19DaGVjayh2KSkgeworICAgICAgICBQeV9JTkNSRUYoUHlfTm90SW1wbGVtZW50ZWQpOworICAgICAgICByZXR1cm4gUHlfTm90SW1wbGVtZW50ZWQ7CisgICAgfQorICAgIHJldHVybiBQeVN0cmluZ19Gb3JtYXQodiwgdyk7Cit9CisKK1B5RG9jX1NUUlZBUihiYXNlc3RyaW5nX2RvYywKKyJUeXBlIGJhc2VzdHJpbmcgY2Fubm90IGJlIGluc3RhbnRpYXRlZDsgaXQgaXMgdGhlIGJhc2UgZm9yIHN0ciBhbmQgdW5pY29kZS4iKTsKKworc3RhdGljIFB5TnVtYmVyTWV0aG9kcyBzdHJpbmdfYXNfbnVtYmVyID0geworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAvKm5iX2FkZCovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgIC8qbmJfc3VidHJhY3QqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAvKm5iX211bHRpcGx5Ki8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgLypuYl9kaXZpZGUqLworICAgIHN0cmluZ19tb2QsICAgICAgICAgICAgICAgICAvKm5iX3JlbWFpbmRlciovCit9OworCisKK1B5VHlwZU9iamVjdCBQeUJhc2VTdHJpbmdfVHlwZSA9IHsKKyAgICBQeVZhck9iamVjdF9IRUFEX0lOSVQoJlB5VHlwZV9UeXBlLCAwKQorICAgICJiYXNlc3RyaW5nIiwKKyAgICAwLAorICAgIDAsCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9kZWFsbG9jICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9wcmludCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZ2V0YXR0ciAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfc2V0YXR0ciAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfY29tcGFyZSAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfcmVwciAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfYXNfbnVtYmVyICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9hc19zZXF1ZW5jZSAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfYXNfbWFwcGluZyAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfaGFzaCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfY2FsbCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfc3RyICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9nZXRhdHRybyAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfc2V0YXR0cm8gKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2FzX2J1ZmZlciAqLworICAgIFB5X1RQRkxBR1NfREVGQVVMVCB8IFB5X1RQRkxBR1NfQkFTRVRZUEUsIC8qIHRwX2ZsYWdzICovCisgICAgYmFzZXN0cmluZ19kb2MsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9kb2MgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3RyYXZlcnNlICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9jbGVhciAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfcmljaGNvbXBhcmUgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3dlYWtsaXN0b2Zmc2V0ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9pdGVyICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9pdGVybmV4dCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfbWV0aG9kcyAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfbWVtYmVycyAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZ2V0c2V0ICovCisgICAgJlB5QmFzZU9iamVjdF9UeXBlLCAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9iYXNlICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9kaWN0ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9kZXNjcl9nZXQgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2Rlc2NyX3NldCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZGljdG9mZnNldCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfaW5pdCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfYWxsb2MgKi8KKyAgICBiYXNlc3RyaW5nX25ldywgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX25ldyAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZnJlZSAqLworfTsKKworUHlEb2NfU1RSVkFSKHN0cmluZ19kb2MsCisic3RyKG9iamVjdD0nJykgLT4gc3RyaW5nXG5cCitcblwKK1JldHVybiBhIG5pY2Ugc3RyaW5nIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBvYmplY3QuXG5cCitJZiB0aGUgYXJndW1lbnQgaXMgYSBzdHJpbmcsIHRoZSByZXR1cm4gdmFsdWUgaXMgdGhlIHNhbWUgb2JqZWN0LiIpOworCitQeVR5cGVPYmplY3QgUHlTdHJpbmdfVHlwZSA9IHsKKyAgICBQeVZhck9iamVjdF9IRUFEX0lOSVQoJlB5VHlwZV9UeXBlLCAwKQorICAgICJzdHIiLAorICAgIFB5U3RyaW5nT2JqZWN0X1NJWkUsCisgICAgc2l6ZW9mKGNoYXIpLAorICAgIHN0cmluZ19kZWFsbG9jLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZGVhbGxvYyAqLworICAgIChwcmludGZ1bmMpc3RyaW5nX3ByaW50LCAgICAgICAgICAgICAgICAgICAgLyogdHBfcHJpbnQgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2dldGF0dHIgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3NldGF0dHIgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2NvbXBhcmUgKi8KKyAgICBzdHJpbmdfcmVwciwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3JlcHIgKi8KKyAgICAmc3RyaW5nX2FzX251bWJlciwgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2FzX251bWJlciAqLworICAgICZzdHJpbmdfYXNfc2VxdWVuY2UsICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfYXNfc2VxdWVuY2UgKi8KKyAgICAmc3RyaW5nX2FzX21hcHBpbmcsICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2FzX21hcHBpbmcgKi8KKyAgICAoaGFzaGZ1bmMpc3RyaW5nX2hhc2gsICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2hhc2ggKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2NhbGwgKi8KKyAgICBzdHJpbmdfc3RyLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3N0ciAqLworICAgIFB5T2JqZWN0X0dlbmVyaWNHZXRBdHRyLCAgICAgICAgICAgICAgICAgICAgLyogdHBfZ2V0YXR0cm8gKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3NldGF0dHJvICovCisgICAgJnN0cmluZ19hc19idWZmZXIsICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9hc19idWZmZXIgKi8KKyAgICBQeV9UUEZMQUdTX0RFRkFVTFQgfCBQeV9UUEZMQUdTX0NIRUNLVFlQRVMgfAorICAgICAgICBQeV9UUEZMQUdTX0JBU0VUWVBFIHwgUHlfVFBGTEFHU19TVFJJTkdfU1VCQ0xBU1MgfAorICAgICAgICBQeV9UUEZMQUdTX0hBVkVfTkVXQlVGRkVSLCAgICAgICAgICAgICAgLyogdHBfZmxhZ3MgKi8KKyAgICBzdHJpbmdfZG9jLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2RvYyAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfdHJhdmVyc2UgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2NsZWFyICovCisgICAgKHJpY2hjbXBmdW5jKXN0cmluZ19yaWNoY29tcGFyZSwgICAgICAgICAgICAvKiB0cF9yaWNoY29tcGFyZSAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfd2Vha2xpc3RvZmZzZXQgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2l0ZXIgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2l0ZXJuZXh0ICovCisgICAgc3RyaW5nX21ldGhvZHMsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9tZXRob2RzICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9tZW1iZXJzICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9nZXRzZXQgKi8KKyAgICAmUHlCYXNlU3RyaW5nX1R5cGUsICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2Jhc2UgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2RpY3QgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2Rlc2NyX2dldCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZGVzY3Jfc2V0ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9kaWN0b2Zmc2V0ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9pbml0ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9hbGxvYyAqLworICAgIHN0cmluZ19uZXcsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfbmV3ICovCisgICAgUHlPYmplY3RfRGVsLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9mcmVlICovCit9OworCit2b2lkCitQeVN0cmluZ19Db25jYXQocmVnaXN0ZXIgUHlPYmplY3QgKipwdiwgcmVnaXN0ZXIgUHlPYmplY3QgKncpCit7CisgICAgcmVnaXN0ZXIgUHlPYmplY3QgKnY7CisgICAgaWYgKCpwdiA9PSBOVUxMKQorICAgICAgICByZXR1cm47CisgICAgaWYgKHcgPT0gTlVMTCB8fCAhUHlTdHJpbmdfQ2hlY2soKnB2KSkgeworICAgICAgICBQeV9DTEVBUigqcHYpOworICAgICAgICByZXR1cm47CisgICAgfQorICAgIHYgPSBzdHJpbmdfY29uY2F0KChQeVN0cmluZ09iamVjdCAqKSAqcHYsIHcpOworICAgIFB5X0RFQ1JFRigqcHYpOworICAgICpwdiA9IHY7Cit9CisKK3ZvaWQKK1B5U3RyaW5nX0NvbmNhdEFuZERlbChyZWdpc3RlciBQeU9iamVjdCAqKnB2LCByZWdpc3RlciBQeU9iamVjdCAqdykKK3sKKyAgICBQeVN0cmluZ19Db25jYXQocHYsIHcpOworICAgIFB5X1hERUNSRUYodyk7Cit9CisKKworLyogVGhlIGZvbGxvd2luZyBmdW5jdGlvbiBicmVha3MgdGhlIG5vdGlvbiB0aGF0IHN0cmluZ3MgYXJlIGltbXV0YWJsZToKKyAgIGl0IGNoYW5nZXMgdGhlIHNpemUgb2YgYSBzdHJpbmcuICBXZSBnZXQgYXdheSB3aXRoIHRoaXMgb25seSBpZiB0aGVyZQorICAgaXMgb25seSBvbmUgbW9kdWxlIHJlZmVyZW5jaW5nIHRoZSBvYmplY3QuICBZb3UgY2FuIGFsc28gdGhpbmsgb2YgaXQKKyAgIGFzIGNyZWF0aW5nIGEgbmV3IHN0cmluZyBvYmplY3QgYW5kIGRlc3Ryb3lpbmcgdGhlIG9sZCBvbmUsIG9ubHkKKyAgIG1vcmUgZWZmaWNpZW50bHkuICBJbiBhbnkgY2FzZSwgZG9uJ3QgdXNlIHRoaXMgaWYgdGhlIHN0cmluZyBtYXkKKyAgIGFscmVhZHkgYmUga25vd24gdG8gc29tZSBvdGhlciBwYXJ0IG9mIHRoZSBjb2RlLi4uCisgICBOb3RlIHRoYXQgaWYgdGhlcmUncyBub3QgZW5vdWdoIG1lbW9yeSB0byByZXNpemUgdGhlIHN0cmluZywgdGhlIG9yaWdpbmFsCisgICBzdHJpbmcgb2JqZWN0IGF0ICpwdiBpcyBkZWFsbG9jYXRlZCwgKnB2IGlzIHNldCB0byBOVUxMLCBhbiAib3V0IG9mCisgICBtZW1vcnkiIGV4Y2VwdGlvbiBpcyBzZXQsIGFuZCAtMSBpcyByZXR1cm5lZC4gIEVsc2UgKG9uIHN1Y2Nlc3MpIDAgaXMKKyAgIHJldHVybmVkLCBhbmQgdGhlIHZhbHVlIGluICpwdiBtYXkgb3IgbWF5IG5vdCBiZSB0aGUgc2FtZSBhcyBvbiBpbnB1dC4KKyAgIEFzIGFsd2F5cywgYW4gZXh0cmEgYnl0ZSBpcyBhbGxvY2F0ZWQgZm9yIGEgdHJhaWxpbmcgXDAgYnl0ZSAobmV3c2l6ZQorICAgZG9lcyAqbm90KiBpbmNsdWRlIHRoYXQpLCBhbmQgYSB0cmFpbGluZyBcMCBieXRlIGlzIHN0b3JlZC4KKyovCisKK2ludAorX1B5U3RyaW5nX1Jlc2l6ZShQeU9iamVjdCAqKnB2LCBQeV9zc2l6ZV90IG5ld3NpemUpCit7CisgICAgcmVnaXN0ZXIgUHlPYmplY3QgKnY7CisgICAgcmVnaXN0ZXIgUHlTdHJpbmdPYmplY3QgKnN2OworICAgIHYgPSAqcHY7CisgICAgaWYgKCFQeVN0cmluZ19DaGVjayh2KSB8fCBQeV9SRUZDTlQodikgIT0gMSB8fCBuZXdzaXplIDwgMCB8fAorICAgICAgICBQeVN0cmluZ19DSEVDS19JTlRFUk5FRCh2KSkgeworICAgICAgICAqcHYgPSAwOworICAgICAgICBQeV9ERUNSRUYodik7CisgICAgICAgIFB5RXJyX0JhZEludGVybmFsQ2FsbCgpOworICAgICAgICByZXR1cm4gLTE7CisgICAgfQorICAgIC8qIFhYWCBVTlJFRi9ORVdSRUYgaW50ZXJmYWNlIHNob3VsZCBiZSBtb3JlIHN5bW1ldHJpY2FsICovCisgICAgX1B5X0RFQ19SRUZUT1RBTDsKKyAgICBfUHlfRm9yZ2V0UmVmZXJlbmNlKHYpOworICAgICpwdiA9IChQeU9iamVjdCAqKQorICAgICAgICBQeU9iamVjdF9SRUFMTE9DKChjaGFyICopdiwgUHlTdHJpbmdPYmplY3RfU0laRSArIG5ld3NpemUpOworICAgIGlmICgqcHYgPT0gTlVMTCkgeworICAgICAgICBQeU9iamVjdF9EZWwodik7CisgICAgICAgIFB5RXJyX05vTWVtb3J5KCk7CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisgICAgX1B5X05ld1JlZmVyZW5jZSgqcHYpOworICAgIHN2ID0gKFB5U3RyaW5nT2JqZWN0ICopICpwdjsKKyAgICBQeV9TSVpFKHN2KSA9IG5ld3NpemU7CisgICAgc3YtPm9iX3N2YWxbbmV3c2l6ZV0gPSAnXDAnOworICAgIHN2LT5vYl9zaGFzaCA9IC0xOyAgICAgICAgICAvKiBpbnZhbGlkYXRlIGNhY2hlZCBoYXNoIHZhbHVlICovCisgICAgcmV0dXJuIDA7Cit9CisKKy8qIEhlbHBlcnMgZm9yIGZvcm1hdHN0cmluZyAqLworCitQeV9MT0NBTF9JTkxJTkUoUHlPYmplY3QgKikKK2dldG5leHRhcmcoUHlPYmplY3QgKmFyZ3MsIFB5X3NzaXplX3QgYXJnbGVuLCBQeV9zc2l6ZV90ICpwX2FyZ2lkeCkKK3sKKyAgICBQeV9zc2l6ZV90IGFyZ2lkeCA9ICpwX2FyZ2lkeDsKKyAgICBpZiAoYXJnaWR4IDwgYXJnbGVuKSB7CisgICAgICAgICgqcF9hcmdpZHgpKys7CisgICAgICAgIGlmIChhcmdsZW4gPCAwKQorICAgICAgICAgICAgcmV0dXJuIGFyZ3M7CisgICAgICAgIGVsc2UKKyAgICAgICAgICAgIHJldHVybiBQeVR1cGxlX0dldEl0ZW0oYXJncywgYXJnaWR4KTsKKyAgICB9CisgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1R5cGVFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgIm5vdCBlbm91Z2ggYXJndW1lbnRzIGZvciBmb3JtYXQgc3RyaW5nIik7CisgICAgcmV0dXJuIE5VTEw7Cit9CisKKy8qIEZvcm1hdCBjb2RlcworICogRl9MSlVTVCAgICAgICctJworICogRl9TSUdOICAgICAgICcrJworICogRl9CTEFOSyAgICAgICcgJworICogRl9BTFQgICAgICAgICcjJworICogRl9aRVJPICAgICAgICcwJworICovCisjZGVmaW5lIEZfTEpVU1QgKDE8PDApCisjZGVmaW5lIEZfU0lHTiAgKDE8PDEpCisjZGVmaW5lIEZfQkxBTksgKDE8PDIpCisjZGVmaW5lIEZfQUxUICAgKDE8PDMpCisjZGVmaW5lIEZfWkVSTyAgKDE8PDQpCisKKy8qIFJldHVybnMgYSBuZXcgcmVmZXJlbmNlIHRvIGEgUHlTdHJpbmcgb2JqZWN0LCBvciBOVUxMIG9uIGZhaWx1cmUuICovCisKK3N0YXRpYyBQeU9iamVjdCAqCitmb3JtYXRmbG9hdChQeU9iamVjdCAqdiwgaW50IGZsYWdzLCBpbnQgcHJlYywgaW50IHR5cGUpCit7CisgICAgY2hhciAqcDsKKyAgICBQeU9iamVjdCAqcmVzdWx0OworICAgIGRvdWJsZSB4OworCisgICAgeCA9IFB5RmxvYXRfQXNEb3VibGUodik7CisgICAgaWYgKHggPT0gLTEuMCAmJiBQeUVycl9PY2N1cnJlZCgpKSB7CisgICAgICAgIFB5RXJyX0Zvcm1hdChQeUV4Y19UeXBlRXJyb3IsICJmbG9hdCBhcmd1bWVudCByZXF1aXJlZCwgIgorICAgICAgICAgICAgICAgICAgICAgIm5vdCAlLjIwMHMiLCBQeV9UWVBFKHYpLT50cF9uYW1lKTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorCisgICAgaWYgKHByZWMgPCAwKQorICAgICAgICBwcmVjID0gNjsKKworICAgIHAgPSBQeU9TX2RvdWJsZV90b19zdHJpbmcoeCwgdHlwZSwgcHJlYywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChmbGFncyAmIEZfQUxUKSA/IFB5X0RUU0ZfQUxUIDogMCwgTlVMTCk7CisKKyAgICBpZiAocCA9PSBOVUxMKQorICAgICAgICByZXR1cm4gTlVMTDsKKyAgICByZXN1bHQgPSBQeVN0cmluZ19Gcm9tU3RyaW5nQW5kU2l6ZShwLCBzdHJsZW4ocCkpOworICAgIFB5TWVtX0ZyZWUocCk7CisgICAgcmV0dXJuIHJlc3VsdDsKK30KKworLyogX1B5U3RyaW5nX0Zvcm1hdExvbmcgZW11bGF0ZXMgdGhlIGZvcm1hdCBjb2RlcyBkLCB1LCBvLCB4IGFuZCBYLCBhbmQKKyAqIHRoZSBGX0FMVCBmbGFnLCBmb3IgUHl0aG9uJ3MgbG9uZyAodW5ib3VuZGVkKSBpbnRzLiAgSXQncyBub3QgdXNlZCBmb3IKKyAqIFB5dGhvbidzIHJlZ3VsYXIgaW50cy4KKyAqIFJldHVybiB2YWx1ZTogIGEgbmV3IFB5U3RyaW5nKiwgb3IgTlVMTCBpZiBlcnJvci4KKyAqICAuICAqcGJ1ZiBpcyBzZXQgdG8gcG9pbnQgaW50byBpdCwKKyAqICAgICAqcGxlbiBzZXQgdG8gdGhlICMgb2YgY2hhcnMgZm9sbG93aW5nIHRoYXQuCisgKiAgICAgQ2FsbGVyIG11c3QgZGVjcmVmIGl0IHdoZW4gZG9uZSB1c2luZyBwYnVmLgorICogICAgIFRoZSBzdHJpbmcgc3RhcnRpbmcgYXQgKnBidWYgaXMgb2YgdGhlIGZvcm0KKyAqICAgICAgICAgIi0iPyAoIjB4IiB8ICIwWCIpPyBkaWdpdCsKKyAqICAgICAiMHgiLyIwWCIgYXJlIHByZXNlbnQgb25seSBmb3IgeCBhbmQgWCBjb252ZXJzaW9ucywgd2l0aCBGX0FMVAorICogICAgICAgICBzZXQgaW4gZmxhZ3MuICBUaGUgY2FzZSBvZiBoZXggZGlnaXRzIHdpbGwgYmUgY29ycmVjdCwKKyAqICAgICBUaGVyZSB3aWxsIGJlIGF0IGxlYXN0IHByZWMgZGlnaXRzLCB6ZXJvLWZpbGxlZCBvbiB0aGUgbGVmdCBpZgorICogICAgICAgICBuZWNlc3NhcnkgdG8gZ2V0IHRoYXQgbWFueS4KKyAqIHZhbCAgICAgICAgICBvYmplY3QgdG8gYmUgY29udmVydGVkCisgKiBmbGFncyAgICAgICAgYml0bWFzayBvZiBmb3JtYXQgZmxhZ3M7IG9ubHkgRl9BTFQgaXMgbG9va2VkIGF0CisgKiBwcmVjICAgICAgICAgbWluaW11bSBudW1iZXIgb2YgZGlnaXRzOyAwLWZpbGwgb24gbGVmdCBpZiBuZWVkZWQKKyAqIHR5cGUgICAgICAgICBhIGNoYXJhY3RlciBpbiBbZHVveFhdOyB1IGFjdHMgdGhlIHNhbWUgYXMgZAorICoKKyAqIENBVVRJT046ICBvLCB4IGFuZCBYIGNvbnZlcnNpb25zIG9uIHJlZ3VsYXIgaW50cyBjYW4gbmV2ZXIKKyAqIHByb2R1Y2UgYSAnLScgc2lnbiwgYnV0IGNhbiBmb3IgUHl0aG9uJ3MgdW5ib3VuZGVkIGludHMuCisgKi8KK1B5T2JqZWN0KgorX1B5U3RyaW5nX0Zvcm1hdExvbmcoUHlPYmplY3QgKnZhbCwgaW50IGZsYWdzLCBpbnQgcHJlYywgaW50IHR5cGUsCisgICAgICAgICAgICAgICAgICAgICBjaGFyICoqcGJ1ZiwgaW50ICpwbGVuKQoreworICAgIFB5T2JqZWN0ICpyZXN1bHQgPSBOVUxMOworICAgIGNoYXIgKmJ1ZjsKKyAgICBQeV9zc2l6ZV90IGk7CisgICAgaW50IHNpZ247ICAgICAgICAgICAvKiAxIGlmICctJywgZWxzZSAwICovCisgICAgaW50IGxlbjsgICAgICAgICAgICAvKiBudW1iZXIgb2YgY2hhcmFjdGVycyAqLworICAgIFB5X3NzaXplX3QgbGxlbjsKKyAgICBpbnQgbnVtZGlnaXRzOyAgICAgIC8qIGxlbiA9PSBudW1ub25kaWdpdHMgKyBudW1kaWdpdHMgKi8KKyAgICBpbnQgbnVtbm9uZGlnaXRzID0gMDsKKworICAgIHN3aXRjaCAodHlwZSkgeworICAgIGNhc2UgJ2QnOgorICAgIGNhc2UgJ3UnOgorICAgICAgICByZXN1bHQgPSBQeV9UWVBFKHZhbCktPnRwX3N0cih2YWwpOworICAgICAgICBicmVhazsKKyAgICBjYXNlICdvJzoKKyAgICAgICAgcmVzdWx0ID0gUHlfVFlQRSh2YWwpLT50cF9hc19udW1iZXItPm5iX29jdCh2YWwpOworICAgICAgICBicmVhazsKKyAgICBjYXNlICd4JzoKKyAgICBjYXNlICdYJzoKKyAgICAgICAgbnVtbm9uZGlnaXRzID0gMjsKKyAgICAgICAgcmVzdWx0ID0gUHlfVFlQRSh2YWwpLT50cF9hc19udW1iZXItPm5iX2hleCh2YWwpOworICAgICAgICBicmVhazsKKyAgICBkZWZhdWx0OgorICAgICAgICBhc3NlcnQoISIndHlwZScgbm90IGluIFtkdW94WF0iKTsKKyAgICB9CisgICAgaWYgKCFyZXN1bHQpCisgICAgICAgIHJldHVybiBOVUxMOworCisgICAgYnVmID0gUHlTdHJpbmdfQXNTdHJpbmcocmVzdWx0KTsKKyAgICBpZiAoIWJ1ZikgeworICAgICAgICBQeV9ERUNSRUYocmVzdWx0KTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorCisgICAgLyogVG8gbW9kaWZ5IHRoZSBzdHJpbmcgaW4tcGxhY2UsIHRoZXJlIGNhbiBvbmx5IGJlIG9uZSByZWZlcmVuY2UuICovCisgICAgaWYgKFB5X1JFRkNOVChyZXN1bHQpICE9IDEpIHsKKyAgICAgICAgUHlFcnJfQmFkSW50ZXJuYWxDYWxsKCk7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICBsbGVuID0gUHlTdHJpbmdfU2l6ZShyZXN1bHQpOworICAgIGlmIChsbGVuID4gSU5UX01BWCkgeworICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfVmFsdWVFcnJvciwgInN0cmluZyB0b28gbGFyZ2UgaW4gX1B5U3RyaW5nX0Zvcm1hdExvbmciKTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIGxlbiA9IChpbnQpbGxlbjsKKyAgICBpZiAoYnVmW2xlbi0xXSA9PSAnTCcpIHsKKyAgICAgICAgLS1sZW47CisgICAgICAgIGJ1ZltsZW5dID0gJ1wwJzsKKyAgICB9CisgICAgc2lnbiA9IGJ1ZlswXSA9PSAnLSc7CisgICAgbnVtbm9uZGlnaXRzICs9IHNpZ247CisgICAgbnVtZGlnaXRzID0gbGVuIC0gbnVtbm9uZGlnaXRzOworICAgIGFzc2VydChudW1kaWdpdHMgPiAwKTsKKworICAgIC8qIEdldCByaWQgb2YgYmFzZSBtYXJrZXIgdW5sZXNzIEZfQUxUICovCisgICAgaWYgKChmbGFncyAmIEZfQUxUKSA9PSAwKSB7CisgICAgICAgIC8qIE5lZWQgdG8gc2tpcCAweCwgMFggb3IgMC4gKi8KKyAgICAgICAgaW50IHNraXBwZWQgPSAwOworICAgICAgICBzd2l0Y2ggKHR5cGUpIHsKKyAgICAgICAgY2FzZSAnbyc6CisgICAgICAgICAgICBhc3NlcnQoYnVmW3NpZ25dID09ICcwJyk7CisgICAgICAgICAgICAvKiBJZiAwIGlzIG9ubHkgZGlnaXQsIGxlYXZlIGl0IGFsb25lLiAqLworICAgICAgICAgICAgaWYgKG51bWRpZ2l0cyA+IDEpIHsKKyAgICAgICAgICAgICAgICBza2lwcGVkID0gMTsKKyAgICAgICAgICAgICAgICAtLW51bWRpZ2l0czsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICBjYXNlICd4JzoKKyAgICAgICAgY2FzZSAnWCc6CisgICAgICAgICAgICBhc3NlcnQoYnVmW3NpZ25dID09ICcwJyk7CisgICAgICAgICAgICBhc3NlcnQoYnVmW3NpZ24gKyAxXSA9PSAneCcpOworICAgICAgICAgICAgc2tpcHBlZCA9IDI7CisgICAgICAgICAgICBudW1ub25kaWdpdHMgLT0gMjsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisgICAgICAgIGlmIChza2lwcGVkKSB7CisgICAgICAgICAgICBidWYgKz0gc2tpcHBlZDsKKyAgICAgICAgICAgIGxlbiAtPSBza2lwcGVkOworICAgICAgICAgICAgaWYgKHNpZ24pCisgICAgICAgICAgICAgICAgYnVmWzBdID0gJy0nOworICAgICAgICB9CisgICAgICAgIGFzc2VydChsZW4gPT0gbnVtbm9uZGlnaXRzICsgbnVtZGlnaXRzKTsKKyAgICAgICAgYXNzZXJ0KG51bWRpZ2l0cyA+IDApOworICAgIH0KKworICAgIC8qIEZpbGwgd2l0aCBsZWFkaW5nIHplcm9lcyB0byBtZWV0IG1pbmltdW0gd2lkdGguICovCisgICAgaWYgKHByZWMgPiBudW1kaWdpdHMpIHsKKyAgICAgICAgUHlPYmplY3QgKnIxID0gUHlTdHJpbmdfRnJvbVN0cmluZ0FuZFNpemUoTlVMTCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnVtbm9uZGlnaXRzICsgcHJlYyk7CisgICAgICAgIGNoYXIgKmIxOworICAgICAgICBpZiAoIXIxKSB7CisgICAgICAgICAgICBQeV9ERUNSRUYocmVzdWx0KTsKKyAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgICAgICB9CisgICAgICAgIGIxID0gUHlTdHJpbmdfQVNfU1RSSU5HKHIxKTsKKyAgICAgICAgZm9yIChpID0gMDsgaSA8IG51bW5vbmRpZ2l0czsgKytpKQorICAgICAgICAgICAgKmIxKysgPSAqYnVmKys7CisgICAgICAgIGZvciAoaSA9IDA7IGkgPCBwcmVjIC0gbnVtZGlnaXRzOyBpKyspCisgICAgICAgICAgICAqYjErKyA9ICcwJzsKKyAgICAgICAgZm9yIChpID0gMDsgaSA8IG51bWRpZ2l0czsgaSsrKQorICAgICAgICAgICAgKmIxKysgPSAqYnVmKys7CisgICAgICAgICpiMSA9ICdcMCc7CisgICAgICAgIFB5X0RFQ1JFRihyZXN1bHQpOworICAgICAgICByZXN1bHQgPSByMTsKKyAgICAgICAgYnVmID0gUHlTdHJpbmdfQVNfU1RSSU5HKHJlc3VsdCk7CisgICAgICAgIGxlbiA9IG51bW5vbmRpZ2l0cyArIHByZWM7CisgICAgfQorCisgICAgLyogRml4IHVwIGNhc2UgZm9yIGhleCBjb252ZXJzaW9ucy4gKi8KKyAgICBpZiAodHlwZSA9PSAnWCcpIHsKKyAgICAgICAgLyogTmVlZCB0byBjb252ZXJ0IGFsbCBsb3dlciBjYXNlIGxldHRlcnMgdG8gdXBwZXIgY2FzZS4KKyAgICAgICAgICAgYW5kIG5lZWQgdG8gY29udmVydCAweCB0byAwWCAoYW5kIC0weCB0byAtMFgpLiAqLworICAgICAgICBmb3IgKGkgPSAwOyBpIDwgbGVuOyBpKyspCisgICAgICAgICAgICBpZiAoYnVmW2ldID49ICdhJyAmJiBidWZbaV0gPD0gJ3gnKQorICAgICAgICAgICAgICAgIGJ1ZltpXSAtPSAnYSctJ0EnOworICAgIH0KKyAgICAqcGJ1ZiA9IGJ1ZjsKKyAgICAqcGxlbiA9IGxlbjsKKyAgICByZXR1cm4gcmVzdWx0OworfQorCitQeV9MT0NBTF9JTkxJTkUoaW50KQorZm9ybWF0aW50KGNoYXIgKmJ1Ziwgc2l6ZV90IGJ1ZmxlbiwgaW50IGZsYWdzLAorICAgICAgICAgIGludCBwcmVjLCBpbnQgdHlwZSwgUHlPYmplY3QgKnYpCit7CisgICAgLyogZm10ID0gJyUjLicgKyBgcHJlY2AgKyAnbCcgKyBgdHlwZWAKKyAgICAgICB3b3JzdCBjYXNlIGxlbmd0aCA9IDMgKyAxOSAod29yc3QgbGVuIG9mIElOVF9NQVggb24gNjQtYml0IG1hY2hpbmUpCisgICAgICAgKyAxICsgMSA9IDI0ICovCisgICAgY2hhciBmbXRbNjRdOyAgICAgICAvKiBwbGVudHkgYmlnIGVub3VnaCEgKi8KKyAgICBjaGFyICpzaWduOworICAgIGxvbmcgeDsKKworICAgIHggPSBQeUludF9Bc0xvbmcodik7CisgICAgaWYgKHggPT0gLTEgJiYgUHlFcnJfT2NjdXJyZWQoKSkgeworICAgICAgICBQeUVycl9Gb3JtYXQoUHlFeGNfVHlwZUVycm9yLCAiaW50IGFyZ3VtZW50IHJlcXVpcmVkLCBub3QgJS4yMDBzIiwKKyAgICAgICAgICAgICAgICAgICAgIFB5X1RZUEUodiktPnRwX25hbWUpOworICAgICAgICByZXR1cm4gLTE7CisgICAgfQorICAgIGlmICh4IDwgMCAmJiB0eXBlID09ICd1JykgeworICAgICAgICB0eXBlID0gJ2QnOworICAgIH0KKyAgICBpZiAoeCA8IDAgJiYgKHR5cGUgPT0gJ3gnIHx8IHR5cGUgPT0gJ1gnIHx8IHR5cGUgPT0gJ28nKSkKKyAgICAgICAgc2lnbiA9ICItIjsKKyAgICBlbHNlCisgICAgICAgIHNpZ24gPSAiIjsKKyAgICBpZiAocHJlYyA8IDApCisgICAgICAgIHByZWMgPSAxOworCisgICAgaWYgKChmbGFncyAmIEZfQUxUKSAmJgorICAgICAgICAodHlwZSA9PSAneCcgfHwgdHlwZSA9PSAnWCcpKSB7CisgICAgICAgIC8qIFdoZW4gY29udmVydGluZyB1bmRlciAlI3ggb3IgJSNYLCB0aGVyZSBhcmUgYSBudW1iZXIKKyAgICAgICAgICogb2YgaXNzdWVzIHRoYXQgY2F1c2UgcGFpbjoKKyAgICAgICAgICogLSB3aGVuIDAgaXMgYmVpbmcgY29udmVydGVkLCB0aGUgQyBzdGFuZGFyZCBsZWF2ZXMgb2ZmCisgICAgICAgICAqICAgdGhlICcweCcgb3IgJzBYJywgd2hpY2ggaXMgaW5jb25zaXN0ZW50IHdpdGggb3RoZXIKKyAgICAgICAgICogICAlI3gvJSNYIGNvbnZlcnNpb25zIGFuZCBpbmNvbnNpc3RlbnQgd2l0aCBQeXRob24ncworICAgICAgICAgKiAgIGhleCgpIGZ1bmN0aW9uCisgICAgICAgICAqIC0gdGhlcmUgYXJlIHBsYXRmb3JtcyB0aGF0IHZpb2xhdGUgdGhlIHN0YW5kYXJkIGFuZAorICAgICAgICAgKiAgIGNvbnZlcnQgMCB3aXRoIHRoZSAnMHgnIG9yICcwWCcKKyAgICAgICAgICogICAoTWV0cm93ZXJrcywgQ29tcGFxIFRydTY0KQorICAgICAgICAgKiAtIHRoZXJlIGFyZSBwbGF0Zm9ybXMgdGhhdCBnaXZlICcweCcgd2hlbiBjb252ZXJ0aW5nCisgICAgICAgICAqICAgdW5kZXIgJSNYLCBidXQgY29udmVydCAwIGluIGFjY29yZGFuY2Ugd2l0aCB0aGUKKyAgICAgICAgICogICBzdGFuZGFyZCAoT1MvMiBFTVgpCisgICAgICAgICAqCisgICAgICAgICAqIFdlIGNhbiBhY2hpZXZlIHRoZSBkZXNpcmVkIGNvbnNpc3RlbmN5IGJ5IGluc2VydGluZyBvdXIKKyAgICAgICAgICogb3duICcweCcgb3IgJzBYJyBwcmVmaXgsIGFuZCBzdWJzdGl0dXRpbmcgJXgvJVggaW4gcGxhY2UKKyAgICAgICAgICogb2YgJSN4LyUjWC4KKyAgICAgICAgICoKKyAgICAgICAgICogTm90ZSB0aGF0IHRoaXMgaXMgdGhlIHNhbWUgYXBwcm9hY2ggYXMgdXNlZCBpbgorICAgICAgICAgKiBmb3JtYXRpbnQoKSBpbiB1bmljb2Rlb2JqZWN0LmMKKyAgICAgICAgICovCisgICAgICAgIFB5T1Nfc25wcmludGYoZm10LCBzaXplb2YoZm10KSwgIiVzMCVjJSUuJWRsJWMiLAorICAgICAgICAgICAgICAgICAgICAgIHNpZ24sIHR5cGUsIHByZWMsIHR5cGUpOworICAgIH0KKyAgICBlbHNlIHsKKyAgICAgICAgUHlPU19zbnByaW50ZihmbXQsIHNpemVvZihmbXQpLCAiJXMlJSVzLiVkbCVjIiwKKyAgICAgICAgICAgICAgICAgICAgICBzaWduLCAoZmxhZ3MmRl9BTFQpID8gIiMiIDogIiIsCisgICAgICAgICAgICAgICAgICAgICAgcHJlYywgdHlwZSk7CisgICAgfQorCisgICAgLyogYnVmID0gJysnLyctJy8nJyArICcwJy8nMHgnLycnICsgJ1swLTldJyptYXgocHJlYywgbGVuKHggaW4gb2N0YWwpKQorICAgICAqIHdvcnN0IGNhc2UgYnVmID0gJy0weCcgKyBbMC05XSpwcmVjLCB3aGVyZSBwcmVjID49IDExCisgICAgICovCisgICAgaWYgKGJ1ZmxlbiA8PSAxNCB8fCBidWZsZW4gPD0gKHNpemVfdCkzICsgKHNpemVfdClwcmVjKSB7CisgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19PdmVyZmxvd0Vycm9yLAorICAgICAgICAgICAgImZvcm1hdHRlZCBpbnRlZ2VyIGlzIHRvbyBsb25nIChwcmVjaXNpb24gdG9vIGxhcmdlPykiKTsKKyAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKyAgICBpZiAoc2lnblswXSkKKyAgICAgICAgUHlPU19zbnByaW50ZihidWYsIGJ1ZmxlbiwgZm10LCAteCk7CisgICAgZWxzZQorICAgICAgICBQeU9TX3NucHJpbnRmKGJ1ZiwgYnVmbGVuLCBmbXQsIHgpOworICAgIHJldHVybiAoaW50KXN0cmxlbihidWYpOworfQorCitQeV9MT0NBTF9JTkxJTkUoaW50KQorZm9ybWF0Y2hhcihjaGFyICpidWYsIHNpemVfdCBidWZsZW4sIFB5T2JqZWN0ICp2KQoreworICAgIC8qIHByZXN1bWUgdGhhdCB0aGUgYnVmZmVyIGlzIGF0IGxlYXN0IDIgY2hhcmFjdGVycyBsb25nICovCisgICAgaWYgKFB5U3RyaW5nX0NoZWNrKHYpKSB7CisgICAgICAgIGlmICghUHlBcmdfUGFyc2UodiwgImM7JWMgcmVxdWlyZXMgaW50IG9yIGNoYXIiLCAmYnVmWzBdKSkKKyAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisgICAgZWxzZSB7CisgICAgICAgIGlmICghUHlBcmdfUGFyc2UodiwgImI7JWMgcmVxdWlyZXMgaW50IG9yIGNoYXIiLCAmYnVmWzBdKSkKKyAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisgICAgYnVmWzFdID0gJ1wwJzsKKyAgICByZXR1cm4gMTsKK30KKworLyogZm10JSh2MSx2MiwuLi4pIGlzIHJvdWdobHkgZXF1aXZhbGVudCB0byBzcHJpbnRmKGZtdCwgdjEsIHYyLCAuLi4pCisKKyAgIEZPUk1BVEJVRkxFTiBpcyB0aGUgbGVuZ3RoIG9mIHRoZSBidWZmZXIgaW4gd2hpY2ggdGhlIGludHMgJgorICAgY2hhcnMgYXJlIGZvcm1hdHRlZC4gWFhYIFRoaXMgaXMgYSBtYWdpYyBudW1iZXIuIEVhY2ggZm9ybWF0dGluZworICAgcm91dGluZSBkb2VzIGJvdW5kcyBjaGVja2luZyB0byBlbnN1cmUgbm8gb3ZlcmZsb3csIGJ1dCBhIGJldHRlcgorICAgc29sdXRpb24gbWF5IGJlIHRvIG1hbGxvYyBhIGJ1ZmZlciBvZiBhcHByb3ByaWF0ZSBzaXplIGZvciBlYWNoCisgICBmb3JtYXQuIEZvciBub3csIHRoZSBjdXJyZW50IHNvbHV0aW9uIGlzIHN1ZmZpY2llbnQuCisqLworI2RlZmluZSBGT1JNQVRCVUZMRU4gKHNpemVfdCkxMjAKKworUHlPYmplY3QgKgorUHlTdHJpbmdfRm9ybWF0KFB5T2JqZWN0ICpmb3JtYXQsIFB5T2JqZWN0ICphcmdzKQoreworICAgIGNoYXIgKmZtdCwgKnJlczsKKyAgICBQeV9zc2l6ZV90IGFyZ2xlbiwgYXJnaWR4OworICAgIFB5X3NzaXplX3QgcmVzbGVuLCByZXNjbnQsIGZtdGNudDsKKyAgICBpbnQgYXJnc19vd25lZCA9IDA7CisgICAgUHlPYmplY3QgKnJlc3VsdCwgKm9yaWdfYXJnczsKKyNpZmRlZiBQeV9VU0lOR19VTklDT0RFCisgICAgUHlPYmplY3QgKnYsICp3OworI2VuZGlmCisgICAgUHlPYmplY3QgKmRpY3QgPSBOVUxMOworICAgIGlmIChmb3JtYXQgPT0gTlVMTCB8fCAhUHlTdHJpbmdfQ2hlY2soZm9ybWF0KSB8fCBhcmdzID09IE5VTEwpIHsKKyAgICAgICAgUHlFcnJfQmFkSW50ZXJuYWxDYWxsKCk7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICBvcmlnX2FyZ3MgPSBhcmdzOworICAgIGZtdCA9IFB5U3RyaW5nX0FTX1NUUklORyhmb3JtYXQpOworICAgIGZtdGNudCA9IFB5U3RyaW5nX0dFVF9TSVpFKGZvcm1hdCk7CisgICAgcmVzbGVuID0gcmVzY250ID0gZm10Y250ICsgMTAwOworICAgIHJlc3VsdCA9IFB5U3RyaW5nX0Zyb21TdHJpbmdBbmRTaXplKChjaGFyICopTlVMTCwgcmVzbGVuKTsKKyAgICBpZiAocmVzdWx0ID09IE5VTEwpCisgICAgICAgIHJldHVybiBOVUxMOworICAgIHJlcyA9IFB5U3RyaW5nX0FzU3RyaW5nKHJlc3VsdCk7CisgICAgaWYgKFB5VHVwbGVfQ2hlY2soYXJncykpIHsKKyAgICAgICAgYXJnbGVuID0gUHlUdXBsZV9HRVRfU0laRShhcmdzKTsKKyAgICAgICAgYXJnaWR4ID0gMDsKKyAgICB9CisgICAgZWxzZSB7CisgICAgICAgIGFyZ2xlbiA9IC0xOworICAgICAgICBhcmdpZHggPSAtMjsKKyAgICB9CisgICAgaWYgKFB5X1RZUEUoYXJncyktPnRwX2FzX21hcHBpbmcgJiYgUHlfVFlQRShhcmdzKS0+dHBfYXNfbWFwcGluZy0+bXBfc3Vic2NyaXB0ICYmCisgICAgICAgICFQeVR1cGxlX0NoZWNrKGFyZ3MpICYmICFQeU9iamVjdF9UeXBlQ2hlY2soYXJncywgJlB5QmFzZVN0cmluZ19UeXBlKSkKKyAgICAgICAgZGljdCA9IGFyZ3M7CisgICAgd2hpbGUgKC0tZm10Y250ID49IDApIHsKKyAgICAgICAgaWYgKCpmbXQgIT0gJyUnKSB7CisgICAgICAgICAgICBpZiAoLS1yZXNjbnQgPCAwKSB7CisgICAgICAgICAgICAgICAgcmVzY250ID0gZm10Y250ICsgMTAwOworICAgICAgICAgICAgICAgIHJlc2xlbiArPSByZXNjbnQ7CisgICAgICAgICAgICAgICAgaWYgKF9QeVN0cmluZ19SZXNpemUoJnJlc3VsdCwgcmVzbGVuKSkKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgICAgICAgICAgICAgcmVzID0gUHlTdHJpbmdfQVNfU1RSSU5HKHJlc3VsdCkKKyAgICAgICAgICAgICAgICAgICAgKyByZXNsZW4gLSByZXNjbnQ7CisgICAgICAgICAgICAgICAgLS1yZXNjbnQ7CisgICAgICAgICAgICB9CisgICAgICAgICAgICAqcmVzKysgPSAqZm10Kys7CisgICAgICAgIH0KKyAgICAgICAgZWxzZSB7CisgICAgICAgICAgICAvKiBHb3QgYSBmb3JtYXQgc3BlY2lmaWVyICovCisgICAgICAgICAgICBpbnQgZmxhZ3MgPSAwOworICAgICAgICAgICAgUHlfc3NpemVfdCB3aWR0aCA9IC0xOworICAgICAgICAgICAgaW50IHByZWMgPSAtMTsKKyAgICAgICAgICAgIGludCBjID0gJ1wwJzsKKyAgICAgICAgICAgIGludCBmaWxsOworICAgICAgICAgICAgaW50IGlzbnVtb2s7CisgICAgICAgICAgICBQeU9iamVjdCAqdiA9IE5VTEw7CisgICAgICAgICAgICBQeU9iamVjdCAqdGVtcCA9IE5VTEw7CisgICAgICAgICAgICBjaGFyICpwYnVmOworICAgICAgICAgICAgaW50IHNpZ247CisgICAgICAgICAgICBQeV9zc2l6ZV90IGxlbjsKKyAgICAgICAgICAgIGNoYXIgZm9ybWF0YnVmW0ZPUk1BVEJVRkxFTl07CisgICAgICAgICAgICAgICAgIC8qIEZvciBmb3JtYXR7aW50LGNoYXJ9KCkgKi8KKyNpZmRlZiBQeV9VU0lOR19VTklDT0RFCisgICAgICAgICAgICBjaGFyICpmbXRfc3RhcnQgPSBmbXQ7CisgICAgICAgICAgICBQeV9zc2l6ZV90IGFyZ2lkeF9zdGFydCA9IGFyZ2lkeDsKKyNlbmRpZgorCisgICAgICAgICAgICBmbXQrKzsKKyAgICAgICAgICAgIGlmICgqZm10ID09ICcoJykgeworICAgICAgICAgICAgICAgIGNoYXIgKmtleXN0YXJ0OworICAgICAgICAgICAgICAgIFB5X3NzaXplX3Qga2V5bGVuOworICAgICAgICAgICAgICAgIFB5T2JqZWN0ICprZXk7CisgICAgICAgICAgICAgICAgaW50IHBjb3VudCA9IDE7CisKKyAgICAgICAgICAgICAgICBpZiAoZGljdCA9PSBOVUxMKSB7CisgICAgICAgICAgICAgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19UeXBlRXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJmb3JtYXQgcmVxdWlyZXMgYSBtYXBwaW5nIik7CisgICAgICAgICAgICAgICAgICAgIGdvdG8gZXJyb3I7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICsrZm10OworICAgICAgICAgICAgICAgIC0tZm10Y250OworICAgICAgICAgICAgICAgIGtleXN0YXJ0ID0gZm10OworICAgICAgICAgICAgICAgIC8qIFNraXAgb3ZlciBiYWxhbmNlZCBwYXJlbnRoZXNlcyAqLworICAgICAgICAgICAgICAgIHdoaWxlIChwY291bnQgPiAwICYmIC0tZm10Y250ID49IDApIHsKKyAgICAgICAgICAgICAgICAgICAgaWYgKCpmbXQgPT0gJyknKQorICAgICAgICAgICAgICAgICAgICAgICAgLS1wY291bnQ7CisgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKCpmbXQgPT0gJygnKQorICAgICAgICAgICAgICAgICAgICAgICAgKytwY291bnQ7CisgICAgICAgICAgICAgICAgICAgIGZtdCsrOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBrZXlsZW4gPSBmbXQgLSBrZXlzdGFydCAtIDE7CisgICAgICAgICAgICAgICAgaWYgKGZtdGNudCA8IDAgfHwgcGNvdW50ID4gMCkgeworICAgICAgICAgICAgICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfVmFsdWVFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiaW5jb21wbGV0ZSBmb3JtYXQga2V5Iik7CisgICAgICAgICAgICAgICAgICAgIGdvdG8gZXJyb3I7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGtleSA9IFB5U3RyaW5nX0Zyb21TdHJpbmdBbmRTaXplKGtleXN0YXJ0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGtleWxlbik7CisgICAgICAgICAgICAgICAgaWYgKGtleSA9PSBOVUxMKQorICAgICAgICAgICAgICAgICAgICBnb3RvIGVycm9yOworICAgICAgICAgICAgICAgIGlmIChhcmdzX293bmVkKSB7CisgICAgICAgICAgICAgICAgICAgIFB5X0RFQ1JFRihhcmdzKTsKKyAgICAgICAgICAgICAgICAgICAgYXJnc19vd25lZCA9IDA7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGFyZ3MgPSBQeU9iamVjdF9HZXRJdGVtKGRpY3QsIGtleSk7CisgICAgICAgICAgICAgICAgUHlfREVDUkVGKGtleSk7CisgICAgICAgICAgICAgICAgaWYgKGFyZ3MgPT0gTlVMTCkgeworICAgICAgICAgICAgICAgICAgICBnb3RvIGVycm9yOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBhcmdzX293bmVkID0gMTsKKyAgICAgICAgICAgICAgICBhcmdsZW4gPSAtMTsKKyAgICAgICAgICAgICAgICBhcmdpZHggPSAtMjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHdoaWxlICgtLWZtdGNudCA+PSAwKSB7CisgICAgICAgICAgICAgICAgc3dpdGNoIChjID0gKmZtdCsrKSB7CisgICAgICAgICAgICAgICAgY2FzZSAnLSc6IGZsYWdzIHw9IEZfTEpVU1Q7IGNvbnRpbnVlOworICAgICAgICAgICAgICAgIGNhc2UgJysnOiBmbGFncyB8PSBGX1NJR047IGNvbnRpbnVlOworICAgICAgICAgICAgICAgIGNhc2UgJyAnOiBmbGFncyB8PSBGX0JMQU5LOyBjb250aW51ZTsKKyAgICAgICAgICAgICAgICBjYXNlICcjJzogZmxhZ3MgfD0gRl9BTFQ7IGNvbnRpbnVlOworICAgICAgICAgICAgICAgIGNhc2UgJzAnOiBmbGFncyB8PSBGX1pFUk87IGNvbnRpbnVlOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChjID09ICcqJykgeworICAgICAgICAgICAgICAgIHYgPSBnZXRuZXh0YXJnKGFyZ3MsIGFyZ2xlbiwgJmFyZ2lkeCk7CisgICAgICAgICAgICAgICAgaWYgKHYgPT0gTlVMTCkKKyAgICAgICAgICAgICAgICAgICAgZ290byBlcnJvcjsKKyAgICAgICAgICAgICAgICBpZiAoIVB5SW50X0NoZWNrKHYpKSB7CisgICAgICAgICAgICAgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19UeXBlRXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiKiB3YW50cyBpbnQiKTsKKyAgICAgICAgICAgICAgICAgICAgZ290byBlcnJvcjsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgd2lkdGggPSBQeUludF9Bc1NzaXplX3Qodik7CisgICAgICAgICAgICAgICAgaWYgKHdpZHRoID09IC0xICYmIFB5RXJyX09jY3VycmVkKCkpCisgICAgICAgICAgICAgICAgICAgIGdvdG8gZXJyb3I7CisgICAgICAgICAgICAgICAgaWYgKHdpZHRoIDwgMCkgeworICAgICAgICAgICAgICAgICAgICBmbGFncyB8PSBGX0xKVVNUOworICAgICAgICAgICAgICAgICAgICB3aWR0aCA9IC13aWR0aDsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgaWYgKC0tZm10Y250ID49IDApCisgICAgICAgICAgICAgICAgICAgIGMgPSAqZm10Kys7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBlbHNlIGlmIChjID49IDAgJiYgaXNkaWdpdChjKSkgeworICAgICAgICAgICAgICAgIHdpZHRoID0gYyAtICcwJzsKKyAgICAgICAgICAgICAgICB3aGlsZSAoLS1mbXRjbnQgPj0gMCkgeworICAgICAgICAgICAgICAgICAgICBjID0gUHlfQ0hBUk1BU0soKmZtdCsrKTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKCFpc2RpZ2l0KGMpKQorICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgICAgIGlmICh3aWR0aCA+IChQWV9TU0laRV9UX01BWCAtICgoaW50KWMgLSAnMCcpKSAvIDEwKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBQeUVycl9TZXRTdHJpbmcoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHlFeGNfVmFsdWVFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAid2lkdGggdG9vIGJpZyIpOworICAgICAgICAgICAgICAgICAgICAgICAgZ290byBlcnJvcjsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICB3aWR0aCA9IHdpZHRoKjEwICsgKGMgLSAnMCcpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChjID09ICcuJykgeworICAgICAgICAgICAgICAgIHByZWMgPSAwOworICAgICAgICAgICAgICAgIGlmICgtLWZtdGNudCA+PSAwKQorICAgICAgICAgICAgICAgICAgICBjID0gKmZtdCsrOworICAgICAgICAgICAgICAgIGlmIChjID09ICcqJykgeworICAgICAgICAgICAgICAgICAgICB2ID0gZ2V0bmV4dGFyZyhhcmdzLCBhcmdsZW4sICZhcmdpZHgpOworICAgICAgICAgICAgICAgICAgICBpZiAodiA9PSBOVUxMKQorICAgICAgICAgICAgICAgICAgICAgICAgZ290byBlcnJvcjsKKyAgICAgICAgICAgICAgICAgICAgaWYgKCFQeUludF9DaGVjayh2KSkgeworICAgICAgICAgICAgICAgICAgICAgICAgUHlFcnJfU2V0U3RyaW5nKAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIFB5RXhjX1R5cGVFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAiKiB3YW50cyBpbnQiKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGdvdG8gZXJyb3I7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgcHJlYyA9IF9QeUludF9Bc0ludCh2KTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKHByZWMgPT0gLTEgJiYgUHlFcnJfT2NjdXJyZWQoKSkKKyAgICAgICAgICAgICAgICAgICAgICAgIGdvdG8gZXJyb3I7CisgICAgICAgICAgICAgICAgICAgIGlmIChwcmVjIDwgMCkKKyAgICAgICAgICAgICAgICAgICAgICAgIHByZWMgPSAwOworICAgICAgICAgICAgICAgICAgICBpZiAoLS1mbXRjbnQgPj0gMCkKKyAgICAgICAgICAgICAgICAgICAgICAgIGMgPSAqZm10Kys7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGVsc2UgaWYgKGMgPj0gMCAmJiBpc2RpZ2l0KGMpKSB7CisgICAgICAgICAgICAgICAgICAgIHByZWMgPSBjIC0gJzAnOworICAgICAgICAgICAgICAgICAgICB3aGlsZSAoLS1mbXRjbnQgPj0gMCkgeworICAgICAgICAgICAgICAgICAgICAgICAgYyA9IFB5X0NIQVJNQVNLKCpmbXQrKyk7CisgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWlzZGlnaXQoYykpCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICAgICAgICAgICAgICBpZiAocHJlYyA+IChJTlRfTUFYIC0gKChpbnQpYyAtICcwJykpIC8gMTApIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBQeUVycl9TZXRTdHJpbmcoCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFB5RXhjX1ZhbHVlRXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJwcmVjIHRvbyBiaWciKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBnb3RvIGVycm9yOworICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgcHJlYyA9IHByZWMqMTAgKyAoYyAtICcwJyk7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9IC8qIHByZWMgKi8KKyAgICAgICAgICAgIGlmIChmbXRjbnQgPj0gMCkgeworICAgICAgICAgICAgICAgIGlmIChjID09ICdoJyB8fCBjID09ICdsJyB8fCBjID09ICdMJykgeworICAgICAgICAgICAgICAgICAgICBpZiAoLS1mbXRjbnQgPj0gMCkKKyAgICAgICAgICAgICAgICAgICAgICAgIGMgPSAqZm10Kys7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKGZtdGNudCA8IDApIHsKKyAgICAgICAgICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfVmFsdWVFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImluY29tcGxldGUgZm9ybWF0Iik7CisgICAgICAgICAgICAgICAgZ290byBlcnJvcjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChjICE9ICclJykgeworICAgICAgICAgICAgICAgIHYgPSBnZXRuZXh0YXJnKGFyZ3MsIGFyZ2xlbiwgJmFyZ2lkeCk7CisgICAgICAgICAgICAgICAgaWYgKHYgPT0gTlVMTCkKKyAgICAgICAgICAgICAgICAgICAgZ290byBlcnJvcjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHNpZ24gPSAwOworICAgICAgICAgICAgZmlsbCA9ICcgJzsKKyAgICAgICAgICAgIHN3aXRjaCAoYykgeworICAgICAgICAgICAgY2FzZSAnJSc6CisgICAgICAgICAgICAgICAgcGJ1ZiA9ICIlIjsKKyAgICAgICAgICAgICAgICBsZW4gPSAxOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgY2FzZSAncyc6CisjaWZkZWYgUHlfVVNJTkdfVU5JQ09ERQorICAgICAgICAgICAgICAgIGlmIChQeVVuaWNvZGVfQ2hlY2sodikpIHsKKyAgICAgICAgICAgICAgICAgICAgZm10ID0gZm10X3N0YXJ0OworICAgICAgICAgICAgICAgICAgICBhcmdpZHggPSBhcmdpZHhfc3RhcnQ7CisgICAgICAgICAgICAgICAgICAgIGdvdG8gdW5pY29kZTsKKyAgICAgICAgICAgICAgICB9CisjZW5kaWYKKyAgICAgICAgICAgICAgICB0ZW1wID0gX1B5T2JqZWN0X1N0cih2KTsKKyNpZmRlZiBQeV9VU0lOR19VTklDT0RFCisgICAgICAgICAgICAgICAgaWYgKHRlbXAgIT0gTlVMTCAmJiBQeVVuaWNvZGVfQ2hlY2sodGVtcCkpIHsKKyAgICAgICAgICAgICAgICAgICAgUHlfREVDUkVGKHRlbXApOworICAgICAgICAgICAgICAgICAgICBmbXQgPSBmbXRfc3RhcnQ7CisgICAgICAgICAgICAgICAgICAgIGFyZ2lkeCA9IGFyZ2lkeF9zdGFydDsKKyAgICAgICAgICAgICAgICAgICAgZ290byB1bmljb2RlOworICAgICAgICAgICAgICAgIH0KKyNlbmRpZgorICAgICAgICAgICAgICAgIC8qIEZhbGwgdGhyb3VnaCAqLworICAgICAgICAgICAgY2FzZSAncic6CisgICAgICAgICAgICAgICAgaWYgKGMgPT0gJ3InKQorICAgICAgICAgICAgICAgICAgICB0ZW1wID0gUHlPYmplY3RfUmVwcih2KTsKKyAgICAgICAgICAgICAgICBpZiAodGVtcCA9PSBOVUxMKQorICAgICAgICAgICAgICAgICAgICBnb3RvIGVycm9yOworICAgICAgICAgICAgICAgIGlmICghUHlTdHJpbmdfQ2hlY2sodGVtcCkpIHsKKyAgICAgICAgICAgICAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1R5cGVFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICAiJXMgYXJndW1lbnQgaGFzIG5vbi1zdHJpbmcgc3RyKCkiKTsKKyAgICAgICAgICAgICAgICAgICAgUHlfREVDUkVGKHRlbXApOworICAgICAgICAgICAgICAgICAgICBnb3RvIGVycm9yOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBwYnVmID0gUHlTdHJpbmdfQVNfU1RSSU5HKHRlbXApOworICAgICAgICAgICAgICAgIGxlbiA9IFB5U3RyaW5nX0dFVF9TSVpFKHRlbXApOworICAgICAgICAgICAgICAgIGlmIChwcmVjID49IDAgJiYgbGVuID4gcHJlYykKKyAgICAgICAgICAgICAgICAgICAgbGVuID0gcHJlYzsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIGNhc2UgJ2knOgorICAgICAgICAgICAgY2FzZSAnZCc6CisgICAgICAgICAgICBjYXNlICd1JzoKKyAgICAgICAgICAgIGNhc2UgJ28nOgorICAgICAgICAgICAgY2FzZSAneCc6CisgICAgICAgICAgICBjYXNlICdYJzoKKyAgICAgICAgICAgICAgICBpZiAoYyA9PSAnaScpCisgICAgICAgICAgICAgICAgICAgIGMgPSAnZCc7CisgICAgICAgICAgICAgICAgaXNudW1vayA9IDA7CisgICAgICAgICAgICAgICAgaWYgKFB5TnVtYmVyX0NoZWNrKHYpKSB7CisgICAgICAgICAgICAgICAgICAgIFB5T2JqZWN0ICppb2JqPU5VTEw7CisKKyAgICAgICAgICAgICAgICAgICAgaWYgKFB5SW50X0NoZWNrKHYpIHx8IChQeUxvbmdfQ2hlY2sodikpKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBpb2JqID0gdjsKKyAgICAgICAgICAgICAgICAgICAgICAgIFB5X0lOQ1JFRihpb2JqKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGlvYmogPSBQeU51bWJlcl9JbnQodik7CisgICAgICAgICAgICAgICAgICAgICAgICBpZiAoaW9iaj09TlVMTCkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIFB5RXJyX0NsZWFyKCk7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW9iaiA9IFB5TnVtYmVyX0xvbmcodik7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgaWYgKGlvYmohPU5VTEwpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGlmIChQeUludF9DaGVjayhpb2JqKSkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzbnVtb2sgPSAxOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBidWYgPSBmb3JtYXRidWY7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGVuID0gZm9ybWF0aW50KHBidWYsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZihmb3JtYXRidWYpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmbGFncywgcHJlYywgYywgaW9iaik7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHlfREVDUkVGKGlvYmopOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChsZW4gPCAwKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnb3RvIGVycm9yOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpZ24gPSAxOworICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoUHlMb25nX0NoZWNrKGlvYmopKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGlsZW47CisKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBpc251bW9rID0gMTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZW1wID0gX1B5U3RyaW5nX0Zvcm1hdExvbmcoaW9iaiwgZmxhZ3MsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByZWMsIGMsICZwYnVmLCAmaWxlbik7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHlfREVDUkVGKGlvYmopOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxlbiA9IGlsZW47CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCF0ZW1wKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnb3RvIGVycm9yOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpZ24gPSAxOworICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICAgICAgZWxzZSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHlfREVDUkVGKGlvYmopOworICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGlmICghaXNudW1vaykgeworICAgICAgICAgICAgICAgICAgICBQeUVycl9Gb3JtYXQoUHlFeGNfVHlwZUVycm9yLAorICAgICAgICAgICAgICAgICAgICAgICAgIiUlJWMgZm9ybWF0OiBhIG51bWJlciBpcyByZXF1aXJlZCwgIgorICAgICAgICAgICAgICAgICAgICAgICAgIm5vdCAlLjIwMHMiLCBjLCBQeV9UWVBFKHYpLT50cF9uYW1lKTsKKyAgICAgICAgICAgICAgICAgICAgZ290byBlcnJvcjsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgaWYgKGZsYWdzICYgRl9aRVJPKQorICAgICAgICAgICAgICAgICAgICBmaWxsID0gJzAnOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgY2FzZSAnZSc6CisgICAgICAgICAgICBjYXNlICdFJzoKKyAgICAgICAgICAgIGNhc2UgJ2YnOgorICAgICAgICAgICAgY2FzZSAnRic6CisgICAgICAgICAgICBjYXNlICdnJzoKKyAgICAgICAgICAgIGNhc2UgJ0cnOgorICAgICAgICAgICAgICAgIHRlbXAgPSBmb3JtYXRmbG9hdCh2LCBmbGFncywgcHJlYywgYyk7CisgICAgICAgICAgICAgICAgaWYgKHRlbXAgPT0gTlVMTCkKKyAgICAgICAgICAgICAgICAgICAgZ290byBlcnJvcjsKKyAgICAgICAgICAgICAgICBwYnVmID0gUHlTdHJpbmdfQVNfU1RSSU5HKHRlbXApOworICAgICAgICAgICAgICAgIGxlbiA9IFB5U3RyaW5nX0dFVF9TSVpFKHRlbXApOworICAgICAgICAgICAgICAgIHNpZ24gPSAxOworICAgICAgICAgICAgICAgIGlmIChmbGFncyAmIEZfWkVSTykKKyAgICAgICAgICAgICAgICAgICAgZmlsbCA9ICcwJzsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIGNhc2UgJ2MnOgorI2lmZGVmIFB5X1VTSU5HX1VOSUNPREUKKyAgICAgICAgICAgICAgICBpZiAoUHlVbmljb2RlX0NoZWNrKHYpKSB7CisgICAgICAgICAgICAgICAgICAgIGZtdCA9IGZtdF9zdGFydDsKKyAgICAgICAgICAgICAgICAgICAgYXJnaWR4ID0gYXJnaWR4X3N0YXJ0OworICAgICAgICAgICAgICAgICAgICBnb3RvIHVuaWNvZGU7CisgICAgICAgICAgICAgICAgfQorI2VuZGlmCisgICAgICAgICAgICAgICAgcGJ1ZiA9IGZvcm1hdGJ1ZjsKKyAgICAgICAgICAgICAgICBsZW4gPSBmb3JtYXRjaGFyKHBidWYsIHNpemVvZihmb3JtYXRidWYpLCB2KTsKKyAgICAgICAgICAgICAgICBpZiAobGVuIDwgMCkKKyAgICAgICAgICAgICAgICAgICAgZ290byBlcnJvcjsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICAgICAgUHlFcnJfRm9ybWF0KFB5RXhjX1ZhbHVlRXJyb3IsCisgICAgICAgICAgICAgICAgICAidW5zdXBwb3J0ZWQgZm9ybWF0IGNoYXJhY3RlciAnJWMnICgweCV4KSAiCisgICAgICAgICAgICAgICAgICAiYXQgaW5kZXggJXpkIiwKKyAgICAgICAgICAgICAgICAgIGMsIGMsCisgICAgICAgICAgICAgICAgICAoUHlfc3NpemVfdCkoZm10IC0gMSAtCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHlTdHJpbmdfQXNTdHJpbmcoZm9ybWF0KSkpOworICAgICAgICAgICAgICAgIGdvdG8gZXJyb3I7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoc2lnbikgeworICAgICAgICAgICAgICAgIGlmICgqcGJ1ZiA9PSAnLScgfHwgKnBidWYgPT0gJysnKSB7CisgICAgICAgICAgICAgICAgICAgIHNpZ24gPSAqcGJ1ZisrOworICAgICAgICAgICAgICAgICAgICBsZW4tLTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgZWxzZSBpZiAoZmxhZ3MgJiBGX1NJR04pCisgICAgICAgICAgICAgICAgICAgIHNpZ24gPSAnKyc7CisgICAgICAgICAgICAgICAgZWxzZSBpZiAoZmxhZ3MgJiBGX0JMQU5LKQorICAgICAgICAgICAgICAgICAgICBzaWduID0gJyAnOworICAgICAgICAgICAgICAgIGVsc2UKKyAgICAgICAgICAgICAgICAgICAgc2lnbiA9IDA7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAod2lkdGggPCBsZW4pCisgICAgICAgICAgICAgICAgd2lkdGggPSBsZW47CisgICAgICAgICAgICBpZiAocmVzY250IC0gKHNpZ24gIT0gMCkgPCB3aWR0aCkgeworICAgICAgICAgICAgICAgIHJlc2xlbiAtPSByZXNjbnQ7CisgICAgICAgICAgICAgICAgcmVzY250ID0gd2lkdGggKyBmbXRjbnQgKyAxMDA7CisgICAgICAgICAgICAgICAgcmVzbGVuICs9IHJlc2NudDsKKyAgICAgICAgICAgICAgICBpZiAocmVzbGVuIDwgMCkgeworICAgICAgICAgICAgICAgICAgICBQeV9ERUNSRUYocmVzdWx0KTsKKyAgICAgICAgICAgICAgICAgICAgUHlfWERFQ1JFRih0ZW1wKTsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIFB5RXJyX05vTWVtb3J5KCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGlmIChfUHlTdHJpbmdfUmVzaXplKCZyZXN1bHQsIHJlc2xlbikpIHsKKyAgICAgICAgICAgICAgICAgICAgUHlfWERFQ1JFRih0ZW1wKTsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHJlcyA9IFB5U3RyaW5nX0FTX1NUUklORyhyZXN1bHQpCisgICAgICAgICAgICAgICAgICAgICsgcmVzbGVuIC0gcmVzY250OworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKHNpZ24pIHsKKyAgICAgICAgICAgICAgICBpZiAoZmlsbCAhPSAnICcpCisgICAgICAgICAgICAgICAgICAgICpyZXMrKyA9IHNpZ247CisgICAgICAgICAgICAgICAgcmVzY250LS07CisgICAgICAgICAgICAgICAgaWYgKHdpZHRoID4gbGVuKQorICAgICAgICAgICAgICAgICAgICB3aWR0aC0tOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKChmbGFncyAmIEZfQUxUKSAmJiAoYyA9PSAneCcgfHwgYyA9PSAnWCcpKSB7CisgICAgICAgICAgICAgICAgYXNzZXJ0KHBidWZbMF0gPT0gJzAnKTsKKyAgICAgICAgICAgICAgICBhc3NlcnQocGJ1ZlsxXSA9PSBjKTsKKyAgICAgICAgICAgICAgICBpZiAoZmlsbCAhPSAnICcpIHsKKyAgICAgICAgICAgICAgICAgICAgKnJlcysrID0gKnBidWYrKzsKKyAgICAgICAgICAgICAgICAgICAgKnJlcysrID0gKnBidWYrKzsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgcmVzY250IC09IDI7CisgICAgICAgICAgICAgICAgd2lkdGggLT0gMjsKKyAgICAgICAgICAgICAgICBpZiAod2lkdGggPCAwKQorICAgICAgICAgICAgICAgICAgICB3aWR0aCA9IDA7CisgICAgICAgICAgICAgICAgbGVuIC09IDI7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAod2lkdGggPiBsZW4gJiYgIShmbGFncyAmIEZfTEpVU1QpKSB7CisgICAgICAgICAgICAgICAgZG8geworICAgICAgICAgICAgICAgICAgICAtLXJlc2NudDsKKyAgICAgICAgICAgICAgICAgICAgKnJlcysrID0gZmlsbDsKKyAgICAgICAgICAgICAgICB9IHdoaWxlICgtLXdpZHRoID4gbGVuKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChmaWxsID09ICcgJykgeworICAgICAgICAgICAgICAgIGlmIChzaWduKQorICAgICAgICAgICAgICAgICAgICAqcmVzKysgPSBzaWduOworICAgICAgICAgICAgICAgIGlmICgoZmxhZ3MgJiBGX0FMVCkgJiYKKyAgICAgICAgICAgICAgICAgICAgKGMgPT0gJ3gnIHx8IGMgPT0gJ1gnKSkgeworICAgICAgICAgICAgICAgICAgICBhc3NlcnQocGJ1ZlswXSA9PSAnMCcpOworICAgICAgICAgICAgICAgICAgICBhc3NlcnQocGJ1ZlsxXSA9PSBjKTsKKyAgICAgICAgICAgICAgICAgICAgKnJlcysrID0gKnBidWYrKzsKKyAgICAgICAgICAgICAgICAgICAgKnJlcysrID0gKnBidWYrKzsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICBQeV9NRU1DUFkocmVzLCBwYnVmLCBsZW4pOworICAgICAgICAgICAgcmVzICs9IGxlbjsKKyAgICAgICAgICAgIHJlc2NudCAtPSBsZW47CisgICAgICAgICAgICB3aGlsZSAoLS13aWR0aCA+PSBsZW4pIHsKKyAgICAgICAgICAgICAgICAtLXJlc2NudDsKKyAgICAgICAgICAgICAgICAqcmVzKysgPSAnICc7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoZGljdCAmJiAoYXJnaWR4IDwgYXJnbGVuKSAmJiBjICE9ICclJykgeworICAgICAgICAgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19UeXBlRXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAibm90IGFsbCBhcmd1bWVudHMgY29udmVydGVkIGR1cmluZyBzdHJpbmcgZm9ybWF0dGluZyIpOworICAgICAgICAgICAgICAgIFB5X1hERUNSRUYodGVtcCk7CisgICAgICAgICAgICAgICAgZ290byBlcnJvcjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIFB5X1hERUNSRUYodGVtcCk7CisgICAgICAgIH0gLyogJyUnICovCisgICAgfSAvKiB1bnRpbCBlbmQgKi8KKyAgICBpZiAoYXJnaWR4IDwgYXJnbGVuICYmICFkaWN0KSB7CisgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19UeXBlRXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAgICAibm90IGFsbCBhcmd1bWVudHMgY29udmVydGVkIGR1cmluZyBzdHJpbmcgZm9ybWF0dGluZyIpOworICAgICAgICBnb3RvIGVycm9yOworICAgIH0KKyAgICBpZiAoYXJnc19vd25lZCkgeworICAgICAgICBQeV9ERUNSRUYoYXJncyk7CisgICAgfQorICAgIGlmIChfUHlTdHJpbmdfUmVzaXplKCZyZXN1bHQsIHJlc2xlbiAtIHJlc2NudCkpCisgICAgICAgIHJldHVybiBOVUxMOworICAgIHJldHVybiByZXN1bHQ7CisKKyNpZmRlZiBQeV9VU0lOR19VTklDT0RFCisgdW5pY29kZToKKyAgICBpZiAoYXJnc19vd25lZCkgeworICAgICAgICBQeV9ERUNSRUYoYXJncyk7CisgICAgICAgIGFyZ3Nfb3duZWQgPSAwOworICAgIH0KKyAgICAvKiBGaWRkbGUgYXJncyByaWdodCAocmVtb3ZlIHRoZSBmaXJzdCBhcmdpZHggYXJndW1lbnRzKSAqLworICAgIGlmIChQeVR1cGxlX0NoZWNrKG9yaWdfYXJncykgJiYgYXJnaWR4ID4gMCkgeworICAgICAgICBQeU9iamVjdCAqdjsKKyAgICAgICAgUHlfc3NpemVfdCBuID0gUHlUdXBsZV9HRVRfU0laRShvcmlnX2FyZ3MpIC0gYXJnaWR4OworICAgICAgICB2ID0gUHlUdXBsZV9OZXcobik7CisgICAgICAgIGlmICh2ID09IE5VTEwpCisgICAgICAgICAgICBnb3RvIGVycm9yOworICAgICAgICB3aGlsZSAoLS1uID49IDApIHsKKyAgICAgICAgICAgIFB5T2JqZWN0ICp3ID0gUHlUdXBsZV9HRVRfSVRFTShvcmlnX2FyZ3MsIG4gKyBhcmdpZHgpOworICAgICAgICAgICAgUHlfSU5DUkVGKHcpOworICAgICAgICAgICAgUHlUdXBsZV9TRVRfSVRFTSh2LCBuLCB3KTsKKyAgICAgICAgfQorICAgICAgICBhcmdzID0gdjsKKyAgICB9IGVsc2UgeworICAgICAgICBQeV9JTkNSRUYob3JpZ19hcmdzKTsKKyAgICAgICAgYXJncyA9IG9yaWdfYXJnczsKKyAgICB9CisgICAgYXJnc19vd25lZCA9IDE7CisgICAgLyogVGFrZSB3aGF0IHdlIGhhdmUgb2YgdGhlIHJlc3VsdCBhbmQgbGV0IHRoZSBVbmljb2RlIGZvcm1hdHRpbmcKKyAgICAgICBmdW5jdGlvbiBmb3JtYXQgdGhlIHJlc3Qgb2YgdGhlIGlucHV0LiAqLworICAgIHJlc2NudCA9IHJlcyAtIFB5U3RyaW5nX0FTX1NUUklORyhyZXN1bHQpOworICAgIGlmIChfUHlTdHJpbmdfUmVzaXplKCZyZXN1bHQsIHJlc2NudCkpCisgICAgICAgIGdvdG8gZXJyb3I7CisgICAgZm10Y250ID0gUHlTdHJpbmdfR0VUX1NJWkUoZm9ybWF0KSAtIFwKKyAgICAgICAgICAgICAoZm10IC0gUHlTdHJpbmdfQVNfU1RSSU5HKGZvcm1hdCkpOworICAgIGZvcm1hdCA9IFB5VW5pY29kZV9EZWNvZGUoZm10LCBmbXRjbnQsIE5VTEwsIE5VTEwpOworICAgIGlmIChmb3JtYXQgPT0gTlVMTCkKKyAgICAgICAgZ290byBlcnJvcjsKKyAgICB2ID0gUHlVbmljb2RlX0Zvcm1hdChmb3JtYXQsIGFyZ3MpOworICAgIFB5X0RFQ1JFRihmb3JtYXQpOworICAgIGlmICh2ID09IE5VTEwpCisgICAgICAgIGdvdG8gZXJyb3I7CisgICAgLyogUGFzdGUgd2hhdCB3ZSBoYXZlIChyZXN1bHQpIHRvIHdoYXQgdGhlIFVuaWNvZGUgZm9ybWF0dGluZworICAgICAgIGZ1bmN0aW9uIHJldHVybmVkICh2KSBhbmQgcmV0dXJuIHRoZSByZXN1bHQgKG9yIGVycm9yKSAqLworICAgIHcgPSBQeVVuaWNvZGVfQ29uY2F0KHJlc3VsdCwgdik7CisgICAgUHlfREVDUkVGKHJlc3VsdCk7CisgICAgUHlfREVDUkVGKHYpOworICAgIFB5X0RFQ1JFRihhcmdzKTsKKyAgICByZXR1cm4gdzsKKyNlbmRpZiAvKiBQeV9VU0lOR19VTklDT0RFICovCisKKyBlcnJvcjoKKyAgICBQeV9ERUNSRUYocmVzdWx0KTsKKyAgICBpZiAoYXJnc19vd25lZCkgeworICAgICAgICBQeV9ERUNSRUYoYXJncyk7CisgICAgfQorICAgIHJldHVybiBOVUxMOworfQorCit2b2lkCitQeVN0cmluZ19JbnRlcm5JblBsYWNlKFB5T2JqZWN0ICoqcCkKK3sKKyAgICByZWdpc3RlciBQeVN0cmluZ09iamVjdCAqcyA9IChQeVN0cmluZ09iamVjdCAqKSgqcCk7CisgICAgUHlPYmplY3QgKnQ7CisgICAgaWYgKHMgPT0gTlVMTCB8fCAhUHlTdHJpbmdfQ2hlY2socykpCisgICAgICAgIFB5X0ZhdGFsRXJyb3IoIlB5U3RyaW5nX0ludGVybkluUGxhY2U6IHN0cmluZ3Mgb25seSBwbGVhc2UhIik7CisgICAgLyogSWYgaXQncyBhIHN0cmluZyBzdWJjbGFzcywgd2UgZG9uJ3QgcmVhbGx5IGtub3cgd2hhdCBwdXR0aW5nCisgICAgICAgaXQgaW4gdGhlIGludGVybmVkIGRpY3QgbWlnaHQgZG8uICovCisgICAgaWYgKCFQeVN0cmluZ19DaGVja0V4YWN0KHMpKQorICAgICAgICByZXR1cm47CisgICAgaWYgKFB5U3RyaW5nX0NIRUNLX0lOVEVSTkVEKHMpKQorICAgICAgICByZXR1cm47CisgICAgaWYgKGludGVybmVkID09IE5VTEwpIHsKKyAgICAgICAgaW50ZXJuZWQgPSBQeURpY3RfTmV3KCk7CisgICAgICAgIGlmIChpbnRlcm5lZCA9PSBOVUxMKSB7CisgICAgICAgICAgICBQeUVycl9DbGVhcigpOyAvKiBEb24ndCBsZWF2ZSBhbiBleGNlcHRpb24gKi8KKyAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorICAgIH0KKyAgICB0ID0gUHlEaWN0X0dldEl0ZW0oaW50ZXJuZWQsIChQeU9iamVjdCAqKXMpOworICAgIGlmICh0KSB7CisgICAgICAgIFB5X0lOQ1JFRih0KTsKKyAgICAgICAgUHlfREVDUkVGKCpwKTsKKyAgICAgICAgKnAgPSB0OworICAgICAgICByZXR1cm47CisgICAgfQorCisgICAgaWYgKFB5RGljdF9TZXRJdGVtKGludGVybmVkLCAoUHlPYmplY3QgKilzLCAoUHlPYmplY3QgKilzKSA8IDApIHsKKyAgICAgICAgUHlFcnJfQ2xlYXIoKTsKKyAgICAgICAgcmV0dXJuOworICAgIH0KKyAgICAvKiBUaGUgdHdvIHJlZmVyZW5jZXMgaW4gaW50ZXJuZWQgYXJlIG5vdCBjb3VudGVkIGJ5IHJlZmNudC4KKyAgICAgICBUaGUgc3RyaW5nIGRlYWxsb2NhdG9yIHdpbGwgdGFrZSBjYXJlIG9mIHRoaXMgKi8KKyAgICBQeV9SRUZDTlQocykgLT0gMjsKKyAgICBQeVN0cmluZ19DSEVDS19JTlRFUk5FRChzKSA9IFNTVEFURV9JTlRFUk5FRF9NT1JUQUw7Cit9CisKK3ZvaWQKK1B5U3RyaW5nX0ludGVybkltbW9ydGFsKFB5T2JqZWN0ICoqcCkKK3sKKyAgICBQeVN0cmluZ19JbnRlcm5JblBsYWNlKHApOworICAgIGlmIChQeVN0cmluZ19DSEVDS19JTlRFUk5FRCgqcCkgIT0gU1NUQVRFX0lOVEVSTkVEX0lNTU9SVEFMKSB7CisgICAgICAgIFB5U3RyaW5nX0NIRUNLX0lOVEVSTkVEKCpwKSA9IFNTVEFURV9JTlRFUk5FRF9JTU1PUlRBTDsKKyAgICAgICAgUHlfSU5DUkVGKCpwKTsKKyAgICB9Cit9CisKKworUHlPYmplY3QgKgorUHlTdHJpbmdfSW50ZXJuRnJvbVN0cmluZyhjb25zdCBjaGFyICpjcCkKK3sKKyAgICBQeU9iamVjdCAqcyA9IFB5U3RyaW5nX0Zyb21TdHJpbmcoY3ApOworICAgIGlmIChzID09IE5VTEwpCisgICAgICAgIHJldHVybiBOVUxMOworICAgIFB5U3RyaW5nX0ludGVybkluUGxhY2UoJnMpOworICAgIHJldHVybiBzOworfQorCit2b2lkCitQeVN0cmluZ19GaW5pKHZvaWQpCit7CisgICAgaW50IGk7CisgICAgZm9yIChpID0gMDsgaSA8IFVDSEFSX01BWCArIDE7IGkrKykKKyAgICAgICAgUHlfQ0xFQVIoY2hhcmFjdGVyc1tpXSk7CisgICAgUHlfQ0xFQVIobnVsbHN0cmluZyk7Cit9CisKK3ZvaWQgX1B5X1JlbGVhc2VJbnRlcm5lZFN0cmluZ3Modm9pZCkKK3sKKyAgICBQeU9iamVjdCAqa2V5czsKKyAgICBQeVN0cmluZ09iamVjdCAqczsKKyAgICBQeV9zc2l6ZV90IGksIG47CisgICAgUHlfc3NpemVfdCBpbW1vcnRhbF9zaXplID0gMCwgbW9ydGFsX3NpemUgPSAwOworCisgICAgaWYgKGludGVybmVkID09IE5VTEwgfHwgIVB5RGljdF9DaGVjayhpbnRlcm5lZCkpCisgICAgICAgIHJldHVybjsKKyAgICBrZXlzID0gUHlEaWN0X0tleXMoaW50ZXJuZWQpOworICAgIGlmIChrZXlzID09IE5VTEwgfHwgIVB5TGlzdF9DaGVjayhrZXlzKSkgeworICAgICAgICBQeUVycl9DbGVhcigpOworICAgICAgICByZXR1cm47CisgICAgfQorCisgICAgLyogU2luY2UgX1B5X1JlbGVhc2VJbnRlcm5lZFN0cmluZ3MoKSBpcyBpbnRlbmRlZCB0byBoZWxwIGEgbGVhaworICAgICAgIGRldGVjdG9yLCBpbnRlcm5lZCBzdHJpbmdzIGFyZSBub3QgZm9yY2libHkgZGVhbGxvY2F0ZWQ7IHJhdGhlciwgd2UKKyAgICAgICBnaXZlIHRoZW0gdGhlaXIgc3RvbGVuIHJlZmVyZW5jZXMgYmFjaywgYW5kIHRoZW4gY2xlYXIgYW5kIERFQ1JFRgorICAgICAgIHRoZSBpbnRlcm5lZCBkaWN0LiAqLworCisgICAgbiA9IFB5TGlzdF9HRVRfU0laRShrZXlzKTsKKyAgICBmcHJpbnRmKHN0ZGVyciwgInJlbGVhc2luZyAlIiBQWV9GT1JNQVRfU0laRV9UICJkIGludGVybmVkIHN0cmluZ3NcbiIsCisgICAgICAgIG4pOworICAgIGZvciAoaSA9IDA7IGkgPCBuOyBpKyspIHsKKyAgICAgICAgcyA9IChQeVN0cmluZ09iamVjdCAqKSBQeUxpc3RfR0VUX0lURU0oa2V5cywgaSk7CisgICAgICAgIHN3aXRjaCAocy0+b2Jfc3N0YXRlKSB7CisgICAgICAgIGNhc2UgU1NUQVRFX05PVF9JTlRFUk5FRDoKKyAgICAgICAgICAgIC8qIFhYWCBTaG91bGRuJ3QgaGFwcGVuICovCisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgY2FzZSBTU1RBVEVfSU5URVJORURfSU1NT1JUQUw6CisgICAgICAgICAgICBQeV9SRUZDTlQocykgKz0gMTsKKyAgICAgICAgICAgIGltbW9ydGFsX3NpemUgKz0gUHlfU0laRShzKTsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICBjYXNlIFNTVEFURV9JTlRFUk5FRF9NT1JUQUw6CisgICAgICAgICAgICBQeV9SRUZDTlQocykgKz0gMjsKKyAgICAgICAgICAgIG1vcnRhbF9zaXplICs9IFB5X1NJWkUocyk7CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAgIFB5X0ZhdGFsRXJyb3IoIkluY29uc2lzdGVudCBpbnRlcm5lZCBzdHJpbmcgc3RhdGUuIik7CisgICAgICAgIH0KKyAgICAgICAgcy0+b2Jfc3N0YXRlID0gU1NUQVRFX05PVF9JTlRFUk5FRDsKKyAgICB9CisgICAgZnByaW50ZihzdGRlcnIsICJ0b3RhbCBzaXplIG9mIGFsbCBpbnRlcm5lZCBzdHJpbmdzOiAiCisgICAgICAgICAgICAgICAgICAgICIlIiBQWV9GT1JNQVRfU0laRV9UICJkLyUiIFBZX0ZPUk1BVF9TSVpFX1QgImQgIgorICAgICAgICAgICAgICAgICAgICAibW9ydGFsL2ltbW9ydGFsXG4iLCBtb3J0YWxfc2l6ZSwgaW1tb3J0YWxfc2l6ZSk7CisgICAgUHlfREVDUkVGKGtleXMpOworICAgIFB5RGljdF9DbGVhcihpbnRlcm5lZCk7CisgICAgUHlfQ0xFQVIoaW50ZXJuZWQpOworfQpkaWZmIC0tZ2l0IGEvUHl0aG9uLTIuNy41L09iamVjdHMvc3RydWN0c2VxLmMgYi9QeXRob24tMi43LjUvT2JqZWN0cy9zdHJ1Y3RzZXEuYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi43NWMxZmZiCi0tLSAvZGV2L251bGwKKysrIGIvUHl0aG9uLTIuNy41L09iamVjdHMvc3RydWN0c2VxLmMKQEAgLTAsMCArMSw1NDAgQEAKKy8qIEltcGxlbWVudGF0aW9uIGhlbHBlcjogYSBzdHJ1Y3QgdGhhdCBsb29rcyBsaWtlIGEgdHVwbGUuICBTZWUgdGltZW1vZHVsZQorICAgYW5kIHBvc2l4bW9kdWxlIGZvciBleGFtcGxlIHVzZXMuICovCisKKyNpbmNsdWRlICJQeXRob24uaCIKKyNpbmNsdWRlICJzdHJ1Y3RtZW1iZXIuaCIKKyNpbmNsdWRlICJzdHJ1Y3RzZXEuaCIKKworc3RhdGljIGNoYXIgdmlzaWJsZV9sZW5ndGhfa2V5W10gPSAibl9zZXF1ZW5jZV9maWVsZHMiOworc3RhdGljIGNoYXIgcmVhbF9sZW5ndGhfa2V5W10gPSAibl9maWVsZHMiOworc3RhdGljIGNoYXIgdW5uYW1lZF9maWVsZHNfa2V5W10gPSAibl91bm5hbWVkX2ZpZWxkcyI7CisKKy8qIEZpZWxkcyB3aXRoIHRoaXMgbmFtZSBoYXZlIG9ubHkgYSBmaWVsZCBpbmRleCwgbm90IGEgZmllbGQgbmFtZS4KKyAgIFRoZXkgYXJlIG9ubHkgYWxsb3dlZCBmb3IgaW5kaWNlcyA8IG5fdmlzaWJsZV9maWVsZHMuICovCitjaGFyICpQeVN0cnVjdFNlcXVlbmNlX1VubmFtZWRGaWVsZCA9ICJ1bm5hbWVkIGZpZWxkIjsKKworI2RlZmluZSBWSVNJQkxFX1NJWkUob3ApIFB5X1NJWkUob3ApCisjZGVmaW5lIFZJU0lCTEVfU0laRV9UUCh0cCkgUHlJbnRfQXNMb25nKCBcCisgICAgICAgICAgICAgICAgICAgICAgUHlEaWN0X0dldEl0ZW1TdHJpbmcoKHRwKS0+dHBfZGljdCwgdmlzaWJsZV9sZW5ndGhfa2V5KSkKKworI2RlZmluZSBSRUFMX1NJWkVfVFAodHApIFB5SW50X0FzTG9uZyggXAorICAgICAgICAgICAgICAgICAgICAgIFB5RGljdF9HZXRJdGVtU3RyaW5nKCh0cCktPnRwX2RpY3QsIHJlYWxfbGVuZ3RoX2tleSkpCisjZGVmaW5lIFJFQUxfU0laRShvcCkgUkVBTF9TSVpFX1RQKFB5X1RZUEUob3ApKQorCisjZGVmaW5lIFVOTkFNRURfRklFTERTX1RQKHRwKSBQeUludF9Bc0xvbmcoIFwKKyAgICAgICAgICAgICAgICAgICAgICBQeURpY3RfR2V0SXRlbVN0cmluZygodHApLT50cF9kaWN0LCB1bm5hbWVkX2ZpZWxkc19rZXkpKQorI2RlZmluZSBVTk5BTUVEX0ZJRUxEUyhvcCkgVU5OQU1FRF9GSUVMRFNfVFAoUHlfVFlQRShvcCkpCisKKworUHlPYmplY3QgKgorUHlTdHJ1Y3RTZXF1ZW5jZV9OZXcoUHlUeXBlT2JqZWN0ICp0eXBlKQoreworICAgIFB5U3RydWN0U2VxdWVuY2UgKm9iajsKKworICAgIG9iaiA9IFB5T2JqZWN0X05ldyhQeVN0cnVjdFNlcXVlbmNlLCB0eXBlKTsKKyAgICBpZiAob2JqID09IE5VTEwpCisgICAgICAgIHJldHVybiBOVUxMOworICAgIFB5X1NJWkUob2JqKSA9IFZJU0lCTEVfU0laRV9UUCh0eXBlKTsKKworICAgIHJldHVybiAoUHlPYmplY3QqKSBvYmo7Cit9CisKK3N0YXRpYyB2b2lkCitzdHJ1Y3RzZXFfZGVhbGxvYyhQeVN0cnVjdFNlcXVlbmNlICpvYmopCit7CisgICAgUHlfc3NpemVfdCBpLCBzaXplOworCisgICAgc2l6ZSA9IFJFQUxfU0laRShvYmopOworICAgIGZvciAoaSA9IDA7IGkgPCBzaXplOyArK2kpIHsKKyAgICAgICAgUHlfWERFQ1JFRihvYmotPm9iX2l0ZW1baV0pOworICAgIH0KKyAgICBQeU9iamVjdF9EZWwob2JqKTsKK30KKworc3RhdGljIFB5X3NzaXplX3QKK3N0cnVjdHNlcV9sZW5ndGgoUHlTdHJ1Y3RTZXF1ZW5jZSAqb2JqKQoreworICAgIHJldHVybiBWSVNJQkxFX1NJWkUob2JqKTsKK30KKworc3RhdGljIFB5T2JqZWN0Kgorc3RydWN0c2VxX2l0ZW0oUHlTdHJ1Y3RTZXF1ZW5jZSAqb2JqLCBQeV9zc2l6ZV90IGkpCit7CisgICAgaWYgKGkgPCAwIHx8IGkgPj0gVklTSUJMRV9TSVpFKG9iaikpIHsKKyAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX0luZGV4RXJyb3IsICJ0dXBsZSBpbmRleCBvdXQgb2YgcmFuZ2UiKTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIFB5X0lOQ1JFRihvYmotPm9iX2l0ZW1baV0pOworICAgIHJldHVybiBvYmotPm9iX2l0ZW1baV07Cit9CisKK3N0YXRpYyBQeU9iamVjdCoKK3N0cnVjdHNlcV9zbGljZShQeVN0cnVjdFNlcXVlbmNlICpvYmosIFB5X3NzaXplX3QgbG93LCBQeV9zc2l6ZV90IGhpZ2gpCit7CisgICAgUHlUdXBsZU9iamVjdCAqbnA7CisgICAgUHlfc3NpemVfdCBpOworCisgICAgaWYgKGxvdyA8IDApCisgICAgICAgIGxvdyA9IDA7CisgICAgaWYgKGhpZ2ggPiBWSVNJQkxFX1NJWkUob2JqKSkKKyAgICAgICAgaGlnaCA9IFZJU0lCTEVfU0laRShvYmopOworICAgIGlmIChoaWdoIDwgbG93KQorICAgICAgICBoaWdoID0gbG93OworICAgIG5wID0gKFB5VHVwbGVPYmplY3QgKilQeVR1cGxlX05ldyhoaWdoLWxvdyk7CisgICAgaWYgKG5wID09IE5VTEwpCisgICAgICAgIHJldHVybiBOVUxMOworICAgIGZvcihpID0gbG93OyBpIDwgaGlnaDsgKytpKSB7CisgICAgICAgIFB5T2JqZWN0ICp2ID0gb2JqLT5vYl9pdGVtW2ldOworICAgICAgICBQeV9JTkNSRUYodik7CisgICAgICAgIFB5VHVwbGVfU0VUX0lURU0obnAsIGktbG93LCB2KTsKKyAgICB9CisgICAgcmV0dXJuIChQeU9iamVjdCAqKSBucDsKK30KKworc3RhdGljIFB5T2JqZWN0ICoKK3N0cnVjdHNlcV9zdWJzY3JpcHQoUHlTdHJ1Y3RTZXF1ZW5jZSAqc2VsZiwgUHlPYmplY3QgKml0ZW0pCit7CisgICAgaWYgKFB5SW5kZXhfQ2hlY2soaXRlbSkpIHsKKyAgICAgICAgUHlfc3NpemVfdCBpID0gUHlOdW1iZXJfQXNTc2l6ZV90KGl0ZW0sIFB5RXhjX0luZGV4RXJyb3IpOworICAgICAgICBpZiAoaSA9PSAtMSAmJiBQeUVycl9PY2N1cnJlZCgpKQorICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisKKyAgICAgICAgaWYgKGkgPCAwKQorICAgICAgICAgICAgaSArPSBWSVNJQkxFX1NJWkUoc2VsZik7CisKKyAgICAgICAgaWYgKGkgPCAwIHx8IGkgPj0gVklTSUJMRV9TSVpFKHNlbGYpKSB7CisgICAgICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfSW5kZXhFcnJvciwKKyAgICAgICAgICAgICAgICAidHVwbGUgaW5kZXggb3V0IG9mIHJhbmdlIik7CisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgfQorICAgICAgICBQeV9JTkNSRUYoc2VsZi0+b2JfaXRlbVtpXSk7CisgICAgICAgIHJldHVybiBzZWxmLT5vYl9pdGVtW2ldOworICAgIH0KKyAgICBlbHNlIGlmIChQeVNsaWNlX0NoZWNrKGl0ZW0pKSB7CisgICAgICAgIFB5X3NzaXplX3Qgc3RhcnQsIHN0b3AsIHN0ZXAsIHNsaWNlbGVuLCBjdXIsIGk7CisgICAgICAgIFB5T2JqZWN0ICpyZXN1bHQ7CisKKyAgICAgICAgaWYgKFB5U2xpY2VfR2V0SW5kaWNlc0V4KChQeVNsaWNlT2JqZWN0ICopaXRlbSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFZJU0lCTEVfU0laRShzZWxmKSwgJnN0YXJ0LCAmc3RvcCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZzdGVwLCAmc2xpY2VsZW4pIDwgMCkgeworICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgICAgIH0KKyAgICAgICAgaWYgKHNsaWNlbGVuIDw9IDApCisgICAgICAgICAgICByZXR1cm4gUHlUdXBsZV9OZXcoMCk7CisgICAgICAgIHJlc3VsdCA9IFB5VHVwbGVfTmV3KHNsaWNlbGVuKTsKKyAgICAgICAgaWYgKHJlc3VsdCA9PSBOVUxMKQorICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgICAgIGZvciAoY3VyID0gc3RhcnQsIGkgPSAwOyBpIDwgc2xpY2VsZW47CisgICAgICAgICAgICAgY3VyICs9IHN0ZXAsIGkrKykgeworICAgICAgICAgICAgUHlPYmplY3QgKnYgPSBzZWxmLT5vYl9pdGVtW2N1cl07CisgICAgICAgICAgICBQeV9JTkNSRUYodik7CisgICAgICAgICAgICBQeVR1cGxlX1NFVF9JVEVNKHJlc3VsdCwgaSwgdik7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICB9CisgICAgZWxzZSB7CisgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19UeXBlRXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAgICAic3RydWN0c2VxIGluZGV4IG11c3QgYmUgaW50ZWdlciIpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9Cit9CisKK3N0YXRpYyBQeU9iamVjdCAqCitzdHJ1Y3RzZXFfbmV3KFB5VHlwZU9iamVjdCAqdHlwZSwgUHlPYmplY3QgKmFyZ3MsIFB5T2JqZWN0ICprd2RzKQoreworICAgIFB5T2JqZWN0ICphcmcgPSBOVUxMOworICAgIFB5T2JqZWN0ICpkaWN0ID0gTlVMTDsKKyAgICBQeU9iamVjdCAqb2I7CisgICAgUHlTdHJ1Y3RTZXF1ZW5jZSAqcmVzID0gTlVMTDsKKyAgICBQeV9zc2l6ZV90IGxlbiwgbWluX2xlbiwgbWF4X2xlbiwgaSwgbl91bm5hbWVkX2ZpZWxkczsKKyAgICBzdGF0aWMgY2hhciAqa3dsaXN0W10gPSB7InNlcXVlbmNlIiwgImRpY3QiLCAwfTsKKworICAgIGlmICghUHlBcmdfUGFyc2VUdXBsZUFuZEtleXdvcmRzKGFyZ3MsIGt3ZHMsICJPfE86c3RydWN0c2VxIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBrd2xpc3QsICZhcmcsICZkaWN0KSkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisKKyAgICBhcmcgPSBQeVNlcXVlbmNlX0Zhc3QoYXJnLCAiY29uc3RydWN0b3IgcmVxdWlyZXMgYSBzZXF1ZW5jZSIpOworCisgICAgaWYgKCFhcmcpIHsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorCisgICAgaWYgKGRpY3QgJiYgIVB5RGljdF9DaGVjayhkaWN0KSkgeworICAgICAgICBQeUVycl9Gb3JtYXQoUHlFeGNfVHlwZUVycm9yLAorICAgICAgICAgICAgICAgICAgICAgIiUuNTAwcygpIHRha2VzIGEgZGljdCBhcyBzZWNvbmQgYXJnLCBpZiBhbnkiLAorICAgICAgICAgICAgICAgICAgICAgdHlwZS0+dHBfbmFtZSk7CisgICAgICAgIFB5X0RFQ1JFRihhcmcpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisKKyAgICBsZW4gPSBQeVNlcXVlbmNlX0Zhc3RfR0VUX1NJWkUoYXJnKTsKKyAgICBtaW5fbGVuID0gVklTSUJMRV9TSVpFX1RQKHR5cGUpOworICAgIG1heF9sZW4gPSBSRUFMX1NJWkVfVFAodHlwZSk7CisgICAgbl91bm5hbWVkX2ZpZWxkcyA9IFVOTkFNRURfRklFTERTX1RQKHR5cGUpOworCisgICAgaWYgKG1pbl9sZW4gIT0gbWF4X2xlbikgeworICAgICAgICBpZiAobGVuIDwgbWluX2xlbikgeworICAgICAgICAgICAgUHlFcnJfRm9ybWF0KFB5RXhjX1R5cGVFcnJvciwKKyAgICAgICAgICAgICAgICAiJS41MDBzKCkgdGFrZXMgYW4gYXQgbGVhc3QgJXpkLXNlcXVlbmNlICglemQtc2VxdWVuY2UgZ2l2ZW4pIiwKKyAgICAgICAgICAgICAgICB0eXBlLT50cF9uYW1lLCBtaW5fbGVuLCBsZW4pOworICAgICAgICAgICAgUHlfREVDUkVGKGFyZyk7CisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChsZW4gPiBtYXhfbGVuKSB7CisgICAgICAgICAgICBQeUVycl9Gb3JtYXQoUHlFeGNfVHlwZUVycm9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICIlLjUwMHMoKSB0YWtlcyBhbiBhdCBtb3N0ICV6ZC1zZXF1ZW5jZSAoJXpkLXNlcXVlbmNlIGdpdmVuKSIsCisgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZS0+dHBfbmFtZSwgbWF4X2xlbiwgbGVuKTsKKyAgICAgICAgICAgIFB5X0RFQ1JFRihhcmcpOworICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgICAgIH0KKyAgICB9CisgICAgZWxzZSB7CisgICAgICAgIGlmIChsZW4gIT0gbWluX2xlbikgeworICAgICAgICAgICAgUHlFcnJfRm9ybWF0KFB5RXhjX1R5cGVFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAiJS41MDBzKCkgdGFrZXMgYSAlemQtc2VxdWVuY2UgKCV6ZC1zZXF1ZW5jZSBnaXZlbikiLAorICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGUtPnRwX25hbWUsIG1pbl9sZW4sIGxlbik7CisgICAgICAgICAgICBQeV9ERUNSRUYoYXJnKTsKKyAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgICAgICB9CisgICAgfQorCisgICAgcmVzID0gKFB5U3RydWN0U2VxdWVuY2UqKSBQeVN0cnVjdFNlcXVlbmNlX05ldyh0eXBlKTsKKyAgICBpZiAocmVzID09IE5VTEwpIHsKKyAgICAgICAgUHlfREVDUkVGKGFyZyk7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICBmb3IgKGkgPSAwOyBpIDwgbGVuOyArK2kpIHsKKyAgICAgICAgUHlPYmplY3QgKnYgPSBQeVNlcXVlbmNlX0Zhc3RfR0VUX0lURU0oYXJnLCBpKTsKKyAgICAgICAgUHlfSU5DUkVGKHYpOworICAgICAgICByZXMtPm9iX2l0ZW1baV0gPSB2OworICAgIH0KKyAgICBmb3IgKDsgaSA8IG1heF9sZW47ICsraSkgeworICAgICAgICBpZiAoZGljdCAmJiAob2IgPSBQeURpY3RfR2V0SXRlbVN0cmluZygKKyAgICAgICAgICAgIGRpY3QsIHR5cGUtPnRwX21lbWJlcnNbaS1uX3VubmFtZWRfZmllbGRzXS5uYW1lKSkpIHsKKyAgICAgICAgfQorICAgICAgICBlbHNlIHsKKyAgICAgICAgICAgIG9iID0gUHlfTm9uZTsKKyAgICAgICAgfQorICAgICAgICBQeV9JTkNSRUYob2IpOworICAgICAgICByZXMtPm9iX2l0ZW1baV0gPSBvYjsKKyAgICB9CisKKyAgICBQeV9ERUNSRUYoYXJnKTsKKyAgICByZXR1cm4gKFB5T2JqZWN0KikgcmVzOworfQorCitzdGF0aWMgUHlPYmplY3QgKgorbWFrZV90dXBsZShQeVN0cnVjdFNlcXVlbmNlICpvYmopCit7CisgICAgcmV0dXJuIHN0cnVjdHNlcV9zbGljZShvYmosIDAsIFZJU0lCTEVfU0laRShvYmopKTsKK30KKworc3RhdGljIFB5T2JqZWN0ICoKK3N0cnVjdHNlcV9yZXByKFB5U3RydWN0U2VxdWVuY2UgKm9iaikKK3sKKyAgICAvKiBidWZmZXIgYW5kIHR5cGUgc2l6ZSB3ZXJlIGNob3NlbiB3ZWxsIGNvbnNpZGVyZWQuICovCisjZGVmaW5lIFJFUFJfQlVGRkVSX1NJWkUgNTEyCisjZGVmaW5lIFRZUEVfTUFYU0laRSAxMDAKKworICAgIFB5T2JqZWN0ICp0dXA7CisgICAgUHlUeXBlT2JqZWN0ICp0eXAgPSBQeV9UWVBFKG9iaik7CisgICAgaW50IGksIHJlbW92ZWxhc3QgPSAwOworICAgIFB5X3NzaXplX3QgbGVuOworICAgIGNoYXIgYnVmW1JFUFJfQlVGRkVSX1NJWkVdOworICAgIGNoYXIgKmVuZG9mYnVmLCAqcGJ1ZiA9IGJ1ZjsKKworICAgIC8qIHBvaW50ZXIgdG8gZW5kIG9mIHdyaXRlYWJsZSBidWZmZXI7IHNhZmVzIHNwYWNlIGZvciAiLi4uKVwwIiAqLworICAgIGVuZG9mYnVmPSAmYnVmW1JFUFJfQlVGRkVSX1NJWkUtNV07CisKKyAgICBpZiAoKHR1cCA9IG1ha2VfdHVwbGUob2JqKSkgPT0gTlVMTCkgeworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisKKyAgICAvKiAidHlwZW5hbWUoIiwgbGltaXRlZCB0byAgVFlQRV9NQVhTSVpFICovCisgICAgbGVuID0gc3RybGVuKHR5cC0+dHBfbmFtZSkgPiBUWVBFX01BWFNJWkUgPyBUWVBFX01BWFNJWkUgOgorICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cmxlbih0eXAtPnRwX25hbWUpOworICAgIHN0cm5jcHkocGJ1ZiwgdHlwLT50cF9uYW1lLCBsZW4pOworICAgIHBidWYgKz0gbGVuOworICAgICpwYnVmKysgPSAnKCc7CisKKyAgICBmb3IgKGk9MDsgaSA8IFZJU0lCTEVfU0laRShvYmopOyBpKyspIHsKKyAgICAgICAgUHlPYmplY3QgKnZhbCwgKnJlcHI7CisgICAgICAgIGNoYXIgKmNuYW1lLCAqY3JlcHI7CisKKyAgICAgICAgY25hbWUgPSB0eXAtPnRwX21lbWJlcnNbaV0ubmFtZTsKKworICAgICAgICB2YWwgPSBQeVR1cGxlX0dldEl0ZW0odHVwLCBpKTsKKyAgICAgICAgaWYgKGNuYW1lID09IE5VTEwgfHwgdmFsID09IE5VTEwpIHsKKyAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgICAgICB9CisgICAgICAgIHJlcHIgPSBQeU9iamVjdF9SZXByKHZhbCk7CisgICAgICAgIGlmIChyZXByID09IE5VTEwpIHsKKyAgICAgICAgICAgIFB5X0RFQ1JFRih0dXApOworICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgICAgIH0KKyAgICAgICAgY3JlcHIgPSBQeVN0cmluZ19Bc1N0cmluZyhyZXByKTsKKyAgICAgICAgaWYgKGNyZXByID09IE5VTEwpIHsKKyAgICAgICAgICAgIFB5X0RFQ1JFRih0dXApOworICAgICAgICAgICAgUHlfREVDUkVGKHJlcHIpOworICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgICAgIH0KKworICAgICAgICAvKiArIDM6IGtlZXAgc3BhY2UgZm9yICI9IiBhbmQgIiwgIiAqLworICAgICAgICBsZW4gPSBzdHJsZW4oY25hbWUpICsgc3RybGVuKGNyZXByKSArIDM7CisgICAgICAgIGlmICgocGJ1ZitsZW4pIDw9IGVuZG9mYnVmKSB7CisgICAgICAgICAgICBzdHJjcHkocGJ1ZiwgY25hbWUpOworICAgICAgICAgICAgcGJ1ZiArPSBzdHJsZW4oY25hbWUpOworICAgICAgICAgICAgKnBidWYrKyA9ICc9JzsKKyAgICAgICAgICAgIHN0cmNweShwYnVmLCBjcmVwcik7CisgICAgICAgICAgICBwYnVmICs9IHN0cmxlbihjcmVwcik7CisgICAgICAgICAgICAqcGJ1ZisrID0gJywnOworICAgICAgICAgICAgKnBidWYrKyA9ICcgJzsKKyAgICAgICAgICAgIHJlbW92ZWxhc3QgPSAxOworICAgICAgICAgICAgUHlfREVDUkVGKHJlcHIpOworICAgICAgICB9CisgICAgICAgIGVsc2UgeworICAgICAgICAgICAgc3RyY3B5KHBidWYsICIuLi4iKTsKKyAgICAgICAgICAgIHBidWYgKz0gMzsKKyAgICAgICAgICAgIHJlbW92ZWxhc3QgPSAwOworICAgICAgICAgICAgUHlfREVDUkVGKHJlcHIpOworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKyAgICB9CisgICAgUHlfREVDUkVGKHR1cCk7CisgICAgaWYgKHJlbW92ZWxhc3QpIHsKKyAgICAgICAgLyogb3ZlcndyaXRlIGxhc3QgIiwgIiAqLworICAgICAgICBwYnVmLT0yOworICAgIH0KKyAgICAqcGJ1ZisrID0gJyknOworICAgICpwYnVmID0gJ1wwJzsKKworICAgIHJldHVybiBQeVN0cmluZ19Gcm9tU3RyaW5nKGJ1Zik7Cit9CisKK3N0YXRpYyBQeU9iamVjdCAqCitzdHJ1Y3RzZXFfY29uY2F0KFB5U3RydWN0U2VxdWVuY2UgKm9iaiwgUHlPYmplY3QgKmIpCit7CisgICAgUHlPYmplY3QgKnR1cCwgKnJlc3VsdDsKKyAgICB0dXAgPSBtYWtlX3R1cGxlKG9iaik7CisgICAgcmVzdWx0ID0gUHlTZXF1ZW5jZV9Db25jYXQodHVwLCBiKTsKKyAgICBQeV9ERUNSRUYodHVwKTsKKyAgICByZXR1cm4gcmVzdWx0OworfQorCitzdGF0aWMgUHlPYmplY3QgKgorc3RydWN0c2VxX3JlcGVhdChQeVN0cnVjdFNlcXVlbmNlICpvYmosIFB5X3NzaXplX3QgbikKK3sKKyAgICBQeU9iamVjdCAqdHVwLCAqcmVzdWx0OworICAgIHR1cCA9IG1ha2VfdHVwbGUob2JqKTsKKyAgICByZXN1bHQgPSBQeVNlcXVlbmNlX1JlcGVhdCh0dXAsIG4pOworICAgIFB5X0RFQ1JFRih0dXApOworICAgIHJldHVybiByZXN1bHQ7Cit9CisKK3N0YXRpYyBpbnQKK3N0cnVjdHNlcV9jb250YWlucyhQeVN0cnVjdFNlcXVlbmNlICpvYmosIFB5T2JqZWN0ICpvKQoreworICAgIFB5T2JqZWN0ICp0dXA7CisgICAgaW50IHJlc3VsdDsKKyAgICB0dXAgPSBtYWtlX3R1cGxlKG9iaik7CisgICAgaWYgKCF0dXApCisgICAgICAgIHJldHVybiAtMTsKKyAgICByZXN1bHQgPSBQeVNlcXVlbmNlX0NvbnRhaW5zKHR1cCwgbyk7CisgICAgUHlfREVDUkVGKHR1cCk7CisgICAgcmV0dXJuIHJlc3VsdDsKK30KKworc3RhdGljIGxvbmcKK3N0cnVjdHNlcV9oYXNoKFB5T2JqZWN0ICpvYmopCit7CisgICAgUHlPYmplY3QgKnR1cDsKKyAgICBsb25nIHJlc3VsdDsKKyAgICB0dXAgPSBtYWtlX3R1cGxlKChQeVN0cnVjdFNlcXVlbmNlKikgb2JqKTsKKyAgICBpZiAoIXR1cCkKKyAgICAgICAgcmV0dXJuIC0xOworICAgIHJlc3VsdCA9IFB5T2JqZWN0X0hhc2godHVwKTsKKyAgICBQeV9ERUNSRUYodHVwKTsKKyAgICByZXR1cm4gcmVzdWx0OworfQorCitzdGF0aWMgUHlPYmplY3QgKgorc3RydWN0c2VxX3JpY2hjb21wYXJlKFB5T2JqZWN0ICpvYmosIFB5T2JqZWN0ICpvMiwgaW50IG9wKQoreworICAgIFB5T2JqZWN0ICp0dXAsICpyZXN1bHQ7CisgICAgdHVwID0gbWFrZV90dXBsZSgoUHlTdHJ1Y3RTZXF1ZW5jZSopIG9iaik7CisgICAgcmVzdWx0ID0gUHlPYmplY3RfUmljaENvbXBhcmUodHVwLCBvMiwgb3ApOworICAgIFB5X0RFQ1JFRih0dXApOworICAgIHJldHVybiByZXN1bHQ7Cit9CisKK3N0YXRpYyBQeU9iamVjdCAqCitzdHJ1Y3RzZXFfcmVkdWNlKFB5U3RydWN0U2VxdWVuY2UqIHNlbGYpCit7CisgICAgUHlPYmplY3QqIHR1cDsKKyAgICBQeU9iamVjdCogZGljdDsKKyAgICBQeU9iamVjdCogcmVzdWx0OworICAgIFB5X3NzaXplX3Qgbl9maWVsZHMsIG5fdmlzaWJsZV9maWVsZHMsIG5fdW5uYW1lZF9maWVsZHM7CisgICAgaW50IGk7CisKKyAgICBuX2ZpZWxkcyA9IFJFQUxfU0laRShzZWxmKTsKKyAgICBuX3Zpc2libGVfZmllbGRzID0gVklTSUJMRV9TSVpFKHNlbGYpOworICAgIG5fdW5uYW1lZF9maWVsZHMgPSBVTk5BTUVEX0ZJRUxEUyhzZWxmKTsKKyAgICB0dXAgPSBQeVR1cGxlX05ldyhuX3Zpc2libGVfZmllbGRzKTsKKyAgICBpZiAoIXR1cCkgeworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisKKyAgICBkaWN0ID0gUHlEaWN0X05ldygpOworICAgIGlmICghZGljdCkgeworICAgICAgICBQeV9ERUNSRUYodHVwKTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorCisgICAgZm9yIChpID0gMDsgaSA8IG5fdmlzaWJsZV9maWVsZHM7IGkrKykgeworICAgICAgICBQeV9JTkNSRUYoc2VsZi0+b2JfaXRlbVtpXSk7CisgICAgICAgIFB5VHVwbGVfU0VUX0lURU0odHVwLCBpLCBzZWxmLT5vYl9pdGVtW2ldKTsKKyAgICB9CisKKyAgICBmb3IgKDsgaSA8IG5fZmllbGRzOyBpKyspIHsKKyAgICAgICAgY2hhciAqbiA9IFB5X1RZUEUoc2VsZiktPnRwX21lbWJlcnNbaS1uX3VubmFtZWRfZmllbGRzXS5uYW1lOworICAgICAgICBQeURpY3RfU2V0SXRlbVN0cmluZyhkaWN0LCBuLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLT5vYl9pdGVtW2ldKTsKKyAgICB9CisKKyAgICByZXN1bHQgPSBQeV9CdWlsZFZhbHVlKCIoTyhPTykpIiwgUHlfVFlQRShzZWxmKSwgdHVwLCBkaWN0KTsKKworICAgIFB5X0RFQ1JFRih0dXApOworICAgIFB5X0RFQ1JFRihkaWN0KTsKKworICAgIHJldHVybiByZXN1bHQ7Cit9CisKK3N0YXRpYyBQeVNlcXVlbmNlTWV0aG9kcyBzdHJ1Y3RzZXFfYXNfc2VxdWVuY2UgPSB7CisgICAgKGxlbmZ1bmMpc3RydWN0c2VxX2xlbmd0aCwKKyAgICAoYmluYXJ5ZnVuYylzdHJ1Y3RzZXFfY29uY2F0LCAgICAgICAgICAgLyogc3FfY29uY2F0ICovCisgICAgKHNzaXplYXJnZnVuYylzdHJ1Y3RzZXFfcmVwZWF0LCAgICAgICAgIC8qIHNxX3JlcGVhdCAqLworICAgIChzc2l6ZWFyZ2Z1bmMpc3RydWN0c2VxX2l0ZW0sICAgICAgICAgICAgICAgLyogc3FfaXRlbSAqLworICAgIChzc2l6ZXNzaXplYXJnZnVuYylzdHJ1Y3RzZXFfc2xpY2UsICAgICAgICAgLyogc3Ffc2xpY2UgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHNxX2Fzc19pdGVtICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBzcV9hc3Nfc2xpY2UgKi8KKyAgICAob2Jqb2JqcHJvYylzdHJ1Y3RzZXFfY29udGFpbnMsICAgICAgICAgICAgIC8qIHNxX2NvbnRhaW5zICovCit9OworCitzdGF0aWMgUHlNYXBwaW5nTWV0aG9kcyBzdHJ1Y3RzZXFfYXNfbWFwcGluZyA9IHsKKyAgICAobGVuZnVuYylzdHJ1Y3RzZXFfbGVuZ3RoLAorICAgIChiaW5hcnlmdW5jKXN0cnVjdHNlcV9zdWJzY3JpcHQsCit9OworCitzdGF0aWMgUHlNZXRob2REZWYgc3RydWN0c2VxX21ldGhvZHNbXSA9IHsKKyAgICB7Il9fcmVkdWNlX18iLCAoUHlDRnVuY3Rpb24pc3RydWN0c2VxX3JlZHVjZSwKKyAgICAgTUVUSF9OT0FSR1MsIE5VTEx9LAorICAgIHtOVUxMLCBOVUxMfQorfTsKKworc3RhdGljIFB5VHlwZU9iamVjdCBfc3RydWN0X3NlcXVlbmNlX3RlbXBsYXRlID0geworICAgIFB5VmFyT2JqZWN0X0hFQURfSU5JVCgmUHlUeXBlX1R5cGUsIDApCisgICAgTlVMTCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9uYW1lICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9iYXNpY3NpemUgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2l0ZW1zaXplICovCisgICAgKGRlc3RydWN0b3Ipc3RydWN0c2VxX2RlYWxsb2MsICAgICAgICAgICAgICAvKiB0cF9kZWFsbG9jICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9wcmludCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZ2V0YXR0ciAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfc2V0YXR0ciAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfY29tcGFyZSAqLworICAgIChyZXByZnVuYylzdHJ1Y3RzZXFfcmVwciwgICAgICAgICAgICAgICAgICAgLyogdHBfcmVwciAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfYXNfbnVtYmVyICovCisgICAgJnN0cnVjdHNlcV9hc19zZXF1ZW5jZSwgICAgICAgICAgICAgICAgICAgICAvKiB0cF9hc19zZXF1ZW5jZSAqLworICAgICZzdHJ1Y3RzZXFfYXNfbWFwcGluZywgICAgICAgICAgICAgICAgICAgICAgLyogdHBfYXNfbWFwcGluZyAqLworICAgIHN0cnVjdHNlcV9oYXNoLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfaGFzaCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfY2FsbCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfc3RyICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9nZXRhdHRybyAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfc2V0YXR0cm8gKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2FzX2J1ZmZlciAqLworICAgIFB5X1RQRkxBR1NfREVGQVVMVCwgICAgICAgICAgICAgICAgICAgICAvKiB0cF9mbGFncyAqLworICAgIE5VTEwsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZG9jICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF90cmF2ZXJzZSAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfY2xlYXIgKi8KKyAgICBzdHJ1Y3RzZXFfcmljaGNvbXBhcmUsICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3JpY2hjb21wYXJlICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF93ZWFrbGlzdG9mZnNldCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfaXRlciAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfaXRlcm5leHQgKi8KKyAgICBzdHJ1Y3RzZXFfbWV0aG9kcywgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX21ldGhvZHMgKi8KKyAgICBOVUxMLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX21lbWJlcnMgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2dldHNldCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfYmFzZSAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZGljdCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZGVzY3JfZ2V0ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9kZXNjcl9zZXQgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2RpY3RvZmZzZXQgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2luaXQgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2FsbG9jICovCisgICAgc3RydWN0c2VxX25ldywgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9uZXcgKi8KK307CisKK3ZvaWQKK1B5U3RydWN0U2VxdWVuY2VfSW5pdFR5cGUoUHlUeXBlT2JqZWN0ICp0eXBlLCBQeVN0cnVjdFNlcXVlbmNlX0Rlc2MgKmRlc2MpCit7CisgICAgUHlPYmplY3QgKmRpY3Q7CisgICAgUHlNZW1iZXJEZWYqIG1lbWJlcnM7CisgICAgaW50IG5fbWVtYmVycywgbl91bm5hbWVkX21lbWJlcnMsIGksIGs7CisKKyNpZmRlZiBQeV9UUkFDRV9SRUZTCisgICAgLyogaWYgdGhlIHR5cGUgb2JqZWN0IHdhcyBjaGFpbmVkLCB1bmNoYWluIGl0IGZpcnN0CisgICAgICAgYmVmb3JlIG92ZXJ3cml0aW5nIGl0cyBzdG9yYWdlICovCisgICAgaWYgKHR5cGUtPl9vYl9uZXh0KSB7CisgICAgICAgIF9QeV9Gb3JnZXRSZWZlcmVuY2UoKFB5T2JqZWN0Kil0eXBlKTsKKyAgICB9CisjZW5kaWYKKworICAgIG5fdW5uYW1lZF9tZW1iZXJzID0gMDsKKyAgICBmb3IgKGkgPSAwOyBkZXNjLT5maWVsZHNbaV0ubmFtZSAhPSBOVUxMOyArK2kpCisgICAgICAgIGlmIChkZXNjLT5maWVsZHNbaV0ubmFtZSA9PSBQeVN0cnVjdFNlcXVlbmNlX1VubmFtZWRGaWVsZCkKKyAgICAgICAgICAgIG5fdW5uYW1lZF9tZW1iZXJzKys7CisgICAgbl9tZW1iZXJzID0gaTsKKworICAgIG1lbWNweSh0eXBlLCAmX3N0cnVjdF9zZXF1ZW5jZV90ZW1wbGF0ZSwgc2l6ZW9mKFB5VHlwZU9iamVjdCkpOworICAgIHR5cGUtPnRwX25hbWUgPSBkZXNjLT5uYW1lOworICAgIHR5cGUtPnRwX2RvYyA9IGRlc2MtPmRvYzsKKyAgICB0eXBlLT50cF9iYXNpY3NpemUgPSBzaXplb2YoUHlTdHJ1Y3RTZXF1ZW5jZSkrCisgICAgICAgIHNpemVvZihQeU9iamVjdCopKihuX21lbWJlcnMtMSk7CisgICAgdHlwZS0+dHBfaXRlbXNpemUgPSAwOworCisgICAgbWVtYmVycyA9IFB5TWVtX05FVyhQeU1lbWJlckRlZiwgbl9tZW1iZXJzLW5fdW5uYW1lZF9tZW1iZXJzKzEpOworICAgIGlmIChtZW1iZXJzID09IE5VTEwpCisgICAgICAgIHJldHVybjsKKworICAgIGZvciAoaSA9IGsgPSAwOyBpIDwgbl9tZW1iZXJzOyArK2kpIHsKKyAgICAgICAgaWYgKGRlc2MtPmZpZWxkc1tpXS5uYW1lID09IFB5U3RydWN0U2VxdWVuY2VfVW5uYW1lZEZpZWxkKQorICAgICAgICAgICAgY29udGludWU7CisgICAgICAgIG1lbWJlcnNba10ubmFtZSA9IGRlc2MtPmZpZWxkc1tpXS5uYW1lOworICAgICAgICBtZW1iZXJzW2tdLnR5cGUgPSBUX09CSkVDVDsKKyAgICAgICAgbWVtYmVyc1trXS5vZmZzZXQgPSBvZmZzZXRvZihQeVN0cnVjdFNlcXVlbmNlLCBvYl9pdGVtKQorICAgICAgICAgICsgaSAqIHNpemVvZihQeU9iamVjdCopOworICAgICAgICBtZW1iZXJzW2tdLmZsYWdzID0gUkVBRE9OTFk7CisgICAgICAgIG1lbWJlcnNba10uZG9jID0gZGVzYy0+ZmllbGRzW2ldLmRvYzsKKyAgICAgICAgaysrOworICAgIH0KKyAgICBtZW1iZXJzW2tdLm5hbWUgPSBOVUxMOworCisgICAgdHlwZS0+dHBfbWVtYmVycyA9IG1lbWJlcnM7CisKKyAgICBpZiAoUHlUeXBlX1JlYWR5KHR5cGUpIDwgMCkKKyAgICAgICAgcmV0dXJuOworICAgIFB5X0lOQ1JFRih0eXBlKTsKKworICAgIGRpY3QgPSB0eXBlLT50cF9kaWN0OworI2RlZmluZSBTRVRfRElDVF9GUk9NX0lOVChrZXksIHZhbHVlKSAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICBkbyB7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgIFB5T2JqZWN0ICp2ID0gUHlJbnRfRnJvbUxvbmcoKGxvbmcpIHZhbHVlKTsgICAgICAgICAgICAgXAorICAgICAgICBpZiAodiAhPSBOVUxMKSB7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICAgIFB5RGljdF9TZXRJdGVtU3RyaW5nKGRpY3QsIGtleSwgdik7ICAgICAgICAgICAgICAgICBcCisgICAgICAgICAgICBQeV9ERUNSRUYodik7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICB9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICB9IHdoaWxlICgwKQorCisgICAgU0VUX0RJQ1RfRlJPTV9JTlQodmlzaWJsZV9sZW5ndGhfa2V5LCBkZXNjLT5uX2luX3NlcXVlbmNlKTsKKyAgICBTRVRfRElDVF9GUk9NX0lOVChyZWFsX2xlbmd0aF9rZXksIG5fbWVtYmVycyk7CisgICAgU0VUX0RJQ1RfRlJPTV9JTlQodW5uYW1lZF9maWVsZHNfa2V5LCBuX3VubmFtZWRfbWVtYmVycyk7Cit9CmRpZmYgLS1naXQgYS9QeXRob24tMi43LjUvT2JqZWN0cy90dXBsZW9iamVjdC5jIGIvUHl0aG9uLTIuNy41L09iamVjdHMvdHVwbGVvYmplY3QuYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4wMGYyZTQ3Ci0tLSAvZGV2L251bGwKKysrIGIvUHl0aG9uLTIuNy41L09iamVjdHMvdHVwbGVvYmplY3QuYwpAQCAtMCwwICsxLDEwNTQgQEAKKworLyogVHVwbGUgb2JqZWN0IGltcGxlbWVudGF0aW9uICovCisKKyNpbmNsdWRlICJQeXRob24uaCIKKworLyogU3BlZWQgb3B0aW1pemF0aW9uIHRvIGF2b2lkIGZyZXF1ZW50IG1hbGxvYy9mcmVlIG9mIHNtYWxsIHR1cGxlcyAqLworI2lmbmRlZiBQeVR1cGxlX01BWFNBVkVTSVpFCisjZGVmaW5lIFB5VHVwbGVfTUFYU0FWRVNJWkUgICAgIDIwICAvKiBMYXJnZXN0IHR1cGxlIHRvIHNhdmUgb24gZnJlZSBsaXN0ICovCisjZW5kaWYKKyNpZm5kZWYgUHlUdXBsZV9NQVhGUkVFTElTVAorI2RlZmluZSBQeVR1cGxlX01BWEZSRUVMSVNUICAyMDAwICAvKiBNYXhpbXVtIG51bWJlciBvZiB0dXBsZXMgb2YgZWFjaCBzaXplIHRvIHNhdmUgKi8KKyNlbmRpZgorCisjaWYgUHlUdXBsZV9NQVhTQVZFU0laRSA+IDAKKy8qIEVudHJpZXMgMSB1cCB0byBQeVR1cGxlX01BWFNBVkVTSVpFIGFyZSBmcmVlIGxpc3RzLCBlbnRyeSAwIGlzIHRoZSBlbXB0eQorICAgdHVwbGUgKCkgb2Ygd2hpY2ggYXQgbW9zdCBvbmUgaW5zdGFuY2Ugd2lsbCBiZSBhbGxvY2F0ZWQuCisqLworc3RhdGljIFB5VHVwbGVPYmplY3QgKmZyZWVfbGlzdFtQeVR1cGxlX01BWFNBVkVTSVpFXTsKK3N0YXRpYyBpbnQgbnVtZnJlZVtQeVR1cGxlX01BWFNBVkVTSVpFXTsKKyNlbmRpZgorI2lmZGVmIENPVU5UX0FMTE9DUworUHlfc3NpemVfdCBmYXN0X3R1cGxlX2FsbG9jczsKK1B5X3NzaXplX3QgdHVwbGVfemVyb19hbGxvY3M7CisjZW5kaWYKKworLyogRGVidWcgc3RhdGlzdGljIHRvIGNvdW50IEdDIHRyYWNraW5nIG9mIHR1cGxlcy4KKyAgIFBsZWFzZSBub3RlIHRoYXQgdHVwbGVzIGFyZSBvbmx5IHVudHJhY2tlZCB3aGVuIGNvbnNpZGVyZWQgYnkgdGhlIEdDLCBhbmQKKyAgIG1hbnkgb2YgdGhlbSB3aWxsIGJlIGRlYWQgYmVmb3JlLiBUaGVyZWZvcmUsIGEgdHJhY2tpbmcgcmF0ZSBjbG9zZSB0byAxMDAlCisgICBkb2VzIG5vdCBuZWNlc3NhcmlseSBwcm92ZSB0aGF0IHRoZSBoZXVyaXN0aWMgaXMgaW5lZmZpY2llbnQuCisqLworI2lmZGVmIFNIT1dfVFJBQ0tfQ09VTlQKK3N0YXRpYyBQeV9zc2l6ZV90IGNvdW50X3VudHJhY2tlZCA9IDA7CitzdGF0aWMgUHlfc3NpemVfdCBjb3VudF90cmFja2VkID0gMDsKKworc3RhdGljIHZvaWQKK3Nob3dfdHJhY2sodm9pZCkKK3sKKyAgICBmcHJpbnRmKHN0ZGVyciwgIlR1cGxlcyBjcmVhdGVkOiAlIiBQWV9GT1JNQVRfU0laRV9UICJkXG4iLAorICAgICAgICBjb3VudF90cmFja2VkICsgY291bnRfdW50cmFja2VkKTsKKyAgICBmcHJpbnRmKHN0ZGVyciwgIlR1cGxlcyB0cmFja2VkIGJ5IHRoZSBHQzogJSIgUFlfRk9STUFUX1NJWkVfVAorICAgICAgICAiZFxuIiwgY291bnRfdHJhY2tlZCk7CisgICAgZnByaW50ZihzdGRlcnIsICIlLjJmJSUgdHVwbGUgdHJhY2tpbmcgcmF0ZVxuXG4iLAorICAgICAgICAoMTAwLjAqY291bnRfdHJhY2tlZC8oY291bnRfdW50cmFja2VkK2NvdW50X3RyYWNrZWQpKSk7Cit9CisjZW5kaWYKKworCitQeU9iamVjdCAqCitQeVR1cGxlX05ldyhyZWdpc3RlciBQeV9zc2l6ZV90IHNpemUpCit7CisgICAgcmVnaXN0ZXIgUHlUdXBsZU9iamVjdCAqb3A7CisgICAgUHlfc3NpemVfdCBpOworICAgIGlmIChzaXplIDwgMCkgeworICAgICAgICBQeUVycl9CYWRJbnRlcm5hbENhbGwoKTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorI2lmIFB5VHVwbGVfTUFYU0FWRVNJWkUgPiAwCisgICAgaWYgKHNpemUgPT0gMCAmJiBmcmVlX2xpc3RbMF0pIHsKKyAgICAgICAgb3AgPSBmcmVlX2xpc3RbMF07CisgICAgICAgIFB5X0lOQ1JFRihvcCk7CisjaWZkZWYgQ09VTlRfQUxMT0NTCisgICAgICAgIHR1cGxlX3plcm9fYWxsb2NzKys7CisjZW5kaWYKKyAgICAgICAgcmV0dXJuIChQeU9iamVjdCAqKSBvcDsKKyAgICB9CisgICAgaWYgKHNpemUgPCBQeVR1cGxlX01BWFNBVkVTSVpFICYmIChvcCA9IGZyZWVfbGlzdFtzaXplXSkgIT0gTlVMTCkgeworICAgICAgICBmcmVlX2xpc3Rbc2l6ZV0gPSAoUHlUdXBsZU9iamVjdCAqKSBvcC0+b2JfaXRlbVswXTsKKyAgICAgICAgbnVtZnJlZVtzaXplXS0tOworI2lmZGVmIENPVU5UX0FMTE9DUworICAgICAgICBmYXN0X3R1cGxlX2FsbG9jcysrOworI2VuZGlmCisgICAgICAgIC8qIElubGluZSBQeU9iamVjdF9Jbml0VmFyICovCisjaWZkZWYgUHlfVFJBQ0VfUkVGUworICAgICAgICBQeV9TSVpFKG9wKSA9IHNpemU7CisgICAgICAgIFB5X1RZUEUob3ApID0gJlB5VHVwbGVfVHlwZTsKKyNlbmRpZgorICAgICAgICBfUHlfTmV3UmVmZXJlbmNlKChQeU9iamVjdCAqKW9wKTsKKyAgICB9CisgICAgZWxzZQorI2VuZGlmCisgICAgeworICAgICAgICBQeV9zc2l6ZV90IG5ieXRlcyA9IHNpemUgKiBzaXplb2YoUHlPYmplY3QgKik7CisgICAgICAgIC8qIENoZWNrIGZvciBvdmVyZmxvdyAqLworICAgICAgICBpZiAobmJ5dGVzIC8gc2l6ZW9mKFB5T2JqZWN0ICopICE9IChzaXplX3Qpc2l6ZSB8fAorICAgICAgICAgICAgKG5ieXRlcyA+IFBZX1NTSVpFX1RfTUFYIC0gc2l6ZW9mKFB5VHVwbGVPYmplY3QpIC0gc2l6ZW9mKFB5T2JqZWN0ICopKSkKKyAgICAgICAgeworICAgICAgICAgICAgcmV0dXJuIFB5RXJyX05vTWVtb3J5KCk7CisgICAgICAgIH0KKworICAgICAgICBvcCA9IFB5T2JqZWN0X0dDX05ld1ZhcihQeVR1cGxlT2JqZWN0LCAmUHlUdXBsZV9UeXBlLCBzaXplKTsKKyAgICAgICAgaWYgKG9wID09IE5VTEwpCisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgZm9yIChpPTA7IGkgPCBzaXplOyBpKyspCisgICAgICAgIG9wLT5vYl9pdGVtW2ldID0gTlVMTDsKKyNpZiBQeVR1cGxlX01BWFNBVkVTSVpFID4gMAorICAgIGlmIChzaXplID09IDApIHsKKyAgICAgICAgZnJlZV9saXN0WzBdID0gb3A7CisgICAgICAgICsrbnVtZnJlZVswXTsKKyAgICAgICAgUHlfSU5DUkVGKG9wKTsgICAgICAgICAgLyogZXh0cmEgSU5DUkVGIHNvIHRoYXQgdGhpcyBpcyBuZXZlciBmcmVlZCAqLworICAgIH0KKyNlbmRpZgorI2lmZGVmIFNIT1dfVFJBQ0tfQ09VTlQKKyAgICBjb3VudF90cmFja2VkKys7CisjZW5kaWYKKyAgICBfUHlPYmplY3RfR0NfVFJBQ0sob3ApOworICAgIHJldHVybiAoUHlPYmplY3QgKikgb3A7Cit9CisKK1B5X3NzaXplX3QKK1B5VHVwbGVfU2l6ZShyZWdpc3RlciBQeU9iamVjdCAqb3ApCit7CisgICAgaWYgKCFQeVR1cGxlX0NoZWNrKG9wKSkgeworICAgICAgICBQeUVycl9CYWRJbnRlcm5hbENhbGwoKTsKKyAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKyAgICBlbHNlCisgICAgICAgIHJldHVybiBQeV9TSVpFKG9wKTsKK30KKworUHlPYmplY3QgKgorUHlUdXBsZV9HZXRJdGVtKHJlZ2lzdGVyIFB5T2JqZWN0ICpvcCwgcmVnaXN0ZXIgUHlfc3NpemVfdCBpKQoreworICAgIGlmICghUHlUdXBsZV9DaGVjayhvcCkpIHsKKyAgICAgICAgUHlFcnJfQmFkSW50ZXJuYWxDYWxsKCk7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICBpZiAoaSA8IDAgfHwgaSA+PSBQeV9TSVpFKG9wKSkgeworICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfSW5kZXhFcnJvciwgInR1cGxlIGluZGV4IG91dCBvZiByYW5nZSIpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgcmV0dXJuICgoUHlUdXBsZU9iamVjdCAqKW9wKSAtPiBvYl9pdGVtW2ldOworfQorCitpbnQKK1B5VHVwbGVfU2V0SXRlbShyZWdpc3RlciBQeU9iamVjdCAqb3AsIHJlZ2lzdGVyIFB5X3NzaXplX3QgaSwgUHlPYmplY3QgKm5ld2l0ZW0pCit7CisgICAgcmVnaXN0ZXIgUHlPYmplY3QgKm9sZGl0ZW07CisgICAgcmVnaXN0ZXIgUHlPYmplY3QgKipwOworICAgIGlmICghUHlUdXBsZV9DaGVjayhvcCkgfHwgb3AtPm9iX3JlZmNudCAhPSAxKSB7CisgICAgICAgIFB5X1hERUNSRUYobmV3aXRlbSk7CisgICAgICAgIFB5RXJyX0JhZEludGVybmFsQ2FsbCgpOworICAgICAgICByZXR1cm4gLTE7CisgICAgfQorICAgIGlmIChpIDwgMCB8fCBpID49IFB5X1NJWkUob3ApKSB7CisgICAgICAgIFB5X1hERUNSRUYobmV3aXRlbSk7CisgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19JbmRleEVycm9yLAorICAgICAgICAgICAgICAgICAgICAgICAgInR1cGxlIGFzc2lnbm1lbnQgaW5kZXggb3V0IG9mIHJhbmdlIik7CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisgICAgcCA9ICgoUHlUdXBsZU9iamVjdCAqKW9wKSAtPiBvYl9pdGVtICsgaTsKKyAgICBvbGRpdGVtID0gKnA7CisgICAgKnAgPSBuZXdpdGVtOworICAgIFB5X1hERUNSRUYob2xkaXRlbSk7CisgICAgcmV0dXJuIDA7Cit9CisKK3ZvaWQKK19QeVR1cGxlX01heWJlVW50cmFjayhQeU9iamVjdCAqb3ApCit7CisgICAgUHlUdXBsZU9iamVjdCAqdDsKKyAgICBQeV9zc2l6ZV90IGksIG47CisKKyAgICBpZiAoIVB5VHVwbGVfQ2hlY2tFeGFjdChvcCkgfHwgIV9QeU9iamVjdF9HQ19JU19UUkFDS0VEKG9wKSkKKyAgICAgICAgcmV0dXJuOworICAgIHQgPSAoUHlUdXBsZU9iamVjdCAqKSBvcDsKKyAgICBuID0gUHlfU0laRSh0KTsKKyAgICBmb3IgKGkgPSAwOyBpIDwgbjsgaSsrKSB7CisgICAgICAgIFB5T2JqZWN0ICplbHQgPSBQeVR1cGxlX0dFVF9JVEVNKHQsIGkpOworICAgICAgICAvKiBUdXBsZSB3aXRoIE5VTEwgZWxlbWVudHMgYXJlbid0CisgICAgICAgICAgIGZ1bGx5IGNvbnN0cnVjdGVkLCBkb24ndCB1bnRyYWNrCisgICAgICAgICAgIHRoZW0geWV0LiAqLworICAgICAgICBpZiAoIWVsdCB8fAorICAgICAgICAgICAgX1B5T2JqZWN0X0dDX01BWV9CRV9UUkFDS0VEKGVsdCkpCisgICAgICAgICAgICByZXR1cm47CisgICAgfQorI2lmZGVmIFNIT1dfVFJBQ0tfQ09VTlQKKyAgICBjb3VudF90cmFja2VkLS07CisgICAgY291bnRfdW50cmFja2VkKys7CisjZW5kaWYKKyAgICBfUHlPYmplY3RfR0NfVU5UUkFDSyhvcCk7Cit9CisKK1B5T2JqZWN0ICoKK1B5VHVwbGVfUGFjayhQeV9zc2l6ZV90IG4sIC4uLikKK3sKKyAgICBQeV9zc2l6ZV90IGk7CisgICAgUHlPYmplY3QgKm87CisgICAgUHlPYmplY3QgKnJlc3VsdDsKKyAgICBQeU9iamVjdCAqKml0ZW1zOworICAgIHZhX2xpc3QgdmFyZ3M7CisKKyAgICB2YV9zdGFydCh2YXJncywgbik7CisgICAgcmVzdWx0ID0gUHlUdXBsZV9OZXcobik7CisgICAgaWYgKHJlc3VsdCA9PSBOVUxMKSB7CisgICAgICAgIHZhX2VuZCh2YXJncyk7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICBpdGVtcyA9ICgoUHlUdXBsZU9iamVjdCAqKXJlc3VsdCktPm9iX2l0ZW07CisgICAgZm9yIChpID0gMDsgaSA8IG47IGkrKykgeworICAgICAgICBvID0gdmFfYXJnKHZhcmdzLCBQeU9iamVjdCAqKTsKKyAgICAgICAgUHlfSU5DUkVGKG8pOworICAgICAgICBpdGVtc1tpXSA9IG87CisgICAgfQorICAgIHZhX2VuZCh2YXJncyk7CisgICAgcmV0dXJuIHJlc3VsdDsKK30KKworCisvKiBNZXRob2RzICovCisKK3N0YXRpYyB2b2lkCit0dXBsZWRlYWxsb2MocmVnaXN0ZXIgUHlUdXBsZU9iamVjdCAqb3ApCit7CisgICAgcmVnaXN0ZXIgUHlfc3NpemVfdCBpOworICAgIHJlZ2lzdGVyIFB5X3NzaXplX3QgbGVuID0gIFB5X1NJWkUob3ApOworICAgIFB5T2JqZWN0X0dDX1VuVHJhY2sob3ApOworICAgIFB5X1RSQVNIQ0FOX1NBRkVfQkVHSU4ob3ApCisgICAgaWYgKGxlbiA+IDApIHsKKyAgICAgICAgaSA9IGxlbjsKKyAgICAgICAgd2hpbGUgKC0taSA+PSAwKQorICAgICAgICAgICAgUHlfWERFQ1JFRihvcC0+b2JfaXRlbVtpXSk7CisjaWYgUHlUdXBsZV9NQVhTQVZFU0laRSA+IDAKKyAgICAgICAgaWYgKGxlbiA8IFB5VHVwbGVfTUFYU0FWRVNJWkUgJiYKKyAgICAgICAgICAgIG51bWZyZWVbbGVuXSA8IFB5VHVwbGVfTUFYRlJFRUxJU1QgJiYKKyAgICAgICAgICAgIFB5X1RZUEUob3ApID09ICZQeVR1cGxlX1R5cGUpCisgICAgICAgIHsKKyAgICAgICAgICAgIG9wLT5vYl9pdGVtWzBdID0gKFB5T2JqZWN0ICopIGZyZWVfbGlzdFtsZW5dOworICAgICAgICAgICAgbnVtZnJlZVtsZW5dKys7CisgICAgICAgICAgICBmcmVlX2xpc3RbbGVuXSA9IG9wOworICAgICAgICAgICAgZ290byBkb25lOyAvKiByZXR1cm4gKi8KKyAgICAgICAgfQorI2VuZGlmCisgICAgfQorICAgIFB5X1RZUEUob3ApLT50cF9mcmVlKChQeU9iamVjdCAqKW9wKTsKK2RvbmU6CisgICAgUHlfVFJBU0hDQU5fU0FGRV9FTkQob3ApCit9CisKK3N0YXRpYyBpbnQKK3R1cGxlcHJpbnQoUHlUdXBsZU9iamVjdCAqb3AsIEZJTEUgKmZwLCBpbnQgZmxhZ3MpCit7CisgICAgUHlfc3NpemVfdCBpOworICAgIFB5X0JFR0lOX0FMTE9XX1RIUkVBRFMKKyAgICBmcHJpbnRmKGZwLCAiKCIpOworICAgIFB5X0VORF9BTExPV19USFJFQURTCisgICAgZm9yIChpID0gMDsgaSA8IFB5X1NJWkUob3ApOyBpKyspIHsKKyAgICAgICAgaWYgKGkgPiAwKSB7CisgICAgICAgICAgICBQeV9CRUdJTl9BTExPV19USFJFQURTCisgICAgICAgICAgICBmcHJpbnRmKGZwLCAiLCAiKTsKKyAgICAgICAgICAgIFB5X0VORF9BTExPV19USFJFQURTCisgICAgICAgIH0KKyAgICAgICAgaWYgKFB5T2JqZWN0X1ByaW50KG9wLT5vYl9pdGVtW2ldLCBmcCwgMCkgIT0gMCkKKyAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisgICAgaSA9IFB5X1NJWkUob3ApOworICAgIFB5X0JFR0lOX0FMTE9XX1RIUkVBRFMKKyAgICBpZiAoaSA9PSAxKQorICAgICAgICBmcHJpbnRmKGZwLCAiLCIpOworICAgIGZwcmludGYoZnAsICIpIik7CisgICAgUHlfRU5EX0FMTE9XX1RIUkVBRFMKKyAgICByZXR1cm4gMDsKK30KKworc3RhdGljIFB5T2JqZWN0ICoKK3R1cGxlcmVwcihQeVR1cGxlT2JqZWN0ICp2KQoreworICAgIFB5X3NzaXplX3QgaSwgbjsKKyAgICBQeU9iamVjdCAqcywgKnRlbXA7CisgICAgUHlPYmplY3QgKnBpZWNlcywgKnJlc3VsdCA9IE5VTEw7CisKKyAgICBuID0gUHlfU0laRSh2KTsKKyAgICBpZiAobiA9PSAwKQorICAgICAgICByZXR1cm4gUHlTdHJpbmdfRnJvbVN0cmluZygiKCkiKTsKKworICAgIC8qIFdoaWxlIG5vdCBtdXRhYmxlLCBpdCBpcyBzdGlsbCBwb3NzaWJsZSB0byBlbmQgdXAgd2l0aCBhIGN5Y2xlIGluIGEKKyAgICAgICB0dXBsZSB0aHJvdWdoIGFuIG9iamVjdCB0aGF0IHN0b3JlcyBpdHNlbGYgd2l0aGluIGEgdHVwbGUgKGFuZCB0aHVzCisgICAgICAgaW5maW5pdGVseSBhc2tzIGZvciB0aGUgcmVwciBvZiBpdHNlbGYpLiBUaGlzIHNob3VsZCBvbmx5IGJlCisgICAgICAgcG9zc2libGUgd2l0aGluIGEgdHlwZS4gKi8KKyAgICBpID0gUHlfUmVwckVudGVyKChQeU9iamVjdCAqKXYpOworICAgIGlmIChpICE9IDApIHsKKyAgICAgICAgcmV0dXJuIGkgPiAwID8gUHlTdHJpbmdfRnJvbVN0cmluZygiKC4uLikiKSA6IE5VTEw7CisgICAgfQorCisgICAgcGllY2VzID0gUHlUdXBsZV9OZXcobik7CisgICAgaWYgKHBpZWNlcyA9PSBOVUxMKQorICAgICAgICByZXR1cm4gTlVMTDsKKworICAgIC8qIERvIHJlcHIoKSBvbiBlYWNoIGVsZW1lbnQuICovCisgICAgZm9yIChpID0gMDsgaSA8IG47ICsraSkgeworICAgICAgICBpZiAoUHlfRW50ZXJSZWN1cnNpdmVDYWxsKCIgd2hpbGUgZ2V0dGluZyB0aGUgcmVwciBvZiBhIHR1cGxlIikpCisgICAgICAgICAgICBnb3RvIERvbmU7CisgICAgICAgIHMgPSBQeU9iamVjdF9SZXByKHYtPm9iX2l0ZW1baV0pOworICAgICAgICBQeV9MZWF2ZVJlY3Vyc2l2ZUNhbGwoKTsKKyAgICAgICAgaWYgKHMgPT0gTlVMTCkKKyAgICAgICAgICAgIGdvdG8gRG9uZTsKKyAgICAgICAgUHlUdXBsZV9TRVRfSVRFTShwaWVjZXMsIGksIHMpOworICAgIH0KKworICAgIC8qIEFkZCAiKCkiIGRlY29yYXRpb25zIHRvIHRoZSBmaXJzdCBhbmQgbGFzdCBpdGVtcy4gKi8KKyAgICBhc3NlcnQobiA+IDApOworICAgIHMgPSBQeVN0cmluZ19Gcm9tU3RyaW5nKCIoIik7CisgICAgaWYgKHMgPT0gTlVMTCkKKyAgICAgICAgZ290byBEb25lOworICAgIHRlbXAgPSBQeVR1cGxlX0dFVF9JVEVNKHBpZWNlcywgMCk7CisgICAgUHlTdHJpbmdfQ29uY2F0QW5kRGVsKCZzLCB0ZW1wKTsKKyAgICBQeVR1cGxlX1NFVF9JVEVNKHBpZWNlcywgMCwgcyk7CisgICAgaWYgKHMgPT0gTlVMTCkKKyAgICAgICAgZ290byBEb25lOworCisgICAgcyA9IFB5U3RyaW5nX0Zyb21TdHJpbmcobiA9PSAxID8gIiwpIiA6ICIpIik7CisgICAgaWYgKHMgPT0gTlVMTCkKKyAgICAgICAgZ290byBEb25lOworICAgIHRlbXAgPSBQeVR1cGxlX0dFVF9JVEVNKHBpZWNlcywgbi0xKTsKKyAgICBQeVN0cmluZ19Db25jYXRBbmREZWwoJnRlbXAsIHMpOworICAgIFB5VHVwbGVfU0VUX0lURU0ocGllY2VzLCBuLTEsIHRlbXApOworICAgIGlmICh0ZW1wID09IE5VTEwpCisgICAgICAgIGdvdG8gRG9uZTsKKworICAgIC8qIFBhc3RlIHRoZW0gYWxsIHRvZ2V0aGVyIHdpdGggIiwgIiBiZXR3ZWVuLiAqLworICAgIHMgPSBQeVN0cmluZ19Gcm9tU3RyaW5nKCIsICIpOworICAgIGlmIChzID09IE5VTEwpCisgICAgICAgIGdvdG8gRG9uZTsKKyAgICByZXN1bHQgPSBfUHlTdHJpbmdfSm9pbihzLCBwaWVjZXMpOworICAgIFB5X0RFQ1JFRihzKTsKKworRG9uZToKKyAgICBQeV9ERUNSRUYocGllY2VzKTsKKyAgICBQeV9SZXByTGVhdmUoKFB5T2JqZWN0ICopdik7CisgICAgcmV0dXJuIHJlc3VsdDsKK30KKworLyogVGhlIGFkZGVuZCA4MjUyMCwgd2FzIHNlbGVjdGVkIGZyb20gdGhlIHJhbmdlKDAsIDEwMDAwMDApIGZvcgorICAgZ2VuZXJhdGluZyB0aGUgZ3JlYXRlc3QgbnVtYmVyIG9mIHByaW1lIG11bHRpcGxpZXJzIGZvciB0dXBsZXMKKyAgIHVwdG8gbGVuZ3RoIGVpZ2h0OgorCisgICAgIDEwODI1MjcsIDExNjUwNDksIDEwODI1MzEsIDExNjUwNTcsIDEyNDc1ODEsIDEzMzAxMDMsIDEwODI1MzMsCisgICAgIDEzMzAxMTEsIDE0MTI2MzMsIDExNjUwNjksIDEyNDc1OTksIDE0OTUxNzcsIDE1Nzc2OTkKKyovCisKK3N0YXRpYyBsb25nCit0dXBsZWhhc2goUHlUdXBsZU9iamVjdCAqdikKK3sKKyAgICByZWdpc3RlciBsb25nIHgsIHk7CisgICAgcmVnaXN0ZXIgUHlfc3NpemVfdCBsZW4gPSBQeV9TSVpFKHYpOworICAgIHJlZ2lzdGVyIFB5T2JqZWN0ICoqcDsKKyAgICBsb25nIG11bHQgPSAxMDAwMDAzTDsKKyAgICB4ID0gMHgzNDU2NzhMOworICAgIHAgPSB2LT5vYl9pdGVtOworICAgIHdoaWxlICgtLWxlbiA+PSAwKSB7CisgICAgICAgIHkgPSBQeU9iamVjdF9IYXNoKCpwKyspOworICAgICAgICBpZiAoeSA9PSAtMSkKKyAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgeCA9ICh4IF4geSkgKiBtdWx0OworICAgICAgICAvKiB0aGUgY2FzdCBtaWdodCB0cnVuY2F0ZSBsZW47IHRoYXQgZG9lc24ndCBjaGFuZ2UgaGFzaCBzdGFiaWxpdHkgKi8KKyAgICAgICAgbXVsdCArPSAobG9uZykoODI1MjBMICsgbGVuICsgbGVuKTsKKyAgICB9CisgICAgeCArPSA5NzUzMUw7CisgICAgaWYgKHggPT0gLTEpCisgICAgICAgIHggPSAtMjsKKyAgICByZXR1cm4geDsKK30KKworc3RhdGljIFB5X3NzaXplX3QKK3R1cGxlbGVuZ3RoKFB5VHVwbGVPYmplY3QgKmEpCit7CisgICAgcmV0dXJuIFB5X1NJWkUoYSk7Cit9CisKK3N0YXRpYyBpbnQKK3R1cGxlY29udGFpbnMoUHlUdXBsZU9iamVjdCAqYSwgUHlPYmplY3QgKmVsKQoreworICAgIFB5X3NzaXplX3QgaTsKKyAgICBpbnQgY21wOworCisgICAgZm9yIChpID0gMCwgY21wID0gMCA7IGNtcCA9PSAwICYmIGkgPCBQeV9TSVpFKGEpOyArK2kpCisgICAgICAgIGNtcCA9IFB5T2JqZWN0X1JpY2hDb21wYXJlQm9vbChlbCwgUHlUdXBsZV9HRVRfSVRFTShhLCBpKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQeV9FUSk7CisgICAgcmV0dXJuIGNtcDsKK30KKworc3RhdGljIFB5T2JqZWN0ICoKK3R1cGxlaXRlbShyZWdpc3RlciBQeVR1cGxlT2JqZWN0ICphLCByZWdpc3RlciBQeV9zc2l6ZV90IGkpCit7CisgICAgaWYgKGkgPCAwIHx8IGkgPj0gUHlfU0laRShhKSkgeworICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfSW5kZXhFcnJvciwgInR1cGxlIGluZGV4IG91dCBvZiByYW5nZSIpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgUHlfSU5DUkVGKGEtPm9iX2l0ZW1baV0pOworICAgIHJldHVybiBhLT5vYl9pdGVtW2ldOworfQorCitzdGF0aWMgUHlPYmplY3QgKgordHVwbGVzbGljZShyZWdpc3RlciBQeVR1cGxlT2JqZWN0ICphLCByZWdpc3RlciBQeV9zc2l6ZV90IGlsb3csCisgICAgICAgICAgIHJlZ2lzdGVyIFB5X3NzaXplX3QgaWhpZ2gpCit7CisgICAgcmVnaXN0ZXIgUHlUdXBsZU9iamVjdCAqbnA7CisgICAgUHlPYmplY3QgKipzcmMsICoqZGVzdDsKKyAgICByZWdpc3RlciBQeV9zc2l6ZV90IGk7CisgICAgUHlfc3NpemVfdCBsZW47CisgICAgaWYgKGlsb3cgPCAwKQorICAgICAgICBpbG93ID0gMDsKKyAgICBpZiAoaWhpZ2ggPiBQeV9TSVpFKGEpKQorICAgICAgICBpaGlnaCA9IFB5X1NJWkUoYSk7CisgICAgaWYgKGloaWdoIDwgaWxvdykKKyAgICAgICAgaWhpZ2ggPSBpbG93OworICAgIGlmIChpbG93ID09IDAgJiYgaWhpZ2ggPT0gUHlfU0laRShhKSAmJiBQeVR1cGxlX0NoZWNrRXhhY3QoYSkpIHsKKyAgICAgICAgUHlfSU5DUkVGKGEpOworICAgICAgICByZXR1cm4gKFB5T2JqZWN0ICopYTsKKyAgICB9CisgICAgbGVuID0gaWhpZ2ggLSBpbG93OworICAgIG5wID0gKFB5VHVwbGVPYmplY3QgKilQeVR1cGxlX05ldyhsZW4pOworICAgIGlmIChucCA9PSBOVUxMKQorICAgICAgICByZXR1cm4gTlVMTDsKKyAgICBzcmMgPSBhLT5vYl9pdGVtICsgaWxvdzsKKyAgICBkZXN0ID0gbnAtPm9iX2l0ZW07CisgICAgZm9yIChpID0gMDsgaSA8IGxlbjsgaSsrKSB7CisgICAgICAgIFB5T2JqZWN0ICp2ID0gc3JjW2ldOworICAgICAgICBQeV9JTkNSRUYodik7CisgICAgICAgIGRlc3RbaV0gPSB2OworICAgIH0KKyAgICByZXR1cm4gKFB5T2JqZWN0ICopbnA7Cit9CisKK1B5T2JqZWN0ICoKK1B5VHVwbGVfR2V0U2xpY2UoUHlPYmplY3QgKm9wLCBQeV9zc2l6ZV90IGksIFB5X3NzaXplX3QgaikKK3sKKyAgICBpZiAob3AgPT0gTlVMTCB8fCAhUHlUdXBsZV9DaGVjayhvcCkpIHsKKyAgICAgICAgUHlFcnJfQmFkSW50ZXJuYWxDYWxsKCk7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICByZXR1cm4gdHVwbGVzbGljZSgoUHlUdXBsZU9iamVjdCAqKW9wLCBpLCBqKTsKK30KKworc3RhdGljIFB5T2JqZWN0ICoKK3R1cGxlY29uY2F0KHJlZ2lzdGVyIFB5VHVwbGVPYmplY3QgKmEsIHJlZ2lzdGVyIFB5T2JqZWN0ICpiYikKK3sKKyAgICByZWdpc3RlciBQeV9zc2l6ZV90IHNpemU7CisgICAgcmVnaXN0ZXIgUHlfc3NpemVfdCBpOworICAgIFB5T2JqZWN0ICoqc3JjLCAqKmRlc3Q7CisgICAgUHlUdXBsZU9iamVjdCAqbnA7CisgICAgaWYgKCFQeVR1cGxlX0NoZWNrKGJiKSkgeworICAgICAgICBQeUVycl9Gb3JtYXQoUHlFeGNfVHlwZUVycm9yLAorICAgICAgICAgICAgICJjYW4gb25seSBjb25jYXRlbmF0ZSB0dXBsZSAobm90IFwiJS4yMDBzXCIpIHRvIHR1cGxlIiwKKyAgICAgICAgICAgICAgICAgUHlfVFlQRShiYiktPnRwX25hbWUpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisjZGVmaW5lIGIgKChQeVR1cGxlT2JqZWN0ICopYmIpCisgICAgc2l6ZSA9IFB5X1NJWkUoYSkgKyBQeV9TSVpFKGIpOworICAgIGlmIChzaXplIDwgMCkKKyAgICAgICAgcmV0dXJuIFB5RXJyX05vTWVtb3J5KCk7CisgICAgbnAgPSAoUHlUdXBsZU9iamVjdCAqKSBQeVR1cGxlX05ldyhzaXplKTsKKyAgICBpZiAobnAgPT0gTlVMTCkgeworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgc3JjID0gYS0+b2JfaXRlbTsKKyAgICBkZXN0ID0gbnAtPm9iX2l0ZW07CisgICAgZm9yIChpID0gMDsgaSA8IFB5X1NJWkUoYSk7IGkrKykgeworICAgICAgICBQeU9iamVjdCAqdiA9IHNyY1tpXTsKKyAgICAgICAgUHlfSU5DUkVGKHYpOworICAgICAgICBkZXN0W2ldID0gdjsKKyAgICB9CisgICAgc3JjID0gYi0+b2JfaXRlbTsKKyAgICBkZXN0ID0gbnAtPm9iX2l0ZW0gKyBQeV9TSVpFKGEpOworICAgIGZvciAoaSA9IDA7IGkgPCBQeV9TSVpFKGIpOyBpKyspIHsKKyAgICAgICAgUHlPYmplY3QgKnYgPSBzcmNbaV07CisgICAgICAgIFB5X0lOQ1JFRih2KTsKKyAgICAgICAgZGVzdFtpXSA9IHY7CisgICAgfQorICAgIHJldHVybiAoUHlPYmplY3QgKilucDsKKyN1bmRlZiBiCit9CisKK3N0YXRpYyBQeU9iamVjdCAqCit0dXBsZXJlcGVhdChQeVR1cGxlT2JqZWN0ICphLCBQeV9zc2l6ZV90IG4pCit7CisgICAgUHlfc3NpemVfdCBpLCBqOworICAgIFB5X3NzaXplX3Qgc2l6ZTsKKyAgICBQeVR1cGxlT2JqZWN0ICpucDsKKyAgICBQeU9iamVjdCAqKnAsICoqaXRlbXM7CisgICAgaWYgKG4gPCAwKQorICAgICAgICBuID0gMDsKKyAgICBpZiAoUHlfU0laRShhKSA9PSAwIHx8IG4gPT0gMSkgeworICAgICAgICBpZiAoUHlUdXBsZV9DaGVja0V4YWN0KGEpKSB7CisgICAgICAgICAgICAvKiBTaW5jZSB0dXBsZXMgYXJlIGltbXV0YWJsZSwgd2UgY2FuIHJldHVybiBhIHNoYXJlZAorICAgICAgICAgICAgICAgY29weSBpbiB0aGlzIGNhc2UgKi8KKyAgICAgICAgICAgIFB5X0lOQ1JFRihhKTsKKyAgICAgICAgICAgIHJldHVybiAoUHlPYmplY3QgKilhOworICAgICAgICB9CisgICAgICAgIGlmIChQeV9TSVpFKGEpID09IDApCisgICAgICAgICAgICByZXR1cm4gUHlUdXBsZV9OZXcoMCk7CisgICAgfQorICAgIHNpemUgPSBQeV9TSVpFKGEpICogbjsKKyAgICBpZiAoc2l6ZS9QeV9TSVpFKGEpICE9IG4pCisgICAgICAgIHJldHVybiBQeUVycl9Ob01lbW9yeSgpOworICAgIG5wID0gKFB5VHVwbGVPYmplY3QgKikgUHlUdXBsZV9OZXcoc2l6ZSk7CisgICAgaWYgKG5wID09IE5VTEwpCisgICAgICAgIHJldHVybiBOVUxMOworICAgIHAgPSBucC0+b2JfaXRlbTsKKyAgICBpdGVtcyA9IGEtPm9iX2l0ZW07CisgICAgZm9yIChpID0gMDsgaSA8IG47IGkrKykgeworICAgICAgICBmb3IgKGogPSAwOyBqIDwgUHlfU0laRShhKTsgaisrKSB7CisgICAgICAgICAgICAqcCA9IGl0ZW1zW2pdOworICAgICAgICAgICAgUHlfSU5DUkVGKCpwKTsKKyAgICAgICAgICAgIHArKzsKKyAgICAgICAgfQorICAgIH0KKyAgICByZXR1cm4gKFB5T2JqZWN0ICopIG5wOworfQorCitzdGF0aWMgUHlPYmplY3QgKgordHVwbGVpbmRleChQeVR1cGxlT2JqZWN0ICpzZWxmLCBQeU9iamVjdCAqYXJncykKK3sKKyAgICBQeV9zc2l6ZV90IGksIHN0YXJ0PTAsIHN0b3A9UHlfU0laRShzZWxmKTsKKyAgICBQeU9iamVjdCAqdjsKKworICAgIGlmICghUHlBcmdfUGFyc2VUdXBsZShhcmdzLCAiT3xPJk8mOmluZGV4IiwgJnYsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF9QeUV2YWxfU2xpY2VJbmRleCwgJnN0YXJ0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfUHlFdmFsX1NsaWNlSW5kZXgsICZzdG9wKSkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgaWYgKHN0YXJ0IDwgMCkgeworICAgICAgICBzdGFydCArPSBQeV9TSVpFKHNlbGYpOworICAgICAgICBpZiAoc3RhcnQgPCAwKQorICAgICAgICAgICAgc3RhcnQgPSAwOworICAgIH0KKyAgICBpZiAoc3RvcCA8IDApIHsKKyAgICAgICAgc3RvcCArPSBQeV9TSVpFKHNlbGYpOworICAgICAgICBpZiAoc3RvcCA8IDApCisgICAgICAgICAgICBzdG9wID0gMDsKKyAgICB9CisgICAgZm9yIChpID0gc3RhcnQ7IGkgPCBzdG9wICYmIGkgPCBQeV9TSVpFKHNlbGYpOyBpKyspIHsKKyAgICAgICAgaW50IGNtcCA9IFB5T2JqZWN0X1JpY2hDb21wYXJlQm9vbChzZWxmLT5vYl9pdGVtW2ldLCB2LCBQeV9FUSk7CisgICAgICAgIGlmIChjbXAgPiAwKQorICAgICAgICAgICAgcmV0dXJuIFB5SW50X0Zyb21Tc2l6ZV90KGkpOworICAgICAgICBlbHNlIGlmIChjbXAgPCAwKQorICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19WYWx1ZUVycm9yLCAidHVwbGUuaW5kZXgoeCk6IHggbm90IGluIHR1cGxlIik7CisgICAgcmV0dXJuIE5VTEw7Cit9CisKK3N0YXRpYyBQeU9iamVjdCAqCit0dXBsZWNvdW50KFB5VHVwbGVPYmplY3QgKnNlbGYsIFB5T2JqZWN0ICp2KQoreworICAgIFB5X3NzaXplX3QgY291bnQgPSAwOworICAgIFB5X3NzaXplX3QgaTsKKworICAgIGZvciAoaSA9IDA7IGkgPCBQeV9TSVpFKHNlbGYpOyBpKyspIHsKKyAgICAgICAgaW50IGNtcCA9IFB5T2JqZWN0X1JpY2hDb21wYXJlQm9vbChzZWxmLT5vYl9pdGVtW2ldLCB2LCBQeV9FUSk7CisgICAgICAgIGlmIChjbXAgPiAwKQorICAgICAgICAgICAgY291bnQrKzsKKyAgICAgICAgZWxzZSBpZiAoY21wIDwgMCkKKyAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICByZXR1cm4gUHlJbnRfRnJvbVNzaXplX3QoY291bnQpOworfQorCitzdGF0aWMgaW50Cit0dXBsZXRyYXZlcnNlKFB5VHVwbGVPYmplY3QgKm8sIHZpc2l0cHJvYyB2aXNpdCwgdm9pZCAqYXJnKQoreworICAgIFB5X3NzaXplX3QgaTsKKworICAgIGZvciAoaSA9IFB5X1NJWkUobyk7IC0taSA+PSAwOyApCisgICAgICAgIFB5X1ZJU0lUKG8tPm9iX2l0ZW1baV0pOworICAgIHJldHVybiAwOworfQorCitzdGF0aWMgUHlPYmplY3QgKgordHVwbGVyaWNoY29tcGFyZShQeU9iamVjdCAqdiwgUHlPYmplY3QgKncsIGludCBvcCkKK3sKKyAgICBQeVR1cGxlT2JqZWN0ICp2dCwgKnd0OworICAgIFB5X3NzaXplX3QgaTsKKyAgICBQeV9zc2l6ZV90IHZsZW4sIHdsZW47CisKKyAgICBpZiAoIVB5VHVwbGVfQ2hlY2sodikgfHwgIVB5VHVwbGVfQ2hlY2sodykpIHsKKyAgICAgICAgUHlfSU5DUkVGKFB5X05vdEltcGxlbWVudGVkKTsKKyAgICAgICAgcmV0dXJuIFB5X05vdEltcGxlbWVudGVkOworICAgIH0KKworICAgIHZ0ID0gKFB5VHVwbGVPYmplY3QgKil2OworICAgIHd0ID0gKFB5VHVwbGVPYmplY3QgKil3OworCisgICAgdmxlbiA9IFB5X1NJWkUodnQpOworICAgIHdsZW4gPSBQeV9TSVpFKHd0KTsKKworICAgIC8qIE5vdGU6ICB0aGUgY29ycmVzcG9uZGluZyBjb2RlIGZvciBsaXN0cyBoYXMgYW4gImVhcmx5IG91dCIgdGVzdAorICAgICAqIGhlcmUgd2hlbiBvcCBpcyBFUSBvciBORSBhbmQgdGhlIGxlbmd0aHMgZGlmZmVyLiAgVGhhdCBwYXlzIHRoZXJlLAorICAgICAqIGJ1dCBUaW0gd2FzIHVuYWJsZSB0byBmaW5kIGFueSByZWFsIGNvZGUgd2hlcmUgRVEvTkUgdHVwbGUKKyAgICAgKiBjb21wYXJlcyBkb24ndCBoYXZlIHRoZSBzYW1lIGxlbmd0aCwgc28gdGVzdGluZyBmb3IgaXQgaGVyZSB3b3VsZAorICAgICAqIGhhdmUgY29zdCB3aXRob3V0IGJlbmVmaXQuCisgICAgICovCisKKyAgICAvKiBTZWFyY2ggZm9yIHRoZSBmaXJzdCBpbmRleCB3aGVyZSBpdGVtcyBhcmUgZGlmZmVyZW50LgorICAgICAqIE5vdGUgdGhhdCBiZWNhdXNlIHR1cGxlcyBhcmUgaW1tdXRhYmxlLCBpdCdzIHNhZmUgdG8gcmV1c2UKKyAgICAgKiB2bGVuIGFuZCB3bGVuIGFjcm9zcyB0aGUgY29tcGFyaXNvbiBjYWxscy4KKyAgICAgKi8KKyAgICBmb3IgKGkgPSAwOyBpIDwgdmxlbiAmJiBpIDwgd2xlbjsgaSsrKSB7CisgICAgICAgIGludCBrID0gUHlPYmplY3RfUmljaENvbXBhcmVCb29sKHZ0LT5vYl9pdGVtW2ldLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3dC0+b2JfaXRlbVtpXSwgUHlfRVEpOworICAgICAgICBpZiAoayA8IDApCisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgaWYgKCFrKQorICAgICAgICAgICAgYnJlYWs7CisgICAgfQorCisgICAgaWYgKGkgPj0gdmxlbiB8fCBpID49IHdsZW4pIHsKKyAgICAgICAgLyogTm8gbW9yZSBpdGVtcyB0byBjb21wYXJlIC0tIGNvbXBhcmUgc2l6ZXMgKi8KKyAgICAgICAgaW50IGNtcDsKKyAgICAgICAgUHlPYmplY3QgKnJlczsKKyAgICAgICAgc3dpdGNoIChvcCkgeworICAgICAgICBjYXNlIFB5X0xUOiBjbXAgPSB2bGVuIDwgIHdsZW47IGJyZWFrOworICAgICAgICBjYXNlIFB5X0xFOiBjbXAgPSB2bGVuIDw9IHdsZW47IGJyZWFrOworICAgICAgICBjYXNlIFB5X0VROiBjbXAgPSB2bGVuID09IHdsZW47IGJyZWFrOworICAgICAgICBjYXNlIFB5X05FOiBjbXAgPSB2bGVuICE9IHdsZW47IGJyZWFrOworICAgICAgICBjYXNlIFB5X0dUOiBjbXAgPSB2bGVuID4gIHdsZW47IGJyZWFrOworICAgICAgICBjYXNlIFB5X0dFOiBjbXAgPSB2bGVuID49IHdsZW47IGJyZWFrOworICAgICAgICBkZWZhdWx0OiByZXR1cm4gTlVMTDsgLyogY2Fubm90IGhhcHBlbiAqLworICAgICAgICB9CisgICAgICAgIGlmIChjbXApCisgICAgICAgICAgICByZXMgPSBQeV9UcnVlOworICAgICAgICBlbHNlCisgICAgICAgICAgICByZXMgPSBQeV9GYWxzZTsKKyAgICAgICAgUHlfSU5DUkVGKHJlcyk7CisgICAgICAgIHJldHVybiByZXM7CisgICAgfQorCisgICAgLyogV2UgaGF2ZSBhbiBpdGVtIHRoYXQgZGlmZmVycyAtLSBzaG9ydGN1dHMgZm9yIEVRL05FICovCisgICAgaWYgKG9wID09IFB5X0VRKSB7CisgICAgICAgIFB5X0lOQ1JFRihQeV9GYWxzZSk7CisgICAgICAgIHJldHVybiBQeV9GYWxzZTsKKyAgICB9CisgICAgaWYgKG9wID09IFB5X05FKSB7CisgICAgICAgIFB5X0lOQ1JFRihQeV9UcnVlKTsKKyAgICAgICAgcmV0dXJuIFB5X1RydWU7CisgICAgfQorCisgICAgLyogQ29tcGFyZSB0aGUgZmluYWwgaXRlbSBhZ2FpbiB1c2luZyB0aGUgcHJvcGVyIG9wZXJhdG9yICovCisgICAgcmV0dXJuIFB5T2JqZWN0X1JpY2hDb21wYXJlKHZ0LT5vYl9pdGVtW2ldLCB3dC0+b2JfaXRlbVtpXSwgb3ApOworfQorCitzdGF0aWMgUHlPYmplY3QgKgordHVwbGVfc3VidHlwZV9uZXcoUHlUeXBlT2JqZWN0ICp0eXBlLCBQeU9iamVjdCAqYXJncywgUHlPYmplY3QgKmt3ZHMpOworCitzdGF0aWMgUHlPYmplY3QgKgordHVwbGVfbmV3KFB5VHlwZU9iamVjdCAqdHlwZSwgUHlPYmplY3QgKmFyZ3MsIFB5T2JqZWN0ICprd2RzKQoreworICAgIFB5T2JqZWN0ICphcmcgPSBOVUxMOworICAgIHN0YXRpYyBjaGFyICprd2xpc3RbXSA9IHsic2VxdWVuY2UiLCAwfTsKKworICAgIGlmICh0eXBlICE9ICZQeVR1cGxlX1R5cGUpCisgICAgICAgIHJldHVybiB0dXBsZV9zdWJ0eXBlX25ldyh0eXBlLCBhcmdzLCBrd2RzKTsKKyAgICBpZiAoIVB5QXJnX1BhcnNlVHVwbGVBbmRLZXl3b3JkcyhhcmdzLCBrd2RzLCAifE86dHVwbGUiLCBrd2xpc3QsICZhcmcpKQorICAgICAgICByZXR1cm4gTlVMTDsKKworICAgIGlmIChhcmcgPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIFB5VHVwbGVfTmV3KDApOworICAgIGVsc2UKKyAgICAgICAgcmV0dXJuIFB5U2VxdWVuY2VfVHVwbGUoYXJnKTsKK30KKworc3RhdGljIFB5T2JqZWN0ICoKK3R1cGxlX3N1YnR5cGVfbmV3KFB5VHlwZU9iamVjdCAqdHlwZSwgUHlPYmplY3QgKmFyZ3MsIFB5T2JqZWN0ICprd2RzKQoreworICAgIFB5T2JqZWN0ICp0bXAsICpuZXdvYmosICppdGVtOworICAgIFB5X3NzaXplX3QgaSwgbjsKKworICAgIGFzc2VydChQeVR5cGVfSXNTdWJ0eXBlKHR5cGUsICZQeVR1cGxlX1R5cGUpKTsKKyAgICB0bXAgPSB0dXBsZV9uZXcoJlB5VHVwbGVfVHlwZSwgYXJncywga3dkcyk7CisgICAgaWYgKHRtcCA9PSBOVUxMKQorICAgICAgICByZXR1cm4gTlVMTDsKKyAgICBhc3NlcnQoUHlUdXBsZV9DaGVjayh0bXApKTsKKyAgICBuZXdvYmogPSB0eXBlLT50cF9hbGxvYyh0eXBlLCBuID0gUHlUdXBsZV9HRVRfU0laRSh0bXApKTsKKyAgICBpZiAobmV3b2JqID09IE5VTEwpCisgICAgICAgIHJldHVybiBOVUxMOworICAgIGZvciAoaSA9IDA7IGkgPCBuOyBpKyspIHsKKyAgICAgICAgaXRlbSA9IFB5VHVwbGVfR0VUX0lURU0odG1wLCBpKTsKKyAgICAgICAgUHlfSU5DUkVGKGl0ZW0pOworICAgICAgICBQeVR1cGxlX1NFVF9JVEVNKG5ld29iaiwgaSwgaXRlbSk7CisgICAgfQorICAgIFB5X0RFQ1JFRih0bXApOworICAgIHJldHVybiBuZXdvYmo7Cit9CisKK1B5RG9jX1NUUlZBUih0dXBsZV9kb2MsCisidHVwbGUoKSAtPiBlbXB0eSB0dXBsZVxuXAordHVwbGUoaXRlcmFibGUpIC0+IHR1cGxlIGluaXRpYWxpemVkIGZyb20gaXRlcmFibGUncyBpdGVtc1xuXAorXG5cCitJZiB0aGUgYXJndW1lbnQgaXMgYSB0dXBsZSwgdGhlIHJldHVybiB2YWx1ZSBpcyB0aGUgc2FtZSBvYmplY3QuIik7CisKK3N0YXRpYyBQeVNlcXVlbmNlTWV0aG9kcyB0dXBsZV9hc19zZXF1ZW5jZSA9IHsKKyAgICAobGVuZnVuYyl0dXBsZWxlbmd0aCwgICAgICAgICAgICAgICAgICAgICAgIC8qIHNxX2xlbmd0aCAqLworICAgIChiaW5hcnlmdW5jKXR1cGxlY29uY2F0LCAgICAgICAgICAgICAgICAgICAgLyogc3FfY29uY2F0ICovCisgICAgKHNzaXplYXJnZnVuYyl0dXBsZXJlcGVhdCwgICAgICAgICAgICAgICAgICAvKiBzcV9yZXBlYXQgKi8KKyAgICAoc3NpemVhcmdmdW5jKXR1cGxlaXRlbSwgICAgICAgICAgICAgICAgICAgIC8qIHNxX2l0ZW0gKi8KKyAgICAoc3NpemVzc2l6ZWFyZ2Z1bmMpdHVwbGVzbGljZSwgICAgICAgICAgICAgIC8qIHNxX3NsaWNlICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBzcV9hc3NfaXRlbSAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogc3FfYXNzX3NsaWNlICovCisgICAgKG9iam9ianByb2MpdHVwbGVjb250YWlucywgICAgICAgICAgICAgICAgICAvKiBzcV9jb250YWlucyAqLworfTsKKworc3RhdGljIFB5T2JqZWN0KgordHVwbGVzdWJzY3JpcHQoUHlUdXBsZU9iamVjdCogc2VsZiwgUHlPYmplY3QqIGl0ZW0pCit7CisgICAgaWYgKFB5SW5kZXhfQ2hlY2soaXRlbSkpIHsKKyAgICAgICAgUHlfc3NpemVfdCBpID0gUHlOdW1iZXJfQXNTc2l6ZV90KGl0ZW0sIFB5RXhjX0luZGV4RXJyb3IpOworICAgICAgICBpZiAoaSA9PSAtMSAmJiBQeUVycl9PY2N1cnJlZCgpKQorICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgICAgIGlmIChpIDwgMCkKKyAgICAgICAgICAgIGkgKz0gUHlUdXBsZV9HRVRfU0laRShzZWxmKTsKKyAgICAgICAgcmV0dXJuIHR1cGxlaXRlbShzZWxmLCBpKTsKKyAgICB9CisgICAgZWxzZSBpZiAoUHlTbGljZV9DaGVjayhpdGVtKSkgeworICAgICAgICBQeV9zc2l6ZV90IHN0YXJ0LCBzdG9wLCBzdGVwLCBzbGljZWxlbmd0aCwgY3VyLCBpOworICAgICAgICBQeU9iamVjdCogcmVzdWx0OworICAgICAgICBQeU9iamVjdCogaXQ7CisgICAgICAgIFB5T2JqZWN0ICoqc3JjLCAqKmRlc3Q7CisKKyAgICAgICAgaWYgKFB5U2xpY2VfR2V0SW5kaWNlc0V4KChQeVNsaWNlT2JqZWN0KilpdGVtLAorICAgICAgICAgICAgICAgICAgICAgICAgIFB5VHVwbGVfR0VUX1NJWkUoc2VsZiksCisgICAgICAgICAgICAgICAgICAgICAgICAgJnN0YXJ0LCAmc3RvcCwgJnN0ZXAsICZzbGljZWxlbmd0aCkgPCAwKSB7CisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChzbGljZWxlbmd0aCA8PSAwKSB7CisgICAgICAgICAgICByZXR1cm4gUHlUdXBsZV9OZXcoMCk7CisgICAgICAgIH0KKyAgICAgICAgZWxzZSBpZiAoc3RhcnQgPT0gMCAmJiBzdGVwID09IDEgJiYKKyAgICAgICAgICAgICAgICAgc2xpY2VsZW5ndGggPT0gUHlUdXBsZV9HRVRfU0laRShzZWxmKSAmJgorICAgICAgICAgICAgICAgICBQeVR1cGxlX0NoZWNrRXhhY3Qoc2VsZikpIHsKKyAgICAgICAgICAgIFB5X0lOQ1JFRihzZWxmKTsKKyAgICAgICAgICAgIHJldHVybiAoUHlPYmplY3QgKilzZWxmOworICAgICAgICB9CisgICAgICAgIGVsc2UgeworICAgICAgICAgICAgcmVzdWx0ID0gUHlUdXBsZV9OZXcoc2xpY2VsZW5ndGgpOworICAgICAgICAgICAgaWYgKCFyZXN1bHQpIHJldHVybiBOVUxMOworCisgICAgICAgICAgICBzcmMgPSBzZWxmLT5vYl9pdGVtOworICAgICAgICAgICAgZGVzdCA9ICgoUHlUdXBsZU9iamVjdCAqKXJlc3VsdCktPm9iX2l0ZW07CisgICAgICAgICAgICBmb3IgKGN1ciA9IHN0YXJ0LCBpID0gMDsgaSA8IHNsaWNlbGVuZ3RoOworICAgICAgICAgICAgICAgICBjdXIgKz0gc3RlcCwgaSsrKSB7CisgICAgICAgICAgICAgICAgaXQgPSBzcmNbY3VyXTsKKyAgICAgICAgICAgICAgICBQeV9JTkNSRUYoaXQpOworICAgICAgICAgICAgICAgIGRlc3RbaV0gPSBpdDsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICAgICAgfQorICAgIH0KKyAgICBlbHNlIHsKKyAgICAgICAgUHlFcnJfRm9ybWF0KFB5RXhjX1R5cGVFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICJ0dXBsZSBpbmRpY2VzIG11c3QgYmUgaW50ZWdlcnMsIG5vdCAlLjIwMHMiLAorICAgICAgICAgICAgICAgICAgICAgUHlfVFlQRShpdGVtKS0+dHBfbmFtZSk7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KK30KKworc3RhdGljIFB5T2JqZWN0ICoKK3R1cGxlX2dldG5ld2FyZ3MoUHlUdXBsZU9iamVjdCAqdikKK3sKKyAgICByZXR1cm4gUHlfQnVpbGRWYWx1ZSgiKE4pIiwgdHVwbGVzbGljZSh2LCAwLCBQeV9TSVpFKHYpKSk7CisKK30KKworc3RhdGljIFB5T2JqZWN0ICoKK3R1cGxlX3NpemVvZihQeVR1cGxlT2JqZWN0ICpzZWxmKQoreworICAgIFB5X3NzaXplX3QgcmVzOworCisgICAgcmVzID0gUHlUdXBsZV9UeXBlLnRwX2Jhc2ljc2l6ZSArIFB5X1NJWkUoc2VsZikgKiBzaXplb2YoUHlPYmplY3QgKik7CisgICAgcmV0dXJuIFB5SW50X0Zyb21Tc2l6ZV90KHJlcyk7Cit9CisKK1B5RG9jX1NUUlZBUihpbmRleF9kb2MsCisiVC5pbmRleCh2YWx1ZSwgW3N0YXJ0LCBbc3RvcF1dKSAtPiBpbnRlZ2VyIC0tIHJldHVybiBmaXJzdCBpbmRleCBvZiB2YWx1ZS5cbiIKKyJSYWlzZXMgVmFsdWVFcnJvciBpZiB0aGUgdmFsdWUgaXMgbm90IHByZXNlbnQuIgorKTsKK1B5RG9jX1NUUlZBUihjb3VudF9kb2MsCisiVC5jb3VudCh2YWx1ZSkgLT4gaW50ZWdlciAtLSByZXR1cm4gbnVtYmVyIG9mIG9jY3VycmVuY2VzIG9mIHZhbHVlIik7CitQeURvY19TVFJWQVIoc2l6ZW9mX2RvYywKKyJULl9fc2l6ZW9mX18oKSAtLSBzaXplIG9mIFQgaW4gbWVtb3J5LCBpbiBieXRlcyIpOworCitzdGF0aWMgUHlNZXRob2REZWYgdHVwbGVfbWV0aG9kc1tdID0geworICAgIHsiX19nZXRuZXdhcmdzX18iLCAgICAgICAgICAoUHlDRnVuY3Rpb24pdHVwbGVfZ2V0bmV3YXJncywgIE1FVEhfTk9BUkdTfSwKKyAgICB7Il9fc2l6ZW9mX18iLCAgICAgIChQeUNGdW5jdGlvbil0dXBsZV9zaXplb2YsIE1FVEhfTk9BUkdTLCBzaXplb2ZfZG9jfSwKKyAgICB7ImluZGV4IiwgICAgICAgICAgIChQeUNGdW5jdGlvbil0dXBsZWluZGV4LCAgTUVUSF9WQVJBUkdTLCBpbmRleF9kb2N9LAorICAgIHsiY291bnQiLCAgICAgICAgICAgKFB5Q0Z1bmN0aW9uKXR1cGxlY291bnQsICBNRVRIX08sIGNvdW50X2RvY30sCisgICAge05VTEwsICAgICAgICAgICAgICBOVUxMfSAgICAgICAgICAgLyogc2VudGluZWwgKi8KK307CisKK3N0YXRpYyBQeU1hcHBpbmdNZXRob2RzIHR1cGxlX2FzX21hcHBpbmcgPSB7CisgICAgKGxlbmZ1bmMpdHVwbGVsZW5ndGgsCisgICAgKGJpbmFyeWZ1bmMpdHVwbGVzdWJzY3JpcHQsCisgICAgMAorfTsKKworc3RhdGljIFB5T2JqZWN0ICp0dXBsZV9pdGVyKFB5T2JqZWN0ICpzZXEpOworCitQeVR5cGVPYmplY3QgUHlUdXBsZV9UeXBlID0geworICAgIFB5VmFyT2JqZWN0X0hFQURfSU5JVCgmUHlUeXBlX1R5cGUsIDApCisgICAgInR1cGxlIiwKKyAgICBzaXplb2YoUHlUdXBsZU9iamVjdCkgLSBzaXplb2YoUHlPYmplY3QgKiksCisgICAgc2l6ZW9mKFB5T2JqZWN0ICopLAorICAgIChkZXN0cnVjdG9yKXR1cGxlZGVhbGxvYywgICAgICAgICAgICAgICAgICAgLyogdHBfZGVhbGxvYyAqLworICAgIChwcmludGZ1bmMpdHVwbGVwcmludCwgICAgICAgICAgICAgICAgICAgICAgLyogdHBfcHJpbnQgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2dldGF0dHIgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3NldGF0dHIgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2NvbXBhcmUgKi8KKyAgICAocmVwcmZ1bmMpdHVwbGVyZXByLCAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3JlcHIgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2FzX251bWJlciAqLworICAgICZ0dXBsZV9hc19zZXF1ZW5jZSwgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfYXNfc2VxdWVuY2UgKi8KKyAgICAmdHVwbGVfYXNfbWFwcGluZywgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2FzX21hcHBpbmcgKi8KKyAgICAoaGFzaGZ1bmMpdHVwbGVoYXNoLCAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2hhc2ggKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2NhbGwgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3N0ciAqLworICAgIFB5T2JqZWN0X0dlbmVyaWNHZXRBdHRyLCAgICAgICAgICAgICAgICAgICAgLyogdHBfZ2V0YXR0cm8gKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3NldGF0dHJvICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9hc19idWZmZXIgKi8KKyAgICBQeV9UUEZMQUdTX0RFRkFVTFQgfCBQeV9UUEZMQUdTX0hBVkVfR0MgfAorICAgICAgICBQeV9UUEZMQUdTX0JBU0VUWVBFIHwgUHlfVFBGTEFHU19UVVBMRV9TVUJDTEFTUywgLyogdHBfZmxhZ3MgKi8KKyAgICB0dXBsZV9kb2MsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2RvYyAqLworICAgICh0cmF2ZXJzZXByb2MpdHVwbGV0cmF2ZXJzZSwgICAgICAgICAgICAgICAgLyogdHBfdHJhdmVyc2UgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2NsZWFyICovCisgICAgdHVwbGVyaWNoY29tcGFyZSwgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9yaWNoY29tcGFyZSAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfd2Vha2xpc3RvZmZzZXQgKi8KKyAgICB0dXBsZV9pdGVyLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2l0ZXIgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2l0ZXJuZXh0ICovCisgICAgdHVwbGVfbWV0aG9kcywgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9tZXRob2RzICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9tZW1iZXJzICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9nZXRzZXQgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2Jhc2UgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2RpY3QgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2Rlc2NyX2dldCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZGVzY3Jfc2V0ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9kaWN0b2Zmc2V0ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9pbml0ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9hbGxvYyAqLworICAgIHR1cGxlX25ldywgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfbmV3ICovCisgICAgUHlPYmplY3RfR0NfRGVsLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9mcmVlICovCit9OworCisvKiBUaGUgZm9sbG93aW5nIGZ1bmN0aW9uIGJyZWFrcyB0aGUgbm90aW9uIHRoYXQgdHVwbGVzIGFyZSBpbW11dGFibGU6CisgICBpdCBjaGFuZ2VzIHRoZSBzaXplIG9mIGEgdHVwbGUuICBXZSBnZXQgYXdheSB3aXRoIHRoaXMgb25seSBpZiB0aGVyZQorICAgaXMgb25seSBvbmUgbW9kdWxlIHJlZmVyZW5jaW5nIHRoZSBvYmplY3QuICBZb3UgY2FuIGFsc28gdGhpbmsgb2YgaXQKKyAgIGFzIGNyZWF0aW5nIGEgbmV3IHR1cGxlIG9iamVjdCBhbmQgZGVzdHJveWluZyB0aGUgb2xkIG9uZSwgb25seSBtb3JlCisgICBlZmZpY2llbnRseS4gIEluIGFueSBjYXNlLCBkb24ndCB1c2UgdGhpcyBpZiB0aGUgdHVwbGUgbWF5IGFscmVhZHkgYmUKKyAgIGtub3duIHRvIHNvbWUgb3RoZXIgcGFydCBvZiB0aGUgY29kZS4gKi8KKworaW50CitfUHlUdXBsZV9SZXNpemUoUHlPYmplY3QgKipwdiwgUHlfc3NpemVfdCBuZXdzaXplKQoreworICAgIHJlZ2lzdGVyIFB5VHVwbGVPYmplY3QgKnY7CisgICAgcmVnaXN0ZXIgUHlUdXBsZU9iamVjdCAqc3Y7CisgICAgUHlfc3NpemVfdCBpOworICAgIFB5X3NzaXplX3Qgb2xkc2l6ZTsKKworICAgIHYgPSAoUHlUdXBsZU9iamVjdCAqKSAqcHY7CisgICAgaWYgKHYgPT0gTlVMTCB8fCBQeV9UWVBFKHYpICE9ICZQeVR1cGxlX1R5cGUgfHwKKyAgICAgICAgKFB5X1NJWkUodikgIT0gMCAmJiBQeV9SRUZDTlQodikgIT0gMSkpIHsKKyAgICAgICAgKnB2ID0gMDsKKyAgICAgICAgUHlfWERFQ1JFRih2KTsKKyAgICAgICAgUHlFcnJfQmFkSW50ZXJuYWxDYWxsKCk7CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisgICAgb2xkc2l6ZSA9IFB5X1NJWkUodik7CisgICAgaWYgKG9sZHNpemUgPT0gbmV3c2l6ZSkKKyAgICAgICAgcmV0dXJuIDA7CisKKyAgICBpZiAob2xkc2l6ZSA9PSAwKSB7CisgICAgICAgIC8qIEVtcHR5IHR1cGxlcyBhcmUgb2Z0ZW4gc2hhcmVkLCBzbyB3ZSBzaG91bGQgbmV2ZXIKKyAgICAgICAgICAgcmVzaXplIHRoZW0gaW4tcGxhY2UgZXZlbiBpZiB3ZSBkbyBvd24gdGhlIG9ubHkKKyAgICAgICAgICAgKGN1cnJlbnQpIHJlZmVyZW5jZSAqLworICAgICAgICBQeV9ERUNSRUYodik7CisgICAgICAgICpwdiA9IFB5VHVwbGVfTmV3KG5ld3NpemUpOworICAgICAgICByZXR1cm4gKnB2ID09IE5VTEwgPyAtMSA6IDA7CisgICAgfQorCisgICAgLyogWFhYIFVOUkVGL05FV1JFRiBpbnRlcmZhY2Ugc2hvdWxkIGJlIG1vcmUgc3ltbWV0cmljYWwgKi8KKyAgICBfUHlfREVDX1JFRlRPVEFMOworICAgIGlmIChfUHlPYmplY3RfR0NfSVNfVFJBQ0tFRCh2KSkKKyAgICAgICAgX1B5T2JqZWN0X0dDX1VOVFJBQ0sodik7CisgICAgX1B5X0ZvcmdldFJlZmVyZW5jZSgoUHlPYmplY3QgKikgdik7CisgICAgLyogREVDUkVGIGl0ZW1zIGRlbGV0ZWQgYnkgc2hyaW5rYWdlICovCisgICAgZm9yIChpID0gbmV3c2l6ZTsgaSA8IG9sZHNpemU7IGkrKykgeworICAgICAgICBQeV9YREVDUkVGKHYtPm9iX2l0ZW1baV0pOworICAgICAgICB2LT5vYl9pdGVtW2ldID0gTlVMTDsKKyAgICB9CisgICAgc3YgPSBQeU9iamVjdF9HQ19SZXNpemUoUHlUdXBsZU9iamVjdCwgdiwgbmV3c2l6ZSk7CisgICAgaWYgKHN2ID09IE5VTEwpIHsKKyAgICAgICAgKnB2ID0gTlVMTDsKKyAgICAgICAgUHlPYmplY3RfR0NfRGVsKHYpOworICAgICAgICByZXR1cm4gLTE7CisgICAgfQorICAgIF9QeV9OZXdSZWZlcmVuY2UoKFB5T2JqZWN0ICopIHN2KTsKKyAgICAvKiBaZXJvIG91dCBpdGVtcyBhZGRlZCBieSBncm93aW5nICovCisgICAgaWYgKG5ld3NpemUgPiBvbGRzaXplKQorICAgICAgICBtZW1zZXQoJnN2LT5vYl9pdGVtW29sZHNpemVdLCAwLAorICAgICAgICAgICAgICAgc2l6ZW9mKCpzdi0+b2JfaXRlbSkgKiAobmV3c2l6ZSAtIG9sZHNpemUpKTsKKyAgICAqcHYgPSAoUHlPYmplY3QgKikgc3Y7CisgICAgX1B5T2JqZWN0X0dDX1RSQUNLKHN2KTsKKyAgICByZXR1cm4gMDsKK30KKworaW50CitQeVR1cGxlX0NsZWFyRnJlZUxpc3Qodm9pZCkKK3sKKyAgICBpbnQgZnJlZWxpc3Rfc2l6ZSA9IDA7CisjaWYgUHlUdXBsZV9NQVhTQVZFU0laRSA+IDAKKyAgICBpbnQgaTsKKyAgICBmb3IgKGkgPSAxOyBpIDwgUHlUdXBsZV9NQVhTQVZFU0laRTsgaSsrKSB7CisgICAgICAgIFB5VHVwbGVPYmplY3QgKnAsICpxOworICAgICAgICBwID0gZnJlZV9saXN0W2ldOworICAgICAgICBmcmVlbGlzdF9zaXplICs9IG51bWZyZWVbaV07CisgICAgICAgIGZyZWVfbGlzdFtpXSA9IE5VTEw7CisgICAgICAgIG51bWZyZWVbaV0gPSAwOworICAgICAgICB3aGlsZSAocCkgeworICAgICAgICAgICAgcSA9IHA7CisgICAgICAgICAgICBwID0gKFB5VHVwbGVPYmplY3QgKikocC0+b2JfaXRlbVswXSk7CisgICAgICAgICAgICBQeU9iamVjdF9HQ19EZWwocSk7CisgICAgICAgIH0KKyAgICB9CisjZW5kaWYKKyAgICByZXR1cm4gZnJlZWxpc3Rfc2l6ZTsKK30KKwordm9pZAorUHlUdXBsZV9GaW5pKHZvaWQpCit7CisjaWYgUHlUdXBsZV9NQVhTQVZFU0laRSA+IDAKKyAgICAvKiBlbXB0eSB0dXBsZXMgYXJlIHVzZWQgYWxsIG92ZXIgdGhlIHBsYWNlIGFuZCBhcHBsaWNhdGlvbnMgbWF5CisgICAgICogcmVseSBvbiB0aGUgZmFjdCB0aGF0IGFuIGVtcHR5IHR1cGxlIGlzIGEgc2luZ2xldG9uLiAqLworICAgIFB5X1hERUNSRUYoZnJlZV9saXN0WzBdKTsKKyAgICBmcmVlX2xpc3RbMF0gPSBOVUxMOworCisgICAgKHZvaWQpUHlUdXBsZV9DbGVhckZyZWVMaXN0KCk7CisjZW5kaWYKKyNpZmRlZiBTSE9XX1RSQUNLX0NPVU5UCisgICAgc2hvd190cmFjaygpOworI2VuZGlmCit9CisKKy8qKioqKioqKioqKioqKioqKioqKioqKiBUdXBsZSBJdGVyYXRvciAqKioqKioqKioqKioqKioqKioqKioqKioqKi8KKwordHlwZWRlZiBzdHJ1Y3QgeworICAgIFB5T2JqZWN0X0hFQUQKKyAgICBsb25nIGl0X2luZGV4OworICAgIFB5VHVwbGVPYmplY3QgKml0X3NlcTsgLyogU2V0IHRvIE5VTEwgd2hlbiBpdGVyYXRvciBpcyBleGhhdXN0ZWQgKi8KK30gdHVwbGVpdGVyb2JqZWN0OworCitzdGF0aWMgdm9pZAordHVwbGVpdGVyX2RlYWxsb2ModHVwbGVpdGVyb2JqZWN0ICppdCkKK3sKKyAgICBfUHlPYmplY3RfR0NfVU5UUkFDSyhpdCk7CisgICAgUHlfWERFQ1JFRihpdC0+aXRfc2VxKTsKKyAgICBQeU9iamVjdF9HQ19EZWwoaXQpOworfQorCitzdGF0aWMgaW50Cit0dXBsZWl0ZXJfdHJhdmVyc2UodHVwbGVpdGVyb2JqZWN0ICppdCwgdmlzaXRwcm9jIHZpc2l0LCB2b2lkICphcmcpCit7CisgICAgUHlfVklTSVQoaXQtPml0X3NlcSk7CisgICAgcmV0dXJuIDA7Cit9CisKK3N0YXRpYyBQeU9iamVjdCAqCit0dXBsZWl0ZXJfbmV4dCh0dXBsZWl0ZXJvYmplY3QgKml0KQoreworICAgIFB5VHVwbGVPYmplY3QgKnNlcTsKKyAgICBQeU9iamVjdCAqaXRlbTsKKworICAgIGFzc2VydChpdCAhPSBOVUxMKTsKKyAgICBzZXEgPSBpdC0+aXRfc2VxOworICAgIGlmIChzZXEgPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgYXNzZXJ0KFB5VHVwbGVfQ2hlY2soc2VxKSk7CisKKyAgICBpZiAoaXQtPml0X2luZGV4IDwgUHlUdXBsZV9HRVRfU0laRShzZXEpKSB7CisgICAgICAgIGl0ZW0gPSBQeVR1cGxlX0dFVF9JVEVNKHNlcSwgaXQtPml0X2luZGV4KTsKKyAgICAgICAgKytpdC0+aXRfaW5kZXg7CisgICAgICAgIFB5X0lOQ1JFRihpdGVtKTsKKyAgICAgICAgcmV0dXJuIGl0ZW07CisgICAgfQorCisgICAgUHlfREVDUkVGKHNlcSk7CisgICAgaXQtPml0X3NlcSA9IE5VTEw7CisgICAgcmV0dXJuIE5VTEw7Cit9CisKK3N0YXRpYyBQeU9iamVjdCAqCit0dXBsZWl0ZXJfbGVuKHR1cGxlaXRlcm9iamVjdCAqaXQpCit7CisgICAgUHlfc3NpemVfdCBsZW4gPSAwOworICAgIGlmIChpdC0+aXRfc2VxKQorICAgICAgICBsZW4gPSBQeVR1cGxlX0dFVF9TSVpFKGl0LT5pdF9zZXEpIC0gaXQtPml0X2luZGV4OworICAgIHJldHVybiBQeUludF9Gcm9tU3NpemVfdChsZW4pOworfQorCitQeURvY19TVFJWQVIobGVuZ3RoX2hpbnRfZG9jLCAiUHJpdmF0ZSBtZXRob2QgcmV0dXJuaW5nIGFuIGVzdGltYXRlIG9mIGxlbihsaXN0KGl0KSkuIik7CisKK3N0YXRpYyBQeU1ldGhvZERlZiB0dXBsZWl0ZXJfbWV0aG9kc1tdID0geworICAgIHsiX19sZW5ndGhfaGludF9fIiwgKFB5Q0Z1bmN0aW9uKXR1cGxlaXRlcl9sZW4sIE1FVEhfTk9BUkdTLCBsZW5ndGhfaGludF9kb2N9LAorICAgIHtOVUxMLCAgICAgICAgICAgICAgTlVMTH0gICAgICAgICAgIC8qIHNlbnRpbmVsICovCit9OworCitQeVR5cGVPYmplY3QgUHlUdXBsZUl0ZXJfVHlwZSA9IHsKKyAgICBQeVZhck9iamVjdF9IRUFEX0lOSVQoJlB5VHlwZV9UeXBlLCAwKQorICAgICJ0dXBsZWl0ZXJhdG9yIiwgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfbmFtZSAqLworICAgIHNpemVvZih0dXBsZWl0ZXJvYmplY3QpLCAgICAgICAgICAgICAgICAgICAgLyogdHBfYmFzaWNzaXplICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9pdGVtc2l6ZSAqLworICAgIC8qIG1ldGhvZHMgKi8KKyAgICAoZGVzdHJ1Y3Rvcil0dXBsZWl0ZXJfZGVhbGxvYywgICAgICAgICAgICAgIC8qIHRwX2RlYWxsb2MgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3ByaW50ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9nZXRhdHRyICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9zZXRhdHRyICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9jb21wYXJlICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9yZXByICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9hc19udW1iZXIgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2FzX3NlcXVlbmNlICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9hc19tYXBwaW5nICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9oYXNoICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9jYWxsICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9zdHIgKi8KKyAgICBQeU9iamVjdF9HZW5lcmljR2V0QXR0ciwgICAgICAgICAgICAgICAgICAgIC8qIHRwX2dldGF0dHJvICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9zZXRhdHRybyAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfYXNfYnVmZmVyICovCisgICAgUHlfVFBGTEFHU19ERUZBVUxUIHwgUHlfVFBGTEFHU19IQVZFX0dDLC8qIHRwX2ZsYWdzICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9kb2MgKi8KKyAgICAodHJhdmVyc2Vwcm9jKXR1cGxlaXRlcl90cmF2ZXJzZSwgICAgICAgICAgIC8qIHRwX3RyYXZlcnNlICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9jbGVhciAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfcmljaGNvbXBhcmUgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3dlYWtsaXN0b2Zmc2V0ICovCisgICAgUHlPYmplY3RfU2VsZkl0ZXIsICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9pdGVyICovCisgICAgKGl0ZXJuZXh0ZnVuYyl0dXBsZWl0ZXJfbmV4dCwgICAgICAgICAgICAgICAvKiB0cF9pdGVybmV4dCAqLworICAgIHR1cGxlaXRlcl9tZXRob2RzLCAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfbWV0aG9kcyAqLworICAgIDAsCit9OworCitzdGF0aWMgUHlPYmplY3QgKgordHVwbGVfaXRlcihQeU9iamVjdCAqc2VxKQoreworICAgIHR1cGxlaXRlcm9iamVjdCAqaXQ7CisKKyAgICBpZiAoIVB5VHVwbGVfQ2hlY2soc2VxKSkgeworICAgICAgICBQeUVycl9CYWRJbnRlcm5hbENhbGwoKTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIGl0ID0gUHlPYmplY3RfR0NfTmV3KHR1cGxlaXRlcm9iamVjdCwgJlB5VHVwbGVJdGVyX1R5cGUpOworICAgIGlmIChpdCA9PSBOVUxMKQorICAgICAgICByZXR1cm4gTlVMTDsKKyAgICBpdC0+aXRfaW5kZXggPSAwOworICAgIFB5X0lOQ1JFRihzZXEpOworICAgIGl0LT5pdF9zZXEgPSAoUHlUdXBsZU9iamVjdCAqKXNlcTsKKyAgICBfUHlPYmplY3RfR0NfVFJBQ0soaXQpOworICAgIHJldHVybiAoUHlPYmplY3QgKilpdDsKK30KZGlmZiAtLWdpdCBhL1B5dGhvbi0yLjcuNS9PYmplY3RzL3R5cGVvYmplY3QuYyBiL1B5dGhvbi0yLjcuNS9PYmplY3RzL3R5cGVvYmplY3QuYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iZTA0YzllCi0tLSAvZGV2L251bGwKKysrIGIvUHl0aG9uLTIuNy41L09iamVjdHMvdHlwZW9iamVjdC5jCkBAIC0wLDAgKzEsNjczMSBAQAorLyogVHlwZSBvYmplY3QgaW1wbGVtZW50YXRpb24gKi8KKworI2luY2x1ZGUgIlB5dGhvbi5oIgorI2luY2x1ZGUgInN0cnVjdG1lbWJlci5oIgorCisjaW5jbHVkZSA8Y3R5cGUuaD4KKworCisvKiBTdXBwb3J0IHR5cGUgYXR0cmlidXRlIGNhY2hlICovCisKKy8qIFRoZSBjYWNoZSBjYW4ga2VlcCByZWZlcmVuY2VzIHRvIHRoZSBuYW1lcyBhbGl2ZSBmb3IgbG9uZ2VyIHRoYW4KKyAgIHRoZXkgbm9ybWFsbHkgd291bGQuICBUaGlzIGlzIHdoeSB0aGUgbWF4aW11bSBzaXplIGlzIGxpbWl0ZWQgdG8KKyAgIE1DQUNIRV9NQVhfQVRUUl9TSVpFLCBzaW5jZSBpdCBtaWdodCBiZSBhIHByb2JsZW0gaWYgdmVyeSBsYXJnZQorICAgc3RyaW5ncyBhcmUgdXNlZCBhcyBhdHRyaWJ1dGUgbmFtZXMuICovCisjZGVmaW5lIE1DQUNIRV9NQVhfQVRUUl9TSVpFICAgIDEwMAorI2RlZmluZSBNQ0FDSEVfU0laRV9FWFAgICAgICAgICAxMAorI2RlZmluZSBNQ0FDSEVfSEFTSCh2ZXJzaW9uLCBuYW1lX2hhc2gpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAoKCh1bnNpZ25lZCBpbnQpKHZlcnNpb24pICogKHVuc2lnbmVkIGludCkobmFtZV9oYXNoKSkgICAgICAgICAgXAorICAgICAgICAgPj4gKDgqc2l6ZW9mKHVuc2lnbmVkIGludCkgLSBNQ0FDSEVfU0laRV9FWFApKQorI2RlZmluZSBNQ0FDSEVfSEFTSF9NRVRIT0QodHlwZSwgbmFtZSkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICBNQ0FDSEVfSEFTSCgodHlwZSktPnRwX3ZlcnNpb25fdGFnLCAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICAgICAgICAgICAgKChQeVN0cmluZ09iamVjdCAqKShuYW1lKSktPm9iX3NoYXNoKQorI2RlZmluZSBNQ0FDSEVfQ0FDSEVBQkxFX05BTUUobmFtZSkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICBQeVN0cmluZ19DaGVja0V4YWN0KG5hbWUpICYmICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgUHlTdHJpbmdfR0VUX1NJWkUobmFtZSkgPD0gTUNBQ0hFX01BWF9BVFRSX1NJWkUKKworc3RydWN0IG1ldGhvZF9jYWNoZV9lbnRyeSB7CisgICAgdW5zaWduZWQgaW50IHZlcnNpb247CisgICAgUHlPYmplY3QgKm5hbWU7ICAgICAgICAgICAgIC8qIHJlZmVyZW5jZSB0byBleGFjdGx5IGEgc3RyIG9yIE5vbmUgKi8KKyAgICBQeU9iamVjdCAqdmFsdWU7ICAgICAgICAgICAgLyogYm9ycm93ZWQgKi8KK307CisKK3N0YXRpYyBzdHJ1Y3QgbWV0aG9kX2NhY2hlX2VudHJ5IG1ldGhvZF9jYWNoZVsxIDw8IE1DQUNIRV9TSVpFX0VYUF07CitzdGF0aWMgdW5zaWduZWQgaW50IG5leHRfdmVyc2lvbl90YWcgPSAwOworCit1bnNpZ25lZCBpbnQKK1B5VHlwZV9DbGVhckNhY2hlKHZvaWQpCit7CisgICAgUHlfc3NpemVfdCBpOworICAgIHVuc2lnbmVkIGludCBjdXJfdmVyc2lvbl90YWcgPSBuZXh0X3ZlcnNpb25fdGFnIC0gMTsKKworICAgIGZvciAoaSA9IDA7IGkgPCAoMSA8PCBNQ0FDSEVfU0laRV9FWFApOyBpKyspIHsKKyAgICAgICAgbWV0aG9kX2NhY2hlW2ldLnZlcnNpb24gPSAwOworICAgICAgICBQeV9DTEVBUihtZXRob2RfY2FjaGVbaV0ubmFtZSk7CisgICAgICAgIG1ldGhvZF9jYWNoZVtpXS52YWx1ZSA9IE5VTEw7CisgICAgfQorICAgIG5leHRfdmVyc2lvbl90YWcgPSAwOworICAgIC8qIG1hcmsgYWxsIHZlcnNpb24gdGFncyBhcyBpbnZhbGlkICovCisgICAgUHlUeXBlX01vZGlmaWVkKCZQeUJhc2VPYmplY3RfVHlwZSk7CisgICAgcmV0dXJuIGN1cl92ZXJzaW9uX3RhZzsKK30KKwordm9pZAorUHlUeXBlX01vZGlmaWVkKFB5VHlwZU9iamVjdCAqdHlwZSkKK3sKKyAgICAvKiBJbnZhbGlkYXRlIGFueSBjYWNoZWQgZGF0YSBmb3IgdGhlIHNwZWNpZmllZCB0eXBlIGFuZCBhbGwKKyAgICAgICBzdWJjbGFzc2VzLiAgVGhpcyBmdW5jdGlvbiBpcyBjYWxsZWQgYWZ0ZXIgdGhlIGJhc2UKKyAgICAgICBjbGFzc2VzLCBtcm8sIG9yIGF0dHJpYnV0ZXMgb2YgdGhlIHR5cGUgYXJlIGFsdGVyZWQuCisKKyAgICAgICBJbnZhcmlhbnRzOgorCisgICAgICAgLSBQeV9UUEZMQUdTX1ZBTElEX1ZFUlNJT05fVEFHIGlzIG5ldmVyIHNldCBpZgorICAgICAgICAgUHlfVFBGTEFHU19IQVZFX1ZFUlNJT05fVEFHIGlzIG5vdCBzZXQgKGUuZy4gb24gdHlwZQorICAgICAgICAgb2JqZWN0cyBjb21pbmcgZnJvbSBub24tcmVjb21waWxlZCBleHRlbnNpb24gbW9kdWxlcykKKworICAgICAgIC0gYmVmb3JlIFB5X1RQRkxBR1NfVkFMSURfVkVSU0lPTl9UQUcgY2FuIGJlIHNldCBvbiBhIHR5cGUsCisgICAgICAgICBpdCBtdXN0IGZpcnN0IGJlIHNldCBvbiBhbGwgc3VwZXIgdHlwZXMuCisKKyAgICAgICBUaGlzIGZ1bmN0aW9uIGNsZWFycyB0aGUgUHlfVFBGTEFHU19WQUxJRF9WRVJTSU9OX1RBRyBvZiBhCisgICAgICAgdHlwZSAoc28gaXQgbXVzdCBmaXJzdCBjbGVhciBpdCBvbiBhbGwgc3ViY2xhc3NlcykuICBUaGUKKyAgICAgICB0cF92ZXJzaW9uX3RhZyB2YWx1ZSBpcyBtZWFuaW5nbGVzcyB1bmxlc3MgdGhpcyBmbGFnIGlzIHNldC4KKyAgICAgICBXZSBkb24ndCBhc3NpZ24gbmV3IHZlcnNpb24gdGFncyBlYWdlcmx5LCBidXQgb25seSBhcworICAgICAgIG5lZWRlZC4KKyAgICAgKi8KKyAgICBQeU9iamVjdCAqcmF3LCAqcmVmOworICAgIFB5X3NzaXplX3QgaSwgbjsKKworICAgIGlmICghUHlUeXBlX0hhc0ZlYXR1cmUodHlwZSwgUHlfVFBGTEFHU19WQUxJRF9WRVJTSU9OX1RBRykpCisgICAgICAgIHJldHVybjsKKworICAgIHJhdyA9IHR5cGUtPnRwX3N1YmNsYXNzZXM7CisgICAgaWYgKHJhdyAhPSBOVUxMKSB7CisgICAgICAgIG4gPSBQeUxpc3RfR0VUX1NJWkUocmF3KTsKKyAgICAgICAgZm9yIChpID0gMDsgaSA8IG47IGkrKykgeworICAgICAgICAgICAgcmVmID0gUHlMaXN0X0dFVF9JVEVNKHJhdywgaSk7CisgICAgICAgICAgICByZWYgPSBQeVdlYWtyZWZfR0VUX09CSkVDVChyZWYpOworICAgICAgICAgICAgaWYgKHJlZiAhPSBQeV9Ob25lKSB7CisgICAgICAgICAgICAgICAgUHlUeXBlX01vZGlmaWVkKChQeVR5cGVPYmplY3QgKilyZWYpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorICAgIHR5cGUtPnRwX2ZsYWdzICY9IH5QeV9UUEZMQUdTX1ZBTElEX1ZFUlNJT05fVEFHOworfQorCitzdGF0aWMgdm9pZAordHlwZV9tcm9fbW9kaWZpZWQoUHlUeXBlT2JqZWN0ICp0eXBlLCBQeU9iamVjdCAqYmFzZXMpIHsKKyAgICAvKgorICAgICAgIENoZWNrIHRoYXQgYWxsIGJhc2UgY2xhc3NlcyBvciBlbGVtZW50cyBvZiB0aGUgbXJvIG9mIHR5cGUgYXJlCisgICAgICAgYWJsZSB0byBiZSBjYWNoZWQuICBUaGlzIGZ1bmN0aW9uIGlzIGNhbGxlZCBhZnRlciB0aGUgYmFzZQorICAgICAgIGNsYXNzZXMgb3IgbXJvIG9mIHRoZSB0eXBlIGFyZSBhbHRlcmVkLgorCisgICAgICAgVW5zZXQgSEFWRV9WRVJTSU9OX1RBRyBhbmQgVkFMSURfVkVSU0lPTl9UQUcgaWYgdGhlIHR5cGUKKyAgICAgICBpbmhlcml0cyBmcm9tIGFuIG9sZC1zdHlsZSBjbGFzcywgZWl0aGVyIGRpcmVjdGx5IG9yIGlmIGl0CisgICAgICAgYXBwZWFycyBpbiB0aGUgTVJPIG9mIGEgbmV3LXN0eWxlIGNsYXNzLiAgTm8gc3VwcG9ydCBlaXRoZXIgZm9yCisgICAgICAgY3VzdG9tIE1ST3MgdGhhdCBpbmNsdWRlIHR5cGVzIHRoYXQgYXJlIG5vdCBvZmZpY2lhbGx5IHN1cGVyCisgICAgICAgdHlwZXMuCisKKyAgICAgICBDYWxsZWQgZnJvbSBtcm9faW50ZXJuYWwsIHdoaWNoIHdpbGwgc3Vic2VxdWVudGx5IGJlIGNhbGxlZCBvbgorICAgICAgIGVhY2ggc3ViY2xhc3Mgd2hlbiB0aGVpciBtcm8gaXMgcmVjdXJzaXZlbHkgdXBkYXRlZC4KKyAgICAgKi8KKyAgICBQeV9zc2l6ZV90IGksIG47CisgICAgaW50IGNsZWFyID0gMDsKKworICAgIGlmICghUHlUeXBlX0hhc0ZlYXR1cmUodHlwZSwgUHlfVFBGTEFHU19IQVZFX1ZFUlNJT05fVEFHKSkKKyAgICAgICAgcmV0dXJuOworCisgICAgbiA9IFB5VHVwbGVfR0VUX1NJWkUoYmFzZXMpOworICAgIGZvciAoaSA9IDA7IGkgPCBuOyBpKyspIHsKKyAgICAgICAgUHlPYmplY3QgKmIgPSBQeVR1cGxlX0dFVF9JVEVNKGJhc2VzLCBpKTsKKyAgICAgICAgUHlUeXBlT2JqZWN0ICpjbHM7CisKKyAgICAgICAgaWYgKCFQeVR5cGVfQ2hlY2soYikgKSB7CisgICAgICAgICAgICBjbGVhciA9IDE7CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgfQorCisgICAgICAgIGNscyA9IChQeVR5cGVPYmplY3QgKiliOworCisgICAgICAgIGlmICghUHlUeXBlX0hhc0ZlYXR1cmUoY2xzLCBQeV9UUEZMQUdTX0hBVkVfVkVSU0lPTl9UQUcpIHx8CisgICAgICAgICAgICAhUHlUeXBlX0lzU3VidHlwZSh0eXBlLCBjbHMpKSB7CisgICAgICAgICAgICBjbGVhciA9IDE7CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgfQorICAgIH0KKworICAgIGlmIChjbGVhcikKKyAgICAgICAgdHlwZS0+dHBfZmxhZ3MgJj0gfihQeV9UUEZMQUdTX0hBVkVfVkVSU0lPTl9UQUd8CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHlfVFBGTEFHU19WQUxJRF9WRVJTSU9OX1RBRyk7Cit9CisKK3N0YXRpYyBpbnQKK2Fzc2lnbl92ZXJzaW9uX3RhZyhQeVR5cGVPYmplY3QgKnR5cGUpCit7CisgICAgLyogRW5zdXJlIHRoYXQgdGhlIHRwX3ZlcnNpb25fdGFnIGlzIHZhbGlkIGFuZCBzZXQKKyAgICAgICBQeV9UUEZMQUdTX1ZBTElEX1ZFUlNJT05fVEFHLiAgVG8gcmVzcGVjdCB0aGUgaW52YXJpYW50LCB0aGlzCisgICAgICAgbXVzdCBmaXJzdCBiZSBkb25lIG9uIGFsbCBzdXBlciBjbGFzc2VzLiAgUmV0dXJuIDAgaWYgdGhpcworICAgICAgIGNhbm5vdCBiZSBkb25lLCAxIGlmIFB5X1RQRkxBR1NfVkFMSURfVkVSU0lPTl9UQUcuCisgICAgKi8KKyAgICBQeV9zc2l6ZV90IGksIG47CisgICAgUHlPYmplY3QgKmJhc2VzOworCisgICAgaWYgKFB5VHlwZV9IYXNGZWF0dXJlKHR5cGUsIFB5X1RQRkxBR1NfVkFMSURfVkVSU0lPTl9UQUcpKQorICAgICAgICByZXR1cm4gMTsKKyAgICBpZiAoIVB5VHlwZV9IYXNGZWF0dXJlKHR5cGUsIFB5X1RQRkxBR1NfSEFWRV9WRVJTSU9OX1RBRykpCisgICAgICAgIHJldHVybiAwOworICAgIGlmICghUHlUeXBlX0hhc0ZlYXR1cmUodHlwZSwgUHlfVFBGTEFHU19SRUFEWSkpCisgICAgICAgIHJldHVybiAwOworCisgICAgdHlwZS0+dHBfdmVyc2lvbl90YWcgPSBuZXh0X3ZlcnNpb25fdGFnKys7CisgICAgLyogZm9yIHN0cmVzcy10ZXN0aW5nOiBuZXh0X3ZlcnNpb25fdGFnICY9IDB4RkY7ICovCisKKyAgICBpZiAodHlwZS0+dHBfdmVyc2lvbl90YWcgPT0gMCkgeworICAgICAgICAvKiB3cmFwLWFyb3VuZCBvciBqdXN0IHN0YXJ0aW5nIFB5dGhvbiAtIGNsZWFyIHRoZSB3aG9sZQorICAgICAgICAgICBjYWNoZSBieSBmaWxsaW5nIG5hbWVzIHdpdGggcmVmZXJlbmNlcyB0byBQeV9Ob25lLgorICAgICAgICAgICBWYWx1ZXMgYXJlIGFsc28gc2V0IHRvIE5VTEwgZm9yIGFkZGVkIHByb3RlY3Rpb24sIGFzIHRoZXkKKyAgICAgICAgICAgYXJlIGJvcnJvd2VkIHJlZmVyZW5jZSAqLworICAgICAgICBmb3IgKGkgPSAwOyBpIDwgKDEgPDwgTUNBQ0hFX1NJWkVfRVhQKTsgaSsrKSB7CisgICAgICAgICAgICBtZXRob2RfY2FjaGVbaV0udmFsdWUgPSBOVUxMOworICAgICAgICAgICAgUHlfWERFQ1JFRihtZXRob2RfY2FjaGVbaV0ubmFtZSk7CisgICAgICAgICAgICBtZXRob2RfY2FjaGVbaV0ubmFtZSA9IFB5X05vbmU7CisgICAgICAgICAgICBQeV9JTkNSRUYoUHlfTm9uZSk7CisgICAgICAgIH0KKyAgICAgICAgLyogbWFyayBhbGwgdmVyc2lvbiB0YWdzIGFzIGludmFsaWQgKi8KKyAgICAgICAgUHlUeXBlX01vZGlmaWVkKCZQeUJhc2VPYmplY3RfVHlwZSk7CisgICAgICAgIHJldHVybiAxOworICAgIH0KKyAgICBiYXNlcyA9IHR5cGUtPnRwX2Jhc2VzOworICAgIG4gPSBQeVR1cGxlX0dFVF9TSVpFKGJhc2VzKTsKKyAgICBmb3IgKGkgPSAwOyBpIDwgbjsgaSsrKSB7CisgICAgICAgIFB5T2JqZWN0ICpiID0gUHlUdXBsZV9HRVRfSVRFTShiYXNlcywgaSk7CisgICAgICAgIGFzc2VydChQeVR5cGVfQ2hlY2soYikpOworICAgICAgICBpZiAoIWFzc2lnbl92ZXJzaW9uX3RhZygoUHlUeXBlT2JqZWN0ICopYikpCisgICAgICAgICAgICByZXR1cm4gMDsKKyAgICB9CisgICAgdHlwZS0+dHBfZmxhZ3MgfD0gUHlfVFBGTEFHU19WQUxJRF9WRVJTSU9OX1RBRzsKKyAgICByZXR1cm4gMTsKK30KKworCitzdGF0aWMgUHlNZW1iZXJEZWYgdHlwZV9tZW1iZXJzW10gPSB7CisgICAgeyJfX2Jhc2ljc2l6ZV9fIiwgVF9QWVNTSVpFVCwgb2Zmc2V0b2YoUHlUeXBlT2JqZWN0LHRwX2Jhc2ljc2l6ZSksUkVBRE9OTFl9LAorICAgIHsiX19pdGVtc2l6ZV9fIiwgVF9QWVNTSVpFVCwgb2Zmc2V0b2YoUHlUeXBlT2JqZWN0LCB0cF9pdGVtc2l6ZSksIFJFQURPTkxZfSwKKyAgICB7Il9fZmxhZ3NfXyIsIFRfTE9ORywgb2Zmc2V0b2YoUHlUeXBlT2JqZWN0LCB0cF9mbGFncyksIFJFQURPTkxZfSwKKyAgICB7Il9fd2Vha3JlZm9mZnNldF9fIiwgVF9MT05HLAorICAgICBvZmZzZXRvZihQeVR5cGVPYmplY3QsIHRwX3dlYWtsaXN0b2Zmc2V0KSwgUkVBRE9OTFl9LAorICAgIHsiX19iYXNlX18iLCBUX09CSkVDVCwgb2Zmc2V0b2YoUHlUeXBlT2JqZWN0LCB0cF9iYXNlKSwgUkVBRE9OTFl9LAorICAgIHsiX19kaWN0b2Zmc2V0X18iLCBUX0xPTkcsCisgICAgIG9mZnNldG9mKFB5VHlwZU9iamVjdCwgdHBfZGljdG9mZnNldCksIFJFQURPTkxZfSwKKyAgICB7Il9fbXJvX18iLCBUX09CSkVDVCwgb2Zmc2V0b2YoUHlUeXBlT2JqZWN0LCB0cF9tcm8pLCBSRUFET05MWX0sCisgICAgezB9Cit9OworCitzdGF0aWMgUHlPYmplY3QgKgordHlwZV9uYW1lKFB5VHlwZU9iamVjdCAqdHlwZSwgdm9pZCAqY29udGV4dCkKK3sKKyAgICBjb25zdCBjaGFyICpzOworCisgICAgaWYgKHR5cGUtPnRwX2ZsYWdzICYgUHlfVFBGTEFHU19IRUFQVFlQRSkgeworICAgICAgICBQeUhlYXBUeXBlT2JqZWN0KiBldCA9IChQeUhlYXBUeXBlT2JqZWN0Kil0eXBlOworCisgICAgICAgIFB5X0lOQ1JFRihldC0+aHRfbmFtZSk7CisgICAgICAgIHJldHVybiBldC0+aHRfbmFtZTsKKyAgICB9CisgICAgZWxzZSB7CisgICAgICAgIHMgPSBzdHJyY2hyKHR5cGUtPnRwX25hbWUsICcuJyk7CisgICAgICAgIGlmIChzID09IE5VTEwpCisgICAgICAgICAgICBzID0gdHlwZS0+dHBfbmFtZTsKKyAgICAgICAgZWxzZQorICAgICAgICAgICAgcysrOworICAgICAgICByZXR1cm4gUHlTdHJpbmdfRnJvbVN0cmluZyhzKTsKKyAgICB9Cit9CisKK3N0YXRpYyBpbnQKK3R5cGVfc2V0X25hbWUoUHlUeXBlT2JqZWN0ICp0eXBlLCBQeU9iamVjdCAqdmFsdWUsIHZvaWQgKmNvbnRleHQpCit7CisgICAgUHlIZWFwVHlwZU9iamVjdCogZXQ7CisgICAgUHlPYmplY3QgKnRtcDsKKworICAgIGlmICghKHR5cGUtPnRwX2ZsYWdzICYgUHlfVFBGTEFHU19IRUFQVFlQRSkpIHsKKyAgICAgICAgUHlFcnJfRm9ybWF0KFB5RXhjX1R5cGVFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICJjYW4ndCBzZXQgJXMuX19uYW1lX18iLCB0eXBlLT50cF9uYW1lKTsKKyAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKyAgICBpZiAoIXZhbHVlKSB7CisgICAgICAgIFB5RXJyX0Zvcm1hdChQeUV4Y19UeXBlRXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAiY2FuJ3QgZGVsZXRlICVzLl9fbmFtZV9fIiwgdHlwZS0+dHBfbmFtZSk7CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisgICAgaWYgKCFQeVN0cmluZ19DaGVjayh2YWx1ZSkpIHsKKyAgICAgICAgUHlFcnJfRm9ybWF0KFB5RXhjX1R5cGVFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICJjYW4gb25seSBhc3NpZ24gc3RyaW5nIHRvICVzLl9fbmFtZV9fLCBub3QgJyVzJyIsCisgICAgICAgICAgICAgICAgICAgICB0eXBlLT50cF9uYW1lLCBQeV9UWVBFKHZhbHVlKS0+dHBfbmFtZSk7CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisgICAgaWYgKHN0cmxlbihQeVN0cmluZ19BU19TVFJJTkcodmFsdWUpKQorICAgICAgICAhPSAoc2l6ZV90KVB5U3RyaW5nX0dFVF9TSVpFKHZhbHVlKSkgeworICAgICAgICBQeUVycl9Gb3JtYXQoUHlFeGNfVmFsdWVFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICJfX25hbWVfXyBtdXN0IG5vdCBjb250YWluIG51bGwgYnl0ZXMiKTsKKyAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKworICAgIGV0ID0gKFB5SGVhcFR5cGVPYmplY3QqKXR5cGU7CisKKyAgICBQeV9JTkNSRUYodmFsdWUpOworCisgICAgLyogV2FpdCB1bnRpbCBldCBpcyBhIHNhbmUgc3RhdGUgYmVmb3JlIFB5X0RFQ1JFRidpbmcgdGhlIG9sZCBldC0+aHRfbmFtZQorICAgICAgIHZhbHVlLiAgKEJ1ZyAjMTY0NDcuKSAgKi8KKyAgICB0bXAgPSBldC0+aHRfbmFtZTsKKyAgICBldC0+aHRfbmFtZSA9IHZhbHVlOworCisgICAgdHlwZS0+dHBfbmFtZSA9IFB5U3RyaW5nX0FTX1NUUklORyh2YWx1ZSk7CisgICAgUHlfREVDUkVGKHRtcCk7CisKKyAgICByZXR1cm4gMDsKK30KKworc3RhdGljIFB5T2JqZWN0ICoKK3R5cGVfbW9kdWxlKFB5VHlwZU9iamVjdCAqdHlwZSwgdm9pZCAqY29udGV4dCkKK3sKKyAgICBQeU9iamVjdCAqbW9kOworICAgIGNoYXIgKnM7CisKKyAgICBpZiAodHlwZS0+dHBfZmxhZ3MgJiBQeV9UUEZMQUdTX0hFQVBUWVBFKSB7CisgICAgICAgIG1vZCA9IFB5RGljdF9HZXRJdGVtU3RyaW5nKHR5cGUtPnRwX2RpY3QsICJfX21vZHVsZV9fIik7CisgICAgICAgIGlmICghbW9kKSB7CisgICAgICAgICAgICBQeUVycl9Gb3JtYXQoUHlFeGNfQXR0cmlidXRlRXJyb3IsICJfX21vZHVsZV9fIik7CisgICAgICAgICAgICByZXR1cm4gMDsKKyAgICAgICAgfQorICAgICAgICBQeV9YSU5DUkVGKG1vZCk7CisgICAgICAgIHJldHVybiBtb2Q7CisgICAgfQorICAgIGVsc2UgeworICAgICAgICBzID0gc3RycmNocih0eXBlLT50cF9uYW1lLCAnLicpOworICAgICAgICBpZiAocyAhPSBOVUxMKQorICAgICAgICAgICAgcmV0dXJuIFB5U3RyaW5nX0Zyb21TdHJpbmdBbmRTaXplKAorICAgICAgICAgICAgICAgIHR5cGUtPnRwX25hbWUsIChQeV9zc2l6ZV90KShzIC0gdHlwZS0+dHBfbmFtZSkpOworICAgICAgICByZXR1cm4gUHlTdHJpbmdfRnJvbVN0cmluZygiX19idWlsdGluX18iKTsKKyAgICB9Cit9CisKK3N0YXRpYyBpbnQKK3R5cGVfc2V0X21vZHVsZShQeVR5cGVPYmplY3QgKnR5cGUsIFB5T2JqZWN0ICp2YWx1ZSwgdm9pZCAqY29udGV4dCkKK3sKKyAgICBpZiAoISh0eXBlLT50cF9mbGFncyAmIFB5X1RQRkxBR1NfSEVBUFRZUEUpKSB7CisgICAgICAgIFB5RXJyX0Zvcm1hdChQeUV4Y19UeXBlRXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAiY2FuJ3Qgc2V0ICVzLl9fbW9kdWxlX18iLCB0eXBlLT50cF9uYW1lKTsKKyAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKyAgICBpZiAoIXZhbHVlKSB7CisgICAgICAgIFB5RXJyX0Zvcm1hdChQeUV4Y19UeXBlRXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAiY2FuJ3QgZGVsZXRlICVzLl9fbW9kdWxlX18iLCB0eXBlLT50cF9uYW1lKTsKKyAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKworICAgIFB5VHlwZV9Nb2RpZmllZCh0eXBlKTsKKworICAgIHJldHVybiBQeURpY3RfU2V0SXRlbVN0cmluZyh0eXBlLT50cF9kaWN0LCAiX19tb2R1bGVfXyIsIHZhbHVlKTsKK30KKworc3RhdGljIFB5T2JqZWN0ICoKK3R5cGVfYWJzdHJhY3RtZXRob2RzKFB5VHlwZU9iamVjdCAqdHlwZSwgdm9pZCAqY29udGV4dCkKK3sKKyAgICBQeU9iamVjdCAqbW9kID0gTlVMTDsKKyAgICAvKiB0eXBlIGl0c2VsZiBoYXMgYW4gX19hYnN0cmFjdG1ldGhvZHNfXyBkZXNjcmlwdG9yICh0aGlzKS4gRG9uJ3QgcmV0dXJuCisgICAgICAgdGhhdC4gKi8KKyAgICBpZiAodHlwZSAhPSAmUHlUeXBlX1R5cGUpCisgICAgICAgIG1vZCA9IFB5RGljdF9HZXRJdGVtU3RyaW5nKHR5cGUtPnRwX2RpY3QsICJfX2Fic3RyYWN0bWV0aG9kc19fIik7CisgICAgaWYgKCFtb2QpIHsKKyAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX0F0dHJpYnV0ZUVycm9yLCAiX19hYnN0cmFjdG1ldGhvZHNfXyIpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgUHlfWElOQ1JFRihtb2QpOworICAgIHJldHVybiBtb2Q7Cit9CisKK3N0YXRpYyBpbnQKK3R5cGVfc2V0X2Fic3RyYWN0bWV0aG9kcyhQeVR5cGVPYmplY3QgKnR5cGUsIFB5T2JqZWN0ICp2YWx1ZSwgdm9pZCAqY29udGV4dCkKK3sKKyAgICAvKiBfX2Fic3RyYWN0bWV0aG9kc19fIHNob3VsZCBvbmx5IGJlIHNldCBvbmNlIG9uIGEgdHlwZSwgaW4KKyAgICAgICBhYmMuQUJDTWV0YS5fX25ld19fLCBzbyB0aGlzIGZ1bmN0aW9uIGRvZXNuJ3QgZG8gYW55dGhpbmcKKyAgICAgICBzcGVjaWFsIHRvIHVwZGF0ZSBzdWJjbGFzc2VzLgorICAgICovCisgICAgaW50IGFic3RyYWN0LCByZXM7CisgICAgaWYgKHZhbHVlICE9IE5VTEwpIHsKKyAgICAgICAgYWJzdHJhY3QgPSBQeU9iamVjdF9Jc1RydWUodmFsdWUpOworICAgICAgICBpZiAoYWJzdHJhY3QgPCAwKQorICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICByZXMgPSBQeURpY3RfU2V0SXRlbVN0cmluZyh0eXBlLT50cF9kaWN0LCAiX19hYnN0cmFjdG1ldGhvZHNfXyIsIHZhbHVlKTsKKyAgICB9CisgICAgZWxzZSB7CisgICAgICAgIGFic3RyYWN0ID0gMDsKKyAgICAgICAgcmVzID0gUHlEaWN0X0RlbEl0ZW1TdHJpbmcodHlwZS0+dHBfZGljdCwgIl9fYWJzdHJhY3RtZXRob2RzX18iKTsKKyAgICAgICAgaWYgKHJlcyAmJiBQeUVycl9FeGNlcHRpb25NYXRjaGVzKFB5RXhjX0tleUVycm9yKSkgeworICAgICAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX0F0dHJpYnV0ZUVycm9yLCAiX19hYnN0cmFjdG1ldGhvZHNfXyIpOworICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICB9CisgICAgfQorICAgIGlmIChyZXMgPT0gMCkgeworICAgICAgICBQeVR5cGVfTW9kaWZpZWQodHlwZSk7CisgICAgICAgIGlmIChhYnN0cmFjdCkKKyAgICAgICAgICAgIHR5cGUtPnRwX2ZsYWdzIHw9IFB5X1RQRkxBR1NfSVNfQUJTVFJBQ1Q7CisgICAgICAgIGVsc2UKKyAgICAgICAgICAgIHR5cGUtPnRwX2ZsYWdzICY9IH5QeV9UUEZMQUdTX0lTX0FCU1RSQUNUOworICAgIH0KKyAgICByZXR1cm4gcmVzOworfQorCitzdGF0aWMgUHlPYmplY3QgKgordHlwZV9nZXRfYmFzZXMoUHlUeXBlT2JqZWN0ICp0eXBlLCB2b2lkICpjb250ZXh0KQoreworICAgIFB5X0lOQ1JFRih0eXBlLT50cF9iYXNlcyk7CisgICAgcmV0dXJuIHR5cGUtPnRwX2Jhc2VzOworfQorCitzdGF0aWMgUHlUeXBlT2JqZWN0ICpiZXN0X2Jhc2UoUHlPYmplY3QgKik7CitzdGF0aWMgaW50IG1yb19pbnRlcm5hbChQeVR5cGVPYmplY3QgKik7CitzdGF0aWMgaW50IGNvbXBhdGlibGVfZm9yX2Fzc2lnbm1lbnQoUHlUeXBlT2JqZWN0ICosIFB5VHlwZU9iamVjdCAqLCBjaGFyICopOworc3RhdGljIGludCBhZGRfc3ViY2xhc3MoUHlUeXBlT2JqZWN0KiwgUHlUeXBlT2JqZWN0Kik7CitzdGF0aWMgdm9pZCByZW1vdmVfc3ViY2xhc3MoUHlUeXBlT2JqZWN0ICosIFB5VHlwZU9iamVjdCAqKTsKK3N0YXRpYyB2b2lkIHVwZGF0ZV9hbGxfc2xvdHMoUHlUeXBlT2JqZWN0ICopOworCit0eXBlZGVmIGludCAoKnVwZGF0ZV9jYWxsYmFjaykoUHlUeXBlT2JqZWN0ICosIHZvaWQgKik7CitzdGF0aWMgaW50IHVwZGF0ZV9zdWJjbGFzc2VzKFB5VHlwZU9iamVjdCAqdHlwZSwgUHlPYmplY3QgKm5hbWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVwZGF0ZV9jYWxsYmFjayBjYWxsYmFjaywgdm9pZCAqZGF0YSk7CitzdGF0aWMgaW50IHJlY3Vyc2VfZG93bl9zdWJjbGFzc2VzKFB5VHlwZU9iamVjdCAqdHlwZSwgUHlPYmplY3QgKm5hbWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVwZGF0ZV9jYWxsYmFjayBjYWxsYmFjaywgdm9pZCAqZGF0YSk7CisKK3N0YXRpYyBpbnQKK21yb19zdWJjbGFzc2VzKFB5VHlwZU9iamVjdCAqdHlwZSwgUHlPYmplY3QqIHRlbXApCit7CisgICAgUHlUeXBlT2JqZWN0ICpzdWJjbGFzczsKKyAgICBQeU9iamVjdCAqcmVmLCAqc3ViY2xhc3NlcywgKm9sZF9tcm87CisgICAgUHlfc3NpemVfdCBpLCBuOworCisgICAgc3ViY2xhc3NlcyA9IHR5cGUtPnRwX3N1YmNsYXNzZXM7CisgICAgaWYgKHN1YmNsYXNzZXMgPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIDA7CisgICAgYXNzZXJ0KFB5TGlzdF9DaGVjayhzdWJjbGFzc2VzKSk7CisgICAgbiA9IFB5TGlzdF9HRVRfU0laRShzdWJjbGFzc2VzKTsKKyAgICBmb3IgKGkgPSAwOyBpIDwgbjsgaSsrKSB7CisgICAgICAgIHJlZiA9IFB5TGlzdF9HRVRfSVRFTShzdWJjbGFzc2VzLCBpKTsKKyAgICAgICAgYXNzZXJ0KFB5V2Vha3JlZl9DaGVja1JlZihyZWYpKTsKKyAgICAgICAgc3ViY2xhc3MgPSAoUHlUeXBlT2JqZWN0ICopUHlXZWFrcmVmX0dFVF9PQkpFQ1QocmVmKTsKKyAgICAgICAgYXNzZXJ0KHN1YmNsYXNzICE9IE5VTEwpOworICAgICAgICBpZiAoKFB5T2JqZWN0ICopc3ViY2xhc3MgPT0gUHlfTm9uZSkKKyAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICBhc3NlcnQoUHlUeXBlX0NoZWNrKHN1YmNsYXNzKSk7CisgICAgICAgIG9sZF9tcm8gPSBzdWJjbGFzcy0+dHBfbXJvOworICAgICAgICBpZiAobXJvX2ludGVybmFsKHN1YmNsYXNzKSA8IDApIHsKKyAgICAgICAgICAgIHN1YmNsYXNzLT50cF9tcm8gPSBvbGRfbXJvOworICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICB9CisgICAgICAgIGVsc2UgeworICAgICAgICAgICAgUHlPYmplY3QqIHR1cGxlOworICAgICAgICAgICAgdHVwbGUgPSBQeVR1cGxlX1BhY2soMiwgc3ViY2xhc3MsIG9sZF9tcm8pOworICAgICAgICAgICAgUHlfREVDUkVGKG9sZF9tcm8pOworICAgICAgICAgICAgaWYgKCF0dXBsZSkKKyAgICAgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgICAgICBpZiAoUHlMaXN0X0FwcGVuZCh0ZW1wLCB0dXBsZSkgPCAwKQorICAgICAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgICAgIFB5X0RFQ1JFRih0dXBsZSk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKG1yb19zdWJjbGFzc2VzKHN1YmNsYXNzLCB0ZW1wKSA8IDApCisgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgfQorICAgIHJldHVybiAwOworfQorCitzdGF0aWMgaW50Cit0eXBlX3NldF9iYXNlcyhQeVR5cGVPYmplY3QgKnR5cGUsIFB5T2JqZWN0ICp2YWx1ZSwgdm9pZCAqY29udGV4dCkKK3sKKyAgICBQeV9zc2l6ZV90IGk7CisgICAgaW50IHIgPSAwOworICAgIFB5T2JqZWN0ICpvYiwgKnRlbXA7CisgICAgUHlUeXBlT2JqZWN0ICpuZXdfYmFzZSwgKm9sZF9iYXNlOworICAgIFB5T2JqZWN0ICpvbGRfYmFzZXMsICpvbGRfbXJvOworCisgICAgaWYgKCEodHlwZS0+dHBfZmxhZ3MgJiBQeV9UUEZMQUdTX0hFQVBUWVBFKSkgeworICAgICAgICBQeUVycl9Gb3JtYXQoUHlFeGNfVHlwZUVycm9yLAorICAgICAgICAgICAgICAgICAgICAgImNhbid0IHNldCAlcy5fX2Jhc2VzX18iLCB0eXBlLT50cF9uYW1lKTsKKyAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKyAgICBpZiAoIXZhbHVlKSB7CisgICAgICAgIFB5RXJyX0Zvcm1hdChQeUV4Y19UeXBlRXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAiY2FuJ3QgZGVsZXRlICVzLl9fYmFzZXNfXyIsIHR5cGUtPnRwX25hbWUpOworICAgICAgICByZXR1cm4gLTE7CisgICAgfQorICAgIGlmICghUHlUdXBsZV9DaGVjayh2YWx1ZSkpIHsKKyAgICAgICAgUHlFcnJfRm9ybWF0KFB5RXhjX1R5cGVFcnJvciwKKyAgICAgICAgICAgICAiY2FuIG9ubHkgYXNzaWduIHR1cGxlIHRvICVzLl9fYmFzZXNfXywgbm90ICVzIiwKKyAgICAgICAgICAgICAgICAgdHlwZS0+dHBfbmFtZSwgUHlfVFlQRSh2YWx1ZSktPnRwX25hbWUpOworICAgICAgICByZXR1cm4gLTE7CisgICAgfQorICAgIGlmIChQeVR1cGxlX0dFVF9TSVpFKHZhbHVlKSA9PSAwKSB7CisgICAgICAgIFB5RXJyX0Zvcm1hdChQeUV4Y19UeXBlRXJyb3IsCisgICAgICAgICAgICAgImNhbiBvbmx5IGFzc2lnbiBub24tZW1wdHkgdHVwbGUgdG8gJXMuX19iYXNlc19fLCBub3QgKCkiLAorICAgICAgICAgICAgICAgICB0eXBlLT50cF9uYW1lKTsKKyAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKyAgICBmb3IgKGkgPSAwOyBpIDwgUHlUdXBsZV9HRVRfU0laRSh2YWx1ZSk7IGkrKykgeworICAgICAgICBvYiA9IFB5VHVwbGVfR0VUX0lURU0odmFsdWUsIGkpOworICAgICAgICBpZiAoIVB5Q2xhc3NfQ2hlY2sob2IpICYmICFQeVR5cGVfQ2hlY2sob2IpKSB7CisgICAgICAgICAgICBQeUVycl9Gb3JtYXQoCisgICAgICAgICAgICAgICAgUHlFeGNfVHlwZUVycm9yLAorICAgICIlcy5fX2Jhc2VzX18gbXVzdCBiZSB0dXBsZSBvZiBvbGQtIG9yIG5ldy1zdHlsZSBjbGFzc2VzLCBub3QgJyVzJyIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHlwZS0+dHBfbmFtZSwgUHlfVFlQRShvYiktPnRwX25hbWUpOworICAgICAgICAgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgIH0KKyAgICAgICAgaWYgKFB5VHlwZV9DaGVjayhvYikpIHsKKyAgICAgICAgICAgIGlmIChQeVR5cGVfSXNTdWJ0eXBlKChQeVR5cGVPYmplY3QqKW9iLCB0eXBlKSkgeworICAgICAgICAgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19UeXBlRXJyb3IsCisgICAgICAgICAgICAiYSBfX2Jhc2VzX18gaXRlbSBjYXVzZXMgYW4gaW5oZXJpdGFuY2UgY3ljbGUiKTsKKyAgICAgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisKKyAgICBuZXdfYmFzZSA9IGJlc3RfYmFzZSh2YWx1ZSk7CisKKyAgICBpZiAoIW5ld19iYXNlKSB7CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisKKyAgICBpZiAoIWNvbXBhdGlibGVfZm9yX2Fzc2lnbm1lbnQodHlwZS0+dHBfYmFzZSwgbmV3X2Jhc2UsICJfX2Jhc2VzX18iKSkKKyAgICAgICAgcmV0dXJuIC0xOworCisgICAgUHlfSU5DUkVGKG5ld19iYXNlKTsKKyAgICBQeV9JTkNSRUYodmFsdWUpOworCisgICAgb2xkX2Jhc2VzID0gdHlwZS0+dHBfYmFzZXM7CisgICAgb2xkX2Jhc2UgPSB0eXBlLT50cF9iYXNlOworICAgIG9sZF9tcm8gPSB0eXBlLT50cF9tcm87CisKKyAgICB0eXBlLT50cF9iYXNlcyA9IHZhbHVlOworICAgIHR5cGUtPnRwX2Jhc2UgPSBuZXdfYmFzZTsKKworICAgIGlmIChtcm9faW50ZXJuYWwodHlwZSkgPCAwKSB7CisgICAgICAgIGdvdG8gYmFpbDsKKyAgICB9CisKKyAgICB0ZW1wID0gUHlMaXN0X05ldygwKTsKKyAgICBpZiAoIXRlbXApCisgICAgICAgIGdvdG8gYmFpbDsKKworICAgIHIgPSBtcm9fc3ViY2xhc3Nlcyh0eXBlLCB0ZW1wKTsKKworICAgIGlmIChyIDwgMCkgeworICAgICAgICBmb3IgKGkgPSAwOyBpIDwgUHlMaXN0X1NpemUodGVtcCk7IGkrKykgeworICAgICAgICAgICAgUHlUeXBlT2JqZWN0KiBjbHM7CisgICAgICAgICAgICBQeU9iamVjdCogbXJvOworICAgICAgICAgICAgUHlBcmdfVW5wYWNrVHVwbGUoUHlMaXN0X0dFVF9JVEVNKHRlbXAsIGkpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiIiwgMiwgMiwgJmNscywgJm1ybyk7CisgICAgICAgICAgICBQeV9JTkNSRUYobXJvKTsKKyAgICAgICAgICAgIG9iID0gY2xzLT50cF9tcm87CisgICAgICAgICAgICBjbHMtPnRwX21ybyA9IG1ybzsKKyAgICAgICAgICAgIFB5X0RFQ1JFRihvYik7CisgICAgICAgIH0KKyAgICAgICAgUHlfREVDUkVGKHRlbXApOworICAgICAgICBnb3RvIGJhaWw7CisgICAgfQorCisgICAgUHlfREVDUkVGKHRlbXApOworCisgICAgLyogYW55IGJhc2UgdGhhdCB3YXMgaW4gX19iYXNlc19fIGJ1dCBub3cgaXNuJ3QsIHdlCisgICAgICAgbmVlZCB0byByZW1vdmUgfHR5cGV8IGZyb20gaXRzIHRwX3N1YmNsYXNzZXMuCisgICAgICAgY29udmVyc2VseSwgYW55IGNsYXNzIG5vdyBpbiBfX2Jhc2VzX18gdGhhdCB3YXNuJ3QKKyAgICAgICBuZWVkcyB0byBoYXZlIHx0eXBlfCBhZGRlZCB0byBpdHMgc3ViY2xhc3Nlcy4gKi8KKworICAgIC8qIGZvciBub3csIHNvZCB0aGF0OiBqdXN0IHJlbW92ZSBmcm9tIGFsbCBvbGRfYmFzZXMsCisgICAgICAgYWRkIHRvIGFsbCBuZXdfYmFzZXMgKi8KKworICAgIGZvciAoaSA9IFB5VHVwbGVfR0VUX1NJWkUob2xkX2Jhc2VzKSAtIDE7IGkgPj0gMDsgaS0tKSB7CisgICAgICAgIG9iID0gUHlUdXBsZV9HRVRfSVRFTShvbGRfYmFzZXMsIGkpOworICAgICAgICBpZiAoUHlUeXBlX0NoZWNrKG9iKSkgeworICAgICAgICAgICAgcmVtb3ZlX3N1YmNsYXNzKAorICAgICAgICAgICAgICAgIChQeVR5cGVPYmplY3QqKW9iLCB0eXBlKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIGZvciAoaSA9IFB5VHVwbGVfR0VUX1NJWkUodmFsdWUpIC0gMTsgaSA+PSAwOyBpLS0pIHsKKyAgICAgICAgb2IgPSBQeVR1cGxlX0dFVF9JVEVNKHZhbHVlLCBpKTsKKyAgICAgICAgaWYgKFB5VHlwZV9DaGVjayhvYikpIHsKKyAgICAgICAgICAgIGlmIChhZGRfc3ViY2xhc3MoKFB5VHlwZU9iamVjdCopb2IsIHR5cGUpIDwgMCkKKyAgICAgICAgICAgICAgICByID0gLTE7CisgICAgICAgIH0KKyAgICB9CisKKyAgICB1cGRhdGVfYWxsX3Nsb3RzKHR5cGUpOworCisgICAgUHlfREVDUkVGKG9sZF9iYXNlcyk7CisgICAgUHlfREVDUkVGKG9sZF9iYXNlKTsKKyAgICBQeV9ERUNSRUYob2xkX21ybyk7CisKKyAgICByZXR1cm4gcjsKKworICBiYWlsOgorICAgIFB5X0RFQ1JFRih0eXBlLT50cF9iYXNlcyk7CisgICAgUHlfREVDUkVGKHR5cGUtPnRwX2Jhc2UpOworICAgIGlmICh0eXBlLT50cF9tcm8gIT0gb2xkX21ybykgeworICAgICAgICBQeV9ERUNSRUYodHlwZS0+dHBfbXJvKTsKKyAgICB9CisKKyAgICB0eXBlLT50cF9iYXNlcyA9IG9sZF9iYXNlczsKKyAgICB0eXBlLT50cF9iYXNlID0gb2xkX2Jhc2U7CisgICAgdHlwZS0+dHBfbXJvID0gb2xkX21ybzsKKworICAgIHJldHVybiAtMTsKK30KKworc3RhdGljIFB5T2JqZWN0ICoKK3R5cGVfZGljdChQeVR5cGVPYmplY3QgKnR5cGUsIHZvaWQgKmNvbnRleHQpCit7CisgICAgaWYgKHR5cGUtPnRwX2RpY3QgPT0gTlVMTCkgeworICAgICAgICBQeV9JTkNSRUYoUHlfTm9uZSk7CisgICAgICAgIHJldHVybiBQeV9Ob25lOworICAgIH0KKyAgICByZXR1cm4gUHlEaWN0UHJveHlfTmV3KHR5cGUtPnRwX2RpY3QpOworfQorCitzdGF0aWMgUHlPYmplY3QgKgordHlwZV9nZXRfZG9jKFB5VHlwZU9iamVjdCAqdHlwZSwgdm9pZCAqY29udGV4dCkKK3sKKyAgICBQeU9iamVjdCAqcmVzdWx0OworICAgIGlmICghKHR5cGUtPnRwX2ZsYWdzICYgUHlfVFBGTEFHU19IRUFQVFlQRSkgJiYgdHlwZS0+dHBfZG9jICE9IE5VTEwpCisgICAgICAgIHJldHVybiBQeVN0cmluZ19Gcm9tU3RyaW5nKHR5cGUtPnRwX2RvYyk7CisgICAgcmVzdWx0ID0gUHlEaWN0X0dldEl0ZW1TdHJpbmcodHlwZS0+dHBfZGljdCwgIl9fZG9jX18iKTsKKyAgICBpZiAocmVzdWx0ID09IE5VTEwpIHsKKyAgICAgICAgcmVzdWx0ID0gUHlfTm9uZTsKKyAgICAgICAgUHlfSU5DUkVGKHJlc3VsdCk7CisgICAgfQorICAgIGVsc2UgaWYgKFB5X1RZUEUocmVzdWx0KS0+dHBfZGVzY3JfZ2V0KSB7CisgICAgICAgIHJlc3VsdCA9IFB5X1RZUEUocmVzdWx0KS0+dHBfZGVzY3JfZ2V0KHJlc3VsdCwgTlVMTCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKFB5T2JqZWN0ICopdHlwZSk7CisgICAgfQorICAgIGVsc2UgeworICAgICAgICBQeV9JTkNSRUYocmVzdWx0KTsKKyAgICB9CisgICAgcmV0dXJuIHJlc3VsdDsKK30KKworc3RhdGljIFB5T2JqZWN0ICoKK3R5cGVfX19pbnN0YW5jZWNoZWNrX18oUHlPYmplY3QgKnR5cGUsIFB5T2JqZWN0ICppbnN0KQoreworICAgIHN3aXRjaCAoX1B5T2JqZWN0X1JlYWxJc0luc3RhbmNlKGluc3QsIHR5cGUpKSB7CisgICAgY2FzZSAtMToKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgY2FzZSAwOgorICAgICAgICBQeV9SRVRVUk5fRkFMU0U7CisgICAgZGVmYXVsdDoKKyAgICAgICAgUHlfUkVUVVJOX1RSVUU7CisgICAgfQorfQorCisKK3N0YXRpYyBQeU9iamVjdCAqCit0eXBlX19fc3ViY2xhc3NjaGVja19fKFB5T2JqZWN0ICp0eXBlLCBQeU9iamVjdCAqaW5zdCkKK3sKKyAgICBzd2l0Y2ggKF9QeU9iamVjdF9SZWFsSXNTdWJjbGFzcyhpbnN0LCB0eXBlKSkgeworICAgIGNhc2UgLTE6CisgICAgICAgIHJldHVybiBOVUxMOworICAgIGNhc2UgMDoKKyAgICAgICAgUHlfUkVUVVJOX0ZBTFNFOworICAgIGRlZmF1bHQ6CisgICAgICAgIFB5X1JFVFVSTl9UUlVFOworICAgIH0KK30KKworCitzdGF0aWMgUHlHZXRTZXREZWYgdHlwZV9nZXRzZXRzW10gPSB7CisgICAgeyJfX25hbWVfXyIsIChnZXR0ZXIpdHlwZV9uYW1lLCAoc2V0dGVyKXR5cGVfc2V0X25hbWUsIE5VTEx9LAorICAgIHsiX19iYXNlc19fIiwgKGdldHRlcil0eXBlX2dldF9iYXNlcywgKHNldHRlcil0eXBlX3NldF9iYXNlcywgTlVMTH0sCisgICAgeyJfX21vZHVsZV9fIiwgKGdldHRlcil0eXBlX21vZHVsZSwgKHNldHRlcil0eXBlX3NldF9tb2R1bGUsIE5VTEx9LAorICAgIHsiX19hYnN0cmFjdG1ldGhvZHNfXyIsIChnZXR0ZXIpdHlwZV9hYnN0cmFjdG1ldGhvZHMsCisgICAgIChzZXR0ZXIpdHlwZV9zZXRfYWJzdHJhY3RtZXRob2RzLCBOVUxMfSwKKyAgICB7Il9fZGljdF9fIiwgIChnZXR0ZXIpdHlwZV9kaWN0LCAgTlVMTCwgTlVMTH0sCisgICAgeyJfX2RvY19fIiwgKGdldHRlcil0eXBlX2dldF9kb2MsIE5VTEwsIE5VTEx9LAorICAgIHswfQorfTsKKworCitzdGF0aWMgUHlPYmplY3QqCit0eXBlX3JpY2hjb21wYXJlKFB5T2JqZWN0ICp2LCBQeU9iamVjdCAqdywgaW50IG9wKQoreworICAgIFB5T2JqZWN0ICpyZXN1bHQ7CisgICAgUHlfdWludHB0cl90IHZ2LCB3dzsKKyAgICBpbnQgYzsKKworICAgIC8qIE1ha2Ugc3VyZSBib3RoIGFyZ3VtZW50cyBhcmUgdHlwZXMuICovCisgICAgaWYgKCFQeVR5cGVfQ2hlY2sodikgfHwgIVB5VHlwZV9DaGVjayh3KSB8fAorICAgICAgICAvKiBJZiB0aGVyZSBpcyBhIF9fY21wX18gbWV0aG9kIGRlZmluZWQsIGxldCBpdCBiZSBjYWxsZWQgaW5zdGVhZAorICAgICAgICAgICBvZiBvdXIgZHVtYiBmdW5jdGlvbiBkZXNpZ25lZCBtZXJlbHkgdG8gd2Fybi4gIFNlZSBidWcKKyAgICAgICAgICAgIzc0OTEuICovCisgICAgICAgIFB5X1RZUEUodiktPnRwX2NvbXBhcmUgfHwgUHlfVFlQRSh3KS0+dHBfY29tcGFyZSkgeworICAgICAgICByZXN1bHQgPSBQeV9Ob3RJbXBsZW1lbnRlZDsKKyAgICAgICAgZ290byBvdXQ7CisgICAgfQorCisgICAgLyogUHkzSyB3YXJuaW5nIGlmIGNvbXBhcmlzb24gaXNuJ3QgPT0gb3IgIT0gICovCisgICAgaWYgKFB5X1B5M2tXYXJuaW5nRmxhZyAmJiBvcCAhPSBQeV9FUSAmJiBvcCAhPSBQeV9ORSAmJgorICAgICAgICBQeUVycl9XYXJuRXgoUHlFeGNfRGVwcmVjYXRpb25XYXJuaW5nLAorICAgICAgICAgICAgICAgICAgICJ0eXBlIGluZXF1YWxpdHkgY29tcGFyaXNvbnMgbm90IHN1cHBvcnRlZCAiCisgICAgICAgICAgICAgICAgICAgImluIDMueCIsIDEpIDwgMCkgeworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisKKyAgICAvKiBDb21wYXJlIGFkZHJlc3NlcyAqLworICAgIHZ2ID0gKFB5X3VpbnRwdHJfdCl2OworICAgIHd3ID0gKFB5X3VpbnRwdHJfdCl3OworICAgIHN3aXRjaCAob3ApIHsKKyAgICBjYXNlIFB5X0xUOiBjID0gdnYgPCAgd3c7IGJyZWFrOworICAgIGNhc2UgUHlfTEU6IGMgPSB2diA8PSB3dzsgYnJlYWs7CisgICAgY2FzZSBQeV9FUTogYyA9IHZ2ID09IHd3OyBicmVhazsKKyAgICBjYXNlIFB5X05FOiBjID0gdnYgIT0gd3c7IGJyZWFrOworICAgIGNhc2UgUHlfR1Q6IGMgPSB2diA+ICB3dzsgYnJlYWs7CisgICAgY2FzZSBQeV9HRTogYyA9IHZ2ID49IHd3OyBicmVhazsKKyAgICBkZWZhdWx0OgorICAgICAgICByZXN1bHQgPSBQeV9Ob3RJbXBsZW1lbnRlZDsKKyAgICAgICAgZ290byBvdXQ7CisgICAgfQorICAgIHJlc3VsdCA9IGMgPyBQeV9UcnVlIDogUHlfRmFsc2U7CisKKyAgLyogaW5jcmVmIGFuZCByZXR1cm4gKi8KKyAgb3V0OgorICAgIFB5X0lOQ1JFRihyZXN1bHQpOworICAgIHJldHVybiByZXN1bHQ7Cit9CisKK3N0YXRpYyBQeU9iamVjdCAqCit0eXBlX3JlcHIoUHlUeXBlT2JqZWN0ICp0eXBlKQoreworICAgIFB5T2JqZWN0ICptb2QsICpuYW1lLCAqcnRuOworICAgIGNoYXIgKmtpbmQ7CisKKyAgICBtb2QgPSB0eXBlX21vZHVsZSh0eXBlLCBOVUxMKTsKKyAgICBpZiAobW9kID09IE5VTEwpCisgICAgICAgIFB5RXJyX0NsZWFyKCk7CisgICAgZWxzZSBpZiAoIVB5U3RyaW5nX0NoZWNrKG1vZCkpIHsKKyAgICAgICAgUHlfREVDUkVGKG1vZCk7CisgICAgICAgIG1vZCA9IE5VTEw7CisgICAgfQorICAgIG5hbWUgPSB0eXBlX25hbWUodHlwZSwgTlVMTCk7CisgICAgaWYgKG5hbWUgPT0gTlVMTCkgeworICAgICAgICBQeV9YREVDUkVGKG1vZCk7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKworICAgIGlmICh0eXBlLT50cF9mbGFncyAmIFB5X1RQRkxBR1NfSEVBUFRZUEUpCisgICAgICAgIGtpbmQgPSAiY2xhc3MiOworICAgIGVsc2UKKyAgICAgICAga2luZCA9ICJ0eXBlIjsKKworICAgIGlmIChtb2QgIT0gTlVMTCAmJiBzdHJjbXAoUHlTdHJpbmdfQVNfU1RSSU5HKG1vZCksICJfX2J1aWx0aW5fXyIpKSB7CisgICAgICAgIHJ0biA9IFB5U3RyaW5nX0Zyb21Gb3JtYXQoIjwlcyAnJXMuJXMnPiIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAga2luZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQeVN0cmluZ19BU19TVFJJTkcobW9kKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQeVN0cmluZ19BU19TVFJJTkcobmFtZSkpOworICAgIH0KKyAgICBlbHNlCisgICAgICAgIHJ0biA9IFB5U3RyaW5nX0Zyb21Gb3JtYXQoIjwlcyAnJXMnPiIsIGtpbmQsIHR5cGUtPnRwX25hbWUpOworCisgICAgUHlfWERFQ1JFRihtb2QpOworICAgIFB5X0RFQ1JFRihuYW1lKTsKKyAgICByZXR1cm4gcnRuOworfQorCitzdGF0aWMgUHlPYmplY3QgKgordHlwZV9jYWxsKFB5VHlwZU9iamVjdCAqdHlwZSwgUHlPYmplY3QgKmFyZ3MsIFB5T2JqZWN0ICprd2RzKQoreworICAgIFB5T2JqZWN0ICpvYmo7CisKKyAgICBpZiAodHlwZS0+dHBfbmV3ID09IE5VTEwpIHsKKyAgICAgICAgUHlFcnJfRm9ybWF0KFB5RXhjX1R5cGVFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICJjYW5ub3QgY3JlYXRlICclLjEwMHMnIGluc3RhbmNlcyIsCisgICAgICAgICAgICAgICAgICAgICB0eXBlLT50cF9uYW1lKTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorCisgICAgb2JqID0gdHlwZS0+dHBfbmV3KHR5cGUsIGFyZ3MsIGt3ZHMpOworICAgIGlmIChvYmogIT0gTlVMTCkgeworICAgICAgICAvKiBVZ2x5IGV4Y2VwdGlvbjogd2hlbiB0aGUgY2FsbCB3YXMgdHlwZShzb21ldGhpbmcpLAorICAgICAgICAgICBkb24ndCBjYWxsIHRwX2luaXQgb24gdGhlIHJlc3VsdC4gKi8KKyAgICAgICAgaWYgKHR5cGUgPT0gJlB5VHlwZV9UeXBlICYmCisgICAgICAgICAgICBQeVR1cGxlX0NoZWNrKGFyZ3MpICYmIFB5VHVwbGVfR0VUX1NJWkUoYXJncykgPT0gMSAmJgorICAgICAgICAgICAgKGt3ZHMgPT0gTlVMTCB8fAorICAgICAgICAgICAgIChQeURpY3RfQ2hlY2soa3dkcykgJiYgUHlEaWN0X1NpemUoa3dkcykgPT0gMCkpKQorICAgICAgICAgICAgcmV0dXJuIG9iajsKKyAgICAgICAgLyogSWYgdGhlIHJldHVybmVkIG9iamVjdCBpcyBub3QgYW4gaW5zdGFuY2Ugb2YgdHlwZSwKKyAgICAgICAgICAgaXQgd29uJ3QgYmUgaW5pdGlhbGl6ZWQuICovCisgICAgICAgIGlmICghUHlUeXBlX0lzU3VidHlwZShvYmotPm9iX3R5cGUsIHR5cGUpKQorICAgICAgICAgICAgcmV0dXJuIG9iajsKKyAgICAgICAgdHlwZSA9IG9iai0+b2JfdHlwZTsKKyAgICAgICAgaWYgKFB5VHlwZV9IYXNGZWF0dXJlKHR5cGUsIFB5X1RQRkxBR1NfSEFWRV9DTEFTUykgJiYKKyAgICAgICAgICAgIHR5cGUtPnRwX2luaXQgIT0gTlVMTCAmJgorICAgICAgICAgICAgdHlwZS0+dHBfaW5pdChvYmosIGFyZ3MsIGt3ZHMpIDwgMCkgeworICAgICAgICAgICAgUHlfREVDUkVGKG9iaik7CisgICAgICAgICAgICBvYmogPSBOVUxMOworICAgICAgICB9CisgICAgfQorICAgIHJldHVybiBvYmo7Cit9CisKK1B5T2JqZWN0ICoKK1B5VHlwZV9HZW5lcmljQWxsb2MoUHlUeXBlT2JqZWN0ICp0eXBlLCBQeV9zc2l6ZV90IG5pdGVtcykKK3sKKyAgICBQeU9iamVjdCAqb2JqOworICAgIGNvbnN0IHNpemVfdCBzaXplID0gX1B5T2JqZWN0X1ZBUl9TSVpFKHR5cGUsIG5pdGVtcysxKTsKKyAgICAvKiBub3RlIHRoYXQgd2UgbmVlZCB0byBhZGQgb25lLCBmb3IgdGhlIHNlbnRpbmVsICovCisKKyAgICBpZiAoUHlUeXBlX0lTX0dDKHR5cGUpKQorICAgICAgICBvYmogPSBfUHlPYmplY3RfR0NfTWFsbG9jKHNpemUpOworICAgIGVsc2UKKyAgICAgICAgb2JqID0gKFB5T2JqZWN0ICopUHlPYmplY3RfTUFMTE9DKHNpemUpOworCisgICAgaWYgKG9iaiA9PSBOVUxMKQorICAgICAgICByZXR1cm4gUHlFcnJfTm9NZW1vcnkoKTsKKworICAgIG1lbXNldChvYmosICdcMCcsIHNpemUpOworCisgICAgaWYgKHR5cGUtPnRwX2ZsYWdzICYgUHlfVFBGTEFHU19IRUFQVFlQRSkKKyAgICAgICAgUHlfSU5DUkVGKHR5cGUpOworCisgICAgaWYgKHR5cGUtPnRwX2l0ZW1zaXplID09IDApCisgICAgICAgIFB5T2JqZWN0X0lOSVQob2JqLCB0eXBlKTsKKyAgICBlbHNlCisgICAgICAgICh2b2lkKSBQeU9iamVjdF9JTklUX1ZBUigoUHlWYXJPYmplY3QgKilvYmosIHR5cGUsIG5pdGVtcyk7CisKKyAgICBpZiAoUHlUeXBlX0lTX0dDKHR5cGUpKQorICAgICAgICBfUHlPYmplY3RfR0NfVFJBQ0sob2JqKTsKKyAgICByZXR1cm4gb2JqOworfQorCitQeU9iamVjdCAqCitQeVR5cGVfR2VuZXJpY05ldyhQeVR5cGVPYmplY3QgKnR5cGUsIFB5T2JqZWN0ICphcmdzLCBQeU9iamVjdCAqa3dkcykKK3sKKyAgICByZXR1cm4gdHlwZS0+dHBfYWxsb2ModHlwZSwgMCk7Cit9CisKKy8qIEhlbHBlcnMgZm9yIHN1YnR5cGluZyAqLworCitzdGF0aWMgaW50Cit0cmF2ZXJzZV9zbG90cyhQeVR5cGVPYmplY3QgKnR5cGUsIFB5T2JqZWN0ICpzZWxmLCB2aXNpdHByb2MgdmlzaXQsIHZvaWQgKmFyZykKK3sKKyAgICBQeV9zc2l6ZV90IGksIG47CisgICAgUHlNZW1iZXJEZWYgKm1wOworCisgICAgbiA9IFB5X1NJWkUodHlwZSk7CisgICAgbXAgPSBQeUhlYXBUeXBlX0dFVF9NRU1CRVJTKChQeUhlYXBUeXBlT2JqZWN0ICopdHlwZSk7CisgICAgZm9yIChpID0gMDsgaSA8IG47IGkrKywgbXArKykgeworICAgICAgICBpZiAobXAtPnR5cGUgPT0gVF9PQkpFQ1RfRVgpIHsKKyAgICAgICAgICAgIGNoYXIgKmFkZHIgPSAoY2hhciAqKXNlbGYgKyBtcC0+b2Zmc2V0OworICAgICAgICAgICAgUHlPYmplY3QgKm9iaiA9ICooUHlPYmplY3QgKiopYWRkcjsKKyAgICAgICAgICAgIGlmIChvYmogIT0gTlVMTCkgeworICAgICAgICAgICAgICAgIGludCBlcnIgPSB2aXNpdChvYmosIGFyZyk7CisgICAgICAgICAgICAgICAgaWYgKGVycikKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGVycjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKyAgICByZXR1cm4gMDsKK30KKworc3RhdGljIGludAorc3VidHlwZV90cmF2ZXJzZShQeU9iamVjdCAqc2VsZiwgdmlzaXRwcm9jIHZpc2l0LCB2b2lkICphcmcpCit7CisgICAgUHlUeXBlT2JqZWN0ICp0eXBlLCAqYmFzZTsKKyAgICB0cmF2ZXJzZXByb2MgYmFzZXRyYXZlcnNlOworCisgICAgLyogRmluZCB0aGUgbmVhcmVzdCBiYXNlIHdpdGggYSBkaWZmZXJlbnQgdHBfdHJhdmVyc2UsCisgICAgICAgYW5kIHRyYXZlcnNlIHNsb3RzIHdoaWxlIHdlJ3JlIGF0IGl0ICovCisgICAgdHlwZSA9IFB5X1RZUEUoc2VsZik7CisgICAgYmFzZSA9IHR5cGU7CisgICAgd2hpbGUgKChiYXNldHJhdmVyc2UgPSBiYXNlLT50cF90cmF2ZXJzZSkgPT0gc3VidHlwZV90cmF2ZXJzZSkgeworICAgICAgICBpZiAoUHlfU0laRShiYXNlKSkgeworICAgICAgICAgICAgaW50IGVyciA9IHRyYXZlcnNlX3Nsb3RzKGJhc2UsIHNlbGYsIHZpc2l0LCBhcmcpOworICAgICAgICAgICAgaWYgKGVycikKKyAgICAgICAgICAgICAgICByZXR1cm4gZXJyOworICAgICAgICB9CisgICAgICAgIGJhc2UgPSBiYXNlLT50cF9iYXNlOworICAgICAgICBhc3NlcnQoYmFzZSk7CisgICAgfQorCisgICAgaWYgKHR5cGUtPnRwX2RpY3RvZmZzZXQgIT0gYmFzZS0+dHBfZGljdG9mZnNldCkgeworICAgICAgICBQeU9iamVjdCAqKmRpY3RwdHIgPSBfUHlPYmplY3RfR2V0RGljdFB0cihzZWxmKTsKKyAgICAgICAgaWYgKGRpY3RwdHIgJiYgKmRpY3RwdHIpCisgICAgICAgICAgICBQeV9WSVNJVCgqZGljdHB0cik7CisgICAgfQorCisgICAgaWYgKHR5cGUtPnRwX2ZsYWdzICYgUHlfVFBGTEFHU19IRUFQVFlQRSkKKyAgICAgICAgLyogRm9yIGEgaGVhcHR5cGUsIHRoZSBpbnN0YW5jZXMgY291bnQgYXMgcmVmZXJlbmNlcworICAgICAgICAgICB0byB0aGUgdHlwZS4gICAgICAgICAgVHJhdmVyc2UgdGhlIHR5cGUgc28gdGhlIGNvbGxlY3RvcgorICAgICAgICAgICBjYW4gZmluZCBjeWNsZXMgaW52b2x2aW5nIHRoaXMgbGluay4gKi8KKyAgICAgICAgUHlfVklTSVQodHlwZSk7CisKKyAgICBpZiAoYmFzZXRyYXZlcnNlKQorICAgICAgICByZXR1cm4gYmFzZXRyYXZlcnNlKHNlbGYsIHZpc2l0LCBhcmcpOworICAgIHJldHVybiAwOworfQorCitzdGF0aWMgdm9pZAorY2xlYXJfc2xvdHMoUHlUeXBlT2JqZWN0ICp0eXBlLCBQeU9iamVjdCAqc2VsZikKK3sKKyAgICBQeV9zc2l6ZV90IGksIG47CisgICAgUHlNZW1iZXJEZWYgKm1wOworCisgICAgbiA9IFB5X1NJWkUodHlwZSk7CisgICAgbXAgPSBQeUhlYXBUeXBlX0dFVF9NRU1CRVJTKChQeUhlYXBUeXBlT2JqZWN0ICopdHlwZSk7CisgICAgZm9yIChpID0gMDsgaSA8IG47IGkrKywgbXArKykgeworICAgICAgICBpZiAobXAtPnR5cGUgPT0gVF9PQkpFQ1RfRVggJiYgIShtcC0+ZmxhZ3MgJiBSRUFET05MWSkpIHsKKyAgICAgICAgICAgIGNoYXIgKmFkZHIgPSAoY2hhciAqKXNlbGYgKyBtcC0+b2Zmc2V0OworICAgICAgICAgICAgUHlPYmplY3QgKm9iaiA9ICooUHlPYmplY3QgKiopYWRkcjsKKyAgICAgICAgICAgIGlmIChvYmogIT0gTlVMTCkgeworICAgICAgICAgICAgICAgICooUHlPYmplY3QgKiopYWRkciA9IE5VTEw7CisgICAgICAgICAgICAgICAgUHlfREVDUkVGKG9iaik7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9Cit9CisKK3N0YXRpYyBpbnQKK3N1YnR5cGVfY2xlYXIoUHlPYmplY3QgKnNlbGYpCit7CisgICAgUHlUeXBlT2JqZWN0ICp0eXBlLCAqYmFzZTsKKyAgICBpbnF1aXJ5IGJhc2VjbGVhcjsKKworICAgIC8qIEZpbmQgdGhlIG5lYXJlc3QgYmFzZSB3aXRoIGEgZGlmZmVyZW50IHRwX2NsZWFyCisgICAgICAgYW5kIGNsZWFyIHNsb3RzIHdoaWxlIHdlJ3JlIGF0IGl0ICovCisgICAgdHlwZSA9IFB5X1RZUEUoc2VsZik7CisgICAgYmFzZSA9IHR5cGU7CisgICAgd2hpbGUgKChiYXNlY2xlYXIgPSBiYXNlLT50cF9jbGVhcikgPT0gc3VidHlwZV9jbGVhcikgeworICAgICAgICBpZiAoUHlfU0laRShiYXNlKSkKKyAgICAgICAgICAgIGNsZWFyX3Nsb3RzKGJhc2UsIHNlbGYpOworICAgICAgICBiYXNlID0gYmFzZS0+dHBfYmFzZTsKKyAgICAgICAgYXNzZXJ0KGJhc2UpOworICAgIH0KKworICAgIC8qIENsZWFyIHRoZSBpbnN0YW5jZSBkaWN0IChpZiBhbnkpLCB0byBicmVhayBjeWNsZXMgaW52b2x2aW5nIG9ubHkKKyAgICAgICBfX2RpY3RfXyBzbG90cyAoYXMgaW4gdGhlIGNhc2UgJ3NlbGYuX19kaWN0X18gaXMgc2VsZicpLiAqLworICAgIGlmICh0eXBlLT50cF9kaWN0b2Zmc2V0ICE9IGJhc2UtPnRwX2RpY3RvZmZzZXQpIHsKKyAgICAgICAgUHlPYmplY3QgKipkaWN0cHRyID0gX1B5T2JqZWN0X0dldERpY3RQdHIoc2VsZik7CisgICAgICAgIGlmIChkaWN0cHRyICYmICpkaWN0cHRyKQorICAgICAgICAgICAgUHlfQ0xFQVIoKmRpY3RwdHIpOworICAgIH0KKworICAgIGlmIChiYXNlY2xlYXIpCisgICAgICAgIHJldHVybiBiYXNlY2xlYXIoc2VsZik7CisgICAgcmV0dXJuIDA7Cit9CisKK3N0YXRpYyB2b2lkCitzdWJ0eXBlX2RlYWxsb2MoUHlPYmplY3QgKnNlbGYpCit7CisgICAgUHlUeXBlT2JqZWN0ICp0eXBlLCAqYmFzZTsKKyAgICBkZXN0cnVjdG9yIGJhc2VkZWFsbG9jOworICAgIFB5VGhyZWFkU3RhdGUgKnRzdGF0ZSA9IFB5VGhyZWFkU3RhdGVfR0VUKCk7CisKKyAgICAvKiBFeHRyYWN0IHRoZSB0eXBlOyB3ZSBleHBlY3QgaXQgdG8gYmUgYSBoZWFwIHR5cGUgKi8KKyAgICB0eXBlID0gUHlfVFlQRShzZWxmKTsKKyAgICBhc3NlcnQodHlwZS0+dHBfZmxhZ3MgJiBQeV9UUEZMQUdTX0hFQVBUWVBFKTsKKworICAgIC8qIFRlc3Qgd2hldGhlciB0aGUgdHlwZSBoYXMgR0MgZXhhY3RseSBvbmNlICovCisKKyAgICBpZiAoIVB5VHlwZV9JU19HQyh0eXBlKSkgeworICAgICAgICAvKiBJdCdzIHJlYWxseSByYXJlIHRvIGZpbmQgYSBkeW5hbWljIHR5cGUgdGhhdCBkb2Vzbid0IGhhdmUKKyAgICAgICAgICAgR0M7IGl0IGNhbiBvbmx5IGhhcHBlbiB3aGVuIGRlcml2aW5nIGZyb20gJ29iamVjdCcgYW5kIG5vdAorICAgICAgICAgICBhZGRpbmcgYW55IHNsb3RzIG9yIGluc3RhbmNlIHZhcmlhYmxlcy4gIFRoaXMgYWxsb3dzCisgICAgICAgICAgIGNlcnRhaW4gc2ltcGxpZmljYXRpb25zOiB0aGVyZSdzIG5vIG5lZWQgdG8gY2FsbAorICAgICAgICAgICBjbGVhcl9zbG90cygpLCBvciBERUNSRUYgdGhlIGRpY3QsIG9yIGNsZWFyIHdlYWtyZWZzLiAqLworCisgICAgICAgIC8qIE1heWJlIGNhbGwgZmluYWxpemVyOyBleGl0IGVhcmx5IGlmIHJlc3VycmVjdGVkICovCisgICAgICAgIGlmICh0eXBlLT50cF9kZWwpIHsKKyAgICAgICAgICAgIHR5cGUtPnRwX2RlbChzZWxmKTsKKyAgICAgICAgICAgIGlmIChzZWxmLT5vYl9yZWZjbnQgPiAwKQorICAgICAgICAgICAgICAgIHJldHVybjsKKyAgICAgICAgfQorCisgICAgICAgIC8qIEZpbmQgdGhlIG5lYXJlc3QgYmFzZSB3aXRoIGEgZGlmZmVyZW50IHRwX2RlYWxsb2MgKi8KKyAgICAgICAgYmFzZSA9IHR5cGU7CisgICAgICAgIHdoaWxlICgoYmFzZWRlYWxsb2MgPSBiYXNlLT50cF9kZWFsbG9jKSA9PSBzdWJ0eXBlX2RlYWxsb2MpIHsKKyAgICAgICAgICAgIGFzc2VydChQeV9TSVpFKGJhc2UpID09IDApOworICAgICAgICAgICAgYmFzZSA9IGJhc2UtPnRwX2Jhc2U7CisgICAgICAgICAgICBhc3NlcnQoYmFzZSk7CisgICAgICAgIH0KKworICAgICAgICAvKiBFeHRyYWN0IHRoZSB0eXBlIGFnYWluOyB0cF9kZWwgbWF5IGhhdmUgY2hhbmdlZCBpdCAqLworICAgICAgICB0eXBlID0gUHlfVFlQRShzZWxmKTsKKworICAgICAgICAvKiBDYWxsIHRoZSBiYXNlIHRwX2RlYWxsb2MoKSAqLworICAgICAgICBhc3NlcnQoYmFzZWRlYWxsb2MpOworICAgICAgICBiYXNlZGVhbGxvYyhzZWxmKTsKKworICAgICAgICAvKiBDYW4ndCByZWZlcmVuY2Ugc2VsZiBiZXlvbmQgdGhpcyBwb2ludCAqLworICAgICAgICBQeV9ERUNSRUYodHlwZSk7CisKKyAgICAgICAgLyogRG9uZSAqLworICAgICAgICByZXR1cm47CisgICAgfQorCisgICAgLyogV2UgZ2V0IGhlcmUgb25seSBpZiB0aGUgdHlwZSBoYXMgR0MgKi8KKworICAgIC8qIFVuVHJhY2sgYW5kIHJlLVRyYWNrIGFyb3VuZCB0aGUgdHJhc2hjYW4gbWFjcm8sIGFsYXMgKi8KKyAgICAvKiBTZWUgZXhwbGFuYXRpb24gYXQgZW5kIG9mIGZ1bmN0aW9uIGZvciBmdWxsIGRpc2Nsb3N1cmUgKi8KKyAgICBQeU9iamVjdF9HQ19VblRyYWNrKHNlbGYpOworICAgICsrX1B5VHJhc2hfZGVsZXRlX25lc3Rpbmc7CisgICAgKysgdHN0YXRlLT50cmFzaF9kZWxldGVfbmVzdGluZzsKKyAgICBQeV9UUkFTSENBTl9TQUZFX0JFR0lOKHNlbGYpOworICAgIC0tX1B5VHJhc2hfZGVsZXRlX25lc3Rpbmc7CisgICAgLS0gdHN0YXRlLT50cmFzaF9kZWxldGVfbmVzdGluZzsKKyAgICAvKiBETyBOT1QgcmVzdG9yZSBHQyB0cmFja2luZyBhdCB0aGlzIHBvaW50LiAgd2Vha3JlZiBjYWxsYmFja3MKKyAgICAgKiAoaWYgYW55LCBhbmQgd2hldGhlciBkaXJlY3RseSBoZXJlIG9yIGluZGlyZWN0bHkgaW4gc29tZXRoaW5nIHdlCisgICAgICogY2FsbCkgbWF5IHRyaWdnZXIgR0MsIGFuZCBpZiBzZWxmIGlzIHRyYWNrZWQgYXQgdGhhdCBwb2ludCwgaXQKKyAgICAgKiB3aWxsIGxvb2sgbGlrZSB0cmFzaCB0byBHQyBhbmQgR0Mgd2lsbCB0cnkgdG8gZGVsZXRlIHNlbGYgYWdhaW4uCisgICAgICovCisKKyAgICAvKiBGaW5kIHRoZSBuZWFyZXN0IGJhc2Ugd2l0aCBhIGRpZmZlcmVudCB0cF9kZWFsbG9jICovCisgICAgYmFzZSA9IHR5cGU7CisgICAgd2hpbGUgKChiYXNlZGVhbGxvYyA9IGJhc2UtPnRwX2RlYWxsb2MpID09IHN1YnR5cGVfZGVhbGxvYykgeworICAgICAgICBiYXNlID0gYmFzZS0+dHBfYmFzZTsKKyAgICAgICAgYXNzZXJ0KGJhc2UpOworICAgIH0KKworICAgIC8qIElmIHdlIGFkZGVkIGEgd2Vha2xpc3QsIHdlIGNsZWFyIGl0LiAgICAgIERvIHRoaXMgKmJlZm9yZSogY2FsbGluZworICAgICAgIHRoZSBmaW5hbGl6ZXIgKF9fZGVsX18pLCBjbGVhcmluZyBzbG90cywgb3IgY2xlYXJpbmcgdGhlIGluc3RhbmNlCisgICAgICAgZGljdC4gKi8KKworICAgIGlmICh0eXBlLT50cF93ZWFrbGlzdG9mZnNldCAmJiAhYmFzZS0+dHBfd2Vha2xpc3RvZmZzZXQpCisgICAgICAgIFB5T2JqZWN0X0NsZWFyV2Vha1JlZnMoc2VsZik7CisKKyAgICAvKiBNYXliZSBjYWxsIGZpbmFsaXplcjsgZXhpdCBlYXJseSBpZiByZXN1cnJlY3RlZCAqLworICAgIGlmICh0eXBlLT50cF9kZWwpIHsKKyAgICAgICAgX1B5T2JqZWN0X0dDX1RSQUNLKHNlbGYpOworICAgICAgICB0eXBlLT50cF9kZWwoc2VsZik7CisgICAgICAgIGlmIChzZWxmLT5vYl9yZWZjbnQgPiAwKQorICAgICAgICAgICAgZ290byBlbmRsYWJlbDsgICAgICAgICAgICAgIC8qIHJlc3VycmVjdGVkICovCisgICAgICAgIGVsc2UKKyAgICAgICAgICAgIF9QeU9iamVjdF9HQ19VTlRSQUNLKHNlbGYpOworICAgICAgICAvKiBOZXcgd2Vha3JlZnMgY291bGQgYmUgY3JlYXRlZCBkdXJpbmcgdGhlIGZpbmFsaXplciBjYWxsLgorICAgICAgICAgICAgSWYgdGhpcyBvY2N1cnMsIGNsZWFyIHRoZW0gb3V0IHdpdGhvdXQgY2FsbGluZyB0aGVpcgorICAgICAgICAgICAgZmluYWxpemVycyBzaW5jZSB0aGV5IG1pZ2h0IHJlbHkgb24gcGFydCBvZiB0aGUgb2JqZWN0CisgICAgICAgICAgICBiZWluZyBmaW5hbGl6ZWQgdGhhdCBoYXMgYWxyZWFkeSBiZWVuIGRlc3Ryb3llZC4gKi8KKyAgICAgICAgaWYgKHR5cGUtPnRwX3dlYWtsaXN0b2Zmc2V0ICYmICFiYXNlLT50cF93ZWFrbGlzdG9mZnNldCkgeworICAgICAgICAgICAgLyogTW9kZWxlZCBhZnRlciBHRVRfV0VBS1JFRlNfTElTVFBUUigpICovCisgICAgICAgICAgICBQeVdlYWtSZWZlcmVuY2UgKipsaXN0ID0gKFB5V2Vha1JlZmVyZW5jZSAqKikgXAorICAgICAgICAgICAgICAgIFB5T2JqZWN0X0dFVF9XRUFLUkVGU19MSVNUUFRSKHNlbGYpOworICAgICAgICAgICAgd2hpbGUgKCpsaXN0KQorICAgICAgICAgICAgICAgIF9QeVdlYWtyZWZfQ2xlYXJSZWYoKmxpc3QpOworICAgICAgICB9CisgICAgfQorCisgICAgLyogIENsZWFyIHNsb3RzIHVwIHRvIHRoZSBuZWFyZXN0IGJhc2Ugd2l0aCBhIGRpZmZlcmVudCB0cF9kZWFsbG9jICovCisgICAgYmFzZSA9IHR5cGU7CisgICAgd2hpbGUgKGJhc2UtPnRwX2RlYWxsb2MgPT0gc3VidHlwZV9kZWFsbG9jKSB7CisgICAgICAgIGlmIChQeV9TSVpFKGJhc2UpKQorICAgICAgICAgICAgY2xlYXJfc2xvdHMoYmFzZSwgc2VsZik7CisgICAgICAgIGJhc2UgPSBiYXNlLT50cF9iYXNlOworICAgICAgICBhc3NlcnQoYmFzZSk7CisgICAgfQorCisgICAgLyogSWYgd2UgYWRkZWQgYSBkaWN0LCBERUNSRUYgaXQgKi8KKyAgICBpZiAodHlwZS0+dHBfZGljdG9mZnNldCAmJiAhYmFzZS0+dHBfZGljdG9mZnNldCkgeworICAgICAgICBQeU9iamVjdCAqKmRpY3RwdHIgPSBfUHlPYmplY3RfR2V0RGljdFB0cihzZWxmKTsKKyAgICAgICAgaWYgKGRpY3RwdHIgIT0gTlVMTCkgeworICAgICAgICAgICAgUHlPYmplY3QgKmRpY3QgPSAqZGljdHB0cjsKKyAgICAgICAgICAgIGlmIChkaWN0ICE9IE5VTEwpIHsKKyAgICAgICAgICAgICAgICBQeV9ERUNSRUYoZGljdCk7CisgICAgICAgICAgICAgICAgKmRpY3RwdHIgPSBOVUxMOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyogRXh0cmFjdCB0aGUgdHlwZSBhZ2FpbjsgdHBfZGVsIG1heSBoYXZlIGNoYW5nZWQgaXQgKi8KKyAgICB0eXBlID0gUHlfVFlQRShzZWxmKTsKKworICAgIC8qIENhbGwgdGhlIGJhc2UgdHBfZGVhbGxvYygpOyBmaXJzdCByZXRyYWNrIHNlbGYgaWYKKyAgICAgKiBiYXNlZGVhbGxvYyBrbm93cyBhYm91dCBnYy4KKyAgICAgKi8KKyAgICBpZiAoUHlUeXBlX0lTX0dDKGJhc2UpKQorICAgICAgICBfUHlPYmplY3RfR0NfVFJBQ0soc2VsZik7CisgICAgYXNzZXJ0KGJhc2VkZWFsbG9jKTsKKyAgICBiYXNlZGVhbGxvYyhzZWxmKTsKKworICAgIC8qIENhbid0IHJlZmVyZW5jZSBzZWxmIGJleW9uZCB0aGlzIHBvaW50ICovCisgICAgUHlfREVDUkVGKHR5cGUpOworCisgIGVuZGxhYmVsOgorICAgICsrX1B5VHJhc2hfZGVsZXRlX25lc3Rpbmc7CisgICAgKysgdHN0YXRlLT50cmFzaF9kZWxldGVfbmVzdGluZzsKKyAgICBQeV9UUkFTSENBTl9TQUZFX0VORChzZWxmKTsKKyAgICAtLV9QeVRyYXNoX2RlbGV0ZV9uZXN0aW5nOworICAgIC0tIHRzdGF0ZS0+dHJhc2hfZGVsZXRlX25lc3Rpbmc7CisKKyAgICAvKiBFeHBsYW5hdGlvbiBvZiB0aGUgd2VpcmRuZXNzIGFyb3VuZCB0aGUgdHJhc2hjYW4gbWFjcm9zOgorCisgICAgICAgUS4gV2hhdCBkbyB0aGUgdHJhc2hjYW4gbWFjcm9zIGRvPworCisgICAgICAgQS4gUmVhZCB0aGUgY29tbWVudCB0aXRsZWQgIlRyYXNoY2FuIG1lY2hhbmlzbSIgaW4gb2JqZWN0LmguCisgICAgICAgICAgRm9yIG9uZSwgdGhpcyBleHBsYWlucyB3aHkgdGhlcmUgbXVzdCBiZSBhIGNhbGwgdG8gR0MtdW50cmFjaworICAgICAgICAgIGJlZm9yZSB0aGUgdHJhc2hjYW4gYmVnaW4gbWFjcm8uICAgICAgV2l0aG91dCB1bmRlcnN0YW5kaW5nIHRoZQorICAgICAgICAgIHRyYXNoY2FuIGNvZGUsIHRoZSBhbnN3ZXJzIHRvIHRoZSBmb2xsb3dpbmcgcXVlc3Rpb25zIGRvbid0IG1ha2UKKyAgICAgICAgICBzZW5zZS4KKworICAgICAgIFEuIFdoeSBkbyB3ZSBHQy11bnRyYWNrIGJlZm9yZSB0aGUgdHJhc2hjYW4gYW5kIHRoZW4gaW1tZWRpYXRlbHkKKyAgICAgICAgICBHQy10cmFjayBhZ2FpbiBhZnRlcndhcmQ/CisKKyAgICAgICBBLiBJbiB0aGUgY2FzZSB0aGF0IHRoZSBiYXNlIGNsYXNzIGlzIEdDLWF3YXJlLCB0aGUgYmFzZSBjbGFzcworICAgICAgICAgIHByb2JhYmx5IEdDLXVudHJhY2tzIHRoZSBvYmplY3QuICAgICAgSWYgaXQgZG9lcyB0aGF0IHVzaW5nIHRoZQorICAgICAgICAgIFVOVFJBQ0sgbWFjcm8sIHRoaXMgd2lsbCBjcmFzaCB3aGVuIHRoZSBvYmplY3QgaXMgYWxyZWFkeQorICAgICAgICAgIHVudHJhY2tlZC4gIEJlY2F1c2Ugd2UgZG9uJ3Qga25vdyB3aGF0IHRoZSBiYXNlIGNsYXNzIGRvZXMsIHRoZQorICAgICAgICAgIG9ubHkgc2FmZSB0aGluZyBpcyB0byBtYWtlIHN1cmUgdGhlIG9iamVjdCBpcyB0cmFja2VkIHdoZW4gd2UKKyAgICAgICAgICBjYWxsIHRoZSBiYXNlIGNsYXNzIGRlYWxsb2MuICBCdXQuLi4gIFRoZSB0cmFzaGNhbiBiZWdpbiBtYWNybworICAgICAgICAgIHJlcXVpcmVzIHRoYXQgdGhlIG9iamVjdCBpcyAqdW50cmFja2VkKiBiZWZvcmUgaXQgaXMgY2FsbGVkLiAgU28KKyAgICAgICAgICB0aGUgZGFuY2UgYmVjb21lczoKKworICAgICAgICAgR0MgdW50cmFjaworICAgICAgICAgdHJhc2hjYW4gYmVnaW4KKyAgICAgICAgIEdDIHRyYWNrCisKKyAgICAgICBRLiBXaHkgZGlkIHRoZSBsYXN0IHF1ZXN0aW9uIHNheSAiaW1tZWRpYXRlbHkgR0MtdHJhY2sgYWdhaW4iPworICAgICAgICAgIEl0J3Mgbm93aGVyZSBuZWFyIGltbWVkaWF0ZWx5LgorCisgICAgICAgQS4gQmVjYXVzZSB0aGUgY29kZSAqdXNlZCogdG8gcmUtdHJhY2sgaW1tZWRpYXRlbHkuICAgICAgQmFkIElkZWEuCisgICAgICAgICAgc2VsZiBoYXMgYSByZWZjb3VudCBvZiAwLCBhbmQgaWYgZ2MgZXZlciBnZXRzIGl0cyBoYW5kcyBvbiBpdAorICAgICAgICAgICh3aGljaCBjYW4gaGFwcGVuIGlmIGFueSB3ZWFrcmVmIGNhbGxiYWNrIGdldHMgaW52b2tlZCksIGl0CisgICAgICAgICAgbG9va3MgbGlrZSB0cmFzaCB0byBnYyB0b28sIGFuZCBnYyBhbHNvIHRyaWVzIHRvIGRlbGV0ZSBzZWxmCisgICAgICAgICAgdGhlbi4gIEJ1dCB3ZSdyZSBhbHJlYWR5IGRlbGV0aW5nIHNlbGYuICBEb3VibGUgZGVhbGxvY2F0aW9uIGlzCisgICAgICAgICAgYSBzdWJ0bGUgZGlzYXN0ZXIuCisKKyAgICAgICBRLiBXaHkgdGhlIGJpemFycmUgKG5ldC16ZXJvKSBtYW5pcHVsYXRpb24gb2YKKyAgICAgICAgICBfUHlUcmFzaF9kZWxldGVfbmVzdGluZyBhcm91bmQgdGhlIHRyYXNoY2FuIG1hY3Jvcz8KKworICAgICAgIEEuIFNvbWUgYmFzZSBjbGFzc2VzIChlLmcuIGxpc3QpIGFsc28gdXNlIHRoZSB0cmFzaGNhbiBtZWNoYW5pc20uCisgICAgICAgICAgVGhlIGZvbGxvd2luZyBzY2VuYXJpbyB1c2VkIHRvIGJlIHBvc3NpYmxlOgorCisgICAgICAgICAgLSBzdXBwb3NlIHRoZSB0cmFzaGNhbiBsZXZlbCBpcyBvbmUgYmVsb3cgdGhlIHRyYXNoY2FuIGxpbWl0CisKKyAgICAgICAgICAtIHN1YnR5cGVfZGVhbGxvYygpIGlzIGNhbGxlZAorCisgICAgICAgICAgLSB0aGUgdHJhc2hjYW4gbGltaXQgaXMgbm90IHlldCByZWFjaGVkLCBzbyB0aGUgdHJhc2hjYW4gbGV2ZWwKKyAgICAgICAgaXMgaW5jcmVtZW50ZWQgYW5kIHRoZSBjb2RlIGJldHdlZW4gdHJhc2hjYW4gYmVnaW4gYW5kIGVuZCBpcworICAgICAgICBleGVjdXRlZAorCisgICAgICAgICAgLSB0aGlzIGRlc3Ryb3lzIG11Y2ggb2YgdGhlIG9iamVjdCdzIGNvbnRlbnRzLCBpbmNsdWRpbmcgaXRzCisgICAgICAgIHNsb3RzIGFuZCBfX2RpY3RfXworCisgICAgICAgICAgLSBiYXNlZGVhbGxvYygpIGlzIGNhbGxlZDsgdGhpcyBpcyByZWFsbHkgbGlzdF9kZWFsbG9jKCksIG9yCisgICAgICAgIHNvbWUgb3RoZXIgdHlwZSB3aGljaCBhbHNvIHVzZXMgdGhlIHRyYXNoY2FuIG1hY3JvcworCisgICAgICAgICAgLSB0aGUgdHJhc2hjYW4gbGltaXQgaXMgbm93IHJlYWNoZWQsIHNvIHRoZSBvYmplY3QgaXMgcHV0IG9uIHRoZQorICAgICAgICB0cmFzaGNhbidzIHRvLWJlLWRlbGV0ZWQtbGF0ZXIgbGlzdAorCisgICAgICAgICAgLSBiYXNlZGVhbGxvYygpIHJldHVybnMKKworICAgICAgICAgIC0gc3VidHlwZV9kZWFsbG9jKCkgZGVjcmVmcyB0aGUgb2JqZWN0J3MgdHlwZQorCisgICAgICAgICAgLSBzdWJ0eXBlX2RlYWxsb2MoKSByZXR1cm5zCisKKyAgICAgICAgICAtIGxhdGVyLCB0aGUgdHJhc2hjYW4gY29kZSBzdGFydHMgZGVsZXRpbmcgdGhlIG9iamVjdHMgZnJvbSBpdHMKKyAgICAgICAgdG8tYmUtZGVsZXRlZC1sYXRlciBsaXN0CisKKyAgICAgICAgICAtIHN1YnR5cGVfZGVhbGxvYygpIGlzIGNhbGxlZCAqQUdBSU4qIGZvciB0aGUgc2FtZSBvYmplY3QKKworICAgICAgICAgIC0gYXQgdGhlIHZlcnkgbGVhc3QgKGlmIHRoZSBkZXN0cm95ZWQgc2xvdHMgYW5kIF9fZGljdF9fIGRvbid0CisgICAgICAgIGNhdXNlIHByb2JsZW1zKSB0aGUgb2JqZWN0J3MgdHlwZSBnZXRzIGRlY3JlZidlZCBhIHNlY29uZAorICAgICAgICB0aW1lLCB3aGljaCBpcyAqQkFEKiEhIQorCisgICAgICAgICAgVGhlIHJlbWVkeSBpcyB0byBtYWtlIHN1cmUgdGhhdCBpZiB0aGUgY29kZSBiZXR3ZWVuIHRyYXNoY2FuCisgICAgICAgICAgYmVnaW4gYW5kIGVuZCBpbiBzdWJ0eXBlX2RlYWxsb2MoKSBpcyBjYWxsZWQsIHRoZSBjb2RlIGJldHdlZW4KKyAgICAgICAgICB0cmFzaGNhbiBiZWdpbiBhbmQgZW5kIGluIGJhc2VkZWFsbG9jKCkgd2lsbCBhbHNvIGJlIGNhbGxlZC4KKyAgICAgICAgICBUaGlzIGlzIGRvbmUgYnkgZGVjcmVtZW50aW5nIHRoZSBsZXZlbCBhZnRlciBwYXNzaW5nIGludG8gdGhlCisgICAgICAgICAgdHJhc2hjYW4gYmxvY2ssIGFuZCBpbmNyZW1lbnRpbmcgaXQganVzdCBiZWZvcmUgbGVhdmluZyB0aGUKKyAgICAgICAgICBibG9jay4KKworICAgICAgICAgIEJ1dCBub3cgaXQncyBwb3NzaWJsZSB0aGF0IGEgY2hhaW4gb2Ygb2JqZWN0cyBjb25zaXN0aW5nIHNvbGVseQorICAgICAgICAgIG9mIG9iamVjdHMgd2hvc2UgZGVhbGxvY2F0b3IgaXMgc3VidHlwZV9kZWFsbG9jKCkgd2lsbCBkZWZlYXQKKyAgICAgICAgICB0aGUgdHJhc2hjYW4gbWVjaGFuaXNtIGNvbXBsZXRlbHk6IHRoZSBkZWNyZW1lbnRlZCBsZXZlbCBtZWFucworICAgICAgICAgIHRoYXQgdGhlIGVmZmVjdGl2ZSBsZXZlbCBuZXZlciByZWFjaGVzIHRoZSBsaW1pdC4gICAgICBUaGVyZWZvcmUsIHdlCisgICAgICAgICAgKmluY3JlbWVudCogdGhlIGxldmVsICpiZWZvcmUqIGVudGVyaW5nIHRoZSB0cmFzaGNhbiBibG9jaywgYW5kCisgICAgICAgICAgbWF0Y2hpbmdseSBkZWNyZW1lbnQgaXQgYWZ0ZXIgbGVhdmluZy4gIFRoaXMgbWVhbnMgdGhlIHRyYXNoY2FuCisgICAgICAgICAgY29kZSB3aWxsIHRyaWdnZXIgYSBsaXR0bGUgZWFybHksIGJ1dCB0aGF0J3Mgbm8gYmlnIGRlYWwuCisKKyAgICAgICBRLiBBcmUgdGhlcmUgYW55IGxpdmUgZXhhbXBsZXMgb2YgY29kZSBpbiBuZWVkIG9mIGFsbCB0aGlzCisgICAgICAgICAgY29tcGxleGl0eT8KKworICAgICAgIEEuIFllcy4gIFNlZSBTRiBidWcgNjY4NDMzIGZvciBjb2RlIHRoYXQgY3Jhc2hlZCAod2hlbiBQeXRob24gd2FzCisgICAgICAgICAgY29tcGlsZWQgaW4gZGVidWcgbW9kZSkgYmVmb3JlIHRoZSB0cmFzaGNhbiBsZXZlbCBtYW5pcHVsYXRpb25zCisgICAgICAgICAgd2VyZSBhZGRlZC4gIEZvciBtb3JlIGRpc2N1c3Npb24sIHNlZSBTRiBwYXRjaGVzIDU4MTc0MiwgNTc1MDczCisgICAgICAgICAgYW5kIGJ1ZyA1NzQyMDcuCisgICAgKi8KK30KKworc3RhdGljIFB5VHlwZU9iamVjdCAqc29saWRfYmFzZShQeVR5cGVPYmplY3QgKnR5cGUpOworCisvKiB0eXBlIHRlc3Qgd2l0aCBzdWJjbGFzc2luZyBzdXBwb3J0ICovCisKK2ludAorUHlUeXBlX0lzU3VidHlwZShQeVR5cGVPYmplY3QgKmEsIFB5VHlwZU9iamVjdCAqYikKK3sKKyAgICBQeU9iamVjdCAqbXJvOworCisgICAgaWYgKCEoYS0+dHBfZmxhZ3MgJiBQeV9UUEZMQUdTX0hBVkVfQ0xBU1MpKQorICAgICAgICByZXR1cm4gYiA9PSBhIHx8IGIgPT0gJlB5QmFzZU9iamVjdF9UeXBlOworCisgICAgbXJvID0gYS0+dHBfbXJvOworICAgIGlmIChtcm8gIT0gTlVMTCkgeworICAgICAgICAvKiBEZWFsIHdpdGggbXVsdGlwbGUgaW5oZXJpdGFuY2Ugd2l0aG91dCByZWN1cnNpb24KKyAgICAgICAgICAgYnkgd2Fsa2luZyB0aGUgTVJPIHR1cGxlICovCisgICAgICAgIFB5X3NzaXplX3QgaSwgbjsKKyAgICAgICAgYXNzZXJ0KFB5VHVwbGVfQ2hlY2sobXJvKSk7CisgICAgICAgIG4gPSBQeVR1cGxlX0dFVF9TSVpFKG1ybyk7CisgICAgICAgIGZvciAoaSA9IDA7IGkgPCBuOyBpKyspIHsKKyAgICAgICAgICAgIGlmIChQeVR1cGxlX0dFVF9JVEVNKG1ybywgaSkgPT0gKFB5T2JqZWN0ICopYikKKyAgICAgICAgICAgICAgICByZXR1cm4gMTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gMDsKKyAgICB9CisgICAgZWxzZSB7CisgICAgICAgIC8qIGEgaXMgbm90IGNvbXBsZXRlbHkgaW5pdGlsaXplZCB5ZXQ7IGZvbGxvdyB0cF9iYXNlICovCisgICAgICAgIGRvIHsKKyAgICAgICAgICAgIGlmIChhID09IGIpCisgICAgICAgICAgICAgICAgcmV0dXJuIDE7CisgICAgICAgICAgICBhID0gYS0+dHBfYmFzZTsKKyAgICAgICAgfSB3aGlsZSAoYSAhPSBOVUxMKTsKKyAgICAgICAgcmV0dXJuIGIgPT0gJlB5QmFzZU9iamVjdF9UeXBlOworICAgIH0KK30KKworLyogSW50ZXJuYWwgcm91dGluZXMgdG8gZG8gYSBtZXRob2QgbG9va3VwIGluIHRoZSB0eXBlCisgICB3aXRob3V0IGxvb2tpbmcgaW4gdGhlIGluc3RhbmNlIGRpY3Rpb25hcnkKKyAgIChzbyB3ZSBjYW4ndCB1c2UgUHlPYmplY3RfR2V0QXR0cikgYnV0IHN0aWxsIGJpbmRpbmcKKyAgIGl0IHRvIHRoZSBpbnN0YW5jZS4gIFRoZSBhcmd1bWVudHMgYXJlIHRoZSBvYmplY3QsCisgICB0aGUgbWV0aG9kIG5hbWUgYXMgYSBDIHN0cmluZywgYW5kIHRoZSBhZGRyZXNzIG9mIGEKKyAgIHN0YXRpYyB2YXJpYWJsZSB1c2VkIHRvIGNhY2hlIHRoZSBpbnRlcm5lZCBQeXRob24gc3RyaW5nLgorCisgICBUd28gdmFyaWFudHM6CisKKyAgIC0gbG9va3VwX21heWJlKCkgcmV0dXJucyBOVUxMIHdpdGhvdXQgcmFpc2luZyBhbiBleGNlcHRpb24KKyAgICAgd2hlbiB0aGUgX1B5VHlwZV9Mb29rdXAoKSBjYWxsIGZhaWxzOworCisgICAtIGxvb2t1cF9tZXRob2QoKSBhbHdheXMgcmFpc2VzIGFuIGV4Y2VwdGlvbiB1cG9uIGVycm9ycy4KKworICAgLSBfUHlPYmplY3RfTG9va3VwU3BlY2lhbCgpIGV4cG9ydGVkIGZvciB0aGUgYmVuZWZpdCBvZiBvdGhlciBwbGFjZXMuCisqLworCitzdGF0aWMgUHlPYmplY3QgKgorbG9va3VwX21heWJlKFB5T2JqZWN0ICpzZWxmLCBjaGFyICphdHRyc3RyLCBQeU9iamVjdCAqKmF0dHJvYmopCit7CisgICAgUHlPYmplY3QgKnJlczsKKworICAgIGlmICgqYXR0cm9iaiA9PSBOVUxMKSB7CisgICAgICAgICphdHRyb2JqID0gUHlTdHJpbmdfSW50ZXJuRnJvbVN0cmluZyhhdHRyc3RyKTsKKyAgICAgICAgaWYgKCphdHRyb2JqID09IE5VTEwpCisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgcmVzID0gX1B5VHlwZV9Mb29rdXAoUHlfVFlQRShzZWxmKSwgKmF0dHJvYmopOworICAgIGlmIChyZXMgIT0gTlVMTCkgeworICAgICAgICBkZXNjcmdldGZ1bmMgZjsKKyAgICAgICAgaWYgKChmID0gUHlfVFlQRShyZXMpLT50cF9kZXNjcl9nZXQpID09IE5VTEwpCisgICAgICAgICAgICBQeV9JTkNSRUYocmVzKTsKKyAgICAgICAgZWxzZQorICAgICAgICAgICAgcmVzID0gZihyZXMsIHNlbGYsIChQeU9iamVjdCAqKShQeV9UWVBFKHNlbGYpKSk7CisgICAgfQorICAgIHJldHVybiByZXM7Cit9CisKK3N0YXRpYyBQeU9iamVjdCAqCitsb29rdXBfbWV0aG9kKFB5T2JqZWN0ICpzZWxmLCBjaGFyICphdHRyc3RyLCBQeU9iamVjdCAqKmF0dHJvYmopCit7CisgICAgUHlPYmplY3QgKnJlcyA9IGxvb2t1cF9tYXliZShzZWxmLCBhdHRyc3RyLCBhdHRyb2JqKTsKKyAgICBpZiAocmVzID09IE5VTEwgJiYgIVB5RXJyX09jY3VycmVkKCkpCisgICAgICAgIFB5RXJyX1NldE9iamVjdChQeUV4Y19BdHRyaWJ1dGVFcnJvciwgKmF0dHJvYmopOworICAgIHJldHVybiByZXM7Cit9CisKK1B5T2JqZWN0ICoKK19QeU9iamVjdF9Mb29rdXBTcGVjaWFsKFB5T2JqZWN0ICpzZWxmLCBjaGFyICphdHRyc3RyLCBQeU9iamVjdCAqKmF0dHJvYmopCit7CisgICAgYXNzZXJ0KCFQeUluc3RhbmNlX0NoZWNrKHNlbGYpKTsKKyAgICByZXR1cm4gbG9va3VwX21heWJlKHNlbGYsIGF0dHJzdHIsIGF0dHJvYmopOworfQorCisvKiBBIHZhcmlhdGlvbiBvZiBQeU9iamVjdF9DYWxsTWV0aG9kIHRoYXQgdXNlcyBsb29rdXBfbWV0aG9kKCkKKyAgIGluc3RlYWQgb2YgUHlPYmplY3RfR2V0QXR0clN0cmluZygpLiAgVGhpcyB1c2VzIHRoZSBzYW1lIGNvbnZlbnRpb24KKyAgIGFzIGxvb2t1cF9tZXRob2QgdG8gY2FjaGUgdGhlIGludGVybmVkIG5hbWUgc3RyaW5nIG9iamVjdC4gKi8KKworc3RhdGljIFB5T2JqZWN0ICoKK2NhbGxfbWV0aG9kKFB5T2JqZWN0ICpvLCBjaGFyICpuYW1lLCBQeU9iamVjdCAqKm5hbWVvYmosIGNoYXIgKmZvcm1hdCwgLi4uKQoreworICAgIHZhX2xpc3QgdmE7CisgICAgUHlPYmplY3QgKmFyZ3MsICpmdW5jID0gMCwgKnJldHZhbDsKKyAgICB2YV9zdGFydCh2YSwgZm9ybWF0KTsKKworICAgIGZ1bmMgPSBsb29rdXBfbWF5YmUobywgbmFtZSwgbmFtZW9iaik7CisgICAgaWYgKGZ1bmMgPT0gTlVMTCkgeworICAgICAgICB2YV9lbmQodmEpOworICAgICAgICBpZiAoIVB5RXJyX09jY3VycmVkKCkpCisgICAgICAgICAgICBQeUVycl9TZXRPYmplY3QoUHlFeGNfQXR0cmlidXRlRXJyb3IsICpuYW1lb2JqKTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorCisgICAgaWYgKGZvcm1hdCAmJiAqZm9ybWF0KQorICAgICAgICBhcmdzID0gUHlfVmFCdWlsZFZhbHVlKGZvcm1hdCwgdmEpOworICAgIGVsc2UKKyAgICAgICAgYXJncyA9IFB5VHVwbGVfTmV3KDApOworCisgICAgdmFfZW5kKHZhKTsKKworICAgIGlmIChhcmdzID09IE5VTEwpCisgICAgICAgIHJldHVybiBOVUxMOworCisgICAgYXNzZXJ0KFB5VHVwbGVfQ2hlY2soYXJncykpOworICAgIHJldHZhbCA9IFB5T2JqZWN0X0NhbGwoZnVuYywgYXJncywgTlVMTCk7CisKKyAgICBQeV9ERUNSRUYoYXJncyk7CisgICAgUHlfREVDUkVGKGZ1bmMpOworCisgICAgcmV0dXJuIHJldHZhbDsKK30KKworLyogQ2xvbmUgb2YgY2FsbF9tZXRob2QoKSB0aGF0IHJldHVybnMgTm90SW1wbGVtZW50ZWQgd2hlbiB0aGUgbG9va3VwIGZhaWxzLiAqLworCitzdGF0aWMgUHlPYmplY3QgKgorY2FsbF9tYXliZShQeU9iamVjdCAqbywgY2hhciAqbmFtZSwgUHlPYmplY3QgKipuYW1lb2JqLCBjaGFyICpmb3JtYXQsIC4uLikKK3sKKyAgICB2YV9saXN0IHZhOworICAgIFB5T2JqZWN0ICphcmdzLCAqZnVuYyA9IDAsICpyZXR2YWw7CisgICAgdmFfc3RhcnQodmEsIGZvcm1hdCk7CisKKyAgICBmdW5jID0gbG9va3VwX21heWJlKG8sIG5hbWUsIG5hbWVvYmopOworICAgIGlmIChmdW5jID09IE5VTEwpIHsKKyAgICAgICAgdmFfZW5kKHZhKTsKKyAgICAgICAgaWYgKCFQeUVycl9PY2N1cnJlZCgpKSB7CisgICAgICAgICAgICBQeV9JTkNSRUYoUHlfTm90SW1wbGVtZW50ZWQpOworICAgICAgICAgICAgcmV0dXJuIFB5X05vdEltcGxlbWVudGVkOworICAgICAgICB9CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKworICAgIGlmIChmb3JtYXQgJiYgKmZvcm1hdCkKKyAgICAgICAgYXJncyA9IFB5X1ZhQnVpbGRWYWx1ZShmb3JtYXQsIHZhKTsKKyAgICBlbHNlCisgICAgICAgIGFyZ3MgPSBQeVR1cGxlX05ldygwKTsKKworICAgIHZhX2VuZCh2YSk7CisKKyAgICBpZiAoYXJncyA9PSBOVUxMKQorICAgICAgICByZXR1cm4gTlVMTDsKKworICAgIGFzc2VydChQeVR1cGxlX0NoZWNrKGFyZ3MpKTsKKyAgICByZXR2YWwgPSBQeU9iamVjdF9DYWxsKGZ1bmMsIGFyZ3MsIE5VTEwpOworCisgICAgUHlfREVDUkVGKGFyZ3MpOworICAgIFB5X0RFQ1JFRihmdW5jKTsKKworICAgIHJldHVybiByZXR2YWw7Cit9CisKK3N0YXRpYyBpbnQKK2ZpbGxfY2xhc3NpY19tcm8oUHlPYmplY3QgKm1ybywgUHlPYmplY3QgKmNscykKK3sKKyAgICBQeU9iamVjdCAqYmFzZXMsICpiYXNlOworICAgIFB5X3NzaXplX3QgaSwgbjsKKworICAgIGFzc2VydChQeUxpc3RfQ2hlY2sobXJvKSk7CisgICAgYXNzZXJ0KFB5Q2xhc3NfQ2hlY2soY2xzKSk7CisgICAgaSA9IFB5U2VxdWVuY2VfQ29udGFpbnMobXJvLCBjbHMpOworICAgIGlmIChpIDwgMCkKKyAgICAgICAgcmV0dXJuIC0xOworICAgIGlmICghaSkgeworICAgICAgICBpZiAoUHlMaXN0X0FwcGVuZChtcm8sIGNscykgPCAwKQorICAgICAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKyAgICBiYXNlcyA9ICgoUHlDbGFzc09iamVjdCAqKWNscyktPmNsX2Jhc2VzOworICAgIGFzc2VydChiYXNlcyAmJiBQeVR1cGxlX0NoZWNrKGJhc2VzKSk7CisgICAgbiA9IFB5VHVwbGVfR0VUX1NJWkUoYmFzZXMpOworICAgIGZvciAoaSA9IDA7IGkgPCBuOyBpKyspIHsKKyAgICAgICAgYmFzZSA9IFB5VHVwbGVfR0VUX0lURU0oYmFzZXMsIGkpOworICAgICAgICBpZiAoZmlsbF9jbGFzc2ljX21ybyhtcm8sIGJhc2UpIDwgMCkKKyAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisgICAgcmV0dXJuIDA7Cit9CisKK3N0YXRpYyBQeU9iamVjdCAqCitjbGFzc2ljX21ybyhQeU9iamVjdCAqY2xzKQoreworICAgIFB5T2JqZWN0ICptcm87CisKKyAgICBhc3NlcnQoUHlDbGFzc19DaGVjayhjbHMpKTsKKyAgICBtcm8gPSBQeUxpc3RfTmV3KDApOworICAgIGlmIChtcm8gIT0gTlVMTCkgeworICAgICAgICBpZiAoZmlsbF9jbGFzc2ljX21ybyhtcm8sIGNscykgPT0gMCkKKyAgICAgICAgICAgIHJldHVybiBtcm87CisgICAgICAgIFB5X0RFQ1JFRihtcm8pOworICAgIH0KKyAgICByZXR1cm4gTlVMTDsKK30KKworLyoKKyAgICBNZXRob2QgcmVzb2x1dGlvbiBvcmRlciBhbGdvcml0aG0gQzMgZGVzY3JpYmVkIGluCisgICAgIkEgTW9ub3RvbmljIFN1cGVyY2xhc3MgTGluZWFyaXphdGlvbiBmb3IgRHlsYW4iLAorICAgIGJ5IEtpbSBCYXJyZXR0LCBCb2IgQ2Fzc2VsLCBQYXVsIEhhYWhyLAorICAgIERhdmlkIEEuIE1vb24sIEtlaXRoIFBsYXlmb3JkLCBhbmQgUC4gVHVja2VyIFdpdGhpbmd0b24uCisgICAgKE9PUFNMQSAxOTk2KQorCisgICAgU29tZSBub3RlcyBhYm91dCB0aGUgcnVsZXMgaW1wbGllZCBieSBDMzoKKworICAgIE5vIGR1cGxpY2F0ZSBiYXNlcy4KKyAgICBJdCBpc24ndCBsZWdhbCB0byByZXBlYXQgYSBjbGFzcyBpbiBhIGxpc3Qgb2YgYmFzZSBjbGFzc2VzLgorCisgICAgVGhlIG5leHQgdGhyZWUgcHJvcGVydGllcyBhcmUgdGhlIDMgY29uc3RyYWludHMgaW4gIkMzIi4KKworICAgIExvY2FsIHByZWNlbmRlY2Ugb3JkZXIuCisgICAgSWYgQSBwcmVjZWRlcyBCIGluIEMncyBNUk8sIHRoZW4gQSB3aWxsIHByZWNlZGUgQiBpbiB0aGUgTVJPIG9mIGFsbAorICAgIHN1YmNsYXNzZXMgb2YgQy4KKworICAgIE1vbm90b25pY2l0eS4KKyAgICBUaGUgTVJPIG9mIGEgY2xhc3MgbXVzdCBiZSBhbiBleHRlbnNpb24gd2l0aG91dCByZW9yZGVyaW5nIG9mIHRoZQorICAgIE1STyBvZiBlYWNoIG9mIGl0cyBzdXBlcmNsYXNzZXMuCisKKyAgICBFeHRlbmRlZCBQcmVjZWRlbmNlIEdyYXBoIChFUEcpLgorICAgIExpbmVhcml6YXRpb24gaXMgY29uc2lzdGVudCBpZiB0aGVyZSBpcyBhIHBhdGggaW4gdGhlIEVQRyBmcm9tCisgICAgZWFjaCBjbGFzcyB0byBhbGwgaXRzIHN1Y2Nlc3NvcnMgaW4gdGhlIGxpbmVhcml6YXRpb24uICBTZWUKKyAgICB0aGUgcGFwZXIgZm9yIGRlZmluaXRpb24gb2YgRVBHLgorICovCisKK3N0YXRpYyBpbnQKK3RhaWxfY29udGFpbnMoUHlPYmplY3QgKmxpc3QsIGludCB3aGVuY2UsIFB5T2JqZWN0ICpvKSB7CisgICAgUHlfc3NpemVfdCBqLCBzaXplOworICAgIHNpemUgPSBQeUxpc3RfR0VUX1NJWkUobGlzdCk7CisKKyAgICBmb3IgKGogPSB3aGVuY2UrMTsgaiA8IHNpemU7IGorKykgeworICAgICAgICBpZiAoUHlMaXN0X0dFVF9JVEVNKGxpc3QsIGopID09IG8pCisgICAgICAgICAgICByZXR1cm4gMTsKKyAgICB9CisgICAgcmV0dXJuIDA7Cit9CisKK3N0YXRpYyBQeU9iamVjdCAqCitjbGFzc19uYW1lKFB5T2JqZWN0ICpjbHMpCit7CisgICAgUHlPYmplY3QgKm5hbWUgPSBQeU9iamVjdF9HZXRBdHRyU3RyaW5nKGNscywgIl9fbmFtZV9fIik7CisgICAgaWYgKG5hbWUgPT0gTlVMTCkgeworICAgICAgICBQeUVycl9DbGVhcigpOworICAgICAgICBQeV9YREVDUkVGKG5hbWUpOworICAgICAgICBuYW1lID0gUHlPYmplY3RfUmVwcihjbHMpOworICAgIH0KKyAgICBpZiAobmFtZSA9PSBOVUxMKQorICAgICAgICByZXR1cm4gTlVMTDsKKyAgICBpZiAoIVB5U3RyaW5nX0NoZWNrKG5hbWUpKSB7CisgICAgICAgIFB5X0RFQ1JFRihuYW1lKTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIHJldHVybiBuYW1lOworfQorCitzdGF0aWMgaW50CitjaGVja19kdXBsaWNhdGVzKFB5T2JqZWN0ICpsaXN0KQoreworICAgIFB5X3NzaXplX3QgaSwgaiwgbjsKKyAgICAvKiBMZXQncyB1c2UgYSBxdWFkcmF0aWMgdGltZSBhbGdvcml0aG0sCisgICAgICAgYXNzdW1pbmcgdGhhdCB0aGUgYmFzZXMgbGlzdHMgaXMgc2hvcnQuCisgICAgKi8KKyAgICBuID0gUHlMaXN0X0dFVF9TSVpFKGxpc3QpOworICAgIGZvciAoaSA9IDA7IGkgPCBuOyBpKyspIHsKKyAgICAgICAgUHlPYmplY3QgKm8gPSBQeUxpc3RfR0VUX0lURU0obGlzdCwgaSk7CisgICAgICAgIGZvciAoaiA9IGkgKyAxOyBqIDwgbjsgaisrKSB7CisgICAgICAgICAgICBpZiAoUHlMaXN0X0dFVF9JVEVNKGxpc3QsIGopID09IG8pIHsKKyAgICAgICAgICAgICAgICBvID0gY2xhc3NfbmFtZShvKTsKKyAgICAgICAgICAgICAgICBQeUVycl9Gb3JtYXQoUHlFeGNfVHlwZUVycm9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiZHVwbGljYXRlIGJhc2UgY2xhc3MgJXMiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvID8gUHlTdHJpbmdfQVNfU1RSSU5HKG8pIDogIj8iKTsKKyAgICAgICAgICAgICAgICBQeV9YREVDUkVGKG8pOworICAgICAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKyAgICByZXR1cm4gMDsKK30KKworLyogUmFpc2UgYSBUeXBlRXJyb3IgZm9yIGFuIE1STyBvcmRlciBkaXNhZ3JlZW1lbnQuCisKKyAgIEl0J3MgaGFyZCB0byBwcm9kdWNlIGEgZ29vZCBlcnJvciBtZXNzYWdlLiAgSW4gdGhlIGFic2VuY2Ugb2YgYmV0dGVyCisgICBpbnNpZ2h0IGludG8gZXJyb3IgcmVwb3J0aW5nLCByZXBvcnQgdGhlIGNsYXNzZXMgdGhhdCB3ZXJlIGNhbmRpZGF0ZXMKKyAgIHRvIGJlIHB1dCBuZXh0IGludG8gdGhlIE1STy4gIFRoZXJlIGlzIHNvbWUgY29uZmxpY3QgYmV0d2VlbiB0aGUKKyAgIG9yZGVyIGluIHdoaWNoIHRoZXkgc2hvdWxkIGJlIHB1dCBpbiB0aGUgTVJPLCBidXQgaXQncyBoYXJkIHRvCisgICBkaWFnbm9zZSB3aGF0IGNvbnN0cmFpbnQgY2FuJ3QgYmUgc2F0aXNmaWVkLgorKi8KKworc3RhdGljIHZvaWQKK3NldF9tcm9fZXJyb3IoUHlPYmplY3QgKnRvX21lcmdlLCBpbnQgKnJlbWFpbikKK3sKKyAgICBQeV9zc2l6ZV90IGksIG4sIG9mZiwgdG9fbWVyZ2Vfc2l6ZTsKKyAgICBjaGFyIGJ1ZlsxMDAwXTsKKyAgICBQeU9iamVjdCAqaywgKnY7CisgICAgUHlPYmplY3QgKnNldCA9IFB5RGljdF9OZXcoKTsKKyAgICBpZiAoIXNldCkgcmV0dXJuOworCisgICAgdG9fbWVyZ2Vfc2l6ZSA9IFB5TGlzdF9HRVRfU0laRSh0b19tZXJnZSk7CisgICAgZm9yIChpID0gMDsgaSA8IHRvX21lcmdlX3NpemU7IGkrKykgeworICAgICAgICBQeU9iamVjdCAqTCA9IFB5TGlzdF9HRVRfSVRFTSh0b19tZXJnZSwgaSk7CisgICAgICAgIGlmIChyZW1haW5baV0gPCBQeUxpc3RfR0VUX1NJWkUoTCkpIHsKKyAgICAgICAgICAgIFB5T2JqZWN0ICpjID0gUHlMaXN0X0dFVF9JVEVNKEwsIHJlbWFpbltpXSk7CisgICAgICAgICAgICBpZiAoUHlEaWN0X1NldEl0ZW0oc2V0LCBjLCBQeV9Ob25lKSA8IDApIHsKKyAgICAgICAgICAgICAgICBQeV9ERUNSRUYoc2V0KTsKKyAgICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisgICAgbiA9IFB5RGljdF9TaXplKHNldCk7CisKKyAgICBvZmYgPSBQeU9TX3NucHJpbnRmKGJ1Ziwgc2l6ZW9mKGJ1ZiksICJDYW5ub3QgY3JlYXRlIGEgXAorY29uc2lzdGVudCBtZXRob2QgcmVzb2x1dGlvblxub3JkZXIgKE1STykgZm9yIGJhc2VzIik7CisgICAgaSA9IDA7CisgICAgd2hpbGUgKFB5RGljdF9OZXh0KHNldCwgJmksICZrLCAmdikgJiYgKHNpemVfdClvZmYgPCBzaXplb2YoYnVmKSkgeworICAgICAgICBQeU9iamVjdCAqbmFtZSA9IGNsYXNzX25hbWUoayk7CisgICAgICAgIG9mZiArPSBQeU9TX3NucHJpbnRmKGJ1ZiArIG9mZiwgc2l6ZW9mKGJ1ZikgLSBvZmYsICIgJXMiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lID8gUHlTdHJpbmdfQVNfU1RSSU5HKG5hbWUpIDogIj8iKTsKKyAgICAgICAgUHlfWERFQ1JFRihuYW1lKTsKKyAgICAgICAgaWYgKC0tbiAmJiAoc2l6ZV90KShvZmYrMSkgPCBzaXplb2YoYnVmKSkgeworICAgICAgICAgICAgYnVmW29mZisrXSA9ICcsJzsKKyAgICAgICAgICAgIGJ1ZltvZmZdID0gJ1wwJzsKKyAgICAgICAgfQorICAgIH0KKyAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfVHlwZUVycm9yLCBidWYpOworICAgIFB5X0RFQ1JFRihzZXQpOworfQorCitzdGF0aWMgaW50CitwbWVyZ2UoUHlPYmplY3QgKmFjYywgUHlPYmplY3QqIHRvX21lcmdlKSB7CisgICAgUHlfc3NpemVfdCBpLCBqLCB0b19tZXJnZV9zaXplLCBlbXB0eV9jbnQ7CisgICAgaW50ICpyZW1haW47CisgICAgaW50IG9rOworCisgICAgdG9fbWVyZ2Vfc2l6ZSA9IFB5TGlzdF9HRVRfU0laRSh0b19tZXJnZSk7CisKKyAgICAvKiByZW1haW4gc3RvcmVzIGFuIGluZGV4IGludG8gZWFjaCBzdWJsaXN0IG9mIHRvX21lcmdlLgorICAgICAgIHJlbWFpbltpXSBpcyB0aGUgaW5kZXggb2YgdGhlIG5leHQgYmFzZSBpbiB0b19tZXJnZVtpXQorICAgICAgIHRoYXQgaXMgbm90IGluY2x1ZGVkIGluIGFjYy4KKyAgICAqLworICAgIHJlbWFpbiA9IChpbnQgKilQeU1lbV9NQUxMT0MoU0laRU9GX0lOVCp0b19tZXJnZV9zaXplKTsKKyAgICBpZiAocmVtYWluID09IE5VTEwpCisgICAgICAgIHJldHVybiAtMTsKKyAgICBmb3IgKGkgPSAwOyBpIDwgdG9fbWVyZ2Vfc2l6ZTsgaSsrKQorICAgICAgICByZW1haW5baV0gPSAwOworCisgIGFnYWluOgorICAgIGVtcHR5X2NudCA9IDA7CisgICAgZm9yIChpID0gMDsgaSA8IHRvX21lcmdlX3NpemU7IGkrKykgeworICAgICAgICBQeU9iamVjdCAqY2FuZGlkYXRlOworCisgICAgICAgIFB5T2JqZWN0ICpjdXJfbGlzdCA9IFB5TGlzdF9HRVRfSVRFTSh0b19tZXJnZSwgaSk7CisKKyAgICAgICAgaWYgKHJlbWFpbltpXSA+PSBQeUxpc3RfR0VUX1NJWkUoY3VyX2xpc3QpKSB7CisgICAgICAgICAgICBlbXB0eV9jbnQrKzsKKyAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICB9CisKKyAgICAgICAgLyogQ2hvb3NlIG5leHQgY2FuZGlkYXRlIGZvciBNUk8uCisKKyAgICAgICAgICAgVGhlIGlucHV0IHNlcXVlbmNlcyBhbG9uZSBjYW4gZGV0ZXJtaW5lIHRoZSBjaG9pY2UuCisgICAgICAgICAgIElmIG5vdCwgY2hvb3NlIHRoZSBjbGFzcyB3aGljaCBhcHBlYXJzIGluIHRoZSBNUk8KKyAgICAgICAgICAgb2YgdGhlIGVhcmxpZXN0IGRpcmVjdCBzdXBlcmNsYXNzIG9mIHRoZSBuZXcgY2xhc3MuCisgICAgICAgICovCisKKyAgICAgICAgY2FuZGlkYXRlID0gUHlMaXN0X0dFVF9JVEVNKGN1cl9saXN0LCByZW1haW5baV0pOworICAgICAgICBmb3IgKGogPSAwOyBqIDwgdG9fbWVyZ2Vfc2l6ZTsgaisrKSB7CisgICAgICAgICAgICBQeU9iamVjdCAqal9sc3QgPSBQeUxpc3RfR0VUX0lURU0odG9fbWVyZ2UsIGopOworICAgICAgICAgICAgaWYgKHRhaWxfY29udGFpbnMoal9sc3QsIHJlbWFpbltqXSwgY2FuZGlkYXRlKSkgeworICAgICAgICAgICAgICAgIGdvdG8gc2tpcDsgLyogY29udGludWUgb3V0ZXIgbG9vcCAqLworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIG9rID0gUHlMaXN0X0FwcGVuZChhY2MsIGNhbmRpZGF0ZSk7CisgICAgICAgIGlmIChvayA8IDApIHsKKyAgICAgICAgICAgIFB5TWVtX0ZyZWUocmVtYWluKTsKKyAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgfQorICAgICAgICBmb3IgKGogPSAwOyBqIDwgdG9fbWVyZ2Vfc2l6ZTsgaisrKSB7CisgICAgICAgICAgICBQeU9iamVjdCAqal9sc3QgPSBQeUxpc3RfR0VUX0lURU0odG9fbWVyZ2UsIGopOworICAgICAgICAgICAgaWYgKHJlbWFpbltqXSA8IFB5TGlzdF9HRVRfU0laRShqX2xzdCkgJiYKKyAgICAgICAgICAgICAgICBQeUxpc3RfR0VUX0lURU0oal9sc3QsIHJlbWFpbltqXSkgPT0gY2FuZGlkYXRlKSB7CisgICAgICAgICAgICAgICAgcmVtYWluW2pdKys7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgZ290byBhZ2FpbjsKKyAgICAgIHNraXA6IDsKKyAgICB9CisKKyAgICBpZiAoZW1wdHlfY250ID09IHRvX21lcmdlX3NpemUpIHsKKyAgICAgICAgUHlNZW1fRlJFRShyZW1haW4pOworICAgICAgICByZXR1cm4gMDsKKyAgICB9CisgICAgc2V0X21yb19lcnJvcih0b19tZXJnZSwgcmVtYWluKTsKKyAgICBQeU1lbV9GUkVFKHJlbWFpbik7CisgICAgcmV0dXJuIC0xOworfQorCitzdGF0aWMgUHlPYmplY3QgKgorbXJvX2ltcGxlbWVudGF0aW9uKFB5VHlwZU9iamVjdCAqdHlwZSkKK3sKKyAgICBQeV9zc2l6ZV90IGksIG47CisgICAgaW50IG9rOworICAgIFB5T2JqZWN0ICpiYXNlcywgKnJlc3VsdDsKKyAgICBQeU9iamVjdCAqdG9fbWVyZ2UsICpiYXNlc19hc2xpc3Q7CisKKyAgICBpZiAodHlwZS0+dHBfZGljdCA9PSBOVUxMKSB7CisgICAgICAgIGlmIChQeVR5cGVfUmVhZHkodHlwZSkgPCAwKQorICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorCisgICAgLyogRmluZCBhIHN1cGVyY2xhc3MgbGluZWFyaXphdGlvbiB0aGF0IGhvbm9ycyB0aGUgY29uc3RyYWludHMKKyAgICAgICBvZiB0aGUgZXhwbGljaXQgbGlzdHMgb2YgYmFzZXMgYW5kIHRoZSBjb25zdHJhaW50cyBpbXBsaWVkIGJ5CisgICAgICAgZWFjaCBiYXNlIGNsYXNzLgorCisgICAgICAgdG9fbWVyZ2UgaXMgYSBsaXN0IG9mIGxpc3RzLCB3aGVyZSBlYWNoIGxpc3QgaXMgYSBzdXBlcmNsYXNzCisgICAgICAgbGluZWFyaXphdGlvbiBpbXBsaWVkIGJ5IGEgYmFzZSBjbGFzcy4gIFRoZSBsYXN0IGVsZW1lbnQgb2YKKyAgICAgICB0b19tZXJnZSBpcyB0aGUgZGVjbGFyZWQgbGlzdCBvZiBiYXNlcy4KKyAgICAqLworCisgICAgYmFzZXMgPSB0eXBlLT50cF9iYXNlczsKKyAgICBuID0gUHlUdXBsZV9HRVRfU0laRShiYXNlcyk7CisKKyAgICB0b19tZXJnZSA9IFB5TGlzdF9OZXcobisxKTsKKyAgICBpZiAodG9fbWVyZ2UgPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisKKyAgICBmb3IgKGkgPSAwOyBpIDwgbjsgaSsrKSB7CisgICAgICAgIFB5T2JqZWN0ICpiYXNlID0gUHlUdXBsZV9HRVRfSVRFTShiYXNlcywgaSk7CisgICAgICAgIFB5T2JqZWN0ICpwYXJlbnRNUk87CisgICAgICAgIGlmIChQeVR5cGVfQ2hlY2soYmFzZSkpCisgICAgICAgICAgICBwYXJlbnRNUk8gPSBQeVNlcXVlbmNlX0xpc3QoCisgICAgICAgICAgICAgICAgKChQeVR5cGVPYmplY3QqKWJhc2UpLT50cF9tcm8pOworICAgICAgICBlbHNlCisgICAgICAgICAgICBwYXJlbnRNUk8gPSBjbGFzc2ljX21ybyhiYXNlKTsKKyAgICAgICAgaWYgKHBhcmVudE1STyA9PSBOVUxMKSB7CisgICAgICAgICAgICBQeV9ERUNSRUYodG9fbWVyZ2UpOworICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgICAgIH0KKworICAgICAgICBQeUxpc3RfU0VUX0lURU0odG9fbWVyZ2UsIGksIHBhcmVudE1STyk7CisgICAgfQorCisgICAgYmFzZXNfYXNsaXN0ID0gUHlTZXF1ZW5jZV9MaXN0KGJhc2VzKTsKKyAgICBpZiAoYmFzZXNfYXNsaXN0ID09IE5VTEwpIHsKKyAgICAgICAgUHlfREVDUkVGKHRvX21lcmdlKTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIC8qIFRoaXMgaXMganVzdCBhIGJhc2ljIHNhbml0eSBjaGVjay4gKi8KKyAgICBpZiAoY2hlY2tfZHVwbGljYXRlcyhiYXNlc19hc2xpc3QpIDwgMCkgeworICAgICAgICBQeV9ERUNSRUYodG9fbWVyZ2UpOworICAgICAgICBQeV9ERUNSRUYoYmFzZXNfYXNsaXN0KTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIFB5TGlzdF9TRVRfSVRFTSh0b19tZXJnZSwgbiwgYmFzZXNfYXNsaXN0KTsKKworICAgIHJlc3VsdCA9IFB5X0J1aWxkVmFsdWUoIltPXSIsIChQeU9iamVjdCAqKXR5cGUpOworICAgIGlmIChyZXN1bHQgPT0gTlVMTCkgeworICAgICAgICBQeV9ERUNSRUYodG9fbWVyZ2UpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisKKyAgICBvayA9IHBtZXJnZShyZXN1bHQsIHRvX21lcmdlKTsKKyAgICBQeV9ERUNSRUYodG9fbWVyZ2UpOworICAgIGlmIChvayA8IDApIHsKKyAgICAgICAgUHlfREVDUkVGKHJlc3VsdCk7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKworICAgIHJldHVybiByZXN1bHQ7Cit9CisKK3N0YXRpYyBQeU9iamVjdCAqCittcm9fZXh0ZXJuYWwoUHlPYmplY3QgKnNlbGYpCit7CisgICAgUHlUeXBlT2JqZWN0ICp0eXBlID0gKFB5VHlwZU9iamVjdCAqKXNlbGY7CisKKyAgICByZXR1cm4gbXJvX2ltcGxlbWVudGF0aW9uKHR5cGUpOworfQorCitzdGF0aWMgaW50Cittcm9faW50ZXJuYWwoUHlUeXBlT2JqZWN0ICp0eXBlKQoreworICAgIFB5T2JqZWN0ICptcm8sICpyZXN1bHQsICp0dXBsZTsKKyAgICBpbnQgY2hlY2tpdCA9IDA7CisKKyAgICBpZiAoUHlfVFlQRSh0eXBlKSA9PSAmUHlUeXBlX1R5cGUpIHsKKyAgICAgICAgcmVzdWx0ID0gbXJvX2ltcGxlbWVudGF0aW9uKHR5cGUpOworICAgIH0KKyAgICBlbHNlIHsKKyAgICAgICAgc3RhdGljIFB5T2JqZWN0ICptcm9fc3RyOworICAgICAgICBjaGVja2l0ID0gMTsKKyAgICAgICAgbXJvID0gbG9va3VwX21ldGhvZCgoUHlPYmplY3QgKil0eXBlLCAibXJvIiwgJm1yb19zdHIpOworICAgICAgICBpZiAobXJvID09IE5VTEwpCisgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgIHJlc3VsdCA9IFB5T2JqZWN0X0NhbGxPYmplY3QobXJvLCBOVUxMKTsKKyAgICAgICAgUHlfREVDUkVGKG1ybyk7CisgICAgfQorICAgIGlmIChyZXN1bHQgPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIC0xOworICAgIHR1cGxlID0gUHlTZXF1ZW5jZV9UdXBsZShyZXN1bHQpOworICAgIFB5X0RFQ1JFRihyZXN1bHQpOworICAgIGlmICh0dXBsZSA9PSBOVUxMKQorICAgICAgICByZXR1cm4gLTE7CisgICAgaWYgKGNoZWNraXQpIHsKKyAgICAgICAgUHlfc3NpemVfdCBpLCBsZW47CisgICAgICAgIFB5T2JqZWN0ICpjbHM7CisgICAgICAgIFB5VHlwZU9iamVjdCAqc29saWQ7CisKKyAgICAgICAgc29saWQgPSBzb2xpZF9iYXNlKHR5cGUpOworCisgICAgICAgIGxlbiA9IFB5VHVwbGVfR0VUX1NJWkUodHVwbGUpOworCisgICAgICAgIGZvciAoaSA9IDA7IGkgPCBsZW47IGkrKykgeworICAgICAgICAgICAgUHlUeXBlT2JqZWN0ICp0OworICAgICAgICAgICAgY2xzID0gUHlUdXBsZV9HRVRfSVRFTSh0dXBsZSwgaSk7CisgICAgICAgICAgICBpZiAoUHlDbGFzc19DaGVjayhjbHMpKQorICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgZWxzZSBpZiAoIVB5VHlwZV9DaGVjayhjbHMpKSB7CisgICAgICAgICAgICAgICAgUHlFcnJfRm9ybWF0KFB5RXhjX1R5cGVFcnJvciwKKyAgICAgICAgICAgICAgICAgIm1ybygpIHJldHVybmVkIGEgbm9uLWNsYXNzICgnJS41MDBzJykiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHlfVFlQRShjbHMpLT50cF9uYW1lKTsKKyAgICAgICAgICAgICAgICBQeV9ERUNSRUYodHVwbGUpOworICAgICAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHQgPSAoUHlUeXBlT2JqZWN0KiljbHM7CisgICAgICAgICAgICBpZiAoIVB5VHlwZV9Jc1N1YnR5cGUoc29saWQsIHNvbGlkX2Jhc2UodCkpKSB7CisgICAgICAgICAgICAgICAgUHlFcnJfRm9ybWF0KFB5RXhjX1R5cGVFcnJvciwKKyAgICAgICAgICAgICAibXJvKCkgcmV0dXJuZWQgYmFzZSB3aXRoIHVuc3VpdGFibGUgbGF5b3V0ICgnJS41MDBzJykiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHQtPnRwX25hbWUpOworICAgICAgICAgICAgICAgICAgICAgICAgUHlfREVDUkVGKHR1cGxlKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKyAgICB0eXBlLT50cF9tcm8gPSB0dXBsZTsKKworICAgIHR5cGVfbXJvX21vZGlmaWVkKHR5cGUsIHR5cGUtPnRwX21ybyk7CisgICAgLyogY29ybmVyIGNhc2U6IHRoZSBvbGQtc3R5bGUgc3VwZXIgY2xhc3MgbWlnaHQgaGF2ZSBiZWVuIGhpZGRlbgorICAgICAgIGZyb20gdGhlIGN1c3RvbSBNUk8gKi8KKyAgICB0eXBlX21yb19tb2RpZmllZCh0eXBlLCB0eXBlLT50cF9iYXNlcyk7CisKKyAgICBQeVR5cGVfTW9kaWZpZWQodHlwZSk7CisKKyAgICByZXR1cm4gMDsKK30KKworCisvKiBDYWxjdWxhdGUgdGhlIGJlc3QgYmFzZSBhbW9uZ3N0IG11bHRpcGxlIGJhc2UgY2xhc3Nlcy4KKyAgIFRoaXMgaXMgdGhlIGZpcnN0IG9uZSB0aGF0J3Mgb24gdGhlIHBhdGggdG8gdGhlICJzb2xpZCBiYXNlIi4gKi8KKworc3RhdGljIFB5VHlwZU9iamVjdCAqCitiZXN0X2Jhc2UoUHlPYmplY3QgKmJhc2VzKQoreworICAgIFB5X3NzaXplX3QgaSwgbjsKKyAgICBQeVR5cGVPYmplY3QgKmJhc2UsICp3aW5uZXIsICpjYW5kaWRhdGUsICpiYXNlX2k7CisgICAgUHlPYmplY3QgKmJhc2VfcHJvdG87CisKKyAgICBhc3NlcnQoUHlUdXBsZV9DaGVjayhiYXNlcykpOworICAgIG4gPSBQeVR1cGxlX0dFVF9TSVpFKGJhc2VzKTsKKyAgICBhc3NlcnQobiA+IDApOworICAgIGJhc2UgPSBOVUxMOworICAgIHdpbm5lciA9IE5VTEw7CisgICAgZm9yIChpID0gMDsgaSA8IG47IGkrKykgeworICAgICAgICBiYXNlX3Byb3RvID0gUHlUdXBsZV9HRVRfSVRFTShiYXNlcywgaSk7CisgICAgICAgIGlmIChQeUNsYXNzX0NoZWNrKGJhc2VfcHJvdG8pKQorICAgICAgICAgICAgY29udGludWU7CisgICAgICAgIGlmICghUHlUeXBlX0NoZWNrKGJhc2VfcHJvdG8pKSB7CisgICAgICAgICAgICBQeUVycl9TZXRTdHJpbmcoCisgICAgICAgICAgICAgICAgUHlFeGNfVHlwZUVycm9yLAorICAgICAgICAgICAgICAgICJiYXNlcyBtdXN0IGJlIHR5cGVzIik7CisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgfQorICAgICAgICBiYXNlX2kgPSAoUHlUeXBlT2JqZWN0ICopYmFzZV9wcm90bzsKKyAgICAgICAgaWYgKGJhc2VfaS0+dHBfZGljdCA9PSBOVUxMKSB7CisgICAgICAgICAgICBpZiAoUHlUeXBlX1JlYWR5KGJhc2VfaSkgPCAwKQorICAgICAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgICAgICB9CisgICAgICAgIGNhbmRpZGF0ZSA9IHNvbGlkX2Jhc2UoYmFzZV9pKTsKKyAgICAgICAgaWYgKHdpbm5lciA9PSBOVUxMKSB7CisgICAgICAgICAgICB3aW5uZXIgPSBjYW5kaWRhdGU7CisgICAgICAgICAgICBiYXNlID0gYmFzZV9pOworICAgICAgICB9CisgICAgICAgIGVsc2UgaWYgKFB5VHlwZV9Jc1N1YnR5cGUod2lubmVyLCBjYW5kaWRhdGUpKQorICAgICAgICAgICAgOworICAgICAgICBlbHNlIGlmIChQeVR5cGVfSXNTdWJ0eXBlKGNhbmRpZGF0ZSwgd2lubmVyKSkgeworICAgICAgICAgICAgd2lubmVyID0gY2FuZGlkYXRlOworICAgICAgICAgICAgYmFzZSA9IGJhc2VfaTsKKyAgICAgICAgfQorICAgICAgICBlbHNlIHsKKyAgICAgICAgICAgIFB5RXJyX1NldFN0cmluZygKKyAgICAgICAgICAgICAgICBQeUV4Y19UeXBlRXJyb3IsCisgICAgICAgICAgICAgICAgIm11bHRpcGxlIGJhc2VzIGhhdmUgIgorICAgICAgICAgICAgICAgICJpbnN0YW5jZSBsYXktb3V0IGNvbmZsaWN0Iik7CisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgfQorICAgIH0KKyAgICBpZiAoYmFzZSA9PSBOVUxMKQorICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfVHlwZUVycm9yLAorICAgICAgICAgICAgImEgbmV3LXN0eWxlIGNsYXNzIGNhbid0IGhhdmUgb25seSBjbGFzc2ljIGJhc2VzIik7CisgICAgcmV0dXJuIGJhc2U7Cit9CisKK3N0YXRpYyBpbnQKK2V4dHJhX2l2YXJzKFB5VHlwZU9iamVjdCAqdHlwZSwgUHlUeXBlT2JqZWN0ICpiYXNlKQoreworICAgIHNpemVfdCB0X3NpemUgPSB0eXBlLT50cF9iYXNpY3NpemU7CisgICAgc2l6ZV90IGJfc2l6ZSA9IGJhc2UtPnRwX2Jhc2ljc2l6ZTsKKworICAgIGFzc2VydCh0X3NpemUgPj0gYl9zaXplKTsgLyogRWxzZSB0eXBlIHNtYWxsZXIgdGhhbiBiYXNlISAqLworICAgIGlmICh0eXBlLT50cF9pdGVtc2l6ZSB8fCBiYXNlLT50cF9pdGVtc2l6ZSkgeworICAgICAgICAvKiBJZiBpdGVtc2l6ZSBpcyBpbnZvbHZlZCwgc3RyaWN0ZXIgcnVsZXMgKi8KKyAgICAgICAgcmV0dXJuIHRfc2l6ZSAhPSBiX3NpemUgfHwKKyAgICAgICAgICAgIHR5cGUtPnRwX2l0ZW1zaXplICE9IGJhc2UtPnRwX2l0ZW1zaXplOworICAgIH0KKyAgICBpZiAodHlwZS0+dHBfd2Vha2xpc3RvZmZzZXQgJiYgYmFzZS0+dHBfd2Vha2xpc3RvZmZzZXQgPT0gMCAmJgorICAgICAgICB0eXBlLT50cF93ZWFrbGlzdG9mZnNldCArIHNpemVvZihQeU9iamVjdCAqKSA9PSB0X3NpemUgJiYKKyAgICAgICAgdHlwZS0+dHBfZmxhZ3MgJiBQeV9UUEZMQUdTX0hFQVBUWVBFKQorICAgICAgICB0X3NpemUgLT0gc2l6ZW9mKFB5T2JqZWN0ICopOworICAgIGlmICh0eXBlLT50cF9kaWN0b2Zmc2V0ICYmIGJhc2UtPnRwX2RpY3RvZmZzZXQgPT0gMCAmJgorICAgICAgICB0eXBlLT50cF9kaWN0b2Zmc2V0ICsgc2l6ZW9mKFB5T2JqZWN0ICopID09IHRfc2l6ZSAmJgorICAgICAgICB0eXBlLT50cF9mbGFncyAmIFB5X1RQRkxBR1NfSEVBUFRZUEUpCisgICAgICAgIHRfc2l6ZSAtPSBzaXplb2YoUHlPYmplY3QgKik7CisKKyAgICByZXR1cm4gdF9zaXplICE9IGJfc2l6ZTsKK30KKworc3RhdGljIFB5VHlwZU9iamVjdCAqCitzb2xpZF9iYXNlKFB5VHlwZU9iamVjdCAqdHlwZSkKK3sKKyAgICBQeVR5cGVPYmplY3QgKmJhc2U7CisKKyAgICBpZiAodHlwZS0+dHBfYmFzZSkKKyAgICAgICAgYmFzZSA9IHNvbGlkX2Jhc2UodHlwZS0+dHBfYmFzZSk7CisgICAgZWxzZQorICAgICAgICBiYXNlID0gJlB5QmFzZU9iamVjdF9UeXBlOworICAgIGlmIChleHRyYV9pdmFycyh0eXBlLCBiYXNlKSkKKyAgICAgICAgcmV0dXJuIHR5cGU7CisgICAgZWxzZQorICAgICAgICByZXR1cm4gYmFzZTsKK30KKworc3RhdGljIHZvaWQgb2JqZWN0X2RlYWxsb2MoUHlPYmplY3QgKik7CitzdGF0aWMgaW50IG9iamVjdF9pbml0KFB5T2JqZWN0ICosIFB5T2JqZWN0ICosIFB5T2JqZWN0ICopOworc3RhdGljIGludCB1cGRhdGVfc2xvdChQeVR5cGVPYmplY3QgKiwgUHlPYmplY3QgKik7CitzdGF0aWMgdm9pZCBmaXh1cF9zbG90X2Rpc3BhdGNoZXJzKFB5VHlwZU9iamVjdCAqKTsKKworLyoKKyAqIEhlbHBlcnMgZm9yICBfX2RpY3RfXyBkZXNjcmlwdG9yLiAgV2UgZG9uJ3Qgd2FudCB0byBleHBvc2UgdGhlIGRpY3RzCisgKiBpbmhlcml0ZWQgZnJvbSB2YXJpb3VzIGJ1aWx0aW4gdHlwZXMuICBUaGUgYnVpbHRpbiBiYXNlIHVzdWFsbHkgcHJvdmlkZXMKKyAqIGl0cyBvd24gX19kaWN0X18gZGVzY3JpcHRvciwgc28gd2UgdXNlIHRoYXQgd2hlbiB3ZSBjYW4uCisgKi8KK3N0YXRpYyBQeVR5cGVPYmplY3QgKgorZ2V0X2J1aWx0aW5fYmFzZV93aXRoX2RpY3QoUHlUeXBlT2JqZWN0ICp0eXBlKQoreworICAgIHdoaWxlICh0eXBlLT50cF9iYXNlICE9IE5VTEwpIHsKKyAgICAgICAgaWYgKHR5cGUtPnRwX2RpY3RvZmZzZXQgIT0gMCAmJgorICAgICAgICAgICAgISh0eXBlLT50cF9mbGFncyAmIFB5X1RQRkxBR1NfSEVBUFRZUEUpKQorICAgICAgICAgICAgcmV0dXJuIHR5cGU7CisgICAgICAgIHR5cGUgPSB0eXBlLT50cF9iYXNlOworICAgIH0KKyAgICByZXR1cm4gTlVMTDsKK30KKworc3RhdGljIFB5T2JqZWN0ICoKK2dldF9kaWN0X2Rlc2NyaXB0b3IoUHlUeXBlT2JqZWN0ICp0eXBlKQoreworICAgIHN0YXRpYyBQeU9iamVjdCAqZGljdF9zdHI7CisgICAgUHlPYmplY3QgKmRlc2NyOworCisgICAgaWYgKGRpY3Rfc3RyID09IE5VTEwpIHsKKyAgICAgICAgZGljdF9zdHIgPSBQeVN0cmluZ19JbnRlcm5Gcm9tU3RyaW5nKCJfX2RpY3RfXyIpOworICAgICAgICBpZiAoZGljdF9zdHIgPT0gTlVMTCkKKyAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICBkZXNjciA9IF9QeVR5cGVfTG9va3VwKHR5cGUsIGRpY3Rfc3RyKTsKKyAgICBpZiAoZGVzY3IgPT0gTlVMTCB8fCAhUHlEZXNjcl9Jc0RhdGEoZGVzY3IpKQorICAgICAgICByZXR1cm4gTlVMTDsKKworICAgIHJldHVybiBkZXNjcjsKK30KKworc3RhdGljIHZvaWQKK3JhaXNlX2RpY3RfZGVzY3JfZXJyb3IoUHlPYmplY3QgKm9iaikKK3sKKyAgICBQeUVycl9Gb3JtYXQoUHlFeGNfVHlwZUVycm9yLAorICAgICAgICAgICAgICAgICAidGhpcyBfX2RpY3RfXyBkZXNjcmlwdG9yIGRvZXMgbm90IHN1cHBvcnQgIgorICAgICAgICAgICAgICAgICAiJyUuMjAwcycgb2JqZWN0cyIsIG9iai0+b2JfdHlwZS0+dHBfbmFtZSk7Cit9CisKK3N0YXRpYyBQeU9iamVjdCAqCitzdWJ0eXBlX2RpY3QoUHlPYmplY3QgKm9iaiwgdm9pZCAqY29udGV4dCkKK3sKKyAgICBQeU9iamVjdCAqKmRpY3RwdHI7CisgICAgUHlPYmplY3QgKmRpY3Q7CisgICAgUHlUeXBlT2JqZWN0ICpiYXNlOworCisgICAgYmFzZSA9IGdldF9idWlsdGluX2Jhc2Vfd2l0aF9kaWN0KG9iai0+b2JfdHlwZSk7CisgICAgaWYgKGJhc2UgIT0gTlVMTCkgeworICAgICAgICBkZXNjcmdldGZ1bmMgZnVuYzsKKyAgICAgICAgUHlPYmplY3QgKmRlc2NyID0gZ2V0X2RpY3RfZGVzY3JpcHRvcihiYXNlKTsKKyAgICAgICAgaWYgKGRlc2NyID09IE5VTEwpIHsKKyAgICAgICAgICAgIHJhaXNlX2RpY3RfZGVzY3JfZXJyb3Iob2JqKTsKKyAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgICAgICB9CisgICAgICAgIGZ1bmMgPSBkZXNjci0+b2JfdHlwZS0+dHBfZGVzY3JfZ2V0OworICAgICAgICBpZiAoZnVuYyA9PSBOVUxMKSB7CisgICAgICAgICAgICByYWlzZV9kaWN0X2Rlc2NyX2Vycm9yKG9iaik7CisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZnVuYyhkZXNjciwgb2JqLCAoUHlPYmplY3QgKikob2JqLT5vYl90eXBlKSk7CisgICAgfQorCisgICAgZGljdHB0ciA9IF9QeU9iamVjdF9HZXREaWN0UHRyKG9iaik7CisgICAgaWYgKGRpY3RwdHIgPT0gTlVMTCkgeworICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfQXR0cmlidXRlRXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAgICAiVGhpcyBvYmplY3QgaGFzIG5vIF9fZGljdF9fIik7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICBkaWN0ID0gKmRpY3RwdHI7CisgICAgaWYgKGRpY3QgPT0gTlVMTCkKKyAgICAgICAgKmRpY3RwdHIgPSBkaWN0ID0gUHlEaWN0X05ldygpOworICAgIFB5X1hJTkNSRUYoZGljdCk7CisgICAgcmV0dXJuIGRpY3Q7Cit9CisKK3N0YXRpYyBpbnQKK3N1YnR5cGVfc2V0ZGljdChQeU9iamVjdCAqb2JqLCBQeU9iamVjdCAqdmFsdWUsIHZvaWQgKmNvbnRleHQpCit7CisgICAgUHlPYmplY3QgKipkaWN0cHRyOworICAgIFB5T2JqZWN0ICpkaWN0OworICAgIFB5VHlwZU9iamVjdCAqYmFzZTsKKworICAgIGJhc2UgPSBnZXRfYnVpbHRpbl9iYXNlX3dpdGhfZGljdChvYmotPm9iX3R5cGUpOworICAgIGlmIChiYXNlICE9IE5VTEwpIHsKKyAgICAgICAgZGVzY3JzZXRmdW5jIGZ1bmM7CisgICAgICAgIFB5T2JqZWN0ICpkZXNjciA9IGdldF9kaWN0X2Rlc2NyaXB0b3IoYmFzZSk7CisgICAgICAgIGlmIChkZXNjciA9PSBOVUxMKSB7CisgICAgICAgICAgICByYWlzZV9kaWN0X2Rlc2NyX2Vycm9yKG9iaik7CisgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgIH0KKyAgICAgICAgZnVuYyA9IGRlc2NyLT5vYl90eXBlLT50cF9kZXNjcl9zZXQ7CisgICAgICAgIGlmIChmdW5jID09IE5VTEwpIHsKKyAgICAgICAgICAgIHJhaXNlX2RpY3RfZGVzY3JfZXJyb3Iob2JqKTsKKyAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgfQorICAgICAgICByZXR1cm4gZnVuYyhkZXNjciwgb2JqLCB2YWx1ZSk7CisgICAgfQorCisgICAgZGljdHB0ciA9IF9QeU9iamVjdF9HZXREaWN0UHRyKG9iaik7CisgICAgaWYgKGRpY3RwdHIgPT0gTlVMTCkgeworICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfQXR0cmlidXRlRXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAgICAiVGhpcyBvYmplY3QgaGFzIG5vIF9fZGljdF9fIik7CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisgICAgaWYgKHZhbHVlICE9IE5VTEwgJiYgIVB5RGljdF9DaGVjayh2YWx1ZSkpIHsKKyAgICAgICAgUHlFcnJfRm9ybWF0KFB5RXhjX1R5cGVFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICJfX2RpY3RfXyBtdXN0IGJlIHNldCB0byBhIGRpY3Rpb25hcnksICIKKyAgICAgICAgICAgICAgICAgICAgICJub3QgYSAnJS4yMDBzJyIsIFB5X1RZUEUodmFsdWUpLT50cF9uYW1lKTsKKyAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKyAgICBkaWN0ID0gKmRpY3RwdHI7CisgICAgUHlfWElOQ1JFRih2YWx1ZSk7CisgICAgKmRpY3RwdHIgPSB2YWx1ZTsKKyAgICBQeV9YREVDUkVGKGRpY3QpOworICAgIHJldHVybiAwOworfQorCitzdGF0aWMgUHlPYmplY3QgKgorc3VidHlwZV9nZXR3ZWFrcmVmKFB5T2JqZWN0ICpvYmosIHZvaWQgKmNvbnRleHQpCit7CisgICAgUHlPYmplY3QgKip3ZWFrbGlzdHB0cjsKKyAgICBQeU9iamVjdCAqcmVzdWx0OworCisgICAgaWYgKFB5X1RZUEUob2JqKS0+dHBfd2Vha2xpc3RvZmZzZXQgPT0gMCkgeworICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfQXR0cmlidXRlRXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAgICAiVGhpcyBvYmplY3QgaGFzIG5vIF9fd2Vha3JlZl9fIik7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICBhc3NlcnQoUHlfVFlQRShvYmopLT50cF93ZWFrbGlzdG9mZnNldCA+IDApOworICAgIGFzc2VydChQeV9UWVBFKG9iaiktPnRwX3dlYWtsaXN0b2Zmc2V0ICsgc2l6ZW9mKFB5T2JqZWN0ICopIDw9CisgICAgICAgICAgIChzaXplX3QpKFB5X1RZUEUob2JqKS0+dHBfYmFzaWNzaXplKSk7CisgICAgd2Vha2xpc3RwdHIgPSAoUHlPYmplY3QgKiopCisgICAgICAgICgoY2hhciAqKW9iaiArIFB5X1RZUEUob2JqKS0+dHBfd2Vha2xpc3RvZmZzZXQpOworICAgIGlmICgqd2Vha2xpc3RwdHIgPT0gTlVMTCkKKyAgICAgICAgcmVzdWx0ID0gUHlfTm9uZTsKKyAgICBlbHNlCisgICAgICAgIHJlc3VsdCA9ICp3ZWFrbGlzdHB0cjsKKyAgICBQeV9JTkNSRUYocmVzdWx0KTsKKyAgICByZXR1cm4gcmVzdWx0OworfQorCisvKiBUaHJlZSB2YXJpYW50cyBvbiB0aGUgc3VidHlwZV9nZXRzZXRzIGxpc3QuICovCisKK3N0YXRpYyBQeUdldFNldERlZiBzdWJ0eXBlX2dldHNldHNfZnVsbFtdID0geworICAgIHsiX19kaWN0X18iLCBzdWJ0eXBlX2RpY3QsIHN1YnR5cGVfc2V0ZGljdCwKKyAgICAgUHlEb2NfU1RSKCJkaWN0aW9uYXJ5IGZvciBpbnN0YW5jZSB2YXJpYWJsZXMgKGlmIGRlZmluZWQpIil9LAorICAgIHsiX193ZWFrcmVmX18iLCBzdWJ0eXBlX2dldHdlYWtyZWYsIE5VTEwsCisgICAgIFB5RG9jX1NUUigibGlzdCBvZiB3ZWFrIHJlZmVyZW5jZXMgdG8gdGhlIG9iamVjdCAoaWYgZGVmaW5lZCkiKX0sCisgICAgezB9Cit9OworCitzdGF0aWMgUHlHZXRTZXREZWYgc3VidHlwZV9nZXRzZXRzX2RpY3Rfb25seVtdID0geworICAgIHsiX19kaWN0X18iLCBzdWJ0eXBlX2RpY3QsIHN1YnR5cGVfc2V0ZGljdCwKKyAgICAgUHlEb2NfU1RSKCJkaWN0aW9uYXJ5IGZvciBpbnN0YW5jZSB2YXJpYWJsZXMgKGlmIGRlZmluZWQpIil9LAorICAgIHswfQorfTsKKworc3RhdGljIFB5R2V0U2V0RGVmIHN1YnR5cGVfZ2V0c2V0c193ZWFrcmVmX29ubHlbXSA9IHsKKyAgICB7Il9fd2Vha3JlZl9fIiwgc3VidHlwZV9nZXR3ZWFrcmVmLCBOVUxMLAorICAgICBQeURvY19TVFIoImxpc3Qgb2Ygd2VhayByZWZlcmVuY2VzIHRvIHRoZSBvYmplY3QgKGlmIGRlZmluZWQpIil9LAorICAgIHswfQorfTsKKworc3RhdGljIGludAordmFsaWRfaWRlbnRpZmllcihQeU9iamVjdCAqcykKK3sKKyAgICB1bnNpZ25lZCBjaGFyICpwOworICAgIFB5X3NzaXplX3QgaSwgbjsKKworICAgIGlmICghUHlTdHJpbmdfQ2hlY2socykpIHsKKyAgICAgICAgUHlFcnJfRm9ybWF0KFB5RXhjX1R5cGVFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICJfX3Nsb3RzX18gaXRlbXMgbXVzdCBiZSBzdHJpbmdzLCBub3QgJyUuMjAwcyciLAorICAgICAgICAgICAgICAgICAgICAgUHlfVFlQRShzKS0+dHBfbmFtZSk7CisgICAgICAgIHJldHVybiAwOworICAgIH0KKyAgICBwID0gKHVuc2lnbmVkIGNoYXIgKikgUHlTdHJpbmdfQVNfU1RSSU5HKHMpOworICAgIG4gPSBQeVN0cmluZ19HRVRfU0laRShzKTsKKyAgICAvKiBXZSBtdXN0IHJlamVjdCBhbiBlbXB0eSBuYW1lLiAgQXMgYSBoYWNrLCB3ZSBidW1wIHRoZQorICAgICAgIGxlbmd0aCB0byAxIHNvIHRoYXQgdGhlIGxvb3Agd2lsbCBiYWxrIG9uIHRoZSB0cmFpbGluZyBcMC4gKi8KKyAgICBpZiAobiA9PSAwKQorICAgICAgICBuID0gMTsKKyAgICBmb3IgKGkgPSAwOyBpIDwgbjsgaSsrLCBwKyspIHsKKyAgICAgICAgaWYgKCEoaSA9PSAwID8gaXNhbHBoYSgqcCkgOiBpc2FsbnVtKCpwKSkgJiYgKnAgIT0gJ18nKSB7CisgICAgICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfVHlwZUVycm9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICJfX3Nsb3RzX18gbXVzdCBiZSBpZGVudGlmaWVycyIpOworICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgIH0KKyAgICB9CisgICAgcmV0dXJuIDE7Cit9CisKKyNpZmRlZiBQeV9VU0lOR19VTklDT0RFCisvKiBSZXBsYWNlIFVuaWNvZGUgb2JqZWN0cyBpbiBzbG90cy4gICovCisKK3N0YXRpYyBQeU9iamVjdCAqCitfdW5pY29kZV90b19zdHJpbmcoUHlPYmplY3QgKnNsb3RzLCBQeV9zc2l6ZV90IG5zbG90cykKK3sKKyAgICBQeU9iamVjdCAqdG1wID0gTlVMTDsKKyAgICBQeU9iamVjdCAqc2xvdF9uYW1lLCAqbmV3X25hbWU7CisgICAgUHlfc3NpemVfdCBpOworCisgICAgZm9yIChpID0gMDsgaSA8IG5zbG90czsgaSsrKSB7CisgICAgICAgIGlmIChQeVVuaWNvZGVfQ2hlY2soc2xvdF9uYW1lID0gUHlUdXBsZV9HRVRfSVRFTShzbG90cywgaSkpKSB7CisgICAgICAgICAgICBpZiAodG1wID09IE5VTEwpIHsKKyAgICAgICAgICAgICAgICB0bXAgPSBQeVNlcXVlbmNlX0xpc3Qoc2xvdHMpOworICAgICAgICAgICAgICAgIGlmICh0bXAgPT0gTlVMTCkKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBuZXdfbmFtZSA9IF9QeVVuaWNvZGVfQXNEZWZhdWx0RW5jb2RlZFN0cmluZyhzbG90X25hbWUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOVUxMKTsKKyAgICAgICAgICAgIGlmIChuZXdfbmFtZSA9PSBOVUxMKSB7CisgICAgICAgICAgICAgICAgUHlfREVDUkVGKHRtcCk7CisgICAgICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBQeV9JTkNSRUYobmV3X25hbWUpOworICAgICAgICAgICAgUHlMaXN0X1NFVF9JVEVNKHRtcCwgaSwgbmV3X25hbWUpOworICAgICAgICAgICAgUHlfREVDUkVGKHNsb3RfbmFtZSk7CisgICAgICAgIH0KKyAgICB9CisgICAgaWYgKHRtcCAhPSBOVUxMKSB7CisgICAgICAgIHNsb3RzID0gUHlMaXN0X0FzVHVwbGUodG1wKTsKKyAgICAgICAgUHlfREVDUkVGKHRtcCk7CisgICAgfQorICAgIHJldHVybiBzbG90czsKK30KKyNlbmRpZgorCisvKiBGb3J3YXJkICovCitzdGF0aWMgaW50CitvYmplY3RfaW5pdChQeU9iamVjdCAqc2VsZiwgUHlPYmplY3QgKmFyZ3MsIFB5T2JqZWN0ICprd2RzKTsKKworc3RhdGljIGludAordHlwZV9pbml0KFB5T2JqZWN0ICpjbHMsIFB5T2JqZWN0ICphcmdzLCBQeU9iamVjdCAqa3dkcykKK3sKKyAgICBpbnQgcmVzOworCisgICAgYXNzZXJ0KGFyZ3MgIT0gTlVMTCAmJiBQeVR1cGxlX0NoZWNrKGFyZ3MpKTsKKyAgICBhc3NlcnQoa3dkcyA9PSBOVUxMIHx8IFB5RGljdF9DaGVjayhrd2RzKSk7CisKKyAgICBpZiAoa3dkcyAhPSBOVUxMICYmIFB5RGljdF9DaGVjayhrd2RzKSAmJiBQeURpY3RfU2l6ZShrd2RzKSAhPSAwKSB7CisgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19UeXBlRXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAgICAidHlwZS5fX2luaXRfXygpIHRha2VzIG5vIGtleXdvcmQgYXJndW1lbnRzIik7CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisKKyAgICBpZiAoYXJncyAhPSBOVUxMICYmIFB5VHVwbGVfQ2hlY2soYXJncykgJiYKKyAgICAgICAgKFB5VHVwbGVfR0VUX1NJWkUoYXJncykgIT0gMSAmJiBQeVR1cGxlX0dFVF9TSVpFKGFyZ3MpICE9IDMpKSB7CisgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19UeXBlRXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAgICAidHlwZS5fX2luaXRfXygpIHRha2VzIDEgb3IgMyBhcmd1bWVudHMiKTsKKyAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKworICAgIC8qIENhbGwgb2JqZWN0Ll9faW5pdF9fKHNlbGYpIG5vdy4gKi8KKyAgICAvKiBYWFggQ291bGQgY2FsbCBzdXBlcih0eXBlLCBjbHMpLl9faW5pdF9fKCkgYnV0IHdoYXQncyB0aGUgcG9pbnQ/ICovCisgICAgYXJncyA9IFB5VHVwbGVfR2V0U2xpY2UoYXJncywgMCwgMCk7CisgICAgcmVzID0gb2JqZWN0X2luaXQoY2xzLCBhcmdzLCBOVUxMKTsKKyAgICBQeV9ERUNSRUYoYXJncyk7CisgICAgcmV0dXJuIHJlczsKK30KKworc3RhdGljIFB5T2JqZWN0ICoKK3R5cGVfbmV3KFB5VHlwZU9iamVjdCAqbWV0YXR5cGUsIFB5T2JqZWN0ICphcmdzLCBQeU9iamVjdCAqa3dkcykKK3sKKyAgICBQeU9iamVjdCAqbmFtZSwgKmJhc2VzLCAqZGljdDsKKyAgICBzdGF0aWMgY2hhciAqa3dsaXN0W10gPSB7Im5hbWUiLCAiYmFzZXMiLCAiZGljdCIsIDB9OworICAgIFB5T2JqZWN0ICpzbG90cywgKnRtcCwgKm5ld3Nsb3RzOworICAgIFB5VHlwZU9iamVjdCAqdHlwZSwgKmJhc2UsICp0bXB0eXBlLCAqd2lubmVyOworICAgIFB5SGVhcFR5cGVPYmplY3QgKmV0OworICAgIFB5TWVtYmVyRGVmICptcDsKKyAgICBQeV9zc2l6ZV90IGksIG5iYXNlcywgbnNsb3RzLCBzbG90b2Zmc2V0LCBhZGRfZGljdCwgYWRkX3dlYWs7CisgICAgaW50IGosIG1heV9hZGRfZGljdCwgbWF5X2FkZF93ZWFrOworCisgICAgYXNzZXJ0KGFyZ3MgIT0gTlVMTCAmJiBQeVR1cGxlX0NoZWNrKGFyZ3MpKTsKKyAgICBhc3NlcnQoa3dkcyA9PSBOVUxMIHx8IFB5RGljdF9DaGVjayhrd2RzKSk7CisKKyAgICAvKiBTcGVjaWFsIGNhc2U6IHR5cGUoeCkgc2hvdWxkIHJldHVybiB4LT5vYl90eXBlICovCisgICAgeworICAgICAgICBjb25zdCBQeV9zc2l6ZV90IG5hcmdzID0gUHlUdXBsZV9HRVRfU0laRShhcmdzKTsKKyAgICAgICAgY29uc3QgUHlfc3NpemVfdCBua3dkcyA9IGt3ZHMgPT0gTlVMTCA/IDAgOiBQeURpY3RfU2l6ZShrd2RzKTsKKworICAgICAgICBpZiAoUHlUeXBlX0NoZWNrRXhhY3QobWV0YXR5cGUpICYmIG5hcmdzID09IDEgJiYgbmt3ZHMgPT0gMCkgeworICAgICAgICAgICAgUHlPYmplY3QgKnggPSBQeVR1cGxlX0dFVF9JVEVNKGFyZ3MsIDApOworICAgICAgICAgICAgUHlfSU5DUkVGKFB5X1RZUEUoeCkpOworICAgICAgICAgICAgcmV0dXJuIChQeU9iamVjdCAqKSBQeV9UWVBFKHgpOworICAgICAgICB9CisKKyAgICAgICAgLyogU0YgYnVnIDQ3NTMyNyAtLSBpZiB0aGF0IGRpZG4ndCB0cmlnZ2VyLCB3ZSBuZWVkIDMKKyAgICAgICAgICAgYXJndW1lbnRzLiBidXQgUHlBcmdfUGFyc2VUdXBsZUFuZEtleXdvcmRzIGJlbG93IG1heSBnaXZlCisgICAgICAgICAgIGEgbXNnIHNheWluZyB0eXBlKCkgbmVlZHMgZXhhY3RseSAzLiAqLworICAgICAgICBpZiAobmFyZ3MgKyBua3dkcyAhPSAzKSB7CisgICAgICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfVHlwZUVycm9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ0eXBlKCkgdGFrZXMgMSBvciAzIGFyZ3VtZW50cyIpOworICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKiBDaGVjayBhcmd1bWVudHM6IChuYW1lLCBiYXNlcywgZGljdCkgKi8KKyAgICBpZiAoIVB5QXJnX1BhcnNlVHVwbGVBbmRLZXl3b3JkcyhhcmdzLCBrd2RzLCAiU08hTyE6dHlwZSIsIGt3bGlzdCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmbmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmUHlUdXBsZV9UeXBlLCAmYmFzZXMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJlB5RGljdF9UeXBlLCAmZGljdCkpCisgICAgICAgIHJldHVybiBOVUxMOworCisgICAgLyogRGV0ZXJtaW5lIHRoZSBwcm9wZXIgbWV0YXR5cGUgdG8gZGVhbCB3aXRoIHRoaXMsCisgICAgICAgYW5kIGNoZWNrIGZvciBtZXRhdHlwZSBjb25mbGljdHMgd2hpbGUgd2UncmUgYXQgaXQuCisgICAgICAgTm90ZSB0aGF0IGlmIHNvbWUgb3RoZXIgbWV0YXR5cGUgd2lucyB0byBjb250cmFjdCwKKyAgICAgICBpdCdzIHBvc3NpYmxlIHRoYXQgaXRzIGluc3RhbmNlcyBhcmUgbm90IHR5cGVzLiAqLworICAgIG5iYXNlcyA9IFB5VHVwbGVfR0VUX1NJWkUoYmFzZXMpOworICAgIHdpbm5lciA9IG1ldGF0eXBlOworICAgIGZvciAoaSA9IDA7IGkgPCBuYmFzZXM7IGkrKykgeworICAgICAgICB0bXAgPSBQeVR1cGxlX0dFVF9JVEVNKGJhc2VzLCBpKTsKKyAgICAgICAgdG1wdHlwZSA9IHRtcC0+b2JfdHlwZTsKKyAgICAgICAgaWYgKHRtcHR5cGUgPT0gJlB5Q2xhc3NfVHlwZSkKKyAgICAgICAgICAgIGNvbnRpbnVlOyAvKiBTcGVjaWFsIGNhc2UgY2xhc3NpYyBjbGFzc2VzICovCisgICAgICAgIGlmIChQeVR5cGVfSXNTdWJ0eXBlKHdpbm5lciwgdG1wdHlwZSkpCisgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgaWYgKFB5VHlwZV9Jc1N1YnR5cGUodG1wdHlwZSwgd2lubmVyKSkgeworICAgICAgICAgICAgd2lubmVyID0gdG1wdHlwZTsKKyAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICB9CisgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19UeXBlRXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAgICAibWV0YWNsYXNzIGNvbmZsaWN0OiAiCisgICAgICAgICAgICAgICAgICAgICAgICAidGhlIG1ldGFjbGFzcyBvZiBhIGRlcml2ZWQgY2xhc3MgIgorICAgICAgICAgICAgICAgICAgICAgICAgIm11c3QgYmUgYSAobm9uLXN0cmljdCkgc3ViY2xhc3MgIgorICAgICAgICAgICAgICAgICAgICAgICAgIm9mIHRoZSBtZXRhY2xhc3NlcyBvZiBhbGwgaXRzIGJhc2VzIik7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICBpZiAod2lubmVyICE9IG1ldGF0eXBlKSB7CisgICAgICAgIGlmICh3aW5uZXItPnRwX25ldyAhPSB0eXBlX25ldykgLyogUGFzcyBpdCB0byB0aGUgd2lubmVyICovCisgICAgICAgICAgICByZXR1cm4gd2lubmVyLT50cF9uZXcod2lubmVyLCBhcmdzLCBrd2RzKTsKKyAgICAgICAgbWV0YXR5cGUgPSB3aW5uZXI7CisgICAgfQorCisgICAgLyogQWRqdXN0IGZvciBlbXB0eSB0dXBsZSBiYXNlcyAqLworICAgIGlmIChuYmFzZXMgPT0gMCkgeworICAgICAgICBiYXNlcyA9IFB5VHVwbGVfUGFjaygxLCAmUHlCYXNlT2JqZWN0X1R5cGUpOworICAgICAgICBpZiAoYmFzZXMgPT0gTlVMTCkKKyAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgICAgICBuYmFzZXMgPSAxOworICAgIH0KKyAgICBlbHNlCisgICAgICAgIFB5X0lOQ1JFRihiYXNlcyk7CisKKyAgICAvKiBYWFggRnJvbSBoZXJlIHVudGlsIHR5cGUgaXMgYWxsb2NhdGVkLCAicmV0dXJuIE5VTEwiIGxlYWtzIGJhc2VzISAqLworCisgICAgLyogQ2FsY3VsYXRlIGJlc3QgYmFzZSwgYW5kIGNoZWNrIHRoYXQgYWxsIGJhc2VzIGFyZSB0eXBlIG9iamVjdHMgKi8KKyAgICBiYXNlID0gYmVzdF9iYXNlKGJhc2VzKTsKKyAgICBpZiAoYmFzZSA9PSBOVUxMKSB7CisgICAgICAgIFB5X0RFQ1JFRihiYXNlcyk7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICBpZiAoIVB5VHlwZV9IYXNGZWF0dXJlKGJhc2UsIFB5X1RQRkxBR1NfQkFTRVRZUEUpKSB7CisgICAgICAgIFB5RXJyX0Zvcm1hdChQeUV4Y19UeXBlRXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAidHlwZSAnJS4xMDBzJyBpcyBub3QgYW4gYWNjZXB0YWJsZSBiYXNlIHR5cGUiLAorICAgICAgICAgICAgICAgICAgICAgYmFzZS0+dHBfbmFtZSk7CisgICAgICAgIFB5X0RFQ1JFRihiYXNlcyk7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKworICAgIC8qIENoZWNrIGZvciBhIF9fc2xvdHNfXyBzZXF1ZW5jZSB2YXJpYWJsZSBpbiBkaWN0LCBhbmQgY291bnQgaXQgKi8KKyAgICBzbG90cyA9IFB5RGljdF9HZXRJdGVtU3RyaW5nKGRpY3QsICJfX3Nsb3RzX18iKTsKKyAgICBuc2xvdHMgPSAwOworICAgIGFkZF9kaWN0ID0gMDsKKyAgICBhZGRfd2VhayA9IDA7CisgICAgbWF5X2FkZF9kaWN0ID0gYmFzZS0+dHBfZGljdG9mZnNldCA9PSAwOworICAgIG1heV9hZGRfd2VhayA9IGJhc2UtPnRwX3dlYWtsaXN0b2Zmc2V0ID09IDAgJiYgYmFzZS0+dHBfaXRlbXNpemUgPT0gMDsKKyAgICBpZiAoc2xvdHMgPT0gTlVMTCkgeworICAgICAgICBpZiAobWF5X2FkZF9kaWN0KSB7CisgICAgICAgICAgICBhZGRfZGljdCsrOworICAgICAgICB9CisgICAgICAgIGlmIChtYXlfYWRkX3dlYWspIHsKKyAgICAgICAgICAgIGFkZF93ZWFrKys7CisgICAgICAgIH0KKyAgICB9CisgICAgZWxzZSB7CisgICAgICAgIC8qIEhhdmUgc2xvdHMgKi8KKworICAgICAgICAvKiBNYWtlIGl0IGludG8gYSB0dXBsZSAqLworICAgICAgICBpZiAoUHlTdHJpbmdfQ2hlY2soc2xvdHMpIHx8IFB5VW5pY29kZV9DaGVjayhzbG90cykpCisgICAgICAgICAgICBzbG90cyA9IFB5VHVwbGVfUGFjaygxLCBzbG90cyk7CisgICAgICAgIGVsc2UKKyAgICAgICAgICAgIHNsb3RzID0gUHlTZXF1ZW5jZV9UdXBsZShzbG90cyk7CisgICAgICAgIGlmIChzbG90cyA9PSBOVUxMKSB7CisgICAgICAgICAgICBQeV9ERUNSRUYoYmFzZXMpOworICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgICAgIH0KKyAgICAgICAgYXNzZXJ0KFB5VHVwbGVfQ2hlY2soc2xvdHMpKTsKKworICAgICAgICAvKiBBcmUgc2xvdHMgYWxsb3dlZD8gKi8KKyAgICAgICAgbnNsb3RzID0gUHlUdXBsZV9HRVRfU0laRShzbG90cyk7CisgICAgICAgIGlmIChuc2xvdHMgPiAwICYmIGJhc2UtPnRwX2l0ZW1zaXplICE9IDApIHsKKyAgICAgICAgICAgIFB5RXJyX0Zvcm1hdChQeUV4Y19UeXBlRXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgIm5vbmVtcHR5IF9fc2xvdHNfXyAiCisgICAgICAgICAgICAgICAgICAgICAgICAgIm5vdCBzdXBwb3J0ZWQgZm9yIHN1YnR5cGUgb2YgJyVzJyIsCisgICAgICAgICAgICAgICAgICAgICAgICAgYmFzZS0+dHBfbmFtZSk7CisgICAgICAgICAgYmFkX3Nsb3RzOgorICAgICAgICAgICAgUHlfREVDUkVGKGJhc2VzKTsKKyAgICAgICAgICAgIFB5X0RFQ1JFRihzbG90cyk7CisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgfQorCisjaWZkZWYgUHlfVVNJTkdfVU5JQ09ERQorICAgICAgICB0bXAgPSBfdW5pY29kZV90b19zdHJpbmcoc2xvdHMsIG5zbG90cyk7CisgICAgICAgIGlmICh0bXAgPT0gTlVMTCkKKyAgICAgICAgICAgIGdvdG8gYmFkX3Nsb3RzOworICAgICAgICBpZiAodG1wICE9IHNsb3RzKSB7CisgICAgICAgICAgICBQeV9ERUNSRUYoc2xvdHMpOworICAgICAgICAgICAgc2xvdHMgPSB0bXA7CisgICAgICAgIH0KKyNlbmRpZgorICAgICAgICAvKiBDaGVjayBmb3IgdmFsaWQgc2xvdCBuYW1lcyBhbmQgdHdvIHNwZWNpYWwgY2FzZXMgKi8KKyAgICAgICAgZm9yIChpID0gMDsgaSA8IG5zbG90czsgaSsrKSB7CisgICAgICAgICAgICBQeU9iamVjdCAqdG1wID0gUHlUdXBsZV9HRVRfSVRFTShzbG90cywgaSk7CisgICAgICAgICAgICBjaGFyICpzOworICAgICAgICAgICAgaWYgKCF2YWxpZF9pZGVudGlmaWVyKHRtcCkpCisgICAgICAgICAgICAgICAgZ290byBiYWRfc2xvdHM7CisgICAgICAgICAgICBhc3NlcnQoUHlTdHJpbmdfQ2hlY2sodG1wKSk7CisgICAgICAgICAgICBzID0gUHlTdHJpbmdfQVNfU1RSSU5HKHRtcCk7CisgICAgICAgICAgICBpZiAoc3RyY21wKHMsICJfX2RpY3RfXyIpID09IDApIHsKKyAgICAgICAgICAgICAgICBpZiAoIW1heV9hZGRfZGljdCB8fCBhZGRfZGljdCkgeworICAgICAgICAgICAgICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfVHlwZUVycm9yLAorICAgICAgICAgICAgICAgICAgICAgICAgIl9fZGljdF9fIHNsb3QgZGlzYWxsb3dlZDogIgorICAgICAgICAgICAgICAgICAgICAgICAgIndlIGFscmVhZHkgZ290IG9uZSIpOworICAgICAgICAgICAgICAgICAgICBnb3RvIGJhZF9zbG90czsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgYWRkX2RpY3QrKzsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChzdHJjbXAocywgIl9fd2Vha3JlZl9fIikgPT0gMCkgeworICAgICAgICAgICAgICAgIGlmICghbWF5X2FkZF93ZWFrIHx8IGFkZF93ZWFrKSB7CisgICAgICAgICAgICAgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19UeXBlRXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAgICAiX193ZWFrcmVmX18gc2xvdCBkaXNhbGxvd2VkOiAiCisgICAgICAgICAgICAgICAgICAgICAgICAiZWl0aGVyIHdlIGFscmVhZHkgZ290IG9uZSwgIgorICAgICAgICAgICAgICAgICAgICAgICAgIm9yIF9faXRlbXNpemVfXyAhPSAwIik7CisgICAgICAgICAgICAgICAgICAgIGdvdG8gYmFkX3Nsb3RzOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBhZGRfd2VhaysrOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgLyogQ29weSBzbG90cyBpbnRvIGEgbGlzdCwgbWFuZ2xlIG5hbWVzIGFuZCBzb3J0IHRoZW0uCisgICAgICAgICAgIFNvcnRlZCBuYW1lcyBhcmUgbmVlZGVkIGZvciBfX2NsYXNzX18gYXNzaWdubWVudC4KKyAgICAgICAgICAgQ29udmVydCB0aGVtIGJhY2sgdG8gdHVwbGUgYXQgdGhlIGVuZC4KKyAgICAgICAgKi8KKyAgICAgICAgbmV3c2xvdHMgPSBQeUxpc3RfTmV3KG5zbG90cyAtIGFkZF9kaWN0IC0gYWRkX3dlYWspOworICAgICAgICBpZiAobmV3c2xvdHMgPT0gTlVMTCkKKyAgICAgICAgICAgIGdvdG8gYmFkX3Nsb3RzOworICAgICAgICBmb3IgKGkgPSBqID0gMDsgaSA8IG5zbG90czsgaSsrKSB7CisgICAgICAgICAgICBjaGFyICpzOworICAgICAgICAgICAgdG1wID0gUHlUdXBsZV9HRVRfSVRFTShzbG90cywgaSk7CisgICAgICAgICAgICBzID0gUHlTdHJpbmdfQVNfU1RSSU5HKHRtcCk7CisgICAgICAgICAgICBpZiAoKGFkZF9kaWN0ICYmIHN0cmNtcChzLCAiX19kaWN0X18iKSA9PSAwKSB8fAorICAgICAgICAgICAgICAgIChhZGRfd2VhayAmJiBzdHJjbXAocywgIl9fd2Vha3JlZl9fIikgPT0gMCkpCisgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICB0bXAgPV9QeV9NYW5nbGUobmFtZSwgdG1wKTsKKyAgICAgICAgICAgIGlmICghdG1wKSB7CisgICAgICAgICAgICAgICAgUHlfREVDUkVGKG5ld3Nsb3RzKTsKKyAgICAgICAgICAgICAgICBnb3RvIGJhZF9zbG90czsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIFB5TGlzdF9TRVRfSVRFTShuZXdzbG90cywgaiwgdG1wKTsKKyAgICAgICAgICAgIGorKzsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnQoaiA9PSBuc2xvdHMgLSBhZGRfZGljdCAtIGFkZF93ZWFrKTsKKyAgICAgICAgbnNsb3RzID0gajsKKyAgICAgICAgUHlfREVDUkVGKHNsb3RzKTsKKyAgICAgICAgaWYgKFB5TGlzdF9Tb3J0KG5ld3Nsb3RzKSA9PSAtMSkgeworICAgICAgICAgICAgUHlfREVDUkVGKGJhc2VzKTsKKyAgICAgICAgICAgIFB5X0RFQ1JFRihuZXdzbG90cyk7CisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgfQorICAgICAgICBzbG90cyA9IFB5TGlzdF9Bc1R1cGxlKG5ld3Nsb3RzKTsKKyAgICAgICAgUHlfREVDUkVGKG5ld3Nsb3RzKTsKKyAgICAgICAgaWYgKHNsb3RzID09IE5VTEwpIHsKKyAgICAgICAgICAgIFB5X0RFQ1JFRihiYXNlcyk7CisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgfQorCisgICAgICAgIC8qIFNlY29uZGFyeSBiYXNlcyBtYXkgcHJvdmlkZSB3ZWFrcmVmcyBvciBkaWN0ICovCisgICAgICAgIGlmIChuYmFzZXMgPiAxICYmCisgICAgICAgICAgICAoKG1heV9hZGRfZGljdCAmJiAhYWRkX2RpY3QpIHx8CisgICAgICAgICAgICAgKG1heV9hZGRfd2VhayAmJiAhYWRkX3dlYWspKSkgeworICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IG5iYXNlczsgaSsrKSB7CisgICAgICAgICAgICAgICAgdG1wID0gUHlUdXBsZV9HRVRfSVRFTShiYXNlcywgaSk7CisgICAgICAgICAgICAgICAgaWYgKHRtcCA9PSAoUHlPYmplY3QgKiliYXNlKQorICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsgLyogU2tpcCBwcmltYXJ5IGJhc2UgKi8KKyAgICAgICAgICAgICAgICBpZiAoUHlDbGFzc19DaGVjayh0bXApKSB7CisgICAgICAgICAgICAgICAgICAgIC8qIENsYXNzaWMgYmFzZSBjbGFzcyBwcm92aWRlcyBib3RoICovCisgICAgICAgICAgICAgICAgICAgIGlmIChtYXlfYWRkX2RpY3QgJiYgIWFkZF9kaWN0KQorICAgICAgICAgICAgICAgICAgICAgICAgYWRkX2RpY3QrKzsKKyAgICAgICAgICAgICAgICAgICAgaWYgKG1heV9hZGRfd2VhayAmJiAhYWRkX3dlYWspCisgICAgICAgICAgICAgICAgICAgICAgICBhZGRfd2VhaysrOworICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgYXNzZXJ0KFB5VHlwZV9DaGVjayh0bXApKTsKKyAgICAgICAgICAgICAgICB0bXB0eXBlID0gKFB5VHlwZU9iamVjdCAqKXRtcDsKKyAgICAgICAgICAgICAgICBpZiAobWF5X2FkZF9kaWN0ICYmICFhZGRfZGljdCAmJgorICAgICAgICAgICAgICAgICAgICB0bXB0eXBlLT50cF9kaWN0b2Zmc2V0ICE9IDApCisgICAgICAgICAgICAgICAgICAgIGFkZF9kaWN0Kys7CisgICAgICAgICAgICAgICAgaWYgKG1heV9hZGRfd2VhayAmJiAhYWRkX3dlYWsgJiYKKyAgICAgICAgICAgICAgICAgICAgdG1wdHlwZS0+dHBfd2Vha2xpc3RvZmZzZXQgIT0gMCkKKyAgICAgICAgICAgICAgICAgICAgYWRkX3dlYWsrKzsKKyAgICAgICAgICAgICAgICBpZiAobWF5X2FkZF9kaWN0ICYmICFhZGRfZGljdCkKKyAgICAgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICAgICAgaWYgKG1heV9hZGRfd2VhayAmJiAhYWRkX3dlYWspCisgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgICAgIC8qIE5vdGhpbmcgbW9yZSB0byBjaGVjayAqLworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyogWFhYIEZyb20gaGVyZSB1bnRpbCB0eXBlIGlzIHNhZmVseSBhbGxvY2F0ZWQsCisgICAgICAgInJldHVybiBOVUxMIiBtYXkgbGVhayBzbG90cyEgKi8KKworICAgIC8qIEFsbG9jYXRlIHRoZSB0eXBlIG9iamVjdCAqLworICAgIHR5cGUgPSAoUHlUeXBlT2JqZWN0ICopbWV0YXR5cGUtPnRwX2FsbG9jKG1ldGF0eXBlLCBuc2xvdHMpOworICAgIGlmICh0eXBlID09IE5VTEwpIHsKKyAgICAgICAgUHlfWERFQ1JFRihzbG90cyk7CisgICAgICAgIFB5X0RFQ1JFRihiYXNlcyk7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKworICAgIC8qIEtlZXAgbmFtZSBhbmQgc2xvdHMgYWxpdmUgaW4gdGhlIGV4dGVuZGVkIHR5cGUgb2JqZWN0ICovCisgICAgZXQgPSAoUHlIZWFwVHlwZU9iamVjdCAqKXR5cGU7CisgICAgUHlfSU5DUkVGKG5hbWUpOworICAgIGV0LT5odF9uYW1lID0gbmFtZTsKKyAgICBldC0+aHRfc2xvdHMgPSBzbG90czsKKworICAgIC8qIEluaXRpYWxpemUgdHBfZmxhZ3MgKi8KKyAgICB0eXBlLT50cF9mbGFncyA9IFB5X1RQRkxBR1NfREVGQVVMVCB8IFB5X1RQRkxBR1NfSEVBUFRZUEUgfAorICAgICAgICBQeV9UUEZMQUdTX0JBU0VUWVBFOworICAgIGlmIChiYXNlLT50cF9mbGFncyAmIFB5X1RQRkxBR1NfSEFWRV9HQykKKyAgICAgICAgdHlwZS0+dHBfZmxhZ3MgfD0gUHlfVFBGTEFHU19IQVZFX0dDOworICAgIGlmIChiYXNlLT50cF9mbGFncyAmIFB5X1RQRkxBR1NfSEFWRV9ORVdCVUZGRVIpCisgICAgICAgIHR5cGUtPnRwX2ZsYWdzIHw9IFB5X1RQRkxBR1NfSEFWRV9ORVdCVUZGRVI7CisKKyAgICAvKiBJdCdzIGEgbmV3LXN0eWxlIG51bWJlciB1bmxlc3MgaXQgc3BlY2lmaWNhbGx5IGluaGVyaXRzIGFueQorICAgICAgIG9sZC1zdHlsZSBudW1lcmljIGJlaGF2aW9yICovCisgICAgaWYgKChiYXNlLT50cF9mbGFncyAmIFB5X1RQRkxBR1NfQ0hFQ0tUWVBFUykgfHwKKyAgICAgICAgKGJhc2UtPnRwX2FzX251bWJlciA9PSBOVUxMKSkKKyAgICAgICAgdHlwZS0+dHBfZmxhZ3MgfD0gUHlfVFBGTEFHU19DSEVDS1RZUEVTOworCisgICAgLyogSW5pdGlhbGl6ZSBlc3NlbnRpYWwgZmllbGRzICovCisgICAgdHlwZS0+dHBfYXNfbnVtYmVyID0gJmV0LT5hc19udW1iZXI7CisgICAgdHlwZS0+dHBfYXNfc2VxdWVuY2UgPSAmZXQtPmFzX3NlcXVlbmNlOworICAgIHR5cGUtPnRwX2FzX21hcHBpbmcgPSAmZXQtPmFzX21hcHBpbmc7CisgICAgdHlwZS0+dHBfYXNfYnVmZmVyID0gJmV0LT5hc19idWZmZXI7CisgICAgdHlwZS0+dHBfbmFtZSA9IFB5U3RyaW5nX0FTX1NUUklORyhuYW1lKTsKKworICAgIC8qIFNldCB0cF9iYXNlIGFuZCB0cF9iYXNlcyAqLworICAgIHR5cGUtPnRwX2Jhc2VzID0gYmFzZXM7CisgICAgUHlfSU5DUkVGKGJhc2UpOworICAgIHR5cGUtPnRwX2Jhc2UgPSBiYXNlOworCisgICAgLyogSW5pdGlhbGl6ZSB0cF9kaWN0IGZyb20gcGFzc2VkLWluIGRpY3QgKi8KKyAgICB0eXBlLT50cF9kaWN0ID0gZGljdCA9IFB5RGljdF9Db3B5KGRpY3QpOworICAgIGlmIChkaWN0ID09IE5VTEwpIHsKKyAgICAgICAgUHlfREVDUkVGKHR5cGUpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisKKyAgICAvKiBTZXQgX19tb2R1bGVfXyBpbiB0aGUgZGljdCAqLworICAgIGlmIChQeURpY3RfR2V0SXRlbVN0cmluZyhkaWN0LCAiX19tb2R1bGVfXyIpID09IE5VTEwpIHsKKyAgICAgICAgdG1wID0gUHlFdmFsX0dldEdsb2JhbHMoKTsKKyAgICAgICAgaWYgKHRtcCAhPSBOVUxMKSB7CisgICAgICAgICAgICB0bXAgPSBQeURpY3RfR2V0SXRlbVN0cmluZyh0bXAsICJfX25hbWVfXyIpOworICAgICAgICAgICAgaWYgKHRtcCAhPSBOVUxMKSB7CisgICAgICAgICAgICAgICAgaWYgKFB5RGljdF9TZXRJdGVtU3RyaW5nKGRpY3QsICJfX21vZHVsZV9fIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdG1wKSA8IDApCisgICAgICAgICAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgLyogU2V0IHRwX2RvYyB0byBhIGNvcHkgb2YgZGljdFsnX19kb2NfXyddLCBpZiB0aGUgbGF0dGVyIGlzIHRoZXJlCisgICAgICAgYW5kIGlzIGEgc3RyaW5nLiAgVGhlIF9fZG9jX18gYWNjZXNzb3Igd2lsbCBmaXJzdCBsb29rIGZvciB0cF9kb2M7CisgICAgICAgaWYgdGhhdCBmYWlscywgaXQgd2lsbCBzdGlsbCBsb29rIGludG8gX19kaWN0X18uCisgICAgKi8KKyAgICB7CisgICAgICAgIFB5T2JqZWN0ICpkb2MgPSBQeURpY3RfR2V0SXRlbVN0cmluZyhkaWN0LCAiX19kb2NfXyIpOworICAgICAgICBpZiAoZG9jICE9IE5VTEwgJiYgUHlTdHJpbmdfQ2hlY2soZG9jKSkgeworICAgICAgICAgICAgY29uc3Qgc2l6ZV90IG4gPSAoc2l6ZV90KVB5U3RyaW5nX0dFVF9TSVpFKGRvYyk7CisgICAgICAgICAgICBjaGFyICp0cF9kb2MgPSAoY2hhciAqKVB5T2JqZWN0X01BTExPQyhuKzEpOworICAgICAgICAgICAgaWYgKHRwX2RvYyA9PSBOVUxMKSB7CisgICAgICAgICAgICAgICAgUHlfREVDUkVGKHR5cGUpOworICAgICAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgICAgICAgICAgfQorICAgICAgICAgICAgbWVtY3B5KHRwX2RvYywgUHlTdHJpbmdfQVNfU1RSSU5HKGRvYyksIG4rMSk7CisgICAgICAgICAgICB0eXBlLT50cF9kb2MgPSB0cF9kb2M7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKiBTcGVjaWFsLWNhc2UgX19uZXdfXzogaWYgaXQncyBhIHBsYWluIGZ1bmN0aW9uLAorICAgICAgIG1ha2UgaXQgYSBzdGF0aWMgZnVuY3Rpb24gKi8KKyAgICB0bXAgPSBQeURpY3RfR2V0SXRlbVN0cmluZyhkaWN0LCAiX19uZXdfXyIpOworICAgIGlmICh0bXAgIT0gTlVMTCAmJiBQeUZ1bmN0aW9uX0NoZWNrKHRtcCkpIHsKKyAgICAgICAgdG1wID0gUHlTdGF0aWNNZXRob2RfTmV3KHRtcCk7CisgICAgICAgIGlmICh0bXAgPT0gTlVMTCkgeworICAgICAgICAgICAgUHlfREVDUkVGKHR5cGUpOworICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgICAgIH0KKyAgICAgICAgUHlEaWN0X1NldEl0ZW1TdHJpbmcoZGljdCwgIl9fbmV3X18iLCB0bXApOworICAgICAgICBQeV9ERUNSRUYodG1wKTsKKyAgICB9CisKKyAgICAvKiBBZGQgZGVzY3JpcHRvcnMgZm9yIGN1c3RvbSBzbG90cyBmcm9tIF9fc2xvdHNfXywgb3IgZm9yIF9fZGljdF9fICovCisgICAgbXAgPSBQeUhlYXBUeXBlX0dFVF9NRU1CRVJTKGV0KTsKKyAgICBzbG90b2Zmc2V0ID0gYmFzZS0+dHBfYmFzaWNzaXplOworICAgIGlmIChzbG90cyAhPSBOVUxMKSB7CisgICAgICAgIGZvciAoaSA9IDA7IGkgPCBuc2xvdHM7IGkrKywgbXArKykgeworICAgICAgICAgICAgbXAtPm5hbWUgPSBQeVN0cmluZ19BU19TVFJJTkcoCisgICAgICAgICAgICAgICAgUHlUdXBsZV9HRVRfSVRFTShzbG90cywgaSkpOworICAgICAgICAgICAgbXAtPnR5cGUgPSBUX09CSkVDVF9FWDsKKyAgICAgICAgICAgIG1wLT5vZmZzZXQgPSBzbG90b2Zmc2V0OworCisgICAgICAgICAgICAvKiBfX2RpY3RfXyBhbmQgX193ZWFrcmVmX18gYXJlIGFscmVhZHkgZmlsdGVyZWQgb3V0ICovCisgICAgICAgICAgICBhc3NlcnQoc3RyY21wKG1wLT5uYW1lLCAiX19kaWN0X18iKSAhPSAwKTsKKyAgICAgICAgICAgIGFzc2VydChzdHJjbXAobXAtPm5hbWUsICJfX3dlYWtyZWZfXyIpICE9IDApOworCisgICAgICAgICAgICBzbG90b2Zmc2V0ICs9IHNpemVvZihQeU9iamVjdCAqKTsKKyAgICAgICAgfQorICAgIH0KKyAgICBpZiAoYWRkX2RpY3QpIHsKKyAgICAgICAgaWYgKGJhc2UtPnRwX2l0ZW1zaXplKQorICAgICAgICAgICAgdHlwZS0+dHBfZGljdG9mZnNldCA9IC0obG9uZylzaXplb2YoUHlPYmplY3QgKik7CisgICAgICAgIGVsc2UKKyAgICAgICAgICAgIHR5cGUtPnRwX2RpY3RvZmZzZXQgPSBzbG90b2Zmc2V0OworICAgICAgICBzbG90b2Zmc2V0ICs9IHNpemVvZihQeU9iamVjdCAqKTsKKyAgICB9CisgICAgaWYgKGFkZF93ZWFrKSB7CisgICAgICAgIGFzc2VydCghYmFzZS0+dHBfaXRlbXNpemUpOworICAgICAgICB0eXBlLT50cF93ZWFrbGlzdG9mZnNldCA9IHNsb3RvZmZzZXQ7CisgICAgICAgIHNsb3RvZmZzZXQgKz0gc2l6ZW9mKFB5T2JqZWN0ICopOworICAgIH0KKyAgICB0eXBlLT50cF9iYXNpY3NpemUgPSBzbG90b2Zmc2V0OworICAgIHR5cGUtPnRwX2l0ZW1zaXplID0gYmFzZS0+dHBfaXRlbXNpemU7CisgICAgdHlwZS0+dHBfbWVtYmVycyA9IFB5SGVhcFR5cGVfR0VUX01FTUJFUlMoZXQpOworCisgICAgaWYgKHR5cGUtPnRwX3dlYWtsaXN0b2Zmc2V0ICYmIHR5cGUtPnRwX2RpY3RvZmZzZXQpCisgICAgICAgIHR5cGUtPnRwX2dldHNldCA9IHN1YnR5cGVfZ2V0c2V0c19mdWxsOworICAgIGVsc2UgaWYgKHR5cGUtPnRwX3dlYWtsaXN0b2Zmc2V0ICYmICF0eXBlLT50cF9kaWN0b2Zmc2V0KQorICAgICAgICB0eXBlLT50cF9nZXRzZXQgPSBzdWJ0eXBlX2dldHNldHNfd2Vha3JlZl9vbmx5OworICAgIGVsc2UgaWYgKCF0eXBlLT50cF93ZWFrbGlzdG9mZnNldCAmJiB0eXBlLT50cF9kaWN0b2Zmc2V0KQorICAgICAgICB0eXBlLT50cF9nZXRzZXQgPSBzdWJ0eXBlX2dldHNldHNfZGljdF9vbmx5OworICAgIGVsc2UKKyAgICAgICAgdHlwZS0+dHBfZ2V0c2V0ID0gTlVMTDsKKworICAgIC8qIFNwZWNpYWwgY2FzZSBzb21lIHNsb3RzICovCisgICAgaWYgKHR5cGUtPnRwX2RpY3RvZmZzZXQgIT0gMCB8fCBuc2xvdHMgPiAwKSB7CisgICAgICAgIGlmIChiYXNlLT50cF9nZXRhdHRyID09IE5VTEwgJiYgYmFzZS0+dHBfZ2V0YXR0cm8gPT0gTlVMTCkKKyAgICAgICAgICAgIHR5cGUtPnRwX2dldGF0dHJvID0gUHlPYmplY3RfR2VuZXJpY0dldEF0dHI7CisgICAgICAgIGlmIChiYXNlLT50cF9zZXRhdHRyID09IE5VTEwgJiYgYmFzZS0+dHBfc2V0YXR0cm8gPT0gTlVMTCkKKyAgICAgICAgICAgIHR5cGUtPnRwX3NldGF0dHJvID0gUHlPYmplY3RfR2VuZXJpY1NldEF0dHI7CisgICAgfQorICAgIHR5cGUtPnRwX2RlYWxsb2MgPSBzdWJ0eXBlX2RlYWxsb2M7CisKKyAgICAvKiBFbmFibGUgR0MgdW5sZXNzIHRoZXJlIGFyZSByZWFsbHkgbm8gaW5zdGFuY2UgdmFyaWFibGVzIHBvc3NpYmxlICovCisgICAgaWYgKCEodHlwZS0+dHBfYmFzaWNzaXplID09IHNpemVvZihQeU9iamVjdCkgJiYKKyAgICAgICAgICB0eXBlLT50cF9pdGVtc2l6ZSA9PSAwKSkKKyAgICAgICAgdHlwZS0+dHBfZmxhZ3MgfD0gUHlfVFBGTEFHU19IQVZFX0dDOworCisgICAgLyogQWx3YXlzIG92ZXJyaWRlIGFsbG9jYXRpb24gc3RyYXRlZ3kgdG8gdXNlIHJlZ3VsYXIgaGVhcCAqLworICAgIHR5cGUtPnRwX2FsbG9jID0gUHlUeXBlX0dlbmVyaWNBbGxvYzsKKyAgICBpZiAodHlwZS0+dHBfZmxhZ3MgJiBQeV9UUEZMQUdTX0hBVkVfR0MpIHsKKyAgICAgICAgdHlwZS0+dHBfZnJlZSA9IFB5T2JqZWN0X0dDX0RlbDsKKyAgICAgICAgdHlwZS0+dHBfdHJhdmVyc2UgPSBzdWJ0eXBlX3RyYXZlcnNlOworICAgICAgICB0eXBlLT50cF9jbGVhciA9IHN1YnR5cGVfY2xlYXI7CisgICAgfQorICAgIGVsc2UKKyAgICAgICAgdHlwZS0+dHBfZnJlZSA9IFB5T2JqZWN0X0RlbDsKKworICAgIC8qIEluaXRpYWxpemUgdGhlIHJlc3QgKi8KKyAgICBpZiAoUHlUeXBlX1JlYWR5KHR5cGUpIDwgMCkgeworICAgICAgICBQeV9ERUNSRUYodHlwZSk7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKworICAgIC8qIFB1dCB0aGUgcHJvcGVyIHNsb3RzIGluIHBsYWNlICovCisgICAgZml4dXBfc2xvdF9kaXNwYXRjaGVycyh0eXBlKTsKKworICAgIHJldHVybiAoUHlPYmplY3QgKil0eXBlOworfQorCisvKiBJbnRlcm5hbCBBUEkgdG8gbG9vayBmb3IgYSBuYW1lIHRocm91Z2ggdGhlIE1STy4KKyAgIFRoaXMgcmV0dXJucyBhIGJvcnJvd2VkIHJlZmVyZW5jZSwgYW5kIGRvZXNuJ3Qgc2V0IGFuIGV4Y2VwdGlvbiEgKi8KK1B5T2JqZWN0ICoKK19QeVR5cGVfTG9va3VwKFB5VHlwZU9iamVjdCAqdHlwZSwgUHlPYmplY3QgKm5hbWUpCit7CisgICAgUHlfc3NpemVfdCBpLCBuOworICAgIFB5T2JqZWN0ICptcm8sICpyZXMsICpiYXNlLCAqZGljdDsKKyAgICB1bnNpZ25lZCBpbnQgaDsKKworICAgIGlmIChNQ0FDSEVfQ0FDSEVBQkxFX05BTUUobmFtZSkgJiYKKyAgICAgICAgUHlUeXBlX0hhc0ZlYXR1cmUodHlwZSwgUHlfVFBGTEFHU19WQUxJRF9WRVJTSU9OX1RBRykpIHsKKyAgICAgICAgLyogZmFzdCBwYXRoICovCisgICAgICAgIGggPSBNQ0FDSEVfSEFTSF9NRVRIT0QodHlwZSwgbmFtZSk7CisgICAgICAgIGlmIChtZXRob2RfY2FjaGVbaF0udmVyc2lvbiA9PSB0eXBlLT50cF92ZXJzaW9uX3RhZyAmJgorICAgICAgICAgICAgbWV0aG9kX2NhY2hlW2hdLm5hbWUgPT0gbmFtZSkKKyAgICAgICAgICAgIHJldHVybiBtZXRob2RfY2FjaGVbaF0udmFsdWU7CisgICAgfQorCisgICAgLyogTG9vayBpbiB0cF9kaWN0IG9mIHR5cGVzIGluIE1STyAqLworICAgIG1ybyA9IHR5cGUtPnRwX21ybzsKKworICAgIC8qIElmIG1ybyBpcyBOVUxMLCB0aGUgdHlwZSBpcyBlaXRoZXIgbm90IHlldCBpbml0aWFsaXplZAorICAgICAgIGJ5IFB5VHlwZV9SZWFkeSgpLCBvciBhbHJlYWR5IGNsZWFyZWQgYnkgdHlwZV9jbGVhcigpLgorICAgICAgIEVpdGhlciB3YXkgdGhlIHNhZmVzdCB0aGluZyB0byBkbyBpcyB0byByZXR1cm4gTlVMTC4gKi8KKyAgICBpZiAobXJvID09IE5VTEwpCisgICAgICAgIHJldHVybiBOVUxMOworCisgICAgcmVzID0gTlVMTDsKKyAgICBhc3NlcnQoUHlUdXBsZV9DaGVjayhtcm8pKTsKKyAgICBuID0gUHlUdXBsZV9HRVRfU0laRShtcm8pOworICAgIGZvciAoaSA9IDA7IGkgPCBuOyBpKyspIHsKKyAgICAgICAgYmFzZSA9IFB5VHVwbGVfR0VUX0lURU0obXJvLCBpKTsKKyAgICAgICAgaWYgKFB5Q2xhc3NfQ2hlY2soYmFzZSkpCisgICAgICAgICAgICBkaWN0ID0gKChQeUNsYXNzT2JqZWN0ICopYmFzZSktPmNsX2RpY3Q7CisgICAgICAgIGVsc2UgeworICAgICAgICAgICAgYXNzZXJ0KFB5VHlwZV9DaGVjayhiYXNlKSk7CisgICAgICAgICAgICBkaWN0ID0gKChQeVR5cGVPYmplY3QgKiliYXNlKS0+dHBfZGljdDsKKyAgICAgICAgfQorICAgICAgICBhc3NlcnQoZGljdCAmJiBQeURpY3RfQ2hlY2soZGljdCkpOworICAgICAgICByZXMgPSBQeURpY3RfR2V0SXRlbShkaWN0LCBuYW1lKTsKKyAgICAgICAgaWYgKHJlcyAhPSBOVUxMKQorICAgICAgICAgICAgYnJlYWs7CisgICAgfQorCisgICAgaWYgKE1DQUNIRV9DQUNIRUFCTEVfTkFNRShuYW1lKSAmJiBhc3NpZ25fdmVyc2lvbl90YWcodHlwZSkpIHsKKyAgICAgICAgaCA9IE1DQUNIRV9IQVNIX01FVEhPRCh0eXBlLCBuYW1lKTsKKyAgICAgICAgbWV0aG9kX2NhY2hlW2hdLnZlcnNpb24gPSB0eXBlLT50cF92ZXJzaW9uX3RhZzsKKyAgICAgICAgbWV0aG9kX2NhY2hlW2hdLnZhbHVlID0gcmVzOyAgLyogYm9ycm93ZWQgKi8KKyAgICAgICAgUHlfSU5DUkVGKG5hbWUpOworICAgICAgICBQeV9ERUNSRUYobWV0aG9kX2NhY2hlW2hdLm5hbWUpOworICAgICAgICBtZXRob2RfY2FjaGVbaF0ubmFtZSA9IG5hbWU7CisgICAgfQorICAgIHJldHVybiByZXM7Cit9CisKKy8qIFRoaXMgaXMgc2ltaWxhciB0byBQeU9iamVjdF9HZW5lcmljR2V0QXR0cigpLAorICAgYnV0IHVzZXMgX1B5VHlwZV9Mb29rdXAoKSBpbnN0ZWFkIG9mIGp1c3QgbG9va2luZyBpbiB0eXBlLT50cF9kaWN0LiAqLworc3RhdGljIFB5T2JqZWN0ICoKK3R5cGVfZ2V0YXR0cm8oUHlUeXBlT2JqZWN0ICp0eXBlLCBQeU9iamVjdCAqbmFtZSkKK3sKKyAgICBQeVR5cGVPYmplY3QgKm1ldGF0eXBlID0gUHlfVFlQRSh0eXBlKTsKKyAgICBQeU9iamVjdCAqbWV0YV9hdHRyaWJ1dGUsICphdHRyaWJ1dGU7CisgICAgZGVzY3JnZXRmdW5jIG1ldGFfZ2V0OworCisgICAgaWYgKCFQeVN0cmluZ19DaGVjayhuYW1lKSkgeworICAgICAgICBQeUVycl9Gb3JtYXQoUHlFeGNfVHlwZUVycm9yLAorICAgICAgICAgICAgICAgICAgICAgImF0dHJpYnV0ZSBuYW1lIG11c3QgYmUgc3RyaW5nLCBub3QgJyUuMjAwcyciLAorICAgICAgICAgICAgICAgICAgICAgbmFtZS0+b2JfdHlwZS0+dHBfbmFtZSk7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKworICAgIC8qIEluaXRpYWxpemUgdGhpcyB0eXBlICh3ZSdsbCBhc3N1bWUgdGhlIG1ldGF0eXBlIGlzIGluaXRpYWxpemVkKSAqLworICAgIGlmICh0eXBlLT50cF9kaWN0ID09IE5VTEwpIHsKKyAgICAgICAgaWYgKFB5VHlwZV9SZWFkeSh0eXBlKSA8IDApCisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisKKyAgICAvKiBObyByZWFkYWJsZSBkZXNjcmlwdG9yIGZvdW5kIHlldCAqLworICAgIG1ldGFfZ2V0ID0gTlVMTDsKKworICAgIC8qIExvb2sgZm9yIHRoZSBhdHRyaWJ1dGUgaW4gdGhlIG1ldGF0eXBlICovCisgICAgbWV0YV9hdHRyaWJ1dGUgPSBfUHlUeXBlX0xvb2t1cChtZXRhdHlwZSwgbmFtZSk7CisKKyAgICBpZiAobWV0YV9hdHRyaWJ1dGUgIT0gTlVMTCkgeworICAgICAgICBtZXRhX2dldCA9IFB5X1RZUEUobWV0YV9hdHRyaWJ1dGUpLT50cF9kZXNjcl9nZXQ7CisKKyAgICAgICAgaWYgKG1ldGFfZ2V0ICE9IE5VTEwgJiYgUHlEZXNjcl9Jc0RhdGEobWV0YV9hdHRyaWJ1dGUpKSB7CisgICAgICAgICAgICAvKiBEYXRhIGRlc2NyaXB0b3JzIGltcGxlbWVudCB0cF9kZXNjcl9zZXQgdG8gaW50ZXJjZXB0CisgICAgICAgICAgICAgKiB3cml0ZXMuIEFzc3VtZSB0aGUgYXR0cmlidXRlIGlzIG5vdCBvdmVycmlkZGVuIGluCisgICAgICAgICAgICAgKiB0eXBlJ3MgdHBfZGljdCAoYW5kIGJhc2VzKTogY2FsbCB0aGUgZGVzY3JpcHRvciBub3cuCisgICAgICAgICAgICAgKi8KKyAgICAgICAgICAgIHJldHVybiBtZXRhX2dldChtZXRhX2F0dHJpYnV0ZSwgKFB5T2JqZWN0ICopdHlwZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAoUHlPYmplY3QgKiltZXRhdHlwZSk7CisgICAgICAgIH0KKyAgICAgICAgUHlfSU5DUkVGKG1ldGFfYXR0cmlidXRlKTsKKyAgICB9CisKKyAgICAvKiBObyBkYXRhIGRlc2NyaXB0b3IgZm91bmQgb24gbWV0YXR5cGUuIExvb2sgaW4gdHBfZGljdCBvZiB0aGlzCisgICAgICogdHlwZSBhbmQgaXRzIGJhc2VzICovCisgICAgYXR0cmlidXRlID0gX1B5VHlwZV9Mb29rdXAodHlwZSwgbmFtZSk7CisgICAgaWYgKGF0dHJpYnV0ZSAhPSBOVUxMKSB7CisgICAgICAgIC8qIEltcGxlbWVudCBkZXNjcmlwdG9yIGZ1bmN0aW9uYWxpdHksIGlmIGFueSAqLworICAgICAgICBkZXNjcmdldGZ1bmMgbG9jYWxfZ2V0ID0gUHlfVFlQRShhdHRyaWJ1dGUpLT50cF9kZXNjcl9nZXQ7CisKKyAgICAgICAgUHlfWERFQ1JFRihtZXRhX2F0dHJpYnV0ZSk7CisKKyAgICAgICAgaWYgKGxvY2FsX2dldCAhPSBOVUxMKSB7CisgICAgICAgICAgICAvKiBOVUxMIDJuZCBhcmd1bWVudCBpbmRpY2F0ZXMgdGhlIGRlc2NyaXB0b3Igd2FzCisgICAgICAgICAgICAgKiBmb3VuZCBvbiB0aGUgdGFyZ2V0IG9iamVjdCBpdHNlbGYgKG9yIGEgYmFzZSkgICovCisgICAgICAgICAgICByZXR1cm4gbG9jYWxfZ2V0KGF0dHJpYnV0ZSwgKFB5T2JqZWN0ICopTlVMTCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKFB5T2JqZWN0ICopdHlwZSk7CisgICAgICAgIH0KKworICAgICAgICBQeV9JTkNSRUYoYXR0cmlidXRlKTsKKyAgICAgICAgcmV0dXJuIGF0dHJpYnV0ZTsKKyAgICB9CisKKyAgICAvKiBObyBhdHRyaWJ1dGUgZm91bmQgaW4gbG9jYWwgX19kaWN0X18gKG9yIGJhc2VzKTogdXNlIHRoZQorICAgICAqIGRlc2NyaXB0b3IgZnJvbSB0aGUgbWV0YXR5cGUsIGlmIGFueSAqLworICAgIGlmIChtZXRhX2dldCAhPSBOVUxMKSB7CisgICAgICAgIFB5T2JqZWN0ICpyZXM7CisgICAgICAgIHJlcyA9IG1ldGFfZ2V0KG1ldGFfYXR0cmlidXRlLCAoUHlPYmplY3QgKil0eXBlLAorICAgICAgICAgICAgICAgICAgICAgICAoUHlPYmplY3QgKiltZXRhdHlwZSk7CisgICAgICAgIFB5X0RFQ1JFRihtZXRhX2F0dHJpYnV0ZSk7CisgICAgICAgIHJldHVybiByZXM7CisgICAgfQorCisgICAgLyogSWYgYW4gb3JkaW5hcnkgYXR0cmlidXRlIHdhcyBmb3VuZCBvbiB0aGUgbWV0YXR5cGUsIHJldHVybiBpdCBub3cgKi8KKyAgICBpZiAobWV0YV9hdHRyaWJ1dGUgIT0gTlVMTCkgeworICAgICAgICByZXR1cm4gbWV0YV9hdHRyaWJ1dGU7CisgICAgfQorCisgICAgLyogR2l2ZSB1cCAqLworICAgIFB5RXJyX0Zvcm1hdChQeUV4Y19BdHRyaWJ1dGVFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICJ0eXBlIG9iamVjdCAnJS41MHMnIGhhcyBubyBhdHRyaWJ1dGUgJyUuNDAwcyciLAorICAgICAgICAgICAgICAgICAgICAgdHlwZS0+dHBfbmFtZSwgUHlTdHJpbmdfQVNfU1RSSU5HKG5hbWUpKTsKKyAgICByZXR1cm4gTlVMTDsKK30KKworc3RhdGljIGludAordHlwZV9zZXRhdHRybyhQeVR5cGVPYmplY3QgKnR5cGUsIFB5T2JqZWN0ICpuYW1lLCBQeU9iamVjdCAqdmFsdWUpCit7CisgICAgaWYgKCEodHlwZS0+dHBfZmxhZ3MgJiBQeV9UUEZMQUdTX0hFQVBUWVBFKSkgeworICAgICAgICBQeUVycl9Gb3JtYXQoCisgICAgICAgICAgICBQeUV4Y19UeXBlRXJyb3IsCisgICAgICAgICAgICAiY2FuJ3Qgc2V0IGF0dHJpYnV0ZXMgb2YgYnVpbHQtaW4vZXh0ZW5zaW9uIHR5cGUgJyVzJyIsCisgICAgICAgICAgICB0eXBlLT50cF9uYW1lKTsKKyAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKyAgICBpZiAoUHlPYmplY3RfR2VuZXJpY1NldEF0dHIoKFB5T2JqZWN0ICopdHlwZSwgbmFtZSwgdmFsdWUpIDwgMCkKKyAgICAgICAgcmV0dXJuIC0xOworICAgIHJldHVybiB1cGRhdGVfc2xvdCh0eXBlLCBuYW1lKTsKK30KKworc3RhdGljIHZvaWQKK3R5cGVfZGVhbGxvYyhQeVR5cGVPYmplY3QgKnR5cGUpCit7CisgICAgUHlIZWFwVHlwZU9iamVjdCAqZXQ7CisKKyAgICAvKiBBc3NlcnQgdGhpcyBpcyBhIGhlYXAtYWxsb2NhdGVkIHR5cGUgb2JqZWN0ICovCisgICAgYXNzZXJ0KHR5cGUtPnRwX2ZsYWdzICYgUHlfVFBGTEFHU19IRUFQVFlQRSk7CisgICAgX1B5T2JqZWN0X0dDX1VOVFJBQ0sodHlwZSk7CisgICAgUHlPYmplY3RfQ2xlYXJXZWFrUmVmcygoUHlPYmplY3QgKil0eXBlKTsKKyAgICBldCA9IChQeUhlYXBUeXBlT2JqZWN0ICopdHlwZTsKKyAgICBQeV9YREVDUkVGKHR5cGUtPnRwX2Jhc2UpOworICAgIFB5X1hERUNSRUYodHlwZS0+dHBfZGljdCk7CisgICAgUHlfWERFQ1JFRih0eXBlLT50cF9iYXNlcyk7CisgICAgUHlfWERFQ1JFRih0eXBlLT50cF9tcm8pOworICAgIFB5X1hERUNSRUYodHlwZS0+dHBfY2FjaGUpOworICAgIFB5X1hERUNSRUYodHlwZS0+dHBfc3ViY2xhc3Nlcyk7CisgICAgLyogQSB0eXBlJ3MgdHBfZG9jIGlzIGhlYXAgYWxsb2NhdGVkLCB1bmxpa2UgdGhlIHRwX2RvYyBzbG90cworICAgICAqIG9mIG1vc3Qgb3RoZXIgb2JqZWN0cy4gIEl0J3Mgb2theSB0byBjYXN0IGl0IHRvIGNoYXIgKi4KKyAgICAgKi8KKyAgICBQeU9iamVjdF9GcmVlKChjaGFyICopdHlwZS0+dHBfZG9jKTsKKyAgICBQeV9YREVDUkVGKGV0LT5odF9uYW1lKTsKKyAgICBQeV9YREVDUkVGKGV0LT5odF9zbG90cyk7CisgICAgUHlfVFlQRSh0eXBlKS0+dHBfZnJlZSgoUHlPYmplY3QgKil0eXBlKTsKK30KKworc3RhdGljIFB5T2JqZWN0ICoKK3R5cGVfc3ViY2xhc3NlcyhQeVR5cGVPYmplY3QgKnR5cGUsIFB5T2JqZWN0ICphcmdzX2lnbm9yZWQpCit7CisgICAgUHlPYmplY3QgKmxpc3QsICpyYXcsICpyZWY7CisgICAgUHlfc3NpemVfdCBpLCBuOworCisgICAgbGlzdCA9IFB5TGlzdF9OZXcoMCk7CisgICAgaWYgKGxpc3QgPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgcmF3ID0gdHlwZS0+dHBfc3ViY2xhc3NlczsKKyAgICBpZiAocmF3ID09IE5VTEwpCisgICAgICAgIHJldHVybiBsaXN0OworICAgIGFzc2VydChQeUxpc3RfQ2hlY2socmF3KSk7CisgICAgbiA9IFB5TGlzdF9HRVRfU0laRShyYXcpOworICAgIGZvciAoaSA9IDA7IGkgPCBuOyBpKyspIHsKKyAgICAgICAgcmVmID0gUHlMaXN0X0dFVF9JVEVNKHJhdywgaSk7CisgICAgICAgIGFzc2VydChQeVdlYWtyZWZfQ2hlY2tSZWYocmVmKSk7CisgICAgICAgIHJlZiA9IFB5V2Vha3JlZl9HRVRfT0JKRUNUKHJlZik7CisgICAgICAgIGlmIChyZWYgIT0gUHlfTm9uZSkgeworICAgICAgICAgICAgaWYgKFB5TGlzdF9BcHBlbmQobGlzdCwgcmVmKSA8IDApIHsKKyAgICAgICAgICAgICAgICBQeV9ERUNSRUYobGlzdCk7CisgICAgICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisgICAgcmV0dXJuIGxpc3Q7Cit9CisKK3N0YXRpYyBQeU1ldGhvZERlZiB0eXBlX21ldGhvZHNbXSA9IHsKKyAgICB7Im1ybyIsIChQeUNGdW5jdGlvbiltcm9fZXh0ZXJuYWwsIE1FVEhfTk9BUkdTLAorICAgICBQeURvY19TVFIoIm1ybygpIC0+IGxpc3RcbnJldHVybiBhIHR5cGUncyBtZXRob2QgcmVzb2x1dGlvbiBvcmRlciIpfSwKKyAgICB7Il9fc3ViY2xhc3Nlc19fIiwgKFB5Q0Z1bmN0aW9uKXR5cGVfc3ViY2xhc3NlcywgTUVUSF9OT0FSR1MsCisgICAgIFB5RG9jX1NUUigiX19zdWJjbGFzc2VzX18oKSAtPiBsaXN0IG9mIGltbWVkaWF0ZSBzdWJjbGFzc2VzIil9LAorICAgIHsiX19pbnN0YW5jZWNoZWNrX18iLCB0eXBlX19faW5zdGFuY2VjaGVja19fLCBNRVRIX08sCisgICAgIFB5RG9jX1NUUigiX19pbnN0YW5jZWNoZWNrX18oKSAtPiBib29sXG5jaGVjayBpZiBhbiBvYmplY3QgaXMgYW4gaW5zdGFuY2UiKX0sCisgICAgeyJfX3N1YmNsYXNzY2hlY2tfXyIsIHR5cGVfX19zdWJjbGFzc2NoZWNrX18sIE1FVEhfTywKKyAgICAgUHlEb2NfU1RSKCJfX3N1YmNsYXNzY2hlY2tfXygpIC0+IGJvb2xcbmNoZWNrIGlmIGEgY2xhc3MgaXMgYSBzdWJjbGFzcyIpfSwKKyAgICB7MH0KK307CisKK1B5RG9jX1NUUlZBUih0eXBlX2RvYywKKyJ0eXBlKG9iamVjdCkgLT4gdGhlIG9iamVjdCdzIHR5cGVcbiIKKyJ0eXBlKG5hbWUsIGJhc2VzLCBkaWN0KSAtPiBhIG5ldyB0eXBlIik7CisKK3N0YXRpYyBpbnQKK3R5cGVfdHJhdmVyc2UoUHlUeXBlT2JqZWN0ICp0eXBlLCB2aXNpdHByb2MgdmlzaXQsIHZvaWQgKmFyZykKK3sKKyAgICAvKiBCZWNhdXNlIG9mIHR5cGVfaXNfZ2MoKSwgdGhlIGNvbGxlY3RvciBvbmx5IGNhbGxzIHRoaXMKKyAgICAgICBmb3IgaGVhcHR5cGVzLiAqLworICAgIGFzc2VydCh0eXBlLT50cF9mbGFncyAmIFB5X1RQRkxBR1NfSEVBUFRZUEUpOworCisgICAgUHlfVklTSVQodHlwZS0+dHBfZGljdCk7CisgICAgUHlfVklTSVQodHlwZS0+dHBfY2FjaGUpOworICAgIFB5X1ZJU0lUKHR5cGUtPnRwX21ybyk7CisgICAgUHlfVklTSVQodHlwZS0+dHBfYmFzZXMpOworICAgIFB5X1ZJU0lUKHR5cGUtPnRwX2Jhc2UpOworCisgICAgLyogVGhlcmUncyBubyBuZWVkIHRvIHZpc2l0IHR5cGUtPnRwX3N1YmNsYXNzZXMgb3IKKyAgICAgICAoKFB5SGVhcFR5cGVPYmplY3QgKil0eXBlKS0+aHRfc2xvdHMsIGJlY2F1c2UgdGhleSBjYW4ndCBiZSBpbnZvbHZlZAorICAgICAgIGluIGN5Y2xlczsgdHBfc3ViY2xhc3NlcyBpcyBhIGxpc3Qgb2Ygd2VhayByZWZlcmVuY2VzLAorICAgICAgIGFuZCBzbG90cyBpcyBhIHR1cGxlIG9mIHN0cmluZ3MuICovCisKKyAgICByZXR1cm4gMDsKK30KKworc3RhdGljIGludAordHlwZV9jbGVhcihQeVR5cGVPYmplY3QgKnR5cGUpCit7CisgICAgLyogQmVjYXVzZSBvZiB0eXBlX2lzX2djKCksIHRoZSBjb2xsZWN0b3Igb25seSBjYWxscyB0aGlzCisgICAgICAgZm9yIGhlYXB0eXBlcy4gKi8KKyAgICBhc3NlcnQodHlwZS0+dHBfZmxhZ3MgJiBQeV9UUEZMQUdTX0hFQVBUWVBFKTsKKworICAgIC8qIFdlIG5lZWQgdG8gaW52YWxpZGF0ZSB0aGUgbWV0aG9kIGNhY2hlIGNhcmVmdWxseSBiZWZvcmUgY2xlYXJpbmcKKyAgICAgICB0aGUgZGljdCwgc28gdGhhdCBvdGhlciBvYmplY3RzIGNhdWdodCBpbiBhIHJlZmVyZW5jZSBjeWNsZQorICAgICAgIGRvbid0IHN0YXJ0IGNhbGxpbmcgZGVzdHJveWVkIG1ldGhvZHMuCisKKyAgICAgICBPdGhlcndpc2UsIHRoZSBvbmx5IGZpZWxkIHdlIG5lZWQgdG8gY2xlYXIgaXMgdHBfbXJvLCB3aGljaCBpcworICAgICAgIHBhcnQgb2YgYSBoYXJkIGN5Y2xlIChpdHMgZmlyc3QgZWxlbWVudCBpcyB0aGUgY2xhc3MgaXRzZWxmKSB0aGF0CisgICAgICAgd29uJ3QgYmUgYnJva2VuIG90aGVyd2lzZSAoaXQncyBhIHR1cGxlIGFuZCB0dXBsZXMgZG9uJ3QgaGF2ZSBhCisgICAgICAgdHBfY2xlYXIgaGFuZGxlcikuICBOb25lIG9mIHRoZSBvdGhlciBmaWVsZHMgbmVlZCB0byBiZQorICAgICAgIGNsZWFyZWQsIGFuZCBoZXJlJ3Mgd2h5OgorCisgICAgICAgdHBfY2FjaGU6CisgICAgICAgICAgIE5vdCB1c2VkOyBpZiBpdCB3ZXJlLCBpdCB3b3VsZCBiZSBhIGRpY3QuCisKKyAgICAgICB0cF9iYXNlcywgdHBfYmFzZToKKyAgICAgICAgICAgSWYgdGhlc2UgYXJlIGludm9sdmVkIGluIGEgY3ljbGUsIHRoZXJlIG11c3QgYmUgYXQgbGVhc3QKKyAgICAgICAgICAgb25lIG90aGVyLCBtdXRhYmxlIG9iamVjdCBpbiB0aGUgY3ljbGUsIGUuZy4gYSBiYXNlCisgICAgICAgICAgIGNsYXNzJ3MgZGljdDsgdGhlIGN5Y2xlIHdpbGwgYmUgYnJva2VuIHRoYXQgd2F5LgorCisgICAgICAgdHBfc3ViY2xhc3NlczoKKyAgICAgICAgICAgQSBsaXN0IG9mIHdlYWsgcmVmZXJlbmNlcyBjYW4ndCBiZSBwYXJ0IG9mIGEgY3ljbGU7IGFuZAorICAgICAgICAgICBsaXN0cyBoYXZlIHRoZWlyIG93biB0cF9jbGVhci4KKworICAgICAgIHNsb3RzIChpbiBQeUhlYXBUeXBlT2JqZWN0KToKKyAgICAgICAgICAgQSB0dXBsZSBvZiBzdHJpbmdzIGNhbid0IGJlIHBhcnQgb2YgYSBjeWNsZS4KKyAgICAqLworCisgICAgUHlUeXBlX01vZGlmaWVkKHR5cGUpOworICAgIGlmICh0eXBlLT50cF9kaWN0KQorICAgICAgICBQeURpY3RfQ2xlYXIodHlwZS0+dHBfZGljdCk7CisgICAgUHlfQ0xFQVIodHlwZS0+dHBfbXJvKTsKKworICAgIHJldHVybiAwOworfQorCitzdGF0aWMgaW50Cit0eXBlX2lzX2djKFB5VHlwZU9iamVjdCAqdHlwZSkKK3sKKyAgICByZXR1cm4gdHlwZS0+dHBfZmxhZ3MgJiBQeV9UUEZMQUdTX0hFQVBUWVBFOworfQorCitQeVR5cGVPYmplY3QgUHlUeXBlX1R5cGUgPSB7CisgICAgUHlWYXJPYmplY3RfSEVBRF9JTklUKCZQeVR5cGVfVHlwZSwgMCkKKyAgICAidHlwZSIsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX25hbWUgKi8KKyAgICBzaXplb2YoUHlIZWFwVHlwZU9iamVjdCksICAgICAgICAgICAgICAgICAgIC8qIHRwX2Jhc2ljc2l6ZSAqLworICAgIHNpemVvZihQeU1lbWJlckRlZiksICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfaXRlbXNpemUgKi8KKyAgICAoZGVzdHJ1Y3Rvcil0eXBlX2RlYWxsb2MsICAgICAgICAgICAgICAgICAgIC8qIHRwX2RlYWxsb2MgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3ByaW50ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9nZXRhdHRyICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9zZXRhdHRyICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfY29tcGFyZSAqLworICAgIChyZXByZnVuYyl0eXBlX3JlcHIsICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfcmVwciAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfYXNfbnVtYmVyICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9hc19zZXF1ZW5jZSAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfYXNfbWFwcGluZyAqLworICAgIChoYXNoZnVuYylfUHlfSGFzaFBvaW50ZXIsICAgICAgICAgICAgICAgICAgLyogdHBfaGFzaCAqLworICAgICh0ZXJuYXJ5ZnVuYyl0eXBlX2NhbGwsICAgICAgICAgICAgICAgICAgICAgLyogdHBfY2FsbCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfc3RyICovCisgICAgKGdldGF0dHJvZnVuYyl0eXBlX2dldGF0dHJvLCAgICAgICAgICAgICAgICAvKiB0cF9nZXRhdHRybyAqLworICAgIChzZXRhdHRyb2Z1bmMpdHlwZV9zZXRhdHRybywgICAgICAgICAgICAgICAgLyogdHBfc2V0YXR0cm8gKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2FzX2J1ZmZlciAqLworICAgIFB5X1RQRkxBR1NfREVGQVVMVCB8IFB5X1RQRkxBR1NfSEFWRV9HQyB8CisgICAgICAgIFB5X1RQRkxBR1NfQkFTRVRZUEUgfCBQeV9UUEZMQUdTX1RZUEVfU1VCQ0xBU1MsICAgICAgICAgLyogdHBfZmxhZ3MgKi8KKyAgICB0eXBlX2RvYywgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2RvYyAqLworICAgICh0cmF2ZXJzZXByb2MpdHlwZV90cmF2ZXJzZSwgICAgICAgICAgICAgICAgLyogdHBfdHJhdmVyc2UgKi8KKyAgICAoaW5xdWlyeSl0eXBlX2NsZWFyLCAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2NsZWFyICovCisgICAgdHlwZV9yaWNoY29tcGFyZSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfcmljaGNvbXBhcmUgKi8KKyAgICBvZmZzZXRvZihQeVR5cGVPYmplY3QsIHRwX3dlYWtsaXN0KSwgICAgICAgIC8qIHRwX3dlYWtsaXN0b2Zmc2V0ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9pdGVyICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9pdGVybmV4dCAqLworICAgIHR5cGVfbWV0aG9kcywgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfbWV0aG9kcyAqLworICAgIHR5cGVfbWVtYmVycywgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfbWVtYmVycyAqLworICAgIHR5cGVfZ2V0c2V0cywgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZ2V0c2V0ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9iYXNlICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9kaWN0ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9kZXNjcl9nZXQgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2Rlc2NyX3NldCAqLworICAgIG9mZnNldG9mKFB5VHlwZU9iamVjdCwgdHBfZGljdCksICAgICAgICAgICAgLyogdHBfZGljdG9mZnNldCAqLworICAgIHR5cGVfaW5pdCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfaW5pdCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfYWxsb2MgKi8KKyAgICB0eXBlX25ldywgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX25ldyAqLworICAgIFB5T2JqZWN0X0dDX0RlbCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZnJlZSAqLworICAgIChpbnF1aXJ5KXR5cGVfaXNfZ2MsICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfaXNfZ2MgKi8KK307CisKKworLyogVGhlIGJhc2UgdHlwZSBvZiBhbGwgdHlwZXMgKGV2ZW50dWFsbHkpLi4uIGV4Y2VwdCBpdHNlbGYuICovCisKKy8qIFlvdSBtYXkgd29uZGVyIHdoeSBvYmplY3QuX19uZXdfXygpIG9ubHkgY29tcGxhaW5zIGFib3V0IGFyZ3VtZW50cworICAgd2hlbiBvYmplY3QuX19pbml0X18oKSBpcyBub3Qgb3ZlcnJpZGRlbiwgYW5kIHZpY2UgdmVyc2EuCisKKyAgIENvbnNpZGVyIHRoZSB1c2UgY2FzZXM6CisKKyAgIDEuIFdoZW4gbmVpdGhlciBpcyBvdmVycmlkZGVuLCB3ZSB3YW50IHRvIGhlYXIgY29tcGxhaW50cyBhYm91dAorICAgICAgZXhjZXNzIChpLmUuLCBhbnkpIGFyZ3VtZW50cywgc2luY2UgdGhlaXIgcHJlc2VuY2UgY291bGQKKyAgICAgIGluZGljYXRlIHRoZXJlJ3MgYSBidWcuCisKKyAgIDIuIFdoZW4gZGVmaW5pbmcgYW4gSW1tdXRhYmxlIHR5cGUsIHdlIGFyZSBsaWtlbHkgdG8gb3ZlcnJpZGUgb25seQorICAgICAgX19uZXdfXygpLCBzaW5jZSBfX2luaXRfXygpIGlzIGNhbGxlZCB0b28gbGF0ZSB0byBpbml0aWFsaXplIGFuCisgICAgICBJbW11dGFibGUgb2JqZWN0LiAgU2luY2UgX19uZXdfXygpIGRlZmluZXMgdGhlIHNpZ25hdHVyZSBmb3IgdGhlCisgICAgICB0eXBlLCBpdCB3b3VsZCBiZSBhIHBhaW4gdG8gaGF2ZSB0byBvdmVycmlkZSBfX2luaXRfXygpIGp1c3QgdG8KKyAgICAgIHN0b3AgaXQgZnJvbSBjb21wbGFpbmluZyBhYm91dCBleGNlc3MgYXJndW1lbnRzLgorCisgICAzLiBXaGVuIGRlZmluaW5nIGEgTXV0YWJsZSB0eXBlLCB3ZSBhcmUgbGlrZWx5IHRvIG92ZXJyaWRlIG9ubHkKKyAgICAgIF9faW5pdF9fKCkuICBTbyBoZXJlIHRoZSBjb252ZXJzZSByZWFzb25pbmcgYXBwbGllczogd2UgZG9uJ3QKKyAgICAgIHdhbnQgdG8gaGF2ZSB0byBvdmVycmlkZSBfX25ld19fKCkganVzdCB0byBzdG9wIGl0IGZyb20KKyAgICAgIGNvbXBsYWluaW5nLgorCisgICA0LiBXaGVuIF9faW5pdF9fKCkgaXMgb3ZlcnJpZGRlbiwgYW5kIHRoZSBzdWJjbGFzcyBfX2luaXRfXygpIGNhbGxzCisgICAgICBvYmplY3QuX19pbml0X18oKSwgdGhlIGxhdHRlciBzaG91bGQgY29tcGxhaW4gYWJvdXQgZXhjZXNzCisgICAgICBhcmd1bWVudHM7IGRpdHRvIGZvciBfX25ld19fKCkuCisKKyAgIFVzZSBjYXNlcyAyIGFuZCAzIG1ha2UgaXQgdW5hdHRyYWN0aXZlIHRvIHVuY29uZGl0aW9uYWxseSBjaGVjayBmb3IKKyAgIGV4Y2VzcyBhcmd1bWVudHMuICBUaGUgYmVzdCBzb2x1dGlvbiB0aGF0IGFkZHJlc3NlcyBhbGwgZm91ciB1c2UKKyAgIGNhc2VzIGlzIGFzIGZvbGxvd3M6IF9faW5pdF9fKCkgY29tcGxhaW5zIGFib3V0IGV4Y2VzcyBhcmd1bWVudHMKKyAgIHVubGVzcyBfX25ld19fKCkgaXMgb3ZlcnJpZGRlbiBhbmQgX19pbml0X18oKSBpcyBub3Qgb3ZlcnJpZGRlbgorICAgKElPVywgaWYgX19pbml0X18oKSBpcyBvdmVycmlkZGVuIG9yIF9fbmV3X18oKSBpcyBub3Qgb3ZlcnJpZGRlbik7CisgICBzeW1tZXRyaWNhbGx5LCBfX25ld19fKCkgY29tcGxhaW5zIGFib3V0IGV4Y2VzcyBhcmd1bWVudHMgdW5sZXNzCisgICBfX2luaXRfXygpIGlzIG92ZXJyaWRkZW4gYW5kIF9fbmV3X18oKSBpcyBub3Qgb3ZlcnJpZGRlbgorICAgKElPVywgaWYgX19uZXdfXygpIGlzIG92ZXJyaWRkZW4gb3IgX19pbml0X18oKSBpcyBub3Qgb3ZlcnJpZGRlbikuCisKKyAgIEhvd2V2ZXIsIGZvciBiYWNrd2FyZHMgY29tcGF0aWJpbGl0eSwgdGhpcyBicmVha3MgdG9vIG11Y2ggY29kZS4KKyAgIFRoZXJlZm9yZSwgaW4gMi42LCB3ZSdsbCAqd2FybiogYWJvdXQgZXhjZXNzIGFyZ3VtZW50cyB3aGVuIGJvdGgKKyAgIG1ldGhvZHMgYXJlIG92ZXJyaWRkZW47IGZvciBhbGwgb3RoZXIgY2FzZXMgd2UnbGwgdXNlIHRoZSBhYm92ZQorICAgcnVsZXMuCisKKyovCisKKy8qIEZvcndhcmQgKi8KK3N0YXRpYyBQeU9iamVjdCAqCitvYmplY3RfbmV3KFB5VHlwZU9iamVjdCAqdHlwZSwgUHlPYmplY3QgKmFyZ3MsIFB5T2JqZWN0ICprd2RzKTsKKworc3RhdGljIGludAorZXhjZXNzX2FyZ3MoUHlPYmplY3QgKmFyZ3MsIFB5T2JqZWN0ICprd2RzKQoreworICAgIHJldHVybiBQeVR1cGxlX0dFVF9TSVpFKGFyZ3MpIHx8CisgICAgICAgIChrd2RzICYmIFB5RGljdF9DaGVjayhrd2RzKSAmJiBQeURpY3RfU2l6ZShrd2RzKSk7Cit9CisKK3N0YXRpYyBpbnQKK29iamVjdF9pbml0KFB5T2JqZWN0ICpzZWxmLCBQeU9iamVjdCAqYXJncywgUHlPYmplY3QgKmt3ZHMpCit7CisgICAgaW50IGVyciA9IDA7CisgICAgaWYgKGV4Y2Vzc19hcmdzKGFyZ3MsIGt3ZHMpKSB7CisgICAgICAgIFB5VHlwZU9iamVjdCAqdHlwZSA9IFB5X1RZUEUoc2VsZik7CisgICAgICAgIGlmICh0eXBlLT50cF9pbml0ICE9IG9iamVjdF9pbml0ICYmCisgICAgICAgICAgICB0eXBlLT50cF9uZXcgIT0gb2JqZWN0X25ldykKKyAgICAgICAgeworICAgICAgICAgICAgZXJyID0gUHlFcnJfV2FybkV4KFB5RXhjX0RlcHJlY2F0aW9uV2FybmluZywKKyAgICAgICAgICAgICAgICAgICAgICAgIm9iamVjdC5fX2luaXRfXygpIHRha2VzIG5vIHBhcmFtZXRlcnMiLAorICAgICAgICAgICAgICAgICAgICAgICAxKTsKKyAgICAgICAgfQorICAgICAgICBlbHNlIGlmICh0eXBlLT50cF9pbml0ICE9IG9iamVjdF9pbml0IHx8CisgICAgICAgICAgICAgICAgIHR5cGUtPnRwX25ldyA9PSBvYmplY3RfbmV3KQorICAgICAgICB7CisgICAgICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfVHlwZUVycm9yLAorICAgICAgICAgICAgICAgICJvYmplY3QuX19pbml0X18oKSB0YWtlcyBubyBwYXJhbWV0ZXJzIik7CisgICAgICAgICAgICBlcnIgPSAtMTsKKyAgICAgICAgfQorICAgIH0KKyAgICByZXR1cm4gZXJyOworfQorCitzdGF0aWMgUHlPYmplY3QgKgorb2JqZWN0X25ldyhQeVR5cGVPYmplY3QgKnR5cGUsIFB5T2JqZWN0ICphcmdzLCBQeU9iamVjdCAqa3dkcykKK3sKKyAgICBpbnQgZXJyID0gMDsKKyAgICBpZiAoZXhjZXNzX2FyZ3MoYXJncywga3dkcykpIHsKKyAgICAgICAgaWYgKHR5cGUtPnRwX25ldyAhPSBvYmplY3RfbmV3ICYmCisgICAgICAgICAgICB0eXBlLT50cF9pbml0ICE9IG9iamVjdF9pbml0KQorICAgICAgICB7CisgICAgICAgICAgICBlcnIgPSBQeUVycl9XYXJuRXgoUHlFeGNfRGVwcmVjYXRpb25XYXJuaW5nLAorICAgICAgICAgICAgICAgICAgICAgICAib2JqZWN0KCkgdGFrZXMgbm8gcGFyYW1ldGVycyIsCisgICAgICAgICAgICAgICAgICAgICAgIDEpOworICAgICAgICB9CisgICAgICAgIGVsc2UgaWYgKHR5cGUtPnRwX25ldyAhPSBvYmplY3RfbmV3IHx8CisgICAgICAgICAgICAgICAgIHR5cGUtPnRwX2luaXQgPT0gb2JqZWN0X2luaXQpCisgICAgICAgIHsKKyAgICAgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19UeXBlRXJyb3IsCisgICAgICAgICAgICAgICAgIm9iamVjdCgpIHRha2VzIG5vIHBhcmFtZXRlcnMiKTsKKyAgICAgICAgICAgIGVyciA9IC0xOworICAgICAgICB9CisgICAgfQorICAgIGlmIChlcnIgPCAwKQorICAgICAgICByZXR1cm4gTlVMTDsKKworICAgIGlmICh0eXBlLT50cF9mbGFncyAmIFB5X1RQRkxBR1NfSVNfQUJTVFJBQ1QpIHsKKyAgICAgICAgc3RhdGljIFB5T2JqZWN0ICpjb21tYSA9IE5VTEw7CisgICAgICAgIFB5T2JqZWN0ICphYnN0cmFjdF9tZXRob2RzID0gTlVMTDsKKyAgICAgICAgUHlPYmplY3QgKmJ1aWx0aW5zOworICAgICAgICBQeU9iamVjdCAqc29ydGVkOworICAgICAgICBQeU9iamVjdCAqc29ydGVkX21ldGhvZHMgPSBOVUxMOworICAgICAgICBQeU9iamVjdCAqam9pbmVkID0gTlVMTDsKKyAgICAgICAgY29uc3QgY2hhciAqam9pbmVkX3N0cjsKKworICAgICAgICAvKiBDb21wdXRlICIsICIuam9pbihzb3J0ZWQodHlwZS5fX2Fic3RyYWN0bWV0aG9kc19fKSkKKyAgICAgICAgICAgaW50byBqb2luZWQuICovCisgICAgICAgIGFic3RyYWN0X21ldGhvZHMgPSB0eXBlX2Fic3RyYWN0bWV0aG9kcyh0eXBlLCBOVUxMKTsKKyAgICAgICAgaWYgKGFic3RyYWN0X21ldGhvZHMgPT0gTlVMTCkKKyAgICAgICAgICAgIGdvdG8gZXJyb3I7CisgICAgICAgIGJ1aWx0aW5zID0gUHlFdmFsX0dldEJ1aWx0aW5zKCk7CisgICAgICAgIGlmIChidWlsdGlucyA9PSBOVUxMKQorICAgICAgICAgICAgZ290byBlcnJvcjsKKyAgICAgICAgc29ydGVkID0gUHlEaWN0X0dldEl0ZW1TdHJpbmcoYnVpbHRpbnMsICJzb3J0ZWQiKTsKKyAgICAgICAgaWYgKHNvcnRlZCA9PSBOVUxMKQorICAgICAgICAgICAgZ290byBlcnJvcjsKKyAgICAgICAgc29ydGVkX21ldGhvZHMgPSBQeU9iamVjdF9DYWxsRnVuY3Rpb25PYmpBcmdzKHNvcnRlZCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFic3RyYWN0X21ldGhvZHMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOVUxMKTsKKyAgICAgICAgaWYgKHNvcnRlZF9tZXRob2RzID09IE5VTEwpCisgICAgICAgICAgICBnb3RvIGVycm9yOworICAgICAgICBpZiAoY29tbWEgPT0gTlVMTCkgeworICAgICAgICAgICAgY29tbWEgPSBQeVN0cmluZ19JbnRlcm5Gcm9tU3RyaW5nKCIsICIpOworICAgICAgICAgICAgaWYgKGNvbW1hID09IE5VTEwpCisgICAgICAgICAgICAgICAgZ290byBlcnJvcjsKKyAgICAgICAgfQorICAgICAgICBqb2luZWQgPSBQeU9iamVjdF9DYWxsTWV0aG9kKGNvbW1hLCAiam9pbiIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIk8iLCAgc29ydGVkX21ldGhvZHMpOworICAgICAgICBpZiAoam9pbmVkID09IE5VTEwpCisgICAgICAgICAgICBnb3RvIGVycm9yOworICAgICAgICBqb2luZWRfc3RyID0gUHlTdHJpbmdfQXNTdHJpbmcoam9pbmVkKTsKKyAgICAgICAgaWYgKGpvaW5lZF9zdHIgPT0gTlVMTCkKKyAgICAgICAgICAgIGdvdG8gZXJyb3I7CisKKyAgICAgICAgUHlFcnJfRm9ybWF0KFB5RXhjX1R5cGVFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICJDYW4ndCBpbnN0YW50aWF0ZSBhYnN0cmFjdCBjbGFzcyAlcyAiCisgICAgICAgICAgICAgICAgICAgICAid2l0aCBhYnN0cmFjdCBtZXRob2RzICVzIiwKKyAgICAgICAgICAgICAgICAgICAgIHR5cGUtPnRwX25hbWUsCisgICAgICAgICAgICAgICAgICAgICBqb2luZWRfc3RyKTsKKyAgICBlcnJvcjoKKyAgICAgICAgUHlfWERFQ1JFRihqb2luZWQpOworICAgICAgICBQeV9YREVDUkVGKHNvcnRlZF9tZXRob2RzKTsKKyAgICAgICAgUHlfWERFQ1JFRihhYnN0cmFjdF9tZXRob2RzKTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIHJldHVybiB0eXBlLT50cF9hbGxvYyh0eXBlLCAwKTsKK30KKworc3RhdGljIHZvaWQKK29iamVjdF9kZWFsbG9jKFB5T2JqZWN0ICpzZWxmKQoreworICAgIFB5X1RZUEUoc2VsZiktPnRwX2ZyZWUoc2VsZik7Cit9CisKK3N0YXRpYyBQeU9iamVjdCAqCitvYmplY3RfcmVwcihQeU9iamVjdCAqc2VsZikKK3sKKyAgICBQeVR5cGVPYmplY3QgKnR5cGU7CisgICAgUHlPYmplY3QgKm1vZCwgKm5hbWUsICpydG47CisKKyAgICB0eXBlID0gUHlfVFlQRShzZWxmKTsKKyAgICBtb2QgPSB0eXBlX21vZHVsZSh0eXBlLCBOVUxMKTsKKyAgICBpZiAobW9kID09IE5VTEwpCisgICAgICAgIFB5RXJyX0NsZWFyKCk7CisgICAgZWxzZSBpZiAoIVB5U3RyaW5nX0NoZWNrKG1vZCkpIHsKKyAgICAgICAgUHlfREVDUkVGKG1vZCk7CisgICAgICAgIG1vZCA9IE5VTEw7CisgICAgfQorICAgIG5hbWUgPSB0eXBlX25hbWUodHlwZSwgTlVMTCk7CisgICAgaWYgKG5hbWUgPT0gTlVMTCkgeworICAgICAgICBQeV9YREVDUkVGKG1vZCk7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICBpZiAobW9kICE9IE5VTEwgJiYgc3RyY21wKFB5U3RyaW5nX0FTX1NUUklORyhtb2QpLCAiX19idWlsdGluX18iKSkKKyAgICAgICAgcnRuID0gUHlTdHJpbmdfRnJvbUZvcm1hdCgiPCVzLiVzIG9iamVjdCBhdCAlcD4iLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFB5U3RyaW5nX0FTX1NUUklORyhtb2QpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFB5U3RyaW5nX0FTX1NUUklORyhuYW1lKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmKTsKKyAgICBlbHNlCisgICAgICAgIHJ0biA9IFB5U3RyaW5nX0Zyb21Gb3JtYXQoIjwlcyBvYmplY3QgYXQgJXA+IiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlLT50cF9uYW1lLCBzZWxmKTsKKyAgICBQeV9YREVDUkVGKG1vZCk7CisgICAgUHlfREVDUkVGKG5hbWUpOworICAgIHJldHVybiBydG47Cit9CisKK3N0YXRpYyBQeU9iamVjdCAqCitvYmplY3Rfc3RyKFB5T2JqZWN0ICpzZWxmKQoreworICAgIHVuYXJ5ZnVuYyBmOworCisgICAgZiA9IFB5X1RZUEUoc2VsZiktPnRwX3JlcHI7CisgICAgaWYgKGYgPT0gTlVMTCkKKyAgICAgICAgZiA9IG9iamVjdF9yZXByOworICAgIHJldHVybiBmKHNlbGYpOworfQorCitzdGF0aWMgUHlPYmplY3QgKgorb2JqZWN0X2dldF9jbGFzcyhQeU9iamVjdCAqc2VsZiwgdm9pZCAqY2xvc3VyZSkKK3sKKyAgICBQeV9JTkNSRUYoUHlfVFlQRShzZWxmKSk7CisgICAgcmV0dXJuIChQeU9iamVjdCAqKShQeV9UWVBFKHNlbGYpKTsKK30KKworc3RhdGljIGludAorZXF1aXZfc3RydWN0cyhQeVR5cGVPYmplY3QgKmEsIFB5VHlwZU9iamVjdCAqYikKK3sKKyAgICByZXR1cm4gYSA9PSBiIHx8CisgICAgICAgICAgIChhICE9IE5VTEwgJiYKKyAgICAgICAgYiAhPSBOVUxMICYmCisgICAgICAgIGEtPnRwX2Jhc2ljc2l6ZSA9PSBiLT50cF9iYXNpY3NpemUgJiYKKyAgICAgICAgYS0+dHBfaXRlbXNpemUgPT0gYi0+dHBfaXRlbXNpemUgJiYKKyAgICAgICAgYS0+dHBfZGljdG9mZnNldCA9PSBiLT50cF9kaWN0b2Zmc2V0ICYmCisgICAgICAgIGEtPnRwX3dlYWtsaXN0b2Zmc2V0ID09IGItPnRwX3dlYWtsaXN0b2Zmc2V0ICYmCisgICAgICAgICgoYS0+dHBfZmxhZ3MgJiBQeV9UUEZMQUdTX0hBVkVfR0MpID09CisgICAgICAgICAoYi0+dHBfZmxhZ3MgJiBQeV9UUEZMQUdTX0hBVkVfR0MpKSk7Cit9CisKK3N0YXRpYyBpbnQKK3NhbWVfc2xvdHNfYWRkZWQoUHlUeXBlT2JqZWN0ICphLCBQeVR5cGVPYmplY3QgKmIpCit7CisgICAgUHlUeXBlT2JqZWN0ICpiYXNlID0gYS0+dHBfYmFzZTsKKyAgICBQeV9zc2l6ZV90IHNpemU7CisgICAgUHlPYmplY3QgKnNsb3RzX2EsICpzbG90c19iOworCisgICAgYXNzZXJ0KGJhc2UgPT0gYi0+dHBfYmFzZSk7CisgICAgc2l6ZSA9IGJhc2UtPnRwX2Jhc2ljc2l6ZTsKKyAgICBpZiAoYS0+dHBfZGljdG9mZnNldCA9PSBzaXplICYmIGItPnRwX2RpY3RvZmZzZXQgPT0gc2l6ZSkKKyAgICAgICAgc2l6ZSArPSBzaXplb2YoUHlPYmplY3QgKik7CisgICAgaWYgKGEtPnRwX3dlYWtsaXN0b2Zmc2V0ID09IHNpemUgJiYgYi0+dHBfd2Vha2xpc3RvZmZzZXQgPT0gc2l6ZSkKKyAgICAgICAgc2l6ZSArPSBzaXplb2YoUHlPYmplY3QgKik7CisKKyAgICAvKiBDaGVjayBzbG90cyBjb21wbGlhbmNlICovCisgICAgc2xvdHNfYSA9ICgoUHlIZWFwVHlwZU9iamVjdCAqKWEpLT5odF9zbG90czsKKyAgICBzbG90c19iID0gKChQeUhlYXBUeXBlT2JqZWN0ICopYiktPmh0X3Nsb3RzOworICAgIGlmIChzbG90c19hICYmIHNsb3RzX2IpIHsKKyAgICAgICAgaWYgKFB5T2JqZWN0X0NvbXBhcmUoc2xvdHNfYSwgc2xvdHNfYikgIT0gMCkKKyAgICAgICAgICAgIHJldHVybiAwOworICAgICAgICBzaXplICs9IHNpemVvZihQeU9iamVjdCAqKSAqIFB5VHVwbGVfR0VUX1NJWkUoc2xvdHNfYSk7CisgICAgfQorICAgIHJldHVybiBzaXplID09IGEtPnRwX2Jhc2ljc2l6ZSAmJiBzaXplID09IGItPnRwX2Jhc2ljc2l6ZTsKK30KKworc3RhdGljIGludAorY29tcGF0aWJsZV9mb3JfYXNzaWdubWVudChQeVR5cGVPYmplY3QqIG9sZHRvLCBQeVR5cGVPYmplY3QqIG5ld3RvLCBjaGFyKiBhdHRyKQoreworICAgIFB5VHlwZU9iamVjdCAqbmV3YmFzZSwgKm9sZGJhc2U7CisKKyAgICBpZiAobmV3dG8tPnRwX2RlYWxsb2MgIT0gb2xkdG8tPnRwX2RlYWxsb2MgfHwKKyAgICAgICAgbmV3dG8tPnRwX2ZyZWUgIT0gb2xkdG8tPnRwX2ZyZWUpCisgICAgeworICAgICAgICBQeUVycl9Gb3JtYXQoUHlFeGNfVHlwZUVycm9yLAorICAgICAgICAgICAgICAgICAgICAgIiVzIGFzc2lnbm1lbnQ6ICIKKyAgICAgICAgICAgICAgICAgICAgICInJXMnIGRlYWxsb2NhdG9yIGRpZmZlcnMgZnJvbSAnJXMnIiwKKyAgICAgICAgICAgICAgICAgICAgIGF0dHIsCisgICAgICAgICAgICAgICAgICAgICBuZXd0by0+dHBfbmFtZSwKKyAgICAgICAgICAgICAgICAgICAgIG9sZHRvLT50cF9uYW1lKTsKKyAgICAgICAgcmV0dXJuIDA7CisgICAgfQorICAgIG5ld2Jhc2UgPSBuZXd0bzsKKyAgICBvbGRiYXNlID0gb2xkdG87CisgICAgd2hpbGUgKGVxdWl2X3N0cnVjdHMobmV3YmFzZSwgbmV3YmFzZS0+dHBfYmFzZSkpCisgICAgICAgIG5ld2Jhc2UgPSBuZXdiYXNlLT50cF9iYXNlOworICAgIHdoaWxlIChlcXVpdl9zdHJ1Y3RzKG9sZGJhc2UsIG9sZGJhc2UtPnRwX2Jhc2UpKQorICAgICAgICBvbGRiYXNlID0gb2xkYmFzZS0+dHBfYmFzZTsKKyAgICBpZiAobmV3YmFzZSAhPSBvbGRiYXNlICYmCisgICAgICAgIChuZXdiYXNlLT50cF9iYXNlICE9IG9sZGJhc2UtPnRwX2Jhc2UgfHwKKyAgICAgICAgICFzYW1lX3Nsb3RzX2FkZGVkKG5ld2Jhc2UsIG9sZGJhc2UpKSkgeworICAgICAgICBQeUVycl9Gb3JtYXQoUHlFeGNfVHlwZUVycm9yLAorICAgICAgICAgICAgICAgICAgICAgIiVzIGFzc2lnbm1lbnQ6ICIKKyAgICAgICAgICAgICAgICAgICAgICInJXMnIG9iamVjdCBsYXlvdXQgZGlmZmVycyBmcm9tICclcyciLAorICAgICAgICAgICAgICAgICAgICAgYXR0ciwKKyAgICAgICAgICAgICAgICAgICAgIG5ld3RvLT50cF9uYW1lLAorICAgICAgICAgICAgICAgICAgICAgb2xkdG8tPnRwX25hbWUpOworICAgICAgICByZXR1cm4gMDsKKyAgICB9CisKKyAgICByZXR1cm4gMTsKK30KKworc3RhdGljIGludAorb2JqZWN0X3NldF9jbGFzcyhQeU9iamVjdCAqc2VsZiwgUHlPYmplY3QgKnZhbHVlLCB2b2lkICpjbG9zdXJlKQoreworICAgIFB5VHlwZU9iamVjdCAqb2xkdG8gPSBQeV9UWVBFKHNlbGYpOworICAgIFB5VHlwZU9iamVjdCAqbmV3dG87CisKKyAgICBpZiAodmFsdWUgPT0gTlVMTCkgeworICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfVHlwZUVycm9yLAorICAgICAgICAgICAgICAgICAgICAgICAgImNhbid0IGRlbGV0ZSBfX2NsYXNzX18gYXR0cmlidXRlIik7CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisgICAgaWYgKCFQeVR5cGVfQ2hlY2sodmFsdWUpKSB7CisgICAgICAgIFB5RXJyX0Zvcm1hdChQeUV4Y19UeXBlRXJyb3IsCisgICAgICAgICAgIl9fY2xhc3NfXyBtdXN0IGJlIHNldCB0byBuZXctc3R5bGUgY2xhc3MsIG5vdCAnJXMnIG9iamVjdCIsCisgICAgICAgICAgUHlfVFlQRSh2YWx1ZSktPnRwX25hbWUpOworICAgICAgICByZXR1cm4gLTE7CisgICAgfQorICAgIG5ld3RvID0gKFB5VHlwZU9iamVjdCAqKXZhbHVlOworICAgIGlmICghKG5ld3RvLT50cF9mbGFncyAmIFB5X1RQRkxBR1NfSEVBUFRZUEUpIHx8CisgICAgICAgICEob2xkdG8tPnRwX2ZsYWdzICYgUHlfVFBGTEFHU19IRUFQVFlQRSkpCisgICAgeworICAgICAgICBQeUVycl9Gb3JtYXQoUHlFeGNfVHlwZUVycm9yLAorICAgICAgICAgICAgICAgICAgICAgIl9fY2xhc3NfXyBhc3NpZ25tZW50OiBvbmx5IGZvciBoZWFwIHR5cGVzIik7CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisgICAgaWYgKGNvbXBhdGlibGVfZm9yX2Fzc2lnbm1lbnQobmV3dG8sIG9sZHRvLCAiX19jbGFzc19fIikpIHsKKyAgICAgICAgUHlfSU5DUkVGKG5ld3RvKTsKKyAgICAgICAgUHlfVFlQRShzZWxmKSA9IG5ld3RvOworICAgICAgICBQeV9ERUNSRUYob2xkdG8pOworICAgICAgICByZXR1cm4gMDsKKyAgICB9CisgICAgZWxzZSB7CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9Cit9CisKK3N0YXRpYyBQeUdldFNldERlZiBvYmplY3RfZ2V0c2V0c1tdID0geworICAgIHsiX19jbGFzc19fIiwgb2JqZWN0X2dldF9jbGFzcywgb2JqZWN0X3NldF9jbGFzcywKKyAgICAgUHlEb2NfU1RSKCJ0aGUgb2JqZWN0J3MgY2xhc3MiKX0sCisgICAgezB9Cit9OworCisKKy8qIFN0dWZmIHRvIGltcGxlbWVudCBfX3JlZHVjZV9leF9fIGZvciBwaWNrbGUgcHJvdG9jb2xzID49IDIuCisgICBXZSBmYWxsIGJhY2sgdG8gaGVscGVycyBpbiBjb3B5X3JlZyBmb3I6CisgICAtIHBpY2tsZSBwcm90b2NvbHMgPCAyCisgICAtIGNhbGN1bGF0aW5nIHRoZSBsaXN0IG9mIHNsb3QgbmFtZXMgKGRvbmUgb25seSBvbmNlIHBlciBjbGFzcykKKyAgIC0gdGhlIF9fbmV3b2JqX18gZnVuY3Rpb24gKHdoaWNoIGlzIHVzZWQgYXMgYSB0b2tlbiBidXQgbmV2ZXIgY2FsbGVkKQorKi8KKworc3RhdGljIFB5T2JqZWN0ICoKK2ltcG9ydF9jb3B5cmVnKHZvaWQpCit7CisgICAgc3RhdGljIFB5T2JqZWN0ICpjb3B5cmVnX3N0cjsKKworICAgIGlmICghY29weXJlZ19zdHIpIHsKKyAgICAgICAgY29weXJlZ19zdHIgPSBQeVN0cmluZ19JbnRlcm5Gcm9tU3RyaW5nKCJjb3B5X3JlZyIpOworICAgICAgICBpZiAoY29weXJlZ19zdHIgPT0gTlVMTCkKKyAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKworICAgIHJldHVybiBQeUltcG9ydF9JbXBvcnQoY29weXJlZ19zdHIpOworfQorCitzdGF0aWMgUHlPYmplY3QgKgorc2xvdG5hbWVzKFB5T2JqZWN0ICpjbHMpCit7CisgICAgUHlPYmplY3QgKmNsc2RpY3Q7CisgICAgUHlPYmplY3QgKmNvcHlyZWc7CisgICAgUHlPYmplY3QgKnNsb3RuYW1lczsKKworICAgIGlmICghUHlUeXBlX0NoZWNrKGNscykpIHsKKyAgICAgICAgUHlfSU5DUkVGKFB5X05vbmUpOworICAgICAgICByZXR1cm4gUHlfTm9uZTsKKyAgICB9CisKKyAgICBjbHNkaWN0ID0gKChQeVR5cGVPYmplY3QgKiljbHMpLT50cF9kaWN0OworICAgIHNsb3RuYW1lcyA9IFB5RGljdF9HZXRJdGVtU3RyaW5nKGNsc2RpY3QsICJfX3Nsb3RuYW1lc19fIik7CisgICAgaWYgKHNsb3RuYW1lcyAhPSBOVUxMICYmIFB5TGlzdF9DaGVjayhzbG90bmFtZXMpKSB7CisgICAgICAgIFB5X0lOQ1JFRihzbG90bmFtZXMpOworICAgICAgICByZXR1cm4gc2xvdG5hbWVzOworICAgIH0KKworICAgIGNvcHlyZWcgPSBpbXBvcnRfY29weXJlZygpOworICAgIGlmIChjb3B5cmVnID09IE5VTEwpCisgICAgICAgIHJldHVybiBOVUxMOworCisgICAgc2xvdG5hbWVzID0gUHlPYmplY3RfQ2FsbE1ldGhvZChjb3B5cmVnLCAiX3Nsb3RuYW1lcyIsICJPIiwgY2xzKTsKKyAgICBQeV9ERUNSRUYoY29weXJlZyk7CisgICAgaWYgKHNsb3RuYW1lcyAhPSBOVUxMICYmCisgICAgICAgIHNsb3RuYW1lcyAhPSBQeV9Ob25lICYmCisgICAgICAgICFQeUxpc3RfQ2hlY2soc2xvdG5hbWVzKSkKKyAgICB7CisgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19UeXBlRXJyb3IsCisgICAgICAgICAgICAiY29weV9yZWcuX3Nsb3RuYW1lcyBkaWRuJ3QgcmV0dXJuIGEgbGlzdCBvciBOb25lIik7CisgICAgICAgIFB5X0RFQ1JFRihzbG90bmFtZXMpOworICAgICAgICBzbG90bmFtZXMgPSBOVUxMOworICAgIH0KKworICAgIHJldHVybiBzbG90bmFtZXM7Cit9CisKK3N0YXRpYyBQeU9iamVjdCAqCityZWR1Y2VfMihQeU9iamVjdCAqb2JqKQoreworICAgIFB5T2JqZWN0ICpjbHMsICpnZXRuZXdhcmdzOworICAgIFB5T2JqZWN0ICphcmdzID0gTlVMTCwgKmFyZ3MyID0gTlVMTDsKKyAgICBQeU9iamVjdCAqZ2V0c3RhdGUgPSBOVUxMLCAqc3RhdGUgPSBOVUxMLCAqbmFtZXMgPSBOVUxMOworICAgIFB5T2JqZWN0ICpzbG90cyA9IE5VTEwsICpsaXN0aXRlbXMgPSBOVUxMLCAqZGljdGl0ZW1zID0gTlVMTDsKKyAgICBQeU9iamVjdCAqY29weXJlZyA9IE5VTEwsICpuZXdvYmogPSBOVUxMLCAqcmVzID0gTlVMTDsKKyAgICBQeV9zc2l6ZV90IGksIG47CisKKyAgICBjbHMgPSBQeU9iamVjdF9HZXRBdHRyU3RyaW5nKG9iaiwgIl9fY2xhc3NfXyIpOworICAgIGlmIChjbHMgPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisKKyAgICBnZXRuZXdhcmdzID0gUHlPYmplY3RfR2V0QXR0clN0cmluZyhvYmosICJfX2dldG5ld2FyZ3NfXyIpOworICAgIGlmIChnZXRuZXdhcmdzICE9IE5VTEwpIHsKKyAgICAgICAgYXJncyA9IFB5T2JqZWN0X0NhbGxPYmplY3QoZ2V0bmV3YXJncywgTlVMTCk7CisgICAgICAgIFB5X0RFQ1JFRihnZXRuZXdhcmdzKTsKKyAgICAgICAgaWYgKGFyZ3MgIT0gTlVMTCAmJiAhUHlUdXBsZV9DaGVjayhhcmdzKSkgeworICAgICAgICAgICAgUHlFcnJfRm9ybWF0KFB5RXhjX1R5cGVFcnJvciwKKyAgICAgICAgICAgICAgICAiX19nZXRuZXdhcmdzX18gc2hvdWxkIHJldHVybiBhIHR1cGxlLCAiCisgICAgICAgICAgICAgICAgIm5vdCAnJS4yMDBzJyIsIFB5X1RZUEUoYXJncyktPnRwX25hbWUpOworICAgICAgICAgICAgZ290byBlbmQ7CisgICAgICAgIH0KKyAgICB9CisgICAgZWxzZSB7CisgICAgICAgIFB5RXJyX0NsZWFyKCk7CisgICAgICAgIGFyZ3MgPSBQeVR1cGxlX05ldygwKTsKKyAgICB9CisgICAgaWYgKGFyZ3MgPT0gTlVMTCkKKyAgICAgICAgZ290byBlbmQ7CisKKyAgICBnZXRzdGF0ZSA9IFB5T2JqZWN0X0dldEF0dHJTdHJpbmcob2JqLCAiX19nZXRzdGF0ZV9fIik7CisgICAgaWYgKGdldHN0YXRlICE9IE5VTEwpIHsKKyAgICAgICAgc3RhdGUgPSBQeU9iamVjdF9DYWxsT2JqZWN0KGdldHN0YXRlLCBOVUxMKTsKKyAgICAgICAgUHlfREVDUkVGKGdldHN0YXRlKTsKKyAgICAgICAgaWYgKHN0YXRlID09IE5VTEwpCisgICAgICAgICAgICBnb3RvIGVuZDsKKyAgICB9CisgICAgZWxzZSB7CisgICAgICAgIFB5RXJyX0NsZWFyKCk7CisgICAgICAgIHN0YXRlID0gUHlPYmplY3RfR2V0QXR0clN0cmluZyhvYmosICJfX2RpY3RfXyIpOworICAgICAgICBpZiAoc3RhdGUgPT0gTlVMTCkgeworICAgICAgICAgICAgUHlFcnJfQ2xlYXIoKTsKKyAgICAgICAgICAgIHN0YXRlID0gUHlfTm9uZTsKKyAgICAgICAgICAgIFB5X0lOQ1JFRihzdGF0ZSk7CisgICAgICAgIH0KKyAgICAgICAgbmFtZXMgPSBzbG90bmFtZXMoY2xzKTsKKyAgICAgICAgaWYgKG5hbWVzID09IE5VTEwpCisgICAgICAgICAgICBnb3RvIGVuZDsKKyAgICAgICAgaWYgKG5hbWVzICE9IFB5X05vbmUpIHsKKyAgICAgICAgICAgIGFzc2VydChQeUxpc3RfQ2hlY2sobmFtZXMpKTsKKyAgICAgICAgICAgIHNsb3RzID0gUHlEaWN0X05ldygpOworICAgICAgICAgICAgaWYgKHNsb3RzID09IE5VTEwpCisgICAgICAgICAgICAgICAgZ290byBlbmQ7CisgICAgICAgICAgICBuID0gMDsKKyAgICAgICAgICAgIC8qIENhbid0IHByZS1jb21wdXRlIHRoZSBsaXN0IHNpemU7IHRoZSBsaXN0CisgICAgICAgICAgICAgICBpcyBzdG9yZWQgb24gdGhlIGNsYXNzIHNvIGFjY2Vzc2libGUgdG8gb3RoZXIKKyAgICAgICAgICAgICAgIHRocmVhZHMsIHdoaWNoIG1heSBiZSBydW4gYnkgREVDUkVGICovCisgICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgUHlMaXN0X0dFVF9TSVpFKG5hbWVzKTsgaSsrKSB7CisgICAgICAgICAgICAgICAgUHlPYmplY3QgKm5hbWUsICp2YWx1ZTsKKyAgICAgICAgICAgICAgICBuYW1lID0gUHlMaXN0X0dFVF9JVEVNKG5hbWVzLCBpKTsKKyAgICAgICAgICAgICAgICB2YWx1ZSA9IFB5T2JqZWN0X0dldEF0dHIob2JqLCBuYW1lKTsKKyAgICAgICAgICAgICAgICBpZiAodmFsdWUgPT0gTlVMTCkKKyAgICAgICAgICAgICAgICAgICAgUHlFcnJfQ2xlYXIoKTsKKyAgICAgICAgICAgICAgICBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgaW50IGVyciA9IFB5RGljdF9TZXRJdGVtKHNsb3RzLCBuYW1lLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWUpOworICAgICAgICAgICAgICAgICAgICBQeV9ERUNSRUYodmFsdWUpOworICAgICAgICAgICAgICAgICAgICBpZiAoZXJyKQorICAgICAgICAgICAgICAgICAgICAgICAgZ290byBlbmQ7CisgICAgICAgICAgICAgICAgICAgIG4rKzsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAobikgeworICAgICAgICAgICAgICAgIHN0YXRlID0gUHlfQnVpbGRWYWx1ZSgiKE5PKSIsIHN0YXRlLCBzbG90cyk7CisgICAgICAgICAgICAgICAgaWYgKHN0YXRlID09IE5VTEwpCisgICAgICAgICAgICAgICAgICAgIGdvdG8gZW5kOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorCisgICAgaWYgKCFQeUxpc3RfQ2hlY2sob2JqKSkgeworICAgICAgICBsaXN0aXRlbXMgPSBQeV9Ob25lOworICAgICAgICBQeV9JTkNSRUYobGlzdGl0ZW1zKTsKKyAgICB9CisgICAgZWxzZSB7CisgICAgICAgIGxpc3RpdGVtcyA9IFB5T2JqZWN0X0dldEl0ZXIob2JqKTsKKyAgICAgICAgaWYgKGxpc3RpdGVtcyA9PSBOVUxMKQorICAgICAgICAgICAgZ290byBlbmQ7CisgICAgfQorCisgICAgaWYgKCFQeURpY3RfQ2hlY2sob2JqKSkgeworICAgICAgICBkaWN0aXRlbXMgPSBQeV9Ob25lOworICAgICAgICBQeV9JTkNSRUYoZGljdGl0ZW1zKTsKKyAgICB9CisgICAgZWxzZSB7CisgICAgICAgIGRpY3RpdGVtcyA9IFB5T2JqZWN0X0NhbGxNZXRob2Qob2JqLCAiaXRlcml0ZW1zIiwgIiIpOworICAgICAgICBpZiAoZGljdGl0ZW1zID09IE5VTEwpCisgICAgICAgICAgICBnb3RvIGVuZDsKKyAgICB9CisKKyAgICBjb3B5cmVnID0gaW1wb3J0X2NvcHlyZWcoKTsKKyAgICBpZiAoY29weXJlZyA9PSBOVUxMKQorICAgICAgICBnb3RvIGVuZDsKKyAgICBuZXdvYmogPSBQeU9iamVjdF9HZXRBdHRyU3RyaW5nKGNvcHlyZWcsICJfX25ld29ial9fIik7CisgICAgaWYgKG5ld29iaiA9PSBOVUxMKQorICAgICAgICBnb3RvIGVuZDsKKworICAgIG4gPSBQeVR1cGxlX0dFVF9TSVpFKGFyZ3MpOworICAgIGFyZ3MyID0gUHlUdXBsZV9OZXcobisxKTsKKyAgICBpZiAoYXJnczIgPT0gTlVMTCkKKyAgICAgICAgZ290byBlbmQ7CisgICAgUHlUdXBsZV9TRVRfSVRFTShhcmdzMiwgMCwgY2xzKTsKKyAgICBjbHMgPSBOVUxMOworICAgIGZvciAoaSA9IDA7IGkgPCBuOyBpKyspIHsKKyAgICAgICAgUHlPYmplY3QgKnYgPSBQeVR1cGxlX0dFVF9JVEVNKGFyZ3MsIGkpOworICAgICAgICBQeV9JTkNSRUYodik7CisgICAgICAgIFB5VHVwbGVfU0VUX0lURU0oYXJnczIsIGkrMSwgdik7CisgICAgfQorCisgICAgcmVzID0gUHlUdXBsZV9QYWNrKDUsIG5ld29iaiwgYXJnczIsIHN0YXRlLCBsaXN0aXRlbXMsIGRpY3RpdGVtcyk7CisKKyAgZW5kOgorICAgIFB5X1hERUNSRUYoY2xzKTsKKyAgICBQeV9YREVDUkVGKGFyZ3MpOworICAgIFB5X1hERUNSRUYoYXJnczIpOworICAgIFB5X1hERUNSRUYoc2xvdHMpOworICAgIFB5X1hERUNSRUYoc3RhdGUpOworICAgIFB5X1hERUNSRUYobmFtZXMpOworICAgIFB5X1hERUNSRUYobGlzdGl0ZW1zKTsKKyAgICBQeV9YREVDUkVGKGRpY3RpdGVtcyk7CisgICAgUHlfWERFQ1JFRihjb3B5cmVnKTsKKyAgICBQeV9YREVDUkVGKG5ld29iaik7CisgICAgcmV0dXJuIHJlczsKK30KKworLyoKKyAqIFRoZXJlIHdlcmUgdHdvIHByb2JsZW1zIHdoZW4gb2JqZWN0Ll9fcmVkdWNlX18gYW5kIG9iamVjdC5fX3JlZHVjZV9leF9fCisgKiB3ZXJlIGltcGxlbWVudGVkIGluIHRoZSBzYW1lIGZ1bmN0aW9uOgorICogIC0gdHJ5aW5nIHRvIHBpY2tsZSBhbiBvYmplY3Qgd2l0aCBhIGN1c3RvbSBfX3JlZHVjZV9fIG1ldGhvZCB0aGF0CisgKiAgICBmZWxsIGJhY2sgdG8gb2JqZWN0Ll9fcmVkdWNlX18gaW4gY2VydGFpbiBjaXJjdW1zdGFuY2VzIGxlZCB0bworICogICAgaW5maW5pdGUgcmVjdXJzaW9uIGF0IFB5dGhvbiBsZXZlbCBhbmQgZXZlbnR1YWwgUnVudGltZUVycm9yLgorICogIC0gUGlja2xpbmcgb2JqZWN0cyB0aGF0IGxpZWQgYWJvdXQgdGhlaXIgdHlwZSBieSBvdmVyd3JpdGluZyB0aGUKKyAqICAgIF9fY2xhc3NfXyBkZXNjcmlwdG9yIGNvdWxkIGxlYWQgdG8gaW5maW5pdGUgcmVjdXJzaW9uIGF0IEMgbGV2ZWwKKyAqICAgIGFuZCBldmVudHVhbCBzZWdmYXVsdC4KKyAqCisgKiBCZWNhdXNlIG9mIGJhY2t3YXJkcyBjb21wYXRpYmlsaXR5LCB0aGUgdHdvIG1ldGhvZHMgc3RpbGwgaGF2ZSB0bworICogYmVoYXZlIGluIHRoZSBzYW1lIHdheSwgZXZlbiBpZiB0aGlzIGlzIG5vdCByZXF1aXJlZCBieSB0aGUgcGlja2xlCisgKiBwcm90b2NvbC4gVGhpcyBjb21tb24gZnVuY3Rpb25hbGl0eSB3YXMgbW92ZWQgdG8gdGhlIF9jb21tb25fcmVkdWNlCisgKiBmdW5jdGlvbi4KKyAqLworc3RhdGljIFB5T2JqZWN0ICoKK19jb21tb25fcmVkdWNlKFB5T2JqZWN0ICpzZWxmLCBpbnQgcHJvdG8pCit7CisgICAgUHlPYmplY3QgKmNvcHlyZWcsICpyZXM7CisKKyAgICBpZiAocHJvdG8gPj0gMikKKyAgICAgICAgcmV0dXJuIHJlZHVjZV8yKHNlbGYpOworCisgICAgY29weXJlZyA9IGltcG9ydF9jb3B5cmVnKCk7CisgICAgaWYgKCFjb3B5cmVnKQorICAgICAgICByZXR1cm4gTlVMTDsKKworICAgIHJlcyA9IFB5RXZhbF9DYWxsTWV0aG9kKGNvcHlyZWcsICJfcmVkdWNlX2V4IiwgIihPaSkiLCBzZWxmLCBwcm90byk7CisgICAgUHlfREVDUkVGKGNvcHlyZWcpOworCisgICAgcmV0dXJuIHJlczsKK30KKworc3RhdGljIFB5T2JqZWN0ICoKK29iamVjdF9yZWR1Y2UoUHlPYmplY3QgKnNlbGYsIFB5T2JqZWN0ICphcmdzKQoreworICAgIGludCBwcm90byA9IDA7CisKKyAgICBpZiAoIVB5QXJnX1BhcnNlVHVwbGUoYXJncywgInxpOl9fcmVkdWNlX18iLCAmcHJvdG8pKQorICAgICAgICByZXR1cm4gTlVMTDsKKworICAgIHJldHVybiBfY29tbW9uX3JlZHVjZShzZWxmLCBwcm90byk7Cit9CisKK3N0YXRpYyBQeU9iamVjdCAqCitvYmplY3RfcmVkdWNlX2V4KFB5T2JqZWN0ICpzZWxmLCBQeU9iamVjdCAqYXJncykKK3sKKyAgICBQeU9iamVjdCAqcmVkdWNlLCAqcmVzOworICAgIGludCBwcm90byA9IDA7CisKKyAgICBpZiAoIVB5QXJnX1BhcnNlVHVwbGUoYXJncywgInxpOl9fcmVkdWNlX2V4X18iLCAmcHJvdG8pKQorICAgICAgICByZXR1cm4gTlVMTDsKKworICAgIHJlZHVjZSA9IFB5T2JqZWN0X0dldEF0dHJTdHJpbmcoc2VsZiwgIl9fcmVkdWNlX18iKTsKKyAgICBpZiAocmVkdWNlID09IE5VTEwpCisgICAgICAgIFB5RXJyX0NsZWFyKCk7CisgICAgZWxzZSB7CisgICAgICAgIFB5T2JqZWN0ICpjbHMsICpjbHNyZWR1Y2UsICpvYmpyZWR1Y2U7CisgICAgICAgIGludCBvdmVycmlkZTsKKyAgICAgICAgY2xzID0gUHlPYmplY3RfR2V0QXR0clN0cmluZyhzZWxmLCAiX19jbGFzc19fIik7CisgICAgICAgIGlmIChjbHMgPT0gTlVMTCkgeworICAgICAgICAgICAgUHlfREVDUkVGKHJlZHVjZSk7CisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgfQorICAgICAgICBjbHNyZWR1Y2UgPSBQeU9iamVjdF9HZXRBdHRyU3RyaW5nKGNscywgIl9fcmVkdWNlX18iKTsKKyAgICAgICAgUHlfREVDUkVGKGNscyk7CisgICAgICAgIGlmIChjbHNyZWR1Y2UgPT0gTlVMTCkgeworICAgICAgICAgICAgUHlfREVDUkVGKHJlZHVjZSk7CisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgfQorICAgICAgICBvYmpyZWR1Y2UgPSBQeURpY3RfR2V0SXRlbVN0cmluZyhQeUJhc2VPYmplY3RfVHlwZS50cF9kaWN0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiX19yZWR1Y2VfXyIpOworICAgICAgICBvdmVycmlkZSA9IChjbHNyZWR1Y2UgIT0gb2JqcmVkdWNlKTsKKyAgICAgICAgUHlfREVDUkVGKGNsc3JlZHVjZSk7CisgICAgICAgIGlmIChvdmVycmlkZSkgeworICAgICAgICAgICAgcmVzID0gUHlPYmplY3RfQ2FsbE9iamVjdChyZWR1Y2UsIE5VTEwpOworICAgICAgICAgICAgUHlfREVDUkVGKHJlZHVjZSk7CisgICAgICAgICAgICByZXR1cm4gcmVzOworICAgICAgICB9CisgICAgICAgIGVsc2UKKyAgICAgICAgICAgIFB5X0RFQ1JFRihyZWR1Y2UpOworICAgIH0KKworICAgIHJldHVybiBfY29tbW9uX3JlZHVjZShzZWxmLCBwcm90byk7Cit9CisKK3N0YXRpYyBQeU9iamVjdCAqCitvYmplY3Rfc3ViY2xhc3Nob29rKFB5T2JqZWN0ICpjbHMsIFB5T2JqZWN0ICphcmdzKQoreworICAgIFB5X0lOQ1JFRihQeV9Ob3RJbXBsZW1lbnRlZCk7CisgICAgcmV0dXJuIFB5X05vdEltcGxlbWVudGVkOworfQorCitQeURvY19TVFJWQVIob2JqZWN0X3N1YmNsYXNzaG9va19kb2MsCisiQWJzdHJhY3QgY2xhc3NlcyBjYW4gb3ZlcnJpZGUgdGhpcyB0byBjdXN0b21pemUgaXNzdWJjbGFzcygpLlxuIgorIlxuIgorIlRoaXMgaXMgaW52b2tlZCBlYXJseSBvbiBieSBhYmMuQUJDTWV0YS5fX3N1YmNsYXNzY2hlY2tfXygpLlxuIgorIkl0IHNob3VsZCByZXR1cm4gVHJ1ZSwgRmFsc2Ugb3IgTm90SW1wbGVtZW50ZWQuICBJZiBpdCByZXR1cm5zXG4iCisiTm90SW1wbGVtZW50ZWQsIHRoZSBub3JtYWwgYWxnb3JpdGhtIGlzIHVzZWQuICBPdGhlcndpc2UsIGl0XG4iCisib3ZlcnJpZGVzIHRoZSBub3JtYWwgYWxnb3JpdGhtIChhbmQgdGhlIG91dGNvbWUgaXMgY2FjaGVkKS5cbiIpOworCisvKgorICAgZnJvbSBQRVAgMzEwMSwgdGhpcyBjb2RlIGltcGxlbWVudHM6CisKKyAgIGNsYXNzIG9iamVjdDoKKyAgICAgICBkZWYgX19mb3JtYXRfXyhzZWxmLCBmb3JtYXRfc3BlYyk6CisgICAgICAgaWYgaXNpbnN0YW5jZShmb3JtYXRfc3BlYywgc3RyKToKKyAgICAgICAgICAgcmV0dXJuIGZvcm1hdChzdHIoc2VsZiksIGZvcm1hdF9zcGVjKQorICAgICAgIGVsaWYgaXNpbnN0YW5jZShmb3JtYXRfc3BlYywgdW5pY29kZSk6CisgICAgICAgICAgIHJldHVybiBmb3JtYXQodW5pY29kZShzZWxmKSwgZm9ybWF0X3NwZWMpCisqLworc3RhdGljIFB5T2JqZWN0ICoKK29iamVjdF9mb3JtYXQoUHlPYmplY3QgKnNlbGYsIFB5T2JqZWN0ICphcmdzKQoreworICAgIFB5T2JqZWN0ICpmb3JtYXRfc3BlYzsKKyAgICBQeU9iamVjdCAqc2VsZl9hc19zdHIgPSBOVUxMOworICAgIFB5T2JqZWN0ICpyZXN1bHQgPSBOVUxMOworICAgIFB5X3NzaXplX3QgZm9ybWF0X2xlbjsKKworICAgIGlmICghUHlBcmdfUGFyc2VUdXBsZShhcmdzLCAiTzpfX2Zvcm1hdF9fIiwgJmZvcm1hdF9zcGVjKSkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisjaWZkZWYgUHlfVVNJTkdfVU5JQ09ERQorICAgIGlmIChQeVVuaWNvZGVfQ2hlY2soZm9ybWF0X3NwZWMpKSB7CisgICAgICAgIGZvcm1hdF9sZW4gPSBQeVVuaWNvZGVfR0VUX1NJWkUoZm9ybWF0X3NwZWMpOworICAgICAgICBzZWxmX2FzX3N0ciA9IFB5T2JqZWN0X1VuaWNvZGUoc2VsZik7CisgICAgfSBlbHNlIGlmIChQeVN0cmluZ19DaGVjayhmb3JtYXRfc3BlYykpIHsKKyNlbHNlCisgICAgaWYgKFB5U3RyaW5nX0NoZWNrKGZvcm1hdF9zcGVjKSkgeworI2VuZGlmCisgICAgICAgIGZvcm1hdF9sZW4gPSBQeVN0cmluZ19HRVRfU0laRShmb3JtYXRfc3BlYyk7CisgICAgICAgIHNlbGZfYXNfc3RyID0gUHlPYmplY3RfU3RyKHNlbGYpOworICAgIH0gZWxzZSB7CisgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19UeXBlRXJyb3IsCisgICAgICAgICAgICAgICAgICJhcmd1bWVudCB0byBfX2Zvcm1hdF9fIG11c3QgYmUgdW5pY29kZSBvciBzdHIiKTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorCisgICAgaWYgKHNlbGZfYXNfc3RyICE9IE5VTEwpIHsKKyAgICAgICAgLyogSXNzdWUgNzk5NDogSWYgd2UncmUgY29udmVydGluZyB0byBhIHN0cmluZywgd2UKKyAgICAgICAgICAgc2hvdWxkIHJlamVjdCBmb3JtYXQgc3BlY2lmaWNhdGlvbnMgKi8KKyAgICAgICAgaWYgKGZvcm1hdF9sZW4gPiAwKSB7CisgICAgICAgICAgICBpZiAoUHlFcnJfV2FybkV4KFB5RXhjX1BlbmRpbmdEZXByZWNhdGlvbldhcm5pbmcsCisgICAgICAgICAgICAgIm9iamVjdC5fX2Zvcm1hdF9fIHdpdGggYSBub24tZW1wdHkgZm9ybWF0ICIKKyAgICAgICAgICAgICAic3RyaW5nIGlzIGRlcHJlY2F0ZWQiLCAxKSA8IDApIHsKKyAgICAgICAgICAgICAgICBnb3RvIGRvbmU7CisgICAgICAgICAgICB9CisgICAgICAgICAgICAvKiBFdmVudHVhbGx5IHRoaXMgd2lsbCBiZWNvbWUgYW4gZXJyb3I6CisgICAgICAgICAgICBQeUVycl9Gb3JtYXQoUHlFeGNfVHlwZUVycm9yLAorICAgICAgICAgICAgICAgIm5vbi1lbXB0eSBmb3JtYXQgc3RyaW5nIHBhc3NlZCB0byBvYmplY3QuX19mb3JtYXRfXyIpOworICAgICAgICAgICAgZ290byBkb25lOworICAgICAgICAgICAgKi8KKyAgICAgICAgfQorICAgICAgICByZXN1bHQgPSBQeU9iamVjdF9Gb3JtYXQoc2VsZl9hc19zdHIsIGZvcm1hdF9zcGVjKTsKKyAgICB9CisKK2RvbmU6CisgICAgUHlfWERFQ1JFRihzZWxmX2FzX3N0cik7CisKKyAgICByZXR1cm4gcmVzdWx0OworfQorCitzdGF0aWMgUHlPYmplY3QgKgorb2JqZWN0X3NpemVvZihQeU9iamVjdCAqc2VsZiwgUHlPYmplY3QgKmFyZ3MpCit7CisgICAgUHlfc3NpemVfdCByZXMsIGlzaXplOworCisgICAgcmVzID0gMDsKKyAgICBpc2l6ZSA9IHNlbGYtPm9iX3R5cGUtPnRwX2l0ZW1zaXplOworICAgIGlmIChpc2l6ZSA+IDApCisgICAgICAgIHJlcyA9IHNlbGYtPm9iX3R5cGUtPm9iX3NpemUgKiBpc2l6ZTsKKyAgICByZXMgKz0gc2VsZi0+b2JfdHlwZS0+dHBfYmFzaWNzaXplOworCisgICAgcmV0dXJuIFB5SW50X0Zyb21Tc2l6ZV90KHJlcyk7Cit9CisKK3N0YXRpYyBQeU1ldGhvZERlZiBvYmplY3RfbWV0aG9kc1tdID0geworICAgIHsiX19yZWR1Y2VfZXhfXyIsIG9iamVjdF9yZWR1Y2VfZXgsIE1FVEhfVkFSQVJHUywKKyAgICAgUHlEb2NfU1RSKCJoZWxwZXIgZm9yIHBpY2tsZSIpfSwKKyAgICB7Il9fcmVkdWNlX18iLCBvYmplY3RfcmVkdWNlLCBNRVRIX1ZBUkFSR1MsCisgICAgIFB5RG9jX1NUUigiaGVscGVyIGZvciBwaWNrbGUiKX0sCisgICAgeyJfX3N1YmNsYXNzaG9va19fIiwgb2JqZWN0X3N1YmNsYXNzaG9vaywgTUVUSF9DTEFTUyB8IE1FVEhfVkFSQVJHUywKKyAgICAgb2JqZWN0X3N1YmNsYXNzaG9va19kb2N9LAorICAgIHsiX19mb3JtYXRfXyIsIG9iamVjdF9mb3JtYXQsIE1FVEhfVkFSQVJHUywKKyAgICAgUHlEb2NfU1RSKCJkZWZhdWx0IG9iamVjdCBmb3JtYXR0ZXIiKX0sCisgICAgeyJfX3NpemVvZl9fIiwgb2JqZWN0X3NpemVvZiwgTUVUSF9OT0FSR1MsCisgICAgIFB5RG9jX1NUUigiX19zaXplb2ZfXygpIC0+IGludFxuc2l6ZSBvZiBvYmplY3QgaW4gbWVtb3J5LCBpbiBieXRlcyIpfSwKKyAgICB7MH0KK307CisKKworUHlUeXBlT2JqZWN0IFB5QmFzZU9iamVjdF9UeXBlID0geworICAgIFB5VmFyT2JqZWN0X0hFQURfSU5JVCgmUHlUeXBlX1R5cGUsIDApCisgICAgIm9iamVjdCIsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9uYW1lICovCisgICAgc2l6ZW9mKFB5T2JqZWN0KSwgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9iYXNpY3NpemUgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2l0ZW1zaXplICovCisgICAgb2JqZWN0X2RlYWxsb2MsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9kZWFsbG9jICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9wcmludCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZ2V0YXR0ciAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfc2V0YXR0ciAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfY29tcGFyZSAqLworICAgIG9iamVjdF9yZXByLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfcmVwciAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfYXNfbnVtYmVyICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9hc19zZXF1ZW5jZSAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfYXNfbWFwcGluZyAqLworICAgIChoYXNoZnVuYylfUHlfSGFzaFBvaW50ZXIsICAgICAgICAgICAgICAgICAgLyogdHBfaGFzaCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfY2FsbCAqLworICAgIG9iamVjdF9zdHIsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfc3RyICovCisgICAgUHlPYmplY3RfR2VuZXJpY0dldEF0dHIsICAgICAgICAgICAgICAgICAgICAvKiB0cF9nZXRhdHRybyAqLworICAgIFB5T2JqZWN0X0dlbmVyaWNTZXRBdHRyLCAgICAgICAgICAgICAgICAgICAgLyogdHBfc2V0YXR0cm8gKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2FzX2J1ZmZlciAqLworICAgIFB5X1RQRkxBR1NfREVGQVVMVCB8IFB5X1RQRkxBR1NfQkFTRVRZUEUsIC8qIHRwX2ZsYWdzICovCisgICAgUHlEb2NfU1RSKCJUaGUgbW9zdCBiYXNlIHR5cGUiKSwgICAgICAgICAgICAvKiB0cF9kb2MgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3RyYXZlcnNlICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9jbGVhciAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfcmljaGNvbXBhcmUgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3dlYWtsaXN0b2Zmc2V0ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9pdGVyICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9pdGVybmV4dCAqLworICAgIG9iamVjdF9tZXRob2RzLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfbWV0aG9kcyAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfbWVtYmVycyAqLworICAgIG9iamVjdF9nZXRzZXRzLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZ2V0c2V0ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9iYXNlICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9kaWN0ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9kZXNjcl9nZXQgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2Rlc2NyX3NldCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZGljdG9mZnNldCAqLworICAgIG9iamVjdF9pbml0LCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfaW5pdCAqLworICAgIFB5VHlwZV9HZW5lcmljQWxsb2MsICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfYWxsb2MgKi8KKyAgICBvYmplY3RfbmV3LCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX25ldyAqLworICAgIFB5T2JqZWN0X0RlbCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZnJlZSAqLworfTsKKworCisvKiBJbml0aWFsaXplIHRoZSBfX2RpY3RfXyBpbiBhIHR5cGUgb2JqZWN0ICovCisKK3N0YXRpYyBpbnQKK2FkZF9tZXRob2RzKFB5VHlwZU9iamVjdCAqdHlwZSwgUHlNZXRob2REZWYgKm1ldGgpCit7CisgICAgUHlPYmplY3QgKmRpY3QgPSB0eXBlLT50cF9kaWN0OworCisgICAgZm9yICg7IG1ldGgtPm1sX25hbWUgIT0gTlVMTDsgbWV0aCsrKSB7CisgICAgICAgIFB5T2JqZWN0ICpkZXNjcjsKKyAgICAgICAgaW50IGVycjsKKyAgICAgICAgaWYgKFB5RGljdF9HZXRJdGVtU3RyaW5nKGRpY3QsIG1ldGgtPm1sX25hbWUpICYmCisgICAgICAgICAgICAhKG1ldGgtPm1sX2ZsYWdzICYgTUVUSF9DT0VYSVNUKSkKKyAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgaWYgKG1ldGgtPm1sX2ZsYWdzICYgTUVUSF9DTEFTUykgeworICAgICAgICAgICAgaWYgKG1ldGgtPm1sX2ZsYWdzICYgTUVUSF9TVEFUSUMpIHsKKyAgICAgICAgICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfVmFsdWVFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICJtZXRob2QgY2Fubm90IGJlIGJvdGggY2xhc3MgYW5kIHN0YXRpYyIpOworICAgICAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGRlc2NyID0gUHlEZXNjcl9OZXdDbGFzc01ldGhvZCh0eXBlLCBtZXRoKTsKKyAgICAgICAgfQorICAgICAgICBlbHNlIGlmIChtZXRoLT5tbF9mbGFncyAmIE1FVEhfU1RBVElDKSB7CisgICAgICAgICAgICBQeU9iamVjdCAqY2Z1bmMgPSBQeUNGdW5jdGlvbl9OZXcobWV0aCwgTlVMTCk7CisgICAgICAgICAgICBpZiAoY2Z1bmMgPT0gTlVMTCkKKyAgICAgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgICAgICBkZXNjciA9IFB5U3RhdGljTWV0aG9kX05ldyhjZnVuYyk7CisgICAgICAgICAgICBQeV9ERUNSRUYoY2Z1bmMpOworICAgICAgICB9CisgICAgICAgIGVsc2UgeworICAgICAgICAgICAgZGVzY3IgPSBQeURlc2NyX05ld01ldGhvZCh0eXBlLCBtZXRoKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoZGVzY3IgPT0gTlVMTCkKKyAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgZXJyID0gUHlEaWN0X1NldEl0ZW1TdHJpbmcoZGljdCwgbWV0aC0+bWxfbmFtZSwgZGVzY3IpOworICAgICAgICBQeV9ERUNSRUYoZGVzY3IpOworICAgICAgICBpZiAoZXJyIDwgMCkKKyAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisgICAgcmV0dXJuIDA7Cit9CisKK3N0YXRpYyBpbnQKK2FkZF9tZW1iZXJzKFB5VHlwZU9iamVjdCAqdHlwZSwgUHlNZW1iZXJEZWYgKm1lbWIpCit7CisgICAgUHlPYmplY3QgKmRpY3QgPSB0eXBlLT50cF9kaWN0OworCisgICAgZm9yICg7IG1lbWItPm5hbWUgIT0gTlVMTDsgbWVtYisrKSB7CisgICAgICAgIFB5T2JqZWN0ICpkZXNjcjsKKyAgICAgICAgaWYgKFB5RGljdF9HZXRJdGVtU3RyaW5nKGRpY3QsIG1lbWItPm5hbWUpKQorICAgICAgICAgICAgY29udGludWU7CisgICAgICAgIGRlc2NyID0gUHlEZXNjcl9OZXdNZW1iZXIodHlwZSwgbWVtYik7CisgICAgICAgIGlmIChkZXNjciA9PSBOVUxMKQorICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICBpZiAoUHlEaWN0X1NldEl0ZW1TdHJpbmcoZGljdCwgbWVtYi0+bmFtZSwgZGVzY3IpIDwgMCkKKyAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgUHlfREVDUkVGKGRlc2NyKTsKKyAgICB9CisgICAgcmV0dXJuIDA7Cit9CisKK3N0YXRpYyBpbnQKK2FkZF9nZXRzZXQoUHlUeXBlT2JqZWN0ICp0eXBlLCBQeUdldFNldERlZiAqZ3NwKQoreworICAgIFB5T2JqZWN0ICpkaWN0ID0gdHlwZS0+dHBfZGljdDsKKworICAgIGZvciAoOyBnc3AtPm5hbWUgIT0gTlVMTDsgZ3NwKyspIHsKKyAgICAgICAgUHlPYmplY3QgKmRlc2NyOworICAgICAgICBpZiAoUHlEaWN0X0dldEl0ZW1TdHJpbmcoZGljdCwgZ3NwLT5uYW1lKSkKKyAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICBkZXNjciA9IFB5RGVzY3JfTmV3R2V0U2V0KHR5cGUsIGdzcCk7CisKKyAgICAgICAgaWYgKGRlc2NyID09IE5VTEwpCisgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgIGlmIChQeURpY3RfU2V0SXRlbVN0cmluZyhkaWN0LCBnc3AtPm5hbWUsIGRlc2NyKSA8IDApCisgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgIFB5X0RFQ1JFRihkZXNjcik7CisgICAgfQorICAgIHJldHVybiAwOworfQorCisjZGVmaW5lIEJVRkZFUl9GTEFHUyAoUHlfVFBGTEFHU19IQVZFX0dFVENIQVJCVUZGRVIgfCBQeV9UUEZMQUdTX0hBVkVfTkVXQlVGRkVSKQorCitzdGF0aWMgdm9pZAoraW5oZXJpdF9zcGVjaWFsKFB5VHlwZU9iamVjdCAqdHlwZSwgUHlUeXBlT2JqZWN0ICpiYXNlKQoreworICAgIFB5X3NzaXplX3Qgb2xkc2l6ZSwgbmV3c2l6ZTsKKworICAgIC8qIFNwZWNpYWwgZmxhZyBtYWdpYyAqLworICAgIGlmICghdHlwZS0+dHBfYXNfYnVmZmVyICYmIGJhc2UtPnRwX2FzX2J1ZmZlcikgeworICAgICAgICB0eXBlLT50cF9mbGFncyAmPSB+QlVGRkVSX0ZMQUdTOworICAgICAgICB0eXBlLT50cF9mbGFncyB8PQorICAgICAgICAgICAgYmFzZS0+dHBfZmxhZ3MgJiBCVUZGRVJfRkxBR1M7CisgICAgfQorICAgIGlmICghdHlwZS0+dHBfYXNfc2VxdWVuY2UgJiYgYmFzZS0+dHBfYXNfc2VxdWVuY2UpIHsKKyAgICAgICAgdHlwZS0+dHBfZmxhZ3MgJj0gflB5X1RQRkxBR1NfSEFWRV9TRVFVRU5DRV9JTjsKKyAgICAgICAgdHlwZS0+dHBfZmxhZ3MgfD0gYmFzZS0+dHBfZmxhZ3MgJiBQeV9UUEZMQUdTX0hBVkVfU0VRVUVOQ0VfSU47CisgICAgfQorICAgIGlmICgodHlwZS0+dHBfZmxhZ3MgJiBQeV9UUEZMQUdTX0hBVkVfSU5QTEFDRU9QUykgIT0KKyAgICAgICAgKGJhc2UtPnRwX2ZsYWdzICYgUHlfVFBGTEFHU19IQVZFX0lOUExBQ0VPUFMpKSB7CisgICAgICAgIGlmICgoIXR5cGUtPnRwX2FzX251bWJlciAmJiBiYXNlLT50cF9hc19udW1iZXIpIHx8CisgICAgICAgICAgICAoIXR5cGUtPnRwX2FzX3NlcXVlbmNlICYmIGJhc2UtPnRwX2FzX3NlcXVlbmNlKSkgeworICAgICAgICAgICAgdHlwZS0+dHBfZmxhZ3MgJj0gflB5X1RQRkxBR1NfSEFWRV9JTlBMQUNFT1BTOworICAgICAgICAgICAgaWYgKCF0eXBlLT50cF9hc19udW1iZXIgJiYgIXR5cGUtPnRwX2FzX3NlcXVlbmNlKSB7CisgICAgICAgICAgICAgICAgdHlwZS0+dHBfZmxhZ3MgfD0gYmFzZS0+dHBfZmxhZ3MgJgorICAgICAgICAgICAgICAgICAgICBQeV9UUEZMQUdTX0hBVkVfSU5QTEFDRU9QUzsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICAvKiBXb3cgKi8KKyAgICB9CisgICAgaWYgKCF0eXBlLT50cF9hc19udW1iZXIgJiYgYmFzZS0+dHBfYXNfbnVtYmVyKSB7CisgICAgICAgIHR5cGUtPnRwX2ZsYWdzICY9IH5QeV9UUEZMQUdTX0NIRUNLVFlQRVM7CisgICAgICAgIHR5cGUtPnRwX2ZsYWdzIHw9IGJhc2UtPnRwX2ZsYWdzICYgUHlfVFBGTEFHU19DSEVDS1RZUEVTOworICAgIH0KKworICAgIC8qIENvcHlpbmcgYmFzaWNzaXplIGlzIGNvbm5lY3RlZCB0byB0aGUgR0MgZmxhZ3MgKi8KKyAgICBvbGRzaXplID0gYmFzZS0+dHBfYmFzaWNzaXplOworICAgIG5ld3NpemUgPSB0eXBlLT50cF9iYXNpY3NpemUgPyB0eXBlLT50cF9iYXNpY3NpemUgOiBvbGRzaXplOworICAgIGlmICghKHR5cGUtPnRwX2ZsYWdzICYgUHlfVFBGTEFHU19IQVZFX0dDKSAmJgorICAgICAgICAoYmFzZS0+dHBfZmxhZ3MgJiBQeV9UUEZMQUdTX0hBVkVfR0MpICYmCisgICAgICAgICh0eXBlLT50cF9mbGFncyAmIFB5X1RQRkxBR1NfSEFWRV9SSUNIQ09NUEFSRS8qR0Mgc2xvdHMgZXhpc3QqLykgJiYKKyAgICAgICAgKCF0eXBlLT50cF90cmF2ZXJzZSAmJiAhdHlwZS0+dHBfY2xlYXIpKSB7CisgICAgICAgIHR5cGUtPnRwX2ZsYWdzIHw9IFB5X1RQRkxBR1NfSEFWRV9HQzsKKyAgICAgICAgaWYgKHR5cGUtPnRwX3RyYXZlcnNlID09IE5VTEwpCisgICAgICAgICAgICB0eXBlLT50cF90cmF2ZXJzZSA9IGJhc2UtPnRwX3RyYXZlcnNlOworICAgICAgICBpZiAodHlwZS0+dHBfY2xlYXIgPT0gTlVMTCkKKyAgICAgICAgICAgIHR5cGUtPnRwX2NsZWFyID0gYmFzZS0+dHBfY2xlYXI7CisgICAgfQorICAgIGlmICh0eXBlLT50cF9mbGFncyAmIGJhc2UtPnRwX2ZsYWdzICYgUHlfVFBGTEFHU19IQVZFX0NMQVNTKSB7CisgICAgICAgIC8qIFRoZSBjb25kaXRpb24gYmVsb3cgY291bGQgdXNlIHNvbWUgZXhwbGFuYXRpb24uCisgICAgICAgICAgIEl0IGFwcGVhcnMgdGhhdCB0cF9uZXcgaXMgbm90IGluaGVyaXRlZCBmb3Igc3RhdGljIHR5cGVzCisgICAgICAgICAgIHdob3NlIGJhc2UgY2xhc3MgaXMgJ29iamVjdCc7IHRoaXMgc2VlbXMgdG8gYmUgYSBwcmVjYXV0aW9uCisgICAgICAgICAgIHNvIHRoYXQgb2xkIGV4dGVuc2lvbiB0eXBlcyBkb24ndCBzdWRkZW5seSBiZWNvbWUKKyAgICAgICAgICAgY2FsbGFibGUgKG9iamVjdC5fX25ld19fIHdvdWxkbid0IGluc3VyZSB0aGUgaW52YXJpYW50cworICAgICAgICAgICB0aGF0IHRoZSBleHRlbnNpb24gdHlwZSdzIG93biBmYWN0b3J5IGZ1bmN0aW9uIGVuc3VyZXMpLgorICAgICAgICAgICBIZWFwIHR5cGVzLCBvZiBjb3Vyc2UsIGFyZSB1bmRlciBvdXIgY29udHJvbCwgc28gdGhleSBkbworICAgICAgICAgICBpbmhlcml0IHRwX25ldzsgc3RhdGljIGV4dGVuc2lvbiB0eXBlcyB0aGF0IHNwZWNpZnkgc29tZQorICAgICAgICAgICBvdGhlciBidWlsdC1pbiB0eXBlIGFzIHRoZSBkZWZhdWx0IGFyZSBjb25zaWRlcmVkCisgICAgICAgICAgIG5ldy1zdHlsZS1hd2FyZSBzbyB0aGV5IGFsc28gaW5oZXJpdCBvYmplY3QuX19uZXdfXy4gKi8KKyAgICAgICAgaWYgKGJhc2UgIT0gJlB5QmFzZU9iamVjdF9UeXBlIHx8CisgICAgICAgICAgICAodHlwZS0+dHBfZmxhZ3MgJiBQeV9UUEZMQUdTX0hFQVBUWVBFKSkgeworICAgICAgICAgICAgaWYgKHR5cGUtPnRwX25ldyA9PSBOVUxMKQorICAgICAgICAgICAgICAgIHR5cGUtPnRwX25ldyA9IGJhc2UtPnRwX25ldzsKKyAgICAgICAgfQorICAgIH0KKyAgICB0eXBlLT50cF9iYXNpY3NpemUgPSBuZXdzaXplOworCisgICAgLyogQ29weSBvdGhlciBub24tZnVuY3Rpb24gc2xvdHMgKi8KKworI3VuZGVmIENPUFlWQUwKKyNkZWZpbmUgQ09QWVZBTChTTE9UKSBcCisgICAgaWYgKHR5cGUtPlNMT1QgPT0gMCkgdHlwZS0+U0xPVCA9IGJhc2UtPlNMT1QKKworICAgIENPUFlWQUwodHBfaXRlbXNpemUpOworICAgIGlmICh0eXBlLT50cF9mbGFncyAmIGJhc2UtPnRwX2ZsYWdzICYgUHlfVFBGTEFHU19IQVZFX1dFQUtSRUZTKSB7CisgICAgICAgIENPUFlWQUwodHBfd2Vha2xpc3RvZmZzZXQpOworICAgIH0KKyAgICBpZiAodHlwZS0+dHBfZmxhZ3MgJiBiYXNlLT50cF9mbGFncyAmIFB5X1RQRkxBR1NfSEFWRV9DTEFTUykgeworICAgICAgICBDT1BZVkFMKHRwX2RpY3RvZmZzZXQpOworICAgIH0KKworICAgIC8qIFNldHVwIGZhc3Qgc3ViY2xhc3MgZmxhZ3MgKi8KKyAgICBpZiAoUHlUeXBlX0lzU3VidHlwZShiYXNlLCAoUHlUeXBlT2JqZWN0KilQeUV4Y19CYXNlRXhjZXB0aW9uKSkKKyAgICAgICAgdHlwZS0+dHBfZmxhZ3MgfD0gUHlfVFBGTEFHU19CQVNFX0VYQ19TVUJDTEFTUzsKKyAgICBlbHNlIGlmIChQeVR5cGVfSXNTdWJ0eXBlKGJhc2UsICZQeVR5cGVfVHlwZSkpCisgICAgICAgIHR5cGUtPnRwX2ZsYWdzIHw9IFB5X1RQRkxBR1NfVFlQRV9TVUJDTEFTUzsKKyAgICBlbHNlIGlmIChQeVR5cGVfSXNTdWJ0eXBlKGJhc2UsICZQeUludF9UeXBlKSkKKyAgICAgICAgdHlwZS0+dHBfZmxhZ3MgfD0gUHlfVFBGTEFHU19JTlRfU1VCQ0xBU1M7CisgICAgZWxzZSBpZiAoUHlUeXBlX0lzU3VidHlwZShiYXNlLCAmUHlMb25nX1R5cGUpKQorICAgICAgICB0eXBlLT50cF9mbGFncyB8PSBQeV9UUEZMQUdTX0xPTkdfU1VCQ0xBU1M7CisgICAgZWxzZSBpZiAoUHlUeXBlX0lzU3VidHlwZShiYXNlLCAmUHlTdHJpbmdfVHlwZSkpCisgICAgICAgIHR5cGUtPnRwX2ZsYWdzIHw9IFB5X1RQRkxBR1NfU1RSSU5HX1NVQkNMQVNTOworI2lmZGVmIFB5X1VTSU5HX1VOSUNPREUKKyAgICBlbHNlIGlmIChQeVR5cGVfSXNTdWJ0eXBlKGJhc2UsICZQeVVuaWNvZGVfVHlwZSkpCisgICAgICAgIHR5cGUtPnRwX2ZsYWdzIHw9IFB5X1RQRkxBR1NfVU5JQ09ERV9TVUJDTEFTUzsKKyNlbmRpZgorICAgIGVsc2UgaWYgKFB5VHlwZV9Jc1N1YnR5cGUoYmFzZSwgJlB5VHVwbGVfVHlwZSkpCisgICAgICAgIHR5cGUtPnRwX2ZsYWdzIHw9IFB5X1RQRkxBR1NfVFVQTEVfU1VCQ0xBU1M7CisgICAgZWxzZSBpZiAoUHlUeXBlX0lzU3VidHlwZShiYXNlLCAmUHlMaXN0X1R5cGUpKQorICAgICAgICB0eXBlLT50cF9mbGFncyB8PSBQeV9UUEZMQUdTX0xJU1RfU1VCQ0xBU1M7CisgICAgZWxzZSBpZiAoUHlUeXBlX0lzU3VidHlwZShiYXNlLCAmUHlEaWN0X1R5cGUpKQorICAgICAgICB0eXBlLT50cF9mbGFncyB8PSBQeV9UUEZMQUdTX0RJQ1RfU1VCQ0xBU1M7Cit9CisKK3N0YXRpYyBpbnQKK292ZXJyaWRlc19uYW1lKFB5VHlwZU9iamVjdCAqdHlwZSwgY2hhciAqbmFtZSkKK3sKKyAgICBQeU9iamVjdCAqZGljdCA9IHR5cGUtPnRwX2RpY3Q7CisKKyAgICBhc3NlcnQoZGljdCAhPSBOVUxMKTsKKyAgICBpZiAoUHlEaWN0X0dldEl0ZW1TdHJpbmcoZGljdCwgbmFtZSkgIT0gTlVMTCkgeworICAgICAgICByZXR1cm4gMTsKKyAgICB9CisgICAgcmV0dXJuIDA7Cit9CisKKyNkZWZpbmUgT1ZFUlJJREVTX0hBU0goeCkgICAgICAgb3ZlcnJpZGVzX25hbWUoeCwgIl9faGFzaF9fIikKKyNkZWZpbmUgT1ZFUlJJREVTX0VRKHgpICAgICAgICAgb3ZlcnJpZGVzX25hbWUoeCwgIl9fZXFfXyIpCisKK3N0YXRpYyB2b2lkCitpbmhlcml0X3Nsb3RzKFB5VHlwZU9iamVjdCAqdHlwZSwgUHlUeXBlT2JqZWN0ICpiYXNlKQoreworICAgIFB5VHlwZU9iamVjdCAqYmFzZWJhc2U7CisKKyN1bmRlZiBTTE9UREVGSU5FRAorI3VuZGVmIENPUFlTTE9UCisjdW5kZWYgQ09QWU5VTQorI3VuZGVmIENPUFlTRVEKKyN1bmRlZiBDT1BZTUFQCisjdW5kZWYgQ09QWUJVRgorCisjZGVmaW5lIFNMT1RERUZJTkVEKFNMT1QpIFwKKyAgICAoYmFzZS0+U0xPVCAhPSAwICYmIFwKKyAgICAgKGJhc2ViYXNlID09IE5VTEwgfHwgYmFzZS0+U0xPVCAhPSBiYXNlYmFzZS0+U0xPVCkpCisKKyNkZWZpbmUgQ09QWVNMT1QoU0xPVCkgXAorICAgIGlmICghdHlwZS0+U0xPVCAmJiBTTE9UREVGSU5FRChTTE9UKSkgdHlwZS0+U0xPVCA9IGJhc2UtPlNMT1QKKworI2RlZmluZSBDT1BZTlVNKFNMT1QpIENPUFlTTE9UKHRwX2FzX251bWJlci0+U0xPVCkKKyNkZWZpbmUgQ09QWVNFUShTTE9UKSBDT1BZU0xPVCh0cF9hc19zZXF1ZW5jZS0+U0xPVCkKKyNkZWZpbmUgQ09QWU1BUChTTE9UKSBDT1BZU0xPVCh0cF9hc19tYXBwaW5nLT5TTE9UKQorI2RlZmluZSBDT1BZQlVGKFNMT1QpIENPUFlTTE9UKHRwX2FzX2J1ZmZlci0+U0xPVCkKKworICAgIC8qIFRoaXMgd29uJ3QgaW5oZXJpdCBpbmRpcmVjdCBzbG90cyAoZnJvbSB0cF9hc19udW1iZXIgZXRjLikKKyAgICAgICBpZiB0eXBlIGRvZXNuJ3QgcHJvdmlkZSB0aGUgc3BhY2UuICovCisKKyAgICBpZiAodHlwZS0+dHBfYXNfbnVtYmVyICE9IE5VTEwgJiYgYmFzZS0+dHBfYXNfbnVtYmVyICE9IE5VTEwpIHsKKyAgICAgICAgYmFzZWJhc2UgPSBiYXNlLT50cF9iYXNlOworICAgICAgICBpZiAoYmFzZWJhc2UtPnRwX2FzX251bWJlciA9PSBOVUxMKQorICAgICAgICAgICAgYmFzZWJhc2UgPSBOVUxMOworICAgICAgICBDT1BZTlVNKG5iX2FkZCk7CisgICAgICAgIENPUFlOVU0obmJfc3VidHJhY3QpOworICAgICAgICBDT1BZTlVNKG5iX211bHRpcGx5KTsKKyAgICAgICAgQ09QWU5VTShuYl9kaXZpZGUpOworICAgICAgICBDT1BZTlVNKG5iX3JlbWFpbmRlcik7CisgICAgICAgIENPUFlOVU0obmJfZGl2bW9kKTsKKyAgICAgICAgQ09QWU5VTShuYl9wb3dlcik7CisgICAgICAgIENPUFlOVU0obmJfbmVnYXRpdmUpOworICAgICAgICBDT1BZTlVNKG5iX3Bvc2l0aXZlKTsKKyAgICAgICAgQ09QWU5VTShuYl9hYnNvbHV0ZSk7CisgICAgICAgIENPUFlOVU0obmJfbm9uemVybyk7CisgICAgICAgIENPUFlOVU0obmJfaW52ZXJ0KTsKKyAgICAgICAgQ09QWU5VTShuYl9sc2hpZnQpOworICAgICAgICBDT1BZTlVNKG5iX3JzaGlmdCk7CisgICAgICAgIENPUFlOVU0obmJfYW5kKTsKKyAgICAgICAgQ09QWU5VTShuYl94b3IpOworICAgICAgICBDT1BZTlVNKG5iX29yKTsKKyAgICAgICAgQ09QWU5VTShuYl9jb2VyY2UpOworICAgICAgICBDT1BZTlVNKG5iX2ludCk7CisgICAgICAgIENPUFlOVU0obmJfbG9uZyk7CisgICAgICAgIENPUFlOVU0obmJfZmxvYXQpOworICAgICAgICBDT1BZTlVNKG5iX29jdCk7CisgICAgICAgIENPUFlOVU0obmJfaGV4KTsKKyAgICAgICAgQ09QWU5VTShuYl9pbnBsYWNlX2FkZCk7CisgICAgICAgIENPUFlOVU0obmJfaW5wbGFjZV9zdWJ0cmFjdCk7CisgICAgICAgIENPUFlOVU0obmJfaW5wbGFjZV9tdWx0aXBseSk7CisgICAgICAgIENPUFlOVU0obmJfaW5wbGFjZV9kaXZpZGUpOworICAgICAgICBDT1BZTlVNKG5iX2lucGxhY2VfcmVtYWluZGVyKTsKKyAgICAgICAgQ09QWU5VTShuYl9pbnBsYWNlX3Bvd2VyKTsKKyAgICAgICAgQ09QWU5VTShuYl9pbnBsYWNlX2xzaGlmdCk7CisgICAgICAgIENPUFlOVU0obmJfaW5wbGFjZV9yc2hpZnQpOworICAgICAgICBDT1BZTlVNKG5iX2lucGxhY2VfYW5kKTsKKyAgICAgICAgQ09QWU5VTShuYl9pbnBsYWNlX3hvcik7CisgICAgICAgIENPUFlOVU0obmJfaW5wbGFjZV9vcik7CisgICAgICAgIGlmIChiYXNlLT50cF9mbGFncyAmIFB5X1RQRkxBR1NfQ0hFQ0tUWVBFUykgeworICAgICAgICAgICAgQ09QWU5VTShuYl90cnVlX2RpdmlkZSk7CisgICAgICAgICAgICBDT1BZTlVNKG5iX2Zsb29yX2RpdmlkZSk7CisgICAgICAgICAgICBDT1BZTlVNKG5iX2lucGxhY2VfdHJ1ZV9kaXZpZGUpOworICAgICAgICAgICAgQ09QWU5VTShuYl9pbnBsYWNlX2Zsb29yX2RpdmlkZSk7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGJhc2UtPnRwX2ZsYWdzICYgUHlfVFBGTEFHU19IQVZFX0lOREVYKSB7CisgICAgICAgICAgICBDT1BZTlVNKG5iX2luZGV4KTsKKyAgICAgICAgfQorICAgIH0KKworICAgIGlmICh0eXBlLT50cF9hc19zZXF1ZW5jZSAhPSBOVUxMICYmIGJhc2UtPnRwX2FzX3NlcXVlbmNlICE9IE5VTEwpIHsKKyAgICAgICAgYmFzZWJhc2UgPSBiYXNlLT50cF9iYXNlOworICAgICAgICBpZiAoYmFzZWJhc2UtPnRwX2FzX3NlcXVlbmNlID09IE5VTEwpCisgICAgICAgICAgICBiYXNlYmFzZSA9IE5VTEw7CisgICAgICAgIENPUFlTRVEoc3FfbGVuZ3RoKTsKKyAgICAgICAgQ09QWVNFUShzcV9jb25jYXQpOworICAgICAgICBDT1BZU0VRKHNxX3JlcGVhdCk7CisgICAgICAgIENPUFlTRVEoc3FfaXRlbSk7CisgICAgICAgIENPUFlTRVEoc3Ffc2xpY2UpOworICAgICAgICBDT1BZU0VRKHNxX2Fzc19pdGVtKTsKKyAgICAgICAgQ09QWVNFUShzcV9hc3Nfc2xpY2UpOworICAgICAgICBDT1BZU0VRKHNxX2NvbnRhaW5zKTsKKyAgICAgICAgQ09QWVNFUShzcV9pbnBsYWNlX2NvbmNhdCk7CisgICAgICAgIENPUFlTRVEoc3FfaW5wbGFjZV9yZXBlYXQpOworICAgIH0KKworICAgIGlmICh0eXBlLT50cF9hc19tYXBwaW5nICE9IE5VTEwgJiYgYmFzZS0+dHBfYXNfbWFwcGluZyAhPSBOVUxMKSB7CisgICAgICAgIGJhc2ViYXNlID0gYmFzZS0+dHBfYmFzZTsKKyAgICAgICAgaWYgKGJhc2ViYXNlLT50cF9hc19tYXBwaW5nID09IE5VTEwpCisgICAgICAgICAgICBiYXNlYmFzZSA9IE5VTEw7CisgICAgICAgIENPUFlNQVAobXBfbGVuZ3RoKTsKKyAgICAgICAgQ09QWU1BUChtcF9zdWJzY3JpcHQpOworICAgICAgICBDT1BZTUFQKG1wX2Fzc19zdWJzY3JpcHQpOworICAgIH0KKworICAgIGlmICh0eXBlLT50cF9hc19idWZmZXIgIT0gTlVMTCAmJiBiYXNlLT50cF9hc19idWZmZXIgIT0gTlVMTCkgeworICAgICAgICBiYXNlYmFzZSA9IGJhc2UtPnRwX2Jhc2U7CisgICAgICAgIGlmIChiYXNlYmFzZS0+dHBfYXNfYnVmZmVyID09IE5VTEwpCisgICAgICAgICAgICBiYXNlYmFzZSA9IE5VTEw7CisgICAgICAgIENPUFlCVUYoYmZfZ2V0cmVhZGJ1ZmZlcik7CisgICAgICAgIENPUFlCVUYoYmZfZ2V0d3JpdGVidWZmZXIpOworICAgICAgICBDT1BZQlVGKGJmX2dldHNlZ2NvdW50KTsKKyAgICAgICAgQ09QWUJVRihiZl9nZXRjaGFyYnVmZmVyKTsKKyAgICAgICAgQ09QWUJVRihiZl9nZXRidWZmZXIpOworICAgICAgICBDT1BZQlVGKGJmX3JlbGVhc2VidWZmZXIpOworICAgIH0KKworICAgIGJhc2ViYXNlID0gYmFzZS0+dHBfYmFzZTsKKworICAgIENPUFlTTE9UKHRwX2RlYWxsb2MpOworICAgIENPUFlTTE9UKHRwX3ByaW50KTsKKyAgICBpZiAodHlwZS0+dHBfZ2V0YXR0ciA9PSBOVUxMICYmIHR5cGUtPnRwX2dldGF0dHJvID09IE5VTEwpIHsKKyAgICAgICAgdHlwZS0+dHBfZ2V0YXR0ciA9IGJhc2UtPnRwX2dldGF0dHI7CisgICAgICAgIHR5cGUtPnRwX2dldGF0dHJvID0gYmFzZS0+dHBfZ2V0YXR0cm87CisgICAgfQorICAgIGlmICh0eXBlLT50cF9zZXRhdHRyID09IE5VTEwgJiYgdHlwZS0+dHBfc2V0YXR0cm8gPT0gTlVMTCkgeworICAgICAgICB0eXBlLT50cF9zZXRhdHRyID0gYmFzZS0+dHBfc2V0YXR0cjsKKyAgICAgICAgdHlwZS0+dHBfc2V0YXR0cm8gPSBiYXNlLT50cF9zZXRhdHRybzsKKyAgICB9CisgICAgLyogdHBfY29tcGFyZSBzZWUgdHBfcmljaGNvbXBhcmUgKi8KKyAgICBDT1BZU0xPVCh0cF9yZXByKTsKKyAgICAvKiB0cF9oYXNoIHNlZSB0cF9yaWNoY29tcGFyZSAqLworICAgIENPUFlTTE9UKHRwX2NhbGwpOworICAgIENPUFlTTE9UKHRwX3N0cik7CisgICAgaWYgKHR5cGUtPnRwX2ZsYWdzICYgYmFzZS0+dHBfZmxhZ3MgJiBQeV9UUEZMQUdTX0hBVkVfUklDSENPTVBBUkUpIHsKKyAgICAgICAgaWYgKHR5cGUtPnRwX2NvbXBhcmUgPT0gTlVMTCAmJgorICAgICAgICAgICAgdHlwZS0+dHBfcmljaGNvbXBhcmUgPT0gTlVMTCAmJgorICAgICAgICAgICAgdHlwZS0+dHBfaGFzaCA9PSBOVUxMKQorICAgICAgICB7CisgICAgICAgICAgICB0eXBlLT50cF9jb21wYXJlID0gYmFzZS0+dHBfY29tcGFyZTsKKyAgICAgICAgICAgIHR5cGUtPnRwX3JpY2hjb21wYXJlID0gYmFzZS0+dHBfcmljaGNvbXBhcmU7CisgICAgICAgICAgICB0eXBlLT50cF9oYXNoID0gYmFzZS0+dHBfaGFzaDsKKyAgICAgICAgICAgIC8qIENoZWNrIGZvciBjaGFuZ2VzIHRvIGluaGVyaXRlZCBtZXRob2RzIGluIFB5M2sqLworICAgICAgICAgICAgaWYgKFB5X1B5M2tXYXJuaW5nRmxhZykgeworICAgICAgICAgICAgICAgIGlmIChiYXNlLT50cF9oYXNoICYmCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChiYXNlLT50cF9oYXNoICE9IFB5T2JqZWN0X0hhc2hOb3RJbXBsZW1lbnRlZCkgJiYKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIU9WRVJSSURFU19IQVNIKHR5cGUpKSB7CisgICAgICAgICAgICAgICAgICAgIGlmIChPVkVSUklERVNfRVEodHlwZSkpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGlmIChQeUVycl9XYXJuUHkzaygiT3ZlcnJpZGluZyAiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIl9fZXFfXyBibG9ja3MgaW5oZXJpdGFuY2UgIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJvZiBfX2hhc2hfXyBpbiAzLngiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDEpIDwgMCkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBYWFggVGhpcyBpc24ndCByaWdodC4gIElmIHRoZSB3YXJuaW5nIGlzIHR1cm5lZAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludG8gYW4gZXhjZXB0aW9uLCB3ZSBzaG91bGQgYmUgY29tbXVuaWNhdGluZworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoZSBlcnJvciBiYWNrIHRvIHRoZSBjYWxsZXIsIGJ1dCBmaWd1cmluZyBvdXQKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBob3cgdG8gY2xlYW4gdXAgaW4gdGhhdCBjYXNlIGlzIHRyaWNreS4gIFNlZQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzc3VlIDg2MjcgZm9yIG1vcmUuICovCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHlFcnJfQ2xlYXIoKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKyAgICBlbHNlIHsKKyAgICAgICAgQ09QWVNMT1QodHBfY29tcGFyZSk7CisgICAgfQorICAgIGlmICh0eXBlLT50cF9mbGFncyAmIGJhc2UtPnRwX2ZsYWdzICYgUHlfVFBGTEFHU19IQVZFX0lURVIpIHsKKyAgICAgICAgQ09QWVNMT1QodHBfaXRlcik7CisgICAgICAgIENPUFlTTE9UKHRwX2l0ZXJuZXh0KTsKKyAgICB9CisgICAgaWYgKHR5cGUtPnRwX2ZsYWdzICYgYmFzZS0+dHBfZmxhZ3MgJiBQeV9UUEZMQUdTX0hBVkVfQ0xBU1MpIHsKKyAgICAgICAgQ09QWVNMT1QodHBfZGVzY3JfZ2V0KTsKKyAgICAgICAgQ09QWVNMT1QodHBfZGVzY3Jfc2V0KTsKKyAgICAgICAgQ09QWVNMT1QodHBfZGljdG9mZnNldCk7CisgICAgICAgIENPUFlTTE9UKHRwX2luaXQpOworICAgICAgICBDT1BZU0xPVCh0cF9hbGxvYyk7CisgICAgICAgIENPUFlTTE9UKHRwX2lzX2djKTsKKyAgICAgICAgaWYgKCh0eXBlLT50cF9mbGFncyAmIFB5X1RQRkxBR1NfSEFWRV9HQykgPT0KKyAgICAgICAgICAgIChiYXNlLT50cF9mbGFncyAmIFB5X1RQRkxBR1NfSEFWRV9HQykpIHsKKyAgICAgICAgICAgIC8qIFRoZXkgYWdyZWUgYWJvdXQgZ2MuICovCisgICAgICAgICAgICBDT1BZU0xPVCh0cF9mcmVlKTsKKyAgICAgICAgfQorICAgICAgICBlbHNlIGlmICgodHlwZS0+dHBfZmxhZ3MgJiBQeV9UUEZMQUdTX0hBVkVfR0MpICYmCisgICAgICAgICAgICAgICAgIHR5cGUtPnRwX2ZyZWUgPT0gTlVMTCAmJgorICAgICAgICAgICAgICAgICBiYXNlLT50cF9mcmVlID09IF9QeU9iamVjdF9EZWwpIHsKKyAgICAgICAgICAgIC8qIEEgYml0IG9mIG1hZ2ljIHRvIHBsdWcgaW4gdGhlIGNvcnJlY3QgZGVmYXVsdAorICAgICAgICAgICAgICogdHBfZnJlZSBmdW5jdGlvbiB3aGVuIGEgZGVyaXZlZCBjbGFzcyBhZGRzIGdjLAorICAgICAgICAgICAgICogZGlkbid0IGRlZmluZSB0cF9mcmVlLCBhbmQgdGhlIGJhc2UgdXNlcyB0aGUKKyAgICAgICAgICAgICAqIGRlZmF1bHQgbm9uLWdjIHRwX2ZyZWUuCisgICAgICAgICAgICAgKi8KKyAgICAgICAgICAgIHR5cGUtPnRwX2ZyZWUgPSBQeU9iamVjdF9HQ19EZWw7CisgICAgICAgIH0KKyAgICAgICAgLyogZWxzZSB0aGV5IGRpZG4ndCBhZ3JlZSBhYm91dCBnYywgYW5kIHRoZXJlIGlzbid0IHNvbWV0aGluZworICAgICAgICAgKiBvYnZpb3VzIHRvIGJlIGRvbmUgLS0gdGhlIHR5cGUgaXMgb24gaXRzIG93bi4KKyAgICAgICAgICovCisgICAgfQorfQorCitzdGF0aWMgaW50IGFkZF9vcGVyYXRvcnMoUHlUeXBlT2JqZWN0ICopOworCitpbnQKK1B5VHlwZV9SZWFkeShQeVR5cGVPYmplY3QgKnR5cGUpCit7CisgICAgUHlPYmplY3QgKmRpY3QsICpiYXNlczsKKyAgICBQeVR5cGVPYmplY3QgKmJhc2U7CisgICAgUHlfc3NpemVfdCBpLCBuOworCisgICAgaWYgKHR5cGUtPnRwX2ZsYWdzICYgUHlfVFBGTEFHU19SRUFEWSkgeworICAgICAgICBhc3NlcnQodHlwZS0+dHBfZGljdCAhPSBOVUxMKTsKKyAgICAgICAgcmV0dXJuIDA7CisgICAgfQorICAgIGFzc2VydCgodHlwZS0+dHBfZmxhZ3MgJiBQeV9UUEZMQUdTX1JFQURZSU5HKSA9PSAwKTsKKworICAgIHR5cGUtPnRwX2ZsYWdzIHw9IFB5X1RQRkxBR1NfUkVBRFlJTkc7CisKKyNpZmRlZiBQeV9UUkFDRV9SRUZTCisgICAgLyogUHlUeXBlX1JlYWR5IGlzIHRoZSBjbG9zZXN0IHRoaW5nIHdlIGhhdmUgdG8gYSBjaG9rZSBwb2ludAorICAgICAqIGZvciB0eXBlIG9iamVjdHMsIHNvIGlzIHRoZSBiZXN0IHBsYWNlIEkgY2FuIHRoaW5rIG9mIHRvIHRyeQorICAgICAqIHRvIGdldCB0eXBlIG9iamVjdHMgaW50byB0aGUgZG91Ymx5LWxpbmtlZCBsaXN0IG9mIGFsbCBvYmplY3RzLgorICAgICAqIFN0aWxsLCBub3QgYWxsIHR5cGUgb2JqZWN0cyBnbyB0aHJ1IFB5VHlwZV9SZWFkeS4KKyAgICAgKi8KKyAgICBfUHlfQWRkVG9BbGxPYmplY3RzKChQeU9iamVjdCAqKXR5cGUsIDApOworI2VuZGlmCisKKyAgICAvKiBJbml0aWFsaXplIHRwX2Jhc2UgKGRlZmF1bHRzIHRvIEJhc2VPYmplY3QgdW5sZXNzIHRoYXQncyB1cykgKi8KKyAgICBiYXNlID0gdHlwZS0+dHBfYmFzZTsKKyAgICBpZiAoYmFzZSA9PSBOVUxMICYmIHR5cGUgIT0gJlB5QmFzZU9iamVjdF9UeXBlKSB7CisgICAgICAgIGJhc2UgPSB0eXBlLT50cF9iYXNlID0gJlB5QmFzZU9iamVjdF9UeXBlOworICAgICAgICBQeV9JTkNSRUYoYmFzZSk7CisgICAgfQorCisgICAgLyogTm93IHRoZSBvbmx5IHdheSBiYXNlIGNhbiBzdGlsbCBiZSBOVUxMIGlzIGlmIHR5cGUgaXMKKyAgICAgKiAmUHlCYXNlT2JqZWN0X1R5cGUuCisgICAgICovCisKKyAgICAvKiBJbml0aWFsaXplIHRoZSBiYXNlIGNsYXNzICovCisgICAgaWYgKGJhc2UgJiYgYmFzZS0+dHBfZGljdCA9PSBOVUxMKSB7CisgICAgICAgIGlmIChQeVR5cGVfUmVhZHkoYmFzZSkgPCAwKQorICAgICAgICAgICAgZ290byBlcnJvcjsKKyAgICB9CisKKyAgICAvKiBJbml0aWFsaXplIG9iX3R5cGUgaWYgTlVMTC4gICAgICBUaGlzIG1lYW5zIGV4dGVuc2lvbnMgdGhhdCB3YW50IHRvIGJlCisgICAgICAgY29tcGlsYWJsZSBzZXBhcmF0ZWx5IG9uIFdpbmRvd3MgY2FuIGNhbGwgUHlUeXBlX1JlYWR5KCkgaW5zdGVhZCBvZgorICAgICAgIGluaXRpYWxpemluZyB0aGUgb2JfdHlwZSBmaWVsZCBvZiB0aGVpciB0eXBlIG9iamVjdHMuICovCisgICAgLyogVGhlIHRlc3QgZm9yIGJhc2UgIT0gTlVMTCBpcyByZWFsbHkgdW5uZWNlc3NhcnksIHNpbmNlIGJhc2UgaXMgb25seQorICAgICAgIE5VTEwgd2hlbiB0eXBlIGlzICZQeUJhc2VPYmplY3RfVHlwZSwgYW5kIHdlIGtub3cgaXRzIG9iX3R5cGUgaXMKKyAgICAgICBub3QgTlVMTCAoaXQncyBpbml0aWFsaXplZCB0byAmUHlUeXBlX1R5cGUpLiAgICAgIEJ1dCBjb3Zlcml0eSBkb2Vzbid0CisgICAgICAga25vdyB0aGF0LiAqLworICAgIGlmIChQeV9UWVBFKHR5cGUpID09IE5VTEwgJiYgYmFzZSAhPSBOVUxMKQorICAgICAgICBQeV9UWVBFKHR5cGUpID0gUHlfVFlQRShiYXNlKTsKKworICAgIC8qIEluaXRpYWxpemUgdHBfYmFzZXMgKi8KKyAgICBiYXNlcyA9IHR5cGUtPnRwX2Jhc2VzOworICAgIGlmIChiYXNlcyA9PSBOVUxMKSB7CisgICAgICAgIGlmIChiYXNlID09IE5VTEwpCisgICAgICAgICAgICBiYXNlcyA9IFB5VHVwbGVfTmV3KDApOworICAgICAgICBlbHNlCisgICAgICAgICAgICBiYXNlcyA9IFB5VHVwbGVfUGFjaygxLCBiYXNlKTsKKyAgICAgICAgaWYgKGJhc2VzID09IE5VTEwpCisgICAgICAgICAgICBnb3RvIGVycm9yOworICAgICAgICB0eXBlLT50cF9iYXNlcyA9IGJhc2VzOworICAgIH0KKworICAgIC8qIEluaXRpYWxpemUgdHBfZGljdCAqLworICAgIGRpY3QgPSB0eXBlLT50cF9kaWN0OworICAgIGlmIChkaWN0ID09IE5VTEwpIHsKKyAgICAgICAgZGljdCA9IFB5RGljdF9OZXcoKTsKKyAgICAgICAgaWYgKGRpY3QgPT0gTlVMTCkKKyAgICAgICAgICAgIGdvdG8gZXJyb3I7CisgICAgICAgIHR5cGUtPnRwX2RpY3QgPSBkaWN0OworICAgIH0KKworICAgIC8qIEFkZCB0eXBlLXNwZWNpZmljIGRlc2NyaXB0b3JzIHRvIHRwX2RpY3QgKi8KKyAgICBpZiAoYWRkX29wZXJhdG9ycyh0eXBlKSA8IDApCisgICAgICAgIGdvdG8gZXJyb3I7CisgICAgaWYgKHR5cGUtPnRwX21ldGhvZHMgIT0gTlVMTCkgeworICAgICAgICBpZiAoYWRkX21ldGhvZHModHlwZSwgdHlwZS0+dHBfbWV0aG9kcykgPCAwKQorICAgICAgICAgICAgZ290byBlcnJvcjsKKyAgICB9CisgICAgaWYgKHR5cGUtPnRwX21lbWJlcnMgIT0gTlVMTCkgeworICAgICAgICBpZiAoYWRkX21lbWJlcnModHlwZSwgdHlwZS0+dHBfbWVtYmVycykgPCAwKQorICAgICAgICAgICAgZ290byBlcnJvcjsKKyAgICB9CisgICAgaWYgKHR5cGUtPnRwX2dldHNldCAhPSBOVUxMKSB7CisgICAgICAgIGlmIChhZGRfZ2V0c2V0KHR5cGUsIHR5cGUtPnRwX2dldHNldCkgPCAwKQorICAgICAgICAgICAgZ290byBlcnJvcjsKKyAgICB9CisKKyAgICAvKiBDYWxjdWxhdGUgbWV0aG9kIHJlc29sdXRpb24gb3JkZXIgKi8KKyAgICBpZiAobXJvX2ludGVybmFsKHR5cGUpIDwgMCkgeworICAgICAgICBnb3RvIGVycm9yOworICAgIH0KKworICAgIC8qIEluaGVyaXQgc3BlY2lhbCBmbGFncyBmcm9tIGRvbWluYW50IGJhc2UgKi8KKyAgICBpZiAodHlwZS0+dHBfYmFzZSAhPSBOVUxMKQorICAgICAgICBpbmhlcml0X3NwZWNpYWwodHlwZSwgdHlwZS0+dHBfYmFzZSk7CisKKyAgICAvKiBJbml0aWFsaXplIHRwX2RpY3QgcHJvcGVybHkgKi8KKyAgICBiYXNlcyA9IHR5cGUtPnRwX21ybzsKKyAgICBhc3NlcnQoYmFzZXMgIT0gTlVMTCk7CisgICAgYXNzZXJ0KFB5VHVwbGVfQ2hlY2soYmFzZXMpKTsKKyAgICBuID0gUHlUdXBsZV9HRVRfU0laRShiYXNlcyk7CisgICAgZm9yIChpID0gMTsgaSA8IG47IGkrKykgeworICAgICAgICBQeU9iamVjdCAqYiA9IFB5VHVwbGVfR0VUX0lURU0oYmFzZXMsIGkpOworICAgICAgICBpZiAoUHlUeXBlX0NoZWNrKGIpKQorICAgICAgICAgICAgaW5oZXJpdF9zbG90cyh0eXBlLCAoUHlUeXBlT2JqZWN0ICopYik7CisgICAgfQorCisgICAgLyogU2FuaXR5IGNoZWNrIGZvciB0cF9mcmVlLiAqLworICAgIGlmIChQeVR5cGVfSVNfR0ModHlwZSkgJiYgKHR5cGUtPnRwX2ZsYWdzICYgUHlfVFBGTEFHU19CQVNFVFlQRSkgJiYKKyAgICAgICAgKHR5cGUtPnRwX2ZyZWUgPT0gTlVMTCB8fCB0eXBlLT50cF9mcmVlID09IFB5T2JqZWN0X0RlbCkpIHsKKyAgICAgICAgLyogVGhpcyBiYXNlIGNsYXNzIG5lZWRzIHRvIGNhbGwgdHBfZnJlZSwgYnV0IGRvZXNuJ3QgaGF2ZQorICAgICAgICAgKiBvbmUsIG9yIGl0cyB0cF9mcmVlIGlzIGZvciBub24tZ2MnZWQgb2JqZWN0cy4KKyAgICAgICAgICovCisgICAgICAgIFB5RXJyX0Zvcm1hdChQeUV4Y19UeXBlRXJyb3IsICJ0eXBlICclLjEwMHMnIHBhcnRpY2lwYXRlcyBpbiAiCisgICAgICAgICAgICAgICAgICAgICAiZ2MgYW5kIGlzIGEgYmFzZSB0eXBlIGJ1dCBoYXMgaW5hcHByb3ByaWF0ZSAiCisgICAgICAgICAgICAgICAgICAgICAidHBfZnJlZSBzbG90IiwKKyAgICAgICAgICAgICAgICAgICAgIHR5cGUtPnRwX25hbWUpOworICAgICAgICBnb3RvIGVycm9yOworICAgIH0KKworICAgIC8qIGlmIHRoZSB0eXBlIGRpY3Rpb25hcnkgZG9lc24ndCBjb250YWluIGEgX19kb2NfXywgc2V0IGl0IGZyb20KKyAgICAgICB0aGUgdHBfZG9jIHNsb3QuCisgICAgICovCisgICAgaWYgKFB5RGljdF9HZXRJdGVtU3RyaW5nKHR5cGUtPnRwX2RpY3QsICJfX2RvY19fIikgPT0gTlVMTCkgeworICAgICAgICBpZiAodHlwZS0+dHBfZG9jICE9IE5VTEwpIHsKKyAgICAgICAgICAgIFB5T2JqZWN0ICpkb2MgPSBQeVN0cmluZ19Gcm9tU3RyaW5nKHR5cGUtPnRwX2RvYyk7CisgICAgICAgICAgICBpZiAoZG9jID09IE5VTEwpCisgICAgICAgICAgICAgICAgZ290byBlcnJvcjsKKyAgICAgICAgICAgIFB5RGljdF9TZXRJdGVtU3RyaW5nKHR5cGUtPnRwX2RpY3QsICJfX2RvY19fIiwgZG9jKTsKKyAgICAgICAgICAgIFB5X0RFQ1JFRihkb2MpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgUHlEaWN0X1NldEl0ZW1TdHJpbmcodHlwZS0+dHBfZGljdCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJfX2RvY19fIiwgUHlfTm9uZSk7CisgICAgICAgIH0KKyAgICB9CisKKyAgICAvKiBTb21lIG1vcmUgc3BlY2lhbCBzdHVmZiAqLworICAgIGJhc2UgPSB0eXBlLT50cF9iYXNlOworICAgIGlmIChiYXNlICE9IE5VTEwpIHsKKyAgICAgICAgaWYgKHR5cGUtPnRwX2FzX251bWJlciA9PSBOVUxMKQorICAgICAgICAgICAgdHlwZS0+dHBfYXNfbnVtYmVyID0gYmFzZS0+dHBfYXNfbnVtYmVyOworICAgICAgICBpZiAodHlwZS0+dHBfYXNfc2VxdWVuY2UgPT0gTlVMTCkKKyAgICAgICAgICAgIHR5cGUtPnRwX2FzX3NlcXVlbmNlID0gYmFzZS0+dHBfYXNfc2VxdWVuY2U7CisgICAgICAgIGlmICh0eXBlLT50cF9hc19tYXBwaW5nID09IE5VTEwpCisgICAgICAgICAgICB0eXBlLT50cF9hc19tYXBwaW5nID0gYmFzZS0+dHBfYXNfbWFwcGluZzsKKyAgICAgICAgaWYgKHR5cGUtPnRwX2FzX2J1ZmZlciA9PSBOVUxMKQorICAgICAgICAgICAgdHlwZS0+dHBfYXNfYnVmZmVyID0gYmFzZS0+dHBfYXNfYnVmZmVyOworICAgIH0KKworICAgIC8qIExpbmsgaW50byBlYWNoIGJhc2UgY2xhc3MncyBsaXN0IG9mIHN1YmNsYXNzZXMgKi8KKyAgICBiYXNlcyA9IHR5cGUtPnRwX2Jhc2VzOworICAgIG4gPSBQeVR1cGxlX0dFVF9TSVpFKGJhc2VzKTsKKyAgICBmb3IgKGkgPSAwOyBpIDwgbjsgaSsrKSB7CisgICAgICAgIFB5T2JqZWN0ICpiID0gUHlUdXBsZV9HRVRfSVRFTShiYXNlcywgaSk7CisgICAgICAgIGlmIChQeVR5cGVfQ2hlY2soYikgJiYKKyAgICAgICAgICAgIGFkZF9zdWJjbGFzcygoUHlUeXBlT2JqZWN0ICopYiwgdHlwZSkgPCAwKQorICAgICAgICAgICAgZ290byBlcnJvcjsKKyAgICB9CisKKyAgICAvKiBBbGwgZG9uZSAtLSBzZXQgdGhlIHJlYWR5IGZsYWcgKi8KKyAgICBhc3NlcnQodHlwZS0+dHBfZGljdCAhPSBOVUxMKTsKKyAgICB0eXBlLT50cF9mbGFncyA9CisgICAgICAgICh0eXBlLT50cF9mbGFncyAmIH5QeV9UUEZMQUdTX1JFQURZSU5HKSB8IFB5X1RQRkxBR1NfUkVBRFk7CisgICAgcmV0dXJuIDA7CisKKyAgZXJyb3I6CisgICAgdHlwZS0+dHBfZmxhZ3MgJj0gflB5X1RQRkxBR1NfUkVBRFlJTkc7CisgICAgcmV0dXJuIC0xOworfQorCitzdGF0aWMgaW50CithZGRfc3ViY2xhc3MoUHlUeXBlT2JqZWN0ICpiYXNlLCBQeVR5cGVPYmplY3QgKnR5cGUpCit7CisgICAgUHlfc3NpemVfdCBpOworICAgIGludCByZXN1bHQ7CisgICAgUHlPYmplY3QgKmxpc3QsICpyZWYsICpuZXdvYmo7CisKKyAgICBsaXN0ID0gYmFzZS0+dHBfc3ViY2xhc3NlczsKKyAgICBpZiAobGlzdCA9PSBOVUxMKSB7CisgICAgICAgIGJhc2UtPnRwX3N1YmNsYXNzZXMgPSBsaXN0ID0gUHlMaXN0X05ldygwKTsKKyAgICAgICAgaWYgKGxpc3QgPT0gTlVMTCkKKyAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisgICAgYXNzZXJ0KFB5TGlzdF9DaGVjayhsaXN0KSk7CisgICAgbmV3b2JqID0gUHlXZWFrcmVmX05ld1JlZigoUHlPYmplY3QgKil0eXBlLCBOVUxMKTsKKyAgICBpID0gUHlMaXN0X0dFVF9TSVpFKGxpc3QpOworICAgIHdoaWxlICgtLWkgPj0gMCkgeworICAgICAgICByZWYgPSBQeUxpc3RfR0VUX0lURU0obGlzdCwgaSk7CisgICAgICAgIGFzc2VydChQeVdlYWtyZWZfQ2hlY2tSZWYocmVmKSk7CisgICAgICAgIGlmIChQeVdlYWtyZWZfR0VUX09CSkVDVChyZWYpID09IFB5X05vbmUpCisgICAgICAgICAgICByZXR1cm4gUHlMaXN0X1NldEl0ZW0obGlzdCwgaSwgbmV3b2JqKTsKKyAgICB9CisgICAgcmVzdWx0ID0gUHlMaXN0X0FwcGVuZChsaXN0LCBuZXdvYmopOworICAgIFB5X0RFQ1JFRihuZXdvYmopOworICAgIHJldHVybiByZXN1bHQ7Cit9CisKK3N0YXRpYyB2b2lkCityZW1vdmVfc3ViY2xhc3MoUHlUeXBlT2JqZWN0ICpiYXNlLCBQeVR5cGVPYmplY3QgKnR5cGUpCit7CisgICAgUHlfc3NpemVfdCBpOworICAgIFB5T2JqZWN0ICpsaXN0LCAqcmVmOworCisgICAgbGlzdCA9IGJhc2UtPnRwX3N1YmNsYXNzZXM7CisgICAgaWYgKGxpc3QgPT0gTlVMTCkgeworICAgICAgICByZXR1cm47CisgICAgfQorICAgIGFzc2VydChQeUxpc3RfQ2hlY2sobGlzdCkpOworICAgIGkgPSBQeUxpc3RfR0VUX1NJWkUobGlzdCk7CisgICAgd2hpbGUgKC0taSA+PSAwKSB7CisgICAgICAgIHJlZiA9IFB5TGlzdF9HRVRfSVRFTShsaXN0LCBpKTsKKyAgICAgICAgYXNzZXJ0KFB5V2Vha3JlZl9DaGVja1JlZihyZWYpKTsKKyAgICAgICAgaWYgKFB5V2Vha3JlZl9HRVRfT0JKRUNUKHJlZikgPT0gKFB5T2JqZWN0Kil0eXBlKSB7CisgICAgICAgICAgICAvKiB0aGlzIGNhbid0IGZhaWwsIHJpZ2h0PyAqLworICAgICAgICAgICAgUHlTZXF1ZW5jZV9EZWxJdGVtKGxpc3QsIGkpOworICAgICAgICAgICAgcmV0dXJuOworICAgICAgICB9CisgICAgfQorfQorCitzdGF0aWMgaW50CitjaGVja19udW1fYXJncyhQeU9iamVjdCAqb2IsIGludCBuKQoreworICAgIGlmICghUHlUdXBsZV9DaGVja0V4YWN0KG9iKSkgeworICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfU3lzdGVtRXJyb3IsCisgICAgICAgICAgICAiUHlBcmdfVW5wYWNrVHVwbGUoKSBhcmd1bWVudCBsaXN0IGlzIG5vdCBhIHR1cGxlIik7CisgICAgICAgIHJldHVybiAwOworICAgIH0KKyAgICBpZiAobiA9PSBQeVR1cGxlX0dFVF9TSVpFKG9iKSkKKyAgICAgICAgcmV0dXJuIDE7CisgICAgUHlFcnJfRm9ybWF0KAorICAgICAgICBQeUV4Y19UeXBlRXJyb3IsCisgICAgICAgICJleHBlY3RlZCAlZCBhcmd1bWVudHMsIGdvdCAlemQiLCBuLCBQeVR1cGxlX0dFVF9TSVpFKG9iKSk7CisgICAgcmV0dXJuIDA7Cit9CisKKy8qIEdlbmVyaWMgd3JhcHBlcnMgZm9yIG92ZXJsb2FkYWJsZSAnb3BlcmF0b3JzJyBzdWNoIGFzIF9fZ2V0aXRlbV9fICovCisKKy8qIFRoZXJlJ3MgYSB3cmFwcGVyICpmdW5jdGlvbiogZm9yIGVhY2ggZGlzdGluY3QgZnVuY3Rpb24gdHlwZWRlZiB1c2VkCisgICBmb3IgdHlwZSBvYmplY3Qgc2xvdHMgKGUuZy4gYmluYXJ5ZnVuYywgdGVybmFyeWZ1bmMsIGV0Yy4pLiAgVGhlcmUncyBhCisgICB3cmFwcGVyICp0YWJsZSogZm9yIGVhY2ggZGlzdGluY3Qgb3BlcmF0aW9uIChlLmcuIF9fbGVuX18sIF9fYWRkX18pLgorICAgTW9zdCB0YWJsZXMgaGF2ZSBvbmx5IG9uZSBlbnRyeTsgdGhlIHRhYmxlcyBmb3IgYmluYXJ5IG9wZXJhdG9ycyBoYXZlIHR3bworICAgZW50cmllcywgb25lIHJlZ3VsYXIgYW5kIG9uZSB3aXRoIHJldmVyc2VkIGFyZ3VtZW50cy4gKi8KKworc3RhdGljIFB5T2JqZWN0ICoKK3dyYXBfbGVuZnVuYyhQeU9iamVjdCAqc2VsZiwgUHlPYmplY3QgKmFyZ3MsIHZvaWQgKndyYXBwZWQpCit7CisgICAgbGVuZnVuYyBmdW5jID0gKGxlbmZ1bmMpd3JhcHBlZDsKKyAgICBQeV9zc2l6ZV90IHJlczsKKworICAgIGlmICghY2hlY2tfbnVtX2FyZ3MoYXJncywgMCkpCisgICAgICAgIHJldHVybiBOVUxMOworICAgIHJlcyA9ICgqZnVuYykoc2VsZik7CisgICAgaWYgKHJlcyA9PSAtMSAmJiBQeUVycl9PY2N1cnJlZCgpKQorICAgICAgICByZXR1cm4gTlVMTDsKKyAgICByZXR1cm4gUHlJbnRfRnJvbUxvbmcoKGxvbmcpcmVzKTsKK30KKworc3RhdGljIFB5T2JqZWN0ICoKK3dyYXBfaW5xdWlyeXByZWQoUHlPYmplY3QgKnNlbGYsIFB5T2JqZWN0ICphcmdzLCB2b2lkICp3cmFwcGVkKQoreworICAgIGlucXVpcnkgZnVuYyA9IChpbnF1aXJ5KXdyYXBwZWQ7CisgICAgaW50IHJlczsKKworICAgIGlmICghY2hlY2tfbnVtX2FyZ3MoYXJncywgMCkpCisgICAgICAgIHJldHVybiBOVUxMOworICAgIHJlcyA9ICgqZnVuYykoc2VsZik7CisgICAgaWYgKHJlcyA9PSAtMSAmJiBQeUVycl9PY2N1cnJlZCgpKQorICAgICAgICByZXR1cm4gTlVMTDsKKyAgICByZXR1cm4gUHlCb29sX0Zyb21Mb25nKChsb25nKXJlcyk7Cit9CisKK3N0YXRpYyBQeU9iamVjdCAqCit3cmFwX2JpbmFyeWZ1bmMoUHlPYmplY3QgKnNlbGYsIFB5T2JqZWN0ICphcmdzLCB2b2lkICp3cmFwcGVkKQoreworICAgIGJpbmFyeWZ1bmMgZnVuYyA9IChiaW5hcnlmdW5jKXdyYXBwZWQ7CisgICAgUHlPYmplY3QgKm90aGVyOworCisgICAgaWYgKCFjaGVja19udW1fYXJncyhhcmdzLCAxKSkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgb3RoZXIgPSBQeVR1cGxlX0dFVF9JVEVNKGFyZ3MsIDApOworICAgIHJldHVybiAoKmZ1bmMpKHNlbGYsIG90aGVyKTsKK30KKworc3RhdGljIFB5T2JqZWN0ICoKK3dyYXBfYmluYXJ5ZnVuY19sKFB5T2JqZWN0ICpzZWxmLCBQeU9iamVjdCAqYXJncywgdm9pZCAqd3JhcHBlZCkKK3sKKyAgICBiaW5hcnlmdW5jIGZ1bmMgPSAoYmluYXJ5ZnVuYyl3cmFwcGVkOworICAgIFB5T2JqZWN0ICpvdGhlcjsKKworICAgIGlmICghY2hlY2tfbnVtX2FyZ3MoYXJncywgMSkpCisgICAgICAgIHJldHVybiBOVUxMOworICAgIG90aGVyID0gUHlUdXBsZV9HRVRfSVRFTShhcmdzLCAwKTsKKyAgICBpZiAoIShzZWxmLT5vYl90eXBlLT50cF9mbGFncyAmIFB5X1RQRkxBR1NfQ0hFQ0tUWVBFUykgJiYKKyAgICAgICAgIVB5VHlwZV9Jc1N1YnR5cGUob3RoZXItPm9iX3R5cGUsIHNlbGYtPm9iX3R5cGUpKSB7CisgICAgICAgIFB5X0lOQ1JFRihQeV9Ob3RJbXBsZW1lbnRlZCk7CisgICAgICAgIHJldHVybiBQeV9Ob3RJbXBsZW1lbnRlZDsKKyAgICB9CisgICAgcmV0dXJuICgqZnVuYykoc2VsZiwgb3RoZXIpOworfQorCitzdGF0aWMgUHlPYmplY3QgKgord3JhcF9iaW5hcnlmdW5jX3IoUHlPYmplY3QgKnNlbGYsIFB5T2JqZWN0ICphcmdzLCB2b2lkICp3cmFwcGVkKQoreworICAgIGJpbmFyeWZ1bmMgZnVuYyA9IChiaW5hcnlmdW5jKXdyYXBwZWQ7CisgICAgUHlPYmplY3QgKm90aGVyOworCisgICAgaWYgKCFjaGVja19udW1fYXJncyhhcmdzLCAxKSkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgb3RoZXIgPSBQeVR1cGxlX0dFVF9JVEVNKGFyZ3MsIDApOworICAgIGlmICghKHNlbGYtPm9iX3R5cGUtPnRwX2ZsYWdzICYgUHlfVFBGTEFHU19DSEVDS1RZUEVTKSAmJgorICAgICAgICAhUHlUeXBlX0lzU3VidHlwZShvdGhlci0+b2JfdHlwZSwgc2VsZi0+b2JfdHlwZSkpIHsKKyAgICAgICAgUHlfSU5DUkVGKFB5X05vdEltcGxlbWVudGVkKTsKKyAgICAgICAgcmV0dXJuIFB5X05vdEltcGxlbWVudGVkOworICAgIH0KKyAgICByZXR1cm4gKCpmdW5jKShvdGhlciwgc2VsZik7Cit9CisKK3N0YXRpYyBQeU9iamVjdCAqCit3cmFwX2NvZXJjZWZ1bmMoUHlPYmplY3QgKnNlbGYsIFB5T2JqZWN0ICphcmdzLCB2b2lkICp3cmFwcGVkKQoreworICAgIGNvZXJjaW9uIGZ1bmMgPSAoY29lcmNpb24pd3JhcHBlZDsKKyAgICBQeU9iamVjdCAqb3RoZXIsICpyZXM7CisgICAgaW50IG9rOworCisgICAgaWYgKCFjaGVja19udW1fYXJncyhhcmdzLCAxKSkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgb3RoZXIgPSBQeVR1cGxlX0dFVF9JVEVNKGFyZ3MsIDApOworICAgIG9rID0gZnVuYygmc2VsZiwgJm90aGVyKTsKKyAgICBpZiAob2sgPCAwKQorICAgICAgICByZXR1cm4gTlVMTDsKKyAgICBpZiAob2sgPiAwKSB7CisgICAgICAgIFB5X0lOQ1JFRihQeV9Ob3RJbXBsZW1lbnRlZCk7CisgICAgICAgIHJldHVybiBQeV9Ob3RJbXBsZW1lbnRlZDsKKyAgICB9CisgICAgcmVzID0gUHlUdXBsZV9OZXcoMik7CisgICAgaWYgKHJlcyA9PSBOVUxMKSB7CisgICAgICAgIFB5X0RFQ1JFRihzZWxmKTsKKyAgICAgICAgUHlfREVDUkVGKG90aGVyKTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIFB5VHVwbGVfU0VUX0lURU0ocmVzLCAwLCBzZWxmKTsKKyAgICBQeVR1cGxlX1NFVF9JVEVNKHJlcywgMSwgb3RoZXIpOworICAgIHJldHVybiByZXM7Cit9CisKK3N0YXRpYyBQeU9iamVjdCAqCit3cmFwX3Rlcm5hcnlmdW5jKFB5T2JqZWN0ICpzZWxmLCBQeU9iamVjdCAqYXJncywgdm9pZCAqd3JhcHBlZCkKK3sKKyAgICB0ZXJuYXJ5ZnVuYyBmdW5jID0gKHRlcm5hcnlmdW5jKXdyYXBwZWQ7CisgICAgUHlPYmplY3QgKm90aGVyOworICAgIFB5T2JqZWN0ICp0aGlyZCA9IFB5X05vbmU7CisKKyAgICAvKiBOb3RlOiBUaGlzIHdyYXBwZXIgb25seSB3b3JrcyBmb3IgX19wb3dfXygpICovCisKKyAgICBpZiAoIVB5QXJnX1VucGFja1R1cGxlKGFyZ3MsICIiLCAxLCAyLCAmb3RoZXIsICZ0aGlyZCkpCisgICAgICAgIHJldHVybiBOVUxMOworICAgIHJldHVybiAoKmZ1bmMpKHNlbGYsIG90aGVyLCB0aGlyZCk7Cit9CisKK3N0YXRpYyBQeU9iamVjdCAqCit3cmFwX3Rlcm5hcnlmdW5jX3IoUHlPYmplY3QgKnNlbGYsIFB5T2JqZWN0ICphcmdzLCB2b2lkICp3cmFwcGVkKQoreworICAgIHRlcm5hcnlmdW5jIGZ1bmMgPSAodGVybmFyeWZ1bmMpd3JhcHBlZDsKKyAgICBQeU9iamVjdCAqb3RoZXI7CisgICAgUHlPYmplY3QgKnRoaXJkID0gUHlfTm9uZTsKKworICAgIC8qIE5vdGU6IFRoaXMgd3JhcHBlciBvbmx5IHdvcmtzIGZvciBfX3Bvd19fKCkgKi8KKworICAgIGlmICghUHlBcmdfVW5wYWNrVHVwbGUoYXJncywgIiIsIDEsIDIsICZvdGhlciwgJnRoaXJkKSkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgcmV0dXJuICgqZnVuYykob3RoZXIsIHNlbGYsIHRoaXJkKTsKK30KKworc3RhdGljIFB5T2JqZWN0ICoKK3dyYXBfdW5hcnlmdW5jKFB5T2JqZWN0ICpzZWxmLCBQeU9iamVjdCAqYXJncywgdm9pZCAqd3JhcHBlZCkKK3sKKyAgICB1bmFyeWZ1bmMgZnVuYyA9ICh1bmFyeWZ1bmMpd3JhcHBlZDsKKworICAgIGlmICghY2hlY2tfbnVtX2FyZ3MoYXJncywgMCkpCisgICAgICAgIHJldHVybiBOVUxMOworICAgIHJldHVybiAoKmZ1bmMpKHNlbGYpOworfQorCitzdGF0aWMgUHlPYmplY3QgKgord3JhcF9pbmRleGFyZ2Z1bmMoUHlPYmplY3QgKnNlbGYsIFB5T2JqZWN0ICphcmdzLCB2b2lkICp3cmFwcGVkKQoreworICAgIHNzaXplYXJnZnVuYyBmdW5jID0gKHNzaXplYXJnZnVuYyl3cmFwcGVkOworICAgIFB5T2JqZWN0KiBvOworICAgIFB5X3NzaXplX3QgaTsKKworICAgIGlmICghUHlBcmdfVW5wYWNrVHVwbGUoYXJncywgIiIsIDEsIDEsICZvKSkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgaSA9IFB5TnVtYmVyX0FzU3NpemVfdChvLCBQeUV4Y19PdmVyZmxvd0Vycm9yKTsKKyAgICBpZiAoaSA9PSAtMSAmJiBQeUVycl9PY2N1cnJlZCgpKQorICAgICAgICByZXR1cm4gTlVMTDsKKyAgICByZXR1cm4gKCpmdW5jKShzZWxmLCBpKTsKK30KKworc3RhdGljIFB5X3NzaXplX3QKK2dldGluZGV4KFB5T2JqZWN0ICpzZWxmLCBQeU9iamVjdCAqYXJnKQoreworICAgIFB5X3NzaXplX3QgaTsKKworICAgIGkgPSBQeU51bWJlcl9Bc1NzaXplX3QoYXJnLCBQeUV4Y19PdmVyZmxvd0Vycm9yKTsKKyAgICBpZiAoaSA9PSAtMSAmJiBQeUVycl9PY2N1cnJlZCgpKQorICAgICAgICByZXR1cm4gLTE7CisgICAgaWYgKGkgPCAwKSB7CisgICAgICAgIFB5U2VxdWVuY2VNZXRob2RzICpzcSA9IFB5X1RZUEUoc2VsZiktPnRwX2FzX3NlcXVlbmNlOworICAgICAgICBpZiAoc3EgJiYgc3EtPnNxX2xlbmd0aCkgeworICAgICAgICAgICAgUHlfc3NpemVfdCBuID0gKCpzcS0+c3FfbGVuZ3RoKShzZWxmKTsKKyAgICAgICAgICAgIGlmIChuIDwgMCkKKyAgICAgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgICAgICBpICs9IG47CisgICAgICAgIH0KKyAgICB9CisgICAgcmV0dXJuIGk7Cit9CisKK3N0YXRpYyBQeU9iamVjdCAqCit3cmFwX3NxX2l0ZW0oUHlPYmplY3QgKnNlbGYsIFB5T2JqZWN0ICphcmdzLCB2b2lkICp3cmFwcGVkKQoreworICAgIHNzaXplYXJnZnVuYyBmdW5jID0gKHNzaXplYXJnZnVuYyl3cmFwcGVkOworICAgIFB5T2JqZWN0ICphcmc7CisgICAgUHlfc3NpemVfdCBpOworCisgICAgaWYgKFB5VHVwbGVfR0VUX1NJWkUoYXJncykgPT0gMSkgeworICAgICAgICBhcmcgPSBQeVR1cGxlX0dFVF9JVEVNKGFyZ3MsIDApOworICAgICAgICBpID0gZ2V0aW5kZXgoc2VsZiwgYXJnKTsKKyAgICAgICAgaWYgKGkgPT0gLTEgJiYgUHlFcnJfT2NjdXJyZWQoKSkKKyAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgICAgICByZXR1cm4gKCpmdW5jKShzZWxmLCBpKTsKKyAgICB9CisgICAgY2hlY2tfbnVtX2FyZ3MoYXJncywgMSk7CisgICAgYXNzZXJ0KFB5RXJyX09jY3VycmVkKCkpOworICAgIHJldHVybiBOVUxMOworfQorCitzdGF0aWMgUHlPYmplY3QgKgord3JhcF9zc2l6ZXNzaXplYXJnZnVuYyhQeU9iamVjdCAqc2VsZiwgUHlPYmplY3QgKmFyZ3MsIHZvaWQgKndyYXBwZWQpCit7CisgICAgc3NpemVzc2l6ZWFyZ2Z1bmMgZnVuYyA9IChzc2l6ZXNzaXplYXJnZnVuYyl3cmFwcGVkOworICAgIFB5X3NzaXplX3QgaSwgajsKKworICAgIGlmICghUHlBcmdfUGFyc2VUdXBsZShhcmdzLCAibm4iLCAmaSwgJmopKQorICAgICAgICByZXR1cm4gTlVMTDsKKyAgICByZXR1cm4gKCpmdW5jKShzZWxmLCBpLCBqKTsKK30KKworc3RhdGljIFB5T2JqZWN0ICoKK3dyYXBfc3Ffc2V0aXRlbShQeU9iamVjdCAqc2VsZiwgUHlPYmplY3QgKmFyZ3MsIHZvaWQgKndyYXBwZWQpCit7CisgICAgc3NpemVvYmphcmdwcm9jIGZ1bmMgPSAoc3NpemVvYmphcmdwcm9jKXdyYXBwZWQ7CisgICAgUHlfc3NpemVfdCBpOworICAgIGludCByZXM7CisgICAgUHlPYmplY3QgKmFyZywgKnZhbHVlOworCisgICAgaWYgKCFQeUFyZ19VbnBhY2tUdXBsZShhcmdzLCAiIiwgMiwgMiwgJmFyZywgJnZhbHVlKSkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgaSA9IGdldGluZGV4KHNlbGYsIGFyZyk7CisgICAgaWYgKGkgPT0gLTEgJiYgUHlFcnJfT2NjdXJyZWQoKSkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgcmVzID0gKCpmdW5jKShzZWxmLCBpLCB2YWx1ZSk7CisgICAgaWYgKHJlcyA9PSAtMSAmJiBQeUVycl9PY2N1cnJlZCgpKQorICAgICAgICByZXR1cm4gTlVMTDsKKyAgICBQeV9JTkNSRUYoUHlfTm9uZSk7CisgICAgcmV0dXJuIFB5X05vbmU7Cit9CisKK3N0YXRpYyBQeU9iamVjdCAqCit3cmFwX3NxX2RlbGl0ZW0oUHlPYmplY3QgKnNlbGYsIFB5T2JqZWN0ICphcmdzLCB2b2lkICp3cmFwcGVkKQoreworICAgIHNzaXplb2JqYXJncHJvYyBmdW5jID0gKHNzaXplb2JqYXJncHJvYyl3cmFwcGVkOworICAgIFB5X3NzaXplX3QgaTsKKyAgICBpbnQgcmVzOworICAgIFB5T2JqZWN0ICphcmc7CisKKyAgICBpZiAoIWNoZWNrX251bV9hcmdzKGFyZ3MsIDEpKQorICAgICAgICByZXR1cm4gTlVMTDsKKyAgICBhcmcgPSBQeVR1cGxlX0dFVF9JVEVNKGFyZ3MsIDApOworICAgIGkgPSBnZXRpbmRleChzZWxmLCBhcmcpOworICAgIGlmIChpID09IC0xICYmIFB5RXJyX09jY3VycmVkKCkpCisgICAgICAgIHJldHVybiBOVUxMOworICAgIHJlcyA9ICgqZnVuYykoc2VsZiwgaSwgTlVMTCk7CisgICAgaWYgKHJlcyA9PSAtMSAmJiBQeUVycl9PY2N1cnJlZCgpKQorICAgICAgICByZXR1cm4gTlVMTDsKKyAgICBQeV9JTkNSRUYoUHlfTm9uZSk7CisgICAgcmV0dXJuIFB5X05vbmU7Cit9CisKK3N0YXRpYyBQeU9iamVjdCAqCit3cmFwX3NzaXplc3NpemVvYmphcmdwcm9jKFB5T2JqZWN0ICpzZWxmLCBQeU9iamVjdCAqYXJncywgdm9pZCAqd3JhcHBlZCkKK3sKKyAgICBzc2l6ZXNzaXplb2JqYXJncHJvYyBmdW5jID0gKHNzaXplc3NpemVvYmphcmdwcm9jKXdyYXBwZWQ7CisgICAgUHlfc3NpemVfdCBpLCBqOworICAgIGludCByZXM7CisgICAgUHlPYmplY3QgKnZhbHVlOworCisgICAgaWYgKCFQeUFyZ19QYXJzZVR1cGxlKGFyZ3MsICJubk8iLCAmaSwgJmosICZ2YWx1ZSkpCisgICAgICAgIHJldHVybiBOVUxMOworICAgIHJlcyA9ICgqZnVuYykoc2VsZiwgaSwgaiwgdmFsdWUpOworICAgIGlmIChyZXMgPT0gLTEgJiYgUHlFcnJfT2NjdXJyZWQoKSkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgUHlfSU5DUkVGKFB5X05vbmUpOworICAgIHJldHVybiBQeV9Ob25lOworfQorCitzdGF0aWMgUHlPYmplY3QgKgord3JhcF9kZWxzbGljZShQeU9iamVjdCAqc2VsZiwgUHlPYmplY3QgKmFyZ3MsIHZvaWQgKndyYXBwZWQpCit7CisgICAgc3NpemVzc2l6ZW9iamFyZ3Byb2MgZnVuYyA9IChzc2l6ZXNzaXplb2JqYXJncHJvYyl3cmFwcGVkOworICAgIFB5X3NzaXplX3QgaSwgajsKKyAgICBpbnQgcmVzOworCisgICAgaWYgKCFQeUFyZ19QYXJzZVR1cGxlKGFyZ3MsICJubiIsICZpLCAmaikpCisgICAgICAgIHJldHVybiBOVUxMOworICAgIHJlcyA9ICgqZnVuYykoc2VsZiwgaSwgaiwgTlVMTCk7CisgICAgaWYgKHJlcyA9PSAtMSAmJiBQeUVycl9PY2N1cnJlZCgpKQorICAgICAgICByZXR1cm4gTlVMTDsKKyAgICBQeV9JTkNSRUYoUHlfTm9uZSk7CisgICAgcmV0dXJuIFB5X05vbmU7Cit9CisKKy8qIFhYWCBvYmpvYmpwcm9jIGlzIGEgbWlzbm9tZXI7IHNob3VsZCBiZSBvYmphcmdwcmVkICovCitzdGF0aWMgUHlPYmplY3QgKgord3JhcF9vYmpvYmpwcm9jKFB5T2JqZWN0ICpzZWxmLCBQeU9iamVjdCAqYXJncywgdm9pZCAqd3JhcHBlZCkKK3sKKyAgICBvYmpvYmpwcm9jIGZ1bmMgPSAob2Jqb2JqcHJvYyl3cmFwcGVkOworICAgIGludCByZXM7CisgICAgUHlPYmplY3QgKnZhbHVlOworCisgICAgaWYgKCFjaGVja19udW1fYXJncyhhcmdzLCAxKSkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgdmFsdWUgPSBQeVR1cGxlX0dFVF9JVEVNKGFyZ3MsIDApOworICAgIHJlcyA9ICgqZnVuYykoc2VsZiwgdmFsdWUpOworICAgIGlmIChyZXMgPT0gLTEgJiYgUHlFcnJfT2NjdXJyZWQoKSkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgZWxzZQorICAgICAgICByZXR1cm4gUHlCb29sX0Zyb21Mb25nKHJlcyk7Cit9CisKK3N0YXRpYyBQeU9iamVjdCAqCit3cmFwX29iam9iamFyZ3Byb2MoUHlPYmplY3QgKnNlbGYsIFB5T2JqZWN0ICphcmdzLCB2b2lkICp3cmFwcGVkKQoreworICAgIG9iam9iamFyZ3Byb2MgZnVuYyA9IChvYmpvYmphcmdwcm9jKXdyYXBwZWQ7CisgICAgaW50IHJlczsKKyAgICBQeU9iamVjdCAqa2V5LCAqdmFsdWU7CisKKyAgICBpZiAoIVB5QXJnX1VucGFja1R1cGxlKGFyZ3MsICIiLCAyLCAyLCAma2V5LCAmdmFsdWUpKQorICAgICAgICByZXR1cm4gTlVMTDsKKyAgICByZXMgPSAoKmZ1bmMpKHNlbGYsIGtleSwgdmFsdWUpOworICAgIGlmIChyZXMgPT0gLTEgJiYgUHlFcnJfT2NjdXJyZWQoKSkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgUHlfSU5DUkVGKFB5X05vbmUpOworICAgIHJldHVybiBQeV9Ob25lOworfQorCitzdGF0aWMgUHlPYmplY3QgKgord3JhcF9kZWxpdGVtKFB5T2JqZWN0ICpzZWxmLCBQeU9iamVjdCAqYXJncywgdm9pZCAqd3JhcHBlZCkKK3sKKyAgICBvYmpvYmphcmdwcm9jIGZ1bmMgPSAob2Jqb2JqYXJncHJvYyl3cmFwcGVkOworICAgIGludCByZXM7CisgICAgUHlPYmplY3QgKmtleTsKKworICAgIGlmICghY2hlY2tfbnVtX2FyZ3MoYXJncywgMSkpCisgICAgICAgIHJldHVybiBOVUxMOworICAgIGtleSA9IFB5VHVwbGVfR0VUX0lURU0oYXJncywgMCk7CisgICAgcmVzID0gKCpmdW5jKShzZWxmLCBrZXksIE5VTEwpOworICAgIGlmIChyZXMgPT0gLTEgJiYgUHlFcnJfT2NjdXJyZWQoKSkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgUHlfSU5DUkVGKFB5X05vbmUpOworICAgIHJldHVybiBQeV9Ob25lOworfQorCitzdGF0aWMgUHlPYmplY3QgKgord3JhcF9jbXBmdW5jKFB5T2JqZWN0ICpzZWxmLCBQeU9iamVjdCAqYXJncywgdm9pZCAqd3JhcHBlZCkKK3sKKyAgICBjbXBmdW5jIGZ1bmMgPSAoY21wZnVuYyl3cmFwcGVkOworICAgIGludCByZXM7CisgICAgUHlPYmplY3QgKm90aGVyOworCisgICAgaWYgKCFjaGVja19udW1fYXJncyhhcmdzLCAxKSkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgb3RoZXIgPSBQeVR1cGxlX0dFVF9JVEVNKGFyZ3MsIDApOworICAgIGlmIChQeV9UWVBFKG90aGVyKS0+dHBfY29tcGFyZSAhPSBmdW5jICYmCisgICAgICAgICFQeVR5cGVfSXNTdWJ0eXBlKFB5X1RZUEUob3RoZXIpLCBQeV9UWVBFKHNlbGYpKSkgeworICAgICAgICBQeUVycl9Gb3JtYXQoCisgICAgICAgICAgICBQeUV4Y19UeXBlRXJyb3IsCisgICAgICAgICAgICAiJXMuX19jbXBfXyh4LHkpIHJlcXVpcmVzIHkgdG8gYmUgYSAnJXMnLCBub3QgYSAnJXMnIiwKKyAgICAgICAgICAgIFB5X1RZUEUoc2VsZiktPnRwX25hbWUsCisgICAgICAgICAgICBQeV9UWVBFKHNlbGYpLT50cF9uYW1lLAorICAgICAgICAgICAgUHlfVFlQRShvdGhlciktPnRwX25hbWUpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgcmVzID0gKCpmdW5jKShzZWxmLCBvdGhlcik7CisgICAgaWYgKFB5RXJyX09jY3VycmVkKCkpCisgICAgICAgIHJldHVybiBOVUxMOworICAgIHJldHVybiBQeUludF9Gcm9tTG9uZygobG9uZylyZXMpOworfQorCisvKiBIZWxwZXIgdG8gY2hlY2sgZm9yIG9iamVjdC5fX3NldGF0dHJfXyBvciBfX2RlbGF0dHJfXyBhcHBsaWVkIHRvIGEgdHlwZS4KKyAgIFRoaXMgaXMgY2FsbGVkIHRoZSBDYXJsbyBWZXJyZSBoYWNrIGFmdGVyIGl0cyBkaXNjb3ZlcmVyLiAqLworc3RhdGljIGludAoraGFja2NoZWNrKFB5T2JqZWN0ICpzZWxmLCBzZXRhdHRyb2Z1bmMgZnVuYywgY2hhciAqd2hhdCkKK3sKKyAgICBQeVR5cGVPYmplY3QgKnR5cGUgPSBQeV9UWVBFKHNlbGYpOworICAgIHdoaWxlICh0eXBlICYmIHR5cGUtPnRwX2ZsYWdzICYgUHlfVFBGTEFHU19IRUFQVFlQRSkKKyAgICAgICAgdHlwZSA9IHR5cGUtPnRwX2Jhc2U7CisgICAgLyogSWYgdHlwZSBpcyBOVUxMIG5vdywgdGhpcyBpcyBhIHJlYWxseSB3ZWlyZCB0eXBlLgorICAgICAgIEluIHRoZSBzcGlyaXQgb2YgYmFja3dhcmRzIGNvbXBhdGliaWxpdHkgKD8pLCBqdXN0IHNodXQgdXAuICovCisgICAgaWYgKHR5cGUgJiYgdHlwZS0+dHBfc2V0YXR0cm8gIT0gZnVuYykgeworICAgICAgICBQeUVycl9Gb3JtYXQoUHlFeGNfVHlwZUVycm9yLAorICAgICAgICAgICAgICAgICAgICAgImNhbid0IGFwcGx5IHRoaXMgJXMgdG8gJXMgb2JqZWN0IiwKKyAgICAgICAgICAgICAgICAgICAgIHdoYXQsCisgICAgICAgICAgICAgICAgICAgICB0eXBlLT50cF9uYW1lKTsKKyAgICAgICAgcmV0dXJuIDA7CisgICAgfQorICAgIHJldHVybiAxOworfQorCitzdGF0aWMgUHlPYmplY3QgKgord3JhcF9zZXRhdHRyKFB5T2JqZWN0ICpzZWxmLCBQeU9iamVjdCAqYXJncywgdm9pZCAqd3JhcHBlZCkKK3sKKyAgICBzZXRhdHRyb2Z1bmMgZnVuYyA9IChzZXRhdHRyb2Z1bmMpd3JhcHBlZDsKKyAgICBpbnQgcmVzOworICAgIFB5T2JqZWN0ICpuYW1lLCAqdmFsdWU7CisKKyAgICBpZiAoIVB5QXJnX1VucGFja1R1cGxlKGFyZ3MsICIiLCAyLCAyLCAmbmFtZSwgJnZhbHVlKSkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgaWYgKCFoYWNrY2hlY2soc2VsZiwgZnVuYywgIl9fc2V0YXR0cl9fIikpCisgICAgICAgIHJldHVybiBOVUxMOworICAgIHJlcyA9ICgqZnVuYykoc2VsZiwgbmFtZSwgdmFsdWUpOworICAgIGlmIChyZXMgPCAwKQorICAgICAgICByZXR1cm4gTlVMTDsKKyAgICBQeV9JTkNSRUYoUHlfTm9uZSk7CisgICAgcmV0dXJuIFB5X05vbmU7Cit9CisKK3N0YXRpYyBQeU9iamVjdCAqCit3cmFwX2RlbGF0dHIoUHlPYmplY3QgKnNlbGYsIFB5T2JqZWN0ICphcmdzLCB2b2lkICp3cmFwcGVkKQoreworICAgIHNldGF0dHJvZnVuYyBmdW5jID0gKHNldGF0dHJvZnVuYyl3cmFwcGVkOworICAgIGludCByZXM7CisgICAgUHlPYmplY3QgKm5hbWU7CisKKyAgICBpZiAoIWNoZWNrX251bV9hcmdzKGFyZ3MsIDEpKQorICAgICAgICByZXR1cm4gTlVMTDsKKyAgICBuYW1lID0gUHlUdXBsZV9HRVRfSVRFTShhcmdzLCAwKTsKKyAgICBpZiAoIWhhY2tjaGVjayhzZWxmLCBmdW5jLCAiX19kZWxhdHRyX18iKSkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgcmVzID0gKCpmdW5jKShzZWxmLCBuYW1lLCBOVUxMKTsKKyAgICBpZiAocmVzIDwgMCkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgUHlfSU5DUkVGKFB5X05vbmUpOworICAgIHJldHVybiBQeV9Ob25lOworfQorCitzdGF0aWMgUHlPYmplY3QgKgord3JhcF9oYXNoZnVuYyhQeU9iamVjdCAqc2VsZiwgUHlPYmplY3QgKmFyZ3MsIHZvaWQgKndyYXBwZWQpCit7CisgICAgaGFzaGZ1bmMgZnVuYyA9IChoYXNoZnVuYyl3cmFwcGVkOworICAgIGxvbmcgcmVzOworCisgICAgaWYgKCFjaGVja19udW1fYXJncyhhcmdzLCAwKSkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgcmVzID0gKCpmdW5jKShzZWxmKTsKKyAgICBpZiAocmVzID09IC0xICYmIFB5RXJyX09jY3VycmVkKCkpCisgICAgICAgIHJldHVybiBOVUxMOworICAgIHJldHVybiBQeUludF9Gcm9tTG9uZyhyZXMpOworfQorCitzdGF0aWMgUHlPYmplY3QgKgord3JhcF9jYWxsKFB5T2JqZWN0ICpzZWxmLCBQeU9iamVjdCAqYXJncywgdm9pZCAqd3JhcHBlZCwgUHlPYmplY3QgKmt3ZHMpCit7CisgICAgdGVybmFyeWZ1bmMgZnVuYyA9ICh0ZXJuYXJ5ZnVuYyl3cmFwcGVkOworCisgICAgcmV0dXJuICgqZnVuYykoc2VsZiwgYXJncywga3dkcyk7Cit9CisKK3N0YXRpYyBQeU9iamVjdCAqCit3cmFwX3JpY2hjbXBmdW5jKFB5T2JqZWN0ICpzZWxmLCBQeU9iamVjdCAqYXJncywgdm9pZCAqd3JhcHBlZCwgaW50IG9wKQoreworICAgIHJpY2hjbXBmdW5jIGZ1bmMgPSAocmljaGNtcGZ1bmMpd3JhcHBlZDsKKyAgICBQeU9iamVjdCAqb3RoZXI7CisKKyAgICBpZiAoIWNoZWNrX251bV9hcmdzKGFyZ3MsIDEpKQorICAgICAgICByZXR1cm4gTlVMTDsKKyAgICBvdGhlciA9IFB5VHVwbGVfR0VUX0lURU0oYXJncywgMCk7CisgICAgcmV0dXJuICgqZnVuYykoc2VsZiwgb3RoZXIsIG9wKTsKK30KKworI3VuZGVmIFJJQ0hDTVBfV1JBUFBFUgorI2RlZmluZSBSSUNIQ01QX1dSQVBQRVIoTkFNRSwgT1ApIFwKK3N0YXRpYyBQeU9iamVjdCAqIFwKK3JpY2hjbXBfIyNOQU1FKFB5T2JqZWN0ICpzZWxmLCBQeU9iamVjdCAqYXJncywgdm9pZCAqd3JhcHBlZCkgXAoreyBcCisgICAgcmV0dXJuIHdyYXBfcmljaGNtcGZ1bmMoc2VsZiwgYXJncywgd3JhcHBlZCwgT1ApOyBcCit9CisKK1JJQ0hDTVBfV1JBUFBFUihsdCwgUHlfTFQpCitSSUNIQ01QX1dSQVBQRVIobGUsIFB5X0xFKQorUklDSENNUF9XUkFQUEVSKGVxLCBQeV9FUSkKK1JJQ0hDTVBfV1JBUFBFUihuZSwgUHlfTkUpCitSSUNIQ01QX1dSQVBQRVIoZ3QsIFB5X0dUKQorUklDSENNUF9XUkFQUEVSKGdlLCBQeV9HRSkKKworc3RhdGljIFB5T2JqZWN0ICoKK3dyYXBfbmV4dChQeU9iamVjdCAqc2VsZiwgUHlPYmplY3QgKmFyZ3MsIHZvaWQgKndyYXBwZWQpCit7CisgICAgdW5hcnlmdW5jIGZ1bmMgPSAodW5hcnlmdW5jKXdyYXBwZWQ7CisgICAgUHlPYmplY3QgKnJlczsKKworICAgIGlmICghY2hlY2tfbnVtX2FyZ3MoYXJncywgMCkpCisgICAgICAgIHJldHVybiBOVUxMOworICAgIHJlcyA9ICgqZnVuYykoc2VsZik7CisgICAgaWYgKHJlcyA9PSBOVUxMICYmICFQeUVycl9PY2N1cnJlZCgpKQorICAgICAgICBQeUVycl9TZXROb25lKFB5RXhjX1N0b3BJdGVyYXRpb24pOworICAgIHJldHVybiByZXM7Cit9CisKK3N0YXRpYyBQeU9iamVjdCAqCit3cmFwX2Rlc2NyX2dldChQeU9iamVjdCAqc2VsZiwgUHlPYmplY3QgKmFyZ3MsIHZvaWQgKndyYXBwZWQpCit7CisgICAgZGVzY3JnZXRmdW5jIGZ1bmMgPSAoZGVzY3JnZXRmdW5jKXdyYXBwZWQ7CisgICAgUHlPYmplY3QgKm9iajsKKyAgICBQeU9iamVjdCAqdHlwZSA9IE5VTEw7CisKKyAgICBpZiAoIVB5QXJnX1VucGFja1R1cGxlKGFyZ3MsICIiLCAxLCAyLCAmb2JqLCAmdHlwZSkpCisgICAgICAgIHJldHVybiBOVUxMOworICAgIGlmIChvYmogPT0gUHlfTm9uZSkKKyAgICAgICAgb2JqID0gTlVMTDsKKyAgICBpZiAodHlwZSA9PSBQeV9Ob25lKQorICAgICAgICB0eXBlID0gTlVMTDsKKyAgICBpZiAodHlwZSA9PSBOVUxMICYmb2JqID09IE5VTEwpIHsKKyAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1R5cGVFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICJfX2dldF9fKE5vbmUsIE5vbmUpIGlzIGludmFsaWQiKTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIHJldHVybiAoKmZ1bmMpKHNlbGYsIG9iaiwgdHlwZSk7Cit9CisKK3N0YXRpYyBQeU9iamVjdCAqCit3cmFwX2Rlc2NyX3NldChQeU9iamVjdCAqc2VsZiwgUHlPYmplY3QgKmFyZ3MsIHZvaWQgKndyYXBwZWQpCit7CisgICAgZGVzY3JzZXRmdW5jIGZ1bmMgPSAoZGVzY3JzZXRmdW5jKXdyYXBwZWQ7CisgICAgUHlPYmplY3QgKm9iaiwgKnZhbHVlOworICAgIGludCByZXQ7CisKKyAgICBpZiAoIVB5QXJnX1VucGFja1R1cGxlKGFyZ3MsICIiLCAyLCAyLCAmb2JqLCAmdmFsdWUpKQorICAgICAgICByZXR1cm4gTlVMTDsKKyAgICByZXQgPSAoKmZ1bmMpKHNlbGYsIG9iaiwgdmFsdWUpOworICAgIGlmIChyZXQgPCAwKQorICAgICAgICByZXR1cm4gTlVMTDsKKyAgICBQeV9JTkNSRUYoUHlfTm9uZSk7CisgICAgcmV0dXJuIFB5X05vbmU7Cit9CisKK3N0YXRpYyBQeU9iamVjdCAqCit3cmFwX2Rlc2NyX2RlbGV0ZShQeU9iamVjdCAqc2VsZiwgUHlPYmplY3QgKmFyZ3MsIHZvaWQgKndyYXBwZWQpCit7CisgICAgZGVzY3JzZXRmdW5jIGZ1bmMgPSAoZGVzY3JzZXRmdW5jKXdyYXBwZWQ7CisgICAgUHlPYmplY3QgKm9iajsKKyAgICBpbnQgcmV0OworCisgICAgaWYgKCFjaGVja19udW1fYXJncyhhcmdzLCAxKSkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgb2JqID0gUHlUdXBsZV9HRVRfSVRFTShhcmdzLCAwKTsKKyAgICByZXQgPSAoKmZ1bmMpKHNlbGYsIG9iaiwgTlVMTCk7CisgICAgaWYgKHJldCA8IDApCisgICAgICAgIHJldHVybiBOVUxMOworICAgIFB5X0lOQ1JFRihQeV9Ob25lKTsKKyAgICByZXR1cm4gUHlfTm9uZTsKK30KKworc3RhdGljIFB5T2JqZWN0ICoKK3dyYXBfaW5pdChQeU9iamVjdCAqc2VsZiwgUHlPYmplY3QgKmFyZ3MsIHZvaWQgKndyYXBwZWQsIFB5T2JqZWN0ICprd2RzKQoreworICAgIGluaXRwcm9jIGZ1bmMgPSAoaW5pdHByb2Mpd3JhcHBlZDsKKworICAgIGlmIChmdW5jKHNlbGYsIGFyZ3MsIGt3ZHMpIDwgMCkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgUHlfSU5DUkVGKFB5X05vbmUpOworICAgIHJldHVybiBQeV9Ob25lOworfQorCitzdGF0aWMgUHlPYmplY3QgKgordHBfbmV3X3dyYXBwZXIoUHlPYmplY3QgKnNlbGYsIFB5T2JqZWN0ICphcmdzLCBQeU9iamVjdCAqa3dkcykKK3sKKyAgICBQeVR5cGVPYmplY3QgKnR5cGUsICpzdWJ0eXBlLCAqc3RhdGljYmFzZTsKKyAgICBQeU9iamVjdCAqYXJnMCwgKnJlczsKKworICAgIGlmIChzZWxmID09IE5VTEwgfHwgIVB5VHlwZV9DaGVjayhzZWxmKSkKKyAgICAgICAgUHlfRmF0YWxFcnJvcigiX19uZXdfXygpIGNhbGxlZCB3aXRoIG5vbi10eXBlICdzZWxmJyIpOworICAgIHR5cGUgPSAoUHlUeXBlT2JqZWN0ICopc2VsZjsKKyAgICBpZiAoIVB5VHVwbGVfQ2hlY2soYXJncykgfHwgUHlUdXBsZV9HRVRfU0laRShhcmdzKSA8IDEpIHsKKyAgICAgICAgUHlFcnJfRm9ybWF0KFB5RXhjX1R5cGVFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICIlcy5fX25ld19fKCk6IG5vdCBlbm91Z2ggYXJndW1lbnRzIiwKKyAgICAgICAgICAgICAgICAgICAgIHR5cGUtPnRwX25hbWUpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgYXJnMCA9IFB5VHVwbGVfR0VUX0lURU0oYXJncywgMCk7CisgICAgaWYgKCFQeVR5cGVfQ2hlY2soYXJnMCkpIHsKKyAgICAgICAgUHlFcnJfRm9ybWF0KFB5RXhjX1R5cGVFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICIlcy5fX25ld19fKFgpOiBYIGlzIG5vdCBhIHR5cGUgb2JqZWN0ICglcykiLAorICAgICAgICAgICAgICAgICAgICAgdHlwZS0+dHBfbmFtZSwKKyAgICAgICAgICAgICAgICAgICAgIFB5X1RZUEUoYXJnMCktPnRwX25hbWUpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgc3VidHlwZSA9IChQeVR5cGVPYmplY3QgKilhcmcwOworICAgIGlmICghUHlUeXBlX0lzU3VidHlwZShzdWJ0eXBlLCB0eXBlKSkgeworICAgICAgICBQeUVycl9Gb3JtYXQoUHlFeGNfVHlwZUVycm9yLAorICAgICAgICAgICAgICAgICAgICAgIiVzLl9fbmV3X18oJXMpOiAlcyBpcyBub3QgYSBzdWJ0eXBlIG9mICVzIiwKKyAgICAgICAgICAgICAgICAgICAgIHR5cGUtPnRwX25hbWUsCisgICAgICAgICAgICAgICAgICAgICBzdWJ0eXBlLT50cF9uYW1lLAorICAgICAgICAgICAgICAgICAgICAgc3VidHlwZS0+dHBfbmFtZSwKKyAgICAgICAgICAgICAgICAgICAgIHR5cGUtPnRwX25hbWUpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisKKyAgICAvKiBDaGVjayB0aGF0IHRoZSB1c2UgZG9lc24ndCBkbyBzb21ldGhpbmcgc2lsbHkgYW5kIHVuc2FmZSBsaWtlCisgICAgICAgb2JqZWN0Ll9fbmV3X18oZGljdCkuICBUbyBkbyB0aGlzLCB3ZSBjaGVjayB0aGF0IHRoZQorICAgICAgIG1vc3QgZGVyaXZlZCBiYXNlIHRoYXQncyBub3QgYSBoZWFwIHR5cGUgaXMgdGhpcyB0eXBlLiAqLworICAgIHN0YXRpY2Jhc2UgPSBzdWJ0eXBlOworICAgIHdoaWxlIChzdGF0aWNiYXNlICYmIChzdGF0aWNiYXNlLT50cF9mbGFncyAmIFB5X1RQRkxBR1NfSEVBUFRZUEUpKQorICAgICAgICBzdGF0aWNiYXNlID0gc3RhdGljYmFzZS0+dHBfYmFzZTsKKyAgICAvKiBJZiBzdGF0aWNiYXNlIGlzIE5VTEwgbm93LCBpdCBpcyBhIHJlYWxseSB3ZWlyZCB0eXBlLgorICAgICAgIEluIHRoZSBzcGlyaXQgb2YgYmFja3dhcmRzIGNvbXBhdGliaWxpdHkgKD8pLCBqdXN0IHNodXQgdXAuICovCisgICAgaWYgKHN0YXRpY2Jhc2UgJiYgc3RhdGljYmFzZS0+dHBfbmV3ICE9IHR5cGUtPnRwX25ldykgeworICAgICAgICBQeUVycl9Gb3JtYXQoUHlFeGNfVHlwZUVycm9yLAorICAgICAgICAgICAgICAgICAgICAgIiVzLl9fbmV3X18oJXMpIGlzIG5vdCBzYWZlLCB1c2UgJXMuX19uZXdfXygpIiwKKyAgICAgICAgICAgICAgICAgICAgIHR5cGUtPnRwX25hbWUsCisgICAgICAgICAgICAgICAgICAgICBzdWJ0eXBlLT50cF9uYW1lLAorICAgICAgICAgICAgICAgICAgICAgc3RhdGljYmFzZSA9PSBOVUxMID8gIj8iIDogc3RhdGljYmFzZS0+dHBfbmFtZSk7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKworICAgIGFyZ3MgPSBQeVR1cGxlX0dldFNsaWNlKGFyZ3MsIDEsIFB5VHVwbGVfR0VUX1NJWkUoYXJncykpOworICAgIGlmIChhcmdzID09IE5VTEwpCisgICAgICAgIHJldHVybiBOVUxMOworICAgIHJlcyA9IHR5cGUtPnRwX25ldyhzdWJ0eXBlLCBhcmdzLCBrd2RzKTsKKyAgICBQeV9ERUNSRUYoYXJncyk7CisgICAgcmV0dXJuIHJlczsKK30KKworc3RhdGljIHN0cnVjdCBQeU1ldGhvZERlZiB0cF9uZXdfbWV0aG9kZGVmW10gPSB7CisgICAgeyJfX25ld19fIiwgKFB5Q0Z1bmN0aW9uKXRwX25ld193cmFwcGVyLCBNRVRIX1ZBUkFSR1N8TUVUSF9LRVlXT1JEUywKKyAgICAgUHlEb2NfU1RSKCJULl9fbmV3X18oUywgLi4uKSAtPiAiCisgICAgICAgICAgICAgICAiYSBuZXcgb2JqZWN0IHdpdGggdHlwZSBTLCBhIHN1YnR5cGUgb2YgVCIpfSwKKyAgICB7MH0KK307CisKK3N0YXRpYyBpbnQKK2FkZF90cF9uZXdfd3JhcHBlcihQeVR5cGVPYmplY3QgKnR5cGUpCit7CisgICAgUHlPYmplY3QgKmZ1bmM7CisKKyAgICBpZiAoUHlEaWN0X0dldEl0ZW1TdHJpbmcodHlwZS0+dHBfZGljdCwgIl9fbmV3X18iKSAhPSBOVUxMKQorICAgICAgICByZXR1cm4gMDsKKyAgICBmdW5jID0gUHlDRnVuY3Rpb25fTmV3KHRwX25ld19tZXRob2RkZWYsIChQeU9iamVjdCAqKXR5cGUpOworICAgIGlmIChmdW5jID09IE5VTEwpCisgICAgICAgIHJldHVybiAtMTsKKyAgICBpZiAoUHlEaWN0X1NldEl0ZW1TdHJpbmcodHlwZS0+dHBfZGljdCwgIl9fbmV3X18iLCBmdW5jKSkgeworICAgICAgICBQeV9ERUNSRUYoZnVuYyk7CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisgICAgUHlfREVDUkVGKGZ1bmMpOworICAgIHJldHVybiAwOworfQorCisvKiBTbG90IHdyYXBwZXJzIHRoYXQgY2FsbCB0aGUgY29ycmVzcG9uZGluZyBfX2Zvb19fIHNsb3QuICBTZWUgY29tbWVudHMKKyAgIGJlbG93IGF0IG92ZXJyaWRlX3Nsb3RzKCkgZm9yIG1vcmUgZXhwbGFuYXRpb24uICovCisKKyNkZWZpbmUgU0xPVDAoRlVOQ05BTUUsIE9QU1RSKSBcCitzdGF0aWMgUHlPYmplY3QgKiBcCitGVU5DTkFNRShQeU9iamVjdCAqc2VsZikgXAoreyBcCisgICAgc3RhdGljIFB5T2JqZWN0ICpjYWNoZV9zdHI7IFwKKyAgICByZXR1cm4gY2FsbF9tZXRob2Qoc2VsZiwgT1BTVFIsICZjYWNoZV9zdHIsICIoKSIpOyBcCit9CisKKyNkZWZpbmUgU0xPVDEoRlVOQ05BTUUsIE9QU1RSLCBBUkcxVFlQRSwgQVJHQ09ERVMpIFwKK3N0YXRpYyBQeU9iamVjdCAqIFwKK0ZVTkNOQU1FKFB5T2JqZWN0ICpzZWxmLCBBUkcxVFlQRSBhcmcxKSBcCit7IFwKKyAgICBzdGF0aWMgUHlPYmplY3QgKmNhY2hlX3N0cjsgXAorICAgIHJldHVybiBjYWxsX21ldGhvZChzZWxmLCBPUFNUUiwgJmNhY2hlX3N0ciwgIigiIEFSR0NPREVTICIpIiwgYXJnMSk7IFwKK30KKworLyogQm9vbGVhbiBoZWxwZXIgZm9yIFNMT1QxQklORlVMTCgpLgorICAgcmlnaHQuX19jbGFzc19fIGlzIGEgbm9udHJpdmlhbCBzdWJjbGFzcyBvZiBsZWZ0Ll9fY2xhc3NfXy4gKi8KK3N0YXRpYyBpbnQKK21ldGhvZF9pc19vdmVybG9hZGVkKFB5T2JqZWN0ICpsZWZ0LCBQeU9iamVjdCAqcmlnaHQsIGNoYXIgKm5hbWUpCit7CisgICAgUHlPYmplY3QgKmEsICpiOworICAgIGludCBvazsKKworICAgIGIgPSBQeU9iamVjdF9HZXRBdHRyU3RyaW5nKChQeU9iamVjdCAqKShQeV9UWVBFKHJpZ2h0KSksIG5hbWUpOworICAgIGlmIChiID09IE5VTEwpIHsKKyAgICAgICAgUHlFcnJfQ2xlYXIoKTsKKyAgICAgICAgLyogSWYgcmlnaHQgZG9lc24ndCBoYXZlIGl0LCBpdCdzIG5vdCBvdmVybG9hZGVkICovCisgICAgICAgIHJldHVybiAwOworICAgIH0KKworICAgIGEgPSBQeU9iamVjdF9HZXRBdHRyU3RyaW5nKChQeU9iamVjdCAqKShQeV9UWVBFKGxlZnQpKSwgbmFtZSk7CisgICAgaWYgKGEgPT0gTlVMTCkgeworICAgICAgICBQeUVycl9DbGVhcigpOworICAgICAgICBQeV9ERUNSRUYoYik7CisgICAgICAgIC8qIElmIHJpZ2h0IGhhcyBpdCBidXQgbGVmdCBkb2Vzbid0LCBpdCdzIG92ZXJsb2FkZWQgKi8KKyAgICAgICAgcmV0dXJuIDE7CisgICAgfQorCisgICAgb2sgPSBQeU9iamVjdF9SaWNoQ29tcGFyZUJvb2woYSwgYiwgUHlfTkUpOworICAgIFB5X0RFQ1JFRihhKTsKKyAgICBQeV9ERUNSRUYoYik7CisgICAgaWYgKG9rIDwgMCkgeworICAgICAgICBQeUVycl9DbGVhcigpOworICAgICAgICByZXR1cm4gMDsKKyAgICB9CisKKyAgICByZXR1cm4gb2s7Cit9CisKKworI2RlZmluZSBTTE9UMUJJTkZVTEwoRlVOQ05BTUUsIFRFU1RGVU5DLCBTTE9UTkFNRSwgT1BTVFIsIFJPUFNUUikgXAorc3RhdGljIFB5T2JqZWN0ICogXAorRlVOQ05BTUUoUHlPYmplY3QgKnNlbGYsIFB5T2JqZWN0ICpvdGhlcikgXAoreyBcCisgICAgc3RhdGljIFB5T2JqZWN0ICpjYWNoZV9zdHIsICpyY2FjaGVfc3RyOyBcCisgICAgaW50IGRvX290aGVyID0gUHlfVFlQRShzZWxmKSAhPSBQeV9UWVBFKG90aGVyKSAmJiBcCisgICAgICAgIFB5X1RZUEUob3RoZXIpLT50cF9hc19udW1iZXIgIT0gTlVMTCAmJiBcCisgICAgICAgIFB5X1RZUEUob3RoZXIpLT50cF9hc19udW1iZXItPlNMT1ROQU1FID09IFRFU1RGVU5DOyBcCisgICAgaWYgKFB5X1RZUEUoc2VsZiktPnRwX2FzX251bWJlciAhPSBOVUxMICYmIFwKKyAgICAgICAgUHlfVFlQRShzZWxmKS0+dHBfYXNfbnVtYmVyLT5TTE9UTkFNRSA9PSBURVNURlVOQykgeyBcCisgICAgICAgIFB5T2JqZWN0ICpyOyBcCisgICAgICAgIGlmIChkb19vdGhlciAmJiBcCisgICAgICAgICAgICBQeVR5cGVfSXNTdWJ0eXBlKFB5X1RZUEUob3RoZXIpLCBQeV9UWVBFKHNlbGYpKSAmJiBcCisgICAgICAgICAgICBtZXRob2RfaXNfb3ZlcmxvYWRlZChzZWxmLCBvdGhlciwgUk9QU1RSKSkgeyBcCisgICAgICAgICAgICByID0gY2FsbF9tYXliZSggXAorICAgICAgICAgICAgICAgIG90aGVyLCBST1BTVFIsICZyY2FjaGVfc3RyLCAiKE8pIiwgc2VsZik7IFwKKyAgICAgICAgICAgIGlmIChyICE9IFB5X05vdEltcGxlbWVudGVkKSBcCisgICAgICAgICAgICAgICAgcmV0dXJuIHI7IFwKKyAgICAgICAgICAgIFB5X0RFQ1JFRihyKTsgXAorICAgICAgICAgICAgZG9fb3RoZXIgPSAwOyBcCisgICAgICAgIH0gXAorICAgICAgICByID0gY2FsbF9tYXliZSggXAorICAgICAgICAgICAgc2VsZiwgT1BTVFIsICZjYWNoZV9zdHIsICIoTykiLCBvdGhlcik7IFwKKyAgICAgICAgaWYgKHIgIT0gUHlfTm90SW1wbGVtZW50ZWQgfHwgXAorICAgICAgICAgICAgUHlfVFlQRShvdGhlcikgPT0gUHlfVFlQRShzZWxmKSkgXAorICAgICAgICAgICAgcmV0dXJuIHI7IFwKKyAgICAgICAgUHlfREVDUkVGKHIpOyBcCisgICAgfSBcCisgICAgaWYgKGRvX290aGVyKSB7IFwKKyAgICAgICAgcmV0dXJuIGNhbGxfbWF5YmUoIFwKKyAgICAgICAgICAgIG90aGVyLCBST1BTVFIsICZyY2FjaGVfc3RyLCAiKE8pIiwgc2VsZik7IFwKKyAgICB9IFwKKyAgICBQeV9JTkNSRUYoUHlfTm90SW1wbGVtZW50ZWQpOyBcCisgICAgcmV0dXJuIFB5X05vdEltcGxlbWVudGVkOyBcCit9CisKKyNkZWZpbmUgU0xPVDFCSU4oRlVOQ05BTUUsIFNMT1ROQU1FLCBPUFNUUiwgUk9QU1RSKSBcCisgICAgU0xPVDFCSU5GVUxMKEZVTkNOQU1FLCBGVU5DTkFNRSwgU0xPVE5BTUUsIE9QU1RSLCBST1BTVFIpCisKKyNkZWZpbmUgU0xPVDIoRlVOQ05BTUUsIE9QU1RSLCBBUkcxVFlQRSwgQVJHMlRZUEUsIEFSR0NPREVTKSBcCitzdGF0aWMgUHlPYmplY3QgKiBcCitGVU5DTkFNRShQeU9iamVjdCAqc2VsZiwgQVJHMVRZUEUgYXJnMSwgQVJHMlRZUEUgYXJnMikgXAoreyBcCisgICAgc3RhdGljIFB5T2JqZWN0ICpjYWNoZV9zdHI7IFwKKyAgICByZXR1cm4gY2FsbF9tZXRob2Qoc2VsZiwgT1BTVFIsICZjYWNoZV9zdHIsIFwKKyAgICAgICAgICAgICAgICAgICAgICAgIigiIEFSR0NPREVTICIpIiwgYXJnMSwgYXJnMik7IFwKK30KKworc3RhdGljIFB5X3NzaXplX3QKK3Nsb3Rfc3FfbGVuZ3RoKFB5T2JqZWN0ICpzZWxmKQoreworICAgIHN0YXRpYyBQeU9iamVjdCAqbGVuX3N0cjsKKyAgICBQeU9iamVjdCAqcmVzID0gY2FsbF9tZXRob2Qoc2VsZiwgIl9fbGVuX18iLCAmbGVuX3N0ciwgIigpIik7CisgICAgUHlfc3NpemVfdCBsZW47CisKKyAgICBpZiAocmVzID09IE5VTEwpCisgICAgICAgIHJldHVybiAtMTsKKyAgICBsZW4gPSBQeUludF9Bc1NzaXplX3QocmVzKTsKKyAgICBQeV9ERUNSRUYocmVzKTsKKyAgICBpZiAobGVuIDwgMCkgeworICAgICAgICBpZiAoIVB5RXJyX09jY3VycmVkKCkpCisgICAgICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfVmFsdWVFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAiX19sZW5fXygpIHNob3VsZCByZXR1cm4gPj0gMCIpOworICAgICAgICByZXR1cm4gLTE7CisgICAgfQorICAgIHJldHVybiBsZW47Cit9CisKKy8qIFN1cGVyLW9wdGltaXplZCB2ZXJzaW9uIG9mIHNsb3Rfc3FfaXRlbS4KKyAgIE90aGVyIHNsb3RzIGNvdWxkIGRvIHRoZSBzYW1lLi4uICovCitzdGF0aWMgUHlPYmplY3QgKgorc2xvdF9zcV9pdGVtKFB5T2JqZWN0ICpzZWxmLCBQeV9zc2l6ZV90IGkpCit7CisgICAgc3RhdGljIFB5T2JqZWN0ICpnZXRpdGVtX3N0cjsKKyAgICBQeU9iamVjdCAqZnVuYywgKmFyZ3MgPSBOVUxMLCAqaXZhbCA9IE5VTEwsICpyZXR2YWwgPSBOVUxMOworICAgIGRlc2NyZ2V0ZnVuYyBmOworCisgICAgaWYgKGdldGl0ZW1fc3RyID09IE5VTEwpIHsKKyAgICAgICAgZ2V0aXRlbV9zdHIgPSBQeVN0cmluZ19JbnRlcm5Gcm9tU3RyaW5nKCJfX2dldGl0ZW1fXyIpOworICAgICAgICBpZiAoZ2V0aXRlbV9zdHIgPT0gTlVMTCkKKyAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICBmdW5jID0gX1B5VHlwZV9Mb29rdXAoUHlfVFlQRShzZWxmKSwgZ2V0aXRlbV9zdHIpOworICAgIGlmIChmdW5jICE9IE5VTEwpIHsKKyAgICAgICAgaWYgKChmID0gUHlfVFlQRShmdW5jKS0+dHBfZGVzY3JfZ2V0KSA9PSBOVUxMKQorICAgICAgICAgICAgUHlfSU5DUkVGKGZ1bmMpOworICAgICAgICBlbHNlIHsKKyAgICAgICAgICAgIGZ1bmMgPSBmKGZ1bmMsIHNlbGYsIChQeU9iamVjdCAqKShQeV9UWVBFKHNlbGYpKSk7CisgICAgICAgICAgICBpZiAoZnVuYyA9PSBOVUxMKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICAgICAgaXZhbCA9IFB5SW50X0Zyb21Tc2l6ZV90KGkpOworICAgICAgICBpZiAoaXZhbCAhPSBOVUxMKSB7CisgICAgICAgICAgICBhcmdzID0gUHlUdXBsZV9OZXcoMSk7CisgICAgICAgICAgICBpZiAoYXJncyAhPSBOVUxMKSB7CisgICAgICAgICAgICAgICAgUHlUdXBsZV9TRVRfSVRFTShhcmdzLCAwLCBpdmFsKTsKKyAgICAgICAgICAgICAgICByZXR2YWwgPSBQeU9iamVjdF9DYWxsKGZ1bmMsIGFyZ3MsIE5VTEwpOworICAgICAgICAgICAgICAgIFB5X1hERUNSRUYoYXJncyk7CisgICAgICAgICAgICAgICAgUHlfWERFQ1JFRihmdW5jKTsKKyAgICAgICAgICAgICAgICByZXR1cm4gcmV0dmFsOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorICAgIGVsc2UgeworICAgICAgICBQeUVycl9TZXRPYmplY3QoUHlFeGNfQXR0cmlidXRlRXJyb3IsIGdldGl0ZW1fc3RyKTsKKyAgICB9CisgICAgUHlfWERFQ1JFRihhcmdzKTsKKyAgICBQeV9YREVDUkVGKGl2YWwpOworICAgIFB5X1hERUNSRUYoZnVuYyk7CisgICAgcmV0dXJuIE5VTEw7Cit9CisKK3N0YXRpYyBQeU9iamVjdCoKK3Nsb3Rfc3Ffc2xpY2UoUHlPYmplY3QgKnNlbGYsIFB5X3NzaXplX3QgaSwgUHlfc3NpemVfdCBqKQoreworICAgIHN0YXRpYyBQeU9iamVjdCAqZ2V0c2xpY2Vfc3RyOworCisgICAgaWYgKFB5RXJyX1dhcm5QeTNrKCJpbiAzLngsIF9fZ2V0c2xpY2VfXyBoYXMgYmVlbiByZW1vdmVkOyAiCisgICAgICAgICAgICAgICAgICAgICAgICAidXNlIF9fZ2V0aXRlbV9fIiwgMSkgPCAwKQorICAgICAgICByZXR1cm4gTlVMTDsKKyAgICByZXR1cm4gY2FsbF9tZXRob2Qoc2VsZiwgIl9fZ2V0c2xpY2VfXyIsICZnZXRzbGljZV9zdHIsCisgICAgICAgICJubiIsIGksIGopOworfQorCitzdGF0aWMgaW50CitzbG90X3NxX2Fzc19pdGVtKFB5T2JqZWN0ICpzZWxmLCBQeV9zc2l6ZV90IGluZGV4LCBQeU9iamVjdCAqdmFsdWUpCit7CisgICAgUHlPYmplY3QgKnJlczsKKyAgICBzdGF0aWMgUHlPYmplY3QgKmRlbGl0ZW1fc3RyLCAqc2V0aXRlbV9zdHI7CisKKyAgICBpZiAodmFsdWUgPT0gTlVMTCkKKyAgICAgICAgcmVzID0gY2FsbF9tZXRob2Qoc2VsZiwgIl9fZGVsaXRlbV9fIiwgJmRlbGl0ZW1fc3RyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAiKG4pIiwgaW5kZXgpOworICAgIGVsc2UKKyAgICAgICAgcmVzID0gY2FsbF9tZXRob2Qoc2VsZiwgIl9fc2V0aXRlbV9fIiwgJnNldGl0ZW1fc3RyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAiKG5PKSIsIGluZGV4LCB2YWx1ZSk7CisgICAgaWYgKHJlcyA9PSBOVUxMKQorICAgICAgICByZXR1cm4gLTE7CisgICAgUHlfREVDUkVGKHJlcyk7CisgICAgcmV0dXJuIDA7Cit9CisKK3N0YXRpYyBpbnQKK3Nsb3Rfc3FfYXNzX3NsaWNlKFB5T2JqZWN0ICpzZWxmLCBQeV9zc2l6ZV90IGksIFB5X3NzaXplX3QgaiwgUHlPYmplY3QgKnZhbHVlKQoreworICAgIFB5T2JqZWN0ICpyZXM7CisgICAgc3RhdGljIFB5T2JqZWN0ICpkZWxzbGljZV9zdHIsICpzZXRzbGljZV9zdHI7CisKKyAgICBpZiAodmFsdWUgPT0gTlVMTCkgeworICAgICAgICBpZiAoUHlFcnJfV2FyblB5M2soImluIDMueCwgX19kZWxzbGljZV9fIGhhcyBiZWVuIHJlbW92ZWQ7ICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICJ1c2UgX19kZWxpdGVtX18iLCAxKSA8IDApCisgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgIHJlcyA9IGNhbGxfbWV0aG9kKHNlbGYsICJfX2RlbHNsaWNlX18iLCAmZGVsc2xpY2Vfc3RyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAiKG5uKSIsIGksIGopOworICAgIH0KKyAgICBlbHNlIHsKKyAgICAgICAgaWYgKFB5RXJyX1dhcm5QeTNrKCJpbiAzLngsIF9fc2V0c2xpY2VfXyBoYXMgYmVlbiByZW1vdmVkOyAiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ1c2UgX19zZXRpdGVtX18iLCAxKSA8IDApCisgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgIHJlcyA9IGNhbGxfbWV0aG9kKHNlbGYsICJfX3NldHNsaWNlX18iLCAmc2V0c2xpY2Vfc3RyLAorICAgICAgICAgICAgICAgICAgIihubk8pIiwgaSwgaiwgdmFsdWUpOworICAgIH0KKyAgICBpZiAocmVzID09IE5VTEwpCisgICAgICAgIHJldHVybiAtMTsKKyAgICBQeV9ERUNSRUYocmVzKTsKKyAgICByZXR1cm4gMDsKK30KKworc3RhdGljIGludAorc2xvdF9zcV9jb250YWlucyhQeU9iamVjdCAqc2VsZiwgUHlPYmplY3QgKnZhbHVlKQoreworICAgIFB5T2JqZWN0ICpmdW5jLCAqcmVzLCAqYXJnczsKKyAgICBpbnQgcmVzdWx0ID0gLTE7CisKKyAgICBzdGF0aWMgUHlPYmplY3QgKmNvbnRhaW5zX3N0cjsKKworICAgIGZ1bmMgPSBsb29rdXBfbWF5YmUoc2VsZiwgIl9fY29udGFpbnNfXyIsICZjb250YWluc19zdHIpOworICAgIGlmIChmdW5jICE9IE5VTEwpIHsKKyAgICAgICAgYXJncyA9IFB5VHVwbGVfUGFjaygxLCB2YWx1ZSk7CisgICAgICAgIGlmIChhcmdzID09IE5VTEwpCisgICAgICAgICAgICByZXMgPSBOVUxMOworICAgICAgICBlbHNlIHsKKyAgICAgICAgICAgIHJlcyA9IFB5T2JqZWN0X0NhbGwoZnVuYywgYXJncywgTlVMTCk7CisgICAgICAgICAgICBQeV9ERUNSRUYoYXJncyk7CisgICAgICAgIH0KKyAgICAgICAgUHlfREVDUkVGKGZ1bmMpOworICAgICAgICBpZiAocmVzICE9IE5VTEwpIHsKKyAgICAgICAgICAgIHJlc3VsdCA9IFB5T2JqZWN0X0lzVHJ1ZShyZXMpOworICAgICAgICAgICAgUHlfREVDUkVGKHJlcyk7CisgICAgICAgIH0KKyAgICB9CisgICAgZWxzZSBpZiAoISBQeUVycl9PY2N1cnJlZCgpKSB7CisgICAgICAgIC8qIFBvc3NpYmxlIHJlc3VsdHM6IC0xIGFuZCAxICovCisgICAgICAgIHJlc3VsdCA9IChpbnQpX1B5U2VxdWVuY2VfSXRlclNlYXJjaChzZWxmLCB2YWx1ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUFlfSVRFUlNFQVJDSF9DT05UQUlOUyk7CisgICAgfQorICAgIHJldHVybiByZXN1bHQ7Cit9CisKKyNkZWZpbmUgc2xvdF9tcF9sZW5ndGggc2xvdF9zcV9sZW5ndGgKKworU0xPVDEoc2xvdF9tcF9zdWJzY3JpcHQsICJfX2dldGl0ZW1fXyIsIFB5T2JqZWN0ICosICJPIikKKworc3RhdGljIGludAorc2xvdF9tcF9hc3Nfc3Vic2NyaXB0KFB5T2JqZWN0ICpzZWxmLCBQeU9iamVjdCAqa2V5LCBQeU9iamVjdCAqdmFsdWUpCit7CisgICAgUHlPYmplY3QgKnJlczsKKyAgICBzdGF0aWMgUHlPYmplY3QgKmRlbGl0ZW1fc3RyLCAqc2V0aXRlbV9zdHI7CisKKyAgICBpZiAodmFsdWUgPT0gTlVMTCkKKyAgICAgICAgcmVzID0gY2FsbF9tZXRob2Qoc2VsZiwgIl9fZGVsaXRlbV9fIiwgJmRlbGl0ZW1fc3RyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAiKE8pIiwga2V5KTsKKyAgICBlbHNlCisgICAgICAgIHJlcyA9IGNhbGxfbWV0aG9kKHNlbGYsICJfX3NldGl0ZW1fXyIsICZzZXRpdGVtX3N0ciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAiKE9PKSIsIGtleSwgdmFsdWUpOworICAgIGlmIChyZXMgPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIC0xOworICAgIFB5X0RFQ1JFRihyZXMpOworICAgIHJldHVybiAwOworfQorCitTTE9UMUJJTihzbG90X25iX2FkZCwgbmJfYWRkLCAiX19hZGRfXyIsICJfX3JhZGRfXyIpCitTTE9UMUJJTihzbG90X25iX3N1YnRyYWN0LCBuYl9zdWJ0cmFjdCwgIl9fc3ViX18iLCAiX19yc3ViX18iKQorU0xPVDFCSU4oc2xvdF9uYl9tdWx0aXBseSwgbmJfbXVsdGlwbHksICJfX211bF9fIiwgIl9fcm11bF9fIikKK1NMT1QxQklOKHNsb3RfbmJfZGl2aWRlLCBuYl9kaXZpZGUsICJfX2Rpdl9fIiwgIl9fcmRpdl9fIikKK1NMT1QxQklOKHNsb3RfbmJfcmVtYWluZGVyLCBuYl9yZW1haW5kZXIsICJfX21vZF9fIiwgIl9fcm1vZF9fIikKK1NMT1QxQklOKHNsb3RfbmJfZGl2bW9kLCBuYl9kaXZtb2QsICJfX2Rpdm1vZF9fIiwgIl9fcmRpdm1vZF9fIikKKworc3RhdGljIFB5T2JqZWN0ICpzbG90X25iX3Bvd2VyKFB5T2JqZWN0ICosIFB5T2JqZWN0ICosIFB5T2JqZWN0ICopOworCitTTE9UMUJJTkZVTEwoc2xvdF9uYl9wb3dlcl9iaW5hcnksIHNsb3RfbmJfcG93ZXIsCisgICAgICAgICAgICAgbmJfcG93ZXIsICJfX3Bvd19fIiwgIl9fcnBvd19fIikKKworc3RhdGljIFB5T2JqZWN0ICoKK3Nsb3RfbmJfcG93ZXIoUHlPYmplY3QgKnNlbGYsIFB5T2JqZWN0ICpvdGhlciwgUHlPYmplY3QgKm1vZHVsdXMpCit7CisgICAgc3RhdGljIFB5T2JqZWN0ICpwb3dfc3RyOworCisgICAgaWYgKG1vZHVsdXMgPT0gUHlfTm9uZSkKKyAgICAgICAgcmV0dXJuIHNsb3RfbmJfcG93ZXJfYmluYXJ5KHNlbGYsIG90aGVyKTsKKyAgICAvKiBUaHJlZS1hcmcgcG93ZXIgZG9lc24ndCB1c2UgX19ycG93X18uICBCdXQgdGVybmFyeV9vcAorICAgICAgIGNhbiBjYWxsIHRoaXMgd2hlbiB0aGUgc2Vjb25kIGFyZ3VtZW50J3MgdHlwZSB1c2VzCisgICAgICAgc2xvdF9uYl9wb3dlciwgc28gY2hlY2sgYmVmb3JlIGNhbGxpbmcgc2VsZi5fX3Bvd19fLiAqLworICAgIGlmIChQeV9UWVBFKHNlbGYpLT50cF9hc19udW1iZXIgIT0gTlVMTCAmJgorICAgICAgICBQeV9UWVBFKHNlbGYpLT50cF9hc19udW1iZXItPm5iX3Bvd2VyID09IHNsb3RfbmJfcG93ZXIpIHsKKyAgICAgICAgcmV0dXJuIGNhbGxfbWV0aG9kKHNlbGYsICJfX3Bvd19fIiwgJnBvd19zdHIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAiKE9PKSIsIG90aGVyLCBtb2R1bHVzKTsKKyAgICB9CisgICAgUHlfSU5DUkVGKFB5X05vdEltcGxlbWVudGVkKTsKKyAgICByZXR1cm4gUHlfTm90SW1wbGVtZW50ZWQ7Cit9CisKK1NMT1QwKHNsb3RfbmJfbmVnYXRpdmUsICJfX25lZ19fIikKK1NMT1QwKHNsb3RfbmJfcG9zaXRpdmUsICJfX3Bvc19fIikKK1NMT1QwKHNsb3RfbmJfYWJzb2x1dGUsICJfX2Fic19fIikKKworc3RhdGljIGludAorc2xvdF9uYl9ub256ZXJvKFB5T2JqZWN0ICpzZWxmKQoreworICAgIFB5T2JqZWN0ICpmdW5jLCAqYXJnczsKKyAgICBzdGF0aWMgUHlPYmplY3QgKm5vbnplcm9fc3RyLCAqbGVuX3N0cjsKKyAgICBpbnQgcmVzdWx0ID0gLTE7CisgICAgaW50IHVzaW5nX2xlbiA9IDA7CisKKyAgICBmdW5jID0gbG9va3VwX21heWJlKHNlbGYsICJfX25vbnplcm9fXyIsICZub256ZXJvX3N0cik7CisgICAgaWYgKGZ1bmMgPT0gTlVMTCkgeworICAgICAgICBpZiAoUHlFcnJfT2NjdXJyZWQoKSkKKyAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgZnVuYyA9IGxvb2t1cF9tYXliZShzZWxmLCAiX19sZW5fXyIsICZsZW5fc3RyKTsKKyAgICAgICAgaWYgKGZ1bmMgPT0gTlVMTCkKKyAgICAgICAgICAgIHJldHVybiBQeUVycl9PY2N1cnJlZCgpID8gLTEgOiAxOworICAgICAgICB1c2luZ19sZW4gPSAxOworICAgIH0KKyAgICBhcmdzID0gUHlUdXBsZV9OZXcoMCk7CisgICAgaWYgKGFyZ3MgIT0gTlVMTCkgeworICAgICAgICBQeU9iamVjdCAqdGVtcCA9IFB5T2JqZWN0X0NhbGwoZnVuYywgYXJncywgTlVMTCk7CisgICAgICAgIFB5X0RFQ1JFRihhcmdzKTsKKyAgICAgICAgaWYgKHRlbXAgIT0gTlVMTCkgeworICAgICAgICAgICAgaWYgKFB5SW50X0NoZWNrRXhhY3QodGVtcCkgfHwgUHlCb29sX0NoZWNrKHRlbXApKQorICAgICAgICAgICAgICAgIHJlc3VsdCA9IFB5T2JqZWN0X0lzVHJ1ZSh0ZW1wKTsKKyAgICAgICAgICAgIGVsc2UgeworICAgICAgICAgICAgICAgIFB5RXJyX0Zvcm1hdChQeUV4Y19UeXBlRXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIlcyBzaG91bGQgcmV0dXJuICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImJvb2wgb3IgaW50LCByZXR1cm5lZCAlcyIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh1c2luZ19sZW4gPyAiX19sZW5fXyIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6ICJfX25vbnplcm9fXyIpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZW1wLT5vYl90eXBlLT50cF9uYW1lKTsKKyAgICAgICAgICAgICAgICByZXN1bHQgPSAtMTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIFB5X0RFQ1JFRih0ZW1wKTsKKyAgICAgICAgfQorICAgIH0KKyAgICBQeV9ERUNSRUYoZnVuYyk7CisgICAgcmV0dXJuIHJlc3VsdDsKK30KKworCitzdGF0aWMgUHlPYmplY3QgKgorc2xvdF9uYl9pbmRleChQeU9iamVjdCAqc2VsZikKK3sKKyAgICBzdGF0aWMgUHlPYmplY3QgKmluZGV4X3N0cjsKKyAgICByZXR1cm4gY2FsbF9tZXRob2Qoc2VsZiwgIl9faW5kZXhfXyIsICZpbmRleF9zdHIsICIoKSIpOworfQorCisKK1NMT1QwKHNsb3RfbmJfaW52ZXJ0LCAiX19pbnZlcnRfXyIpCitTTE9UMUJJTihzbG90X25iX2xzaGlmdCwgbmJfbHNoaWZ0LCAiX19sc2hpZnRfXyIsICJfX3Jsc2hpZnRfXyIpCitTTE9UMUJJTihzbG90X25iX3JzaGlmdCwgbmJfcnNoaWZ0LCAiX19yc2hpZnRfXyIsICJfX3Jyc2hpZnRfXyIpCitTTE9UMUJJTihzbG90X25iX2FuZCwgbmJfYW5kLCAiX19hbmRfXyIsICJfX3JhbmRfXyIpCitTTE9UMUJJTihzbG90X25iX3hvciwgbmJfeG9yLCAiX194b3JfXyIsICJfX3J4b3JfXyIpCitTTE9UMUJJTihzbG90X25iX29yLCBuYl9vciwgIl9fb3JfXyIsICJfX3Jvcl9fIikKKworc3RhdGljIGludAorc2xvdF9uYl9jb2VyY2UoUHlPYmplY3QgKiphLCBQeU9iamVjdCAqKmIpCit7CisgICAgc3RhdGljIFB5T2JqZWN0ICpjb2VyY2Vfc3RyOworICAgIFB5T2JqZWN0ICpzZWxmID0gKmEsICpvdGhlciA9ICpiOworCisgICAgaWYgKHNlbGYtPm9iX3R5cGUtPnRwX2FzX251bWJlciAhPSBOVUxMICYmCisgICAgICAgIHNlbGYtPm9iX3R5cGUtPnRwX2FzX251bWJlci0+bmJfY29lcmNlID09IHNsb3RfbmJfY29lcmNlKSB7CisgICAgICAgIFB5T2JqZWN0ICpyOworICAgICAgICByID0gY2FsbF9tYXliZSgKKyAgICAgICAgICAgIHNlbGYsICJfX2NvZXJjZV9fIiwgJmNvZXJjZV9zdHIsICIoTykiLCBvdGhlcik7CisgICAgICAgIGlmIChyID09IE5VTEwpCisgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgIGlmIChyID09IFB5X05vdEltcGxlbWVudGVkKSB7CisgICAgICAgICAgICBQeV9ERUNSRUYocik7CisgICAgICAgIH0KKyAgICAgICAgZWxzZSB7CisgICAgICAgICAgICBpZiAoIVB5VHVwbGVfQ2hlY2socikgfHwgUHlUdXBsZV9HRVRfU0laRShyKSAhPSAyKSB7CisgICAgICAgICAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1R5cGVFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgIl9fY29lcmNlX18gZGlkbid0IHJldHVybiBhIDItdHVwbGUiKTsKKyAgICAgICAgICAgICAgICBQeV9ERUNSRUYocik7CisgICAgICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICAgICAgfQorICAgICAgICAgICAgKmEgPSBQeVR1cGxlX0dFVF9JVEVNKHIsIDApOworICAgICAgICAgICAgUHlfSU5DUkVGKCphKTsKKyAgICAgICAgICAgICpiID0gUHlUdXBsZV9HRVRfSVRFTShyLCAxKTsKKyAgICAgICAgICAgIFB5X0lOQ1JFRigqYik7CisgICAgICAgICAgICBQeV9ERUNSRUYocik7CisgICAgICAgICAgICByZXR1cm4gMDsKKyAgICAgICAgfQorICAgIH0KKyAgICBpZiAob3RoZXItPm9iX3R5cGUtPnRwX2FzX251bWJlciAhPSBOVUxMICYmCisgICAgICAgIG90aGVyLT5vYl90eXBlLT50cF9hc19udW1iZXItPm5iX2NvZXJjZSA9PSBzbG90X25iX2NvZXJjZSkgeworICAgICAgICBQeU9iamVjdCAqcjsKKyAgICAgICAgciA9IGNhbGxfbWF5YmUoCisgICAgICAgICAgICBvdGhlciwgIl9fY29lcmNlX18iLCAmY29lcmNlX3N0ciwgIihPKSIsIHNlbGYpOworICAgICAgICBpZiAociA9PSBOVUxMKQorICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICBpZiAociA9PSBQeV9Ob3RJbXBsZW1lbnRlZCkgeworICAgICAgICAgICAgUHlfREVDUkVGKHIpOworICAgICAgICAgICAgcmV0dXJuIDE7CisgICAgICAgIH0KKyAgICAgICAgaWYgKCFQeVR1cGxlX0NoZWNrKHIpIHx8IFB5VHVwbGVfR0VUX1NJWkUocikgIT0gMikgeworICAgICAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1R5cGVFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAiX19jb2VyY2VfXyBkaWRuJ3QgcmV0dXJuIGEgMi10dXBsZSIpOworICAgICAgICAgICAgUHlfREVDUkVGKHIpOworICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICB9CisgICAgICAgICphID0gUHlUdXBsZV9HRVRfSVRFTShyLCAxKTsKKyAgICAgICAgUHlfSU5DUkVGKCphKTsKKyAgICAgICAgKmIgPSBQeVR1cGxlX0dFVF9JVEVNKHIsIDApOworICAgICAgICBQeV9JTkNSRUYoKmIpOworICAgICAgICBQeV9ERUNSRUYocik7CisgICAgICAgIHJldHVybiAwOworICAgIH0KKyAgICByZXR1cm4gMTsKK30KKworU0xPVDAoc2xvdF9uYl9pbnQsICJfX2ludF9fIikKK1NMT1QwKHNsb3RfbmJfbG9uZywgIl9fbG9uZ19fIikKK1NMT1QwKHNsb3RfbmJfZmxvYXQsICJfX2Zsb2F0X18iKQorU0xPVDAoc2xvdF9uYl9vY3QsICJfX29jdF9fIikKK1NMT1QwKHNsb3RfbmJfaGV4LCAiX19oZXhfXyIpCitTTE9UMShzbG90X25iX2lucGxhY2VfYWRkLCAiX19pYWRkX18iLCBQeU9iamVjdCAqLCAiTyIpCitTTE9UMShzbG90X25iX2lucGxhY2Vfc3VidHJhY3QsICJfX2lzdWJfXyIsIFB5T2JqZWN0ICosICJPIikKK1NMT1QxKHNsb3RfbmJfaW5wbGFjZV9tdWx0aXBseSwgIl9faW11bF9fIiwgUHlPYmplY3QgKiwgIk8iKQorU0xPVDEoc2xvdF9uYl9pbnBsYWNlX2RpdmlkZSwgIl9faWRpdl9fIiwgUHlPYmplY3QgKiwgIk8iKQorU0xPVDEoc2xvdF9uYl9pbnBsYWNlX3JlbWFpbmRlciwgIl9faW1vZF9fIiwgUHlPYmplY3QgKiwgIk8iKQorLyogQ2FuJ3QgdXNlIFNMT1QxIGhlcmUsIGJlY2F1c2UgbmJfaW5wbGFjZV9wb3dlciBpcyB0ZXJuYXJ5ICovCitzdGF0aWMgUHlPYmplY3QgKgorc2xvdF9uYl9pbnBsYWNlX3Bvd2VyKFB5T2JqZWN0ICpzZWxmLCBQeU9iamVjdCAqIGFyZzEsIFB5T2JqZWN0ICphcmcyKQoreworICBzdGF0aWMgUHlPYmplY3QgKmNhY2hlX3N0cjsKKyAgcmV0dXJuIGNhbGxfbWV0aG9kKHNlbGYsICJfX2lwb3dfXyIsICZjYWNoZV9zdHIsICIoIiAiTyIgIikiLCBhcmcxKTsKK30KK1NMT1QxKHNsb3RfbmJfaW5wbGFjZV9sc2hpZnQsICJfX2lsc2hpZnRfXyIsIFB5T2JqZWN0ICosICJPIikKK1NMT1QxKHNsb3RfbmJfaW5wbGFjZV9yc2hpZnQsICJfX2lyc2hpZnRfXyIsIFB5T2JqZWN0ICosICJPIikKK1NMT1QxKHNsb3RfbmJfaW5wbGFjZV9hbmQsICJfX2lhbmRfXyIsIFB5T2JqZWN0ICosICJPIikKK1NMT1QxKHNsb3RfbmJfaW5wbGFjZV94b3IsICJfX2l4b3JfXyIsIFB5T2JqZWN0ICosICJPIikKK1NMT1QxKHNsb3RfbmJfaW5wbGFjZV9vciwgIl9faW9yX18iLCBQeU9iamVjdCAqLCAiTyIpCitTTE9UMUJJTihzbG90X25iX2Zsb29yX2RpdmlkZSwgbmJfZmxvb3JfZGl2aWRlLAorICAgICAgICAgIl9fZmxvb3JkaXZfXyIsICJfX3JmbG9vcmRpdl9fIikKK1NMT1QxQklOKHNsb3RfbmJfdHJ1ZV9kaXZpZGUsIG5iX3RydWVfZGl2aWRlLCAiX190cnVlZGl2X18iLCAiX19ydHJ1ZWRpdl9fIikKK1NMT1QxKHNsb3RfbmJfaW5wbGFjZV9mbG9vcl9kaXZpZGUsICJfX2lmbG9vcmRpdl9fIiwgUHlPYmplY3QgKiwgIk8iKQorU0xPVDEoc2xvdF9uYl9pbnBsYWNlX3RydWVfZGl2aWRlLCAiX19pdHJ1ZWRpdl9fIiwgUHlPYmplY3QgKiwgIk8iKQorCitzdGF0aWMgaW50CitoYWxmX2NvbXBhcmUoUHlPYmplY3QgKnNlbGYsIFB5T2JqZWN0ICpvdGhlcikKK3sKKyAgICBQeU9iamVjdCAqZnVuYywgKmFyZ3MsICpyZXM7CisgICAgc3RhdGljIFB5T2JqZWN0ICpjbXBfc3RyOworICAgIFB5X3NzaXplX3QgYzsKKworICAgIGZ1bmMgPSBsb29rdXBfbWV0aG9kKHNlbGYsICJfX2NtcF9fIiwgJmNtcF9zdHIpOworICAgIGlmIChmdW5jID09IE5VTEwpIHsKKyAgICAgICAgUHlFcnJfQ2xlYXIoKTsKKyAgICB9CisgICAgZWxzZSB7CisgICAgICAgIGFyZ3MgPSBQeVR1cGxlX1BhY2soMSwgb3RoZXIpOworICAgICAgICBpZiAoYXJncyA9PSBOVUxMKQorICAgICAgICAgICAgcmVzID0gTlVMTDsKKyAgICAgICAgZWxzZSB7CisgICAgICAgICAgICByZXMgPSBQeU9iamVjdF9DYWxsKGZ1bmMsIGFyZ3MsIE5VTEwpOworICAgICAgICAgICAgUHlfREVDUkVGKGFyZ3MpOworICAgICAgICB9CisgICAgICAgIFB5X0RFQ1JFRihmdW5jKTsKKyAgICAgICAgaWYgKHJlcyAhPSBQeV9Ob3RJbXBsZW1lbnRlZCkgeworICAgICAgICAgICAgaWYgKHJlcyA9PSBOVUxMKQorICAgICAgICAgICAgICAgIHJldHVybiAtMjsKKyAgICAgICAgICAgIGMgPSBQeUludF9Bc0xvbmcocmVzKTsKKyAgICAgICAgICAgIFB5X0RFQ1JFRihyZXMpOworICAgICAgICAgICAgaWYgKGMgPT0gLTEgJiYgUHlFcnJfT2NjdXJyZWQoKSkKKyAgICAgICAgICAgICAgICByZXR1cm4gLTI7CisgICAgICAgICAgICByZXR1cm4gKGMgPCAwKSA/IC0xIDogKGMgPiAwKSA/IDEgOiAwOworICAgICAgICB9CisgICAgICAgIFB5X0RFQ1JFRihyZXMpOworICAgIH0KKyAgICByZXR1cm4gMjsKK30KKworLyogVGhpcyBzbG90IGlzIHB1Ymxpc2hlZCBmb3IgdGhlIGJlbmVmaXQgb2YgdHJ5XzN3YXlfY29tcGFyZSBpbiBvYmplY3QuYyAqLworaW50CitfUHlPYmplY3RfU2xvdENvbXBhcmUoUHlPYmplY3QgKnNlbGYsIFB5T2JqZWN0ICpvdGhlcikKK3sKKyAgICBpbnQgYzsKKworICAgIGlmIChQeV9UWVBFKHNlbGYpLT50cF9jb21wYXJlID09IF9QeU9iamVjdF9TbG90Q29tcGFyZSkgeworICAgICAgICBjID0gaGFsZl9jb21wYXJlKHNlbGYsIG90aGVyKTsKKyAgICAgICAgaWYgKGMgPD0gMSkKKyAgICAgICAgICAgIHJldHVybiBjOworICAgIH0KKyAgICBpZiAoUHlfVFlQRShvdGhlciktPnRwX2NvbXBhcmUgPT0gX1B5T2JqZWN0X1Nsb3RDb21wYXJlKSB7CisgICAgICAgIGMgPSBoYWxmX2NvbXBhcmUob3RoZXIsIHNlbGYpOworICAgICAgICBpZiAoYyA8IC0xKQorICAgICAgICAgICAgcmV0dXJuIC0yOworICAgICAgICBpZiAoYyA8PSAxKQorICAgICAgICAgICAgcmV0dXJuIC1jOworICAgIH0KKyAgICByZXR1cm4gKHZvaWQgKilzZWxmIDwgKHZvaWQgKilvdGhlciA/IC0xIDoKKyAgICAgICAgKHZvaWQgKilzZWxmID4gKHZvaWQgKilvdGhlciA/IDEgOiAwOworfQorCitzdGF0aWMgUHlPYmplY3QgKgorc2xvdF90cF9yZXByKFB5T2JqZWN0ICpzZWxmKQoreworICAgIFB5T2JqZWN0ICpmdW5jLCAqcmVzOworICAgIHN0YXRpYyBQeU9iamVjdCAqcmVwcl9zdHI7CisKKyAgICBmdW5jID0gbG9va3VwX21ldGhvZChzZWxmLCAiX19yZXByX18iLCAmcmVwcl9zdHIpOworICAgIGlmIChmdW5jICE9IE5VTEwpIHsKKyAgICAgICAgcmVzID0gUHlFdmFsX0NhbGxPYmplY3QoZnVuYywgTlVMTCk7CisgICAgICAgIFB5X0RFQ1JFRihmdW5jKTsKKyAgICAgICAgcmV0dXJuIHJlczsKKyAgICB9CisgICAgUHlFcnJfQ2xlYXIoKTsKKyAgICByZXR1cm4gUHlTdHJpbmdfRnJvbUZvcm1hdCgiPCVzIG9iamVjdCBhdCAlcD4iLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFB5X1RZUEUoc2VsZiktPnRwX25hbWUsIHNlbGYpOworfQorCitzdGF0aWMgUHlPYmplY3QgKgorc2xvdF90cF9zdHIoUHlPYmplY3QgKnNlbGYpCit7CisgICAgUHlPYmplY3QgKmZ1bmMsICpyZXM7CisgICAgc3RhdGljIFB5T2JqZWN0ICpzdHJfc3RyOworCisgICAgZnVuYyA9IGxvb2t1cF9tZXRob2Qoc2VsZiwgIl9fc3RyX18iLCAmc3RyX3N0cik7CisgICAgaWYgKGZ1bmMgIT0gTlVMTCkgeworICAgICAgICByZXMgPSBQeUV2YWxfQ2FsbE9iamVjdChmdW5jLCBOVUxMKTsKKyAgICAgICAgUHlfREVDUkVGKGZ1bmMpOworICAgICAgICByZXR1cm4gcmVzOworICAgIH0KKyAgICBlbHNlIHsKKyAgICAgICAgUHlFcnJfQ2xlYXIoKTsKKyAgICAgICAgcmV0dXJuIHNsb3RfdHBfcmVwcihzZWxmKTsKKyAgICB9Cit9CisKK3N0YXRpYyBsb25nCitzbG90X3RwX2hhc2goUHlPYmplY3QgKnNlbGYpCit7CisgICAgUHlPYmplY3QgKmZ1bmM7CisgICAgc3RhdGljIFB5T2JqZWN0ICpoYXNoX3N0ciwgKmVxX3N0ciwgKmNtcF9zdHI7CisgICAgbG9uZyBoOworCisgICAgZnVuYyA9IGxvb2t1cF9tZXRob2Qoc2VsZiwgIl9faGFzaF9fIiwgJmhhc2hfc3RyKTsKKworICAgIGlmIChmdW5jICE9IE5VTEwgJiYgZnVuYyAhPSBQeV9Ob25lKSB7CisgICAgICAgIFB5T2JqZWN0ICpyZXMgPSBQeUV2YWxfQ2FsbE9iamVjdChmdW5jLCBOVUxMKTsKKyAgICAgICAgUHlfREVDUkVGKGZ1bmMpOworICAgICAgICBpZiAocmVzID09IE5VTEwpCisgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgIGlmIChQeUxvbmdfQ2hlY2socmVzKSkKKyAgICAgICAgICAgIGggPSBQeUxvbmdfVHlwZS50cF9oYXNoKHJlcyk7CisgICAgICAgIGVsc2UKKyAgICAgICAgICAgIGggPSBQeUludF9Bc0xvbmcocmVzKTsKKyAgICAgICAgUHlfREVDUkVGKHJlcyk7CisgICAgfQorICAgIGVsc2UgeworICAgICAgICBQeV9YREVDUkVGKGZ1bmMpOyAvKiBtYXkgYmUgTm9uZSAqLworICAgICAgICBQeUVycl9DbGVhcigpOworICAgICAgICBmdW5jID0gbG9va3VwX21ldGhvZChzZWxmLCAiX19lcV9fIiwgJmVxX3N0cik7CisgICAgICAgIGlmIChmdW5jID09IE5VTEwpIHsKKyAgICAgICAgICAgIFB5RXJyX0NsZWFyKCk7CisgICAgICAgICAgICBmdW5jID0gbG9va3VwX21ldGhvZChzZWxmLCAiX19jbXBfXyIsICZjbXBfc3RyKTsKKyAgICAgICAgfQorICAgICAgICBpZiAoZnVuYyAhPSBOVUxMKSB7CisgICAgICAgICAgICBQeV9ERUNSRUYoZnVuYyk7CisgICAgICAgICAgICByZXR1cm4gUHlPYmplY3RfSGFzaE5vdEltcGxlbWVudGVkKHNlbGYpOworICAgICAgICB9CisgICAgICAgIFB5RXJyX0NsZWFyKCk7CisgICAgICAgIGggPSBfUHlfSGFzaFBvaW50ZXIoKHZvaWQgKilzZWxmKTsKKyAgICB9CisgICAgaWYgKGggPT0gLTEgJiYgIVB5RXJyX09jY3VycmVkKCkpCisgICAgICAgIGggPSAtMjsKKyAgICByZXR1cm4gaDsKK30KKworc3RhdGljIFB5T2JqZWN0ICoKK3Nsb3RfdHBfY2FsbChQeU9iamVjdCAqc2VsZiwgUHlPYmplY3QgKmFyZ3MsIFB5T2JqZWN0ICprd2RzKQoreworICAgIHN0YXRpYyBQeU9iamVjdCAqY2FsbF9zdHI7CisgICAgUHlPYmplY3QgKm1ldGggPSBsb29rdXBfbWV0aG9kKHNlbGYsICJfX2NhbGxfXyIsICZjYWxsX3N0cik7CisgICAgUHlPYmplY3QgKnJlczsKKworICAgIGlmIChtZXRoID09IE5VTEwpCisgICAgICAgIHJldHVybiBOVUxMOworCisgICAgcmVzID0gUHlPYmplY3RfQ2FsbChtZXRoLCBhcmdzLCBrd2RzKTsKKworICAgIFB5X0RFQ1JFRihtZXRoKTsKKyAgICByZXR1cm4gcmVzOworfQorCisvKiBUaGVyZSBhcmUgdHdvIHNsb3QgZGlzcGF0Y2ggZnVuY3Rpb25zIGZvciB0cF9nZXRhdHRyby4KKworICAgLSBzbG90X3RwX2dldGF0dHJvKCkgaXMgdXNlZCB3aGVuIF9fZ2V0YXR0cmlidXRlX18gaXMgb3ZlcnJpZGRlbgorICAgICBidXQgbm8gX19nZXRhdHRyX18gaG9vayBpcyBwcmVzZW50OworCisgICAtIHNsb3RfdHBfZ2V0YXR0cl9ob29rKCkgaXMgdXNlZCB3aGVuIGEgX19nZXRhdHRyX18gaG9vayBpcyBwcmVzZW50LgorCisgICBUaGUgY29kZSBpbiB1cGRhdGVfb25lX3Nsb3QoKSBhbHdheXMgaW5zdGFsbHMgc2xvdF90cF9nZXRhdHRyX2hvb2soKTsgdGhpcworICAgZGV0ZWN0cyB0aGUgYWJzZW5jZSBvZiBfX2dldGF0dHJfXyBhbmQgdGhlbiBpbnN0YWxscyB0aGUgc2ltcGxlciBzbG90IGlmCisgICBuZWNlc3NhcnkuICovCisKK3N0YXRpYyBQeU9iamVjdCAqCitzbG90X3RwX2dldGF0dHJvKFB5T2JqZWN0ICpzZWxmLCBQeU9iamVjdCAqbmFtZSkKK3sKKyAgICBzdGF0aWMgUHlPYmplY3QgKmdldGF0dHJpYnV0ZV9zdHIgPSBOVUxMOworICAgIHJldHVybiBjYWxsX21ldGhvZChzZWxmLCAiX19nZXRhdHRyaWJ1dGVfXyIsICZnZXRhdHRyaWJ1dGVfc3RyLAorICAgICAgICAgICAgICAgICAgICAgICAiKE8pIiwgbmFtZSk7Cit9CisKK3N0YXRpYyBQeU9iamVjdCAqCitjYWxsX2F0dHJpYnV0ZShQeU9iamVjdCAqc2VsZiwgUHlPYmplY3QgKmF0dHIsIFB5T2JqZWN0ICpuYW1lKQoreworICAgIFB5T2JqZWN0ICpyZXMsICpkZXNjciA9IE5VTEw7CisgICAgZGVzY3JnZXRmdW5jIGYgPSBQeV9UWVBFKGF0dHIpLT50cF9kZXNjcl9nZXQ7CisKKyAgICBpZiAoZiAhPSBOVUxMKSB7CisgICAgICAgIGRlc2NyID0gZihhdHRyLCBzZWxmLCAoUHlPYmplY3QgKikoUHlfVFlQRShzZWxmKSkpOworICAgICAgICBpZiAoZGVzY3IgPT0gTlVMTCkKKyAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgICAgICBlbHNlCisgICAgICAgICAgICBhdHRyID0gZGVzY3I7CisgICAgfQorICAgIHJlcyA9IFB5T2JqZWN0X0NhbGxGdW5jdGlvbk9iakFyZ3MoYXR0ciwgbmFtZSwgTlVMTCk7CisgICAgUHlfWERFQ1JFRihkZXNjcik7CisgICAgcmV0dXJuIHJlczsKK30KKworc3RhdGljIFB5T2JqZWN0ICoKK3Nsb3RfdHBfZ2V0YXR0cl9ob29rKFB5T2JqZWN0ICpzZWxmLCBQeU9iamVjdCAqbmFtZSkKK3sKKyAgICBQeVR5cGVPYmplY3QgKnRwID0gUHlfVFlQRShzZWxmKTsKKyAgICBQeU9iamVjdCAqZ2V0YXR0ciwgKmdldGF0dHJpYnV0ZSwgKnJlczsKKyAgICBzdGF0aWMgUHlPYmplY3QgKmdldGF0dHJpYnV0ZV9zdHIgPSBOVUxMOworICAgIHN0YXRpYyBQeU9iamVjdCAqZ2V0YXR0cl9zdHIgPSBOVUxMOworCisgICAgaWYgKGdldGF0dHJfc3RyID09IE5VTEwpIHsKKyAgICAgICAgZ2V0YXR0cl9zdHIgPSBQeVN0cmluZ19JbnRlcm5Gcm9tU3RyaW5nKCJfX2dldGF0dHJfXyIpOworICAgICAgICBpZiAoZ2V0YXR0cl9zdHIgPT0gTlVMTCkKKyAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICBpZiAoZ2V0YXR0cmlidXRlX3N0ciA9PSBOVUxMKSB7CisgICAgICAgIGdldGF0dHJpYnV0ZV9zdHIgPQorICAgICAgICAgICAgUHlTdHJpbmdfSW50ZXJuRnJvbVN0cmluZygiX19nZXRhdHRyaWJ1dGVfXyIpOworICAgICAgICBpZiAoZ2V0YXR0cmlidXRlX3N0ciA9PSBOVUxMKQorICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIC8qIHNwZWVkIGhhY2s6IHdlIGNvdWxkIHVzZSBsb29rdXBfbWF5YmUsIGJ1dCB0aGF0IHdvdWxkIHJlc29sdmUgdGhlCisgICAgICAgbWV0aG9kIGZ1bGx5IGZvciBlYWNoIGF0dHJpYnV0ZSBsb29rdXAgZm9yIGNsYXNzZXMgd2l0aAorICAgICAgIF9fZ2V0YXR0cl9fLCBldmVuIHdoZW4gdGhlIGF0dHJpYnV0ZSBpcyBwcmVzZW50LiBTbyB3ZSB1c2UKKyAgICAgICBfUHlUeXBlX0xvb2t1cCBhbmQgY3JlYXRlIHRoZSBtZXRob2Qgb25seSB3aGVuIG5lZWRlZCwgd2l0aAorICAgICAgIGNhbGxfYXR0cmlidXRlLiAqLworICAgIGdldGF0dHIgPSBfUHlUeXBlX0xvb2t1cCh0cCwgZ2V0YXR0cl9zdHIpOworICAgIGlmIChnZXRhdHRyID09IE5VTEwpIHsKKyAgICAgICAgLyogTm8gX19nZXRhdHRyX18gaG9vazogdXNlIGEgc2ltcGxlciBkaXNwYXRjaGVyICovCisgICAgICAgIHRwLT50cF9nZXRhdHRybyA9IHNsb3RfdHBfZ2V0YXR0cm87CisgICAgICAgIHJldHVybiBzbG90X3RwX2dldGF0dHJvKHNlbGYsIG5hbWUpOworICAgIH0KKyAgICBQeV9JTkNSRUYoZ2V0YXR0cik7CisgICAgLyogc3BlZWQgaGFjazogd2UgY291bGQgdXNlIGxvb2t1cF9tYXliZSwgYnV0IHRoYXQgd291bGQgcmVzb2x2ZSB0aGUKKyAgICAgICBtZXRob2QgZnVsbHkgZm9yIGVhY2ggYXR0cmlidXRlIGxvb2t1cCBmb3IgY2xhc3NlcyB3aXRoCisgICAgICAgX19nZXRhdHRyX18sIGV2ZW4gd2hlbiBzZWxmIGhhcyB0aGUgZGVmYXVsdCBfX2dldGF0dHJpYnV0ZV9fCisgICAgICAgbWV0aG9kLiBTbyB3ZSB1c2UgX1B5VHlwZV9Mb29rdXAgYW5kIGNyZWF0ZSB0aGUgbWV0aG9kIG9ubHkgd2hlbgorICAgICAgIG5lZWRlZCwgd2l0aCBjYWxsX2F0dHJpYnV0ZS4gKi8KKyAgICBnZXRhdHRyaWJ1dGUgPSBfUHlUeXBlX0xvb2t1cCh0cCwgZ2V0YXR0cmlidXRlX3N0cik7CisgICAgaWYgKGdldGF0dHJpYnV0ZSA9PSBOVUxMIHx8CisgICAgICAgIChQeV9UWVBFKGdldGF0dHJpYnV0ZSkgPT0gJlB5V3JhcHBlckRlc2NyX1R5cGUgJiYKKyAgICAgICAgICgoUHlXcmFwcGVyRGVzY3JPYmplY3QgKilnZXRhdHRyaWJ1dGUpLT5kX3dyYXBwZWQgPT0KKyAgICAgICAgICh2b2lkICopUHlPYmplY3RfR2VuZXJpY0dldEF0dHIpKQorICAgICAgICByZXMgPSBQeU9iamVjdF9HZW5lcmljR2V0QXR0cihzZWxmLCBuYW1lKTsKKyAgICBlbHNlIHsKKyAgICAgICAgUHlfSU5DUkVGKGdldGF0dHJpYnV0ZSk7CisgICAgICAgIHJlcyA9IGNhbGxfYXR0cmlidXRlKHNlbGYsIGdldGF0dHJpYnV0ZSwgbmFtZSk7CisgICAgICAgIFB5X0RFQ1JFRihnZXRhdHRyaWJ1dGUpOworICAgIH0KKyAgICBpZiAocmVzID09IE5VTEwgJiYgUHlFcnJfRXhjZXB0aW9uTWF0Y2hlcyhQeUV4Y19BdHRyaWJ1dGVFcnJvcikpIHsKKyAgICAgICAgUHlFcnJfQ2xlYXIoKTsKKyAgICAgICAgcmVzID0gY2FsbF9hdHRyaWJ1dGUoc2VsZiwgZ2V0YXR0ciwgbmFtZSk7CisgICAgfQorICAgIFB5X0RFQ1JFRihnZXRhdHRyKTsKKyAgICByZXR1cm4gcmVzOworfQorCitzdGF0aWMgaW50CitzbG90X3RwX3NldGF0dHJvKFB5T2JqZWN0ICpzZWxmLCBQeU9iamVjdCAqbmFtZSwgUHlPYmplY3QgKnZhbHVlKQoreworICAgIFB5T2JqZWN0ICpyZXM7CisgICAgc3RhdGljIFB5T2JqZWN0ICpkZWxhdHRyX3N0ciwgKnNldGF0dHJfc3RyOworCisgICAgaWYgKHZhbHVlID09IE5VTEwpCisgICAgICAgIHJlcyA9IGNhbGxfbWV0aG9kKHNlbGYsICJfX2RlbGF0dHJfXyIsICZkZWxhdHRyX3N0ciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIihPKSIsIG5hbWUpOworICAgIGVsc2UKKyAgICAgICAgcmVzID0gY2FsbF9tZXRob2Qoc2VsZiwgIl9fc2V0YXR0cl9fIiwgJnNldGF0dHJfc3RyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAiKE9PKSIsIG5hbWUsIHZhbHVlKTsKKyAgICBpZiAocmVzID09IE5VTEwpCisgICAgICAgIHJldHVybiAtMTsKKyAgICBQeV9ERUNSRUYocmVzKTsKKyAgICByZXR1cm4gMDsKK30KKworc3RhdGljIGNoYXIgKm5hbWVfb3BbXSA9IHsKKyAgICAiX19sdF9fIiwKKyAgICAiX19sZV9fIiwKKyAgICAiX19lcV9fIiwKKyAgICAiX19uZV9fIiwKKyAgICAiX19ndF9fIiwKKyAgICAiX19nZV9fIiwKK307CisKK3N0YXRpYyBQeU9iamVjdCAqCitoYWxmX3JpY2hjb21wYXJlKFB5T2JqZWN0ICpzZWxmLCBQeU9iamVjdCAqb3RoZXIsIGludCBvcCkKK3sKKyAgICBQeU9iamVjdCAqZnVuYywgKmFyZ3MsICpyZXM7CisgICAgc3RhdGljIFB5T2JqZWN0ICpvcF9zdHJbNl07CisKKyAgICBmdW5jID0gbG9va3VwX21ldGhvZChzZWxmLCBuYW1lX29wW29wXSwgJm9wX3N0cltvcF0pOworICAgIGlmIChmdW5jID09IE5VTEwpIHsKKyAgICAgICAgUHlFcnJfQ2xlYXIoKTsKKyAgICAgICAgUHlfSU5DUkVGKFB5X05vdEltcGxlbWVudGVkKTsKKyAgICAgICAgcmV0dXJuIFB5X05vdEltcGxlbWVudGVkOworICAgIH0KKyAgICBhcmdzID0gUHlUdXBsZV9QYWNrKDEsIG90aGVyKTsKKyAgICBpZiAoYXJncyA9PSBOVUxMKQorICAgICAgICByZXMgPSBOVUxMOworICAgIGVsc2UgeworICAgICAgICByZXMgPSBQeU9iamVjdF9DYWxsKGZ1bmMsIGFyZ3MsIE5VTEwpOworICAgICAgICBQeV9ERUNSRUYoYXJncyk7CisgICAgfQorICAgIFB5X0RFQ1JFRihmdW5jKTsKKyAgICByZXR1cm4gcmVzOworfQorCitzdGF0aWMgUHlPYmplY3QgKgorc2xvdF90cF9yaWNoY29tcGFyZShQeU9iamVjdCAqc2VsZiwgUHlPYmplY3QgKm90aGVyLCBpbnQgb3ApCit7CisgICAgUHlPYmplY3QgKnJlczsKKworICAgIGlmIChQeV9UWVBFKHNlbGYpLT50cF9yaWNoY29tcGFyZSA9PSBzbG90X3RwX3JpY2hjb21wYXJlKSB7CisgICAgICAgIHJlcyA9IGhhbGZfcmljaGNvbXBhcmUoc2VsZiwgb3RoZXIsIG9wKTsKKyAgICAgICAgaWYgKHJlcyAhPSBQeV9Ob3RJbXBsZW1lbnRlZCkKKyAgICAgICAgICAgIHJldHVybiByZXM7CisgICAgICAgIFB5X0RFQ1JFRihyZXMpOworICAgIH0KKyAgICBpZiAoUHlfVFlQRShvdGhlciktPnRwX3JpY2hjb21wYXJlID09IHNsb3RfdHBfcmljaGNvbXBhcmUpIHsKKyAgICAgICAgcmVzID0gaGFsZl9yaWNoY29tcGFyZShvdGhlciwgc2VsZiwgX1B5X1N3YXBwZWRPcFtvcF0pOworICAgICAgICBpZiAocmVzICE9IFB5X05vdEltcGxlbWVudGVkKSB7CisgICAgICAgICAgICByZXR1cm4gcmVzOworICAgICAgICB9CisgICAgICAgIFB5X0RFQ1JFRihyZXMpOworICAgIH0KKyAgICBQeV9JTkNSRUYoUHlfTm90SW1wbGVtZW50ZWQpOworICAgIHJldHVybiBQeV9Ob3RJbXBsZW1lbnRlZDsKK30KKworc3RhdGljIFB5T2JqZWN0ICoKK3Nsb3RfdHBfaXRlcihQeU9iamVjdCAqc2VsZikKK3sKKyAgICBQeU9iamVjdCAqZnVuYywgKnJlczsKKyAgICBzdGF0aWMgUHlPYmplY3QgKml0ZXJfc3RyLCAqZ2V0aXRlbV9zdHI7CisKKyAgICBmdW5jID0gbG9va3VwX21ldGhvZChzZWxmLCAiX19pdGVyX18iLCAmaXRlcl9zdHIpOworICAgIGlmIChmdW5jICE9IE5VTEwpIHsKKyAgICAgICAgUHlPYmplY3QgKmFyZ3M7CisgICAgICAgIGFyZ3MgPSByZXMgPSBQeVR1cGxlX05ldygwKTsKKyAgICAgICAgaWYgKGFyZ3MgIT0gTlVMTCkgeworICAgICAgICAgICAgcmVzID0gUHlPYmplY3RfQ2FsbChmdW5jLCBhcmdzLCBOVUxMKTsKKyAgICAgICAgICAgIFB5X0RFQ1JFRihhcmdzKTsKKyAgICAgICAgfQorICAgICAgICBQeV9ERUNSRUYoZnVuYyk7CisgICAgICAgIHJldHVybiByZXM7CisgICAgfQorICAgIFB5RXJyX0NsZWFyKCk7CisgICAgZnVuYyA9IGxvb2t1cF9tZXRob2Qoc2VsZiwgIl9fZ2V0aXRlbV9fIiwgJmdldGl0ZW1fc3RyKTsKKyAgICBpZiAoZnVuYyA9PSBOVUxMKSB7CisgICAgICAgIFB5RXJyX0Zvcm1hdChQeUV4Y19UeXBlRXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAiJyUuMjAwcycgb2JqZWN0IGlzIG5vdCBpdGVyYWJsZSIsCisgICAgICAgICAgICAgICAgICAgICBQeV9UWVBFKHNlbGYpLT50cF9uYW1lKTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIFB5X0RFQ1JFRihmdW5jKTsKKyAgICByZXR1cm4gUHlTZXFJdGVyX05ldyhzZWxmKTsKK30KKworc3RhdGljIFB5T2JqZWN0ICoKK3Nsb3RfdHBfaXRlcm5leHQoUHlPYmplY3QgKnNlbGYpCit7CisgICAgc3RhdGljIFB5T2JqZWN0ICpuZXh0X3N0cjsKKyAgICByZXR1cm4gY2FsbF9tZXRob2Qoc2VsZiwgIm5leHQiLCAmbmV4dF9zdHIsICIoKSIpOworfQorCitzdGF0aWMgUHlPYmplY3QgKgorc2xvdF90cF9kZXNjcl9nZXQoUHlPYmplY3QgKnNlbGYsIFB5T2JqZWN0ICpvYmosIFB5T2JqZWN0ICp0eXBlKQoreworICAgIFB5VHlwZU9iamVjdCAqdHAgPSBQeV9UWVBFKHNlbGYpOworICAgIFB5T2JqZWN0ICpnZXQ7CisgICAgc3RhdGljIFB5T2JqZWN0ICpnZXRfc3RyID0gTlVMTDsKKworICAgIGlmIChnZXRfc3RyID09IE5VTEwpIHsKKyAgICAgICAgZ2V0X3N0ciA9IFB5U3RyaW5nX0ludGVybkZyb21TdHJpbmcoIl9fZ2V0X18iKTsKKyAgICAgICAgaWYgKGdldF9zdHIgPT0gTlVMTCkKKyAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICBnZXQgPSBfUHlUeXBlX0xvb2t1cCh0cCwgZ2V0X3N0cik7CisgICAgaWYgKGdldCA9PSBOVUxMKSB7CisgICAgICAgIC8qIEF2b2lkIGZ1cnRoZXIgc2xvd2Rvd25zICovCisgICAgICAgIGlmICh0cC0+dHBfZGVzY3JfZ2V0ID09IHNsb3RfdHBfZGVzY3JfZ2V0KQorICAgICAgICAgICAgdHAtPnRwX2Rlc2NyX2dldCA9IE5VTEw7CisgICAgICAgIFB5X0lOQ1JFRihzZWxmKTsKKyAgICAgICAgcmV0dXJuIHNlbGY7CisgICAgfQorICAgIGlmIChvYmogPT0gTlVMTCkKKyAgICAgICAgb2JqID0gUHlfTm9uZTsKKyAgICBpZiAodHlwZSA9PSBOVUxMKQorICAgICAgICB0eXBlID0gUHlfTm9uZTsKKyAgICByZXR1cm4gUHlPYmplY3RfQ2FsbEZ1bmN0aW9uT2JqQXJncyhnZXQsIHNlbGYsIG9iaiwgdHlwZSwgTlVMTCk7Cit9CisKK3N0YXRpYyBpbnQKK3Nsb3RfdHBfZGVzY3Jfc2V0KFB5T2JqZWN0ICpzZWxmLCBQeU9iamVjdCAqdGFyZ2V0LCBQeU9iamVjdCAqdmFsdWUpCit7CisgICAgUHlPYmplY3QgKnJlczsKKyAgICBzdGF0aWMgUHlPYmplY3QgKmRlbF9zdHIsICpzZXRfc3RyOworCisgICAgaWYgKHZhbHVlID09IE5VTEwpCisgICAgICAgIHJlcyA9IGNhbGxfbWV0aG9kKHNlbGYsICJfX2RlbGV0ZV9fIiwgJmRlbF9zdHIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICIoTykiLCB0YXJnZXQpOworICAgIGVsc2UKKyAgICAgICAgcmVzID0gY2FsbF9tZXRob2Qoc2VsZiwgIl9fc2V0X18iLCAmc2V0X3N0ciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIihPTykiLCB0YXJnZXQsIHZhbHVlKTsKKyAgICBpZiAocmVzID09IE5VTEwpCisgICAgICAgIHJldHVybiAtMTsKKyAgICBQeV9ERUNSRUYocmVzKTsKKyAgICByZXR1cm4gMDsKK30KKworc3RhdGljIGludAorc2xvdF90cF9pbml0KFB5T2JqZWN0ICpzZWxmLCBQeU9iamVjdCAqYXJncywgUHlPYmplY3QgKmt3ZHMpCit7CisgICAgc3RhdGljIFB5T2JqZWN0ICppbml0X3N0cjsKKyAgICBQeU9iamVjdCAqbWV0aCA9IGxvb2t1cF9tZXRob2Qoc2VsZiwgIl9faW5pdF9fIiwgJmluaXRfc3RyKTsKKyAgICBQeU9iamVjdCAqcmVzOworCisgICAgaWYgKG1ldGggPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIC0xOworICAgIHJlcyA9IFB5T2JqZWN0X0NhbGwobWV0aCwgYXJncywga3dkcyk7CisgICAgUHlfREVDUkVGKG1ldGgpOworICAgIGlmIChyZXMgPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIC0xOworICAgIGlmIChyZXMgIT0gUHlfTm9uZSkgeworICAgICAgICBQeUVycl9Gb3JtYXQoUHlFeGNfVHlwZUVycm9yLAorICAgICAgICAgICAgICAgICAgICAgIl9faW5pdF9fKCkgc2hvdWxkIHJldHVybiBOb25lLCBub3QgJyUuMjAwcyciLAorICAgICAgICAgICAgICAgICAgICAgUHlfVFlQRShyZXMpLT50cF9uYW1lKTsKKyAgICAgICAgUHlfREVDUkVGKHJlcyk7CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisgICAgUHlfREVDUkVGKHJlcyk7CisgICAgcmV0dXJuIDA7Cit9CisKK3N0YXRpYyBQeU9iamVjdCAqCitzbG90X3RwX25ldyhQeVR5cGVPYmplY3QgKnR5cGUsIFB5T2JqZWN0ICphcmdzLCBQeU9iamVjdCAqa3dkcykKK3sKKyAgICBzdGF0aWMgUHlPYmplY3QgKm5ld19zdHI7CisgICAgUHlPYmplY3QgKmZ1bmM7CisgICAgUHlPYmplY3QgKm5ld2FyZ3MsICp4OworICAgIFB5X3NzaXplX3QgaSwgbjsKKworICAgIGlmIChuZXdfc3RyID09IE5VTEwpIHsKKyAgICAgICAgbmV3X3N0ciA9IFB5U3RyaW5nX0ludGVybkZyb21TdHJpbmcoIl9fbmV3X18iKTsKKyAgICAgICAgaWYgKG5ld19zdHIgPT0gTlVMTCkKKyAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICBmdW5jID0gUHlPYmplY3RfR2V0QXR0cigoUHlPYmplY3QgKil0eXBlLCBuZXdfc3RyKTsKKyAgICBpZiAoZnVuYyA9PSBOVUxMKQorICAgICAgICByZXR1cm4gTlVMTDsKKyAgICBhc3NlcnQoUHlUdXBsZV9DaGVjayhhcmdzKSk7CisgICAgbiA9IFB5VHVwbGVfR0VUX1NJWkUoYXJncyk7CisgICAgbmV3YXJncyA9IFB5VHVwbGVfTmV3KG4rMSk7CisgICAgaWYgKG5ld2FyZ3MgPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgUHlfSU5DUkVGKHR5cGUpOworICAgIFB5VHVwbGVfU0VUX0lURU0obmV3YXJncywgMCwgKFB5T2JqZWN0ICopdHlwZSk7CisgICAgZm9yIChpID0gMDsgaSA8IG47IGkrKykgeworICAgICAgICB4ID0gUHlUdXBsZV9HRVRfSVRFTShhcmdzLCBpKTsKKyAgICAgICAgUHlfSU5DUkVGKHgpOworICAgICAgICBQeVR1cGxlX1NFVF9JVEVNKG5ld2FyZ3MsIGkrMSwgeCk7CisgICAgfQorICAgIHggPSBQeU9iamVjdF9DYWxsKGZ1bmMsIG5ld2FyZ3MsIGt3ZHMpOworICAgIFB5X0RFQ1JFRihuZXdhcmdzKTsKKyAgICBQeV9ERUNSRUYoZnVuYyk7CisgICAgcmV0dXJuIHg7Cit9CisKK3N0YXRpYyB2b2lkCitzbG90X3RwX2RlbChQeU9iamVjdCAqc2VsZikKK3sKKyAgICBzdGF0aWMgUHlPYmplY3QgKmRlbF9zdHIgPSBOVUxMOworICAgIFB5T2JqZWN0ICpkZWwsICpyZXM7CisgICAgUHlPYmplY3QgKmVycm9yX3R5cGUsICplcnJvcl92YWx1ZSwgKmVycm9yX3RyYWNlYmFjazsKKworICAgIC8qIFRlbXBvcmFyaWx5IHJlc3VycmVjdCB0aGUgb2JqZWN0LiAqLworICAgIGFzc2VydChzZWxmLT5vYl9yZWZjbnQgPT0gMCk7CisgICAgc2VsZi0+b2JfcmVmY250ID0gMTsKKworICAgIC8qIFNhdmUgdGhlIGN1cnJlbnQgZXhjZXB0aW9uLCBpZiBhbnkuICovCisgICAgUHlFcnJfRmV0Y2goJmVycm9yX3R5cGUsICZlcnJvcl92YWx1ZSwgJmVycm9yX3RyYWNlYmFjayk7CisKKyAgICAvKiBFeGVjdXRlIF9fZGVsX18gbWV0aG9kLCBpZiBhbnkuICovCisgICAgZGVsID0gbG9va3VwX21heWJlKHNlbGYsICJfX2RlbF9fIiwgJmRlbF9zdHIpOworICAgIGlmIChkZWwgIT0gTlVMTCkgeworICAgICAgICByZXMgPSBQeUV2YWxfQ2FsbE9iamVjdChkZWwsIE5VTEwpOworICAgICAgICBpZiAocmVzID09IE5VTEwpCisgICAgICAgICAgICBQeUVycl9Xcml0ZVVucmFpc2FibGUoZGVsKTsKKyAgICAgICAgZWxzZQorICAgICAgICAgICAgUHlfREVDUkVGKHJlcyk7CisgICAgICAgIFB5X0RFQ1JFRihkZWwpOworICAgIH0KKworICAgIC8qIFJlc3RvcmUgdGhlIHNhdmVkIGV4Y2VwdGlvbi4gKi8KKyAgICBQeUVycl9SZXN0b3JlKGVycm9yX3R5cGUsIGVycm9yX3ZhbHVlLCBlcnJvcl90cmFjZWJhY2spOworCisgICAgLyogVW5kbyB0aGUgdGVtcG9yYXJ5IHJlc3VycmVjdGlvbjsgY2FuJ3QgdXNlIERFQ1JFRiBoZXJlLCBpdCB3b3VsZAorICAgICAqIGNhdXNlIGEgcmVjdXJzaXZlIGNhbGwuCisgICAgICovCisgICAgYXNzZXJ0KHNlbGYtPm9iX3JlZmNudCA+IDApOworICAgIGlmICgtLXNlbGYtPm9iX3JlZmNudCA9PSAwKQorICAgICAgICByZXR1cm47ICAgICAgICAgLyogdGhpcyBpcyB0aGUgbm9ybWFsIHBhdGggb3V0ICovCisKKyAgICAvKiBfX2RlbF9fIHJlc3VycmVjdGVkIGl0ISAgTWFrZSBpdCBsb29rIGxpa2UgdGhlIG9yaWdpbmFsIFB5X0RFQ1JFRgorICAgICAqIG5ldmVyIGhhcHBlbmVkLgorICAgICAqLworICAgIHsKKyAgICAgICAgUHlfc3NpemVfdCByZWZjbnQgPSBzZWxmLT5vYl9yZWZjbnQ7CisgICAgICAgIF9QeV9OZXdSZWZlcmVuY2Uoc2VsZik7CisgICAgICAgIHNlbGYtPm9iX3JlZmNudCA9IHJlZmNudDsKKyAgICB9CisgICAgYXNzZXJ0KCFQeVR5cGVfSVNfR0MoUHlfVFlQRShzZWxmKSkgfHwKKyAgICAgICAgICAgX1B5X0FTX0dDKHNlbGYpLT5nYy5nY19yZWZzICE9IF9QeUdDX1JFRlNfVU5UUkFDS0VEKTsKKyAgICAvKiBJZiBQeV9SRUZfREVCVUcsIF9QeV9OZXdSZWZlcmVuY2UgYnVtcGVkIF9QeV9SZWZUb3RhbCwgc28KKyAgICAgKiB3ZSBuZWVkIHRvIHVuZG8gdGhhdC4gKi8KKyAgICBfUHlfREVDX1JFRlRPVEFMOworICAgIC8qIElmIFB5X1RSQUNFX1JFRlMsIF9QeV9OZXdSZWZlcmVuY2UgcmUtYWRkZWQgc2VsZiB0byB0aGUgb2JqZWN0CisgICAgICogY2hhaW4sIHNvIG5vIG1vcmUgdG8gZG8gdGhlcmUuCisgICAgICogSWYgQ09VTlRfQUxMT0NTLCB0aGUgb3JpZ2luYWwgZGVjcmVmIGJ1bXBlZCB0cF9mcmVlcywgYW5kCisgICAgICogX1B5X05ld1JlZmVyZW5jZSBidW1wZWQgdHBfYWxsb2NzOiAgYm90aCBvZiB0aG9zZSBuZWVkIHRvIGJlCisgICAgICogdW5kb25lLgorICAgICAqLworI2lmZGVmIENPVU5UX0FMTE9DUworICAgIC0tUHlfVFlQRShzZWxmKS0+dHBfZnJlZXM7CisgICAgLS1QeV9UWVBFKHNlbGYpLT50cF9hbGxvY3M7CisjZW5kaWYKK30KKworCisvKgorVGFibGUgbWFwcGluZyBfX2Zvb19fIG5hbWVzIHRvIHRwX2ZvbyBvZmZzZXRzIGFuZCBzbG90X3RwX2ZvbyB3cmFwcGVyIGZ1bmN0aW9ucy4KKworVGhlIHRhYmxlIGlzIG9yZGVyZWQgYnkgb2Zmc2V0cyByZWxhdGl2ZSB0byB0aGUgJ1B5SGVhcFR5cGVPYmplY3QnIHN0cnVjdHVyZSwKK3doaWNoIGluY29ycG9yYXRlcyB0aGUgYWRkaXRpb25hbCBzdHJ1Y3R1cmVzIHVzZWQgZm9yIG51bWJlcnMsIHNlcXVlbmNlcyBhbmQKK21hcHBpbmdzLiAgTm90ZSB0aGF0IG11bHRpcGxlIG5hbWVzIG1heSBtYXAgdG8gdGhlIHNhbWUgc2xvdCAoZS5nLiBfX2VxX18sCitfX25lX18gZXRjLiBhbGwgbWFwIHRvIHRwX3JpY2hjb21wYXJlKSBhbmQgb25lIG5hbWUgbWF5IG1hcCB0byBtdWx0aXBsZSBzbG90cworKGUuZy4gX19zdHJfXyBhZmZlY3RzIHRwX3N0ciBhcyB3ZWxsIGFzIHRwX3JlcHIpLiBUaGUgdGFibGUgaXMgdGVybWluYXRlZCB3aXRoCithbiBhbGwtemVybyBlbnRyeS4gIChUaGlzIHRhYmxlIGlzIGZ1cnRoZXIgaW5pdGlhbGl6ZWQgaW4gaW5pdF9zbG90ZGVmcygpLikKKyovCisKK3R5cGVkZWYgc3RydWN0IHdyYXBwZXJiYXNlIHNsb3RkZWY7CisKKyN1bmRlZiBUUFNMT1QKKyN1bmRlZiBGTFNMT1QKKyN1bmRlZiBFVFNMT1QKKyN1bmRlZiBTUVNMT1QKKyN1bmRlZiBNUFNMT1QKKyN1bmRlZiBOQlNMT1QKKyN1bmRlZiBVTlNMT1QKKyN1bmRlZiBJQlNMT1QKKyN1bmRlZiBCSU5TTE9UCisjdW5kZWYgUkJJTlNMT1QKKworI2RlZmluZSBUUFNMT1QoTkFNRSwgU0xPVCwgRlVOQ1RJT04sIFdSQVBQRVIsIERPQykgXAorICAgIHtOQU1FLCBvZmZzZXRvZihQeVR5cGVPYmplY3QsIFNMT1QpLCAodm9pZCAqKShGVU5DVElPTiksIFdSQVBQRVIsIFwKKyAgICAgUHlEb2NfU1RSKERPQyl9CisjZGVmaW5lIEZMU0xPVChOQU1FLCBTTE9ULCBGVU5DVElPTiwgV1JBUFBFUiwgRE9DLCBGTEFHUykgXAorICAgIHtOQU1FLCBvZmZzZXRvZihQeVR5cGVPYmplY3QsIFNMT1QpLCAodm9pZCAqKShGVU5DVElPTiksIFdSQVBQRVIsIFwKKyAgICAgUHlEb2NfU1RSKERPQyksIEZMQUdTfQorI2RlZmluZSBFVFNMT1QoTkFNRSwgU0xPVCwgRlVOQ1RJT04sIFdSQVBQRVIsIERPQykgXAorICAgIHtOQU1FLCBvZmZzZXRvZihQeUhlYXBUeXBlT2JqZWN0LCBTTE9UKSwgKHZvaWQgKikoRlVOQ1RJT04pLCBXUkFQUEVSLCBcCisgICAgIFB5RG9jX1NUUihET0MpfQorI2RlZmluZSBTUVNMT1QoTkFNRSwgU0xPVCwgRlVOQ1RJT04sIFdSQVBQRVIsIERPQykgXAorICAgIEVUU0xPVChOQU1FLCBhc19zZXF1ZW5jZS5TTE9ULCBGVU5DVElPTiwgV1JBUFBFUiwgRE9DKQorI2RlZmluZSBNUFNMT1QoTkFNRSwgU0xPVCwgRlVOQ1RJT04sIFdSQVBQRVIsIERPQykgXAorICAgIEVUU0xPVChOQU1FLCBhc19tYXBwaW5nLlNMT1QsIEZVTkNUSU9OLCBXUkFQUEVSLCBET0MpCisjZGVmaW5lIE5CU0xPVChOQU1FLCBTTE9ULCBGVU5DVElPTiwgV1JBUFBFUiwgRE9DKSBcCisgICAgRVRTTE9UKE5BTUUsIGFzX251bWJlci5TTE9ULCBGVU5DVElPTiwgV1JBUFBFUiwgRE9DKQorI2RlZmluZSBVTlNMT1QoTkFNRSwgU0xPVCwgRlVOQ1RJT04sIFdSQVBQRVIsIERPQykgXAorICAgIEVUU0xPVChOQU1FLCBhc19udW1iZXIuU0xPVCwgRlVOQ1RJT04sIFdSQVBQRVIsIFwKKyAgICAgICAgICAgInguIiBOQU1FICIoKSA8PT0+ICIgRE9DKQorI2RlZmluZSBJQlNMT1QoTkFNRSwgU0xPVCwgRlVOQ1RJT04sIFdSQVBQRVIsIERPQykgXAorICAgIEVUU0xPVChOQU1FLCBhc19udW1iZXIuU0xPVCwgRlVOQ1RJT04sIFdSQVBQRVIsIFwKKyAgICAgICAgICAgInguIiBOQU1FICIoeSkgPD09PiB4IiBET0MgInkiKQorI2RlZmluZSBCSU5TTE9UKE5BTUUsIFNMT1QsIEZVTkNUSU9OLCBET0MpIFwKKyAgICBFVFNMT1QoTkFNRSwgYXNfbnVtYmVyLlNMT1QsIEZVTkNUSU9OLCB3cmFwX2JpbmFyeWZ1bmNfbCwgXAorICAgICAgICAgICAieC4iIE5BTUUgIih5KSA8PT0+IHgiIERPQyAieSIpCisjZGVmaW5lIFJCSU5TTE9UKE5BTUUsIFNMT1QsIEZVTkNUSU9OLCBET0MpIFwKKyAgICBFVFNMT1QoTkFNRSwgYXNfbnVtYmVyLlNMT1QsIEZVTkNUSU9OLCB3cmFwX2JpbmFyeWZ1bmNfciwgXAorICAgICAgICAgICAieC4iIE5BTUUgIih5KSA8PT0+IHkiIERPQyAieCIpCisjZGVmaW5lIEJJTlNMT1ROT1RJTkZJWChOQU1FLCBTTE9ULCBGVU5DVElPTiwgRE9DKSBcCisgICAgRVRTTE9UKE5BTUUsIGFzX251bWJlci5TTE9ULCBGVU5DVElPTiwgd3JhcF9iaW5hcnlmdW5jX2wsIFwKKyAgICAgICAgICAgInguIiBOQU1FICIoeSkgPD09PiAiIERPQykKKyNkZWZpbmUgUkJJTlNMT1ROT1RJTkZJWChOQU1FLCBTTE9ULCBGVU5DVElPTiwgRE9DKSBcCisgICAgRVRTTE9UKE5BTUUsIGFzX251bWJlci5TTE9ULCBGVU5DVElPTiwgd3JhcF9iaW5hcnlmdW5jX3IsIFwKKyAgICAgICAgICAgInguIiBOQU1FICIoeSkgPD09PiAiIERPQykKKworc3RhdGljIHNsb3RkZWYgc2xvdGRlZnNbXSA9IHsKKyAgICBUUFNMT1QoIl9fc3RyX18iLCB0cF9wcmludCwgTlVMTCwgTlVMTCwgIiIpLAorICAgIFRQU0xPVCgiX19yZXByX18iLCB0cF9wcmludCwgTlVMTCwgTlVMTCwgIiIpLAorICAgIFRQU0xPVCgiX19nZXRhdHRyaWJ1dGVfXyIsIHRwX2dldGF0dHIsIE5VTEwsIE5VTEwsICIiKSwKKyAgICBUUFNMT1QoIl9fZ2V0YXR0cl9fIiwgdHBfZ2V0YXR0ciwgTlVMTCwgTlVMTCwgIiIpLAorICAgIFRQU0xPVCgiX19zZXRhdHRyX18iLCB0cF9zZXRhdHRyLCBOVUxMLCBOVUxMLCAiIiksCisgICAgVFBTTE9UKCJfX2RlbGF0dHJfXyIsIHRwX3NldGF0dHIsIE5VTEwsIE5VTEwsICIiKSwKKyAgICBUUFNMT1QoIl9fY21wX18iLCB0cF9jb21wYXJlLCBfUHlPYmplY3RfU2xvdENvbXBhcmUsIHdyYXBfY21wZnVuYywKKyAgICAgICAgICAgInguX19jbXBfXyh5KSA8PT0+IGNtcCh4LHkpIiksCisgICAgVFBTTE9UKCJfX3JlcHJfXyIsIHRwX3JlcHIsIHNsb3RfdHBfcmVwciwgd3JhcF91bmFyeWZ1bmMsCisgICAgICAgICAgICJ4Ll9fcmVwcl9fKCkgPD09PiByZXByKHgpIiksCisgICAgVFBTTE9UKCJfX2hhc2hfXyIsIHRwX2hhc2gsIHNsb3RfdHBfaGFzaCwgd3JhcF9oYXNoZnVuYywKKyAgICAgICAgICAgInguX19oYXNoX18oKSA8PT0+IGhhc2goeCkiKSwKKyAgICBGTFNMT1QoIl9fY2FsbF9fIiwgdHBfY2FsbCwgc2xvdF90cF9jYWxsLCAod3JhcHBlcmZ1bmMpd3JhcF9jYWxsLAorICAgICAgICAgICAieC5fX2NhbGxfXyguLi4pIDw9PT4geCguLi4pIiwgUHlXcmFwcGVyRmxhZ19LRVlXT1JEUyksCisgICAgVFBTTE9UKCJfX3N0cl9fIiwgdHBfc3RyLCBzbG90X3RwX3N0ciwgd3JhcF91bmFyeWZ1bmMsCisgICAgICAgICAgICJ4Ll9fc3RyX18oKSA8PT0+IHN0cih4KSIpLAorICAgIFRQU0xPVCgiX19nZXRhdHRyaWJ1dGVfXyIsIHRwX2dldGF0dHJvLCBzbG90X3RwX2dldGF0dHJfaG9vaywKKyAgICAgICAgICAgd3JhcF9iaW5hcnlmdW5jLCAieC5fX2dldGF0dHJpYnV0ZV9fKCduYW1lJykgPD09PiB4Lm5hbWUiKSwKKyAgICBUUFNMT1QoIl9fZ2V0YXR0cl9fIiwgdHBfZ2V0YXR0cm8sIHNsb3RfdHBfZ2V0YXR0cl9ob29rLCBOVUxMLCAiIiksCisgICAgVFBTTE9UKCJfX3NldGF0dHJfXyIsIHRwX3NldGF0dHJvLCBzbG90X3RwX3NldGF0dHJvLCB3cmFwX3NldGF0dHIsCisgICAgICAgICAgICJ4Ll9fc2V0YXR0cl9fKCduYW1lJywgdmFsdWUpIDw9PT4geC5uYW1lID0gdmFsdWUiKSwKKyAgICBUUFNMT1QoIl9fZGVsYXR0cl9fIiwgdHBfc2V0YXR0cm8sIHNsb3RfdHBfc2V0YXR0cm8sIHdyYXBfZGVsYXR0ciwKKyAgICAgICAgICAgInguX19kZWxhdHRyX18oJ25hbWUnKSA8PT0+IGRlbCB4Lm5hbWUiKSwKKyAgICBUUFNMT1QoIl9fbHRfXyIsIHRwX3JpY2hjb21wYXJlLCBzbG90X3RwX3JpY2hjb21wYXJlLCByaWNoY21wX2x0LAorICAgICAgICAgICAieC5fX2x0X18oeSkgPD09PiB4PHkiKSwKKyAgICBUUFNMT1QoIl9fbGVfXyIsIHRwX3JpY2hjb21wYXJlLCBzbG90X3RwX3JpY2hjb21wYXJlLCByaWNoY21wX2xlLAorICAgICAgICAgICAieC5fX2xlX18oeSkgPD09PiB4PD15IiksCisgICAgVFBTTE9UKCJfX2VxX18iLCB0cF9yaWNoY29tcGFyZSwgc2xvdF90cF9yaWNoY29tcGFyZSwgcmljaGNtcF9lcSwKKyAgICAgICAgICAgInguX19lcV9fKHkpIDw9PT4geD09eSIpLAorICAgIFRQU0xPVCgiX19uZV9fIiwgdHBfcmljaGNvbXBhcmUsIHNsb3RfdHBfcmljaGNvbXBhcmUsIHJpY2hjbXBfbmUsCisgICAgICAgICAgICJ4Ll9fbmVfXyh5KSA8PT0+IHghPXkiKSwKKyAgICBUUFNMT1QoIl9fZ3RfXyIsIHRwX3JpY2hjb21wYXJlLCBzbG90X3RwX3JpY2hjb21wYXJlLCByaWNoY21wX2d0LAorICAgICAgICAgICAieC5fX2d0X18oeSkgPD09PiB4PnkiKSwKKyAgICBUUFNMT1QoIl9fZ2VfXyIsIHRwX3JpY2hjb21wYXJlLCBzbG90X3RwX3JpY2hjb21wYXJlLCByaWNoY21wX2dlLAorICAgICAgICAgICAieC5fX2dlX18oeSkgPD09PiB4Pj15IiksCisgICAgVFBTTE9UKCJfX2l0ZXJfXyIsIHRwX2l0ZXIsIHNsb3RfdHBfaXRlciwgd3JhcF91bmFyeWZ1bmMsCisgICAgICAgICAgICJ4Ll9faXRlcl9fKCkgPD09PiBpdGVyKHgpIiksCisgICAgVFBTTE9UKCJuZXh0IiwgdHBfaXRlcm5leHQsIHNsb3RfdHBfaXRlcm5leHQsIHdyYXBfbmV4dCwKKyAgICAgICAgICAgIngubmV4dCgpIC0+IHRoZSBuZXh0IHZhbHVlLCBvciByYWlzZSBTdG9wSXRlcmF0aW9uIiksCisgICAgVFBTTE9UKCJfX2dldF9fIiwgdHBfZGVzY3JfZ2V0LCBzbG90X3RwX2Rlc2NyX2dldCwgd3JhcF9kZXNjcl9nZXQsCisgICAgICAgICAgICJkZXNjci5fX2dldF9fKG9ialssIHR5cGVdKSAtPiB2YWx1ZSIpLAorICAgIFRQU0xPVCgiX19zZXRfXyIsIHRwX2Rlc2NyX3NldCwgc2xvdF90cF9kZXNjcl9zZXQsIHdyYXBfZGVzY3Jfc2V0LAorICAgICAgICAgICAiZGVzY3IuX19zZXRfXyhvYmosIHZhbHVlKSIpLAorICAgIFRQU0xPVCgiX19kZWxldGVfXyIsIHRwX2Rlc2NyX3NldCwgc2xvdF90cF9kZXNjcl9zZXQsCisgICAgICAgICAgIHdyYXBfZGVzY3JfZGVsZXRlLCAiZGVzY3IuX19kZWxldGVfXyhvYmopIiksCisgICAgRkxTTE9UKCJfX2luaXRfXyIsIHRwX2luaXQsIHNsb3RfdHBfaW5pdCwgKHdyYXBwZXJmdW5jKXdyYXBfaW5pdCwKKyAgICAgICAgICAgInguX19pbml0X18oLi4uKSBpbml0aWFsaXplcyB4OyAiCisgICAgICAgICAgICJzZWUgaGVscCh0eXBlKHgpKSBmb3Igc2lnbmF0dXJlIiwKKyAgICAgICAgICAgUHlXcmFwcGVyRmxhZ19LRVlXT1JEUyksCisgICAgVFBTTE9UKCJfX25ld19fIiwgdHBfbmV3LCBzbG90X3RwX25ldywgTlVMTCwgIiIpLAorICAgIFRQU0xPVCgiX19kZWxfXyIsIHRwX2RlbCwgc2xvdF90cF9kZWwsIE5VTEwsICIiKSwKKyAgICBCSU5TTE9UKCJfX2FkZF9fIiwgbmJfYWRkLCBzbG90X25iX2FkZCwKKyAgICAgICAgIisiKSwKKyAgICBSQklOU0xPVCgiX19yYWRkX18iLCBuYl9hZGQsIHNsb3RfbmJfYWRkLAorICAgICAgICAgICAgICIrIiksCisgICAgQklOU0xPVCgiX19zdWJfXyIsIG5iX3N1YnRyYWN0LCBzbG90X25iX3N1YnRyYWN0LAorICAgICAgICAiLSIpLAorICAgIFJCSU5TTE9UKCJfX3JzdWJfXyIsIG5iX3N1YnRyYWN0LCBzbG90X25iX3N1YnRyYWN0LAorICAgICAgICAgICAgICItIiksCisgICAgQklOU0xPVCgiX19tdWxfXyIsIG5iX211bHRpcGx5LCBzbG90X25iX211bHRpcGx5LAorICAgICAgICAiKiIpLAorICAgIFJCSU5TTE9UKCJfX3JtdWxfXyIsIG5iX211bHRpcGx5LCBzbG90X25iX211bHRpcGx5LAorICAgICAgICAgICAgICIqIiksCisgICAgQklOU0xPVCgiX19kaXZfXyIsIG5iX2RpdmlkZSwgc2xvdF9uYl9kaXZpZGUsCisgICAgICAgICIvIiksCisgICAgUkJJTlNMT1QoIl9fcmRpdl9fIiwgbmJfZGl2aWRlLCBzbG90X25iX2RpdmlkZSwKKyAgICAgICAgICAgICAiLyIpLAorICAgIEJJTlNMT1QoIl9fbW9kX18iLCBuYl9yZW1haW5kZXIsIHNsb3RfbmJfcmVtYWluZGVyLAorICAgICAgICAiJSIpLAorICAgIFJCSU5TTE9UKCJfX3Jtb2RfXyIsIG5iX3JlbWFpbmRlciwgc2xvdF9uYl9yZW1haW5kZXIsCisgICAgICAgICAgICAgIiUiKSwKKyAgICBCSU5TTE9UTk9USU5GSVgoIl9fZGl2bW9kX18iLCBuYl9kaXZtb2QsIHNsb3RfbmJfZGl2bW9kLAorICAgICAgICAiZGl2bW9kKHgsIHkpIiksCisgICAgUkJJTlNMT1ROT1RJTkZJWCgiX19yZGl2bW9kX18iLCBuYl9kaXZtb2QsIHNsb3RfbmJfZGl2bW9kLAorICAgICAgICAgICAgICJkaXZtb2QoeSwgeCkiKSwKKyAgICBOQlNMT1QoIl9fcG93X18iLCBuYl9wb3dlciwgc2xvdF9uYl9wb3dlciwgd3JhcF90ZXJuYXJ5ZnVuYywKKyAgICAgICAgICAgInguX19wb3dfXyh5Wywgel0pIDw9PT4gcG93KHgsIHlbLCB6XSkiKSwKKyAgICBOQlNMT1QoIl9fcnBvd19fIiwgbmJfcG93ZXIsIHNsb3RfbmJfcG93ZXIsIHdyYXBfdGVybmFyeWZ1bmNfciwKKyAgICAgICAgICAgInkuX19ycG93X18oeFssIHpdKSA8PT0+IHBvdyh4LCB5Wywgel0pIiksCisgICAgVU5TTE9UKCJfX25lZ19fIiwgbmJfbmVnYXRpdmUsIHNsb3RfbmJfbmVnYXRpdmUsIHdyYXBfdW5hcnlmdW5jLCAiLXgiKSwKKyAgICBVTlNMT1QoIl9fcG9zX18iLCBuYl9wb3NpdGl2ZSwgc2xvdF9uYl9wb3NpdGl2ZSwgd3JhcF91bmFyeWZ1bmMsICIreCIpLAorICAgIFVOU0xPVCgiX19hYnNfXyIsIG5iX2Fic29sdXRlLCBzbG90X25iX2Fic29sdXRlLCB3cmFwX3VuYXJ5ZnVuYywKKyAgICAgICAgICAgImFicyh4KSIpLAorICAgIFVOU0xPVCgiX19ub256ZXJvX18iLCBuYl9ub256ZXJvLCBzbG90X25iX25vbnplcm8sIHdyYXBfaW5xdWlyeXByZWQsCisgICAgICAgICAgICJ4ICE9IDAiKSwKKyAgICBVTlNMT1QoIl9faW52ZXJ0X18iLCBuYl9pbnZlcnQsIHNsb3RfbmJfaW52ZXJ0LCB3cmFwX3VuYXJ5ZnVuYywgIn54IiksCisgICAgQklOU0xPVCgiX19sc2hpZnRfXyIsIG5iX2xzaGlmdCwgc2xvdF9uYl9sc2hpZnQsICI8PCIpLAorICAgIFJCSU5TTE9UKCJfX3Jsc2hpZnRfXyIsIG5iX2xzaGlmdCwgc2xvdF9uYl9sc2hpZnQsICI8PCIpLAorICAgIEJJTlNMT1QoIl9fcnNoaWZ0X18iLCBuYl9yc2hpZnQsIHNsb3RfbmJfcnNoaWZ0LCAiPj4iKSwKKyAgICBSQklOU0xPVCgiX19ycnNoaWZ0X18iLCBuYl9yc2hpZnQsIHNsb3RfbmJfcnNoaWZ0LCAiPj4iKSwKKyAgICBCSU5TTE9UKCJfX2FuZF9fIiwgbmJfYW5kLCBzbG90X25iX2FuZCwgIiYiKSwKKyAgICBSQklOU0xPVCgiX19yYW5kX18iLCBuYl9hbmQsIHNsb3RfbmJfYW5kLCAiJiIpLAorICAgIEJJTlNMT1QoIl9feG9yX18iLCBuYl94b3IsIHNsb3RfbmJfeG9yLCAiXiIpLAorICAgIFJCSU5TTE9UKCJfX3J4b3JfXyIsIG5iX3hvciwgc2xvdF9uYl94b3IsICJeIiksCisgICAgQklOU0xPVCgiX19vcl9fIiwgbmJfb3IsIHNsb3RfbmJfb3IsICJ8IiksCisgICAgUkJJTlNMT1QoIl9fcm9yX18iLCBuYl9vciwgc2xvdF9uYl9vciwgInwiKSwKKyAgICBOQlNMT1QoIl9fY29lcmNlX18iLCBuYl9jb2VyY2UsIHNsb3RfbmJfY29lcmNlLCB3cmFwX2NvZXJjZWZ1bmMsCisgICAgICAgICAgICJ4Ll9fY29lcmNlX18oeSkgPD09PiBjb2VyY2UoeCwgeSkiKSwKKyAgICBVTlNMT1QoIl9faW50X18iLCBuYl9pbnQsIHNsb3RfbmJfaW50LCB3cmFwX3VuYXJ5ZnVuYywKKyAgICAgICAgICAgImludCh4KSIpLAorICAgIFVOU0xPVCgiX19sb25nX18iLCBuYl9sb25nLCBzbG90X25iX2xvbmcsIHdyYXBfdW5hcnlmdW5jLAorICAgICAgICAgICAibG9uZyh4KSIpLAorICAgIFVOU0xPVCgiX19mbG9hdF9fIiwgbmJfZmxvYXQsIHNsb3RfbmJfZmxvYXQsIHdyYXBfdW5hcnlmdW5jLAorICAgICAgICAgICAiZmxvYXQoeCkiKSwKKyAgICBVTlNMT1QoIl9fb2N0X18iLCBuYl9vY3QsIHNsb3RfbmJfb2N0LCB3cmFwX3VuYXJ5ZnVuYywKKyAgICAgICAgICAgIm9jdCh4KSIpLAorICAgIFVOU0xPVCgiX19oZXhfXyIsIG5iX2hleCwgc2xvdF9uYl9oZXgsIHdyYXBfdW5hcnlmdW5jLAorICAgICAgICAgICAiaGV4KHgpIiksCisgICAgSUJTTE9UKCJfX2lhZGRfXyIsIG5iX2lucGxhY2VfYWRkLCBzbG90X25iX2lucGxhY2VfYWRkLAorICAgICAgICAgICB3cmFwX2JpbmFyeWZ1bmMsICIrPSIpLAorICAgIElCU0xPVCgiX19pc3ViX18iLCBuYl9pbnBsYWNlX3N1YnRyYWN0LCBzbG90X25iX2lucGxhY2Vfc3VidHJhY3QsCisgICAgICAgICAgIHdyYXBfYmluYXJ5ZnVuYywgIi09IiksCisgICAgSUJTTE9UKCJfX2ltdWxfXyIsIG5iX2lucGxhY2VfbXVsdGlwbHksIHNsb3RfbmJfaW5wbGFjZV9tdWx0aXBseSwKKyAgICAgICAgICAgd3JhcF9iaW5hcnlmdW5jLCAiKj0iKSwKKyAgICBJQlNMT1QoIl9faWRpdl9fIiwgbmJfaW5wbGFjZV9kaXZpZGUsIHNsb3RfbmJfaW5wbGFjZV9kaXZpZGUsCisgICAgICAgICAgIHdyYXBfYmluYXJ5ZnVuYywgIi89IiksCisgICAgSUJTTE9UKCJfX2ltb2RfXyIsIG5iX2lucGxhY2VfcmVtYWluZGVyLCBzbG90X25iX2lucGxhY2VfcmVtYWluZGVyLAorICAgICAgICAgICB3cmFwX2JpbmFyeWZ1bmMsICIlPSIpLAorICAgIElCU0xPVCgiX19pcG93X18iLCBuYl9pbnBsYWNlX3Bvd2VyLCBzbG90X25iX2lucGxhY2VfcG93ZXIsCisgICAgICAgICAgIHdyYXBfYmluYXJ5ZnVuYywgIioqPSIpLAorICAgIElCU0xPVCgiX19pbHNoaWZ0X18iLCBuYl9pbnBsYWNlX2xzaGlmdCwgc2xvdF9uYl9pbnBsYWNlX2xzaGlmdCwKKyAgICAgICAgICAgd3JhcF9iaW5hcnlmdW5jLCAiPDw9IiksCisgICAgSUJTTE9UKCJfX2lyc2hpZnRfXyIsIG5iX2lucGxhY2VfcnNoaWZ0LCBzbG90X25iX2lucGxhY2VfcnNoaWZ0LAorICAgICAgICAgICB3cmFwX2JpbmFyeWZ1bmMsICI+Pj0iKSwKKyAgICBJQlNMT1QoIl9faWFuZF9fIiwgbmJfaW5wbGFjZV9hbmQsIHNsb3RfbmJfaW5wbGFjZV9hbmQsCisgICAgICAgICAgIHdyYXBfYmluYXJ5ZnVuYywgIiY9IiksCisgICAgSUJTTE9UKCJfX2l4b3JfXyIsIG5iX2lucGxhY2VfeG9yLCBzbG90X25iX2lucGxhY2VfeG9yLAorICAgICAgICAgICB3cmFwX2JpbmFyeWZ1bmMsICJePSIpLAorICAgIElCU0xPVCgiX19pb3JfXyIsIG5iX2lucGxhY2Vfb3IsIHNsb3RfbmJfaW5wbGFjZV9vciwKKyAgICAgICAgICAgd3JhcF9iaW5hcnlmdW5jLCAifD0iKSwKKyAgICBCSU5TTE9UKCJfX2Zsb29yZGl2X18iLCBuYl9mbG9vcl9kaXZpZGUsIHNsb3RfbmJfZmxvb3JfZGl2aWRlLCAiLy8iKSwKKyAgICBSQklOU0xPVCgiX19yZmxvb3JkaXZfXyIsIG5iX2Zsb29yX2RpdmlkZSwgc2xvdF9uYl9mbG9vcl9kaXZpZGUsICIvLyIpLAorICAgIEJJTlNMT1QoIl9fdHJ1ZWRpdl9fIiwgbmJfdHJ1ZV9kaXZpZGUsIHNsb3RfbmJfdHJ1ZV9kaXZpZGUsICIvIiksCisgICAgUkJJTlNMT1QoIl9fcnRydWVkaXZfXyIsIG5iX3RydWVfZGl2aWRlLCBzbG90X25iX3RydWVfZGl2aWRlLCAiLyIpLAorICAgIElCU0xPVCgiX19pZmxvb3JkaXZfXyIsIG5iX2lucGxhY2VfZmxvb3JfZGl2aWRlLAorICAgICAgICAgICBzbG90X25iX2lucGxhY2VfZmxvb3JfZGl2aWRlLCB3cmFwX2JpbmFyeWZ1bmMsICIvLyIpLAorICAgIElCU0xPVCgiX19pdHJ1ZWRpdl9fIiwgbmJfaW5wbGFjZV90cnVlX2RpdmlkZSwKKyAgICAgICAgICAgc2xvdF9uYl9pbnBsYWNlX3RydWVfZGl2aWRlLCB3cmFwX2JpbmFyeWZ1bmMsICIvIiksCisgICAgTkJTTE9UKCJfX2luZGV4X18iLCBuYl9pbmRleCwgc2xvdF9uYl9pbmRleCwgd3JhcF91bmFyeWZ1bmMsCisgICAgICAgICAgICJ4W3k6el0gPD09PiB4W3kuX19pbmRleF9fKCk6ei5fX2luZGV4X18oKV0iKSwKKyAgICBNUFNMT1QoIl9fbGVuX18iLCBtcF9sZW5ndGgsIHNsb3RfbXBfbGVuZ3RoLCB3cmFwX2xlbmZ1bmMsCisgICAgICAgICAgICJ4Ll9fbGVuX18oKSA8PT0+IGxlbih4KSIpLAorICAgIE1QU0xPVCgiX19nZXRpdGVtX18iLCBtcF9zdWJzY3JpcHQsIHNsb3RfbXBfc3Vic2NyaXB0LAorICAgICAgICAgICB3cmFwX2JpbmFyeWZ1bmMsCisgICAgICAgICAgICJ4Ll9fZ2V0aXRlbV9fKHkpIDw9PT4geFt5XSIpLAorICAgIE1QU0xPVCgiX19zZXRpdGVtX18iLCBtcF9hc3Nfc3Vic2NyaXB0LCBzbG90X21wX2Fzc19zdWJzY3JpcHQsCisgICAgICAgICAgIHdyYXBfb2Jqb2JqYXJncHJvYywKKyAgICAgICAgICAgInguX19zZXRpdGVtX18oaSwgeSkgPD09PiB4W2ldPXkiKSwKKyAgICBNUFNMT1QoIl9fZGVsaXRlbV9fIiwgbXBfYXNzX3N1YnNjcmlwdCwgc2xvdF9tcF9hc3Nfc3Vic2NyaXB0LAorICAgICAgICAgICB3cmFwX2RlbGl0ZW0sCisgICAgICAgICAgICJ4Ll9fZGVsaXRlbV9fKHkpIDw9PT4gZGVsIHhbeV0iKSwKKyAgICBTUVNMT1QoIl9fbGVuX18iLCBzcV9sZW5ndGgsIHNsb3Rfc3FfbGVuZ3RoLCB3cmFwX2xlbmZ1bmMsCisgICAgICAgICAgICJ4Ll9fbGVuX18oKSA8PT0+IGxlbih4KSIpLAorICAgIC8qIEhlYXAgdHlwZXMgZGVmaW5pbmcgX19hZGRfXy9fX211bF9fIGhhdmUgc3FfY29uY2F0L3NxX3JlcGVhdCA9PSBOVUxMLgorICAgICAgIFRoZSBsb2dpYyBpbiBhYnN0cmFjdC5jIGFsd2F5cyBmYWxscyBiYWNrIHRvIG5iX2FkZC9uYl9tdWx0aXBseSBpbgorICAgICAgIHRoaXMgY2FzZS4gIERlZmluaW5nIGJvdGggdGhlIG5iXyogYW5kIHRoZSBzcV8qIHNsb3RzIHRvIGNhbGwgdGhlCisgICAgICAgdXNlci1kZWZpbmVkIG1ldGhvZHMgaGFzIHVuZXhwZWN0ZWQgc2lkZS1lZmZlY3RzLCBhcyBzaG93biBieQorICAgICAgIHRlc3RfZGVzY3Iubm90aW1wbGVtZW50ZWQoKSAqLworICAgIFNRU0xPVCgiX19hZGRfXyIsIHNxX2NvbmNhdCwgTlVMTCwgd3JhcF9iaW5hcnlmdW5jLAorICAgICAgInguX19hZGRfXyh5KSA8PT0+IHgreSIpLAorICAgIFNRU0xPVCgiX19tdWxfXyIsIHNxX3JlcGVhdCwgTlVMTCwgd3JhcF9pbmRleGFyZ2Z1bmMsCisgICAgICAieC5fX211bF9fKG4pIDw9PT4geCpuIiksCisgICAgU1FTTE9UKCJfX3JtdWxfXyIsIHNxX3JlcGVhdCwgTlVMTCwgd3JhcF9pbmRleGFyZ2Z1bmMsCisgICAgICAieC5fX3JtdWxfXyhuKSA8PT0+IG4qeCIpLAorICAgIFNRU0xPVCgiX19nZXRpdGVtX18iLCBzcV9pdGVtLCBzbG90X3NxX2l0ZW0sIHdyYXBfc3FfaXRlbSwKKyAgICAgICAgICAgInguX19nZXRpdGVtX18oeSkgPD09PiB4W3ldIiksCisgICAgU1FTTE9UKCJfX2dldHNsaWNlX18iLCBzcV9zbGljZSwgc2xvdF9zcV9zbGljZSwgd3JhcF9zc2l6ZXNzaXplYXJnZnVuYywKKyAgICAgICAgICAgInguX19nZXRzbGljZV9fKGksIGopIDw9PT4geFtpOmpdXG5cCisgICAgICAgICAgIFxuXAorICAgICAgICAgICBVc2Ugb2YgbmVnYXRpdmUgaW5kaWNlcyBpcyBub3Qgc3VwcG9ydGVkLiIpLAorICAgIFNRU0xPVCgiX19zZXRpdGVtX18iLCBzcV9hc3NfaXRlbSwgc2xvdF9zcV9hc3NfaXRlbSwgd3JhcF9zcV9zZXRpdGVtLAorICAgICAgICAgICAieC5fX3NldGl0ZW1fXyhpLCB5KSA8PT0+IHhbaV09eSIpLAorICAgIFNRU0xPVCgiX19kZWxpdGVtX18iLCBzcV9hc3NfaXRlbSwgc2xvdF9zcV9hc3NfaXRlbSwgd3JhcF9zcV9kZWxpdGVtLAorICAgICAgICAgICAieC5fX2RlbGl0ZW1fXyh5KSA8PT0+IGRlbCB4W3ldIiksCisgICAgU1FTTE9UKCJfX3NldHNsaWNlX18iLCBzcV9hc3Nfc2xpY2UsIHNsb3Rfc3FfYXNzX3NsaWNlLAorICAgICAgICAgICB3cmFwX3NzaXplc3NpemVvYmphcmdwcm9jLAorICAgICAgICAgICAieC5fX3NldHNsaWNlX18oaSwgaiwgeSkgPD09PiB4W2k6al09eVxuXAorICAgICAgICAgICBcblwKKyAgICAgICAgICAgVXNlICBvZiBuZWdhdGl2ZSBpbmRpY2VzIGlzIG5vdCBzdXBwb3J0ZWQuIiksCisgICAgU1FTTE9UKCJfX2RlbHNsaWNlX18iLCBzcV9hc3Nfc2xpY2UsIHNsb3Rfc3FfYXNzX3NsaWNlLCB3cmFwX2RlbHNsaWNlLAorICAgICAgICAgICAieC5fX2RlbHNsaWNlX18oaSwgaikgPD09PiBkZWwgeFtpOmpdXG5cCisgICAgICAgICAgIFxuXAorICAgICAgICAgICBVc2Ugb2YgbmVnYXRpdmUgaW5kaWNlcyBpcyBub3Qgc3VwcG9ydGVkLiIpLAorICAgIFNRU0xPVCgiX19jb250YWluc19fIiwgc3FfY29udGFpbnMsIHNsb3Rfc3FfY29udGFpbnMsIHdyYXBfb2Jqb2JqcHJvYywKKyAgICAgICAgICAgInguX19jb250YWluc19fKHkpIDw9PT4geSBpbiB4IiksCisgICAgU1FTTE9UKCJfX2lhZGRfXyIsIHNxX2lucGxhY2VfY29uY2F0LCBOVUxMLAorICAgICAgd3JhcF9iaW5hcnlmdW5jLCAieC5fX2lhZGRfXyh5KSA8PT0+IHgrPXkiKSwKKyAgICBTUVNMT1QoIl9faW11bF9fIiwgc3FfaW5wbGFjZV9yZXBlYXQsIE5VTEwsCisgICAgICB3cmFwX2luZGV4YXJnZnVuYywgInguX19pbXVsX18oeSkgPD09PiB4Kj15IiksCisgICAge05VTEx9Cit9OworCisvKiBHaXZlbiBhIHR5cGUgcG9pbnRlciBhbmQgYW4gb2Zmc2V0IGdvdHRlbiBmcm9tIGEgc2xvdGRlZiBlbnRyeSwgcmV0dXJuIGEKKyAgIHBvaW50ZXIgdG8gdGhlIGFjdHVhbCBzbG90LiAgVGhpcyBpcyBub3QgcXVpdGUgdGhlIHNhbWUgYXMgc2ltcGx5IGFkZGluZworICAgdGhlIG9mZnNldCB0byB0aGUgdHlwZSBwb2ludGVyLCBzaW5jZSBpdCB0YWtlcyBjYXJlIHRvIGluZGlyZWN0IHRocm91Z2ggdGhlCisgICBwcm9wZXIgaW5kaXJlY3Rpb24gcG9pbnRlciAoYXNfYnVmZmVyLCBldGMuKTsgaXQgcmV0dXJucyBOVUxMIGlmIHRoZQorICAgaW5kaXJlY3Rpb24gcG9pbnRlciBpcyBOVUxMLiAqLworc3RhdGljIHZvaWQgKioKK3Nsb3RwdHIoUHlUeXBlT2JqZWN0ICp0eXBlLCBpbnQgaW9mZnNldCkKK3sKKyAgICBjaGFyICpwdHI7CisgICAgbG9uZyBvZmZzZXQgPSBpb2Zmc2V0OworCisgICAgLyogTm90ZTogdGhpcyBkZXBlbmRzIG9uIHRoZSBvcmRlciBvZiB0aGUgbWVtYmVycyBvZiBQeUhlYXBUeXBlT2JqZWN0ISAqLworICAgIGFzc2VydChvZmZzZXQgPj0gMCk7CisgICAgYXNzZXJ0KChzaXplX3Qpb2Zmc2V0IDwgb2Zmc2V0b2YoUHlIZWFwVHlwZU9iamVjdCwgYXNfYnVmZmVyKSk7CisgICAgaWYgKChzaXplX3Qpb2Zmc2V0ID49IG9mZnNldG9mKFB5SGVhcFR5cGVPYmplY3QsIGFzX3NlcXVlbmNlKSkgeworICAgICAgICBwdHIgPSAoY2hhciAqKXR5cGUtPnRwX2FzX3NlcXVlbmNlOworICAgICAgICBvZmZzZXQgLT0gb2Zmc2V0b2YoUHlIZWFwVHlwZU9iamVjdCwgYXNfc2VxdWVuY2UpOworICAgIH0KKyAgICBlbHNlIGlmICgoc2l6ZV90KW9mZnNldCA+PSBvZmZzZXRvZihQeUhlYXBUeXBlT2JqZWN0LCBhc19tYXBwaW5nKSkgeworICAgICAgICBwdHIgPSAoY2hhciAqKXR5cGUtPnRwX2FzX21hcHBpbmc7CisgICAgICAgIG9mZnNldCAtPSBvZmZzZXRvZihQeUhlYXBUeXBlT2JqZWN0LCBhc19tYXBwaW5nKTsKKyAgICB9CisgICAgZWxzZSBpZiAoKHNpemVfdClvZmZzZXQgPj0gb2Zmc2V0b2YoUHlIZWFwVHlwZU9iamVjdCwgYXNfbnVtYmVyKSkgeworICAgICAgICBwdHIgPSAoY2hhciAqKXR5cGUtPnRwX2FzX251bWJlcjsKKyAgICAgICAgb2Zmc2V0IC09IG9mZnNldG9mKFB5SGVhcFR5cGVPYmplY3QsIGFzX251bWJlcik7CisgICAgfQorICAgIGVsc2UgeworICAgICAgICBwdHIgPSAoY2hhciAqKXR5cGU7CisgICAgfQorICAgIGlmIChwdHIgIT0gTlVMTCkKKyAgICAgICAgcHRyICs9IG9mZnNldDsKKyAgICByZXR1cm4gKHZvaWQgKiopcHRyOworfQorCisvKiBMZW5ndGggb2YgYXJyYXkgb2Ygc2xvdGRlZiBwb2ludGVycyB1c2VkIHRvIHN0b3JlIHNsb3RzIHdpdGggdGhlCisgICBzYW1lIF9fbmFtZV9fLiAgVGhlcmUgc2hvdWxkIGJlIGF0IG1vc3QgTUFYX0VRVUlWLTEgc2xvdGRlZiBlbnRyaWVzIHdpdGgKKyAgIHRoZSBzYW1lIF9fbmFtZV9fLCBmb3IgYW55IF9fbmFtZV9fLiBTaW5jZSB0aGF0J3MgYSBzdGF0aWMgcHJvcGVydHksIGl0IGlzCisgICBhcHByb3ByaWF0ZSB0byBkZWNsYXJlIGZpeGVkLXNpemUgYXJyYXlzIGZvciB0aGlzLiAqLworI2RlZmluZSBNQVhfRVFVSVYgMTAKKworLyogUmV0dXJuIGEgc2xvdCBwb2ludGVyIGZvciBhIGdpdmVuIG5hbWUsIGJ1dCBPTkxZIGlmIHRoZSBhdHRyaWJ1dGUgaGFzCisgICBleGFjdGx5IG9uZSBzbG90IGZ1bmN0aW9uLiAgVGhlIG5hbWUgbXVzdCBiZSBhbiBpbnRlcm5lZCBzdHJpbmcuICovCitzdGF0aWMgdm9pZCAqKgorcmVzb2x2ZV9zbG90ZHVwcyhQeVR5cGVPYmplY3QgKnR5cGUsIFB5T2JqZWN0ICpuYW1lKQoreworICAgIC8qIFhYWCBNYXliZSB0aGlzIGNvdWxkIGJlIG9wdGltaXplZCBtb3JlIC0tIGJ1dCBpcyBpdCB3b3J0aCBpdD8gKi8KKworICAgIC8qIHBuYW1lIGFuZCBwdHJzIGFjdCBhcyBhIGxpdHRsZSBjYWNoZSAqLworICAgIHN0YXRpYyBQeU9iamVjdCAqcG5hbWU7CisgICAgc3RhdGljIHNsb3RkZWYgKnB0cnNbTUFYX0VRVUlWXTsKKyAgICBzbG90ZGVmICpwLCAqKnBwOworICAgIHZvaWQgKipyZXMsICoqcHRyOworCisgICAgaWYgKHBuYW1lICE9IG5hbWUpIHsKKyAgICAgICAgLyogQ29sbGVjdCBhbGwgc2xvdGRlZnMgdGhhdCBtYXRjaCBuYW1lIGludG8gcHRycy4gKi8KKyAgICAgICAgcG5hbWUgPSBuYW1lOworICAgICAgICBwcCA9IHB0cnM7CisgICAgICAgIGZvciAocCA9IHNsb3RkZWZzOyBwLT5uYW1lX3N0cm9iajsgcCsrKSB7CisgICAgICAgICAgICBpZiAocC0+bmFtZV9zdHJvYmogPT0gbmFtZSkKKyAgICAgICAgICAgICAgICAqcHArKyA9IHA7CisgICAgICAgIH0KKyAgICAgICAgKnBwID0gTlVMTDsKKyAgICB9CisKKyAgICAvKiBMb29rIGluIGFsbCBtYXRjaGluZyBzbG90cyBvZiB0aGUgdHlwZTsgaWYgZXhhY3RseSBvbmUgb2YgdGhlc2UgaGFzCisgICAgICAgYSBmaWxsZWQtaW4gc2xvdCwgcmV0dXJuIGl0cyB2YWx1ZS4gICAgICBPdGhlcndpc2UgcmV0dXJuIE5VTEwuICovCisgICAgcmVzID0gTlVMTDsKKyAgICBmb3IgKHBwID0gcHRyczsgKnBwOyBwcCsrKSB7CisgICAgICAgIHB0ciA9IHNsb3RwdHIodHlwZSwgKCpwcCktPm9mZnNldCk7CisgICAgICAgIGlmIChwdHIgPT0gTlVMTCB8fCAqcHRyID09IE5VTEwpCisgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgaWYgKHJlcyAhPSBOVUxMKQorICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgICAgIHJlcyA9IHB0cjsKKyAgICB9CisgICAgcmV0dXJuIHJlczsKK30KKworLyogQ29tbW9uIGNvZGUgZm9yIHVwZGF0ZV9zbG90c19jYWxsYmFjaygpIGFuZCBmaXh1cF9zbG90X2Rpc3BhdGNoZXJzKCkuICBUaGlzCisgICBkb2VzIHNvbWUgaW5jcmVkaWJseSBjb21wbGV4IHRoaW5raW5nIGFuZCB0aGVuIHN0aWNrcyBzb21ldGhpbmcgaW50byB0aGUKKyAgIHNsb3QuICAoSXQgc2VlcyBpZiB0aGUgYWRqYWNlbnQgc2xvdGRlZnMgZm9yIHRoZSBzYW1lIHNsb3QgaGF2ZSBjb25mbGljdGluZworICAgaW50ZXJlc3RzLCBhbmQgdGhlbiBzdG9yZXMgYSBnZW5lcmljIHdyYXBwZXIgb3IgYSBzcGVjaWZpYyBmdW5jdGlvbiBpbnRvCisgICB0aGUgc2xvdC4pICBSZXR1cm4gYSBwb2ludGVyIHRvIHRoZSBuZXh0IHNsb3RkZWYgd2l0aCBhIGRpZmZlcmVudCBvZmZzZXQsCisgICBiZWNhdXNlIHRoYXQncyBjb252ZW5pZW50ICBmb3IgZml4dXBfc2xvdF9kaXNwYXRjaGVycygpLiAqLworc3RhdGljIHNsb3RkZWYgKgordXBkYXRlX29uZV9zbG90KFB5VHlwZU9iamVjdCAqdHlwZSwgc2xvdGRlZiAqcCkKK3sKKyAgICBQeU9iamVjdCAqZGVzY3I7CisgICAgUHlXcmFwcGVyRGVzY3JPYmplY3QgKmQ7CisgICAgdm9pZCAqZ2VuZXJpYyA9IE5VTEwsICpzcGVjaWZpYyA9IE5VTEw7CisgICAgaW50IHVzZV9nZW5lcmljID0gMDsKKyAgICBpbnQgb2Zmc2V0ID0gcC0+b2Zmc2V0OworICAgIHZvaWQgKipwdHIgPSBzbG90cHRyKHR5cGUsIG9mZnNldCk7CisKKyAgICBpZiAocHRyID09IE5VTEwpIHsKKyAgICAgICAgZG8geworICAgICAgICAgICAgKytwOworICAgICAgICB9IHdoaWxlIChwLT5vZmZzZXQgPT0gb2Zmc2V0KTsKKyAgICAgICAgcmV0dXJuIHA7CisgICAgfQorICAgIGRvIHsKKyAgICAgICAgZGVzY3IgPSBfUHlUeXBlX0xvb2t1cCh0eXBlLCBwLT5uYW1lX3N0cm9iaik7CisgICAgICAgIGlmIChkZXNjciA9PSBOVUxMKSB7CisgICAgICAgICAgICBpZiAocHRyID09ICh2b2lkKiopJnR5cGUtPnRwX2l0ZXJuZXh0KSB7CisgICAgICAgICAgICAgICAgc3BlY2lmaWMgPSBfUHlPYmplY3RfTmV4dE5vdEltcGxlbWVudGVkOworICAgICAgICAgICAgfQorICAgICAgICAgICAgY29udGludWU7CisgICAgICAgIH0KKyAgICAgICAgaWYgKFB5X1RZUEUoZGVzY3IpID09ICZQeVdyYXBwZXJEZXNjcl9UeXBlICYmCisgICAgICAgICAgICAoKFB5V3JhcHBlckRlc2NyT2JqZWN0ICopZGVzY3IpLT5kX2Jhc2UtPm5hbWVfc3Ryb2JqID09IHAtPm5hbWVfc3Ryb2JqKSB7CisgICAgICAgICAgICB2b2lkICoqdHB0ciA9IHJlc29sdmVfc2xvdGR1cHModHlwZSwgcC0+bmFtZV9zdHJvYmopOworICAgICAgICAgICAgaWYgKHRwdHIgPT0gTlVMTCB8fCB0cHRyID09IHB0cikKKyAgICAgICAgICAgICAgICBnZW5lcmljID0gcC0+ZnVuY3Rpb247CisgICAgICAgICAgICBkID0gKFB5V3JhcHBlckRlc2NyT2JqZWN0ICopZGVzY3I7CisgICAgICAgICAgICBpZiAoZC0+ZF9iYXNlLT53cmFwcGVyID09IHAtPndyYXBwZXIgJiYKKyAgICAgICAgICAgICAgICBQeVR5cGVfSXNTdWJ0eXBlKHR5cGUsIGQtPmRfdHlwZSkpCisgICAgICAgICAgICB7CisgICAgICAgICAgICAgICAgaWYgKHNwZWNpZmljID09IE5VTEwgfHwKKyAgICAgICAgICAgICAgICAgICAgc3BlY2lmaWMgPT0gZC0+ZF93cmFwcGVkKQorICAgICAgICAgICAgICAgICAgICBzcGVjaWZpYyA9IGQtPmRfd3JhcHBlZDsKKyAgICAgICAgICAgICAgICBlbHNlCisgICAgICAgICAgICAgICAgICAgIHVzZV9nZW5lcmljID0gMTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBlbHNlIGlmIChQeV9UWVBFKGRlc2NyKSA9PSAmUHlDRnVuY3Rpb25fVHlwZSAmJgorICAgICAgICAgICAgICAgICBQeUNGdW5jdGlvbl9HRVRfRlVOQ1RJT04oZGVzY3IpID09CisgICAgICAgICAgICAgICAgIChQeUNGdW5jdGlvbil0cF9uZXdfd3JhcHBlciAmJgorICAgICAgICAgICAgICAgICBwdHIgPT0gKHZvaWQqKikmdHlwZS0+dHBfbmV3KQorICAgICAgICB7CisgICAgICAgICAgICAvKiBUaGUgX19uZXdfXyB3cmFwcGVyIGlzIG5vdCBhIHdyYXBwZXIgZGVzY3JpcHRvciwKKyAgICAgICAgICAgICAgIHNvIG11c3QgYmUgc3BlY2lhbC1jYXNlZCBkaWZmZXJlbnRseS4KKyAgICAgICAgICAgICAgIElmIHdlIGRvbid0IGRvIHRoaXMsIGNyZWF0aW5nIGFuIGluc3RhbmNlIHdpbGwKKyAgICAgICAgICAgICAgIGFsd2F5cyB1c2Ugc2xvdF90cF9uZXcgd2hpY2ggd2lsbCBsb29rIHVwCisgICAgICAgICAgICAgICBfX25ld19fIGluIHRoZSBNUk8gd2hpY2ggd2lsbCBjYWxsIHRwX25ld193cmFwcGVyCisgICAgICAgICAgICAgICB3aGljaCB3aWxsIGxvb2sgdGhyb3VnaCB0aGUgYmFzZSBjbGFzc2VzIGxvb2tpbmcKKyAgICAgICAgICAgICAgIGZvciBhIHN0YXRpYyBiYXNlIGFuZCBjYWxsIGl0cyB0cF9uZXcgKHVzdWFsbHkKKyAgICAgICAgICAgICAgIFB5VHlwZV9HZW5lcmljTmV3KSwgYWZ0ZXIgcGVyZm9ybWluZyB2YXJpb3VzCisgICAgICAgICAgICAgICBzYW5pdHkgY2hlY2tzIGFuZCBjb25zdHJ1Y3RpbmcgYSBuZXcgYXJndW1lbnQKKyAgICAgICAgICAgICAgIGxpc3QuICBDdXQgYWxsIHRoYXQgbm9uc2Vuc2Ugc2hvcnQgLS0gdGhpcyBzcGVlZHMKKyAgICAgICAgICAgICAgIHVwIGluc3RhbmNlIGNyZWF0aW9uIHRyZW1lbmRvdXNseS4gKi8KKyAgICAgICAgICAgIHNwZWNpZmljID0gKHZvaWQgKil0eXBlLT50cF9uZXc7CisgICAgICAgICAgICAvKiBYWFggSSdtIG5vdCAxMDAlIHN1cmUgdGhhdCB0aGVyZSBpc24ndCBhIGhvbGUKKyAgICAgICAgICAgICAgIGluIHRoaXMgcmVhc29uaW5nIHRoYXQgcmVxdWlyZXMgYWRkaXRpb25hbAorICAgICAgICAgICAgICAgc2FuaXR5IGNoZWNrcy4gIEknbGwgYnV5IHRoZSBmaXJzdCBwZXJzb24gdG8KKyAgICAgICAgICAgICAgIHBvaW50IG91dCBhIGJ1ZyBpbiB0aGlzIHJlYXNvbmluZyBhIGJlZXIuICovCisgICAgICAgIH0KKyAgICAgICAgZWxzZSBpZiAoZGVzY3IgPT0gUHlfTm9uZSAmJgorICAgICAgICAgICAgICAgICBwdHIgPT0gKHZvaWQqKikmdHlwZS0+dHBfaGFzaCkgeworICAgICAgICAgICAgLyogV2Ugc3BlY2lmaWNhbGx5IGFsbG93IF9faGFzaF9fIHRvIGJlIHNldCB0byBOb25lCisgICAgICAgICAgICAgICB0byBwcmV2ZW50IGluaGVyaXRhbmNlIG9mIHRoZSBkZWZhdWx0CisgICAgICAgICAgICAgICBpbXBsZW1lbnRhdGlvbiBmcm9tIG9iamVjdC5fX2hhc2hfXyAqLworICAgICAgICAgICAgc3BlY2lmaWMgPSBQeU9iamVjdF9IYXNoTm90SW1wbGVtZW50ZWQ7CisgICAgICAgIH0KKyAgICAgICAgZWxzZSB7CisgICAgICAgICAgICB1c2VfZ2VuZXJpYyA9IDE7CisgICAgICAgICAgICBnZW5lcmljID0gcC0+ZnVuY3Rpb247CisgICAgICAgIH0KKyAgICB9IHdoaWxlICgoKytwKS0+b2Zmc2V0ID09IG9mZnNldCk7CisgICAgaWYgKHNwZWNpZmljICYmICF1c2VfZ2VuZXJpYykKKyAgICAgICAgKnB0ciA9IHNwZWNpZmljOworICAgIGVsc2UKKyAgICAgICAgKnB0ciA9IGdlbmVyaWM7CisgICAgcmV0dXJuIHA7Cit9CisKKy8qIEluIHRoZSB0eXBlLCB1cGRhdGUgdGhlIHNsb3RzIHdob3NlIHNsb3RkZWZzIGFyZSBnYXRoZXJlZCBpbiB0aGUgcHAgYXJyYXkuCisgICBUaGlzIGlzIGEgY2FsbGJhY2sgZm9yIHVwZGF0ZV9zdWJjbGFzc2VzKCkuICovCitzdGF0aWMgaW50Cit1cGRhdGVfc2xvdHNfY2FsbGJhY2soUHlUeXBlT2JqZWN0ICp0eXBlLCB2b2lkICpkYXRhKQoreworICAgIHNsb3RkZWYgKipwcCA9IChzbG90ZGVmICoqKWRhdGE7CisKKyAgICBmb3IgKDsgKnBwOyBwcCsrKQorICAgICAgICB1cGRhdGVfb25lX3Nsb3QodHlwZSwgKnBwKTsKKyAgICByZXR1cm4gMDsKK30KKworLyogSW5pdGlhbGl6ZSB0aGUgc2xvdGRlZnMgdGFibGUgYnkgYWRkaW5nIGludGVybmVkIHN0cmluZyBvYmplY3RzIGZvciB0aGUKKyAgIG5hbWVzIGFuZCBzb3J0aW5nIHRoZSBlbnRyaWVzLiAqLworc3RhdGljIHZvaWQKK2luaXRfc2xvdGRlZnModm9pZCkKK3sKKyAgICBzbG90ZGVmICpwOworICAgIHN0YXRpYyBpbnQgaW5pdGlhbGl6ZWQgPSAwOworCisgICAgaWYgKGluaXRpYWxpemVkKQorICAgICAgICByZXR1cm47CisgICAgZm9yIChwID0gc2xvdGRlZnM7IHAtPm5hbWU7IHArKykgeworICAgICAgICAvKiBTbG90cyBtdXN0IGJlIG9yZGVyZWQgYnkgdGhlaXIgb2Zmc2V0IGluIHRoZSBQeUhlYXBUeXBlT2JqZWN0LiAqLworICAgICAgICBhc3NlcnQoIXBbMV0ubmFtZSB8fCBwLT5vZmZzZXQgPD0gcFsxXS5vZmZzZXQpOworICAgICAgICBwLT5uYW1lX3N0cm9iaiA9IFB5U3RyaW5nX0ludGVybkZyb21TdHJpbmcocC0+bmFtZSk7CisgICAgICAgIGlmICghcC0+bmFtZV9zdHJvYmopCisgICAgICAgICAgICBQeV9GYXRhbEVycm9yKCJPdXQgb2YgbWVtb3J5IGludGVybmluZyBzbG90ZGVmIG5hbWVzIik7CisgICAgfQorICAgIGluaXRpYWxpemVkID0gMTsKK30KKworLyogVXBkYXRlIHRoZSBzbG90cyBhZnRlciBhc3NpZ25tZW50IHRvIGEgY2xhc3MgKHR5cGUpIGF0dHJpYnV0ZS4gKi8KK3N0YXRpYyBpbnQKK3VwZGF0ZV9zbG90KFB5VHlwZU9iamVjdCAqdHlwZSwgUHlPYmplY3QgKm5hbWUpCit7CisgICAgc2xvdGRlZiAqcHRyc1tNQVhfRVFVSVZdOworICAgIHNsb3RkZWYgKnA7CisgICAgc2xvdGRlZiAqKnBwOworICAgIGludCBvZmZzZXQ7CisKKyAgICAvKiBDbGVhciB0aGUgVkFMSURfVkVSU0lPTiBmbGFnIG9mICd0eXBlJyBhbmQgYWxsIGl0cworICAgICAgIHN1YmNsYXNzZXMuICBUaGlzIGNvdWxkIHBvc3NpYmx5IGJlIHVuaWZpZWQgd2l0aCB0aGUKKyAgICAgICB1cGRhdGVfc3ViY2xhc3NlcygpIHJlY3Vyc2lvbiBiZWxvdywgYnV0IGNhcmVmdWxseToKKyAgICAgICB0aGV5IGVhY2ggaGF2ZSB0aGVpciBvd24gY29uZGl0aW9ucyBvbiB3aGljaCB0byBzdG9wCisgICAgICAgcmVjdXJzaW5nIGludG8gc3ViY2xhc3Nlcy4gKi8KKyAgICBQeVR5cGVfTW9kaWZpZWQodHlwZSk7CisKKyAgICBpbml0X3Nsb3RkZWZzKCk7CisgICAgcHAgPSBwdHJzOworICAgIGZvciAocCA9IHNsb3RkZWZzOyBwLT5uYW1lOyBwKyspIHsKKyAgICAgICAgLyogWFhYIGFzc3VtZSBuYW1lIGlzIGludGVybmVkISAqLworICAgICAgICBpZiAocC0+bmFtZV9zdHJvYmogPT0gbmFtZSkKKyAgICAgICAgICAgICpwcCsrID0gcDsKKyAgICB9CisgICAgKnBwID0gTlVMTDsKKyAgICBmb3IgKHBwID0gcHRyczsgKnBwOyBwcCsrKSB7CisgICAgICAgIHAgPSAqcHA7CisgICAgICAgIG9mZnNldCA9IHAtPm9mZnNldDsKKyAgICAgICAgd2hpbGUgKHAgPiBzbG90ZGVmcyAmJiAocC0xKS0+b2Zmc2V0ID09IG9mZnNldCkKKyAgICAgICAgICAgIC0tcDsKKyAgICAgICAgKnBwID0gcDsKKyAgICB9CisgICAgaWYgKHB0cnNbMF0gPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIDA7IC8qIE5vdCBhbiBhdHRyaWJ1dGUgdGhhdCBhZmZlY3RzIGFueSBzbG90cyAqLworICAgIHJldHVybiB1cGRhdGVfc3ViY2xhc3Nlcyh0eXBlLCBuYW1lLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1cGRhdGVfc2xvdHNfY2FsbGJhY2ssICh2b2lkICopcHRycyk7Cit9CisKKy8qIFN0b3JlIHRoZSBwcm9wZXIgZnVuY3Rpb25zIGluIHRoZSBzbG90IGRpc3BhdGNoZXMgYXQgY2xhc3MgKHR5cGUpCisgICBkZWZpbml0aW9uIHRpbWUsIGJhc2VkIHVwb24gd2hpY2ggb3BlcmF0aW9ucyB0aGUgY2xhc3Mgb3ZlcnJpZGVzIGluIGl0cworICAgZGljdC4gKi8KK3N0YXRpYyB2b2lkCitmaXh1cF9zbG90X2Rpc3BhdGNoZXJzKFB5VHlwZU9iamVjdCAqdHlwZSkKK3sKKyAgICBzbG90ZGVmICpwOworCisgICAgaW5pdF9zbG90ZGVmcygpOworICAgIGZvciAocCA9IHNsb3RkZWZzOyBwLT5uYW1lOyApCisgICAgICAgIHAgPSB1cGRhdGVfb25lX3Nsb3QodHlwZSwgcCk7Cit9CisKK3N0YXRpYyB2b2lkCit1cGRhdGVfYWxsX3Nsb3RzKFB5VHlwZU9iamVjdCogdHlwZSkKK3sKKyAgICBzbG90ZGVmICpwOworCisgICAgaW5pdF9zbG90ZGVmcygpOworICAgIGZvciAocCA9IHNsb3RkZWZzOyBwLT5uYW1lOyBwKyspIHsKKyAgICAgICAgLyogdXBkYXRlX3Nsb3QgcmV0dXJucyBpbnQgYnV0IGNhbid0IGFjdHVhbGx5IGZhaWwgKi8KKyAgICAgICAgdXBkYXRlX3Nsb3QodHlwZSwgcC0+bmFtZV9zdHJvYmopOworICAgIH0KK30KKworLyogcmVjdXJzZV9kb3duX3N1YmNsYXNzZXMoKSBhbmQgdXBkYXRlX3N1YmNsYXNzZXMoKSBhcmUgbXV0dWFsbHkKKyAgIHJlY3Vyc2l2ZSBmdW5jdGlvbnMgdG8gY2FsbCBhIGNhbGxiYWNrIGZvciBhbGwgc3ViY2xhc3NlcywKKyAgIGJ1dCByZWZyYWluaW5nIGZyb20gcmVjdXJzaW5nIGludG8gc3ViY2xhc3NlcyB0aGF0IGRlZmluZSAnbmFtZScuICovCisKK3N0YXRpYyBpbnQKK3VwZGF0ZV9zdWJjbGFzc2VzKFB5VHlwZU9iamVjdCAqdHlwZSwgUHlPYmplY3QgKm5hbWUsCisgICAgICAgICAgICAgICAgICB1cGRhdGVfY2FsbGJhY2sgY2FsbGJhY2ssIHZvaWQgKmRhdGEpCit7CisgICAgaWYgKGNhbGxiYWNrKHR5cGUsIGRhdGEpIDwgMCkKKyAgICAgICAgcmV0dXJuIC0xOworICAgIHJldHVybiByZWN1cnNlX2Rvd25fc3ViY2xhc3Nlcyh0eXBlLCBuYW1lLCBjYWxsYmFjaywgZGF0YSk7Cit9CisKK3N0YXRpYyBpbnQKK3JlY3Vyc2VfZG93bl9zdWJjbGFzc2VzKFB5VHlwZU9iamVjdCAqdHlwZSwgUHlPYmplY3QgKm5hbWUsCisgICAgICAgICAgICAgICAgICAgICAgICB1cGRhdGVfY2FsbGJhY2sgY2FsbGJhY2ssIHZvaWQgKmRhdGEpCit7CisgICAgUHlUeXBlT2JqZWN0ICpzdWJjbGFzczsKKyAgICBQeU9iamVjdCAqcmVmLCAqc3ViY2xhc3NlcywgKmRpY3Q7CisgICAgUHlfc3NpemVfdCBpLCBuOworCisgICAgc3ViY2xhc3NlcyA9IHR5cGUtPnRwX3N1YmNsYXNzZXM7CisgICAgaWYgKHN1YmNsYXNzZXMgPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIDA7CisgICAgYXNzZXJ0KFB5TGlzdF9DaGVjayhzdWJjbGFzc2VzKSk7CisgICAgbiA9IFB5TGlzdF9HRVRfU0laRShzdWJjbGFzc2VzKTsKKyAgICBmb3IgKGkgPSAwOyBpIDwgbjsgaSsrKSB7CisgICAgICAgIHJlZiA9IFB5TGlzdF9HRVRfSVRFTShzdWJjbGFzc2VzLCBpKTsKKyAgICAgICAgYXNzZXJ0KFB5V2Vha3JlZl9DaGVja1JlZihyZWYpKTsKKyAgICAgICAgc3ViY2xhc3MgPSAoUHlUeXBlT2JqZWN0ICopUHlXZWFrcmVmX0dFVF9PQkpFQ1QocmVmKTsKKyAgICAgICAgYXNzZXJ0KHN1YmNsYXNzICE9IE5VTEwpOworICAgICAgICBpZiAoKFB5T2JqZWN0ICopc3ViY2xhc3MgPT0gUHlfTm9uZSkKKyAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICBhc3NlcnQoUHlUeXBlX0NoZWNrKHN1YmNsYXNzKSk7CisgICAgICAgIC8qIEF2b2lkIHJlY3Vyc2luZyBkb3duIGludG8gdW5hZmZlY3RlZCBjbGFzc2VzICovCisgICAgICAgIGRpY3QgPSBzdWJjbGFzcy0+dHBfZGljdDsKKyAgICAgICAgaWYgKGRpY3QgIT0gTlVMTCAmJiBQeURpY3RfQ2hlY2soZGljdCkgJiYKKyAgICAgICAgICAgIFB5RGljdF9HZXRJdGVtKGRpY3QsIG5hbWUpICE9IE5VTEwpCisgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgaWYgKHVwZGF0ZV9zdWJjbGFzc2VzKHN1YmNsYXNzLCBuYW1lLCBjYWxsYmFjaywgZGF0YSkgPCAwKQorICAgICAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKyAgICByZXR1cm4gMDsKK30KKworLyogVGhpcyBmdW5jdGlvbiBpcyBjYWxsZWQgYnkgUHlUeXBlX1JlYWR5KCkgdG8gcG9wdWxhdGUgdGhlIHR5cGUncworICAgZGljdGlvbmFyeSB3aXRoIG1ldGhvZCBkZXNjcmlwdG9ycyBmb3IgZnVuY3Rpb24gc2xvdHMuICBGb3IgZWFjaAorICAgZnVuY3Rpb24gc2xvdCAobGlrZSB0cF9yZXByKSB0aGF0J3MgZGVmaW5lZCBpbiB0aGUgdHlwZSwgb25lIG9yIG1vcmUKKyAgIGNvcnJlc3BvbmRpbmcgZGVzY3JpcHRvcnMgYXJlIGFkZGVkIGluIHRoZSB0eXBlJ3MgdHBfZGljdCBkaWN0aW9uYXJ5CisgICB1bmRlciB0aGUgYXBwcm9wcmlhdGUgbmFtZSAobGlrZSBfX3JlcHJfXykuICBTb21lIGZ1bmN0aW9uIHNsb3RzCisgICBjYXVzZSBtb3JlIHRoYW4gb25lIGRlc2NyaXB0b3IgdG8gYmUgYWRkZWQgKGZvciBleGFtcGxlLCB0aGUgbmJfYWRkCisgICBzbG90IGFkZHMgYm90aCBfX2FkZF9fIGFuZCBfX3JhZGRfXyBkZXNjcmlwdG9ycykgYW5kIHNvbWUgZnVuY3Rpb24KKyAgIHNsb3RzIGNvbXBldGUgZm9yIHRoZSBzYW1lIGRlc2NyaXB0b3IgKGZvciBleGFtcGxlIGJvdGggc3FfaXRlbSBhbmQKKyAgIG1wX3N1YnNjcmlwdCBnZW5lcmF0ZSBhIF9fZ2V0aXRlbV9fIGRlc2NyaXB0b3IpLgorCisgICBJbiB0aGUgbGF0dGVyIGNhc2UsIHRoZSBmaXJzdCBzbG90ZGVmIGVudHJ5IGVuY291bnRlcmVkIHdpbnMuICBTaW5jZQorICAgc2xvdGRlZiBlbnRyaWVzIGFyZSBzb3J0ZWQgYnkgdGhlIG9mZnNldCBvZiB0aGUgc2xvdCBpbiB0aGUKKyAgIFB5SGVhcFR5cGVPYmplY3QsIHRoaXMgZ2l2ZXMgdXMgc29tZSBjb250cm9sIG92ZXIgZGlzYW1iaWd1YXRpbmcKKyAgIGJldHdlZW4gY29tcGV0aW5nIHNsb3RzOiB0aGUgbWVtYmVycyBvZiBQeUhlYXBUeXBlT2JqZWN0IGFyZSBsaXN0ZWQKKyAgIGZyb20gbW9zdCBnZW5lcmFsIHRvIGxlYXN0IGdlbmVyYWwsIHNvIHRoZSBtb3N0IGdlbmVyYWwgc2xvdCBpcworICAgcHJlZmVycmVkLiAgSW4gcGFydGljdWxhciwgYmVjYXVzZSBhc19tYXBwaW5nIGNvbWVzIGJlZm9yZSBhc19zZXF1ZW5jZSwKKyAgIGZvciBhIHR5cGUgdGhhdCBkZWZpbmVzIGJvdGggbXBfc3Vic2NyaXB0IGFuZCBzcV9pdGVtLCBtcF9zdWJzY3JpcHQKKyAgIHdpbnMuCisKKyAgIFRoaXMgb25seSBhZGRzIG5ldyBkZXNjcmlwdG9ycyBhbmQgZG9lc24ndCBvdmVyd3JpdGUgZW50cmllcyBpbgorICAgdHBfZGljdCB0aGF0IHdlcmUgcHJldmlvdXNseSBkZWZpbmVkLiAgVGhlIGRlc2NyaXB0b3JzIGNvbnRhaW4gYQorICAgcmVmZXJlbmNlIHRvIHRoZSBDIGZ1bmN0aW9uIHRoZXkgbXVzdCBjYWxsLCBzbyB0aGF0IGl0J3Mgc2FmZSBpZiB0aGV5CisgICBhcmUgY29waWVkIGludG8gYSBzdWJ0eXBlJ3MgX19kaWN0X18gYW5kIHRoZSBzdWJ0eXBlIGhhcyBhIGRpZmZlcmVudAorICAgQyBmdW5jdGlvbiBpbiBpdHMgc2xvdCAtLSBjYWxsaW5nIHRoZSBtZXRob2QgZGVmaW5lZCBieSB0aGUKKyAgIGRlc2NyaXB0b3Igd2lsbCBjYWxsIHRoZSBDIGZ1bmN0aW9uIHRoYXQgd2FzIHVzZWQgdG8gY3JlYXRlIGl0LAorICAgcmF0aGVyIHRoYW4gdGhlIEMgZnVuY3Rpb24gcHJlc2VudCBpbiB0aGUgc2xvdCB3aGVuIGl0IGlzIGNhbGxlZC4KKyAgIChUaGlzIGlzIGltcG9ydGFudCBiZWNhdXNlIGEgc3VidHlwZSBtYXkgaGF2ZSBhIEMgZnVuY3Rpb24gaW4gdGhlCisgICBzbG90IHRoYXQgY2FsbHMgdGhlIG1ldGhvZCBmcm9tIHRoZSBkaWN0aW9uYXJ5LCBhbmQgd2Ugd2FudCB0byBhdm9pZAorICAgaW5maW5pdGUgcmVjdXJzaW9uIGhlcmUuKSAqLworCitzdGF0aWMgaW50CithZGRfb3BlcmF0b3JzKFB5VHlwZU9iamVjdCAqdHlwZSkKK3sKKyAgICBQeU9iamVjdCAqZGljdCA9IHR5cGUtPnRwX2RpY3Q7CisgICAgc2xvdGRlZiAqcDsKKyAgICBQeU9iamVjdCAqZGVzY3I7CisgICAgdm9pZCAqKnB0cjsKKworICAgIGluaXRfc2xvdGRlZnMoKTsKKyAgICBmb3IgKHAgPSBzbG90ZGVmczsgcC0+bmFtZTsgcCsrKSB7CisgICAgICAgIGlmIChwLT53cmFwcGVyID09IE5VTEwpCisgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgcHRyID0gc2xvdHB0cih0eXBlLCBwLT5vZmZzZXQpOworICAgICAgICBpZiAoIXB0ciB8fCAhKnB0cikKKyAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICBpZiAoUHlEaWN0X0dldEl0ZW0oZGljdCwgcC0+bmFtZV9zdHJvYmopKQorICAgICAgICAgICAgY29udGludWU7CisgICAgICAgIGlmICgqcHRyID09IFB5T2JqZWN0X0hhc2hOb3RJbXBsZW1lbnRlZCkgeworICAgICAgICAgICAgLyogQ2xhc3NlcyBtYXkgcHJldmVudCB0aGUgaW5oZXJpdGFuY2Ugb2YgdGhlIHRwX2hhc2gKKyAgICAgICAgICAgICAgIHNsb3QgYnkgc3RvcmluZyBQeU9iamVjdF9IYXNoTm90SW1wbGVtZW50ZWQgaW4gaXQuIE1ha2UgaXQKKyAgICAgICAgICAgICAgIHZpc2libGUgYXMgYSBOb25lIHZhbHVlIGZvciB0aGUgX19oYXNoX18gYXR0cmlidXRlLiAqLworICAgICAgICAgICAgaWYgKFB5RGljdF9TZXRJdGVtKGRpY3QsIHAtPm5hbWVfc3Ryb2JqLCBQeV9Ob25lKSA8IDApCisgICAgICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICB9CisgICAgICAgIGVsc2UgeworICAgICAgICAgICAgZGVzY3IgPSBQeURlc2NyX05ld1dyYXBwZXIodHlwZSwgcCwgKnB0cik7CisgICAgICAgICAgICBpZiAoZGVzY3IgPT0gTlVMTCkKKyAgICAgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgICAgICBpZiAoUHlEaWN0X1NldEl0ZW0oZGljdCwgcC0+bmFtZV9zdHJvYmosIGRlc2NyKSA8IDApCisgICAgICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICAgICAgUHlfREVDUkVGKGRlc2NyKTsKKyAgICAgICAgfQorICAgIH0KKyAgICBpZiAodHlwZS0+dHBfbmV3ICE9IE5VTEwpIHsKKyAgICAgICAgaWYgKGFkZF90cF9uZXdfd3JhcHBlcih0eXBlKSA8IDApCisgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgfQorICAgIHJldHVybiAwOworfQorCisKKy8qIENvb3BlcmF0aXZlICdzdXBlcicgKi8KKwordHlwZWRlZiBzdHJ1Y3QgeworICAgIFB5T2JqZWN0X0hFQUQKKyAgICBQeVR5cGVPYmplY3QgKnR5cGU7CisgICAgUHlPYmplY3QgKm9iajsKKyAgICBQeVR5cGVPYmplY3QgKm9ial90eXBlOworfSBzdXBlcm9iamVjdDsKKworc3RhdGljIFB5TWVtYmVyRGVmIHN1cGVyX21lbWJlcnNbXSA9IHsKKyAgICB7Il9fdGhpc2NsYXNzX18iLCBUX09CSkVDVCwgb2Zmc2V0b2Yoc3VwZXJvYmplY3QsIHR5cGUpLCBSRUFET05MWSwKKyAgICAgInRoZSBjbGFzcyBpbnZva2luZyBzdXBlcigpIn0sCisgICAgeyJfX3NlbGZfXyIsICBUX09CSkVDVCwgb2Zmc2V0b2Yoc3VwZXJvYmplY3QsIG9iaiksIFJFQURPTkxZLAorICAgICAidGhlIGluc3RhbmNlIGludm9raW5nIHN1cGVyKCk7IG1heSBiZSBOb25lIn0sCisgICAgeyJfX3NlbGZfY2xhc3NfXyIsIFRfT0JKRUNULCBvZmZzZXRvZihzdXBlcm9iamVjdCwgb2JqX3R5cGUpLCBSRUFET05MWSwKKyAgICAgInRoZSB0eXBlIG9mIHRoZSBpbnN0YW5jZSBpbnZva2luZyBzdXBlcigpOyBtYXkgYmUgTm9uZSJ9LAorICAgIHswfQorfTsKKworc3RhdGljIHZvaWQKK3N1cGVyX2RlYWxsb2MoUHlPYmplY3QgKnNlbGYpCit7CisgICAgc3VwZXJvYmplY3QgKnN1ID0gKHN1cGVyb2JqZWN0ICopc2VsZjsKKworICAgIF9QeU9iamVjdF9HQ19VTlRSQUNLKHNlbGYpOworICAgIFB5X1hERUNSRUYoc3UtPm9iaik7CisgICAgUHlfWERFQ1JFRihzdS0+dHlwZSk7CisgICAgUHlfWERFQ1JFRihzdS0+b2JqX3R5cGUpOworICAgIFB5X1RZUEUoc2VsZiktPnRwX2ZyZWUoc2VsZik7Cit9CisKK3N0YXRpYyBQeU9iamVjdCAqCitzdXBlcl9yZXByKFB5T2JqZWN0ICpzZWxmKQoreworICAgIHN1cGVyb2JqZWN0ICpzdSA9IChzdXBlcm9iamVjdCAqKXNlbGY7CisKKyAgICBpZiAoc3UtPm9ial90eXBlKQorICAgICAgICByZXR1cm4gUHlTdHJpbmdfRnJvbUZvcm1hdCgKKyAgICAgICAgICAgICI8c3VwZXI6IDxjbGFzcyAnJXMnPiwgPCVzIG9iamVjdD4+IiwKKyAgICAgICAgICAgIHN1LT50eXBlID8gc3UtPnR5cGUtPnRwX25hbWUgOiAiTlVMTCIsCisgICAgICAgICAgICBzdS0+b2JqX3R5cGUtPnRwX25hbWUpOworICAgIGVsc2UKKyAgICAgICAgcmV0dXJuIFB5U3RyaW5nX0Zyb21Gb3JtYXQoCisgICAgICAgICAgICAiPHN1cGVyOiA8Y2xhc3MgJyVzJz4sIE5VTEw+IiwKKyAgICAgICAgICAgIHN1LT50eXBlID8gc3UtPnR5cGUtPnRwX25hbWUgOiAiTlVMTCIpOworfQorCitzdGF0aWMgUHlPYmplY3QgKgorc3VwZXJfZ2V0YXR0cm8oUHlPYmplY3QgKnNlbGYsIFB5T2JqZWN0ICpuYW1lKQoreworICAgIHN1cGVyb2JqZWN0ICpzdSA9IChzdXBlcm9iamVjdCAqKXNlbGY7CisgICAgaW50IHNraXAgPSBzdS0+b2JqX3R5cGUgPT0gTlVMTDsKKworICAgIGlmICghc2tpcCkgeworICAgICAgICAvKiBXZSB3YW50IF9fY2xhc3NfXyB0byByZXR1cm4gdGhlIGNsYXNzIG9mIHRoZSBzdXBlciBvYmplY3QKKyAgICAgICAgICAgKGkuZS4gc3VwZXIsIG9yIGEgc3ViY2xhc3MpLCBub3QgdGhlIGNsYXNzIG9mIHN1LT5vYmouICovCisgICAgICAgIHNraXAgPSAoUHlTdHJpbmdfQ2hlY2sobmFtZSkgJiYKKyAgICAgICAgICAgIFB5U3RyaW5nX0dFVF9TSVpFKG5hbWUpID09IDkgJiYKKyAgICAgICAgICAgIHN0cmNtcChQeVN0cmluZ19BU19TVFJJTkcobmFtZSksICJfX2NsYXNzX18iKSA9PSAwKTsKKyAgICB9CisKKyAgICBpZiAoIXNraXApIHsKKyAgICAgICAgUHlPYmplY3QgKm1ybywgKnJlcywgKnRtcCwgKmRpY3Q7CisgICAgICAgIFB5VHlwZU9iamVjdCAqc3RhcnR0eXBlOworICAgICAgICBkZXNjcmdldGZ1bmMgZjsKKyAgICAgICAgUHlfc3NpemVfdCBpLCBuOworCisgICAgICAgIHN0YXJ0dHlwZSA9IHN1LT5vYmpfdHlwZTsKKyAgICAgICAgbXJvID0gc3RhcnR0eXBlLT50cF9tcm87CisKKyAgICAgICAgaWYgKG1ybyA9PSBOVUxMKQorICAgICAgICAgICAgbiA9IDA7CisgICAgICAgIGVsc2UgeworICAgICAgICAgICAgYXNzZXJ0KFB5VHVwbGVfQ2hlY2sobXJvKSk7CisgICAgICAgICAgICBuID0gUHlUdXBsZV9HRVRfU0laRShtcm8pOworICAgICAgICB9CisgICAgICAgIGZvciAoaSA9IDA7IGkgPCBuOyBpKyspIHsKKyAgICAgICAgICAgIGlmICgoUHlPYmplY3QgKikoc3UtPnR5cGUpID09IFB5VHVwbGVfR0VUX0lURU0obXJvLCBpKSkKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgfQorICAgICAgICBpKys7CisgICAgICAgIHJlcyA9IE5VTEw7CisgICAgICAgIGZvciAoOyBpIDwgbjsgaSsrKSB7CisgICAgICAgICAgICB0bXAgPSBQeVR1cGxlX0dFVF9JVEVNKG1ybywgaSk7CisgICAgICAgICAgICBpZiAoUHlUeXBlX0NoZWNrKHRtcCkpCisgICAgICAgICAgICAgICAgZGljdCA9ICgoUHlUeXBlT2JqZWN0ICopdG1wKS0+dHBfZGljdDsKKyAgICAgICAgICAgIGVsc2UgaWYgKFB5Q2xhc3NfQ2hlY2sodG1wKSkKKyAgICAgICAgICAgICAgICBkaWN0ID0gKChQeUNsYXNzT2JqZWN0ICopdG1wKS0+Y2xfZGljdDsKKyAgICAgICAgICAgIGVsc2UKKyAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgIHJlcyA9IFB5RGljdF9HZXRJdGVtKGRpY3QsIG5hbWUpOworICAgICAgICAgICAgaWYgKHJlcyAhPSBOVUxMKSB7CisgICAgICAgICAgICAgICAgUHlfSU5DUkVGKHJlcyk7CisgICAgICAgICAgICAgICAgZiA9IFB5X1RZUEUocmVzKS0+dHBfZGVzY3JfZ2V0OworICAgICAgICAgICAgICAgIGlmIChmICE9IE5VTEwpIHsKKyAgICAgICAgICAgICAgICAgICAgdG1wID0gZihyZXMsCisgICAgICAgICAgICAgICAgICAgICAgICAvKiBPbmx5IHBhc3MgJ29iaicgcGFyYW0gaWYKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMgaXMgaW5zdGFuY2UtbW9kZSBzdXBlcgorICAgICAgICAgICAgICAgICAgICAgICAgICAgKFNlZSBTRiBJRCAjNzQzNjI3KQorICAgICAgICAgICAgICAgICAgICAgICAgKi8KKyAgICAgICAgICAgICAgICAgICAgICAgIChzdS0+b2JqID09IChQeU9iamVjdCAqKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3UtPm9ial90eXBlCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgPyAoUHlPYmplY3QgKilOVUxMCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiBzdS0+b2JqKSwKKyAgICAgICAgICAgICAgICAgICAgICAgIChQeU9iamVjdCAqKXN0YXJ0dHlwZSk7CisgICAgICAgICAgICAgICAgICAgIFB5X0RFQ1JFRihyZXMpOworICAgICAgICAgICAgICAgICAgICByZXMgPSB0bXA7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHJldHVybiByZXM7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisgICAgcmV0dXJuIFB5T2JqZWN0X0dlbmVyaWNHZXRBdHRyKHNlbGYsIG5hbWUpOworfQorCitzdGF0aWMgUHlUeXBlT2JqZWN0ICoKK3N1cGVyY2hlY2soUHlUeXBlT2JqZWN0ICp0eXBlLCBQeU9iamVjdCAqb2JqKQoreworICAgIC8qIENoZWNrIHRoYXQgYSBzdXBlcigpIGNhbGwgbWFrZXMgc2Vuc2UuICBSZXR1cm4gYSB0eXBlIG9iamVjdC4KKworICAgICAgIG9iaiBjYW4gYmUgYSBuZXctc3R5bGUgY2xhc3MsIG9yIGFuIGluc3RhbmNlIG9mIG9uZToKKworICAgICAgIC0gSWYgaXQgaXMgYSBjbGFzcywgaXQgbXVzdCBiZSBhIHN1YmNsYXNzIG9mICd0eXBlJy4gICAgICBUaGlzIGNhc2UgaXMKKyAgICAgICAgIHVzZWQgZm9yIGNsYXNzIG1ldGhvZHM7IHRoZSByZXR1cm4gdmFsdWUgaXMgb2JqLgorCisgICAgICAgLSBJZiBpdCBpcyBhbiBpbnN0YW5jZSwgaXQgbXVzdCBiZSBhbiBpbnN0YW5jZSBvZiAndHlwZScuICBUaGlzIGlzCisgICAgICAgICB0aGUgbm9ybWFsIGNhc2U7IHRoZSByZXR1cm4gdmFsdWUgaXMgb2JqLl9fY2xhc3NfXy4KKworICAgICAgIEJ1dC4uLiB3aGVuIG9iaiBpcyBhbiBpbnN0YW5jZSwgd2Ugd2FudCB0byBhbGxvdyBmb3IgdGhlIGNhc2Ugd2hlcmUKKyAgICAgICBQeV9UWVBFKG9iaikgaXMgbm90IGEgc3ViY2xhc3Mgb2YgdHlwZSwgYnV0IG9iai5fX2NsYXNzX18gaXMhCisgICAgICAgVGhpcyB3aWxsIGFsbG93IHVzaW5nIHN1cGVyKCkgd2l0aCBhIHByb3h5IGZvciBvYmouCisgICAgKi8KKworICAgIC8qIENoZWNrIGZvciBmaXJzdCBidWxsZXQgYWJvdmUgKHNwZWNpYWwgY2FzZSkgKi8KKyAgICBpZiAoUHlUeXBlX0NoZWNrKG9iaikgJiYgUHlUeXBlX0lzU3VidHlwZSgoUHlUeXBlT2JqZWN0ICopb2JqLCB0eXBlKSkgeworICAgICAgICBQeV9JTkNSRUYob2JqKTsKKyAgICAgICAgcmV0dXJuIChQeVR5cGVPYmplY3QgKilvYmo7CisgICAgfQorCisgICAgLyogTm9ybWFsIGNhc2UgKi8KKyAgICBpZiAoUHlUeXBlX0lzU3VidHlwZShQeV9UWVBFKG9iaiksIHR5cGUpKSB7CisgICAgICAgIFB5X0lOQ1JFRihQeV9UWVBFKG9iaikpOworICAgICAgICByZXR1cm4gUHlfVFlQRShvYmopOworICAgIH0KKyAgICBlbHNlIHsKKyAgICAgICAgLyogVHJ5IHRoZSBzbG93IHdheSAqLworICAgICAgICBzdGF0aWMgUHlPYmplY3QgKmNsYXNzX3N0ciA9IE5VTEw7CisgICAgICAgIFB5T2JqZWN0ICpjbGFzc19hdHRyOworCisgICAgICAgIGlmIChjbGFzc19zdHIgPT0gTlVMTCkgeworICAgICAgICAgICAgY2xhc3Nfc3RyID0gUHlTdHJpbmdfRnJvbVN0cmluZygiX19jbGFzc19fIik7CisgICAgICAgICAgICBpZiAoY2xhc3Nfc3RyID09IE5VTEwpCisgICAgICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgICAgIH0KKworICAgICAgICBjbGFzc19hdHRyID0gUHlPYmplY3RfR2V0QXR0cihvYmosIGNsYXNzX3N0cik7CisKKyAgICAgICAgaWYgKGNsYXNzX2F0dHIgIT0gTlVMTCAmJgorICAgICAgICAgICAgUHlUeXBlX0NoZWNrKGNsYXNzX2F0dHIpICYmCisgICAgICAgICAgICAoUHlUeXBlT2JqZWN0ICopY2xhc3NfYXR0ciAhPSBQeV9UWVBFKG9iaikpCisgICAgICAgIHsKKyAgICAgICAgICAgIGludCBvayA9IFB5VHlwZV9Jc1N1YnR5cGUoCisgICAgICAgICAgICAgICAgKFB5VHlwZU9iamVjdCAqKWNsYXNzX2F0dHIsIHR5cGUpOworICAgICAgICAgICAgaWYgKG9rKQorICAgICAgICAgICAgICAgIHJldHVybiAoUHlUeXBlT2JqZWN0ICopY2xhc3NfYXR0cjsKKyAgICAgICAgfQorCisgICAgICAgIGlmIChjbGFzc19hdHRyID09IE5VTEwpCisgICAgICAgICAgICBQeUVycl9DbGVhcigpOworICAgICAgICBlbHNlCisgICAgICAgICAgICBQeV9ERUNSRUYoY2xhc3NfYXR0cik7CisgICAgfQorCisgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1R5cGVFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgInN1cGVyKHR5cGUsIG9iaik6ICIKKyAgICAgICAgICAgICAgICAgICAgIm9iaiBtdXN0IGJlIGFuIGluc3RhbmNlIG9yIHN1YnR5cGUgb2YgdHlwZSIpOworICAgIHJldHVybiBOVUxMOworfQorCitzdGF0aWMgUHlPYmplY3QgKgorc3VwZXJfZGVzY3JfZ2V0KFB5T2JqZWN0ICpzZWxmLCBQeU9iamVjdCAqb2JqLCBQeU9iamVjdCAqdHlwZSkKK3sKKyAgICBzdXBlcm9iamVjdCAqc3UgPSAoc3VwZXJvYmplY3QgKilzZWxmOworICAgIHN1cGVyb2JqZWN0ICpuZXdvYmo7CisKKyAgICBpZiAob2JqID09IE5VTEwgfHwgb2JqID09IFB5X05vbmUgfHwgc3UtPm9iaiAhPSBOVUxMKSB7CisgICAgICAgIC8qIE5vdCBiaW5kaW5nIHRvIGFuIG9iamVjdCwgb3IgYWxyZWFkeSBib3VuZCAqLworICAgICAgICBQeV9JTkNSRUYoc2VsZik7CisgICAgICAgIHJldHVybiBzZWxmOworICAgIH0KKyAgICBpZiAoUHlfVFlQRShzdSkgIT0gJlB5U3VwZXJfVHlwZSkKKyAgICAgICAgLyogSWYgc3UgaXMgYW4gaW5zdGFuY2Ugb2YgYSAoc3RyaWN0KSBzdWJjbGFzcyBvZiBzdXBlciwKKyAgICAgICAgICAgY2FsbCBpdHMgdHlwZSAqLworICAgICAgICByZXR1cm4gUHlPYmplY3RfQ2FsbEZ1bmN0aW9uT2JqQXJncygoUHlPYmplY3QgKilQeV9UWVBFKHN1KSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3UtPnR5cGUsIG9iaiwgTlVMTCk7CisgICAgZWxzZSB7CisgICAgICAgIC8qIElubGluZSB0aGUgY29tbW9uIGNhc2UgKi8KKyAgICAgICAgUHlUeXBlT2JqZWN0ICpvYmpfdHlwZSA9IHN1cGVyY2hlY2soc3UtPnR5cGUsIG9iaik7CisgICAgICAgIGlmIChvYmpfdHlwZSA9PSBOVUxMKQorICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgICAgIG5ld29iaiA9IChzdXBlcm9iamVjdCAqKVB5U3VwZXJfVHlwZS50cF9uZXcoJlB5U3VwZXJfVHlwZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOVUxMLCBOVUxMKTsKKyAgICAgICAgaWYgKG5ld29iaiA9PSBOVUxMKQorICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgICAgIFB5X0lOQ1JFRihzdS0+dHlwZSk7CisgICAgICAgIFB5X0lOQ1JFRihvYmopOworICAgICAgICBuZXdvYmotPnR5cGUgPSBzdS0+dHlwZTsKKyAgICAgICAgbmV3b2JqLT5vYmogPSBvYmo7CisgICAgICAgIG5ld29iai0+b2JqX3R5cGUgPSBvYmpfdHlwZTsKKyAgICAgICAgcmV0dXJuIChQeU9iamVjdCAqKW5ld29iajsKKyAgICB9Cit9CisKK3N0YXRpYyBpbnQKK3N1cGVyX2luaXQoUHlPYmplY3QgKnNlbGYsIFB5T2JqZWN0ICphcmdzLCBQeU9iamVjdCAqa3dkcykKK3sKKyAgICBzdXBlcm9iamVjdCAqc3UgPSAoc3VwZXJvYmplY3QgKilzZWxmOworICAgIFB5VHlwZU9iamVjdCAqdHlwZTsKKyAgICBQeU9iamVjdCAqb2JqID0gTlVMTDsKKyAgICBQeVR5cGVPYmplY3QgKm9ial90eXBlID0gTlVMTDsKKworICAgIGlmICghX1B5QXJnX05vS2V5d29yZHMoInN1cGVyIiwga3dkcykpCisgICAgICAgIHJldHVybiAtMTsKKyAgICBpZiAoIVB5QXJnX1BhcnNlVHVwbGUoYXJncywgIk8hfE86c3VwZXIiLCAmUHlUeXBlX1R5cGUsICZ0eXBlLCAmb2JqKSkKKyAgICAgICAgcmV0dXJuIC0xOworICAgIGlmIChvYmogPT0gUHlfTm9uZSkKKyAgICAgICAgb2JqID0gTlVMTDsKKyAgICBpZiAob2JqICE9IE5VTEwpIHsKKyAgICAgICAgb2JqX3R5cGUgPSBzdXBlcmNoZWNrKHR5cGUsIG9iaik7CisgICAgICAgIGlmIChvYmpfdHlwZSA9PSBOVUxMKQorICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICBQeV9JTkNSRUYob2JqKTsKKyAgICB9CisgICAgUHlfSU5DUkVGKHR5cGUpOworICAgIHN1LT50eXBlID0gdHlwZTsKKyAgICBzdS0+b2JqID0gb2JqOworICAgIHN1LT5vYmpfdHlwZSA9IG9ial90eXBlOworICAgIHJldHVybiAwOworfQorCitQeURvY19TVFJWQVIoc3VwZXJfZG9jLAorInN1cGVyKHR5cGUsIG9iaikgLT4gYm91bmQgc3VwZXIgb2JqZWN0OyByZXF1aXJlcyBpc2luc3RhbmNlKG9iaiwgdHlwZSlcbiIKKyJzdXBlcih0eXBlKSAtPiB1bmJvdW5kIHN1cGVyIG9iamVjdFxuIgorInN1cGVyKHR5cGUsIHR5cGUyKSAtPiBib3VuZCBzdXBlciBvYmplY3Q7IHJlcXVpcmVzIGlzc3ViY2xhc3ModHlwZTIsIHR5cGUpXG4iCisiVHlwaWNhbCB1c2UgdG8gY2FsbCBhIGNvb3BlcmF0aXZlIHN1cGVyY2xhc3MgbWV0aG9kOlxuIgorImNsYXNzIEMoQik6XG4iCisiICAgIGRlZiBtZXRoKHNlbGYsIGFyZyk6XG4iCisiICAgICAgICBzdXBlcihDLCBzZWxmKS5tZXRoKGFyZykiKTsKKworc3RhdGljIGludAorc3VwZXJfdHJhdmVyc2UoUHlPYmplY3QgKnNlbGYsIHZpc2l0cHJvYyB2aXNpdCwgdm9pZCAqYXJnKQoreworICAgIHN1cGVyb2JqZWN0ICpzdSA9IChzdXBlcm9iamVjdCAqKXNlbGY7CisKKyAgICBQeV9WSVNJVChzdS0+b2JqKTsKKyAgICBQeV9WSVNJVChzdS0+dHlwZSk7CisgICAgUHlfVklTSVQoc3UtPm9ial90eXBlKTsKKworICAgIHJldHVybiAwOworfQorCitQeVR5cGVPYmplY3QgUHlTdXBlcl9UeXBlID0geworICAgIFB5VmFyT2JqZWN0X0hFQURfSU5JVCgmUHlUeXBlX1R5cGUsIDApCisgICAgInN1cGVyIiwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9uYW1lICovCisgICAgc2l6ZW9mKHN1cGVyb2JqZWN0KSwgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9iYXNpY3NpemUgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2l0ZW1zaXplICovCisgICAgLyogbWV0aG9kcyAqLworICAgIHN1cGVyX2RlYWxsb2MsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZGVhbGxvYyAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfcHJpbnQgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2dldGF0dHIgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3NldGF0dHIgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2NvbXBhcmUgKi8KKyAgICBzdXBlcl9yZXByLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3JlcHIgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2FzX251bWJlciAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfYXNfc2VxdWVuY2UgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2FzX21hcHBpbmcgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2hhc2ggKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2NhbGwgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3N0ciAqLworICAgIHN1cGVyX2dldGF0dHJvLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZ2V0YXR0cm8gKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3NldGF0dHJvICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9hc19idWZmZXIgKi8KKyAgICBQeV9UUEZMQUdTX0RFRkFVTFQgfCBQeV9UUEZMQUdTX0hBVkVfR0MgfAorICAgICAgICBQeV9UUEZMQUdTX0JBU0VUWVBFLCAgICAgICAgICAgICAgICAgICAgLyogdHBfZmxhZ3MgKi8KKyAgICBzdXBlcl9kb2MsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2RvYyAqLworICAgIHN1cGVyX3RyYXZlcnNlLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfdHJhdmVyc2UgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2NsZWFyICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9yaWNoY29tcGFyZSAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfd2Vha2xpc3RvZmZzZXQgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2l0ZXIgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2l0ZXJuZXh0ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9tZXRob2RzICovCisgICAgc3VwZXJfbWVtYmVycywgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9tZW1iZXJzICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9nZXRzZXQgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2Jhc2UgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2RpY3QgKi8KKyAgICBzdXBlcl9kZXNjcl9nZXQsICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2Rlc2NyX2dldCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZGVzY3Jfc2V0ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9kaWN0b2Zmc2V0ICovCisgICAgc3VwZXJfaW5pdCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9pbml0ICovCisgICAgUHlUeXBlX0dlbmVyaWNBbGxvYywgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9hbGxvYyAqLworICAgIFB5VHlwZV9HZW5lcmljTmV3LCAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfbmV3ICovCisgICAgUHlPYmplY3RfR0NfRGVsLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9mcmVlICovCit9OwpkaWZmIC0tZ2l0IGEvUHl0aG9uLTIuNy41L09iamVjdHMvdW5pY29kZWN0eXBlLmMgYi9QeXRob24tMi43LjUvT2JqZWN0cy91bmljb2RlY3R5cGUuYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45YzQzOWE3Ci0tLSAvZGV2L251bGwKKysrIGIvUHl0aG9uLTIuNy41L09iamVjdHMvdW5pY29kZWN0eXBlLmMKQEAgLTAsMCArMSwyMTUgQEAKKy8qCisgICBVbmljb2RlIGNoYXJhY3RlciB0eXBlIGhlbHBlcnMuCisKKyAgIFdyaXR0ZW4gYnkgTWFyYy1BbmRyZSBMZW1idXJnIChtYWxAbGVtYnVyZy5jb20pLgorICAgTW9kaWZpZWQgZm9yIFB5dGhvbiAyLjAgYnkgRnJlZHJpayBMdW5kaCAoZnJlZHJpa0BweXRob253YXJlLmNvbSkKKworICAgQ29weXJpZ2h0IChjKSBDb3Jwb3JhdGlvbiBmb3IgTmF0aW9uYWwgUmVzZWFyY2ggSW5pdGlhdGl2ZXMuCisKKyovCisKKyNpbmNsdWRlICJQeXRob24uaCIKKyNpbmNsdWRlICJ1bmljb2Rlb2JqZWN0LmgiCisKKyNkZWZpbmUgQUxQSEFfTUFTSyAweDAxCisjZGVmaW5lIERFQ0lNQUxfTUFTSyAweDAyCisjZGVmaW5lIERJR0lUX01BU0sgMHgwNAorI2RlZmluZSBMT1dFUl9NQVNLIDB4MDgKKyNkZWZpbmUgTElORUJSRUFLX01BU0sgMHgxMAorI2RlZmluZSBTUEFDRV9NQVNLIDB4MjAKKyNkZWZpbmUgVElUTEVfTUFTSyAweDQwCisjZGVmaW5lIFVQUEVSX01BU0sgMHg4MAorI2RlZmluZSBOT0RFTFRBX01BU0sgMHgxMDAKKyNkZWZpbmUgTlVNRVJJQ19NQVNLIDB4MjAwCisKK3R5cGVkZWYgc3RydWN0IHsKKyAgICBjb25zdCBQeV9VTklDT0RFIHVwcGVyOworICAgIGNvbnN0IFB5X1VOSUNPREUgbG93ZXI7CisgICAgY29uc3QgUHlfVU5JQ09ERSB0aXRsZTsKKyAgICBjb25zdCB1bnNpZ25lZCBjaGFyIGRlY2ltYWw7CisgICAgY29uc3QgdW5zaWduZWQgY2hhciBkaWdpdDsKKyAgICBjb25zdCB1bnNpZ25lZCBzaG9ydCBmbGFnczsKK30gX1B5VW5pY29kZV9UeXBlUmVjb3JkOworCisjaW5jbHVkZSAidW5pY29kZXR5cGVfZGIuaCIKKworc3RhdGljIGNvbnN0IF9QeVVuaWNvZGVfVHlwZVJlY29yZCAqCitnZXR0eXBlcmVjb3JkKFB5X1VOSUNPREUgY29kZSkKK3sKKyAgICBpbnQgaW5kZXg7CisKKyNpZmRlZiBQeV9VTklDT0RFX1dJREUKKyAgICBpZiAoY29kZSA+PSAweDExMDAwMCkKKyAgICAgICAgaW5kZXggPSAwOworICAgIGVsc2UKKyNlbmRpZgorICAgIHsKKyAgICAgICAgaW5kZXggPSBpbmRleDFbKGNvZGU+PlNISUZUKV07CisgICAgICAgIGluZGV4ID0gaW5kZXgyWyhpbmRleDw8U0hJRlQpKyhjb2RlJigoMTw8U0hJRlQpLTEpKV07CisgICAgfQorCisgICAgcmV0dXJuICZfUHlVbmljb2RlX1R5cGVSZWNvcmRzW2luZGV4XTsKK30KKworLyogUmV0dXJucyB0aGUgdGl0bGVjYXNlIFVuaWNvZGUgY2hhcmFjdGVycyBjb3JyZXNwb25kaW5nIHRvIGNoIG9yIGp1c3QKKyAgIGNoIGlmIG5vIHRpdGxlY2FzZSBtYXBwaW5nIGlzIGtub3duLiAqLworCitQeV9VTklDT0RFIF9QeVVuaWNvZGVfVG9UaXRsZWNhc2UocmVnaXN0ZXIgUHlfVU5JQ09ERSBjaCkKK3sKKyAgICBjb25zdCBfUHlVbmljb2RlX1R5cGVSZWNvcmQgKmN0eXBlID0gZ2V0dHlwZXJlY29yZChjaCk7CisgICAgaW50IGRlbHRhID0gY3R5cGUtPnRpdGxlOworCisgICAgaWYgKGN0eXBlLT5mbGFncyAmIE5PREVMVEFfTUFTSykKKwlyZXR1cm4gZGVsdGE7CisKKyAgICBpZiAoZGVsdGEgPj0gMzI3NjgpCisJICAgIGRlbHRhIC09IDY1NTM2OworCisgICAgcmV0dXJuIGNoICsgZGVsdGE7Cit9CisKKy8qIFJldHVybnMgMSBmb3IgVW5pY29kZSBjaGFyYWN0ZXJzIGhhdmluZyB0aGUgY2F0ZWdvcnkgJ0x0JywgMAorICAgb3RoZXJ3aXNlLiAqLworCitpbnQgX1B5VW5pY29kZV9Jc1RpdGxlY2FzZShQeV9VTklDT0RFIGNoKQoreworICAgIGNvbnN0IF9QeVVuaWNvZGVfVHlwZVJlY29yZCAqY3R5cGUgPSBnZXR0eXBlcmVjb3JkKGNoKTsKKworICAgIHJldHVybiAoY3R5cGUtPmZsYWdzICYgVElUTEVfTUFTSykgIT0gMDsKK30KKworLyogUmV0dXJucyB0aGUgaW50ZWdlciBkZWNpbWFsICgwLTkpIGZvciBVbmljb2RlIGNoYXJhY3RlcnMgaGF2aW5nCisgICB0aGlzIHByb3BlcnR5LCAtMSBvdGhlcndpc2UuICovCisKK2ludCBfUHlVbmljb2RlX1RvRGVjaW1hbERpZ2l0KFB5X1VOSUNPREUgY2gpCit7CisgICAgY29uc3QgX1B5VW5pY29kZV9UeXBlUmVjb3JkICpjdHlwZSA9IGdldHR5cGVyZWNvcmQoY2gpOworCisgICAgcmV0dXJuIChjdHlwZS0+ZmxhZ3MgJiBERUNJTUFMX01BU0spID8gY3R5cGUtPmRlY2ltYWwgOiAtMTsKK30KKworaW50IF9QeVVuaWNvZGVfSXNEZWNpbWFsRGlnaXQoUHlfVU5JQ09ERSBjaCkKK3sKKyAgICBpZiAoX1B5VW5pY29kZV9Ub0RlY2ltYWxEaWdpdChjaCkgPCAwKQorCXJldHVybiAwOworICAgIHJldHVybiAxOworfQorCisvKiBSZXR1cm5zIHRoZSBpbnRlZ2VyIGRpZ2l0ICgwLTkpIGZvciBVbmljb2RlIGNoYXJhY3RlcnMgaGF2aW5nCisgICB0aGlzIHByb3BlcnR5LCAtMSBvdGhlcndpc2UuICovCisKK2ludCBfUHlVbmljb2RlX1RvRGlnaXQoUHlfVU5JQ09ERSBjaCkKK3sKKyAgICBjb25zdCBfUHlVbmljb2RlX1R5cGVSZWNvcmQgKmN0eXBlID0gZ2V0dHlwZXJlY29yZChjaCk7CisKKyAgICByZXR1cm4gKGN0eXBlLT5mbGFncyAmIERJR0lUX01BU0spID8gY3R5cGUtPmRpZ2l0IDogLTE7Cit9CisKK2ludCBfUHlVbmljb2RlX0lzRGlnaXQoUHlfVU5JQ09ERSBjaCkKK3sKKyAgICBpZiAoX1B5VW5pY29kZV9Ub0RpZ2l0KGNoKSA8IDApCisJcmV0dXJuIDA7CisgICAgcmV0dXJuIDE7Cit9CisKKy8qIFJldHVybnMgdGhlIG51bWVyaWMgdmFsdWUgYXMgZG91YmxlIGZvciBVbmljb2RlIGNoYXJhY3RlcnMgaGF2aW5nCisgICB0aGlzIHByb3BlcnR5LCAtMS4wIG90aGVyd2lzZS4gKi8KKworaW50IF9QeVVuaWNvZGVfSXNOdW1lcmljKFB5X1VOSUNPREUgY2gpCit7CisgICAgY29uc3QgX1B5VW5pY29kZV9UeXBlUmVjb3JkICpjdHlwZSA9IGdldHR5cGVyZWNvcmQoY2gpOworCisgICAgcmV0dXJuIChjdHlwZS0+ZmxhZ3MgJiBOVU1FUklDX01BU0spICE9IDA7Cit9CisKKyNpZm5kZWYgV0FOVF9XQ1RZUEVfRlVOQ1RJT05TCisKKy8qIFJldHVybnMgMSBmb3IgVW5pY29kZSBjaGFyYWN0ZXJzIGhhdmluZyB0aGUgY2F0ZWdvcnkgJ0xsJywgMAorICAgb3RoZXJ3aXNlLiAqLworCitpbnQgX1B5VW5pY29kZV9Jc0xvd2VyY2FzZShQeV9VTklDT0RFIGNoKQoreworICAgIGNvbnN0IF9QeVVuaWNvZGVfVHlwZVJlY29yZCAqY3R5cGUgPSBnZXR0eXBlcmVjb3JkKGNoKTsKKworICAgIHJldHVybiAoY3R5cGUtPmZsYWdzICYgTE9XRVJfTUFTSykgIT0gMDsKK30KKworLyogUmV0dXJucyAxIGZvciBVbmljb2RlIGNoYXJhY3RlcnMgaGF2aW5nIHRoZSBjYXRlZ29yeSAnTHUnLCAwCisgICBvdGhlcndpc2UuICovCisKK2ludCBfUHlVbmljb2RlX0lzVXBwZXJjYXNlKFB5X1VOSUNPREUgY2gpCit7CisgICAgY29uc3QgX1B5VW5pY29kZV9UeXBlUmVjb3JkICpjdHlwZSA9IGdldHR5cGVyZWNvcmQoY2gpOworCisgICAgcmV0dXJuIChjdHlwZS0+ZmxhZ3MgJiBVUFBFUl9NQVNLKSAhPSAwOworfQorCisvKiBSZXR1cm5zIHRoZSB1cHBlcmNhc2UgVW5pY29kZSBjaGFyYWN0ZXJzIGNvcnJlc3BvbmRpbmcgdG8gY2ggb3IganVzdAorICAgY2ggaWYgbm8gdXBwZXJjYXNlIG1hcHBpbmcgaXMga25vd24uICovCisKK1B5X1VOSUNPREUgX1B5VW5pY29kZV9Ub1VwcGVyY2FzZShQeV9VTklDT0RFIGNoKQoreworICAgIGNvbnN0IF9QeVVuaWNvZGVfVHlwZVJlY29yZCAqY3R5cGUgPSBnZXR0eXBlcmVjb3JkKGNoKTsKKyAgICBpbnQgZGVsdGEgPSBjdHlwZS0+dXBwZXI7CisgICAgaWYgKGN0eXBlLT5mbGFncyAmIE5PREVMVEFfTUFTSykKKwlyZXR1cm4gZGVsdGE7CisgICAgaWYgKGRlbHRhID49IDMyNzY4KQorCSAgICBkZWx0YSAtPSA2NTUzNjsKKyAgICByZXR1cm4gY2ggKyBkZWx0YTsKK30KKworLyogUmV0dXJucyB0aGUgbG93ZXJjYXNlIFVuaWNvZGUgY2hhcmFjdGVycyBjb3JyZXNwb25kaW5nIHRvIGNoIG9yIGp1c3QKKyAgIGNoIGlmIG5vIGxvd2VyY2FzZSBtYXBwaW5nIGlzIGtub3duLiAqLworCitQeV9VTklDT0RFIF9QeVVuaWNvZGVfVG9Mb3dlcmNhc2UoUHlfVU5JQ09ERSBjaCkKK3sKKyAgICBjb25zdCBfUHlVbmljb2RlX1R5cGVSZWNvcmQgKmN0eXBlID0gZ2V0dHlwZXJlY29yZChjaCk7CisgICAgaW50IGRlbHRhID0gY3R5cGUtPmxvd2VyOworICAgIGlmIChjdHlwZS0+ZmxhZ3MgJiBOT0RFTFRBX01BU0spCisJcmV0dXJuIGRlbHRhOworICAgIGlmIChkZWx0YSA+PSAzMjc2OCkKKwkgICAgZGVsdGEgLT0gNjU1MzY7CisgICAgcmV0dXJuIGNoICsgZGVsdGE7Cit9CisKKy8qIFJldHVybnMgMSBmb3IgVW5pY29kZSBjaGFyYWN0ZXJzIGhhdmluZyB0aGUgY2F0ZWdvcnkgJ0xsJywgJ0x1JywgJ0x0JywKKyAgICdMbycgb3IgJ0xtJywgIDAgb3RoZXJ3aXNlLiAqLworCitpbnQgX1B5VW5pY29kZV9Jc0FscGhhKFB5X1VOSUNPREUgY2gpCit7CisgICAgY29uc3QgX1B5VW5pY29kZV9UeXBlUmVjb3JkICpjdHlwZSA9IGdldHR5cGVyZWNvcmQoY2gpOworCisgICAgcmV0dXJuIChjdHlwZS0+ZmxhZ3MgJiBBTFBIQV9NQVNLKSAhPSAwOworfQorCisjZWxzZQorCisvKiBFeHBvcnQgdGhlIGludGVyZmFjZXMgdXNpbmcgdGhlIHdjaGFyX3QgdHlwZSBmb3IgcG9ydGFiaWxpdHkKKyAgIHJlYXNvbnM6ICAqLworCitpbnQgX1B5VW5pY29kZV9Jc0xvd2VyY2FzZShQeV9VTklDT0RFIGNoKQoreworICAgIHJldHVybiBpc3dsb3dlcihjaCk7Cit9CisKK2ludCBfUHlVbmljb2RlX0lzVXBwZXJjYXNlKFB5X1VOSUNPREUgY2gpCit7CisgICAgcmV0dXJuIGlzd3VwcGVyKGNoKTsKK30KKworUHlfVU5JQ09ERSBfUHlVbmljb2RlX1RvTG93ZXJjYXNlKFB5X1VOSUNPREUgY2gpCit7CisgICAgcmV0dXJuIHRvd2xvd2VyKGNoKTsKK30KKworUHlfVU5JQ09ERSBfUHlVbmljb2RlX1RvVXBwZXJjYXNlKFB5X1VOSUNPREUgY2gpCit7CisgICAgcmV0dXJuIHRvd3VwcGVyKGNoKTsKK30KKworaW50IF9QeVVuaWNvZGVfSXNBbHBoYShQeV9VTklDT0RFIGNoKQoreworICAgIHJldHVybiBpc3dhbHBoYShjaCk7Cit9CisKKyNlbmRpZgpkaWZmIC0tZ2l0IGEvUHl0aG9uLTIuNy41L09iamVjdHMvdW5pY29kZW9iamVjdC5jIGIvUHl0aG9uLTIuNy41L09iamVjdHMvdW5pY29kZW9iamVjdC5jCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjBlYWQwNmYKLS0tIC9kZXYvbnVsbAorKysgYi9QeXRob24tMi43LjUvT2JqZWN0cy91bmljb2Rlb2JqZWN0LmMKQEAgLTAsMCArMSw4OTA2IEBACisvKgorCitVbmljb2RlIGltcGxlbWVudGF0aW9uIGJhc2VkIG9uIG9yaWdpbmFsIGNvZGUgYnkgRnJlZHJpayBMdW5kaCwKK21vZGlmaWVkIGJ5IE1hcmMtQW5kcmUgTGVtYnVyZyA8bWFsQGxlbWJ1cmcuY29tPiBhY2NvcmRpbmcgdG8gdGhlCitVbmljb2RlIEludGVncmF0aW9uIFByb3Bvc2FsIChzZWUgZmlsZSBNaXNjL3VuaWNvZGUudHh0KS4KKworTWFqb3Igc3BlZWQgdXBncmFkZXMgdG8gdGhlIG1ldGhvZCBpbXBsZW1lbnRhdGlvbnMgYXQgdGhlIFJleWtqYXZpaworTmVlZEZvclNwZWVkIHNwcmludCwgYnkgRnJlZHJpayBMdW5kaCBhbmQgQW5kcmV3IERhbGtlLgorCitDb3B5cmlnaHQgKGMpIENvcnBvcmF0aW9uIGZvciBOYXRpb25hbCBSZXNlYXJjaCBJbml0aWF0aXZlcy4KKworLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KK1RoZSBvcmlnaW5hbCBzdHJpbmcgdHlwZSBpbXBsZW1lbnRhdGlvbiBpczoKKworICBDb3B5cmlnaHQgKGMpIDE5OTkgYnkgU2VjcmV0IExhYnMgQUIKKyAgQ29weXJpZ2h0IChjKSAxOTk5IGJ5IEZyZWRyaWsgTHVuZGgKKworQnkgb2J0YWluaW5nLCB1c2luZywgYW5kL29yIGNvcHlpbmcgdGhpcyBzb2Z0d2FyZSBhbmQvb3IgaXRzCithc3NvY2lhdGVkIGRvY3VtZW50YXRpb24sIHlvdSBhZ3JlZSB0aGF0IHlvdSBoYXZlIHJlYWQsIHVuZGVyc3Rvb2QsCithbmQgd2lsbCBjb21wbHkgd2l0aCB0aGUgZm9sbG93aW5nIHRlcm1zIGFuZCBjb25kaXRpb25zOgorCitQZXJtaXNzaW9uIHRvIHVzZSwgY29weSwgbW9kaWZ5LCBhbmQgZGlzdHJpYnV0ZSB0aGlzIHNvZnR3YXJlIGFuZCBpdHMKK2Fzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmb3IgYW55IHB1cnBvc2UgYW5kIHdpdGhvdXQgZmVlIGlzIGhlcmVieQorZ3JhbnRlZCwgcHJvdmlkZWQgdGhhdCB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhcHBlYXJzIGluIGFsbAorY29waWVzLCBhbmQgdGhhdCBib3RoIHRoYXQgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZQorYXBwZWFyIGluIHN1cHBvcnRpbmcgZG9jdW1lbnRhdGlvbiwgYW5kIHRoYXQgdGhlIG5hbWUgb2YgU2VjcmV0IExhYnMKK0FCIG9yIHRoZSBhdXRob3Igbm90IGJlIHVzZWQgaW4gYWR2ZXJ0aXNpbmcgb3IgcHVibGljaXR5IHBlcnRhaW5pbmcgdG8KK2Rpc3RyaWJ1dGlvbiBvZiB0aGUgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYywgd3JpdHRlbiBwcmlvcgorcGVybWlzc2lvbi4KKworU0VDUkVUIExBQlMgQUIgQU5EIFRIRSBBVVRIT1IgRElTQ0xBSU1TIEFMTCBXQVJSQU5USUVTIFdJVEggUkVHQVJEIFRPCitUSElTIFNPRlRXQVJFLCBJTkNMVURJTkcgQUxMIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5ECitGSVRORVNTLiAgSU4gTk8gRVZFTlQgU0hBTEwgU0VDUkVUIExBQlMgQUIgT1IgVEhFIEFVVEhPUiBCRSBMSUFCTEUgRk9SCitBTlkgU1BFQ0lBTCwgSU5ESVJFQ1QgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIE9SIEFOWSBEQU1BR0VTCitXSEFUU09FVkVSIFJFU1VMVElORyBGUk9NIExPU1MgT0YgVVNFLCBEQVRBIE9SIFBST0ZJVFMsIFdIRVRIRVIgSU4gQU4KK0FDVElPTiBPRiBDT05UUkFDVCwgTkVHTElHRU5DRSBPUiBPVEhFUiBUT1JUSU9VUyBBQ1RJT04sIEFSSVNJTkcgT1VUCitPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFVTRSBPUiBQRVJGT1JNQU5DRSBPRiBUSElTIFNPRlRXQVJFLgorLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKworKi8KKworI2RlZmluZSBQWV9TU0laRV9UX0NMRUFOCisjaW5jbHVkZSAiUHl0aG9uLmgiCisKKyNpbmNsdWRlICJ1bmljb2Rlb2JqZWN0LmgiCisjaW5jbHVkZSAidWNuaGFzaC5oIgorCisjaWZkZWYgTVNfV0lORE9XUworI2luY2x1ZGUgPHdpbmRvd3MuaD4KKyNlbmRpZgorCisvKiBMaW1pdCBmb3IgdGhlIFVuaWNvZGUgb2JqZWN0IGZyZWUgbGlzdCAqLworCisjZGVmaW5lIFB5VW5pY29kZV9NQVhGUkVFTElTVCAgICAgICAxMDI0CisKKy8qIExpbWl0IGZvciB0aGUgVW5pY29kZSBvYmplY3QgZnJlZSBsaXN0IHN0YXkgYWxpdmUgb3B0aW1pemF0aW9uLgorCisgICBUaGUgaW1wbGVtZW50YXRpb24gd2lsbCBrZWVwIGFsbG9jYXRlZCBVbmljb2RlIG1lbW9yeSBpbnRhY3QgZm9yCisgICBhbGwgb2JqZWN0cyBvbiB0aGUgZnJlZSBsaXN0IGhhdmluZyBhIHNpemUgbGVzcyB0aGFuIHRoaXMKKyAgIGxpbWl0LiBUaGlzIHJlZHVjZXMgbWFsbG9jKCkgb3ZlcmhlYWQgZm9yIHNtYWxsIFVuaWNvZGUgb2JqZWN0cy4KKworICAgQXQgd29yc3QgdGhpcyB3aWxsIHJlc3VsdCBpbiBQeVVuaWNvZGVfTUFYRlJFRUxJU1QgKgorICAgKHNpemVvZihQeVVuaWNvZGVPYmplY3QpICsgS0VFUEFMSVZFX1NJWkVfTElNSVQgKworICAgbWFsbG9jKCktb3ZlcmhlYWQpIGJ5dGVzIG9mIHVudXNlZCBnYXJiYWdlLgorCisgICBTZXR0aW5nIHRoZSBsaW1pdCB0byAwIGVmZmVjdGl2ZWx5IHR1cm5zIHRoZSBmZWF0dXJlIG9mZi4KKworICAgTm90ZTogVGhpcyBpcyBhbiBleHBlcmltZW50YWwgZmVhdHVyZSAhIElmIHlvdSBnZXQgY29yZSBkdW1wcyB3aGVuCisgICB1c2luZyBVbmljb2RlIG9iamVjdHMsIHR1cm4gdGhpcyBmZWF0dXJlIG9mZi4KKworKi8KKworI2RlZmluZSBLRUVQQUxJVkVfU0laRV9MSU1JVCAgICAgICA5CisKKy8qIEVuZGlhbm5lc3Mgc3dpdGNoZXM7IGRlZmF1bHRzIHRvIGxpdHRsZSBlbmRpYW4gKi8KKworI2lmZGVmIFdPUkRTX0JJR0VORElBTgorIyBkZWZpbmUgQllURU9SREVSX0lTX0JJR19FTkRJQU4KKyNlbHNlCisjIGRlZmluZSBCWVRFT1JERVJfSVNfTElUVExFX0VORElBTgorI2VuZGlmCisKKy8qIC0tLSBHbG9iYWxzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQorCitOT1RFOiBJbiB0aGUgaW50ZXJwcmV0ZXIncyBpbml0aWFsaXphdGlvbiBwaGFzZSwgc29tZSBnbG9iYWxzIGFyZSBjdXJyZW50bHkKKyAgICAgIGluaXRpYWxpemVkIGR5bmFtaWNhbGx5IGFzIG5lZWRlZC4gSW4gdGhlIHByb2Nlc3MgVW5pY29kZSBvYmplY3RzIG1heQorICAgICAgYmUgY3JlYXRlZCBiZWZvcmUgdGhlIFVuaWNvZGUgdHlwZSBpcyByZWFkeS4KKworKi8KKworCisjaWZkZWYgX19jcGx1c3BsdXMKK2V4dGVybiAiQyIgeworI2VuZGlmCisKKy8qIEZyZWUgbGlzdCBmb3IgVW5pY29kZSBvYmplY3RzICovCitzdGF0aWMgUHlVbmljb2RlT2JqZWN0ICpmcmVlX2xpc3QgPSBOVUxMOworc3RhdGljIGludCBudW1mcmVlID0gMDsKKworLyogVGhlIGVtcHR5IFVuaWNvZGUgb2JqZWN0IGlzIHNoYXJlZCB0byBpbXByb3ZlIHBlcmZvcm1hbmNlLiAqLworc3RhdGljIFB5VW5pY29kZU9iamVjdCAqdW5pY29kZV9lbXB0eSA9IE5VTEw7CisKKyNkZWZpbmUgX1B5X1JFVFVSTl9VTklDT0RFX0VNUFRZKCkgICAgICAgICAgICAgICAgICAgICAgXAorICAgIGRvIHsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgIGlmICh1bmljb2RlX2VtcHR5ICE9IE5VTEwpICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgICAgIFB5X0lOQ1JFRih1bmljb2RlX2VtcHR5KTsgICAgICAgICAgICAgICAgICAgXAorICAgICAgICBlbHNlIHsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgICAgICB1bmljb2RlX2VtcHR5ID0gX1B5VW5pY29kZV9OZXcoMCk7ICAgICAgICAgIFwKKyAgICAgICAgICAgIGlmICh1bmljb2RlX2VtcHR5ICE9IE5VTEwpICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgICAgICAgIFB5X0lOQ1JFRih1bmljb2RlX2VtcHR5KTsgICAgICAgICAgICAgICBcCisgICAgICAgIH0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgICAgcmV0dXJuIChQeU9iamVjdCAqKXVuaWNvZGVfZW1wdHk7ICAgICAgICAgICAgICAgXAorICAgIH0gd2hpbGUgKDApCisKKy8qIFNpbmdsZSBjaGFyYWN0ZXIgVW5pY29kZSBzdHJpbmdzIGluIHRoZSBMYXRpbi0xIHJhbmdlIGFyZSBiZWluZworICAgc2hhcmVkIGFzIHdlbGwuICovCitzdGF0aWMgUHlVbmljb2RlT2JqZWN0ICp1bmljb2RlX2xhdGluMVsyNTZdID0ge05VTEx9OworCisvKiBEZWZhdWx0IGVuY29kaW5nIHRvIHVzZSBhbmQgYXNzdW1lIHdoZW4gTlVMTCBpcyBwYXNzZWQgYXMgZW5jb2RpbmcKKyAgIHBhcmFtZXRlcjsgaXQgaXMgaW5pdGlhbGl6ZWQgYnkgX1B5VW5pY29kZV9Jbml0KCkuCisKKyAgIEFsd2F5cyB1c2UgdGhlIFB5VW5pY29kZV9TZXREZWZhdWx0RW5jb2RpbmcoKSBhbmQKKyAgIFB5VW5pY29kZV9HZXREZWZhdWx0RW5jb2RpbmcoKSBBUElzIHRvIGFjY2VzcyB0aGlzIGdsb2JhbC4KKworKi8KK3N0YXRpYyBjaGFyIHVuaWNvZGVfZGVmYXVsdF9lbmNvZGluZ1sxMDAgKyAxXSA9ICJhc2NpaSI7CisKKy8qIEZhc3QgZGV0ZWN0aW9uIG9mIHRoZSBtb3N0IGZyZXF1ZW50IHdoaXRlc3BhY2UgY2hhcmFjdGVycyAqLworY29uc3QgdW5zaWduZWQgY2hhciBfUHlfYXNjaWlfd2hpdGVzcGFjZVtdID0geworICAgIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsCisvKiAgICAgY2FzZSAweDAwMDk6ICogQ0hBUkFDVEVSIFRBQlVMQVRJT04gKi8KKy8qICAgICBjYXNlIDB4MDAwQTogKiBMSU5FIEZFRUQgKi8KKy8qICAgICBjYXNlIDB4MDAwQjogKiBMSU5FIFRBQlVMQVRJT04gKi8KKy8qICAgICBjYXNlIDB4MDAwQzogKiBGT1JNIEZFRUQgKi8KKy8qICAgICBjYXNlIDB4MDAwRDogKiBDQVJSSUFHRSBSRVRVUk4gKi8KKyAgICAwLCAxLCAxLCAxLCAxLCAxLCAwLCAwLAorICAgIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsCisvKiAgICAgY2FzZSAweDAwMUM6ICogRklMRSBTRVBBUkFUT1IgKi8KKy8qICAgICBjYXNlIDB4MDAxRDogKiBHUk9VUCBTRVBBUkFUT1IgKi8KKy8qICAgICBjYXNlIDB4MDAxRTogKiBSRUNPUkQgU0VQQVJBVE9SICovCisvKiAgICAgY2FzZSAweDAwMUY6ICogVU5JVCBTRVBBUkFUT1IgKi8KKyAgICAwLCAwLCAwLCAwLCAxLCAxLCAxLCAxLAorLyogICAgIGNhc2UgMHgwMDIwOiAqIFNQQUNFICovCisgICAgMSwgMCwgMCwgMCwgMCwgMCwgMCwgMCwKKyAgICAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLAorICAgIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsCisgICAgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwKKworICAgIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsCisgICAgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwKKyAgICAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLAorICAgIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsCisgICAgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwKKyAgICAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLAorICAgIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsCisgICAgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMAorfTsKKworLyogU2FtZSBmb3IgbGluZWJyZWFrcyAqLworc3RhdGljIHVuc2lnbmVkIGNoYXIgYXNjaWlfbGluZWJyZWFrW10gPSB7CisgICAgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwKKy8qICAgICAgICAgMHgwMDBBLCAqIExJTkUgRkVFRCAqLworLyogICAgICAgICAweDAwMEIsICogTElORSBUQUJVTEFUSU9OICovCisvKiAgICAgICAgIDB4MDAwQywgKiBGT1JNIEZFRUQgKi8KKy8qICAgICAgICAgMHgwMDBELCAqIENBUlJJQUdFIFJFVFVSTiAqLworICAgIDAsIDAsIDEsIDEsIDEsIDEsIDAsIDAsCisgICAgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwKKy8qICAgICAgICAgMHgwMDFDLCAqIEZJTEUgU0VQQVJBVE9SICovCisvKiAgICAgICAgIDB4MDAxRCwgKiBHUk9VUCBTRVBBUkFUT1IgKi8KKy8qICAgICAgICAgMHgwMDFFLCAqIFJFQ09SRCBTRVBBUkFUT1IgKi8KKyAgICAwLCAwLCAwLCAwLCAxLCAxLCAxLCAwLAorICAgIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsCisgICAgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwKKyAgICAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLAorICAgIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsCisKKyAgICAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLAorICAgIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsCisgICAgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwKKyAgICAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLAorICAgIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsCisgICAgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwKKyAgICAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLAorICAgIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAKK307CisKKworUHlfVU5JQ09ERQorUHlVbmljb2RlX0dldE1heCh2b2lkKQoreworI2lmZGVmIFB5X1VOSUNPREVfV0lERQorICAgIHJldHVybiAweDEwRkZGRjsKKyNlbHNlCisgICAgLyogVGhpcyBpcyBhY3R1YWxseSBhbiBpbGxlZ2FsIGNoYXJhY3Rlciwgc28gaXQgc2hvdWxkCisgICAgICAgbm90IGJlIHBhc3NlZCB0byB1bmljaHIuICovCisgICAgcmV0dXJuIDB4RkZGRjsKKyNlbmRpZgorfQorCisvKiAtLS0gQmxvb20gRmlsdGVycyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLworCisvKiBzdHVmZiB0byBpbXBsZW1lbnQgc2ltcGxlICJibG9vbSBmaWx0ZXJzIiBmb3IgVW5pY29kZSBjaGFyYWN0ZXJzLgorICAgdG8ga2VlcCB0aGluZ3Mgc2ltcGxlLCB3ZSB1c2UgYSBzaW5nbGUgYml0bWFzaywgdXNpbmcgdGhlIGxlYXN0IDUKKyAgIGJpdHMgZnJvbSBlYWNoIHVuaWNvZGUgY2hhcmFjdGVycyBhcyB0aGUgYml0IGluZGV4LiAqLworCisvKiB0aGUgbGluZWJyZWFrIG1hc2sgaXMgc2V0IHVwIGJ5IFVuaWNvZGVfSW5pdCBiZWxvdyAqLworCisjaWYgTE9OR19CSVQgPj0gMTI4CisjZGVmaW5lIEJMT09NX1dJRFRIIDEyOAorI2VsaWYgTE9OR19CSVQgPj0gNjQKKyNkZWZpbmUgQkxPT01fV0lEVEggNjQKKyNlbGlmIExPTkdfQklUID49IDMyCisjZGVmaW5lIEJMT09NX1dJRFRIIDMyCisjZWxzZQorI2Vycm9yICJMT05HX0JJVCBpcyBzbWFsbGVyIHRoYW4gMzIiCisjZW5kaWYKKworI2RlZmluZSBCTE9PTV9NQVNLIHVuc2lnbmVkIGxvbmcKKworc3RhdGljIEJMT09NX01BU0sgYmxvb21fbGluZWJyZWFrID0gfihCTE9PTV9NQVNLKTA7CisKKyNkZWZpbmUgQkxPT01fQUREKG1hc2ssIGNoKSAoKG1hc2sgfD0gKDFVTCA8PCAoKGNoKSAmIChCTE9PTV9XSURUSCAtIDEpKSkpKQorI2RlZmluZSBCTE9PTShtYXNrLCBjaCkgICAgICgobWFzayAmICAoMVVMIDw8ICgoY2gpICYgKEJMT09NX1dJRFRIIC0gMSkpKSkpCisKKyNkZWZpbmUgQkxPT01fTElORUJSRUFLKGNoKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAoKGNoKSA8IDEyOFUgPyBhc2NpaV9saW5lYnJlYWtbKGNoKV0gOiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKyAgICAgKEJMT09NKGJsb29tX2xpbmVicmVhaywgKGNoKSkgJiYgUHlfVU5JQ09ERV9JU0xJTkVCUkVBSyhjaCkpKQorCitQeV9MT0NBTF9JTkxJTkUoQkxPT01fTUFTSykgbWFrZV9ibG9vbV9tYXNrKFB5X1VOSUNPREUqIHB0ciwgUHlfc3NpemVfdCBsZW4pCit7CisgICAgLyogY2FsY3VsYXRlIHNpbXBsZSBibG9vbS1zdHlsZSBiaXRtYXNrIGZvciBhIGdpdmVuIHVuaWNvZGUgc3RyaW5nICovCisKKyAgICBCTE9PTV9NQVNLIG1hc2s7CisgICAgUHlfc3NpemVfdCBpOworCisgICAgbWFzayA9IDA7CisgICAgZm9yIChpID0gMDsgaSA8IGxlbjsgaSsrKQorICAgICAgICBCTE9PTV9BREQobWFzaywgcHRyW2ldKTsKKworICAgIHJldHVybiBtYXNrOworfQorCitQeV9MT0NBTF9JTkxJTkUoaW50KSB1bmljb2RlX21lbWJlcihQeV9VTklDT0RFIGNociwgUHlfVU5JQ09ERSogc2V0LCBQeV9zc2l6ZV90IHNldGxlbikKK3sKKyAgICBQeV9zc2l6ZV90IGk7CisKKyAgICBmb3IgKGkgPSAwOyBpIDwgc2V0bGVuOyBpKyspCisgICAgICAgIGlmIChzZXRbaV0gPT0gY2hyKQorICAgICAgICAgICAgcmV0dXJuIDE7CisKKyAgICByZXR1cm4gMDsKK30KKworI2RlZmluZSBCTE9PTV9NRU1CRVIobWFzaywgY2hyLCBzZXQsIHNldGxlbikgICAgICAgICAgICAgICAgICAgIFwKKyAgICBCTE9PTShtYXNrLCBjaHIpICYmIHVuaWNvZGVfbWVtYmVyKGNociwgc2V0LCBzZXRsZW4pCisKKy8qIC0tLSBVbmljb2RlIE9iamVjdCAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLworCitzdGF0aWMKK2ludCB1bmljb2RlX3Jlc2l6ZShyZWdpc3RlciBQeVVuaWNvZGVPYmplY3QgKnVuaWNvZGUsCisgICAgICAgICAgICAgICAgICAgUHlfc3NpemVfdCBsZW5ndGgpCit7CisgICAgdm9pZCAqb2xkc3RyOworCisgICAgLyogU2hvcnRjdXQgaWYgdGhlcmUncyBub3RoaW5nIG11Y2ggdG8gZG8uICovCisgICAgaWYgKHVuaWNvZGUtPmxlbmd0aCA9PSBsZW5ndGgpCisgICAgICAgIGdvdG8gcmVzZXQ7CisKKyAgICAvKiBSZXNpemluZyBzaGFyZWQgb2JqZWN0ICh1bmljb2RlX2VtcHR5IG9yIHNpbmdsZSBjaGFyYWN0ZXIKKyAgICAgICBvYmplY3RzKSBpbi1wbGFjZSBpcyBub3QgYWxsb3dlZC4gVXNlIFB5VW5pY29kZV9SZXNpemUoKQorICAgICAgIGluc3RlYWQgISAqLworCisgICAgaWYgKHVuaWNvZGUgPT0gdW5pY29kZV9lbXB0eSB8fAorICAgICAgICAodW5pY29kZS0+bGVuZ3RoID09IDEgJiYKKyAgICAgICAgIHVuaWNvZGUtPnN0clswXSA8IDI1NlUgJiYKKyAgICAgICAgIHVuaWNvZGVfbGF0aW4xW3VuaWNvZGUtPnN0clswXV0gPT0gdW5pY29kZSkpIHsKKyAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1N5c3RlbUVycm9yLAorICAgICAgICAgICAgICAgICAgICAgICAgImNhbid0IHJlc2l6ZSBzaGFyZWQgdW5pY29kZSBvYmplY3RzIik7CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisKKyAgICAvKiBXZSBhbGxvY2F0ZSBvbmUgbW9yZSBieXRlIHRvIG1ha2Ugc3VyZSB0aGUgc3RyaW5nIGlzIFV4MDAwMCB0ZXJtaW5hdGVkLgorICAgICAgIFRoZSBvdmVyYWxsb2NhdGlvbiBpcyBhbHNvIHVzZWQgYnkgZmFzdHNlYXJjaCwgd2hpY2ggYXNzdW1lcyB0aGF0IGl0J3MKKyAgICAgICBzYWZlIHRvIGxvb2sgYXQgc3RyW2xlbmd0aF0gKHdpdGhvdXQgbWFraW5nIGFueSBhc3N1bXB0aW9ucyBhYm91dCB3aGF0CisgICAgICAgaXQgY29udGFpbnMpLiAqLworCisgICAgb2xkc3RyID0gdW5pY29kZS0+c3RyOworICAgIHVuaWNvZGUtPnN0ciA9IFB5T2JqZWN0X1JFQUxMT0ModW5pY29kZS0+c3RyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZW9mKFB5X1VOSUNPREUpICogKGxlbmd0aCArIDEpKTsKKyAgICBpZiAoIXVuaWNvZGUtPnN0cikgeworICAgICAgICB1bmljb2RlLT5zdHIgPSAoUHlfVU5JQ09ERSAqKW9sZHN0cjsKKyAgICAgICAgUHlFcnJfTm9NZW1vcnkoKTsKKyAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKyAgICB1bmljb2RlLT5zdHJbbGVuZ3RoXSA9IDA7CisgICAgdW5pY29kZS0+bGVuZ3RoID0gbGVuZ3RoOworCisgIHJlc2V0OgorICAgIC8qIFJlc2V0IHRoZSBvYmplY3QgY2FjaGVzICovCisgICAgaWYgKHVuaWNvZGUtPmRlZmVuYykgeworICAgICAgICBQeV9DTEVBUih1bmljb2RlLT5kZWZlbmMpOworICAgIH0KKyAgICB1bmljb2RlLT5oYXNoID0gLTE7CisKKyAgICByZXR1cm4gMDsKK30KKworLyogV2UgYWxsb2NhdGUgb25lIG1vcmUgYnl0ZSB0byBtYWtlIHN1cmUgdGhlIHN0cmluZyBpcworICAgVXgwMDAwIHRlcm1pbmF0ZWQ7IHNvbWUgY29kZSByZWxpZXMgb24gdGhhdC4KKworICAgWFhYIFRoaXMgYWxsb2NhdG9yIGNvdWxkIGZ1cnRoZXIgYmUgZW5oYW5jZWQgYnkgYXNzdXJpbmcgdGhhdCB0aGUKKyAgIGZyZWUgbGlzdCBuZXZlciByZWR1Y2VzIGl0cyBzaXplIGJlbG93IDEuCisKKyovCisKK3N0YXRpYworUHlVbmljb2RlT2JqZWN0ICpfUHlVbmljb2RlX05ldyhQeV9zc2l6ZV90IGxlbmd0aCkKK3sKKyAgICByZWdpc3RlciBQeVVuaWNvZGVPYmplY3QgKnVuaWNvZGU7CisKKyAgICAvKiBPcHRpbWl6YXRpb24gZm9yIGVtcHR5IHN0cmluZ3MgKi8KKyAgICBpZiAobGVuZ3RoID09IDAgJiYgdW5pY29kZV9lbXB0eSAhPSBOVUxMKSB7CisgICAgICAgIFB5X0lOQ1JFRih1bmljb2RlX2VtcHR5KTsKKyAgICAgICAgcmV0dXJuIHVuaWNvZGVfZW1wdHk7CisgICAgfQorCisgICAgLyogRW5zdXJlIHdlIHdvbid0IG92ZXJmbG93IHRoZSBzaXplLiAqLworICAgIGlmIChsZW5ndGggPiAoKFBZX1NTSVpFX1RfTUFYIC8gc2l6ZW9mKFB5X1VOSUNPREUpKSAtIDEpKSB7CisgICAgICAgIHJldHVybiAoUHlVbmljb2RlT2JqZWN0ICopUHlFcnJfTm9NZW1vcnkoKTsKKyAgICB9CisKKyAgICAvKiBVbmljb2RlIGZyZWVsaXN0ICYgbWVtb3J5IGFsbG9jYXRpb24gKi8KKyAgICBpZiAoZnJlZV9saXN0KSB7CisgICAgICAgIHVuaWNvZGUgPSBmcmVlX2xpc3Q7CisgICAgICAgIGZyZWVfbGlzdCA9ICooUHlVbmljb2RlT2JqZWN0ICoqKXVuaWNvZGU7CisgICAgICAgIG51bWZyZWUtLTsKKyAgICAgICAgaWYgKHVuaWNvZGUtPnN0cikgeworICAgICAgICAgICAgLyogS2VlcC1BbGl2ZSBvcHRpbWl6YXRpb246IHdlIG9ubHkgdXBzaXplIHRoZSBidWZmZXIsCisgICAgICAgICAgICAgICBuZXZlciBkb3duc2l6ZSBpdC4gKi8KKyAgICAgICAgICAgIGlmICgodW5pY29kZS0+bGVuZ3RoIDwgbGVuZ3RoKSAmJgorICAgICAgICAgICAgICAgIHVuaWNvZGVfcmVzaXplKHVuaWNvZGUsIGxlbmd0aCkgPCAwKSB7CisgICAgICAgICAgICAgICAgUHlPYmplY3RfREVMKHVuaWNvZGUtPnN0cik7CisgICAgICAgICAgICAgICAgdW5pY29kZS0+c3RyID0gTlVMTDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBlbHNlIHsKKyAgICAgICAgICAgIHNpemVfdCBuZXdfc2l6ZSA9IHNpemVvZihQeV9VTklDT0RFKSAqICgoc2l6ZV90KWxlbmd0aCArIDEpOworICAgICAgICAgICAgdW5pY29kZS0+c3RyID0gKFB5X1VOSUNPREUqKSBQeU9iamVjdF9NQUxMT0MobmV3X3NpemUpOworICAgICAgICB9CisgICAgICAgIFB5T2JqZWN0X0lOSVQodW5pY29kZSwgJlB5VW5pY29kZV9UeXBlKTsKKyAgICB9CisgICAgZWxzZSB7CisgICAgICAgIHNpemVfdCBuZXdfc2l6ZTsKKyAgICAgICAgdW5pY29kZSA9IFB5T2JqZWN0X05ldyhQeVVuaWNvZGVPYmplY3QsICZQeVVuaWNvZGVfVHlwZSk7CisgICAgICAgIGlmICh1bmljb2RlID09IE5VTEwpCisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgbmV3X3NpemUgPSBzaXplb2YoUHlfVU5JQ09ERSkgKiAoKHNpemVfdClsZW5ndGggKyAxKTsKKyAgICAgICAgdW5pY29kZS0+c3RyID0gKFB5X1VOSUNPREUqKSBQeU9iamVjdF9NQUxMT0MobmV3X3NpemUpOworICAgIH0KKworICAgIGlmICghdW5pY29kZS0+c3RyKSB7CisgICAgICAgIFB5RXJyX05vTWVtb3J5KCk7CisgICAgICAgIGdvdG8gb25FcnJvcjsKKyAgICB9CisgICAgLyogSW5pdGlhbGl6ZSB0aGUgZmlyc3QgZWxlbWVudCB0byBndWFyZCBhZ2FpbnN0IGNhc2VzIHdoZXJlCisgICAgICogdGhlIGNhbGxlciBmYWlscyBiZWZvcmUgaW5pdGlhbGl6aW5nIHN0ciAtLSB1bmljb2RlX3Jlc2l6ZSgpCisgICAgICogcmVhZHMgc3RyWzBdLCBhbmQgdGhlIEtlZXAtQWxpdmUgb3B0aW1pemF0aW9uIGNhbiBrZWVwIG1lbW9yeQorICAgICAqIGFsbG9jYXRlZCBmb3Igc3RyIGFsaXZlIGFjcm9zcyBhIGNhbGwgdG8gdW5pY29kZV9kZWFsbG9jKHVuaWNvZGUpLgorICAgICAqIFdlIGRvbid0IHdhbnQgdW5pY29kZV9yZXNpemUgdG8gcmVhZCB1bmluaXRpYWxpemVkIG1lbW9yeSBpbgorICAgICAqIHRoYXQgY2FzZS4KKyAgICAgKi8KKyAgICB1bmljb2RlLT5zdHJbMF0gPSAwOworICAgIHVuaWNvZGUtPnN0cltsZW5ndGhdID0gMDsKKyAgICB1bmljb2RlLT5sZW5ndGggPSBsZW5ndGg7CisgICAgdW5pY29kZS0+aGFzaCA9IC0xOworICAgIHVuaWNvZGUtPmRlZmVuYyA9IE5VTEw7CisgICAgcmV0dXJuIHVuaWNvZGU7CisKKyAgb25FcnJvcjoKKyAgICAvKiBYWFggVU5SRUYvTkVXUkVGIGludGVyZmFjZSBzaG91bGQgYmUgbW9yZSBzeW1tZXRyaWNhbCAqLworICAgIF9QeV9ERUNfUkVGVE9UQUw7CisgICAgX1B5X0ZvcmdldFJlZmVyZW5jZSgoUHlPYmplY3QgKil1bmljb2RlKTsKKyAgICBQeU9iamVjdF9EZWwodW5pY29kZSk7CisgICAgcmV0dXJuIE5VTEw7Cit9CisKK3N0YXRpYwordm9pZCB1bmljb2RlX2RlYWxsb2MocmVnaXN0ZXIgUHlVbmljb2RlT2JqZWN0ICp1bmljb2RlKQoreworICAgIGlmIChQeVVuaWNvZGVfQ2hlY2tFeGFjdCh1bmljb2RlKSAmJgorICAgICAgICBudW1mcmVlIDwgUHlVbmljb2RlX01BWEZSRUVMSVNUKSB7CisgICAgICAgIC8qIEtlZXAtQWxpdmUgb3B0aW1pemF0aW9uICovCisgICAgICAgIGlmICh1bmljb2RlLT5sZW5ndGggPj0gS0VFUEFMSVZFX1NJWkVfTElNSVQpIHsKKyAgICAgICAgICAgIFB5T2JqZWN0X0RFTCh1bmljb2RlLT5zdHIpOworICAgICAgICAgICAgdW5pY29kZS0+c3RyID0gTlVMTDsKKyAgICAgICAgICAgIHVuaWNvZGUtPmxlbmd0aCA9IDA7CisgICAgICAgIH0KKyAgICAgICAgaWYgKHVuaWNvZGUtPmRlZmVuYykgeworICAgICAgICAgICAgUHlfQ0xFQVIodW5pY29kZS0+ZGVmZW5jKTsKKyAgICAgICAgfQorICAgICAgICAvKiBBZGQgdG8gZnJlZSBsaXN0ICovCisgICAgICAgICooUHlVbmljb2RlT2JqZWN0ICoqKXVuaWNvZGUgPSBmcmVlX2xpc3Q7CisgICAgICAgIGZyZWVfbGlzdCA9IHVuaWNvZGU7CisgICAgICAgIG51bWZyZWUrKzsKKyAgICB9CisgICAgZWxzZSB7CisgICAgICAgIFB5T2JqZWN0X0RFTCh1bmljb2RlLT5zdHIpOworICAgICAgICBQeV9YREVDUkVGKHVuaWNvZGUtPmRlZmVuYyk7CisgICAgICAgIFB5X1RZUEUodW5pY29kZSktPnRwX2ZyZWUoKFB5T2JqZWN0ICopdW5pY29kZSk7CisgICAgfQorfQorCitzdGF0aWMKK2ludCBfUHlVbmljb2RlX1Jlc2l6ZShQeVVuaWNvZGVPYmplY3QgKip1bmljb2RlLCBQeV9zc2l6ZV90IGxlbmd0aCkKK3sKKyAgICByZWdpc3RlciBQeVVuaWNvZGVPYmplY3QgKnY7CisKKyAgICAvKiBBcmd1bWVudCBjaGVja3MgKi8KKyAgICBpZiAodW5pY29kZSA9PSBOVUxMKSB7CisgICAgICAgIFB5RXJyX0JhZEludGVybmFsQ2FsbCgpOworICAgICAgICByZXR1cm4gLTE7CisgICAgfQorICAgIHYgPSAqdW5pY29kZTsKKyAgICBpZiAodiA9PSBOVUxMIHx8ICFQeVVuaWNvZGVfQ2hlY2sodikgfHwgUHlfUkVGQ05UKHYpICE9IDEgfHwgbGVuZ3RoIDwgMCkgeworICAgICAgICBQeUVycl9CYWRJbnRlcm5hbENhbGwoKTsKKyAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKworICAgIC8qIFJlc2l6aW5nIHVuaWNvZGVfZW1wdHkgYW5kIHNpbmdsZSBjaGFyYWN0ZXIgb2JqZWN0cyBpcyBub3QKKyAgICAgICBwb3NzaWJsZSBzaW5jZSB0aGVzZSBhcmUgYmVpbmcgc2hhcmVkLiBXZSBzaW1wbHkgcmV0dXJuIGEgZnJlc2gKKyAgICAgICBjb3B5IHdpdGggdGhlIHNhbWUgVW5pY29kZSBjb250ZW50LiAqLworICAgIGlmICh2LT5sZW5ndGggIT0gbGVuZ3RoICYmCisgICAgICAgICh2ID09IHVuaWNvZGVfZW1wdHkgfHwgdi0+bGVuZ3RoID09IDEpKSB7CisgICAgICAgIFB5VW5pY29kZU9iamVjdCAqdyA9IF9QeVVuaWNvZGVfTmV3KGxlbmd0aCk7CisgICAgICAgIGlmICh3ID09IE5VTEwpCisgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgIFB5X1VOSUNPREVfQ09QWSh3LT5zdHIsIHYtPnN0ciwKKyAgICAgICAgICAgICAgICAgICAgICAgIGxlbmd0aCA8IHYtPmxlbmd0aCA/IGxlbmd0aCA6IHYtPmxlbmd0aCk7CisgICAgICAgIFB5X0RFQ1JFRigqdW5pY29kZSk7CisgICAgICAgICp1bmljb2RlID0gdzsKKyAgICAgICAgcmV0dXJuIDA7CisgICAgfQorCisgICAgLyogTm90ZSB0aGF0IHdlIGRvbid0IGhhdmUgdG8gbW9kaWZ5ICp1bmljb2RlIGZvciB1bnNoYXJlZCBVbmljb2RlCisgICAgICAgb2JqZWN0cywgc2luY2Ugd2UgY2FuIG1vZGlmeSB0aGVtIGluLXBsYWNlLiAqLworICAgIHJldHVybiB1bmljb2RlX3Jlc2l6ZSh2LCBsZW5ndGgpOworfQorCitpbnQgUHlVbmljb2RlX1Jlc2l6ZShQeU9iamVjdCAqKnVuaWNvZGUsIFB5X3NzaXplX3QgbGVuZ3RoKQoreworICAgIHJldHVybiBfUHlVbmljb2RlX1Jlc2l6ZSgoUHlVbmljb2RlT2JqZWN0ICoqKXVuaWNvZGUsIGxlbmd0aCk7Cit9CisKK1B5T2JqZWN0ICpQeVVuaWNvZGVfRnJvbVVuaWNvZGUoY29uc3QgUHlfVU5JQ09ERSAqdSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHlfc3NpemVfdCBzaXplKQoreworICAgIFB5VW5pY29kZU9iamVjdCAqdW5pY29kZTsKKworICAgIC8qIElmIHRoZSBVbmljb2RlIGRhdGEgaXMga25vd24gYXQgY29uc3RydWN0aW9uIHRpbWUsIHdlIGNhbiBhcHBseQorICAgICAgIHNvbWUgb3B0aW1pemF0aW9ucyB3aGljaCBzaGFyZSBjb21tb25seSB1c2VkIG9iamVjdHMuICovCisgICAgaWYgKHUgIT0gTlVMTCkgeworCisgICAgICAgIC8qIE9wdGltaXphdGlvbiBmb3IgZW1wdHkgc3RyaW5ncyAqLworICAgICAgICBpZiAoc2l6ZSA9PSAwKQorICAgICAgICAgICAgX1B5X1JFVFVSTl9VTklDT0RFX0VNUFRZKCk7CisKKyAgICAgICAgLyogU2luZ2xlIGNoYXJhY3RlciBVbmljb2RlIG9iamVjdHMgaW4gdGhlIExhdGluLTEgcmFuZ2UgYXJlCisgICAgICAgICAgIHNoYXJlZCB3aGVuIHVzaW5nIHRoaXMgY29uc3RydWN0b3IgKi8KKyAgICAgICAgaWYgKHNpemUgPT0gMSAmJiAqdSA8IDI1NikgeworICAgICAgICAgICAgdW5pY29kZSA9IHVuaWNvZGVfbGF0aW4xWyp1XTsKKyAgICAgICAgICAgIGlmICghdW5pY29kZSkgeworICAgICAgICAgICAgICAgIHVuaWNvZGUgPSBfUHlVbmljb2RlX05ldygxKTsKKyAgICAgICAgICAgICAgICBpZiAoIXVuaWNvZGUpCisgICAgICAgICAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgICAgICAgICAgICAgIHVuaWNvZGUtPnN0clswXSA9ICp1OworICAgICAgICAgICAgICAgIHVuaWNvZGVfbGF0aW4xWyp1XSA9IHVuaWNvZGU7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBQeV9JTkNSRUYodW5pY29kZSk7CisgICAgICAgICAgICByZXR1cm4gKFB5T2JqZWN0ICopdW5pY29kZTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHVuaWNvZGUgPSBfUHlVbmljb2RlX05ldyhzaXplKTsKKyAgICBpZiAoIXVuaWNvZGUpCisgICAgICAgIHJldHVybiBOVUxMOworCisgICAgLyogQ29weSB0aGUgVW5pY29kZSBkYXRhIGludG8gdGhlIG5ldyBvYmplY3QgKi8KKyAgICBpZiAodSAhPSBOVUxMKQorICAgICAgICBQeV9VTklDT0RFX0NPUFkodW5pY29kZS0+c3RyLCB1LCBzaXplKTsKKworICAgIHJldHVybiAoUHlPYmplY3QgKil1bmljb2RlOworfQorCitQeU9iamVjdCAqUHlVbmljb2RlX0Zyb21TdHJpbmdBbmRTaXplKGNvbnN0IGNoYXIgKnUsIFB5X3NzaXplX3Qgc2l6ZSkKK3sKKyAgICBQeVVuaWNvZGVPYmplY3QgKnVuaWNvZGU7CisKKyAgICBpZiAoc2l6ZSA8IDApIHsKKyAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1N5c3RlbUVycm9yLAorICAgICAgICAgICAgICAgICAgICAgICAgIk5lZ2F0aXZlIHNpemUgcGFzc2VkIHRvIFB5VW5pY29kZV9Gcm9tU3RyaW5nQW5kU2l6ZSIpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisKKyAgICAvKiBJZiB0aGUgVW5pY29kZSBkYXRhIGlzIGtub3duIGF0IGNvbnN0cnVjdGlvbiB0aW1lLCB3ZSBjYW4gYXBwbHkKKyAgICAgICBzb21lIG9wdGltaXphdGlvbnMgd2hpY2ggc2hhcmUgY29tbW9ubHkgdXNlZCBvYmplY3RzLgorICAgICAgIEFsc28sIHRoaXMgbWVhbnMgdGhlIGlucHV0IG11c3QgYmUgVVRGLTgsIHNvIGZhbGwgYmFjayB0byB0aGUKKyAgICAgICBVVEYtOCBkZWNvZGVyIGF0IHRoZSBlbmQuICovCisgICAgaWYgKHUgIT0gTlVMTCkgeworCisgICAgICAgIC8qIE9wdGltaXphdGlvbiBmb3IgZW1wdHkgc3RyaW5ncyAqLworICAgICAgICBpZiAoc2l6ZSA9PSAwKQorICAgICAgICAgICAgX1B5X1JFVFVSTl9VTklDT0RFX0VNUFRZKCk7CisKKyAgICAgICAgLyogU2luZ2xlIGNoYXJhY3RlcnMgYXJlIHNoYXJlZCB3aGVuIHVzaW5nIHRoaXMgY29uc3RydWN0b3IuCisgICAgICAgICAgIFJlc3RyaWN0IHRvIEFTQ0lJLCBzaW5jZSB0aGUgaW5wdXQgbXVzdCBiZSBVVEYtOC4gKi8KKyAgICAgICAgaWYgKHNpemUgPT0gMSAmJiBQeV9DSEFSTUFTSygqdSkgPCAxMjgpIHsKKyAgICAgICAgICAgIHVuaWNvZGUgPSB1bmljb2RlX2xhdGluMVtQeV9DSEFSTUFTSygqdSldOworICAgICAgICAgICAgaWYgKCF1bmljb2RlKSB7CisgICAgICAgICAgICAgICAgdW5pY29kZSA9IF9QeVVuaWNvZGVfTmV3KDEpOworICAgICAgICAgICAgICAgIGlmICghdW5pY29kZSkKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgICAgICAgICAgICAgdW5pY29kZS0+c3RyWzBdID0gUHlfQ0hBUk1BU0soKnUpOworICAgICAgICAgICAgICAgIHVuaWNvZGVfbGF0aW4xW1B5X0NIQVJNQVNLKCp1KV0gPSB1bmljb2RlOworICAgICAgICAgICAgfQorICAgICAgICAgICAgUHlfSU5DUkVGKHVuaWNvZGUpOworICAgICAgICAgICAgcmV0dXJuIChQeU9iamVjdCAqKXVuaWNvZGU7CisgICAgICAgIH0KKworICAgICAgICByZXR1cm4gUHlVbmljb2RlX0RlY29kZVVURjgodSwgc2l6ZSwgTlVMTCk7CisgICAgfQorCisgICAgdW5pY29kZSA9IF9QeVVuaWNvZGVfTmV3KHNpemUpOworICAgIGlmICghdW5pY29kZSkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisKKyAgICByZXR1cm4gKFB5T2JqZWN0ICopdW5pY29kZTsKK30KKworUHlPYmplY3QgKlB5VW5pY29kZV9Gcm9tU3RyaW5nKGNvbnN0IGNoYXIgKnUpCit7CisgICAgc2l6ZV90IHNpemUgPSBzdHJsZW4odSk7CisgICAgaWYgKHNpemUgPiBQWV9TU0laRV9UX01BWCkgeworICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfT3ZlcmZsb3dFcnJvciwgImlucHV0IHRvbyBsb25nIik7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKworICAgIHJldHVybiBQeVVuaWNvZGVfRnJvbVN0cmluZ0FuZFNpemUodSwgc2l6ZSk7Cit9CisKKyNpZmRlZiBIQVZFX1dDSEFSX0gKKworI2lmIChQeV9VTklDT0RFX1NJWkUgPT0gMikgJiYgZGVmaW5lZChTSVpFT0ZfV0NIQVJfVCkgJiYgKFNJWkVPRl9XQ0hBUl9UID09IDQpCisjIGRlZmluZSBDT05WRVJUX1dDSEFSX1RPX1NVUlJPR0FURVMKKyNlbmRpZgorCisjaWZkZWYgQ09OVkVSVF9XQ0hBUl9UT19TVVJST0dBVEVTCisKKy8qIEhlcmUgc2l6ZW9mKHdjaGFyX3QpIGlzIDQgYnV0IFB5X1VOSUNPREVfU0laRSA9PSAyLCBzbyB3ZSBuZWVkCisgICB0byBjb252ZXJ0IGZyb20gVVRGMzIgdG8gVVRGMTYuICovCisKK1B5T2JqZWN0ICpQeVVuaWNvZGVfRnJvbVdpZGVDaGFyKHJlZ2lzdGVyIGNvbnN0IHdjaGFyX3QgKncsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQeV9zc2l6ZV90IHNpemUpCit7CisgICAgUHlVbmljb2RlT2JqZWN0ICp1bmljb2RlOworICAgIHJlZ2lzdGVyIFB5X3NzaXplX3QgaTsKKyAgICBQeV9zc2l6ZV90IGFsbG9jOworICAgIGNvbnN0IHdjaGFyX3QgKm9yaWdfdzsKKworICAgIGlmICh3ID09IE5VTEwpIHsKKyAgICAgICAgUHlFcnJfQmFkSW50ZXJuYWxDYWxsKCk7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKworICAgIGFsbG9jID0gc2l6ZTsKKyAgICBvcmlnX3cgPSB3OworICAgIGZvciAoaSA9IHNpemU7IGkgPiAwOyBpLS0pIHsKKyAgICAgICAgaWYgKCp3ID4gMHhGRkZGKQorICAgICAgICAgICAgYWxsb2MrKzsKKyAgICAgICAgdysrOworICAgIH0KKyAgICB3ID0gb3JpZ193OworICAgIHVuaWNvZGUgPSBfUHlVbmljb2RlX05ldyhhbGxvYyk7CisgICAgaWYgKCF1bmljb2RlKQorICAgICAgICByZXR1cm4gTlVMTDsKKworICAgIC8qIENvcHkgdGhlIHdjaGFyX3QgZGF0YSBpbnRvIHRoZSBuZXcgb2JqZWN0ICovCisgICAgeworICAgICAgICByZWdpc3RlciBQeV9VTklDT0RFICp1OworICAgICAgICB1ID0gUHlVbmljb2RlX0FTX1VOSUNPREUodW5pY29kZSk7CisgICAgICAgIGZvciAoaSA9IHNpemU7IGkgPiAwOyBpLS0pIHsKKyAgICAgICAgICAgIGlmICgqdyA+IDB4RkZGRikgeworICAgICAgICAgICAgICAgIHdjaGFyX3Qgb3JkaW5hbCA9ICp3Kys7CisgICAgICAgICAgICAgICAgb3JkaW5hbCAtPSAweDEwMDAwOworICAgICAgICAgICAgICAgICp1KysgPSAweEQ4MDAgfCAob3JkaW5hbCA+PiAxMCk7CisgICAgICAgICAgICAgICAgKnUrKyA9IDB4REMwMCB8IChvcmRpbmFsICYgMHgzRkYpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgZWxzZQorICAgICAgICAgICAgICAgICp1KysgPSAqdysrOworICAgICAgICB9CisgICAgfQorICAgIHJldHVybiAoUHlPYmplY3QgKil1bmljb2RlOworfQorCisjZWxzZQorCitQeU9iamVjdCAqUHlVbmljb2RlX0Zyb21XaWRlQ2hhcihyZWdpc3RlciBjb25zdCB3Y2hhcl90ICp3LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHlfc3NpemVfdCBzaXplKQoreworICAgIFB5VW5pY29kZU9iamVjdCAqdW5pY29kZTsKKworICAgIGlmICh3ID09IE5VTEwpIHsKKyAgICAgICAgUHlFcnJfQmFkSW50ZXJuYWxDYWxsKCk7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKworICAgIHVuaWNvZGUgPSBfUHlVbmljb2RlX05ldyhzaXplKTsKKyAgICBpZiAoIXVuaWNvZGUpCisgICAgICAgIHJldHVybiBOVUxMOworCisgICAgLyogQ29weSB0aGUgd2NoYXJfdCBkYXRhIGludG8gdGhlIG5ldyBvYmplY3QgKi8KKyNpZmRlZiBIQVZFX1VTQUJMRV9XQ0hBUl9UCisgICAgbWVtY3B5KHVuaWNvZGUtPnN0ciwgdywgc2l6ZSAqIHNpemVvZih3Y2hhcl90KSk7CisjZWxzZQorICAgIHsKKyAgICAgICAgcmVnaXN0ZXIgUHlfVU5JQ09ERSAqdTsKKyAgICAgICAgcmVnaXN0ZXIgUHlfc3NpemVfdCBpOworICAgICAgICB1ID0gUHlVbmljb2RlX0FTX1VOSUNPREUodW5pY29kZSk7CisgICAgICAgIGZvciAoaSA9IHNpemU7IGkgPiAwOyBpLS0pCisgICAgICAgICAgICAqdSsrID0gKncrKzsKKyAgICB9CisjZW5kaWYKKworICAgIHJldHVybiAoUHlPYmplY3QgKil1bmljb2RlOworfQorCisjZW5kaWYgLyogQ09OVkVSVF9XQ0hBUl9UT19TVVJST0dBVEVTICovCisKKyN1bmRlZiBDT05WRVJUX1dDSEFSX1RPX1NVUlJPR0FURVMKKworc3RhdGljIHZvaWQKK21ha2VmbXQoY2hhciAqZm10LCBpbnQgbG9uZ2ZsYWcsIGludCBzaXplX3RmbGFnLCBpbnQgemVyb3BhZCwgaW50IHdpZHRoLCBpbnQgcHJlY2lzaW9uLCBjaGFyIGMpCit7CisgICAgKmZtdCsrID0gJyUnOworICAgIGlmICh3aWR0aCkgeworICAgICAgICBpZiAoemVyb3BhZCkKKyAgICAgICAgICAgICpmbXQrKyA9ICcwJzsKKyAgICAgICAgZm10ICs9IHNwcmludGYoZm10LCAiJWQiLCB3aWR0aCk7CisgICAgfQorICAgIGlmIChwcmVjaXNpb24pCisgICAgICAgIGZtdCArPSBzcHJpbnRmKGZtdCwgIi4lZCIsIHByZWNpc2lvbik7CisgICAgaWYgKGxvbmdmbGFnKQorICAgICAgICAqZm10KysgPSAnbCc7CisgICAgZWxzZSBpZiAoc2l6ZV90ZmxhZykgeworICAgICAgICBjaGFyICpmID0gUFlfRk9STUFUX1NJWkVfVDsKKyAgICAgICAgd2hpbGUgKCpmKQorICAgICAgICAgICAgKmZtdCsrID0gKmYrKzsKKyAgICB9CisgICAgKmZtdCsrID0gYzsKKyAgICAqZm10ID0gJ1wwJzsKK30KKworI2RlZmluZSBhcHBlbmRzdHJpbmcoc3RyaW5nKSB7Zm9yIChjb3B5ID0gc3RyaW5nOypjb3B5OykgKnMrKyA9ICpjb3B5Kys7fQorCitQeU9iamVjdCAqCitQeVVuaWNvZGVfRnJvbUZvcm1hdFYoY29uc3QgY2hhciAqZm9ybWF0LCB2YV9saXN0IHZhcmdzKQoreworICAgIHZhX2xpc3QgY291bnQ7CisgICAgUHlfc3NpemVfdCBjYWxsY291bnQgPSAwOworICAgIFB5T2JqZWN0ICoqY2FsbHJlc3VsdHMgPSBOVUxMOworICAgIFB5T2JqZWN0ICoqY2FsbHJlc3VsdCA9IE5VTEw7CisgICAgUHlfc3NpemVfdCBuID0gMDsKKyAgICBpbnQgd2lkdGggPSAwOworICAgIGludCBwcmVjaXNpb24gPSAwOworICAgIGludCB6ZXJvcGFkOworICAgIGNvbnN0IGNoYXIqIGY7CisgICAgUHlfVU5JQ09ERSAqczsKKyAgICBQeU9iamVjdCAqc3RyaW5nOworICAgIC8qIHVzZWQgYnkgc3ByaW50ZiAqLworICAgIGNoYXIgYnVmZmVyWzIxXTsKKyAgICAvKiB1c2UgYWJ1ZmZlciBpbnN0ZWFkIG9mIGJ1ZmZlciwgaWYgd2UgbmVlZCBtb3JlIHNwYWNlCisgICAgICogKHdoaWNoIGNhbiBoYXBwZW4gaWYgdGhlcmUncyBhIGZvcm1hdCBzcGVjaWZpZXIgd2l0aCB3aWR0aCkuICovCisgICAgY2hhciAqYWJ1ZmZlciA9IE5VTEw7CisgICAgY2hhciAqcmVhbGJ1ZmZlcjsKKyAgICBQeV9zc2l6ZV90IGFidWZmZXJzaXplID0gMDsKKyAgICBjaGFyIGZtdFs2MF07IC8qIHNob3VsZCBiZSBlbm91Z2ggZm9yICUwd2lkdGgucHJlY2lzaW9ubGQgKi8KKyAgICBjb25zdCBjaGFyICpjb3B5OworCisjaWZkZWYgVkFfTElTVF9JU19BUlJBWQorICAgIFB5X01FTUNQWShjb3VudCwgdmFyZ3MsIHNpemVvZih2YV9saXN0KSk7CisjZWxzZQorI2lmZGVmICBfX3ZhX2NvcHkKKyAgICBfX3ZhX2NvcHkoY291bnQsIHZhcmdzKTsKKyNlbHNlCisgICAgY291bnQgPSB2YXJnczsKKyNlbmRpZgorI2VuZGlmCisgICAgIC8qIHN0ZXAgMTogY291bnQgdGhlIG51bWJlciBvZiAlUy8lUi8lcyBmb3JtYXQgc3BlY2lmaWNhdGlvbnMKKyAgICAgICogKHdlIGNhbGwgUHlPYmplY3RfU3RyKCkvUHlPYmplY3RfUmVwcigpL1B5VW5pY29kZV9EZWNvZGVVVEY4KCkgZm9yIHRoZXNlCisgICAgICAqIG9iamVjdHMgb25jZSBkdXJpbmcgc3RlcCAzIGFuZCBwdXQgdGhlIHJlc3VsdCBpbiBhbiBhcnJheSkgKi8KKyAgICBmb3IgKGYgPSBmb3JtYXQ7ICpmOyBmKyspIHsKKyAgICAgICAgIGlmICgqZiA9PSAnJScpIHsKKyAgICAgICAgICAgICBpZiAoKihmKzEpPT0nJScpCisgICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgIGlmICgqKGYrMSk9PSdTJyB8fCAqKGYrMSk9PSdSJykKKyAgICAgICAgICAgICAgICAgKytjYWxsY291bnQ7CisgICAgICAgICAgICAgd2hpbGUgKGlzZGlnaXQoKHVuc2lnbmVkKSpmKSkKKyAgICAgICAgICAgICAgICAgd2lkdGggPSAod2lkdGgqMTApICsgKmYrKyAtICcwJzsKKyAgICAgICAgICAgICB3aGlsZSAoKisrZiAmJiAqZiAhPSAnJScgJiYgIWlzYWxwaGEoKHVuc2lnbmVkKSpmKSkKKyAgICAgICAgICAgICAgICAgOworICAgICAgICAgICAgIGlmICgqZiA9PSAncycpCisgICAgICAgICAgICAgICAgICsrY2FsbGNvdW50OworICAgICAgICAgfQorICAgIH0KKyAgICAvKiBzdGVwIDI6IGFsbG9jYXRlIG1lbW9yeSBmb3IgdGhlIHJlc3VsdHMgb2YKKyAgICAgKiBQeU9iamVjdF9TdHIoKS9QeU9iamVjdF9SZXByKCkvUHlVbmljb2RlX0RlY29kZVVURjgoKSBjYWxscyAqLworICAgIGlmIChjYWxsY291bnQpIHsKKyAgICAgICAgY2FsbHJlc3VsdHMgPSBQeU9iamVjdF9NYWxsb2Moc2l6ZW9mKFB5T2JqZWN0ICopKmNhbGxjb3VudCk7CisgICAgICAgIGlmICghY2FsbHJlc3VsdHMpIHsKKyAgICAgICAgICAgIFB5RXJyX05vTWVtb3J5KCk7CisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgfQorICAgICAgICBjYWxscmVzdWx0ID0gY2FsbHJlc3VsdHM7CisgICAgfQorICAgIC8qIHN0ZXAgMzogZmlndXJlIG91dCBob3cgbGFyZ2UgYSBidWZmZXIgd2UgbmVlZCAqLworICAgIGZvciAoZiA9IGZvcm1hdDsgKmY7IGYrKykgeworICAgICAgICBpZiAoKmYgPT0gJyUnKSB7CisgICAgICAgICAgICBjb25zdCBjaGFyKiBwID0gZjsKKyAgICAgICAgICAgIHdpZHRoID0gMDsKKyAgICAgICAgICAgIHdoaWxlIChpc2RpZ2l0KCh1bnNpZ25lZCkqZikpCisgICAgICAgICAgICAgICAgd2lkdGggPSAod2lkdGgqMTApICsgKmYrKyAtICcwJzsKKyAgICAgICAgICAgIHdoaWxlICgqKytmICYmICpmICE9ICclJyAmJiAhaXNhbHBoYSgodW5zaWduZWQpKmYpKQorICAgICAgICAgICAgICAgIDsKKworICAgICAgICAgICAgLyogc2tpcCB0aGUgJ2wnIG9yICd6JyBpbiB7JWxkLCAlemQsICVsdSwgJXp1fSBzaW5jZQorICAgICAgICAgICAgICogdGhleSBkb24ndCBhZmZlY3QgdGhlIGFtb3VudCBvZiBzcGFjZSB3ZSByZXNlcnZlLgorICAgICAgICAgICAgICovCisgICAgICAgICAgICBpZiAoKCpmID09ICdsJyB8fCAqZiA9PSAneicpICYmCisgICAgICAgICAgICAgICAgKGZbMV0gPT0gJ2QnIHx8IGZbMV0gPT0gJ3UnKSkKKyAgICAgICAgICAgICAgICArK2Y7CisKKyAgICAgICAgICAgIHN3aXRjaCAoKmYpIHsKKyAgICAgICAgICAgIGNhc2UgJ2MnOgorICAgICAgICAgICAgICAgICh2b2lkKXZhX2FyZyhjb3VudCwgaW50KTsKKyAgICAgICAgICAgICAgICAvKiBmYWxsIHRocm91Z2guLi4gKi8KKyAgICAgICAgICAgIGNhc2UgJyUnOgorICAgICAgICAgICAgICAgIG4rKzsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIGNhc2UgJ2QnOiBjYXNlICd1JzogY2FzZSAnaSc6IGNhc2UgJ3gnOgorICAgICAgICAgICAgICAgICh2b2lkKSB2YV9hcmcoY291bnQsIGludCk7CisgICAgICAgICAgICAgICAgLyogMjAgYnl0ZXMgaXMgZW5vdWdoIHRvIGhvbGQgYSA2NC1iaXQKKyAgICAgICAgICAgICAgICAgICBpbnRlZ2VyLiAgRGVjaW1hbCB0YWtlcyB0aGUgbW9zdCBzcGFjZS4KKyAgICAgICAgICAgICAgICAgICBUaGlzIGlzbid0IGVub3VnaCBmb3Igb2N0YWwuCisgICAgICAgICAgICAgICAgICAgSWYgYSB3aWR0aCBpcyBzcGVjaWZpZWQgd2UgbmVlZCBtb3JlCisgICAgICAgICAgICAgICAgICAgKHdoaWNoIHdlIGFsbG9jYXRlIGxhdGVyKS4gKi8KKyAgICAgICAgICAgICAgICBpZiAod2lkdGggPCAyMCkKKyAgICAgICAgICAgICAgICAgICAgd2lkdGggPSAyMDsKKyAgICAgICAgICAgICAgICBuICs9IHdpZHRoOworICAgICAgICAgICAgICAgIGlmIChhYnVmZmVyc2l6ZSA8IHdpZHRoKQorICAgICAgICAgICAgICAgICAgICBhYnVmZmVyc2l6ZSA9IHdpZHRoOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgY2FzZSAncyc6CisgICAgICAgICAgICB7CisgICAgICAgICAgICAgICAgLyogVVRGLTggKi8KKyAgICAgICAgICAgICAgICBjb25zdCBjaGFyICpzID0gdmFfYXJnKGNvdW50LCBjb25zdCBjaGFyKik7CisgICAgICAgICAgICAgICAgUHlPYmplY3QgKnN0ciA9IFB5VW5pY29kZV9EZWNvZGVVVEY4KHMsIHN0cmxlbihzKSwgInJlcGxhY2UiKTsKKyAgICAgICAgICAgICAgICBpZiAoIXN0cikKKyAgICAgICAgICAgICAgICAgICAgZ290byBmYWlsOworICAgICAgICAgICAgICAgIG4gKz0gUHlVbmljb2RlX0dFVF9TSVpFKHN0cik7CisgICAgICAgICAgICAgICAgLyogUmVtZW1iZXIgdGhlIHN0ciBhbmQgc3dpdGNoIHRvIHRoZSBuZXh0IHNsb3QgKi8KKyAgICAgICAgICAgICAgICAqY2FsbHJlc3VsdCsrID0gc3RyOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgfQorICAgICAgICAgICAgY2FzZSAnVSc6CisgICAgICAgICAgICB7CisgICAgICAgICAgICAgICAgUHlPYmplY3QgKm9iaiA9IHZhX2FyZyhjb3VudCwgUHlPYmplY3QgKik7CisgICAgICAgICAgICAgICAgYXNzZXJ0KG9iaiAmJiBQeVVuaWNvZGVfQ2hlY2sob2JqKSk7CisgICAgICAgICAgICAgICAgbiArPSBQeVVuaWNvZGVfR0VUX1NJWkUob2JqKTsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGNhc2UgJ1YnOgorICAgICAgICAgICAgeworICAgICAgICAgICAgICAgIFB5T2JqZWN0ICpvYmogPSB2YV9hcmcoY291bnQsIFB5T2JqZWN0ICopOworICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgKnN0ciA9IHZhX2FyZyhjb3VudCwgY29uc3QgY2hhciAqKTsKKyAgICAgICAgICAgICAgICBhc3NlcnQob2JqIHx8IHN0cik7CisgICAgICAgICAgICAgICAgYXNzZXJ0KCFvYmogfHwgUHlVbmljb2RlX0NoZWNrKG9iaikpOworICAgICAgICAgICAgICAgIGlmIChvYmopCisgICAgICAgICAgICAgICAgICAgIG4gKz0gUHlVbmljb2RlX0dFVF9TSVpFKG9iaik7CisgICAgICAgICAgICAgICAgZWxzZQorICAgICAgICAgICAgICAgICAgICBuICs9IHN0cmxlbihzdHIpOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgfQorICAgICAgICAgICAgY2FzZSAnUyc6CisgICAgICAgICAgICB7CisgICAgICAgICAgICAgICAgUHlPYmplY3QgKm9iaiA9IHZhX2FyZyhjb3VudCwgUHlPYmplY3QgKik7CisgICAgICAgICAgICAgICAgUHlPYmplY3QgKnN0cjsKKyAgICAgICAgICAgICAgICBhc3NlcnQob2JqKTsKKyAgICAgICAgICAgICAgICBzdHIgPSBQeU9iamVjdF9TdHIob2JqKTsKKyAgICAgICAgICAgICAgICBpZiAoIXN0cikKKyAgICAgICAgICAgICAgICAgICAgZ290byBmYWlsOworICAgICAgICAgICAgICAgIG4gKz0gUHlVbmljb2RlX0dFVF9TSVpFKHN0cik7CisgICAgICAgICAgICAgICAgLyogUmVtZW1iZXIgdGhlIHN0ciBhbmQgc3dpdGNoIHRvIHRoZSBuZXh0IHNsb3QgKi8KKyAgICAgICAgICAgICAgICAqY2FsbHJlc3VsdCsrID0gc3RyOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgfQorICAgICAgICAgICAgY2FzZSAnUic6CisgICAgICAgICAgICB7CisgICAgICAgICAgICAgICAgUHlPYmplY3QgKm9iaiA9IHZhX2FyZyhjb3VudCwgUHlPYmplY3QgKik7CisgICAgICAgICAgICAgICAgUHlPYmplY3QgKnJlcHI7CisgICAgICAgICAgICAgICAgYXNzZXJ0KG9iaik7CisgICAgICAgICAgICAgICAgcmVwciA9IFB5T2JqZWN0X1JlcHIob2JqKTsKKyAgICAgICAgICAgICAgICBpZiAoIXJlcHIpCisgICAgICAgICAgICAgICAgICAgIGdvdG8gZmFpbDsKKyAgICAgICAgICAgICAgICBuICs9IFB5VW5pY29kZV9HRVRfU0laRShyZXByKTsKKyAgICAgICAgICAgICAgICAvKiBSZW1lbWJlciB0aGUgcmVwciBhbmQgc3dpdGNoIHRvIHRoZSBuZXh0IHNsb3QgKi8KKyAgICAgICAgICAgICAgICAqY2FsbHJlc3VsdCsrID0gcmVwcjsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGNhc2UgJ3AnOgorICAgICAgICAgICAgICAgICh2b2lkKSB2YV9hcmcoY291bnQsIGludCk7CisgICAgICAgICAgICAgICAgLyogbWF4aW11bSA2NC1iaXQgcG9pbnRlciByZXByZXNlbnRhdGlvbjoKKyAgICAgICAgICAgICAgICAgKiAweGZmZmZmZmZmZmZmZmZmZmYKKyAgICAgICAgICAgICAgICAgKiBzbyAxOSBjaGFyYWN0ZXJzIGlzIGVub3VnaC4KKyAgICAgICAgICAgICAgICAgKiBYWFggSSBjb3VudCAxOCAtLSB3aGF0J3MgdGhlIGV4dHJhIGZvcj8KKyAgICAgICAgICAgICAgICAgKi8KKyAgICAgICAgICAgICAgICBuICs9IDE5OworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAgICAgICAvKiBpZiB3ZSBzdHVtYmxlIHVwb24gYW4gdW5rbm93bgorICAgICAgICAgICAgICAgICAgIGZvcm1hdHRpbmcgY29kZSwgY29weSB0aGUgcmVzdCBvZgorICAgICAgICAgICAgICAgICAgIHRoZSBmb3JtYXQgc3RyaW5nIHRvIHRoZSBvdXRwdXQKKyAgICAgICAgICAgICAgICAgICBzdHJpbmcuICh3ZSBjYW5ub3QganVzdCBza2lwIHRoZQorICAgICAgICAgICAgICAgICAgIGNvZGUsIHNpbmNlIHRoZXJlJ3Mgbm8gd2F5IHRvIGtub3cKKyAgICAgICAgICAgICAgICAgICB3aGF0J3MgaW4gdGhlIGFyZ3VtZW50IGxpc3QpICovCisgICAgICAgICAgICAgICAgbiArPSBzdHJsZW4ocCk7CisgICAgICAgICAgICAgICAgZ290byBleHBhbmQ7CisgICAgICAgICAgICB9CisgICAgICAgIH0gZWxzZQorICAgICAgICAgICAgbisrOworICAgIH0KKyAgZXhwYW5kOgorICAgIGlmIChhYnVmZmVyc2l6ZSA+IDIwKSB7CisgICAgICAgIGFidWZmZXIgPSBQeU9iamVjdF9NYWxsb2MoYWJ1ZmZlcnNpemUpOworICAgICAgICBpZiAoIWFidWZmZXIpIHsKKyAgICAgICAgICAgIFB5RXJyX05vTWVtb3J5KCk7CisgICAgICAgICAgICBnb3RvIGZhaWw7CisgICAgICAgIH0KKyAgICAgICAgcmVhbGJ1ZmZlciA9IGFidWZmZXI7CisgICAgfQorICAgIGVsc2UKKyAgICAgICAgcmVhbGJ1ZmZlciA9IGJ1ZmZlcjsKKyAgICAvKiBzdGVwIDQ6IGZpbGwgdGhlIGJ1ZmZlciAqLworICAgIC8qIFNpbmNlIHdlJ3ZlIGFuYWx5emVkIGhvdyBtdWNoIHNwYWNlIHdlIG5lZWQgZm9yIHRoZSB3b3JzdCBjYXNlLAorICAgICAgIHdlIGRvbid0IGhhdmUgdG8gcmVzaXplIHRoZSBzdHJpbmcuCisgICAgICAgVGhlcmUgY2FuIGJlIG5vIGVycm9ycyBiZXlvbmQgdGhpcyBwb2ludC4gKi8KKyAgICBzdHJpbmcgPSBQeVVuaWNvZGVfRnJvbVVuaWNvZGUoTlVMTCwgbik7CisgICAgaWYgKCFzdHJpbmcpCisgICAgICAgIGdvdG8gZmFpbDsKKworICAgIHMgPSBQeVVuaWNvZGVfQVNfVU5JQ09ERShzdHJpbmcpOworICAgIGNhbGxyZXN1bHQgPSBjYWxscmVzdWx0czsKKworICAgIGZvciAoZiA9IGZvcm1hdDsgKmY7IGYrKykgeworICAgICAgICBpZiAoKmYgPT0gJyUnKSB7CisgICAgICAgICAgICBjb25zdCBjaGFyKiBwID0gZisrOworICAgICAgICAgICAgaW50IGxvbmdmbGFnID0gMDsKKyAgICAgICAgICAgIGludCBzaXplX3RmbGFnID0gMDsKKyAgICAgICAgICAgIHplcm9wYWQgPSAoKmYgPT0gJzAnKTsKKyAgICAgICAgICAgIC8qIHBhcnNlIHRoZSB3aWR0aC5wcmVjaXNpb24gcGFydCAqLworICAgICAgICAgICAgd2lkdGggPSAwOworICAgICAgICAgICAgd2hpbGUgKGlzZGlnaXQoKHVuc2lnbmVkKSpmKSkKKyAgICAgICAgICAgICAgICB3aWR0aCA9ICh3aWR0aCoxMCkgKyAqZisrIC0gJzAnOworICAgICAgICAgICAgcHJlY2lzaW9uID0gMDsKKyAgICAgICAgICAgIGlmICgqZiA9PSAnLicpIHsKKyAgICAgICAgICAgICAgICBmKys7CisgICAgICAgICAgICAgICAgd2hpbGUgKGlzZGlnaXQoKHVuc2lnbmVkKSpmKSkKKyAgICAgICAgICAgICAgICAgICAgcHJlY2lzaW9uID0gKHByZWNpc2lvbioxMCkgKyAqZisrIC0gJzAnOworICAgICAgICAgICAgfQorICAgICAgICAgICAgLyogaGFuZGxlIHRoZSBsb25nIGZsYWcsIGJ1dCBvbmx5IGZvciAlbGQgYW5kICVsdS4KKyAgICAgICAgICAgICAgIG90aGVycyBjYW4gYmUgYWRkZWQgd2hlbiBuZWNlc3NhcnkuICovCisgICAgICAgICAgICBpZiAoKmYgPT0gJ2wnICYmIChmWzFdID09ICdkJyB8fCBmWzFdID09ICd1JykpIHsKKyAgICAgICAgICAgICAgICBsb25nZmxhZyA9IDE7CisgICAgICAgICAgICAgICAgKytmOworICAgICAgICAgICAgfQorICAgICAgICAgICAgLyogaGFuZGxlIHRoZSBzaXplX3QgZmxhZy4gKi8KKyAgICAgICAgICAgIGlmICgqZiA9PSAneicgJiYgKGZbMV0gPT0gJ2QnIHx8IGZbMV0gPT0gJ3UnKSkgeworICAgICAgICAgICAgICAgIHNpemVfdGZsYWcgPSAxOworICAgICAgICAgICAgICAgICsrZjsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgc3dpdGNoICgqZikgeworICAgICAgICAgICAgY2FzZSAnYyc6CisgICAgICAgICAgICAgICAgKnMrKyA9IHZhX2FyZyh2YXJncywgaW50KTsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIGNhc2UgJ2QnOgorICAgICAgICAgICAgICAgIG1ha2VmbXQoZm10LCBsb25nZmxhZywgc2l6ZV90ZmxhZywgemVyb3BhZCwgd2lkdGgsIHByZWNpc2lvbiwgJ2QnKTsKKyAgICAgICAgICAgICAgICBpZiAobG9uZ2ZsYWcpCisgICAgICAgICAgICAgICAgICAgIHNwcmludGYocmVhbGJ1ZmZlciwgZm10LCB2YV9hcmcodmFyZ3MsIGxvbmcpKTsKKyAgICAgICAgICAgICAgICBlbHNlIGlmIChzaXplX3RmbGFnKQorICAgICAgICAgICAgICAgICAgICBzcHJpbnRmKHJlYWxidWZmZXIsIGZtdCwgdmFfYXJnKHZhcmdzLCBQeV9zc2l6ZV90KSk7CisgICAgICAgICAgICAgICAgZWxzZQorICAgICAgICAgICAgICAgICAgICBzcHJpbnRmKHJlYWxidWZmZXIsIGZtdCwgdmFfYXJnKHZhcmdzLCBpbnQpKTsKKyAgICAgICAgICAgICAgICBhcHBlbmRzdHJpbmcocmVhbGJ1ZmZlcik7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICBjYXNlICd1JzoKKyAgICAgICAgICAgICAgICBtYWtlZm10KGZtdCwgbG9uZ2ZsYWcsIHNpemVfdGZsYWcsIHplcm9wYWQsIHdpZHRoLCBwcmVjaXNpb24sICd1Jyk7CisgICAgICAgICAgICAgICAgaWYgKGxvbmdmbGFnKQorICAgICAgICAgICAgICAgICAgICBzcHJpbnRmKHJlYWxidWZmZXIsIGZtdCwgdmFfYXJnKHZhcmdzLCB1bnNpZ25lZCBsb25nKSk7CisgICAgICAgICAgICAgICAgZWxzZSBpZiAoc2l6ZV90ZmxhZykKKyAgICAgICAgICAgICAgICAgICAgc3ByaW50ZihyZWFsYnVmZmVyLCBmbXQsIHZhX2FyZyh2YXJncywgc2l6ZV90KSk7CisgICAgICAgICAgICAgICAgZWxzZQorICAgICAgICAgICAgICAgICAgICBzcHJpbnRmKHJlYWxidWZmZXIsIGZtdCwgdmFfYXJnKHZhcmdzLCB1bnNpZ25lZCBpbnQpKTsKKyAgICAgICAgICAgICAgICBhcHBlbmRzdHJpbmcocmVhbGJ1ZmZlcik7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICBjYXNlICdpJzoKKyAgICAgICAgICAgICAgICBtYWtlZm10KGZtdCwgMCwgMCwgemVyb3BhZCwgd2lkdGgsIHByZWNpc2lvbiwgJ2knKTsKKyAgICAgICAgICAgICAgICBzcHJpbnRmKHJlYWxidWZmZXIsIGZtdCwgdmFfYXJnKHZhcmdzLCBpbnQpKTsKKyAgICAgICAgICAgICAgICBhcHBlbmRzdHJpbmcocmVhbGJ1ZmZlcik7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICBjYXNlICd4JzoKKyAgICAgICAgICAgICAgICBtYWtlZm10KGZtdCwgMCwgMCwgemVyb3BhZCwgd2lkdGgsIHByZWNpc2lvbiwgJ3gnKTsKKyAgICAgICAgICAgICAgICBzcHJpbnRmKHJlYWxidWZmZXIsIGZtdCwgdmFfYXJnKHZhcmdzLCBpbnQpKTsKKyAgICAgICAgICAgICAgICBhcHBlbmRzdHJpbmcocmVhbGJ1ZmZlcik7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICBjYXNlICdzJzoKKyAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgICAvKiB1bnVzZWQsIHNpbmNlIHdlIGFscmVhZHkgaGF2ZSB0aGUgcmVzdWx0ICovCisgICAgICAgICAgICAgICAgKHZvaWQpIHZhX2FyZyh2YXJncywgY2hhciAqKTsKKyAgICAgICAgICAgICAgICBQeV9VTklDT0RFX0NPUFkocywgUHlVbmljb2RlX0FTX1VOSUNPREUoKmNhbGxyZXN1bHQpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQeVVuaWNvZGVfR0VUX1NJWkUoKmNhbGxyZXN1bHQpKTsKKyAgICAgICAgICAgICAgICBzICs9IFB5VW5pY29kZV9HRVRfU0laRSgqY2FsbHJlc3VsdCk7CisgICAgICAgICAgICAgICAgLyogV2UncmUgZG9uZSB3aXRoIHRoZSB1bmljb2RlKCkvcmVwcigpID0+IGZvcmdldCBpdCAqLworICAgICAgICAgICAgICAgIFB5X0RFQ1JFRigqY2FsbHJlc3VsdCk7CisgICAgICAgICAgICAgICAgLyogc3dpdGNoIHRvIG5leHQgdW5pY29kZSgpL3JlcHIoKSByZXN1bHQgKi8KKyAgICAgICAgICAgICAgICArK2NhbGxyZXN1bHQ7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBjYXNlICdVJzoKKyAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgICBQeU9iamVjdCAqb2JqID0gdmFfYXJnKHZhcmdzLCBQeU9iamVjdCAqKTsKKyAgICAgICAgICAgICAgICBQeV9zc2l6ZV90IHNpemUgPSBQeVVuaWNvZGVfR0VUX1NJWkUob2JqKTsKKyAgICAgICAgICAgICAgICBQeV9VTklDT0RFX0NPUFkocywgUHlVbmljb2RlX0FTX1VOSUNPREUob2JqKSwgc2l6ZSk7CisgICAgICAgICAgICAgICAgcyArPSBzaXplOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgfQorICAgICAgICAgICAgY2FzZSAnVic6CisgICAgICAgICAgICB7CisgICAgICAgICAgICAgICAgUHlPYmplY3QgKm9iaiA9IHZhX2FyZyh2YXJncywgUHlPYmplY3QgKik7CisgICAgICAgICAgICAgICAgY29uc3QgY2hhciAqc3RyID0gdmFfYXJnKHZhcmdzLCBjb25zdCBjaGFyICopOworICAgICAgICAgICAgICAgIGlmIChvYmopIHsKKyAgICAgICAgICAgICAgICAgICAgUHlfc3NpemVfdCBzaXplID0gUHlVbmljb2RlX0dFVF9TSVpFKG9iaik7CisgICAgICAgICAgICAgICAgICAgIFB5X1VOSUNPREVfQ09QWShzLCBQeVVuaWNvZGVfQVNfVU5JQ09ERShvYmopLCBzaXplKTsKKyAgICAgICAgICAgICAgICAgICAgcyArPSBzaXplOworICAgICAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIGFwcGVuZHN0cmluZyhzdHIpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGNhc2UgJ1MnOgorICAgICAgICAgICAgY2FzZSAnUic6CisgICAgICAgICAgICB7CisgICAgICAgICAgICAgICAgUHlfVU5JQ09ERSAqdWNvcHk7CisgICAgICAgICAgICAgICAgUHlfc3NpemVfdCB1c2l6ZTsKKyAgICAgICAgICAgICAgICBQeV9zc2l6ZV90IHVwb3M7CisgICAgICAgICAgICAgICAgLyogdW51c2VkLCBzaW5jZSB3ZSBhbHJlYWR5IGhhdmUgdGhlIHJlc3VsdCAqLworICAgICAgICAgICAgICAgICh2b2lkKSB2YV9hcmcodmFyZ3MsIFB5T2JqZWN0ICopOworICAgICAgICAgICAgICAgIHVjb3B5ID0gUHlVbmljb2RlX0FTX1VOSUNPREUoKmNhbGxyZXN1bHQpOworICAgICAgICAgICAgICAgIHVzaXplID0gUHlVbmljb2RlX0dFVF9TSVpFKCpjYWxscmVzdWx0KTsKKyAgICAgICAgICAgICAgICBmb3IgKHVwb3MgPSAwOyB1cG9zPHVzaXplOykKKyAgICAgICAgICAgICAgICAgICAgKnMrKyA9IHVjb3B5W3Vwb3MrK107CisgICAgICAgICAgICAgICAgLyogV2UncmUgZG9uZSB3aXRoIHRoZSB1bmljb2RlKCkvcmVwcigpID0+IGZvcmdldCBpdCAqLworICAgICAgICAgICAgICAgIFB5X0RFQ1JFRigqY2FsbHJlc3VsdCk7CisgICAgICAgICAgICAgICAgLyogc3dpdGNoIHRvIG5leHQgdW5pY29kZSgpL3JlcHIoKSByZXN1bHQgKi8KKyAgICAgICAgICAgICAgICArK2NhbGxyZXN1bHQ7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBjYXNlICdwJzoKKyAgICAgICAgICAgICAgICBzcHJpbnRmKGJ1ZmZlciwgIiVwIiwgdmFfYXJnKHZhcmdzLCB2b2lkKikpOworICAgICAgICAgICAgICAgIC8qICVwIGlzIGlsbC1kZWZpbmVkOiAgZW5zdXJlIGxlYWRpbmcgMHguICovCisgICAgICAgICAgICAgICAgaWYgKGJ1ZmZlclsxXSA9PSAnWCcpCisgICAgICAgICAgICAgICAgICAgIGJ1ZmZlclsxXSA9ICd4JzsKKyAgICAgICAgICAgICAgICBlbHNlIGlmIChidWZmZXJbMV0gIT0gJ3gnKSB7CisgICAgICAgICAgICAgICAgICAgIG1lbW1vdmUoYnVmZmVyKzIsIGJ1ZmZlciwgc3RybGVuKGJ1ZmZlcikrMSk7CisgICAgICAgICAgICAgICAgICAgIGJ1ZmZlclswXSA9ICcwJzsKKyAgICAgICAgICAgICAgICAgICAgYnVmZmVyWzFdID0gJ3gnOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBhcHBlbmRzdHJpbmcoYnVmZmVyKTsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIGNhc2UgJyUnOgorICAgICAgICAgICAgICAgICpzKysgPSAnJSc7CisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgICAgICBkZWZhdWx0OgorICAgICAgICAgICAgICAgIGFwcGVuZHN0cmluZyhwKTsKKyAgICAgICAgICAgICAgICBnb3RvIGVuZDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfSBlbHNlCisgICAgICAgICAgICAqcysrID0gKmY7CisgICAgfQorCisgIGVuZDoKKyAgICBpZiAoY2FsbHJlc3VsdHMpCisgICAgICAgIFB5T2JqZWN0X0ZyZWUoY2FsbHJlc3VsdHMpOworICAgIGlmIChhYnVmZmVyKQorICAgICAgICBQeU9iamVjdF9GcmVlKGFidWZmZXIpOworICAgIFB5VW5pY29kZV9SZXNpemUoJnN0cmluZywgcyAtIFB5VW5pY29kZV9BU19VTklDT0RFKHN0cmluZykpOworICAgIHJldHVybiBzdHJpbmc7CisgIGZhaWw6CisgICAgaWYgKGNhbGxyZXN1bHRzKSB7CisgICAgICAgIFB5T2JqZWN0ICoqY2FsbHJlc3VsdDIgPSBjYWxscmVzdWx0czsKKyAgICAgICAgd2hpbGUgKGNhbGxyZXN1bHQyIDwgY2FsbHJlc3VsdCkgeworICAgICAgICAgICAgUHlfREVDUkVGKCpjYWxscmVzdWx0Mik7CisgICAgICAgICAgICArK2NhbGxyZXN1bHQyOworICAgICAgICB9CisgICAgICAgIFB5T2JqZWN0X0ZyZWUoY2FsbHJlc3VsdHMpOworICAgIH0KKyAgICBpZiAoYWJ1ZmZlcikKKyAgICAgICAgUHlPYmplY3RfRnJlZShhYnVmZmVyKTsKKyAgICByZXR1cm4gTlVMTDsKK30KKworI3VuZGVmIGFwcGVuZHN0cmluZworCitQeU9iamVjdCAqCitQeVVuaWNvZGVfRnJvbUZvcm1hdChjb25zdCBjaGFyICpmb3JtYXQsIC4uLikKK3sKKyAgICBQeU9iamVjdCogcmV0OworICAgIHZhX2xpc3QgdmFyZ3M7CisKKyNpZmRlZiBIQVZFX1NUREFSR19QUk9UT1RZUEVTCisgICAgdmFfc3RhcnQodmFyZ3MsIGZvcm1hdCk7CisjZWxzZQorICAgIHZhX3N0YXJ0KHZhcmdzKTsKKyNlbmRpZgorICAgIHJldCA9IFB5VW5pY29kZV9Gcm9tRm9ybWF0Vihmb3JtYXQsIHZhcmdzKTsKKyAgICB2YV9lbmQodmFyZ3MpOworICAgIHJldHVybiByZXQ7Cit9CisKK1B5X3NzaXplX3QgUHlVbmljb2RlX0FzV2lkZUNoYXIoUHlVbmljb2RlT2JqZWN0ICp1bmljb2RlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB3Y2hhcl90ICp3LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQeV9zc2l6ZV90IHNpemUpCit7CisgICAgaWYgKHVuaWNvZGUgPT0gTlVMTCkgeworICAgICAgICBQeUVycl9CYWRJbnRlcm5hbENhbGwoKTsKKyAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKworICAgIC8qIElmIHBvc3NpYmxlLCB0cnkgdG8gY29weSB0aGUgMC10ZXJtaW5hdGlvbiBhcyB3ZWxsICovCisgICAgaWYgKHNpemUgPiBQeVVuaWNvZGVfR0VUX1NJWkUodW5pY29kZSkpCisgICAgICAgIHNpemUgPSBQeVVuaWNvZGVfR0VUX1NJWkUodW5pY29kZSkgKyAxOworCisjaWZkZWYgSEFWRV9VU0FCTEVfV0NIQVJfVAorICAgIG1lbWNweSh3LCB1bmljb2RlLT5zdHIsIHNpemUgKiBzaXplb2Yod2NoYXJfdCkpOworI2Vsc2UKKyAgICB7CisgICAgICAgIHJlZ2lzdGVyIFB5X1VOSUNPREUgKnU7CisgICAgICAgIHJlZ2lzdGVyIFB5X3NzaXplX3QgaTsKKyAgICAgICAgdSA9IFB5VW5pY29kZV9BU19VTklDT0RFKHVuaWNvZGUpOworICAgICAgICBmb3IgKGkgPSBzaXplOyBpID4gMDsgaS0tKQorICAgICAgICAgICAgKncrKyA9ICp1Kys7CisgICAgfQorI2VuZGlmCisKKyAgICBpZiAoc2l6ZSA+IFB5VW5pY29kZV9HRVRfU0laRSh1bmljb2RlKSkKKyAgICAgICAgcmV0dXJuIFB5VW5pY29kZV9HRVRfU0laRSh1bmljb2RlKTsKKyAgICBlbHNlCisgICAgICAgIHJldHVybiBzaXplOworfQorCisjZW5kaWYKKworUHlPYmplY3QgKlB5VW5pY29kZV9Gcm9tT3JkaW5hbChpbnQgb3JkaW5hbCkKK3sKKyAgICBQeV9VTklDT0RFIHNbMV07CisKKyNpZmRlZiBQeV9VTklDT0RFX1dJREUKKyAgICBpZiAob3JkaW5hbCA8IDAgfHwgb3JkaW5hbCA+IDB4MTBmZmZmKSB7CisgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19WYWx1ZUVycm9yLAorICAgICAgICAgICAgICAgICAgICAgICAgInVuaWNocigpIGFyZyBub3QgaW4gcmFuZ2UoMHgxMTAwMDApICIKKyAgICAgICAgICAgICAgICAgICAgICAgICIod2lkZSBQeXRob24gYnVpbGQpIik7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyNlbHNlCisgICAgaWYgKG9yZGluYWwgPCAwIHx8IG9yZGluYWwgPiAweGZmZmYpIHsKKyAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1ZhbHVlRXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAgICAidW5pY2hyKCkgYXJnIG5vdCBpbiByYW5nZSgweDEwMDAwKSAiCisgICAgICAgICAgICAgICAgICAgICAgICAiKG5hcnJvdyBQeXRob24gYnVpbGQpIik7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyNlbmRpZgorCisgICAgc1swXSA9IChQeV9VTklDT0RFKW9yZGluYWw7CisgICAgcmV0dXJuIFB5VW5pY29kZV9Gcm9tVW5pY29kZShzLCAxKTsKK30KKworUHlPYmplY3QgKlB5VW5pY29kZV9Gcm9tT2JqZWN0KHJlZ2lzdGVyIFB5T2JqZWN0ICpvYmopCit7CisgICAgLyogWFhYIFBlcmhhcHMgd2Ugc2hvdWxkIG1ha2UgdGhpcyBBUEkgYW4gYWxpYXMgb2YKKyAgICAgICBQeU9iamVjdF9Vbmljb2RlKCkgaW5zdGVhZCA/ISAqLworICAgIGlmIChQeVVuaWNvZGVfQ2hlY2tFeGFjdChvYmopKSB7CisgICAgICAgIFB5X0lOQ1JFRihvYmopOworICAgICAgICByZXR1cm4gb2JqOworICAgIH0KKyAgICBpZiAoUHlVbmljb2RlX0NoZWNrKG9iaikpIHsKKyAgICAgICAgLyogRm9yIGEgVW5pY29kZSBzdWJ0eXBlIHRoYXQncyBub3QgYSBVbmljb2RlIG9iamVjdCwKKyAgICAgICAgICAgcmV0dXJuIGEgdHJ1ZSBVbmljb2RlIG9iamVjdCB3aXRoIHRoZSBzYW1lIGRhdGEuICovCisgICAgICAgIHJldHVybiBQeVVuaWNvZGVfRnJvbVVuaWNvZGUoUHlVbmljb2RlX0FTX1VOSUNPREUob2JqKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQeVVuaWNvZGVfR0VUX1NJWkUob2JqKSk7CisgICAgfQorICAgIHJldHVybiBQeVVuaWNvZGVfRnJvbUVuY29kZWRPYmplY3Qob2JqLCBOVUxMLCAic3RyaWN0Iik7Cit9CisKK1B5T2JqZWN0ICpQeVVuaWNvZGVfRnJvbUVuY29kZWRPYmplY3QocmVnaXN0ZXIgUHlPYmplY3QgKm9iaiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciAqZW5jb2RpbmcsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgKmVycm9ycykKK3sKKyAgICBjb25zdCBjaGFyICpzID0gTlVMTDsKKyAgICBQeV9zc2l6ZV90IGxlbjsKKyAgICBQeU9iamVjdCAqdjsKKworICAgIGlmIChvYmogPT0gTlVMTCkgeworICAgICAgICBQeUVycl9CYWRJbnRlcm5hbENhbGwoKTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorCisjaWYgMAorICAgIC8qIEZvciBiL3cgY29tcGF0aWJpbGl0eSB3ZSBhbHNvIGFjY2VwdCBVbmljb2RlIG9iamVjdHMgcHJvdmlkZWQKKyAgICAgICB0aGF0IG5vIGVuY29kaW5ncyBpcyBnaXZlbiBhbmQgdGhlbiByZWRpcmVjdCB0bworICAgICAgIFB5T2JqZWN0X1VuaWNvZGUoKSB3aGljaCB0aGVuIGFwcGxpZXMgdGhlIGFkZGl0aW9uYWwgbG9naWMgZm9yCisgICAgICAgVW5pY29kZSBzdWJjbGFzc2VzLgorCisgICAgICAgTk9URTogVGhpcyBBUEkgc2hvdWxkIHJlYWxseSBvbmx5IGJlIHVzZWQgZm9yIG9iamVjdCB3aGljaAorICAgICAgIHJlcHJlc2VudCAqZW5jb2RlZCogVW5pY29kZSAhCisKKyAgICAqLworICAgIGlmIChQeVVuaWNvZGVfQ2hlY2sob2JqKSkgeworICAgICAgICBpZiAoZW5jb2RpbmcpIHsKKyAgICAgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19UeXBlRXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgImRlY29kaW5nIFVuaWNvZGUgaXMgbm90IHN1cHBvcnRlZCIpOworICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIFB5T2JqZWN0X1VuaWNvZGUob2JqKTsKKyAgICB9CisjZWxzZQorICAgIGlmIChQeVVuaWNvZGVfQ2hlY2sob2JqKSkgeworICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfVHlwZUVycm9yLAorICAgICAgICAgICAgICAgICAgICAgICAgImRlY29kaW5nIFVuaWNvZGUgaXMgbm90IHN1cHBvcnRlZCIpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisjZW5kaWYKKworICAgIC8qIENvZXJjZSBvYmplY3QgKi8KKyAgICBpZiAoUHlTdHJpbmdfQ2hlY2sob2JqKSkgeworICAgICAgICBzID0gUHlTdHJpbmdfQVNfU1RSSU5HKG9iaik7CisgICAgICAgIGxlbiA9IFB5U3RyaW5nX0dFVF9TSVpFKG9iaik7CisgICAgfQorICAgIGVsc2UgaWYgKFB5Qnl0ZUFycmF5X0NoZWNrKG9iaikpIHsKKyAgICAgICAgLyogUHl0aG9uIDIueCBzcGVjaWZpYyAqLworICAgICAgICBQeUVycl9Gb3JtYXQoUHlFeGNfVHlwZUVycm9yLAorICAgICAgICAgICAgICAgICAgICAgImRlY29kaW5nIGJ5dGVhcnJheSBpcyBub3Qgc3VwcG9ydGVkIik7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICBlbHNlIGlmIChQeU9iamVjdF9Bc0NoYXJCdWZmZXIob2JqLCAmcywgJmxlbikpIHsKKyAgICAgICAgLyogT3ZlcndyaXRlIHRoZSBlcnJvciBtZXNzYWdlIHdpdGggc29tZXRoaW5nIG1vcmUgdXNlZnVsIGluCisgICAgICAgICAgIGNhc2Ugb2YgYSBUeXBlRXJyb3IuICovCisgICAgICAgIGlmIChQeUVycl9FeGNlcHRpb25NYXRjaGVzKFB5RXhjX1R5cGVFcnJvcikpCisgICAgICAgICAgICBQeUVycl9Gb3JtYXQoUHlFeGNfVHlwZUVycm9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICJjb2VyY2luZyB0byBVbmljb2RlOiBuZWVkIHN0cmluZyBvciBidWZmZXIsICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAiJS44MHMgZm91bmQiLAorICAgICAgICAgICAgICAgICAgICAgICAgIFB5X1RZUEUob2JqKS0+dHBfbmFtZSk7CisgICAgICAgIGdvdG8gb25FcnJvcjsKKyAgICB9CisKKyAgICAvKiBDb252ZXJ0IHRvIFVuaWNvZGUgKi8KKyAgICBpZiAobGVuID09IDApCisgICAgICAgIF9QeV9SRVRVUk5fVU5JQ09ERV9FTVBUWSgpOworCisgICAgdiA9IFB5VW5pY29kZV9EZWNvZGUocywgbGVuLCBlbmNvZGluZywgZXJyb3JzKTsKKyAgICByZXR1cm4gdjsKKworICBvbkVycm9yOgorICAgIHJldHVybiBOVUxMOworfQorCitQeU9iamVjdCAqUHlVbmljb2RlX0RlY29kZShjb25zdCBjaGFyICpzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgUHlfc3NpemVfdCBzaXplLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciAqZW5jb2RpbmcsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyICplcnJvcnMpCit7CisgICAgUHlPYmplY3QgKmJ1ZmZlciA9IE5VTEwsICp1bmljb2RlOworCisgICAgaWYgKGVuY29kaW5nID09IE5VTEwpCisgICAgICAgIGVuY29kaW5nID0gUHlVbmljb2RlX0dldERlZmF1bHRFbmNvZGluZygpOworCisgICAgLyogU2hvcnRjdXRzIGZvciBjb21tb24gZGVmYXVsdCBlbmNvZGluZ3MgKi8KKyAgICBpZiAoc3RyY21wKGVuY29kaW5nLCAidXRmLTgiKSA9PSAwKQorICAgICAgICByZXR1cm4gUHlVbmljb2RlX0RlY29kZVVURjgocywgc2l6ZSwgZXJyb3JzKTsKKyAgICBlbHNlIGlmIChzdHJjbXAoZW5jb2RpbmcsICJsYXRpbi0xIikgPT0gMCkKKyAgICAgICAgcmV0dXJuIFB5VW5pY29kZV9EZWNvZGVMYXRpbjEocywgc2l6ZSwgZXJyb3JzKTsKKyNpZiBkZWZpbmVkKE1TX1dJTkRPV1MpICYmIGRlZmluZWQoSEFWRV9VU0FCTEVfV0NIQVJfVCkKKyAgICBlbHNlIGlmIChzdHJjbXAoZW5jb2RpbmcsICJtYmNzIikgPT0gMCkKKyAgICAgICAgcmV0dXJuIFB5VW5pY29kZV9EZWNvZGVNQkNTKHMsIHNpemUsIGVycm9ycyk7CisjZW5kaWYKKyAgICBlbHNlIGlmIChzdHJjbXAoZW5jb2RpbmcsICJhc2NpaSIpID09IDApCisgICAgICAgIHJldHVybiBQeVVuaWNvZGVfRGVjb2RlQVNDSUkocywgc2l6ZSwgZXJyb3JzKTsKKworICAgIC8qIERlY29kZSB2aWEgdGhlIGNvZGVjIHJlZ2lzdHJ5ICovCisgICAgYnVmZmVyID0gUHlCdWZmZXJfRnJvbU1lbW9yeSgodm9pZCAqKXMsIHNpemUpOworICAgIGlmIChidWZmZXIgPT0gTlVMTCkKKyAgICAgICAgZ290byBvbkVycm9yOworICAgIHVuaWNvZGUgPSBQeUNvZGVjX0RlY29kZShidWZmZXIsIGVuY29kaW5nLCBlcnJvcnMpOworICAgIGlmICh1bmljb2RlID09IE5VTEwpCisgICAgICAgIGdvdG8gb25FcnJvcjsKKyAgICBpZiAoIVB5VW5pY29kZV9DaGVjayh1bmljb2RlKSkgeworICAgICAgICBQeUVycl9Gb3JtYXQoUHlFeGNfVHlwZUVycm9yLAorICAgICAgICAgICAgICAgICAgICAgImRlY29kZXIgZGlkIG5vdCByZXR1cm4gYW4gdW5pY29kZSBvYmplY3QgKHR5cGU9JS40MDBzKSIsCisgICAgICAgICAgICAgICAgICAgICBQeV9UWVBFKHVuaWNvZGUpLT50cF9uYW1lKTsKKyAgICAgICAgUHlfREVDUkVGKHVuaWNvZGUpOworICAgICAgICBnb3RvIG9uRXJyb3I7CisgICAgfQorICAgIFB5X0RFQ1JFRihidWZmZXIpOworICAgIHJldHVybiB1bmljb2RlOworCisgIG9uRXJyb3I6CisgICAgUHlfWERFQ1JFRihidWZmZXIpOworICAgIHJldHVybiBOVUxMOworfQorCitQeU9iamVjdCAqUHlVbmljb2RlX0FzRGVjb2RlZE9iamVjdChQeU9iamVjdCAqdW5pY29kZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgKmVuY29kaW5nLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciAqZXJyb3JzKQoreworICAgIFB5T2JqZWN0ICp2OworCisgICAgaWYgKCFQeVVuaWNvZGVfQ2hlY2sodW5pY29kZSkpIHsKKyAgICAgICAgUHlFcnJfQmFkQXJndW1lbnQoKTsKKyAgICAgICAgZ290byBvbkVycm9yOworICAgIH0KKworICAgIGlmIChlbmNvZGluZyA9PSBOVUxMKQorICAgICAgICBlbmNvZGluZyA9IFB5VW5pY29kZV9HZXREZWZhdWx0RW5jb2RpbmcoKTsKKworICAgIC8qIERlY29kZSB2aWEgdGhlIGNvZGVjIHJlZ2lzdHJ5ICovCisgICAgdiA9IFB5Q29kZWNfRGVjb2RlKHVuaWNvZGUsIGVuY29kaW5nLCBlcnJvcnMpOworICAgIGlmICh2ID09IE5VTEwpCisgICAgICAgIGdvdG8gb25FcnJvcjsKKyAgICByZXR1cm4gdjsKKworICBvbkVycm9yOgorICAgIHJldHVybiBOVUxMOworfQorCitQeU9iamVjdCAqUHlVbmljb2RlX0VuY29kZShjb25zdCBQeV9VTklDT0RFICpzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgUHlfc3NpemVfdCBzaXplLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciAqZW5jb2RpbmcsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyICplcnJvcnMpCit7CisgICAgUHlPYmplY3QgKnYsICp1bmljb2RlOworCisgICAgdW5pY29kZSA9IFB5VW5pY29kZV9Gcm9tVW5pY29kZShzLCBzaXplKTsKKyAgICBpZiAodW5pY29kZSA9PSBOVUxMKQorICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB2ID0gUHlVbmljb2RlX0FzRW5jb2RlZFN0cmluZyh1bmljb2RlLCBlbmNvZGluZywgZXJyb3JzKTsKKyAgICBQeV9ERUNSRUYodW5pY29kZSk7CisgICAgcmV0dXJuIHY7Cit9CisKK1B5T2JqZWN0ICpQeVVuaWNvZGVfQXNFbmNvZGVkT2JqZWN0KFB5T2JqZWN0ICp1bmljb2RlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciAqZW5jb2RpbmcsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyICplcnJvcnMpCit7CisgICAgUHlPYmplY3QgKnY7CisKKyAgICBpZiAoIVB5VW5pY29kZV9DaGVjayh1bmljb2RlKSkgeworICAgICAgICBQeUVycl9CYWRBcmd1bWVudCgpOworICAgICAgICBnb3RvIG9uRXJyb3I7CisgICAgfQorCisgICAgaWYgKGVuY29kaW5nID09IE5VTEwpCisgICAgICAgIGVuY29kaW5nID0gUHlVbmljb2RlX0dldERlZmF1bHRFbmNvZGluZygpOworCisgICAgLyogRW5jb2RlIHZpYSB0aGUgY29kZWMgcmVnaXN0cnkgKi8KKyAgICB2ID0gUHlDb2RlY19FbmNvZGUodW5pY29kZSwgZW5jb2RpbmcsIGVycm9ycyk7CisgICAgaWYgKHYgPT0gTlVMTCkKKyAgICAgICAgZ290byBvbkVycm9yOworICAgIHJldHVybiB2OworCisgIG9uRXJyb3I6CisgICAgcmV0dXJuIE5VTEw7Cit9CisKK1B5T2JqZWN0ICpQeVVuaWNvZGVfQXNFbmNvZGVkU3RyaW5nKFB5T2JqZWN0ICp1bmljb2RlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciAqZW5jb2RpbmcsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyICplcnJvcnMpCit7CisgICAgUHlPYmplY3QgKnY7CisKKyAgICBpZiAoIVB5VW5pY29kZV9DaGVjayh1bmljb2RlKSkgeworICAgICAgICBQeUVycl9CYWRBcmd1bWVudCgpOworICAgICAgICBnb3RvIG9uRXJyb3I7CisgICAgfQorCisgICAgaWYgKGVuY29kaW5nID09IE5VTEwpCisgICAgICAgIGVuY29kaW5nID0gUHlVbmljb2RlX0dldERlZmF1bHRFbmNvZGluZygpOworCisgICAgLyogU2hvcnRjdXRzIGZvciBjb21tb24gZGVmYXVsdCBlbmNvZGluZ3MgKi8KKyAgICBpZiAoZXJyb3JzID09IE5VTEwpIHsKKyAgICAgICAgaWYgKHN0cmNtcChlbmNvZGluZywgInV0Zi04IikgPT0gMCkKKyAgICAgICAgICAgIHJldHVybiBQeVVuaWNvZGVfQXNVVEY4U3RyaW5nKHVuaWNvZGUpOworICAgICAgICBlbHNlIGlmIChzdHJjbXAoZW5jb2RpbmcsICJsYXRpbi0xIikgPT0gMCkKKyAgICAgICAgICAgIHJldHVybiBQeVVuaWNvZGVfQXNMYXRpbjFTdHJpbmcodW5pY29kZSk7CisjaWYgZGVmaW5lZChNU19XSU5ET1dTKSAmJiBkZWZpbmVkKEhBVkVfVVNBQkxFX1dDSEFSX1QpCisgICAgICAgIGVsc2UgaWYgKHN0cmNtcChlbmNvZGluZywgIm1iY3MiKSA9PSAwKQorICAgICAgICAgICAgcmV0dXJuIFB5VW5pY29kZV9Bc01CQ1NTdHJpbmcodW5pY29kZSk7CisjZW5kaWYKKyAgICAgICAgZWxzZSBpZiAoc3RyY21wKGVuY29kaW5nLCAiYXNjaWkiKSA9PSAwKQorICAgICAgICAgICAgcmV0dXJuIFB5VW5pY29kZV9Bc0FTQ0lJU3RyaW5nKHVuaWNvZGUpOworICAgIH0KKworICAgIC8qIEVuY29kZSB2aWEgdGhlIGNvZGVjIHJlZ2lzdHJ5ICovCisgICAgdiA9IFB5Q29kZWNfRW5jb2RlKHVuaWNvZGUsIGVuY29kaW5nLCBlcnJvcnMpOworICAgIGlmICh2ID09IE5VTEwpCisgICAgICAgIGdvdG8gb25FcnJvcjsKKyAgICBpZiAoIVB5U3RyaW5nX0NoZWNrKHYpKSB7CisgICAgICAgIFB5RXJyX0Zvcm1hdChQeUV4Y19UeXBlRXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAiZW5jb2RlciBkaWQgbm90IHJldHVybiBhIHN0cmluZyBvYmplY3QgKHR5cGU9JS40MDBzKSIsCisgICAgICAgICAgICAgICAgICAgICBQeV9UWVBFKHYpLT50cF9uYW1lKTsKKyAgICAgICAgUHlfREVDUkVGKHYpOworICAgICAgICBnb3RvIG9uRXJyb3I7CisgICAgfQorICAgIHJldHVybiB2OworCisgIG9uRXJyb3I6CisgICAgcmV0dXJuIE5VTEw7Cit9CisKK1B5T2JqZWN0ICpfUHlVbmljb2RlX0FzRGVmYXVsdEVuY29kZWRTdHJpbmcoUHlPYmplY3QgKnVuaWNvZGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgKmVycm9ycykKK3sKKyAgICBQeU9iamVjdCAqdiA9ICgoUHlVbmljb2RlT2JqZWN0ICopdW5pY29kZSktPmRlZmVuYzsKKworICAgIGlmICh2KQorICAgICAgICByZXR1cm4gdjsKKyAgICB2ID0gUHlVbmljb2RlX0FzRW5jb2RlZFN0cmluZyh1bmljb2RlLCBOVUxMLCBlcnJvcnMpOworICAgIGlmICh2ICYmIGVycm9ycyA9PSBOVUxMKQorICAgICAgICAoKFB5VW5pY29kZU9iamVjdCAqKXVuaWNvZGUpLT5kZWZlbmMgPSB2OworICAgIHJldHVybiB2OworfQorCitQeV9VTklDT0RFICpQeVVuaWNvZGVfQXNVbmljb2RlKFB5T2JqZWN0ICp1bmljb2RlKQoreworICAgIGlmICghUHlVbmljb2RlX0NoZWNrKHVuaWNvZGUpKSB7CisgICAgICAgIFB5RXJyX0JhZEFyZ3VtZW50KCk7CisgICAgICAgIGdvdG8gb25FcnJvcjsKKyAgICB9CisgICAgcmV0dXJuIFB5VW5pY29kZV9BU19VTklDT0RFKHVuaWNvZGUpOworCisgIG9uRXJyb3I6CisgICAgcmV0dXJuIE5VTEw7Cit9CisKK1B5X3NzaXplX3QgUHlVbmljb2RlX0dldFNpemUoUHlPYmplY3QgKnVuaWNvZGUpCit7CisgICAgaWYgKCFQeVVuaWNvZGVfQ2hlY2sodW5pY29kZSkpIHsKKyAgICAgICAgUHlFcnJfQmFkQXJndW1lbnQoKTsKKyAgICAgICAgZ290byBvbkVycm9yOworICAgIH0KKyAgICByZXR1cm4gUHlVbmljb2RlX0dFVF9TSVpFKHVuaWNvZGUpOworCisgIG9uRXJyb3I6CisgICAgcmV0dXJuIC0xOworfQorCitjb25zdCBjaGFyICpQeVVuaWNvZGVfR2V0RGVmYXVsdEVuY29kaW5nKHZvaWQpCit7CisgICAgcmV0dXJuIHVuaWNvZGVfZGVmYXVsdF9lbmNvZGluZzsKK30KKworaW50IFB5VW5pY29kZV9TZXREZWZhdWx0RW5jb2RpbmcoY29uc3QgY2hhciAqZW5jb2RpbmcpCit7CisgICAgUHlPYmplY3QgKnY7CisKKyAgICAvKiBNYWtlIHN1cmUgdGhlIGVuY29kaW5nIGlzIHZhbGlkLiBBcyBzaWRlIGVmZmVjdCwgdGhpcyBhbHNvCisgICAgICAgbG9hZHMgdGhlIGVuY29kaW5nIGludG8gdGhlIGNvZGVjIHJlZ2lzdHJ5IGNhY2hlLiAqLworICAgIHYgPSBfUHlDb2RlY19Mb29rdXAoZW5jb2RpbmcpOworICAgIGlmICh2ID09IE5VTEwpCisgICAgICAgIGdvdG8gb25FcnJvcjsKKyAgICBQeV9ERUNSRUYodik7CisgICAgc3RybmNweSh1bmljb2RlX2RlZmF1bHRfZW5jb2RpbmcsCisgICAgICAgICAgICBlbmNvZGluZywKKyAgICAgICAgICAgIHNpemVvZih1bmljb2RlX2RlZmF1bHRfZW5jb2RpbmcpIC0gMSk7CisgICAgcmV0dXJuIDA7CisKKyAgb25FcnJvcjoKKyAgICByZXR1cm4gLTE7Cit9CisKKy8qIGVycm9yIGhhbmRsaW5nIGNhbGxiYWNrIGhlbHBlcjoKKyAgIGJ1aWxkIGFyZ3VtZW50cywgY2FsbCB0aGUgY2FsbGJhY2sgYW5kIGNoZWNrIHRoZSBhcmd1bWVudHMsCisgICBpZiBubyBleGNlcHRpb24gb2NjdXJyZWQsIGNvcHkgdGhlIHJlcGxhY2VtZW50IHRvIHRoZSBvdXRwdXQKKyAgIGFuZCBhZGp1c3QgdmFyaW91cyBzdGF0ZSB2YXJpYWJsZXMuCisgICByZXR1cm4gMCBvbiBzdWNjZXNzLCAtMSBvbiBlcnJvcgorKi8KKworc3RhdGljCitpbnQgdW5pY29kZV9kZWNvZGVfY2FsbF9lcnJvcmhhbmRsZXIoY29uc3QgY2hhciAqZXJyb3JzLCBQeU9iamVjdCAqKmVycm9ySGFuZGxlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyICplbmNvZGluZywgY29uc3QgY2hhciAqcmVhc29uLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgKmlucHV0LCBQeV9zc2l6ZV90IGluc2l6ZSwgUHlfc3NpemVfdCAqc3RhcnRpbnBvcywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQeV9zc2l6ZV90ICplbmRpbnBvcywgUHlPYmplY3QgKipleGNlcHRpb25PYmplY3QsIGNvbnN0IGNoYXIgKippbnB0ciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQeVVuaWNvZGVPYmplY3QgKipvdXRwdXQsIFB5X3NzaXplX3QgKm91dHBvcywgUHlfVU5JQ09ERSAqKm91dHB0cikKK3sKKyAgICBzdGF0aWMgY2hhciAqYXJncGFyc2UgPSAiTyFuO2RlY29kaW5nIGVycm9yIGhhbmRsZXIgbXVzdCByZXR1cm4gKHVuaWNvZGUsIGludCkgdHVwbGUiOworCisgICAgUHlPYmplY3QgKnJlc3R1cGxlID0gTlVMTDsKKyAgICBQeU9iamVjdCAqcmVwdW5pY29kZSA9IE5VTEw7CisgICAgUHlfc3NpemVfdCBvdXRzaXplID0gUHlVbmljb2RlX0dFVF9TSVpFKCpvdXRwdXQpOworICAgIFB5X3NzaXplX3QgcmVxdWlyZWRzaXplOworICAgIFB5X3NzaXplX3QgbmV3cG9zOworICAgIFB5X1VOSUNPREUgKnJlcHB0cjsKKyAgICBQeV9zc2l6ZV90IHJlcHNpemU7CisgICAgaW50IHJlcyA9IC0xOworCisgICAgaWYgKCplcnJvckhhbmRsZXIgPT0gTlVMTCkgeworICAgICAgICAqZXJyb3JIYW5kbGVyID0gUHlDb2RlY19Mb29rdXBFcnJvcihlcnJvcnMpOworICAgICAgICBpZiAoKmVycm9ySGFuZGxlciA9PSBOVUxMKQorICAgICAgICAgICAgZ290byBvbkVycm9yOworICAgIH0KKworICAgIGlmICgqZXhjZXB0aW9uT2JqZWN0ID09IE5VTEwpIHsKKyAgICAgICAgKmV4Y2VwdGlvbk9iamVjdCA9IFB5VW5pY29kZURlY29kZUVycm9yX0NyZWF0ZSgKKyAgICAgICAgICAgIGVuY29kaW5nLCBpbnB1dCwgaW5zaXplLCAqc3RhcnRpbnBvcywgKmVuZGlucG9zLCByZWFzb24pOworICAgICAgICBpZiAoKmV4Y2VwdGlvbk9iamVjdCA9PSBOVUxMKQorICAgICAgICAgICAgZ290byBvbkVycm9yOworICAgIH0KKyAgICBlbHNlIHsKKyAgICAgICAgaWYgKFB5VW5pY29kZURlY29kZUVycm9yX1NldFN0YXJ0KCpleGNlcHRpb25PYmplY3QsICpzdGFydGlucG9zKSkKKyAgICAgICAgICAgIGdvdG8gb25FcnJvcjsKKyAgICAgICAgaWYgKFB5VW5pY29kZURlY29kZUVycm9yX1NldEVuZCgqZXhjZXB0aW9uT2JqZWN0LCAqZW5kaW5wb3MpKQorICAgICAgICAgICAgZ290byBvbkVycm9yOworICAgICAgICBpZiAoUHlVbmljb2RlRGVjb2RlRXJyb3JfU2V0UmVhc29uKCpleGNlcHRpb25PYmplY3QsIHJlYXNvbikpCisgICAgICAgICAgICBnb3RvIG9uRXJyb3I7CisgICAgfQorCisgICAgcmVzdHVwbGUgPSBQeU9iamVjdF9DYWxsRnVuY3Rpb25PYmpBcmdzKCplcnJvckhhbmRsZXIsICpleGNlcHRpb25PYmplY3QsIE5VTEwpOworICAgIGlmIChyZXN0dXBsZSA9PSBOVUxMKQorICAgICAgICBnb3RvIG9uRXJyb3I7CisgICAgaWYgKCFQeVR1cGxlX0NoZWNrKHJlc3R1cGxlKSkgeworICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfVHlwZUVycm9yLCAmYXJncGFyc2VbNF0pOworICAgICAgICBnb3RvIG9uRXJyb3I7CisgICAgfQorICAgIGlmICghUHlBcmdfUGFyc2VUdXBsZShyZXN0dXBsZSwgYXJncGFyc2UsICZQeVVuaWNvZGVfVHlwZSwgJnJlcHVuaWNvZGUsICZuZXdwb3MpKQorICAgICAgICBnb3RvIG9uRXJyb3I7CisgICAgaWYgKG5ld3BvczwwKQorICAgICAgICBuZXdwb3MgPSBpbnNpemUrbmV3cG9zOworICAgIGlmIChuZXdwb3M8MCB8fCBuZXdwb3M+aW5zaXplKSB7CisgICAgICAgIFB5RXJyX0Zvcm1hdChQeUV4Y19JbmRleEVycm9yLCAicG9zaXRpb24gJXpkIGZyb20gZXJyb3IgaGFuZGxlciBvdXQgb2YgYm91bmRzIiwgbmV3cG9zKTsKKyAgICAgICAgZ290byBvbkVycm9yOworICAgIH0KKworICAgIC8qIG5lZWQgbW9yZSBzcGFjZT8gKGF0IGxlYXN0IGVub3VnaCBmb3Igd2hhdCB3ZQorICAgICAgIGhhdmUrdGhlIHJlcGxhY2VtZW50K3RoZSByZXN0IG9mIHRoZSBzdHJpbmcgKHN0YXJ0aW5nCisgICAgICAgYXQgdGhlIG5ldyBpbnB1dCBwb3NpdGlvbiksIHNvIHdlIHdvbid0IGhhdmUgdG8gY2hlY2sgc3BhY2UKKyAgICAgICB3aGVuIHRoZXJlIGFyZSBubyBlcnJvcnMgaW4gdGhlIHJlc3Qgb2YgdGhlIHN0cmluZykgKi8KKyAgICByZXBwdHIgPSBQeVVuaWNvZGVfQVNfVU5JQ09ERShyZXB1bmljb2RlKTsKKyAgICByZXBzaXplID0gUHlVbmljb2RlX0dFVF9TSVpFKHJlcHVuaWNvZGUpOworICAgIHJlcXVpcmVkc2l6ZSA9ICpvdXRwb3MgKyByZXBzaXplICsgaW5zaXplLW5ld3BvczsKKyAgICBpZiAocmVxdWlyZWRzaXplID4gb3V0c2l6ZSkgeworICAgICAgICBpZiAocmVxdWlyZWRzaXplPDIqb3V0c2l6ZSkKKyAgICAgICAgICAgIHJlcXVpcmVkc2l6ZSA9IDIqb3V0c2l6ZTsKKyAgICAgICAgaWYgKF9QeVVuaWNvZGVfUmVzaXplKG91dHB1dCwgcmVxdWlyZWRzaXplKSA8IDApCisgICAgICAgICAgICBnb3RvIG9uRXJyb3I7CisgICAgICAgICpvdXRwdHIgPSBQeVVuaWNvZGVfQVNfVU5JQ09ERSgqb3V0cHV0KSArICpvdXRwb3M7CisgICAgfQorICAgICplbmRpbnBvcyA9IG5ld3BvczsKKyAgICAqaW5wdHIgPSBpbnB1dCArIG5ld3BvczsKKyAgICBQeV9VTklDT0RFX0NPUFkoKm91dHB0ciwgcmVwcHRyLCByZXBzaXplKTsKKyAgICAqb3V0cHRyICs9IHJlcHNpemU7CisgICAgKm91dHBvcyArPSByZXBzaXplOworICAgIC8qIHdlIG1hZGUgaXQhICovCisgICAgcmVzID0gMDsKKworICBvbkVycm9yOgorICAgIFB5X1hERUNSRUYocmVzdHVwbGUpOworICAgIHJldHVybiByZXM7Cit9CisKKy8qIC0tLSBVVEYtNyBDb2RlYyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLworCisvKiBTZWUgUkZDMjE1MiBmb3IgZGV0YWlscy4gIFdlIGVuY29kZSBjb25zZXJ2YXRpdmVseSBhbmQgZGVjb2RlIGxpYmVyYWxseS4gKi8KKworLyogVGhyZWUgc2ltcGxlIG1hY3JvcyBkZWZpbmluZyBiYXNlLTY0LiAqLworCisvKiBJcyBjIGEgYmFzZS02NCBjaGFyYWN0ZXI/ICovCisKKyNkZWZpbmUgSVNfQkFTRTY0KGMpIFwKKyAgICAoaXNhbG51bShjKSB8fCAoYykgPT0gJysnIHx8IChjKSA9PSAnLycpCisKKy8qIGdpdmVuIHRoYXQgYyBpcyBhIGJhc2UtNjQgY2hhcmFjdGVyLCB3aGF0IGlzIGl0cyBiYXNlLTY0IHZhbHVlPyAqLworCisjZGVmaW5lIEZST01fQkFTRTY0KGMpICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgKCgoYykgPj0gJ0EnICYmIChjKSA8PSAnWicpID8gKGMpIC0gJ0EnIDogICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICgoYykgPj0gJ2EnICYmIChjKSA8PSAneicpID8gKGMpIC0gJ2EnICsgMjYgOiAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICgoYykgPj0gJzAnICYmIChjKSA8PSAnOScpID8gKGMpIC0gJzAnICsgNTIgOiAgICAgICAgICAgICAgICAgICAgICBcCisgICAgIChjKSA9PSAnKycgPyA2MiA6IDYzKQorCisvKiBXaGF0IGlzIHRoZSBiYXNlLTY0IGNoYXJhY3RlciBvZiB0aGUgYm90dG9tIDYgYml0cyBvZiBuPyAqLworCisjZGVmaW5lIFRPX0JBU0U2NChuKSAgXAorICAgICgiQUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVphYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ejAxMjM0NTY3ODkrLyJbKG4pICYgMHgzZl0pCisKKy8qIERFQ09ERV9ESVJFQ1Q6IHRoaXMgYnl0ZSBlbmNvdW50ZXJlZCBpbiBhIFVURi03IHN0cmluZyBzaG91bGQgYmUKKyAqIGRlY29kZWQgYXMgaXRzZWxmLiAgV2UgYXJlIHBlcm1pc3NpdmUgb24gZGVjb2Rpbmc7IHRoZSBvbmx5IEFTQ0lJCisgKiBieXRlIG5vdCBkZWNvZGluZyB0byBpdHNlbGYgaXMgdGhlICsgd2hpY2ggYmVnaW5zIGEgYmFzZTY0CisgKiBzdHJpbmcuICovCisKKyNkZWZpbmUgREVDT0RFX0RJUkVDVChjKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICgoYykgPD0gMTI3ICYmIChjKSAhPSAnKycpCisKKy8qIFRoZSBVVEYtNyBlbmNvZGVyIHRyZWF0cyBBU0NJSSBjaGFyYWN0ZXJzIGRpZmZlcmVudGx5IGFjY29yZGluZyB0bworICogd2hldGhlciB0aGV5IGFyZSBTZXQgRCwgU2V0IE8sIFdoaXRlc3BhY2UsIG9yIHNwZWNpYWwgKGkuZS4gbm9uZSBvZgorICogdGhlIGFib3ZlKS4gIFNlZSBSRkMyMTUyLiAgVGhpcyBhcnJheSBpZGVudGlmaWVzIHRoZXNlIGRpZmZlcmVudAorICogc2V0czoKKyAqIDAgOiAiU2V0IEQiCisgKiAgICAgYWxwaGFudW1lcmljIGFuZCAnKCksLS4vOj8KKyAqIDEgOiAiU2V0IE8iCisgKiAgICAgISIjJCUmKjs8PT5AW11eX2B7fH0KKyAqIDIgOiAid2hpdGVzcGFjZSIKKyAqICAgICBodCBubCBjciBzcAorICogMyA6IHNwZWNpYWwgKG11c3QgYmUgYmFzZTY0IGVuY29kZWQpCisgKiAgICAgZXZlcnl0aGluZyBlbHNlIChpLmUuICtcfiBhbmQgbm9uLXByaW50aW5nIGNvZGVzIDAtOCAxMS0xMiAxNC0zMSAxMjcpCisgKi8KKworc3RhdGljCitjaGFyIHV0ZjdfY2F0ZWdvcnlbMTI4XSA9IHsKKy8qIG51bCBzb2ggc3R4IGV0eCBlb3QgZW5xIGFjayBiZWwgYnMgIGh0ICBubCAgdnQgIG5wICBjciAgc28gIHNpICAqLworICAgIDMsICAzLCAgMywgIDMsICAzLCAgMywgIDMsICAzLCAgMywgIDIsICAyLCAgMywgIDMsICAyLCAgMywgIDMsCisvKiBkbGUgZGMxIGRjMiBkYzMgZGM0IG5hayBzeW4gZXRiIGNhbiBlbSAgc3ViIGVzYyBmcyAgZ3MgIHJzICB1cyAgKi8KKyAgICAzLCAgMywgIDMsICAzLCAgMywgIDMsICAzLCAgMywgIDMsICAzLCAgMywgIDMsICAzLCAgMywgIDMsICAzLAorLyogc3AgICAhICAgIiAgICMgICAkICAgJSAgICYgICAnICAgKCAgICkgICAqICAgKyAgICwgICAtICAgLiAgIC8gICovCisgICAgMiwgIDEsICAxLCAgMSwgIDEsICAxLCAgMSwgIDAsICAwLCAgMCwgIDEsICAzLCAgMCwgIDAsICAwLCAgMCwKKy8qICAwICAgMSAgIDIgICAzICAgNCAgIDUgICA2ICAgNyAgIDggICA5ICAgOiAgIDsgICA8ICAgPSAgID4gICA/ICAqLworICAgIDAsICAwLCAgMCwgIDAsICAwLCAgMCwgIDAsICAwLCAgMCwgIDAsICAwLCAgMSwgIDEsICAxLCAgMSwgIDAsCisvKiAgQCAgIEEgICBCICAgQyAgIEQgICBFICAgRiAgIEcgICBIICAgSSAgIEogICBLICAgTCAgIE0gICBOICAgTyAgKi8KKyAgICAxLCAgMCwgIDAsICAwLCAgMCwgIDAsICAwLCAgMCwgIDAsICAwLCAgMCwgIDAsICAwLCAgMCwgIDAsICAwLAorLyogIFAgICBRICAgUiAgIFMgICBUICAgVSAgIFYgICBXICAgWCAgIFkgICBaICAgWyAgIFwgICBdICAgXiAgIF8gICovCisgICAgMCwgIDAsICAwLCAgMCwgIDAsICAwLCAgMCwgIDAsICAwLCAgMCwgIDAsICAxLCAgMywgIDEsICAxLCAgMSwKKy8qICBgICAgYSAgIGIgICBjICAgZCAgIGUgICBmICAgZyAgIGggICBpICAgaiAgIGsgICBsICAgbSAgIG4gICBvICAqLworICAgIDEsICAwLCAgMCwgIDAsICAwLCAgMCwgIDAsICAwLCAgMCwgIDAsICAwLCAgMCwgIDAsICAwLCAgMCwgIDAsCisvKiAgcCAgIHEgICByICAgcyAgIHQgICB1ICAgdiAgIHcgICB4ICAgeSAgIHogICB7ICAgfCAgIH0gICB+ICBkZWwgKi8KKyAgICAwLCAgMCwgIDAsICAwLCAgMCwgIDAsICAwLCAgMCwgIDAsICAwLCAgMCwgIDEsICAxLCAgMSwgIDMsICAzLAorfTsKKworLyogRU5DT0RFX0RJUkVDVDogdGhpcyBjaGFyYWN0ZXIgc2hvdWxkIGJlIGVuY29kZWQgYXMgaXRzZWxmLiAgVGhlCisgKiBhbnN3ZXIgZGVwZW5kcyBvbiB3aGV0aGVyIHdlIGFyZSBlbmNvZGluZyBzZXQgTyBhcyBpdHNlbGYsIGFuZCBhbHNvCisgKiBvbiB3aGV0aGVyIHdlIGFyZSBlbmNvZGluZyB3aGl0ZXNwYWNlIGFzIGl0c2VsZi4gIFJGQzIxNTIgbWFrZXMgaXQKKyAqIGNsZWFyIHRoYXQgdGhlIGFuc3dlcnMgdG8gdGhlc2UgcXVlc3Rpb25zIHZhcnkgYmV0d2VlbgorICogYXBwbGljYXRpb25zLCBzbyB0aGlzIGNvZGUgbmVlZHMgdG8gYmUgZmxleGlibGUuICAqLworCisjZGVmaW5lIEVOQ09ERV9ESVJFQ1QoYywgZGlyZWN0TywgZGlyZWN0V1MpICAgICAgICAgICAgIFwKKyAgICAoKGMpIDwgMTI4ICYmIChjKSA+IDAgJiYgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAoKHV0ZjdfY2F0ZWdvcnlbKGMpXSA9PSAwKSB8fCAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAoZGlyZWN0V1MgJiYgKHV0ZjdfY2F0ZWdvcnlbKGMpXSA9PSAyKSkgfHwgICAgICAgIFwKKyAgICAgIChkaXJlY3RPICYmICh1dGY3X2NhdGVnb3J5WyhjKV0gPT0gMSkpKSkKKworUHlPYmplY3QgKlB5VW5pY29kZV9EZWNvZGVVVEY3KGNvbnN0IGNoYXIgKnMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHlfc3NpemVfdCBzaXplLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgKmVycm9ycykKK3sKKyAgICByZXR1cm4gUHlVbmljb2RlX0RlY29kZVVURjdTdGF0ZWZ1bChzLCBzaXplLCBlcnJvcnMsIE5VTEwpOworfQorCisvKiBUaGUgZGVjb2Rlci4gIFRoZSBvbmx5IHN0YXRlIHdlIHByZXNlcnZlIGlzIG91ciByZWFkIHBvc2l0aW9uLAorICogaS5lLiBob3cgbWFueSBjaGFyYWN0ZXJzIHdlIGhhdmUgY29uc3VtZWQuICBTbyBpZiB3ZSBlbmQgaW4gdGhlCisgKiBtaWRkbGUgb2YgYSBzaGlmdCBzZXF1ZW5jZSB3ZSBoYXZlIHRvIGJhY2sgb2ZmIHRoZSByZWFkIHBvc2l0aW9uCisgKiBhbmQgdGhlIG91dHB1dCB0byB0aGUgYmVnaW5uaW5nIG9mIHRoZSBzZXF1ZW5jZSwgb3RoZXJ3aXNlIHdlIGxvc2UKKyAqIGFsbCB0aGUgc2hpZnQgc3RhdGUgKHNlZW4gYml0cywgbnVtYmVyIG9mIGJpdHMgc2VlbiwgaGlnaAorICogc3Vycm9nYXRlKS4gKi8KKworUHlPYmplY3QgKlB5VW5pY29kZV9EZWNvZGVVVEY3U3RhdGVmdWwoY29uc3QgY2hhciAqcywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFB5X3NzaXplX3Qgc2l6ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgKmVycm9ycywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFB5X3NzaXplX3QgKmNvbnN1bWVkKQoreworICAgIGNvbnN0IGNoYXIgKnN0YXJ0cyA9IHM7CisgICAgUHlfc3NpemVfdCBzdGFydGlucG9zOworICAgIFB5X3NzaXplX3QgZW5kaW5wb3M7CisgICAgUHlfc3NpemVfdCBvdXRwb3M7CisgICAgY29uc3QgY2hhciAqZTsKKyAgICBQeVVuaWNvZGVPYmplY3QgKnVuaWNvZGU7CisgICAgUHlfVU5JQ09ERSAqcDsKKyAgICBjb25zdCBjaGFyICplcnJtc2cgPSAiIjsKKyAgICBpbnQgaW5TaGlmdCA9IDA7CisgICAgUHlfVU5JQ09ERSAqc2hpZnRPdXRTdGFydDsKKyAgICB1bnNpZ25lZCBpbnQgYmFzZTY0Yml0cyA9IDA7CisgICAgdW5zaWduZWQgbG9uZyBiYXNlNjRidWZmZXIgPSAwOworICAgIFB5X1VOSUNPREUgc3Vycm9nYXRlID0gMDsKKyAgICBQeU9iamVjdCAqZXJyb3JIYW5kbGVyID0gTlVMTDsKKyAgICBQeU9iamVjdCAqZXhjID0gTlVMTDsKKworICAgIHVuaWNvZGUgPSBfUHlVbmljb2RlX05ldyhzaXplKTsKKyAgICBpZiAoIXVuaWNvZGUpCisgICAgICAgIHJldHVybiBOVUxMOworICAgIGlmIChzaXplID09IDApIHsKKyAgICAgICAgaWYgKGNvbnN1bWVkKQorICAgICAgICAgICAgKmNvbnN1bWVkID0gMDsKKyAgICAgICAgcmV0dXJuIChQeU9iamVjdCAqKXVuaWNvZGU7CisgICAgfQorCisgICAgcCA9IHVuaWNvZGUtPnN0cjsKKyAgICBzaGlmdE91dFN0YXJ0ID0gcDsKKyAgICBlID0gcyArIHNpemU7CisKKyAgICB3aGlsZSAocyA8IGUpIHsKKyAgICAgICAgUHlfVU5JQ09ERSBjaCA9ICh1bnNpZ25lZCBjaGFyKSAqczsKKworICAgICAgICBpZiAoaW5TaGlmdCkgeyAvKiBpbiBhIGJhc2UtNjQgc2VjdGlvbiAqLworICAgICAgICAgICAgaWYgKElTX0JBU0U2NChjaCkpIHsgLyogY29uc3VtZSBhIGJhc2UtNjQgY2hhcmFjdGVyICovCisgICAgICAgICAgICAgICAgYmFzZTY0YnVmZmVyID0gKGJhc2U2NGJ1ZmZlciA8PCA2KSB8IEZST01fQkFTRTY0KGNoKTsKKyAgICAgICAgICAgICAgICBiYXNlNjRiaXRzICs9IDY7CisgICAgICAgICAgICAgICAgcysrOworICAgICAgICAgICAgICAgIGlmIChiYXNlNjRiaXRzID49IDE2KSB7CisgICAgICAgICAgICAgICAgICAgIC8qIHdlIGhhdmUgZW5vdWdoIGJpdHMgZm9yIGEgVVRGLTE2IHZhbHVlICovCisgICAgICAgICAgICAgICAgICAgIFB5X1VOSUNPREUgb3V0Q2ggPSAoUHlfVU5JQ09ERSkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChiYXNlNjRidWZmZXIgPj4gKGJhc2U2NGJpdHMtMTYpKTsKKyAgICAgICAgICAgICAgICAgICAgYmFzZTY0Yml0cyAtPSAxNjsKKyAgICAgICAgICAgICAgICAgICAgYmFzZTY0YnVmZmVyICY9ICgxIDw8IGJhc2U2NGJpdHMpIC0gMTsgLyogY2xlYXIgaGlnaCBiaXRzICovCisgICAgICAgICAgICAgICAgICAgIGlmIChzdXJyb2dhdGUpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIC8qIGV4cGVjdGluZyBhIHNlY29uZCBzdXJyb2dhdGUgKi8KKyAgICAgICAgICAgICAgICAgICAgICAgIGlmIChvdXRDaCA+PSAweERDMDAgJiYgb3V0Q2ggPD0gMHhERkZGKSB7CisjaWZkZWYgUHlfVU5JQ09ERV9XSURFCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgKnArKyA9ICgoKHN1cnJvZ2F0ZSAmIDB4M0ZGKTw8MTApCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IChvdXRDaCAmIDB4M0ZGKSkgKyAweDEwMDAwOworI2Vsc2UKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAqcCsrID0gc3Vycm9nYXRlOworICAgICAgICAgICAgICAgICAgICAgICAgICAgICpwKysgPSBvdXRDaDsKKyNlbmRpZgorICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1cnJvZ2F0ZSA9IDA7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAqcCsrID0gc3Vycm9nYXRlOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN1cnJvZ2F0ZSA9IDA7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgaWYgKG91dENoID49IDB4RDgwMCAmJiBvdXRDaCA8PSAweERCRkYpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIC8qIGZpcnN0IHN1cnJvZ2F0ZSAqLworICAgICAgICAgICAgICAgICAgICAgICAgc3Vycm9nYXRlID0gb3V0Q2g7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgZWxzZSB7CisgICAgICAgICAgICAgICAgICAgICAgICAqcCsrID0gb3V0Q2g7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICBlbHNlIHsgLyogbm93IGxlYXZpbmcgYSBiYXNlLTY0IHNlY3Rpb24gKi8KKyAgICAgICAgICAgICAgICBpblNoaWZ0ID0gMDsKKyAgICAgICAgICAgICAgICBzKys7CisgICAgICAgICAgICAgICAgaWYgKHN1cnJvZ2F0ZSkgeworICAgICAgICAgICAgICAgICAgICAqcCsrID0gc3Vycm9nYXRlOworICAgICAgICAgICAgICAgICAgICBzdXJyb2dhdGUgPSAwOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBpZiAoYmFzZTY0Yml0cyA+IDApIHsgLyogbGVmdC1vdmVyIGJpdHMgKi8KKyAgICAgICAgICAgICAgICAgICAgaWYgKGJhc2U2NGJpdHMgPj0gNikgeworICAgICAgICAgICAgICAgICAgICAgICAgLyogV2UndmUgc2VlbiBhdCBsZWFzdCBvbmUgYmFzZS02NCBjaGFyYWN0ZXIgKi8KKyAgICAgICAgICAgICAgICAgICAgICAgIGVycm1zZyA9ICJwYXJ0aWFsIGNoYXJhY3RlciBpbiBzaGlmdCBzZXF1ZW5jZSI7CisgICAgICAgICAgICAgICAgICAgICAgICBnb3RvIHV0ZjdFcnJvcjsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIC8qIFNvbWUgYml0cyByZW1haW47IHRoZXkgc2hvdWxkIGJlIHplcm8gKi8KKyAgICAgICAgICAgICAgICAgICAgICAgIGlmIChiYXNlNjRidWZmZXIgIT0gMCkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVycm1zZyA9ICJub24temVybyBwYWRkaW5nIGJpdHMgaW4gc2hpZnQgc2VxdWVuY2UiOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdvdG8gdXRmN0Vycm9yOworICAgICAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGlmIChjaCAhPSAnLScpIHsKKyAgICAgICAgICAgICAgICAgICAgLyogJy0nIGlzIGFic29yYmVkOyBvdGhlciB0ZXJtaW5hdGluZworICAgICAgICAgICAgICAgICAgICAgICBjaGFyYWN0ZXJzIGFyZSBwcmVzZXJ2ZWQgKi8KKyAgICAgICAgICAgICAgICAgICAgKnArKyA9IGNoOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBlbHNlIGlmICggY2ggPT0gJysnICkgeworICAgICAgICAgICAgc3RhcnRpbnBvcyA9IHMtc3RhcnRzOworICAgICAgICAgICAgcysrOyAvKiBjb25zdW1lICcrJyAqLworICAgICAgICAgICAgaWYgKHMgPCBlICYmICpzID09ICctJykgeyAvKiAnKy0nIGVuY29kZXMgJysnICovCisgICAgICAgICAgICAgICAgcysrOworICAgICAgICAgICAgICAgICpwKysgPSAnKyc7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBlbHNlIHsgLyogYmVnaW4gYmFzZTY0LWVuY29kZWQgc2VjdGlvbiAqLworICAgICAgICAgICAgICAgIGluU2hpZnQgPSAxOworICAgICAgICAgICAgICAgIHNoaWZ0T3V0U3RhcnQgPSBwOworICAgICAgICAgICAgICAgIGJhc2U2NGJpdHMgPSAwOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGVsc2UgaWYgKERFQ09ERV9ESVJFQ1QoY2gpKSB7IC8qIGNoYXJhY3RlciBkZWNvZGVzIGFzIGl0c2VsZiAqLworICAgICAgICAgICAgKnArKyA9IGNoOworICAgICAgICAgICAgcysrOworICAgICAgICB9CisgICAgICAgIGVsc2UgeworICAgICAgICAgICAgc3RhcnRpbnBvcyA9IHMtc3RhcnRzOworICAgICAgICAgICAgcysrOworICAgICAgICAgICAgZXJybXNnID0gInVuZXhwZWN0ZWQgc3BlY2lhbCBjaGFyYWN0ZXIiOworICAgICAgICAgICAgZ290byB1dGY3RXJyb3I7CisgICAgICAgIH0KKyAgICAgICAgY29udGludWU7Cit1dGY3RXJyb3I6CisgICAgICAgIG91dHBvcyA9IHAtUHlVbmljb2RlX0FTX1VOSUNPREUodW5pY29kZSk7CisgICAgICAgIGVuZGlucG9zID0gcy1zdGFydHM7CisgICAgICAgIGlmICh1bmljb2RlX2RlY29kZV9jYWxsX2Vycm9yaGFuZGxlcigKKyAgICAgICAgICAgICAgICBlcnJvcnMsICZlcnJvckhhbmRsZXIsCisgICAgICAgICAgICAgICAgInV0ZjciLCBlcnJtc2csCisgICAgICAgICAgICAgICAgc3RhcnRzLCBzaXplLCAmc3RhcnRpbnBvcywgJmVuZGlucG9zLCAmZXhjLCAmcywKKyAgICAgICAgICAgICAgICAmdW5pY29kZSwgJm91dHBvcywgJnApKQorICAgICAgICAgICAgZ290byBvbkVycm9yOworICAgIH0KKworICAgIC8qIGVuZCBvZiBzdHJpbmcgKi8KKworICAgIGlmIChpblNoaWZ0ICYmICFjb25zdW1lZCkgeyAvKiBpbiBzaGlmdCBzZXF1ZW5jZSwgbm8gbW9yZSB0byBmb2xsb3cgKi8KKyAgICAgICAgLyogaWYgd2UncmUgaW4gYW4gaW5jb25zaXN0ZW50IHN0YXRlLCB0aGF0J3MgYW4gZXJyb3IgKi8KKyAgICAgICAgaWYgKHN1cnJvZ2F0ZSB8fAorICAgICAgICAgICAgICAgIChiYXNlNjRiaXRzID49IDYpIHx8CisgICAgICAgICAgICAgICAgKGJhc2U2NGJpdHMgPiAwICYmIGJhc2U2NGJ1ZmZlciAhPSAwKSkgeworICAgICAgICAgICAgb3V0cG9zID0gcC1QeVVuaWNvZGVfQVNfVU5JQ09ERSh1bmljb2RlKTsKKyAgICAgICAgICAgIGVuZGlucG9zID0gc2l6ZTsKKyAgICAgICAgICAgIGlmICh1bmljb2RlX2RlY29kZV9jYWxsX2Vycm9yaGFuZGxlcigKKyAgICAgICAgICAgICAgICAgICAgZXJyb3JzLCAmZXJyb3JIYW5kbGVyLAorICAgICAgICAgICAgICAgICAgICAidXRmNyIsICJ1bnRlcm1pbmF0ZWQgc2hpZnQgc2VxdWVuY2UiLAorICAgICAgICAgICAgICAgICAgICBzdGFydHMsIHNpemUsICZzdGFydGlucG9zLCAmZW5kaW5wb3MsICZleGMsICZzLAorICAgICAgICAgICAgICAgICAgICAmdW5pY29kZSwgJm91dHBvcywgJnApKQorICAgICAgICAgICAgICAgIGdvdG8gb25FcnJvcjsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qIHJldHVybiBzdGF0ZSAqLworICAgIGlmIChjb25zdW1lZCkgeworICAgICAgICBpZiAoaW5TaGlmdCkgeworICAgICAgICAgICAgcCA9IHNoaWZ0T3V0U3RhcnQ7IC8qIGJhY2sgb2ZmIG91dHB1dCAqLworICAgICAgICAgICAgKmNvbnN1bWVkID0gc3RhcnRpbnBvczsKKyAgICAgICAgfQorICAgICAgICBlbHNlIHsKKyAgICAgICAgICAgICpjb25zdW1lZCA9IHMtc3RhcnRzOworICAgICAgICB9CisgICAgfQorCisgICAgaWYgKF9QeVVuaWNvZGVfUmVzaXplKCZ1bmljb2RlLCBwIC0gUHlVbmljb2RlX0FTX1VOSUNPREUodW5pY29kZSkpIDwgMCkKKyAgICAgICAgZ290byBvbkVycm9yOworCisgICAgUHlfWERFQ1JFRihlcnJvckhhbmRsZXIpOworICAgIFB5X1hERUNSRUYoZXhjKTsKKyAgICByZXR1cm4gKFB5T2JqZWN0ICopdW5pY29kZTsKKworICBvbkVycm9yOgorICAgIFB5X1hERUNSRUYoZXJyb3JIYW5kbGVyKTsKKyAgICBQeV9YREVDUkVGKGV4Yyk7CisgICAgUHlfREVDUkVGKHVuaWNvZGUpOworICAgIHJldHVybiBOVUxMOworfQorCisKK1B5T2JqZWN0ICpQeVVuaWNvZGVfRW5jb2RlVVRGNyhjb25zdCBQeV9VTklDT0RFICpzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFB5X3NzaXplX3Qgc2l6ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgYmFzZTY0U2V0TywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgYmFzZTY0V2hpdGVTcGFjZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyICplcnJvcnMpCit7CisgICAgUHlPYmplY3QgKnY7CisgICAgLyogSXQgbWlnaHQgYmUgcG9zc2libGUgdG8gdGlnaHRlbiB0aGlzIHdvcnN0IGNhc2UgKi8KKyAgICBQeV9zc2l6ZV90IGFsbG9jYXRlZCA9IDggKiBzaXplOworICAgIGludCBpblNoaWZ0ID0gMDsKKyAgICBQeV9zc2l6ZV90IGkgPSAwOworICAgIHVuc2lnbmVkIGludCBiYXNlNjRiaXRzID0gMDsKKyAgICB1bnNpZ25lZCBsb25nIGJhc2U2NGJ1ZmZlciA9IDA7CisgICAgY2hhciAqIG91dDsKKyAgICBjaGFyICogc3RhcnQ7CisKKyAgICBpZiAoYWxsb2NhdGVkIC8gOCAhPSBzaXplKQorICAgICAgICByZXR1cm4gUHlFcnJfTm9NZW1vcnkoKTsKKworICAgIGlmIChzaXplID09IDApCisgICAgICAgIHJldHVybiBQeVN0cmluZ19Gcm9tU3RyaW5nQW5kU2l6ZShOVUxMLCAwKTsKKworICAgIHYgPSBQeVN0cmluZ19Gcm9tU3RyaW5nQW5kU2l6ZShOVUxMLCBhbGxvY2F0ZWQpOworICAgIGlmICh2ID09IE5VTEwpCisgICAgICAgIHJldHVybiBOVUxMOworCisgICAgc3RhcnQgPSBvdXQgPSBQeVN0cmluZ19BU19TVFJJTkcodik7CisgICAgZm9yICg7aSA8IHNpemU7ICsraSkgeworICAgICAgICBQeV9VTklDT0RFIGNoID0gc1tpXTsKKworICAgICAgICBpZiAoaW5TaGlmdCkgeworICAgICAgICAgICAgaWYgKEVOQ09ERV9ESVJFQ1QoY2gsICFiYXNlNjRTZXRPLCAhYmFzZTY0V2hpdGVTcGFjZSkpIHsKKyAgICAgICAgICAgICAgICAvKiBzaGlmdGluZyBvdXQgKi8KKyAgICAgICAgICAgICAgICBpZiAoYmFzZTY0Yml0cykgeyAvKiBvdXRwdXQgcmVtYWluaW5nIGJpdHMgKi8KKyAgICAgICAgICAgICAgICAgICAgKm91dCsrID0gVE9fQkFTRTY0KGJhc2U2NGJ1ZmZlciA8PCAoNi1iYXNlNjRiaXRzKSk7CisgICAgICAgICAgICAgICAgICAgIGJhc2U2NGJ1ZmZlciA9IDA7CisgICAgICAgICAgICAgICAgICAgIGJhc2U2NGJpdHMgPSAwOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBpblNoaWZ0ID0gMDsKKyAgICAgICAgICAgICAgICAvKiBDaGFyYWN0ZXJzIG5vdCBpbiB0aGUgQkFTRTY0IHNldCBpbXBsaWNpdGx5IHVuc2hpZnQgdGhlIHNlcXVlbmNlCisgICAgICAgICAgICAgICAgICAgc28gbm8gJy0nIGlzIHJlcXVpcmVkLCBleGNlcHQgaWYgdGhlIGNoYXJhY3RlciBpcyBpdHNlbGYgYSAnLScgKi8KKyAgICAgICAgICAgICAgICBpZiAoSVNfQkFTRTY0KGNoKSB8fCBjaCA9PSAnLScpIHsKKyAgICAgICAgICAgICAgICAgICAgKm91dCsrID0gJy0nOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAqb3V0KysgPSAoY2hhcikgY2g7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBlbHNlIHsKKyAgICAgICAgICAgICAgICBnb3RvIGVuY29kZV9jaGFyOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGVsc2UgeyAvKiBub3QgaW4gYSBzaGlmdCBzZXF1ZW5jZSAqLworICAgICAgICAgICAgaWYgKGNoID09ICcrJykgeworICAgICAgICAgICAgICAgICpvdXQrKyA9ICcrJzsKKyAgICAgICAgICAgICAgICAgICAgICAgICpvdXQrKyA9ICctJzsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGVsc2UgaWYgKEVOQ09ERV9ESVJFQ1QoY2gsICFiYXNlNjRTZXRPLCAhYmFzZTY0V2hpdGVTcGFjZSkpIHsKKyAgICAgICAgICAgICAgICAqb3V0KysgPSAoY2hhcikgY2g7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBlbHNlIHsKKyAgICAgICAgICAgICAgICAqb3V0KysgPSAnKyc7CisgICAgICAgICAgICAgICAgaW5TaGlmdCA9IDE7CisgICAgICAgICAgICAgICAgZ290byBlbmNvZGVfY2hhcjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBjb250aW51ZTsKK2VuY29kZV9jaGFyOgorI2lmZGVmIFB5X1VOSUNPREVfV0lERQorICAgICAgICBpZiAoY2ggPj0gMHgxMDAwMCkgeworICAgICAgICAgICAgLyogY29kZSBmaXJzdCBzdXJyb2dhdGUgKi8KKyAgICAgICAgICAgIGJhc2U2NGJpdHMgKz0gMTY7CisgICAgICAgICAgICBiYXNlNjRidWZmZXIgPSAoYmFzZTY0YnVmZmVyIDw8IDE2KSB8IDB4ZDgwMCB8ICgoY2gtMHgxMDAwMCkgPj4gMTApOworICAgICAgICAgICAgd2hpbGUgKGJhc2U2NGJpdHMgPj0gNikgeworICAgICAgICAgICAgICAgICpvdXQrKyA9IFRPX0JBU0U2NChiYXNlNjRidWZmZXIgPj4gKGJhc2U2NGJpdHMtNikpOworICAgICAgICAgICAgICAgIGJhc2U2NGJpdHMgLT0gNjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIC8qIHByZXBhcmUgc2Vjb25kIHN1cnJvZ2F0ZSAqLworICAgICAgICAgICAgY2ggPSAgMHhEQzAwIHwgKChjaC0weDEwMDAwKSAmIDB4M0ZGKTsKKyAgICAgICAgfQorI2VuZGlmCisgICAgICAgIGJhc2U2NGJpdHMgKz0gMTY7CisgICAgICAgIGJhc2U2NGJ1ZmZlciA9IChiYXNlNjRidWZmZXIgPDwgMTYpIHwgY2g7CisgICAgICAgIHdoaWxlIChiYXNlNjRiaXRzID49IDYpIHsKKyAgICAgICAgICAgICpvdXQrKyA9IFRPX0JBU0U2NChiYXNlNjRidWZmZXIgPj4gKGJhc2U2NGJpdHMtNikpOworICAgICAgICAgICAgYmFzZTY0Yml0cyAtPSA2OworICAgICAgICB9CisgICAgfQorICAgIGlmIChiYXNlNjRiaXRzKQorICAgICAgICAqb3V0Kys9IFRPX0JBU0U2NChiYXNlNjRidWZmZXIgPDwgKDYtYmFzZTY0Yml0cykgKTsKKyAgICBpZiAoaW5TaGlmdCkKKyAgICAgICAgKm91dCsrID0gJy0nOworCisgICAgaWYgKF9QeVN0cmluZ19SZXNpemUoJnYsIG91dCAtIHN0YXJ0KSkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgcmV0dXJuIHY7Cit9CisKKyN1bmRlZiBJU19CQVNFNjQKKyN1bmRlZiBGUk9NX0JBU0U2NAorI3VuZGVmIFRPX0JBU0U2NAorI3VuZGVmIERFQ09ERV9ESVJFQ1QKKyN1bmRlZiBFTkNPREVfRElSRUNUCisKKy8qIC0tLSBVVEYtOCBDb2RlYyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLworCitzdGF0aWMKK2NoYXIgdXRmOF9jb2RlX2xlbmd0aFsyNTZdID0geworICAgIC8qIE1hcCBVVEYtOCBlbmNvZGVkIHByZWZpeCBieXRlIHRvIHNlcXVlbmNlIGxlbmd0aC4gIFplcm8gbWVhbnMKKyAgICAgICBpbGxlZ2FsIHByZWZpeC4gIFNlZSBSRkMgMzYyOSBmb3IgZGV0YWlscyAqLworICAgIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIC8qIDAwLTBGICovCisgICAgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwKKyAgICAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLAorICAgIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsCisgICAgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwKKyAgICAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLAorICAgIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsCisgICAgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgLyogNzAtN0YgKi8KKyAgICAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAvKiA4MC04RiAqLworICAgIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsCisgICAgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwKKyAgICAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAvKiBCMC1CRiAqLworICAgIDAsIDAsIDIsIDIsIDIsIDIsIDIsIDIsIDIsIDIsIDIsIDIsIDIsIDIsIDIsIDIsIC8qIEMwLUMxICsgQzItQ0YgKi8KKyAgICAyLCAyLCAyLCAyLCAyLCAyLCAyLCAyLCAyLCAyLCAyLCAyLCAyLCAyLCAyLCAyLCAvKiBEMC1ERiAqLworICAgIDMsIDMsIDMsIDMsIDMsIDMsIDMsIDMsIDMsIDMsIDMsIDMsIDMsIDMsIDMsIDMsIC8qIEUwLUVGICovCisgICAgNCwgNCwgNCwgNCwgNCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCAgLyogRjAtRjQgKyBGNS1GRiAqLworfTsKKworUHlPYmplY3QgKlB5VW5pY29kZV9EZWNvZGVVVEY4KGNvbnN0IGNoYXIgKnMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHlfc3NpemVfdCBzaXplLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgKmVycm9ycykKK3sKKyAgICByZXR1cm4gUHlVbmljb2RlX0RlY29kZVVURjhTdGF0ZWZ1bChzLCBzaXplLCBlcnJvcnMsIE5VTEwpOworfQorCitQeU9iamVjdCAqUHlVbmljb2RlX0RlY29kZVVURjhTdGF0ZWZ1bChjb25zdCBjaGFyICpzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHlfc3NpemVfdCBzaXplLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciAqZXJyb3JzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHlfc3NpemVfdCAqY29uc3VtZWQpCit7CisgICAgY29uc3QgY2hhciAqc3RhcnRzID0gczsKKyAgICBpbnQgbjsKKyAgICBpbnQgazsKKyAgICBQeV9zc2l6ZV90IHN0YXJ0aW5wb3M7CisgICAgUHlfc3NpemVfdCBlbmRpbnBvczsKKyAgICBQeV9zc2l6ZV90IG91dHBvczsKKyAgICBjb25zdCBjaGFyICplOworICAgIFB5VW5pY29kZU9iamVjdCAqdW5pY29kZTsKKyAgICBQeV9VTklDT0RFICpwOworICAgIGNvbnN0IGNoYXIgKmVycm1zZyA9ICIiOworICAgIFB5T2JqZWN0ICplcnJvckhhbmRsZXIgPSBOVUxMOworICAgIFB5T2JqZWN0ICpleGMgPSBOVUxMOworCisgICAgLyogTm90ZTogc2l6ZSB3aWxsIGFsd2F5cyBiZSBsb25nZXIgdGhhbiB0aGUgcmVzdWx0aW5nIFVuaWNvZGUKKyAgICAgICBjaGFyYWN0ZXIgY291bnQgKi8KKyAgICB1bmljb2RlID0gX1B5VW5pY29kZV9OZXcoc2l6ZSk7CisgICAgaWYgKCF1bmljb2RlKQorICAgICAgICByZXR1cm4gTlVMTDsKKyAgICBpZiAoc2l6ZSA9PSAwKSB7CisgICAgICAgIGlmIChjb25zdW1lZCkKKyAgICAgICAgICAgICpjb25zdW1lZCA9IDA7CisgICAgICAgIHJldHVybiAoUHlPYmplY3QgKil1bmljb2RlOworICAgIH0KKworICAgIC8qIFVucGFjayBVVEYtOCBlbmNvZGVkIGRhdGEgKi8KKyAgICBwID0gdW5pY29kZS0+c3RyOworICAgIGUgPSBzICsgc2l6ZTsKKworICAgIHdoaWxlIChzIDwgZSkgeworICAgICAgICBQeV9VQ1M0IGNoID0gKHVuc2lnbmVkIGNoYXIpKnM7CisKKyAgICAgICAgaWYgKGNoIDwgMHg4MCkgeworICAgICAgICAgICAgKnArKyA9IChQeV9VTklDT0RFKWNoOworICAgICAgICAgICAgcysrOworICAgICAgICAgICAgY29udGludWU7CisgICAgICAgIH0KKworICAgICAgICBuID0gdXRmOF9jb2RlX2xlbmd0aFtjaF07CisKKyAgICAgICAgaWYgKHMgKyBuID4gZSkgeworICAgICAgICAgICAgaWYgKGNvbnN1bWVkKQorICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgZWxzZSB7CisgICAgICAgICAgICAgICAgZXJybXNnID0gInVuZXhwZWN0ZWQgZW5kIG9mIGRhdGEiOworICAgICAgICAgICAgICAgIHN0YXJ0aW5wb3MgPSBzLXN0YXJ0czsKKyAgICAgICAgICAgICAgICBlbmRpbnBvcyA9IHN0YXJ0aW5wb3MrMTsKKyAgICAgICAgICAgICAgICBmb3IgKGs9MTsgKGsgPCBzaXplLXN0YXJ0aW5wb3MpICYmICgoc1trXSYweEMwKSA9PSAweDgwKTsgaysrKQorICAgICAgICAgICAgICAgICAgICBlbmRpbnBvcysrOworICAgICAgICAgICAgICAgIGdvdG8gdXRmOEVycm9yOworICAgICAgICAgICAgfQorICAgICAgICB9CisKKyAgICAgICAgc3dpdGNoIChuKSB7CisKKyAgICAgICAgY2FzZSAwOgorICAgICAgICAgICAgZXJybXNnID0gImludmFsaWQgc3RhcnQgYnl0ZSI7CisgICAgICAgICAgICBzdGFydGlucG9zID0gcy1zdGFydHM7CisgICAgICAgICAgICBlbmRpbnBvcyA9IHN0YXJ0aW5wb3MrMTsKKyAgICAgICAgICAgIGdvdG8gdXRmOEVycm9yOworCisgICAgICAgIGNhc2UgMToKKyAgICAgICAgICAgIGVycm1zZyA9ICJpbnRlcm5hbCBlcnJvciI7CisgICAgICAgICAgICBzdGFydGlucG9zID0gcy1zdGFydHM7CisgICAgICAgICAgICBlbmRpbnBvcyA9IHN0YXJ0aW5wb3MrMTsKKyAgICAgICAgICAgIGdvdG8gdXRmOEVycm9yOworCisgICAgICAgIGNhc2UgMjoKKyAgICAgICAgICAgIGlmICgoc1sxXSAmIDB4YzApICE9IDB4ODApIHsKKyAgICAgICAgICAgICAgICBlcnJtc2cgPSAiaW52YWxpZCBjb250aW51YXRpb24gYnl0ZSI7CisgICAgICAgICAgICAgICAgc3RhcnRpbnBvcyA9IHMtc3RhcnRzOworICAgICAgICAgICAgICAgIGVuZGlucG9zID0gc3RhcnRpbnBvcyArIDE7CisgICAgICAgICAgICAgICAgZ290byB1dGY4RXJyb3I7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBjaCA9ICgoc1swXSAmIDB4MWYpIDw8IDYpICsgKHNbMV0gJiAweDNmKTsKKyAgICAgICAgICAgIGFzc2VydCAoKGNoID4gMHgwMDdGKSAmJiAoY2ggPD0gMHgwN0ZGKSk7CisgICAgICAgICAgICAqcCsrID0gKFB5X1VOSUNPREUpY2g7CisgICAgICAgICAgICBicmVhazsKKworICAgICAgICBjYXNlIDM6CisgICAgICAgICAgICAvKiBYWFg6IHN1cnJvZ2F0ZXMgc2hvdWxkbid0IGJlIHZhbGlkIFVURi04IQorICAgICAgICAgICAgICAgc2VlIGh0dHA6Ly93d3cudW5pY29kZS5vcmcvdmVyc2lvbnMvVW5pY29kZTUuMi4wL2NoMDMucGRmCisgICAgICAgICAgICAgICAodGFibGUgMy03KSBhbmQgaHR0cDovL3d3dy5yZmMtZWRpdG9yLm9yZy9yZmMvcmZjMzYyOS50eHQKKyAgICAgICAgICAgICAgIFVuY29tbWVudCB0aGUgMiBsaW5lcyBiZWxvdyB0byBtYWtlIHRoZW0gaW52YWxpZCwKKyAgICAgICAgICAgICAgIGNvZGVwb2ludHM6IGQ4MDAtZGZmZjsgVVRGLTg6IFx4ZWRceGEwXHg4MC1ceGVkXHhiZlx4YmYuICovCisgICAgICAgICAgICBpZiAoKHNbMV0gJiAweGMwKSAhPSAweDgwIHx8CisgICAgICAgICAgICAgICAgKHNbMl0gJiAweGMwKSAhPSAweDgwIHx8CisgICAgICAgICAgICAgICAgKCh1bnNpZ25lZCBjaGFyKXNbMF0gPT0gMHhFMCAmJgorICAgICAgICAgICAgICAgICAodW5zaWduZWQgY2hhcilzWzFdIDwgMHhBMCkvKiB8fAorICAgICAgICAgICAgICAgICgodW5zaWduZWQgY2hhcilzWzBdID09IDB4RUQgJiYKKyAgICAgICAgICAgICAgICAgKHVuc2lnbmVkIGNoYXIpc1sxXSA+IDB4OUYpKi8pIHsKKyAgICAgICAgICAgICAgICBlcnJtc2cgPSAiaW52YWxpZCBjb250aW51YXRpb24gYnl0ZSI7CisgICAgICAgICAgICAgICAgc3RhcnRpbnBvcyA9IHMtc3RhcnRzOworICAgICAgICAgICAgICAgIGVuZGlucG9zID0gc3RhcnRpbnBvcyArIDE7CisKKyAgICAgICAgICAgICAgICAvKiBpZiBzWzFdIGZpcnN0IHR3byBiaXRzIGFyZSAxIGFuZCAwLCB0aGVuIHRoZSBpbnZhbGlkCisgICAgICAgICAgICAgICAgICAgY29udGludWF0aW9uIGJ5dGUgaXMgc1syXSwgc28gaW5jcmVtZW50IGVuZGlucG9zIGJ5IDEsCisgICAgICAgICAgICAgICAgICAgaWYgbm90LCBzWzFdIGlzIGludmFsaWQgYW5kIGVuZGlucG9zIGRvZXNuJ3QgbmVlZCB0bworICAgICAgICAgICAgICAgICAgIGJlIGluY3JlbWVudGVkLiAqLworICAgICAgICAgICAgICAgIGlmICgoc1sxXSAmIDB4QzApID09IDB4ODApCisgICAgICAgICAgICAgICAgICAgIGVuZGlucG9zKys7CisgICAgICAgICAgICAgICAgZ290byB1dGY4RXJyb3I7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBjaCA9ICgoc1swXSAmIDB4MGYpIDw8IDEyKSArICgoc1sxXSAmIDB4M2YpIDw8IDYpICsgKHNbMl0gJiAweDNmKTsKKyAgICAgICAgICAgIGFzc2VydCAoKGNoID4gMHgwN0ZGKSAmJiAoY2ggPD0gMHhGRkZGKSk7CisgICAgICAgICAgICAqcCsrID0gKFB5X1VOSUNPREUpY2g7CisgICAgICAgICAgICBicmVhazsKKworICAgICAgICBjYXNlIDQ6CisgICAgICAgICAgICBpZiAoKHNbMV0gJiAweGMwKSAhPSAweDgwIHx8CisgICAgICAgICAgICAgICAgKHNbMl0gJiAweGMwKSAhPSAweDgwIHx8CisgICAgICAgICAgICAgICAgKHNbM10gJiAweGMwKSAhPSAweDgwIHx8CisgICAgICAgICAgICAgICAgKCh1bnNpZ25lZCBjaGFyKXNbMF0gPT0gMHhGMCAmJgorICAgICAgICAgICAgICAgICAodW5zaWduZWQgY2hhcilzWzFdIDwgMHg5MCkgfHwKKyAgICAgICAgICAgICAgICAoKHVuc2lnbmVkIGNoYXIpc1swXSA9PSAweEY0ICYmCisgICAgICAgICAgICAgICAgICh1bnNpZ25lZCBjaGFyKXNbMV0gPiAweDhGKSkgeworICAgICAgICAgICAgICAgIGVycm1zZyA9ICJpbnZhbGlkIGNvbnRpbnVhdGlvbiBieXRlIjsKKyAgICAgICAgICAgICAgICBzdGFydGlucG9zID0gcy1zdGFydHM7CisgICAgICAgICAgICAgICAgZW5kaW5wb3MgPSBzdGFydGlucG9zICsgMTsKKyAgICAgICAgICAgICAgICBpZiAoKHNbMV0gJiAweEMwKSA9PSAweDgwKSB7CisgICAgICAgICAgICAgICAgICAgIGVuZGlucG9zKys7CisgICAgICAgICAgICAgICAgICAgIGlmICgoc1syXSAmIDB4QzApID09IDB4ODApCisgICAgICAgICAgICAgICAgICAgICAgICBlbmRpbnBvcysrOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBnb3RvIHV0ZjhFcnJvcjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGNoID0gKChzWzBdICYgMHg3KSA8PCAxOCkgKyAoKHNbMV0gJiAweDNmKSA8PCAxMikgKworICAgICAgICAgICAgICAgICAoKHNbMl0gJiAweDNmKSA8PCA2KSArIChzWzNdICYgMHgzZik7CisgICAgICAgICAgICBhc3NlcnQgKChjaCA+IDB4RkZGRikgJiYgKGNoIDw9IDB4MTBmZmZmKSk7CisKKyNpZmRlZiBQeV9VTklDT0RFX1dJREUKKyAgICAgICAgICAgICpwKysgPSAoUHlfVU5JQ09ERSljaDsKKyNlbHNlCisgICAgICAgICAgICAvKiAgY29tcHV0ZSBhbmQgYXBwZW5kIHRoZSB0d28gc3Vycm9nYXRlczogKi8KKworICAgICAgICAgICAgLyogIHRyYW5zbGF0ZSBmcm9tIDEwMDAwLi4xMEZGRkYgdG8gMC4uRkZGRiAqLworICAgICAgICAgICAgY2ggLT0gMHgxMDAwMDsKKworICAgICAgICAgICAgLyogIGhpZ2ggc3Vycm9nYXRlID0gdG9wIDEwIGJpdHMgYWRkZWQgdG8gRDgwMCAqLworICAgICAgICAgICAgKnArKyA9IChQeV9VTklDT0RFKSgweEQ4MDAgKyAoY2ggPj4gMTApKTsKKworICAgICAgICAgICAgLyogIGxvdyBzdXJyb2dhdGUgPSBib3R0b20gMTAgYml0cyBhZGRlZCB0byBEQzAwICovCisgICAgICAgICAgICAqcCsrID0gKFB5X1VOSUNPREUpKDB4REMwMCArIChjaCAmIDB4MDNGRikpOworI2VuZGlmCisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgfQorICAgICAgICBzICs9IG47CisgICAgICAgIGNvbnRpbnVlOworCisgICAgICB1dGY4RXJyb3I6CisgICAgICAgIG91dHBvcyA9IHAtUHlVbmljb2RlX0FTX1VOSUNPREUodW5pY29kZSk7CisgICAgICAgIGlmICh1bmljb2RlX2RlY29kZV9jYWxsX2Vycm9yaGFuZGxlcigKKyAgICAgICAgICAgICAgICBlcnJvcnMsICZlcnJvckhhbmRsZXIsCisgICAgICAgICAgICAgICAgInV0ZjgiLCBlcnJtc2csCisgICAgICAgICAgICAgICAgc3RhcnRzLCBzaXplLCAmc3RhcnRpbnBvcywgJmVuZGlucG9zLCAmZXhjLCAmcywKKyAgICAgICAgICAgICAgICAmdW5pY29kZSwgJm91dHBvcywgJnApKQorICAgICAgICAgICAgZ290byBvbkVycm9yOworICAgIH0KKyAgICBpZiAoY29uc3VtZWQpCisgICAgICAgICpjb25zdW1lZCA9IHMtc3RhcnRzOworCisgICAgLyogQWRqdXN0IGxlbmd0aCAqLworICAgIGlmIChfUHlVbmljb2RlX1Jlc2l6ZSgmdW5pY29kZSwgcCAtIHVuaWNvZGUtPnN0cikgPCAwKQorICAgICAgICBnb3RvIG9uRXJyb3I7CisKKyAgICBQeV9YREVDUkVGKGVycm9ySGFuZGxlcik7CisgICAgUHlfWERFQ1JFRihleGMpOworICAgIHJldHVybiAoUHlPYmplY3QgKil1bmljb2RlOworCisgIG9uRXJyb3I6CisgICAgUHlfWERFQ1JFRihlcnJvckhhbmRsZXIpOworICAgIFB5X1hERUNSRUYoZXhjKTsKKyAgICBQeV9ERUNSRUYodW5pY29kZSk7CisgICAgcmV0dXJuIE5VTEw7Cit9CisKKy8qIEFsbG9jYXRpb24gc3RyYXRlZ3k6ICBpZiB0aGUgc3RyaW5nIGlzIHNob3J0LCBjb252ZXJ0IGludG8gYSBzdGFjayBidWZmZXIKKyAgIGFuZCBhbGxvY2F0ZSBleGFjdGx5IGFzIG11Y2ggc3BhY2UgbmVlZGVkIGF0IHRoZSBlbmQuICBFbHNlIGFsbG9jYXRlIHRoZQorICAgbWF4aW11bSBwb3NzaWJsZSBuZWVkZWQgKDQgcmVzdWx0IGJ5dGVzIHBlciBVbmljb2RlIGNoYXJhY3RlciksIGFuZCByZXR1cm4KKyAgIHRoZSBleGNlc3MgbWVtb3J5IGF0IHRoZSBlbmQuCisqLworUHlPYmplY3QgKgorUHlVbmljb2RlX0VuY29kZVVURjgoY29uc3QgUHlfVU5JQ09ERSAqcywKKyAgICAgICAgICAgICAgICAgICAgIFB5X3NzaXplX3Qgc2l6ZSwKKyAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgKmVycm9ycykKK3sKKyNkZWZpbmUgTUFYX1NIT1JUX1VOSUNIQVJTIDMwMCAgLyogbGFyZ2VzdCBzaXplIHdlJ2xsIGRvIG9uIHRoZSBzdGFjayAqLworCisgICAgUHlfc3NpemVfdCBpOyAgICAgICAgICAgLyogaW5kZXggaW50byBzIG9mIG5leHQgaW5wdXQgYnl0ZSAqLworICAgIFB5T2JqZWN0ICp2OyAgICAgICAgLyogcmVzdWx0IHN0cmluZyBvYmplY3QgKi8KKyAgICBjaGFyICpwOyAgICAgICAgICAgIC8qIG5leHQgZnJlZSBieXRlIGluIG91dHB1dCBidWZmZXIgKi8KKyAgICBQeV9zc2l6ZV90IG5hbGxvY2F0ZWQ7ICAvKiBudW1iZXIgb2YgcmVzdWx0IGJ5dGVzIGFsbG9jYXRlZCAqLworICAgIFB5X3NzaXplX3Qgbm5lZWRlZDsgICAgICAgIC8qIG51bWJlciBvZiByZXN1bHQgYnl0ZXMgbmVlZGVkICovCisgICAgY2hhciBzdGFja2J1ZltNQVhfU0hPUlRfVU5JQ0hBUlMgKiA0XTsKKworICAgIGFzc2VydChzICE9IE5VTEwpOworICAgIGFzc2VydChzaXplID49IDApOworCisgICAgaWYgKHNpemUgPD0gTUFYX1NIT1JUX1VOSUNIQVJTKSB7CisgICAgICAgIC8qIFdyaXRlIGludG8gdGhlIHN0YWNrIGJ1ZmZlcjsgbmFsbG9jYXRlZCBjYW4ndCBvdmVyZmxvdy4KKyAgICAgICAgICogQXQgdGhlIGVuZCwgd2UnbGwgYWxsb2NhdGUgZXhhY3RseSBhcyBtdWNoIGhlYXAgc3BhY2UgYXMgaXQKKyAgICAgICAgICogdHVybnMgb3V0IHdlIG5lZWQuCisgICAgICAgICAqLworICAgICAgICBuYWxsb2NhdGVkID0gUHlfU0FGRV9ET1dOQ0FTVChzaXplb2Yoc3RhY2tidWYpLCBzaXplX3QsIGludCk7CisgICAgICAgIHYgPSBOVUxMOyAgIC8qIHdpbGwgYWxsb2NhdGUgYWZ0ZXIgd2UncmUgZG9uZSAqLworICAgICAgICBwID0gc3RhY2tidWY7CisgICAgfQorICAgIGVsc2UgeworICAgICAgICAvKiBPdmVyYWxsb2NhdGUgb24gdGhlIGhlYXAsIGFuZCBnaXZlIHRoZSBleGNlc3MgYmFjayBhdCB0aGUgZW5kLiAqLworICAgICAgICBuYWxsb2NhdGVkID0gc2l6ZSAqIDQ7CisgICAgICAgIGlmIChuYWxsb2NhdGVkIC8gNCAhPSBzaXplKSAgLyogb3ZlcmZsb3chICovCisgICAgICAgICAgICByZXR1cm4gUHlFcnJfTm9NZW1vcnkoKTsKKyAgICAgICAgdiA9IFB5U3RyaW5nX0Zyb21TdHJpbmdBbmRTaXplKE5VTEwsIG5hbGxvY2F0ZWQpOworICAgICAgICBpZiAodiA9PSBOVUxMKQorICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgICAgIHAgPSBQeVN0cmluZ19BU19TVFJJTkcodik7CisgICAgfQorCisgICAgZm9yIChpID0gMDsgaSA8IHNpemU7KSB7CisgICAgICAgIFB5X1VDUzQgY2ggPSBzW2krK107CisKKyAgICAgICAgaWYgKGNoIDwgMHg4MCkKKyAgICAgICAgICAgIC8qIEVuY29kZSBBU0NJSSAqLworICAgICAgICAgICAgKnArKyA9IChjaGFyKSBjaDsKKworICAgICAgICBlbHNlIGlmIChjaCA8IDB4MDgwMCkgeworICAgICAgICAgICAgLyogRW5jb2RlIExhdGluLTEgKi8KKyAgICAgICAgICAgICpwKysgPSAoY2hhcikoMHhjMCB8IChjaCA+PiA2KSk7CisgICAgICAgICAgICAqcCsrID0gKGNoYXIpKDB4ODAgfCAoY2ggJiAweDNmKSk7CisgICAgICAgIH0KKyAgICAgICAgZWxzZSB7CisgICAgICAgICAgICAvKiBFbmNvZGUgVUNTMiBVbmljb2RlIG9yZGluYWxzICovCisgICAgICAgICAgICBpZiAoY2ggPCAweDEwMDAwKSB7CisgICAgICAgICAgICAgICAgLyogU3BlY2lhbCBjYXNlOiBjaGVjayBmb3IgaGlnaCBzdXJyb2dhdGUgKi8KKyAgICAgICAgICAgICAgICBpZiAoMHhEODAwIDw9IGNoICYmIGNoIDw9IDB4REJGRiAmJiBpICE9IHNpemUpIHsKKyAgICAgICAgICAgICAgICAgICAgUHlfVUNTNCBjaDIgPSBzW2ldOworICAgICAgICAgICAgICAgICAgICAvKiBDaGVjayBmb3IgbG93IHN1cnJvZ2F0ZSBhbmQgY29tYmluZSB0aGUgdHdvIHRvCisgICAgICAgICAgICAgICAgICAgICAgIGZvcm0gYSBVQ1M0IHZhbHVlICovCisgICAgICAgICAgICAgICAgICAgIGlmICgweERDMDAgPD0gY2gyICYmIGNoMiA8PSAweERGRkYpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGNoID0gKChjaCAtIDB4RDgwMCkgPDwgMTAgfCAoY2gyIC0gMHhEQzAwKSkgKyAweDEwMDAwOworICAgICAgICAgICAgICAgICAgICAgICAgaSsrOworICAgICAgICAgICAgICAgICAgICAgICAgZ290byBlbmNvZGVVQ1M0OworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIC8qIEZhbGwgdGhyb3VnaDogaGFuZGxlcyBpc29sYXRlZCBoaWdoIHN1cnJvZ2F0ZXMgKi8KKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgKnArKyA9IChjaGFyKSgweGUwIHwgKGNoID4+IDEyKSk7CisgICAgICAgICAgICAgICAgKnArKyA9IChjaGFyKSgweDgwIHwgKChjaCA+PiA2KSAmIDB4M2YpKTsKKyAgICAgICAgICAgICAgICAqcCsrID0gKGNoYXIpKDB4ODAgfCAoY2ggJiAweDNmKSk7CisgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICB9CisgICAgICAgICAgZW5jb2RlVUNTNDoKKyAgICAgICAgICAgIC8qIEVuY29kZSBVQ1M0IFVuaWNvZGUgb3JkaW5hbHMgKi8KKyAgICAgICAgICAgICpwKysgPSAoY2hhcikoMHhmMCB8IChjaCA+PiAxOCkpOworICAgICAgICAgICAgKnArKyA9IChjaGFyKSgweDgwIHwgKChjaCA+PiAxMikgJiAweDNmKSk7CisgICAgICAgICAgICAqcCsrID0gKGNoYXIpKDB4ODAgfCAoKGNoID4+IDYpICYgMHgzZikpOworICAgICAgICAgICAgKnArKyA9IChjaGFyKSgweDgwIHwgKGNoICYgMHgzZikpOworICAgICAgICB9CisgICAgfQorCisgICAgaWYgKHYgPT0gTlVMTCkgeworICAgICAgICAvKiBUaGlzIHdhcyBzdGFjayBhbGxvY2F0ZWQuICovCisgICAgICAgIG5uZWVkZWQgPSBwIC0gc3RhY2tidWY7CisgICAgICAgIGFzc2VydChubmVlZGVkIDw9IG5hbGxvY2F0ZWQpOworICAgICAgICB2ID0gUHlTdHJpbmdfRnJvbVN0cmluZ0FuZFNpemUoc3RhY2tidWYsIG5uZWVkZWQpOworICAgIH0KKyAgICBlbHNlIHsKKyAgICAgICAgLyogQ3V0IGJhY2sgdG8gc2l6ZSBhY3R1YWxseSBuZWVkZWQuICovCisgICAgICAgIG5uZWVkZWQgPSBwIC0gUHlTdHJpbmdfQVNfU1RSSU5HKHYpOworICAgICAgICBhc3NlcnQobm5lZWRlZCA8PSBuYWxsb2NhdGVkKTsKKyAgICAgICAgaWYgKF9QeVN0cmluZ19SZXNpemUoJnYsIG5uZWVkZWQpKQorICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIHJldHVybiB2OworCisjdW5kZWYgTUFYX1NIT1JUX1VOSUNIQVJTCit9CisKK1B5T2JqZWN0ICpQeVVuaWNvZGVfQXNVVEY4U3RyaW5nKFB5T2JqZWN0ICp1bmljb2RlKQoreworICAgIGlmICghUHlVbmljb2RlX0NoZWNrKHVuaWNvZGUpKSB7CisgICAgICAgIFB5RXJyX0JhZEFyZ3VtZW50KCk7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICByZXR1cm4gUHlVbmljb2RlX0VuY29kZVVURjgoUHlVbmljb2RlX0FTX1VOSUNPREUodW5pY29kZSksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFB5VW5pY29kZV9HRVRfU0laRSh1bmljb2RlKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCk7Cit9CisKKy8qIC0tLSBVVEYtMzIgQ29kZWMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLworCitQeU9iamVjdCAqCitQeVVuaWNvZGVfRGVjb2RlVVRGMzIoY29uc3QgY2hhciAqcywKKyAgICAgICAgICAgICAgICAgICAgICBQeV9zc2l6ZV90IHNpemUsCisgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciAqZXJyb3JzLAorICAgICAgICAgICAgICAgICAgICAgIGludCAqYnl0ZW9yZGVyKQoreworICAgIHJldHVybiBQeVVuaWNvZGVfRGVjb2RlVVRGMzJTdGF0ZWZ1bChzLCBzaXplLCBlcnJvcnMsIGJ5dGVvcmRlciwgTlVMTCk7Cit9CisKK1B5T2JqZWN0ICoKK1B5VW5pY29kZV9EZWNvZGVVVEYzMlN0YXRlZnVsKGNvbnN0IGNoYXIgKnMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQeV9zc2l6ZV90IHNpemUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyICplcnJvcnMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgKmJ5dGVvcmRlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFB5X3NzaXplX3QgKmNvbnN1bWVkKQoreworICAgIGNvbnN0IGNoYXIgKnN0YXJ0cyA9IHM7CisgICAgUHlfc3NpemVfdCBzdGFydGlucG9zOworICAgIFB5X3NzaXplX3QgZW5kaW5wb3M7CisgICAgUHlfc3NpemVfdCBvdXRwb3M7CisgICAgUHlVbmljb2RlT2JqZWN0ICp1bmljb2RlOworICAgIFB5X1VOSUNPREUgKnA7CisjaWZuZGVmIFB5X1VOSUNPREVfV0lERQorICAgIGludCBwYWlycyA9IDA7CisgICAgY29uc3QgdW5zaWduZWQgY2hhciAqcXE7CisjZWxzZQorICAgIGNvbnN0IGludCBwYWlycyA9IDA7CisjZW5kaWYKKyAgICBjb25zdCB1bnNpZ25lZCBjaGFyICpxLCAqZTsKKyAgICBpbnQgYm8gPSAwOyAgICAgICAvKiBhc3N1bWUgbmF0aXZlIG9yZGVyaW5nIGJ5IGRlZmF1bHQgKi8KKyAgICBjb25zdCBjaGFyICplcnJtc2cgPSAiIjsKKyAgICAvKiBPZmZzZXRzIGZyb20gcSBmb3IgcmV0cmlldmluZyBieXRlcyBpbiB0aGUgcmlnaHQgb3JkZXIuICovCisjaWZkZWYgQllURU9SREVSX0lTX0xJVFRMRV9FTkRJQU4KKyAgICBpbnQgaW9yZGVyW10gPSB7MCwgMSwgMiwgM307CisjZWxzZQorICAgIGludCBpb3JkZXJbXSA9IHszLCAyLCAxLCAwfTsKKyNlbmRpZgorICAgIFB5T2JqZWN0ICplcnJvckhhbmRsZXIgPSBOVUxMOworICAgIFB5T2JqZWN0ICpleGMgPSBOVUxMOworCisgICAgcSA9ICh1bnNpZ25lZCBjaGFyICopczsKKyAgICBlID0gcSArIHNpemU7CisKKyAgICBpZiAoYnl0ZW9yZGVyKQorICAgICAgICBibyA9ICpieXRlb3JkZXI7CisKKyAgICAvKiBDaGVjayBmb3IgQk9NIG1hcmtzIChVK0ZFRkYpIGluIHRoZSBpbnB1dCBhbmQgYWRqdXN0IGN1cnJlbnQKKyAgICAgICBieXRlIG9yZGVyIHNldHRpbmcgYWNjb3JkaW5nbHkuIEluIG5hdGl2ZSBtb2RlLCB0aGUgbGVhZGluZyBCT00KKyAgICAgICBtYXJrIGlzIHNraXBwZWQsIGluIGFsbCBvdGhlciBtb2RlcywgaXQgaXMgY29waWVkIHRvIHRoZSBvdXRwdXQKKyAgICAgICBzdHJlYW0gYXMtaXMgKGdpdmluZyBhIFpXTkJTUCBjaGFyYWN0ZXIpLiAqLworICAgIGlmIChibyA9PSAwKSB7CisgICAgICAgIGlmIChzaXplID49IDQpIHsKKyAgICAgICAgICAgIGNvbnN0IFB5X1VDUzQgYm9tID0gKHFbaW9yZGVyWzNdXSA8PCAyNCkgfCAocVtpb3JkZXJbMl1dIDw8IDE2KSB8CisgICAgICAgICAgICAgICAgKHFbaW9yZGVyWzFdXSA8PCA4KSB8IHFbaW9yZGVyWzBdXTsKKyNpZmRlZiBCWVRFT1JERVJfSVNfTElUVExFX0VORElBTgorICAgICAgICAgICAgaWYgKGJvbSA9PSAweDAwMDBGRUZGKSB7CisgICAgICAgICAgICAgICAgcSArPSA0OworICAgICAgICAgICAgICAgIGJvID0gLTE7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBlbHNlIGlmIChib20gPT0gMHhGRkZFMDAwMCkgeworICAgICAgICAgICAgICAgIHEgKz0gNDsKKyAgICAgICAgICAgICAgICBibyA9IDE7CisgICAgICAgICAgICB9CisjZWxzZQorICAgICAgICAgICAgaWYgKGJvbSA9PSAweDAwMDBGRUZGKSB7CisgICAgICAgICAgICAgICAgcSArPSA0OworICAgICAgICAgICAgICAgIGJvID0gMTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGVsc2UgaWYgKGJvbSA9PSAweEZGRkUwMDAwKSB7CisgICAgICAgICAgICAgICAgcSArPSA0OworICAgICAgICAgICAgICAgIGJvID0gLTE7CisgICAgICAgICAgICB9CisjZW5kaWYKKyAgICAgICAgfQorICAgIH0KKworICAgIGlmIChibyA9PSAtMSkgeworICAgICAgICAvKiBmb3JjZSBMRSAqLworICAgICAgICBpb3JkZXJbMF0gPSAwOworICAgICAgICBpb3JkZXJbMV0gPSAxOworICAgICAgICBpb3JkZXJbMl0gPSAyOworICAgICAgICBpb3JkZXJbM10gPSAzOworICAgIH0KKyAgICBlbHNlIGlmIChibyA9PSAxKSB7CisgICAgICAgIC8qIGZvcmNlIEJFICovCisgICAgICAgIGlvcmRlclswXSA9IDM7CisgICAgICAgIGlvcmRlclsxXSA9IDI7CisgICAgICAgIGlvcmRlclsyXSA9IDE7CisgICAgICAgIGlvcmRlclszXSA9IDA7CisgICAgfQorCisgICAgLyogT24gbmFycm93IGJ1aWxkcyB3ZSBzcGxpdCBjaGFyYWN0ZXJzIG91dHNpZGUgdGhlIEJNUCBpbnRvIHR3bworICAgICAgIGNvZGVwb2ludHMgPT4gY291bnQgaG93IG11Y2ggZXh0cmEgc3BhY2Ugd2UgbmVlZC4gKi8KKyNpZm5kZWYgUHlfVU5JQ09ERV9XSURFCisgICAgZm9yIChxcSA9IHE7IGUgLSBxcSA+PSA0OyBxcSArPSA0KQorICAgICAgICBpZiAocXFbaW9yZGVyWzJdXSAhPSAwIHx8IHFxW2lvcmRlclszXV0gIT0gMCkKKyAgICAgICAgICAgIHBhaXJzKys7CisjZW5kaWYKKworICAgIC8qIFRoaXMgbWlnaHQgYmUgb25lIHRvIG11Y2gsIGJlY2F1c2Ugb2YgYSBCT00gKi8KKyAgICB1bmljb2RlID0gX1B5VW5pY29kZV9OZXcoKHNpemUrMykvNCtwYWlycyk7CisgICAgaWYgKCF1bmljb2RlKQorICAgICAgICByZXR1cm4gTlVMTDsKKyAgICBpZiAoc2l6ZSA9PSAwKQorICAgICAgICByZXR1cm4gKFB5T2JqZWN0ICopdW5pY29kZTsKKworICAgIC8qIFVucGFjayBVVEYtMzIgZW5jb2RlZCBkYXRhICovCisgICAgcCA9IHVuaWNvZGUtPnN0cjsKKworICAgIHdoaWxlIChxIDwgZSkgeworICAgICAgICBQeV9VQ1M0IGNoOworICAgICAgICAvKiByZW1haW5pbmcgYnl0ZXMgYXQgdGhlIGVuZD8gKHNpemUgc2hvdWxkIGJlIGRpdmlzaWJsZSBieSA0KSAqLworICAgICAgICBpZiAoZS1xPDQpIHsKKyAgICAgICAgICAgIGlmIChjb25zdW1lZCkKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIGVycm1zZyA9ICJ0cnVuY2F0ZWQgZGF0YSI7CisgICAgICAgICAgICBzdGFydGlucG9zID0gKChjb25zdCBjaGFyICopcSktc3RhcnRzOworICAgICAgICAgICAgZW5kaW5wb3MgPSAoKGNvbnN0IGNoYXIgKillKS1zdGFydHM7CisgICAgICAgICAgICBnb3RvIHV0ZjMyRXJyb3I7CisgICAgICAgICAgICAvKiBUaGUgcmVtYWluaW5nIGlucHV0IGNoYXJzIGFyZSBpZ25vcmVkIGlmIHRoZSBjYWxsYmFjaworICAgICAgICAgICAgICAgY2hvb3NlcyB0byBza2lwIHRoZSBpbnB1dCAqLworICAgICAgICB9CisgICAgICAgIGNoID0gKHFbaW9yZGVyWzNdXSA8PCAyNCkgfCAocVtpb3JkZXJbMl1dIDw8IDE2KSB8CisgICAgICAgICAgICAocVtpb3JkZXJbMV1dIDw8IDgpIHwgcVtpb3JkZXJbMF1dOworCisgICAgICAgIGlmIChjaCA+PSAweDExMDAwMCkKKyAgICAgICAgeworICAgICAgICAgICAgZXJybXNnID0gImNvZGVwb2ludCBub3QgaW4gcmFuZ2UoMHgxMTAwMDApIjsKKyAgICAgICAgICAgIHN0YXJ0aW5wb3MgPSAoKGNvbnN0IGNoYXIgKilxKS1zdGFydHM7CisgICAgICAgICAgICBlbmRpbnBvcyA9IHN0YXJ0aW5wb3MrNDsKKyAgICAgICAgICAgIGdvdG8gdXRmMzJFcnJvcjsKKyAgICAgICAgfQorI2lmbmRlZiBQeV9VTklDT0RFX1dJREUKKyAgICAgICAgaWYgKGNoID49IDB4MTAwMDApCisgICAgICAgIHsKKyAgICAgICAgICAgICpwKysgPSAweEQ4MDAgfCAoKGNoLTB4MTAwMDApID4+IDEwKTsKKyAgICAgICAgICAgICpwKysgPSAweERDMDAgfCAoKGNoLTB4MTAwMDApICYgMHgzRkYpOworICAgICAgICB9CisgICAgICAgIGVsc2UKKyNlbmRpZgorICAgICAgICAgICAgKnArKyA9IGNoOworICAgICAgICBxICs9IDQ7CisgICAgICAgIGNvbnRpbnVlOworICAgICAgdXRmMzJFcnJvcjoKKyAgICAgICAgb3V0cG9zID0gcC1QeVVuaWNvZGVfQVNfVU5JQ09ERSh1bmljb2RlKTsKKyAgICAgICAgaWYgKHVuaWNvZGVfZGVjb2RlX2NhbGxfZXJyb3JoYW5kbGVyKAorICAgICAgICAgICAgICAgIGVycm9ycywgJmVycm9ySGFuZGxlciwKKyAgICAgICAgICAgICAgICAidXRmMzIiLCBlcnJtc2csCisgICAgICAgICAgICAgICAgc3RhcnRzLCBzaXplLCAmc3RhcnRpbnBvcywgJmVuZGlucG9zLCAmZXhjLCAoY29uc3QgY2hhciAqKikmcSwKKyAgICAgICAgICAgICAgICAmdW5pY29kZSwgJm91dHBvcywgJnApKQorICAgICAgICAgICAgZ290byBvbkVycm9yOworICAgIH0KKworICAgIGlmIChieXRlb3JkZXIpCisgICAgICAgICpieXRlb3JkZXIgPSBibzsKKworICAgIGlmIChjb25zdW1lZCkKKyAgICAgICAgKmNvbnN1bWVkID0gKGNvbnN0IGNoYXIgKilxLXN0YXJ0czsKKworICAgIC8qIEFkanVzdCBsZW5ndGggKi8KKyAgICBpZiAoX1B5VW5pY29kZV9SZXNpemUoJnVuaWNvZGUsIHAgLSB1bmljb2RlLT5zdHIpIDwgMCkKKyAgICAgICAgZ290byBvbkVycm9yOworCisgICAgUHlfWERFQ1JFRihlcnJvckhhbmRsZXIpOworICAgIFB5X1hERUNSRUYoZXhjKTsKKyAgICByZXR1cm4gKFB5T2JqZWN0ICopdW5pY29kZTsKKworICBvbkVycm9yOgorICAgIFB5X0RFQ1JFRih1bmljb2RlKTsKKyAgICBQeV9YREVDUkVGKGVycm9ySGFuZGxlcik7CisgICAgUHlfWERFQ1JFRihleGMpOworICAgIHJldHVybiBOVUxMOworfQorCitQeU9iamVjdCAqCitQeVVuaWNvZGVfRW5jb2RlVVRGMzIoY29uc3QgUHlfVU5JQ09ERSAqcywKKyAgICAgICAgICAgICAgICAgICAgICBQeV9zc2l6ZV90IHNpemUsCisgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciAqZXJyb3JzLAorICAgICAgICAgICAgICAgICAgICAgIGludCBieXRlb3JkZXIpCit7CisgICAgUHlPYmplY3QgKnY7CisgICAgdW5zaWduZWQgY2hhciAqcDsKKyAgICBQeV9zc2l6ZV90IG5zaXplLCBieXRlc2l6ZTsKKyNpZm5kZWYgUHlfVU5JQ09ERV9XSURFCisgICAgUHlfc3NpemVfdCBpLCBwYWlyczsKKyNlbHNlCisgICAgY29uc3QgaW50IHBhaXJzID0gMDsKKyNlbmRpZgorICAgIC8qIE9mZnNldHMgZnJvbSBwIGZvciBzdG9yaW5nIGJ5dGUgcGFpcnMgaW4gdGhlIHJpZ2h0IG9yZGVyLiAqLworI2lmZGVmIEJZVEVPUkRFUl9JU19MSVRUTEVfRU5ESUFOCisgICAgaW50IGlvcmRlcltdID0gezAsIDEsIDIsIDN9OworI2Vsc2UKKyAgICBpbnQgaW9yZGVyW10gPSB7MywgMiwgMSwgMH07CisjZW5kaWYKKworI2RlZmluZSBTVE9SRUNIQVIoQ0gpICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIGRvIHsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICBwW2lvcmRlclszXV0gPSAoKENIKSA+PiAyNCkgJiAweGZmOyAgICAgXAorICAgICAgICBwW2lvcmRlclsyXV0gPSAoKENIKSA+PiAxNikgJiAweGZmOyAgICAgXAorICAgICAgICBwW2lvcmRlclsxXV0gPSAoKENIKSA+PiA4KSAmIDB4ZmY7ICAgICAgXAorICAgICAgICBwW2lvcmRlclswXV0gPSAoQ0gpICYgMHhmZjsgICAgICAgICAgICAgXAorICAgICAgICBwICs9IDQ7ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIH0gd2hpbGUoMCkKKworICAgIC8qIEluIG5hcnJvdyBidWlsZHMgd2UgY2FuIG91dHB1dCBzdXJyb2dhdGUgcGFpcnMgYXMgb25lIGNvZGVwb2ludCwKKyAgICAgICBzbyB3ZSBuZWVkIGxlc3Mgc3BhY2UuICovCisjaWZuZGVmIFB5X1VOSUNPREVfV0lERQorICAgIGZvciAoaSA9IHBhaXJzID0gMDsgaSA8IHNpemUtMTsgaSsrKQorICAgICAgICBpZiAoMHhEODAwIDw9IHNbaV0gJiYgc1tpXSA8PSAweERCRkYgJiYKKyAgICAgICAgICAgIDB4REMwMCA8PSBzW2krMV0gJiYgc1tpKzFdIDw9IDB4REZGRikKKyAgICAgICAgICAgIHBhaXJzKys7CisjZW5kaWYKKyAgICBuc2l6ZSA9IChzaXplIC0gcGFpcnMgKyAoYnl0ZW9yZGVyID09IDApKTsKKyAgICBieXRlc2l6ZSA9IG5zaXplICogNDsKKyAgICBpZiAoYnl0ZXNpemUgLyA0ICE9IG5zaXplKQorICAgICAgICByZXR1cm4gUHlFcnJfTm9NZW1vcnkoKTsKKyAgICB2ID0gUHlTdHJpbmdfRnJvbVN0cmluZ0FuZFNpemUoTlVMTCwgYnl0ZXNpemUpOworICAgIGlmICh2ID09IE5VTEwpCisgICAgICAgIHJldHVybiBOVUxMOworCisgICAgcCA9ICh1bnNpZ25lZCBjaGFyICopUHlTdHJpbmdfQVNfU1RSSU5HKHYpOworICAgIGlmIChieXRlb3JkZXIgPT0gMCkKKyAgICAgICAgU1RPUkVDSEFSKDB4RkVGRik7CisgICAgaWYgKHNpemUgPT0gMCkKKyAgICAgICAgcmV0dXJuIHY7CisKKyAgICBpZiAoYnl0ZW9yZGVyID09IC0xKSB7CisgICAgICAgIC8qIGZvcmNlIExFICovCisgICAgICAgIGlvcmRlclswXSA9IDA7CisgICAgICAgIGlvcmRlclsxXSA9IDE7CisgICAgICAgIGlvcmRlclsyXSA9IDI7CisgICAgICAgIGlvcmRlclszXSA9IDM7CisgICAgfQorICAgIGVsc2UgaWYgKGJ5dGVvcmRlciA9PSAxKSB7CisgICAgICAgIC8qIGZvcmNlIEJFICovCisgICAgICAgIGlvcmRlclswXSA9IDM7CisgICAgICAgIGlvcmRlclsxXSA9IDI7CisgICAgICAgIGlvcmRlclsyXSA9IDE7CisgICAgICAgIGlvcmRlclszXSA9IDA7CisgICAgfQorCisgICAgd2hpbGUgKHNpemUtLSA+IDApIHsKKyAgICAgICAgUHlfVUNTNCBjaCA9ICpzKys7CisjaWZuZGVmIFB5X1VOSUNPREVfV0lERQorICAgICAgICBpZiAoMHhEODAwIDw9IGNoICYmIGNoIDw9IDB4REJGRiAmJiBzaXplID4gMCkgeworICAgICAgICAgICAgUHlfVUNTNCBjaDIgPSAqczsKKyAgICAgICAgICAgIGlmICgweERDMDAgPD0gY2gyICYmIGNoMiA8PSAweERGRkYpIHsKKyAgICAgICAgICAgICAgICBjaCA9ICgoKGNoICYgMHgzRkYpPDwxMCkgfCAoY2gyICYgMHgzRkYpKSArIDB4MTAwMDA7CisgICAgICAgICAgICAgICAgcysrOworICAgICAgICAgICAgICAgIHNpemUtLTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorI2VuZGlmCisgICAgICAgIFNUT1JFQ0hBUihjaCk7CisgICAgfQorICAgIHJldHVybiB2OworI3VuZGVmIFNUT1JFQ0hBUgorfQorCitQeU9iamVjdCAqUHlVbmljb2RlX0FzVVRGMzJTdHJpbmcoUHlPYmplY3QgKnVuaWNvZGUpCit7CisgICAgaWYgKCFQeVVuaWNvZGVfQ2hlY2sodW5pY29kZSkpIHsKKyAgICAgICAgUHlFcnJfQmFkQXJndW1lbnQoKTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIHJldHVybiBQeVVuaWNvZGVfRW5jb2RlVVRGMzIoUHlVbmljb2RlX0FTX1VOSUNPREUodW5pY29kZSksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQeVVuaWNvZGVfR0VUX1NJWkUodW5pY29kZSksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOVUxMLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMCk7Cit9CisKKy8qIC0tLSBVVEYtMTYgQ29kZWMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLworCitQeU9iamVjdCAqCitQeVVuaWNvZGVfRGVjb2RlVVRGMTYoY29uc3QgY2hhciAqcywKKyAgICAgICAgICAgICAgICAgICAgICBQeV9zc2l6ZV90IHNpemUsCisgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciAqZXJyb3JzLAorICAgICAgICAgICAgICAgICAgICAgIGludCAqYnl0ZW9yZGVyKQoreworICAgIHJldHVybiBQeVVuaWNvZGVfRGVjb2RlVVRGMTZTdGF0ZWZ1bChzLCBzaXplLCBlcnJvcnMsIGJ5dGVvcmRlciwgTlVMTCk7Cit9CisKK1B5T2JqZWN0ICoKK1B5VW5pY29kZV9EZWNvZGVVVEYxNlN0YXRlZnVsKGNvbnN0IGNoYXIgKnMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQeV9zc2l6ZV90IHNpemUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyICplcnJvcnMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgKmJ5dGVvcmRlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFB5X3NzaXplX3QgKmNvbnN1bWVkKQoreworICAgIGNvbnN0IGNoYXIgKnN0YXJ0cyA9IHM7CisgICAgUHlfc3NpemVfdCBzdGFydGlucG9zOworICAgIFB5X3NzaXplX3QgZW5kaW5wb3M7CisgICAgUHlfc3NpemVfdCBvdXRwb3M7CisgICAgUHlVbmljb2RlT2JqZWN0ICp1bmljb2RlOworICAgIFB5X1VOSUNPREUgKnA7CisgICAgY29uc3QgdW5zaWduZWQgY2hhciAqcSwgKmU7CisgICAgaW50IGJvID0gMDsgICAgICAgLyogYXNzdW1lIG5hdGl2ZSBvcmRlcmluZyBieSBkZWZhdWx0ICovCisgICAgY29uc3QgY2hhciAqZXJybXNnID0gIiI7CisgICAgLyogT2Zmc2V0cyBmcm9tIHEgZm9yIHJldHJpZXZpbmcgYnl0ZSBwYWlycyBpbiB0aGUgcmlnaHQgb3JkZXIuICovCisjaWZkZWYgQllURU9SREVSX0lTX0xJVFRMRV9FTkRJQU4KKyAgICBpbnQgaWhpID0gMSwgaWxvID0gMDsKKyNlbHNlCisgICAgaW50IGloaSA9IDAsIGlsbyA9IDE7CisjZW5kaWYKKyAgICBQeU9iamVjdCAqZXJyb3JIYW5kbGVyID0gTlVMTDsKKyAgICBQeU9iamVjdCAqZXhjID0gTlVMTDsKKworICAgIC8qIE5vdGU6IHNpemUgd2lsbCBhbHdheXMgYmUgbG9uZ2VyIHRoYW4gdGhlIHJlc3VsdGluZyBVbmljb2RlCisgICAgICAgY2hhcmFjdGVyIGNvdW50ICovCisgICAgdW5pY29kZSA9IF9QeVVuaWNvZGVfTmV3KHNpemUpOworICAgIGlmICghdW5pY29kZSkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgaWYgKHNpemUgPT0gMCkKKyAgICAgICAgcmV0dXJuIChQeU9iamVjdCAqKXVuaWNvZGU7CisKKyAgICAvKiBVbnBhY2sgVVRGLTE2IGVuY29kZWQgZGF0YSAqLworICAgIHAgPSB1bmljb2RlLT5zdHI7CisgICAgcSA9ICh1bnNpZ25lZCBjaGFyICopczsKKyAgICBlID0gcSArIHNpemU7CisKKyAgICBpZiAoYnl0ZW9yZGVyKQorICAgICAgICBibyA9ICpieXRlb3JkZXI7CisKKyAgICAvKiBDaGVjayBmb3IgQk9NIG1hcmtzIChVK0ZFRkYpIGluIHRoZSBpbnB1dCBhbmQgYWRqdXN0IGN1cnJlbnQKKyAgICAgICBieXRlIG9yZGVyIHNldHRpbmcgYWNjb3JkaW5nbHkuIEluIG5hdGl2ZSBtb2RlLCB0aGUgbGVhZGluZyBCT00KKyAgICAgICBtYXJrIGlzIHNraXBwZWQsIGluIGFsbCBvdGhlciBtb2RlcywgaXQgaXMgY29waWVkIHRvIHRoZSBvdXRwdXQKKyAgICAgICBzdHJlYW0gYXMtaXMgKGdpdmluZyBhIFpXTkJTUCBjaGFyYWN0ZXIpLiAqLworICAgIGlmIChibyA9PSAwKSB7CisgICAgICAgIGlmIChzaXplID49IDIpIHsKKyAgICAgICAgICAgIGNvbnN0IFB5X1VOSUNPREUgYm9tID0gKHFbaWhpXSA8PCA4KSB8IHFbaWxvXTsKKyNpZmRlZiBCWVRFT1JERVJfSVNfTElUVExFX0VORElBTgorICAgICAgICAgICAgaWYgKGJvbSA9PSAweEZFRkYpIHsKKyAgICAgICAgICAgICAgICBxICs9IDI7CisgICAgICAgICAgICAgICAgYm8gPSAtMTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGVsc2UgaWYgKGJvbSA9PSAweEZGRkUpIHsKKyAgICAgICAgICAgICAgICBxICs9IDI7CisgICAgICAgICAgICAgICAgYm8gPSAxOworICAgICAgICAgICAgfQorI2Vsc2UKKyAgICAgICAgICAgIGlmIChib20gPT0gMHhGRUZGKSB7CisgICAgICAgICAgICAgICAgcSArPSAyOworICAgICAgICAgICAgICAgIGJvID0gMTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGVsc2UgaWYgKGJvbSA9PSAweEZGRkUpIHsKKyAgICAgICAgICAgICAgICBxICs9IDI7CisgICAgICAgICAgICAgICAgYm8gPSAtMTsKKyAgICAgICAgICAgIH0KKyNlbmRpZgorICAgICAgICB9CisgICAgfQorCisgICAgaWYgKGJvID09IC0xKSB7CisgICAgICAgIC8qIGZvcmNlIExFICovCisgICAgICAgIGloaSA9IDE7CisgICAgICAgIGlsbyA9IDA7CisgICAgfQorICAgIGVsc2UgaWYgKGJvID09IDEpIHsKKyAgICAgICAgLyogZm9yY2UgQkUgKi8KKyAgICAgICAgaWhpID0gMDsKKyAgICAgICAgaWxvID0gMTsKKyAgICB9CisKKyAgICB3aGlsZSAocSA8IGUpIHsKKyAgICAgICAgUHlfVU5JQ09ERSBjaDsKKyAgICAgICAgLyogcmVtYWluaW5nIGJ5dGVzIGF0IHRoZSBlbmQ/IChzaXplIHNob3VsZCBiZSBldmVuKSAqLworICAgICAgICBpZiAoZS1xPDIpIHsKKyAgICAgICAgICAgIGlmIChjb25zdW1lZCkKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIGVycm1zZyA9ICJ0cnVuY2F0ZWQgZGF0YSI7CisgICAgICAgICAgICBzdGFydGlucG9zID0gKChjb25zdCBjaGFyICopcSktc3RhcnRzOworICAgICAgICAgICAgZW5kaW5wb3MgPSAoKGNvbnN0IGNoYXIgKillKS1zdGFydHM7CisgICAgICAgICAgICBnb3RvIHV0ZjE2RXJyb3I7CisgICAgICAgICAgICAvKiBUaGUgcmVtYWluaW5nIGlucHV0IGNoYXJzIGFyZSBpZ25vcmVkIGlmIHRoZSBjYWxsYmFjaworICAgICAgICAgICAgICAgY2hvb3NlcyB0byBza2lwIHRoZSBpbnB1dCAqLworICAgICAgICB9CisgICAgICAgIGNoID0gKHFbaWhpXSA8PCA4KSB8IHFbaWxvXTsKKworICAgICAgICBxICs9IDI7CisKKyAgICAgICAgaWYgKGNoIDwgMHhEODAwIHx8IGNoID4gMHhERkZGKSB7CisgICAgICAgICAgICAqcCsrID0gY2g7CisgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgfQorCisgICAgICAgIC8qIFVURi0xNiBjb2RlIHBhaXI6ICovCisgICAgICAgIGlmIChlIC0gcSA8IDIpIHsKKyAgICAgICAgICAgIHEgLT0gMjsKKyAgICAgICAgICAgIGlmIChjb25zdW1lZCkKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIGVycm1zZyA9ICJ1bmV4cGVjdGVkIGVuZCBvZiBkYXRhIjsKKyAgICAgICAgICAgIHN0YXJ0aW5wb3MgPSAoKGNvbnN0IGNoYXIgKilxKS1zdGFydHM7CisgICAgICAgICAgICBlbmRpbnBvcyA9ICgoY29uc3QgY2hhciAqKWUpLXN0YXJ0czsKKyAgICAgICAgICAgIGdvdG8gdXRmMTZFcnJvcjsKKyAgICAgICAgfQorICAgICAgICBpZiAoMHhEODAwIDw9IGNoICYmIGNoIDw9IDB4REJGRikgeworICAgICAgICAgICAgUHlfVU5JQ09ERSBjaDIgPSAocVtpaGldIDw8IDgpIHwgcVtpbG9dOworICAgICAgICAgICAgcSArPSAyOworICAgICAgICAgICAgaWYgKDB4REMwMCA8PSBjaDIgJiYgY2gyIDw9IDB4REZGRikgeworI2lmbmRlZiBQeV9VTklDT0RFX1dJREUKKyAgICAgICAgICAgICAgICAqcCsrID0gY2g7CisgICAgICAgICAgICAgICAgKnArKyA9IGNoMjsKKyNlbHNlCisgICAgICAgICAgICAgICAgKnArKyA9ICgoKGNoICYgMHgzRkYpPDwxMCkgfCAoY2gyICYgMHgzRkYpKSArIDB4MTAwMDA7CisjZW5kaWYKKyAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGVsc2UgeworICAgICAgICAgICAgICAgIGVycm1zZyA9ICJpbGxlZ2FsIFVURi0xNiBzdXJyb2dhdGUiOworICAgICAgICAgICAgICAgIHN0YXJ0aW5wb3MgPSAoKChjb25zdCBjaGFyICopcSktNCktc3RhcnRzOworICAgICAgICAgICAgICAgIGVuZGlucG9zID0gc3RhcnRpbnBvcysyOworICAgICAgICAgICAgICAgIGdvdG8gdXRmMTZFcnJvcjsKKyAgICAgICAgICAgIH0KKworICAgICAgICB9CisgICAgICAgIGVycm1zZyA9ICJpbGxlZ2FsIGVuY29kaW5nIjsKKyAgICAgICAgc3RhcnRpbnBvcyA9ICgoKGNvbnN0IGNoYXIgKilxKS0yKS1zdGFydHM7CisgICAgICAgIGVuZGlucG9zID0gc3RhcnRpbnBvcysyOworICAgICAgICAvKiBGYWxsIHRocm91Z2ggdG8gcmVwb3J0IHRoZSBlcnJvciAqLworCisgICAgICB1dGYxNkVycm9yOgorICAgICAgICBvdXRwb3MgPSBwLVB5VW5pY29kZV9BU19VTklDT0RFKHVuaWNvZGUpOworICAgICAgICBpZiAodW5pY29kZV9kZWNvZGVfY2FsbF9lcnJvcmhhbmRsZXIoCisgICAgICAgICAgICAgICAgZXJyb3JzLCAmZXJyb3JIYW5kbGVyLAorICAgICAgICAgICAgICAgICJ1dGYxNiIsIGVycm1zZywKKyAgICAgICAgICAgICAgICBzdGFydHMsIHNpemUsICZzdGFydGlucG9zLCAmZW5kaW5wb3MsICZleGMsIChjb25zdCBjaGFyICoqKSZxLAorICAgICAgICAgICAgICAgICZ1bmljb2RlLCAmb3V0cG9zLCAmcCkpCisgICAgICAgICAgICBnb3RvIG9uRXJyb3I7CisgICAgfQorCisgICAgaWYgKGJ5dGVvcmRlcikKKyAgICAgICAgKmJ5dGVvcmRlciA9IGJvOworCisgICAgaWYgKGNvbnN1bWVkKQorICAgICAgICAqY29uc3VtZWQgPSAoY29uc3QgY2hhciAqKXEtc3RhcnRzOworCisgICAgLyogQWRqdXN0IGxlbmd0aCAqLworICAgIGlmIChfUHlVbmljb2RlX1Jlc2l6ZSgmdW5pY29kZSwgcCAtIHVuaWNvZGUtPnN0cikgPCAwKQorICAgICAgICBnb3RvIG9uRXJyb3I7CisKKyAgICBQeV9YREVDUkVGKGVycm9ySGFuZGxlcik7CisgICAgUHlfWERFQ1JFRihleGMpOworICAgIHJldHVybiAoUHlPYmplY3QgKil1bmljb2RlOworCisgIG9uRXJyb3I6CisgICAgUHlfREVDUkVGKHVuaWNvZGUpOworICAgIFB5X1hERUNSRUYoZXJyb3JIYW5kbGVyKTsKKyAgICBQeV9YREVDUkVGKGV4Yyk7CisgICAgcmV0dXJuIE5VTEw7Cit9CisKK1B5T2JqZWN0ICoKK1B5VW5pY29kZV9FbmNvZGVVVEYxNihjb25zdCBQeV9VTklDT0RFICpzLAorICAgICAgICAgICAgICAgICAgICAgIFB5X3NzaXplX3Qgc2l6ZSwKKyAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyICplcnJvcnMsCisgICAgICAgICAgICAgICAgICAgICAgaW50IGJ5dGVvcmRlcikKK3sKKyAgICBQeU9iamVjdCAqdjsKKyAgICB1bnNpZ25lZCBjaGFyICpwOworICAgIFB5X3NzaXplX3QgbnNpemUsIGJ5dGVzaXplOworI2lmZGVmIFB5X1VOSUNPREVfV0lERQorICAgIFB5X3NzaXplX3QgaSwgcGFpcnM7CisjZWxzZQorICAgIGNvbnN0IGludCBwYWlycyA9IDA7CisjZW5kaWYKKyAgICAvKiBPZmZzZXRzIGZyb20gcCBmb3Igc3RvcmluZyBieXRlIHBhaXJzIGluIHRoZSByaWdodCBvcmRlci4gKi8KKyNpZmRlZiBCWVRFT1JERVJfSVNfTElUVExFX0VORElBTgorICAgIGludCBpaGkgPSAxLCBpbG8gPSAwOworI2Vsc2UKKyAgICBpbnQgaWhpID0gMCwgaWxvID0gMTsKKyNlbmRpZgorCisjZGVmaW5lIFNUT1JFQ0hBUihDSCkgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgZG8geyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgICAgIHBbaWhpXSA9ICgoQ0gpID4+IDgpICYgMHhmZjsgICAgICAgICAgICBcCisgICAgICAgIHBbaWxvXSA9IChDSCkgJiAweGZmOyAgICAgICAgICAgICAgICAgICBcCisgICAgICAgIHAgKz0gMjsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcCisgICAgfSB3aGlsZSgwKQorCisjaWZkZWYgUHlfVU5JQ09ERV9XSURFCisgICAgZm9yIChpID0gcGFpcnMgPSAwOyBpIDwgc2l6ZTsgaSsrKQorICAgICAgICBpZiAoc1tpXSA+PSAweDEwMDAwKQorICAgICAgICAgICAgcGFpcnMrKzsKKyNlbmRpZgorICAgIC8qIDIgKiAoc2l6ZSArIHBhaXJzICsgKGJ5dGVvcmRlciA9PSAwKSkgKi8KKyAgICBpZiAoc2l6ZSA+IFBZX1NTSVpFX1RfTUFYIHx8CisgICAgICAgIHNpemUgPiBQWV9TU0laRV9UX01BWCAtIHBhaXJzIC0gKGJ5dGVvcmRlciA9PSAwKSkKKyAgICAgICAgcmV0dXJuIFB5RXJyX05vTWVtb3J5KCk7CisgICAgbnNpemUgPSBzaXplICsgcGFpcnMgKyAoYnl0ZW9yZGVyID09IDApOworICAgIGJ5dGVzaXplID0gbnNpemUgKiAyOworICAgIGlmIChieXRlc2l6ZSAvIDIgIT0gbnNpemUpCisgICAgICAgIHJldHVybiBQeUVycl9Ob01lbW9yeSgpOworICAgIHYgPSBQeVN0cmluZ19Gcm9tU3RyaW5nQW5kU2l6ZShOVUxMLCBieXRlc2l6ZSk7CisgICAgaWYgKHYgPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisKKyAgICBwID0gKHVuc2lnbmVkIGNoYXIgKilQeVN0cmluZ19BU19TVFJJTkcodik7CisgICAgaWYgKGJ5dGVvcmRlciA9PSAwKQorICAgICAgICBTVE9SRUNIQVIoMHhGRUZGKTsKKyAgICBpZiAoc2l6ZSA9PSAwKQorICAgICAgICByZXR1cm4gdjsKKworICAgIGlmIChieXRlb3JkZXIgPT0gLTEpIHsKKyAgICAgICAgLyogZm9yY2UgTEUgKi8KKyAgICAgICAgaWhpID0gMTsKKyAgICAgICAgaWxvID0gMDsKKyAgICB9CisgICAgZWxzZSBpZiAoYnl0ZW9yZGVyID09IDEpIHsKKyAgICAgICAgLyogZm9yY2UgQkUgKi8KKyAgICAgICAgaWhpID0gMDsKKyAgICAgICAgaWxvID0gMTsKKyAgICB9CisKKyAgICB3aGlsZSAoc2l6ZS0tID4gMCkgeworICAgICAgICBQeV9VTklDT0RFIGNoID0gKnMrKzsKKyAgICAgICAgUHlfVU5JQ09ERSBjaDIgPSAwOworI2lmZGVmIFB5X1VOSUNPREVfV0lERQorICAgICAgICBpZiAoY2ggPj0gMHgxMDAwMCkgeworICAgICAgICAgICAgY2gyID0gMHhEQzAwIHwgKChjaC0weDEwMDAwKSAmIDB4M0ZGKTsKKyAgICAgICAgICAgIGNoICA9IDB4RDgwMCB8ICgoY2gtMHgxMDAwMCkgPj4gMTApOworICAgICAgICB9CisjZW5kaWYKKyAgICAgICAgU1RPUkVDSEFSKGNoKTsKKyAgICAgICAgaWYgKGNoMikKKyAgICAgICAgICAgIFNUT1JFQ0hBUihjaDIpOworICAgIH0KKyAgICByZXR1cm4gdjsKKyN1bmRlZiBTVE9SRUNIQVIKK30KKworUHlPYmplY3QgKlB5VW5pY29kZV9Bc1VURjE2U3RyaW5nKFB5T2JqZWN0ICp1bmljb2RlKQoreworICAgIGlmICghUHlVbmljb2RlX0NoZWNrKHVuaWNvZGUpKSB7CisgICAgICAgIFB5RXJyX0JhZEFyZ3VtZW50KCk7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICByZXR1cm4gUHlVbmljb2RlX0VuY29kZVVURjE2KFB5VW5pY29kZV9BU19VTklDT0RFKHVuaWNvZGUpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHlVbmljb2RlX0dFVF9TSVpFKHVuaWNvZGUpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDApOworfQorCisvKiAtLS0gVW5pY29kZSBFc2NhcGUgQ29kZWMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KKworc3RhdGljIF9QeVVuaWNvZGVfTmFtZV9DQVBJICp1Y25oYXNoX0NBUEkgPSBOVUxMOworCitQeU9iamVjdCAqUHlVbmljb2RlX0RlY29kZVVuaWNvZGVFc2NhcGUoY29uc3QgY2hhciAqcywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQeV9zc2l6ZV90IHNpemUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciAqZXJyb3JzKQoreworICAgIGNvbnN0IGNoYXIgKnN0YXJ0cyA9IHM7CisgICAgUHlfc3NpemVfdCBzdGFydGlucG9zOworICAgIFB5X3NzaXplX3QgZW5kaW5wb3M7CisgICAgUHlfc3NpemVfdCBvdXRwb3M7CisgICAgUHlVbmljb2RlT2JqZWN0ICp2OworICAgIFB5X1VOSUNPREUgKnA7CisgICAgY29uc3QgY2hhciAqZW5kOworICAgIGNoYXIqIG1lc3NhZ2U7CisgICAgUHlfVUNTNCBjaHIgPSAweGZmZmZmZmZmOyAvKiBpbiBjYXNlICdnZXRjb2RlJyBtZXNzZXMgdXAgKi8KKyAgICBQeU9iamVjdCAqZXJyb3JIYW5kbGVyID0gTlVMTDsKKyAgICBQeU9iamVjdCAqZXhjID0gTlVMTDsKKworICAgIC8qIEVzY2FwZWQgc3RyaW5ncyB3aWxsIGFsd2F5cyBiZSBsb25nZXIgdGhhbiB0aGUgcmVzdWx0aW5nCisgICAgICAgVW5pY29kZSBzdHJpbmcsIHNvIHdlIHN0YXJ0IHdpdGggc2l6ZSBoZXJlIGFuZCB0aGVuIHJlZHVjZSB0aGUKKyAgICAgICBsZW5ndGggYWZ0ZXIgY29udmVyc2lvbiB0byB0aGUgdHJ1ZSB2YWx1ZS4KKyAgICAgICAoYnV0IGlmIHRoZSBlcnJvciBjYWxsYmFjayByZXR1cm5zIGEgbG9uZyByZXBsYWNlbWVudCBzdHJpbmcKKyAgICAgICB3ZSdsbCBoYXZlIHRvIGFsbG9jYXRlIG1vcmUgc3BhY2UpICovCisgICAgdiA9IF9QeVVuaWNvZGVfTmV3KHNpemUpOworICAgIGlmICh2ID09IE5VTEwpCisgICAgICAgIGdvdG8gb25FcnJvcjsKKyAgICBpZiAoc2l6ZSA9PSAwKQorICAgICAgICByZXR1cm4gKFB5T2JqZWN0ICopdjsKKworICAgIHAgPSBQeVVuaWNvZGVfQVNfVU5JQ09ERSh2KTsKKyAgICBlbmQgPSBzICsgc2l6ZTsKKworICAgIHdoaWxlIChzIDwgZW5kKSB7CisgICAgICAgIHVuc2lnbmVkIGNoYXIgYzsKKyAgICAgICAgUHlfVU5JQ09ERSB4OworICAgICAgICBpbnQgZGlnaXRzOworCisgICAgICAgIC8qIE5vbi1lc2NhcGUgY2hhcmFjdGVycyBhcmUgaW50ZXJwcmV0ZWQgYXMgVW5pY29kZSBvcmRpbmFscyAqLworICAgICAgICBpZiAoKnMgIT0gJ1xcJykgeworICAgICAgICAgICAgKnArKyA9ICh1bnNpZ25lZCBjaGFyKSAqcysrOworICAgICAgICAgICAgY29udGludWU7CisgICAgICAgIH0KKworICAgICAgICBzdGFydGlucG9zID0gcy1zdGFydHM7CisgICAgICAgIC8qIFwgLSBFc2NhcGVzICovCisgICAgICAgIHMrKzsKKyAgICAgICAgYyA9ICpzKys7CisgICAgICAgIGlmIChzID4gZW5kKQorICAgICAgICAgICAgYyA9ICdcMCc7IC8qIEludmFsaWQgYWZ0ZXIgXCAqLworICAgICAgICBzd2l0Y2ggKGMpIHsKKworICAgICAgICAgICAgLyogXHggZXNjYXBlcyAqLworICAgICAgICBjYXNlICdcbic6IGJyZWFrOworICAgICAgICBjYXNlICdcXCc6ICpwKysgPSAnXFwnOyBicmVhazsKKyAgICAgICAgY2FzZSAnXCcnOiAqcCsrID0gJ1wnJzsgYnJlYWs7CisgICAgICAgIGNhc2UgJ1wiJzogKnArKyA9ICdcIic7IGJyZWFrOworICAgICAgICBjYXNlICdiJzogKnArKyA9ICdcYic7IGJyZWFrOworICAgICAgICBjYXNlICdmJzogKnArKyA9ICdcMDE0JzsgYnJlYWs7IC8qIEZGICovCisgICAgICAgIGNhc2UgJ3QnOiAqcCsrID0gJ1x0JzsgYnJlYWs7CisgICAgICAgIGNhc2UgJ24nOiAqcCsrID0gJ1xuJzsgYnJlYWs7CisgICAgICAgIGNhc2UgJ3InOiAqcCsrID0gJ1xyJzsgYnJlYWs7CisgICAgICAgIGNhc2UgJ3YnOiAqcCsrID0gJ1wwMTMnOyBicmVhazsgLyogVlQgKi8KKyAgICAgICAgY2FzZSAnYSc6ICpwKysgPSAnXDAwNyc7IGJyZWFrOyAvKiBCRUwsIG5vdCBjbGFzc2ljIEMgKi8KKworICAgICAgICAgICAgLyogXE9PTyAob2N0YWwpIGVzY2FwZXMgKi8KKyAgICAgICAgY2FzZSAnMCc6IGNhc2UgJzEnOiBjYXNlICcyJzogY2FzZSAnMyc6CisgICAgICAgIGNhc2UgJzQnOiBjYXNlICc1JzogY2FzZSAnNic6IGNhc2UgJzcnOgorICAgICAgICAgICAgeCA9IHNbLTFdIC0gJzAnOworICAgICAgICAgICAgaWYgKHMgPCBlbmQgJiYgJzAnIDw9ICpzICYmICpzIDw9ICc3JykgeworICAgICAgICAgICAgICAgIHggPSAoeDw8MykgKyAqcysrIC0gJzAnOworICAgICAgICAgICAgICAgIGlmIChzIDwgZW5kICYmICcwJyA8PSAqcyAmJiAqcyA8PSAnNycpCisgICAgICAgICAgICAgICAgICAgIHggPSAoeDw8MykgKyAqcysrIC0gJzAnOworICAgICAgICAgICAgfQorICAgICAgICAgICAgKnArKyA9IHg7CisgICAgICAgICAgICBicmVhazsKKworICAgICAgICAgICAgLyogaGV4IGVzY2FwZXMgKi8KKyAgICAgICAgICAgIC8qIFx4WFggKi8KKyAgICAgICAgY2FzZSAneCc6CisgICAgICAgICAgICBkaWdpdHMgPSAyOworICAgICAgICAgICAgbWVzc2FnZSA9ICJ0cnVuY2F0ZWQgXFx4WFggZXNjYXBlIjsKKyAgICAgICAgICAgIGdvdG8gaGV4ZXNjYXBlOworCisgICAgICAgICAgICAvKiBcdVhYWFggKi8KKyAgICAgICAgY2FzZSAndSc6CisgICAgICAgICAgICBkaWdpdHMgPSA0OworICAgICAgICAgICAgbWVzc2FnZSA9ICJ0cnVuY2F0ZWQgXFx1WFhYWCBlc2NhcGUiOworICAgICAgICAgICAgZ290byBoZXhlc2NhcGU7CisKKyAgICAgICAgICAgIC8qIFxVWFhYWFhYWFggKi8KKyAgICAgICAgY2FzZSAnVSc6CisgICAgICAgICAgICBkaWdpdHMgPSA4OworICAgICAgICAgICAgbWVzc2FnZSA9ICJ0cnVuY2F0ZWQgXFxVWFhYWFhYWFggZXNjYXBlIjsKKyAgICAgICAgaGV4ZXNjYXBlOgorICAgICAgICAgICAgY2hyID0gMDsKKyAgICAgICAgICAgIGlmIChlbmQgLSBzIDwgZGlnaXRzKSB7CisgICAgICAgICAgICAgICAgLyogY291bnQgb25seSBoZXggZGlnaXRzICovCisgICAgICAgICAgICAgICAgZm9yICg7IHMgPCBlbmQ7ICsrcykgeworICAgICAgICAgICAgICAgICAgICBjID0gKHVuc2lnbmVkIGNoYXIpKnM7CisgICAgICAgICAgICAgICAgICAgIGlmICghUHlfSVNYRElHSVQoYykpCisgICAgICAgICAgICAgICAgICAgICAgICBnb3RvIGVycm9yOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBnb3RvIGVycm9yOworICAgICAgICAgICAgfQorICAgICAgICAgICAgZm9yICg7IGRpZ2l0cy0tOyArK3MpIHsKKyAgICAgICAgICAgICAgICBjID0gKHVuc2lnbmVkIGNoYXIpKnM7CisgICAgICAgICAgICAgICAgaWYgKCFQeV9JU1hESUdJVChjKSkKKyAgICAgICAgICAgICAgICAgICAgZ290byBlcnJvcjsKKyAgICAgICAgICAgICAgICBjaHIgPSAoY2hyPDw0KSAmIH4weEY7CisgICAgICAgICAgICAgICAgaWYgKGMgPj0gJzAnICYmIGMgPD0gJzknKQorICAgICAgICAgICAgICAgICAgICBjaHIgKz0gYyAtICcwJzsKKyAgICAgICAgICAgICAgICBlbHNlIGlmIChjID49ICdhJyAmJiBjIDw9ICdmJykKKyAgICAgICAgICAgICAgICAgICAgY2hyICs9IDEwICsgYyAtICdhJzsKKyAgICAgICAgICAgICAgICBlbHNlCisgICAgICAgICAgICAgICAgICAgIGNociArPSAxMCArIGMgLSAnQSc7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoY2hyID09IDB4ZmZmZmZmZmYgJiYgUHlFcnJfT2NjdXJyZWQoKSkKKyAgICAgICAgICAgICAgICAvKiBfZGVjb2RpbmdfZXJyb3Igd2lsbCBoYXZlIGFscmVhZHkgd3JpdHRlbiBpbnRvIHRoZQorICAgICAgICAgICAgICAgICAgIHRhcmdldCBidWZmZXIuICovCisgICAgICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIHN0b3JlOgorICAgICAgICAgICAgLyogd2hlbiB3ZSBnZXQgaGVyZSwgY2hyIGlzIGEgMzItYml0IHVuaWNvZGUgY2hhcmFjdGVyICovCisgICAgICAgICAgICBpZiAoY2hyIDw9IDB4ZmZmZikKKyAgICAgICAgICAgICAgICAvKiBVQ1MtMiBjaGFyYWN0ZXIgKi8KKyAgICAgICAgICAgICAgICAqcCsrID0gKFB5X1VOSUNPREUpIGNocjsKKyAgICAgICAgICAgIGVsc2UgaWYgKGNociA8PSAweDEwZmZmZikgeworICAgICAgICAgICAgICAgIC8qIFVDUy00IGNoYXJhY3Rlci4gRWl0aGVyIHN0b3JlIGRpcmVjdGx5LCBvciBhcworICAgICAgICAgICAgICAgICAgIHN1cnJvZ2F0ZSBwYWlyLiAqLworI2lmZGVmIFB5X1VOSUNPREVfV0lERQorICAgICAgICAgICAgICAgICpwKysgPSBjaHI7CisjZWxzZQorICAgICAgICAgICAgICAgIGNociAtPSAweDEwMDAwTDsKKyAgICAgICAgICAgICAgICAqcCsrID0gMHhEODAwICsgKFB5X1VOSUNPREUpIChjaHIgPj4gMTApOworICAgICAgICAgICAgICAgICpwKysgPSAweERDMDAgKyAoUHlfVU5JQ09ERSkgKGNociAmIDB4MDNGRik7CisjZW5kaWYKKyAgICAgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICAgICAgbWVzc2FnZSA9ICJpbGxlZ2FsIFVuaWNvZGUgY2hhcmFjdGVyIjsKKyAgICAgICAgICAgICAgICBnb3RvIGVycm9yOworICAgICAgICAgICAgfQorICAgICAgICAgICAgYnJlYWs7CisKKyAgICAgICAgICAgIC8qIFxOe25hbWV9ICovCisgICAgICAgIGNhc2UgJ04nOgorICAgICAgICAgICAgbWVzc2FnZSA9ICJtYWxmb3JtZWQgXFxOIGNoYXJhY3RlciBlc2NhcGUiOworICAgICAgICAgICAgaWYgKHVjbmhhc2hfQ0FQSSA9PSBOVUxMKSB7CisgICAgICAgICAgICAgICAgLyogbG9hZCB0aGUgdW5pY29kZSBkYXRhIG1vZHVsZSAqLworICAgICAgICAgICAgICAgIHVjbmhhc2hfQ0FQSSA9IChfUHlVbmljb2RlX05hbWVfQ0FQSSAqKVB5Q2Fwc3VsZV9JbXBvcnQoUHlVbmljb2RlRGF0YV9DQVBTVUxFX05BTUUsIDEpOworICAgICAgICAgICAgICAgIGlmICh1Y25oYXNoX0NBUEkgPT0gTlVMTCkKKyAgICAgICAgICAgICAgICAgICAgZ290byB1Y25oYXNoRXJyb3I7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoKnMgPT0gJ3snKSB7CisgICAgICAgICAgICAgICAgY29uc3QgY2hhciAqc3RhcnQgPSBzKzE7CisgICAgICAgICAgICAgICAgLyogbG9vayBmb3IgdGhlIGNsb3NpbmcgYnJhY2UgKi8KKyAgICAgICAgICAgICAgICB3aGlsZSAoKnMgIT0gJ30nICYmIHMgPCBlbmQpCisgICAgICAgICAgICAgICAgICAgIHMrKzsKKyAgICAgICAgICAgICAgICBpZiAocyA+IHN0YXJ0ICYmIHMgPCBlbmQgJiYgKnMgPT0gJ30nKSB7CisgICAgICAgICAgICAgICAgICAgIC8qIGZvdW5kIGEgbmFtZS4gIGxvb2sgaXQgdXAgaW4gdGhlIHVuaWNvZGUgZGF0YWJhc2UgKi8KKyAgICAgICAgICAgICAgICAgICAgbWVzc2FnZSA9ICJ1bmtub3duIFVuaWNvZGUgY2hhcmFjdGVyIG5hbWUiOworICAgICAgICAgICAgICAgICAgICBzKys7CisgICAgICAgICAgICAgICAgICAgIGlmIChzIC0gc3RhcnQgLSAxIDw9IElOVF9NQVggJiYKKyAgICAgICAgICAgICAgICAgICAgICAgIHVjbmhhc2hfQ0FQSS0+Z2V0Y29kZShOVUxMLCBzdGFydCwgKGludCkocy1zdGFydC0xKSwgJmNocikpCisgICAgICAgICAgICAgICAgICAgICAgICBnb3RvIHN0b3JlOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGdvdG8gZXJyb3I7CisKKyAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAgIGlmIChzID4gZW5kKSB7CisgICAgICAgICAgICAgICAgbWVzc2FnZSA9ICJcXCBhdCBlbmQgb2Ygc3RyaW5nIjsKKyAgICAgICAgICAgICAgICBzLS07CisgICAgICAgICAgICAgICAgZ290byBlcnJvcjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGVsc2UgeworICAgICAgICAgICAgICAgICpwKysgPSAnXFwnOworICAgICAgICAgICAgICAgICpwKysgPSAodW5zaWduZWQgY2hhcilzWy0xXTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisgICAgICAgIGNvbnRpbnVlOworCisgICAgICBlcnJvcjoKKyAgICAgICAgZW5kaW5wb3MgPSBzLXN0YXJ0czsKKyAgICAgICAgb3V0cG9zID0gcC1QeVVuaWNvZGVfQVNfVU5JQ09ERSh2KTsKKyAgICAgICAgaWYgKHVuaWNvZGVfZGVjb2RlX2NhbGxfZXJyb3JoYW5kbGVyKAorICAgICAgICAgICAgICAgIGVycm9ycywgJmVycm9ySGFuZGxlciwKKyAgICAgICAgICAgICAgICAidW5pY29kZWVzY2FwZSIsIG1lc3NhZ2UsCisgICAgICAgICAgICAgICAgc3RhcnRzLCBzaXplLCAmc3RhcnRpbnBvcywgJmVuZGlucG9zLCAmZXhjLCAmcywKKyAgICAgICAgICAgICAgICAmdiwgJm91dHBvcywgJnApKQorICAgICAgICAgICAgZ290byBvbkVycm9yOworICAgICAgICBjb250aW51ZTsKKyAgICB9CisgICAgaWYgKF9QeVVuaWNvZGVfUmVzaXplKCZ2LCBwIC0gUHlVbmljb2RlX0FTX1VOSUNPREUodikpIDwgMCkKKyAgICAgICAgZ290byBvbkVycm9yOworICAgIFB5X1hERUNSRUYoZXJyb3JIYW5kbGVyKTsKKyAgICBQeV9YREVDUkVGKGV4Yyk7CisgICAgcmV0dXJuIChQeU9iamVjdCAqKXY7CisKKyAgdWNuaGFzaEVycm9yOgorICAgIFB5RXJyX1NldFN0cmluZygKKyAgICAgICAgUHlFeGNfVW5pY29kZUVycm9yLAorICAgICAgICAiXFxOIGVzY2FwZXMgbm90IHN1cHBvcnRlZCAoY2FuJ3QgbG9hZCB1bmljb2RlZGF0YSBtb2R1bGUpIgorICAgICAgICApOworICAgIFB5X1hERUNSRUYodik7CisgICAgUHlfWERFQ1JFRihlcnJvckhhbmRsZXIpOworICAgIFB5X1hERUNSRUYoZXhjKTsKKyAgICByZXR1cm4gTlVMTDsKKworICBvbkVycm9yOgorICAgIFB5X1hERUNSRUYodik7CisgICAgUHlfWERFQ1JFRihlcnJvckhhbmRsZXIpOworICAgIFB5X1hERUNSRUYoZXhjKTsKKyAgICByZXR1cm4gTlVMTDsKK30KKworLyogUmV0dXJuIGEgVW5pY29kZS1Fc2NhcGUgc3RyaW5nIHZlcnNpb24gb2YgdGhlIFVuaWNvZGUgb2JqZWN0LgorCisgICBJZiBxdW90ZXMgaXMgdHJ1ZSwgdGhlIHN0cmluZyBpcyBlbmNsb3NlZCBpbiB1IiIgb3IgdScnIHF1b3RlcyBhcworICAgYXBwcm9wcmlhdGUuCisKKyovCisKK1B5X0xPQ0FMX0lOTElORShjb25zdCBQeV9VTklDT0RFICopIGZpbmRjaGFyKGNvbnN0IFB5X1VOSUNPREUgKnMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQeV9zc2l6ZV90IHNpemUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQeV9VTklDT0RFIGNoKQoreworICAgIC8qIGxpa2Ugd2NzY2hyLCBidXQgZG9lc24ndCBzdG9wIGF0IE5VTEwgY2hhcmFjdGVycyAqLworCisgICAgd2hpbGUgKHNpemUtLSA+IDApIHsKKyAgICAgICAgaWYgKCpzID09IGNoKQorICAgICAgICAgICAgcmV0dXJuIHM7CisgICAgICAgIHMrKzsKKyAgICB9CisKKyAgICByZXR1cm4gTlVMTDsKK30KKworc3RhdGljCitQeU9iamVjdCAqdW5pY29kZWVzY2FwZV9zdHJpbmcoY29uc3QgUHlfVU5JQ09ERSAqcywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQeV9zc2l6ZV90IHNpemUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IHF1b3RlcykKK3sKKyAgICBQeU9iamVjdCAqcmVwcjsKKyAgICBjaGFyICpwOworCisgICAgc3RhdGljIGNvbnN0IGNoYXIgKmhleGRpZ2l0ID0gIjAxMjM0NTY3ODlhYmNkZWYiOworI2lmZGVmIFB5X1VOSUNPREVfV0lERQorICAgIGNvbnN0IFB5X3NzaXplX3QgZXhwYW5kc2l6ZSA9IDEwOworI2Vsc2UKKyAgICBjb25zdCBQeV9zc2l6ZV90IGV4cGFuZHNpemUgPSA2OworI2VuZGlmCisKKyAgICAvKiBYWFgobm5vcndpdHopOiByYXRoZXIgdGhhbiBvdmVyLWFsbG9jYXRpbmcsIGl0IHdvdWxkIGJlCisgICAgICAgYmV0dGVyIHRvIGNob29zZSBhIGRpZmZlcmVudCBzY2hlbWUuICBQZXJoYXBzIHNjYW4gdGhlCisgICAgICAgZmlyc3QgTi1jaGFycyBvZiB0aGUgc3RyaW5nIGFuZCBhbGxvY2F0ZSBiYXNlZCBvbiB0aGF0IHNpemUuCisgICAgKi8KKyAgICAvKiBJbml0aWFsIGFsbG9jYXRpb24gaXMgYmFzZWQgb24gdGhlIGxvbmdlc3QtcG9zc2libGUgdW5pY2hyCisgICAgICAgZXNjYXBlLgorCisgICAgICAgSW4gd2lkZSAoVVRGLTMyKSBidWlsZHMgJ1xVMDB4eHh4eHgnIGlzIDEwIGNoYXJzIHBlciBzb3VyY2UKKyAgICAgICB1bmljaHIsIHNvIGluIHRoaXMgY2FzZSBpdCdzIHRoZSBsb25nZXN0IHVuaWNociBlc2NhcGUuIEluCisgICAgICAgbmFycm93IChVVEYtMTYpIGJ1aWxkcyB0aGlzIGlzIGZpdmUgY2hhcnMgcGVyIHNvdXJjZSB1bmljaHIKKyAgICAgICBzaW5jZSB0aGVyZSBhcmUgdHdvIHVuaWNocnMgaW4gdGhlIHN1cnJvZ2F0ZSBwYWlyLCBzbyBpbiBuYXJyb3cKKyAgICAgICAoVVRGLTE2KSBidWlsZHMgaXQncyBub3QgdGhlIGxvbmdlc3QgdW5pY2hyIGVzY2FwZS4KKworICAgICAgIEluIHdpZGUgb3IgbmFycm93IGJ1aWxkcyAnXHV4eHh4JyBpcyA2IGNoYXJzIHBlciBzb3VyY2UgdW5pY2hyLAorICAgICAgIHNvIGluIHRoZSBuYXJyb3cgKFVURi0xNikgYnVpbGQgY2FzZSBpdCdzIHRoZSBsb25nZXN0IHVuaWNocgorICAgICAgIGVzY2FwZS4KKyAgICAqLworCisgICAgaWYgKHNpemUgPiAoUFlfU1NJWkVfVF9NQVggLSAyIC0gMSkgLyBleHBhbmRzaXplKQorICAgICAgICByZXR1cm4gUHlFcnJfTm9NZW1vcnkoKTsKKworICAgIHJlcHIgPSBQeVN0cmluZ19Gcm9tU3RyaW5nQW5kU2l6ZShOVUxMLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAyCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgZXhwYW5kc2l6ZSpzaXplCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICsgMSk7CisgICAgaWYgKHJlcHIgPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisKKyAgICBwID0gUHlTdHJpbmdfQVNfU1RSSU5HKHJlcHIpOworCisgICAgaWYgKHF1b3RlcykgeworICAgICAgICAqcCsrID0gJ3UnOworICAgICAgICAqcCsrID0gKGZpbmRjaGFyKHMsIHNpemUsICdcJycpICYmCisgICAgICAgICAgICAgICAgIWZpbmRjaGFyKHMsIHNpemUsICciJykpID8gJyInIDogJ1wnJzsKKyAgICB9CisgICAgd2hpbGUgKHNpemUtLSA+IDApIHsKKyAgICAgICAgUHlfVU5JQ09ERSBjaCA9ICpzKys7CisKKyAgICAgICAgLyogRXNjYXBlIHF1b3RlcyBhbmQgYmFja3NsYXNoZXMgKi8KKyAgICAgICAgaWYgKChxdW90ZXMgJiYKKyAgICAgICAgICAgICBjaCA9PSAoUHlfVU5JQ09ERSkgUHlTdHJpbmdfQVNfU1RSSU5HKHJlcHIpWzFdKSB8fCBjaCA9PSAnXFwnKSB7CisgICAgICAgICAgICAqcCsrID0gJ1xcJzsKKyAgICAgICAgICAgICpwKysgPSAoY2hhcikgY2g7CisgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgfQorCisjaWZkZWYgUHlfVU5JQ09ERV9XSURFCisgICAgICAgIC8qIE1hcCAyMS1iaXQgY2hhcmFjdGVycyB0byAnXFUwMHh4eHh4eCcgKi8KKyAgICAgICAgZWxzZSBpZiAoY2ggPj0gMHgxMDAwMCkgeworICAgICAgICAgICAgKnArKyA9ICdcXCc7CisgICAgICAgICAgICAqcCsrID0gJ1UnOworICAgICAgICAgICAgKnArKyA9IGhleGRpZ2l0WyhjaCA+PiAyOCkgJiAweDAwMDAwMDBGXTsKKyAgICAgICAgICAgICpwKysgPSBoZXhkaWdpdFsoY2ggPj4gMjQpICYgMHgwMDAwMDAwRl07CisgICAgICAgICAgICAqcCsrID0gaGV4ZGlnaXRbKGNoID4+IDIwKSAmIDB4MDAwMDAwMEZdOworICAgICAgICAgICAgKnArKyA9IGhleGRpZ2l0WyhjaCA+PiAxNikgJiAweDAwMDAwMDBGXTsKKyAgICAgICAgICAgICpwKysgPSBoZXhkaWdpdFsoY2ggPj4gMTIpICYgMHgwMDAwMDAwRl07CisgICAgICAgICAgICAqcCsrID0gaGV4ZGlnaXRbKGNoID4+IDgpICYgMHgwMDAwMDAwRl07CisgICAgICAgICAgICAqcCsrID0gaGV4ZGlnaXRbKGNoID4+IDQpICYgMHgwMDAwMDAwRl07CisgICAgICAgICAgICAqcCsrID0gaGV4ZGlnaXRbY2ggJiAweDAwMDAwMDBGXTsKKyAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICB9CisjZWxzZQorICAgICAgICAvKiBNYXAgVVRGLTE2IHN1cnJvZ2F0ZSBwYWlycyB0byAnXFUwMHh4eHh4eCcgKi8KKyAgICAgICAgZWxzZSBpZiAoY2ggPj0gMHhEODAwICYmIGNoIDwgMHhEQzAwKSB7CisgICAgICAgICAgICBQeV9VTklDT0RFIGNoMjsKKyAgICAgICAgICAgIFB5X1VDUzQgdWNzOworCisgICAgICAgICAgICBjaDIgPSAqcysrOworICAgICAgICAgICAgc2l6ZS0tOworICAgICAgICAgICAgaWYgKGNoMiA+PSAweERDMDAgJiYgY2gyIDw9IDB4REZGRikgeworICAgICAgICAgICAgICAgIHVjcyA9ICgoKGNoICYgMHgwM0ZGKSA8PCAxMCkgfCAoY2gyICYgMHgwM0ZGKSkgKyAweDAwMDEwMDAwOworICAgICAgICAgICAgICAgICpwKysgPSAnXFwnOworICAgICAgICAgICAgICAgICpwKysgPSAnVSc7CisgICAgICAgICAgICAgICAgKnArKyA9IGhleGRpZ2l0Wyh1Y3MgPj4gMjgpICYgMHgwMDAwMDAwRl07CisgICAgICAgICAgICAgICAgKnArKyA9IGhleGRpZ2l0Wyh1Y3MgPj4gMjQpICYgMHgwMDAwMDAwRl07CisgICAgICAgICAgICAgICAgKnArKyA9IGhleGRpZ2l0Wyh1Y3MgPj4gMjApICYgMHgwMDAwMDAwRl07CisgICAgICAgICAgICAgICAgKnArKyA9IGhleGRpZ2l0Wyh1Y3MgPj4gMTYpICYgMHgwMDAwMDAwRl07CisgICAgICAgICAgICAgICAgKnArKyA9IGhleGRpZ2l0Wyh1Y3MgPj4gMTIpICYgMHgwMDAwMDAwRl07CisgICAgICAgICAgICAgICAgKnArKyA9IGhleGRpZ2l0Wyh1Y3MgPj4gOCkgJiAweDAwMDAwMDBGXTsKKyAgICAgICAgICAgICAgICAqcCsrID0gaGV4ZGlnaXRbKHVjcyA+PiA0KSAmIDB4MDAwMDAwMEZdOworICAgICAgICAgICAgICAgICpwKysgPSBoZXhkaWdpdFt1Y3MgJiAweDAwMDAwMDBGXTsKKyAgICAgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIC8qIEZhbGwgdGhyb3VnaDogaXNvbGF0ZWQgc3Vycm9nYXRlcyBhcmUgY29waWVkIGFzLWlzICovCisgICAgICAgICAgICBzLS07CisgICAgICAgICAgICBzaXplKys7CisgICAgICAgIH0KKyNlbmRpZgorCisgICAgICAgIC8qIE1hcCAxNi1iaXQgY2hhcmFjdGVycyB0byAnXHV4eHh4JyAqLworICAgICAgICBpZiAoY2ggPj0gMjU2KSB7CisgICAgICAgICAgICAqcCsrID0gJ1xcJzsKKyAgICAgICAgICAgICpwKysgPSAndSc7CisgICAgICAgICAgICAqcCsrID0gaGV4ZGlnaXRbKGNoID4+IDEyKSAmIDB4MDAwRl07CisgICAgICAgICAgICAqcCsrID0gaGV4ZGlnaXRbKGNoID4+IDgpICYgMHgwMDBGXTsKKyAgICAgICAgICAgICpwKysgPSBoZXhkaWdpdFsoY2ggPj4gNCkgJiAweDAwMEZdOworICAgICAgICAgICAgKnArKyA9IGhleGRpZ2l0W2NoICYgMHgwMDBGXTsKKyAgICAgICAgfQorCisgICAgICAgIC8qIE1hcCBzcGVjaWFsIHdoaXRlc3BhY2UgdG8gJ1x0JywgXG4nLCAnXHInICovCisgICAgICAgIGVsc2UgaWYgKGNoID09ICdcdCcpIHsKKyAgICAgICAgICAgICpwKysgPSAnXFwnOworICAgICAgICAgICAgKnArKyA9ICd0JzsKKyAgICAgICAgfQorICAgICAgICBlbHNlIGlmIChjaCA9PSAnXG4nKSB7CisgICAgICAgICAgICAqcCsrID0gJ1xcJzsKKyAgICAgICAgICAgICpwKysgPSAnbic7CisgICAgICAgIH0KKyAgICAgICAgZWxzZSBpZiAoY2ggPT0gJ1xyJykgeworICAgICAgICAgICAgKnArKyA9ICdcXCc7CisgICAgICAgICAgICAqcCsrID0gJ3InOworICAgICAgICB9CisKKyAgICAgICAgLyogTWFwIG5vbi1wcmludGFibGUgVVMgQVNDSUkgdG8gJ1x4aGgnICovCisgICAgICAgIGVsc2UgaWYgKGNoIDwgJyAnIHx8IGNoID49IDB4N0YpIHsKKyAgICAgICAgICAgICpwKysgPSAnXFwnOworICAgICAgICAgICAgKnArKyA9ICd4JzsKKyAgICAgICAgICAgICpwKysgPSBoZXhkaWdpdFsoY2ggPj4gNCkgJiAweDAwMEZdOworICAgICAgICAgICAgKnArKyA9IGhleGRpZ2l0W2NoICYgMHgwMDBGXTsKKyAgICAgICAgfQorCisgICAgICAgIC8qIENvcHkgZXZlcnl0aGluZyBlbHNlIGFzLWlzICovCisgICAgICAgIGVsc2UKKyAgICAgICAgICAgICpwKysgPSAoY2hhcikgY2g7CisgICAgfQorICAgIGlmIChxdW90ZXMpCisgICAgICAgICpwKysgPSBQeVN0cmluZ19BU19TVFJJTkcocmVwcilbMV07CisKKyAgICAqcCA9ICdcMCc7CisgICAgaWYgKF9QeVN0cmluZ19SZXNpemUoJnJlcHIsIHAgLSBQeVN0cmluZ19BU19TVFJJTkcocmVwcikpKQorICAgICAgICByZXR1cm4gTlVMTDsKKyAgICByZXR1cm4gcmVwcjsKK30KKworUHlPYmplY3QgKlB5VW5pY29kZV9FbmNvZGVVbmljb2RlRXNjYXBlKGNvbnN0IFB5X1VOSUNPREUgKnMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHlfc3NpemVfdCBzaXplKQoreworICAgIHJldHVybiB1bmljb2RlZXNjYXBlX3N0cmluZyhzLCBzaXplLCAwKTsKK30KKworUHlPYmplY3QgKlB5VW5pY29kZV9Bc1VuaWNvZGVFc2NhcGVTdHJpbmcoUHlPYmplY3QgKnVuaWNvZGUpCit7CisgICAgaWYgKCFQeVVuaWNvZGVfQ2hlY2sodW5pY29kZSkpIHsKKyAgICAgICAgUHlFcnJfQmFkQXJndW1lbnQoKTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIHJldHVybiBQeVVuaWNvZGVfRW5jb2RlVW5pY29kZUVzY2FwZShQeVVuaWNvZGVfQVNfVU5JQ09ERSh1bmljb2RlKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHlVbmljb2RlX0dFVF9TSVpFKHVuaWNvZGUpKTsKK30KKworLyogLS0tIFJhdyBVbmljb2RlIEVzY2FwZSBDb2RlYyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCisKK1B5T2JqZWN0ICpQeVVuaWNvZGVfRGVjb2RlUmF3VW5pY29kZUVzY2FwZShjb25zdCBjaGFyICpzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFB5X3NzaXplX3Qgc2l6ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyICplcnJvcnMpCit7CisgICAgY29uc3QgY2hhciAqc3RhcnRzID0gczsKKyAgICBQeV9zc2l6ZV90IHN0YXJ0aW5wb3M7CisgICAgUHlfc3NpemVfdCBlbmRpbnBvczsKKyAgICBQeV9zc2l6ZV90IG91dHBvczsKKyAgICBQeVVuaWNvZGVPYmplY3QgKnY7CisgICAgUHlfVU5JQ09ERSAqcDsKKyAgICBjb25zdCBjaGFyICplbmQ7CisgICAgY29uc3QgY2hhciAqYnM7CisgICAgUHlPYmplY3QgKmVycm9ySGFuZGxlciA9IE5VTEw7CisgICAgUHlPYmplY3QgKmV4YyA9IE5VTEw7CisKKyAgICAvKiBFc2NhcGVkIHN0cmluZ3Mgd2lsbCBhbHdheXMgYmUgbG9uZ2VyIHRoYW4gdGhlIHJlc3VsdGluZworICAgICAgIFVuaWNvZGUgc3RyaW5nLCBzbyB3ZSBzdGFydCB3aXRoIHNpemUgaGVyZSBhbmQgdGhlbiByZWR1Y2UgdGhlCisgICAgICAgbGVuZ3RoIGFmdGVyIGNvbnZlcnNpb24gdG8gdGhlIHRydWUgdmFsdWUuIChCdXQgZGVjb2RpbmcgZXJyb3IKKyAgICAgICBoYW5kbGVyIG1pZ2h0IGhhdmUgdG8gcmVzaXplIHRoZSBzdHJpbmcpICovCisgICAgdiA9IF9QeVVuaWNvZGVfTmV3KHNpemUpOworICAgIGlmICh2ID09IE5VTEwpCisgICAgICAgIGdvdG8gb25FcnJvcjsKKyAgICBpZiAoc2l6ZSA9PSAwKQorICAgICAgICByZXR1cm4gKFB5T2JqZWN0ICopdjsKKyAgICBwID0gUHlVbmljb2RlX0FTX1VOSUNPREUodik7CisgICAgZW5kID0gcyArIHNpemU7CisgICAgd2hpbGUgKHMgPCBlbmQpIHsKKyAgICAgICAgdW5zaWduZWQgY2hhciBjOworICAgICAgICBQeV9VQ1M0IHg7CisgICAgICAgIGludCBpOworICAgICAgICBpbnQgY291bnQ7CisKKyAgICAgICAgLyogTm9uLWVzY2FwZSBjaGFyYWN0ZXJzIGFyZSBpbnRlcnByZXRlZCBhcyBVbmljb2RlIG9yZGluYWxzICovCisgICAgICAgIGlmICgqcyAhPSAnXFwnKSB7CisgICAgICAgICAgICAqcCsrID0gKHVuc2lnbmVkIGNoYXIpKnMrKzsKKyAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICB9CisgICAgICAgIHN0YXJ0aW5wb3MgPSBzLXN0YXJ0czsKKworICAgICAgICAvKiBcdS1lc2NhcGVzIGFyZSBvbmx5IGludGVycHJldGVkIGlmZiB0aGUgbnVtYmVyIG9mIGxlYWRpbmcKKyAgICAgICAgICAgYmFja3NsYXNoZXMgaWYgb2RkICovCisgICAgICAgIGJzID0gczsKKyAgICAgICAgZm9yICg7cyA8IGVuZDspIHsKKyAgICAgICAgICAgIGlmICgqcyAhPSAnXFwnKQorICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgKnArKyA9ICh1bnNpZ25lZCBjaGFyKSpzKys7CisgICAgICAgIH0KKyAgICAgICAgaWYgKCgocyAtIGJzKSAmIDEpID09IDAgfHwKKyAgICAgICAgICAgIHMgPj0gZW5kIHx8CisgICAgICAgICAgICAoKnMgIT0gJ3UnICYmICpzICE9ICdVJykpIHsKKyAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICB9CisgICAgICAgIHAtLTsKKyAgICAgICAgY291bnQgPSAqcz09J3UnID8gNCA6IDg7CisgICAgICAgIHMrKzsKKworICAgICAgICAvKiBcdVhYWFggd2l0aCA0IGhleCBkaWdpdHMsIFxVeHh4eHh4eHggd2l0aCA4ICovCisgICAgICAgIG91dHBvcyA9IHAtUHlVbmljb2RlX0FTX1VOSUNPREUodik7CisgICAgICAgIGZvciAoeCA9IDAsIGkgPSAwOyBpIDwgY291bnQ7ICsraSwgKytzKSB7CisgICAgICAgICAgICBjID0gKHVuc2lnbmVkIGNoYXIpKnM7CisgICAgICAgICAgICBpZiAoIWlzeGRpZ2l0KGMpKSB7CisgICAgICAgICAgICAgICAgZW5kaW5wb3MgPSBzLXN0YXJ0czsKKyAgICAgICAgICAgICAgICBpZiAodW5pY29kZV9kZWNvZGVfY2FsbF9lcnJvcmhhbmRsZXIoCisgICAgICAgICAgICAgICAgICAgICAgICBlcnJvcnMsICZlcnJvckhhbmRsZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAicmF3dW5pY29kZWVzY2FwZSIsICJ0cnVuY2F0ZWQgXFx1WFhYWCIsCisgICAgICAgICAgICAgICAgICAgICAgICBzdGFydHMsIHNpemUsICZzdGFydGlucG9zLCAmZW5kaW5wb3MsICZleGMsICZzLAorICAgICAgICAgICAgICAgICAgICAgICAgJnYsICZvdXRwb3MsICZwKSkKKyAgICAgICAgICAgICAgICAgICAgZ290byBvbkVycm9yOworICAgICAgICAgICAgICAgIGdvdG8gbmV4dEJ5dGU7CisgICAgICAgICAgICB9CisgICAgICAgICAgICB4ID0gKHg8PDQpICYgfjB4RjsKKyAgICAgICAgICAgIGlmIChjID49ICcwJyAmJiBjIDw9ICc5JykKKyAgICAgICAgICAgICAgICB4ICs9IGMgLSAnMCc7CisgICAgICAgICAgICBlbHNlIGlmIChjID49ICdhJyAmJiBjIDw9ICdmJykKKyAgICAgICAgICAgICAgICB4ICs9IDEwICsgYyAtICdhJzsKKyAgICAgICAgICAgIGVsc2UKKyAgICAgICAgICAgICAgICB4ICs9IDEwICsgYyAtICdBJzsKKyAgICAgICAgfQorICAgICAgICBpZiAoeCA8PSAweGZmZmYpCisgICAgICAgICAgICAvKiBVQ1MtMiBjaGFyYWN0ZXIgKi8KKyAgICAgICAgICAgICpwKysgPSAoUHlfVU5JQ09ERSkgeDsKKyAgICAgICAgZWxzZSBpZiAoeCA8PSAweDEwZmZmZikgeworICAgICAgICAgICAgLyogVUNTLTQgY2hhcmFjdGVyLiBFaXRoZXIgc3RvcmUgZGlyZWN0bHksIG9yIGFzCisgICAgICAgICAgICAgICBzdXJyb2dhdGUgcGFpci4gKi8KKyNpZmRlZiBQeV9VTklDT0RFX1dJREUKKyAgICAgICAgICAgICpwKysgPSAoUHlfVU5JQ09ERSkgeDsKKyNlbHNlCisgICAgICAgICAgICB4IC09IDB4MTAwMDBMOworICAgICAgICAgICAgKnArKyA9IDB4RDgwMCArIChQeV9VTklDT0RFKSAoeCA+PiAxMCk7CisgICAgICAgICAgICAqcCsrID0gMHhEQzAwICsgKFB5X1VOSUNPREUpICh4ICYgMHgwM0ZGKTsKKyNlbmRpZgorICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgZW5kaW5wb3MgPSBzLXN0YXJ0czsKKyAgICAgICAgICAgIG91dHBvcyA9IHAtUHlVbmljb2RlX0FTX1VOSUNPREUodik7CisgICAgICAgICAgICBpZiAodW5pY29kZV9kZWNvZGVfY2FsbF9lcnJvcmhhbmRsZXIoCisgICAgICAgICAgICAgICAgICAgIGVycm9ycywgJmVycm9ySGFuZGxlciwKKyAgICAgICAgICAgICAgICAgICAgInJhd3VuaWNvZGVlc2NhcGUiLCAiXFxVeHh4eHh4eHggb3V0IG9mIHJhbmdlIiwKKyAgICAgICAgICAgICAgICAgICAgc3RhcnRzLCBzaXplLCAmc3RhcnRpbnBvcywgJmVuZGlucG9zLCAmZXhjLCAmcywKKyAgICAgICAgICAgICAgICAgICAgJnYsICZvdXRwb3MsICZwKSkKKyAgICAgICAgICAgICAgICBnb3RvIG9uRXJyb3I7CisgICAgICAgIH0KKyAgICAgIG5leHRCeXRlOgorICAgICAgICA7CisgICAgfQorICAgIGlmIChfUHlVbmljb2RlX1Jlc2l6ZSgmdiwgcCAtIFB5VW5pY29kZV9BU19VTklDT0RFKHYpKSA8IDApCisgICAgICAgIGdvdG8gb25FcnJvcjsKKyAgICBQeV9YREVDUkVGKGVycm9ySGFuZGxlcik7CisgICAgUHlfWERFQ1JFRihleGMpOworICAgIHJldHVybiAoUHlPYmplY3QgKil2OworCisgIG9uRXJyb3I6CisgICAgUHlfWERFQ1JFRih2KTsKKyAgICBQeV9YREVDUkVGKGVycm9ySGFuZGxlcik7CisgICAgUHlfWERFQ1JFRihleGMpOworICAgIHJldHVybiBOVUxMOworfQorCitQeU9iamVjdCAqUHlVbmljb2RlX0VuY29kZVJhd1VuaWNvZGVFc2NhcGUoY29uc3QgUHlfVU5JQ09ERSAqcywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQeV9zc2l6ZV90IHNpemUpCit7CisgICAgUHlPYmplY3QgKnJlcHI7CisgICAgY2hhciAqcDsKKyAgICBjaGFyICpxOworCisgICAgc3RhdGljIGNvbnN0IGNoYXIgKmhleGRpZ2l0ID0gIjAxMjM0NTY3ODlhYmNkZWYiOworI2lmZGVmIFB5X1VOSUNPREVfV0lERQorICAgIGNvbnN0IFB5X3NzaXplX3QgZXhwYW5kc2l6ZSA9IDEwOworI2Vsc2UKKyAgICBjb25zdCBQeV9zc2l6ZV90IGV4cGFuZHNpemUgPSA2OworI2VuZGlmCisKKyAgICBpZiAoc2l6ZSA+IFBZX1NTSVpFX1RfTUFYIC8gZXhwYW5kc2l6ZSkKKyAgICAgICAgcmV0dXJuIFB5RXJyX05vTWVtb3J5KCk7CisKKyAgICByZXByID0gUHlTdHJpbmdfRnJvbVN0cmluZ0FuZFNpemUoTlVMTCwgZXhwYW5kc2l6ZSAqIHNpemUpOworICAgIGlmIChyZXByID09IE5VTEwpCisgICAgICAgIHJldHVybiBOVUxMOworICAgIGlmIChzaXplID09IDApCisgICAgICAgIHJldHVybiByZXByOworCisgICAgcCA9IHEgPSBQeVN0cmluZ19BU19TVFJJTkcocmVwcik7CisgICAgd2hpbGUgKHNpemUtLSA+IDApIHsKKyAgICAgICAgUHlfVU5JQ09ERSBjaCA9ICpzKys7CisjaWZkZWYgUHlfVU5JQ09ERV9XSURFCisgICAgICAgIC8qIE1hcCAzMi1iaXQgY2hhcmFjdGVycyB0byAnXFV4eHh4eHh4eCcgKi8KKyAgICAgICAgaWYgKGNoID49IDB4MTAwMDApIHsKKyAgICAgICAgICAgICpwKysgPSAnXFwnOworICAgICAgICAgICAgKnArKyA9ICdVJzsKKyAgICAgICAgICAgICpwKysgPSBoZXhkaWdpdFsoY2ggPj4gMjgpICYgMHhmXTsKKyAgICAgICAgICAgICpwKysgPSBoZXhkaWdpdFsoY2ggPj4gMjQpICYgMHhmXTsKKyAgICAgICAgICAgICpwKysgPSBoZXhkaWdpdFsoY2ggPj4gMjApICYgMHhmXTsKKyAgICAgICAgICAgICpwKysgPSBoZXhkaWdpdFsoY2ggPj4gMTYpICYgMHhmXTsKKyAgICAgICAgICAgICpwKysgPSBoZXhkaWdpdFsoY2ggPj4gMTIpICYgMHhmXTsKKyAgICAgICAgICAgICpwKysgPSBoZXhkaWdpdFsoY2ggPj4gOCkgJiAweGZdOworICAgICAgICAgICAgKnArKyA9IGhleGRpZ2l0WyhjaCA+PiA0KSAmIDB4Zl07CisgICAgICAgICAgICAqcCsrID0gaGV4ZGlnaXRbY2ggJiAxNV07CisgICAgICAgIH0KKyAgICAgICAgZWxzZQorI2Vsc2UKKyAgICAgICAgICAgIC8qIE1hcCBVVEYtMTYgc3Vycm9nYXRlIHBhaXJzIHRvICdcVTAweHh4eHh4JyAqLworICAgICAgICAgICAgaWYgKGNoID49IDB4RDgwMCAmJiBjaCA8IDB4REMwMCkgeworICAgICAgICAgICAgICAgIFB5X1VOSUNPREUgY2gyOworICAgICAgICAgICAgICAgIFB5X1VDUzQgdWNzOworCisgICAgICAgICAgICAgICAgY2gyID0gKnMrKzsKKyAgICAgICAgICAgICAgICBzaXplLS07CisgICAgICAgICAgICAgICAgaWYgKGNoMiA+PSAweERDMDAgJiYgY2gyIDw9IDB4REZGRikgeworICAgICAgICAgICAgICAgICAgICB1Y3MgPSAoKChjaCAmIDB4MDNGRikgPDwgMTApIHwgKGNoMiAmIDB4MDNGRikpICsgMHgwMDAxMDAwMDsKKyAgICAgICAgICAgICAgICAgICAgKnArKyA9ICdcXCc7CisgICAgICAgICAgICAgICAgICAgICpwKysgPSAnVSc7CisgICAgICAgICAgICAgICAgICAgICpwKysgPSBoZXhkaWdpdFsodWNzID4+IDI4KSAmIDB4Zl07CisgICAgICAgICAgICAgICAgICAgICpwKysgPSBoZXhkaWdpdFsodWNzID4+IDI0KSAmIDB4Zl07CisgICAgICAgICAgICAgICAgICAgICpwKysgPSBoZXhkaWdpdFsodWNzID4+IDIwKSAmIDB4Zl07CisgICAgICAgICAgICAgICAgICAgICpwKysgPSBoZXhkaWdpdFsodWNzID4+IDE2KSAmIDB4Zl07CisgICAgICAgICAgICAgICAgICAgICpwKysgPSBoZXhkaWdpdFsodWNzID4+IDEyKSAmIDB4Zl07CisgICAgICAgICAgICAgICAgICAgICpwKysgPSBoZXhkaWdpdFsodWNzID4+IDgpICYgMHhmXTsKKyAgICAgICAgICAgICAgICAgICAgKnArKyA9IGhleGRpZ2l0Wyh1Y3MgPj4gNCkgJiAweGZdOworICAgICAgICAgICAgICAgICAgICAqcCsrID0gaGV4ZGlnaXRbdWNzICYgMHhmXTsKKyAgICAgICAgICAgICAgICAgICAgY29udGludWU7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIC8qIEZhbGwgdGhyb3VnaDogaXNvbGF0ZWQgc3Vycm9nYXRlcyBhcmUgY29waWVkIGFzLWlzICovCisgICAgICAgICAgICAgICAgcy0tOworICAgICAgICAgICAgICAgIHNpemUrKzsKKyAgICAgICAgICAgIH0KKyNlbmRpZgorICAgICAgICAvKiBNYXAgMTYtYml0IGNoYXJhY3RlcnMgdG8gJ1x1eHh4eCcgKi8KKyAgICAgICAgaWYgKGNoID49IDI1NikgeworICAgICAgICAgICAgKnArKyA9ICdcXCc7CisgICAgICAgICAgICAqcCsrID0gJ3UnOworICAgICAgICAgICAgKnArKyA9IGhleGRpZ2l0WyhjaCA+PiAxMikgJiAweGZdOworICAgICAgICAgICAgKnArKyA9IGhleGRpZ2l0WyhjaCA+PiA4KSAmIDB4Zl07CisgICAgICAgICAgICAqcCsrID0gaGV4ZGlnaXRbKGNoID4+IDQpICYgMHhmXTsKKyAgICAgICAgICAgICpwKysgPSBoZXhkaWdpdFtjaCAmIDE1XTsKKyAgICAgICAgfQorICAgICAgICAvKiBDb3B5IGV2ZXJ5dGhpbmcgZWxzZSBhcy1pcyAqLworICAgICAgICBlbHNlCisgICAgICAgICAgICAqcCsrID0gKGNoYXIpIGNoOworICAgIH0KKyAgICAqcCA9ICdcMCc7CisgICAgaWYgKF9QeVN0cmluZ19SZXNpemUoJnJlcHIsIHAgLSBxKSkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgcmV0dXJuIHJlcHI7Cit9CisKK1B5T2JqZWN0ICpQeVVuaWNvZGVfQXNSYXdVbmljb2RlRXNjYXBlU3RyaW5nKFB5T2JqZWN0ICp1bmljb2RlKQoreworICAgIGlmICghUHlVbmljb2RlX0NoZWNrKHVuaWNvZGUpKSB7CisgICAgICAgIFB5RXJyX0JhZEFyZ3VtZW50KCk7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICByZXR1cm4gUHlVbmljb2RlX0VuY29kZVJhd1VuaWNvZGVFc2NhcGUoUHlVbmljb2RlX0FTX1VOSUNPREUodW5pY29kZSksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFB5VW5pY29kZV9HRVRfU0laRSh1bmljb2RlKSk7Cit9CisKKy8qIC0tLSBVbmljb2RlIEludGVybmFsIENvZGVjIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KKworUHlPYmplY3QgKl9QeVVuaWNvZGVfRGVjb2RlVW5pY29kZUludGVybmFsKGNvbnN0IGNoYXIgKnMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHlfc3NpemVfdCBzaXplLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgKmVycm9ycykKK3sKKyAgICBjb25zdCBjaGFyICpzdGFydHMgPSBzOworICAgIFB5X3NzaXplX3Qgc3RhcnRpbnBvczsKKyAgICBQeV9zc2l6ZV90IGVuZGlucG9zOworICAgIFB5X3NzaXplX3Qgb3V0cG9zOworICAgIFB5VW5pY29kZU9iamVjdCAqdjsKKyAgICBQeV9VTklDT0RFICpwOworICAgIGNvbnN0IGNoYXIgKmVuZDsKKyAgICBjb25zdCBjaGFyICpyZWFzb247CisgICAgUHlPYmplY3QgKmVycm9ySGFuZGxlciA9IE5VTEw7CisgICAgUHlPYmplY3QgKmV4YyA9IE5VTEw7CisKKyNpZmRlZiBQeV9VTklDT0RFX1dJREUKKyAgICBQeV9VTklDT0RFIHVuaW1heCA9IFB5VW5pY29kZV9HZXRNYXgoKTsKKyNlbmRpZgorCisgICAgLyogWFhYIG92ZXJmbG93IGRldGVjdGlvbiBtaXNzaW5nICovCisgICAgdiA9IF9QeVVuaWNvZGVfTmV3KChzaXplK1B5X1VOSUNPREVfU0laRS0xKS8gUHlfVU5JQ09ERV9TSVpFKTsKKyAgICBpZiAodiA9PSBOVUxMKQorICAgICAgICBnb3RvIG9uRXJyb3I7CisgICAgaWYgKFB5VW5pY29kZV9HZXRTaXplKChQeU9iamVjdCAqKXYpID09IDApCisgICAgICAgIHJldHVybiAoUHlPYmplY3QgKil2OworICAgIHAgPSBQeVVuaWNvZGVfQVNfVU5JQ09ERSh2KTsKKyAgICBlbmQgPSBzICsgc2l6ZTsKKworICAgIHdoaWxlIChzIDwgZW5kKSB7CisgICAgICAgIGlmIChlbmQtcyA8IFB5X1VOSUNPREVfU0laRSkgeworICAgICAgICAgICAgZW5kaW5wb3MgPSBlbmQtc3RhcnRzOworICAgICAgICAgICAgcmVhc29uID0gInRydW5jYXRlZCBpbnB1dCI7CisgICAgICAgICAgICBnb3RvIGVycm9yOworICAgICAgICB9CisgICAgICAgIG1lbWNweShwLCBzLCBzaXplb2YoUHlfVU5JQ09ERSkpOworI2lmZGVmIFB5X1VOSUNPREVfV0lERQorICAgICAgICAvKiBXZSBoYXZlIHRvIHNhbml0eSBjaGVjayB0aGUgcmF3IGRhdGEsIG90aGVyd2lzZSBkb29tIGxvb21zIGZvcgorICAgICAgICAgICBzb21lIG1hbGZvcm1lZCBVQ1MtNCBkYXRhLiAqLworICAgICAgICBpZiAoKnAgPiB1bmltYXggfHwgKnAgPCAwKSB7CisgICAgICAgICAgICBlbmRpbnBvcyA9IHMgLSBzdGFydHMgKyBQeV9VTklDT0RFX1NJWkU7CisgICAgICAgICAgICByZWFzb24gPSAiaWxsZWdhbCBjb2RlIHBvaW50ICg+IDB4MTBGRkZGKSI7CisgICAgICAgICAgICBnb3RvIGVycm9yOworICAgICAgICB9CisjZW5kaWYKKyAgICAgICAgcCsrOworICAgICAgICBzICs9IFB5X1VOSUNPREVfU0laRTsKKyAgICAgICAgY29udGludWU7CisKKyAgZXJyb3I6CisgICAgICAgIHN0YXJ0aW5wb3MgPSBzIC0gc3RhcnRzOworICAgICAgICBvdXRwb3MgPSBwIC0gUHlVbmljb2RlX0FTX1VOSUNPREUodik7CisgICAgICAgIGlmICh1bmljb2RlX2RlY29kZV9jYWxsX2Vycm9yaGFuZGxlcigKKyAgICAgICAgICAgICAgICBlcnJvcnMsICZlcnJvckhhbmRsZXIsCisgICAgICAgICAgICAgICAgInVuaWNvZGVfaW50ZXJuYWwiLCByZWFzb24sCisgICAgICAgICAgICAgICAgc3RhcnRzLCBzaXplLCAmc3RhcnRpbnBvcywgJmVuZGlucG9zLCAmZXhjLCAmcywKKyAgICAgICAgICAgICAgICAmdiwgJm91dHBvcywgJnApKSB7CisgICAgICAgICAgICBnb3RvIG9uRXJyb3I7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBpZiAoX1B5VW5pY29kZV9SZXNpemUoJnYsIHAgLSBQeVVuaWNvZGVfQVNfVU5JQ09ERSh2KSkgPCAwKQorICAgICAgICBnb3RvIG9uRXJyb3I7CisgICAgUHlfWERFQ1JFRihlcnJvckhhbmRsZXIpOworICAgIFB5X1hERUNSRUYoZXhjKTsKKyAgICByZXR1cm4gKFB5T2JqZWN0ICopdjsKKworICBvbkVycm9yOgorICAgIFB5X1hERUNSRUYodik7CisgICAgUHlfWERFQ1JFRihlcnJvckhhbmRsZXIpOworICAgIFB5X1hERUNSRUYoZXhjKTsKKyAgICByZXR1cm4gTlVMTDsKK30KKworLyogLS0tIExhdGluLTEgQ29kZWMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCisKK1B5T2JqZWN0ICpQeVVuaWNvZGVfRGVjb2RlTGF0aW4xKGNvbnN0IGNoYXIgKnMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQeV9zc2l6ZV90IHNpemUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyICplcnJvcnMpCit7CisgICAgUHlVbmljb2RlT2JqZWN0ICp2OworICAgIFB5X1VOSUNPREUgKnA7CisKKyAgICAvKiBMYXRpbi0xIGlzIGVxdWl2YWxlbnQgdG8gdGhlIGZpcnN0IDI1NiBvcmRpbmFscyBpbiBVbmljb2RlLiAqLworICAgIGlmIChzaXplID09IDEpIHsKKyAgICAgICAgUHlfVU5JQ09ERSByID0gKih1bnNpZ25lZCBjaGFyKilzOworICAgICAgICByZXR1cm4gUHlVbmljb2RlX0Zyb21Vbmljb2RlKCZyLCAxKTsKKyAgICB9CisKKyAgICB2ID0gX1B5VW5pY29kZV9OZXcoc2l6ZSk7CisgICAgaWYgKHYgPT0gTlVMTCkKKyAgICAgICAgZ290byBvbkVycm9yOworICAgIGlmIChzaXplID09IDApCisgICAgICAgIHJldHVybiAoUHlPYmplY3QgKil2OworICAgIHAgPSBQeVVuaWNvZGVfQVNfVU5JQ09ERSh2KTsKKyAgICB3aGlsZSAoc2l6ZS0tID4gMCkKKyAgICAgICAgKnArKyA9ICh1bnNpZ25lZCBjaGFyKSpzKys7CisgICAgcmV0dXJuIChQeU9iamVjdCAqKXY7CisKKyAgb25FcnJvcjoKKyAgICBQeV9YREVDUkVGKHYpOworICAgIHJldHVybiBOVUxMOworfQorCisvKiBjcmVhdGUgb3IgYWRqdXN0IGEgVW5pY29kZUVuY29kZUVycm9yICovCitzdGF0aWMgdm9pZCBtYWtlX2VuY29kZV9leGNlcHRpb24oUHlPYmplY3QgKipleGNlcHRpb25PYmplY3QsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciAqZW5jb2RpbmcsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgUHlfVU5JQ09ERSAqdW5pY29kZSwgUHlfc3NpemVfdCBzaXplLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFB5X3NzaXplX3Qgc3RhcnRwb3MsIFB5X3NzaXplX3QgZW5kcG9zLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgKnJlYXNvbikKK3sKKyAgICBpZiAoKmV4Y2VwdGlvbk9iamVjdCA9PSBOVUxMKSB7CisgICAgICAgICpleGNlcHRpb25PYmplY3QgPSBQeVVuaWNvZGVFbmNvZGVFcnJvcl9DcmVhdGUoCisgICAgICAgICAgICBlbmNvZGluZywgdW5pY29kZSwgc2l6ZSwgc3RhcnRwb3MsIGVuZHBvcywgcmVhc29uKTsKKyAgICB9CisgICAgZWxzZSB7CisgICAgICAgIGlmIChQeVVuaWNvZGVFbmNvZGVFcnJvcl9TZXRTdGFydCgqZXhjZXB0aW9uT2JqZWN0LCBzdGFydHBvcykpCisgICAgICAgICAgICBnb3RvIG9uRXJyb3I7CisgICAgICAgIGlmIChQeVVuaWNvZGVFbmNvZGVFcnJvcl9TZXRFbmQoKmV4Y2VwdGlvbk9iamVjdCwgZW5kcG9zKSkKKyAgICAgICAgICAgIGdvdG8gb25FcnJvcjsKKyAgICAgICAgaWYgKFB5VW5pY29kZUVuY29kZUVycm9yX1NldFJlYXNvbigqZXhjZXB0aW9uT2JqZWN0LCByZWFzb24pKQorICAgICAgICAgICAgZ290byBvbkVycm9yOworICAgICAgICByZXR1cm47CisgICAgICBvbkVycm9yOgorICAgICAgICBQeV9ERUNSRUYoKmV4Y2VwdGlvbk9iamVjdCk7CisgICAgICAgICpleGNlcHRpb25PYmplY3QgPSBOVUxMOworICAgIH0KK30KKworLyogcmFpc2VzIGEgVW5pY29kZUVuY29kZUVycm9yICovCitzdGF0aWMgdm9pZCByYWlzZV9lbmNvZGVfZXhjZXB0aW9uKFB5T2JqZWN0ICoqZXhjZXB0aW9uT2JqZWN0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyICplbmNvZGluZywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgUHlfVU5JQ09ERSAqdW5pY29kZSwgUHlfc3NpemVfdCBzaXplLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQeV9zc2l6ZV90IHN0YXJ0cG9zLCBQeV9zc2l6ZV90IGVuZHBvcywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciAqcmVhc29uKQoreworICAgIG1ha2VfZW5jb2RlX2V4Y2VwdGlvbihleGNlcHRpb25PYmplY3QsCisgICAgICAgICAgICAgICAgICAgICAgICAgIGVuY29kaW5nLCB1bmljb2RlLCBzaXplLCBzdGFydHBvcywgZW5kcG9zLCByZWFzb24pOworICAgIGlmICgqZXhjZXB0aW9uT2JqZWN0ICE9IE5VTEwpCisgICAgICAgIFB5Q29kZWNfU3RyaWN0RXJyb3JzKCpleGNlcHRpb25PYmplY3QpOworfQorCisvKiBlcnJvciBoYW5kbGluZyBjYWxsYmFjayBoZWxwZXI6CisgICBidWlsZCBhcmd1bWVudHMsIGNhbGwgdGhlIGNhbGxiYWNrIGFuZCBjaGVjayB0aGUgYXJndW1lbnRzLAorICAgcHV0IHRoZSByZXN1bHQgaW50byBuZXdwb3MgYW5kIHJldHVybiB0aGUgcmVwbGFjZW1lbnQgc3RyaW5nLCB3aGljaAorICAgaGFzIHRvIGJlIGZyZWVkIGJ5IHRoZSBjYWxsZXIgKi8KK3N0YXRpYyBQeU9iamVjdCAqdW5pY29kZV9lbmNvZGVfY2FsbF9lcnJvcmhhbmRsZXIoY29uc3QgY2hhciAqZXJyb3JzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQeU9iamVjdCAqKmVycm9ySGFuZGxlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciAqZW5jb2RpbmcsIGNvbnN0IGNoYXIgKnJlYXNvbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgUHlfVU5JQ09ERSAqdW5pY29kZSwgUHlfc3NpemVfdCBzaXplLCBQeU9iamVjdCAqKmV4Y2VwdGlvbk9iamVjdCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHlfc3NpemVfdCBzdGFydHBvcywgUHlfc3NpemVfdCBlbmRwb3MsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFB5X3NzaXplX3QgKm5ld3BvcykKK3sKKyAgICBzdGF0aWMgY2hhciAqYXJncGFyc2UgPSAiTyFuO2VuY29kaW5nIGVycm9yIGhhbmRsZXIgbXVzdCByZXR1cm4gKHVuaWNvZGUsIGludCkgdHVwbGUiOworCisgICAgUHlPYmplY3QgKnJlc3R1cGxlOworICAgIFB5T2JqZWN0ICpyZXN1bmljb2RlOworCisgICAgaWYgKCplcnJvckhhbmRsZXIgPT0gTlVMTCkgeworICAgICAgICAqZXJyb3JIYW5kbGVyID0gUHlDb2RlY19Mb29rdXBFcnJvcihlcnJvcnMpOworICAgICAgICBpZiAoKmVycm9ySGFuZGxlciA9PSBOVUxMKQorICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorCisgICAgbWFrZV9lbmNvZGVfZXhjZXB0aW9uKGV4Y2VwdGlvbk9iamVjdCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgZW5jb2RpbmcsIHVuaWNvZGUsIHNpemUsIHN0YXJ0cG9zLCBlbmRwb3MsIHJlYXNvbik7CisgICAgaWYgKCpleGNlcHRpb25PYmplY3QgPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisKKyAgICByZXN0dXBsZSA9IFB5T2JqZWN0X0NhbGxGdW5jdGlvbk9iakFyZ3MoCisgICAgICAgICplcnJvckhhbmRsZXIsICpleGNlcHRpb25PYmplY3QsIE5VTEwpOworICAgIGlmIChyZXN0dXBsZSA9PSBOVUxMKQorICAgICAgICByZXR1cm4gTlVMTDsKKyAgICBpZiAoIVB5VHVwbGVfQ2hlY2socmVzdHVwbGUpKSB7CisgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19UeXBlRXJyb3IsICZhcmdwYXJzZVs0XSk7CisgICAgICAgIFB5X0RFQ1JFRihyZXN0dXBsZSk7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICBpZiAoIVB5QXJnX1BhcnNlVHVwbGUocmVzdHVwbGUsIGFyZ3BhcnNlLCAmUHlVbmljb2RlX1R5cGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICZyZXN1bmljb2RlLCBuZXdwb3MpKSB7CisgICAgICAgIFB5X0RFQ1JFRihyZXN0dXBsZSk7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICBpZiAoKm5ld3BvczwwKQorICAgICAgICAqbmV3cG9zID0gc2l6ZSsqbmV3cG9zOworICAgIGlmICgqbmV3cG9zPDAgfHwgKm5ld3Bvcz5zaXplKSB7CisgICAgICAgIFB5RXJyX0Zvcm1hdChQeUV4Y19JbmRleEVycm9yLCAicG9zaXRpb24gJXpkIGZyb20gZXJyb3IgaGFuZGxlciBvdXQgb2YgYm91bmRzIiwgKm5ld3Bvcyk7CisgICAgICAgIFB5X0RFQ1JFRihyZXN0dXBsZSk7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICBQeV9JTkNSRUYocmVzdW5pY29kZSk7CisgICAgUHlfREVDUkVGKHJlc3R1cGxlKTsKKyAgICByZXR1cm4gcmVzdW5pY29kZTsKK30KKworc3RhdGljIFB5T2JqZWN0ICp1bmljb2RlX2VuY29kZV91Y3MxKGNvbnN0IFB5X1VOSUNPREUgKnAsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHlfc3NpemVfdCBzaXplLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgKmVycm9ycywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgbGltaXQpCit7CisgICAgLyogb3V0cHV0IG9iamVjdCAqLworICAgIFB5T2JqZWN0ICpyZXM7CisgICAgLyogcG9pbnRlcnMgdG8gdGhlIGJlZ2lubmluZyBhbmQgZW5kKzEgb2YgaW5wdXQgKi8KKyAgICBjb25zdCBQeV9VTklDT0RFICpzdGFydHAgPSBwOworICAgIGNvbnN0IFB5X1VOSUNPREUgKmVuZHAgPSBwICsgc2l6ZTsKKyAgICAvKiBwb2ludGVyIHRvIHRoZSBiZWdpbm5pbmcgb2YgdGhlIHVuZW5jb2RhYmxlIGNoYXJhY3RlcnMgKi8KKyAgICAvKiBjb25zdCBQeV9VTklDT0RFICpiYWRwID0gTlVMTDsgKi8KKyAgICAvKiBwb2ludGVyIGludG8gdGhlIG91dHB1dCAqLworICAgIGNoYXIgKnN0cjsKKyAgICAvKiBjdXJyZW50IG91dHB1dCBwb3NpdGlvbiAqLworICAgIFB5X3NzaXplX3QgcmVzcG9zID0gMDsKKyAgICBQeV9zc2l6ZV90IHJlc3NpemU7CisgICAgY29uc3QgY2hhciAqZW5jb2RpbmcgPSAobGltaXQgPT0gMjU2KSA/ICJsYXRpbi0xIiA6ICJhc2NpaSI7CisgICAgY29uc3QgY2hhciAqcmVhc29uID0gKGxpbWl0ID09IDI1NikgPyAib3JkaW5hbCBub3QgaW4gcmFuZ2UoMjU2KSIgOiAib3JkaW5hbCBub3QgaW4gcmFuZ2UoMTI4KSI7CisgICAgUHlPYmplY3QgKmVycm9ySGFuZGxlciA9IE5VTEw7CisgICAgUHlPYmplY3QgKmV4YyA9IE5VTEw7CisgICAgLyogdGhlIGZvbGxvd2luZyB2YXJpYWJsZSBpcyB1c2VkIGZvciBjYWNoaW5nIHN0cmluZyBjb21wYXJpc29ucworICAgICAqIC0xPW5vdCBpbml0aWFsaXplZCwgMD11bmtub3duLCAxPXN0cmljdCwgMj1yZXBsYWNlLCAzPWlnbm9yZSwgND14bWxjaGFycmVmcmVwbGFjZSAqLworICAgIGludCBrbm93bl9lcnJvckhhbmRsZXIgPSAtMTsKKworICAgIC8qIGFsbG9jYXRlIGVub3VnaCBmb3IgYSBzaW1wbGUgZW5jb2Rpbmcgd2l0aG91dAorICAgICAgIHJlcGxhY2VtZW50cywgaWYgd2UgbmVlZCBtb3JlLCB3ZSdsbCByZXNpemUgKi8KKyAgICByZXMgPSBQeVN0cmluZ19Gcm9tU3RyaW5nQW5kU2l6ZShOVUxMLCBzaXplKTsKKyAgICBpZiAocmVzID09IE5VTEwpCisgICAgICAgIGdvdG8gb25FcnJvcjsKKyAgICBpZiAoc2l6ZSA9PSAwKQorICAgICAgICByZXR1cm4gcmVzOworICAgIHN0ciA9IFB5U3RyaW5nX0FTX1NUUklORyhyZXMpOworICAgIHJlc3NpemUgPSBzaXplOworCisgICAgd2hpbGUgKHA8ZW5kcCkgeworICAgICAgICBQeV9VTklDT0RFIGMgPSAqcDsKKworICAgICAgICAvKiBjYW4gd2UgZW5jb2RlIHRoaXM/ICovCisgICAgICAgIGlmIChjPGxpbWl0KSB7CisgICAgICAgICAgICAvKiBubyBvdmVyZmxvdyBjaGVjaywgYmVjYXVzZSB3ZSBrbm93IHRoYXQgdGhlIHNwYWNlIGlzIGVub3VnaCAqLworICAgICAgICAgICAgKnN0cisrID0gKGNoYXIpYzsKKyAgICAgICAgICAgICsrcDsKKyAgICAgICAgfQorICAgICAgICBlbHNlIHsKKyAgICAgICAgICAgIFB5X3NzaXplX3QgdW5pY29kZXBvcyA9IHAtc3RhcnRwOworICAgICAgICAgICAgUHlfc3NpemVfdCByZXF1aXJlZHNpemU7CisgICAgICAgICAgICBQeU9iamVjdCAqcmVwdW5pY29kZTsKKyAgICAgICAgICAgIFB5X3NzaXplX3QgcmVwc2l6ZTsKKyAgICAgICAgICAgIFB5X3NzaXplX3QgbmV3cG9zOworICAgICAgICAgICAgUHlfc3NpemVfdCByZXNwb3M7CisgICAgICAgICAgICBQeV9VTklDT0RFICp1bmkyOworICAgICAgICAgICAgLyogc3RhcnRwb3MgZm9yIGNvbGxlY3RpbmcgdW5lbmNvZGFibGUgY2hhcnMgKi8KKyAgICAgICAgICAgIGNvbnN0IFB5X1VOSUNPREUgKmNvbGxzdGFydCA9IHA7CisgICAgICAgICAgICBjb25zdCBQeV9VTklDT0RFICpjb2xsZW5kID0gcDsKKyAgICAgICAgICAgIC8qIGZpbmQgYWxsIHVuZWNvZGFibGUgY2hhcmFjdGVycyAqLworICAgICAgICAgICAgd2hpbGUgKChjb2xsZW5kIDwgZW5kcCkgJiYgKCgqY29sbGVuZCk+PWxpbWl0KSkKKyAgICAgICAgICAgICAgICArK2NvbGxlbmQ7CisgICAgICAgICAgICAvKiBjYWNoZSBjYWxsYmFjayBuYW1lIGxvb2t1cCAoaWYgbm90IGRvbmUgeWV0LCBpLmUuIGl0J3MgdGhlIGZpcnN0IGVycm9yKSAqLworICAgICAgICAgICAgaWYgKGtub3duX2Vycm9ySGFuZGxlcj09LTEpIHsKKyAgICAgICAgICAgICAgICBpZiAoKGVycm9ycz09TlVMTCkgfHwgKCFzdHJjbXAoZXJyb3JzLCAic3RyaWN0IikpKQorICAgICAgICAgICAgICAgICAgICBrbm93bl9lcnJvckhhbmRsZXIgPSAxOworICAgICAgICAgICAgICAgIGVsc2UgaWYgKCFzdHJjbXAoZXJyb3JzLCAicmVwbGFjZSIpKQorICAgICAgICAgICAgICAgICAgICBrbm93bl9lcnJvckhhbmRsZXIgPSAyOworICAgICAgICAgICAgICAgIGVsc2UgaWYgKCFzdHJjbXAoZXJyb3JzLCAiaWdub3JlIikpCisgICAgICAgICAgICAgICAgICAgIGtub3duX2Vycm9ySGFuZGxlciA9IDM7CisgICAgICAgICAgICAgICAgZWxzZSBpZiAoIXN0cmNtcChlcnJvcnMsICJ4bWxjaGFycmVmcmVwbGFjZSIpKQorICAgICAgICAgICAgICAgICAgICBrbm93bl9lcnJvckhhbmRsZXIgPSA0OworICAgICAgICAgICAgICAgIGVsc2UKKyAgICAgICAgICAgICAgICAgICAga25vd25fZXJyb3JIYW5kbGVyID0gMDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHN3aXRjaCAoa25vd25fZXJyb3JIYW5kbGVyKSB7CisgICAgICAgICAgICBjYXNlIDE6IC8qIHN0cmljdCAqLworICAgICAgICAgICAgICAgIHJhaXNlX2VuY29kZV9leGNlcHRpb24oJmV4YywgZW5jb2RpbmcsIHN0YXJ0cCwgc2l6ZSwgY29sbHN0YXJ0LXN0YXJ0cCwgY29sbGVuZC1zdGFydHAsIHJlYXNvbik7CisgICAgICAgICAgICAgICAgZ290byBvbkVycm9yOworICAgICAgICAgICAgY2FzZSAyOiAvKiByZXBsYWNlICovCisgICAgICAgICAgICAgICAgd2hpbGUgKGNvbGxzdGFydCsrPGNvbGxlbmQpCisgICAgICAgICAgICAgICAgICAgICpzdHIrKyA9ICc/JzsgLyogZmFsbCB0aHJvdWdoICovCisgICAgICAgICAgICBjYXNlIDM6IC8qIGlnbm9yZSAqLworICAgICAgICAgICAgICAgIHAgPSBjb2xsZW5kOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgY2FzZSA0OiAvKiB4bWxjaGFycmVmcmVwbGFjZSAqLworICAgICAgICAgICAgICAgIHJlc3BvcyA9IHN0ci1QeVN0cmluZ19BU19TVFJJTkcocmVzKTsKKyAgICAgICAgICAgICAgICAvKiBkZXRlcm1pbmUgcmVwbGFjZW1lbnQgc2l6ZSAodGVtcG9yYXJpbHkgKG1pcyl1c2VzIHApICovCisgICAgICAgICAgICAgICAgZm9yIChwID0gY29sbHN0YXJ0LCByZXBzaXplID0gMDsgcCA8IGNvbGxlbmQ7ICsrcCkgeworICAgICAgICAgICAgICAgICAgICBpZiAoKnA8MTApCisgICAgICAgICAgICAgICAgICAgICAgICByZXBzaXplICs9IDIrMSsxOworICAgICAgICAgICAgICAgICAgICBlbHNlIGlmICgqcDwxMDApCisgICAgICAgICAgICAgICAgICAgICAgICByZXBzaXplICs9IDIrMisxOworICAgICAgICAgICAgICAgICAgICBlbHNlIGlmICgqcDwxMDAwKQorICAgICAgICAgICAgICAgICAgICAgICAgcmVwc2l6ZSArPSAyKzMrMTsKKyAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoKnA8MTAwMDApCisgICAgICAgICAgICAgICAgICAgICAgICByZXBzaXplICs9IDIrNCsxOworI2lmbmRlZiBQeV9VTklDT0RFX1dJREUKKyAgICAgICAgICAgICAgICAgICAgZWxzZQorICAgICAgICAgICAgICAgICAgICAgICAgcmVwc2l6ZSArPSAyKzUrMTsKKyNlbHNlCisgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKCpwPDEwMDAwMCkKKyAgICAgICAgICAgICAgICAgICAgICAgIHJlcHNpemUgKz0gMis1KzE7CisgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKCpwPDEwMDAwMDApCisgICAgICAgICAgICAgICAgICAgICAgICByZXBzaXplICs9IDIrNisxOworICAgICAgICAgICAgICAgICAgICBlbHNlCisgICAgICAgICAgICAgICAgICAgICAgICByZXBzaXplICs9IDIrNysxOworI2VuZGlmCisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHJlcXVpcmVkc2l6ZSA9IHJlc3BvcytyZXBzaXplKyhlbmRwLWNvbGxlbmQpOworICAgICAgICAgICAgICAgIGlmIChyZXF1aXJlZHNpemUgPiByZXNzaXplKSB7CisgICAgICAgICAgICAgICAgICAgIGlmIChyZXF1aXJlZHNpemU8MipyZXNzaXplKQorICAgICAgICAgICAgICAgICAgICAgICAgcmVxdWlyZWRzaXplID0gMipyZXNzaXplOworICAgICAgICAgICAgICAgICAgICBpZiAoX1B5U3RyaW5nX1Jlc2l6ZSgmcmVzLCByZXF1aXJlZHNpemUpKQorICAgICAgICAgICAgICAgICAgICAgICAgZ290byBvbkVycm9yOworICAgICAgICAgICAgICAgICAgICBzdHIgPSBQeVN0cmluZ19BU19TVFJJTkcocmVzKSArIHJlc3BvczsKKyAgICAgICAgICAgICAgICAgICAgcmVzc2l6ZSA9IHJlcXVpcmVkc2l6ZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgLyogZ2VuZXJhdGUgcmVwbGFjZW1lbnQgKHRlbXBvcmFyaWx5IChtaXMpdXNlcyBwKSAqLworICAgICAgICAgICAgICAgIGZvciAocCA9IGNvbGxzdGFydDsgcCA8IGNvbGxlbmQ7ICsrcCkgeworICAgICAgICAgICAgICAgICAgICBzdHIgKz0gc3ByaW50ZihzdHIsICImIyVkOyIsIChpbnQpKnApOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBwID0gY29sbGVuZDsKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICAgICAgcmVwdW5pY29kZSA9IHVuaWNvZGVfZW5jb2RlX2NhbGxfZXJyb3JoYW5kbGVyKGVycm9ycywgJmVycm9ySGFuZGxlciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZW5jb2RpbmcsIHJlYXNvbiwgc3RhcnRwLCBzaXplLCAmZXhjLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xsc3RhcnQtc3RhcnRwLCBjb2xsZW5kLXN0YXJ0cCwgJm5ld3Bvcyk7CisgICAgICAgICAgICAgICAgaWYgKHJlcHVuaWNvZGUgPT0gTlVMTCkKKyAgICAgICAgICAgICAgICAgICAgZ290byBvbkVycm9yOworICAgICAgICAgICAgICAgIC8qIG5lZWQgbW9yZSBzcGFjZT8gKGF0IGxlYXN0IGVub3VnaCBmb3Igd2hhdCB3ZSBoYXZlK3RoZQorICAgICAgICAgICAgICAgICAgIHJlcGxhY2VtZW50K3RoZSByZXN0IG9mIHRoZSBzdHJpbmcsIHNvIHdlIHdvbid0IGhhdmUgdG8KKyAgICAgICAgICAgICAgICAgICBjaGVjayBzcGFjZSBmb3IgZW5jb2RhYmxlIGNoYXJhY3RlcnMpICovCisgICAgICAgICAgICAgICAgcmVzcG9zID0gc3RyLVB5U3RyaW5nX0FTX1NUUklORyhyZXMpOworICAgICAgICAgICAgICAgIHJlcHNpemUgPSBQeVVuaWNvZGVfR0VUX1NJWkUocmVwdW5pY29kZSk7CisgICAgICAgICAgICAgICAgcmVxdWlyZWRzaXplID0gcmVzcG9zK3JlcHNpemUrKGVuZHAtY29sbGVuZCk7CisgICAgICAgICAgICAgICAgaWYgKHJlcXVpcmVkc2l6ZSA+IHJlc3NpemUpIHsKKyAgICAgICAgICAgICAgICAgICAgaWYgKHJlcXVpcmVkc2l6ZTwyKnJlc3NpemUpCisgICAgICAgICAgICAgICAgICAgICAgICByZXF1aXJlZHNpemUgPSAyKnJlc3NpemU7CisgICAgICAgICAgICAgICAgICAgIGlmIChfUHlTdHJpbmdfUmVzaXplKCZyZXMsIHJlcXVpcmVkc2l6ZSkpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIFB5X0RFQ1JFRihyZXB1bmljb2RlKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGdvdG8gb25FcnJvcjsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBzdHIgPSBQeVN0cmluZ19BU19TVFJJTkcocmVzKSArIHJlc3BvczsKKyAgICAgICAgICAgICAgICAgICAgcmVzc2l6ZSA9IHJlcXVpcmVkc2l6ZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgLyogY2hlY2sgaWYgdGhlcmUgaXMgYW55dGhpbmcgdW5lbmNvZGFibGUgaW4gdGhlIHJlcGxhY2VtZW50CisgICAgICAgICAgICAgICAgICAgYW5kIGNvcHkgaXQgdG8gdGhlIG91dHB1dCAqLworICAgICAgICAgICAgICAgIGZvciAodW5pMiA9IFB5VW5pY29kZV9BU19VTklDT0RFKHJlcHVuaWNvZGUpO3JlcHNpemUtLT4wOyArK3VuaTIsICsrc3RyKSB7CisgICAgICAgICAgICAgICAgICAgIGMgPSAqdW5pMjsKKyAgICAgICAgICAgICAgICAgICAgaWYgKGMgPj0gbGltaXQpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJhaXNlX2VuY29kZV9leGNlcHRpb24oJmV4YywgZW5jb2RpbmcsIHN0YXJ0cCwgc2l6ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5pY29kZXBvcywgdW5pY29kZXBvcysxLCByZWFzb24pOworICAgICAgICAgICAgICAgICAgICAgICAgUHlfREVDUkVGKHJlcHVuaWNvZGUpOworICAgICAgICAgICAgICAgICAgICAgICAgZ290byBvbkVycm9yOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICpzdHIgPSAoY2hhciljOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBwID0gc3RhcnRwICsgbmV3cG9zOworICAgICAgICAgICAgICAgIFB5X0RFQ1JFRihyZXB1bmljb2RlKTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKyAgICAvKiBSZXNpemUgaWYgd2UgYWxsb2NhdGVkIHRvIG11Y2ggKi8KKyAgICByZXNwb3MgPSBzdHItUHlTdHJpbmdfQVNfU1RSSU5HKHJlcyk7CisgICAgaWYgKHJlc3BvczxyZXNzaXplKQorICAgICAgICAvKiBJZiB0aGlzIGZhbGxzIHJlcyB3aWxsIGJlIE5VTEwgKi8KKyAgICAgICAgX1B5U3RyaW5nX1Jlc2l6ZSgmcmVzLCByZXNwb3MpOworICAgIFB5X1hERUNSRUYoZXJyb3JIYW5kbGVyKTsKKyAgICBQeV9YREVDUkVGKGV4Yyk7CisgICAgcmV0dXJuIHJlczsKKworICBvbkVycm9yOgorICAgIFB5X1hERUNSRUYocmVzKTsKKyAgICBQeV9YREVDUkVGKGVycm9ySGFuZGxlcik7CisgICAgUHlfWERFQ1JFRihleGMpOworICAgIHJldHVybiBOVUxMOworfQorCitQeU9iamVjdCAqUHlVbmljb2RlX0VuY29kZUxhdGluMShjb25zdCBQeV9VTklDT0RFICpwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHlfc3NpemVfdCBzaXplLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciAqZXJyb3JzKQoreworICAgIHJldHVybiB1bmljb2RlX2VuY29kZV91Y3MxKHAsIHNpemUsIGVycm9ycywgMjU2KTsKK30KKworUHlPYmplY3QgKlB5VW5pY29kZV9Bc0xhdGluMVN0cmluZyhQeU9iamVjdCAqdW5pY29kZSkKK3sKKyAgICBpZiAoIVB5VW5pY29kZV9DaGVjayh1bmljb2RlKSkgeworICAgICAgICBQeUVycl9CYWRBcmd1bWVudCgpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgcmV0dXJuIFB5VW5pY29kZV9FbmNvZGVMYXRpbjEoUHlVbmljb2RlX0FTX1VOSUNPREUodW5pY29kZSksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHlVbmljb2RlX0dFVF9TSVpFKHVuaWNvZGUpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5VTEwpOworfQorCisvKiAtLS0gNy1iaXQgQVNDSUkgQ29kZWMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KKworUHlPYmplY3QgKlB5VW5pY29kZV9EZWNvZGVBU0NJSShjb25zdCBjaGFyICpzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQeV9zc2l6ZV90IHNpemUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgKmVycm9ycykKK3sKKyAgICBjb25zdCBjaGFyICpzdGFydHMgPSBzOworICAgIFB5VW5pY29kZU9iamVjdCAqdjsKKyAgICBQeV9VTklDT0RFICpwOworICAgIFB5X3NzaXplX3Qgc3RhcnRpbnBvczsKKyAgICBQeV9zc2l6ZV90IGVuZGlucG9zOworICAgIFB5X3NzaXplX3Qgb3V0cG9zOworICAgIGNvbnN0IGNoYXIgKmU7CisgICAgUHlPYmplY3QgKmVycm9ySGFuZGxlciA9IE5VTEw7CisgICAgUHlPYmplY3QgKmV4YyA9IE5VTEw7CisKKyAgICAvKiBBU0NJSSBpcyBlcXVpdmFsZW50IHRvIHRoZSBmaXJzdCAxMjggb3JkaW5hbHMgaW4gVW5pY29kZS4gKi8KKyAgICBpZiAoc2l6ZSA9PSAxICYmICoodW5zaWduZWQgY2hhciopcyA8IDEyOCkgeworICAgICAgICBQeV9VTklDT0RFIHIgPSAqKHVuc2lnbmVkIGNoYXIqKXM7CisgICAgICAgIHJldHVybiBQeVVuaWNvZGVfRnJvbVVuaWNvZGUoJnIsIDEpOworICAgIH0KKworICAgIHYgPSBfUHlVbmljb2RlX05ldyhzaXplKTsKKyAgICBpZiAodiA9PSBOVUxMKQorICAgICAgICBnb3RvIG9uRXJyb3I7CisgICAgaWYgKHNpemUgPT0gMCkKKyAgICAgICAgcmV0dXJuIChQeU9iamVjdCAqKXY7CisgICAgcCA9IFB5VW5pY29kZV9BU19VTklDT0RFKHYpOworICAgIGUgPSBzICsgc2l6ZTsKKyAgICB3aGlsZSAocyA8IGUpIHsKKyAgICAgICAgcmVnaXN0ZXIgdW5zaWduZWQgY2hhciBjID0gKHVuc2lnbmVkIGNoYXIpKnM7CisgICAgICAgIGlmIChjIDwgMTI4KSB7CisgICAgICAgICAgICAqcCsrID0gYzsKKyAgICAgICAgICAgICsrczsKKyAgICAgICAgfQorICAgICAgICBlbHNlIHsKKyAgICAgICAgICAgIHN0YXJ0aW5wb3MgPSBzLXN0YXJ0czsKKyAgICAgICAgICAgIGVuZGlucG9zID0gc3RhcnRpbnBvcyArIDE7CisgICAgICAgICAgICBvdXRwb3MgPSBwIC0gKFB5X1VOSUNPREUgKilQeVVuaWNvZGVfQVNfVU5JQ09ERSh2KTsKKyAgICAgICAgICAgIGlmICh1bmljb2RlX2RlY29kZV9jYWxsX2Vycm9yaGFuZGxlcigKKyAgICAgICAgICAgICAgICAgICAgZXJyb3JzLCAmZXJyb3JIYW5kbGVyLAorICAgICAgICAgICAgICAgICAgICAiYXNjaWkiLCAib3JkaW5hbCBub3QgaW4gcmFuZ2UoMTI4KSIsCisgICAgICAgICAgICAgICAgICAgIHN0YXJ0cywgc2l6ZSwgJnN0YXJ0aW5wb3MsICZlbmRpbnBvcywgJmV4YywgJnMsCisgICAgICAgICAgICAgICAgICAgICZ2LCAmb3V0cG9zLCAmcCkpCisgICAgICAgICAgICAgICAgZ290byBvbkVycm9yOworICAgICAgICB9CisgICAgfQorICAgIGlmIChwIC0gUHlVbmljb2RlX0FTX1VOSUNPREUodikgPCBQeVN0cmluZ19HRVRfU0laRSh2KSkKKyAgICAgICAgaWYgKF9QeVVuaWNvZGVfUmVzaXplKCZ2LCBwIC0gUHlVbmljb2RlX0FTX1VOSUNPREUodikpIDwgMCkKKyAgICAgICAgICAgIGdvdG8gb25FcnJvcjsKKyAgICBQeV9YREVDUkVGKGVycm9ySGFuZGxlcik7CisgICAgUHlfWERFQ1JFRihleGMpOworICAgIHJldHVybiAoUHlPYmplY3QgKil2OworCisgIG9uRXJyb3I6CisgICAgUHlfWERFQ1JFRih2KTsKKyAgICBQeV9YREVDUkVGKGVycm9ySGFuZGxlcik7CisgICAgUHlfWERFQ1JFRihleGMpOworICAgIHJldHVybiBOVUxMOworfQorCitQeU9iamVjdCAqUHlVbmljb2RlX0VuY29kZUFTQ0lJKGNvbnN0IFB5X1VOSUNPREUgKnAsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFB5X3NzaXplX3Qgc2l6ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciAqZXJyb3JzKQoreworICAgIHJldHVybiB1bmljb2RlX2VuY29kZV91Y3MxKHAsIHNpemUsIGVycm9ycywgMTI4KTsKK30KKworUHlPYmplY3QgKlB5VW5pY29kZV9Bc0FTQ0lJU3RyaW5nKFB5T2JqZWN0ICp1bmljb2RlKQoreworICAgIGlmICghUHlVbmljb2RlX0NoZWNrKHVuaWNvZGUpKSB7CisgICAgICAgIFB5RXJyX0JhZEFyZ3VtZW50KCk7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICByZXR1cm4gUHlVbmljb2RlX0VuY29kZUFTQ0lJKFB5VW5pY29kZV9BU19VTklDT0RFKHVuaWNvZGUpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHlVbmljb2RlX0dFVF9TSVpFKHVuaWNvZGUpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCk7Cit9CisKKyNpZiBkZWZpbmVkKE1TX1dJTkRPV1MpICYmIGRlZmluZWQoSEFWRV9VU0FCTEVfV0NIQVJfVCkKKworLyogLS0tIE1CQ1MgY29kZWNzIGZvciBXaW5kb3dzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCisKKyNpZiBTSVpFT0ZfSU5UIDwgU0laRU9GX1NJWkVfVAorI2RlZmluZSBORUVEX1JFVFJZCisjZW5kaWYKKworLyogWFhYIFRoaXMgY29kZSBpcyBsaW1pdGVkIHRvICJ0cnVlIiBkb3VibGUtYnl0ZSBlbmNvZGluZ3MsIGFzCisgICBhKSBpdCBhc3N1bWVzIGFuIGluY29tcGxldGUgY2hhcmFjdGVyIGNvbnNpc3RzIG9mIGEgc2luZ2xlIGJ5dGUsIGFuZAorICAgYikgSXNEQkNTTGVhZEJ5dGUgKHByb2JhYmx5KSBkb2VzIG5vdCB3b3JrIGZvciBub24tREJDUyBtdWx0aS1ieXRlCisgICBlbmNvZGluZ3MsIHNlZSBJc0RCQ1NMZWFkQnl0ZUV4IGRvY3VtZW50YXRpb24uICovCisKK3N0YXRpYyBpbnQgaXNfZGJjc19sZWFkX2J5dGUoY29uc3QgY2hhciAqcywgaW50IG9mZnNldCkKK3sKKyAgICBjb25zdCBjaGFyICpjdXJyID0gcyArIG9mZnNldDsKKworICAgIGlmIChJc0RCQ1NMZWFkQnl0ZSgqY3VycikpIHsKKyAgICAgICAgY29uc3QgY2hhciAqcHJldiA9IENoYXJQcmV2KHMsIGN1cnIpOworICAgICAgICByZXR1cm4gKHByZXYgPT0gY3VycikgfHwgIUlzREJDU0xlYWRCeXRlKCpwcmV2KSB8fCAoY3VyciAtIHByZXYgPT0gMik7CisgICAgfQorICAgIHJldHVybiAwOworfQorCisvKgorICogRGVjb2RlIE1CQ1Mgc3RyaW5nIGludG8gdW5pY29kZSBvYmplY3QuIElmICdmaW5hbCcgaXMgc2V0LCBjb252ZXJ0cworICogdHJhaWxpbmcgbGVhZC1ieXRlIHRvby4gUmV0dXJucyBjb25zdW1lZCBzaXplIGlmIHN1Y2NlZWQsIC0xIG90aGVyd2lzZS4KKyAqLworc3RhdGljIGludCBkZWNvZGVfbWJjcyhQeVVuaWNvZGVPYmplY3QgKip2LAorICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyICpzLCAvKiBNQkNTIHN0cmluZyAqLworICAgICAgICAgICAgICAgICAgICAgICBpbnQgc2l6ZSwgLyogc2l6ZW9mIE1CQ1Mgc3RyaW5nICovCisgICAgICAgICAgICAgICAgICAgICAgIGludCBmaW5hbCkKK3sKKyAgICBQeV9VTklDT0RFICpwOworICAgIFB5X3NzaXplX3QgbiA9IDA7CisgICAgaW50IHVzaXplID0gMDsKKworICAgIGFzc2VydChzaXplID49IDApOworCisgICAgLyogU2tpcCB0cmFpbGluZyBsZWFkLWJ5dGUgdW5sZXNzICdmaW5hbCcgaXMgc2V0ICovCisgICAgaWYgKCFmaW5hbCAmJiBzaXplID49IDEgJiYgaXNfZGJjc19sZWFkX2J5dGUocywgc2l6ZSAtIDEpKQorICAgICAgICAtLXNpemU7CisKKyAgICAvKiBGaXJzdCBnZXQgdGhlIHNpemUgb2YgdGhlIHJlc3VsdCAqLworICAgIGlmIChzaXplID4gMCkgeworICAgICAgICB1c2l6ZSA9IE11bHRpQnl0ZVRvV2lkZUNoYXIoQ1BfQUNQLCAwLCBzLCBzaXplLCBOVUxMLCAwKTsKKyAgICAgICAgaWYgKHVzaXplID09IDApIHsKKyAgICAgICAgICAgIFB5RXJyX1NldEZyb21XaW5kb3dzRXJyV2l0aEZpbGVuYW1lKDAsIE5VTEwpOworICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICB9CisgICAgfQorCisgICAgaWYgKCp2ID09IE5VTEwpIHsKKyAgICAgICAgLyogQ3JlYXRlIHVuaWNvZGUgb2JqZWN0ICovCisgICAgICAgICp2ID0gX1B5VW5pY29kZV9OZXcodXNpemUpOworICAgICAgICBpZiAoKnYgPT0gTlVMTCkKKyAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisgICAgZWxzZSB7CisgICAgICAgIC8qIEV4dGVuZCB1bmljb2RlIG9iamVjdCAqLworICAgICAgICBuID0gUHlVbmljb2RlX0dFVF9TSVpFKCp2KTsKKyAgICAgICAgaWYgKF9QeVVuaWNvZGVfUmVzaXplKHYsIG4gKyB1c2l6ZSkgPCAwKQorICAgICAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKworICAgIC8qIERvIHRoZSBjb252ZXJzaW9uICovCisgICAgaWYgKHNpemUgPiAwKSB7CisgICAgICAgIHAgPSBQeVVuaWNvZGVfQVNfVU5JQ09ERSgqdikgKyBuOworICAgICAgICBpZiAoMCA9PSBNdWx0aUJ5dGVUb1dpZGVDaGFyKENQX0FDUCwgMCwgcywgc2l6ZSwgcCwgdXNpemUpKSB7CisgICAgICAgICAgICBQeUVycl9TZXRGcm9tV2luZG93c0VycldpdGhGaWxlbmFtZSgwLCBOVUxMKTsKKyAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgfQorICAgIH0KKworICAgIHJldHVybiBzaXplOworfQorCitQeU9iamVjdCAqUHlVbmljb2RlX0RlY29kZU1CQ1NTdGF0ZWZ1bChjb25zdCBjaGFyICpzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHlfc3NpemVfdCBzaXplLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciAqZXJyb3JzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHlfc3NpemVfdCAqY29uc3VtZWQpCit7CisgICAgUHlVbmljb2RlT2JqZWN0ICp2ID0gTlVMTDsKKyAgICBpbnQgZG9uZTsKKworICAgIGlmIChjb25zdW1lZCkKKyAgICAgICAgKmNvbnN1bWVkID0gMDsKKworI2lmZGVmIE5FRURfUkVUUlkKKyAgcmV0cnk6CisgICAgaWYgKHNpemUgPiBJTlRfTUFYKQorICAgICAgICBkb25lID0gZGVjb2RlX21iY3MoJnYsIHMsIElOVF9NQVgsIDApOworICAgIGVsc2UKKyNlbmRpZgorICAgICAgICBkb25lID0gZGVjb2RlX21iY3MoJnYsIHMsIChpbnQpc2l6ZSwgIWNvbnN1bWVkKTsKKworICAgIGlmIChkb25lIDwgMCkgeworICAgICAgICBQeV9YREVDUkVGKHYpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisKKyAgICBpZiAoY29uc3VtZWQpCisgICAgICAgICpjb25zdW1lZCArPSBkb25lOworCisjaWZkZWYgTkVFRF9SRVRSWQorICAgIGlmIChzaXplID4gSU5UX01BWCkgeworICAgICAgICBzICs9IGRvbmU7CisgICAgICAgIHNpemUgLT0gZG9uZTsKKyAgICAgICAgZ290byByZXRyeTsKKyAgICB9CisjZW5kaWYKKworICAgIHJldHVybiAoUHlPYmplY3QgKil2OworfQorCitQeU9iamVjdCAqUHlVbmljb2RlX0RlY29kZU1CQ1MoY29uc3QgY2hhciAqcywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQeV9zc2l6ZV90IHNpemUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciAqZXJyb3JzKQoreworICAgIHJldHVybiBQeVVuaWNvZGVfRGVjb2RlTUJDU1N0YXRlZnVsKHMsIHNpemUsIGVycm9ycywgTlVMTCk7Cit9CisKKy8qCisgKiBDb252ZXJ0IHVuaWNvZGUgaW50byBzdHJpbmcgb2JqZWN0IChNQkNTKS4KKyAqIFJldHVybnMgMCBpZiBzdWNjZWVkLCAtMSBvdGhlcndpc2UuCisgKi8KK3N0YXRpYyBpbnQgZW5jb2RlX21iY3MoUHlPYmplY3QgKipyZXByLAorICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBQeV9VTklDT0RFICpwLCAvKiB1bmljb2RlICovCisgICAgICAgICAgICAgICAgICAgICAgIGludCBzaXplKSAvKiBzaXplIG9mIHVuaWNvZGUgKi8KK3sKKyAgICBpbnQgbWJjc3NpemUgPSAwOworICAgIFB5X3NzaXplX3QgbiA9IDA7CisKKyAgICBhc3NlcnQoc2l6ZSA+PSAwKTsKKworICAgIC8qIEZpcnN0IGdldCB0aGUgc2l6ZSBvZiB0aGUgcmVzdWx0ICovCisgICAgaWYgKHNpemUgPiAwKSB7CisgICAgICAgIG1iY3NzaXplID0gV2lkZUNoYXJUb011bHRpQnl0ZShDUF9BQ1AsIDAsIHAsIHNpemUsIE5VTEwsIDAsIE5VTEwsIE5VTEwpOworICAgICAgICBpZiAobWJjc3NpemUgPT0gMCkgeworICAgICAgICAgICAgUHlFcnJfU2V0RnJvbVdpbmRvd3NFcnJXaXRoRmlsZW5hbWUoMCwgTlVMTCk7CisgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgIH0KKyAgICB9CisKKyAgICBpZiAoKnJlcHIgPT0gTlVMTCkgeworICAgICAgICAvKiBDcmVhdGUgc3RyaW5nIG9iamVjdCAqLworICAgICAgICAqcmVwciA9IFB5U3RyaW5nX0Zyb21TdHJpbmdBbmRTaXplKE5VTEwsIG1iY3NzaXplKTsKKyAgICAgICAgaWYgKCpyZXByID09IE5VTEwpCisgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgfQorICAgIGVsc2UgeworICAgICAgICAvKiBFeHRlbmQgc3RyaW5nIG9iamVjdCAqLworICAgICAgICBuID0gUHlTdHJpbmdfU2l6ZSgqcmVwcik7CisgICAgICAgIGlmIChfUHlTdHJpbmdfUmVzaXplKHJlcHIsIG4gKyBtYmNzc2l6ZSkgPCAwKQorICAgICAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKworICAgIC8qIERvIHRoZSBjb252ZXJzaW9uICovCisgICAgaWYgKHNpemUgPiAwKSB7CisgICAgICAgIGNoYXIgKnMgPSBQeVN0cmluZ19BU19TVFJJTkcoKnJlcHIpICsgbjsKKyAgICAgICAgaWYgKDAgPT0gV2lkZUNoYXJUb011bHRpQnl0ZShDUF9BQ1AsIDAsIHAsIHNpemUsIHMsIG1iY3NzaXplLCBOVUxMLCBOVUxMKSkgeworICAgICAgICAgICAgUHlFcnJfU2V0RnJvbVdpbmRvd3NFcnJXaXRoRmlsZW5hbWUoMCwgTlVMTCk7CisgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgIH0KKyAgICB9CisKKyAgICByZXR1cm4gMDsKK30KKworUHlPYmplY3QgKlB5VW5pY29kZV9FbmNvZGVNQkNTKGNvbnN0IFB5X1VOSUNPREUgKnAsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHlfc3NpemVfdCBzaXplLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgKmVycm9ycykKK3sKKyAgICBQeU9iamVjdCAqcmVwciA9IE5VTEw7CisgICAgaW50IHJldDsKKworI2lmZGVmIE5FRURfUkVUUlkKKyAgcmV0cnk6CisgICAgaWYgKHNpemUgPiBJTlRfTUFYKQorICAgICAgICByZXQgPSBlbmNvZGVfbWJjcygmcmVwciwgcCwgSU5UX01BWCk7CisgICAgZWxzZQorI2VuZGlmCisgICAgICAgIHJldCA9IGVuY29kZV9tYmNzKCZyZXByLCBwLCAoaW50KXNpemUpOworCisgICAgaWYgKHJldCA8IDApIHsKKyAgICAgICAgUHlfWERFQ1JFRihyZXByKTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorCisjaWZkZWYgTkVFRF9SRVRSWQorICAgIGlmIChzaXplID4gSU5UX01BWCkgeworICAgICAgICBwICs9IElOVF9NQVg7CisgICAgICAgIHNpemUgLT0gSU5UX01BWDsKKyAgICAgICAgZ290byByZXRyeTsKKyAgICB9CisjZW5kaWYKKworICAgIHJldHVybiByZXByOworfQorCitQeU9iamVjdCAqUHlVbmljb2RlX0FzTUJDU1N0cmluZyhQeU9iamVjdCAqdW5pY29kZSkKK3sKKyAgICBpZiAoIVB5VW5pY29kZV9DaGVjayh1bmljb2RlKSkgeworICAgICAgICBQeUVycl9CYWRBcmd1bWVudCgpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgcmV0dXJuIFB5VW5pY29kZV9FbmNvZGVNQkNTKFB5VW5pY29kZV9BU19VTklDT0RFKHVuaWNvZGUpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQeVVuaWNvZGVfR0VUX1NJWkUodW5pY29kZSksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5VTEwpOworfQorCisjdW5kZWYgTkVFRF9SRVRSWQorCisjZW5kaWYgLyogTVNfV0lORE9XUyAqLworCisvKiAtLS0gQ2hhcmFjdGVyIE1hcHBpbmcgQ29kZWMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KKworUHlPYmplY3QgKlB5VW5pY29kZV9EZWNvZGVDaGFybWFwKGNvbnN0IGNoYXIgKnMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHlfc3NpemVfdCBzaXplLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFB5T2JqZWN0ICptYXBwaW5nLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgKmVycm9ycykKK3sKKyAgICBjb25zdCBjaGFyICpzdGFydHMgPSBzOworICAgIFB5X3NzaXplX3Qgc3RhcnRpbnBvczsKKyAgICBQeV9zc2l6ZV90IGVuZGlucG9zOworICAgIFB5X3NzaXplX3Qgb3V0cG9zOworICAgIGNvbnN0IGNoYXIgKmU7CisgICAgUHlVbmljb2RlT2JqZWN0ICp2OworICAgIFB5X1VOSUNPREUgKnA7CisgICAgUHlfc3NpemVfdCBleHRyYWNoYXJzID0gMDsKKyAgICBQeU9iamVjdCAqZXJyb3JIYW5kbGVyID0gTlVMTDsKKyAgICBQeU9iamVjdCAqZXhjID0gTlVMTDsKKyAgICBQeV9VTklDT0RFICptYXBzdHJpbmcgPSBOVUxMOworICAgIFB5X3NzaXplX3QgbWFwbGVuID0gMDsKKworICAgIC8qIERlZmF1bHQgdG8gTGF0aW4tMSAqLworICAgIGlmIChtYXBwaW5nID09IE5VTEwpCisgICAgICAgIHJldHVybiBQeVVuaWNvZGVfRGVjb2RlTGF0aW4xKHMsIHNpemUsIGVycm9ycyk7CisKKyAgICB2ID0gX1B5VW5pY29kZV9OZXcoc2l6ZSk7CisgICAgaWYgKHYgPT0gTlVMTCkKKyAgICAgICAgZ290byBvbkVycm9yOworICAgIGlmIChzaXplID09IDApCisgICAgICAgIHJldHVybiAoUHlPYmplY3QgKil2OworICAgIHAgPSBQeVVuaWNvZGVfQVNfVU5JQ09ERSh2KTsKKyAgICBlID0gcyArIHNpemU7CisgICAgaWYgKFB5VW5pY29kZV9DaGVja0V4YWN0KG1hcHBpbmcpKSB7CisgICAgICAgIG1hcHN0cmluZyA9IFB5VW5pY29kZV9BU19VTklDT0RFKG1hcHBpbmcpOworICAgICAgICBtYXBsZW4gPSBQeVVuaWNvZGVfR0VUX1NJWkUobWFwcGluZyk7CisgICAgICAgIHdoaWxlIChzIDwgZSkgeworICAgICAgICAgICAgdW5zaWduZWQgY2hhciBjaCA9ICpzOworICAgICAgICAgICAgUHlfVU5JQ09ERSB4ID0gMHhmZmZlOyAvKiBpbGxlZ2FsIHZhbHVlICovCisKKyAgICAgICAgICAgIGlmIChjaCA8IG1hcGxlbikKKyAgICAgICAgICAgICAgICB4ID0gbWFwc3RyaW5nW2NoXTsKKworICAgICAgICAgICAgaWYgKHggPT0gMHhmZmZlKSB7CisgICAgICAgICAgICAgICAgLyogdW5kZWZpbmVkIG1hcHBpbmcgKi8KKyAgICAgICAgICAgICAgICBvdXRwb3MgPSBwLVB5VW5pY29kZV9BU19VTklDT0RFKHYpOworICAgICAgICAgICAgICAgIHN0YXJ0aW5wb3MgPSBzLXN0YXJ0czsKKyAgICAgICAgICAgICAgICBlbmRpbnBvcyA9IHN0YXJ0aW5wb3MrMTsKKyAgICAgICAgICAgICAgICBpZiAodW5pY29kZV9kZWNvZGVfY2FsbF9lcnJvcmhhbmRsZXIoCisgICAgICAgICAgICAgICAgICAgICAgICBlcnJvcnMsICZlcnJvckhhbmRsZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAiY2hhcm1hcCIsICJjaGFyYWN0ZXIgbWFwcyB0byA8dW5kZWZpbmVkPiIsCisgICAgICAgICAgICAgICAgICAgICAgICBzdGFydHMsIHNpemUsICZzdGFydGlucG9zLCAmZW5kaW5wb3MsICZleGMsICZzLAorICAgICAgICAgICAgICAgICAgICAgICAgJnYsICZvdXRwb3MsICZwKSkgeworICAgICAgICAgICAgICAgICAgICBnb3RvIG9uRXJyb3I7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICAgICAgfQorICAgICAgICAgICAgKnArKyA9IHg7CisgICAgICAgICAgICArK3M7CisgICAgICAgIH0KKyAgICB9CisgICAgZWxzZSB7CisgICAgICAgIHdoaWxlIChzIDwgZSkgeworICAgICAgICAgICAgdW5zaWduZWQgY2hhciBjaCA9ICpzOworICAgICAgICAgICAgUHlPYmplY3QgKncsICp4OworCisgICAgICAgICAgICAvKiBHZXQgbWFwcGluZyAoY2hhciBvcmRpbmFsIC0+IGludGVnZXIsIFVuaWNvZGUgY2hhciBvciBOb25lKSAqLworICAgICAgICAgICAgdyA9IFB5SW50X0Zyb21Mb25nKChsb25nKWNoKTsKKyAgICAgICAgICAgIGlmICh3ID09IE5VTEwpCisgICAgICAgICAgICAgICAgZ290byBvbkVycm9yOworICAgICAgICAgICAgeCA9IFB5T2JqZWN0X0dldEl0ZW0obWFwcGluZywgdyk7CisgICAgICAgICAgICBQeV9ERUNSRUYodyk7CisgICAgICAgICAgICBpZiAoeCA9PSBOVUxMKSB7CisgICAgICAgICAgICAgICAgaWYgKFB5RXJyX0V4Y2VwdGlvbk1hdGNoZXMoUHlFeGNfTG9va3VwRXJyb3IpKSB7CisgICAgICAgICAgICAgICAgICAgIC8qIE5vIG1hcHBpbmcgZm91bmQgbWVhbnM6IG1hcHBpbmcgaXMgdW5kZWZpbmVkLiAqLworICAgICAgICAgICAgICAgICAgICBQeUVycl9DbGVhcigpOworICAgICAgICAgICAgICAgICAgICBnb3RvIFVuZGVmaW5lZDsKKyAgICAgICAgICAgICAgICB9IGVsc2UKKyAgICAgICAgICAgICAgICAgICAgZ290byBvbkVycm9yOworICAgICAgICAgICAgfQorCisgICAgICAgICAgICAvKiBBcHBseSBtYXBwaW5nICovCisgICAgICAgICAgICBpZiAoeCA9PSBQeV9Ob25lKQorICAgICAgICAgICAgICAgIGdvdG8gVW5kZWZpbmVkOworICAgICAgICAgICAgaWYgKFB5SW50X0NoZWNrKHgpKSB7CisgICAgICAgICAgICAgICAgbG9uZyB2YWx1ZSA9IFB5SW50X0FTX0xPTkcoeCk7CisgICAgICAgICAgICAgICAgaWYgKHZhbHVlID09IDB4RkZGRSkKKyAgICAgICAgICAgICAgICAgICAgZ290byBVbmRlZmluZWQ7CisgICAgICAgICAgICAgICAgaWYgKHZhbHVlIDwgMCB8fCB2YWx1ZSA+IDB4MTBGRkZGKSB7CisgICAgICAgICAgICAgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19UeXBlRXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiY2hhcmFjdGVyIG1hcHBpbmcgbXVzdCBiZSBpbiByYW5nZSgweDExMDAwMCkiKTsKKyAgICAgICAgICAgICAgICAgICAgUHlfREVDUkVGKHgpOworICAgICAgICAgICAgICAgICAgICBnb3RvIG9uRXJyb3I7CisgICAgICAgICAgICAgICAgfQorCisjaWZuZGVmIFB5X1VOSUNPREVfV0lERQorICAgICAgICAgICAgICAgIGlmICh2YWx1ZSA+IDB4RkZGRikgeworICAgICAgICAgICAgICAgICAgICAvKiBzZWUgdGhlIGNvZGUgZm9yIDEtbiBtYXBwaW5nIGJlbG93ICovCisgICAgICAgICAgICAgICAgICAgIGlmIChleHRyYWNoYXJzIDwgMikgeworICAgICAgICAgICAgICAgICAgICAgICAgLyogcmVzaXplIGZpcnN0ICovCisgICAgICAgICAgICAgICAgICAgICAgICBQeV9zc2l6ZV90IG9sZHBvcyA9IHAgLSBQeVVuaWNvZGVfQVNfVU5JQ09ERSh2KTsKKyAgICAgICAgICAgICAgICAgICAgICAgIFB5X3NzaXplX3QgbmVlZGVkID0gMTAgLSBleHRyYWNoYXJzOworICAgICAgICAgICAgICAgICAgICAgICAgZXh0cmFjaGFycyArPSBuZWVkZWQ7CisgICAgICAgICAgICAgICAgICAgICAgICAvKiBYWFggb3ZlcmZsb3cgZGV0ZWN0aW9uIG1pc3NpbmcgKi8KKyAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfUHlVbmljb2RlX1Jlc2l6ZSgmdiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQeVVuaWNvZGVfR0VUX1NJWkUodikgKyBuZWVkZWQpIDwgMCkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIFB5X0RFQ1JFRih4KTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBnb3RvIG9uRXJyb3I7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICBwID0gUHlVbmljb2RlX0FTX1VOSUNPREUodikgKyBvbGRwb3M7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgdmFsdWUgLT0gMHgxMDAwMDsKKyAgICAgICAgICAgICAgICAgICAgKnArKyA9IDB4RDgwMCB8ICh2YWx1ZSA+PiAxMCk7CisgICAgICAgICAgICAgICAgICAgICpwKysgPSAweERDMDAgfCAodmFsdWUgJiAweDNGRik7CisgICAgICAgICAgICAgICAgICAgIGV4dHJhY2hhcnMgLT0gMjsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgZWxzZQorI2VuZGlmCisgICAgICAgICAgICAgICAgKnArKyA9IChQeV9VTklDT0RFKXZhbHVlOworICAgICAgICAgICAgfQorICAgICAgICAgICAgZWxzZSBpZiAoUHlVbmljb2RlX0NoZWNrKHgpKSB7CisgICAgICAgICAgICAgICAgUHlfc3NpemVfdCB0YXJnZXRzaXplID0gUHlVbmljb2RlX0dFVF9TSVpFKHgpOworCisgICAgICAgICAgICAgICAgaWYgKHRhcmdldHNpemUgPT0gMSkgeworICAgICAgICAgICAgICAgICAgICAvKiAxLTEgbWFwcGluZyAqLworICAgICAgICAgICAgICAgICAgICBQeV9VTklDT0RFIHZhbHVlID0gKlB5VW5pY29kZV9BU19VTklDT0RFKHgpOworICAgICAgICAgICAgICAgICAgICBpZiAodmFsdWUgPT0gMHhGRkZFKQorICAgICAgICAgICAgICAgICAgICAgICAgZ290byBVbmRlZmluZWQ7CisgICAgICAgICAgICAgICAgICAgICpwKysgPSB2YWx1ZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgZWxzZSBpZiAodGFyZ2V0c2l6ZSA+IDEpIHsKKyAgICAgICAgICAgICAgICAgICAgLyogMS1uIG1hcHBpbmcgKi8KKyAgICAgICAgICAgICAgICAgICAgaWYgKHRhcmdldHNpemUgPiBleHRyYWNoYXJzKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAvKiByZXNpemUgZmlyc3QgKi8KKyAgICAgICAgICAgICAgICAgICAgICAgIFB5X3NzaXplX3Qgb2xkcG9zID0gcCAtIFB5VW5pY29kZV9BU19VTklDT0RFKHYpOworICAgICAgICAgICAgICAgICAgICAgICAgUHlfc3NpemVfdCBuZWVkZWQgPSAodGFyZ2V0c2l6ZSAtIGV4dHJhY2hhcnMpICsgXAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICh0YXJnZXRzaXplIDw8IDIpOworICAgICAgICAgICAgICAgICAgICAgICAgZXh0cmFjaGFycyArPSBuZWVkZWQ7CisgICAgICAgICAgICAgICAgICAgICAgICAvKiBYWFggb3ZlcmZsb3cgZGV0ZWN0aW9uIG1pc3NpbmcgKi8KKyAgICAgICAgICAgICAgICAgICAgICAgIGlmIChfUHlVbmljb2RlX1Jlc2l6ZSgmdiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQeVVuaWNvZGVfR0VUX1NJWkUodikgKyBuZWVkZWQpIDwgMCkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIFB5X0RFQ1JFRih4KTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBnb3RvIG9uRXJyb3I7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICBwID0gUHlVbmljb2RlX0FTX1VOSUNPREUodikgKyBvbGRwb3M7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgUHlfVU5JQ09ERV9DT1BZKHAsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQeVVuaWNvZGVfQVNfVU5JQ09ERSh4KSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRhcmdldHNpemUpOworICAgICAgICAgICAgICAgICAgICBwICs9IHRhcmdldHNpemU7CisgICAgICAgICAgICAgICAgICAgIGV4dHJhY2hhcnMgLT0gdGFyZ2V0c2l6ZTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgLyogMS0wIG1hcHBpbmc6IHNraXAgdGhlIGNoYXJhY3RlciAqLworICAgICAgICAgICAgfQorICAgICAgICAgICAgZWxzZSB7CisgICAgICAgICAgICAgICAgLyogd3JvbmcgcmV0dXJuIHZhbHVlICovCisgICAgICAgICAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1R5cGVFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImNoYXJhY3RlciBtYXBwaW5nIG11c3QgcmV0dXJuIGludGVnZXIsIE5vbmUgb3IgdW5pY29kZSIpOworICAgICAgICAgICAgICAgIFB5X0RFQ1JFRih4KTsKKyAgICAgICAgICAgICAgICBnb3RvIG9uRXJyb3I7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBQeV9ERUNSRUYoeCk7CisgICAgICAgICAgICArK3M7CisgICAgICAgICAgICBjb250aW51ZTsKK1VuZGVmaW5lZDoKKyAgICAgICAgICAgIC8qIHVuZGVmaW5lZCBtYXBwaW5nICovCisgICAgICAgICAgICBQeV9YREVDUkVGKHgpOworICAgICAgICAgICAgb3V0cG9zID0gcC1QeVVuaWNvZGVfQVNfVU5JQ09ERSh2KTsKKyAgICAgICAgICAgIHN0YXJ0aW5wb3MgPSBzLXN0YXJ0czsKKyAgICAgICAgICAgIGVuZGlucG9zID0gc3RhcnRpbnBvcysxOworICAgICAgICAgICAgaWYgKHVuaWNvZGVfZGVjb2RlX2NhbGxfZXJyb3JoYW5kbGVyKAorICAgICAgICAgICAgICAgICAgICBlcnJvcnMsICZlcnJvckhhbmRsZXIsCisgICAgICAgICAgICAgICAgICAgICJjaGFybWFwIiwgImNoYXJhY3RlciBtYXBzIHRvIDx1bmRlZmluZWQ+IiwKKyAgICAgICAgICAgICAgICAgICAgc3RhcnRzLCBzaXplLCAmc3RhcnRpbnBvcywgJmVuZGlucG9zLCAmZXhjLCAmcywKKyAgICAgICAgICAgICAgICAgICAgJnYsICZvdXRwb3MsICZwKSkgeworICAgICAgICAgICAgICAgIGdvdG8gb25FcnJvcjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKyAgICBpZiAocCAtIFB5VW5pY29kZV9BU19VTklDT0RFKHYpIDwgUHlVbmljb2RlX0dFVF9TSVpFKHYpKQorICAgICAgICBpZiAoX1B5VW5pY29kZV9SZXNpemUoJnYsIHAgLSBQeVVuaWNvZGVfQVNfVU5JQ09ERSh2KSkgPCAwKQorICAgICAgICAgICAgZ290byBvbkVycm9yOworICAgIFB5X1hERUNSRUYoZXJyb3JIYW5kbGVyKTsKKyAgICBQeV9YREVDUkVGKGV4Yyk7CisgICAgcmV0dXJuIChQeU9iamVjdCAqKXY7CisKKyAgb25FcnJvcjoKKyAgICBQeV9YREVDUkVGKGVycm9ySGFuZGxlcik7CisgICAgUHlfWERFQ1JFRihleGMpOworICAgIFB5X1hERUNSRUYodik7CisgICAgcmV0dXJuIE5VTEw7Cit9CisKKy8qIENoYXJtYXAgZW5jb2Rpbmc6IHRoZSBsb29rdXAgdGFibGUgKi8KKworc3RydWN0IGVuY29kaW5nX21hcHsKKyAgICBQeU9iamVjdF9IRUFECisgICAgdW5zaWduZWQgY2hhciBsZXZlbDFbMzJdOworICAgIGludCBjb3VudDIsIGNvdW50MzsKKyAgICB1bnNpZ25lZCBjaGFyIGxldmVsMjNbMV07Cit9OworCitzdGF0aWMgUHlPYmplY3QqCitlbmNvZGluZ19tYXBfc2l6ZShQeU9iamVjdCAqb2JqLCBQeU9iamVjdCogYXJncykKK3sKKyAgICBzdHJ1Y3QgZW5jb2RpbmdfbWFwICptYXAgPSAoc3RydWN0IGVuY29kaW5nX21hcCopb2JqOworICAgIHJldHVybiBQeUludF9Gcm9tTG9uZyhzaXplb2YoKm1hcCkgLSAxICsgMTYqbWFwLT5jb3VudDIgKworICAgICAgICAgICAgICAgICAgICAgICAgICAxMjgqbWFwLT5jb3VudDMpOworfQorCitzdGF0aWMgUHlNZXRob2REZWYgZW5jb2RpbmdfbWFwX21ldGhvZHNbXSA9IHsKKyAgICB7InNpemUiLCBlbmNvZGluZ19tYXBfc2l6ZSwgTUVUSF9OT0FSR1MsCisgICAgIFB5RG9jX1NUUigiUmV0dXJuIHRoZSBzaXplIChpbiBieXRlcykgb2YgdGhpcyBvYmplY3QiKSB9LAorICAgIHsgMCB9Cit9OworCitzdGF0aWMgdm9pZAorZW5jb2RpbmdfbWFwX2RlYWxsb2MoUHlPYmplY3QqIG8pCit7CisgICAgUHlPYmplY3RfRlJFRShvKTsKK30KKworc3RhdGljIFB5VHlwZU9iamVjdCBFbmNvZGluZ01hcFR5cGUgPSB7CisgICAgUHlWYXJPYmplY3RfSEVBRF9JTklUKE5VTEwsIDApCisgICAgIkVuY29kaW5nTWFwIiwgICAgICAgICAgLyp0cF9uYW1lKi8KKyAgICBzaXplb2Yoc3RydWN0IGVuY29kaW5nX21hcCksICAgLyp0cF9iYXNpY3NpemUqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgIC8qdHBfaXRlbXNpemUqLworICAgIC8qIG1ldGhvZHMgKi8KKyAgICBlbmNvZGluZ19tYXBfZGVhbGxvYywgICAvKnRwX2RlYWxsb2MqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgIC8qdHBfcHJpbnQqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgIC8qdHBfZ2V0YXR0ciovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgLyp0cF9zZXRhdHRyKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAvKnRwX2NvbXBhcmUqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgIC8qdHBfcmVwciovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgLyp0cF9hc19udW1iZXIqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgIC8qdHBfYXNfc2VxdWVuY2UqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgIC8qdHBfYXNfbWFwcGluZyovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgLyp0cF9oYXNoKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAvKnRwX2NhbGwqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgIC8qdHBfc3RyKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAvKnRwX2dldGF0dHJvKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAvKnRwX3NldGF0dHJvKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAvKnRwX2FzX2J1ZmZlciovCisgICAgUHlfVFBGTEFHU19ERUZBVUxULCAgICAgLyp0cF9mbGFncyovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgLyp0cF9kb2MqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgIC8qdHBfdHJhdmVyc2UqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgIC8qdHBfY2xlYXIqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgIC8qdHBfcmljaGNvbXBhcmUqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgIC8qdHBfd2Vha2xpc3RvZmZzZXQqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgIC8qdHBfaXRlciovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgLyp0cF9pdGVybmV4dCovCisgICAgZW5jb2RpbmdfbWFwX21ldGhvZHMsICAgLyp0cF9tZXRob2RzKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAvKnRwX21lbWJlcnMqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgIC8qdHBfZ2V0c2V0Ki8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAvKnRwX2Jhc2UqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgIC8qdHBfZGljdCovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgLyp0cF9kZXNjcl9nZXQqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgIC8qdHBfZGVzY3Jfc2V0Ki8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAvKnRwX2RpY3RvZmZzZXQqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgIC8qdHBfaW5pdCovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgLyp0cF9hbGxvYyovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgLyp0cF9uZXcqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgIC8qdHBfZnJlZSovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgLyp0cF9pc19nYyovCit9OworCitQeU9iamVjdCoKK1B5VW5pY29kZV9CdWlsZEVuY29kaW5nTWFwKFB5T2JqZWN0KiBzdHJpbmcpCit7CisgICAgUHlfVU5JQ09ERSAqZGVjb2RlOworICAgIFB5T2JqZWN0ICpyZXN1bHQ7CisgICAgc3RydWN0IGVuY29kaW5nX21hcCAqbXJlc3VsdDsKKyAgICBpbnQgaTsKKyAgICBpbnQgbmVlZF9kaWN0ID0gMDsKKyAgICB1bnNpZ25lZCBjaGFyIGxldmVsMVszMl07CisgICAgdW5zaWduZWQgY2hhciBsZXZlbDJbNTEyXTsKKyAgICB1bnNpZ25lZCBjaGFyICptbGV2ZWwxLCAqbWxldmVsMiwgKm1sZXZlbDM7CisgICAgaW50IGNvdW50MiA9IDAsIGNvdW50MyA9IDA7CisKKyAgICBpZiAoIVB5VW5pY29kZV9DaGVjayhzdHJpbmcpIHx8IFB5VW5pY29kZV9HZXRTaXplKHN0cmluZykgIT0gMjU2KSB7CisgICAgICAgIFB5RXJyX0JhZEFyZ3VtZW50KCk7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICBkZWNvZGUgPSBQeVVuaWNvZGVfQVNfVU5JQ09ERShzdHJpbmcpOworICAgIG1lbXNldChsZXZlbDEsIDB4RkYsIHNpemVvZiBsZXZlbDEpOworICAgIG1lbXNldChsZXZlbDIsIDB4RkYsIHNpemVvZiBsZXZlbDIpOworCisgICAgLyogSWYgdGhlcmUgaXNuJ3QgYSBvbmUtdG8tb25lIG1hcHBpbmcgb2YgTlVMTCB0byBcMCwKKyAgICAgICBvciBpZiB0aGVyZSBhcmUgbm9uLUJNUCBjaGFyYWN0ZXJzLCB3ZSBuZWVkIHRvIHVzZQorICAgICAgIGEgbWFwcGluZyBkaWN0aW9uYXJ5LiAqLworICAgIGlmIChkZWNvZGVbMF0gIT0gMCkKKyAgICAgICAgbmVlZF9kaWN0ID0gMTsKKyAgICBmb3IgKGkgPSAxOyBpIDwgMjU2OyBpKyspIHsKKyAgICAgICAgaW50IGwxLCBsMjsKKyAgICAgICAgaWYgKGRlY29kZVtpXSA9PSAwCisjaWZkZWYgUHlfVU5JQ09ERV9XSURFCisgICAgICAgICAgICB8fCBkZWNvZGVbaV0gPiAweEZGRkYKKyNlbmRpZgorICAgICAgICAgICAgKSB7CisgICAgICAgICAgICBuZWVkX2RpY3QgPSAxOworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIH0KKyAgICAgICAgaWYgKGRlY29kZVtpXSA9PSAweEZGRkUpCisgICAgICAgICAgICAvKiB1bm1hcHBlZCBjaGFyYWN0ZXIgKi8KKyAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICBsMSA9IGRlY29kZVtpXSA+PiAxMTsKKyAgICAgICAgbDIgPSBkZWNvZGVbaV0gPj4gNzsKKyAgICAgICAgaWYgKGxldmVsMVtsMV0gPT0gMHhGRikKKyAgICAgICAgICAgIGxldmVsMVtsMV0gPSBjb3VudDIrKzsKKyAgICAgICAgaWYgKGxldmVsMltsMl0gPT0gMHhGRikKKyAgICAgICAgICAgIGxldmVsMltsMl0gPSBjb3VudDMrKzsKKyAgICB9CisKKyAgICBpZiAoY291bnQyID49IDB4RkYgfHwgY291bnQzID49IDB4RkYpCisgICAgICAgIG5lZWRfZGljdCA9IDE7CisKKyAgICBpZiAobmVlZF9kaWN0KSB7CisgICAgICAgIFB5T2JqZWN0ICpyZXN1bHQgPSBQeURpY3RfTmV3KCk7CisgICAgICAgIFB5T2JqZWN0ICprZXksICp2YWx1ZTsKKyAgICAgICAgaWYgKCFyZXN1bHQpCisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgZm9yIChpID0gMDsgaSA8IDI1NjsgaSsrKSB7CisgICAgICAgICAgICB2YWx1ZSA9IE5VTEw7CisgICAgICAgICAgICBrZXkgPSBQeUludF9Gcm9tTG9uZyhkZWNvZGVbaV0pOworICAgICAgICAgICAgdmFsdWUgPSBQeUludF9Gcm9tTG9uZyhpKTsKKyAgICAgICAgICAgIGlmICgha2V5IHx8ICF2YWx1ZSkKKyAgICAgICAgICAgICAgICBnb3RvIGZhaWxlZDE7CisgICAgICAgICAgICBpZiAoUHlEaWN0X1NldEl0ZW0ocmVzdWx0LCBrZXksIHZhbHVlKSA9PSAtMSkKKyAgICAgICAgICAgICAgICBnb3RvIGZhaWxlZDE7CisgICAgICAgICAgICBQeV9ERUNSRUYoa2V5KTsKKyAgICAgICAgICAgIFB5X0RFQ1JFRih2YWx1ZSk7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHJlc3VsdDsKKyAgICAgIGZhaWxlZDE6CisgICAgICAgIFB5X1hERUNSRUYoa2V5KTsKKyAgICAgICAgUHlfWERFQ1JFRih2YWx1ZSk7CisgICAgICAgIFB5X0RFQ1JFRihyZXN1bHQpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisKKyAgICAvKiBDcmVhdGUgYSB0aHJlZS1sZXZlbCB0cmllICovCisgICAgcmVzdWx0ID0gUHlPYmplY3RfTUFMTE9DKHNpemVvZihzdHJ1Y3QgZW5jb2RpbmdfbWFwKSArCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDE2KmNvdW50MiArIDEyOCpjb3VudDMgLSAxKTsKKyAgICBpZiAoIXJlc3VsdCkKKyAgICAgICAgcmV0dXJuIFB5RXJyX05vTWVtb3J5KCk7CisgICAgUHlPYmplY3RfSW5pdChyZXN1bHQsICZFbmNvZGluZ01hcFR5cGUpOworICAgIG1yZXN1bHQgPSAoc3RydWN0IGVuY29kaW5nX21hcCopcmVzdWx0OworICAgIG1yZXN1bHQtPmNvdW50MiA9IGNvdW50MjsKKyAgICBtcmVzdWx0LT5jb3VudDMgPSBjb3VudDM7CisgICAgbWxldmVsMSA9IG1yZXN1bHQtPmxldmVsMTsKKyAgICBtbGV2ZWwyID0gbXJlc3VsdC0+bGV2ZWwyMzsKKyAgICBtbGV2ZWwzID0gbXJlc3VsdC0+bGV2ZWwyMyArIDE2KmNvdW50MjsKKyAgICBtZW1jcHkobWxldmVsMSwgbGV2ZWwxLCAzMik7CisgICAgbWVtc2V0KG1sZXZlbDIsIDB4RkYsIDE2KmNvdW50Mik7CisgICAgbWVtc2V0KG1sZXZlbDMsIDAsIDEyOCpjb3VudDMpOworICAgIGNvdW50MyA9IDA7CisgICAgZm9yIChpID0gMTsgaSA8IDI1NjsgaSsrKSB7CisgICAgICAgIGludCBvMSwgbzIsIG8zLCBpMiwgaTM7CisgICAgICAgIGlmIChkZWNvZGVbaV0gPT0gMHhGRkZFKQorICAgICAgICAgICAgLyogdW5tYXBwZWQgY2hhcmFjdGVyICovCisgICAgICAgICAgICBjb250aW51ZTsKKyAgICAgICAgbzEgPSBkZWNvZGVbaV0+PjExOworICAgICAgICBvMiA9IChkZWNvZGVbaV0+PjcpICYgMHhGOworICAgICAgICBpMiA9IDE2Km1sZXZlbDFbbzFdICsgbzI7CisgICAgICAgIGlmIChtbGV2ZWwyW2kyXSA9PSAweEZGKQorICAgICAgICAgICAgbWxldmVsMltpMl0gPSBjb3VudDMrKzsKKyAgICAgICAgbzMgPSBkZWNvZGVbaV0gJiAweDdGOworICAgICAgICBpMyA9IDEyOCptbGV2ZWwyW2kyXSArIG8zOworICAgICAgICBtbGV2ZWwzW2kzXSA9IGk7CisgICAgfQorICAgIHJldHVybiByZXN1bHQ7Cit9CisKK3N0YXRpYyBpbnQKK2VuY29kaW5nX21hcF9sb29rdXAoUHlfVU5JQ09ERSBjLCBQeU9iamVjdCAqbWFwcGluZykKK3sKKyAgICBzdHJ1Y3QgZW5jb2RpbmdfbWFwICptYXAgPSAoc3RydWN0IGVuY29kaW5nX21hcCopbWFwcGluZzsKKyAgICBpbnQgbDEgPSBjPj4xMTsKKyAgICBpbnQgbDIgPSAoYz4+NykgJiAweEY7CisgICAgaW50IGwzID0gYyAmIDB4N0Y7CisgICAgaW50IGk7CisKKyNpZmRlZiBQeV9VTklDT0RFX1dJREUKKyAgICBpZiAoYyA+IDB4RkZGRikgeworICAgICAgICByZXR1cm4gLTE7CisgICAgfQorI2VuZGlmCisgICAgaWYgKGMgPT0gMCkKKyAgICAgICAgcmV0dXJuIDA7CisgICAgLyogbGV2ZWwgMSovCisgICAgaSA9IG1hcC0+bGV2ZWwxW2wxXTsKKyAgICBpZiAoaSA9PSAweEZGKSB7CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisgICAgLyogbGV2ZWwgMiovCisgICAgaSA9IG1hcC0+bGV2ZWwyM1sxNippK2wyXTsKKyAgICBpZiAoaSA9PSAweEZGKSB7CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisgICAgLyogbGV2ZWwgMyAqLworICAgIGkgPSBtYXAtPmxldmVsMjNbMTYqbWFwLT5jb3VudDIgKyAxMjgqaSArIGwzXTsKKyAgICBpZiAoaSA9PSAwKSB7CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisgICAgcmV0dXJuIGk7Cit9CisKKy8qIExvb2t1cCB0aGUgY2hhcmFjdGVyIGNoIGluIHRoZSBtYXBwaW5nLiBJZiB0aGUgY2hhcmFjdGVyCisgICBjYW4ndCBiZSBmb3VuZCwgUHlfTm9uZSBpcyByZXR1cm5lZCAob3IgTlVMTCwgaWYgYW5vdGhlcgorICAgZXJyb3Igb2NjdXJyZWQpLiAqLworc3RhdGljIFB5T2JqZWN0ICpjaGFybWFwZW5jb2RlX2xvb2t1cChQeV9VTklDT0RFIGMsIFB5T2JqZWN0ICptYXBwaW5nKQoreworICAgIFB5T2JqZWN0ICp3ID0gUHlJbnRfRnJvbUxvbmcoKGxvbmcpYyk7CisgICAgUHlPYmplY3QgKng7CisKKyAgICBpZiAodyA9PSBOVUxMKQorICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB4ID0gUHlPYmplY3RfR2V0SXRlbShtYXBwaW5nLCB3KTsKKyAgICBQeV9ERUNSRUYodyk7CisgICAgaWYgKHggPT0gTlVMTCkgeworICAgICAgICBpZiAoUHlFcnJfRXhjZXB0aW9uTWF0Y2hlcyhQeUV4Y19Mb29rdXBFcnJvcikpIHsKKyAgICAgICAgICAgIC8qIE5vIG1hcHBpbmcgZm91bmQgbWVhbnM6IG1hcHBpbmcgaXMgdW5kZWZpbmVkLiAqLworICAgICAgICAgICAgUHlFcnJfQ2xlYXIoKTsKKyAgICAgICAgICAgIHggPSBQeV9Ob25lOworICAgICAgICAgICAgUHlfSU5DUkVGKHgpOworICAgICAgICAgICAgcmV0dXJuIHg7CisgICAgICAgIH0gZWxzZQorICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIGVsc2UgaWYgKHggPT0gUHlfTm9uZSkKKyAgICAgICAgcmV0dXJuIHg7CisgICAgZWxzZSBpZiAoUHlJbnRfQ2hlY2soeCkpIHsKKyAgICAgICAgbG9uZyB2YWx1ZSA9IFB5SW50X0FTX0xPTkcoeCk7CisgICAgICAgIGlmICh2YWx1ZSA8IDAgfHwgdmFsdWUgPiAyNTUpIHsKKyAgICAgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19UeXBlRXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgImNoYXJhY3RlciBtYXBwaW5nIG11c3QgYmUgaW4gcmFuZ2UoMjU2KSIpOworICAgICAgICAgICAgUHlfREVDUkVGKHgpOworICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgICAgIH0KKyAgICAgICAgcmV0dXJuIHg7CisgICAgfQorICAgIGVsc2UgaWYgKFB5U3RyaW5nX0NoZWNrKHgpKQorICAgICAgICByZXR1cm4geDsKKyAgICBlbHNlIHsKKyAgICAgICAgLyogd3JvbmcgcmV0dXJuIHZhbHVlICovCisgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19UeXBlRXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAgICAiY2hhcmFjdGVyIG1hcHBpbmcgbXVzdCByZXR1cm4gaW50ZWdlciwgTm9uZSBvciBzdHIiKTsKKyAgICAgICAgUHlfREVDUkVGKHgpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9Cit9CisKK3N0YXRpYyBpbnQKK2NoYXJtYXBlbmNvZGVfcmVzaXplKFB5T2JqZWN0ICoqb3V0b2JqLCBQeV9zc2l6ZV90ICpvdXRwb3MsIFB5X3NzaXplX3QgcmVxdWlyZWRzaXplKQoreworICAgIFB5X3NzaXplX3Qgb3V0c2l6ZSA9IFB5U3RyaW5nX0dFVF9TSVpFKCpvdXRvYmopOworICAgIC8qIGV4cG9uZW50aWFsbHkgb3ZlcmFsbG9jYXRlIHRvIG1pbmltaXplIHJlYWxsb2NhdGlvbnMgKi8KKyAgICBpZiAocmVxdWlyZWRzaXplIDwgMipvdXRzaXplKQorICAgICAgICByZXF1aXJlZHNpemUgPSAyKm91dHNpemU7CisgICAgaWYgKF9QeVN0cmluZ19SZXNpemUob3V0b2JqLCByZXF1aXJlZHNpemUpKSB7CisgICAgICAgIHJldHVybiAwOworICAgIH0KKyAgICByZXR1cm4gMTsKK30KKwordHlwZWRlZiBlbnVtIGNoYXJtYXBlbmNvZGVfcmVzdWx0IHsKKyAgICBlbmNfU1VDQ0VTUywgZW5jX0ZBSUxFRCwgZW5jX0VYQ0VQVElPTgorfWNoYXJtYXBlbmNvZGVfcmVzdWx0OworLyogbG9va3VwIHRoZSBjaGFyYWN0ZXIsIHB1dCB0aGUgcmVzdWx0IGluIHRoZSBvdXRwdXQgc3RyaW5nIGFuZCBhZGp1c3QKKyAgIHZhcmlvdXMgc3RhdGUgdmFyaWFibGVzLiBSZWFsbG9jYXRlIHRoZSBvdXRwdXQgc3RyaW5nIGlmIG5vdCBlbm91Z2gKKyAgIHNwYWNlIGlzIGF2YWlsYWJsZS4gUmV0dXJuIGEgbmV3IHJlZmVyZW5jZSB0byB0aGUgb2JqZWN0IHRoYXQKKyAgIHdhcyBwdXQgaW4gdGhlIG91dHB1dCBidWZmZXIsIG9yIFB5X05vbmUsIGlmIHRoZSBtYXBwaW5nIHdhcyB1bmRlZmluZWQKKyAgIChpbiB3aGljaCBjYXNlIG5vIGNoYXJhY3RlciB3YXMgd3JpdHRlbikgb3IgTlVMTCwgaWYgYQorICAgcmVhbGxvY2F0aW9uIGVycm9yIG9jY3VycmVkLiBUaGUgY2FsbGVyIG11c3QgZGVjcmVmIHRoZSByZXN1bHQgKi8KK3N0YXRpYworY2hhcm1hcGVuY29kZV9yZXN1bHQgY2hhcm1hcGVuY29kZV9vdXRwdXQoUHlfVU5JQ09ERSBjLCBQeU9iamVjdCAqbWFwcGluZywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFB5T2JqZWN0ICoqb3V0b2JqLCBQeV9zc2l6ZV90ICpvdXRwb3MpCit7CisgICAgUHlPYmplY3QgKnJlcDsKKyAgICBjaGFyICpvdXRzdGFydDsKKyAgICBQeV9zc2l6ZV90IG91dHNpemUgPSBQeVN0cmluZ19HRVRfU0laRSgqb3V0b2JqKTsKKworICAgIGlmIChQeV9UWVBFKG1hcHBpbmcpID09ICZFbmNvZGluZ01hcFR5cGUpIHsKKyAgICAgICAgaW50IHJlcyA9IGVuY29kaW5nX21hcF9sb29rdXAoYywgbWFwcGluZyk7CisgICAgICAgIFB5X3NzaXplX3QgcmVxdWlyZWRzaXplID0gKm91dHBvcysxOworICAgICAgICBpZiAocmVzID09IC0xKQorICAgICAgICAgICAgcmV0dXJuIGVuY19GQUlMRUQ7CisgICAgICAgIGlmIChvdXRzaXplPHJlcXVpcmVkc2l6ZSkKKyAgICAgICAgICAgIGlmICghY2hhcm1hcGVuY29kZV9yZXNpemUob3V0b2JqLCBvdXRwb3MsIHJlcXVpcmVkc2l6ZSkpCisgICAgICAgICAgICAgICAgcmV0dXJuIGVuY19FWENFUFRJT047CisgICAgICAgIG91dHN0YXJ0ID0gUHlTdHJpbmdfQVNfU1RSSU5HKCpvdXRvYmopOworICAgICAgICBvdXRzdGFydFsoKm91dHBvcykrK10gPSAoY2hhcilyZXM7CisgICAgICAgIHJldHVybiBlbmNfU1VDQ0VTUzsKKyAgICB9CisKKyAgICByZXAgPSBjaGFybWFwZW5jb2RlX2xvb2t1cChjLCBtYXBwaW5nKTsKKyAgICBpZiAocmVwPT1OVUxMKQorICAgICAgICByZXR1cm4gZW5jX0VYQ0VQVElPTjsKKyAgICBlbHNlIGlmIChyZXA9PVB5X05vbmUpIHsKKyAgICAgICAgUHlfREVDUkVGKHJlcCk7CisgICAgICAgIHJldHVybiBlbmNfRkFJTEVEOworICAgIH0gZWxzZSB7CisgICAgICAgIGlmIChQeUludF9DaGVjayhyZXApKSB7CisgICAgICAgICAgICBQeV9zc2l6ZV90IHJlcXVpcmVkc2l6ZSA9ICpvdXRwb3MrMTsKKyAgICAgICAgICAgIGlmIChvdXRzaXplPHJlcXVpcmVkc2l6ZSkKKyAgICAgICAgICAgICAgICBpZiAoIWNoYXJtYXBlbmNvZGVfcmVzaXplKG91dG9iaiwgb3V0cG9zLCByZXF1aXJlZHNpemUpKSB7CisgICAgICAgICAgICAgICAgICAgIFB5X0RFQ1JFRihyZXApOworICAgICAgICAgICAgICAgICAgICByZXR1cm4gZW5jX0VYQ0VQVElPTjsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICBvdXRzdGFydCA9IFB5U3RyaW5nX0FTX1NUUklORygqb3V0b2JqKTsKKyAgICAgICAgICAgIG91dHN0YXJ0Wygqb3V0cG9zKSsrXSA9IChjaGFyKVB5SW50X0FTX0xPTkcocmVwKTsKKyAgICAgICAgfQorICAgICAgICBlbHNlIHsKKyAgICAgICAgICAgIGNvbnN0IGNoYXIgKnJlcGNoYXJzID0gUHlTdHJpbmdfQVNfU1RSSU5HKHJlcCk7CisgICAgICAgICAgICBQeV9zc2l6ZV90IHJlcHNpemUgPSBQeVN0cmluZ19HRVRfU0laRShyZXApOworICAgICAgICAgICAgUHlfc3NpemVfdCByZXF1aXJlZHNpemUgPSAqb3V0cG9zK3JlcHNpemU7CisgICAgICAgICAgICBpZiAob3V0c2l6ZTxyZXF1aXJlZHNpemUpCisgICAgICAgICAgICAgICAgaWYgKCFjaGFybWFwZW5jb2RlX3Jlc2l6ZShvdXRvYmosIG91dHBvcywgcmVxdWlyZWRzaXplKSkgeworICAgICAgICAgICAgICAgICAgICBQeV9ERUNSRUYocmVwKTsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGVuY19FWENFUFRJT047CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgb3V0c3RhcnQgPSBQeVN0cmluZ19BU19TVFJJTkcoKm91dG9iaik7CisgICAgICAgICAgICBtZW1jcHkob3V0c3RhcnQgKyAqb3V0cG9zLCByZXBjaGFycywgcmVwc2l6ZSk7CisgICAgICAgICAgICAqb3V0cG9zICs9IHJlcHNpemU7CisgICAgICAgIH0KKyAgICB9CisgICAgUHlfREVDUkVGKHJlcCk7CisgICAgcmV0dXJuIGVuY19TVUNDRVNTOworfQorCisvKiBoYW5kbGUgYW4gZXJyb3IgaW4gUHlVbmljb2RlX0VuY29kZUNoYXJtYXAKKyAgIFJldHVybiAwIG9uIHN1Y2Nlc3MsIC0xIG9uIGVycm9yICovCitzdGF0aWMKK2ludCBjaGFybWFwX2VuY29kaW5nX2Vycm9yKAorICAgIGNvbnN0IFB5X1VOSUNPREUgKnAsIFB5X3NzaXplX3Qgc2l6ZSwgUHlfc3NpemVfdCAqaW5wb3MsIFB5T2JqZWN0ICptYXBwaW5nLAorICAgIFB5T2JqZWN0ICoqZXhjZXB0aW9uT2JqZWN0LAorICAgIGludCAqa25vd25fZXJyb3JIYW5kbGVyLCBQeU9iamVjdCAqKmVycm9ySGFuZGxlciwgY29uc3QgY2hhciAqZXJyb3JzLAorICAgIFB5T2JqZWN0ICoqcmVzLCBQeV9zc2l6ZV90ICpyZXNwb3MpCit7CisgICAgUHlPYmplY3QgKnJlcHVuaWNvZGUgPSBOVUxMOyAvKiBpbml0aWFsaXplIHRvIHByZXZlbnQgZ2NjIHdhcm5pbmcgKi8KKyAgICBQeV9zc2l6ZV90IHJlcHNpemU7CisgICAgUHlfc3NpemVfdCBuZXdwb3M7CisgICAgUHlfVU5JQ09ERSAqdW5pMjsKKyAgICAvKiBzdGFydHBvcyBmb3IgY29sbGVjdGluZyB1bmVuY29kYWJsZSBjaGFycyAqLworICAgIFB5X3NzaXplX3QgY29sbHN0YXJ0cG9zID0gKmlucG9zOworICAgIFB5X3NzaXplX3QgY29sbGVuZHBvcyA9ICppbnBvcysxOworICAgIFB5X3NzaXplX3QgY29sbHBvczsKKyAgICBjaGFyICplbmNvZGluZyA9ICJjaGFybWFwIjsKKyAgICBjaGFyICpyZWFzb24gPSAiY2hhcmFjdGVyIG1hcHMgdG8gPHVuZGVmaW5lZD4iOworICAgIGNoYXJtYXBlbmNvZGVfcmVzdWx0IHg7CisKKyAgICAvKiBmaW5kIGFsbCB1bmVuY29kYWJsZSBjaGFyYWN0ZXJzICovCisgICAgd2hpbGUgKGNvbGxlbmRwb3MgPCBzaXplKSB7CisgICAgICAgIFB5T2JqZWN0ICpyZXA7CisgICAgICAgIGlmIChQeV9UWVBFKG1hcHBpbmcpID09ICZFbmNvZGluZ01hcFR5cGUpIHsKKyAgICAgICAgICAgIGludCByZXMgPSBlbmNvZGluZ19tYXBfbG9va3VwKHBbY29sbGVuZHBvc10sIG1hcHBpbmcpOworICAgICAgICAgICAgaWYgKHJlcyAhPSAtMSkKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICsrY29sbGVuZHBvczsKKyAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICB9CisKKyAgICAgICAgcmVwID0gY2hhcm1hcGVuY29kZV9sb29rdXAocFtjb2xsZW5kcG9zXSwgbWFwcGluZyk7CisgICAgICAgIGlmIChyZXA9PU5VTEwpCisgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgIGVsc2UgaWYgKHJlcCE9UHlfTm9uZSkgeworICAgICAgICAgICAgUHlfREVDUkVGKHJlcCk7CisgICAgICAgICAgICBicmVhazsKKyAgICAgICAgfQorICAgICAgICBQeV9ERUNSRUYocmVwKTsKKyAgICAgICAgKytjb2xsZW5kcG9zOworICAgIH0KKyAgICAvKiBjYWNoZSBjYWxsYmFjayBuYW1lIGxvb2t1cAorICAgICAqIChpZiBub3QgZG9uZSB5ZXQsIGkuZS4gaXQncyB0aGUgZmlyc3QgZXJyb3IpICovCisgICAgaWYgKCprbm93bl9lcnJvckhhbmRsZXI9PS0xKSB7CisgICAgICAgIGlmICgoZXJyb3JzPT1OVUxMKSB8fCAoIXN0cmNtcChlcnJvcnMsICJzdHJpY3QiKSkpCisgICAgICAgICAgICAqa25vd25fZXJyb3JIYW5kbGVyID0gMTsKKyAgICAgICAgZWxzZSBpZiAoIXN0cmNtcChlcnJvcnMsICJyZXBsYWNlIikpCisgICAgICAgICAgICAqa25vd25fZXJyb3JIYW5kbGVyID0gMjsKKyAgICAgICAgZWxzZSBpZiAoIXN0cmNtcChlcnJvcnMsICJpZ25vcmUiKSkKKyAgICAgICAgICAgICprbm93bl9lcnJvckhhbmRsZXIgPSAzOworICAgICAgICBlbHNlIGlmICghc3RyY21wKGVycm9ycywgInhtbGNoYXJyZWZyZXBsYWNlIikpCisgICAgICAgICAgICAqa25vd25fZXJyb3JIYW5kbGVyID0gNDsKKyAgICAgICAgZWxzZQorICAgICAgICAgICAgKmtub3duX2Vycm9ySGFuZGxlciA9IDA7CisgICAgfQorICAgIHN3aXRjaCAoKmtub3duX2Vycm9ySGFuZGxlcikgeworICAgIGNhc2UgMTogLyogc3RyaWN0ICovCisgICAgICAgIHJhaXNlX2VuY29kZV9leGNlcHRpb24oZXhjZXB0aW9uT2JqZWN0LCBlbmNvZGluZywgcCwgc2l6ZSwgY29sbHN0YXJ0cG9zLCBjb2xsZW5kcG9zLCByZWFzb24pOworICAgICAgICByZXR1cm4gLTE7CisgICAgY2FzZSAyOiAvKiByZXBsYWNlICovCisgICAgICAgIGZvciAoY29sbHBvcyA9IGNvbGxzdGFydHBvczsgY29sbHBvczxjb2xsZW5kcG9zOyArK2NvbGxwb3MpIHsKKyAgICAgICAgICAgIHggPSBjaGFybWFwZW5jb2RlX291dHB1dCgnPycsIG1hcHBpbmcsIHJlcywgcmVzcG9zKTsKKyAgICAgICAgICAgIGlmICh4PT1lbmNfRVhDRVBUSU9OKSB7CisgICAgICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICAgICAgfQorICAgICAgICAgICAgZWxzZSBpZiAoeD09ZW5jX0ZBSUxFRCkgeworICAgICAgICAgICAgICAgIHJhaXNlX2VuY29kZV9leGNlcHRpb24oZXhjZXB0aW9uT2JqZWN0LCBlbmNvZGluZywgcCwgc2l6ZSwgY29sbHN0YXJ0cG9zLCBjb2xsZW5kcG9zLCByZWFzb24pOworICAgICAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICAvKiBmYWxsIHRocm91Z2ggKi8KKyAgICBjYXNlIDM6IC8qIGlnbm9yZSAqLworICAgICAgICAqaW5wb3MgPSBjb2xsZW5kcG9zOworICAgICAgICBicmVhazsKKyAgICBjYXNlIDQ6IC8qIHhtbGNoYXJyZWZyZXBsYWNlICovCisgICAgICAgIC8qIGdlbmVyYXRlIHJlcGxhY2VtZW50ICh0ZW1wb3JhcmlseSAobWlzKXVzZXMgcCkgKi8KKyAgICAgICAgZm9yIChjb2xscG9zID0gY29sbHN0YXJ0cG9zOyBjb2xscG9zIDwgY29sbGVuZHBvczsgKytjb2xscG9zKSB7CisgICAgICAgICAgICBjaGFyIGJ1ZmZlclsyKzI5KzErMV07CisgICAgICAgICAgICBjaGFyICpjcDsKKyAgICAgICAgICAgIHNwcmludGYoYnVmZmVyLCAiJiMlZDsiLCAoaW50KXBbY29sbHBvc10pOworICAgICAgICAgICAgZm9yIChjcCA9IGJ1ZmZlcjsgKmNwOyArK2NwKSB7CisgICAgICAgICAgICAgICAgeCA9IGNoYXJtYXBlbmNvZGVfb3V0cHV0KCpjcCwgbWFwcGluZywgcmVzLCByZXNwb3MpOworICAgICAgICAgICAgICAgIGlmICh4PT1lbmNfRVhDRVBUSU9OKQorICAgICAgICAgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgICAgICAgICAgZWxzZSBpZiAoeD09ZW5jX0ZBSUxFRCkgeworICAgICAgICAgICAgICAgICAgICByYWlzZV9lbmNvZGVfZXhjZXB0aW9uKGV4Y2VwdGlvbk9iamVjdCwgZW5jb2RpbmcsIHAsIHNpemUsIGNvbGxzdGFydHBvcywgY29sbGVuZHBvcywgcmVhc29uKTsKKyAgICAgICAgICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICAqaW5wb3MgPSBjb2xsZW5kcG9zOworICAgICAgICBicmVhazsKKyAgICBkZWZhdWx0OgorICAgICAgICByZXB1bmljb2RlID0gdW5pY29kZV9lbmNvZGVfY2FsbF9lcnJvcmhhbmRsZXIoZXJyb3JzLCBlcnJvckhhbmRsZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbmNvZGluZywgcmVhc29uLCBwLCBzaXplLCBleGNlcHRpb25PYmplY3QsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xsc3RhcnRwb3MsIGNvbGxlbmRwb3MsICZuZXdwb3MpOworICAgICAgICBpZiAocmVwdW5pY29kZSA9PSBOVUxMKQorICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICAvKiBnZW5lcmF0ZSByZXBsYWNlbWVudCAgKi8KKyAgICAgICAgcmVwc2l6ZSA9IFB5VW5pY29kZV9HRVRfU0laRShyZXB1bmljb2RlKTsKKyAgICAgICAgZm9yICh1bmkyID0gUHlVbmljb2RlX0FTX1VOSUNPREUocmVwdW5pY29kZSk7IHJlcHNpemUtLT4wOyArK3VuaTIpIHsKKyAgICAgICAgICAgIHggPSBjaGFybWFwZW5jb2RlX291dHB1dCgqdW5pMiwgbWFwcGluZywgcmVzLCByZXNwb3MpOworICAgICAgICAgICAgaWYgKHg9PWVuY19FWENFUFRJT04pIHsKKyAgICAgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBlbHNlIGlmICh4PT1lbmNfRkFJTEVEKSB7CisgICAgICAgICAgICAgICAgUHlfREVDUkVGKHJlcHVuaWNvZGUpOworICAgICAgICAgICAgICAgIHJhaXNlX2VuY29kZV9leGNlcHRpb24oZXhjZXB0aW9uT2JqZWN0LCBlbmNvZGluZywgcCwgc2l6ZSwgY29sbHN0YXJ0cG9zLCBjb2xsZW5kcG9zLCByZWFzb24pOworICAgICAgICAgICAgICAgIHJldHVybiAtMTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICAqaW5wb3MgPSBuZXdwb3M7CisgICAgICAgIFB5X0RFQ1JFRihyZXB1bmljb2RlKTsKKyAgICB9CisgICAgcmV0dXJuIDA7Cit9CisKK1B5T2JqZWN0ICpQeVVuaWNvZGVfRW5jb2RlQ2hhcm1hcChjb25zdCBQeV9VTklDT0RFICpwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFB5X3NzaXplX3Qgc2l6ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQeU9iamVjdCAqbWFwcGluZywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyICplcnJvcnMpCit7CisgICAgLyogb3V0cHV0IG9iamVjdCAqLworICAgIFB5T2JqZWN0ICpyZXMgPSBOVUxMOworICAgIC8qIGN1cnJlbnQgaW5wdXQgcG9zaXRpb24gKi8KKyAgICBQeV9zc2l6ZV90IGlucG9zID0gMDsKKyAgICAvKiBjdXJyZW50IG91dHB1dCBwb3NpdGlvbiAqLworICAgIFB5X3NzaXplX3QgcmVzcG9zID0gMDsKKyAgICBQeU9iamVjdCAqZXJyb3JIYW5kbGVyID0gTlVMTDsKKyAgICBQeU9iamVjdCAqZXhjID0gTlVMTDsKKyAgICAvKiB0aGUgZm9sbG93aW5nIHZhcmlhYmxlIGlzIHVzZWQgZm9yIGNhY2hpbmcgc3RyaW5nIGNvbXBhcmlzb25zCisgICAgICogLTE9bm90IGluaXRpYWxpemVkLCAwPXVua25vd24sIDE9c3RyaWN0LCAyPXJlcGxhY2UsCisgICAgICogMz1pZ25vcmUsIDQ9eG1sY2hhcnJlZnJlcGxhY2UgKi8KKyAgICBpbnQga25vd25fZXJyb3JIYW5kbGVyID0gLTE7CisKKyAgICAvKiBEZWZhdWx0IHRvIExhdGluLTEgKi8KKyAgICBpZiAobWFwcGluZyA9PSBOVUxMKQorICAgICAgICByZXR1cm4gUHlVbmljb2RlX0VuY29kZUxhdGluMShwLCBzaXplLCBlcnJvcnMpOworCisgICAgLyogYWxsb2NhdGUgZW5vdWdoIGZvciBhIHNpbXBsZSBlbmNvZGluZyB3aXRob3V0CisgICAgICAgcmVwbGFjZW1lbnRzLCBpZiB3ZSBuZWVkIG1vcmUsIHdlJ2xsIHJlc2l6ZSAqLworICAgIHJlcyA9IFB5U3RyaW5nX0Zyb21TdHJpbmdBbmRTaXplKE5VTEwsIHNpemUpOworICAgIGlmIChyZXMgPT0gTlVMTCkKKyAgICAgICAgZ290byBvbkVycm9yOworICAgIGlmIChzaXplID09IDApCisgICAgICAgIHJldHVybiByZXM7CisKKyAgICB3aGlsZSAoaW5wb3M8c2l6ZSkgeworICAgICAgICAvKiB0cnkgdG8gZW5jb2RlIGl0ICovCisgICAgICAgIGNoYXJtYXBlbmNvZGVfcmVzdWx0IHggPSBjaGFybWFwZW5jb2RlX291dHB1dChwW2lucG9zXSwgbWFwcGluZywgJnJlcywgJnJlc3Bvcyk7CisgICAgICAgIGlmICh4PT1lbmNfRVhDRVBUSU9OKSAvKiBlcnJvciAqLworICAgICAgICAgICAgZ290byBvbkVycm9yOworICAgICAgICBpZiAoeD09ZW5jX0ZBSUxFRCkgeyAvKiB1bmVuY29kYWJsZSBjaGFyYWN0ZXIgKi8KKyAgICAgICAgICAgIGlmIChjaGFybWFwX2VuY29kaW5nX2Vycm9yKHAsIHNpemUsICZpbnBvcywgbWFwcGluZywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZleGMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAma25vd25fZXJyb3JIYW5kbGVyLCAmZXJyb3JIYW5kbGVyLCBlcnJvcnMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmcmVzLCAmcmVzcG9zKSkgeworICAgICAgICAgICAgICAgIGdvdG8gb25FcnJvcjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBlbHNlCisgICAgICAgICAgICAvKiBkb25lIHdpdGggdGhpcyBjaGFyYWN0ZXIgPT4gYWRqdXN0IGlucHV0IHBvc2l0aW9uICovCisgICAgICAgICAgICArK2lucG9zOworICAgIH0KKworICAgIC8qIFJlc2l6ZSBpZiB3ZSBhbGxvY2F0ZWQgdG8gbXVjaCAqLworICAgIGlmIChyZXNwb3M8UHlTdHJpbmdfR0VUX1NJWkUocmVzKSkgeworICAgICAgICBpZiAoX1B5U3RyaW5nX1Jlc2l6ZSgmcmVzLCByZXNwb3MpKQorICAgICAgICAgICAgZ290byBvbkVycm9yOworICAgIH0KKyAgICBQeV9YREVDUkVGKGV4Yyk7CisgICAgUHlfWERFQ1JFRihlcnJvckhhbmRsZXIpOworICAgIHJldHVybiByZXM7CisKKyAgb25FcnJvcjoKKyAgICBQeV9YREVDUkVGKHJlcyk7CisgICAgUHlfWERFQ1JFRihleGMpOworICAgIFB5X1hERUNSRUYoZXJyb3JIYW5kbGVyKTsKKyAgICByZXR1cm4gTlVMTDsKK30KKworUHlPYmplY3QgKlB5VW5pY29kZV9Bc0NoYXJtYXBTdHJpbmcoUHlPYmplY3QgKnVuaWNvZGUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQeU9iamVjdCAqbWFwcGluZykKK3sKKyAgICBpZiAoIVB5VW5pY29kZV9DaGVjayh1bmljb2RlKSB8fCBtYXBwaW5nID09IE5VTEwpIHsKKyAgICAgICAgUHlFcnJfQmFkQXJndW1lbnQoKTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIHJldHVybiBQeVVuaWNvZGVfRW5jb2RlQ2hhcm1hcChQeVVuaWNvZGVfQVNfVU5JQ09ERSh1bmljb2RlKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHlVbmljb2RlX0dFVF9TSVpFKHVuaWNvZGUpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXBwaW5nLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOVUxMKTsKK30KKworLyogY3JlYXRlIG9yIGFkanVzdCBhIFVuaWNvZGVUcmFuc2xhdGVFcnJvciAqLworc3RhdGljIHZvaWQgbWFrZV90cmFuc2xhdGVfZXhjZXB0aW9uKFB5T2JqZWN0ICoqZXhjZXB0aW9uT2JqZWN0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFB5X1VOSUNPREUgKnVuaWNvZGUsIFB5X3NzaXplX3Qgc2l6ZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQeV9zc2l6ZV90IHN0YXJ0cG9zLCBQeV9zc2l6ZV90IGVuZHBvcywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyICpyZWFzb24pCit7CisgICAgaWYgKCpleGNlcHRpb25PYmplY3QgPT0gTlVMTCkgeworICAgICAgICAqZXhjZXB0aW9uT2JqZWN0ID0gUHlVbmljb2RlVHJhbnNsYXRlRXJyb3JfQ3JlYXRlKAorICAgICAgICAgICAgdW5pY29kZSwgc2l6ZSwgc3RhcnRwb3MsIGVuZHBvcywgcmVhc29uKTsKKyAgICB9CisgICAgZWxzZSB7CisgICAgICAgIGlmIChQeVVuaWNvZGVUcmFuc2xhdGVFcnJvcl9TZXRTdGFydCgqZXhjZXB0aW9uT2JqZWN0LCBzdGFydHBvcykpCisgICAgICAgICAgICBnb3RvIG9uRXJyb3I7CisgICAgICAgIGlmIChQeVVuaWNvZGVUcmFuc2xhdGVFcnJvcl9TZXRFbmQoKmV4Y2VwdGlvbk9iamVjdCwgZW5kcG9zKSkKKyAgICAgICAgICAgIGdvdG8gb25FcnJvcjsKKyAgICAgICAgaWYgKFB5VW5pY29kZVRyYW5zbGF0ZUVycm9yX1NldFJlYXNvbigqZXhjZXB0aW9uT2JqZWN0LCByZWFzb24pKQorICAgICAgICAgICAgZ290byBvbkVycm9yOworICAgICAgICByZXR1cm47CisgICAgICBvbkVycm9yOgorICAgICAgICBQeV9ERUNSRUYoKmV4Y2VwdGlvbk9iamVjdCk7CisgICAgICAgICpleGNlcHRpb25PYmplY3QgPSBOVUxMOworICAgIH0KK30KKworLyogcmFpc2VzIGEgVW5pY29kZVRyYW5zbGF0ZUVycm9yICovCitzdGF0aWMgdm9pZCByYWlzZV90cmFuc2xhdGVfZXhjZXB0aW9uKFB5T2JqZWN0ICoqZXhjZXB0aW9uT2JqZWN0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBQeV9VTklDT0RFICp1bmljb2RlLCBQeV9zc2l6ZV90IHNpemUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFB5X3NzaXplX3Qgc3RhcnRwb3MsIFB5X3NzaXplX3QgZW5kcG9zLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyICpyZWFzb24pCit7CisgICAgbWFrZV90cmFuc2xhdGVfZXhjZXB0aW9uKGV4Y2VwdGlvbk9iamVjdCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5pY29kZSwgc2l6ZSwgc3RhcnRwb3MsIGVuZHBvcywgcmVhc29uKTsKKyAgICBpZiAoKmV4Y2VwdGlvbk9iamVjdCAhPSBOVUxMKQorICAgICAgICBQeUNvZGVjX1N0cmljdEVycm9ycygqZXhjZXB0aW9uT2JqZWN0KTsKK30KKworLyogZXJyb3IgaGFuZGxpbmcgY2FsbGJhY2sgaGVscGVyOgorICAgYnVpbGQgYXJndW1lbnRzLCBjYWxsIHRoZSBjYWxsYmFjayBhbmQgY2hlY2sgdGhlIGFyZ3VtZW50cywKKyAgIHB1dCB0aGUgcmVzdWx0IGludG8gbmV3cG9zIGFuZCByZXR1cm4gdGhlIHJlcGxhY2VtZW50IHN0cmluZywgd2hpY2gKKyAgIGhhcyB0byBiZSBmcmVlZCBieSB0aGUgY2FsbGVyICovCitzdGF0aWMgUHlPYmplY3QgKnVuaWNvZGVfdHJhbnNsYXRlX2NhbGxfZXJyb3JoYW5kbGVyKGNvbnN0IGNoYXIgKmVycm9ycywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHlPYmplY3QgKiplcnJvckhhbmRsZXIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgKnJlYXNvbiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgUHlfVU5JQ09ERSAqdW5pY29kZSwgUHlfc3NpemVfdCBzaXplLCBQeU9iamVjdCAqKmV4Y2VwdGlvbk9iamVjdCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHlfc3NpemVfdCBzdGFydHBvcywgUHlfc3NpemVfdCBlbmRwb3MsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFB5X3NzaXplX3QgKm5ld3BvcykKK3sKKyAgICBzdGF0aWMgY2hhciAqYXJncGFyc2UgPSAiTyFuO3RyYW5zbGF0aW5nIGVycm9yIGhhbmRsZXIgbXVzdCByZXR1cm4gKHVuaWNvZGUsIGludCkgdHVwbGUiOworCisgICAgUHlfc3NpemVfdCBpX25ld3BvczsKKyAgICBQeU9iamVjdCAqcmVzdHVwbGU7CisgICAgUHlPYmplY3QgKnJlc3VuaWNvZGU7CisKKyAgICBpZiAoKmVycm9ySGFuZGxlciA9PSBOVUxMKSB7CisgICAgICAgICplcnJvckhhbmRsZXIgPSBQeUNvZGVjX0xvb2t1cEVycm9yKGVycm9ycyk7CisgICAgICAgIGlmICgqZXJyb3JIYW5kbGVyID09IE5VTEwpCisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisKKyAgICBtYWtlX3RyYW5zbGF0ZV9leGNlcHRpb24oZXhjZXB0aW9uT2JqZWN0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1bmljb2RlLCBzaXplLCBzdGFydHBvcywgZW5kcG9zLCByZWFzb24pOworICAgIGlmICgqZXhjZXB0aW9uT2JqZWN0ID09IE5VTEwpCisgICAgICAgIHJldHVybiBOVUxMOworCisgICAgcmVzdHVwbGUgPSBQeU9iamVjdF9DYWxsRnVuY3Rpb25PYmpBcmdzKAorICAgICAgICAqZXJyb3JIYW5kbGVyLCAqZXhjZXB0aW9uT2JqZWN0LCBOVUxMKTsKKyAgICBpZiAocmVzdHVwbGUgPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgaWYgKCFQeVR1cGxlX0NoZWNrKHJlc3R1cGxlKSkgeworICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfVHlwZUVycm9yLCAmYXJncGFyc2VbNF0pOworICAgICAgICBQeV9ERUNSRUYocmVzdHVwbGUpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgaWYgKCFQeUFyZ19QYXJzZVR1cGxlKHJlc3R1cGxlLCBhcmdwYXJzZSwgJlB5VW5pY29kZV9UeXBlLAorICAgICAgICAgICAgICAgICAgICAgICAgICAmcmVzdW5pY29kZSwgJmlfbmV3cG9zKSkgeworICAgICAgICBQeV9ERUNSRUYocmVzdHVwbGUpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgaWYgKGlfbmV3cG9zPDApCisgICAgICAgICpuZXdwb3MgPSBzaXplK2lfbmV3cG9zOworICAgIGVsc2UKKyAgICAgICAgKm5ld3BvcyA9IGlfbmV3cG9zOworICAgIGlmICgqbmV3cG9zPDAgfHwgKm5ld3Bvcz5zaXplKSB7CisgICAgICAgIFB5RXJyX0Zvcm1hdChQeUV4Y19JbmRleEVycm9yLCAicG9zaXRpb24gJXpkIGZyb20gZXJyb3IgaGFuZGxlciBvdXQgb2YgYm91bmRzIiwgKm5ld3Bvcyk7CisgICAgICAgIFB5X0RFQ1JFRihyZXN0dXBsZSk7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICBQeV9JTkNSRUYocmVzdW5pY29kZSk7CisgICAgUHlfREVDUkVGKHJlc3R1cGxlKTsKKyAgICByZXR1cm4gcmVzdW5pY29kZTsKK30KKworLyogTG9va3VwIHRoZSBjaGFyYWN0ZXIgY2ggaW4gdGhlIG1hcHBpbmcgYW5kIHB1dCB0aGUgcmVzdWx0IGluIHJlc3VsdCwKKyAgIHdoaWNoIG11c3QgYmUgZGVjcmVmZWQgYnkgdGhlIGNhbGxlci4KKyAgIFJldHVybiAwIG9uIHN1Y2Nlc3MsIC0xIG9uIGVycm9yICovCitzdGF0aWMKK2ludCBjaGFybWFwdHJhbnNsYXRlX2xvb2t1cChQeV9VTklDT0RFIGMsIFB5T2JqZWN0ICptYXBwaW5nLCBQeU9iamVjdCAqKnJlc3VsdCkKK3sKKyAgICBQeU9iamVjdCAqdyA9IFB5SW50X0Zyb21Mb25nKChsb25nKWMpOworICAgIFB5T2JqZWN0ICp4OworCisgICAgaWYgKHcgPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIC0xOworICAgIHggPSBQeU9iamVjdF9HZXRJdGVtKG1hcHBpbmcsIHcpOworICAgIFB5X0RFQ1JFRih3KTsKKyAgICBpZiAoeCA9PSBOVUxMKSB7CisgICAgICAgIGlmIChQeUVycl9FeGNlcHRpb25NYXRjaGVzKFB5RXhjX0xvb2t1cEVycm9yKSkgeworICAgICAgICAgICAgLyogTm8gbWFwcGluZyBmb3VuZCBtZWFuczogdXNlIDE6MSBtYXBwaW5nLiAqLworICAgICAgICAgICAgUHlFcnJfQ2xlYXIoKTsKKyAgICAgICAgICAgICpyZXN1bHQgPSBOVUxMOworICAgICAgICAgICAgcmV0dXJuIDA7CisgICAgICAgIH0gZWxzZQorICAgICAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKyAgICBlbHNlIGlmICh4ID09IFB5X05vbmUpIHsKKyAgICAgICAgKnJlc3VsdCA9IHg7CisgICAgICAgIHJldHVybiAwOworICAgIH0KKyAgICBlbHNlIGlmIChQeUludF9DaGVjayh4KSkgeworICAgICAgICBsb25nIHZhbHVlID0gUHlJbnRfQVNfTE9ORyh4KTsKKyAgICAgICAgbG9uZyBtYXggPSBQeVVuaWNvZGVfR2V0TWF4KCk7CisgICAgICAgIGlmICh2YWx1ZSA8IDAgfHwgdmFsdWUgPiBtYXgpIHsKKyAgICAgICAgICAgIFB5RXJyX0Zvcm1hdChQeUV4Y19UeXBlRXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgImNoYXJhY3RlciBtYXBwaW5nIG11c3QgYmUgaW4gcmFuZ2UoMHglbHgpIiwgbWF4KzEpOworICAgICAgICAgICAgUHlfREVDUkVGKHgpOworICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICB9CisgICAgICAgICpyZXN1bHQgPSB4OworICAgICAgICByZXR1cm4gMDsKKyAgICB9CisgICAgZWxzZSBpZiAoUHlVbmljb2RlX0NoZWNrKHgpKSB7CisgICAgICAgICpyZXN1bHQgPSB4OworICAgICAgICByZXR1cm4gMDsKKyAgICB9CisgICAgZWxzZSB7CisgICAgICAgIC8qIHdyb25nIHJldHVybiB2YWx1ZSAqLworICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfVHlwZUVycm9yLAorICAgICAgICAgICAgICAgICAgICAgICAgImNoYXJhY3RlciBtYXBwaW5nIG11c3QgcmV0dXJuIGludGVnZXIsIE5vbmUgb3IgdW5pY29kZSIpOworICAgICAgICBQeV9ERUNSRUYoeCk7CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9Cit9CisvKiBlbnN1cmUgdGhhdCAqb3V0b2JqIGlzIGF0IGxlYXN0IHJlcXVpcmVkc2l6ZSBjaGFyYWN0ZXJzIGxvbmcsCisgICBpZiBub3QgcmVhbGxvY2F0ZSBhbmQgYWRqdXN0IHZhcmlvdXMgc3RhdGUgdmFyaWFibGVzLgorICAgUmV0dXJuIDAgb24gc3VjY2VzcywgLTEgb24gZXJyb3IgKi8KK3N0YXRpYworaW50IGNoYXJtYXB0cmFuc2xhdGVfbWFrZXNwYWNlKFB5T2JqZWN0ICoqb3V0b2JqLCBQeV9VTklDT0RFICoqb3V0cCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQeV9zc2l6ZV90IHJlcXVpcmVkc2l6ZSkKK3sKKyAgICBQeV9zc2l6ZV90IG9sZHNpemUgPSBQeVVuaWNvZGVfR0VUX1NJWkUoKm91dG9iaik7CisgICAgaWYgKHJlcXVpcmVkc2l6ZSA+IG9sZHNpemUpIHsKKyAgICAgICAgLyogcmVtZW1iZXIgb2xkIG91dHB1dCBwb3NpdGlvbiAqLworICAgICAgICBQeV9zc2l6ZV90IG91dHBvcyA9ICpvdXRwLVB5VW5pY29kZV9BU19VTklDT0RFKCpvdXRvYmopOworICAgICAgICAvKiBleHBvbmVudGlhbGx5IG92ZXJhbGxvY2F0ZSB0byBtaW5pbWl6ZSByZWFsbG9jYXRpb25zICovCisgICAgICAgIGlmIChyZXF1aXJlZHNpemUgPCAyICogb2xkc2l6ZSkKKyAgICAgICAgICAgIHJlcXVpcmVkc2l6ZSA9IDIgKiBvbGRzaXplOworICAgICAgICBpZiAoUHlVbmljb2RlX1Jlc2l6ZShvdXRvYmosIHJlcXVpcmVkc2l6ZSkgPCAwKQorICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICAqb3V0cCA9IFB5VW5pY29kZV9BU19VTklDT0RFKCpvdXRvYmopICsgb3V0cG9zOworICAgIH0KKyAgICByZXR1cm4gMDsKK30KKy8qIGxvb2t1cCB0aGUgY2hhcmFjdGVyLCBwdXQgdGhlIHJlc3VsdCBpbiB0aGUgb3V0cHV0IHN0cmluZyBhbmQgYWRqdXN0CisgICB2YXJpb3VzIHN0YXRlIHZhcmlhYmxlcy4gUmV0dXJuIGEgbmV3IHJlZmVyZW5jZSB0byB0aGUgb2JqZWN0IHRoYXQKKyAgIHdhcyBwdXQgaW4gdGhlIG91dHB1dCBidWZmZXIgaW4gKnJlc3VsdCwgb3IgUHlfTm9uZSwgaWYgdGhlIG1hcHBpbmcgd2FzCisgICB1bmRlZmluZWQgKGluIHdoaWNoIGNhc2Ugbm8gY2hhcmFjdGVyIHdhcyB3cml0dGVuKS4KKyAgIFRoZSBjYWxsZWQgbXVzdCBkZWNyZWYgcmVzdWx0LgorICAgUmV0dXJuIDAgb24gc3VjY2VzcywgLTEgb24gZXJyb3IuICovCitzdGF0aWMKK2ludCBjaGFybWFwdHJhbnNsYXRlX291dHB1dChjb25zdCBQeV9VTklDT0RFICpzdGFydGlucCwgY29uc3QgUHlfVU5JQ09ERSAqY3VyaW5wLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIFB5X3NzaXplX3QgaW5zaXplLCBQeU9iamVjdCAqbWFwcGluZywgUHlPYmplY3QgKipvdXRvYmosIFB5X1VOSUNPREUgKipvdXRwLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIFB5T2JqZWN0ICoqcmVzKQoreworICAgIGlmIChjaGFybWFwdHJhbnNsYXRlX2xvb2t1cCgqY3VyaW5wLCBtYXBwaW5nLCByZXMpKQorICAgICAgICByZXR1cm4gLTE7CisgICAgaWYgKCpyZXM9PU5VTEwpIHsKKyAgICAgICAgLyogbm90IGZvdW5kID0+IGRlZmF1bHQgdG8gMToxIG1hcHBpbmcgKi8KKyAgICAgICAgKigqb3V0cCkrKyA9ICpjdXJpbnA7CisgICAgfQorICAgIGVsc2UgaWYgKCpyZXM9PVB5X05vbmUpCisgICAgICAgIDsKKyAgICBlbHNlIGlmIChQeUludF9DaGVjaygqcmVzKSkgeworICAgICAgICAvKiBubyBvdmVyZmxvdyBjaGVjaywgYmVjYXVzZSB3ZSBrbm93IHRoYXQgdGhlIHNwYWNlIGlzIGVub3VnaCAqLworICAgICAgICAqKCpvdXRwKSsrID0gKFB5X1VOSUNPREUpUHlJbnRfQVNfTE9ORygqcmVzKTsKKyAgICB9CisgICAgZWxzZSBpZiAoUHlVbmljb2RlX0NoZWNrKCpyZXMpKSB7CisgICAgICAgIFB5X3NzaXplX3QgcmVwc2l6ZSA9IFB5VW5pY29kZV9HRVRfU0laRSgqcmVzKTsKKyAgICAgICAgaWYgKHJlcHNpemU9PTEpIHsKKyAgICAgICAgICAgIC8qIG5vIG92ZXJmbG93IGNoZWNrLCBiZWNhdXNlIHdlIGtub3cgdGhhdCB0aGUgc3BhY2UgaXMgZW5vdWdoICovCisgICAgICAgICAgICAqKCpvdXRwKSsrID0gKlB5VW5pY29kZV9BU19VTklDT0RFKCpyZXMpOworICAgICAgICB9CisgICAgICAgIGVsc2UgaWYgKHJlcHNpemUhPTApIHsKKyAgICAgICAgICAgIC8qIG1vcmUgdGhhbiBvbmUgY2hhcmFjdGVyICovCisgICAgICAgICAgICBQeV9zc2l6ZV90IHJlcXVpcmVkc2l6ZSA9ICgqb3V0cC1QeVVuaWNvZGVfQVNfVU5JQ09ERSgqb3V0b2JqKSkgKworICAgICAgICAgICAgICAgIChpbnNpemUgLSAoY3VyaW5wLXN0YXJ0aW5wKSkgKworICAgICAgICAgICAgICAgIHJlcHNpemUgLSAxOworICAgICAgICAgICAgaWYgKGNoYXJtYXB0cmFuc2xhdGVfbWFrZXNwYWNlKG91dG9iaiwgb3V0cCwgcmVxdWlyZWRzaXplKSkKKyAgICAgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgICAgICBtZW1jcHkoKm91dHAsIFB5VW5pY29kZV9BU19VTklDT0RFKCpyZXMpLCBzaXplb2YoUHlfVU5JQ09ERSkqcmVwc2l6ZSk7CisgICAgICAgICAgICAqb3V0cCArPSByZXBzaXplOworICAgICAgICB9CisgICAgfQorICAgIGVsc2UKKyAgICAgICAgcmV0dXJuIC0xOworICAgIHJldHVybiAwOworfQorCitQeU9iamVjdCAqUHlVbmljb2RlX1RyYW5zbGF0ZUNoYXJtYXAoY29uc3QgUHlfVU5JQ09ERSAqcCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQeV9zc2l6ZV90IHNpemUsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHlPYmplY3QgKm1hcHBpbmcsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciAqZXJyb3JzKQoreworICAgIC8qIG91dHB1dCBvYmplY3QgKi8KKyAgICBQeU9iamVjdCAqcmVzID0gTlVMTDsKKyAgICAvKiBwb2ludGVycyB0byB0aGUgYmVnaW5uaW5nIGFuZCBlbmQrMSBvZiBpbnB1dCAqLworICAgIGNvbnN0IFB5X1VOSUNPREUgKnN0YXJ0cCA9IHA7CisgICAgY29uc3QgUHlfVU5JQ09ERSAqZW5kcCA9IHAgKyBzaXplOworICAgIC8qIHBvaW50ZXIgaW50byB0aGUgb3V0cHV0ICovCisgICAgUHlfVU5JQ09ERSAqc3RyOworICAgIC8qIGN1cnJlbnQgb3V0cHV0IHBvc2l0aW9uICovCisgICAgUHlfc3NpemVfdCByZXNwb3MgPSAwOworICAgIGNoYXIgKnJlYXNvbiA9ICJjaGFyYWN0ZXIgbWFwcyB0byA8dW5kZWZpbmVkPiI7CisgICAgUHlPYmplY3QgKmVycm9ySGFuZGxlciA9IE5VTEw7CisgICAgUHlPYmplY3QgKmV4YyA9IE5VTEw7CisgICAgLyogdGhlIGZvbGxvd2luZyB2YXJpYWJsZSBpcyB1c2VkIGZvciBjYWNoaW5nIHN0cmluZyBjb21wYXJpc29ucworICAgICAqIC0xPW5vdCBpbml0aWFsaXplZCwgMD11bmtub3duLCAxPXN0cmljdCwgMj1yZXBsYWNlLAorICAgICAqIDM9aWdub3JlLCA0PXhtbGNoYXJyZWZyZXBsYWNlICovCisgICAgaW50IGtub3duX2Vycm9ySGFuZGxlciA9IC0xOworCisgICAgaWYgKG1hcHBpbmcgPT0gTlVMTCkgeworICAgICAgICBQeUVycl9CYWRBcmd1bWVudCgpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisKKyAgICAvKiBhbGxvY2F0ZSBlbm91Z2ggZm9yIGEgc2ltcGxlIDE6MSB0cmFuc2xhdGlvbiB3aXRob3V0CisgICAgICAgcmVwbGFjZW1lbnRzLCBpZiB3ZSBuZWVkIG1vcmUsIHdlJ2xsIHJlc2l6ZSAqLworICAgIHJlcyA9IFB5VW5pY29kZV9Gcm9tVW5pY29kZShOVUxMLCBzaXplKTsKKyAgICBpZiAocmVzID09IE5VTEwpCisgICAgICAgIGdvdG8gb25FcnJvcjsKKyAgICBpZiAoc2l6ZSA9PSAwKQorICAgICAgICByZXR1cm4gcmVzOworICAgIHN0ciA9IFB5VW5pY29kZV9BU19VTklDT0RFKHJlcyk7CisKKyAgICB3aGlsZSAocDxlbmRwKSB7CisgICAgICAgIC8qIHRyeSB0byBlbmNvZGUgaXQgKi8KKyAgICAgICAgUHlPYmplY3QgKnggPSBOVUxMOworICAgICAgICBpZiAoY2hhcm1hcHRyYW5zbGF0ZV9vdXRwdXQoc3RhcnRwLCBwLCBzaXplLCBtYXBwaW5nLCAmcmVzLCAmc3RyLCAmeCkpIHsKKyAgICAgICAgICAgIFB5X1hERUNSRUYoeCk7CisgICAgICAgICAgICBnb3RvIG9uRXJyb3I7CisgICAgICAgIH0KKyAgICAgICAgUHlfWERFQ1JFRih4KTsKKyAgICAgICAgaWYgKHghPVB5X05vbmUpIC8qIGl0IHdvcmtlZCA9PiBhZGp1c3QgaW5wdXQgcG9pbnRlciAqLworICAgICAgICAgICAgKytwOworICAgICAgICBlbHNlIHsgLyogdW50cmFuc2xhdGFibGUgY2hhcmFjdGVyICovCisgICAgICAgICAgICBQeU9iamVjdCAqcmVwdW5pY29kZSA9IE5VTEw7IC8qIGluaXRpYWxpemUgdG8gcHJldmVudCBnY2Mgd2FybmluZyAqLworICAgICAgICAgICAgUHlfc3NpemVfdCByZXBzaXplOworICAgICAgICAgICAgUHlfc3NpemVfdCBuZXdwb3M7CisgICAgICAgICAgICBQeV9VTklDT0RFICp1bmkyOworICAgICAgICAgICAgLyogc3RhcnRwb3MgZm9yIGNvbGxlY3RpbmcgdW50cmFuc2xhdGFibGUgY2hhcnMgKi8KKyAgICAgICAgICAgIGNvbnN0IFB5X1VOSUNPREUgKmNvbGxzdGFydCA9IHA7CisgICAgICAgICAgICBjb25zdCBQeV9VTklDT0RFICpjb2xsZW5kID0gcCsxOworICAgICAgICAgICAgY29uc3QgUHlfVU5JQ09ERSAqY29sbDsKKworICAgICAgICAgICAgLyogZmluZCBhbGwgdW50cmFuc2xhdGFibGUgY2hhcmFjdGVycyAqLworICAgICAgICAgICAgd2hpbGUgKGNvbGxlbmQgPCBlbmRwKSB7CisgICAgICAgICAgICAgICAgaWYgKGNoYXJtYXB0cmFuc2xhdGVfbG9va3VwKCpjb2xsZW5kLCBtYXBwaW5nLCAmeCkpCisgICAgICAgICAgICAgICAgICAgIGdvdG8gb25FcnJvcjsKKyAgICAgICAgICAgICAgICBQeV9YREVDUkVGKHgpOworICAgICAgICAgICAgICAgIGlmICh4IT1QeV9Ob25lKQorICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICArK2NvbGxlbmQ7CisgICAgICAgICAgICB9CisgICAgICAgICAgICAvKiBjYWNoZSBjYWxsYmFjayBuYW1lIGxvb2t1cAorICAgICAgICAgICAgICogKGlmIG5vdCBkb25lIHlldCwgaS5lLiBpdCdzIHRoZSBmaXJzdCBlcnJvcikgKi8KKyAgICAgICAgICAgIGlmIChrbm93bl9lcnJvckhhbmRsZXI9PS0xKSB7CisgICAgICAgICAgICAgICAgaWYgKChlcnJvcnM9PU5VTEwpIHx8ICghc3RyY21wKGVycm9ycywgInN0cmljdCIpKSkKKyAgICAgICAgICAgICAgICAgICAga25vd25fZXJyb3JIYW5kbGVyID0gMTsKKyAgICAgICAgICAgICAgICBlbHNlIGlmICghc3RyY21wKGVycm9ycywgInJlcGxhY2UiKSkKKyAgICAgICAgICAgICAgICAgICAga25vd25fZXJyb3JIYW5kbGVyID0gMjsKKyAgICAgICAgICAgICAgICBlbHNlIGlmICghc3RyY21wKGVycm9ycywgImlnbm9yZSIpKQorICAgICAgICAgICAgICAgICAgICBrbm93bl9lcnJvckhhbmRsZXIgPSAzOworICAgICAgICAgICAgICAgIGVsc2UgaWYgKCFzdHJjbXAoZXJyb3JzLCAieG1sY2hhcnJlZnJlcGxhY2UiKSkKKyAgICAgICAgICAgICAgICAgICAga25vd25fZXJyb3JIYW5kbGVyID0gNDsKKyAgICAgICAgICAgICAgICBlbHNlCisgICAgICAgICAgICAgICAgICAgIGtub3duX2Vycm9ySGFuZGxlciA9IDA7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBzd2l0Y2ggKGtub3duX2Vycm9ySGFuZGxlcikgeworICAgICAgICAgICAgY2FzZSAxOiAvKiBzdHJpY3QgKi8KKyAgICAgICAgICAgICAgICByYWlzZV90cmFuc2xhdGVfZXhjZXB0aW9uKCZleGMsIHN0YXJ0cCwgc2l6ZSwgY29sbHN0YXJ0LXN0YXJ0cCwgY29sbGVuZC1zdGFydHAsIHJlYXNvbik7CisgICAgICAgICAgICAgICAgZ290byBvbkVycm9yOworICAgICAgICAgICAgY2FzZSAyOiAvKiByZXBsYWNlICovCisgICAgICAgICAgICAgICAgLyogTm8gbmVlZCB0byBjaGVjayBmb3Igc3BhY2UsIHRoaXMgaXMgYSAxOjEgcmVwbGFjZW1lbnQgKi8KKyAgICAgICAgICAgICAgICBmb3IgKGNvbGwgPSBjb2xsc3RhcnQ7IGNvbGw8Y29sbGVuZDsgKytjb2xsKQorICAgICAgICAgICAgICAgICAgICAqc3RyKysgPSAnPyc7CisgICAgICAgICAgICAgICAgLyogZmFsbCB0aHJvdWdoICovCisgICAgICAgICAgICBjYXNlIDM6IC8qIGlnbm9yZSAqLworICAgICAgICAgICAgICAgIHAgPSBjb2xsZW5kOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgY2FzZSA0OiAvKiB4bWxjaGFycmVmcmVwbGFjZSAqLworICAgICAgICAgICAgICAgIC8qIGdlbmVyYXRlIHJlcGxhY2VtZW50ICh0ZW1wb3JhcmlseSAobWlzKXVzZXMgcCkgKi8KKyAgICAgICAgICAgICAgICBmb3IgKHAgPSBjb2xsc3RhcnQ7IHAgPCBjb2xsZW5kOyArK3ApIHsKKyAgICAgICAgICAgICAgICAgICAgY2hhciBidWZmZXJbMisyOSsxKzFdOworICAgICAgICAgICAgICAgICAgICBjaGFyICpjcDsKKyAgICAgICAgICAgICAgICAgICAgc3ByaW50ZihidWZmZXIsICImIyVkOyIsIChpbnQpKnApOworICAgICAgICAgICAgICAgICAgICBpZiAoY2hhcm1hcHRyYW5zbGF0ZV9tYWtlc3BhY2UoJnJlcywgJnN0ciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChzdHItUHlVbmljb2RlX0FTX1VOSUNPREUocmVzKSkrc3RybGVuKGJ1ZmZlcikrKGVuZHAtY29sbGVuZCkpKQorICAgICAgICAgICAgICAgICAgICAgICAgZ290byBvbkVycm9yOworICAgICAgICAgICAgICAgICAgICBmb3IgKGNwID0gYnVmZmVyOyAqY3A7ICsrY3ApCisgICAgICAgICAgICAgICAgICAgICAgICAqc3RyKysgPSAqY3A7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHAgPSBjb2xsZW5kOworICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgZGVmYXVsdDoKKyAgICAgICAgICAgICAgICByZXB1bmljb2RlID0gdW5pY29kZV90cmFuc2xhdGVfY2FsbF9lcnJvcmhhbmRsZXIoZXJyb3JzLCAmZXJyb3JIYW5kbGVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZWFzb24sIHN0YXJ0cCwgc2l6ZSwgJmV4YywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sbHN0YXJ0LXN0YXJ0cCwgY29sbGVuZC1zdGFydHAsICZuZXdwb3MpOworICAgICAgICAgICAgICAgIGlmIChyZXB1bmljb2RlID09IE5VTEwpCisgICAgICAgICAgICAgICAgICAgIGdvdG8gb25FcnJvcjsKKyAgICAgICAgICAgICAgICAvKiBnZW5lcmF0ZSByZXBsYWNlbWVudCAgKi8KKyAgICAgICAgICAgICAgICByZXBzaXplID0gUHlVbmljb2RlX0dFVF9TSVpFKHJlcHVuaWNvZGUpOworICAgICAgICAgICAgICAgIGlmIChjaGFybWFwdHJhbnNsYXRlX21ha2VzcGFjZSgmcmVzLCAmc3RyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoc3RyLVB5VW5pY29kZV9BU19VTklDT0RFKHJlcykpK3JlcHNpemUrKGVuZHAtY29sbGVuZCkpKSB7CisgICAgICAgICAgICAgICAgICAgIFB5X0RFQ1JFRihyZXB1bmljb2RlKTsKKyAgICAgICAgICAgICAgICAgICAgZ290byBvbkVycm9yOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBmb3IgKHVuaTIgPSBQeVVuaWNvZGVfQVNfVU5JQ09ERShyZXB1bmljb2RlKTsgcmVwc2l6ZS0tPjA7ICsrdW5pMikKKyAgICAgICAgICAgICAgICAgICAgKnN0cisrID0gKnVuaTI7CisgICAgICAgICAgICAgICAgcCA9IHN0YXJ0cCArIG5ld3BvczsKKyAgICAgICAgICAgICAgICBQeV9ERUNSRUYocmVwdW5pY29kZSk7CisgICAgICAgICAgICB9CisgICAgICAgIH0KKyAgICB9CisgICAgLyogUmVzaXplIGlmIHdlIGFsbG9jYXRlZCB0byBtdWNoICovCisgICAgcmVzcG9zID0gc3RyLVB5VW5pY29kZV9BU19VTklDT0RFKHJlcyk7CisgICAgaWYgKHJlc3BvczxQeVVuaWNvZGVfR0VUX1NJWkUocmVzKSkgeworICAgICAgICBpZiAoUHlVbmljb2RlX1Jlc2l6ZSgmcmVzLCByZXNwb3MpIDwgMCkKKyAgICAgICAgICAgIGdvdG8gb25FcnJvcjsKKyAgICB9CisgICAgUHlfWERFQ1JFRihleGMpOworICAgIFB5X1hERUNSRUYoZXJyb3JIYW5kbGVyKTsKKyAgICByZXR1cm4gcmVzOworCisgIG9uRXJyb3I6CisgICAgUHlfWERFQ1JFRihyZXMpOworICAgIFB5X1hERUNSRUYoZXhjKTsKKyAgICBQeV9YREVDUkVGKGVycm9ySGFuZGxlcik7CisgICAgcmV0dXJuIE5VTEw7Cit9CisKK1B5T2JqZWN0ICpQeVVuaWNvZGVfVHJhbnNsYXRlKFB5T2JqZWN0ICpzdHIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQeU9iamVjdCAqbWFwcGluZywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgKmVycm9ycykKK3sKKyAgICBQeU9iamVjdCAqcmVzdWx0OworCisgICAgc3RyID0gUHlVbmljb2RlX0Zyb21PYmplY3Qoc3RyKTsKKyAgICBpZiAoc3RyID09IE5VTEwpCisgICAgICAgIGdvdG8gb25FcnJvcjsKKyAgICByZXN1bHQgPSBQeVVuaWNvZGVfVHJhbnNsYXRlQ2hhcm1hcChQeVVuaWNvZGVfQVNfVU5JQ09ERShzdHIpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFB5VW5pY29kZV9HRVRfU0laRShzdHIpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hcHBpbmcsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXJyb3JzKTsKKyAgICBQeV9ERUNSRUYoc3RyKTsKKyAgICByZXR1cm4gcmVzdWx0OworCisgIG9uRXJyb3I6CisgICAgUHlfWERFQ1JFRihzdHIpOworICAgIHJldHVybiBOVUxMOworfQorCisvKiAtLS0gRGVjaW1hbCBFbmNvZGVyIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KKworaW50IFB5VW5pY29kZV9FbmNvZGVEZWNpbWFsKFB5X1VOSUNPREUgKnMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHlfc3NpemVfdCBsZW5ndGgsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hhciAqb3V0cHV0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgKmVycm9ycykKK3sKKyAgICBQeV9VTklDT0RFICpwLCAqZW5kOworICAgIFB5T2JqZWN0ICplcnJvckhhbmRsZXIgPSBOVUxMOworICAgIFB5T2JqZWN0ICpleGMgPSBOVUxMOworICAgIGNvbnN0IGNoYXIgKmVuY29kaW5nID0gImRlY2ltYWwiOworICAgIGNvbnN0IGNoYXIgKnJlYXNvbiA9ICJpbnZhbGlkIGRlY2ltYWwgVW5pY29kZSBzdHJpbmciOworICAgIC8qIHRoZSBmb2xsb3dpbmcgdmFyaWFibGUgaXMgdXNlZCBmb3IgY2FjaGluZyBzdHJpbmcgY29tcGFyaXNvbnMKKyAgICAgKiAtMT1ub3QgaW5pdGlhbGl6ZWQsIDA9dW5rbm93biwgMT1zdHJpY3QsIDI9cmVwbGFjZSwgMz1pZ25vcmUsIDQ9eG1sY2hhcnJlZnJlcGxhY2UgKi8KKyAgICBpbnQga25vd25fZXJyb3JIYW5kbGVyID0gLTE7CisKKyAgICBpZiAob3V0cHV0ID09IE5VTEwpIHsKKyAgICAgICAgUHlFcnJfQmFkQXJndW1lbnQoKTsKKyAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKworICAgIHAgPSBzOworICAgIGVuZCA9IHMgKyBsZW5ndGg7CisgICAgd2hpbGUgKHAgPCBlbmQpIHsKKyAgICAgICAgcmVnaXN0ZXIgUHlfVU5JQ09ERSBjaCA9ICpwOworICAgICAgICBpbnQgZGVjaW1hbDsKKyAgICAgICAgUHlPYmplY3QgKnJlcHVuaWNvZGU7CisgICAgICAgIFB5X3NzaXplX3QgcmVwc2l6ZTsKKyAgICAgICAgUHlfc3NpemVfdCBuZXdwb3M7CisgICAgICAgIFB5X1VOSUNPREUgKnVuaTI7CisgICAgICAgIFB5X1VOSUNPREUgKmNvbGxzdGFydDsKKyAgICAgICAgUHlfVU5JQ09ERSAqY29sbGVuZDsKKworICAgICAgICBpZiAoUHlfVU5JQ09ERV9JU1NQQUNFKGNoKSkgeworICAgICAgICAgICAgKm91dHB1dCsrID0gJyAnOworICAgICAgICAgICAgKytwOworICAgICAgICAgICAgY29udGludWU7CisgICAgICAgIH0KKyAgICAgICAgZGVjaW1hbCA9IFB5X1VOSUNPREVfVE9ERUNJTUFMKGNoKTsKKyAgICAgICAgaWYgKGRlY2ltYWwgPj0gMCkgeworICAgICAgICAgICAgKm91dHB1dCsrID0gJzAnICsgZGVjaW1hbDsKKyAgICAgICAgICAgICsrcDsKKyAgICAgICAgICAgIGNvbnRpbnVlOworICAgICAgICB9CisgICAgICAgIGlmICgwIDwgY2ggJiYgY2ggPCAyNTYpIHsKKyAgICAgICAgICAgICpvdXRwdXQrKyA9IChjaGFyKWNoOworICAgICAgICAgICAgKytwOworICAgICAgICAgICAgY29udGludWU7CisgICAgICAgIH0KKyAgICAgICAgLyogQWxsIG90aGVyIGNoYXJhY3RlcnMgYXJlIGNvbnNpZGVyZWQgdW5lbmNvZGFibGUgKi8KKyAgICAgICAgY29sbHN0YXJ0ID0gcDsKKyAgICAgICAgZm9yIChjb2xsZW5kID0gcCsxOyBjb2xsZW5kIDwgZW5kOyBjb2xsZW5kKyspIHsKKyAgICAgICAgICAgIGlmICgoMCA8ICpjb2xsZW5kICYmICpjb2xsZW5kIDwgMjU2KSB8fAorICAgICAgICAgICAgICAgIFB5X1VOSUNPREVfSVNTUEFDRSgqY29sbGVuZCkgfHwKKyAgICAgICAgICAgICAgICAwIDw9IFB5X1VOSUNPREVfVE9ERUNJTUFMKCpjb2xsZW5kKSkKKyAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgfQorICAgICAgICAvKiBjYWNoZSBjYWxsYmFjayBuYW1lIGxvb2t1cAorICAgICAgICAgKiAoaWYgbm90IGRvbmUgeWV0LCBpLmUuIGl0J3MgdGhlIGZpcnN0IGVycm9yKSAqLworICAgICAgICBpZiAoa25vd25fZXJyb3JIYW5kbGVyPT0tMSkgeworICAgICAgICAgICAgaWYgKChlcnJvcnM9PU5VTEwpIHx8ICghc3RyY21wKGVycm9ycywgInN0cmljdCIpKSkKKyAgICAgICAgICAgICAgICBrbm93bl9lcnJvckhhbmRsZXIgPSAxOworICAgICAgICAgICAgZWxzZSBpZiAoIXN0cmNtcChlcnJvcnMsICJyZXBsYWNlIikpCisgICAgICAgICAgICAgICAga25vd25fZXJyb3JIYW5kbGVyID0gMjsKKyAgICAgICAgICAgIGVsc2UgaWYgKCFzdHJjbXAoZXJyb3JzLCAiaWdub3JlIikpCisgICAgICAgICAgICAgICAga25vd25fZXJyb3JIYW5kbGVyID0gMzsKKyAgICAgICAgICAgIGVsc2UgaWYgKCFzdHJjbXAoZXJyb3JzLCAieG1sY2hhcnJlZnJlcGxhY2UiKSkKKyAgICAgICAgICAgICAgICBrbm93bl9lcnJvckhhbmRsZXIgPSA0OworICAgICAgICAgICAgZWxzZQorICAgICAgICAgICAgICAgIGtub3duX2Vycm9ySGFuZGxlciA9IDA7CisgICAgICAgIH0KKyAgICAgICAgc3dpdGNoIChrbm93bl9lcnJvckhhbmRsZXIpIHsKKyAgICAgICAgY2FzZSAxOiAvKiBzdHJpY3QgKi8KKyAgICAgICAgICAgIHJhaXNlX2VuY29kZV9leGNlcHRpb24oJmV4YywgZW5jb2RpbmcsIHMsIGxlbmd0aCwgY29sbHN0YXJ0LXMsIGNvbGxlbmQtcywgcmVhc29uKTsKKyAgICAgICAgICAgIGdvdG8gb25FcnJvcjsKKyAgICAgICAgY2FzZSAyOiAvKiByZXBsYWNlICovCisgICAgICAgICAgICBmb3IgKHAgPSBjb2xsc3RhcnQ7IHAgPCBjb2xsZW5kOyArK3ApCisgICAgICAgICAgICAgICAgKm91dHB1dCsrID0gJz8nOworICAgICAgICAgICAgLyogZmFsbCB0aHJvdWdoICovCisgICAgICAgIGNhc2UgMzogLyogaWdub3JlICovCisgICAgICAgICAgICBwID0gY29sbGVuZDsKKyAgICAgICAgICAgIGJyZWFrOworICAgICAgICBjYXNlIDQ6IC8qIHhtbGNoYXJyZWZyZXBsYWNlICovCisgICAgICAgICAgICAvKiBnZW5lcmF0ZSByZXBsYWNlbWVudCAodGVtcG9yYXJpbHkgKG1pcyl1c2VzIHApICovCisgICAgICAgICAgICBmb3IgKHAgPSBjb2xsc3RhcnQ7IHAgPCBjb2xsZW5kOyArK3ApCisgICAgICAgICAgICAgICAgb3V0cHV0ICs9IHNwcmludGYob3V0cHV0LCAiJiMlZDsiLCAoaW50KSpwKTsKKyAgICAgICAgICAgIHAgPSBjb2xsZW5kOworICAgICAgICAgICAgYnJlYWs7CisgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICByZXB1bmljb2RlID0gdW5pY29kZV9lbmNvZGVfY2FsbF9lcnJvcmhhbmRsZXIoZXJyb3JzLCAmZXJyb3JIYW5kbGVyLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVuY29kaW5nLCByZWFzb24sIHMsIGxlbmd0aCwgJmV4YywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xsc3RhcnQtcywgY29sbGVuZC1zLCAmbmV3cG9zKTsKKyAgICAgICAgICAgIGlmIChyZXB1bmljb2RlID09IE5VTEwpCisgICAgICAgICAgICAgICAgZ290byBvbkVycm9yOworICAgICAgICAgICAgLyogZ2VuZXJhdGUgcmVwbGFjZW1lbnQgICovCisgICAgICAgICAgICByZXBzaXplID0gUHlVbmljb2RlX0dFVF9TSVpFKHJlcHVuaWNvZGUpOworICAgICAgICAgICAgZm9yICh1bmkyID0gUHlVbmljb2RlX0FTX1VOSUNPREUocmVwdW5pY29kZSk7IHJlcHNpemUtLT4wOyArK3VuaTIpIHsKKyAgICAgICAgICAgICAgICBQeV9VTklDT0RFIGNoID0gKnVuaTI7CisgICAgICAgICAgICAgICAgaWYgKFB5X1VOSUNPREVfSVNTUEFDRShjaCkpCisgICAgICAgICAgICAgICAgICAgICpvdXRwdXQrKyA9ICcgJzsKKyAgICAgICAgICAgICAgICBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgZGVjaW1hbCA9IFB5X1VOSUNPREVfVE9ERUNJTUFMKGNoKTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKGRlY2ltYWwgPj0gMCkKKyAgICAgICAgICAgICAgICAgICAgICAgICpvdXRwdXQrKyA9ICcwJyArIGRlY2ltYWw7CisgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKDAgPCBjaCAmJiBjaCA8IDI1NikKKyAgICAgICAgICAgICAgICAgICAgICAgICpvdXRwdXQrKyA9IChjaGFyKWNoOworICAgICAgICAgICAgICAgICAgICBlbHNlIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIFB5X0RFQ1JFRihyZXB1bmljb2RlKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIHJhaXNlX2VuY29kZV9leGNlcHRpb24oJmV4YywgZW5jb2RpbmcsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHMsIGxlbmd0aCwgY29sbHN0YXJ0LXMsIGNvbGxlbmQtcywgcmVhc29uKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGdvdG8gb25FcnJvcjsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHAgPSBzICsgbmV3cG9zOworICAgICAgICAgICAgUHlfREVDUkVGKHJlcHVuaWNvZGUpOworICAgICAgICB9CisgICAgfQorICAgIC8qIDAtdGVybWluYXRlIHRoZSBvdXRwdXQgc3RyaW5nICovCisgICAgKm91dHB1dCsrID0gJ1wwJzsKKyAgICBQeV9YREVDUkVGKGV4Yyk7CisgICAgUHlfWERFQ1JFRihlcnJvckhhbmRsZXIpOworICAgIHJldHVybiAwOworCisgIG9uRXJyb3I6CisgICAgUHlfWERFQ1JFRihleGMpOworICAgIFB5X1hERUNSRUYoZXJyb3JIYW5kbGVyKTsKKyAgICByZXR1cm4gLTE7Cit9CisKKy8qIC0tLSBIZWxwZXJzIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLworCisjaW5jbHVkZSAic3RyaW5nbGliL3VuaWNvZGVkZWZzLmgiCisjaW5jbHVkZSAic3RyaW5nbGliL2Zhc3RzZWFyY2guaCIKKworI2luY2x1ZGUgInN0cmluZ2xpYi9jb3VudC5oIgorI2luY2x1ZGUgInN0cmluZ2xpYi9maW5kLmgiCisjaW5jbHVkZSAic3RyaW5nbGliL3BhcnRpdGlvbi5oIgorI2luY2x1ZGUgInN0cmluZ2xpYi9zcGxpdC5oIgorCisvKiBoZWxwZXIgbWFjcm8gdG8gZml4dXAgc3RhcnQvZW5kIHNsaWNlIHZhbHVlcyAqLworI2RlZmluZSBBREpVU1RfSU5ESUNFUyhzdGFydCwgZW5kLCBsZW4pICAgICAgICAgXAorICAgIGlmIChlbmQgPiBsZW4pICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICBlbmQgPSBsZW47ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIGVsc2UgaWYgKGVuZCA8IDApIHsgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICBlbmQgKz0gbGVuOyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICBpZiAoZW5kIDwgMCkgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgICAgZW5kID0gMDsgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIH0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIGlmIChzdGFydCA8IDApIHsgICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICBzdGFydCArPSBsZW47ICAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICBpZiAoc3RhcnQgPCAwKSAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgICAgICAgICAgc3RhcnQgPSAwOyAgICAgICAgICAgICAgICAgICAgICAgICAgXAorICAgIH0KKworUHlfc3NpemVfdCBQeVVuaWNvZGVfQ291bnQoUHlPYmplY3QgKnN0ciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIFB5T2JqZWN0ICpzdWJzdHIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBQeV9zc2l6ZV90IHN0YXJ0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgUHlfc3NpemVfdCBlbmQpCit7CisgICAgUHlfc3NpemVfdCByZXN1bHQ7CisgICAgUHlVbmljb2RlT2JqZWN0KiBzdHJfb2JqOworICAgIFB5VW5pY29kZU9iamVjdCogc3ViX29iajsKKworICAgIHN0cl9vYmogPSAoUHlVbmljb2RlT2JqZWN0KikgUHlVbmljb2RlX0Zyb21PYmplY3Qoc3RyKTsKKyAgICBpZiAoIXN0cl9vYmopCisgICAgICAgIHJldHVybiAtMTsKKyAgICBzdWJfb2JqID0gKFB5VW5pY29kZU9iamVjdCopIFB5VW5pY29kZV9Gcm9tT2JqZWN0KHN1YnN0cik7CisgICAgaWYgKCFzdWJfb2JqKSB7CisgICAgICAgIFB5X0RFQ1JFRihzdHJfb2JqKTsKKyAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKworICAgIEFESlVTVF9JTkRJQ0VTKHN0YXJ0LCBlbmQsIHN0cl9vYmotPmxlbmd0aCk7CisgICAgcmVzdWx0ID0gc3RyaW5nbGliX2NvdW50KAorICAgICAgICBzdHJfb2JqLT5zdHIgKyBzdGFydCwgZW5kIC0gc3RhcnQsIHN1Yl9vYmotPnN0ciwgc3ViX29iai0+bGVuZ3RoLAorICAgICAgICBQWV9TU0laRV9UX01BWAorICAgICAgICApOworCisgICAgUHlfREVDUkVGKHN1Yl9vYmopOworICAgIFB5X0RFQ1JFRihzdHJfb2JqKTsKKworICAgIHJldHVybiByZXN1bHQ7Cit9CisKK1B5X3NzaXplX3QgUHlVbmljb2RlX0ZpbmQoUHlPYmplY3QgKnN0ciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgUHlPYmplY3QgKnN1YiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgUHlfc3NpemVfdCBzdGFydCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgUHlfc3NpemVfdCBlbmQsCisgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBkaXJlY3Rpb24pCit7CisgICAgUHlfc3NpemVfdCByZXN1bHQ7CisKKyAgICBzdHIgPSBQeVVuaWNvZGVfRnJvbU9iamVjdChzdHIpOworICAgIGlmICghc3RyKQorICAgICAgICByZXR1cm4gLTI7CisgICAgc3ViID0gUHlVbmljb2RlX0Zyb21PYmplY3Qoc3ViKTsKKyAgICBpZiAoIXN1YikgeworICAgICAgICBQeV9ERUNSRUYoc3RyKTsKKyAgICAgICAgcmV0dXJuIC0yOworICAgIH0KKworICAgIGlmIChkaXJlY3Rpb24gPiAwKQorICAgICAgICByZXN1bHQgPSBzdHJpbmdsaWJfZmluZF9zbGljZSgKKyAgICAgICAgICAgIFB5VW5pY29kZV9BU19VTklDT0RFKHN0ciksIFB5VW5pY29kZV9HRVRfU0laRShzdHIpLAorICAgICAgICAgICAgUHlVbmljb2RlX0FTX1VOSUNPREUoc3ViKSwgUHlVbmljb2RlX0dFVF9TSVpFKHN1YiksCisgICAgICAgICAgICBzdGFydCwgZW5kCisgICAgICAgICAgICApOworICAgIGVsc2UKKyAgICAgICAgcmVzdWx0ID0gc3RyaW5nbGliX3JmaW5kX3NsaWNlKAorICAgICAgICAgICAgUHlVbmljb2RlX0FTX1VOSUNPREUoc3RyKSwgUHlVbmljb2RlX0dFVF9TSVpFKHN0ciksCisgICAgICAgICAgICBQeVVuaWNvZGVfQVNfVU5JQ09ERShzdWIpLCBQeVVuaWNvZGVfR0VUX1NJWkUoc3ViKSwKKyAgICAgICAgICAgIHN0YXJ0LCBlbmQKKyAgICAgICAgICAgICk7CisKKyAgICBQeV9ERUNSRUYoc3RyKTsKKyAgICBQeV9ERUNSRUYoc3ViKTsKKworICAgIHJldHVybiByZXN1bHQ7Cit9CisKK3N0YXRpYworaW50IHRhaWxtYXRjaChQeVVuaWNvZGVPYmplY3QgKnNlbGYsCisgICAgICAgICAgICAgIFB5VW5pY29kZU9iamVjdCAqc3Vic3RyaW5nLAorICAgICAgICAgICAgICBQeV9zc2l6ZV90IHN0YXJ0LAorICAgICAgICAgICAgICBQeV9zc2l6ZV90IGVuZCwKKyAgICAgICAgICAgICAgaW50IGRpcmVjdGlvbikKK3sKKyAgICBpZiAoc3Vic3RyaW5nLT5sZW5ndGggPT0gMCkKKyAgICAgICAgcmV0dXJuIDE7CisKKyAgICBBREpVU1RfSU5ESUNFUyhzdGFydCwgZW5kLCBzZWxmLT5sZW5ndGgpOworICAgIGVuZCAtPSBzdWJzdHJpbmctPmxlbmd0aDsKKyAgICBpZiAoZW5kIDwgc3RhcnQpCisgICAgICAgIHJldHVybiAwOworCisgICAgaWYgKGRpcmVjdGlvbiA+IDApIHsKKyAgICAgICAgaWYgKFB5X1VOSUNPREVfTUFUQ0goc2VsZiwgZW5kLCBzdWJzdHJpbmcpKQorICAgICAgICAgICAgcmV0dXJuIDE7CisgICAgfSBlbHNlIHsKKyAgICAgICAgaWYgKFB5X1VOSUNPREVfTUFUQ0goc2VsZiwgc3RhcnQsIHN1YnN0cmluZykpCisgICAgICAgICAgICByZXR1cm4gMTsKKyAgICB9CisKKyAgICByZXR1cm4gMDsKK30KKworUHlfc3NpemVfdCBQeVVuaWNvZGVfVGFpbG1hdGNoKFB5T2JqZWN0ICpzdHIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHlPYmplY3QgKnN1YnN0ciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQeV9zc2l6ZV90IHN0YXJ0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFB5X3NzaXplX3QgZW5kLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBkaXJlY3Rpb24pCit7CisgICAgUHlfc3NpemVfdCByZXN1bHQ7CisKKyAgICBzdHIgPSBQeVVuaWNvZGVfRnJvbU9iamVjdChzdHIpOworICAgIGlmIChzdHIgPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIC0xOworICAgIHN1YnN0ciA9IFB5VW5pY29kZV9Gcm9tT2JqZWN0KHN1YnN0cik7CisgICAgaWYgKHN1YnN0ciA9PSBOVUxMKSB7CisgICAgICAgIFB5X0RFQ1JFRihzdHIpOworICAgICAgICByZXR1cm4gLTE7CisgICAgfQorCisgICAgcmVzdWx0ID0gdGFpbG1hdGNoKChQeVVuaWNvZGVPYmplY3QgKilzdHIsCisgICAgICAgICAgICAgICAgICAgICAgIChQeVVuaWNvZGVPYmplY3QgKilzdWJzdHIsCisgICAgICAgICAgICAgICAgICAgICAgIHN0YXJ0LCBlbmQsIGRpcmVjdGlvbik7CisgICAgUHlfREVDUkVGKHN0cik7CisgICAgUHlfREVDUkVGKHN1YnN0cik7CisgICAgcmV0dXJuIHJlc3VsdDsKK30KKworLyogQXBwbHkgZml4ZmN0IGZpbHRlciB0byB0aGUgVW5pY29kZSBvYmplY3Qgc2VsZiBhbmQgcmV0dXJuIGEKKyAgIHJlZmVyZW5jZSB0byB0aGUgbW9kaWZpZWQgb2JqZWN0ICovCisKK3N0YXRpYworUHlPYmplY3QgKmZpeHVwKFB5VW5pY29kZU9iamVjdCAqc2VsZiwKKyAgICAgICAgICAgICAgICBpbnQgKCpmaXhmY3QpKFB5VW5pY29kZU9iamVjdCAqcykpCit7CisKKyAgICBQeVVuaWNvZGVPYmplY3QgKnU7CisKKyAgICB1ID0gKFB5VW5pY29kZU9iamVjdCopIFB5VW5pY29kZV9Gcm9tVW5pY29kZShOVUxMLCBzZWxmLT5sZW5ndGgpOworICAgIGlmICh1ID09IE5VTEwpCisgICAgICAgIHJldHVybiBOVUxMOworCisgICAgUHlfVU5JQ09ERV9DT1BZKHUtPnN0ciwgc2VsZi0+c3RyLCBzZWxmLT5sZW5ndGgpOworCisgICAgaWYgKCFmaXhmY3QodSkgJiYgUHlVbmljb2RlX0NoZWNrRXhhY3Qoc2VsZikpIHsKKyAgICAgICAgLyogZml4ZmN0IHNob3VsZCByZXR1cm4gVFJVRSBpZiBpdCBtb2RpZmllZCB0aGUgYnVmZmVyLiBJZgorICAgICAgICAgICBGQUxTRSwgcmV0dXJuIGEgcmVmZXJlbmNlIHRvIHRoZSBvcmlnaW5hbCBidWZmZXIgaW5zdGVhZAorICAgICAgICAgICAodG8gc2F2ZSBzcGFjZSwgbm90IHRpbWUpICovCisgICAgICAgIFB5X0lOQ1JFRihzZWxmKTsKKyAgICAgICAgUHlfREVDUkVGKHUpOworICAgICAgICByZXR1cm4gKFB5T2JqZWN0Kikgc2VsZjsKKyAgICB9CisgICAgcmV0dXJuIChQeU9iamVjdCopIHU7Cit9CisKK3N0YXRpYworaW50IGZpeHVwcGVyKFB5VW5pY29kZU9iamVjdCAqc2VsZikKK3sKKyAgICBQeV9zc2l6ZV90IGxlbiA9IHNlbGYtPmxlbmd0aDsKKyAgICBQeV9VTklDT0RFICpzID0gc2VsZi0+c3RyOworICAgIGludCBzdGF0dXMgPSAwOworCisgICAgd2hpbGUgKGxlbi0tID4gMCkgeworICAgICAgICByZWdpc3RlciBQeV9VTklDT0RFIGNoOworCisgICAgICAgIGNoID0gUHlfVU5JQ09ERV9UT1VQUEVSKCpzKTsKKyAgICAgICAgaWYgKGNoICE9ICpzKSB7CisgICAgICAgICAgICBzdGF0dXMgPSAxOworICAgICAgICAgICAgKnMgPSBjaDsKKyAgICAgICAgfQorICAgICAgICBzKys7CisgICAgfQorCisgICAgcmV0dXJuIHN0YXR1czsKK30KKworc3RhdGljCitpbnQgZml4bG93ZXIoUHlVbmljb2RlT2JqZWN0ICpzZWxmKQoreworICAgIFB5X3NzaXplX3QgbGVuID0gc2VsZi0+bGVuZ3RoOworICAgIFB5X1VOSUNPREUgKnMgPSBzZWxmLT5zdHI7CisgICAgaW50IHN0YXR1cyA9IDA7CisKKyAgICB3aGlsZSAobGVuLS0gPiAwKSB7CisgICAgICAgIHJlZ2lzdGVyIFB5X1VOSUNPREUgY2g7CisKKyAgICAgICAgY2ggPSBQeV9VTklDT0RFX1RPTE9XRVIoKnMpOworICAgICAgICBpZiAoY2ggIT0gKnMpIHsKKyAgICAgICAgICAgIHN0YXR1cyA9IDE7CisgICAgICAgICAgICAqcyA9IGNoOworICAgICAgICB9CisgICAgICAgIHMrKzsKKyAgICB9CisKKyAgICByZXR1cm4gc3RhdHVzOworfQorCitzdGF0aWMKK2ludCBmaXhzd2FwY2FzZShQeVVuaWNvZGVPYmplY3QgKnNlbGYpCit7CisgICAgUHlfc3NpemVfdCBsZW4gPSBzZWxmLT5sZW5ndGg7CisgICAgUHlfVU5JQ09ERSAqcyA9IHNlbGYtPnN0cjsKKyAgICBpbnQgc3RhdHVzID0gMDsKKworICAgIHdoaWxlIChsZW4tLSA+IDApIHsKKyAgICAgICAgaWYgKFB5X1VOSUNPREVfSVNVUFBFUigqcykpIHsKKyAgICAgICAgICAgICpzID0gUHlfVU5JQ09ERV9UT0xPV0VSKCpzKTsKKyAgICAgICAgICAgIHN0YXR1cyA9IDE7CisgICAgICAgIH0gZWxzZSBpZiAoUHlfVU5JQ09ERV9JU0xPV0VSKCpzKSkgeworICAgICAgICAgICAgKnMgPSBQeV9VTklDT0RFX1RPVVBQRVIoKnMpOworICAgICAgICAgICAgc3RhdHVzID0gMTsKKyAgICAgICAgfQorICAgICAgICBzKys7CisgICAgfQorCisgICAgcmV0dXJuIHN0YXR1czsKK30KKworc3RhdGljCitpbnQgZml4Y2FwaXRhbGl6ZShQeVVuaWNvZGVPYmplY3QgKnNlbGYpCit7CisgICAgUHlfc3NpemVfdCBsZW4gPSBzZWxmLT5sZW5ndGg7CisgICAgUHlfVU5JQ09ERSAqcyA9IHNlbGYtPnN0cjsKKyAgICBpbnQgc3RhdHVzID0gMDsKKworICAgIGlmIChsZW4gPT0gMCkKKyAgICAgICAgcmV0dXJuIDA7CisgICAgaWYgKCFQeV9VTklDT0RFX0lTVVBQRVIoKnMpKSB7CisgICAgICAgICpzID0gUHlfVU5JQ09ERV9UT1VQUEVSKCpzKTsKKyAgICAgICAgc3RhdHVzID0gMTsKKyAgICB9CisgICAgcysrOworICAgIHdoaWxlICgtLWxlbiA+IDApIHsKKyAgICAgICAgaWYgKCFQeV9VTklDT0RFX0lTTE9XRVIoKnMpKSB7CisgICAgICAgICAgICAqcyA9IFB5X1VOSUNPREVfVE9MT1dFUigqcyk7CisgICAgICAgICAgICBzdGF0dXMgPSAxOworICAgICAgICB9CisgICAgICAgIHMrKzsKKyAgICB9CisgICAgcmV0dXJuIHN0YXR1czsKK30KKworc3RhdGljCitpbnQgZml4dGl0bGUoUHlVbmljb2RlT2JqZWN0ICpzZWxmKQoreworICAgIHJlZ2lzdGVyIFB5X1VOSUNPREUgKnAgPSBQeVVuaWNvZGVfQVNfVU5JQ09ERShzZWxmKTsKKyAgICByZWdpc3RlciBQeV9VTklDT0RFICplOworICAgIGludCBwcmV2aW91c19pc19jYXNlZDsKKworICAgIC8qIFNob3J0Y3V0IGZvciBzaW5nbGUgY2hhcmFjdGVyIHN0cmluZ3MgKi8KKyAgICBpZiAoUHlVbmljb2RlX0dFVF9TSVpFKHNlbGYpID09IDEpIHsKKyAgICAgICAgUHlfVU5JQ09ERSBjaCA9IFB5X1VOSUNPREVfVE9USVRMRSgqcCk7CisgICAgICAgIGlmICgqcCAhPSBjaCkgeworICAgICAgICAgICAgKnAgPSBjaDsKKyAgICAgICAgICAgIHJldHVybiAxOworICAgICAgICB9CisgICAgICAgIGVsc2UKKyAgICAgICAgICAgIHJldHVybiAwOworICAgIH0KKworICAgIGUgPSBwICsgUHlVbmljb2RlX0dFVF9TSVpFKHNlbGYpOworICAgIHByZXZpb3VzX2lzX2Nhc2VkID0gMDsKKyAgICBmb3IgKDsgcCA8IGU7IHArKykgeworICAgICAgICByZWdpc3RlciBjb25zdCBQeV9VTklDT0RFIGNoID0gKnA7CisKKyAgICAgICAgaWYgKHByZXZpb3VzX2lzX2Nhc2VkKQorICAgICAgICAgICAgKnAgPSBQeV9VTklDT0RFX1RPTE9XRVIoY2gpOworICAgICAgICBlbHNlCisgICAgICAgICAgICAqcCA9IFB5X1VOSUNPREVfVE9USVRMRShjaCk7CisKKyAgICAgICAgaWYgKFB5X1VOSUNPREVfSVNMT1dFUihjaCkgfHwKKyAgICAgICAgICAgIFB5X1VOSUNPREVfSVNVUFBFUihjaCkgfHwKKyAgICAgICAgICAgIFB5X1VOSUNPREVfSVNUSVRMRShjaCkpCisgICAgICAgICAgICBwcmV2aW91c19pc19jYXNlZCA9IDE7CisgICAgICAgIGVsc2UKKyAgICAgICAgICAgIHByZXZpb3VzX2lzX2Nhc2VkID0gMDsKKyAgICB9CisgICAgcmV0dXJuIDE7Cit9CisKK1B5T2JqZWN0ICoKK1B5VW5pY29kZV9Kb2luKFB5T2JqZWN0ICpzZXBhcmF0b3IsIFB5T2JqZWN0ICpzZXEpCit7CisgICAgUHlPYmplY3QgKmludGVybmFsX3NlcGFyYXRvciA9IE5VTEw7CisgICAgY29uc3QgUHlfVU5JQ09ERSBibGFuayA9ICcgJzsKKyAgICBjb25zdCBQeV9VTklDT0RFICpzZXAgPSAmYmxhbms7CisgICAgUHlfc3NpemVfdCBzZXBsZW4gPSAxOworICAgIFB5VW5pY29kZU9iamVjdCAqcmVzID0gTlVMTDsgLyogdGhlIHJlc3VsdCAqLworICAgIFB5X3NzaXplX3QgcmVzX2FsbG9jID0gMTAwOyAgLyogIyBhbGxvY2F0ZWQgYnl0ZXMgZm9yIHN0cmluZyBpbiByZXMgKi8KKyAgICBQeV9zc2l6ZV90IHJlc191c2VkOyAgICAgICAgIC8qICMgdXNlZCBieXRlcyAqLworICAgIFB5X1VOSUNPREUgKnJlc19wOyAgICAgICAvKiBwb2ludGVyIHRvIGZyZWUgYnl0ZSBpbiByZXMncyBzdHJpbmcgYXJlYSAqLworICAgIFB5T2JqZWN0ICpmc2VxOyAgICAgICAgICAvKiBQeVNlcXVlbmNlX0Zhc3Qoc2VxKSAqLworICAgIFB5X3NzaXplX3Qgc2VxbGVuOyAgICAgICAgICAgICAgLyogbGVuKGZzZXEpIC0tIG51bWJlciBvZiBpdGVtcyBpbiBzZXF1ZW5jZSAqLworICAgIFB5T2JqZWN0ICppdGVtOworICAgIFB5X3NzaXplX3QgaTsKKworICAgIGZzZXEgPSBQeVNlcXVlbmNlX0Zhc3Qoc2VxLCAiIik7CisgICAgaWYgKGZzZXEgPT0gTlVMTCkgeworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisKKyAgICAvKiBHcnJyci4gIEEgY29kZWMgbWF5IGJlIGludm9rZWQgdG8gY29udmVydCBzdHIgb2JqZWN0cyB0bworICAgICAqIFVuaWNvZGUsIGFuZCBzbyBpdCdzIHBvc3NpYmxlIHRvIGNhbGwgYmFjayBpbnRvIFB5dGhvbiBjb2RlCisgICAgICogZHVyaW5nIFB5VW5pY29kZV9Gcm9tT2JqZWN0KCksIGFuZCBzbyBpdCdzIHBvc3NpYmxlIGZvciBhIHNpY2sKKyAgICAgKiBjb2RlYyB0byBjaGFuZ2UgdGhlIHNpemUgb2YgZnNlcSAoaWYgc2VxIGlzIGEgbGlzdCkuICBUaGVyZWZvcmUKKyAgICAgKiB3ZSBoYXZlIHRvIGtlZXAgcmVmZXRjaGluZyB0aGUgc2l6ZSAtLSBjYW4ndCBhc3N1bWUgc2VxbGVuCisgICAgICogaXMgaW52YXJpYW50LgorICAgICAqLworICAgIHNlcWxlbiA9IFB5U2VxdWVuY2VfRmFzdF9HRVRfU0laRShmc2VxKTsKKyAgICAvKiBJZiBlbXB0eSBzZXF1ZW5jZSwgcmV0dXJuIHUiIi4gKi8KKyAgICBpZiAoc2VxbGVuID09IDApIHsKKyAgICAgICAgcmVzID0gX1B5VW5pY29kZV9OZXcoMCk7ICAvKiBlbXB0eSBzZXF1ZW5jZTsgcmV0dXJuIHUiIiAqLworICAgICAgICBnb3RvIERvbmU7CisgICAgfQorICAgIC8qIElmIHNpbmdsZXRvbiBzZXF1ZW5jZSB3aXRoIGFuIGV4YWN0IFVuaWNvZGUsIHJldHVybiB0aGF0LiAqLworICAgIGlmIChzZXFsZW4gPT0gMSkgeworICAgICAgICBpdGVtID0gUHlTZXF1ZW5jZV9GYXN0X0dFVF9JVEVNKGZzZXEsIDApOworICAgICAgICBpZiAoUHlVbmljb2RlX0NoZWNrRXhhY3QoaXRlbSkpIHsKKyAgICAgICAgICAgIFB5X0lOQ1JFRihpdGVtKTsKKyAgICAgICAgICAgIHJlcyA9IChQeVVuaWNvZGVPYmplY3QgKilpdGVtOworICAgICAgICAgICAgZ290byBEb25lOworICAgICAgICB9CisgICAgfQorCisgICAgLyogQXQgbGVhc3QgdHdvIGl0ZW1zIHRvIGpvaW4sIG9yIG9uZSB0aGF0IGlzbid0IGV4YWN0IFVuaWNvZGUuICovCisgICAgaWYgKHNlcWxlbiA+IDEpIHsKKyAgICAgICAgLyogU2V0IHVwIHNlcCBhbmQgc2VwbGVuIC0tIHRoZXkncmUgbmVlZGVkLiAqLworICAgICAgICBpZiAoc2VwYXJhdG9yID09IE5VTEwpIHsKKyAgICAgICAgICAgIHNlcCA9ICZibGFuazsKKyAgICAgICAgICAgIHNlcGxlbiA9IDE7CisgICAgICAgIH0KKyAgICAgICAgZWxzZSB7CisgICAgICAgICAgICBpbnRlcm5hbF9zZXBhcmF0b3IgPSBQeVVuaWNvZGVfRnJvbU9iamVjdChzZXBhcmF0b3IpOworICAgICAgICAgICAgaWYgKGludGVybmFsX3NlcGFyYXRvciA9PSBOVUxMKQorICAgICAgICAgICAgICAgIGdvdG8gb25FcnJvcjsKKyAgICAgICAgICAgIHNlcCA9IFB5VW5pY29kZV9BU19VTklDT0RFKGludGVybmFsX3NlcGFyYXRvcik7CisgICAgICAgICAgICBzZXBsZW4gPSBQeVVuaWNvZGVfR0VUX1NJWkUoaW50ZXJuYWxfc2VwYXJhdG9yKTsKKyAgICAgICAgICAgIC8qIEluIGNhc2UgUHlVbmljb2RlX0Zyb21PYmplY3QoKSBtdXRhdGVkIHNlcS4gKi8KKyAgICAgICAgICAgIHNlcWxlbiA9IFB5U2VxdWVuY2VfRmFzdF9HRVRfU0laRShmc2VxKTsKKyAgICAgICAgfQorICAgIH0KKworICAgIC8qIEdldCBzcGFjZS4gKi8KKyAgICByZXMgPSBfUHlVbmljb2RlX05ldyhyZXNfYWxsb2MpOworICAgIGlmIChyZXMgPT0gTlVMTCkKKyAgICAgICAgZ290byBvbkVycm9yOworICAgIHJlc19wID0gUHlVbmljb2RlX0FTX1VOSUNPREUocmVzKTsKKyAgICByZXNfdXNlZCA9IDA7CisKKyAgICBmb3IgKGkgPSAwOyBpIDwgc2VxbGVuOyArK2kpIHsKKyAgICAgICAgUHlfc3NpemVfdCBpdGVtbGVuOworICAgICAgICBQeV9zc2l6ZV90IG5ld19yZXNfdXNlZDsKKworICAgICAgICBpdGVtID0gUHlTZXF1ZW5jZV9GYXN0X0dFVF9JVEVNKGZzZXEsIGkpOworICAgICAgICAvKiBDb252ZXJ0IGl0ZW0gdG8gVW5pY29kZS4gKi8KKyAgICAgICAgaWYgKCEgUHlVbmljb2RlX0NoZWNrKGl0ZW0pICYmICEgUHlTdHJpbmdfQ2hlY2soaXRlbSkpIHsKKyAgICAgICAgICAgIFB5RXJyX0Zvcm1hdChQeUV4Y19UeXBlRXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgInNlcXVlbmNlIGl0ZW0gJXpkOiBleHBlY3RlZCBzdHJpbmcgb3IgVW5pY29kZSwiCisgICAgICAgICAgICAgICAgICAgICAgICAgIiAlLjgwcyBmb3VuZCIsCisgICAgICAgICAgICAgICAgICAgICAgICAgaSwgUHlfVFlQRShpdGVtKS0+dHBfbmFtZSk7CisgICAgICAgICAgICBnb3RvIG9uRXJyb3I7CisgICAgICAgIH0KKyAgICAgICAgaXRlbSA9IFB5VW5pY29kZV9Gcm9tT2JqZWN0KGl0ZW0pOworICAgICAgICBpZiAoaXRlbSA9PSBOVUxMKQorICAgICAgICAgICAgZ290byBvbkVycm9yOworICAgICAgICAvKiBXZSBvd24gYSByZWZlcmVuY2UgdG8gaXRlbSBmcm9tIGhlcmUgb24uICovCisKKyAgICAgICAgLyogSW4gY2FzZSBQeVVuaWNvZGVfRnJvbU9iamVjdCgpIG11dGF0ZWQgc2VxLiAqLworICAgICAgICBzZXFsZW4gPSBQeVNlcXVlbmNlX0Zhc3RfR0VUX1NJWkUoZnNlcSk7CisKKyAgICAgICAgLyogTWFrZSBzdXJlIHdlIGhhdmUgZW5vdWdoIHNwYWNlIGZvciB0aGUgc2VwYXJhdG9yIGFuZCB0aGUgaXRlbS4gKi8KKyAgICAgICAgaXRlbWxlbiA9IFB5VW5pY29kZV9HRVRfU0laRShpdGVtKTsKKyAgICAgICAgbmV3X3Jlc191c2VkID0gcmVzX3VzZWQgKyBpdGVtbGVuOworICAgICAgICBpZiAobmV3X3Jlc191c2VkIDwgMCkKKyAgICAgICAgICAgIGdvdG8gT3ZlcmZsb3c7CisgICAgICAgIGlmIChpIDwgc2VxbGVuIC0gMSkgeworICAgICAgICAgICAgbmV3X3Jlc191c2VkICs9IHNlcGxlbjsKKyAgICAgICAgICAgIGlmIChuZXdfcmVzX3VzZWQgPCAwKQorICAgICAgICAgICAgICAgIGdvdG8gT3ZlcmZsb3c7CisgICAgICAgIH0KKyAgICAgICAgaWYgKG5ld19yZXNfdXNlZCA+IHJlc19hbGxvYykgeworICAgICAgICAgICAgLyogZG91YmxlIGFsbG9jYXRlZCBzaXplIHVudGlsIGl0J3MgYmlnIGVub3VnaCAqLworICAgICAgICAgICAgZG8geworICAgICAgICAgICAgICAgIHJlc19hbGxvYyArPSByZXNfYWxsb2M7CisgICAgICAgICAgICAgICAgaWYgKHJlc19hbGxvYyA8PSAwKQorICAgICAgICAgICAgICAgICAgICBnb3RvIE92ZXJmbG93OworICAgICAgICAgICAgfSB3aGlsZSAobmV3X3Jlc191c2VkID4gcmVzX2FsbG9jKTsKKyAgICAgICAgICAgIGlmIChfUHlVbmljb2RlX1Jlc2l6ZSgmcmVzLCByZXNfYWxsb2MpIDwgMCkgeworICAgICAgICAgICAgICAgIFB5X0RFQ1JFRihpdGVtKTsKKyAgICAgICAgICAgICAgICBnb3RvIG9uRXJyb3I7CisgICAgICAgICAgICB9CisgICAgICAgICAgICByZXNfcCA9IFB5VW5pY29kZV9BU19VTklDT0RFKHJlcykgKyByZXNfdXNlZDsKKyAgICAgICAgfQorCisgICAgICAgIC8qIENvcHkgaXRlbSwgYW5kIG1heWJlIHRoZSBzZXBhcmF0b3IuICovCisgICAgICAgIFB5X1VOSUNPREVfQ09QWShyZXNfcCwgUHlVbmljb2RlX0FTX1VOSUNPREUoaXRlbSksIGl0ZW1sZW4pOworICAgICAgICByZXNfcCArPSBpdGVtbGVuOworICAgICAgICBpZiAoaSA8IHNlcWxlbiAtIDEpIHsKKyAgICAgICAgICAgIFB5X1VOSUNPREVfQ09QWShyZXNfcCwgc2VwLCBzZXBsZW4pOworICAgICAgICAgICAgcmVzX3AgKz0gc2VwbGVuOworICAgICAgICB9CisgICAgICAgIFB5X0RFQ1JFRihpdGVtKTsKKyAgICAgICAgcmVzX3VzZWQgPSBuZXdfcmVzX3VzZWQ7CisgICAgfQorCisgICAgLyogU2hyaW5rIHJlcyB0byBtYXRjaCB0aGUgdXNlZCBhcmVhOyB0aGlzIHByb2JhYmx5IGNhbid0IGZhaWwsCisgICAgICogYnV0IGl0J3MgY2hlYXAgdG8gY2hlY2suCisgICAgICovCisgICAgaWYgKF9QeVVuaWNvZGVfUmVzaXplKCZyZXMsIHJlc191c2VkKSA8IDApCisgICAgICAgIGdvdG8gb25FcnJvcjsKKworICBEb25lOgorICAgIFB5X1hERUNSRUYoaW50ZXJuYWxfc2VwYXJhdG9yKTsKKyAgICBQeV9ERUNSRUYoZnNlcSk7CisgICAgcmV0dXJuIChQeU9iamVjdCAqKXJlczsKKworICBPdmVyZmxvdzoKKyAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfT3ZlcmZsb3dFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgImpvaW4oKSByZXN1bHQgaXMgdG9vIGxvbmcgZm9yIGEgUHl0aG9uIHN0cmluZyIpOworICAgIFB5X0RFQ1JFRihpdGVtKTsKKyAgICAvKiBmYWxsIHRocm91Z2ggKi8KKworICBvbkVycm9yOgorICAgIFB5X1hERUNSRUYoaW50ZXJuYWxfc2VwYXJhdG9yKTsKKyAgICBQeV9ERUNSRUYoZnNlcSk7CisgICAgUHlfWERFQ1JFRihyZXMpOworICAgIHJldHVybiBOVUxMOworfQorCitzdGF0aWMKK1B5VW5pY29kZU9iamVjdCAqcGFkKFB5VW5pY29kZU9iamVjdCAqc2VsZiwKKyAgICAgICAgICAgICAgICAgICAgIFB5X3NzaXplX3QgbGVmdCwKKyAgICAgICAgICAgICAgICAgICAgIFB5X3NzaXplX3QgcmlnaHQsCisgICAgICAgICAgICAgICAgICAgICBQeV9VTklDT0RFIGZpbGwpCit7CisgICAgUHlVbmljb2RlT2JqZWN0ICp1OworCisgICAgaWYgKGxlZnQgPCAwKQorICAgICAgICBsZWZ0ID0gMDsKKyAgICBpZiAocmlnaHQgPCAwKQorICAgICAgICByaWdodCA9IDA7CisKKyAgICBpZiAobGVmdCA9PSAwICYmIHJpZ2h0ID09IDAgJiYgUHlVbmljb2RlX0NoZWNrRXhhY3Qoc2VsZikpIHsKKyAgICAgICAgUHlfSU5DUkVGKHNlbGYpOworICAgICAgICByZXR1cm4gc2VsZjsKKyAgICB9CisKKyAgICBpZiAobGVmdCA+IFBZX1NTSVpFX1RfTUFYIC0gc2VsZi0+bGVuZ3RoIHx8CisgICAgICAgIHJpZ2h0ID4gUFlfU1NJWkVfVF9NQVggLSAobGVmdCArIHNlbGYtPmxlbmd0aCkpIHsKKyAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX092ZXJmbG93RXJyb3IsICJwYWRkZWQgc3RyaW5nIGlzIHRvbyBsb25nIik7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICB1ID0gX1B5VW5pY29kZV9OZXcobGVmdCArIHNlbGYtPmxlbmd0aCArIHJpZ2h0KTsKKyAgICBpZiAodSkgeworICAgICAgICBpZiAobGVmdCkKKyAgICAgICAgICAgIFB5X1VOSUNPREVfRklMTCh1LT5zdHIsIGZpbGwsIGxlZnQpOworICAgICAgICBQeV9VTklDT0RFX0NPUFkodS0+c3RyICsgbGVmdCwgc2VsZi0+c3RyLCBzZWxmLT5sZW5ndGgpOworICAgICAgICBpZiAocmlnaHQpCisgICAgICAgICAgICBQeV9VTklDT0RFX0ZJTEwodS0+c3RyICsgbGVmdCArIHNlbGYtPmxlbmd0aCwgZmlsbCwgcmlnaHQpOworICAgIH0KKworICAgIHJldHVybiB1OworfQorCitQeU9iamVjdCAqUHlVbmljb2RlX1NwbGl0bGluZXMoUHlPYmplY3QgKnN0cmluZywgaW50IGtlZXBlbmRzKQoreworICAgIFB5T2JqZWN0ICpsaXN0OworCisgICAgc3RyaW5nID0gUHlVbmljb2RlX0Zyb21PYmplY3Qoc3RyaW5nKTsKKyAgICBpZiAoc3RyaW5nID09IE5VTEwpCisgICAgICAgIHJldHVybiBOVUxMOworCisgICAgbGlzdCA9IHN0cmluZ2xpYl9zcGxpdGxpbmVzKAorICAgICAgICAoUHlPYmplY3QqKSBzdHJpbmcsIFB5VW5pY29kZV9BU19VTklDT0RFKHN0cmluZyksCisgICAgICAgIFB5VW5pY29kZV9HRVRfU0laRShzdHJpbmcpLCBrZWVwZW5kcyk7CisKKyAgICBQeV9ERUNSRUYoc3RyaW5nKTsKKyAgICByZXR1cm4gbGlzdDsKK30KKworc3RhdGljCitQeU9iamVjdCAqc3BsaXQoUHlVbmljb2RlT2JqZWN0ICpzZWxmLAorICAgICAgICAgICAgICAgIFB5VW5pY29kZU9iamVjdCAqc3Vic3RyaW5nLAorICAgICAgICAgICAgICAgIFB5X3NzaXplX3QgbWF4Y291bnQpCit7CisgICAgaWYgKG1heGNvdW50IDwgMCkKKyAgICAgICAgbWF4Y291bnQgPSBQWV9TU0laRV9UX01BWDsKKworICAgIGlmIChzdWJzdHJpbmcgPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIHN0cmluZ2xpYl9zcGxpdF93aGl0ZXNwYWNlKAorICAgICAgICAgICAgKFB5T2JqZWN0Kikgc2VsZiwgIHNlbGYtPnN0ciwgc2VsZi0+bGVuZ3RoLCBtYXhjb3VudAorICAgICAgICAgICAgKTsKKworICAgIHJldHVybiBzdHJpbmdsaWJfc3BsaXQoCisgICAgICAgIChQeU9iamVjdCopIHNlbGYsICBzZWxmLT5zdHIsIHNlbGYtPmxlbmd0aCwKKyAgICAgICAgc3Vic3RyaW5nLT5zdHIsIHN1YnN0cmluZy0+bGVuZ3RoLAorICAgICAgICBtYXhjb3VudAorICAgICAgICApOworfQorCitzdGF0aWMKK1B5T2JqZWN0ICpyc3BsaXQoUHlVbmljb2RlT2JqZWN0ICpzZWxmLAorICAgICAgICAgICAgICAgICBQeVVuaWNvZGVPYmplY3QgKnN1YnN0cmluZywKKyAgICAgICAgICAgICAgICAgUHlfc3NpemVfdCBtYXhjb3VudCkKK3sKKyAgICBpZiAobWF4Y291bnQgPCAwKQorICAgICAgICBtYXhjb3VudCA9IFBZX1NTSVpFX1RfTUFYOworCisgICAgaWYgKHN1YnN0cmluZyA9PSBOVUxMKQorICAgICAgICByZXR1cm4gc3RyaW5nbGliX3JzcGxpdF93aGl0ZXNwYWNlKAorICAgICAgICAgICAgKFB5T2JqZWN0Kikgc2VsZiwgIHNlbGYtPnN0ciwgc2VsZi0+bGVuZ3RoLCBtYXhjb3VudAorICAgICAgICAgICAgKTsKKworICAgIHJldHVybiBzdHJpbmdsaWJfcnNwbGl0KAorICAgICAgICAoUHlPYmplY3QqKSBzZWxmLCAgc2VsZi0+c3RyLCBzZWxmLT5sZW5ndGgsCisgICAgICAgIHN1YnN0cmluZy0+c3RyLCBzdWJzdHJpbmctPmxlbmd0aCwKKyAgICAgICAgbWF4Y291bnQKKyAgICAgICAgKTsKK30KKworc3RhdGljCitQeU9iamVjdCAqcmVwbGFjZShQeVVuaWNvZGVPYmplY3QgKnNlbGYsCisgICAgICAgICAgICAgICAgICBQeVVuaWNvZGVPYmplY3QgKnN0cjEsCisgICAgICAgICAgICAgICAgICBQeVVuaWNvZGVPYmplY3QgKnN0cjIsCisgICAgICAgICAgICAgICAgICBQeV9zc2l6ZV90IG1heGNvdW50KQoreworICAgIFB5VW5pY29kZU9iamVjdCAqdTsKKworICAgIGlmIChtYXhjb3VudCA8IDApCisgICAgICAgIG1heGNvdW50ID0gUFlfU1NJWkVfVF9NQVg7CisgICAgZWxzZSBpZiAobWF4Y291bnQgPT0gMCB8fCBzZWxmLT5sZW5ndGggPT0gMCkKKyAgICAgICAgZ290byBub3RoaW5nOworCisgICAgaWYgKHN0cjEtPmxlbmd0aCA9PSBzdHIyLT5sZW5ndGgpIHsKKyAgICAgICAgUHlfc3NpemVfdCBpOworICAgICAgICAvKiBzYW1lIGxlbmd0aCAqLworICAgICAgICBpZiAoc3RyMS0+bGVuZ3RoID09IDApCisgICAgICAgICAgICBnb3RvIG5vdGhpbmc7CisgICAgICAgIGlmIChzdHIxLT5sZW5ndGggPT0gMSkgeworICAgICAgICAgICAgLyogcmVwbGFjZSBjaGFyYWN0ZXJzICovCisgICAgICAgICAgICBQeV9VTklDT0RFIHUxLCB1MjsKKyAgICAgICAgICAgIGlmICghZmluZGNoYXIoc2VsZi0+c3RyLCBzZWxmLT5sZW5ndGgsIHN0cjEtPnN0clswXSkpCisgICAgICAgICAgICAgICAgZ290byBub3RoaW5nOworICAgICAgICAgICAgdSA9IChQeVVuaWNvZGVPYmplY3QqKSBQeVVuaWNvZGVfRnJvbVVuaWNvZGUoTlVMTCwgc2VsZi0+bGVuZ3RoKTsKKyAgICAgICAgICAgIGlmICghdSkKKyAgICAgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgICAgIFB5X1VOSUNPREVfQ09QWSh1LT5zdHIsIHNlbGYtPnN0ciwgc2VsZi0+bGVuZ3RoKTsKKyAgICAgICAgICAgIHUxID0gc3RyMS0+c3RyWzBdOworICAgICAgICAgICAgdTIgPSBzdHIyLT5zdHJbMF07CisgICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgdS0+bGVuZ3RoOyBpKyspCisgICAgICAgICAgICAgICAgaWYgKHUtPnN0cltpXSA9PSB1MSkgeworICAgICAgICAgICAgICAgICAgICBpZiAoLS1tYXhjb3VudCA8IDApCisgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICAgICAgdS0+c3RyW2ldID0gdTI7CisgICAgICAgICAgICAgICAgfQorICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgaSA9IHN0cmluZ2xpYl9maW5kKAorICAgICAgICAgICAgICAgIHNlbGYtPnN0ciwgc2VsZi0+bGVuZ3RoLCBzdHIxLT5zdHIsIHN0cjEtPmxlbmd0aCwgMAorICAgICAgICAgICAgICAgICk7CisgICAgICAgICAgICBpZiAoaSA8IDApCisgICAgICAgICAgICAgICAgZ290byBub3RoaW5nOworICAgICAgICAgICAgdSA9IChQeVVuaWNvZGVPYmplY3QqKSBQeVVuaWNvZGVfRnJvbVVuaWNvZGUoTlVMTCwgc2VsZi0+bGVuZ3RoKTsKKyAgICAgICAgICAgIGlmICghdSkKKyAgICAgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgICAgIFB5X1VOSUNPREVfQ09QWSh1LT5zdHIsIHNlbGYtPnN0ciwgc2VsZi0+bGVuZ3RoKTsKKworICAgICAgICAgICAgLyogY2hhbmdlIGV2ZXJ5dGhpbmcgaW4tcGxhY2UsIHN0YXJ0aW5nIHdpdGggdGhpcyBvbmUgKi8KKyAgICAgICAgICAgIFB5X1VOSUNPREVfQ09QWSh1LT5zdHIraSwgc3RyMi0+c3RyLCBzdHIyLT5sZW5ndGgpOworICAgICAgICAgICAgaSArPSBzdHIxLT5sZW5ndGg7CisKKyAgICAgICAgICAgIHdoaWxlICggLS1tYXhjb3VudCA+IDApIHsKKyAgICAgICAgICAgICAgICBpID0gc3RyaW5nbGliX2ZpbmQoc2VsZi0+c3RyK2ksIHNlbGYtPmxlbmd0aC1pLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHIxLT5zdHIsIHN0cjEtPmxlbmd0aCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaSk7CisgICAgICAgICAgICAgICAgaWYgKGkgPT0gLTEpCisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIFB5X1VOSUNPREVfQ09QWSh1LT5zdHIraSwgc3RyMi0+c3RyLCBzdHIyLT5sZW5ndGgpOworICAgICAgICAgICAgICAgIGkgKz0gc3RyMS0+bGVuZ3RoOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfSBlbHNlIHsKKworICAgICAgICBQeV9zc2l6ZV90IG4sIGksIGo7CisgICAgICAgIFB5X3NzaXplX3QgcHJvZHVjdCwgbmV3X3NpemUsIGRlbHRhOworICAgICAgICBQeV9VTklDT0RFICpwOworCisgICAgICAgIC8qIHJlcGxhY2Ugc3RyaW5ncyAqLworICAgICAgICBuID0gc3RyaW5nbGliX2NvdW50KHNlbGYtPnN0ciwgc2VsZi0+bGVuZ3RoLCBzdHIxLT5zdHIsIHN0cjEtPmxlbmd0aCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXhjb3VudCk7CisgICAgICAgIGlmIChuID09IDApCisgICAgICAgICAgICBnb3RvIG5vdGhpbmc7CisgICAgICAgIC8qIG5ld19zaXplID0gc2VsZi0+bGVuZ3RoICsgbiAqIChzdHIyLT5sZW5ndGggLSBzdHIxLT5sZW5ndGgpKTsgKi8KKyAgICAgICAgZGVsdGEgPSAoc3RyMi0+bGVuZ3RoIC0gc3RyMS0+bGVuZ3RoKTsKKyAgICAgICAgaWYgKGRlbHRhID09IDApIHsKKyAgICAgICAgICAgIG5ld19zaXplID0gc2VsZi0+bGVuZ3RoOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgcHJvZHVjdCA9IG4gKiAoc3RyMi0+bGVuZ3RoIC0gc3RyMS0+bGVuZ3RoKTsKKyAgICAgICAgICAgIGlmICgocHJvZHVjdCAvIChzdHIyLT5sZW5ndGggLSBzdHIxLT5sZW5ndGgpKSAhPSBuKSB7CisgICAgICAgICAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX092ZXJmbG93RXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJyZXBsYWNlIHN0cmluZyBpcyB0b28gbG9uZyIpOworICAgICAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgICAgICAgICAgfQorICAgICAgICAgICAgbmV3X3NpemUgPSBzZWxmLT5sZW5ndGggKyBwcm9kdWN0OworICAgICAgICAgICAgaWYgKG5ld19zaXplIDwgMCkgeworICAgICAgICAgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19PdmVyZmxvd0Vycm9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAicmVwbGFjZSBzdHJpbmcgaXMgdG9vIGxvbmciKTsKKyAgICAgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICB1ID0gX1B5VW5pY29kZV9OZXcobmV3X3NpemUpOworICAgICAgICBpZiAoIXUpCisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgaSA9IDA7CisgICAgICAgIHAgPSB1LT5zdHI7CisgICAgICAgIGlmIChzdHIxLT5sZW5ndGggPiAwKSB7CisgICAgICAgICAgICB3aGlsZSAobi0tID4gMCkgeworICAgICAgICAgICAgICAgIC8qIGxvb2sgZm9yIG5leHQgbWF0Y2ggKi8KKyAgICAgICAgICAgICAgICBqID0gc3RyaW5nbGliX2ZpbmQoc2VsZi0+c3RyK2ksIHNlbGYtPmxlbmd0aC1pLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHIxLT5zdHIsIHN0cjEtPmxlbmd0aCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaSk7CisgICAgICAgICAgICAgICAgaWYgKGogPT0gLTEpCisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgIGVsc2UgaWYgKGogPiBpKSB7CisgICAgICAgICAgICAgICAgICAgIC8qIGNvcHkgdW5jaGFuZ2VkIHBhcnQgW2k6al0gKi8KKyAgICAgICAgICAgICAgICAgICAgUHlfVU5JQ09ERV9DT1BZKHAsIHNlbGYtPnN0citpLCBqLWkpOworICAgICAgICAgICAgICAgICAgICBwICs9IGogLSBpOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAvKiBjb3B5IHN1YnN0aXR1dGlvbiBzdHJpbmcgKi8KKyAgICAgICAgICAgICAgICBpZiAoc3RyMi0+bGVuZ3RoID4gMCkgeworICAgICAgICAgICAgICAgICAgICBQeV9VTklDT0RFX0NPUFkocCwgc3RyMi0+c3RyLCBzdHIyLT5sZW5ndGgpOworICAgICAgICAgICAgICAgICAgICBwICs9IHN0cjItPmxlbmd0aDsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgaSA9IGogKyBzdHIxLT5sZW5ndGg7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoaSA8IHNlbGYtPmxlbmd0aCkKKyAgICAgICAgICAgICAgICAvKiBjb3B5IHRhaWwgW2k6XSAqLworICAgICAgICAgICAgICAgIFB5X1VOSUNPREVfQ09QWShwLCBzZWxmLT5zdHIraSwgc2VsZi0+bGVuZ3RoLWkpOworICAgICAgICB9IGVsc2UgeworICAgICAgICAgICAgLyogaW50ZXJsZWF2ZSAqLworICAgICAgICAgICAgd2hpbGUgKG4gPiAwKSB7CisgICAgICAgICAgICAgICAgUHlfVU5JQ09ERV9DT1BZKHAsIHN0cjItPnN0ciwgc3RyMi0+bGVuZ3RoKTsKKyAgICAgICAgICAgICAgICBwICs9IHN0cjItPmxlbmd0aDsKKyAgICAgICAgICAgICAgICBpZiAoLS1uIDw9IDApCisgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgICpwKysgPSBzZWxmLT5zdHJbaSsrXTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIFB5X1VOSUNPREVfQ09QWShwLCBzZWxmLT5zdHIraSwgc2VsZi0+bGVuZ3RoLWkpOworICAgICAgICB9CisgICAgfQorICAgIHJldHVybiAoUHlPYmplY3QgKikgdTsKKworICBub3RoaW5nOgorICAgIC8qIG5vdGhpbmcgdG8gcmVwbGFjZTsgcmV0dXJuIG9yaWdpbmFsIHN0cmluZyAod2hlbiBwb3NzaWJsZSkgKi8KKyAgICBpZiAoUHlVbmljb2RlX0NoZWNrRXhhY3Qoc2VsZikpIHsKKyAgICAgICAgUHlfSU5DUkVGKHNlbGYpOworICAgICAgICByZXR1cm4gKFB5T2JqZWN0ICopIHNlbGY7CisgICAgfQorICAgIHJldHVybiBQeVVuaWNvZGVfRnJvbVVuaWNvZGUoc2VsZi0+c3RyLCBzZWxmLT5sZW5ndGgpOworfQorCisvKiAtLS0gVW5pY29kZSBPYmplY3QgTWV0aG9kcyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KKworUHlEb2NfU1RSVkFSKHRpdGxlX19kb2NfXywKKyAgICAgICAgICAgICAiUy50aXRsZSgpIC0+IHVuaWNvZGVcblwKK1xuXAorUmV0dXJuIGEgdGl0bGVjYXNlZCB2ZXJzaW9uIG9mIFMsIGkuZS4gd29yZHMgc3RhcnQgd2l0aCB0aXRsZSBjYXNlXG5cCitjaGFyYWN0ZXJzLCBhbGwgcmVtYWluaW5nIGNhc2VkIGNoYXJhY3RlcnMgaGF2ZSBsb3dlciBjYXNlLiIpOworCitzdGF0aWMgUHlPYmplY3QqCit1bmljb2RlX3RpdGxlKFB5VW5pY29kZU9iamVjdCAqc2VsZikKK3sKKyAgICByZXR1cm4gZml4dXAoc2VsZiwgZml4dGl0bGUpOworfQorCitQeURvY19TVFJWQVIoY2FwaXRhbGl6ZV9fZG9jX18sCisgICAgICAgICAgICAgIlMuY2FwaXRhbGl6ZSgpIC0+IHVuaWNvZGVcblwKK1xuXAorUmV0dXJuIGEgY2FwaXRhbGl6ZWQgdmVyc2lvbiBvZiBTLCBpLmUuIG1ha2UgdGhlIGZpcnN0IGNoYXJhY3RlclxuXAoraGF2ZSB1cHBlciBjYXNlIGFuZCB0aGUgcmVzdCBsb3dlciBjYXNlLiIpOworCitzdGF0aWMgUHlPYmplY3QqCit1bmljb2RlX2NhcGl0YWxpemUoUHlVbmljb2RlT2JqZWN0ICpzZWxmKQoreworICAgIHJldHVybiBmaXh1cChzZWxmLCBmaXhjYXBpdGFsaXplKTsKK30KKworI2lmIDAKK1B5RG9jX1NUUlZBUihjYXB3b3Jkc19fZG9jX18sCisgICAgICAgICAgICAgIlMuY2Fwd29yZHMoKSAtPiB1bmljb2RlXG5cCitcblwKK0FwcGx5IC5jYXBpdGFsaXplKCkgdG8gYWxsIHdvcmRzIGluIFMgYW5kIHJldHVybiB0aGUgcmVzdWx0IHdpdGhcblwKK25vcm1hbGl6ZWQgd2hpdGVzcGFjZSAoYWxsIHdoaXRlc3BhY2Ugc3RyaW5ncyBhcmUgcmVwbGFjZWQgYnkgJyAnKS4iKTsKKworc3RhdGljIFB5T2JqZWN0KgordW5pY29kZV9jYXB3b3JkcyhQeVVuaWNvZGVPYmplY3QgKnNlbGYpCit7CisgICAgUHlPYmplY3QgKmxpc3Q7CisgICAgUHlPYmplY3QgKml0ZW07CisgICAgUHlfc3NpemVfdCBpOworCisgICAgLyogU3BsaXQgaW50byB3b3JkcyAqLworICAgIGxpc3QgPSBzcGxpdChzZWxmLCBOVUxMLCAtMSk7CisgICAgaWYgKCFsaXN0KQorICAgICAgICByZXR1cm4gTlVMTDsKKworICAgIC8qIENhcGl0YWxpemUgZWFjaCB3b3JkICovCisgICAgZm9yIChpID0gMDsgaSA8IFB5TGlzdF9HRVRfU0laRShsaXN0KTsgaSsrKSB7CisgICAgICAgIGl0ZW0gPSBmaXh1cCgoUHlVbmljb2RlT2JqZWN0ICopUHlMaXN0X0dFVF9JVEVNKGxpc3QsIGkpLAorICAgICAgICAgICAgICAgICAgICAgZml4Y2FwaXRhbGl6ZSk7CisgICAgICAgIGlmIChpdGVtID09IE5VTEwpCisgICAgICAgICAgICBnb3RvIG9uRXJyb3I7CisgICAgICAgIFB5X0RFQ1JFRihQeUxpc3RfR0VUX0lURU0obGlzdCwgaSkpOworICAgICAgICBQeUxpc3RfU0VUX0lURU0obGlzdCwgaSwgaXRlbSk7CisgICAgfQorCisgICAgLyogSm9pbiB0aGUgd29yZHMgdG8gZm9ybSBhIG5ldyBzdHJpbmcgKi8KKyAgICBpdGVtID0gUHlVbmljb2RlX0pvaW4oTlVMTCwgbGlzdCk7CisKKyAgb25FcnJvcjoKKyAgICBQeV9ERUNSRUYobGlzdCk7CisgICAgcmV0dXJuIChQeU9iamVjdCAqKWl0ZW07Cit9CisjZW5kaWYKKworLyogQXJndW1lbnQgY29udmVydGVyLiAgQ29lcmNlcyB0byBhIHNpbmdsZSB1bmljb2RlIGNoYXJhY3RlciAqLworCitzdGF0aWMgaW50Citjb252ZXJ0X3VjKFB5T2JqZWN0ICpvYmosIHZvaWQgKmFkZHIpCit7CisgICAgUHlfVU5JQ09ERSAqZmlsbGNoYXJsb2MgPSAoUHlfVU5JQ09ERSAqKWFkZHI7CisgICAgUHlPYmplY3QgKnVuaW9iajsKKyAgICBQeV9VTklDT0RFICp1bmlzdHI7CisKKyAgICB1bmlvYmogPSBQeVVuaWNvZGVfRnJvbU9iamVjdChvYmopOworICAgIGlmICh1bmlvYmogPT0gTlVMTCkgeworICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfVHlwZUVycm9yLAorICAgICAgICAgICAgICAgICAgICAgICAgIlRoZSBmaWxsIGNoYXJhY3RlciBjYW5ub3QgYmUgY29udmVydGVkIHRvIFVuaWNvZGUiKTsKKyAgICAgICAgcmV0dXJuIDA7CisgICAgfQorICAgIGlmIChQeVVuaWNvZGVfR0VUX1NJWkUodW5pb2JqKSAhPSAxKSB7CisgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19UeXBlRXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAgICAiVGhlIGZpbGwgY2hhcmFjdGVyIG11c3QgYmUgZXhhY3RseSBvbmUgY2hhcmFjdGVyIGxvbmciKTsKKyAgICAgICAgUHlfREVDUkVGKHVuaW9iaik7CisgICAgICAgIHJldHVybiAwOworICAgIH0KKyAgICB1bmlzdHIgPSBQeVVuaWNvZGVfQVNfVU5JQ09ERSh1bmlvYmopOworICAgICpmaWxsY2hhcmxvYyA9IHVuaXN0clswXTsKKyAgICBQeV9ERUNSRUYodW5pb2JqKTsKKyAgICByZXR1cm4gMTsKK30KKworUHlEb2NfU1RSVkFSKGNlbnRlcl9fZG9jX18sCisgICAgICAgICAgICAgIlMuY2VudGVyKHdpZHRoWywgZmlsbGNoYXJdKSAtPiB1bmljb2RlXG5cCitcblwKK1JldHVybiBTIGNlbnRlcmVkIGluIGEgVW5pY29kZSBzdHJpbmcgb2YgbGVuZ3RoIHdpZHRoLiBQYWRkaW5nIGlzXG5cCitkb25lIHVzaW5nIHRoZSBzcGVjaWZpZWQgZmlsbCBjaGFyYWN0ZXIgKGRlZmF1bHQgaXMgYSBzcGFjZSkiKTsKKworc3RhdGljIFB5T2JqZWN0ICoKK3VuaWNvZGVfY2VudGVyKFB5VW5pY29kZU9iamVjdCAqc2VsZiwgUHlPYmplY3QgKmFyZ3MpCit7CisgICAgUHlfc3NpemVfdCBtYXJnLCBsZWZ0OworICAgIFB5X3NzaXplX3Qgd2lkdGg7CisgICAgUHlfVU5JQ09ERSBmaWxsY2hhciA9ICcgJzsKKworICAgIGlmICghUHlBcmdfUGFyc2VUdXBsZShhcmdzLCAibnxPJjpjZW50ZXIiLCAmd2lkdGgsIGNvbnZlcnRfdWMsICZmaWxsY2hhcikpCisgICAgICAgIHJldHVybiBOVUxMOworCisgICAgaWYgKHNlbGYtPmxlbmd0aCA+PSB3aWR0aCAmJiBQeVVuaWNvZGVfQ2hlY2tFeGFjdChzZWxmKSkgeworICAgICAgICBQeV9JTkNSRUYoc2VsZik7CisgICAgICAgIHJldHVybiAoUHlPYmplY3QqKSBzZWxmOworICAgIH0KKworICAgIG1hcmcgPSB3aWR0aCAtIHNlbGYtPmxlbmd0aDsKKyAgICBsZWZ0ID0gbWFyZyAvIDIgKyAobWFyZyAmIHdpZHRoICYgMSk7CisKKyAgICByZXR1cm4gKFB5T2JqZWN0KikgcGFkKHNlbGYsIGxlZnQsIG1hcmcgLSBsZWZ0LCBmaWxsY2hhcik7Cit9CisKKyNpZiAwCisKKy8qIFRoaXMgY29kZSBzaG91bGQgZ28gaW50byBzb21lIGZ1dHVyZSBVbmljb2RlIGNvbGxhdGlvbiBzdXBwb3J0CisgICBtb2R1bGUuIFRoZSBiYXNpYyBjb21wYXJpc29uIHNob3VsZCBjb21wYXJlIG9yZGluYWxzIG9uIGEgbmFpdmUKKyAgIGJhc2lzICh0aGlzIGlzIHdoYXQgSmF2YSBkb2VzIGFuZCB0aHVzIEp5dGhvbiB0b28pLiAqLworCisvKiBzcGVlZHkgVVRGLTE2IGNvZGUgcG9pbnQgb3JkZXIgY29tcGFyaXNvbiAqLworLyogZ2xlYW5lZCBmcm9tOiAqLworLyogaHR0cDovL3d3dy00LmlibS5jb20vc29mdHdhcmUvZGV2ZWxvcGVyL2xpYnJhcnkvdXRmMTYuaHRtbD9kd3pvbmU9dW5pY29kZSAqLworCitzdGF0aWMgc2hvcnQgdXRmMTZGaXh1cFszMl0gPQoreworICAgIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsCisgICAgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwKKyAgICAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLAorICAgIDAsIDAsIDAsIDB4MjAwMCwgLTB4ODAwLCAtMHg4MDAsIC0weDgwMCwgLTB4ODAwCit9OworCitzdGF0aWMgaW50Cit1bmljb2RlX2NvbXBhcmUoUHlVbmljb2RlT2JqZWN0ICpzdHIxLCBQeVVuaWNvZGVPYmplY3QgKnN0cjIpCit7CisgICAgUHlfc3NpemVfdCBsZW4xLCBsZW4yOworCisgICAgUHlfVU5JQ09ERSAqczEgPSBzdHIxLT5zdHI7CisgICAgUHlfVU5JQ09ERSAqczIgPSBzdHIyLT5zdHI7CisKKyAgICBsZW4xID0gc3RyMS0+bGVuZ3RoOworICAgIGxlbjIgPSBzdHIyLT5sZW5ndGg7CisKKyAgICB3aGlsZSAobGVuMSA+IDAgJiYgbGVuMiA+IDApIHsKKyAgICAgICAgUHlfVU5JQ09ERSBjMSwgYzI7CisKKyAgICAgICAgYzEgPSAqczErKzsKKyAgICAgICAgYzIgPSAqczIrKzsKKworICAgICAgICBpZiAoYzEgPiAoMTw8MTEpICogMjYpCisgICAgICAgICAgICBjMSArPSB1dGYxNkZpeHVwW2MxPj4xMV07CisgICAgICAgIGlmIChjMiA+ICgxPDwxMSkgKiAyNikKKyAgICAgICAgICAgIGMyICs9IHV0ZjE2Rml4dXBbYzI+PjExXTsKKyAgICAgICAgLyogbm93IGMxIGFuZCBjMiBhcmUgaW4gVVRGLTMyLWNvbXBhdGlibGUgb3JkZXIgKi8KKworICAgICAgICBpZiAoYzEgIT0gYzIpCisgICAgICAgICAgICByZXR1cm4gKGMxIDwgYzIpID8gLTEgOiAxOworCisgICAgICAgIGxlbjEtLTsgbGVuMi0tOworICAgIH0KKworICAgIHJldHVybiAobGVuMSA8IGxlbjIpID8gLTEgOiAobGVuMSAhPSBsZW4yKTsKK30KKworI2Vsc2UKKworc3RhdGljIGludAordW5pY29kZV9jb21wYXJlKFB5VW5pY29kZU9iamVjdCAqc3RyMSwgUHlVbmljb2RlT2JqZWN0ICpzdHIyKQoreworICAgIHJlZ2lzdGVyIFB5X3NzaXplX3QgbGVuMSwgbGVuMjsKKworICAgIFB5X1VOSUNPREUgKnMxID0gc3RyMS0+c3RyOworICAgIFB5X1VOSUNPREUgKnMyID0gc3RyMi0+c3RyOworCisgICAgbGVuMSA9IHN0cjEtPmxlbmd0aDsKKyAgICBsZW4yID0gc3RyMi0+bGVuZ3RoOworCisgICAgd2hpbGUgKGxlbjEgPiAwICYmIGxlbjIgPiAwKSB7CisgICAgICAgIFB5X1VOSUNPREUgYzEsIGMyOworCisgICAgICAgIGMxID0gKnMxKys7CisgICAgICAgIGMyID0gKnMyKys7CisKKyAgICAgICAgaWYgKGMxICE9IGMyKQorICAgICAgICAgICAgcmV0dXJuIChjMSA8IGMyKSA/IC0xIDogMTsKKworICAgICAgICBsZW4xLS07IGxlbjItLTsKKyAgICB9CisKKyAgICByZXR1cm4gKGxlbjEgPCBsZW4yKSA/IC0xIDogKGxlbjEgIT0gbGVuMik7Cit9CisKKyNlbmRpZgorCitpbnQgUHlVbmljb2RlX0NvbXBhcmUoUHlPYmplY3QgKmxlZnQsCisgICAgICAgICAgICAgICAgICAgICAgUHlPYmplY3QgKnJpZ2h0KQoreworICAgIFB5VW5pY29kZU9iamVjdCAqdSA9IE5VTEwsICp2ID0gTlVMTDsKKyAgICBpbnQgcmVzdWx0OworCisgICAgLyogQ29lcmNlIHRoZSB0d28gYXJndW1lbnRzICovCisgICAgdSA9IChQeVVuaWNvZGVPYmplY3QgKilQeVVuaWNvZGVfRnJvbU9iamVjdChsZWZ0KTsKKyAgICBpZiAodSA9PSBOVUxMKQorICAgICAgICBnb3RvIG9uRXJyb3I7CisgICAgdiA9IChQeVVuaWNvZGVPYmplY3QgKilQeVVuaWNvZGVfRnJvbU9iamVjdChyaWdodCk7CisgICAgaWYgKHYgPT0gTlVMTCkKKyAgICAgICAgZ290byBvbkVycm9yOworCisgICAgLyogU2hvcnRjdXQgZm9yIGVtcHR5IG9yIGludGVybmVkIG9iamVjdHMgKi8KKyAgICBpZiAodiA9PSB1KSB7CisgICAgICAgIFB5X0RFQ1JFRih1KTsKKyAgICAgICAgUHlfREVDUkVGKHYpOworICAgICAgICByZXR1cm4gMDsKKyAgICB9CisKKyAgICByZXN1bHQgPSB1bmljb2RlX2NvbXBhcmUodSwgdik7CisKKyAgICBQeV9ERUNSRUYodSk7CisgICAgUHlfREVDUkVGKHYpOworICAgIHJldHVybiByZXN1bHQ7CisKKyAgb25FcnJvcjoKKyAgICBQeV9YREVDUkVGKHUpOworICAgIFB5X1hERUNSRUYodik7CisgICAgcmV0dXJuIC0xOworfQorCitQeU9iamVjdCAqUHlVbmljb2RlX1JpY2hDb21wYXJlKFB5T2JqZWN0ICpsZWZ0LAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQeU9iamVjdCAqcmlnaHQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBvcCkKK3sKKyAgICBpbnQgcmVzdWx0OworCisgICAgcmVzdWx0ID0gUHlVbmljb2RlX0NvbXBhcmUobGVmdCwgcmlnaHQpOworICAgIGlmIChyZXN1bHQgPT0gLTEgJiYgUHlFcnJfT2NjdXJyZWQoKSkKKyAgICAgICAgZ290byBvbkVycm9yOworCisgICAgLyogQ29udmVydCB0aGUgcmV0dXJuIHZhbHVlIHRvIGEgQm9vbGVhbiAqLworICAgIHN3aXRjaCAob3ApIHsKKyAgICBjYXNlIFB5X0VROgorICAgICAgICByZXN1bHQgPSAocmVzdWx0ID09IDApOworICAgICAgICBicmVhazsKKyAgICBjYXNlIFB5X05FOgorICAgICAgICByZXN1bHQgPSAocmVzdWx0ICE9IDApOworICAgICAgICBicmVhazsKKyAgICBjYXNlIFB5X0xFOgorICAgICAgICByZXN1bHQgPSAocmVzdWx0IDw9IDApOworICAgICAgICBicmVhazsKKyAgICBjYXNlIFB5X0dFOgorICAgICAgICByZXN1bHQgPSAocmVzdWx0ID49IDApOworICAgICAgICBicmVhazsKKyAgICBjYXNlIFB5X0xUOgorICAgICAgICByZXN1bHQgPSAocmVzdWx0ID09IC0xKTsKKyAgICAgICAgYnJlYWs7CisgICAgY2FzZSBQeV9HVDoKKyAgICAgICAgcmVzdWx0ID0gKHJlc3VsdCA9PSAxKTsKKyAgICAgICAgYnJlYWs7CisgICAgfQorICAgIHJldHVybiBQeUJvb2xfRnJvbUxvbmcocmVzdWx0KTsKKworICBvbkVycm9yOgorCisgICAgLyogU3RhbmRhcmQgY2FzZQorCisgICAgICAgVHlwZSBlcnJvcnMgbWVhbiB0aGF0IFB5VW5pY29kZV9Gcm9tT2JqZWN0KCkgY291bGQgbm90IGNvbnZlcnQKKyAgICAgICBvbmUgb2YgdGhlIGFyZ3VtZW50cyAodXN1YWxseSB0aGUgcmlnaHQgaGFuZCBzaWRlKSB0byBVbmljb2RlLAorICAgICAgIGllLiB3ZSBjYW4ndCBoYW5kbGUgdGhlIGNvbXBhcmlzb24gcmVxdWVzdC4gSG93ZXZlciwgaXQgaXMKKyAgICAgICBwb3NzaWJsZSB0aGF0IHRoZSBvdGhlciBvYmplY3Qga25vd3MgYSBjb21wYXJpc29uIG1ldGhvZCwgd2hpY2gKKyAgICAgICBpcyB3aHkgd2UgcmV0dXJuIFB5X05vdEltcGxlbWVudGVkIHRvIGdpdmUgdGhlIG90aGVyIG9iamVjdCBhCisgICAgICAgY2hhbmNlLgorCisgICAgKi8KKyAgICBpZiAoUHlFcnJfRXhjZXB0aW9uTWF0Y2hlcyhQeUV4Y19UeXBlRXJyb3IpKSB7CisgICAgICAgIFB5RXJyX0NsZWFyKCk7CisgICAgICAgIFB5X0lOQ1JFRihQeV9Ob3RJbXBsZW1lbnRlZCk7CisgICAgICAgIHJldHVybiBQeV9Ob3RJbXBsZW1lbnRlZDsKKyAgICB9CisgICAgaWYgKG9wICE9IFB5X0VRICYmIG9wICE9IFB5X05FKQorICAgICAgICByZXR1cm4gTlVMTDsKKworICAgIC8qIEVxdWFsaXR5IGNvbXBhcmlzb24uCisKKyAgICAgICBUaGlzIGlzIGEgc3BlY2lhbCBjYXNlOiB3ZSBzaWxlbmNlIGFueSBQeUV4Y19Vbmljb2RlRGVjb2RlRXJyb3IKKyAgICAgICBhbmQgaW5zdGVhZCB0dXJuIGl0IGludG8gYSBQeUVycl9Vbmljb2RlV2FybmluZy4KKworICAgICovCisgICAgaWYgKCFQeUVycl9FeGNlcHRpb25NYXRjaGVzKFB5RXhjX1VuaWNvZGVEZWNvZGVFcnJvcikpCisgICAgICAgIHJldHVybiBOVUxMOworICAgIFB5RXJyX0NsZWFyKCk7CisgICAgaWYgKFB5RXJyX1dhcm4oUHlFeGNfVW5pY29kZVdhcm5pbmcsCisgICAgICAgICAgICAgICAgICAgKG9wID09IFB5X0VRKSA/CisgICAgICAgICAgICAgICAgICAgIlVuaWNvZGUgZXF1YWwgY29tcGFyaXNvbiAiCisgICAgICAgICAgICAgICAgICAgImZhaWxlZCB0byBjb252ZXJ0IGJvdGggYXJndW1lbnRzIHRvIFVuaWNvZGUgLSAiCisgICAgICAgICAgICAgICAgICAgImludGVycHJldGluZyB0aGVtIGFzIGJlaW5nIHVuZXF1YWwiIDoKKyAgICAgICAgICAgICAgICAgICAiVW5pY29kZSB1bmVxdWFsIGNvbXBhcmlzb24gIgorICAgICAgICAgICAgICAgICAgICJmYWlsZWQgdG8gY29udmVydCBib3RoIGFyZ3VtZW50cyB0byBVbmljb2RlIC0gIgorICAgICAgICAgICAgICAgICAgICJpbnRlcnByZXRpbmcgdGhlbSBhcyBiZWluZyB1bmVxdWFsIgorICAgICAgICAgICAgKSA8IDApCisgICAgICAgIHJldHVybiBOVUxMOworICAgIHJlc3VsdCA9IChvcCA9PSBQeV9ORSk7CisgICAgcmV0dXJuIFB5Qm9vbF9Gcm9tTG9uZyhyZXN1bHQpOworfQorCitpbnQgUHlVbmljb2RlX0NvbnRhaW5zKFB5T2JqZWN0ICpjb250YWluZXIsCisgICAgICAgICAgICAgICAgICAgICAgIFB5T2JqZWN0ICplbGVtZW50KQoreworICAgIFB5T2JqZWN0ICpzdHIsICpzdWI7CisgICAgaW50IHJlc3VsdDsKKworICAgIC8qIENvZXJjZSB0aGUgdHdvIGFyZ3VtZW50cyAqLworICAgIHN1YiA9IFB5VW5pY29kZV9Gcm9tT2JqZWN0KGVsZW1lbnQpOworICAgIGlmICghc3ViKSB7CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisKKyAgICBzdHIgPSBQeVVuaWNvZGVfRnJvbU9iamVjdChjb250YWluZXIpOworICAgIGlmICghc3RyKSB7CisgICAgICAgIFB5X0RFQ1JFRihzdWIpOworICAgICAgICByZXR1cm4gLTE7CisgICAgfQorCisgICAgcmVzdWx0ID0gc3RyaW5nbGliX2NvbnRhaW5zX29iaihzdHIsIHN1Yik7CisKKyAgICBQeV9ERUNSRUYoc3RyKTsKKyAgICBQeV9ERUNSRUYoc3ViKTsKKworICAgIHJldHVybiByZXN1bHQ7Cit9CisKKy8qIENvbmNhdCB0byBzdHJpbmcgb3IgVW5pY29kZSBvYmplY3QgZ2l2aW5nIGEgbmV3IFVuaWNvZGUgb2JqZWN0LiAqLworCitQeU9iamVjdCAqUHlVbmljb2RlX0NvbmNhdChQeU9iamVjdCAqbGVmdCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIFB5T2JqZWN0ICpyaWdodCkKK3sKKyAgICBQeVVuaWNvZGVPYmplY3QgKnUgPSBOVUxMLCAqdiA9IE5VTEwsICp3OworCisgICAgLyogQ29lcmNlIHRoZSB0d28gYXJndW1lbnRzICovCisgICAgdSA9IChQeVVuaWNvZGVPYmplY3QgKilQeVVuaWNvZGVfRnJvbU9iamVjdChsZWZ0KTsKKyAgICBpZiAodSA9PSBOVUxMKQorICAgICAgICBnb3RvIG9uRXJyb3I7CisgICAgdiA9IChQeVVuaWNvZGVPYmplY3QgKilQeVVuaWNvZGVfRnJvbU9iamVjdChyaWdodCk7CisgICAgaWYgKHYgPT0gTlVMTCkKKyAgICAgICAgZ290byBvbkVycm9yOworCisgICAgLyogU2hvcnRjdXRzICovCisgICAgaWYgKHYgPT0gdW5pY29kZV9lbXB0eSkgeworICAgICAgICBQeV9ERUNSRUYodik7CisgICAgICAgIHJldHVybiAoUHlPYmplY3QgKil1OworICAgIH0KKyAgICBpZiAodSA9PSB1bmljb2RlX2VtcHR5KSB7CisgICAgICAgIFB5X0RFQ1JFRih1KTsKKyAgICAgICAgcmV0dXJuIChQeU9iamVjdCAqKXY7CisgICAgfQorCisgICAgLyogQ29uY2F0IHRoZSB0d28gVW5pY29kZSBzdHJpbmdzICovCisgICAgdyA9IF9QeVVuaWNvZGVfTmV3KHUtPmxlbmd0aCArIHYtPmxlbmd0aCk7CisgICAgaWYgKHcgPT0gTlVMTCkKKyAgICAgICAgZ290byBvbkVycm9yOworICAgIFB5X1VOSUNPREVfQ09QWSh3LT5zdHIsIHUtPnN0ciwgdS0+bGVuZ3RoKTsKKyAgICBQeV9VTklDT0RFX0NPUFkody0+c3RyICsgdS0+bGVuZ3RoLCB2LT5zdHIsIHYtPmxlbmd0aCk7CisKKyAgICBQeV9ERUNSRUYodSk7CisgICAgUHlfREVDUkVGKHYpOworICAgIHJldHVybiAoUHlPYmplY3QgKil3OworCisgIG9uRXJyb3I6CisgICAgUHlfWERFQ1JFRih1KTsKKyAgICBQeV9YREVDUkVGKHYpOworICAgIHJldHVybiBOVUxMOworfQorCitQeURvY19TVFJWQVIoY291bnRfX2RvY19fLAorICAgICAgICAgICAgICJTLmNvdW50KHN1YlssIHN0YXJ0WywgZW5kXV0pIC0+IGludFxuXAorXG5cCitSZXR1cm4gdGhlIG51bWJlciBvZiBub24tb3ZlcmxhcHBpbmcgb2NjdXJyZW5jZXMgb2Ygc3Vic3RyaW5nIHN1YiBpblxuXAorVW5pY29kZSBzdHJpbmcgU1tzdGFydDplbmRdLiAgT3B0aW9uYWwgYXJndW1lbnRzIHN0YXJ0IGFuZCBlbmQgYXJlXG5cCitpbnRlcnByZXRlZCBhcyBpbiBzbGljZSBub3RhdGlvbi4iKTsKKworc3RhdGljIFB5T2JqZWN0ICoKK3VuaWNvZGVfY291bnQoUHlVbmljb2RlT2JqZWN0ICpzZWxmLCBQeU9iamVjdCAqYXJncykKK3sKKyAgICBQeVVuaWNvZGVPYmplY3QgKnN1YnN0cmluZzsKKyAgICBQeV9zc2l6ZV90IHN0YXJ0ID0gMDsKKyAgICBQeV9zc2l6ZV90IGVuZCA9IFBZX1NTSVpFX1RfTUFYOworICAgIFB5T2JqZWN0ICpyZXN1bHQ7CisKKyAgICBpZiAoIXN0cmluZ2xpYl9wYXJzZV9hcmdzX2ZpbmRzX3VuaWNvZGUoImNvdW50IiwgYXJncywgJnN1YnN0cmluZywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnN0YXJ0LCAmZW5kKSkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisKKyAgICBBREpVU1RfSU5ESUNFUyhzdGFydCwgZW5kLCBzZWxmLT5sZW5ndGgpOworICAgIHJlc3VsdCA9IFB5SW50X0Zyb21Tc2l6ZV90KAorICAgICAgICBzdHJpbmdsaWJfY291bnQoc2VsZi0+c3RyICsgc3RhcnQsIGVuZCAtIHN0YXJ0LAorICAgICAgICAgICAgICAgICAgICAgICAgc3Vic3RyaW5nLT5zdHIsIHN1YnN0cmluZy0+bGVuZ3RoLAorICAgICAgICAgICAgICAgICAgICAgICAgUFlfU1NJWkVfVF9NQVgpCisgICAgICAgICk7CisKKyAgICBQeV9ERUNSRUYoc3Vic3RyaW5nKTsKKworICAgIHJldHVybiByZXN1bHQ7Cit9CisKK1B5RG9jX1NUUlZBUihlbmNvZGVfX2RvY19fLAorICAgICAgICAgICAgICJTLmVuY29kZShbZW5jb2RpbmdbLGVycm9yc11dKSAtPiBzdHJpbmcgb3IgdW5pY29kZVxuXAorXG5cCitFbmNvZGVzIFMgdXNpbmcgdGhlIGNvZGVjIHJlZ2lzdGVyZWQgZm9yIGVuY29kaW5nLiBlbmNvZGluZyBkZWZhdWx0c1xuXAordG8gdGhlIGRlZmF1bHQgZW5jb2RpbmcuIGVycm9ycyBtYXkgYmUgZ2l2ZW4gdG8gc2V0IGEgZGlmZmVyZW50IGVycm9yXG5cCitoYW5kbGluZyBzY2hlbWUuIERlZmF1bHQgaXMgJ3N0cmljdCcgbWVhbmluZyB0aGF0IGVuY29kaW5nIGVycm9ycyByYWlzZVxuXAorYSBVbmljb2RlRW5jb2RlRXJyb3IuIE90aGVyIHBvc3NpYmxlIHZhbHVlcyBhcmUgJ2lnbm9yZScsICdyZXBsYWNlJyBhbmRcblwKKyd4bWxjaGFycmVmcmVwbGFjZScgYXMgd2VsbCBhcyBhbnkgb3RoZXIgbmFtZSByZWdpc3RlcmVkIHdpdGhcblwKK2NvZGVjcy5yZWdpc3Rlcl9lcnJvciB0aGF0IGNhbiBoYW5kbGUgVW5pY29kZUVuY29kZUVycm9ycy4iKTsKKworc3RhdGljIFB5T2JqZWN0ICoKK3VuaWNvZGVfZW5jb2RlKFB5VW5pY29kZU9iamVjdCAqc2VsZiwgUHlPYmplY3QgKmFyZ3MsIFB5T2JqZWN0ICprd2FyZ3MpCit7CisgICAgc3RhdGljIGNoYXIgKmt3bGlzdFtdID0geyJlbmNvZGluZyIsICJlcnJvcnMiLCAwfTsKKyAgICBjaGFyICplbmNvZGluZyA9IE5VTEw7CisgICAgY2hhciAqZXJyb3JzID0gTlVMTDsKKyAgICBQeU9iamVjdCAqdjsKKworICAgIGlmICghUHlBcmdfUGFyc2VUdXBsZUFuZEtleXdvcmRzKGFyZ3MsIGt3YXJncywgInxzczplbmNvZGUiLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGt3bGlzdCwgJmVuY29kaW5nLCAmZXJyb3JzKSkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgdiA9IFB5VW5pY29kZV9Bc0VuY29kZWRPYmplY3QoKFB5T2JqZWN0ICopc2VsZiwgZW5jb2RpbmcsIGVycm9ycyk7CisgICAgaWYgKHYgPT0gTlVMTCkKKyAgICAgICAgZ290byBvbkVycm9yOworICAgIGlmICghUHlTdHJpbmdfQ2hlY2sodikgJiYgIVB5VW5pY29kZV9DaGVjayh2KSkgeworICAgICAgICBQeUVycl9Gb3JtYXQoUHlFeGNfVHlwZUVycm9yLAorICAgICAgICAgICAgICAgICAgICAgImVuY29kZXIgZGlkIG5vdCByZXR1cm4gYSBzdHJpbmcvdW5pY29kZSBvYmplY3QgIgorICAgICAgICAgICAgICAgICAgICAgIih0eXBlPSUuNDAwcykiLAorICAgICAgICAgICAgICAgICAgICAgUHlfVFlQRSh2KS0+dHBfbmFtZSk7CisgICAgICAgIFB5X0RFQ1JFRih2KTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIHJldHVybiB2OworCisgIG9uRXJyb3I6CisgICAgcmV0dXJuIE5VTEw7Cit9CisKK1B5RG9jX1NUUlZBUihkZWNvZGVfX2RvY19fLAorICAgICAgICAgICAgICJTLmRlY29kZShbZW5jb2RpbmdbLGVycm9yc11dKSAtPiBzdHJpbmcgb3IgdW5pY29kZVxuXAorXG5cCitEZWNvZGVzIFMgdXNpbmcgdGhlIGNvZGVjIHJlZ2lzdGVyZWQgZm9yIGVuY29kaW5nLiBlbmNvZGluZyBkZWZhdWx0c1xuXAordG8gdGhlIGRlZmF1bHQgZW5jb2RpbmcuIGVycm9ycyBtYXkgYmUgZ2l2ZW4gdG8gc2V0IGEgZGlmZmVyZW50IGVycm9yXG5cCitoYW5kbGluZyBzY2hlbWUuIERlZmF1bHQgaXMgJ3N0cmljdCcgbWVhbmluZyB0aGF0IGVuY29kaW5nIGVycm9ycyByYWlzZVxuXAorYSBVbmljb2RlRGVjb2RlRXJyb3IuIE90aGVyIHBvc3NpYmxlIHZhbHVlcyBhcmUgJ2lnbm9yZScgYW5kICdyZXBsYWNlJ1xuXAorYXMgd2VsbCBhcyBhbnkgb3RoZXIgbmFtZSByZWdpc3RlcmVkIHdpdGggY29kZWNzLnJlZ2lzdGVyX2Vycm9yIHRoYXQgaXNcblwKK2FibGUgdG8gaGFuZGxlIFVuaWNvZGVEZWNvZGVFcnJvcnMuIik7CisKK3N0YXRpYyBQeU9iamVjdCAqCit1bmljb2RlX2RlY29kZShQeVVuaWNvZGVPYmplY3QgKnNlbGYsIFB5T2JqZWN0ICphcmdzLCBQeU9iamVjdCAqa3dhcmdzKQoreworICAgIHN0YXRpYyBjaGFyICprd2xpc3RbXSA9IHsiZW5jb2RpbmciLCAiZXJyb3JzIiwgMH07CisgICAgY2hhciAqZW5jb2RpbmcgPSBOVUxMOworICAgIGNoYXIgKmVycm9ycyA9IE5VTEw7CisgICAgUHlPYmplY3QgKnY7CisKKyAgICBpZiAoIVB5QXJnX1BhcnNlVHVwbGVBbmRLZXl3b3JkcyhhcmdzLCBrd2FyZ3MsICJ8c3M6ZGVjb2RlIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBrd2xpc3QsICZlbmNvZGluZywgJmVycm9ycykpCisgICAgICAgIHJldHVybiBOVUxMOworICAgIHYgPSBQeVVuaWNvZGVfQXNEZWNvZGVkT2JqZWN0KChQeU9iamVjdCAqKXNlbGYsIGVuY29kaW5nLCBlcnJvcnMpOworICAgIGlmICh2ID09IE5VTEwpCisgICAgICAgIGdvdG8gb25FcnJvcjsKKyAgICBpZiAoIVB5U3RyaW5nX0NoZWNrKHYpICYmICFQeVVuaWNvZGVfQ2hlY2sodikpIHsKKyAgICAgICAgUHlFcnJfRm9ybWF0KFB5RXhjX1R5cGVFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICJkZWNvZGVyIGRpZCBub3QgcmV0dXJuIGEgc3RyaW5nL3VuaWNvZGUgb2JqZWN0ICIKKyAgICAgICAgICAgICAgICAgICAgICIodHlwZT0lLjQwMHMpIiwKKyAgICAgICAgICAgICAgICAgICAgIFB5X1RZUEUodiktPnRwX25hbWUpOworICAgICAgICBQeV9ERUNSRUYodik7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICByZXR1cm4gdjsKKworICBvbkVycm9yOgorICAgIHJldHVybiBOVUxMOworfQorCitQeURvY19TVFJWQVIoZXhwYW5kdGFic19fZG9jX18sCisgICAgICAgICAgICAgIlMuZXhwYW5kdGFicyhbdGFic2l6ZV0pIC0+IHVuaWNvZGVcblwKK1xuXAorUmV0dXJuIGEgY29weSBvZiBTIHdoZXJlIGFsbCB0YWIgY2hhcmFjdGVycyBhcmUgZXhwYW5kZWQgdXNpbmcgc3BhY2VzLlxuXAorSWYgdGFic2l6ZSBpcyBub3QgZ2l2ZW4sIGEgdGFiIHNpemUgb2YgOCBjaGFyYWN0ZXJzIGlzIGFzc3VtZWQuIik7CisKK3N0YXRpYyBQeU9iamVjdCoKK3VuaWNvZGVfZXhwYW5kdGFicyhQeVVuaWNvZGVPYmplY3QgKnNlbGYsIFB5T2JqZWN0ICphcmdzKQoreworICAgIFB5X1VOSUNPREUgKmU7CisgICAgUHlfVU5JQ09ERSAqcDsKKyAgICBQeV9VTklDT0RFICpxOworICAgIFB5X1VOSUNPREUgKnFlOworICAgIFB5X3NzaXplX3QgaSwgaiwgaW5jcjsKKyAgICBQeVVuaWNvZGVPYmplY3QgKnU7CisgICAgaW50IHRhYnNpemUgPSA4OworCisgICAgaWYgKCFQeUFyZ19QYXJzZVR1cGxlKGFyZ3MsICJ8aTpleHBhbmR0YWJzIiwgJnRhYnNpemUpKQorICAgICAgICByZXR1cm4gTlVMTDsKKworICAgIC8qIEZpcnN0IHBhc3M6IGRldGVybWluZSBzaXplIG9mIG91dHB1dCBzdHJpbmcgKi8KKyAgICBpID0gMDsgLyogY2hhcnMgdXAgdG8gYW5kIGluY2x1ZGluZyBtb3N0IHJlY2VudCBcbiBvciBcciAqLworICAgIGogPSAwOyAvKiBjaGFycyBzaW5jZSBtb3N0IHJlY2VudCBcbiBvciBcciAodXNlIGluIHRhYiBjYWxjdWxhdGlvbnMpICovCisgICAgZSA9IHNlbGYtPnN0ciArIHNlbGYtPmxlbmd0aDsgLyogZW5kIG9mIGlucHV0ICovCisgICAgZm9yIChwID0gc2VsZi0+c3RyOyBwIDwgZTsgcCsrKQorICAgICAgICBpZiAoKnAgPT0gJ1x0JykgeworICAgICAgICAgICAgaWYgKHRhYnNpemUgPiAwKSB7CisgICAgICAgICAgICAgICAgaW5jciA9IHRhYnNpemUgLSAoaiAlIHRhYnNpemUpOyAvKiBjYW5ub3Qgb3ZlcmZsb3cgKi8KKyAgICAgICAgICAgICAgICBpZiAoaiA+IFBZX1NTSVpFX1RfTUFYIC0gaW5jcikKKyAgICAgICAgICAgICAgICAgICAgZ290byBvdmVyZmxvdzE7CisgICAgICAgICAgICAgICAgaiArPSBpbmNyOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGVsc2UgeworICAgICAgICAgICAgaWYgKGogPiBQWV9TU0laRV9UX01BWCAtIDEpCisgICAgICAgICAgICAgICAgZ290byBvdmVyZmxvdzE7CisgICAgICAgICAgICBqKys7CisgICAgICAgICAgICBpZiAoKnAgPT0gJ1xuJyB8fCAqcCA9PSAnXHInKSB7CisgICAgICAgICAgICAgICAgaWYgKGkgPiBQWV9TU0laRV9UX01BWCAtIGopCisgICAgICAgICAgICAgICAgICAgIGdvdG8gb3ZlcmZsb3cxOworICAgICAgICAgICAgICAgIGkgKz0gajsKKyAgICAgICAgICAgICAgICBqID0gMDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorCisgICAgaWYgKGkgPiBQWV9TU0laRV9UX01BWCAtIGopCisgICAgICAgIGdvdG8gb3ZlcmZsb3cxOworCisgICAgLyogU2Vjb25kIHBhc3M6IGNyZWF0ZSBvdXRwdXQgc3RyaW5nIGFuZCBmaWxsIGl0ICovCisgICAgdSA9IF9QeVVuaWNvZGVfTmV3KGkgKyBqKTsKKyAgICBpZiAoIXUpCisgICAgICAgIHJldHVybiBOVUxMOworCisgICAgaiA9IDA7IC8qIHNhbWUgYXMgaW4gZmlyc3QgcGFzcyAqLworICAgIHEgPSB1LT5zdHI7IC8qIG5leHQgb3V0cHV0IGNoYXIgKi8KKyAgICBxZSA9IHUtPnN0ciArIHUtPmxlbmd0aDsgLyogZW5kIG9mIG91dHB1dCAqLworCisgICAgZm9yIChwID0gc2VsZi0+c3RyOyBwIDwgZTsgcCsrKQorICAgICAgICBpZiAoKnAgPT0gJ1x0JykgeworICAgICAgICAgICAgaWYgKHRhYnNpemUgPiAwKSB7CisgICAgICAgICAgICAgICAgaSA9IHRhYnNpemUgLSAoaiAlIHRhYnNpemUpOworICAgICAgICAgICAgICAgIGogKz0gaTsKKyAgICAgICAgICAgICAgICB3aGlsZSAoaS0tKSB7CisgICAgICAgICAgICAgICAgICAgIGlmIChxID49IHFlKQorICAgICAgICAgICAgICAgICAgICAgICAgZ290byBvdmVyZmxvdzI7CisgICAgICAgICAgICAgICAgICAgICpxKysgPSAnICc7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGVsc2UgeworICAgICAgICAgICAgaWYgKHEgPj0gcWUpCisgICAgICAgICAgICAgICAgZ290byBvdmVyZmxvdzI7CisgICAgICAgICAgICAqcSsrID0gKnA7CisgICAgICAgICAgICBqKys7CisgICAgICAgICAgICBpZiAoKnAgPT0gJ1xuJyB8fCAqcCA9PSAnXHInKQorICAgICAgICAgICAgICAgIGogPSAwOworICAgICAgICB9CisKKyAgICByZXR1cm4gKFB5T2JqZWN0KikgdTsKKworICBvdmVyZmxvdzI6CisgICAgUHlfREVDUkVGKHUpOworICBvdmVyZmxvdzE6CisgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX092ZXJmbG93RXJyb3IsICJuZXcgc3RyaW5nIGlzIHRvbyBsb25nIik7CisgICAgcmV0dXJuIE5VTEw7Cit9CisKK1B5RG9jX1NUUlZBUihmaW5kX19kb2NfXywKKyAgICAgICAgICAgICAiUy5maW5kKHN1YiBbLHN0YXJ0IFssZW5kXV0pIC0+IGludFxuXAorXG5cCitSZXR1cm4gdGhlIGxvd2VzdCBpbmRleCBpbiBTIHdoZXJlIHN1YnN0cmluZyBzdWIgaXMgZm91bmQsXG5cCitzdWNoIHRoYXQgc3ViIGlzIGNvbnRhaW5lZCB3aXRoaW4gU1tzdGFydDplbmRdLiAgT3B0aW9uYWxcblwKK2FyZ3VtZW50cyBzdGFydCBhbmQgZW5kIGFyZSBpbnRlcnByZXRlZCBhcyBpbiBzbGljZSBub3RhdGlvbi5cblwKK1xuXAorUmV0dXJuIC0xIG9uIGZhaWx1cmUuIik7CisKK3N0YXRpYyBQeU9iamVjdCAqCit1bmljb2RlX2ZpbmQoUHlVbmljb2RlT2JqZWN0ICpzZWxmLCBQeU9iamVjdCAqYXJncykKK3sKKyAgICBQeVVuaWNvZGVPYmplY3QgKnN1YnN0cmluZzsKKyAgICBQeV9zc2l6ZV90IHN0YXJ0OworICAgIFB5X3NzaXplX3QgZW5kOworICAgIFB5X3NzaXplX3QgcmVzdWx0OworCisgICAgaWYgKCFzdHJpbmdsaWJfcGFyc2VfYXJnc19maW5kc191bmljb2RlKCJmaW5kIiwgYXJncywgJnN1YnN0cmluZywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnN0YXJ0LCAmZW5kKSkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisKKyAgICByZXN1bHQgPSBzdHJpbmdsaWJfZmluZF9zbGljZSgKKyAgICAgICAgUHlVbmljb2RlX0FTX1VOSUNPREUoc2VsZiksIFB5VW5pY29kZV9HRVRfU0laRShzZWxmKSwKKyAgICAgICAgUHlVbmljb2RlX0FTX1VOSUNPREUoc3Vic3RyaW5nKSwgUHlVbmljb2RlX0dFVF9TSVpFKHN1YnN0cmluZyksCisgICAgICAgIHN0YXJ0LCBlbmQKKyAgICAgICAgKTsKKworICAgIFB5X0RFQ1JFRihzdWJzdHJpbmcpOworCisgICAgcmV0dXJuIFB5SW50X0Zyb21Tc2l6ZV90KHJlc3VsdCk7Cit9CisKK3N0YXRpYyBQeU9iamVjdCAqCit1bmljb2RlX2dldGl0ZW0oUHlVbmljb2RlT2JqZWN0ICpzZWxmLCBQeV9zc2l6ZV90IGluZGV4KQoreworICAgIGlmIChpbmRleCA8IDAgfHwgaW5kZXggPj0gc2VsZi0+bGVuZ3RoKSB7CisgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19JbmRleEVycm9yLCAic3RyaW5nIGluZGV4IG91dCBvZiByYW5nZSIpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisKKyAgICByZXR1cm4gKFB5T2JqZWN0KikgUHlVbmljb2RlX0Zyb21Vbmljb2RlKCZzZWxmLT5zdHJbaW5kZXhdLCAxKTsKK30KKworc3RhdGljIGxvbmcKK3VuaWNvZGVfaGFzaChQeVVuaWNvZGVPYmplY3QgKnNlbGYpCit7CisgICAgLyogU2luY2UgVW5pY29kZSBvYmplY3RzIGNvbXBhcmUgZXF1YWwgdG8gdGhlaXIgQVNDSUkgc3RyaW5nCisgICAgICAgY291bnRlcnBhcnRzLCB0aGV5IHNob3VsZCB1c2UgdGhlIGluZGl2aWR1YWwgY2hhcmFjdGVyIHZhbHVlcworICAgICAgIGFzIGJhc2lzIGZvciB0aGVpciBoYXNoIHZhbHVlLiAgVGhpcyBpcyBuZWVkZWQgdG8gYXNzdXJlIHRoYXQKKyAgICAgICBzdHJpbmdzIGFuZCBVbmljb2RlIG9iamVjdHMgYmVoYXZlIGluIHRoZSBzYW1lIHdheSBhcworICAgICAgIGRpY3Rpb25hcnkga2V5cy4gKi8KKworICAgIHJlZ2lzdGVyIFB5X3NzaXplX3QgbGVuOworICAgIHJlZ2lzdGVyIFB5X1VOSUNPREUgKnA7CisgICAgcmVnaXN0ZXIgbG9uZyB4OworCisjaWZkZWYgUHlfREVCVUcKKyAgICBhc3NlcnQoX1B5X0hhc2hTZWNyZXRfSW5pdGlhbGl6ZWQpOworI2VuZGlmCisgICAgaWYgKHNlbGYtPmhhc2ggIT0gLTEpCisgICAgICAgIHJldHVybiBzZWxmLT5oYXNoOworICAgIGxlbiA9IFB5VW5pY29kZV9HRVRfU0laRShzZWxmKTsKKyAgICAvKgorICAgICAgV2UgbWFrZSB0aGUgaGFzaCBvZiB0aGUgZW1wdHkgc3RyaW5nIGJlIDAsIHJhdGhlciB0aGFuIHVzaW5nCisgICAgICAocHJlZml4IF4gc3VmZml4KSwgc2luY2UgdGhpcyBzbGlnaHRseSBvYmZ1c2NhdGVzIHRoZSBoYXNoIHNlY3JldAorICAgICovCisgICAgaWYgKGxlbiA9PSAwKSB7CisgICAgICAgIHNlbGYtPmhhc2ggPSAwOworICAgICAgICByZXR1cm4gMDsKKyAgICB9CisgICAgcCA9IFB5VW5pY29kZV9BU19VTklDT0RFKHNlbGYpOworICAgIHggPSBfUHlfSGFzaFNlY3JldC5wcmVmaXg7CisgICAgeCBePSAqcCA8PCA3OworICAgIHdoaWxlICgtLWxlbiA+PSAwKQorICAgICAgICB4ID0gKDEwMDAwMDMqeCkgXiAqcCsrOworICAgIHggXj0gUHlVbmljb2RlX0dFVF9TSVpFKHNlbGYpOworICAgIHggXj0gX1B5X0hhc2hTZWNyZXQuc3VmZml4OworICAgIGlmICh4ID09IC0xKQorICAgICAgICB4ID0gLTI7CisgICAgc2VsZi0+aGFzaCA9IHg7CisgICAgcmV0dXJuIHg7Cit9CisKK1B5RG9jX1NUUlZBUihpbmRleF9fZG9jX18sCisgICAgICAgICAgICAgIlMuaW5kZXgoc3ViIFssc3RhcnQgWyxlbmRdXSkgLT4gaW50XG5cCitcblwKK0xpa2UgUy5maW5kKCkgYnV0IHJhaXNlIFZhbHVlRXJyb3Igd2hlbiB0aGUgc3Vic3RyaW5nIGlzIG5vdCBmb3VuZC4iKTsKKworc3RhdGljIFB5T2JqZWN0ICoKK3VuaWNvZGVfaW5kZXgoUHlVbmljb2RlT2JqZWN0ICpzZWxmLCBQeU9iamVjdCAqYXJncykKK3sKKyAgICBQeV9zc2l6ZV90IHJlc3VsdDsKKyAgICBQeVVuaWNvZGVPYmplY3QgKnN1YnN0cmluZzsKKyAgICBQeV9zc2l6ZV90IHN0YXJ0OworICAgIFB5X3NzaXplX3QgZW5kOworCisgICAgaWYgKCFzdHJpbmdsaWJfcGFyc2VfYXJnc19maW5kc191bmljb2RlKCJpbmRleCIsIGFyZ3MsICZzdWJzdHJpbmcsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZzdGFydCwgJmVuZCkpCisgICAgICAgIHJldHVybiBOVUxMOworCisgICAgcmVzdWx0ID0gc3RyaW5nbGliX2ZpbmRfc2xpY2UoCisgICAgICAgIFB5VW5pY29kZV9BU19VTklDT0RFKHNlbGYpLCBQeVVuaWNvZGVfR0VUX1NJWkUoc2VsZiksCisgICAgICAgIFB5VW5pY29kZV9BU19VTklDT0RFKHN1YnN0cmluZyksIFB5VW5pY29kZV9HRVRfU0laRShzdWJzdHJpbmcpLAorICAgICAgICBzdGFydCwgZW5kCisgICAgICAgICk7CisKKyAgICBQeV9ERUNSRUYoc3Vic3RyaW5nKTsKKworICAgIGlmIChyZXN1bHQgPCAwKSB7CisgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19WYWx1ZUVycm9yLCAic3Vic3RyaW5nIG5vdCBmb3VuZCIpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisKKyAgICByZXR1cm4gUHlJbnRfRnJvbVNzaXplX3QocmVzdWx0KTsKK30KKworUHlEb2NfU1RSVkFSKGlzbG93ZXJfX2RvY19fLAorICAgICAgICAgICAgICJTLmlzbG93ZXIoKSAtPiBib29sXG5cCitcblwKK1JldHVybiBUcnVlIGlmIGFsbCBjYXNlZCBjaGFyYWN0ZXJzIGluIFMgYXJlIGxvd2VyY2FzZSBhbmQgdGhlcmUgaXNcblwKK2F0IGxlYXN0IG9uZSBjYXNlZCBjaGFyYWN0ZXIgaW4gUywgRmFsc2Ugb3RoZXJ3aXNlLiIpOworCitzdGF0aWMgUHlPYmplY3QqCit1bmljb2RlX2lzbG93ZXIoUHlVbmljb2RlT2JqZWN0ICpzZWxmKQoreworICAgIHJlZ2lzdGVyIGNvbnN0IFB5X1VOSUNPREUgKnAgPSBQeVVuaWNvZGVfQVNfVU5JQ09ERShzZWxmKTsKKyAgICByZWdpc3RlciBjb25zdCBQeV9VTklDT0RFICplOworICAgIGludCBjYXNlZDsKKworICAgIC8qIFNob3J0Y3V0IGZvciBzaW5nbGUgY2hhcmFjdGVyIHN0cmluZ3MgKi8KKyAgICBpZiAoUHlVbmljb2RlX0dFVF9TSVpFKHNlbGYpID09IDEpCisgICAgICAgIHJldHVybiBQeUJvb2xfRnJvbUxvbmcoUHlfVU5JQ09ERV9JU0xPV0VSKCpwKSk7CisKKyAgICAvKiBTcGVjaWFsIGNhc2UgZm9yIGVtcHR5IHN0cmluZ3MgKi8KKyAgICBpZiAoUHlVbmljb2RlX0dFVF9TSVpFKHNlbGYpID09IDApCisgICAgICAgIHJldHVybiBQeUJvb2xfRnJvbUxvbmcoMCk7CisKKyAgICBlID0gcCArIFB5VW5pY29kZV9HRVRfU0laRShzZWxmKTsKKyAgICBjYXNlZCA9IDA7CisgICAgZm9yICg7IHAgPCBlOyBwKyspIHsKKyAgICAgICAgcmVnaXN0ZXIgY29uc3QgUHlfVU5JQ09ERSBjaCA9ICpwOworCisgICAgICAgIGlmIChQeV9VTklDT0RFX0lTVVBQRVIoY2gpIHx8IFB5X1VOSUNPREVfSVNUSVRMRShjaCkpCisgICAgICAgICAgICByZXR1cm4gUHlCb29sX0Zyb21Mb25nKDApOworICAgICAgICBlbHNlIGlmICghY2FzZWQgJiYgUHlfVU5JQ09ERV9JU0xPV0VSKGNoKSkKKyAgICAgICAgICAgIGNhc2VkID0gMTsKKyAgICB9CisgICAgcmV0dXJuIFB5Qm9vbF9Gcm9tTG9uZyhjYXNlZCk7Cit9CisKK1B5RG9jX1NUUlZBUihpc3VwcGVyX19kb2NfXywKKyAgICAgICAgICAgICAiUy5pc3VwcGVyKCkgLT4gYm9vbFxuXAorXG5cCitSZXR1cm4gVHJ1ZSBpZiBhbGwgY2FzZWQgY2hhcmFjdGVycyBpbiBTIGFyZSB1cHBlcmNhc2UgYW5kIHRoZXJlIGlzXG5cCithdCBsZWFzdCBvbmUgY2FzZWQgY2hhcmFjdGVyIGluIFMsIEZhbHNlIG90aGVyd2lzZS4iKTsKKworc3RhdGljIFB5T2JqZWN0KgordW5pY29kZV9pc3VwcGVyKFB5VW5pY29kZU9iamVjdCAqc2VsZikKK3sKKyAgICByZWdpc3RlciBjb25zdCBQeV9VTklDT0RFICpwID0gUHlVbmljb2RlX0FTX1VOSUNPREUoc2VsZik7CisgICAgcmVnaXN0ZXIgY29uc3QgUHlfVU5JQ09ERSAqZTsKKyAgICBpbnQgY2FzZWQ7CisKKyAgICAvKiBTaG9ydGN1dCBmb3Igc2luZ2xlIGNoYXJhY3RlciBzdHJpbmdzICovCisgICAgaWYgKFB5VW5pY29kZV9HRVRfU0laRShzZWxmKSA9PSAxKQorICAgICAgICByZXR1cm4gUHlCb29sX0Zyb21Mb25nKFB5X1VOSUNPREVfSVNVUFBFUigqcCkgIT0gMCk7CisKKyAgICAvKiBTcGVjaWFsIGNhc2UgZm9yIGVtcHR5IHN0cmluZ3MgKi8KKyAgICBpZiAoUHlVbmljb2RlX0dFVF9TSVpFKHNlbGYpID09IDApCisgICAgICAgIHJldHVybiBQeUJvb2xfRnJvbUxvbmcoMCk7CisKKyAgICBlID0gcCArIFB5VW5pY29kZV9HRVRfU0laRShzZWxmKTsKKyAgICBjYXNlZCA9IDA7CisgICAgZm9yICg7IHAgPCBlOyBwKyspIHsKKyAgICAgICAgcmVnaXN0ZXIgY29uc3QgUHlfVU5JQ09ERSBjaCA9ICpwOworCisgICAgICAgIGlmIChQeV9VTklDT0RFX0lTTE9XRVIoY2gpIHx8IFB5X1VOSUNPREVfSVNUSVRMRShjaCkpCisgICAgICAgICAgICByZXR1cm4gUHlCb29sX0Zyb21Mb25nKDApOworICAgICAgICBlbHNlIGlmICghY2FzZWQgJiYgUHlfVU5JQ09ERV9JU1VQUEVSKGNoKSkKKyAgICAgICAgICAgIGNhc2VkID0gMTsKKyAgICB9CisgICAgcmV0dXJuIFB5Qm9vbF9Gcm9tTG9uZyhjYXNlZCk7Cit9CisKK1B5RG9jX1NUUlZBUihpc3RpdGxlX19kb2NfXywKKyAgICAgICAgICAgICAiUy5pc3RpdGxlKCkgLT4gYm9vbFxuXAorXG5cCitSZXR1cm4gVHJ1ZSBpZiBTIGlzIGEgdGl0bGVjYXNlZCBzdHJpbmcgYW5kIHRoZXJlIGlzIGF0IGxlYXN0IG9uZVxuXAorY2hhcmFjdGVyIGluIFMsIGkuZS4gdXBwZXItIGFuZCB0aXRsZWNhc2UgY2hhcmFjdGVycyBtYXkgb25seVxuXAorZm9sbG93IHVuY2FzZWQgY2hhcmFjdGVycyBhbmQgbG93ZXJjYXNlIGNoYXJhY3RlcnMgb25seSBjYXNlZCBvbmVzLlxuXAorUmV0dXJuIEZhbHNlIG90aGVyd2lzZS4iKTsKKworc3RhdGljIFB5T2JqZWN0KgordW5pY29kZV9pc3RpdGxlKFB5VW5pY29kZU9iamVjdCAqc2VsZikKK3sKKyAgICByZWdpc3RlciBjb25zdCBQeV9VTklDT0RFICpwID0gUHlVbmljb2RlX0FTX1VOSUNPREUoc2VsZik7CisgICAgcmVnaXN0ZXIgY29uc3QgUHlfVU5JQ09ERSAqZTsKKyAgICBpbnQgY2FzZWQsIHByZXZpb3VzX2lzX2Nhc2VkOworCisgICAgLyogU2hvcnRjdXQgZm9yIHNpbmdsZSBjaGFyYWN0ZXIgc3RyaW5ncyAqLworICAgIGlmIChQeVVuaWNvZGVfR0VUX1NJWkUoc2VsZikgPT0gMSkKKyAgICAgICAgcmV0dXJuIFB5Qm9vbF9Gcm9tTG9uZygoUHlfVU5JQ09ERV9JU1RJVExFKCpwKSAhPSAwKSB8fAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChQeV9VTklDT0RFX0lTVVBQRVIoKnApICE9IDApKTsKKworICAgIC8qIFNwZWNpYWwgY2FzZSBmb3IgZW1wdHkgc3RyaW5ncyAqLworICAgIGlmIChQeVVuaWNvZGVfR0VUX1NJWkUoc2VsZikgPT0gMCkKKyAgICAgICAgcmV0dXJuIFB5Qm9vbF9Gcm9tTG9uZygwKTsKKworICAgIGUgPSBwICsgUHlVbmljb2RlX0dFVF9TSVpFKHNlbGYpOworICAgIGNhc2VkID0gMDsKKyAgICBwcmV2aW91c19pc19jYXNlZCA9IDA7CisgICAgZm9yICg7IHAgPCBlOyBwKyspIHsKKyAgICAgICAgcmVnaXN0ZXIgY29uc3QgUHlfVU5JQ09ERSBjaCA9ICpwOworCisgICAgICAgIGlmIChQeV9VTklDT0RFX0lTVVBQRVIoY2gpIHx8IFB5X1VOSUNPREVfSVNUSVRMRShjaCkpIHsKKyAgICAgICAgICAgIGlmIChwcmV2aW91c19pc19jYXNlZCkKKyAgICAgICAgICAgICAgICByZXR1cm4gUHlCb29sX0Zyb21Mb25nKDApOworICAgICAgICAgICAgcHJldmlvdXNfaXNfY2FzZWQgPSAxOworICAgICAgICAgICAgY2FzZWQgPSAxOworICAgICAgICB9CisgICAgICAgIGVsc2UgaWYgKFB5X1VOSUNPREVfSVNMT1dFUihjaCkpIHsKKyAgICAgICAgICAgIGlmICghcHJldmlvdXNfaXNfY2FzZWQpCisgICAgICAgICAgICAgICAgcmV0dXJuIFB5Qm9vbF9Gcm9tTG9uZygwKTsKKyAgICAgICAgICAgIHByZXZpb3VzX2lzX2Nhc2VkID0gMTsKKyAgICAgICAgICAgIGNhc2VkID0gMTsKKyAgICAgICAgfQorICAgICAgICBlbHNlCisgICAgICAgICAgICBwcmV2aW91c19pc19jYXNlZCA9IDA7CisgICAgfQorICAgIHJldHVybiBQeUJvb2xfRnJvbUxvbmcoY2FzZWQpOworfQorCitQeURvY19TVFJWQVIoaXNzcGFjZV9fZG9jX18sCisgICAgICAgICAgICAgIlMuaXNzcGFjZSgpIC0+IGJvb2xcblwKK1xuXAorUmV0dXJuIFRydWUgaWYgYWxsIGNoYXJhY3RlcnMgaW4gUyBhcmUgd2hpdGVzcGFjZVxuXAorYW5kIHRoZXJlIGlzIGF0IGxlYXN0IG9uZSBjaGFyYWN0ZXIgaW4gUywgRmFsc2Ugb3RoZXJ3aXNlLiIpOworCitzdGF0aWMgUHlPYmplY3QqCit1bmljb2RlX2lzc3BhY2UoUHlVbmljb2RlT2JqZWN0ICpzZWxmKQoreworICAgIHJlZ2lzdGVyIGNvbnN0IFB5X1VOSUNPREUgKnAgPSBQeVVuaWNvZGVfQVNfVU5JQ09ERShzZWxmKTsKKyAgICByZWdpc3RlciBjb25zdCBQeV9VTklDT0RFICplOworCisgICAgLyogU2hvcnRjdXQgZm9yIHNpbmdsZSBjaGFyYWN0ZXIgc3RyaW5ncyAqLworICAgIGlmIChQeVVuaWNvZGVfR0VUX1NJWkUoc2VsZikgPT0gMSAmJgorICAgICAgICBQeV9VTklDT0RFX0lTU1BBQ0UoKnApKQorICAgICAgICByZXR1cm4gUHlCb29sX0Zyb21Mb25nKDEpOworCisgICAgLyogU3BlY2lhbCBjYXNlIGZvciBlbXB0eSBzdHJpbmdzICovCisgICAgaWYgKFB5VW5pY29kZV9HRVRfU0laRShzZWxmKSA9PSAwKQorICAgICAgICByZXR1cm4gUHlCb29sX0Zyb21Mb25nKDApOworCisgICAgZSA9IHAgKyBQeVVuaWNvZGVfR0VUX1NJWkUoc2VsZik7CisgICAgZm9yICg7IHAgPCBlOyBwKyspIHsKKyAgICAgICAgaWYgKCFQeV9VTklDT0RFX0lTU1BBQ0UoKnApKQorICAgICAgICAgICAgcmV0dXJuIFB5Qm9vbF9Gcm9tTG9uZygwKTsKKyAgICB9CisgICAgcmV0dXJuIFB5Qm9vbF9Gcm9tTG9uZygxKTsKK30KKworUHlEb2NfU1RSVkFSKGlzYWxwaGFfX2RvY19fLAorICAgICAgICAgICAgICJTLmlzYWxwaGEoKSAtPiBib29sXG5cCitcblwKK1JldHVybiBUcnVlIGlmIGFsbCBjaGFyYWN0ZXJzIGluIFMgYXJlIGFscGhhYmV0aWNcblwKK2FuZCB0aGVyZSBpcyBhdCBsZWFzdCBvbmUgY2hhcmFjdGVyIGluIFMsIEZhbHNlIG90aGVyd2lzZS4iKTsKKworc3RhdGljIFB5T2JqZWN0KgordW5pY29kZV9pc2FscGhhKFB5VW5pY29kZU9iamVjdCAqc2VsZikKK3sKKyAgICByZWdpc3RlciBjb25zdCBQeV9VTklDT0RFICpwID0gUHlVbmljb2RlX0FTX1VOSUNPREUoc2VsZik7CisgICAgcmVnaXN0ZXIgY29uc3QgUHlfVU5JQ09ERSAqZTsKKworICAgIC8qIFNob3J0Y3V0IGZvciBzaW5nbGUgY2hhcmFjdGVyIHN0cmluZ3MgKi8KKyAgICBpZiAoUHlVbmljb2RlX0dFVF9TSVpFKHNlbGYpID09IDEgJiYKKyAgICAgICAgUHlfVU5JQ09ERV9JU0FMUEhBKCpwKSkKKyAgICAgICAgcmV0dXJuIFB5Qm9vbF9Gcm9tTG9uZygxKTsKKworICAgIC8qIFNwZWNpYWwgY2FzZSBmb3IgZW1wdHkgc3RyaW5ncyAqLworICAgIGlmIChQeVVuaWNvZGVfR0VUX1NJWkUoc2VsZikgPT0gMCkKKyAgICAgICAgcmV0dXJuIFB5Qm9vbF9Gcm9tTG9uZygwKTsKKworICAgIGUgPSBwICsgUHlVbmljb2RlX0dFVF9TSVpFKHNlbGYpOworICAgIGZvciAoOyBwIDwgZTsgcCsrKSB7CisgICAgICAgIGlmICghUHlfVU5JQ09ERV9JU0FMUEhBKCpwKSkKKyAgICAgICAgICAgIHJldHVybiBQeUJvb2xfRnJvbUxvbmcoMCk7CisgICAgfQorICAgIHJldHVybiBQeUJvb2xfRnJvbUxvbmcoMSk7Cit9CisKK1B5RG9jX1NUUlZBUihpc2FsbnVtX19kb2NfXywKKyAgICAgICAgICAgICAiUy5pc2FsbnVtKCkgLT4gYm9vbFxuXAorXG5cCitSZXR1cm4gVHJ1ZSBpZiBhbGwgY2hhcmFjdGVycyBpbiBTIGFyZSBhbHBoYW51bWVyaWNcblwKK2FuZCB0aGVyZSBpcyBhdCBsZWFzdCBvbmUgY2hhcmFjdGVyIGluIFMsIEZhbHNlIG90aGVyd2lzZS4iKTsKKworc3RhdGljIFB5T2JqZWN0KgordW5pY29kZV9pc2FsbnVtKFB5VW5pY29kZU9iamVjdCAqc2VsZikKK3sKKyAgICByZWdpc3RlciBjb25zdCBQeV9VTklDT0RFICpwID0gUHlVbmljb2RlX0FTX1VOSUNPREUoc2VsZik7CisgICAgcmVnaXN0ZXIgY29uc3QgUHlfVU5JQ09ERSAqZTsKKworICAgIC8qIFNob3J0Y3V0IGZvciBzaW5nbGUgY2hhcmFjdGVyIHN0cmluZ3MgKi8KKyAgICBpZiAoUHlVbmljb2RlX0dFVF9TSVpFKHNlbGYpID09IDEgJiYKKyAgICAgICAgUHlfVU5JQ09ERV9JU0FMTlVNKCpwKSkKKyAgICAgICAgcmV0dXJuIFB5Qm9vbF9Gcm9tTG9uZygxKTsKKworICAgIC8qIFNwZWNpYWwgY2FzZSBmb3IgZW1wdHkgc3RyaW5ncyAqLworICAgIGlmIChQeVVuaWNvZGVfR0VUX1NJWkUoc2VsZikgPT0gMCkKKyAgICAgICAgcmV0dXJuIFB5Qm9vbF9Gcm9tTG9uZygwKTsKKworICAgIGUgPSBwICsgUHlVbmljb2RlX0dFVF9TSVpFKHNlbGYpOworICAgIGZvciAoOyBwIDwgZTsgcCsrKSB7CisgICAgICAgIGlmICghUHlfVU5JQ09ERV9JU0FMTlVNKCpwKSkKKyAgICAgICAgICAgIHJldHVybiBQeUJvb2xfRnJvbUxvbmcoMCk7CisgICAgfQorICAgIHJldHVybiBQeUJvb2xfRnJvbUxvbmcoMSk7Cit9CisKK1B5RG9jX1NUUlZBUihpc2RlY2ltYWxfX2RvY19fLAorICAgICAgICAgICAgICJTLmlzZGVjaW1hbCgpIC0+IGJvb2xcblwKK1xuXAorUmV0dXJuIFRydWUgaWYgdGhlcmUgYXJlIG9ubHkgZGVjaW1hbCBjaGFyYWN0ZXJzIGluIFMsXG5cCitGYWxzZSBvdGhlcndpc2UuIik7CisKK3N0YXRpYyBQeU9iamVjdCoKK3VuaWNvZGVfaXNkZWNpbWFsKFB5VW5pY29kZU9iamVjdCAqc2VsZikKK3sKKyAgICByZWdpc3RlciBjb25zdCBQeV9VTklDT0RFICpwID0gUHlVbmljb2RlX0FTX1VOSUNPREUoc2VsZik7CisgICAgcmVnaXN0ZXIgY29uc3QgUHlfVU5JQ09ERSAqZTsKKworICAgIC8qIFNob3J0Y3V0IGZvciBzaW5nbGUgY2hhcmFjdGVyIHN0cmluZ3MgKi8KKyAgICBpZiAoUHlVbmljb2RlX0dFVF9TSVpFKHNlbGYpID09IDEgJiYKKyAgICAgICAgUHlfVU5JQ09ERV9JU0RFQ0lNQUwoKnApKQorICAgICAgICByZXR1cm4gUHlCb29sX0Zyb21Mb25nKDEpOworCisgICAgLyogU3BlY2lhbCBjYXNlIGZvciBlbXB0eSBzdHJpbmdzICovCisgICAgaWYgKFB5VW5pY29kZV9HRVRfU0laRShzZWxmKSA9PSAwKQorICAgICAgICByZXR1cm4gUHlCb29sX0Zyb21Mb25nKDApOworCisgICAgZSA9IHAgKyBQeVVuaWNvZGVfR0VUX1NJWkUoc2VsZik7CisgICAgZm9yICg7IHAgPCBlOyBwKyspIHsKKyAgICAgICAgaWYgKCFQeV9VTklDT0RFX0lTREVDSU1BTCgqcCkpCisgICAgICAgICAgICByZXR1cm4gUHlCb29sX0Zyb21Mb25nKDApOworICAgIH0KKyAgICByZXR1cm4gUHlCb29sX0Zyb21Mb25nKDEpOworfQorCitQeURvY19TVFJWQVIoaXNkaWdpdF9fZG9jX18sCisgICAgICAgICAgICAgIlMuaXNkaWdpdCgpIC0+IGJvb2xcblwKK1xuXAorUmV0dXJuIFRydWUgaWYgYWxsIGNoYXJhY3RlcnMgaW4gUyBhcmUgZGlnaXRzXG5cCithbmQgdGhlcmUgaXMgYXQgbGVhc3Qgb25lIGNoYXJhY3RlciBpbiBTLCBGYWxzZSBvdGhlcndpc2UuIik7CisKK3N0YXRpYyBQeU9iamVjdCoKK3VuaWNvZGVfaXNkaWdpdChQeVVuaWNvZGVPYmplY3QgKnNlbGYpCit7CisgICAgcmVnaXN0ZXIgY29uc3QgUHlfVU5JQ09ERSAqcCA9IFB5VW5pY29kZV9BU19VTklDT0RFKHNlbGYpOworICAgIHJlZ2lzdGVyIGNvbnN0IFB5X1VOSUNPREUgKmU7CisKKyAgICAvKiBTaG9ydGN1dCBmb3Igc2luZ2xlIGNoYXJhY3RlciBzdHJpbmdzICovCisgICAgaWYgKFB5VW5pY29kZV9HRVRfU0laRShzZWxmKSA9PSAxICYmCisgICAgICAgIFB5X1VOSUNPREVfSVNESUdJVCgqcCkpCisgICAgICAgIHJldHVybiBQeUJvb2xfRnJvbUxvbmcoMSk7CisKKyAgICAvKiBTcGVjaWFsIGNhc2UgZm9yIGVtcHR5IHN0cmluZ3MgKi8KKyAgICBpZiAoUHlVbmljb2RlX0dFVF9TSVpFKHNlbGYpID09IDApCisgICAgICAgIHJldHVybiBQeUJvb2xfRnJvbUxvbmcoMCk7CisKKyAgICBlID0gcCArIFB5VW5pY29kZV9HRVRfU0laRShzZWxmKTsKKyAgICBmb3IgKDsgcCA8IGU7IHArKykgeworICAgICAgICBpZiAoIVB5X1VOSUNPREVfSVNESUdJVCgqcCkpCisgICAgICAgICAgICByZXR1cm4gUHlCb29sX0Zyb21Mb25nKDApOworICAgIH0KKyAgICByZXR1cm4gUHlCb29sX0Zyb21Mb25nKDEpOworfQorCitQeURvY19TVFJWQVIoaXNudW1lcmljX19kb2NfXywKKyAgICAgICAgICAgICAiUy5pc251bWVyaWMoKSAtPiBib29sXG5cCitcblwKK1JldHVybiBUcnVlIGlmIHRoZXJlIGFyZSBvbmx5IG51bWVyaWMgY2hhcmFjdGVycyBpbiBTLFxuXAorRmFsc2Ugb3RoZXJ3aXNlLiIpOworCitzdGF0aWMgUHlPYmplY3QqCit1bmljb2RlX2lzbnVtZXJpYyhQeVVuaWNvZGVPYmplY3QgKnNlbGYpCit7CisgICAgcmVnaXN0ZXIgY29uc3QgUHlfVU5JQ09ERSAqcCA9IFB5VW5pY29kZV9BU19VTklDT0RFKHNlbGYpOworICAgIHJlZ2lzdGVyIGNvbnN0IFB5X1VOSUNPREUgKmU7CisKKyAgICAvKiBTaG9ydGN1dCBmb3Igc2luZ2xlIGNoYXJhY3RlciBzdHJpbmdzICovCisgICAgaWYgKFB5VW5pY29kZV9HRVRfU0laRShzZWxmKSA9PSAxICYmCisgICAgICAgIFB5X1VOSUNPREVfSVNOVU1FUklDKCpwKSkKKyAgICAgICAgcmV0dXJuIFB5Qm9vbF9Gcm9tTG9uZygxKTsKKworICAgIC8qIFNwZWNpYWwgY2FzZSBmb3IgZW1wdHkgc3RyaW5ncyAqLworICAgIGlmIChQeVVuaWNvZGVfR0VUX1NJWkUoc2VsZikgPT0gMCkKKyAgICAgICAgcmV0dXJuIFB5Qm9vbF9Gcm9tTG9uZygwKTsKKworICAgIGUgPSBwICsgUHlVbmljb2RlX0dFVF9TSVpFKHNlbGYpOworICAgIGZvciAoOyBwIDwgZTsgcCsrKSB7CisgICAgICAgIGlmICghUHlfVU5JQ09ERV9JU05VTUVSSUMoKnApKQorICAgICAgICAgICAgcmV0dXJuIFB5Qm9vbF9Gcm9tTG9uZygwKTsKKyAgICB9CisgICAgcmV0dXJuIFB5Qm9vbF9Gcm9tTG9uZygxKTsKK30KKworUHlEb2NfU1RSVkFSKGpvaW5fX2RvY19fLAorICAgICAgICAgICAgICJTLmpvaW4oaXRlcmFibGUpIC0+IHVuaWNvZGVcblwKK1xuXAorUmV0dXJuIGEgc3RyaW5nIHdoaWNoIGlzIHRoZSBjb25jYXRlbmF0aW9uIG9mIHRoZSBzdHJpbmdzIGluIHRoZVxuXAoraXRlcmFibGUuICBUaGUgc2VwYXJhdG9yIGJldHdlZW4gZWxlbWVudHMgaXMgUy4iKTsKKworc3RhdGljIFB5T2JqZWN0KgordW5pY29kZV9qb2luKFB5T2JqZWN0ICpzZWxmLCBQeU9iamVjdCAqZGF0YSkKK3sKKyAgICByZXR1cm4gUHlVbmljb2RlX0pvaW4oc2VsZiwgZGF0YSk7Cit9CisKK3N0YXRpYyBQeV9zc2l6ZV90Cit1bmljb2RlX2xlbmd0aChQeVVuaWNvZGVPYmplY3QgKnNlbGYpCit7CisgICAgcmV0dXJuIHNlbGYtPmxlbmd0aDsKK30KKworUHlEb2NfU1RSVkFSKGxqdXN0X19kb2NfXywKKyAgICAgICAgICAgICAiUy5sanVzdCh3aWR0aFssIGZpbGxjaGFyXSkgLT4gaW50XG5cCitcblwKK1JldHVybiBTIGxlZnQtanVzdGlmaWVkIGluIGEgVW5pY29kZSBzdHJpbmcgb2YgbGVuZ3RoIHdpZHRoLiBQYWRkaW5nIGlzXG5cCitkb25lIHVzaW5nIHRoZSBzcGVjaWZpZWQgZmlsbCBjaGFyYWN0ZXIgKGRlZmF1bHQgaXMgYSBzcGFjZSkuIik7CisKK3N0YXRpYyBQeU9iamVjdCAqCit1bmljb2RlX2xqdXN0KFB5VW5pY29kZU9iamVjdCAqc2VsZiwgUHlPYmplY3QgKmFyZ3MpCit7CisgICAgUHlfc3NpemVfdCB3aWR0aDsKKyAgICBQeV9VTklDT0RFIGZpbGxjaGFyID0gJyAnOworCisgICAgaWYgKCFQeUFyZ19QYXJzZVR1cGxlKGFyZ3MsICJufE8mOmxqdXN0IiwgJndpZHRoLCBjb252ZXJ0X3VjLCAmZmlsbGNoYXIpKQorICAgICAgICByZXR1cm4gTlVMTDsKKworICAgIGlmIChzZWxmLT5sZW5ndGggPj0gd2lkdGggJiYgUHlVbmljb2RlX0NoZWNrRXhhY3Qoc2VsZikpIHsKKyAgICAgICAgUHlfSU5DUkVGKHNlbGYpOworICAgICAgICByZXR1cm4gKFB5T2JqZWN0Kikgc2VsZjsKKyAgICB9CisKKyAgICByZXR1cm4gKFB5T2JqZWN0KikgcGFkKHNlbGYsIDAsIHdpZHRoIC0gc2VsZi0+bGVuZ3RoLCBmaWxsY2hhcik7Cit9CisKK1B5RG9jX1NUUlZBUihsb3dlcl9fZG9jX18sCisgICAgICAgICAgICAgIlMubG93ZXIoKSAtPiB1bmljb2RlXG5cCitcblwKK1JldHVybiBhIGNvcHkgb2YgdGhlIHN0cmluZyBTIGNvbnZlcnRlZCB0byBsb3dlcmNhc2UuIik7CisKK3N0YXRpYyBQeU9iamVjdCoKK3VuaWNvZGVfbG93ZXIoUHlVbmljb2RlT2JqZWN0ICpzZWxmKQoreworICAgIHJldHVybiBmaXh1cChzZWxmLCBmaXhsb3dlcik7Cit9CisKKyNkZWZpbmUgTEVGVFNUUklQIDAKKyNkZWZpbmUgUklHSFRTVFJJUCAxCisjZGVmaW5lIEJPVEhTVFJJUCAyCisKKy8qIEFycmF5cyBpbmRleGVkIGJ5IGFib3ZlICovCitzdGF0aWMgY29uc3QgY2hhciAqc3RyaXBmb3JtYXRbXSA9IHsifE86bHN0cmlwIiwgInxPOnJzdHJpcCIsICJ8TzpzdHJpcCJ9OworCisjZGVmaW5lIFNUUklQTkFNRShpKSAoc3RyaXBmb3JtYXRbaV0rMykKKworLyogZXh0ZXJuYWxseSB2aXNpYmxlIGZvciBzdHIuc3RyaXAodW5pY29kZSkgKi8KK1B5T2JqZWN0ICoKK19QeVVuaWNvZGVfWFN0cmlwKFB5VW5pY29kZU9iamVjdCAqc2VsZiwgaW50IHN0cmlwdHlwZSwgUHlPYmplY3QgKnNlcG9iaikKK3sKKyAgICBQeV9VTklDT0RFICpzID0gUHlVbmljb2RlX0FTX1VOSUNPREUoc2VsZik7CisgICAgUHlfc3NpemVfdCBsZW4gPSBQeVVuaWNvZGVfR0VUX1NJWkUoc2VsZik7CisgICAgUHlfVU5JQ09ERSAqc2VwID0gUHlVbmljb2RlX0FTX1VOSUNPREUoc2Vwb2JqKTsKKyAgICBQeV9zc2l6ZV90IHNlcGxlbiA9IFB5VW5pY29kZV9HRVRfU0laRShzZXBvYmopOworICAgIFB5X3NzaXplX3QgaSwgajsKKworICAgIEJMT09NX01BU0sgc2VwbWFzayA9IG1ha2VfYmxvb21fbWFzayhzZXAsIHNlcGxlbik7CisKKyAgICBpID0gMDsKKyAgICBpZiAoc3RyaXB0eXBlICE9IFJJR0hUU1RSSVApIHsKKyAgICAgICAgd2hpbGUgKGkgPCBsZW4gJiYgQkxPT01fTUVNQkVSKHNlcG1hc2ssIHNbaV0sIHNlcCwgc2VwbGVuKSkgeworICAgICAgICAgICAgaSsrOworICAgICAgICB9CisgICAgfQorCisgICAgaiA9IGxlbjsKKyAgICBpZiAoc3RyaXB0eXBlICE9IExFRlRTVFJJUCkgeworICAgICAgICBkbyB7CisgICAgICAgICAgICBqLS07CisgICAgICAgIH0gd2hpbGUgKGogPj0gaSAmJiBCTE9PTV9NRU1CRVIoc2VwbWFzaywgc1tqXSwgc2VwLCBzZXBsZW4pKTsKKyAgICAgICAgaisrOworICAgIH0KKworICAgIGlmIChpID09IDAgJiYgaiA9PSBsZW4gJiYgUHlVbmljb2RlX0NoZWNrRXhhY3Qoc2VsZikpIHsKKyAgICAgICAgUHlfSU5DUkVGKHNlbGYpOworICAgICAgICByZXR1cm4gKFB5T2JqZWN0KilzZWxmOworICAgIH0KKyAgICBlbHNlCisgICAgICAgIHJldHVybiBQeVVuaWNvZGVfRnJvbVVuaWNvZGUocytpLCBqLWkpOworfQorCisKK3N0YXRpYyBQeU9iamVjdCAqCitkb19zdHJpcChQeVVuaWNvZGVPYmplY3QgKnNlbGYsIGludCBzdHJpcHR5cGUpCit7CisgICAgUHlfVU5JQ09ERSAqcyA9IFB5VW5pY29kZV9BU19VTklDT0RFKHNlbGYpOworICAgIFB5X3NzaXplX3QgbGVuID0gUHlVbmljb2RlX0dFVF9TSVpFKHNlbGYpLCBpLCBqOworCisgICAgaSA9IDA7CisgICAgaWYgKHN0cmlwdHlwZSAhPSBSSUdIVFNUUklQKSB7CisgICAgICAgIHdoaWxlIChpIDwgbGVuICYmIFB5X1VOSUNPREVfSVNTUEFDRShzW2ldKSkgeworICAgICAgICAgICAgaSsrOworICAgICAgICB9CisgICAgfQorCisgICAgaiA9IGxlbjsKKyAgICBpZiAoc3RyaXB0eXBlICE9IExFRlRTVFJJUCkgeworICAgICAgICBkbyB7CisgICAgICAgICAgICBqLS07CisgICAgICAgIH0gd2hpbGUgKGogPj0gaSAmJiBQeV9VTklDT0RFX0lTU1BBQ0Uoc1tqXSkpOworICAgICAgICBqKys7CisgICAgfQorCisgICAgaWYgKGkgPT0gMCAmJiBqID09IGxlbiAmJiBQeVVuaWNvZGVfQ2hlY2tFeGFjdChzZWxmKSkgeworICAgICAgICBQeV9JTkNSRUYoc2VsZik7CisgICAgICAgIHJldHVybiAoUHlPYmplY3QqKXNlbGY7CisgICAgfQorICAgIGVsc2UKKyAgICAgICAgcmV0dXJuIFB5VW5pY29kZV9Gcm9tVW5pY29kZShzK2ksIGotaSk7Cit9CisKKworc3RhdGljIFB5T2JqZWN0ICoKK2RvX2FyZ3N0cmlwKFB5VW5pY29kZU9iamVjdCAqc2VsZiwgaW50IHN0cmlwdHlwZSwgUHlPYmplY3QgKmFyZ3MpCit7CisgICAgUHlPYmplY3QgKnNlcCA9IE5VTEw7CisKKyAgICBpZiAoIVB5QXJnX1BhcnNlVHVwbGUoYXJncywgKGNoYXIgKilzdHJpcGZvcm1hdFtzdHJpcHR5cGVdLCAmc2VwKSkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisKKyAgICBpZiAoc2VwICE9IE5VTEwgJiYgc2VwICE9IFB5X05vbmUpIHsKKyAgICAgICAgaWYgKFB5VW5pY29kZV9DaGVjayhzZXApKQorICAgICAgICAgICAgcmV0dXJuIF9QeVVuaWNvZGVfWFN0cmlwKHNlbGYsIHN0cmlwdHlwZSwgc2VwKTsKKyAgICAgICAgZWxzZSBpZiAoUHlTdHJpbmdfQ2hlY2soc2VwKSkgeworICAgICAgICAgICAgUHlPYmplY3QgKnJlczsKKyAgICAgICAgICAgIHNlcCA9IFB5VW5pY29kZV9Gcm9tT2JqZWN0KHNlcCk7CisgICAgICAgICAgICBpZiAoc2VwPT1OVUxMKQorICAgICAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgICAgICAgICAgcmVzID0gX1B5VW5pY29kZV9YU3RyaXAoc2VsZiwgc3RyaXB0eXBlLCBzZXApOworICAgICAgICAgICAgUHlfREVDUkVGKHNlcCk7CisgICAgICAgICAgICByZXR1cm4gcmVzOworICAgICAgICB9CisgICAgICAgIGVsc2UgeworICAgICAgICAgICAgUHlFcnJfRm9ybWF0KFB5RXhjX1R5cGVFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAiJXMgYXJnIG11c3QgYmUgTm9uZSwgdW5pY29kZSBvciBzdHIiLAorICAgICAgICAgICAgICAgICAgICAgICAgIFNUUklQTkFNRShzdHJpcHR5cGUpKTsKKyAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgICAgICB9CisgICAgfQorCisgICAgcmV0dXJuIGRvX3N0cmlwKHNlbGYsIHN0cmlwdHlwZSk7Cit9CisKKworUHlEb2NfU1RSVkFSKHN0cmlwX19kb2NfXywKKyAgICAgICAgICAgICAiUy5zdHJpcChbY2hhcnNdKSAtPiB1bmljb2RlXG5cCitcblwKK1JldHVybiBhIGNvcHkgb2YgdGhlIHN0cmluZyBTIHdpdGggbGVhZGluZyBhbmQgdHJhaWxpbmdcblwKK3doaXRlc3BhY2UgcmVtb3ZlZC5cblwKK0lmIGNoYXJzIGlzIGdpdmVuIGFuZCBub3QgTm9uZSwgcmVtb3ZlIGNoYXJhY3RlcnMgaW4gY2hhcnMgaW5zdGVhZC5cblwKK0lmIGNoYXJzIGlzIGEgc3RyLCBpdCB3aWxsIGJlIGNvbnZlcnRlZCB0byB1bmljb2RlIGJlZm9yZSBzdHJpcHBpbmciKTsKKworc3RhdGljIFB5T2JqZWN0ICoKK3VuaWNvZGVfc3RyaXAoUHlVbmljb2RlT2JqZWN0ICpzZWxmLCBQeU9iamVjdCAqYXJncykKK3sKKyAgICBpZiAoUHlUdXBsZV9HRVRfU0laRShhcmdzKSA9PSAwKQorICAgICAgICByZXR1cm4gZG9fc3RyaXAoc2VsZiwgQk9USFNUUklQKTsgLyogQ29tbW9uIGNhc2UgKi8KKyAgICBlbHNlCisgICAgICAgIHJldHVybiBkb19hcmdzdHJpcChzZWxmLCBCT1RIU1RSSVAsIGFyZ3MpOworfQorCisKK1B5RG9jX1NUUlZBUihsc3RyaXBfX2RvY19fLAorICAgICAgICAgICAgICJTLmxzdHJpcChbY2hhcnNdKSAtPiB1bmljb2RlXG5cCitcblwKK1JldHVybiBhIGNvcHkgb2YgdGhlIHN0cmluZyBTIHdpdGggbGVhZGluZyB3aGl0ZXNwYWNlIHJlbW92ZWQuXG5cCitJZiBjaGFycyBpcyBnaXZlbiBhbmQgbm90IE5vbmUsIHJlbW92ZSBjaGFyYWN0ZXJzIGluIGNoYXJzIGluc3RlYWQuXG5cCitJZiBjaGFycyBpcyBhIHN0ciwgaXQgd2lsbCBiZSBjb252ZXJ0ZWQgdG8gdW5pY29kZSBiZWZvcmUgc3RyaXBwaW5nIik7CisKK3N0YXRpYyBQeU9iamVjdCAqCit1bmljb2RlX2xzdHJpcChQeVVuaWNvZGVPYmplY3QgKnNlbGYsIFB5T2JqZWN0ICphcmdzKQoreworICAgIGlmIChQeVR1cGxlX0dFVF9TSVpFKGFyZ3MpID09IDApCisgICAgICAgIHJldHVybiBkb19zdHJpcChzZWxmLCBMRUZUU1RSSVApOyAvKiBDb21tb24gY2FzZSAqLworICAgIGVsc2UKKyAgICAgICAgcmV0dXJuIGRvX2FyZ3N0cmlwKHNlbGYsIExFRlRTVFJJUCwgYXJncyk7Cit9CisKKworUHlEb2NfU1RSVkFSKHJzdHJpcF9fZG9jX18sCisgICAgICAgICAgICAgIlMucnN0cmlwKFtjaGFyc10pIC0+IHVuaWNvZGVcblwKK1xuXAorUmV0dXJuIGEgY29weSBvZiB0aGUgc3RyaW5nIFMgd2l0aCB0cmFpbGluZyB3aGl0ZXNwYWNlIHJlbW92ZWQuXG5cCitJZiBjaGFycyBpcyBnaXZlbiBhbmQgbm90IE5vbmUsIHJlbW92ZSBjaGFyYWN0ZXJzIGluIGNoYXJzIGluc3RlYWQuXG5cCitJZiBjaGFycyBpcyBhIHN0ciwgaXQgd2lsbCBiZSBjb252ZXJ0ZWQgdG8gdW5pY29kZSBiZWZvcmUgc3RyaXBwaW5nIik7CisKK3N0YXRpYyBQeU9iamVjdCAqCit1bmljb2RlX3JzdHJpcChQeVVuaWNvZGVPYmplY3QgKnNlbGYsIFB5T2JqZWN0ICphcmdzKQoreworICAgIGlmIChQeVR1cGxlX0dFVF9TSVpFKGFyZ3MpID09IDApCisgICAgICAgIHJldHVybiBkb19zdHJpcChzZWxmLCBSSUdIVFNUUklQKTsgLyogQ29tbW9uIGNhc2UgKi8KKyAgICBlbHNlCisgICAgICAgIHJldHVybiBkb19hcmdzdHJpcChzZWxmLCBSSUdIVFNUUklQLCBhcmdzKTsKK30KKworCitzdGF0aWMgUHlPYmplY3QqCit1bmljb2RlX3JlcGVhdChQeVVuaWNvZGVPYmplY3QgKnN0ciwgUHlfc3NpemVfdCBsZW4pCit7CisgICAgUHlVbmljb2RlT2JqZWN0ICp1OworICAgIFB5X1VOSUNPREUgKnA7CisgICAgUHlfc3NpemVfdCBuY2hhcnM7CisgICAgc2l6ZV90IG5ieXRlczsKKworICAgIGlmIChsZW4gPCAwKQorICAgICAgICBsZW4gPSAwOworCisgICAgaWYgKGxlbiA9PSAxICYmIFB5VW5pY29kZV9DaGVja0V4YWN0KHN0cikpIHsKKyAgICAgICAgLyogbm8gcmVwZWF0LCByZXR1cm4gb3JpZ2luYWwgc3RyaW5nICovCisgICAgICAgIFB5X0lOQ1JFRihzdHIpOworICAgICAgICByZXR1cm4gKFB5T2JqZWN0Kikgc3RyOworICAgIH0KKworICAgIC8qIGVuc3VyZSAjIG9mIGNoYXJzIG5lZWRlZCBkb2Vzbid0IG92ZXJmbG93IGludCBhbmQgIyBvZiBieXRlcworICAgICAqIG5lZWRlZCBkb2Vzbid0IG92ZXJmbG93IHNpemVfdAorICAgICAqLworICAgIG5jaGFycyA9IGxlbiAqIHN0ci0+bGVuZ3RoOworICAgIGlmIChsZW4gJiYgbmNoYXJzIC8gbGVuICE9IHN0ci0+bGVuZ3RoKSB7CisgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19PdmVyZmxvd0Vycm9yLAorICAgICAgICAgICAgICAgICAgICAgICAgInJlcGVhdGVkIHN0cmluZyBpcyB0b28gbG9uZyIpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgbmJ5dGVzID0gKG5jaGFycyArIDEpICogc2l6ZW9mKFB5X1VOSUNPREUpOworICAgIGlmIChuYnl0ZXMgLyBzaXplb2YoUHlfVU5JQ09ERSkgIT0gKHNpemVfdCkobmNoYXJzICsgMSkpIHsKKyAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX092ZXJmbG93RXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAgICAicmVwZWF0ZWQgc3RyaW5nIGlzIHRvbyBsb25nIik7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICB1ID0gX1B5VW5pY29kZV9OZXcobmNoYXJzKTsKKyAgICBpZiAoIXUpCisgICAgICAgIHJldHVybiBOVUxMOworCisgICAgcCA9IHUtPnN0cjsKKworICAgIGlmIChzdHItPmxlbmd0aCA9PSAxICYmIGxlbiA+IDApIHsKKyAgICAgICAgUHlfVU5JQ09ERV9GSUxMKHAsIHN0ci0+c3RyWzBdLCBsZW4pOworICAgIH0gZWxzZSB7CisgICAgICAgIFB5X3NzaXplX3QgZG9uZSA9IDA7IC8qIG51bWJlciBvZiBjaGFyYWN0ZXJzIGNvcGllZCB0aGlzIGZhciAqLworICAgICAgICBpZiAoZG9uZSA8IG5jaGFycykgeworICAgICAgICAgICAgUHlfVU5JQ09ERV9DT1BZKHAsIHN0ci0+c3RyLCBzdHItPmxlbmd0aCk7CisgICAgICAgICAgICBkb25lID0gc3RyLT5sZW5ndGg7CisgICAgICAgIH0KKyAgICAgICAgd2hpbGUgKGRvbmUgPCBuY2hhcnMpIHsKKyAgICAgICAgICAgIFB5X3NzaXplX3QgbiA9IChkb25lIDw9IG5jaGFycy1kb25lKSA/IGRvbmUgOiBuY2hhcnMtZG9uZTsKKyAgICAgICAgICAgIFB5X1VOSUNPREVfQ09QWShwK2RvbmUsIHAsIG4pOworICAgICAgICAgICAgZG9uZSArPSBuOworICAgICAgICB9CisgICAgfQorCisgICAgcmV0dXJuIChQeU9iamVjdCopIHU7Cit9CisKK1B5T2JqZWN0ICpQeVVuaWNvZGVfUmVwbGFjZShQeU9iamVjdCAqb2JqLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIFB5T2JqZWN0ICpzdWJvYmosCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHlPYmplY3QgKnJlcGxvYmosCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHlfc3NpemVfdCBtYXhjb3VudCkKK3sKKyAgICBQeU9iamVjdCAqc2VsZjsKKyAgICBQeU9iamVjdCAqc3RyMTsKKyAgICBQeU9iamVjdCAqc3RyMjsKKyAgICBQeU9iamVjdCAqcmVzdWx0OworCisgICAgc2VsZiA9IFB5VW5pY29kZV9Gcm9tT2JqZWN0KG9iaik7CisgICAgaWYgKHNlbGYgPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgc3RyMSA9IFB5VW5pY29kZV9Gcm9tT2JqZWN0KHN1Ym9iaik7CisgICAgaWYgKHN0cjEgPT0gTlVMTCkgeworICAgICAgICBQeV9ERUNSRUYoc2VsZik7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICBzdHIyID0gUHlVbmljb2RlX0Zyb21PYmplY3QocmVwbG9iaik7CisgICAgaWYgKHN0cjIgPT0gTlVMTCkgeworICAgICAgICBQeV9ERUNSRUYoc2VsZik7CisgICAgICAgIFB5X0RFQ1JFRihzdHIxKTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIHJlc3VsdCA9IHJlcGxhY2UoKFB5VW5pY29kZU9iamVjdCAqKXNlbGYsCisgICAgICAgICAgICAgICAgICAgICAoUHlVbmljb2RlT2JqZWN0ICopc3RyMSwKKyAgICAgICAgICAgICAgICAgICAgIChQeVVuaWNvZGVPYmplY3QgKilzdHIyLAorICAgICAgICAgICAgICAgICAgICAgbWF4Y291bnQpOworICAgIFB5X0RFQ1JFRihzZWxmKTsKKyAgICBQeV9ERUNSRUYoc3RyMSk7CisgICAgUHlfREVDUkVGKHN0cjIpOworICAgIHJldHVybiByZXN1bHQ7Cit9CisKK1B5RG9jX1NUUlZBUihyZXBsYWNlX19kb2NfXywKKyAgICAgICAgICAgICAiUy5yZXBsYWNlKG9sZCwgbmV3WywgY291bnRdKSAtPiB1bmljb2RlXG5cCitcblwKK1JldHVybiBhIGNvcHkgb2YgUyB3aXRoIGFsbCBvY2N1cnJlbmNlcyBvZiBzdWJzdHJpbmdcblwKK29sZCByZXBsYWNlZCBieSBuZXcuICBJZiB0aGUgb3B0aW9uYWwgYXJndW1lbnQgY291bnQgaXNcblwKK2dpdmVuLCBvbmx5IHRoZSBmaXJzdCBjb3VudCBvY2N1cnJlbmNlcyBhcmUgcmVwbGFjZWQuIik7CisKK3N0YXRpYyBQeU9iamVjdCoKK3VuaWNvZGVfcmVwbGFjZShQeVVuaWNvZGVPYmplY3QgKnNlbGYsIFB5T2JqZWN0ICphcmdzKQoreworICAgIFB5VW5pY29kZU9iamVjdCAqc3RyMTsKKyAgICBQeVVuaWNvZGVPYmplY3QgKnN0cjI7CisgICAgUHlfc3NpemVfdCBtYXhjb3VudCA9IC0xOworICAgIFB5T2JqZWN0ICpyZXN1bHQ7CisKKyAgICBpZiAoIVB5QXJnX1BhcnNlVHVwbGUoYXJncywgIk9PfG46cmVwbGFjZSIsICZzdHIxLCAmc3RyMiwgJm1heGNvdW50KSkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgc3RyMSA9IChQeVVuaWNvZGVPYmplY3QgKilQeVVuaWNvZGVfRnJvbU9iamVjdCgoUHlPYmplY3QgKilzdHIxKTsKKyAgICBpZiAoc3RyMSA9PSBOVUxMKQorICAgICAgICByZXR1cm4gTlVMTDsKKyAgICBzdHIyID0gKFB5VW5pY29kZU9iamVjdCAqKVB5VW5pY29kZV9Gcm9tT2JqZWN0KChQeU9iamVjdCAqKXN0cjIpOworICAgIGlmIChzdHIyID09IE5VTEwpIHsKKyAgICAgICAgUHlfREVDUkVGKHN0cjEpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisKKyAgICByZXN1bHQgPSByZXBsYWNlKHNlbGYsIHN0cjEsIHN0cjIsIG1heGNvdW50KTsKKworICAgIFB5X0RFQ1JFRihzdHIxKTsKKyAgICBQeV9ERUNSRUYoc3RyMik7CisgICAgcmV0dXJuIHJlc3VsdDsKK30KKworc3RhdGljCitQeU9iamVjdCAqdW5pY29kZV9yZXByKFB5T2JqZWN0ICp1bmljb2RlKQoreworICAgIHJldHVybiB1bmljb2RlZXNjYXBlX3N0cmluZyhQeVVuaWNvZGVfQVNfVU5JQ09ERSh1bmljb2RlKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHlVbmljb2RlX0dFVF9TSVpFKHVuaWNvZGUpLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAxKTsKK30KKworUHlEb2NfU1RSVkFSKHJmaW5kX19kb2NfXywKKyAgICAgICAgICAgICAiUy5yZmluZChzdWIgWyxzdGFydCBbLGVuZF1dKSAtPiBpbnRcblwKK1xuXAorUmV0dXJuIHRoZSBoaWdoZXN0IGluZGV4IGluIFMgd2hlcmUgc3Vic3RyaW5nIHN1YiBpcyBmb3VuZCxcblwKK3N1Y2ggdGhhdCBzdWIgaXMgY29udGFpbmVkIHdpdGhpbiBTW3N0YXJ0OmVuZF0uICBPcHRpb25hbFxuXAorYXJndW1lbnRzIHN0YXJ0IGFuZCBlbmQgYXJlIGludGVycHJldGVkIGFzIGluIHNsaWNlIG5vdGF0aW9uLlxuXAorXG5cCitSZXR1cm4gLTEgb24gZmFpbHVyZS4iKTsKKworc3RhdGljIFB5T2JqZWN0ICoKK3VuaWNvZGVfcmZpbmQoUHlVbmljb2RlT2JqZWN0ICpzZWxmLCBQeU9iamVjdCAqYXJncykKK3sKKyAgICBQeVVuaWNvZGVPYmplY3QgKnN1YnN0cmluZzsKKyAgICBQeV9zc2l6ZV90IHN0YXJ0OworICAgIFB5X3NzaXplX3QgZW5kOworICAgIFB5X3NzaXplX3QgcmVzdWx0OworCisgICAgaWYgKCFzdHJpbmdsaWJfcGFyc2VfYXJnc19maW5kc191bmljb2RlKCJyZmluZCIsIGFyZ3MsICZzdWJzdHJpbmcsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZzdGFydCwgJmVuZCkpCisgICAgICAgIHJldHVybiBOVUxMOworCisgICAgcmVzdWx0ID0gc3RyaW5nbGliX3JmaW5kX3NsaWNlKAorICAgICAgICBQeVVuaWNvZGVfQVNfVU5JQ09ERShzZWxmKSwgUHlVbmljb2RlX0dFVF9TSVpFKHNlbGYpLAorICAgICAgICBQeVVuaWNvZGVfQVNfVU5JQ09ERShzdWJzdHJpbmcpLCBQeVVuaWNvZGVfR0VUX1NJWkUoc3Vic3RyaW5nKSwKKyAgICAgICAgc3RhcnQsIGVuZAorICAgICAgICApOworCisgICAgUHlfREVDUkVGKHN1YnN0cmluZyk7CisKKyAgICByZXR1cm4gUHlJbnRfRnJvbVNzaXplX3QocmVzdWx0KTsKK30KKworUHlEb2NfU1RSVkFSKHJpbmRleF9fZG9jX18sCisgICAgICAgICAgICAgIlMucmluZGV4KHN1YiBbLHN0YXJ0IFssZW5kXV0pIC0+IGludFxuXAorXG5cCitMaWtlIFMucmZpbmQoKSBidXQgcmFpc2UgVmFsdWVFcnJvciB3aGVuIHRoZSBzdWJzdHJpbmcgaXMgbm90IGZvdW5kLiIpOworCitzdGF0aWMgUHlPYmplY3QgKgordW5pY29kZV9yaW5kZXgoUHlVbmljb2RlT2JqZWN0ICpzZWxmLCBQeU9iamVjdCAqYXJncykKK3sKKyAgICBQeVVuaWNvZGVPYmplY3QgKnN1YnN0cmluZzsKKyAgICBQeV9zc2l6ZV90IHN0YXJ0OworICAgIFB5X3NzaXplX3QgZW5kOworICAgIFB5X3NzaXplX3QgcmVzdWx0OworCisgICAgaWYgKCFzdHJpbmdsaWJfcGFyc2VfYXJnc19maW5kc191bmljb2RlKCJyaW5kZXgiLCBhcmdzLCAmc3Vic3RyaW5nLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmc3RhcnQsICZlbmQpKQorICAgICAgICByZXR1cm4gTlVMTDsKKworICAgIHJlc3VsdCA9IHN0cmluZ2xpYl9yZmluZF9zbGljZSgKKyAgICAgICAgUHlVbmljb2RlX0FTX1VOSUNPREUoc2VsZiksIFB5VW5pY29kZV9HRVRfU0laRShzZWxmKSwKKyAgICAgICAgUHlVbmljb2RlX0FTX1VOSUNPREUoc3Vic3RyaW5nKSwgUHlVbmljb2RlX0dFVF9TSVpFKHN1YnN0cmluZyksCisgICAgICAgIHN0YXJ0LCBlbmQKKyAgICAgICAgKTsKKworICAgIFB5X0RFQ1JFRihzdWJzdHJpbmcpOworCisgICAgaWYgKHJlc3VsdCA8IDApIHsKKyAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1ZhbHVlRXJyb3IsICJzdWJzdHJpbmcgbm90IGZvdW5kIik7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICByZXR1cm4gUHlJbnRfRnJvbVNzaXplX3QocmVzdWx0KTsKK30KKworUHlEb2NfU1RSVkFSKHJqdXN0X19kb2NfXywKKyAgICAgICAgICAgICAiUy5yanVzdCh3aWR0aFssIGZpbGxjaGFyXSkgLT4gdW5pY29kZVxuXAorXG5cCitSZXR1cm4gUyByaWdodC1qdXN0aWZpZWQgaW4gYSBVbmljb2RlIHN0cmluZyBvZiBsZW5ndGggd2lkdGguIFBhZGRpbmcgaXNcblwKK2RvbmUgdXNpbmcgdGhlIHNwZWNpZmllZCBmaWxsIGNoYXJhY3RlciAoZGVmYXVsdCBpcyBhIHNwYWNlKS4iKTsKKworc3RhdGljIFB5T2JqZWN0ICoKK3VuaWNvZGVfcmp1c3QoUHlVbmljb2RlT2JqZWN0ICpzZWxmLCBQeU9iamVjdCAqYXJncykKK3sKKyAgICBQeV9zc2l6ZV90IHdpZHRoOworICAgIFB5X1VOSUNPREUgZmlsbGNoYXIgPSAnICc7CisKKyAgICBpZiAoIVB5QXJnX1BhcnNlVHVwbGUoYXJncywgIm58TyY6cmp1c3QiLCAmd2lkdGgsIGNvbnZlcnRfdWMsICZmaWxsY2hhcikpCisgICAgICAgIHJldHVybiBOVUxMOworCisgICAgaWYgKHNlbGYtPmxlbmd0aCA+PSB3aWR0aCAmJiBQeVVuaWNvZGVfQ2hlY2tFeGFjdChzZWxmKSkgeworICAgICAgICBQeV9JTkNSRUYoc2VsZik7CisgICAgICAgIHJldHVybiAoUHlPYmplY3QqKSBzZWxmOworICAgIH0KKworICAgIHJldHVybiAoUHlPYmplY3QqKSBwYWQoc2VsZiwgd2lkdGggLSBzZWxmLT5sZW5ndGgsIDAsIGZpbGxjaGFyKTsKK30KKworc3RhdGljIFB5T2JqZWN0KgordW5pY29kZV9zbGljZShQeVVuaWNvZGVPYmplY3QgKnNlbGYsIFB5X3NzaXplX3Qgc3RhcnQsIFB5X3NzaXplX3QgZW5kKQoreworICAgIC8qIHN0YW5kYXJkIGNsYW1waW5nICovCisgICAgaWYgKHN0YXJ0IDwgMCkKKyAgICAgICAgc3RhcnQgPSAwOworICAgIGlmIChlbmQgPCAwKQorICAgICAgICBlbmQgPSAwOworICAgIGlmIChlbmQgPiBzZWxmLT5sZW5ndGgpCisgICAgICAgIGVuZCA9IHNlbGYtPmxlbmd0aDsKKyAgICBpZiAoc3RhcnQgPT0gMCAmJiBlbmQgPT0gc2VsZi0+bGVuZ3RoICYmIFB5VW5pY29kZV9DaGVja0V4YWN0KHNlbGYpKSB7CisgICAgICAgIC8qIGZ1bGwgc2xpY2UsIHJldHVybiBvcmlnaW5hbCBzdHJpbmcgKi8KKyAgICAgICAgUHlfSU5DUkVGKHNlbGYpOworICAgICAgICByZXR1cm4gKFB5T2JqZWN0Kikgc2VsZjsKKyAgICB9CisgICAgaWYgKHN0YXJ0ID4gZW5kKQorICAgICAgICBzdGFydCA9IGVuZDsKKyAgICAvKiBjb3B5IHNsaWNlICovCisgICAgcmV0dXJuIChQeU9iamVjdCopIFB5VW5pY29kZV9Gcm9tVW5pY29kZShzZWxmLT5zdHIgKyBzdGFydCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGVuZCAtIHN0YXJ0KTsKK30KKworUHlPYmplY3QgKlB5VW5pY29kZV9TcGxpdChQeU9iamVjdCAqcywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgUHlPYmplY3QgKnNlcCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgUHlfc3NpemVfdCBtYXhzcGxpdCkKK3sKKyAgICBQeU9iamVjdCAqcmVzdWx0OworCisgICAgcyA9IFB5VW5pY29kZV9Gcm9tT2JqZWN0KHMpOworICAgIGlmIChzID09IE5VTEwpCisgICAgICAgIHJldHVybiBOVUxMOworICAgIGlmIChzZXAgIT0gTlVMTCkgeworICAgICAgICBzZXAgPSBQeVVuaWNvZGVfRnJvbU9iamVjdChzZXApOworICAgICAgICBpZiAoc2VwID09IE5VTEwpIHsKKyAgICAgICAgICAgIFB5X0RFQ1JFRihzKTsKKyAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgICAgICB9CisgICAgfQorCisgICAgcmVzdWx0ID0gc3BsaXQoKFB5VW5pY29kZU9iamVjdCAqKXMsIChQeVVuaWNvZGVPYmplY3QgKilzZXAsIG1heHNwbGl0KTsKKworICAgIFB5X0RFQ1JFRihzKTsKKyAgICBQeV9YREVDUkVGKHNlcCk7CisgICAgcmV0dXJuIHJlc3VsdDsKK30KKworUHlEb2NfU1RSVkFSKHNwbGl0X19kb2NfXywKKyAgICAgICAgICAgICAiUy5zcGxpdChbc2VwIFssbWF4c3BsaXRdXSkgLT4gbGlzdCBvZiBzdHJpbmdzXG5cCitcblwKK1JldHVybiBhIGxpc3Qgb2YgdGhlIHdvcmRzIGluIFMsIHVzaW5nIHNlcCBhcyB0aGVcblwKK2RlbGltaXRlciBzdHJpbmcuICBJZiBtYXhzcGxpdCBpcyBnaXZlbiwgYXQgbW9zdCBtYXhzcGxpdFxuXAorc3BsaXRzIGFyZSBkb25lLiBJZiBzZXAgaXMgbm90IHNwZWNpZmllZCBvciBpcyBOb25lLCBhbnlcblwKK3doaXRlc3BhY2Ugc3RyaW5nIGlzIGEgc2VwYXJhdG9yIGFuZCBlbXB0eSBzdHJpbmdzIGFyZVxuXAorcmVtb3ZlZCBmcm9tIHRoZSByZXN1bHQuIik7CisKK3N0YXRpYyBQeU9iamVjdCoKK3VuaWNvZGVfc3BsaXQoUHlVbmljb2RlT2JqZWN0ICpzZWxmLCBQeU9iamVjdCAqYXJncykKK3sKKyAgICBQeU9iamVjdCAqc3Vic3RyaW5nID0gUHlfTm9uZTsKKyAgICBQeV9zc2l6ZV90IG1heGNvdW50ID0gLTE7CisKKyAgICBpZiAoIVB5QXJnX1BhcnNlVHVwbGUoYXJncywgInxPbjpzcGxpdCIsICZzdWJzdHJpbmcsICZtYXhjb3VudCkpCisgICAgICAgIHJldHVybiBOVUxMOworCisgICAgaWYgKHN1YnN0cmluZyA9PSBQeV9Ob25lKQorICAgICAgICByZXR1cm4gc3BsaXQoc2VsZiwgTlVMTCwgbWF4Y291bnQpOworICAgIGVsc2UgaWYgKFB5VW5pY29kZV9DaGVjayhzdWJzdHJpbmcpKQorICAgICAgICByZXR1cm4gc3BsaXQoc2VsZiwgKFB5VW5pY29kZU9iamVjdCAqKXN1YnN0cmluZywgbWF4Y291bnQpOworICAgIGVsc2UKKyAgICAgICAgcmV0dXJuIFB5VW5pY29kZV9TcGxpdCgoUHlPYmplY3QgKilzZWxmLCBzdWJzdHJpbmcsIG1heGNvdW50KTsKK30KKworUHlPYmplY3QgKgorUHlVbmljb2RlX1BhcnRpdGlvbihQeU9iamVjdCAqc3RyX2luLCBQeU9iamVjdCAqc2VwX2luKQoreworICAgIFB5T2JqZWN0KiBzdHJfb2JqOworICAgIFB5T2JqZWN0KiBzZXBfb2JqOworICAgIFB5T2JqZWN0KiBvdXQ7CisKKyAgICBzdHJfb2JqID0gUHlVbmljb2RlX0Zyb21PYmplY3Qoc3RyX2luKTsKKyAgICBpZiAoIXN0cl9vYmopCisgICAgICAgIHJldHVybiBOVUxMOworICAgIHNlcF9vYmogPSBQeVVuaWNvZGVfRnJvbU9iamVjdChzZXBfaW4pOworICAgIGlmICghc2VwX29iaikgeworICAgICAgICBQeV9ERUNSRUYoc3RyX29iaik7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKworICAgIG91dCA9IHN0cmluZ2xpYl9wYXJ0aXRpb24oCisgICAgICAgIHN0cl9vYmosIFB5VW5pY29kZV9BU19VTklDT0RFKHN0cl9vYmopLCBQeVVuaWNvZGVfR0VUX1NJWkUoc3RyX29iaiksCisgICAgICAgIHNlcF9vYmosIFB5VW5pY29kZV9BU19VTklDT0RFKHNlcF9vYmopLCBQeVVuaWNvZGVfR0VUX1NJWkUoc2VwX29iaikKKyAgICAgICAgKTsKKworICAgIFB5X0RFQ1JFRihzZXBfb2JqKTsKKyAgICBQeV9ERUNSRUYoc3RyX29iaik7CisKKyAgICByZXR1cm4gb3V0OworfQorCisKK1B5T2JqZWN0ICoKK1B5VW5pY29kZV9SUGFydGl0aW9uKFB5T2JqZWN0ICpzdHJfaW4sIFB5T2JqZWN0ICpzZXBfaW4pCit7CisgICAgUHlPYmplY3QqIHN0cl9vYmo7CisgICAgUHlPYmplY3QqIHNlcF9vYmo7CisgICAgUHlPYmplY3QqIG91dDsKKworICAgIHN0cl9vYmogPSBQeVVuaWNvZGVfRnJvbU9iamVjdChzdHJfaW4pOworICAgIGlmICghc3RyX29iaikKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgc2VwX29iaiA9IFB5VW5pY29kZV9Gcm9tT2JqZWN0KHNlcF9pbik7CisgICAgaWYgKCFzZXBfb2JqKSB7CisgICAgICAgIFB5X0RFQ1JFRihzdHJfb2JqKTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorCisgICAgb3V0ID0gc3RyaW5nbGliX3JwYXJ0aXRpb24oCisgICAgICAgIHN0cl9vYmosIFB5VW5pY29kZV9BU19VTklDT0RFKHN0cl9vYmopLCBQeVVuaWNvZGVfR0VUX1NJWkUoc3RyX29iaiksCisgICAgICAgIHNlcF9vYmosIFB5VW5pY29kZV9BU19VTklDT0RFKHNlcF9vYmopLCBQeVVuaWNvZGVfR0VUX1NJWkUoc2VwX29iaikKKyAgICAgICAgKTsKKworICAgIFB5X0RFQ1JFRihzZXBfb2JqKTsKKyAgICBQeV9ERUNSRUYoc3RyX29iaik7CisKKyAgICByZXR1cm4gb3V0OworfQorCitQeURvY19TVFJWQVIocGFydGl0aW9uX19kb2NfXywKKyAgICAgICAgICAgICAiUy5wYXJ0aXRpb24oc2VwKSAtPiAoaGVhZCwgc2VwLCB0YWlsKVxuXAorXG5cCitTZWFyY2ggZm9yIHRoZSBzZXBhcmF0b3Igc2VwIGluIFMsIGFuZCByZXR1cm4gdGhlIHBhcnQgYmVmb3JlIGl0LFxuXAordGhlIHNlcGFyYXRvciBpdHNlbGYsIGFuZCB0aGUgcGFydCBhZnRlciBpdC4gIElmIHRoZSBzZXBhcmF0b3IgaXMgbm90XG5cCitmb3VuZCwgcmV0dXJuIFMgYW5kIHR3byBlbXB0eSBzdHJpbmdzLiIpOworCitzdGF0aWMgUHlPYmplY3QqCit1bmljb2RlX3BhcnRpdGlvbihQeVVuaWNvZGVPYmplY3QgKnNlbGYsIFB5T2JqZWN0ICpzZXBhcmF0b3IpCit7CisgICAgcmV0dXJuIFB5VW5pY29kZV9QYXJ0aXRpb24oKFB5T2JqZWN0ICopc2VsZiwgc2VwYXJhdG9yKTsKK30KKworUHlEb2NfU1RSVkFSKHJwYXJ0aXRpb25fX2RvY19fLAorICAgICAgICAgICAgICJTLnJwYXJ0aXRpb24oc2VwKSAtPiAoaGVhZCwgc2VwLCB0YWlsKVxuXAorXG5cCitTZWFyY2ggZm9yIHRoZSBzZXBhcmF0b3Igc2VwIGluIFMsIHN0YXJ0aW5nIGF0IHRoZSBlbmQgb2YgUywgYW5kIHJldHVyblxuXAordGhlIHBhcnQgYmVmb3JlIGl0LCB0aGUgc2VwYXJhdG9yIGl0c2VsZiwgYW5kIHRoZSBwYXJ0IGFmdGVyIGl0LiAgSWYgdGhlXG5cCitzZXBhcmF0b3IgaXMgbm90IGZvdW5kLCByZXR1cm4gdHdvIGVtcHR5IHN0cmluZ3MgYW5kIFMuIik7CisKK3N0YXRpYyBQeU9iamVjdCoKK3VuaWNvZGVfcnBhcnRpdGlvbihQeVVuaWNvZGVPYmplY3QgKnNlbGYsIFB5T2JqZWN0ICpzZXBhcmF0b3IpCit7CisgICAgcmV0dXJuIFB5VW5pY29kZV9SUGFydGl0aW9uKChQeU9iamVjdCAqKXNlbGYsIHNlcGFyYXRvcik7Cit9CisKK1B5T2JqZWN0ICpQeVVuaWNvZGVfUlNwbGl0KFB5T2JqZWN0ICpzLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgUHlPYmplY3QgKnNlcCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIFB5X3NzaXplX3QgbWF4c3BsaXQpCit7CisgICAgUHlPYmplY3QgKnJlc3VsdDsKKworICAgIHMgPSBQeVVuaWNvZGVfRnJvbU9iamVjdChzKTsKKyAgICBpZiAocyA9PSBOVUxMKQorICAgICAgICByZXR1cm4gTlVMTDsKKyAgICBpZiAoc2VwICE9IE5VTEwpIHsKKyAgICAgICAgc2VwID0gUHlVbmljb2RlX0Zyb21PYmplY3Qoc2VwKTsKKyAgICAgICAgaWYgKHNlcCA9PSBOVUxMKSB7CisgICAgICAgICAgICBQeV9ERUNSRUYocyk7CisgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgfQorICAgIH0KKworICAgIHJlc3VsdCA9IHJzcGxpdCgoUHlVbmljb2RlT2JqZWN0ICopcywgKFB5VW5pY29kZU9iamVjdCAqKXNlcCwgbWF4c3BsaXQpOworCisgICAgUHlfREVDUkVGKHMpOworICAgIFB5X1hERUNSRUYoc2VwKTsKKyAgICByZXR1cm4gcmVzdWx0OworfQorCitQeURvY19TVFJWQVIocnNwbGl0X19kb2NfXywKKyAgICAgICAgICAgICAiUy5yc3BsaXQoW3NlcCBbLG1heHNwbGl0XV0pIC0+IGxpc3Qgb2Ygc3RyaW5nc1xuXAorXG5cCitSZXR1cm4gYSBsaXN0IG9mIHRoZSB3b3JkcyBpbiBTLCB1c2luZyBzZXAgYXMgdGhlXG5cCitkZWxpbWl0ZXIgc3RyaW5nLCBzdGFydGluZyBhdCB0aGUgZW5kIG9mIHRoZSBzdHJpbmcgYW5kXG5cCit3b3JraW5nIHRvIHRoZSBmcm9udC4gIElmIG1heHNwbGl0IGlzIGdpdmVuLCBhdCBtb3N0IG1heHNwbGl0XG5cCitzcGxpdHMgYXJlIGRvbmUuIElmIHNlcCBpcyBub3Qgc3BlY2lmaWVkLCBhbnkgd2hpdGVzcGFjZSBzdHJpbmdcblwKK2lzIGEgc2VwYXJhdG9yLiIpOworCitzdGF0aWMgUHlPYmplY3QqCit1bmljb2RlX3JzcGxpdChQeVVuaWNvZGVPYmplY3QgKnNlbGYsIFB5T2JqZWN0ICphcmdzKQoreworICAgIFB5T2JqZWN0ICpzdWJzdHJpbmcgPSBQeV9Ob25lOworICAgIFB5X3NzaXplX3QgbWF4Y291bnQgPSAtMTsKKworICAgIGlmICghUHlBcmdfUGFyc2VUdXBsZShhcmdzLCAifE9uOnJzcGxpdCIsICZzdWJzdHJpbmcsICZtYXhjb3VudCkpCisgICAgICAgIHJldHVybiBOVUxMOworCisgICAgaWYgKHN1YnN0cmluZyA9PSBQeV9Ob25lKQorICAgICAgICByZXR1cm4gcnNwbGl0KHNlbGYsIE5VTEwsIG1heGNvdW50KTsKKyAgICBlbHNlIGlmIChQeVVuaWNvZGVfQ2hlY2soc3Vic3RyaW5nKSkKKyAgICAgICAgcmV0dXJuIHJzcGxpdChzZWxmLCAoUHlVbmljb2RlT2JqZWN0ICopc3Vic3RyaW5nLCBtYXhjb3VudCk7CisgICAgZWxzZQorICAgICAgICByZXR1cm4gUHlVbmljb2RlX1JTcGxpdCgoUHlPYmplY3QgKilzZWxmLCBzdWJzdHJpbmcsIG1heGNvdW50KTsKK30KKworUHlEb2NfU1RSVkFSKHNwbGl0bGluZXNfX2RvY19fLAorICAgICAgICAgICAgICJTLnNwbGl0bGluZXMoa2VlcGVuZHM9RmFsc2UpIC0+IGxpc3Qgb2Ygc3RyaW5nc1xuXAorXG5cCitSZXR1cm4gYSBsaXN0IG9mIHRoZSBsaW5lcyBpbiBTLCBicmVha2luZyBhdCBsaW5lIGJvdW5kYXJpZXMuXG5cCitMaW5lIGJyZWFrcyBhcmUgbm90IGluY2x1ZGVkIGluIHRoZSByZXN1bHRpbmcgbGlzdCB1bmxlc3Mga2VlcGVuZHNcblwKK2lzIGdpdmVuIGFuZCB0cnVlLiIpOworCitzdGF0aWMgUHlPYmplY3QqCit1bmljb2RlX3NwbGl0bGluZXMoUHlVbmljb2RlT2JqZWN0ICpzZWxmLCBQeU9iamVjdCAqYXJncykKK3sKKyAgICBpbnQga2VlcGVuZHMgPSAwOworCisgICAgaWYgKCFQeUFyZ19QYXJzZVR1cGxlKGFyZ3MsICJ8aTpzcGxpdGxpbmVzIiwgJmtlZXBlbmRzKSkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisKKyAgICByZXR1cm4gUHlVbmljb2RlX1NwbGl0bGluZXMoKFB5T2JqZWN0ICopc2VsZiwga2VlcGVuZHMpOworfQorCitzdGF0aWMKK1B5T2JqZWN0ICp1bmljb2RlX3N0cihQeVVuaWNvZGVPYmplY3QgKnNlbGYpCit7CisgICAgcmV0dXJuIFB5VW5pY29kZV9Bc0VuY29kZWRTdHJpbmcoKFB5T2JqZWN0ICopc2VsZiwgTlVMTCwgTlVMTCk7Cit9CisKK1B5RG9jX1NUUlZBUihzd2FwY2FzZV9fZG9jX18sCisgICAgICAgICAgICAgIlMuc3dhcGNhc2UoKSAtPiB1bmljb2RlXG5cCitcblwKK1JldHVybiBhIGNvcHkgb2YgUyB3aXRoIHVwcGVyY2FzZSBjaGFyYWN0ZXJzIGNvbnZlcnRlZCB0byBsb3dlcmNhc2VcblwKK2FuZCB2aWNlIHZlcnNhLiIpOworCitzdGF0aWMgUHlPYmplY3QqCit1bmljb2RlX3N3YXBjYXNlKFB5VW5pY29kZU9iamVjdCAqc2VsZikKK3sKKyAgICByZXR1cm4gZml4dXAoc2VsZiwgZml4c3dhcGNhc2UpOworfQorCitQeURvY19TVFJWQVIodHJhbnNsYXRlX19kb2NfXywKKyAgICAgICAgICAgICAiUy50cmFuc2xhdGUodGFibGUpIC0+IHVuaWNvZGVcblwKK1xuXAorUmV0dXJuIGEgY29weSBvZiB0aGUgc3RyaW5nIFMsIHdoZXJlIGFsbCBjaGFyYWN0ZXJzIGhhdmUgYmVlbiBtYXBwZWRcblwKK3Rocm91Z2ggdGhlIGdpdmVuIHRyYW5zbGF0aW9uIHRhYmxlLCB3aGljaCBtdXN0IGJlIGEgbWFwcGluZyBvZlxuXAorVW5pY29kZSBvcmRpbmFscyB0byBVbmljb2RlIG9yZGluYWxzLCBVbmljb2RlIHN0cmluZ3Mgb3IgTm9uZS5cblwKK1VubWFwcGVkIGNoYXJhY3RlcnMgYXJlIGxlZnQgdW50b3VjaGVkLiBDaGFyYWN0ZXJzIG1hcHBlZCB0byBOb25lXG5cCithcmUgZGVsZXRlZC4iKTsKKworc3RhdGljIFB5T2JqZWN0KgordW5pY29kZV90cmFuc2xhdGUoUHlVbmljb2RlT2JqZWN0ICpzZWxmLCBQeU9iamVjdCAqdGFibGUpCit7CisgICAgcmV0dXJuIFB5VW5pY29kZV9UcmFuc2xhdGVDaGFybWFwKHNlbGYtPnN0ciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi0+bGVuZ3RoLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0YWJsZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImlnbm9yZSIpOworfQorCitQeURvY19TVFJWQVIodXBwZXJfX2RvY19fLAorICAgICAgICAgICAgICJTLnVwcGVyKCkgLT4gdW5pY29kZVxuXAorXG5cCitSZXR1cm4gYSBjb3B5IG9mIFMgY29udmVydGVkIHRvIHVwcGVyY2FzZS4iKTsKKworc3RhdGljIFB5T2JqZWN0KgordW5pY29kZV91cHBlcihQeVVuaWNvZGVPYmplY3QgKnNlbGYpCit7CisgICAgcmV0dXJuIGZpeHVwKHNlbGYsIGZpeHVwcGVyKTsKK30KKworUHlEb2NfU1RSVkFSKHpmaWxsX19kb2NfXywKKyAgICAgICAgICAgICAiUy56ZmlsbCh3aWR0aCkgLT4gdW5pY29kZVxuXAorXG5cCitQYWQgYSBudW1lcmljIHN0cmluZyBTIHdpdGggemVyb3Mgb24gdGhlIGxlZnQsIHRvIGZpbGwgYSBmaWVsZFxuXAorb2YgdGhlIHNwZWNpZmllZCB3aWR0aC4gVGhlIHN0cmluZyBTIGlzIG5ldmVyIHRydW5jYXRlZC4iKTsKKworc3RhdGljIFB5T2JqZWN0ICoKK3VuaWNvZGVfemZpbGwoUHlVbmljb2RlT2JqZWN0ICpzZWxmLCBQeU9iamVjdCAqYXJncykKK3sKKyAgICBQeV9zc2l6ZV90IGZpbGw7CisgICAgUHlVbmljb2RlT2JqZWN0ICp1OworCisgICAgUHlfc3NpemVfdCB3aWR0aDsKKyAgICBpZiAoIVB5QXJnX1BhcnNlVHVwbGUoYXJncywgIm46emZpbGwiLCAmd2lkdGgpKQorICAgICAgICByZXR1cm4gTlVMTDsKKworICAgIGlmIChzZWxmLT5sZW5ndGggPj0gd2lkdGgpIHsKKyAgICAgICAgaWYgKFB5VW5pY29kZV9DaGVja0V4YWN0KHNlbGYpKSB7CisgICAgICAgICAgICBQeV9JTkNSRUYoc2VsZik7CisgICAgICAgICAgICByZXR1cm4gKFB5T2JqZWN0Kikgc2VsZjsKKyAgICAgICAgfQorICAgICAgICBlbHNlCisgICAgICAgICAgICByZXR1cm4gUHlVbmljb2RlX0Zyb21Vbmljb2RlKAorICAgICAgICAgICAgICAgIFB5VW5pY29kZV9BU19VTklDT0RFKHNlbGYpLAorICAgICAgICAgICAgICAgIFB5VW5pY29kZV9HRVRfU0laRShzZWxmKQorICAgICAgICAgICAgICAgICk7CisgICAgfQorCisgICAgZmlsbCA9IHdpZHRoIC0gc2VsZi0+bGVuZ3RoOworCisgICAgdSA9IHBhZChzZWxmLCBmaWxsLCAwLCAnMCcpOworCisgICAgaWYgKHUgPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisKKyAgICBpZiAodS0+c3RyW2ZpbGxdID09ICcrJyB8fCB1LT5zdHJbZmlsbF0gPT0gJy0nKSB7CisgICAgICAgIC8qIG1vdmUgc2lnbiB0byBiZWdpbm5pbmcgb2Ygc3RyaW5nICovCisgICAgICAgIHUtPnN0clswXSA9IHUtPnN0cltmaWxsXTsKKyAgICAgICAgdS0+c3RyW2ZpbGxdID0gJzAnOworICAgIH0KKworICAgIHJldHVybiAoUHlPYmplY3QqKSB1OworfQorCisjaWYgMAorc3RhdGljIFB5T2JqZWN0KgorZnJlZV9saXN0c2l6ZShQeVVuaWNvZGVPYmplY3QgKnNlbGYpCit7CisgICAgcmV0dXJuIFB5SW50X0Zyb21Mb25nKG51bWZyZWUpOworfQorI2VuZGlmCisKK1B5RG9jX1NUUlZBUihzdGFydHN3aXRoX19kb2NfXywKKyAgICAgICAgICAgICAiUy5zdGFydHN3aXRoKHByZWZpeFssIHN0YXJ0WywgZW5kXV0pIC0+IGJvb2xcblwKK1xuXAorUmV0dXJuIFRydWUgaWYgUyBzdGFydHMgd2l0aCB0aGUgc3BlY2lmaWVkIHByZWZpeCwgRmFsc2Ugb3RoZXJ3aXNlLlxuXAorV2l0aCBvcHRpb25hbCBzdGFydCwgdGVzdCBTIGJlZ2lubmluZyBhdCB0aGF0IHBvc2l0aW9uLlxuXAorV2l0aCBvcHRpb25hbCBlbmQsIHN0b3AgY29tcGFyaW5nIFMgYXQgdGhhdCBwb3NpdGlvbi5cblwKK3ByZWZpeCBjYW4gYWxzbyBiZSBhIHR1cGxlIG9mIHN0cmluZ3MgdG8gdHJ5LiIpOworCitzdGF0aWMgUHlPYmplY3QgKgordW5pY29kZV9zdGFydHN3aXRoKFB5VW5pY29kZU9iamVjdCAqc2VsZiwKKyAgICAgICAgICAgICAgICAgICBQeU9iamVjdCAqYXJncykKK3sKKyAgICBQeU9iamVjdCAqc3Vib2JqOworICAgIFB5VW5pY29kZU9iamVjdCAqc3Vic3RyaW5nOworICAgIFB5X3NzaXplX3Qgc3RhcnQgPSAwOworICAgIFB5X3NzaXplX3QgZW5kID0gUFlfU1NJWkVfVF9NQVg7CisgICAgaW50IHJlc3VsdDsKKworICAgIGlmICghc3RyaW5nbGliX3BhcnNlX2FyZ3NfZmluZHMoInN0YXJ0c3dpdGgiLCBhcmdzLCAmc3Vib2JqLCAmc3RhcnQsICZlbmQpKQorICAgICAgICByZXR1cm4gTlVMTDsKKyAgICBpZiAoUHlUdXBsZV9DaGVjayhzdWJvYmopKSB7CisgICAgICAgIFB5X3NzaXplX3QgaTsKKyAgICAgICAgZm9yIChpID0gMDsgaSA8IFB5VHVwbGVfR0VUX1NJWkUoc3Vib2JqKTsgaSsrKSB7CisgICAgICAgICAgICBzdWJzdHJpbmcgPSAoUHlVbmljb2RlT2JqZWN0ICopUHlVbmljb2RlX0Zyb21PYmplY3QoCisgICAgICAgICAgICAgICAgUHlUdXBsZV9HRVRfSVRFTShzdWJvYmosIGkpKTsKKyAgICAgICAgICAgIGlmIChzdWJzdHJpbmcgPT0gTlVMTCkKKyAgICAgICAgICAgICAgICByZXR1cm4gTlVMTDsKKyAgICAgICAgICAgIHJlc3VsdCA9IHRhaWxtYXRjaChzZWxmLCBzdWJzdHJpbmcsIHN0YXJ0LCBlbmQsIC0xKTsKKyAgICAgICAgICAgIFB5X0RFQ1JFRihzdWJzdHJpbmcpOworICAgICAgICAgICAgaWYgKHJlc3VsdCkgeworICAgICAgICAgICAgICAgIFB5X1JFVFVSTl9UUlVFOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIC8qIG5vdGhpbmcgbWF0Y2hlZCAqLworICAgICAgICBQeV9SRVRVUk5fRkFMU0U7CisgICAgfQorICAgIHN1YnN0cmluZyA9IChQeVVuaWNvZGVPYmplY3QgKilQeVVuaWNvZGVfRnJvbU9iamVjdChzdWJvYmopOworICAgIGlmIChzdWJzdHJpbmcgPT0gTlVMTCkgeworICAgICAgICBpZiAoUHlFcnJfRXhjZXB0aW9uTWF0Y2hlcyhQeUV4Y19UeXBlRXJyb3IpKQorICAgICAgICAgICAgUHlFcnJfRm9ybWF0KFB5RXhjX1R5cGVFcnJvciwgInN0YXJ0c3dpdGggZmlyc3QgYXJnIG11c3QgYmUgc3RyLCAiCisgICAgICAgICAgICAgICAgICAgICAgICAgInVuaWNvZGUsIG9yIHR1cGxlLCBub3QgJXMiLCBQeV9UWVBFKHN1Ym9iaiktPnRwX25hbWUpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgcmVzdWx0ID0gdGFpbG1hdGNoKHNlbGYsIHN1YnN0cmluZywgc3RhcnQsIGVuZCwgLTEpOworICAgIFB5X0RFQ1JFRihzdWJzdHJpbmcpOworICAgIHJldHVybiBQeUJvb2xfRnJvbUxvbmcocmVzdWx0KTsKK30KKworCitQeURvY19TVFJWQVIoZW5kc3dpdGhfX2RvY19fLAorICAgICAgICAgICAgICJTLmVuZHN3aXRoKHN1ZmZpeFssIHN0YXJ0WywgZW5kXV0pIC0+IGJvb2xcblwKK1xuXAorUmV0dXJuIFRydWUgaWYgUyBlbmRzIHdpdGggdGhlIHNwZWNpZmllZCBzdWZmaXgsIEZhbHNlIG90aGVyd2lzZS5cblwKK1dpdGggb3B0aW9uYWwgc3RhcnQsIHRlc3QgUyBiZWdpbm5pbmcgYXQgdGhhdCBwb3NpdGlvbi5cblwKK1dpdGggb3B0aW9uYWwgZW5kLCBzdG9wIGNvbXBhcmluZyBTIGF0IHRoYXQgcG9zaXRpb24uXG5cCitzdWZmaXggY2FuIGFsc28gYmUgYSB0dXBsZSBvZiBzdHJpbmdzIHRvIHRyeS4iKTsKKworc3RhdGljIFB5T2JqZWN0ICoKK3VuaWNvZGVfZW5kc3dpdGgoUHlVbmljb2RlT2JqZWN0ICpzZWxmLAorICAgICAgICAgICAgICAgICBQeU9iamVjdCAqYXJncykKK3sKKyAgICBQeU9iamVjdCAqc3Vib2JqOworICAgIFB5VW5pY29kZU9iamVjdCAqc3Vic3RyaW5nOworICAgIFB5X3NzaXplX3Qgc3RhcnQgPSAwOworICAgIFB5X3NzaXplX3QgZW5kID0gUFlfU1NJWkVfVF9NQVg7CisgICAgaW50IHJlc3VsdDsKKworICAgIGlmICghc3RyaW5nbGliX3BhcnNlX2FyZ3NfZmluZHMoImVuZHN3aXRoIiwgYXJncywgJnN1Ym9iaiwgJnN0YXJ0LCAmZW5kKSkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgaWYgKFB5VHVwbGVfQ2hlY2soc3Vib2JqKSkgeworICAgICAgICBQeV9zc2l6ZV90IGk7CisgICAgICAgIGZvciAoaSA9IDA7IGkgPCBQeVR1cGxlX0dFVF9TSVpFKHN1Ym9iaik7IGkrKykgeworICAgICAgICAgICAgc3Vic3RyaW5nID0gKFB5VW5pY29kZU9iamVjdCAqKVB5VW5pY29kZV9Gcm9tT2JqZWN0KAorICAgICAgICAgICAgICAgIFB5VHVwbGVfR0VUX0lURU0oc3Vib2JqLCBpKSk7CisgICAgICAgICAgICBpZiAoc3Vic3RyaW5nID09IE5VTEwpCisgICAgICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgICAgICAgICByZXN1bHQgPSB0YWlsbWF0Y2goc2VsZiwgc3Vic3RyaW5nLCBzdGFydCwgZW5kLCArMSk7CisgICAgICAgICAgICBQeV9ERUNSRUYoc3Vic3RyaW5nKTsKKyAgICAgICAgICAgIGlmIChyZXN1bHQpIHsKKyAgICAgICAgICAgICAgICBQeV9SRVRVUk5fVFJVRTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgICAgICBQeV9SRVRVUk5fRkFMU0U7CisgICAgfQorICAgIHN1YnN0cmluZyA9IChQeVVuaWNvZGVPYmplY3QgKilQeVVuaWNvZGVfRnJvbU9iamVjdChzdWJvYmopOworICAgIGlmIChzdWJzdHJpbmcgPT0gTlVMTCkgeworICAgICAgICBpZiAoUHlFcnJfRXhjZXB0aW9uTWF0Y2hlcyhQeUV4Y19UeXBlRXJyb3IpKQorICAgICAgICAgICAgUHlFcnJfRm9ybWF0KFB5RXhjX1R5cGVFcnJvciwgImVuZHN3aXRoIGZpcnN0IGFyZyBtdXN0IGJlIHN0ciwgIgorICAgICAgICAgICAgICAgICAgICAgICAgICJ1bmljb2RlLCBvciB0dXBsZSwgbm90ICVzIiwgUHlfVFlQRShzdWJvYmopLT50cF9uYW1lKTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorICAgIHJlc3VsdCA9IHRhaWxtYXRjaChzZWxmLCBzdWJzdHJpbmcsIHN0YXJ0LCBlbmQsICsxKTsKKyAgICBQeV9ERUNSRUYoc3Vic3RyaW5nKTsKKyAgICByZXR1cm4gUHlCb29sX0Zyb21Mb25nKHJlc3VsdCk7Cit9CisKKworLyogSW1wbGVtZW50cyBkb19zdHJpbmdfZm9ybWF0LCB3aGljaCBpcyB1bmljb2RlIGJlY2F1c2Ugb2Ygc3RyaW5nbGliICovCisjaW5jbHVkZSAic3RyaW5nbGliL3N0cmluZ19mb3JtYXQuaCIKKworUHlEb2NfU1RSVkFSKGZvcm1hdF9fZG9jX18sCisgICAgICAgICAgICAgIlMuZm9ybWF0KCphcmdzLCAqKmt3YXJncykgLT4gdW5pY29kZVxuXAorXG5cCitSZXR1cm4gYSBmb3JtYXR0ZWQgdmVyc2lvbiBvZiBTLCB1c2luZyBzdWJzdGl0dXRpb25zIGZyb20gYXJncyBhbmQga3dhcmdzLlxuXAorVGhlIHN1YnN0aXR1dGlvbnMgYXJlIGlkZW50aWZpZWQgYnkgYnJhY2VzICgneycgYW5kICd9JykuIik7CisKK3N0YXRpYyBQeU9iamVjdCAqCit1bmljb2RlX19mb3JtYXRfXyhQeU9iamVjdCAqc2VsZiwgUHlPYmplY3QgKmFyZ3MpCit7CisgICAgUHlPYmplY3QgKmZvcm1hdF9zcGVjOworICAgIFB5T2JqZWN0ICpyZXN1bHQgPSBOVUxMOworICAgIFB5T2JqZWN0ICp0bXAgPSBOVUxMOworCisgICAgLyogSWYgMi54LCBjb252ZXJ0IGZvcm1hdF9zcGVjIHRvIHRoZSBzYW1lIHR5cGUgYXMgdmFsdWUgKi8KKyAgICAvKiBUaGlzIGlzIHRvIGFsbG93IHRoaW5ncyBsaWtlIHUnJy5mb3JtYXQoJycpICovCisgICAgaWYgKCFQeUFyZ19QYXJzZVR1cGxlKGFyZ3MsICJPOl9fZm9ybWF0X18iLCAmZm9ybWF0X3NwZWMpKQorICAgICAgICBnb3RvIGRvbmU7CisgICAgaWYgKCEoUHlCeXRlc19DaGVjayhmb3JtYXRfc3BlYykgfHwgUHlVbmljb2RlX0NoZWNrKGZvcm1hdF9zcGVjKSkpIHsKKyAgICAgICAgUHlFcnJfRm9ybWF0KFB5RXhjX1R5cGVFcnJvciwgIl9fZm9ybWF0X18gYXJnIG11c3QgYmUgc3RyICIKKyAgICAgICAgICAgICAgICAgICAgICJvciB1bmljb2RlLCBub3QgJXMiLCBQeV9UWVBFKGZvcm1hdF9zcGVjKS0+dHBfbmFtZSk7CisgICAgICAgIGdvdG8gZG9uZTsKKyAgICB9CisgICAgdG1wID0gUHlPYmplY3RfVW5pY29kZShmb3JtYXRfc3BlYyk7CisgICAgaWYgKHRtcCA9PSBOVUxMKQorICAgICAgICBnb3RvIGRvbmU7CisgICAgZm9ybWF0X3NwZWMgPSB0bXA7CisKKyAgICByZXN1bHQgPSBfUHlVbmljb2RlX0Zvcm1hdEFkdmFuY2VkKHNlbGYsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQeVVuaWNvZGVfQVNfVU5JQ09ERShmb3JtYXRfc3BlYyksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQeVVuaWNvZGVfR0VUX1NJWkUoZm9ybWF0X3NwZWMpKTsKKyAgZG9uZToKKyAgICBQeV9YREVDUkVGKHRtcCk7CisgICAgcmV0dXJuIHJlc3VsdDsKK30KKworUHlEb2NfU1RSVkFSKHBfZm9ybWF0X19kb2NfXywKKyAgICAgICAgICAgICAiUy5fX2Zvcm1hdF9fKGZvcm1hdF9zcGVjKSAtPiB1bmljb2RlXG5cCitcblwKK1JldHVybiBhIGZvcm1hdHRlZCB2ZXJzaW9uIG9mIFMgYXMgZGVzY3JpYmVkIGJ5IGZvcm1hdF9zcGVjLiIpOworCitzdGF0aWMgUHlPYmplY3QgKgordW5pY29kZV9fc2l6ZW9mX18oUHlVbmljb2RlT2JqZWN0ICp2KQoreworICAgIHJldHVybiBQeUludF9Gcm9tU3NpemVfdChzaXplb2YoUHlVbmljb2RlT2JqZWN0KSArCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZihQeV9VTklDT0RFKSAqICh2LT5sZW5ndGggKyAxKSk7Cit9CisKK1B5RG9jX1NUUlZBUihzaXplb2ZfX2RvY19fLAorICAgICAgICAgICAgICJTLl9fc2l6ZW9mX18oKSAtPiBzaXplIG9mIFMgaW4gbWVtb3J5LCBpbiBieXRlc1xuXAorXG5cCisiKTsKKworc3RhdGljIFB5T2JqZWN0ICoKK3VuaWNvZGVfZ2V0bmV3YXJncyhQeVVuaWNvZGVPYmplY3QgKnYpCit7CisgICAgcmV0dXJuIFB5X0J1aWxkVmFsdWUoIih1IykiLCB2LT5zdHIsIHYtPmxlbmd0aCk7Cit9CisKKworc3RhdGljIFB5TWV0aG9kRGVmIHVuaWNvZGVfbWV0aG9kc1tdID0geworICAgIHsiZW5jb2RlIiwgKFB5Q0Z1bmN0aW9uKSB1bmljb2RlX2VuY29kZSwgTUVUSF9WQVJBUkdTIHwgTUVUSF9LRVlXT1JEUywgZW5jb2RlX19kb2NfX30sCisgICAgeyJyZXBsYWNlIiwgKFB5Q0Z1bmN0aW9uKSB1bmljb2RlX3JlcGxhY2UsIE1FVEhfVkFSQVJHUywgcmVwbGFjZV9fZG9jX199LAorICAgIHsic3BsaXQiLCAoUHlDRnVuY3Rpb24pIHVuaWNvZGVfc3BsaXQsIE1FVEhfVkFSQVJHUywgc3BsaXRfX2RvY19ffSwKKyAgICB7InJzcGxpdCIsIChQeUNGdW5jdGlvbikgdW5pY29kZV9yc3BsaXQsIE1FVEhfVkFSQVJHUywgcnNwbGl0X19kb2NfX30sCisgICAgeyJqb2luIiwgKFB5Q0Z1bmN0aW9uKSB1bmljb2RlX2pvaW4sIE1FVEhfTywgam9pbl9fZG9jX199LAorICAgIHsiY2FwaXRhbGl6ZSIsIChQeUNGdW5jdGlvbikgdW5pY29kZV9jYXBpdGFsaXplLCBNRVRIX05PQVJHUywgY2FwaXRhbGl6ZV9fZG9jX199LAorICAgIHsidGl0bGUiLCAoUHlDRnVuY3Rpb24pIHVuaWNvZGVfdGl0bGUsIE1FVEhfTk9BUkdTLCB0aXRsZV9fZG9jX199LAorICAgIHsiY2VudGVyIiwgKFB5Q0Z1bmN0aW9uKSB1bmljb2RlX2NlbnRlciwgTUVUSF9WQVJBUkdTLCBjZW50ZXJfX2RvY19ffSwKKyAgICB7ImNvdW50IiwgKFB5Q0Z1bmN0aW9uKSB1bmljb2RlX2NvdW50LCBNRVRIX1ZBUkFSR1MsIGNvdW50X19kb2NfX30sCisgICAgeyJleHBhbmR0YWJzIiwgKFB5Q0Z1bmN0aW9uKSB1bmljb2RlX2V4cGFuZHRhYnMsIE1FVEhfVkFSQVJHUywgZXhwYW5kdGFic19fZG9jX199LAorICAgIHsiZmluZCIsIChQeUNGdW5jdGlvbikgdW5pY29kZV9maW5kLCBNRVRIX1ZBUkFSR1MsIGZpbmRfX2RvY19ffSwKKyAgICB7InBhcnRpdGlvbiIsIChQeUNGdW5jdGlvbikgdW5pY29kZV9wYXJ0aXRpb24sIE1FVEhfTywgcGFydGl0aW9uX19kb2NfX30sCisgICAgeyJpbmRleCIsIChQeUNGdW5jdGlvbikgdW5pY29kZV9pbmRleCwgTUVUSF9WQVJBUkdTLCBpbmRleF9fZG9jX199LAorICAgIHsibGp1c3QiLCAoUHlDRnVuY3Rpb24pIHVuaWNvZGVfbGp1c3QsIE1FVEhfVkFSQVJHUywgbGp1c3RfX2RvY19ffSwKKyAgICB7Imxvd2VyIiwgKFB5Q0Z1bmN0aW9uKSB1bmljb2RlX2xvd2VyLCBNRVRIX05PQVJHUywgbG93ZXJfX2RvY19ffSwKKyAgICB7ImxzdHJpcCIsIChQeUNGdW5jdGlvbikgdW5pY29kZV9sc3RyaXAsIE1FVEhfVkFSQVJHUywgbHN0cmlwX19kb2NfX30sCisgICAgeyJkZWNvZGUiLCAoUHlDRnVuY3Rpb24pIHVuaWNvZGVfZGVjb2RlLCBNRVRIX1ZBUkFSR1MgfCBNRVRIX0tFWVdPUkRTLCBkZWNvZGVfX2RvY19ffSwKKy8qICB7Im1ha2V0cmFucyIsIChQeUNGdW5jdGlvbikgdW5pY29kZV9tYWtldHJhbnMsIE1FVEhfVkFSQVJHUywgbWFrZXRyYW5zX19kb2NfX30sICovCisgICAgeyJyZmluZCIsIChQeUNGdW5jdGlvbikgdW5pY29kZV9yZmluZCwgTUVUSF9WQVJBUkdTLCByZmluZF9fZG9jX199LAorICAgIHsicmluZGV4IiwgKFB5Q0Z1bmN0aW9uKSB1bmljb2RlX3JpbmRleCwgTUVUSF9WQVJBUkdTLCByaW5kZXhfX2RvY19ffSwKKyAgICB7InJqdXN0IiwgKFB5Q0Z1bmN0aW9uKSB1bmljb2RlX3JqdXN0LCBNRVRIX1ZBUkFSR1MsIHJqdXN0X19kb2NfX30sCisgICAgeyJyc3RyaXAiLCAoUHlDRnVuY3Rpb24pIHVuaWNvZGVfcnN0cmlwLCBNRVRIX1ZBUkFSR1MsIHJzdHJpcF9fZG9jX199LAorICAgIHsicnBhcnRpdGlvbiIsIChQeUNGdW5jdGlvbikgdW5pY29kZV9ycGFydGl0aW9uLCBNRVRIX08sIHJwYXJ0aXRpb25fX2RvY19ffSwKKyAgICB7InNwbGl0bGluZXMiLCAoUHlDRnVuY3Rpb24pIHVuaWNvZGVfc3BsaXRsaW5lcywgTUVUSF9WQVJBUkdTLCBzcGxpdGxpbmVzX19kb2NfX30sCisgICAgeyJzdHJpcCIsIChQeUNGdW5jdGlvbikgdW5pY29kZV9zdHJpcCwgTUVUSF9WQVJBUkdTLCBzdHJpcF9fZG9jX199LAorICAgIHsic3dhcGNhc2UiLCAoUHlDRnVuY3Rpb24pIHVuaWNvZGVfc3dhcGNhc2UsIE1FVEhfTk9BUkdTLCBzd2FwY2FzZV9fZG9jX199LAorICAgIHsidHJhbnNsYXRlIiwgKFB5Q0Z1bmN0aW9uKSB1bmljb2RlX3RyYW5zbGF0ZSwgTUVUSF9PLCB0cmFuc2xhdGVfX2RvY19ffSwKKyAgICB7InVwcGVyIiwgKFB5Q0Z1bmN0aW9uKSB1bmljb2RlX3VwcGVyLCBNRVRIX05PQVJHUywgdXBwZXJfX2RvY19ffSwKKyAgICB7InN0YXJ0c3dpdGgiLCAoUHlDRnVuY3Rpb24pIHVuaWNvZGVfc3RhcnRzd2l0aCwgTUVUSF9WQVJBUkdTLCBzdGFydHN3aXRoX19kb2NfX30sCisgICAgeyJlbmRzd2l0aCIsIChQeUNGdW5jdGlvbikgdW5pY29kZV9lbmRzd2l0aCwgTUVUSF9WQVJBUkdTLCBlbmRzd2l0aF9fZG9jX199LAorICAgIHsiaXNsb3dlciIsIChQeUNGdW5jdGlvbikgdW5pY29kZV9pc2xvd2VyLCBNRVRIX05PQVJHUywgaXNsb3dlcl9fZG9jX199LAorICAgIHsiaXN1cHBlciIsIChQeUNGdW5jdGlvbikgdW5pY29kZV9pc3VwcGVyLCBNRVRIX05PQVJHUywgaXN1cHBlcl9fZG9jX199LAorICAgIHsiaXN0aXRsZSIsIChQeUNGdW5jdGlvbikgdW5pY29kZV9pc3RpdGxlLCBNRVRIX05PQVJHUywgaXN0aXRsZV9fZG9jX199LAorICAgIHsiaXNzcGFjZSIsIChQeUNGdW5jdGlvbikgdW5pY29kZV9pc3NwYWNlLCBNRVRIX05PQVJHUywgaXNzcGFjZV9fZG9jX199LAorICAgIHsiaXNkZWNpbWFsIiwgKFB5Q0Z1bmN0aW9uKSB1bmljb2RlX2lzZGVjaW1hbCwgTUVUSF9OT0FSR1MsIGlzZGVjaW1hbF9fZG9jX199LAorICAgIHsiaXNkaWdpdCIsIChQeUNGdW5jdGlvbikgdW5pY29kZV9pc2RpZ2l0LCBNRVRIX05PQVJHUywgaXNkaWdpdF9fZG9jX199LAorICAgIHsiaXNudW1lcmljIiwgKFB5Q0Z1bmN0aW9uKSB1bmljb2RlX2lzbnVtZXJpYywgTUVUSF9OT0FSR1MsIGlzbnVtZXJpY19fZG9jX199LAorICAgIHsiaXNhbHBoYSIsIChQeUNGdW5jdGlvbikgdW5pY29kZV9pc2FscGhhLCBNRVRIX05PQVJHUywgaXNhbHBoYV9fZG9jX199LAorICAgIHsiaXNhbG51bSIsIChQeUNGdW5jdGlvbikgdW5pY29kZV9pc2FsbnVtLCBNRVRIX05PQVJHUywgaXNhbG51bV9fZG9jX199LAorICAgIHsiemZpbGwiLCAoUHlDRnVuY3Rpb24pIHVuaWNvZGVfemZpbGwsIE1FVEhfVkFSQVJHUywgemZpbGxfX2RvY19ffSwKKyAgICB7ImZvcm1hdCIsIChQeUNGdW5jdGlvbikgZG9fc3RyaW5nX2Zvcm1hdCwgTUVUSF9WQVJBUkdTIHwgTUVUSF9LRVlXT1JEUywgZm9ybWF0X19kb2NfX30sCisgICAgeyJfX2Zvcm1hdF9fIiwgKFB5Q0Z1bmN0aW9uKSB1bmljb2RlX19mb3JtYXRfXywgTUVUSF9WQVJBUkdTLCBwX2Zvcm1hdF9fZG9jX199LAorICAgIHsiX2Zvcm1hdHRlcl9maWVsZF9uYW1lX3NwbGl0IiwgKFB5Q0Z1bmN0aW9uKSBmb3JtYXR0ZXJfZmllbGRfbmFtZV9zcGxpdCwgTUVUSF9OT0FSR1N9LAorICAgIHsiX2Zvcm1hdHRlcl9wYXJzZXIiLCAoUHlDRnVuY3Rpb24pIGZvcm1hdHRlcl9wYXJzZXIsIE1FVEhfTk9BUkdTfSwKKyAgICB7Il9fc2l6ZW9mX18iLCAoUHlDRnVuY3Rpb24pIHVuaWNvZGVfX3NpemVvZl9fLCBNRVRIX05PQVJHUywgc2l6ZW9mX19kb2NfX30sCisjaWYgMAorICAgIHsiY2Fwd29yZHMiLCAoUHlDRnVuY3Rpb24pIHVuaWNvZGVfY2Fwd29yZHMsIE1FVEhfTk9BUkdTLCBjYXB3b3Jkc19fZG9jX199LAorI2VuZGlmCisKKyNpZiAwCisgICAgLyogVGhpcyBvbmUgaXMganVzdCB1c2VkIGZvciBkZWJ1Z2dpbmcgdGhlIGltcGxlbWVudGF0aW9uLiAqLworICAgIHsiZnJlZWxpc3RzaXplIiwgKFB5Q0Z1bmN0aW9uKSBmcmVlX2xpc3RzaXplLCBNRVRIX05PQVJHU30sCisjZW5kaWYKKworICAgIHsiX19nZXRuZXdhcmdzX18iLCAgKFB5Q0Z1bmN0aW9uKXVuaWNvZGVfZ2V0bmV3YXJncywgTUVUSF9OT0FSR1N9LAorICAgIHtOVUxMLCBOVUxMfQorfTsKKworc3RhdGljIFB5T2JqZWN0ICoKK3VuaWNvZGVfbW9kKFB5T2JqZWN0ICp2LCBQeU9iamVjdCAqdykKK3sKKyAgICBpZiAoIVB5VW5pY29kZV9DaGVjayh2KSkgeworICAgICAgICBQeV9JTkNSRUYoUHlfTm90SW1wbGVtZW50ZWQpOworICAgICAgICByZXR1cm4gUHlfTm90SW1wbGVtZW50ZWQ7CisgICAgfQorICAgIHJldHVybiBQeVVuaWNvZGVfRm9ybWF0KHYsIHcpOworfQorCitzdGF0aWMgUHlOdW1iZXJNZXRob2RzIHVuaWNvZGVfYXNfbnVtYmVyID0geworICAgIDAsICAgICAgICAgICAgICAvKm5iX2FkZCovCisgICAgMCwgICAgICAgICAgICAgIC8qbmJfc3VidHJhY3QqLworICAgIDAsICAgICAgICAgICAgICAvKm5iX211bHRpcGx5Ki8KKyAgICAwLCAgICAgICAgICAgICAgLypuYl9kaXZpZGUqLworICAgIHVuaWNvZGVfbW9kLCAgICAgICAgICAgIC8qbmJfcmVtYWluZGVyKi8KK307CisKK3N0YXRpYyBQeVNlcXVlbmNlTWV0aG9kcyB1bmljb2RlX2FzX3NlcXVlbmNlID0geworICAgIChsZW5mdW5jKSB1bmljb2RlX2xlbmd0aCwgICAgICAgLyogc3FfbGVuZ3RoICovCisgICAgUHlVbmljb2RlX0NvbmNhdCwgICAgICAgICAgIC8qIHNxX2NvbmNhdCAqLworICAgIChzc2l6ZWFyZ2Z1bmMpIHVuaWNvZGVfcmVwZWF0LCAgLyogc3FfcmVwZWF0ICovCisgICAgKHNzaXplYXJnZnVuYykgdW5pY29kZV9nZXRpdGVtLCAgICAgLyogc3FfaXRlbSAqLworICAgIChzc2l6ZXNzaXplYXJnZnVuYykgdW5pY29kZV9zbGljZSwgIC8qIHNxX3NsaWNlICovCisgICAgMCwgICAgICAgICAgICAgICAgICAvKiBzcV9hc3NfaXRlbSAqLworICAgIDAsICAgICAgICAgICAgICAgICAgLyogc3FfYXNzX3NsaWNlICovCisgICAgUHlVbmljb2RlX0NvbnRhaW5zLCAgICAgICAgIC8qIHNxX2NvbnRhaW5zICovCit9OworCitzdGF0aWMgUHlPYmplY3QqCit1bmljb2RlX3N1YnNjcmlwdChQeVVuaWNvZGVPYmplY3QqIHNlbGYsIFB5T2JqZWN0KiBpdGVtKQoreworICAgIGlmIChQeUluZGV4X0NoZWNrKGl0ZW0pKSB7CisgICAgICAgIFB5X3NzaXplX3QgaSA9IFB5TnVtYmVyX0FzU3NpemVfdChpdGVtLCBQeUV4Y19JbmRleEVycm9yKTsKKyAgICAgICAgaWYgKGkgPT0gLTEgJiYgUHlFcnJfT2NjdXJyZWQoKSkKKyAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgICAgICBpZiAoaSA8IDApCisgICAgICAgICAgICBpICs9IFB5VW5pY29kZV9HRVRfU0laRShzZWxmKTsKKyAgICAgICAgcmV0dXJuIHVuaWNvZGVfZ2V0aXRlbShzZWxmLCBpKTsKKyAgICB9IGVsc2UgaWYgKFB5U2xpY2VfQ2hlY2soaXRlbSkpIHsKKyAgICAgICAgUHlfc3NpemVfdCBzdGFydCwgc3RvcCwgc3RlcCwgc2xpY2VsZW5ndGgsIGN1ciwgaTsKKyAgICAgICAgUHlfVU5JQ09ERSogc291cmNlX2J1ZjsKKyAgICAgICAgUHlfVU5JQ09ERSogcmVzdWx0X2J1ZjsKKyAgICAgICAgUHlPYmplY3QqIHJlc3VsdDsKKworICAgICAgICBpZiAoUHlTbGljZV9HZXRJbmRpY2VzRXgoKFB5U2xpY2VPYmplY3QqKWl0ZW0sIFB5VW5pY29kZV9HRVRfU0laRShzZWxmKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZzdGFydCwgJnN0b3AsICZzdGVwLCAmc2xpY2VsZW5ndGgpIDwgMCkgeworICAgICAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgICAgIH0KKworICAgICAgICBpZiAoc2xpY2VsZW5ndGggPD0gMCkgeworICAgICAgICAgICAgcmV0dXJuIFB5VW5pY29kZV9Gcm9tVW5pY29kZShOVUxMLCAwKTsKKyAgICAgICAgfSBlbHNlIGlmIChzdGFydCA9PSAwICYmIHN0ZXAgPT0gMSAmJiBzbGljZWxlbmd0aCA9PSBzZWxmLT5sZW5ndGggJiYKKyAgICAgICAgICAgICAgICAgICBQeVVuaWNvZGVfQ2hlY2tFeGFjdChzZWxmKSkgeworICAgICAgICAgICAgUHlfSU5DUkVGKHNlbGYpOworICAgICAgICAgICAgcmV0dXJuIChQeU9iamVjdCAqKXNlbGY7CisgICAgICAgIH0gZWxzZSBpZiAoc3RlcCA9PSAxKSB7CisgICAgICAgICAgICByZXR1cm4gUHlVbmljb2RlX0Zyb21Vbmljb2RlKHNlbGYtPnN0ciArIHN0YXJ0LCBzbGljZWxlbmd0aCk7CisgICAgICAgIH0gZWxzZSB7CisgICAgICAgICAgICBzb3VyY2VfYnVmID0gUHlVbmljb2RlX0FTX1VOSUNPREUoKFB5T2JqZWN0KilzZWxmKTsKKyAgICAgICAgICAgIHJlc3VsdF9idWYgPSAoUHlfVU5JQ09ERSAqKVB5T2JqZWN0X01BTExPQyhzbGljZWxlbmd0aCoKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplb2YoUHlfVU5JQ09ERSkpOworCisgICAgICAgICAgICBpZiAocmVzdWx0X2J1ZiA9PSBOVUxMKQorICAgICAgICAgICAgICAgIHJldHVybiBQeUVycl9Ob01lbW9yeSgpOworCisgICAgICAgICAgICBmb3IgKGN1ciA9IHN0YXJ0LCBpID0gMDsgaSA8IHNsaWNlbGVuZ3RoOyBjdXIgKz0gc3RlcCwgaSsrKSB7CisgICAgICAgICAgICAgICAgcmVzdWx0X2J1ZltpXSA9IHNvdXJjZV9idWZbY3VyXTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgcmVzdWx0ID0gUHlVbmljb2RlX0Zyb21Vbmljb2RlKHJlc3VsdF9idWYsIHNsaWNlbGVuZ3RoKTsKKyAgICAgICAgICAgIFB5T2JqZWN0X0ZSRUUocmVzdWx0X2J1Zik7CisgICAgICAgICAgICByZXR1cm4gcmVzdWx0OworICAgICAgICB9CisgICAgfSBlbHNlIHsKKyAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1R5cGVFcnJvciwgInN0cmluZyBpbmRpY2VzIG11c3QgYmUgaW50ZWdlcnMiKTsKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgfQorfQorCitzdGF0aWMgUHlNYXBwaW5nTWV0aG9kcyB1bmljb2RlX2FzX21hcHBpbmcgPSB7CisgICAgKGxlbmZ1bmMpdW5pY29kZV9sZW5ndGgsICAgICAgICAvKiBtcF9sZW5ndGggKi8KKyAgICAoYmluYXJ5ZnVuYyl1bmljb2RlX3N1YnNjcmlwdCwgIC8qIG1wX3N1YnNjcmlwdCAqLworICAgIChvYmpvYmphcmdwcm9jKTAsICAgICAgICAgICAvKiBtcF9hc3Nfc3Vic2NyaXB0ICovCit9OworCitzdGF0aWMgUHlfc3NpemVfdAordW5pY29kZV9idWZmZXJfZ2V0cmVhZGJ1ZihQeVVuaWNvZGVPYmplY3QgKnNlbGYsCisgICAgICAgICAgICAgICAgICAgICAgICAgIFB5X3NzaXplX3QgaW5kZXgsCisgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHZvaWQgKipwdHIpCit7CisgICAgaWYgKGluZGV4ICE9IDApIHsKKyAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1N5c3RlbUVycm9yLAorICAgICAgICAgICAgICAgICAgICAgICAgImFjY2Vzc2luZyBub24tZXhpc3RlbnQgdW5pY29kZSBzZWdtZW50Iik7CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisgICAgKnB0ciA9ICh2b2lkICopIHNlbGYtPnN0cjsKKyAgICByZXR1cm4gUHlVbmljb2RlX0dFVF9EQVRBX1NJWkUoc2VsZik7Cit9CisKK3N0YXRpYyBQeV9zc2l6ZV90Cit1bmljb2RlX2J1ZmZlcl9nZXR3cml0ZWJ1ZihQeVVuaWNvZGVPYmplY3QgKnNlbGYsIFB5X3NzaXplX3QgaW5kZXgsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB2b2lkICoqcHRyKQoreworICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19UeXBlRXJyb3IsCisgICAgICAgICAgICAgICAgICAgICJjYW5ub3QgdXNlIHVuaWNvZGUgYXMgbW9kaWZpYWJsZSBidWZmZXIiKTsKKyAgICByZXR1cm4gLTE7Cit9CisKK3N0YXRpYyBpbnQKK3VuaWNvZGVfYnVmZmVyX2dldHNlZ2NvdW50KFB5VW5pY29kZU9iamVjdCAqc2VsZiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgIFB5X3NzaXplX3QgKmxlbnApCit7CisgICAgaWYgKGxlbnApCisgICAgICAgICpsZW5wID0gUHlVbmljb2RlX0dFVF9EQVRBX1NJWkUoc2VsZik7CisgICAgcmV0dXJuIDE7Cit9CisKK3N0YXRpYyBQeV9zc2l6ZV90Cit1bmljb2RlX2J1ZmZlcl9nZXRjaGFyYnVmKFB5VW5pY29kZU9iamVjdCAqc2VsZiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgUHlfc3NpemVfdCBpbmRleCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgdm9pZCAqKnB0cikKK3sKKyAgICBQeU9iamVjdCAqc3RyOworCisgICAgaWYgKGluZGV4ICE9IDApIHsKKyAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1N5c3RlbUVycm9yLAorICAgICAgICAgICAgICAgICAgICAgICAgImFjY2Vzc2luZyBub24tZXhpc3RlbnQgdW5pY29kZSBzZWdtZW50Iik7CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisgICAgc3RyID0gX1B5VW5pY29kZV9Bc0RlZmF1bHRFbmNvZGVkU3RyaW5nKChQeU9iamVjdCAqKXNlbGYsIE5VTEwpOworICAgIGlmIChzdHIgPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIC0xOworICAgICpwdHIgPSAodm9pZCAqKSBQeVN0cmluZ19BU19TVFJJTkcoc3RyKTsKKyAgICByZXR1cm4gUHlTdHJpbmdfR0VUX1NJWkUoc3RyKTsKK30KKworLyogSGVscGVycyBmb3IgUHlVbmljb2RlX0Zvcm1hdCgpICovCisKK3N0YXRpYyBQeU9iamVjdCAqCitnZXRuZXh0YXJnKFB5T2JqZWN0ICphcmdzLCBQeV9zc2l6ZV90IGFyZ2xlbiwgUHlfc3NpemVfdCAqcF9hcmdpZHgpCit7CisgICAgUHlfc3NpemVfdCBhcmdpZHggPSAqcF9hcmdpZHg7CisgICAgaWYgKGFyZ2lkeCA8IGFyZ2xlbikgeworICAgICAgICAoKnBfYXJnaWR4KSsrOworICAgICAgICBpZiAoYXJnbGVuIDwgMCkKKyAgICAgICAgICAgIHJldHVybiBhcmdzOworICAgICAgICBlbHNlCisgICAgICAgICAgICByZXR1cm4gUHlUdXBsZV9HZXRJdGVtKGFyZ3MsIGFyZ2lkeCk7CisgICAgfQorICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19UeXBlRXJyb3IsCisgICAgICAgICAgICAgICAgICAgICJub3QgZW5vdWdoIGFyZ3VtZW50cyBmb3IgZm9ybWF0IHN0cmluZyIpOworICAgIHJldHVybiBOVUxMOworfQorCisjZGVmaW5lIEZfTEpVU1QgKDE8PDApCisjZGVmaW5lIEZfU0lHTiAgKDE8PDEpCisjZGVmaW5lIEZfQkxBTksgKDE8PDIpCisjZGVmaW5lIEZfQUxUICAgKDE8PDMpCisjZGVmaW5lIEZfWkVSTyAgKDE8PDQpCisKK3N0YXRpYyBQeV9zc2l6ZV90CitzdHJ0b3VuaWNvZGUoUHlfVU5JQ09ERSAqYnVmZmVyLCBjb25zdCBjaGFyICpjaGFyYnVmZmVyKQoreworICAgIHJlZ2lzdGVyIFB5X3NzaXplX3QgaTsKKyAgICBQeV9zc2l6ZV90IGxlbiA9IHN0cmxlbihjaGFyYnVmZmVyKTsKKyAgICBmb3IgKGkgPSBsZW4gLSAxOyBpID49IDA7IGktLSkKKyAgICAgICAgYnVmZmVyW2ldID0gKFB5X1VOSUNPREUpIGNoYXJidWZmZXJbaV07CisKKyAgICByZXR1cm4gbGVuOworfQorCitzdGF0aWMgaW50Citsb25ndG91bmljb2RlKFB5X1VOSUNPREUgKmJ1ZmZlciwgc2l6ZV90IGxlbiwgY29uc3QgY2hhciAqZm9ybWF0LCBsb25nIHgpCit7CisgICAgUHlfc3NpemVfdCByZXN1bHQ7CisKKyAgICBQeU9TX3NucHJpbnRmKChjaGFyICopYnVmZmVyLCBsZW4sIGZvcm1hdCwgeCk7CisgICAgcmVzdWx0ID0gc3RydG91bmljb2RlKGJ1ZmZlciwgKGNoYXIgKilidWZmZXIpOworICAgIHJldHVybiBQeV9TQUZFX0RPV05DQVNUKHJlc3VsdCwgUHlfc3NpemVfdCwgaW50KTsKK30KKworLyogWFhYIFRvIHNhdmUgc29tZSBjb2RlIGR1cGxpY2F0aW9uLCBmb3JtYXRmbG9hdC9sb25nL2ludCBjb3VsZCBoYXZlIGJlZW4KKyAgIHNoYXJlZCB3aXRoIHN0cmluZ29iamVjdC5jLCBjb252ZXJ0aW5nIGZyb20gOC1iaXQgdG8gVW5pY29kZSBhZnRlciB0aGUKKyAgIGZvcm1hdHRpbmcgaXMgZG9uZS4gKi8KKworLyogUmV0dXJucyBhIG5ldyByZWZlcmVuY2UgdG8gYSBQeVVuaWNvZGUgb2JqZWN0LCBvciBOVUxMIG9uIGZhaWx1cmUuICovCisKK3N0YXRpYyBQeU9iamVjdCAqCitmb3JtYXRmbG9hdChQeU9iamVjdCAqdiwgaW50IGZsYWdzLCBpbnQgcHJlYywgaW50IHR5cGUpCit7CisgICAgY2hhciAqcDsKKyAgICBQeU9iamVjdCAqcmVzdWx0OworICAgIGRvdWJsZSB4OworCisgICAgeCA9IFB5RmxvYXRfQXNEb3VibGUodik7CisgICAgaWYgKHggPT0gLTEuMCAmJiBQeUVycl9PY2N1cnJlZCgpKQorICAgICAgICByZXR1cm4gTlVMTDsKKworICAgIGlmIChwcmVjIDwgMCkKKyAgICAgICAgcHJlYyA9IDY7CisKKyAgICBwID0gUHlPU19kb3VibGVfdG9fc3RyaW5nKHgsIHR5cGUsIHByZWMsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoZmxhZ3MgJiBGX0FMVCkgPyBQeV9EVFNGX0FMVCA6IDAsIE5VTEwpOworICAgIGlmIChwID09IE5VTEwpCisgICAgICAgIHJldHVybiBOVUxMOworICAgIHJlc3VsdCA9IFB5VW5pY29kZV9Gcm9tU3RyaW5nQW5kU2l6ZShwLCBzdHJsZW4ocCkpOworICAgIFB5TWVtX0ZyZWUocCk7CisgICAgcmV0dXJuIHJlc3VsdDsKK30KKworc3RhdGljIFB5T2JqZWN0KgorZm9ybWF0bG9uZyhQeU9iamVjdCAqdmFsLCBpbnQgZmxhZ3MsIGludCBwcmVjLCBpbnQgdHlwZSkKK3sKKyAgICBjaGFyICpidWY7CisgICAgaW50IGksIGxlbjsKKyAgICBQeU9iamVjdCAqc3RyOyAvKiB0ZW1wb3Jhcnkgc3RyaW5nIG9iamVjdC4gKi8KKyAgICBQeVVuaWNvZGVPYmplY3QgKnJlc3VsdDsKKworICAgIHN0ciA9IF9QeVN0cmluZ19Gb3JtYXRMb25nKHZhbCwgZmxhZ3MsIHByZWMsIHR5cGUsICZidWYsICZsZW4pOworICAgIGlmICghc3RyKQorICAgICAgICByZXR1cm4gTlVMTDsKKyAgICByZXN1bHQgPSBfUHlVbmljb2RlX05ldyhsZW4pOworICAgIGlmICghcmVzdWx0KSB7CisgICAgICAgIFB5X0RFQ1JFRihzdHIpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgZm9yIChpID0gMDsgaSA8IGxlbjsgaSsrKQorICAgICAgICByZXN1bHQtPnN0cltpXSA9IGJ1ZltpXTsKKyAgICByZXN1bHQtPnN0cltsZW5dID0gMDsKKyAgICBQeV9ERUNSRUYoc3RyKTsKKyAgICByZXR1cm4gKFB5T2JqZWN0KilyZXN1bHQ7Cit9CisKK3N0YXRpYyBpbnQKK2Zvcm1hdGludChQeV9VTklDT0RFICpidWYsCisgICAgICAgICAgc2l6ZV90IGJ1ZmxlbiwKKyAgICAgICAgICBpbnQgZmxhZ3MsCisgICAgICAgICAgaW50IHByZWMsCisgICAgICAgICAgaW50IHR5cGUsCisgICAgICAgICAgUHlPYmplY3QgKnYpCit7CisgICAgLyogZm10ID0gJyUjLicgKyBgcHJlY2AgKyAnbCcgKyBgdHlwZWAKKyAgICAgKiB3b3JzdCBjYXNlIGxlbmd0aCA9IDMgKyAxOSAod29yc3QgbGVuIG9mIElOVF9NQVggb24gNjQtYml0IG1hY2hpbmUpCisgICAgICogICAgICAgICAgICAgICAgICAgICArIDEgKyAxCisgICAgICogICAgICAgICAgICAgICAgICAgPSAyNAorICAgICAqLworICAgIGNoYXIgZm10WzY0XTsgLyogcGxlbnR5IGJpZyBlbm91Z2ghICovCisgICAgY2hhciAqc2lnbjsKKyAgICBsb25nIHg7CisKKyAgICB4ID0gUHlJbnRfQXNMb25nKHYpOworICAgIGlmICh4ID09IC0xICYmIFB5RXJyX09jY3VycmVkKCkpCisgICAgICAgIHJldHVybiAtMTsKKyAgICBpZiAoeCA8IDAgJiYgdHlwZSA9PSAndScpIHsKKyAgICAgICAgdHlwZSA9ICdkJzsKKyAgICB9CisgICAgaWYgKHggPCAwICYmICh0eXBlID09ICd4JyB8fCB0eXBlID09ICdYJyB8fCB0eXBlID09ICdvJykpCisgICAgICAgIHNpZ24gPSAiLSI7CisgICAgZWxzZQorICAgICAgICBzaWduID0gIiI7CisgICAgaWYgKHByZWMgPCAwKQorICAgICAgICBwcmVjID0gMTsKKworICAgIC8qIGJ1ZiA9ICcrJy8nLScvJycgKyAnMCcvJzB4Jy8nJyArICdbMC05XScqbWF4KHByZWMsIGxlbih4IGluIG9jdGFsKSkKKyAgICAgKiB3b3JzdCBjYXNlIGJ1ZiA9ICctMHgnICsgWzAtOV0qcHJlYywgd2hlcmUgcHJlYyA+PSAxMQorICAgICAqLworICAgIGlmIChidWZsZW4gPD0gMTQgfHwgYnVmbGVuIDw9IChzaXplX3QpMyArIChzaXplX3QpcHJlYykgeworICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfT3ZlcmZsb3dFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICJmb3JtYXR0ZWQgaW50ZWdlciBpcyB0b28gbG9uZyAocHJlY2lzaW9uIHRvbyBsYXJnZT8pIik7CisgICAgICAgIHJldHVybiAtMTsKKyAgICB9CisKKyAgICBpZiAoKGZsYWdzICYgRl9BTFQpICYmCisgICAgICAgICh0eXBlID09ICd4JyB8fCB0eXBlID09ICdYJykpIHsKKyAgICAgICAgLyogV2hlbiBjb252ZXJ0aW5nIHVuZGVyICUjeCBvciAlI1gsIHRoZXJlIGFyZSBhIG51bWJlcgorICAgICAgICAgKiBvZiBpc3N1ZXMgdGhhdCBjYXVzZSBwYWluOgorICAgICAgICAgKiAtIHdoZW4gMCBpcyBiZWluZyBjb252ZXJ0ZWQsIHRoZSBDIHN0YW5kYXJkIGxlYXZlcyBvZmYKKyAgICAgICAgICogICB0aGUgJzB4JyBvciAnMFgnLCB3aGljaCBpcyBpbmNvbnNpc3RlbnQgd2l0aCBvdGhlcgorICAgICAgICAgKiAgICUjeC8lI1ggY29udmVyc2lvbnMgYW5kIGluY29uc2lzdGVudCB3aXRoIFB5dGhvbidzCisgICAgICAgICAqICAgaGV4KCkgZnVuY3Rpb24KKyAgICAgICAgICogLSB0aGVyZSBhcmUgcGxhdGZvcm1zIHRoYXQgdmlvbGF0ZSB0aGUgc3RhbmRhcmQgYW5kCisgICAgICAgICAqICAgY29udmVydCAwIHdpdGggdGhlICcweCcgb3IgJzBYJworICAgICAgICAgKiAgIChNZXRyb3dlcmtzLCBDb21wYXEgVHJ1NjQpCisgICAgICAgICAqIC0gdGhlcmUgYXJlIHBsYXRmb3JtcyB0aGF0IGdpdmUgJzB4JyB3aGVuIGNvbnZlcnRpbmcKKyAgICAgICAgICogICB1bmRlciAlI1gsIGJ1dCBjb252ZXJ0IDAgaW4gYWNjb3JkYW5jZSB3aXRoIHRoZQorICAgICAgICAgKiAgIHN0YW5kYXJkIChPUy8yIEVNWCkKKyAgICAgICAgICoKKyAgICAgICAgICogV2UgY2FuIGFjaGlldmUgdGhlIGRlc2lyZWQgY29uc2lzdGVuY3kgYnkgaW5zZXJ0aW5nIG91cgorICAgICAgICAgKiBvd24gJzB4JyBvciAnMFgnIHByZWZpeCwgYW5kIHN1YnN0aXR1dGluZyAleC8lWCBpbiBwbGFjZQorICAgICAgICAgKiBvZiAlI3gvJSNYLgorICAgICAgICAgKgorICAgICAgICAgKiBOb3RlIHRoYXQgdGhpcyBpcyB0aGUgc2FtZSBhcHByb2FjaCBhcyB1c2VkIGluCisgICAgICAgICAqIGZvcm1hdGludCgpIGluIHN0cmluZ29iamVjdC5jCisgICAgICAgICAqLworICAgICAgICBQeU9TX3NucHJpbnRmKGZtdCwgc2l6ZW9mKGZtdCksICIlczAlYyUlLiVkbCVjIiwKKyAgICAgICAgICAgICAgICAgICAgICBzaWduLCB0eXBlLCBwcmVjLCB0eXBlKTsKKyAgICB9CisgICAgZWxzZSB7CisgICAgICAgIFB5T1Nfc25wcmludGYoZm10LCBzaXplb2YoZm10KSwgIiVzJSUlcy4lZGwlYyIsCisgICAgICAgICAgICAgICAgICAgICAgc2lnbiwgKGZsYWdzJkZfQUxUKSA/ICIjIiA6ICIiLAorICAgICAgICAgICAgICAgICAgICAgIHByZWMsIHR5cGUpOworICAgIH0KKyAgICBpZiAoc2lnblswXSkKKyAgICAgICAgcmV0dXJuIGxvbmd0b3VuaWNvZGUoYnVmLCBidWZsZW4sIGZtdCwgLXgpOworICAgIGVsc2UKKyAgICAgICAgcmV0dXJuIGxvbmd0b3VuaWNvZGUoYnVmLCBidWZsZW4sIGZtdCwgeCk7Cit9CisKK3N0YXRpYyBpbnQKK2Zvcm1hdGNoYXIoUHlfVU5JQ09ERSAqYnVmLAorICAgICAgICAgICBzaXplX3QgYnVmbGVuLAorICAgICAgICAgICBQeU9iamVjdCAqdikKK3sKKyAgICBQeU9iamVjdCAqdW5pc3RyOworICAgIGNoYXIgKnN0cjsKKyAgICAvKiBwcmVzdW1lIHRoYXQgdGhlIGJ1ZmZlciBpcyBhdCBsZWFzdCAyIGNoYXJhY3RlcnMgbG9uZyAqLworICAgIGlmIChQeVVuaWNvZGVfQ2hlY2sodikpIHsKKyAgICAgICAgaWYgKFB5VW5pY29kZV9HRVRfU0laRSh2KSAhPSAxKQorICAgICAgICAgICAgZ290byBvbkVycm9yOworICAgICAgICBidWZbMF0gPSBQeVVuaWNvZGVfQVNfVU5JQ09ERSh2KVswXTsKKyAgICB9CisKKyAgICBlbHNlIGlmIChQeVN0cmluZ19DaGVjayh2KSkgeworICAgICAgICBpZiAoUHlTdHJpbmdfR0VUX1NJWkUodikgIT0gMSkKKyAgICAgICAgICAgIGdvdG8gb25FcnJvcjsKKyAgICAgICAgLyogIzc2NDk6ICJ1JyVjJyAlIGNoYXIiIHNob3VsZCBiZWhhdmUgbGlrZSAidSclcycgJSBjaGFyIiBhbmQgZmFpbAorICAgICAgICAgICB3aXRoIGEgVW5pY29kZURlY29kZUVycm9yIGlmICdjaGFyJyBpcyBub3QgZGVjb2RhYmxlIHdpdGggdGhlCisgICAgICAgICAgIGRlZmF1bHQgZW5jb2RpbmcgKHVzdWFsbHkgQVNDSUksIGJ1dCBpdCBtaWdodCBiZSBzb21ldGhpbmcgZWxzZSkgKi8KKyAgICAgICAgc3RyID0gUHlTdHJpbmdfQVNfU1RSSU5HKHYpOworICAgICAgICBpZiAoKHVuc2lnbmVkIGNoYXIpc3RyWzBdID4gMHg3RikgeworICAgICAgICAgICAgLyogdGhlIGNoYXIgaXMgbm90IEFTQ0lJOyB0cnkgdG8gZGVjb2RlIHRoZSBzdHJpbmcgdXNpbmcgdGhlCisgICAgICAgICAgICAgICBkZWZhdWx0IGVuY29kaW5nIGFuZCByZXR1cm4gLTEgdG8gbGV0IHRoZSBVbmljb2RlRGVjb2RlRXJyb3IKKyAgICAgICAgICAgICAgIGJlIHJhaXNlZCBpZiB0aGUgc3RyaW5nIGNhbid0IGJlIGRlY29kZWQgKi8KKyAgICAgICAgICAgIHVuaXN0ciA9IFB5VW5pY29kZV9EZWNvZGUoc3RyLCAxLCBOVUxMLCAic3RyaWN0Iik7CisgICAgICAgICAgICBpZiAodW5pc3RyID09IE5VTEwpCisgICAgICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICAgICAgYnVmWzBdID0gUHlVbmljb2RlX0FTX1VOSUNPREUodW5pc3RyKVswXTsKKyAgICAgICAgICAgIFB5X0RFQ1JFRih1bmlzdHIpOworICAgICAgICB9CisgICAgICAgIGVsc2UKKyAgICAgICAgICAgIGJ1ZlswXSA9IChQeV9VTklDT0RFKXN0clswXTsKKyAgICB9CisKKyAgICBlbHNlIHsKKyAgICAgICAgLyogSW50ZWdlciBpbnB1dCB0cnVuY2F0ZWQgdG8gYSBjaGFyYWN0ZXIgKi8KKyAgICAgICAgbG9uZyB4OworICAgICAgICB4ID0gUHlJbnRfQXNMb25nKHYpOworICAgICAgICBpZiAoeCA9PSAtMSAmJiBQeUVycl9PY2N1cnJlZCgpKQorICAgICAgICAgICAgZ290byBvbkVycm9yOworI2lmZGVmIFB5X1VOSUNPREVfV0lERQorICAgICAgICBpZiAoeCA8IDAgfHwgeCA+IDB4MTBmZmZmKSB7CisgICAgICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfT3ZlcmZsb3dFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAiJWMgYXJnIG5vdCBpbiByYW5nZSgweDExMDAwMCkgIgorICAgICAgICAgICAgICAgICAgICAgICAgICAgICIod2lkZSBQeXRob24gYnVpbGQpIik7CisgICAgICAgICAgICByZXR1cm4gLTE7CisgICAgICAgIH0KKyNlbHNlCisgICAgICAgIGlmICh4IDwgMCB8fCB4ID4gMHhmZmZmKSB7CisgICAgICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfT3ZlcmZsb3dFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAiJWMgYXJnIG5vdCBpbiByYW5nZSgweDEwMDAwKSAiCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgIihuYXJyb3cgUHl0aG9uIGJ1aWxkKSIpOworICAgICAgICAgICAgcmV0dXJuIC0xOworICAgICAgICB9CisjZW5kaWYKKyAgICAgICAgYnVmWzBdID0gKFB5X1VOSUNPREUpIHg7CisgICAgfQorICAgIGJ1ZlsxXSA9ICdcMCc7CisgICAgcmV0dXJuIDE7CisKKyAgb25FcnJvcjoKKyAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfVHlwZUVycm9yLAorICAgICAgICAgICAgICAgICAgICAiJWMgcmVxdWlyZXMgaW50IG9yIGNoYXIiKTsKKyAgICByZXR1cm4gLTE7Cit9CisKKy8qIGZtdCUodjEsdjIsLi4uKSBpcyByb3VnaGx5IGVxdWl2YWxlbnQgdG8gc3ByaW50ZihmbXQsIHYxLCB2MiwgLi4uKQorCisgICBGT1JNQVRCVUZMRU4gaXMgdGhlIGxlbmd0aCBvZiB0aGUgYnVmZmVyIGluIHdoaWNoIHRoZSBpbnRzICYKKyAgIGNoYXJzIGFyZSBmb3JtYXR0ZWQuIFhYWCBUaGlzIGlzIGEgbWFnaWMgbnVtYmVyLiBFYWNoIGZvcm1hdHRpbmcKKyAgIHJvdXRpbmUgZG9lcyBib3VuZHMgY2hlY2tpbmcgdG8gZW5zdXJlIG5vIG92ZXJmbG93LCBidXQgYSBiZXR0ZXIKKyAgIHNvbHV0aW9uIG1heSBiZSB0byBtYWxsb2MgYSBidWZmZXIgb2YgYXBwcm9wcmlhdGUgc2l6ZSBmb3IgZWFjaAorICAgZm9ybWF0LiBGb3Igbm93LCB0aGUgY3VycmVudCBzb2x1dGlvbiBpcyBzdWZmaWNpZW50LgorKi8KKyNkZWZpbmUgRk9STUFUQlVGTEVOIChzaXplX3QpMTIwCisKK1B5T2JqZWN0ICpQeVVuaWNvZGVfRm9ybWF0KFB5T2JqZWN0ICpmb3JtYXQsCisgICAgICAgICAgICAgICAgICAgICAgICAgICBQeU9iamVjdCAqYXJncykKK3sKKyAgICBQeV9VTklDT0RFICpmbXQsICpyZXM7CisgICAgUHlfc3NpemVfdCBmbXRjbnQsIHJlc2NudCwgcmVzbGVuLCBhcmdsZW4sIGFyZ2lkeDsKKyAgICBpbnQgYXJnc19vd25lZCA9IDA7CisgICAgUHlVbmljb2RlT2JqZWN0ICpyZXN1bHQgPSBOVUxMOworICAgIFB5T2JqZWN0ICpkaWN0ID0gTlVMTDsKKyAgICBQeU9iamVjdCAqdWZvcm1hdDsKKworICAgIGlmIChmb3JtYXQgPT0gTlVMTCB8fCBhcmdzID09IE5VTEwpIHsKKyAgICAgICAgUHlFcnJfQmFkSW50ZXJuYWxDYWxsKCk7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICB1Zm9ybWF0ID0gUHlVbmljb2RlX0Zyb21PYmplY3QoZm9ybWF0KTsKKyAgICBpZiAodWZvcm1hdCA9PSBOVUxMKQorICAgICAgICByZXR1cm4gTlVMTDsKKyAgICBmbXQgPSBQeVVuaWNvZGVfQVNfVU5JQ09ERSh1Zm9ybWF0KTsKKyAgICBmbXRjbnQgPSBQeVVuaWNvZGVfR0VUX1NJWkUodWZvcm1hdCk7CisKKyAgICByZXNsZW4gPSByZXNjbnQgPSBmbXRjbnQgKyAxMDA7CisgICAgcmVzdWx0ID0gX1B5VW5pY29kZV9OZXcocmVzbGVuKTsKKyAgICBpZiAocmVzdWx0ID09IE5VTEwpCisgICAgICAgIGdvdG8gb25FcnJvcjsKKyAgICByZXMgPSBQeVVuaWNvZGVfQVNfVU5JQ09ERShyZXN1bHQpOworCisgICAgaWYgKFB5VHVwbGVfQ2hlY2soYXJncykpIHsKKyAgICAgICAgYXJnbGVuID0gUHlUdXBsZV9TaXplKGFyZ3MpOworICAgICAgICBhcmdpZHggPSAwOworICAgIH0KKyAgICBlbHNlIHsKKyAgICAgICAgYXJnbGVuID0gLTE7CisgICAgICAgIGFyZ2lkeCA9IC0yOworICAgIH0KKyAgICBpZiAoUHlfVFlQRShhcmdzKS0+dHBfYXNfbWFwcGluZyAmJiBQeV9UWVBFKGFyZ3MpLT50cF9hc19tYXBwaW5nLT5tcF9zdWJzY3JpcHQgJiYKKyAgICAgICAgIVB5VHVwbGVfQ2hlY2soYXJncykgJiYgIVB5T2JqZWN0X1R5cGVDaGVjayhhcmdzLCAmUHlCYXNlU3RyaW5nX1R5cGUpKQorICAgICAgICBkaWN0ID0gYXJnczsKKworICAgIHdoaWxlICgtLWZtdGNudCA+PSAwKSB7CisgICAgICAgIGlmICgqZm10ICE9ICclJykgeworICAgICAgICAgICAgaWYgKC0tcmVzY250IDwgMCkgeworICAgICAgICAgICAgICAgIHJlc2NudCA9IGZtdGNudCArIDEwMDsKKyAgICAgICAgICAgICAgICByZXNsZW4gKz0gcmVzY250OworICAgICAgICAgICAgICAgIGlmIChfUHlVbmljb2RlX1Jlc2l6ZSgmcmVzdWx0LCByZXNsZW4pIDwgMCkKKyAgICAgICAgICAgICAgICAgICAgZ290byBvbkVycm9yOworICAgICAgICAgICAgICAgIHJlcyA9IFB5VW5pY29kZV9BU19VTklDT0RFKHJlc3VsdCkgKyByZXNsZW4gLSByZXNjbnQ7CisgICAgICAgICAgICAgICAgLS1yZXNjbnQ7CisgICAgICAgICAgICB9CisgICAgICAgICAgICAqcmVzKysgPSAqZm10Kys7CisgICAgICAgIH0KKyAgICAgICAgZWxzZSB7CisgICAgICAgICAgICAvKiBHb3QgYSBmb3JtYXQgc3BlY2lmaWVyICovCisgICAgICAgICAgICBpbnQgZmxhZ3MgPSAwOworICAgICAgICAgICAgUHlfc3NpemVfdCB3aWR0aCA9IC0xOworICAgICAgICAgICAgaW50IHByZWMgPSAtMTsKKyAgICAgICAgICAgIFB5X1VOSUNPREUgYyA9ICdcMCc7CisgICAgICAgICAgICBQeV9VTklDT0RFIGZpbGw7CisgICAgICAgICAgICBpbnQgaXNudW1vazsKKyAgICAgICAgICAgIFB5T2JqZWN0ICp2ID0gTlVMTDsKKyAgICAgICAgICAgIFB5T2JqZWN0ICp0ZW1wID0gTlVMTDsKKyAgICAgICAgICAgIFB5X1VOSUNPREUgKnBidWY7CisgICAgICAgICAgICBQeV9VTklDT0RFIHNpZ247CisgICAgICAgICAgICBQeV9zc2l6ZV90IGxlbjsKKyAgICAgICAgICAgIFB5X1VOSUNPREUgZm9ybWF0YnVmW0ZPUk1BVEJVRkxFTl07IC8qIEZvciBmb3JtYXR7aW50LGNoYXJ9KCkgKi8KKworICAgICAgICAgICAgZm10Kys7CisgICAgICAgICAgICBpZiAoKmZtdCA9PSAnKCcpIHsKKyAgICAgICAgICAgICAgICBQeV9VTklDT0RFICprZXlzdGFydDsKKyAgICAgICAgICAgICAgICBQeV9zc2l6ZV90IGtleWxlbjsKKyAgICAgICAgICAgICAgICBQeU9iamVjdCAqa2V5OworICAgICAgICAgICAgICAgIGludCBwY291bnQgPSAxOworCisgICAgICAgICAgICAgICAgaWYgKGRpY3QgPT0gTlVMTCkgeworICAgICAgICAgICAgICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfVHlwZUVycm9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImZvcm1hdCByZXF1aXJlcyBhIG1hcHBpbmciKTsKKyAgICAgICAgICAgICAgICAgICAgZ290byBvbkVycm9yOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICArK2ZtdDsKKyAgICAgICAgICAgICAgICAtLWZtdGNudDsKKyAgICAgICAgICAgICAgICBrZXlzdGFydCA9IGZtdDsKKyAgICAgICAgICAgICAgICAvKiBTa2lwIG92ZXIgYmFsYW5jZWQgcGFyZW50aGVzZXMgKi8KKyAgICAgICAgICAgICAgICB3aGlsZSAocGNvdW50ID4gMCAmJiAtLWZtdGNudCA+PSAwKSB7CisgICAgICAgICAgICAgICAgICAgIGlmICgqZm10ID09ICcpJykKKyAgICAgICAgICAgICAgICAgICAgICAgIC0tcGNvdW50OworICAgICAgICAgICAgICAgICAgICBlbHNlIGlmICgqZm10ID09ICcoJykKKyAgICAgICAgICAgICAgICAgICAgICAgICsrcGNvdW50OworICAgICAgICAgICAgICAgICAgICBmbXQrKzsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAga2V5bGVuID0gZm10IC0ga2V5c3RhcnQgLSAxOworICAgICAgICAgICAgICAgIGlmIChmbXRjbnQgPCAwIHx8IHBjb3VudCA+IDApIHsKKyAgICAgICAgICAgICAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1ZhbHVlRXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiaW5jb21wbGV0ZSBmb3JtYXQga2V5Iik7CisgICAgICAgICAgICAgICAgICAgIGdvdG8gb25FcnJvcjsKKyAgICAgICAgICAgICAgICB9CisjaWYgMAorICAgICAgICAgICAgICAgIC8qIGtleXMgYXJlIGNvbnZlcnRlZCB0byBzdHJpbmdzIHVzaW5nIFVURi04IGFuZAorICAgICAgICAgICAgICAgICAgIHRoZW4gbG9va2VkIHVwIHNpbmNlIFB5dGhvbiB1c2VzIHN0cmluZ3MgdG8gaG9sZAorICAgICAgICAgICAgICAgICAgIHZhcmlhYmxlcyBuYW1lcyBldGMuIGluIGl0cyBuYW1lc3BhY2VzIGFuZCB3ZQorICAgICAgICAgICAgICAgICAgIHdvdWxkbid0IHdhbnQgdG8gYnJlYWsgY29tbW9uIGlkaW9tcy4gKi8KKyAgICAgICAgICAgICAgICBrZXkgPSBQeVVuaWNvZGVfRW5jb2RlVVRGOChrZXlzdGFydCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBrZXlsZW4sCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCk7CisjZWxzZQorICAgICAgICAgICAgICAgIGtleSA9IFB5VW5pY29kZV9Gcm9tVW5pY29kZShrZXlzdGFydCwga2V5bGVuKTsKKyNlbmRpZgorICAgICAgICAgICAgICAgIGlmIChrZXkgPT0gTlVMTCkKKyAgICAgICAgICAgICAgICAgICAgZ290byBvbkVycm9yOworICAgICAgICAgICAgICAgIGlmIChhcmdzX293bmVkKSB7CisgICAgICAgICAgICAgICAgICAgIFB5X0RFQ1JFRihhcmdzKTsKKyAgICAgICAgICAgICAgICAgICAgYXJnc19vd25lZCA9IDA7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGFyZ3MgPSBQeU9iamVjdF9HZXRJdGVtKGRpY3QsIGtleSk7CisgICAgICAgICAgICAgICAgUHlfREVDUkVGKGtleSk7CisgICAgICAgICAgICAgICAgaWYgKGFyZ3MgPT0gTlVMTCkgeworICAgICAgICAgICAgICAgICAgICBnb3RvIG9uRXJyb3I7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGFyZ3Nfb3duZWQgPSAxOworICAgICAgICAgICAgICAgIGFyZ2xlbiA9IC0xOworICAgICAgICAgICAgICAgIGFyZ2lkeCA9IC0yOworICAgICAgICAgICAgfQorICAgICAgICAgICAgd2hpbGUgKC0tZm10Y250ID49IDApIHsKKyAgICAgICAgICAgICAgICBzd2l0Y2ggKGMgPSAqZm10KyspIHsKKyAgICAgICAgICAgICAgICBjYXNlICctJzogZmxhZ3MgfD0gRl9MSlVTVDsgY29udGludWU7CisgICAgICAgICAgICAgICAgY2FzZSAnKyc6IGZsYWdzIHw9IEZfU0lHTjsgY29udGludWU7CisgICAgICAgICAgICAgICAgY2FzZSAnICc6IGZsYWdzIHw9IEZfQkxBTks7IGNvbnRpbnVlOworICAgICAgICAgICAgICAgIGNhc2UgJyMnOiBmbGFncyB8PSBGX0FMVDsgY29udGludWU7CisgICAgICAgICAgICAgICAgY2FzZSAnMCc6IGZsYWdzIHw9IEZfWkVSTzsgY29udGludWU7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKGMgPT0gJyonKSB7CisgICAgICAgICAgICAgICAgdiA9IGdldG5leHRhcmcoYXJncywgYXJnbGVuLCAmYXJnaWR4KTsKKyAgICAgICAgICAgICAgICBpZiAodiA9PSBOVUxMKQorICAgICAgICAgICAgICAgICAgICBnb3RvIG9uRXJyb3I7CisgICAgICAgICAgICAgICAgaWYgKCFQeUludF9DaGVjayh2KSkgeworICAgICAgICAgICAgICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfVHlwZUVycm9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiogd2FudHMgaW50Iik7CisgICAgICAgICAgICAgICAgICAgIGdvdG8gb25FcnJvcjsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgd2lkdGggPSBQeUludF9Bc1NzaXplX3Qodik7CisgICAgICAgICAgICAgICAgaWYgKHdpZHRoID09IC0xICYmIFB5RXJyX09jY3VycmVkKCkpCisgICAgICAgICAgICAgICAgICAgIGdvdG8gb25FcnJvcjsKKyAgICAgICAgICAgICAgICBpZiAod2lkdGggPCAwKSB7CisgICAgICAgICAgICAgICAgICAgIGZsYWdzIHw9IEZfTEpVU1Q7CisgICAgICAgICAgICAgICAgICAgIHdpZHRoID0gLXdpZHRoOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBpZiAoLS1mbXRjbnQgPj0gMCkKKyAgICAgICAgICAgICAgICAgICAgYyA9ICpmbXQrKzsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGVsc2UgaWYgKGMgPj0gJzAnICYmIGMgPD0gJzknKSB7CisgICAgICAgICAgICAgICAgd2lkdGggPSBjIC0gJzAnOworICAgICAgICAgICAgICAgIHdoaWxlICgtLWZtdGNudCA+PSAwKSB7CisgICAgICAgICAgICAgICAgICAgIGMgPSAqZm10Kys7CisgICAgICAgICAgICAgICAgICAgIGlmIChjIDwgJzAnIHx8IGMgPiAnOScpCisgICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKKyAgICAgICAgICAgICAgICAgICAgaWYgKHdpZHRoID4gKFBZX1NTSVpFX1RfTUFYIC0gKChpbnQpYyAtICcwJykpIC8gMTApIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19WYWx1ZUVycm9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ3aWR0aCB0b28gYmlnIik7CisgICAgICAgICAgICAgICAgICAgICAgICBnb3RvIG9uRXJyb3I7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgd2lkdGggPSB3aWR0aCoxMCArIChjIC0gJzAnKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoYyA9PSAnLicpIHsKKyAgICAgICAgICAgICAgICBwcmVjID0gMDsKKyAgICAgICAgICAgICAgICBpZiAoLS1mbXRjbnQgPj0gMCkKKyAgICAgICAgICAgICAgICAgICAgYyA9ICpmbXQrKzsKKyAgICAgICAgICAgICAgICBpZiAoYyA9PSAnKicpIHsKKyAgICAgICAgICAgICAgICAgICAgdiA9IGdldG5leHRhcmcoYXJncywgYXJnbGVuLCAmYXJnaWR4KTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKHYgPT0gTlVMTCkKKyAgICAgICAgICAgICAgICAgICAgICAgIGdvdG8gb25FcnJvcjsKKyAgICAgICAgICAgICAgICAgICAgaWYgKCFQeUludF9DaGVjayh2KSkgeworICAgICAgICAgICAgICAgICAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1R5cGVFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiKiB3YW50cyBpbnQiKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIGdvdG8gb25FcnJvcjsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgICAgICBwcmVjID0gX1B5SW50X0FzSW50KHYpOworICAgICAgICAgICAgICAgICAgICBpZiAocHJlYyA9PSAtMSAmJiBQeUVycl9PY2N1cnJlZCgpKQorICAgICAgICAgICAgICAgICAgICAgICAgZ290byBvbkVycm9yOworICAgICAgICAgICAgICAgICAgICBpZiAocHJlYyA8IDApCisgICAgICAgICAgICAgICAgICAgICAgICBwcmVjID0gMDsKKyAgICAgICAgICAgICAgICAgICAgaWYgKC0tZm10Y250ID49IDApCisgICAgICAgICAgICAgICAgICAgICAgICBjID0gKmZtdCsrOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBlbHNlIGlmIChjID49ICcwJyAmJiBjIDw9ICc5JykgeworICAgICAgICAgICAgICAgICAgICBwcmVjID0gYyAtICcwJzsKKyAgICAgICAgICAgICAgICAgICAgd2hpbGUgKC0tZm10Y250ID49IDApIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIGMgPSAqZm10Kys7CisgICAgICAgICAgICAgICAgICAgICAgICBpZiAoYyA8ICcwJyB8fCBjID4gJzknKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOworICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHByZWMgPiAoSU5UX01BWCAtICgoaW50KWMgLSAnMCcpKSAvIDEwKSB7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1ZhbHVlRXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJwcmVjIHRvbyBiaWciKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBnb3RvIG9uRXJyb3I7CisgICAgICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgICAgICBwcmVjID0gcHJlYyoxMCArIChjIC0gJzAnKTsKKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgIH0gLyogcHJlYyAqLworICAgICAgICAgICAgaWYgKGZtdGNudCA+PSAwKSB7CisgICAgICAgICAgICAgICAgaWYgKGMgPT0gJ2gnIHx8IGMgPT0gJ2wnIHx8IGMgPT0gJ0wnKSB7CisgICAgICAgICAgICAgICAgICAgIGlmICgtLWZtdGNudCA+PSAwKQorICAgICAgICAgICAgICAgICAgICAgICAgYyA9ICpmbXQrKzsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoZm10Y250IDwgMCkgeworICAgICAgICAgICAgICAgIFB5RXJyX1NldFN0cmluZyhQeUV4Y19WYWx1ZUVycm9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiaW5jb21wbGV0ZSBmb3JtYXQiKTsKKyAgICAgICAgICAgICAgICBnb3RvIG9uRXJyb3I7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoYyAhPSAnJScpIHsKKyAgICAgICAgICAgICAgICB2ID0gZ2V0bmV4dGFyZyhhcmdzLCBhcmdsZW4sICZhcmdpZHgpOworICAgICAgICAgICAgICAgIGlmICh2ID09IE5VTEwpCisgICAgICAgICAgICAgICAgICAgIGdvdG8gb25FcnJvcjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIHNpZ24gPSAwOworICAgICAgICAgICAgZmlsbCA9ICcgJzsKKyAgICAgICAgICAgIHN3aXRjaCAoYykgeworCisgICAgICAgICAgICBjYXNlICclJzoKKyAgICAgICAgICAgICAgICBwYnVmID0gZm9ybWF0YnVmOworICAgICAgICAgICAgICAgIC8qIHByZXN1bWUgdGhhdCBidWZmZXIgbGVuZ3RoIGlzIGF0IGxlYXN0IDEgKi8KKyAgICAgICAgICAgICAgICBwYnVmWzBdID0gJyUnOworICAgICAgICAgICAgICAgIGxlbiA9IDE7CisgICAgICAgICAgICAgICAgYnJlYWs7CisKKyAgICAgICAgICAgIGNhc2UgJ3MnOgorICAgICAgICAgICAgY2FzZSAncic6CisgICAgICAgICAgICAgICAgaWYgKFB5VW5pY29kZV9DaGVja0V4YWN0KHYpICYmIGMgPT0gJ3MnKSB7CisgICAgICAgICAgICAgICAgICAgIHRlbXAgPSB2OworICAgICAgICAgICAgICAgICAgICBQeV9JTkNSRUYodGVtcCk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGVsc2UgeworICAgICAgICAgICAgICAgICAgICBQeU9iamVjdCAqdW5pY29kZTsKKyAgICAgICAgICAgICAgICAgICAgaWYgKGMgPT0gJ3MnKQorICAgICAgICAgICAgICAgICAgICAgICAgdGVtcCA9IFB5T2JqZWN0X1VuaWNvZGUodik7CisgICAgICAgICAgICAgICAgICAgIGVsc2UKKyAgICAgICAgICAgICAgICAgICAgICAgIHRlbXAgPSBQeU9iamVjdF9SZXByKHYpOworICAgICAgICAgICAgICAgICAgICBpZiAodGVtcCA9PSBOVUxMKQorICAgICAgICAgICAgICAgICAgICAgICAgZ290byBvbkVycm9yOworICAgICAgICAgICAgICAgICAgICBpZiAoUHlVbmljb2RlX0NoZWNrKHRlbXApKQorICAgICAgICAgICAgICAgICAgICAgICAgLyogbm90aGluZyB0byBkbyAqLzsKKyAgICAgICAgICAgICAgICAgICAgZWxzZSBpZiAoUHlTdHJpbmdfQ2hlY2sodGVtcCkpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgIC8qIGNvbnZlcnQgdG8gc3RyaW5nIHRvIFVuaWNvZGUgKi8KKyAgICAgICAgICAgICAgICAgICAgICAgIHVuaWNvZGUgPSBQeVVuaWNvZGVfRGVjb2RlKFB5U3RyaW5nX0FTX1NUUklORyh0ZW1wKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFB5U3RyaW5nX0dFVF9TSVpFKHRlbXApLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJzdHJpY3QiKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIFB5X0RFQ1JFRih0ZW1wKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIHRlbXAgPSB1bmljb2RlOworICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHRlbXAgPT0gTlVMTCkKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBnb3RvIG9uRXJyb3I7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgZWxzZSB7CisgICAgICAgICAgICAgICAgICAgICAgICBQeV9ERUNSRUYodGVtcCk7CisgICAgICAgICAgICAgICAgICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfVHlwZUVycm9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIlcyBhcmd1bWVudCBoYXMgbm9uLXN0cmluZyBzdHIoKSIpOworICAgICAgICAgICAgICAgICAgICAgICAgZ290byBvbkVycm9yOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHBidWYgPSBQeVVuaWNvZGVfQVNfVU5JQ09ERSh0ZW1wKTsKKyAgICAgICAgICAgICAgICBsZW4gPSBQeVVuaWNvZGVfR0VUX1NJWkUodGVtcCk7CisgICAgICAgICAgICAgICAgaWYgKHByZWMgPj0gMCAmJiBsZW4gPiBwcmVjKQorICAgICAgICAgICAgICAgICAgICBsZW4gPSBwcmVjOworICAgICAgICAgICAgICAgIGJyZWFrOworCisgICAgICAgICAgICBjYXNlICdpJzoKKyAgICAgICAgICAgIGNhc2UgJ2QnOgorICAgICAgICAgICAgY2FzZSAndSc6CisgICAgICAgICAgICBjYXNlICdvJzoKKyAgICAgICAgICAgIGNhc2UgJ3gnOgorICAgICAgICAgICAgY2FzZSAnWCc6CisgICAgICAgICAgICAgICAgaWYgKGMgPT0gJ2knKQorICAgICAgICAgICAgICAgICAgICBjID0gJ2QnOworICAgICAgICAgICAgICAgIGlzbnVtb2sgPSAwOworICAgICAgICAgICAgICAgIGlmIChQeU51bWJlcl9DaGVjayh2KSkgeworICAgICAgICAgICAgICAgICAgICBQeU9iamVjdCAqaW9iaj1OVUxMOworCisgICAgICAgICAgICAgICAgICAgIGlmIChQeUludF9DaGVjayh2KSB8fCAoUHlMb25nX0NoZWNrKHYpKSkgeworICAgICAgICAgICAgICAgICAgICAgICAgaW9iaiA9IHY7CisgICAgICAgICAgICAgICAgICAgICAgICBQeV9JTkNSRUYoaW9iaik7CisgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgZWxzZSB7CisgICAgICAgICAgICAgICAgICAgICAgICBpb2JqID0gUHlOdW1iZXJfSW50KHYpOworICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGlvYmo9PU5VTEwpIGlvYmogPSBQeU51bWJlcl9Mb25nKHYpOworICAgICAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgICAgIGlmIChpb2JqIT1OVUxMKSB7CisgICAgICAgICAgICAgICAgICAgICAgICBpZiAoUHlJbnRfQ2hlY2soaW9iaikpIHsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBpc251bW9rID0gMTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBwYnVmID0gZm9ybWF0YnVmOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxlbiA9IGZvcm1hdGludChwYnVmLCBzaXplb2YoZm9ybWF0YnVmKS9zaXplb2YoUHlfVU5JQ09ERSksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZsYWdzLCBwcmVjLCBjLCBpb2JqKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBQeV9ERUNSRUYoaW9iaik7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGxlbiA8IDApCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdvdG8gb25FcnJvcjsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaWduID0gMTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgaWYgKFB5TG9uZ19DaGVjayhpb2JqKSkgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzbnVtb2sgPSAxOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRlbXAgPSBmb3JtYXRsb25nKGlvYmosIGZsYWdzLCBwcmVjLCBjKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBQeV9ERUNSRUYoaW9iaik7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCF0ZW1wKQorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnb3RvIG9uRXJyb3I7CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGJ1ZiA9IFB5VW5pY29kZV9BU19VTklDT0RFKHRlbXApOworICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxlbiA9IFB5VW5pY29kZV9HRVRfU0laRSh0ZW1wKTsKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaWduID0gMTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgICAgIGVsc2UgeworICAgICAgICAgICAgICAgICAgICAgICAgICAgIFB5X0RFQ1JFRihpb2JqKTsKKyAgICAgICAgICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBpZiAoIWlzbnVtb2spIHsKKyAgICAgICAgICAgICAgICAgICAgUHlFcnJfRm9ybWF0KFB5RXhjX1R5cGVFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIlJSVjIGZvcm1hdDogYSBudW1iZXIgaXMgcmVxdWlyZWQsICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJub3QgJS4yMDBzIiwgKGNoYXIpYywgUHlfVFlQRSh2KS0+dHBfbmFtZSk7CisgICAgICAgICAgICAgICAgICAgIGdvdG8gb25FcnJvcjsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgaWYgKGZsYWdzICYgRl9aRVJPKQorICAgICAgICAgICAgICAgICAgICBmaWxsID0gJzAnOworICAgICAgICAgICAgICAgIGJyZWFrOworCisgICAgICAgICAgICBjYXNlICdlJzoKKyAgICAgICAgICAgIGNhc2UgJ0UnOgorICAgICAgICAgICAgY2FzZSAnZic6CisgICAgICAgICAgICBjYXNlICdGJzoKKyAgICAgICAgICAgIGNhc2UgJ2cnOgorICAgICAgICAgICAgY2FzZSAnRyc6CisgICAgICAgICAgICAgICAgdGVtcCA9IGZvcm1hdGZsb2F0KHYsIGZsYWdzLCBwcmVjLCBjKTsKKyAgICAgICAgICAgICAgICBpZiAodGVtcCA9PSBOVUxMKQorICAgICAgICAgICAgICAgICAgICBnb3RvIG9uRXJyb3I7CisgICAgICAgICAgICAgICAgcGJ1ZiA9IFB5VW5pY29kZV9BU19VTklDT0RFKHRlbXApOworICAgICAgICAgICAgICAgIGxlbiA9IFB5VW5pY29kZV9HRVRfU0laRSh0ZW1wKTsKKyAgICAgICAgICAgICAgICBzaWduID0gMTsKKyAgICAgICAgICAgICAgICBpZiAoZmxhZ3MgJiBGX1pFUk8pCisgICAgICAgICAgICAgICAgICAgIGZpbGwgPSAnMCc7CisgICAgICAgICAgICAgICAgYnJlYWs7CisKKyAgICAgICAgICAgIGNhc2UgJ2MnOgorICAgICAgICAgICAgICAgIHBidWYgPSBmb3JtYXRidWY7CisgICAgICAgICAgICAgICAgbGVuID0gZm9ybWF0Y2hhcihwYnVmLCBzaXplb2YoZm9ybWF0YnVmKS9zaXplb2YoUHlfVU5JQ09ERSksIHYpOworICAgICAgICAgICAgICAgIGlmIChsZW4gPCAwKQorICAgICAgICAgICAgICAgICAgICBnb3RvIG9uRXJyb3I7CisgICAgICAgICAgICAgICAgYnJlYWs7CisKKyAgICAgICAgICAgIGRlZmF1bHQ6CisgICAgICAgICAgICAgICAgUHlFcnJfRm9ybWF0KFB5RXhjX1ZhbHVlRXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ1bnN1cHBvcnRlZCBmb3JtYXQgY2hhcmFjdGVyICclYycgKDB4JXgpICIKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImF0IGluZGV4ICV6ZCIsCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICgzMTw9YyAmJiBjPD0xMjYpID8gKGNoYXIpYyA6ICc/JywKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGludCljLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoUHlfc3NpemVfdCkoZm10IC0gMSAtCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBQeVVuaWNvZGVfQVNfVU5JQ09ERSh1Zm9ybWF0KSkpOworICAgICAgICAgICAgICAgIGdvdG8gb25FcnJvcjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChzaWduKSB7CisgICAgICAgICAgICAgICAgaWYgKCpwYnVmID09ICctJyB8fCAqcGJ1ZiA9PSAnKycpIHsKKyAgICAgICAgICAgICAgICAgICAgc2lnbiA9ICpwYnVmKys7CisgICAgICAgICAgICAgICAgICAgIGxlbi0tOworICAgICAgICAgICAgICAgIH0KKyAgICAgICAgICAgICAgICBlbHNlIGlmIChmbGFncyAmIEZfU0lHTikKKyAgICAgICAgICAgICAgICAgICAgc2lnbiA9ICcrJzsKKyAgICAgICAgICAgICAgICBlbHNlIGlmIChmbGFncyAmIEZfQkxBTkspCisgICAgICAgICAgICAgICAgICAgIHNpZ24gPSAnICc7CisgICAgICAgICAgICAgICAgZWxzZQorICAgICAgICAgICAgICAgICAgICBzaWduID0gMDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmICh3aWR0aCA8IGxlbikKKyAgICAgICAgICAgICAgICB3aWR0aCA9IGxlbjsKKyAgICAgICAgICAgIGlmIChyZXNjbnQgLSAoc2lnbiAhPSAwKSA8IHdpZHRoKSB7CisgICAgICAgICAgICAgICAgcmVzbGVuIC09IHJlc2NudDsKKyAgICAgICAgICAgICAgICByZXNjbnQgPSB3aWR0aCArIGZtdGNudCArIDEwMDsKKyAgICAgICAgICAgICAgICByZXNsZW4gKz0gcmVzY250OworICAgICAgICAgICAgICAgIGlmIChyZXNsZW4gPCAwKSB7CisgICAgICAgICAgICAgICAgICAgIFB5X1hERUNSRUYodGVtcCk7CisgICAgICAgICAgICAgICAgICAgIFB5RXJyX05vTWVtb3J5KCk7CisgICAgICAgICAgICAgICAgICAgIGdvdG8gb25FcnJvcjsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgaWYgKF9QeVVuaWNvZGVfUmVzaXplKCZyZXN1bHQsIHJlc2xlbikgPCAwKSB7CisgICAgICAgICAgICAgICAgICAgIFB5X1hERUNSRUYodGVtcCk7CisgICAgICAgICAgICAgICAgICAgIGdvdG8gb25FcnJvcjsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgcmVzID0gUHlVbmljb2RlX0FTX1VOSUNPREUocmVzdWx0KQorICAgICAgICAgICAgICAgICAgICArIHJlc2xlbiAtIHJlc2NudDsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmIChzaWduKSB7CisgICAgICAgICAgICAgICAgaWYgKGZpbGwgIT0gJyAnKQorICAgICAgICAgICAgICAgICAgICAqcmVzKysgPSBzaWduOworICAgICAgICAgICAgICAgIHJlc2NudC0tOworICAgICAgICAgICAgICAgIGlmICh3aWR0aCA+IGxlbikKKyAgICAgICAgICAgICAgICAgICAgd2lkdGgtLTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGlmICgoZmxhZ3MgJiBGX0FMVCkgJiYgKGMgPT0gJ3gnIHx8IGMgPT0gJ1gnKSkgeworICAgICAgICAgICAgICAgIGFzc2VydChwYnVmWzBdID09ICcwJyk7CisgICAgICAgICAgICAgICAgYXNzZXJ0KHBidWZbMV0gPT0gYyk7CisgICAgICAgICAgICAgICAgaWYgKGZpbGwgIT0gJyAnKSB7CisgICAgICAgICAgICAgICAgICAgICpyZXMrKyA9ICpwYnVmKys7CisgICAgICAgICAgICAgICAgICAgICpyZXMrKyA9ICpwYnVmKys7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIHJlc2NudCAtPSAyOworICAgICAgICAgICAgICAgIHdpZHRoIC09IDI7CisgICAgICAgICAgICAgICAgaWYgKHdpZHRoIDwgMCkKKyAgICAgICAgICAgICAgICAgICAgd2lkdGggPSAwOworICAgICAgICAgICAgICAgIGxlbiAtPSAyOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKHdpZHRoID4gbGVuICYmICEoZmxhZ3MgJiBGX0xKVVNUKSkgeworICAgICAgICAgICAgICAgIGRvIHsKKyAgICAgICAgICAgICAgICAgICAgLS1yZXNjbnQ7CisgICAgICAgICAgICAgICAgICAgICpyZXMrKyA9IGZpbGw7CisgICAgICAgICAgICAgICAgfSB3aGlsZSAoLS13aWR0aCA+IGxlbik7CisgICAgICAgICAgICB9CisgICAgICAgICAgICBpZiAoZmlsbCA9PSAnICcpIHsKKyAgICAgICAgICAgICAgICBpZiAoc2lnbikKKyAgICAgICAgICAgICAgICAgICAgKnJlcysrID0gc2lnbjsKKyAgICAgICAgICAgICAgICBpZiAoKGZsYWdzICYgRl9BTFQpICYmIChjID09ICd4JyB8fCBjID09ICdYJykpIHsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0KHBidWZbMF0gPT0gJzAnKTsKKyAgICAgICAgICAgICAgICAgICAgYXNzZXJ0KHBidWZbMV0gPT0gYyk7CisgICAgICAgICAgICAgICAgICAgICpyZXMrKyA9ICpwYnVmKys7CisgICAgICAgICAgICAgICAgICAgICpyZXMrKyA9ICpwYnVmKys7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgUHlfVU5JQ09ERV9DT1BZKHJlcywgcGJ1ZiwgbGVuKTsKKyAgICAgICAgICAgIHJlcyArPSBsZW47CisgICAgICAgICAgICByZXNjbnQgLT0gbGVuOworICAgICAgICAgICAgd2hpbGUgKC0td2lkdGggPj0gbGVuKSB7CisgICAgICAgICAgICAgICAgLS1yZXNjbnQ7CisgICAgICAgICAgICAgICAgKnJlcysrID0gJyAnOworICAgICAgICAgICAgfQorICAgICAgICAgICAgaWYgKGRpY3QgJiYgKGFyZ2lkeCA8IGFyZ2xlbikgJiYgYyAhPSAnJScpIHsKKyAgICAgICAgICAgICAgICBQeUVycl9TZXRTdHJpbmcoUHlFeGNfVHlwZUVycm9yLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAibm90IGFsbCBhcmd1bWVudHMgY29udmVydGVkIGR1cmluZyBzdHJpbmcgZm9ybWF0dGluZyIpOworICAgICAgICAgICAgICAgIFB5X1hERUNSRUYodGVtcCk7CisgICAgICAgICAgICAgICAgZ290byBvbkVycm9yOworICAgICAgICAgICAgfQorICAgICAgICAgICAgUHlfWERFQ1JFRih0ZW1wKTsKKyAgICAgICAgfSAvKiAnJScgKi8KKyAgICB9IC8qIHVudGlsIGVuZCAqLworICAgIGlmIChhcmdpZHggPCBhcmdsZW4gJiYgIWRpY3QpIHsKKyAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1R5cGVFcnJvciwKKyAgICAgICAgICAgICAgICAgICAgICAgICJub3QgYWxsIGFyZ3VtZW50cyBjb252ZXJ0ZWQgZHVyaW5nIHN0cmluZyBmb3JtYXR0aW5nIik7CisgICAgICAgIGdvdG8gb25FcnJvcjsKKyAgICB9CisKKyAgICBpZiAoX1B5VW5pY29kZV9SZXNpemUoJnJlc3VsdCwgcmVzbGVuIC0gcmVzY250KSA8IDApCisgICAgICAgIGdvdG8gb25FcnJvcjsKKyAgICBpZiAoYXJnc19vd25lZCkgeworICAgICAgICBQeV9ERUNSRUYoYXJncyk7CisgICAgfQorICAgIFB5X0RFQ1JFRih1Zm9ybWF0KTsKKyAgICByZXR1cm4gKFB5T2JqZWN0ICopcmVzdWx0OworCisgIG9uRXJyb3I6CisgICAgUHlfWERFQ1JFRihyZXN1bHQpOworICAgIFB5X0RFQ1JFRih1Zm9ybWF0KTsKKyAgICBpZiAoYXJnc19vd25lZCkgeworICAgICAgICBQeV9ERUNSRUYoYXJncyk7CisgICAgfQorICAgIHJldHVybiBOVUxMOworfQorCitzdGF0aWMgUHlCdWZmZXJQcm9jcyB1bmljb2RlX2FzX2J1ZmZlciA9IHsKKyAgICAocmVhZGJ1ZmZlcnByb2MpIHVuaWNvZGVfYnVmZmVyX2dldHJlYWRidWYsCisgICAgKHdyaXRlYnVmZmVycHJvYykgdW5pY29kZV9idWZmZXJfZ2V0d3JpdGVidWYsCisgICAgKHNlZ2NvdW50cHJvYykgdW5pY29kZV9idWZmZXJfZ2V0c2VnY291bnQsCisgICAgKGNoYXJidWZmZXJwcm9jKSB1bmljb2RlX2J1ZmZlcl9nZXRjaGFyYnVmLAorfTsKKworc3RhdGljIFB5T2JqZWN0ICoKK3VuaWNvZGVfc3VidHlwZV9uZXcoUHlUeXBlT2JqZWN0ICp0eXBlLCBQeU9iamVjdCAqYXJncywgUHlPYmplY3QgKmt3ZHMpOworCitzdGF0aWMgUHlPYmplY3QgKgordW5pY29kZV9uZXcoUHlUeXBlT2JqZWN0ICp0eXBlLCBQeU9iamVjdCAqYXJncywgUHlPYmplY3QgKmt3ZHMpCit7CisgICAgUHlPYmplY3QgKnggPSBOVUxMOworICAgIHN0YXRpYyBjaGFyICprd2xpc3RbXSA9IHsic3RyaW5nIiwgImVuY29kaW5nIiwgImVycm9ycyIsIDB9OworICAgIGNoYXIgKmVuY29kaW5nID0gTlVMTDsKKyAgICBjaGFyICplcnJvcnMgPSBOVUxMOworCisgICAgaWYgKHR5cGUgIT0gJlB5VW5pY29kZV9UeXBlKQorICAgICAgICByZXR1cm4gdW5pY29kZV9zdWJ0eXBlX25ldyh0eXBlLCBhcmdzLCBrd2RzKTsKKyAgICBpZiAoIVB5QXJnX1BhcnNlVHVwbGVBbmRLZXl3b3JkcyhhcmdzLCBrd2RzLCAifE9zczp1bmljb2RlIiwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBrd2xpc3QsICZ4LCAmZW5jb2RpbmcsICZlcnJvcnMpKQorICAgICAgICByZXR1cm4gTlVMTDsKKyAgICBpZiAoeCA9PSBOVUxMKQorICAgICAgICByZXR1cm4gKFB5T2JqZWN0ICopX1B5VW5pY29kZV9OZXcoMCk7CisgICAgaWYgKGVuY29kaW5nID09IE5VTEwgJiYgZXJyb3JzID09IE5VTEwpCisgICAgICAgIHJldHVybiBQeU9iamVjdF9Vbmljb2RlKHgpOworICAgIGVsc2UKKyAgICAgICAgcmV0dXJuIFB5VW5pY29kZV9Gcm9tRW5jb2RlZE9iamVjdCh4LCBlbmNvZGluZywgZXJyb3JzKTsKK30KKworc3RhdGljIFB5T2JqZWN0ICoKK3VuaWNvZGVfc3VidHlwZV9uZXcoUHlUeXBlT2JqZWN0ICp0eXBlLCBQeU9iamVjdCAqYXJncywgUHlPYmplY3QgKmt3ZHMpCit7CisgICAgUHlVbmljb2RlT2JqZWN0ICp0bXAsICpwbmV3OworICAgIFB5X3NzaXplX3QgbjsKKworICAgIGFzc2VydChQeVR5cGVfSXNTdWJ0eXBlKHR5cGUsICZQeVVuaWNvZGVfVHlwZSkpOworICAgIHRtcCA9IChQeVVuaWNvZGVPYmplY3QgKil1bmljb2RlX25ldygmUHlVbmljb2RlX1R5cGUsIGFyZ3MsIGt3ZHMpOworICAgIGlmICh0bXAgPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgYXNzZXJ0KFB5VW5pY29kZV9DaGVjayh0bXApKTsKKyAgICBwbmV3ID0gKFB5VW5pY29kZU9iamVjdCAqKSB0eXBlLT50cF9hbGxvYyh0eXBlLCBuID0gdG1wLT5sZW5ndGgpOworICAgIGlmIChwbmV3ID09IE5VTEwpIHsKKyAgICAgICAgUHlfREVDUkVGKHRtcCk7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICBwbmV3LT5zdHIgPSAoUHlfVU5JQ09ERSopIFB5T2JqZWN0X01BTExPQyhzaXplb2YoUHlfVU5JQ09ERSkgKiAobisxKSk7CisgICAgaWYgKHBuZXctPnN0ciA9PSBOVUxMKSB7CisgICAgICAgIF9QeV9Gb3JnZXRSZWZlcmVuY2UoKFB5T2JqZWN0ICopcG5ldyk7CisgICAgICAgIFB5T2JqZWN0X0RlbChwbmV3KTsKKyAgICAgICAgUHlfREVDUkVGKHRtcCk7CisgICAgICAgIHJldHVybiBQeUVycl9Ob01lbW9yeSgpOworICAgIH0KKyAgICBQeV9VTklDT0RFX0NPUFkocG5ldy0+c3RyLCB0bXAtPnN0ciwgbisxKTsKKyAgICBwbmV3LT5sZW5ndGggPSBuOworICAgIHBuZXctPmhhc2ggPSB0bXAtPmhhc2g7CisgICAgUHlfREVDUkVGKHRtcCk7CisgICAgcmV0dXJuIChQeU9iamVjdCAqKXBuZXc7Cit9CisKK1B5RG9jX1NUUlZBUih1bmljb2RlX2RvYywKKyAgICAgICAgICAgICAidW5pY29kZShvYmplY3Q9JycpIC0+IHVuaWNvZGUgb2JqZWN0XG5cCit1bmljb2RlKHN0cmluZ1ssIGVuY29kaW5nWywgZXJyb3JzXV0pIC0+IHVuaWNvZGUgb2JqZWN0XG5cCitcblwKK0NyZWF0ZSBhIG5ldyBVbmljb2RlIG9iamVjdCBmcm9tIHRoZSBnaXZlbiBlbmNvZGVkIHN0cmluZy5cblwKK2VuY29kaW5nIGRlZmF1bHRzIHRvIHRoZSBjdXJyZW50IGRlZmF1bHQgc3RyaW5nIGVuY29kaW5nLlxuXAorZXJyb3JzIGNhbiBiZSAnc3RyaWN0JywgJ3JlcGxhY2UnIG9yICdpZ25vcmUnIGFuZCBkZWZhdWx0cyB0byAnc3RyaWN0Jy4iKTsKKworUHlUeXBlT2JqZWN0IFB5VW5pY29kZV9UeXBlID0geworICAgIFB5VmFyT2JqZWN0X0hFQURfSU5JVCgmUHlUeXBlX1R5cGUsIDApCisgICAgInVuaWNvZGUiLCAgICAgICAgICAgICAgLyogdHBfbmFtZSAqLworICAgIHNpemVvZihQeVVuaWNvZGVPYmplY3QpLCAgICAgICAgLyogdHBfc2l6ZSAqLworICAgIDAsICAgICAgICAgICAgICAgICAgLyogdHBfaXRlbXNpemUgKi8KKyAgICAvKiBTbG90cyAqLworICAgIChkZXN0cnVjdG9yKXVuaWNvZGVfZGVhbGxvYywgICAgLyogdHBfZGVhbGxvYyAqLworICAgIDAsICAgICAgICAgICAgICAgICAgLyogdHBfcHJpbnQgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgIC8qIHRwX2dldGF0dHIgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgIC8qIHRwX3NldGF0dHIgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgIC8qIHRwX2NvbXBhcmUgKi8KKyAgICB1bmljb2RlX3JlcHIsICAgICAgICAgICAvKiB0cF9yZXByICovCisgICAgJnVuaWNvZGVfYXNfbnVtYmVyLCAgICAgICAgIC8qIHRwX2FzX251bWJlciAqLworICAgICZ1bmljb2RlX2FzX3NlcXVlbmNlLCAgICAgICAvKiB0cF9hc19zZXF1ZW5jZSAqLworICAgICZ1bmljb2RlX2FzX21hcHBpbmcsICAgICAgICAvKiB0cF9hc19tYXBwaW5nICovCisgICAgKGhhc2hmdW5jKSB1bmljb2RlX2hhc2gsICAgICAgICAvKiB0cF9oYXNoKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgIC8qIHRwX2NhbGwqLworICAgIChyZXByZnVuYykgdW5pY29kZV9zdHIsICAgICAvKiB0cF9zdHIgKi8KKyAgICBQeU9iamVjdF9HZW5lcmljR2V0QXR0ciwgICAgICAgIC8qIHRwX2dldGF0dHJvICovCisgICAgMCwgICAgICAgICAgICAgICAgICAvKiB0cF9zZXRhdHRybyAqLworICAgICZ1bmljb2RlX2FzX2J1ZmZlciwgICAgICAgICAvKiB0cF9hc19idWZmZXIgKi8KKyAgICBQeV9UUEZMQUdTX0RFRkFVTFQgfCBQeV9UUEZMQUdTX0NIRUNLVFlQRVMgfAorICAgIFB5X1RQRkxBR1NfQkFTRVRZUEUgfCBQeV9UUEZMQUdTX1VOSUNPREVfU1VCQ0xBU1MsICAvKiB0cF9mbGFncyAqLworICAgIHVuaWNvZGVfZG9jLCAgICAgICAgICAgIC8qIHRwX2RvYyAqLworICAgIDAsICAgICAgICAgICAgICAgICAgLyogdHBfdHJhdmVyc2UgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgIC8qIHRwX2NsZWFyICovCisgICAgUHlVbmljb2RlX1JpY2hDb21wYXJlLCAgICAgIC8qIHRwX3JpY2hjb21wYXJlICovCisgICAgMCwgICAgICAgICAgICAgICAgICAvKiB0cF93ZWFrbGlzdG9mZnNldCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgLyogdHBfaXRlciAqLworICAgIDAsICAgICAgICAgICAgICAgICAgLyogdHBfaXRlcm5leHQgKi8KKyAgICB1bmljb2RlX21ldGhvZHMsICAgICAgICAgICAgLyogdHBfbWV0aG9kcyAqLworICAgIDAsICAgICAgICAgICAgICAgICAgLyogdHBfbWVtYmVycyAqLworICAgIDAsICAgICAgICAgICAgICAgICAgLyogdHBfZ2V0c2V0ICovCisgICAgJlB5QmFzZVN0cmluZ19UeXBlLCAgICAgICAgIC8qIHRwX2Jhc2UgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgIC8qIHRwX2RpY3QgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgIC8qIHRwX2Rlc2NyX2dldCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgLyogdHBfZGVzY3Jfc2V0ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAvKiB0cF9kaWN0b2Zmc2V0ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAvKiB0cF9pbml0ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAvKiB0cF9hbGxvYyAqLworICAgIHVuaWNvZGVfbmV3LCAgICAgICAgICAgIC8qIHRwX25ldyAqLworICAgIFB5T2JqZWN0X0RlbCwgICAgICAgICAgIC8qIHRwX2ZyZWUgKi8KK307CisKKy8qIEluaXRpYWxpemUgdGhlIFVuaWNvZGUgaW1wbGVtZW50YXRpb24gKi8KKwordm9pZCBfUHlVbmljb2RlX0luaXQodm9pZCkKK3sKKyAgICAvKiBYWFggLSBtb3ZlIHRoaXMgYXJyYXkgdG8gdW5pY29kZWN0eXBlLmMgPyAqLworICAgIFB5X1VOSUNPREUgbGluZWJyZWFrW10gPSB7CisgICAgICAgIDB4MDAwQSwgLyogTElORSBGRUVEICovCisgICAgICAgIDB4MDAwRCwgLyogQ0FSUklBR0UgUkVUVVJOICovCisgICAgICAgIDB4MDAxQywgLyogRklMRSBTRVBBUkFUT1IgKi8KKyAgICAgICAgMHgwMDFELCAvKiBHUk9VUCBTRVBBUkFUT1IgKi8KKyAgICAgICAgMHgwMDFFLCAvKiBSRUNPUkQgU0VQQVJBVE9SICovCisgICAgICAgIDB4MDA4NSwgLyogTkVYVCBMSU5FICovCisgICAgICAgIDB4MjAyOCwgLyogTElORSBTRVBBUkFUT1IgKi8KKyAgICAgICAgMHgyMDI5LCAvKiBQQVJBR1JBUEggU0VQQVJBVE9SICovCisgICAgfTsKKworICAgIC8qIEluaXQgdGhlIGltcGxlbWVudGF0aW9uICovCisgICAgaWYgKCF1bmljb2RlX2VtcHR5KSB7CisgICAgICAgIHVuaWNvZGVfZW1wdHkgPSBfUHlVbmljb2RlX05ldygwKTsKKyAgICAgICAgaWYgKCF1bmljb2RlX2VtcHR5KQorICAgICAgICAgICAgcmV0dXJuOworICAgIH0KKworICAgIGlmIChQeVR5cGVfUmVhZHkoJlB5VW5pY29kZV9UeXBlKSA8IDApCisgICAgICAgIFB5X0ZhdGFsRXJyb3IoIkNhbid0IGluaXRpYWxpemUgJ3VuaWNvZGUnIik7CisKKyAgICAvKiBpbml0aWFsaXplIHRoZSBsaW5lYnJlYWsgYmxvb20gZmlsdGVyICovCisgICAgYmxvb21fbGluZWJyZWFrID0gbWFrZV9ibG9vbV9tYXNrKAorICAgICAgICBsaW5lYnJlYWssIHNpemVvZihsaW5lYnJlYWspIC8gc2l6ZW9mKGxpbmVicmVha1swXSkKKyAgICAgICAgKTsKKworICAgIFB5VHlwZV9SZWFkeSgmRW5jb2RpbmdNYXBUeXBlKTsKKworICAgIGlmIChQeVR5cGVfUmVhZHkoJlB5RmllbGROYW1lSXRlcl9UeXBlKSA8IDApCisgICAgICAgIFB5X0ZhdGFsRXJyb3IoIkNhbid0IGluaXRpYWxpemUgZmllbGQgbmFtZSBpdGVyYXRvciB0eXBlIik7CisKKyAgICBpZiAoUHlUeXBlX1JlYWR5KCZQeUZvcm1hdHRlckl0ZXJfVHlwZSkgPCAwKQorICAgICAgICBQeV9GYXRhbEVycm9yKCJDYW4ndCBpbml0aWFsaXplIGZvcm1hdHRlciBpdGVyIHR5cGUiKTsKK30KKworLyogRmluYWxpemUgdGhlIFVuaWNvZGUgaW1wbGVtZW50YXRpb24gKi8KKworaW50CitQeVVuaWNvZGVfQ2xlYXJGcmVlTGlzdCh2b2lkKQoreworICAgIGludCBmcmVlbGlzdF9zaXplID0gbnVtZnJlZTsKKyAgICBQeVVuaWNvZGVPYmplY3QgKnU7CisKKyAgICBmb3IgKHUgPSBmcmVlX2xpc3Q7IHUgIT0gTlVMTDspIHsKKyAgICAgICAgUHlVbmljb2RlT2JqZWN0ICp2ID0gdTsKKyAgICAgICAgdSA9ICooUHlVbmljb2RlT2JqZWN0ICoqKXU7CisgICAgICAgIGlmICh2LT5zdHIpCisgICAgICAgICAgICBQeU9iamVjdF9ERUwodi0+c3RyKTsKKyAgICAgICAgUHlfWERFQ1JFRih2LT5kZWZlbmMpOworICAgICAgICBQeU9iamVjdF9EZWwodik7CisgICAgICAgIG51bWZyZWUtLTsKKyAgICB9CisgICAgZnJlZV9saXN0ID0gTlVMTDsKKyAgICBhc3NlcnQobnVtZnJlZSA9PSAwKTsKKyAgICByZXR1cm4gZnJlZWxpc3Rfc2l6ZTsKK30KKwordm9pZAorX1B5VW5pY29kZV9GaW5pKHZvaWQpCit7CisgICAgaW50IGk7CisKKyAgICBQeV9DTEVBUih1bmljb2RlX2VtcHR5KTsKKworICAgIGZvciAoaSA9IDA7IGkgPCAyNTY7IGkrKykKKyAgICAgICAgUHlfQ0xFQVIodW5pY29kZV9sYXRpbjFbaV0pOworCisgICAgKHZvaWQpUHlVbmljb2RlX0NsZWFyRnJlZUxpc3QoKTsKK30KKworI2lmZGVmIF9fY3BsdXNwbHVzCit9CisjZW5kaWYKZGlmZiAtLWdpdCBhL1B5dGhvbi0yLjcuNS9PYmplY3RzL3VuaWNvZGV0eXBlX2RiLmggYi9QeXRob24tMi43LjUvT2JqZWN0cy91bmljb2RldHlwZV9kYi5oCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmQyZWM0NmIKLS0tIC9kZXYvbnVsbAorKysgYi9QeXRob24tMi43LjUvT2JqZWN0cy91bmljb2RldHlwZV9kYi5oCkBAIC0wLDAgKzEsMzMzNyBAQAorLyogdGhpcyBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgVG9vbHMvdW5pY29kZS9tYWtldW5pY29kZWRhdGEucHkgMi42ICovCisKKy8qIGEgbGlzdCBvZiB1bmlxdWUgY2hhcmFjdGVyIHR5cGUgZGVzY3JpcHRvcnMgKi8KK2NvbnN0IF9QeVVuaWNvZGVfVHlwZVJlY29yZCBfUHlVbmljb2RlX1R5cGVSZWNvcmRzW10gPSB7CisgICAgezAsIDAsIDAsIDAsIDAsIDB9LAorICAgIHswLCAwLCAwLCAwLCAwLCAwfSwKKyAgICB7MCwgMCwgMCwgMCwgMCwgMzJ9LAorICAgIHswLCAwLCAwLCAwLCAwLCA0OH0sCisgICAgezAsIDAsIDAsIDAsIDAsIDUxOH0sCisgICAgezAsIDAsIDAsIDEsIDEsIDUxOH0sCisgICAgezAsIDAsIDAsIDIsIDIsIDUxOH0sCisgICAgezAsIDAsIDAsIDMsIDMsIDUxOH0sCisgICAgezAsIDAsIDAsIDQsIDQsIDUxOH0sCisgICAgezAsIDAsIDAsIDUsIDUsIDUxOH0sCisgICAgezAsIDAsIDAsIDYsIDYsIDUxOH0sCisgICAgezAsIDAsIDAsIDcsIDcsIDUxOH0sCisgICAgezAsIDAsIDAsIDgsIDgsIDUxOH0sCisgICAgezAsIDAsIDAsIDksIDksIDUxOH0sCisgICAgezAsIDMyLCAwLCAwLCAwLCAxMjl9LAorICAgIHs2NTUwNCwgMCwgNjU1MDQsIDAsIDAsIDl9LAorICAgIHswLCAwLCAwLCAwLCAwLCA5fSwKKyAgICB7MCwgMCwgMCwgMCwgMiwgNTE2fSwKKyAgICB7MCwgMCwgMCwgMCwgMywgNTE2fSwKKyAgICB7NzQzLCAwLCA3NDMsIDAsIDAsIDl9LAorICAgIHswLCAwLCAwLCAwLCAxLCA1MTZ9LAorICAgIHswLCAwLCAwLCAwLCAwLCA1MTJ9LAorICAgIHsxMjEsIDAsIDEyMSwgMCwgMCwgOX0sCisgICAgezAsIDEsIDAsIDAsIDAsIDEyOX0sCisgICAgezY1NTM1LCAwLCA2NTUzNSwgMCwgMCwgOX0sCisgICAgezAsIDY1MzM3LCAwLCAwLCAwLCAxMjl9LAorICAgIHs2NTMwNCwgMCwgNjUzMDQsIDAsIDAsIDl9LAorICAgIHswLCA2NTQxNSwgMCwgMCwgMCwgMTI5fSwKKyAgICB7NjUyMzYsIDAsIDY1MjM2LCAwLCAwLCA5fSwKKyAgICB7MTk1LCAwLCAxOTUsIDAsIDAsIDl9LAorICAgIHswLCAyMTAsIDAsIDAsIDAsIDEyOX0sCisgICAgezAsIDIwNiwgMCwgMCwgMCwgMTI5fSwKKyAgICB7MCwgMjA1LCAwLCAwLCAwLCAxMjl9LAorICAgIHswLCA3OSwgMCwgMCwgMCwgMTI5fSwKKyAgICB7MCwgMjAyLCAwLCAwLCAwLCAxMjl9LAorICAgIHswLCAyMDMsIDAsIDAsIDAsIDEyOX0sCisgICAgezAsIDIwNywgMCwgMCwgMCwgMTI5fSwKKyAgICB7OTcsIDAsIDk3LCAwLCAwLCA5fSwKKyAgICB7MCwgMjExLCAwLCAwLCAwLCAxMjl9LAorICAgIHswLCAyMDksIDAsIDAsIDAsIDEyOX0sCisgICAgezE2MywgMCwgMTYzLCAwLCAwLCA5fSwKKyAgICB7MCwgMjEzLCAwLCAwLCAwLCAxMjl9LAorICAgIHsxMzAsIDAsIDEzMCwgMCwgMCwgOX0sCisgICAgezAsIDIxNCwgMCwgMCwgMCwgMTI5fSwKKyAgICB7MCwgMjE4LCAwLCAwLCAwLCAxMjl9LAorICAgIHswLCAyMTcsIDAsIDAsIDAsIDEyOX0sCisgICAgezAsIDIxOSwgMCwgMCwgMCwgMTI5fSwKKyAgICB7MCwgMCwgMCwgMCwgMCwgMX0sCisgICAgezU2LCAwLCA1NiwgMCwgMCwgOX0sCisgICAgezAsIDIsIDEsIDAsIDAsIDEyOX0sCisgICAgezY1NTM1LCAxLCAwLCAwLCAwLCA2NX0sCisgICAgezY1NTM0LCAwLCA2NTUzNSwgMCwgMCwgOX0sCisgICAgezY1NDU3LCAwLCA2NTQ1NywgMCwgMCwgOX0sCisgICAgezAsIDY1NDM5LCAwLCAwLCAwLCAxMjl9LAorICAgIHswLCA2NTQ4MCwgMCwgMCwgMCwgMTI5fSwKKyAgICB7MCwgNjU0MDYsIDAsIDAsIDAsIDEyOX0sCisgICAgezAsIDEwNzk1LCAwLCAwLCAwLCAxMjl9LAorICAgIHswLCA2NTM3MywgMCwgMCwgMCwgMTI5fSwKKyAgICB7MCwgMTA3OTIsIDAsIDAsIDAsIDEyOX0sCisgICAgezEwODE1LCAwLCAxMDgxNSwgMCwgMCwgOX0sCisgICAgezAsIDY1MzQxLCAwLCAwLCAwLCAxMjl9LAorICAgIHswLCA2OSwgMCwgMCwgMCwgMTI5fSwKKyAgICB7MCwgNzEsIDAsIDAsIDAsIDEyOX0sCisgICAgezEwNzgzLCAwLCAxMDc4MywgMCwgMCwgOX0sCisgICAgezEwNzgwLCAwLCAxMDc4MCwgMCwgMCwgOX0sCisgICAgezEwNzgyLCAwLCAxMDc4MiwgMCwgMCwgOX0sCisgICAgezY1MzI2LCAwLCA2NTMyNiwgMCwgMCwgOX0sCisgICAgezY1MzMwLCAwLCA2NTMzMCwgMCwgMCwgOX0sCisgICAgezY1MzMxLCAwLCA2NTMzMSwgMCwgMCwgOX0sCisgICAgezY1MzM0LCAwLCA2NTMzNCwgMCwgMCwgOX0sCisgICAgezY1MzMzLCAwLCA2NTMzMywgMCwgMCwgOX0sCisgICAgezY1MzI5LCAwLCA2NTMyOSwgMCwgMCwgOX0sCisgICAgezY1MzI3LCAwLCA2NTMyNywgMCwgMCwgOX0sCisgICAgezY1MzI1LCAwLCA2NTMyNSwgMCwgMCwgOX0sCisgICAgezEwNzQzLCAwLCAxMDc0MywgMCwgMCwgOX0sCisgICAgezEwNzQ5LCAwLCAxMDc0OSwgMCwgMCwgOX0sCisgICAgezY1MzIzLCAwLCA2NTMyMywgMCwgMCwgOX0sCisgICAgezY1MzIyLCAwLCA2NTMyMiwgMCwgMCwgOX0sCisgICAgezEwNzI3LCAwLCAxMDcyNywgMCwgMCwgOX0sCisgICAgezY1MzE4LCAwLCA2NTMxOCwgMCwgMCwgOX0sCisgICAgezY1NDY3LCAwLCA2NTQ2NywgMCwgMCwgOX0sCisgICAgezY1MzE5LCAwLCA2NTMxOSwgMCwgMCwgOX0sCisgICAgezY1NDY1LCAwLCA2NTQ2NSwgMCwgMCwgOX0sCisgICAgezY1MzE3LCAwLCA2NTMxNywgMCwgMCwgOX0sCisgICAgezg0LCAwLCA4NCwgMCwgMCwgMH0sCisgICAgezAsIDM4LCAwLCAwLCAwLCAxMjl9LAorICAgIHswLCAzNywgMCwgMCwgMCwgMTI5fSwKKyAgICB7MCwgNjQsIDAsIDAsIDAsIDEyOX0sCisgICAgezAsIDYzLCAwLCAwLCAwLCAxMjl9LAorICAgIHs2NTQ5OCwgMCwgNjU0OTgsIDAsIDAsIDl9LAorICAgIHs2NTQ5OSwgMCwgNjU0OTksIDAsIDAsIDl9LAorICAgIHs2NTUwNSwgMCwgNjU1MDUsIDAsIDAsIDl9LAorICAgIHs2NTQ3MiwgMCwgNjU0NzIsIDAsIDAsIDl9LAorICAgIHs2NTQ3MywgMCwgNjU0NzMsIDAsIDAsIDl9LAorICAgIHswLCA4LCAwLCAwLCAwLCAxMjl9LAorICAgIHs2NTQ3NCwgMCwgNjU0NzQsIDAsIDAsIDl9LAorICAgIHs2NTQ3OSwgMCwgNjU0NzksIDAsIDAsIDl9LAorICAgIHswLCAwLCAwLCAwLCAwLCAxMjl9LAorICAgIHs2NTQ4OSwgMCwgNjU0ODksIDAsIDAsIDl9LAorICAgIHs2NTQ4MiwgMCwgNjU0ODIsIDAsIDAsIDl9LAorICAgIHs2NTUyOCwgMCwgNjU1MjgsIDAsIDAsIDl9LAorICAgIHs2NTQ1MCwgMCwgNjU0NTAsIDAsIDAsIDl9LAorICAgIHs2NTQ1NiwgMCwgNjU0NTYsIDAsIDAsIDl9LAorICAgIHs3LCAwLCA3LCAwLCAwLCA5fSwKKyAgICB7MCwgNjU0NzYsIDAsIDAsIDAsIDEyOX0sCisgICAgezY1NDQwLCAwLCA2NTQ0MCwgMCwgMCwgOX0sCisgICAgezAsIDY1NTI5LCAwLCAwLCAwLCAxMjl9LAorICAgIHswLCA4MCwgMCwgMCwgMCwgMTI5fSwKKyAgICB7MCwgMTUsIDAsIDAsIDAsIDEyOX0sCisgICAgezY1NTIxLCAwLCA2NTUyMSwgMCwgMCwgOX0sCisgICAgezAsIDQ4LCAwLCAwLCAwLCAxMjl9LAorICAgIHs2NTQ4OCwgMCwgNjU0ODgsIDAsIDAsIDl9LAorICAgIHswLCA3MjY0LCAwLCAwLCAwLCAxMjl9LAorICAgIHswLCAwLCAwLCAwLCA0LCA1MTZ9LAorICAgIHswLCAwLCAwLCAwLCA1LCA1MTZ9LAorICAgIHswLCAwLCAwLCAwLCA2LCA1MTZ9LAorICAgIHswLCAwLCAwLCAwLCA3LCA1MTZ9LAorICAgIHswLCAwLCAwLCAwLCA4LCA1MTZ9LAorICAgIHswLCAwLCAwLCAwLCA5LCA1MTZ9LAorICAgIHs0Mjg3NywgNzU0NSwgNDI4NzcsIDAsIDAsIDI2NX0sCisgICAgezM4MTQsIDAsIDM4MTQsIDAsIDAsIDl9LAorICAgIHs2NTQ3NywgMCwgNjU0NzcsIDAsIDAsIDl9LAorICAgIHswLCA1NzkyMSwgMCwgMCwgMCwgMTI5fSwKKyAgICB7OCwgMCwgOCwgMCwgMCwgOX0sCisgICAgezAsIDY1NTI4LCAwLCAwLCAwLCAxMjl9LAorICAgIHs3NCwgMCwgNzQsIDAsIDAsIDl9LAorICAgIHs4NiwgMCwgODYsIDAsIDAsIDl9LAorICAgIHsxMDAsIDAsIDEwMCwgMCwgMCwgOX0sCisgICAgezEyOCwgMCwgMTI4LCAwLCAwLCA5fSwKKyAgICB7MTEyLCAwLCAxMTIsIDAsIDAsIDl9LAorICAgIHsxMjYsIDAsIDEyNiwgMCwgMCwgOX0sCisgICAgezAsIDY1NTI4LCAwLCAwLCAwLCA2NX0sCisgICAgezksIDAsIDksIDAsIDAsIDl9LAorICAgIHswLCA2NTQ2MiwgMCwgMCwgMCwgMTI5fSwKKyAgICB7MCwgNjU1MjcsIDAsIDAsIDAsIDY1fSwKKyAgICB7NTgzMzEsIDAsIDU4MzMxLCAwLCAwLCA5fSwKKyAgICB7MCwgNjU0NTAsIDAsIDAsIDAsIDEyOX0sCisgICAgezAsIDY1NDM2LCAwLCAwLCAwLCAxMjl9LAorICAgIHswLCA2NTQyNCwgMCwgMCwgMCwgMTI5fSwKKyAgICB7MCwgNjU0MDgsIDAsIDAsIDAsIDEyOX0sCisgICAgezAsIDY1NDEwLCAwLCAwLCAwLCAxMjl9LAorICAgIHswLCAwLCAwLCAwLCAwLCA1MTZ9LAorICAgIHswLCA1ODAxOSwgMCwgMCwgMCwgMTI5fSwKKyAgICB7MCwgNTcxNTMsIDAsIDAsIDAsIDEyOX0sCisgICAgezAsIDU3Mjc0LCAwLCAwLCAwLCAxMjl9LAorICAgIHswLCAyOCwgMCwgMCwgMCwgMTI5fSwKKyAgICB7NjU1MDgsIDAsIDY1NTA4LCAwLCAwLCA5fSwKKyAgICB7MCwgMTYsIDAsIDAsIDAsIDUxMn0sCisgICAgezY1NTIwLCAwLCA2NTUyMCwgMCwgMCwgNTEyfSwKKyAgICB7MCwgMjYsIDAsIDAsIDAsIDB9LAorICAgIHs2NTUxMCwgMCwgNjU1MTAsIDAsIDAsIDB9LAorICAgIHswLCA1NDc5MywgMCwgMCwgMCwgMTI5fSwKKyAgICB7MCwgNjE3MjIsIDAsIDAsIDAsIDEyOX0sCisgICAgezAsIDU0ODA5LCAwLCAwLCAwLCAxMjl9LAorICAgIHs1NDc0MSwgMCwgNTQ3NDEsIDAsIDAsIDl9LAorICAgIHs1NDc0NCwgMCwgNTQ3NDQsIDAsIDAsIDl9LAorICAgIHswLCA1NDc1NiwgMCwgMCwgMCwgMTI5fSwKKyAgICB7MCwgNTQ3ODcsIDAsIDAsIDAsIDEyOX0sCisgICAgezAsIDU0NzUzLCAwLCAwLCAwLCAxMjl9LAorICAgIHswLCA1NDc1NCwgMCwgMCwgMCwgMTI5fSwKKyAgICB7MCwgNTQ3MjEsIDAsIDAsIDAsIDEyOX0sCisgICAgezU4MjcyLCAwLCA1ODI3MiwgMCwgMCwgOX0sCisgICAgezAsIDAsIDAsIDAsIDAsIDUxM30sCisgICAgezQyODc3LCA3NTQ1LCA0Mjg3NywgMCwgMCwgMzg1fSwKKyAgICB7MCwgNDAsIDAsIDAsIDAsIDEyOX0sCisgICAgezY1NDk2LCAwLCA2NTQ5NiwgMCwgMCwgOX0sCit9OworCisvKiB0eXBlIGluZGV4ZXMgKi8KKyNkZWZpbmUgU0hJRlQgNworc3RhdGljIHVuc2lnbmVkIGNoYXIgaW5kZXgxW10gPSB7CisgICAgMCwgMSwgMiwgMywgNCwgNSwgNiwgNywgOCwgOSwgMTAsIDExLCAxMiwgMTMsIDE0LCAxNSwgMTYsIDE3LCAxOCwgMTksIDIwLCAKKyAgICAyMSwgMjIsIDIzLCAyNCwgMjUsIDI2LCAyNywgMjgsIDI5LCAzMCwgMzEsIDMyLCAzMywgMzQsIDM0LCAzNSwgMzYsIDM3LCAKKyAgICAzOCwgMzksIDM0LCAzNCwgMzQsIDQwLCA0MSwgNDIsIDQzLCA0NCwgNDUsIDQ2LCA0NywgNDgsIDQ5LCA1MCwgNTEsIDUyLCAKKyAgICA1MywgNTQsIDU1LCA1NiwgNTcsIDU4LCA1OSwgNjAsIDYxLCA2MiwgNjMsIDY0LCA2NCwgNjQsIDY1LCA2NiwgNjcsIDY0LCAKKyAgICA2NCwgNjQsIDY4LCA2OSwgNzAsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDcxLCAxNywgNzIsIDczLCA3NCwgNzUsIDc2LCAKKyAgICA3NywgNjQsIDc4LCA3OSwgODAsIDgxLCA4MiwgODMsIDg0LCA2NCwgNjQsIDg1LCA4NiwgMzQsIDM0LCAzNCwgMzQsIDM0LCAKKyAgICAzNCwgODcsIDM0LCAzNCwgMzQsIDM0LCAzNCwgODgsIDM0LCAzNCwgMzQsIDM0LCAzNCwgMzQsIDM0LCAzNCwgMzQsIDM0LCAKKyAgICAzNCwgMzQsIDM0LCAzNCwgMzQsIDM0LCAzNCwgMzQsIDM0LCAzNCwgMzQsIDM0LCAzNCwgMzQsIDM0LCAzNCwgMzQsIDM0LCAKKyAgICAzNCwgMzQsIDM0LCAzNCwgMzQsIDM0LCAzNCwgMzQsIDg5LCA5MCwgOTEsIDkyLCAzNCwgMzQsIDM0LCA5MywgMzQsIDM0LCAKKyAgICAzNCwgOTQsIDk1LCAzNCwgMzQsIDM0LCAzNCwgMzQsIDk2LCAzNCwgMzQsIDM0LCA5NywgMzQsIDM0LCAzNCwgMzQsIDM0LCAKKyAgICAzNCwgMzQsIDM0LCAzNCwgMzQsIDk4LCA5OSwgMTAwLCAzNCwgMzQsIDM0LCAzNCwgMzQsIDM0LCAxMDEsIDEwMiwgMzQsIAorICAgIDM0LCAzNCwgMzQsIDM0LCAzNCwgMzQsIDM0LCAxMDMsIDM0LCAzNCwgMzQsIDM0LCAzNCwgMzQsIDM0LCAzNCwgMzQsIDM0LCAKKyAgICAzNCwgMzQsIDM0LCAzNCwgMTA0LCAzNCwgMzQsIDM0LCAzNCwgMzQsIDM0LCAzNCwgMzQsIDEwNSwgMzQsIDM0LCAzNCwgMzQsIAorICAgIDEwMSwgMzQsIDM0LCAzNCwgMzQsIDM0LCAzNCwgMzQsIDM0LCAzNCwgMzQsIDM0LCAzNCwgMzQsIDM0LCAzNCwgMzQsIDM0LCAKKyAgICAzNCwgMzQsIDM0LCAxMDQsIDM0LCAzNCwgMzQsIDM0LCAzNCwgMzQsIDEwNiwgMzQsIDM0LCAzNCwgMzQsIDM0LCAzNCwgMzQsIAorICAgIDM0LCAzNCwgMzQsIDM0LCAzNCwgMzQsIDM0LCAzNCwgMzQsIDEwNywgMTA4LCAzNCwgMzQsIDM0LCAzNCwgMzQsIDM0LCAzNCwgCisgICAgMzQsIDM0LCAzNCwgMzQsIDM0LCAzNCwgMzQsIDM0LCAzNCwgMzQsIDEwOSwgMTEwLCAzNCwgMzQsIDM0LCAzNCwgMzQsIDM0LCAKKyAgICAzNCwgMzQsIDM0LCAzNCwgMzQsIDM0LCAzNCwgMzQsIDM0LCAzNCwgMzQsIDExMSwgMzQsIDM0LCAzNCwgMzQsIDM0LCAzNCwgCisgICAgMzQsIDM0LCAzNCwgMTEyLCAzNCwgMzQsIDExMywgMTE0LCAxMTUsIDExNiwgMTE3LCAxMTgsIDExOSwgMTIwLCAxMjEsIAorICAgIDEyMiwgMTcsIDEyMywgMzQsIDM0LCAzNCwgMzQsIDM0LCAzNCwgMzQsIDM0LCAzNCwgMzQsIDM0LCAzNCwgMzQsIDM0LCAzNCwgCisgICAgMzQsIDM0LCAzNCwgMzQsIDM0LCAzNCwgMzQsIDM0LCAzNCwgMzQsIDM0LCAzNCwgMzQsIDM0LCAzNCwgMzQsIDM0LCAzNCwgCisgICAgMzQsIDM0LCAzNCwgMzQsIDM0LCAzNCwgMzQsIDM0LCAzNCwgMzQsIDM0LCAzNCwgMzQsIDM0LCAzNCwgMzQsIDM0LCAzNCwgCisgICAgMzQsIDM0LCAzNCwgMzQsIDM0LCAzNCwgMzQsIDM0LCAzNCwgMzQsIDM0LCAzNCwgMzQsIDM0LCAzNCwgMzQsIDM0LCAzNCwgCisgICAgMzQsIDM0LCAzNCwgMzQsIDM0LCAzNCwgMzQsIDM0LCAzNCwgMzQsIDM0LCAzNCwgMzQsIDM0LCAzNCwgMzQsIDM0LCAzNCwgCisgICAgMTI0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIAorICAgIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIAorICAgIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIAorICAgIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCAxMjUsIDEyNiwgMTI3LCAxMjgsIAorICAgIDEyOSwgMTMwLCAzNCwgMzQsIDEzMSwgMTMyLCAxMzMsIDEzNCwgMTM1LCAxMzYsIDEzNywgMTM4LCAxMzksIDE0MCwgMTcsIAorICAgIDE0MSwgMTQyLCAxNDMsIDE0NCwgMTQ1LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNDYsIDE3LCAxNDcsIDE3LCAxNDgsIAorICAgIDE3LCAxNDksIDE3LCAxNTAsIDE3LCAxNywgMTcsIDE1MSwgMTcsIDE3LCAxNywgMTcsIDE1MiwgMTcsIDE3LCAxNywgMTcsIAorICAgIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIAorICAgIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMzQsIDM0LCAzNCwgMzQsIDM0LCAzNCwgMTUzLCAxNywgMTU0LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDM0LCAzNCwgMzQsIDM0LCAzNCwgMzQsIDM0LCAzNCwgMTU1LCAxNywgMTcsIDE3LCAxNywgMTcsIAorICAgIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIAorICAgIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIAorICAgIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIAorICAgIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIAorICAgIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIAorICAgIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIAorICAgIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIAorICAgIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIAorICAgIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIAorICAgIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIAorICAgIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIAorICAgIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIAorICAgIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIAorICAgIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIAorICAgIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIAorICAgIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIAorICAgIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIAorICAgIDY0LCAxNTYsIDE1NywgMTU4LCAxNTksIDE3LCAxNjAsIDE3LCAxNjEsIDE2MiwgMTYzLCAxNjQsIDE2NSwgMTY2LCAxNjcsIAorICAgIDE2OCwgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAKKyAgICAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAKKyAgICAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTY5LCAxNzAsIDE3MSwgMTcyLCAKKyAgICAxNzMsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3NCwgMTc1LCAxNzYsIDM0LCAzNCwgMzQsIDM0LCAKKyAgICAzNCwgMzQsIDM0LCAzNCwgMzQsIDM0LCAzNCwgMzQsIDM0LCAzNCwgMzQsIDg3LCAxNzcsIDM0LCAxNzgsIDE3OSwgMzQsIAorICAgIDM0LCAzNCwgMzQsIDM0LCAzNCwgMzQsIDM0LCAzNCwgMzQsIDM0LCAzNCwgMzQsIDM0LCAzNCwgMzQsIDM0LCAzNCwgMzQsIAorICAgIDM0LCAzNCwgMzQsIDM0LCAzNCwgMzQsIDM0LCAzNCwgMzQsIDM0LCAzNCwgMzQsIDM0LCAzNCwgMzQsIDM0LCAzNCwgMzQsIAorICAgIDM0LCAzNCwgMzQsIDM0LCAzNCwgMzQsIDM0LCAzNCwgMzQsIDM0LCAzNCwgMTgwLCAzNCwgMzQsIDM0LCAzNCwgMzQsIDM0LCAKKyAgICAzNCwgMzQsIDM0LCAzNCwgMzQsIDE4MSwgMzQsIDM0LCAzNCwgMzQsIDM0LCAzNCwgMzQsIDM0LCAzNCwgMzQsIDM0LCAzNCwgCisgICAgMzQsIDM0LCAzNCwgMzQsIDM0LCAzNCwgMzQsIDM0LCAzNCwgMzQsIDM0LCAzNCwgMzQsIDM0LCAzNCwgMzQsIDM0LCAzNCwgCisgICAgMzQsIDM0LCAzNCwgMzQsIDE4MiwgMzQsIDM0LCAzNCwgMzQsIDM0LCAzNCwgMzQsIDM0LCAzNCwgMzQsIDM0LCAzNCwgMzQsIAorICAgIDM0LCAzNCwgMzQsIDM0LCAzNCwgMzQsIDM0LCAzNCwgMzQsIDM0LCAzNCwgMzQsIDM0LCAzNCwgMzQsIDM0LCAzNCwgMzQsIAorICAgIDM0LCAzNCwgMzQsIDM0LCAzNCwgMzQsIDM0LCAzNCwgMzQsIDM0LCAzNCwgMzQsIDM0LCAzNCwgMzQsIDM0LCAzNCwgMzQsIAorICAgIDM0LCAzNCwgMzQsIDM0LCAzNCwgMzQsIDM0LCAzNCwgMzQsIDM0LCAzNCwgMzQsIDM0LCAzNCwgMzQsIDM0LCAzNCwgMzQsIAorICAgIDM0LCAzNCwgMzQsIDM0LCAzNCwgMzQsIDM0LCAzNCwgMzQsIDM0LCAxODMsIDM0LCAzNCwgMzQsIDM0LCAzNCwgMzQsIDM0LCAKKyAgICAzNCwgMzQsIDM0LCAzNCwgMzQsIDM0LCAzNCwgMzQsIDM0LCAzNCwgMzQsIDM0LCAzNCwgMzQsIDM0LCAzNCwgMzQsIDM0LCAKKyAgICAzNCwgMzQsIDM0LCAzNCwgMzQsIDM0LCAzNCwgMzQsIDM0LCAzNCwgMzQsIDM0LCAzNCwgMzQsIDM0LCAzNCwgMzQsIDM0LCAKKyAgICAzNCwgMzQsIDM0LCAzNCwgMzQsIDM0LCAzNCwgMzQsIDM0LCAzNCwgMzQsIDM0LCAzNCwgMzQsIDM0LCAzNCwgMzQsIDM0LCAKKyAgICAzNCwgMzQsIDM0LCAzNCwgMzQsIDM0LCAzNCwgMzQsIDM0LCAzNCwgMzQsIDM0LCAzNCwgMzQsIDM0LCAzNCwgMzQsIDM0LCAKKyAgICAzNCwgMzQsIDM0LCAzNCwgMzQsIDM0LCAzNCwgMzQsIDM0LCAzNCwgMzQsIDM0LCAzNCwgMzQsIDM0LCAzNCwgMzQsIDM0LCAKKyAgICAzNCwgMzQsIDM0LCAzNCwgMzQsIDM0LCAzNCwgMzQsIDM0LCAzNCwgMzQsIDM0LCAzNCwgMzQsIDM0LCAzNCwgMzQsIDM0LCAKKyAgICAzNCwgMzQsIDM0LCAzNCwgMzQsIDM0LCAzNCwgMzQsIDM0LCAzNCwgMzQsIDM0LCAzNCwgMzQsIDM0LCAzNCwgMzQsIDM0LCAKKyAgICAzNCwgMzQsIDM0LCAxODQsIDM0LCAzNCwgMzQsIDM0LCAzNCwgMzQsIDM0LCAzNCwgMzQsIDM0LCAzNCwgMzQsIDM0LCAzNCwgCisgICAgMzQsIDM0LCAzNCwgMzQsIDM0LCAzNCwgMzQsIDM0LCAzNCwgMzQsIDM0LCAzNCwgMzQsIDM0LCAzNCwgMzQsIDM0LCAzNCwgCisgICAgMTg1LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIAorICAgIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIAorICAgIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIAorICAgIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIAorICAgIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIAorICAgIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIAorICAgIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIAorICAgIDE3LCAxNywgMTcsIDE3LCAzNCwgMTgwLCAzNCwgMzQsIDE4NiwgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgCisgICAgMTg3LCAxNywgNjQsIDE4OCwgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAKKyAgICAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAKKyAgICAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAKKyAgICAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAKKyAgICAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAKKyAgICAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAKKyAgICAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAKKyAgICAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAKKyAgICAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAKKyAgICAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAKKyAgICAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAKKyAgICAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAKKyAgICAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAKKyAgICAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAKKyAgICAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAKKyAgICAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAKKyAgICAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAKKyAgICAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAKKyAgICAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAKKyAgICAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAKKyAgICAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAKKyAgICAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAKKyAgICAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAKKyAgICAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAKKyAgICAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAKKyAgICAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAKKyAgICAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAKKyAgICAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAKKyAgICAxNywgMTcsIDE3LCAxNywgMTcsIDE3LCAxNywgMTcsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCAKKyAgICA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCAKKyAgICA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCAKKyAgICA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCAKKyAgICA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCAKKyAgICA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCAKKyAgICA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCAKKyAgICA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCAKKyAgICA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCAKKyAgICA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCAKKyAgICA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCAKKyAgICA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCAKKyAgICA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCAKKyAgICA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCAKKyAgICA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCAKKyAgICA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCAKKyAgICA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCAKKyAgICA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCAKKyAgICA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCAKKyAgICA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCAKKyAgICA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCAKKyAgICA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCAKKyAgICA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCAKKyAgICA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCAKKyAgICA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCAKKyAgICA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCAKKyAgICA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCAKKyAgICA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCAKKyAgICA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCAxODksIDY0LCA2NCwgCisgICAgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgCisgICAgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgCisgICAgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgCisgICAgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgCisgICAgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgCisgICAgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgCisgICAgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgCisgICAgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgCisgICAgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgCisgICAgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgCisgICAgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgCisgICAgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgCisgICAgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgCisgICAgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgCisgICAgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgCisgICAgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgCisgICAgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgCisgICAgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgCisgICAgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgCisgICAgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgCisgICAgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgCisgICAgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgCisgICAgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgCisgICAgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgCisgICAgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgCisgICAgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgCisgICAgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgCisgICAgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgNjQsIDY0LCA2NCwgCisgICAgNjQsIDY0LCA2NCwgNjQsIDY0LCAxODksIAorfTsKKworc3RhdGljIHVuc2lnbmVkIGNoYXIgaW5kZXgyW10gPSB7CisgICAgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMiwgMywgMywgMywgMywgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgCisgICAgMSwgMSwgMSwgMSwgMywgMywgMywgMiwgMiwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgCisgICAgNCwgNSwgNiwgNywgOCwgOSwgMTAsIDExLCAxMiwgMTMsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDE0LCAxNCwgMTQsIDE0LCAKKyAgICAxNCwgMTQsIDE0LCAxNCwgMTQsIDE0LCAxNCwgMTQsIDE0LCAxNCwgMTQsIDE0LCAxNCwgMTQsIDE0LCAxNCwgMTQsIDE0LCAKKyAgICAxNCwgMTQsIDE0LCAxNCwgMSwgMSwgMSwgMSwgMSwgMSwgMTUsIDE1LCAxNSwgMTUsIDE1LCAxNSwgMTUsIDE1LCAxNSwgMTUsIAorICAgIDE1LCAxNSwgMTUsIDE1LCAxNSwgMTUsIDE1LCAxNSwgMTUsIDE1LCAxNSwgMTUsIDE1LCAxNSwgMTUsIDE1LCAxLCAxLCAxLCAKKyAgICAxLCAxLCAxLCAxLCAxLCAxLCAxLCAzLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAKKyAgICAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAyLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxNiwgMSwgMSwgMSwgCisgICAgMSwgMSwgMSwgMSwgMTcsIDE4LCAxLCAxOSwgMSwgMSwgMSwgMjAsIDE2LCAxLCAyMSwgMjEsIDIxLCAxLCAxNCwgMTQsIDE0LCAKKyAgICAxNCwgMTQsIDE0LCAxNCwgMTQsIDE0LCAxNCwgMTQsIDE0LCAxNCwgMTQsIDE0LCAxNCwgMTQsIDE0LCAxNCwgMTQsIDE0LCAKKyAgICAxNCwgMTQsIDEsIDE0LCAxNCwgMTQsIDE0LCAxNCwgMTQsIDE0LCAxNiwgMTUsIDE1LCAxNSwgMTUsIDE1LCAxNSwgMTUsIAorICAgIDE1LCAxNSwgMTUsIDE1LCAxNSwgMTUsIDE1LCAxNSwgMTUsIDE1LCAxNSwgMTUsIDE1LCAxNSwgMTUsIDE1LCAxLCAxNSwgCisgICAgMTUsIDE1LCAxNSwgMTUsIDE1LCAxNSwgMjIsIDIzLCAyNCwgMjMsIDI0LCAyMywgMjQsIDIzLCAyNCwgMjMsIDI0LCAyMywgCisgICAgMjQsIDIzLCAyNCwgMjMsIDI0LCAyMywgMjQsIDIzLCAyNCwgMjMsIDI0LCAyMywgMjQsIDIzLCAyNCwgMjMsIDI0LCAyMywgCisgICAgMjQsIDIzLCAyNCwgMjMsIDI0LCAyMywgMjQsIDIzLCAyNCwgMjMsIDI0LCAyMywgMjQsIDIzLCAyNCwgMjMsIDI0LCAyMywgCisgICAgMjQsIDI1LCAyNiwgMjMsIDI0LCAyMywgMjQsIDIzLCAyNCwgMTYsIDIzLCAyNCwgMjMsIDI0LCAyMywgMjQsIDIzLCAyNCwgCisgICAgMjMsIDI0LCAyMywgMjQsIDIzLCAyNCwgMjMsIDI0LCAxNiwgMjMsIDI0LCAyMywgMjQsIDIzLCAyNCwgMjMsIDI0LCAyMywgCisgICAgMjQsIDIzLCAyNCwgMjMsIDI0LCAyMywgMjQsIDIzLCAyNCwgMjMsIDI0LCAyMywgMjQsIDIzLCAyNCwgMjMsIDI0LCAyMywgCisgICAgMjQsIDIzLCAyNCwgMjMsIDI0LCAyMywgMjQsIDIzLCAyNCwgMjMsIDI0LCAyMywgMjQsIDIzLCAyNCwgMjMsIDI0LCAyMywgCisgICAgMjQsIDI3LCAyMywgMjQsIDIzLCAyNCwgMjMsIDI0LCAyOCwgMjksIDMwLCAyMywgMjQsIDIzLCAyNCwgMzEsIDIzLCAyNCwgCisgICAgMzIsIDMyLCAyMywgMjQsIDE2LCAzMywgMzQsIDM1LCAyMywgMjQsIDMyLCAzNiwgMzcsIDM4LCAzOSwgMjMsIDI0LCA0MCwgCisgICAgMTYsIDM4LCA0MSwgNDIsIDQzLCAyMywgMjQsIDIzLCAyNCwgMjMsIDI0LCA0NCwgMjMsIDI0LCA0NCwgMTYsIDE2LCAyMywgCisgICAgMjQsIDQ0LCAyMywgMjQsIDQ1LCA0NSwgMjMsIDI0LCAyMywgMjQsIDQ2LCAyMywgMjQsIDE2LCA0NywgMjMsIDI0LCAxNiwgCisgICAgNDgsIDQ3LCA0NywgNDcsIDQ3LCA0OSwgNTAsIDUxLCA0OSwgNTAsIDUxLCA0OSwgNTAsIDUxLCAyMywgMjQsIDIzLCAyNCwgCisgICAgMjMsIDI0LCAyMywgMjQsIDIzLCAyNCwgMjMsIDI0LCAyMywgMjQsIDIzLCAyNCwgNTIsIDIzLCAyNCwgMjMsIDI0LCAyMywgCisgICAgMjQsIDIzLCAyNCwgMjMsIDI0LCAyMywgMjQsIDIzLCAyNCwgMjMsIDI0LCAyMywgMjQsIDE2LCA0OSwgNTAsIDUxLCAyMywgCisgICAgMjQsIDUzLCA1NCwgMjMsIDI0LCAyMywgMjQsIDIzLCAyNCwgMjMsIDI0LCAyMywgMjQsIDIzLCAyNCwgMjMsIDI0LCAyMywgCisgICAgMjQsIDIzLCAyNCwgMjMsIDI0LCAyMywgMjQsIDIzLCAyNCwgMjMsIDI0LCAyMywgMjQsIDIzLCAyNCwgMjMsIDI0LCAyMywgCisgICAgMjQsIDIzLCAyNCwgMjMsIDI0LCAyMywgMjQsIDU1LCAxNiwgMjMsIDI0LCAyMywgMjQsIDIzLCAyNCwgMjMsIDI0LCAyMywgCisgICAgMjQsIDIzLCAyNCwgMjMsIDI0LCAyMywgMjQsIDIzLCAyNCwgMTYsIDE2LCAxNiwgMTYsIDE2LCAxNiwgNTYsIDIzLCAyNCwgCisgICAgNTcsIDU4LCA1OSwgNTksIDIzLCAyNCwgNjAsIDYxLCA2MiwgMjMsIDI0LCAyMywgMjQsIDIzLCAyNCwgMjMsIDI0LCAyMywgCisgICAgMjQsIDYzLCA2NCwgNjUsIDY2LCA2NywgMTYsIDY4LCA2OCwgMTYsIDY5LCAxNiwgNzAsIDE2LCAxNiwgMTYsIDE2LCA2OCwgCisgICAgMTYsIDE2LCA3MSwgMTYsIDE2LCAxNiwgMTYsIDcyLCA3MywgMTYsIDc0LCAxNiwgMTYsIDE2LCA3MywgMTYsIDc1LCA3NiwgCisgICAgMTYsIDE2LCA3NywgMTYsIDE2LCAxNiwgMTYsIDE2LCAxNiwgMTYsIDc4LCAxNiwgMTYsIDc5LCAxNiwgMTYsIDc5LCAxNiwgCisgICAgMTYsIDE2LCAxNiwgNzksIDgwLCA4MSwgODEsIDgyLCAxNiwgMTYsIDE2LCAxNiwgMTYsIDgzLCAxNiwgNDcsIDE2LCAxNiwgCisgICAgMTYsIDE2LCAxNiwgMTYsIDE2LCAxNiwgMTYsIDE2LCAxNiwgMTYsIDE2LCAxNiwgMTYsIDE2LCAxNiwgMTYsIDE2LCAxNiwgCisgICAgMTYsIDE2LCAxNiwgMTYsIDE2LCAxNiwgMTYsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDEsIDEsIDEsIDEsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgMSwgMSwgMSwgMSwgMSwgMSwgMSwgNDcsIDEsIDQ3LCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAKKyAgICAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAKKyAgICAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAKKyAgICAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAKKyAgICAxLCAxLCA4NCwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgCisgICAgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMjMsIDI0LCAKKyAgICAyMywgMjQsIDQ3LCAxLCAyMywgMjQsIDAsIDAsIDQ3LCA0MiwgNDIsIDQyLCAxLCAwLCAwLCAwLCAwLCAwLCAxLCAxLCA4NSwgCisgICAgMSwgODYsIDg2LCA4NiwgMCwgODcsIDAsIDg4LCA4OCwgMTYsIDE0LCAxNCwgMTQsIDE0LCAxNCwgMTQsIDE0LCAxNCwgMTQsIAorICAgIDE0LCAxNCwgMTQsIDE0LCAxNCwgMTQsIDE0LCAxNCwgMCwgMTQsIDE0LCAxNCwgMTQsIDE0LCAxNCwgMTQsIDE0LCAxNCwgCisgICAgODksIDkwLCA5MCwgOTAsIDE2LCAxNSwgMTUsIDE1LCAxNSwgMTUsIDE1LCAxNSwgMTUsIDE1LCAxNSwgMTUsIDE1LCAxNSwgCisgICAgMTUsIDE1LCAxNSwgMTUsIDkxLCAxNSwgMTUsIDE1LCAxNSwgMTUsIDE1LCAxNSwgMTUsIDE1LCA5MiwgOTMsIDkzLCA5NCwgCisgICAgOTUsIDk2LCA5NywgOTcsIDk3LCA5OCwgOTksIDEwMCwgMjMsIDI0LCAyMywgMjQsIDIzLCAyNCwgMjMsIDI0LCAyMywgMjQsIAorICAgIDIzLCAyNCwgMjMsIDI0LCAyMywgMjQsIDIzLCAyNCwgMjMsIDI0LCAyMywgMjQsIDIzLCAyNCwgMTAxLCAxMDIsIDEwMywgCisgICAgMTYsIDEwNCwgMTA1LCAxLCAyMywgMjQsIDEwNiwgMjMsIDI0LCAxNiwgNTUsIDU1LCA1NSwgMTA3LCAxMDcsIDEwNywgMTA3LCAKKyAgICAxMDcsIDEwNywgMTA3LCAxMDcsIDEwNywgMTA3LCAxMDcsIDEwNywgMTA3LCAxMDcsIDEwNywgMTA3LCAxNCwgMTQsIDE0LCAKKyAgICAxNCwgMTQsIDE0LCAxNCwgMTQsIDE0LCAxNCwgMTQsIDE0LCAxNCwgMTQsIDE0LCAxNCwgMTQsIDE0LCAxNCwgMTQsIDE0LCAKKyAgICAxNCwgMTQsIDE0LCAxNCwgMTQsIDE0LCAxNCwgMTQsIDE0LCAxNCwgMTQsIDE1LCAxNSwgMTUsIDE1LCAxNSwgMTUsIDE1LCAKKyAgICAxNSwgMTUsIDE1LCAxNSwgMTUsIDE1LCAxNSwgMTUsIDE1LCAxNSwgMTUsIDE1LCAxNSwgMTUsIDE1LCAxNSwgMTUsIDE1LCAKKyAgICAxNSwgMTUsIDE1LCAxNSwgMTUsIDE1LCAxNSwgMTAyLCAxMDIsIDEwMiwgMTAyLCAxMDIsIDEwMiwgMTAyLCAxMDIsIDEwMiwgCisgICAgMTAyLCAxMDIsIDEwMiwgMTAyLCAxMDIsIDEwMiwgMTAyLCAyMywgMjQsIDIzLCAyNCwgMjMsIDI0LCAyMywgMjQsIDIzLCAKKyAgICAyNCwgMjMsIDI0LCAyMywgMjQsIDIzLCAyNCwgMjMsIDI0LCAyMywgMjQsIDIzLCAyNCwgMjMsIDI0LCAyMywgMjQsIDIzLCAKKyAgICAyNCwgMjMsIDI0LCAyMywgMjQsIDIzLCAyNCwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMjMsIDI0LCAyMywgMjQsIDIzLCAKKyAgICAyNCwgMjMsIDI0LCAyMywgMjQsIDIzLCAyNCwgMjMsIDI0LCAyMywgMjQsIDIzLCAyNCwgMjMsIDI0LCAyMywgMjQsIDIzLCAKKyAgICAyNCwgMjMsIDI0LCAyMywgMjQsIDIzLCAyNCwgMjMsIDI0LCAyMywgMjQsIDIzLCAyNCwgMjMsIDI0LCAyMywgMjQsIDIzLCAKKyAgICAyNCwgMjMsIDI0LCAyMywgMjQsIDIzLCAyNCwgMjMsIDI0LCAyMywgMjQsIDIzLCAyNCwgMTA4LCAyMywgMjQsIDIzLCAyNCwgCisgICAgMjMsIDI0LCAyMywgMjQsIDIzLCAyNCwgMjMsIDI0LCAyMywgMjQsIDEwOSwgMjMsIDI0LCAyMywgMjQsIDIzLCAyNCwgMjMsIAorICAgIDI0LCAyMywgMjQsIDIzLCAyNCwgMjMsIDI0LCAyMywgMjQsIDIzLCAyNCwgMjMsIDI0LCAyMywgMjQsIDIzLCAyNCwgMjMsIAorICAgIDI0LCAyMywgMjQsIDIzLCAyNCwgMjMsIDI0LCAyMywgMjQsIDIzLCAyNCwgMjMsIDI0LCAyMywgMjQsIDIzLCAyNCwgMjMsIAorICAgIDI0LCAyMywgMjQsIDIzLCAyNCwgMjMsIDI0LCAyMywgMjQsIDIzLCAyNCwgMjMsIDI0LCAyMywgMjQsIDIzLCAyNCwgMjMsIAorICAgIDI0LCAyMywgMjQsIDIzLCAyNCwgMjMsIDI0LCAyMywgMjQsIDIzLCAyNCwgMjMsIDI0LCAyMywgMjQsIDIzLCAyNCwgMjMsIAorICAgIDI0LCAyMywgMjQsIDIzLCAyNCwgMjMsIDI0LCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAxMTAsIDExMCwgCisgICAgMTEwLCAxMTAsIDExMCwgMTEwLCAxMTAsIDExMCwgMTEwLCAxMTAsIDExMCwgMTEwLCAxMTAsIDExMCwgMTEwLCAxMTAsIAorICAgIDExMCwgMTEwLCAxMTAsIDExMCwgMTEwLCAxMTAsIDExMCwgMTEwLCAxMTAsIDExMCwgMTEwLCAxMTAsIDExMCwgMTEwLCAKKyAgICAxMTAsIDExMCwgMTEwLCAxMTAsIDExMCwgMTEwLCAxMTAsIDExMCwgMCwgMCwgNDcsIDEsIDEsIDEsIDEsIDEsIDEsIDAsIAorICAgIDExMSwgMTExLCAxMTEsIDExMSwgMTExLCAxMTEsIDExMSwgMTExLCAxMTEsIDExMSwgMTExLCAxMTEsIDExMSwgMTExLCAKKyAgICAxMTEsIDExMSwgMTExLCAxMTEsIDExMSwgMTExLCAxMTEsIDExMSwgMTExLCAxMTEsIDExMSwgMTExLCAxMTEsIDExMSwgCisgICAgMTExLCAxMTEsIDExMSwgMTExLCAxMTEsIDExMSwgMTExLCAxMTEsIDExMSwgMTExLCAxNiwgMCwgMSwgMSwgMCwgMCwgMCwgCisgICAgMCwgMCwgMCwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgCisgICAgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgCisgICAgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgMCwgMCwgMCwgMCwgMCwgNDcsIDQ3LCA0NywgMSwgMSwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgCisgICAgMCwgMCwgMCwgMSwgMSwgMSwgMSwgMCwgMCwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgCisgICAgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMCwgMCwgMSwgMSwgMCwgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgMSwgMSwgMSwgMSwgCisgICAgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMCwgNCwgNSwgNiwgNywgOCwgOSwgMTAsIAorICAgIDExLCAxMiwgMTMsIDEsIDEsIDEsIDEsIDQ3LCA0NywgMSwgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgMSwgNDcsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDQ3LCA0NywgMSwgMSwgMSwgMSwgCisgICAgMSwgMSwgMSwgNDcsIDQ3LCA0LCA1LCA2LCA3LCA4LCA5LCAxMCwgMTEsIDEyLCAxMywgNDcsIDQ3LCA0NywgMSwgMSwgNDcsIAorICAgIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDAsIDEsIDQ3LCAxLCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAKKyAgICAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAwLCAwLCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIAorICAgIDQ3LCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCA0LCA1LCA2LCA3LCA4LCA5LCAxMCwgMTEsIAorICAgIDEyLCAxMywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgMSwgMSwgCisgICAgMSwgMSwgMSwgMSwgMSwgMSwgMSwgNDcsIDQ3LCAxLCAxLCAxLCAxLCA0NywgMCwgMCwgMCwgMCwgMCwgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDEsIDEsIDEsIDEsIDQ3LCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCA0NywgMSwgMSwgMSwgNDcsIDEsIDEsIDEsIAorICAgIDEsIDEsIDAsIDAsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDAsIDAsIDAsIDAsIDAsIAorICAgIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIAorICAgIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIAorICAgIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIAorICAgIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIAorICAgIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIAorICAgIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIAorICAgIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIAorICAgIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDEsIDEsIDEsIDEsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDAsIDAsIDEsIDQ3LCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAwLCA0NywgMSwgCisgICAgMSwgMSwgMSwgMSwgMCwgMCwgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDEsIDEsIDEsIDEsIDQsIAorICAgIDUsIDYsIDcsIDgsIDksIDEwLCAxMSwgMTIsIDEzLCAxLCA0NywgNDcsIDAsIDAsIDAsIDAsIDAsIDAsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCAwLCAxLCAxLCAxLCAwLCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDAsIDAsIDQ3LCAKKyAgICA0NywgMCwgMCwgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDAsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAwLCA0NywgMCwgMCwgMCwgCisgICAgNDcsIDQ3LCA0NywgNDcsIDAsIDAsIDEsIDQ3LCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAwLCAwLCAxLCAxLCAwLCAwLCAxLCAxLCAKKyAgICAxLCA0NywgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMSwgMCwgMCwgMCwgMCwgNDcsIDQ3LCAwLCA0NywgNDcsIDQ3LCAxLCAKKyAgICAxLCAwLCAwLCA0LCA1LCA2LCA3LCA4LCA5LCAxMCwgMTEsIDEyLCAxMywgNDcsIDQ3LCAxLCAxLCAyMSwgMjEsIDIxLCAyMSwgCisgICAgMjEsIDIxLCAxLCAxLCAwLCAwLCAwLCAwLCAwLCAxLCAxLCAxLCAwLCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAwLCAwLCAwLCAKKyAgICAwLCA0NywgNDcsIDAsIDAsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAwLCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgMCwgNDcsIDQ3LCAKKyAgICAwLCA0NywgNDcsIDAsIDQ3LCA0NywgMCwgMCwgMSwgMCwgMSwgMSwgMSwgMSwgMSwgMCwgMCwgMCwgMCwgMSwgMSwgMCwgMCwgCisgICAgMSwgMSwgMSwgMCwgMCwgMCwgMSwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgNDcsIDQ3LCA0NywgNDcsIDAsIDQ3LCAwLCAwLCAwLCAKKyAgICAwLCAwLCAwLCAwLCA0LCA1LCA2LCA3LCA4LCA5LCAxMCwgMTEsIDEyLCAxMywgMSwgMSwgNDcsIDQ3LCA0NywgMSwgMCwgMCwgCisgICAgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMSwgMSwgMSwgMCwgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgMCwgNDcsIDQ3LCA0NywgMCwgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDAsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAwLCA0NywgCisgICAgNDcsIDAsIDQ3LCA0NywgNDcsIDQ3LCA0NywgMCwgMCwgMSwgNDcsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDAsIDEsIDEsIAorICAgIDEsIDAsIDEsIDEsIDEsIDAsIDAsIDQ3LCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCA0NywgCisgICAgNDcsIDEsIDEsIDAsIDAsIDQsIDUsIDYsIDcsIDgsIDksIDEwLCAxMSwgMTIsIDEzLCAwLCAxLCAwLCAwLCAwLCAwLCAwLCAwLCAKKyAgICAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAxLCAxLCAxLCAwLCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDAsIAorICAgIDAsIDQ3LCA0NywgMCwgMCwgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDAsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAwLCA0NywgNDcsIAorICAgIDAsIDQ3LCA0NywgNDcsIDQ3LCA0NywgMCwgMCwgMSwgNDcsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDAsIDAsIDEsIDEsIDAsIAorICAgIDAsIDEsIDEsIDEsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDEsIDEsIDAsIDAsIDAsIDAsIDQ3LCA0NywgMCwgNDcsIDQ3LCAKKyAgICA0NywgMSwgMSwgMCwgMCwgNCwgNSwgNiwgNywgOCwgOSwgMTAsIDExLCAxMiwgMTMsIDEsIDQ3LCAwLCAwLCAwLCAwLCAwLCAKKyAgICAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAxLCA0NywgMCwgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgMCwgMCwgCisgICAgMCwgNDcsIDQ3LCA0NywgMCwgNDcsIDQ3LCA0NywgNDcsIDAsIDAsIDAsIDQ3LCA0NywgMCwgNDcsIDAsIDQ3LCA0NywgMCwgCisgICAgMCwgMCwgNDcsIDQ3LCAwLCAwLCAwLCA0NywgNDcsIDQ3LCAwLCAwLCAwLCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCAwLCAwLCAwLCAwLCAxLCAxLCAxLCAxLCAxLCAwLCAwLCAwLCAxLCAxLCAxLCAwLCAxLCAxLCAKKyAgICAxLCAxLCAwLCAwLCA0NywgMCwgMCwgMCwgMCwgMCwgMCwgMSwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgCisgICAgMCwgMCwgNCwgNSwgNiwgNywgOCwgOSwgMTAsIDExLCAxMiwgMTMsIDIxLCAyMSwgMjEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIAorICAgIDEsIDAsIDAsIDAsIDAsIDAsIDAsIDEsIDEsIDEsIDAsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgMCwgNDcsIAorICAgIDQ3LCA0NywgMCwgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAwLCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgMCwgNDcsIDQ3LCA0NywgNDcsIDQ3LCAwLCAwLCAwLCA0NywgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMCwgMSwgMSwgMSwgCisgICAgMCwgMSwgMSwgMSwgMSwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMSwgMSwgMCwgNDcsIDQ3LCAwLCAwLCAwLCAwLCAwLCAwLCAKKyAgICA0NywgNDcsIDEsIDEsIDAsIDAsIDQsIDUsIDYsIDcsIDgsIDksIDEwLCAxMSwgMTIsIDEzLCAwLCAwLCAwLCAwLCAwLCAwLCAKKyAgICAwLCAwLCAyMSwgMjEsIDIxLCAyMSwgMjEsIDIxLCAyMSwgMSwgMCwgMCwgMSwgMSwgMCwgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCAwLCA0NywgNDcsIDQ3LCAwLCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDAsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCAwLCA0NywgNDcsIDQ3LCA0NywgNDcsIDAsIDAsIDEsIDQ3LCAxLCAxLCAxLCAxLCAxLCAxLCAKKyAgICAxLCAwLCAxLCAxLCAxLCAwLCAxLCAxLCAxLCAxLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAxLCAxLCAwLCAwLCAwLCAwLCAwLCAKKyAgICAwLCAwLCA0NywgMCwgNDcsIDQ3LCAxLCAxLCAwLCAwLCA0LCA1LCA2LCA3LCA4LCA5LCAxMCwgMTEsIDEyLCAxMywgMCwgMSwgCisgICAgMSwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMSwgMSwgMCwgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCAwLCA0NywgNDcsIDQ3LCAwLCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDAsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAwLCAwLCAwLCA0NywgMSwgMSwgMSwgMSwgCisgICAgMSwgMSwgMSwgMCwgMSwgMSwgMSwgMCwgMSwgMSwgMSwgMSwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMSwgMCwgMCwgCisgICAgMCwgMCwgMCwgMCwgMCwgMCwgNDcsIDQ3LCAxLCAxLCAwLCAwLCA0LCA1LCA2LCA3LCA4LCA5LCAxMCwgMTEsIDEyLCAxMywgCisgICAgMjEsIDIxLCAyMSwgMjEsIDIxLCAyMSwgMCwgMCwgMCwgMSwgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgMCwgMCwgMSwgMSwgCisgICAgMCwgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgMCwgMCwgMCwgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgMCwgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgMCwgNDcsIDAsIDAsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAwLCAwLCAwLCAxLCAwLCAwLCAwLCAwLCAxLCAKKyAgICAxLCAxLCAxLCAxLCAxLCAwLCAxLCAwLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAKKyAgICAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAxLCAxLCAxLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAKKyAgICAwLCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAxLCA0NywgNDcsIDEsIDEsIDEsIAorICAgIDEsIDEsIDEsIDEsIDAsIDAsIDAsIDAsIDEsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAxLCAxLCAxLCAxLCAxLCAxLCAKKyAgICAxLCAxLCAxLCA0LCA1LCA2LCA3LCA4LCA5LCAxMCwgMTEsIDEyLCAxMywgMSwgMSwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgCisgICAgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgCisgICAgMCwgMCwgMCwgMCwgMCwgNDcsIDQ3LCAwLCA0NywgMCwgMCwgNDcsIDQ3LCAwLCA0NywgMCwgMCwgNDcsIDAsIDAsIDAsIDAsIAorICAgIDAsIDAsIDQ3LCA0NywgNDcsIDQ3LCAwLCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgMCwgNDcsIDQ3LCA0NywgMCwgCisgICAgNDcsIDAsIDQ3LCAwLCAwLCA0NywgNDcsIDAsIDQ3LCA0NywgNDcsIDQ3LCAxLCA0NywgNDcsIDEsIDEsIDEsIDEsIDEsIDEsIAorICAgIDAsIDEsIDEsIDQ3LCAwLCAwLCA0NywgNDcsIDQ3LCA0NywgNDcsIDAsIDQ3LCAwLCAxLCAxLCAxLCAxLCAxLCAxLCAwLCAwLCAKKyAgICA0LCA1LCA2LCA3LCA4LCA5LCAxMCwgMTEsIDEyLCAxMywgMCwgMCwgNDcsIDQ3LCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAKKyAgICAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAKKyAgICAwLCAwLCA0NywgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgCisgICAgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgNCwgNSwgNiwgNywgOCwgOSwgMTAsIDExLCAxMiwgMTMsIDIxLCAyMSwgCisgICAgMjEsIDIxLCAyMSwgMjEsIDIxLCAyMSwgMjEsIDIxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDAsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDAsIDAsIDAsIDAsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIAorICAgIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDQ3LCA0NywgNDcsIDQ3LCAwLCAwLCAwLCAwLCAxLCAxLCAKKyAgICAxLCAxLCAxLCAxLCAxLCAxLCAwLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAKKyAgICAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAwLCAxLCAxLCAxLCAxLCAKKyAgICAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAwLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAwLCAKKyAgICAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAKKyAgICAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgMSwgMSwgCisgICAgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgNDcsIDQsIDUsIDYsIDcsIDgsIAorICAgIDksIDEwLCAxMSwgMTIsIDEzLCAxLCAxLCAxLCAxLCAxLCAxLCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAxLCAxLCAxLCAxLCAKKyAgICA0NywgNDcsIDQ3LCA0NywgMSwgMSwgMSwgNDcsIDEsIDEsIDEsIDQ3LCA0NywgMSwgMSwgMSwgMSwgMSwgMSwgMSwgNDcsIAorICAgIDQ3LCA0NywgMSwgMSwgMSwgMSwgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDQ3LCAxLCA0LCA1LCA2LCA3LCA4LCA5LCAxMCwgMTEsIDEyLCAKKyAgICAxMywgMSwgMSwgMSwgMSwgMSwgMSwgMTEyLCAxMTIsIDExMiwgMTEyLCAxMTIsIDExMiwgMTEyLCAxMTIsIDExMiwgMTEyLCAKKyAgICAxMTIsIDExMiwgMTEyLCAxMTIsIDExMiwgMTEyLCAxMTIsIDExMiwgMTEyLCAxMTIsIDExMiwgMTEyLCAxMTIsIDExMiwgCisgICAgMTEyLCAxMTIsIDExMiwgMTEyLCAxMTIsIDExMiwgMTEyLCAxMTIsIDExMiwgMTEyLCAxMTIsIDExMiwgMTEyLCAxMTIsIDAsIAorICAgIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAxLCA0NywgMCwgMCwgMCwgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgMCwgNDcsIDQ3LCA0NywgNDcsIDAsIDAsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAwLCA0NywgCisgICAgMCwgNDcsIDQ3LCA0NywgNDcsIDAsIDAsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgMCwgNDcsIDQ3LCA0NywgNDcsIDAsIDAsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDAsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCAwLCAwLCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgMCwgNDcsIDAsIDQ3LCA0NywgNDcsIDQ3LCAwLCAwLCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAwLCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICAwLCA0NywgNDcsIDQ3LCA0NywgMCwgMCwgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDAsIDAsIDAsIDAsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDIwLCAxNywgMTgsIDExMywgMTE0LCAxMTUsIAorICAgIDExNiwgMTE3LCAxMTgsIDIxLCAyMSwgMjEsIDIxLCAyMSwgMjEsIDIxLCAyMSwgMjEsIDIxLCAyMSwgMCwgMCwgMCwgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDEsIDEsIDEsIDEsIAorICAgIDEsIDEsIDEsIDEsIDEsIDEsIDAsIDAsIDAsIDAsIDAsIDAsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAxLCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDEsIDEsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgMiwgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAxLCAxLCAwLCAwLCAwLCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAxLCAxLCAxLCAyMSwgMjEsIDIxLCAKKyAgICAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgMCwgNDcsIDQ3LCA0NywgNDcsIDEsIDEsIDEsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIAorICAgIDAsIDAsIDAsIDAsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDEsIDEsIDEsIDEsIDEsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDEsIDEsIDAsIDAsIDAsIDAsIDAsIAorICAgIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICAwLCA0NywgNDcsIDQ3LCAwLCAxLCAxLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgMSwgMSwgMSwgMSwgMSwgMSwgMSwgCisgICAgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgCisgICAgMSwgMSwgMSwgMSwgNDcsIDEsIDEsIDEsIDEsIDQ3LCAxLCAwLCAwLCA0LCA1LCA2LCA3LCA4LCA5LCAxMCwgMTEsIDEyLCAKKyAgICAxMywgMCwgMCwgMCwgMCwgMCwgMCwgMjEsIDIxLCAyMSwgMjEsIDIxLCAyMSwgMjEsIDIxLCAyMSwgMjEsIDAsIDAsIDAsIDAsIAorICAgIDAsIDAsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDIsIDAsIDQsIDUsIDYsIDcsIDgsIDksIAorICAgIDEwLCAxMSwgMTIsIDEzLCAwLCAwLCAwLCAwLCAwLCAwLCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAxLCAKKyAgICA0NywgMCwgMCwgMCwgMCwgMCwgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgMCwgMCwgMCwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMCwgMCwgMCwgMCwgMSwgCisgICAgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMCwgMCwgMCwgMCwgMSwgMCwgMCwgMCwgMSwgMSwgNCwgNSwgNiwgCisgICAgNywgOCwgOSwgMTAsIDExLCAxMiwgMTMsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDAsIDAsIDQ3LCA0NywgNDcsIDQ3LCA0NywgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCAwLCAwLCAwLCAwLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAKKyAgICAxLCAxLCAxLCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgMSwgMSwgMCwgMCwgMCwgMCwgMCwgMCwgNCwgNSwgNiwgNywgCisgICAgOCwgOSwgMTAsIDExLCAxMiwgMTMsIDUsIDAsIDAsIDAsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIAorICAgIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgMSwgMSwgMSwgMSwgMSwgMCwgMCwgMSwgMSwgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAwLCAxLCAKKyAgICAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAKKyAgICAxLCAxLCAxLCAxLCAwLCAwLCAxLCA0LCA1LCA2LCA3LCA4LCA5LCAxMCwgMTEsIDEyLCAxMywgMCwgMCwgMCwgMCwgMCwgMCwgCisgICAgNCwgNSwgNiwgNywgOCwgOSwgMTAsIDExLCAxMiwgMTMsIDAsIDAsIDAsIDAsIDAsIDAsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIAorICAgIDQ3LCAxLCAxLCAxLCAxLCAxLCAxLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAKKyAgICAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAKKyAgICAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAKKyAgICAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAxLCAxLCAxLCAxLCAxLCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIAorICAgIDEsIDEsIDEsIDEsIDEsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAwLCAwLCAwLCAwLCA0LCA1LCA2LCA3LCA4LCA5LCAKKyAgICAxMCwgMTEsIDEyLCAxMywgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgCisgICAgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMCwgMCwgMCwgMSwgMSwgMSwgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMCwgCisgICAgMCwgMCwgNDcsIDQ3LCA0LCA1LCA2LCA3LCA4LCA5LCAxMCwgMTEsIDEyLCAxMywgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgCisgICAgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgCisgICAgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgCisgICAgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgCisgICAgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMCwgMCwgMCwgMSwgMSwgMSwgMSwgMSwgNCwgNSwgNiwgNywgOCwgOSwgMTAsIAorICAgIDExLCAxMiwgMTMsIDAsIDAsIDAsIDQ3LCA0NywgNDcsIDQsIDUsIDYsIDcsIDgsIDksIDEwLCAxMSwgMTIsIDEzLCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAxLCAxLCAKKyAgICAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAKKyAgICAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAKKyAgICAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAKKyAgICAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAKKyAgICAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCA0NywgNDcsIDQ3LCA0NywgMSwgNDcsIDQ3LCA0NywgNDcsIDEsIDAsIDAsIDAsIAorICAgIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDE2LCAxNiwgMTYsIDE2LCAxNiwgMTYsIDE2LCAxNiwgMTYsIDE2LCAxNiwgCisgICAgMTYsIDE2LCAxNiwgMTYsIDE2LCAxNiwgMTYsIDE2LCAxNiwgMTYsIDE2LCAxNiwgMTYsIDE2LCAxNiwgMTYsIDE2LCAxNiwgCisgICAgMTYsIDE2LCAxNiwgMTYsIDE2LCAxNiwgMTYsIDE2LCAxNiwgMTYsIDE2LCAxNiwgMTYsIDE2LCAxNiwgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgMTYsIDE2LCAxNiwgCisgICAgMTYsIDE2LCAxNiwgMTYsIDE2LCAxNiwgMTYsIDE2LCAxNiwgMTYsIDE2LCAxNiwgMTYsIDE2LCAxNiwgMTYsIDE2LCAxNiwgCisgICAgMTYsIDQ3LCAxMTksIDE2LCAxNiwgMTYsIDEyMCwgMTYsIDE2LCAxNiwgMTYsIDE2LCAxNiwgMTYsIDE2LCAxNiwgMTYsIDE2LCAKKyAgICAxNiwgMTYsIDE2LCAxNiwgMTYsIDE2LCAxNiwgMTYsIDE2LCAxNiwgMTYsIDE2LCAxNiwgMTYsIDE2LCAxNiwgMTYsIDE2LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgCisgICAgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgCisgICAgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMSwgMSwgMSwgMjMsIDI0LCAyMywgMjQsIDIzLCAKKyAgICAyNCwgMjMsIDI0LCAyMywgMjQsIDIzLCAyNCwgMjMsIDI0LCAyMywgMjQsIDIzLCAyNCwgMjMsIDI0LCAyMywgMjQsIDIzLCAKKyAgICAyNCwgMjMsIDI0LCAyMywgMjQsIDIzLCAyNCwgMjMsIDI0LCAyMywgMjQsIDIzLCAyNCwgMjMsIDI0LCAyMywgMjQsIDIzLCAKKyAgICAyNCwgMjMsIDI0LCAyMywgMjQsIDIzLCAyNCwgMjMsIDI0LCAyMywgMjQsIDIzLCAyNCwgMjMsIDI0LCAyMywgMjQsIDIzLCAKKyAgICAyNCwgMjMsIDI0LCAyMywgMjQsIDIzLCAyNCwgMjMsIDI0LCAyMywgMjQsIDIzLCAyNCwgMjMsIDI0LCAyMywgMjQsIDIzLCAKKyAgICAyNCwgMjMsIDI0LCAyMywgMjQsIDIzLCAyNCwgMjMsIDI0LCAyMywgMjQsIDIzLCAyNCwgMjMsIDI0LCAyMywgMjQsIDIzLCAKKyAgICAyNCwgMjMsIDI0LCAyMywgMjQsIDIzLCAyNCwgMjMsIDI0LCAyMywgMjQsIDIzLCAyNCwgMjMsIDI0LCAyMywgMjQsIDIzLCAKKyAgICAyNCwgMjMsIDI0LCAyMywgMjQsIDIzLCAyNCwgMjMsIDI0LCAyMywgMjQsIDIzLCAyNCwgMjMsIDI0LCAyMywgMjQsIDIzLCAKKyAgICAyNCwgMjMsIDI0LCAyMywgMjQsIDIzLCAyNCwgMjMsIDI0LCAyMywgMjQsIDIzLCAyNCwgMjMsIDI0LCAyMywgMjQsIDIzLCAKKyAgICAyNCwgMTYsIDE2LCAxNiwgMTYsIDE2LCAxMjEsIDE2LCAxNiwgMTIyLCAxNiwgMjMsIDI0LCAyMywgMjQsIDIzLCAyNCwgMjMsIAorICAgIDI0LCAyMywgMjQsIDIzLCAyNCwgMjMsIDI0LCAyMywgMjQsIDIzLCAyNCwgMjMsIDI0LCAyMywgMjQsIDIzLCAyNCwgMjMsIAorICAgIDI0LCAyMywgMjQsIDIzLCAyNCwgMjMsIDI0LCAyMywgMjQsIDIzLCAyNCwgMjMsIDI0LCAyMywgMjQsIDIzLCAyNCwgMjMsIAorICAgIDI0LCAyMywgMjQsIDIzLCAyNCwgMjMsIDI0LCAyMywgMjQsIDIzLCAyNCwgMjMsIDI0LCAyMywgMjQsIDIzLCAyNCwgMjMsIAorICAgIDI0LCAyMywgMjQsIDIzLCAyNCwgMjMsIDI0LCAyMywgMjQsIDIzLCAyNCwgMjMsIDI0LCAyMywgMjQsIDIzLCAyNCwgMjMsIAorICAgIDI0LCAyMywgMjQsIDIzLCAyNCwgMjMsIDI0LCAyMywgMjQsIDIzLCAyNCwgMjMsIDI0LCAyMywgMjQsIDIzLCAyNCwgMTIzLCAKKyAgICAxMjMsIDEyMywgMTIzLCAxMjMsIDEyMywgMTIzLCAxMjMsIDEyNCwgMTI0LCAxMjQsIDEyNCwgMTI0LCAxMjQsIDEyNCwgCisgICAgMTI0LCAxMjMsIDEyMywgMTIzLCAxMjMsIDEyMywgMTIzLCAwLCAwLCAxMjQsIDEyNCwgMTI0LCAxMjQsIDEyNCwgMTI0LCAwLCAKKyAgICAwLCAxMjMsIDEyMywgMTIzLCAxMjMsIDEyMywgMTIzLCAxMjMsIDEyMywgMTI0LCAxMjQsIDEyNCwgMTI0LCAxMjQsIDEyNCwgCisgICAgMTI0LCAxMjQsIDEyMywgMTIzLCAxMjMsIDEyMywgMTIzLCAxMjMsIDEyMywgMTIzLCAxMjQsIDEyNCwgMTI0LCAxMjQsIAorICAgIDEyNCwgMTI0LCAxMjQsIDEyNCwgMTIzLCAxMjMsIDEyMywgMTIzLCAxMjMsIDEyMywgMCwgMCwgMTI0LCAxMjQsIDEyNCwgCisgICAgMTI0LCAxMjQsIDEyNCwgMCwgMCwgMTYsIDEyMywgMTYsIDEyMywgMTYsIDEyMywgMTYsIDEyMywgMCwgMTI0LCAwLCAxMjQsIAorICAgIDAsIDEyNCwgMCwgMTI0LCAxMjMsIDEyMywgMTIzLCAxMjMsIDEyMywgMTIzLCAxMjMsIDEyMywgMTI0LCAxMjQsIDEyNCwgCisgICAgMTI0LCAxMjQsIDEyNCwgMTI0LCAxMjQsIDEyNSwgMTI1LCAxMjYsIDEyNiwgMTI2LCAxMjYsIDEyNywgMTI3LCAxMjgsIAorICAgIDEyOCwgMTI5LCAxMjksIDEzMCwgMTMwLCAwLCAwLCAxMjMsIDEyMywgMTIzLCAxMjMsIDEyMywgMTIzLCAxMjMsIDEyMywgCisgICAgMTMxLCAxMzEsIDEzMSwgMTMxLCAxMzEsIDEzMSwgMTMxLCAxMzEsIDEyMywgMTIzLCAxMjMsIDEyMywgMTIzLCAxMjMsIAorICAgIDEyMywgMTIzLCAxMzEsIDEzMSwgMTMxLCAxMzEsIDEzMSwgMTMxLCAxMzEsIDEzMSwgMTIzLCAxMjMsIDEyMywgMTIzLCAKKyAgICAxMjMsIDEyMywgMTIzLCAxMjMsIDEzMSwgMTMxLCAxMzEsIDEzMSwgMTMxLCAxMzEsIDEzMSwgMTMxLCAxMjMsIDEyMywgMTYsIAorICAgIDEzMiwgMTYsIDAsIDE2LCAxNiwgMTI0LCAxMjQsIDEzMywgMTMzLCAxMzQsIDEsIDEzNSwgMSwgMSwgMSwgMTYsIDEzMiwgCisgICAgMTYsIDAsIDE2LCAxNiwgMTM2LCAxMzYsIDEzNiwgMTM2LCAxMzQsIDEsIDEsIDEsIDEyMywgMTIzLCAxNiwgMTYsIDAsIDAsIAorICAgIDE2LCAxNiwgMTI0LCAxMjQsIDEzNywgMTM3LCAwLCAxLCAxLCAxLCAxMjMsIDEyMywgMTYsIDE2LCAxNiwgMTAzLCAxNiwgCisgICAgMTYsIDEyNCwgMTI0LCAxMzgsIDEzOCwgMTA2LCAxLCAxLCAxLCAwLCAwLCAxNiwgMTMyLCAxNiwgMCwgMTYsIDE2LCAxMzksIAorICAgIDEzOSwgMTQwLCAxNDAsIDEzNCwgMSwgMSwgMCwgMiwgMiwgMiwgMiwgMiwgMiwgMiwgMiwgMiwgMiwgMiwgMSwgMSwgMSwgMSwgCisgICAgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgCisgICAgMSwgMywgMywgMSwgMSwgMSwgMSwgMSwgMiwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgCisgICAgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgCisgICAgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMiwgMSwgMSwgMSwgMSwgMSwgMCwgMCwgMCwgMCwgMCwgMSwgMSwgMSwgMSwgMSwgCisgICAgMSwgMTQxLCA0NywgMCwgMCwgMTEzLCAxMTQsIDExNSwgMTE2LCAxMTcsIDExOCwgMSwgMSwgMSwgMSwgMSwgNDcsIDE0MSwgCisgICAgMjAsIDE3LCAxOCwgMTEzLCAxMTQsIDExNSwgMTE2LCAxMTcsIDExOCwgMSwgMSwgMSwgMSwgMSwgMCwgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAKKyAgICAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAKKyAgICAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAKKyAgICAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAwLCAwLCAKKyAgICAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAxLCAxLCA5NywgMSwgMSwgMSwgMSwgOTcsIDEsIDEsIAorICAgIDE2LCA5NywgOTcsIDk3LCAxNiwgMTYsIDk3LCA5NywgOTcsIDE2LCAxLCA5NywgMSwgMSwgMSwgOTcsIDk3LCA5NywgOTcsIAorICAgIDk3LCAxLCAxLCAxLCAxLCAxLCAxLCA5NywgMSwgMTQyLCAxLCA5NywgMSwgMTQzLCAxNDQsIDk3LCA5NywgMSwgMTYsIDk3LCAKKyAgICA5NywgMTQ1LCA5NywgMTYsIDQ3LCA0NywgNDcsIDQ3LCAxNiwgMSwgMSwgMTYsIDE2LCA5NywgOTcsIDEsIDEsIDEsIDEsIDEsIAorICAgIDk3LCAxNiwgMTYsIDE2LCAxNiwgMSwgMSwgMSwgMSwgMTQ2LCAxLCAyMSwgMjEsIDIxLCAyMSwgMjEsIDIxLCAyMSwgMjEsIAorICAgIDIxLCAyMSwgMjEsIDIxLCAyMSwgMjEsIDIxLCAyMSwgMTQ3LCAxNDcsIDE0NywgMTQ3LCAxNDcsIDE0NywgMTQ3LCAxNDcsIAorICAgIDE0NywgMTQ3LCAxNDcsIDE0NywgMTQ3LCAxNDcsIDE0NywgMTQ3LCAxNDgsIDE0OCwgMTQ4LCAxNDgsIDE0OCwgMTQ4LCAKKyAgICAxNDgsIDE0OCwgMTQ4LCAxNDgsIDE0OCwgMTQ4LCAxNDgsIDE0OCwgMTQ4LCAxNDgsIDIxLCAyMSwgMjEsIDIzLCAyNCwgMjEsIAorICAgIDIxLCAyMSwgMjEsIDIxLCAwLCAwLCAwLCAwLCAwLCAwLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAKKyAgICAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAKKyAgICAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAKKyAgICAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAKKyAgICAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAKKyAgICAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAKKyAgICAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAKKyAgICAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAKKyAgICAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAKKyAgICAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAKKyAgICAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAKKyAgICAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAKKyAgICAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAKKyAgICAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAKKyAgICAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAwLCAwLCAwLCAwLCAKKyAgICAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAxLCAxLCAxLCAxLCAxLCAKKyAgICAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAKKyAgICAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAKKyAgICAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAwLCAwLCAKKyAgICAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAyMCwgMTcsIDE4LCAxMTMsIAorICAgIDExNCwgMTE1LCAxMTYsIDExNywgMTE4LCAyMSwgMjEsIDIxLCAyMSwgMjEsIDIxLCAyMSwgMjEsIDIxLCAyMSwgMjEsIDIwLCAKKyAgICAxNywgMTgsIDExMywgMTE0LCAxMTUsIDExNiwgMTE3LCAxMTgsIDIxLCAyMSwgMjEsIDIxLCAyMSwgMjEsIDIxLCAyMSwgMjEsIAorICAgIDIxLCAyMSwgMjAsIDE3LCAxOCwgMTEzLCAxMTQsIDExNSwgMTE2LCAxMTcsIDExOCwgMjEsIDIxLCAyMSwgMjEsIDIxLCAyMSwgCisgICAgMjEsIDIxLCAyMSwgMjEsIDIxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAKKyAgICAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxNDksIDE0OSwgMTQ5LCAxNDksIDE0OSwgMTQ5LCAxNDksIDE0OSwgMTQ5LCAxNDksIAorICAgIDE0OSwgMTQ5LCAxNDksIDE0OSwgMTQ5LCAxNDksIDE0OSwgMTQ5LCAxNDksIDE0OSwgMTQ5LCAxNDksIDE0OSwgMTQ5LCAKKyAgICAxNDksIDE0OSwgMTUwLCAxNTAsIDE1MCwgMTUwLCAxNTAsIDE1MCwgMTUwLCAxNTAsIDE1MCwgMTUwLCAxNTAsIDE1MCwgCisgICAgMTUwLCAxNTAsIDE1MCwgMTUwLCAxNTAsIDE1MCwgMTUwLCAxNTAsIDE1MCwgMTUwLCAxNTAsIDE1MCwgMTUwLCAxNTAsIAorICAgIDE0MSwgMjEsIDIxLCAyMSwgMjEsIDIxLCAyMSwgMjEsIDIxLCAyMSwgMjEsIDIwLCAxNywgMTgsIDExMywgMTE0LCAxMTUsIAorICAgIDExNiwgMTE3LCAxMTgsIDIxLCAxNDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIAorICAgIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIAorICAgIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIAorICAgIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDAsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIAorICAgIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDAsIDEsIDAsIDAsIDAsIDAsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIAorICAgIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDAsIDEsIDEsIDEsIDEsIDAsIDEsIDEsIAorICAgIDEsIDEsIDAsIDAsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIAorICAgIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDAsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIAorICAgIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDAsIDEsIDAsIDEsIAorICAgIDEsIDEsIDEsIDAsIDAsIDAsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDAsIDAsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIAorICAgIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDIwLCAxNywgMTgsIDExMywgMTE0LCAxMTUsIDExNiwgCisgICAgMTE3LCAxMTgsIDIxLCAyMCwgMTcsIDE4LCAxMTMsIDExNCwgMTE1LCAxMTYsIDExNywgMTE4LCAyMSwgMjAsIDE3LCAxOCwgCisgICAgMTEzLCAxMTQsIDExNSwgMTE2LCAxMTcsIDExOCwgMjEsIDEsIDAsIDAsIDAsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIAorICAgIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDAsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIAorICAgIDEsIDEsIDEsIDEsIDEsIDEsIDAsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDAsIDEsIDAsIDAsIDAsIDEsIAorICAgIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIAorICAgIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIAorICAgIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIAorICAgIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIAorICAgIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIAorICAgIDEsIDEsIDEsIDEsIDAsIDAsIDAsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIAorICAgIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIAorICAgIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDExMCwgMTEwLCAxMTAsIDExMCwgMTEwLCAxMTAsIDExMCwgMTEwLCAxMTAsIDExMCwgCisgICAgMTEwLCAxMTAsIDExMCwgMTEwLCAxMTAsIDExMCwgMTEwLCAxMTAsIDExMCwgMTEwLCAxMTAsIDExMCwgMTEwLCAxMTAsIAorICAgIDExMCwgMTEwLCAxMTAsIDExMCwgMTEwLCAxMTAsIDExMCwgMTEwLCAxMTAsIDExMCwgMTEwLCAxMTAsIDExMCwgMTEwLCAKKyAgICAxMTAsIDExMCwgMTEwLCAxMTAsIDExMCwgMTEwLCAxMTAsIDExMCwgMTEwLCAwLCAxMTEsIDExMSwgMTExLCAxMTEsIDExMSwgCisgICAgMTExLCAxMTEsIDExMSwgMTExLCAxMTEsIDExMSwgMTExLCAxMTEsIDExMSwgMTExLCAxMTEsIDExMSwgMTExLCAxMTEsIAorICAgIDExMSwgMTExLCAxMTEsIDExMSwgMTExLCAxMTEsIDExMSwgMTExLCAxMTEsIDExMSwgMTExLCAxMTEsIDExMSwgMTExLCAKKyAgICAxMTEsIDExMSwgMTExLCAxMTEsIDExMSwgMTExLCAxMTEsIDExMSwgMTExLCAxMTEsIDExMSwgMTExLCAxMTEsIDExMSwgMCwgCisgICAgMjMsIDI0LCAxNTEsIDE1MiwgMTUzLCAxNTQsIDE1NSwgMjMsIDI0LCAyMywgMjQsIDIzLCAyNCwgMTU2LCAxNTcsIDE1OCwgCisgICAgMTU5LCAxNiwgMjMsIDI0LCAxNiwgMjMsIDI0LCAxNiwgMTYsIDE2LCAxNiwgMTYsIDE2LCA0NywgMTYwLCAxNjAsIDIzLCAKKyAgICAyNCwgMjMsIDI0LCAyMywgMjQsIDIzLCAyNCwgMjMsIDI0LCAyMywgMjQsIDIzLCAyNCwgMjMsIDI0LCAyMywgMjQsIDIzLCAKKyAgICAyNCwgMjMsIDI0LCAyMywgMjQsIDIzLCAyNCwgMjMsIDI0LCAyMywgMjQsIDIzLCAyNCwgMjMsIDI0LCAyMywgMjQsIDIzLCAKKyAgICAyNCwgMjMsIDI0LCAyMywgMjQsIDIzLCAyNCwgMjMsIDI0LCAyMywgMjQsIDIzLCAyNCwgMjMsIDI0LCAyMywgMjQsIDIzLCAKKyAgICAyNCwgMjMsIDI0LCAyMywgMjQsIDIzLCAyNCwgMjMsIDI0LCAyMywgMjQsIDIzLCAyNCwgMjMsIDI0LCAyMywgMjQsIDIzLCAKKyAgICAyNCwgMjMsIDI0LCAyMywgMjQsIDIzLCAyNCwgMjMsIDI0LCAyMywgMjQsIDIzLCAyNCwgMjMsIDI0LCAyMywgMjQsIDIzLCAKKyAgICAyNCwgMjMsIDI0LCAyMywgMjQsIDIzLCAyNCwgMjMsIDI0LCAxNiwgMSwgMSwgMSwgMSwgMSwgMSwgMjMsIDI0LCAyMywgMjQsIAorICAgIDEsIDEsIDEsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDEsIDEsIDEsIDEsIDIxLCAxLCAxLCAxNjEsIDE2MSwgMTYxLCAxNjEsIAorICAgIDE2MSwgMTYxLCAxNjEsIDE2MSwgMTYxLCAxNjEsIDE2MSwgMTYxLCAxNjEsIDE2MSwgMTYxLCAxNjEsIDE2MSwgMTYxLCAKKyAgICAxNjEsIDE2MSwgMTYxLCAxNjEsIDE2MSwgMTYxLCAxNjEsIDE2MSwgMTYxLCAxNjEsIDE2MSwgMTYxLCAxNjEsIDE2MSwgCisgICAgMTYxLCAxNjEsIDE2MSwgMTYxLCAxNjEsIDE2MSwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgMCwgMCwgMCwgMCwgCisgICAgMCwgMCwgMCwgMCwgMCwgNDcsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDAsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAwLCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgMCwgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDAsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAwLCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgMCwgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDAsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAwLCAxLCAKKyAgICAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAKKyAgICAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAKKyAgICAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAKKyAgICAxLCAxLCAxLCAxLCAxLCAxLCA0NywgMSwgMSwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgCisgICAgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgCisgICAgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgCisgICAgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgCisgICAgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMCwgMSwgMSwgMSwgMSwgMSwgMSwgCisgICAgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgCisgICAgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgCisgICAgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgCisgICAgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMSwgCisgICAgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgCisgICAgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgCisgICAgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgCisgICAgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgCisgICAgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgCisgICAgMSwgMSwgMSwgMCwgMCwgMCwgMCwgMiwgMSwgMSwgMSwgMSwgNDcsIDQ3LCAyMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgCisgICAgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMjEsIDIxLCAyMSwgMjEsIDIxLCAKKyAgICAyMSwgMjEsIDIxLCAyMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgNDcsIDQ3LCA0NywgNDcsIDQ3LCAxLCAxLCAyMSwgMjEsIAorICAgIDIxLCA0NywgNDcsIDEsIDEsIDEsIDAsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgMCwgMCwgMSwgMSwgMSwgMSwgNDcsIDQ3LCA0NywgMSwgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgMSwgNDcsIDQ3LCA0NywgNDcsIDAsIDAsIDAsIDAsIDAsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgMCwgMCwgMCwgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDAsIDEsIDEsIDIxLCAyMSwgMjEsIDIxLCAxLCAKKyAgICAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAKKyAgICAwLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAKKyAgICAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAKKyAgICAwLCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgMSwgMSwgCisgICAgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgCisgICAgMSwgMSwgMSwgMSwgMSwgMCwgMjEsIDIxLCAyMSwgMjEsIDIxLCAyMSwgMjEsIDIxLCAyMSwgMjEsIDEsIDEsIDEsIDEsIDEsIAorICAgIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIAorICAgIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDIxLCAyMSwgMjEsIDIxLCAyMSwgMjEsIDIxLCAyMSwgMjEsIDIxLCAyMSwgCisgICAgMjEsIDIxLCAyMSwgMjEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIAorICAgIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDIxLCAyMSwgMjEsIDIxLCAyMSwgMjEsIDIxLCAyMSwgCisgICAgMjEsIDIxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAKKyAgICAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAyMSwgMjEsIDIxLCAyMSwgMjEsIAorICAgIDIxLCAyMSwgMjEsIDIxLCAyMSwgMjEsIDIxLCAyMSwgMjEsIDIxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAKKyAgICAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAKKyAgICAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAKKyAgICAxLCAxLCAxLCAxLCAwLCA0NywgNDcsIDQ3LCA0NywgNDcsIDE2MiwgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAxNjIsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAxNjIsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDE2MiwgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAKKyAgICAwLCAwLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAKKyAgICAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAKKyAgICAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxNjIsIDQ3LCA0NywgMTYyLCAKKyAgICA0NywgNDcsIDQ3LCAxNjIsIDQ3LCAxNjIsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgMTYyLCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgMTYyLCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgMTYyLCA0NywgMTYyLCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgMTYyLCAxNjIsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDE2MiwgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAxNjIsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDE2MiwgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCAxNjIsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAxNjIsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgMTYyLCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgMTYyLCAKKyAgICA0NywgMTYyLCA0NywgMTYyLCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDE2MiwgNDcsIDE2MiwgCisgICAgMTYyLCAxNjIsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDE2MiwgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICAxNjIsIDE2MiwgMTYyLCAxNjIsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDE2MiwgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAxNjIsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAxNjIsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgMTYyLCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDE2MiwgMTYyLCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAxNjIsIDE2MiwgMTYyLCA0NywgMTYyLCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCAxNjIsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgMTYyLCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgMTYyLCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAxNjIsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgMTYyLCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDE2MiwgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgMTYyLCA0NywgNDcsIDQ3LCA0NywgMTYyLCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgMTYyLCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgMTYyLCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAxNjIsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgMTYyLCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgMTYyLCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDE2MiwgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIAorICAgIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIAorICAgIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAwLCAwLCAwLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAKKyAgICAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAKKyAgICAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAwLCAwLCAwLCAwLCAwLCAKKyAgICAwLCAwLCAwLCAwLCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgMSwgMSwgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDEsIDEsIDEsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0LCA1LCA2LCA3LCA4LCA5LCAxMCwgMTEsIDEyLCAxMywgNDcsIAorICAgIDQ3LCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAyMywgMjQsIAorICAgIDIzLCAyNCwgMjMsIDI0LCAyMywgMjQsIDIzLCAyNCwgMjMsIDI0LCAyMywgMjQsIDIzLCAyNCwgMjMsIDI0LCAyMywgMjQsIAorICAgIDIzLCAyNCwgMjMsIDI0LCAyMywgMjQsIDIzLCAyNCwgMjMsIDI0LCAyMywgMjQsIDAsIDAsIDIzLCAyNCwgMjMsIDI0LCAyMywgCisgICAgMjQsIDIzLCAyNCwgMjMsIDI0LCAyMywgMjQsIDQ3LCAxLCAxLCAxLCAxLCAxLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAxLCAKKyAgICAxLCAxLCA0NywgMjMsIDI0LCAyMywgMjQsIDIzLCAyNCwgMjMsIDI0LCAyMywgMjQsIDIzLCAyNCwgMjMsIDI0LCAyMywgMjQsIAorICAgIDIzLCAyNCwgMjMsIDI0LCAyMywgMjQsIDIzLCAyNCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDIxLCAyMSwgMjEsIDIxLCAyMSwgMjEsIAorICAgIDIxLCAyMSwgMjEsIDIxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAxLCAxLCAxLCAKKyAgICAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAxLCAxLCAyMywgMjQsIDIzLCAyNCwgMjMsIDI0LCAyMywgMjQsIDIzLCAyNCwgMjMsIAorICAgIDI0LCAyMywgMjQsIDE2LCAxNiwgMjMsIDI0LCAyMywgMjQsIDIzLCAyNCwgMjMsIDI0LCAyMywgMjQsIDIzLCAyNCwgMjMsIAorICAgIDI0LCAyMywgMjQsIDIzLCAyNCwgMjMsIDI0LCAyMywgMjQsIDIzLCAyNCwgMjMsIDI0LCAyMywgMjQsIDIzLCAyNCwgMjMsIAorICAgIDI0LCAyMywgMjQsIDIzLCAyNCwgMjMsIDI0LCAyMywgMjQsIDIzLCAyNCwgMjMsIDI0LCAyMywgMjQsIDIzLCAyNCwgMjMsIAorICAgIDI0LCAyMywgMjQsIDIzLCAyNCwgMjMsIDI0LCAyMywgMjQsIDIzLCAyNCwgMjMsIDI0LCA0NywgMTYsIDE2LCAxNiwgMTYsIAorICAgIDE2LCAxNiwgMTYsIDE2LCAyMywgMjQsIDIzLCAyNCwgMTYzLCAyMywgMjQsIDIzLCAyNCwgMjMsIDI0LCAyMywgMjQsIDIzLCAKKyAgICAyNCwgNDcsIDEsIDEsIDIzLCAyNCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgCisgICAgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgCisgICAgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgCisgICAgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgCisgICAgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDEsIDQ3LCA0NywgNDcsIDEsIDQ3LCA0NywgNDcsIDQ3LCAxLCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDAsIDAsIDAsIDAsIDIxLCAyMSwgMjEsIDIxLCAyMSwgMjEsIDEsIDEsIAorICAgIDEsIDEsIDAsIDAsIDAsIDAsIDAsIDAsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCAxLCAxLCAxLCAxLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAxLCAxLCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIAorICAgIDEsIDEsIDEsIDEsIDEsIDEsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDEsIDEsIDQsIDUsIDYsIDcsIDgsIDksIDEwLCAKKyAgICAxMSwgMTIsIDEzLCAwLCAwLCAwLCAwLCAwLCAwLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAKKyAgICAxLCAxLCAxLCAxLCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAxLCAxLCAxLCA0NywgMCwgMCwgMCwgMCwgNCwgNSwgNiwgNywgCisgICAgOCwgOSwgMTAsIDExLCAxMiwgMTMsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAxLCAxLCAxLCAxLCAKKyAgICAxLCAxLCAxLCAxLCAxLCAxLCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIAorICAgIDEsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDEsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgMCwgMCwgMCwgMSwgMSwgMSwgMSwgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAKKyAgICAxLCAxLCAxLCAxLCAwLCA0NywgNCwgNSwgNiwgNywgOCwgOSwgMTAsIDExLCAxMiwgMTMsIDAsIDAsIDAsIDAsIDEsIDEsIDAsIAorICAgIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIAorICAgIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgCisgICAgMSwgMSwgMSwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgNDcsIDQ3LCA0NywgMSwgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCAxLCAxLCAwLCAwLCA0LCA1LCA2LCA3LCA4LCA5LCAxMCwgMTEsIDEyLCAxMywgMCwgMCwgMSwgMSwgMSwgCisgICAgMSwgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAxLCAxLCAxLCA0NywgMSwgMCwgMCwgMCwgMCwgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgMSwgNDcsIDEsIDEsIDEsIDQ3LCA0NywgMSwgMSwgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCAxLCAxLCA0NywgMSwgNDcsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIAorICAgIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDQ3LCA0NywgNDcsIDEsIDEsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIAorICAgIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIAorICAgIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIAorICAgIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIAorICAgIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMCwgCisgICAgMCwgNCwgNSwgNiwgNywgOCwgOSwgMTAsIDExLCAxMiwgMTMsIDAsIDAsIDAsIDAsIDAsIDAsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDAsIDAsIDAsIDAsIDAsIDAsIAorICAgIDAsIDAsIDAsIDAsIDAsIDAsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgMCwgMCwgMCwgMCwgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDAsIDAsIDAsIDAsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgMTYyLCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgMTYyLCAKKyAgICA0NywgNDcsIDQ3LCA0NywgMTYyLCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAxNjIsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDE2MiwgNDcsIDE2MiwgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAxNjIsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDAsIDAsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgMCwgMCwgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDAsIDAsIDAsIDAsIDAsIDAsIAorICAgIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIAorICAgIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDE2LCAxNiwgMTYsIDE2LCAxNiwgMTYsIDE2LCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAKKyAgICAwLCAwLCAwLCAwLCAwLCAxNiwgMTYsIDE2LCAxNiwgMTYsIDAsIDAsIDAsIDAsIDAsIDQ3LCAxLCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgMSwgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDAsIDQ3LCA0NywgNDcsIDQ3LCA0NywgMCwgNDcsIDAsIDQ3LCA0NywgMCwgNDcsIDQ3LCAwLCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAwLCAwLCAwLCAKKyAgICAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAKKyAgICAwLCAwLCAwLCAwLCAwLCAwLCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDEsIDEsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAwLCAwLCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAKKyAgICAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAKKyAgICAwLCAwLCAwLCAwLCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAxLCAxLCAwLCAwLCAKKyAgICAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAKKyAgICAxLCAxLCAwLCAwLCAwLCAwLCAwLCAwLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAKKyAgICAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAKKyAgICAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAwLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAKKyAgICAxLCAxLCAxLCAxLCAxLCAxLCAxLCAwLCAxLCAxLCAxLCAxLCAwLCAwLCAwLCAwLCA0NywgNDcsIDQ3LCA0NywgNDcsIDAsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDAsIDAsIDEsIDAsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIAorICAgIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDQsIDUsIDYsIDcsIDgsIDksIDEwLCAxMSwgMTIsIDEzLCAxLCAxLCAxLCAxLCAxLCAxLCAKKyAgICAxLCAxNCwgMTQsIDE0LCAxNCwgMTQsIDE0LCAxNCwgMTQsIDE0LCAxNCwgMTQsIDE0LCAxNCwgMTQsIDE0LCAxNCwgMTQsIAorICAgIDE0LCAxNCwgMTQsIDE0LCAxNCwgMTQsIDE0LCAxNCwgMTQsIDEsIDEsIDEsIDEsIDEsIDEsIDE1LCAxNSwgMTUsIDE1LCAxNSwgCisgICAgMTUsIDE1LCAxNSwgMTUsIDE1LCAxNSwgMTUsIDE1LCAxNSwgMTUsIDE1LCAxNSwgMTUsIDE1LCAxNSwgMTUsIDE1LCAxNSwgCisgICAgMTUsIDE1LCAxNSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAwLCAwLCAwLCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICAwLCAwLCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAwLCAwLCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAwLCAwLCA0NywgNDcsIAorICAgIDQ3LCAwLCAwLCAwLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAwLCAxLCAxLCAxLCAxLCAxLCAxLCAxLCAwLCAwLCAwLCAwLCAwLCAKKyAgICAwLCAwLCAwLCAwLCAwLCAxLCAxLCAxLCAxLCAxLCAwLCAwLCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCAwLCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDAsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAwLCA0NywgNDcsIDAsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDAsIDAsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgCisgICAgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgMCwgMCwgMCwgMCwgCisgICAgMCwgMSwgMSwgMSwgMCwgMCwgMCwgMCwgMjEsIDIxLCAyMSwgMjEsIDIxLCAyMSwgMjEsIDIxLCAyMSwgMjEsIDIxLCAyMSwgCisgICAgMjEsIDIxLCAyMSwgMjEsIDIxLCAyMSwgMjEsIDIxLCAyMSwgMjEsIDIxLCAyMSwgMjEsIDIxLCAyMSwgMjEsIDIxLCAyMSwgCisgICAgMjEsIDIxLCAyMSwgMjEsIDIxLCAyMSwgMjEsIDIxLCAyMSwgMjEsIDIxLCAyMSwgMjEsIDIxLCAyMSwgMCwgMCwgMCwgMSwgCisgICAgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMjEsIDIxLCAyMSwgMjEsIDIxLCAyMSwgMjEsIDIxLCAyMSwgMjEsIDIxLCAyMSwgCisgICAgMjEsIDIxLCAyMSwgMjEsIDIxLCAyMSwgMjEsIDIxLCAyMSwgMjEsIDIxLCAyMSwgMjEsIDIxLCAyMSwgMjEsIDIxLCAyMSwgCisgICAgMjEsIDIxLCAyMSwgMjEsIDIxLCAyMSwgMjEsIDIxLCAyMSwgMjEsIDIxLCAyMSwgMjEsIDIxLCAyMSwgMjEsIDIxLCAyMSwgCisgICAgMjEsIDIxLCAyMSwgMjEsIDIxLCAyMSwgMjEsIDIxLCAyMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgCisgICAgMSwgMSwgMSwgMSwgMSwgMjEsIDAsIDAsIDAsIDAsIDAsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDAsIAorICAgIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIAorICAgIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIAorICAgIDAsIDAsIDAsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIAorICAgIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIAorICAgIDEsIDAsIDAsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgMCwgMCwgMCwgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIAorICAgIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIAorICAgIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCAwLCAyMSwgMjEsIDIxLCAyMSwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAyMSwgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAyMSwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgCisgICAgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgCisgICAgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgMCwgMSwgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgMCwgMCwgMCwgMCwgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCAxLCAyMSwgMjEsIDIxLCAyMSwgMjEsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIAorICAgIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIAorICAgIDAsIDAsIDAsIDE2NCwgMTY0LCAxNjQsIDE2NCwgMTY0LCAxNjQsIDE2NCwgMTY0LCAxNjQsIDE2NCwgMTY0LCAxNjQsIDE2NCwgCisgICAgMTY0LCAxNjQsIDE2NCwgMTY0LCAxNjQsIDE2NCwgMTY0LCAxNjQsIDE2NCwgMTY0LCAxNjQsIDE2NCwgMTY0LCAxNjQsIAorICAgIDE2NCwgMTY0LCAxNjQsIDE2NCwgMTY0LCAxNjQsIDE2NCwgMTY0LCAxNjQsIDE2NCwgMTY0LCAxNjQsIDE2NCwgMTY1LCAKKyAgICAxNjUsIDE2NSwgMTY1LCAxNjUsIDE2NSwgMTY1LCAxNjUsIDE2NSwgMTY1LCAxNjUsIDE2NSwgMTY1LCAxNjUsIDE2NSwgCisgICAgMTY1LCAxNjUsIDE2NSwgMTY1LCAxNjUsIDE2NSwgMTY1LCAxNjUsIDE2NSwgMTY1LCAxNjUsIDE2NSwgMTY1LCAxNjUsIAorICAgIDE2NSwgMTY1LCAxNjUsIDE2NSwgMTY1LCAxNjUsIDE2NSwgMTY1LCAxNjUsIDE2NSwgMTY1LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCAwLCAwLCA0LCA1LCA2LCA3LCA4LCA5LCAxMCwgMTEsIDEyLCAxMywgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgCisgICAgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgCisgICAgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgCisgICAgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgCisgICAgMCwgMCwgMCwgMCwgMCwgMCwgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgMCwgMCwgNDcsIDAsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgMCwgNDcsIDQ3LCAwLCAwLCAwLCA0NywgMCwgMCwgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAwLCAxLCAyMSwgCisgICAgMjEsIDIxLCAyMSwgMjEsIDIxLCAyMSwgMjEsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIAorICAgIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAyMSwgCisgICAgMjEsIDIxLCAyMSwgMjEsIDIxLCAwLCAwLCAwLCAxLCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDAsIDAsIDAsIAorICAgIDAsIDAsIDEsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIAorICAgIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIAorICAgIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDQ3LCAxLCAxLCAxLCAwLCAKKyAgICAxLCAxLCAwLCAwLCAwLCAwLCAwLCAxLCAxLCAxLCAxLCA0NywgNDcsIDQ3LCA0NywgMCwgNDcsIDQ3LCA0NywgMCwgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgMCwgMCwgMCwgMCwgMSwgMSwgMSwgMCwgMCwgMCwgMCwgMSwgMjAsIAorICAgIDE3LCAxOCwgMTEzLCAyMSwgMjEsIDIxLCAyMSwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgCisgICAgMSwgMSwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICAyMSwgMjEsIDEsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDAsIDAsIDAsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAwLCAwLCAyMSwgMjEsIDIxLCAKKyAgICAyMSwgMjEsIDIxLCAyMSwgMjEsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAwLCAwLCAwLCAwLCAwLCAyMSwgMjEsIDIxLCAyMSwgMjEsIDIxLCAyMSwgMjEsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAKKyAgICAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAKKyAgICAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAKKyAgICAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAKKyAgICAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAKKyAgICAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAKKyAgICAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAyMCwgMTcsIDE4LCAxMTMsIDExNCwgMTE1LCAxMTYsIDExNywgMTE4LCAyMSwgMjEsIAorICAgIDIxLCAyMSwgMjEsIDIxLCAyMSwgMjEsIDIxLCAyMSwgMjEsIDIxLCAyMSwgMjEsIDIxLCAyMSwgMjEsIDIxLCAyMSwgMjEsIAorICAgIDIxLCAyMSwgMCwgMSwgMSwgMSwgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgMSwgMSwgMSwgMSwgMSwgMSwgCisgICAgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgCisgICAgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgCisgICAgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgCisgICAgMCwgMCwgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMjEsIAorICAgIDIxLCAyMSwgMjEsIDIxLCAyMSwgMjEsIDIxLCAyMSwgMjEsIDIxLCAyMSwgMjEsIDIxLCAyMSwgMjEsIDIxLCAyMSwgMjEsIAorICAgIDIxLCAyMSwgMjEsIDIxLCAyMSwgMjEsIDIxLCAyMSwgMjEsIDIxLCAyMSwgMjEsIDIxLCAyMSwgMjEsIDIxLCAyMSwgMjEsIAorICAgIDIxLCAyMSwgMjEsIDIxLCAyMSwgMjEsIDIxLCAyMSwgMjEsIDIxLCAyMSwgMjEsIDIxLCAxLCAxLCAyMSwgMjEsIDIxLCAyMSwgCisgICAgMjEsIDIxLCAyMSwgMjEsIDIxLCAyMSwgMjEsIDIxLCAyMSwgMjEsIDIxLCAyMSwgMjEsIDIxLCAyMSwgMjEsIDIxLCAyMSwgCisgICAgMjEsIDIxLCAyMSwgMjEsIDIxLCAyMSwgMjEsIDIxLCAyMSwgMjEsIDIxLCAyMSwgMSwgMSwgMjEsIDIxLCAyMSwgMjEsIDIxLCAKKyAgICAyMSwgMjEsIDIxLCAyMSwgMjEsIDIxLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAxLCAxLCAxLCAKKyAgICAxLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIAorICAgIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIAorICAgIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIAorICAgIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIAorICAgIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIAorICAgIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIAorICAgIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIAorICAgIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIAorICAgIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDEsIDEsIDEsIAorICAgIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIAorICAgIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDAsIDAsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIAorICAgIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIAorICAgIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIAorICAgIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIAorICAgIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIAorICAgIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIAorICAgIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIAorICAgIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIAorICAgIDEsIDEsIDEsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIAorICAgIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIAorICAgIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIAorICAgIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIAorICAgIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIAorICAgIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIAorICAgIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDEsIDEsIDEsIAorICAgIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIAorICAgIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIAorICAgIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIAorICAgIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDIxLCAyMSwgCisgICAgMjEsIDIxLCAyMSwgMjEsIDIxLCAyMSwgMjEsIDIxLCAyMSwgMjEsIDIxLCAyMSwgMjEsIDIxLCAyMSwgMjEsIDAsIDAsIDAsIAorICAgIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDk3LCA5NywgOTcsIDk3LCA5NywgOTcsIDk3LCA5NywgOTcsIDk3LCAKKyAgICA5NywgOTcsIDk3LCA5NywgOTcsIDk3LCA5NywgOTcsIDk3LCA5NywgOTcsIDk3LCA5NywgOTcsIDk3LCA5NywgMTYsIDE2LCAKKyAgICAxNiwgMTYsIDE2LCAxNiwgMTYsIDE2LCAxNiwgMTYsIDE2LCAxNiwgMTYsIDE2LCAxNiwgMTYsIDE2LCAxNiwgMTYsIDE2LCAKKyAgICAxNiwgMTYsIDE2LCAxNiwgMTYsIDE2LCA5NywgOTcsIDk3LCA5NywgOTcsIDk3LCA5NywgOTcsIDk3LCA5NywgOTcsIDk3LCAKKyAgICA5NywgOTcsIDk3LCA5NywgOTcsIDk3LCA5NywgOTcsIDk3LCA5NywgOTcsIDk3LCA5NywgOTcsIDE2LCAxNiwgMTYsIDE2LCAKKyAgICAxNiwgMTYsIDE2LCAwLCAxNiwgMTYsIDE2LCAxNiwgMTYsIDE2LCAxNiwgMTYsIDE2LCAxNiwgMTYsIDE2LCAxNiwgMTYsIAorICAgIDE2LCAxNiwgMTYsIDE2LCA5NywgOTcsIDk3LCA5NywgOTcsIDk3LCA5NywgOTcsIDk3LCA5NywgOTcsIDk3LCA5NywgOTcsIAorICAgIDk3LCA5NywgOTcsIDk3LCA5NywgOTcsIDk3LCA5NywgOTcsIDk3LCA5NywgOTcsIDE2LCAxNiwgMTYsIDE2LCAxNiwgMTYsIAorICAgIDE2LCAxNiwgMTYsIDE2LCAxNiwgMTYsIDE2LCAxNiwgMTYsIDE2LCAxNiwgMTYsIDE2LCAxNiwgMTYsIDE2LCAxNiwgMTYsIAorICAgIDE2LCAxNiwgOTcsIDAsIDk3LCA5NywgMCwgMCwgOTcsIDAsIDAsIDk3LCA5NywgMCwgMCwgOTcsIDk3LCA5NywgOTcsIDAsIAorICAgIDk3LCA5NywgOTcsIDk3LCA5NywgOTcsIDk3LCA5NywgMTYsIDE2LCAxNiwgMTYsIDAsIDE2LCAwLCAxNiwgMTYsIDE2LCAxNiwgCisgICAgMTYsIDE2LCAxNiwgMCwgMTYsIDE2LCAxNiwgMTYsIDE2LCAxNiwgMTYsIDE2LCAxNiwgMTYsIDE2LCA5NywgOTcsIDk3LCAKKyAgICA5NywgOTcsIDk3LCA5NywgOTcsIDk3LCA5NywgOTcsIDk3LCA5NywgOTcsIDk3LCA5NywgOTcsIDk3LCA5NywgOTcsIDk3LCAKKyAgICA5NywgOTcsIDk3LCA5NywgOTcsIDE2LCAxNiwgMTYsIDE2LCAxNiwgMTYsIDE2LCAxNiwgMTYsIDE2LCAxNiwgMTYsIDE2LCAKKyAgICAxNiwgMTYsIDE2LCAxNiwgMTYsIDE2LCAxNiwgMTYsIDE2LCAxNiwgMTYsIDE2LCAxNiwgOTcsIDk3LCAwLCA5NywgOTcsIAorICAgIDk3LCA5NywgMCwgMCwgOTcsIDk3LCA5NywgOTcsIDk3LCA5NywgOTcsIDk3LCAwLCA5NywgOTcsIDk3LCA5NywgOTcsIDk3LCAKKyAgICA5NywgMCwgMTYsIDE2LCAxNiwgMTYsIDE2LCAxNiwgMTYsIDE2LCAxNiwgMTYsIDE2LCAxNiwgMTYsIDE2LCAxNiwgMTYsIAorICAgIDE2LCAxNiwgMTYsIDE2LCAxNiwgMTYsIDE2LCAxNiwgMTYsIDE2LCA5NywgOTcsIDAsIDk3LCA5NywgOTcsIDk3LCAwLCA5NywgCisgICAgOTcsIDk3LCA5NywgOTcsIDAsIDk3LCAwLCAwLCAwLCA5NywgOTcsIDk3LCA5NywgOTcsIDk3LCA5NywgMCwgMTYsIDE2LCAKKyAgICAxNiwgMTYsIDE2LCAxNiwgMTYsIDE2LCAxNiwgMTYsIDE2LCAxNiwgMTYsIDE2LCAxNiwgMTYsIDE2LCAxNiwgMTYsIDE2LCAKKyAgICAxNiwgMTYsIDE2LCAxNiwgMTYsIDE2LCA5NywgOTcsIDk3LCA5NywgOTcsIDk3LCA5NywgOTcsIDk3LCA5NywgOTcsIDk3LCAKKyAgICA5NywgOTcsIDk3LCA5NywgOTcsIDk3LCA5NywgOTcsIDk3LCA5NywgOTcsIDk3LCA5NywgOTcsIDE2LCAxNiwgMTYsIDE2LCAKKyAgICAxNiwgMTYsIDE2LCAxNiwgMTYsIDE2LCAxNiwgMTYsIDE2LCAxNiwgMTYsIDE2LCAxNiwgMTYsIDE2LCAxNiwgMTYsIDE2LCAKKyAgICAxNiwgMTYsIDE2LCAxNiwgOTcsIDk3LCA5NywgOTcsIDk3LCA5NywgOTcsIDk3LCA5NywgOTcsIDk3LCA5NywgOTcsIDk3LCAKKyAgICA5NywgOTcsIDk3LCA5NywgOTcsIDk3LCA5NywgOTcsIDk3LCA5NywgOTcsIDk3LCAxNiwgMTYsIDE2LCAxNiwgMTYsIDE2LCAKKyAgICAxNiwgMTYsIDE2LCAxNiwgMTYsIDE2LCAxNiwgMTYsIDE2LCAxNiwgMTYsIDE2LCAxNiwgMTYsIDE2LCAxNiwgMTYsIDE2LCAKKyAgICAxNiwgMTYsIDk3LCA5NywgOTcsIDk3LCA5NywgOTcsIDk3LCA5NywgOTcsIDk3LCA5NywgOTcsIDk3LCA5NywgOTcsIDk3LCAKKyAgICA5NywgOTcsIDk3LCA5NywgOTcsIDk3LCA5NywgOTcsIDk3LCA5NywgMTYsIDE2LCAxNiwgMTYsIDE2LCAxNiwgMTYsIDE2LCAKKyAgICAxNiwgMTYsIDE2LCAxNiwgMTYsIDE2LCAxNiwgMTYsIDE2LCAxNiwgMTYsIDE2LCAxNiwgMTYsIDE2LCAxNiwgMTYsIDE2LCAKKyAgICA5NywgOTcsIDk3LCA5NywgOTcsIDk3LCA5NywgOTcsIDk3LCA5NywgOTcsIDk3LCA5NywgOTcsIDk3LCA5NywgOTcsIDk3LCAKKyAgICA5NywgOTcsIDk3LCA5NywgOTcsIDk3LCA5NywgOTcsIDE2LCAxNiwgMTYsIDE2LCAxNiwgMTYsIDE2LCAxNiwgMTYsIDE2LCAKKyAgICAxNiwgMTYsIDE2LCAxNiwgMTYsIDE2LCAxNiwgMTYsIDE2LCAxNiwgMTYsIDE2LCAxNiwgMTYsIDE2LCAxNiwgOTcsIDk3LCAKKyAgICA5NywgOTcsIDk3LCA5NywgOTcsIDk3LCA5NywgOTcsIDk3LCA5NywgOTcsIDk3LCA5NywgOTcsIDk3LCA5NywgOTcsIDk3LCAKKyAgICA5NywgOTcsIDk3LCA5NywgOTcsIDk3LCAxNiwgMTYsIDE2LCAxNiwgMTYsIDE2LCAxNiwgMTYsIDE2LCAxNiwgMTYsIDE2LCAKKyAgICAxNiwgMTYsIDE2LCAxNiwgMTYsIDE2LCAxNiwgMTYsIDE2LCAxNiwgMTYsIDE2LCAxNiwgMTYsIDk3LCA5NywgOTcsIDk3LCAKKyAgICA5NywgOTcsIDk3LCA5NywgOTcsIDk3LCA5NywgOTcsIDk3LCA5NywgOTcsIDk3LCA5NywgOTcsIDk3LCA5NywgOTcsIDk3LCAKKyAgICA5NywgOTcsIDk3LCA5NywgMTYsIDE2LCAxNiwgMTYsIDE2LCAxNiwgMTYsIDE2LCAxNiwgMTYsIDE2LCAxNiwgMTYsIDE2LCAKKyAgICAxNiwgMTYsIDE2LCAxNiwgMTYsIDE2LCAxNiwgMTYsIDE2LCAxNiwgMTYsIDE2LCAxNiwgMTYsIDAsIDAsIDk3LCA5NywgOTcsIAorICAgIDk3LCA5NywgOTcsIDk3LCA5NywgOTcsIDk3LCA5NywgOTcsIDk3LCA5NywgOTcsIDk3LCA5NywgOTcsIDk3LCA5NywgOTcsIAorICAgIDk3LCA5NywgOTcsIDk3LCAxLCAxNiwgMTYsIDE2LCAxNiwgMTYsIDE2LCAxNiwgMTYsIDE2LCAxNiwgMTYsIDE2LCAxNiwgCisgICAgMTYsIDE2LCAxNiwgMTYsIDE2LCAxNiwgMTYsIDE2LCAxNiwgMTYsIDE2LCAxNiwgMSwgMTYsIDE2LCAxNiwgMTYsIDE2LCAKKyAgICAxNiwgOTcsIDk3LCA5NywgOTcsIDk3LCA5NywgOTcsIDk3LCA5NywgOTcsIDk3LCA5NywgOTcsIDk3LCA5NywgOTcsIDk3LCAKKyAgICA5NywgOTcsIDk3LCA5NywgOTcsIDk3LCA5NywgOTcsIDEsIDE2LCAxNiwgMTYsIDE2LCAxNiwgMTYsIDE2LCAxNiwgMTYsIAorICAgIDE2LCAxNiwgMTYsIDE2LCAxNiwgMTYsIDE2LCAxNiwgMTYsIDE2LCAxNiwgMTYsIDE2LCAxNiwgMTYsIDE2LCAxLCAxNiwgCisgICAgMTYsIDE2LCAxNiwgMTYsIDE2LCA5NywgOTcsIDk3LCA5NywgOTcsIDk3LCA5NywgOTcsIDk3LCA5NywgOTcsIDk3LCA5NywgCisgICAgOTcsIDk3LCA5NywgOTcsIDk3LCA5NywgOTcsIDk3LCA5NywgOTcsIDk3LCA5NywgMSwgMTYsIDE2LCAxNiwgMTYsIDE2LCAKKyAgICAxNiwgMTYsIDE2LCAxNiwgMTYsIDE2LCAxNiwgMTYsIDE2LCAxNiwgMTYsIDE2LCAxNiwgMTYsIDE2LCAxNiwgMTYsIDE2LCAKKyAgICAxNiwgMTYsIDEsIDE2LCAxNiwgMTYsIDE2LCAxNiwgMTYsIDk3LCA5NywgOTcsIDk3LCA5NywgOTcsIDk3LCA5NywgOTcsIAorICAgIDk3LCA5NywgOTcsIDk3LCA5NywgOTcsIDk3LCA5NywgOTcsIDk3LCA5NywgOTcsIDk3LCA5NywgOTcsIDk3LCAxLCAxNiwgCisgICAgMTYsIDE2LCAxNiwgMTYsIDE2LCAxNiwgMTYsIDE2LCAxNiwgMTYsIDE2LCAxNiwgMTYsIDE2LCAxNiwgMTYsIDE2LCAxNiwgCisgICAgMTYsIDE2LCAxNiwgMTYsIDE2LCAxNiwgMSwgMTYsIDE2LCAxNiwgMTYsIDE2LCAxNiwgOTcsIDk3LCA5NywgOTcsIDk3LCAKKyAgICA5NywgOTcsIDk3LCA5NywgOTcsIDk3LCA5NywgOTcsIDk3LCA5NywgOTcsIDk3LCA5NywgOTcsIDk3LCA5NywgOTcsIDk3LCAKKyAgICA5NywgOTcsIDEsIDE2LCAxNiwgMTYsIDE2LCAxNiwgMTYsIDE2LCAxNiwgMTYsIDE2LCAxNiwgMTYsIDE2LCAxNiwgMTYsIAorICAgIDE2LCAxNiwgMTYsIDE2LCAxNiwgMTYsIDE2LCAxNiwgMTYsIDE2LCAxLCAxNiwgMTYsIDE2LCAxNiwgMTYsIDE2LCA5NywgCisgICAgMTYsIDAsIDAsIDQsIDUsIDYsIDcsIDgsIDksIDEwLCAxMSwgMTIsIDEzLCA0LCA1LCA2LCA3LCA4LCA5LCAxMCwgMTEsIDEyLCAKKyAgICAxMywgNCwgNSwgNiwgNywgOCwgOSwgMTAsIDExLCAxMiwgMTMsIDQsIDUsIDYsIDcsIDgsIDksIDEwLCAxMSwgMTIsIDEzLCAKKyAgICA0LCA1LCA2LCA3LCA4LCA5LCAxMCwgMTEsIDEyLCAxMywgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgCisgICAgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgCisgICAgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMCwgMCwgMCwgMCwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgCisgICAgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgCisgICAgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgCisgICAgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgCisgICAgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMSwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgCisgICAgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgCisgICAgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgCisgICAgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgCisgICAgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgMCwgCisgICAgMCwgMCwgMCwgMTQxLCAxNDEsIDIwLCAxNywgMTgsIDExMywgMTE0LCAxMTUsIDExNiwgMTE3LCAxMTgsIDAsIDAsIDAsIDAsIAorICAgIDAsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIAorICAgIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDAsIDAsIDEsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDEsIDAsIAorICAgIDEsIDAsIDAsIDEsIDAsIDAsIDAsIDEsIDAsIDAsIDAsIDEsIDEsIDEsIDEsIDEsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIAorICAgIDEsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDEsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIAorICAgIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDEsIDAsIDEsIDEsIDAsIDAsIDEsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIAorICAgIDAsIDAsIDAsIDEsIDEsIDEsIDEsIDAsIDAsIDEsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIAorICAgIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIAorICAgIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIAorICAgIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIAorICAgIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIAorICAgIDAsIDEsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIAorICAgIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIAorICAgIDEsIDEsIDEsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIAorICAgIDEsIDEsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIAorICAgIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIAorICAgIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDQ3LCAxNjIsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgMTYyLCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDE2MiwgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAxNjIsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAxNjIsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgMTYyLCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCAxNjIsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAxNjIsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDE2MiwgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgMTYyLCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgMTYyLCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAxNjIsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgCisgICAgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAxNjIsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgMTYyLCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAKKyAgICAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAwLCAKKyAgICAwLCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIAorICAgIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIAorICAgIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIAorICAgIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIAorICAgIDAsIDAsIDAsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCAKKyAgICA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDQ3LCA0NywgNDcsIDAsIDAsIDAsIDAsIDAsIDAsIAorICAgIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIAorICAgIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIAorICAgIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIAorICAgIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDEsIDAsIDAsIAorICAgIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIAorICAgIDAsIDAsIDAsIDAsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIAorICAgIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIAorICAgIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIAorICAgIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIAorICAgIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIAorICAgIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIAorICAgIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIAorICAgIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIAorICAgIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDAsIDAsIDAsIDAsIAorICAgIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDAsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIAorICAgIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIAorICAgIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIAorICAgIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIAorICAgIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIAorICAgIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDEsIDAsIDAsIAorfTsKKworLyogUmV0dXJucyB0aGUgbnVtZXJpYyB2YWx1ZSBhcyBkb3VibGUgZm9yIFVuaWNvZGUgY2hhcmFjdGVycworICogaGF2aW5nIHRoaXMgcHJvcGVydHksIC0xLjAgb3RoZXJ3aXNlLgorICovCitkb3VibGUgX1B5VW5pY29kZV9Ub051bWVyaWMoUHlfVU5JQ09ERSBjaCkKK3sKKyAgICBzd2l0Y2ggKGNoKSB7CisgICAgY2FzZSAweDBGMzM6CisgICAgICAgIHJldHVybiAoZG91YmxlKSAtMS4wLzIuMDsKKyAgICBjYXNlIDB4MDAzMDoKKyAgICBjYXNlIDB4MDY2MDoKKyAgICBjYXNlIDB4MDZGMDoKKyAgICBjYXNlIDB4MDdDMDoKKyAgICBjYXNlIDB4MDk2NjoKKyAgICBjYXNlIDB4MDlFNjoKKyAgICBjYXNlIDB4MEE2NjoKKyAgICBjYXNlIDB4MEFFNjoKKyAgICBjYXNlIDB4MEI2NjoKKyAgICBjYXNlIDB4MEJFNjoKKyAgICBjYXNlIDB4MEM2NjoKKyAgICBjYXNlIDB4MEM3ODoKKyAgICBjYXNlIDB4MENFNjoKKyAgICBjYXNlIDB4MEQ2NjoKKyAgICBjYXNlIDB4MEU1MDoKKyAgICBjYXNlIDB4MEVEMDoKKyAgICBjYXNlIDB4MEYyMDoKKyAgICBjYXNlIDB4MTA0MDoKKyAgICBjYXNlIDB4MTA5MDoKKyAgICBjYXNlIDB4MTdFMDoKKyAgICBjYXNlIDB4MTdGMDoKKyAgICBjYXNlIDB4MTgxMDoKKyAgICBjYXNlIDB4MTk0NjoKKyAgICBjYXNlIDB4MTlEMDoKKyAgICBjYXNlIDB4MUE4MDoKKyAgICBjYXNlIDB4MUE5MDoKKyAgICBjYXNlIDB4MUI1MDoKKyAgICBjYXNlIDB4MUJCMDoKKyAgICBjYXNlIDB4MUM0MDoKKyAgICBjYXNlIDB4MUM1MDoKKyAgICBjYXNlIDB4MjA3MDoKKyAgICBjYXNlIDB4MjA4MDoKKyAgICBjYXNlIDB4MjE4OToKKyAgICBjYXNlIDB4MjRFQToKKyAgICBjYXNlIDB4MjRGRjoKKyAgICBjYXNlIDB4MzAwNzoKKyAgICBjYXNlIDB4OTZGNjoKKyAgICBjYXNlIDB4QTYyMDoKKyAgICBjYXNlIDB4QTZFRjoKKyAgICBjYXNlIDB4QThEMDoKKyAgICBjYXNlIDB4QTkwMDoKKyAgICBjYXNlIDB4QTlEMDoKKyAgICBjYXNlIDB4QUE1MDoKKyAgICBjYXNlIDB4QUJGMDoKKyAgICBjYXNlIDB4RjlCMjoKKyAgICBjYXNlIDB4RkYxMDoKKyNpZmRlZiBQeV9VTklDT0RFX1dJREUKKyAgICBjYXNlIDB4MTAxOEE6CisgICAgY2FzZSAweDEwNEEwOgorICAgIGNhc2UgMHgxRDdDRToKKyAgICBjYXNlIDB4MUQ3RDg6CisgICAgY2FzZSAweDFEN0UyOgorICAgIGNhc2UgMHgxRDdFQzoKKyAgICBjYXNlIDB4MUQ3RjY6CisgICAgY2FzZSAweDFGMTAwOgorICAgIGNhc2UgMHgxRjEwMToKKyNlbmRpZgorICAgICAgICByZXR1cm4gKGRvdWJsZSkgMC4wOworICAgIGNhc2UgMHgwMDMxOgorICAgIGNhc2UgMHgwMEI5OgorICAgIGNhc2UgMHgwNjYxOgorICAgIGNhc2UgMHgwNkYxOgorICAgIGNhc2UgMHgwN0MxOgorICAgIGNhc2UgMHgwOTY3OgorICAgIGNhc2UgMHgwOUU3OgorICAgIGNhc2UgMHgwQTY3OgorICAgIGNhc2UgMHgwQUU3OgorICAgIGNhc2UgMHgwQjY3OgorICAgIGNhc2UgMHgwQkU3OgorICAgIGNhc2UgMHgwQzY3OgorICAgIGNhc2UgMHgwQzc5OgorICAgIGNhc2UgMHgwQzdDOgorICAgIGNhc2UgMHgwQ0U3OgorICAgIGNhc2UgMHgwRDY3OgorICAgIGNhc2UgMHgwRTUxOgorICAgIGNhc2UgMHgwRUQxOgorICAgIGNhc2UgMHgwRjIxOgorICAgIGNhc2UgMHgxMDQxOgorICAgIGNhc2UgMHgxMDkxOgorICAgIGNhc2UgMHgxMzY5OgorICAgIGNhc2UgMHgxN0UxOgorICAgIGNhc2UgMHgxN0YxOgorICAgIGNhc2UgMHgxODExOgorICAgIGNhc2UgMHgxOTQ3OgorICAgIGNhc2UgMHgxOUQxOgorICAgIGNhc2UgMHgxOURBOgorICAgIGNhc2UgMHgxQTgxOgorICAgIGNhc2UgMHgxQTkxOgorICAgIGNhc2UgMHgxQjUxOgorICAgIGNhc2UgMHgxQkIxOgorICAgIGNhc2UgMHgxQzQxOgorICAgIGNhc2UgMHgxQzUxOgorICAgIGNhc2UgMHgyMDgxOgorICAgIGNhc2UgMHgyMTVGOgorICAgIGNhc2UgMHgyMTYwOgorICAgIGNhc2UgMHgyMTcwOgorICAgIGNhc2UgMHgyNDYwOgorICAgIGNhc2UgMHgyNDc0OgorICAgIGNhc2UgMHgyNDg4OgorICAgIGNhc2UgMHgyNEY1OgorICAgIGNhc2UgMHgyNzc2OgorICAgIGNhc2UgMHgyNzgwOgorICAgIGNhc2UgMHgyNzhBOgorICAgIGNhc2UgMHgzMDIxOgorICAgIGNhc2UgMHgzMTkyOgorICAgIGNhc2UgMHgzMjIwOgorICAgIGNhc2UgMHgzMjgwOgorICAgIGNhc2UgMHg0RTAwOgorICAgIGNhc2UgMHg1OEYxOgorICAgIGNhc2UgMHg1OEY5OgorICAgIGNhc2UgMHg1RTdBOgorICAgIGNhc2UgMHg1RjBDOgorICAgIGNhc2UgMHhBNjIxOgorICAgIGNhc2UgMHhBNkU2OgorICAgIGNhc2UgMHhBOEQxOgorICAgIGNhc2UgMHhBOTAxOgorICAgIGNhc2UgMHhBOUQxOgorICAgIGNhc2UgMHhBQTUxOgorICAgIGNhc2UgMHhBQkYxOgorICAgIGNhc2UgMHhGRjExOgorI2lmZGVmIFB5X1VOSUNPREVfV0lERQorICAgIGNhc2UgMHgxMDEwNzoKKyAgICBjYXNlIDB4MTAxNDI6CisgICAgY2FzZSAweDEwMTU4OgorICAgIGNhc2UgMHgxMDE1OToKKyAgICBjYXNlIDB4MTAxNUE6CisgICAgY2FzZSAweDEwMzIwOgorICAgIGNhc2UgMHgxMDNEMToKKyAgICBjYXNlIDB4MTA0QTE6CisgICAgY2FzZSAweDEwODU4OgorICAgIGNhc2UgMHgxMDkxNjoKKyAgICBjYXNlIDB4MTBBNDA6CisgICAgY2FzZSAweDEwQTdEOgorICAgIGNhc2UgMHgxMEI1ODoKKyAgICBjYXNlIDB4MTBCNzg6CisgICAgY2FzZSAweDEwRTYwOgorICAgIGNhc2UgMHgxMjQxNToKKyAgICBjYXNlIDB4MTI0MUU6CisgICAgY2FzZSAweDEyNDJDOgorICAgIGNhc2UgMHgxMjQzNDoKKyAgICBjYXNlIDB4MTI0NEY6CisgICAgY2FzZSAweDEyNDU4OgorICAgIGNhc2UgMHgxRDM2MDoKKyAgICBjYXNlIDB4MUQ3Q0Y6CisgICAgY2FzZSAweDFEN0Q5OgorICAgIGNhc2UgMHgxRDdFMzoKKyAgICBjYXNlIDB4MUQ3RUQ6CisgICAgY2FzZSAweDFEN0Y3OgorICAgIGNhc2UgMHgxRjEwMjoKKyAgICBjYXNlIDB4MjA5MkE6CisjZW5kaWYKKyAgICAgICAgcmV0dXJuIChkb3VibGUpIDEuMDsKKyAgICBjYXNlIDB4MjE1MjoKKyAgICAgICAgcmV0dXJuIChkb3VibGUpIDEuMC8xMC4wOworICAgIGNhc2UgMHgwOUY0OgorICAgIGNhc2UgMHhBODMzOgorICAgICAgICByZXR1cm4gKGRvdWJsZSkgMS4wLzE2LjA7CisgICAgY2FzZSAweDAwQkQ6CisgICAgY2FzZSAweDBENzQ6CisgICAgY2FzZSAweDBGMkE6CisgICAgY2FzZSAweDJDRkQ6CisgICAgY2FzZSAweEE4MzE6CisjaWZkZWYgUHlfVU5JQ09ERV9XSURFCisgICAgY2FzZSAweDEwMTQxOgorICAgIGNhc2UgMHgxMDE3NToKKyAgICBjYXNlIDB4MTAxNzY6CisgICAgY2FzZSAweDEwRTdCOgorI2VuZGlmCisgICAgICAgIHJldHVybiAoZG91YmxlKSAxLjAvMi4wOworICAgIGNhc2UgMHgyMTUzOgorI2lmZGVmIFB5X1VOSUNPREVfV0lERQorICAgIGNhc2UgMHgxMEU3RDoKKyAgICBjYXNlIDB4MTI0NUE6CisgICAgY2FzZSAweDEyNDVEOgorI2VuZGlmCisgICAgICAgIHJldHVybiAoZG91YmxlKSAxLjAvMy4wOworICAgIGNhc2UgMHgwMEJDOgorICAgIGNhc2UgMHgwOUY3OgorICAgIGNhc2UgMHgwRDczOgorICAgIGNhc2UgMHhBODMwOgorI2lmZGVmIFB5X1VOSUNPREVfV0lERQorICAgIGNhc2UgMHgxMDE0MDoKKyAgICBjYXNlIDB4MTBFN0M6CisgICAgY2FzZSAweDEyNDYwOgorICAgIGNhc2UgMHgxMjQ2MjoKKyNlbmRpZgorICAgICAgICByZXR1cm4gKGRvdWJsZSkgMS4wLzQuMDsKKyAgICBjYXNlIDB4MjE1NToKKyAgICAgICAgcmV0dXJuIChkb3VibGUpIDEuMC81LjA7CisgICAgY2FzZSAweDIxNTk6CisjaWZkZWYgUHlfVU5JQ09ERV9XSURFCisgICAgY2FzZSAweDEyNDYxOgorI2VuZGlmCisgICAgICAgIHJldHVybiAoZG91YmxlKSAxLjAvNi4wOworICAgIGNhc2UgMHgyMTUwOgorICAgICAgICByZXR1cm4gKGRvdWJsZSkgMS4wLzcuMDsKKyAgICBjYXNlIDB4MDlGNToKKyAgICBjYXNlIDB4MjE1QjoKKyAgICBjYXNlIDB4QTgzNDoKKyNpZmRlZiBQeV9VTklDT0RFX1dJREUKKyAgICBjYXNlIDB4MTI0NUY6CisjZW5kaWYKKyAgICAgICAgcmV0dXJuIChkb3VibGUpIDEuMC84LjA7CisgICAgY2FzZSAweDIxNTE6CisgICAgICAgIHJldHVybiAoZG91YmxlKSAxLjAvOS4wOworICAgIGNhc2UgMHgwQkYwOgorICAgIGNhc2UgMHgwRDcwOgorICAgIGNhc2UgMHgxMzcyOgorICAgIGNhc2UgMHgyMTY5OgorICAgIGNhc2UgMHgyMTc5OgorICAgIGNhc2UgMHgyNDY5OgorICAgIGNhc2UgMHgyNDdEOgorICAgIGNhc2UgMHgyNDkxOgorICAgIGNhc2UgMHgyNEZFOgorICAgIGNhc2UgMHgyNzdGOgorICAgIGNhc2UgMHgyNzg5OgorICAgIGNhc2UgMHgyNzkzOgorICAgIGNhc2UgMHgzMDM4OgorICAgIGNhc2UgMHgzMjI5OgorICAgIGNhc2UgMHgzMjg5OgorICAgIGNhc2UgMHg0RUMwOgorICAgIGNhc2UgMHg1MzQxOgorICAgIGNhc2UgMHg2MkZFOgorICAgIGNhc2UgMHhGOTczOgorICAgIGNhc2UgMHhGOUZEOgorI2lmZGVmIFB5X1VOSUNPREVfV0lERQorICAgIGNhc2UgMHgxMDExMDoKKyAgICBjYXNlIDB4MTAxNDk6CisgICAgY2FzZSAweDEwMTUwOgorICAgIGNhc2UgMHgxMDE1NzoKKyAgICBjYXNlIDB4MTAxNjA6CisgICAgY2FzZSAweDEwMTYxOgorICAgIGNhc2UgMHgxMDE2MjoKKyAgICBjYXNlIDB4MTAxNjM6CisgICAgY2FzZSAweDEwMTY0OgorICAgIGNhc2UgMHgxMDMyMjoKKyAgICBjYXNlIDB4MTAzRDM6CisgICAgY2FzZSAweDEwODVCOgorICAgIGNhc2UgMHgxMDkxNzoKKyAgICBjYXNlIDB4MTBBNDQ6CisgICAgY2FzZSAweDEwQjVDOgorICAgIGNhc2UgMHgxMEI3QzoKKyAgICBjYXNlIDB4MTBFNjk6CisgICAgY2FzZSAweDFEMzY5OgorI2VuZGlmCisgICAgICAgIHJldHVybiAoZG91YmxlKSAxMC4wOworICAgIGNhc2UgMHgwQkYxOgorICAgIGNhc2UgMHgwRDcxOgorICAgIGNhc2UgMHgxMzdCOgorICAgIGNhc2UgMHgyMTZEOgorICAgIGNhc2UgMHgyMTdEOgorICAgIGNhc2UgMHg0RjcwOgorICAgIGNhc2UgMHg3NjdFOgorICAgIGNhc2UgMHg5NjRDOgorI2lmZGVmIFB5X1VOSUNPREVfV0lERQorICAgIGNhc2UgMHgxMDExOToKKyAgICBjYXNlIDB4MTAxNEI6CisgICAgY2FzZSAweDEwMTUyOgorICAgIGNhc2UgMHgxMDE2QToKKyAgICBjYXNlIDB4MTAzRDU6CisgICAgY2FzZSAweDEwODVEOgorICAgIGNhc2UgMHgxMDkxOToKKyAgICBjYXNlIDB4MTBBNDY6CisgICAgY2FzZSAweDEwQjVFOgorICAgIGNhc2UgMHgxMEI3RToKKyAgICBjYXNlIDB4MTBFNzI6CisjZW5kaWYKKyAgICAgICAgcmV0dXJuIChkb3VibGUpIDEwMC4wOworICAgIGNhc2UgMHgwQkYyOgorICAgIGNhc2UgMHgwRDcyOgorICAgIGNhc2UgMHgyMTZGOgorICAgIGNhc2UgMHgyMTdGOgorICAgIGNhc2UgMHgyMTgwOgorICAgIGNhc2UgMHg0RURGOgorICAgIGNhc2UgMHg1MzQzOgorICAgIGNhc2UgMHg5NjIxOgorI2lmZGVmIFB5X1VOSUNPREVfV0lERQorICAgIGNhc2UgMHgxMDEyMjoKKyAgICBjYXNlIDB4MTAxNEQ6CisgICAgY2FzZSAweDEwMTU0OgorICAgIGNhc2UgMHgxMDE3MToKKyAgICBjYXNlIDB4MTA4NUU6CisgICAgY2FzZSAweDEwQTQ3OgorICAgIGNhc2UgMHgxMEI1RjoKKyAgICBjYXNlIDB4MTBCN0Y6CisjZW5kaWYKKyAgICAgICAgcmV0dXJuIChkb3VibGUpIDEwMDAuMDsKKyAgICBjYXNlIDB4MTM3QzoKKyAgICBjYXNlIDB4MjE4MjoKKyAgICBjYXNlIDB4NEUwNzoKKyAgICBjYXNlIDB4ODQyQzoKKyNpZmRlZiBQeV9VTklDT0RFX1dJREUKKyAgICBjYXNlIDB4MTAxMkI6CisgICAgY2FzZSAweDEwMTU1OgorICAgIGNhc2UgMHgxMDg1RjoKKyNlbmRpZgorICAgICAgICByZXR1cm4gKGRvdWJsZSkgMTAwMDAuMDsKKyAgICBjYXNlIDB4MjE4ODoKKyAgICAgICAgcmV0dXJuIChkb3VibGUpIDEwMDAwMC4wOworICAgIGNhc2UgMHg0RUJGOgorICAgIGNhc2UgMHg1MTA0OgorICAgICAgICByZXR1cm4gKGRvdWJsZSkgMTAwMDAwMDAwLjA7CisgICAgY2FzZSAweDUxNDY6CisgICAgICAgIHJldHVybiAoZG91YmxlKSAxMDAwMDAwMDAwMDAwLjA7CisgICAgY2FzZSAweDIxNkE6CisgICAgY2FzZSAweDIxN0E6CisgICAgY2FzZSAweDI0NkE6CisgICAgY2FzZSAweDI0N0U6CisgICAgY2FzZSAweDI0OTI6CisgICAgY2FzZSAweDI0RUI6CisgICAgICAgIHJldHVybiAoZG91YmxlKSAxMS4wOworICAgIGNhc2UgMHgwRjJGOgorICAgICAgICByZXR1cm4gKGRvdWJsZSkgMTEuMC8yLjA7CisgICAgY2FzZSAweDIxNkI6CisgICAgY2FzZSAweDIxN0I6CisgICAgY2FzZSAweDI0NkI6CisgICAgY2FzZSAweDI0N0Y6CisgICAgY2FzZSAweDI0OTM6CisgICAgY2FzZSAweDI0RUM6CisgICAgICAgIHJldHVybiAoZG91YmxlKSAxMi4wOworICAgIGNhc2UgMHgyNDZDOgorICAgIGNhc2UgMHgyNDgwOgorICAgIGNhc2UgMHgyNDk0OgorICAgIGNhc2UgMHgyNEVEOgorICAgICAgICByZXR1cm4gKGRvdWJsZSkgMTMuMDsKKyAgICBjYXNlIDB4MEYzMDoKKyAgICAgICAgcmV0dXJuIChkb3VibGUpIDEzLjAvMi4wOworICAgIGNhc2UgMHgyNDZEOgorICAgIGNhc2UgMHgyNDgxOgorICAgIGNhc2UgMHgyNDk1OgorICAgIGNhc2UgMHgyNEVFOgorICAgICAgICByZXR1cm4gKGRvdWJsZSkgMTQuMDsKKyAgICBjYXNlIDB4MjQ2RToKKyAgICBjYXNlIDB4MjQ4MjoKKyAgICBjYXNlIDB4MjQ5NjoKKyAgICBjYXNlIDB4MjRFRjoKKyAgICAgICAgcmV0dXJuIChkb3VibGUpIDE1LjA7CisgICAgY2FzZSAweDBGMzE6CisgICAgICAgIHJldHVybiAoZG91YmxlKSAxNS4wLzIuMDsKKyAgICBjYXNlIDB4MDlGOToKKyAgICBjYXNlIDB4MjQ2RjoKKyAgICBjYXNlIDB4MjQ4MzoKKyAgICBjYXNlIDB4MjQ5NzoKKyAgICBjYXNlIDB4MjRGMDoKKyAgICAgICAgcmV0dXJuIChkb3VibGUpIDE2LjA7CisgICAgY2FzZSAweDE2RUU6CisgICAgY2FzZSAweDI0NzA6CisgICAgY2FzZSAweDI0ODQ6CisgICAgY2FzZSAweDI0OTg6CisgICAgY2FzZSAweDI0RjE6CisgICAgICAgIHJldHVybiAoZG91YmxlKSAxNy4wOworICAgIGNhc2UgMHgwRjMyOgorICAgICAgICByZXR1cm4gKGRvdWJsZSkgMTcuMC8yLjA7CisgICAgY2FzZSAweDE2RUY6CisgICAgY2FzZSAweDI0NzE6CisgICAgY2FzZSAweDI0ODU6CisgICAgY2FzZSAweDI0OTk6CisgICAgY2FzZSAweDI0RjI6CisgICAgICAgIHJldHVybiAoZG91YmxlKSAxOC4wOworICAgIGNhc2UgMHgxNkYwOgorICAgIGNhc2UgMHgyNDcyOgorICAgIGNhc2UgMHgyNDg2OgorICAgIGNhc2UgMHgyNDlBOgorICAgIGNhc2UgMHgyNEYzOgorICAgICAgICByZXR1cm4gKGRvdWJsZSkgMTkuMDsKKyAgICBjYXNlIDB4MDAzMjoKKyAgICBjYXNlIDB4MDBCMjoKKyAgICBjYXNlIDB4MDY2MjoKKyAgICBjYXNlIDB4MDZGMjoKKyAgICBjYXNlIDB4MDdDMjoKKyAgICBjYXNlIDB4MDk2ODoKKyAgICBjYXNlIDB4MDlFODoKKyAgICBjYXNlIDB4MEE2ODoKKyAgICBjYXNlIDB4MEFFODoKKyAgICBjYXNlIDB4MEI2ODoKKyAgICBjYXNlIDB4MEJFODoKKyAgICBjYXNlIDB4MEM2ODoKKyAgICBjYXNlIDB4MEM3QToKKyAgICBjYXNlIDB4MEM3RDoKKyAgICBjYXNlIDB4MENFODoKKyAgICBjYXNlIDB4MEQ2ODoKKyAgICBjYXNlIDB4MEU1MjoKKyAgICBjYXNlIDB4MEVEMjoKKyAgICBjYXNlIDB4MEYyMjoKKyAgICBjYXNlIDB4MTA0MjoKKyAgICBjYXNlIDB4MTA5MjoKKyAgICBjYXNlIDB4MTM2QToKKyAgICBjYXNlIDB4MTdFMjoKKyAgICBjYXNlIDB4MTdGMjoKKyAgICBjYXNlIDB4MTgxMjoKKyAgICBjYXNlIDB4MTk0ODoKKyAgICBjYXNlIDB4MTlEMjoKKyAgICBjYXNlIDB4MUE4MjoKKyAgICBjYXNlIDB4MUE5MjoKKyAgICBjYXNlIDB4MUI1MjoKKyAgICBjYXNlIDB4MUJCMjoKKyAgICBjYXNlIDB4MUM0MjoKKyAgICBjYXNlIDB4MUM1MjoKKyAgICBjYXNlIDB4MjA4MjoKKyAgICBjYXNlIDB4MjE2MToKKyAgICBjYXNlIDB4MjE3MToKKyAgICBjYXNlIDB4MjQ2MToKKyAgICBjYXNlIDB4MjQ3NToKKyAgICBjYXNlIDB4MjQ4OToKKyAgICBjYXNlIDB4MjRGNjoKKyAgICBjYXNlIDB4Mjc3NzoKKyAgICBjYXNlIDB4Mjc4MToKKyAgICBjYXNlIDB4Mjc4QjoKKyAgICBjYXNlIDB4MzAyMjoKKyAgICBjYXNlIDB4MzE5MzoKKyAgICBjYXNlIDB4MzIyMToKKyAgICBjYXNlIDB4MzI4MToKKyAgICBjYXNlIDB4MzQ4MzoKKyAgICBjYXNlIDB4NEU4QzoKKyAgICBjYXNlIDB4NTE2OToKKyAgICBjYXNlIDB4NUYwRDoKKyAgICBjYXNlIDB4NUYxMDoKKyAgICBjYXNlIDB4OENBRToKKyAgICBjYXNlIDB4OENCMzoKKyAgICBjYXNlIDB4OEQzMDoKKyAgICBjYXNlIDB4QTYyMjoKKyAgICBjYXNlIDB4QTZFNzoKKyAgICBjYXNlIDB4QThEMjoKKyAgICBjYXNlIDB4QTkwMjoKKyAgICBjYXNlIDB4QTlEMjoKKyAgICBjYXNlIDB4QUE1MjoKKyAgICBjYXNlIDB4QUJGMjoKKyAgICBjYXNlIDB4Rjk3ODoKKyAgICBjYXNlIDB4RkYxMjoKKyNpZmRlZiBQeV9VTklDT0RFX1dJREUKKyAgICBjYXNlIDB4MTAxMDg6CisgICAgY2FzZSAweDEwMTVCOgorICAgIGNhc2UgMHgxMDE1QzoKKyAgICBjYXNlIDB4MTAxNUQ6CisgICAgY2FzZSAweDEwMTVFOgorICAgIGNhc2UgMHgxMDNEMjoKKyAgICBjYXNlIDB4MTA0QTI6CisgICAgY2FzZSAweDEwODU5OgorICAgIGNhc2UgMHgxMDkxQToKKyAgICBjYXNlIDB4MTBBNDE6CisgICAgY2FzZSAweDEwQjU5OgorICAgIGNhc2UgMHgxMEI3OToKKyAgICBjYXNlIDB4MTBFNjE6CisgICAgY2FzZSAweDEyNDAwOgorICAgIGNhc2UgMHgxMjQxNjoKKyAgICBjYXNlIDB4MTI0MUY6CisgICAgY2FzZSAweDEyNDIzOgorICAgIGNhc2UgMHgxMjQyRDoKKyAgICBjYXNlIDB4MTI0MzU6CisgICAgY2FzZSAweDEyNDRBOgorICAgIGNhc2UgMHgxMjQ1MDoKKyAgICBjYXNlIDB4MTI0NTk6CisgICAgY2FzZSAweDFEMzYxOgorICAgIGNhc2UgMHgxRDdEMDoKKyAgICBjYXNlIDB4MUQ3REE6CisgICAgY2FzZSAweDFEN0U0OgorICAgIGNhc2UgMHgxRDdFRToKKyAgICBjYXNlIDB4MUQ3Rjg6CisgICAgY2FzZSAweDFGMTAzOgorICAgIGNhc2UgMHgyMjM5MDoKKyNlbmRpZgorICAgICAgICByZXR1cm4gKGRvdWJsZSkgMi4wOworICAgIGNhc2UgMHgyMTU0OgorI2lmZGVmIFB5X1VOSUNPREVfV0lERQorICAgIGNhc2UgMHgxMDE3NzoKKyAgICBjYXNlIDB4MTBFN0U6CisgICAgY2FzZSAweDEyNDVCOgorICAgIGNhc2UgMHgxMjQ1RToKKyNlbmRpZgorICAgICAgICByZXR1cm4gKGRvdWJsZSkgMi4wLzMuMDsKKyAgICBjYXNlIDB4MjE1NjoKKyAgICAgICAgcmV0dXJuIChkb3VibGUpIDIuMC81LjA7CisgICAgY2FzZSAweDEzNzM6CisgICAgY2FzZSAweDI0NzM6CisgICAgY2FzZSAweDI0ODc6CisgICAgY2FzZSAweDI0OUI6CisgICAgY2FzZSAweDI0RjQ6CisgICAgY2FzZSAweDMwMzk6CisgICAgY2FzZSAweDUzNDQ6CisgICAgY2FzZSAweDVFRkY6CisjaWZkZWYgUHlfVU5JQ09ERV9XSURFCisgICAgY2FzZSAweDEwMTExOgorICAgIGNhc2UgMHgxMDNENDoKKyAgICBjYXNlIDB4MTA4NUM6CisgICAgY2FzZSAweDEwOTE4OgorICAgIGNhc2UgMHgxMEE0NToKKyAgICBjYXNlIDB4MTBCNUQ6CisgICAgY2FzZSAweDEwQjdEOgorICAgIGNhc2UgMHgxMEU2QToKKyAgICBjYXNlIDB4MUQzNkE6CisjZW5kaWYKKyAgICAgICAgcmV0dXJuIChkb3VibGUpIDIwLjA7CisjaWZkZWYgUHlfVU5JQ09ERV9XSURFCisgICAgY2FzZSAweDEwMTFBOgorICAgIGNhc2UgMHgxMEU3MzoKKyAgICAgICAgcmV0dXJuIChkb3VibGUpIDIwMC4wOworI2VuZGlmCisjaWZkZWYgUHlfVU5JQ09ERV9XSURFCisgICAgY2FzZSAweDEwMTIzOgorICAgICAgICByZXR1cm4gKGRvdWJsZSkgMjAwMC4wOworI2VuZGlmCisjaWZkZWYgUHlfVU5JQ09ERV9XSURFCisgICAgY2FzZSAweDEwMTJDOgorICAgICAgICByZXR1cm4gKGRvdWJsZSkgMjAwMDAuMDsKKyNlbmRpZgorICAgIGNhc2UgMHgzMjUxOgorICAgICAgICByZXR1cm4gKGRvdWJsZSkgMjEuMDsKKyAgICBjYXNlIDB4MzI1MjoKKyAgICAgICAgcmV0dXJuIChkb3VibGUpIDIyLjA7CisgICAgY2FzZSAweDMyNTM6CisgICAgICAgIHJldHVybiAoZG91YmxlKSAyMy4wOworICAgIGNhc2UgMHgzMjU0OgorICAgICAgICByZXR1cm4gKGRvdWJsZSkgMjQuMDsKKyAgICBjYXNlIDB4MzI1NToKKyAgICAgICAgcmV0dXJuIChkb3VibGUpIDI1LjA7CisgICAgY2FzZSAweDMyNTY6CisgICAgICAgIHJldHVybiAoZG91YmxlKSAyNi4wOworICAgIGNhc2UgMHgzMjU3OgorICAgICAgICByZXR1cm4gKGRvdWJsZSkgMjcuMDsKKyAgICBjYXNlIDB4MzI1ODoKKyAgICAgICAgcmV0dXJuIChkb3VibGUpIDI4LjA7CisgICAgY2FzZSAweDMyNTk6CisgICAgICAgIHJldHVybiAoZG91YmxlKSAyOS4wOworICAgIGNhc2UgMHgwMDMzOgorICAgIGNhc2UgMHgwMEIzOgorICAgIGNhc2UgMHgwNjYzOgorICAgIGNhc2UgMHgwNkYzOgorICAgIGNhc2UgMHgwN0MzOgorICAgIGNhc2UgMHgwOTY5OgorICAgIGNhc2UgMHgwOUU5OgorICAgIGNhc2UgMHgwQTY5OgorICAgIGNhc2UgMHgwQUU5OgorICAgIGNhc2UgMHgwQjY5OgorICAgIGNhc2UgMHgwQkU5OgorICAgIGNhc2UgMHgwQzY5OgorICAgIGNhc2UgMHgwQzdCOgorICAgIGNhc2UgMHgwQzdFOgorICAgIGNhc2UgMHgwQ0U5OgorICAgIGNhc2UgMHgwRDY5OgorICAgIGNhc2UgMHgwRTUzOgorICAgIGNhc2UgMHgwRUQzOgorICAgIGNhc2UgMHgwRjIzOgorICAgIGNhc2UgMHgxMDQzOgorICAgIGNhc2UgMHgxMDkzOgorICAgIGNhc2UgMHgxMzZCOgorICAgIGNhc2UgMHgxN0UzOgorICAgIGNhc2UgMHgxN0YzOgorICAgIGNhc2UgMHgxODEzOgorICAgIGNhc2UgMHgxOTQ5OgorICAgIGNhc2UgMHgxOUQzOgorICAgIGNhc2UgMHgxQTgzOgorICAgIGNhc2UgMHgxQTkzOgorICAgIGNhc2UgMHgxQjUzOgorICAgIGNhc2UgMHgxQkIzOgorICAgIGNhc2UgMHgxQzQzOgorICAgIGNhc2UgMHgxQzUzOgorICAgIGNhc2UgMHgyMDgzOgorICAgIGNhc2UgMHgyMTYyOgorICAgIGNhc2UgMHgyMTcyOgorICAgIGNhc2UgMHgyNDYyOgorICAgIGNhc2UgMHgyNDc2OgorICAgIGNhc2UgMHgyNDhBOgorICAgIGNhc2UgMHgyNEY3OgorICAgIGNhc2UgMHgyNzc4OgorICAgIGNhc2UgMHgyNzgyOgorICAgIGNhc2UgMHgyNzhDOgorICAgIGNhc2UgMHgzMDIzOgorICAgIGNhc2UgMHgzMTk0OgorICAgIGNhc2UgMHgzMjIyOgorICAgIGNhc2UgMHgzMjgyOgorICAgIGNhc2UgMHg0RTA5OgorICAgIGNhc2UgMHg0RUU4OgorICAgIGNhc2UgMHg1M0MxOgorICAgIGNhc2UgMHg1M0MyOgorICAgIGNhc2UgMHg1M0MzOgorICAgIGNhc2UgMHg1M0M0OgorICAgIGNhc2UgMHg1RjBFOgorICAgIGNhc2UgMHhBNjIzOgorICAgIGNhc2UgMHhBNkU4OgorICAgIGNhc2UgMHhBOEQzOgorICAgIGNhc2UgMHhBOTAzOgorICAgIGNhc2UgMHhBOUQzOgorICAgIGNhc2UgMHhBQTUzOgorICAgIGNhc2UgMHhBQkYzOgorICAgIGNhc2UgMHhGOTZCOgorICAgIGNhc2UgMHhGRjEzOgorI2lmZGVmIFB5X1VOSUNPREVfV0lERQorICAgIGNhc2UgMHgxMDEwOToKKyAgICBjYXNlIDB4MTA0QTM6CisgICAgY2FzZSAweDEwODVBOgorICAgIGNhc2UgMHgxMDkxQjoKKyAgICBjYXNlIDB4MTBBNDI6CisgICAgY2FzZSAweDEwQjVBOgorICAgIGNhc2UgMHgxMEI3QToKKyAgICBjYXNlIDB4MTBFNjI6CisgICAgY2FzZSAweDEyNDAxOgorICAgIGNhc2UgMHgxMjQwODoKKyAgICBjYXNlIDB4MTI0MTc6CisgICAgY2FzZSAweDEyNDIwOgorICAgIGNhc2UgMHgxMjQyNDoKKyAgICBjYXNlIDB4MTI0MjU6CisgICAgY2FzZSAweDEyNDJFOgorICAgIGNhc2UgMHgxMjQyRjoKKyAgICBjYXNlIDB4MTI0MzY6CisgICAgY2FzZSAweDEyNDM3OgorICAgIGNhc2UgMHgxMjQzQToKKyAgICBjYXNlIDB4MTI0M0I6CisgICAgY2FzZSAweDEyNDRCOgorICAgIGNhc2UgMHgxMjQ1MToKKyAgICBjYXNlIDB4MUQzNjI6CisgICAgY2FzZSAweDFEN0QxOgorICAgIGNhc2UgMHgxRDdEQjoKKyAgICBjYXNlIDB4MUQ3RTU6CisgICAgY2FzZSAweDFEN0VGOgorICAgIGNhc2UgMHgxRDdGOToKKyAgICBjYXNlIDB4MUYxMDQ6CisgICAgY2FzZSAweDIwQUZEOgorICAgIGNhc2UgMHgyMEIxOToKKyAgICBjYXNlIDB4MjI5OTg6CisgICAgY2FzZSAweDIzQjFCOgorI2VuZGlmCisgICAgICAgIHJldHVybiAoZG91YmxlKSAzLjA7CisgICAgY2FzZSAweDA5RjY6CisgICAgY2FzZSAweEE4MzU6CisgICAgICAgIHJldHVybiAoZG91YmxlKSAzLjAvMTYuMDsKKyAgICBjYXNlIDB4MEYyQjoKKyAgICAgICAgcmV0dXJuIChkb3VibGUpIDMuMC8yLjA7CisgICAgY2FzZSAweDAwQkU6CisgICAgY2FzZSAweDA5Rjg6CisgICAgY2FzZSAweDBENzU6CisgICAgY2FzZSAweEE4MzI6CisjaWZkZWYgUHlfVU5JQ09ERV9XSURFCisgICAgY2FzZSAweDEwMTc4OgorI2VuZGlmCisgICAgICAgIHJldHVybiAoZG91YmxlKSAzLjAvNC4wOworICAgIGNhc2UgMHgyMTU3OgorICAgICAgICByZXR1cm4gKGRvdWJsZSkgMy4wLzUuMDsKKyAgICBjYXNlIDB4MjE1QzoKKyAgICAgICAgcmV0dXJuIChkb3VibGUpIDMuMC84LjA7CisgICAgY2FzZSAweDEzNzQ6CisgICAgY2FzZSAweDMwM0E6CisgICAgY2FzZSAweDMyNUE6CisgICAgY2FzZSAweDUzNDU6CisjaWZkZWYgUHlfVU5JQ09ERV9XSURFCisgICAgY2FzZSAweDEwMTEyOgorICAgIGNhc2UgMHgxMDE2NToKKyAgICBjYXNlIDB4MTBFNkI6CisgICAgY2FzZSAweDFEMzZCOgorICAgIGNhc2UgMHgyMDk4MzoKKyNlbmRpZgorICAgICAgICByZXR1cm4gKGRvdWJsZSkgMzAuMDsKKyNpZmRlZiBQeV9VTklDT0RFX1dJREUKKyAgICBjYXNlIDB4MTAxMUI6CisgICAgY2FzZSAweDEwMTZCOgorICAgIGNhc2UgMHgxMEU3NDoKKyAgICAgICAgcmV0dXJuIChkb3VibGUpIDMwMC4wOworI2VuZGlmCisjaWZkZWYgUHlfVU5JQ09ERV9XSURFCisgICAgY2FzZSAweDEwMTI0OgorICAgICAgICByZXR1cm4gKGRvdWJsZSkgMzAwMC4wOworI2VuZGlmCisjaWZkZWYgUHlfVU5JQ09ERV9XSURFCisgICAgY2FzZSAweDEwMTJEOgorICAgICAgICByZXR1cm4gKGRvdWJsZSkgMzAwMDAuMDsKKyNlbmRpZgorICAgIGNhc2UgMHgzMjVCOgorICAgICAgICByZXR1cm4gKGRvdWJsZSkgMzEuMDsKKyAgICBjYXNlIDB4MzI1QzoKKyAgICAgICAgcmV0dXJuIChkb3VibGUpIDMyLjA7CisgICAgY2FzZSAweDMyNUQ6CisgICAgICAgIHJldHVybiAoZG91YmxlKSAzMy4wOworICAgIGNhc2UgMHgzMjVFOgorICAgICAgICByZXR1cm4gKGRvdWJsZSkgMzQuMDsKKyAgICBjYXNlIDB4MzI1RjoKKyAgICAgICAgcmV0dXJuIChkb3VibGUpIDM1LjA7CisgICAgY2FzZSAweDMyQjE6CisgICAgICAgIHJldHVybiAoZG91YmxlKSAzNi4wOworICAgIGNhc2UgMHgzMkIyOgorICAgICAgICByZXR1cm4gKGRvdWJsZSkgMzcuMDsKKyAgICBjYXNlIDB4MzJCMzoKKyAgICAgICAgcmV0dXJuIChkb3VibGUpIDM4LjA7CisgICAgY2FzZSAweDMyQjQ6CisgICAgICAgIHJldHVybiAoZG91YmxlKSAzOS4wOworICAgIGNhc2UgMHgwMDM0OgorICAgIGNhc2UgMHgwNjY0OgorICAgIGNhc2UgMHgwNkY0OgorICAgIGNhc2UgMHgwN0M0OgorICAgIGNhc2UgMHgwOTZBOgorICAgIGNhc2UgMHgwOUVBOgorICAgIGNhc2UgMHgwQTZBOgorICAgIGNhc2UgMHgwQUVBOgorICAgIGNhc2UgMHgwQjZBOgorICAgIGNhc2UgMHgwQkVBOgorICAgIGNhc2UgMHgwQzZBOgorICAgIGNhc2UgMHgwQ0VBOgorICAgIGNhc2UgMHgwRDZBOgorICAgIGNhc2UgMHgwRTU0OgorICAgIGNhc2UgMHgwRUQ0OgorICAgIGNhc2UgMHgwRjI0OgorICAgIGNhc2UgMHgxMDQ0OgorICAgIGNhc2UgMHgxMDk0OgorICAgIGNhc2UgMHgxMzZDOgorICAgIGNhc2UgMHgxN0U0OgorICAgIGNhc2UgMHgxN0Y0OgorICAgIGNhc2UgMHgxODE0OgorICAgIGNhc2UgMHgxOTRBOgorICAgIGNhc2UgMHgxOUQ0OgorICAgIGNhc2UgMHgxQTg0OgorICAgIGNhc2UgMHgxQTk0OgorICAgIGNhc2UgMHgxQjU0OgorICAgIGNhc2UgMHgxQkI0OgorICAgIGNhc2UgMHgxQzQ0OgorICAgIGNhc2UgMHgxQzU0OgorICAgIGNhc2UgMHgyMDc0OgorICAgIGNhc2UgMHgyMDg0OgorICAgIGNhc2UgMHgyMTYzOgorICAgIGNhc2UgMHgyMTczOgorICAgIGNhc2UgMHgyNDYzOgorICAgIGNhc2UgMHgyNDc3OgorICAgIGNhc2UgMHgyNDhCOgorICAgIGNhc2UgMHgyNEY4OgorICAgIGNhc2UgMHgyNzc5OgorICAgIGNhc2UgMHgyNzgzOgorICAgIGNhc2UgMHgyNzhEOgorICAgIGNhc2UgMHgzMDI0OgorICAgIGNhc2UgMHgzMTk1OgorICAgIGNhc2UgMHgzMjIzOgorICAgIGNhc2UgMHgzMjgzOgorICAgIGNhc2UgMHg0RTk2OgorICAgIGNhc2UgMHg1NkRCOgorICAgIGNhc2UgMHg4MDg2OgorICAgIGNhc2UgMHhBNjI0OgorICAgIGNhc2UgMHhBNkU5OgorICAgIGNhc2UgMHhBOEQ0OgorICAgIGNhc2UgMHhBOTA0OgorICAgIGNhc2UgMHhBOUQ0OgorICAgIGNhc2UgMHhBQTU0OgorICAgIGNhc2UgMHhBQkY0OgorICAgIGNhc2UgMHhGRjE0OgorI2lmZGVmIFB5X1VOSUNPREVfV0lERQorICAgIGNhc2UgMHgxMDEwQToKKyAgICBjYXNlIDB4MTA0QTQ6CisgICAgY2FzZSAweDEwQTQzOgorICAgIGNhc2UgMHgxMEI1QjoKKyAgICBjYXNlIDB4MTBCN0I6CisgICAgY2FzZSAweDEwRTYzOgorICAgIGNhc2UgMHgxMjQwMjoKKyAgICBjYXNlIDB4MTI0MDk6CisgICAgY2FzZSAweDEyNDBGOgorICAgIGNhc2UgMHgxMjQxODoKKyAgICBjYXNlIDB4MTI0MjE6CisgICAgY2FzZSAweDEyNDI2OgorICAgIGNhc2UgMHgxMjQzMDoKKyAgICBjYXNlIDB4MTI0Mzg6CisgICAgY2FzZSAweDEyNDNDOgorICAgIGNhc2UgMHgxMjQzRDoKKyAgICBjYXNlIDB4MTI0M0U6CisgICAgY2FzZSAweDEyNDNGOgorICAgIGNhc2UgMHgxMjQ0QzoKKyAgICBjYXNlIDB4MTI0NTI6CisgICAgY2FzZSAweDEyNDUzOgorICAgIGNhc2UgMHgxRDM2MzoKKyAgICBjYXNlIDB4MUQ3RDI6CisgICAgY2FzZSAweDFEN0RDOgorICAgIGNhc2UgMHgxRDdFNjoKKyAgICBjYXNlIDB4MUQ3RjA6CisgICAgY2FzZSAweDFEN0ZBOgorICAgIGNhc2UgMHgxRjEwNToKKyAgICBjYXNlIDB4MjAwNjQ6CisgICAgY2FzZSAweDIwMEUyOgorICAgIGNhc2UgMHgyNjI2RDoKKyNlbmRpZgorICAgICAgICByZXR1cm4gKGRvdWJsZSkgNC4wOworICAgIGNhc2UgMHgyMTU4OgorICAgICAgICByZXR1cm4gKGRvdWJsZSkgNC4wLzUuMDsKKyAgICBjYXNlIDB4MTM3NToKKyAgICBjYXNlIDB4MzJCNToKKyAgICBjYXNlIDB4NTM0QzoKKyNpZmRlZiBQeV9VTklDT0RFX1dJREUKKyAgICBjYXNlIDB4MTAxMTM6CisgICAgY2FzZSAweDEwRTZDOgorICAgIGNhc2UgMHgxRDM2QzoKKyAgICBjYXNlIDB4MjA5OEM6CisgICAgY2FzZSAweDIwOTlDOgorI2VuZGlmCisgICAgICAgIHJldHVybiAoZG91YmxlKSA0MC4wOworI2lmZGVmIFB5X1VOSUNPREVfV0lERQorICAgIGNhc2UgMHgxMDExQzoKKyAgICBjYXNlIDB4MTBFNzU6CisgICAgICAgIHJldHVybiAoZG91YmxlKSA0MDAuMDsKKyNlbmRpZgorI2lmZGVmIFB5X1VOSUNPREVfV0lERQorICAgIGNhc2UgMHgxMDEyNToKKyAgICAgICAgcmV0dXJuIChkb3VibGUpIDQwMDAuMDsKKyNlbmRpZgorI2lmZGVmIFB5X1VOSUNPREVfV0lERQorICAgIGNhc2UgMHgxMDEyRToKKyAgICAgICAgcmV0dXJuIChkb3VibGUpIDQwMDAwLjA7CisjZW5kaWYKKyAgICBjYXNlIDB4MzJCNjoKKyAgICAgICAgcmV0dXJuIChkb3VibGUpIDQxLjA7CisgICAgY2FzZSAweDMyQjc6CisgICAgICAgIHJldHVybiAoZG91YmxlKSA0Mi4wOworICAgIGNhc2UgMHgzMkI4OgorICAgICAgICByZXR1cm4gKGRvdWJsZSkgNDMuMDsKKyAgICBjYXNlIDB4MzJCOToKKyAgICAgICAgcmV0dXJuIChkb3VibGUpIDQ0LjA7CisgICAgY2FzZSAweDMyQkE6CisgICAgICAgIHJldHVybiAoZG91YmxlKSA0NS4wOworICAgIGNhc2UgMHgzMkJCOgorICAgICAgICByZXR1cm4gKGRvdWJsZSkgNDYuMDsKKyAgICBjYXNlIDB4MzJCQzoKKyAgICAgICAgcmV0dXJuIChkb3VibGUpIDQ3LjA7CisgICAgY2FzZSAweDMyQkQ6CisgICAgICAgIHJldHVybiAoZG91YmxlKSA0OC4wOworICAgIGNhc2UgMHgzMkJFOgorICAgICAgICByZXR1cm4gKGRvdWJsZSkgNDkuMDsKKyAgICBjYXNlIDB4MDAzNToKKyAgICBjYXNlIDB4MDY2NToKKyAgICBjYXNlIDB4MDZGNToKKyAgICBjYXNlIDB4MDdDNToKKyAgICBjYXNlIDB4MDk2QjoKKyAgICBjYXNlIDB4MDlFQjoKKyAgICBjYXNlIDB4MEE2QjoKKyAgICBjYXNlIDB4MEFFQjoKKyAgICBjYXNlIDB4MEI2QjoKKyAgICBjYXNlIDB4MEJFQjoKKyAgICBjYXNlIDB4MEM2QjoKKyAgICBjYXNlIDB4MENFQjoKKyAgICBjYXNlIDB4MEQ2QjoKKyAgICBjYXNlIDB4MEU1NToKKyAgICBjYXNlIDB4MEVENToKKyAgICBjYXNlIDB4MEYyNToKKyAgICBjYXNlIDB4MTA0NToKKyAgICBjYXNlIDB4MTA5NToKKyAgICBjYXNlIDB4MTM2RDoKKyAgICBjYXNlIDB4MTdFNToKKyAgICBjYXNlIDB4MTdGNToKKyAgICBjYXNlIDB4MTgxNToKKyAgICBjYXNlIDB4MTk0QjoKKyAgICBjYXNlIDB4MTlENToKKyAgICBjYXNlIDB4MUE4NToKKyAgICBjYXNlIDB4MUE5NToKKyAgICBjYXNlIDB4MUI1NToKKyAgICBjYXNlIDB4MUJCNToKKyAgICBjYXNlIDB4MUM0NToKKyAgICBjYXNlIDB4MUM1NToKKyAgICBjYXNlIDB4MjA3NToKKyAgICBjYXNlIDB4MjA4NToKKyAgICBjYXNlIDB4MjE2NDoKKyAgICBjYXNlIDB4MjE3NDoKKyAgICBjYXNlIDB4MjQ2NDoKKyAgICBjYXNlIDB4MjQ3ODoKKyAgICBjYXNlIDB4MjQ4QzoKKyAgICBjYXNlIDB4MjRGOToKKyAgICBjYXNlIDB4Mjc3QToKKyAgICBjYXNlIDB4Mjc4NDoKKyAgICBjYXNlIDB4Mjc4RToKKyAgICBjYXNlIDB4MzAyNToKKyAgICBjYXNlIDB4MzIyNDoKKyAgICBjYXNlIDB4MzI4NDoKKyAgICBjYXNlIDB4MzQwNToKKyAgICBjYXNlIDB4MzgyQToKKyAgICBjYXNlIDB4NEU5NDoKKyAgICBjYXNlIDB4NEYwRDoKKyAgICBjYXNlIDB4QTYyNToKKyAgICBjYXNlIDB4QTZFQToKKyAgICBjYXNlIDB4QThENToKKyAgICBjYXNlIDB4QTkwNToKKyAgICBjYXNlIDB4QTlENToKKyAgICBjYXNlIDB4QUE1NToKKyAgICBjYXNlIDB4QUJGNToKKyAgICBjYXNlIDB4RkYxNToKKyNpZmRlZiBQeV9VTklDT0RFX1dJREUKKyAgICBjYXNlIDB4MTAxMEI6CisgICAgY2FzZSAweDEwMTQzOgorICAgIGNhc2UgMHgxMDE0ODoKKyAgICBjYXNlIDB4MTAxNEY6CisgICAgY2FzZSAweDEwMTVGOgorICAgIGNhc2UgMHgxMDE3MzoKKyAgICBjYXNlIDB4MTAzMjE6CisgICAgY2FzZSAweDEwNEE1OgorICAgIGNhc2UgMHgxMEU2NDoKKyAgICBjYXNlIDB4MTI0MDM6CisgICAgY2FzZSAweDEyNDBBOgorICAgIGNhc2UgMHgxMjQxMDoKKyAgICBjYXNlIDB4MTI0MTk6CisgICAgY2FzZSAweDEyNDIyOgorICAgIGNhc2UgMHgxMjQyNzoKKyAgICBjYXNlIDB4MTI0MzE6CisgICAgY2FzZSAweDEyNDM5OgorICAgIGNhc2UgMHgxMjQ0RDoKKyAgICBjYXNlIDB4MTI0NTQ6CisgICAgY2FzZSAweDEyNDU1OgorICAgIGNhc2UgMHgxRDM2NDoKKyAgICBjYXNlIDB4MUQ3RDM6CisgICAgY2FzZSAweDFEN0REOgorICAgIGNhc2UgMHgxRDdFNzoKKyAgICBjYXNlIDB4MUQ3RjE6CisgICAgY2FzZSAweDFEN0ZCOgorICAgIGNhc2UgMHgxRjEwNjoKKyAgICBjYXNlIDB4MjAxMjE6CisjZW5kaWYKKyAgICAgICAgcmV0dXJuIChkb3VibGUpIDUuMDsKKyAgICBjYXNlIDB4MEYyQzoKKyAgICAgICAgcmV0dXJuIChkb3VibGUpIDUuMC8yLjA7CisgICAgY2FzZSAweDIxNUE6CisjaWZkZWYgUHlfVU5JQ09ERV9XSURFCisgICAgY2FzZSAweDEyNDVDOgorI2VuZGlmCisgICAgICAgIHJldHVybiAoZG91YmxlKSA1LjAvNi4wOworICAgIGNhc2UgMHgyMTVEOgorICAgICAgICByZXR1cm4gKGRvdWJsZSkgNS4wLzguMDsKKyAgICBjYXNlIDB4MTM3NjoKKyAgICBjYXNlIDB4MjE2QzoKKyAgICBjYXNlIDB4MjE3QzoKKyAgICBjYXNlIDB4MjE4NjoKKyAgICBjYXNlIDB4MzJCRjoKKyNpZmRlZiBQeV9VTklDT0RFX1dJREUKKyAgICBjYXNlIDB4MTAxMTQ6CisgICAgY2FzZSAweDEwMTQ0OgorICAgIGNhc2UgMHgxMDE0QToKKyAgICBjYXNlIDB4MTAxNTE6CisgICAgY2FzZSAweDEwMTY2OgorICAgIGNhc2UgMHgxMDE2NzoKKyAgICBjYXNlIDB4MTAxNjg6CisgICAgY2FzZSAweDEwMTY5OgorICAgIGNhc2UgMHgxMDE3NDoKKyAgICBjYXNlIDB4MTAzMjM6CisgICAgY2FzZSAweDEwQTdFOgorICAgIGNhc2UgMHgxMEU2RDoKKyAgICBjYXNlIDB4MUQzNkQ6CisjZW5kaWYKKyAgICAgICAgcmV0dXJuIChkb3VibGUpIDUwLjA7CisgICAgY2FzZSAweDIxNkU6CisgICAgY2FzZSAweDIxN0U6CisjaWZkZWYgUHlfVU5JQ09ERV9XSURFCisgICAgY2FzZSAweDEwMTFEOgorICAgIGNhc2UgMHgxMDE0NToKKyAgICBjYXNlIDB4MTAxNEM6CisgICAgY2FzZSAweDEwMTUzOgorICAgIGNhc2UgMHgxMDE2QzoKKyAgICBjYXNlIDB4MTAxNkQ6CisgICAgY2FzZSAweDEwMTZFOgorICAgIGNhc2UgMHgxMDE2RjoKKyAgICBjYXNlIDB4MTAxNzA6CisgICAgY2FzZSAweDEwRTc2OgorI2VuZGlmCisgICAgICAgIHJldHVybiAoZG91YmxlKSA1MDAuMDsKKyAgICBjYXNlIDB4MjE4MToKKyNpZmRlZiBQeV9VTklDT0RFX1dJREUKKyAgICBjYXNlIDB4MTAxMjY6CisgICAgY2FzZSAweDEwMTQ2OgorICAgIGNhc2UgMHgxMDE0RToKKyAgICBjYXNlIDB4MTAxNzI6CisjZW5kaWYKKyAgICAgICAgcmV0dXJuIChkb3VibGUpIDUwMDAuMDsKKyAgICBjYXNlIDB4MjE4NzoKKyNpZmRlZiBQeV9VTklDT0RFX1dJREUKKyAgICBjYXNlIDB4MTAxMkY6CisgICAgY2FzZSAweDEwMTQ3OgorICAgIGNhc2UgMHgxMDE1NjoKKyNlbmRpZgorICAgICAgICByZXR1cm4gKGRvdWJsZSkgNTAwMDAuMDsKKyAgICBjYXNlIDB4MDAzNjoKKyAgICBjYXNlIDB4MDY2NjoKKyAgICBjYXNlIDB4MDZGNjoKKyAgICBjYXNlIDB4MDdDNjoKKyAgICBjYXNlIDB4MDk2QzoKKyAgICBjYXNlIDB4MDlFQzoKKyAgICBjYXNlIDB4MEE2QzoKKyAgICBjYXNlIDB4MEFFQzoKKyAgICBjYXNlIDB4MEI2QzoKKyAgICBjYXNlIDB4MEJFQzoKKyAgICBjYXNlIDB4MEM2QzoKKyAgICBjYXNlIDB4MENFQzoKKyAgICBjYXNlIDB4MEQ2QzoKKyAgICBjYXNlIDB4MEU1NjoKKyAgICBjYXNlIDB4MEVENjoKKyAgICBjYXNlIDB4MEYyNjoKKyAgICBjYXNlIDB4MTA0NjoKKyAgICBjYXNlIDB4MTA5NjoKKyAgICBjYXNlIDB4MTM2RToKKyAgICBjYXNlIDB4MTdFNjoKKyAgICBjYXNlIDB4MTdGNjoKKyAgICBjYXNlIDB4MTgxNjoKKyAgICBjYXNlIDB4MTk0QzoKKyAgICBjYXNlIDB4MTlENjoKKyAgICBjYXNlIDB4MUE4NjoKKyAgICBjYXNlIDB4MUE5NjoKKyAgICBjYXNlIDB4MUI1NjoKKyAgICBjYXNlIDB4MUJCNjoKKyAgICBjYXNlIDB4MUM0NjoKKyAgICBjYXNlIDB4MUM1NjoKKyAgICBjYXNlIDB4MjA3NjoKKyAgICBjYXNlIDB4MjA4NjoKKyAgICBjYXNlIDB4MjE2NToKKyAgICBjYXNlIDB4MjE3NToKKyAgICBjYXNlIDB4MjE4NToKKyAgICBjYXNlIDB4MjQ2NToKKyAgICBjYXNlIDB4MjQ3OToKKyAgICBjYXNlIDB4MjQ4RDoKKyAgICBjYXNlIDB4MjRGQToKKyAgICBjYXNlIDB4Mjc3QjoKKyAgICBjYXNlIDB4Mjc4NToKKyAgICBjYXNlIDB4Mjc4RjoKKyAgICBjYXNlIDB4MzAyNjoKKyAgICBjYXNlIDB4MzIyNToKKyAgICBjYXNlIDB4MzI4NToKKyAgICBjYXNlIDB4NTE2RDoKKyAgICBjYXNlIDB4OTY0NjoKKyAgICBjYXNlIDB4OTY3ODoKKyAgICBjYXNlIDB4QTYyNjoKKyAgICBjYXNlIDB4QTZFQjoKKyAgICBjYXNlIDB4QThENjoKKyAgICBjYXNlIDB4QTkwNjoKKyAgICBjYXNlIDB4QTlENjoKKyAgICBjYXNlIDB4QUE1NjoKKyAgICBjYXNlIDB4QUJGNjoKKyAgICBjYXNlIDB4RjlEMToKKyAgICBjYXNlIDB4RjlEMzoKKyAgICBjYXNlIDB4RkYxNjoKKyNpZmRlZiBQeV9VTklDT0RFX1dJREUKKyAgICBjYXNlIDB4MTAxMEM6CisgICAgY2FzZSAweDEwNEE2OgorICAgIGNhc2UgMHgxMEU2NToKKyAgICBjYXNlIDB4MTI0MDQ6CisgICAgY2FzZSAweDEyNDBCOgorICAgIGNhc2UgMHgxMjQxMToKKyAgICBjYXNlIDB4MTI0MUE6CisgICAgY2FzZSAweDEyNDI4OgorICAgIGNhc2UgMHgxMjQ0MDoKKyAgICBjYXNlIDB4MTI0NEU6CisgICAgY2FzZSAweDFEMzY1OgorICAgIGNhc2UgMHgxRDdENDoKKyAgICBjYXNlIDB4MUQ3REU6CisgICAgY2FzZSAweDFEN0U4OgorICAgIGNhc2UgMHgxRDdGMjoKKyAgICBjYXNlIDB4MUQ3RkM6CisgICAgY2FzZSAweDFGMTA3OgorICAgIGNhc2UgMHgyMEFFQToKKyNlbmRpZgorICAgICAgICByZXR1cm4gKGRvdWJsZSkgNi4wOworICAgIGNhc2UgMHgxMzc3OgorI2lmZGVmIFB5X1VOSUNPREVfV0lERQorICAgIGNhc2UgMHgxMDExNToKKyAgICBjYXNlIDB4MTBFNkU6CisgICAgY2FzZSAweDFEMzZFOgorI2VuZGlmCisgICAgICAgIHJldHVybiAoZG91YmxlKSA2MC4wOworI2lmZGVmIFB5X1VOSUNPREVfV0lERQorICAgIGNhc2UgMHgxMDExRToKKyAgICBjYXNlIDB4MTBFNzc6CisgICAgICAgIHJldHVybiAoZG91YmxlKSA2MDAuMDsKKyNlbmRpZgorI2lmZGVmIFB5X1VOSUNPREVfV0lERQorICAgIGNhc2UgMHgxMDEyNzoKKyAgICAgICAgcmV0dXJuIChkb3VibGUpIDYwMDAuMDsKKyNlbmRpZgorI2lmZGVmIFB5X1VOSUNPREVfV0lERQorICAgIGNhc2UgMHgxMDEzMDoKKyAgICAgICAgcmV0dXJuIChkb3VibGUpIDYwMDAwLjA7CisjZW5kaWYKKyAgICBjYXNlIDB4MDAzNzoKKyAgICBjYXNlIDB4MDY2NzoKKyAgICBjYXNlIDB4MDZGNzoKKyAgICBjYXNlIDB4MDdDNzoKKyAgICBjYXNlIDB4MDk2RDoKKyAgICBjYXNlIDB4MDlFRDoKKyAgICBjYXNlIDB4MEE2RDoKKyAgICBjYXNlIDB4MEFFRDoKKyAgICBjYXNlIDB4MEI2RDoKKyAgICBjYXNlIDB4MEJFRDoKKyAgICBjYXNlIDB4MEM2RDoKKyAgICBjYXNlIDB4MENFRDoKKyAgICBjYXNlIDB4MEQ2RDoKKyAgICBjYXNlIDB4MEU1NzoKKyAgICBjYXNlIDB4MEVENzoKKyAgICBjYXNlIDB4MEYyNzoKKyAgICBjYXNlIDB4MTA0NzoKKyAgICBjYXNlIDB4MTA5NzoKKyAgICBjYXNlIDB4MTM2RjoKKyAgICBjYXNlIDB4MTdFNzoKKyAgICBjYXNlIDB4MTdGNzoKKyAgICBjYXNlIDB4MTgxNzoKKyAgICBjYXNlIDB4MTk0RDoKKyAgICBjYXNlIDB4MTlENzoKKyAgICBjYXNlIDB4MUE4NzoKKyAgICBjYXNlIDB4MUE5NzoKKyAgICBjYXNlIDB4MUI1NzoKKyAgICBjYXNlIDB4MUJCNzoKKyAgICBjYXNlIDB4MUM0NzoKKyAgICBjYXNlIDB4MUM1NzoKKyAgICBjYXNlIDB4MjA3NzoKKyAgICBjYXNlIDB4MjA4NzoKKyAgICBjYXNlIDB4MjE2NjoKKyAgICBjYXNlIDB4MjE3NjoKKyAgICBjYXNlIDB4MjQ2NjoKKyAgICBjYXNlIDB4MjQ3QToKKyAgICBjYXNlIDB4MjQ4RToKKyAgICBjYXNlIDB4MjRGQjoKKyAgICBjYXNlIDB4Mjc3QzoKKyAgICBjYXNlIDB4Mjc4NjoKKyAgICBjYXNlIDB4Mjc5MDoKKyAgICBjYXNlIDB4MzAyNzoKKyAgICBjYXNlIDB4MzIyNjoKKyAgICBjYXNlIDB4MzI4NjoKKyAgICBjYXNlIDB4M0I0RDoKKyAgICBjYXNlIDB4NEUwMzoKKyAgICBjYXNlIDB4NjdEMjoKKyAgICBjYXNlIDB4NkYwNjoKKyAgICBjYXNlIDB4QTYyNzoKKyAgICBjYXNlIDB4QTZFQzoKKyAgICBjYXNlIDB4QThENzoKKyAgICBjYXNlIDB4QTkwNzoKKyAgICBjYXNlIDB4QTlENzoKKyAgICBjYXNlIDB4QUE1NzoKKyAgICBjYXNlIDB4QUJGNzoKKyAgICBjYXNlIDB4RkYxNzoKKyNpZmRlZiBQeV9VTklDT0RFX1dJREUKKyAgICBjYXNlIDB4MTAxMEQ6CisgICAgY2FzZSAweDEwNEE3OgorICAgIGNhc2UgMHgxMEU2NjoKKyAgICBjYXNlIDB4MTI0MDU6CisgICAgY2FzZSAweDEyNDBDOgorICAgIGNhc2UgMHgxMjQxMjoKKyAgICBjYXNlIDB4MTI0MUI6CisgICAgY2FzZSAweDEyNDI5OgorICAgIGNhc2UgMHgxMjQ0MToKKyAgICBjYXNlIDB4MTI0NDI6CisgICAgY2FzZSAweDEyNDQzOgorICAgIGNhc2UgMHgxRDM2NjoKKyAgICBjYXNlIDB4MUQ3RDU6CisgICAgY2FzZSAweDFEN0RGOgorICAgIGNhc2UgMHgxRDdFOToKKyAgICBjYXNlIDB4MUQ3RjM6CisgICAgY2FzZSAweDFEN0ZEOgorICAgIGNhc2UgMHgxRjEwODoKKyAgICBjYXNlIDB4MjAwMDE6CisjZW5kaWYKKyAgICAgICAgcmV0dXJuIChkb3VibGUpIDcuMDsKKyAgICBjYXNlIDB4MEYyRDoKKyAgICAgICAgcmV0dXJuIChkb3VibGUpIDcuMC8yLjA7CisgICAgY2FzZSAweDIxNUU6CisgICAgICAgIHJldHVybiAoZG91YmxlKSA3LjAvOC4wOworICAgIGNhc2UgMHgxMzc4OgorI2lmZGVmIFB5X1VOSUNPREVfV0lERQorICAgIGNhc2UgMHgxMDExNjoKKyAgICBjYXNlIDB4MTBFNkY6CisgICAgY2FzZSAweDFEMzZGOgorI2VuZGlmCisgICAgICAgIHJldHVybiAoZG91YmxlKSA3MC4wOworI2lmZGVmIFB5X1VOSUNPREVfV0lERQorICAgIGNhc2UgMHgxMDExRjoKKyAgICBjYXNlIDB4MTBFNzg6CisgICAgICAgIHJldHVybiAoZG91YmxlKSA3MDAuMDsKKyNlbmRpZgorI2lmZGVmIFB5X1VOSUNPREVfV0lERQorICAgIGNhc2UgMHgxMDEyODoKKyAgICAgICAgcmV0dXJuIChkb3VibGUpIDcwMDAuMDsKKyNlbmRpZgorI2lmZGVmIFB5X1VOSUNPREVfV0lERQorICAgIGNhc2UgMHgxMDEzMToKKyAgICAgICAgcmV0dXJuIChkb3VibGUpIDcwMDAwLjA7CisjZW5kaWYKKyAgICBjYXNlIDB4MDAzODoKKyAgICBjYXNlIDB4MDY2ODoKKyAgICBjYXNlIDB4MDZGODoKKyAgICBjYXNlIDB4MDdDODoKKyAgICBjYXNlIDB4MDk2RToKKyAgICBjYXNlIDB4MDlFRToKKyAgICBjYXNlIDB4MEE2RToKKyAgICBjYXNlIDB4MEFFRToKKyAgICBjYXNlIDB4MEI2RToKKyAgICBjYXNlIDB4MEJFRToKKyAgICBjYXNlIDB4MEM2RToKKyAgICBjYXNlIDB4MENFRToKKyAgICBjYXNlIDB4MEQ2RToKKyAgICBjYXNlIDB4MEU1ODoKKyAgICBjYXNlIDB4MEVEODoKKyAgICBjYXNlIDB4MEYyODoKKyAgICBjYXNlIDB4MTA0ODoKKyAgICBjYXNlIDB4MTA5ODoKKyAgICBjYXNlIDB4MTM3MDoKKyAgICBjYXNlIDB4MTdFODoKKyAgICBjYXNlIDB4MTdGODoKKyAgICBjYXNlIDB4MTgxODoKKyAgICBjYXNlIDB4MTk0RToKKyAgICBjYXNlIDB4MTlEODoKKyAgICBjYXNlIDB4MUE4ODoKKyAgICBjYXNlIDB4MUE5ODoKKyAgICBjYXNlIDB4MUI1ODoKKyAgICBjYXNlIDB4MUJCODoKKyAgICBjYXNlIDB4MUM0ODoKKyAgICBjYXNlIDB4MUM1ODoKKyAgICBjYXNlIDB4MjA3ODoKKyAgICBjYXNlIDB4MjA4ODoKKyAgICBjYXNlIDB4MjE2NzoKKyAgICBjYXNlIDB4MjE3NzoKKyAgICBjYXNlIDB4MjQ2NzoKKyAgICBjYXNlIDB4MjQ3QjoKKyAgICBjYXNlIDB4MjQ4RjoKKyAgICBjYXNlIDB4MjRGQzoKKyAgICBjYXNlIDB4Mjc3RDoKKyAgICBjYXNlIDB4Mjc4NzoKKyAgICBjYXNlIDB4Mjc5MToKKyAgICBjYXNlIDB4MzAyODoKKyAgICBjYXNlIDB4MzIyNzoKKyAgICBjYXNlIDB4MzI4NzoKKyAgICBjYXNlIDB4NTE2QjoKKyAgICBjYXNlIDB4NjM0QzoKKyAgICBjYXNlIDB4QTYyODoKKyAgICBjYXNlIDB4QTZFRDoKKyAgICBjYXNlIDB4QThEODoKKyAgICBjYXNlIDB4QTkwODoKKyAgICBjYXNlIDB4QTlEODoKKyAgICBjYXNlIDB4QUE1ODoKKyAgICBjYXNlIDB4QUJGODoKKyAgICBjYXNlIDB4RkYxODoKKyNpZmRlZiBQeV9VTklDT0RFX1dJREUKKyAgICBjYXNlIDB4MTAxMEU6CisgICAgY2FzZSAweDEwNEE4OgorICAgIGNhc2UgMHgxMEU2NzoKKyAgICBjYXNlIDB4MTI0MDY6CisgICAgY2FzZSAweDEyNDBEOgorICAgIGNhc2UgMHgxMjQxMzoKKyAgICBjYXNlIDB4MTI0MUM6CisgICAgY2FzZSAweDEyNDJBOgorICAgIGNhc2UgMHgxMjQ0NDoKKyAgICBjYXNlIDB4MTI0NDU6CisgICAgY2FzZSAweDFEMzY3OgorICAgIGNhc2UgMHgxRDdENjoKKyAgICBjYXNlIDB4MUQ3RTA6CisgICAgY2FzZSAweDFEN0VBOgorICAgIGNhc2UgMHgxRDdGNDoKKyAgICBjYXNlIDB4MUQ3RkU6CisgICAgY2FzZSAweDFGMTA5OgorI2VuZGlmCisgICAgICAgIHJldHVybiAoZG91YmxlKSA4LjA7CisgICAgY2FzZSAweDEzNzk6CisjaWZkZWYgUHlfVU5JQ09ERV9XSURFCisgICAgY2FzZSAweDEwMTE3OgorICAgIGNhc2UgMHgxMEU3MDoKKyAgICBjYXNlIDB4MUQzNzA6CisjZW5kaWYKKyAgICAgICAgcmV0dXJuIChkb3VibGUpIDgwLjA7CisjaWZkZWYgUHlfVU5JQ09ERV9XSURFCisgICAgY2FzZSAweDEwMTIwOgorICAgIGNhc2UgMHgxMEU3OToKKyAgICAgICAgcmV0dXJuIChkb3VibGUpIDgwMC4wOworI2VuZGlmCisjaWZkZWYgUHlfVU5JQ09ERV9XSURFCisgICAgY2FzZSAweDEwMTI5OgorICAgICAgICByZXR1cm4gKGRvdWJsZSkgODAwMC4wOworI2VuZGlmCisjaWZkZWYgUHlfVU5JQ09ERV9XSURFCisgICAgY2FzZSAweDEwMTMyOgorICAgICAgICByZXR1cm4gKGRvdWJsZSkgODAwMDAuMDsKKyNlbmRpZgorICAgIGNhc2UgMHgwMDM5OgorICAgIGNhc2UgMHgwNjY5OgorICAgIGNhc2UgMHgwNkY5OgorICAgIGNhc2UgMHgwN0M5OgorICAgIGNhc2UgMHgwOTZGOgorICAgIGNhc2UgMHgwOUVGOgorICAgIGNhc2UgMHgwQTZGOgorICAgIGNhc2UgMHgwQUVGOgorICAgIGNhc2UgMHgwQjZGOgorICAgIGNhc2UgMHgwQkVGOgorICAgIGNhc2UgMHgwQzZGOgorICAgIGNhc2UgMHgwQ0VGOgorICAgIGNhc2UgMHgwRDZGOgorICAgIGNhc2UgMHgwRTU5OgorICAgIGNhc2UgMHgwRUQ5OgorICAgIGNhc2UgMHgwRjI5OgorICAgIGNhc2UgMHgxMDQ5OgorICAgIGNhc2UgMHgxMDk5OgorICAgIGNhc2UgMHgxMzcxOgorICAgIGNhc2UgMHgxN0U5OgorICAgIGNhc2UgMHgxN0Y5OgorICAgIGNhc2UgMHgxODE5OgorICAgIGNhc2UgMHgxOTRGOgorICAgIGNhc2UgMHgxOUQ5OgorICAgIGNhc2UgMHgxQTg5OgorICAgIGNhc2UgMHgxQTk5OgorICAgIGNhc2UgMHgxQjU5OgorICAgIGNhc2UgMHgxQkI5OgorICAgIGNhc2UgMHgxQzQ5OgorICAgIGNhc2UgMHgxQzU5OgorICAgIGNhc2UgMHgyMDc5OgorICAgIGNhc2UgMHgyMDg5OgorICAgIGNhc2UgMHgyMTY4OgorICAgIGNhc2UgMHgyMTc4OgorICAgIGNhc2UgMHgyNDY4OgorICAgIGNhc2UgMHgyNDdDOgorICAgIGNhc2UgMHgyNDkwOgorICAgIGNhc2UgMHgyNEZEOgorICAgIGNhc2UgMHgyNzdFOgorICAgIGNhc2UgMHgyNzg4OgorICAgIGNhc2UgMHgyNzkyOgorICAgIGNhc2UgMHgzMDI5OgorICAgIGNhc2UgMHgzMjI4OgorICAgIGNhc2UgMHgzMjg4OgorICAgIGNhc2UgMHg0RTVEOgorICAgIGNhc2UgMHg1RUZFOgorICAgIGNhc2UgMHg3Mzk2OgorICAgIGNhc2UgMHhBNjI5OgorICAgIGNhc2UgMHhBNkVFOgorICAgIGNhc2UgMHhBOEQ5OgorICAgIGNhc2UgMHhBOTA5OgorICAgIGNhc2UgMHhBOUQ5OgorICAgIGNhc2UgMHhBQTU5OgorICAgIGNhc2UgMHhBQkY5OgorICAgIGNhc2UgMHhGRjE5OgorI2lmZGVmIFB5X1VOSUNPREVfV0lERQorICAgIGNhc2UgMHgxMDEwRjoKKyAgICBjYXNlIDB4MTA0QTk6CisgICAgY2FzZSAweDEwRTY4OgorICAgIGNhc2UgMHgxMjQwNzoKKyAgICBjYXNlIDB4MTI0MEU6CisgICAgY2FzZSAweDEyNDE0OgorICAgIGNhc2UgMHgxMjQxRDoKKyAgICBjYXNlIDB4MTI0MkI6CisgICAgY2FzZSAweDEyNDQ2OgorICAgIGNhc2UgMHgxMjQ0NzoKKyAgICBjYXNlIDB4MTI0NDg6CisgICAgY2FzZSAweDEyNDQ5OgorICAgIGNhc2UgMHgxRDM2ODoKKyAgICBjYXNlIDB4MUQ3RDc6CisgICAgY2FzZSAweDFEN0UxOgorICAgIGNhc2UgMHgxRDdFQjoKKyAgICBjYXNlIDB4MUQ3RjU6CisgICAgY2FzZSAweDFEN0ZGOgorICAgIGNhc2UgMHgxRjEwQToKKyAgICBjYXNlIDB4MkY4OTA6CisjZW5kaWYKKyAgICAgICAgcmV0dXJuIChkb3VibGUpIDkuMDsKKyAgICBjYXNlIDB4MEYyRToKKyAgICAgICAgcmV0dXJuIChkb3VibGUpIDkuMC8yLjA7CisgICAgY2FzZSAweDEzN0E6CisjaWZkZWYgUHlfVU5JQ09ERV9XSURFCisgICAgY2FzZSAweDEwMTE4OgorICAgIGNhc2UgMHgxMDM0MToKKyAgICBjYXNlIDB4MTBFNzE6CisgICAgY2FzZSAweDFEMzcxOgorI2VuZGlmCisgICAgICAgIHJldHVybiAoZG91YmxlKSA5MC4wOworI2lmZGVmIFB5X1VOSUNPREVfV0lERQorICAgIGNhc2UgMHgxMDEyMToKKyAgICBjYXNlIDB4MTAzNEE6CisgICAgY2FzZSAweDEwRTdBOgorICAgICAgICByZXR1cm4gKGRvdWJsZSkgOTAwLjA7CisjZW5kaWYKKyNpZmRlZiBQeV9VTklDT0RFX1dJREUKKyAgICBjYXNlIDB4MTAxMkE6CisgICAgICAgIHJldHVybiAoZG91YmxlKSA5MDAwLjA7CisjZW5kaWYKKyNpZmRlZiBQeV9VTklDT0RFX1dJREUKKyAgICBjYXNlIDB4MTAxMzM6CisgICAgICAgIHJldHVybiAoZG91YmxlKSA5MDAwMC4wOworI2VuZGlmCisgICAgfQorICAgIHJldHVybiAtMS4wOworfQorCisvKiBSZXR1cm5zIDEgZm9yIFVuaWNvZGUgY2hhcmFjdGVycyBoYXZpbmcgdGhlIGJpZGlyZWN0aW9uYWwKKyAqIHR5cGUgJ1dTJywgJ0InIG9yICdTJyBvciB0aGUgY2F0ZWdvcnkgJ1pzJywgMCBvdGhlcndpc2UuCisgKi8KK2ludCBfUHlVbmljb2RlX0lzV2hpdGVzcGFjZShyZWdpc3RlciBjb25zdCBQeV9VTklDT0RFIGNoKQoreworI2lmZGVmIFdBTlRfV0NUWVBFX0ZVTkNUSU9OUworICAgIHJldHVybiBpc3dzcGFjZShjaCk7CisjZWxzZQorICAgIHN3aXRjaCAoY2gpIHsKKyAgICBjYXNlIDB4MDAwOToKKyAgICBjYXNlIDB4MDAwQToKKyAgICBjYXNlIDB4MDAwQjoKKyAgICBjYXNlIDB4MDAwQzoKKyAgICBjYXNlIDB4MDAwRDoKKyAgICBjYXNlIDB4MDAxQzoKKyAgICBjYXNlIDB4MDAxRDoKKyAgICBjYXNlIDB4MDAxRToKKyAgICBjYXNlIDB4MDAxRjoKKyAgICBjYXNlIDB4MDAyMDoKKyAgICBjYXNlIDB4MDA4NToKKyAgICBjYXNlIDB4MDBBMDoKKyAgICBjYXNlIDB4MTY4MDoKKyAgICBjYXNlIDB4MTgwRToKKyAgICBjYXNlIDB4MjAwMDoKKyAgICBjYXNlIDB4MjAwMToKKyAgICBjYXNlIDB4MjAwMjoKKyAgICBjYXNlIDB4MjAwMzoKKyAgICBjYXNlIDB4MjAwNDoKKyAgICBjYXNlIDB4MjAwNToKKyAgICBjYXNlIDB4MjAwNjoKKyAgICBjYXNlIDB4MjAwNzoKKyAgICBjYXNlIDB4MjAwODoKKyAgICBjYXNlIDB4MjAwOToKKyAgICBjYXNlIDB4MjAwQToKKyAgICBjYXNlIDB4MjAyODoKKyAgICBjYXNlIDB4MjAyOToKKyAgICBjYXNlIDB4MjAyRjoKKyAgICBjYXNlIDB4MjA1RjoKKyAgICBjYXNlIDB4MzAwMDoKKyAgICAgICAgcmV0dXJuIDE7CisgICAgfQorICAgIHJldHVybiAwOworI2VuZGlmCit9CisKKy8qIFJldHVybnMgMSBmb3IgVW5pY29kZSBjaGFyYWN0ZXJzIGhhdmluZyB0aGUgbGluZSBicmVhaworICogcHJvcGVydHkgJ0JLJywgJ0NSJywgJ0xGJyBvciAnTkwnIG9yIGhhdmluZyBiaWRpcmVjdGlvbmFsCisgKiB0eXBlICdCJywgMCBvdGhlcndpc2UuCisgKi8KK2ludCBfUHlVbmljb2RlX0lzTGluZWJyZWFrKHJlZ2lzdGVyIGNvbnN0IFB5X1VOSUNPREUgY2gpCit7CisgICAgc3dpdGNoIChjaCkgeworICAgIGNhc2UgMHgwMDBBOgorICAgIGNhc2UgMHgwMDBCOgorICAgIGNhc2UgMHgwMDBDOgorICAgIGNhc2UgMHgwMDBEOgorICAgIGNhc2UgMHgwMDFDOgorICAgIGNhc2UgMHgwMDFEOgorICAgIGNhc2UgMHgwMDFFOgorICAgIGNhc2UgMHgwMDg1OgorICAgIGNhc2UgMHgyMDI4OgorICAgIGNhc2UgMHgyMDI5OgorICAgICAgICByZXR1cm4gMTsKKyAgICB9CisgICAgcmV0dXJuIDA7Cit9CisKZGlmZiAtLWdpdCBhL1B5dGhvbi0yLjcuNS9PYmplY3RzL3dlYWtyZWZvYmplY3QuYyBiL1B5dGhvbi0yLjcuNS9PYmplY3RzL3dlYWtyZWZvYmplY3QuYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44NzFjMjQ4Ci0tLSAvZGV2L251bGwKKysrIGIvUHl0aG9uLTIuNy41L09iamVjdHMvd2Vha3JlZm9iamVjdC5jCkBAIC0wLDAgKzEsOTg0IEBACisjaW5jbHVkZSAiUHl0aG9uLmgiCisjaW5jbHVkZSAic3RydWN0bWVtYmVyLmgiCisKKworI2RlZmluZSBHRVRfV0VBS1JFRlNfTElTVFBUUihvKSBcCisgICAgICAgICgoUHlXZWFrUmVmZXJlbmNlICoqKSBQeU9iamVjdF9HRVRfV0VBS1JFRlNfTElTVFBUUihvKSkKKworCitQeV9zc2l6ZV90CitfUHlXZWFrcmVmX0dldFdlYWtyZWZDb3VudChQeVdlYWtSZWZlcmVuY2UgKmhlYWQpCit7CisgICAgUHlfc3NpemVfdCBjb3VudCA9IDA7CisKKyAgICB3aGlsZSAoaGVhZCAhPSBOVUxMKSB7CisgICAgICAgICsrY291bnQ7CisgICAgICAgIGhlYWQgPSBoZWFkLT53cl9uZXh0OworICAgIH0KKyAgICByZXR1cm4gY291bnQ7Cit9CisKKworc3RhdGljIHZvaWQKK2luaXRfd2Vha3JlZihQeVdlYWtSZWZlcmVuY2UgKnNlbGYsIFB5T2JqZWN0ICpvYiwgUHlPYmplY3QgKmNhbGxiYWNrKQoreworICAgIHNlbGYtPmhhc2ggPSAtMTsKKyAgICBzZWxmLT53cl9vYmplY3QgPSBvYjsKKyAgICBQeV9YSU5DUkVGKGNhbGxiYWNrKTsKKyAgICBzZWxmLT53cl9jYWxsYmFjayA9IGNhbGxiYWNrOworfQorCitzdGF0aWMgUHlXZWFrUmVmZXJlbmNlICoKK25ld193ZWFrcmVmKFB5T2JqZWN0ICpvYiwgUHlPYmplY3QgKmNhbGxiYWNrKQoreworICAgIFB5V2Vha1JlZmVyZW5jZSAqcmVzdWx0OworCisgICAgcmVzdWx0ID0gUHlPYmplY3RfR0NfTmV3KFB5V2Vha1JlZmVyZW5jZSwgJl9QeVdlYWtyZWZfUmVmVHlwZSk7CisgICAgaWYgKHJlc3VsdCkgeworICAgICAgICBpbml0X3dlYWtyZWYocmVzdWx0LCBvYiwgY2FsbGJhY2spOworICAgICAgICBQeU9iamVjdF9HQ19UcmFjayhyZXN1bHQpOworICAgIH0KKyAgICByZXR1cm4gcmVzdWx0OworfQorCisKKy8qIFRoaXMgZnVuY3Rpb24gY2xlYXJzIHRoZSBwYXNzZWQtaW4gcmVmZXJlbmNlIGFuZCByZW1vdmVzIGl0IGZyb20gdGhlCisgKiBsaXN0IG9mIHdlYWsgcmVmZXJlbmNlcyBmb3IgdGhlIHJlZmVyZW50LiAgVGhpcyBpcyB0aGUgb25seSBjb2RlIHRoYXQKKyAqIHJlbW92ZXMgYW4gaXRlbSBmcm9tIHRoZSBkb3VibHktbGlua2VkIGxpc3Qgb2Ygd2VhayByZWZlcmVuY2VzIGZvciBhbgorICogb2JqZWN0OyBpdCBpcyBhbHNvIHJlc3BvbnNpYmxlIGZvciBjbGVhcmluZyB0aGUgY2FsbGJhY2sgc2xvdC4KKyAqLworc3RhdGljIHZvaWQKK2NsZWFyX3dlYWtyZWYoUHlXZWFrUmVmZXJlbmNlICpzZWxmKQoreworICAgIFB5T2JqZWN0ICpjYWxsYmFjayA9IHNlbGYtPndyX2NhbGxiYWNrOworCisgICAgaWYgKHNlbGYtPndyX29iamVjdCAhPSBQeV9Ob25lKSB7CisgICAgICAgIFB5V2Vha1JlZmVyZW5jZSAqKmxpc3QgPSBHRVRfV0VBS1JFRlNfTElTVFBUUihzZWxmLT53cl9vYmplY3QpOworCisgICAgICAgIGlmICgqbGlzdCA9PSBzZWxmKQorICAgICAgICAgICAgLyogSWYgJ3NlbGYnIGlzIHRoZSBlbmQgb2YgdGhlIGxpc3QgKGFuZCB0aHVzIHNlbGYtPndyX25leHQgPT0gTlVMTCkKKyAgICAgICAgICAgICAgIHRoZW4gdGhlIHdlYWtyZWYgbGlzdCBpdHNlbGYgKGFuZCB0aHVzIHRoZSB2YWx1ZSBvZiAqbGlzdCkgd2lsbAorICAgICAgICAgICAgICAgZW5kIHVwIGJlaW5nIHNldCB0byBOVUxMLiAqLworICAgICAgICAgICAgKmxpc3QgPSBzZWxmLT53cl9uZXh0OworICAgICAgICBzZWxmLT53cl9vYmplY3QgPSBQeV9Ob25lOworICAgICAgICBpZiAoc2VsZi0+d3JfcHJldiAhPSBOVUxMKQorICAgICAgICAgICAgc2VsZi0+d3JfcHJldi0+d3JfbmV4dCA9IHNlbGYtPndyX25leHQ7CisgICAgICAgIGlmIChzZWxmLT53cl9uZXh0ICE9IE5VTEwpCisgICAgICAgICAgICBzZWxmLT53cl9uZXh0LT53cl9wcmV2ID0gc2VsZi0+d3JfcHJldjsKKyAgICAgICAgc2VsZi0+d3JfcHJldiA9IE5VTEw7CisgICAgICAgIHNlbGYtPndyX25leHQgPSBOVUxMOworICAgIH0KKyAgICBpZiAoY2FsbGJhY2sgIT0gTlVMTCkgeworICAgICAgICBQeV9ERUNSRUYoY2FsbGJhY2spOworICAgICAgICBzZWxmLT53cl9jYWxsYmFjayA9IE5VTEw7CisgICAgfQorfQorCisvKiBDeWNsaWMgZ2MgdXNlcyB0aGlzIHRvICpqdXN0KiBjbGVhciB0aGUgcGFzc2VkLWluIHJlZmVyZW5jZSwgbGVhdmluZworICogdGhlIGNhbGxiYWNrIGludGFjdCBhbmQgdW5jYWxsZWQuICBJdCBtdXN0IGJlIHBvc3NpYmxlIHRvIGNhbGwgc2VsZidzCisgKiB0cF9kZWFsbG9jKCkgYWZ0ZXIgY2FsbGluZyB0aGlzLCBzbyBzZWxmIGhhcyB0byBiZSBsZWZ0IGluIGEgc2FuZSBlbm91Z2gKKyAqIHN0YXRlIGZvciB0aGF0IHRvIHdvcmsuICBXZSBleHBlY3QgdHBfZGVhbGxvYyB0byBkZWNyZWYgdGhlIGNhbGxiYWNrCisgKiB0aGVuLiAgVGhlIHJlYXNvbiBmb3Igbm90IGxldHRpbmcgY2xlYXJfd2Vha3JlZigpIGRlY3JlZiB0aGUgY2FsbGJhY2sKKyAqIHJpZ2h0IG5vdyBpcyB0aGF0IGlmIHRoZSBjYWxsYmFjayBnb2VzIGF3YXksIHRoYXQgbWF5IGluIHR1cm4gdHJpZ2dlcgorICogYW5vdGhlciBjYWxsYmFjayAoaWYgYSB3ZWFrIHJlZmVyZW5jZSB0byB0aGUgY2FsbGJhY2sgZXhpc3RzKSAtLSBydW5uaW5nCisgKiBhcmJpdHJhcnkgUHl0aG9uIGNvZGUgaW4gdGhlIG1pZGRsZSBvZiBnYyBpcyBhIGRpc2FzdGVyLiAgVGhlIGNvbnZvbHV0aW9uCisgKiBoZXJlIGFsbG93cyBnYyB0byBkZWxheSB0cmlnZ2VyaW5nIHN1Y2ggY2FsbGJhY2tzIHVudGlsIHRoZSB3b3JsZCBpcyBpbgorICogYSBzYW5lIHN0YXRlIGFnYWluLgorICovCit2b2lkCitfUHlXZWFrcmVmX0NsZWFyUmVmKFB5V2Vha1JlZmVyZW5jZSAqc2VsZikKK3sKKyAgICBQeU9iamVjdCAqY2FsbGJhY2s7CisKKyAgICBhc3NlcnQoc2VsZiAhPSBOVUxMKTsKKyAgICBhc3NlcnQoUHlXZWFrcmVmX0NoZWNrKHNlbGYpKTsKKyAgICAvKiBQcmVzZXJ2ZSBhbmQgcmVzdG9yZSB0aGUgY2FsbGJhY2sgYXJvdW5kIGNsZWFyX3dlYWtyZWYuICovCisgICAgY2FsbGJhY2sgPSBzZWxmLT53cl9jYWxsYmFjazsKKyAgICBzZWxmLT53cl9jYWxsYmFjayA9IE5VTEw7CisgICAgY2xlYXJfd2Vha3JlZihzZWxmKTsKKyAgICBzZWxmLT53cl9jYWxsYmFjayA9IGNhbGxiYWNrOworfQorCitzdGF0aWMgdm9pZAord2Vha3JlZl9kZWFsbG9jKFB5T2JqZWN0ICpzZWxmKQoreworICAgIFB5T2JqZWN0X0dDX1VuVHJhY2soc2VsZik7CisgICAgY2xlYXJfd2Vha3JlZigoUHlXZWFrUmVmZXJlbmNlICopIHNlbGYpOworICAgIFB5X1RZUEUoc2VsZiktPnRwX2ZyZWUoc2VsZik7Cit9CisKKworc3RhdGljIGludAorZ2NfdHJhdmVyc2UoUHlXZWFrUmVmZXJlbmNlICpzZWxmLCB2aXNpdHByb2MgdmlzaXQsIHZvaWQgKmFyZykKK3sKKyAgICBQeV9WSVNJVChzZWxmLT53cl9jYWxsYmFjayk7CisgICAgcmV0dXJuIDA7Cit9CisKKworc3RhdGljIGludAorZ2NfY2xlYXIoUHlXZWFrUmVmZXJlbmNlICpzZWxmKQoreworICAgIGNsZWFyX3dlYWtyZWYoc2VsZik7CisgICAgcmV0dXJuIDA7Cit9CisKKworc3RhdGljIFB5T2JqZWN0ICoKK3dlYWtyZWZfY2FsbChQeVdlYWtSZWZlcmVuY2UgKnNlbGYsIFB5T2JqZWN0ICphcmdzLCBQeU9iamVjdCAqa3cpCit7CisgICAgc3RhdGljIGNoYXIgKmt3bGlzdFtdID0ge05VTEx9OworCisgICAgaWYgKFB5QXJnX1BhcnNlVHVwbGVBbmRLZXl3b3JkcyhhcmdzLCBrdywgIjpfX2NhbGxfXyIsIGt3bGlzdCkpIHsKKyAgICAgICAgUHlPYmplY3QgKm9iamVjdCA9IFB5V2Vha3JlZl9HRVRfT0JKRUNUKHNlbGYpOworICAgICAgICBQeV9JTkNSRUYob2JqZWN0KTsKKyAgICAgICAgcmV0dXJuIChvYmplY3QpOworICAgIH0KKyAgICByZXR1cm4gTlVMTDsKK30KKworCitzdGF0aWMgbG9uZword2Vha3JlZl9oYXNoKFB5V2Vha1JlZmVyZW5jZSAqc2VsZikKK3sKKyAgICBpZiAoc2VsZi0+aGFzaCAhPSAtMSkKKyAgICAgICAgcmV0dXJuIHNlbGYtPmhhc2g7CisgICAgaWYgKFB5V2Vha3JlZl9HRVRfT0JKRUNUKHNlbGYpID09IFB5X05vbmUpIHsKKyAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1R5cGVFcnJvciwgIndlYWsgb2JqZWN0IGhhcyBnb25lIGF3YXkiKTsKKyAgICAgICAgcmV0dXJuIC0xOworICAgIH0KKyAgICBzZWxmLT5oYXNoID0gUHlPYmplY3RfSGFzaChQeVdlYWtyZWZfR0VUX09CSkVDVChzZWxmKSk7CisgICAgcmV0dXJuIHNlbGYtPmhhc2g7Cit9CisKKworc3RhdGljIFB5T2JqZWN0ICoKK3dlYWtyZWZfcmVwcihQeVdlYWtSZWZlcmVuY2UgKnNlbGYpCit7CisgICAgY2hhciBidWZmZXJbMjU2XTsKKyAgICBpZiAoUHlXZWFrcmVmX0dFVF9PQkpFQ1Qoc2VsZikgPT0gUHlfTm9uZSkgeworICAgICAgICBQeU9TX3NucHJpbnRmKGJ1ZmZlciwgc2l6ZW9mKGJ1ZmZlciksICI8d2Vha3JlZiBhdCAlcDsgZGVhZD4iLCBzZWxmKTsKKyAgICB9CisgICAgZWxzZSB7CisgICAgICAgIGNoYXIgKm5hbWUgPSBOVUxMOworICAgICAgICBQeU9iamVjdCAqbmFtZW9iaiA9IFB5T2JqZWN0X0dldEF0dHJTdHJpbmcoUHlXZWFrcmVmX0dFVF9PQkpFQ1Qoc2VsZiksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiX19uYW1lX18iKTsKKyAgICAgICAgaWYgKG5hbWVvYmogPT0gTlVMTCkKKyAgICAgICAgICAgICAgICBQeUVycl9DbGVhcigpOworICAgICAgICBlbHNlIGlmIChQeVN0cmluZ19DaGVjayhuYW1lb2JqKSkKKyAgICAgICAgICAgICAgICBuYW1lID0gUHlTdHJpbmdfQVNfU1RSSU5HKG5hbWVvYmopOworICAgICAgICBpZiAobmFtZSAhPSBOVUxMKSB7CisgICAgICAgICAgICBQeU9TX3NucHJpbnRmKGJ1ZmZlciwgc2l6ZW9mKGJ1ZmZlciksCisgICAgICAgICAgICAgICAgICAgICAgICAgICI8d2Vha3JlZiBhdCAlcDsgdG8gJyUuNTBzJyBhdCAlcCAoJXMpPiIsCisgICAgICAgICAgICAgICAgICAgICAgICAgIHNlbGYsCisgICAgICAgICAgICAgICAgICAgICAgICAgIFB5X1RZUEUoUHlXZWFrcmVmX0dFVF9PQkpFQ1Qoc2VsZikpLT50cF9uYW1lLAorICAgICAgICAgICAgICAgICAgICAgICAgICBQeVdlYWtyZWZfR0VUX09CSkVDVChzZWxmKSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZSk7CisgICAgICAgIH0KKyAgICAgICAgZWxzZSB7CisgICAgICAgICAgICBQeU9TX3NucHJpbnRmKGJ1ZmZlciwgc2l6ZW9mKGJ1ZmZlciksCisgICAgICAgICAgICAgICAgICAgICAgICAgICI8d2Vha3JlZiBhdCAlcDsgdG8gJyUuNTBzJyBhdCAlcD4iLAorICAgICAgICAgICAgICAgICAgICAgICAgICBzZWxmLAorICAgICAgICAgICAgICAgICAgICAgICAgICBQeV9UWVBFKFB5V2Vha3JlZl9HRVRfT0JKRUNUKHNlbGYpKS0+dHBfbmFtZSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgUHlXZWFrcmVmX0dFVF9PQkpFQ1Qoc2VsZikpOworICAgICAgICB9CisgICAgICAgIFB5X1hERUNSRUYobmFtZW9iaik7CisgICAgfQorICAgIHJldHVybiBQeVN0cmluZ19Gcm9tU3RyaW5nKGJ1ZmZlcik7Cit9CisKKy8qIFdlYWsgcmVmZXJlbmNlcyBvbmx5IHN1cHBvcnQgZXF1YWxpdHksIG5vdCBvcmRlcmluZy4gVHdvIHdlYWsgcmVmZXJlbmNlcworICAgYXJlIGVxdWFsIGlmIHRoZSB1bmRlcmx5aW5nIG9iamVjdHMgYXJlIGVxdWFsLiBJZiB0aGUgdW5kZXJseWluZyBvYmplY3QgaGFzCisgICBnb25lIGF3YXksIHRoZXkgYXJlIGVxdWFsIGlmIHRoZXkgYXJlIGlkZW50aWNhbC4gKi8KKworc3RhdGljIFB5T2JqZWN0ICoKK3dlYWtyZWZfcmljaGNvbXBhcmUoUHlXZWFrUmVmZXJlbmNlKiBzZWxmLCBQeVdlYWtSZWZlcmVuY2UqIG90aGVyLCBpbnQgb3ApCit7CisgICAgaWYgKChvcCAhPSBQeV9FUSAmJiBvcCAhPSBQeV9ORSkgfHwgc2VsZi0+b2JfdHlwZSAhPSBvdGhlci0+b2JfdHlwZSkgeworICAgICAgICBQeV9JTkNSRUYoUHlfTm90SW1wbGVtZW50ZWQpOworICAgICAgICByZXR1cm4gUHlfTm90SW1wbGVtZW50ZWQ7CisgICAgfQorICAgIGlmIChQeVdlYWtyZWZfR0VUX09CSkVDVChzZWxmKSA9PSBQeV9Ob25lCisgICAgICAgIHx8IFB5V2Vha3JlZl9HRVRfT0JKRUNUKG90aGVyKSA9PSBQeV9Ob25lKSB7CisgICAgICAgIGludCByZXMgPSAoc2VsZiA9PSBvdGhlcik7CisgICAgICAgIGlmIChvcCA9PSBQeV9ORSkKKyAgICAgICAgICAgIHJlcyA9ICFyZXM7CisgICAgICAgIGlmIChyZXMpCisgICAgICAgICAgICBQeV9SRVRVUk5fVFJVRTsKKyAgICAgICAgZWxzZQorICAgICAgICAgICAgUHlfUkVUVVJOX0ZBTFNFOworICAgIH0KKyAgICByZXR1cm4gUHlPYmplY3RfUmljaENvbXBhcmUoUHlXZWFrcmVmX0dFVF9PQkpFQ1Qoc2VsZiksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFB5V2Vha3JlZl9HRVRfT0JKRUNUKG90aGVyKSwgb3ApOworfQorCisvKiBHaXZlbiB0aGUgaGVhZCBvZiBhbiBvYmplY3QncyBsaXN0IG9mIHdlYWsgcmVmZXJlbmNlcywgZXh0cmFjdCB0aGUKKyAqIHR3byBjYWxsYmFjay1sZXNzIHJlZnMgKHJlZiBhbmQgcHJveHkpLiAgVXNlZCB0byBkZXRlcm1pbmUgaWYgdGhlCisgKiBzaGFyZWQgcmVmZXJlbmNlcyBleGlzdCBhbmQgdG8gZGV0ZXJtaW5lIHRoZSBiYWNrIGxpbmsgZm9yIG5ld2x5CisgKiBpbnNlcnRlZCByZWZlcmVuY2VzLgorICovCitzdGF0aWMgdm9pZAorZ2V0X2Jhc2ljX3JlZnMoUHlXZWFrUmVmZXJlbmNlICpoZWFkLAorICAgICAgICAgICAgICAgUHlXZWFrUmVmZXJlbmNlICoqcmVmcCwgUHlXZWFrUmVmZXJlbmNlICoqcHJveHlwKQoreworICAgICpyZWZwID0gTlVMTDsKKyAgICAqcHJveHlwID0gTlVMTDsKKworICAgIGlmIChoZWFkICE9IE5VTEwgJiYgaGVhZC0+d3JfY2FsbGJhY2sgPT0gTlVMTCkgeworICAgICAgICAvKiBXZSBuZWVkIHRvIGJlIGNhcmVmdWwgdGhhdCB0aGUgImJhc2ljIHJlZnMiIGFyZW4ndAorICAgICAgICAgICBzdWJjbGFzc2VzIG9mIHRoZSBtYWluIHR5cGVzLiAgVGhhdCBjb21wbGljYXRlcyB0aGlzIGEKKyAgICAgICAgICAgbGl0dGxlLiAqLworICAgICAgICBpZiAoUHlXZWFrcmVmX0NoZWNrUmVmRXhhY3QoaGVhZCkpIHsKKyAgICAgICAgICAgICpyZWZwID0gaGVhZDsKKyAgICAgICAgICAgIGhlYWQgPSBoZWFkLT53cl9uZXh0OworICAgICAgICB9CisgICAgICAgIGlmIChoZWFkICE9IE5VTEwKKyAgICAgICAgICAgICYmIGhlYWQtPndyX2NhbGxiYWNrID09IE5VTEwKKyAgICAgICAgICAgICYmIFB5V2Vha3JlZl9DaGVja1Byb3h5KGhlYWQpKSB7CisgICAgICAgICAgICAqcHJveHlwID0gaGVhZDsKKyAgICAgICAgICAgIC8qIGhlYWQgPSBoZWFkLT53cl9uZXh0OyAqLworICAgICAgICB9CisgICAgfQorfQorCisvKiBJbnNlcnQgJ25ld3JlZicgaW4gdGhlIGxpc3QgYWZ0ZXIgJ3ByZXYnLiAgQm90aCBtdXN0IGJlIG5vbi1OVUxMLiAqLworc3RhdGljIHZvaWQKK2luc2VydF9hZnRlcihQeVdlYWtSZWZlcmVuY2UgKm5ld3JlZiwgUHlXZWFrUmVmZXJlbmNlICpwcmV2KQoreworICAgIG5ld3JlZi0+d3JfcHJldiA9IHByZXY7CisgICAgbmV3cmVmLT53cl9uZXh0ID0gcHJldi0+d3JfbmV4dDsKKyAgICBpZiAocHJldi0+d3JfbmV4dCAhPSBOVUxMKQorICAgICAgICBwcmV2LT53cl9uZXh0LT53cl9wcmV2ID0gbmV3cmVmOworICAgIHByZXYtPndyX25leHQgPSBuZXdyZWY7Cit9CisKKy8qIEluc2VydCAnbmV3cmVmJyBhdCB0aGUgaGVhZCBvZiB0aGUgbGlzdDsgJ2xpc3QnIHBvaW50cyB0byB0aGUgdmFyaWFibGUKKyAqIHRoYXQgc3RvcmVzIHRoZSBoZWFkLgorICovCitzdGF0aWMgdm9pZAoraW5zZXJ0X2hlYWQoUHlXZWFrUmVmZXJlbmNlICpuZXdyZWYsIFB5V2Vha1JlZmVyZW5jZSAqKmxpc3QpCit7CisgICAgUHlXZWFrUmVmZXJlbmNlICpuZXh0ID0gKmxpc3Q7CisKKyAgICBuZXdyZWYtPndyX3ByZXYgPSBOVUxMOworICAgIG5ld3JlZi0+d3JfbmV4dCA9IG5leHQ7CisgICAgaWYgKG5leHQgIT0gTlVMTCkKKyAgICAgICAgbmV4dC0+d3JfcHJldiA9IG5ld3JlZjsKKyAgICAqbGlzdCA9IG5ld3JlZjsKK30KKworc3RhdGljIGludAorcGFyc2Vfd2Vha3JlZl9pbml0X2FyZ3MoY2hhciAqZnVuY25hbWUsIFB5T2JqZWN0ICphcmdzLCBQeU9iamVjdCAqa3dhcmdzLAorICAgICAgICAgICAgICAgICAgICAgICAgUHlPYmplY3QgKipvYnAsIFB5T2JqZWN0ICoqY2FsbGJhY2twKQoreworICAgIC8qIFhYWCBTaG91bGQgY2hlY2sgdGhhdCBrd2FyZ3MgPT0gTlVMTCBvciBpcyBlbXB0eS4gKi8KKyAgICByZXR1cm4gUHlBcmdfVW5wYWNrVHVwbGUoYXJncywgZnVuY25hbWUsIDEsIDIsIG9icCwgY2FsbGJhY2twKTsKK30KKworc3RhdGljIFB5T2JqZWN0ICoKK3dlYWtyZWZfX19uZXdfXyhQeVR5cGVPYmplY3QgKnR5cGUsIFB5T2JqZWN0ICphcmdzLCBQeU9iamVjdCAqa3dhcmdzKQoreworICAgIFB5V2Vha1JlZmVyZW5jZSAqc2VsZiA9IE5VTEw7CisgICAgUHlPYmplY3QgKm9iLCAqY2FsbGJhY2sgPSBOVUxMOworCisgICAgaWYgKHBhcnNlX3dlYWtyZWZfaW5pdF9hcmdzKCJfX25ld19fIiwgYXJncywga3dhcmdzLCAmb2IsICZjYWxsYmFjaykpIHsKKyAgICAgICAgUHlXZWFrUmVmZXJlbmNlICpyZWYsICpwcm94eTsKKyAgICAgICAgUHlXZWFrUmVmZXJlbmNlICoqbGlzdDsKKworICAgICAgICBpZiAoIVB5VHlwZV9TVVBQT1JUU19XRUFLUkVGUyhQeV9UWVBFKG9iKSkpIHsKKyAgICAgICAgICAgIFB5RXJyX0Zvcm1hdChQeUV4Y19UeXBlRXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAgICAgImNhbm5vdCBjcmVhdGUgd2VhayByZWZlcmVuY2UgdG8gJyVzJyBvYmplY3QiLAorICAgICAgICAgICAgICAgICAgICAgICAgIFB5X1RZUEUob2IpLT50cF9uYW1lKTsKKyAgICAgICAgICAgIHJldHVybiBOVUxMOworICAgICAgICB9CisgICAgICAgIGlmIChjYWxsYmFjayA9PSBQeV9Ob25lKQorICAgICAgICAgICAgY2FsbGJhY2sgPSBOVUxMOworICAgICAgICBsaXN0ID0gR0VUX1dFQUtSRUZTX0xJU1RQVFIob2IpOworICAgICAgICBnZXRfYmFzaWNfcmVmcygqbGlzdCwgJnJlZiwgJnByb3h5KTsKKyAgICAgICAgaWYgKGNhbGxiYWNrID09IE5VTEwgJiYgdHlwZSA9PSAmX1B5V2Vha3JlZl9SZWZUeXBlKSB7CisgICAgICAgICAgICBpZiAocmVmICE9IE5VTEwpIHsKKyAgICAgICAgICAgICAgICAvKiBXZSBjYW4gcmUtdXNlIGFuIGV4aXN0aW5nIHJlZmVyZW5jZS4gKi8KKyAgICAgICAgICAgICAgICBQeV9JTkNSRUYocmVmKTsKKyAgICAgICAgICAgICAgICByZXR1cm4gKFB5T2JqZWN0ICopcmVmOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIC8qIFdlIGhhdmUgdG8gY3JlYXRlIGEgbmV3IHJlZmVyZW5jZS4gKi8KKyAgICAgICAgLyogTm90ZTogdGhlIHRwX2FsbG9jKCkgY2FuIHRyaWdnZXIgY3ljbGljIEdDLCBzbyB0aGUgd2Vha3JlZgorICAgICAgICAgICBsaXN0IG9uIG9iIGNhbiBiZSBtdXRhdGVkLiAgVGhpcyBtZWFucyB0aGF0IHRoZSByZWYgYW5kCisgICAgICAgICAgIHByb3h5IHBvaW50ZXJzIHdlIGdvdCBiYWNrIGVhcmxpZXIgbWF5IGhhdmUgYmVlbiBjb2xsZWN0ZWQsCisgICAgICAgICAgIHNvIHdlIG5lZWQgdG8gY29tcHV0ZSB0aGVzZSB2YWx1ZXMgYWdhaW4gYmVmb3JlIHdlIHVzZQorICAgICAgICAgICB0aGVtLiAqLworICAgICAgICBzZWxmID0gKFB5V2Vha1JlZmVyZW5jZSAqKSAodHlwZS0+dHBfYWxsb2ModHlwZSwgMCkpOworICAgICAgICBpZiAoc2VsZiAhPSBOVUxMKSB7CisgICAgICAgICAgICBpbml0X3dlYWtyZWYoc2VsZiwgb2IsIGNhbGxiYWNrKTsKKyAgICAgICAgICAgIGlmIChjYWxsYmFjayA9PSBOVUxMICYmIHR5cGUgPT0gJl9QeVdlYWtyZWZfUmVmVHlwZSkgeworICAgICAgICAgICAgICAgIGluc2VydF9oZWFkKHNlbGYsIGxpc3QpOworICAgICAgICAgICAgfQorICAgICAgICAgICAgZWxzZSB7CisgICAgICAgICAgICAgICAgUHlXZWFrUmVmZXJlbmNlICpwcmV2OworCisgICAgICAgICAgICAgICAgZ2V0X2Jhc2ljX3JlZnMoKmxpc3QsICZyZWYsICZwcm94eSk7CisgICAgICAgICAgICAgICAgcHJldiA9IChwcm94eSA9PSBOVUxMKSA/IHJlZiA6IHByb3h5OworICAgICAgICAgICAgICAgIGlmIChwcmV2ID09IE5VTEwpCisgICAgICAgICAgICAgICAgICAgIGluc2VydF9oZWFkKHNlbGYsIGxpc3QpOworICAgICAgICAgICAgICAgIGVsc2UKKyAgICAgICAgICAgICAgICAgICAgaW5zZXJ0X2FmdGVyKHNlbGYsIHByZXYpOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQorICAgIHJldHVybiAoUHlPYmplY3QgKilzZWxmOworfQorCitzdGF0aWMgaW50Cit3ZWFrcmVmX19faW5pdF9fKFB5T2JqZWN0ICpzZWxmLCBQeU9iamVjdCAqYXJncywgUHlPYmplY3QgKmt3YXJncykKK3sKKyAgICBQeU9iamVjdCAqdG1wOworCisgICAgaWYgKHBhcnNlX3dlYWtyZWZfaW5pdF9hcmdzKCJfX2luaXRfXyIsIGFyZ3MsIGt3YXJncywgJnRtcCwgJnRtcCkpCisgICAgICAgIHJldHVybiAwOworICAgIGVsc2UKKyAgICAgICAgcmV0dXJuIC0xOworfQorCisKK1B5VHlwZU9iamVjdAorX1B5V2Vha3JlZl9SZWZUeXBlID0geworICAgIFB5VmFyT2JqZWN0X0hFQURfSU5JVCgmUHlUeXBlX1R5cGUsIDApCisgICAgIndlYWtyZWYiLAorICAgIHNpemVvZihQeVdlYWtSZWZlcmVuY2UpLAorICAgIDAsCisgICAgd2Vha3JlZl9kZWFsbG9jLCAgICAgICAgICAgIC8qdHBfZGVhbGxvYyovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgIC8qdHBfcHJpbnQqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAvKnRwX2dldGF0dHIqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAvKnRwX3NldGF0dHIqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAvKnRwX2NvbXBhcmUqLworICAgIChyZXByZnVuYyl3ZWFrcmVmX3JlcHIsICAgICAvKnRwX3JlcHIqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAvKnRwX2FzX251bWJlciovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgIC8qdHBfYXNfc2VxdWVuY2UqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAvKnRwX2FzX21hcHBpbmcqLworICAgIChoYXNoZnVuYyl3ZWFrcmVmX2hhc2gsICAgICAvKnRwX2hhc2gqLworICAgICh0ZXJuYXJ5ZnVuYyl3ZWFrcmVmX2NhbGwsICAvKnRwX2NhbGwqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAvKnRwX3N0ciovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgIC8qdHBfZ2V0YXR0cm8qLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAvKnRwX3NldGF0dHJvKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgLyp0cF9hc19idWZmZXIqLworICAgIFB5X1RQRkxBR1NfREVGQVVMVCB8IFB5X1RQRkxBR1NfSEFWRV9HQyB8IFB5X1RQRkxBR1NfSEFWRV9SSUNIQ09NUEFSRQorICAgICAgICB8IFB5X1RQRkxBR1NfQkFTRVRZUEUsICAvKnRwX2ZsYWdzKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgLyp0cF9kb2MqLworICAgICh0cmF2ZXJzZXByb2MpZ2NfdHJhdmVyc2UsICAvKnRwX3RyYXZlcnNlKi8KKyAgICAoaW5xdWlyeSlnY19jbGVhciwgICAgICAgICAgLyp0cF9jbGVhciovCisgICAgKHJpY2hjbXBmdW5jKXdlYWtyZWZfcmljaGNvbXBhcmUsICAgLyp0cF9yaWNoY29tcGFyZSovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgIC8qdHBfd2Vha2xpc3RvZmZzZXQqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAvKnRwX2l0ZXIqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAvKnRwX2l0ZXJuZXh0Ki8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgLyp0cF9tZXRob2RzKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgLyp0cF9tZW1iZXJzKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgLyp0cF9nZXRzZXQqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAvKnRwX2Jhc2UqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAvKnRwX2RpY3QqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAvKnRwX2Rlc2NyX2dldCovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgIC8qdHBfZGVzY3Jfc2V0Ki8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgLyp0cF9kaWN0b2Zmc2V0Ki8KKyAgICB3ZWFrcmVmX19faW5pdF9fLCAgICAgICAgICAgLyp0cF9pbml0Ki8KKyAgICBQeVR5cGVfR2VuZXJpY0FsbG9jLCAgICAgICAgLyp0cF9hbGxvYyovCisgICAgd2Vha3JlZl9fX25ld19fLCAgICAgICAgICAgIC8qdHBfbmV3Ki8KKyAgICBQeU9iamVjdF9HQ19EZWwsICAgICAgICAgICAgLyp0cF9mcmVlKi8KK307CisKKworc3RhdGljIGludAorcHJveHlfY2hlY2tyZWYoUHlXZWFrUmVmZXJlbmNlICpwcm94eSkKK3sKKyAgICBpZiAoUHlXZWFrcmVmX0dFVF9PQkpFQ1QocHJveHkpID09IFB5X05vbmUpIHsKKyAgICAgICAgUHlFcnJfU2V0U3RyaW5nKFB5RXhjX1JlZmVyZW5jZUVycm9yLAorICAgICAgICAgICAgICAgICAgICAgICAgIndlYWtseS1yZWZlcmVuY2VkIG9iamVjdCBubyBsb25nZXIgZXhpc3RzIik7CisgICAgICAgIHJldHVybiAwOworICAgIH0KKyAgICByZXR1cm4gMTsKK30KKworCisvKiBJZiBhIHBhcmFtZXRlciBpcyBhIHByb3h5LCBjaGVjayB0aGF0IGl0IGlzIHN0aWxsICJsaXZlIiBhbmQgd3JhcCBpdCwKKyAqIHJlcGxhY2luZyB0aGUgb3JpZ2luYWwgdmFsdWUgd2l0aCB0aGUgcmF3IG9iamVjdC4gIFJhaXNlcyBSZWZlcmVuY2VFcnJvcgorICogaWYgdGhlIHBhcmFtIGlzIGEgZGVhZCBwcm94eS4KKyAqLworI2RlZmluZSBVTldSQVAobykgXAorICAgICAgICBpZiAoUHlXZWFrcmVmX0NoZWNrUHJveHkobykpIHsgXAorICAgICAgICAgICAgaWYgKCFwcm94eV9jaGVja3JlZigoUHlXZWFrUmVmZXJlbmNlICopbykpIFwKKyAgICAgICAgICAgICAgICByZXR1cm4gTlVMTDsgXAorICAgICAgICAgICAgbyA9IFB5V2Vha3JlZl9HRVRfT0JKRUNUKG8pOyBcCisgICAgICAgIH0KKworI2RlZmluZSBVTldSQVBfSShvKSBcCisgICAgICAgIGlmIChQeVdlYWtyZWZfQ2hlY2tQcm94eShvKSkgeyBcCisgICAgICAgICAgICBpZiAoIXByb3h5X2NoZWNrcmVmKChQeVdlYWtSZWZlcmVuY2UgKilvKSkgXAorICAgICAgICAgICAgICAgIHJldHVybiAtMTsgXAorICAgICAgICAgICAgbyA9IFB5V2Vha3JlZl9HRVRfT0JKRUNUKG8pOyBcCisgICAgICAgIH0KKworI2RlZmluZSBXUkFQX1VOQVJZKG1ldGhvZCwgZ2VuZXJpYykgXAorICAgIHN0YXRpYyBQeU9iamVjdCAqIFwKKyAgICBtZXRob2QoUHlPYmplY3QgKnByb3h5KSB7IFwKKyAgICAgICAgVU5XUkFQKHByb3h5KTsgXAorICAgICAgICByZXR1cm4gZ2VuZXJpYyhwcm94eSk7IFwKKyAgICB9CisKKyNkZWZpbmUgV1JBUF9CSU5BUlkobWV0aG9kLCBnZW5lcmljKSBcCisgICAgc3RhdGljIFB5T2JqZWN0ICogXAorICAgIG1ldGhvZChQeU9iamVjdCAqeCwgUHlPYmplY3QgKnkpIHsgXAorICAgICAgICBVTldSQVAoeCk7IFwKKyAgICAgICAgVU5XUkFQKHkpOyBcCisgICAgICAgIHJldHVybiBnZW5lcmljKHgsIHkpOyBcCisgICAgfQorCisvKiBOb3RlIHRoYXQgdGhlIHRoaXJkIGFyZyBuZWVkcyB0byBiZSBjaGVja2VkIGZvciBOVUxMIHNpbmNlIHRoZSB0cF9jYWxsCisgKiBzbG90IGNhbiByZWNlaXZlIE5VTEwgZm9yIHRoaXMgYXJnLgorICovCisjZGVmaW5lIFdSQVBfVEVSTkFSWShtZXRob2QsIGdlbmVyaWMpIFwKKyAgICBzdGF0aWMgUHlPYmplY3QgKiBcCisgICAgbWV0aG9kKFB5T2JqZWN0ICpwcm94eSwgUHlPYmplY3QgKnYsIFB5T2JqZWN0ICp3KSB7IFwKKyAgICAgICAgVU5XUkFQKHByb3h5KTsgXAorICAgICAgICBVTldSQVAodik7IFwKKyAgICAgICAgaWYgKHcgIT0gTlVMTCkgXAorICAgICAgICAgICAgVU5XUkFQKHcpOyBcCisgICAgICAgIHJldHVybiBnZW5lcmljKHByb3h5LCB2LCB3KTsgXAorICAgIH0KKworI2RlZmluZSBXUkFQX01FVEhPRChtZXRob2QsIHNwZWNpYWwpIFwKKyAgICBzdGF0aWMgUHlPYmplY3QgKiBcCisgICAgbWV0aG9kKFB5T2JqZWN0ICpwcm94eSkgeyBcCisgICAgICAgICAgICBVTldSQVAocHJveHkpOyBcCisgICAgICAgICAgICAgICAgcmV0dXJuIFB5T2JqZWN0X0NhbGxNZXRob2QocHJveHksIHNwZWNpYWwsICIiKTsgXAorICAgICAgICB9CisKKworLyogZGlyZWN0IHNsb3RzICovCisKK1dSQVBfQklOQVJZKHByb3h5X2dldGF0dHIsIFB5T2JqZWN0X0dldEF0dHIpCitXUkFQX1VOQVJZKHByb3h5X3N0ciwgUHlPYmplY3RfU3RyKQorV1JBUF9URVJOQVJZKHByb3h5X2NhbGwsIFB5RXZhbF9DYWxsT2JqZWN0V2l0aEtleXdvcmRzKQorCitzdGF0aWMgUHlPYmplY3QgKgorcHJveHlfcmVwcihQeVdlYWtSZWZlcmVuY2UgKnByb3h5KQoreworICAgIGNoYXIgYnVmWzE2MF07CisgICAgUHlPU19zbnByaW50ZihidWYsIHNpemVvZihidWYpLAorICAgICAgICAgICAgICAgICAgIjx3ZWFrcHJveHkgYXQgJXAgdG8gJS4xMDBzIGF0ICVwPiIsIHByb3h5LAorICAgICAgICAgICAgICAgICAgUHlfVFlQRShQeVdlYWtyZWZfR0VUX09CSkVDVChwcm94eSkpLT50cF9uYW1lLAorICAgICAgICAgICAgICAgICAgUHlXZWFrcmVmX0dFVF9PQkpFQ1QocHJveHkpKTsKKyAgICByZXR1cm4gUHlTdHJpbmdfRnJvbVN0cmluZyhidWYpOworfQorCisKK3N0YXRpYyBpbnQKK3Byb3h5X3NldGF0dHIoUHlXZWFrUmVmZXJlbmNlICpwcm94eSwgUHlPYmplY3QgKm5hbWUsIFB5T2JqZWN0ICp2YWx1ZSkKK3sKKyAgICBpZiAoIXByb3h5X2NoZWNrcmVmKHByb3h5KSkKKyAgICAgICAgcmV0dXJuIC0xOworICAgIHJldHVybiBQeU9iamVjdF9TZXRBdHRyKFB5V2Vha3JlZl9HRVRfT0JKRUNUKHByb3h5KSwgbmFtZSwgdmFsdWUpOworfQorCitzdGF0aWMgaW50Citwcm94eV9jb21wYXJlKFB5T2JqZWN0ICpwcm94eSwgUHlPYmplY3QgKnYpCit7CisgICAgVU5XUkFQX0kocHJveHkpOworICAgIFVOV1JBUF9JKHYpOworICAgIHJldHVybiBQeU9iamVjdF9Db21wYXJlKHByb3h5LCB2KTsKK30KKworLyogbnVtYmVyIHNsb3RzICovCitXUkFQX0JJTkFSWShwcm94eV9hZGQsIFB5TnVtYmVyX0FkZCkKK1dSQVBfQklOQVJZKHByb3h5X3N1YiwgUHlOdW1iZXJfU3VidHJhY3QpCitXUkFQX0JJTkFSWShwcm94eV9tdWwsIFB5TnVtYmVyX011bHRpcGx5KQorV1JBUF9CSU5BUlkocHJveHlfZGl2LCBQeU51bWJlcl9EaXZpZGUpCitXUkFQX0JJTkFSWShwcm94eV9mbG9vcl9kaXYsIFB5TnVtYmVyX0Zsb29yRGl2aWRlKQorV1JBUF9CSU5BUlkocHJveHlfdHJ1ZV9kaXYsIFB5TnVtYmVyX1RydWVEaXZpZGUpCitXUkFQX0JJTkFSWShwcm94eV9tb2QsIFB5TnVtYmVyX1JlbWFpbmRlcikKK1dSQVBfQklOQVJZKHByb3h5X2Rpdm1vZCwgUHlOdW1iZXJfRGl2bW9kKQorV1JBUF9URVJOQVJZKHByb3h5X3BvdywgUHlOdW1iZXJfUG93ZXIpCitXUkFQX1VOQVJZKHByb3h5X25lZywgUHlOdW1iZXJfTmVnYXRpdmUpCitXUkFQX1VOQVJZKHByb3h5X3BvcywgUHlOdW1iZXJfUG9zaXRpdmUpCitXUkFQX1VOQVJZKHByb3h5X2FicywgUHlOdW1iZXJfQWJzb2x1dGUpCitXUkFQX1VOQVJZKHByb3h5X2ludmVydCwgUHlOdW1iZXJfSW52ZXJ0KQorV1JBUF9CSU5BUlkocHJveHlfbHNoaWZ0LCBQeU51bWJlcl9Mc2hpZnQpCitXUkFQX0JJTkFSWShwcm94eV9yc2hpZnQsIFB5TnVtYmVyX1JzaGlmdCkKK1dSQVBfQklOQVJZKHByb3h5X2FuZCwgUHlOdW1iZXJfQW5kKQorV1JBUF9CSU5BUlkocHJveHlfeG9yLCBQeU51bWJlcl9Yb3IpCitXUkFQX0JJTkFSWShwcm94eV9vciwgUHlOdW1iZXJfT3IpCitXUkFQX1VOQVJZKHByb3h5X2ludCwgUHlOdW1iZXJfSW50KQorV1JBUF9VTkFSWShwcm94eV9sb25nLCBQeU51bWJlcl9Mb25nKQorV1JBUF9VTkFSWShwcm94eV9mbG9hdCwgUHlOdW1iZXJfRmxvYXQpCitXUkFQX0JJTkFSWShwcm94eV9pYWRkLCBQeU51bWJlcl9JblBsYWNlQWRkKQorV1JBUF9CSU5BUlkocHJveHlfaXN1YiwgUHlOdW1iZXJfSW5QbGFjZVN1YnRyYWN0KQorV1JBUF9CSU5BUlkocHJveHlfaW11bCwgUHlOdW1iZXJfSW5QbGFjZU11bHRpcGx5KQorV1JBUF9CSU5BUlkocHJveHlfaWRpdiwgUHlOdW1iZXJfSW5QbGFjZURpdmlkZSkKK1dSQVBfQklOQVJZKHByb3h5X2lmbG9vcl9kaXYsIFB5TnVtYmVyX0luUGxhY2VGbG9vckRpdmlkZSkKK1dSQVBfQklOQVJZKHByb3h5X2l0cnVlX2RpdiwgUHlOdW1iZXJfSW5QbGFjZVRydWVEaXZpZGUpCitXUkFQX0JJTkFSWShwcm94eV9pbW9kLCBQeU51bWJlcl9JblBsYWNlUmVtYWluZGVyKQorV1JBUF9URVJOQVJZKHByb3h5X2lwb3csIFB5TnVtYmVyX0luUGxhY2VQb3dlcikKK1dSQVBfQklOQVJZKHByb3h5X2lsc2hpZnQsIFB5TnVtYmVyX0luUGxhY2VMc2hpZnQpCitXUkFQX0JJTkFSWShwcm94eV9pcnNoaWZ0LCBQeU51bWJlcl9JblBsYWNlUnNoaWZ0KQorV1JBUF9CSU5BUlkocHJveHlfaWFuZCwgUHlOdW1iZXJfSW5QbGFjZUFuZCkKK1dSQVBfQklOQVJZKHByb3h5X2l4b3IsIFB5TnVtYmVyX0luUGxhY2VYb3IpCitXUkFQX0JJTkFSWShwcm94eV9pb3IsIFB5TnVtYmVyX0luUGxhY2VPcikKK1dSQVBfVU5BUlkocHJveHlfaW5kZXgsIFB5TnVtYmVyX0luZGV4KQorCitzdGF0aWMgaW50Citwcm94eV9ub256ZXJvKFB5V2Vha1JlZmVyZW5jZSAqcHJveHkpCit7CisgICAgUHlPYmplY3QgKm8gPSBQeVdlYWtyZWZfR0VUX09CSkVDVChwcm94eSk7CisgICAgaWYgKCFwcm94eV9jaGVja3JlZihwcm94eSkpCisgICAgICAgIHJldHVybiAtMTsKKyAgICByZXR1cm4gUHlPYmplY3RfSXNUcnVlKG8pOworfQorCitzdGF0aWMgdm9pZAorcHJveHlfZGVhbGxvYyhQeVdlYWtSZWZlcmVuY2UgKnNlbGYpCit7CisgICAgaWYgKHNlbGYtPndyX2NhbGxiYWNrICE9IE5VTEwpCisgICAgICAgIFB5T2JqZWN0X0dDX1VuVHJhY2soKFB5T2JqZWN0ICopc2VsZik7CisgICAgY2xlYXJfd2Vha3JlZihzZWxmKTsKKyAgICBQeU9iamVjdF9HQ19EZWwoc2VsZik7Cit9CisKKy8qIHNlcXVlbmNlIHNsb3RzICovCisKK3N0YXRpYyBQeU9iamVjdCAqCitwcm94eV9zbGljZShQeVdlYWtSZWZlcmVuY2UgKnByb3h5LCBQeV9zc2l6ZV90IGksIFB5X3NzaXplX3QgaikKK3sKKyAgICBpZiAoIXByb3h5X2NoZWNrcmVmKHByb3h5KSkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgcmV0dXJuIFB5U2VxdWVuY2VfR2V0U2xpY2UoUHlXZWFrcmVmX0dFVF9PQkpFQ1QocHJveHkpLCBpLCBqKTsKK30KKworc3RhdGljIGludAorcHJveHlfYXNzX3NsaWNlKFB5V2Vha1JlZmVyZW5jZSAqcHJveHksIFB5X3NzaXplX3QgaSwgUHlfc3NpemVfdCBqLCBQeU9iamVjdCAqdmFsdWUpCit7CisgICAgaWYgKCFwcm94eV9jaGVja3JlZihwcm94eSkpCisgICAgICAgIHJldHVybiAtMTsKKyAgICByZXR1cm4gUHlTZXF1ZW5jZV9TZXRTbGljZShQeVdlYWtyZWZfR0VUX09CSkVDVChwcm94eSksIGksIGosIHZhbHVlKTsKK30KKworc3RhdGljIGludAorcHJveHlfY29udGFpbnMoUHlXZWFrUmVmZXJlbmNlICpwcm94eSwgUHlPYmplY3QgKnZhbHVlKQoreworICAgIGlmICghcHJveHlfY2hlY2tyZWYocHJveHkpKQorICAgICAgICByZXR1cm4gLTE7CisgICAgcmV0dXJuIFB5U2VxdWVuY2VfQ29udGFpbnMoUHlXZWFrcmVmX0dFVF9PQkpFQ1QocHJveHkpLCB2YWx1ZSk7Cit9CisKKworLyogbWFwcGluZyBzbG90cyAqLworCitzdGF0aWMgUHlfc3NpemVfdAorcHJveHlfbGVuZ3RoKFB5V2Vha1JlZmVyZW5jZSAqcHJveHkpCit7CisgICAgaWYgKCFwcm94eV9jaGVja3JlZihwcm94eSkpCisgICAgICAgIHJldHVybiAtMTsKKyAgICByZXR1cm4gUHlPYmplY3RfTGVuZ3RoKFB5V2Vha3JlZl9HRVRfT0JKRUNUKHByb3h5KSk7Cit9CisKK1dSQVBfQklOQVJZKHByb3h5X2dldGl0ZW0sIFB5T2JqZWN0X0dldEl0ZW0pCisKK3N0YXRpYyBpbnQKK3Byb3h5X3NldGl0ZW0oUHlXZWFrUmVmZXJlbmNlICpwcm94eSwgUHlPYmplY3QgKmtleSwgUHlPYmplY3QgKnZhbHVlKQoreworICAgIGlmICghcHJveHlfY2hlY2tyZWYocHJveHkpKQorICAgICAgICByZXR1cm4gLTE7CisKKyAgICBpZiAodmFsdWUgPT0gTlVMTCkKKyAgICAgICAgcmV0dXJuIFB5T2JqZWN0X0RlbEl0ZW0oUHlXZWFrcmVmX0dFVF9PQkpFQ1QocHJveHkpLCBrZXkpOworICAgIGVsc2UKKyAgICAgICAgcmV0dXJuIFB5T2JqZWN0X1NldEl0ZW0oUHlXZWFrcmVmX0dFVF9PQkpFQ1QocHJveHkpLCBrZXksIHZhbHVlKTsKK30KKworLyogaXRlcmF0b3Igc2xvdHMgKi8KKworc3RhdGljIFB5T2JqZWN0ICoKK3Byb3h5X2l0ZXIoUHlXZWFrUmVmZXJlbmNlICpwcm94eSkKK3sKKyAgICBpZiAoIXByb3h5X2NoZWNrcmVmKHByb3h5KSkKKyAgICAgICAgcmV0dXJuIE5VTEw7CisgICAgcmV0dXJuIFB5T2JqZWN0X0dldEl0ZXIoUHlXZWFrcmVmX0dFVF9PQkpFQ1QocHJveHkpKTsKK30KKworc3RhdGljIFB5T2JqZWN0ICoKK3Byb3h5X2l0ZXJuZXh0KFB5V2Vha1JlZmVyZW5jZSAqcHJveHkpCit7CisgICAgaWYgKCFwcm94eV9jaGVja3JlZihwcm94eSkpCisgICAgICAgIHJldHVybiBOVUxMOworICAgIHJldHVybiBQeUl0ZXJfTmV4dChQeVdlYWtyZWZfR0VUX09CSkVDVChwcm94eSkpOworfQorCisKK1dSQVBfTUVUSE9EKHByb3h5X3VuaWNvZGUsICJfX3VuaWNvZGVfXyIpOworCisKK3N0YXRpYyBQeU1ldGhvZERlZiBwcm94eV9tZXRob2RzW10gPSB7CisgICAgICAgIHsiX191bmljb2RlX18iLCAoUHlDRnVuY3Rpb24pcHJveHlfdW5pY29kZSwgTUVUSF9OT0FSR1N9LAorICAgICAgICB7TlVMTCwgTlVMTH0KK307CisKKworc3RhdGljIFB5TnVtYmVyTWV0aG9kcyBwcm94eV9hc19udW1iZXIgPSB7CisgICAgcHJveHlfYWRkLCAgICAgICAgICAgICAgLypuYl9hZGQqLworICAgIHByb3h5X3N1YiwgICAgICAgICAgICAgIC8qbmJfc3VidHJhY3QqLworICAgIHByb3h5X211bCwgICAgICAgICAgICAgIC8qbmJfbXVsdGlwbHkqLworICAgIHByb3h5X2RpdiwgICAgICAgICAgICAgIC8qbmJfZGl2aWRlKi8KKyAgICBwcm94eV9tb2QsICAgICAgICAgICAgICAvKm5iX3JlbWFpbmRlciovCisgICAgcHJveHlfZGl2bW9kLCAgICAgICAgICAgLypuYl9kaXZtb2QqLworICAgIHByb3h5X3BvdywgICAgICAgICAgICAgIC8qbmJfcG93ZXIqLworICAgIHByb3h5X25lZywgICAgICAgICAgICAgIC8qbmJfbmVnYXRpdmUqLworICAgIHByb3h5X3BvcywgICAgICAgICAgICAgIC8qbmJfcG9zaXRpdmUqLworICAgIHByb3h5X2FicywgICAgICAgICAgICAgIC8qbmJfYWJzb2x1dGUqLworICAgIChpbnF1aXJ5KXByb3h5X25vbnplcm8sIC8qbmJfbm9uemVybyovCisgICAgcHJveHlfaW52ZXJ0LCAgICAgICAgICAgLypuYl9pbnZlcnQqLworICAgIHByb3h5X2xzaGlmdCwgICAgICAgICAgIC8qbmJfbHNoaWZ0Ki8KKyAgICBwcm94eV9yc2hpZnQsICAgICAgICAgICAvKm5iX3JzaGlmdCovCisgICAgcHJveHlfYW5kLCAgICAgICAgICAgICAgLypuYl9hbmQqLworICAgIHByb3h5X3hvciwgICAgICAgICAgICAgIC8qbmJfeG9yKi8KKyAgICBwcm94eV9vciwgICAgICAgICAgICAgICAvKm5iX29yKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAvKm5iX2NvZXJjZSovCisgICAgcHJveHlfaW50LCAgICAgICAgICAgICAgLypuYl9pbnQqLworICAgIHByb3h5X2xvbmcsICAgICAgICAgICAgIC8qbmJfbG9uZyovCisgICAgcHJveHlfZmxvYXQsICAgICAgICAgICAgLypuYl9mbG9hdCovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgLypuYl9vY3QqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgIC8qbmJfaGV4Ki8KKyAgICBwcm94eV9pYWRkLCAgICAgICAgICAgICAvKm5iX2lucGxhY2VfYWRkKi8KKyAgICBwcm94eV9pc3ViLCAgICAgICAgICAgICAvKm5iX2lucGxhY2Vfc3VidHJhY3QqLworICAgIHByb3h5X2ltdWwsICAgICAgICAgICAgIC8qbmJfaW5wbGFjZV9tdWx0aXBseSovCisgICAgcHJveHlfaWRpdiwgICAgICAgICAgICAgLypuYl9pbnBsYWNlX2RpdmlkZSovCisgICAgcHJveHlfaW1vZCwgICAgICAgICAgICAgLypuYl9pbnBsYWNlX3JlbWFpbmRlciovCisgICAgcHJveHlfaXBvdywgICAgICAgICAgICAgLypuYl9pbnBsYWNlX3Bvd2VyKi8KKyAgICBwcm94eV9pbHNoaWZ0LCAgICAgICAgICAvKm5iX2lucGxhY2VfbHNoaWZ0Ki8KKyAgICBwcm94eV9pcnNoaWZ0LCAgICAgICAgICAvKm5iX2lucGxhY2VfcnNoaWZ0Ki8KKyAgICBwcm94eV9pYW5kLCAgICAgICAgICAgICAvKm5iX2lucGxhY2VfYW5kKi8KKyAgICBwcm94eV9peG9yLCAgICAgICAgICAgICAvKm5iX2lucGxhY2VfeG9yKi8KKyAgICBwcm94eV9pb3IsICAgICAgICAgICAgICAvKm5iX2lucGxhY2Vfb3IqLworICAgIHByb3h5X2Zsb29yX2RpdiwgICAgICAgIC8qbmJfZmxvb3JfZGl2aWRlKi8KKyAgICBwcm94eV90cnVlX2RpdiwgICAgICAgICAvKm5iX3RydWVfZGl2aWRlKi8KKyAgICBwcm94eV9pZmxvb3JfZGl2LCAgICAgICAvKm5iX2lucGxhY2VfZmxvb3JfZGl2aWRlKi8KKyAgICBwcm94eV9pdHJ1ZV9kaXYsICAgICAgICAvKm5iX2lucGxhY2VfdHJ1ZV9kaXZpZGUqLworICAgIHByb3h5X2luZGV4LCAgICAgICAgICAgIC8qbmJfaW5kZXgqLworfTsKKworc3RhdGljIFB5U2VxdWVuY2VNZXRob2RzIHByb3h5X2FzX3NlcXVlbmNlID0geworICAgIChsZW5mdW5jKXByb3h5X2xlbmd0aCwgICAgICAvKnNxX2xlbmd0aCovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgIC8qc3FfY29uY2F0Ki8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgLypzcV9yZXBlYXQqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAvKnNxX2l0ZW0qLworICAgIChzc2l6ZXNzaXplYXJnZnVuYylwcm94eV9zbGljZSwgLypzcV9zbGljZSovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgIC8qc3FfYXNzX2l0ZW0qLworICAgIChzc2l6ZXNzaXplb2JqYXJncHJvYylwcm94eV9hc3Nfc2xpY2UsIC8qc3FfYXNzX3NsaWNlKi8KKyAgICAob2Jqb2JqcHJvYylwcm94eV9jb250YWlucywgLyogc3FfY29udGFpbnMgKi8KK307CisKK3N0YXRpYyBQeU1hcHBpbmdNZXRob2RzIHByb3h5X2FzX21hcHBpbmcgPSB7CisgICAgKGxlbmZ1bmMpcHJveHlfbGVuZ3RoLCAgICAgICAgLyptcF9sZW5ndGgqLworICAgIHByb3h5X2dldGl0ZW0sICAgICAgICAgICAgICAgIC8qbXBfc3Vic2NyaXB0Ki8KKyAgICAob2Jqb2JqYXJncHJvYylwcm94eV9zZXRpdGVtLCAvKm1wX2Fzc19zdWJzY3JpcHQqLworfTsKKworCitQeVR5cGVPYmplY3QKK19QeVdlYWtyZWZfUHJveHlUeXBlID0geworICAgIFB5VmFyT2JqZWN0X0hFQURfSU5JVCgmUHlUeXBlX1R5cGUsIDApCisgICAgIndlYWtwcm94eSIsCisgICAgc2l6ZW9mKFB5V2Vha1JlZmVyZW5jZSksCisgICAgMCwKKyAgICAvKiBtZXRob2RzICovCisgICAgKGRlc3RydWN0b3IpcHJveHlfZGVhbGxvYywgICAgICAgICAgLyogdHBfZGVhbGxvYyAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3ByaW50ICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZ2V0YXR0ciAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3NldGF0dHIgKi8KKyAgICBwcm94eV9jb21wYXJlLCAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9jb21wYXJlICovCisgICAgKHJlcHJmdW5jKXByb3h5X3JlcHIsICAgICAgICAgICAgICAgLyogdHBfcmVwciAqLworICAgICZwcm94eV9hc19udW1iZXIsICAgICAgICAgICAgICAgICAgIC8qIHRwX2FzX251bWJlciAqLworICAgICZwcm94eV9hc19zZXF1ZW5jZSwgICAgICAgICAgICAgICAgIC8qIHRwX2FzX3NlcXVlbmNlICovCisgICAgJnByb3h5X2FzX21hcHBpbmcsICAgICAgICAgICAgICAgICAgLyogdHBfYXNfbWFwcGluZyAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2hhc2ggKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9jYWxsICovCisgICAgcHJveHlfc3RyLCAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfc3RyICovCisgICAgcHJveHlfZ2V0YXR0ciwgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZ2V0YXR0cm8gKi8KKyAgICAoc2V0YXR0cm9mdW5jKXByb3h5X3NldGF0dHIsICAgICAgICAvKiB0cF9zZXRhdHRybyAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2FzX2J1ZmZlciAqLworICAgIFB5X1RQRkxBR1NfREVGQVVMVCB8IFB5X1RQRkxBR1NfSEFWRV9HQworICAgIHwgUHlfVFBGTEFHU19DSEVDS1RZUEVTLCAgICAgICAgICAgIC8qIHRwX2ZsYWdzICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfZG9jICovCisgICAgKHRyYXZlcnNlcHJvYylnY190cmF2ZXJzZSwgICAgICAgICAgLyogdHBfdHJhdmVyc2UgKi8KKyAgICAoaW5xdWlyeSlnY19jbGVhciwgICAgICAgICAgICAgICAgICAvKiB0cF9jbGVhciAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3JpY2hjb21wYXJlICovCisgICAgMCwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfd2Vha2xpc3RvZmZzZXQgKi8KKyAgICAoZ2V0aXRlcmZ1bmMpcHJveHlfaXRlciwgICAgICAgICAgICAvKiB0cF9pdGVyICovCisgICAgKGl0ZXJuZXh0ZnVuYylwcm94eV9pdGVybmV4dCwgICAgICAgLyogdHBfaXRlcm5leHQgKi8KKyAgICAgICAgcHJveHlfbWV0aG9kcywgICAgICAgICAgICAgICAgICAgICAgLyogdHBfbWV0aG9kcyAqLworfTsKKworCitQeVR5cGVPYmplY3QKK19QeVdlYWtyZWZfQ2FsbGFibGVQcm94eVR5cGUgPSB7CisgICAgUHlWYXJPYmplY3RfSEVBRF9JTklUKCZQeVR5cGVfVHlwZSwgMCkKKyAgICAid2Vha2NhbGxhYmxlcHJveHkiLAorICAgIHNpemVvZihQeVdlYWtSZWZlcmVuY2UpLAorICAgIDAsCisgICAgLyogbWV0aG9kcyAqLworICAgIChkZXN0cnVjdG9yKXByb3h5X2RlYWxsb2MsICAgICAgICAgIC8qIHRwX2RlYWxsb2MgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9wcmludCAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2dldGF0dHIgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9zZXRhdHRyICovCisgICAgcHJveHlfY29tcGFyZSwgICAgICAgICAgICAgICAgICAgICAgLyogdHBfY29tcGFyZSAqLworICAgICh1bmFyeWZ1bmMpcHJveHlfcmVwciwgICAgICAgICAgICAgIC8qIHRwX3JlcHIgKi8KKyAgICAmcHJveHlfYXNfbnVtYmVyLCAgICAgICAgICAgICAgICAgICAvKiB0cF9hc19udW1iZXIgKi8KKyAgICAmcHJveHlfYXNfc2VxdWVuY2UsICAgICAgICAgICAgICAgICAvKiB0cF9hc19zZXF1ZW5jZSAqLworICAgICZwcm94eV9hc19tYXBwaW5nLCAgICAgICAgICAgICAgICAgIC8qIHRwX2FzX21hcHBpbmcgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9oYXNoICovCisgICAgcHJveHlfY2FsbCwgICAgICAgICAgICAgICAgICAgICAgICAgLyogdHBfY2FsbCAqLworICAgIHByb3h5X3N0ciwgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3N0ciAqLworICAgIHByb3h5X2dldGF0dHIsICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2dldGF0dHJvICovCisgICAgKHNldGF0dHJvZnVuYylwcm94eV9zZXRhdHRyLCAgICAgICAgLyogdHBfc2V0YXR0cm8gKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9hc19idWZmZXIgKi8KKyAgICBQeV9UUEZMQUdTX0RFRkFVTFQgfCBQeV9UUEZMQUdTX0hBVkVfR0MKKyAgICB8IFB5X1RQRkxBR1NfQ0hFQ0tUWVBFUywgICAgICAgICAgICAvKiB0cF9mbGFncyAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX2RvYyAqLworICAgICh0cmF2ZXJzZXByb2MpZ2NfdHJhdmVyc2UsICAgICAgICAgIC8qIHRwX3RyYXZlcnNlICovCisgICAgKGlucXVpcnkpZ2NfY2xlYXIsICAgICAgICAgICAgICAgICAgLyogdHBfY2xlYXIgKi8KKyAgICAwLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiB0cF9yaWNoY29tcGFyZSAqLworICAgIDAsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIHRwX3dlYWtsaXN0b2Zmc2V0ICovCisgICAgKGdldGl0ZXJmdW5jKXByb3h5X2l0ZXIsICAgICAgICAgICAgLyogdHBfaXRlciAqLworICAgIChpdGVybmV4dGZ1bmMpcHJveHlfaXRlcm5leHQsICAgICAgIC8qIHRwX2l0ZXJuZXh0ICovCit9OworCisKKworUHlPYmplY3QgKgorUHlXZWFrcmVmX05ld1JlZihQeU9iamVjdCAqb2IsIFB5T2JqZWN0ICpjYWxsYmFjaykKK3sKKyAgICBQeVdlYWtSZWZlcmVuY2UgKnJlc3VsdCA9IE5VTEw7CisgICAgUHlXZWFrUmVmZXJlbmNlICoqbGlzdDsKKyAgICBQeVdlYWtSZWZlcmVuY2UgKnJlZiwgKnByb3h5OworCisgICAgaWYgKCFQeVR5cGVfU1VQUE9SVFNfV0VBS1JFRlMoUHlfVFlQRShvYikpKSB7CisgICAgICAgIFB5RXJyX0Zvcm1hdChQeUV4Y19UeXBlRXJyb3IsCisgICAgICAgICAgICAgICAgICAgICAiY2Fubm90IGNyZWF0ZSB3ZWFrIHJlZmVyZW5jZSB0byAnJXMnIG9iamVjdCIsCisgICAgICAgICAgICAgICAgICAgICBQeV9UWVBFKG9iKS0+dHBfbmFtZSk7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICBsaXN0ID0gR0VUX1dFQUtSRUZTX0xJU1RQVFIob2IpOworICAgIGdldF9iYXNpY19yZWZzKCpsaXN0LCAmcmVmLCAmcHJveHkpOworICAgIGlmIChjYWxsYmFjayA9PSBQeV9Ob25lKQorICAgICAgICBjYWxsYmFjayA9IE5VTEw7CisgICAgaWYgKGNhbGxiYWNrID09IE5VTEwpCisgICAgICAgIC8qIHJldHVybiBleGlzdGluZyB3ZWFrIHJlZmVyZW5jZSBpZiBpdCBleGlzdHMgKi8KKyAgICAgICAgcmVzdWx0ID0gcmVmOworICAgIGlmIChyZXN1bHQgIT0gTlVMTCkKKyAgICAgICAgUHlfSU5DUkVGKHJlc3VsdCk7CisgICAgZWxzZSB7CisgICAgICAgIC8qIE5vdGU6IG5ld193ZWFrcmVmKCkgY2FuIHRyaWdnZXIgY3ljbGljIEdDLCBzbyB0aGUgd2Vha3JlZgorICAgICAgICAgICBsaXN0IG9uIG9iIGNhbiBiZSBtdXRhdGVkLiAgVGhpcyBtZWFucyB0aGF0IHRoZSByZWYgYW5kCisgICAgICAgICAgIHByb3h5IHBvaW50ZXJzIHdlIGdvdCBiYWNrIGVhcmxpZXIgbWF5IGhhdmUgYmVlbiBjb2xsZWN0ZWQsCisgICAgICAgICAgIHNvIHdlIG5lZWQgdG8gY29tcHV0ZSB0aGVzZSB2YWx1ZXMgYWdhaW4gYmVmb3JlIHdlIHVzZQorICAgICAgICAgICB0aGVtLiAqLworICAgICAgICByZXN1bHQgPSBuZXdfd2Vha3JlZihvYiwgY2FsbGJhY2spOworICAgICAgICBpZiAocmVzdWx0ICE9IE5VTEwpIHsKKyAgICAgICAgICAgIGdldF9iYXNpY19yZWZzKCpsaXN0LCAmcmVmLCAmcHJveHkpOworICAgICAgICAgICAgaWYgKGNhbGxiYWNrID09IE5VTEwpIHsKKyAgICAgICAgICAgICAgICBpZiAocmVmID09IE5VTEwpCisgICAgICAgICAgICAgICAgICAgIGluc2VydF9oZWFkKHJlc3VsdCwgbGlzdCk7CisgICAgICAgICAgICAgICAgZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIC8qIFNvbWVvbmUgZWxzZSBhZGRlZCBhIHJlZiB3aXRob3V0IGEgY2FsbGJhY2sKKyAgICAgICAgICAgICAgICAgICAgICAgZHVyaW5nIEdDLiAgUmV0dXJuIHRoYXQgb25lIGluc3RlYWQgb2YgdGhpcyBvbmUKKyAgICAgICAgICAgICAgICAgICAgICAgdG8gYXZvaWQgdmlvbGF0aW5nIHRoZSBpbnZhcmlhbnRzIG9mIHRoZSBsaXN0CisgICAgICAgICAgICAgICAgICAgICAgIG9mIHdlYWtyZWZzIGZvciBvYi4gKi8KKyAgICAgICAgICAgICAgICAgICAgUHlfREVDUkVGKHJlc3VsdCk7CisgICAgICAgICAgICAgICAgICAgIFB5X0lOQ1JFRihyZWYpOworICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSByZWY7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgfQorICAgICAgICAgICAgZWxzZSB7CisgICAgICAgICAgICAgICAgUHlXZWFrUmVmZXJlbmNlICpwcmV2OworCisgICAgICAgICAgICAgICAgcHJldiA9IChwcm94eSA9PSBOVUxMKSA/IHJlZiA6IHByb3h5OworICAgICAgICAgICAgICAgIGlmIChwcmV2ID09IE5VTEwpCisgICAgICAgICAgICAgICAgICAgIGluc2VydF9oZWFkKHJlc3VsdCwgbGlzdCk7CisgICAgICAgICAgICAgICAgZWxzZQorICAgICAgICAgICAgICAgICAgICBpbnNlcnRfYWZ0ZXIocmVzdWx0LCBwcmV2KTsKKyAgICAgICAgICAgIH0KKyAgICAgICAgfQorICAgIH0KKyAgICByZXR1cm4gKFB5T2JqZWN0ICopIHJlc3VsdDsKK30KKworCitQeU9iamVjdCAqCitQeVdlYWtyZWZfTmV3UHJveHkoUHlPYmplY3QgKm9iLCBQeU9iamVjdCAqY2FsbGJhY2spCit7CisgICAgUHlXZWFrUmVmZXJlbmNlICpyZXN1bHQgPSBOVUxMOworICAgIFB5V2Vha1JlZmVyZW5jZSAqKmxpc3Q7CisgICAgUHlXZWFrUmVmZXJlbmNlICpyZWYsICpwcm94eTsKKworICAgIGlmICghUHlUeXBlX1NVUFBPUlRTX1dFQUtSRUZTKFB5X1RZUEUob2IpKSkgeworICAgICAgICBQeUVycl9Gb3JtYXQoUHlFeGNfVHlwZUVycm9yLAorICAgICAgICAgICAgICAgICAgICAgImNhbm5vdCBjcmVhdGUgd2VhayByZWZlcmVuY2UgdG8gJyVzJyBvYmplY3QiLAorICAgICAgICAgICAgICAgICAgICAgUHlfVFlQRShvYiktPnRwX25hbWUpOworICAgICAgICByZXR1cm4gTlVMTDsKKyAgICB9CisgICAgbGlzdCA9IEdFVF9XRUFLUkVGU19MSVNUUFRSKG9iKTsKKyAgICBnZXRfYmFzaWNfcmVmcygqbGlzdCwgJnJlZiwgJnByb3h5KTsKKyAgICBpZiAoY2FsbGJhY2sgPT0gUHlfTm9uZSkKKyAgICAgICAgY2FsbGJhY2sgPSBOVUxMOworICAgIGlmIChjYWxsYmFjayA9PSBOVUxMKQorICAgICAgICAvKiBhdHRlbXB0IHRvIHJldHVybiBhbiBleGlzdGluZyB3ZWFrIHJlZmVyZW5jZSBpZiBpdCBleGlzdHMgKi8KKyAgICAgICAgcmVzdWx0ID0gcHJveHk7CisgICAgaWYgKHJlc3VsdCAhPSBOVUxMKQorICAgICAgICBQeV9JTkNSRUYocmVzdWx0KTsKKyAgICBlbHNlIHsKKyAgICAgICAgLyogTm90ZTogbmV3X3dlYWtyZWYoKSBjYW4gdHJpZ2dlciBjeWNsaWMgR0MsIHNvIHRoZSB3ZWFrcmVmCisgICAgICAgICAgIGxpc3Qgb24gb2IgY2FuIGJlIG11dGF0ZWQuICBUaGlzIG1lYW5zIHRoYXQgdGhlIHJlZiBhbmQKKyAgICAgICAgICAgcHJveHkgcG9pbnRlcnMgd2UgZ290IGJhY2sgZWFybGllciBtYXkgaGF2ZSBiZWVuIGNvbGxlY3RlZCwKKyAgICAgICAgICAgc28gd2UgbmVlZCB0byBjb21wdXRlIHRoZXNlIHZhbHVlcyBhZ2FpbiBiZWZvcmUgd2UgdXNlCisgICAgICAgICAgIHRoZW0uICovCisgICAgICAgIHJlc3VsdCA9IG5ld193ZWFrcmVmKG9iLCBjYWxsYmFjayk7CisgICAgICAgIGlmIChyZXN1bHQgIT0gTlVMTCkgeworICAgICAgICAgICAgUHlXZWFrUmVmZXJlbmNlICpwcmV2OworCisgICAgICAgICAgICBpZiAoUHlDYWxsYWJsZV9DaGVjayhvYikpCisgICAgICAgICAgICAgICAgUHlfVFlQRShyZXN1bHQpID0gJl9QeVdlYWtyZWZfQ2FsbGFibGVQcm94eVR5cGU7CisgICAgICAgICAgICBlbHNlCisgICAgICAgICAgICAgICAgUHlfVFlQRShyZXN1bHQpID0gJl9QeVdlYWtyZWZfUHJveHlUeXBlOworICAgICAgICAgICAgZ2V0X2Jhc2ljX3JlZnMoKmxpc3QsICZyZWYsICZwcm94eSk7CisgICAgICAgICAgICBpZiAoY2FsbGJhY2sgPT0gTlVMTCkgeworICAgICAgICAgICAgICAgIGlmIChwcm94eSAhPSBOVUxMKSB7CisgICAgICAgICAgICAgICAgICAgIC8qIFNvbWVvbmUgZWxzZSBhZGRlZCBhIHByb3h5IHdpdGhvdXQgYSBjYWxsYmFjaworICAgICAgICAgICAgICAgICAgICAgICBkdXJpbmcgR0MuICBSZXR1cm4gdGhhdCBvbmUgaW5zdGVhZCBvZiB0aGlzIG9uZQorICAgICAgICAgICAgICAgICAgICAgICB0byBhdm9pZCB2aW9sYXRpbmcgdGhlIGludmFyaWFudHMgb2YgdGhlIGxpc3QKKyAgICAgICAgICAgICAgICAgICAgICAgb2Ygd2Vha3JlZnMgZm9yIG9iLiAqLworICAgICAgICAgICAgICAgICAgICBQeV9ERUNSRUYocmVzdWx0KTsKKyAgICAgICAgICAgICAgICAgICAgUHlfSU5DUkVGKHJlc3VsdCA9IHByb3h5KTsKKyAgICAgICAgICAgICAgICAgICAgZ290byBza2lwX2luc2VydDsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgcHJldiA9IHJlZjsKKyAgICAgICAgICAgIH0KKyAgICAgICAgICAgIGVsc2UKKyAgICAgICAgICAgICAgICBwcmV2ID0gKHByb3h5ID09IE5VTEwpID8gcmVmIDogcHJveHk7CisKKyAgICAgICAgICAgIGlmIChwcmV2ID09IE5VTEwpCisgICAgICAgICAgICAgICAgaW5zZXJ0X2hlYWQocmVzdWx0LCBsaXN0KTsKKyAgICAgICAgICAgIGVsc2UKKyAgICAgICAgICAgICAgICBpbnNlcnRfYWZ0ZXIocmVzdWx0LCBwcmV2KTsKKyAgICAgICAgc2tpcF9pbnNlcnQ6CisgICAgICAgICAgICA7CisgICAgICAgIH0KKyAgICB9CisgICAgcmV0dXJuIChQeU9iamVjdCAqKSByZXN1bHQ7Cit9CisKKworUHlPYmplY3QgKgorUHlXZWFrcmVmX0dldE9iamVjdChQeU9iamVjdCAqcmVmKQoreworICAgIGlmIChyZWYgPT0gTlVMTCB8fCAhUHlXZWFrcmVmX0NoZWNrKHJlZikpIHsKKyAgICAgICAgUHlFcnJfQmFkSW50ZXJuYWxDYWxsKCk7CisgICAgICAgIHJldHVybiBOVUxMOworICAgIH0KKyAgICByZXR1cm4gUHlXZWFrcmVmX0dFVF9PQkpFQ1QocmVmKTsKK30KKworLyogTm90ZSB0aGF0IHRoZXJlJ3MgYW4gaW5saW5lZCBjb3B5LXBhc3RlIG9mIGhhbmRsZV9jYWxsYmFjaygpIGluIGdjbW9kdWxlLmMncworICogaGFuZGxlX3dlYWtyZWZzKCkuCisgKi8KK3N0YXRpYyB2b2lkCitoYW5kbGVfY2FsbGJhY2soUHlXZWFrUmVmZXJlbmNlICpyZWYsIFB5T2JqZWN0ICpjYWxsYmFjaykKK3sKKyAgICBQeU9iamVjdCAqY2JyZXN1bHQgPSBQeU9iamVjdF9DYWxsRnVuY3Rpb25PYmpBcmdzKGNhbGxiYWNrLCByZWYsIE5VTEwpOworCisgICAgaWYgKGNicmVzdWx0ID09IE5VTEwpCisgICAgICAgIFB5RXJyX1dyaXRlVW5yYWlzYWJsZShjYWxsYmFjayk7CisgICAgZWxzZQorICAgICAgICBQeV9ERUNSRUYoY2JyZXN1bHQpOworfQorCisvKiBUaGlzIGZ1bmN0aW9uIGlzIGNhbGxlZCBieSB0aGUgdHBfZGVhbGxvYyBoYW5kbGVyIHRvIGNsZWFyIHdlYWsgcmVmZXJlbmNlcy4KKyAqCisgKiBUaGlzIGl0ZXJhdGVzIHRocm91Z2ggdGhlIHdlYWsgcmVmZXJlbmNlcyBmb3IgJ29iamVjdCcgYW5kIGNhbGxzIGNhbGxiYWNrcworICogZm9yIHRob3NlIHJlZmVyZW5jZXMgd2hpY2ggaGF2ZSBvbmUuICBJdCByZXR1cm5zIHdoZW4gYWxsIGNhbGxiYWNrcyBoYXZlCisgKiBiZWVuIGF0dGVtcHRlZC4KKyAqLwordm9pZAorUHlPYmplY3RfQ2xlYXJXZWFrUmVmcyhQeU9iamVjdCAqb2JqZWN0KQoreworICAgIFB5V2Vha1JlZmVyZW5jZSAqKmxpc3Q7CisKKyAgICBpZiAob2JqZWN0ID09IE5VTEwKKyAgICAgICAgfHwgIVB5VHlwZV9TVVBQT1JUU19XRUFLUkVGUyhQeV9UWVBFKG9iamVjdCkpCisgICAgICAgIHx8IG9iamVjdC0+b2JfcmVmY250ICE9IDApIHsKKyAgICAgICAgUHlFcnJfQmFkSW50ZXJuYWxDYWxsKCk7CisgICAgICAgIHJldHVybjsKKyAgICB9CisgICAgbGlzdCA9IEdFVF9XRUFLUkVGU19MSVNUUFRSKG9iamVjdCk7CisgICAgLyogUmVtb3ZlIHRoZSBjYWxsYmFjay1sZXNzIGJhc2ljIGFuZCBwcm94eSByZWZlcmVuY2VzICovCisgICAgaWYgKCpsaXN0ICE9IE5VTEwgJiYgKCpsaXN0KS0+d3JfY2FsbGJhY2sgPT0gTlVMTCkgeworICAgICAgICBjbGVhcl93ZWFrcmVmKCpsaXN0KTsKKyAgICAgICAgaWYgKCpsaXN0ICE9IE5VTEwgJiYgKCpsaXN0KS0+d3JfY2FsbGJhY2sgPT0gTlVMTCkKKyAgICAgICAgICAgIGNsZWFyX3dlYWtyZWYoKmxpc3QpOworICAgIH0KKyAgICBpZiAoKmxpc3QgIT0gTlVMTCkgeworICAgICAgICBQeVdlYWtSZWZlcmVuY2UgKmN1cnJlbnQgPSAqbGlzdDsKKyAgICAgICAgUHlfc3NpemVfdCBjb3VudCA9IF9QeVdlYWtyZWZfR2V0V2Vha3JlZkNvdW50KGN1cnJlbnQpOworICAgICAgICBpbnQgcmVzdG9yZV9lcnJvciA9IFB5RXJyX09jY3VycmVkKCkgPyAxIDogMDsKKyAgICAgICAgUHlPYmplY3QgKmVycl90eXBlLCAqZXJyX3ZhbHVlLCAqZXJyX3RiOworCisgICAgICAgIGlmIChyZXN0b3JlX2Vycm9yKQorICAgICAgICAgICAgUHlFcnJfRmV0Y2goJmVycl90eXBlLCAmZXJyX3ZhbHVlLCAmZXJyX3RiKTsKKyAgICAgICAgaWYgKGNvdW50ID09IDEpIHsKKyAgICAgICAgICAgIFB5T2JqZWN0ICpjYWxsYmFjayA9IGN1cnJlbnQtPndyX2NhbGxiYWNrOworCisgICAgICAgICAgICBjdXJyZW50LT53cl9jYWxsYmFjayA9IE5VTEw7CisgICAgICAgICAgICBjbGVhcl93ZWFrcmVmKGN1cnJlbnQpOworICAgICAgICAgICAgaWYgKGNhbGxiYWNrICE9IE5VTEwpIHsKKyAgICAgICAgICAgICAgICBpZiAoY3VycmVudC0+b2JfcmVmY250ID4gMCkKKyAgICAgICAgICAgICAgICAgICAgaGFuZGxlX2NhbGxiYWNrKGN1cnJlbnQsIGNhbGxiYWNrKTsKKyAgICAgICAgICAgICAgICBQeV9ERUNSRUYoY2FsbGJhY2spOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgICAgIGVsc2UgeworICAgICAgICAgICAgUHlPYmplY3QgKnR1cGxlOworICAgICAgICAgICAgUHlfc3NpemVfdCBpID0gMDsKKworICAgICAgICAgICAgdHVwbGUgPSBQeVR1cGxlX05ldyhjb3VudCAqIDIpOworICAgICAgICAgICAgaWYgKHR1cGxlID09IE5VTEwpIHsKKyAgICAgICAgICAgICAgICBpZiAocmVzdG9yZV9lcnJvcikKKyAgICAgICAgICAgICAgICAgICAgUHlFcnJfRmV0Y2goJmVycl90eXBlLCAmZXJyX3ZhbHVlLCAmZXJyX3RiKTsKKyAgICAgICAgICAgICAgICByZXR1cm47CisgICAgICAgICAgICB9CisKKyAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCBjb3VudDsgKytpKSB7CisgICAgICAgICAgICAgICAgUHlXZWFrUmVmZXJlbmNlICpuZXh0ID0gY3VycmVudC0+d3JfbmV4dDsKKworICAgICAgICAgICAgICAgIGlmIChjdXJyZW50LT5vYl9yZWZjbnQgPiAwKQorICAgICAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAgICAgICAgUHlfSU5DUkVGKGN1cnJlbnQpOworICAgICAgICAgICAgICAgICAgICBQeVR1cGxlX1NFVF9JVEVNKHR1cGxlLCBpICogMiwgKFB5T2JqZWN0ICopIGN1cnJlbnQpOworICAgICAgICAgICAgICAgICAgICBQeVR1cGxlX1NFVF9JVEVNKHR1cGxlLCBpICogMiArIDEsIGN1cnJlbnQtPndyX2NhbGxiYWNrKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICAgICAgZWxzZSB7CisgICAgICAgICAgICAgICAgICAgIFB5X0RFQ1JFRihjdXJyZW50LT53cl9jYWxsYmFjayk7CisgICAgICAgICAgICAgICAgfQorICAgICAgICAgICAgICAgIGN1cnJlbnQtPndyX2NhbGxiYWNrID0gTlVMTDsKKyAgICAgICAgICAgICAgICBjbGVhcl93ZWFrcmVmKGN1cnJlbnQpOworICAgICAgICAgICAgICAgIGN1cnJlbnQgPSBuZXh0OworICAgICAgICAgICAgfQorICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IGNvdW50OyArK2kpIHsKKyAgICAgICAgICAgICAgICBQeU9iamVjdCAqY2FsbGJhY2sgPSBQeVR1cGxlX0dFVF9JVEVNKHR1cGxlLCBpICogMiArIDEpOworCisgICAgICAgICAgICAgICAgLyogVGhlIHR1cGxlIG1heSBoYXZlIHNsb3RzIGxlZnQgdG8gTlVMTCAqLworICAgICAgICAgICAgICAgIGlmIChjYWxsYmFjayAhPSBOVUxMKSB7CisgICAgICAgICAgICAgICAgICAgIFB5T2JqZWN0ICppdGVtID0gUHlUdXBsZV9HRVRfSVRFTSh0dXBsZSwgaSAqIDIpOworICAgICAgICAgICAgICAgICAgICBoYW5kbGVfY2FsbGJhY2soKFB5V2Vha1JlZmVyZW5jZSAqKWl0ZW0sIGNhbGxiYWNrKTsKKyAgICAgICAgICAgICAgICB9CisgICAgICAgICAgICB9CisgICAgICAgICAgICBQeV9ERUNSRUYodHVwbGUpOworICAgICAgICB9CisgICAgICAgIGlmIChyZXN0b3JlX2Vycm9yKQorICAgICAgICAgICAgUHlFcnJfUmVzdG9yZShlcnJfdHlwZSwgZXJyX3ZhbHVlLCBlcnJfdGIpOworICAgIH0KK30K