LyoKICogYWdlbnRfdHJhcC5jCiAqLwovKiBQb3J0aW9ucyBvZiB0aGlzIGZpbGUgYXJlIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb3B5cmlnaHQocykuICBTZWUKICogdGhlIE5ldC1TTk1QJ3MgQ09QWUlORyBmaWxlIGZvciBtb3JlIGRldGFpbHMgYW5kIG90aGVyIGNvcHlyaWdodHMKICogdGhhdCBtYXkgYXBwbHk6CiAqLwovKgogKiBQb3J0aW9ucyBvZiB0aGlzIGZpbGUgYXJlIGNvcHlyaWdodGVkIGJ5OgogKiBDb3B5cmlnaHQgqSAyMDAzIFN1biBNaWNyb3N5c3RlbXMsIEluYy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogVXNlIGlzIHN1YmplY3QgdG8gbGljZW5zZSB0ZXJtcyBzcGVjaWZpZWQgaW4gdGhlIENPUFlJTkcgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoZSBOZXQtU05NUCBwYWNrYWdlLgogKi8KLyoqIEBkZWZncm91cCBhZ2VudF90cmFwIFRyYXAgZ2VuZXJhdGlvbiByb3V0aW5lcyBmb3IgbWliIG1vZHVsZXMgdG8gdXNlCiAqICBAaW5ncm91cCBhZ2VudAogKgogKiBAewogKi8KCiNpbmNsdWRlIDxuZXQtc25tcC9uZXQtc25tcC1jb25maWcuaD4KCiNpZiBIQVZFX1VOSVNURF9ICiNpbmNsdWRlIDx1bmlzdGQuaD4KI2VuZGlmCiNpZiBIQVZFX05FVERCX0gKI2luY2x1ZGUgPG5ldGRiLmg+CiNlbmRpZgojaWYgSEFWRV9TVERMSUJfSAojaW5jbHVkZSA8c3RkbGliLmg+CiNlbmRpZgojaWYgSEFWRV9TVFJJTkdfSAojaW5jbHVkZSA8c3RyaW5nLmg+CiNlbHNlCiNpbmNsdWRlIDxzdHJpbmdzLmg+CiNlbmRpZgojaWYgVElNRV9XSVRIX1NZU19USU1FCiMgaW5jbHVkZSA8c3lzL3RpbWUuaD4KIyBpbmNsdWRlIDx0aW1lLmg+CiNlbHNlCiMgaWYgSEFWRV9TWVNfVElNRV9ICiMgIGluY2x1ZGUgPHN5cy90aW1lLmg+CiMgZWxzZQojICBpbmNsdWRlIDx0aW1lLmg+CiMgZW5kaWYKI2VuZGlmCiNpZiBIQVZFX1NZU19TT0NLRVRfSAojaW5jbHVkZSA8c3lzL3NvY2tldC5oPgojZW5kaWYKI2lmIEhBVkVfTkVUSU5FVF9JTl9ICiNpbmNsdWRlIDxuZXRpbmV0L2luLmg+CiNlbmRpZgojaW5jbHVkZSA8bmV0LXNubXAvdXRpbGl0aWVzLmg+CgojaW5jbHVkZSA8bmV0LXNubXAvbmV0LXNubXAtaW5jbHVkZXMuaD4KI2luY2x1ZGUgPG5ldC1zbm1wL2FnZW50L25ldC1zbm1wLWFnZW50LWluY2x1ZGVzLmg+CiNpbmNsdWRlIDxuZXQtc25tcC9hZ2VudC9hZ2VudF90cmFwLmg+CiNpbmNsdWRlIDxuZXQtc25tcC9hZ2VudC9zbm1wX2FnZW50Lmg+CiNpbmNsdWRlIDxuZXQtc25tcC9hZ2VudC9hZ2VudF9jYWxsYmFja3MuaD4KCiNpbmNsdWRlIDxuZXQtc25tcC9hZ2VudC9hZ2VudF9tb2R1bGVfY29uZmlnLmg+CiNpbmNsdWRlIDxuZXQtc25tcC9hZ2VudC9taWJfbW9kdWxlX2NvbmZpZy5oPgoKI2lmZGVmIFVTSU5HX0FHRU5UWF9QUk9UT0NPTF9NT0RVTEUKI2luY2x1ZGUgImFnZW50eC9wcm90b2NvbC5oIgojZW5kaWYKCnN0cnVjdCB0cmFwX3NpbmsgewogICAgbmV0c25tcF9zZXNzaW9uICpzZXNwOwogICAgc3RydWN0IHRyYXBfc2luayAqbmV4dDsKICAgIGludCAgICAgICAgICAgICBwZHV0eXBlOwogICAgaW50ICAgICAgICAgICAgIHZlcnNpb247Cn07CgpzdHJ1Y3QgdHJhcF9zaW5rICpzaW5rcyA9IE5VTEw7Cgpjb25zdCBvaWQgICAgICAgb2JqaWRfZW50ZXJwcmlzZXRyYXBbXSA9IHsgTkVUU05NUF9OT1RJRklDQVRJT05fTUlCIH07CmNvbnN0IG9pZCAgICAgICB0cmFwX3ZlcnNpb25faWRbXSA9IHsgTkVUU05NUF9TWVNURU1fTUlCIH07CmNvbnN0IGludCAgICAgICBlbnRlcnByaXNldHJhcF9sZW4gPSBPSURfTEVOR1RIKG9iamlkX2VudGVycHJpc2V0cmFwKTsKY29uc3QgaW50ICAgICAgIHRyYXBfdmVyc2lvbl9pZF9sZW4gPSBPSURfTEVOR1RIKHRyYXBfdmVyc2lvbl9pZCk7CgojZGVmaW5lIFNOTVBWMl9UUkFQU19QUkVGSVgJU05NUF9PSURfU05NUE1PRFVMRVMsMSwxLDUKY29uc3Qgb2lkICAgICAgIHRyYXBfcHJlZml4W10gICAgPSB7IFNOTVBWMl9UUkFQU19QUkVGSVggfTsKY29uc3Qgb2lkICAgICAgIGNvbGRfc3RhcnRfb2lkW10gPSB7IFNOTVBWMl9UUkFQU19QUkVGSVgsIDEgfTsgIC8qIFNOTVB2Mi1NSUIgKi8KCiNkZWZpbmUgU05NUFYyX1RSQVBfT0JKU19QUkVGSVgJU05NUF9PSURfU05NUE1PRFVMRVMsMSwxLDQKY29uc3Qgb2lkICAgICAgIHNubXB0cmFwX29pZFtdID0geyBTTk1QVjJfVFJBUF9PQkpTX1BSRUZJWCwgMSwgMCB9Owpjb25zdCBvaWQgICAgICAgc25tcHRyYXBlbnRlcnByaXNlX29pZFtdID0geyBTTk1QVjJfVFJBUF9PQkpTX1BSRUZJWCwgMywgMCB9Owpjb25zdCBvaWQgICAgICAgc3lzdXB0aW1lX29pZFtdID0geyBTTk1QX09JRF9NSUIyLCAxLCAzLCAwIH07CmNvbnN0IHNpemVfdCAgICBzbm1wdHJhcF9vaWRfbGVuID0gT0lEX0xFTkdUSChzbm1wdHJhcF9vaWQpOwpjb25zdCBzaXplX3QgICAgc25tcHRyYXBlbnRlcnByaXNlX29pZF9sZW4gPSBPSURfTEVOR1RIKHNubXB0cmFwZW50ZXJwcmlzZV9vaWQpOwpjb25zdCBzaXplX3QgICAgc3lzdXB0aW1lX29pZF9sZW4gPSBPSURfTEVOR1RIKHN5c3VwdGltZV9vaWQpOwoKI2RlZmluZSBTTk1QVjJfQ09NTV9PQkpTX1BSRUZJWAlTTk1QX09JRF9TTk1QTU9EVUxFUywxOCwxCmNvbnN0IG9pZCAgICAgICBhZ2VudGFkZHJfb2lkW10gPSB7IFNOTVBWMl9DT01NX09CSlNfUFJFRklYLCAzLCAwIH07CmNvbnN0IHNpemVfdCAgICBhZ2VudGFkZHJfb2lkX2xlbiA9IE9JRF9MRU5HVEgoYWdlbnRhZGRyX29pZCk7CmNvbnN0IG9pZCAgICAgICBjb21tdW5pdHlfb2lkW10gPSB7IFNOTVBWMl9DT01NX09CSlNfUFJFRklYLCA0LCAwIH07CmNvbnN0IHNpemVfdCAgICBjb21tdW5pdHlfb2lkX2xlbiA9IE9JRF9MRU5HVEgoY29tbXVuaXR5X29pZCk7CiNpZiAhZGVmaW5lZChORVRTTk1QX0RJU0FCTEVfU05NUFYxKSB8fCAhZGVmaW5lZChORVRTTk1QX0RJU0FCTEVfU05NUFYyQykKY2hhciAgICAgICAgICAgKnNubXBfdHJhcGNvbW11bml0eSA9IE5VTEw7CiNlbmRpZgoKCiNkZWZpbmUgU05NUF9BVVRIRU5USUNBVEVEX1RSQVBTX0VOQUJMRUQJMQojZGVmaW5lIFNOTVBfQVVUSEVOVElDQVRFRF9UUkFQU19ESVNBQkxFRAkyCgpsb25nICAgICAgICAgICAgc25tcF9lbmFibGVhdXRoZW50cmFwcyA9IFNOTVBfQVVUSEVOVElDQVRFRF9UUkFQU19ESVNBQkxFRDsKaW50ICAgICAgICAgICAgIHNubXBfZW5hYmxlYXV0aGVudHJhcHNzZXQgPSAwOwoKLyoKICogUHJvdG90eXBlcyAKICovCiAvKgogICogc3RhdGljIGludCBjcmVhdGVfdjFfdHJhcF9zZXNzaW9uIChjb25zdCBjaGFyICosIHVfc2hvcnQsIGNvbnN0IGNoYXIgKik7CiAgKiBzdGF0aWMgaW50IGNyZWF0ZV92Ml90cmFwX3Nlc3Npb24gKGNvbnN0IGNoYXIgKiwgdV9zaG9ydCwgY29uc3QgY2hhciAqKTsKICAqIHN0YXRpYyBpbnQgY3JlYXRlX3YyX2luZm9ybV9zZXNzaW9uIChjb25zdCBjaGFyICosIHVfc2hvcnQsIGNvbnN0IGNoYXIgKik7CiAgKiBzdGF0aWMgdm9pZCBmcmVlX3RyYXBfc2Vzc2lvbiAoc3RydWN0IHRyYXBfc2luayAqc3ApOwogICogc3RhdGljIHZvaWQgc2VuZF92MV90cmFwIChuZXRzbm1wX3Nlc3Npb24gKiwgaW50LCBpbnQpOwogICogc3RhdGljIHZvaWQgc2VuZF92Ml90cmFwIChuZXRzbm1wX3Nlc3Npb24gKiwgaW50LCBpbnQsIGludCk7CiAgKi8KCgogICAgICAgIC8qKioqKioqKioqKioqKioqKioqCgkgKgoJICogVHJhcCBzZXNzaW9uIGhhbmRsaW5nCgkgKgoJICoqKioqKioqKioqKioqKioqKiovCgp2b2lkCmluaXRfdHJhcHModm9pZCkKewp9CgpzdGF0aWMgdm9pZApmcmVlX3RyYXBfc2Vzc2lvbihzdHJ1Y3QgdHJhcF9zaW5rICpzcCkKewogICAgREVCVUdNU0dUTCgoInRyYXAiLCAiZnJlZWluZyBjYWxsYmFjayB0cmFwIHNlc3Npb24gKCVwLCAlcClcbiIsIHNwLCBzcC0+c2VzcCkpOwogICAgc25tcF9jbG9zZShzcC0+c2VzcCk7CiAgICBmcmVlKHNwKTsKfQoKaW50CmFkZF90cmFwX3Nlc3Npb24obmV0c25tcF9zZXNzaW9uICogc3MsIGludCBwZHV0eXBlLCBpbnQgY29uZmlybSwKICAgICAgICAgICAgICAgICBpbnQgdmVyc2lvbikKewogICAgaWYgKHNubXBfY2FsbGJhY2tfYXZhaWxhYmxlKFNOTVBfQ0FMTEJBQ0tfQVBQTElDQVRJT04sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU05NUERfQ0FMTEJBQ0tfUkVHSVNURVJfTk9USUZJQ0FUSU9OUykgPT0KICAgICAgICBTTk1QRVJSX1NVQ0NFU1MpIHsKICAgICAgICAvKgogICAgICAgICAqIHNvbWV0aGluZyBlbHNlIHdhbnRzIHRvIGhhbmRsZSBub3RpZmljYXRpb24gcmVnaXN0cmF0aW9ucyAKICAgICAgICAgKi8KICAgICAgICBzdHJ1Y3QgYWdlbnRfYWRkX3RyYXBfYXJncyBhcmdzOwogICAgICAgIERFQlVHTVNHVEwoKCJ0cmFwIiwgImFkZGluZyBjYWxsYmFjayB0cmFwIHNpbmsgKCVwKVxuIiwgc3MpKTsKICAgICAgICBhcmdzLnNzID0gc3M7CiAgICAgICAgYXJncy5jb25maXJtID0gY29uZmlybTsKICAgICAgICBzbm1wX2NhbGxfY2FsbGJhY2tzKFNOTVBfQ0FMTEJBQ0tfQVBQTElDQVRJT04sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBTTk1QRF9DQUxMQkFDS19SRUdJU1RFUl9OT1RJRklDQVRJT05TLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgKHZvaWQgKikgJmFyZ3MpOwogICAgfSBlbHNlIHsKICAgICAgICAvKgogICAgICAgICAqIG5vIG90aGVyIHN1cHBvcnQgZXhpc3RzLCBoYW5kbGUgaXQgb3Vyc2VsdmVzLiAKICAgICAgICAgKi8KICAgICAgICBzdHJ1Y3QgdHJhcF9zaW5rICpuZXdfc2luazsKCiAgICAgICAgREVCVUdNU0dUTCgoInRyYXAiLCAiYWRkaW5nIGludGVybmFsIHRyYXAgc2lua1xuIikpOwogICAgICAgIG5ld19zaW5rID0gKHN0cnVjdCB0cmFwX3NpbmsgKikgbWFsbG9jKHNpemVvZigqbmV3X3NpbmspKTsKICAgICAgICBpZiAobmV3X3NpbmsgPT0gTlVMTCkKICAgICAgICAgICAgcmV0dXJuIDA7CgogICAgICAgIG5ld19zaW5rLT5zZXNwID0gc3M7CiAgICAgICAgbmV3X3NpbmstPnBkdXR5cGUgPSBwZHV0eXBlOwogICAgICAgIG5ld19zaW5rLT52ZXJzaW9uID0gdmVyc2lvbjsKICAgICAgICBuZXdfc2luay0+bmV4dCA9IHNpbmtzOwogICAgICAgIHNpbmtzID0gbmV3X3Npbms7CiAgICB9CiAgICByZXR1cm4gMTsKfQoKaW50CnJlbW92ZV90cmFwX3Nlc3Npb24obmV0c25tcF9zZXNzaW9uICogc3MpCnsKICAgIHN0cnVjdCB0cmFwX3NpbmsgKnNwID0gc2lua3MsICpwcmV2ID0gTlVMTDsKCiAgICBERUJVR01TR1RMKCgidHJhcCIsICJyZW1vdmluZyB0cmFwIHNlc3Npb25zXG4iKSk7CiAgICB3aGlsZSAoc3ApIHsKICAgICAgICBpZiAoc3AtPnNlc3AgPT0gc3MpIHsKICAgICAgICAgICAgaWYgKHByZXYpIHsKICAgICAgICAgICAgICAgIHByZXYtPm5leHQgPSBzcC0+bmV4dDsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHNpbmtzID0gc3AtPm5leHQ7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogSSBkb24ndCBiZWxpZXZlIHlvdSAqcmVhbGx5KiB3YW50IHRvIGNsb3NlIHRoZSBzZXNzaW9uIGhlcmU7CiAgICAgICAgICAgICAqIGl0IG1heSBzdGlsbCBiZSBpbiB1c2UgZm9yIG90aGVyIHB1cnBvc2VzLiAgSW4gcGFydGljdWxhciB0aGlzCiAgICAgICAgICAgICAqIGlzIGF3a3dhcmQgZm9yIEFnZW50WCwgc2luY2Ugd2Ugd2FudCB0byBjYWxsIHRoaXMgZnVuY3Rpb24KICAgICAgICAgICAgICogZnJvbSB0aGUgc2Vzc2lvbidzIGNhbGxiYWNrLiAgTGV0J3MganVzdCBmcmVlIHRoZSB0cmFwc2luawogICAgICAgICAgICAgKiBkYXRhIHN0cnVjdHVyZS4gIFtqYnBuXSAgCiAgICAgICAgICAgICAqLwogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBmcmVlX3RyYXBfc2Vzc2lvbihzcCk7ICAKICAgICAgICAgICAgICovCiAgICAgICAgICAgIERFQlVHTVNHVEwoKCJ0cmFwIiwgInJlbW92aW5nIHRyYXAgc2Vzc2lvbiAoJXAsICVwKVxuIiwgc3AsIHNwLT5zZXNwKSk7CiAgICAgICAgICAgIGZyZWUoc3ApOwogICAgICAgICAgICByZXR1cm4gMTsKICAgICAgICB9CiAgICAgICAgcHJldiA9IHNwOwogICAgICAgIHNwID0gc3AtPm5leHQ7CiAgICB9CiAgICByZXR1cm4gMDsKfQoKI2lmICFkZWZpbmVkKE5FVFNOTVBfRElTQUJMRV9TTk1QVjEpIHx8ICFkZWZpbmVkKE5FVFNOTVBfRElTQUJMRV9TTk1QVjJDKQpzdGF0aWMgaW50CmNyZWF0ZV90cmFwX3Nlc3Npb24yKGNvbnN0IGNoYXIgKnNpbmssIGNvbnN0IGNoYXIqIHNpbmtwb3J0LAoJCSAgICAgY2hhciAqY29tLCBpbnQgdmVyc2lvbiwgaW50IHBkdXR5cGUpCnsKICAgIG5ldHNubXBfdHJhbnNwb3J0ICp0OwogICAgbmV0c25tcF9zZXNzaW9uIHNlc3Npb24sICpzZXNwOwoKICAgIG1lbXNldCgmc2Vzc2lvbiwgMCwgc2l6ZW9mKG5ldHNubXBfc2Vzc2lvbikpOwogICAgc2Vzc2lvbi52ZXJzaW9uID0gdmVyc2lvbjsKICAgIGlmIChjb20pIHsKICAgICAgICBzZXNzaW9uLmNvbW11bml0eSA9ICh1X2NoYXIgKikgY29tOwogICAgICAgIHNlc3Npb24uY29tbXVuaXR5X2xlbiA9IHN0cmxlbihjb20pOwogICAgfQoKICAgIC8qCiAgICAgKiBmb3IgaW5mb3Jtcywgc2V0IHJldHJpZXMgdG8gZGVmYXVsdAogICAgICovCiAgICBpZiAoU05NUF9NU0dfSU5GT1JNID09IHBkdXR5cGUpIHsKICAgICAgICBzZXNzaW9uLnRpbWVvdXQgPSBTTk1QX0RFRkFVTFRfVElNRU9VVDsKICAgICAgICBzZXNzaW9uLnJldHJpZXMgPSBTTk1QX0RFRkFVTFRfUkVUUklFUzsKICAgIH0KCiAgICAvKgogICAgICogaWYgdGhlIHNpbmsgaXMgbG9jYWxob3N0LCBiaW5kIHRvIGxvY2FsaG9zdCwgdG8gcmVkdWNlIG9wZW4gcG9ydHMuCiAgICAgKi8KICAgIGlmICgoTlVMTCA9PSBuZXRzbm1wX2RzX2dldF9zdHJpbmcoTkVUU05NUF9EU19MSUJSQVJZX0lELAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBORVRTTk1QX0RTX0xJQl9DTElFTlRfQUREUikpICYmIAogICAgICAgICgoMCA9PSBzdHJjbXAoImxvY2FsaG9zdCIsc2luaykpIHx8ICgwID09IHN0cmNtcCgiMTI3LjAuMC4xIixzaW5rKSkpKQogICAgICAgIHNlc3Npb24ubG9jYWxuYW1lID0gc3RyZHVwKCJsb2NhbGhvc3QiKTsKCiAgICB0ID0gbmV0c25tcF90ZG9tYWluX3RyYW5zcG9ydF9mdWxsKCJzbm1wdHJhcCIsIHNpbmssIDAsIE5VTEwsIHNpbmtwb3J0KTsKICAgIGlmICh0ICE9IE5VTEwpIHsKCXNlc3AgPSBzbm1wX2FkZCgmc2Vzc2lvbiwgdCwgTlVMTCwgTlVMTCk7CgoJaWYgKHNlc3ApIHsKCSAgICByZXR1cm4gYWRkX3RyYXBfc2Vzc2lvbihzZXNwLCBwZHV0eXBlLAoJCQkJICAgIChwZHV0eXBlID09IFNOTVBfTVNHX0lORk9STSksIHZlcnNpb24pOwoJfQogICAgfQogICAgLyoKICAgICAqIGRpYWdub3NlIHNubXBfb3BlbiBlcnJvcnMgd2l0aCB0aGUgaW5wdXQgbmV0c25tcF9zZXNzaW9uIHBvaW50ZXIgCiAgICAgKi8KICAgIHNubXBfc2Vzc19wZXJyb3IoInNubXBkOiBjcmVhdGVfdHJhcF9zZXNzaW9uIiwgJnNlc3Npb24pOwogICAgcmV0dXJuIDA7Cn0KCmludApjcmVhdGVfdHJhcF9zZXNzaW9uKGNoYXIgKnNpbmssIHVfc2hvcnQgc2lua3BvcnQsCgkJICAgIGNoYXIgKmNvbSwgaW50IHZlcnNpb24sIGludCBwZHV0eXBlKQp7CiAgICBjaGFyIGJ1ZltzaXplb2Yoc2lua3BvcnQpICogMyArIDJdOwogICAgaWYgKHNpbmtwb3J0ICE9IDApIHsKCXNwcmludGYoYnVmLCAiOiVodSIsIHNpbmtwb3J0KTsKCXNubXBfbG9nKExPR19OT1RJQ0UsCgkJICJVc2luZyBhIHNlcGFyYXRlIHBvcnQgbnVtYmVyIGlzIGRlcHJlY2F0ZWQsIHBsZWFzZSBjb3JyZWN0ICIKCQkgInRoZSBzaW5rIHNwZWNpZmljYXRpb24gaW5zdGVhZCIpOwogICAgfQogICAgcmV0dXJuIGNyZWF0ZV90cmFwX3Nlc3Npb24yKHNpbmssIHNpbmtwb3J0ID8gYnVmIDogTlVMTCwgY29tLCB2ZXJzaW9uLAoJCQkJcGR1dHlwZSk7Cn0KCiNlbmRpZiAvKiBzdXBwb3J0IGZvciBjb21tdW5pdHkgYmFzZWQgU05NUCAqLwoKI2lmbmRlZiBORVRTTk1QX0RJU0FCTEVfU05NUFYxCnN0YXRpYyBpbnQKY3JlYXRlX3YxX3RyYXBfc2Vzc2lvbihjaGFyICpzaW5rLCBjb25zdCBjaGFyICpzaW5rcG9ydCwgY2hhciAqY29tKQp7CiAgICByZXR1cm4gY3JlYXRlX3RyYXBfc2Vzc2lvbjIoc2luaywgc2lua3BvcnQsIGNvbSwKCQkJCVNOTVBfVkVSU0lPTl8xLCBTTk1QX01TR19UUkFQKTsKfQojZW5kaWYKCiNpZm5kZWYgTkVUU05NUF9ESVNBQkxFX1NOTVBWMkMKc3RhdGljIGludApjcmVhdGVfdjJfdHJhcF9zZXNzaW9uKGNvbnN0IGNoYXIgKnNpbmssIGNvbnN0IGNoYXIgKnNpbmtwb3J0LCBjaGFyICpjb20pCnsKICAgIHJldHVybiBjcmVhdGVfdHJhcF9zZXNzaW9uMihzaW5rLCBzaW5rcG9ydCwgY29tLAoJCQkJU05NUF9WRVJTSU9OXzJjLCBTTk1QX01TR19UUkFQMik7Cn0KCnN0YXRpYyBpbnQKY3JlYXRlX3YyX2luZm9ybV9zZXNzaW9uKGNvbnN0IGNoYXIgKnNpbmssIGNvbnN0IGNoYXIgKnNpbmtwb3J0LCBjaGFyICpjb20pCnsKICAgIHJldHVybiBjcmVhdGVfdHJhcF9zZXNzaW9uMihzaW5rLCBzaW5rcG9ydCwgY29tLAoJCQkJU05NUF9WRVJTSU9OXzJjLCBTTk1QX01TR19JTkZPUk0pOwp9CiNlbmRpZgoKdm9pZApzbm1wZF9mcmVlX3RyYXBzaW5rcyh2b2lkKQp7CiAgICBzdHJ1Y3QgdHJhcF9zaW5rICpzcCA9IHNpbmtzOwogICAgREVCVUdNU0dUTCgoInRyYXAiLCAiZnJlZWluZyB0cmFwIHNlc3Npb25zXG4iKSk7CiAgICB3aGlsZSAoc3ApIHsKICAgICAgICBzaW5rcyA9IHNpbmtzLT5uZXh0OwogICAgICAgIGZyZWVfdHJhcF9zZXNzaW9uKHNwKTsKICAgICAgICBzcCA9IHNpbmtzOwogICAgfQp9CgogICAgICAgIC8qKioqKioqKioqKioqKioqKioqCgkgKgoJICogVHJhcCBoYW5kbGluZwoJICoKCSAqKioqKioqKioqKioqKioqKioqLwoKCm5ldHNubXBfcGR1Kgpjb252ZXJ0X3YycGR1X3RvX3YxKCBuZXRzbm1wX3BkdSogdGVtcGxhdGVfdjJwZHUgKQp7CiAgICBuZXRzbm1wX3BkdSAgICAgICAgICAgKnRlbXBsYXRlX3YxcGR1OwogICAgbmV0c25tcF92YXJpYWJsZV9saXN0ICpmaXJzdF92YiwgKnZibGlzdDsKICAgIG5ldHNubXBfdmFyaWFibGVfbGlzdCAqdmFyOwoKICAgIC8qCiAgICAgKiBNYWtlIGEgY29weSBvZiB0aGUgdjIgVHJhcCBQRFUKICAgICAqICAgYmVmb3JlIHN0YXJ0aW5nIHRvIGNvbnZlcnQgdGhpcwogICAgICogICBpbnRvIGEgdjEgVHJhcCBQRFUuCiAgICAgKi8KICAgIHRlbXBsYXRlX3YxcGR1ID0gc25tcF9jbG9uZV9wZHUoIHRlbXBsYXRlX3YycGR1KTsKICAgIGlmICghdGVtcGxhdGVfdjFwZHUpIHsKICAgICAgICBzbm1wX2xvZyhMT0dfV0FSTklORywKICAgICAgICAgICAgICAgICAic2VuZF90cmFwOiBmYWlsZWQgdG8gY29weSB2MSB0ZW1wbGF0ZSBQRFVcbiIpOwogICAgICAgIHJldHVybiBOVUxMOwogICAgfQogICAgdGVtcGxhdGVfdjFwZHUtPmNvbW1hbmQgPSBTTk1QX01TR19UUkFQOwogICAgZmlyc3RfdmIgPSB0ZW1wbGF0ZV92MXBkdS0+dmFyaWFibGVzOwogICAgdmJsaXN0ICAgPSB0ZW1wbGF0ZV92MXBkdS0+dmFyaWFibGVzOwoKICAgIC8qCiAgICAgKiBUaGUgZmlyc3QgdmFyYmluZCBzaG91bGQgYmUgdGhlIHN5c3RlbSB1cHRpbWUuCiAgICAgKi8KICAgIGlmICghdmJsaXN0IHx8CiAgICAgICAgc25tcF9vaWRfY29tcGFyZSh2Ymxpc3QtPm5hbWUsICB2Ymxpc3QtPm5hbWVfbGVuZ3RoLAogICAgICAgICAgICAgICAgICAgICAgICAgc3lzdXB0aW1lX29pZCwgc3lzdXB0aW1lX29pZF9sZW4pKSB7CiAgICAgICAgc25tcF9sb2coTE9HX1dBUk5JTkcsCiAgICAgICAgICAgICAgICAgInNlbmRfdHJhcDogbm8gdjIgc3lzVXB0aW1lIHZhcmJpbmQgdG8gc2V0IGZyb21cbiIpOwogICAgICAgIHNubXBfZnJlZV9wZHUodGVtcGxhdGVfdjFwZHUpOwogICAgICAgIHJldHVybiBOVUxMOwogICAgfQogICAgdGVtcGxhdGVfdjFwZHUtPnRpbWUgPSAqdmJsaXN0LT52YWwuaW50ZWdlcjsKICAgIHZibGlzdCA9IHZibGlzdC0+bmV4dF92YXJpYWJsZTsKICAgICAgICAgICAgCiAgICAvKgogICAgICogVGhlIHNlY29uZCB2YXJiaW5kIHNob3VsZCBiZSB0aGUgc25tcFRyYXBPSUQuCiAgICAgKi8KICAgIGlmICghdmJsaXN0IHx8CiAgICAgICAgc25tcF9vaWRfY29tcGFyZSh2Ymxpc3QtPm5hbWUsIHZibGlzdC0+bmFtZV9sZW5ndGgsCiAgICAgICAgICAgICAgICAgICAgICAgICBzbm1wdHJhcF9vaWQsIHNubXB0cmFwX29pZF9sZW4pKSB7CiAgICAgICAgc25tcF9sb2coTE9HX1dBUk5JTkcsCiAgICAgICAgICAgICAgICAgInNlbmRfdHJhcDogbm8gdjIgdHJhcE9JRCB2YXJiaW5kIHRvIHNldCBmcm9tXG4iKTsKICAgICAgICBzbm1wX2ZyZWVfcGR1KHRlbXBsYXRlX3YxcGR1KTsKICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0KCiAgICAvKgogICAgICogQ2hlY2sgdGhlIHYyIHZhcmJpbmQgbGlzdCBmb3IgYW55IHZhcmJpbmRzCiAgICAgKiAgdGhhdCBhcmUgbm90IHZhbGlkIGluIGFuIFNOTVB2MSB0cmFwLgogICAgICogIFRoaXMgYmFzaWNhbGx5IG1lYW5zIENvdW50ZXI2NCB2YWx1ZXMuCiAgICAgKgogICAgICogUkZDIDIwODkgc2FpZCB0byBvbWl0IHN1Y2ggdmFyYmluZHMgZnJvbSB0aGUgbGlzdC4KICAgICAqIFJGQyAyNTc2LzM1ODQgc2F5IHRvIGRyb3AgdGhlIHRyYXAgY29tcGxldGVseS4KICAgICAqLwogICAgZm9yICh2YXIgPSB2Ymxpc3QtPm5leHRfdmFyaWFibGU7IHZhcjsgdmFyID0gdmFyLT5uZXh0X3ZhcmlhYmxlKSB7CiAgICAgICAgaWYgKCB2YXItPnR5cGUgPT0gQVNOX0NPVU5URVI2NCApIHsKICAgICAgICAgICAgc25tcF9sb2coTE9HX1dBUk5JTkcsCiAgICAgICAgICAgICAgICAgICAgICJzZW5kX3RyYXA6IHYxIHRyYXBzIGNhbid0IGNhcnJ5IENvdW50ZXI2NCB2YXJiaW5kc1xuIik7CiAgICAgICAgICAgIHNubXBfZnJlZV9wZHUodGVtcGxhdGVfdjFwZHUpOwogICAgICAgICAgICByZXR1cm4gTlVMTDsKICAgICAgICB9CiAgICB9CgogICAgLyoKICAgICAqIFNldCB0aGUgZ2VuZXJpYyAmIHNwZWNpZmljIHRyYXAgdHlwZXMsCiAgICAgKiAgICBhbmQgdGhlIGVudGVycHJpc2UgZmllbGQgZnJvbSB0aGUgdjIgdmFyYmluZCBsaXN0LgogICAgICogSWYgdGhlcmUncyBhbiBhZ2VudElQQWRkcmVzcyB2YXJiaW5kLCBzZXQgdGhlIGFnZW50X2FkZHIgdG9vCiAgICAgKi8KICAgIGlmICghc25tcF9vaWRfY29tcGFyZSh2Ymxpc3QtPnZhbC5vYmppZCwgT0lEX0xFTkdUSCh0cmFwX3ByZWZpeCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgdHJhcF9wcmVmaXgsICAgICAgIE9JRF9MRU5HVEgodHJhcF9wcmVmaXgpKSkgewogICAgICAgIC8qCiAgICAgICAgICogRm9yICdzdGFuZGFyZCcgdHJhcHMsIGV4dHJhY3QgdGhlIGdlbmVyaWMgdHJhcCB0eXBlCiAgICAgICAgICogICBmcm9tIHRoZSBzbm1wVHJhcE9JRCB2YWx1ZSwgYW5kIHRha2UgdGhlIGVudGVycHJpc2UKICAgICAgICAgKiAgIHZhbHVlIGZyb20gdGhlICdzbm1wRW50ZXJwcmlzZScgdmFyYmluZC4KICAgICAgICAgKi8KICAgICAgICB0ZW1wbGF0ZV92MXBkdS0+dHJhcF90eXBlID0KICAgICAgICAgICAgdmJsaXN0LT52YWwub2JqaWRbT0lEX0xFTkdUSCh0cmFwX3ByZWZpeCldIC0gMTsKICAgICAgICB0ZW1wbGF0ZV92MXBkdS0+c3BlY2lmaWNfdHlwZSA9IDA7CgogICAgICAgIHZhciA9IGZpbmRfdmFyYmluZF9pbl9saXN0KCB2Ymxpc3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc25tcHRyYXBlbnRlcnByaXNlX29pZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzbm1wdHJhcGVudGVycHJpc2Vfb2lkX2xlbik7CiAgICAgICAgaWYgKHZhcikgewogICAgICAgICAgICB0ZW1wbGF0ZV92MXBkdS0+ZW50ZXJwcmlzZV9sZW5ndGggPSB2YXItPnZhbF9sZW4vc2l6ZW9mKG9pZCk7CiAgICAgICAgICAgIHRlbXBsYXRlX3YxcGR1LT5lbnRlcnByaXNlID0KICAgICAgICAgICAgICAgIHNubXBfZHVwbGljYXRlX29iamlkKHZhci0+dmFsLm9iamlkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGVtcGxhdGVfdjFwZHUtPmVudGVycHJpc2VfbGVuZ3RoKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICB0ZW1wbGF0ZV92MXBkdS0+ZW50ZXJwcmlzZSAgICAgICAgPSBOVUxMOwogICAgICAgICAgICB0ZW1wbGF0ZV92MXBkdS0+ZW50ZXJwcmlzZV9sZW5ndGggPSAwOwkJLyogWFhYID8/PyAqLwogICAgICAgIH0KICAgIH0gZWxzZSB7CiAgICAgICAgLyoKICAgICAgICAgKiBGb3IgZW50ZXJwcmlzZS1zcGVjaWZpYyB0cmFwcywgc3BsaXQgdGhlIHNubXBUcmFwT0lEIHZhbHVlCiAgICAgICAgICogICBpbnRvIGVudGVycHJpc2UgYW5kIHNwZWNpZmljIHRyYXAKICAgICAgICAgKi8KICAgICAgICBzaXplX3QgbGVuID0gdmJsaXN0LT52YWxfbGVuIC8gc2l6ZW9mKG9pZCk7CiAgICAgICAgaWYgKCBsZW4gPD0gMiApIHsKICAgICAgICAgICAgc25tcF9sb2coTE9HX1dBUk5JTkcsCiAgICAgICAgICAgICAgICAgICAgICJzZW5kX3RyYXA6IHYyIHRyYXBPSUQgdG9vIHNob3J0ICglZClcbiIsIChpbnQpbGVuKTsKICAgICAgICAgICAgc25tcF9mcmVlX3BkdSh0ZW1wbGF0ZV92MXBkdSk7CiAgICAgICAgICAgIHJldHVybiBOVUxMOwogICAgICAgIH0KICAgICAgICB0ZW1wbGF0ZV92MXBkdS0+dHJhcF90eXBlICAgICA9IFNOTVBfVFJBUF9FTlRFUlBSSVNFU1BFQ0lGSUM7CiAgICAgICAgdGVtcGxhdGVfdjFwZHUtPnNwZWNpZmljX3R5cGUgPSB2Ymxpc3QtPnZhbC5vYmppZFtsZW4gLSAxXTsKICAgICAgICBsZW4tLTsKICAgICAgICBpZiAodmJsaXN0LT52YWwub2JqaWRbbGVuLTFdID09IDApCiAgICAgICAgICAgIGxlbi0tOwogICAgICAgIFNOTVBfRlJFRSh0ZW1wbGF0ZV92MXBkdS0+ZW50ZXJwcmlzZSk7CiAgICAgICAgdGVtcGxhdGVfdjFwZHUtPmVudGVycHJpc2UgPQogICAgICAgICAgICBzbm1wX2R1cGxpY2F0ZV9vYmppZCh2Ymxpc3QtPnZhbC5vYmppZCwgbGVuKTsKICAgICAgICB0ZW1wbGF0ZV92MXBkdS0+ZW50ZXJwcmlzZV9sZW5ndGggPSBsZW47CiAgICB9CiAgICB2YXIgPSBmaW5kX3ZhcmJpbmRfaW5fbGlzdCggdmJsaXN0LCBhZ2VudGFkZHJfb2lkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWdlbnRhZGRyX29pZF9sZW4pOwogICAgaWYgKHZhcikgewogICAgICAgIG1lbWNweSh0ZW1wbGF0ZV92MXBkdS0+YWdlbnRfYWRkciwKICAgICAgICAgICAgICAgdmFyLT52YWwuc3RyaW5nLCA0KTsKICAgIH0KCiAgICAvKgogICAgICogVGhlIHJlbWFpbmRlciBvZiB0aGUgdjIgdmFyYmluZCBsaXN0IGlzIGtlcHQKICAgICAqIGFzIHRoZSB2MiB2YXJiaW5kIGxpc3QuICBVcGRhdGUgdGhlIFBEVSBhbmQKICAgICAqIGZyZWUgdGhlIHR3byByZWR1bmRhbnQgdmFyYmluZHMuCiAgICAgKi8KICAgIHRlbXBsYXRlX3YxcGR1LT52YXJpYWJsZXMgPSB2Ymxpc3QtPm5leHRfdmFyaWFibGU7CiAgICB2Ymxpc3QtPm5leHRfdmFyaWFibGUgPSBOVUxMOwogICAgc25tcF9mcmVlX3ZhcmJpbmQoIGZpcnN0X3ZiICk7CiAgICAgICAgICAgIAogICAgcmV0dXJuIHRlbXBsYXRlX3YxcGR1Owp9CgpuZXRzbm1wX3BkdSoKY29udmVydF92MXBkdV90b192MiggbmV0c25tcF9wZHUqIHRlbXBsYXRlX3YxcGR1ICkKewogICAgbmV0c25tcF9wZHUgICAgICAgICAgICp0ZW1wbGF0ZV92MnBkdTsKICAgIG5ldHNubXBfdmFyaWFibGVfbGlzdCAqdmFyOwogICAgb2lkICAgICAgICAgICAgICAgICAgICBlbnRlcnByaXNlW01BWF9PSURfTEVOXTsKICAgIHNpemVfdCAgICAgICAgICAgICAgICAgZW50ZXJwcmlzZV9sZW47CgogICAgLyoKICAgICAqIE1ha2UgYSBjb3B5IG9mIHRoZSB2MSBUcmFwIFBEVQogICAgICogICBiZWZvcmUgc3RhcnRpbmcgdG8gY29udmVydCB0aGlzCiAgICAgKiAgIGludG8gYSB2MiBUcmFwIFBEVS4KICAgICAqLwogICAgdGVtcGxhdGVfdjJwZHUgPSBzbm1wX2Nsb25lX3BkdSggdGVtcGxhdGVfdjFwZHUpOwogICAgaWYgKCF0ZW1wbGF0ZV92MnBkdSkgewogICAgICAgIHNubXBfbG9nKExPR19XQVJOSU5HLAogICAgICAgICAgICAgICAgICJzZW5kX3RyYXA6IGZhaWxlZCB0byBjb3B5IHYyIHRlbXBsYXRlIFBEVVxuIik7CiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICB9CiAgICB0ZW1wbGF0ZV92MnBkdS0+Y29tbWFuZCA9IFNOTVBfTVNHX1RSQVAyOwoKICAgIC8qCiAgICAgKiBJbnNlcnQgYW4gc25tcFRyYXBPSUQgdmFyYmluZCBiZWZvcmUgdGhlIG9yaWdpbmFsIHYxIHZhcmJpbmQgbGlzdAogICAgICogICBlaXRoZXIgdXNpbmcgb25lIG9mIHRoZSBzdGFuZGFyZCBkZWZpbmVkIHRyYXAgT0lEcywKICAgICAqICAgb3IgY29uc3RydWN0aW5nIHRoaXMgZnJvbSB0aGUgUERVIGVudGVycHJpc2UgJiBzcGVjaWZpYyB0cmFwIGZpZWxkcwogICAgICovCiAgICBpZiAodGVtcGxhdGVfdjFwZHUtPnRyYXBfdHlwZSA9PSBTTk1QX1RSQVBfRU5URVJQUklTRVNQRUNJRklDKSB7CiAgICAgICAgbWVtY3B5KGVudGVycHJpc2UsIHRlbXBsYXRlX3YxcGR1LT5lbnRlcnByaXNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICB0ZW1wbGF0ZV92MXBkdS0+ZW50ZXJwcmlzZV9sZW5ndGgqc2l6ZW9mKG9pZCkpOwogICAgICAgIGVudGVycHJpc2VfbGVuICAgICAgICAgICAgICAgPSB0ZW1wbGF0ZV92MXBkdS0+ZW50ZXJwcmlzZV9sZW5ndGg7CiAgICAgICAgZW50ZXJwcmlzZVtlbnRlcnByaXNlX2xlbisrXSA9IDA7CiAgICAgICAgZW50ZXJwcmlzZVtlbnRlcnByaXNlX2xlbisrXSA9IHRlbXBsYXRlX3YxcGR1LT5zcGVjaWZpY190eXBlOwogICAgfSBlbHNlIHsKICAgICAgICBtZW1jcHkoZW50ZXJwcmlzZSwgY29sZF9zdGFydF9vaWQsIHNpemVvZihjb2xkX3N0YXJ0X29pZCkpOwoJZW50ZXJwcmlzZVs5XSAgPSB0ZW1wbGF0ZV92MXBkdS0+dHJhcF90eXBlKzE7CiAgICAgICAgZW50ZXJwcmlzZV9sZW4gPSBzaXplb2YoY29sZF9zdGFydF9vaWQpL3NpemVvZihvaWQpOwogICAgfQoKICAgIHZhciA9IE5VTEw7CiAgICBpZiAoIXNubXBfdmFybGlzdF9hZGRfdmFyaWFibGUoICZ2YXIsCiAgICAgICAgICAgICBzbm1wdHJhcF9vaWQsIHNubXB0cmFwX29pZF9sZW4sCiAgICAgICAgICAgICBBU05fT0JKRUNUX0lELAogICAgICAgICAgICAgKHVfY2hhciopZW50ZXJwcmlzZSwgZW50ZXJwcmlzZV9sZW4qc2l6ZW9mKG9pZCkpKSB7CiAgICAgICAgc25tcF9sb2coTE9HX1dBUk5JTkcsCiAgICAgICAgICAgICAgICAgInNlbmRfdHJhcDogZmFpbGVkIHRvIGluc2VydCBjb3BpZWQgc25tcFRyYXBPSUQgdmFyYmluZFxuIik7CiAgICAgICAgc25tcF9mcmVlX3BkdSh0ZW1wbGF0ZV92MnBkdSk7CiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICB9CiAgICB2YXItPm5leHRfdmFyaWFibGUgICAgICAgID0gdGVtcGxhdGVfdjJwZHUtPnZhcmlhYmxlczsKICAgIHRlbXBsYXRlX3YycGR1LT52YXJpYWJsZXMgPSB2YXI7CgogICAgLyoKICAgICAqIEluc2VydCBhIHN5c1VwdGltZSB2YXJiaW5kIGF0IHRoZSBoZWFkIG9mIHRoZSB2MiB2YXJiaW5kIGxpc3QKICAgICAqLwogICAgdmFyID0gTlVMTDsKICAgIGlmICghc25tcF92YXJsaXN0X2FkZF92YXJpYWJsZSggJnZhciwKICAgICAgICAgICAgIHN5c3VwdGltZV9vaWQsIHN5c3VwdGltZV9vaWRfbGVuLAogICAgICAgICAgICAgQVNOX1RJTUVUSUNLUywKICAgICAgICAgICAgICh1X2NoYXIqKSYodGVtcGxhdGVfdjFwZHUtPnRpbWUpLCAKICAgICAgICAgICAgIHNpemVvZih0ZW1wbGF0ZV92MXBkdS0+dGltZSkpKSB7CiAgICAgICAgc25tcF9sb2coTE9HX1dBUk5JTkcsCiAgICAgICAgICAgICAgICAgInNlbmRfdHJhcDogZmFpbGVkIHRvIGluc2VydCBjb3BpZWQgc3lzVXB0aW1lIHZhcmJpbmRcbiIpOwogICAgICAgIHNubXBfZnJlZV9wZHUodGVtcGxhdGVfdjJwZHUpOwogICAgICAgIHJldHVybiBOVUxMOwogICAgfQogICAgdmFyLT5uZXh0X3ZhcmlhYmxlICAgICAgICA9IHRlbXBsYXRlX3YycGR1LT52YXJpYWJsZXM7CiAgICB0ZW1wbGF0ZV92MnBkdS0+dmFyaWFibGVzID0gdmFyOwoKICAgIC8qCiAgICAgKiBBcHBlbmQgdGhlIG90aGVyIHRocmVlIGNvbnZlcnNpb24gdmFyYmluZHMsCiAgICAgKiAgKHNubXBUcmFwQWdlbnRBZGRyLCBzbm1wVHJhcENvbW11bml0eSAmIHNubXBUcmFwRW50ZXJwcmlzZSkKICAgICAqICBpZiB0aGV5J3JlIG5vdCBhbHJlYWR5IHByZXNlbnQuCiAgICAgKiAgQnV0IGRvbid0IGJvbWIgb3V0IGNvbXBsZXRlbHkgaWYgdGhlcmUgYXJlIHByb2JsZW1zLgogICAgICovCiAgICB2YXIgPSBmaW5kX3ZhcmJpbmRfaW5fbGlzdCggdGVtcGxhdGVfdjJwZHUtPnZhcmlhYmxlcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZ2VudGFkZHJfb2lkLCBhZ2VudGFkZHJfb2lkX2xlbik7CiAgICBpZiAoIXZhciAmJiAodGVtcGxhdGVfdjFwZHUtPmFnZW50X2FkZHJbMF0KICAgICAgICAgICAgICB8fCB0ZW1wbGF0ZV92MXBkdS0+YWdlbnRfYWRkclsxXQogICAgICAgICAgICAgIHx8IHRlbXBsYXRlX3YxcGR1LT5hZ2VudF9hZGRyWzJdCiAgICAgICAgICAgICAgfHwgdGVtcGxhdGVfdjFwZHUtPmFnZW50X2FkZHJbM10pKSB7CiAgICAgICAgaWYgKCFzbm1wX3Zhcmxpc3RfYWRkX3ZhcmlhYmxlKCAmKHRlbXBsYXRlX3YycGR1LT52YXJpYWJsZXMpLAogICAgICAgICAgICAgICAgIGFnZW50YWRkcl9vaWQsIGFnZW50YWRkcl9vaWRfbGVuLAogICAgICAgICAgICAgICAgIEFTTl9JUEFERFJFU1MsCiAgICAgICAgICAgICAgICAgKHVfY2hhciopJih0ZW1wbGF0ZV92MXBkdS0+YWdlbnRfYWRkciksIAogICAgICAgICAgICAgICAgIHNpemVvZih0ZW1wbGF0ZV92MXBkdS0+YWdlbnRfYWRkcikpKQogICAgICAgICAgICBzbm1wX2xvZyhMT0dfV0FSTklORywKICAgICAgICAgICAgICAgICAic2VuZF90cmFwOiBmYWlsZWQgdG8gYXBwZW5kIHNubXBUcmFwQWRkciB2YXJiaW5kXG4iKTsKICAgIH0KICAgIHZhciA9IGZpbmRfdmFyYmluZF9pbl9saXN0KCB0ZW1wbGF0ZV92MnBkdS0+dmFyaWFibGVzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbW11bml0eV9vaWQsIGNvbW11bml0eV9vaWRfbGVuKTsKICAgIGlmICghdmFyICYmIHRlbXBsYXRlX3YxcGR1LT5jb21tdW5pdHkpIHsKICAgICAgICBpZiAoIXNubXBfdmFybGlzdF9hZGRfdmFyaWFibGUoICYodGVtcGxhdGVfdjJwZHUtPnZhcmlhYmxlcyksCiAgICAgICAgICAgICAgICAgY29tbXVuaXR5X29pZCwgY29tbXVuaXR5X29pZF9sZW4sCiAgICAgICAgICAgICAgICAgQVNOX09DVEVUX1NUUiwKICAgICAgICAgICAgICAgICB0ZW1wbGF0ZV92MXBkdS0+Y29tbXVuaXR5LCAKICAgICAgICAgICAgICAgICB0ZW1wbGF0ZV92MXBkdS0+Y29tbXVuaXR5X2xlbikpCiAgICAgICAgICAgIHNubXBfbG9nKExPR19XQVJOSU5HLAogICAgICAgICAgICAgICAgICJzZW5kX3RyYXA6IGZhaWxlZCB0byBhcHBlbmQgc25tcFRyYXBDb21tdW5pdHkgdmFyYmluZFxuIik7CiAgICB9CiAgICB2YXIgPSBmaW5kX3ZhcmJpbmRfaW5fbGlzdCggdGVtcGxhdGVfdjJwZHUtPnZhcmlhYmxlcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzbm1wdHJhcGVudGVycHJpc2Vfb2lkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNubXB0cmFwZW50ZXJwcmlzZV9vaWRfbGVuKTsKICAgIGlmICghdmFyKSB7CiAgICAgICAgaWYgKCFzbm1wX3Zhcmxpc3RfYWRkX3ZhcmlhYmxlKCAmKHRlbXBsYXRlX3YycGR1LT52YXJpYWJsZXMpLAogICAgICAgICAgICAgICAgIHNubXB0cmFwZW50ZXJwcmlzZV9vaWQsIHNubXB0cmFwZW50ZXJwcmlzZV9vaWRfbGVuLAogICAgICAgICAgICAgICAgIEFTTl9PQkpFQ1RfSUQsCiAgICAgICAgICAgICAgICAgKHVfY2hhciopdGVtcGxhdGVfdjFwZHUtPmVudGVycHJpc2UsIAogICAgICAgICAgICAgICAgIHRlbXBsYXRlX3YxcGR1LT5lbnRlcnByaXNlX2xlbmd0aCpzaXplb2Yob2lkKSkpCiAgICAgICAgICAgIHNubXBfbG9nKExPR19XQVJOSU5HLAogICAgICAgICAgICAgICAgICJzZW5kX3RyYXA6IGZhaWxlZCB0byBhcHBlbmQgc25tcEVudGVycHJpc2UgdmFyYmluZFxuIik7CiAgICB9CiAgICByZXR1cm4gdGVtcGxhdGVfdjJwZHU7Cn0KCi8qKgogKiBUaGlzIGZ1bmN0aW9uIGFsbG93cyB5b3UgdG8gbWFrZSBhIGRpc3RpbmN0aW9uIGJldHdlZW4gZ2VuZXJpYyAKICogdHJhcHMgZnJvbSBkaWZmZXJlbnQgY2xhc3NlcyBvZiBlcXVpcG1lbnQuIEZvciBleGFtcGxlLCB5b3UgbWF5IHdhbnQgCiAqIHRvIGhhbmRsZSBhIFNOTVBfVFJBUF9MSU5LRE9XTiB0cmFwIGZvciBhIHBhcnRpY3VsYXIgZGV2aWNlIGluIGEgCiAqIGRpZmZlcmVudCBtYW5uZXIgdG8gYSBnZW5lcmljIHN5c3RlbSBTTk1QX1RSQVBfTElOS0RPV04gdHJhcC4KICogICAKICoKICogQHBhcmFtIHRyYXAgaXMgdGhlIGdlbmVyaWMgdHJhcCB0eXBlLiAgVGhlIHRyYXAgdHlwZXMgYXJlOgogKgkJLSBTTk1QX1RSQVBfQ09MRFNUQVJUOgogKgkJCWNvbGQgc3RhcnQKICoJCS0gU05NUF9UUkFQX1dBUk1TVEFSVDoKICoJCQl3YXJtIHN0YXJ0CiAqCQktIFNOTVBfVFJBUF9MSU5LRE9XTjoKICoJCQlsaW5rIGRvd24KICoJCS0gU05NUF9UUkFQX0xJTktVUDoKICoJCQlsaW5rIHVwCiAqCQktIFNOTVBfVFJBUF9BVVRIRkFJTDoKICoJCQlhdXRoZW50aWNhdGlvbiBmYWlsdXJlCiAqCQktIFNOTVBfVFJBUF9FR1BORUlHSEJPUkxPU1M6CiAqCQkJZWdwIG5laWdoYm9yIGxvc3MKICoJCS0gU05NUF9UUkFQX0VOVEVSUFJJU0VTUEVDSUZJQzoKICoJCQllbnRlcnByaXNlIHNwZWNpZmljCiAqCQkJCiAqIEBwYXJhbSBzcGVjaWZpYyBpcyB0aGUgc3BlY2lmaWMgdHJhcCB2YWx1ZS4KICoKICogQHBhcmFtIGVudGVycHJpc2UgaXMgYW4gZW50ZXJwcmlzZSBvaWQgaW4gd2hpY2ggeW91IHdhbnQgdG8gc2VuZCBzcGVjaWZpYyAKICoJdHJhcHMgZnJvbS4gCiAqCiAqIEBwYXJhbSBlbnRlcnByaXNlX2xlbmd0aCBpcyB0aGUgbGVuZ3RoIG9mIHRoZSBlbnRlcnByaXNlIG9pZCwgdXNlIG1hY3JvLAogKglPSURfTEVOR1RILCB0byBjb21wdXRlIGxlbmd0aC4KICoKICogQHBhcmFtIHZhcnMgaXMgdXNlZCB0byBzdXBwbHkgbGlzdCBvZiB2YXJpYWJsZSBiaW5kaW5ncyB0byBmb3JtIGFuIFNOTVB2MiAKICoJdHJhcC4KICoKICogQHBhcmFtIGNvbnRleHQgY3VycmVudGx5IHVudXNlZCAKICoKICogQHBhcmFtIGZsYWdzIGN1cnJlbnRseSB1bnVzZWQgCiAqCiAqIEByZXR1cm4gdm9pZAogKgogKiBAc2VlIHNlbmRfZWFzeV90cmFwCiAqIEBzZWUgc2VuZF92MnRyYXAKICovCmludApuZXRzbm1wX3NlbmRfdHJhcHMoaW50IHRyYXAsIGludCBzcGVjaWZpYywKICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBvaWQgKiBlbnRlcnByaXNlLCBpbnQgZW50ZXJwcmlzZV9sZW5ndGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF92YXJpYWJsZV9saXN0ICogdmFycywKICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyICogY29udGV4dCwgaW50IGZsYWdzKQp7CiAgICBuZXRzbm1wX3BkdSAgICAgICAgICAgKnRlbXBsYXRlX3YxcGR1OwogICAgbmV0c25tcF9wZHUgICAgICAgICAgICp0ZW1wbGF0ZV92MnBkdTsKICAgIG5ldHNubXBfdmFyaWFibGVfbGlzdCAqdmJsaXN0ID0gTlVMTDsKICAgIG5ldHNubXBfdmFyaWFibGVfbGlzdCAqdHJhcF92YjsKICAgIG5ldHNubXBfdmFyaWFibGVfbGlzdCAqdmFyOwogICAgaW5fYWRkcl90ICAgICAgICAgICAgICpwZHVfaW5fYWRkcl90OwogICAgdV9sb25nICAgICAgICAgICAgICAgICB1cHRpbWU7CiAgICBzdHJ1Y3QgdHJhcF9zaW5rICpzaW5rOwogICAgY29uc3QgY2hhciAgICAgICAgICAgICp2MXRyYXBhZGRyZXNzOwogICAgaW50ICAgICAgICAgICAgICAgICAgICByZXMgPSAwOwoKICAgIERFQlVHTVNHVEwoKCAidHJhcCIsICJzZW5kX3RyYXAgJWQgJWQgIiwgdHJhcCwgc3BlY2lmaWMpKTsKICAgIERFQlVHTVNHT0lEKCgidHJhcCIsIGVudGVycHJpc2UsIGVudGVycHJpc2VfbGVuZ3RoKSk7CiAgICBERUJVR01TRygoICJ0cmFwIiwgIlxuIikpOwoKICAgIGlmICh2YXJzKSB7CiAgICAgICAgdmJsaXN0ID0gc25tcF9jbG9uZV92YXJiaW5kKCB2YXJzICk7CiAgICAgICAgaWYgKCF2Ymxpc3QpIHsKICAgICAgICAgICAgc25tcF9sb2coTE9HX1dBUk5JTkcsCiAgICAgICAgICAgICAgICAgICAgICJzZW5kX3RyYXA6IGZhaWxlZCB0byBjbG9uZSB2YXJiaW5kIGxpc3RcbiIpOwogICAgICAgICAgICByZXR1cm4gLTE7CiAgICAgICAgfQogICAgfQoKICAgIGlmICggdHJhcCA9PSAtMSApIHsKICAgICAgICAvKgogICAgICAgICAqIENvbnN0cnVjdCB0aGUgU05NUHYyLXN0eWxlIG5vdGlmaWNhdGlvbiBQRFUKICAgICAgICAgKi8KICAgICAgICBpZiAoIXZibGlzdCkgewogICAgICAgICAgICBzbm1wX2xvZyhMT0dfV0FSTklORywKICAgICAgICAgICAgICAgICAgICAgInNlbmRfdHJhcDogY2FsbGVkIHdpdGggTlVMTCB2MiBpbmZvcm1hdGlvblxuIik7CiAgICAgICAgICAgIHJldHVybiAtMTsKICAgICAgICB9CiAgICAgICAgdGVtcGxhdGVfdjJwZHUgPSBzbm1wX3BkdV9jcmVhdGUoU05NUF9NU0dfVFJBUDIpOwogICAgICAgIGlmICghdGVtcGxhdGVfdjJwZHUpIHsKICAgICAgICAgICAgc25tcF9sb2coTE9HX1dBUk5JTkcsCiAgICAgICAgICAgICAgICAgICAgICJzZW5kX3RyYXA6IGZhaWxlZCB0byBjb25zdHJ1Y3QgdjIgdGVtcGxhdGUgUERVXG4iKTsKICAgICAgICAgICAgc25tcF9mcmVlX3ZhcmJpbmQodmJsaXN0KTsKICAgICAgICAgICAgcmV0dXJuIC0xOwogICAgICAgIH0KCiAgICAgICAgLyoKICAgICAgICAgKiBDaGVjayB0aGUgdmFyYmluZCBsaXN0IHdlJ3ZlIGJlZW4gZ2l2ZW4uCiAgICAgICAgICogSWYgaXQgc3RhcnRzIHdpdGggYSAnc3lzVXB0aW1lLjAnIHZhcmJpbmQsIHRoZW4gdXNlIHRoYXQuCiAgICAgICAgICogT3RoZXJ3aXNlLCBwcmVwZW5kIGEgc3VpdGFibGUgJ3N5c1VwdGltZS4wJyB2YXJiaW5kLgogICAgICAgICAqLwogICAgICAgIGlmICghc25tcF9vaWRfY29tcGFyZSggdmJsaXN0LT5uYW1lLCAgICB2Ymxpc3QtPm5hbWVfbGVuZ3RoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3lzdXB0aW1lX29pZCwgc3lzdXB0aW1lX29pZF9sZW4gKSkgewogICAgICAgICAgICB0ZW1wbGF0ZV92MnBkdS0+dmFyaWFibGVzID0gdmJsaXN0OwogICAgICAgICAgICB0cmFwX3ZiICA9IHZibGlzdC0+bmV4dF92YXJpYWJsZTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICB1cHRpbWUgICA9IG5ldHNubXBfZ2V0X2FnZW50X3VwdGltZSgpOwogICAgICAgICAgICB2YXIgPSBOVUxMOwogICAgICAgICAgICBzbm1wX3Zhcmxpc3RfYWRkX3ZhcmlhYmxlKCAmdmFyLAogICAgICAgICAgICAgICAgICAgICAgICAgICBzeXN1cHRpbWVfb2lkLCBzeXN1cHRpbWVfb2lkX2xlbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgQVNOX1RJTUVUSUNLUywgKHVfY2hhciopJnVwdGltZSwgc2l6ZW9mKHVwdGltZSkpOwogICAgICAgICAgICBpZiAoIXZhcikgewogICAgICAgICAgICAgICAgc25tcF9sb2coTE9HX1dBUk5JTkcsCiAgICAgICAgICAgICAgICAgICAgICJzZW5kX3RyYXA6IGZhaWxlZCB0byBpbnNlcnQgc3lzVXB0aW1lIHZhcmJpbmRcbiIpOwogICAgICAgICAgICAgICAgc25tcF9mcmVlX3BkdSh0ZW1wbGF0ZV92MnBkdSk7CiAgICAgICAgICAgICAgICBzbm1wX2ZyZWVfdmFyYmluZCh2Ymxpc3QpOwogICAgICAgICAgICAgICAgcmV0dXJuIC0xOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHRlbXBsYXRlX3YycGR1LT52YXJpYWJsZXMgPSB2YXI7CiAgICAgICAgICAgIHZhci0+bmV4dF92YXJpYWJsZSAgICAgICAgPSB2Ymxpc3Q7CiAgICAgICAgICAgIHRyYXBfdmIgID0gdmJsaXN0OwogICAgICAgIH0KCiAgICAgICAgLyoKICAgICAgICAgKiAndHJhcF92Yicgc2hvdWxkIHBvaW50IHRvIHRoZSBzbm1wVHJhcE9JRC4wIHZhcmJpbmQsCiAgICAgICAgICogICBpZGVudGlmeWluZyB0aGUgcmVxdWVzdGVkIHRyYXAuICBJZiBub3QgdGhlbiBib21iIG91dC4KICAgICAgICAgKiBJZiBpdCdzIGEgJ3N0YW5kYXJkJyB0cmFwLCB0aGVuIHdlIG5lZWQgdG8gYXBwZW5kIGFuCiAgICAgICAgICogICBzbm1wRW50ZXJwcmlzZSB2YXJiaW5kIChpZiB0aGVyZSBpc24ndCBhbHJlYWR5IG9uZSkuCiAgICAgICAgICovCiAgICAgICAgaWYgKCF0cmFwX3ZiIHx8CiAgICAgICAgICAgIHNubXBfb2lkX2NvbXBhcmUodHJhcF92Yi0+bmFtZSwgdHJhcF92Yi0+bmFtZV9sZW5ndGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc25tcHRyYXBfb2lkLCAgc25tcHRyYXBfb2lkX2xlbikpIHsKICAgICAgICAgICAgc25tcF9sb2coTE9HX1dBUk5JTkcsCiAgICAgICAgICAgICAgICAgICAgICJzZW5kX3RyYXA6IG5vIHYyIHRyYXBPSUQgdmFyYmluZCBwcm92aWRlZFxuIik7CiAgICAgICAgICAgIHNubXBfZnJlZV9wZHUodGVtcGxhdGVfdjJwZHUpOwogICAgICAgICAgICByZXR1cm4gLTE7CiAgICAgICAgfQogICAgICAgIGlmICghc25tcF9vaWRfY29tcGFyZSh2Ymxpc3QtPnZhbC5vYmppZCwgT0lEX0xFTkdUSCh0cmFwX3ByZWZpeCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyYXBfcHJlZml4LCAgICAgICBPSURfTEVOR1RIKHRyYXBfcHJlZml4KSkpIHsKICAgICAgICAgICAgdmFyID0gZmluZF92YXJiaW5kX2luX2xpc3QoIHRlbXBsYXRlX3YycGR1LT52YXJpYWJsZXMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzbm1wdHJhcGVudGVycHJpc2Vfb2lkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc25tcHRyYXBlbnRlcnByaXNlX29pZF9sZW4pOwogICAgICAgICAgICBpZiAoIXZhciAmJgogICAgICAgICAgICAgICAgIXNubXBfdmFybGlzdF9hZGRfdmFyaWFibGUoICYodGVtcGxhdGVfdjJwZHUtPnZhcmlhYmxlcyksCiAgICAgICAgICAgICAgICAgICAgIHNubXB0cmFwZW50ZXJwcmlzZV9vaWQsIHNubXB0cmFwZW50ZXJwcmlzZV9vaWRfbGVuLAogICAgICAgICAgICAgICAgICAgICBBU05fT0JKRUNUX0lELAogICAgICAgICAgICAgICAgICAgICBlbnRlcnByaXNlLCBlbnRlcnByaXNlX2xlbmd0aCpzaXplb2Yob2lkKSkpIHsKICAgICAgICAgICAgICAgIHNubXBfbG9nKExPR19XQVJOSU5HLAogICAgICAgICAgICAgICAgICAgICAic2VuZF90cmFwOiBmYWlsZWQgdG8gYWRkIHNubXBFbnRlcnByaXNlIHRvIHYyIHRyYXBcbiIpOwogICAgICAgICAgICAgICAgc25tcF9mcmVlX3BkdSh0ZW1wbGF0ZV92MnBkdSk7CiAgICAgICAgICAgICAgICByZXR1cm4gLTE7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgICAgIAoKICAgICAgICAvKgogICAgICAgICAqIElmIGV2ZXJ5dGhpbmcncyBPSywgY29udmVydCB0aGUgdjIgdGVtcGxhdGUgaW50byBhbiBTTk1QdjEgdHJhcCBQRFUuCiAgICAgICAgICovCiAgICAgICAgdGVtcGxhdGVfdjFwZHUgPSBjb252ZXJ0X3YycGR1X3RvX3YxKCB0ZW1wbGF0ZV92MnBkdSApOwogICAgICAgIGlmICghdGVtcGxhdGVfdjFwZHUpIHsKICAgICAgICAgICAgc25tcF9sb2coTE9HX1dBUk5JTkcsCiAgICAgICAgICAgICAgICAgICAgICJzZW5kX3RyYXA6IGZhaWxlZCB0byBjb252ZXJ0IHYyLT52MSB0ZW1wbGF0ZSBQRFVcbiIpOwogICAgICAgIH0KCiAgICB9IGVsc2UgewogICAgICAgIC8qCiAgICAgICAgICogQ29uc3RydWN0IHRoZSBTTk1QdjEgdHJhcCBQRFUuLi4uCiAgICAgICAgICovCiAgICAgICAgdGVtcGxhdGVfdjFwZHUgPSBzbm1wX3BkdV9jcmVhdGUoU05NUF9NU0dfVFJBUCk7CiAgICAgICAgaWYgKCF0ZW1wbGF0ZV92MXBkdSkgewogICAgICAgICAgICBzbm1wX2xvZyhMT0dfV0FSTklORywKICAgICAgICAgICAgICAgICAgICAgInNlbmRfdHJhcDogZmFpbGVkIHRvIGNvbnN0cnVjdCB2MSB0ZW1wbGF0ZSBQRFVcbiIpOwogICAgICAgICAgICBzbm1wX2ZyZWVfdmFyYmluZCh2Ymxpc3QpOwogICAgICAgICAgICByZXR1cm4gLTE7CiAgICAgICAgfQogICAgICAgIHRlbXBsYXRlX3YxcGR1LT50cmFwX3R5cGUgICAgID0gdHJhcDsKICAgICAgICB0ZW1wbGF0ZV92MXBkdS0+c3BlY2lmaWNfdHlwZSA9IHNwZWNpZmljOwogICAgICAgIHRlbXBsYXRlX3YxcGR1LT50aW1lICAgICAgICAgID0gbmV0c25tcF9nZXRfYWdlbnRfdXB0aW1lKCk7CgogICAgICAgIGlmIChzbm1wX2Nsb25lX21lbSgodm9pZCAqKikgJnRlbXBsYXRlX3YxcGR1LT5lbnRlcnByaXNlLAogICAgICAgICAgICAgICAgICAgICAgIGVudGVycHJpc2UsIGVudGVycHJpc2VfbGVuZ3RoICogc2l6ZW9mKG9pZCkpKSB7CiAgICAgICAgICAgIHNubXBfbG9nKExPR19XQVJOSU5HLAogICAgICAgICAgICAgICAgICAgICAic2VuZF90cmFwOiBmYWlsZWQgdG8gc2V0IHYxIGVudGVycHJpc2UgT0lEXG4iKTsKICAgICAgICAgICAgc25tcF9mcmVlX3ZhcmJpbmQodmJsaXN0KTsKICAgICAgICAgICAgc25tcF9mcmVlX3BkdSh0ZW1wbGF0ZV92MXBkdSk7CiAgICAgICAgICAgIHJldHVybiAtMTsKICAgICAgICB9CiAgICAgICAgdGVtcGxhdGVfdjFwZHUtPmVudGVycHJpc2VfbGVuZ3RoID0gZW50ZXJwcmlzZV9sZW5ndGg7CgogICAgICAgIHRlbXBsYXRlX3YxcGR1LT5mbGFncyAgICB8PSBVQ0RfTVNHX0ZMQUdfRk9SQ0VfUERVX0NPUFk7CiAgICAgICAgdGVtcGxhdGVfdjFwZHUtPnZhcmlhYmxlcyA9IHZibGlzdDsKCiAgICAgICAgLyoKICAgICAgICAgKiAuLi4gYW5kIGNvbnZlcnQgaXQgaW50byBhbiBTTk1QdjItc3R5bGUgbm90aWZpY2F0aW9uIFBEVS4KICAgICAgICAgKi8KCiAgICAgICAgdGVtcGxhdGVfdjJwZHUgPSBjb252ZXJ0X3YxcGR1X3RvX3YyKCB0ZW1wbGF0ZV92MXBkdSApOwogICAgICAgIGlmICghdGVtcGxhdGVfdjJwZHUpIHsKICAgICAgICAgICAgc25tcF9sb2coTE9HX1dBUk5JTkcsCiAgICAgICAgICAgICAgICAgICAgICJzZW5kX3RyYXA6IGZhaWxlZCB0byBjb252ZXJ0IHYxLT52MiB0ZW1wbGF0ZSBQRFVcbiIpOwogICAgICAgIH0KICAgIH0KCiAgICAvKgogICAgICogQ2hlY2sgd2hldGhlciB3ZSdyZSBpZ25vcmluZyBhdXRoRmFpbCB0cmFwcwogICAgICovCiAgICBpZiAodGVtcGxhdGVfdjFwZHUpIHsKICAgICAgaWYgKHRlbXBsYXRlX3YxcGR1LT50cmFwX3R5cGUgPT0gU05NUF9UUkFQX0FVVEhGQUlMICYmCiAgICAgICAgc25tcF9lbmFibGVhdXRoZW50cmFwcyA9PSBTTk1QX0FVVEhFTlRJQ0FURURfVFJBUFNfRElTQUJMRUQpIHsKICAgICAgICBzbm1wX2ZyZWVfcGR1KHRlbXBsYXRlX3YxcGR1KTsKICAgICAgICBzbm1wX2ZyZWVfcGR1KHRlbXBsYXRlX3YycGR1KTsKICAgICAgICByZXR1cm4gMDsKICAgICAgfQoKICAgIC8qCiAgICAgKiBFbnN1cmUgdGhhdCB0aGUgdjEgdHJhcCBQRFUgaW5jbHVkZXMgdGhlIGxvY2FsIElQIGFkZHJlc3MKICAgICAqLwogICAgICAgcGR1X2luX2FkZHJfdCA9IChpbl9hZGRyX3QgKikgdGVtcGxhdGVfdjFwZHUtPmFnZW50X2FkZHI7CiAgICAgICB2MXRyYXBhZGRyZXNzID0gbmV0c25tcF9kc19nZXRfc3RyaW5nKE5FVFNOTVBfRFNfQVBQTElDQVRJT05fSUQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5FVFNOTVBfRFNfQUdFTlRfVFJBUF9BRERSKTsKICAgICAgIGlmICh2MXRyYXBhZGRyZXNzICE9IE5VTEwpIHsKICAgICAgICAgICAvKiAidjF0cmFwYWRkcmVzcyIgd2FzIHNwZWNpZmllZCBpbiBjb25maWcsIHRyeSB0byByZXNvbHZlIGl0ICovCiAgICAgICAgICAgcmVzID0gbmV0c25tcF9nZXRob3N0YnluYW1lX3Y0KHYxdHJhcGFkZHJlc3MsIHBkdV9pbl9hZGRyX3QpOwogICAgICAgfQogICAgICAgaWYgKHYxdHJhcGFkZHJlc3MgPT0gTlVMTCB8fCByZXMgPCAwKSB7CiAgICAgICAgICAgLyogInYxdHJhcGFkZHJlc3MiIHdhcyBub3Qgc3BlY2lmaWVkIGluIGNvbmZpZyBvciB0aGUgcmVzb2x1dGlvbiBmYWlsZWQsCiAgICAgICAgICAgICogdHJ5IGFueSBsb2NhbCBhZGRyZXNzICovCiAgICAgICAgICAgKnBkdV9pbl9hZGRyX3QgPSBnZXRfbXlhZGRyKCk7CiAgICAgICB9CgogICAgfQoKICAgIGlmICh0ZW1wbGF0ZV92MnBkdSkgewoJLyogQSBjb250ZXh0IG5hbWUgd2FzIHByb3ZpZGVkLCBzbyBjb3B5IGl0IGFuZCBpdHMgbGVuZ3RoIHRvIHRoZSB2MiBwZHUKCSAqIHRlbXBsYXRlLiAqLwoJaWYgKGNvbnRleHQgIT0gTlVMTCkKCXsKCQl0ZW1wbGF0ZV92MnBkdS0+Y29udGV4dE5hbWUgICAgPSBzdHJkdXAoY29udGV4dCk7CgkJdGVtcGxhdGVfdjJwZHUtPmNvbnRleHROYW1lTGVuID0gc3RybGVuKGNvbnRleHQpOwoJfQogICAgfQoKICAgIC8qCiAgICAgKiAgTm93IGxvb3AgdGhyb3VnaCB0aGUgbGlzdCBvZiB0cmFwIHNpbmtzCiAgICAgKiAgIGFuZCBjYWxsIHRoZSB0cmFwIGNhbGxiYWNrIHJvdXRpbmVzLAogICAgICogICBwcm92aWRpbmcgYW4gYXBwcm9wcmlhdGVseSBmb3JtYXR0ZWQgUERVIGluIGVhY2ggY2FzZQogICAgICovCiAgICBmb3IgKHNpbmsgPSBzaW5rczsgc2luazsgc2luayA9IHNpbmstPm5leHQpIHsKI2lmbmRlZiBORVRTTk1QX0RJU0FCTEVfU05NUFYxCiAgICAgICAgaWYgKHNpbmstPnZlcnNpb24gPT0gU05NUF9WRVJTSU9OXzEpIHsKICAgICAgICAgIGlmICh0ZW1wbGF0ZV92MXBkdSkgewogICAgICAgICAgICBzZW5kX3RyYXBfdG9fc2VzcyhzaW5rLT5zZXNwLCB0ZW1wbGF0ZV92MXBkdSk7CiAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKI2VuZGlmCiAgICAgICAgICBpZiAodGVtcGxhdGVfdjJwZHUpIHsKICAgICAgICAgICAgdGVtcGxhdGVfdjJwZHUtPmNvbW1hbmQgPSBzaW5rLT5wZHV0eXBlOwogICAgICAgICAgICBzZW5kX3RyYXBfdG9fc2VzcyhzaW5rLT5zZXNwLCB0ZW1wbGF0ZV92MnBkdSk7CiAgICAgICAgICB9CiNpZm5kZWYgTkVUU05NUF9ESVNBQkxFX1NOTVBWMQogICAgICAgIH0KI2VuZGlmCiAgICB9CiAgICBpZiAodGVtcGxhdGVfdjFwZHUpCiAgICAgICAgc25tcF9jYWxsX2NhbGxiYWNrcyhTTk1QX0NBTExCQUNLX0FQUExJQ0FUSU9OLAogICAgICAgICAgICAgICAgICAgICAgICBTTk1QRF9DQUxMQkFDS19TRU5EX1RSQVAxLCB0ZW1wbGF0ZV92MXBkdSk7CiAgICBpZiAodGVtcGxhdGVfdjJwZHUpCiAgICAgICAgc25tcF9jYWxsX2NhbGxiYWNrcyhTTk1QX0NBTExCQUNLX0FQUExJQ0FUSU9OLAogICAgICAgICAgICAgICAgICAgICAgICBTTk1QRF9DQUxMQkFDS19TRU5EX1RSQVAyLCB0ZW1wbGF0ZV92MnBkdSk7CiAgICBzbm1wX2ZyZWVfcGR1KHRlbXBsYXRlX3YxcGR1KTsKICAgIHNubXBfZnJlZV9wZHUodGVtcGxhdGVfdjJwZHUpOwogICAgcmV0dXJuIDA7Cn0KCgp2b2lkCnNlbmRfZW50ZXJwcmlzZV90cmFwX3ZhcnMoaW50IHRyYXAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IHNwZWNpZmljLAogICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG9pZCAqIGVudGVycHJpc2UsIGludCBlbnRlcnByaXNlX2xlbmd0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX3ZhcmlhYmxlX2xpc3QgKiB2YXJzKQp7CiAgICBuZXRzbm1wX3NlbmRfdHJhcHModHJhcCwgc3BlY2lmaWMsCiAgICAgICAgICAgICAgICAgICAgICAgZW50ZXJwcmlzZSwgZW50ZXJwcmlzZV9sZW5ndGgsCiAgICAgICAgICAgICAgICAgICAgICAgdmFycywgTlVMTCwgMCk7CiAgICByZXR1cm47Cn0KCi8qKgogKiBDYXB0dXJlcyByZXNwb25zZXMgb3IgdGhlIGxhY2sgdGhlcmUgb2YgZnJvbSBJTkZPUk1zIHRoYXQgd2VyZSBzZW50CiAqIDEpIGEgcmVzcG9uc2UgaXMgcmVjZWl2ZWQgZnJvbSBhbiBJTkZPUk0KICogMikgb25lIGlzbid0IHJlY2VpdmVkIGFuZCB0aGUgcmV0cmllcy90aW1lb3V0cyBoYXZlIGZhaWxlZAoqLwppbnQKaGFuZGxlX2luZm9ybV9yZXNwb25zZShpbnQgb3AsIG5ldHNubXBfc2Vzc2lvbiAqIHNlc3Npb24sCiAgICAgICAgICAgICAgICAgICAgICAgaW50IHJlcWlkLCBuZXRzbm1wX3BkdSAqcGR1LAogICAgICAgICAgICAgICAgICAgICAgIHZvaWQgKm1hZ2ljKQp7CiAgICAvKiBYWFg6IHBvc3NpYmx5IHN0YXRzIHVwZGF0ZSAqLwogICAgc3dpdGNoIChvcCkgewoKICAgIGNhc2UgTkVUU05NUF9DQUxMQkFDS19PUF9SRUNFSVZFRF9NRVNTQUdFOgogICAgICAgIHNubXBfaW5jcmVtZW50X3N0YXRpc3RpYyhTVEFUX1NOTVBJTlBLVFMpOwogICAgICAgIERFQlVHTVNHVEwoKCJ0cmFwIiwgInJlY2VpdmVkIHRoZSBpbmZvcm0gcmVzcG9uc2UgZm9yIHJlcWlkPSVkXG4iLAogICAgICAgICAgICAgICAgICAgIHJlcWlkKSk7CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSBORVRTTk1QX0NBTExCQUNLX09QX1RJTUVEX09VVDoKICAgICAgICBERUJVR01TR1RMKCgidHJhcCIsCiAgICAgICAgICAgICAgICAgICAgInJlY2VpdmVkIGEgdGltZW91dCBzZW5kaW5nIGFuIGluZm9ybSBmb3IgcmVxaWQ9JWRcbiIsCiAgICAgICAgICAgICAgICAgICAgcmVxaWQpKTsKICAgICAgICBicmVhazsKCiAgICBjYXNlIE5FVFNOTVBfQ0FMTEJBQ0tfT1BfU0VORF9GQUlMRUQ6CiAgICAgICAgREVCVUdNU0dUTCgoInRyYXAiLAogICAgICAgICAgICAgICAgICAgICJmYWlsZWQgdG8gc2VuZCBhbiBpbmZvcm0gZm9yIHJlcWlkPSVkXG4iLAogICAgICAgICAgICAgICAgICAgIHJlcWlkKSk7CiAgICAgICAgYnJlYWs7CgogICAgZGVmYXVsdDoKICAgICAgICBERUJVR01TR1RMKCgidHJhcCIsICJyZWNlaXZlZCBvcD0lZCBmb3IgcmVxaWQ9JWQgd2hlbiB0cnlpbmcgdG8gc2VuZCBhbiBpbmZvcm1cbiIsIG9wLCByZXFpZCkpOwogICAgfQoKICAgIHJldHVybiAxOwp9CgoKLyoKICogc2VuZF90cmFwX3RvX3Nlc3M6IHNlbmRzIGEgdHJhcCB0byBhIHNlc3Npb24gYnV0IGFzc3VtZXMgdGhhdCB0aGUKICogcGR1IGlzIGNvbnN0cnVjdGVkIGNvcnJlY3RseSBmb3IgdGhlIHNlc3Npb24gdHlwZS4gCiAqLwp2b2lkCnNlbmRfdHJhcF90b19zZXNzKG5ldHNubXBfc2Vzc2lvbiAqIHNlc3MsIG5ldHNubXBfcGR1ICp0ZW1wbGF0ZV9wZHUpCnsKICAgIG5ldHNubXBfcGR1ICAgICpwZHU7CiAgICBpbnQgICAgICAgICAgICByZXN1bHQ7CiAgICBpbnQgICAgICAgICAgICBsZW47CgoKICAgIGlmICghc2VzcyB8fCAhdGVtcGxhdGVfcGR1KQogICAgICAgIHJldHVybjsKCiAgICBERUJVR01TR1RMKCgidHJhcCIsICJzZW5kaW5nIHRyYXAgdHlwZT0lZCwgdmVyc2lvbj0lbGRcbiIsCiAgICAgICAgICAgICAgICB0ZW1wbGF0ZV9wZHUtPmNvbW1hbmQsIHNlc3MtPnZlcnNpb24pKTsKCiNpZm5kZWYgTkVUU05NUF9ESVNBQkxFX1NOTVBWMQogICAgaWYgKHNlc3MtPnZlcnNpb24gPT0gU05NUF9WRVJTSU9OXzEgJiYKICAgICAgICAodGVtcGxhdGVfcGR1LT5jb21tYW5kICE9IFNOTVBfTVNHX1RSQVApKQogICAgICAgIHJldHVybjsgICAgICAgICAgICAgICAgIC8qIFNraXAgdjEgc2lua3MgZm9yIHYyIG9ubHkgdHJhcHMgKi8KICAgIGlmIChzZXNzLT52ZXJzaW9uICE9IFNOTVBfVkVSU0lPTl8xICYmCiAgICAgICAgKHRlbXBsYXRlX3BkdS0+Y29tbWFuZCA9PSBTTk1QX01TR19UUkFQKSkKICAgICAgICByZXR1cm47ICAgICAgICAgICAgICAgICAvKiBTa2lwIHYyKyBzaW5rcyBmb3IgdjEgb25seSB0cmFwcyAqLwojZW5kaWYKICAgIHRlbXBsYXRlX3BkdS0+dmVyc2lvbiA9IHNlc3MtPnZlcnNpb247CiAgICBwZHUgPSBzbm1wX2Nsb25lX3BkdSh0ZW1wbGF0ZV9wZHUpOwogICAgcGR1LT5zZXNzaWQgPSBzZXNzLT5zZXNzaWQ7IC8qIEFnZW50WCBvbmx5ID8gKi8KCiAgICBpZiAoIHRlbXBsYXRlX3BkdS0+Y29tbWFuZCA9PSBTTk1QX01TR19JTkZPUk0KI2lmZGVmIFVTSU5HX0FHRU5UWF9QUk9UT0NPTF9NT0RVTEUKICAgICAgICAgfHwgdGVtcGxhdGVfcGR1LT5jb21tYW5kID09IEFHRU5UWF9NU0dfTk9USUZZCiNlbmRpZgogICAgICAgKSB7CiAgICAgICAgcmVzdWx0ID0KICAgICAgICAgICAgc25tcF9hc3luY19zZW5kKHNlc3MsIHBkdSwgJmhhbmRsZV9pbmZvcm1fcmVzcG9uc2UsIE5VTEwpOwogICAgICAgIAogICAgfSBlbHNlIHsKICAgICAgICBpZiAoKHNlc3MtPnZlcnNpb24gPT0gU05NUF9WRVJTSU9OXzMpICYmCiAgICAgICAgICAgICAgICAocGR1LT5jb21tYW5kID09IFNOTVBfTVNHX1RSQVAyKSAmJgogICAgICAgICAgICAgICAgKHNlc3MtPnNlY3VyaXR5RW5naW5lSURMZW4gPT0gMCkpIHsKICAgICAgICAgICAgdV9jaGFyICAgICAgICAgIHRtcFtTUFJJTlRfTUFYX0xFTl07CgogICAgICAgICAgICBsZW4gPSBzbm1wdjNfZ2V0X2VuZ2luZUlEKHRtcCwgc2l6ZW9mKHRtcCkpOwogICAgICAgICAgICBwZHUtPnNlY3VyaXR5RW5naW5lSUQgPSBuZXRzbm1wX21lbWR1cCh0bXAsIGxlbik7CiAgICAgICAgICAgIHBkdS0+c2VjdXJpdHlFbmdpbmVJRExlbiA9IGxlbjsKICAgICAgICB9CgogICAgICAgIHJlc3VsdCA9IHNubXBfc2VuZChzZXNzLCBwZHUpOwogICAgfQoKICAgIGlmIChyZXN1bHQgPT0gMCkgewogICAgICAgIHNubXBfc2Vzc19wZXJyb3IoInNubXBkOiBzZW5kX3RyYXAiLCBzZXNzKTsKICAgICAgICBzbm1wX2ZyZWVfcGR1KHBkdSk7CiAgICB9IGVsc2UgewogICAgICAgIHNubXBfaW5jcmVtZW50X3N0YXRpc3RpYyhTVEFUX1NOTVBPVVRUUkFQUyk7CiAgICAgICAgc25tcF9pbmNyZW1lbnRfc3RhdGlzdGljKFNUQVRfU05NUE9VVFBLVFMpOwogICAgfQp9Cgp2b2lkCnNlbmRfdHJhcF92YXJzKGludCB0cmFwLCBpbnQgc3BlY2lmaWMsIG5ldHNubXBfdmFyaWFibGVfbGlzdCAqIHZhcnMpCnsKICAgIGlmICh0cmFwID09IFNOTVBfVFJBUF9FTlRFUlBSSVNFU1BFQ0lGSUMpCiAgICAgICAgc2VuZF9lbnRlcnByaXNlX3RyYXBfdmFycyh0cmFwLCBzcGVjaWZpYywgb2JqaWRfZW50ZXJwcmlzZXRyYXAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBPSURfTEVOR1RIKG9iamlkX2VudGVycHJpc2V0cmFwKSwgdmFycyk7CiAgICBlbHNlCiAgICAgICAgc2VuZF9lbnRlcnByaXNlX3RyYXBfdmFycyh0cmFwLCBzcGVjaWZpYywgdHJhcF92ZXJzaW9uX2lkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgT0lEX0xFTkdUSCh0cmFwX3ZlcnNpb25faWQpLCB2YXJzKTsKfQoKLyogU2VuZCBhIHRyYXAgdW5kZXIgYSBjb250ZXh0ICovCnZvaWQgc2VuZF90cmFwX3ZhcnNfd2l0aF9jb250ZXh0KGludCB0cmFwLCBpbnQgc3BlY2lmaWMsIAogICAgICAgICAgICAgIG5ldHNubXBfdmFyaWFibGVfbGlzdCAqdmFycywgY29uc3QgY2hhciAqY29udGV4dCkKewogICAgaWYgKHRyYXAgPT0gU05NUF9UUkFQX0VOVEVSUFJJU0VTUEVDSUZJQykKICAgICAgICBuZXRzbm1wX3NlbmRfdHJhcHModHJhcCwgc3BlY2lmaWMsIG9iamlkX2VudGVycHJpc2V0cmFwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgT0lEX0xFTkdUSChvYmppZF9lbnRlcnByaXNldHJhcCksIHZhcnMsCgkJCQkJCQkJICBjb250ZXh0LCAwKTsKICAgIGVsc2UKICAgICAgICBuZXRzbm1wX3NlbmRfdHJhcHModHJhcCwgc3BlY2lmaWMsIHRyYXBfdmVyc2lvbl9pZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE9JRF9MRU5HVEgodHJhcF92ZXJzaW9uX2lkKSwgdmFycywgCgkJCQkJCQkJICBjb250ZXh0LCAwKTsKICAgIAkKfQoKLyoqCiAqIFNlbmRzIGFuIFNOTVB2MSB0cmFwIChvciB0aGUgU05NUHYyIGVxdWl2YWxlbnQpIHRvIHRoZSBsaXN0IG9mICAKICogY29uZmlndXJlZCB0cmFwIGRlc3RpbmF0aW9ucyAob3IgInNpbmtzIiksIHVzaW5nIHRoZSBwcm92aWRlZCAKICogdmFsdWVzIGZvciB0aGUgZ2VuZXJpYyB0cmFwIHR5cGUgYW5kIHNwZWNpZmljIHRyYXAgdmFsdWUuCiAqCiAqIFRoaXMgZnVuY3Rpb24gZXZlbnR1YWxseSBjYWxscyBzZW5kX2VudGVycHJpc2VfdHJhcF92YXJzLiAgSWYgdGhlCiAqIHRyYXAgdHlwZSBpcyBub3Qgc2V0IHRvIFNOTVBfVFJBUF9FTlRFUlBSSVNFU1BFQ0lGSUMgdGhlIGVudGVycHJpc2UgCiAqIGFuZCBlbnRlcnByaXNlX2xlbmd0aCBwYXJhbWF0ZXIgaXMgc2V0IHRvIHRoZSBwcmUgZGVmaW5lZCBORVRTTk1QX1NZU1RFTV9NSUIgCiAqIG9pZCBhbmQgbGVuZ3RoIHJlc3BlY3RpdmVseS4gIElmIHRoZSB0cmFwIHR5cGUgaXMgc2V0IHRvIAogKiBTTk1QX1RSQVBfRU5URVJQUklTRVNQRUNJRklDIHRoZSBlbnRlcnByaXNlIGFuZCBlbnRlcnByaXNlX2xlbmd0aCAKICogcGFyYW1ldGVycyBhcmUgc2V0IHRvIHRoZSBwcmUtZGVmaW5lZCBORVRTTk1QX05PVElGSUNBVElPTl9NSUIgb2lkIGFuZCBsZW5ndGggCiAqIHJlc3BlY3RpdmVseS4KICoKICogQHBhcmFtIHRyYXAgaXMgdGhlIGdlbmVyaWMgdHJhcCB0eXBlLgogKgogKiBAcGFyYW0gc3BlY2lmaWMgaXMgdGhlIHNwZWNpZmljIHRyYXAgdmFsdWUuCiAqCiAqIEByZXR1cm4gdm9pZAogKgogKiBAc2VlIHNlbmRfZW50ZXJwcmlzZV90cmFwX3ZhcnMKICogQHNlZSBzZW5kX3YydHJhcAogKi8KICAgICAgIAkKdm9pZApzZW5kX2Vhc3lfdHJhcChpbnQgdHJhcCwgaW50IHNwZWNpZmljKQp7CiAgICBzZW5kX3RyYXBfdmFycyh0cmFwLCBzcGVjaWZpYywgTlVMTCk7Cn0KCi8qKgogKiBVc2VzIHRoZSBzdXBwbGllZCBsaXN0IG9mIHZhcmlhYmxlIGJpbmRpbmdzIHRvIGZvcm0gYW4gU05NUHYyIHRyYXAsIAogKiB3aGljaCBpcyBzZW50IHRvIFNOTVB2Mi1jYXBhYmxlIHNpbmtzICBvbiAgdGhlICBjb25maWd1cmVkICBsaXN0LiAgCiAqIEFuIGVxdWl2YWxlbnQgSU5GT1JNIGlzIHNlbnQgdG8gdGhlIGNvbmZpZ3VyZWQgbGlzdCBvZiBpbmZvcm0gc2lua3MuICAKICogU2lua3MgdGhhdCBjYW4gb25seSBoYW5kbGUgU05NUHYxIHRyYXBzIGFyZSBza2lwcGVkLgogKgogKiBUaGlzIGZ1bmN0aW9uIGV2ZW50dWFsbHkgY2FsbHMgc2VuZF9lbnRlcnByaXNlX3RyYXBfdmFycy4gIElmIHRoZQogKiB0cmFwIHR5cGUgaXMgbm90IHNldCB0byBTTk1QX1RSQVBfRU5URVJQUklTRVNQRUNJRklDIHRoZSBlbnRlcnByaXNlIAogKiBhbmQgZW50ZXJwcmlzZV9sZW5ndGggcGFyYW1hdGVyIGlzIHNldCB0byB0aGUgcHJlIGRlZmluZWQgTkVUU05NUF9TWVNURU1fTUlCIAogKiBvaWQgYW5kIGxlbmd0aCByZXNwZWN0aXZlbHkuICBJZiB0aGUgdHJhcCB0eXBlIGlzIHNldCB0byAKICogU05NUF9UUkFQX0VOVEVSUFJJU0VTUEVDSUZJQyB0aGUgZW50ZXJwcmlzZSBhbmQgZW50ZXJwcmlzZV9sZW5ndGggCiAqIHBhcmFtZXRlcnMgYXJlIHNldCB0byB0aGUgcHJlLWRlZmluZWQgTkVUU05NUF9OT1RJRklDQVRJT05fTUlCIG9pZCBhbmQgbGVuZ3RoIAogKiByZXNwZWN0aXZlbHkuCiAqCiAqIEBwYXJhbSB2YXJzIGlzIHVzZWQgdG8gc3VwcGx5IGxpc3Qgb2YgdmFyaWFibGUgYmluZGluZ3MgdG8gZm9ybSBhbiBTTk1QdjIgCiAqCXRyYXAuCiAqCiAqIEByZXR1cm4gdm9pZAogKgogKiBAc2VlIHNlbmRfZWFzeV90cmFwCiAqIEBzZWUgc2VuZF9lbnRlcnByaXNlX3RyYXBfdmFycwogKi8KCnZvaWQKc2VuZF92MnRyYXAobmV0c25tcF92YXJpYWJsZV9saXN0ICogdmFycykKewogICAgc2VuZF90cmFwX3ZhcnMoLTEsIC0xLCB2YXJzKTsKfQoKLyoqCiAqIFNpbWlsYXIgdG8gc2VuZF92MnRyYXAoKSwgd2l0aCB0aGUgYWRkZWQgYWJpbGl0eSB0byBzcGVjaWZ5IGEgY29udGV4dC4gIElmCiAqIHRoZSBsYXN0IHBhcmFtZXRlciBpcyBOVUxMLCB0aGVuIHRoaXMgY2FsbCBpcyBlcXVpdmFsZW50IHRvIHNlbmRfdjJ0cmFwKCkuCiAqCiAqIEBwYXJhbSB2YXJzIGlzIHVzZWQgdG8gc3VwcGx5IHRoZSBsaXN0IG9mIHZhcmlhYmxlIGJpbmRpbmdzIGZvciB0aGUgdHJhcC4KICogCiAqIEBwYXJhbSBjb250ZXh0IGlzIHVzZWQgdG8gc3BlY2lmeSB0aGUgY29udGV4dCBvZiB0aGUgdHJhcC4KICoKICogQHJldHVybiB2b2lkCiAqCiAqIEBzZWUgc2VuZF92MnRyYXAKICovCnZvaWQgc2VuZF92M3RyYXAobmV0c25tcF92YXJpYWJsZV9saXN0ICp2YXJzLCBjb25zdCBjaGFyICpjb250ZXh0KQp7CiAgICBuZXRzbm1wX3NlbmRfdHJhcHMoLTEsIC0xLCAKICAgICAgICAgICAgICAgICAgICAgICB0cmFwX3ZlcnNpb25faWQsIE9JRF9MRU5HVEgodHJhcF92ZXJzaW9uX2lkKSwKICAgICAgICAgICAgICAgICAgICAgICB2YXJzLCBjb250ZXh0LCAwKTsKfQoKdm9pZApzZW5kX3RyYXBfcGR1KG5ldHNubXBfcGR1ICpwZHUpCnsKICAgIHNlbmRfdHJhcF92YXJzKC0xLCAtMSwgcGR1LT52YXJpYWJsZXMpOwp9CgoKCiAgICAgICAgLyoqKioqKioqKioqKioqKioqKioKCSAqCgkgKiBDb25maWcgZmlsZSBoYW5kbGluZwoJICoKCSAqKioqKioqKioqKioqKioqKioqLwoKdm9pZApzbm1wZF9wYXJzZV9jb25maWdfYXV0aHRyYXAoY29uc3QgY2hhciAqdG9rZW4sIGNoYXIgKmNwdHIpCnsKICAgIGludCAgICAgICAgICAgICBpOwoKICAgIGkgPSBhdG9pKGNwdHIpOwogICAgaWYgKGkgPT0gMCkgewogICAgICAgIGlmIChzdHJjbXAoY3B0ciwgImVuYWJsZSIpID09IDApIHsKICAgICAgICAgICAgaSA9IFNOTVBfQVVUSEVOVElDQVRFRF9UUkFQU19FTkFCTEVEOwogICAgICAgIH0gZWxzZSBpZiAoc3RyY21wKGNwdHIsICJkaXNhYmxlIikgPT0gMCkgewogICAgICAgICAgICBpID0gU05NUF9BVVRIRU5USUNBVEVEX1RSQVBTX0RJU0FCTEVEOwogICAgICAgIH0KICAgIH0KICAgIGlmIChpIDwgMSB8fCBpID4gMikgewogICAgICAgIGNvbmZpZ19wZXJyb3IoImF1dGh0cmFwZW5hYmxlIG11c3QgYmUgMSBvciAyIik7CiAgICB9IGVsc2UgewogICAgICAgIGlmIChzdHJjbXAodG9rZW4sICJwYXV0aHRyYXBlbmFibGUiKSA9PSAwKSB7CiAgICAgICAgICAgIGlmIChzbm1wX2VuYWJsZWF1dGhlbnRyYXBzc2V0IDwgMCkgewogICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAqIFRoaXMgaXMgYm9ndXMgKGFuZCBzaG91bGRuJ3QgaGFwcGVuIGFueXdheSkgLS0gdGhlIHZhbHVlCiAgICAgICAgICAgICAgICAgKiBvZiBzbm1wRW5hYmxlQXV0aGVuVHJhcHMuMCBpcyBhbHJlYWR5IGNvbmZpZ3VyZWQKICAgICAgICAgICAgICAgICAqIHJlYWQtb25seS4gIAogICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICBzbm1wX2xvZyhMT0dfV0FSTklORywKICAgICAgICAgICAgICAgICAgICAgICAgICJpZ25vcmluZyBhdHRlbXB0ZWQgb3ZlcnJpZGUgb2YgcmVhZC1vbmx5IHNubXBFbmFibGVBdXRoZW5UcmFwcy4wXG4iKTsKICAgICAgICAgICAgICAgIHJldHVybjsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHNubXBfZW5hYmxlYXV0aGVudHJhcHNzZXQrKzsKICAgICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGlmIChzbm1wX2VuYWJsZWF1dGhlbnRyYXBzc2V0ID4gMCkgewogICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAqIFRoaXMgaXMgYm9ndXMgKGFuZCBzaG91bGRuJ3QgaGFwcGVuIGFueXdheSkgLS0gd2UgYWxyZWFkeQogICAgICAgICAgICAgICAgICogcmVhZCBhIHBlcnNpc3RlbnQgdmFsdWUgb2Ygc25tcEVuYWJsZUF1dGhlblRyYXBzLjAsIHdoaWNoCiAgICAgICAgICAgICAgICAgKiB3ZSBzaG91bGQgaWdub3JlIGluIGZhdm91ciBvZiB0aGlzIG9uZS4gIAogICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICBzbm1wX2xvZyhMT0dfV0FSTklORywKICAgICAgICAgICAgICAgICAgICAgICAgICJpZ25vcmluZyBhdHRlbXB0ZWQgb3ZlcnJpZGUgb2YgcmVhZC1vbmx5IHNubXBFbmFibGVBdXRoZW5UcmFwcy4wXG4iKTsKICAgICAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAgICAgKiBGYWxsIHRocm91Z2ggYW5kIGNvcHkgaW4gdGhpcyB2YWx1ZS4gIAogICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgIH0KICAgICAgICAgICAgc25tcF9lbmFibGVhdXRoZW50cmFwc3NldCA9IC0xOwogICAgICAgIH0KICAgICAgICBzbm1wX2VuYWJsZWF1dGhlbnRyYXBzID0gaTsKICAgIH0KfQoKI2lmbmRlZiBORVRTTk1QX0RJU0FCTEVfU05NUFYxCnZvaWQKc25tcGRfcGFyc2VfY29uZmlnX3RyYXBzaW5rKGNvbnN0IGNoYXIgKnRva2VuLCBjaGFyICpjcHRyKQp7CiAgICBjaGFyICAgICAgICAgICAqc3AsICpjcCwgKnBwID0gTlVMTDsKICAgIGNoYXIgICAgICAgICAgICAqc3Q7CgogICAgaWYgKCFzbm1wX3RyYXBjb21tdW5pdHkpCiAgICAgICAgc25tcF90cmFwY29tbXVuaXR5ID0gc3RyZHVwKCJwdWJsaWMiKTsKICAgIHNwID0gc3RydG9rX3IoY3B0ciwgIiBcdFxuIiwgJnN0KTsKICAgIGNwID0gc3RydG9rX3IoTlVMTCwgIiBcdFxuIiwgJnN0KTsKICAgIGlmIChjcCkKICAgICAgICBwcCA9IHN0cnRva19yKE5VTEwsICIgXHRcbiIsICZzdCk7CiAgICBpZiAocHApCgljb25maWdfcHdhcm4oIlRoZSBzZXBhcmF0ZSBwb3J0IGFyZ3VtZW50IHRvIHRyYXBzaW5rIGlzIGRlcHJlY2F0ZWQiKTsKICAgIGlmIChjcmVhdGVfdjFfdHJhcF9zZXNzaW9uKHNwLCBwcCwgY3AgPyBjcCA6IHNubXBfdHJhcGNvbW11bml0eSkgPT0gMCkgewoJbmV0c25tcF9jb25maWdfZXJyb3IoImNhbm5vdCBjcmVhdGUgdHJhcHNpbms6ICVzIiwgY3B0cik7CiAgICB9Cn0KI2VuZGlmCgojaWZuZGVmIE5FVFNOTVBfRElTQUJMRV9TTk1QVjJDCnZvaWQKc25tcGRfcGFyc2VfY29uZmlnX3RyYXAyc2luayhjb25zdCBjaGFyICp3b3JkLCBjaGFyICpjcHRyKQp7CiAgICBjaGFyICAgICAgICAgICAqc3QsICpzcCwgKmNwLCAqcHAgPSBOVUxMOwoKICAgIGlmICghc25tcF90cmFwY29tbXVuaXR5KQogICAgICAgIHNubXBfdHJhcGNvbW11bml0eSA9IHN0cmR1cCgicHVibGljIik7CiAgICBzcCA9IHN0cnRva19yKGNwdHIsICIgXHRcbiIsICZzdCk7CiAgICBjcCA9IHN0cnRva19yKE5VTEwsICIgXHRcbiIsICZzdCk7CiAgICBpZiAoY3ApCiAgICAgICAgcHAgPSBzdHJ0b2tfcihOVUxMLCAiIFx0XG4iLCAmc3QpOwogICAgaWYgKHBwKQoJY29uZmlnX3B3YXJuKCJUaGUgc2VwYXJhdGUgcG9ydCBhcmd1bWVudCB0byB0cmFwc2luazIgaXMgZGVwcmVjYXRlZCIpOwogICAgaWYgKGNyZWF0ZV92Ml90cmFwX3Nlc3Npb24oc3AsIHBwLCBjcCA/IGNwIDogc25tcF90cmFwY29tbXVuaXR5KSA9PSAwKSB7CgluZXRzbm1wX2NvbmZpZ19lcnJvcigiY2Fubm90IGNyZWF0ZSB0cmFwMnNpbms6ICVzIiwgY3B0cik7CiAgICB9Cn0KCnZvaWQKc25tcGRfcGFyc2VfY29uZmlnX2luZm9ybXNpbmsoY29uc3QgY2hhciAqd29yZCwgY2hhciAqY3B0cikKewogICAgY2hhciAgICAgICAgICAgKnN0LCAqc3AsICpjcCwgKnBwID0gTlVMTDsKCiAgICBpZiAoIXNubXBfdHJhcGNvbW11bml0eSkKICAgICAgICBzbm1wX3RyYXBjb21tdW5pdHkgPSBzdHJkdXAoInB1YmxpYyIpOwogICAgc3AgPSBzdHJ0b2tfcihjcHRyLCAiIFx0XG4iLCAmc3QpOwogICAgY3AgPSBzdHJ0b2tfcihOVUxMLCAiIFx0XG4iLCAmc3QpOwogICAgaWYgKGNwKQogICAgICAgIHBwID0gc3RydG9rX3IoTlVMTCwgIiBcdFxuIiwgJnN0KTsKICAgIGlmIChwcCkKCWNvbmZpZ19wd2FybigiVGhlIHNlcGFyYXRlIHBvcnQgYXJndW1lbnQgdG8gaW5mb3Jtc2luayBpcyBkZXByZWNhdGVkIik7CiAgICBpZiAoY3JlYXRlX3YyX2luZm9ybV9zZXNzaW9uKHNwLCBwcCwgY3AgPyBjcCA6IHNubXBfdHJhcGNvbW11bml0eSkgPT0gMCkgewoJbmV0c25tcF9jb25maWdfZXJyb3IoImNhbm5vdCBjcmVhdGUgaW5mb3Jtc2luazogJXMiLCBjcHRyKTsKICAgIH0KfQojZW5kaWYKCi8qCiAqIHRoaXMgbXVzdCBiZSBzdGFuZGFyZGl6ZWQgc29tZXdoZXJlLCByaWdodD8gCiAqLwojZGVmaW5lIE1BWF9BUkdTIDEyOAoKc3RhdGljIGludCAgICAgIHRyYXB0eXBlOwoKc3RhdGljIHZvaWQKdHJhcE9wdFByb2MoaW50IGFyZ2MsIGNoYXIgKmNvbnN0ICphcmd2LCBpbnQgb3B0KQp7CiAgICBzd2l0Y2ggKG9wdCkgewogICAgY2FzZSAnQyc6CiAgICAgICAgd2hpbGUgKCpvcHRhcmcpIHsKICAgICAgICAgICAgc3dpdGNoICgqb3B0YXJnKyspIHsKICAgICAgICAgICAgY2FzZSAnaSc6CiAgICAgICAgICAgICAgICB0cmFwdHlwZSA9IFNOTVBfTVNHX0lORk9STTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgY29uZmlnX3BlcnJvcigidW5rbm93biBhcmd1bWVudCBwYXNzZWQgdG8gLUMiKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIGJyZWFrOwogICAgfQp9CgoKdm9pZApzbm1wZF9wYXJzZV9jb25maWdfdHJhcHNlc3MoY29uc3QgY2hhciAqd29yZCwgY2hhciAqY3B0cikKewogICAgY2hhciAgICAgICAgICAgKmFyZ3ZbTUFYX0FSR1NdLCAqY3AgPSBjcHRyOwogICAgaW50ICAgICAgICAgICAgIGFyZ24sIHJjOwogICAgbmV0c25tcF9zZXNzaW9uIHNlc3Npb24sICpzczsKICAgIG5ldHNubXBfdHJhbnNwb3J0ICp0cmFuc3BvcnQ7CiAgICBzaXplX3QgICAgICAgICAgbGVuOwoKICAgIC8qCiAgICAgKiBpbmZvcm0gb3IgdHJhcD8gIGRlZmF1bHQgdG8gdHJhcCAKICAgICAqLwogICAgdHJhcHR5cGUgPSBTTk1QX01TR19UUkFQMjsKCiAgICAvKgogICAgICogY3JlYXRlIHRoZSBhcmd2W10gbGlrZSBhcnJheSAKICAgICAqLwogICAgYXJndlswXSA9IHN0cmR1cCgic25tcGQtdHJhcHNlc3MiKTsgLyogYm9ndXMgZW50cnkgZm9yIGdldG9wdCgpICovCiAgICBmb3IgKGFyZ24gPSAxOyBjcCAmJiBhcmduIDwgTUFYX0FSR1M7IGFyZ24rKykgewogICAgICAgIGNoYXIgICAgICAgICAgICB0bXBbU1BSSU5UX01BWF9MRU5dOwoKICAgICAgICBjcCA9IGNvcHlfbndvcmQoY3AsIHRtcCwgU1BSSU5UX01BWF9MRU4pOwogICAgICAgIGFyZ3ZbYXJnbl0gPSBzdHJkdXAodG1wKTsKICAgIH0KCiAgICBuZXRzbm1wX3BhcnNlX2FyZ3MoYXJnbiwgYXJndiwgJnNlc3Npb24sICJDOiIsIHRyYXBPcHRQcm9jLAogICAgICAgICAgICAgICAgICAgICAgIE5FVFNOTVBfUEFSU0VfQVJHU19OT0xPR0dJTkcgfAogICAgICAgICAgICAgICAgICAgICAgIE5FVFNOTVBfUEFSU0VfQVJHU19OT1pFUk8pOwoKICAgIHRyYW5zcG9ydCA9IG5ldHNubXBfdHJhbnNwb3J0X29wZW5fY2xpZW50KCJzbm1wdHJhcCIsIHNlc3Npb24ucGVlcm5hbWUpOwogICAgaWYgKHRyYW5zcG9ydCA9PSBOVUxMKSB7CiAgICAgICAgY29uZmlnX3BlcnJvcigic25tcGQ6IGZhaWxlZCB0byBwYXJzZSB0aGlzIGxpbmUuIik7CiAgICAgICAgcmV0dXJuOwogICAgfQogICAgaWYgKChyYyA9IG5ldHNubXBfc2Vzc19jb25maWdfYW5kX29wZW5fdHJhbnNwb3J0KCZzZXNzaW9uLCB0cmFuc3BvcnQpKQogICAgICAgICE9IFNOTVBFUlJfU1VDQ0VTUykgewogICAgICAgIHNlc3Npb24uc19zbm1wX2Vycm5vID0gcmM7CiAgICAgICAgc2Vzc2lvbi5zX2Vycm5vID0gMDsKICAgICAgICByZXR1cm47CiAgICB9CiAgICBzcyA9IHNubXBfYWRkKCZzZXNzaW9uLCB0cmFuc3BvcnQsIE5VTEwsIE5VTEwpOwogICAgZm9yICg7IGFyZ24gPiAwOyBhcmduLS0pIHsKICAgICAgICBmcmVlKGFyZ3ZbYXJnbiAtIDFdKTsKICAgIH0KCiAgICBpZiAoIXNzKSB7CiAgICAgICAgY29uZmlnX3BlcnJvcgogICAgICAgICAgICAoInNubXBkOiBmYWlsZWQgdG8gcGFyc2UgdGhpcyBsaW5lIG9yIHRoZSByZW1vdGUgdHJhcCByZWNlaXZlciBpcyBkb3duLiAgUG9zc2libGUgY2F1c2U6Iik7CiAgICAgICAgc25tcF9zZXNzX3BlcnJvcigic25tcGQ6IHNubXBkX3BhcnNlX2NvbmZpZ190cmFwc2VzcygpIiwgJnNlc3Npb24pOwogICAgICAgIHJldHVybjsKICAgIH0KCiAgICAvKgogICAgICogSWYgdGhpcyBpcyBhbiBTTk1QdjMgVFJBUCBzZXNzaW9uLCB0aGVuIHRoZSBhZ2VudCBpcwogICAgICogICB0aGUgYXV0aG9yaXRhdGl2ZSBlbmdpbmUsIHNvIHNldCB0aGUgZW5naW5lSUQgYWNjb3JkaW5nbHkKICAgICAqLwogICAgaWYgKHNzLT52ZXJzaW9uID09IFNOTVBfVkVSU0lPTl8zICYmCiAgICAgICAgdHJhcHR5cGUgIT0gU05NUF9NU0dfSU5GT1JNICAgJiYKICAgICAgICBzcy0+c2VjdXJpdHlFbmdpbmVJRExlbiA9PSAwKSB7CiAgICAgICAgICAgIHVfY2hhciAgICAgICAgICB0bXBbU1BSSU5UX01BWF9MRU5dOwoKICAgICAgICAgICAgbGVuID0gc25tcHYzX2dldF9lbmdpbmVJRCggdG1wLCBzaXplb2YodG1wKSk7CiAgICAgICAgICAgIHNzLT5zZWN1cml0eUVuZ2luZUlEID0gbmV0c25tcF9tZW1kdXAodG1wLCBsZW4pOwogICAgICAgICAgICBzcy0+c2VjdXJpdHlFbmdpbmVJRExlbiA9IGxlbjsKICAgIH0KCiNpZm5kZWYgTkVUU05NUF9ESVNBQkxFX1NOTVBWMQogICAgaWYgKHNzLT52ZXJzaW9uID09IFNOTVBfVkVSU0lPTl8xKQogICAgICAgIHRyYXB0eXBlID0gU05NUF9NU0dfVFJBUDsKI2VuZGlmCiAgICBhZGRfdHJhcF9zZXNzaW9uKHNzLCB0cmFwdHlwZSwgKHRyYXB0eXBlID09IFNOTVBfTVNHX0lORk9STSksIHNzLT52ZXJzaW9uKTsKfQoKI2lmICFkZWZpbmVkKE5FVFNOTVBfRElTQUJMRV9TTk1QVjEpIHx8ICFkZWZpbmVkKE5FVFNOTVBfRElTQUJMRV9TTk1QVjJDKQp2b2lkCnNubXBkX3BhcnNlX2NvbmZpZ190cmFwY29tbXVuaXR5KGNvbnN0IGNoYXIgKndvcmQsIGNoYXIgKmNwdHIpCnsKICAgIGlmIChzbm1wX3RyYXBjb21tdW5pdHkgIT0gTlVMTCkgewogICAgICAgIGZyZWUoc25tcF90cmFwY29tbXVuaXR5KTsKICAgIH0KICAgIHNubXBfdHJhcGNvbW11bml0eSA9IChjaGFyICopIG1hbGxvYyhzdHJsZW4oY3B0cikgKyAxKTsKICAgIGlmIChzbm1wX3RyYXBjb21tdW5pdHkgIT0gTlVMTCkgewogICAgICAgIGNvcHlfbndvcmQoY3B0ciwgc25tcF90cmFwY29tbXVuaXR5LCBzdHJsZW4oY3B0cikgKyAxKTsKICAgIH0KfQoKdm9pZApzbm1wZF9mcmVlX3RyYXBjb21tdW5pdHkodm9pZCkKewogICAgaWYgKHNubXBfdHJhcGNvbW11bml0eSkgewogICAgICAgIGZyZWUoc25tcF90cmFwY29tbXVuaXR5KTsKICAgICAgICBzbm1wX3RyYXBjb21tdW5pdHkgPSBOVUxMOwogICAgfQp9CiNlbmRpZgovKiogQH0gKi8K