Ci8qIFBvcnRpb25zIG9mIHRoaXMgZmlsZSBhcmUgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIGNvcHlyaWdodChzKS4gIFNlZQogKiB0aGUgTmV0LVNOTVAncyBDT1BZSU5HIGZpbGUgZm9yIG1vcmUgZGV0YWlscyBhbmQgb3RoZXIgY29weXJpZ2h0cwogKiB0aGF0IG1heSBhcHBseToKICovCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKCUNvcHlyaWdodCAxOTg5LCAxOTkxLCAxOTkyIGJ5IENhcm5lZ2llIE1lbGxvbiBVbml2ZXJzaXR5CgogICAgICAgICAgICAgICAgICAgICAgQWxsIFJpZ2h0cyBSZXNlcnZlZAoKUGVybWlzc2lvbiB0byB1c2UsIGNvcHksIG1vZGlmeSwgYW5kIGRpc3RyaWJ1dGUgdGhpcyBzb2Z0d2FyZSBhbmQgaXRzCmRvY3VtZW50YXRpb24gZm9yIGFueSBwdXJwb3NlIGFuZCB3aXRob3V0IGZlZSBpcyBoZXJlYnkgZ3JhbnRlZCwKcHJvdmlkZWQgdGhhdCB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhcHBlYXIgaW4gYWxsIGNvcGllcyBhbmQgdGhhdApib3RoIHRoYXQgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBhcHBlYXIgaW4Kc3VwcG9ydGluZyBkb2N1bWVudGF0aW9uLCBhbmQgdGhhdCB0aGUgbmFtZSBvZiBDTVUgbm90IGJlCnVzZWQgaW4gYWR2ZXJ0aXNpbmcgb3IgcHVibGljaXR5IHBlcnRhaW5pbmcgdG8gZGlzdHJpYnV0aW9uIG9mIHRoZQpzb2Z0d2FyZSB3aXRob3V0IHNwZWNpZmljLCB3cml0dGVuIHByaW9yIHBlcm1pc3Npb24uCgpDTVUgRElTQ0xBSU1TIEFMTCBXQVJSQU5USUVTIFdJVEggUkVHQVJEIFRPIFRISVMgU09GVFdBUkUsIElOQ0xVRElORwpBTEwgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUywgSU4gTk8gRVZFTlQgU0hBTEwKQ01VIEJFIExJQUJMRSBGT1IgQU5ZIFNQRUNJQUwsIElORElSRUNUIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyBPUgpBTlkgREFNQUdFUyBXSEFUU09FVkVSIFJFU1VMVElORyBGUk9NIExPU1MgT0YgVVNFLCBEQVRBIE9SIFBST0ZJVFMsCldIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBORUdMSUdFTkNFIE9SIE9USEVSIFRPUlRJT1VTIEFDVElPTiwKQVJJU0lORyBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBVU0UgT1IgUEVSRk9STUFOQ0UgT0YgVEhJUwpTT0ZUV0FSRS4KKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwovKgogKiBQb3J0aW9ucyBvZiB0aGlzIGZpbGUgYXJlIGNvcHlyaWdodGVkIGJ5OgogKiBDb3B5cmlnaHQgQ29weXJpZ2h0IDIwMDMgU3VuIE1pY3Jvc3lzdGVtcywgSW5jLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBVc2UgaXMgc3ViamVjdCB0byBsaWNlbnNlIHRlcm1zIHNwZWNpZmllZCBpbiB0aGUgQ09QWUlORyBmaWxlCiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhlIE5ldC1TTk1QIHBhY2thZ2UuCiAqLwoKLyoqIEBkZWZncm91cCBsaWJyYXJ5IFRoZSBOZXQtU05NUCBsaWJyYXJ5CiAqICBAewogKi8KLyoKICogc25tcF9hcGkuYyAtIEFQSSBmb3IgYWNjZXNzIHRvIHNubXAuCiAqLwojaW5jbHVkZSA8bmV0LXNubXAvbmV0LXNubXAtY29uZmlnLmg+CgojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPGN0eXBlLmg+CiNpZiBIQVZFX1NURExJQl9ICiNpbmNsdWRlIDxzdGRsaWIuaD4KI2VuZGlmCiNpZiBIQVZFX1NUUklOR19ICiNpbmNsdWRlIDxzdHJpbmcuaD4KI2Vsc2UKI2luY2x1ZGUgPHN0cmluZ3MuaD4KI2VuZGlmCiNpZiBIQVZFX1VOSVNURF9ICiNpbmNsdWRlIDx1bmlzdGQuaD4KI2VuZGlmCiNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KI2lmIEhBVkVfU1lTX1BBUkFNX0gKI2luY2x1ZGUgPHN5cy9wYXJhbS5oPgojZW5kaWYKI2lmIFRJTUVfV0lUSF9TWVNfVElNRQojIGluY2x1ZGUgPHN5cy90aW1lLmg+CiMgaW5jbHVkZSA8dGltZS5oPgojZWxzZQojIGlmIEhBVkVfU1lTX1RJTUVfSAojICBpbmNsdWRlIDxzeXMvdGltZS5oPgojIGVsc2UKIyAgaW5jbHVkZSA8dGltZS5oPgojIGVuZGlmCiNlbmRpZgojaWYgSEFWRV9ORVRJTkVUX0lOX0gKI2luY2x1ZGUgPG5ldGluZXQvaW4uaD4KI2VuZGlmCiNpZiBIQVZFX0FSUEFfSU5FVF9ICiNpbmNsdWRlIDxhcnBhL2luZXQuaD4KI2VuZGlmCiNpZiBIQVZFX1NZU19TRUxFQ1RfSAojaW5jbHVkZSA8c3lzL3NlbGVjdC5oPgojZW5kaWYKI2lmIEhBVkVfSU9fSAojaW5jbHVkZSA8aW8uaD4KI2VuZGlmCiNpZiBIQVZFX1NZU19TT0NLRVRfSAojaW5jbHVkZSA8c3lzL3NvY2tldC5oPgojZW5kaWYKI2lmIEhBVkVfU1lTX1VOX0gKI2luY2x1ZGUgPHN5cy91bi5oPgojZW5kaWYKI2lmIEhBVkVfTkVUREJfSAojaW5jbHVkZSA8bmV0ZGIuaD4KI2VuZGlmCiNpZiBIQVZFX05FVF9JRl9ETF9ICiNpZm5kZWYgZHluaXgKI2luY2x1ZGUgPG5ldC9pZl9kbC5oPgojZWxzZQojaW5jbHVkZSA8c3lzL25ldC9pZl9kbC5oPgojZW5kaWYKI2VuZGlmCiNpbmNsdWRlIDxlcnJuby5oPgoKI2lmIEhBVkVfTE9DQUxFX0gKI2luY2x1ZGUgPGxvY2FsZS5oPgojZW5kaWYKCiNpZiBIQVZFX0RNQUxMT0NfSAojaW5jbHVkZSA8ZG1hbGxvYy5oPgojZW5kaWYKCiNkZWZpbmUgU05NUF9ORUVEX1JFUVVFU1RfTElTVAojaW5jbHVkZSA8bmV0LXNubXAvdHlwZXMuaD4KI2luY2x1ZGUgPG5ldC1zbm1wL291dHB1dF9hcGkuaD4KI2luY2x1ZGUgPG5ldC1zbm1wL2NvbmZpZ19hcGkuaD4KI2luY2x1ZGUgPG5ldC1zbm1wL3V0aWxpdGllcy5oPgoKI2luY2x1ZGUgPG5ldC1zbm1wL2xpYnJhcnkvYXNuMS5oPgojaW5jbHVkZSA8bmV0LXNubXAvbGlicmFyeS9zbm1wLmg+ICAgICAgLyogZm9yIHhkdW1wICYge2J1aWxkLHBhcnNlfV92YXJfb3AgKi8KI2luY2x1ZGUgPG5ldC1zbm1wL2xpYnJhcnkvc25tcF9hcGkuaD4KI2luY2x1ZGUgPG5ldC1zbm1wL2xpYnJhcnkvc25tcF9jbGllbnQuaD4KI2luY2x1ZGUgPG5ldC1zbm1wL2xpYnJhcnkvcGFyc2UuaD4KI2luY2x1ZGUgPG5ldC1zbm1wL2xpYnJhcnkvbWliLmg+CiNpbmNsdWRlIDxuZXQtc25tcC9saWJyYXJ5L2ludDY0Lmg+CiNpbmNsdWRlIDxuZXQtc25tcC9saWJyYXJ5L3NubXB2My5oPgojaW5jbHVkZSA8bmV0LXNubXAvbGlicmFyeS9jYWxsYmFjay5oPgojaW5jbHVkZSA8bmV0LXNubXAvbGlicmFyeS9jb250YWluZXIuaD4KI2luY2x1ZGUgPG5ldC1zbm1wL2xpYnJhcnkvc25tcF9zZWNtb2QuaD4KI2luY2x1ZGUgPG5ldC1zbm1wL2xpYnJhcnkvbGFyZ2VfZmRfc2V0Lmg+CiNpZmRlZiBORVRTTk1QX1NFQ01PRF9VU00KI2luY2x1ZGUgPG5ldC1zbm1wL2xpYnJhcnkvc25tcHVzbS5oPgojZW5kaWYKI2lmZGVmIE5FVFNOTVBfU0VDTU9EX0tTTQojaW5jbHVkZSA8bmV0LXNubXAvbGlicmFyeS9zbm1wa3NtLmg+CiNlbmRpZgojaW5jbHVkZSA8bmV0LXNubXAvbGlicmFyeS9rZXl0b29scy5oPgojaW5jbHVkZSA8bmV0LXNubXAvbGlicmFyeS9sY2RfdGltZS5oPgojaW5jbHVkZSA8bmV0LXNubXAvbGlicmFyeS9zbm1wX2FsYXJtLmg+CiNpbmNsdWRlIDxuZXQtc25tcC9saWJyYXJ5L3NubXBfdHJhbnNwb3J0Lmg+CiNpbmNsdWRlIDxuZXQtc25tcC9saWJyYXJ5L3NubXBfc2VydmljZS5oPgojaW5jbHVkZSA8bmV0LXNubXAvbGlicmFyeS92YWNtLmg+CgojaWYgZGVmaW5lZChORVRTTk1QX1VTRV9PUEVOU1NMKSAmJiBkZWZpbmVkKEhBVkVfTElCU1NMKQpleHRlcm4gdm9pZCBuZXRzbm1wX2NlcnRzX2luaXQodm9pZCk7CiNlbmRpZgoKc3RhdGljIHZvaWQgICAgIF9pbml0X3NubXAodm9pZCk7CgpzdGF0aWMgaW50ICAgICAgX3NubXBfc3RvcmVfbmVlZGVkID0gMDsKCiNpbmNsdWRlICIuLi9hZ2VudC9taWJncm91cC9hZ2VudHgvcHJvdG9jb2wuaCIKI2luY2x1ZGUgPG5ldC1zbm1wL2xpYnJhcnkvdHJhbnNmb3JtX29pZHMuaD4KI2lmbmRlZiB0aW1lcmNtcAojZGVmaW5lCXRpbWVyY21wKHR2cCwgdXZwLCBjbXApIFwKCS8qIENTVFlMRUQgKi8gXAoJKCh0dnApLT50dl9zZWMgY21wICh1dnApLT50dl9zZWMgfHwgXAoJKCh0dnApLT50dl9zZWMgPT0gKHV2cCktPnR2X3NlYyAmJiBcCgkvKiBDU1RZTEVEICovIFwKCSh0dnApLT50dl91c2VjIGNtcCAodXZwKS0+dHZfdXNlYykpCiNlbmRpZgojaWZuZGVmIHRpbWVyY2xlYXIKI2RlZmluZQl0aW1lcmNsZWFyKHR2cCkJCSh0dnApLT50dl9zZWMgPSAodHZwKS0+dHZfdXNlYyA9IDAKI2VuZGlmCgovKgogKiBHbG9iYWxzLgogKi8KI2RlZmluZSBNQVhfUEFDS0VUX0xFTkdUSAkoMHg3ZmZmZmZmZikKI2lmbmRlZiBORVRTTk1QX1NUUkVBTV9RVUVVRV9MRU4KI2RlZmluZSBORVRTTk1QX1NUUkVBTV9RVUVVRV9MRU4gIDUKI2VuZGlmCgojaWZuZGVmIEJTRDRfMwojZGVmaW5lIEJTRDRfMgojZW5kaWYKCiNpZm5kZWYgRkRfU0VUCgp0eXBlZGVmIGxvbmcgICAgZmRfbWFzazsKI2RlZmluZSBORkRCSVRTCShzaXplb2YoZmRfbWFzaykgKiBOQkJZKSAgICAgICAgLyogYml0cyBwZXIgbWFzayAqLwoKI2RlZmluZQlGRF9TRVQobiwgcCkJKChwKS0+ZmRzX2JpdHNbKG4pL05GREJJVFNdIHw9ICgxIDw8ICgobikgJSBORkRCSVRTKSkpCiNkZWZpbmUJRkRfQ0xSKG4sIHApCSgocCktPmZkc19iaXRzWyhuKS9ORkRCSVRTXSAmPSB+KDEgPDwgKChuKSAlIE5GREJJVFMpKSkKI2RlZmluZQlGRF9JU1NFVChuLCBwKQkoKHApLT5mZHNfYml0c1sobikvTkZEQklUU10gJiAoMSA8PCAoKG4pICUgTkZEQklUUykpKQojZGVmaW5lIEZEX1pFUk8ocCkJbWVtc2V0KChwKSwgMCwgc2l6ZW9mKCoocCkpKQojZW5kaWYKCnN0YXRpYyBvaWQgICAgICBkZWZhdWx0X2VudGVycHJpc2VbXSA9IHsgMSwgMywgNiwgMSwgNCwgMSwgMywgMSwgMSB9OwovKgogKiBlbnRlcnByaXNlcy5jbXUuc3lzdGVtcy5jbXVTTk1QIAogKi8KCiNkZWZpbmUgREVGQVVMVF9DT01NVU5JVFkgICAicHVibGljIgojZGVmaW5lIERFRkFVTFRfUkVUUklFUwkgICAgNQojZGVmaW5lIERFRkFVTFRfVElNRU9VVAkgICAgMTAwMDAwMEwKI2RlZmluZSBERUZBVUxUX1JFTVBPUlQJICAgIFNOTVBfUE9SVAojZGVmaW5lIERFRkFVTFRfRU5URVJQUklTRSAgZGVmYXVsdF9lbnRlcnByaXNlCiNkZWZpbmUgREVGQVVMVF9USU1FCSAgICAwCgovKgogKiBkb24ndCBzZXQgaGlnaGVyIHRoYW4gMHg3ZmZmZmZmZiwgYW5kIEkgZG91YnQgaXQgc2hvdWxkIGJlIHRoYXQgaGlnaAogKiAqID0gNCBnaWcgc25tcCBtZXNzYWdlcyBtYXggCiAqLwojZGVmaW5lIE1BWElNVU1fUEFDS0VUX1NJWkUgMHg3ZmZmZmZmZgoKLyoKICogSW50ZXJuYWwgaW5mb3JtYXRpb24gYWJvdXQgdGhlIHN0YXRlIG9mIHRoZSBzbm1wIHNlc3Npb24uCiAqLwpzdHJ1Y3Qgc25tcF9pbnRlcm5hbF9zZXNzaW9uIHsKICAgIG5ldHNubXBfcmVxdWVzdF9saXN0ICpyZXF1ZXN0czsgICAgIC8qIEluZm8gYWJvdXQgb3V0c3RhbmRpbmcgcmVxdWVzdHMgKi8KICAgIG5ldHNubXBfcmVxdWVzdF9saXN0ICpyZXF1ZXN0c0VuZDsgIC8qIHB0ciB0byBlbmQgb2YgbGlzdCAqLwogICAgaW50ICAgICAgICAgICAgICgqaG9va19wcmUpIChuZXRzbm1wX3Nlc3Npb24gKiwgbmV0c25tcF90cmFuc3BvcnQgKiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdm9pZCAqLCBpbnQpOwogICAgaW50ICAgICAgICAgICAgICgqaG9va19wYXJzZSkgKG5ldHNubXBfc2Vzc2lvbiAqLCBuZXRzbm1wX3BkdSAqLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVfY2hhciAqLCBzaXplX3QpOwogICAgaW50ICAgICAgICAgICAgICgqaG9va19wb3N0KSAobmV0c25tcF9zZXNzaW9uICosIG5ldHNubXBfcGR1ICosIGludCk7CiAgICBpbnQgICAgICAgICAgICAgKCpob29rX2J1aWxkKSAobmV0c25tcF9zZXNzaW9uICosIG5ldHNubXBfcGR1ICosCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdV9jaGFyICosIHNpemVfdCAqKTsKICAgIGludCAgICAgICAgICAgICAoKmhvb2tfcmVhbGxvY19idWlsZCkgKG5ldHNubXBfc2Vzc2lvbiAqLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9wZHUgKiwgdV9jaGFyICoqLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZV90ICosIHNpemVfdCAqKTsKICAgIGludCAgICAgICAgICAgICAoKmNoZWNrX3BhY2tldCkgKHVfY2hhciAqLCBzaXplX3QpOwogICAgbmV0c25tcF9wZHUgICAgKigqaG9va19jcmVhdGVfcGR1KSAobmV0c25tcF90cmFuc3BvcnQgKiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZvaWQgKiwgc2l6ZV90KTsKCiAgICB1X2NoYXIgICAgICAgICAqcGFja2V0OwogICAgc2l6ZV90ICAgICAgICAgIHBhY2tldF9sZW4sIHBhY2tldF9zaXplOwp9OwoKLyoKICogVGhlIGxpc3Qgb2YgYWN0aXZlL29wZW4gc2Vzc2lvbnMuCiAqLwpzdHJ1Y3Qgc2Vzc2lvbl9saXN0IHsKICAgIHN0cnVjdCBzZXNzaW9uX2xpc3QgKm5leHQ7CiAgICBuZXRzbm1wX3Nlc3Npb24gKnNlc3Npb247CiAgICBuZXRzbm1wX3RyYW5zcG9ydCAqdHJhbnNwb3J0OwogICAgc3RydWN0IHNubXBfaW50ZXJuYWxfc2Vzc2lvbiAqaW50ZXJuYWw7Cn07CgoKCnN0YXRpYyBjb25zdCBjaGFyICphcGlfZXJyb3JzWy1TTk1QRVJSX01BWCArIDFdID0gewogICAgIk5vIGVycm9yIiwgICAgICAgICAgICAgICAgIC8qIFNOTVBFUlJfU1VDQ0VTUyAqLwogICAgIkdlbmVyaWMgZXJyb3IiLCAgICAgICAgICAgIC8qIFNOTVBFUlJfR0VORVJSICovCiAgICAiSW52YWxpZCBsb2NhbCBwb3J0IiwgICAgICAgLyogU05NUEVSUl9CQURfTE9DUE9SVCAqLwogICAgIlVua25vd24gaG9zdCIsICAgICAgICAgICAgIC8qIFNOTVBFUlJfQkFEX0FERFJFU1MgKi8KICAgICJVbmtub3duIHNlc3Npb24iLCAgICAgICAgICAvKiBTTk1QRVJSX0JBRF9TRVNTSU9OICovCiAgICAiVG9vIGxvbmciLCAgICAgICAgICAgICAgICAgLyogU05NUEVSUl9UT09fTE9ORyAqLwogICAgIk5vIHNvY2tldCIsICAgICAgICAgICAgICAgIC8qIFNOTVBFUlJfTk9fU09DS0VUICovCiAgICAiQ2Fubm90IHNlbmQgVjIgUERVIG9uIFYxIHNlc3Npb24iLCAvKiBTTk1QRVJSX1YyX0lOX1YxICovCiAgICAiQ2Fubm90IHNlbmQgVjEgUERVIG9uIFYyIHNlc3Npb24iLCAvKiBTTk1QRVJSX1YxX0lOX1YyICovCiAgICAiQmFkIHZhbHVlIGZvciBub24tcmVwZWF0ZXJzIiwgICAgICAvKiBTTk1QRVJSX0JBRF9SRVBFQVRFUlMgKi8KICAgICJCYWQgdmFsdWUgZm9yIG1heC1yZXBldGl0aW9ucyIsICAgIC8qIFNOTVBFUlJfQkFEX1JFUEVUSVRJT05TICovCiAgICAiRXJyb3IgYnVpbGRpbmcgQVNOLjEgcmVwcmVzZW50YXRpb24iLCAgICAgIC8qIFNOTVBFUlJfQkFEX0FTTjFfQlVJTEQgKi8KICAgICJGYWlsdXJlIGluIHNlbmR0byIsICAgICAgICAvKiBTTk1QRVJSX0JBRF9TRU5EVE8gKi8KICAgICJCYWQgcGFyc2Ugb2YgQVNOLjEgdHlwZSIsICAvKiBTTk1QRVJSX0JBRF9QQVJTRSAqLwogICAgIkJhZCB2ZXJzaW9uIHNwZWNpZmllZCIsICAgIC8qIFNOTVBFUlJfQkFEX1ZFUlNJT04gKi8KICAgICJCYWQgc291cmNlIHBhcnR5IHNwZWNpZmllZCIsICAgICAgIC8qIFNOTVBFUlJfQkFEX1NSQ19QQVJUWSAqLwogICAgIkJhZCBkZXN0aW5hdGlvbiBwYXJ0eSBzcGVjaWZpZWQiLCAgLyogU05NUEVSUl9CQURfRFNUX1BBUlRZICovCiAgICAiQmFkIGNvbnRleHQgc3BlY2lmaWVkIiwgICAgLyogU05NUEVSUl9CQURfQ09OVEVYVCAqLwogICAgIkJhZCBjb21tdW5pdHkgc3BlY2lmaWVkIiwgIC8qIFNOTVBFUlJfQkFEX0NPTU1VTklUWSAqLwogICAgIkNhbm5vdCBzZW5kIG5vQXV0aC9Qcml2IiwgICAgICAgLyogU05NUEVSUl9OT0FVVEhfREVTUFJJViAqLwogICAgIkJhZCBBQ0wgZGVmaW5pdGlvbiIsICAgICAgIC8qIFNOTVBFUlJfQkFEX0FDTCAqLwogICAgIkJhZCBQYXJ0eSBkZWZpbml0aW9uIiwgICAgIC8qIFNOTVBFUlJfQkFEX1BBUlRZICovCiAgICAiU2Vzc2lvbiBhYm9ydCBmYWlsdXJlIiwgICAgLyogU05NUEVSUl9BQk9SVCAqLwogICAgIlVua25vd24gUERVIHR5cGUiLCAgICAgICAgIC8qIFNOTVBFUlJfVU5LTk9XTl9QRFUgKi8KICAgICJUaW1lb3V0IiwgICAgICAgICAgICAgICAgICAvKiBTTk1QRVJSX1RJTUVPVVQgKi8KICAgICJGYWlsdXJlIGluIHJlY3Zmcm9tIiwgICAgICAvKiBTTk1QRVJSX0JBRF9SRUNWRlJPTSAqLwogICAgIlVuYWJsZSB0byBkZXRlcm1pbmUgY29udGV4dEVuZ2luZUlEIiwgICAgICAvKiBTTk1QRVJSX0JBRF9FTkdfSUQgKi8KICAgICJObyBzZWN1cml0eU5hbWUgc3BlY2lmaWVkIiwgICAgICAgIC8qIFNOTVBFUlJfQkFEX1NFQ19OQU1FICovCiAgICAiVW5hYmxlIHRvIGRldGVybWluZSBzZWN1cml0eUxldmVsIiwgICAgICAgIC8qIFNOTVBFUlJfQkFEX1NFQ19MRVZFTCAgKi8KICAgICJBU04uMSBwYXJzZSBlcnJvciBpbiBtZXNzYWdlIiwgICAgIC8qIFNOTVBFUlJfQVNOX1BBUlNFX0VSUiAqLwogICAgIlVua25vd24gc2VjdXJpdHkgbW9kZWwgaW4gbWVzc2FnZSIsICAgICAgICAvKiBTTk1QRVJSX1VOS05PV05fU0VDX01PREVMICovCiAgICAiSW52YWxpZCBtZXNzYWdlIChlLmcuIG1zZ0ZsYWdzKSIsICAvKiBTTk1QRVJSX0lOVkFMSURfTVNHICovCiAgICAiVW5rbm93biBlbmdpbmUgSUQiLCAgICAgICAgLyogU05NUEVSUl9VTktOT1dOX0VOR19JRCAqLwogICAgIlVua25vd24gdXNlciBuYW1lIiwgICAgICAgIC8qIFNOTVBFUlJfVU5LTk9XTl9VU0VSX05BTUUgKi8KICAgICJVbnN1cHBvcnRlZCBzZWN1cml0eSBsZXZlbCIsICAgICAgIC8qIFNOTVBFUlJfVU5TVVBQT1JURURfU0VDX0xFVkVMICovCiAgICAiQXV0aGVudGljYXRpb24gZmFpbHVyZSAoaW5jb3JyZWN0IHBhc3N3b3JkLCBjb21tdW5pdHkgb3Iga2V5KSIsICAgIC8qIFNOTVBFUlJfQVVUSEVOVElDQVRJT05fRkFJTFVSRSAqLwogICAgIk5vdCBpbiB0aW1lIHdpbmRvdyIsICAgICAgIC8qIFNOTVBFUlJfTk9UX0lOX1RJTUVfV0lORE9XICovCiAgICAiRGVjcnlwdGlvbiBlcnJvciIsICAgICAgICAgLyogU05NUEVSUl9ERUNSWVBUSU9OX0VSUiAqLwogICAgIlNDQVBJIGdlbmVyYWwgZmFpbHVyZSIsICAgIC8qIFNOTVBFUlJfU0NfR0VORVJBTF9GQUlMVVJFICovCiAgICAiU0NBUEkgc3ViLXN5c3RlbSBub3QgY29uZmlndXJlZCIsICAvKiBTTk1QRVJSX1NDX05PVF9DT05GSUdVUkVEICovCiAgICAiS2V5IHRvb2xzIG5vdCBhdmFpbGFibGUiLCAgLyogU05NUEVSUl9LVF9OT1RfQVZBSUxBQkxFICovCiAgICAiVW5rbm93biBSZXBvcnQgbWVzc2FnZSIsICAgLyogU05NUEVSUl9VTktOT1dOX1JFUE9SVCAqLwogICAgIlVTTSBnZW5lcmljIGVycm9yIiwgICAgICAgIC8qIFNOTVBFUlJfVVNNX0dFTkVSSUNFUlJPUiAqLwogICAgIlVTTSB1bmtub3duIHNlY3VyaXR5IG5hbWUgKG5vIHN1Y2ggdXNlciBleGlzdHMpIiwgIC8qIFNOTVBFUlJfVVNNX1VOS05PV05TRUNVUklUWU5BTUUgKi8KICAgICJVU00gdW5zdXBwb3J0ZWQgc2VjdXJpdHkgbGV2ZWwgKHRoaXMgdXNlciBoYXMgbm90IGJlZW4gY29uZmlndXJlZCBmb3IgdGhhdCBsZXZlbCBvZiBzZWN1cml0eSkiLCAgICAvKiBTTk1QRVJSX1VTTV9VTlNVUFBPUlRFRFNFQ1VSSVRZTEVWRUwgKi8KICAgICJVU00gZW5jcnlwdGlvbiBlcnJvciIsICAgICAvKiBTTk1QRVJSX1VTTV9FTkNSWVBUSU9ORVJST1IgKi8KICAgICJVU00gYXV0aGVudGljYXRpb24gZmFpbHVyZSAoaW5jb3JyZWN0IHBhc3N3b3JkIG9yIGtleSkiLCAgIC8qIFNOTVBFUlJfVVNNX0FVVEhFTlRJQ0FUSU9ORkFJTFVSRSAqLwogICAgIlVTTSBwYXJzZSBlcnJvciIsICAgICAgICAgIC8qIFNOTVBFUlJfVVNNX1BBUlNFRVJST1IgKi8KICAgICJVU00gdW5rbm93biBlbmdpbmVJRCIsICAgICAvKiBTTk1QRVJSX1VTTV9VTktOT1dORU5HSU5FSUQgKi8KICAgICJVU00gbm90IGluIHRpbWUgd2luZG93IiwgICAvKiBTTk1QRVJSX1VTTV9OT1RJTlRJTUVXSU5ET1cgKi8KICAgICJVU00gZGVjcnlwdGlvbiBlcnJvciIsICAgICAvKiBTTk1QRVJSX1VTTV9ERUNSWVBUSU9ORVJST1IgKi8KICAgICJNSUIgbm90IGluaXRpYWxpemVkIiwgICAgICAvKiBTTk1QRVJSX05PTUlCICovCiAgICAiVmFsdWUgb3V0IG9mIHJhbmdlIiwgICAgICAgLyogU05NUEVSUl9SQU5HRSAqLwogICAgIlN1Yi1pZCBvdXQgb2YgcmFuZ2UiLCAgICAgIC8qIFNOTVBFUlJfTUFYX1NVQklEICovCiAgICAiQmFkIHN1Yi1pZCBpbiBvYmplY3QgaWRlbnRpZmllciIsICAvKiBTTk1QRVJSX0JBRF9TVUJJRCAqLwogICAgIk9iamVjdCBpZGVudGlmaWVyIHRvbyBsb25nIiwgICAgICAgLyogU05NUEVSUl9MT05HX09JRCAqLwogICAgIkJhZCB2YWx1ZSBuYW1lIiwgICAgICAgICAgIC8qIFNOTVBFUlJfQkFEX05BTUUgKi8KICAgICJCYWQgdmFsdWUgbm90YXRpb24iLCAgICAgICAvKiBTTk1QRVJSX1ZBTFVFICovCiAgICAiVW5rbm93biBPYmplY3QgSWRlbnRpZmllciIsICAgICAgICAvKiBTTk1QRVJSX1VOS05PV05fT0JKSUQgKi8KICAgICJObyBQRFUgaW4gc25tcF9zZW5kIiwgICAgICAvKiBTTk1QRVJSX05VTExfUERVICovCiAgICAiTWlzc2luZyB2YXJpYWJsZXMgaW4gUERVIiwgLyogU05NUEVSUl9OT19WQVJTICovCiAgICAiQmFkIHZhcmlhYmxlIHR5cGUiLCAgICAgICAgLyogU05NUEVSUl9WQVJfVFlQRSAqLwogICAgIk91dCBvZiBtZW1vcnkgKG1hbGxvYyBmYWlsdXJlKSIsICAgLyogU05NUEVSUl9NQUxMT0MgKi8KICAgICJLZXJiZXJvcyByZWxhdGVkIGVycm9yIiwgICAvKiBTTk1QRVJSX0tSQjUgKi8KICAgICJQcm90b2NvbCBlcnJvciIsCQkvKiBTTk1QRVJSX1BST1RPQ09MICovCiAgICAiT0lEIG5vdCBpbmNyZWFzaW5nIiwgICAgICAgLyogU05NUEVSUl9PSURfTk9OSU5DUkVBU0lORyAqLwogICAgIkNvbnRleHQgcHJvYmUiLCAgICAgICAgICAgIC8qIFNOTVBFUlJfSlVTVF9BX0NPTlRFWFRfUFJPQkUgKi8KICAgICJDb25maWd1cmF0aW9uIGRhdGEgZm91bmQgYnV0IHRoZSB0cmFuc3BvcnQgY2FuJ3QgYmUgY29uZmlndXJlZCIsIC8qIFNOTVBFUlJfVFJBTlNQT1JUX05PX0NPTkZJRyAqLwogICAgIlRyYW5zcG9ydCBjb25maWd1cmF0aW9uIGZhaWxlZCIsIC8qIFNOTVBFUlJfVFJBTlNQT1JUX0NPTkZJR19FUlJPUiAqLwp9OwoKc3RhdGljIGNvbnN0IGNoYXIgKnNlY0xldmVsTmFtZVtdID0gewogICAgIkJBRF9TRUNfTEVWRUwiLAogICAgIm5vQXV0aE5vUHJpdiIsCiAgICAiYXV0aE5vUHJpdiIsCiAgICAiYXV0aFByaXYiCn07CgovKgogKiBNdWx0aXBsZSB0aHJlYWRzIG1heSBjaGFuZ2VzIHRoZXNlIHZhcmlhYmxlcy4KICogU3VnZ2VzdCB1c2luZyB0aGUgU2luZ2xlIEFQSSwgd2hpY2ggZG9lcyBub3QgdXNlIFNlc3Npb25zLgogKgogKiBSZXFpZCBtYXkgbmVlZCB0byBiZSBwcm90ZWN0ZWQuIFRpbWUgd2lsbCB0ZWxsLi4uCiAqCiAqLwovKgogKiBNVENSSVRJQ0FMX1JFU09VUkNFCiAqLwovKgogKiB1c2UgdG9rZW4gaW4gY29tbWVudHMgdG8gaW5kaXZpZHVhbGx5IHByb3RlY3QgdGhlc2UgcmVzb3VyY2VzIAogKi8Kc3RydWN0IHNlc3Npb25fbGlzdCAqU2Vzc2lvbnMgPSBOVUxMOyAgIC8qIE1UX0xJQl9TRVNTSU9OICovCnN0YXRpYyBsb25nICAgICBSZXFpZCA9IDA7ICAgICAgLyogTVRfTElCX1JFUVVFU1RJRCAqLwpzdGF0aWMgbG9uZyAgICAgTXNnaWQgPSAwOyAgICAgIC8qIE1UX0xJQl9NRVNTQUdFSUQgKi8Kc3RhdGljIGxvbmcgICAgIFNlc3NpZCA9IDA7ICAgICAvKiBNVF9MSUJfU0VTU0lPTklEICovCnN0YXRpYyBsb25nICAgICBUcmFuc2lkID0gMDsgICAgLyogTVRfTElCX1RSQU5TSUQgKi8KaW50ICAgICAgICAgICAgIHNubXBfZXJybm8gPSAwOwovKgogKiBFTkQgTVRDUklUSUNBTF9SRVNPVVJDRQogKi8KCi8qCiAqIGdsb2JhbCBlcnJvciBkZXRhaWwgc3RvcmFnZQogKi8Kc3RhdGljIGNoYXIgICAgIHNubXBfZGV0YWlsWzE5Ml07CnN0YXRpYyBpbnQgICAgICBzbm1wX2RldGFpbF9mID0gMDsKCi8qCiAqIFByb3RvdHlwZXMuCiAqLwppbnQgICAgICAgICAgICAgc25tcF9idWlsZCh1X2NoYXIgKiogcGt0LCBzaXplX3QgKiBwa3RfbGVuLAogICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplX3QgKiBvZmZzZXQsIG5ldHNubXBfc2Vzc2lvbiAqIHBzcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9wZHUgKnBkdSk7CnN0YXRpYyBpbnQgICAgICBzbm1wX3BhcnNlKHZvaWQgKiwgbmV0c25tcF9zZXNzaW9uICosIG5ldHNubXBfcGR1ICosCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHVfY2hhciAqLCBzaXplX3QpOwoKc3RhdGljIHZvaWQgICAgIHNubXB2M19jYWxjX21zZ19mbGFncyhpbnQsIGludCwgdV9jaGFyICopOwpzdGF0aWMgaW50ICAgICAgc25tcHYzX3ZlcmlmeV9tc2cobmV0c25tcF9yZXF1ZXN0X2xpc3QgKiwgbmV0c25tcF9wZHUgKik7CnN0YXRpYyBpbnQgICAgICBzbm1wdjNfYnVpbGRfcHJvYmVfcGR1KG5ldHNubXBfcGR1ICoqKTsKc3RhdGljIGludCAgICAgIHNubXB2M19idWlsZCh1X2NoYXIgKiogcGt0LCBzaXplX3QgKiBwa3RfbGVuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVfdCAqIG9mZnNldCwgbmV0c25tcF9zZXNzaW9uICogc2Vzc2lvbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX3BkdSAqcGR1KTsKc3RhdGljIGludCAgICAgIHNubXBfcGFyc2VfdmVyc2lvbih1X2NoYXIgKiwgc2l6ZV90KTsKc3RhdGljIGludCAgICAgIHNubXBfcmVzZW5kX3JlcXVlc3Qoc3RydWN0IHNlc3Npb25fbGlzdCAqc2xwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX3JlcXVlc3RfbGlzdCAqcnAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBpbmNyX3JldHJpZXMpOwpzdGF0aWMgdm9pZCAgICAgcmVnaXN0ZXJfZGVmYXVsdF9oYW5kbGVycyh2b2lkKTsKc3RhdGljIHN0cnVjdCBzZXNzaW9uX2xpc3QgKnNubXBfc2Vzc19jb3B5KG5ldHNubXBfc2Vzc2lvbiAqIHBzcyk7CmludCAgICAgICAgICAgICBzbm1wX2dldF9lcnJubyh2b2lkKTsKTkVUU05NUF9JTVBPUlQKdm9pZCAgICAgICAgICAgIHNubXBfc3luY2hfcmVzZXQobmV0c25tcF9zZXNzaW9uICogbm90dXNlZCk7Ck5FVFNOTVBfSU1QT1JUCnZvaWQgICAgICAgICAgICBzbm1wX3N5bmNoX3NldHVwKG5ldHNubXBfc2Vzc2lvbiAqIG5vdHVzZWQpOwoKI2lmbmRlZiBIQVZFX1NUUkVSUk9SCmNvbnN0IGNoYXIgICAgICoKc3RyZXJyb3IoaW50IGVycikKewogICAgZXh0ZXJuIGNvbnN0IGNoYXIgKnN5c19lcnJsaXN0W107CiAgICBleHRlcm4gaW50ICAgICAgc3lzX25lcnI7CgogICAgaWYgKGVyciA8IDAgfHwgZXJyID49IHN5c19uZXJyKQogICAgICAgIHJldHVybiAiVW5rbm93biBlcnJvciI7CiAgICByZXR1cm4gc3lzX2Vycmxpc3RbZXJyXTsKfQojZW5kaWYKCmNvbnN0IGNoYXIgKgpzbm1wX3BkdV90eXBlKGludCB0eXBlKQp7CiAgICBzdGF0aWMgY2hhciB1bmtub3duWzIwXTsKICAgIHN3aXRjaCh0eXBlKSB7CiAgICBjYXNlIFNOTVBfTVNHX0dFVDoKICAgICAgICByZXR1cm4gIkdFVCI7CiAgICBjYXNlIFNOTVBfTVNHX0dFVE5FWFQ6CiAgICAgICAgcmV0dXJuICJHRVRORVhUIjsKICAgIGNhc2UgU05NUF9NU0dfUkVTUE9OU0U6CiAgICAgICAgcmV0dXJuICJSRVNQT05TRSI7CiAgICBjYXNlIFNOTVBfTVNHX1NFVDoKICAgICAgICByZXR1cm4gIlNFVCI7CiAgICBjYXNlIFNOTVBfTVNHX0dFVEJVTEs6CiAgICAgICAgcmV0dXJuICJHRVRCVUxLIjsKICAgIGNhc2UgU05NUF9NU0dfSU5GT1JNOgogICAgICAgIHJldHVybiAiSU5GT1JNIjsKICAgIGNhc2UgU05NUF9NU0dfVFJBUDI6CiAgICAgICAgcmV0dXJuICJUUkFQMiI7CiAgICBjYXNlIFNOTVBfTVNHX1JFUE9SVDoKICAgICAgICByZXR1cm4gIlJFUE9SVCI7CiAgICBkZWZhdWx0OgogICAgICAgIHNucHJpbnRmKHVua25vd24sIHNpemVvZih1bmtub3duKSwgIj8weCUyWD8iLCB0eXBlKTsKCXJldHVybiB1bmtub3duOwogICAgfQp9CgojZGVmaW5lIERFQlVHUFJJTlRQRFVUWVBFKHRva2VuLCB0eXBlKSBcCiAgICBERUJVR0RVTVBTRUNUSU9OKHRva2VuLCBzbm1wX3BkdV90eXBlKHR5cGUpKQoKbG9uZwpzbm1wX2dldF9uZXh0X3JlcWlkKHZvaWQpCnsKICAgIGxvbmcgICAgICAgICAgICByZXRWYWw7CiAgICBzbm1wX3Jlc19sb2NrKE1UX0xJQlJBUllfSUQsIE1UX0xJQl9SRVFVRVNUSUQpOwogICAgcmV0VmFsID0gMSArIFJlcWlkOyAgICAgICAgIC8qTVRDUklUSUNBTF9SRVNPVVJDRSAqLwogICAgaWYgKCFyZXRWYWwpCiAgICAgICAgcmV0VmFsID0gMjsKICAgIFJlcWlkID0gcmV0VmFsOwogICAgaWYgKG5ldHNubXBfZHNfZ2V0X2Jvb2xlYW4oTkVUU05NUF9EU19MSUJSQVJZX0lELCBORVRTTk1QX0RTX0xJQl8xNkJJVF9JRFMpKQogICAgICAgIHJldFZhbCAmPSAweDdmZmY7CS8qIG1hc2sgdG8gMTUgYml0cyAqLwogICAgZWxzZQogICAgICAgIHJldFZhbCAmPSAweDdmZmZmZmZmOwkvKiBtYXNrIHRvIDMxIGJpdHMgKi8KCiAgICBpZiAoIXJldFZhbCkgewogICAgICAgIFJlcWlkID0gcmV0VmFsID0gMjsKICAgIH0KICAgIHNubXBfcmVzX3VubG9jayhNVF9MSUJSQVJZX0lELCBNVF9MSUJfUkVRVUVTVElEKTsKICAgIHJldHVybiByZXRWYWw7Cn0KCmxvbmcKc25tcF9nZXRfbmV4dF9tc2dpZCh2b2lkKQp7CiAgICBsb25nICAgICAgICAgICAgcmV0VmFsOwogICAgc25tcF9yZXNfbG9jayhNVF9MSUJSQVJZX0lELCBNVF9MSUJfTUVTU0FHRUlEKTsKICAgIHJldFZhbCA9IDEgKyBNc2dpZDsgICAgICAgICAvKk1UQ1JJVElDQUxfUkVTT1VSQ0UgKi8KICAgIGlmICghcmV0VmFsKQogICAgICAgIHJldFZhbCA9IDI7CiAgICBNc2dpZCA9IHJldFZhbDsKICAgIGlmIChuZXRzbm1wX2RzX2dldF9ib29sZWFuKE5FVFNOTVBfRFNfTElCUkFSWV9JRCwgTkVUU05NUF9EU19MSUJfMTZCSVRfSURTKSkKICAgICAgICByZXRWYWwgJj0gMHg3ZmZmOwkvKiBtYXNrIHRvIDE1IGJpdHMgKi8KICAgIGVsc2UKICAgICAgICByZXRWYWwgJj0gMHg3ZmZmZmZmZjsJLyogbWFzayB0byAzMSBiaXRzICovCgogICAgaWYgKCFyZXRWYWwpIHsKICAgICAgICBNc2dpZCA9IHJldFZhbCA9IDI7CiAgICB9CiAgICBzbm1wX3Jlc191bmxvY2soTVRfTElCUkFSWV9JRCwgTVRfTElCX01FU1NBR0VJRCk7CiAgICByZXR1cm4gcmV0VmFsOwp9Cgpsb25nCnNubXBfZ2V0X25leHRfc2Vzc2lkKHZvaWQpCnsKICAgIGxvbmcgICAgICAgICAgICByZXRWYWw7CiAgICBzbm1wX3Jlc19sb2NrKE1UX0xJQlJBUllfSUQsIE1UX0xJQl9TRVNTSU9OSUQpOwogICAgcmV0VmFsID0gMSArIFNlc3NpZDsgICAgICAgIC8qTVRDUklUSUNBTF9SRVNPVVJDRSAqLwogICAgaWYgKCFyZXRWYWwpCiAgICAgICAgcmV0VmFsID0gMjsKICAgIFNlc3NpZCA9IHJldFZhbDsKICAgIGlmIChuZXRzbm1wX2RzX2dldF9ib29sZWFuKE5FVFNOTVBfRFNfTElCUkFSWV9JRCwgTkVUU05NUF9EU19MSUJfMTZCSVRfSURTKSkKICAgICAgICByZXRWYWwgJj0gMHg3ZmZmOwkvKiBtYXNrIHRvIDE1IGJpdHMgKi8KICAgIGVsc2UKICAgICAgICByZXRWYWwgJj0gMHg3ZmZmZmZmZjsJLyogbWFzayB0byAzMSBiaXRzICovCgogICAgaWYgKCFyZXRWYWwpIHsKICAgICAgICBTZXNzaWQgPSByZXRWYWwgPSAyOwogICAgfQogICAgc25tcF9yZXNfdW5sb2NrKE1UX0xJQlJBUllfSUQsIE1UX0xJQl9TRVNTSU9OSUQpOwogICAgcmV0dXJuIHJldFZhbDsKfQoKbG9uZwpzbm1wX2dldF9uZXh0X3RyYW5zaWQodm9pZCkKewogICAgbG9uZyAgICAgICAgICAgIHJldFZhbDsKICAgIHNubXBfcmVzX2xvY2soTVRfTElCUkFSWV9JRCwgTVRfTElCX1RSQU5TSUQpOwogICAgcmV0VmFsID0gMSArIFRyYW5zaWQ7ICAgICAgIC8qTVRDUklUSUNBTF9SRVNPVVJDRSAqLwogICAgaWYgKCFyZXRWYWwpCiAgICAgICAgcmV0VmFsID0gMjsKICAgIFRyYW5zaWQgPSByZXRWYWw7CiAgICBpZiAobmV0c25tcF9kc19nZXRfYm9vbGVhbihORVRTTk1QX0RTX0xJQlJBUllfSUQsIE5FVFNOTVBfRFNfTElCXzE2QklUX0lEUykpCiAgICAgICAgcmV0VmFsICY9IDB4N2ZmZjsJLyogbWFzayB0byAxNSBiaXRzICovCiAgICBlbHNlCiAgICAgICAgcmV0VmFsICY9IDB4N2ZmZmZmZmY7CS8qIG1hc2sgdG8gMzEgYml0cyAqLwoKICAgIGlmICghcmV0VmFsKSB7CiAgICAgICAgVHJhbnNpZCA9IHJldFZhbCA9IDI7CiAgICB9CiAgICBzbm1wX3Jlc191bmxvY2soTVRfTElCUkFSWV9JRCwgTVRfTElCX1RSQU5TSUQpOwogICAgcmV0dXJuIHJldFZhbDsKfQoKdm9pZApzbm1wX3BlcnJvcihjb25zdCBjaGFyICpwcm9nX3N0cmluZykKewogICAgY29uc3QgY2hhciAgICAgKnN0cjsKICAgIGludCAgICAgICAgICAgICB4ZXJyOwogICAgeGVyciA9IHNubXBfZXJybm87ICAgICAgICAgIC8qTVRDUklUSUNBTF9SRVNPVVJDRSAqLwogICAgc3RyID0gc25tcF9hcGlfZXJyc3RyaW5nKHhlcnIpOwogICAgc25tcF9sb2coTE9HX0VSUiwgIiVzOiAlc1xuIiwgcHJvZ19zdHJpbmcsIHN0cik7Cn0KCnZvaWQKc25tcF9zZXRfZGV0YWlsKGNvbnN0IGNoYXIgKmRldGFpbF9zdHJpbmcpCnsKICAgIGlmIChkZXRhaWxfc3RyaW5nICE9IE5VTEwpIHsKICAgICAgICBzdHJsY3B5KChjaGFyICopIHNubXBfZGV0YWlsLCBkZXRhaWxfc3RyaW5nLCBzaXplb2Yoc25tcF9kZXRhaWwpKTsKICAgICAgICBzbm1wX2RldGFpbF9mID0gMTsKICAgIH0KfQoKLyoKICogcmV0dXJucyBwb2ludGVyIHRvIHN0YXRpYyBkYXRhIAogKi8KLyoKICogcmVzdWx0cyBub3QgZ3VhcmFudGVlZCBpbiBtdWx0aS10aHJlYWRlZCB1c2UgCiAqLwpjb25zdCBjaGFyICAgICAqCnNubXBfYXBpX2VycnN0cmluZyhpbnQgc25tcF9lcnJudW1iZXIpCnsKICAgIGNvbnN0IGNoYXIgICAgICptc2cgPSAiIjsKICAgIHN0YXRpYyBjaGFyICAgICBtc2dfYnVmW1NQUklOVF9NQVhfTEVOXTsKCiAgICBpZiAoc25tcF9lcnJudW1iZXIgPj0gU05NUEVSUl9NQVggJiYgc25tcF9lcnJudW1iZXIgPD0gU05NUEVSUl9HRU5FUlIpIHsKICAgICAgICBtc2cgPSBhcGlfZXJyb3JzWy1zbm1wX2Vycm51bWJlcl07CiAgICB9IGVsc2UgaWYgKHNubXBfZXJybnVtYmVyICE9IFNOTVBFUlJfU1VDQ0VTUykgewogICAgICAgIG1zZyA9IE5VTEw7CiAgICB9CiAgICBpZiAoIW1zZykgewoJc25wcmludGYobXNnX2J1Ziwgc2l6ZW9mKG1zZ19idWYpLCAiVW5rbm93biBlcnJvcjogJWQiLCBzbm1wX2Vycm51bWJlcik7CiAgICAgICAgbXNnX2J1ZltzaXplb2YobXNnX2J1ZiktMV0gPSAnXDAnOwogICAgfSBlbHNlIGlmIChzbm1wX2RldGFpbF9mKSB7CiAgICAgICAgc25wcmludGYobXNnX2J1Ziwgc2l6ZW9mKG1zZ19idWYpLCAiJXMgKCVzKSIsIG1zZywgc25tcF9kZXRhaWwpOwogICAgICAgIG1zZ19idWZbc2l6ZW9mKG1zZ19idWYpLTFdID0gJ1wwJzsKICAgICAgICBzbm1wX2RldGFpbF9mID0gMDsKICAgIH0gZWxzZSB7CiAgICAgICAgc3RybGNweShtc2dfYnVmLCBtc2csIHNpemVvZihtc2dfYnVmKSk7CiAgICB9CgogICAgcmV0dXJuIChtc2dfYnVmKTsKfQoKLyoKICogc25tcF9lcnJvciAtIHJldHVybiBlcnJvciBkYXRhCiAqIElucHV0cyA6ICBhZGRyZXNzIG9mIGVycm5vLCBhZGRyZXNzIG9mIHNubXBfZXJybm8sIGFkZHJlc3Mgb2Ygc3RyaW5nCiAqIENhbGxlciBtdXN0IGZyZWUgdGhlIHN0cmluZyByZXR1cm5lZCBhZnRlciB1c2UuCiAqLwp2b2lkCnNubXBfZXJyb3IobmV0c25tcF9zZXNzaW9uICogcHNlc3MsCiAgICAgICAgICAgaW50ICpwX2Vycm5vLCBpbnQgKnBfc25tcF9lcnJubywgY2hhciAqKnBfc3RyKQp7CiAgICBjaGFyICAgICAgICAgICAgYnVmW1NQUklOVF9NQVhfTEVOXTsKICAgIGludCAgICAgICAgICAgICBzbm1wX2Vycm51bWJlcjsKCiAgICBpZiAocF9lcnJubykKICAgICAgICAqcF9lcnJubyA9IHBzZXNzLT5zX2Vycm5vOwogICAgaWYgKHBfc25tcF9lcnJubykKICAgICAgICAqcF9zbm1wX2Vycm5vID0gcHNlc3MtPnNfc25tcF9lcnJubzsKICAgIGlmIChwX3N0ciA9PSBOVUxMKQogICAgICAgIHJldHVybjsKCiAgICBzdHJjcHkoYnVmLCAiIik7CiAgICBzbm1wX2Vycm51bWJlciA9IHBzZXNzLT5zX3NubXBfZXJybm87CiAgICBpZiAoc25tcF9lcnJudW1iZXIgPj0gU05NUEVSUl9NQVggJiYgc25tcF9lcnJudW1iZXIgPD0gU05NUEVSUl9HRU5FUlIpIHsKCWlmIChzbm1wX2RldGFpbF9mKSB7CiAgICAgICAgICAgIHNucHJpbnRmKGJ1Ziwgc2l6ZW9mKGJ1ZiksICIlcyAoJXMpIiwgYXBpX2Vycm9yc1stc25tcF9lcnJudW1iZXJdLAoJCSAgICBzbm1wX2RldGFpbCk7CiAgICAgICAgICAgIGJ1ZltzaXplb2YoYnVmKS0xXSA9ICdcMCc7CgkgICAgc25tcF9kZXRhaWxfZiA9IDA7Cgl9CgllbHNlCgkgICAgc3RybGNweShidWYsIGFwaV9lcnJvcnNbLXNubXBfZXJybnVtYmVyXSwgc2l6ZW9mKGJ1ZikpOwogICAgfSBlbHNlIHsKICAgICAgICBpZiAoc25tcF9lcnJudW1iZXIpIHsKICAgICAgICAgICAgc25wcmludGYoYnVmLCBzaXplb2YoYnVmKSwgIlVua25vd24gRXJyb3IgJWQiLCBzbm1wX2Vycm51bWJlcik7CiAgICAgICAgICAgIGJ1ZltzaXplb2YoYnVmKS0xXSA9ICdcMCc7CiAgICAgICAgfQogICAgfQoKICAgIC8qCiAgICAgKiBhcHBlbmQgYSB1c2VmdWwgc3lzdGVtIGVycm5vIGludGVycHJldGF0aW9uLiAKICAgICAqLwogICAgaWYgKHBzZXNzLT5zX2Vycm5vKSB7CiAgICAgICAgY29uc3QgY2hhciogZXJyb3IgPSBzdHJlcnJvcihwc2Vzcy0+c19lcnJubyk7CiAgICAgICAgaWYoZXJyb3IgPT0gTlVMTCkKICAgICAgICAgICAgZXJyb3IgPSAiVW5rbm93biBFcnJvciI7CiAgICAgICAgc25wcmludGYgKCZidWZbc3RybGVuKGJ1ZildLCBzaXplb2YoYnVmKS1zdHJsZW4oYnVmKSwKICAgICAgICAgICAgICAgICAiICglcykiLCBlcnJvcik7CiAgICB9CiAgICBidWZbc2l6ZW9mKGJ1ZiktMV0gPSAnXDAnOwogICAgKnBfc3RyID0gc3RyZHVwKGJ1Zik7Cn0KCi8qCiAqIHNubXBfc2Vzc19lcnJvciAtIHNhbWUgYXMgc25tcF9lcnJvciBmb3Igc2luZ2xlIHNlc3Npb24gQVBJIHVzZS4KICovCnZvaWQKc25tcF9zZXNzX2Vycm9yKHZvaWQgKnNlc3NwLCBpbnQgKnBfZXJybm8sIGludCAqcF9zbm1wX2Vycm5vLCBjaGFyICoqcF9zdHIpCnsKICAgIHN0cnVjdCBzZXNzaW9uX2xpc3QgKnNscCA9IChzdHJ1Y3Qgc2Vzc2lvbl9saXN0ICopIHNlc3NwOwoKICAgIGlmICgoc2xwKSAmJiAoc2xwLT5zZXNzaW9uKSkKICAgICAgICBzbm1wX2Vycm9yKHNscC0+c2Vzc2lvbiwgcF9lcnJubywgcF9zbm1wX2Vycm5vLCBwX3N0cik7Cn0KCi8qCiAqIG5ldHNubXBfc2Vzc19sb2dfZXJyb3IoKTogcHJpbnQgYSBlcnJvciBzdG9yZWQgaW4gYSBzZXNzaW9uIHBvaW50ZXIgCiAqLwp2b2lkCm5ldHNubXBfc2Vzc19sb2dfZXJyb3IoaW50IHByaW9yaXR5LAogICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgKnByb2dfc3RyaW5nLCBuZXRzbm1wX3Nlc3Npb24gKiBzcykKewogICAgY2hhciAgICAgICAgICAgKmVycjsKICAgIHNubXBfZXJyb3Ioc3MsIE5VTEwsIE5VTEwsICZlcnIpOwogICAgc25tcF9sb2cocHJpb3JpdHksICIlczogJXNcbiIsIHByb2dfc3RyaW5nLCBlcnIpOwogICAgU05NUF9GUkVFKGVycik7Cn0KCi8qCiAqIHNubXBfc2Vzc19wZXJyb3IoKTogcHJpbnQgYSBlcnJvciBzdG9yZWQgaW4gYSBzZXNzaW9uIHBvaW50ZXIgCiAqLwp2b2lkCnNubXBfc2Vzc19wZXJyb3IoY29uc3QgY2hhciAqcHJvZ19zdHJpbmcsIG5ldHNubXBfc2Vzc2lvbiAqIHNzKQp7CiAgICBuZXRzbm1wX3Nlc3NfbG9nX2Vycm9yKExPR19FUlIsIHByb2dfc3RyaW5nLCBzcyk7Cn0KCgoKLyoKICogUHJpbW9yZGlhbCBTTk1QIGxpYnJhcnkgaW5pdGlhbGl6YXRpb24uCiAqIEluaXRpYWxpemVzIG11dGV4IGxvY2tzLgogKiBJbnZva2VzIG1pbmltdW0gcmVxdWlyZWQgaW5pdGlhbGl6YXRpb24gZm9yIGRpc3BsYXlpbmcgTUlCIG9iamVjdHMuCiAqIEdldHMgaW5pdGlhbCByZXF1ZXN0IElEIGZvciBhbGwgdHJhbnNhY3Rpb25zLAogKiBhbmQgZmluZHMgd2hpY2ggcG9ydCBTTk1QIG92ZXIgVURQIHVzZXMuCiAqIFNOTVAgb3ZlciBBcHBsZVRhbGsgaXMgbm90IGN1cnJlbnRseSBzdXBwb3J0ZWQuCiAqCiAqIFdhcm5pbmc6IG5vIGRlYnVnIG1lc3NhZ2VzIGhlcmUuCiAqLwpzdGF0aWMgY2hhciBfaW5pdF9zbm1wX2luaXRfZG9uZSA9IDA7CnN0YXRpYyB2b2lkCl9pbml0X3NubXAodm9pZCkKewoKICAgIHN0cnVjdCB0aW1ldmFsICB0djsKICAgIGxvbmcgICAgICAgICAgICB0bXBSZXFpZCwgdG1wTXNnaWQ7CgogICAgaWYgKF9pbml0X3NubXBfaW5pdF9kb25lKQogICAgICAgIHJldHVybjsKICAgIF9pbml0X3NubXBfaW5pdF9kb25lID0gMTsKICAgIFJlcWlkID0gMTsKCiAgICBzbm1wX3Jlc19pbml0KCk7ICAgICAgICAgICAgLyogaW5pdGlhbGl6ZSB0aGUgbXQgbG9ja2luZyBzdHJ1Y3R1cmVzICovCiNpZm5kZWYgTkVUU05NUF9ESVNBQkxFX01JQl9MT0FESU5HCiAgICBuZXRzbm1wX2luaXRfbWliX2ludGVybmFscygpOwojZW5kaWYgLyogTkVUU05NUF9ESVNBQkxFX01JQl9MT0FESU5HICovCiAgICBuZXRzbm1wX3Rkb21haW5faW5pdCgpOwoKICAgIGdldHRpbWVvZmRheSgmdHYsIChzdHJ1Y3QgdGltZXpvbmUgKikgMCk7CiAgICAvKgogICAgICogTm93ID0gdHY7CiAgICAgKi8KCiAgICAvKgogICAgICogZ2V0IHBzZXVkby1yYW5kb20gdmFsdWVzIGZvciByZXF1ZXN0IElEIGFuZCBtZXNzYWdlIElEIAogICAgICovCiNpZmRlZiBTVlI0CiAgICBzcmFuZDQ4KHR2LnR2X3NlYyBeIHR2LnR2X3VzZWMpOwogICAgdG1wUmVxaWQgPSBscmFuZDQ4KCk7CiAgICB0bXBNc2dpZCA9IGxyYW5kNDgoKTsKI2Vsc2UKICAgIHNyYW5kb20odHYudHZfc2VjIF4gdHYudHZfdXNlYyk7CiAgICB0bXBSZXFpZCA9IHJhbmRvbSgpOwogICAgdG1wTXNnaWQgPSByYW5kb20oKTsKI2VuZGlmCgogICAgLyoKICAgICAqIGRvbid0IGFsbG93IHplcm8gdmFsdWUgdG8gcmVwZWF0IGluaXQgCiAgICAgKi8KICAgIGlmICh0bXBSZXFpZCA9PSAwKQogICAgICAgIHRtcFJlcWlkID0gMTsKICAgIGlmICh0bXBNc2dpZCA9PSAwKQogICAgICAgIHRtcE1zZ2lkID0gMTsKICAgIFJlcWlkID0gdG1wUmVxaWQ7CiAgICBNc2dpZCA9IHRtcE1zZ2lkOwoKICAgIG5ldHNubXBfcmVnaXN0ZXJfZGVmYXVsdF9kb21haW4oInNubXAiLCAidWRwIHVkcDYiKTsKICAgIG5ldHNubXBfcmVnaXN0ZXJfZGVmYXVsdF9kb21haW4oInNubXB0cmFwIiwgInVkcCB1ZHA2Iik7CgogICAgbmV0c25tcF9yZWdpc3Rlcl9kZWZhdWx0X3RhcmdldCgic25tcCIsICJ1ZHAiLCAiOjE2MSIpOwogICAgbmV0c25tcF9yZWdpc3Rlcl9kZWZhdWx0X3RhcmdldCgic25tcCIsICJ0Y3AiLCAiOjE2MSIpOwogICAgbmV0c25tcF9yZWdpc3Rlcl9kZWZhdWx0X3RhcmdldCgic25tcCIsICJ1ZHA2IiwgIjoxNjEiKTsKICAgIG5ldHNubXBfcmVnaXN0ZXJfZGVmYXVsdF90YXJnZXQoInNubXAiLCAidGNwNiIsICI6MTYxIik7CiAgICBuZXRzbm1wX3JlZ2lzdGVyX2RlZmF1bHRfdGFyZ2V0KCJzbm1wIiwgImR0bHN1ZHAiLCAiOjEwMTYxIik7CiAgICBuZXRzbm1wX3JlZ2lzdGVyX2RlZmF1bHRfdGFyZ2V0KCJzbm1wIiwgInRsc3RjcCIsICI6MTAxNjEiKTsKICAgIG5ldHNubXBfcmVnaXN0ZXJfZGVmYXVsdF90YXJnZXQoInNubXAiLCAiaXB4IiwgIi8zNjg3OSIpOwoKICAgIG5ldHNubXBfcmVnaXN0ZXJfZGVmYXVsdF90YXJnZXQoInNubXB0cmFwIiwgInVkcCIsICI6MTYyIik7CiAgICBuZXRzbm1wX3JlZ2lzdGVyX2RlZmF1bHRfdGFyZ2V0KCJzbm1wdHJhcCIsICJ0Y3AiLCAiOjE2MiIpOwogICAgbmV0c25tcF9yZWdpc3Rlcl9kZWZhdWx0X3RhcmdldCgic25tcHRyYXAiLCAidWRwNiIsICI6MTYyIik7CiAgICBuZXRzbm1wX3JlZ2lzdGVyX2RlZmF1bHRfdGFyZ2V0KCJzbm1wdHJhcCIsICJ0Y3A2IiwgIjoxNjIiKTsKICAgIG5ldHNubXBfcmVnaXN0ZXJfZGVmYXVsdF90YXJnZXQoInNubXB0cmFwIiwgImR0bHN1ZHAiLCAiOjEwMTYyIik7CiAgICBuZXRzbm1wX3JlZ2lzdGVyX2RlZmF1bHRfdGFyZ2V0KCJzbm1wdHJhcCIsICJ0bHN0Y3AiLCAiOjEwMTYyIik7CiAgICBuZXRzbm1wX3JlZ2lzdGVyX2RlZmF1bHRfdGFyZ2V0KCJzbm1wdHJhcCIsICJpcHgiLCAiLzM2ODgwIik7CgogICAgbmV0c25tcF9kc19zZXRfaW50KE5FVFNOTVBfRFNfTElCUkFSWV9JRCwgCiAgICAgICAgICAgICAgICAgICAgICAgTkVUU05NUF9EU19MSUJfSEVYX09VVFBVVF9MRU5HVEgsIDE2KTsKCiNpZmRlZiBORVRTTk1QX1VTRV9SRVZFUlNFX0FTTkVOQ09ESU5HCiAgICBuZXRzbm1wX2RzX3NldF9ib29sZWFuKE5FVFNOTVBfRFNfTElCUkFSWV9JRCwgCgkJCSAgIE5FVFNOTVBfRFNfTElCX1JFVkVSU0VfRU5DT0RFLAoJCQkgICBORVRTTk1QX0RFRkFVTFRfQVNORU5DT0RJTkdfRElSRUNUSU9OKTsKI2VuZGlmCn0KCi8qCiAqIEluaXRpYWxpemVzIHRoZSBzZXNzaW9uIHN0cnVjdHVyZS4KICogTWF5IHBlcmZvcm0gb25lIHRpbWUgbWluaW1hbCBsaWJyYXJ5IGluaXRpYWxpemF0aW9uLgogKiBObyBNSUIgZmlsZSBwcm9jZXNzaW5nIGlzIGRvbmUgdmlhIHRoaXMgY2FsbC4KICovCnZvaWQKc25tcF9zZXNzX2luaXQobmV0c25tcF9zZXNzaW9uICogc2Vzc2lvbikKewogICAgX2luaXRfc25tcCgpOwoKICAgIC8qCiAgICAgKiBpbml0aWFsaXplIHNlc3Npb24gdG8gZGVmYXVsdCB2YWx1ZXMgCiAgICAgKi8KCiAgICBtZW1zZXQoc2Vzc2lvbiwgMCwgc2l6ZW9mKG5ldHNubXBfc2Vzc2lvbikpOwogICAgc2Vzc2lvbi0+cmVtb3RlX3BvcnQgPSBTTk1QX0RFRkFVTFRfUkVNUE9SVDsKICAgIHNlc3Npb24tPnRpbWVvdXQgPSBTTk1QX0RFRkFVTFRfVElNRU9VVDsKICAgIHNlc3Npb24tPnJldHJpZXMgPSBTTk1QX0RFRkFVTFRfUkVUUklFUzsKICAgIHNlc3Npb24tPnZlcnNpb24gPSBTTk1QX0RFRkFVTFRfVkVSU0lPTjsKICAgIHNlc3Npb24tPnNlY3VyaXR5TW9kZWwgPSBTTk1QX0RFRkFVTFRfU0VDTU9ERUw7CiAgICBzZXNzaW9uLT5yY3ZNc2dNYXhTaXplID0gU05NUF9NQVhfTVNHX1NJWkU7CiAgICBzZXNzaW9uLT5mbGFncyB8PSBTTk1QX0ZMQUdTX0RPTlRfUFJPQkU7Cn0KCgpzdGF0aWMgdm9pZApyZWdpc3Rlcl9kZWZhdWx0X2hhbmRsZXJzKHZvaWQpCnsKICAgIG5ldHNubXBfZHNfcmVnaXN0ZXJfY29uZmlnKEFTTl9CT09MRUFOLCAic25tcCIsICJkdW1wUGFja2V0IiwKCQkgICAgICBORVRTTk1QX0RTX0xJQlJBUllfSUQsIE5FVFNOTVBfRFNfTElCX0RVTVBfUEFDS0VUKTsKICAgIG5ldHNubXBfZHNfcmVnaXN0ZXJfY29uZmlnKEFTTl9CT09MRUFOLCAic25tcCIsICJyZXZlcnNlRW5jb2RlQkVSIiwKCQkgICAgICBORVRTTk1QX0RTX0xJQlJBUllfSUQsIE5FVFNOTVBfRFNfTElCX1JFVkVSU0VfRU5DT0RFKTsKICAgIG5ldHNubXBfZHNfcmVnaXN0ZXJfY29uZmlnKEFTTl9JTlRFR0VSLCAic25tcCIsICJkZWZhdWx0UG9ydCIsCgkJICAgICAgTkVUU05NUF9EU19MSUJSQVJZX0lELCBORVRTTk1QX0RTX0xJQl9ERUZBVUxUX1BPUlQpOwojaWYgIWRlZmluZWQoTkVUU05NUF9ESVNBQkxFX1NOTVBWMSkgfHwgIWRlZmluZWQoTkVUU05NUF9ESVNBQkxFX1NOTVBWMkMpCiAgICBuZXRzbm1wX2RzX3JlZ2lzdGVyX2NvbmZpZyhBU05fT0NURVRfU1RSLCAic25tcCIsICJkZWZDb21tdW5pdHkiLAogICAgICAgICAgICAgICAgICAgICAgTkVUU05NUF9EU19MSUJSQVJZX0lELCBORVRTTk1QX0RTX0xJQl9DT01NVU5JVFkpOwojZW5kaWYKICAgIG5ldHNubXBfZHNfcmVnaXN0ZXJfcHJlbWliKEFTTl9CT09MRUFOLCAic25tcCIsICJub1Rva2VuV2FybmluZ3MiLAogICAgICAgICAgICAgICAgICAgICAgTkVUU05NUF9EU19MSUJSQVJZX0lELCBORVRTTk1QX0RTX0xJQl9OT19UT0tFTl9XQVJOSU5HUyk7CiAgICBuZXRzbm1wX2RzX3JlZ2lzdGVyX2NvbmZpZyhBU05fQk9PTEVBTiwgInNubXAiLCAibm9SYW5nZUNoZWNrIiwKCQkgICAgICBORVRTTk1QX0RTX0xJQlJBUllfSUQsIE5FVFNOTVBfRFNfTElCX0RPTlRfQ0hFQ0tfUkFOR0UpOwogICAgbmV0c25tcF9kc19yZWdpc3Rlcl9wcmVtaWIoQVNOX09DVEVUX1NUUiwgInNubXAiLCAicGVyc2lzdGVudERpciIsCgkgICAgICAgICAgICAgIE5FVFNOTVBfRFNfTElCUkFSWV9JRCwgTkVUU05NUF9EU19MSUJfUEVSU0lTVEVOVF9ESVIpOwogICAgbmV0c25tcF9kc19yZWdpc3Rlcl9jb25maWcoQVNOX09DVEVUX1NUUiwgInNubXAiLCAidGVtcEZpbGVQYXR0ZXJuIiwKCSAgICAgICAgICAgICAgTkVUU05NUF9EU19MSUJSQVJZX0lELCBORVRTTk1QX0RTX0xJQl9URU1QX0ZJTEVfUEFUVEVSTik7CiAgICBuZXRzbm1wX2RzX3JlZ2lzdGVyX2NvbmZpZyhBU05fQk9PTEVBTiwgInNubXAiLCAibm9EaXNwbGF5SGludCIsCgkgICAgICAgICAgICAgIE5FVFNOTVBfRFNfTElCUkFSWV9JRCwgTkVUU05NUF9EU19MSUJfTk9fRElTUExBWV9ISU5UKTsKICAgIG5ldHNubXBfZHNfcmVnaXN0ZXJfY29uZmlnKEFTTl9CT09MRUFOLCAic25tcCIsICIxNmJpdElEcyIsCgkgICAgICAgICAgICAgIE5FVFNOTVBfRFNfTElCUkFSWV9JRCwgTkVUU05NUF9EU19MSUJfMTZCSVRfSURTKTsKICAgIG5ldHNubXBfZHNfcmVnaXN0ZXJfcHJlbWliKEFTTl9PQ1RFVF9TVFIsICJzbm1wIiwgImNsaWVudGFkZHIiLAogICAgICAgICAgICAgICAgICAgICAgTkVUU05NUF9EU19MSUJSQVJZX0lELCBORVRTTk1QX0RTX0xJQl9DTElFTlRfQUREUik7CiAgICBuZXRzbm1wX2RzX3JlZ2lzdGVyX2NvbmZpZyhBU05fSU5URUdFUiwgInNubXAiLCAic2VydmVyU2VuZEJ1ZiIsCgkJICAgICAgTkVUU05NUF9EU19MSUJSQVJZX0lELCBORVRTTk1QX0RTX0xJQl9TRVJWRVJTRU5EQlVGKTsKICAgIG5ldHNubXBfZHNfcmVnaXN0ZXJfY29uZmlnKEFTTl9JTlRFR0VSLCAic25tcCIsICJzZXJ2ZXJSZWN2QnVmIiwKCQkgICAgICBORVRTTk1QX0RTX0xJQlJBUllfSUQsIE5FVFNOTVBfRFNfTElCX1NFUlZFUlJFQ1ZCVUYpOwogICAgbmV0c25tcF9kc19yZWdpc3Rlcl9jb25maWcoQVNOX0lOVEVHRVIsICJzbm1wIiwgImNsaWVudFNlbmRCdWYiLAoJCSAgICAgIE5FVFNOTVBfRFNfTElCUkFSWV9JRCwgTkVUU05NUF9EU19MSUJfQ0xJRU5UU0VOREJVRik7CiAgICBuZXRzbm1wX2RzX3JlZ2lzdGVyX2NvbmZpZyhBU05fSU5URUdFUiwgInNubXAiLCAiY2xpZW50UmVjdkJ1ZiIsCgkJICAgICAgTkVUU05NUF9EU19MSUJSQVJZX0lELCBORVRTTk1QX0RTX0xJQl9DTElFTlRSRUNWQlVGKTsKICAgIG5ldHNubXBfZHNfcmVnaXN0ZXJfY29uZmlnKEFTTl9CT09MRUFOLCAic25tcCIsICJub1BlcnNpc3RlbnRMb2FkIiwKCQkgICAgICBORVRTTk1QX0RTX0xJQlJBUllfSUQsIE5FVFNOTVBfRFNfTElCX0RJU0FCTEVfUEVSU0lTVEVOVF9MT0FEKTsKICAgIG5ldHNubXBfZHNfcmVnaXN0ZXJfY29uZmlnKEFTTl9CT09MRUFOLCAic25tcCIsICJub1BlcnNpc3RlbnRTYXZlIiwKCQkgICAgICBORVRTTk1QX0RTX0xJQlJBUllfSUQsIE5FVFNOTVBfRFNfTElCX0RJU0FCTEVfUEVSU0lTVEVOVF9TQVZFKTsKICAgIG5ldHNubXBfZHNfcmVnaXN0ZXJfY29uZmlnKEFTTl9CT09MRUFOLCAic25tcCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAibm9Db250ZXh0RW5naW5lSUREaXNjb3ZlcnkiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTkVUU05NUF9EU19MSUJSQVJZX0lELAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTkVUU05NUF9EU19MSUJfTk9fRElTQ09WRVJZKTsKCiAgICBuZXRzbm1wX3JlZ2lzdGVyX3NlcnZpY2VfaGFuZGxlcnMoKTsKfQoKc3RhdGljIGludCBpbml0X3NubXBfaW5pdF9kb25lID0gMDsgLyogVG8gcHJldmVudCBkb3VibGUgaW5pdCdzLiAqLwovKioKICogQ2FsbHMgdGhlIGZ1bmN0aW9ucyB0byBkbyBjb25maWcgZmlsZSBsb2FkaW5nIGFuZCAgbWliIG1vZHVsZSBwYXJzaW5nCiAqIGluIHRoZSBjb3JyZWN0IG9yZGVyLgogKgogKiBAcGFyYW0gdHlwZSBsYWJlbCBmb3IgdGhlIGNvbmZpZyBmaWxlICJ0eXBlIgogKgogKiBAcmV0dXJuIHZvaWQKICoKICogQHNlZSBpbml0X2FnZW50CiAqLwp2b2lkCmluaXRfc25tcChjb25zdCBjaGFyICp0eXBlKQp7CiAgICBpZiAoaW5pdF9zbm1wX2luaXRfZG9uZSkgewogICAgICAgIHJldHVybjsKICAgIH0KCiAgICBpbml0X3NubXBfaW5pdF9kb25lID0gMTsKCiAgICAvKgogICAgICogbWFrZSB0aGUgdHlwZSBhdmFpbGFibGUgZXZlcnl3aGVyZSBlbHNlIAogICAgICovCiAgICBpZiAodHlwZSAmJiAhbmV0c25tcF9kc19nZXRfc3RyaW5nKE5FVFNOTVBfRFNfTElCUkFSWV9JRCwgCgkJCQkgICAgICAgTkVUU05NUF9EU19MSUJfQVBQVFlQRSkpIHsKICAgICAgICBuZXRzbm1wX2RzX3NldF9zdHJpbmcoTkVUU05NUF9EU19MSUJSQVJZX0lELCAKCQkJICAgICAgTkVUU05NUF9EU19MSUJfQVBQVFlQRSwgdHlwZSk7CiAgICB9CgogICAgX2luaXRfc25tcCgpOwoKICAgIC8qCiAgICAgKiBzZXQgb3VyIGN1cnJlbnQgbG9jYWxlIHByb3Blcmx5IHRvIGluaXRpYWxpemUgaXNwcmludCgpIHR5cGUgZnVuY3Rpb25zIAogICAgICovCiNpZmRlZiBIQVZFX1NFVExPQ0FMRQogICAgc2V0bG9jYWxlKExDX0NUWVBFLCAiIik7CiNlbmRpZgoKICAgIHNubXBfZGVidWdfaW5pdCgpOyAgICAvKiBzaG91bGQgYmUgZG9uZSBmaXJzdCwgdG8gdHVybiBvbiBkZWJ1Z2dpbmcgQVNBUCAqLwogICAgbmV0c25tcF9jb250YWluZXJfaW5pdF9saXN0KCk7CiAgICBpbml0X2NhbGxiYWNrcygpOwogICAgaW5pdF9zbm1wX2xvZ2dpbmcoKTsKICAgIHNubXBfaW5pdF9zdGF0aXN0aWNzKCk7CiAgICByZWdpc3Rlcl9taWJfaGFuZGxlcnMoKTsKICAgIHJlZ2lzdGVyX2RlZmF1bHRfaGFuZGxlcnMoKTsKICAgIGluaXRfc25tcF90cmFuc3BvcnQoKTsKICAgIGluaXRfc25tcHYzKHR5cGUpOwogICAgaW5pdF9zbm1wX2FsYXJtKCk7CiAgICBpbml0X3NubXBfZW51bSh0eXBlKTsKICAgIGluaXRfdmFjbSgpOwojaWYgZGVmaW5lZChORVRTTk1QX1VTRV9PUEVOU1NMKSAmJiBkZWZpbmVkKEhBVkVfTElCU1NMKQogICAgbmV0c25tcF9jZXJ0c19pbml0KCk7CiNlbmRpZgoKICAgIHJlYWRfcHJlbWliX2NvbmZpZ3MoKTsKI2lmbmRlZiBORVRTTk1QX0RJU0FCTEVfTUlCX0xPQURJTkcKICAgIG5ldHNubXBfaW5pdF9taWIoKTsKI2VuZGlmIC8qIE5FVFNOTVBfRElTQUJMRV9NSUJfTE9BRElORyAqLwoKICAgIHJlYWRfY29uZmlncygpOwoKfSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBlbmQgaW5pdF9zbm1wKCkgKi8KCi8qKgogKiBzZXQgYSBmbGFnIGluZGljYXRpbmcgdGhhdCB0aGUgcGVyc2lzdGVudCBzdG9yZSBuZWVkcyB0byBiZSBzYXZlZC4KICovCnZvaWQKc25tcF9zdG9yZV9uZWVkZWQoY29uc3QgY2hhciAqdHlwZSkKewogICAgREVCVUdNU0dUTCgoInNubXBfc3RvcmUiLCAic2V0dGluZyBuZWVkZWQgZmxhZy4uLlxuIikpOwogICAgX3NubXBfc3RvcmVfbmVlZGVkID0gMTsKfQoKdm9pZApzbm1wX3N0b3JlX2lmX25lZWRlZCh2b2lkKQp7CiAgICBpZiAoMCA9PSBfc25tcF9zdG9yZV9uZWVkZWQpCiAgICAgICAgcmV0dXJuOwogICAgCiAgICBERUJVR01TR1RMKCgic25tcF9zdG9yZSIsICJzdG9yZSBuZWVkZWQuLi5cbiIpKTsKICAgIHNubXBfc3RvcmUobmV0c25tcF9kc19nZXRfc3RyaW5nKE5FVFNOTVBfRFNfTElCUkFSWV9JRCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBORVRTTk1QX0RTX0xJQl9BUFBUWVBFKSk7CiAgICBfc25tcF9zdG9yZV9uZWVkZWQgPSAwOwp9Cgp2b2lkCnNubXBfc3RvcmUoY29uc3QgY2hhciAqdHlwZSkKewogICAgREVCVUdNU0dUTCgoInNubXBfc3RvcmUiLCAic3RvcmluZyBzdHVmZi4uLlxuIikpOwogICAgc25tcF9zYXZlX3BlcnNpc3RlbnQodHlwZSk7CiAgICBzbm1wX2NhbGxfY2FsbGJhY2tzKFNOTVBfQ0FMTEJBQ0tfTElCUkFSWSwgU05NUF9DQUxMQkFDS19TVE9SRV9EQVRBLCBOVUxMKTsKICAgIHNubXBfY2xlYW5fcGVyc2lzdGVudCh0eXBlKTsKfQoKCi8qKgogKiBTaHV0cyBkb3duIHRoZSBhcHBsaWNhdGlvbiwgc2F2aW5nIGFueSBuZWVkZWQgcGVyc2lzdGVudCBzdG9yYWdlLAogKiBhbmQgYXBwcm9wcmlhdGUgY2xlYW4gdXAuCiAqIAogKiBAcGFyYW0gdHlwZSBMYWJlbCBmb3IgdGhlIGNvbmZpZyBmaWxlICJ0eXBlIiB1c2VkCiAqCiAqIEByZXR1cm4gdm9pZAogKi8Kdm9pZApzbm1wX3NodXRkb3duKGNvbnN0IGNoYXIgKnR5cGUpCnsKICAgIHNubXBfc3RvcmUodHlwZSk7CiAgICBzbm1wX2NhbGxfY2FsbGJhY2tzKFNOTVBfQ0FMTEJBQ0tfTElCUkFSWSwgU05NUF9DQUxMQkFDS19TSFVURE9XTiwgTlVMTCk7CiAgICBzaHV0ZG93bl9zbm1wX2xvZ2dpbmcoKTsKICAgIHNubXBfYWxhcm1fdW5yZWdpc3Rlcl9hbGwoKTsKICAgIHNubXBfY2xvc2Vfc2Vzc2lvbnMoKTsKI2lmbmRlZiBORVRTTk1QX0RJU0FCTEVfTUlCX0xPQURJTkcKICAgIHNodXRkb3duX21pYigpOwojZW5kaWYgLyogTkVUU05NUF9ESVNBQkxFX01JQl9MT0FESU5HICovCiAgICB1bnJlZ2lzdGVyX2FsbF9jb25maWdfaGFuZGxlcnMoKTsKICAgIG5ldHNubXBfY29udGFpbmVyX2ZyZWVfbGlzdCgpOwogICAgY2xlYXJfc2VjX21vZCgpOwogICAgY2xlYXJfc25tcF9lbnVtKCk7CiAgICBuZXRzbm1wX2NsZWFyX3Rkb21haW5fbGlzdCgpOwogICAgY2xlYXJfY2FsbGJhY2soKTsKICAgIG5ldHNubXBfZHNfc2h1dGRvd24oKTsKICAgIGNsZWFyX3VzZXJfbGlzdCgpOwogICAgbmV0c25tcF9jbGVhcl9kZWZhdWx0X3RhcmdldCgpOwogICAgbmV0c25tcF9jbGVhcl9kZWZhdWx0X2RvbWFpbigpOwogICAgZnJlZV9ldGltZWxpc3QoKTsKCiAgICBpbml0X3NubXBfaW5pdF9kb25lICA9IDA7CiAgICBfaW5pdF9zbm1wX2luaXRfZG9uZSA9IDA7Cn0KCgovKgogKiBTZXRzIHVwIHRoZSBzZXNzaW9uIHdpdGggdGhlIHNubXBfc2Vzc2lvbiBpbmZvcm1hdGlvbiBwcm92aWRlZCBieSB0aGUgdXNlci4KICogVGhlbiBvcGVucyBhbmQgYmluZHMgdGhlIG5lY2Vzc2FyeSBsb3ctbGV2ZWwgdHJhbnNwb3J0LiAgQSBoYW5kbGUgdG8gdGhlCiAqIGNyZWF0ZWQgc2Vzc2lvbiBpcyByZXR1cm5lZCAodGhpcyBpcyBOT1QgdGhlIHNhbWUgYXMgdGhlIHBvaW50ZXIgcGFzc2VkIHRvCiAqIHNubXBfb3BlbigpKS4gIE9uIGFueSBlcnJvciwgTlVMTCBpcyByZXR1cm5lZCBhbmQgc25tcF9lcnJubyBpcyBzZXQgdG8gdGhlCiAqIGFwcHJvcHJpYXRlIGVycm9yIGNvZGUuCiAqLwpuZXRzbm1wX3Nlc3Npb24gKgpzbm1wX29wZW4obmV0c25tcF9zZXNzaW9uICpzZXNzaW9uKQp7CiAgICBzdHJ1Y3Qgc2Vzc2lvbl9saXN0ICpzbHA7CiAgICBzbHAgPSAoc3RydWN0IHNlc3Npb25fbGlzdCAqKSBzbm1wX3Nlc3Nfb3BlbihzZXNzaW9uKTsKICAgIGlmICghc2xwKSB7CiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICB9CgogICAgc25tcF9yZXNfbG9jayhNVF9MSUJSQVJZX0lELCBNVF9MSUJfU0VTU0lPTik7CiAgICBzbHAtPm5leHQgPSBTZXNzaW9uczsKICAgIFNlc3Npb25zID0gc2xwOwogICAgc25tcF9yZXNfdW5sb2NrKE1UX0xJQlJBUllfSUQsIE1UX0xJQl9TRVNTSU9OKTsKCiAgICByZXR1cm4gKHNscC0+c2Vzc2lvbik7Cn0KCi8qCiAqIGV4dGVuZGVkIG9wZW4gCiAqLwpuZXRzbm1wX3Nlc3Npb24gKgpzbm1wX29wZW5fZXgobmV0c25tcF9zZXNzaW9uICpzZXNzaW9uLAogICAgICAgICAgICAgaW50ICgqZnByZV9wYXJzZSkJKG5ldHNubXBfc2Vzc2lvbiAqLCBuZXRzbm1wX3RyYW5zcG9ydCAqLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZvaWQgKiwgaW50KSwKICAgICAgICAgICAgIGludCAoKmZwYXJzZSkJKG5ldHNubXBfc2Vzc2lvbiAqLCBuZXRzbm1wX3BkdSAqLCB1X2NoYXIgKiwKCQkJCSBzaXplX3QpLAoJICAgICBpbnQgKCpmcG9zdF9wYXJzZSkJKG5ldHNubXBfc2Vzc2lvbiAqLCBuZXRzbm1wX3BkdSAqLCBpbnQpLAoKICAgICAgICAgICAgIGludCAoKmZidWlsZCkJKG5ldHNubXBfc2Vzc2lvbiAqLCBuZXRzbm1wX3BkdSAqLCB1X2NoYXIgKiwKCQkJCSBzaXplX3QgKiksCgkgICAgIGludCAoKmZyYnVpbGQpCShuZXRzbm1wX3Nlc3Npb24gKiwgbmV0c25tcF9wZHUgKiwKCQkJCSB1X2NoYXIgKiosIHNpemVfdCAqLCBzaXplX3QgKiksCiAgICAgICAgICAgICBpbnQgKCpmY2hlY2spCSh1X2NoYXIgKiwgc2l6ZV90KQoJICAgICApCnsKICAgIHN0cnVjdCBzZXNzaW9uX2xpc3QgKnNscDsKICAgIHNscCA9IChzdHJ1Y3Qgc2Vzc2lvbl9saXN0ICopIHNubXBfc2Vzc19vcGVuKHNlc3Npb24pOwogICAgaWYgKCFzbHApIHsKICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0KICAgIHNscC0+aW50ZXJuYWwtPmhvb2tfcHJlID0gZnByZV9wYXJzZTsKICAgIHNscC0+aW50ZXJuYWwtPmhvb2tfcGFyc2UgPSBmcGFyc2U7CiAgICBzbHAtPmludGVybmFsLT5ob29rX3Bvc3QgPSBmcG9zdF9wYXJzZTsKICAgIHNscC0+aW50ZXJuYWwtPmhvb2tfYnVpbGQgPSBmYnVpbGQ7CiAgICBzbHAtPmludGVybmFsLT5ob29rX3JlYWxsb2NfYnVpbGQgPSBmcmJ1aWxkOwogICAgc2xwLT5pbnRlcm5hbC0+Y2hlY2tfcGFja2V0ID0gZmNoZWNrOwoKICAgIHNubXBfcmVzX2xvY2soTVRfTElCUkFSWV9JRCwgTVRfTElCX1NFU1NJT04pOwogICAgc2xwLT5uZXh0ID0gU2Vzc2lvbnM7CiAgICBTZXNzaW9ucyA9IHNscDsKICAgIHNubXBfcmVzX3VubG9jayhNVF9MSUJSQVJZX0lELCBNVF9MSUJfU0VTU0lPTik7CgogICAgcmV0dXJuIChzbHAtPnNlc3Npb24pOwp9CgpzdGF0aWMgc3RydWN0IHNlc3Npb25fbGlzdCAqCl9zZXNzX2NvcHkobmV0c25tcF9zZXNzaW9uICogaW5fc2Vzc2lvbikKewogICAgc3RydWN0IHNlc3Npb25fbGlzdCAqc2xwOwogICAgc3RydWN0IHNubXBfaW50ZXJuYWxfc2Vzc2lvbiAqaXNwOwogICAgbmV0c25tcF9zZXNzaW9uICpzZXNzaW9uOwogICAgc3RydWN0IHNubXBfc2VjbW9kX2RlZiAqc3B0cjsKICAgIGNoYXIgICAgICAgICAgICpjcDsKICAgIHVfY2hhciAgICAgICAgICp1Y3A7CgogICAgaW5fc2Vzc2lvbi0+c19zbm1wX2Vycm5vID0gMDsKICAgIGluX3Nlc3Npb24tPnNfZXJybm8gPSAwOwoKICAgIC8qCiAgICAgKiBDb3B5IHNlc3Npb24gc3RydWN0dXJlIGFuZCBsaW5rIGludG8gbGlzdCAKICAgICAqLwogICAgc2xwID0gKHN0cnVjdCBzZXNzaW9uX2xpc3QgKikgY2FsbG9jKDEsIHNpemVvZihzdHJ1Y3Qgc2Vzc2lvbl9saXN0KSk7CiAgICBpZiAoc2xwID09IE5VTEwpIHsKICAgICAgICBpbl9zZXNzaW9uLT5zX3NubXBfZXJybm8gPSBTTk1QRVJSX01BTExPQzsKICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgfQoKICAgIHNscC0+dHJhbnNwb3J0ID0gTlVMTDsKCiAgICBpc3AgPSAoc3RydWN0IHNubXBfaW50ZXJuYWxfc2Vzc2lvbiAqKWNhbGxvYygxLCBzaXplb2Yoc3RydWN0IHNubXBfaW50ZXJuYWxfc2Vzc2lvbikpOwoKICAgIGlmIChpc3AgPT0gTlVMTCkgewogICAgICAgIHNubXBfc2Vzc19jbG9zZShzbHApOwogICAgICAgIGluX3Nlc3Npb24tPnNfc25tcF9lcnJubyA9IFNOTVBFUlJfTUFMTE9DOwogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICB9CgogICAgc2xwLT5pbnRlcm5hbCA9IGlzcDsKICAgIHNscC0+c2Vzc2lvbiA9IChuZXRzbm1wX3Nlc3Npb24gKiltYWxsb2Moc2l6ZW9mKG5ldHNubXBfc2Vzc2lvbikpOwogICAgaWYgKHNscC0+c2Vzc2lvbiA9PSBOVUxMKSB7CiAgICAgICAgc25tcF9zZXNzX2Nsb3NlKHNscCk7CiAgICAgICAgaW5fc2Vzc2lvbi0+c19zbm1wX2Vycm5vID0gU05NUEVSUl9NQUxMT0M7CiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIH0KICAgIG1lbW1vdmUoc2xwLT5zZXNzaW9uLCBpbl9zZXNzaW9uLCBzaXplb2YobmV0c25tcF9zZXNzaW9uKSk7CiAgICBzZXNzaW9uID0gc2xwLT5zZXNzaW9uOwoKICAgIC8qCiAgICAgKiB6ZXJvIG91dCBwb2ludGVycyBzbyBpZiB3ZSBoYXZlIHRvIGZyZWUgdGhlIHNlc3Npb24gd2Ugd29udCBmcmVlIG1lbQogICAgICogb3duZWQgYnkgaW5fc2Vzc2lvbiAKICAgICAqLwogICAgc2Vzc2lvbi0+bG9jYWxuYW1lID0gTlVMTDsKICAgIHNlc3Npb24tPnBlZXJuYW1lID0gTlVMTDsKICAgIHNlc3Npb24tPmNvbW11bml0eSA9IE5VTEw7CiAgICBzZXNzaW9uLT5jb250ZXh0RW5naW5lSUQgPSBOVUxMOwogICAgc2Vzc2lvbi0+Y29udGV4dE5hbWUgPSBOVUxMOwogICAgc2Vzc2lvbi0+c2VjdXJpdHlFbmdpbmVJRCA9IE5VTEw7CiAgICBzZXNzaW9uLT5zZWN1cml0eU5hbWUgPSBOVUxMOwogICAgc2Vzc2lvbi0+c2VjdXJpdHlBdXRoUHJvdG8gPSBOVUxMOwogICAgc2Vzc2lvbi0+c2VjdXJpdHlQcml2UHJvdG8gPSBOVUxMOwogICAgLyoKICAgICAqIHNlc3Npb24gbm93IHBvaW50cyB0byB0aGUgbmV3IHN0cnVjdHVyZSB0aGF0IHN0aWxsIGNvbnRhaW5zIHBvaW50ZXJzIHRvCiAgICAgKiBkYXRhIGFsbG9jYXRlZCBlbHNld2hlcmUuICBTb21lIG9mIHRoaXMgZGF0YSBpcyBjb3BpZWQgdG8gc3BhY2UgbWFsbG9jJ2QKICAgICAqIGhlcmUsIGFuZCB0aGUgcG9pbnRlciByZXBsYWNlZCB3aXRoIHRoZSBuZXcgb25lLgogICAgICovCgogICAgaWYgKGluX3Nlc3Npb24tPnBlZXJuYW1lICE9IE5VTEwpIHsKICAgICAgICBzZXNzaW9uLT5wZWVybmFtZSA9IChjaGFyICopbWFsbG9jKHN0cmxlbihpbl9zZXNzaW9uLT5wZWVybmFtZSkgKyAxKTsKICAgICAgICBpZiAoc2Vzc2lvbi0+cGVlcm5hbWUgPT0gTlVMTCkgewogICAgICAgICAgICBzbm1wX3Nlc3NfY2xvc2Uoc2xwKTsKICAgICAgICAgICAgaW5fc2Vzc2lvbi0+c19zbm1wX2Vycm5vID0gU05NUEVSUl9NQUxMT0M7CiAgICAgICAgICAgIHJldHVybiAoTlVMTCk7CiAgICAgICAgfQogICAgICAgIHN0cmNweShzZXNzaW9uLT5wZWVybmFtZSwgaW5fc2Vzc2lvbi0+cGVlcm5hbWUpOwogICAgfQoKICAgIC8qCiAgICAgKiBGaWxsIGluIGRlZmF1bHRzIGlmIG5lY2Vzc2FyeSAKICAgICAqLwojaWYgIWRlZmluZWQoTkVUU05NUF9ESVNBQkxFX1NOTVBWMSkgfHwgIWRlZmluZWQoTkVUU05NUF9ESVNBQkxFX1NOTVBWMkMpCiAgICBpZiAoaW5fc2Vzc2lvbi0+Y29tbXVuaXR5X2xlbiAhPSBTTk1QX0RFRkFVTFRfQ09NTVVOSVRZX0xFTikgewogICAgICAgIHVjcCA9ICh1X2NoYXIgKikgbWFsbG9jKGluX3Nlc3Npb24tPmNvbW11bml0eV9sZW4pOwogICAgICAgIGlmICh1Y3AgIT0gTlVMTCkKICAgICAgICAgICAgbWVtbW92ZSh1Y3AsIGluX3Nlc3Npb24tPmNvbW11bml0eSwgaW5fc2Vzc2lvbi0+Y29tbXVuaXR5X2xlbik7CiAgICB9IGVsc2UgewogICAgICAgIGlmICgoY3AgPSBuZXRzbm1wX2RzX2dldF9zdHJpbmcoTkVUU05NUF9EU19MSUJSQVJZX0lELCAKCQkJCQlORVRTTk1QX0RTX0xJQl9DT01NVU5JVFkpKSAhPSBOVUxMKSB7CiAgICAgICAgICAgIHNlc3Npb24tPmNvbW11bml0eV9sZW4gPSBzdHJsZW4oY3ApOwogICAgICAgICAgICB1Y3AgPSAodV9jaGFyICopIG1hbGxvYyhzZXNzaW9uLT5jb21tdW5pdHlfbGVuKTsKICAgICAgICAgICAgaWYgKHVjcCkKICAgICAgICAgICAgICAgIG1lbW1vdmUodWNwLCBjcCwgc2Vzc2lvbi0+Y29tbXVuaXR5X2xlbik7CiAgICAgICAgfSBlbHNlIHsKI2lmZGVmIE5FVFNOTVBfTk9fWkVST0xFTkdUSF9DT01NVU5JVFkKICAgICAgICAgICAgc2Vzc2lvbi0+Y29tbXVuaXR5X2xlbiA9IHN0cmxlbihERUZBVUxUX0NPTU1VTklUWSk7CiAgICAgICAgICAgIHVjcCA9ICh1X2NoYXIgKikgbWFsbG9jKHNlc3Npb24tPmNvbW11bml0eV9sZW4pOwogICAgICAgICAgICBpZiAodWNwKQogICAgICAgICAgICAgICAgbWVtbW92ZSh1Y3AsIERFRkFVTFRfQ09NTVVOSVRZLCBzZXNzaW9uLT5jb21tdW5pdHlfbGVuKTsKI2Vsc2UKICAgICAgICAgICAgdWNwID0gKHVfY2hhciAqKSBzdHJkdXAoIiIpOwojZW5kaWYKICAgICAgICB9CiAgICB9CgogICAgaWYgKHVjcCA9PSBOVUxMKSB7CiAgICAgICAgc25tcF9zZXNzX2Nsb3NlKHNscCk7CiAgICAgICAgaW5fc2Vzc2lvbi0+c19zbm1wX2Vycm5vID0gU05NUEVSUl9NQUxMT0M7CiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIH0KICAgIHNlc3Npb24tPmNvbW11bml0eSA9IHVjcDsgICAvKiByZXBsYWNlIHBvaW50ZXIgd2l0aCBwb2ludGVyIHRvIG5ldyBkYXRhICovCiNlbmRpZgoKICAgIGlmIChzZXNzaW9uLT5zZWN1cml0eUxldmVsIDw9IDApIHsKICAgICAgICBzZXNzaW9uLT5zZWN1cml0eUxldmVsID0KICAgICAgICAgICAgbmV0c25tcF9kc19nZXRfaW50KE5FVFNOTVBfRFNfTElCUkFSWV9JRCwgTkVUU05NUF9EU19MSUJfU0VDTEVWRUwpOwogICAgfQoKICAgIGlmIChpbl9zZXNzaW9uLT5zZWN1cml0eUVuZ2luZUlETGVuID4gMCkgewogICAgICAgIHVjcCA9ICh1X2NoYXIgKikgbWFsbG9jKGluX3Nlc3Npb24tPnNlY3VyaXR5RW5naW5lSURMZW4pOwogICAgICAgIGlmICh1Y3AgPT0gTlVMTCkgewogICAgICAgICAgICBzbm1wX3Nlc3NfY2xvc2Uoc2xwKTsKICAgICAgICAgICAgaW5fc2Vzc2lvbi0+c19zbm1wX2Vycm5vID0gU05NUEVSUl9NQUxMT0M7CiAgICAgICAgICAgIHJldHVybiAoTlVMTCk7CiAgICAgICAgfQogICAgICAgIG1lbW1vdmUodWNwLCBpbl9zZXNzaW9uLT5zZWN1cml0eUVuZ2luZUlELAogICAgICAgICAgICAgICAgaW5fc2Vzc2lvbi0+c2VjdXJpdHlFbmdpbmVJRExlbik7CiAgICAgICAgc2Vzc2lvbi0+c2VjdXJpdHlFbmdpbmVJRCA9IHVjcDsKCiAgICB9CgogICAgaWYgKGluX3Nlc3Npb24tPmNvbnRleHRFbmdpbmVJRExlbiA+IDApIHsKICAgICAgICB1Y3AgPSAodV9jaGFyICopIG1hbGxvYyhpbl9zZXNzaW9uLT5jb250ZXh0RW5naW5lSURMZW4pOwogICAgICAgIGlmICh1Y3AgPT0gTlVMTCkgewogICAgICAgICAgICBzbm1wX3Nlc3NfY2xvc2Uoc2xwKTsKICAgICAgICAgICAgaW5fc2Vzc2lvbi0+c19zbm1wX2Vycm5vID0gU05NUEVSUl9NQUxMT0M7CiAgICAgICAgICAgIHJldHVybiAoTlVMTCk7CiAgICAgICAgfQogICAgICAgIG1lbW1vdmUodWNwLCBpbl9zZXNzaW9uLT5jb250ZXh0RW5naW5lSUQsCiAgICAgICAgICAgICAgICBpbl9zZXNzaW9uLT5jb250ZXh0RW5naW5lSURMZW4pOwogICAgICAgIHNlc3Npb24tPmNvbnRleHRFbmdpbmVJRCA9IHVjcDsKICAgIH0gZWxzZSBpZiAoaW5fc2Vzc2lvbi0+c2VjdXJpdHlFbmdpbmVJRExlbiA+IDApIHsKICAgICAgICAvKgogICAgICAgICAqIGRlZmF1bHQgY29udGV4dEVuZ2luZUlEIHRvIHNlY3VyaXR5RW5naW5lSURMZW4gaWYgZGVmaW5lZCAKICAgICAgICAgKi8KICAgICAgICB1Y3AgPSAodV9jaGFyICopIG1hbGxvYyhpbl9zZXNzaW9uLT5zZWN1cml0eUVuZ2luZUlETGVuKTsKICAgICAgICBpZiAodWNwID09IE5VTEwpIHsKICAgICAgICAgICAgc25tcF9zZXNzX2Nsb3NlKHNscCk7CiAgICAgICAgICAgIGluX3Nlc3Npb24tPnNfc25tcF9lcnJubyA9IFNOTVBFUlJfTUFMTE9DOwogICAgICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgICAgIH0KICAgICAgICBtZW1tb3ZlKHVjcCwgaW5fc2Vzc2lvbi0+c2VjdXJpdHlFbmdpbmVJRCwKICAgICAgICAgICAgICAgIGluX3Nlc3Npb24tPnNlY3VyaXR5RW5naW5lSURMZW4pOwogICAgICAgIHNlc3Npb24tPmNvbnRleHRFbmdpbmVJRCA9IHVjcDsKICAgICAgICBzZXNzaW9uLT5jb250ZXh0RW5naW5lSURMZW4gPSBpbl9zZXNzaW9uLT5zZWN1cml0eUVuZ2luZUlETGVuOwogICAgfQoKICAgIGlmIChpbl9zZXNzaW9uLT5jb250ZXh0TmFtZSkgewogICAgICAgIHNlc3Npb24tPmNvbnRleHROYW1lID0gc3RyZHVwKGluX3Nlc3Npb24tPmNvbnRleHROYW1lKTsKICAgICAgICBpZiAoc2Vzc2lvbi0+Y29udGV4dE5hbWUgPT0gTlVMTCkgewogICAgICAgICAgICBzbm1wX3Nlc3NfY2xvc2Uoc2xwKTsKICAgICAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgICAgICB9CiAgICAgICAgc2Vzc2lvbi0+Y29udGV4dE5hbWVMZW4gPSBpbl9zZXNzaW9uLT5jb250ZXh0TmFtZUxlbjsKICAgIH0gZWxzZSB7CiAgICAgICAgaWYgKChjcCA9IG5ldHNubXBfZHNfZ2V0X3N0cmluZyhORVRTTk1QX0RTX0xJQlJBUllfSUQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBORVRTTk1QX0RTX0xJQl9DT05URVhUKSkgIT0gTlVMTCkKICAgICAgICAgICAgY3AgPSBzdHJkdXAoY3ApOwogICAgICAgIGVsc2UKICAgICAgICAgICAgY3AgPSBzdHJkdXAoU05NUF9ERUZBVUxUX0NPTlRFWFQpOwogICAgICAgIGlmIChjcCA9PSBOVUxMKSB7CiAgICAgICAgICAgIHNubXBfc2Vzc19jbG9zZShzbHApOwogICAgICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgICAgIH0KICAgICAgICBzZXNzaW9uLT5jb250ZXh0TmFtZSA9IGNwOwogICAgICAgIHNlc3Npb24tPmNvbnRleHROYW1lTGVuID0gc3RybGVuKGNwKTsKICAgIH0KCiAgICBpZiAoaW5fc2Vzc2lvbi0+c2VjdXJpdHlOYW1lKSB7CiAgICAgICAgc2Vzc2lvbi0+c2VjdXJpdHlOYW1lID0gc3RyZHVwKGluX3Nlc3Npb24tPnNlY3VyaXR5TmFtZSk7CiAgICAgICAgaWYgKHNlc3Npb24tPnNlY3VyaXR5TmFtZSA9PSBOVUxMKSB7CiAgICAgICAgICAgIHNubXBfc2Vzc19jbG9zZShzbHApOwogICAgICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgICAgIH0KICAgIH0gZWxzZSBpZiAoKGNwID0gbmV0c25tcF9kc19nZXRfc3RyaW5nKE5FVFNOTVBfRFNfTElCUkFSWV9JRCwgCgkJCQkJICAgTkVUU05NUF9EU19MSUJfU0VDTkFNRSkpICE9IE5VTEwpIHsKICAgICAgICBjcCA9IHN0cmR1cChjcCk7CiAgICAgICAgaWYgKGNwID09IE5VTEwpIHsKICAgICAgICAgICAgc25tcF9zZXNzX2Nsb3NlKHNscCk7CiAgICAgICAgICAgIHJldHVybiAoTlVMTCk7CiAgICAgICAgfQogICAgICAgIHNlc3Npb24tPnNlY3VyaXR5TmFtZSA9IGNwOwogICAgICAgIHNlc3Npb24tPnNlY3VyaXR5TmFtZUxlbiA9IHN0cmxlbihjcCk7CiAgICB9CgogICAgaWYgKHNlc3Npb24tPnJldHJpZXMgPT0gU05NUF9ERUZBVUxUX1JFVFJJRVMpCiAgICAgICAgc2Vzc2lvbi0+cmV0cmllcyA9IERFRkFVTFRfUkVUUklFUzsKICAgIGlmIChzZXNzaW9uLT50aW1lb3V0ID09IFNOTVBfREVGQVVMVF9USU1FT1VUKQogICAgICAgIHNlc3Npb24tPnRpbWVvdXQgPSBERUZBVUxUX1RJTUVPVVQ7CiAgICBzZXNzaW9uLT5zZXNzaWQgPSBzbm1wX2dldF9uZXh0X3Nlc3NpZCgpOwoKICAgIHNubXBfY2FsbF9jYWxsYmFja3MoU05NUF9DQUxMQkFDS19MSUJSQVJZLCBTTk1QX0NBTExCQUNLX1NFU1NJT05fSU5JVCwKICAgICAgICAgICAgICAgICAgICAgICAgc2Vzc2lvbik7CgogICAgaWYgKChzcHRyID0gZmluZF9zZWNfbW9kKHNlc3Npb24tPnNlY3VyaXR5TW9kZWwpKSAhPSBOVUxMKSB7CiAgICAgICAgLyoKICAgICAgICAgKiBzZWN1cml0eSBtb2R1bGUgc3BlY2lmaWMgY29weWluZyAKICAgICAgICAgKi8KICAgICAgICBpZiAoc3B0ci0+c2Vzc2lvbl9zZXR1cCkgewogICAgICAgICAgICBpbnQgcmV0ID0gKCpzcHRyLT5zZXNzaW9uX3NldHVwKSAoaW5fc2Vzc2lvbiwgc2Vzc2lvbik7CiAgICAgICAgICAgIGlmIChyZXQgIT0gU05NUEVSUl9TVUNDRVNTKSB7CiAgICAgICAgICAgICAgICBzbm1wX3Nlc3NfY2xvc2Uoc2xwKTsKICAgICAgICAgICAgICAgIHJldHVybiBOVUxMOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvKgogICAgICAgICAqIHNlY3VyaXR5IG1vZHVsZSBzcGVjaWZpYyBvcGVuaW5nCiAgICAgICAgICovCiAgICAgICAgaWYgKHNwdHItPnNlc3Npb25fb3BlbikgewogICAgICAgICAgICBpbnQgcmV0ID0gKCpzcHRyLT5zZXNzaW9uX29wZW4pIChzZXNzaW9uKTsKICAgICAgICAgICAgaWYgKHJldCAhPSBTTk1QRVJSX1NVQ0NFU1MpIHsKICAgICAgICAgICAgICAgIHNubXBfc2Vzc19jbG9zZShzbHApOwogICAgICAgICAgICAgICAgcmV0dXJuIE5VTEw7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLyogQW55dGhpbmcgYmVsb3cgdGhpcyBwb2ludCBzaG91bGQgb25seSBiZSBkb25lIGlmIHRoZSB0cmFuc3BvcnQKICAgICAgIGhhZCBubyBzYXkgaW4gdGhlIG1hdHRlciAqLwogICAgaWYgKHNlc3Npb24tPnNlY3VyaXR5TGV2ZWwgPT0gMCkKICAgICAgICBzZXNzaW9uLT5zZWN1cml0eUxldmVsID0gU05NUF9TRUNfTEVWRUxfTk9BVVRIOwoKICAgIHJldHVybiAoc2xwKTsKfQoKc3RhdGljIHN0cnVjdCBzZXNzaW9uX2xpc3QgKgpzbm1wX3Nlc3NfY29weShuZXRzbm1wX3Nlc3Npb24gKiBwc3MpCnsKICAgIHN0cnVjdCBzZXNzaW9uX2xpc3QgKnBzbDsKICAgIHBzbCA9IF9zZXNzX2NvcHkocHNzKTsKICAgIGlmICghcHNsKSB7CiAgICAgICAgaWYgKCFwc3MtPnNfc25tcF9lcnJubykgewogICAgICAgICAgICBwc3MtPnNfc25tcF9lcnJubyA9IFNOTVBFUlJfR0VORVJSOwogICAgICAgIH0KICAgICAgICBTRVRfU05NUF9FUlJPUihwc3MtPnNfc25tcF9lcnJubyk7CiAgICB9CiAgICByZXR1cm4gcHNsOwp9CgovKioKICogcHJvYmUgZm9yIGVuZ2luZUlEIHVzaW5nIFJGQyA1MzQzIHByb2JpbmcgbWVjaGFuaXNtcwogKgogKiBEZXNpZ25lZCB0byBiZSBhIGNhbGxiYWNrIGZvciB3aXRoaW4gYSBzZWN1cml0eSBtb2RlbCdzIHByb2JlX2VuZ2luZWlkIGhvb2suCiAqIFNpbmNlIGl0J3MgbGlrZWx5IG11bHRpcGxlIHNlY3VyaXR5IG1vZGVscyB3b24ndCBoYXZlIGVuZ2luZUlEcyB0bwogKiBwcm9iZSBmb3IgdGhlbiB0aGlzIGZ1bmN0aW9uIGlzIGEgY2FsbGJhY2sgbGlrZWx5IHRvIGJlIHVzZWQgYnkKICogbXVsdGlwbGUgZnV0dXJlIHNlY3VyaXR5IG1vZGVscy4gIEUuRy4gYm90aCBTU0ggYW5kIERUTFMuCiAqLwppbnQKc25tcHYzX3Byb2JlX2NvbnRleHRFbmdpbmVJRF9yZmM1MzQzKHZvaWQgKnNscCwgbmV0c25tcF9zZXNzaW9uICpzZXNzaW9uKSB7CiAgICBuZXRzbm1wX3BkdSAgICAqcGR1ID0gTlVMTCwgKnJlc3BvbnNlID0gTlVMTDsKICAgIHN0YXRpYyBvaWQgICAgICBzbm1wRW5naW5lSURvaWRbXSAgID0geyAxLDMsNiwxLDYsMywxMCwyLDEsMSwwfTsKICAgIHN0YXRpYyBzaXplX3QgICBzbm1wRW5naW5lSURvaWRfbGVuID0gMTE7CgogICAgc3RhdGljIGNoYXIgICAgIHByb2JlRW5naW5lSURbXSA9IHsgKGNoYXIpMHg4MCwgMCwgMCwgMCwgNiB9OwogICAgc3RhdGljIHNpemVfdCAgIHByb2JlRW5naW5lSURfbGVuID0gc2l6ZW9mKHByb2JlRW5naW5lSUQpOwogICAgCiAgICBpbnQgc3RhdHVzOwoKICAgIHBkdSA9IHNubXBfcGR1X2NyZWF0ZShTTk1QX01TR19HRVQpOwogICAgaWYgKCFwZHUpCiAgICAgICAgcmV0dXJuIFNOTVBfRVJSX0dFTkVSUjsKICAgIHBkdS0+dmVyc2lvbiA9IFNOTVBfVkVSU0lPTl8zOwogICAgLyogZG9uJ3QgcmVxdWlyZSBhIHNlY3VyaXR5TmFtZSAqLwogICAgaWYgKHNlc3Npb24tPnNlY3VyaXR5TmFtZSkgewogICAgICAgIHBkdS0+c2VjdXJpdHlOYW1lID0gc3RyZHVwKHNlc3Npb24tPnNlY3VyaXR5TmFtZSk7CiAgICAgICAgcGR1LT5zZWN1cml0eU5hbWVMZW4gPSBzdHJsZW4ocGR1LT5zZWN1cml0eU5hbWUpOwogICAgfQogICAgcGR1LT5zZWN1cml0eUxldmVsID0gU05NUF9TRUNfTEVWRUxfTk9BVVRIOwogICAgcGR1LT5zZWN1cml0eU1vZGVsID0gc2Vzc2lvbi0+c2VjdXJpdHlNb2RlbDsKICAgIHBkdS0+Y29udGV4dEVuZ2luZUlEID0gbmV0c25tcF9tZW1kdXAocHJvYmVFbmdpbmVJRCwgcHJvYmVFbmdpbmVJRF9sZW4pOwogICAgaWYgKCFwZHUtPmNvbnRleHRFbmdpbmVJRCkgewogICAgICAgIHNubXBfbG9nKExPR19FUlIsICJmYWlsZWQgdG8gY2xvbmUgbWVtb3J5IGZvciByZmM1MzQzIHByb2JlXG4iKTsKICAgICAgICBzbm1wX2ZyZWVfcGR1KHBkdSk7CiAgICAgICAgcmV0dXJuIFNOTVBfRVJSX0dFTkVSUjsKICAgIH0KICAgIHBkdS0+Y29udGV4dEVuZ2luZUlETGVuID0gcHJvYmVFbmdpbmVJRF9sZW47CiAgICAKICAgIHNubXBfYWRkX251bGxfdmFyKHBkdSwgc25tcEVuZ2luZUlEb2lkLCBzbm1wRW5naW5lSURvaWRfbGVuKTsKCiAgICBERUJVR01TR1RMKCgic25tcF9hcGkiLCAicHJvYmluZyBmb3IgZW5naW5lSUQgdXNpbmcgcmZjNTM0MyBtZXRob2RzLi4uXG4iKSk7CiAgICBzZXNzaW9uLT5mbGFncyB8PSBTTk1QX0ZMQUdTX0RPTlRfUFJPQkU7IC8qIHByZXZlbnQgcmVjdXJzaW9uICovCiAgICBzdGF0dXMgPSBzbm1wX3Nlc3Nfc3luY2hfcmVzcG9uc2Uoc2xwLCBwZHUsICZyZXNwb25zZSk7CgogICAgaWYgKChyZXNwb25zZSA9PSBOVUxMKSB8fCAoc3RhdHVzICE9IFNUQVRfU1VDQ0VTUykpIHsKICAgICAgICBzbm1wX2xvZyhMT0dfRVJSLCAiZmFpbGVkIHJmYzUzNDMgY29udGV4dEVuZ2luZUlEIHByb2JpbmdcbiIpOwogICAgICAgIHJldHVybiBTTk1QX0VSUl9HRU5FUlI7CiAgICB9CgogICAgLyogY2hlY2sgdGhhdCB0aGUgcmVzcG9uc2UgbWFrZXMgc2Vuc2UgKi8KICAgIGlmIChOVUxMICE9IHJlc3BvbnNlLT52YXJpYWJsZXMgJiYKICAgICAgICBOVUxMICE9IHJlc3BvbnNlLT52YXJpYWJsZXMtPm5hbWUgJiYKICAgICAgICBzbm1wX29pZF9jb21wYXJlKHJlc3BvbnNlLT52YXJpYWJsZXMtPm5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICByZXNwb25zZS0+dmFyaWFibGVzLT5uYW1lX2xlbmd0aCwKICAgICAgICAgICAgICAgICAgICAgICAgIHNubXBFbmdpbmVJRG9pZCwgc25tcEVuZ2luZUlEb2lkX2xlbikgPT0gMCAmJgogICAgICAgIEFTTl9PQ1RFVF9TVFIgPT0gcmVzcG9uc2UtPnZhcmlhYmxlcy0+dHlwZSAgJiYKICAgICAgICBOVUxMICE9IHJlc3BvbnNlLT52YXJpYWJsZXMtPnZhbC5zdHJpbmcgJiYKICAgICAgICByZXNwb25zZS0+dmFyaWFibGVzLT52YWxfbGVuID4gMCkgewogICAgICAgIHNlc3Npb24tPmNvbnRleHRFbmdpbmVJRCA9CiAgICAgICAgICAgIG5ldHNubXBfbWVtZHVwKHJlc3BvbnNlLT52YXJpYWJsZXMtPnZhbC5zdHJpbmcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3BvbnNlLT52YXJpYWJsZXMtPnZhbF9sZW4pOwogICAgICAgIGlmICghc2Vzc2lvbi0+Y29udGV4dEVuZ2luZUlEKSB7CiAgICAgICAgICAgIHNubXBfbG9nKExPR19FUlIsICJmYWlsZWQgcmZjNTM0MyBjb250ZXh0RW5naW5lSUQgcHJvYmluZzogbWVtb3J5IGFsbG9jYXRpb24gZmFpbGVkXG4iKTsKICAgICAgICAgICAgcmV0dXJuIFNOTVBfRVJSX0dFTkVSUjsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgLyogdGVjaG5pY2FsbHkgdGhlcmUgbGlrZWx5IGlzbid0IGEgc2VjdXJpdHlFbmdpbmVJRCBidXQganVzdAogICAgICAgICAgIGluIGNhc2UgYW55b25lIGdvZXMgbG9va2luZyB3ZSBtaWdodCBhcyB3ZWxsIGhhdmUgb25lICovCiAgICAgICAgc2Vzc2lvbi0+c2VjdXJpdHlFbmdpbmVJRCA9CiAgICAgICAgICAgIG5ldHNubXBfbWVtZHVwKHJlc3BvbnNlLT52YXJpYWJsZXMtPnZhbC5zdHJpbmcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlc3BvbnNlLT52YXJpYWJsZXMtPnZhbF9sZW4pOwogICAgICAgIGlmICghc2Vzc2lvbi0+c2VjdXJpdHlFbmdpbmVJRCkgewogICAgICAgICAgICBzbm1wX2xvZyhMT0dfRVJSLCAiZmFpbGVkIHJmYzUzNDMgc2VjdXJpdHlFbmdpbmVJRCBwcm9iaW5nOiBtZW1vcnkgYWxsb2NhdGlvbiBmYWlsZWRcbiIpOwogICAgICAgICAgICByZXR1cm4gU05NUF9FUlJfR0VORVJSOwogICAgICAgIH0KICAgICAgICAKICAgICAgICBzZXNzaW9uLT5zZWN1cml0eUVuZ2luZUlETGVuID0gc2Vzc2lvbi0+Y29udGV4dEVuZ2luZUlETGVuID0KICAgICAgICAgICAgcmVzcG9uc2UtPnZhcmlhYmxlcy0+dmFsX2xlbjsKICAgICAgICAKICAgICAgICBpZiAoc25tcF9nZXRfZG9fZGVidWdnaW5nKCkpIHsKICAgICAgICAgICAgc2l6ZV90IGk7CiAgICAgICAgICAgIERFQlVHTVNHVEwoKCJzbm1wX3Nlc3Nfb3BlbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICIgIHByb2JlIGZvdW5kIGVuZ2luZUlEOiAgIikpOwogICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgc2Vzc2lvbi0+c2VjdXJpdHlFbmdpbmVJRExlbjsgaSsrKQogICAgICAgICAgICAgICAgREVCVUdNU0coKCJzbm1wX3Nlc3Nfb3BlbiIsICIlMDJ4IiwKICAgICAgICAgICAgICAgICAgICAgICAgICBzZXNzaW9uLT5zZWN1cml0eUVuZ2luZUlEW2ldKSk7CiAgICAgICAgICAgIERFQlVHTVNHKCgic25tcF9zZXNzX29wZW4iLCAiXG4iKSk7CiAgICAgICAgfQogICAgfQogICAgcmV0dXJuIFNOTVBFUlJfU1VDQ0VTUzsKfQoKCi8qKgogKiBwcm9iZSBmb3IgcGVlciBlbmdpbmVJRAogKgogKiBAcGFyYW0gc2xwICAgICAgICAgc2Vzc2lvbiBsaXN0IHBvaW50ZXIuCiAqIEBwYXJhbSBpbl9zZXNzaW9uICBzZXNzaW9uIGZvciBlcnJvcnMKICoKICogQG5vdGUKICogIC0gY2FsbGVkIGJ5IF9zZXNzX29wZW4oKSwgc25tcF9zZXNzX2FkZF9leCgpCiAqICAtIGluX3Nlc3Npb24gaXMgdGhlIHVzZXIgc3VwcGxpZWQgc2Vzc2lvbiBwcm92aWRlZCB0byB0aG9zZSBmdW5jdGlvbnMuCiAqICAtIHRoZSBmaXJzdCBzZXNzaW9uIGluIHNscCBzaG91bGQgdGhlIGludGVybmFsIGFsbG9jYXRlZCBjb3B5IG9mIGluX3Nlc3Npb24KICoKICogQHJldHVybiAwIDogZXJyb3IKICogQHJldHVybiAxIDogb2sKICoKICovCmludApzbm1wdjNfZW5naW5lSURfcHJvYmUoc3RydWN0IHNlc3Npb25fbGlzdCAqc2xwLAogICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9zZXNzaW9uICogaW5fc2Vzc2lvbikKewogICAgbmV0c25tcF9wZHUgICAgKnBkdSA9IE5VTEwsICpyZXNwb25zZSA9IE5VTEw7CiAgICBuZXRzbm1wX3Nlc3Npb24gKnNlc3Npb247CiAgICB1bnNpZ25lZCBpbnQgICAgaTsKICAgIGludCAgICAgICAgICAgICBzdGF0dXM7CgogICAgaWYgKHNscCA9PSBOVUxMIHx8IHNscC0+c2Vzc2lvbiA9PSBOVUxMKSB7CiAgICAgICAgcmV0dXJuIDA7CiAgICB9CgogICAgc2Vzc2lvbiA9IHNscC0+c2Vzc2lvbjsKCiAgICAvKgogICAgICogSWYgd2UgYXJlIG9wZW5pbmcgYSBWMyBzZXNzaW9uIGFuZCB3ZSBkb24ndCBrbm93IGVuZ2luZUlEIHdlIG11c3QgcHJvYmUKICAgICAqIGl0IC0tIHRoaXMgbXVzdCBiZSBkb25lIGFmdGVyIHRoZSBzZXNzaW9uIGlzIGNyZWF0ZWQgYW5kIGluc2VydGVkIGluIHRoZQogICAgICogbGlzdCBzbyB0aGF0IHRoZSByZXNwb25zZSBjYW4gaGFuZGxlZCBjb3JyZWN0bHkuIAogICAgICovCgogICAgaWYgKChzZXNzaW9uLT5mbGFncyAmIFNOTVBfRkxBR1NfRE9OVF9QUk9CRSkgPT0gU05NUF9GTEFHU19ET05UX1BST0JFKQogICAgICAgIHJldHVybiAxOwoKICAgIGlmIChzZXNzaW9uLT52ZXJzaW9uID09IFNOTVBfVkVSU0lPTl8zKSB7CiAgICAgICAgc3RydWN0IHNubXBfc2VjbW9kX2RlZiAqc3B0ciA9IGZpbmRfc2VjX21vZChzZXNzaW9uLT5zZWN1cml0eU1vZGVsKTsKCiAgICAgICAgaWYgKE5VTEwgIT0gc3B0ciAmJiBOVUxMICE9IHNwdHItPnByb2JlX2VuZ2luZWlkKSB7CiAgICAgICAgICAgIERFQlVHTVNHVEwoKCJzbm1wX2FwaSIsICJwcm9iaW5nIGZvciBlbmdpbmVJRCB1c2luZyBzZWN1cml0eSBtb2RlbCBjYWxsYmFjay4uLlxuIikpOwogICAgICAgICAgICAvKiBzZWN1cml0eSBtb2RlbCBzcGVjaWZpYyBtZWNoYW5pc20gb2YgZGV0ZXJtaW5pbmcgZW5naW5lSUQgKi8KICAgICAgICAgICAgc3RhdHVzID0gKCpzcHRyLT5wcm9iZV9lbmdpbmVpZCkgKHNscCwgc2Vzc2lvbik7CiAgICAgICAgICAgIGlmIChzdGF0dXMpCiAgICAgICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICAgICAgcmV0dXJuIDE7IC8qIHN1Y2Nlc3MhICovCiAgICAgICAgfSBlbHNlIGlmIChzZXNzaW9uLT5zZWN1cml0eUVuZ2luZUlETGVuID09IDApIHsKICAgICAgICAgICAgaWYgKHNubXB2M19idWlsZF9wcm9iZV9wZHUoJnBkdSkgIT0gMCkgewogICAgICAgICAgICAgICAgREVCVUdNU0dUTCgoInNubXBfYXBpIiwgInVuYWJsZSB0byBjcmVhdGUgcHJvYmUgUERVXG4iKSk7CiAgICAgICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICAgICAgfQogICAgICAgICAgICBERUJVR01TR1RMKCgic25tcF9hcGkiLCAicHJvYmluZyBmb3IgZW5naW5lSUQuLi5cbiIpKTsKICAgICAgICAgICAgc2Vzc2lvbi0+ZmxhZ3MgfD0gU05NUF9GTEFHU19ET05UX1BST0JFOyAvKiBwcmV2ZW50IHJlY3Vyc2lvbiAqLwogICAgICAgICAgICBzdGF0dXMgPSBzbm1wX3Nlc3Nfc3luY2hfcmVzcG9uc2Uoc2xwLCBwZHUsICZyZXNwb25zZSk7CgogICAgICAgICAgICBpZiAoKHJlc3BvbnNlID09IE5VTEwpICYmIChzdGF0dXMgPT0gU1RBVF9TVUNDRVNTKSkgewogICAgICAgICAgICAgICAgc3RhdHVzID0gU1RBVF9FUlJPUjsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgc3dpdGNoIChzdGF0dXMpIHsKICAgICAgICAgICAgY2FzZSBTVEFUX1NVQ0NFU1M6CiAgICAgICAgICAgICAgICBpbl9zZXNzaW9uLT5zX3NubXBfZXJybm8gPSBTTk1QRVJSX0lOVkFMSURfTVNHOyAvKiBYWD8/ICovCiAgICAgICAgICAgICAgICBERUJVR01TR1RMKCgic25tcF9zZXNzX29wZW4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgImVycm9yOiBleHBlY3RlZCBSZXBvcnQgYXMgcmVzcG9uc2UgdG8gcHJvYmU6ICVzICglbGQpXG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgc25tcF9lcnJzdHJpbmcocmVzcG9uc2UtPmVycnN0YXQpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzcG9uc2UtPmVycnN0YXQpKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIFNUQVRfRVJST1I6ICAgLyogdGhpcyBpcyB3aGF0IHdlIGV4cGVjdGVkIC0+IFJlcG9ydCA9PSBTVEFUX0VSUk9SICovCiAgICAgICAgICAgICAgICBpbl9zZXNzaW9uLT5zX3NubXBfZXJybm8gPSBTTk1QRVJSX1VOS05PV05fRU5HX0lEOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgU1RBVF9USU1FT1VUOgogICAgICAgICAgICAgICAgaW5fc2Vzc2lvbi0+c19zbm1wX2Vycm5vID0gU05NUEVSUl9USU1FT1VUOwogICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgREVCVUdNU0dUTCgoInNubXBfc2Vzc19vcGVuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ1bmFibGUgdG8gY29ubmVjdCB3aXRoIHJlbW90ZSBlbmdpbmU6ICVzICglZClcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzbm1wX2FwaV9lcnJzdHJpbmcoc2Vzc2lvbi0+c19zbm1wX2Vycm5vKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlc3Npb24tPnNfc25tcF9lcnJubykpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChzbHAtPnNlc3Npb24tPnNlY3VyaXR5RW5naW5lSURMZW4gPT0gMCkgewogICAgICAgICAgICAgICAgREVCVUdNU0dUTCgoInNubXBfYXBpIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ1bmFibGUgdG8gZGV0ZXJtaW5lIHJlbW90ZSBlbmdpbmUgSURcbiIpKTsKICAgICAgICAgICAgICAgIC8qIGNsZWFyIHRoZSBmbGFnIHNvIHRoYXQgcHJvYmUgb2NjdXJzIG9uIG5leHQgaW5mb3JtICovCiAgICAgICAgICAgICAgICBzZXNzaW9uLT5mbGFncyAmPSB+U05NUF9GTEFHU19ET05UX1BST0JFOwogICAgICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGluX3Nlc3Npb24tPnNfc25tcF9lcnJubyA9IFNOTVBFUlJfU1VDQ0VTUzsKICAgICAgICAgICAgaWYgKHNubXBfZ2V0X2RvX2RlYnVnZ2luZygpKSB7CiAgICAgICAgICAgICAgICBERUJVR01TR1RMKCgic25tcF9zZXNzX29wZW4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIiAgcHJvYmUgZm91bmQgZW5naW5lSUQ6ICAiKSk7CiAgICAgICAgICAgICAgICBmb3IgKGkgPSAwOyBpIDwgc2xwLT5zZXNzaW9uLT5zZWN1cml0eUVuZ2luZUlETGVuOyBpKyspCiAgICAgICAgICAgICAgICAgICAgREVCVUdNU0coKCJzbm1wX3Nlc3Nfb3BlbiIsICIlMDJ4IiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2xwLT5zZXNzaW9uLT5zZWN1cml0eUVuZ2luZUlEW2ldKSk7CiAgICAgICAgICAgICAgICBERUJVR01TRygoInNubXBfc2Vzc19vcGVuIiwgIlxuIikpOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICAvKgogICAgICAgICAqIGlmIGJvb3QvdGltZSBzdXBwbGllZCBzZXQgaXQgZm9yIHRoaXMgZW5naW5lSUQgCiAgICAgICAgICovCiAgICAgICAgaWYgKHNlc3Npb24tPmVuZ2luZUJvb3RzIHx8IHNlc3Npb24tPmVuZ2luZVRpbWUpIHsKICAgICAgICAgICAgc2V0X2VuZ2luZXRpbWUoc2Vzc2lvbi0+c2VjdXJpdHlFbmdpbmVJRCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgc2Vzc2lvbi0+c2VjdXJpdHlFbmdpbmVJRExlbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgc2Vzc2lvbi0+ZW5naW5lQm9vdHMsIHNlc3Npb24tPmVuZ2luZVRpbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIFRSVUUpOwogICAgICAgIH0KCiAgICAgICAgaWYgKGNyZWF0ZV91c2VyX2Zyb21fc2Vzc2lvbihzbHAtPnNlc3Npb24pICE9IFNOTVBFUlJfU1VDQ0VTUykgewogICAgICAgICAgICBpbl9zZXNzaW9uLT5zX3NubXBfZXJybm8gPSBTTk1QRVJSX1VOS05PV05fVVNFUl9OQU1FOyAgICAgICAvKiBYWD8/ICovCiAgICAgICAgICAgIERFQlVHTVNHVEwoKCJzbm1wX2FwaSIsCiAgICAgICAgICAgICAgICAgICAgICAgICJzbm1wdjNfZW5naW5lX3Byb2JlKCk6IGZhaWxlZCgyKSB0byBjcmVhdGUgYSBuZXcgdXNlciBmcm9tIHNlc3Npb25cbiIpKTsKICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgfQogICAgfQoKICAgIHJldHVybiAxOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi1vLSoqKioqKgogKiBuZXRzbm1wX3Nlc3NfY29uZmlnX3RyYW5zcG9ydAogKgogKiBQYXJhbWV0ZXJzOgogKgkqaW5fc2Vzc2lvbgogKgkqaW5fdHJhbnNwb3J0CiAqCiAqIFJldHVybnM6CiAqICAgICAgU05NUEVSUl9TVUNDRVNTICAgICAgICAgICAgICAgICAgICAgLSBZYXkKICogICAgICBTTk1QRVJSX0dFTkVSUiAgICAgICAgICAgICAgICAgICAgICAtIEdlbmVyaWMgRXJyb3IKICogICAgICBTTk1QRVJSX1RSQU5TUE9SVF9DT05GSUdfRVJST1IgICAgICAtIFRyYW5zcG9ydCByZWplY3RlZCBjb25maWcKICogICAgICBTTk1QRVJSX1RSQU5TUE9SVF9OT19DT05GSUcgICAgICAgICAtIFRyYW5zcG9ydCBjYW4ndCBjb25maWcKICovCmludApuZXRzbm1wX3Nlc3NfY29uZmlnX3RyYW5zcG9ydChuZXRzbm1wX2NvbnRhaW5lciAqdHJhbnNwb3J0X2NvbmZpZ3VyYXRpb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfdHJhbnNwb3J0ICp0cmFuc3BvcnQpCnsKICAgIC8qIE9wdGlvbmFsIHN1cHBsaW1lbnRhbCB0cmFuc3BvcnQgY29uZmlndXJhdGlvbiBpbmZvcm1hdGlvbiBhbmQKICAgICAgIGZpbmFsIGNhbGwgdG8gYWN0dWFsbHkgb3BlbiB0aGUgdHJhbnNwb3J0ICovCiAgICBpZiAodHJhbnNwb3J0X2NvbmZpZ3VyYXRpb24pIHsKICAgICAgICBERUJVR01TR1RMKCgic25tcF9zZXNzIiwgImNvbmZpZ3VyaW5nIHRyYW5zcG9ydFxuIikpOwogICAgICAgIGlmICh0cmFuc3BvcnQtPmZfY29uZmlnKSB7CiAgICAgICAgICAgIG5ldHNubXBfaXRlcmF0b3IgKml0ZXI7CiAgICAgICAgICAgIG5ldHNubXBfdHJhbnNwb3J0X2NvbmZpZyAqY29uZmlnX2RhdGE7CiAgICAgICAgICAgIGludCByZXQ7CgogICAgICAgICAgICBpdGVyID0gQ09OVEFJTkVSX0lURVJBVE9SKHRyYW5zcG9ydF9jb25maWd1cmF0aW9uKTsKICAgICAgICAgICAgaWYgKE5VTEwgPT0gaXRlcikgewogICAgICAgICAgICAgICAgcmV0dXJuIFNOTVBFUlJfR0VORVJSOwogICAgICAgICAgICB9CgogICAgICAgICAgICBmb3IoY29uZmlnX2RhdGEgPSAobmV0c25tcF90cmFuc3BvcnRfY29uZmlnKilJVEVSQVRPUl9GSVJTVChpdGVyKTsgY29uZmlnX2RhdGE7CiAgICAgICAgICAgICAgICBjb25maWdfZGF0YSA9IChuZXRzbm1wX3RyYW5zcG9ydF9jb25maWcqKUlURVJBVE9SX05FWFQoaXRlcikpIHsKICAgICAgICAgICAgICAgIHJldCA9IHRyYW5zcG9ydC0+Zl9jb25maWcodHJhbnNwb3J0LCBjb25maWdfZGF0YS0+a2V5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25maWdfZGF0YS0+dmFsdWUpOwogICAgICAgICAgICAgICAgaWYgKHJldCkgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBTTk1QRVJSX1RSQU5TUE9SVF9DT05GSUdfRVJST1I7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgICByZXR1cm4gU05NUEVSUl9UUkFOU1BPUlRfTk9fQ09ORklHOwogICAgICAgIH0KICAgIH0KICAgIHJldHVybiBTTk1QRVJSX1NVQ0NFU1M7Cn0KCiAKLyoqCiAqIENvcGllcyBjb25maWd1cmF0aW9uIGZyb20gdGhlIHNlc3Npb24gYW5kIGNhbGxzIGZfb3BlbgogKiBUaGlzIGZ1bmN0aW9uIGNvcGllcyBhbnkgY29uZmlndXJhdGlvbiBzdG9yZWQgaW4gdGhlIHNlc3Npb24KICogcG9pbnRlciB0byB0aGUgdHJhbnNwb3J0IGlmIGl0IGhhcyBhIGZfY29uZmlnIHBvaW50ZXIgYW5kIHRoZW4KICogY2FsbHMgdGhlIHRyYW5zcG9ydCdzIGZfb3BlbiBmdW5jdGlvbiB0byBhY3R1YWxseSBvcGVuIHRoZQogKiBjb25uZWN0aW9uLgogKgogKiBAcGFyYW0gaW5fc2Vzc2lvbiBBIHBvaW50ZXIgdG8gdGhlIHNlc3Npb24gdGhhdCBjb25maWcgaW5mb3JtYXRpb24gaXMgaW4uCiAqIEBwYXJhbSB0cmFuc3BvcnQgQSBwb2ludGVyIHRvIHRoZSB0cmFuc3BvcnQgdG8gY29uZmlnL29wZW4uCiAqCiAqIEByZXR1cm4gU05NUEVSUl9TVUNDRVNTIDogb24gc3VjY2VzcwogKi8KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLW8tKioqKioqCiAqIG5ldHNubXBfc2Vzc19jb25maWdfdHJhbnNwb3J0CiAqCiAqIFBhcmFtZXRlcnM6CiAqCSppbl9zZXNzaW9uCiAqCSppbl90cmFuc3BvcnQKICoKICogUmV0dXJuczoKICogICAgICBTTk1QRVJSX1NVQ0NFU1MgICAgICAgICAgICAgICAgICAgICAtIFlheQogKiAgICAgIFNOTVBFUlJfR0VORVJSICAgICAgICAgICAgICAgICAgICAgIC0gR2VuZXJpYyBFcnJvcgogKiAgICAgIFNOTVBFUlJfVFJBTlNQT1JUX0NPTkZJR19FUlJPUiAgICAgIC0gVHJhbnNwb3J0IHJlamVjdGVkIGNvbmZpZwogKiAgICAgIFNOTVBFUlJfVFJBTlNQT1JUX05PX0NPTkZJRyAgICAgICAgIC0gVHJhbnNwb3J0IGNhbid0IGNvbmZpZwogKi8KaW50Cm5ldHNubXBfc2Vzc19jb25maWdfYW5kX29wZW5fdHJhbnNwb3J0KG5ldHNubXBfc2Vzc2lvbiAqaW5fc2Vzc2lvbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF90cmFuc3BvcnQgKnRyYW5zcG9ydCkKewogICAgaW50IHJjOwogICAgCiAgICBERUJVR01TR1RMKCgic25tcF9zZXNzIiwgIm9wZW5pbmcgdHJhbnNwb3J0OiAleFxuIiwgdHJhbnNwb3J0LT5mbGFncyAmIE5FVFNOTVBfVFJBTlNQT1JUX0ZMQUdfT1BFTkVEKSk7CgogICAgLyogZG9uJ3QgZG91YmxlIG9wZW4gKi8KICAgIGlmICh0cmFuc3BvcnQtPmZsYWdzICYgTkVUU05NUF9UUkFOU1BPUlRfRkxBR19PUEVORUQpCiAgICAgICAgcmV0dXJuIFNOTVBFUlJfU1VDQ0VTUzsKCiAgICBpZiAoKHJjID0gbmV0c25tcF9zZXNzX2NvbmZpZ190cmFuc3BvcnQoaW5fc2Vzc2lvbi0+dHJhbnNwb3J0X2NvbmZpZ3VyYXRpb24sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdHJhbnNwb3J0KSkgIT0gU05NUEVSUl9TVUNDRVNTKSB7CiAgICAgICAgaW5fc2Vzc2lvbi0+c19zbm1wX2Vycm5vID0gcmM7CiAgICAgICAgaW5fc2Vzc2lvbi0+c19lcnJubyA9IDA7CiAgICAgICAgcmV0dXJuIHJjOwogICAgfQogICAgICAgIAogICAgaWYgKHRyYW5zcG9ydC0+Zl9vcGVuKQogICAgICAgIHRyYW5zcG9ydCA9IHRyYW5zcG9ydC0+Zl9vcGVuKHRyYW5zcG9ydCk7CgogICAgaWYgKHRyYW5zcG9ydCA9PSBOVUxMKSB7CiAgICAgICAgREVCVUdNU0dUTCgoInNubXBfc2VzcyIsICJjb3VsZG4ndCBpbnRlcnByZXQgcGVlcm5hbWVcbiIpKTsKICAgICAgICBpbl9zZXNzaW9uLT5zX3NubXBfZXJybm8gPSBTTk1QRVJSX0JBRF9BRERSRVNTOwogICAgICAgIGluX3Nlc3Npb24tPnNfZXJybm8gPSBlcnJubzsKICAgICAgICBzbm1wX3NldF9kZXRhaWwoaW5fc2Vzc2lvbi0+cGVlcm5hbWUpOwogICAgICAgIHJldHVybiBTTk1QRVJSX0JBRF9BRERSRVNTOwogICAgfQoKICAgIHRyYW5zcG9ydC0+ZmxhZ3MgfD0gTkVUU05NUF9UUkFOU1BPUlRfRkxBR19PUEVORUQ7CiAgICBERUJVR01TR1RMKCgic25tcF9zZXNzIiwgImRvbmUgb3BlbmluZyB0cmFuc3BvcnQ6ICV4XG4iLCB0cmFuc3BvcnQtPmZsYWdzICYgTkVUU05NUF9UUkFOU1BPUlRfRkxBR19PUEVORUQpKTsKICAgIHJldHVybiBTTk1QRVJSX1NVQ0NFU1M7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLW8tKioqKioqCiAqIHNubXBfc2Vzc19vcGVuCiAqCiAqIFBhcmFtZXRlcnM6CiAqCSppbl9zZXNzaW9uCiAqCiAqIFJldHVybnM6CiAqICAgICAgUG9pbnRlciB0byBhIHNlc3Npb24gaW4gdGhlIHNlc3Npb24gbGlzdCAgIC1PUi0JCUZJWCAtLSByaWdodD8KICoJTlVMTCBvbiBmYWlsdXJlLgogKgogKiBUaGUgInNwaW4tZnJlZSIgdmVyc2lvbiBvZiBzbm1wX29wZW4uCiAqLwpzdGF0aWMgdm9pZCAgICAqCl9zZXNzX29wZW4obmV0c25tcF9zZXNzaW9uICogaW5fc2Vzc2lvbikKewogICAgbmV0c25tcF90cmFuc3BvcnQgKnRyYW5zcG9ydCA9IE5VTEw7CiAgICBpbnQgcmM7CgogICAgaW5fc2Vzc2lvbi0+c19zbm1wX2Vycm5vID0gMDsKICAgIGluX3Nlc3Npb24tPnNfZXJybm8gPSAwOwoKICAgIF9pbml0X3NubXAoKTsKCiAgICB7CiAgICAgICAgY2hhciAqY2xpZW50YWRkcl9zYXZlID0gTlVMTDsKCiAgICAgICAgaWYgKE5VTEwgIT0gaW5fc2Vzc2lvbi0+bG9jYWxuYW1lKSB7CiAgICAgICAgICAgIGNsaWVudGFkZHJfc2F2ZSA9CiAgICAgICAgICAgICAgICBuZXRzbm1wX2RzX2dldF9zdHJpbmcoTkVUU05NUF9EU19MSUJSQVJZX0lELAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5FVFNOTVBfRFNfTElCX0NMSUVOVF9BRERSKTsKICAgICAgICAgICAgbmV0c25tcF9kc19zZXRfc3RyaW5nKE5FVFNOTVBfRFNfTElCUkFSWV9JRCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5FVFNOTVBfRFNfTElCX0NMSUVOVF9BRERSLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5fc2Vzc2lvbi0+bG9jYWxuYW1lKTsKICAgICAgICB9CgogICAgICAgIGlmIChpbl9zZXNzaW9uLT5mbGFncyAmIFNOTVBfRkxBR1NfU1RSRUFNX1NPQ0tFVCkgewogICAgICAgICAgICB0cmFuc3BvcnQgPQogICAgICAgICAgICAgICAgbmV0c25tcF90ZG9tYWluX3RyYW5zcG9ydF9mdWxsKCJzbm1wIiwgaW5fc2Vzc2lvbi0+cGVlcm5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW5fc2Vzc2lvbi0+bG9jYWxfcG9ydCwgInRjcCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgdHJhbnNwb3J0ID0KICAgICAgICAgICAgICAgIG5ldHNubXBfdGRvbWFpbl90cmFuc3BvcnRfZnVsbCgic25tcCIsIGluX3Nlc3Npb24tPnBlZXJuYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluX3Nlc3Npb24tPmxvY2FsX3BvcnQsICJ1ZHAiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5VTEwpOwogICAgICAgIH0KCiAgICAgICAgaWYgKE5VTEwgIT0gY2xpZW50YWRkcl9zYXZlKQogICAgICAgICAgICBuZXRzbm1wX2RzX3NldF9zdHJpbmcoTkVUU05NUF9EU19MSUJSQVJZX0lELAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTkVUU05NUF9EU19MSUJfQ0xJRU5UX0FERFIsIGNsaWVudGFkZHJfc2F2ZSk7CiAgICB9CgogICAgaWYgKHRyYW5zcG9ydCA9PSBOVUxMKSB7CiAgICAgICAgREVCVUdNU0dUTCgoIl9zZXNzX29wZW4iLCAiY291bGRuJ3QgaW50ZXJwcmV0IHBlZXJuYW1lXG4iKSk7CiAgICAgICAgaW5fc2Vzc2lvbi0+c19zbm1wX2Vycm5vID0gU05NUEVSUl9CQURfQUREUkVTUzsKICAgICAgICBpbl9zZXNzaW9uLT5zX2Vycm5vID0gZXJybm87CiAgICAgICAgc25tcF9zZXRfZGV0YWlsKGluX3Nlc3Npb24tPnBlZXJuYW1lKTsKICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0KCiAgICAvKiBPcHRpb25hbCBzdXBwbGltZW50YWwgdHJhbnNwb3J0IGNvbmZpZ3VyYXRpb24gaW5mb3JtYXRpb24gYW5kCiAgICAgICBmaW5hbCBjYWxsIHRvIGFjdHVhbGx5IG9wZW4gdGhlIHRyYW5zcG9ydCAqLwogICAgaWYgKChyYyA9IG5ldHNubXBfc2Vzc19jb25maWdfYW5kX29wZW5fdHJhbnNwb3J0KGluX3Nlc3Npb24sIHRyYW5zcG9ydCkpCiAgICAgICAgIT0gU05NUEVSUl9TVUNDRVNTKSB7CiAgICAgICAgdHJhbnNwb3J0ID0gTlVMTDsKICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0KCiNpZiBkZWZpbmVkKFNPX0JST0FEQ0FTVCkgJiYgZGVmaW5lZChTT0xfU09DS0VUKQogICAgaWYgKCBpbl9zZXNzaW9uLT5mbGFncyAmIFNOTVBfRkxBR1NfVURQX0JST0FEQ0FTVCkgewogICAgICAgIGludCAgIGIgPSAxOwogICAgICAgIGludCAgIHJjOwoKICAgICAgICByYyA9IHNldHNvY2tvcHQodHJhbnNwb3J0LT5zb2NrLCBTT0xfU09DS0VULCBTT19CUk9BRENBU1QsCiAgICAgICAgICAgICAgICAgICAgICAgIChjaGFyICopJmIsIHNpemVvZihiKSk7CgogICAgICAgIGlmICggcmMgIT0gMCApIHsKICAgICAgICAgICAgaW5fc2Vzc2lvbi0+c19zbm1wX2Vycm5vID0gU05NUEVSUl9CQURfQUREUkVTUzsgLyogZ29vZCBhcyBhbnk/ICovCiAgICAgICAgICAgIGluX3Nlc3Npb24tPnNfZXJybm8gPSBlcnJubzsKCiAgICAgICAgICAgIERFQlVHTVNHVEwoKCJfc2Vzc19vcGVuIiwgImNvdWxkbid0IGVuYWJsZSBVRFBfQlJPQURDQVNUXG4iKSk7CiAgICAgICAgICAgIHJldHVybiBOVUxMOwogICAgICAgIH0KICAgIH0KI2VuZGlmCgogICAgcmV0dXJuIHNubXBfc2Vzc19hZGQoaW5fc2Vzc2lvbiwgdHJhbnNwb3J0LCBOVUxMLCBOVUxMKTsKfQoKLyoKICogRVhURU5ERUQgU0VTU0lPTiBBUEkgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tIAogKiAKICogc25tcF9zZXNzX2FkZF9leCwgc25tcF9zZXNzX2FkZCwgc25tcF9hZGQgCiAqIAogKiBBbmFsb2dvdXMgdG8gc25tcF9vcGVuIGZhbWlseSBvZiBmdW5jdGlvbnMsIGJ1dCB0YWtpbmcgYSBuZXRzbm1wX3RyYW5zcG9ydAogKiBwb2ludGVyIGFzIGFuIGV4dHJhIGFyZ3VtZW50LiAgVW5saWtlIHNubXBfb3BlbiBldCBhbC4gaXQgZG9lc24ndCBhdHRlbXB0CiAqIHRvIGludGVycHJldCB0aGUgaW5fc2Vzc2lvbi0+cGVlcm5hbWUgYXMgYSB0cmFuc3BvcnQgZW5kcG9pbnQgc3BlY2lmaWVyLAogKiBidXQgaW5zdGVhZCB1c2VzIHRoZSBzdXBwbGllZCB0cmFuc3BvcnQuICBKQlBOCiAqIAogKi8KCm5ldHNubXBfc2Vzc2lvbiAqCnNubXBfYWRkKG5ldHNubXBfc2Vzc2lvbiAqIGluX3Nlc3Npb24sCiAgICAgICAgIG5ldHNubXBfdHJhbnNwb3J0ICp0cmFuc3BvcnQsCiAgICAgICAgIGludCAoKmZwcmVfcGFyc2UpIChuZXRzbm1wX3Nlc3Npb24gKiwgbmV0c25tcF90cmFuc3BvcnQgKiwgdm9pZCAqLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50KSwgaW50ICgqZnBvc3RfcGFyc2UpIChuZXRzbm1wX3Nlc3Npb24gKiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9wZHUgKiwgaW50KSkKewogICAgc3RydWN0IHNlc3Npb25fbGlzdCAqc2xwOwogICAgc2xwID0gKHN0cnVjdCBzZXNzaW9uX2xpc3QgKikgc25tcF9zZXNzX2FkZF9leChpbl9zZXNzaW9uLCB0cmFuc3BvcnQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZwcmVfcGFyc2UsIE5VTEwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZwb3N0X3BhcnNlLCBOVUxMLCBOVUxMLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOVUxMLCBOVUxMKTsKICAgIGlmIChzbHAgPT0gTlVMTCkgewogICAgICAgIHJldHVybiBOVUxMOwogICAgfQoKICAgIHNubXBfcmVzX2xvY2soTVRfTElCUkFSWV9JRCwgTVRfTElCX1NFU1NJT04pOwogICAgc2xwLT5uZXh0ID0gU2Vzc2lvbnM7CiAgICBTZXNzaW9ucyA9IHNscDsKICAgIHNubXBfcmVzX3VubG9jayhNVF9MSUJSQVJZX0lELCBNVF9MSUJfU0VTU0lPTik7CgogICAgcmV0dXJuIChzbHAtPnNlc3Npb24pOwp9CgpuZXRzbm1wX3Nlc3Npb24gKgpzbm1wX2FkZF9mdWxsKG5ldHNubXBfc2Vzc2lvbiAqIGluX3Nlc3Npb24sCiAgICAgICAgICAgICAgbmV0c25tcF90cmFuc3BvcnQgKnRyYW5zcG9ydCwKICAgICAgICAgICAgICBpbnQgKCpmcHJlX3BhcnNlKSAobmV0c25tcF9zZXNzaW9uICosIG5ldHNubXBfdHJhbnNwb3J0ICosCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZvaWQgKiwgaW50KSwKICAgICAgICAgICAgICBpbnQgKCpmcGFyc2UpIChuZXRzbm1wX3Nlc3Npb24gKiwgbmV0c25tcF9wZHUgKiwgdV9jaGFyICosCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZV90KSwKICAgICAgICAgICAgICBpbnQgKCpmcG9zdF9wYXJzZSkgKG5ldHNubXBfc2Vzc2lvbiAqLCBuZXRzbm1wX3BkdSAqLCBpbnQpLAogICAgICAgICAgICAgIGludCAoKmZidWlsZCkgKG5ldHNubXBfc2Vzc2lvbiAqLCBuZXRzbm1wX3BkdSAqLCB1X2NoYXIgKiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplX3QgKiksIGludCAoKmZyYnVpbGQpIChuZXRzbm1wX3Nlc3Npb24gKiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX3BkdSAqLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVfY2hhciAqKiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplX3QgKiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplX3QgKiksCiAgICAgICAgICAgICAgaW50ICgqZmNoZWNrKSAodV9jaGFyICosIHNpemVfdCksCiAgICAgICAgICAgICAgbmV0c25tcF9wZHUgKigqZmNyZWF0ZV9wZHUpIChuZXRzbm1wX3RyYW5zcG9ydCAqLCB2b2lkICosCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplX3QpKQp7CiAgICBzdHJ1Y3Qgc2Vzc2lvbl9saXN0ICpzbHA7CiAgICBzbHAgPSAoc3RydWN0IHNlc3Npb25fbGlzdCAqKSBzbm1wX3Nlc3NfYWRkX2V4KGluX3Nlc3Npb24sIHRyYW5zcG9ydCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZnByZV9wYXJzZSwgZnBhcnNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmcG9zdF9wYXJzZSwgZmJ1aWxkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmcmJ1aWxkLCBmY2hlY2ssCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZjcmVhdGVfcGR1KTsKICAgIGlmIChzbHAgPT0gTlVMTCkgewogICAgICAgIHJldHVybiBOVUxMOwogICAgfQoKICAgIHNubXBfcmVzX2xvY2soTVRfTElCUkFSWV9JRCwgTVRfTElCX1NFU1NJT04pOwogICAgc2xwLT5uZXh0ID0gU2Vzc2lvbnM7CiAgICBTZXNzaW9ucyA9IHNscDsKICAgIHNubXBfcmVzX3VubG9jayhNVF9MSUJSQVJZX0lELCBNVF9MSUJfU0VTU0lPTik7CgogICAgcmV0dXJuIChzbHAtPnNlc3Npb24pOwp9CgoKCnZvaWQgICAgICAgICAgICoKc25tcF9zZXNzX2FkZF9leChuZXRzbm1wX3Nlc3Npb24gKiBpbl9zZXNzaW9uLAogICAgICAgICAgICAgICAgIG5ldHNubXBfdHJhbnNwb3J0ICp0cmFuc3BvcnQsCiAgICAgICAgICAgICAgICAgaW50ICgqZnByZV9wYXJzZSkgKG5ldHNubXBfc2Vzc2lvbiAqLCBuZXRzbm1wX3RyYW5zcG9ydCAqLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2b2lkICosIGludCksCiAgICAgICAgICAgICAgICAgaW50ICgqZnBhcnNlKSAobmV0c25tcF9zZXNzaW9uICosIG5ldHNubXBfcGR1ICosIHVfY2hhciAqLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVfdCksCiAgICAgICAgICAgICAgICAgaW50ICgqZnBvc3RfcGFyc2UpIChuZXRzbm1wX3Nlc3Npb24gKiwgbmV0c25tcF9wZHUgKiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCksCiAgICAgICAgICAgICAgICAgaW50ICgqZmJ1aWxkKSAobmV0c25tcF9zZXNzaW9uICosIG5ldHNubXBfcGR1ICosIHVfY2hhciAqLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVfdCAqKSwKICAgICAgICAgICAgICAgICBpbnQgKCpmcmJ1aWxkKSAobmV0c25tcF9zZXNzaW9uICosIG5ldHNubXBfcGR1ICosCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVfY2hhciAqKiwgc2l6ZV90ICosIHNpemVfdCAqKSwKICAgICAgICAgICAgICAgICBpbnQgKCpmY2hlY2spICh1X2NoYXIgKiwgc2l6ZV90KSwKICAgICAgICAgICAgICAgICBuZXRzbm1wX3BkdSAqKCpmY3JlYXRlX3BkdSkgKG5ldHNubXBfdHJhbnNwb3J0ICosIHZvaWQgKiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVfdCkpCnsKICAgIHN0cnVjdCBzZXNzaW9uX2xpc3QgKnNscDsKICAgIGludCByYzsKICAgIAogICAgX2luaXRfc25tcCgpOwoKICAgIGlmICh0cmFuc3BvcnQgPT0gTlVMTCkKICAgICAgICByZXR1cm4gTlVMTDsKCiAgICBpZiAoaW5fc2Vzc2lvbiA9PSBOVUxMKSB7CiAgICAgICAgdHJhbnNwb3J0LT5mX2Nsb3NlKHRyYW5zcG9ydCk7CiAgICAgICAgbmV0c25tcF90cmFuc3BvcnRfZnJlZSh0cmFuc3BvcnQpOwogICAgICAgIHJldHVybiBOVUxMOwogICAgfQoKICAgIC8qIGlmIHRoZSB0cmFuc3BvcnQgaGFzbid0IGJlZW4gZnVsbHkgb3BlbmVkIHlldCwgb3BlbiBpdCBub3cgKi8KICAgIGlmICgocmMgPSBuZXRzbm1wX3Nlc3NfY29uZmlnX2FuZF9vcGVuX3RyYW5zcG9ydChpbl9zZXNzaW9uLCB0cmFuc3BvcnQpKQogICAgICAgICE9IFNOTVBFUlJfU1VDQ0VTUykgewogICAgICAgIHJldHVybiBOVUxMOwogICAgfQoKICAgIGlmICh0cmFuc3BvcnQtPmZfc2V0dXBfc2Vzc2lvbikgewogICAgICAgIGlmIChTTk1QRVJSX1NVQ0NFU1MgIT0KICAgICAgICAgICAgdHJhbnNwb3J0LT5mX3NldHVwX3Nlc3Npb24odHJhbnNwb3J0LCBpbl9zZXNzaW9uKSkgewogICAgICAgICAgICBuZXRzbm1wX3RyYW5zcG9ydF9mcmVlKHRyYW5zcG9ydCk7CiAgICAgICAgICAgIHJldHVybiBOVUxMOwogICAgICAgIH0KICAgIH0KICAgICAgICAKICAgICAgICAgICAgCiAgICBERUJVR01TR1RMKCgic25tcF9zZXNzX2FkZCIsICJmZCAlZFxuIiwgdHJhbnNwb3J0LT5zb2NrKSk7CgoKICAgIGlmICgoc2xwID0gc25tcF9zZXNzX2NvcHkoaW5fc2Vzc2lvbikpID09IE5VTEwpIHsKICAgICAgICB0cmFuc3BvcnQtPmZfY2xvc2UodHJhbnNwb3J0KTsKICAgICAgICBuZXRzbm1wX3RyYW5zcG9ydF9mcmVlKHRyYW5zcG9ydCk7CiAgICAgICAgcmV0dXJuIChOVUxMKTsKICAgIH0KCiAgICBzbHAtPnRyYW5zcG9ydCA9IHRyYW5zcG9ydDsKICAgIHNscC0+aW50ZXJuYWwtPmhvb2tfcHJlID0gZnByZV9wYXJzZTsKICAgIHNscC0+aW50ZXJuYWwtPmhvb2tfcGFyc2UgPSBmcGFyc2U7CiAgICBzbHAtPmludGVybmFsLT5ob29rX3Bvc3QgPSBmcG9zdF9wYXJzZTsKICAgIHNscC0+aW50ZXJuYWwtPmhvb2tfYnVpbGQgPSBmYnVpbGQ7CiAgICBzbHAtPmludGVybmFsLT5ob29rX3JlYWxsb2NfYnVpbGQgPSBmcmJ1aWxkOwogICAgc2xwLT5pbnRlcm5hbC0+Y2hlY2tfcGFja2V0ID0gZmNoZWNrOwogICAgc2xwLT5pbnRlcm5hbC0+aG9va19jcmVhdGVfcGR1ID0gZmNyZWF0ZV9wZHU7CgogICAgc2xwLT5zZXNzaW9uLT5yY3ZNc2dNYXhTaXplID0gdHJhbnNwb3J0LT5tc2dNYXhTaXplOwoKICAgIGlmIChzbHAtPnNlc3Npb24tPnZlcnNpb24gPT0gU05NUF9WRVJTSU9OXzMpIHsKICAgICAgICBERUJVR01TR1RMKCgic25tcF9zZXNzX2FkZCIsCiAgICAgICAgICAgICAgICAgICAgImFkZGluZyB2MyBzZXNzaW9uIC0tIG1heWJlIGVuZ2luZUlEIHByb2JlIG5vd1xuIikpOwogICAgICAgIGlmICghc25tcHYzX2VuZ2luZUlEX3Byb2JlKHNscCwgaW5fc2Vzc2lvbikpIHsKICAgICAgICAgICAgREVCVUdNU0dUTCgoInNubXBfc2Vzc19hZGQiLCAiZW5naW5lIElEIHByb2JlIGZhaWxlZFxuIikpOwogICAgICAgICAgICBzbm1wX3Nlc3NfY2xvc2Uoc2xwKTsKICAgICAgICAgICAgcmV0dXJuIE5VTEw7CiAgICAgICAgfQogICAgICAgIGlmIChjcmVhdGVfdXNlcl9mcm9tX3Nlc3Npb24oc2xwLT5zZXNzaW9uKSAhPSBTTk1QRVJSX1NVQ0NFU1MpIHsKICAgICAgICAgICAgaW5fc2Vzc2lvbi0+c19zbm1wX2Vycm5vID0gU05NUEVSUl9VTktOT1dOX1VTRVJfTkFNRTsKICAgICAgICAgICAgREVCVUdNU0dUTCgoInNubXBfYXBpIiwKICAgICAgICAgICAgICAgICAgICAgICAgInNubXBfc2Vzc19hZGQoKTogZmFpbGVkKDIpIHRvIGNyZWF0ZSBhIG5ldyB1c2VyIGZyb20gc2Vzc2lvblxuIikpOwogICAgICAgICAgICBzbm1wX3Nlc3NfY2xvc2Uoc2xwKTsKICAgICAgICAgICAgcmV0dXJuIE5VTEw7CiAgICAgICAgfQogICAgfQoKICAgIHNscC0+c2Vzc2lvbi0+ZmxhZ3MgJj0gflNOTVBfRkxBR1NfRE9OVF9QUk9CRTsKCiAgICByZXR1cm4gKHZvaWQgKikgc2xwOwp9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qICBlbmQgc25tcF9zZXNzX2FkZF9leCgpICAqLwoKCgp2b2lkICAgICAgICAgICAqCnNubXBfc2Vzc19hZGQobmV0c25tcF9zZXNzaW9uICogaW5fc2Vzc2lvbiwKICAgICAgICAgICAgICBuZXRzbm1wX3RyYW5zcG9ydCAqdHJhbnNwb3J0LAogICAgICAgICAgICAgIGludCAoKmZwcmVfcGFyc2UpIChuZXRzbm1wX3Nlc3Npb24gKiwgbmV0c25tcF90cmFuc3BvcnQgKiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdm9pZCAqLCBpbnQpLAogICAgICAgICAgICAgIGludCAoKmZwb3N0X3BhcnNlKSAobmV0c25tcF9zZXNzaW9uICosIG5ldHNubXBfcGR1ICosIGludCkpCnsKICAgIHJldHVybiBzbm1wX3Nlc3NfYWRkX2V4KGluX3Nlc3Npb24sIHRyYW5zcG9ydCwgZnByZV9wYXJzZSwgTlVMTCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZwb3N0X3BhcnNlLCBOVUxMLCBOVUxMLCBOVUxMLCBOVUxMKTsKfQoKCgp2b2lkICAgICAgICAgICAqCnNubXBfc2Vzc19vcGVuKG5ldHNubXBfc2Vzc2lvbiAqIHBzcykKewogICAgdm9pZCAgICAgICAgICAgKnB2b2lkOwogICAgcHZvaWQgPSBfc2Vzc19vcGVuKHBzcyk7CiAgICBpZiAoIXB2b2lkKSB7CiAgICAgICAgU0VUX1NOTVBfRVJST1IocHNzLT5zX3NubXBfZXJybm8pOwogICAgfQogICAgcmV0dXJuIHB2b2lkOwp9CgoKCi8qCiAqIGNyZWF0ZV91c2VyX2Zyb21fc2Vzc2lvbihuZXRzbm1wX3Nlc3Npb24gKnNlc3Npb24pOgogKiAKICogY3JlYXRlcyBhIHVzZXIgaW4gdGhlIHVzbSB0YWJsZSBmcm9tIHRoZSBpbmZvcm1hdGlvbiBpbiBhIHNlc3Npb24uCiAqIElmIHRoZSB1c2VyIGFscmVhZHkgZXhpc3RzLCBpdCBpcyB1cGRhdGVkIHdpdGggdGhlIGN1cnJlbnQKICogaW5mb3JtYXRpb24gZnJvbSB0aGUgc2Vzc2lvbgogKiAKICogUGFyYW1ldGVyczoKICogc2Vzc2lvbiAtLSBJTjogcG9pbnRlciB0byB0aGUgc2Vzc2lvbiB0byB1c2Ugd2hlbiBjcmVhdGluZyB0aGUgdXNlci4KICogCiAqIFJldHVybnM6CiAqIFNOTVBFUlJfU1VDQ0VTUwogKiBTTk1QRVJSX0dFTkVSUiAKICovCmludApjcmVhdGVfdXNlcl9mcm9tX3Nlc3Npb24obmV0c25tcF9zZXNzaW9uICogc2Vzc2lvbikKewogICAgc3RydWN0IHVzbVVzZXIgKnVzZXI7CiAgICBpbnQgICAgICAgICAgICAgdXNlcl9qdXN0X2NyZWF0ZWQgPSAwOwogICAgY2hhciAqY3A7CgogICAgLyoKICAgICAqIC0gZG9uJ3QgY3JlYXRlLWFub3RoZXIvY29weS1pbnRvIHVzZXIgZm9yIHRoaXMgc2Vzc2lvbiBieSBkZWZhdWx0CiAgICAgKiAtIGJhaWwgbm93IChubyBlcnJvcikgaWYgd2UgZG9uJ3QgaGF2ZSBhbiBlbmdpbmVJRAogICAgICovCiAgICBpZiAoU05NUF9GTEFHU19VU0VSX0NSRUFURUQgPT0gKHNlc3Npb24tPmZsYWdzICYgU05NUF9GTEFHU19VU0VSX0NSRUFURUQpIHx8CiAgICAgICAgc2Vzc2lvbi0+c2VjdXJpdHlNb2RlbCAhPSBTTk1QX1NFQ19NT0RFTF9VU00gfHwKICAgICAgICBzZXNzaW9uLT52ZXJzaW9uICE9IFNOTVBfVkVSU0lPTl8zIHx8CiAgICAgICAgc2Vzc2lvbi0+c2VjdXJpdHlOYW1lTGVuID09IDAgfHwKICAgICAgICBzZXNzaW9uLT5zZWN1cml0eUVuZ2luZUlETGVuID09IDApCiAgICAgICAgcmV0dXJuIFNOTVBFUlJfU1VDQ0VTUzsKCiAgICBzZXNzaW9uLT5mbGFncyB8PSBTTk1QX0ZMQUdTX1VTRVJfQ1JFQVRFRDsKCiAgICAvKgogICAgICogbm93IHRoYXQgd2UgaGF2ZSB0aGUgZW5naW5lSUQsIGNyZWF0ZSBhbiBlbnRyeSBpbiB0aGUgVVNNIGxpc3QKICAgICAqIGZvciB0aGlzIHVzZXIgdXNpbmcgdGhlIGluZm9ybWF0aW9uIGluIHRoZSBzZXNzaW9uIAogICAgICovCiAgICB1c2VyID0gdXNtX2dldF91c2VyX2Zyb21fbGlzdChzZXNzaW9uLT5zZWN1cml0eUVuZ2luZUlELAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2Vzc2lvbi0+c2VjdXJpdHlFbmdpbmVJRExlbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlc3Npb24tPnNlY3VyaXR5TmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVzbV9nZXRfdXNlckxpc3QoKSwgMCk7CiAgICBpZiAodXNlciA9PSBOVUxMKSB7CiAgICAgICAgREVCVUdNU0dUTCgoInNubXBfYXBpIiwgIkJ1aWxkaW5nIHVzZXIgJXMuLi5cbiIsCiAgICAgICAgICAgICAgICAgICAgc2Vzc2lvbi0+c2VjdXJpdHlOYW1lKSk7CiAgICAgICAgLyoKICAgICAgICAgKiB1c2VyIGRvZXNuJ3QgZXhpc3Qgc28gd2UgY3JlYXRlIGFuZCBhZGQgaXQgCiAgICAgICAgICovCiAgICAgICAgdXNlciA9IChzdHJ1Y3QgdXNtVXNlciAqKSBjYWxsb2MoMSwgc2l6ZW9mKHN0cnVjdCB1c21Vc2VyKSk7CiAgICAgICAgaWYgKHVzZXIgPT0gTlVMTCkKICAgICAgICAgICAgcmV0dXJuIFNOTVBFUlJfR0VORVJSOwoKICAgICAgICAvKgogICAgICAgICAqIGNvcHkgaW4gdGhlIHNlY3VyaXR5TmFtZSAKICAgICAgICAgKi8KICAgICAgICBpZiAoc2Vzc2lvbi0+c2VjdXJpdHlOYW1lKSB7CiAgICAgICAgICAgIHVzZXItPm5hbWUgPSBzdHJkdXAoc2Vzc2lvbi0+c2VjdXJpdHlOYW1lKTsKICAgICAgICAgICAgdXNlci0+c2VjTmFtZSA9IHN0cmR1cChzZXNzaW9uLT5zZWN1cml0eU5hbWUpOwogICAgICAgICAgICBpZiAodXNlci0+bmFtZSA9PSBOVUxMIHx8IHVzZXItPnNlY05hbWUgPT0gTlVMTCkgewogICAgICAgICAgICAgICAgdXNtX2ZyZWVfdXNlcih1c2VyKTsKICAgICAgICAgICAgICAgIHJldHVybiBTTk1QRVJSX0dFTkVSUjsKICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLyoKICAgICAgICAgKiBjb3B5IGluIHRoZSBlbmdpbmVJRCAKICAgICAgICAgKi8KICAgICAgICB1c2VyLT5lbmdpbmVJRCA9IG5ldHNubXBfbWVtZHVwKHNlc3Npb24tPnNlY3VyaXR5RW5naW5lSUQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXNzaW9uLT5zZWN1cml0eUVuZ2luZUlETGVuKTsKICAgICAgICBpZiAoIXVzZXItPmVuZ2luZUlEKSB7CiAgICAgICAgICAgIHVzbV9mcmVlX3VzZXIodXNlcik7CiAgICAgICAgICAgIHJldHVybiBTTk1QRVJSX0dFTkVSUjsKICAgICAgICB9CiAgICAgICAgdXNlci0+ZW5naW5lSURMZW4gPSBzZXNzaW9uLT5zZWN1cml0eUVuZ2luZUlETGVuOwoKICAgICAgICB1c2VyX2p1c3RfY3JlYXRlZCA9IDE7CiAgICB9CgogICAgLyoKICAgICAqIGNvcHkgdGhlIGF1dGggcHJvdG9jb2wgCiAgICAgKi8KICAgIGlmICh1c2VyLT5hdXRoUHJvdG9jb2wgPT0gTlVMTCAmJiBzZXNzaW9uLT5zZWN1cml0eUF1dGhQcm90byAhPSBOVUxMKSB7CiAgICAgICAgU05NUF9GUkVFKHVzZXItPmF1dGhQcm90b2NvbCk7CiAgICAgICAgdXNlci0+YXV0aFByb3RvY29sID0KICAgICAgICAgICAgc25tcF9kdXBsaWNhdGVfb2JqaWQoc2Vzc2lvbi0+c2VjdXJpdHlBdXRoUHJvdG8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlc3Npb24tPnNlY3VyaXR5QXV0aFByb3RvTGVuKTsKICAgICAgICBpZiAodXNlci0+YXV0aFByb3RvY29sID09IE5VTEwpIHsKICAgICAgICAgICAgdXNtX2ZyZWVfdXNlcih1c2VyKTsKICAgICAgICAgICAgcmV0dXJuIFNOTVBFUlJfR0VORVJSOwogICAgICAgIH0KICAgICAgICB1c2VyLT5hdXRoUHJvdG9jb2xMZW4gPSBzZXNzaW9uLT5zZWN1cml0eUF1dGhQcm90b0xlbjsKICAgIH0KCiAgICAvKgogICAgICogY29weSB0aGUgcHJpdiBwcm90b2NvbCAKICAgICAqLwogICAgaWYgKHVzZXItPnByaXZQcm90b2NvbCA9PSBOVUxMICYmIHNlc3Npb24tPnNlY3VyaXR5UHJpdlByb3RvICE9IE5VTEwpIHsKICAgICAgICBTTk1QX0ZSRUUodXNlci0+cHJpdlByb3RvY29sKTsKICAgICAgICB1c2VyLT5wcml2UHJvdG9jb2wgPQogICAgICAgICAgICBzbm1wX2R1cGxpY2F0ZV9vYmppZChzZXNzaW9uLT5zZWN1cml0eVByaXZQcm90bywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2Vzc2lvbi0+c2VjdXJpdHlQcml2UHJvdG9MZW4pOwogICAgICAgIGlmICh1c2VyLT5wcml2UHJvdG9jb2wgPT0gTlVMTCkgewogICAgICAgICAgICB1c21fZnJlZV91c2VyKHVzZXIpOwogICAgICAgICAgICByZXR1cm4gU05NUEVSUl9HRU5FUlI7CiAgICAgICAgfQogICAgICAgIHVzZXItPnByaXZQcm90b2NvbExlbiA9IHNlc3Npb24tPnNlY3VyaXR5UHJpdlByb3RvTGVuOwogICAgfQoKICAgIC8qCiAgICAgKiBjb3B5IGluIHRoZSBhdXRoZW50aWNhdGlvbiBLZXkuICBJZiBub3QgbG9jYWxpemVkLCBsb2NhbGl6ZSBpdCAKICAgICAqLwogICAgaWYgKHVzZXItPmF1dGhLZXkgPT0gTlVMTCkgewogICAgICAgIGlmIChzZXNzaW9uLT5zZWN1cml0eUF1dGhMb2NhbEtleSAhPSBOVUxMCiAgICAgICAgICAgICYmIHNlc3Npb24tPnNlY3VyaXR5QXV0aExvY2FsS2V5TGVuICE9IDApIHsKICAgICAgICAgICAgLyogYWxyZWFkeSBsb2NhbGl6ZWQga2V5IHBhc3NlZCBpbi4gIHVzZSBpdCAqLwogICAgICAgICAgICBTTk1QX0ZSRUUodXNlci0+YXV0aEtleSk7CiAgICAgICAgICAgIHVzZXItPmF1dGhLZXkgPSBuZXRzbm1wX21lbWR1cChzZXNzaW9uLT5zZWN1cml0eUF1dGhMb2NhbEtleSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlc3Npb24tPnNlY3VyaXR5QXV0aExvY2FsS2V5TGVuKTsKICAgICAgICAgICAgaWYgKCF1c2VyLT5hdXRoS2V5KSB7CiAgICAgICAgICAgICAgICB1c21fZnJlZV91c2VyKHVzZXIpOwogICAgICAgICAgICAgICAgcmV0dXJuIFNOTVBFUlJfR0VORVJSOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHVzZXItPmF1dGhLZXlMZW4gPSBzZXNzaW9uLT5zZWN1cml0eUF1dGhMb2NhbEtleUxlbjsKICAgICAgICB9IGVsc2UgaWYgKHNlc3Npb24tPnNlY3VyaXR5QXV0aEtleSAhPSBOVUxMCiAgICAgICAgICAgICAgICAgICAmJiBzZXNzaW9uLT5zZWN1cml0eUF1dGhLZXlMZW4gIT0gMCkgewogICAgICAgICAgICBTTk1QX0ZSRUUodXNlci0+YXV0aEtleSk7CiAgICAgICAgICAgIHVzZXItPmF1dGhLZXkgPSAodV9jaGFyICopIGNhbGxvYygxLCBVU01fTEVOR1RIX0tVX0hBU0hCTE9DSyk7CiAgICAgICAgICAgIGlmICh1c2VyLT5hdXRoS2V5ID09IE5VTEwpIHsKICAgICAgICAgICAgICAgIHVzbV9mcmVlX3VzZXIodXNlcik7CiAgICAgICAgICAgICAgICByZXR1cm4gU05NUEVSUl9HRU5FUlI7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdXNlci0+YXV0aEtleUxlbiA9IFVTTV9MRU5HVEhfS1VfSEFTSEJMT0NLOwogICAgICAgICAgICBpZiAoZ2VuZXJhdGVfa3VsKHVzZXItPmF1dGhQcm90b2NvbCwgdXNlci0+YXV0aFByb3RvY29sTGVuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlc3Npb24tPnNlY3VyaXR5RW5naW5lSUQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2Vzc2lvbi0+c2VjdXJpdHlFbmdpbmVJRExlbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXNzaW9uLT5zZWN1cml0eUF1dGhLZXksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2Vzc2lvbi0+c2VjdXJpdHlBdXRoS2V5TGVuLCB1c2VyLT5hdXRoS2V5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICZ1c2VyLT5hdXRoS2V5TGVuKSAhPSBTTk1QRVJSX1NVQ0NFU1MpIHsKICAgICAgICAgICAgICAgIHVzbV9mcmVlX3VzZXIodXNlcik7CiAgICAgICAgICAgICAgICByZXR1cm4gU05NUEVSUl9HRU5FUlI7CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgaWYgKChjcCA9IG5ldHNubXBfZHNfZ2V0X3N0cmluZyhORVRTTk1QX0RTX0xJQlJBUllfSUQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5FVFNOTVBfRFNfTElCX0FVVEhMT0NBTElaRURLRVkpKSkgewogICAgICAgICAgICBzaXplX3QgYnVmbGVuID0gVVNNX0FVVEhfS1VfTEVOOwogICAgICAgICAgICBTTk1QX0ZSRUUodXNlci0+YXV0aEtleSk7CiAgICAgICAgICAgIHVzZXItPmF1dGhLZXkgPSAodV9jaGFyICopbWFsbG9jKGJ1Zmxlbik7IC8qIG1heCBsZW5ndGggbmVlZGVkICovCiAgICAgICAgICAgIHVzZXItPmF1dGhLZXlMZW4gPSAwOwogICAgICAgICAgICAvKiBpdCB3aWxsIGJlIGEgaGV4IHN0cmluZyAqLwogICAgICAgICAgICBpZiAoIXNubXBfaGV4X3RvX2JpbmFyeSgmdXNlci0+YXV0aEtleSwgJmJ1ZmxlbiwgJnVzZXItPmF1dGhLZXlMZW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAsIGNwKSkgewogICAgICAgICAgICAgICAgdXNtX2ZyZWVfdXNlcih1c2VyKTsKICAgICAgICAgICAgICAgIHJldHVybiBTTk1QRVJSX0dFTkVSUjsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICAvKgogICAgICogY29weSBpbiB0aGUgcHJpdmFjeSBLZXkuICBJZiBub3QgbG9jYWxpemVkLCBsb2NhbGl6ZSBpdCAKICAgICAqLwogICAgaWYgKHVzZXItPnByaXZLZXkgPT0gTlVMTCkgewogICAgICAgIGlmIChzZXNzaW9uLT5zZWN1cml0eVByaXZMb2NhbEtleSAhPSBOVUxMCiAgICAgICAgICAgICYmIHNlc3Npb24tPnNlY3VyaXR5UHJpdkxvY2FsS2V5TGVuICE9IDApIHsKICAgICAgICAgICAgLyogYWxyZWFkeSBsb2NhbGl6ZWQga2V5IHBhc3NlZCBpbi4gIHVzZSBpdCAqLwogICAgICAgICAgICBTTk1QX0ZSRUUodXNlci0+cHJpdktleSk7CiAgICAgICAgICAgIHVzZXItPnByaXZLZXkgPSBuZXRzbm1wX21lbWR1cChzZXNzaW9uLT5zZWN1cml0eVByaXZMb2NhbEtleSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlc3Npb24tPnNlY3VyaXR5UHJpdkxvY2FsS2V5TGVuKTsKICAgICAgICAgICAgaWYgKCF1c2VyLT5wcml2S2V5KSB7CiAgICAgICAgICAgICAgICB1c21fZnJlZV91c2VyKHVzZXIpOwogICAgICAgICAgICAgICAgcmV0dXJuIFNOTVBFUlJfR0VORVJSOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHVzZXItPnByaXZLZXlMZW4gPSBzZXNzaW9uLT5zZWN1cml0eVByaXZMb2NhbEtleUxlbjsKICAgICAgICB9IGVsc2UgaWYgKHNlc3Npb24tPnNlY3VyaXR5UHJpdktleSAhPSBOVUxMCiAgICAgICAgICAgICAgICAgICAmJiBzZXNzaW9uLT5zZWN1cml0eVByaXZLZXlMZW4gIT0gMCkgewogICAgICAgICAgICBTTk1QX0ZSRUUodXNlci0+cHJpdktleSk7CiAgICAgICAgICAgIHVzZXItPnByaXZLZXkgPSAodV9jaGFyICopIGNhbGxvYygxLCBVU01fTEVOR1RIX0tVX0hBU0hCTE9DSyk7CiAgICAgICAgICAgIGlmICh1c2VyLT5wcml2S2V5ID09IE5VTEwpIHsKICAgICAgICAgICAgICAgIHVzbV9mcmVlX3VzZXIodXNlcik7CiAgICAgICAgICAgICAgICByZXR1cm4gU05NUEVSUl9HRU5FUlI7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgdXNlci0+cHJpdktleUxlbiA9IFVTTV9MRU5HVEhfS1VfSEFTSEJMT0NLOwogICAgICAgICAgICBpZiAoZ2VuZXJhdGVfa3VsKHVzZXItPmF1dGhQcm90b2NvbCwgdXNlci0+YXV0aFByb3RvY29sTGVuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNlc3Npb24tPnNlY3VyaXR5RW5naW5lSUQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2Vzc2lvbi0+c2VjdXJpdHlFbmdpbmVJRExlbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXNzaW9uLT5zZWN1cml0eVByaXZLZXksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2Vzc2lvbi0+c2VjdXJpdHlQcml2S2V5TGVuLCB1c2VyLT5wcml2S2V5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICZ1c2VyLT5wcml2S2V5TGVuKSAhPSBTTk1QRVJSX1NVQ0NFU1MpIHsKICAgICAgICAgICAgICAgIHVzbV9mcmVlX3VzZXIodXNlcik7CiAgICAgICAgICAgICAgICByZXR1cm4gU05NUEVSUl9HRU5FUlI7CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgaWYgKChjcCA9IG5ldHNubXBfZHNfZ2V0X3N0cmluZyhORVRTTk1QX0RTX0xJQlJBUllfSUQsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5FVFNOTVBfRFNfTElCX1BSSVZMT0NBTElaRURLRVkpKSkgewogICAgICAgICAgICBzaXplX3QgYnVmbGVuID0gVVNNX1BSSVZfS1VfTEVOOwogICAgICAgICAgICBTTk1QX0ZSRUUodXNlci0+cHJpdktleSk7CiAgICAgICAgICAgIHVzZXItPnByaXZLZXkgPSAodV9jaGFyICopbWFsbG9jKGJ1Zmxlbik7IC8qIG1heCBsZW5ndGggbmVlZGVkICovCiAgICAgICAgICAgIHVzZXItPnByaXZLZXlMZW4gPSAwOwogICAgICAgICAgICAvKiBpdCB3aWxsIGJlIGEgaGV4IHN0cmluZyAqLwogICAgICAgICAgICBpZiAoIXNubXBfaGV4X3RvX2JpbmFyeSgmdXNlci0+cHJpdktleSwgJmJ1ZmxlbiwgJnVzZXItPnByaXZLZXlMZW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDAsIGNwKSkgewogICAgICAgICAgICAgICAgdXNtX2ZyZWVfdXNlcih1c2VyKTsKICAgICAgICAgICAgICAgIHJldHVybiBTTk1QRVJSX0dFTkVSUjsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICBpZiAodXNlcl9qdXN0X2NyZWF0ZWQpIHsKICAgICAgICAvKgogICAgICAgICAqIGFkZCB0aGUgdXNlciBpbnRvIHRoZSBkYXRhYmFzZSAKICAgICAgICAgKi8KICAgICAgICB1c2VyLT51c2VyU3RhdHVzID0gUlNfQUNUSVZFOwogICAgICAgIHVzZXItPnVzZXJTdG9yYWdlVHlwZSA9IFNUX1JFQURPTkxZOwogICAgICAgIHVzbV9hZGRfdXNlcih1c2VyKTsKICAgIH0KCiAgICByZXR1cm4gU05NUEVSUl9TVUNDRVNTOwoKCn0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogZW5kIGNyZWF0ZV91c2VyX2Zyb21fc2Vzc2lvbigpICovCgovKgogKiAgRG8gYSAiZGVlcCBmcmVlKCkiIG9mIGEgbmV0c25tcF9zZXNzaW9uLgogKgogKiAgQ0FVVElPTjogIFNIT1VMRCBPTkxZIEJFIFVTRUQgRlJPTSBzbm1wX3Nlc3NfY2xvc2UoKSBPUiBTSU1JTEFSLgogKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChoZW5jZSBpdCBpcyBzdGF0aWMpCiAqLwoKc3RhdGljIHZvaWQKc25tcF9mcmVlX3Nlc3Npb24obmV0c25tcF9zZXNzaW9uICogcykKewogICAgaWYgKHMpIHsKICAgICAgICBTTk1QX0ZSRUUocy0+bG9jYWxuYW1lKTsKICAgICAgICBTTk1QX0ZSRUUocy0+cGVlcm5hbWUpOwogICAgICAgIFNOTVBfRlJFRShzLT5jb21tdW5pdHkpOwogICAgICAgIFNOTVBfRlJFRShzLT5jb250ZXh0RW5naW5lSUQpOwogICAgICAgIFNOTVBfRlJFRShzLT5jb250ZXh0TmFtZSk7CiAgICAgICAgU05NUF9GUkVFKHMtPnNlY3VyaXR5RW5naW5lSUQpOwogICAgICAgIFNOTVBfRlJFRShzLT5zZWN1cml0eU5hbWUpOwogICAgICAgIFNOTVBfRlJFRShzLT5zZWN1cml0eUF1dGhQcm90byk7CiAgICAgICAgU05NUF9GUkVFKHMtPnNlY3VyaXR5UHJpdlByb3RvKTsKICAgICAgICBTTk1QX0ZSRUUocy0+cGFyYW1OYW1lKTsKCiAgICAgICAgLyoKICAgICAgICAgKiBjbGVhciBzZXNzaW9uIGZyb20gYW55IGNhbGxiYWNrcwogICAgICAgICAqLwogICAgICAgIG5ldHNubXBfY2FsbGJhY2tfY2xlYXJfY2xpZW50X2FyZyhzLCAwLCAwKTsKCiAgICAgICAgZnJlZSgoY2hhciAqKSBzKTsKICAgIH0KfQoKLyoKICogQ2xvc2UgdGhlIGlucHV0IHNlc3Npb24uICBGcmVlcyBhbGwgZGF0YSBhbGxvY2F0ZWQgZm9yIHRoZSBzZXNzaW9uLAogKiBkZXF1ZXVlcyBhbnkgcGVuZGluZyByZXF1ZXN0cywgYW5kIGNsb3NlcyBhbnkgc29ja2V0cyBhbGxvY2F0ZWQgZm9yCiAqIHRoZSBzZXNzaW9uLiAgUmV0dXJucyAwIG9uIGVycm9yLCAxIG90aGVyd2lzZS4KICovCmludApzbm1wX3Nlc3NfY2xvc2Uodm9pZCAqc2Vzc3ApCnsKICAgIHN0cnVjdCBzZXNzaW9uX2xpc3QgKnNscCA9IChzdHJ1Y3Qgc2Vzc2lvbl9saXN0ICopIHNlc3NwOwogICAgbmV0c25tcF90cmFuc3BvcnQgKnRyYW5zcG9ydDsKICAgIHN0cnVjdCBzbm1wX2ludGVybmFsX3Nlc3Npb24gKmlzcDsKICAgIG5ldHNubXBfc2Vzc2lvbiAqc2VzcCA9IE5VTEw7CiAgICBzdHJ1Y3Qgc25tcF9zZWNtb2RfZGVmICpzcHRyOwoKICAgIGlmIChzbHAgPT0gTlVMTCkgewogICAgICAgIHJldHVybiAwOwogICAgfQoKICAgIGlmIChzbHAtPnNlc3Npb24gIT0gTlVMTCAmJgogICAgICAgIChzcHRyID0gZmluZF9zZWNfbW9kKHNscC0+c2Vzc2lvbi0+c2VjdXJpdHlNb2RlbCkpICE9IE5VTEwgJiYKICAgICAgICBzcHRyLT5zZXNzaW9uX2Nsb3NlICE9IE5VTEwpIHsKICAgICAgICAoKnNwdHItPnNlc3Npb25fY2xvc2UpIChzbHAtPnNlc3Npb24pOwogICAgfQoKICAgIGlzcCA9IHNscC0+aW50ZXJuYWw7CiAgICBzbHAtPmludGVybmFsID0gTlVMTDsKCiAgICBpZiAoaXNwKSB7CiAgICAgICAgbmV0c25tcF9yZXF1ZXN0X2xpc3QgKnJwLCAqb3JwOwoKICAgICAgICBTTk1QX0ZSRUUoaXNwLT5wYWNrZXQpOwoKICAgICAgICAvKgogICAgICAgICAqIEZyZWUgZWFjaCBlbGVtZW50IGluIHRoZSBpbnB1dCByZXF1ZXN0IGxpc3QuICAKICAgICAgICAgKi8KICAgICAgICBycCA9IGlzcC0+cmVxdWVzdHM7CiAgICAgICAgd2hpbGUgKHJwKSB7CiAgICAgICAgICAgIG9ycCA9IHJwOwogICAgICAgICAgICBycCA9IHJwLT5uZXh0X3JlcXVlc3Q7CiAgICAgICAgICAgIGlmIChvcnAtPmNhbGxiYWNrKSB7CiAgICAgICAgICAgICAgICBvcnAtPmNhbGxiYWNrKE5FVFNOTVBfQ0FMTEJBQ0tfT1BfVElNRURfT1VULAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzbHAtPnNlc3Npb24sIG9ycC0+cGR1LT5yZXFpZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3JwLT5wZHUsIG9ycC0+Y2JfZGF0YSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgc25tcF9mcmVlX3BkdShvcnAtPnBkdSk7CiAgICAgICAgICAgIGZyZWUoKGNoYXIgKikgb3JwKTsKICAgICAgICB9CgogICAgICAgIGZyZWUoKGNoYXIgKikgaXNwKTsKICAgIH0KCiAgICB0cmFuc3BvcnQgPSBzbHAtPnRyYW5zcG9ydDsKICAgIHNscC0+dHJhbnNwb3J0ID0gTlVMTDsKCiAgICBpZiAodHJhbnNwb3J0KSB7CiAgICAgICAgdHJhbnNwb3J0LT5mX2Nsb3NlKHRyYW5zcG9ydCk7CiAgICAgICAgbmV0c25tcF90cmFuc3BvcnRfZnJlZSh0cmFuc3BvcnQpOwogICAgfQoKICAgIHNlc3AgPSBzbHAtPnNlc3Npb247CiAgICBzbHAtPnNlc3Npb24gPSBOVUxMOwoKICAgIC8qCiAgICAgKiBUaGUgZm9sbG93aW5nIGlzIG5lY2Vzc2FyeSB0byBhdm9pZCBtZW1vcnkgbGVha2FnZSB3aGVuIGNsb3NpbmcgQWdlbnRYIAogICAgICogc2Vzc2lvbnMgdGhhdCBtYXkgaGF2ZSBtdWx0aXBsZSBzdWJzZXNzaW9ucy4gIFRoZXNlIGhhbmcgb2ZmIHRoZSBtYWluCiAgICAgKiBzZXNzaW9uIGF0IC0+c3Vic2Vzc2lvbiwgYW5kIGNoYWluIHRocm91Z2ggLT5uZXh0LiAgCiAgICAgKi8KCiAgICBpZiAoc2VzcCAhPSBOVUxMICYmIHNlc3AtPnN1YnNlc3Npb24gIT0gTlVMTCkgewogICAgICAgIG5ldHNubXBfc2Vzc2lvbiAqc3Vic2Vzc2lvbiA9IHNlc3AtPnN1YnNlc3Npb24sICp0bXBzdWI7CgogICAgICAgIHdoaWxlIChzdWJzZXNzaW9uICE9IE5VTEwpIHsKICAgICAgICAgICAgREVCVUdNU0dUTCgoInNubXBfc2Vzc19jbG9zZSIsCiAgICAgICAgICAgICAgICAgICAgICAgICJjbG9zaW5nIHNlc3Npb24gJXAsIHN1YnNlc3Npb24gJXBcbiIsIHNlc3AsCiAgICAgICAgICAgICAgICAgICAgICAgIHN1YnNlc3Npb24pKTsKICAgICAgICAgICAgdG1wc3ViID0gc3Vic2Vzc2lvbi0+bmV4dDsKICAgICAgICAgICAgc25tcF9mcmVlX3Nlc3Npb24oc3Vic2Vzc2lvbik7CiAgICAgICAgICAgIHN1YnNlc3Npb24gPSB0bXBzdWI7CiAgICAgICAgfQogICAgfQoKICAgIHNubXBfZnJlZV9zZXNzaW9uKHNlc3ApOwogICAgZnJlZSgoY2hhciAqKSBzbHApOwogICAgcmV0dXJuIDE7Cn0KCmludApzbm1wX2Nsb3NlKG5ldHNubXBfc2Vzc2lvbiAqIHNlc3Npb24pCnsKICAgIHN0cnVjdCBzZXNzaW9uX2xpc3QgKnNscCA9IE5VTEwsICpvc2xwID0gTlVMTDsKCiAgICB7ICAgICAgICAgICAgICAgICAgICAgICAgICAgLypNVENSSVRJQ0FMX1JFU09VUkNFICovCiAgICAgICAgc25tcF9yZXNfbG9jayhNVF9MSUJSQVJZX0lELCBNVF9MSUJfU0VTU0lPTik7CiAgICAgICAgaWYgKFNlc3Npb25zICYmIFNlc3Npb25zLT5zZXNzaW9uID09IHNlc3Npb24pIHsgLyogSWYgZmlyc3QgZW50cnkgKi8KICAgICAgICAgICAgc2xwID0gU2Vzc2lvbnM7CiAgICAgICAgICAgIFNlc3Npb25zID0gc2xwLT5uZXh0OwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGZvciAoc2xwID0gU2Vzc2lvbnM7IHNscDsgc2xwID0gc2xwLT5uZXh0KSB7CiAgICAgICAgICAgICAgICBpZiAoc2xwLT5zZXNzaW9uID09IHNlc3Npb24pIHsKICAgICAgICAgICAgICAgICAgICBpZiAob3NscCkgICAvKiBpZiB3ZSBmb3VuZCBlbnRyeSB0aGF0IHBvaW50cyBoZXJlICovCiAgICAgICAgICAgICAgICAgICAgICAgIG9zbHAtPm5leHQgPSBzbHAtPm5leHQ7IC8qIGxpbmsgYXJvdW5kIHRoaXMgZW50cnkgKi8KICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIG9zbHAgPSBzbHA7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgc25tcF9yZXNfdW5sb2NrKE1UX0xJQlJBUllfSUQsIE1UX0xJQl9TRVNTSU9OKTsKICAgIH0gICAgICAgICAgICAgICAgICAgICAgICAgICAvKkVORCBNVENSSVRJQ0FMX1JFU09VUkNFICovCiAgICBpZiAoc2xwID09IE5VTEwpIHsKICAgICAgICByZXR1cm4gMDsKICAgIH0KICAgIHJldHVybiBzbm1wX3Nlc3NfY2xvc2UoKHZvaWQgKikgc2xwKTsKfQoKaW50CnNubXBfY2xvc2Vfc2Vzc2lvbnModm9pZCkKewogICAgc3RydWN0IHNlc3Npb25fbGlzdCAqc2xwOwoKICAgIHNubXBfcmVzX2xvY2soTVRfTElCUkFSWV9JRCwgTVRfTElCX1NFU1NJT04pOwogICAgd2hpbGUgKFNlc3Npb25zKSB7CiAgICAgICAgc2xwID0gU2Vzc2lvbnM7CiAgICAgICAgU2Vzc2lvbnMgPSBTZXNzaW9ucy0+bmV4dDsKICAgICAgICBzbm1wX3Nlc3NfY2xvc2UoKHZvaWQgKikgc2xwKTsKICAgIH0KICAgIHNubXBfcmVzX3VubG9jayhNVF9MSUJSQVJZX0lELCBNVF9MSUJfU0VTU0lPTik7CiAgICByZXR1cm4gMTsKfQoKc3RhdGljIGludApzbm1wdjNfYnVpbGRfcHJvYmVfcGR1KG5ldHNubXBfcGR1ICoqcGR1KQp7CiAgICBzdHJ1Y3QgdXNtVXNlciAqdXNlcjsKCiAgICAvKgogICAgICogY3JlYXRlIHRoZSBwZHUgCiAgICAgKi8KICAgIGlmICghcGR1KQogICAgICAgIHJldHVybiAtMTsKICAgICpwZHUgPSBzbm1wX3BkdV9jcmVhdGUoU05NUF9NU0dfR0VUKTsKICAgIGlmICghKCpwZHUpKQogICAgICAgIHJldHVybiAtMTsKICAgICgqcGR1KS0+dmVyc2lvbiA9IFNOTVBfVkVSU0lPTl8zOwogICAgKCpwZHUpLT5zZWN1cml0eU5hbWUgPSBzdHJkdXAoIiIpOwogICAgKCpwZHUpLT5zZWN1cml0eU5hbWVMZW4gPSBzdHJsZW4oKCpwZHUpLT5zZWN1cml0eU5hbWUpOwogICAgKCpwZHUpLT5zZWN1cml0eUxldmVsID0gU05NUF9TRUNfTEVWRUxfTk9BVVRIOwogICAgKCpwZHUpLT5zZWN1cml0eU1vZGVsID0gU05NUF9TRUNfTU9ERUxfVVNNOwoKICAgIC8qCiAgICAgKiBjcmVhdGUgdGhlIGVtcHR5IHVzZXIgCiAgICAgKi8KICAgIHVzZXIgPSB1c21fZ2V0X3VzZXIoTlVMTCwgMCwgKCpwZHUpLT5zZWN1cml0eU5hbWUpOwogICAgaWYgKHVzZXIgPT0gTlVMTCkgewogICAgICAgIHVzZXIgPSAoc3RydWN0IHVzbVVzZXIgKikgY2FsbG9jKDEsIHNpemVvZihzdHJ1Y3QgdXNtVXNlcikpOwogICAgICAgIGlmICh1c2VyID09IE5VTEwpIHsKICAgICAgICAgICAgc25tcF9mcmVlX3BkdSgqcGR1KTsKICAgICAgICAgICAgKnBkdSA9IChuZXRzbm1wX3BkdSAqKSBOVUxMOwogICAgICAgICAgICByZXR1cm4gLTE7CiAgICAgICAgfQogICAgICAgIHVzZXItPm5hbWUgPSBzdHJkdXAoKCpwZHUpLT5zZWN1cml0eU5hbWUpOwogICAgICAgIHVzZXItPnNlY05hbWUgPSBzdHJkdXAoKCpwZHUpLT5zZWN1cml0eU5hbWUpOwogICAgICAgIHVzZXItPmF1dGhQcm90b2NvbExlbiA9IHNpemVvZih1c21Ob0F1dGhQcm90b2NvbCkgLyBzaXplb2Yob2lkKTsKICAgICAgICB1c2VyLT5hdXRoUHJvdG9jb2wgPQogICAgICAgICAgICBzbm1wX2R1cGxpY2F0ZV9vYmppZCh1c21Ob0F1dGhQcm90b2NvbCwgdXNlci0+YXV0aFByb3RvY29sTGVuKTsKICAgICAgICB1c2VyLT5wcml2UHJvdG9jb2xMZW4gPSBzaXplb2YodXNtTm9Qcml2UHJvdG9jb2wpIC8gc2l6ZW9mKG9pZCk7CiAgICAgICAgdXNlci0+cHJpdlByb3RvY29sID0KICAgICAgICAgICAgc25tcF9kdXBsaWNhdGVfb2JqaWQodXNtTm9Qcml2UHJvdG9jb2wsIHVzZXItPnByaXZQcm90b2NvbExlbik7CiAgICAgICAgdXNtX2FkZF91c2VyKHVzZXIpOwogICAgfQogICAgcmV0dXJuIDA7Cn0KCnN0YXRpYyB2b2lkCnNubXB2M19jYWxjX21zZ19mbGFncyhpbnQgc2VjX2xldmVsLCBpbnQgbXNnX2NvbW1hbmQsIHVfY2hhciAqIGZsYWdzKQp7CiAgICAqZmxhZ3MgPSAwOwogICAgaWYgKHNlY19sZXZlbCA9PSBTTk1QX1NFQ19MRVZFTF9BVVRITk9QUklWKQogICAgICAgICpmbGFncyA9IFNOTVBfTVNHX0ZMQUdfQVVUSF9CSVQ7CiAgICBlbHNlIGlmIChzZWNfbGV2ZWwgPT0gU05NUF9TRUNfTEVWRUxfQVVUSFBSSVYpCiAgICAgICAgKmZsYWdzID0gU05NUF9NU0dfRkxBR19BVVRIX0JJVCB8IFNOTVBfTVNHX0ZMQUdfUFJJVl9CSVQ7CgogICAgaWYgKFNOTVBfQ01EX0NPTkZJUk1FRChtc2dfY29tbWFuZCkpCiAgICAgICAgKmZsYWdzIHw9IFNOTVBfTVNHX0ZMQUdfUlBSVF9CSVQ7CgogICAgcmV0dXJuOwp9CgpzdGF0aWMgaW50CnNubXB2M192ZXJpZnlfbXNnKG5ldHNubXBfcmVxdWVzdF9saXN0ICpycCwgbmV0c25tcF9wZHUgKnBkdSkKewogICAgbmV0c25tcF9wZHUgICAgKnJwZHU7CgogICAgaWYgKCFycCB8fCAhcnAtPnBkdSB8fCAhcGR1KQogICAgICAgIHJldHVybiAwOwogICAgLyoKICAgICAqIFJlcG9ydHMgZG9uJ3QgaGF2ZSB0byBtYXRjaCBhbnl0aGluZyBhY2NvcmRpbmcgdG8gdGhlIHNwZWMgCiAgICAgKi8KICAgIGlmIChwZHUtPmNvbW1hbmQgPT0gU05NUF9NU0dfUkVQT1JUKQogICAgICAgIHJldHVybiAxOwogICAgcnBkdSA9IHJwLT5wZHU7CiAgICBpZiAocnAtPnJlcXVlc3RfaWQgIT0gcGR1LT5yZXFpZCB8fCBycGR1LT5yZXFpZCAhPSBwZHUtPnJlcWlkKQogICAgICAgIHJldHVybiAwOwogICAgaWYgKHJwZHUtPnZlcnNpb24gIT0gcGR1LT52ZXJzaW9uKQogICAgICAgIHJldHVybiAwOwogICAgaWYgKHJwZHUtPnNlY3VyaXR5TW9kZWwgIT0gcGR1LT5zZWN1cml0eU1vZGVsKQogICAgICAgIHJldHVybiAwOwogICAgaWYgKHJwZHUtPnNlY3VyaXR5TGV2ZWwgIT0gcGR1LT5zZWN1cml0eUxldmVsKQogICAgICAgIHJldHVybiAwOwoKICAgIGlmIChycGR1LT5jb250ZXh0RW5naW5lSURMZW4gIT0gcGR1LT5jb250ZXh0RW5naW5lSURMZW4gfHwKICAgICAgICBtZW1jbXAocnBkdS0+Y29udGV4dEVuZ2luZUlELCBwZHUtPmNvbnRleHRFbmdpbmVJRCwKICAgICAgICAgICAgICAgcGR1LT5jb250ZXh0RW5naW5lSURMZW4pKQogICAgICAgIHJldHVybiAwOwogICAgaWYgKHJwZHUtPmNvbnRleHROYW1lTGVuICE9IHBkdS0+Y29udGV4dE5hbWVMZW4gfHwKICAgICAgICBtZW1jbXAocnBkdS0+Y29udGV4dE5hbWUsIHBkdS0+Y29udGV4dE5hbWUsIHBkdS0+Y29udGV4dE5hbWVMZW4pKQogICAgICAgIHJldHVybiAwOwoKICAgIC8qIHR1bm5lbGVkIHRyYW5zcG9ydHMgZG9uJ3QgaGF2ZSBhIHNlY3VyaXR5RW5naW5lSUQuLi4gIHRoYXQncwogICAgICAgVVNNIHNwZWNpZmljIChhbmQgbWF5YmUgb3RoZXIgZnV0dXJlIG9uZXMpICovCiAgICBpZiAocGR1LT5zZWN1cml0eU1vZGVsID09IFNOTVBfU0VDX01PREVMX1VTTSAmJgogICAgICAgIChycGR1LT5zZWN1cml0eUVuZ2luZUlETGVuICE9IHBkdS0+c2VjdXJpdHlFbmdpbmVJRExlbiB8fAogICAgICAgIG1lbWNtcChycGR1LT5zZWN1cml0eUVuZ2luZUlELCBwZHUtPnNlY3VyaXR5RW5naW5lSUQsCiAgICAgICAgICAgICAgIHBkdS0+c2VjdXJpdHlFbmdpbmVJRExlbikpKQogICAgICAgIHJldHVybiAwOwoKICAgIC8qIHRoZSBzZWN1cml0eU5hbWUgbXVzdCBtYXRjaCB0aG91Z2ggcmVnYXJkbGVzcyBvZiBzZWNtb2RlbCAqLwogICAgaWYgKHJwZHUtPnNlY3VyaXR5TmFtZUxlbiAhPSBwZHUtPnNlY3VyaXR5TmFtZUxlbiB8fAogICAgICAgIG1lbWNtcChycGR1LT5zZWN1cml0eU5hbWUsIHBkdS0+c2VjdXJpdHlOYW1lLAogICAgICAgICAgICAgICBwZHUtPnNlY3VyaXR5TmFtZUxlbikpCiAgICAgICAgcmV0dXJuIDA7CiAgICByZXR1cm4gMTsKfQoKCi8qCiAqIFNOTVB2MwogKiAqIFRha2VzIGEgc2Vzc2lvbiBhbmQgYSBwZHUgYW5kIHNlcmlhbGl6ZXMgdGhlIEFTTiBQRFUgaW50byB0aGUgYXJlYQogKiAqIHBvaW50ZWQgdG8gYnkgcGFja2V0LiAgb3V0X2xlbmd0aCBpcyB0aGUgc2l6ZSBvZiB0aGUgZGF0YSBhcmVhIGF2YWlsYWJsZS4KICogKiBSZXR1cm5zIHRoZSBsZW5ndGggb2YgdGhlIGNvbXBsZXRlZCBwYWNrZXQgaW4gb3V0X2xlbmd0aC4gIElmIGFueSBlcnJvcnMKICogKiBvY2N1ciwgLTEgaXMgcmV0dXJuZWQuICBJZiBhbGwgZ29lcyB3ZWxsLCAwIGlzIHJldHVybmVkLgogKi8Kc3RhdGljIGludApzbm1wdjNfYnVpbGQodV9jaGFyICoqIHBrdCwgc2l6ZV90ICogcGt0X2xlbiwgc2l6ZV90ICogb2Zmc2V0LAogICAgICAgICAgICAgbmV0c25tcF9zZXNzaW9uICogc2Vzc2lvbiwgbmV0c25tcF9wZHUgKnBkdSkKewogICAgaW50ICAgICAgICAgICAgIHJldDsKCiAgICBzZXNzaW9uLT5zX3NubXBfZXJybm8gPSAwOwogICAgc2Vzc2lvbi0+c19lcnJubyA9IDA7CgogICAgLyoKICAgICAqIGRvIHZhbGlkYXRpb24gZm9yIFBEVSB0eXBlcyAKICAgICAqLwogICAgc3dpdGNoIChwZHUtPmNvbW1hbmQpIHsKICAgIGNhc2UgU05NUF9NU0dfUkVTUE9OU0U6CiAgICBjYXNlIFNOTVBfTVNHX1RSQVAyOgogICAgY2FzZSBTTk1QX01TR19SRVBPUlQ6CiAgICAgICAgbmV0c25tcF9hc3NlcnQoMCA9PSAocGR1LT5mbGFncyAmIFVDRF9NU0dfRkxBR19FWFBFQ1RfUkVTUE9OU0UpKTsKICAgICAgICAvKgogICAgICAgICAqIEZhbGx0aHJvdWdoIAogICAgICAgICAqLwogICAgY2FzZSBTTk1QX01TR19HRVQ6CiAgICBjYXNlIFNOTVBfTVNHX0dFVE5FWFQ6CiAgICBjYXNlIFNOTVBfTVNHX1NFVDoKICAgIGNhc2UgU05NUF9NU0dfSU5GT1JNOgogICAgICAgIGlmIChwZHUtPmVycnN0YXQgPT0gU05NUF9ERUZBVUxUX0VSUlNUQVQpCiAgICAgICAgICAgIHBkdS0+ZXJyc3RhdCA9IDA7CiAgICAgICAgaWYgKHBkdS0+ZXJyaW5kZXggPT0gU05NUF9ERUZBVUxUX0VSUklOREVYKQogICAgICAgICAgICBwZHUtPmVycmluZGV4ID0gMDsKICAgICAgICBicmVhazsKCiAgICBjYXNlIFNOTVBfTVNHX0dFVEJVTEs6CiAgICAgICAgaWYgKHBkdS0+bWF4X3JlcGV0aXRpb25zIDwgMCkgewogICAgICAgICAgICBzZXNzaW9uLT5zX3NubXBfZXJybm8gPSBTTk1QRVJSX0JBRF9SRVBFVElUSU9OUzsKICAgICAgICAgICAgcmV0dXJuIC0xOwogICAgICAgIH0KICAgICAgICBpZiAocGR1LT5ub25fcmVwZWF0ZXJzIDwgMCkgewogICAgICAgICAgICBzZXNzaW9uLT5zX3NubXBfZXJybm8gPSBTTk1QRVJSX0JBRF9SRVBFQVRFUlM7CiAgICAgICAgICAgIHJldHVybiAtMTsKICAgICAgICB9CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSBTTk1QX01TR19UUkFQOgogICAgICAgIHNlc3Npb24tPnNfc25tcF9lcnJubyA9IFNOTVBFUlJfVjFfSU5fVjI7CiAgICAgICAgcmV0dXJuIC0xOwoKICAgIGRlZmF1bHQ6CiAgICAgICAgc2Vzc2lvbi0+c19zbm1wX2Vycm5vID0gU05NUEVSUl9VTktOT1dOX1BEVTsKICAgICAgICByZXR1cm4gLTE7CiAgICB9CgogICAgLyogRG8gd2UgbmVlZCB0byBzZXQgdGhlIHNlc3Npb24gc2VjdXJpdHkgZW5naW5laWQ/ICovCiAgICBpZiAocGR1LT5zZWN1cml0eUVuZ2luZUlETGVuID09IDApIHsKICAgICAgICBpZiAoc2Vzc2lvbi0+c2VjdXJpdHlFbmdpbmVJRExlbikgewogICAgICAgICAgICBzbm1wdjNfY2xvbmVfZW5naW5lSUQoJnBkdS0+c2VjdXJpdHlFbmdpbmVJRCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZwZHUtPnNlY3VyaXR5RW5naW5lSURMZW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXNzaW9uLT5zZWN1cml0eUVuZ2luZUlELAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2Vzc2lvbi0+c2VjdXJpdHlFbmdpbmVJRExlbik7CiAgICAgICAgfQogICAgfQogICAgCiAgICAvKiBEbyB3ZSBuZWVkIHRvIHNldCB0aGUgc2Vzc2lvbiBjb250ZXh0IGVuZ2luZWlkPyAqLwogICAgaWYgKHBkdS0+Y29udGV4dEVuZ2luZUlETGVuID09IDApIHsKICAgICAgICBpZiAoc2Vzc2lvbi0+Y29udGV4dEVuZ2luZUlETGVuKSB7CiAgICAgICAgICAgIHNubXB2M19jbG9uZV9lbmdpbmVJRCgmcGR1LT5jb250ZXh0RW5naW5lSUQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmcGR1LT5jb250ZXh0RW5naW5lSURMZW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXNzaW9uLT5jb250ZXh0RW5naW5lSUQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXNzaW9uLT5jb250ZXh0RW5naW5lSURMZW4pOwogICAgICAgIH0gZWxzZSBpZiAocGR1LT5zZWN1cml0eUVuZ2luZUlETGVuKSB7CiAgICAgICAgICAgIHNubXB2M19jbG9uZV9lbmdpbmVJRCgmcGR1LT5jb250ZXh0RW5naW5lSUQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmcGR1LT5jb250ZXh0RW5naW5lSURMZW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwZHUtPnNlY3VyaXR5RW5naW5lSUQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwZHUtPnNlY3VyaXR5RW5naW5lSURMZW4pOwogICAgICAgIH0KICAgIH0KCiAgICBpZiAocGR1LT5jb250ZXh0TmFtZSA9PSBOVUxMKSB7CiAgICAgICAgaWYgKCFzZXNzaW9uLT5jb250ZXh0TmFtZSkgewogICAgICAgICAgICBzZXNzaW9uLT5zX3NubXBfZXJybm8gPSBTTk1QRVJSX0JBRF9DT05URVhUOwogICAgICAgICAgICByZXR1cm4gLTE7CiAgICAgICAgfQogICAgICAgIHBkdS0+Y29udGV4dE5hbWUgPSBzdHJkdXAoc2Vzc2lvbi0+Y29udGV4dE5hbWUpOwogICAgICAgIGlmIChwZHUtPmNvbnRleHROYW1lID09IE5VTEwpIHsKICAgICAgICAgICAgc2Vzc2lvbi0+c19zbm1wX2Vycm5vID0gU05NUEVSUl9HRU5FUlI7CiAgICAgICAgICAgIHJldHVybiAtMTsKICAgICAgICB9CiAgICAgICAgcGR1LT5jb250ZXh0TmFtZUxlbiA9IHNlc3Npb24tPmNvbnRleHROYW1lTGVuOwogICAgfQogICAgaWYgKHBkdS0+c2VjdXJpdHlNb2RlbCA9PSBTTk1QX0RFRkFVTFRfU0VDTU9ERUwpIHsKICAgICAgICBwZHUtPnNlY3VyaXR5TW9kZWwgPSBzZXNzaW9uLT5zZWN1cml0eU1vZGVsOwogICAgICAgIGlmIChwZHUtPnNlY3VyaXR5TW9kZWwgPT0gU05NUF9ERUZBVUxUX1NFQ01PREVMKSB7CiAgICAgICAgICAgIHBkdS0+c2VjdXJpdHlNb2RlbCA9IHNlX2ZpbmRfdmFsdWVfaW5fc2xpc3QoInNubXBfc2VjbW9kcyIsIG5ldHNubXBfZHNfZ2V0X3N0cmluZyhORVRTTk1QX0RTX0xJQlJBUllfSUQsIE5FVFNOTVBfRFNfTElCX1NFQ01PREVMKSk7CiAgICAgICAgICAgIAogICAgICAgICAgICBpZiAocGR1LT5zZWN1cml0eU1vZGVsIDw9IDApIHsKICAgICAgICAgICAgICAgIHBkdS0+c2VjdXJpdHlNb2RlbCA9IFNOTVBfU0VDX01PREVMX1VTTTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KICAgIGlmIChwZHUtPnNlY3VyaXR5TmFtZUxlbiA9PSAwICYmIHBkdS0+c2VjdXJpdHlOYW1lID09IE5VTEwpIHsKICAgICAgICBpZiAoc2Vzc2lvbi0+c2VjdXJpdHlNb2RlbCAhPSBTTk1QX1NFQ19NT0RFTF9UU00gJiYKICAgICAgICAgICAgc2Vzc2lvbi0+c2VjdXJpdHlOYW1lTGVuID09IDApIHsKICAgICAgICAgICAgc2Vzc2lvbi0+c19zbm1wX2Vycm5vID0gU05NUEVSUl9CQURfU0VDX05BTUU7CiAgICAgICAgICAgIHJldHVybiAtMTsKICAgICAgICB9CiAgICAgICAgaWYgKHNlc3Npb24tPnNlY3VyaXR5TmFtZSkgewogICAgICAgICAgICBwZHUtPnNlY3VyaXR5TmFtZSA9IHN0cmR1cChzZXNzaW9uLT5zZWN1cml0eU5hbWUpOwogICAgICAgICAgICBpZiAocGR1LT5zZWN1cml0eU5hbWUgPT0gTlVMTCkgewogICAgICAgICAgICAgICAgc2Vzc2lvbi0+c19zbm1wX2Vycm5vID0gU05NUEVSUl9HRU5FUlI7CiAgICAgICAgICAgICAgICByZXR1cm4gLTE7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcGR1LT5zZWN1cml0eU5hbWVMZW4gPSBzZXNzaW9uLT5zZWN1cml0eU5hbWVMZW47CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcGR1LT5zZWN1cml0eU5hbWUgPSBzdHJkdXAoIiIpOwogICAgICAgICAgICBzZXNzaW9uLT5zZWN1cml0eU5hbWUgPSBzdHJkdXAoIiIpOwogICAgICAgIH0KICAgIH0KICAgIGlmIChwZHUtPnNlY3VyaXR5TGV2ZWwgPT0gMCkgewogICAgICAgIGlmIChzZXNzaW9uLT5zZWN1cml0eUxldmVsID09IDApIHsKICAgICAgICAgICAgc2Vzc2lvbi0+c19zbm1wX2Vycm5vID0gU05NUEVSUl9CQURfU0VDX0xFVkVMOwogICAgICAgICAgICByZXR1cm4gLTE7CiAgICAgICAgfQogICAgICAgIHBkdS0+c2VjdXJpdHlMZXZlbCA9IHNlc3Npb24tPnNlY3VyaXR5TGV2ZWw7CiAgICB9CiAgICBERUJVR01TR1RMKCgic25tcF9idWlsZCIsCiAgICAgICAgICAgICAgICAiQnVpbGRpbmcgU05NUHYzIG1lc3NhZ2UgKHNlY05hbWU6XCIlc1wiLCBzZWNMZXZlbDolcykuLi5cbiIsCiAgICAgICAgICAgICAgICAoKHNlc3Npb24tPnNlY3VyaXR5TmFtZSkgPyAoY2hhciAqKSBzZXNzaW9uLT5zZWN1cml0eU5hbWUgOgogICAgICAgICAgICAgICAgICgocGR1LT5zZWN1cml0eU5hbWUpID8gKGNoYXIgKikgcGR1LT5zZWN1cml0eU5hbWUgOgogICAgICAgICAgICAgICAgICAiRVJST1I6IHVuZGVmaW5lZCIpKSwgc2VjTGV2ZWxOYW1lW3BkdS0+c2VjdXJpdHlMZXZlbF0pKTsKCiAgICBERUJVR0RVTVBTRUNUSU9OKCJzZW5kIiwgIlNOTVB2MyBNZXNzYWdlIik7CiNpZmRlZiBORVRTTk1QX1VTRV9SRVZFUlNFX0FTTkVOQ09ESU5HCiAgICBpZiAobmV0c25tcF9kc19nZXRfYm9vbGVhbihORVRTTk1QX0RTX0xJQlJBUllfSUQsIE5FVFNOTVBfRFNfTElCX1JFVkVSU0VfRU5DT0RFKSkgewogICAgICAgIHJldCA9IHNubXB2M19wYWNrZXRfcmVhbGxvY19yYnVpbGQocGt0LCBwa3RfbGVuLCBvZmZzZXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXNzaW9uLCBwZHUsIE5VTEwsIDApOwogICAgfSBlbHNlIHsKI2VuZGlmCiAgICAgICAgcmV0ID0gc25tcHYzX3BhY2tldF9idWlsZChzZXNzaW9uLCBwZHUsICpwa3QsIHBrdF9sZW4sIE5VTEwsIDApOwojaWZkZWYgTkVUU05NUF9VU0VfUkVWRVJTRV9BU05FTkNPRElORwogICAgfQojZW5kaWYKICAgIERFQlVHSU5ERU5UTEVTUygpOwogICAgaWYgKC0xICE9IHJldCkgewogICAgICAgIHNlc3Npb24tPnNfc25tcF9lcnJubyA9IHJldDsKICAgIH0KCiAgICByZXR1cm4gcmV0OwoKfSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBlbmQgc25tcHYzX2J1aWxkKCkgKi8KCgoKCnN0YXRpYyB1X2NoYXIgICoKc25tcHYzX2hlYWRlcl9idWlsZChuZXRzbm1wX3Nlc3Npb24gKiBzZXNzaW9uLCBuZXRzbm1wX3BkdSAqcGR1LAogICAgICAgICAgICAgICAgICAgIHVfY2hhciAqIHBhY2tldCwgc2l6ZV90ICogb3V0X2xlbmd0aCwKICAgICAgICAgICAgICAgICAgICBzaXplX3QgbGVuZ3RoLCB1X2NoYXIgKiogbXNnX2hkcl9lKQp7CiAgICB1X2NoYXIgICAgICAgICAqZ2xvYmFsX2hkciwgKmdsb2JhbF9oZHJfZTsKICAgIHVfY2hhciAgICAgICAgICpjcDsKICAgIHVfY2hhciAgICAgICAgICBtc2dfZmxhZ3M7CiAgICBsb25nICAgICAgICAgICAgbWF4X3NpemU7CiAgICBsb25nICAgICAgICAgICAgc2VjX21vZGVsOwogICAgdV9jaGFyICAgICAgICAgKnBiLCAqcGIwZTsKCiAgICAvKgogICAgICogU2F2ZSBjdXJyZW50IGxvY2F0aW9uIGFuZCBidWlsZCBTRVFVRU5DRSB0YWcgYW5kIGxlbmd0aCBwbGFjZWhvbGRlcgogICAgICogKiBmb3IgU05NUCBtZXNzYWdlIHNlcXVlbmNlIChhY3R1YWwgbGVuZ3RoIGluc2VydGVkIGxhdGVyKQogICAgICovCiAgICBjcCA9IGFzbl9idWlsZF9zZXF1ZW5jZShwYWNrZXQsIG91dF9sZW5ndGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAodV9jaGFyKSAoQVNOX1NFUVVFTkNFIHwgQVNOX0NPTlNUUlVDVE9SKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxlbmd0aCk7CiAgICBpZiAoY3AgPT0gTlVMTCkKICAgICAgICByZXR1cm4gTlVMTDsKICAgIGlmIChtc2dfaGRyX2UgIT0gTlVMTCkKICAgICAgICAqbXNnX2hkcl9lID0gY3A7CiAgICBwYjBlID0gY3A7CgoKICAgIC8qCiAgICAgKiBzdG9yZSB0aGUgdmVyc2lvbiBmaWVsZCAtIG1zZ1ZlcnNpb24KICAgICAqLwogICAgREVCVUdEVU1QSEVBREVSKCJzZW5kIiwgIlNOTVAgVmVyc2lvbiBOdW1iZXIiKTsKICAgIGNwID0gYXNuX2J1aWxkX2ludChjcCwgb3V0X2xlbmd0aCwKICAgICAgICAgICAgICAgICAgICAgICAodV9jaGFyKSAoQVNOX1VOSVZFUlNBTCB8IEFTTl9QUklNSVRJVkUgfAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBU05fSU5URUdFUiksIChsb25nICopICZwZHUtPnZlcnNpb24sCiAgICAgICAgICAgICAgICAgICAgICAgc2l6ZW9mKHBkdS0+dmVyc2lvbikpOwogICAgREVCVUdJTkRFTlRMRVNTKCk7CiAgICBpZiAoY3AgPT0gTlVMTCkKICAgICAgICByZXR1cm4gTlVMTDsKCiAgICBnbG9iYWxfaGRyID0gY3A7CiAgICAvKgogICAgICogbXNnR2xvYmFsRGF0YSBIZWFkZXJEYXRhIAogICAgICovCiAgICBERUJVR0RVTVBTRUNUSU9OKCJzZW5kIiwgIm1zZ0dsb2JhbERhdGEiKTsKICAgIGNwID0gYXNuX2J1aWxkX3NlcXVlbmNlKGNwLCBvdXRfbGVuZ3RoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgKHVfY2hhcikgKEFTTl9TRVFVRU5DRSB8IEFTTl9DT05TVFJVQ1RPUiksIDApOwogICAgaWYgKGNwID09IE5VTEwpCiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICBnbG9iYWxfaGRyX2UgPSBjcDsKCgogICAgLyoKICAgICAqIG1zZ0lEIAogICAgICovCiAgICBERUJVR0RVTVBIRUFERVIoInNlbmQiLCAibXNnSUQiKTsKICAgIGNwID0gYXNuX2J1aWxkX2ludChjcCwgb3V0X2xlbmd0aCwKICAgICAgICAgICAgICAgICAgICAgICAodV9jaGFyKSAoQVNOX1VOSVZFUlNBTCB8IEFTTl9QUklNSVRJVkUgfAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBU05fSU5URUdFUiksICZwZHUtPm1zZ2lkLAogICAgICAgICAgICAgICAgICAgICAgIHNpemVvZihwZHUtPm1zZ2lkKSk7CiAgICBERUJVR0lOREVOVExFU1MoKTsKICAgIGlmIChjcCA9PSBOVUxMKQogICAgICAgIHJldHVybiBOVUxMOwoKICAgIC8qCiAgICAgKiBtc2dNYXhTaXplIAogICAgICovCiAgICBtYXhfc2l6ZSA9IHNlc3Npb24tPnJjdk1zZ01heFNpemU7CiAgICBERUJVR0RVTVBIRUFERVIoInNlbmQiLCAibXNnTWF4U2l6ZSIpOwogICAgY3AgPSBhc25fYnVpbGRfaW50KGNwLCBvdXRfbGVuZ3RoLAogICAgICAgICAgICAgICAgICAgICAgICh1X2NoYXIpIChBU05fVU5JVkVSU0FMIHwgQVNOX1BSSU1JVElWRSB8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFTTl9JTlRFR0VSKSwgJm1heF9zaXplLAogICAgICAgICAgICAgICAgICAgICAgIHNpemVvZihtYXhfc2l6ZSkpOwogICAgREVCVUdJTkRFTlRMRVNTKCk7CiAgICBpZiAoY3AgPT0gTlVMTCkKICAgICAgICByZXR1cm4gTlVMTDsKCiAgICAvKgogICAgICogbXNnRmxhZ3MgCiAgICAgKi8KICAgIHNubXB2M19jYWxjX21zZ19mbGFncyhwZHUtPnNlY3VyaXR5TGV2ZWwsIHBkdS0+Y29tbWFuZCwgJm1zZ19mbGFncyk7CiAgICBERUJVR0RVTVBIRUFERVIoInNlbmQiLCAibXNnRmxhZ3MiKTsKICAgIGNwID0gYXNuX2J1aWxkX3N0cmluZyhjcCwgb3V0X2xlbmd0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAodV9jaGFyKSAoQVNOX1VOSVZFUlNBTCB8IEFTTl9QUklNSVRJVkUgfAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBU05fT0NURVRfU1RSKSwgJm1zZ19mbGFncywKICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplb2YobXNnX2ZsYWdzKSk7CiAgICBERUJVR0lOREVOVExFU1MoKTsKICAgIGlmIChjcCA9PSBOVUxMKQogICAgICAgIHJldHVybiBOVUxMOwoKICAgIC8qCiAgICAgKiBtc2dTZWN1cml0eU1vZGVsIAogICAgICovCiAgICBzZWNfbW9kZWwgPSBwZHUtPnNlY3VyaXR5TW9kZWw7CiAgICBERUJVR0RVTVBIRUFERVIoInNlbmQiLCAibXNnU2VjdXJpdHlNb2RlbCIpOwogICAgY3AgPSBhc25fYnVpbGRfaW50KGNwLCBvdXRfbGVuZ3RoLAogICAgICAgICAgICAgICAgICAgICAgICh1X2NoYXIpIChBU05fVU5JVkVSU0FMIHwgQVNOX1BSSU1JVElWRSB8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFTTl9JTlRFR0VSKSwgJnNlY19tb2RlbCwKICAgICAgICAgICAgICAgICAgICAgICBzaXplb2Yoc2VjX21vZGVsKSk7CiAgICBERUJVR0lOREVOVEFERCgtNCk7ICAgICAgICAgLyogcmV0dXJuIGZyb20gZ2xvYmFsIGRhdGEgaW5kZW50ICovCiAgICBpZiAoY3AgPT0gTlVMTCkKICAgICAgICByZXR1cm4gTlVMTDsKCgogICAgLyoKICAgICAqIGluc2VydCBhY3R1YWwgbGVuZ3RoIG9mIGdsb2JhbERhdGEKICAgICAqLwogICAgcGIgPSBhc25fYnVpbGRfc2VxdWVuY2UoZ2xvYmFsX2hkciwgb3V0X2xlbmd0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICh1X2NoYXIpIChBU05fU0VRVUVOQ0UgfCBBU05fQ09OU1RSVUNUT1IpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgY3AgLSBnbG9iYWxfaGRyX2UpOwogICAgaWYgKHBiID09IE5VTEwpCiAgICAgICAgcmV0dXJuIE5VTEw7CgoKICAgIC8qCiAgICAgKiBpbnNlcnQgdGhlIGFjdHVhbCBsZW5ndGggb2YgdGhlIGVudGlyZSBwYWNrZXQKICAgICAqLwogICAgcGIgPSBhc25fYnVpbGRfc2VxdWVuY2UocGFja2V0LCBvdXRfbGVuZ3RoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgKHVfY2hhcikgKEFTTl9TRVFVRU5DRSB8IEFTTl9DT05TVFJVQ1RPUiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZW5ndGggKyAoY3AgLSBwYjBlKSk7CiAgICBpZiAocGIgPT0gTlVMTCkKICAgICAgICByZXR1cm4gTlVMTDsKCiAgICByZXR1cm4gY3A7Cgp9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIGVuZCBzbm1wdjNfaGVhZGVyX2J1aWxkKCkgKi8KCiNpZmRlZiBORVRTTk1QX1VTRV9SRVZFUlNFX0FTTkVOQ09ESU5HCgppbnQKc25tcHYzX2hlYWRlcl9yZWFsbG9jX3JidWlsZCh1X2NoYXIgKiogcGt0LCBzaXplX3QgKiBwa3RfbGVuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVfdCAqIG9mZnNldCwgbmV0c25tcF9zZXNzaW9uICogc2Vzc2lvbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX3BkdSAqcGR1KQp7CiAgICBzaXplX3QgICAgICAgICAgc3RhcnRfb2Zmc2V0ID0gKm9mZnNldDsKICAgIHVfY2hhciAgICAgICAgICBtc2dfZmxhZ3M7CiAgICBsb25nICAgICAgICAgICAgbWF4X3NpemUsIHNlY19tb2RlbDsKICAgIGludCAgICAgICAgICAgICByYyA9IDA7CgogICAgLyoKICAgICAqIG1zZ1NlY3VyaXR5TW9kZWwuICAKICAgICAqLwogICAgc2VjX21vZGVsID0gcGR1LT5zZWN1cml0eU1vZGVsOwogICAgREVCVUdEVU1QSEVBREVSKCJzZW5kIiwgIm1zZ1NlY3VyaXR5TW9kZWwiKTsKICAgIHJjID0gYXNuX3JlYWxsb2NfcmJ1aWxkX2ludChwa3QsIHBrdF9sZW4sIG9mZnNldCwgMSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodV9jaGFyKSAoQVNOX1VOSVZFUlNBTCB8IEFTTl9QUklNSVRJVkUgfAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBU05fSU5URUdFUiksICZzZWNfbW9kZWwsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZW9mKHNlY19tb2RlbCkpOwogICAgREVCVUdJTkRFTlRMRVNTKCk7CiAgICBpZiAocmMgPT0gMCkgewogICAgICAgIHJldHVybiAwOwogICAgfQoKICAgIC8qCiAgICAgKiBtc2dGbGFncy4gIAogICAgICovCiAgICBzbm1wdjNfY2FsY19tc2dfZmxhZ3MocGR1LT5zZWN1cml0eUxldmVsLCBwZHUtPmNvbW1hbmQsICZtc2dfZmxhZ3MpOwogICAgREVCVUdEVU1QSEVBREVSKCJzZW5kIiwgIm1zZ0ZsYWdzIik7CiAgICByYyA9IGFzbl9yZWFsbG9jX3JidWlsZF9zdHJpbmcocGt0LCBwa3RfbGVuLCBvZmZzZXQsIDEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHVfY2hhcikgKEFTTl9VTklWRVJTQUwgfCBBU05fUFJJTUlUSVZFCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgQVNOX09DVEVUX1NUUiksICZtc2dfZmxhZ3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZW9mKG1zZ19mbGFncykpOwogICAgREVCVUdJTkRFTlRMRVNTKCk7CiAgICBpZiAocmMgPT0gMCkgewogICAgICAgIHJldHVybiAwOwogICAgfQoKICAgIC8qCiAgICAgKiBtc2dNYXhTaXplLiAgCiAgICAgKi8KICAgIG1heF9zaXplID0gc2Vzc2lvbi0+cmN2TXNnTWF4U2l6ZTsKICAgIERFQlVHRFVNUEhFQURFUigic2VuZCIsICJtc2dNYXhTaXplIik7CiAgICByYyA9IGFzbl9yZWFsbG9jX3JidWlsZF9pbnQocGt0LCBwa3RfbGVuLCBvZmZzZXQsIDEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHVfY2hhcikgKEFTTl9VTklWRVJTQUwgfCBBU05fUFJJTUlUSVZFIHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQVNOX0lOVEVHRVIpLCAmbWF4X3NpemUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZW9mKG1heF9zaXplKSk7CiAgICBERUJVR0lOREVOVExFU1MoKTsKICAgIGlmIChyYyA9PSAwKSB7CiAgICAgICAgcmV0dXJuIDA7CiAgICB9CgogICAgLyoKICAgICAqIG1zZ0lELiAgCiAgICAgKi8KICAgIERFQlVHRFVNUEhFQURFUigic2VuZCIsICJtc2dJRCIpOwogICAgcmMgPSBhc25fcmVhbGxvY19yYnVpbGRfaW50KHBrdCwgcGt0X2xlbiwgb2Zmc2V0LCAxLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh1X2NoYXIpIChBU05fVU5JVkVSU0FMIHwgQVNOX1BSSU1JVElWRSB8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFTTl9JTlRFR0VSKSwgJnBkdS0+bXNnaWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZW9mKHBkdS0+bXNnaWQpKTsKICAgIERFQlVHSU5ERU5UTEVTUygpOwogICAgaWYgKHJjID09IDApIHsKICAgICAgICByZXR1cm4gMDsKICAgIH0KCiAgICAvKgogICAgICogR2xvYmFsIGRhdGEgc2VxdWVuY2UuICAKICAgICAqLwogICAgcmMgPSBhc25fcmVhbGxvY19yYnVpbGRfc2VxdWVuY2UocGt0LCBwa3RfbGVuLCBvZmZzZXQsIDEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodV9jaGFyKSAoQVNOX1NFUVVFTkNFIHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBU05fQ09OU1RSVUNUT1IpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKm9mZnNldCAtIHN0YXJ0X29mZnNldCk7CiAgICBpZiAocmMgPT0gMCkgewogICAgICAgIHJldHVybiAwOwogICAgfQoKICAgIC8qCiAgICAgKiBTdG9yZSB0aGUgdmVyc2lvbiBmaWVsZCAtIG1zZ1ZlcnNpb24uICAKICAgICAqLwogICAgREVCVUdEVU1QSEVBREVSKCJzZW5kIiwgIlNOTVAgVmVyc2lvbiBOdW1iZXIiKTsKICAgIHJjID0gYXNuX3JlYWxsb2NfcmJ1aWxkX2ludChwa3QsIHBrdF9sZW4sIG9mZnNldCwgMSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodV9jaGFyKSAoQVNOX1VOSVZFUlNBTCB8IEFTTl9QUklNSVRJVkUgfAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBU05fSU5URUdFUiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGxvbmcgKikgJnBkdS0+dmVyc2lvbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplb2YocGR1LT52ZXJzaW9uKSk7CiAgICBERUJVR0lOREVOVExFU1MoKTsKICAgIHJldHVybiByYzsKfSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBlbmQgc25tcHYzX2hlYWRlcl9yZWFsbG9jX3JidWlsZCgpICovCiNlbmRpZiAgICAgICAgICAgICAgICAgICAgICAgICAgLyogTkVUU05NUF9VU0VfUkVWRVJTRV9BU05FTkNPRElORyAqLwoKc3RhdGljIHVfY2hhciAgKgpzbm1wdjNfc2NvcGVkUERVX2hlYWRlcl9idWlsZChuZXRzbm1wX3BkdSAqcGR1LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1X2NoYXIgKiBwYWNrZXQsIHNpemVfdCAqIG91dF9sZW5ndGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVfY2hhciAqKiBzcGR1X2UpCnsKICAgIHVfY2hhciAgICAgICAgICpzY29wZWRQZHUsICpwYjsKCiAgICBwYiA9IHNjb3BlZFBkdSA9IHBhY2tldDsKICAgIHBiID0gYXNuX2J1aWxkX3NlcXVlbmNlKHBiLCBvdXRfbGVuZ3RoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgKHVfY2hhcikgKEFTTl9TRVFVRU5DRSB8IEFTTl9DT05TVFJVQ1RPUiksIDApOwogICAgaWYgKHBiID09IE5VTEwpCiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICBpZiAoc3BkdV9lKQogICAgICAgICpzcGR1X2UgPSBwYjsKCiAgICBERUJVR0RVTVBIRUFERVIoInNlbmQiLCAiY29udGV4dEVuZ2luZUlEIik7CiAgICBwYiA9IGFzbl9idWlsZF9zdHJpbmcocGIsIG91dF9sZW5ndGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgKEFTTl9VTklWRVJTQUwgfCBBU05fUFJJTUlUSVZFIHwgQVNOX09DVEVUX1NUUiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgcGR1LT5jb250ZXh0RW5naW5lSUQsIHBkdS0+Y29udGV4dEVuZ2luZUlETGVuKTsKICAgIERFQlVHSU5ERU5UTEVTUygpOwogICAgaWYgKHBiID09IE5VTEwpCiAgICAgICAgcmV0dXJuIE5VTEw7CgogICAgREVCVUdEVU1QSEVBREVSKCJzZW5kIiwgImNvbnRleHROYW1lIik7CiAgICBwYiA9IGFzbl9idWlsZF9zdHJpbmcocGIsIG91dF9sZW5ndGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgKEFTTl9VTklWRVJTQUwgfCBBU05fUFJJTUlUSVZFIHwgQVNOX09DVEVUX1NUUiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgKHVfY2hhciAqKSBwZHUtPmNvbnRleHROYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgIHBkdS0+Y29udGV4dE5hbWVMZW4pOwogICAgREVCVUdJTkRFTlRMRVNTKCk7CiAgICBpZiAocGIgPT0gTlVMTCkKICAgICAgICByZXR1cm4gTlVMTDsKCiAgICByZXR1cm4gcGI7Cgp9ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIGVuZCBzbm1wdjNfc2NvcGVkUERVX2hlYWRlcl9idWlsZCgpICovCgoKI2lmZGVmIE5FVFNOTVBfVVNFX1JFVkVSU0VfQVNORU5DT0RJTkcKaW50CnNubXB2M19zY29wZWRQRFVfaGVhZGVyX3JlYWxsb2NfcmJ1aWxkKHVfY2hhciAqKiBwa3QsIHNpemVfdCAqIHBrdF9sZW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVfdCAqIG9mZnNldCwgbmV0c25tcF9wZHUgKnBkdSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZV90IGJvZHlfbGVuKQp7CiAgICBzaXplX3QgICAgICAgICAgc3RhcnRfb2Zmc2V0ID0gKm9mZnNldDsKICAgIGludCAgICAgICAgICAgICByYyA9IDA7CgogICAgLyoKICAgICAqIGNvbnRleHROYW1lLiAgCiAgICAgKi8KICAgIERFQlVHRFVNUEhFQURFUigic2VuZCIsICJjb250ZXh0TmFtZSIpOwogICAgcmMgPSBhc25fcmVhbGxvY19yYnVpbGRfc3RyaW5nKHBrdCwgcGt0X2xlbiwgb2Zmc2V0LCAxLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh1X2NoYXIpIChBU05fVU5JVkVSU0FMIHwgQVNOX1BSSU1JVElWRQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IEFTTl9PQ1RFVF9TVFIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh1X2NoYXIgKikgcGR1LT5jb250ZXh0TmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwZHUtPmNvbnRleHROYW1lTGVuKTsKICAgIERFQlVHSU5ERU5UTEVTUygpOwogICAgaWYgKHJjID09IDApIHsKICAgICAgICByZXR1cm4gMDsKICAgIH0KCiAgICAvKgogICAgICogY29udGV4dEVuZ2luZUlELiAgCiAgICAgKi8KICAgIERFQlVHRFVNUEhFQURFUigic2VuZCIsICJjb250ZXh0RW5naW5lSUQiKTsKICAgIHJjID0gYXNuX3JlYWxsb2NfcmJ1aWxkX3N0cmluZyhwa3QsIHBrdF9sZW4sIG9mZnNldCwgMSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodV9jaGFyKSAoQVNOX1VOSVZFUlNBTCB8IEFTTl9QUklNSVRJVkUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBBU05fT0NURVRfU1RSKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwZHUtPmNvbnRleHRFbmdpbmVJRCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwZHUtPmNvbnRleHRFbmdpbmVJRExlbik7CiAgICBERUJVR0lOREVOVExFU1MoKTsKICAgIGlmIChyYyA9PSAwKSB7CiAgICAgICAgcmV0dXJuIDA7CiAgICB9CgogICAgcmMgPSBhc25fcmVhbGxvY19yYnVpbGRfc2VxdWVuY2UocGt0LCBwa3RfbGVuLCBvZmZzZXQsIDEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodV9jaGFyKSAoQVNOX1NFUVVFTkNFIHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBU05fQ09OU1RSVUNUT1IpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKm9mZnNldCAtIHN0YXJ0X29mZnNldCArIGJvZHlfbGVuKTsKCiAgICByZXR1cm4gcmM7Cn0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogZW5kIHNubXB2M19zY29wZWRQRFVfaGVhZGVyX3JlYWxsb2NfcmJ1aWxkKCkgKi8KI2VuZGlmICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBORVRTTk1QX1VTRV9SRVZFUlNFX0FTTkVOQ09ESU5HICovCgojaWZkZWYgTkVUU05NUF9VU0VfUkVWRVJTRV9BU05FTkNPRElORwovKgogKiByZXR1cm5zIDAgaWYgc3VjY2VzcywgLTEgaWYgZmFpbCwgbm90IDAgaWYgU00gYnVpbGQgZmFpbHVyZSAKICovCmludApzbm1wdjNfcGFja2V0X3JlYWxsb2NfcmJ1aWxkKHVfY2hhciAqKiBwa3QsIHNpemVfdCAqIHBrdF9sZW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZV90ICogb2Zmc2V0LCBuZXRzbm1wX3Nlc3Npb24gKiBzZXNzaW9uLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfcGR1ICpwZHUsIHVfY2hhciAqIHBkdV9kYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVfdCBwZHVfZGF0YV9sZW4pCnsKICAgIHVfY2hhciAgICAgICAgICpzY29wZWRfcGR1LCAqaGRyYnVmID0gTlVMTCwgKmhkciA9IE5VTEw7CiAgICBzaXplX3QgICAgICAgICAgaGRyYnVmX2xlbiA9IFNOTVBfTUFYX01TR19WM19IRFJTLCBoZHJfb2Zmc2V0ID0KICAgICAgICAwLCBzcGR1X29mZnNldCA9IDA7CiAgICBzaXplX3QgICAgICAgICAgYm9keV9lbmRfb2Zmc2V0ID0gKm9mZnNldCwgYm9keV9sZW4gPSAwOwogICAgc3RydWN0IHNubXBfc2VjbW9kX2RlZiAqc3B0ciA9IE5VTEw7CiAgICBpbnQgICAgICAgICAgICAgcmMgPSAwOwoKICAgIC8qCiAgICAgKiBCdWlsZCBhIHNjb3BlZFBEVSBzdHJ1Y3R1cmUgaW50byB0aGUgcGFja2V0IGJ1ZmZlci4gIAogICAgICovCiAgICBERUJVR1BSSU5UUERVVFlQRSgic2VuZCIsIHBkdS0+Y29tbWFuZCk7CiAgICBpZiAocGR1X2RhdGEpIHsKICAgICAgICB3aGlsZSAoKCpwa3RfbGVuIC0gKm9mZnNldCkgPCBwZHVfZGF0YV9sZW4pIHsKICAgICAgICAgICAgaWYgKCFhc25fcmVhbGxvYyhwa3QsIHBrdF9sZW4pKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gLTE7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgICpvZmZzZXQgKz0gcGR1X2RhdGFfbGVuOwogICAgICAgIG1lbWNweSgqcGt0ICsgKnBrdF9sZW4gLSAqb2Zmc2V0LCBwZHVfZGF0YSwgcGR1X2RhdGFfbGVuKTsKICAgIH0gZWxzZSB7CiAgICAgICAgcmMgPSBzbm1wX3BkdV9yZWFsbG9jX3JidWlsZChwa3QsIHBrdF9sZW4sIG9mZnNldCwgcGR1KTsKICAgICAgICBpZiAocmMgPT0gMCkgewogICAgICAgICAgICByZXR1cm4gLTE7CiAgICAgICAgfQogICAgfQogICAgYm9keV9sZW4gPSAqb2Zmc2V0IC0gYm9keV9lbmRfb2Zmc2V0OwoKICAgIERFQlVHRFVNUFNFQ1RJT04oInNlbmQiLCAiU2NvcGVkUGR1Iik7CiAgICByYyA9IHNubXB2M19zY29wZWRQRFVfaGVhZGVyX3JlYWxsb2NfcmJ1aWxkKHBrdCwgcGt0X2xlbiwgb2Zmc2V0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwZHUsIGJvZHlfbGVuKTsKICAgIGlmIChyYyA9PSAwKSB7CiAgICAgICAgcmV0dXJuIC0xOwogICAgfQogICAgc3BkdV9vZmZzZXQgPSAqb2Zmc2V0OwogICAgREVCVUdJTkRFTlRBREQoLTQpOyAgICAgICAgIC8qICBSZXR1cm4gZnJvbSBTY29wZWQgUERVLiAgKi8KCiAgICBpZiAoKGhkcmJ1ZiA9ICh1X2NoYXIgKikgbWFsbG9jKGhkcmJ1Zl9sZW4pKSA9PSBOVUxMKSB7CiAgICAgICAgcmV0dXJuIC0xOwogICAgfQoKICAgIHJjID0gc25tcHYzX2hlYWRlcl9yZWFsbG9jX3JidWlsZCgmaGRyYnVmLCAmaGRyYnVmX2xlbiwgJmhkcl9vZmZzZXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2Vzc2lvbiwgcGR1KTsKICAgIGlmIChyYyA9PSAwKSB7CiAgICAgICAgU05NUF9GUkVFKGhkcmJ1Zik7CiAgICAgICAgcmV0dXJuIC0xOwogICAgfQogICAgaGRyID0gaGRyYnVmICsgaGRyYnVmX2xlbiAtIGhkcl9vZmZzZXQ7CiAgICBzY29wZWRfcGR1ID0gKnBrdCArICpwa3RfbGVuIC0gc3BkdV9vZmZzZXQ7CgogICAgLyoKICAgICAqIENhbGwgdGhlIHNlY3VyaXR5IG1vZHVsZSB0byBwb3NzaWJseSBlbmNyeXB0IGFuZCBhdXRoZW50aWNhdGUgdGhlCiAgICAgKiBtZXNzYWdlLS0tdGhlIGVudGlyZSBtZXNzYWdlIHRvIHRyYW5zbWl0dGVkIG9uIHRoZSB3aXJlIGlzIHJldHVybmVkLiAgCiAgICAgKi8KCiAgICBzcHRyID0gZmluZF9zZWNfbW9kKHBkdS0+c2VjdXJpdHlNb2RlbCk7CiAgICBERUJVR0RVTVBTRUNUSU9OKCJzZW5kIiwgIlNNIG1zZ1NlY3VyaXR5UGFyYW1ldGVycyIpOwogICAgaWYgKHNwdHIgJiYgc3B0ci0+ZW5jb2RlX3JldmVyc2UpIHsKICAgICAgICBzdHJ1Y3Qgc25tcF9zZWNtb2Rfb3V0Z29pbmdfcGFyYW1zIHBhcm1zOwoKICAgICAgICBwYXJtcy5tc2dQcm9jTW9kZWwgPSBwZHUtPm1zZ1BhcnNlTW9kZWw7CiAgICAgICAgcGFybXMuZ2xvYmFsRGF0YSA9IGhkcjsKICAgICAgICBwYXJtcy5nbG9iYWxEYXRhTGVuID0gaGRyX29mZnNldDsKICAgICAgICBwYXJtcy5tYXhNc2dTaXplID0gU05NUF9NQVhfTVNHX1NJWkU7CiAgICAgICAgcGFybXMuc2VjTW9kZWwgPSBwZHUtPnNlY3VyaXR5TW9kZWw7CiAgICAgICAgcGFybXMuc2VjRW5naW5lSUQgPSBwZHUtPnNlY3VyaXR5RW5naW5lSUQ7CiAgICAgICAgcGFybXMuc2VjRW5naW5lSURMZW4gPSBwZHUtPnNlY3VyaXR5RW5naW5lSURMZW47CiAgICAgICAgcGFybXMuc2VjTmFtZSA9IHBkdS0+c2VjdXJpdHlOYW1lOwogICAgICAgIHBhcm1zLnNlY05hbWVMZW4gPSBwZHUtPnNlY3VyaXR5TmFtZUxlbjsKICAgICAgICBwYXJtcy5zZWNMZXZlbCA9IHBkdS0+c2VjdXJpdHlMZXZlbDsKICAgICAgICBwYXJtcy5zY29wZWRQZHUgPSBzY29wZWRfcGR1OwogICAgICAgIHBhcm1zLnNjb3BlZFBkdUxlbiA9IHNwZHVfb2Zmc2V0OwogICAgICAgIHBhcm1zLnNlY1N0YXRlUmVmID0gcGR1LT5zZWN1cml0eVN0YXRlUmVmOwogICAgICAgIHBhcm1zLndob2xlTXNnID0gcGt0OwogICAgICAgIHBhcm1zLndob2xlTXNnTGVuID0gcGt0X2xlbjsKICAgICAgICBwYXJtcy53aG9sZU1zZ09mZnNldCA9IG9mZnNldDsKICAgICAgICBwYXJtcy5zZXNzaW9uID0gc2Vzc2lvbjsKICAgICAgICBwYXJtcy5wZHUgPSBwZHU7CgogICAgICAgIHJjID0gKCpzcHRyLT5lbmNvZGVfcmV2ZXJzZSkgKCZwYXJtcyk7CiAgICB9IGVsc2UgewogICAgICAgIGlmICghc3B0cikgewogICAgICAgICAgICBzbm1wX2xvZyhMT0dfRVJSLAogICAgICAgICAgICAgICAgICAgICAibm8gc3VjaCBzZWN1cml0eSBzZXJ2aWNlIGF2YWlsYWJsZTogJWRcbiIsCiAgICAgICAgICAgICAgICAgICAgIHBkdS0+c2VjdXJpdHlNb2RlbCk7CiAgICAgICAgfSBlbHNlIGlmICghc3B0ci0+ZW5jb2RlX3JldmVyc2UpIHsKICAgICAgICAgICAgc25tcF9sb2coTE9HX0VSUiwKICAgICAgICAgICAgICAgICAgICAgInNlY3VyaXR5IHNlcnZpY2UgJWQgZG9lc24ndCBzdXBwb3J0IHJldmVyc2UgZW5jb2RpbmcuXG4iLAogICAgICAgICAgICAgICAgICAgICBwZHUtPnNlY3VyaXR5TW9kZWwpOwogICAgICAgIH0KICAgICAgICByYyA9IC0xOwogICAgfQoKICAgIERFQlVHSU5ERU5UTEVTUygpOwogICAgU05NUF9GUkVFKGhkcmJ1Zik7CiAgICByZXR1cm4gcmM7Cn0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogZW5kIHNubXB2M19wYWNrZXRfcmVhbGxvY19yYnVpbGQoKSAqLwojZW5kaWYgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIE5FVFNOTVBfVVNFX1JFVkVSU0VfQVNORU5DT0RJTkcgKi8KCi8qCiAqIHJldHVybnMgMCBpZiBzdWNjZXNzLCAtMSBpZiBmYWlsLCBub3QgMCBpZiBTTSBidWlsZCBmYWlsdXJlIAogKi8KaW50CnNubXB2M19wYWNrZXRfYnVpbGQobmV0c25tcF9zZXNzaW9uICogc2Vzc2lvbiwgbmV0c25tcF9wZHUgKnBkdSwKICAgICAgICAgICAgICAgICAgICB1X2NoYXIgKiBwYWNrZXQsIHNpemVfdCAqIG91dF9sZW5ndGgsCiAgICAgICAgICAgICAgICAgICAgdV9jaGFyICogcGR1X2RhdGEsIHNpemVfdCBwZHVfZGF0YV9sZW4pCnsKICAgIHVfY2hhciAgICAgICAgICpnbG9iYWxfZGF0YSwgKnNlY19wYXJhbXMsICpzcGR1X2hkcl9lOwogICAgc2l6ZV90ICAgICAgICAgIGdsb2JhbF9kYXRhX2xlbiwgc2VjX3BhcmFtc19sZW47CiAgICB1X2NoYXIgICAgICAgICAgc3BkdV9idWZbU05NUF9NQVhfTVNHX1NJWkVdOwogICAgc2l6ZV90ICAgICAgICAgIHNwZHVfYnVmX2xlbiwgc3BkdV9sZW47CiAgICB1X2NoYXIgICAgICAgICAqY3A7CiAgICBpbnQgICAgICAgICAgICAgcmVzdWx0OwogICAgc3RydWN0IHNubXBfc2VjbW9kX2RlZiAqc3B0cjsKCiAgICBnbG9iYWxfZGF0YSA9IHBhY2tldDsKCiAgICAvKgogICAgICogYnVpbGQgdGhlIGhlYWRlcnMgZm9yIHRoZSBwYWNrZXQsIHJldHVybmVkIGFkZHIgPSBzdGFydCBvZiBzZWNQYXJhbXMKICAgICAqLwogICAgc2VjX3BhcmFtcyA9IHNubXB2M19oZWFkZXJfYnVpbGQoc2Vzc2lvbiwgcGR1LCBnbG9iYWxfZGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG91dF9sZW5ndGgsIDAsIE5VTEwpOwogICAgaWYgKHNlY19wYXJhbXMgPT0gTlVMTCkKICAgICAgICByZXR1cm4gLTE7CiAgICBnbG9iYWxfZGF0YV9sZW4gPSBzZWNfcGFyYW1zIC0gZ2xvYmFsX2RhdGE7CiAgICBzZWNfcGFyYW1zX2xlbiA9ICpvdXRfbGVuZ3RoOyAgICAgICAvKiBsZW5ndGggbGVmdCBpbiBwYWNrZXQgYnVmIGZvciBzZWNfcGFyYW1zICovCgoKICAgIC8qCiAgICAgKiBidWlsZCBhIHNjb3BlZFBEVSBzdHJ1Y3R1cmUgaW50byBzcGR1X2J1ZgogICAgICovCiAgICBzcGR1X2J1Zl9sZW4gPSBTTk1QX01BWF9NU0dfU0laRTsKICAgIERFQlVHRFVNUFNFQ1RJT04oInNlbmQiLCAiU2NvcGVkUGR1Iik7CiAgICBjcCA9IHNubXB2M19zY29wZWRQRFVfaGVhZGVyX2J1aWxkKHBkdSwgc3BkdV9idWYsICZzcGR1X2J1Zl9sZW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZzcGR1X2hkcl9lKTsKICAgIGlmIChjcCA9PSBOVUxMKQogICAgICAgIHJldHVybiAtMTsKCiAgICAvKgogICAgICogYnVpbGQgdGhlIFBEVSBzdHJ1Y3R1cmUgb250byB0aGUgZW5kIG9mIHNwZHVfYnVmIAogICAgICovCiAgICBERUJVR1BSSU5UUERVVFlQRSgic2VuZCIsICgocGR1X2RhdGEpID8gKnBkdV9kYXRhIDogMHgwMCkpOwogICAgaWYgKHBkdV9kYXRhKSB7CiAgICAgICAgbWVtY3B5KGNwLCBwZHVfZGF0YSwgcGR1X2RhdGFfbGVuKTsKICAgICAgICBjcCArPSBwZHVfZGF0YV9sZW47CiAgICB9IGVsc2UgewogICAgICAgIGNwID0gc25tcF9wZHVfYnVpbGQocGR1LCBjcCwgJnNwZHVfYnVmX2xlbik7CiAgICAgICAgaWYgKGNwID09IE5VTEwpCiAgICAgICAgICAgIHJldHVybiAtMTsKICAgIH0KICAgIERFQlVHSU5ERU5UQUREKC00KTsgICAgICAgICAvKiByZXR1cm4gZnJvbSBTY29wZWQgUERVICovCgogICAgLyoKICAgICAqIHJlLWVuY29kZSB0aGUgYWN0dWFsIEFTTi4xIGxlbmd0aCBvZiB0aGUgc2NvcGVkUGR1CiAgICAgKi8KICAgIHNwZHVfbGVuID0gY3AgLSBzcGR1X2hkcl9lOyAvKiBsZW5ndGggb2Ygc2NvcGVkUGR1IG1pbnVzIEFTTi4xIGhlYWRlcnMgKi8KICAgIHNwZHVfYnVmX2xlbiA9IFNOTVBfTUFYX01TR19TSVpFOwogICAgaWYgKGFzbl9idWlsZF9zZXF1ZW5jZShzcGR1X2J1ZiwgJnNwZHVfYnVmX2xlbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgKHVfY2hhcikgKEFTTl9TRVFVRU5DRSB8IEFTTl9DT05TVFJVQ1RPUiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHNwZHVfbGVuKSA9PSBOVUxMKQogICAgICAgIHJldHVybiAtMTsKICAgIHNwZHVfbGVuID0gY3AgLSBzcGR1X2J1ZjsgICAvKiB0aGUgbGVuZ3RoIG9mIHRoZSBlbnRpcmUgc2NvcGVkUGR1ICovCgoKICAgIC8qCiAgICAgKiBjYWxsIHRoZSBzZWN1cml0eSBtb2R1bGUgdG8gcG9zc2libHkgZW5jcnlwdCBhbmQgYXV0aGVudGljYXRlIHRoZQogICAgICogbWVzc2FnZSAtIHRoZSBlbnRpcmUgbWVzc2FnZSB0byB0cmFuc21pdHRlZCBvbiB0aGUgd2lyZSBpcyByZXR1cm5lZAogICAgICovCiAgICBjcCA9IE5VTEw7CiAgICAqb3V0X2xlbmd0aCA9IFNOTVBfTUFYX01TR19TSVpFOwogICAgREVCVUdEVU1QU0VDVElPTigic2VuZCIsICJTTSBtc2dTZWN1cml0eVBhcmFtZXRlcnMiKTsKICAgIHNwdHIgPSBmaW5kX3NlY19tb2QocGR1LT5zZWN1cml0eU1vZGVsKTsKICAgIGlmIChzcHRyICYmIHNwdHItPmVuY29kZV9mb3J3YXJkKSB7CiAgICAgICAgc3RydWN0IHNubXBfc2VjbW9kX291dGdvaW5nX3BhcmFtcyBwYXJtczsKICAgICAgICBwYXJtcy5tc2dQcm9jTW9kZWwgPSBwZHUtPm1zZ1BhcnNlTW9kZWw7CiAgICAgICAgcGFybXMuZ2xvYmFsRGF0YSA9IGdsb2JhbF9kYXRhOwogICAgICAgIHBhcm1zLmdsb2JhbERhdGFMZW4gPSBnbG9iYWxfZGF0YV9sZW47CiAgICAgICAgcGFybXMubWF4TXNnU2l6ZSA9IFNOTVBfTUFYX01TR19TSVpFOwogICAgICAgIHBhcm1zLnNlY01vZGVsID0gcGR1LT5zZWN1cml0eU1vZGVsOwogICAgICAgIHBhcm1zLnNlY0VuZ2luZUlEID0gcGR1LT5zZWN1cml0eUVuZ2luZUlEOwogICAgICAgIHBhcm1zLnNlY0VuZ2luZUlETGVuID0gcGR1LT5zZWN1cml0eUVuZ2luZUlETGVuOwogICAgICAgIHBhcm1zLnNlY05hbWUgPSBwZHUtPnNlY3VyaXR5TmFtZTsKICAgICAgICBwYXJtcy5zZWNOYW1lTGVuID0gcGR1LT5zZWN1cml0eU5hbWVMZW47CiAgICAgICAgcGFybXMuc2VjTGV2ZWwgPSBwZHUtPnNlY3VyaXR5TGV2ZWw7CiAgICAgICAgcGFybXMuc2NvcGVkUGR1ID0gc3BkdV9idWY7CiAgICAgICAgcGFybXMuc2NvcGVkUGR1TGVuID0gc3BkdV9sZW47CiAgICAgICAgcGFybXMuc2VjU3RhdGVSZWYgPSBwZHUtPnNlY3VyaXR5U3RhdGVSZWY7CiAgICAgICAgcGFybXMuc2VjUGFyYW1zID0gc2VjX3BhcmFtczsKICAgICAgICBwYXJtcy5zZWNQYXJhbXNMZW4gPSAmc2VjX3BhcmFtc19sZW47CiAgICAgICAgcGFybXMud2hvbGVNc2cgPSAmY3A7CiAgICAgICAgcGFybXMud2hvbGVNc2dMZW4gPSBvdXRfbGVuZ3RoOwogICAgICAgIHBhcm1zLnNlc3Npb24gPSBzZXNzaW9uOwogICAgICAgIHBhcm1zLnBkdSA9IHBkdTsKICAgICAgICByZXN1bHQgPSAoKnNwdHItPmVuY29kZV9mb3J3YXJkKSAoJnBhcm1zKTsKICAgIH0gZWxzZSB7CiAgICAgICAgaWYgKCFzcHRyKSB7CiAgICAgICAgICAgIHNubXBfbG9nKExPR19FUlIsICJubyBzdWNoIHNlY3VyaXR5IHNlcnZpY2UgYXZhaWxhYmxlOiAlZFxuIiwKICAgICAgICAgICAgICAgICAgICAgcGR1LT5zZWN1cml0eU1vZGVsKTsKICAgICAgICB9IGVsc2UgaWYgKCFzcHRyLT5lbmNvZGVfZm9yd2FyZCkgewogICAgICAgICAgICBzbm1wX2xvZyhMT0dfRVJSLAogICAgICAgICAgICAgICAgICAgICAic2VjdXJpdHkgc2VydmljZSAlZCBkb2Vzbid0IHN1cHBvcnQgZm9yd2FyZCBvdXQgZW5jb2RpbmcuXG4iLAogICAgICAgICAgICAgICAgICAgICBwZHUtPnNlY3VyaXR5TW9kZWwpOwogICAgICAgIH0KICAgICAgICByZXN1bHQgPSAtMTsKICAgIH0KICAgIERFQlVHSU5ERU5UTEVTUygpOwogICAgcmV0dXJuIHJlc3VsdDsKCn0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogZW5kIHNubXB2M19wYWNrZXRfYnVpbGQoKSAqLwoKCi8qCiAqIFRha2VzIGEgc2Vzc2lvbiBhbmQgYSBwZHUgYW5kIHNlcmlhbGl6ZXMgdGhlIEFTTiBQRFUgaW50byB0aGUgYXJlYQogKiBwb2ludGVkIHRvIGJ5ICpwa3QuICAqcGt0X2xlbiBpcyB0aGUgc2l6ZSBvZiB0aGUgZGF0YSBhcmVhIGF2YWlsYWJsZS4KICogUmV0dXJucyB0aGUgbGVuZ3RoIG9mIHRoZSBjb21wbGV0ZWQgcGFja2V0IGluICpvZmZzZXQuICBJZiBhbnkgZXJyb3JzCiAqIG9jY3VyLCAtMSBpcyByZXR1cm5lZC4gIElmIGFsbCBnb2VzIHdlbGwsIDAgaXMgcmV0dXJuZWQuCiAqLwoKc3RhdGljIGludApfc25tcF9idWlsZCh1X2NoYXIgKiogcGt0LCBzaXplX3QgKiBwa3RfbGVuLCBzaXplX3QgKiBvZmZzZXQsCiAgICAgICAgICAgIG5ldHNubXBfc2Vzc2lvbiAqIHNlc3Npb24sIG5ldHNubXBfcGR1ICpwZHUpCnsKI2lmICFkZWZpbmVkKE5FVFNOTVBfRElTQUJMRV9TTk1QVjEpIHx8ICFkZWZpbmVkKE5FVFNOTVBfRElTQUJMRV9TTk1QVjJDKQogICAgdV9jaGFyICAgICAgICAgKmgwZSA9IE5VTEw7CiAgICBzaXplX3QgICAgICAgICAgc3RhcnRfb2Zmc2V0ID0gKm9mZnNldDsKICAgIGxvbmcgICAgICAgICAgICB2ZXJzaW9uOwogICAgaW50ICAgICAgICAgICAgIHJjID0gMDsKI2VuZGlmIC8qIHN1cHBvcnQgZm9yIGNvbW11bml0eSBiYXNlZCBTTk1QICovCiAgICAKICAgIHVfY2hhciAgICAgICAgICpjcDsKICAgIHNpemVfdCAgICAgICAgICBsZW5ndGg7CgogICAgc2Vzc2lvbi0+c19zbm1wX2Vycm5vID0gMDsKICAgIHNlc3Npb24tPnNfZXJybm8gPSAwOwoKICAgIGlmIChwZHUtPnZlcnNpb24gPT0gU05NUF9WRVJTSU9OXzMpIHsKICAgICAgICByZXR1cm4gc25tcHYzX2J1aWxkKHBrdCwgcGt0X2xlbiwgb2Zmc2V0LCBzZXNzaW9uLCBwZHUpOwogICAgfQoKICAgIHN3aXRjaCAocGR1LT5jb21tYW5kKSB7CiAgICBjYXNlIFNOTVBfTVNHX1JFU1BPTlNFOgogICAgICAgIG5ldHNubXBfYXNzZXJ0KDAgPT0gKHBkdS0+ZmxhZ3MgJiBVQ0RfTVNHX0ZMQUdfRVhQRUNUX1JFU1BPTlNFKSk7CiAgICAgICAgLyoKICAgICAgICAgKiBGYWxsdGhyb3VnaCAKICAgICAgICAgKi8KICAgIGNhc2UgU05NUF9NU0dfR0VUOgogICAgY2FzZSBTTk1QX01TR19HRVRORVhUOgogICAgY2FzZSBTTk1QX01TR19TRVQ6CiAgICAgICAgLyoKICAgICAgICAgKiBhbGwgdmVyc2lvbnMgc3VwcG9ydCB0aGVzZSBQRFUgdHlwZXMgCiAgICAgICAgICovCiAgICAgICAgLyoKICAgICAgICAgKiBpbml0aWFsaXplIGRlZmF1bHRlZCBQRFUgZmllbGRzIAogICAgICAgICAqLwoKICAgICAgICBpZiAocGR1LT5lcnJzdGF0ID09IFNOTVBfREVGQVVMVF9FUlJTVEFUKQogICAgICAgICAgICBwZHUtPmVycnN0YXQgPSAwOwogICAgICAgIGlmIChwZHUtPmVycmluZGV4ID09IFNOTVBfREVGQVVMVF9FUlJJTkRFWCkKICAgICAgICAgICAgcGR1LT5lcnJpbmRleCA9IDA7CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSBTTk1QX01TR19UUkFQMjoKICAgICAgICBuZXRzbm1wX2Fzc2VydCgwID09IChwZHUtPmZsYWdzICYgVUNEX01TR19GTEFHX0VYUEVDVF9SRVNQT05TRSkpOwogICAgICAgIC8qCiAgICAgICAgICogRmFsbHRocm91Z2ggCiAgICAgICAgICovCiAgICBjYXNlIFNOTVBfTVNHX0lORk9STToKI2lmbmRlZiBORVRTTk1QX0RJU0FCTEVfU05NUFYxCiAgICAgICAgLyoKICAgICAgICAgKiBub3Qgc3VwcG9ydGVkIGluIFNOTVB2MSBhbmQgU05NUHNlYyAKICAgICAgICAgKi8KICAgICAgICBpZiAocGR1LT52ZXJzaW9uID09IFNOTVBfVkVSU0lPTl8xKSB7CiAgICAgICAgICAgIHNlc3Npb24tPnNfc25tcF9lcnJubyA9IFNOTVBFUlJfVjJfSU5fVjE7CiAgICAgICAgICAgIHJldHVybiAtMTsKICAgICAgICB9CiNlbmRpZgogICAgICAgIGlmIChwZHUtPmVycnN0YXQgPT0gU05NUF9ERUZBVUxUX0VSUlNUQVQpCiAgICAgICAgICAgIHBkdS0+ZXJyc3RhdCA9IDA7CiAgICAgICAgaWYgKHBkdS0+ZXJyaW5kZXggPT0gU05NUF9ERUZBVUxUX0VSUklOREVYKQogICAgICAgICAgICBwZHUtPmVycmluZGV4ID0gMDsKICAgICAgICBicmVhazsKCiAgICBjYXNlIFNOTVBfTVNHX0dFVEJVTEs6CiAgICAgICAgLyoKICAgICAgICAgKiBub3Qgc3VwcG9ydGVkIGluIFNOTVB2MSBhbmQgU05NUHNlYyAKICAgICAgICAgKi8KI2lmbmRlZiBORVRTTk1QX0RJU0FCTEVfU05NUFYxCiAgICAgICAgaWYgKHBkdS0+dmVyc2lvbiA9PSBTTk1QX1ZFUlNJT05fMSkgewogICAgICAgICAgICBzZXNzaW9uLT5zX3NubXBfZXJybm8gPSBTTk1QRVJSX1YyX0lOX1YxOwogICAgICAgICAgICByZXR1cm4gLTE7CiAgICAgICAgfQojZW5kaWYKICAgICAgICBpZiAocGR1LT5tYXhfcmVwZXRpdGlvbnMgPCAwKSB7CiAgICAgICAgICAgIHNlc3Npb24tPnNfc25tcF9lcnJubyA9IFNOTVBFUlJfQkFEX1JFUEVUSVRJT05TOwogICAgICAgICAgICByZXR1cm4gLTE7CiAgICAgICAgfQogICAgICAgIGlmIChwZHUtPm5vbl9yZXBlYXRlcnMgPCAwKSB7CiAgICAgICAgICAgIHNlc3Npb24tPnNfc25tcF9lcnJubyA9IFNOTVBFUlJfQkFEX1JFUEVBVEVSUzsKICAgICAgICAgICAgcmV0dXJuIC0xOwogICAgICAgIH0KICAgICAgICBicmVhazsKCiAgICBjYXNlIFNOTVBfTVNHX1RSQVA6CiAgICAgICAgLyoKICAgICAgICAgKiAqb25seSogc3VwcG9ydGVkIGluIFNOTVB2MSBhbmQgU05NUHNlYyAKICAgICAgICAgKi8KI2lmbmRlZiBORVRTTk1QX0RJU0FCTEVfU05NUFYxCiAgICAgICAgaWYgKHBkdS0+dmVyc2lvbiAhPSBTTk1QX1ZFUlNJT05fMSkgewogICAgICAgICAgICBzZXNzaW9uLT5zX3NubXBfZXJybm8gPSBTTk1QRVJSX1YxX0lOX1YyOwogICAgICAgICAgICByZXR1cm4gLTE7CiAgICAgICAgfQojZW5kaWYKICAgICAgICAvKgogICAgICAgICAqIGluaXRpYWxpemUgZGVmYXVsdGVkIFRyYXAgUERVIGZpZWxkcyAKICAgICAgICAgKi8KICAgICAgICBwZHUtPnJlcWlkID0gMTsgICAgICAgICAvKiBnaXZlIGEgYm9ndXMgbm9uLWVycm9yIHJlcWlkIGZvciB0cmFwcyAqLwogICAgICAgIGlmIChwZHUtPmVudGVycHJpc2VfbGVuZ3RoID09IFNOTVBfREVGQVVMVF9FTlRFUlBSSVNFX0xFTkdUSCkgewogICAgICAgICAgICBwZHUtPmVudGVycHJpc2UgPSAob2lkICopIG1hbGxvYyhzaXplb2YoREVGQVVMVF9FTlRFUlBSSVNFKSk7CiAgICAgICAgICAgIGlmIChwZHUtPmVudGVycHJpc2UgPT0gTlVMTCkgewogICAgICAgICAgICAgICAgc2Vzc2lvbi0+c19zbm1wX2Vycm5vID0gU05NUEVSUl9NQUxMT0M7CiAgICAgICAgICAgICAgICByZXR1cm4gLTE7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgbWVtbW92ZShwZHUtPmVudGVycHJpc2UsIERFRkFVTFRfRU5URVJQUklTRSwKICAgICAgICAgICAgICAgICAgICBzaXplb2YoREVGQVVMVF9FTlRFUlBSSVNFKSk7CiAgICAgICAgICAgIHBkdS0+ZW50ZXJwcmlzZV9sZW5ndGggPQogICAgICAgICAgICAgICAgc2l6ZW9mKERFRkFVTFRfRU5URVJQUklTRSkgLyBzaXplb2Yob2lkKTsKICAgICAgICB9CiAgICAgICAgaWYgKHBkdS0+dGltZSA9PSBTTk1QX0RFRkFVTFRfVElNRSkKICAgICAgICAgICAgcGR1LT50aW1lID0gREVGQVVMVF9USU1FOwogICAgICAgIC8qCiAgICAgICAgICogZG9uJ3QgZXhwZWN0IGEgcmVzcG9uc2UgCiAgICAgICAgICovCiAgICAgICAgcGR1LT5mbGFncyAmPSAoflVDRF9NU0dfRkxBR19FWFBFQ1RfUkVTUE9OU0UpOwogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgU05NUF9NU0dfUkVQT1JUOiAgICAgIC8qIFNOTVB2MyBvbmx5ICovCiAgICBkZWZhdWx0OgogICAgICAgIHNlc3Npb24tPnNfc25tcF9lcnJubyA9IFNOTVBFUlJfVU5LTk9XTl9QRFU7CiAgICAgICAgcmV0dXJuIC0xOwogICAgfQoKICAgIC8qCiAgICAgKiBzYXZlIGxlbmd0aCAKICAgICAqLwogICAgbGVuZ3RoID0gKnBrdF9sZW47CgogICAgLyoKICAgICAqIHNldHVwIGFkbWluaXN0cmF0aXZlIGZpZWxkcyBiYXNlZCBvbiB2ZXJzaW9uIAogICAgICovCiAgICAvKgogICAgICogYnVpbGQgdGhlIG1lc3NhZ2Ugd3JhcHBlciBhbmQgYWxsIHRoZSBhZG1pbmlzdHJhdGl2ZSBmaWVsZHMKICAgICAqIHVwdG8gdGhlIFBEVSBzZXF1ZW5jZQogICAgICogKG5vdGUgdGhhdCBhY3R1YWwgbGVuZ3RoIG9mIG1lc3NhZ2Ugd2lsbCBiZSBpbnNlcnRlZCBsYXRlcikgCiAgICAgKi8KICAgIHN3aXRjaCAocGR1LT52ZXJzaW9uKSB7CiNpZm5kZWYgTkVUU05NUF9ESVNBQkxFX1NOTVBWMQogICAgY2FzZSBTTk1QX1ZFUlNJT05fMToKI2VuZGlmCiNpZm5kZWYgTkVUU05NUF9ESVNBQkxFX1NOTVBWMkMKICAgIGNhc2UgU05NUF9WRVJTSU9OXzJjOgojZW5kaWYKI2lmICFkZWZpbmVkKE5FVFNOTVBfRElTQUJMRV9TTk1QVjEpIHx8ICFkZWZpbmVkKE5FVFNOTVBfRElTQUJMRV9TTk1QVjJDKQojaWZkZWYgTkVUU05NUF9OT19aRVJPTEVOR1RIX0NPTU1VTklUWQogICAgICAgIGlmIChwZHUtPmNvbW11bml0eV9sZW4gPT0gMCkgewogICAgICAgICAgICBpZiAoc2Vzc2lvbi0+Y29tbXVuaXR5X2xlbiA9PSAwKSB7CiAgICAgICAgICAgICAgICBzZXNzaW9uLT5zX3NubXBfZXJybm8gPSBTTk1QRVJSX0JBRF9DT01NVU5JVFk7CiAgICAgICAgICAgICAgICByZXR1cm4gLTE7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcGR1LT5jb21tdW5pdHkgPSAodV9jaGFyICopIG1hbGxvYyhzZXNzaW9uLT5jb21tdW5pdHlfbGVuKTsKICAgICAgICAgICAgaWYgKHBkdS0+Y29tbXVuaXR5ID09IE5VTEwpIHsKICAgICAgICAgICAgICAgIHNlc3Npb24tPnNfc25tcF9lcnJubyA9IFNOTVBFUlJfTUFMTE9DOwogICAgICAgICAgICAgICAgcmV0dXJuIC0xOwogICAgICAgICAgICB9CiAgICAgICAgICAgIG1lbW1vdmUocGR1LT5jb21tdW5pdHksCiAgICAgICAgICAgICAgICAgICAgc2Vzc2lvbi0+Y29tbXVuaXR5LCBzZXNzaW9uLT5jb21tdW5pdHlfbGVuKTsKICAgICAgICAgICAgcGR1LT5jb21tdW5pdHlfbGVuID0gc2Vzc2lvbi0+Y29tbXVuaXR5X2xlbjsKICAgICAgICB9CiNlbHNlICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogIU5FVFNOTVBfTk9fWkVST0xFTkdUSF9DT01NVU5JVFkgKi8KICAgICAgICBpZiAocGR1LT5jb21tdW5pdHlfbGVuID09IDAgJiYgcGR1LT5jb21tYW5kICE9IFNOTVBfTVNHX1JFU1BPTlNFKSB7CiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIGNvcHkgc2Vzc2lvbiBjb21tdW5pdHkgZXhhY3RseSB0byBwZHUgY29tbXVuaXR5IAogICAgICAgICAgICAgKi8KICAgICAgICAgICAgaWYgKDAgPT0gc2Vzc2lvbi0+Y29tbXVuaXR5X2xlbikgewogICAgICAgICAgICAgICAgU05NUF9GUkVFKHBkdS0+Y29tbXVuaXR5KTsKICAgICAgICAgICAgICAgIHBkdS0+Y29tbXVuaXR5ID0gTlVMTDsKICAgICAgICAgICAgfSBlbHNlIGlmIChwZHUtPmNvbW11bml0eV9sZW4gPT0gc2Vzc2lvbi0+Y29tbXVuaXR5X2xlbikgewogICAgICAgICAgICAgICAgbWVtbW92ZShwZHUtPmNvbW11bml0eSwKICAgICAgICAgICAgICAgICAgICAgICAgc2Vzc2lvbi0+Y29tbXVuaXR5LCBzZXNzaW9uLT5jb21tdW5pdHlfbGVuKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIFNOTVBfRlJFRShwZHUtPmNvbW11bml0eSk7CiAgICAgICAgICAgICAgICBwZHUtPmNvbW11bml0eSA9ICh1X2NoYXIgKikgbWFsbG9jKHNlc3Npb24tPmNvbW11bml0eV9sZW4pOwogICAgICAgICAgICAgICAgaWYgKHBkdS0+Y29tbXVuaXR5ID09IE5VTEwpIHsKICAgICAgICAgICAgICAgICAgICBzZXNzaW9uLT5zX3NubXBfZXJybm8gPSBTTk1QRVJSX01BTExPQzsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gLTE7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBtZW1tb3ZlKHBkdS0+Y29tbXVuaXR5LAogICAgICAgICAgICAgICAgICAgICAgICBzZXNzaW9uLT5jb21tdW5pdHksIHNlc3Npb24tPmNvbW11bml0eV9sZW4pOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHBkdS0+Y29tbXVuaXR5X2xlbiA9IHNlc3Npb24tPmNvbW11bml0eV9sZW47CiAgICAgICAgfQojZW5kaWYgICAgICAgICAgICAgICAgICAgICAgICAgIC8qICFORVRTTk1QX05PX1pFUk9MRU5HVEhfQ09NTVVOSVRZICovCgogICAgICAgIERFQlVHTVNHVEwoKCJzbm1wX3NlbmQiLCAiQnVpbGRpbmcgU05NUHYlbGQgbWVzc2FnZS4uLlxuIiwKICAgICAgICAgICAgICAgICAgICAoMSArIHBkdS0+dmVyc2lvbikpKTsKI2lmZGVmIE5FVFNOTVBfVVNFX1JFVkVSU0VfQVNORU5DT0RJTkcKICAgICAgICBpZiAobmV0c25tcF9kc19nZXRfYm9vbGVhbihORVRTTk1QX0RTX0xJQlJBUllfSUQsIE5FVFNOTVBfRFNfTElCX1JFVkVSU0VfRU5DT0RFKSkgewogICAgICAgICAgICBERUJVR1BSSU5UUERVVFlQRSgic2VuZCIsIHBkdS0+Y29tbWFuZCk7CiAgICAgICAgICAgIHJjID0gc25tcF9wZHVfcmVhbGxvY19yYnVpbGQocGt0LCBwa3RfbGVuLCBvZmZzZXQsIHBkdSk7CiAgICAgICAgICAgIGlmIChyYyA9PSAwKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gLTE7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIERFQlVHRFVNUEhFQURFUigic2VuZCIsICJDb21tdW5pdHkgU3RyaW5nIik7CiAgICAgICAgICAgIHJjID0gYXNuX3JlYWxsb2NfcmJ1aWxkX3N0cmluZyhwa3QsIHBrdF9sZW4sIG9mZnNldCwgMSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh1X2NoYXIpIChBU05fVU5JVkVSU0FMIHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBU05fUFJJTUlUSVZFIHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBU05fT0NURVRfU1RSKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBkdS0+Y29tbXVuaXR5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGR1LT5jb21tdW5pdHlfbGVuKTsKICAgICAgICAgICAgREVCVUdJTkRFTlRMRVNTKCk7CiAgICAgICAgICAgIGlmIChyYyA9PSAwKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gLTE7CiAgICAgICAgICAgIH0KCgogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBTdG9yZSB0aGUgdmVyc2lvbiBmaWVsZC4gIAogICAgICAgICAgICAgKi8KICAgICAgICAgICAgREVCVUdEVU1QSEVBREVSKCJzZW5kIiwgIlNOTVAgVmVyc2lvbiBOdW1iZXIiKTsKCiAgICAgICAgICAgIHZlcnNpb24gPSBwZHUtPnZlcnNpb247CiAgICAgICAgICAgIHJjID0gYXNuX3JlYWxsb2NfcmJ1aWxkX2ludChwa3QsIHBrdF9sZW4sIG9mZnNldCwgMSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh1X2NoYXIpIChBU05fVU5JVkVSU0FMIHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBU05fUFJJTUlUSVZFIHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBU05fSU5URUdFUiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAobG9uZyAqKSAmdmVyc2lvbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZih2ZXJzaW9uKSk7CiAgICAgICAgICAgIERFQlVHSU5ERU5UTEVTUygpOwogICAgICAgICAgICBpZiAocmMgPT0gMCkgewogICAgICAgICAgICAgICAgcmV0dXJuIC0xOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBCdWlsZCB0aGUgZmluYWwgc2VxdWVuY2UuICAKICAgICAgICAgICAgICovCiNpZm5kZWYgTkVUU05NUF9ESVNBQkxFX1NOTVBWMQogICAgICAgICAgICBpZiAocGR1LT52ZXJzaW9uID09IFNOTVBfVkVSU0lPTl8xKSB7CiAgICAgICAgICAgICAgICBERUJVR0RVTVBTRUNUSU9OKCJzZW5kIiwgIlNOTVB2MSBNZXNzYWdlIik7CiAgICAgICAgICAgIH0gZWxzZSB7CiNlbmRpZgogICAgICAgICAgICAgICAgREVCVUdEVU1QU0VDVElPTigic2VuZCIsICJTTk1QdjJjIE1lc3NhZ2UiKTsKI2lmbmRlZiBORVRTTk1QX0RJU0FCTEVfU05NUFYxCiAgICAgICAgICAgIH0KI2VuZGlmCiAgICAgICAgICAgIHJjID0gYXNuX3JlYWxsb2NfcmJ1aWxkX3NlcXVlbmNlKHBrdCwgcGt0X2xlbiwgb2Zmc2V0LCAxLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodV9jaGFyKSAoQVNOX1NFUVVFTkNFIHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFTTl9DT05TVFJVQ1RPUiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpvZmZzZXQgLSBzdGFydF9vZmZzZXQpOwogICAgICAgICAgICBERUJVR0lOREVOVExFU1MoKTsKCiAgICAgICAgICAgIGlmIChyYyA9PSAwKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gLTE7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgfSBlbHNlIHsKCiNlbmRpZiAgICAgICAgICAgICAgICAgICAgICAgICAgLyogTkVUU05NUF9VU0VfUkVWRVJTRV9BU05FTkNPRElORyAqLwogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBTYXZlIGN1cnJlbnQgbG9jYXRpb24gYW5kIGJ1aWxkIFNFUVVFTkNFIHRhZyBhbmQgbGVuZ3RoCiAgICAgICAgICAgICAqIHBsYWNlaG9sZGVyIGZvciBTTk1QIG1lc3NhZ2Ugc2VxdWVuY2UKICAgICAgICAgICAgICogKGFjdHVhbCBsZW5ndGggd2lsbCBiZSBpbnNlcnRlZCBsYXRlcikgCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBjcCA9IGFzbl9idWlsZF9zZXF1ZW5jZSgqcGt0LCBwa3RfbGVuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodV9jaGFyKSAoQVNOX1NFUVVFTkNFIHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFTTl9DT05TVFJVQ1RPUiksIDApOwogICAgICAgICAgICBpZiAoY3AgPT0gTlVMTCkgewogICAgICAgICAgICAgICAgcmV0dXJuIC0xOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGgwZSA9IGNwOwoKI2lmbmRlZiBORVRTTk1QX0RJU0FCTEVfU05NUFYxCiAgICAgICAgICAgIGlmIChwZHUtPnZlcnNpb24gPT0gU05NUF9WRVJTSU9OXzEpIHsKICAgICAgICAgICAgICAgIERFQlVHRFVNUFNFQ1RJT04oInNlbmQiLCAiU05NUHYxIE1lc3NhZ2UiKTsKICAgICAgICAgICAgfSBlbHNlIHsKI2VuZGlmCiAgICAgICAgICAgICAgICBERUJVR0RVTVBTRUNUSU9OKCJzZW5kIiwgIlNOTVB2MmMgTWVzc2FnZSIpOwojaWZuZGVmIE5FVFNOTVBfRElTQUJMRV9TTk1QVjEKICAgICAgICAgICAgfQojZW5kaWYKCiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIHN0b3JlIHRoZSB2ZXJzaW9uIGZpZWxkIAogICAgICAgICAgICAgKi8KICAgICAgICAgICAgREVCVUdEVU1QSEVBREVSKCJzZW5kIiwgIlNOTVAgVmVyc2lvbiBOdW1iZXIiKTsKCiAgICAgICAgICAgIHZlcnNpb24gPSBwZHUtPnZlcnNpb247CiAgICAgICAgICAgIGNwID0gYXNuX2J1aWxkX2ludChjcCwgcGt0X2xlbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh1X2NoYXIpIChBU05fVU5JVkVSU0FMIHwgQVNOX1BSSU1JVElWRSB8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQVNOX0lOVEVHRVIpLCAobG9uZyAqKSAmdmVyc2lvbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZih2ZXJzaW9uKSk7CiAgICAgICAgICAgIERFQlVHSU5ERU5UTEVTUygpOwogICAgICAgICAgICBpZiAoY3AgPT0gTlVMTCkKICAgICAgICAgICAgICAgIHJldHVybiAtMTsKCiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIHN0b3JlIHRoZSBjb21tdW5pdHkgc3RyaW5nIAogICAgICAgICAgICAgKi8KICAgICAgICAgICAgREVCVUdEVU1QSEVBREVSKCJzZW5kIiwgIkNvbW11bml0eSBTdHJpbmciKTsKICAgICAgICAgICAgY3AgPSBhc25fYnVpbGRfc3RyaW5nKGNwLCBwa3RfbGVuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHVfY2hhcikgKEFTTl9VTklWRVJTQUwgfCBBU05fUFJJTUlUSVZFIHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBU05fT0NURVRfU1RSKSwgcGR1LT5jb21tdW5pdHksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwZHUtPmNvbW11bml0eV9sZW4pOwogICAgICAgICAgICBERUJVR0lOREVOVExFU1MoKTsKICAgICAgICAgICAgaWYgKGNwID09IE5VTEwpCiAgICAgICAgICAgICAgICByZXR1cm4gLTE7CiAgICAgICAgICAgIGJyZWFrOwoKI2lmZGVmIE5FVFNOTVBfVVNFX1JFVkVSU0VfQVNORU5DT0RJTkcKICAgICAgICB9CiNlbmRpZiAgICAgICAgICAgICAgICAgICAgICAgICAgLyogTkVUU05NUF9VU0VfUkVWRVJTRV9BU05FTkNPRElORyAqLwogICAgICAgIGJyZWFrOwojZW5kaWYgLyogc3VwcG9ydCBmb3IgY29tbXVuaXR5IGJhc2VkIFNOTVAgKi8KICAgIGNhc2UgU05NUF9WRVJTSU9OXzJwOgogICAgY2FzZSBTTk1QX1ZFUlNJT05fc2VjOgogICAgY2FzZSBTTk1QX1ZFUlNJT05fMnU6CiAgICBjYXNlIFNOTVBfVkVSU0lPTl8yc3RhcjoKICAgIGRlZmF1bHQ6CiAgICAgICAgc2Vzc2lvbi0+c19zbm1wX2Vycm5vID0gU05NUEVSUl9CQURfVkVSU0lPTjsKICAgICAgICByZXR1cm4gLTE7CiAgICB9CgogICAgREVCVUdQUklOVFBEVVRZUEUoInNlbmQiLCBwZHUtPmNvbW1hbmQpOwogICAgY3AgPSBzbm1wX3BkdV9idWlsZChwZHUsIGNwLCBwa3RfbGVuKTsKICAgIERFQlVHSU5ERU5UQUREKC00KTsgICAgICAgICAvKiByZXR1cm4gZnJvbSBlbnRpcmUgdjEvdjJjIG1lc3NhZ2UgKi8KICAgIGlmIChjcCA9PSBOVUxMKQogICAgICAgIHJldHVybiAtMTsKCiAgICAvKgogICAgICogaW5zZXJ0IHRoZSBhY3R1YWwgbGVuZ3RoIG9mIHRoZSBtZXNzYWdlIHNlcXVlbmNlIAogICAgICovCiAgICBzd2l0Y2ggKHBkdS0+dmVyc2lvbikgewojaWZuZGVmIE5FVFNOTVBfRElTQUJMRV9TTk1QVjEKICAgIGNhc2UgU05NUF9WRVJTSU9OXzE6CiNlbmRpZgojaWZuZGVmIE5FVFNOTVBfRElTQUJMRV9TTk1QVjJDCiAgICBjYXNlIFNOTVBfVkVSU0lPTl8yYzoKI2VuZGlmCiNpZiAhZGVmaW5lZChORVRTTk1QX0RJU0FCTEVfU05NUFYxKSB8fCAhZGVmaW5lZChORVRTTk1QX0RJU0FCTEVfU05NUFYyQykKICAgICAgICBhc25fYnVpbGRfc2VxdWVuY2UoKnBrdCwgJmxlbmd0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgKHVfY2hhcikgKEFTTl9TRVFVRU5DRSB8IEFTTl9DT05TVFJVQ1RPUiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGNwIC0gaDBlKTsKICAgICAgICBicmVhazsKI2VuZGlmIC8qIHN1cHBvcnQgZm9yIGNvbW11bml0eSBiYXNlZCBTTk1QICovCgogICAgY2FzZSBTTk1QX1ZFUlNJT05fMnA6CiAgICBjYXNlIFNOTVBfVkVSU0lPTl9zZWM6CiAgICBjYXNlIFNOTVBfVkVSU0lPTl8ydToKICAgIGNhc2UgU05NUF9WRVJTSU9OXzJzdGFyOgogICAgZGVmYXVsdDoKICAgICAgICBzZXNzaW9uLT5zX3NubXBfZXJybm8gPSBTTk1QRVJSX0JBRF9WRVJTSU9OOwogICAgICAgIHJldHVybiAtMTsKICAgIH0KICAgICpwa3RfbGVuID0gY3AgLSAqcGt0OwogICAgcmV0dXJuIDA7Cn0KCmludApzbm1wX2J1aWxkKHVfY2hhciAqKiBwa3QsIHNpemVfdCAqIHBrdF9sZW4sIHNpemVfdCAqIG9mZnNldCwKICAgICAgICAgICBuZXRzbm1wX3Nlc3Npb24gKiBwc3MsIG5ldHNubXBfcGR1ICpwZHUpCnsKICAgIGludCAgICAgICAgICAgICByYzsKICAgIHJjID0gX3NubXBfYnVpbGQocGt0LCBwa3RfbGVuLCBvZmZzZXQsIHBzcywgcGR1KTsKICAgIGlmIChyYykgewogICAgICAgIGlmICghcHNzLT5zX3NubXBfZXJybm8pIHsKICAgICAgICAgICAgc25tcF9sb2coTE9HX0VSUiwgInNubXBfYnVpbGQ6IHVua25vd24gZmFpbHVyZVxuIik7CiAgICAgICAgICAgIHBzcy0+c19zbm1wX2Vycm5vID0gU05NUEVSUl9CQURfQVNOMV9CVUlMRDsKICAgICAgICB9CiAgICAgICAgU0VUX1NOTVBfRVJST1IocHNzLT5zX3NubXBfZXJybm8pOwogICAgICAgIHJjID0gLTE7CiAgICB9CiAgICByZXR1cm4gcmM7Cn0KCi8qCiAqIG9uIGVycm9yLCByZXR1cm5zIE5VTEwgKGxpa2VseSBhbiBlbmNvZGluZyBwcm9ibGVtKS4gCiAqLwp1X2NoYXIgICAgICAgICAqCnNubXBfcGR1X2J1aWxkKG5ldHNubXBfcGR1ICpwZHUsIHVfY2hhciAqIGNwLCBzaXplX3QgKiBvdXRfbGVuZ3RoKQp7CiAgICB1X2NoYXIgICAgICAgICAqaDEsICpoMWUsICpoMiwgKmgyZTsKICAgIG5ldHNubXBfdmFyaWFibGVfbGlzdCAqdnA7CiAgICBzaXplX3QgICAgICAgICAgbGVuZ3RoOwoKICAgIGxlbmd0aCA9ICpvdXRfbGVuZ3RoOwogICAgLyoKICAgICAqIFNhdmUgY3VycmVudCBsb2NhdGlvbiBhbmQgYnVpbGQgUERVIHRhZyBhbmQgbGVuZ3RoIHBsYWNlaG9sZGVyCiAgICAgKiAoYWN0dWFsIGxlbmd0aCB3aWxsIGJlIGluc2VydGVkIGxhdGVyKSAKICAgICAqLwogICAgaDEgPSBjcDsKICAgIGNwID0gYXNuX2J1aWxkX3NlcXVlbmNlKGNwLCBvdXRfbGVuZ3RoLCAodV9jaGFyKSBwZHUtPmNvbW1hbmQsIDApOwogICAgaWYgKGNwID09IE5VTEwpCiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICBoMWUgPSBjcDsKCiAgICAvKgogICAgICogc3RvcmUgZmllbGRzIGluIHRoZSBQRFUgcHJlY2VlZGluZyB0aGUgdmFyaWFibGUtYmluZGluZ3Mgc2VxdWVuY2UgCiAgICAgKi8KICAgIGlmIChwZHUtPmNvbW1hbmQgIT0gU05NUF9NU0dfVFJBUCkgewogICAgICAgIC8qCiAgICAgICAgICogUERVIGlzIG5vdCBhbiBTTk1QdjEgdHJhcCAKICAgICAgICAgKi8KCiAgICAgICAgREVCVUdEVU1QSEVBREVSKCJzZW5kIiwgInJlcXVlc3RfaWQiKTsKICAgICAgICAvKgogICAgICAgICAqIHJlcXVlc3QgaWQgCiAgICAgICAgICovCiAgICAgICAgY3AgPSBhc25fYnVpbGRfaW50KGNwLCBvdXRfbGVuZ3RoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAodV9jaGFyKSAoQVNOX1VOSVZFUlNBTCB8IEFTTl9QUklNSVRJVkUgfAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQVNOX0lOVEVHRVIpLCAmcGR1LT5yZXFpZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZW9mKHBkdS0+cmVxaWQpKTsKICAgICAgICBERUJVR0lOREVOVExFU1MoKTsKICAgICAgICBpZiAoY3AgPT0gTlVMTCkKICAgICAgICAgICAgcmV0dXJuIE5VTEw7CgogICAgICAgIC8qCiAgICAgICAgICogZXJyb3Igc3RhdHVzIChnZXRidWxrIG5vbi1yZXBlYXRlcnMpIAogICAgICAgICAqLwogICAgICAgIERFQlVHRFVNUEhFQURFUigic2VuZCIsICJlcnJvciBzdGF0dXMiKTsKICAgICAgICBjcCA9IGFzbl9idWlsZF9pbnQoY3AsIG91dF9sZW5ndGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICh1X2NoYXIpIChBU05fVU5JVkVSU0FMIHwgQVNOX1BSSU1JVElWRSB8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBU05fSU5URUdFUiksICZwZHUtPmVycnN0YXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZihwZHUtPmVycnN0YXQpKTsKICAgICAgICBERUJVR0lOREVOVExFU1MoKTsKICAgICAgICBpZiAoY3AgPT0gTlVMTCkKICAgICAgICAgICAgcmV0dXJuIE5VTEw7CgogICAgICAgIC8qCiAgICAgICAgICogZXJyb3IgaW5kZXggKGdldGJ1bGsgbWF4LXJlcGV0aXRpb25zKSAKICAgICAgICAgKi8KICAgICAgICBERUJVR0RVTVBIRUFERVIoInNlbmQiLCAiZXJyb3IgaW5kZXgiKTsKICAgICAgICBjcCA9IGFzbl9idWlsZF9pbnQoY3AsIG91dF9sZW5ndGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICh1X2NoYXIpIChBU05fVU5JVkVSU0FMIHwgQVNOX1BSSU1JVElWRSB8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBU05fSU5URUdFUiksICZwZHUtPmVycmluZGV4LAogICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplb2YocGR1LT5lcnJpbmRleCkpOwogICAgICAgIERFQlVHSU5ERU5UTEVTUygpOwogICAgICAgIGlmIChjcCA9PSBOVUxMKQogICAgICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0gZWxzZSB7CiAgICAgICAgLyoKICAgICAgICAgKiBhbiBTTk1QdjEgdHJhcCBQRFUgCiAgICAgICAgICovCgogICAgICAgIC8qCiAgICAgICAgICogZW50ZXJwcmlzZSAKICAgICAgICAgKi8KICAgICAgICBERUJVR0RVTVBIRUFERVIoInNlbmQiLCAiZW50ZXJwcmlzZSBPQkpJRCIpOwogICAgICAgIGNwID0gYXNuX2J1aWxkX29iamlkKGNwLCBvdXRfbGVuZ3RoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICh1X2NoYXIpIChBU05fVU5JVkVSU0FMIHwgQVNOX1BSSU1JVElWRSB8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFTTl9PQkpFQ1RfSUQpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIChvaWQgKikgcGR1LT5lbnRlcnByaXNlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBkdS0+ZW50ZXJwcmlzZV9sZW5ndGgpOwogICAgICAgIERFQlVHSU5ERU5UTEVTUygpOwogICAgICAgIGlmIChjcCA9PSBOVUxMKQogICAgICAgICAgICByZXR1cm4gTlVMTDsKCiAgICAgICAgLyoKICAgICAgICAgKiBhZ2VudC1hZGRyIAogICAgICAgICAqLwogICAgICAgIERFQlVHRFVNUEhFQURFUigic2VuZCIsICJhZ2VudCBBZGRyZXNzIik7CiAgICAgICAgY3AgPSBhc25fYnVpbGRfc3RyaW5nKGNwLCBvdXRfbGVuZ3RoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodV9jaGFyKSAoQVNOX0lQQUREUkVTUyB8IEFTTl9QUklNSVRJVkUpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodV9jaGFyICopIHBkdS0+YWdlbnRfYWRkciwgNCk7CiAgICAgICAgREVCVUdJTkRFTlRMRVNTKCk7CiAgICAgICAgaWYgKGNwID09IE5VTEwpCiAgICAgICAgICAgIHJldHVybiBOVUxMOwoKICAgICAgICAvKgogICAgICAgICAqIGdlbmVyaWMgdHJhcCAKICAgICAgICAgKi8KICAgICAgICBERUJVR0RVTVBIRUFERVIoInNlbmQiLCAiZ2VuZXJpYyB0cmFwIG51bWJlciIpOwogICAgICAgIGNwID0gYXNuX2J1aWxkX2ludChjcCwgb3V0X2xlbmd0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgKHVfY2hhcikgKEFTTl9VTklWRVJTQUwgfCBBU05fUFJJTUlUSVZFIHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFTTl9JTlRFR0VSKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgKGxvbmcgKikgJnBkdS0+dHJhcF90eXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplb2YocGR1LT50cmFwX3R5cGUpKTsKICAgICAgICBERUJVR0lOREVOVExFU1MoKTsKICAgICAgICBpZiAoY3AgPT0gTlVMTCkKICAgICAgICAgICAgcmV0dXJuIE5VTEw7CgogICAgICAgIC8qCiAgICAgICAgICogc3BlY2lmaWMgdHJhcCAKICAgICAgICAgKi8KICAgICAgICBERUJVR0RVTVBIRUFERVIoInNlbmQiLCAic3BlY2lmaWMgdHJhcCBudW1iZXIiKTsKICAgICAgICBjcCA9IGFzbl9idWlsZF9pbnQoY3AsIG91dF9sZW5ndGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICh1X2NoYXIpIChBU05fVU5JVkVSU0FMIHwgQVNOX1BSSU1JVElWRSB8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBU05fSU5URUdFUiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgIChsb25nICopICZwZHUtPnNwZWNpZmljX3R5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZihwZHUtPnNwZWNpZmljX3R5cGUpKTsKICAgICAgICBERUJVR0lOREVOVExFU1MoKTsKICAgICAgICBpZiAoY3AgPT0gTlVMTCkKICAgICAgICAgICAgcmV0dXJuIE5VTEw7CgogICAgICAgIC8qCiAgICAgICAgICogdGltZXN0YW1wICAKICAgICAgICAgKi8KICAgICAgICBERUJVR0RVTVBIRUFERVIoInNlbmQiLCAidGltZXN0YW1wIik7CiAgICAgICAgY3AgPSBhc25fYnVpbGRfdW5zaWduZWRfaW50KGNwLCBvdXRfbGVuZ3RoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodV9jaGFyKSAoQVNOX1RJTUVUSUNLUyB8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBU05fUFJJTUlUSVZFKSwgJnBkdS0+dGltZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZW9mKHBkdS0+dGltZSkpOwogICAgICAgIERFQlVHSU5ERU5UTEVTUygpOwogICAgICAgIGlmIChjcCA9PSBOVUxMKQogICAgICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0KCiAgICAvKgogICAgICogU2F2ZSBjdXJyZW50IGxvY2F0aW9uIGFuZCBidWlsZCBTRVFVRU5DRSB0YWcgYW5kIGxlbmd0aCBwbGFjZWhvbGRlcgogICAgICogZm9yIHZhcmlhYmxlLWJpbmRpbmdzIHNlcXVlbmNlCiAgICAgKiAoYWN0dWFsIGxlbmd0aCB3aWxsIGJlIGluc2VydGVkIGxhdGVyKSAKICAgICAqLwogICAgaDIgPSBjcDsKICAgIGNwID0gYXNuX2J1aWxkX3NlcXVlbmNlKGNwLCBvdXRfbGVuZ3RoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgKHVfY2hhcikgKEFTTl9TRVFVRU5DRSB8IEFTTl9DT05TVFJVQ1RPUiksIDApOwogICAgaWYgKGNwID09IE5VTEwpCiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICBoMmUgPSBjcDsKCiAgICAvKgogICAgICogU3RvcmUgdmFyaWFibGUtYmluZGluZ3MgCiAgICAgKi8KICAgIERFQlVHRFVNUFNFQ1RJT04oInNlbmQiLCAiVmFyQmluZExpc3QiKTsKICAgIGZvciAodnAgPSBwZHUtPnZhcmlhYmxlczsgdnA7IHZwID0gdnAtPm5leHRfdmFyaWFibGUpIHsKICAgICAgICBERUJVR0RVTVBTRUNUSU9OKCJzZW5kIiwgIlZhckJpbmQiKTsKICAgICAgICBjcCA9IHNubXBfYnVpbGRfdmFyX29wKGNwLCB2cC0+bmFtZSwgJnZwLT5uYW1lX2xlbmd0aCwgdnAtPnR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2cC0+dmFsX2xlbiwgKHVfY2hhciAqKSB2cC0+dmFsLnN0cmluZywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG91dF9sZW5ndGgpOwogICAgICAgIERFQlVHSU5ERU5UTEVTUygpOwogICAgICAgIGlmIChjcCA9PSBOVUxMKQogICAgICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0KICAgIERFQlVHSU5ERU5UTEVTUygpOwoKICAgIC8qCiAgICAgKiBpbnNlcnQgYWN0dWFsIGxlbmd0aCBvZiB2YXJpYWJsZS1iaW5kaW5ncyBzZXF1ZW5jZSAKICAgICAqLwogICAgYXNuX2J1aWxkX3NlcXVlbmNlKGgyLCAmbGVuZ3RoLAogICAgICAgICAgICAgICAgICAgICAgICh1X2NoYXIpIChBU05fU0VRVUVOQ0UgfCBBU05fQ09OU1RSVUNUT1IpLAogICAgICAgICAgICAgICAgICAgICAgIGNwIC0gaDJlKTsKCiAgICAvKgogICAgICogaW5zZXJ0IGFjdHVhbCBsZW5ndGggb2YgUERVIHNlcXVlbmNlIAogICAgICovCiAgICBhc25fYnVpbGRfc2VxdWVuY2UoaDEsICZsZW5ndGgsICh1X2NoYXIpIHBkdS0+Y29tbWFuZCwgY3AgLSBoMWUpOwoKICAgIHJldHVybiBjcDsKfQoKI2lmZGVmIE5FVFNOTVBfVVNFX1JFVkVSU0VfQVNORU5DT0RJTkcKLyoKICogT24gZXJyb3IsIHJldHVybnMgMCAobGlrZWx5IGFuIGVuY29kaW5nIHByb2JsZW0pLiAgCiAqLwppbnQKc25tcF9wZHVfcmVhbGxvY19yYnVpbGQodV9jaGFyICoqIHBrdCwgc2l6ZV90ICogcGt0X2xlbiwgc2l6ZV90ICogb2Zmc2V0LAogICAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX3BkdSAqcGR1KQp7CiNpZm5kZWYgVlBDQUNIRV9TSVpFCiNkZWZpbmUgVlBDQUNIRV9TSVpFIDUwCiNlbmRpZgogICAgbmV0c25tcF92YXJpYWJsZV9saXN0ICp2cGNhY2hlW1ZQQ0FDSEVfU0laRV07CiAgICBuZXRzbm1wX3ZhcmlhYmxlX2xpc3QgKnZwLCAqdG1wdnA7CiAgICBzaXplX3QgICAgICAgICAgc3RhcnRfb2Zmc2V0ID0gKm9mZnNldDsKICAgIGludCAgICAgICAgICAgICBpLCB3cmFwcGVkID0gMCwgbm90ZG9uZSwgZmluYWwsIHJjID0gMDsKCiAgICBERUJVR01TR1RMKCgic25tcF9wZHVfcmVhbGxvY19yYnVpbGQiLCAic3RhcnRpbmdcbiIpKTsKICAgIGZvciAodnAgPSBwZHUtPnZhcmlhYmxlcywgaSA9IFZQQ0FDSEVfU0laRSAtIDE7IHZwOwogICAgICAgICB2cCA9IHZwLT5uZXh0X3ZhcmlhYmxlLCBpLS0pIHsKICAgICAgICBpZiAoaSA8IDApIHsKICAgICAgICAgICAgd3JhcHBlZCA9IG5vdGRvbmUgPSAxOwogICAgICAgICAgICBpID0gVlBDQUNIRV9TSVpFIC0gMTsKICAgICAgICAgICAgREVCVUdNU0dUTCgoInNubXBfcGR1X3JlYWxsb2NfcmJ1aWxkIiwgIndyYXBwZWRcbiIpKTsKICAgICAgICB9CiAgICAgICAgdnBjYWNoZVtpXSA9IHZwOwogICAgfQogICAgZmluYWwgPSBpICsgMTsKCiAgICBkbyB7CiAgICAgICAgZm9yIChpID0gZmluYWw7IGkgPCBWUENBQ0hFX1NJWkU7IGkrKykgewogICAgICAgICAgICB2cCA9IHZwY2FjaGVbaV07CiAgICAgICAgICAgIERFQlVHRFVNUFNFQ1RJT04oInNlbmQiLCAiVmFyQmluZCIpOwogICAgICAgICAgICByYyA9IHNubXBfcmVhbGxvY19yYnVpbGRfdmFyX29wKHBrdCwgcGt0X2xlbiwgb2Zmc2V0LCAxLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZwLT5uYW1lLCAmdnAtPm5hbWVfbGVuZ3RoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZwLT50eXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh1X2NoYXIgKikgdnAtPnZhbC5zdHJpbmcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdnAtPnZhbF9sZW4pOwogICAgICAgICAgICBERUJVR0lOREVOVExFU1MoKTsKICAgICAgICAgICAgaWYgKHJjID09IDApIHsKICAgICAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBERUJVR0lOREVOVExFU1MoKTsKICAgICAgICBpZiAod3JhcHBlZCkgewogICAgICAgICAgICBub3Rkb25lID0gMTsKICAgICAgICAgICAgZm9yIChpID0gMDsgaSA8IGZpbmFsOyBpKyspIHsKICAgICAgICAgICAgICAgIHZwID0gdnBjYWNoZVtpXTsKICAgICAgICAgICAgICAgIERFQlVHRFVNUFNFQ1RJT04oInNlbmQiLCAiVmFyQmluZCIpOwogICAgICAgICAgICAgICAgcmMgPSBzbm1wX3JlYWxsb2NfcmJ1aWxkX3Zhcl9vcChwa3QsIHBrdF9sZW4sIG9mZnNldCwgMSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdnAtPm5hbWUsICZ2cC0+bmFtZV9sZW5ndGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZwLT50eXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodV9jaGFyICopIHZwLT52YWwuc3RyaW5nLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2cC0+dmFsX2xlbik7CiAgICAgICAgICAgICAgICBERUJVR0lOREVOVExFU1MoKTsKICAgICAgICAgICAgICAgIGlmIChyYyA9PSAwKSB7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGlmIChmaW5hbCA9PSAwKSB7CiAgICAgICAgICAgICAgICB0bXB2cCA9IHZwY2FjaGVbVlBDQUNIRV9TSVpFIC0gMV07CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICB0bXB2cCA9IHZwY2FjaGVbZmluYWwgLSAxXTsKICAgICAgICAgICAgfQogICAgICAgICAgICB3cmFwcGVkID0gMDsKCiAgICAgICAgICAgIGZvciAodnAgPSBwZHUtPnZhcmlhYmxlcywgaSA9IFZQQ0FDSEVfU0laRSAtIDE7CiAgICAgICAgICAgICAgICAgdnAgJiYgdnAgIT0gdG1wdnA7IHZwID0gdnAtPm5leHRfdmFyaWFibGUsIGktLSkgewogICAgICAgICAgICAgICAgaWYgKGkgPCAwKSB7CiAgICAgICAgICAgICAgICAgICAgd3JhcHBlZCA9IDE7CiAgICAgICAgICAgICAgICAgICAgaSA9IFZQQ0FDSEVfU0laRSAtIDE7CiAgICAgICAgICAgICAgICAgICAgREVCVUdNU0dUTCgoInNubXBfcGR1X3JlYWxsb2NfcmJ1aWxkIiwgIndyYXBwZWRcbiIpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHZwY2FjaGVbaV0gPSB2cDsKICAgICAgICAgICAgfQogICAgICAgICAgICBmaW5hbCA9IGkgKyAxOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIG5vdGRvbmUgPSAwOwogICAgICAgIH0KICAgIH0gd2hpbGUgKG5vdGRvbmUpOwoKICAgIC8qCiAgICAgKiBTYXZlIGN1cnJlbnQgbG9jYXRpb24gYW5kIGJ1aWxkIFNFUVVFTkNFIHRhZyBhbmQgbGVuZ3RoIHBsYWNlaG9sZGVyIGZvcgogICAgICogdmFyaWFibGUtYmluZGluZ3Mgc2VxdWVuY2UgKGFjdHVhbCBsZW5ndGggd2lsbCBiZSBpbnNlcnRlZCBsYXRlcikuICAKICAgICAqLwoKICAgIHJjID0gYXNuX3JlYWxsb2NfcmJ1aWxkX3NlcXVlbmNlKHBrdCwgcGt0X2xlbiwgb2Zmc2V0LCAxLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHVfY2hhcikgKEFTTl9TRVFVRU5DRSB8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQVNOX0NPTlNUUlVDVE9SKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICpvZmZzZXQgLSBzdGFydF9vZmZzZXQpOwoKICAgIC8qCiAgICAgKiBTdG9yZSBmaWVsZHMgaW4gdGhlIFBEVSBwcmVjZWVkaW5nIHRoZSB2YXJpYWJsZS1iaW5kaW5ncyBzZXF1ZW5jZS4gIAogICAgICovCiAgICBpZiAocGR1LT5jb21tYW5kICE9IFNOTVBfTVNHX1RSQVApIHsKICAgICAgICAvKgogICAgICAgICAqIEVycm9yIGluZGV4IChnZXRidWxrIG1heC1yZXBldGl0aW9ucykuICAKICAgICAgICAgKi8KICAgICAgICBERUJVR0RVTVBIRUFERVIoInNlbmQiLCAiZXJyb3IgaW5kZXgiKTsKICAgICAgICByYyA9IGFzbl9yZWFsbG9jX3JidWlsZF9pbnQocGt0LCBwa3RfbGVuLCBvZmZzZXQsIDEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh1X2NoYXIpIChBU05fVU5JVkVSU0FMIHwgQVNOX1BSSU1JVElWRQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBBU05fSU5URUdFUiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZwZHUtPmVycmluZGV4LCBzaXplb2YocGR1LT5lcnJpbmRleCkpOwogICAgICAgIERFQlVHSU5ERU5UTEVTUygpOwogICAgICAgIGlmIChyYyA9PSAwKSB7CiAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgIH0KCiAgICAgICAgLyoKICAgICAgICAgKiBFcnJvciBzdGF0dXMgKGdldGJ1bGsgbm9uLXJlcGVhdGVycykuICAKICAgICAgICAgKi8KICAgICAgICBERUJVR0RVTVBIRUFERVIoInNlbmQiLCAiZXJyb3Igc3RhdHVzIik7CiAgICAgICAgcmMgPSBhc25fcmVhbGxvY19yYnVpbGRfaW50KHBrdCwgcGt0X2xlbiwgb2Zmc2V0LCAxLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodV9jaGFyKSAoQVNOX1VOSVZFUlNBTCB8IEFTTl9QUklNSVRJVkUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgQVNOX0lOVEVHRVIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmcGR1LT5lcnJzdGF0LCBzaXplb2YocGR1LT5lcnJzdGF0KSk7CiAgICAgICAgREVCVUdJTkRFTlRMRVNTKCk7CiAgICAgICAgaWYgKHJjID09IDApIHsKICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgfQoKICAgICAgICAvKgogICAgICAgICAqIFJlcXVlc3QgSUQuICAKICAgICAgICAgKi8KICAgICAgICBERUJVR0RVTVBIRUFERVIoInNlbmQiLCAicmVxdWVzdF9pZCIpOwogICAgICAgIHJjID0gYXNuX3JlYWxsb2NfcmJ1aWxkX2ludChwa3QsIHBrdF9sZW4sIG9mZnNldCwgMSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHVfY2hhcikgKEFTTl9VTklWRVJTQUwgfCBBU05fUFJJTUlUSVZFCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8IEFTTl9JTlRFR0VSKSwgJnBkdS0+cmVxaWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZihwZHUtPnJlcWlkKSk7CiAgICAgICAgREVCVUdJTkRFTlRMRVNTKCk7CiAgICAgICAgaWYgKHJjID09IDApIHsKICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgfQogICAgfSBlbHNlIHsKICAgICAgICAvKgogICAgICAgICAqIEFuIFNOTVB2MSB0cmFwIFBEVS4gIAogICAgICAgICAqLwoKICAgICAgICAvKgogICAgICAgICAqIFRpbWVzdGFtcC4gIAogICAgICAgICAqLwogICAgICAgIERFQlVHRFVNUEhFQURFUigic2VuZCIsICJ0aW1lc3RhbXAiKTsKICAgICAgICByYyA9IGFzbl9yZWFsbG9jX3JidWlsZF91bnNpZ25lZF9pbnQocGt0LCBwa3RfbGVuLCBvZmZzZXQsIDEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh1X2NoYXIpIChBU05fVElNRVRJQ0tTIHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEFTTl9QUklNSVRJVkUpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmcGR1LT50aW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplb2YocGR1LT50aW1lKSk7CiAgICAgICAgREVCVUdJTkRFTlRMRVNTKCk7CiAgICAgICAgaWYgKHJjID09IDApIHsKICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgfQoKICAgICAgICAvKgogICAgICAgICAqIFNwZWNpZmljIHRyYXAuICAKICAgICAgICAgKi8KICAgICAgICBERUJVR0RVTVBIRUFERVIoInNlbmQiLCAic3BlY2lmaWMgdHJhcCBudW1iZXIiKTsKICAgICAgICByYyA9IGFzbl9yZWFsbG9jX3JidWlsZF9pbnQocGt0LCBwa3RfbGVuLCBvZmZzZXQsIDEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh1X2NoYXIpIChBU05fVU5JVkVSU0FMIHwgQVNOX1BSSU1JVElWRQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBBU05fSU5URUdFUiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChsb25nICopICZwZHUtPnNwZWNpZmljX3R5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZihwZHUtPnNwZWNpZmljX3R5cGUpKTsKICAgICAgICBERUJVR0lOREVOVExFU1MoKTsKICAgICAgICBpZiAocmMgPT0gMCkgewogICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICB9CgogICAgICAgIC8qCiAgICAgICAgICogR2VuZXJpYyB0cmFwLiAgCiAgICAgICAgICovCiAgICAgICAgREVCVUdEVU1QSEVBREVSKCJzZW5kIiwgImdlbmVyaWMgdHJhcCBudW1iZXIiKTsKICAgICAgICByYyA9IGFzbl9yZWFsbG9jX3JidWlsZF9pbnQocGt0LCBwa3RfbGVuLCBvZmZzZXQsIDEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh1X2NoYXIpIChBU05fVU5JVkVSU0FMIHwgQVNOX1BSSU1JVElWRQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfCBBU05fSU5URUdFUiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChsb25nICopICZwZHUtPnRyYXBfdHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZW9mKHBkdS0+dHJhcF90eXBlKSk7CiAgICAgICAgREVCVUdJTkRFTlRMRVNTKCk7CiAgICAgICAgaWYgKHJjID09IDApIHsKICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgfQoKICAgICAgICAvKgogICAgICAgICAqIEFnZW50LWFkZHIuICAKICAgICAgICAgKi8KICAgICAgICBERUJVR0RVTVBIRUFERVIoInNlbmQiLCAiYWdlbnQgQWRkcmVzcyIpOwogICAgICAgIHJjID0gYXNuX3JlYWxsb2NfcmJ1aWxkX3N0cmluZyhwa3QsIHBrdF9sZW4sIG9mZnNldCwgMSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHVfY2hhcikgKEFTTl9JUEFERFJFU1MgfAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQVNOX1BSSU1JVElWRSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh1X2NoYXIgKikgcGR1LT5hZ2VudF9hZGRyLCA0KTsKICAgICAgICBERUJVR0lOREVOVExFU1MoKTsKICAgICAgICBpZiAocmMgPT0gMCkgewogICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICB9CgogICAgICAgIC8qCiAgICAgICAgICogRW50ZXJwcmlzZS4gIAogICAgICAgICAqLwogICAgICAgIERFQlVHRFVNUEhFQURFUigic2VuZCIsICJlbnRlcnByaXNlIE9CSklEIik7CiAgICAgICAgcmMgPSBhc25fcmVhbGxvY19yYnVpbGRfb2JqaWQocGt0LCBwa3RfbGVuLCBvZmZzZXQsIDEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHVfY2hhcikgKEFTTl9VTklWRVJTQUwgfAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBU05fUFJJTUlUSVZFIHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQVNOX09CSkVDVF9JRCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKG9pZCAqKSBwZHUtPmVudGVycHJpc2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGR1LT5lbnRlcnByaXNlX2xlbmd0aCk7CiAgICAgICAgREVCVUdJTkRFTlRMRVNTKCk7CiAgICAgICAgaWYgKHJjID09IDApIHsKICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgfQogICAgfQoKICAgIC8qCiAgICAgKiBCdWlsZCB0aGUgUERVIHNlcXVlbmNlLiAgCiAgICAgKi8KICAgIHJjID0gYXNuX3JlYWxsb2NfcmJ1aWxkX3NlcXVlbmNlKHBrdCwgcGt0X2xlbiwgb2Zmc2V0LCAxLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHVfY2hhcikgcGR1LT5jb21tYW5kLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKm9mZnNldCAtIHN0YXJ0X29mZnNldCk7CiAgICByZXR1cm4gcmM7Cn0KI2VuZGlmICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBORVRTTk1QX1VTRV9SRVZFUlNFX0FTTkVOQ09ESU5HICovCgovKgogKiBQYXJzZXMgdGhlIHBhY2tldCByZWNlaXZlZCB0byBkZXRlcm1pbmUgdmVyc2lvbiwgZWl0aGVyIGRpcmVjdGx5CiAqIGZyb20gcGFja2V0cyB2ZXJzaW9uIGZpZWxkIG9yIGluZmVycmVkIGZyb20gQVNOLjEgY29uc3RydWN0LgogKi8Kc3RhdGljIGludApzbm1wX3BhcnNlX3ZlcnNpb24odV9jaGFyICogZGF0YSwgc2l6ZV90IGxlbmd0aCkKewogICAgdV9jaGFyICAgICAgICAgIHR5cGU7CiAgICBsb25nICAgICAgICAgICAgdmVyc2lvbiA9IFNOTVBFUlJfQkFEX1ZFUlNJT047CgogICAgZGF0YSA9IGFzbl9wYXJzZV9zZXF1ZW5jZShkYXRhLCAmbGVuZ3RoLCAmdHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKEFTTl9TRVFVRU5DRSB8IEFTTl9DT05TVFJVQ1RPUiksICJ2ZXJzaW9uIik7CiAgICBpZiAoZGF0YSkgewogICAgICAgIERFQlVHRFVNUEhFQURFUigicmVjdiIsICJTTk1QIFZlcnNpb24iKTsKICAgICAgICBkYXRhID0KICAgICAgICAgICAgYXNuX3BhcnNlX2ludChkYXRhLCAmbGVuZ3RoLCAmdHlwZSwgJnZlcnNpb24sIHNpemVvZih2ZXJzaW9uKSk7CiAgICAgICAgREVCVUdJTkRFTlRMRVNTKCk7CiAgICAgICAgaWYgKCFkYXRhIHx8IHR5cGUgIT0gQVNOX0lOVEVHRVIpIHsKICAgICAgICAgICAgcmV0dXJuIFNOTVBFUlJfQkFEX1ZFUlNJT047CiAgICAgICAgfQogICAgfQogICAgcmV0dXJuIHZlcnNpb247Cn0KCgppbnQKc25tcHYzX3BhcnNlKG5ldHNubXBfcGR1ICpwZHUsCiAgICAgICAgICAgICB1X2NoYXIgKiBkYXRhLAogICAgICAgICAgICAgc2l6ZV90ICogbGVuZ3RoLAogICAgICAgICAgICAgdV9jaGFyICoqIGFmdGVyX2hlYWRlciwgbmV0c25tcF9zZXNzaW9uICogc2VzcykKewogICAgdV9jaGFyICAgICAgICAgIHR5cGUsIG1zZ19mbGFnczsKICAgIGxvbmcgICAgICAgICAgICB2ZXIsIG1zZ19tYXhfc2l6ZSwgbXNnX3NlY19tb2RlbDsKICAgIHNpemVfdCAgICAgICAgICBtYXhfc2l6ZV9yZXNwb25zZTsKICAgIHVfY2hhciAgICAgICAgICB0bXBfYnVmW1NOTVBfTUFYX01TR19TSVpFXTsKICAgIHNpemVfdCAgICAgICAgICB0bXBfYnVmX2xlbjsKICAgIHVfY2hhciAgICAgICAgICBwZHVfYnVmW1NOTVBfTUFYX01TR19TSVpFXTsKICAgIHVfY2hhciAgICAgICAgICptYWxsb2NidWYgPSBOVUxMOwogICAgc2l6ZV90ICAgICAgICAgIHBkdV9idWZfbGVuID0gU05NUF9NQVhfTVNHX1NJWkU7CiAgICB1X2NoYXIgICAgICAgICAqc2VjX3BhcmFtczsKICAgIHVfY2hhciAgICAgICAgICptc2dfZGF0YTsKICAgIHVfY2hhciAgICAgICAgICpjcDsKICAgIHNpemVfdCAgICAgICAgICBhc25fbGVuLCBtc2dfbGVuOwogICAgaW50ICAgICAgICAgICAgIHJldCwgcmV0X3ZhbDsKICAgIHN0cnVjdCBzbm1wX3NlY21vZF9kZWYgKnNwdHI7CgoKICAgIG1zZ19kYXRhID0gZGF0YTsKICAgIG1zZ19sZW4gPSAqbGVuZ3RoOwoKCiAgICAvKgogICAgICogbWVzc2FnZSBpcyBhbiBBU04uMSBTRVFVRU5DRSAgCiAgICAgKi8KICAgIERFQlVHRFVNUFNFQ1RJT04oInJlY3YiLCAiU05NUHYzIE1lc3NhZ2UiKTsKICAgIGRhdGEgPSBhc25fcGFyc2Vfc2VxdWVuY2UoZGF0YSwgbGVuZ3RoLCAmdHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKEFTTl9TRVFVRU5DRSB8IEFTTl9DT05TVFJVQ1RPUiksICJtZXNzYWdlIik7CiAgICBpZiAoZGF0YSA9PSBOVUxMKSB7CiAgICAgICAgLyoKICAgICAgICAgKiBlcnJvciBtc2cgZGV0YWlsIGlzIHNldCAKICAgICAgICAgKi8KICAgICAgICBzbm1wX2luY3JlbWVudF9zdGF0aXN0aWMoU1RBVF9TTk1QSU5BU05QQVJTRUVSUlMpOwogICAgICAgIERFQlVHSU5ERU5UTEVTUygpOwogICAgICAgIHJldHVybiBTTk1QRVJSX0FTTl9QQVJTRV9FUlI7CiAgICB9CgogICAgLyoKICAgICAqIHBhcnNlIG1zZ1ZlcnNpb24gIAogICAgICovCiAgICBERUJVR0RVTVBIRUFERVIoInJlY3YiLCAiU05NUCBWZXJzaW9uIE51bWJlciIpOwogICAgZGF0YSA9IGFzbl9wYXJzZV9pbnQoZGF0YSwgbGVuZ3RoLCAmdHlwZSwgJnZlciwgc2l6ZW9mKHZlcikpOwogICAgREVCVUdJTkRFTlRMRVNTKCk7CiAgICBpZiAoZGF0YSA9PSBOVUxMKSB7CiAgICAgICAgRVJST1JfTVNHKCJiYWQgcGFyc2Ugb2YgdmVyc2lvbiIpOwogICAgICAgIHNubXBfaW5jcmVtZW50X3N0YXRpc3RpYyhTVEFUX1NOTVBJTkFTTlBBUlNFRVJSUyk7CiAgICAgICAgREVCVUdJTkRFTlRMRVNTKCk7CiAgICAgICAgcmV0dXJuIFNOTVBFUlJfQVNOX1BBUlNFX0VSUjsKICAgIH0KICAgIHBkdS0+dmVyc2lvbiA9IHZlcjsKCiAgICAvKgogICAgICogcGFyc2UgbXNnR2xvYmFsRGF0YSBzZXF1ZW5jZSAgCiAgICAgKi8KICAgIGNwID0gZGF0YTsKICAgIGFzbl9sZW4gPSAqbGVuZ3RoOwogICAgREVCVUdEVU1QU0VDVElPTigicmVjdiIsICJtc2dHbG9iYWxEYXRhIik7CiAgICBkYXRhID0gYXNuX3BhcnNlX3NlcXVlbmNlKGRhdGEsICZhc25fbGVuLCAmdHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKEFTTl9TRVFVRU5DRSB8IEFTTl9DT05TVFJVQ1RPUiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJtc2dHbG9iYWxEYXRhIik7CiAgICBpZiAoZGF0YSA9PSBOVUxMKSB7CiAgICAgICAgLyoKICAgICAgICAgKiBlcnJvciBtc2cgZGV0YWlsIGlzIHNldCAKICAgICAgICAgKi8KICAgICAgICBzbm1wX2luY3JlbWVudF9zdGF0aXN0aWMoU1RBVF9TTk1QSU5BU05QQVJTRUVSUlMpOwogICAgICAgIERFQlVHSU5ERU5UQUREKC00KTsKICAgICAgICByZXR1cm4gU05NUEVSUl9BU05fUEFSU0VfRVJSOwogICAgfQogICAgKmxlbmd0aCAtPSBkYXRhIC0gY3A7ICAgICAgIC8qIHN1YnRyYWN0IG9mZiB0aGUgbGVuZ3RoIG9mIHRoZSBoZWFkZXIgKi8KCiAgICAvKgogICAgICogbXNnSUQgCiAgICAgKi8KICAgIERFQlVHRFVNUEhFQURFUigicmVjdiIsICJtc2dJRCIpOwogICAgZGF0YSA9CiAgICAgICAgYXNuX3BhcnNlX2ludChkYXRhLCBsZW5ndGgsICZ0eXBlLCAmcGR1LT5tc2dpZCwKICAgICAgICAgICAgICAgICAgICAgIHNpemVvZihwZHUtPm1zZ2lkKSk7CiAgICBERUJVR0lOREVOVExFU1MoKTsKICAgIGlmIChkYXRhID09IE5VTEwgfHwgdHlwZSAhPSBBU05fSU5URUdFUikgewogICAgICAgIEVSUk9SX01TRygiZXJyb3IgcGFyc2luZyBtc2dJRCIpOwogICAgICAgIERFQlVHSU5ERU5UQUREKC00KTsKICAgICAgICBzbm1wX2luY3JlbWVudF9zdGF0aXN0aWMoU1RBVF9TTk1QSU5BU05QQVJTRUVSUlMpOwogICAgICAgIHJldHVybiBTTk1QRVJSX0FTTl9QQVJTRV9FUlI7CiAgICB9CgogICAgLyoKICAgICAqIENoZWNrIHRoZSBtc2dJRCB3ZSByZWNlaXZlZCBpcyBhIGxlZ2FsIHZhbHVlLiAgSWYgbm90LCB0aGVuIGluY3JlbWVudAogICAgICogc25tcEluQVNOUGFyc2VFcnJzIGFuZCByZXR1cm4gdGhlIGFwcHJvcHJpYXRlIGVycm9yIChzZWUgUkZDIDI1NzIsCiAgICAgKiBwYXJhLiA3LjIsIHNlY3Rpb24gMiAtLSBub3RlIHRoYXQgYSBiYWQgbXNnSUQgbWVhbnMgdGhhdCB0aGUgcmVjZWl2ZWQKICAgICAqIG1lc3NhZ2UgaXMgTk9UIGEgc2VyaWFsaWl6YXRpb24gb2YgYW4gU05NUHYzTWVzc2FnZSwgc2luY2UgdGhlIG1zZ0lECiAgICAgKiBmaWVsZCBpcyBvdXQgb2YgYm91bmRzKS4gIAogICAgICovCgogICAgaWYgKHBkdS0+bXNnaWQgPCAwIHx8IHBkdS0+bXNnaWQgPiAweDdmZmZmZmZmKSB7CiAgICAgICAgc25tcF9sb2coTE9HX0VSUiwgIlJlY2VpdmVkIGJhZCBtc2dJRCAoJWxkICVzICVzKS5cbiIsIHBkdS0+bXNnaWQsCiAgICAgICAgICAgICAgICAgKHBkdS0+bXNnaWQgPCAwKSA/ICI8IiA6ICI+IiwKICAgICAgICAgICAgICAgICAocGR1LT5tc2dpZCA8IDApID8gIjAiIDogIjJeMzEgLSAxIik7CiAgICAgICAgc25tcF9pbmNyZW1lbnRfc3RhdGlzdGljKFNUQVRfU05NUElOQVNOUEFSU0VFUlJTKTsKICAgICAgICBERUJVR0lOREVOVEFERCgtNCk7CiAgICAgICAgcmV0dXJuIFNOTVBFUlJfQVNOX1BBUlNFX0VSUjsKICAgIH0KCiAgICAvKgogICAgICogbXNnTWF4U2l6ZSAKICAgICAqLwogICAgREVCVUdEVU1QSEVBREVSKCJyZWN2IiwgIm1zZ01heFNpemUiKTsKICAgIGRhdGEgPSBhc25fcGFyc2VfaW50KGRhdGEsIGxlbmd0aCwgJnR5cGUsICZtc2dfbWF4X3NpemUsCiAgICAgICAgICAgICAgICAgICAgICAgICBzaXplb2YobXNnX21heF9zaXplKSk7CiAgICBERUJVR0lOREVOVExFU1MoKTsKICAgIGlmIChkYXRhID09IE5VTEwgfHwgdHlwZSAhPSBBU05fSU5URUdFUikgewogICAgICAgIEVSUk9SX01TRygiZXJyb3IgcGFyc2luZyBtc2dNYXhTaXplIik7CiAgICAgICAgc25tcF9pbmNyZW1lbnRfc3RhdGlzdGljKFNUQVRfU05NUElOQVNOUEFSU0VFUlJTKTsKICAgICAgICBERUJVR0lOREVOVEFERCgtNCk7CiAgICAgICAgcmV0dXJuIFNOTVBFUlJfQVNOX1BBUlNFX0VSUjsKICAgIH0KCiAgICAvKgogICAgICogQ2hlY2sgdGhlIG1zZ01heFNpemUgd2UgcmVjZWl2ZWQgaXMgYSBsZWdhbCB2YWx1ZS4gIElmIG5vdCwgdGhlbgogICAgICogaW5jcmVtZW50IHNubXBJbkFTTlBhcnNlRXJycyBhbmQgcmV0dXJuIHRoZSBhcHByb3ByaWF0ZSBlcnJvciAoc2VlIFJGQwogICAgICogMjU3MiwgcGFyYS4gNy4yLCBzZWN0aW9uIDIgLS0gbm90ZSB0aGF0IGEgYmFkIG1zZ01heFNpemUgbWVhbnMgdGhhdCB0aGUKICAgICAqIHJlY2VpdmVkIG1lc3NhZ2UgaXMgTk9UIGEgc2VyaWFsaWl6YXRpb24gb2YgYW4gU05NUHYzTWVzc2FnZSwgc2luY2UgdGhlCiAgICAgKiBtc2dNYXhTaXplIGZpZWxkIGlzIG91dCBvZiBib3VuZHMpLgogICAgICogCiAgICAgKiBOb3RlIHdlIHN0b3JlIHRoZSBtc2dNYXhTaXplIG9uIGEgcGVyLXNlc3Npb24gYmFzaXMgd2hpY2ggYWxzbyBzZWVtcwogICAgICogcmVhc29uYWJsZTsgaXQgY291bGQgdmFyeSBmcm9tIFBEVSB0byBQRFUgYnV0IHRoYXQgd291bGQgYmUgc3RyYW5nZQogICAgICogKGFsc28gc2luY2Ugd2UgZGVhbCB3aXRoIGEgUERVIGF0IGEgdGltZSwgaXQgd291bGRuJ3QgbWFrZSBhbnkKICAgICAqIGRpZmZlcmVuY2UgdG8gb3VyIHJlc3BvbnNlcywgaWYgYW55KS4gIAogICAgICovCgogICAgaWYgKG1zZ19tYXhfc2l6ZSA8IDQ4NCkgewogICAgICAgIHNubXBfbG9nKExPR19FUlIsICJSZWNlaXZlZCBiYWQgbXNnTWF4U2l6ZSAoJWx1IDwgNDg0KS5cbiIsCiAgICAgICAgICAgICAgICAgbXNnX21heF9zaXplKTsKICAgICAgICBzbm1wX2luY3JlbWVudF9zdGF0aXN0aWMoU1RBVF9TTk1QSU5BU05QQVJTRUVSUlMpOwogICAgICAgIERFQlVHSU5ERU5UQUREKC00KTsKICAgICAgICByZXR1cm4gU05NUEVSUl9BU05fUEFSU0VfRVJSOwogICAgfSBlbHNlIGlmIChtc2dfbWF4X3NpemUgPiAweDdmZmZmZmZmKSB7CiAgICAgICAgc25tcF9sb2coTE9HX0VSUiwgIlJlY2VpdmVkIGJhZCBtc2dNYXhTaXplICglbHUgPiAyXjMxIC0gMSkuXG4iLAogICAgICAgICAgICAgICAgIG1zZ19tYXhfc2l6ZSk7CiAgICAgICAgc25tcF9pbmNyZW1lbnRfc3RhdGlzdGljKFNUQVRfU05NUElOQVNOUEFSU0VFUlJTKTsKICAgICAgICBERUJVR0lOREVOVEFERCgtNCk7CiAgICAgICAgcmV0dXJuIFNOTVBFUlJfQVNOX1BBUlNFX0VSUjsKICAgIH0gZWxzZSB7CiAgICAgICAgREVCVUdNU0dUTCgoInNubXB2M19wYXJzZSIsICJtc2dNYXhTaXplICVsdSByZWNlaXZlZFxuIiwKICAgICAgICAgICAgICAgICAgICBtc2dfbWF4X3NpemUpKTsKICAgICAgICBzZXNzLT5zbmRNc2dNYXhTaXplID0gbXNnX21heF9zaXplOwogICAgfQoKICAgIC8qCiAgICAgKiBtc2dGbGFncyAKICAgICAqLwogICAgdG1wX2J1Zl9sZW4gPSBTTk1QX01BWF9NU0dfU0laRTsKICAgIERFQlVHRFVNUEhFQURFUigicmVjdiIsICJtc2dGbGFncyIpOwogICAgZGF0YSA9IGFzbl9wYXJzZV9zdHJpbmcoZGF0YSwgbGVuZ3RoLCAmdHlwZSwgdG1wX2J1ZiwgJnRtcF9idWZfbGVuKTsKICAgIERFQlVHSU5ERU5UTEVTUygpOwogICAgaWYgKGRhdGEgPT0gTlVMTCB8fCB0eXBlICE9IEFTTl9PQ1RFVF9TVFIgfHwgdG1wX2J1Zl9sZW4gIT0gMSkgewogICAgICAgIEVSUk9SX01TRygiZXJyb3IgcGFyc2luZyBtc2dGbGFncyIpOwogICAgICAgIHNubXBfaW5jcmVtZW50X3N0YXRpc3RpYyhTVEFUX1NOTVBJTkFTTlBBUlNFRVJSUyk7CiAgICAgICAgREVCVUdJTkRFTlRBREQoLTQpOwogICAgICAgIHJldHVybiBTTk1QRVJSX0FTTl9QQVJTRV9FUlI7CiAgICB9CiAgICBtc2dfZmxhZ3MgPSAqdG1wX2J1ZjsKICAgIGlmIChtc2dfZmxhZ3MgJiBTTk1QX01TR19GTEFHX1JQUlRfQklUKQogICAgICAgIHBkdS0+ZmxhZ3MgfD0gU05NUF9NU0dfRkxBR19SUFJUX0JJVDsKICAgIGVsc2UKICAgICAgICBwZHUtPmZsYWdzICY9ICh+U05NUF9NU0dfRkxBR19SUFJUX0JJVCk7CgogICAgLyoKICAgICAqIG1zZ1NlY3VyaXR5TW9kZWwgCiAgICAgKi8KICAgIERFQlVHRFVNUEhFQURFUigicmVjdiIsICJtc2dTZWN1cml0eU1vZGVsIik7CiAgICBkYXRhID0gYXNuX3BhcnNlX2ludChkYXRhLCBsZW5ndGgsICZ0eXBlLCAmbXNnX3NlY19tb2RlbCwKICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZihtc2dfc2VjX21vZGVsKSk7CiAgICBERUJVR0lOREVOVEFERCgtNCk7ICAgICAgICAgLyogcmV0dXJuIGZyb20gZ2xvYmFsIGRhdGEgaW5kZW50ICovCiAgICBpZiAoZGF0YSA9PSBOVUxMIHx8IHR5cGUgIT0gQVNOX0lOVEVHRVIgfHwKICAgICAgICBtc2dfc2VjX21vZGVsIDwgMSB8fCBtc2dfc2VjX21vZGVsID4gMHg3ZmZmZmZmZikgewogICAgICAgIEVSUk9SX01TRygiZXJyb3IgcGFyc2luZyBtc2dTZWN1cml0eU1vZGVsIik7CiAgICAgICAgc25tcF9pbmNyZW1lbnRfc3RhdGlzdGljKFNUQVRfU05NUElOQVNOUEFSU0VFUlJTKTsKICAgICAgICBERUJVR0lOREVOVExFU1MoKTsKICAgICAgICByZXR1cm4gU05NUEVSUl9BU05fUEFSU0VfRVJSOwogICAgfQogICAgc3B0ciA9IGZpbmRfc2VjX21vZChtc2dfc2VjX21vZGVsKTsKICAgIGlmICghc3B0cikgewogICAgICAgIHNubXBfbG9nKExPR19XQVJOSU5HLCAidW5rbm93biBzZWN1cml0eSBtb2RlbDogJWxkXG4iLAogICAgICAgICAgICAgICAgIG1zZ19zZWNfbW9kZWwpOwogICAgICAgIHNubXBfaW5jcmVtZW50X3N0YXRpc3RpYyhTVEFUX1NOTVBVTktOT1dOU0VDVVJJVFlNT0RFTFMpOwogICAgICAgIERFQlVHSU5ERU5UTEVTUygpOwogICAgICAgIHJldHVybiBTTk1QRVJSX1VOS05PV05fU0VDX01PREVMOwogICAgfQogICAgcGR1LT5zZWN1cml0eU1vZGVsID0gbXNnX3NlY19tb2RlbDsKCiAgICBpZiAobXNnX2ZsYWdzICYgU05NUF9NU0dfRkxBR19QUklWX0JJVCAmJgogICAgICAgICEobXNnX2ZsYWdzICYgU05NUF9NU0dfRkxBR19BVVRIX0JJVCkpIHsKICAgICAgICBFUlJPUl9NU0coImludmFsaWQgbWVzc2FnZSwgaWxsZWdhbCBtc2dGbGFncyIpOwogICAgICAgIHNubXBfaW5jcmVtZW50X3N0YXRpc3RpYyhTVEFUX1NOTVBJTlZBTElETVNHUyk7CiAgICAgICAgREVCVUdJTkRFTlRMRVNTKCk7CiAgICAgICAgcmV0dXJuIFNOTVBFUlJfSU5WQUxJRF9NU0c7CiAgICB9CiAgICBwZHUtPnNlY3VyaXR5TGV2ZWwgPSAoKG1zZ19mbGFncyAmIFNOTVBfTVNHX0ZMQUdfQVVUSF9CSVQpCiAgICAgICAgICAgICAgICAgICAgICAgICAgPyAoKG1zZ19mbGFncyAmIFNOTVBfTVNHX0ZMQUdfUFJJVl9CSVQpCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPyBTTk1QX1NFQ19MRVZFTF9BVVRIUFJJVgogICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogU05NUF9TRUNfTEVWRUxfQVVUSE5PUFJJVikKICAgICAgICAgICAgICAgICAgICAgICAgICA6IFNOTVBfU0VDX0xFVkVMX05PQVVUSCk7CiAgICAvKgogICAgICogZW5kIG9mIG1zZ0dsb2JhbERhdGEgCiAgICAgKi8KCiAgICAvKgogICAgICogc2VjdXJ0aXR5UGFyYW1ldGVycyBPQ1RFVCBTVFJJTkcgYmVnaW5zIGFmdGVyIG1zZ0dsb2JhbERhdGEgCiAgICAgKi8KICAgIHNlY19wYXJhbXMgPSBkYXRhOwogICAgcGR1LT5jb250ZXh0RW5naW5lSUQgPSAodV9jaGFyICopIGNhbGxvYygxLCBTTk1QX01BWF9FTkdfU0laRSk7CiAgICBwZHUtPmNvbnRleHRFbmdpbmVJRExlbiA9IFNOTVBfTUFYX0VOR19TSVpFOwoKICAgIC8qCiAgICAgKiBOb3RlOiB0aGVyZSBpcyBubyBsZW5ndGggbGltaXQgb24gdGhlIG1zZ0F1dGhvcml0YXRpdmVFbmdpbmVJRCBmaWVsZCwKICAgICAqIGFsdGhvdWdoIHdlIHdvdWxkIEVYUEVDVCBpdCB0byBiZSBsaW1pdGVkIHRvIDMyICh0aGUgU25tcEVuZ2luZUlEIFRDCiAgICAgKiBsaW1pdCkuICBXZSdsbCB1c2UgZG91YmxlIHRoYXQgaGVyZSB0byBiZSBvbiB0aGUgc2FmZSBzaWRlLiAgCiAgICAgKi8KCiAgICBwZHUtPnNlY3VyaXR5RW5naW5lSUQgPSAodV9jaGFyICopIGNhbGxvYygxLCBTTk1QX01BWF9FTkdfU0laRSAqIDIpOwogICAgcGR1LT5zZWN1cml0eUVuZ2luZUlETGVuID0gU05NUF9NQVhfRU5HX1NJWkUgKiAyOwogICAgcGR1LT5zZWN1cml0eU5hbWUgPSAoY2hhciAqKSBjYWxsb2MoMSwgU05NUF9NQVhfU0VDX05BTUVfU0laRSk7CiAgICBwZHUtPnNlY3VyaXR5TmFtZUxlbiA9IFNOTVBfTUFYX1NFQ19OQU1FX1NJWkU7CgogICAgaWYgKChwZHUtPnNlY3VyaXR5TmFtZSA9PSBOVUxMKSB8fAogICAgICAgIChwZHUtPnNlY3VyaXR5RW5naW5lSUQgPT0gTlVMTCkgfHwKICAgICAgICAocGR1LT5jb250ZXh0RW5naW5lSUQgPT0gTlVMTCkpIHsKICAgICAgICByZXR1cm4gU05NUEVSUl9NQUxMT0M7CiAgICB9CgogICAgaWYgKHBkdV9idWZfbGVuIDwgbXNnX2xlbgogICAgICAgICYmIHBkdS0+c2VjdXJpdHlMZXZlbCA9PSBTTk1QX1NFQ19MRVZFTF9BVVRIUFJJVikgewogICAgICAgIC8qCiAgICAgICAgICogc3BhY2UgbmVlZGVkIGlzIGxhcmdlciB0aGFuIHdlIGhhdmUgaW4gdGhlIGRlZmF1bHQgYnVmZmVyIAogICAgICAgICAqLwogICAgICAgIG1hbGxvY2J1ZiA9ICh1X2NoYXIgKikgY2FsbG9jKDEsIG1zZ19sZW4pOwogICAgICAgIHBkdV9idWZfbGVuID0gbXNnX2xlbjsKICAgICAgICBjcCA9IG1hbGxvY2J1ZjsKICAgIH0gZWxzZSB7CiAgICAgICAgbWVtc2V0KHBkdV9idWYsIDAsIHBkdV9idWZfbGVuKTsKICAgICAgICBjcCA9IHBkdV9idWY7CiAgICB9CgogICAgREVCVUdEVU1QU0VDVElPTigicmVjdiIsICJTTSBtc2dTZWN1cml0eVBhcmFtZXRlcnMiKTsKICAgIGlmIChzcHRyLT5kZWNvZGUpIHsKICAgICAgICBzdHJ1Y3Qgc25tcF9zZWNtb2RfaW5jb21pbmdfcGFyYW1zIHBhcm1zOwogICAgICAgIHBhcm1zLm1zZ1Byb2NNb2RlbCA9IHBkdS0+bXNnUGFyc2VNb2RlbDsKICAgICAgICBwYXJtcy5tYXhNc2dTaXplID0gbXNnX21heF9zaXplOwogICAgICAgIHBhcm1zLnNlY1BhcmFtcyA9IHNlY19wYXJhbXM7CiAgICAgICAgcGFybXMuc2VjTW9kZWwgPSBtc2dfc2VjX21vZGVsOwogICAgICAgIHBhcm1zLnNlY0xldmVsID0gcGR1LT5zZWN1cml0eUxldmVsOwogICAgICAgIHBhcm1zLndob2xlTXNnID0gbXNnX2RhdGE7CiAgICAgICAgcGFybXMud2hvbGVNc2dMZW4gPSBtc2dfbGVuOwogICAgICAgIHBhcm1zLnNlY0VuZ2luZUlEID0gcGR1LT5zZWN1cml0eUVuZ2luZUlEOwogICAgICAgIHBhcm1zLnNlY0VuZ2luZUlETGVuID0gJnBkdS0+c2VjdXJpdHlFbmdpbmVJRExlbjsKICAgICAgICBwYXJtcy5zZWNOYW1lID0gcGR1LT5zZWN1cml0eU5hbWU7CiAgICAgICAgcGFybXMuc2VjTmFtZUxlbiA9ICZwZHUtPnNlY3VyaXR5TmFtZUxlbjsKICAgICAgICBwYXJtcy5zY29wZWRQZHUgPSAmY3A7CiAgICAgICAgcGFybXMuc2NvcGVkUGR1TGVuID0gJnBkdV9idWZfbGVuOwogICAgICAgIHBhcm1zLm1heFNpemVSZXNwb25zZSA9ICZtYXhfc2l6ZV9yZXNwb25zZTsKICAgICAgICBwYXJtcy5zZWNTdGF0ZVJlZiA9ICZwZHUtPnNlY3VyaXR5U3RhdGVSZWY7CiAgICAgICAgcGFybXMuc2VzcyA9IHNlc3M7CiAgICAgICAgcGFybXMucGR1ID0gcGR1OwogICAgICAgIHBhcm1zLm1zZ19mbGFncyA9IG1zZ19mbGFnczsKICAgICAgICByZXRfdmFsID0gKCpzcHRyLT5kZWNvZGUpICgmcGFybXMpOwogICAgfSBlbHNlIHsKICAgICAgICBTTk1QX0ZSRUUobWFsbG9jYnVmKTsKICAgICAgICBERUJVR0lOREVOVExFU1MoKTsKICAgICAgICBzbm1wX2xvZyhMT0dfV0FSTklORywgInNlY3VyaXR5IHNlcnZpY2UgJWxkIGNhbid0IGRlY29kZSBwYWNrZXRzXG4iLAogICAgICAgICAgICAgICAgIG1zZ19zZWNfbW9kZWwpOwogICAgICAgIHJldHVybiAoLTEpOwogICAgfQoKICAgIGlmIChyZXRfdmFsICE9IFNOTVBFUlJfU1VDQ0VTUykgewogICAgICAgIERFQlVHRFVNUFNFQ1RJT04oInJlY3YiLCAiU2NvcGVkUERVIik7CiAgICAgICAgLyoKICAgICAgICAgKiBQYXJzZSBhcyBtdWNoIGFzIHBvc3NpYmxlIC0tIHRob3VnaCBJIGRvbid0IHNlZSB0aGUgcG9pbnQ/IFtqYnBuXS4gIAogICAgICAgICAqLwogICAgICAgIGlmIChjcCkgewogICAgICAgICAgICBjcCA9IHNubXB2M19zY29wZWRQRFVfcGFyc2UocGR1LCBjcCwgJnBkdV9idWZfbGVuKTsKICAgICAgICB9CiAgICAgICAgaWYgKGNwKSB7CiAgICAgICAgICAgIERFQlVHUFJJTlRQRFVUWVBFKCJyZWN2IiwgKmNwKTsKICAgICAgICAgICAgc25tcF9wZHVfcGFyc2UocGR1LCBjcCwgJnBkdV9idWZfbGVuKTsKICAgICAgICAgICAgREVCVUdJTkRFTlRBREQoLTgpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIERFQlVHSU5ERU5UQUREKC00KTsKICAgICAgICB9CgogICAgICAgIGlmIChtYWxsb2NidWYpIHsKICAgICAgICAgICAgU05NUF9GUkVFKG1hbGxvY2J1Zik7CiAgICAgICAgfQogICAgICAgIHJldHVybiByZXRfdmFsOwogICAgfQoKICAgIC8qCiAgICAgKiBwYXJzZSBwbGFpbnRleHQgU2NvcGVkUERVIHNlcXVlbmNlIAogICAgICovCiAgICAqbGVuZ3RoID0gcGR1X2J1Zl9sZW47CiAgICBERUJVR0RVTVBTRUNUSU9OKCJyZWN2IiwgIlNjb3BlZFBEVSIpOwogICAgZGF0YSA9IHNubXB2M19zY29wZWRQRFVfcGFyc2UocGR1LCBjcCwgbGVuZ3RoKTsKICAgIGlmIChkYXRhID09IE5VTEwpIHsKICAgICAgICBzbm1wX2luY3JlbWVudF9zdGF0aXN0aWMoU1RBVF9TTk1QSU5BU05QQVJTRUVSUlMpOwogICAgICAgIERFQlVHSU5ERU5UQUREKC00KTsKICAgICAgICBpZiAobWFsbG9jYnVmKSB7CiAgICAgICAgICAgIFNOTVBfRlJFRShtYWxsb2NidWYpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gU05NUEVSUl9BU05fUEFSU0VfRVJSOwogICAgfQoKICAgIC8qCiAgICAgKiBwYXJzZSB0aGUgUERVLiAgCiAgICAgKi8KICAgIGlmIChhZnRlcl9oZWFkZXIgIT0gTlVMTCkgewogICAgICAgICphZnRlcl9oZWFkZXIgPSBkYXRhOwogICAgICAgIHRtcF9idWZfbGVuID0gKmxlbmd0aDsKICAgIH0KCiAgICBERUJVR1BSSU5UUERVVFlQRSgicmVjdiIsICpkYXRhKTsKICAgIHJldCA9IHNubXBfcGR1X3BhcnNlKHBkdSwgZGF0YSwgbGVuZ3RoKTsKICAgIERFQlVHSU5ERU5UQUREKC04KTsKCiAgICBpZiAoYWZ0ZXJfaGVhZGVyICE9IE5VTEwpIHsKICAgICAgICAqbGVuZ3RoID0gdG1wX2J1Zl9sZW47CiAgICB9CgogICAgaWYgKHJldCAhPSBTTk1QRVJSX1NVQ0NFU1MpIHsKICAgICAgICBFUlJPUl9NU0coImVycm9yIHBhcnNpbmcgUERVIik7CiAgICAgICAgc25tcF9pbmNyZW1lbnRfc3RhdGlzdGljKFNUQVRfU05NUElOQVNOUEFSU0VFUlJTKTsKICAgICAgICBpZiAobWFsbG9jYnVmKSB7CiAgICAgICAgICAgIFNOTVBfRlJFRShtYWxsb2NidWYpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gU05NUEVSUl9BU05fUEFSU0VfRVJSOwogICAgfQoKICAgIGlmIChtYWxsb2NidWYpIHsKICAgICAgICBTTk1QX0ZSRUUobWFsbG9jYnVmKTsKICAgIH0KICAgIHJldHVybiBTTk1QRVJSX1NVQ0NFU1M7Cn0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLyogZW5kIHNubXB2M19wYXJzZSgpICovCgojZGVmaW5lIEVSUk9SX1NUQVRfTEVOR1RIIDExCgppbnQKc25tcHYzX21ha2VfcmVwb3J0KG5ldHNubXBfcGR1ICpwZHUsIGludCBlcnJvcikKewoKICAgIGxvbmcgICAgICAgICAgICBsdG1wOwogICAgc3RhdGljIG9pZCAgICAgIHVua25vd25TZWN1cml0eUxldmVsW10gPQogICAgICAgIHsgMSwgMywgNiwgMSwgNiwgMywgMTUsIDEsIDEsIDEsIDAgfTsKICAgIHN0YXRpYyBvaWQgICAgICBub3RJblRpbWVXaW5kb3dbXSA9CiAgICAgICAgeyAxLCAzLCA2LCAxLCA2LCAzLCAxNSwgMSwgMSwgMiwgMCB9OwogICAgc3RhdGljIG9pZCAgICAgIHVua25vd25Vc2VyTmFtZVtdID0KICAgICAgICB7IDEsIDMsIDYsIDEsIDYsIDMsIDE1LCAxLCAxLCAzLCAwIH07CiAgICBzdGF0aWMgb2lkICAgICAgdW5rbm93bkVuZ2luZUlEW10gPQogICAgICAgIHsgMSwgMywgNiwgMSwgNiwgMywgMTUsIDEsIDEsIDQsIDAgfTsKICAgIHN0YXRpYyBvaWQgICAgICB3cm9uZ0RpZ2VzdFtdID0geyAxLCAzLCA2LCAxLCA2LCAzLCAxNSwgMSwgMSwgNSwgMCB9OwogICAgc3RhdGljIG9pZCAgICAgIGRlY3J5cHRpb25FcnJvcltdID0KICAgICAgICB7IDEsIDMsIDYsIDEsIDYsIDMsIDE1LCAxLCAxLCA2LCAwIH07CiAgICBvaWQgICAgICAgICAgICAqZXJyX3ZhcjsKICAgIGludCAgICAgICAgICAgICBlcnJfdmFyX2xlbjsKICAgIGludCAgICAgICAgICAgICBzdGF0X2luZDsKICAgIHN0cnVjdCBzbm1wX3NlY21vZF9kZWYgKnNwdHI7CgogICAgc3dpdGNoIChlcnJvcikgewogICAgY2FzZSBTTk1QRVJSX1VTTV9VTktOT1dORU5HSU5FSUQ6CiAgICAgICAgc3RhdF9pbmQgPSBTVEFUX1VTTVNUQVRTVU5LTk9XTkVOR0lORUlEUzsKICAgICAgICBlcnJfdmFyID0gdW5rbm93bkVuZ2luZUlEOwogICAgICAgIGVycl92YXJfbGVuID0gRVJST1JfU1RBVF9MRU5HVEg7CiAgICAgICAgYnJlYWs7CiAgICBjYXNlIFNOTVBFUlJfVVNNX1VOS05PV05TRUNVUklUWU5BTUU6CiAgICAgICAgc3RhdF9pbmQgPSBTVEFUX1VTTVNUQVRTVU5LTk9XTlVTRVJOQU1FUzsKICAgICAgICBlcnJfdmFyID0gdW5rbm93blVzZXJOYW1lOwogICAgICAgIGVycl92YXJfbGVuID0gRVJST1JfU1RBVF9MRU5HVEg7CiAgICAgICAgYnJlYWs7CiAgICBjYXNlIFNOTVBFUlJfVVNNX1VOU1VQUE9SVEVEU0VDVVJJVFlMRVZFTDoKICAgICAgICBzdGF0X2luZCA9IFNUQVRfVVNNU1RBVFNVTlNVUFBPUlRFRFNFQ0xFVkVMUzsKICAgICAgICBlcnJfdmFyID0gdW5rbm93blNlY3VyaXR5TGV2ZWw7CiAgICAgICAgZXJyX3Zhcl9sZW4gPSBFUlJPUl9TVEFUX0xFTkdUSDsKICAgICAgICBicmVhazsKICAgIGNhc2UgU05NUEVSUl9VU01fQVVUSEVOVElDQVRJT05GQUlMVVJFOgogICAgICAgIHN0YXRfaW5kID0gU1RBVF9VU01TVEFUU1dST05HRElHRVNUUzsKICAgICAgICBlcnJfdmFyID0gd3JvbmdEaWdlc3Q7CiAgICAgICAgZXJyX3Zhcl9sZW4gPSBFUlJPUl9TVEFUX0xFTkdUSDsKICAgICAgICBicmVhazsKICAgIGNhc2UgU05NUEVSUl9VU01fTk9USU5USU1FV0lORE9XOgogICAgICAgIHN0YXRfaW5kID0gU1RBVF9VU01TVEFUU05PVElOVElNRVdJTkRPV1M7CiAgICAgICAgZXJyX3ZhciA9IG5vdEluVGltZVdpbmRvdzsKICAgICAgICBlcnJfdmFyX2xlbiA9IEVSUk9SX1NUQVRfTEVOR1RIOwogICAgICAgIGJyZWFrOwogICAgY2FzZSBTTk1QRVJSX1VTTV9ERUNSWVBUSU9ORVJST1I6CiAgICAgICAgc3RhdF9pbmQgPSBTVEFUX1VTTVNUQVRTREVDUllQVElPTkVSUk9SUzsKICAgICAgICBlcnJfdmFyID0gZGVjcnlwdGlvbkVycm9yOwogICAgICAgIGVycl92YXJfbGVuID0gRVJST1JfU1RBVF9MRU5HVEg7CiAgICAgICAgYnJlYWs7CiAgICBkZWZhdWx0OgogICAgICAgIHJldHVybiBTTk1QRVJSX0dFTkVSUjsKICAgIH0KCiAgICBzbm1wX2ZyZWVfdmFyYmluZChwZHUtPnZhcmlhYmxlcyk7ICAvKiBmcmVlIHRoZSBjdXJyZW50IHZhcmJpbmQgKi8KCiAgICBwZHUtPnZhcmlhYmxlcyA9IE5VTEw7CiAgICBTTk1QX0ZSRUUocGR1LT5zZWN1cml0eUVuZ2luZUlEKTsKICAgIHBkdS0+c2VjdXJpdHlFbmdpbmVJRCA9CiAgICAgICAgc25tcHYzX2dlbmVyYXRlX2VuZ2luZUlEKCZwZHUtPnNlY3VyaXR5RW5naW5lSURMZW4pOwogICAgU05NUF9GUkVFKHBkdS0+Y29udGV4dEVuZ2luZUlEKTsKICAgIHBkdS0+Y29udGV4dEVuZ2luZUlEID0KICAgICAgICBzbm1wdjNfZ2VuZXJhdGVfZW5naW5lSUQoJnBkdS0+Y29udGV4dEVuZ2luZUlETGVuKTsKICAgIHBkdS0+Y29tbWFuZCA9IFNOTVBfTVNHX1JFUE9SVDsKICAgIHBkdS0+ZXJyc3RhdCA9IDA7CiAgICBwZHUtPmVycmluZGV4ID0gMDsKICAgIFNOTVBfRlJFRShwZHUtPmNvbnRleHROYW1lKTsKICAgIHBkdS0+Y29udGV4dE5hbWUgPSBzdHJkdXAoIiIpOwogICAgcGR1LT5jb250ZXh0TmFtZUxlbiA9IHN0cmxlbihwZHUtPmNvbnRleHROYW1lKTsKCiAgICAvKgogICAgICogcmVwb3J0cyBzaG91bGRuJ3QgY2FjaGUgcHJldmlvdXMgZGF0YS4gCiAgICAgKi8KICAgIC8qCiAgICAgKiBGSVggLSB5ZXMgdGhleSBzaG91bGQgYnV0IFVTTSBuZWVkcyB0byBmb2xsb3cgbmV3IEVvUCB0byBkZXRlcm1pbmUKICAgICAqIHdoaWNoIGNhY2hlZCB2YWx1ZXMgdG8gdXNlIAogICAgICovCiAgICBpZiAocGR1LT5zZWN1cml0eVN0YXRlUmVmKSB7CiAgICAgICAgc3B0ciA9IGZpbmRfc2VjX21vZChwZHUtPnNlY3VyaXR5TW9kZWwpOwogICAgICAgIGlmIChzcHRyKSB7CiAgICAgICAgICAgIGlmIChzcHRyLT5wZHVfZnJlZV9zdGF0ZV9yZWYpIHsKICAgICAgICAgICAgICAgICgqc3B0ci0+cGR1X2ZyZWVfc3RhdGVfcmVmKSAocGR1LT5zZWN1cml0eVN0YXRlUmVmKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHNubXBfbG9nKExPR19FUlIsCiAgICAgICAgICAgICAgICAgICAgICAgICAiU2VjdXJpdHkgTW9kZWwgJWQgY2FuJ3QgZnJlZSBzdGF0ZSByZWZlcmVuY2VzXG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgcGR1LT5zZWN1cml0eU1vZGVsKTsKICAgICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHNubXBfbG9nKExPR19FUlIsCiAgICAgICAgICAgICAgICAgICAgICJDYW4ndCBmaW5kIHNlY3VyaXR5IG1vZGVsIHRvIGZyZWUgcHRyOiAlZFxuIiwKICAgICAgICAgICAgICAgICAgICAgcGR1LT5zZWN1cml0eU1vZGVsKTsKICAgICAgICB9CiAgICAgICAgcGR1LT5zZWN1cml0eVN0YXRlUmVmID0gTlVMTDsKICAgIH0KCiAgICBpZiAoZXJyb3IgPT0gU05NUEVSUl9VU01fTk9USU5USU1FV0lORE9XKSB7CiAgICAgICAgcGR1LT5zZWN1cml0eUxldmVsID0gU05NUF9TRUNfTEVWRUxfQVVUSE5PUFJJVjsKICAgIH0gZWxzZSB7CiAgICAgICAgcGR1LT5zZWN1cml0eUxldmVsID0gU05NUF9TRUNfTEVWRUxfTk9BVVRIOwogICAgfQoKICAgIC8qCiAgICAgKiBmaW5kIHRoZSBhcHByb3ByaWF0ZSBlcnJvciBjb3VudGVyICAKICAgICAqLwogICAgbHRtcCA9IHNubXBfZ2V0X3N0YXRpc3RpYyhzdGF0X2luZCk7CgogICAgLyoKICAgICAqIHJldHVybiB0aGUgYXBwcm9wcmlhdGUgZXJyb3IgY291bnRlciAgCiAgICAgKi8KICAgIHNubXBfcGR1X2FkZF92YXJpYWJsZShwZHUsIGVycl92YXIsIGVycl92YXJfbGVuLAogICAgICAgICAgICAgICAgICAgICAgICAgIEFTTl9DT1VOVEVSLCAmIGx0bXAsIHNpemVvZihsdG1wKSk7CgogICAgcmV0dXJuIFNOTVBFUlJfU1VDQ0VTUzsKfSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBlbmQgc25tcHYzX21ha2VfcmVwb3J0KCkgKi8KCgppbnQKc25tcHYzX2dldF9yZXBvcnRfdHlwZShuZXRzbm1wX3BkdSAqcGR1KQp7CiAgICBzdGF0aWMgb2lkICAgICAgc25tcE1QRFN0YXRzW10gPSB7IDEsIDMsIDYsIDEsIDYsIDMsIDExLCAyLCAxIH07CiAgICBzdGF0aWMgb2lkICAgICAgdGFyZ2V0U3RhdHNbXSAgPSB7IDEsIDMsIDYsIDEsIDYsIDMsIDEyLCAxICAgIH07CiAgICBzdGF0aWMgb2lkICAgICAgdXNtU3RhdHNbXSAgICAgPSB7IDEsIDMsIDYsIDEsIDYsIDMsIDE1LCAxLCAxIH07CiAgICBuZXRzbm1wX3ZhcmlhYmxlX2xpc3QgKnZwOwogICAgaW50ICAgICAgICAgICAgIHJwdF90eXBlID0gU05NUEVSUl9VTktOT1dOX1JFUE9SVDsKCiAgICBpZiAocGR1ID09IE5VTEwgfHwgcGR1LT52YXJpYWJsZXMgPT0gTlVMTCkKICAgICAgICByZXR1cm4gcnB0X3R5cGU7CiAgICB2cCA9IHBkdS0+dmFyaWFibGVzOwogICAgLyogTVBEIG9yIFVTTSBiYXNlZCByZXBvcnQgc3RhdGlzdGljcyBvYmplY3RzIGhhdmUgdGhlIHNhbWUgbGVuZ3RoIHByZWZpeAogICAgICogICBzbyB0aGUgYWN0dWFsIHN0YXRpc3RpY3MgT0lEIHdpbGwgaGF2ZSB0aGlzIGxlbmd0aCwKICAgICAqICAgcGx1cyBvbmUgc3ViaWRlbnRpZmllciBmb3IgdGhlIHNjYWxhciBNSUIgb2JqZWN0IGl0c2VsZiwKICAgICAqICAgYW5kIG9uZSBmb3IgdGhlIGluc3RhbmNlIHN1YmlkZW50aWZpZXIKICAgICAqLwogICAgaWYgKHZwLT5uYW1lX2xlbmd0aCA9PSBSRVBPUlRfU1RBVFNfTEVOICsgMikgewogICAgICAgIGlmIChtZW1jbXAoc25tcE1QRFN0YXRzLCB2cC0+bmFtZSwgUkVQT1JUX1NUQVRTX0xFTiAqIHNpemVvZihvaWQpKSA9PSAwKSB7CiAgICAgICAgICAgIHN3aXRjaCAodnAtPm5hbWVbUkVQT1JUX1NUQVRTX0xFTl0pIHsKICAgICAgICAgICAgY2FzZSBSRVBPUlRfc25tcFVua25vd25TZWN1cml0eU1vZGVsc19OVU06CiAgICAgICAgICAgICAgICBycHRfdHlwZSA9IFNOTVBFUlJfVU5LTk9XTl9TRUNfTU9ERUw7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSBSRVBPUlRfc25tcEludmFsaWRNc2dzX05VTToKICAgICAgICAgICAgICAgIHJwdF90eXBlID0gU05NUEVSUl9JTlZBTElEX01TRzsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIFJFUE9SVF9zbm1wVW5rbm93blBEVUhhbmRsZXJzX05VTToKICAgICAgICAgICAgICAgIHJwdF90eXBlID0gU05NUEVSUl9CQURfVkVSU0lPTjsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIGlmIChtZW1jbXAodXNtU3RhdHMsIHZwLT5uYW1lLCBSRVBPUlRfU1RBVFNfTEVOICogc2l6ZW9mKG9pZCkpID09IDApIHsKICAgICAgICAgICAgc3dpdGNoICh2cC0+bmFtZVtSRVBPUlRfU1RBVFNfTEVOXSkgewogICAgICAgICAgICBjYXNlIFJFUE9SVF91c21TdGF0c1Vuc3VwcG9ydGVkU2VjTGV2ZWxzX05VTToKICAgICAgICAgICAgICAgIHJwdF90eXBlID0gU05NUEVSUl9VTlNVUFBPUlRFRF9TRUNfTEVWRUw7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSBSRVBPUlRfdXNtU3RhdHNOb3RJblRpbWVXaW5kb3dzX05VTToKICAgICAgICAgICAgICAgIHJwdF90eXBlID0gU05NUEVSUl9OT1RfSU5fVElNRV9XSU5ET1c7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgY2FzZSBSRVBPUlRfdXNtU3RhdHNVbmtub3duVXNlck5hbWVzX05VTToKICAgICAgICAgICAgICAgIHJwdF90eXBlID0gU05NUEVSUl9VTktOT1dOX1VTRVJfTkFNRTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIFJFUE9SVF91c21TdGF0c1Vua25vd25FbmdpbmVJRHNfTlVNOgogICAgICAgICAgICAgICAgcnB0X3R5cGUgPSBTTk1QRVJSX1VOS05PV05fRU5HX0lEOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgUkVQT1JUX3VzbVN0YXRzV3JvbmdEaWdlc3RzX05VTToKICAgICAgICAgICAgICAgIHJwdF90eXBlID0gU05NUEVSUl9BVVRIRU5USUNBVElPTl9GQUlMVVJFOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIGNhc2UgUkVQT1JUX3VzbVN0YXRzRGVjcnlwdGlvbkVycm9yc19OVU06CiAgICAgICAgICAgICAgICBycHRfdHlwZSA9IFNOTVBFUlJfREVDUllQVElPTl9FUlI7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KICAgIC8qIENvbnRleHQtYmFzZWQgcmVwb3J0IHN0YXRpc3RpY3MgZnJvbSB0aGUgVGFyZ2V0IE1JQiBhcmUgc2ltaWxhcgogICAgICogICBidXQgdGhlIE9JRCBwcmVmaXggaGFzIGEgZGlmZmVyZW50IGxlbmd0aAogICAgICovCiAgICBpZiAodnAtPm5hbWVfbGVuZ3RoID09IFJFUE9SVF9TVEFUU19MRU4yICsgMikgewogICAgICAgIGlmIChtZW1jbXAodGFyZ2V0U3RhdHMsIHZwLT5uYW1lLCBSRVBPUlRfU1RBVFNfTEVOMiAqIHNpemVvZihvaWQpKSA9PSAwKSB7CiAgICAgICAgICAgIHN3aXRjaCAodnAtPm5hbWVbUkVQT1JUX1NUQVRTX0xFTjJdKSB7CiAgICAgICAgICAgIGNhc2UgUkVQT1JUX3NubXBVbmF2YWlsYWJsZUNvbnRleHRzX05VTToKICAgICAgICAgICAgICAgIHJwdF90eXBlID0gU05NUEVSUl9CQURfQ09OVEVYVDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBjYXNlIFJFUE9SVF9zbm1wVW5rbm93bkNvbnRleHRzX05VTToKICAgICAgICAgICAgICAgIHJwdF90eXBlID0gU05NUEVSUl9CQURfQ09OVEVYVDsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQogICAgREVCVUdNU0dUTCgoInJlcG9ydCIsICJSZXBvcnQgdHlwZTogJWRcbiIsIHJwdF90eXBlKSk7CiAgICByZXR1cm4gcnB0X3R5cGU7Cn0KCi8qCiAqIFBhcnNlcyB0aGUgcGFja2V0IHJlY2VpdmVkIG9uIHRoZSBpbnB1dCBzZXNzaW9uLCBhbmQgcGxhY2VzIHRoZSBkYXRhIGludG8KICogdGhlIGlucHV0IHBkdS4gIGxlbmd0aCBpcyB0aGUgbGVuZ3RoIG9mIHRoZSBpbnB1dCBwYWNrZXQuCiAqIElmIGFueSBlcnJvcnMgYXJlIGVuY291bnRlcmVkLCAtMSBvciBVU00gZXJyb3IgaXMgcmV0dXJuZWQuCiAqIE90aGVyd2lzZSwgYSAwIGlzIHJldHVybmVkLgogKi8Kc3RhdGljIGludApfc25tcF9wYXJzZSh2b2lkICpzZXNzcCwKICAgICAgICAgICAgbmV0c25tcF9zZXNzaW9uICogc2Vzc2lvbiwKICAgICAgICAgICAgbmV0c25tcF9wZHUgKnBkdSwgdV9jaGFyICogZGF0YSwgc2l6ZV90IGxlbmd0aCkKewojaWYgIWRlZmluZWQoTkVUU05NUF9ESVNBQkxFX1NOTVBWMSkgfHwgIWRlZmluZWQoTkVUU05NUF9ESVNBQkxFX1NOTVBWMkMpCiAgICB1X2NoYXIgICAgICAgICAgY29tbXVuaXR5W0NPTU1VTklUWV9NQVhfTEVOXTsKICAgIHNpemVfdCAgICAgICAgICBjb21tdW5pdHlfbGVuZ3RoID0gQ09NTVVOSVRZX01BWF9MRU47CiNlbmRpZgogICAgaW50ICAgICAgICAgICAgIHJlc3VsdCA9IC0xOwoKICAgIHN0YXRpYyBvaWQgICAgICBzbm1wRW5naW5lSURvaWRbXSAgID0geyAxLDMsNiwxLDYsMywxMCwyLDEsMSwwfTsKICAgIHN0YXRpYyBzaXplX3QgICBzbm1wRW5naW5lSURvaWRfbGVuID0gMTE7CgogICAgc3RhdGljIGNoYXIgICAgIG91ckVuZ2luZUlEW1NOTVBfU0VDX1BBUkFNX0JVRl9TSVpFXTsKICAgIHN0YXRpYyBzaXplX3QgICBvdXJFbmdpbmVJRF9sZW4gPSBzaXplb2Yob3VyRW5naW5lSUQpOwoKICAgIG5ldHNubXBfcGR1ICAgICpwZHUyID0gTlVMTDsKCiAgICBzZXNzaW9uLT5zX3NubXBfZXJybm8gPSAwOwogICAgc2Vzc2lvbi0+c19lcnJubyA9IDA7CgogICAgLyoKICAgICAqIEVuc3VyZSBhbGwgaW5jb21pbmcgUERVcyBoYXZlIGEgdW5pcXVlIG1lYW5zIG9mIGlkZW50aWZpY2F0aW9uIAogICAgICogKFRoaXMgaXMgbm90IHJlc3RyaWN0ZWQgdG8gQWdlbnRYIGhhbmRsaW5nLAogICAgICogdGhvdWdoIHRoYXQgaXMgd2hlcmUgdGhlIG5lZWQgYmVjb21lcyB2aXNpYmxlKSAgIAogICAgICovCiAgICBwZHUtPnRyYW5zaWQgPSBzbm1wX2dldF9uZXh0X3RyYW5zaWQoKTsKCiAgICBpZiAoc2Vzc2lvbi0+dmVyc2lvbiAhPSBTTk1QX0RFRkFVTFRfVkVSU0lPTikgewogICAgICAgIHBkdS0+dmVyc2lvbiA9IHNlc3Npb24tPnZlcnNpb247CiAgICB9IGVsc2UgewogICAgICAgIHBkdS0+dmVyc2lvbiA9IHNubXBfcGFyc2VfdmVyc2lvbihkYXRhLCBsZW5ndGgpOwogICAgfQoKICAgIHN3aXRjaCAocGR1LT52ZXJzaW9uKSB7CiNpZm5kZWYgTkVUU05NUF9ESVNBQkxFX1NOTVBWMQogICAgY2FzZSBTTk1QX1ZFUlNJT05fMToKI2VuZGlmCiNpZm5kZWYgTkVUU05NUF9ESVNBQkxFX1NOTVBWMkMKICAgIGNhc2UgU05NUF9WRVJTSU9OXzJjOgojZW5kaWYKI2lmICFkZWZpbmVkKE5FVFNOTVBfRElTQUJMRV9TTk1QVjEpIHx8ICFkZWZpbmVkKE5FVFNOTVBfRElTQUJMRV9TTk1QVjJDKQogICAgICAgIERFQlVHTVNHVEwoKCJzbm1wX2FwaSIsICJQYXJzaW5nIFNOTVB2JWxkIG1lc3NhZ2UuLi5cbiIsCiAgICAgICAgICAgICAgICAgICAgKDEgKyBwZHUtPnZlcnNpb24pKSk7CgogICAgICAgIC8qCiAgICAgICAgICogYXV0aGVudGljYXRlcyBtZXNzYWdlIGFuZCByZXR1cm5zIGxlbmd0aCBpZiB2YWxpZCAKICAgICAgICAgKi8KI2lmbmRlZiBORVRTTk1QX0RJU0FCTEVfU05NUFYxCiAgICAgICAgaWYgKHBkdS0+dmVyc2lvbiA9PSBTTk1QX1ZFUlNJT05fMSkgewogICAgICAgICAgICBERUJVR0RVTVBTRUNUSU9OKCJyZWN2IiwgIlNOTVB2MSBtZXNzYWdlXG4iKTsKICAgICAgICB9IGVsc2UgewojZW5kaWYKICAgICAgICAgICAgREVCVUdEVU1QU0VDVElPTigicmVjdiIsICJTTk1QdjJjIG1lc3NhZ2VcbiIpOwojaWZuZGVmIE5FVFNOTVBfRElTQUJMRV9TTk1QVjEKICAgICAgICB9CiNlbmRpZgogICAgICAgIGRhdGEgPSBzbm1wX2NvbXN0cl9wYXJzZShkYXRhLCAmbGVuZ3RoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb21tdW5pdHksICZjb21tdW5pdHlfbGVuZ3RoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmcGR1LT52ZXJzaW9uKTsKICAgICAgICBpZiAoZGF0YSA9PSBOVUxMKQogICAgICAgICAgICByZXR1cm4gLTE7CgogICAgICAgIGlmIChwZHUtPnZlcnNpb24gIT0gc2Vzc2lvbi0+dmVyc2lvbiAmJgogICAgICAgICAgICBzZXNzaW9uLT52ZXJzaW9uICE9IFNOTVBfREVGQVVMVF9WRVJTSU9OKSB7CiAgICAgICAgICAgIHNlc3Npb24tPnNfc25tcF9lcnJubyA9IFNOTVBFUlJfQkFEX1ZFUlNJT047CiAgICAgICAgICAgIHJldHVybiAtMTsKICAgICAgICB9CgogICAgICAgIC8qCiAgICAgICAgICogbWF5YmUgZ2V0IHRoZSBjb21tdW5pdHkgc3RyaW5nLiAKICAgICAgICAgKi8KICAgICAgICBwZHUtPnNlY3VyaXR5TGV2ZWwgPSBTTk1QX1NFQ19MRVZFTF9OT0FVVEg7CiAgICAgICAgcGR1LT5zZWN1cml0eU1vZGVsID0gCiNpZm5kZWYgTkVUU05NUF9ESVNBQkxFX1NOTVBWMQogICAgICAgICAgICAocGR1LT52ZXJzaW9uID09IFNOTVBfVkVSU0lPTl8xKSA/IFNOTVBfU0VDX01PREVMX1NOTVB2MSA6IAojZW5kaWYKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTTk1QX1NFQ19NT0RFTF9TTk1QdjJjOwogICAgICAgIFNOTVBfRlJFRShwZHUtPmNvbW11bml0eSk7CiAgICAgICAgcGR1LT5jb21tdW5pdHlfbGVuID0gMDsKICAgICAgICBwZHUtPmNvbW11bml0eSA9ICh1X2NoYXIgKikgMDsKICAgICAgICBpZiAoY29tbXVuaXR5X2xlbmd0aCkgewogICAgICAgICAgICBwZHUtPmNvbW11bml0eV9sZW4gPSBjb21tdW5pdHlfbGVuZ3RoOwogICAgICAgICAgICBwZHUtPmNvbW11bml0eSA9ICh1X2NoYXIgKikgbWFsbG9jKGNvbW11bml0eV9sZW5ndGgpOwogICAgICAgICAgICBpZiAocGR1LT5jb21tdW5pdHkgPT0gTlVMTCkgewogICAgICAgICAgICAgICAgc2Vzc2lvbi0+c19zbm1wX2Vycm5vID0gU05NUEVSUl9NQUxMT0M7CiAgICAgICAgICAgICAgICByZXR1cm4gLTE7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgbWVtbW92ZShwZHUtPmNvbW11bml0eSwgY29tbXVuaXR5LCBjb21tdW5pdHlfbGVuZ3RoKTsKICAgICAgICB9CiAgICAgICAgaWYgKHNlc3Npb24tPmF1dGhlbnRpY2F0b3IpIHsKICAgICAgICAgICAgZGF0YSA9IHNlc3Npb24tPmF1dGhlbnRpY2F0b3IoZGF0YSwgJmxlbmd0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29tbXVuaXR5LCBjb21tdW5pdHlfbGVuZ3RoKTsKICAgICAgICAgICAgaWYgKGRhdGEgPT0gTlVMTCkgewogICAgICAgICAgICAgICAgc2Vzc2lvbi0+c19zbm1wX2Vycm5vID0gU05NUEVSUl9BVVRIRU5USUNBVElPTl9GQUlMVVJFOwogICAgICAgICAgICAgICAgcmV0dXJuIC0xOwogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBERUJVR0RVTVBTRUNUSU9OKCJyZWN2IiwgIlBEVSIpOwogICAgICAgIHJlc3VsdCA9IHNubXBfcGR1X3BhcnNlKHBkdSwgZGF0YSwgJmxlbmd0aCk7CiAgICAgICAgaWYgKHJlc3VsdCA8IDApIHsKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogVGhpcyBpbmRpY2F0ZXMgYSBwYXJzZSBlcnJvci4gIAogICAgICAgICAgICAgKi8KICAgICAgICAgICAgc25tcF9pbmNyZW1lbnRfc3RhdGlzdGljKFNUQVRfU05NUElOQVNOUEFSU0VFUlJTKTsKICAgICAgICB9CiAgICAgICAgREVCVUdJTkRFTlRBREQoLTYpOwogICAgICAgIGJyZWFrOwojZW5kaWYgLyogc3VwcG9ydCBmb3IgY29tbXVuaXR5IGJhc2VkIFNOTVAgKi8KCiAgICBjYXNlIFNOTVBfVkVSU0lPTl8zOgogICAgICAgIHJlc3VsdCA9IHNubXB2M19wYXJzZShwZHUsIGRhdGEsICZsZW5ndGgsIE5VTEwsIHNlc3Npb24pOwogICAgICAgIERFQlVHTVNHVEwoKCJzbm1wX3BhcnNlIiwKICAgICAgICAgICAgICAgICAgICAiUGFyc2VkIFNOTVB2MyBtZXNzYWdlIChzZWNOYW1lOiVzLCBzZWNMZXZlbDolcyk6ICVzXG4iLAogICAgICAgICAgICAgICAgICAgIHBkdS0+c2VjdXJpdHlOYW1lLCBzZWNMZXZlbE5hbWVbcGR1LT5zZWN1cml0eUxldmVsXSwKICAgICAgICAgICAgICAgICAgICBzbm1wX2FwaV9lcnJzdHJpbmcocmVzdWx0KSkpOwoKICAgICAgICBpZiAocmVzdWx0KSB7CiAgICAgICAgICAgIHN0cnVjdCBzbm1wX3NlY21vZF9kZWYgKnNlY21vZCA9CiAgICAgICAgICAgICAgICBmaW5kX3NlY19tb2QocGR1LT5zZWN1cml0eU1vZGVsKTsKICAgICAgICAgICAgaWYgKCFzZXNzcCkgewogICAgICAgICAgICAgICAgc2Vzc2lvbi0+c19zbm1wX2Vycm5vID0gcmVzdWx0OwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAqIENhbGwgdGhlIHNlY3VyaXR5IG1vZGVsIHRvIHNwZWNpYWwgaGFuZGxlIGFueSBlcnJvcnMKICAgICAgICAgICAgICAgICAqLwoKICAgICAgICAgICAgICAgIGlmIChzZWNtb2QgJiYgc2VjbW9kLT5oYW5kbGVfcmVwb3J0KSB7CiAgICAgICAgICAgICAgICAgICAgc3RydWN0IHNlc3Npb25fbGlzdCAqc2xwID0gKHN0cnVjdCBzZXNzaW9uX2xpc3QgKikgc2Vzc3A7CiAgICAgICAgICAgICAgICAgICAgKCpzZWNtb2QtPmhhbmRsZV9yZXBvcnQpKHNlc3NwLCBzbHAtPnRyYW5zcG9ydCwgc2Vzc2lvbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVzdWx0LCBwZHUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChwZHUtPnNlY3VyaXR5U3RhdGVSZWYgIT0gTlVMTCkgewogICAgICAgICAgICAgICAgaWYgKHNlY21vZCAmJiBzZWNtb2QtPnBkdV9mcmVlX3N0YXRlX3JlZikgewogICAgICAgICAgICAgICAgICAgIHNlY21vZC0+cGR1X2ZyZWVfc3RhdGVfcmVmKHBkdS0+c2VjdXJpdHlTdGF0ZVJlZik7CiAgICAgICAgICAgICAgICAgICAgcGR1LT5zZWN1cml0eVN0YXRlUmVmID0gTlVMTDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgLyogSW1wbGVtZW50IFJGQzUzNDMgaGVyZSBmb3IgdHdvIHJlYXNvbnM6CiAgICAgICAgICAgMSkgRnJvbSBhIHNlY3VyaXR5IHBlcnNwZWN0aXZlIGl0IGhhbmRsZXMgdGhpcyBvdGhlcndpc2UKICAgICAgICAgICAgICBhbHdheXMgYXBwcm92ZWQgcmVxdWVzdCBlYXJsaWVyLiAgSXQgYnlwYXNzZXMgdGhlIG5lZWQKICAgICAgICAgICAgICBmb3IgYXV0aG9yaXphdGlvbiB0byB0aGUgc25tcEVuZ2luZUlEIHNjYWxhciwgd2hpY2ggaXMKICAgICAgICAgICAgICB3aGF0IGlzIHdoYXQgUkZDMzQxNSBhcHBlbmRpeCBBIHNwZWNpZXMgYXMgb2suICBOb3RlCiAgICAgICAgICAgICAgdGhhdCB3ZSBoYXZlbid0IGJ5cGFzc2VkIGF1dGhlbnRpY2F0aW9uIHNpbmNlIGlmIHRoZXJlCiAgICAgICAgICAgICAgd2FzIGFuIGF1dGhlbnRpY2F0aW9uIGVyb3IgaXQgd291bGQgaGF2ZSBiZWVuIGhhbmRsZWQKICAgICAgICAgICAgICBhYm92ZSBpbiB0aGUgaWYocmVzdWx0KSBwYXJ0IGF0IHRoZSBsYXN0ZXQuCiAgICAgICAgICAgMikgRnJvbSBhbiBhcHBsaWNhdGlvbiBwb2ludCBvZiB2aWV3IGlmIHdlIGxldCB0aGlzIHJlcXVlc3QKICAgICAgICAgICAgICBnZXQgYWxsIHRoZSB3YXkgdG8gdGhlIGFwcGxpY2F0aW9uLCBpdCdkIHJlcXVpcmUgdGhhdAogICAgICAgICAgICAgIGFsbCBhcHBsaWNhdGlvbiB0eXBlcyBzdXBwb3J0aW5nIGRpc2NvdmVyeSBhbHNvIGZpcmUgdXAKICAgICAgICAgICAgICBhIG1pbmltYWwgYWdlbnQgaW4gb3JkZXIgdG8gaGFuZGxlIGp1c3QgdGhpcyByZXF1ZXN0CiAgICAgICAgICAgICAgd2hpY2ggc2VlbXMgbGlrZSBvdmVya2lsbC4gIFRob3VnaCB0aGVyZSBpcyBubyBvdGhlcgogICAgICAgICAgICAgIGFwcGxpY2F0aW9uIHR5cGVzIHRoYXQgY3VycmVudGx5IG5lZWQgZGlzY292ZXJ5IChOUnMKICAgICAgICAgICAgICBhY2NlcHQgbm90aWZpY2F0aW9ucyBmcm9tIGNvbnRleHRFbmdpbmVJRHMgdGhhdCBkZXJpdmUKICAgICAgICAgICAgICBmcm9tIHRoZSBOTyBub3QgdGhlIE5SKS4gIEFsc28gYSBsYW1lIGV4Y3VzZSBmb3IgZG9pbmcKICAgICAgICAgICAgICBpdCBoZXJlLgogICAgICAgICAgIDMpIExlc3MgaW1wb3J0YW50IHRlY2huaWNhbGx5LCBidXQgdGhlIG5ldC1zbm1wIGFnZW50CiAgICAgICAgICAgICAgZG9lc24ndCBjdXJyZW50bHkgaGFuZGxlIHJlZ2lzdHJhdGlvbnMgb2YgZGlmZmVyZW50CiAgICAgICAgICAgICAgZW5naW5lSURzIGVpdGhlciBhbmQgaXQgd291bGQgaGF2ZSBiZWVuIGEgbG90IG1vcmUgd29yawogICAgICAgICAgICAgIHRvIGltcGxlbWVudCB0aGVyZSBzaW5jZSB3ZSdkIG5lZWQgdG8gc3VwcG9ydCB0aGF0CiAgICAgICAgICAgICAgZmlyc3QuIDotLyBTdXBwb3J0aW5nIG11bHRpcGxlIGNvbnRleHQgZW5naW5lSURzIHNob3VsZAogICAgICAgICAgICAgIGJlIGRvbmUgYW55d2F5LCBzbyBpdCdzIG5vdCBhIHZhbGlkIGV4Y3VzZSBoZXJlLgogICAgICAgICAgIDQpIFRoZXJlIGlzIGEgbG90IGxlc3MgdG8gZG8gaWYgd2UgdHJ1bXAgdGhlIGFnZW50IGF0IHRoaXMKICAgICAgICAgICAgICBwb2ludDsgSUUsIHRoZSBhZ2VudCBkb2VzIGEgbG90IG1vcmUgdW5uZWNlc3NhcnkKICAgICAgICAgICAgICBwcm9jZXNzaW5nIHdoZW4gdGhlIG9ubHkgdGhpbmcgdGhhdCBzaG91bGQgZXZlciBiZSBpbgogICAgICAgICAgICAgIHRoaXMgY29udGV4dCBieSBkZWZpbml0aW9uIGlzIHRoZSBzaW5nbGUgc2NhbGFyLgogICAgICAgICovCgogICAgICAgIC8qIHNwZWNpYWwgUkZDNTM0MyBlbmdpbmVJRCBkaXNjb3ZlcnkgZW5naW5lSUQgY2hlY2sgKi8KICAgICAgICBpZiAoIW5ldHNubXBfZHNfZ2V0X2Jvb2xlYW4oTkVUU05NUF9EU19MSUJSQVJZX0lELAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBORVRTTk1QX0RTX0xJQl9OT19ESVNDT1ZFUlkpICYmCiAgICAgICAgICAgIFNOTVBfTVNHX1JFU1BPTlNFICAgICAgICE9IHBkdS0+Y29tbWFuZCAmJgogICAgICAgICAgICBOVUxMICAgICAgICAgICAgICAgICAgICAhPSBwZHUtPmNvbnRleHRFbmdpbmVJRCAmJgogICAgICAgICAgICBwZHUtPmNvbnRleHRFbmdpbmVJRExlbiA9PSA1ICYmCiAgICAgICAgICAgIHBkdS0+Y29udGV4dEVuZ2luZUlEWzBdID09IDB4ODAgJiYKICAgICAgICAgICAgcGR1LT5jb250ZXh0RW5naW5lSURbMV0gPT0gMHgwMCAmJgogICAgICAgICAgICBwZHUtPmNvbnRleHRFbmdpbmVJRFsyXSA9PSAweDAwICYmCiAgICAgICAgICAgIHBkdS0+Y29udGV4dEVuZ2luZUlEWzNdID09IDB4MDAgJiYKICAgICAgICAgICAgcGR1LT5jb250ZXh0RW5naW5lSURbNF0gPT0gMHgwNikgewoKICAgICAgICAgICAgLyogZGVmaW5lIGEgcmVzdWx0IHNvIGl0IGRvZXNuJ3QgZ2V0IHBhc3QgdXMgYXQgdGhpcyBwb2ludAogICAgICAgICAgICAgICBhbmQgZ2V0cyBkcm9wcGVkIGJ5IGZ1dHVyZSBwYXJ0cyBvZiB0aGUgc3RhY2sgKi8KICAgICAgICAgICAgcmVzdWx0ID0gU05NUEVSUl9KVVNUX0FfQ09OVEVYVF9QUk9CRTsKCiAgICAgICAgICAgIERFQlVHTVNHVEwoKCJzbm1wdjNfY29udGV4dGlkIiwgInN0YXJ0aW5nIGNvbnRleHQgSUQgZGlzY292ZXJ5XG4iKSk7CiAgICAgICAgICAgIC8qIGVuc3VyZSBleGFjdGx5IG9uZSB2YXJpYWJsZSAqLwogICAgICAgICAgICBpZiAoTlVMTCAhPSBwZHUtPnZhcmlhYmxlcyAmJgogICAgICAgICAgICAgICAgTlVMTCA9PSBwZHUtPnZhcmlhYmxlcy0+bmV4dF92YXJpYWJsZSAmJgoKICAgICAgICAgICAgICAgIC8qIGlmIGl0J3MgYSBHRVQsIG1hdGNoIGl0IGV4YWN0bHkgKi8KICAgICAgICAgICAgICAgICgoU05NUF9NU0dfR0VUID09IHBkdS0+Y29tbWFuZCAmJgogICAgICAgICAgICAgICAgICBzbm1wX29pZF9jb21wYXJlKHNubXBFbmdpbmVJRG9pZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzbm1wRW5naW5lSURvaWRfbGVuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBkdS0+dmFyaWFibGVzLT5uYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBkdS0+dmFyaWFibGVzLT5uYW1lX2xlbmd0aCkgPT0gMCkKICAgICAgICAgICAgICAgICAvKiBpZiBpdCdzIGEgR0VUTkVYVCBlbnN1cmUgaXQncyBsZXNzIHRoYW4gdGhlIGVuZ2luZUlEIG9pZCAqLwogICAgICAgICAgICAgICAgIHx8CiAgICAgICAgICAgICAgICAgKFNOTVBfTVNHX0dFVE5FWFQgPT0gcGR1LT5jb21tYW5kICYmCiAgICAgICAgICAgICAgICAgIHNubXBfb2lkX2NvbXBhcmUoc25tcEVuZ2luZUlEb2lkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNubXBFbmdpbmVJRG9pZF9sZW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGR1LT52YXJpYWJsZXMtPm5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGR1LT52YXJpYWJsZXMtPm5hbWVfbGVuZ3RoKSA+IDApCiAgICAgICAgICAgICAgICAgICAgKSkgewoKICAgICAgICAgICAgICAgIERFQlVHTVNHVEwoKCJzbm1wdjNfY29udGV4dGlkIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICIgIE9uZSBjb3JyZWN0IHZhcmlhYmxlIGZvdW5kXG4iKSk7CgogICAgICAgICAgICAgICAgLyogTm90ZTogd2UncmUgZXhwbGljdGx5IG5vdCBoYW5kbGluZyBhIEdFVEJVTEsuICBEZWFsLiAqLwoKICAgICAgICAgICAgICAgIC8qIHNldCB1cCB0aGUgcmVzcG9uc2UgKi8KICAgICAgICAgICAgICAgIHBkdTIgPSBzbm1wX2Nsb25lX3BkdShwZHUpOwoKICAgICAgICAgICAgICAgIC8qIGZyZWUgdGhlIGN1cnJlbnQgdmFyYmluZCAqLwogICAgICAgICAgICAgICAgc25tcF9mcmVlX3ZhcmJpbmQocGR1Mi0+dmFyaWFibGVzKTsKCiAgICAgICAgICAgICAgICAvKiBzZXQgdGhlIHZhcmlhYmxlcyAqLwogICAgICAgICAgICAgICAgcGR1Mi0+dmFyaWFibGVzID0gTlVMTDsKICAgICAgICAgICAgICAgIHBkdTItPmNvbW1hbmQgPSBTTk1QX01TR19SRVNQT05TRTsKICAgICAgICAgICAgICAgIHBkdTItPmVycnN0YXQgPSAwOwogICAgICAgICAgICAgICAgcGR1Mi0+ZXJyaW5kZXggPSAwOwoKICAgICAgICAgICAgICAgIG91ckVuZ2luZUlEX2xlbiA9CiAgICAgICAgICAgICAgICAgICAgc25tcHYzX2dldF9lbmdpbmVJRCgodV9jaGFyKilvdXJFbmdpbmVJRCwgb3VyRW5naW5lSURfbGVuKTsKICAgICAgICAgICAgICAgIGlmICgwICE9IG91ckVuZ2luZUlEX2xlbikgewoKICAgICAgICAgICAgICAgICAgICBERUJVR01TR1RMKCgic25tcHYzX2NvbnRleHRpZCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiAgcmVzcG9uZGluZyB3aXRoIG91ciBlbmdpbmVJRFxuIikpOwoKICAgICAgICAgICAgICAgICAgICBzbm1wX3BkdV9hZGRfdmFyaWFibGUocGR1MiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc25tcEVuZ2luZUlEb2lkLCBzbm1wRW5naW5lSURvaWRfbGVuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBBU05fT0NURVRfU1RSLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvdXJFbmdpbmVJRCwgb3VyRW5naW5lSURfbGVuKTsKICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgICAgICAgICAgICAvKiBzZW5kIHRoZSByZXNwb25zZSAqLwogICAgICAgICAgICAgICAgICAgIGlmICgwID09IHNubXBfc2Vzc19zZW5kKHNlc3NwLCBwZHUyKSkgewoKICAgICAgICAgICAgICAgICAgICAgICAgREVCVUdNU0dUTCgoInNubXB2M19jb250ZXh0aWQiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiICBzZW50IGl0IG9mZiFcbiIpKTsKCiAgICAgICAgICAgICAgICAgICAgICAgIHNubXBfZnJlZV9wZHUocGR1Mik7CiAgICAgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICAgICBzbm1wX2xvZyhMT0dfRVJSLCAic2VuZGluZyBhIHJlc3BvbnNlIHRvIHRoZSBjb250ZXh0IGVuZ2luZUlEIHByb2JlIGZhaWxlZFxuIik7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBzbm1wX2xvZyhMT0dfRVJSLCAiZmFpbGVkIHRvIGdldCBvdXIgb3duIGVuZ2luZUlEIVxuIik7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBzbm1wX2xvZyhMT0dfV0FSTklORywKICAgICAgICAgICAgICAgICAgICAgICAgICJyZWNlaXZlZCBhbiBvZGQgY29udGV4dCBlbmdpbmVJRCBwcm9iZVxuIik7CiAgICAgICAgICAgIH0KICAgICAgICB9CgogICAgICAgIGJyZWFrOwogICAgY2FzZSBTTk1QRVJSX0JBRF9WRVJTSU9OOgogICAgICAgIEVSUk9SX01TRygiZXJyb3IgcGFyc2luZyBzbm1wIG1lc3NhZ2UgdmVyc2lvbiIpOwogICAgICAgIHNubXBfaW5jcmVtZW50X3N0YXRpc3RpYyhTVEFUX1NOTVBJTkFTTlBBUlNFRVJSUyk7CiAgICAgICAgc2Vzc2lvbi0+c19zbm1wX2Vycm5vID0gU05NUEVSUl9CQURfVkVSU0lPTjsKICAgICAgICBicmVhazsKICAgIGNhc2UgU05NUF9WRVJTSU9OX3NlYzoKICAgIGNhc2UgU05NUF9WRVJTSU9OXzJ1OgogICAgY2FzZSBTTk1QX1ZFUlNJT05fMnN0YXI6CiAgICBjYXNlIFNOTVBfVkVSU0lPTl8ycDoKICAgIGRlZmF1bHQ6CiAgICAgICAgRVJST1JfTVNHKCJ1bnN1cHBvcnRlZCBzbm1wIG1lc3NhZ2UgdmVyc2lvbiIpOwogICAgICAgIHNubXBfaW5jcmVtZW50X3N0YXRpc3RpYyhTVEFUX1NOTVBJTkJBRFZFUlNJT05TKTsKCiAgICAgICAgLyoKICAgICAgICAgKiBuZWVkIGJldHRlciB3YXkgdG8gZGV0ZXJtaW5lIE9TIGluZGVwZW5kZW50CiAgICAgICAgICogSU5UMzJfTUFYIHZhbHVlLCBmb3Igbm93IGhhcmRjb2RlCiAgICAgICAgICovCiAgICAgICAgaWYgKHBkdS0+dmVyc2lvbiA8IDAgfHwgcGR1LT52ZXJzaW9uID4gMjE0NzQ4MzY0NykgewogICAgICAgICAgICBzbm1wX2luY3JlbWVudF9zdGF0aXN0aWMoU1RBVF9TTk1QSU5BU05QQVJTRUVSUlMpOwogICAgICAgIH0KICAgICAgICBzZXNzaW9uLT5zX3NubXBfZXJybm8gPSBTTk1QRVJSX0JBRF9WRVJTSU9OOwogICAgICAgIGJyZWFrOwogICAgfQoKICAgIHJldHVybiByZXN1bHQ7Cn0KCnN0YXRpYyBpbnQKc25tcF9wYXJzZSh2b2lkICpzZXNzcCwKICAgICAgICAgICBuZXRzbm1wX3Nlc3Npb24gKiBwc3MsCiAgICAgICAgICAgbmV0c25tcF9wZHUgKnBkdSwgdV9jaGFyICogZGF0YSwgc2l6ZV90IGxlbmd0aCkKewogICAgaW50ICAgICAgICAgICAgIHJjOwoKICAgIHJjID0gX3NubXBfcGFyc2Uoc2Vzc3AsIHBzcywgcGR1LCBkYXRhLCBsZW5ndGgpOwogICAgaWYgKHJjKSB7CiAgICAgICAgaWYgKCFwc3MtPnNfc25tcF9lcnJubykgewogICAgICAgICAgICBwc3MtPnNfc25tcF9lcnJubyA9IFNOTVBFUlJfQkFEX1BBUlNFOwogICAgICAgIH0KICAgICAgICBTRVRfU05NUF9FUlJPUihwc3MtPnNfc25tcF9lcnJubyk7CiAgICB9CgogICAgcmV0dXJuIHJjOwp9CgppbnQKc25tcF9wZHVfcGFyc2UobmV0c25tcF9wZHUgKnBkdSwgdV9jaGFyICogZGF0YSwgc2l6ZV90ICogbGVuZ3RoKQp7CiAgICB1X2NoYXIgICAgICAgICAgdHlwZTsKICAgIHVfY2hhciAgICAgICAgICBtc2dfdHlwZTsKICAgIHVfY2hhciAgICAgICAgICp2YXJfdmFsOwogICAgaW50ICAgICAgICAgICAgIGJhZHR5cGUgPSAwOwogICAgc2l6ZV90ICAgICAgICAgIGxlbjsKICAgIHNpemVfdCAgICAgICAgICBmb3VyOwogICAgbmV0c25tcF92YXJpYWJsZV9saXN0ICp2cCA9IE5VTEw7CiAgICBvaWQgICAgICAgICAgICAgb2JqaWRbTUFYX09JRF9MRU5dOwogICAgdV9jaGFyICAgICAgICAgKnA7CgogICAgLyoKICAgICAqIEdldCB0aGUgUERVIHR5cGUgCiAgICAgKi8KICAgIGRhdGEgPSBhc25fcGFyc2VfaGVhZGVyKGRhdGEsIGxlbmd0aCwgJm1zZ190eXBlKTsKICAgIGlmIChkYXRhID09IE5VTEwpCiAgICAgICAgcmV0dXJuIC0xOwogICAgREVCVUdNU0dUTCgoImR1bXB2X3JlY3YiLCIgICAgQ29tbWFuZCAlc1xuIiwgc25tcF9wZHVfdHlwZShtc2dfdHlwZSkpKTsKICAgIHBkdS0+Y29tbWFuZCA9IG1zZ190eXBlOwogICAgcGR1LT5mbGFncyAmPSAoflVDRF9NU0dfRkxBR19SRVNQT05TRV9QRFUpOwoKICAgIC8qCiAgICAgKiBnZXQgdGhlIGZpZWxkcyBpbiB0aGUgUERVIHByZWNlZWRpbmcgdGhlIHZhcmlhYmxlLWJpbmRpbmdzIHNlcXVlbmNlIAogICAgICovCiAgICBzd2l0Y2ggKHBkdS0+Y29tbWFuZCkgewogICAgY2FzZSBTTk1QX01TR19UUkFQOgogICAgICAgIC8qCiAgICAgICAgICogZW50ZXJwcmlzZSAKICAgICAgICAgKi8KICAgICAgICBwZHUtPmVudGVycHJpc2VfbGVuZ3RoID0gTUFYX09JRF9MRU47CiAgICAgICAgZGF0YSA9IGFzbl9wYXJzZV9vYmppZChkYXRhLCBsZW5ndGgsICZ0eXBlLCBvYmppZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZwZHUtPmVudGVycHJpc2VfbGVuZ3RoKTsKICAgICAgICBpZiAoZGF0YSA9PSBOVUxMKQogICAgICAgICAgICByZXR1cm4gLTE7CiAgICAgICAgcGR1LT5lbnRlcnByaXNlID0KICAgICAgICAgICAgKG9pZCAqKSBtYWxsb2MocGR1LT5lbnRlcnByaXNlX2xlbmd0aCAqIHNpemVvZihvaWQpKTsKICAgICAgICBpZiAocGR1LT5lbnRlcnByaXNlID09IE5VTEwpIHsKICAgICAgICAgICAgcmV0dXJuIC0xOwogICAgICAgIH0KICAgICAgICBtZW1tb3ZlKHBkdS0+ZW50ZXJwcmlzZSwgb2JqaWQsCiAgICAgICAgICAgICAgICBwZHUtPmVudGVycHJpc2VfbGVuZ3RoICogc2l6ZW9mKG9pZCkpOwoKICAgICAgICAvKgogICAgICAgICAqIGFnZW50LWFkZHIgCiAgICAgICAgICovCiAgICAgICAgZm91ciA9IDQ7CiAgICAgICAgZGF0YSA9IGFzbl9wYXJzZV9zdHJpbmcoZGF0YSwgbGVuZ3RoLCAmdHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodV9jaGFyICopIHBkdS0+YWdlbnRfYWRkciwgJmZvdXIpOwogICAgICAgIGlmIChkYXRhID09IE5VTEwpCiAgICAgICAgICAgIHJldHVybiAtMTsKCiAgICAgICAgLyoKICAgICAgICAgKiBnZW5lcmljIHRyYXAgCiAgICAgICAgICovCiAgICAgICAgZGF0YSA9IGFzbl9wYXJzZV9pbnQoZGF0YSwgbGVuZ3RoLCAmdHlwZSwgKGxvbmcgKikgJnBkdS0+dHJhcF90eXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZihwZHUtPnRyYXBfdHlwZSkpOwogICAgICAgIGlmIChkYXRhID09IE5VTEwpCiAgICAgICAgICAgIHJldHVybiAtMTsKICAgICAgICAvKgogICAgICAgICAqIHNwZWNpZmljIHRyYXAgCiAgICAgICAgICovCiAgICAgICAgZGF0YSA9CiAgICAgICAgICAgIGFzbl9wYXJzZV9pbnQoZGF0YSwgbGVuZ3RoLCAmdHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAobG9uZyAqKSAmcGR1LT5zcGVjaWZpY190eXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZihwZHUtPnNwZWNpZmljX3R5cGUpKTsKICAgICAgICBpZiAoZGF0YSA9PSBOVUxMKQogICAgICAgICAgICByZXR1cm4gLTE7CgogICAgICAgIC8qCiAgICAgICAgICogdGltZXN0YW1wICAKICAgICAgICAgKi8KICAgICAgICBkYXRhID0gYXNuX3BhcnNlX3Vuc2lnbmVkX2ludChkYXRhLCBsZW5ndGgsICZ0eXBlLCAmcGR1LT50aW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZihwZHUtPnRpbWUpKTsKICAgICAgICBpZiAoZGF0YSA9PSBOVUxMKQogICAgICAgICAgICByZXR1cm4gLTE7CgogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgU05NUF9NU0dfUkVTUE9OU0U6CiAgICBjYXNlIFNOTVBfTVNHX1JFUE9SVDoKICAgICAgICBwZHUtPmZsYWdzIHw9IFVDRF9NU0dfRkxBR19SRVNQT05TRV9QRFU7CiAgICAgICAgLyoKICAgICAgICAgKiBmYWxsdGhyb3VnaCAKICAgICAgICAgKi8KCiAgICBjYXNlIFNOTVBfTVNHX0dFVDoKICAgIGNhc2UgU05NUF9NU0dfR0VUTkVYVDoKICAgIGNhc2UgU05NUF9NU0dfR0VUQlVMSzoKICAgIGNhc2UgU05NUF9NU0dfVFJBUDI6CiAgICBjYXNlIFNOTVBfTVNHX0lORk9STToKICAgIGNhc2UgU05NUF9NU0dfU0VUOgogICAgICAgIC8qCiAgICAgICAgICogUERVIGlzIG5vdCBhbiBTTk1QdjEgVFJBUCAKICAgICAgICAgKi8KCiAgICAgICAgLyoKICAgICAgICAgKiByZXF1ZXN0IGlkIAogICAgICAgICAqLwogICAgICAgIERFQlVHRFVNUEhFQURFUigicmVjdiIsICJyZXF1ZXN0X2lkIik7CiAgICAgICAgZGF0YSA9IGFzbl9wYXJzZV9pbnQoZGF0YSwgbGVuZ3RoLCAmdHlwZSwgJnBkdS0+cmVxaWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZW9mKHBkdS0+cmVxaWQpKTsKICAgICAgICBERUJVR0lOREVOVExFU1MoKTsKICAgICAgICBpZiAoZGF0YSA9PSBOVUxMKSB7CiAgICAgICAgICAgIHJldHVybiAtMTsKICAgICAgICB9CgogICAgICAgIC8qCiAgICAgICAgICogZXJyb3Igc3RhdHVzIChnZXRidWxrIG5vbi1yZXBlYXRlcnMpIAogICAgICAgICAqLwogICAgICAgIERFQlVHRFVNUEhFQURFUigicmVjdiIsICJlcnJvciBzdGF0dXMiKTsKICAgICAgICBkYXRhID0gYXNuX3BhcnNlX2ludChkYXRhLCBsZW5ndGgsICZ0eXBlLCAmcGR1LT5lcnJzdGF0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZihwZHUtPmVycnN0YXQpKTsKICAgICAgICBERUJVR0lOREVOVExFU1MoKTsKICAgICAgICBpZiAoZGF0YSA9PSBOVUxMKSB7CiAgICAgICAgICAgIHJldHVybiAtMTsKICAgICAgICB9CgogICAgICAgIC8qCiAgICAgICAgICogZXJyb3IgaW5kZXggKGdldGJ1bGsgbWF4LXJlcGV0aXRpb25zKSAKICAgICAgICAgKi8KICAgICAgICBERUJVR0RVTVBIRUFERVIoInJlY3YiLCAiZXJyb3IgaW5kZXgiKTsKICAgICAgICBkYXRhID0gYXNuX3BhcnNlX2ludChkYXRhLCBsZW5ndGgsICZ0eXBlLCAmcGR1LT5lcnJpbmRleCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplb2YocGR1LT5lcnJpbmRleCkpOwogICAgICAgIERFQlVHSU5ERU5UTEVTUygpOwogICAgICAgIGlmIChkYXRhID09IE5VTEwpIHsKICAgICAgICAgICAgcmV0dXJuIC0xOwogICAgICAgIH0KCWJyZWFrOwoKICAgIGRlZmF1bHQ6CiAgICAgICAgc25tcF9sb2coTE9HX0VSUiwgIkJhZCBQRFUgdHlwZSByZWNlaXZlZDogMHglLjJ4XG4iLCBwZHUtPmNvbW1hbmQpOwogICAgICAgIHNubXBfaW5jcmVtZW50X3N0YXRpc3RpYyhTVEFUX1NOTVBJTkFTTlBBUlNFRVJSUyk7CiAgICAgICAgcmV0dXJuIC0xOwogICAgfQoKICAgIC8qCiAgICAgKiBnZXQgaGVhZGVyIGZvciB2YXJpYWJsZS1iaW5kaW5ncyBzZXF1ZW5jZSAKICAgICAqLwogICAgREVCVUdEVU1QU0VDVElPTigicmVjdiIsICJWYXJCaW5kTGlzdCIpOwogICAgZGF0YSA9IGFzbl9wYXJzZV9zZXF1ZW5jZShkYXRhLCBsZW5ndGgsICZ0eXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoQVNOX1NFUVVFTkNFIHwgQVNOX0NPTlNUUlVDVE9SKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInZhcmJpbmRzIik7CiAgICBpZiAoZGF0YSA9PSBOVUxMKQogICAgICAgIHJldHVybiAtMTsKCiAgICAvKgogICAgICogZ2V0IGVhY2ggdmFyQmluZCBzZXF1ZW5jZSAKICAgICAqLwogICAgd2hpbGUgKChpbnQpICpsZW5ndGggPiAwKSB7CiAgICAgICAgbmV0c25tcF92YXJpYWJsZV9saXN0ICp2cHRlbXA7CiAgICAgICAgdnB0ZW1wID0gKG5ldHNubXBfdmFyaWFibGVfbGlzdCAqKSBtYWxsb2Moc2l6ZW9mKCp2cHRlbXApKTsKICAgICAgICBpZiAoTlVMTCA9PSB2cHRlbXApIHsKICAgICAgICAgICAgcmV0dXJuIC0xOwogICAgICAgIH0KICAgICAgICBpZiAoTlVMTCA9PSB2cCkgewogICAgICAgICAgICBwZHUtPnZhcmlhYmxlcyA9IHZwdGVtcDsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICB2cC0+bmV4dF92YXJpYWJsZSA9IHZwdGVtcDsKICAgICAgICB9CiAgICAgICAgdnAgPSB2cHRlbXA7CgogICAgICAgIHZwLT5uZXh0X3ZhcmlhYmxlID0gTlVMTDsKICAgICAgICB2cC0+dmFsLnN0cmluZyA9IE5VTEw7CiAgICAgICAgdnAtPm5hbWVfbGVuZ3RoID0gTUFYX09JRF9MRU47CiAgICAgICAgdnAtPm5hbWUgPSBOVUxMOwogICAgICAgIHZwLT5pbmRleCA9IDA7CiAgICAgICAgdnAtPmRhdGEgPSBOVUxMOwogICAgICAgIHZwLT5kYXRhRnJlZUhvb2sgPSBOVUxMOwogICAgICAgIERFQlVHRFVNUFNFQ1RJT04oInJlY3YiLCAiVmFyQmluZCIpOwogICAgICAgIGRhdGEgPSBzbm1wX3BhcnNlX3Zhcl9vcChkYXRhLCBvYmppZCwgJnZwLT5uYW1lX2xlbmd0aCwgJnZwLT50eXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmdnAtPnZhbF9sZW4sICZ2YXJfdmFsLCBsZW5ndGgpOwogICAgICAgIGlmIChkYXRhID09IE5VTEwpCiAgICAgICAgICAgIHJldHVybiAtMTsKICAgICAgICBpZiAoc25tcF9zZXRfdmFyX29iamlkKHZwLCBvYmppZCwgdnAtPm5hbWVfbGVuZ3RoKSkKICAgICAgICAgICAgcmV0dXJuIC0xOwoKICAgICAgICBsZW4gPSBNQVhfUEFDS0VUX0xFTkdUSDsKICAgICAgICBERUJVR0RVTVBIRUFERVIoInJlY3YiLCAiVmFsdWUiKTsKICAgICAgICBzd2l0Y2ggKChzaG9ydCkgdnAtPnR5cGUpIHsKICAgICAgICBjYXNlIEFTTl9JTlRFR0VSOgogICAgICAgICAgICB2cC0+dmFsLmludGVnZXIgPSAobG9uZyAqKSB2cC0+YnVmOwogICAgICAgICAgICB2cC0+dmFsX2xlbiA9IHNpemVvZihsb25nKTsKICAgICAgICAgICAgcCA9IGFzbl9wYXJzZV9pbnQodmFyX3ZhbCwgJmxlbiwgJnZwLT50eXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgIChsb25nICopIHZwLT52YWwuaW50ZWdlciwKICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplb2YoKnZwLT52YWwuaW50ZWdlcikpOwogICAgICAgICAgICBpZiAoIXApCiAgICAgICAgICAgICAgICByZXR1cm4gLTE7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgQVNOX0NPVU5URVI6CiAgICAgICAgY2FzZSBBU05fR0FVR0U6CiAgICAgICAgY2FzZSBBU05fVElNRVRJQ0tTOgogICAgICAgIGNhc2UgQVNOX1VJTlRFR0VSOgogICAgICAgICAgICB2cC0+dmFsLmludGVnZXIgPSAobG9uZyAqKSB2cC0+YnVmOwogICAgICAgICAgICB2cC0+dmFsX2xlbiA9IHNpemVvZih1X2xvbmcpOwogICAgICAgICAgICBwID0gYXNuX3BhcnNlX3Vuc2lnbmVkX2ludCh2YXJfdmFsLCAmbGVuLCAmdnAtPnR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHVfbG9uZyAqKSB2cC0+dmFsLmludGVnZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdnAtPnZhbF9sZW4pOwogICAgICAgICAgICBpZiAoIXApCiAgICAgICAgICAgICAgICByZXR1cm4gLTE7CiAgICAgICAgICAgIGJyZWFrOwojaWZkZWYgTkVUU05NUF9XSVRIX09QQVFVRV9TUEVDSUFMX1RZUEVTCiAgICAgICAgY2FzZSBBU05fT1BBUVVFX0NPVU5URVI2NDoKICAgICAgICBjYXNlIEFTTl9PUEFRVUVfVTY0OgojZW5kaWYgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIE5FVFNOTVBfV0lUSF9PUEFRVUVfU1BFQ0lBTF9UWVBFUyAqLwogICAgICAgIGNhc2UgQVNOX0NPVU5URVI2NDoKICAgICAgICAgICAgdnAtPnZhbC5jb3VudGVyNjQgPSAoc3RydWN0IGNvdW50ZXI2NCAqKSB2cC0+YnVmOwogICAgICAgICAgICB2cC0+dmFsX2xlbiA9IHNpemVvZihzdHJ1Y3QgY291bnRlcjY0KTsKICAgICAgICAgICAgcCA9IGFzbl9wYXJzZV91bnNpZ25lZF9pbnQ2NCh2YXJfdmFsLCAmbGVuLCAmdnAtPnR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoc3RydWN0IGNvdW50ZXI2NCAqKSB2cC0+dmFsLgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY291bnRlcjY0LCB2cC0+dmFsX2xlbik7CiAgICAgICAgICAgIGlmICghcCkKICAgICAgICAgICAgICAgIHJldHVybiAtMTsKICAgICAgICAgICAgYnJlYWs7CiNpZmRlZiBORVRTTk1QX1dJVEhfT1BBUVVFX1NQRUNJQUxfVFlQRVMKICAgICAgICBjYXNlIEFTTl9PUEFRVUVfRkxPQVQ6CiAgICAgICAgICAgIHZwLT52YWwuZmxvYXRWYWwgPSAoZmxvYXQgKikgdnAtPmJ1ZjsKICAgICAgICAgICAgdnAtPnZhbF9sZW4gPSBzaXplb2YoZmxvYXQpOwogICAgICAgICAgICBwID0gYXNuX3BhcnNlX2Zsb2F0KHZhcl92YWwsICZsZW4sICZ2cC0+dHlwZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZwLT52YWwuZmxvYXRWYWwsIHZwLT52YWxfbGVuKTsKICAgICAgICAgICAgaWYgKCFwKQogICAgICAgICAgICAgICAgcmV0dXJuIC0xOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIEFTTl9PUEFRVUVfRE9VQkxFOgogICAgICAgICAgICB2cC0+dmFsLmRvdWJsZVZhbCA9IChkb3VibGUgKikgdnAtPmJ1ZjsKICAgICAgICAgICAgdnAtPnZhbF9sZW4gPSBzaXplb2YoZG91YmxlKTsKICAgICAgICAgICAgcCA9IGFzbl9wYXJzZV9kb3VibGUodmFyX3ZhbCwgJmxlbiwgJnZwLT50eXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZwLT52YWwuZG91YmxlVmFsLCB2cC0+dmFsX2xlbik7CiAgICAgICAgICAgIGlmICghcCkKICAgICAgICAgICAgICAgIHJldHVybiAtMTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBBU05fT1BBUVVFX0k2NDoKICAgICAgICAgICAgdnAtPnZhbC5jb3VudGVyNjQgPSAoc3RydWN0IGNvdW50ZXI2NCAqKSB2cC0+YnVmOwogICAgICAgICAgICB2cC0+dmFsX2xlbiA9IHNpemVvZihzdHJ1Y3QgY291bnRlcjY0KTsKICAgICAgICAgICAgcCA9IGFzbl9wYXJzZV9zaWduZWRfaW50NjQodmFyX3ZhbCwgJmxlbiwgJnZwLT50eXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChzdHJ1Y3QgY291bnRlcjY0ICopIHZwLT52YWwuY291bnRlcjY0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZigqdnAtPnZhbC5jb3VudGVyNjQpKTsKCiAgICAgICAgICAgIGlmICghcCkKICAgICAgICAgICAgICAgIHJldHVybiAtMTsKICAgICAgICAgICAgYnJlYWs7CiNlbmRpZiAgICAgICAgICAgICAgICAgICAgICAgICAgLyogTkVUU05NUF9XSVRIX09QQVFVRV9TUEVDSUFMX1RZUEVTICovCiAgICAgICAgY2FzZSBBU05fSVBBRERSRVNTOgogICAgICAgICAgICBpZiAodnAtPnZhbF9sZW4gIT0gNCkKICAgICAgICAgICAgICAgIHJldHVybiAtMTsKICAgICAgICAgICAgLyogZmFsbHRocm91Z2ggKi8KICAgICAgICBjYXNlIEFTTl9PQ1RFVF9TVFI6CiAgICAgICAgY2FzZSBBU05fT1BBUVVFOgogICAgICAgIGNhc2UgQVNOX05TQVA6CiAgICAgICAgICAgIGlmICh2cC0+dmFsX2xlbiA8IHNpemVvZih2cC0+YnVmKSkgewogICAgICAgICAgICAgICAgdnAtPnZhbC5zdHJpbmcgPSAodV9jaGFyICopIHZwLT5idWY7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICB2cC0+dmFsLnN0cmluZyA9ICh1X2NoYXIgKikgbWFsbG9jKHZwLT52YWxfbGVuKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAodnAtPnZhbC5zdHJpbmcgPT0gTlVMTCkgewogICAgICAgICAgICAgICAgcmV0dXJuIC0xOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHAgPSBhc25fcGFyc2Vfc3RyaW5nKHZhcl92YWwsICZsZW4sICZ2cC0+dHlwZSwgdnAtPnZhbC5zdHJpbmcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnZwLT52YWxfbGVuKTsKICAgICAgICAgICAgaWYgKCFwKQogICAgICAgICAgICAgICAgcmV0dXJuIC0xOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIEFTTl9PQkpFQ1RfSUQ6CiAgICAgICAgICAgIHZwLT52YWxfbGVuID0gTUFYX09JRF9MRU47CiAgICAgICAgICAgIHAgPSBhc25fcGFyc2Vfb2JqaWQodmFyX3ZhbCwgJmxlbiwgJnZwLT50eXBlLCBvYmppZCwgJnZwLT52YWxfbGVuKTsKICAgICAgICAgICAgaWYgKCFwKQogICAgICAgICAgICAgICAgcmV0dXJuIC0xOwogICAgICAgICAgICB2cC0+dmFsX2xlbiAqPSBzaXplb2Yob2lkKTsKICAgICAgICAgICAgdnAtPnZhbC5vYmppZCA9IChvaWQgKikgbWFsbG9jKHZwLT52YWxfbGVuKTsKICAgICAgICAgICAgaWYgKHZwLT52YWwub2JqaWQgPT0gTlVMTCkgewogICAgICAgICAgICAgICAgcmV0dXJuIC0xOwogICAgICAgICAgICB9CiAgICAgICAgICAgIG1lbW1vdmUodnAtPnZhbC5vYmppZCwgb2JqaWQsIHZwLT52YWxfbGVuKTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBTTk1QX05PU1VDSE9CSkVDVDoKICAgICAgICBjYXNlIFNOTVBfTk9TVUNISU5TVEFOQ0U6CiAgICAgICAgY2FzZSBTTk1QX0VORE9GTUlCVklFVzoKICAgICAgICBjYXNlIEFTTl9OVUxMOgogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIEFTTl9CSVRfU1RSOgogICAgICAgICAgICB2cC0+dmFsLmJpdHN0cmluZyA9ICh1X2NoYXIgKikgbWFsbG9jKHZwLT52YWxfbGVuKTsKICAgICAgICAgICAgaWYgKHZwLT52YWwuYml0c3RyaW5nID09IE5VTEwpIHsKICAgICAgICAgICAgICAgIHJldHVybiAtMTsKICAgICAgICAgICAgfQogICAgICAgICAgICBwID0gYXNuX3BhcnNlX2JpdHN0cmluZyh2YXJfdmFsLCAmbGVuLCAmdnAtPnR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdnAtPnZhbC5iaXRzdHJpbmcsICZ2cC0+dmFsX2xlbik7CiAgICAgICAgICAgIGlmICghcCkKICAgICAgICAgICAgICAgIHJldHVybiAtMTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgc25tcF9sb2coTE9HX0VSUiwgImJhZCB0eXBlIHJldHVybmVkICgleClcbiIsIHZwLT50eXBlKTsKICAgICAgICAgICAgYmFkdHlwZSA9IC0xOwogICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgICAgREVCVUdJTkRFTlRBREQoLTQpOwogICAgfQogICAgcmV0dXJuIGJhZHR5cGU7Cn0KCi8qCiAqIHNubXAgdjMgdXRpbGl0eSBmdW5jdGlvbiB0byBwYXJzZSBpbnRvIHRoZSBzY29wZWRQZHUuIHN0b3JlcyBjb250ZXh0TmFtZQogKiBhbmQgY29udGV4dEVuZ2luZUlEIGluIHBkdSBzdHJ1Y3QuIEFsc28gc3RvcmVzIHBkdS0+Y29tbWFuZCAoaGFuZHkgZm9yIAogKiBSZXBvcnQgZ2VuZXJhdGlvbikuCiAqIAogKiByZXR1cm5zIHBvaW50ZXIgdG8gYmVnaW5pbmcgb2YgUERVIG9yIE5VTEwgb24gZXJyb3IuCiAqLwp1X2NoYXIgICAgICAgICAqCnNubXB2M19zY29wZWRQRFVfcGFyc2UobmV0c25tcF9wZHUgKnBkdSwgdV9jaGFyICogY3AsIHNpemVfdCAqIGxlbmd0aCkKewogICAgdV9jaGFyICAgICAgICAgIHRtcF9idWZbU05NUF9NQVhfTVNHX1NJWkVdOwogICAgc2l6ZV90ICAgICAgICAgIHRtcF9idWZfbGVuOwogICAgdV9jaGFyICAgICAgICAgIHR5cGU7CiAgICBzaXplX3QgICAgICAgICAgYXNuX2xlbjsKICAgIHVfY2hhciAgICAgICAgICpkYXRhOwoKICAgIHBkdS0+Y29tbWFuZCA9IDA7ICAgICAgICAgICAvKiBpbml0aWFsaXplIHNvIHdlIGtub3cgaWYgaXQgZ290IHBhcnNlZCAqLwogICAgYXNuX2xlbiA9ICpsZW5ndGg7CiAgICBkYXRhID0gYXNuX3BhcnNlX3NlcXVlbmNlKGNwLCAmYXNuX2xlbiwgJnR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChBU05fU0VRVUVOQ0UgfCBBU05fQ09OU1RSVUNUT1IpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAicGxhaW50ZXh0IHNjb3BlZFBEVSIpOwogICAgaWYgKGRhdGEgPT0gTlVMTCkgewogICAgICAgIHJldHVybiBOVUxMOwogICAgfQogICAgKmxlbmd0aCAtPSBkYXRhIC0gY3A7CgogICAgLyoKICAgICAqIGNvbnRleHRFbmdpbmVJRCBmcm9tIHNjb3BlZFBkdSAgCiAgICAgKi8KICAgIERFQlVHRFVNUEhFQURFUigicmVjdiIsICJjb250ZXh0RW5naW5lSUQiKTsKICAgIGRhdGEgPSBhc25fcGFyc2Vfc3RyaW5nKGRhdGEsIGxlbmd0aCwgJnR5cGUsIHBkdS0+Y29udGV4dEVuZ2luZUlELAogICAgICAgICAgICAgICAgICAgICAgICAgICAgJnBkdS0+Y29udGV4dEVuZ2luZUlETGVuKTsKICAgIERFQlVHSU5ERU5UTEVTUygpOwogICAgaWYgKGRhdGEgPT0gTlVMTCkgewogICAgICAgIEVSUk9SX01TRygiZXJyb3IgcGFyc2luZyBjb250ZXh0RW5naW5lSUQgZnJvbSBzY29wZWRQZHUiKTsKICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0KCiAgICAvKgogICAgICogY2hlY2sgdGhhdCBpdCBhZ3JlZXMgd2l0aCBlbmdpbmVJRCByZXR1cm5lZCBmcm9tIFVTTSBhYm92ZQogICAgICogKiBvbmx5IGEgd2FybmluZyBiZWNhdXNlIHRoaXMgY291bGQgYmUgbGVnYWwgaWYgd2UgYXJlIGEgcHJveHkKICAgICAqLwogICAgaWYgKHBkdS0+c2VjdXJpdHlNb2RlbCA9PSBORVRTTk1QX1NFQ01PRF9VU00gJiYKICAgICAgICAocGR1LT5zZWN1cml0eUVuZ2luZUlETGVuICE9IHBkdS0+Y29udGV4dEVuZ2luZUlETGVuIHx8CiAgICAgICAgIG1lbWNtcChwZHUtPnNlY3VyaXR5RW5naW5lSUQsIHBkdS0+Y29udGV4dEVuZ2luZUlELAogICAgICAgICAgICAgICAgcGR1LT5zZWN1cml0eUVuZ2luZUlETGVuKSAhPSAwKSkgewogICAgICAgIERFQlVHTVNHVEwoKCJzY29wZWRQRFVfcGFyc2UiLAogICAgICAgICAgICAgICAgICAgICJOb3RlOiBzZWN1cml0eSBhbmQgY29udGV4dCBlbmdpbmVJRHMgZGlmZmVyXG4iKSk7CiAgICB9CgogICAgLyoKICAgICAqIHBhcnNlIGNvbnRleHROYW1lIGZyb20gc2NvcGVkUGR1CiAgICAgKi8KICAgIHRtcF9idWZfbGVuID0gU05NUF9NQVhfQ09OVEVYVF9TSVpFOwogICAgREVCVUdEVU1QSEVBREVSKCJyZWN2IiwgImNvbnRleHROYW1lIik7CiAgICBkYXRhID0gYXNuX3BhcnNlX3N0cmluZyhkYXRhLCBsZW5ndGgsICZ0eXBlLCB0bXBfYnVmLCAmdG1wX2J1Zl9sZW4pOwogICAgREVCVUdJTkRFTlRMRVNTKCk7CiAgICBpZiAoZGF0YSA9PSBOVUxMKSB7CiAgICAgICAgRVJST1JfTVNHKCJlcnJvciBwYXJzaW5nIGNvbnRleHROYW1lIGZyb20gc2NvcGVkUGR1Iik7CiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICB9CgogICAgaWYgKHRtcF9idWZfbGVuKSB7CiAgICAgICAgcGR1LT5jb250ZXh0TmFtZSA9IChjaGFyICopIG1hbGxvYyh0bXBfYnVmX2xlbik7CiAgICAgICAgbWVtbW92ZShwZHUtPmNvbnRleHROYW1lLCB0bXBfYnVmLCB0bXBfYnVmX2xlbik7CiAgICAgICAgcGR1LT5jb250ZXh0TmFtZUxlbiA9IHRtcF9idWZfbGVuOwogICAgfSBlbHNlIHsKICAgICAgICBwZHUtPmNvbnRleHROYW1lID0gc3RyZHVwKCIiKTsKICAgICAgICBwZHUtPmNvbnRleHROYW1lTGVuID0gMDsKICAgIH0KICAgIGlmIChwZHUtPmNvbnRleHROYW1lID09IE5VTEwpIHsKICAgICAgICBFUlJPUl9NU0coImVycm9yIGNvcHlpbmcgY29udGV4dE5hbWUgZnJvbSBzY29wZWRQZHUiKTsKICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0KCiAgICAvKgogICAgICogR2V0IHRoZSBQRFUgdHlwZSAKICAgICAqLwogICAgYXNuX2xlbiA9ICpsZW5ndGg7CiAgICBjcCA9IGFzbl9wYXJzZV9oZWFkZXIoZGF0YSwgJmFzbl9sZW4sICZ0eXBlKTsKICAgIGlmIChjcCA9PSBOVUxMKQogICAgICAgIHJldHVybiBOVUxMOwoKICAgIHBkdS0+Y29tbWFuZCA9IHR5cGU7CgogICAgcmV0dXJuIGRhdGE7Cn0KCi8qCiAqIFRoZXNlIGZ1bmN0aW9ucyBzZW5kIFBEVXMgdXNpbmcgYW4gYWN0aXZlIHNlc3Npb246CiAqIHNubXBfc2VuZCAgICAgICAgICAgICAtIHRyYWRpdGlvbmFsIEFQSSwgbm8gY2FsbGJhY2sKICogc25tcF9hc3luY19zZW5kICAgICAgIC0gdHJhZGl0aW9uYWwgQVBJLCB3aXRoIGNhbGxiYWNrCiAqIHNubXBfc2Vzc19zZW5kICAgICAgICAtIHNpbmdsZSBzZXNzaW9uIEFQSSwgbm8gY2FsbGJhY2sKICogc25tcF9zZXNzX2FzeW5jX3NlbmQgIC0gc2luZ2xlIHNlc3Npb24gQVBJLCB3aXRoIGNhbGxiYWNrCiAqCiAqIENhbGwgc25tcF9idWlsZCB0byBjcmVhdGUgYSBzZXJpYWxpemVkIHBhY2tldCAodGhlIHBkdSkuCiAqIElmIG5lY2Vzc2FyeSwgc2V0IHNvbWUgb2YgdGhlIHBkdSBkYXRhIGZyb20gdGhlCiAqIHNlc3Npb24gZGVmYXVsdHMuCiAqIElmIHRoZXJlIGlzIGFuIGV4cGVjdGVkIHJlc3BvbnNlIGZvciB0aGlzIFBEVSwKICogcXVldWUgYSBjb3JyZXNwb25kaW5nIHJlcXVlc3Qgb24gdGhlIGxpc3QKICogb2Ygb3V0c3RhbmRpbmcgcmVxdWVzdHMgZm9yIHRoaXMgc2Vzc2lvbiwKICogYW5kIHN0b3JlIHRoZSBjYWxsYmFjayB2ZWN0b3JzIGluIHRoZSByZXF1ZXN0LgogKgogKiBTZW5kIHRoZSBwZHUgdG8gdGhlIHRhcmdldCBpZGVudGlmaWVkIGJ5IHRoaXMgc2Vzc2lvbi4KICogUmV0dXJuIG9uIHN1Y2Nlc3M6CiAqICAgVGhlIHJlcXVlc3QgaWQgb2YgdGhlIHBkdSBpcyByZXR1cm5lZCwgYW5kIHRoZSBwZHUgaXMgZnJlZWQuCiAqIFJldHVybiBvbiBmYWlsdXJlOgogKiAgIFplcm8gKDApIGlzIHJldHVybmVkLgogKiAgIFRoZSBjYWxsZXIgbXVzdCBjYWxsIHNubXBfZnJlZV9wZHUgaWYgMCBpcyByZXR1cm5lZC4KICovCmludApzbm1wX3NlbmQobmV0c25tcF9zZXNzaW9uICogc2Vzc2lvbiwgbmV0c25tcF9wZHUgKnBkdSkKewogICAgcmV0dXJuIHNubXBfYXN5bmNfc2VuZChzZXNzaW9uLCBwZHUsIE5VTEwsIE5VTEwpOwp9CgppbnQKc25tcF9zZXNzX3NlbmQodm9pZCAqc2Vzc3AsIG5ldHNubXBfcGR1ICpwZHUpCnsKICAgIHJldHVybiBzbm1wX3Nlc3NfYXN5bmNfc2VuZChzZXNzcCwgcGR1LCBOVUxMLCBOVUxMKTsKfQoKaW50CnNubXBfYXN5bmNfc2VuZChuZXRzbm1wX3Nlc3Npb24gKiBzZXNzaW9uLAogICAgICAgICAgICAgICAgbmV0c25tcF9wZHUgKnBkdSwgc25tcF9jYWxsYmFjayBjYWxsYmFjaywgdm9pZCAqY2JfZGF0YSkKewogICAgdm9pZCAgICAgICAgICAgKnNlc3NwID0gc25tcF9zZXNzX3BvaW50ZXIoc2Vzc2lvbik7CiAgICByZXR1cm4gc25tcF9zZXNzX2FzeW5jX3NlbmQoc2Vzc3AsIHBkdSwgY2FsbGJhY2ssIGNiX2RhdGEpOwp9CgpzdGF0aWMgaW50Cl9zZXNzX2FzeW5jX3NlbmQodm9pZCAqc2Vzc3AsCiAgICAgICAgICAgICAgICAgbmV0c25tcF9wZHUgKnBkdSwgc25tcF9jYWxsYmFjayBjYWxsYmFjaywgdm9pZCAqY2JfZGF0YSkKewogICAgc3RydWN0IHNlc3Npb25fbGlzdCAqc2xwID0gKHN0cnVjdCBzZXNzaW9uX2xpc3QgKikgc2Vzc3A7CiAgICBuZXRzbm1wX3Nlc3Npb24gKnNlc3Npb247CiAgICBzdHJ1Y3Qgc25tcF9pbnRlcm5hbF9zZXNzaW9uICppc3A7CiAgICBuZXRzbm1wX3RyYW5zcG9ydCAqdHJhbnNwb3J0ID0gTlVMTDsKICAgIHVfY2hhciAgICAgICAgICpwa3RidWYgPSBOVUxMLCAqcGFja2V0ID0gTlVMTDsKICAgIHNpemVfdCAgICAgICAgICBwa3RidWZfbGVuID0gMCwgb2Zmc2V0ID0gMCwgbGVuZ3RoID0gMDsKICAgIGludCAgICAgICAgICAgICByZXN1bHQ7CiAgICBsb25nICAgICAgICAgICAgcmVxaWQ7CgogICAgaWYgKHNscCA9PSBOVUxMKSB7CiAgICAgICAgcmV0dXJuIDA7CiAgICB9IGVsc2UgewogICAgICAgIHNlc3Npb24gPSBzbHAtPnNlc3Npb247CiAgICAgICAgaXNwID0gc2xwLT5pbnRlcm5hbDsKICAgICAgICB0cmFuc3BvcnQgPSBzbHAtPnRyYW5zcG9ydDsKICAgICAgICBpZiAoIXNlc3Npb24gfHwgIWlzcCB8fCAhdHJhbnNwb3J0KSB7CiAgICAgICAgICAgIERFQlVHTVNHVEwoKCJzZXNzX2FzeW5jX3NlbmQiLCAic2VuZCBmYWlsOiBjbG9zaW5nLi4uXG4iKSk7CiAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgIH0KICAgIH0KCiAgICBpZiAocGR1ID09IE5VTEwpIHsKICAgICAgICBzZXNzaW9uLT5zX3NubXBfZXJybm8gPSBTTk1QRVJSX05VTExfUERVOwogICAgICAgIHJldHVybiAwOwogICAgfQoKICAgIHNlc3Npb24tPnNfc25tcF9lcnJubyA9IDA7CiAgICBzZXNzaW9uLT5zX2Vycm5vID0gMDsKCiAgICAvKgogICAgICogQ2hlY2svc2V0dXAgdGhlIHZlcnNpb24uICAKICAgICAqLwogICAgaWYgKHBkdS0+dmVyc2lvbiA9PSBTTk1QX0RFRkFVTFRfVkVSU0lPTikgewogICAgICAgIGlmIChzZXNzaW9uLT52ZXJzaW9uID09IFNOTVBfREVGQVVMVF9WRVJTSU9OKSB7CiAgICAgICAgICAgIHNlc3Npb24tPnNfc25tcF9lcnJubyA9IFNOTVBFUlJfQkFEX1ZFUlNJT047CiAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgIH0KICAgICAgICBwZHUtPnZlcnNpb24gPSBzZXNzaW9uLT52ZXJzaW9uOwogICAgfSBlbHNlIGlmIChzZXNzaW9uLT52ZXJzaW9uID09IFNOTVBfREVGQVVMVF9WRVJTSU9OKSB7CiAgICAgICAgLyoKICAgICAgICAgKiBJdCdzIE9LICAKICAgICAgICAgKi8KICAgIH0gZWxzZSBpZiAocGR1LT52ZXJzaW9uICE9IHNlc3Npb24tPnZlcnNpb24pIHsKICAgICAgICAvKgogICAgICAgICAqIEVOSEFOQ0U6IHdlIHNob3VsZCBzdXBwb3J0IG11bHRpLWxpbmd1YWwgc2Vzc2lvbnMgIAogICAgICAgICAqLwogICAgICAgIHNlc3Npb24tPnNfc25tcF9lcnJubyA9IFNOTVBFUlJfQkFEX1ZFUlNJT047CiAgICAgICAgcmV0dXJuIDA7CiAgICB9CgogICAgLyoKICAgICAqIGRvIHdlIGV4cGVjdCBhIHJlc3BvbnNlPwogICAgICovCiAgICBzd2l0Y2ggKHBkdS0+Y29tbWFuZCkgewoKICAgICAgICBjYXNlIFNOTVBfTVNHX1JFU1BPTlNFOgogICAgICAgIGNhc2UgU05NUF9NU0dfVFJBUDoKICAgICAgICBjYXNlIFNOTVBfTVNHX1RSQVAyOgogICAgICAgIGNhc2UgU05NUF9NU0dfUkVQT1JUOgogICAgICAgIGNhc2UgQUdFTlRYX01TR19DTEVBTlVQU0VUOgogICAgICAgIGNhc2UgQUdFTlRYX01TR19SRVNQT05TRToKICAgICAgICAgICAgcGR1LT5mbGFncyAmPSB+VUNEX01TR19GTEFHX0VYUEVDVF9SRVNQT05TRTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIAogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIHBkdS0+ZmxhZ3MgfD0gVUNEX01TR19GTEFHX0VYUEVDVF9SRVNQT05TRTsKICAgICAgICAgICAgYnJlYWs7CiAgICB9CgogICAgLyoKICAgICAqIGNoZWNrIHRvIHNlZSBpZiB3ZSBuZWVkIGEgdjMgZW5naW5lSUQgcHJvYmUKICAgICAqLwogICAgaWYgKChwZHUtPnZlcnNpb24gPT0gU05NUF9WRVJTSU9OXzMpICYmCiAgICAgICAgKHBkdS0+ZmxhZ3MgJiBVQ0RfTVNHX0ZMQUdfRVhQRUNUX1JFU1BPTlNFKSAmJgogICAgICAgIChzZXNzaW9uLT5zZWN1cml0eUVuZ2luZUlETGVuID09IDApICYmCiAgICAgICAgKDAgPT0gKHNlc3Npb24tPmZsYWdzICYgU05NUF9GTEFHU19ET05UX1BST0JFKSkpIHsKICAgICAgICBpbnQgcmM7CiAgICAgICAgREVCVUdNU0dUTCgoInNubXB2M19idWlsZCIsICJkZWxheWVkIHByb2JlIGZvciBlbmdpbmVJRFxuIikpOwogICAgICAgIHJjID0gc25tcHYzX2VuZ2luZUlEX3Byb2JlKHNscCwgc2Vzc2lvbik7CiAgICAgICAgaWYgKHJjID09IDApCiAgICAgICAgICAgIHJldHVybiAwOyAvKiBzX3NubXBfZXJybm8gYWxyZWFkeSBzZXQgKi8KICAgIH0KCiAgICAvKgogICAgICogY2hlY2sgdG8gc2VlIGlmIHdlIG5lZWQgdG8gY3JlYXRlIGEgdjMgdXNlciBmcm9tIHRoZSBzZXNzaW9uIGluZm8KICAgICAqLwogICAgaWYgKGNyZWF0ZV91c2VyX2Zyb21fc2Vzc2lvbihzZXNzaW9uKSAhPSBTTk1QRVJSX1NVQ0NFU1MpIHsKICAgICAgICBzZXNzaW9uLT5zX3NubXBfZXJybm8gPSBTTk1QRVJSX1VOS05PV05fVVNFUl9OQU1FOyAgLyogWFg/PyAqLwogICAgICAgIERFQlVHTVNHVEwoKCJzbm1wX2FwaSIsCiAgICAgICAgICAgICAgICAgICAgInNubXBfc2VuZCgpOiBmYWlsZWQoMikgdG8gY3JlYXRlIGEgbmV3IHVzZXIgZnJvbSBzZXNzaW9uXG4iKSk7CiAgICAgICAgcmV0dXJuIDA7CiAgICB9CgogICAgaWYgKChwa3RidWYgPSAodV9jaGFyICopbWFsbG9jKDIwNDgpKSA9PSBOVUxMKSB7CiAgICAgICAgREVCVUdNU0dUTCgoInNlc3NfYXN5bmNfc2VuZCIsCiAgICAgICAgICAgICAgICAgICAgImNvdWxkbid0IG1hbGxvYyBpbml0aWFsIHBhY2tldCBidWZmZXJcbiIpKTsKICAgICAgICBzZXNzaW9uLT5zX3NubXBfZXJybm8gPSBTTk1QRVJSX01BTExPQzsKICAgICAgICByZXR1cm4gMDsKICAgIH0gZWxzZSB7CiAgICAgICAgcGt0YnVmX2xlbiA9IDIwNDg7CiAgICB9CgojaWYgVEVNUE9SQVJJTFlfRElTQUJMRUQKICAgIC8qCiAgICAgKiAgTlVMTCB2YXJpYWJsZSBhcmUgYWxsb3dlZCBpbiBjZXJ0YWluIFBEVSB0eXBlcy4KICAgICAqICBJbiBwYXJ0aWN1bGFyLCBTTk1QdjMgZW5naW5lSUQgcHJvYmVzIGFyZSBvZiB0aGlzIGZvcm0uCiAgICAgKiAgVGhlcmUgaXMgYW4gaW50ZXJuYWwgUERVIGZsYWcgdG8gaW5kaWNhdGUgdGhhdCB0aGlzCiAgICAgKiAgICBpcyBhY2NlcHRhYmxlLCBidXQgdW50aWwgdGhlIGNvbnN0cnVjdGlvbiBvZiBlbmdpbmVJRAogICAgICogICAgcHJvYmVzIGNhbiBiZSBhbWVuZGVkIHRvIHNldCB0aGlzIGZsYWcsIHdlJ2xsIHNpbXBseQogICAgICogICAgc2tpcCB0aGlzIHRlc3QgYWx0b2dldGhlci4KICAgICAqLwogICAgaWYgKHBkdS0+dmFyaWFibGVzID09IE5VTEwpIHsKICAgICAgICBzd2l0Y2ggKHBkdS0+Y29tbWFuZCkgewogICAgICAgIGNhc2UgU05NUF9NU0dfR0VUOgogICAgICAgIGNhc2UgU05NUF9NU0dfU0VUOgogICAgICAgIGNhc2UgU05NUF9NU0dfR0VUTkVYVDoKICAgICAgICBjYXNlIFNOTVBfTVNHX0dFVEJVTEs6CiAgICAgICAgY2FzZSBTTk1QX01TR19SRVNQT05TRToKICAgICAgICBjYXNlIFNOTVBfTVNHX1RSQVAyOgogICAgICAgIGNhc2UgU05NUF9NU0dfUkVQT1JUOgogICAgICAgIGNhc2UgU05NUF9NU0dfSU5GT1JNOgogICAgICAgICAgICBzZXNzaW9uLT5zX3NubXBfZXJybm8gPSBzbm1wX2Vycm5vID0gU05NUEVSUl9OT19WQVJTOwogICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICBjYXNlIFNOTVBfTVNHX1RSQVA6CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgIH0KI2VuZGlmCgoKICAgIC8qCiAgICAgKiBCdWlsZCB0aGUgbWVzc2FnZSB0byBzZW5kLiAgCiAgICAgKi8KICAgIGlmIChpc3AtPmhvb2tfcmVhbGxvY19idWlsZCkgewogICAgICAgIHJlc3VsdCA9IGlzcC0+aG9va19yZWFsbG9jX2J1aWxkKHNlc3Npb24sIHBkdSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmcGt0YnVmLCAmcGt0YnVmX2xlbiwgJm9mZnNldCk7CiAgICAgICAgcGFja2V0ID0gcGt0YnVmOwogICAgICAgIGxlbmd0aCA9IG9mZnNldDsKICAgIH0gZWxzZSBpZiAoaXNwLT5ob29rX2J1aWxkKSB7CiAgICAgICAgcGFja2V0ID0gcGt0YnVmOwogICAgICAgIGxlbmd0aCA9IHBrdGJ1Zl9sZW47CiAgICAgICAgcmVzdWx0ID0gaXNwLT5ob29rX2J1aWxkKHNlc3Npb24sIHBkdSwgcGt0YnVmLCAmbGVuZ3RoKTsKICAgIH0gZWxzZSB7CiNpZmRlZiBORVRTTk1QX1VTRV9SRVZFUlNFX0FTTkVOQ09ESU5HCiAgICAgICAgaWYgKG5ldHNubXBfZHNfZ2V0X2Jvb2xlYW4oTkVUU05NUF9EU19MSUJSQVJZX0lELCBORVRTTk1QX0RTX0xJQl9SRVZFUlNFX0VOQ09ERSkpIHsKICAgICAgICAgICAgcmVzdWx0ID0KICAgICAgICAgICAgICAgIHNubXBfYnVpbGQoJnBrdGJ1ZiwgJnBrdGJ1Zl9sZW4sICZvZmZzZXQsIHNlc3Npb24sIHBkdSk7CiAgICAgICAgICAgIHBhY2tldCA9IHBrdGJ1ZiArIHBrdGJ1Zl9sZW4gLSBvZmZzZXQ7CiAgICAgICAgICAgIGxlbmd0aCA9IG9mZnNldDsKICAgICAgICB9IGVsc2UgewojZW5kaWYKICAgICAgICAgICAgcGFja2V0ID0gcGt0YnVmOwogICAgICAgICAgICBsZW5ndGggPSBwa3RidWZfbGVuOwogICAgICAgICAgICByZXN1bHQgPSBzbm1wX2J1aWxkKCZwa3RidWYsICZsZW5ndGgsICZvZmZzZXQsIHNlc3Npb24sIHBkdSk7CiNpZmRlZiBORVRTTk1QX1VTRV9SRVZFUlNFX0FTTkVOQ09ESU5HCiAgICAgICAgfQojZW5kaWYKICAgIH0KCiAgICBpZiAocmVzdWx0IDwgMCkgewogICAgICAgIERFQlVHTVNHVEwoKCJzZXNzX2FzeW5jX3NlbmQiLCAiZW5jb2RpbmcgZmFpbHVyZVxuIikpOwogICAgICAgIFNOTVBfRlJFRShwa3RidWYpOwogICAgICAgIHJldHVybiAwOwogICAgfQoKICAgIC8qCiAgICAgKiBNYWtlIHN1cmUgd2UgZG9uJ3Qgc2VuZCBzb21ldGhpbmcgdGhhdCBpcyBiaWdnZXIgdGhhbiB0aGUgbXNnTWF4U2l6ZQogICAgICogc3BlY2lmaWVkIGluIHRoZSByZWNlaXZlZCBQRFUuICAKICAgICAqLwoKICAgIGlmIChzZXNzaW9uLT5zbmRNc2dNYXhTaXplICE9IDAgJiYgbGVuZ3RoID4gc2Vzc2lvbi0+c25kTXNnTWF4U2l6ZSkgewogICAgICAgIERFQlVHTVNHVEwoKCJzZXNzX2FzeW5jX3NlbmQiLAogICAgICAgICAgICAgICAgICAgICJsZW5ndGggb2YgcGFja2V0ICglbHUpIGV4Y2VlZHMgc2Vzc2lvbiBtYXhpbXVtICglbHUpXG4iLAogICAgICAgICAgICAgICAgICAgICh1bnNpZ25lZCBsb25nKWxlbmd0aCwgKHVuc2lnbmVkIGxvbmcpc2Vzc2lvbi0+c25kTXNnTWF4U2l6ZSkpOwogICAgICAgIHNlc3Npb24tPnNfc25tcF9lcnJubyA9IFNOTVBFUlJfVE9PX0xPTkc7CiAgICAgICAgU05NUF9GUkVFKHBrdGJ1Zik7CiAgICAgICAgcmV0dXJuIDA7CiAgICB9CgogICAgLyoKICAgICAqIENoZWNrIHRoYXQgdGhlIHVuZGVybHlpbmcgdHJhbnNwb3J0IGlzIGNhcGFibGUgb2Ygc2VuZGluZyBhIHBhY2tldCBhcwogICAgICogbGFyZ2UgYXMgbGVuZ3RoLiAgCiAgICAgKi8KCiAgICBpZiAodHJhbnNwb3J0LT5tc2dNYXhTaXplICE9IDAgJiYgbGVuZ3RoID4gdHJhbnNwb3J0LT5tc2dNYXhTaXplKSB7CiAgICAgICAgREVCVUdNU0dUTCgoInNlc3NfYXN5bmNfc2VuZCIsCiAgICAgICAgICAgICAgICAgICAgImxlbmd0aCBvZiBwYWNrZXQgKCVsdSkgZXhjZWVkcyB0cmFuc3BvcnQgbWF4aW11bSAoJWx1KVxuIiwKICAgICAgICAgICAgICAgICAgICAodW5zaWduZWQgbG9uZylsZW5ndGgsICh1bnNpZ25lZCBsb25nKXRyYW5zcG9ydC0+bXNnTWF4U2l6ZSkpOwogICAgICAgIHNlc3Npb24tPnNfc25tcF9lcnJubyA9IFNOTVBFUlJfVE9PX0xPTkc7CiAgICAgICAgU05NUF9GUkVFKHBrdGJ1Zik7CiAgICAgICAgcmV0dXJuIDA7CiAgICB9CgogICAgLyoKICAgICAqIFNlbmQgdGhlIG1lc3NhZ2UuICAKICAgICAqLwoKICAgIERFQlVHTVNHVEwoKCJzZXNzX3Byb2Nlc3NfcGFja2V0IiwgInNlbmRpbmcgbWVzc2FnZSBpZCMlbGQgcmVxaWQjJWxkIGxlbiAlIgogICAgICAgICAgICAgICAgTkVUU05NUF9QUkl6ICJ1XG4iLCBwZHUtPm1zZ2lkLCBwZHUtPnJlcWlkLCBsZW5ndGgpKTsKICAgIHJlc3VsdCA9IG5ldHNubXBfdHJhbnNwb3J0X3NlbmQodHJhbnNwb3J0LCBwYWNrZXQsIGxlbmd0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJihwZHUtPnRyYW5zcG9ydF9kYXRhKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJihwZHUtPnRyYW5zcG9ydF9kYXRhX2xlbmd0aCkpOwoKICAgIFNOTVBfRlJFRShwa3RidWYpOwoKICAgIGlmIChyZXN1bHQgPCAwKSB7CiAgICAgICAgc2Vzc2lvbi0+c19zbm1wX2Vycm5vID0gU05NUEVSUl9CQURfU0VORFRPOwogICAgICAgIHNlc3Npb24tPnNfZXJybm8gPSBlcnJubzsKICAgICAgICByZXR1cm4gMDsKICAgIH0KCiAgICByZXFpZCA9IHBkdS0+cmVxaWQ7CgogICAgLyoKICAgICAqIEFkZCB0byBwZW5kaW5nIHJlcXVlc3RzIGxpc3QgaWYgd2UgZXhwZWN0IGEgcmVzcG9uc2UuICAKICAgICAqLwogICAgaWYgKHBkdS0+ZmxhZ3MgJiBVQ0RfTVNHX0ZMQUdfRVhQRUNUX1JFU1BPTlNFKSB7CiAgICAgICAgbmV0c25tcF9yZXF1ZXN0X2xpc3QgKnJwOwogICAgICAgIHN0cnVjdCB0aW1ldmFsICB0djsKCiAgICAgICAgcnAgPSAobmV0c25tcF9yZXF1ZXN0X2xpc3QgKikgY2FsbG9jKDEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZihuZXRzbm1wX3JlcXVlc3RfbGlzdCkpOwogICAgICAgIGlmIChycCA9PSBOVUxMKSB7CiAgICAgICAgICAgIHNlc3Npb24tPnNfc25tcF9lcnJubyA9IFNOTVBFUlJfR0VORVJSOwogICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICB9CgogICAgICAgIGdldHRpbWVvZmRheSgmdHYsIChzdHJ1Y3QgdGltZXpvbmUgKikgMCk7CiAgICAgICAgcnAtPnBkdSA9IHBkdTsKICAgICAgICBycC0+cmVxdWVzdF9pZCA9IHBkdS0+cmVxaWQ7CiAgICAgICAgcnAtPm1lc3NhZ2VfaWQgPSBwZHUtPm1zZ2lkOwogICAgICAgIHJwLT5jYWxsYmFjayA9IGNhbGxiYWNrOwogICAgICAgIHJwLT5jYl9kYXRhID0gY2JfZGF0YTsKICAgICAgICBycC0+cmV0cmllcyA9IDA7CiAgICAgICAgaWYgKHBkdS0+ZmxhZ3MgJiBVQ0RfTVNHX0ZMQUdfUERVX1RJTUVPVVQpIHsKICAgICAgICAgICAgcnAtPnRpbWVvdXQgPSBwZHUtPnRpbWUgKiAxMDAwMDAwTDsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBycC0+dGltZW91dCA9IHNlc3Npb24tPnRpbWVvdXQ7CiAgICAgICAgfQogICAgICAgIHJwLT50aW1lID0gdHY7CiAgICAgICAgdHYudHZfdXNlYyArPSBycC0+dGltZW91dDsKICAgICAgICB0di50dl9zZWMgKz0gdHYudHZfdXNlYyAvIDEwMDAwMDBMOwogICAgICAgIHR2LnR2X3VzZWMgJT0gMTAwMDAwMEw7CiAgICAgICAgcnAtPmV4cGlyZSA9IHR2OwoKICAgICAgICAvKgogICAgICAgICAqIFhYIGxvY2sgc2hvdWxkIGJlIHBlciBzZXNzaW9uICEgCiAgICAgICAgICovCiAgICAgICAgc25tcF9yZXNfbG9jayhNVF9MSUJSQVJZX0lELCBNVF9MSUJfU0VTU0lPTik7CiAgICAgICAgaWYgKGlzcC0+cmVxdWVzdHNFbmQpIHsKICAgICAgICAgICAgcnAtPm5leHRfcmVxdWVzdCA9IGlzcC0+cmVxdWVzdHNFbmQtPm5leHRfcmVxdWVzdDsKICAgICAgICAgICAgaXNwLT5yZXF1ZXN0c0VuZC0+bmV4dF9yZXF1ZXN0ID0gcnA7CiAgICAgICAgICAgIGlzcC0+cmVxdWVzdHNFbmQgPSBycDsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBycC0+bmV4dF9yZXF1ZXN0ID0gaXNwLT5yZXF1ZXN0czsKICAgICAgICAgICAgaXNwLT5yZXF1ZXN0cyA9IHJwOwogICAgICAgICAgICBpc3AtPnJlcXVlc3RzRW5kID0gcnA7CiAgICAgICAgfQogICAgICAgIHNubXBfcmVzX3VubG9jayhNVF9MSUJSQVJZX0lELCBNVF9MSUJfU0VTU0lPTik7CiAgICB9IGVsc2UgewogICAgICAgIC8qCiAgICAgICAgICogTm8gcmVzcG9uc2UgZXhwZWN0ZWQuLi4gIAogICAgICAgICAqLwogICAgICAgIGlmIChyZXFpZCkgewogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBGcmVlIHYxIG9yIHYyIFRSQVAgUERVIGlmZiBubyBlcnJvciAgCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBzbm1wX2ZyZWVfcGR1KHBkdSk7CiAgICAgICAgfQogICAgfQoKICAgIHJldHVybiByZXFpZDsKfQoKaW50CnNubXBfc2Vzc19hc3luY19zZW5kKHZvaWQgKnNlc3NwLAogICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX3BkdSAqcGR1LAogICAgICAgICAgICAgICAgICAgICBzbm1wX2NhbGxiYWNrIGNhbGxiYWNrLCB2b2lkICpjYl9kYXRhKQp7CiAgICBpbnQgICAgICAgICAgICAgcmM7CgogICAgaWYgKHNlc3NwID09IE5VTEwpIHsKICAgICAgICBzbm1wX2Vycm5vID0gU05NUEVSUl9CQURfU0VTU0lPTjsgICAgICAgLypNVENSSVRJQ0FMX1JFU09VUkNFICovCiAgICAgICAgcmV0dXJuICgwKTsKICAgIH0KICAgIC8qCiAgICAgKiBzZW5kIHBkdQogICAgICovCiAgICByYyA9IF9zZXNzX2FzeW5jX3NlbmQoc2Vzc3AsIHBkdSwgY2FsbGJhY2ssIGNiX2RhdGEpOwogICAgaWYgKHJjID09IDApIHsKICAgICAgICBzdHJ1Y3Qgc2Vzc2lvbl9saXN0ICpwc2w7CiAgICAgICAgbmV0c25tcF9zZXNzaW9uICpwc3M7CiAgICAgICAgcHNsID0gKHN0cnVjdCBzZXNzaW9uX2xpc3QgKikgc2Vzc3A7CiAgICAgICAgcHNzID0gcHNsLT5zZXNzaW9uOwogICAgICAgIFNFVF9TTk1QX0VSUk9SKHBzcy0+c19zbm1wX2Vycm5vKTsKICAgIH0KICAgIHJldHVybiByYzsKfQoKCi8qCiAqIEZyZWVzIHRoZSB2YXJpYWJsZSBhbmQgYW55IG1hbGxvYydkIGRhdGEgYXNzb2NpYXRlZCB3aXRoIGl0LgogKi8Kdm9pZApzbm1wX2ZyZWVfdmFyX2ludGVybmFscyhuZXRzbm1wX3ZhcmlhYmxlX2xpc3QgKiB2YXIpCnsKICAgIGlmICghdmFyKQogICAgICAgIHJldHVybjsKCiAgICBpZiAodmFyLT5uYW1lICE9IHZhci0+bmFtZV9sb2MpCiAgICAgICAgU05NUF9GUkVFKHZhci0+bmFtZSk7CiAgICBpZiAodmFyLT52YWwuc3RyaW5nICE9IHZhci0+YnVmKQogICAgICAgIFNOTVBfRlJFRSh2YXItPnZhbC5zdHJpbmcpOwogICAgaWYgKHZhci0+ZGF0YSkgewogICAgICAgIGlmICh2YXItPmRhdGFGcmVlSG9vaykgewogICAgICAgICAgICB2YXItPmRhdGFGcmVlSG9vayh2YXItPmRhdGEpOwogICAgICAgICAgICB2YXItPmRhdGEgPSBOVUxMOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIFNOTVBfRlJFRSh2YXItPmRhdGEpOwogICAgICAgIH0KICAgIH0KfQoKdm9pZApzbm1wX2ZyZWVfdmFyKG5ldHNubXBfdmFyaWFibGVfbGlzdCAqIHZhcikKewogICAgc25tcF9mcmVlX3Zhcl9pbnRlcm5hbHModmFyKTsKICAgIGZyZWUoKGNoYXIgKikgdmFyKTsKfQoKdm9pZApzbm1wX2ZyZWVfdmFyYmluZChuZXRzbm1wX3ZhcmlhYmxlX2xpc3QgKiB2YXIpCnsKICAgIG5ldHNubXBfdmFyaWFibGVfbGlzdCAqcHRyOwogICAgd2hpbGUgKHZhcikgewogICAgICAgIHB0ciA9IHZhci0+bmV4dF92YXJpYWJsZTsKICAgICAgICBzbm1wX2ZyZWVfdmFyKHZhcik7CiAgICAgICAgdmFyID0gcHRyOwogICAgfQp9CgovKgogKiBGcmVlcyB0aGUgcGR1IGFuZCBhbnkgbWFsbG9jJ2QgZGF0YSBhc3NvY2lhdGVkIHdpdGggaXQuCiAqLwp2b2lkCnNubXBfZnJlZV9wZHUobmV0c25tcF9wZHUgKnBkdSkKewogICAgc3RydWN0IHNubXBfc2VjbW9kX2RlZiAqc3B0cjsKCiAgICBpZiAoIXBkdSkKICAgICAgICByZXR1cm47CgogICAgLyoKICAgICAqIElmIHRoZSBjb21tYW5kIGZpZWxkIGlzIGVtcHR5LCB0aGF0IHByb2JhYmx5IGluZGljYXRlcwogICAgICogICB0aGF0IHRoaXMgUERVIHN0cnVjdHVyZSBoYXMgYWxyZWFkeSBiZWVuIGZyZWVkLgogICAgICogICBMb2cgYSB3YXJuaW5nIGFuZCByZXR1cm4gKHJhdGhlciB0aGFuIGZyZWVpbmcgdGhpbmdzIGFnYWluKQogICAgICoKICAgICAqIE5vdGUgdGhhdCB0aGlzIGRvZXMgbm90IHBpY2sgdXAgZHVhbC1mcmVlcyB3aGVyZSB0aGUKICAgICAqICAgbWVtb3J5IGlzIHNldCB0byByYW5kb20ganVuaywgd2hpY2ggaXMgcHJvYmFibHkgbW9yZSBzZXJpb3VzLgogICAgICoKICAgICAqIHJrczogd2hpbGUgdGhpcyBpcyBhIGdvb2QgaWRlYSwgdGhlcmUgYXJlIHR3byBwcm9ibGVtcy4KICAgICAqICAgICAgICAgMSkgYWdlbnR4IHNldHMgY29tbWFuZCB0byAwIGluIHNvbWUgY2FzZXMKICAgICAqICAgICAgICAgMikgYWNjb3JkaW5nIHRvIFdlcywgYSBiYWQgZGVjb2RlIG9mIGEgdjMgbWVzc2FnZSBjb3VsZAogICAgICogICAgICAgICAgICByZXN1bHQgaW4gYSAwIGF0IHRoaXMgb2Zmc2V0LgogICAgICogICAgICBzbyBJJ20gY29tbWVudGluZyBpdCBvdXQgdW50aWwgYSBiZXR0ZXIgc29sdXRpb24gaXMgZm91bmQuCiAgICAgKiAgICAgIG5vdGUgdGhhdCBJJ20gbGVhdmluZyB0aGUgbWVtc2V0LCBiZWxvdy4uLi4KICAgICAqCiAgICBpZiAocGR1LT5jb21tYW5kID09IDApIHsKICAgICAgICBzbm1wX2xvZyhMT0dfV0FSTklORywgInNubXBfZnJlZV9wZHUgcHJvYmFibHkgY2FsbGVkIHR3aWNlXG4iKTsKICAgICAgICByZXR1cm47CiAgICB9CiAgICAgKi8KICAgIGlmICgoc3B0ciA9IGZpbmRfc2VjX21vZChwZHUtPnNlY3VyaXR5TW9kZWwpKSAhPSBOVUxMICYmCiAgICAgICAgc3B0ci0+cGR1X2ZyZWUgIT0gTlVMTCkgewogICAgICAgICgqc3B0ci0+cGR1X2ZyZWUpIChwZHUpOwogICAgfQogICAgc25tcF9mcmVlX3ZhcmJpbmQocGR1LT52YXJpYWJsZXMpOwogICAgU05NUF9GUkVFKHBkdS0+ZW50ZXJwcmlzZSk7CiAgICBTTk1QX0ZSRUUocGR1LT5jb21tdW5pdHkpOwogICAgU05NUF9GUkVFKHBkdS0+Y29udGV4dEVuZ2luZUlEKTsKICAgIFNOTVBfRlJFRShwZHUtPnNlY3VyaXR5RW5naW5lSUQpOwogICAgU05NUF9GUkVFKHBkdS0+Y29udGV4dE5hbWUpOwogICAgU05NUF9GUkVFKHBkdS0+c2VjdXJpdHlOYW1lKTsKICAgIFNOTVBfRlJFRShwZHUtPnRyYW5zcG9ydF9kYXRhKTsKICAgIG1lbXNldChwZHUsIDAsIHNpemVvZihuZXRzbm1wX3BkdSkpOwogICAgZnJlZSgoY2hhciAqKSBwZHUpOwp9CgpuZXRzbm1wX3BkdSAgICAqCnNubXBfY3JlYXRlX3Nlc3NfcGR1KG5ldHNubXBfdHJhbnNwb3J0ICp0cmFuc3BvcnQsIHZvaWQgKm9wYXF1ZSwKICAgICAgICAgICAgICAgICAgICAgc2l6ZV90IG9sZW5ndGgpCnsKICAgIG5ldHNubXBfcGR1ICpwZHUgPSAobmV0c25tcF9wZHUgKiljYWxsb2MoMSwgc2l6ZW9mKG5ldHNubXBfcGR1KSk7CiAgICBpZiAocGR1ID09IE5VTEwpIHsKICAgICAgICBERUJVR01TR1RMKCgic2Vzc19wcm9jZXNzX3BhY2tldCIsICJjYW4ndCBtYWxsb2Mgc3BhY2UgZm9yIFBEVVxuIikpOwogICAgICAgIHJldHVybiBOVUxMOwogICAgfQoKICAgIC8qCiAgICAgKiBTYXZlIHRoZSB0cmFuc3BvcnQtbGV2ZWwgZGF0YSBzcGVjaWZpYyB0byB0aGlzIHJlY2VwdGlvbiAoZS5nLiBVRFAKICAgICAqIHNvdXJjZSBhZGRyZXNzKS4gIAogICAgICovCgogICAgcGR1LT50cmFuc3BvcnRfZGF0YSA9IG9wYXF1ZTsKICAgIHBkdS0+dHJhbnNwb3J0X2RhdGFfbGVuZ3RoID0gb2xlbmd0aDsKICAgIHBkdS0+dERvbWFpbiA9IHRyYW5zcG9ydC0+ZG9tYWluOwogICAgcGR1LT50RG9tYWluTGVuID0gdHJhbnNwb3J0LT5kb21haW5fbGVuZ3RoOwogICAgcmV0dXJuIHBkdTsKfQoKCi8qCiAqIFRoaXMgZnVuY3Rpb24gcHJvY2Vzc2VzIGEgY29tcGxldGUgKGFjY29yZGluZyB0byBhc25fY2hlY2tfcGFja2V0IG9yIHRoZQogKiBBZ2VudFggZXF1aXZhbGVudCkgcGFja2V0LCBwYXJzaW5nIGl0IGludG8gYSBQRFUgYW5kIGNhbGxpbmcgdGhlIHJlbGV2YW50CiAqIGNhbGxiYWNrcy4gIE9uIGVudHJ5LCBwYWNrZXRwdHIgcG9pbnRzIGF0IHRoZSBwYWNrZXQgaW4gdGhlIHNlc3Npb24ncwogKiBidWZmZXIgYW5kIGxlbmd0aCBpcyB0aGUgbGVuZ3RoIG9mIHRoZSBwYWNrZXQuICAKICovCgpzdGF0aWMgaW50Cl9zZXNzX3Byb2Nlc3NfcGFja2V0KHZvaWQgKnNlc3NwLCBuZXRzbm1wX3Nlc3Npb24gKiBzcCwKICAgICAgICAgICAgICAgICAgICAgc3RydWN0IHNubXBfaW50ZXJuYWxfc2Vzc2lvbiAqaXNwLAogICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX3RyYW5zcG9ydCAqdHJhbnNwb3J0LAogICAgICAgICAgICAgICAgICAgICB2b2lkICpvcGFxdWUsIGludCBvbGVuZ3RoLAogICAgICAgICAgICAgICAgICAgICB1X2NoYXIgKiBwYWNrZXRwdHIsIGludCBsZW5ndGgpCnsKICBzdHJ1Y3Qgc2Vzc2lvbl9saXN0ICpzbHAgPSAoc3RydWN0IHNlc3Npb25fbGlzdCAqKSBzZXNzcDsKICBuZXRzbm1wX3BkdSAgICAqcGR1OwogIG5ldHNubXBfcmVxdWVzdF9saXN0ICpycCwgKm9ycCA9IE5VTEw7CiAgc3RydWN0IHNubXBfc2VjbW9kX2RlZiAqc3B0cjsKICBpbnQgICAgICAgICAgICAgcmV0ID0gMCwgaGFuZGxlZCA9IDA7CgogIERFQlVHTVNHVEwoKCJzZXNzX3Byb2Nlc3NfcGFja2V0IiwKCSAgICAgICJzZXNzaW9uICVwIGZkICVkIHBrdCAlcCBsZW5ndGggJWRcbiIsIHNlc3NwLAoJICAgICAgdHJhbnNwb3J0LT5zb2NrLCBwYWNrZXRwdHIsIGxlbmd0aCkpOwoKICBpZiAobmV0c25tcF9kc19nZXRfYm9vbGVhbihORVRTTk1QX0RTX0xJQlJBUllfSUQsTkVUU05NUF9EU19MSUJfRFVNUF9QQUNLRVQpKSB7CiAgICAgIGNoYXIgKmFkZHJ0eHQgPSBuZXRzbm1wX3RyYW5zcG9ydF9wZWVyX3N0cmluZyh0cmFuc3BvcnQsIG9wYXF1ZSwgb2xlbmd0aCk7CiAgICAgIHNubXBfbG9nKExPR19ERUJVRywgIlxuUmVjZWl2ZWQgJWQgYnl0ZSBwYWNrZXQgZnJvbSAlc1xuIiwKICAgICAgICAgICAgICAgbGVuZ3RoLCBhZGRydHh0KTsKICAgICAgU05NUF9GUkVFKGFkZHJ0eHQpOwogICAgICB4ZHVtcChwYWNrZXRwdHIsIGxlbmd0aCwgIiIpOwogIH0KCiAgLyoKICAgKiBEbyB0cmFuc3BvcnQtbGV2ZWwgZmlsdGVyaW5nIChlLmcuIElQLWFkZHJlc3MgYmFzZWQgYWxsb3cvZGVueSkuICAKICAgKi8KCiAgaWYgKGlzcC0+aG9va19wcmUpIHsKICAgIGlmIChpc3AtPmhvb2tfcHJlKHNwLCB0cmFuc3BvcnQsIG9wYXF1ZSwgb2xlbmd0aCkgPT0gMCkgewogICAgICBERUJVR01TR1RMKCgic2Vzc19wcm9jZXNzX3BhY2tldCIsICJwcmUtcGFyc2UgZmFpbFxuIikpOwogICAgICBpZiAob3BhcXVlICE9IE5VTEwpIHsKCVNOTVBfRlJFRShvcGFxdWUpOwogICAgICB9CiAgICAgIHJldHVybiAtMTsKICAgIH0KICB9CgogIGlmIChpc3AtPmhvb2tfY3JlYXRlX3BkdSkgewogICAgcGR1ID0gaXNwLT5ob29rX2NyZWF0ZV9wZHUodHJhbnNwb3J0LCBvcGFxdWUsIG9sZW5ndGgpOwogIH0gZWxzZSB7CiAgICBwZHUgPSBzbm1wX2NyZWF0ZV9zZXNzX3BkdSh0cmFuc3BvcnQsIG9wYXF1ZSwgb2xlbmd0aCk7CiAgfQoKICBpZiAocGR1ID09IE5VTEwpIHsKICAgIHNubXBfbG9nKExPR19FUlIsICJwZHUgZmFpbGVkIHRvIGJlIGNyZWF0ZWRcbiIpOwogICAgaWYgKG9wYXF1ZSAhPSBOVUxMKSB7CiAgICAgIFNOTVBfRlJFRShvcGFxdWUpOwogICAgfQogICAgcmV0dXJuIC0xOwogIH0KCiAgLyogaWYgdGhlIHRyYW5zcG9ydCB3YXMgYSBtYWdpYyB0dW5uZWwsIG1hcmsgdGhlIFBEVSBhcyBoYXZpbmcgY29tZQogICAgIHRocm91Z2ggb25lLiAqLwogIGlmICh0cmFuc3BvcnQtPmZsYWdzICYgTkVUU05NUF9UUkFOU1BPUlRfRkxBR19UVU5ORUxFRCkgewogICAgICBwZHUtPmZsYWdzIHw9IFVDRF9NU0dfRkxBR19UVU5ORUxFRDsKICB9CgogIGlmIChpc3AtPmhvb2tfcGFyc2UpIHsKICAgIHJldCA9IGlzcC0+aG9va19wYXJzZShzcCwgcGR1LCBwYWNrZXRwdHIsIGxlbmd0aCk7CiAgfSBlbHNlIHsKICAgIHJldCA9IHNubXBfcGFyc2Uoc2Vzc3AsIHNwLCBwZHUsIHBhY2tldHB0ciwgbGVuZ3RoKTsKICB9CgogIERFQlVHTVNHVEwoKCJzZXNzX3Byb2Nlc3NfcGFja2V0IiwgInJlY2VpdmVkIG1lc3NhZ2UgaWQjJWxkIHJlcWlkIyVsZCBsZW4gIgogICAgICAgICAgICAgICIldVxuIiwgcGR1LT5tc2dpZCwgcGR1LT5yZXFpZCwgbGVuZ3RoKSk7CgogIGlmIChyZXQgIT0gU05NUF9FUlJfTk9FUlJPUikgewogICAgREVCVUdNU0dUTCgoInNlc3NfcHJvY2Vzc19wYWNrZXQiLCAicGFyc2UgZmFpbFxuIikpOwogIH0KCiAgaWYgKGlzcC0+aG9va19wb3N0KSB7CiAgICBpZiAoaXNwLT5ob29rX3Bvc3Qoc3AsIHBkdSwgcmV0KSA9PSAwKSB7CiAgICAgIERFQlVHTVNHVEwoKCJzZXNzX3Byb2Nlc3NfcGFja2V0IiwgInBvc3QtcGFyc2UgZmFpbFxuIikpOwogICAgICByZXQgPSBTTk1QRVJSX0FTTl9QQVJTRV9FUlI7CiAgICB9CiAgfQoKICBpZiAocmV0ICE9IFNOTVBfRVJSX05PRVJST1IpIHsKICAgIC8qCiAgICAgKiBDYWxsIHRoZSBzZWN1cml0eSBtb2RlbCB0byBmcmVlIGFueSBzZWN1cml0eVN0YXRlUmVmIHN1cHBsaWVkIHcvIG1zZy4gIAogICAgICovCiAgICBpZiAocGR1LT5zZWN1cml0eVN0YXRlUmVmICE9IE5VTEwpIHsKICAgICAgc3B0ciA9IGZpbmRfc2VjX21vZChwZHUtPnNlY3VyaXR5TW9kZWwpOwogICAgICBpZiAoc3B0ciAhPSBOVUxMKSB7CglpZiAoc3B0ci0+cGR1X2ZyZWVfc3RhdGVfcmVmICE9IE5VTEwpIHsKCSAgKCpzcHRyLT5wZHVfZnJlZV9zdGF0ZV9yZWYpIChwZHUtPnNlY3VyaXR5U3RhdGVSZWYpOwoJfSBlbHNlIHsKCSAgc25tcF9sb2coTE9HX0VSUiwKCQkgICAiU2VjdXJpdHkgTW9kZWwgJWQgY2FuJ3QgZnJlZSBzdGF0ZSByZWZlcmVuY2VzXG4iLAoJCSAgIHBkdS0+c2VjdXJpdHlNb2RlbCk7Cgl9CiAgICAgIH0gZWxzZSB7Cglzbm1wX2xvZyhMT0dfRVJSLAoJCSAiQ2FuJ3QgZmluZCBzZWN1cml0eSBtb2RlbCB0byBmcmVlIHB0cjogJWRcbiIsCgkJIHBkdS0+c2VjdXJpdHlNb2RlbCk7CiAgICAgIH0KICAgICAgcGR1LT5zZWN1cml0eVN0YXRlUmVmID0gTlVMTDsKICAgIH0KICAgIHNubXBfZnJlZV9wZHUocGR1KTsKICAgIHJldHVybiAtMTsKICB9CgogIGlmIChwZHUtPmZsYWdzICYgVUNEX01TR19GTEFHX1JFU1BPTlNFX1BEVSkgewogICAgLyoKICAgICAqIENhbGwgVVNNIHRvIGZyZWUgYW55IHNlY3VyaXR5U3RhdGVSZWYgc3VwcGxpZWQgd2l0aCB0aGUgbWVzc2FnZS4gIAogICAgICovCiAgICBpZiAocGR1LT5zZWN1cml0eVN0YXRlUmVmKSB7CiAgICAgIHNwdHIgPSBmaW5kX3NlY19tb2QocGR1LT5zZWN1cml0eU1vZGVsKTsKICAgICAgaWYgKHNwdHIpIHsKCWlmIChzcHRyLT5wZHVfZnJlZV9zdGF0ZV9yZWYpIHsKCSAgKCpzcHRyLT5wZHVfZnJlZV9zdGF0ZV9yZWYpIChwZHUtPnNlY3VyaXR5U3RhdGVSZWYpOwoJfSBlbHNlIHsKCSAgc25tcF9sb2coTE9HX0VSUiwKCQkgICAiU2VjdXJpdHkgTW9kZWwgJWQgY2FuJ3QgZnJlZSBzdGF0ZSByZWZlcmVuY2VzXG4iLAoJCSAgIHBkdS0+c2VjdXJpdHlNb2RlbCk7Cgl9CiAgICAgIH0gZWxzZSB7Cglzbm1wX2xvZyhMT0dfRVJSLAoJCSAiQ2FuJ3QgZmluZCBzZWN1cml0eSBtb2RlbCB0byBmcmVlIHB0cjogJWRcbiIsCgkJIHBkdS0+c2VjdXJpdHlNb2RlbCk7CiAgICAgIH0KICAgICAgcGR1LT5zZWN1cml0eVN0YXRlUmVmID0gTlVMTDsKICAgIH0KCiAgICBmb3IgKHJwID0gaXNwLT5yZXF1ZXN0czsgcnA7IG9ycCA9IHJwLCBycCA9IHJwLT5uZXh0X3JlcXVlc3QpIHsKICAgICAgc25tcF9jYWxsYmFjayAgIGNhbGxiYWNrOwogICAgICB2b2lkICAgICAgICAgICAqbWFnaWM7CgogICAgICBpZiAocGR1LT52ZXJzaW9uID09IFNOTVBfVkVSU0lPTl8zKSB7CgkvKgoJICogbXNnSWQgbXVzdCBtYXRjaCBmb3IgdjMgbWVzc2FnZXMuICAKCSAqLwoJaWYgKHJwLT5tZXNzYWdlX2lkICE9IHBkdS0+bXNnaWQpIHsKICAgICAgICAgICAgREVCVUdNU0dUTCgoInNlc3NfcHJvY2Vzc19wYWNrZXQiLCAidW5tYXRjaGVkIG1zZyBpZDogJWxkICE9ICVsZFxuIiwKICAgICAgICAgICAgICAgICAgICAgICAgcnAtPm1lc3NhZ2VfaWQsIHBkdS0+bXNnaWQpKTsKCSAgICBjb250aW51ZTsKCX0KCgkvKgoJICogQ2hlY2sgdGhhdCBtZXNzYWdlIGZpZWxkcyBtYXRjaCBvcmlnaW5hbCwgaWYgbm90LCBubyBmdXJ0aGVyCgkgKiBwcm9jZXNzaW5nLiAgCgkgKi8KCWlmICghc25tcHYzX3ZlcmlmeV9tc2cocnAsIHBkdSkpIHsKCSAgYnJlYWs7Cgl9CiAgICAgIH0gZWxzZSB7CglpZiAocnAtPnJlcXVlc3RfaWQgIT0gcGR1LT5yZXFpZCkgewoJICBjb250aW51ZTsKCX0KICAgICAgfQoKICAgICAgaWYgKHJwLT5jYWxsYmFjaykgewoJY2FsbGJhY2sgPSBycC0+Y2FsbGJhY2s7CgltYWdpYyA9IHJwLT5jYl9kYXRhOwogICAgICB9IGVsc2UgewoJY2FsbGJhY2sgPSBzcC0+Y2FsbGJhY2s7CgltYWdpYyA9IHNwLT5jYWxsYmFja19tYWdpYzsKICAgICAgfQogICAgICBoYW5kbGVkID0gMTsKCiAgICAgIC8qCiAgICAgICAqIE1UUiBzbm1wX3Jlc19sb2NrKE1UX0xJQlJBUllfSUQsIE1UX0xJQl9TRVNTSU9OKTsgID8qIFhYIGxvY2sKICAgICAgICogc2hvdWxkIGJlIHBlciBzZXNzaW9uICEgCiAgICAgICAqLwoKICAgICAgaWYgKGNhbGxiYWNrID09IE5VTEwKCSAgfHwgY2FsbGJhY2soTkVUU05NUF9DQUxMQkFDS19PUF9SRUNFSVZFRF9NRVNTQUdFLCBzcCwKCQkgICAgICBwZHUtPnJlcWlkLCBwZHUsIG1hZ2ljKSA9PSAxKSB7CglpZiAocGR1LT5jb21tYW5kID09IFNOTVBfTVNHX1JFUE9SVCkgewoJICBpZiAoc3AtPnNfc25tcF9lcnJubyA9PSBTTk1QRVJSX05PVF9JTl9USU1FX1dJTkRPVyB8fAoJICAgICAgc25tcHYzX2dldF9yZXBvcnRfdHlwZShwZHUpID09CgkgICAgICBTTk1QRVJSX05PVF9JTl9USU1FX1dJTkRPVykgewoJICAgIC8qCgkgICAgICogdHJpZ2dlciBpbW1lZGlhdGUgcmV0cnkgb24gcmVjb3ZlcmFibGUgUmVwb3J0cyAKCSAgICAgKiAqIChub3RJblRpbWVXaW5kb3cpLCBpbmNyX3JldHJpZXMgPT0gVFJVRSB0byBwcmV2ZW50CgkgICAgICogKiBpbmlmaW5pdGUgcmVzZW5kICAgICAgICAgICAgICAgICAgICAgIAoJICAgICAqLwoJICAgIGlmIChycC0+cmV0cmllcyA8PSBzcC0+cmV0cmllcykgewoJICAgICAgc25tcF9yZXNlbmRfcmVxdWVzdChzbHAsIHJwLCBUUlVFKTsKCSAgICAgIGJyZWFrOwoJICAgIH0gZWxzZSB7CgkgICAgICAvKiBXZSdyZSBkb25lIHdpdGggcmV0cmllcywgc28gbm8gbG9uZ2VyIHdhaXRpbmcgZm9yIGEgcmVzcG9uc2UgKi8KCSAgICAgIGlmIChtYWdpYykgewoJCSgoc3RydWN0IHN5bmNoX3N0YXRlKiltYWdpYyktPndhaXRpbmcgPSAwOwoJICAgICAgfQoJICAgIH0KCSAgfSBlbHNlIHsKCSAgICBpZiAoU05NUFYzX0lHTk9SRV9VTkFVVEhfUkVQT1JUUykgewoJICAgICAgYnJlYWs7CgkgICAgfSBlbHNlIHsgLyogU2V0IHRoZSBzdGF0ZSB0byBubyBsb25nZXIgYmUgd2FpdGluZywgc2luY2Ugd2UncmUgZG9uZSB3aXRoIHJldHJpZXMgKi8KCSAgICAgIGlmIChtYWdpYykgewoJCSgoc3RydWN0IHN5bmNoX3N0YXRlKiltYWdpYyktPndhaXRpbmcgPSAwOwoJICAgICAgfQoJICAgIH0KCSAgfQoKCSAgLyoKCSAgICogSGFuZGxlIGVuZ2luZUlEIGRpc2NvdmVyeS4gIAoJICAgKi8KCSAgaWYgKCFzcC0+c2VjdXJpdHlFbmdpbmVJRExlbiAmJiBwZHUtPnNlY3VyaXR5RW5naW5lSURMZW4pIHsKCSAgICBzcC0+c2VjdXJpdHlFbmdpbmVJRCA9CgkgICAgICAodV9jaGFyICopIG1hbGxvYyhwZHUtPnNlY3VyaXR5RW5naW5lSURMZW4pOwoJICAgIGlmIChzcC0+c2VjdXJpdHlFbmdpbmVJRCA9PSBOVUxMKSB7CgkgICAgICAvKgoJICAgICAgICogVE9ETyBGSVg6IHJlY292ZXIgYWZ0ZXIgbWVzc2FnZSBjYWxsYmFjayAqPwogICAgICAgICAgICAgICAqLwoJICAgICAgcmV0dXJuIC0xOwoJICAgIH0KCSAgICBtZW1jcHkoc3AtPnNlY3VyaXR5RW5naW5lSUQsIHBkdS0+c2VjdXJpdHlFbmdpbmVJRCwKCQkgICBwZHUtPnNlY3VyaXR5RW5naW5lSURMZW4pOwoJICAgIHNwLT5zZWN1cml0eUVuZ2luZUlETGVuID0gcGR1LT5zZWN1cml0eUVuZ2luZUlETGVuOwoJICAgIGlmICghc3AtPmNvbnRleHRFbmdpbmVJRExlbikgewoJICAgICAgc3AtPmNvbnRleHRFbmdpbmVJRCA9CgkJKHVfY2hhciAqKSBtYWxsb2MocGR1LT4KCQkJCSAgc2VjdXJpdHlFbmdpbmVJRExlbik7CgkgICAgICBpZiAoc3AtPmNvbnRleHRFbmdpbmVJRCA9PSBOVUxMKSB7CgkJLyoKCQkgKiBUT0RPIEZJWDogcmVjb3ZlciBhZnRlciBtZXNzYWdlIGNhbGxiYWNrICo/CgkJICovCiAgICAgICAgICAgICAgICByZXR1cm4gLTE7CgkgICAgICB9CgkgICAgICBtZW1jcHkoc3AtPmNvbnRleHRFbmdpbmVJRCwKCQkgICAgIHBkdS0+c2VjdXJpdHlFbmdpbmVJRCwKCQkgICAgIHBkdS0+c2VjdXJpdHlFbmdpbmVJRExlbik7CgkgICAgICBzcC0+Y29udGV4dEVuZ2luZUlETGVuID0KCQlwZHUtPnNlY3VyaXR5RW5naW5lSURMZW47CgkgICAgfQoJICB9Cgl9CgoJLyoKCSAqIFN1Y2Nlc3NmdWwsIHNvIGRlbGV0ZSByZXF1ZXN0LiAgCgkgKi8KCWlmIChpc3AtPnJlcXVlc3RzID09IHJwKSB7CgkgIGlzcC0+cmVxdWVzdHMgPSBycC0+bmV4dF9yZXF1ZXN0OwoJICBpZiAoaXNwLT5yZXF1ZXN0c0VuZCA9PSBycCkgewoJICAgIGlzcC0+cmVxdWVzdHNFbmQgPSBOVUxMOwoJICB9Cgl9IGVsc2UgewoJICBvcnAtPm5leHRfcmVxdWVzdCA9IHJwLT5uZXh0X3JlcXVlc3Q7CgkgIGlmIChpc3AtPnJlcXVlc3RzRW5kID09IHJwKSB7CgkgICAgaXNwLT5yZXF1ZXN0c0VuZCA9IG9ycDsKCSAgfQoJfQoJc25tcF9mcmVlX3BkdShycC0+cGR1KTsKCWZyZWUoKGNoYXIgKikgcnApOwoJLyoKCSAqIFRoZXJlIHNob3VsZG4ndCBiZSBhbnkgbW9yZSByZXF1ZXN0cyB3aXRoIHRoZSBzYW1lIHJlcWlkLiAgCgkgKi8KCWJyZWFrOwogICAgICB9CiAgICAgIC8qCiAgICAgICAqIE1UUiBzbm1wX3Jlc191bmxvY2soTVRfTElCUkFSWV9JRCwgTVRfTElCX1NFU1NJT04pOyAgPyogWFggbG9jayBzaG91bGQgYmUgcGVyIHNlc3Npb24gISAKICAgICAgICovCiAgICB9CiAgfSBlbHNlIHsKICAgIGlmIChzcC0+Y2FsbGJhY2spIHsKICAgICAgLyoKICAgICAgICogTVRSIHNubXBfcmVzX2xvY2soTVRfTElCUkFSWV9JRCwgTVRfTElCX1NFU1NJT04pOyAKICAgICAgICovCiAgICAgIGhhbmRsZWQgPSAxOwogICAgICBzcC0+Y2FsbGJhY2soTkVUU05NUF9DQUxMQkFDS19PUF9SRUNFSVZFRF9NRVNTQUdFLAoJCSAgIHNwLCBwZHUtPnJlcWlkLCBwZHUsIHNwLT5jYWxsYmFja19tYWdpYyk7CiAgICAgIC8qCiAgICAgICAqIE1UUiBzbm1wX3Jlc191bmxvY2soTVRfTElCUkFSWV9JRCwgTVRfTElCX1NFU1NJT04pOyAKICAgICAgICovCiAgICB9CiAgfQoKICAvKgogICAqIENhbGwgVVNNIHRvIGZyZWUgYW55IHNlY3VyaXR5U3RhdGVSZWYgc3VwcGxpZWQgd2l0aCB0aGUgbWVzc2FnZS4gIAogICAqLwogIGlmIChwZHUgIT0gTlVMTCAmJiBwZHUtPnNlY3VyaXR5U3RhdGVSZWYgJiYKICAgICAgcGR1LT5jb21tYW5kID09IFNOTVBfTVNHX1RSQVAyKSB7CiAgICBzcHRyID0gZmluZF9zZWNfbW9kKHBkdS0+c2VjdXJpdHlNb2RlbCk7CiAgICBpZiAoc3B0cikgewogICAgICBpZiAoc3B0ci0+cGR1X2ZyZWVfc3RhdGVfcmVmKSB7CgkoKnNwdHItPnBkdV9mcmVlX3N0YXRlX3JlZikgKHBkdS0+c2VjdXJpdHlTdGF0ZVJlZik7CiAgICAgIH0gZWxzZSB7Cglzbm1wX2xvZyhMT0dfRVJSLAoJCSAiU2VjdXJpdHkgTW9kZWwgJWQgY2FuJ3QgZnJlZSBzdGF0ZSByZWZlcmVuY2VzXG4iLAoJCSBwZHUtPnNlY3VyaXR5TW9kZWwpOwogICAgICB9CiAgICB9IGVsc2UgewogICAgICBzbm1wX2xvZyhMT0dfRVJSLAoJICAgICAgICJDYW4ndCBmaW5kIHNlY3VyaXR5IG1vZGVsIHRvIGZyZWUgcHRyOiAlZFxuIiwKCSAgICAgICBwZHUtPnNlY3VyaXR5TW9kZWwpOwogICAgfQogICAgcGR1LT5zZWN1cml0eVN0YXRlUmVmID0gTlVMTDsKICB9CgogIGlmICghaGFuZGxlZCkgewogICAgc25tcF9pbmNyZW1lbnRfc3RhdGlzdGljKFNUQVRfU05NUFVOS05PV05QRFVIQU5ETEVSUyk7CiAgICBERUJVR01TR1RMKCgic2Vzc19wcm9jZXNzX3BhY2tldCIsICJ1bmhhbmRsZWQgUERVXG4iKSk7CiAgfQoKICBzbm1wX2ZyZWVfcGR1KHBkdSk7CiAgcmV0dXJuIDA7Cn0KCi8qCiAqIENoZWNrcyB0byBzZWUgaWYgYW55IG9mIHRoZSBmZCdzIHNldCBpbiB0aGUgZmRzZXQgYmVsb25nIHRvCiAqIHNubXAuICBFYWNoIHNvY2tldCB3aXRoIGl0J3MgZmQgc2V0IGhhcyBhIHBhY2tldCByZWFkIGZyb20gaXQKICogYW5kIHNubXBfcGFyc2UgaXMgY2FsbGVkIG9uIHRoZSBwYWNrZXQgcmVjZWl2ZWQuICBUaGUgcmVzdWx0aW5nIHBkdQogKiBpcyBwYXNzZWQgdG8gdGhlIGNhbGxiYWNrIHJvdXRpbmUgZm9yIHRoYXQgc2Vzc2lvbi4gIElmIHRoZSBjYWxsYmFjawogKiByb3V0aW5lIHJldHVybnMgc3VjY2Vzc2Z1bGx5LCB0aGUgcGR1IGFuZCBpdCdzIHJlcXVlc3QgYXJlIGRlbGV0ZWQuCiAqLwp2b2lkCnNubXBfcmVhZChmZF9zZXQgKiBmZHNldCkKewogICAgbmV0c25tcF9sYXJnZV9mZF9zZXQgbGZkc2V0OwoKICAgIG5ldHNubXBfbGFyZ2VfZmRfc2V0X2luaXQoJmxmZHNldCwgRkRfU0VUU0laRSk7CiAgICBuZXRzbm1wX2NvcHlfZmRfc2V0X3RvX2xhcmdlX2ZkX3NldCgmbGZkc2V0LCBmZHNldCk7CiAgICBzbm1wX3JlYWQyKCZsZmRzZXQpOwogICAgbmV0c25tcF9sYXJnZV9mZF9zZXRfY2xlYW51cCgmbGZkc2V0KTsKfQoKdm9pZApzbm1wX3JlYWQyKG5ldHNubXBfbGFyZ2VfZmRfc2V0ICogZmRzZXQpCnsKICAgIHN0cnVjdCBzZXNzaW9uX2xpc3QgKnNscDsKICAgIHNubXBfcmVzX2xvY2soTVRfTElCUkFSWV9JRCwgTVRfTElCX1NFU1NJT04pOwogICAgZm9yIChzbHAgPSBTZXNzaW9uczsgc2xwOyBzbHAgPSBzbHAtPm5leHQpIHsKICAgICAgICBzbm1wX3Nlc3NfcmVhZDIoKHZvaWQgKikgc2xwLCBmZHNldCk7CiAgICB9CiAgICBzbm1wX3Jlc191bmxvY2soTVRfTElCUkFSWV9JRCwgTVRfTElCX1NFU1NJT04pOwp9CgovKgogKiBTYW1lIGFzIHNubXBfcmVhZCwgYnV0IHdvcmtzIGp1c3Qgb25lIHNlc3Npb24uIAogKiByZXR1cm5zIDAgaWYgc3VjY2VzcywgLTEgaWYgZmFpbCAKICogTVRSOiBjYW4ndCBsb2NrIGhlcmUgYW5kIGF0IHNubXBfcmVhZCAKICogQmV3YXJlIHJlY3Vyc2l2ZSBzZW5kIG1heWJlIGluc2lkZSBzbm1wX3JlYWQgY2FsbGJhY2sgZnVuY3Rpb24uIAogKi8KaW50Cl9zZXNzX3JlYWQodm9pZCAqc2Vzc3AsIG5ldHNubXBfbGFyZ2VfZmRfc2V0ICogZmRzZXQpCnsKICAgIHN0cnVjdCBzZXNzaW9uX2xpc3QgKnNscCA9IChzdHJ1Y3Qgc2Vzc2lvbl9saXN0ICopIHNlc3NwOwogICAgbmV0c25tcF9zZXNzaW9uICpzcCA9IHNscCA/IHNscC0+c2Vzc2lvbiA6IE5VTEw7CiAgICBzdHJ1Y3Qgc25tcF9pbnRlcm5hbF9zZXNzaW9uICppc3AgPSBzbHAgPyBzbHAtPmludGVybmFsIDogTlVMTDsKICAgIG5ldHNubXBfdHJhbnNwb3J0ICp0cmFuc3BvcnQgPSBzbHAgPyBzbHAtPnRyYW5zcG9ydCA6IE5VTEw7CiAgICBzaXplX3QgICAgICAgICAgcGR1bGVuID0gMCwgcnhidWZfbGVuID0gNjU1MzY7CiAgICB1X2NoYXIgICAgICAgICAqcnhidWYgPSBOVUxMOwogICAgaW50ICAgICAgICAgICAgIGxlbmd0aCA9IDAsIG9sZW5ndGggPSAwLCByYyA9IDA7CiAgICB2b2lkICAgICAgICAgICAqb3BhcXVlID0gTlVMTDsKCiAgICBpZiAoIXNwIHx8ICFpc3AgfHwgIXRyYW5zcG9ydCkgewogICAgICAgIERFQlVHTVNHVEwoKCJzZXNzX3JlYWQiLCAicmVhZCBmYWlsOiBjbG9zaW5nLi4uXG4iKSk7CiAgICAgICAgcmV0dXJuIDA7CiAgICB9CgogICAgLyogdG8gYXZvaWQgc3ViYWdlbnQgY3Jhc2ggKi8gCiAgICBpZiAodHJhbnNwb3J0LT5zb2NrIDwgMCkgeyAKICAgICAgICBzbm1wX2xvZyAoTE9HX0lORk8sICJ0cmFuc3BvcnQtPnNvY2sgZ290IG5lZ2F0aXZlIGZkIHZhbHVlICVkXG4iLCB0cmFuc3BvcnQtPnNvY2spOwogICAgICAgIHJldHVybiAwOyAKICAgIH0KCiAgICBpZiAoIWZkc2V0IHx8ICEoTkVUU05NUF9MQVJHRV9GRF9JU1NFVCh0cmFuc3BvcnQtPnNvY2ssIGZkc2V0KSkpIHsKICAgICAgICBERUJVR01TR1RMKCgic2Vzc19yZWFkIiwgIm5vdCByZWFkaW5nICVkIChmZHNldCAlcCBzZXQgJWQpXG4iLAogICAgICAgICAgICAgICAgICAgIHRyYW5zcG9ydC0+c29jaywgZmRzZXQsCiAgICAgICAgICAgICAgICAgICAgZmRzZXQgPyBORVRTTk1QX0xBUkdFX0ZEX0lTU0VUKHRyYW5zcG9ydC0+c29jaywgZmRzZXQpCgkJICAgIDogLTkpKTsKICAgICAgICByZXR1cm4gMDsKICAgIH0KCiAgICBzcC0+c19zbm1wX2Vycm5vID0gMDsKICAgIHNwLT5zX2Vycm5vID0gMDsKCiAgICBpZiAodHJhbnNwb3J0LT5mbGFncyAmIE5FVFNOTVBfVFJBTlNQT1JUX0ZMQUdfTElTVEVOKSB7CiAgICAgICAgaW50ICAgICAgICAgICAgIGRhdGFfc29jayA9IHRyYW5zcG9ydC0+Zl9hY2NlcHQodHJhbnNwb3J0KTsKCiAgICAgICAgaWYgKGRhdGFfc29jayA+PSAwKSB7CiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIFdlJ3ZlIHN1Y2Nlc3NmdWxseSBhY2NlcHRlZCBhIG5ldyBzdHJlYW0tYmFzZWQgY29ubmVjdGlvbi4KICAgICAgICAgICAgICogSXQncyBub3QgdG9vIGNsZWFyIHdoYXQgc2hvdWxkIGhhcHBlbiBoZXJlIGlmIHdlIGFyZSB1c2luZyB0aGUKICAgICAgICAgICAgICogc2luZ2xlLXNlc3Npb24gQVBJIGF0IHRoaXMgcG9pbnQuICBCYXNpY2FsbHkgYSAic2Vzc2lvbgogICAgICAgICAgICAgKiBhY2NlcHRlZCIgY2FsbGJhY2sgaXMgcHJvYmFibHkgbmVlZGVkIHRvIGhhbmQgdGhlIG5ldyBzZXNzaW9uCiAgICAgICAgICAgICAqIG92ZXIgdG8gdGhlIGFwcGxpY2F0aW9uLgogICAgICAgICAgICAgKiAKICAgICAgICAgICAgICogSG93ZXZlciwgZm9yIG5vdywgYXMgaW4gdGhlIG9yaWdpbmFsIHNubXBfYXBpLCB3ZSB3aWxsIEFTU1VNRQogICAgICAgICAgICAgKiB0aGF0IHdlJ3JlIHVzaW5nIHRoZSB0cmFkaXRpb25hbCBBUEksIGFuZCBzaW1wbHkgYWRkIHRoZSBuZXcKICAgICAgICAgICAgICogc2Vzc2lvbiB0byB0aGUgbGlzdC4gIE5vdGUgd2UgZG9uJ3QgaGF2ZSB0byBnZXQgdGhlIFNlc3Npb24KICAgICAgICAgICAgICogbGlzdCBsb2NrIGhlcmUsIGJlY2F1c2UgdW5kZXIgdGhhdCBhc3N1bXB0aW9uIHdlIGFscmVhZHkgaG9sZAogICAgICAgICAgICAgKiBpdCAodGhpcyBpcyBhbHNvIHdoeSB3ZSBkb24ndCBqdXN0IHVzZSBzbm1wX2FkZCkuCiAgICAgICAgICAgICAqIAogICAgICAgICAgICAgKiBUaGUgbW9yYWwgb2YgdGhlIHN0b3J5IGlzOiBkb24ndCB1c2UgbGlzdGVuaW5nIHN0cmVhbS1iYXNlZAogICAgICAgICAgICAgKiB0cmFuc3BvcnRzIGluIGEgbXVsdGktdGhyZWFkZWQgZW52aXJvbm1lbnQgYmVjYXVzZSBzb21ldGhpbmcKICAgICAgICAgICAgICogd2lsbCBnbyBIT1JSSUJMWSB3cm9uZyAoYW5kIGFsc28gdGhhdCBTTk1QL1RDUCBpcyBub3QgdHJpdmlhbCkuCiAgICAgICAgICAgICAqIAogICAgICAgICAgICAgKiBBbm90aGVyIG9wZW4gaXNzdWU6IHdoYXQgc2hvdWxkIGhhcHBlbiB0byBzb2NrZXRzIHRoYXQgaGF2ZQogICAgICAgICAgICAgKiBiZWVuIGFjY2VwdCgpZWQgZnJvbSBhIGxpc3RlbmluZyBzb2NrZXQgd2hlbiB0aGF0IG9yaWdpbmFsCiAgICAgICAgICAgICAqIHNvY2tldCBpcyBjbG9zZWQ/ICBJZiB0aGV5IGFyZSBsZWZ0IG9wZW4sIHRoZW4gYXR0ZW1wdGluZyB0bwogICAgICAgICAgICAgKiByZS1vcGVuIHRoZSBsaXN0ZW5pbmcgc29ja2V0IHdpbGwgZmFpbCwgd2hpY2ggaXMgc2VtYW50aWNhbGx5CiAgICAgICAgICAgICAqIGNvbmZ1c2luZy4gIFBlcmhhcHMgdGhlcmUgc2hvdWxkIGJlIHNvbWUga2luZCBvZiBjaGFpbmluZyBpbgogICAgICAgICAgICAgKiB0aGUgdHJhbnNwb3J0IHN0cnVjdHVyZSBzbyB0aGF0IHRoZXkgY2FuIGFsbCBiZSBjbG9zZWQuCiAgICAgICAgICAgICAqIERpc2N1c3MuICA7LSkKICAgICAgICAgICAgICovCgoJICAgIG5ldHNubXBfdHJhbnNwb3J0ICpuZXdfdHJhbnNwb3J0PW5ldHNubXBfdHJhbnNwb3J0X2NvcHkodHJhbnNwb3J0KTsKICAgICAgICAgICAgaWYgKG5ld190cmFuc3BvcnQgIT0gTlVMTCkgewogICAgICAgICAgICAgICAgc3RydWN0IHNlc3Npb25fbGlzdCAqbnNscCA9IE5VTEw7CgogICAgICAgICAgICAgICAgbmV3X3RyYW5zcG9ydC0+c29jayA9IGRhdGFfc29jazsKICAgICAgICAgICAgICAgIG5ld190cmFuc3BvcnQtPmZsYWdzICY9IH5ORVRTTk1QX1RSQU5TUE9SVF9GTEFHX0xJU1RFTjsKCiAgICAgICAgICAgICAgICBuc2xwID0gKHN0cnVjdCBzZXNzaW9uX2xpc3QgKilzbm1wX3Nlc3NfYWRkX2V4KHNwLAoJCQkgIG5ld190cmFuc3BvcnQsIGlzcC0+aG9va19wcmUsIGlzcC0+aG9va19wYXJzZSwKCQkJICBpc3AtPmhvb2tfcG9zdCwgaXNwLT5ob29rX2J1aWxkLAoJCQkgIGlzcC0+aG9va19yZWFsbG9jX2J1aWxkLCBpc3AtPmNoZWNrX3BhY2tldCwKCQkJICBpc3AtPmhvb2tfY3JlYXRlX3BkdSk7CgogICAgICAgICAgICAgICAgaWYgKG5zbHAgIT0gTlVMTCkgewogICAgICAgICAgICAgICAgICAgIG5zbHAtPm5leHQgPSBTZXNzaW9uczsKICAgICAgICAgICAgICAgICAgICBTZXNzaW9ucyA9IG5zbHA7CiAgICAgICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAgICAgKiBUZWxsIHRoZSBuZXcgc2Vzc2lvbiBhYm91dCBpdHMgZXhpc3RhbmNlIGlmIHBvc3NpYmxlLgogICAgICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgICAgIERFQlVHTVNHVEwoKCJzZXNzX3JlYWQiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJwZXJmb3JtIGNhbGxiYWNrIHdpdGggb3A9Q09OTkVDVFxuIikpOwogICAgICAgICAgICAgICAgICAgICh2b2lkKW5zbHAtPnNlc3Npb24tPmNhbGxiYWNrKE5FVFNOTVBfQ0FMTEJBQ0tfT1BfQ09OTkVDVCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuc2xwLT5zZXNzaW9uLCAwLCBOVUxMLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNwLT5jYWxsYmFja19tYWdpYyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHNwLT5zX3NubXBfZXJybm8gPSBTTk1QRVJSX01BTExPQzsKICAgICAgICAgICAgICAgIHNwLT5zX2Vycm5vID0gZXJybm87CiAgICAgICAgICAgICAgICBzbm1wX3NldF9kZXRhaWwoc3RyZXJyb3IoZXJybm8pKTsKICAgICAgICAgICAgICAgIHJldHVybiAtMTsKICAgICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHNwLT5zX3NubXBfZXJybm8gPSBTTk1QRVJSX0JBRF9SRUNWRlJPTTsKICAgICAgICAgICAgc3AtPnNfZXJybm8gPSBlcnJubzsKICAgICAgICAgICAgc25tcF9zZXRfZGV0YWlsKHN0cmVycm9yKGVycm5vKSk7CiAgICAgICAgICAgIHJldHVybiAtMTsKICAgICAgICB9CiAgICB9CgogICAgLyoKICAgICAqIFdvcmsgb3V0IHdoZXJlIHRvIHJlY2VpdmUgdGhlIGRhdGEgdG8uICAKICAgICAqLwoKICAgIGlmICh0cmFuc3BvcnQtPmZsYWdzICYgTkVUU05NUF9UUkFOU1BPUlRfRkxBR19TVFJFQU0pIHsKICAgICAgICBpZiAoaXNwLT5wYWNrZXQgPT0gTlVMTCkgewogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBXZSBoYXZlIG5vIHNhdmVkIHBhY2tldC4gIEFsbG9jYXRlIG9uZS4gIAogICAgICAgICAgICAgKi8KICAgICAgICAgICAgaWYgKChpc3AtPnBhY2tldCA9ICh1X2NoYXIgKikgbWFsbG9jKHJ4YnVmX2xlbikpID09IE5VTEwpIHsKICAgICAgICAgICAgICAgIERFQlVHTVNHVEwoKCJzZXNzX3JlYWQiLCAiY2FuJ3QgbWFsbG9jICUiIE5FVFNOTVBfUFJJegogICAgICAgICAgICAgICAgICAgICAgICAgICAgInUgYnl0ZXMgZm9yIHJ4YnVmXG4iLCByeGJ1Zl9sZW4pKTsKICAgICAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgcnhidWYgPSBpc3AtPnBhY2tldDsKICAgICAgICAgICAgICAgIGlzcC0+cGFja2V0X3NpemUgPSByeGJ1Zl9sZW47CiAgICAgICAgICAgICAgICBpc3AtPnBhY2tldF9sZW4gPSAwOwogICAgICAgICAgICB9CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogV2UgaGF2ZSBzYXZlZCBhIHBhcnRpYWwgcGFja2V0IGZyb20gbGFzdCB0aW1lLiAgRXh0ZW5kIHRoYXQsIGlmCiAgICAgICAgICAgICAqIG5lY2Vzc2FyeSwgYW5kIHJlY2VpdmUgbmV3IGRhdGEgYWZ0ZXIgdGhlIG9sZCBkYXRhLiAgCiAgICAgICAgICAgICAqLwogICAgICAgICAgICB1X2NoYXIgICAgICAgICAqbmV3YnVmOwoKICAgICAgICAgICAgaWYgKGlzcC0+cGFja2V0X3NpemUgPCBpc3AtPnBhY2tldF9sZW4gKyByeGJ1Zl9sZW4pIHsKICAgICAgICAgICAgICAgIG5ld2J1ZiA9CiAgICAgICAgICAgICAgICAgICAgKHVfY2hhciAqKSByZWFsbG9jKGlzcC0+cGFja2V0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpc3AtPnBhY2tldF9sZW4gKyByeGJ1Zl9sZW4pOwogICAgICAgICAgICAgICAgaWYgKG5ld2J1ZiA9PSBOVUxMKSB7CiAgICAgICAgICAgICAgICAgICAgREVCVUdNU0dUTCgoInNlc3NfcmVhZCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgImNhbid0IG1hbGxvYyAlIiBORVRTTk1QX1BSSXoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAidSBtb3JlIGZvciByeGJ1ZiAoJSIgTkVUU05NUF9QUkl6ICJ1IHRvdClcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcnhidWZfbGVuLCBpc3AtPnBhY2tldF9sZW4gKyByeGJ1Zl9sZW4pKTsKICAgICAgICAgICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgaXNwLT5wYWNrZXQgPSBuZXdidWY7CiAgICAgICAgICAgICAgICAgICAgaXNwLT5wYWNrZXRfc2l6ZSA9IGlzcC0+cGFja2V0X2xlbiArIHJ4YnVmX2xlbjsKICAgICAgICAgICAgICAgICAgICByeGJ1ZiA9IGlzcC0+cGFja2V0ICsgaXNwLT5wYWNrZXRfbGVuOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgcnhidWYgPSBpc3AtPnBhY2tldCArIGlzcC0+cGFja2V0X2xlbjsKICAgICAgICAgICAgICAgIHJ4YnVmX2xlbiA9IGlzcC0+cGFja2V0X3NpemUgLSBpc3AtPnBhY2tldF9sZW47CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9IGVsc2UgewogICAgICAgIGlmICgocnhidWYgPSAodV9jaGFyICopIG1hbGxvYyhyeGJ1Zl9sZW4pKSA9PSBOVUxMKSB7CiAgICAgICAgICAgIERFQlVHTVNHVEwoKCJzZXNzX3JlYWQiLCAiY2FuJ3QgbWFsbG9jICUiIE5FVFNOTVBfUFJJegogICAgICAgICAgICAgICAgICAgICAgICAidSBieXRlcyBmb3IgcnhidWZcbiIsIHJ4YnVmX2xlbikpOwogICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICB9CiAgICB9CgogICAgbGVuZ3RoID0gbmV0c25tcF90cmFuc3BvcnRfcmVjdih0cmFuc3BvcnQsIHJ4YnVmLCByeGJ1Zl9sZW4sICZvcGFxdWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZvbGVuZ3RoKTsKCiAgICBpZiAobGVuZ3RoID09IC0xICYmICEodHJhbnNwb3J0LT5mbGFncyAmIE5FVFNOTVBfVFJBTlNQT1JUX0ZMQUdfU1RSRUFNKSkgewogICAgICAgIHNwLT5zX3NubXBfZXJybm8gPSBTTk1QRVJSX0JBRF9SRUNWRlJPTTsKICAgICAgICBzcC0+c19lcnJubyA9IGVycm5vOwogICAgICAgIHNubXBfc2V0X2RldGFpbChzdHJlcnJvcihlcnJubykpOwogICAgICAgIFNOTVBfRlJFRShyeGJ1Zik7CiAgICAgICAgaWYgKG9wYXF1ZSAhPSBOVUxMKSB7CiAgICAgICAgICAgIFNOTVBfRlJFRShvcGFxdWUpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gLTE7CiAgICB9CgogICAgaWYgKDAgPT0gbGVuZ3RoICYmIHRyYW5zcG9ydC0+ZmxhZ3MgJiBORVRTTk1QX1RSQU5TUE9SVF9GTEFHX0VNUFRZX1BLVCkgewogICAgICAgIC8qIHRoaXMgYWxsb3dzIGZvciBhIHRyYW5zcG9ydCB0aGF0IG5lZWRzIHRvIHJldHVybiBmcm9tCiAgICAgICAgICogcGFja2V0IHByb2Nlc3NpbmcgdGhhdCBkb2Vzbid0IG5lY2Vzc2FyaWx5IGhhdmUgYW55CiAgICAgICAgICogY29uc3VtYWJsZSBkYXRhIGluIGl0LiAqLwoKICAgICAgICAvKiByZXNldCB0aGUgZmxhZyBzaW5jZSBpdCdzIGEgcGVyLW1lc3NhZ2UgZmxhZyAqLwogICAgICAgIHRyYW5zcG9ydC0+ZmxhZ3MgJj0gKH5ORVRTTk1QX1RSQU5TUE9SVF9GTEFHX0VNUFRZX1BLVCk7CgogICAgICAgIHJldHVybiAwOwogICAgfQoKICAgIC8qCiAgICAgKiBSZW1vdGUgZW5kIGNsb3NlZCBjb25uZWN0aW9uLiAgCiAgICAgKi8KCiAgICBpZiAobGVuZ3RoIDw9IDAgJiYgdHJhbnNwb3J0LT5mbGFncyAmIE5FVFNOTVBfVFJBTlNQT1JUX0ZMQUdfU1RSRUFNKSB7CiAgICAgICAgLyoKICAgICAgICAgKiBBbGVydCB0aGUgYXBwbGljYXRpb24gaWYgcG9zc2libGUuICAKICAgICAgICAgKi8KICAgICAgICBpZiAoc3AtPmNhbGxiYWNrICE9IE5VTEwpIHsKICAgICAgICAgICAgREVCVUdNU0dUTCgoInNlc3NfcmVhZCIsICJwZXJmb3JtIGNhbGxiYWNrIHdpdGggb3A9RElTQ09OTkVDVFxuIikpOwogICAgICAgICAgICAodm9pZCkgc3AtPmNhbGxiYWNrKE5FVFNOTVBfQ0FMTEJBQ0tfT1BfRElTQ09OTkVDVCwgc3AsIDAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCwgc3AtPmNhbGxiYWNrX21hZ2ljKTsKICAgICAgICB9CiAgICAgICAgLyoKICAgICAgICAgKiBDbG9zZSBzb2NrZXQgYW5kIG1hcmsgc2Vzc2lvbiBmb3IgZGVsZXRpb24uICAKICAgICAgICAgKi8KICAgICAgICBERUJVR01TR1RMKCgic2Vzc19yZWFkIiwgImZkICVkIGNsb3NlZFxuIiwgdHJhbnNwb3J0LT5zb2NrKSk7CiAgICAgICAgdHJhbnNwb3J0LT5mX2Nsb3NlKHRyYW5zcG9ydCk7CiAgICAgICAgU05NUF9GUkVFKGlzcC0+cGFja2V0KTsKICAgICAgICBpZiAob3BhcXVlICE9IE5VTEwpIHsKICAgICAgICAgICAgU05NUF9GUkVFKG9wYXF1ZSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiAtMTsKICAgIH0KCiAgICBpZiAodHJhbnNwb3J0LT5mbGFncyAmIE5FVFNOTVBfVFJBTlNQT1JUX0ZMQUdfU1RSRUFNKSB7CiAgICAgICAgdV9jaGFyICpwcHRyID0gaXNwLT5wYWNrZXQ7Cgl2b2lkICpvY29weSA9IE5VTEw7CgogICAgICAgIGlzcC0+cGFja2V0X2xlbiArPSBsZW5ndGg7CgogICAgICAgIHdoaWxlIChpc3AtPnBhY2tldF9sZW4gPiAwKSB7CgogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBHZXQgdGhlIHRvdGFsIGRhdGEgbGVuZ3RoIHdlJ3JlIGV4cGVjdGluZyAoYW5kIG5lZWQgdG8gd2FpdAogICAgICAgICAgICAgKiBmb3IpLgogICAgICAgICAgICAgKi8KICAgICAgICAgICAgaWYgKGlzcC0+Y2hlY2tfcGFja2V0KSB7CiAgICAgICAgICAgICAgICBwZHVsZW4gPSBpc3AtPmNoZWNrX3BhY2tldChwcHRyLCBpc3AtPnBhY2tldF9sZW4pOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgcGR1bGVuID0gYXNuX2NoZWNrX3BhY2tldChwcHRyLCBpc3AtPnBhY2tldF9sZW4pOwogICAgICAgICAgICB9CgogICAgICAgICAgICBERUJVR01TR1RMKCgic2Vzc19yZWFkIiwKICAgICAgICAgICAgICAgICAgICAgICAgIiAgbG9vcCBwYWNrZXRfbGVuICUiIE5FVFNOTVBfUFJJeiAidSwgUERVIGxlbmd0aCAlIgogICAgICAgICAgICAgICAgICAgICAgICBORVRTTk1QX1BSSXogInVcbiIsIGlzcC0+cGFja2V0X2xlbiwgcGR1bGVuKSk7CgogICAgICAgICAgICBpZiAocGR1bGVuID4gTUFYX1BBQ0tFVF9MRU5HVEgpIHsKICAgICAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAgICAgKiBJbGxlZ2FsIGxlbmd0aCwgZHJvcCB0aGUgY29ubmVjdGlvbi4gIAogICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICBzbm1wX2xvZyhMT0dfRVJSLCAKCQkJICJSZWNlaXZlZCBicm9rZW4gcGFja2V0LiBDbG9zaW5nIHNlc3Npb24uXG4iKTsKCQlpZiAoc3AtPmNhbGxiYWNrICE9IE5VTEwpIHsKCQkgIERFQlVHTVNHVEwoKCJzZXNzX3JlYWQiLAoJCQkgICAgICAicGVyZm9ybSBjYWxsYmFjayB3aXRoIG9wPURJU0NPTk5FQ1RcbiIpKTsKCQkgICh2b2lkKXNwLT5jYWxsYmFjayhORVRTTk1QX0NBTExCQUNLX09QX0RJU0NPTk5FQ1QsCgkJCQkgICAgIHNwLCAwLCBOVUxMLCBzcC0+Y2FsbGJhY2tfbWFnaWMpOwoJCX0KCQlERUJVR01TR1RMKCgic2Vzc19yZWFkIiwgImZkICVkIGNsb3NlZFxuIiwgdHJhbnNwb3J0LT5zb2NrKSk7CiAgICAgICAgICAgICAgICB0cmFuc3BvcnQtPmZfY2xvc2UodHJhbnNwb3J0KTsKICAgICAgICAgICAgICAgIGlmIChvcGFxdWUgIT0gTlVMTCkgewogICAgICAgICAgICAgICAgICAgIFNOTVBfRlJFRShvcGFxdWUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgLyoqIFhYWC1ya3M6IHdoeSBubyBTTk1QX0ZSRUUoaXNwLT5wYWNrZXQpOyA/PyAqLwogICAgICAgICAgICAgICAgcmV0dXJuIC0xOwogICAgICAgICAgICB9CgogICAgICAgICAgICBpZiAocGR1bGVuID4gaXNwLT5wYWNrZXRfbGVuIHx8IHBkdWxlbiA9PSAwKSB7CiAgICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAgICogV2UgZG9uJ3QgaGF2ZSBhIGNvbXBsZXRlIHBhY2tldCB5ZXQuICBJZiB3ZSd2ZSBhbHJlYWR5CiAgICAgICAgICAgICAgICAgKiBwcm9jZXNzZWQgYSBwYWNrZXQsIGJyZWFrIG91dCBzbyB3ZSdsbCBzaGlmdCB0aGlzIHBhY2tldAogICAgICAgICAgICAgICAgICogdG8gdGhlIHN0YXJ0IG9mIHRoZSBidWZmZXIuIElmIHdlJ3JlIGFscmVhZHkgYXQgdGhlCiAgICAgICAgICAgICAgICAgKiBzdGFydCwgc2ltcGx5IHJldHVybiBhbmQgd2FpdCBmb3IgbW9yZSBkYXRhIHRvIGFycml2ZS4KICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgREVCVUdNU0dUTCgoInNlc3NfcmVhZCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAicGt0IG5vdCBjb21wbGV0ZSAobmVlZCAlIiBORVRTTk1QX1BSSXogInUgZ290ICUiCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBORVRTTk1QX1BSSXogInUgc28gZmFyKVxuIiwgcGR1bGVuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgaXNwLT5wYWNrZXRfbGVuKSk7CgogICAgICAgICAgICAgICAgaWYgKHBwdHIgIT0gaXNwLT5wYWNrZXQpCiAgICAgICAgICAgICAgICAgICAgYnJlYWs7IC8qIG9wYXF1ZSBmcmVlZCBmb3IgdXMgb3V0c2lkZSBvZiBsb29wLiAqLwoKICAgICAgICAgICAgICAgIGlmIChvcGFxdWUgIT0gTlVMTCkgewogICAgICAgICAgICAgICAgICAgIFNOTVBfRlJFRShvcGFxdWUpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8qICBXZSBoYXZlICphdCBsZWFzdCogb25lIGNvbXBsZXRlIHBhY2tldCBpbiB0aGUgYnVmZmVyIG5vdy4gIElmCgkJd2UgaGF2ZSBwb3NzaWJseSBtb3JlIHRoYW4gb25lIHBhY2tldCwgd2UgbXVzdCBjb3B5IHRoZSBvcGFxdWUKCQlwb2ludGVyIGJlY2F1c2Ugd2UgbWF5IG5lZWQgdG8gcmV1c2UgaXQgZm9yIGEgbGF0ZXIgcGFja2V0LiAgKi8KCgkgICAgaWYgKHBkdWxlbiA8IGlzcC0+cGFja2V0X2xlbikgewoJCWlmIChvbGVuZ3RoID4gMCAmJiBvcGFxdWUgIT0gTlVMTCkgewoJCSAgICBvY29weSA9IG1hbGxvYyhvbGVuZ3RoKTsKCQkgICAgaWYgKG9jb3B5ICE9IE5VTEwpIHsKCQkJbWVtY3B5KG9jb3B5LCBvcGFxdWUsIG9sZW5ndGgpOwoJCSAgICB9CgkJfQoJICAgIH0gZWxzZSBpZiAocGR1bGVuID09IGlzcC0+cGFja2V0X2xlbikgewoJCS8qICBDb21tb24gY2FzZSAtLSBleGFjdGx5IG9uZSBwYWNrZXQuICBObyBuZWVkIHRvIGNvcHkgdGhlCgkJICAgIG9wYXF1ZSBwb2ludGVyLiAgKi8KCQlvY29weSA9IG9wYXF1ZTsKCQlvcGFxdWUgPSBOVUxMOwoJICAgIH0KCiAgICAgICAgICAgIGlmICgocmMgPSBfc2Vzc19wcm9jZXNzX3BhY2tldChzZXNzcCwgc3AsIGlzcCwgdHJhbnNwb3J0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2NvcHksIG9jb3B5P29sZW5ndGg6MCwgcHB0ciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBkdWxlbikpKSB7CiAgICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAgICogU29tZXRoaW5nIHdlbnQgd3Jvbmcgd2hpbGUgcHJvY2Vzc2luZyB0aGlzIHBhY2tldCAtLSBzZXQgdGhlCiAgICAgICAgICAgICAgICAgKiBlcnJuby4gIAogICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICBpZiAoc3AtPnNfc25tcF9lcnJubyAhPSAwKSB7CiAgICAgICAgICAgICAgICAgICAgU0VUX1NOTVBfRVJST1Ioc3AtPnNfc25tcF9lcnJubyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KCgkgICAgLyogIG9jb3B5IGhhcyBiZWVuIGZyZWUoKWQgYnkgX3Nlc3NfcHJvY2Vzc19wYWNrZXQgYnkgdGhpcyBwb2ludCwKCQlzbyBzZXQgaXQgdG8gTlVMTC4gICovCgoJICAgIG9jb3B5ID0gTlVMTDsKCgkgICAgLyogIFN0ZXAgcGFzdCB0aGUgcGFja2V0IHdlJ3ZlIGp1c3QgZGVhbHQgd2l0aC4gICovCgogICAgICAgICAgICBwcHRyICs9IHBkdWxlbjsKICAgICAgICAgICAgaXNwLT5wYWNrZXRfbGVuIC09IHBkdWxlbjsKICAgICAgICB9CgoJLyogIElmIHdlIGhhZCBtb3JlIHRoYW4gb25lIHBhY2tldCwgdGhlbiB3ZSB3ZXJlIHdvcmtpbmcgd2l0aCBjb3BpZXMKCSAgICBvZiB0aGUgb3BhcXVlIHBvaW50ZXIsIHNvIHdlIHN0aWxsIG5lZWQgdG8gZnJlZSgpIHRoZSBvcGFxdWUKCSAgICBwb2ludGVyIGl0c2VsZi4gICovCgoJaWYgKG9wYXF1ZSAhPSBOVUxMKSB7CgkgICAgU05NUF9GUkVFKG9wYXF1ZSk7Cgl9CgogICAgICAgIGlmIChpc3AtPnBhY2tldF9sZW4gPj0gTUFYSU1VTV9QQUNLRVRfU0laRSkgewogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBPYnZpb3VzbHkgdGhpcyBzaG91bGQgbmV2ZXIgaGFwcGVuISAgCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBzbm1wX2xvZyhMT0dfRVJSLAogICAgICAgICAgICAgICAgICAgICAidG9vIGxhcmdlIHBhY2tldF9sZW4gPSAlIiBORVRTTk1QX1BSSXoKICAgICAgICAgICAgICAgICAgICAgInUsIGRyb3BwaW5nIGNvbm5lY3Rpb24gJWRcbiIsCiAgICAgICAgICAgICAgICAgICAgIGlzcC0+cGFja2V0X2xlbiwgdHJhbnNwb3J0LT5zb2NrKTsKICAgICAgICAgICAgdHJhbnNwb3J0LT5mX2Nsb3NlKHRyYW5zcG9ydCk7CiAgICAgICAgICAgIC8qKiBYWFgtcmtzOiB3aHkgbm8gU05NUF9GUkVFKGlzcC0+cGFja2V0KTsgPz8gKi8KICAgICAgICAgICAgcmV0dXJuIC0xOwogICAgICAgIH0gZWxzZSBpZiAoaXNwLT5wYWNrZXRfbGVuID09IDApIHsKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogVGhpcyBpcyBnb29kOiBpdCBtZWFucyB0aGUgcGFja2V0IGJ1ZmZlciBjb250YWluZWQgYW4gaW50ZWdyYWwKICAgICAgICAgICAgICogbnVtYmVyIG9mIFBEVXMsIHNvIHdlIGRvbid0IGhhdmUgdG8gc2F2ZSBhbnkgZGF0YSBmb3IgbmV4dAogICAgICAgICAgICAgKiB0aW1lLiAgV2UgY2FuIGZyZWUoKSB0aGUgYnVmZmVyIG5vdyB0byBrZWVwIHRoZSBtZW1vcnkKICAgICAgICAgICAgICogZm9vdHByaW50IGRvd24uCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBTTk1QX0ZSRUUoaXNwLT5wYWNrZXQpOwogICAgICAgICAgICBpc3AtPnBhY2tldCA9IE5VTEw7CiAgICAgICAgICAgIGlzcC0+cGFja2V0X3NpemUgPSAwOwogICAgICAgICAgICBpc3AtPnBhY2tldF9sZW4gPSAwOwogICAgICAgICAgICByZXR1cm4gcmM7CiAgICAgICAgfQoKICAgICAgICAvKgogICAgICAgICAqIElmIHdlIGdldCBoZXJlLCB0aGVuIHRoZXJlIGlzIGEgcGFydGlhbCBwYWNrZXQgb2YgbGVuZ3RoCiAgICAgICAgICogaXNwLT5wYWNrZXRfbGVuIGJ5dGVzIHN0YXJ0aW5nIGF0IHBwdHIgbGVmdCBvdmVyLiAgTW92ZSB0aGF0IHRvIHRoZQogICAgICAgICAqIHN0YXJ0IG9mIHRoZSBidWZmZXIsIGFuZCB0aGVuIHJlYWxsb2MoKSB0aGUgYnVmZmVyIGRvd24gdG8gc2l6ZSB0bwogICAgICAgICAqIHJlZHVjZSB0aGUgbWVtb3J5IGZvb3RwcmludC4gIAogICAgICAgICAqLwoKICAgICAgICBtZW1tb3ZlKGlzcC0+cGFja2V0LCBwcHRyLCBpc3AtPnBhY2tldF9sZW4pOwogICAgICAgIERFQlVHTVNHVEwoKCJzZXNzX3JlYWQiLAogICAgICAgICAgICAgICAgICAgICJlbmQ6IG1lbW1vdmUoJXAsICVwLCAlIiBORVRTTk1QX1BSSXogInUpOyByZWFsbG9jKCVwLCAlIgogICAgICAgICAgICAgICAgICAgIE5FVFNOTVBfUFJJeiAidSlcbiIsCiAgICAgICAgICAgICAgICAgICAgaXNwLT5wYWNrZXQsIHBwdHIsIGlzcC0+cGFja2V0X2xlbiwKCQkgICAgaXNwLT5wYWNrZXQsIGlzcC0+cGFja2V0X2xlbikpOwoKICAgICAgICBpZiAoKHJ4YnVmID0gKHVfY2hhciAqKXJlYWxsb2MoaXNwLT5wYWNrZXQsIGlzcC0+cGFja2V0X2xlbikpID09IE5VTEwpIHsKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogSSBkb24ndCBzZWUgd2h5IHRoaXMgc2hvdWxkIGV2ZXIgZmFpbCwgYnV0IGl0J3Mgbm90IGEgYmlnIGRlYWwuCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBERUJVR01TR1RMKCgic2Vzc19yZWFkIiwgInJlYWxsb2MoKSBmYWlsZWRcbiIpKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBERUJVR01TR1RMKCgic2Vzc19yZWFkIiwgInJlYWxsb2MoKSBva2F5LCBvbGQgYnVmZmVyICVwLCBuZXcgJXBcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgIGlzcC0+cGFja2V0LCByeGJ1ZikpOwogICAgICAgICAgICBpc3AtPnBhY2tldCA9IHJ4YnVmOwogICAgICAgICAgICBpc3AtPnBhY2tldF9zaXplID0gaXNwLT5wYWNrZXRfbGVuOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmM7CiAgICB9IGVsc2UgewogICAgICAgIHJjID0gX3Nlc3NfcHJvY2Vzc19wYWNrZXQoc2Vzc3AsIHNwLCBpc3AsIHRyYW5zcG9ydCwgb3BhcXVlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb2xlbmd0aCwgcnhidWYsIGxlbmd0aCk7CiAgICAgICAgU05NUF9GUkVFKHJ4YnVmKTsKICAgICAgICByZXR1cm4gcmM7CiAgICB9Cn0KCgoKLyoKICogcmV0dXJucyAwIGlmIHN1Y2Nlc3MsIC0xIGlmIGZhaWwgCiAqLwppbnQKc25tcF9zZXNzX3JlYWQodm9pZCAqc2Vzc3AsIGZkX3NldCAqIGZkc2V0KQp7CiAgaW50IHJjOwogIG5ldHNubXBfbGFyZ2VfZmRfc2V0IGxmZHNldDsKICAKICBuZXRzbm1wX2xhcmdlX2ZkX3NldF9pbml0KCZsZmRzZXQsIEZEX1NFVFNJWkUpOwogIG5ldHNubXBfY29weV9mZF9zZXRfdG9fbGFyZ2VfZmRfc2V0KCZsZmRzZXQsIGZkc2V0KTsKICByYyA9IHNubXBfc2Vzc19yZWFkMihzZXNzcCwgJmxmZHNldCk7CiAgbmV0c25tcF9sYXJnZV9mZF9zZXRfY2xlYW51cCgmbGZkc2V0KTsKICByZXR1cm4gcmM7Cn0KCmludApzbm1wX3Nlc3NfcmVhZDIodm9pZCAqc2Vzc3AsIG5ldHNubXBfbGFyZ2VfZmRfc2V0ICogZmRzZXQpCnsKICAgIHN0cnVjdCBzZXNzaW9uX2xpc3QgKnBzbDsKICAgIG5ldHNubXBfc2Vzc2lvbiAqcHNzOwogICAgaW50ICAgICAgICAgICAgIHJjOwoKICAgIHJjID0gX3Nlc3NfcmVhZChzZXNzcCwgZmRzZXQpOwogICAgcHNsID0gKHN0cnVjdCBzZXNzaW9uX2xpc3QgKikgc2Vzc3A7CiAgICBwc3MgPSBwc2wtPnNlc3Npb247CiAgICBpZiAocmMgJiYgcHNzLT5zX3NubXBfZXJybm8pIHsKICAgICAgICBTRVRfU05NUF9FUlJPUihwc3MtPnNfc25tcF9lcnJubyk7CiAgICB9CiAgICByZXR1cm4gcmM7Cn0KCgovKioKICogUmV0dXJucyBpbmZvIGFib3V0IHdoYXQgc25tcCByZXF1aXJlcyBmcm9tIGEgc2VsZWN0IHN0YXRlbWVudC4KICogbnVtZmRzIGlzIHRoZSBudW1iZXIgb2YgZmRzIGluIHRoZSBsaXN0IHRoYXQgYXJlIHNpZ25pZmljYW50LgogKiBBbGwgZmlsZSBkZXNjcmlwdG9ycyBvcGVuZWQgZm9yIFNOTVAgYXJlIE9SJ2QgaW50byB0aGUgZmRzZXQuCiAqIElmIGFjdGl2aXR5IG9jY3VycyBvbiBhbnkgb2YgdGhlc2UgZmlsZSBkZXNjcmlwdG9ycywgc25tcF9yZWFkCiAqIHNob3VsZCBiZSBjYWxsZWQgd2l0aCB0aGF0IGZpbGUgZGVzY3JpcHRvciBzZXQKICoKICogVGhlIHRpbWVvdXQgaXMgdGhlIGxhdGVzdCB0aW1lIHRoYXQgU05NUCBjYW4gd2FpdCBmb3IgYSB0aW1lb3V0LiAgVGhlCiAqIHNlbGVjdCBzaG91bGQgYmUgZG9uZSB3aXRoIHRoZSBtaW5pbXVtIHRpbWUgYmV0d2VlbiB0aW1lb3V0IGFuZCBhbnkgb3RoZXIKICogdGltZW91dHMgbmVjZXNzYXJ5LiAgVGhpcyBzaG91bGQgYmUgY2hlY2tlZCB1cG9uIGVhY2ggaW52b2NhdGlvbiBvZiBzZWxlY3QuCiAqIElmIGEgdGltZW91dCBpcyByZWNlaXZlZCwgc25tcF90aW1lb3V0IHNob3VsZCBiZSBjYWxsZWQgdG8gY2hlY2sgaWYgdGhlCiAqIHRpbWVvdXQgd2FzIGZvciBTTk1QLiAgKHNubXBfdGltZW91dCBpcyBpZGVtcG90ZW50KQogKgogKiBUaGUgdmFsdWUgb2YgYmxvY2sgaW5kaWNhdGVzIGhvdyB0aGUgdGltZW91dCB2YWx1ZSBpcyBpbnRlcnByZXRlZC4KICogSWYgYmxvY2sgaXMgdHJ1ZSBvbiBpbnB1dCwgdGhlIHRpbWVvdXQgdmFsdWUgd2lsbCBiZSB0cmVhdGVkIGFzIHVuZGVmaW5lZCwKICogYnV0IGl0IG11c3QgYmUgYXZhaWxhYmxlIGZvciBzZXR0aW5nIGluIHNubXBfc2VsZWN0X2luZm8uICBPbiByZXR1cm4sCiAqIGJsb2NrIGlzIHNldCB0byB0cnVlIGlmIHRoZSB2YWx1ZSByZXR1cm5lZCBmb3IgdGltZW91dCBpcyB1bmRlZmluZWQ7CiAqIHdoZW4gYmxvY2sgaXMgc2V0IHRvIGZhbHNlLCB0aW1lb3V0IG1heSBiZSB1c2VkIGFzIGEgcGFybWV0ZXIgdG8gJ3NlbGVjdCcuCiAqCiAqIHNubXBfc2VsZWN0X2luZm8gcmV0dXJucyB0aGUgbnVtYmVyIG9mIG9wZW4gc29ja2V0cy4gIChpLmUuIFRoZSBudW1iZXIgb2YKICogc2Vzc2lvbnMgb3BlbikKICoKICogQHNlZSBTZWUgYWxzbyBzbm1wX3Nlc3Nfc2VsZWN0X2luZm8yX2ZsYWdzKCkuCiAqLwppbnQKc25tcF9zZWxlY3RfaW5mbyhpbnQgKm51bWZkcywgZmRfc2V0ICpmZHNldCwgc3RydWN0IHRpbWV2YWwgKnRpbWVvdXQsCiAgICAgICAgICAgICAgICAgaW50ICpibG9jaykKewogICAgcmV0dXJuIHNubXBfc2Vzc19zZWxlY3RfaW5mbyhOVUxMLCBudW1mZHMsIGZkc2V0LCB0aW1lb3V0LCBibG9jayk7Cn0KCi8qKgogKiBAc2VlIFNlZSBhbHNvIHNubXBfc2Vzc19zZWxlY3RfaW5mbzJfZmxhZ3MoKS4KICovCmludApzbm1wX3NlbGVjdF9pbmZvMihpbnQgKm51bWZkcywgbmV0c25tcF9sYXJnZV9mZF9zZXQgKmZkc2V0LAoJCSAgc3RydWN0IHRpbWV2YWwgKnRpbWVvdXQsIGludCAqYmxvY2spCnsKICAgIHJldHVybiBzbm1wX3Nlc3Nfc2VsZWN0X2luZm8yKE5VTEwsIG51bWZkcywgZmRzZXQsIHRpbWVvdXQsIGJsb2NrKTsKfQoKLyoqCiAqIEBzZWUgU2VlIGFsc28gc25tcF9zZXNzX3NlbGVjdF9pbmZvMl9mbGFncygpLgogKi8KaW50CnNubXBfc2Vzc19zZWxlY3RfaW5mbyh2b2lkICpzZXNzcCwgaW50ICpudW1mZHMsIGZkX3NldCAqZmRzZXQsCiAgICAgICAgICAgICAgICAgICAgICBzdHJ1Y3QgdGltZXZhbCAqdGltZW91dCwgaW50ICpibG9jaykKewogICAgcmV0dXJuIHNubXBfc2Vzc19zZWxlY3RfaW5mb19mbGFncyhzZXNzcCwgbnVtZmRzLCBmZHNldCwgdGltZW91dCwgYmxvY2ssCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5FVFNOTVBfU0VMRUNUX05PRkxBR1MpOwp9CiAgICAgICAgCi8qKgogKiBAc2VlIFNlZSBhbHNvIHNubXBfc2Vzc19zZWxlY3RfaW5mbzJfZmxhZ3MoKS4KICovCmludApzbm1wX3Nlc3Nfc2VsZWN0X2luZm9fZmxhZ3Modm9pZCAqc2Vzc3AsIGludCAqbnVtZmRzLCBmZF9zZXQgKmZkc2V0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RydWN0IHRpbWV2YWwgKnRpbWVvdXQsIGludCAqYmxvY2ssIGludCBmbGFncykKewogIGludCByYzsKICBuZXRzbm1wX2xhcmdlX2ZkX3NldCBsZmRzZXQ7CgogIG5ldHNubXBfbGFyZ2VfZmRfc2V0X2luaXQoJmxmZHNldCwgRkRfU0VUU0laRSk7CiAgbmV0c25tcF9jb3B5X2ZkX3NldF90b19sYXJnZV9mZF9zZXQoJmxmZHNldCwgZmRzZXQpOwogIHJjID0gc25tcF9zZXNzX3NlbGVjdF9pbmZvMl9mbGFncyhzZXNzcCwgbnVtZmRzLCAmbGZkc2V0LCB0aW1lb3V0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBibG9jaywgZmxhZ3MpOwogIGlmIChuZXRzbm1wX2NvcHlfbGFyZ2VfZmRfc2V0X3RvX2ZkX3NldChmZHNldCwgJmxmZHNldCkgPCAwKSB7CiAgICAgIHNubXBfbG9nKExPR19FUlIsCgkgICAgICJVc2Ugc25tcF9zZXNzX3NlbGVjdF9pbmZvMigpIGZvciBwcm9jZXNzaW5nIgoJICAgICAiIGxhcmdlIGZpbGUgZGVzY3JpcHRvcnNcbiIpOwogIH0KICBuZXRzbm1wX2xhcmdlX2ZkX3NldF9jbGVhbnVwKCZsZmRzZXQpOwogIHJldHVybiByYzsKfQoKLyoqCiAqIEBzZWUgU2VlIGFsc28gc25tcF9zZXNzX3NlbGVjdF9pbmZvMl9mbGFncygpLgogKi8KaW50CnNubXBfc2Vzc19zZWxlY3RfaW5mbzIodm9pZCAqc2Vzc3AsIGludCAqbnVtZmRzLCBuZXRzbm1wX2xhcmdlX2ZkX3NldCAqZmRzZXQsCgkJICAgICAgIHN0cnVjdCB0aW1ldmFsICp0aW1lb3V0LCBpbnQgKmJsb2NrKQp7CiAgICByZXR1cm4gc25tcF9zZXNzX3NlbGVjdF9pbmZvMl9mbGFncyhzZXNzcCwgbnVtZmRzLCBmZHNldCwgdGltZW91dCwgYmxvY2ssCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBORVRTTk1QX1NFTEVDVF9OT0ZMQUdTKTsKfQoKLyoqCiAqIENvbXB1dGUvdXBkYXRlIHRoZSBhcmd1bWVudHMgdG8gYmUgcGFzc2VkIHRvIHNlbGVjdCgpLgogKgogKiBAcGFyYW1baW5dICAgICBzZXNzcCAgIFdoaWNoIHNlc3Npb25zIHRvIHByb2Nlc3M6IGVpdGhlciBhIHBvaW50ZXIgdG8gYQogKiAgIHNwZWNpZmljIHNlc3Npb24gb3IgTlVMTCB3aGljaCBtZWFucyB0byBwcm9jZXNzIGFsbCBzZXNzaW9ucy4KICogQHBhcmFtW2luLG91dF0gbnVtZmRzICBPbiBQT1NJWCBzeXN0ZW1zIG9uZSBtb3JlIHRoYW4gdGhlIHRoZSBsYXJnZXN0IGZpbGUKICogICBkZXNjcmlwdG9yIHRoYXQgaXMgcHJlc2VudCBpbiAqZmRzZXQuIE9uIHN5c3RlbXMgdGhhdCB1c2UgV2luc29jayAoTWluR1cKICogICBhbmQgTVNWQyksIGRvIG5vdCB1c2UgdGhlIHZhbHVlIHdyaXR0ZW4gaW50byAqbnVtZmRzLgogKiBAcGFyYW1baW4sb3V0XSBmZHNldCAgIEEgbGFyZ2UgZmlsZSBkZXNjcmlwdG9yIHNldCB0byB3aGljaCBhbGwgZmlsZQogKiAgIGRlc2NyaXB0b3JzIHdpbGwgYmUgYWRkZWQgdGhhdCBhcmUgYXNzb2NpYXRlZCB3aXRoIG9uZSBvZiB0aGUgZXhhbWluZWQKICogICBzZXNzaW9ucy4KICogQHBhcmFtW2luLG91dF0gdGltZW91dCBPbiBpbnB1dCwgaWYgKmJsb2NrID0gMSwgdGhlIG1heGltdW0gdGltZSB0aGUgY2FsbGVyCiAqICAgd2lsbCBibG9jayB3aGlsZSB3YWl0aW5nIGZvciBOZXQtU05NUCBhY3Rpdml0eS4gT24gb3V0cHV0LCBpZiB0aGlzIGZ1bmN0aW9uCiAqICAgaGFzIHNldCAqYmxvY2sgdG8gMCwgdGhlIG1heGltdW0gdGltZSB0aGUgY2FsbGVyIGlzIGFsbG93ZWQgdG8gd2FpdCBiZWZvcmUKICogICBpbnZva2luZyB0aGUgTmV0LVNOTVAgcHJvY2Vzc2luZyBmdW5jdGlvbnMgKHNubXBfcmVhZCgpLCBzbm1wX3RpbWVvdXQoKQogKiAgIGFuZCBydW5fYWxhcm1zKCkpLiBJZiB0aGlzIGZ1bmN0aW9uIGhhcyBzZXQgKmJsb2NrIHRvIDEsICp0aW1lb3V0IHdvbid0CiAqICAgaGF2ZSBiZWVuIG1vZGlmaWVkIGFuZCBubyBhbGFybXMgYXJlIGFjdGl2ZS4KICogQHBhcmFtW2luLG91dF0gYmxvY2sgICBPbiBpbnB1dCwgd2hldGhlciB0aGUgY2FsbGVyIHByZWZlcnMgdG8gYmxvY2sgZm9yZXZlcgogKiAgIHdoZW4gbm8gYWxhcm1zIGFyZSBhY3RpdmUuIE9uIG91dHB1dCwgMCBtZWFucyB0aGF0IG5vIGFsYXJtcyBhcmUgYWN0aXZlCiAqICAgbm9yIHRoYXQgdGhlcmUgaXMgYSB0aW1lb3V0IHBlbmRpbmcgZm9yIGFueSBvZiB0aGUgcHJvY2Vzc2VkIHNlc3Npb25zLgogKiBAcGFyYW1baW5dICAgICBmbGFncyAgIEVpdGhlciAwIG9yIE5FVFNOTVBfU0VMRUNUX05PQUxBUk1TLgogKgogKiBAcmV0dXJuIE51bWJlciBvZiBzZXNzaW9ucyBwcm9jZXNzZWQgYnkgdGhpcyBmdW5jdGlvbi4KICoKICogQHNlZSBTZWUgYWxzbyBhZ2VudF9jaGVja19hbmRfcHJvY2VzcygpIGZvciBhbiBleGFtcGxlIG9mIGhvdyB0byB1c2UgdGhpcwogKiAgIGZ1bmN0aW9uLgogKi8KaW50CnNubXBfc2Vzc19zZWxlY3RfaW5mbzJfZmxhZ3Modm9pZCAqc2Vzc3AsIGludCAqbnVtZmRzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfbGFyZ2VfZmRfc2V0ICogZmRzZXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RydWN0IHRpbWV2YWwgKnRpbWVvdXQsIGludCAqYmxvY2ssIGludCBmbGFncykKewogICAgc3RydWN0IHNlc3Npb25fbGlzdCAqc2xwLCAqbmV4dCA9IE5VTEw7CiAgICBuZXRzbm1wX3JlcXVlc3RfbGlzdCAqcnA7CiAgICBzdHJ1Y3QgdGltZXZhbCAgbm93LCBlYXJsaWVzdCwgYWxhcm1fdG07CiAgICBpbnQgICAgICAgICAgICAgYWN0aXZlID0gMCwgcmVxdWVzdHMgPSAwOwogICAgaW50ICAgICAgICAgICAgIG5leHRfYWxhcm0gPSAwOwoKICAgIHRpbWVyY2xlYXIoJmVhcmxpZXN0KTsKCiAgICAvKgogICAgICogRm9yIGVhY2ggc2Vzc2lvbiBleGFtaW5lZCwgYWRkIGl0cyBzb2NrZXQgdG8gdGhlIGZkc2V0LAogICAgICogYW5kIGlmIGl0IGlzIHRoZSBlYXJsaWVzdCB0aW1lb3V0IHRvIGV4cGlyZSwgbWFyayBpdCBhcyBsb3dlc3QuCiAgICAgKiBJZiBhIHNpbmdsZSBzZXNzaW9uIGlzIHNwZWNpZmllZCwgZG8ganVzdCBmb3IgdGhhdCBzZXNzaW9uLgogICAgICovCgogICAgREVCVUdNU0dUTCgoInNlc3Nfc2VsZWN0IiwgImZvciAlcyBzZXNzaW9uJXM6ICIsCiAgICAgICAgICAgICAgICBzZXNzcCA/ICJzaW5nbGUiIDogImFsbCIsIHNlc3NwID8gIiIgOiAicyIpKTsKCiAgICBmb3IgKHNscCA9IHNlc3NwID8gc2Vzc3AgOiBTZXNzaW9uczsgc2xwOyBzbHAgPSBuZXh0KSB7CiAgICAgICAgbmV4dCA9IHNscC0+bmV4dDsKCiAgICAgICAgaWYgKHNscC0+dHJhbnNwb3J0ID09IE5VTEwpIHsKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogQ2xvc2UgaW4gcHJvZ3Jlc3MgLS0gc2tpcCB0aGlzIG9uZS4gIAogICAgICAgICAgICAgKi8KICAgICAgICAgICAgREVCVUdNU0coKCJzZXNzX3NlbGVjdCIsICJza2lwICIpKTsKICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgfQoKICAgICAgICBpZiAoc2xwLT50cmFuc3BvcnQtPnNvY2sgPT0gLTEpIHsKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogVGhpcyBzZXNzaW9uIHdhcyBtYXJrZWQgZm9yIGRlbGV0aW9uLiAgCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBERUJVR01TRygoInNlc3Nfc2VsZWN0IiwgImRlbGV0ZVxuIikpOwogICAgICAgICAgICBpZiAoc2Vzc3AgPT0gTlVMTCkgewogICAgICAgICAgICAgICAgc25tcF9jbG9zZShzbHAtPnNlc3Npb24pOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgc25tcF9zZXNzX2Nsb3NlKHNscCk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgREVCVUdNU0dUTCgoInNlc3Nfc2VsZWN0IiwgImZvciAlcyBzZXNzaW9uJXM6ICIsCiAgICAgICAgICAgICAgICAgICAgICAgIHNlc3NwID8gInNpbmdsZSIgOiAiYWxsIiwgc2Vzc3AgPyAiIiA6ICJzIikpOwogICAgICAgICAgICBjb250aW51ZTsKICAgICAgICB9CgogICAgICAgIERFQlVHTVNHKCgic2Vzc19zZWxlY3QiLCAiJWQgIiwgc2xwLT50cmFuc3BvcnQtPnNvY2spKTsKICAgICAgICBpZiAoKHNscC0+dHJhbnNwb3J0LT5zb2NrICsgMSkgPiAqbnVtZmRzKSB7CiAgICAgICAgICAgICpudW1mZHMgPSAoc2xwLT50cmFuc3BvcnQtPnNvY2sgKyAxKTsKICAgICAgICB9CgogICAgICAgIE5FVFNOTVBfTEFSR0VfRkRfU0VUKHNscC0+dHJhbnNwb3J0LT5zb2NrLCBmZHNldCk7CiAgICAgICAgaWYgKHNscC0+aW50ZXJuYWwgIT0gTlVMTCAmJiBzbHAtPmludGVybmFsLT5yZXF1ZXN0cykgewogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBGb3VuZCBhbm90aGVyIHNlc3Npb24gd2l0aCBvdXRzdGFuZGluZyByZXF1ZXN0cy4gIAogICAgICAgICAgICAgKi8KICAgICAgICAgICAgcmVxdWVzdHMrKzsKICAgICAgICAgICAgZm9yIChycCA9IHNscC0+aW50ZXJuYWwtPnJlcXVlc3RzOyBycDsgcnAgPSBycC0+bmV4dF9yZXF1ZXN0KSB7CiAgICAgICAgICAgICAgICBpZiAoKCF0aW1lcmlzc2V0KCZlYXJsaWVzdCkKICAgICAgICAgICAgICAgICAgICAgfHwgKHRpbWVyY21wKCZycC0+ZXhwaXJlLCAmZWFybGllc3QsIDwpKSkpIHsKICAgICAgICAgICAgICAgICAgICBlYXJsaWVzdCA9IHJwLT5leHBpcmU7CiAgICAgICAgICAgICAgICAgICAgREVCVUdNU0coKCJ2ZXJib3NlOnNlc3Nfc2VsZWN0IiwiKHRvIGluICVkLiUwNmQgc2VjKSAiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGludCllYXJsaWVzdC50dl9zZWMsIChpbnQpZWFybGllc3QudHZfdXNlYykpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQoKICAgICAgICBhY3RpdmUrKzsKICAgICAgICBpZiAoc2Vzc3ApIHsKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogU2luZ2xlIHNlc3Npb24gcHJvY2Vzc2luZy4gIAogICAgICAgICAgICAgKi8KICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgfQogICAgREVCVUdNU0coKCJzZXNzX3NlbGVjdCIsICJcbiIpKTsKCiAgICBnZXR0aW1lb2ZkYXkoJm5vdywgTlVMTCk7CgogICAgaWYgKG5ldHNubXBfZHNfZ2V0X2Jvb2xlYW4oTkVUU05NUF9EU19MSUJSQVJZX0lELAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTkVUU05NUF9EU19MSUJfQUxBUk1fRE9OVF9VU0VfU0lHKSAmJgogICAgICAgICEoZmxhZ3MgJiBORVRTTk1QX1NFTEVDVF9OT0FMQVJNUykpIHsKICAgICAgICBuZXh0X2FsYXJtID0gbmV0c25tcF9nZXRfbmV4dF9hbGFybV90aW1lKCZhbGFybV90bSwgJm5vdyk7CiAgICAgICAgaWYgKG5leHRfYWxhcm0pCiAgICAgICAgICAgIERFQlVHTVNHVCgoInNlc3Nfc2VsZWN0IiwibmV4dCBhbGFybSBhdCAlbGQuJTA2bGQgc2VjXG4iLAogICAgICAgICAgICAgICAgICAgICAgIChsb25nKWFsYXJtX3RtLnR2X3NlYywgKGxvbmcpYWxhcm1fdG0udHZfdXNlYykpOwogICAgfQogICAgaWYgKG5leHRfYWxhcm0gPT0gMCAmJiByZXF1ZXN0cyA9PSAwKSB7CiAgICAgICAgLyoKICAgICAgICAgKiBJZiBub25lIGFyZSBhY3RpdmUsIHNraXAgYXJpdGhtZXRpYy4gIAogICAgICAgICAqLwogICAgICAgIERFQlVHTVNHVCgoInNlc3Nfc2VsZWN0IiwiYmxvY2tpbmc6bm8gc2Vzc2lvbiByZXF1ZXN0cyBvciBhbGFybXMuXG4iKSk7CiAgICAgICAgKmJsb2NrID0gMTsgLyogY2FuIGJsb2NrIC0gdGltZW91dCB2YWx1ZSBpcyB1bmRlZmluZWQgaWYgbm8gcmVxdWVzdHMgKi8KICAgICAgICByZXR1cm4gYWN0aXZlOwogICAgfQoKICAgIGlmIChuZXh0X2FsYXJtICYmCiAgICAgICAgKCF0aW1lcmlzc2V0KCZlYXJsaWVzdCkgfHwgdGltZXJjbXAoJmFsYXJtX3RtLCAmZWFybGllc3QsIDwpKSkKICAgICAgICBlYXJsaWVzdCA9IGFsYXJtX3RtOwoKICAgIE5FVFNOTVBfVElNRVJTVUIoJmVhcmxpZXN0LCAmbm93LCAmZWFybGllc3QpOwogICAgaWYgKGVhcmxpZXN0LnR2X3NlYyA8IDApIHsKICAgICAgICB0aW1lX3Qgb3ZlcmR1ZV9tcyA9IC0oZWFybGllc3QudHZfc2VjICogMTAwMCArIGVhcmxpZXN0LnR2X3VzZWMgLyAxMDAwKTsKICAgICAgICBpZiAob3ZlcmR1ZV9tcyA+PSAxMCkKICAgICAgICAgICAgREVCVUdNU0dUKCgidmVyYm9zZTpzZXNzX3NlbGVjdCIsInRpbWVyIG92ZXJkdWUgYnkgJWxkIG1zXG4iLAogICAgICAgICAgICAgICAgICAgICAgIG92ZXJkdWVfbXMpKTsKICAgICAgICB0aW1lcmNsZWFyKCZlYXJsaWVzdCk7CiAgICB9IGVsc2UgewogICAgICAgIERFQlVHTVNHVCgoInZlcmJvc2U6c2Vzc19zZWxlY3QiLCJ0aW1lciBkdWUgaW4gJWQuJTA2ZCBzZWNcbiIsCiAgICAgICAgICAgICAgICAgICAoaW50KWVhcmxpZXN0LnR2X3NlYywgKGludCllYXJsaWVzdC50dl91c2VjKSk7CiAgICB9CgogICAgLyoKICAgICAqIGlmIGl0IHdhcyBibG9ja2luZyBiZWZvcmUgb3Igb3VyIGRlbHRhIHRpbWUgaXMgbGVzcywgcmVzZXQgdGltZW91dCAKICAgICAqLwogICAgaWYgKCgqYmxvY2sgfHwgKHRpbWVyY21wKCZlYXJsaWVzdCwgdGltZW91dCwgPCkpKSkgewogICAgICAgIERFQlVHTVNHVCgoInZlcmJvc2U6c2Vzc19zZWxlY3QiLAogICAgICAgICAgICAgICAgICAgInNldHRpbmcgdGltZXIgdG8gJWQuJTA2ZCBzZWMsIGNsZWFyIGJsb2NrICh3YXMgJWQpXG4iLAogICAgICAgICAgICAgICAgICAgKGludCllYXJsaWVzdC50dl9zZWMsIChpbnQpZWFybGllc3QudHZfdXNlYywgKmJsb2NrKSk7CiAgICAgICAgKnRpbWVvdXQgPSBlYXJsaWVzdDsKICAgICAgICAqYmxvY2sgPSAwOwogICAgfQogICAgcmV0dXJuIGFjdGl2ZTsKfQoKLyoKICogc25tcF90aW1lb3V0IHNob3VsZCBiZSBjYWxsZWQgd2hlbmV2ZXIgdGhlIHRpbWVvdXQgZnJvbSBzbm1wX3NlbGVjdF9pbmZvCiAqIGV4cGlyZXMsIGJ1dCBpdCBpcyBpZGVtcG90ZW50LCBzbyBzbm1wX3RpbWVvdXQgY2FuIGJlIHBvbGxlZCAocHJvYmFibHkgYQogKiBjcHUgZXhwZW5zaXZlIHByb3Bvc2l0aW9uKS4gIHNubXBfdGltZW91dCBjaGVja3MgdG8gc2VlIGlmIGFueSBvZiB0aGUKICogc2Vzc2lvbnMgaGF2ZSBhbiBvdXRzdGFuZGluZyByZXF1ZXN0IHRoYXQgaGFzIHRpbWVkIG91dC4gIElmIGl0IGZpbmRzIG9uZQogKiAob3IgbW9yZSksIGFuZCB0aGF0IHBkdSBoYXMgbW9yZSByZXRyaWVzIGF2YWlsYWJsZSwgYSBuZXcgcGFja2V0IGlzIGZvcm1lZAogKiBmcm9tIHRoZSBwZHUgYW5kIGlzIHJlc2VudC4gIElmIHRoZXJlIGFyZSBubyBtb3JlIHJldHJpZXMgYXZhaWxhYmxlLCB0aGUKICogIGNhbGxiYWNrIGZvciB0aGUgc2Vzc2lvbiBpcyB1c2VkIHRvIGFsZXJ0IHRoZSB1c2VyIG9mIHRoZSB0aW1lb3V0LgogKi8Kdm9pZApzbm1wX3RpbWVvdXQodm9pZCkKewogICAgc3RydWN0IHNlc3Npb25fbGlzdCAqc2xwOwogICAgc25tcF9yZXNfbG9jayhNVF9MSUJSQVJZX0lELCBNVF9MSUJfU0VTU0lPTik7CiAgICBmb3IgKHNscCA9IFNlc3Npb25zOyBzbHA7IHNscCA9IHNscC0+bmV4dCkgewogICAgICAgIHNubXBfc2Vzc190aW1lb3V0KCh2b2lkICopIHNscCk7CiAgICB9CiAgICBzbm1wX3Jlc191bmxvY2soTVRfTElCUkFSWV9JRCwgTVRfTElCX1NFU1NJT04pOwp9CgpzdGF0aWMgaW50CnNubXBfcmVzZW5kX3JlcXVlc3Qoc3RydWN0IHNlc3Npb25fbGlzdCAqc2xwLCBuZXRzbm1wX3JlcXVlc3RfbGlzdCAqcnAsCiAgICAgICAgICAgICAgICAgICAgaW50IGluY3JfcmV0cmllcykKewogICAgc3RydWN0IHNubXBfaW50ZXJuYWxfc2Vzc2lvbiAqaXNwOwogICAgbmV0c25tcF9zZXNzaW9uICpzcDsKICAgIG5ldHNubXBfdHJhbnNwb3J0ICp0cmFuc3BvcnQ7CiAgICB1X2NoYXIgICAgICAgICAqcGt0YnVmID0gTlVMTCwgKnBhY2tldCA9IE5VTEw7CiAgICBzaXplX3QgICAgICAgICAgcGt0YnVmX2xlbiA9IDAsIG9mZnNldCA9IDAsIGxlbmd0aCA9IDA7CiAgICBzdHJ1Y3QgdGltZXZhbCAgdHYsIG5vdzsKICAgIGludCAgICAgICAgICAgICByZXN1bHQgPSAwOwoKICAgIHNwID0gc2xwLT5zZXNzaW9uOwogICAgaXNwID0gc2xwLT5pbnRlcm5hbDsKICAgIHRyYW5zcG9ydCA9IHNscC0+dHJhbnNwb3J0OwogICAgaWYgKCFzcCB8fCAhaXNwIHx8ICF0cmFuc3BvcnQpIHsKICAgICAgICBERUJVR01TR1RMKCgic2Vzc19yZWFkIiwgInJlc2VuZCBmYWlsOiBjbG9zaW5nLi4uXG4iKSk7CiAgICAgICAgcmV0dXJuIDA7CiAgICB9CgogICAgaWYgKChwa3RidWYgPSAodV9jaGFyICopbWFsbG9jKDIwNDgpKSA9PSBOVUxMKSB7CiAgICAgICAgREVCVUdNU0dUTCgoInNlc3NfcmVzZW5kIiwKICAgICAgICAgICAgICAgICAgICAiY291bGRuJ3QgbWFsbG9jIGluaXRpYWwgcGFja2V0IGJ1ZmZlclxuIikpOwogICAgICAgIHJldHVybiAwOwogICAgfSBlbHNlIHsKICAgICAgICBwa3RidWZfbGVuID0gMjA0ODsKICAgIH0KCiAgICBpZiAoaW5jcl9yZXRyaWVzKSB7CiAgICAgICAgcnAtPnJldHJpZXMrKzsKICAgIH0KCiAgICAvKgogICAgICogQWx3YXlzIGluY3JlbWVudCBtc2dJZCBmb3IgcmVzZW50IG1lc3NhZ2VzLiAgCiAgICAgKi8KICAgIHJwLT5wZHUtPm1zZ2lkID0gcnAtPm1lc3NhZ2VfaWQgPSBzbm1wX2dldF9uZXh0X21zZ2lkKCk7CgogICAgaWYgKGlzcC0+aG9va19yZWFsbG9jX2J1aWxkKSB7CiAgICAgICAgcmVzdWx0ID0gaXNwLT5ob29rX3JlYWxsb2NfYnVpbGQoc3AsIHJwLT5wZHUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnBrdGJ1ZiwgJnBrdGJ1Zl9sZW4sICZvZmZzZXQpOwoKICAgICAgICBwYWNrZXQgPSBwa3RidWY7CiAgICAgICAgbGVuZ3RoID0gb2Zmc2V0OwogICAgfSBlbHNlIGlmIChpc3AtPmhvb2tfYnVpbGQpIHsKICAgICAgICBwYWNrZXQgPSBwa3RidWY7CiAgICAgICAgbGVuZ3RoID0gcGt0YnVmX2xlbjsKICAgICAgICByZXN1bHQgPSBpc3AtPmhvb2tfYnVpbGQoc3AsIHJwLT5wZHUsIHBrdGJ1ZiwgJmxlbmd0aCk7CiAgICB9IGVsc2UgewojaWZkZWYgTkVUU05NUF9VU0VfUkVWRVJTRV9BU05FTkNPRElORwogICAgICAgIGlmIChuZXRzbm1wX2RzX2dldF9ib29sZWFuKE5FVFNOTVBfRFNfTElCUkFSWV9JRCwgTkVUU05NUF9EU19MSUJfUkVWRVJTRV9FTkNPREUpKSB7CiAgICAgICAgICAgIHJlc3VsdCA9CiAgICAgICAgICAgICAgICBzbm1wX2J1aWxkKCZwa3RidWYsICZwa3RidWZfbGVuLCAmb2Zmc2V0LCBzcCwgcnAtPnBkdSk7CiAgICAgICAgICAgIHBhY2tldCA9IHBrdGJ1ZiArIHBrdGJ1Zl9sZW4gLSBvZmZzZXQ7CiAgICAgICAgICAgIGxlbmd0aCA9IG9mZnNldDsKICAgICAgICB9IGVsc2UgewojZW5kaWYKICAgICAgICAgICAgcGFja2V0ID0gcGt0YnVmOwogICAgICAgICAgICBsZW5ndGggPSBwa3RidWZfbGVuOwogICAgICAgICAgICByZXN1bHQgPSBzbm1wX2J1aWxkKCZwa3RidWYsICZsZW5ndGgsICZvZmZzZXQsIHNwLCBycC0+cGR1KTsKI2lmZGVmIE5FVFNOTVBfVVNFX1JFVkVSU0VfQVNORU5DT0RJTkcKICAgICAgICB9CiNlbmRpZgogICAgfQoKICAgIGlmIChyZXN1bHQgPCAwKSB7CiAgICAgICAgLyoKICAgICAgICAgKiBUaGlzIHNob3VsZCBuZXZlciBoYXBwZW4uICAKICAgICAgICAgKi8KICAgICAgICBERUJVR01TR1RMKCgic2Vzc19yZXNlbmQiLCAiZW5jb2RpbmcgZmFpbHVyZVxuIikpOwogICAgICAgIGlmIChwa3RidWYgIT0gTlVMTCkgewogICAgICAgICAgICBTTk1QX0ZSRUUocGt0YnVmKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIC0xOwogICAgfQoKICAgIERFQlVHTVNHVEwoKCJzZXNzX3Byb2Nlc3NfcGFja2V0IiwgInJlc2VuZGluZyBtZXNzYWdlIGlkIyVsZCByZXFpZCMlbGQgIgogICAgICAgICAgICAgICAgInJwX3JlcWlkIyVsZCBycF9tc2dpZCMlbGQgbGVuICUiIE5FVFNOTVBfUFJJeiAidVxuIiwKICAgICAgICAgICAgICAgIHJwLT5wZHUtPm1zZ2lkLCBycC0+cGR1LT5yZXFpZCwgcnAtPnJlcXVlc3RfaWQsIHJwLT5tZXNzYWdlX2lkLCBsZW5ndGgpKTsKICAgIHJlc3VsdCA9IG5ldHNubXBfdHJhbnNwb3J0X3NlbmQodHJhbnNwb3J0LCBwYWNrZXQsIGxlbmd0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJihycC0+cGR1LT50cmFuc3BvcnRfZGF0YSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICYocnAtPnBkdS0+dHJhbnNwb3J0X2RhdGFfbGVuZ3RoKSk7CgogICAgLyoKICAgICAqIFdlIGFyZSBmaW5pc2hlZCB3aXRoIHRoZSBsb2NhbCBwYWNrZXQgYnVmZmVyLCBpZiB3ZSBhbGxvY2F0ZWQgb25lIChkdWUKICAgICAqIHRvIHRoZXJlIGJlaW5nIG5vIHNhdmVkIHBhY2tldCkuICAKICAgICAqLwoKICAgIGlmIChwa3RidWYgIT0gTlVMTCkgewogICAgICAgIFNOTVBfRlJFRShwa3RidWYpOwogICAgICAgIHBrdGJ1ZiA9IHBhY2tldCA9IE5VTEw7CiAgICB9CgogICAgaWYgKHJlc3VsdCA8IDApIHsKICAgICAgICBzcC0+c19zbm1wX2Vycm5vID0gU05NUEVSUl9CQURfU0VORFRPOwogICAgICAgIHNwLT5zX2Vycm5vID0gZXJybm87CiAgICAgICAgc25tcF9zZXRfZGV0YWlsKHN0cmVycm9yKGVycm5vKSk7CiAgICAgICAgcmV0dXJuIC0xOwogICAgfSBlbHNlIHsKICAgICAgICBnZXR0aW1lb2ZkYXkoJm5vdywgKHN0cnVjdCB0aW1lem9uZSAqKSAwKTsKICAgICAgICB0diA9IG5vdzsKICAgICAgICBycC0+dGltZSA9IHR2OwogICAgICAgIHR2LnR2X3VzZWMgKz0gcnAtPnRpbWVvdXQ7CiAgICAgICAgdHYudHZfc2VjICs9IHR2LnR2X3VzZWMgLyAxMDAwMDAwTDsKICAgICAgICB0di50dl91c2VjICU9IDEwMDAwMDBMOwogICAgICAgIHJwLT5leHBpcmUgPSB0djsKICAgIH0KICAgIHJldHVybiAwOwp9CgoKCnZvaWQKc25tcF9zZXNzX3RpbWVvdXQodm9pZCAqc2Vzc3ApCnsKICAgIHN0cnVjdCBzZXNzaW9uX2xpc3QgKnNscCA9IChzdHJ1Y3Qgc2Vzc2lvbl9saXN0ICopIHNlc3NwOwogICAgbmV0c25tcF9zZXNzaW9uICpzcDsKICAgIHN0cnVjdCBzbm1wX2ludGVybmFsX3Nlc3Npb24gKmlzcDsKICAgIG5ldHNubXBfcmVxdWVzdF9saXN0ICpycCwgKm9ycCA9IE5VTEwsICpmcmVlbWUgPSBOVUxMOwogICAgc3RydWN0IHRpbWV2YWwgIG5vdzsKICAgIHNubXBfY2FsbGJhY2sgICBjYWxsYmFjazsKICAgIHZvaWQgICAgICAgICAgICptYWdpYzsKICAgIHN0cnVjdCBzbm1wX3NlY21vZF9kZWYgKnNwdHI7CgogICAgc3AgPSBzbHAtPnNlc3Npb247CiAgICBpc3AgPSBzbHAtPmludGVybmFsOwogICAgaWYgKCFzcCB8fCAhaXNwKSB7CiAgICAgICAgREVCVUdNU0dUTCgoInNlc3NfcmVhZCIsICJ0aW1lb3V0IGZhaWw6IGNsb3NpbmcuLi5cbiIpKTsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgZ2V0dGltZW9mZGF5KCZub3csIChzdHJ1Y3QgdGltZXpvbmUgKikgMCk7CgogICAgLyoKICAgICAqIEZvciBlYWNoIHJlcXVlc3Qgb3V0c3RhbmRpbmcsIGNoZWNrIHRvIHNlZSBpZiBpdCBoYXMgZXhwaXJlZC4KICAgICAqLwogICAgZm9yIChycCA9IGlzcC0+cmVxdWVzdHM7IHJwOyBycCA9IHJwLT5uZXh0X3JlcXVlc3QpIHsKICAgICAgICBpZiAoZnJlZW1lICE9IE5VTEwpIHsKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogZnJlZXMgcnAncyBhZnRlciB0aGUgZm9yIGxvb3AgZ29lcyBvbiB0byB0aGUgbmV4dF9yZXF1ZXN0IAogICAgICAgICAgICAgKi8KICAgICAgICAgICAgZnJlZSgoY2hhciAqKSBmcmVlbWUpOwogICAgICAgICAgICBmcmVlbWUgPSBOVUxMOwogICAgICAgIH0KCiAgICAgICAgaWYgKCh0aW1lcmNtcCgmcnAtPmV4cGlyZSwgJm5vdywgPCkpKSB7CiAgICAgICAgICAgIGlmICgoc3B0ciA9IGZpbmRfc2VjX21vZChycC0+cGR1LT5zZWN1cml0eU1vZGVsKSkgIT0gTlVMTCAmJgogICAgICAgICAgICAgICAgc3B0ci0+cGR1X3RpbWVvdXQgIT0gTlVMTCkgewogICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAqIGNhbGwgc2VjdXJpdHkgbW9kZWwgaWYgaXQgbmVlZHMgdG8ga25vdyBhYm91dCB0aGlzIAogICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICAoKnNwdHItPnBkdV90aW1lb3V0KSAocnAtPnBkdSk7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIHRoaXMgdGltZXIgaGFzIGV4cGlyZWQgCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBpZiAocnAtPnJldHJpZXMgPj0gc3AtPnJldHJpZXMpIHsKICAgICAgICAgICAgICAgIGlmIChycC0+Y2FsbGJhY2spIHsKICAgICAgICAgICAgICAgICAgICBjYWxsYmFjayA9IHJwLT5jYWxsYmFjazsKICAgICAgICAgICAgICAgICAgICBtYWdpYyA9IHJwLT5jYl9kYXRhOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICBjYWxsYmFjayA9IHNwLT5jYWxsYmFjazsKICAgICAgICAgICAgICAgICAgICBtYWdpYyA9IHNwLT5jYWxsYmFja19tYWdpYzsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAgICogTm8gbW9yZSBjaGFuY2VzLCBkZWxldGUgdGhpcyBlbnRyeSAKICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgaWYgKGNhbGxiYWNrKSB7CiAgICAgICAgICAgICAgICAgICAgY2FsbGJhY2soTkVUU05NUF9DQUxMQkFDS19PUF9USU1FRF9PVVQsIHNwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJwLT5wZHUtPnJlcWlkLCBycC0+cGR1LCBtYWdpYyk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBpZiAoaXNwLT5yZXF1ZXN0cyA9PSBycCkgewogICAgICAgICAgICAgICAgICAgIGlzcC0+cmVxdWVzdHMgPSBycC0+bmV4dF9yZXF1ZXN0OwogICAgICAgICAgICAgICAgICAgIGlmIChpc3AtPnJlcXVlc3RzRW5kID09IHJwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlzcC0+cmVxdWVzdHNFbmQgPSBOVUxMOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgb3JwLT5uZXh0X3JlcXVlc3QgPSBycC0+bmV4dF9yZXF1ZXN0OwogICAgICAgICAgICAgICAgICAgIGlmIChpc3AtPnJlcXVlc3RzRW5kID09IHJwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGlzcC0+cmVxdWVzdHNFbmQgPSBvcnA7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgc25tcF9mcmVlX3BkdShycC0+cGR1KTsgLyogRklYICBycCBpcyBhbHJlYWR5IGZyZWUnZCEgKi8KICAgICAgICAgICAgICAgIGZyZWVtZSA9IHJwOwogICAgICAgICAgICAgICAgY29udGludWU7ICAgICAgIC8qIGRvbid0IHVwZGF0ZSBvcnAgYmVsb3cgKi8KICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGlmIChzbm1wX3Jlc2VuZF9yZXF1ZXN0KHNscCwgcnAsIFRSVUUpKSB7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgb3JwID0gcnA7CiAgICB9CgogICAgaWYgKGZyZWVtZSAhPSBOVUxMKSB7CiAgICAgICAgZnJlZSgoY2hhciAqKSBmcmVlbWUpOwogICAgICAgIGZyZWVtZSA9IE5VTEw7CiAgICB9Cn0KCi8qCiAqIGxleGljb2dyYXBoaWNhbCBjb21wYXJlIHR3byBvYmplY3QgaWRlbnRpZmllcnMuCiAqICogUmV0dXJucyAtMSBpZiBuYW1lMSA8IG5hbWUyLAogKiAqICAgICAgICAgIDAgaWYgbmFtZTEgPSBuYW1lMiwKICogKiAgICAgICAgICAxIGlmIG5hbWUxID4gbmFtZTIKICogKgogKiAqIENhdXRpb246IHRoaXMgbWV0aG9kIGlzIGNhbGxlZCBvZnRlbiBieQogKiAqICAgICAgICAgIGNvbW1hbmQgcmVzcG9uZGVyIGFwcGxpY2F0aW9ucyAoaWUsIGFnZW50KS4KICovCmludApzbm1wX29pZF9uY29tcGFyZShjb25zdCBvaWQgKiBpbl9uYW1lMSwKICAgICAgICAgICAgICAgICAgc2l6ZV90IGxlbjEsCiAgICAgICAgICAgICAgICAgIGNvbnN0IG9pZCAqIGluX25hbWUyLCBzaXplX3QgbGVuMiwgc2l6ZV90IG1heF9sZW4pCnsKICAgIHJlZ2lzdGVyIGludCAgICBsZW47CiAgICByZWdpc3RlciBjb25zdCBvaWQgKm5hbWUxID0gaW5fbmFtZTE7CiAgICByZWdpc3RlciBjb25zdCBvaWQgKm5hbWUyID0gaW5fbmFtZTI7CiAgICBzaXplX3QgICAgICAgICAgbWluX2xlbjsKCiAgICAvKgogICAgICogbGVuID0gbWluaW11bSBvZiBsZW4xIGFuZCBsZW4yIAogICAgICovCiAgICBpZiAobGVuMSA8IGxlbjIpCiAgICAgICAgbWluX2xlbiA9IGxlbjE7CiAgICBlbHNlCiAgICAgICAgbWluX2xlbiA9IGxlbjI7CgogICAgaWYgKG1pbl9sZW4gPiBtYXhfbGVuKQogICAgICAgIG1pbl9sZW4gPSBtYXhfbGVuOwoKICAgIGxlbiA9IG1pbl9sZW47CgogICAgLyoKICAgICAqIGZpbmQgZmlyc3Qgbm9uLW1hdGNoaW5nIE9JRCAKICAgICAqLwogICAgd2hpbGUgKGxlbi0tID4gMCkgewogICAgICAgIC8qCiAgICAgICAgICogdGhlc2UgbXVzdCBiZSBkb25lIGluIHNlcGVyYXRlIGNvbXBhcmlzb25zLCBzaW5jZQogICAgICAgICAqIHN1YnRyYWN0aW5nIHRoZW0gYW5kIHVzaW5nIHRoYXQgcmVzdWx0IGhhcyBwcm9ibGVtcyB3aXRoCiAgICAgICAgICogc3ViaWRzID4gMl4zMS4gCiAgICAgICAgICovCiAgICAgICAgaWYgKCoobmFtZTEpICE9ICoobmFtZTIpKSB7CiAgICAgICAgICAgIGlmICgqKG5hbWUxKSA8ICoobmFtZTIpKQogICAgICAgICAgICAgICAgcmV0dXJuIC0xOwogICAgICAgICAgICByZXR1cm4gMTsKICAgICAgICB9CiAgICAgICAgbmFtZTErKzsKICAgICAgICBuYW1lMisrOwogICAgfQoKICAgIGlmIChtaW5fbGVuICE9IG1heF9sZW4pIHsKICAgICAgICAvKgogICAgICAgICAqIGJvdGggT0lEcyBlcXVhbCB1cCB0byBsZW5ndGggb2Ygc2hvcnRlciBPSUQgCiAgICAgICAgICovCiAgICAgICAgaWYgKGxlbjEgPCBsZW4yKQogICAgICAgICAgICByZXR1cm4gLTE7CiAgICAgICAgaWYgKGxlbjIgPCBsZW4xKQogICAgICAgICAgICByZXR1cm4gMTsKICAgIH0KCiAgICByZXR1cm4gMDsKfQoKLyoqIGxleGljb2dyYXBoaWNhbCBjb21wYXJlIHR3byBvYmplY3QgaWRlbnRpZmllcnMuCiAqIAogKiBDYXV0aW9uOiB0aGlzIG1ldGhvZCBpcyBjYWxsZWQgb2Z0ZW4gYnkKICogICAgICAgICAgY29tbWFuZCByZXNwb25kZXIgYXBwbGljYXRpb25zIChpZSwgYWdlbnQpLgogKgogKiBAcmV0dXJuIC0xIGlmIG5hbWUxIDwgbmFtZTIsIDAgaWYgbmFtZTEgPSBuYW1lMiwgMSBpZiBuYW1lMSA+IG5hbWUyCiAqLwppbnQKc25tcF9vaWRfY29tcGFyZShjb25zdCBvaWQgKiBpbl9uYW1lMSwKICAgICAgICAgICAgICAgICBzaXplX3QgbGVuMSwgY29uc3Qgb2lkICogaW5fbmFtZTIsIHNpemVfdCBsZW4yKQp7CiAgICByZWdpc3RlciBpbnQgICAgbGVuOwogICAgcmVnaXN0ZXIgY29uc3Qgb2lkICpuYW1lMSA9IGluX25hbWUxOwogICAgcmVnaXN0ZXIgY29uc3Qgb2lkICpuYW1lMiA9IGluX25hbWUyOwoKICAgIC8qCiAgICAgKiBsZW4gPSBtaW5pbXVtIG9mIGxlbjEgYW5kIGxlbjIgCiAgICAgKi8KICAgIGlmIChsZW4xIDwgbGVuMikKICAgICAgICBsZW4gPSBsZW4xOwogICAgZWxzZQogICAgICAgIGxlbiA9IGxlbjI7CiAgICAvKgogICAgICogZmluZCBmaXJzdCBub24tbWF0Y2hpbmcgT0lEIAogICAgICovCiAgICB3aGlsZSAobGVuLS0gPiAwKSB7CiAgICAgICAgLyoKICAgICAgICAgKiB0aGVzZSBtdXN0IGJlIGRvbmUgaW4gc2VwZXJhdGUgY29tcGFyaXNvbnMsIHNpbmNlCiAgICAgICAgICogc3VidHJhY3RpbmcgdGhlbSBhbmQgdXNpbmcgdGhhdCByZXN1bHQgaGFzIHByb2JsZW1zIHdpdGgKICAgICAgICAgKiBzdWJpZHMgPiAyXjMxLiAKICAgICAgICAgKi8KICAgICAgICBpZiAoKihuYW1lMSkgIT0gKihuYW1lMikpIHsKICAgICAgICAgICAgaWYgKCoobmFtZTEpIDwgKihuYW1lMikpCiAgICAgICAgICAgICAgICByZXR1cm4gLTE7CiAgICAgICAgICAgIHJldHVybiAxOwogICAgICAgIH0KICAgICAgICBuYW1lMSsrOwogICAgICAgIG5hbWUyKys7CiAgICB9CiAgICAvKgogICAgICogYm90aCBPSURzIGVxdWFsIHVwIHRvIGxlbmd0aCBvZiBzaG9ydGVyIE9JRCAKICAgICAqLwogICAgaWYgKGxlbjEgPCBsZW4yKQogICAgICAgIHJldHVybiAtMTsKICAgIGlmIChsZW4yIDwgbGVuMSkKICAgICAgICByZXR1cm4gMTsKICAgIHJldHVybiAwOwp9CgovKiogbGV4aWNvZ3JhcGhpY2FsIGNvbXBhcmUgdHdvIG9iamVjdCBpZGVudGlmaWVycyBhbmQgcmV0dXJuIHRoZSBwb2ludCB3aGVyZSB0aGV5IGRpZmZlcgogKiAKICogQ2F1dGlvbjogdGhpcyBtZXRob2QgaXMgY2FsbGVkIG9mdGVuIGJ5CiAqICAgICAgICAgIGNvbW1hbmQgcmVzcG9uZGVyIGFwcGxpY2F0aW9ucyAoaWUsIGFnZW50KS4KICoKICogQHJldHVybiAtMSBpZiBuYW1lMSA8IG5hbWUyLCAwIGlmIG5hbWUxID0gbmFtZTIsIDEgaWYgbmFtZTEgPiBuYW1lMiBhbmQgb2ZmcHQgPSBsZW4gd2hlcmUgbmFtZTEgIT0gbmFtZTIKICovCmludApuZXRzbm1wX29pZF9jb21wYXJlX2xsKGNvbnN0IG9pZCAqIGluX25hbWUxLAogICAgICAgICAgICAgICAgICAgICAgIHNpemVfdCBsZW4xLCBjb25zdCBvaWQgKiBpbl9uYW1lMiwgc2l6ZV90IGxlbjIsCiAgICAgICAgICAgICAgICAgICAgICAgc2l6ZV90ICpvZmZwdCkKewogICAgcmVnaXN0ZXIgaW50ICAgIGxlbjsKICAgIHJlZ2lzdGVyIGNvbnN0IG9pZCAqbmFtZTEgPSBpbl9uYW1lMTsKICAgIHJlZ2lzdGVyIGNvbnN0IG9pZCAqbmFtZTIgPSBpbl9uYW1lMjsKICAgIGludCBpbml0bGVuOwoKICAgIC8qCiAgICAgKiBsZW4gPSBtaW5pbXVtIG9mIGxlbjEgYW5kIGxlbjIgCiAgICAgKi8KICAgIGlmIChsZW4xIDwgbGVuMikKICAgICAgICBpbml0bGVuID0gbGVuID0gbGVuMTsKICAgIGVsc2UKICAgICAgICBpbml0bGVuID0gbGVuID0gbGVuMjsKICAgIC8qCiAgICAgKiBmaW5kIGZpcnN0IG5vbi1tYXRjaGluZyBPSUQgCiAgICAgKi8KICAgIHdoaWxlIChsZW4tLSA+IDApIHsKICAgICAgICAvKgogICAgICAgICAqIHRoZXNlIG11c3QgYmUgZG9uZSBpbiBzZXBlcmF0ZSBjb21wYXJpc29ucywgc2luY2UKICAgICAgICAgKiBzdWJ0cmFjdGluZyB0aGVtIGFuZCB1c2luZyB0aGF0IHJlc3VsdCBoYXMgcHJvYmxlbXMgd2l0aAogICAgICAgICAqIHN1YmlkcyA+IDJeMzEuIAogICAgICAgICAqLwogICAgICAgIGlmICgqKG5hbWUxKSAhPSAqKG5hbWUyKSkgewogICAgICAgICAgICAqb2ZmcHQgPSBpbml0bGVuIC0gbGVuOwogICAgICAgICAgICBpZiAoKihuYW1lMSkgPCAqKG5hbWUyKSkKICAgICAgICAgICAgICAgIHJldHVybiAtMTsKICAgICAgICAgICAgcmV0dXJuIDE7CiAgICAgICAgfQogICAgICAgIG5hbWUxKys7CiAgICAgICAgbmFtZTIrKzsKICAgIH0KICAgIC8qCiAgICAgKiBib3RoIE9JRHMgZXF1YWwgdXAgdG8gbGVuZ3RoIG9mIHNob3J0ZXIgT0lEIAogICAgICovCiAgICAqb2ZmcHQgPSBpbml0bGVuIC0gbGVuOwogICAgaWYgKGxlbjEgPCBsZW4yKQogICAgICAgIHJldHVybiAtMTsKICAgIGlmIChsZW4yIDwgbGVuMSkKICAgICAgICByZXR1cm4gMTsKICAgIHJldHVybiAwOwp9CgovKiogQ29tcGFyZXMgMiBPSURzIHRvIGRldGVybWluZSBpZiB0aGV5IGFyZSBlcXVhbCB1cCB1bnRpbCB0aGUgc2hvcnRlc3QgbGVuZ3RoLgogKiBAcGFyYW0gaW5fbmFtZTEgQSBwb2ludGVyIHRvIHRoZSBmaXJzdCBvaWQuCiAqIEBwYXJhbSBsZW4xICAgICBsZW5ndGggb2YgdGhlIGZpcnN0IE9JRCAoaW4gc2VnbWVudHMsIG5vdCBieXRlcykKICogQHBhcmFtIGluX25hbWUyIEEgcG9pbnRlciB0byB0aGUgc2Vjb25kIG9pZC4KICogQHBhcmFtIGxlbjIgICAgIGxlbmd0aCBvZiB0aGUgc2Vjb25kIE9JRCAoaW4gc2VnbWVudHMsIG5vdCBieXRlcykKICogQHJldHVybiAwIGlmIHRoZXkgYXJlIGVxdWFsLCAxIGlmIGluX25hbWUxIGlzID4gaW5fbmFtZTIsIG9yIC0xIGlmIDwuCiAqLyAKaW50CnNubXBfb2lkdHJlZV9jb21wYXJlKGNvbnN0IG9pZCAqIGluX25hbWUxLAogICAgICAgICAgICAgICAgICAgICBzaXplX3QgbGVuMSwgY29uc3Qgb2lkICogaW5fbmFtZTIsIHNpemVfdCBsZW4yKQp7CiAgICBpbnQgICAgICAgICAgICAgbGVuID0gKChsZW4xIDwgbGVuMikgPyBsZW4xIDogbGVuMik7CgogICAgcmV0dXJuIChzbm1wX29pZF9jb21wYXJlKGluX25hbWUxLCBsZW4sIGluX25hbWUyLCBsZW4pKTsKfQoKaW50CnNubXBfb2lkc3VidHJlZV9jb21wYXJlKGNvbnN0IG9pZCAqIGluX25hbWUxLAogICAgICAgICAgICAgICAgICAgICBzaXplX3QgbGVuMSwgY29uc3Qgb2lkICogaW5fbmFtZTIsIHNpemVfdCBsZW4yKQp7CiAgICBpbnQgICAgICAgICAgICAgbGVuID0gKChsZW4xIDwgbGVuMikgPyBsZW4xIDogbGVuMik7CgogICAgcmV0dXJuIChzbm1wX29pZF9jb21wYXJlKGluX25hbWUxLCBsZW4xLCBpbl9uYW1lMiwgbGVuKSk7Cn0KCi8qKiBDb21wYXJlcyAyIE9JRHMgdG8gZGV0ZXJtaW5lIGlmIHRoZXkgYXJlIGV4YWN0bHkgZXF1YWwuCiAqICBUaGlzIHNob3VsZCBiZSBmYXN0ZXIgdGhhbiBkb2luZyBhIHNubXBfb2lkX2NvbXBhcmUgZm9yIGRpZmZlcmVudAogKiAgbGVuZ3RoIE9JRHMsIHNpbmNlIHRoZSBsZW5ndGggaXMgY2hlY2tlZCBmaXJzdCBhbmQgaWYgIT0gcmV0dXJucwogKiAgaW1tZWRpYXRlbHkuICBNaWdodCBiZSB2ZXJ5IHNsaWdobHkgZmFzdGVyIGlmIGxlbmd0aHMgYXJlID09LgogKiBAcGFyYW0gaW5fbmFtZTEgQSBwb2ludGVyIHRvIHRoZSBmaXJzdCBvaWQuCiAqIEBwYXJhbSBsZW4xICAgICBsZW5ndGggb2YgdGhlIGZpcnN0IE9JRCAoaW4gc2VnbWVudHMsIG5vdCBieXRlcykKICogQHBhcmFtIGluX25hbWUyIEEgcG9pbnRlciB0byB0aGUgc2Vjb25kIG9pZC4KICogQHBhcmFtIGxlbjIgICAgIGxlbmd0aCBvZiB0aGUgc2Vjb25kIE9JRCAoaW4gc2VnbWVudHMsIG5vdCBieXRlcykKICogQHJldHVybiAwIGlmIHRoZXkgYXJlIGVxdWFsLCAxIGlmIHRoZXkgYXJlIG5vdC4KICovIAppbnQKbmV0c25tcF9vaWRfZXF1YWxzKGNvbnN0IG9pZCAqIGluX25hbWUxLAogICAgICAgICAgICAgICAgICAgc2l6ZV90IGxlbjEsIGNvbnN0IG9pZCAqIGluX25hbWUyLCBzaXplX3QgbGVuMikKewogICAgcmVnaXN0ZXIgY29uc3Qgb2lkICpuYW1lMSA9IGluX25hbWUxOwogICAgcmVnaXN0ZXIgY29uc3Qgb2lkICpuYW1lMiA9IGluX25hbWUyOwogICAgcmVnaXN0ZXIgaW50ICAgIGxlbiA9IGxlbjE7CgogICAgLyoKICAgICAqIGxlbiA9IG1pbmltdW0gb2YgbGVuMSBhbmQgbGVuMiAKICAgICAqLwogICAgaWYgKGxlbjEgIT0gbGVuMikKICAgICAgICByZXR1cm4gMTsKICAgIC8qCiAgICAgKiBIYW5kbGUgJ251bGwnIE9JRHMKICAgICAqLwogICAgaWYgKGxlbjEgPT0gMCkKICAgICAgICByZXR1cm4gMDsgICAvKiBUd28gbnVsbCBPSURzIGFyZSAodHJpdmlhbGx5KSB0aGUgc2FtZSAqLwogICAgaWYgKCFuYW1lMSB8fCAhbmFtZTIpCiAgICAgICAgcmV0dXJuIDE7ICAgLyogT3RoZXJ3aXNlIHNvbWV0aGluZydzIHdyb25nLCBzbyByZXBvcnQgYSBub24tbWF0Y2ggKi8KICAgIC8qCiAgICAgKiBmaW5kIGZpcnN0IG5vbi1tYXRjaGluZyBPSUQgCiAgICAgKi8KICAgIHdoaWxlIChsZW4tLSA+IDApIHsKICAgICAgICAvKgogICAgICAgICAqIHRoZXNlIG11c3QgYmUgZG9uZSBpbiBzZXBlcmF0ZSBjb21wYXJpc29ucywgc2luY2UKICAgICAgICAgKiBzdWJ0cmFjdGluZyB0aGVtIGFuZCB1c2luZyB0aGF0IHJlc3VsdCBoYXMgcHJvYmxlbXMgd2l0aAogICAgICAgICAqIHN1YmlkcyA+IDJeMzEuIAogICAgICAgICAqLwogICAgICAgIGlmICgqKG5hbWUxKyspICE9ICoobmFtZTIrKykpCiAgICAgICAgICAgIHJldHVybiAxOwogICAgfQogICAgcmV0dXJuIDA7Cn0KCi8qKiBJZGVudGljYWwgdG8gbmV0c25tcF9vaWRfZXF1YWxzLCBleGNlcHQgb25seSB0aGUgbGVuZ3RoIHVwIHRvIGxlbjEgaXMgY29tcGFyZWQuCiAqIEZ1bmN0aW9uYWxseSwgdGhpcyBkZXRlcm1pbmVzIGlmIGluX25hbWUyIGlzIGVxdWFsIG9yIGEgc3VidHJlZSBvZiBpbl9uYW1lMQogKiBAcGFyYW0gaW5fbmFtZTEgQSBwb2ludGVyIHRvIHRoZSBmaXJzdCBvaWQuCiAqIEBwYXJhbSBsZW4xICAgICBsZW5ndGggb2YgdGhlIGZpcnN0IE9JRCAoaW4gc2VnbWVudHMsIG5vdCBieXRlcykKICogQHBhcmFtIGluX25hbWUyIEEgcG9pbnRlciB0byB0aGUgc2Vjb25kIG9pZC4KICogQHBhcmFtIGxlbjIgICAgIGxlbmd0aCBvZiB0aGUgc2Vjb25kIE9JRCAoaW4gc2VnbWVudHMsIG5vdCBieXRlcykKICogQHJldHVybiAwIGlmIG9uZSBpcyBhIGNvbW1vbiBwcmVmaXggb2YgdGhlIG90aGVyLgogKi8gCmludApuZXRzbm1wX29pZF9pc19zdWJ0cmVlKGNvbnN0IG9pZCAqIGluX25hbWUxLAogICAgICAgICAgICAgICAgICAgICAgIHNpemVfdCBsZW4xLCBjb25zdCBvaWQgKiBpbl9uYW1lMiwgc2l6ZV90IGxlbjIpCnsKICAgIGlmIChsZW4xID4gbGVuMikKICAgICAgICByZXR1cm4gMTsKCiAgICBpZiAobWVtY21wKGluX25hbWUxLCBpbl9uYW1lMiwgbGVuMSAqIHNpemVvZihvaWQpKSkKICAgICAgICByZXR1cm4gMTsKCiAgICByZXR1cm4gMDsKfQoKLyoqIEdpdmVuIHR3byBPSURzLCBkZXRlcm1pbmUgdGhlIGNvbW1vbiBwcmVmaXggdG8gdGhlbSBib3RoLgogKiBAcGFyYW0gaW5fbmFtZTEgQSBwb2ludGVyIHRvIHRoZSBmaXJzdCBvaWQuCiAqIEBwYXJhbSBsZW4xICAgICBMZW5ndGggb2YgdGhlIGZpcnN0IG9pZC4KICogQHBhcmFtIGluX25hbWUyIEEgcG9pbnRlciB0byB0aGUgc2Vjb25kIG9pZC4KICogQHBhcmFtIGxlbjIgICAgIExlbmd0aCBvZiB0aGUgc2Vjb25kIG9pZC4KICogQHJldHVybiAgICAgICAgIGxlbmd0aCBvZiBjb21tb24gcHJlZml4CiAqICAgICAgICAgICAgICAgICAwIGlmIG5vIGNvbW1vbiBwcmVmaXgsIC0xIG9uIGVycm9yLgogKi8KaW50Cm5ldHNubXBfb2lkX2ZpbmRfcHJlZml4KGNvbnN0IG9pZCAqIGluX25hbWUxLCBzaXplX3QgbGVuMSwKICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgb2lkICogaW5fbmFtZTIsIHNpemVfdCBsZW4yKQp7CiAgICBpbnQgaTsKICAgIHNpemVfdCBtaW5fc2l6ZTsKCiAgICBpZiAoIWluX25hbWUxIHx8ICFpbl9uYW1lMiB8fCAhbGVuMSB8fCAhbGVuMikKICAgICAgICByZXR1cm4gLTE7CgogICAgaWYgKGluX25hbWUxWzBdICE9IGluX25hbWUyWzBdKQogICAgICAgIHJldHVybiAwOyAgIC8qIE5vIG1hdGNoICovCiAgICBtaW5fc2l6ZSA9IFNOTVBfTUlOKGxlbjEsIGxlbjIpOwogICAgZm9yKGkgPSAwOyBpIDwgKGludCltaW5fc2l6ZTsgaSsrKSB7CiAgICAgICAgaWYgKGluX25hbWUxW2ldICE9IGluX25hbWUyW2ldKQogICAgICAgICAgICByZXR1cm4gaTsgICAgLyogJ+0nIGlzIHRoZSBmaXJzdCBkaWZmZXJpbmcgc3ViaWRlbnRpZmllcgogICAgICAgICAgICAgICAgICAgICAgICAgICAgU28gdGhlIGNvbW1vbiBwcmVmaXggaXMgMC4uKGktMSksIG9mIGxlbmd0aCBpICovCiAgICB9CiAgICByZXR1cm4gbWluX3NpemU7CS8qIFRoZSBzaG9ydGVyIE9JRCBpcyBhIHByZWZpeCBvZiB0aGUgbG9uZ2VyLCBhbmQKICAgICAgICAgICAgICAgICAgICAgICAgICAgaGVuY2UgaXMgcHJlY2lzZWx5IHRoZSBjb21tb24gcHJlZml4IG9mIHRoZSB0d28uCiAgICAgICAgICAgICAgICAgICAgICAgICAgIFJldHVybiBpdHMgbGVuZ3RoLiAqLwp9CgpzdGF0aWMgaW50IF9jaGVja19yYW5nZShzdHJ1Y3QgdHJlZSAqdHAsIGxvbmcgbHRtcCwgaW50ICpyZXNwdHIsCgkgICAgICAgICAgICAgICAgY29uc3QgY2hhciAqZXJybXNnKQp7CiAgICBjaGFyICpjcCAgID0gTlVMTDsKICAgIGNoYXIgKnRlbXAgPSBOVUxMOwogICAgaW50ICAgdGVtcF9sZW4gPSAwOwogICAgaW50IGNoZWNrID0gIW5ldHNubXBfZHNfZ2V0X2Jvb2xlYW4oTkVUU05NUF9EU19MSUJSQVJZX0lELAoJICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBORVRTTk1QX0RTX0xJQl9ET05UX0NIRUNLX1JBTkdFKTsKICAKICAgIGlmIChjaGVjayAmJiB0cCAmJiB0cC0+cmFuZ2VzKSB7CglzdHJ1Y3QgcmFuZ2VfbGlzdCAqcnAgPSB0cC0+cmFuZ2VzOwoJd2hpbGUgKHJwKSB7CgkgICAgaWYgKHJwLT5sb3cgPD0gbHRtcCAmJiBsdG1wIDw9IHJwLT5oaWdoKSBicmVhazsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIEFsbG93IGZvdXIgZGlnaXRzIHBlciByYW5nZSB2YWx1ZSAqLwogICAgICAgICAgICB0ZW1wX2xlbiArPSAoKHJwLT5sb3cgIT0gcnAtPmhpZ2gpID8gMTQgOiA4ICk7CgkgICAgcnAgPSBycC0+bmV4dDsKCX0KCWlmICghcnApIHsKCSAgICAqcmVzcHRyID0gU05NUEVSUl9SQU5HRTsKICAgICAgICAgICAgdGVtcCA9IChjaGFyICopbWFsbG9jKCB0ZW1wX2xlbitzdHJsZW4oZXJybXNnKSs3KTsKICAgICAgICAgICAgaWYgKCB0ZW1wICkgewogICAgICAgICAgICAgICAgLyogQXBwZW5kIHRoZSBEaXNwbGF5IEhpbnQgcmFuZ2UgaW5mb3JtYXRpb24gdG8gdGhlIGVycm9yIG1lc3NhZ2UgKi8KICAgICAgICAgICAgICAgIHNwcmludGYoIHRlbXAsICIlcyA6OiB7IiwgZXJybXNnICk7CiAgICAgICAgICAgICAgICBjcCA9IHRlbXArKHN0cmxlbih0ZW1wKSk7CiAgICAgICAgICAgICAgICBmb3IgKCBycCA9IHRwLT5yYW5nZXM7IHJwOyBycD1ycC0+bmV4dCApIHsKICAgICAgICAgICAgICAgICAgICBpZiAoIHJwLT5sb3cgIT0gcnAtPmhpZ2ggKSAKICAgICAgICAgICAgICAgICAgICAgICAgc3ByaW50ZiggY3AsICIoJWQuLiVkKSwgIiwgcnAtPmxvdywgcnAtPmhpZ2ggKTsKICAgICAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgICAgIHNwcmludGYoIGNwLCAiKCVkKSwgIiwgcnAtPmxvdyApOwogICAgICAgICAgICAgICAgICAgIGNwICs9IHN0cmxlbihjcCk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAqKGNwLTIpID0gJ30nOyAgIC8qIFJlcGxhY2UgdGhlIGZpbmFsIGNvbW1hIHdpdGggYSAnfScgKi8KICAgICAgICAgICAgICAgICooY3AtMSkgPSAwOwoJICAgICAgICBzbm1wX3NldF9kZXRhaWwodGVtcCk7CgkgICAgICAgIGZyZWUodGVtcCk7CiAgICAgICAgICAgIH0KCSAgICByZXR1cm4gMDsKCX0KICAgIH0KICAgIGZyZWUodGVtcCk7CiAgICByZXR1cm4gMTsKfQogICAgICAgIAoKLyoKICogQWRkIGEgdmFyaWFibGUgd2l0aCB0aGUgcmVxdWVzdGVkIG5hbWUgdG8gdGhlIGVuZCBvZiB0aGUgbGlzdCBvZgogKiB2YXJpYWJsZXMgZm9yIHRoaXMgcGR1LgogKi8KbmV0c25tcF92YXJpYWJsZV9saXN0ICoKc25tcF9wZHVfYWRkX3ZhcmlhYmxlKG5ldHNubXBfcGR1ICpwZHUsCiAgICAgICAgICAgICAgICAgICAgICBjb25zdCBvaWQgKiBuYW1lLAogICAgICAgICAgICAgICAgICAgICAgc2l6ZV90IG5hbWVfbGVuZ3RoLAogICAgICAgICAgICAgICAgICAgICAgdV9jaGFyIHR5cGUsIGNvbnN0IHZvaWQgKiB2YWx1ZSwgc2l6ZV90IGxlbikKewogICAgcmV0dXJuIHNubXBfdmFybGlzdF9hZGRfdmFyaWFibGUoJnBkdS0+dmFyaWFibGVzLCBuYW1lLCBuYW1lX2xlbmd0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHR5cGUsIHZhbHVlLCBsZW4pOwp9CgovKgogKiBBZGQgYSB2YXJpYWJsZSB3aXRoIHRoZSByZXF1ZXN0ZWQgbmFtZSB0byB0aGUgZW5kIG9mIHRoZSBsaXN0IG9mCiAqIHZhcmlhYmxlcyBmb3IgdGhpcyBwZHUuCiAqLwpuZXRzbm1wX3ZhcmlhYmxlX2xpc3QgKgpzbm1wX3Zhcmxpc3RfYWRkX3ZhcmlhYmxlKG5ldHNubXBfdmFyaWFibGVfbGlzdCAqKiB2YXJsaXN0LAogICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG9pZCAqIG5hbWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgc2l6ZV90IG5hbWVfbGVuZ3RoLAogICAgICAgICAgICAgICAgICAgICAgICAgIHVfY2hhciB0eXBlLCBjb25zdCB2b2lkICogdmFsdWUsIHNpemVfdCBsZW4pCnsKICAgIG5ldHNubXBfdmFyaWFibGVfbGlzdCAqdmFycywgKnZ0bXA7CiAgICBpbnQgcmM7CgogICAgaWYgKHZhcmxpc3QgPT0gTlVMTCkKICAgICAgICByZXR1cm4gTlVMTDsKCiAgICB2YXJzID0gU05NUF9NQUxMT0NfVFlQRURFRihuZXRzbm1wX3ZhcmlhYmxlX2xpc3QpOwogICAgaWYgKHZhcnMgPT0gTlVMTCkKICAgICAgICByZXR1cm4gTlVMTDsKCiAgICB2YXJzLT50eXBlID0gdHlwZTsKCiAgICByYyA9IHNubXBfc2V0X3Zhcl92YWx1ZSggdmFycywgdmFsdWUsIGxlbiApOwogICAgaWYgKCggMCAhPSByYyApIHx8CiAgICAgICAgKG5hbWUgIT0gTlVMTCAmJiBzbm1wX3NldF92YXJfb2JqaWQodmFycywgbmFtZSwgbmFtZV9sZW5ndGgpKSkgewogICAgICAgIHNubXBfZnJlZV92YXIodmFycyk7CiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICB9CgogICAgLyoKICAgICAqIHB1dCBvbmx5IHF1YWxpZmllZCB2YXJpYWJsZSBvbnRvIHZhcmxpc3QgCiAgICAgKi8KICAgIGlmICgqdmFybGlzdCA9PSBOVUxMKSB7CiAgICAgICAgKnZhcmxpc3QgPSB2YXJzOwogICAgfSBlbHNlIHsKICAgICAgICBmb3IgKHZ0bXAgPSAqdmFybGlzdDsgdnRtcC0+bmV4dF92YXJpYWJsZTsKICAgICAgICAgICAgIHZ0bXAgPSB2dG1wLT5uZXh0X3ZhcmlhYmxlKTsKCiAgICAgICAgdnRtcC0+bmV4dF92YXJpYWJsZSA9IHZhcnM7CiAgICB9CgogICAgcmV0dXJuIHZhcnM7Cn0KCgoKLyoKICogQWRkIGEgdmFyaWFibGUgd2l0aCB0aGUgcmVxdWVzdGVkIG5hbWUgdG8gdGhlIGVuZCBvZiB0aGUgbGlzdCBvZgogKiB2YXJpYWJsZXMgZm9yIHRoaXMgcGR1LgogKiBSZXR1cm5zOgogKiBtYXkgc2V0IHRoZXNlIGVycm9yIHR5cGVzIDoKICogU05NUEVSUl9SQU5HRSAtIHR5cGUsIHZhbHVlLCBvciBsZW5ndGggbm90IGZvdW5kIG9yIG91dCBvZiByYW5nZQogKiBTTk1QRVJSX1ZBTFVFIC0gdmFsdWUgaXMgbm90IGNvcnJlY3QKICogU05NUEVSUl9WQVJfVFlQRSAtIHR5cGUgaXMgbm90IGNvcnJlY3QKICogU05NUEVSUl9CQURfTkFNRSAtIG5hbWUgaXMgbm90IGZvdW5kCiAqCiAqIHJldHVybnMgMCBpZiBzdWNjZXNzLCBlcnJvciBpZiBmYWlsdXJlLgogKi8KaW50CnNubXBfYWRkX3ZhcihuZXRzbm1wX3BkdSAqcGR1LAogICAgICAgICAgICAgY29uc3Qgb2lkICogbmFtZSwgc2l6ZV90IG5hbWVfbGVuZ3RoLCBjaGFyIHR5cGUsIGNvbnN0IGNoYXIgKnZhbHVlKQp7CiAgICBjaGFyICAgICAgICAgICAqc3Q7CiAgICBjb25zdCBjaGFyICAgICAqY3A7CiAgICBjaGFyICAgICAgICAgICAqZWNwLCAqdnA7CiAgICBpbnQgICAgICAgICAgICAgcmVzdWx0ID0gU05NUEVSUl9TVUNDRVNTOwojaWZuZGVmIE5FVFNOTVBfRElTQUJMRV9NSUJfTE9BRElORwogICAgaW50ICAgICAgICAgICAgIGNoZWNrID0gIW5ldHNubXBfZHNfZ2V0X2Jvb2xlYW4oTkVUU05NUF9EU19MSUJSQVJZX0lELAoJCQkJCSAgICAgTkVUU05NUF9EU19MSUJfRE9OVF9DSEVDS19SQU5HRSk7CiAgICBpbnQgICAgICAgICAgICAgZG9faGludCA9ICFuZXRzbm1wX2RzX2dldF9ib29sZWFuKE5FVFNOTVBfRFNfTElCUkFSWV9JRCwKCQkJCQkgICAgIE5FVFNOTVBfRFNfTElCX05PX0RJU1BMQVlfSElOVCk7CiAgICB1X2NoYXIgICAgICAgICAqaGludHB0cjsKICAgIHN0cnVjdCB0cmVlICAgICp0cDsKI2VuZGlmIC8qIE5FVFNOTVBfRElTQUJMRV9NSUJfTE9BRElORyAqLwogICAgdV9jaGFyICAgICAgICAgKmJ1ZiA9IE5VTEw7CiAgICBjb25zdCB1X2NoYXIgICAqYnVmX3B0ciA9IE5VTEw7CiAgICBzaXplX3QgICAgICAgICAgYnVmX2xlbiA9IDAsIHZhbHVlX2xlbiA9IDAsIHRpbnQ7CiAgICBpbl9hZGRyX3QgICAgICAgYXRtcDsKICAgIGxvbmcgICAgICAgICAgICBsdG1wOwogICAgaW50ICAgICAgICAgICAgIGl0bXA7CiAgICBzdHJ1Y3QgZW51bV9saXN0ICplcDsKI2lmZGVmIE5FVFNOTVBfV0lUSF9PUEFRVUVfU1BFQ0lBTF9UWVBFUwogICAgZG91YmxlICAgICAgICAgIGR0bXA7CiAgICBmbG9hdCAgICAgICAgICAgZnRtcDsKI2VuZGlmICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBORVRTTk1QX1dJVEhfT1BBUVVFX1NQRUNJQUxfVFlQRVMgKi8KICAgIHN0cnVjdCBjb3VudGVyNjQgYzY0dG1wOwoKI2lmbmRlZiBORVRTTk1QX0RJU0FCTEVfTUlCX0xPQURJTkcKICAgIHRwID0gZ2V0X3RyZWUobmFtZSwgbmFtZV9sZW5ndGgsIGdldF90cmVlX2hlYWQoKSk7CiAgICBpZiAoIXRwIHx8ICF0cC0+dHlwZSB8fCB0cC0+dHlwZSA+IFRZUEVfU0lNUExFX0xBU1QpIHsKICAgICAgICBjaGVjayA9IDA7CiAgICB9CiAgICBpZiAoISh0cCAmJiB0cC0+aGludCkpCglkb19oaW50ID0gMDsKCiAgICBpZiAodHAgJiYgdHlwZSA9PSAnPScpIHsKICAgICAgICAvKgogICAgICAgICAqIGdlbmVyaWMgYXNzaWdubWVudCAtIGxldCB0aGUgdHJlZSBub2RlIGRlY2lkZSB2YWx1ZSBmb3JtYXQgCiAgICAgICAgICovCiAgICAgICAgc3dpdGNoICh0cC0+dHlwZSkgewogICAgICAgIGNhc2UgVFlQRV9JTlRFR0VSOgogICAgICAgIGNhc2UgVFlQRV9JTlRFR0VSMzI6CiAgICAgICAgICAgIHR5cGUgPSAnaSc7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgVFlQRV9HQVVHRToKICAgICAgICBjYXNlIFRZUEVfVU5TSUdORUQzMjoKICAgICAgICAgICAgdHlwZSA9ICd1JzsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBUWVBFX1VJTlRFR0VSOgogICAgICAgICAgICB0eXBlID0gJzMnOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFRZUEVfQ09VTlRFUjoKICAgICAgICAgICAgdHlwZSA9ICdjJzsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBUWVBFX0NPVU5URVI2NDoKICAgICAgICAgICAgdHlwZSA9ICdDJzsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBUWVBFX1RJTUVUSUNLUzoKICAgICAgICAgICAgdHlwZSA9ICd0JzsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBUWVBFX09DVEVUU1RSOgogICAgICAgICAgICB0eXBlID0gJ3MnOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFRZUEVfQklUU1RSSU5HOgogICAgICAgICAgICB0eXBlID0gJ2InOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFRZUEVfSVBBRERSOgogICAgICAgICAgICB0eXBlID0gJ2EnOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFRZUEVfT0JKSUQ6CiAgICAgICAgICAgIHR5cGUgPSAnbyc7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgIH0KI2VuZGlmIC8qIE5FVFNOTVBfRElTQUJMRV9NSUJfTE9BRElORyAqLwoKICAgIHN3aXRjaCAodHlwZSkgewogICAgY2FzZSAnaSc6CiNpZm5kZWYgTkVUU05NUF9ESVNBQkxFX01JQl9MT0FESU5HCiAgICAgICAgaWYgKGNoZWNrICYmIHRwLT50eXBlICE9IFRZUEVfSU5URUdFUgogICAgICAgICAgICAmJiB0cC0+dHlwZSAhPSBUWVBFX0lOVEVHRVIzMikgewogICAgICAgICAgICB2YWx1ZSA9ICJJTlRFR0VSIjsKICAgICAgICAgICAgcmVzdWx0ID0gU05NUEVSUl9WQUxVRTsKICAgICAgICAgICAgZ290byB0eXBlX2Vycm9yOwogICAgICAgIH0KI2VuZGlmIC8qIE5FVFNOTVBfRElTQUJMRV9NSUJfTE9BRElORyAqLwogICAgICAgIGlmICghKnZhbHVlKQogICAgICAgICAgICBnb3RvIGZhaWw7CiAgICAgICAgbHRtcCA9IHN0cnRvbCh2YWx1ZSwgJmVjcCwgMTApOwogICAgICAgIGlmICgqZWNwKSB7CiNpZm5kZWYgTkVUU05NUF9ESVNBQkxFX01JQl9MT0FESU5HCiAgICAgICAgICAgIGVwID0gdHAgPyB0cC0+ZW51bXMgOiBOVUxMOwogICAgICAgICAgICB3aGlsZSAoZXApIHsKICAgICAgICAgICAgICAgIGlmIChzdHJjbXAodmFsdWUsIGVwLT5sYWJlbCkgPT0gMCkgewogICAgICAgICAgICAgICAgICAgIGx0bXAgPSBlcC0+dmFsdWU7CiAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlcCA9IGVwLT5uZXh0OwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmICghZXApIHsKI2VuZGlmIC8qIE5FVFNOTVBfRElTQUJMRV9NSUJfTE9BRElORyAqLwogICAgICAgICAgICAgICAgcmVzdWx0ID0gU05NUEVSUl9SQU5HRTsgICAvKiA/PyBvciBTTk1QRVJSX1ZBTFVFOyAqLwogICAgICAgICAgICAgICAgc25tcF9zZXRfZGV0YWlsKHZhbHVlKTsKICAgICAgICAgICAgICAgIGJyZWFrOwojaWZuZGVmIE5FVFNOTVBfRElTQUJMRV9NSUJfTE9BRElORwogICAgICAgICAgICB9CiNlbmRpZiAvKiBORVRTTk1QX0RJU0FCTEVfTUlCX0xPQURJTkcgKi8KICAgICAgICB9CgojaWZuZGVmIE5FVFNOTVBfRElTQUJMRV9NSUJfTE9BRElORwogICAgICAgIGlmICghX2NoZWNrX3JhbmdlKHRwLCBsdG1wLCAmcmVzdWx0LCB2YWx1ZSkpCiAgICAgICAgICAgIGJyZWFrOwojZW5kaWYgLyogTkVUU05NUF9ESVNBQkxFX01JQl9MT0FESU5HICovCiAgICAgICAgc25tcF9wZHVfYWRkX3ZhcmlhYmxlKHBkdSwgbmFtZSwgbmFtZV9sZW5ndGgsIEFTTl9JTlRFR0VSLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmbHRtcCwgc2l6ZW9mKGx0bXApKTsKICAgICAgICBicmVhazsKCiAgICBjYXNlICd1JzoKI2lmbmRlZiBORVRTTk1QX0RJU0FCTEVfTUlCX0xPQURJTkcKICAgICAgICBpZiAoY2hlY2sgJiYgdHAtPnR5cGUgIT0gVFlQRV9HQVVHRSAmJiB0cC0+dHlwZSAhPSBUWVBFX1VOU0lHTkVEMzIpIHsKICAgICAgICAgICAgdmFsdWUgPSAiVW5zaWduZWQzMiI7CiAgICAgICAgICAgIHJlc3VsdCA9IFNOTVBFUlJfVkFMVUU7CiAgICAgICAgICAgIGdvdG8gdHlwZV9lcnJvcjsKICAgICAgICB9CiNlbmRpZiAvKiBORVRTTk1QX0RJU0FCTEVfTUlCX0xPQURJTkcgKi8KICAgICAgICBsdG1wID0gc3RydG91bCh2YWx1ZSwgJmVjcCwgMTApOwogICAgICAgIGlmICgqdmFsdWUgJiYgISplY3ApCiAgICAgICAgICAgIHNubXBfcGR1X2FkZF92YXJpYWJsZShwZHUsIG5hbWUsIG5hbWVfbGVuZ3RoLCBBU05fVU5TSUdORUQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmbHRtcCwgc2l6ZW9mKGx0bXApKTsKICAgICAgICBlbHNlCiAgICAgICAgICAgIGdvdG8gZmFpbDsKICAgICAgICBicmVhazsKCiAgICBjYXNlICczJzoKI2lmbmRlZiBORVRTTk1QX0RJU0FCTEVfTUlCX0xPQURJTkcKICAgICAgICBpZiAoY2hlY2sgJiYgdHAtPnR5cGUgIT0gVFlQRV9VSU5URUdFUikgewogICAgICAgICAgICB2YWx1ZSA9ICJVSW50ZWdlcjMyIjsKICAgICAgICAgICAgcmVzdWx0ID0gU05NUEVSUl9WQUxVRTsKICAgICAgICAgICAgZ290byB0eXBlX2Vycm9yOwogICAgICAgIH0KI2VuZGlmIC8qIE5FVFNOTVBfRElTQUJMRV9NSUJfTE9BRElORyAqLwogICAgICAgIGx0bXAgPSBzdHJ0b3VsKHZhbHVlLCAmZWNwLCAxMCk7CiAgICAgICAgaWYgKCp2YWx1ZSAmJiAhKmVjcCkKICAgICAgICAgICAgc25tcF9wZHVfYWRkX3ZhcmlhYmxlKHBkdSwgbmFtZSwgbmFtZV9sZW5ndGgsIEFTTl9VSU5URUdFUiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZsdG1wLCBzaXplb2YobHRtcCkpOwogICAgICAgIGVsc2UKICAgICAgICAgICAgZ290byBmYWlsOwogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgJ2MnOgojaWZuZGVmIE5FVFNOTVBfRElTQUJMRV9NSUJfTE9BRElORwogICAgICAgIGlmIChjaGVjayAmJiB0cC0+dHlwZSAhPSBUWVBFX0NPVU5URVIpIHsKICAgICAgICAgICAgdmFsdWUgPSAiQ291bnRlcjMyIjsKICAgICAgICAgICAgcmVzdWx0ID0gU05NUEVSUl9WQUxVRTsKICAgICAgICAgICAgZ290byB0eXBlX2Vycm9yOwogICAgICAgIH0KI2VuZGlmIC8qIE5FVFNOTVBfRElTQUJMRV9NSUJfTE9BRElORyAqLwogICAgICAgIGx0bXAgPSBzdHJ0b3VsKHZhbHVlLCAmZWNwLCAxMCk7CiAgICAgICAgaWYgKCp2YWx1ZSAmJiAhKmVjcCkKICAgICAgICAgICAgc25tcF9wZHVfYWRkX3ZhcmlhYmxlKHBkdSwgbmFtZSwgbmFtZV9sZW5ndGgsIEFTTl9DT1VOVEVSLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJmx0bXAsIHNpemVvZihsdG1wKSk7CiAgICAgICAgZWxzZQogICAgICAgICAgICBnb3RvIGZhaWw7CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSAnQyc6CiNpZm5kZWYgTkVUU05NUF9ESVNBQkxFX01JQl9MT0FESU5HCiAgICAgICAgaWYgKGNoZWNrICYmIHRwLT50eXBlICE9IFRZUEVfQ09VTlRFUjY0KSB7CiAgICAgICAgICAgIHZhbHVlID0gIkNvdW50ZXI2NCI7CiAgICAgICAgICAgIHJlc3VsdCA9IFNOTVBFUlJfVkFMVUU7CiAgICAgICAgICAgIGdvdG8gdHlwZV9lcnJvcjsKICAgICAgICB9CiNlbmRpZiAvKiBORVRTTk1QX0RJU0FCTEVfTUlCX0xPQURJTkcgKi8KICAgICAgICBpZiAocmVhZDY0KCZjNjR0bXAsIHZhbHVlKSkKICAgICAgICAgICAgc25tcF9wZHVfYWRkX3ZhcmlhYmxlKHBkdSwgbmFtZSwgbmFtZV9sZW5ndGgsIEFTTl9DT1VOVEVSNjQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmYzY0dG1wLCBzaXplb2YoYzY0dG1wKSk7CiAgICAgICAgZWxzZQogICAgICAgICAgICBnb3RvIGZhaWw7CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSAndCc6CiNpZm5kZWYgTkVUU05NUF9ESVNBQkxFX01JQl9MT0FESU5HCiAgICAgICAgaWYgKGNoZWNrICYmIHRwLT50eXBlICE9IFRZUEVfVElNRVRJQ0tTKSB7CiAgICAgICAgICAgIHZhbHVlID0gIlRpbWV0aWNrcyI7CiAgICAgICAgICAgIHJlc3VsdCA9IFNOTVBFUlJfVkFMVUU7CiAgICAgICAgICAgIGdvdG8gdHlwZV9lcnJvcjsKICAgICAgICB9CiNlbmRpZiAvKiBORVRTTk1QX0RJU0FCTEVfTUlCX0xPQURJTkcgKi8KICAgICAgICBsdG1wID0gc3RydG91bCh2YWx1ZSwgJmVjcCwgMTApOwogICAgICAgIGlmICgqdmFsdWUgJiYgISplY3ApCiAgICAgICAgICAgIHNubXBfcGR1X2FkZF92YXJpYWJsZShwZHUsIG5hbWUsIG5hbWVfbGVuZ3RoLCBBU05fVElNRVRJQ0tTLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJmx0bXAsIHNpemVvZihsb25nKSk7CiAgICAgICAgZWxzZQogICAgICAgICAgICBnb3RvIGZhaWw7CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSAnYSc6CiNpZm5kZWYgTkVUU05NUF9ESVNBQkxFX01JQl9MT0FESU5HCiAgICAgICAgaWYgKGNoZWNrICYmIHRwLT50eXBlICE9IFRZUEVfSVBBRERSKSB7CiAgICAgICAgICAgIHZhbHVlID0gIklwQWRkcmVzcyI7CiAgICAgICAgICAgIHJlc3VsdCA9IFNOTVBFUlJfVkFMVUU7CiAgICAgICAgICAgIGdvdG8gdHlwZV9lcnJvcjsKICAgICAgICB9CiNlbmRpZiAvKiBORVRTTk1QX0RJU0FCTEVfTUlCX0xPQURJTkcgKi8KICAgICAgICBhdG1wID0gaW5ldF9hZGRyKHZhbHVlKTsKICAgICAgICBpZiAoYXRtcCAhPSAoaW5fYWRkcl90KSAtMSB8fCAhc3RyY21wKHZhbHVlLCAiMjU1LjI1NS4yNTUuMjU1IikpCiAgICAgICAgICAgIHNubXBfcGR1X2FkZF92YXJpYWJsZShwZHUsIG5hbWUsIG5hbWVfbGVuZ3RoLCBBU05fSVBBRERSRVNTLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJmF0bXAsIHNpemVvZihhdG1wKSk7CiAgICAgICAgZWxzZQogICAgICAgICAgICBnb3RvIGZhaWw7CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSAnbyc6CiNpZm5kZWYgTkVUU05NUF9ESVNBQkxFX01JQl9MT0FESU5HCiAgICAgICAgaWYgKGNoZWNrICYmIHRwLT50eXBlICE9IFRZUEVfT0JKSUQpIHsKICAgICAgICAgICAgdmFsdWUgPSAiT0JKRUNUIElERU5USUZJRVIiOwogICAgICAgICAgICByZXN1bHQgPSBTTk1QRVJSX1ZBTFVFOwogICAgICAgICAgICBnb3RvIHR5cGVfZXJyb3I7CiAgICAgICAgfQojZW5kaWYgLyogTkVUU05NUF9ESVNBQkxFX01JQl9MT0FESU5HICovCiAgICAgICAgaWYgKChidWYgPSAodV9jaGFyICopbWFsbG9jKHNpemVvZihvaWQpICogTUFYX09JRF9MRU4pKSA9PSBOVUxMKSB7CiAgICAgICAgICAgIHJlc3VsdCA9IFNOTVBFUlJfTUFMTE9DOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHRpbnQgPSBNQVhfT0lEX0xFTjsKICAgICAgICAgICAgaWYgKHNubXBfcGFyc2Vfb2lkKHZhbHVlLCAob2lkICopIGJ1ZiwgJnRpbnQpKSB7CiAgICAgICAgICAgICAgICBzbm1wX3BkdV9hZGRfdmFyaWFibGUocGR1LCBuYW1lLCBuYW1lX2xlbmd0aCwgQVNOX09CSkVDVF9JRCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBidWYsIHNpemVvZihvaWQpICogdGludCk7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICByZXN1bHQgPSBzbm1wX2Vycm5vOyAgICAvKk1UQ1JJVElDQUxfUkVTT1VSQ0UgKi8KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBicmVhazsKCiAgICBjYXNlICdzJzoKICAgIGNhc2UgJ3gnOgogICAgY2FzZSAnZCc6CiNpZm5kZWYgTkVUU05NUF9ESVNBQkxFX01JQl9MT0FESU5HCiAgICAgICAgaWYgKGNoZWNrICYmIHRwLT50eXBlICE9IFRZUEVfT0NURVRTVFIgJiYgdHAtPnR5cGUgIT0gVFlQRV9CSVRTVFJJTkcpIHsKICAgICAgICAgICAgdmFsdWUgPSAiT0NURVQgU1RSSU5HIjsKICAgICAgICAgICAgcmVzdWx0ID0gU05NUEVSUl9WQUxVRTsKICAgICAgICAgICAgZ290byB0eXBlX2Vycm9yOwogICAgICAgIH0KCWlmICgncycgPT0gdHlwZSAmJiBkb19oaW50ICYmICFwYXJzZV9vY3RldF9oaW50KHRwLT5oaW50LCB2YWx1ZSwgJmhpbnRwdHIsICZpdG1wKSkgewogICAgICAgICAgICBpZiAoX2NoZWNrX3JhbmdlKHRwLCBpdG1wLCAmcmVzdWx0LCAiVmFsdWUgZG9lcyBub3QgbWF0Y2ggRElTUExBWS1ISU5UIikpIHsKICAgICAgICAgICAgICAgIHNubXBfcGR1X2FkZF92YXJpYWJsZShwZHUsIG5hbWUsIG5hbWVfbGVuZ3RoLCBBU05fT0NURVRfU1RSLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGhpbnRwdHIsIGl0bXApOwogICAgICAgICAgICB9CiAgICAgICAgICAgIFNOTVBfRlJFRShoaW50cHRyKTsKICAgICAgICAgICAgaGludHB0ciA9IGJ1ZjsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQojZW5kaWYgLyogTkVUU05NUF9ESVNBQkxFX01JQl9MT0FESU5HICovCiAgICAgICAgaWYgKHR5cGUgPT0gJ2QnKSB7CiAgICAgICAgICAgIGlmICghc25tcF9kZWNpbWFsX3RvX2JpbmFyeQogICAgICAgICAgICAgICAgKCZidWYsICZidWZfbGVuLCAmdmFsdWVfbGVuLCAxLCB2YWx1ZSkpIHsKICAgICAgICAgICAgICAgIHJlc3VsdCA9IFNOTVBFUlJfVkFMVUU7CiAgICAgICAgICAgICAgICBzbm1wX3NldF9kZXRhaWwodmFsdWUpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYnVmX3B0ciA9IGJ1ZjsKICAgICAgICB9IGVsc2UgaWYgKHR5cGUgPT0gJ3gnKSB7CiAgICAgICAgICAgIGlmICghc25tcF9oZXhfdG9fYmluYXJ5KCZidWYsICZidWZfbGVuLCAmdmFsdWVfbGVuLCAxLCB2YWx1ZSkpIHsKICAgICAgICAgICAgICAgIHJlc3VsdCA9IFNOTVBFUlJfVkFMVUU7CiAgICAgICAgICAgICAgICBzbm1wX3NldF9kZXRhaWwodmFsdWUpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLyogaW5pdGlhbGl6ZSBpdG1wIHZhbHVlIHNvIHRoYXQgcmFuZ2UgY2hlY2sgYmVsb3cgd29ya3MgKi8KICAgICAgICAgICAgaXRtcCA9IHZhbHVlX2xlbjsKICAgICAgICAgICAgYnVmX3B0ciA9IGJ1ZjsKICAgICAgICB9IGVsc2UgaWYgKHR5cGUgPT0gJ3MnKSB7CiAgICAgICAgICAgIGJ1Zl9wdHIgPSAoY29uc3QgdV9jaGFyICopdmFsdWU7CiAgICAgICAgICAgIHZhbHVlX2xlbiA9IHN0cmxlbih2YWx1ZSk7CiAgICAgICAgfQojaWZuZGVmIE5FVFNOTVBfRElTQUJMRV9NSUJfTE9BRElORwogICAgICAgIGlmICghX2NoZWNrX3JhbmdlKHRwLCB2YWx1ZV9sZW4sICZyZXN1bHQsICJCYWQgc3RyaW5nIGxlbmd0aCIpKQogICAgICAgICAgICBicmVhazsKI2VuZGlmIC8qIE5FVFNOTVBfRElTQUJMRV9NSUJfTE9BRElORyAqLwogICAgICAgIHNubXBfcGR1X2FkZF92YXJpYWJsZShwZHUsIG5hbWUsIG5hbWVfbGVuZ3RoLCBBU05fT0NURVRfU1RSLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICBidWZfcHRyLCB2YWx1ZV9sZW4pOwogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgJ24nOgogICAgICAgIHNubXBfcGR1X2FkZF92YXJpYWJsZShwZHUsIG5hbWUsIG5hbWVfbGVuZ3RoLCBBU05fTlVMTCwgTlVMTCwgMCk7CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSAnYic6CiNpZm5kZWYgTkVUU05NUF9ESVNBQkxFX01JQl9MT0FESU5HCiAgICAgICAgaWYgKGNoZWNrICYmICh0cC0+dHlwZSAhPSBUWVBFX0JJVFNUUklORyB8fCAhdHAtPmVudW1zKSkgewogICAgICAgICAgICB2YWx1ZSA9ICJCSVRTIjsKICAgICAgICAgICAgcmVzdWx0ID0gU05NUEVSUl9WQUxVRTsKICAgICAgICAgICAgZ290byB0eXBlX2Vycm9yOwogICAgICAgIH0KI2VuZGlmIC8qIE5FVFNOTVBfRElTQUJMRV9NSUJfTE9BRElORyAqLwogICAgICAgIHRpbnQgPSAwOwogICAgICAgIGlmICgoYnVmID0gKHVfY2hhciAqKSBtYWxsb2MoMjU2KSkgPT0gTlVMTCkgewogICAgICAgICAgICByZXN1bHQgPSBTTk1QRVJSX01BTExPQzsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgYnVmX2xlbiA9IDI1NjsKICAgICAgICAgICAgbWVtc2V0KGJ1ZiwgMCwgYnVmX2xlbik7CiAgICAgICAgfQoKI2lmbmRlZiBORVRTTk1QX0RJU0FCTEVfTUlCX0xPQURJTkcKICAgICAgICBmb3IgKGVwID0gdHAgPyB0cC0+ZW51bXMgOiBOVUxMOyBlcDsgZXAgPSBlcC0+bmV4dCkgewogICAgICAgICAgICBpZiAoZXAtPnZhbHVlIC8gOCA+PSAoaW50KSB0aW50KSB7CiAgICAgICAgICAgICAgICB0aW50ID0gZXAtPnZhbHVlIC8gOCArIDE7CiAgICAgICAgICAgIH0KICAgICAgICB9CiNlbmRpZiAvKiBORVRTTk1QX0RJU0FCTEVfTUlCX0xPQURJTkcgKi8KCgl2cCA9IHN0cmR1cCh2YWx1ZSk7Cglmb3IgKGNwID0gc3RydG9rX3IodnAsICIgLFx0IiwgJnN0KTsgY3A7IGNwID0gc3RydG9rX3IoTlVMTCwgIiAsXHQiLCAmc3QpKSB7CiAgICAgICAgICAgIGludCAgICAgICAgICAgICBpeCwgYml0OwoKICAgICAgICAgICAgbHRtcCA9IHN0cnRvdWwoY3AsICZlY3AsIDApOwogICAgICAgICAgICBpZiAoKmVjcCAhPSAwKSB7CiNpZm5kZWYgTkVUU05NUF9ESVNBQkxFX01JQl9MT0FESU5HCiAgICAgICAgICAgICAgICBmb3IgKGVwID0gdHAgPyB0cC0+ZW51bXMgOiBOVUxMOyBlcCAhPSBOVUxMOyBlcCA9IGVwLT5uZXh0KSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKHN0cm5jbXAoZXAtPmxhYmVsLCBjcCwgc3RybGVuKGVwLT5sYWJlbCkpID09IDApIHsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKGVwICE9IE5VTEwpIHsKICAgICAgICAgICAgICAgICAgICBsdG1wID0gZXAtPnZhbHVlOwogICAgICAgICAgICAgICAgfSBlbHNlIHsKI2VuZGlmIC8qIE5FVFNOTVBfRElTQUJMRV9NSUJfTE9BRElORyAqLwogICAgICAgICAgICAgICAgICAgIHJlc3VsdCA9IFNOTVBFUlJfUkFOR0U7ICAgLyogPz8gb3IgU05NUEVSUl9WQUxVRTsgKi8KICAgICAgICAgICAgICAgICAgICBzbm1wX3NldF9kZXRhaWwoY3ApOwogICAgICAgICAgICAgICAgICAgIFNOTVBfRlJFRShidWYpOwoJCSAgICBTTk1QX0ZSRUUodnApOwogICAgICAgICAgICAgICAgICAgIGdvdG8gb3V0OwojaWZuZGVmIE5FVFNOTVBfRElTQUJMRV9NSUJfTE9BRElORwogICAgICAgICAgICAgICAgfQojZW5kaWYgLyogTkVUU05NUF9ESVNBQkxFX01JQl9MT0FESU5HICovCiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIGl4ID0gbHRtcCAvIDg7CiAgICAgICAgICAgIGlmIChpeCA+PSAoaW50KSB0aW50KSB7CiAgICAgICAgICAgICAgICB0aW50ID0gaXggKyAxOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChpeCA+PSAoaW50KWJ1Zl9sZW4gJiYgIXNubXBfcmVhbGxvYygmYnVmLCAmYnVmX2xlbikpIHsKICAgICAgICAgICAgICAgIHJlc3VsdCA9IFNOTVBFUlJfTUFMTE9DOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYml0ID0gMHg4MCA+PiBsdG1wICUgODsKICAgICAgICAgICAgYnVmW2l4XSB8PSBiaXQ7CgkgICAgCiAgICAgICAgfQoJU05NUF9GUkVFKHZwKTsKICAgICAgICBzbm1wX3BkdV9hZGRfdmFyaWFibGUocGR1LCBuYW1lLCBuYW1lX2xlbmd0aCwgQVNOX09DVEVUX1NUUiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnVmLCB0aW50KTsKICAgICAgICBicmVhazsKCiNpZmRlZiBORVRTTk1QX1dJVEhfT1BBUVVFX1NQRUNJQUxfVFlQRVMKICAgIGNhc2UgJ1UnOgogICAgICAgIGlmIChyZWFkNjQoJmM2NHRtcCwgdmFsdWUpKQogICAgICAgICAgICBzbm1wX3BkdV9hZGRfdmFyaWFibGUocGR1LCBuYW1lLCBuYW1lX2xlbmd0aCwgQVNOX09QQVFVRV9VNjQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmYzY0dG1wLCBzaXplb2YoYzY0dG1wKSk7CiAgICAgICAgZWxzZQogICAgICAgICAgICBnb3RvIGZhaWw7CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSAnSSc6CiAgICAgICAgaWYgKHJlYWQ2NCgmYzY0dG1wLCB2YWx1ZSkpCiAgICAgICAgICAgIHNubXBfcGR1X2FkZF92YXJpYWJsZShwZHUsIG5hbWUsIG5hbWVfbGVuZ3RoLCBBU05fT1BBUVVFX0k2NCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZjNjR0bXAsIHNpemVvZihjNjR0bXApKTsKICAgICAgICBlbHNlCiAgICAgICAgICAgIGdvdG8gZmFpbDsKICAgICAgICBicmVhazsKCiAgICBjYXNlICdGJzoKICAgICAgICBpZiAoc3NjYW5mKHZhbHVlLCAiJWYiLCAmZnRtcCkgPT0gMSkKICAgICAgICAgICAgc25tcF9wZHVfYWRkX3ZhcmlhYmxlKHBkdSwgbmFtZSwgbmFtZV9sZW5ndGgsIEFTTl9PUEFRVUVfRkxPQVQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmZnRtcCwgc2l6ZW9mKGZ0bXApKTsKICAgICAgICBlbHNlCiAgICAgICAgICAgIGdvdG8gZmFpbDsKICAgICAgICBicmVhazsKCiAgICBjYXNlICdEJzoKICAgICAgICBpZiAoc3NjYW5mKHZhbHVlLCAiJWxmIiwgJmR0bXApID09IDEpCiAgICAgICAgICAgIHNubXBfcGR1X2FkZF92YXJpYWJsZShwZHUsIG5hbWUsIG5hbWVfbGVuZ3RoLCBBU05fT1BBUVVFX0RPVUJMRSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZkdG1wLCBzaXplb2YoZHRtcCkpOwogICAgICAgIGVsc2UKICAgICAgICAgICAgZ290byBmYWlsOwogICAgICAgIGJyZWFrOwojZW5kaWYgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIE5FVFNOTVBfV0lUSF9PUEFRVUVfU1BFQ0lBTF9UWVBFUyAqLwoKICAgIGRlZmF1bHQ6CiAgICAgICAgcmVzdWx0ID0gU05NUEVSUl9WQVJfVFlQRTsKCWJ1ZiA9ICh1X2NoYXIgKiljYWxsb2MoMSwgNCk7CglpZiAoYnVmICE9IE5VTEwpIHsKCSAgICBzcHJpbnRmKChjaGFyICopYnVmLCAiXCIlY1wiIiwgdHlwZSk7CgkgICAgc25tcF9zZXRfZGV0YWlsKChjaGFyICopYnVmKTsKCX0KICAgICAgICBicmVhazsKICAgIH0KCiAgICBTTk1QX0ZSRUUoYnVmKTsKICAgIFNFVF9TTk1QX0VSUk9SKHJlc3VsdCk7CiAgICByZXR1cm4gcmVzdWx0OwoKI2lmbmRlZiBORVRTTk1QX0RJU0FCTEVfTUlCX0xPQURJTkcKICB0eXBlX2Vycm9yOgogICAgewogICAgICAgIGNoYXIgICAgICAgICAgICBlcnJvcl9tc2dbMjU2XTsKICAgICAgICBjaGFyICAgICAgICAgICAgdW5kZWZfbXNnWzMyXTsKICAgICAgICBjb25zdCBjaGFyICAgICAqdmFyX3R5cGU7CiAgICAgICAgc3dpdGNoICh0cC0+dHlwZSkgewogICAgICAgIGNhc2UgVFlQRV9PQkpJRDoKICAgICAgICAgICAgdmFyX3R5cGUgPSAiT0JKRUNUIElERU5USUZJRVIiOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFRZUEVfT0NURVRTVFI6CiAgICAgICAgICAgIHZhcl90eXBlID0gIk9DVEVUIFNUUklORyI7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgVFlQRV9JTlRFR0VSOgogICAgICAgICAgICB2YXJfdHlwZSA9ICJJTlRFR0VSIjsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBUWVBFX05FVEFERFI6CiAgICAgICAgICAgIHZhcl90eXBlID0gIk5ldHdvcmtBZGRyZXNzIjsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBUWVBFX0lQQUREUjoKICAgICAgICAgICAgdmFyX3R5cGUgPSAiSXBBZGRyZXNzIjsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBUWVBFX0NPVU5URVI6CiAgICAgICAgICAgIHZhcl90eXBlID0gIkNvdW50ZXIzMiI7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgVFlQRV9HQVVHRToKICAgICAgICAgICAgdmFyX3R5cGUgPSAiR2F1Z2UzMiI7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgVFlQRV9USU1FVElDS1M6CiAgICAgICAgICAgIHZhcl90eXBlID0gIlRpbWV0aWNrcyI7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgVFlQRV9PUEFRVUU6CiAgICAgICAgICAgIHZhcl90eXBlID0gIk9wYXF1ZSI7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgVFlQRV9OVUxMOgogICAgICAgICAgICB2YXJfdHlwZSA9ICJOdWxsIjsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBUWVBFX0NPVU5URVI2NDoKICAgICAgICAgICAgdmFyX3R5cGUgPSAiQ291bnRlcjY0IjsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBUWVBFX0JJVFNUUklORzoKICAgICAgICAgICAgdmFyX3R5cGUgPSAiQklUUyI7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgVFlQRV9OU0FQQUREUkVTUzoKICAgICAgICAgICAgdmFyX3R5cGUgPSAiTnNhcEFkZHJlc3MiOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFRZUEVfVUlOVEVHRVI6CiAgICAgICAgICAgIHZhcl90eXBlID0gIlVJbnRlZ2VyIjsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBUWVBFX1VOU0lHTkVEMzI6CiAgICAgICAgICAgIHZhcl90eXBlID0gIlVuc2lnbmVkMzIiOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFRZUEVfSU5URUdFUjMyOgogICAgICAgICAgICB2YXJfdHlwZSA9ICJJbnRlZ2VyMzIiOwogICAgICAgICAgICBicmVhazsKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICBzcHJpbnRmKHVuZGVmX21zZywgIlRZUEVfJWQiLCB0cC0+dHlwZSk7CiAgICAgICAgICAgIHZhcl90eXBlID0gdW5kZWZfbXNnOwogICAgICAgIH0KICAgICAgICBzbnByaW50ZihlcnJvcl9tc2csIHNpemVvZihlcnJvcl9tc2cpLAogICAgICAgICAgICAgICAiVHlwZSBvZiBhdHRyaWJ1dGUgaXMgJXMsIG5vdCAlcyIsIHZhcl90eXBlLCB2YWx1ZSk7CiAgICAgICAgZXJyb3JfbXNnWyBzaXplb2YoZXJyb3JfbXNnKS0xIF0gPSAwOwogICAgICAgIHJlc3VsdCA9IFNOTVBFUlJfVkFSX1RZUEU7CiAgICAgICAgc25tcF9zZXRfZGV0YWlsKGVycm9yX21zZyk7CiAgICAgICAgZ290byBvdXQ7CiAgICB9CiNlbmRpZiAvKiBORVRTTk1QX0RJU0FCTEVfTUlCX0xPQURJTkcgKi8KICBmYWlsOgogICAgcmVzdWx0ID0gU05NUEVSUl9WQUxVRTsKICAgIHNubXBfc2V0X2RldGFpbCh2YWx1ZSk7CiAgb3V0OgogICAgU0VUX1NOTVBfRVJST1IocmVzdWx0KTsKICAgIHJldHVybiByZXN1bHQ7Cn0KCi8qCiAqIHJldHVybnMgTlVMTCBvciBpbnRlcm5hbCBwb2ludGVyIHRvIHNlc3Npb24KICogdXNlIHRoaXMgcG9pbnRlciBmb3IgdGhlIG90aGVyIHNubXBfc2Vzcyogcm91dGluZXMsCiAqIHdoaWNoIGd1YXJhbnRlZSBhY3Rpb24gd2lsbCBvY2N1ciBPTkxZIGZvciB0aGlzIGdpdmVuIHNlc3Npb24uCiAqLwp2b2lkICAgICAgICAgICAqCnNubXBfc2Vzc19wb2ludGVyKG5ldHNubXBfc2Vzc2lvbiAqIHNlc3Npb24pCnsKICAgIHN0cnVjdCBzZXNzaW9uX2xpc3QgKnNscDsKCiAgICBzbm1wX3Jlc19sb2NrKE1UX0xJQlJBUllfSUQsIE1UX0xJQl9TRVNTSU9OKTsKICAgIGZvciAoc2xwID0gU2Vzc2lvbnM7IHNscDsgc2xwID0gc2xwLT5uZXh0KSB7CiAgICAgICAgaWYgKHNscC0+c2Vzc2lvbiA9PSBzZXNzaW9uKSB7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgIH0KICAgIHNubXBfcmVzX3VubG9jayhNVF9MSUJSQVJZX0lELCBNVF9MSUJfU0VTU0lPTik7CgogICAgaWYgKHNscCA9PSBOVUxMKSB7CiAgICAgICAgc25tcF9lcnJubyA9IFNOTVBFUlJfQkFEX1NFU1NJT047ICAgICAgIC8qTVRDUklUSUNBTF9SRVNPVVJDRSAqLwogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICB9CiAgICByZXR1cm4gKCh2b2lkICopIHNscCk7Cn0KCi8qCiAqIElucHV0IDogYW4gb3BhcXVlIHBvaW50ZXIsIHJldHVybmVkIGJ5IHNubXBfc2Vzc19vcGVuLgogKiByZXR1cm5zIE5VTEwgb3IgcG9pbnRlciB0byBzZXNzaW9uLgogKi8KbmV0c25tcF9zZXNzaW9uICoKc25tcF9zZXNzX3Nlc3Npb24odm9pZCAqc2Vzc3ApCnsKICAgIHN0cnVjdCBzZXNzaW9uX2xpc3QgKnNscCA9IChzdHJ1Y3Qgc2Vzc2lvbl9saXN0ICopIHNlc3NwOwogICAgaWYgKHNscCA9PSBOVUxMKQogICAgICAgIHJldHVybiAoTlVMTCk7CiAgICByZXR1cm4gKHNscC0+c2Vzc2lvbik7Cn0KCi8qKgogKiBMb29rIHVwIGEgc2Vzc2lvbiB0aGF0IGFscmVhZHkgbWF5IGhhdmUgYmVlbiBjbG9zZWQuCiAqCiAqIEBwYXJhbSBzZXNzcCBPcGFxdWUgcG9pbnRlciwgcmV0dXJuZWQgYnkgc25tcF9zZXNzX29wZW4uCiAqCiAqIEByZXR1cm4gUG9pbnRlciB0byBzZXNzaW9uIHVwb24gc3VjY2VzcyBvciBOVUxMIHVwb24gZmFpbHVyZS4KICoKICogQHNlZSBzbm1wX3Nlc3Nfc2Vzc2lvbigpCiAqLwpuZXRzbm1wX3Nlc3Npb24gKgpzbm1wX3Nlc3Nfc2Vzc2lvbl9sb29rdXAodm9pZCAqc2Vzc3ApCnsKICAgIHN0cnVjdCBzZXNzaW9uX2xpc3QgKnNscDsKCiAgICBzbm1wX3Jlc19sb2NrKE1UX0xJQlJBUllfSUQsIE1UX0xJQl9TRVNTSU9OKTsKICAgIGZvciAoc2xwID0gU2Vzc2lvbnM7IHNscDsgc2xwID0gc2xwLT5uZXh0KSB7CiAgICAgICAgaWYgKHNscCA9PSBzZXNzcCkgewogICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICB9CiAgICBzbm1wX3Jlc191bmxvY2soTVRfTElCUkFSWV9JRCwgTVRfTElCX1NFU1NJT04pOwoKICAgIHJldHVybiAobmV0c25tcF9zZXNzaW9uICopc2xwOwp9CgoKLyoKICogc25tcF9zZXNzX3RyYW5zcG9ydDogdGFrZXMgYW4gb3BhcXVlIHBvaW50ZXIgKGFzIHJldHVybmVkIGJ5CiAqIHNubXBfc2Vzc19vcGVuIG9yIHNubXBfc2Vzc19wb2ludGVyKSBhbmQgcmV0dXJucyB0aGUgY29ycmVzcG9uZGluZwogKiBuZXRzbm1wX3RyYW5zcG9ydCBwb2ludGVyIChvciBOVUxMIGlmIHRoZSBvcGFxdWUgcG9pbnRlciBkb2VzIG5vdCBjb3JyZXNwb25kCiAqIHRvIGFuIGFjdGl2ZSBpbnRlcm5hbCBzZXNzaW9uKS4gIAogKi8KCm5ldHNubXBfdHJhbnNwb3J0ICoKc25tcF9zZXNzX3RyYW5zcG9ydCh2b2lkICpzZXNzcCkKewogICAgc3RydWN0IHNlc3Npb25fbGlzdCAqc2xwID0gKHN0cnVjdCBzZXNzaW9uX2xpc3QgKikgc2Vzc3A7CiAgICBpZiAoc2xwID09IE5VTEwpIHsKICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0gZWxzZSB7CiAgICAgICAgcmV0dXJuIHNscC0+dHJhbnNwb3J0OwogICAgfQp9CgoKCi8qCiAqIHNubXBfc2Vzc190cmFuc3BvcnRfc2V0OiBzZXQgdGhlIHRyYW5zcG9ydCBwb2ludGVyIGZvciB0aGUgb3BhcXVlCiAqIHNlc3Npb24gcG9pbnRlciBzcC4gIAogKi8KCnZvaWQKc25tcF9zZXNzX3RyYW5zcG9ydF9zZXQodm9pZCAqc3AsIG5ldHNubXBfdHJhbnNwb3J0ICp0KQp7CiAgICBzdHJ1Y3Qgc2Vzc2lvbl9saXN0ICpzbHAgPSAoc3RydWN0IHNlc3Npb25fbGlzdCAqKSBzcDsKICAgIGlmIChzbHAgIT0gTlVMTCkgewogICAgICAgIHNscC0+dHJhbnNwb3J0ID0gdDsKICAgIH0KfQoKCi8qCiAqIHNubXBfZHVwbGljYXRlX29iamlkOiBkdXBsaWNhdGVzIChtYWxsb2NzKSBhbiBvYmppZCBiYXNlZCBvbiB0aGUKICogaW5wdXQgb2JqaWQgCiAqLwpvaWQgICAgICAgICAgICAqCnNubXBfZHVwbGljYXRlX29iamlkKGNvbnN0IG9pZCAqIG9ialRvQ29weSwgc2l6ZV90IG9ialRvQ29weUxlbikKewogICAgb2lkICAgICAgICAgICAgKnJldHVybk9pZDsKICAgIGlmIChvYmpUb0NvcHkgIT0gTlVMTCAmJiBvYmpUb0NvcHlMZW4gIT0gMCkgewogICAgICAgIHJldHVybk9pZCA9IChvaWQgKikgbWFsbG9jKG9ialRvQ29weUxlbiAqIHNpemVvZihvaWQpKTsKICAgICAgICBpZiAocmV0dXJuT2lkKSB7CiAgICAgICAgICAgIG1lbWNweShyZXR1cm5PaWQsIG9ialRvQ29weSwgb2JqVG9Db3B5TGVuICogc2l6ZW9mKG9pZCkpOwogICAgICAgIH0KICAgIH0gZWxzZQogICAgICAgIHJldHVybk9pZCA9IE5VTEw7CiAgICByZXR1cm4gcmV0dXJuT2lkOwp9CgovKgogKiBnZW5lcmljIHN0YXRpc3RpY3MgY291bnRlciBmdW5jdGlvbnMgCiAqLwpzdGF0aWMgdV9pbnQgICAgc3RhdGlzdGljc1tORVRTTk1QX1NUQVRfTUFYX1NUQVRTXTsKCnVfaW50CnNubXBfaW5jcmVtZW50X3N0YXRpc3RpYyhpbnQgd2hpY2gpCnsKICAgIGlmICh3aGljaCA+PSAwICYmIHdoaWNoIDwgTkVUU05NUF9TVEFUX01BWF9TVEFUUykgewogICAgICAgIHN0YXRpc3RpY3Nbd2hpY2hdKys7CiAgICAgICAgcmV0dXJuIHN0YXRpc3RpY3Nbd2hpY2hdOwogICAgfQogICAgcmV0dXJuIDA7Cn0KCnVfaW50CnNubXBfaW5jcmVtZW50X3N0YXRpc3RpY19ieShpbnQgd2hpY2gsIGludCBjb3VudCkKewogICAgaWYgKHdoaWNoID49IDAgJiYgd2hpY2ggPCBORVRTTk1QX1NUQVRfTUFYX1NUQVRTKSB7CiAgICAgICAgc3RhdGlzdGljc1t3aGljaF0gKz0gY291bnQ7CiAgICAgICAgcmV0dXJuIHN0YXRpc3RpY3Nbd2hpY2hdOwogICAgfQogICAgcmV0dXJuIDA7Cn0KCnVfaW50CnNubXBfZ2V0X3N0YXRpc3RpYyhpbnQgd2hpY2gpCnsKICAgIGlmICh3aGljaCA+PSAwICYmIHdoaWNoIDwgTkVUU05NUF9TVEFUX01BWF9TVEFUUykKICAgICAgICByZXR1cm4gc3RhdGlzdGljc1t3aGljaF07CiAgICByZXR1cm4gMDsKfQoKdm9pZApzbm1wX2luaXRfc3RhdGlzdGljcyh2b2lkKQp7CiAgICBtZW1zZXQoc3RhdGlzdGljcywgMCwgc2l6ZW9mKHN0YXRpc3RpY3MpKTsKfQovKiogIEB9ICovCgo=