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+aG9va19yZWFsbG9jX2J1aWxkKHNlc3Npb24sIHBkdSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmcGt0YnVmLCAmcGt0YnVmX2xlbiwgJm9mZnNldCk7CiAgICAgICAgcGFja2V0ID0gcGt0YnVmOwogICAgICAgIGxlbmd0aCA9IG9mZnNldDsKICAgIH0gZWxzZSBpZiAoaXNwLT5ob29rX2J1aWxkKSB7CiAgICAgICAgcGFja2V0ID0gcGt0YnVmOwogICAgICAgIGxlbmd0aCA9IHBrdGJ1Zl9sZW47CiAgICAgICAgcmVzdWx0ID0gaXNwLT5ob29rX2J1aWxkKHNlc3Npb24sIHBkdSwgcGt0YnVmLCAmbGVuZ3RoKTsKICAgIH0gZWxzZSB7CiNpZmRlZiBORVRTTk1QX1VTRV9SRVZFUlNFX0FTTkVOQ09ESU5HCiAgICAgICAgaWYgKG5ldHNubXBfZHNfZ2V0X2Jvb2xlYW4oTkVUU05NUF9EU19MSUJSQVJZX0lELCBORVRTTk1QX0RTX0xJQl9SRVZFUlNFX0VOQ09ERSkpIHsKICAgICAgICAgICAgcmVzdWx0ID0KICAgICAgICAgICAgICAgIHNubXBfYnVpbGQoJnBrdGJ1ZiwgJnBrdGJ1Zl9sZW4sICZvZmZzZXQsIHNlc3Npb24sIHBkdSk7CiAgICAgICAgICAgIHBhY2tldCA9IHBrdGJ1ZiArIHBrdGJ1Zl9sZW4gLSBvZmZzZXQ7CiAgICAgICAgICAgIGxlbmd0aCA9IG9mZnNldDsKICAgICAgICB9IGVsc2UgewojZW5kaWYKICAgICAgICAgICAgcGFja2V0ID0gcGt0YnVmOwogICAgICAgICAgICBsZW5ndGggPSBwa3RidWZfbGVuOwogICAgICAgICAgICByZXN1bHQgPSBzbm1wX2J1aWxkKCZwa3RidWYsICZsZW5ndGgsICZvZmZzZXQsIHNlc3Npb24sIHBkdSk7CiNpZmRlZiBORVRTTk1QX1VTRV9SRVZFUlNFX0FTTkVOQ09ESU5HCiAgICAgICAgfQojZW5kaWYKICAgIH0KCiAgICBpZiAocmVzdWx0IDwgMCkgewogICAgICAgIERFQlVHTVNHVEwoKCJzZXNzX2FzeW5jX3NlbmQiLCAiZW5jb2RpbmcgZmFpbHVyZVxuIikpOwogICAgICAgIFNOTVBfRlJFRShwa3RidWYpOwogICAgICAgIHJldHVybiAwOwogICAgfQoKICAgIC8qCiAgICAgKiBNYWtlIHN1cmUgd2UgZG9uJ3Qgc2VuZCBzb21ldGhpbmcgdGhhdCBpcyBiaWdnZXIgdGhhbiB0aGUgbXNnTWF4U2l6ZQogICAgICogc3BlY2lmaWVkIGluIHRoZSByZWNlaXZlZCBQRFUuICAKICAgICAqLwoKICAgIGlmIChwZHUtPnZlcnNpb24gPT0gU05NUF9WRVJTSU9OXzMgJiYgc2Vzc2lvbi0+c25kTXNnTWF4U2l6ZSAhPSAwICYmIGxlbmd0aCA+IHNlc3Npb24tPnNuZE1zZ01heFNpemUpIHsKICAgICAgICBERUJVR01TR1RMKCgic2Vzc19hc3luY19zZW5kIiwKICAgICAgICAgICAgICAgICAgICAibGVuZ3RoIG9mIHBhY2tldCAoJWx1KSBleGNlZWRzIHNlc3Npb24gbWF4aW11bSAoJWx1KVxuIiwKICAgICAgICAgICAgICAgICAgICAodW5zaWduZWQgbG9uZylsZW5ndGgsICh1bnNpZ25lZCBsb25nKXNlc3Npb24tPnNuZE1zZ01heFNpemUpKTsKICAgICAgICBzZXNzaW9uLT5zX3NubXBfZXJybm8gPSBTTk1QRVJSX1RPT19MT05HOwogICAgICAgIFNOTVBfRlJFRShwa3RidWYpOwogICAgICAgIHJldHVybiAwOwogICAgfQoKICAgIC8qCiAgICAgKiBDaGVjayB0aGF0IHRoZSB1bmRlcmx5aW5nIHRyYW5zcG9ydCBpcyBjYXBhYmxlIG9mIHNlbmRpbmcgYSBwYWNrZXQgYXMKICAgICAqIGxhcmdlIGFzIGxlbmd0aC4gIAogICAgICovCgogICAgaWYgKHRyYW5zcG9ydC0+bXNnTWF4U2l6ZSAhPSAwICYmIGxlbmd0aCA+IHRyYW5zcG9ydC0+bXNnTWF4U2l6ZSkgewogICAgICAgIERFQlVHTVNHVEwoKCJzZXNzX2FzeW5jX3NlbmQiLAogICAgICAgICAgICAgICAgICAgICJsZW5ndGggb2YgcGFja2V0ICglbHUpIGV4Y2VlZHMgdHJhbnNwb3J0IG1heGltdW0gKCVsdSlcbiIsCiAgICAgICAgICAgICAgICAgICAgKHVuc2lnbmVkIGxvbmcpbGVuZ3RoLCAodW5zaWduZWQgbG9uZyl0cmFuc3BvcnQtPm1zZ01heFNpemUpKTsKICAgICAgICBzZXNzaW9uLT5zX3NubXBfZXJybm8gPSBTTk1QRVJSX1RPT19MT05HOwogICAgICAgIFNOTVBfRlJFRShwa3RidWYpOwogICAgICAgIHJldHVybiAwOwogICAgfQoKICAgIC8qCiAgICAgKiBTZW5kIHRoZSBtZXNzYWdlLiAgCiAgICAgKi8KCiAgICBERUJVR01TR1RMKCgic2Vzc19wcm9jZXNzX3BhY2tldCIsICJzZW5kaW5nIG1lc3NhZ2UgaWQjJWxkIHJlcWlkIyVsZCBsZW4gJSIKICAgICAgICAgICAgICAgIE5FVFNOTVBfUFJJeiAidVxuIiwgcGR1LT5tc2dpZCwgcGR1LT5yZXFpZCwgbGVuZ3RoKSk7CiAgICByZXN1bHQgPSBuZXRzbm1wX3RyYW5zcG9ydF9zZW5kKHRyYW5zcG9ydCwgcGFja2V0LCBsZW5ndGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICYocGR1LT50cmFuc3BvcnRfZGF0YSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICYocGR1LT50cmFuc3BvcnRfZGF0YV9sZW5ndGgpKTsKCiAgICBTTk1QX0ZSRUUocGt0YnVmKTsKCiAgICBpZiAocmVzdWx0IDwgMCkgewogICAgICAgIHNlc3Npb24tPnNfc25tcF9lcnJubyA9IFNOTVBFUlJfQkFEX1NFTkRUTzsKICAgICAgICBzZXNzaW9uLT5zX2Vycm5vID0gZXJybm87CiAgICAgICAgcmV0dXJuIDA7CiAgICB9CgogICAgcmVxaWQgPSBwZHUtPnJlcWlkOwoKICAgIC8qCiAgICAgKiBBZGQgdG8gcGVuZGluZyByZXF1ZXN0cyBsaXN0IGlmIHdlIGV4cGVjdCBhIHJlc3BvbnNlLiAgCiAgICAgKi8KICAgIGlmIChwZHUtPmZsYWdzICYgVUNEX01TR19GTEFHX0VYUEVDVF9SRVNQT05TRSkgewogICAgICAgIG5ldHNubXBfcmVxdWVzdF9saXN0ICpycDsKICAgICAgICBzdHJ1Y3QgdGltZXZhbCAgdHY7CgogICAgICAgIHJwID0gKG5ldHNubXBfcmVxdWVzdF9saXN0ICopIGNhbGxvYygxLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplb2YobmV0c25tcF9yZXF1ZXN0X2xpc3QpKTsKICAgICAgICBpZiAocnAgPT0gTlVMTCkgewogICAgICAgICAgICBzZXNzaW9uLT5zX3NubXBfZXJybm8gPSBTTk1QRVJSX0dFTkVSUjsKICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgfQoKICAgICAgICBnZXR0aW1lb2ZkYXkoJnR2LCAoc3RydWN0IHRpbWV6b25lICopIDApOwogICAgICAgIHJwLT5wZHUgPSBwZHU7CiAgICAgICAgcnAtPnJlcXVlc3RfaWQgPSBwZHUtPnJlcWlkOwogICAgICAgIHJwLT5tZXNzYWdlX2lkID0gcGR1LT5tc2dpZDsKICAgICAgICBycC0+Y2FsbGJhY2sgPSBjYWxsYmFjazsKICAgICAgICBycC0+Y2JfZGF0YSA9IGNiX2RhdGE7CiAgICAgICAgcnAtPnJldHJpZXMgPSAwOwogICAgICAgIGlmIChwZHUtPmZsYWdzICYgVUNEX01TR19GTEFHX1BEVV9USU1FT1VUKSB7CiAgICAgICAgICAgIHJwLT50aW1lb3V0ID0gcGR1LT50aW1lICogMTAwMDAwMEw7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcnAtPnRpbWVvdXQgPSBzZXNzaW9uLT50aW1lb3V0OwogICAgICAgIH0KICAgICAgICBycC0+dGltZSA9IHR2OwogICAgICAgIHR2LnR2X3VzZWMgKz0gcnAtPnRpbWVvdXQ7CiAgICAgICAgdHYudHZfc2VjICs9IHR2LnR2X3VzZWMgLyAxMDAwMDAwTDsKICAgICAgICB0di50dl91c2VjICU9IDEwMDAwMDBMOwogICAgICAgIHJwLT5leHBpcmUgPSB0djsKCiAgICAgICAgLyoKICAgICAgICAgKiBYWCBsb2NrIHNob3VsZCBiZSBwZXIgc2Vzc2lvbiAhIAogICAgICAgICAqLwogICAgICAgIHNubXBfcmVzX2xvY2soTVRfTElCUkFSWV9JRCwgTVRfTElCX1NFU1NJT04pOwogICAgICAgIGlmIChpc3AtPnJlcXVlc3RzRW5kKSB7CiAgICAgICAgICAgIHJwLT5uZXh0X3JlcXVlc3QgPSBpc3AtPnJlcXVlc3RzRW5kLT5uZXh0X3JlcXVlc3Q7CiAgICAgICAgICAgIGlzcC0+cmVxdWVzdHNFbmQtPm5leHRfcmVxdWVzdCA9IHJwOwogICAgICAgICAgICBpc3AtPnJlcXVlc3RzRW5kID0gcnA7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcnAtPm5leHRfcmVxdWVzdCA9IGlzcC0+cmVxdWVzdHM7CiAgICAgICAgICAgIGlzcC0+cmVxdWVzdHMgPSBycDsKICAgICAgICAgICAgaXNwLT5yZXF1ZXN0c0VuZCA9IHJwOwogICAgICAgIH0KICAgICAgICBzbm1wX3Jlc191bmxvY2soTVRfTElCUkFSWV9JRCwgTVRfTElCX1NFU1NJT04pOwogICAgfSBlbHNlIHsKICAgICAgICAvKgogICAgICAgICAqIE5vIHJlc3BvbnNlIGV4cGVjdGVkLi4uICAKICAgICAgICAgKi8KICAgICAgICBpZiAocmVxaWQpIHsKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogRnJlZSB2MSBvciB2MiBUUkFQIFBEVSBpZmYgbm8gZXJyb3IgIAogICAgICAgICAgICAgKi8KICAgICAgICAgICAgc25tcF9mcmVlX3BkdShwZHUpOwogICAgICAgIH0KICAgIH0KCiAgICByZXR1cm4gcmVxaWQ7Cn0KCmludApzbm1wX3Nlc3NfYXN5bmNfc2VuZCh2b2lkICpzZXNzcCwKICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9wZHUgKnBkdSwKICAgICAgICAgICAgICAgICAgICAgc25tcF9jYWxsYmFjayBjYWxsYmFjaywgdm9pZCAqY2JfZGF0YSkKewogICAgaW50ICAgICAgICAgICAgIHJjOwoKICAgIGlmIChzZXNzcCA9PSBOVUxMKSB7CiAgICAgICAgc25tcF9lcnJubyA9IFNOTVBFUlJfQkFEX1NFU1NJT047ICAgICAgIC8qTVRDUklUSUNBTF9SRVNPVVJDRSAqLwogICAgICAgIHJldHVybiAoMCk7CiAgICB9CiAgICAvKgogICAgICogc2VuZCBwZHUKICAgICAqLwogICAgcmMgPSBfc2Vzc19hc3luY19zZW5kKHNlc3NwLCBwZHUsIGNhbGxiYWNrLCBjYl9kYXRhKTsKICAgIGlmIChyYyA9PSAwKSB7CiAgICAgICAgc3RydWN0IHNlc3Npb25fbGlzdCAqcHNsOwogICAgICAgIG5ldHNubXBfc2Vzc2lvbiAqcHNzOwogICAgICAgIHBzbCA9IChzdHJ1Y3Qgc2Vzc2lvbl9saXN0ICopIHNlc3NwOwogICAgICAgIHBzcyA9IHBzbC0+c2Vzc2lvbjsKICAgICAgICBTRVRfU05NUF9FUlJPUihwc3MtPnNfc25tcF9lcnJubyk7CiAgICB9CiAgICByZXR1cm4gcmM7Cn0KCgovKgogKiBGcmVlcyB0aGUgdmFyaWFibGUgYW5kIGFueSBtYWxsb2MnZCBkYXRhIGFzc29jaWF0ZWQgd2l0aCBpdC4KICovCnZvaWQKc25tcF9mcmVlX3Zhcl9pbnRlcm5hbHMobmV0c25tcF92YXJpYWJsZV9saXN0ICogdmFyKQp7CiAgICBpZiAoIXZhcikKICAgICAgICByZXR1cm47CgogICAgaWYgKHZhci0+bmFtZSAhPSB2YXItPm5hbWVfbG9jKQogICAgICAgIFNOTVBfRlJFRSh2YXItPm5hbWUpOwogICAgaWYgKHZhci0+dmFsLnN0cmluZyAhPSB2YXItPmJ1ZikKICAgICAgICBTTk1QX0ZSRUUodmFyLT52YWwuc3RyaW5nKTsKICAgIGlmICh2YXItPmRhdGEpIHsKICAgICAgICBpZiAodmFyLT5kYXRhRnJlZUhvb2spIHsKICAgICAgICAgICAgdmFyLT5kYXRhRnJlZUhvb2sodmFyLT5kYXRhKTsKICAgICAgICAgICAgdmFyLT5kYXRhID0gTlVMTDsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBTTk1QX0ZSRUUodmFyLT5kYXRhKTsKICAgICAgICB9CiAgICB9Cn0KCnZvaWQKc25tcF9mcmVlX3ZhcihuZXRzbm1wX3ZhcmlhYmxlX2xpc3QgKiB2YXIpCnsKICAgIHNubXBfZnJlZV92YXJfaW50ZXJuYWxzKHZhcik7CiAgICBmcmVlKChjaGFyICopIHZhcik7Cn0KCnZvaWQKc25tcF9mcmVlX3ZhcmJpbmQobmV0c25tcF92YXJpYWJsZV9saXN0ICogdmFyKQp7CiAgICBuZXRzbm1wX3ZhcmlhYmxlX2xpc3QgKnB0cjsKICAgIHdoaWxlICh2YXIpIHsKICAgICAgICBwdHIgPSB2YXItPm5leHRfdmFyaWFibGU7CiAgICAgICAgc25tcF9mcmVlX3Zhcih2YXIpOwogICAgICAgIHZhciA9IHB0cjsKICAgIH0KfQoKLyoKICogRnJlZXMgdGhlIHBkdSBhbmQgYW55IG1hbGxvYydkIGRhdGEgYXNzb2NpYXRlZCB3aXRoIGl0LgogKi8Kdm9pZApzbm1wX2ZyZWVfcGR1KG5ldHNubXBfcGR1ICpwZHUpCnsKICAgIHN0cnVjdCBzbm1wX3NlY21vZF9kZWYgKnNwdHI7CgogICAgaWYgKCFwZHUpCiAgICAgICAgcmV0dXJuOwoKICAgIC8qCiAgICAgKiBJZiB0aGUgY29tbWFuZCBmaWVsZCBpcyBlbXB0eSwgdGhhdCBwcm9iYWJseSBpbmRpY2F0ZXMKICAgICAqICAgdGhhdCB0aGlzIFBEVSBzdHJ1Y3R1cmUgaGFzIGFscmVhZHkgYmVlbiBmcmVlZC4KICAgICAqICAgTG9nIGEgd2FybmluZyBhbmQgcmV0dXJuIChyYXRoZXIgdGhhbiBmcmVlaW5nIHRoaW5ncyBhZ2FpbikKICAgICAqCiAgICAgKiBOb3RlIHRoYXQgdGhpcyBkb2VzIG5vdCBwaWNrIHVwIGR1YWwtZnJlZXMgd2hlcmUgdGhlCiAgICAgKiAgIG1lbW9yeSBpcyBzZXQgdG8gcmFuZG9tIGp1bmssIHdoaWNoIGlzIHByb2JhYmx5IG1vcmUgc2VyaW91cy4KICAgICAqCiAgICAgKiBya3M6IHdoaWxlIHRoaXMgaXMgYSBnb29kIGlkZWEsIHRoZXJlIGFyZSB0d28gcHJvYmxlbXMuCiAgICAgKiAgICAgICAgIDEpIGFnZW50eCBzZXRzIGNvbW1hbmQgdG8gMCBpbiBzb21lIGNhc2VzCiAgICAgKiAgICAgICAgIDIpIGFjY29yZGluZyB0byBXZXMsIGEgYmFkIGRlY29kZSBvZiBhIHYzIG1lc3NhZ2UgY291bGQKICAgICAqICAgICAgICAgICAgcmVzdWx0IGluIGEgMCBhdCB0aGlzIG9mZnNldC4KICAgICAqICAgICAgc28gSSdtIGNvbW1lbnRpbmcgaXQgb3V0IHVudGlsIGEgYmV0dGVyIHNvbHV0aW9uIGlzIGZvdW5kLgogICAgICogICAgICBub3RlIHRoYXQgSSdtIGxlYXZpbmcgdGhlIG1lbXNldCwgYmVsb3cuLi4uCiAgICAgKgogICAgaWYgKHBkdS0+Y29tbWFuZCA9PSAwKSB7CiAgICAgICAgc25tcF9sb2coTE9HX1dBUk5JTkcsICJzbm1wX2ZyZWVfcGR1IHByb2JhYmx5IGNhbGxlZCB0d2ljZVxuIik7CiAgICAgICAgcmV0dXJuOwogICAgfQogICAgICovCiAgICBpZiAoKHNwdHIgPSBmaW5kX3NlY19tb2QocGR1LT5zZWN1cml0eU1vZGVsKSkgIT0gTlVMTCAmJgogICAgICAgIHNwdHItPnBkdV9mcmVlICE9IE5VTEwpIHsKICAgICAgICAoKnNwdHItPnBkdV9mcmVlKSAocGR1KTsKICAgIH0KICAgIHNubXBfZnJlZV92YXJiaW5kKHBkdS0+dmFyaWFibGVzKTsKICAgIFNOTVBfRlJFRShwZHUtPmVudGVycHJpc2UpOwogICAgU05NUF9GUkVFKHBkdS0+Y29tbXVuaXR5KTsKICAgIFNOTVBfRlJFRShwZHUtPmNvbnRleHRFbmdpbmVJRCk7CiAgICBTTk1QX0ZSRUUocGR1LT5zZWN1cml0eUVuZ2luZUlEKTsKICAgIFNOTVBfRlJFRShwZHUtPmNvbnRleHROYW1lKTsKICAgIFNOTVBfRlJFRShwZHUtPnNlY3VyaXR5TmFtZSk7CiAgICBTTk1QX0ZSRUUocGR1LT50cmFuc3BvcnRfZGF0YSk7CiAgICBtZW1zZXQocGR1LCAwLCBzaXplb2YobmV0c25tcF9wZHUpKTsKICAgIGZyZWUoKGNoYXIgKikgcGR1KTsKfQoKbmV0c25tcF9wZHUgICAgKgpzbm1wX2NyZWF0ZV9zZXNzX3BkdShuZXRzbm1wX3RyYW5zcG9ydCAqdHJhbnNwb3J0LCB2b2lkICpvcGFxdWUsCiAgICAgICAgICAgICAgICAgICAgIHNpemVfdCBvbGVuZ3RoKQp7CiAgICBuZXRzbm1wX3BkdSAqcGR1ID0gKG5ldHNubXBfcGR1ICopY2FsbG9jKDEsIHNpemVvZihuZXRzbm1wX3BkdSkpOwogICAgaWYgKHBkdSA9PSBOVUxMKSB7CiAgICAgICAgREVCVUdNU0dUTCgoInNlc3NfcHJvY2Vzc19wYWNrZXQiLCAiY2FuJ3QgbWFsbG9jIHNwYWNlIGZvciBQRFVcbiIpKTsKICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0KCiAgICAvKgogICAgICogU2F2ZSB0aGUgdHJhbnNwb3J0LWxldmVsIGRhdGEgc3BlY2lmaWMgdG8gdGhpcyByZWNlcHRpb24gKGUuZy4gVURQCiAgICAgKiBzb3VyY2UgYWRkcmVzcykuICAKICAgICAqLwoKICAgIHBkdS0+dHJhbnNwb3J0X2RhdGEgPSBvcGFxdWU7CiAgICBwZHUtPnRyYW5zcG9ydF9kYXRhX2xlbmd0aCA9IG9sZW5ndGg7CiAgICBwZHUtPnREb21haW4gPSB0cmFuc3BvcnQtPmRvbWFpbjsKICAgIHBkdS0+dERvbWFpbkxlbiA9IHRyYW5zcG9ydC0+ZG9tYWluX2xlbmd0aDsKICAgIHJldHVybiBwZHU7Cn0KCgovKgogKiBUaGlzIGZ1bmN0aW9uIHByb2Nlc3NlcyBhIGNvbXBsZXRlIChhY2NvcmRpbmcgdG8gYXNuX2NoZWNrX3BhY2tldCBvciB0aGUKICogQWdlbnRYIGVxdWl2YWxlbnQpIHBhY2tldCwgcGFyc2luZyBpdCBpbnRvIGEgUERVIGFuZCBjYWxsaW5nIHRoZSByZWxldmFudAogKiBjYWxsYmFja3MuICBPbiBlbnRyeSwgcGFja2V0cHRyIHBvaW50cyBhdCB0aGUgcGFja2V0IGluIHRoZSBzZXNzaW9uJ3MKICogYnVmZmVyIGFuZCBsZW5ndGggaXMgdGhlIGxlbmd0aCBvZiB0aGUgcGFja2V0LiAgCiAqLwoKc3RhdGljIGludApfc2Vzc19wcm9jZXNzX3BhY2tldCh2b2lkICpzZXNzcCwgbmV0c25tcF9zZXNzaW9uICogc3AsCiAgICAgICAgICAgICAgICAgICAgIHN0cnVjdCBzbm1wX2ludGVybmFsX3Nlc3Npb24gKmlzcCwKICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF90cmFuc3BvcnQgKnRyYW5zcG9ydCwKICAgICAgICAgICAgICAgICAgICAgdm9pZCAqb3BhcXVlLCBpbnQgb2xlbmd0aCwKICAgICAgICAgICAgICAgICAgICAgdV9jaGFyICogcGFja2V0cHRyLCBpbnQgbGVuZ3RoKQp7CiAgc3RydWN0IHNlc3Npb25fbGlzdCAqc2xwID0gKHN0cnVjdCBzZXNzaW9uX2xpc3QgKikgc2Vzc3A7CiAgbmV0c25tcF9wZHUgICAgKnBkdTsKICBuZXRzbm1wX3JlcXVlc3RfbGlzdCAqcnAsICpvcnAgPSBOVUxMOwogIHN0cnVjdCBzbm1wX3NlY21vZF9kZWYgKnNwdHI7CiAgaW50ICAgICAgICAgICAgIHJldCA9IDAsIGhhbmRsZWQgPSAwOwoKICBERUJVR01TR1RMKCgic2Vzc19wcm9jZXNzX3BhY2tldCIsCgkgICAgICAic2Vzc2lvbiAlcCBmZCAlZCBwa3QgJXAgbGVuZ3RoICVkXG4iLCBzZXNzcCwKCSAgICAgIHRyYW5zcG9ydC0+c29jaywgcGFja2V0cHRyLCBsZW5ndGgpKTsKCiAgaWYgKG5ldHNubXBfZHNfZ2V0X2Jvb2xlYW4oTkVUU05NUF9EU19MSUJSQVJZX0lELE5FVFNOTVBfRFNfTElCX0RVTVBfUEFDS0VUKSkgewogICAgICBjaGFyICphZGRydHh0ID0gbmV0c25tcF90cmFuc3BvcnRfcGVlcl9zdHJpbmcodHJhbnNwb3J0LCBvcGFxdWUsIG9sZW5ndGgpOwogICAgICBzbm1wX2xvZyhMT0dfREVCVUcsICJcblJlY2VpdmVkICVkIGJ5dGUgcGFja2V0IGZyb20gJXNcbiIsCiAgICAgICAgICAgICAgIGxlbmd0aCwgYWRkcnR4dCk7CiAgICAgIFNOTVBfRlJFRShhZGRydHh0KTsKICAgICAgeGR1bXAocGFja2V0cHRyLCBsZW5ndGgsICIiKTsKICB9CgogIC8qCiAgICogRG8gdHJhbnNwb3J0LWxldmVsIGZpbHRlcmluZyAoZS5nLiBJUC1hZGRyZXNzIGJhc2VkIGFsbG93L2RlbnkpLiAgCiAgICovCgogIGlmIChpc3AtPmhvb2tfcHJlKSB7CiAgICBpZiAoaXNwLT5ob29rX3ByZShzcCwgdHJhbnNwb3J0LCBvcGFxdWUsIG9sZW5ndGgpID09IDApIHsKICAgICAgREVCVUdNU0dUTCgoInNlc3NfcHJvY2Vzc19wYWNrZXQiLCAicHJlLXBhcnNlIGZhaWxcbiIpKTsKICAgICAgaWYgKG9wYXF1ZSAhPSBOVUxMKSB7CglTTk1QX0ZSRUUob3BhcXVlKTsKICAgICAgfQogICAgICByZXR1cm4gLTE7CiAgICB9CiAgfQoKICBpZiAoaXNwLT5ob29rX2NyZWF0ZV9wZHUpIHsKICAgIHBkdSA9IGlzcC0+aG9va19jcmVhdGVfcGR1KHRyYW5zcG9ydCwgb3BhcXVlLCBvbGVuZ3RoKTsKICB9IGVsc2UgewogICAgcGR1ID0gc25tcF9jcmVhdGVfc2Vzc19wZHUodHJhbnNwb3J0LCBvcGFxdWUsIG9sZW5ndGgpOwogIH0KCiAgaWYgKHBkdSA9PSBOVUxMKSB7CiAgICBzbm1wX2xvZyhMT0dfRVJSLCAicGR1IGZhaWxlZCB0byBiZSBjcmVhdGVkXG4iKTsKICAgIGlmIChvcGFxdWUgIT0gTlVMTCkgewogICAgICBTTk1QX0ZSRUUob3BhcXVlKTsKICAgIH0KICAgIHJldHVybiAtMTsKICB9CgogIC8qIGlmIHRoZSB0cmFuc3BvcnQgd2FzIGEgbWFnaWMgdHVubmVsLCBtYXJrIHRoZSBQRFUgYXMgaGF2aW5nIGNvbWUKICAgICB0aHJvdWdoIG9uZS4gKi8KICBpZiAodHJhbnNwb3J0LT5mbGFncyAmIE5FVFNOTVBfVFJBTlNQT1JUX0ZMQUdfVFVOTkVMRUQpIHsKICAgICAgcGR1LT5mbGFncyB8PSBVQ0RfTVNHX0ZMQUdfVFVOTkVMRUQ7CiAgfQoKICBpZiAoaXNwLT5ob29rX3BhcnNlKSB7CiAgICByZXQgPSBpc3AtPmhvb2tfcGFyc2Uoc3AsIHBkdSwgcGFja2V0cHRyLCBsZW5ndGgpOwogIH0gZWxzZSB7CiAgICByZXQgPSBzbm1wX3BhcnNlKHNlc3NwLCBzcCwgcGR1LCBwYWNrZXRwdHIsIGxlbmd0aCk7CiAgfQoKICBERUJVR01TR1RMKCgic2Vzc19wcm9jZXNzX3BhY2tldCIsICJyZWNlaXZlZCBtZXNzYWdlIGlkIyVsZCByZXFpZCMlbGQgbGVuICIKICAgICAgICAgICAgICAiJXVcbiIsIHBkdS0+bXNnaWQsIHBkdS0+cmVxaWQsIGxlbmd0aCkpOwoKICBpZiAocmV0ICE9IFNOTVBfRVJSX05PRVJST1IpIHsKICAgIERFQlVHTVNHVEwoKCJzZXNzX3Byb2Nlc3NfcGFja2V0IiwgInBhcnNlIGZhaWxcbiIpKTsKICB9CgogIGlmIChpc3AtPmhvb2tfcG9zdCkgewogICAgaWYgKGlzcC0+aG9va19wb3N0KHNwLCBwZHUsIHJldCkgPT0gMCkgewogICAgICBERUJVR01TR1RMKCgic2Vzc19wcm9jZXNzX3BhY2tldCIsICJwb3N0LXBhcnNlIGZhaWxcbiIpKTsKICAgICAgcmV0ID0gU05NUEVSUl9BU05fUEFSU0VfRVJSOwogICAgfQogIH0KCiAgaWYgKHJldCAhPSBTTk1QX0VSUl9OT0VSUk9SKSB7CiAgICAvKgogICAgICogQ2FsbCB0aGUgc2VjdXJpdHkgbW9kZWwgdG8gZnJlZSBhbnkgc2VjdXJpdHlTdGF0ZVJlZiBzdXBwbGllZCB3LyBtc2cuICAKICAgICAqLwogICAgaWYgKHBkdS0+c2VjdXJpdHlTdGF0ZVJlZiAhPSBOVUxMKSB7CiAgICAgIHNwdHIgPSBmaW5kX3NlY19tb2QocGR1LT5zZWN1cml0eU1vZGVsKTsKICAgICAgaWYgKHNwdHIgIT0gTlVMTCkgewoJaWYgKHNwdHItPnBkdV9mcmVlX3N0YXRlX3JlZiAhPSBOVUxMKSB7CgkgICgqc3B0ci0+cGR1X2ZyZWVfc3RhdGVfcmVmKSAocGR1LT5zZWN1cml0eVN0YXRlUmVmKTsKCX0gZWxzZSB7CgkgIHNubXBfbG9nKExPR19FUlIsCgkJICAgIlNlY3VyaXR5IE1vZGVsICVkIGNhbid0IGZyZWUgc3RhdGUgcmVmZXJlbmNlc1xuIiwKCQkgICBwZHUtPnNlY3VyaXR5TW9kZWwpOwoJfQogICAgICB9IGVsc2UgewoJc25tcF9sb2coTE9HX0VSUiwKCQkgIkNhbid0IGZpbmQgc2VjdXJpdHkgbW9kZWwgdG8gZnJlZSBwdHI6ICVkXG4iLAoJCSBwZHUtPnNlY3VyaXR5TW9kZWwpOwogICAgICB9CiAgICAgIHBkdS0+c2VjdXJpdHlTdGF0ZVJlZiA9IE5VTEw7CiAgICB9CiAgICBzbm1wX2ZyZWVfcGR1KHBkdSk7CiAgICByZXR1cm4gLTE7CiAgfQoKICBpZiAocGR1LT5mbGFncyAmIFVDRF9NU0dfRkxBR19SRVNQT05TRV9QRFUpIHsKICAgIC8qCiAgICAgKiBDYWxsIFVTTSB0byBmcmVlIGFueSBzZWN1cml0eVN0YXRlUmVmIHN1cHBsaWVkIHdpdGggdGhlIG1lc3NhZ2UuICAKICAgICAqLwogICAgaWYgKHBkdS0+c2VjdXJpdHlTdGF0ZVJlZikgewogICAgICBzcHRyID0gZmluZF9zZWNfbW9kKHBkdS0+c2VjdXJpdHlNb2RlbCk7CiAgICAgIGlmIChzcHRyKSB7CglpZiAoc3B0ci0+cGR1X2ZyZWVfc3RhdGVfcmVmKSB7CgkgICgqc3B0ci0+cGR1X2ZyZWVfc3RhdGVfcmVmKSAocGR1LT5zZWN1cml0eVN0YXRlUmVmKTsKCX0gZWxzZSB7CgkgIHNubXBfbG9nKExPR19FUlIsCgkJICAgIlNlY3VyaXR5IE1vZGVsICVkIGNhbid0IGZyZWUgc3RhdGUgcmVmZXJlbmNlc1xuIiwKCQkgICBwZHUtPnNlY3VyaXR5TW9kZWwpOwoJfQogICAgICB9IGVsc2UgewoJc25tcF9sb2coTE9HX0VSUiwKCQkgIkNhbid0IGZpbmQgc2VjdXJpdHkgbW9kZWwgdG8gZnJlZSBwdHI6ICVkXG4iLAoJCSBwZHUtPnNlY3VyaXR5TW9kZWwpOwogICAgICB9CiAgICAgIHBkdS0+c2VjdXJpdHlTdGF0ZVJlZiA9IE5VTEw7CiAgICB9CgogICAgZm9yIChycCA9IGlzcC0+cmVxdWVzdHM7IHJwOyBvcnAgPSBycCwgcnAgPSBycC0+bmV4dF9yZXF1ZXN0KSB7CiAgICAgIHNubXBfY2FsbGJhY2sgICBjYWxsYmFjazsKICAgICAgdm9pZCAgICAgICAgICAgKm1hZ2ljOwoKICAgICAgaWYgKHBkdS0+dmVyc2lvbiA9PSBTTk1QX1ZFUlNJT05fMykgewoJLyoKCSAqIG1zZ0lkIG11c3QgbWF0Y2ggZm9yIHYzIG1lc3NhZ2VzLiAgCgkgKi8KCWlmIChycC0+bWVzc2FnZV9pZCAhPSBwZHUtPm1zZ2lkKSB7CiAgICAgICAgICAgIERFQlVHTVNHVEwoKCJzZXNzX3Byb2Nlc3NfcGFja2V0IiwgInVubWF0Y2hlZCBtc2cgaWQ6ICVsZCAhPSAlbGRcbiIsCiAgICAgICAgICAgICAgICAgICAgICAgIHJwLT5tZXNzYWdlX2lkLCBwZHUtPm1zZ2lkKSk7CgkgICAgY29udGludWU7Cgl9CgoJLyoKCSAqIENoZWNrIHRoYXQgbWVzc2FnZSBmaWVsZHMgbWF0Y2ggb3JpZ2luYWwsIGlmIG5vdCwgbm8gZnVydGhlcgoJICogcHJvY2Vzc2luZy4gIAoJICovCglpZiAoIXNubXB2M192ZXJpZnlfbXNnKHJwLCBwZHUpKSB7CgkgIGJyZWFrOwoJfQogICAgICB9IGVsc2UgewoJaWYgKHJwLT5yZXF1ZXN0X2lkICE9IHBkdS0+cmVxaWQpIHsKCSAgY29udGludWU7Cgl9CiAgICAgIH0KCiAgICAgIGlmIChycC0+Y2FsbGJhY2spIHsKCWNhbGxiYWNrID0gcnAtPmNhbGxiYWNrOwoJbWFnaWMgPSBycC0+Y2JfZGF0YTsKICAgICAgfSBlbHNlIHsKCWNhbGxiYWNrID0gc3AtPmNhbGxiYWNrOwoJbWFnaWMgPSBzcC0+Y2FsbGJhY2tfbWFnaWM7CiAgICAgIH0KICAgICAgaGFuZGxlZCA9IDE7CgogICAgICAvKgogICAgICAgKiBNVFIgc25tcF9yZXNfbG9jayhNVF9MSUJSQVJZX0lELCBNVF9MSUJfU0VTU0lPTik7ICA/KiBYWCBsb2NrCiAgICAgICAqIHNob3VsZCBiZSBwZXIgc2Vzc2lvbiAhIAogICAgICAgKi8KCiAgICAgIGlmIChjYWxsYmFjayA9PSBOVUxMCgkgIHx8IGNhbGxiYWNrKE5FVFNOTVBfQ0FMTEJBQ0tfT1BfUkVDRUlWRURfTUVTU0FHRSwgc3AsCgkJICAgICAgcGR1LT5yZXFpZCwgcGR1LCBtYWdpYykgPT0gMSkgewoJaWYgKHBkdS0+Y29tbWFuZCA9PSBTTk1QX01TR19SRVBPUlQpIHsKCSAgaWYgKHNwLT5zX3NubXBfZXJybm8gPT0gU05NUEVSUl9OT1RfSU5fVElNRV9XSU5ET1cgfHwKCSAgICAgIHNubXB2M19nZXRfcmVwb3J0X3R5cGUocGR1KSA9PQoJICAgICAgU05NUEVSUl9OT1RfSU5fVElNRV9XSU5ET1cpIHsKCSAgICAvKgoJICAgICAqIHRyaWdnZXIgaW1tZWRpYXRlIHJldHJ5IG9uIHJlY292ZXJhYmxlIFJlcG9ydHMgCgkgICAgICogKiAobm90SW5UaW1lV2luZG93KSwgaW5jcl9yZXRyaWVzID09IFRSVUUgdG8gcHJldmVudAoJICAgICAqICogaW5pZmluaXRlIHJlc2VuZCAgICAgICAgICAgICAgICAgICAgICAKCSAgICAgKi8KCSAgICBpZiAocnAtPnJldHJpZXMgPD0gc3AtPnJldHJpZXMpIHsKCSAgICAgIHNubXBfcmVzZW5kX3JlcXVlc3Qoc2xwLCBycCwgVFJVRSk7CgkgICAgICBicmVhazsKCSAgICB9IGVsc2UgewoJICAgICAgLyogV2UncmUgZG9uZSB3aXRoIHJldHJpZXMsIHNvIG5vIGxvbmdlciB3YWl0aW5nIGZvciBhIHJlc3BvbnNlICovCgkgICAgICBpZiAobWFnaWMpIHsKCQkoKHN0cnVjdCBzeW5jaF9zdGF0ZSopbWFnaWMpLT53YWl0aW5nID0gMDsKCSAgICAgIH0KCSAgICB9CgkgIH0gZWxzZSB7CgkgICAgaWYgKFNOTVBWM19JR05PUkVfVU5BVVRIX1JFUE9SVFMpIHsKCSAgICAgIGJyZWFrOwoJICAgIH0gZWxzZSB7IC8qIFNldCB0aGUgc3RhdGUgdG8gbm8gbG9uZ2VyIGJlIHdhaXRpbmcsIHNpbmNlIHdlJ3JlIGRvbmUgd2l0aCByZXRyaWVzICovCgkgICAgICBpZiAobWFnaWMpIHsKCQkoKHN0cnVjdCBzeW5jaF9zdGF0ZSopbWFnaWMpLT53YWl0aW5nID0gMDsKCSAgICAgIH0KCSAgICB9CgkgIH0KCgkgIC8qCgkgICAqIEhhbmRsZSBlbmdpbmVJRCBkaXNjb3ZlcnkuICAKCSAgICovCgkgIGlmICghc3AtPnNlY3VyaXR5RW5naW5lSURMZW4gJiYgcGR1LT5zZWN1cml0eUVuZ2luZUlETGVuKSB7CgkgICAgc3AtPnNlY3VyaXR5RW5naW5lSUQgPQoJICAgICAgKHVfY2hhciAqKSBtYWxsb2MocGR1LT5zZWN1cml0eUVuZ2luZUlETGVuKTsKCSAgICBpZiAoc3AtPnNlY3VyaXR5RW5naW5lSUQgPT0gTlVMTCkgewoJICAgICAgLyoKCSAgICAgICAqIFRPRE8gRklYOiByZWNvdmVyIGFmdGVyIG1lc3NhZ2UgY2FsbGJhY2sgKj8KICAgICAgICAgICAgICAgKi8KCSAgICAgIHJldHVybiAtMTsKCSAgICB9CgkgICAgbWVtY3B5KHNwLT5zZWN1cml0eUVuZ2luZUlELCBwZHUtPnNlY3VyaXR5RW5naW5lSUQsCgkJICAgcGR1LT5zZWN1cml0eUVuZ2luZUlETGVuKTsKCSAgICBzcC0+c2VjdXJpdHlFbmdpbmVJRExlbiA9IHBkdS0+c2VjdXJpdHlFbmdpbmVJRExlbjsKCSAgICBpZiAoIXNwLT5jb250ZXh0RW5naW5lSURMZW4pIHsKCSAgICAgIHNwLT5jb250ZXh0RW5naW5lSUQgPQoJCSh1X2NoYXIgKikgbWFsbG9jKHBkdS0+CgkJCQkgIHNlY3VyaXR5RW5naW5lSURMZW4pOwoJICAgICAgaWYgKHNwLT5jb250ZXh0RW5naW5lSUQgPT0gTlVMTCkgewoJCS8qCgkJICogVE9ETyBGSVg6IHJlY292ZXIgYWZ0ZXIgbWVzc2FnZSBjYWxsYmFjayAqPwoJCSAqLwogICAgICAgICAgICAgICAgcmV0dXJuIC0xOwoJICAgICAgfQoJICAgICAgbWVtY3B5KHNwLT5jb250ZXh0RW5naW5lSUQsCgkJICAgICBwZHUtPnNlY3VyaXR5RW5naW5lSUQsCgkJICAgICBwZHUtPnNlY3VyaXR5RW5naW5lSURMZW4pOwoJICAgICAgc3AtPmNvbnRleHRFbmdpbmVJRExlbiA9CgkJcGR1LT5zZWN1cml0eUVuZ2luZUlETGVuOwoJICAgIH0KCSAgfQoJfQoKCS8qCgkgKiBTdWNjZXNzZnVsLCBzbyBkZWxldGUgcmVxdWVzdC4gIAoJICovCglpZiAoaXNwLT5yZXF1ZXN0cyA9PSBycCkgewoJICBpc3AtPnJlcXVlc3RzID0gcnAtPm5leHRfcmVxdWVzdDsKCSAgaWYgKGlzcC0+cmVxdWVzdHNFbmQgPT0gcnApIHsKCSAgICBpc3AtPnJlcXVlc3RzRW5kID0gTlVMTDsKCSAgfQoJfSBlbHNlIHsKCSAgb3JwLT5uZXh0X3JlcXVlc3QgPSBycC0+bmV4dF9yZXF1ZXN0OwoJICBpZiAoaXNwLT5yZXF1ZXN0c0VuZCA9PSBycCkgewoJICAgIGlzcC0+cmVxdWVzdHNFbmQgPSBvcnA7CgkgIH0KCX0KCXNubXBfZnJlZV9wZHUocnAtPnBkdSk7CglmcmVlKChjaGFyICopIHJwKTsKCS8qCgkgKiBUaGVyZSBzaG91bGRuJ3QgYmUgYW55IG1vcmUgcmVxdWVzdHMgd2l0aCB0aGUgc2FtZSByZXFpZC4gIAoJICovCglicmVhazsKICAgICAgfQogICAgICAvKgogICAgICAgKiBNVFIgc25tcF9yZXNfdW5sb2NrKE1UX0xJQlJBUllfSUQsIE1UX0xJQl9TRVNTSU9OKTsgID8qIFhYIGxvY2sgc2hvdWxkIGJlIHBlciBzZXNzaW9uICEgCiAgICAgICAqLwogICAgfQogIH0gZWxzZSB7CiAgICBpZiAoc3AtPmNhbGxiYWNrKSB7CiAgICAgIC8qCiAgICAgICAqIE1UUiBzbm1wX3Jlc19sb2NrKE1UX0xJQlJBUllfSUQsIE1UX0xJQl9TRVNTSU9OKTsgCiAgICAgICAqLwogICAgICBoYW5kbGVkID0gMTsKICAgICAgc3AtPmNhbGxiYWNrKE5FVFNOTVBfQ0FMTEJBQ0tfT1BfUkVDRUlWRURfTUVTU0FHRSwKCQkgICBzcCwgcGR1LT5yZXFpZCwgcGR1LCBzcC0+Y2FsbGJhY2tfbWFnaWMpOwogICAgICAvKgogICAgICAgKiBNVFIgc25tcF9yZXNfdW5sb2NrKE1UX0xJQlJBUllfSUQsIE1UX0xJQl9TRVNTSU9OKTsgCiAgICAgICAqLwogICAgfQogIH0KCiAgLyoKICAgKiBDYWxsIFVTTSB0byBmcmVlIGFueSBzZWN1cml0eVN0YXRlUmVmIHN1cHBsaWVkIHdpdGggdGhlIG1lc3NhZ2UuICAKICAgKi8KICBpZiAocGR1ICE9IE5VTEwgJiYgcGR1LT5zZWN1cml0eVN0YXRlUmVmICYmCiAgICAgIHBkdS0+Y29tbWFuZCA9PSBTTk1QX01TR19UUkFQMikgewogICAgc3B0ciA9IGZpbmRfc2VjX21vZChwZHUtPnNlY3VyaXR5TW9kZWwpOwogICAgaWYgKHNwdHIpIHsKICAgICAgaWYgKHNwdHItPnBkdV9mcmVlX3N0YXRlX3JlZikgewoJKCpzcHRyLT5wZHVfZnJlZV9zdGF0ZV9yZWYpIChwZHUtPnNlY3VyaXR5U3RhdGVSZWYpOwogICAgICB9IGVsc2UgewoJc25tcF9sb2coTE9HX0VSUiwKCQkgIlNlY3VyaXR5IE1vZGVsICVkIGNhbid0IGZyZWUgc3RhdGUgcmVmZXJlbmNlc1xuIiwKCQkgcGR1LT5zZWN1cml0eU1vZGVsKTsKICAgICAgfQogICAgfSBlbHNlIHsKICAgICAgc25tcF9sb2coTE9HX0VSUiwKCSAgICAgICAiQ2FuJ3QgZmluZCBzZWN1cml0eSBtb2RlbCB0byBmcmVlIHB0cjogJWRcbiIsCgkgICAgICAgcGR1LT5zZWN1cml0eU1vZGVsKTsKICAgIH0KICAgIHBkdS0+c2VjdXJpdHlTdGF0ZVJlZiA9IE5VTEw7CiAgfQoKICBpZiAoIWhhbmRsZWQpIHsKICAgIHNubXBfaW5jcmVtZW50X3N0YXRpc3RpYyhTVEFUX1NOTVBVTktOT1dOUERVSEFORExFUlMpOwogICAgREVCVUdNU0dUTCgoInNlc3NfcHJvY2Vzc19wYWNrZXQiLCAidW5oYW5kbGVkIFBEVVxuIikpOwogIH0KCiAgc25tcF9mcmVlX3BkdShwZHUpOwogIHJldHVybiAwOwp9CgovKgogKiBDaGVja3MgdG8gc2VlIGlmIGFueSBvZiB0aGUgZmQncyBzZXQgaW4gdGhlIGZkc2V0IGJlbG9uZyB0bwogKiBzbm1wLiAgRWFjaCBzb2NrZXQgd2l0aCBpdCdzIGZkIHNldCBoYXMgYSBwYWNrZXQgcmVhZCBmcm9tIGl0CiAqIGFuZCBzbm1wX3BhcnNlIGlzIGNhbGxlZCBvbiB0aGUgcGFja2V0IHJlY2VpdmVkLiAgVGhlIHJlc3VsdGluZyBwZHUKICogaXMgcGFzc2VkIHRvIHRoZSBjYWxsYmFjayByb3V0aW5lIGZvciB0aGF0IHNlc3Npb24uICBJZiB0aGUgY2FsbGJhY2sKICogcm91dGluZSByZXR1cm5zIHN1Y2Nlc3NmdWxseSwgdGhlIHBkdSBhbmQgaXQncyByZXF1ZXN0IGFyZSBkZWxldGVkLgogKi8Kdm9pZApzbm1wX3JlYWQoZmRfc2V0ICogZmRzZXQpCnsKICAgIG5ldHNubXBfbGFyZ2VfZmRfc2V0IGxmZHNldDsKCiAgICBuZXRzbm1wX2xhcmdlX2ZkX3NldF9pbml0KCZsZmRzZXQsIEZEX1NFVFNJWkUpOwogICAgbmV0c25tcF9jb3B5X2ZkX3NldF90b19sYXJnZV9mZF9zZXQoJmxmZHNldCwgZmRzZXQpOwogICAgc25tcF9yZWFkMigmbGZkc2V0KTsKICAgIG5ldHNubXBfbGFyZ2VfZmRfc2V0X2NsZWFudXAoJmxmZHNldCk7Cn0KCnZvaWQKc25tcF9yZWFkMihuZXRzbm1wX2xhcmdlX2ZkX3NldCAqIGZkc2V0KQp7CiAgICBzdHJ1Y3Qgc2Vzc2lvbl9saXN0ICpzbHA7CiAgICBzbm1wX3Jlc19sb2NrKE1UX0xJQlJBUllfSUQsIE1UX0xJQl9TRVNTSU9OKTsKICAgIGZvciAoc2xwID0gU2Vzc2lvbnM7IHNscDsgc2xwID0gc2xwLT5uZXh0KSB7CiAgICAgICAgc25tcF9zZXNzX3JlYWQyKCh2b2lkICopIHNscCwgZmRzZXQpOwogICAgfQogICAgc25tcF9yZXNfdW5sb2NrKE1UX0xJQlJBUllfSUQsIE1UX0xJQl9TRVNTSU9OKTsKfQoKLyoKICogU2FtZSBhcyBzbm1wX3JlYWQsIGJ1dCB3b3JrcyBqdXN0IG9uZSBzZXNzaW9uLiAKICogcmV0dXJucyAwIGlmIHN1Y2Nlc3MsIC0xIGlmIGZhaWwgCiAqIE1UUjogY2FuJ3QgbG9jayBoZXJlIGFuZCBhdCBzbm1wX3JlYWQgCiAqIEJld2FyZSByZWN1cnNpdmUgc2VuZCBtYXliZSBpbnNpZGUgc25tcF9yZWFkIGNhbGxiYWNrIGZ1bmN0aW9uLiAKICovCmludApfc2Vzc19yZWFkKHZvaWQgKnNlc3NwLCBuZXRzbm1wX2xhcmdlX2ZkX3NldCAqIGZkc2V0KQp7CiAgICBzdHJ1Y3Qgc2Vzc2lvbl9saXN0ICpzbHAgPSAoc3RydWN0IHNlc3Npb25fbGlzdCAqKSBzZXNzcDsKICAgIG5ldHNubXBfc2Vzc2lvbiAqc3AgPSBzbHAgPyBzbHAtPnNlc3Npb24gOiBOVUxMOwogICAgc3RydWN0IHNubXBfaW50ZXJuYWxfc2Vzc2lvbiAqaXNwID0gc2xwID8gc2xwLT5pbnRlcm5hbCA6IE5VTEw7CiAgICBuZXRzbm1wX3RyYW5zcG9ydCAqdHJhbnNwb3J0ID0gc2xwID8gc2xwLT50cmFuc3BvcnQgOiBOVUxMOwogICAgc2l6ZV90ICAgICAgICAgIHBkdWxlbiA9IDAsIHJ4YnVmX2xlbiA9IDY1NTM2OwogICAgdV9jaGFyICAgICAgICAgKnJ4YnVmID0gTlVMTDsKICAgIGludCAgICAgICAgICAgICBsZW5ndGggPSAwLCBvbGVuZ3RoID0gMCwgcmMgPSAwOwogICAgdm9pZCAgICAgICAgICAgKm9wYXF1ZSA9IE5VTEw7CgogICAgaWYgKCFzcCB8fCAhaXNwIHx8ICF0cmFuc3BvcnQpIHsKICAgICAgICBERUJVR01TR1RMKCgic2Vzc19yZWFkIiwgInJlYWQgZmFpbDogY2xvc2luZy4uLlxuIikpOwogICAgICAgIHJldHVybiAwOwogICAgfQoKICAgIC8qIHRvIGF2b2lkIHN1YmFnZW50IGNyYXNoICovIAogICAgaWYgKHRyYW5zcG9ydC0+c29jayA8IDApIHsgCiAgICAgICAgc25tcF9sb2cgKExPR19JTkZPLCAidHJhbnNwb3J0LT5zb2NrIGdvdCBuZWdhdGl2ZSBmZCB2YWx1ZSAlZFxuIiwgdHJhbnNwb3J0LT5zb2NrKTsKICAgICAgICByZXR1cm4gMDsgCiAgICB9CgogICAgaWYgKCFmZHNldCB8fCAhKE5FVFNOTVBfTEFSR0VfRkRfSVNTRVQodHJhbnNwb3J0LT5zb2NrLCBmZHNldCkpKSB7CiAgICAgICAgREVCVUdNU0dUTCgoInNlc3NfcmVhZCIsICJub3QgcmVhZGluZyAlZCAoZmRzZXQgJXAgc2V0ICVkKVxuIiwKICAgICAgICAgICAgICAgICAgICB0cmFuc3BvcnQtPnNvY2ssIGZkc2V0LAogICAgICAgICAgICAgICAgICAgIGZkc2V0ID8gTkVUU05NUF9MQVJHRV9GRF9JU1NFVCh0cmFuc3BvcnQtPnNvY2ssIGZkc2V0KQoJCSAgICA6IC05KSk7CiAgICAgICAgcmV0dXJuIDA7CiAgICB9CgogICAgc3AtPnNfc25tcF9lcnJubyA9IDA7CiAgICBzcC0+c19lcnJubyA9IDA7CgogICAgaWYgKHRyYW5zcG9ydC0+ZmxhZ3MgJiBORVRTTk1QX1RSQU5TUE9SVF9GTEFHX0xJU1RFTikgewogICAgICAgIGludCAgICAgICAgICAgICBkYXRhX3NvY2sgPSB0cmFuc3BvcnQtPmZfYWNjZXB0KHRyYW5zcG9ydCk7CgogICAgICAgIGlmIChkYXRhX3NvY2sgPj0gMCkgewogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBXZSd2ZSBzdWNjZXNzZnVsbHkgYWNjZXB0ZWQgYSBuZXcgc3RyZWFtLWJhc2VkIGNvbm5lY3Rpb24uCiAgICAgICAgICAgICAqIEl0J3Mgbm90IHRvbyBjbGVhciB3aGF0IHNob3VsZCBoYXBwZW4gaGVyZSBpZiB3ZSBhcmUgdXNpbmcgdGhlCiAgICAgICAgICAgICAqIHNpbmdsZS1zZXNzaW9uIEFQSSBhdCB0aGlzIHBvaW50LiAgQmFzaWNhbGx5IGEgInNlc3Npb24KICAgICAgICAgICAgICogYWNjZXB0ZWQiIGNhbGxiYWNrIGlzIHByb2JhYmx5IG5lZWRlZCB0byBoYW5kIHRoZSBuZXcgc2Vzc2lvbgogICAgICAgICAgICAgKiBvdmVyIHRvIHRoZSBhcHBsaWNhdGlvbi4KICAgICAgICAgICAgICogCiAgICAgICAgICAgICAqIEhvd2V2ZXIsIGZvciBub3csIGFzIGluIHRoZSBvcmlnaW5hbCBzbm1wX2FwaSwgd2Ugd2lsbCBBU1NVTUUKICAgICAgICAgICAgICogdGhhdCB3ZSdyZSB1c2luZyB0aGUgdHJhZGl0aW9uYWwgQVBJLCBhbmQgc2ltcGx5IGFkZCB0aGUgbmV3CiAgICAgICAgICAgICAqIHNlc3Npb24gdG8gdGhlIGxpc3QuICBOb3RlIHdlIGRvbid0IGhhdmUgdG8gZ2V0IHRoZSBTZXNzaW9uCiAgICAgICAgICAgICAqIGxpc3QgbG9jayBoZXJlLCBiZWNhdXNlIHVuZGVyIHRoYXQgYXNzdW1wdGlvbiB3ZSBhbHJlYWR5IGhvbGQKICAgICAgICAgICAgICogaXQgKHRoaXMgaXMgYWxzbyB3aHkgd2UgZG9uJ3QganVzdCB1c2Ugc25tcF9hZGQpLgogICAgICAgICAgICAgKiAKICAgICAgICAgICAgICogVGhlIG1vcmFsIG9mIHRoZSBzdG9yeSBpczogZG9uJ3QgdXNlIGxpc3RlbmluZyBzdHJlYW0tYmFzZWQKICAgICAgICAgICAgICogdHJhbnNwb3J0cyBpbiBhIG11bHRpLXRocmVhZGVkIGVudmlyb25tZW50IGJlY2F1c2Ugc29tZXRoaW5nCiAgICAgICAgICAgICAqIHdpbGwgZ28gSE9SUklCTFkgd3JvbmcgKGFuZCBhbHNvIHRoYXQgU05NUC9UQ1AgaXMgbm90IHRyaXZpYWwpLgogICAgICAgICAgICAgKiAKICAgICAgICAgICAgICogQW5vdGhlciBvcGVuIGlzc3VlOiB3aGF0IHNob3VsZCBoYXBwZW4gdG8gc29ja2V0cyB0aGF0IGhhdmUKICAgICAgICAgICAgICogYmVlbiBhY2NlcHQoKWVkIGZyb20gYSBsaXN0ZW5pbmcgc29ja2V0IHdoZW4gdGhhdCBvcmlnaW5hbAogICAgICAgICAgICAgKiBzb2NrZXQgaXMgY2xvc2VkPyAgSWYgdGhleSBhcmUgbGVmdCBvcGVuLCB0aGVuIGF0dGVtcHRpbmcgdG8KICAgICAgICAgICAgICogcmUtb3BlbiB0aGUgbGlzdGVuaW5nIHNvY2tldCB3aWxsIGZhaWwsIHdoaWNoIGlzIHNlbWFudGljYWxseQogICAgICAgICAgICAgKiBjb25mdXNpbmcuICBQZXJoYXBzIHRoZXJlIHNob3VsZCBiZSBzb21lIGtpbmQgb2YgY2hhaW5pbmcgaW4KICAgICAgICAgICAgICogdGhlIHRyYW5zcG9ydCBzdHJ1Y3R1cmUgc28gdGhhdCB0aGV5IGNhbiBhbGwgYmUgY2xvc2VkLgogICAgICAgICAgICAgKiBEaXNjdXNzLiAgOy0pCiAgICAgICAgICAgICAqLwoKCSAgICBuZXRzbm1wX3RyYW5zcG9ydCAqbmV3X3RyYW5zcG9ydD1uZXRzbm1wX3RyYW5zcG9ydF9jb3B5KHRyYW5zcG9ydCk7CiAgICAgICAgICAgIGlmIChuZXdfdHJhbnNwb3J0ICE9IE5VTEwpIHsKICAgICAgICAgICAgICAgIHN0cnVjdCBzZXNzaW9uX2xpc3QgKm5zbHAgPSBOVUxMOwoKICAgICAgICAgICAgICAgIG5ld190cmFuc3BvcnQtPnNvY2sgPSBkYXRhX3NvY2s7CiAgICAgICAgICAgICAgICBuZXdfdHJhbnNwb3J0LT5mbGFncyAmPSB+TkVUU05NUF9UUkFOU1BPUlRfRkxBR19MSVNURU47CgogICAgICAgICAgICAgICAgbnNscCA9IChzdHJ1Y3Qgc2Vzc2lvbl9saXN0ICopc25tcF9zZXNzX2FkZF9leChzcCwKCQkJICBuZXdfdHJhbnNwb3J0LCBpc3AtPmhvb2tfcHJlLCBpc3AtPmhvb2tfcGFyc2UsCgkJCSAgaXNwLT5ob29rX3Bvc3QsIGlzcC0+aG9va19idWlsZCwKCQkJICBpc3AtPmhvb2tfcmVhbGxvY19idWlsZCwgaXNwLT5jaGVja19wYWNrZXQsCgkJCSAgaXNwLT5ob29rX2NyZWF0ZV9wZHUpOwoKICAgICAgICAgICAgICAgIGlmIChuc2xwICE9IE5VTEwpIHsKICAgICAgICAgICAgICAgICAgICBuc2xwLT5uZXh0ID0gU2Vzc2lvbnM7CiAgICAgICAgICAgICAgICAgICAgU2Vzc2lvbnMgPSBuc2xwOwogICAgICAgICAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAgICAgICAgICogVGVsbCB0aGUgbmV3IHNlc3Npb24gYWJvdXQgaXRzIGV4aXN0YW5jZSBpZiBwb3NzaWJsZS4KICAgICAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgICAgICBERUJVR01TR1RMKCgic2Vzc19yZWFkIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAicGVyZm9ybSBjYWxsYmFjayB3aXRoIG9wPUNPTk5FQ1RcbiIpKTsKICAgICAgICAgICAgICAgICAgICAodm9pZCluc2xwLT5zZXNzaW9uLT5jYWxsYmFjayhORVRTTk1QX0NBTExCQUNLX09QX0NPTk5FQ1QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbnNscC0+c2Vzc2lvbiwgMCwgTlVMTCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzcC0+Y2FsbGJhY2tfbWFnaWMpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBzcC0+c19zbm1wX2Vycm5vID0gU05NUEVSUl9NQUxMT0M7CiAgICAgICAgICAgICAgICBzcC0+c19lcnJubyA9IGVycm5vOwogICAgICAgICAgICAgICAgc25tcF9zZXRfZGV0YWlsKHN0cmVycm9yKGVycm5vKSk7CiAgICAgICAgICAgICAgICByZXR1cm4gLTE7CiAgICAgICAgICAgIH0KICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBzcC0+c19zbm1wX2Vycm5vID0gU05NUEVSUl9CQURfUkVDVkZST007CiAgICAgICAgICAgIHNwLT5zX2Vycm5vID0gZXJybm87CiAgICAgICAgICAgIHNubXBfc2V0X2RldGFpbChzdHJlcnJvcihlcnJubykpOwogICAgICAgICAgICByZXR1cm4gLTE7CiAgICAgICAgfQogICAgfQoKICAgIC8qCiAgICAgKiBXb3JrIG91dCB3aGVyZSB0byByZWNlaXZlIHRoZSBkYXRhIHRvLiAgCiAgICAgKi8KCiAgICBpZiAodHJhbnNwb3J0LT5mbGFncyAmIE5FVFNOTVBfVFJBTlNQT1JUX0ZMQUdfU1RSRUFNKSB7CiAgICAgICAgaWYgKGlzcC0+cGFja2V0ID09IE5VTEwpIHsKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogV2UgaGF2ZSBubyBzYXZlZCBwYWNrZXQuICBBbGxvY2F0ZSBvbmUuICAKICAgICAgICAgICAgICovCiAgICAgICAgICAgIGlmICgoaXNwLT5wYWNrZXQgPSAodV9jaGFyICopIG1hbGxvYyhyeGJ1Zl9sZW4pKSA9PSBOVUxMKSB7CiAgICAgICAgICAgICAgICBERUJVR01TR1RMKCgic2Vzc19yZWFkIiwgImNhbid0IG1hbGxvYyAlIiBORVRTTk1QX1BSSXoKICAgICAgICAgICAgICAgICAgICAgICAgICAgICJ1IGJ5dGVzIGZvciByeGJ1ZlxuIiwgcnhidWZfbGVuKSk7CiAgICAgICAgICAgICAgICByZXR1cm4gMDsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHJ4YnVmID0gaXNwLT5wYWNrZXQ7CiAgICAgICAgICAgICAgICBpc3AtPnBhY2tldF9zaXplID0gcnhidWZfbGVuOwogICAgICAgICAgICAgICAgaXNwLT5wYWNrZXRfbGVuID0gMDsKICAgICAgICAgICAgfQogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIFdlIGhhdmUgc2F2ZWQgYSBwYXJ0aWFsIHBhY2tldCBmcm9tIGxhc3QgdGltZS4gIEV4dGVuZCB0aGF0LCBpZgogICAgICAgICAgICAgKiBuZWNlc3NhcnksIGFuZCByZWNlaXZlIG5ldyBkYXRhIGFmdGVyIHRoZSBvbGQgZGF0YS4gIAogICAgICAgICAgICAgKi8KICAgICAgICAgICAgdV9jaGFyICAgICAgICAgKm5ld2J1ZjsKCiAgICAgICAgICAgIGlmIChpc3AtPnBhY2tldF9zaXplIDwgaXNwLT5wYWNrZXRfbGVuICsgcnhidWZfbGVuKSB7CiAgICAgICAgICAgICAgICBuZXdidWYgPQogICAgICAgICAgICAgICAgICAgICh1X2NoYXIgKikgcmVhbGxvYyhpc3AtPnBhY2tldCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaXNwLT5wYWNrZXRfbGVuICsgcnhidWZfbGVuKTsKICAgICAgICAgICAgICAgIGlmIChuZXdidWYgPT0gTlVMTCkgewogICAgICAgICAgICAgICAgICAgIERFQlVHTVNHVEwoKCJzZXNzX3JlYWQiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJjYW4ndCBtYWxsb2MgJSIgTkVUU05NUF9QUkl6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgInUgbW9yZSBmb3IgcnhidWYgKCUiIE5FVFNOTVBfUFJJeiAidSB0b3QpXG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJ4YnVmX2xlbiwgaXNwLT5wYWNrZXRfbGVuICsgcnhidWZfbGVuKSk7CiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIGlzcC0+cGFja2V0ID0gbmV3YnVmOwogICAgICAgICAgICAgICAgICAgIGlzcC0+cGFja2V0X3NpemUgPSBpc3AtPnBhY2tldF9sZW4gKyByeGJ1Zl9sZW47CiAgICAgICAgICAgICAgICAgICAgcnhidWYgPSBpc3AtPnBhY2tldCArIGlzcC0+cGFja2V0X2xlbjsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHJ4YnVmID0gaXNwLT5wYWNrZXQgKyBpc3AtPnBhY2tldF9sZW47CiAgICAgICAgICAgICAgICByeGJ1Zl9sZW4gPSBpc3AtPnBhY2tldF9zaXplIC0gaXNwLT5wYWNrZXRfbGVuOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfSBlbHNlIHsKICAgICAgICBpZiAoKHJ4YnVmID0gKHVfY2hhciAqKSBtYWxsb2MocnhidWZfbGVuKSkgPT0gTlVMTCkgewogICAgICAgICAgICBERUJVR01TR1RMKCgic2Vzc19yZWFkIiwgImNhbid0IG1hbGxvYyAlIiBORVRTTk1QX1BSSXoKICAgICAgICAgICAgICAgICAgICAgICAgInUgYnl0ZXMgZm9yIHJ4YnVmXG4iLCByeGJ1Zl9sZW4pKTsKICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgfQogICAgfQoKICAgIGxlbmd0aCA9IG5ldHNubXBfdHJhbnNwb3J0X3JlY3YodHJhbnNwb3J0LCByeGJ1ZiwgcnhidWZfbGVuLCAmb3BhcXVlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmb2xlbmd0aCk7CgogICAgaWYgKGxlbmd0aCA9PSAtMSAmJiAhKHRyYW5zcG9ydC0+ZmxhZ3MgJiBORVRTTk1QX1RSQU5TUE9SVF9GTEFHX1NUUkVBTSkpIHsKICAgICAgICBzcC0+c19zbm1wX2Vycm5vID0gU05NUEVSUl9CQURfUkVDVkZST007CiAgICAgICAgc3AtPnNfZXJybm8gPSBlcnJubzsKICAgICAgICBzbm1wX3NldF9kZXRhaWwoc3RyZXJyb3IoZXJybm8pKTsKICAgICAgICBTTk1QX0ZSRUUocnhidWYpOwogICAgICAgIGlmIChvcGFxdWUgIT0gTlVMTCkgewogICAgICAgICAgICBTTk1QX0ZSRUUob3BhcXVlKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIC0xOwogICAgfQoKICAgIGlmICgwID09IGxlbmd0aCAmJiB0cmFuc3BvcnQtPmZsYWdzICYgTkVUU05NUF9UUkFOU1BPUlRfRkxBR19FTVBUWV9QS1QpIHsKICAgICAgICAvKiB0aGlzIGFsbG93cyBmb3IgYSB0cmFuc3BvcnQgdGhhdCBuZWVkcyB0byByZXR1cm4gZnJvbQogICAgICAgICAqIHBhY2tldCBwcm9jZXNzaW5nIHRoYXQgZG9lc24ndCBuZWNlc3NhcmlseSBoYXZlIGFueQogICAgICAgICAqIGNvbnN1bWFibGUgZGF0YSBpbiBpdC4gKi8KCiAgICAgICAgLyogcmVzZXQgdGhlIGZsYWcgc2luY2UgaXQncyBhIHBlci1tZXNzYWdlIGZsYWcgKi8KICAgICAgICB0cmFuc3BvcnQtPmZsYWdzICY9ICh+TkVUU05NUF9UUkFOU1BPUlRfRkxBR19FTVBUWV9QS1QpOwoKICAgICAgICByZXR1cm4gMDsKICAgIH0KCiAgICAvKgogICAgICogUmVtb3RlIGVuZCBjbG9zZWQgY29ubmVjdGlvbi4gIAogICAgICovCgogICAgaWYgKGxlbmd0aCA8PSAwICYmIHRyYW5zcG9ydC0+ZmxhZ3MgJiBORVRTTk1QX1RSQU5TUE9SVF9GTEFHX1NUUkVBTSkgewogICAgICAgIC8qCiAgICAgICAgICogQWxlcnQgdGhlIGFwcGxpY2F0aW9uIGlmIHBvc3NpYmxlLiAgCiAgICAgICAgICovCiAgICAgICAgaWYgKHNwLT5jYWxsYmFjayAhPSBOVUxMKSB7CiAgICAgICAgICAgIERFQlVHTVNHVEwoKCJzZXNzX3JlYWQiLCAicGVyZm9ybSBjYWxsYmFjayB3aXRoIG9wPURJU0NPTk5FQ1RcbiIpKTsKICAgICAgICAgICAgKHZvaWQpIHNwLT5jYWxsYmFjayhORVRTTk1QX0NBTExCQUNLX09QX0RJU0NPTk5FQ1QsIHNwLCAwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5VTEwsIHNwLT5jYWxsYmFja19tYWdpYyk7CiAgICAgICAgfQogICAgICAgIC8qCiAgICAgICAgICogQ2xvc2Ugc29ja2V0IGFuZCBtYXJrIHNlc3Npb24gZm9yIGRlbGV0aW9uLiAgCiAgICAgICAgICovCiAgICAgICAgREVCVUdNU0dUTCgoInNlc3NfcmVhZCIsICJmZCAlZCBjbG9zZWRcbiIsIHRyYW5zcG9ydC0+c29jaykpOwogICAgICAgIHRyYW5zcG9ydC0+Zl9jbG9zZSh0cmFuc3BvcnQpOwogICAgICAgIFNOTVBfRlJFRShpc3AtPnBhY2tldCk7CiAgICAgICAgaWYgKG9wYXF1ZSAhPSBOVUxMKSB7CiAgICAgICAgICAgIFNOTVBfRlJFRShvcGFxdWUpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gLTE7CiAgICB9CgogICAgaWYgKHRyYW5zcG9ydC0+ZmxhZ3MgJiBORVRTTk1QX1RSQU5TUE9SVF9GTEFHX1NUUkVBTSkgewogICAgICAgIHVfY2hhciAqcHB0ciA9IGlzcC0+cGFja2V0OwoJdm9pZCAqb2NvcHkgPSBOVUxMOwoKICAgICAgICBpc3AtPnBhY2tldF9sZW4gKz0gbGVuZ3RoOwoKICAgICAgICB3aGlsZSAoaXNwLT5wYWNrZXRfbGVuID4gMCkgewoKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogR2V0IHRoZSB0b3RhbCBkYXRhIGxlbmd0aCB3ZSdyZSBleHBlY3RpbmcgKGFuZCBuZWVkIHRvIHdhaXQKICAgICAgICAgICAgICogZm9yKS4KICAgICAgICAgICAgICovCiAgICAgICAgICAgIGlmIChpc3AtPmNoZWNrX3BhY2tldCkgewogICAgICAgICAgICAgICAgcGR1bGVuID0gaXNwLT5jaGVja19wYWNrZXQocHB0ciwgaXNwLT5wYWNrZXRfbGVuKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHBkdWxlbiA9IGFzbl9jaGVja19wYWNrZXQocHB0ciwgaXNwLT5wYWNrZXRfbGVuKTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgREVCVUdNU0dUTCgoInNlc3NfcmVhZCIsCiAgICAgICAgICAgICAgICAgICAgICAgICIgIGxvb3AgcGFja2V0X2xlbiAlIiBORVRTTk1QX1BSSXogInUsIFBEVSBsZW5ndGggJSIKICAgICAgICAgICAgICAgICAgICAgICAgTkVUU05NUF9QUkl6ICJ1XG4iLCBpc3AtPnBhY2tldF9sZW4sIHBkdWxlbikpOwoKICAgICAgICAgICAgaWYgKHBkdWxlbiA+IE1BWF9QQUNLRVRfTEVOR1RIKSB7CiAgICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAgICogSWxsZWdhbCBsZW5ndGgsIGRyb3AgdGhlIGNvbm5lY3Rpb24uICAKICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgc25tcF9sb2coTE9HX0VSUiwgCgkJCSAiUmVjZWl2ZWQgYnJva2VuIHBhY2tldC4gQ2xvc2luZyBzZXNzaW9uLlxuIik7CgkJaWYgKHNwLT5jYWxsYmFjayAhPSBOVUxMKSB7CgkJICBERUJVR01TR1RMKCgic2Vzc19yZWFkIiwKCQkJICAgICAgInBlcmZvcm0gY2FsbGJhY2sgd2l0aCBvcD1ESVNDT05ORUNUXG4iKSk7CgkJICAodm9pZClzcC0+Y2FsbGJhY2soTkVUU05NUF9DQUxMQkFDS19PUF9ESVNDT05ORUNULAoJCQkJICAgICBzcCwgMCwgTlVMTCwgc3AtPmNhbGxiYWNrX21hZ2ljKTsKCQl9CgkJREVCVUdNU0dUTCgoInNlc3NfcmVhZCIsICJmZCAlZCBjbG9zZWRcbiIsIHRyYW5zcG9ydC0+c29jaykpOwogICAgICAgICAgICAgICAgdHJhbnNwb3J0LT5mX2Nsb3NlKHRyYW5zcG9ydCk7CiAgICAgICAgICAgICAgICBpZiAob3BhcXVlICE9IE5VTEwpIHsKICAgICAgICAgICAgICAgICAgICBTTk1QX0ZSRUUob3BhcXVlKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIC8qKiBYWFgtcmtzOiB3aHkgbm8gU05NUF9GUkVFKGlzcC0+cGFja2V0KTsgPz8gKi8KICAgICAgICAgICAgICAgIHJldHVybiAtMTsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgaWYgKHBkdWxlbiA+IGlzcC0+cGFja2V0X2xlbiB8fCBwZHVsZW4gPT0gMCkgewogICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAqIFdlIGRvbid0IGhhdmUgYSBjb21wbGV0ZSBwYWNrZXQgeWV0LiAgSWYgd2UndmUgYWxyZWFkeQogICAgICAgICAgICAgICAgICogcHJvY2Vzc2VkIGEgcGFja2V0LCBicmVhayBvdXQgc28gd2UnbGwgc2hpZnQgdGhpcyBwYWNrZXQKICAgICAgICAgICAgICAgICAqIHRvIHRoZSBzdGFydCBvZiB0aGUgYnVmZmVyLiBJZiB3ZSdyZSBhbHJlYWR5IGF0IHRoZQogICAgICAgICAgICAgICAgICogc3RhcnQsIHNpbXBseSByZXR1cm4gYW5kIHdhaXQgZm9yIG1vcmUgZGF0YSB0byBhcnJpdmUuCiAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgIERFQlVHTVNHVEwoKCJzZXNzX3JlYWQiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgInBrdCBub3QgY29tcGxldGUgKG5lZWQgJSIgTkVUU05NUF9QUkl6ICJ1IGdvdCAlIgogICAgICAgICAgICAgICAgICAgICAgICAgICAgTkVUU05NUF9QUkl6ICJ1IHNvIGZhcilcbiIsIHBkdWxlbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlzcC0+cGFja2V0X2xlbikpOwoKICAgICAgICAgICAgICAgIGlmIChwcHRyICE9IGlzcC0+cGFja2V0KQogICAgICAgICAgICAgICAgICAgIGJyZWFrOyAvKiBvcGFxdWUgZnJlZWQgZm9yIHVzIG91dHNpZGUgb2YgbG9vcC4gKi8KCiAgICAgICAgICAgICAgICBpZiAob3BhcXVlICE9IE5VTEwpIHsKICAgICAgICAgICAgICAgICAgICBTTk1QX0ZSRUUob3BhcXVlKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHJldHVybiAwOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvKiAgV2UgaGF2ZSAqYXQgbGVhc3QqIG9uZSBjb21wbGV0ZSBwYWNrZXQgaW4gdGhlIGJ1ZmZlciBub3cuICBJZgoJCXdlIGhhdmUgcG9zc2libHkgbW9yZSB0aGFuIG9uZSBwYWNrZXQsIHdlIG11c3QgY29weSB0aGUgb3BhcXVlCgkJcG9pbnRlciBiZWNhdXNlIHdlIG1heSBuZWVkIHRvIHJldXNlIGl0IGZvciBhIGxhdGVyIHBhY2tldC4gICovCgoJICAgIGlmIChwZHVsZW4gPCBpc3AtPnBhY2tldF9sZW4pIHsKCQlpZiAob2xlbmd0aCA+IDAgJiYgb3BhcXVlICE9IE5VTEwpIHsKCQkgICAgb2NvcHkgPSBtYWxsb2Mob2xlbmd0aCk7CgkJICAgIGlmIChvY29weSAhPSBOVUxMKSB7CgkJCW1lbWNweShvY29weSwgb3BhcXVlLCBvbGVuZ3RoKTsKCQkgICAgfQoJCX0KCSAgICB9IGVsc2UgaWYgKHBkdWxlbiA9PSBpc3AtPnBhY2tldF9sZW4pIHsKCQkvKiAgQ29tbW9uIGNhc2UgLS0gZXhhY3RseSBvbmUgcGFja2V0LiAgTm8gbmVlZCB0byBjb3B5IHRoZQoJCSAgICBvcGFxdWUgcG9pbnRlci4gICovCgkJb2NvcHkgPSBvcGFxdWU7CgkJb3BhcXVlID0gTlVMTDsKCSAgICB9CgogICAgICAgICAgICBpZiAoKHJjID0gX3Nlc3NfcHJvY2Vzc19wYWNrZXQoc2Vzc3AsIHNwLCBpc3AsIHRyYW5zcG9ydCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9jb3B5LCBvY29weT9vbGVuZ3RoOjAsIHBwdHIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwZHVsZW4pKSkgewogICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAqIFNvbWV0aGluZyB3ZW50IHdyb25nIHdoaWxlIHByb2Nlc3NpbmcgdGhpcyBwYWNrZXQgLS0gc2V0IHRoZQogICAgICAgICAgICAgICAgICogZXJybm8uICAKICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgaWYgKHNwLT5zX3NubXBfZXJybm8gIT0gMCkgewogICAgICAgICAgICAgICAgICAgIFNFVF9TTk1QX0VSUk9SKHNwLT5zX3NubXBfZXJybm8pOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CgoJICAgIC8qICBvY29weSBoYXMgYmVlbiBmcmVlKClkIGJ5IF9zZXNzX3Byb2Nlc3NfcGFja2V0IGJ5IHRoaXMgcG9pbnQsCgkJc28gc2V0IGl0IHRvIE5VTEwuICAqLwoKCSAgICBvY29weSA9IE5VTEw7CgoJICAgIC8qICBTdGVwIHBhc3QgdGhlIHBhY2tldCB3ZSd2ZSBqdXN0IGRlYWx0IHdpdGguICAqLwoKICAgICAgICAgICAgcHB0ciArPSBwZHVsZW47CiAgICAgICAgICAgIGlzcC0+cGFja2V0X2xlbiAtPSBwZHVsZW47CiAgICAgICAgfQoKCS8qICBJZiB3ZSBoYWQgbW9yZSB0aGFuIG9uZSBwYWNrZXQsIHRoZW4gd2Ugd2VyZSB3b3JraW5nIHdpdGggY29waWVzCgkgICAgb2YgdGhlIG9wYXF1ZSBwb2ludGVyLCBzbyB3ZSBzdGlsbCBuZWVkIHRvIGZyZWUoKSB0aGUgb3BhcXVlCgkgICAgcG9pbnRlciBpdHNlbGYuICAqLwoKCWlmIChvcGFxdWUgIT0gTlVMTCkgewoJICAgIFNOTVBfRlJFRShvcGFxdWUpOwoJfQoKICAgICAgICBpZiAoaXNwLT5wYWNrZXRfbGVuID49IE1BWElNVU1fUEFDS0VUX1NJWkUpIHsKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogT2J2aW91c2x5IHRoaXMgc2hvdWxkIG5ldmVyIGhhcHBlbiEgIAogICAgICAgICAgICAgKi8KICAgICAgICAgICAgc25tcF9sb2coTE9HX0VSUiwKICAgICAgICAgICAgICAgICAgICAgInRvbyBsYXJnZSBwYWNrZXRfbGVuID0gJSIgTkVUU05NUF9QUkl6CiAgICAgICAgICAgICAgICAgICAgICJ1LCBkcm9wcGluZyBjb25uZWN0aW9uICVkXG4iLAogICAgICAgICAgICAgICAgICAgICBpc3AtPnBhY2tldF9sZW4sIHRyYW5zcG9ydC0+c29jayk7CiAgICAgICAgICAgIHRyYW5zcG9ydC0+Zl9jbG9zZSh0cmFuc3BvcnQpOwogICAgICAgICAgICAvKiogWFhYLXJrczogd2h5IG5vIFNOTVBfRlJFRShpc3AtPnBhY2tldCk7ID8/ICovCiAgICAgICAgICAgIHJldHVybiAtMTsKICAgICAgICB9IGVsc2UgaWYgKGlzcC0+cGFja2V0X2xlbiA9PSAwKSB7CiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIFRoaXMgaXMgZ29vZDogaXQgbWVhbnMgdGhlIHBhY2tldCBidWZmZXIgY29udGFpbmVkIGFuIGludGVncmFsCiAgICAgICAgICAgICAqIG51bWJlciBvZiBQRFVzLCBzbyB3ZSBkb24ndCBoYXZlIHRvIHNhdmUgYW55IGRhdGEgZm9yIG5leHQKICAgICAgICAgICAgICogdGltZS4gIFdlIGNhbiBmcmVlKCkgdGhlIGJ1ZmZlciBub3cgdG8ga2VlcCB0aGUgbWVtb3J5CiAgICAgICAgICAgICAqIGZvb3RwcmludCBkb3duLgogICAgICAgICAgICAgKi8KICAgICAgICAgICAgU05NUF9GUkVFKGlzcC0+cGFja2V0KTsKICAgICAgICAgICAgaXNwLT5wYWNrZXQgPSBOVUxMOwogICAgICAgICAgICBpc3AtPnBhY2tldF9zaXplID0gMDsKICAgICAgICAgICAgaXNwLT5wYWNrZXRfbGVuID0gMDsKICAgICAgICAgICAgcmV0dXJuIHJjOwogICAgICAgIH0KCiAgICAgICAgLyoKICAgICAgICAgKiBJZiB3ZSBnZXQgaGVyZSwgdGhlbiB0aGVyZSBpcyBhIHBhcnRpYWwgcGFja2V0IG9mIGxlbmd0aAogICAgICAgICAqIGlzcC0+cGFja2V0X2xlbiBieXRlcyBzdGFydGluZyBhdCBwcHRyIGxlZnQgb3Zlci4gIE1vdmUgdGhhdCB0byB0aGUKICAgICAgICAgKiBzdGFydCBvZiB0aGUgYnVmZmVyLCBhbmQgdGhlbiByZWFsbG9jKCkgdGhlIGJ1ZmZlciBkb3duIHRvIHNpemUgdG8KICAgICAgICAgKiByZWR1Y2UgdGhlIG1lbW9yeSBmb290cHJpbnQuICAKICAgICAgICAgKi8KCiAgICAgICAgbWVtbW92ZShpc3AtPnBhY2tldCwgcHB0ciwgaXNwLT5wYWNrZXRfbGVuKTsKICAgICAgICBERUJVR01TR1RMKCgic2Vzc19yZWFkIiwKICAgICAgICAgICAgICAgICAgICAiZW5kOiBtZW1tb3ZlKCVwLCAlcCwgJSIgTkVUU05NUF9QUkl6ICJ1KTsgcmVhbGxvYyglcCwgJSIKICAgICAgICAgICAgICAgICAgICBORVRTTk1QX1BSSXogInUpXG4iLAogICAgICAgICAgICAgICAgICAgIGlzcC0+cGFja2V0LCBwcHRyLCBpc3AtPnBhY2tldF9sZW4sCgkJICAgIGlzcC0+cGFja2V0LCBpc3AtPnBhY2tldF9sZW4pKTsKCiAgICAgICAgaWYgKChyeGJ1ZiA9ICh1X2NoYXIgKilyZWFsbG9jKGlzcC0+cGFja2V0LCBpc3AtPnBhY2tldF9sZW4pKSA9PSBOVUxMKSB7CiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIEkgZG9uJ3Qgc2VlIHdoeSB0aGlzIHNob3VsZCBldmVyIGZhaWwsIGJ1dCBpdCdzIG5vdCBhIGJpZyBkZWFsLgogICAgICAgICAgICAgKi8KICAgICAgICAgICAgREVCVUdNU0dUTCgoInNlc3NfcmVhZCIsICJyZWFsbG9jKCkgZmFpbGVkXG4iKSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgREVCVUdNU0dUTCgoInNlc3NfcmVhZCIsICJyZWFsbG9jKCkgb2theSwgb2xkIGJ1ZmZlciAlcCwgbmV3ICVwXG4iLAogICAgICAgICAgICAgICAgICAgICAgICBpc3AtPnBhY2tldCwgcnhidWYpKTsKICAgICAgICAgICAgaXNwLT5wYWNrZXQgPSByeGJ1ZjsKICAgICAgICAgICAgaXNwLT5wYWNrZXRfc2l6ZSA9IGlzcC0+cGFja2V0X2xlbjsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJjOwogICAgfSBlbHNlIHsKICAgICAgICByYyA9IF9zZXNzX3Byb2Nlc3NfcGFja2V0KHNlc3NwLCBzcCwgaXNwLCB0cmFuc3BvcnQsIG9wYXF1ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9sZW5ndGgsIHJ4YnVmLCBsZW5ndGgpOwogICAgICAgIFNOTVBfRlJFRShyeGJ1Zik7CiAgICAgICAgcmV0dXJuIHJjOwogICAgfQp9CgoKCi8qCiAqIHJldHVybnMgMCBpZiBzdWNjZXNzLCAtMSBpZiBmYWlsIAogKi8KaW50CnNubXBfc2Vzc19yZWFkKHZvaWQgKnNlc3NwLCBmZF9zZXQgKiBmZHNldCkKewogIGludCByYzsKICBuZXRzbm1wX2xhcmdlX2ZkX3NldCBsZmRzZXQ7CiAgCiAgbmV0c25tcF9sYXJnZV9mZF9zZXRfaW5pdCgmbGZkc2V0LCBGRF9TRVRTSVpFKTsKICBuZXRzbm1wX2NvcHlfZmRfc2V0X3RvX2xhcmdlX2ZkX3NldCgmbGZkc2V0LCBmZHNldCk7CiAgcmMgPSBzbm1wX3Nlc3NfcmVhZDIoc2Vzc3AsICZsZmRzZXQpOwogIG5ldHNubXBfbGFyZ2VfZmRfc2V0X2NsZWFudXAoJmxmZHNldCk7CiAgcmV0dXJuIHJjOwp9CgppbnQKc25tcF9zZXNzX3JlYWQyKHZvaWQgKnNlc3NwLCBuZXRzbm1wX2xhcmdlX2ZkX3NldCAqIGZkc2V0KQp7CiAgICBzdHJ1Y3Qgc2Vzc2lvbl9saXN0ICpwc2w7CiAgICBuZXRzbm1wX3Nlc3Npb24gKnBzczsKICAgIGludCAgICAgICAgICAgICByYzsKCiAgICByYyA9IF9zZXNzX3JlYWQoc2Vzc3AsIGZkc2V0KTsKICAgIHBzbCA9IChzdHJ1Y3Qgc2Vzc2lvbl9saXN0ICopIHNlc3NwOwogICAgcHNzID0gcHNsLT5zZXNzaW9uOwogICAgaWYgKHJjICYmIHBzcy0+c19zbm1wX2Vycm5vKSB7CiAgICAgICAgU0VUX1NOTVBfRVJST1IocHNzLT5zX3NubXBfZXJybm8pOwogICAgfQogICAgcmV0dXJuIHJjOwp9CgoKLyoqCiAqIFJldHVybnMgaW5mbyBhYm91dCB3aGF0IHNubXAgcmVxdWlyZXMgZnJvbSBhIHNlbGVjdCBzdGF0ZW1lbnQuCiAqIG51bWZkcyBpcyB0aGUgbnVtYmVyIG9mIGZkcyBpbiB0aGUgbGlzdCB0aGF0IGFyZSBzaWduaWZpY2FudC4KICogQWxsIGZpbGUgZGVzY3JpcHRvcnMgb3BlbmVkIGZvciBTTk1QIGFyZSBPUidkIGludG8gdGhlIGZkc2V0LgogKiBJZiBhY3Rpdml0eSBvY2N1cnMgb24gYW55IG9mIHRoZXNlIGZpbGUgZGVzY3JpcHRvcnMsIHNubXBfcmVhZAogKiBzaG91bGQgYmUgY2FsbGVkIHdpdGggdGhhdCBmaWxlIGRlc2NyaXB0b3Igc2V0CiAqCiAqIFRoZSB0aW1lb3V0IGlzIHRoZSBsYXRlc3QgdGltZSB0aGF0IFNOTVAgY2FuIHdhaXQgZm9yIGEgdGltZW91dC4gIFRoZQogKiBzZWxlY3Qgc2hvdWxkIGJlIGRvbmUgd2l0aCB0aGUgbWluaW11bSB0aW1lIGJldHdlZW4gdGltZW91dCBhbmQgYW55IG90aGVyCiAqIHRpbWVvdXRzIG5lY2Vzc2FyeS4gIFRoaXMgc2hvdWxkIGJlIGNoZWNrZWQgdXBvbiBlYWNoIGludm9jYXRpb24gb2Ygc2VsZWN0LgogKiBJZiBhIHRpbWVvdXQgaXMgcmVjZWl2ZWQsIHNubXBfdGltZW91dCBzaG91bGQgYmUgY2FsbGVkIHRvIGNoZWNrIGlmIHRoZQogKiB0aW1lb3V0IHdhcyBmb3IgU05NUC4gIChzbm1wX3RpbWVvdXQgaXMgaWRlbXBvdGVudCkKICoKICogVGhlIHZhbHVlIG9mIGJsb2NrIGluZGljYXRlcyBob3cgdGhlIHRpbWVvdXQgdmFsdWUgaXMgaW50ZXJwcmV0ZWQuCiAqIElmIGJsb2NrIGlzIHRydWUgb24gaW5wdXQsIHRoZSB0aW1lb3V0IHZhbHVlIHdpbGwgYmUgdHJlYXRlZCBhcyB1bmRlZmluZWQsCiAqIGJ1dCBpdCBtdXN0IGJlIGF2YWlsYWJsZSBmb3Igc2V0dGluZyBpbiBzbm1wX3NlbGVjdF9pbmZvLiAgT24gcmV0dXJuLAogKiBibG9jayBpcyBzZXQgdG8gdHJ1ZSBpZiB0aGUgdmFsdWUgcmV0dXJuZWQgZm9yIHRpbWVvdXQgaXMgdW5kZWZpbmVkOwogKiB3aGVuIGJsb2NrIGlzIHNldCB0byBmYWxzZSwgdGltZW91dCBtYXkgYmUgdXNlZCBhcyBhIHBhcm1ldGVyIHRvICdzZWxlY3QnLgogKgogKiBzbm1wX3NlbGVjdF9pbmZvIHJldHVybnMgdGhlIG51bWJlciBvZiBvcGVuIHNvY2tldHMuICAoaS5lLiBUaGUgbnVtYmVyIG9mCiAqIHNlc3Npb25zIG9wZW4pCiAqCiAqIEBzZWUgU2VlIGFsc28gc25tcF9zZXNzX3NlbGVjdF9pbmZvMl9mbGFncygpLgogKi8KaW50CnNubXBfc2VsZWN0X2luZm8oaW50ICpudW1mZHMsIGZkX3NldCAqZmRzZXQsIHN0cnVjdCB0aW1ldmFsICp0aW1lb3V0LAogICAgICAgICAgICAgICAgIGludCAqYmxvY2spCnsKICAgIHJldHVybiBzbm1wX3Nlc3Nfc2VsZWN0X2luZm8oTlVMTCwgbnVtZmRzLCBmZHNldCwgdGltZW91dCwgYmxvY2spOwp9CgovKioKICogQHNlZSBTZWUgYWxzbyBzbm1wX3Nlc3Nfc2VsZWN0X2luZm8yX2ZsYWdzKCkuCiAqLwppbnQKc25tcF9zZWxlY3RfaW5mbzIoaW50ICpudW1mZHMsIG5ldHNubXBfbGFyZ2VfZmRfc2V0ICpmZHNldCwKCQkgIHN0cnVjdCB0aW1ldmFsICp0aW1lb3V0LCBpbnQgKmJsb2NrKQp7CiAgICByZXR1cm4gc25tcF9zZXNzX3NlbGVjdF9pbmZvMihOVUxMLCBudW1mZHMsIGZkc2V0LCB0aW1lb3V0LCBibG9jayk7Cn0KCi8qKgogKiBAc2VlIFNlZSBhbHNvIHNubXBfc2Vzc19zZWxlY3RfaW5mbzJfZmxhZ3MoKS4KICovCmludApzbm1wX3Nlc3Nfc2VsZWN0X2luZm8odm9pZCAqc2Vzc3AsIGludCAqbnVtZmRzLCBmZF9zZXQgKmZkc2V0LAogICAgICAgICAgICAgICAgICAgICAgc3RydWN0IHRpbWV2YWwgKnRpbWVvdXQsIGludCAqYmxvY2spCnsKICAgIHJldHVybiBzbm1wX3Nlc3Nfc2VsZWN0X2luZm9fZmxhZ3Moc2Vzc3AsIG51bWZkcywgZmRzZXQsIHRpbWVvdXQsIGJsb2NrLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBORVRTTk1QX1NFTEVDVF9OT0ZMQUdTKTsKfQogICAgICAgIAovKioKICogQHNlZSBTZWUgYWxzbyBzbm1wX3Nlc3Nfc2VsZWN0X2luZm8yX2ZsYWdzKCkuCiAqLwppbnQKc25tcF9zZXNzX3NlbGVjdF9pbmZvX2ZsYWdzKHZvaWQgKnNlc3NwLCBpbnQgKm51bWZkcywgZmRfc2V0ICpmZHNldCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cnVjdCB0aW1ldmFsICp0aW1lb3V0LCBpbnQgKmJsb2NrLCBpbnQgZmxhZ3MpCnsKICBpbnQgcmM7CiAgbmV0c25tcF9sYXJnZV9mZF9zZXQgbGZkc2V0OwoKICBuZXRzbm1wX2xhcmdlX2ZkX3NldF9pbml0KCZsZmRzZXQsIEZEX1NFVFNJWkUpOwogIG5ldHNubXBfY29weV9mZF9zZXRfdG9fbGFyZ2VfZmRfc2V0KCZsZmRzZXQsIGZkc2V0KTsKICByYyA9IHNubXBfc2Vzc19zZWxlY3RfaW5mbzJfZmxhZ3Moc2Vzc3AsIG51bWZkcywgJmxmZHNldCwgdGltZW91dCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYmxvY2ssIGZsYWdzKTsKICBpZiAobmV0c25tcF9jb3B5X2xhcmdlX2ZkX3NldF90b19mZF9zZXQoZmRzZXQsICZsZmRzZXQpIDwgMCkgewogICAgICBzbm1wX2xvZyhMT0dfRVJSLAoJICAgICAiVXNlIHNubXBfc2Vzc19zZWxlY3RfaW5mbzIoKSBmb3IgcHJvY2Vzc2luZyIKCSAgICAgIiBsYXJnZSBmaWxlIGRlc2NyaXB0b3JzXG4iKTsKICB9CiAgbmV0c25tcF9sYXJnZV9mZF9zZXRfY2xlYW51cCgmbGZkc2V0KTsKICByZXR1cm4gcmM7Cn0KCi8qKgogKiBAc2VlIFNlZSBhbHNvIHNubXBfc2Vzc19zZWxlY3RfaW5mbzJfZmxhZ3MoKS4KICovCmludApzbm1wX3Nlc3Nfc2VsZWN0X2luZm8yKHZvaWQgKnNlc3NwLCBpbnQgKm51bWZkcywgbmV0c25tcF9sYXJnZV9mZF9zZXQgKmZkc2V0LAoJCSAgICAgICBzdHJ1Y3QgdGltZXZhbCAqdGltZW91dCwgaW50ICpibG9jaykKewogICAgcmV0dXJuIHNubXBfc2Vzc19zZWxlY3RfaW5mbzJfZmxhZ3Moc2Vzc3AsIG51bWZkcywgZmRzZXQsIHRpbWVvdXQsIGJsb2NrLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTkVUU05NUF9TRUxFQ1RfTk9GTEFHUyk7Cn0KCi8qKgogKiBDb21wdXRlL3VwZGF0ZSB0aGUgYXJndW1lbnRzIHRvIGJlIHBhc3NlZCB0byBzZWxlY3QoKS4KICoKICogQHBhcmFtW2luXSAgICAgc2Vzc3AgICBXaGljaCBzZXNzaW9ucyB0byBwcm9jZXNzOiBlaXRoZXIgYSBwb2ludGVyIHRvIGEKICogICBzcGVjaWZpYyBzZXNzaW9uIG9yIE5VTEwgd2hpY2ggbWVhbnMgdG8gcHJvY2VzcyBhbGwgc2Vzc2lvbnMuCiAqIEBwYXJhbVtpbixvdXRdIG51bWZkcyAgT24gUE9TSVggc3lzdGVtcyBvbmUgbW9yZSB0aGFuIHRoZSB0aGUgbGFyZ2VzdCBmaWxlCiAqICAgZGVzY3JpcHRvciB0aGF0IGlzIHByZXNlbnQgaW4gKmZkc2V0LiBPbiBzeXN0ZW1zIHRoYXQgdXNlIFdpbnNvY2sgKE1pbkdXCiAqICAgYW5kIE1TVkMpLCBkbyBub3QgdXNlIHRoZSB2YWx1ZSB3cml0dGVuIGludG8gKm51bWZkcy4KICogQHBhcmFtW2luLG91dF0gZmRzZXQgICBBIGxhcmdlIGZpbGUgZGVzY3JpcHRvciBzZXQgdG8gd2hpY2ggYWxsIGZpbGUKICogICBkZXNjcmlwdG9ycyB3aWxsIGJlIGFkZGVkIHRoYXQgYXJlIGFzc29jaWF0ZWQgd2l0aCBvbmUgb2YgdGhlIGV4YW1pbmVkCiAqICAgc2Vzc2lvbnMuCiAqIEBwYXJhbVtpbixvdXRdIHRpbWVvdXQgT24gaW5wdXQsIGlmICpibG9jayA9IDEsIHRoZSBtYXhpbXVtIHRpbWUgdGhlIGNhbGxlcgogKiAgIHdpbGwgYmxvY2sgd2hpbGUgd2FpdGluZyBmb3IgTmV0LVNOTVAgYWN0aXZpdHkuIE9uIG91dHB1dCwgaWYgdGhpcyBmdW5jdGlvbgogKiAgIGhhcyBzZXQgKmJsb2NrIHRvIDAsIHRoZSBtYXhpbXVtIHRpbWUgdGhlIGNhbGxlciBpcyBhbGxvd2VkIHRvIHdhaXQgYmVmb3JlCiAqICAgaW52b2tpbmcgdGhlIE5ldC1TTk1QIHByb2Nlc3NpbmcgZnVuY3Rpb25zIChzbm1wX3JlYWQoKSwgc25tcF90aW1lb3V0KCkKICogICBhbmQgcnVuX2FsYXJtcygpKS4gSWYgdGhpcyBmdW5jdGlvbiBoYXMgc2V0ICpibG9jayB0byAxLCAqdGltZW91dCB3b24ndAogKiAgIGhhdmUgYmVlbiBtb2RpZmllZCBhbmQgbm8gYWxhcm1zIGFyZSBhY3RpdmUuCiAqIEBwYXJhbVtpbixvdXRdIGJsb2NrICAgT24gaW5wdXQsIHdoZXRoZXIgdGhlIGNhbGxlciBwcmVmZXJzIHRvIGJsb2NrIGZvcmV2ZXIKICogICB3aGVuIG5vIGFsYXJtcyBhcmUgYWN0aXZlLiBPbiBvdXRwdXQsIDAgbWVhbnMgdGhhdCBubyBhbGFybXMgYXJlIGFjdGl2ZQogKiAgIG5vciB0aGF0IHRoZXJlIGlzIGEgdGltZW91dCBwZW5kaW5nIGZvciBhbnkgb2YgdGhlIHByb2Nlc3NlZCBzZXNzaW9ucy4KICogQHBhcmFtW2luXSAgICAgZmxhZ3MgICBFaXRoZXIgMCBvciBORVRTTk1QX1NFTEVDVF9OT0FMQVJNUy4KICoKICogQHJldHVybiBOdW1iZXIgb2Ygc2Vzc2lvbnMgcHJvY2Vzc2VkIGJ5IHRoaXMgZnVuY3Rpb24uCiAqCiAqIEBzZWUgU2VlIGFsc28gYWdlbnRfY2hlY2tfYW5kX3Byb2Nlc3MoKSBmb3IgYW4gZXhhbXBsZSBvZiBob3cgdG8gdXNlIHRoaXMKICogICBmdW5jdGlvbi4KICovCmludApzbm1wX3Nlc3Nfc2VsZWN0X2luZm8yX2ZsYWdzKHZvaWQgKnNlc3NwLCBpbnQgKm51bWZkcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX2xhcmdlX2ZkX3NldCAqIGZkc2V0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0cnVjdCB0aW1ldmFsICp0aW1lb3V0LCBpbnQgKmJsb2NrLCBpbnQgZmxhZ3MpCnsKICAgIHN0cnVjdCBzZXNzaW9uX2xpc3QgKnNscCwgKm5leHQgPSBOVUxMOwogICAgbmV0c25tcF9yZXF1ZXN0X2xpc3QgKnJwOwogICAgc3RydWN0IHRpbWV2YWwgIG5vdywgZWFybGllc3QsIGFsYXJtX3RtOwogICAgaW50ICAgICAgICAgICAgIGFjdGl2ZSA9IDAsIHJlcXVlc3RzID0gMDsKICAgIGludCAgICAgICAgICAgICBuZXh0X2FsYXJtID0gMDsKCiAgICB0aW1lcmNsZWFyKCZlYXJsaWVzdCk7CgogICAgLyoKICAgICAqIEZvciBlYWNoIHNlc3Npb24gZXhhbWluZWQsIGFkZCBpdHMgc29ja2V0IHRvIHRoZSBmZHNldCwKICAgICAqIGFuZCBpZiBpdCBpcyB0aGUgZWFybGllc3QgdGltZW91dCB0byBleHBpcmUsIG1hcmsgaXQgYXMgbG93ZXN0LgogICAgICogSWYgYSBzaW5nbGUgc2Vzc2lvbiBpcyBzcGVjaWZpZWQsIGRvIGp1c3QgZm9yIHRoYXQgc2Vzc2lvbi4KICAgICAqLwoKICAgIERFQlVHTVNHVEwoKCJzZXNzX3NlbGVjdCIsICJmb3IgJXMgc2Vzc2lvbiVzOiAiLAogICAgICAgICAgICAgICAgc2Vzc3AgPyAic2luZ2xlIiA6ICJhbGwiLCBzZXNzcCA/ICIiIDogInMiKSk7CgogICAgZm9yIChzbHAgPSBzZXNzcCA/IHNlc3NwIDogU2Vzc2lvbnM7IHNscDsgc2xwID0gbmV4dCkgewogICAgICAgIG5leHQgPSBzbHAtPm5leHQ7CgogICAgICAgIGlmIChzbHAtPnRyYW5zcG9ydCA9PSBOVUxMKSB7CiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIENsb3NlIGluIHByb2dyZXNzIC0tIHNraXAgdGhpcyBvbmUuICAKICAgICAgICAgICAgICovCiAgICAgICAgICAgIERFQlVHTVNHKCgic2Vzc19zZWxlY3QiLCAic2tpcCAiKSk7CiAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgIH0KCiAgICAgICAgaWYgKHNscC0+dHJhbnNwb3J0LT5zb2NrID09IC0xKSB7CiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIFRoaXMgc2Vzc2lvbiB3YXMgbWFya2VkIGZvciBkZWxldGlvbi4gIAogICAgICAgICAgICAgKi8KICAgICAgICAgICAgREVCVUdNU0coKCJzZXNzX3NlbGVjdCIsICJkZWxldGVcbiIpKTsKICAgICAgICAgICAgaWYgKHNlc3NwID09IE5VTEwpIHsKICAgICAgICAgICAgICAgIHNubXBfY2xvc2Uoc2xwLT5zZXNzaW9uKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIHNubXBfc2Vzc19jbG9zZShzbHApOwogICAgICAgICAgICB9CiAgICAgICAgICAgIERFQlVHTVNHVEwoKCJzZXNzX3NlbGVjdCIsICJmb3IgJXMgc2Vzc2lvbiVzOiAiLAogICAgICAgICAgICAgICAgICAgICAgICBzZXNzcCA/ICJzaW5nbGUiIDogImFsbCIsIHNlc3NwID8gIiIgOiAicyIpKTsKICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgfQoKICAgICAgICBERUJVR01TRygoInNlc3Nfc2VsZWN0IiwgIiVkICIsIHNscC0+dHJhbnNwb3J0LT5zb2NrKSk7CiAgICAgICAgaWYgKChzbHAtPnRyYW5zcG9ydC0+c29jayArIDEpID4gKm51bWZkcykgewogICAgICAgICAgICAqbnVtZmRzID0gKHNscC0+dHJhbnNwb3J0LT5zb2NrICsgMSk7CiAgICAgICAgfQoKICAgICAgICBORVRTTk1QX0xBUkdFX0ZEX1NFVChzbHAtPnRyYW5zcG9ydC0+c29jaywgZmRzZXQpOwogICAgICAgIGlmIChzbHAtPmludGVybmFsICE9IE5VTEwgJiYgc2xwLT5pbnRlcm5hbC0+cmVxdWVzdHMpIHsKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogRm91bmQgYW5vdGhlciBzZXNzaW9uIHdpdGggb3V0c3RhbmRpbmcgcmVxdWVzdHMuICAKICAgICAgICAgICAgICovCiAgICAgICAgICAgIHJlcXVlc3RzKys7CiAgICAgICAgICAgIGZvciAocnAgPSBzbHAtPmludGVybmFsLT5yZXF1ZXN0czsgcnA7IHJwID0gcnAtPm5leHRfcmVxdWVzdCkgewogICAgICAgICAgICAgICAgaWYgKCghdGltZXJpc3NldCgmZWFybGllc3QpCiAgICAgICAgICAgICAgICAgICAgIHx8ICh0aW1lcmNtcCgmcnAtPmV4cGlyZSwgJmVhcmxpZXN0LCA8KSkpKSB7CiAgICAgICAgICAgICAgICAgICAgZWFybGllc3QgPSBycC0+ZXhwaXJlOwogICAgICAgICAgICAgICAgICAgIERFQlVHTVNHKCgidmVyYm9zZTpzZXNzX3NlbGVjdCIsIih0byBpbiAlZC4lMDZkIHNlYykgIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChpbnQpZWFybGllc3QudHZfc2VjLCAoaW50KWVhcmxpZXN0LnR2X3VzZWMpKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KCiAgICAgICAgYWN0aXZlKys7CiAgICAgICAgaWYgKHNlc3NwKSB7CiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIFNpbmdsZSBzZXNzaW9uIHByb2Nlc3NpbmcuICAKICAgICAgICAgICAgICovCiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgIH0KICAgIERFQlVHTVNHKCgic2Vzc19zZWxlY3QiLCAiXG4iKSk7CgogICAgZ2V0dGltZW9mZGF5KCZub3csIE5VTEwpOwoKICAgIGlmIChuZXRzbm1wX2RzX2dldF9ib29sZWFuKE5FVFNOTVBfRFNfTElCUkFSWV9JRCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5FVFNOTVBfRFNfTElCX0FMQVJNX0RPTlRfVVNFX1NJRykgJiYKICAgICAgICAhKGZsYWdzICYgTkVUU05NUF9TRUxFQ1RfTk9BTEFSTVMpKSB7CiAgICAgICAgbmV4dF9hbGFybSA9IG5ldHNubXBfZ2V0X25leHRfYWxhcm1fdGltZSgmYWxhcm1fdG0sICZub3cpOwogICAgICAgIGlmIChuZXh0X2FsYXJtKQogICAgICAgICAgICBERUJVR01TR1QoKCJzZXNzX3NlbGVjdCIsIm5leHQgYWxhcm0gYXQgJWxkLiUwNmxkIHNlY1xuIiwKICAgICAgICAgICAgICAgICAgICAgICAobG9uZylhbGFybV90bS50dl9zZWMsIChsb25nKWFsYXJtX3RtLnR2X3VzZWMpKTsKICAgIH0KICAgIGlmIChuZXh0X2FsYXJtID09IDAgJiYgcmVxdWVzdHMgPT0gMCkgewogICAgICAgIC8qCiAgICAgICAgICogSWYgbm9uZSBhcmUgYWN0aXZlLCBza2lwIGFyaXRobWV0aWMuICAKICAgICAgICAgKi8KICAgICAgICBERUJVR01TR1QoKCJzZXNzX3NlbGVjdCIsImJsb2NraW5nOm5vIHNlc3Npb24gcmVxdWVzdHMgb3IgYWxhcm1zLlxuIikpOwogICAgICAgICpibG9jayA9IDE7IC8qIGNhbiBibG9jayAtIHRpbWVvdXQgdmFsdWUgaXMgdW5kZWZpbmVkIGlmIG5vIHJlcXVlc3RzICovCiAgICAgICAgcmV0dXJuIGFjdGl2ZTsKICAgIH0KCiAgICBpZiAobmV4dF9hbGFybSAmJgogICAgICAgICghdGltZXJpc3NldCgmZWFybGllc3QpIHx8IHRpbWVyY21wKCZhbGFybV90bSwgJmVhcmxpZXN0LCA8KSkpCiAgICAgICAgZWFybGllc3QgPSBhbGFybV90bTsKCiAgICBORVRTTk1QX1RJTUVSU1VCKCZlYXJsaWVzdCwgJm5vdywgJmVhcmxpZXN0KTsKICAgIGlmIChlYXJsaWVzdC50dl9zZWMgPCAwKSB7CiAgICAgICAgdGltZV90IG92ZXJkdWVfbXMgPSAtKGVhcmxpZXN0LnR2X3NlYyAqIDEwMDAgKyBlYXJsaWVzdC50dl91c2VjIC8gMTAwMCk7CiAgICAgICAgaWYgKG92ZXJkdWVfbXMgPj0gMTApCiAgICAgICAgICAgIERFQlVHTVNHVCgoInZlcmJvc2U6c2Vzc19zZWxlY3QiLCJ0aW1lciBvdmVyZHVlIGJ5ICVsZCBtc1xuIiwKICAgICAgICAgICAgICAgICAgICAgICBvdmVyZHVlX21zKSk7CiAgICAgICAgdGltZXJjbGVhcigmZWFybGllc3QpOwogICAgfSBlbHNlIHsKICAgICAgICBERUJVR01TR1QoKCJ2ZXJib3NlOnNlc3Nfc2VsZWN0IiwidGltZXIgZHVlIGluICVkLiUwNmQgc2VjXG4iLAogICAgICAgICAgICAgICAgICAgKGludCllYXJsaWVzdC50dl9zZWMsIChpbnQpZWFybGllc3QudHZfdXNlYykpOwogICAgfQoKICAgIC8qCiAgICAgKiBpZiBpdCB3YXMgYmxvY2tpbmcgYmVmb3JlIG9yIG91ciBkZWx0YSB0aW1lIGlzIGxlc3MsIHJlc2V0IHRpbWVvdXQgCiAgICAgKi8KICAgIGlmICgoKmJsb2NrIHx8ICh0aW1lcmNtcCgmZWFybGllc3QsIHRpbWVvdXQsIDwpKSkpIHsKICAgICAgICBERUJVR01TR1QoKCJ2ZXJib3NlOnNlc3Nfc2VsZWN0IiwKICAgICAgICAgICAgICAgICAgICJzZXR0aW5nIHRpbWVyIHRvICVkLiUwNmQgc2VjLCBjbGVhciBibG9jayAod2FzICVkKVxuIiwKICAgICAgICAgICAgICAgICAgIChpbnQpZWFybGllc3QudHZfc2VjLCAoaW50KWVhcmxpZXN0LnR2X3VzZWMsICpibG9jaykpOwogICAgICAgICp0aW1lb3V0ID0gZWFybGllc3Q7CiAgICAgICAgKmJsb2NrID0gMDsKICAgIH0KICAgIHJldHVybiBhY3RpdmU7Cn0KCi8qCiAqIHNubXBfdGltZW91dCBzaG91bGQgYmUgY2FsbGVkIHdoZW5ldmVyIHRoZSB0aW1lb3V0IGZyb20gc25tcF9zZWxlY3RfaW5mbwogKiBleHBpcmVzLCBidXQgaXQgaXMgaWRlbXBvdGVudCwgc28gc25tcF90aW1lb3V0IGNhbiBiZSBwb2xsZWQgKHByb2JhYmx5IGEKICogY3B1IGV4cGVuc2l2ZSBwcm9wb3NpdGlvbikuICBzbm1wX3RpbWVvdXQgY2hlY2tzIHRvIHNlZSBpZiBhbnkgb2YgdGhlCiAqIHNlc3Npb25zIGhhdmUgYW4gb3V0c3RhbmRpbmcgcmVxdWVzdCB0aGF0IGhhcyB0aW1lZCBvdXQuICBJZiBpdCBmaW5kcyBvbmUKICogKG9yIG1vcmUpLCBhbmQgdGhhdCBwZHUgaGFzIG1vcmUgcmV0cmllcyBhdmFpbGFibGUsIGEgbmV3IHBhY2tldCBpcyBmb3JtZWQKICogZnJvbSB0aGUgcGR1IGFuZCBpcyByZXNlbnQuICBJZiB0aGVyZSBhcmUgbm8gbW9yZSByZXRyaWVzIGF2YWlsYWJsZSwgdGhlCiAqICBjYWxsYmFjayBmb3IgdGhlIHNlc3Npb24gaXMgdXNlZCB0byBhbGVydCB0aGUgdXNlciBvZiB0aGUgdGltZW91dC4KICovCnZvaWQKc25tcF90aW1lb3V0KHZvaWQpCnsKICAgIHN0cnVjdCBzZXNzaW9uX2xpc3QgKnNscDsKICAgIHNubXBfcmVzX2xvY2soTVRfTElCUkFSWV9JRCwgTVRfTElCX1NFU1NJT04pOwogICAgZm9yIChzbHAgPSBTZXNzaW9uczsgc2xwOyBzbHAgPSBzbHAtPm5leHQpIHsKICAgICAgICBzbm1wX3Nlc3NfdGltZW91dCgodm9pZCAqKSBzbHApOwogICAgfQogICAgc25tcF9yZXNfdW5sb2NrKE1UX0xJQlJBUllfSUQsIE1UX0xJQl9TRVNTSU9OKTsKfQoKc3RhdGljIGludApzbm1wX3Jlc2VuZF9yZXF1ZXN0KHN0cnVjdCBzZXNzaW9uX2xpc3QgKnNscCwgbmV0c25tcF9yZXF1ZXN0X2xpc3QgKnJwLAogICAgICAgICAgICAgICAgICAgIGludCBpbmNyX3JldHJpZXMpCnsKICAgIHN0cnVjdCBzbm1wX2ludGVybmFsX3Nlc3Npb24gKmlzcDsKICAgIG5ldHNubXBfc2Vzc2lvbiAqc3A7CiAgICBuZXRzbm1wX3RyYW5zcG9ydCAqdHJhbnNwb3J0OwogICAgdV9jaGFyICAgICAgICAgKnBrdGJ1ZiA9IE5VTEwsICpwYWNrZXQgPSBOVUxMOwogICAgc2l6ZV90ICAgICAgICAgIHBrdGJ1Zl9sZW4gPSAwLCBvZmZzZXQgPSAwLCBsZW5ndGggPSAwOwogICAgc3RydWN0IHRpbWV2YWwgIHR2LCBub3c7CiAgICBpbnQgICAgICAgICAgICAgcmVzdWx0ID0gMDsKCiAgICBzcCA9IHNscC0+c2Vzc2lvbjsKICAgIGlzcCA9IHNscC0+aW50ZXJuYWw7CiAgICB0cmFuc3BvcnQgPSBzbHAtPnRyYW5zcG9ydDsKICAgIGlmICghc3AgfHwgIWlzcCB8fCAhdHJhbnNwb3J0KSB7CiAgICAgICAgREVCVUdNU0dUTCgoInNlc3NfcmVhZCIsICJyZXNlbmQgZmFpbDogY2xvc2luZy4uLlxuIikpOwogICAgICAgIHJldHVybiAwOwogICAgfQoKICAgIGlmICgocGt0YnVmID0gKHVfY2hhciAqKW1hbGxvYygyMDQ4KSkgPT0gTlVMTCkgewogICAgICAgIERFQlVHTVNHVEwoKCJzZXNzX3Jlc2VuZCIsCiAgICAgICAgICAgICAgICAgICAgImNvdWxkbid0IG1hbGxvYyBpbml0aWFsIHBhY2tldCBidWZmZXJcbiIpKTsKICAgICAgICByZXR1cm4gMDsKICAgIH0gZWxzZSB7CiAgICAgICAgcGt0YnVmX2xlbiA9IDIwNDg7CiAgICB9CgogICAgaWYgKGluY3JfcmV0cmllcykgewogICAgICAgIHJwLT5yZXRyaWVzKys7CiAgICB9CgogICAgLyoKICAgICAqIEFsd2F5cyBpbmNyZW1lbnQgbXNnSWQgZm9yIHJlc2VudCBtZXNzYWdlcy4gIAogICAgICovCiAgICBycC0+cGR1LT5tc2dpZCA9IHJwLT5tZXNzYWdlX2lkID0gc25tcF9nZXRfbmV4dF9tc2dpZCgpOwoKICAgIGlmIChpc3AtPmhvb2tfcmVhbGxvY19idWlsZCkgewogICAgICAgIHJlc3VsdCA9IGlzcC0+aG9va19yZWFsbG9jX2J1aWxkKHNwLCBycC0+cGR1LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZwa3RidWYsICZwa3RidWZfbGVuLCAmb2Zmc2V0KTsKCiAgICAgICAgcGFja2V0ID0gcGt0YnVmOwogICAgICAgIGxlbmd0aCA9IG9mZnNldDsKICAgIH0gZWxzZSBpZiAoaXNwLT5ob29rX2J1aWxkKSB7CiAgICAgICAgcGFja2V0ID0gcGt0YnVmOwogICAgICAgIGxlbmd0aCA9IHBrdGJ1Zl9sZW47CiAgICAgICAgcmVzdWx0ID0gaXNwLT5ob29rX2J1aWxkKHNwLCBycC0+cGR1LCBwa3RidWYsICZsZW5ndGgpOwogICAgfSBlbHNlIHsKI2lmZGVmIE5FVFNOTVBfVVNFX1JFVkVSU0VfQVNORU5DT0RJTkcKICAgICAgICBpZiAobmV0c25tcF9kc19nZXRfYm9vbGVhbihORVRTTk1QX0RTX0xJQlJBUllfSUQsIE5FVFNOTVBfRFNfTElCX1JFVkVSU0VfRU5DT0RFKSkgewogICAgICAgICAgICByZXN1bHQgPQogICAgICAgICAgICAgICAgc25tcF9idWlsZCgmcGt0YnVmLCAmcGt0YnVmX2xlbiwgJm9mZnNldCwgc3AsIHJwLT5wZHUpOwogICAgICAgICAgICBwYWNrZXQgPSBwa3RidWYgKyBwa3RidWZfbGVuIC0gb2Zmc2V0OwogICAgICAgICAgICBsZW5ndGggPSBvZmZzZXQ7CiAgICAgICAgfSBlbHNlIHsKI2VuZGlmCiAgICAgICAgICAgIHBhY2tldCA9IHBrdGJ1ZjsKICAgICAgICAgICAgbGVuZ3RoID0gcGt0YnVmX2xlbjsKICAgICAgICAgICAgcmVzdWx0ID0gc25tcF9idWlsZCgmcGt0YnVmLCAmbGVuZ3RoLCAmb2Zmc2V0LCBzcCwgcnAtPnBkdSk7CiNpZmRlZiBORVRTTk1QX1VTRV9SRVZFUlNFX0FTTkVOQ09ESU5HCiAgICAgICAgfQojZW5kaWYKICAgIH0KCiAgICBpZiAocmVzdWx0IDwgMCkgewogICAgICAgIC8qCiAgICAgICAgICogVGhpcyBzaG91bGQgbmV2ZXIgaGFwcGVuLiAgCiAgICAgICAgICovCiAgICAgICAgREVCVUdNU0dUTCgoInNlc3NfcmVzZW5kIiwgImVuY29kaW5nIGZhaWx1cmVcbiIpKTsKICAgICAgICBpZiAocGt0YnVmICE9IE5VTEwpIHsKICAgICAgICAgICAgU05NUF9GUkVFKHBrdGJ1Zik7CiAgICAgICAgfQogICAgICAgIHJldHVybiAtMTsKICAgIH0KCiAgICBERUJVR01TR1RMKCgic2Vzc19wcm9jZXNzX3BhY2tldCIsICJyZXNlbmRpbmcgbWVzc2FnZSBpZCMlbGQgcmVxaWQjJWxkICIKICAgICAgICAgICAgICAgICJycF9yZXFpZCMlbGQgcnBfbXNnaWQjJWxkIGxlbiAlIiBORVRTTk1QX1BSSXogInVcbiIsCiAgICAgICAgICAgICAgICBycC0+cGR1LT5tc2dpZCwgcnAtPnBkdS0+cmVxaWQsIHJwLT5yZXF1ZXN0X2lkLCBycC0+bWVzc2FnZV9pZCwgbGVuZ3RoKSk7CiAgICByZXN1bHQgPSBuZXRzbm1wX3RyYW5zcG9ydF9zZW5kKHRyYW5zcG9ydCwgcGFja2V0LCBsZW5ndGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICYocnAtPnBkdS0+dHJhbnNwb3J0X2RhdGEpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmKHJwLT5wZHUtPnRyYW5zcG9ydF9kYXRhX2xlbmd0aCkpOwoKICAgIC8qCiAgICAgKiBXZSBhcmUgZmluaXNoZWQgd2l0aCB0aGUgbG9jYWwgcGFja2V0IGJ1ZmZlciwgaWYgd2UgYWxsb2NhdGVkIG9uZSAoZHVlCiAgICAgKiB0byB0aGVyZSBiZWluZyBubyBzYXZlZCBwYWNrZXQpLiAgCiAgICAgKi8KCiAgICBpZiAocGt0YnVmICE9IE5VTEwpIHsKICAgICAgICBTTk1QX0ZSRUUocGt0YnVmKTsKICAgICAgICBwa3RidWYgPSBwYWNrZXQgPSBOVUxMOwogICAgfQoKICAgIGlmIChyZXN1bHQgPCAwKSB7CiAgICAgICAgc3AtPnNfc25tcF9lcnJubyA9IFNOTVBFUlJfQkFEX1NFTkRUTzsKICAgICAgICBzcC0+c19lcnJubyA9IGVycm5vOwogICAgICAgIHNubXBfc2V0X2RldGFpbChzdHJlcnJvcihlcnJubykpOwogICAgICAgIHJldHVybiAtMTsKICAgIH0gZWxzZSB7CiAgICAgICAgZ2V0dGltZW9mZGF5KCZub3csIChzdHJ1Y3QgdGltZXpvbmUgKikgMCk7CiAgICAgICAgdHYgPSBub3c7CiAgICAgICAgcnAtPnRpbWUgPSB0djsKICAgICAgICB0di50dl91c2VjICs9IHJwLT50aW1lb3V0OwogICAgICAgIHR2LnR2X3NlYyArPSB0di50dl91c2VjIC8gMTAwMDAwMEw7CiAgICAgICAgdHYudHZfdXNlYyAlPSAxMDAwMDAwTDsKICAgICAgICBycC0+ZXhwaXJlID0gdHY7CiAgICB9CiAgICByZXR1cm4gMDsKfQoKCgp2b2lkCnNubXBfc2Vzc190aW1lb3V0KHZvaWQgKnNlc3NwKQp7CiAgICBzdHJ1Y3Qgc2Vzc2lvbl9saXN0ICpzbHAgPSAoc3RydWN0IHNlc3Npb25fbGlzdCAqKSBzZXNzcDsKICAgIG5ldHNubXBfc2Vzc2lvbiAqc3A7CiAgICBzdHJ1Y3Qgc25tcF9pbnRlcm5hbF9zZXNzaW9uICppc3A7CiAgICBuZXRzbm1wX3JlcXVlc3RfbGlzdCAqcnAsICpvcnAgPSBOVUxMLCAqZnJlZW1lID0gTlVMTDsKICAgIHN0cnVjdCB0aW1ldmFsICBub3c7CiAgICBzbm1wX2NhbGxiYWNrICAgY2FsbGJhY2s7CiAgICB2b2lkICAgICAgICAgICAqbWFnaWM7CiAgICBzdHJ1Y3Qgc25tcF9zZWNtb2RfZGVmICpzcHRyOwoKICAgIHNwID0gc2xwLT5zZXNzaW9uOwogICAgaXNwID0gc2xwLT5pbnRlcm5hbDsKICAgIGlmICghc3AgfHwgIWlzcCkgewogICAgICAgIERFQlVHTVNHVEwoKCJzZXNzX3JlYWQiLCAidGltZW91dCBmYWlsOiBjbG9zaW5nLi4uXG4iKSk7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgIGdldHRpbWVvZmRheSgmbm93LCAoc3RydWN0IHRpbWV6b25lICopIDApOwoKICAgIC8qCiAgICAgKiBGb3IgZWFjaCByZXF1ZXN0IG91dHN0YW5kaW5nLCBjaGVjayB0byBzZWUgaWYgaXQgaGFzIGV4cGlyZWQuCiAgICAgKi8KICAgIGZvciAocnAgPSBpc3AtPnJlcXVlc3RzOyBycDsgcnAgPSBycC0+bmV4dF9yZXF1ZXN0KSB7CiAgICAgICAgaWYgKGZyZWVtZSAhPSBOVUxMKSB7CiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIGZyZWVzIHJwJ3MgYWZ0ZXIgdGhlIGZvciBsb29wIGdvZXMgb24gdG8gdGhlIG5leHRfcmVxdWVzdCAKICAgICAgICAgICAgICovCiAgICAgICAgICAgIGZyZWUoKGNoYXIgKikgZnJlZW1lKTsKICAgICAgICAgICAgZnJlZW1lID0gTlVMTDsKICAgICAgICB9CgogICAgICAgIGlmICgodGltZXJjbXAoJnJwLT5leHBpcmUsICZub3csIDwpKSkgewogICAgICAgICAgICBpZiAoKHNwdHIgPSBmaW5kX3NlY19tb2QocnAtPnBkdS0+c2VjdXJpdHlNb2RlbCkpICE9IE5VTEwgJiYKICAgICAgICAgICAgICAgIHNwdHItPnBkdV90aW1lb3V0ICE9IE5VTEwpIHsKICAgICAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAgICAgKiBjYWxsIHNlY3VyaXR5IG1vZGVsIGlmIGl0IG5lZWRzIHRvIGtub3cgYWJvdXQgdGhpcyAKICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgKCpzcHRyLT5wZHVfdGltZW91dCkgKHJwLT5wZHUpOwogICAgICAgICAgICB9CgogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiB0aGlzIHRpbWVyIGhhcyBleHBpcmVkIAogICAgICAgICAgICAgKi8KICAgICAgICAgICAgaWYgKHJwLT5yZXRyaWVzID49IHNwLT5yZXRyaWVzKSB7CiAgICAgICAgICAgICAgICBpZiAocnAtPmNhbGxiYWNrKSB7CiAgICAgICAgICAgICAgICAgICAgY2FsbGJhY2sgPSBycC0+Y2FsbGJhY2s7CiAgICAgICAgICAgICAgICAgICAgbWFnaWMgPSBycC0+Y2JfZGF0YTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgY2FsbGJhY2sgPSBzcC0+Y2FsbGJhY2s7CiAgICAgICAgICAgICAgICAgICAgbWFnaWMgPSBzcC0+Y2FsbGJhY2tfbWFnaWM7CiAgICAgICAgICAgICAgICB9CgogICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAqIE5vIG1vcmUgY2hhbmNlcywgZGVsZXRlIHRoaXMgZW50cnkgCiAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgIGlmIChjYWxsYmFjaykgewogICAgICAgICAgICAgICAgICAgIGNhbGxiYWNrKE5FVFNOTVBfQ0FMTEJBQ0tfT1BfVElNRURfT1VULCBzcCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICBycC0+cGR1LT5yZXFpZCwgcnAtPnBkdSwgbWFnaWMpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKGlzcC0+cmVxdWVzdHMgPT0gcnApIHsKICAgICAgICAgICAgICAgICAgICBpc3AtPnJlcXVlc3RzID0gcnAtPm5leHRfcmVxdWVzdDsKICAgICAgICAgICAgICAgICAgICBpZiAoaXNwLT5yZXF1ZXN0c0VuZCA9PSBycCkgewogICAgICAgICAgICAgICAgICAgICAgICBpc3AtPnJlcXVlc3RzRW5kID0gTlVMTDsKICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIG9ycC0+bmV4dF9yZXF1ZXN0ID0gcnAtPm5leHRfcmVxdWVzdDsKICAgICAgICAgICAgICAgICAgICBpZiAoaXNwLT5yZXF1ZXN0c0VuZCA9PSBycCkgewogICAgICAgICAgICAgICAgICAgICAgICBpc3AtPnJlcXVlc3RzRW5kID0gb3JwOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIHNubXBfZnJlZV9wZHUocnAtPnBkdSk7IC8qIEZJWCAgcnAgaXMgYWxyZWFkeSBmcmVlJ2QhICovCiAgICAgICAgICAgICAgICBmcmVlbWUgPSBycDsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOyAgICAgICAvKiBkb24ndCB1cGRhdGUgb3JwIGJlbG93ICovCiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBpZiAoc25tcF9yZXNlbmRfcmVxdWVzdChzbHAsIHJwLCBUUlVFKSkgewogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIG9ycCA9IHJwOwogICAgfQoKICAgIGlmIChmcmVlbWUgIT0gTlVMTCkgewogICAgICAgIGZyZWUoKGNoYXIgKikgZnJlZW1lKTsKICAgICAgICBmcmVlbWUgPSBOVUxMOwogICAgfQp9CgovKgogKiBsZXhpY29ncmFwaGljYWwgY29tcGFyZSB0d28gb2JqZWN0IGlkZW50aWZpZXJzLgogKiAqIFJldHVybnMgLTEgaWYgbmFtZTEgPCBuYW1lMiwKICogKiAgICAgICAgICAwIGlmIG5hbWUxID0gbmFtZTIsCiAqICogICAgICAgICAgMSBpZiBuYW1lMSA+IG5hbWUyCiAqICoKICogKiBDYXV0aW9uOiB0aGlzIG1ldGhvZCBpcyBjYWxsZWQgb2Z0ZW4gYnkKICogKiAgICAgICAgICBjb21tYW5kIHJlc3BvbmRlciBhcHBsaWNhdGlvbnMgKGllLCBhZ2VudCkuCiAqLwppbnQKc25tcF9vaWRfbmNvbXBhcmUoY29uc3Qgb2lkICogaW5fbmFtZTEsCiAgICAgICAgICAgICAgICAgIHNpemVfdCBsZW4xLAogICAgICAgICAgICAgICAgICBjb25zdCBvaWQgKiBpbl9uYW1lMiwgc2l6ZV90IGxlbjIsIHNpemVfdCBtYXhfbGVuKQp7CiAgICByZWdpc3RlciBpbnQgICAgbGVuOwogICAgcmVnaXN0ZXIgY29uc3Qgb2lkICpuYW1lMSA9IGluX25hbWUxOwogICAgcmVnaXN0ZXIgY29uc3Qgb2lkICpuYW1lMiA9IGluX25hbWUyOwogICAgc2l6ZV90ICAgICAgICAgIG1pbl9sZW47CgogICAgLyoKICAgICAqIGxlbiA9IG1pbmltdW0gb2YgbGVuMSBhbmQgbGVuMiAKICAgICAqLwogICAgaWYgKGxlbjEgPCBsZW4yKQogICAgICAgIG1pbl9sZW4gPSBsZW4xOwogICAgZWxzZQogICAgICAgIG1pbl9sZW4gPSBsZW4yOwoKICAgIGlmIChtaW5fbGVuID4gbWF4X2xlbikKICAgICAgICBtaW5fbGVuID0gbWF4X2xlbjsKCiAgICBsZW4gPSBtaW5fbGVuOwoKICAgIC8qCiAgICAgKiBmaW5kIGZpcnN0IG5vbi1tYXRjaGluZyBPSUQgCiAgICAgKi8KICAgIHdoaWxlIChsZW4tLSA+IDApIHsKICAgICAgICAvKgogICAgICAgICAqIHRoZXNlIG11c3QgYmUgZG9uZSBpbiBzZXBlcmF0ZSBjb21wYXJpc29ucywgc2luY2UKICAgICAgICAgKiBzdWJ0cmFjdGluZyB0aGVtIGFuZCB1c2luZyB0aGF0IHJlc3VsdCBoYXMgcHJvYmxlbXMgd2l0aAogICAgICAgICAqIHN1YmlkcyA+IDJeMzEuIAogICAgICAgICAqLwogICAgICAgIGlmICgqKG5hbWUxKSAhPSAqKG5hbWUyKSkgewogICAgICAgICAgICBpZiAoKihuYW1lMSkgPCAqKG5hbWUyKSkKICAgICAgICAgICAgICAgIHJldHVybiAtMTsKICAgICAgICAgICAgcmV0dXJuIDE7CiAgICAgICAgfQogICAgICAgIG5hbWUxKys7CiAgICAgICAgbmFtZTIrKzsKICAgIH0KCiAgICBpZiAobWluX2xlbiAhPSBtYXhfbGVuKSB7CiAgICAgICAgLyoKICAgICAgICAgKiBib3RoIE9JRHMgZXF1YWwgdXAgdG8gbGVuZ3RoIG9mIHNob3J0ZXIgT0lEIAogICAgICAgICAqLwogICAgICAgIGlmIChsZW4xIDwgbGVuMikKICAgICAgICAgICAgcmV0dXJuIC0xOwogICAgICAgIGlmIChsZW4yIDwgbGVuMSkKICAgICAgICAgICAgcmV0dXJuIDE7CiAgICB9CgogICAgcmV0dXJuIDA7Cn0KCi8qKiBsZXhpY29ncmFwaGljYWwgY29tcGFyZSB0d28gb2JqZWN0IGlkZW50aWZpZXJzLgogKiAKICogQ2F1dGlvbjogdGhpcyBtZXRob2QgaXMgY2FsbGVkIG9mdGVuIGJ5CiAqICAgICAgICAgIGNvbW1hbmQgcmVzcG9uZGVyIGFwcGxpY2F0aW9ucyAoaWUsIGFnZW50KS4KICoKICogQHJldHVybiAtMSBpZiBuYW1lMSA8IG5hbWUyLCAwIGlmIG5hbWUxID0gbmFtZTIsIDEgaWYgbmFtZTEgPiBuYW1lMgogKi8KaW50CnNubXBfb2lkX2NvbXBhcmUoY29uc3Qgb2lkICogaW5fbmFtZTEsCiAgICAgICAgICAgICAgICAgc2l6ZV90IGxlbjEsIGNvbnN0IG9pZCAqIGluX25hbWUyLCBzaXplX3QgbGVuMikKewogICAgcmVnaXN0ZXIgaW50ICAgIGxlbjsKICAgIHJlZ2lzdGVyIGNvbnN0IG9pZCAqbmFtZTEgPSBpbl9uYW1lMTsKICAgIHJlZ2lzdGVyIGNvbnN0IG9pZCAqbmFtZTIgPSBpbl9uYW1lMjsKCiAgICAvKgogICAgICogbGVuID0gbWluaW11bSBvZiBsZW4xIGFuZCBsZW4yIAogICAgICovCiAgICBpZiAobGVuMSA8IGxlbjIpCiAgICAgICAgbGVuID0gbGVuMTsKICAgIGVsc2UKICAgICAgICBsZW4gPSBsZW4yOwogICAgLyoKICAgICAqIGZpbmQgZmlyc3Qgbm9uLW1hdGNoaW5nIE9JRCAKICAgICAqLwogICAgd2hpbGUgKGxlbi0tID4gMCkgewogICAgICAgIC8qCiAgICAgICAgICogdGhlc2UgbXVzdCBiZSBkb25lIGluIHNlcGVyYXRlIGNvbXBhcmlzb25zLCBzaW5jZQogICAgICAgICAqIHN1YnRyYWN0aW5nIHRoZW0gYW5kIHVzaW5nIHRoYXQgcmVzdWx0IGhhcyBwcm9ibGVtcyB3aXRoCiAgICAgICAgICogc3ViaWRzID4gMl4zMS4gCiAgICAgICAgICovCiAgICAgICAgaWYgKCoobmFtZTEpICE9ICoobmFtZTIpKSB7CiAgICAgICAgICAgIGlmICgqKG5hbWUxKSA8ICoobmFtZTIpKQogICAgICAgICAgICAgICAgcmV0dXJuIC0xOwogICAgICAgICAgICByZXR1cm4gMTsKICAgICAgICB9CiAgICAgICAgbmFtZTErKzsKICAgICAgICBuYW1lMisrOwogICAgfQogICAgLyoKICAgICAqIGJvdGggT0lEcyBlcXVhbCB1cCB0byBsZW5ndGggb2Ygc2hvcnRlciBPSUQgCiAgICAgKi8KICAgIGlmIChsZW4xIDwgbGVuMikKICAgICAgICByZXR1cm4gLTE7CiAgICBpZiAobGVuMiA8IGxlbjEpCiAgICAgICAgcmV0dXJuIDE7CiAgICByZXR1cm4gMDsKfQoKLyoqIGxleGljb2dyYXBoaWNhbCBjb21wYXJlIHR3byBvYmplY3QgaWRlbnRpZmllcnMgYW5kIHJldHVybiB0aGUgcG9pbnQgd2hlcmUgdGhleSBkaWZmZXIKICogCiAqIENhdXRpb246IHRoaXMgbWV0aG9kIGlzIGNhbGxlZCBvZnRlbiBieQogKiAgICAgICAgICBjb21tYW5kIHJlc3BvbmRlciBhcHBsaWNhdGlvbnMgKGllLCBhZ2VudCkuCiAqCiAqIEByZXR1cm4gLTEgaWYgbmFtZTEgPCBuYW1lMiwgMCBpZiBuYW1lMSA9IG5hbWUyLCAxIGlmIG5hbWUxID4gbmFtZTIgYW5kIG9mZnB0ID0gbGVuIHdoZXJlIG5hbWUxICE9IG5hbWUyCiAqLwppbnQKbmV0c25tcF9vaWRfY29tcGFyZV9sbChjb25zdCBvaWQgKiBpbl9uYW1lMSwKICAgICAgICAgICAgICAgICAgICAgICBzaXplX3QgbGVuMSwgY29uc3Qgb2lkICogaW5fbmFtZTIsIHNpemVfdCBsZW4yLAogICAgICAgICAgICAgICAgICAgICAgIHNpemVfdCAqb2ZmcHQpCnsKICAgIHJlZ2lzdGVyIGludCAgICBsZW47CiAgICByZWdpc3RlciBjb25zdCBvaWQgKm5hbWUxID0gaW5fbmFtZTE7CiAgICByZWdpc3RlciBjb25zdCBvaWQgKm5hbWUyID0gaW5fbmFtZTI7CiAgICBpbnQgaW5pdGxlbjsKCiAgICAvKgogICAgICogbGVuID0gbWluaW11bSBvZiBsZW4xIGFuZCBsZW4yIAogICAgICovCiAgICBpZiAobGVuMSA8IGxlbjIpCiAgICAgICAgaW5pdGxlbiA9IGxlbiA9IGxlbjE7CiAgICBlbHNlCiAgICAgICAgaW5pdGxlbiA9IGxlbiA9IGxlbjI7CiAgICAvKgogICAgICogZmluZCBmaXJzdCBub24tbWF0Y2hpbmcgT0lEIAogICAgICovCiAgICB3aGlsZSAobGVuLS0gPiAwKSB7CiAgICAgICAgLyoKICAgICAgICAgKiB0aGVzZSBtdXN0IGJlIGRvbmUgaW4gc2VwZXJhdGUgY29tcGFyaXNvbnMsIHNpbmNlCiAgICAgICAgICogc3VidHJhY3RpbmcgdGhlbSBhbmQgdXNpbmcgdGhhdCByZXN1bHQgaGFzIHByb2JsZW1zIHdpdGgKICAgICAgICAgKiBzdWJpZHMgPiAyXjMxLiAKICAgICAgICAgKi8KICAgICAgICBpZiAoKihuYW1lMSkgIT0gKihuYW1lMikpIHsKICAgICAgICAgICAgKm9mZnB0ID0gaW5pdGxlbiAtIGxlbjsKICAgICAgICAgICAgaWYgKCoobmFtZTEpIDwgKihuYW1lMikpCiAgICAgICAgICAgICAgICByZXR1cm4gLTE7CiAgICAgICAgICAgIHJldHVybiAxOwogICAgICAgIH0KICAgICAgICBuYW1lMSsrOwogICAgICAgIG5hbWUyKys7CiAgICB9CiAgICAvKgogICAgICogYm90aCBPSURzIGVxdWFsIHVwIHRvIGxlbmd0aCBvZiBzaG9ydGVyIE9JRCAKICAgICAqLwogICAgKm9mZnB0ID0gaW5pdGxlbiAtIGxlbjsKICAgIGlmIChsZW4xIDwgbGVuMikKICAgICAgICByZXR1cm4gLTE7CiAgICBpZiAobGVuMiA8IGxlbjEpCiAgICAgICAgcmV0dXJuIDE7CiAgICByZXR1cm4gMDsKfQoKLyoqIENvbXBhcmVzIDIgT0lEcyB0byBkZXRlcm1pbmUgaWYgdGhleSBhcmUgZXF1YWwgdXAgdW50aWwgdGhlIHNob3J0ZXN0IGxlbmd0aC4KICogQHBhcmFtIGluX25hbWUxIEEgcG9pbnRlciB0byB0aGUgZmlyc3Qgb2lkLgogKiBAcGFyYW0gbGVuMSAgICAgbGVuZ3RoIG9mIHRoZSBmaXJzdCBPSUQgKGluIHNlZ21lbnRzLCBub3QgYnl0ZXMpCiAqIEBwYXJhbSBpbl9uYW1lMiBBIHBvaW50ZXIgdG8gdGhlIHNlY29uZCBvaWQuCiAqIEBwYXJhbSBsZW4yICAgICBsZW5ndGggb2YgdGhlIHNlY29uZCBPSUQgKGluIHNlZ21lbnRzLCBub3QgYnl0ZXMpCiAqIEByZXR1cm4gMCBpZiB0aGV5IGFyZSBlcXVhbCwgMSBpZiBpbl9uYW1lMSBpcyA+IGluX25hbWUyLCBvciAtMSBpZiA8LgogKi8gCmludApzbm1wX29pZHRyZWVfY29tcGFyZShjb25zdCBvaWQgKiBpbl9uYW1lMSwKICAgICAgICAgICAgICAgICAgICAgc2l6ZV90IGxlbjEsIGNvbnN0IG9pZCAqIGluX25hbWUyLCBzaXplX3QgbGVuMikKewogICAgaW50ICAgICAgICAgICAgIGxlbiA9ICgobGVuMSA8IGxlbjIpID8gbGVuMSA6IGxlbjIpOwoKICAgIHJldHVybiAoc25tcF9vaWRfY29tcGFyZShpbl9uYW1lMSwgbGVuLCBpbl9uYW1lMiwgbGVuKSk7Cn0KCmludApzbm1wX29pZHN1YnRyZWVfY29tcGFyZShjb25zdCBvaWQgKiBpbl9uYW1lMSwKICAgICAgICAgICAgICAgICAgICAgc2l6ZV90IGxlbjEsIGNvbnN0IG9pZCAqIGluX25hbWUyLCBzaXplX3QgbGVuMikKewogICAgaW50ICAgICAgICAgICAgIGxlbiA9ICgobGVuMSA8IGxlbjIpID8gbGVuMSA6IGxlbjIpOwoKICAgIHJldHVybiAoc25tcF9vaWRfY29tcGFyZShpbl9uYW1lMSwgbGVuMSwgaW5fbmFtZTIsIGxlbikpOwp9CgovKiogQ29tcGFyZXMgMiBPSURzIHRvIGRldGVybWluZSBpZiB0aGV5IGFyZSBleGFjdGx5IGVxdWFsLgogKiAgVGhpcyBzaG91bGQgYmUgZmFzdGVyIHRoYW4gZG9pbmcgYSBzbm1wX29pZF9jb21wYXJlIGZvciBkaWZmZXJlbnQKICogIGxlbmd0aCBPSURzLCBzaW5jZSB0aGUgbGVuZ3RoIGlzIGNoZWNrZWQgZmlyc3QgYW5kIGlmICE9IHJldHVybnMKICogIGltbWVkaWF0ZWx5LiAgTWlnaHQgYmUgdmVyeSBzbGlnaGx5IGZhc3RlciBpZiBsZW5ndGhzIGFyZSA9PS4KICogQHBhcmFtIGluX25hbWUxIEEgcG9pbnRlciB0byB0aGUgZmlyc3Qgb2lkLgogKiBAcGFyYW0gbGVuMSAgICAgbGVuZ3RoIG9mIHRoZSBmaXJzdCBPSUQgKGluIHNlZ21lbnRzLCBub3QgYnl0ZXMpCiAqIEBwYXJhbSBpbl9uYW1lMiBBIHBvaW50ZXIgdG8gdGhlIHNlY29uZCBvaWQuCiAqIEBwYXJhbSBsZW4yICAgICBsZW5ndGggb2YgdGhlIHNlY29uZCBPSUQgKGluIHNlZ21lbnRzLCBub3QgYnl0ZXMpCiAqIEByZXR1cm4gMCBpZiB0aGV5IGFyZSBlcXVhbCwgMSBpZiB0aGV5IGFyZSBub3QuCiAqLyAKaW50Cm5ldHNubXBfb2lkX2VxdWFscyhjb25zdCBvaWQgKiBpbl9uYW1lMSwKICAgICAgICAgICAgICAgICAgIHNpemVfdCBsZW4xLCBjb25zdCBvaWQgKiBpbl9uYW1lMiwgc2l6ZV90IGxlbjIpCnsKICAgIHJlZ2lzdGVyIGNvbnN0IG9pZCAqbmFtZTEgPSBpbl9uYW1lMTsKICAgIHJlZ2lzdGVyIGNvbnN0IG9pZCAqbmFtZTIgPSBpbl9uYW1lMjsKICAgIHJlZ2lzdGVyIGludCAgICBsZW4gPSBsZW4xOwoKICAgIC8qCiAgICAgKiBsZW4gPSBtaW5pbXVtIG9mIGxlbjEgYW5kIGxlbjIgCiAgICAgKi8KICAgIGlmIChsZW4xICE9IGxlbjIpCiAgICAgICAgcmV0dXJuIDE7CiAgICAvKgogICAgICogSGFuZGxlICdudWxsJyBPSURzCiAgICAgKi8KICAgIGlmIChsZW4xID09IDApCiAgICAgICAgcmV0dXJuIDA7ICAgLyogVHdvIG51bGwgT0lEcyBhcmUgKHRyaXZpYWxseSkgdGhlIHNhbWUgKi8KICAgIGlmICghbmFtZTEgfHwgIW5hbWUyKQogICAgICAgIHJldHVybiAxOyAgIC8qIE90aGVyd2lzZSBzb21ldGhpbmcncyB3cm9uZywgc28gcmVwb3J0IGEgbm9uLW1hdGNoICovCiAgICAvKgogICAgICogZmluZCBmaXJzdCBub24tbWF0Y2hpbmcgT0lEIAogICAgICovCiAgICB3aGlsZSAobGVuLS0gPiAwKSB7CiAgICAgICAgLyoKICAgICAgICAgKiB0aGVzZSBtdXN0IGJlIGRvbmUgaW4gc2VwZXJhdGUgY29tcGFyaXNvbnMsIHNpbmNlCiAgICAgICAgICogc3VidHJhY3RpbmcgdGhlbSBhbmQgdXNpbmcgdGhhdCByZXN1bHQgaGFzIHByb2JsZW1zIHdpdGgKICAgICAgICAgKiBzdWJpZHMgPiAyXjMxLiAKICAgICAgICAgKi8KICAgICAgICBpZiAoKihuYW1lMSsrKSAhPSAqKG5hbWUyKyspKQogICAgICAgICAgICByZXR1cm4gMTsKICAgIH0KICAgIHJldHVybiAwOwp9CgovKiogSWRlbnRpY2FsIHRvIG5ldHNubXBfb2lkX2VxdWFscywgZXhjZXB0IG9ubHkgdGhlIGxlbmd0aCB1cCB0byBsZW4xIGlzIGNvbXBhcmVkLgogKiBGdW5jdGlvbmFsbHksIHRoaXMgZGV0ZXJtaW5lcyBpZiBpbl9uYW1lMiBpcyBlcXVhbCBvciBhIHN1YnRyZWUgb2YgaW5fbmFtZTEKICogQHBhcmFtIGluX25hbWUxIEEgcG9pbnRlciB0byB0aGUgZmlyc3Qgb2lkLgogKiBAcGFyYW0gbGVuMSAgICAgbGVuZ3RoIG9mIHRoZSBmaXJzdCBPSUQgKGluIHNlZ21lbnRzLCBub3QgYnl0ZXMpCiAqIEBwYXJhbSBpbl9uYW1lMiBBIHBvaW50ZXIgdG8gdGhlIHNlY29uZCBvaWQuCiAqIEBwYXJhbSBsZW4yICAgICBsZW5ndGggb2YgdGhlIHNlY29uZCBPSUQgKGluIHNlZ21lbnRzLCBub3QgYnl0ZXMpCiAqIEByZXR1cm4gMCBpZiBvbmUgaXMgYSBjb21tb24gcHJlZml4IG9mIHRoZSBvdGhlci4KICovIAppbnQKbmV0c25tcF9vaWRfaXNfc3VidHJlZShjb25zdCBvaWQgKiBpbl9uYW1lMSwKICAgICAgICAgICAgICAgICAgICAgICBzaXplX3QgbGVuMSwgY29uc3Qgb2lkICogaW5fbmFtZTIsIHNpemVfdCBsZW4yKQp7CiAgICBpZiAobGVuMSA+IGxlbjIpCiAgICAgICAgcmV0dXJuIDE7CgogICAgaWYgKG1lbWNtcChpbl9uYW1lMSwgaW5fbmFtZTIsIGxlbjEgKiBzaXplb2Yob2lkKSkpCiAgICAgICAgcmV0dXJuIDE7CgogICAgcmV0dXJuIDA7Cn0KCi8qKiBHaXZlbiB0d28gT0lEcywgZGV0ZXJtaW5lIHRoZSBjb21tb24gcHJlZml4IHRvIHRoZW0gYm90aC4KICogQHBhcmFtIGluX25hbWUxIEEgcG9pbnRlciB0byB0aGUgZmlyc3Qgb2lkLgogKiBAcGFyYW0gbGVuMSAgICAgTGVuZ3RoIG9mIHRoZSBmaXJzdCBvaWQuCiAqIEBwYXJhbSBpbl9uYW1lMiBBIHBvaW50ZXIgdG8gdGhlIHNlY29uZCBvaWQuCiAqIEBwYXJhbSBsZW4yICAgICBMZW5ndGggb2YgdGhlIHNlY29uZCBvaWQuCiAqIEByZXR1cm4gICAgICAgICBsZW5ndGggb2YgY29tbW9uIHByZWZpeAogKiAgICAgICAgICAgICAgICAgMCBpZiBubyBjb21tb24gcHJlZml4LCAtMSBvbiBlcnJvci4KICovCmludApuZXRzbm1wX29pZF9maW5kX3ByZWZpeChjb25zdCBvaWQgKiBpbl9uYW1lMSwgc2l6ZV90IGxlbjEsCiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG9pZCAqIGluX25hbWUyLCBzaXplX3QgbGVuMikKewogICAgaW50IGk7CiAgICBzaXplX3QgbWluX3NpemU7CgogICAgaWYgKCFpbl9uYW1lMSB8fCAhaW5fbmFtZTIgfHwgIWxlbjEgfHwgIWxlbjIpCiAgICAgICAgcmV0dXJuIC0xOwoKICAgIGlmIChpbl9uYW1lMVswXSAhPSBpbl9uYW1lMlswXSkKICAgICAgICByZXR1cm4gMDsgICAvKiBObyBtYXRjaCAqLwogICAgbWluX3NpemUgPSBTTk1QX01JTihsZW4xLCBsZW4yKTsKICAgIGZvcihpID0gMDsgaSA8IChpbnQpbWluX3NpemU7IGkrKykgewogICAgICAgIGlmIChpbl9uYW1lMVtpXSAhPSBpbl9uYW1lMltpXSkKICAgICAgICAgICAgcmV0dXJuIGk7ICAgIC8qICftJyBpcyB0aGUgZmlyc3QgZGlmZmVyaW5nIHN1YmlkZW50aWZpZXIKICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNvIHRoZSBjb21tb24gcHJlZml4IGlzIDAuLihpLTEpLCBvZiBsZW5ndGggaSAqLwogICAgfQogICAgcmV0dXJuIG1pbl9zaXplOwkvKiBUaGUgc2hvcnRlciBPSUQgaXMgYSBwcmVmaXggb2YgdGhlIGxvbmdlciwgYW5kCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGhlbmNlIGlzIHByZWNpc2VseSB0aGUgY29tbW9uIHByZWZpeCBvZiB0aGUgdHdvLgogICAgICAgICAgICAgICAgICAgICAgICAgICBSZXR1cm4gaXRzIGxlbmd0aC4gKi8KfQoKc3RhdGljIGludCBfY2hlY2tfcmFuZ2Uoc3RydWN0IHRyZWUgKnRwLCBsb25nIGx0bXAsIGludCAqcmVzcHRyLAoJICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgKmVycm1zZykKewogICAgY2hhciAqY3AgICA9IE5VTEw7CiAgICBjaGFyICp0ZW1wID0gTlVMTDsKICAgIGludCAgIHRlbXBfbGVuID0gMDsKICAgIGludCBjaGVjayA9ICFuZXRzbm1wX2RzX2dldF9ib29sZWFuKE5FVFNOTVBfRFNfTElCUkFSWV9JRCwKCSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTkVUU05NUF9EU19MSUJfRE9OVF9DSEVDS19SQU5HRSk7CiAgCiAgICBpZiAoY2hlY2sgJiYgdHAgJiYgdHAtPnJhbmdlcykgewoJc3RydWN0IHJhbmdlX2xpc3QgKnJwID0gdHAtPnJhbmdlczsKCXdoaWxlIChycCkgewoJICAgIGlmIChycC0+bG93IDw9IGx0bXAgJiYgbHRtcCA8PSBycC0+aGlnaCkgYnJlYWs7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBBbGxvdyBmb3VyIGRpZ2l0cyBwZXIgcmFuZ2UgdmFsdWUgKi8KICAgICAgICAgICAgdGVtcF9sZW4gKz0gKChycC0+bG93ICE9IHJwLT5oaWdoKSA/IDE0IDogOCApOwoJICAgIHJwID0gcnAtPm5leHQ7Cgl9CglpZiAoIXJwKSB7CgkgICAgKnJlc3B0ciA9IFNOTVBFUlJfUkFOR0U7CiAgICAgICAgICAgIHRlbXAgPSAoY2hhciAqKW1hbGxvYyggdGVtcF9sZW4rc3RybGVuKGVycm1zZykrNyk7CiAgICAgICAgICAgIGlmICggdGVtcCApIHsKICAgICAgICAgICAgICAgIC8qIEFwcGVuZCB0aGUgRGlzcGxheSBIaW50IHJhbmdlIGluZm9ybWF0aW9uIHRvIHRoZSBlcnJvciBtZXNzYWdlICovCiAgICAgICAgICAgICAgICBzcHJpbnRmKCB0ZW1wLCAiJXMgOjogeyIsIGVycm1zZyApOwogICAgICAgICAgICAgICAgY3AgPSB0ZW1wKyhzdHJsZW4odGVtcCkpOwogICAgICAgICAgICAgICAgZm9yICggcnAgPSB0cC0+cmFuZ2VzOyBycDsgcnA9cnAtPm5leHQgKSB7CiAgICAgICAgICAgICAgICAgICAgaWYgKCBycC0+bG93ICE9IHJwLT5oaWdoICkgCiAgICAgICAgICAgICAgICAgICAgICAgIHNwcmludGYoIGNwLCAiKCVkLi4lZCksICIsIHJwLT5sb3csIHJwLT5oaWdoICk7CiAgICAgICAgICAgICAgICAgICAgZWxzZQogICAgICAgICAgICAgICAgICAgICAgICBzcHJpbnRmKCBjcCwgIiglZCksICIsIHJwLT5sb3cgKTsKICAgICAgICAgICAgICAgICAgICBjcCArPSBzdHJsZW4oY3ApOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgKihjcC0yKSA9ICd9JzsgICAvKiBSZXBsYWNlIHRoZSBmaW5hbCBjb21tYSB3aXRoIGEgJ30nICovCiAgICAgICAgICAgICAgICAqKGNwLTEpID0gMDsKCSAgICAgICAgc25tcF9zZXRfZGV0YWlsKHRlbXApOwoJICAgICAgICBmcmVlKHRlbXApOwogICAgICAgICAgICB9CgkgICAgcmV0dXJuIDA7Cgl9CiAgICB9CiAgICBmcmVlKHRlbXApOwogICAgcmV0dXJuIDE7Cn0KICAgICAgICAKCi8qCiAqIEFkZCBhIHZhcmlhYmxlIHdpdGggdGhlIHJlcXVlc3RlZCBuYW1lIHRvIHRoZSBlbmQgb2YgdGhlIGxpc3Qgb2YKICogdmFyaWFibGVzIGZvciB0aGlzIHBkdS4KICovCm5ldHNubXBfdmFyaWFibGVfbGlzdCAqCnNubXBfcGR1X2FkZF92YXJpYWJsZShuZXRzbm1wX3BkdSAqcGR1LAogICAgICAgICAgICAgICAgICAgICAgY29uc3Qgb2lkICogbmFtZSwKICAgICAgICAgICAgICAgICAgICAgIHNpemVfdCBuYW1lX2xlbmd0aCwKICAgICAgICAgICAgICAgICAgICAgIHVfY2hhciB0eXBlLCBjb25zdCB2b2lkICogdmFsdWUsIHNpemVfdCBsZW4pCnsKICAgIHJldHVybiBzbm1wX3Zhcmxpc3RfYWRkX3ZhcmlhYmxlKCZwZHUtPnZhcmlhYmxlcywgbmFtZSwgbmFtZV9sZW5ndGgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlLCB2YWx1ZSwgbGVuKTsKfQoKLyoKICogQWRkIGEgdmFyaWFibGUgd2l0aCB0aGUgcmVxdWVzdGVkIG5hbWUgdG8gdGhlIGVuZCBvZiB0aGUgbGlzdCBvZgogKiB2YXJpYWJsZXMgZm9yIHRoaXMgcGR1LgogKi8KbmV0c25tcF92YXJpYWJsZV9saXN0ICoKc25tcF92YXJsaXN0X2FkZF92YXJpYWJsZShuZXRzbm1wX3ZhcmlhYmxlX2xpc3QgKiogdmFybGlzdCwKICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBvaWQgKiBuYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVfdCBuYW1lX2xlbmd0aCwKICAgICAgICAgICAgICAgICAgICAgICAgICB1X2NoYXIgdHlwZSwgY29uc3Qgdm9pZCAqIHZhbHVlLCBzaXplX3QgbGVuKQp7CiAgICBuZXRzbm1wX3ZhcmlhYmxlX2xpc3QgKnZhcnMsICp2dG1wOwogICAgaW50IHJjOwoKICAgIGlmICh2YXJsaXN0ID09IE5VTEwpCiAgICAgICAgcmV0dXJuIE5VTEw7CgogICAgdmFycyA9IFNOTVBfTUFMTE9DX1RZUEVERUYobmV0c25tcF92YXJpYWJsZV9saXN0KTsKICAgIGlmICh2YXJzID09IE5VTEwpCiAgICAgICAgcmV0dXJuIE5VTEw7CgogICAgdmFycy0+dHlwZSA9IHR5cGU7CgogICAgcmMgPSBzbm1wX3NldF92YXJfdmFsdWUoIHZhcnMsIHZhbHVlLCBsZW4gKTsKICAgIGlmICgoIDAgIT0gcmMgKSB8fAogICAgICAgIChuYW1lICE9IE5VTEwgJiYgc25tcF9zZXRfdmFyX29iamlkKHZhcnMsIG5hbWUsIG5hbWVfbGVuZ3RoKSkpIHsKICAgICAgICBzbm1wX2ZyZWVfdmFyKHZhcnMpOwogICAgICAgIHJldHVybiBOVUxMOwogICAgfQoKICAgIC8qCiAgICAgKiBwdXQgb25seSBxdWFsaWZpZWQgdmFyaWFibGUgb250byB2YXJsaXN0IAogICAgICovCiAgICBpZiAoKnZhcmxpc3QgPT0gTlVMTCkgewogICAgICAgICp2YXJsaXN0ID0gdmFyczsKICAgIH0gZWxzZSB7CiAgICAgICAgZm9yICh2dG1wID0gKnZhcmxpc3Q7IHZ0bXAtPm5leHRfdmFyaWFibGU7CiAgICAgICAgICAgICB2dG1wID0gdnRtcC0+bmV4dF92YXJpYWJsZSk7CgogICAgICAgIHZ0bXAtPm5leHRfdmFyaWFibGUgPSB2YXJzOwogICAgfQoKICAgIHJldHVybiB2YXJzOwp9CgoKCi8qCiAqIEFkZCBhIHZhcmlhYmxlIHdpdGggdGhlIHJlcXVlc3RlZCBuYW1lIHRvIHRoZSBlbmQgb2YgdGhlIGxpc3Qgb2YKICogdmFyaWFibGVzIGZvciB0aGlzIHBkdS4KICogUmV0dXJuczoKICogbWF5IHNldCB0aGVzZSBlcnJvciB0eXBlcyA6CiAqIFNOTVBFUlJfUkFOR0UgLSB0eXBlLCB2YWx1ZSwgb3IgbGVuZ3RoIG5vdCBmb3VuZCBvciBvdXQgb2YgcmFuZ2UKICogU05NUEVSUl9WQUxVRSAtIHZhbHVlIGlzIG5vdCBjb3JyZWN0CiAqIFNOTVBFUlJfVkFSX1RZUEUgLSB0eXBlIGlzIG5vdCBjb3JyZWN0CiAqIFNOTVBFUlJfQkFEX05BTUUgLSBuYW1lIGlzIG5vdCBmb3VuZAogKgogKiByZXR1cm5zIDAgaWYgc3VjY2VzcywgZXJyb3IgaWYgZmFpbHVyZS4KICovCmludApzbm1wX2FkZF92YXIobmV0c25tcF9wZHUgKnBkdSwKICAgICAgICAgICAgIGNvbnN0IG9pZCAqIG5hbWUsIHNpemVfdCBuYW1lX2xlbmd0aCwgY2hhciB0eXBlLCBjb25zdCBjaGFyICp2YWx1ZSkKewogICAgY2hhciAgICAgICAgICAgKnN0OwogICAgY29uc3QgY2hhciAgICAgKmNwOwogICAgY2hhciAgICAgICAgICAgKmVjcCwgKnZwOwogICAgaW50ICAgICAgICAgICAgIHJlc3VsdCA9IFNOTVBFUlJfU1VDQ0VTUzsKI2lmbmRlZiBORVRTTk1QX0RJU0FCTEVfTUlCX0xPQURJTkcKICAgIGludCAgICAgICAgICAgICBjaGVjayA9ICFuZXRzbm1wX2RzX2dldF9ib29sZWFuKE5FVFNOTVBfRFNfTElCUkFSWV9JRCwKCQkJCQkgICAgIE5FVFNOTVBfRFNfTElCX0RPTlRfQ0hFQ0tfUkFOR0UpOwogICAgaW50ICAgICAgICAgICAgIGRvX2hpbnQgPSAhbmV0c25tcF9kc19nZXRfYm9vbGVhbihORVRTTk1QX0RTX0xJQlJBUllfSUQsCgkJCQkJICAgICBORVRTTk1QX0RTX0xJQl9OT19ESVNQTEFZX0hJTlQpOwogICAgdV9jaGFyICAgICAgICAgKmhpbnRwdHI7CiAgICBzdHJ1Y3QgdHJlZSAgICAqdHA7CiNlbmRpZiAvKiBORVRTTk1QX0RJU0FCTEVfTUlCX0xPQURJTkcgKi8KICAgIHVfY2hhciAgICAgICAgICpidWYgPSBOVUxMOwogICAgY29uc3QgdV9jaGFyICAgKmJ1Zl9wdHIgPSBOVUxMOwogICAgc2l6ZV90ICAgICAgICAgIGJ1Zl9sZW4gPSAwLCB2YWx1ZV9sZW4gPSAwLCB0aW50OwogICAgaW5fYWRkcl90ICAgICAgIGF0bXA7CiAgICBsb25nICAgICAgICAgICAgbHRtcDsKICAgIGludCAgICAgICAgICAgICBpdG1wOwogICAgc3RydWN0IGVudW1fbGlzdCAqZXA7CiNpZmRlZiBORVRTTk1QX1dJVEhfT1BBUVVFX1NQRUNJQUxfVFlQRVMKICAgIGRvdWJsZSAgICAgICAgICBkdG1wOwogICAgZmxvYXQgICAgICAgICAgIGZ0bXA7CiNlbmRpZiAgICAgICAgICAgICAgICAgICAgICAgICAgLyogTkVUU05NUF9XSVRIX09QQVFVRV9TUEVDSUFMX1RZUEVTICovCiAgICBzdHJ1Y3QgY291bnRlcjY0IGM2NHRtcDsKCiNpZm5kZWYgTkVUU05NUF9ESVNBQkxFX01JQl9MT0FESU5HCiAgICB0cCA9IGdldF90cmVlKG5hbWUsIG5hbWVfbGVuZ3RoLCBnZXRfdHJlZV9oZWFkKCkpOwogICAgaWYgKCF0cCB8fCAhdHAtPnR5cGUgfHwgdHAtPnR5cGUgPiBUWVBFX1NJTVBMRV9MQVNUKSB7CiAgICAgICAgY2hlY2sgPSAwOwogICAgfQogICAgaWYgKCEodHAgJiYgdHAtPmhpbnQpKQoJZG9faGludCA9IDA7CgogICAgaWYgKHRwICYmIHR5cGUgPT0gJz0nKSB7CiAgICAgICAgLyoKICAgICAgICAgKiBnZW5lcmljIGFzc2lnbm1lbnQgLSBsZXQgdGhlIHRyZWUgbm9kZSBkZWNpZGUgdmFsdWUgZm9ybWF0IAogICAgICAgICAqLwogICAgICAgIHN3aXRjaCAodHAtPnR5cGUpIHsKICAgICAgICBjYXNlIFRZUEVfSU5URUdFUjoKICAgICAgICBjYXNlIFRZUEVfSU5URUdFUjMyOgogICAgICAgICAgICB0eXBlID0gJ2knOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFRZUEVfR0FVR0U6CiAgICAgICAgY2FzZSBUWVBFX1VOU0lHTkVEMzI6CiAgICAgICAgICAgIHR5cGUgPSAndSc7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgVFlQRV9VSU5URUdFUjoKICAgICAgICAgICAgdHlwZSA9ICczJzsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBUWVBFX0NPVU5URVI6CiAgICAgICAgICAgIHR5cGUgPSAnYyc7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgVFlQRV9DT1VOVEVSNjQ6CiAgICAgICAgICAgIHR5cGUgPSAnQyc7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgVFlQRV9USU1FVElDS1M6CiAgICAgICAgICAgIHR5cGUgPSAndCc7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgVFlQRV9PQ1RFVFNUUjoKICAgICAgICAgICAgdHlwZSA9ICdzJzsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBUWVBFX0JJVFNUUklORzoKICAgICAgICAgICAgdHlwZSA9ICdiJzsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBUWVBFX0lQQUREUjoKICAgICAgICAgICAgdHlwZSA9ICdhJzsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBUWVBFX09CSklEOgogICAgICAgICAgICB0eXBlID0gJ28nOwogICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICB9CiNlbmRpZiAvKiBORVRTTk1QX0RJU0FCTEVfTUlCX0xPQURJTkcgKi8KCiAgICBzd2l0Y2ggKHR5cGUpIHsKICAgIGNhc2UgJ2knOgojaWZuZGVmIE5FVFNOTVBfRElTQUJMRV9NSUJfTE9BRElORwogICAgICAgIGlmIChjaGVjayAmJiB0cC0+dHlwZSAhPSBUWVBFX0lOVEVHRVIKICAgICAgICAgICAgJiYgdHAtPnR5cGUgIT0gVFlQRV9JTlRFR0VSMzIpIHsKICAgICAgICAgICAgdmFsdWUgPSAiSU5URUdFUiI7CiAgICAgICAgICAgIHJlc3VsdCA9IFNOTVBFUlJfVkFMVUU7CiAgICAgICAgICAgIGdvdG8gdHlwZV9lcnJvcjsKICAgICAgICB9CiNlbmRpZiAvKiBORVRTTk1QX0RJU0FCTEVfTUlCX0xPQURJTkcgKi8KICAgICAgICBpZiAoISp2YWx1ZSkKICAgICAgICAgICAgZ290byBmYWlsOwogICAgICAgIGx0bXAgPSBzdHJ0b2wodmFsdWUsICZlY3AsIDEwKTsKICAgICAgICBpZiAoKmVjcCkgewojaWZuZGVmIE5FVFNOTVBfRElTQUJMRV9NSUJfTE9BRElORwogICAgICAgICAgICBlcCA9IHRwID8gdHAtPmVudW1zIDogTlVMTDsKICAgICAgICAgICAgd2hpbGUgKGVwKSB7CiAgICAgICAgICAgICAgICBpZiAoc3RyY21wKHZhbHVlLCBlcC0+bGFiZWwpID09IDApIHsKICAgICAgICAgICAgICAgICAgICBsdG1wID0gZXAtPnZhbHVlOwogICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgZXAgPSBlcC0+bmV4dDsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoIWVwKSB7CiNlbmRpZiAvKiBORVRTTk1QX0RJU0FCTEVfTUlCX0xPQURJTkcgKi8KICAgICAgICAgICAgICAgIHJlc3VsdCA9IFNOTVBFUlJfUkFOR0U7ICAgLyogPz8gb3IgU05NUEVSUl9WQUxVRTsgKi8KICAgICAgICAgICAgICAgIHNubXBfc2V0X2RldGFpbCh2YWx1ZSk7CiAgICAgICAgICAgICAgICBicmVhazsKI2lmbmRlZiBORVRTTk1QX0RJU0FCTEVfTUlCX0xPQURJTkcKICAgICAgICAgICAgfQojZW5kaWYgLyogTkVUU05NUF9ESVNBQkxFX01JQl9MT0FESU5HICovCiAgICAgICAgfQoKI2lmbmRlZiBORVRTTk1QX0RJU0FCTEVfTUlCX0xPQURJTkcKICAgICAgICBpZiAoIV9jaGVja19yYW5nZSh0cCwgbHRtcCwgJnJlc3VsdCwgdmFsdWUpKQogICAgICAgICAgICBicmVhazsKI2VuZGlmIC8qIE5FVFNOTVBfRElTQUJMRV9NSUJfTE9BRElORyAqLwogICAgICAgIHNubXBfcGR1X2FkZF92YXJpYWJsZShwZHUsIG5hbWUsIG5hbWVfbGVuZ3RoLCBBU05fSU5URUdFUiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJmx0bXAsIHNpemVvZihsdG1wKSk7CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSAndSc6CiNpZm5kZWYgTkVUU05NUF9ESVNBQkxFX01JQl9MT0FESU5HCiAgICAgICAgaWYgKGNoZWNrICYmIHRwLT50eXBlICE9IFRZUEVfR0FVR0UgJiYgdHAtPnR5cGUgIT0gVFlQRV9VTlNJR05FRDMyKSB7CiAgICAgICAgICAgIHZhbHVlID0gIlVuc2lnbmVkMzIiOwogICAgICAgICAgICByZXN1bHQgPSBTTk1QRVJSX1ZBTFVFOwogICAgICAgICAgICBnb3RvIHR5cGVfZXJyb3I7CiAgICAgICAgfQojZW5kaWYgLyogTkVUU05NUF9ESVNBQkxFX01JQl9MT0FESU5HICovCiAgICAgICAgbHRtcCA9IHN0cnRvdWwodmFsdWUsICZlY3AsIDEwKTsKICAgICAgICBpZiAoKnZhbHVlICYmICEqZWNwKQogICAgICAgICAgICBzbm1wX3BkdV9hZGRfdmFyaWFibGUocGR1LCBuYW1lLCBuYW1lX2xlbmd0aCwgQVNOX1VOU0lHTkVELAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJmx0bXAsIHNpemVvZihsdG1wKSk7CiAgICAgICAgZWxzZQogICAgICAgICAgICBnb3RvIGZhaWw7CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSAnMyc6CiNpZm5kZWYgTkVUU05NUF9ESVNBQkxFX01JQl9MT0FESU5HCiAgICAgICAgaWYgKGNoZWNrICYmIHRwLT50eXBlICE9IFRZUEVfVUlOVEVHRVIpIHsKICAgICAgICAgICAgdmFsdWUgPSAiVUludGVnZXIzMiI7CiAgICAgICAgICAgIHJlc3VsdCA9IFNOTVBFUlJfVkFMVUU7CiAgICAgICAgICAgIGdvdG8gdHlwZV9lcnJvcjsKICAgICAgICB9CiNlbmRpZiAvKiBORVRTTk1QX0RJU0FCTEVfTUlCX0xPQURJTkcgKi8KICAgICAgICBsdG1wID0gc3RydG91bCh2YWx1ZSwgJmVjcCwgMTApOwogICAgICAgIGlmICgqdmFsdWUgJiYgISplY3ApCiAgICAgICAgICAgIHNubXBfcGR1X2FkZF92YXJpYWJsZShwZHUsIG5hbWUsIG5hbWVfbGVuZ3RoLCBBU05fVUlOVEVHRVIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmbHRtcCwgc2l6ZW9mKGx0bXApKTsKICAgICAgICBlbHNlCiAgICAgICAgICAgIGdvdG8gZmFpbDsKICAgICAgICBicmVhazsKCiAgICBjYXNlICdjJzoKI2lmbmRlZiBORVRTTk1QX0RJU0FCTEVfTUlCX0xPQURJTkcKICAgICAgICBpZiAoY2hlY2sgJiYgdHAtPnR5cGUgIT0gVFlQRV9DT1VOVEVSKSB7CiAgICAgICAgICAgIHZhbHVlID0gIkNvdW50ZXIzMiI7CiAgICAgICAgICAgIHJlc3VsdCA9IFNOTVBFUlJfVkFMVUU7CiAgICAgICAgICAgIGdvdG8gdHlwZV9lcnJvcjsKICAgICAgICB9CiNlbmRpZiAvKiBORVRTTk1QX0RJU0FCTEVfTUlCX0xPQURJTkcgKi8KICAgICAgICBsdG1wID0gc3RydG91bCh2YWx1ZSwgJmVjcCwgMTApOwogICAgICAgIGlmICgqdmFsdWUgJiYgISplY3ApCiAgICAgICAgICAgIHNubXBfcGR1X2FkZF92YXJpYWJsZShwZHUsIG5hbWUsIG5hbWVfbGVuZ3RoLCBBU05fQ09VTlRFUiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZsdG1wLCBzaXplb2YobHRtcCkpOwogICAgICAgIGVsc2UKICAgICAgICAgICAgZ290byBmYWlsOwogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgJ0MnOgojaWZuZGVmIE5FVFNOTVBfRElTQUJMRV9NSUJfTE9BRElORwogICAgICAgIGlmIChjaGVjayAmJiB0cC0+dHlwZSAhPSBUWVBFX0NPVU5URVI2NCkgewogICAgICAgICAgICB2YWx1ZSA9ICJDb3VudGVyNjQiOwogICAgICAgICAgICByZXN1bHQgPSBTTk1QRVJSX1ZBTFVFOwogICAgICAgICAgICBnb3RvIHR5cGVfZXJyb3I7CiAgICAgICAgfQojZW5kaWYgLyogTkVUU05NUF9ESVNBQkxFX01JQl9MT0FESU5HICovCiAgICAgICAgaWYgKHJlYWQ2NCgmYzY0dG1wLCB2YWx1ZSkpCiAgICAgICAgICAgIHNubXBfcGR1X2FkZF92YXJpYWJsZShwZHUsIG5hbWUsIG5hbWVfbGVuZ3RoLCBBU05fQ09VTlRFUjY0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJmM2NHRtcCwgc2l6ZW9mKGM2NHRtcCkpOwogICAgICAgIGVsc2UKICAgICAgICAgICAgZ290byBmYWlsOwogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgJ3QnOgojaWZuZGVmIE5FVFNOTVBfRElTQUJMRV9NSUJfTE9BRElORwogICAgICAgIGlmIChjaGVjayAmJiB0cC0+dHlwZSAhPSBUWVBFX1RJTUVUSUNLUykgewogICAgICAgICAgICB2YWx1ZSA9ICJUaW1ldGlja3MiOwogICAgICAgICAgICByZXN1bHQgPSBTTk1QRVJSX1ZBTFVFOwogICAgICAgICAgICBnb3RvIHR5cGVfZXJyb3I7CiAgICAgICAgfQojZW5kaWYgLyogTkVUU05NUF9ESVNBQkxFX01JQl9MT0FESU5HICovCiAgICAgICAgbHRtcCA9IHN0cnRvdWwodmFsdWUsICZlY3AsIDEwKTsKICAgICAgICBpZiAoKnZhbHVlICYmICEqZWNwKQogICAgICAgICAgICBzbm1wX3BkdV9hZGRfdmFyaWFibGUocGR1LCBuYW1lLCBuYW1lX2xlbmd0aCwgQVNOX1RJTUVUSUNLUywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZsdG1wLCBzaXplb2YobG9uZykpOwogICAgICAgIGVsc2UKICAgICAgICAgICAgZ290byBmYWlsOwogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgJ2EnOgojaWZuZGVmIE5FVFNOTVBfRElTQUJMRV9NSUJfTE9BRElORwogICAgICAgIGlmIChjaGVjayAmJiB0cC0+dHlwZSAhPSBUWVBFX0lQQUREUikgewogICAgICAgICAgICB2YWx1ZSA9ICJJcEFkZHJlc3MiOwogICAgICAgICAgICByZXN1bHQgPSBTTk1QRVJSX1ZBTFVFOwogICAgICAgICAgICBnb3RvIHR5cGVfZXJyb3I7CiAgICAgICAgfQojZW5kaWYgLyogTkVUU05NUF9ESVNBQkxFX01JQl9MT0FESU5HICovCiAgICAgICAgYXRtcCA9IGluZXRfYWRkcih2YWx1ZSk7CiAgICAgICAgaWYgKGF0bXAgIT0gKGluX2FkZHJfdCkgLTEgfHwgIXN0cmNtcCh2YWx1ZSwgIjI1NS4yNTUuMjU1LjI1NSIpKQogICAgICAgICAgICBzbm1wX3BkdV9hZGRfdmFyaWFibGUocGR1LCBuYW1lLCBuYW1lX2xlbmd0aCwgQVNOX0lQQUREUkVTUywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZhdG1wLCBzaXplb2YoYXRtcCkpOwogICAgICAgIGVsc2UKICAgICAgICAgICAgZ290byBmYWlsOwogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgJ28nOgojaWZuZGVmIE5FVFNOTVBfRElTQUJMRV9NSUJfTE9BRElORwogICAgICAgIGlmIChjaGVjayAmJiB0cC0+dHlwZSAhPSBUWVBFX09CSklEKSB7CiAgICAgICAgICAgIHZhbHVlID0gIk9CSkVDVCBJREVOVElGSUVSIjsKICAgICAgICAgICAgcmVzdWx0ID0gU05NUEVSUl9WQUxVRTsKICAgICAgICAgICAgZ290byB0eXBlX2Vycm9yOwogICAgICAgIH0KI2VuZGlmIC8qIE5FVFNOTVBfRElTQUJMRV9NSUJfTE9BRElORyAqLwogICAgICAgIGlmICgoYnVmID0gKHVfY2hhciAqKW1hbGxvYyhzaXplb2Yob2lkKSAqIE1BWF9PSURfTEVOKSkgPT0gTlVMTCkgewogICAgICAgICAgICByZXN1bHQgPSBTTk1QRVJSX01BTExPQzsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICB0aW50ID0gTUFYX09JRF9MRU47CiAgICAgICAgICAgIGlmIChzbm1wX3BhcnNlX29pZCh2YWx1ZSwgKG9pZCAqKSBidWYsICZ0aW50KSkgewogICAgICAgICAgICAgICAgc25tcF9wZHVfYWRkX3ZhcmlhYmxlKHBkdSwgbmFtZSwgbmFtZV9sZW5ndGgsIEFTTl9PQkpFQ1RfSUQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnVmLCBzaXplb2Yob2lkKSAqIHRpbnQpOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgcmVzdWx0ID0gc25tcF9lcnJubzsgICAgLypNVENSSVRJQ0FMX1JFU09VUkNFICovCiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSAncyc6CiAgICBjYXNlICd4JzoKICAgIGNhc2UgJ2QnOgojaWZuZGVmIE5FVFNOTVBfRElTQUJMRV9NSUJfTE9BRElORwogICAgICAgIGlmIChjaGVjayAmJiB0cC0+dHlwZSAhPSBUWVBFX09DVEVUU1RSICYmIHRwLT50eXBlICE9IFRZUEVfQklUU1RSSU5HKSB7CiAgICAgICAgICAgIHZhbHVlID0gIk9DVEVUIFNUUklORyI7CiAgICAgICAgICAgIHJlc3VsdCA9IFNOTVBFUlJfVkFMVUU7CiAgICAgICAgICAgIGdvdG8gdHlwZV9lcnJvcjsKICAgICAgICB9CglpZiAoJ3MnID09IHR5cGUgJiYgZG9faGludCAmJiAhcGFyc2Vfb2N0ZXRfaGludCh0cC0+aGludCwgdmFsdWUsICZoaW50cHRyLCAmaXRtcCkpIHsKICAgICAgICAgICAgaWYgKF9jaGVja19yYW5nZSh0cCwgaXRtcCwgJnJlc3VsdCwgIlZhbHVlIGRvZXMgbm90IG1hdGNoIERJU1BMQVktSElOVCIpKSB7CiAgICAgICAgICAgICAgICBzbm1wX3BkdV9hZGRfdmFyaWFibGUocGR1LCBuYW1lLCBuYW1lX2xlbmd0aCwgQVNOX09DVEVUX1NUUiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoaW50cHRyLCBpdG1wKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBTTk1QX0ZSRUUoaGludHB0cik7CiAgICAgICAgICAgIGhpbnRwdHIgPSBidWY7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0KI2VuZGlmIC8qIE5FVFNOTVBfRElTQUJMRV9NSUJfTE9BRElORyAqLwogICAgICAgIGlmICh0eXBlID09ICdkJykgewogICAgICAgICAgICBpZiAoIXNubXBfZGVjaW1hbF90b19iaW5hcnkKICAgICAgICAgICAgICAgICgmYnVmLCAmYnVmX2xlbiwgJnZhbHVlX2xlbiwgMSwgdmFsdWUpKSB7CiAgICAgICAgICAgICAgICByZXN1bHQgPSBTTk1QRVJSX1ZBTFVFOwogICAgICAgICAgICAgICAgc25tcF9zZXRfZGV0YWlsKHZhbHVlKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGJ1Zl9wdHIgPSBidWY7CiAgICAgICAgfSBlbHNlIGlmICh0eXBlID09ICd4JykgewogICAgICAgICAgICBpZiAoIXNubXBfaGV4X3RvX2JpbmFyeSgmYnVmLCAmYnVmX2xlbiwgJnZhbHVlX2xlbiwgMSwgdmFsdWUpKSB7CiAgICAgICAgICAgICAgICByZXN1bHQgPSBTTk1QRVJSX1ZBTFVFOwogICAgICAgICAgICAgICAgc25tcF9zZXRfZGV0YWlsKHZhbHVlKTsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgICAgIC8qIGluaXRpYWxpemUgaXRtcCB2YWx1ZSBzbyB0aGF0IHJhbmdlIGNoZWNrIGJlbG93IHdvcmtzICovCiAgICAgICAgICAgIGl0bXAgPSB2YWx1ZV9sZW47CiAgICAgICAgICAgIGJ1Zl9wdHIgPSBidWY7CiAgICAgICAgfSBlbHNlIGlmICh0eXBlID09ICdzJykgewogICAgICAgICAgICBidWZfcHRyID0gKGNvbnN0IHVfY2hhciAqKXZhbHVlOwogICAgICAgICAgICB2YWx1ZV9sZW4gPSBzdHJsZW4odmFsdWUpOwogICAgICAgIH0KI2lmbmRlZiBORVRTTk1QX0RJU0FCTEVfTUlCX0xPQURJTkcKICAgICAgICBpZiAoIV9jaGVja19yYW5nZSh0cCwgdmFsdWVfbGVuLCAmcmVzdWx0LCAiQmFkIHN0cmluZyBsZW5ndGgiKSkKICAgICAgICAgICAgYnJlYWs7CiNlbmRpZiAvKiBORVRTTk1QX0RJU0FCTEVfTUlCX0xPQURJTkcgKi8KICAgICAgICBzbm1wX3BkdV9hZGRfdmFyaWFibGUocGR1LCBuYW1lLCBuYW1lX2xlbmd0aCwgQVNOX09DVEVUX1NUUiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYnVmX3B0ciwgdmFsdWVfbGVuKTsKICAgICAgICBicmVhazsKCiAgICBjYXNlICduJzoKICAgICAgICBzbm1wX3BkdV9hZGRfdmFyaWFibGUocGR1LCBuYW1lLCBuYW1lX2xlbmd0aCwgQVNOX05VTEwsIE5VTEwsIDApOwogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgJ2InOgojaWZuZGVmIE5FVFNOTVBfRElTQUJMRV9NSUJfTE9BRElORwogICAgICAgIGlmIChjaGVjayAmJiAodHAtPnR5cGUgIT0gVFlQRV9CSVRTVFJJTkcgfHwgIXRwLT5lbnVtcykpIHsKICAgICAgICAgICAgdmFsdWUgPSAiQklUUyI7CiAgICAgICAgICAgIHJlc3VsdCA9IFNOTVBFUlJfVkFMVUU7CiAgICAgICAgICAgIGdvdG8gdHlwZV9lcnJvcjsKICAgICAgICB9CiNlbmRpZiAvKiBORVRTTk1QX0RJU0FCTEVfTUlCX0xPQURJTkcgKi8KICAgICAgICB0aW50ID0gMDsKICAgICAgICBpZiAoKGJ1ZiA9ICh1X2NoYXIgKikgbWFsbG9jKDI1NikpID09IE5VTEwpIHsKICAgICAgICAgICAgcmVzdWx0ID0gU05NUEVSUl9NQUxMT0M7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGJ1Zl9sZW4gPSAyNTY7CiAgICAgICAgICAgIG1lbXNldChidWYsIDAsIGJ1Zl9sZW4pOwogICAgICAgIH0KCiNpZm5kZWYgTkVUU05NUF9ESVNBQkxFX01JQl9MT0FESU5HCiAgICAgICAgZm9yIChlcCA9IHRwID8gdHAtPmVudW1zIDogTlVMTDsgZXA7IGVwID0gZXAtPm5leHQpIHsKICAgICAgICAgICAgaWYgKGVwLT52YWx1ZSAvIDggPj0gKGludCkgdGludCkgewogICAgICAgICAgICAgICAgdGludCA9IGVwLT52YWx1ZSAvIDggKyAxOwogICAgICAgICAgICB9CiAgICAgICAgfQojZW5kaWYgLyogTkVUU05NUF9ESVNBQkxFX01JQl9MT0FESU5HICovCgoJdnAgPSBzdHJkdXAodmFsdWUpOwoJZm9yIChjcCA9IHN0cnRva19yKHZwLCAiICxcdCIsICZzdCk7IGNwOyBjcCA9IHN0cnRva19yKE5VTEwsICIgLFx0IiwgJnN0KSkgewogICAgICAgICAgICBpbnQgICAgICAgICAgICAgaXgsIGJpdDsKCiAgICAgICAgICAgIGx0bXAgPSBzdHJ0b3VsKGNwLCAmZWNwLCAwKTsKICAgICAgICAgICAgaWYgKCplY3AgIT0gMCkgewojaWZuZGVmIE5FVFNOTVBfRElTQUJMRV9NSUJfTE9BRElORwogICAgICAgICAgICAgICAgZm9yIChlcCA9IHRwID8gdHAtPmVudW1zIDogTlVMTDsgZXAgIT0gTlVMTDsgZXAgPSBlcC0+bmV4dCkgewogICAgICAgICAgICAgICAgICAgIGlmIChzdHJuY21wKGVwLT5sYWJlbCwgY3AsIHN0cmxlbihlcC0+bGFiZWwpKSA9PSAwKSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmIChlcCAhPSBOVUxMKSB7CiAgICAgICAgICAgICAgICAgICAgbHRtcCA9IGVwLT52YWx1ZTsKICAgICAgICAgICAgICAgIH0gZWxzZSB7CiNlbmRpZiAvKiBORVRTTk1QX0RJU0FCTEVfTUlCX0xPQURJTkcgKi8KICAgICAgICAgICAgICAgICAgICByZXN1bHQgPSBTTk1QRVJSX1JBTkdFOyAgIC8qID8/IG9yIFNOTVBFUlJfVkFMVUU7ICovCiAgICAgICAgICAgICAgICAgICAgc25tcF9zZXRfZGV0YWlsKGNwKTsKICAgICAgICAgICAgICAgICAgICBTTk1QX0ZSRUUoYnVmKTsKCQkgICAgU05NUF9GUkVFKHZwKTsKICAgICAgICAgICAgICAgICAgICBnb3RvIG91dDsKI2lmbmRlZiBORVRTTk1QX0RJU0FCTEVfTUlCX0xPQURJTkcKICAgICAgICAgICAgICAgIH0KI2VuZGlmIC8qIE5FVFNOTVBfRElTQUJMRV9NSUJfTE9BRElORyAqLwogICAgICAgICAgICB9CgogICAgICAgICAgICBpeCA9IGx0bXAgLyA4OwogICAgICAgICAgICBpZiAoaXggPj0gKGludCkgdGludCkgewogICAgICAgICAgICAgICAgdGludCA9IGl4ICsgMTsKICAgICAgICAgICAgfQogICAgICAgICAgICBpZiAoaXggPj0gKGludClidWZfbGVuICYmICFzbm1wX3JlYWxsb2MoJmJ1ZiwgJmJ1Zl9sZW4pKSB7CiAgICAgICAgICAgICAgICByZXN1bHQgPSBTTk1QRVJSX01BTExPQzsKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGJpdCA9IDB4ODAgPj4gbHRtcCAlIDg7CiAgICAgICAgICAgIGJ1ZltpeF0gfD0gYml0OwoJICAgIAogICAgICAgIH0KCVNOTVBfRlJFRSh2cCk7CiAgICAgICAgc25tcF9wZHVfYWRkX3ZhcmlhYmxlKHBkdSwgbmFtZSwgbmFtZV9sZW5ndGgsIEFTTl9PQ1RFVF9TVFIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ1ZiwgdGludCk7CiAgICAgICAgYnJlYWs7CgojaWZkZWYgTkVUU05NUF9XSVRIX09QQVFVRV9TUEVDSUFMX1RZUEVTCiAgICBjYXNlICdVJzoKICAgICAgICBpZiAocmVhZDY0KCZjNjR0bXAsIHZhbHVlKSkKICAgICAgICAgICAgc25tcF9wZHVfYWRkX3ZhcmlhYmxlKHBkdSwgbmFtZSwgbmFtZV9sZW5ndGgsIEFTTl9PUEFRVUVfVTY0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJmM2NHRtcCwgc2l6ZW9mKGM2NHRtcCkpOwogICAgICAgIGVsc2UKICAgICAgICAgICAgZ290byBmYWlsOwogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgJ0knOgogICAgICAgIGlmIChyZWFkNjQoJmM2NHRtcCwgdmFsdWUpKQogICAgICAgICAgICBzbm1wX3BkdV9hZGRfdmFyaWFibGUocGR1LCBuYW1lLCBuYW1lX2xlbmd0aCwgQVNOX09QQVFVRV9JNjQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmYzY0dG1wLCBzaXplb2YoYzY0dG1wKSk7CiAgICAgICAgZWxzZQogICAgICAgICAgICBnb3RvIGZhaWw7CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSAnRic6CiAgICAgICAgaWYgKHNzY2FuZih2YWx1ZSwgIiVmIiwgJmZ0bXApID09IDEpCiAgICAgICAgICAgIHNubXBfcGR1X2FkZF92YXJpYWJsZShwZHUsIG5hbWUsIG5hbWVfbGVuZ3RoLCBBU05fT1BBUVVFX0ZMT0FULAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJmZ0bXAsIHNpemVvZihmdG1wKSk7CiAgICAgICAgZWxzZQogICAgICAgICAgICBnb3RvIGZhaWw7CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSAnRCc6CiAgICAgICAgaWYgKHNzY2FuZih2YWx1ZSwgIiVsZiIsICZkdG1wKSA9PSAxKQogICAgICAgICAgICBzbm1wX3BkdV9hZGRfdmFyaWFibGUocGR1LCBuYW1lLCBuYW1lX2xlbmd0aCwgQVNOX09QQVFVRV9ET1VCTEUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmZHRtcCwgc2l6ZW9mKGR0bXApKTsKICAgICAgICBlbHNlCiAgICAgICAgICAgIGdvdG8gZmFpbDsKICAgICAgICBicmVhazsKI2VuZGlmICAgICAgICAgICAgICAgICAgICAgICAgICAvKiBORVRTTk1QX1dJVEhfT1BBUVVFX1NQRUNJQUxfVFlQRVMgKi8KCiAgICBkZWZhdWx0OgogICAgICAgIHJlc3VsdCA9IFNOTVBFUlJfVkFSX1RZUEU7CglidWYgPSAodV9jaGFyICopY2FsbG9jKDEsIDQpOwoJaWYgKGJ1ZiAhPSBOVUxMKSB7CgkgICAgc3ByaW50ZigoY2hhciAqKWJ1ZiwgIlwiJWNcIiIsIHR5cGUpOwoJICAgIHNubXBfc2V0X2RldGFpbCgoY2hhciAqKWJ1Zik7Cgl9CiAgICAgICAgYnJlYWs7CiAgICB9CgogICAgU05NUF9GUkVFKGJ1Zik7CiAgICBTRVRfU05NUF9FUlJPUihyZXN1bHQpOwogICAgcmV0dXJuIHJlc3VsdDsKCiNpZm5kZWYgTkVUU05NUF9ESVNBQkxFX01JQl9MT0FESU5HCiAgdHlwZV9lcnJvcjoKICAgIHsKICAgICAgICBjaGFyICAgICAgICAgICAgZXJyb3JfbXNnWzI1Nl07CiAgICAgICAgY2hhciAgICAgICAgICAgIHVuZGVmX21zZ1szMl07CiAgICAgICAgY29uc3QgY2hhciAgICAgKnZhcl90eXBlOwogICAgICAgIHN3aXRjaCAodHAtPnR5cGUpIHsKICAgICAgICBjYXNlIFRZUEVfT0JKSUQ6CiAgICAgICAgICAgIHZhcl90eXBlID0gIk9CSkVDVCBJREVOVElGSUVSIjsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBUWVBFX09DVEVUU1RSOgogICAgICAgICAgICB2YXJfdHlwZSA9ICJPQ1RFVCBTVFJJTkciOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFRZUEVfSU5URUdFUjoKICAgICAgICAgICAgdmFyX3R5cGUgPSAiSU5URUdFUiI7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgVFlQRV9ORVRBRERSOgogICAgICAgICAgICB2YXJfdHlwZSA9ICJOZXR3b3JrQWRkcmVzcyI7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgVFlQRV9JUEFERFI6CiAgICAgICAgICAgIHZhcl90eXBlID0gIklwQWRkcmVzcyI7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgVFlQRV9DT1VOVEVSOgogICAgICAgICAgICB2YXJfdHlwZSA9ICJDb3VudGVyMzIiOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFRZUEVfR0FVR0U6CiAgICAgICAgICAgIHZhcl90eXBlID0gIkdhdWdlMzIiOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFRZUEVfVElNRVRJQ0tTOgogICAgICAgICAgICB2YXJfdHlwZSA9ICJUaW1ldGlja3MiOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFRZUEVfT1BBUVVFOgogICAgICAgICAgICB2YXJfdHlwZSA9ICJPcGFxdWUiOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFRZUEVfTlVMTDoKICAgICAgICAgICAgdmFyX3R5cGUgPSAiTnVsbCI7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgVFlQRV9DT1VOVEVSNjQ6CiAgICAgICAgICAgIHZhcl90eXBlID0gIkNvdW50ZXI2NCI7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgVFlQRV9CSVRTVFJJTkc6CiAgICAgICAgICAgIHZhcl90eXBlID0gIkJJVFMiOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIFRZUEVfTlNBUEFERFJFU1M6CiAgICAgICAgICAgIHZhcl90eXBlID0gIk5zYXBBZGRyZXNzIjsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBUWVBFX1VJTlRFR0VSOgogICAgICAgICAgICB2YXJfdHlwZSA9ICJVSW50ZWdlciI7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgVFlQRV9VTlNJR05FRDMyOgogICAgICAgICAgICB2YXJfdHlwZSA9ICJVbnNpZ25lZDMyIjsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBUWVBFX0lOVEVHRVIzMjoKICAgICAgICAgICAgdmFyX3R5cGUgPSAiSW50ZWdlcjMyIjsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgc3ByaW50Zih1bmRlZl9tc2csICJUWVBFXyVkIiwgdHAtPnR5cGUpOwogICAgICAgICAgICB2YXJfdHlwZSA9IHVuZGVmX21zZzsKICAgICAgICB9CiAgICAgICAgc25wcmludGYoZXJyb3JfbXNnLCBzaXplb2YoZXJyb3JfbXNnKSwKICAgICAgICAgICAgICAgIlR5cGUgb2YgYXR0cmlidXRlIGlzICVzLCBub3QgJXMiLCB2YXJfdHlwZSwgdmFsdWUpOwogICAgICAgIGVycm9yX21zZ1sgc2l6ZW9mKGVycm9yX21zZyktMSBdID0gMDsKICAgICAgICByZXN1bHQgPSBTTk1QRVJSX1ZBUl9UWVBFOwogICAgICAgIHNubXBfc2V0X2RldGFpbChlcnJvcl9tc2cpOwogICAgICAgIGdvdG8gb3V0OwogICAgfQojZW5kaWYgLyogTkVUU05NUF9ESVNBQkxFX01JQl9MT0FESU5HICovCiAgZmFpbDoKICAgIHJlc3VsdCA9IFNOTVBFUlJfVkFMVUU7CiAgICBzbm1wX3NldF9kZXRhaWwodmFsdWUpOwogIG91dDoKICAgIFNFVF9TTk1QX0VSUk9SKHJlc3VsdCk7CiAgICByZXR1cm4gcmVzdWx0Owp9CgovKgogKiByZXR1cm5zIE5VTEwgb3IgaW50ZXJuYWwgcG9pbnRlciB0byBzZXNzaW9uCiAqIHVzZSB0aGlzIHBvaW50ZXIgZm9yIHRoZSBvdGhlciBzbm1wX3Nlc3MqIHJvdXRpbmVzLAogKiB3aGljaCBndWFyYW50ZWUgYWN0aW9uIHdpbGwgb2NjdXIgT05MWSBmb3IgdGhpcyBnaXZlbiBzZXNzaW9uLgogKi8Kdm9pZCAgICAgICAgICAgKgpzbm1wX3Nlc3NfcG9pbnRlcihuZXRzbm1wX3Nlc3Npb24gKiBzZXNzaW9uKQp7CiAgICBzdHJ1Y3Qgc2Vzc2lvbl9saXN0ICpzbHA7CgogICAgc25tcF9yZXNfbG9jayhNVF9MSUJSQVJZX0lELCBNVF9MSUJfU0VTU0lPTik7CiAgICBmb3IgKHNscCA9IFNlc3Npb25zOyBzbHA7IHNscCA9IHNscC0+bmV4dCkgewogICAgICAgIGlmIChzbHAtPnNlc3Npb24gPT0gc2Vzc2lvbikgewogICAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICB9CiAgICBzbm1wX3Jlc191bmxvY2soTVRfTElCUkFSWV9JRCwgTVRfTElCX1NFU1NJT04pOwoKICAgIGlmIChzbHAgPT0gTlVMTCkgewogICAgICAgIHNubXBfZXJybm8gPSBTTk1QRVJSX0JBRF9TRVNTSU9OOyAgICAgICAvKk1UQ1JJVElDQUxfUkVTT1VSQ0UgKi8KICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgfQogICAgcmV0dXJuICgodm9pZCAqKSBzbHApOwp9CgovKgogKiBJbnB1dCA6IGFuIG9wYXF1ZSBwb2ludGVyLCByZXR1cm5lZCBieSBzbm1wX3Nlc3Nfb3Blbi4KICogcmV0dXJucyBOVUxMIG9yIHBvaW50ZXIgdG8gc2Vzc2lvbi4KICovCm5ldHNubXBfc2Vzc2lvbiAqCnNubXBfc2Vzc19zZXNzaW9uKHZvaWQgKnNlc3NwKQp7CiAgICBzdHJ1Y3Qgc2Vzc2lvbl9saXN0ICpzbHAgPSAoc3RydWN0IHNlc3Npb25fbGlzdCAqKSBzZXNzcDsKICAgIGlmIChzbHAgPT0gTlVMTCkKICAgICAgICByZXR1cm4gKE5VTEwpOwogICAgcmV0dXJuIChzbHAtPnNlc3Npb24pOwp9CgovKioKICogTG9vayB1cCBhIHNlc3Npb24gdGhhdCBhbHJlYWR5IG1heSBoYXZlIGJlZW4gY2xvc2VkLgogKgogKiBAcGFyYW0gc2Vzc3AgT3BhcXVlIHBvaW50ZXIsIHJldHVybmVkIGJ5IHNubXBfc2Vzc19vcGVuLgogKgogKiBAcmV0dXJuIFBvaW50ZXIgdG8gc2Vzc2lvbiB1cG9uIHN1Y2Nlc3Mgb3IgTlVMTCB1cG9uIGZhaWx1cmUuCiAqCiAqIEBzZWUgc25tcF9zZXNzX3Nlc3Npb24oKQogKi8KbmV0c25tcF9zZXNzaW9uICoKc25tcF9zZXNzX3Nlc3Npb25fbG9va3VwKHZvaWQgKnNlc3NwKQp7CiAgICBzdHJ1Y3Qgc2Vzc2lvbl9saXN0ICpzbHA7CgogICAgc25tcF9yZXNfbG9jayhNVF9MSUJSQVJZX0lELCBNVF9MSUJfU0VTU0lPTik7CiAgICBmb3IgKHNscCA9IFNlc3Npb25zOyBzbHA7IHNscCA9IHNscC0+bmV4dCkgewogICAgICAgIGlmIChzbHAgPT0gc2Vzc3ApIHsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgfQogICAgc25tcF9yZXNfdW5sb2NrKE1UX0xJQlJBUllfSUQsIE1UX0xJQl9TRVNTSU9OKTsKCiAgICByZXR1cm4gKG5ldHNubXBfc2Vzc2lvbiAqKXNscDsKfQoKCi8qCiAqIHNubXBfc2Vzc190cmFuc3BvcnQ6IHRha2VzIGFuIG9wYXF1ZSBwb2ludGVyIChhcyByZXR1cm5lZCBieQogKiBzbm1wX3Nlc3Nfb3BlbiBvciBzbm1wX3Nlc3NfcG9pbnRlcikgYW5kIHJldHVybnMgdGhlIGNvcnJlc3BvbmRpbmcKICogbmV0c25tcF90cmFuc3BvcnQgcG9pbnRlciAob3IgTlVMTCBpZiB0aGUgb3BhcXVlIHBvaW50ZXIgZG9lcyBub3QgY29ycmVzcG9uZAogKiB0byBhbiBhY3RpdmUgaW50ZXJuYWwgc2Vzc2lvbikuICAKICovCgpuZXRzbm1wX3RyYW5zcG9ydCAqCnNubXBfc2Vzc190cmFuc3BvcnQodm9pZCAqc2Vzc3ApCnsKICAgIHN0cnVjdCBzZXNzaW9uX2xpc3QgKnNscCA9IChzdHJ1Y3Qgc2Vzc2lvbl9saXN0ICopIHNlc3NwOwogICAgaWYgKHNscCA9PSBOVUxMKSB7CiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICB9IGVsc2UgewogICAgICAgIHJldHVybiBzbHAtPnRyYW5zcG9ydDsKICAgIH0KfQoKCgovKgogKiBzbm1wX3Nlc3NfdHJhbnNwb3J0X3NldDogc2V0IHRoZSB0cmFuc3BvcnQgcG9pbnRlciBmb3IgdGhlIG9wYXF1ZQogKiBzZXNzaW9uIHBvaW50ZXIgc3AuICAKICovCgp2b2lkCnNubXBfc2Vzc190cmFuc3BvcnRfc2V0KHZvaWQgKnNwLCBuZXRzbm1wX3RyYW5zcG9ydCAqdCkKewogICAgc3RydWN0IHNlc3Npb25fbGlzdCAqc2xwID0gKHN0cnVjdCBzZXNzaW9uX2xpc3QgKikgc3A7CiAgICBpZiAoc2xwICE9IE5VTEwpIHsKICAgICAgICBzbHAtPnRyYW5zcG9ydCA9IHQ7CiAgICB9Cn0KCgovKgogKiBzbm1wX2R1cGxpY2F0ZV9vYmppZDogZHVwbGljYXRlcyAobWFsbG9jcykgYW4gb2JqaWQgYmFzZWQgb24gdGhlCiAqIGlucHV0IG9iamlkIAogKi8Kb2lkICAgICAgICAgICAgKgpzbm1wX2R1cGxpY2F0ZV9vYmppZChjb25zdCBvaWQgKiBvYmpUb0NvcHksIHNpemVfdCBvYmpUb0NvcHlMZW4pCnsKICAgIG9pZCAgICAgICAgICAgICpyZXR1cm5PaWQ7CiAgICBpZiAob2JqVG9Db3B5ICE9IE5VTEwgJiYgb2JqVG9Db3B5TGVuICE9IDApIHsKICAgICAgICByZXR1cm5PaWQgPSAob2lkICopIG1hbGxvYyhvYmpUb0NvcHlMZW4gKiBzaXplb2Yob2lkKSk7CiAgICAgICAgaWYgKHJldHVybk9pZCkgewogICAgICAgICAgICBtZW1jcHkocmV0dXJuT2lkLCBvYmpUb0NvcHksIG9ialRvQ29weUxlbiAqIHNpemVvZihvaWQpKTsKICAgICAgICB9CiAgICB9IGVsc2UKICAgICAgICByZXR1cm5PaWQgPSBOVUxMOwogICAgcmV0dXJuIHJldHVybk9pZDsKfQoKLyoKICogZ2VuZXJpYyBzdGF0aXN0aWNzIGNvdW50ZXIgZnVuY3Rpb25zIAogKi8Kc3RhdGljIHVfaW50ICAgIHN0YXRpc3RpY3NbTkVUU05NUF9TVEFUX01BWF9TVEFUU107Cgp1X2ludApzbm1wX2luY3JlbWVudF9zdGF0aXN0aWMoaW50IHdoaWNoKQp7CiAgICBpZiAod2hpY2ggPj0gMCAmJiB3aGljaCA8IE5FVFNOTVBfU1RBVF9NQVhfU1RBVFMpIHsKICAgICAgICBzdGF0aXN0aWNzW3doaWNoXSsrOwogICAgICAgIHJldHVybiBzdGF0aXN0aWNzW3doaWNoXTsKICAgIH0KICAgIHJldHVybiAwOwp9Cgp1X2ludApzbm1wX2luY3JlbWVudF9zdGF0aXN0aWNfYnkoaW50IHdoaWNoLCBpbnQgY291bnQpCnsKICAgIGlmICh3aGljaCA+PSAwICYmIHdoaWNoIDwgTkVUU05NUF9TVEFUX01BWF9TVEFUUykgewogICAgICAgIHN0YXRpc3RpY3Nbd2hpY2hdICs9IGNvdW50OwogICAgICAgIHJldHVybiBzdGF0aXN0aWNzW3doaWNoXTsKICAgIH0KICAgIHJldHVybiAwOwp9Cgp1X2ludApzbm1wX2dldF9zdGF0aXN0aWMoaW50IHdoaWNoKQp7CiAgICBpZiAod2hpY2ggPj0gMCAmJiB3aGljaCA8IE5FVFNOTVBfU1RBVF9NQVhfU1RBVFMpCiAgICAgICAgcmV0dXJuIHN0YXRpc3RpY3Nbd2hpY2hdOwogICAgcmV0dXJuIDA7Cn0KCnZvaWQKc25tcF9pbml0X3N0YXRpc3RpY3Modm9pZCkKewogICAgbWVtc2V0KHN0YXRpc3RpY3MsIDAsIHNpemVvZihzdGF0aXN0aWNzKSk7Cn0KLyoqICBAfSAqLwoK