I2luY2x1ZGUgPHN0ZGlvLmg+DQojaW5jbHVkZSA8c3RkbGliLmg+DQojaW5jbHVkZSA8dW5pc3RkLmg+DQojaW5jbHVkZSA8c3RyaW5nLmg+DQojaW5jbHVkZSA8ZXJybm8uaD4NCiNpbmNsdWRlIDxhcnBhL2luZXQuaD4NCiNpbmNsdWRlIDxsaW51eC9uZXRsaW5rLmg+DQojaW5jbHVkZSA8bGludXgvc29ja2V0Lmg+DQojaW5jbHVkZSA8c3lzL3NvY2tldC5oPg0KI2luY2x1ZGUgPHN5c2xvZy5oPg0KI2luY2x1ZGUgPHN5cy9rbG9nLmg+DQojaW5jbHVkZSA8c3RkYXJnLmg+DQojaW5jbHVkZSAiaXBzZWNfYXBpLmgiDQojaW5jbHVkZSA8YXNzZXJ0Lmg+DQoNCnN0YXRpYyB2b2lkIExPR19QUklOVChpbnQgcHJpb3JpdHksIGNvbnN0IGNoYXIqIGZtdCwgLi4uKQ0Kew0KICAgIHZhX2xpc3QgYXJncyA9IHswfTsNCgljaGFyIGJ1ZmZbNTEyXTsNCgltZW1zZXQoYnVmZiwgMHgwMCwgc2l6ZW9mKGJ1ZmYpKTsNCiAgICB2YV9zdGFydChhcmdzLCBmbXQpOyANCgl2c25wcmludGYoYnVmZiwgc2l6ZW9mKGJ1ZmYpLCBmbXQsIGFyZ3MpOw0KCXZhX2VuZChhcmdzKTsgIA0KCXN5c2xvZyhwcmlvcml0eSwiQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAlcyIsIGJ1ZmYpOyANCglwcmludGYoIiVzXG4iLCBidWZmKTsNCgkNCn0NCg0KLy/TydPaaXByb3V0ZdbQsru05tTavauhsHVkcKGxoaKhsHRjcKGx19S2r9equ7vOqs/g06a0q8rksuPQrdLpusW1xLmmxNyjrNLytMvU2sXk1sNpcHNlY8qxo6zWsb3TyrnTw7SryuSy49Ct0um6xcXk1sNwcm90b7LOyv0NCmludCBpcHNlY19zZXQoaW50IHMsIHZvaWQgKmRhdGEsIGludCBkYXRhbGVuKQ0Kew0KDQoJaXBzZWNfc2V0X21zZyAqc2V0X21zZyA9IChpcHNlY19zZXRfbXNnICopZGF0YTsNCgl1bnNpZ25lZCBzaG9ydCBjbGllbnRfcG9ydCwgc2VydmVyX3BvcnQ7DQoJaW50IHNwaTsNCgljaGFyICogc291cmNlX2FkZHIsICpkZXN0X2FkZHIsICphdXRoX2tleSwgKmNyeXB0b19rZXksICp4ZnJtcHJvdG8sICptb2RlLCAqZWFsZywgKmFsZywgKmRpcjsNCgljaGFyIGNtZFs1MTJdOw0KCQ0KCWlmKHMgPCAwKQ0KCXsNCgkJTE9HX1BSSU5UKExPR19BTEVSVCwiaXBzZWNfc2V0OnNvY2tldCBzIGlzIG5vdCBsZWdhbCIpOw0KCQlyZXR1cm4gLTE7CQkNCgl9DQoJaWYgKGRhdGEgPT0gTlVMTCkNCgl7DQoJCUxPR19QUklOVChMT0dfQUxFUlQsImlwc2VjX3NldDpkYXRhIGlzIG5vdCBsZWdhbCIpOw0KCQlyZXR1cm4gLTE7DQoJfQ0KCQ0KCWlmKGRhdGFsZW4gIT0gc2l6ZW9mKGlwc2VjX3NldF9tc2cpKQ0KCXsNCgkJTE9HX1BSSU5UKExPR19BTEVSVCwiaXBzZWNfc2V0OlRoZSBsZW5ndGggb2YgbXNnIGlzIG5vdCBsZWdhbCIpOw0KCQlyZXR1cm4gLTE7DQoJfQ0KDQoJY3J5cHRvX2tleSA9IHNldF9tc2ctPkNrZXk7DQoJeGZybXByb3RvID0gc2V0X21zZy0+UHJvdDsNCgltb2RlID0gc2V0X21zZy0+TW9kOw0KCWVhbGcgPSBzZXRfbXNnLT5FYWxnOw0KCWFsZyA9IHNldF9tc2ctPkFsZzsNCglkaXIgPSBzZXRfbXNnLT5kaXI7DQoJYXV0aF9rZXkgPSBzZXRfbXNnLT5Ja2V5Ow0KCWNsaWVudF9wb3J0ID0gc2V0X21zZy0+UG9ydEM7DQoJc2VydmVyX3BvcnQgPSBzZXRfbXNnLT5Qb3J0UzsNCglzcGkgPSBzZXRfbXNnLT5TcGk7DQoJDQoJaWYgKDEgPT0gc2V0X21zZy0+SXNJcHY0KQ0KCXsNCgkJc291cmNlX2FkZHIgPSBzZXRfbXNnLT5TcmNJcHY0Ow0KCQlkZXN0X2FkZHIgPSBzZXRfbXNnLT5EZXN0SXB2NDsNCgl9DQoJZWxzZQ0KCXsNCgkJc291cmNlX2FkZHIgPSBzZXRfbXNnLT5TcmNJcHY2Ow0KCQlkZXN0X2FkZHIgPSBzZXRfbXNnLT5EZXN0SXB2NjsNCgl9DQoJDQoJaWYoMCA9PSBzdHJjbXAoYWxnLCJobWFjLW1kNS05NiIpKQ0KCXsNCgkJbWVtc2V0KGFsZywweDAwLHN0cmxlbihhbGcpKTsNCgkJc3ByaW50ZihhbGcsIm1kNSIpOw0KCX0NCgllbHNlIGlmICgwID09IHN0cmNtcChhbGcsImhtYWMtc2hhLTEtOTYiKSkNCgl7DQoJCW1lbXNldChhbGcsMHgwMCxzdHJsZW4oYWxnKSk7DQoJCXNwcmludGYoYWxnLCJzaGExIik7DQoJfQ0KCWVsc2UNCgl7DQoJCUxPR19QUklOVChMT0dfQUxFUlQsImlwc2VjX3NldDpPTkxZIHN1cHBvcnQgbWQ1IGFuZCBzaGExIGFsZ29yaXRobSBub3csIGFsZyAlcyBpcyBub3QgdmFsaWQiLGFsZyk7DQoJCXJldHVybiAtMTsNCgl9DQoJDQoJaWYoMCA9PSBzdHJjbXAoZWFsZywiYWVzLWNiYyIpKQ0KCXsNCgkJbWVtc2V0KGVhbGcsMHgwMCxzdHJsZW4oZWFsZykpOw0KCQlzcHJpbnRmKGVhbGcsImFlcyIpOw0KCX0NCgllbHNlIGlmKDAgPT0gc3RyY21wKGVhbGcsImRlcy1lZGUzLWNiYyIpKQ0KCXsNCgkJbWVtc2V0KGVhbGcsMHgwMCxzdHJsZW4oZWFsZykpOw0KCQlzcHJpbnRmKGVhbGcsImRlczNfZWRlIik7DQoJfQ0KCWVsc2UgaWYoMCA9PSBzdHJjbXAoZWFsZywibnVsbCIpKQ0KCXsNCgkJbWVtc2V0KGVhbGcsMHgwMCxzdHJsZW4oZWFsZykpOw0KCQlzcHJpbnRmKGVhbGcsImNpcGhlcl9udWxsIik7DQoJCW1lbXNldChjcnlwdG9fa2V5LDB4MDAsc3RybGVuKGNyeXB0b19rZXkpKTsNCgkJc3ByaW50ZihjcnlwdG9fa2V5LCJcIlwiIik7DQoJfQ0KCWVsc2UNCgl7DQoJCUxPR19QUklOVChMT0dfQUxFUlQsImlwc2VjX3NldDpPTkxZIHN1cHBvcnQgYWVzLWNiY6OsZGVzLWVkZTMtY2JjIGFuZCBudWxsIHRocmVlIGNyeXB0byBhbGdvcml0aG0sIHRoZSBhbGcgJXMgaXMgbm90IHZhbGlkIiwgZWFsZyk7DQoJCXJldHVybiAtMTsNCgl9DQoJDQoJbWVtc2V0KGNtZCwgMHgwMCwgc2l6ZW9mKGNtZCkpOyANCglpZigwICE9IHN0cmNtcChlYWxnLCJjaXBoZXJfbnVsbCIpKQ0KCXsNCgkJc3ByaW50ZihjbWQsICJpcCB4ZnJtIHN0YXRlIGFkZCBzcmMgJXMgZHN0ICVzIHByb3RvICVzIHNwaSAweCV4ICBhdXRoICVzIDB4JXMgZW5jICVzIDB4JXMgbW9kZSAlcyIsIA0KCQkJCQkJCQlzb3VyY2VfYWRkciwgZGVzdF9hZGRyLCB4ZnJtcHJvdG8sIHNwaSwgYWxnLGF1dGhfa2V5LCBlYWxnLGNyeXB0b19rZXksIG1vZGUpOw0KCX0NCgllbHNlDQoJew0KCQlzcHJpbnRmKGNtZCwgImlwIHhmcm0gc3RhdGUgYWRkIHNyYyAlcyBkc3QgJXMgcHJvdG8gJXMgc3BpIDB4JXggIGF1dGggJXMgMHglcyBlbmMgJXMgJXMgbW9kZSAlcyIsIA0KCQkJCQkJCQlzb3VyY2VfYWRkciwgZGVzdF9hZGRyLCB4ZnJtcHJvdG8sIHNwaSwgYWxnLGF1dGhfa2V5LCBlYWxnLGNyeXB0b19rZXksIG1vZGUpOw0KCX0NCglzb2Z0X3N5c3RlbShjbWQpOw0KDQoJTE9HX1BSSU5UKExPR19BTEVSVCwiaXBzZWNfc2V0OiVzXG4iLCBjbWQpOw0KCQ0KCW1lbXNldChjbWQsIDB4MDAsIHNpemVvZihjbWQpKTsgDQoJLy/F5NbDdWRw0K3S6Wlwc2Vjss7K/aOsdWRwtKvK5LLj0K3S6brFzqoxNw0KCXNwcmludGYoY21kLCAiaXAgeGZybSBwb2xpY3kgYWRkIGRpciAlcyBzcmMgJXMgZHN0ICVzIHByb3RvIDE3IHNwb3J0ICVkIGRwb3J0ICVkIHB0eXBlIG1haW4gdG1wbCBzcmMgJXMgZHN0ICVzIHByb3RvIGVzcCBzcGkgJWQgbW9kZSB0cmFuc3BvcnQiLA0KCQkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRpciwgc291cmNlX2FkZHIsIGRlc3RfYWRkciwgY2xpZW50X3BvcnQsIHNlcnZlcl9wb3J0LCBzb3VyY2VfYWRkciwgZGVzdF9hZGRyLCBzcGkpOw0KCXNvZnRfc3lzdGVtKGNtZCk7DQoJTE9HX1BSSU5UKExPR19BTEVSVCwiaXBzZWNfc2V0OiVzXG4iLCBjbWQpOw0KCQ0KCW1lbXNldChjbWQsIDB4MDAsIHNpemVvZihjbWQpKTsgDQoJLy/F5NbDdGNw0K3S6Wlwc2Vjss7K/aOsdGNwtKvK5LLj0K3S6brFzqo2DQoJc3ByaW50ZihjbWQsICJpcCB4ZnJtIHBvbGljeSBhZGQgZGlyICVzIHNyYyAlcyBkc3QgJXMgcHJvdG8gNiBzcG9ydCAlZCBkcG9ydCAlZCBwdHlwZSBtYWluIHRtcGwgc3JjICVzIGRzdCAlcyBwcm90byBlc3Agc3BpICVkIG1vZGUgdHJhbnNwb3J0IiwNCgkJICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkaXIsIHNvdXJjZV9hZGRyLCBkZXN0X2FkZHIsIGNsaWVudF9wb3J0LCBzZXJ2ZXJfcG9ydCwgc291cmNlX2FkZHIsIGRlc3RfYWRkciwgc3BpKTsNCglzb2Z0X3N5c3RlbShjbWQpOw0KCQ0KCUxPR19QUklOVChMT0dfQUxFUlQsImlwc2VjX3NldDolc1xuIiwgY21kKTsNCgkNCgkNCglyZXR1cm4gMDsNCn0NCg0KDQppbnQgaXBzZWNfZGVsKGludCBzLCB2b2lkICpkYXRhLCBpbnQgZGF0YWxlbikNCnsNCglpcHNlY19kZWxfbXNnICogcF9kZWxfbXNnID0gKGlwc2VjX2RlbF9tc2cgKilkYXRhOw0KCWlwc2VjX2RlbF9tc2cgKiBkZWxfbXNnID0gTlVMTDsNCgl1bnNpZ25lZCBzaG9ydCBjbGllbnRfcG9ydCwgc2VydmVyX3BvcnQ7DQoJaW50IHNwaSwgaTsNCgljaGFyICogc291cmNlX2FkZHIsICpkZXN0X2FkZHIsICphdXRoX2tleSwgKmNyeXB0b19rZXksICp4ZnJtcHJvdG8sICptb2RlLCAqZWFsZywgKmFsZywgKmRpcjsNCgljaGFyIGNtZFs1MTJdOw0KCQ0KCWlmKHMgPCAwKQ0KCXsNCgkJTE9HX1BSSU5UKExPR19BTEVSVCwiaXBzZWNfZGVsOnNvY2tldCBzIGlzIG5vdCBsZWdhbCIpOw0KCQlyZXR1cm4gLTE7CQkNCgl9DQoJDQoJaWYgKGRhdGEgPT0gTlVMTCkNCgl7DQoJCUxPR19QUklOVChMT0dfQUxFUlQsImlwc2VjX2RlbDpkYXRhIGlzIG5vdCBsZWdhbCIpOw0KCQlyZXR1cm4gLTE7DQoJfQ0KCQ0KCWlmKCAwIT0gZGF0YWxlbiVzaXplb2YoaXBzZWNfZGVsX21zZykpDQoJew0KCQlMT0dfUFJJTlQoTE9HX0FMRVJULCJpcHNlY19kZWw6VGhlIGxlbmd0aCBvZiBtc2cgaXMgbm90IGxlZ2FsIik7DQoJCXJldHVybiAtMTsNCgl9DQoJDQoNCglmb3IoaSA9IDA7aTxkYXRhbGVuL3NpemVvZihpcHNlY19kZWxfbXNnKTtpKyspDQoJew0KCQlkZWxfbXNnID0gcF9kZWxfbXNnK2k7DQoNCgkJY3J5cHRvX2tleSA9IGRlbF9tc2ctPkNrZXk7DQoJCXhmcm1wcm90byA9IGRlbF9tc2ctPlByb3Q7DQoJCW1vZGUgPSBkZWxfbXNnLT5Nb2Q7DQoJCWVhbGcgPSBkZWxfbXNnLT5FYWxnOw0KCQlhbGcgPSBkZWxfbXNnLT5BbGc7DQoJCWRpciA9IGRlbF9tc2ctPmRpcjsNCgkJYXV0aF9rZXkgPSBkZWxfbXNnLT5Ja2V5Ow0KCQljbGllbnRfcG9ydCA9IGRlbF9tc2ctPlBvcnRDOw0KCQlzZXJ2ZXJfcG9ydCA9IGRlbF9tc2ctPlBvcnRTOw0KCQlzcGkgPSBkZWxfbXNnLT5TcGk7DQoJCQ0KCQlpZiAoMSA9PSBkZWxfbXNnLT5Jc0lwdjQpDQoJCXsNCgkJCXNvdXJjZV9hZGRyID0gZGVsX21zZy0+U3JjSXB2NDsNCgkJCWRlc3RfYWRkciA9IGRlbF9tc2ctPkRlc3RJcHY0Ow0KCQl9DQoJCWVsc2UNCgkJew0KCQkJc291cmNlX2FkZHIgPSBkZWxfbXNnLT5TcmNJcHY2Ow0KCQkJZGVzdF9hZGRyID0gZGVsX21zZy0+RGVzdElwdjY7DQoJCX0NCgkJDQoJCW1lbXNldChjbWQsIDB4MDAsIHNpemVvZihjbWQpKTsgDQoJCQ0KCQlzcHJpbnRmKGNtZCwiaXAgeGZybSBzdGF0ZSBkZWxhbGwgc3BpIDB4JXgiLHNwaSk7DQoJCXNvZnRfc3lzdGVtKGNtZCk7DQoNCgkJTE9HX1BSSU5UKExPR19BTEVSVCwiaXBzZWNfZGVsOiVzXG4iLCBjbWQpOw0KCQkNCgkJbWVtc2V0KGNtZCwgMHgwMCwgc2l6ZW9mKGNtZCkpOyANCgkJLy/JvrP9dWRw0K3S6Wlwc2VjxeTWww0KCQlzcHJpbnRmKGNtZCwgImlwIHhmcm0gcG9saWN5IGRlbGFsbCBkaXIgJXMgc3JjICVzIGRzdCAlcyBwcm90byAxNyBzcG9ydCAlZCBkcG9ydCAlZCIsZGlyLCBzb3VyY2VfYWRkciwgZGVzdF9hZGRyLCBjbGllbnRfcG9ydCwgc2VydmVyX3BvcnQpOw0KCQlzb2Z0X3N5c3RlbShjbWQpOw0KCQlMT0dfUFJJTlQoTE9HX0FMRVJULCJpcHNlY19kZWw6JXNcbiIsIGNtZCk7DQoJCQ0KCQltZW1zZXQoY21kLCAweDAwLCBzaXplb2YoY21kKSk7IA0KCQkvL8m+s/10Y3DQrdLpaXBzZWPF5NbDDQoJCXNwcmludGYoY21kLCAiaXAgeGZybSBwb2xpY3kgZGVsYWxsIGRpciAlcyBzcmMgJXMgZHN0ICVzIHByb3RvIDYgc3BvcnQgJWQgZHBvcnQgJWQgIixkaXIsIHNvdXJjZV9hZGRyLCBkZXN0X2FkZHIsIGNsaWVudF9wb3J0LCBzZXJ2ZXJfcG9ydCk7DQoJCXNvZnRfc3lzdGVtKGNtZCk7DQoJCQ0KCQlMT0dfUFJJTlQoTE9HX0FMRVJULCJpcHNlY19kZWw6JXNcbiIsIGNtZCk7DQoJfQ0KCXJldHVybiAwOw0KfQ0KDQojaWYgMA0KaW50IGlwc2VjX3NldF9zYShpbnQgcywgdm9pZCAqZGF0YSwgaW50IGRhdGFsZW4pDQp7DQoJDQoJaXBzZWNfc2V0X3NhX21zZyAqIHNldF9zYV9tc2cgPSAoaXBzZWNfc2V0X3NhX21zZyAqKWRhdGE7DQoJaW50IHNwaTsNCgljaGFyICogc291cmNlX2FkZHIsICpkZXN0X2FkZHIsICphdXRoX2tleSwgKmNyeXB0b19rZXksICp4ZnJtcHJvdG8sICptb2RlLCAqZWFsZywgKmFsZzsNCgljaGFyIGNtZFs1MTJdOw0KCQ0KCWlmKHMgPCAwKQ0KCXsNCgkJTE9HX1BSSU5UKExPR19BTEVSVCwiaXBzZWNfc2V0X3NhOnNvY2tldCBzIGlzIG5vdCBsZWdhbCIpOw0KCQlyZXR1cm4gLTE7CQkNCgl9DQoJDQoJaWYgKGRhdGEgPT0gTlVMTCkNCgl7DQoJCUxPR19QUklOVChMT0dfQUxFUlQsImlwc2VjX3NldF9zYTpkYXRhIGlzIG5vdCBsZWdhbCIpOw0KCQlyZXR1cm4gLTE7DQoJfQ0KCQ0KCWlmKGRhdGFsZW4gIT0gc2l6ZW9mKGlwc2VjX3NldF9zYV9tc2cpKQ0KCXsNCgkJTE9HX1BSSU5UKExPR19BTEVSVCwiaXBzZWNfc2V0X3NhOlRoZSBsZW5ndGggb2YgbXNnIGlzIG5vdCBsZWdhbCIpOw0KCQlyZXR1cm4gLTE7DQoJfQ0KCQ0KCWNyeXB0b19rZXkgPSBzZXRfc2FfbXNnLT5Da2V5Ow0KCXhmcm1wcm90byA9IHNldF9zYV9tc2ctPlhmcm1Qcm90Ow0KCW1vZGUgPSBzZXRfc2FfbXNnLT5Nb2Q7DQoJZWFsZyA9IHNldF9zYV9tc2ctPkVhbGc7DQoJYWxnID0gc2V0X3NhX21zZy0+QWxnOw0KCWF1dGhfa2V5ID0gc2V0X3NhX21zZy0+SWtleTsNCglzcGkgPSBzZXRfc2FfbXNnLT5TcGk7DQoJDQoJaWYgKDEgPT0gc2V0X3NhX21zZy0+SXNJcHY0KQ0KCXsNCgkJc291cmNlX2FkZHIgPSBzZXRfc2FfbXNnLT5TcmNJcHY0Ow0KCQlkZXN0X2FkZHIgPSBzZXRfc2FfbXNnLT5EZXN0SXB2NDsNCgl9DQoJZWxzZQ0KCXsNCgkJc291cmNlX2FkZHIgPSBzZXRfc2FfbXNnLT5TcmNJcHY2Ow0KCQlkZXN0X2FkZHIgPSBzZXRfc2FfbXNnLT5EZXN0SXB2NjsNCgl9DQoJDQoJaWYoMCA9PSBzdHJjbXAoYWxnLCJobWFjLW1kNS05NiIpKQ0KCXsNCgkJbWVtc2V0KGFsZywweDAwLHNpemVvZihhbGcpKTsNCgkJc3ByaW50ZihhbGcsIm1kNSIpOw0KCX0NCgllbHNlIGlmICgwID09IHN0cmNtcChhbGcsImhtYWMtc2hhLTEtOTYiKSkNCgl7DQoJCW1lbXNldChhbGcsMHgwMCxzaXplb2YoYWxnKSk7DQoJCXNwcmludGYoYWxnLCJzaGExIik7DQoJfQ0KCWVsc2UNCgl7DQoJCUxPR19QUklOVChMT0dfQUxFUlQsImlwc2VjX3NldF9zYTpPTkxZIHN1cHBvcnQgbWQ1IGFuZCBzaGExIGFsZ29yaXRobSBub3csIGFsZyAlcyBpcyBub3QgdmFsaWQiLGFsZyk7DQoJCXJldHVybiAtMTsNCgl9DQoJDQoJaWYoMCA9PSBzdHJjbXAoZWFsZywiYWVzLWNiYyIpKQ0KCXsNCgkJbWVtc2V0KGVhbGcsMHgwMCxzaXplb2YoZWFsZykpOw0KCQlzcHJpbnRmKGVhbGcsImFlcyIpOw0KCX0NCgllbHNlIGlmKDAgPT0gc3RyY21wKGVhbGcsImRlcy1lZGUzLWNiYyIpKQ0KCXsNCgkJbWVtc2V0KGVhbGcsMHgwMCxzaXplb2YoZWFsZykpOw0KCQlzcHJpbnRmKGVhbGcsImRlczNfZWRlIik7DQoJfQ0KCWVsc2UgaWYoMCA9PSBzdHJjbXAoZWFsZywibnVsbCIpKQ0KCXsNCgkJbWVtc2V0KGVhbGcsMHgwMCxzaXplb2YoZWFsZykpOw0KCQlzcHJpbnRmKGVhbGcsImNpcGhlcl9udWxsIik7DQoJCW1lbXNldChjcnlwdG9fa2V5LDB4MDAsc2l6ZW9mKGNyeXB0b19rZXkpKTsNCgkJc3ByaW50ZihjcnlwdG9fa2V5LCJcIlwiIik7DQoJfQ0KCWVsc2UNCgl7DQoJCUxPR19QUklOVChMT0dfQUxFUlQsImlwc2VjX3NldF9zYTpPTkxZIHN1cHBvcnQgYWVzLWNiY6OsZGVzLWVkZTMtY2JjIGFuZCBudWxsIHRocmVlIGNyeXB0byBhbGdvcml0aG0sIHRoZSBhbGcgJXMgaXMgbm90IHZhbGlkIiwgZWFsZyk7DQoJCXJldHVybiAtMTsNCgl9DQoJDQoJbWVtc2V0KGNtZCwgMHgwMCwgc2l6ZW9mKGNtZCkpOyANCglpZigwICE9IHN0cmNtcChlYWxnLCJjaXBoZXJfbnVsbCIpKQ0KCXsNCgkJc3ByaW50ZihjbWQsICJpcCB4ZnJtIHN0YXRlIGFkZCBzcmMgJXMgZHN0ICVzIHByb3RvICVzIHNwaSAweCV4IGF1dGggJXMgMHglcyBlbmMgJXMgMHglcyBtb2RlICVzIiwgDQoJCQkJCQkJCXNvdXJjZV9hZGRyLCBkZXN0X2FkZHIsIHhmcm1wcm90bywgc3BpLCBhbGcsYXV0aF9rZXksIGVhbGcsY3J5cHRvX2tleSwgbW9kZSk7DQoJfQ0KCWVsc2UNCgl7DQoJCXNwcmludGYoY21kLCAiaXAgeGZybSBzdGF0ZSBhZGQgc3JjICVzIGRzdCAlcyBwcm90byAlcyBzcGkgMHgleCAgYXV0aCAlcyAweCVzIGVuYyAlcyAlcyBtb2RlICVzIiwgDQoJCQkJCQkJCXNvdXJjZV9hZGRyLCBkZXN0X2FkZHIsIHhmcm1wcm90bywgc3BpLCBhbGcsYXV0aF9rZXksIGVhbGcsIGNyeXB0b19rZXksIG1vZGUpOw0KCX0NCglzeXN0ZW0oY21kKTsNCg0KCUxPR19QUklOVChMT0dfQUxFUlQsImlwc2VjX3NldF9zYTolc1xuIiwgY21kKTsNCglyZXR1cm4gMDsNCn0NCg0KDQppbnQgaXBzZWNfc2V0X3NwKGludCBzLCB2b2lkICpkYXRhLCBpbnQgZGF0YWxlbikNCnsNCglpcHNlY19zZXRfc3BfbXNnICogc2V0X3NwX21zZyA9IChpcHNlY19zZXRfc3BfbXNnICopZGF0YTsNCgl1bnNpZ25lZCBzaG9ydCBjbGllbnRfcG9ydCwgc2VydmVyX3BvcnQ7DQoJaW50ICBwcm90bzsNCgljaGFyICogc291cmNlX2FkZHIsICpkZXN0X2FkZHIsICpkaXI7DQoJY2hhciBjbWRbNTEyXSwgY21kX3RjcFs1MTJdOw0KCWludCBvZmZzZXQgPSAwLCBvZmZzZXRfdGNwID0gMDsNCg0KCWlmKHMgPCAwKQ0KCXsNCgkJTE9HX1BSSU5UKExPR19BTEVSVCwiaXBzZWNfc2V0X3NwOnNvY2tldCBzIGlzIG5vdCBsZWdhbCIpOw0KCQlyZXR1cm4gLTE7CQkNCgl9DQoJDQoJaWYgKGRhdGEgPT0gTlVMTCkNCgl7DQoJCUxPR19QUklOVChMT0dfQUxFUlQsImlwc2VjX3NldF9zcDpkYXRhIGlzIG5vdCBsZWdhbCIpOw0KCQlyZXR1cm4gLTE7DQoJfQ0KCQ0KCWlmKGRhdGFsZW4gIT0gc2l6ZW9mKGlwc2VjX3NldF9zcF9tc2cpKQ0KCXsNCgkJTE9HX1BSSU5UKExPR19BTEVSVCwiaXBzZWNfZGVsX3NwOlRoZSBsZW5ndGggb2YgbXNnIGlzIG5vdCBsZWdhbCIpOw0KCQlyZXR1cm4gLTE7DQoJfQ0KCQ0KCXByb3RvID0gc2V0X3NwX21zZy0+UHJvdDsNCglkaXIgPSBzZXRfc3BfbXNnLT5kaXI7DQoJY2xpZW50X3BvcnQgPSBzZXRfc3BfbXNnLT5Qb3J0QzsNCglzZXJ2ZXJfcG9ydCA9IHNldF9zcF9tc2ctPlBvcnRTOw0KCWlmICgxID09IHNldF9zcF9tc2ctPklzSXB2NCkNCgl7DQoJCXNvdXJjZV9hZGRyID0gc2V0X3NwX21zZy0+U3JjSXB2NDsNCgkJZGVzdF9hZGRyID0gc2V0X3NwX21zZy0+RGVzdElwdjQ7DQoJfQ0KCWVsc2UNCgl7DQoJCXNvdXJjZV9hZGRyID0gc2V0X3NwX21zZy0+U3JjSXB2NjsNCgkJZGVzdF9hZGRyID0gc2V0X3NwX21zZy0+RGVzdElwdjY7DQoJfQ0KCQ0KDQoJaWYoIHByb3RvIDwgSVBTRUNfUFJPVE9fQkFTRSB8fCBwcm90byA+IElQU0VDX1BST1RPX01BWCkNCgl7DQoJCUxPR19QUklOVChMT0dfQUxFUlQsImlwc2VjX3NldF9zcDppcHNlYyBwcm90b2NvbCBvbmx5IHN1cHBvcnQgdGNwIGFuZCB1ZHAgbm93IVxuIik7DQoJCXJldHVybiAtMTsNCgl9DQoJDQoJbWVtc2V0KGNtZCwgMHgwMCwgc2l6ZW9mKGNtZCkpOw0KDQoJb2Zmc2V0ICs9IHNwcmludGYoY21kICsgb2Zmc2V0LCAiaXAgeGZybSBwb2xpY3kgYWRkICIpOw0KCQ0KCWlmKCAwICE9IHN0cmxlbihkaXIpKQ0KCXsNCgkJb2Zmc2V0ICs9IHNwcmludGYoY21kICsgb2Zmc2V0LCJkaXIgJXMgIiwgZGlyKTsNCgl9DQoNCglpZiggMCAhPSBzdHJsZW4oc291cmNlX2FkZHIpKQ0KCXsNCgkJCW9mZnNldCArPSBzcHJpbnRmKGNtZCArIG9mZnNldCwgInNyYyAlcyAiLCBzb3VyY2VfYWRkcik7DQoJfQ0KDQoJaWYoIDAgIT0gc3RybGVuKGRlc3RfYWRkcikpDQoJew0KCQkJb2Zmc2V0ICs9IHNwcmludGYoY21kICsgb2Zmc2V0LCAiZHN0ICVzICIsIGRlc3RfYWRkcik7DQoJfQ0KDQoJaWYoIChJUFNFQ19QUk9UT19VTktPV04gPT0gcHJvdG8pICYmIChjbGllbnRfcG9ydCB8fCBzZXJ2ZXJfcG9ydCkpDQoJew0KDQoJCUxPR19QUklOVChMT0dfQUxFUlQsImlwc2VjX3NldF9zcDppcHNlY19kZWxfc3AgOiBtc2cgbXVzdCBoYXZlIHByb3RvY29sIG1lc3NhZ2VzIHdoZW4gcG9ydCBpcyBub3QgZXF1YWwgdG8gemVybyFcbiIpOw0KCQlyZXR1cm4gLTE7DQoJCQ0KCX0NCgllbHNlIGlmKCBJUFNFQ19QUk9UT19VTktPV04gPT0gcHJvdG8pDQoJew0KCQlzeXN0ZW0oY21kKTsNCgkJTE9HX1BSSU5UKExPR19BTEVSVCwiaXBzZWNfc2V0X3NwOiVzXG4iLCBjbWQpOw0KCX0NCgllbHNlDQoJew0KCQlvZmZzZXRfdGNwICs9IHNwcmludGYoY21kX3RjcCArIG9mZnNldF90Y3AsICIlcyIsY21kKTsNCgkJDQoJCWlmKCBwcm90byZJUFNFQ19QUk9UT19VRFApDQoJCXsNCgkJCW9mZnNldCArPSBzcHJpbnRmKGNtZCArIG9mZnNldCwgInByb3RvIDE3ICIpOw0KCQkJaWYoY2xpZW50X3BvcnQpDQoJCQl7DQoJCQkJb2Zmc2V0ICs9IHNwcmludGYoY21kICsgb2Zmc2V0LCJzcG9ydCAlZCAiLCBjbGllbnRfcG9ydCk7DQoJCQl9DQoJCQlpZihzZXJ2ZXJfcG9ydCkNCgkJCXsNCgkJCQlvZmZzZXQgKz0gc3ByaW50ZihjbWQgKyBvZmZzZXQsImRwb3J0ICVkICIsIHNlcnZlcl9wb3J0KTsNCgkJCX0NCgkJCXN5c3RlbShjbWQpOw0KCQkJTE9HX1BSSU5UKExPR19BTEVSVCwiaXBzZWNfc2V0X3NwOiVzXG4iLCBjbWQpOw0KCQl9DQoNCgkJaWYocHJvdG8mSVBTRUNfUFJPVE9fVENQKQ0KCQl7DQoJCQlvZmZzZXRfdGNwICs9IHNwcmludGYoY21kX3RjcCArIG9mZnNldF90Y3AsICJwcm90byA2ICIpOw0KCQkJaWYoY2xpZW50X3BvcnQpDQoJCQl7DQoJCQkJb2Zmc2V0X3RjcCArPSBzcHJpbnRmKGNtZF90Y3AgKyBvZmZzZXRfdGNwLCJzcG9ydCAlZCAiLCBjbGllbnRfcG9ydCk7DQoJCQl9DQoJCQlpZihzZXJ2ZXJfcG9ydCkNCgkJCXsNCgkJCQlvZmZzZXRfdGNwICs9IHNwcmludGYoY21kX3RjcCArIG9mZnNldF90Y3AsImRwb3J0ICVkICIsIHNlcnZlcl9wb3J0KTsNCgkJCX0NCgkJCXN5c3RlbShjbWRfdGNwKTsNCgkJCUxPR19QUklOVChMT0dfQUxFUlQsImlwc2VjX3NldF9zcDolc1xuIiwgY21kX3RjcCk7DQoJCX0NCgl9DQoJcmV0dXJuIDA7DQp9DQoNCmludCBpcHNlY19kZWxfc2EoaW50IHMsIHZvaWQgKmRhdGEsIGludCBkYXRhbGVuKQ0Kew0KCWlwc2VjX2RlbF9zYV9tc2cgKiBkZWxfc2FfbXNnID0gKGlwc2VjX2RlbF9zYV9tc2cgKilkYXRhOw0KCWludCBzcGk7DQoJY2hhciAqIHNvdXJjZV9hZGRyLCAqZGVzdF9hZGRyLCAgKnhmcm1wcm90bywgKm1vZGU7DQoJaW50IG9mZnNldCA9IDA7DQoJY2hhciBjbWRbNTEyXTsNCgkNCglpZihzIDwgMCkNCgl7DQoJCUxPR19QUklOVChMT0dfQUxFUlQsImlwc2VjX2RlbF9zYTpzb2NrZXQgcyBpcyBub3QgbGVnYWwiKTsNCgkJcmV0dXJuIC0xOwkJDQoJfQ0KCQ0KCWlmIChkYXRhID09IE5VTEwpDQoJew0KCQlMT0dfUFJJTlQoTE9HX0FMRVJULCJpcHNlY19kZWxfc2E6ZGF0YSBpcyBub3QgbGVnYWwiKTsNCgkJcmV0dXJuIC0xOw0KCX0NCgkNCglpZihkYXRhbGVuICE9IHNpemVvZihpcHNlY19kZWxfc2FfbXNnKSkNCgl7DQoJCUxPR19QUklOVChMT0dfQUxFUlQsImlwc2VjX2RlbF9zYTpUaGUgbGVuZ3RoIG9mIG1zZyBpcyBub3QgbGVnYWwiKTsNCgkJcmV0dXJuIC0xOw0KCX0NCgkNCgl4ZnJtcHJvdG8gPSBkZWxfc2FfbXNnLT5YZnJtUHJvdDsNCgltb2RlID0gZGVsX3NhX21zZy0+TW9kOw0KCXNwaSA9IGRlbF9zYV9tc2ctPlNwaTsNCgkNCglpZiAoMSA9PSBkZWxfc2FfbXNnLT5Jc0lwdjQpDQoJew0KCQlzb3VyY2VfYWRkciA9IGRlbF9zYV9tc2ctPlNyY0lwdjQ7DQoJCWRlc3RfYWRkciA9IGRlbF9zYV9tc2ctPkRlc3RJcHY0Ow0KCX0NCgllbHNlDQoJew0KCQlzb3VyY2VfYWRkciA9IGRlbF9zYV9tc2ctPlNyY0lwdjY7DQoJCWRlc3RfYWRkciA9IGRlbF9zYV9tc2ctPkRlc3RJcHY2Ow0KCX0NCg0KDQoJbWVtc2V0KGNtZCwgMHgwMCwgc2l6ZW9mKGNtZCkpOw0KDQoNCglvZmZzZXQgKz0gc3ByaW50ZihjbWQgKyBvZmZzZXQsICJpcCB4ZnJtIHN0YXRlIGRlbGFsbCAiKTsNCg0KCWlmKCAwICE9IHN0cmxlbihzb3VyY2VfYWRkcikpDQoJew0KCQlvZmZzZXQgKz0gc3ByaW50ZihjbWQgKyBvZmZzZXQsICJzcmMgJXMgIixzb3VyY2VfYWRkcik7DQoJfQ0KDQoJaWYoIDAgIT0gc3RybGVuKGRlc3RfYWRkcikpDQoJew0KCQlvZmZzZXQgKz0gc3ByaW50ZihjbWQgKyBvZmZzZXQsICJkc3QgJXMgIixkZXN0X2FkZHIpOw0KCX0NCg0KCWlmKCAwICE9IHN0cmxlbih4ZnJtcHJvdG8pKQ0KCXsNCgkJb2Zmc2V0ICs9IHNwcmludGYoY21kICsgb2Zmc2V0LCAicHJvdG8gJXMgIiwgeGZybXByb3RvKTsNCgl9DQoNCglpZiggMCAhPSBzcGkpDQoJew0KCQlvZmZzZXQgKz0gc3ByaW50ZihjbWQgKyBvZmZzZXQsICJzcGkgMHgleCAiLHNwaSk7DQoJfQ0KDQoJaWYoIDAgIT0gc3RybGVuKG1vZGUpKQ0KCXsNCgkJb2Zmc2V0ICs9IHNwcmludGYoY21kICsgb2Zmc2V0LCAibW9kZSAlcyAiLCBtb2RlKTsNCgl9DQoJDQoJc3lzdGVtKGNtZCk7DQoNCglMT0dfUFJJTlQoTE9HX0FMRVJULCJpcHNlY19kZWxfc2E6JXNcbiIsIGNtZCk7DQoJDQoJcmV0dXJuIDA7DQoNCn0NCg0KDQppbnQgaXBzZWNfZGVsX3NwKGludCBzLCB2b2lkICpkYXRhLCBpbnQgZGF0YWxlbikNCnsNCglpcHNlY19kZWxfc3BfbXNnICogZGVsX3NwX21zZyA9IChpcHNlY19kZWxfc3BfbXNnICopZGF0YTsNCgl1bnNpZ25lZCBzaG9ydCBjbGllbnRfcG9ydCwgc2VydmVyX3BvcnQ7DQoJaW50ICBwcm90bzsNCgljaGFyICogc291cmNlX2FkZHIsICpkZXN0X2FkZHIsICpkaXI7DQoJY2hhciBjbWRbNTEyXSwgY21kX3RjcFs1MTJdOw0KCWludCBvZmZzZXQgPSAwLCBvZmZzZXRfdGNwID0gMDsNCg0KCWlmKHMgPCAwKQ0KCXsNCgkJTE9HX1BSSU5UKExPR19BTEVSVCwiaXBzZWNfZGVsX3NwOnNvY2tldCBzIGlzIG5vdCBsZWdhbCIpOw0KCQlyZXR1cm4gLTE7CQkNCgl9DQoJDQoJaWYgKGRhdGEgPT0gTlVMTCkNCgl7DQoJCUxPR19QUklOVChMT0dfQUxFUlQsImlwc2VjX2RlbF9zcDpkYXRhIGlzIG5vdCBsZWdhbCIpOw0KCQlyZXR1cm4gLTE7DQoJfQ0KCQ0KCWlmKGRhdGFsZW4gIT0gc2l6ZW9mKGlwc2VjX2RlbF9zcF9tc2cpKQ0KCXsNCgkJTE9HX1BSSU5UKExPR19BTEVSVCwiaXBzZWNfZGVsX3NwOlRoZSBsZW5ndGggb2YgbXNnIGlzIG5vdCBsZWdhbCIpOw0KCQlyZXR1cm4gLTE7DQoJfQ0KCQ0KCXByb3RvID0gZGVsX3NwX21zZy0+UHJvdDsNCglkaXIgPSBkZWxfc3BfbXNnLT5kaXI7DQoJY2xpZW50X3BvcnQgPSBkZWxfc3BfbXNnLT5Qb3J0QzsNCglzZXJ2ZXJfcG9ydCA9IGRlbF9zcF9tc2ctPlBvcnRTOw0KCWlmICgxID09IGRlbF9zcF9tc2ctPklzSXB2NCkNCgl7DQoJCXNvdXJjZV9hZGRyID0gZGVsX3NwX21zZy0+U3JjSXB2NDsNCgkJZGVzdF9hZGRyID0gZGVsX3NwX21zZy0+RGVzdElwdjQ7DQoJfQ0KCWVsc2UNCgl7DQoJCXNvdXJjZV9hZGRyID0gZGVsX3NwX21zZy0+U3JjSXB2NjsNCgkJZGVzdF9hZGRyID0gZGVsX3NwX21zZy0+RGVzdElwdjY7DQoJfQ0KCQ0KDQoJaWYoIHByb3RvIDwgSVBTRUNfUFJPVE9fQkFTRSB8fCBwcm90byA+IElQU0VDX1BST1RPX01BWCkNCgl7DQoJCUxPR19QUklOVChMT0dfQUxFUlQsImlwc2VjX2RlbF9zcDppcHNlYyBwcm90b2NvbCBvbmx5IHN1cHBvcnQgdGNwIGFuZCB1ZHAgbm93IVxuIik7DQoJCXJldHVybiAtMTsNCgl9DQoJDQoJbWVtc2V0KGNtZCwgMHgwMCwgc2l6ZW9mKGNtZCkpOw0KDQoJb2Zmc2V0ICs9IHNwcmludGYoY21kICsgb2Zmc2V0LCAiaXAgeGZybSBwb2xpY3kgZGVsYWxsICIpOw0KCQ0KCWlmKCAwICE9IHN0cmxlbihkaXIpKQ0KCXsNCgkJb2Zmc2V0ICs9IHNwcmludGYoY21kICsgb2Zmc2V0LCJkaXIgJXMgIiwgZGlyKTsNCgl9DQoNCglpZiggMCAhPSBzdHJsZW4oc291cmNlX2FkZHIpKQ0KCXsNCgkJCW9mZnNldCArPSBzcHJpbnRmKGNtZCArIG9mZnNldCwgInNyYyAlcyAiLCBzb3VyY2VfYWRkcik7DQoJfQ0KDQoJaWYoIDAgIT0gc3RybGVuKGRlc3RfYWRkcikpDQoJew0KCQkJb2Zmc2V0ICs9IHNwcmludGYoY21kICsgb2Zmc2V0LCAiZHN0ICVzICIsIGRlc3RfYWRkcik7DQoJfQ0KDQoJaWYoIChJUFNFQ19QUk9UT19VTktPV04gPT0gcHJvdG8pICYmIChjbGllbnRfcG9ydCB8fCBzZXJ2ZXJfcG9ydCkpDQoJew0KDQoJCUxPR19QUklOVChMT0dfQUxFUlQsImlwc2VjX2RlbF9zcDppcHNlY19kZWxfc3AgOiBtc2cgbXVzdCBoYXZlIHByb3RvY29sIG1lc3NhZ2VzIHdoZW4gcG9ydCBpcyBub3QgZXF1YWwgdG8gemVybyFcbiIpOw0KCQlyZXR1cm4gLTE7DQoJCQ0KCX0NCgllbHNlIGlmKCBJUFNFQ19QUk9UT19VTktPV04gPT0gcHJvdG8pDQoJew0KCQlzeXN0ZW0oY21kKTsNCgkJTE9HX1BSSU5UKExPR19BTEVSVCwiaXBzZWNfZGVsX3NwOiVzXG4iLCBjbWQpOw0KCX0NCgllbHNlDQoJew0KCQlvZmZzZXRfdGNwICs9IHNwcmludGYoY21kX3RjcCArIG9mZnNldF90Y3AsICIlcyIsY21kKTsNCgkJDQoJCWlmKCBwcm90byZJUFNFQ19QUk9UT19VRFApDQoJCXsNCgkJCW9mZnNldCArPSBzcHJpbnRmKGNtZCArIG9mZnNldCwgInByb3RvIDE3ICIpOw0KCQkJaWYoY2xpZW50X3BvcnQpDQoJCQl7DQoJCQkJb2Zmc2V0ICs9IHNwcmludGYoY21kICsgb2Zmc2V0LCJzcG9ydCAlZCAiLCBjbGllbnRfcG9ydCk7DQoJCQl9DQoJCQlpZihzZXJ2ZXJfcG9ydCkNCgkJCXsNCgkJCQlvZmZzZXQgKz0gc3ByaW50ZihjbWQgKyBvZmZzZXQsImRwb3J0ICVkICIsIHNlcnZlcl9wb3J0KTsNCgkJCX0NCgkJCXN5c3RlbShjbWQpOw0KCQkJTE9HX1BSSU5UKExPR19BTEVSVCwiaXBzZWNfZGVsX3NwOiVzXG4iLCBjbWQpOw0KCQl9DQoNCgkJaWYocHJvdG8mSVBTRUNfUFJPVE9fVENQKQ0KCQl7DQoJCQlvZmZzZXRfdGNwICs9IHNwcmludGYoY21kX3RjcCArIG9mZnNldF90Y3AsICJwcm90byA2ICIpOw0KCQkJaWYoY2xpZW50X3BvcnQpDQoJCQl7DQoJCQkJb2Zmc2V0X3RjcCArPSBzcHJpbnRmKGNtZF90Y3AgKyBvZmZzZXRfdGNwLCJzcG9ydCAlZCAiLCBjbGllbnRfcG9ydCk7DQoJCQl9DQoJCQlpZihzZXJ2ZXJfcG9ydCkNCgkJCXsNCgkJCQlvZmZzZXRfdGNwICs9IHNwcmludGYoY21kX3RjcCArIG9mZnNldF90Y3AsImRwb3J0ICVkICIsIHNlcnZlcl9wb3J0KTsNCgkJCX0NCgkJCXN5c3RlbShjbWRfdGNwKTsNCgkJCUxPR19QUklOVChMT0dfQUxFUlQsImlwc2VjX2RlbF9zcDolc1xuIiwgY21kX3RjcCk7DQoJCX0NCgl9DQoJcmV0dXJuIDA7DQp9DQojZW5kaWYNCg==