LyogdmltOnNldCBzaGlmdHdpZHRoPTQgdHM9ODogKi8KLyoKICogUUVNVSBCbG9jayBkcml2ZXIgZm9yIHZpcnR1YWwgVkZBVCAoc2hhZG93cyBhIGxvY2FsIGRpcmVjdG9yeSkKICoKICogQ29weXJpZ2h0IChjKSAyMDA0LDIwMDUgSm9oYW5uZXMgRS4gU2NoaW5kZWxpbgogKgogKiBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYSBjb3B5CiAqIG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlICJTb2Z0d2FyZSIpLCB0byBkZWFsCiAqIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHMKICogdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLCBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLCBhbmQvb3Igc2VsbAogKiBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXMKICogZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczoKICoKICogVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWQgaW4KICogYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuCiAqCiAqIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCAiQVMgSVMiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTIE9SCiAqIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZLAogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTiBOTyBFVkVOVCBTSEFMTAogKiBUSEUgQVVUSE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSwgREFNQUdFUyBPUiBPVEhFUgogKiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQU4gQUNUSU9OIE9GIENPTlRSQUNULCBUT1JUIE9SIE9USEVSV0lTRSwgQVJJU0lORyBGUk9NLAogKiBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEUgVVNFIE9SIE9USEVSIERFQUxJTkdTIElOCiAqIFRIRSBTT0ZUV0FSRS4KICovCiNpbmNsdWRlIDxzeXMvc3RhdC5oPgojaW5jbHVkZSA8ZGlyZW50Lmg+CiNpbmNsdWRlIDxhc3NlcnQuaD4KI2luY2x1ZGUgInFlbXUtY29tbW9uLmgiCiNpbmNsdWRlICJibG9ja19pbnQuaCIKCiNpZm5kZWYgU19JV0dSUAojZGVmaW5lIFNfSVdHUlAgMAojZW5kaWYKI2lmbmRlZiBTX0lXT1RICiNkZWZpbmUgU19JV09USCAwCiNlbmRpZgoKLyogVE9ETzogYWRkICI6Ym9vdHNlY3Rvcj1ibGFibGEuaW1nOiIgKi8KLyogTEFURVIgVE9ETzogYWRkIGF1dG9tYXRpYyBib290IHNlY3RvciBnZW5lcmF0aW9uIGZyb20KICAgIEJPT1RFQVNZLkFTTSBhbmQgUmFuaXNoIFBhcnRpdGlvbiBNYW5hZ2VyCiAgICBOb3RlIHRoYXQgRE9TIGFzc3VtZXMgdGhlIHN5c3RlbSBmaWxlcyB0byBiZSB0aGUgZmlyc3QgZmlsZXMgaW4gdGhlCiAgICBmaWxlIHN5c3RlbSAodGVzdCBpZiB0aGUgYm9vdCBzZWN0b3Igc3RpbGwgcmVsaWVzIG9uIHRoYXQgZmFjdCkhICovCi8qIE1BWUJFIFRPRE86IHdyaXRlIGJsb2NrLXZpc29mcy5jICovCi8qIFRPRE86IGNhbGwgdHJ5X2NvbW1pdCgpIG9ubHkgYWZ0ZXIgYSB0aW1lb3V0ICovCgovKiAjZGVmaW5lIERFQlVHICovCgojaWZkZWYgREVCVUcKCiNkZWZpbmUgRExPRyhhKSBhCgojdW5kZWYgc3RkZXJyCiNkZWZpbmUgc3RkZXJyIFNUREVSUgpGSUxFKiBzdGRlcnIgPSBOVUxMOwoKc3RhdGljIHZvaWQgY2hlY2twb2ludCgpOwoKI2lmZGVmIF9fTUlOR1czMl9fCnZvaWQgbm9ub25vKGNvbnN0IGNoYXIqIGZpbGUsIGludCBsaW5lLCBjb25zdCBjaGFyKiBtc2cpIHsKICAgIGZwcmludGYoc3RkZXJyLCAiTm9ub25vISAlczolZCAlc1xuIiwgZmlsZSwgbGluZSwgbXNnKTsKICAgIGV4aXQoLTUpOwp9CiN1bmRlZiBhc3NlcnQKI2RlZmluZSBhc3NlcnQoYSkgZG8ge2lmICghKGEpKSBub25vbm8oX19GSUxFX18sIF9fTElORV9fLCAjYSk7fXdoaWxlKDApCiNlbmRpZgoKI2Vsc2UKCiNkZWZpbmUgRExPRyhhKQoKI2VuZGlmCgovKiBkeW5hbWljIGFycmF5IGZ1bmN0aW9ucyAqLwp0eXBlZGVmIHN0cnVjdCBhcnJheV90IHsKICAgIGNoYXIqIHBvaW50ZXI7CiAgICB1bnNpZ25lZCBpbnQgc2l6ZSxuZXh0LGl0ZW1fc2l6ZTsKfSBhcnJheV90OwoKc3RhdGljIGlubGluZSB2b2lkIGFycmF5X2luaXQoYXJyYXlfdCogYXJyYXksdW5zaWduZWQgaW50IGl0ZW1fc2l6ZSkKewogICAgYXJyYXktPnBvaW50ZXI9MDsKICAgIGFycmF5LT5zaXplPTA7CiAgICBhcnJheS0+bmV4dD0wOwogICAgYXJyYXktPml0ZW1fc2l6ZT1pdGVtX3NpemU7Cn0KCnN0YXRpYyBpbmxpbmUgdm9pZCBhcnJheV9mcmVlKGFycmF5X3QqIGFycmF5KQp7CiAgICBpZihhcnJheS0+cG9pbnRlcikKICAgICAgICBmcmVlKGFycmF5LT5wb2ludGVyKTsKICAgIGFycmF5LT5zaXplPWFycmF5LT5uZXh0PTA7Cn0KCi8qIGRvZXMgbm90IGF1dG9tYXRpY2FsbHkgZ3JvdyAqLwpzdGF0aWMgaW5saW5lIHZvaWQqIGFycmF5X2dldChhcnJheV90KiBhcnJheSx1bnNpZ25lZCBpbnQgaW5kZXgpIHsKICAgIGFzc2VydChpbmRleCA+PSAwKTsKICAgIGFzc2VydChpbmRleCA8IGFycmF5LT5uZXh0KTsKICAgIHJldHVybiBhcnJheS0+cG9pbnRlciArIGluZGV4ICogYXJyYXktPml0ZW1fc2l6ZTsKfQoKc3RhdGljIGlubGluZSBpbnQgYXJyYXlfZW5zdXJlX2FsbG9jYXRlZChhcnJheV90KiBhcnJheSwgaW50IGluZGV4KQp7CiAgICBpZigoaW5kZXggKyAxKSAqIGFycmF5LT5pdGVtX3NpemUgPiBhcnJheS0+c2l6ZSkgewoJaW50IG5ld19zaXplID0gKGluZGV4ICsgMzIpICogYXJyYXktPml0ZW1fc2l6ZTsKCWFycmF5LT5wb2ludGVyID0gcmVhbGxvYyhhcnJheS0+cG9pbnRlciwgbmV3X3NpemUpOwoJaWYgKCFhcnJheS0+cG9pbnRlcikKCSAgICByZXR1cm4gLTE7CglhcnJheS0+c2l6ZSA9IG5ld19zaXplOwoJYXJyYXktPm5leHQgPSBpbmRleCArIDE7CiAgICB9CgogICAgcmV0dXJuIDA7Cn0KCnN0YXRpYyBpbmxpbmUgdm9pZCogYXJyYXlfZ2V0X25leHQoYXJyYXlfdCogYXJyYXkpIHsKICAgIHVuc2lnbmVkIGludCBuZXh0ID0gYXJyYXktPm5leHQ7CiAgICB2b2lkKiByZXN1bHQ7CgogICAgaWYgKGFycmF5X2Vuc3VyZV9hbGxvY2F0ZWQoYXJyYXksIG5leHQpIDwgMCkKCXJldHVybiBOVUxMOwoKICAgIGFycmF5LT5uZXh0ID0gbmV4dCArIDE7CiAgICByZXN1bHQgPSBhcnJheV9nZXQoYXJyYXksIG5leHQpOwoKICAgIHJldHVybiByZXN1bHQ7Cn0KCnN0YXRpYyBpbmxpbmUgdm9pZCogYXJyYXlfaW5zZXJ0KGFycmF5X3QqIGFycmF5LHVuc2lnbmVkIGludCBpbmRleCx1bnNpZ25lZCBpbnQgY291bnQpIHsKICAgIGlmKChhcnJheS0+bmV4dCtjb3VudCkqYXJyYXktPml0ZW1fc2l6ZT5hcnJheS0+c2l6ZSkgewoJaW50IGluY3JlbWVudD1jb3VudCphcnJheS0+aXRlbV9zaXplOwoJYXJyYXktPnBvaW50ZXI9cmVhbGxvYyhhcnJheS0+cG9pbnRlcixhcnJheS0+c2l6ZStpbmNyZW1lbnQpOwoJaWYoIWFycmF5LT5wb2ludGVyKQoJICAgIHJldHVybiAwOwoJYXJyYXktPnNpemUrPWluY3JlbWVudDsKICAgIH0KICAgIG1lbW1vdmUoYXJyYXktPnBvaW50ZXIrKGluZGV4K2NvdW50KSphcnJheS0+aXRlbV9zaXplLAoJCWFycmF5LT5wb2ludGVyK2luZGV4KmFycmF5LT5pdGVtX3NpemUsCgkJKGFycmF5LT5uZXh0LWluZGV4KSphcnJheS0+aXRlbV9zaXplKTsKICAgIGFycmF5LT5uZXh0Kz1jb3VudDsKICAgIHJldHVybiBhcnJheS0+cG9pbnRlcitpbmRleCphcnJheS0+aXRlbV9zaXplOwp9CgovKiB0aGlzIHBlcmZvcm1zIGEgInJvbGwiLCBzbyB0aGF0IHRoZSBlbGVtZW50IHdoaWNoIHdhcyBhdCBpbmRleF9mcm9tIGJlY29tZXMKICogaW5kZXhfdG8sIGJ1dCB0aGUgb3JkZXIgb2YgYWxsIG90aGVyIGVsZW1lbnRzIGlzIHByZXNlcnZlZC4gKi8Kc3RhdGljIGlubGluZSBpbnQgYXJyYXlfcm9sbChhcnJheV90KiBhcnJheSxpbnQgaW5kZXhfdG8saW50IGluZGV4X2Zyb20saW50IGNvdW50KQp7CiAgICBjaGFyKiBidWY7CiAgICBjaGFyKiBmcm9tOwogICAgY2hhciogdG87CiAgICBpbnQgaXM7CgogICAgaWYoIWFycmF5IHx8CgkgICAgaW5kZXhfdG88MCB8fCBpbmRleF90bz49YXJyYXktPm5leHQgfHwKCSAgICBpbmRleF9mcm9tPDAgfHwgaW5kZXhfZnJvbT49YXJyYXktPm5leHQpCglyZXR1cm4gLTE7CgogICAgaWYoaW5kZXhfdG89PWluZGV4X2Zyb20pCglyZXR1cm4gMDsKCiAgICBpcz1hcnJheS0+aXRlbV9zaXplOwogICAgZnJvbT1hcnJheS0+cG9pbnRlcitpbmRleF9mcm9tKmlzOwogICAgdG89YXJyYXktPnBvaW50ZXIraW5kZXhfdG8qaXM7CiAgICBidWY9bWFsbG9jKGlzKmNvdW50KTsKICAgIG1lbWNweShidWYsZnJvbSxpcypjb3VudCk7CgogICAgaWYoaW5kZXhfdG88aW5kZXhfZnJvbSkKCW1lbW1vdmUodG8raXMqY291bnQsdG8sZnJvbS10byk7CiAgICBlbHNlCgltZW1tb3ZlKGZyb20sZnJvbStpcypjb3VudCx0by1mcm9tKTsKCiAgICBtZW1jcHkodG8sYnVmLGlzKmNvdW50KTsKCiAgICBmcmVlKGJ1Zik7CgogICAgcmV0dXJuIDA7Cn0KCnN0YXRpYyBpbmxpbmUgaW50IGFycmF5X3JlbW92ZV9zbGljZShhcnJheV90KiBhcnJheSxpbnQgaW5kZXgsIGludCBjb3VudCkKewogICAgYXNzZXJ0KGluZGV4ID49MCk7CiAgICBhc3NlcnQoY291bnQgPiAwKTsKICAgIGFzc2VydChpbmRleCArIGNvdW50IDw9IGFycmF5LT5uZXh0KTsKICAgIGlmKGFycmF5X3JvbGwoYXJyYXksYXJyYXktPm5leHQtMSxpbmRleCxjb3VudCkpCglyZXR1cm4gLTE7CiAgICBhcnJheS0+bmV4dCAtPSBjb3VudDsKICAgIHJldHVybiAwOwp9CgpzdGF0aWMgaW50IGFycmF5X3JlbW92ZShhcnJheV90KiBhcnJheSxpbnQgaW5kZXgpCnsKICAgIHJldHVybiBhcnJheV9yZW1vdmVfc2xpY2UoYXJyYXksIGluZGV4LCAxKTsKfQoKLyogcmV0dXJuIHRoZSBpbmRleCBmb3IgYSBnaXZlbiBtZW1iZXIgKi8Kc3RhdGljIGludCBhcnJheV9pbmRleChhcnJheV90KiBhcnJheSwgdm9pZCogcG9pbnRlcikKewogICAgc2l6ZV90IG9mZnNldCA9IChjaGFyKilwb2ludGVyIC0gYXJyYXktPnBvaW50ZXI7CiAgICBhc3NlcnQob2Zmc2V0ID49IDApOwogICAgYXNzZXJ0KChvZmZzZXQgJSBhcnJheS0+aXRlbV9zaXplKSA9PSAwKTsKICAgIGFzc2VydChvZmZzZXQvYXJyYXktPml0ZW1fc2l6ZSA8IGFycmF5LT5uZXh0KTsKICAgIHJldHVybiBvZmZzZXQvYXJyYXktPml0ZW1fc2l6ZTsKfQoKLyogVGhlc2Ugc3RydWN0dXJlcyBhcmUgdXNlZCB0byBmYWtlIGEgZGlzayBhbmQgdGhlIFZGQVQgZmlsZXN5c3RlbS4KICogRm9yIHRoaXMgcmVhc29uIHdlIG5lZWQgdG8gdXNlIF9fYXR0cmlidXRlX18oKHBhY2tlZCkpLiAqLwoKdHlwZWRlZiBzdHJ1Y3QgYm9vdHNlY3Rvcl90IHsKICAgIHVpbnQ4X3QganVtcFszXTsKICAgIHVpbnQ4X3QgbmFtZVs4XTsKICAgIHVpbnQxNl90IHNlY3Rvcl9zaXplOwogICAgdWludDhfdCBzZWN0b3JzX3Blcl9jbHVzdGVyOwogICAgdWludDE2X3QgcmVzZXJ2ZWRfc2VjdG9yczsKICAgIHVpbnQ4X3QgbnVtYmVyX29mX2ZhdHM7CiAgICB1aW50MTZfdCByb290X2VudHJpZXM7CiAgICB1aW50MTZfdCB0b3RhbF9zZWN0b3JzMTY7CiAgICB1aW50OF90IG1lZGlhX3R5cGU7CiAgICB1aW50MTZfdCBzZWN0b3JzX3Blcl9mYXQ7CiAgICB1aW50MTZfdCBzZWN0b3JzX3Blcl90cmFjazsKICAgIHVpbnQxNl90IG51bWJlcl9vZl9oZWFkczsKICAgIHVpbnQzMl90IGhpZGRlbl9zZWN0b3JzOwogICAgdWludDMyX3QgdG90YWxfc2VjdG9yczsKICAgIHVuaW9uIHsKICAgICAgICBzdHJ1Y3QgewoJICAgIHVpbnQ4X3QgZHJpdmVfbnVtYmVyOwoJICAgIHVpbnQ4X3QgY3VycmVudF9oZWFkOwoJICAgIHVpbnQ4X3Qgc2lnbmF0dXJlOwoJICAgIHVpbnQzMl90IGlkOwoJICAgIHVpbnQ4X3Qgdm9sdW1lX2xhYmVsWzExXTsKCX0gX19hdHRyaWJ1dGVfXygocGFja2VkKSkgZmF0MTY7CglzdHJ1Y3QgewoJICAgIHVpbnQzMl90IHNlY3RvcnNfcGVyX2ZhdDsKCSAgICB1aW50MTZfdCBmbGFnczsKCSAgICB1aW50OF90IG1ham9yLG1pbm9yOwoJICAgIHVpbnQzMl90IGZpcnN0X2NsdXN0ZXJfb2Zfcm9vdF9kaXJlY3Rvcnk7CgkgICAgdWludDE2X3QgaW5mb19zZWN0b3I7CgkgICAgdWludDE2X3QgYmFja3VwX2Jvb3Rfc2VjdG9yOwoJICAgIHVpbnQxNl90IGlnbm9yZWQ7Cgl9IF9fYXR0cmlidXRlX18oKHBhY2tlZCkpIGZhdDMyOwogICAgfSB1OwogICAgdWludDhfdCBmYXRfdHlwZVs4XTsKICAgIHVpbnQ4X3QgaWdub3JlZFsweDFjMF07CiAgICB1aW50OF90IG1hZ2ljWzJdOwp9IF9fYXR0cmlidXRlX18oKHBhY2tlZCkpIGJvb3RzZWN0b3JfdDsKCnR5cGVkZWYgc3RydWN0IHsKICAgIHVpbnQ4X3QgaGVhZDsKICAgIHVpbnQ4X3Qgc2VjdG9yOwogICAgdWludDhfdCBjeWxpbmRlcjsKfSBtYnJfY2hzX3Q7Cgp0eXBlZGVmIHN0cnVjdCBwYXJ0aXRpb25fdCB7CiAgICB1aW50OF90IGF0dHJpYnV0ZXM7IC8qIDB4ODAgPSBib290YWJsZSAqLwogICAgbWJyX2Noc190IHN0YXJ0X0NIUzsKICAgIHVpbnQ4X3QgICBmc190eXBlOyAvKiAweDEgPSBGQVQxMiwgMHg2ID0gRkFUMTYsIDB4ZSA9IEZBVDE2X0xCQSwgMHhiID0gRkFUMzIsIDB4YyA9IEZBVDMyX0xCQSAqLwogICAgbWJyX2Noc190IGVuZF9DSFM7CiAgICB1aW50MzJfdCBzdGFydF9zZWN0b3JfbG9uZzsKICAgIHVpbnQzMl90IGxlbmd0aF9zZWN0b3JfbG9uZzsKfSBfX2F0dHJpYnV0ZV9fKChwYWNrZWQpKSBwYXJ0aXRpb25fdDsKCnR5cGVkZWYgc3RydWN0IG1icl90IHsKICAgIHVpbnQ4X3QgaWdub3JlZFsweDFiOF07CiAgICB1aW50MzJfdCBudF9pZDsKICAgIHVpbnQ4X3QgaWdub3JlZDJbMl07CiAgICBwYXJ0aXRpb25fdCBwYXJ0aXRpb25bNF07CiAgICB1aW50OF90IG1hZ2ljWzJdOwp9IF9fYXR0cmlidXRlX18oKHBhY2tlZCkpIG1icl90OwoKdHlwZWRlZiBzdHJ1Y3QgZGlyZW50cnlfdCB7CiAgICB1aW50OF90IG5hbWVbOF07CiAgICB1aW50OF90IGV4dGVuc2lvblszXTsKICAgIHVpbnQ4X3QgYXR0cmlidXRlczsKICAgIHVpbnQ4X3QgcmVzZXJ2ZWRbMl07CiAgICB1aW50MTZfdCBjdGltZTsKICAgIHVpbnQxNl90IGNkYXRlOwogICAgdWludDE2X3QgYWRhdGU7CiAgICB1aW50MTZfdCBiZWdpbl9oaTsKICAgIHVpbnQxNl90IG10aW1lOwogICAgdWludDE2X3QgbWRhdGU7CiAgICB1aW50MTZfdCBiZWdpbjsKICAgIHVpbnQzMl90IHNpemU7Cn0gX19hdHRyaWJ1dGVfXygocGFja2VkKSkgZGlyZW50cnlfdDsKCi8qIHRoaXMgc3RydWN0dXJlIGFyZSB1c2VkIHRvIHRyYW5zcGFyZW50bHkgYWNjZXNzIHRoZSBmaWxlcyAqLwoKdHlwZWRlZiBzdHJ1Y3QgbWFwcGluZ190IHsKICAgIC8qIGJlZ2luIGlzIHRoZSBmaXJzdCBjbHVzdGVyLCBlbmQgaXMgdGhlIGxhc3QrMSAqLwogICAgdWludDMyX3QgYmVnaW4sZW5kOwogICAgLyogYXMgcy0+ZGlyZWN0b3J5IGlzIGdyb3dhYmxlLCBubyBwb2ludGVyIG1heSBiZSB1c2VkIGhlcmUgKi8KICAgIHVuc2lnbmVkIGludCBkaXJfaW5kZXg7CiAgICAvKiB0aGUgY2x1c3RlcnMgb2YgYSBmaWxlIG1heSBiZSBpbiBhbnkgb3JkZXI7IHRoaXMgcG9pbnRzIHRvIHRoZSBmaXJzdCAqLwogICAgaW50IGZpcnN0X21hcHBpbmdfaW5kZXg7CiAgICB1bmlvbiB7CgkvKiBvZmZzZXQgaXMKCSAqIC0gdGhlIG9mZnNldCBpbiB0aGUgZmlsZSAoaW4gY2x1c3RlcnMpIGZvciBhIGZpbGUsIG9yCgkgKiAtIHRoZSBuZXh0IGNsdXN0ZXIgb2YgdGhlIGRpcmVjdG9yeSBmb3IgYSBkaXJlY3RvcnksIGFuZAoJICogLSB0aGUgYWRkcmVzcyBvZiB0aGUgYnVmZmVyIGZvciBhIGZha2VkIGVudHJ5CgkgKi8KCXN0cnVjdCB7CgkgICAgdWludDMyX3Qgb2Zmc2V0OwoJfSBmaWxlOwoJc3RydWN0IHsKCSAgICBpbnQgcGFyZW50X21hcHBpbmdfaW5kZXg7CgkgICAgaW50IGZpcnN0X2Rpcl9pbmRleDsKCX0gZGlyOwogICAgfSBpbmZvOwogICAgLyogcGF0aCBjb250YWlucyB0aGUgZnVsbCBwYXRoLCBpLmUuIGl0IGFsd2F5cyBzdGFydHMgd2l0aCBzLT5wYXRoICovCiAgICBjaGFyKiBwYXRoOwoKICAgIGVudW0geyBNT0RFX1VOREVGSU5FRCA9IDAsIE1PREVfTk9STUFMID0gMSwgTU9ERV9NT0RJRklFRCA9IDIsCglNT0RFX0RJUkVDVE9SWSA9IDQsIE1PREVfRkFLRUQgPSA4LAoJTU9ERV9ERUxFVEVEID0gMTYsIE1PREVfUkVOQU1FRCA9IDMyIH0gbW9kZTsKICAgIGludCByZWFkX29ubHk7Cn0gbWFwcGluZ190OwoKI2lmZGVmIERFQlVHCnN0YXRpYyB2b2lkIHByaW50X2RpcmVudHJ5KGNvbnN0IHN0cnVjdCBkaXJlbnRyeV90Kik7CnN0YXRpYyB2b2lkIHByaW50X21hcHBpbmcoY29uc3Qgc3RydWN0IG1hcHBpbmdfdCogbWFwcGluZyk7CiNlbmRpZgoKLyogaGVyZSBiZWdpbnMgdGhlIHJlYWwgVlZGQVQgZHJpdmVyICovCgp0eXBlZGVmIHN0cnVjdCBCRFJWVlZGQVRTdGF0ZSB7CiAgICBCbG9ja0RyaXZlclN0YXRlKiBiczsgLyogcG9pbnRlciB0byBwYXJlbnQgKi8KICAgIHVuc2lnbmVkIGludCBmaXJzdF9zZWN0b3JzX251bWJlcjsgLyogMSBmb3IgYSBzaW5nbGUgcGFydGl0aW9uLCAweDQwIGZvciBhIGRpc2sgd2l0aCBwYXJ0aXRpb24gdGFibGUgKi8KICAgIHVuc2lnbmVkIGNoYXIgZmlyc3Rfc2VjdG9yc1sweDQwKjB4MjAwXTsKCiAgICBpbnQgZmF0X3R5cGU7IC8qIDE2IG9yIDMyICovCiAgICBhcnJheV90IGZhdCxkaXJlY3RvcnksbWFwcGluZzsKCiAgICB1bnNpZ25lZCBpbnQgY2x1c3Rlcl9zaXplOwogICAgdW5zaWduZWQgaW50IHNlY3RvcnNfcGVyX2NsdXN0ZXI7CiAgICB1bnNpZ25lZCBpbnQgc2VjdG9yc19wZXJfZmF0OwogICAgdW5zaWduZWQgaW50IHNlY3RvcnNfb2Zfcm9vdF9kaXJlY3Rvcnk7CiAgICB1aW50MzJfdCBsYXN0X2NsdXN0ZXJfb2Zfcm9vdF9kaXJlY3Rvcnk7CiAgICB1bnNpZ25lZCBpbnQgZmFrZWRfc2VjdG9yczsgLyogaG93IG1hbnkgc2VjdG9ycyBhcmUgZmFrZWQgYmVmb3JlIGZpbGUgZGF0YSAqLwogICAgdWludDMyX3Qgc2VjdG9yX2NvdW50OyAvKiB0b3RhbCBudW1iZXIgb2Ygc2VjdG9ycyBvZiB0aGUgcGFydGl0aW9uICovCiAgICB1aW50MzJfdCBjbHVzdGVyX2NvdW50OyAvKiB0b3RhbCBudW1iZXIgb2YgY2x1c3RlcnMgb2YgdGhpcyBwYXJ0aXRpb24gKi8KICAgIHVpbnQzMl90IG1heF9mYXRfdmFsdWU7CgogICAgaW50IGN1cnJlbnRfZmQ7CiAgICBtYXBwaW5nX3QqIGN1cnJlbnRfbWFwcGluZzsKICAgIHVuc2lnbmVkIGNoYXIqIGNsdXN0ZXI7IC8qIHBvaW50cyB0byBjdXJyZW50IGNsdXN0ZXIgKi8KICAgIHVuc2lnbmVkIGNoYXIqIGNsdXN0ZXJfYnVmZmVyOyAvKiBwb2ludHMgdG8gYSBidWZmZXIgdG8gaG9sZCB0ZW1wIGRhdGEgKi8KICAgIHVuc2lnbmVkIGludCBjdXJyZW50X2NsdXN0ZXI7CgogICAgLyogd3JpdGUgc3VwcG9ydCAqLwogICAgQmxvY2tEcml2ZXJTdGF0ZSogd3JpdGVfdGFyZ2V0OwogICAgY2hhciogcWNvd19maWxlbmFtZTsKICAgIEJsb2NrRHJpdmVyU3RhdGUqIHFjb3c7CiAgICB2b2lkKiBmYXQyOwogICAgY2hhciogdXNlZF9jbHVzdGVyczsKICAgIGFycmF5X3QgY29tbWl0czsKICAgIGNvbnN0IGNoYXIqIHBhdGg7CiAgICBpbnQgZG93bmNhc2Vfc2hvcnRfbmFtZXM7Cn0gQkRSVlZWRkFUU3RhdGU7CgovKiB0YWtlIHRoZSBzZWN0b3IgcG9zaXRpb24gc3BvcyBhbmQgY29udmVydCBpdCB0byBDeWxpbmRlci9IZWFkL1NlY3RvciBwb3NpdGlvbgogKiBpZiB0aGUgcG9zaXRpb24gaXMgb3V0c2lkZSB0aGUgc3BlY2lmaWVkIGdlb21ldHJ5LCBmaWxsIG1heGltdW0gdmFsdWUgZm9yIENIUwogKiBhbmQgcmV0dXJuIDEgdG8gc2lnbmFsIG92ZXJmbG93LgogKi8Kc3RhdGljIGludCBzZWN0b3IyQ0hTKEJsb2NrRHJpdmVyU3RhdGUqIGJzLCBtYnJfY2hzX3QgKiBjaHMsIGludCBzcG9zKXsKICAgIGludCBoZWFkLHNlY3RvcjsKICAgIHNlY3RvciAgID0gc3BvcyAlIChicy0+c2Vjcyk7ICBzcG9zLz0gYnMtPnNlY3M7CiAgICBoZWFkICAgICA9IHNwb3MgJSAoYnMtPmhlYWRzKTsgc3Bvcy89IGJzLT5oZWFkczsKICAgIGlmKHNwb3MgPj0gYnMtPmN5bHMpewogICAgICAgIC8qIE92ZXJmbG93LAogICAgICAgIGl0IGhhcHBlbnMgaWYgMzJiaXQgc2VjdG9yIHBvc2l0aW9ucyBhcmUgdXNlZCwgd2hpbGUgQ0hTIGlzIG9ubHkgMjRiaXQuCiAgICAgICAgV2luZG93cy9Eb3MgaXMgc2FpZCB0byB0YWtlIDEwMjMvMjU1LzYzIGFzIG5vbnJlcHJlc2VudGFibGUgQ0hTICovCiAgICAgICAgY2hzLT5oZWFkICAgICA9IDB4RkY7CiAgICAgICAgY2hzLT5zZWN0b3IgICA9IDB4RkY7CiAgICAgICAgY2hzLT5jeWxpbmRlciA9IDB4RkY7CiAgICAgICAgcmV0dXJuIDE7CiAgICB9CiAgICBjaHMtPmhlYWQgICAgID0gKHVpbnQ4X3QpaGVhZDsKICAgIGNocy0+c2VjdG9yICAgPSAodWludDhfdCkoIChzZWN0b3IrMSkgfCAoKHNwb3M+PjgpPDw2KSApOwogICAgY2hzLT5jeWxpbmRlciA9ICh1aW50OF90KXNwb3M7CiAgICByZXR1cm4gMDsKfQoKc3RhdGljIHZvaWQgaW5pdF9tYnIoQkRSVlZWRkFUU3RhdGUqIHMpCnsKICAgIC8qIFRPRE86IGlmIHRoZSBmaWxlcyBtYnIuaW1nIGFuZCBib290c2VjdC5pbWcgZXhpc3QsIHVzZSB0aGVtICovCiAgICBtYnJfdCogcmVhbF9tYnI9KG1icl90KilzLT5maXJzdF9zZWN0b3JzOwogICAgcGFydGl0aW9uX3QqIHBhcnRpdGlvbj0mKHJlYWxfbWJyLT5wYXJ0aXRpb25bMF0pOwogICAgaW50IGxiYTsKCiAgICBtZW1zZXQocy0+Zmlyc3Rfc2VjdG9ycywwLDUxMik7CgogICAgLyogV2luIE5UIERpc2sgU2lnbmF0dXJlICovCiAgICByZWFsX21ici0+bnRfaWQ9IGNwdV90b19sZTMyKDB4YmUxYWZkZmEpOwoKICAgIHBhcnRpdGlvbi0+YXR0cmlidXRlcz0weDgwOyAvKiBib290YWJsZSAqLwoKICAgIC8qIExCQSBpcyB1c2VkIHdoZW4gcGFydGl0aW9uIGlzIG91dHNpZGUgdGhlIENIUyBnZW9tZXRyeSAqLwogICAgbGJhID0gc2VjdG9yMkNIUyhzLT5icywgJnBhcnRpdGlvbi0+c3RhcnRfQ0hTLCBzLT5maXJzdF9zZWN0b3JzX251bWJlci0xKTsKICAgIGxiYXw9IHNlY3RvcjJDSFMocy0+YnMsICZwYXJ0aXRpb24tPmVuZF9DSFMsICAgcy0+c2VjdG9yX2NvdW50KTsKCiAgICAvKkxCQSBwYXJ0aXRpb25zIGFyZSBpZGVudGlmaWVkIG9ubHkgYnkgc3RhcnQvbGVuZ3RoX3NlY3Rvcl9sb25nIG5vdCBieSBDSFMqLwogICAgcGFydGl0aW9uLT5zdGFydF9zZWN0b3JfbG9uZyA9Y3B1X3RvX2xlMzIocy0+Zmlyc3Rfc2VjdG9yc19udW1iZXItMSk7CiAgICBwYXJ0aXRpb24tPmxlbmd0aF9zZWN0b3JfbG9uZz1jcHVfdG9fbGUzMihzLT5zZWN0b3JfY291bnQgLSBzLT5maXJzdF9zZWN0b3JzX251bWJlcisxKTsKCiAgICAvKiBGQVQxMi9GQVQxNi9GQVQzMiAqLwogICAgLyogRE9TIHVzZXMgZGlmZmVyZW50IHR5cGVzIHdoZW4gcGFydGl0aW9uIGlzIExCQSwKICAgICAgIHByb2JhYmx5IHRvIHByZXZlbnQgb2xkZXIgdmVyc2lvbnMgZnJvbSB1c2luZyBDSFMgb24gdGhlbSAqLwogICAgcGFydGl0aW9uLT5mc190eXBlPSBzLT5mYXRfdHlwZT09MTIgPyAweDE6CiAgICAgICAgICAgICAgICAgICAgICAgIHMtPmZhdF90eXBlPT0xNiA/IChsYmE/MHhlOjB4MDYpOgogICAgICAgICAgICAgICAgICAgICAgICAgLypmYXRfdHlvZT09MzIqLyAobGJhPzB4YzoweDBiKTsKCiAgICByZWFsX21ici0+bWFnaWNbMF09MHg1NTsgcmVhbF9tYnItPm1hZ2ljWzFdPTB4YWE7Cn0KCi8qIGRpcmVudHJ5IGZ1bmN0aW9ucyAqLwoKLyogZGVzdCBpcyBhc3N1bWVkIHRvIGhvbGQgMjU4IGJ5dGVzLCBhbmQgcGFkcyB3aXRoIDB4ZmZmZiB1cCB0byBuZXh0IG11bHRpcGxlIG9mIDI2ICovCnN0YXRpYyBpbmxpbmUgaW50IHNob3J0MmxvbmdfbmFtZShjaGFyKiBkZXN0LGNvbnN0IGNoYXIqIHNyYykKewogICAgaW50IGk7CiAgICBpbnQgbGVuOwogICAgZm9yKGk9MDtpPDEyOSAmJiBzcmNbaV07aSsrKSB7CiAgICAgICAgZGVzdFsyKmldPXNyY1tpXTsKCWRlc3RbMippKzFdPTA7CiAgICB9CiAgICBsZW49MippOwogICAgZGVzdFsyKmldPWRlc3RbMippKzFdPTA7CiAgICBmb3IoaT0yKmkrMjsoaSUyNik7aSsrKQoJZGVzdFtpXT0weGZmOwogICAgcmV0dXJuIGxlbjsKfQoKc3RhdGljIGlubGluZSBkaXJlbnRyeV90KiBjcmVhdGVfbG9uZ19maWxlbmFtZShCRFJWVlZGQVRTdGF0ZSogcyxjb25zdCBjaGFyKiBmaWxlbmFtZSkKewogICAgY2hhciBidWZmZXJbMjU4XTsKICAgIGludCBsZW5ndGg9c2hvcnQybG9uZ19uYW1lKGJ1ZmZlcixmaWxlbmFtZSksCiAgICAgICAgbnVtYmVyX29mX2VudHJpZXM9KGxlbmd0aCsyNSkvMjYsaTsKICAgIGRpcmVudHJ5X3QqIGVudHJ5OwoKICAgIGZvcihpPTA7aTxudW1iZXJfb2ZfZW50cmllcztpKyspIHsKCWVudHJ5PWFycmF5X2dldF9uZXh0KCYocy0+ZGlyZWN0b3J5KSk7CgllbnRyeS0+YXR0cmlidXRlcz0weGY7CgllbnRyeS0+cmVzZXJ2ZWRbMF09MDsKCWVudHJ5LT5iZWdpbj0wOwoJZW50cnktPm5hbWVbMF09KG51bWJlcl9vZl9lbnRyaWVzLWkpfChpPT0wPzB4NDA6MCk7CiAgICB9CiAgICBmb3IoaT0wO2k8MjYqbnVtYmVyX29mX2VudHJpZXM7aSsrKSB7CglpbnQgb2Zmc2V0PShpJTI2KTsKCWlmKG9mZnNldDwxMCkgb2Zmc2V0PTErb2Zmc2V0OwoJZWxzZSBpZihvZmZzZXQ8MjIpIG9mZnNldD0xNCtvZmZzZXQtMTA7CgllbHNlIG9mZnNldD0yOCtvZmZzZXQtMjI7CgllbnRyeT1hcnJheV9nZXQoJihzLT5kaXJlY3RvcnkpLHMtPmRpcmVjdG9yeS5uZXh0LTEtKGkvMjYpKTsKCWVudHJ5LT5uYW1lW29mZnNldF09YnVmZmVyW2ldOwogICAgfQogICAgcmV0dXJuIGFycmF5X2dldCgmKHMtPmRpcmVjdG9yeSkscy0+ZGlyZWN0b3J5Lm5leHQtbnVtYmVyX29mX2VudHJpZXMpOwp9CgpzdGF0aWMgY2hhciBpc19mcmVlKGNvbnN0IGRpcmVudHJ5X3QqIGRpcmVudHJ5KQp7CiAgICAvKiByZXR1cm4gZGlyZW50cnktPm5hbWVbMF09PTAgOyAqLwogICAgcmV0dXJuIGRpcmVudHJ5LT5hdHRyaWJ1dGVzID09IDAgfHwgZGlyZW50cnktPm5hbWVbMF09PTB4ZTU7Cn0KCnN0YXRpYyBjaGFyIGlzX3ZvbHVtZV9sYWJlbChjb25zdCBkaXJlbnRyeV90KiBkaXJlbnRyeSkKewogICAgcmV0dXJuIGRpcmVudHJ5LT5hdHRyaWJ1dGVzID09IDB4Mjg7Cn0KCnN0YXRpYyBjaGFyIGlzX2xvbmdfbmFtZShjb25zdCBkaXJlbnRyeV90KiBkaXJlbnRyeSkKewogICAgcmV0dXJuIGRpcmVudHJ5LT5hdHRyaWJ1dGVzID09IDB4ZjsKfQoKc3RhdGljIGNoYXIgaXNfc2hvcnRfbmFtZShjb25zdCBkaXJlbnRyeV90KiBkaXJlbnRyeSkKewogICAgcmV0dXJuICFpc192b2x1bWVfbGFiZWwoZGlyZW50cnkpICYmICFpc19sb25nX25hbWUoZGlyZW50cnkpCgkmJiAhaXNfZnJlZShkaXJlbnRyeSk7Cn0KCnN0YXRpYyBjaGFyIGlzX2RpcmVjdG9yeShjb25zdCBkaXJlbnRyeV90KiBkaXJlbnRyeSkKewogICAgcmV0dXJuIGRpcmVudHJ5LT5hdHRyaWJ1dGVzICYgMHgxMCAmJiBkaXJlbnRyeS0+bmFtZVswXSAhPSAweGU1Owp9CgpzdGF0aWMgaW5saW5lIGNoYXIgaXNfZG90KGNvbnN0IGRpcmVudHJ5X3QqIGRpcmVudHJ5KQp7CiAgICByZXR1cm4gaXNfc2hvcnRfbmFtZShkaXJlbnRyeSkgJiYgZGlyZW50cnktPm5hbWVbMF0gPT0gJy4nOwp9CgpzdGF0aWMgY2hhciBpc19maWxlKGNvbnN0IGRpcmVudHJ5X3QqIGRpcmVudHJ5KQp7CiAgICByZXR1cm4gaXNfc2hvcnRfbmFtZShkaXJlbnRyeSkgJiYgIWlzX2RpcmVjdG9yeShkaXJlbnRyeSk7Cn0KCnN0YXRpYyBpbmxpbmUgdWludDMyX3QgYmVnaW5fb2ZfZGlyZW50cnkoY29uc3QgZGlyZW50cnlfdCogZGlyZW50cnkpCnsKICAgIHJldHVybiBsZTE2X3RvX2NwdShkaXJlbnRyeS0+YmVnaW4pfChsZTE2X3RvX2NwdShkaXJlbnRyeS0+YmVnaW5faGkpPDwxNik7Cn0KCnN0YXRpYyBpbmxpbmUgdWludDMyX3QgZmlsZXNpemVfb2ZfZGlyZW50cnkoY29uc3QgZGlyZW50cnlfdCogZGlyZW50cnkpCnsKICAgIHJldHVybiBsZTMyX3RvX2NwdShkaXJlbnRyeS0+c2l6ZSk7Cn0KCnN0YXRpYyB2b2lkIHNldF9iZWdpbl9vZl9kaXJlbnRyeShkaXJlbnRyeV90KiBkaXJlbnRyeSwgdWludDMyX3QgYmVnaW4pCnsKICAgIGRpcmVudHJ5LT5iZWdpbiA9IGNwdV90b19sZTE2KGJlZ2luICYgMHhmZmZmKTsKICAgIGRpcmVudHJ5LT5iZWdpbl9oaSA9IGNwdV90b19sZTE2KChiZWdpbiA+PiAxNikgJiAweGZmZmYpOwp9CgovKiBmYXQgZnVuY3Rpb25zICovCgpzdGF0aWMgaW5saW5lIHVpbnQ4X3QgZmF0X2Noa3N1bShjb25zdCBkaXJlbnRyeV90KiBlbnRyeSkKewogICAgdWludDhfdCBjaGtzdW09MDsKICAgIGludCBpOwoKICAgIGZvcihpPTA7aTwxMTtpKyspCgljaGtzdW09KCgoY2hrc3VtJjB4ZmUpPj4xKXwoKGNoa3N1bSYweDAxKT8weDgwOjApKQoJICAgICsodW5zaWduZWQgY2hhcillbnRyeS0+bmFtZVtpXTsKCiAgICByZXR1cm4gY2hrc3VtOwp9CgovKiBpZiByZXR1cm5fdGltZT09MCwgdGhpcyByZXR1cm5zIHRoZSBmYXRfZGF0ZSwgZWxzZSB0aGUgZmF0X3RpbWUgKi8Kc3RhdGljIHVpbnQxNl90IGZhdF9kYXRldGltZSh0aW1lX3QgdGltZSxpbnQgcmV0dXJuX3RpbWUpIHsKICAgIHN0cnVjdCB0bSogdDsKI2lmZGVmIF9XSU4zMgogICAgdD1sb2NhbHRpbWUoJnRpbWUpOyAvKiB0aGlzIGlzIG5vdCB0aHJlYWQgc2FmZSAqLwojZWxzZQogICAgc3RydWN0IHRtIHQxOwogICAgdD0mdDE7CiAgICBsb2NhbHRpbWVfcigmdGltZSx0KTsKI2VuZGlmCiAgICBpZihyZXR1cm5fdGltZSkKCXJldHVybiBjcHVfdG9fbGUxNigodC0+dG1fc2VjLzIpfCh0LT50bV9taW48PDUpfCh0LT50bV9ob3VyPDwxMSkpOwogICAgcmV0dXJuIGNwdV90b19sZTE2KCh0LT50bV9tZGF5KXwoKHQtPnRtX21vbisxKTw8NSl8KCh0LT50bV95ZWFyLTgwKTw8OSkpOwp9CgpzdGF0aWMgaW5saW5lIHZvaWQgZmF0X3NldChCRFJWVlZGQVRTdGF0ZSogcyx1bnNpZ25lZCBpbnQgY2x1c3Rlcix1aW50MzJfdCB2YWx1ZSkKewogICAgaWYocy0+ZmF0X3R5cGU9PTMyKSB7Cgl1aW50MzJfdCogZW50cnk9YXJyYXlfZ2V0KCYocy0+ZmF0KSxjbHVzdGVyKTsKCSplbnRyeT1jcHVfdG9fbGUzMih2YWx1ZSk7CiAgICB9IGVsc2UgaWYocy0+ZmF0X3R5cGU9PTE2KSB7Cgl1aW50MTZfdCogZW50cnk9YXJyYXlfZ2V0KCYocy0+ZmF0KSxjbHVzdGVyKTsKCSplbnRyeT1jcHVfdG9fbGUxNih2YWx1ZSYweGZmZmYpOwogICAgfSBlbHNlIHsKCWludCBvZmZzZXQgPSAoY2x1c3RlciozLzIpOwoJdW5zaWduZWQgY2hhciogcCA9IGFycmF5X2dldCgmKHMtPmZhdCksIG9mZnNldCk7CiAgICAgICAgc3dpdGNoIChjbHVzdGVyJjEpIHsKCWNhc2UgMDoKCQlwWzBdID0gdmFsdWUmMHhmZjsKCQlwWzFdID0gKHBbMV0mMHhmMCkgfCAoKHZhbHVlPj44KSYweGYpOwoJCWJyZWFrOwoJY2FzZSAxOgoJCXBbMF0gPSAocFswXSYweGYpIHwgKCh2YWx1ZSYweGYpPDw0KTsKCQlwWzFdID0gKHZhbHVlPj40KTsKCQlicmVhazsKCX0KICAgIH0KfQoKc3RhdGljIGlubGluZSB1aW50MzJfdCBmYXRfZ2V0KEJEUlZWVkZBVFN0YXRlKiBzLHVuc2lnbmVkIGludCBjbHVzdGVyKQp7CiAgICBpZihzLT5mYXRfdHlwZT09MzIpIHsKCXVpbnQzMl90KiBlbnRyeT1hcnJheV9nZXQoJihzLT5mYXQpLGNsdXN0ZXIpOwoJcmV0dXJuIGxlMzJfdG9fY3B1KCplbnRyeSk7CiAgICB9IGVsc2UgaWYocy0+ZmF0X3R5cGU9PTE2KSB7Cgl1aW50MTZfdCogZW50cnk9YXJyYXlfZ2V0KCYocy0+ZmF0KSxjbHVzdGVyKTsKCXJldHVybiBsZTE2X3RvX2NwdSgqZW50cnkpOwogICAgfSBlbHNlIHsKCWNvbnN0IHVpbnQ4X3QqIHg9KHVpbnQ4X3QqKShzLT5mYXQucG9pbnRlcikrY2x1c3RlciozLzI7CglyZXR1cm4gKCh4WzBdfCh4WzFdPDw4KSk+PihjbHVzdGVyJjE/NDowKSkmMHgwZmZmOwogICAgfQp9CgpzdGF0aWMgaW5saW5lIGludCBmYXRfZW9mKEJEUlZWVkZBVFN0YXRlKiBzLHVpbnQzMl90IGZhdF9lbnRyeSkKewogICAgaWYoZmF0X2VudHJ5PnMtPm1heF9mYXRfdmFsdWUtOCkKCXJldHVybiAtMTsKICAgIHJldHVybiAwOwp9CgpzdGF0aWMgaW5saW5lIHZvaWQgaW5pdF9mYXQoQkRSVlZWRkFUU3RhdGUqIHMpCnsKICAgIGlmIChzLT5mYXRfdHlwZSA9PSAxMikgewoJYXJyYXlfaW5pdCgmKHMtPmZhdCksMSk7CglhcnJheV9lbnN1cmVfYWxsb2NhdGVkKCYocy0+ZmF0KSwKCQlzLT5zZWN0b3JzX3Blcl9mYXQgKiAweDIwMCAqIDMgLyAyIC0gMSk7CiAgICB9IGVsc2UgewoJYXJyYXlfaW5pdCgmKHMtPmZhdCksKHMtPmZhdF90eXBlPT0zMj80OjIpKTsKCWFycmF5X2Vuc3VyZV9hbGxvY2F0ZWQoJihzLT5mYXQpLAoJCXMtPnNlY3RvcnNfcGVyX2ZhdCAqIDB4MjAwIC8gcy0+ZmF0Lml0ZW1fc2l6ZSAtIDEpOwogICAgfQogICAgbWVtc2V0KHMtPmZhdC5wb2ludGVyLDAscy0+ZmF0LnNpemUpOwoKICAgIHN3aXRjaChzLT5mYXRfdHlwZSkgewoJY2FzZSAxMjogcy0+bWF4X2ZhdF92YWx1ZT0weGZmZjsgYnJlYWs7CgljYXNlIDE2OiBzLT5tYXhfZmF0X3ZhbHVlPTB4ZmZmZjsgYnJlYWs7CgljYXNlIDMyOiBzLT5tYXhfZmF0X3ZhbHVlPTB4MGZmZmZmZmY7IGJyZWFrOwoJZGVmYXVsdDogcy0+bWF4X2ZhdF92YWx1ZT0wOyAvKiBlcnJvci4uLiAqLwogICAgfQoKfQoKLyogVE9ETzogaW4gY3JlYXRlX3Nob3J0X2ZpbGVuYW1lLCAweGU1LT4weDA1IGlzIG5vdCB5ZXQgaGFuZGxlZCEgKi8KLyogVE9ETzogaW4gcGFyc2Vfc2hvcnRfZmlsZW5hbWUsIDB4MDUtPjB4ZTUgaXMgbm90IHlldCBoYW5kbGVkISAqLwpzdGF0aWMgaW5saW5lIGRpcmVudHJ5X3QqIGNyZWF0ZV9zaG9ydF9hbmRfbG9uZ19uYW1lKEJEUlZWVkZBVFN0YXRlKiBzLAoJdW5zaWduZWQgaW50IGRpcmVjdG9yeV9zdGFydCwgY29uc3QgY2hhciogZmlsZW5hbWUsIGludCBpc19kb3QpCnsKICAgIGludCBpLGosbG9uZ19pbmRleD1zLT5kaXJlY3RvcnkubmV4dDsKICAgIGRpcmVudHJ5X3QqIGVudHJ5PTA7CiAgICBkaXJlbnRyeV90KiBlbnRyeV9sb25nPTA7CgogICAgaWYoaXNfZG90KSB7CgllbnRyeT1hcnJheV9nZXRfbmV4dCgmKHMtPmRpcmVjdG9yeSkpOwoJbWVtc2V0KGVudHJ5LT5uYW1lLDB4MjAsMTEpOwoJbWVtY3B5KGVudHJ5LT5uYW1lLGZpbGVuYW1lLHN0cmxlbihmaWxlbmFtZSkpOwoJcmV0dXJuIGVudHJ5OwogICAgfQoKICAgIGVudHJ5X2xvbmc9Y3JlYXRlX2xvbmdfZmlsZW5hbWUocyxmaWxlbmFtZSk7CgogICAgaSA9IHN0cmxlbihmaWxlbmFtZSk7CiAgICBmb3IoaiA9IGkgLSAxOyBqPjAgICYmIGZpbGVuYW1lW2pdIT0nLic7ai0tKTsKICAgIGlmIChqID4gMCkKCWkgPSAoaiA+IDggPyA4IDogaik7CiAgICBlbHNlIGlmIChpID4gOCkKCWkgPSA4OwoKICAgIGVudHJ5PWFycmF5X2dldF9uZXh0KCYocy0+ZGlyZWN0b3J5KSk7CiAgICBtZW1zZXQoZW50cnktPm5hbWUsMHgyMCwxMSk7CiAgICBzdHJuY3B5KChjaGFyKillbnRyeS0+bmFtZSxmaWxlbmFtZSxpKTsKCiAgICBpZihqID4gMCkKCWZvciAoaSA9IDA7IGkgPCAzICYmIGZpbGVuYW1lW2orMStpXTsgaSsrKQoJICAgIGVudHJ5LT5leHRlbnNpb25baV0gPSBmaWxlbmFtZVtqKzEraV07CgogICAgLyogdXBjYXNlICYgcmVtb3ZlIHVud2FudGVkIGNoYXJhY3RlcnMgKi8KICAgIGZvcihpPTEwO2k+PTA7aS0tKSB7CglpZihpPT0xMCB8fCBpPT03KSBmb3IoO2k+MCAmJiBlbnRyeS0+bmFtZVtpXT09JyAnO2ktLSk7CglpZihlbnRyeS0+bmFtZVtpXTw9JyAnIHx8IGVudHJ5LT5uYW1lW2ldPjB4N2YKCQl8fCBzdHJjaHIoIi4qPzw+fFwiOi9cXFtdOywrPSciLGVudHJ5LT5uYW1lW2ldKSkKCSAgICBlbnRyeS0+bmFtZVtpXT0nXyc7CiAgICAgICAgZWxzZSBpZihlbnRyeS0+bmFtZVtpXT49J2EnICYmIGVudHJ5LT5uYW1lW2ldPD0neicpCiAgICAgICAgICAgIGVudHJ5LT5uYW1lW2ldKz0nQSctJ2EnOwogICAgfQoKICAgIC8qIG1hbmdsZSBkdXBsaWNhdGVzICovCiAgICB3aGlsZSgxKSB7CglkaXJlbnRyeV90KiBlbnRyeTE9YXJyYXlfZ2V0KCYocy0+ZGlyZWN0b3J5KSxkaXJlY3Rvcnlfc3RhcnQpOwoJaW50IGo7CgoJZm9yKDtlbnRyeTE8ZW50cnk7ZW50cnkxKyspCgkgICAgaWYoIWlzX2xvbmdfbmFtZShlbnRyeTEpICYmICFtZW1jbXAoZW50cnkxLT5uYW1lLGVudHJ5LT5uYW1lLDExKSkKCQlicmVhazsgLyogZm91bmQgZHVwZSAqLwoJaWYoZW50cnkxPT1lbnRyeSkgLyogbm8gZHVwZSBmb3VuZCAqLwoJICAgIGJyZWFrOwoKCS8qIHVzZSBhbGwgOCBjaGFyYWN0ZXJzIG9mIG5hbWUgKi8KCWlmKGVudHJ5LT5uYW1lWzddPT0nICcpIHsKCSAgICBpbnQgajsKCSAgICBmb3Ioaj02O2o+MCAmJiBlbnRyeS0+bmFtZVtqXT09JyAnO2otLSkKCQllbnRyeS0+bmFtZVtqXT0nfic7Cgl9CgoJLyogaW5jcmVtZW50IG51bWJlciAqLwoJZm9yKGo9NztqPjAgJiYgZW50cnktPm5hbWVbal09PSc5JztqLS0pCgkgICAgZW50cnktPm5hbWVbal09JzAnOwoJaWYoaj4wKSB7CgkgICAgaWYoZW50cnktPm5hbWVbal08JzAnIHx8IGVudHJ5LT5uYW1lW2pdPic5JykKCSAgICAgICAgZW50cnktPm5hbWVbal09JzAnOwoJICAgIGVsc2UKCSAgICAgICAgZW50cnktPm5hbWVbal0rKzsKCX0KICAgIH0KCiAgICAvKiBjYWxjdWxhdGUgY2hlY2tzdW07IHByb3BhZ2F0ZSB0byBsb25nIG5hbWUgKi8KICAgIGlmKGVudHJ5X2xvbmcpIHsKICAgICAgICB1aW50OF90IGNoa3N1bT1mYXRfY2hrc3VtKGVudHJ5KTsKCgkvKiBjYWxjdWxhdGUgYW5ldywgYmVjYXVzZSByZWFsbG9jIGNvdWxkIGhhdmUgdGFrZW4gcGxhY2UgKi8KCWVudHJ5X2xvbmc9YXJyYXlfZ2V0KCYocy0+ZGlyZWN0b3J5KSxsb25nX2luZGV4KTsKCXdoaWxlKGVudHJ5X2xvbmc8ZW50cnkgJiYgaXNfbG9uZ19uYW1lKGVudHJ5X2xvbmcpKSB7CgkgICAgZW50cnlfbG9uZy0+cmVzZXJ2ZWRbMV09Y2hrc3VtOwoJICAgIGVudHJ5X2xvbmcrKzsKCX0KICAgIH0KCiAgICByZXR1cm4gZW50cnk7Cn0KCi8qCiAqIFJlYWQgYSBkaXJlY3RvcnkuICh0aGUgaW5kZXggb2YgdGhlIGNvcnJlc3BvbmRpbmcgbWFwcGluZyBtdXN0IGJlIHBhc3NlZCkuCiAqLwpzdGF0aWMgaW50IHJlYWRfZGlyZWN0b3J5KEJEUlZWVkZBVFN0YXRlKiBzLCBpbnQgbWFwcGluZ19pbmRleCkKewogICAgbWFwcGluZ190KiBtYXBwaW5nID0gYXJyYXlfZ2V0KCYocy0+bWFwcGluZyksIG1hcHBpbmdfaW5kZXgpOwogICAgZGlyZW50cnlfdCogZGlyZW50cnk7CiAgICBjb25zdCBjaGFyKiBkaXJuYW1lID0gbWFwcGluZy0+cGF0aDsKICAgIGludCBmaXJzdF9jbHVzdGVyID0gbWFwcGluZy0+YmVnaW47CiAgICBpbnQgcGFyZW50X2luZGV4ID0gbWFwcGluZy0+aW5mby5kaXIucGFyZW50X21hcHBpbmdfaW5kZXg7CiAgICBtYXBwaW5nX3QqIHBhcmVudF9tYXBwaW5nID0gKG1hcHBpbmdfdCopCgkocGFyZW50X2luZGV4ID49IDAgPyBhcnJheV9nZXQoJihzLT5tYXBwaW5nKSwgcGFyZW50X2luZGV4KSA6IDApOwogICAgaW50IGZpcnN0X2NsdXN0ZXJfb2ZfcGFyZW50ID0gcGFyZW50X21hcHBpbmcgPyBwYXJlbnRfbWFwcGluZy0+YmVnaW4gOiAtMTsKCiAgICBESVIqIGRpcj1vcGVuZGlyKGRpcm5hbWUpOwogICAgc3RydWN0IGRpcmVudCogZW50cnk7CiAgICBpbnQgaTsKCiAgICBhc3NlcnQobWFwcGluZy0+bW9kZSAmIE1PREVfRElSRUNUT1JZKTsKCiAgICBpZighZGlyKSB7CgltYXBwaW5nLT5lbmQgPSBtYXBwaW5nLT5iZWdpbjsKCXJldHVybiAtMTsKICAgIH0KCiAgICBpID0gbWFwcGluZy0+aW5mby5kaXIuZmlyc3RfZGlyX2luZGV4ID0KCSAgICBmaXJzdF9jbHVzdGVyID09IDAgPyAwIDogcy0+ZGlyZWN0b3J5Lm5leHQ7CgogICAgLyogYWN0dWFsbHkgcmVhZCB0aGUgZGlyZWN0b3J5LCBhbmQgYWxsb2NhdGUgdGhlIG1hcHBpbmdzICovCiAgICB3aGlsZSgoZW50cnk9cmVhZGRpcihkaXIpKSkgewoJdW5zaWduZWQgaW50IGxlbmd0aD1zdHJsZW4oZGlybmFtZSkrMitzdHJsZW4oZW50cnktPmRfbmFtZSk7CiAgICAgICAgY2hhciogYnVmZmVyOwoJZGlyZW50cnlfdCogZGlyZW50cnk7CiAgICAgICAgc3RydWN0IHN0YXQgc3Q7CglpbnQgaXNfZG90PSFzdHJjbXAoZW50cnktPmRfbmFtZSwiLiIpOwoJaW50IGlzX2RvdGRvdD0hc3RyY21wKGVudHJ5LT5kX25hbWUsIi4uIik7CgoJaWYoZmlyc3RfY2x1c3RlciA9PSAwICYmIChpc19kb3Rkb3QgfHwgaXNfZG90KSkKCSAgICBjb250aW51ZTsKCglidWZmZXI9KGNoYXIqKW1hbGxvYyhsZW5ndGgpOwoJYXNzZXJ0KGJ1ZmZlcik7CglzbnByaW50ZihidWZmZXIsbGVuZ3RoLCIlcy8lcyIsZGlybmFtZSxlbnRyeS0+ZF9uYW1lKTsKCglpZihzdGF0KGJ1ZmZlciwmc3QpPDApIHsKCSAgICBmcmVlKGJ1ZmZlcik7CiAgICAgICAgICAgIGNvbnRpbnVlOwoJfQoKCS8qIGNyZWF0ZSBkaXJlY3RvcnkgZW50cnkgZm9yIHRoaXMgZmlsZSAqLwoJZGlyZW50cnk9Y3JlYXRlX3Nob3J0X2FuZF9sb25nX25hbWUocywgaSwgZW50cnktPmRfbmFtZSwKCQlpc19kb3QgfHwgaXNfZG90ZG90KTsKCWRpcmVudHJ5LT5hdHRyaWJ1dGVzPShTX0lTRElSKHN0LnN0X21vZGUpPzB4MTA6MHgyMCk7CglkaXJlbnRyeS0+cmVzZXJ2ZWRbMF09ZGlyZW50cnktPnJlc2VydmVkWzFdPTA7CglkaXJlbnRyeS0+Y3RpbWU9ZmF0X2RhdGV0aW1lKHN0LnN0X2N0aW1lLDEpOwoJZGlyZW50cnktPmNkYXRlPWZhdF9kYXRldGltZShzdC5zdF9jdGltZSwwKTsKCWRpcmVudHJ5LT5hZGF0ZT1mYXRfZGF0ZXRpbWUoc3Quc3RfYXRpbWUsMCk7CglkaXJlbnRyeS0+YmVnaW5faGk9MDsKCWRpcmVudHJ5LT5tdGltZT1mYXRfZGF0ZXRpbWUoc3Quc3RfbXRpbWUsMSk7CglkaXJlbnRyeS0+bWRhdGU9ZmF0X2RhdGV0aW1lKHN0LnN0X210aW1lLDApOwoJaWYoaXNfZG90ZG90KQoJICAgIHNldF9iZWdpbl9vZl9kaXJlbnRyeShkaXJlbnRyeSwgZmlyc3RfY2x1c3Rlcl9vZl9wYXJlbnQpOwoJZWxzZSBpZihpc19kb3QpCgkgICAgc2V0X2JlZ2luX29mX2RpcmVudHJ5KGRpcmVudHJ5LCBmaXJzdF9jbHVzdGVyKTsKCWVsc2UKCSAgICBkaXJlbnRyeS0+YmVnaW49MDsgLyogZG8gdGhhdCBsYXRlciAqLwogICAgICAgIGlmIChzdC5zdF9zaXplID4gMHg3ZmZmZmZmZikgewoJICAgIGZwcmludGYoc3RkZXJyLCAiRmlsZSAlcyBpcyBsYXJnZXIgdGhhbiAyR0JcbiIsIGJ1ZmZlcik7CgkgICAgZnJlZShidWZmZXIpOwoJICAgIHJldHVybiAtMjsKICAgICAgICB9CglkaXJlbnRyeS0+c2l6ZT1jcHVfdG9fbGUzMihTX0lTRElSKHN0LnN0X21vZGUpPzA6c3Quc3Rfc2l6ZSk7CgoJLyogY3JlYXRlIG1hcHBpbmcgZm9yIHRoaXMgZmlsZSAqLwoJaWYoIWlzX2RvdCAmJiAhaXNfZG90ZG90ICYmIChTX0lTRElSKHN0LnN0X21vZGUpIHx8IHN0LnN0X3NpemUpKSB7CgkgICAgcy0+Y3VycmVudF9tYXBwaW5nPShtYXBwaW5nX3QqKWFycmF5X2dldF9uZXh0KCYocy0+bWFwcGluZykpOwoJICAgIHMtPmN1cnJlbnRfbWFwcGluZy0+YmVnaW49MDsKCSAgICBzLT5jdXJyZW50X21hcHBpbmctPmVuZD1zdC5zdF9zaXplOwoJICAgIC8qCgkgICAgICogd2UgZ2V0IHRoZSBkaXJlbnRyeSBvZiB0aGUgbW9zdCByZWNlbnQgZGlyZW50cnksIHdoaWNoCgkgICAgICogY29udGFpbnMgdGhlIHNob3J0IG5hbWUgYW5kIGFsbCB0aGUgcmVsZXZhbnQgaW5mb3JtYXRpb24uCgkgICAgICovCgkgICAgcy0+Y3VycmVudF9tYXBwaW5nLT5kaXJfaW5kZXg9cy0+ZGlyZWN0b3J5Lm5leHQtMTsKCSAgICBzLT5jdXJyZW50X21hcHBpbmctPmZpcnN0X21hcHBpbmdfaW5kZXggPSAtMTsKCSAgICBpZiAoU19JU0RJUihzdC5zdF9tb2RlKSkgewoJCXMtPmN1cnJlbnRfbWFwcGluZy0+bW9kZSA9IE1PREVfRElSRUNUT1JZOwoJCXMtPmN1cnJlbnRfbWFwcGluZy0+aW5mby5kaXIucGFyZW50X21hcHBpbmdfaW5kZXggPQoJCSAgICBtYXBwaW5nX2luZGV4OwoJICAgIH0gZWxzZSB7CgkJcy0+Y3VycmVudF9tYXBwaW5nLT5tb2RlID0gTU9ERV9VTkRFRklORUQ7CgkJcy0+Y3VycmVudF9tYXBwaW5nLT5pbmZvLmZpbGUub2Zmc2V0ID0gMDsKCSAgICB9CgkgICAgcy0+Y3VycmVudF9tYXBwaW5nLT5wYXRoPWJ1ZmZlcjsKCSAgICBzLT5jdXJyZW50X21hcHBpbmctPnJlYWRfb25seSA9CgkJKHN0LnN0X21vZGUgJiAoU19JV1VTUiB8IFNfSVdHUlAgfCBTX0lXT1RIKSkgPT0gMDsKCX0KICAgIH0KICAgIGNsb3NlZGlyKGRpcik7CgogICAgLyogZmlsbCB3aXRoIHplcm9lcyB1cCB0byB0aGUgZW5kIG9mIHRoZSBjbHVzdGVyICovCiAgICB3aGlsZShzLT5kaXJlY3RvcnkubmV4dCUoMHgxMCpzLT5zZWN0b3JzX3Blcl9jbHVzdGVyKSkgewoJZGlyZW50cnlfdCogZGlyZW50cnk9YXJyYXlfZ2V0X25leHQoJihzLT5kaXJlY3RvcnkpKTsKCW1lbXNldChkaXJlbnRyeSwwLHNpemVvZihkaXJlbnRyeV90KSk7CiAgICB9CgovKiBUT0RPOiBpZiB0aGVyZSBhcmUgbW9yZSBlbnRyaWVzLCBib290c2VjdG9yIGhhcyB0byBiZSBhZGp1c3RlZCEgKi8KI2RlZmluZSBST09UX0VOVFJJRVMgKDB4MDIgKiAweDEwICogcy0+c2VjdG9yc19wZXJfY2x1c3RlcikKICAgIGlmIChtYXBwaW5nX2luZGV4ID09IDAgJiYgcy0+ZGlyZWN0b3J5Lm5leHQgPCBST09UX0VOVFJJRVMpIHsKCS8qIHJvb3QgZGlyZWN0b3J5ICovCglpbnQgY3VyID0gcy0+ZGlyZWN0b3J5Lm5leHQ7CglhcnJheV9lbnN1cmVfYWxsb2NhdGVkKCYocy0+ZGlyZWN0b3J5KSwgUk9PVF9FTlRSSUVTIC0gMSk7CgltZW1zZXQoYXJyYXlfZ2V0KCYocy0+ZGlyZWN0b3J5KSwgY3VyKSwgMCwKCQkoUk9PVF9FTlRSSUVTIC0gY3VyKSAqIHNpemVvZihkaXJlbnRyeV90KSk7CiAgICB9CgogICAgIC8qIHJlZ2V0IHRoZSBtYXBwaW5nLCBzaW5jZSBzLT5tYXBwaW5nIHdhcyBwb3NzaWJseSByZWFsbG9jKCllZCAqLwogICAgbWFwcGluZyA9IChtYXBwaW5nX3QqKWFycmF5X2dldCgmKHMtPm1hcHBpbmcpLCBtYXBwaW5nX2luZGV4KTsKICAgIGZpcnN0X2NsdXN0ZXIgKz0gKHMtPmRpcmVjdG9yeS5uZXh0IC0gbWFwcGluZy0+aW5mby5kaXIuZmlyc3RfZGlyX2luZGV4KQoJKiAweDIwIC8gcy0+Y2x1c3Rlcl9zaXplOwogICAgbWFwcGluZy0+ZW5kID0gZmlyc3RfY2x1c3RlcjsKCiAgICBkaXJlbnRyeSA9IChkaXJlbnRyeV90KilhcnJheV9nZXQoJihzLT5kaXJlY3RvcnkpLCBtYXBwaW5nLT5kaXJfaW5kZXgpOwogICAgc2V0X2JlZ2luX29mX2RpcmVudHJ5KGRpcmVudHJ5LCBtYXBwaW5nLT5iZWdpbik7CgogICAgcmV0dXJuIDA7Cn0KCnN0YXRpYyBpbmxpbmUgdWludDMyX3Qgc2VjdG9yMmNsdXN0ZXIoQkRSVlZWRkFUU3RhdGUqIHMsb2ZmX3Qgc2VjdG9yX251bSkKewogICAgcmV0dXJuIChzZWN0b3JfbnVtLXMtPmZha2VkX3NlY3RvcnMpL3MtPnNlY3RvcnNfcGVyX2NsdXN0ZXI7Cn0KCnN0YXRpYyBpbmxpbmUgb2ZmX3QgY2x1c3RlcjJzZWN0b3IoQkRSVlZWRkFUU3RhdGUqIHMsIHVpbnQzMl90IGNsdXN0ZXJfbnVtKQp7CiAgICByZXR1cm4gcy0+ZmFrZWRfc2VjdG9ycyArIHMtPnNlY3RvcnNfcGVyX2NsdXN0ZXIgKiBjbHVzdGVyX251bTsKfQoKc3RhdGljIGlubGluZSB1aW50MzJfdCBzZWN0b3Jfb2Zmc2V0X2luX2NsdXN0ZXIoQkRSVlZWRkFUU3RhdGUqIHMsb2ZmX3Qgc2VjdG9yX251bSkKewogICAgcmV0dXJuIChzZWN0b3JfbnVtLXMtPmZpcnN0X3NlY3RvcnNfbnVtYmVyLTIqcy0+c2VjdG9yc19wZXJfZmF0KSVzLT5zZWN0b3JzX3Blcl9jbHVzdGVyOwp9CgojaWZkZWYgREJHCnN0YXRpYyBkaXJlbnRyeV90KiBnZXRfZGlyZW50cnlfZm9yX21hcHBpbmcoQkRSVlZWRkFUU3RhdGUqIHMsbWFwcGluZ190KiBtYXBwaW5nKQp7CiAgICBpZihtYXBwaW5nLT5tb2RlPT1NT0RFX1VOREVGSU5FRCkKCXJldHVybiAwOwogICAgcmV0dXJuIChkaXJlbnRyeV90Kikocy0+ZGlyZWN0b3J5LnBvaW50ZXIrc2l6ZW9mKGRpcmVudHJ5X3QpKm1hcHBpbmctPmRpcl9pbmRleCk7Cn0KI2VuZGlmCgpzdGF0aWMgaW50IGluaXRfZGlyZWN0b3JpZXMoQkRSVlZWRkFUU3RhdGUqIHMsCgljb25zdCBjaGFyKiBkaXJuYW1lKQp7CiAgICBib290c2VjdG9yX3QqIGJvb3RzZWN0b3I7CiAgICBtYXBwaW5nX3QqIG1hcHBpbmc7CiAgICB1bnNpZ25lZCBpbnQgaTsKICAgIHVuc2lnbmVkIGludCBjbHVzdGVyOwoKICAgIG1lbXNldCgmKHMtPmZpcnN0X3NlY3RvcnNbMF0pLDAsMHg0MCoweDIwMCk7CgogICAgcy0+Y2x1c3Rlcl9zaXplPXMtPnNlY3RvcnNfcGVyX2NsdXN0ZXIqMHgyMDA7CiAgICBzLT5jbHVzdGVyX2J1ZmZlcj1tYWxsb2Mocy0+Y2x1c3Rlcl9zaXplKTsKICAgIGFzc2VydChzLT5jbHVzdGVyX2J1ZmZlcik7CgogICAgLyoKICAgICAqIFRoZSBmb3JtdWxhOiBzYyA9IHNwZisxK3NwZipzcGMqKDUxMio4L2ZhdF90eXBlKSwKICAgICAqIHdoZXJlIHNjIGlzIHNlY3Rvcl9jb3VudCwKICAgICAqIHNwZiBpcyBzZWN0b3JzX3Blcl9mYXQsCiAgICAgKiBzcGMgaXMgc2VjdG9yc19wZXJfY2x1c3RlcnMsIGFuZAogICAgICogZmF0X3R5cGUgPSAxMiwgMTYgb3IgMzIuCiAgICAgKi8KICAgIGkgPSAxK3MtPnNlY3RvcnNfcGVyX2NsdXN0ZXIqMHgyMDAqOC9zLT5mYXRfdHlwZTsKICAgIHMtPnNlY3RvcnNfcGVyX2ZhdD0ocy0+c2VjdG9yX2NvdW50K2kpL2k7IC8qIHJvdW5kIHVwICovCgogICAgYXJyYXlfaW5pdCgmKHMtPm1hcHBpbmcpLHNpemVvZihtYXBwaW5nX3QpKTsKICAgIGFycmF5X2luaXQoJihzLT5kaXJlY3RvcnkpLHNpemVvZihkaXJlbnRyeV90KSk7CgogICAgLyogYWRkIHZvbHVtZSBsYWJlbCAqLwogICAgewoJZGlyZW50cnlfdCogZW50cnk9YXJyYXlfZ2V0X25leHQoJihzLT5kaXJlY3RvcnkpKTsKCWVudHJ5LT5hdHRyaWJ1dGVzPTB4Mjg7IC8qIGFyY2hpdmUgfCB2b2x1bWUgbGFiZWwgKi8KCXNucHJpbnRmKChjaGFyKillbnRyeS0+bmFtZSwxMSwiUUVNVSBWVkZBVCIpOwogICAgfQoKICAgIC8qIE5vdyBidWlsZCBGQVQsIGFuZCB3cml0ZSBiYWNrIGluZm9ybWF0aW9uIGludG8gZGlyZWN0b3J5ICovCiAgICBpbml0X2ZhdChzKTsKCiAgICBzLT5mYWtlZF9zZWN0b3JzPXMtPmZpcnN0X3NlY3RvcnNfbnVtYmVyK3MtPnNlY3RvcnNfcGVyX2ZhdCoyOwogICAgcy0+Y2x1c3Rlcl9jb3VudD1zZWN0b3IyY2x1c3RlcihzLCBzLT5zZWN0b3JfY291bnQpOwoKICAgIG1hcHBpbmcgPSBhcnJheV9nZXRfbmV4dCgmKHMtPm1hcHBpbmcpKTsKICAgIG1hcHBpbmctPmJlZ2luID0gMDsKICAgIG1hcHBpbmctPmRpcl9pbmRleCA9IDA7CiAgICBtYXBwaW5nLT5pbmZvLmRpci5wYXJlbnRfbWFwcGluZ19pbmRleCA9IC0xOwogICAgbWFwcGluZy0+Zmlyc3RfbWFwcGluZ19pbmRleCA9IC0xOwogICAgbWFwcGluZy0+cGF0aCA9IHN0cmR1cChkaXJuYW1lKTsKICAgIGkgPSBzdHJsZW4obWFwcGluZy0+cGF0aCk7CiAgICBpZiAoaSA+IDAgJiYgbWFwcGluZy0+cGF0aFtpIC0gMV0gPT0gJy8nKQoJbWFwcGluZy0+cGF0aFtpIC0gMV0gPSAnXDAnOwogICAgbWFwcGluZy0+bW9kZSA9IE1PREVfRElSRUNUT1JZOwogICAgbWFwcGluZy0+cmVhZF9vbmx5ID0gMDsKICAgIHMtPnBhdGggPSBtYXBwaW5nLT5wYXRoOwoKICAgIGZvciAoaSA9IDAsIGNsdXN0ZXIgPSAwOyBpIDwgcy0+bWFwcGluZy5uZXh0OyBpKyspIHsKCWludCBqOwoJLyogTVMtRE9TIGV4cGVjdHMgdGhlIEZBVCB0byBiZSAwIGZvciB0aGUgcm9vdCBkaXJlY3RvcnkKCSAqIChleGNlcHQgZm9yIHRoZSBtZWRpYSBieXRlKS4gKi8KCS8qIExBVEVSIFRPRE86IHN0aWxsIHRydWUgZm9yIEZBVDMyPyAqLwoJaW50IGZpeF9mYXQgPSAoaSAhPSAwKTsKCW1hcHBpbmcgPSBhcnJheV9nZXQoJihzLT5tYXBwaW5nKSwgaSk7CgogICAgICAgIGlmIChtYXBwaW5nLT5tb2RlICYgTU9ERV9ESVJFQ1RPUlkpIHsKCSAgICBtYXBwaW5nLT5iZWdpbiA9IGNsdXN0ZXI7CgkgICAgaWYocmVhZF9kaXJlY3RvcnkocywgaSkpIHsKCQlmcHJpbnRmKHN0ZGVyciwgIkNvdWxkIG5vdCByZWFkIGRpcmVjdG9yeSAlc1xuIiwKCQkJbWFwcGluZy0+cGF0aCk7CgkJcmV0dXJuIC0xOwoJICAgIH0KCSAgICBtYXBwaW5nID0gYXJyYXlfZ2V0KCYocy0+bWFwcGluZyksIGkpOwoJfSBlbHNlIHsKCSAgICBhc3NlcnQobWFwcGluZy0+bW9kZSA9PSBNT0RFX1VOREVGSU5FRCk7CgkgICAgbWFwcGluZy0+bW9kZT1NT0RFX05PUk1BTDsKCSAgICBtYXBwaW5nLT5iZWdpbiA9IGNsdXN0ZXI7CgkgICAgaWYgKG1hcHBpbmctPmVuZCA+IDApIHsKCQlkaXJlbnRyeV90KiBkaXJlbnRyeSA9IGFycmF5X2dldCgmKHMtPmRpcmVjdG9yeSksCgkJCW1hcHBpbmctPmRpcl9pbmRleCk7CgoJCW1hcHBpbmctPmVuZCA9IGNsdXN0ZXIgKyAxICsgKG1hcHBpbmctPmVuZC0xKS9zLT5jbHVzdGVyX3NpemU7CgkJc2V0X2JlZ2luX29mX2RpcmVudHJ5KGRpcmVudHJ5LCBtYXBwaW5nLT5iZWdpbik7CgkgICAgfSBlbHNlIHsKCQltYXBwaW5nLT5lbmQgPSBjbHVzdGVyICsgMTsKCQlmaXhfZmF0ID0gMDsKCSAgICB9Cgl9CgoJYXNzZXJ0KG1hcHBpbmctPmJlZ2luIDwgbWFwcGluZy0+ZW5kKTsKCgkvKiBmaXggZmF0IGZvciBlbnRyeSAqLwoJaWYgKGZpeF9mYXQpIHsKCSAgICBmb3IoaiA9IG1hcHBpbmctPmJlZ2luOyBqIDwgbWFwcGluZy0+ZW5kIC0gMTsgaisrKQoJCWZhdF9zZXQocywgaiwgaisxKTsKCSAgICBmYXRfc2V0KHMsIG1hcHBpbmctPmVuZCAtIDEsIHMtPm1heF9mYXRfdmFsdWUpOwoJfQoKCS8qIG5leHQgZnJlZSBjbHVzdGVyICovCgljbHVzdGVyID0gbWFwcGluZy0+ZW5kOwoKCWlmKGNsdXN0ZXIgPiBzLT5jbHVzdGVyX2NvdW50KSB7CgkgICAgZnByaW50ZihzdGRlcnIsIkRpcmVjdG9yeSBkb2VzIG5vdCBmaXQgaW4gRkFUJWRcbiIscy0+ZmF0X3R5cGUpOwoJICAgIHJldHVybiAtMTsKCX0KICAgIH0KCiAgICBtYXBwaW5nID0gYXJyYXlfZ2V0KCYocy0+bWFwcGluZyksIDApOwogICAgcy0+c2VjdG9yc19vZl9yb290X2RpcmVjdG9yeSA9IG1hcHBpbmctPmVuZCAqIHMtPnNlY3RvcnNfcGVyX2NsdXN0ZXI7CiAgICBzLT5sYXN0X2NsdXN0ZXJfb2Zfcm9vdF9kaXJlY3RvcnkgPSBtYXBwaW5nLT5lbmQ7CgogICAgLyogdGhlIEZBVCBzaWduYXR1cmUgKi8KICAgIGZhdF9zZXQocywwLHMtPm1heF9mYXRfdmFsdWUpOwogICAgZmF0X3NldChzLDEscy0+bWF4X2ZhdF92YWx1ZSk7CgogICAgcy0+Y3VycmVudF9tYXBwaW5nID0gTlVMTDsKCiAgICBib290c2VjdG9yPShib290c2VjdG9yX3QqKShzLT5maXJzdF9zZWN0b3JzKyhzLT5maXJzdF9zZWN0b3JzX251bWJlci0xKSoweDIwMCk7CiAgICBib290c2VjdG9yLT5qdW1wWzBdPTB4ZWI7CiAgICBib290c2VjdG9yLT5qdW1wWzFdPTB4M2U7CiAgICBib290c2VjdG9yLT5qdW1wWzJdPTB4OTA7CiAgICBtZW1jcHkoYm9vdHNlY3Rvci0+bmFtZSwiUUVNVSAgICAiLDgpOwogICAgYm9vdHNlY3Rvci0+c2VjdG9yX3NpemU9Y3B1X3RvX2xlMTYoMHgyMDApOwogICAgYm9vdHNlY3Rvci0+c2VjdG9yc19wZXJfY2x1c3Rlcj1zLT5zZWN0b3JzX3Blcl9jbHVzdGVyOwogICAgYm9vdHNlY3Rvci0+cmVzZXJ2ZWRfc2VjdG9ycz1jcHVfdG9fbGUxNigxKTsKICAgIGJvb3RzZWN0b3ItPm51bWJlcl9vZl9mYXRzPTB4MjsgLyogbnVtYmVyIG9mIEZBVHMgKi8KICAgIGJvb3RzZWN0b3ItPnJvb3RfZW50cmllcz1jcHVfdG9fbGUxNihzLT5zZWN0b3JzX29mX3Jvb3RfZGlyZWN0b3J5KjB4MTApOwogICAgYm9vdHNlY3Rvci0+dG90YWxfc2VjdG9yczE2PXMtPnNlY3Rvcl9jb3VudD4weGZmZmY/MDpjcHVfdG9fbGUxNihzLT5zZWN0b3JfY291bnQpOwogICAgYm9vdHNlY3Rvci0+bWVkaWFfdHlwZT0ocy0+ZmF0X3R5cGUhPTEyPzB4Zjg6cy0+c2VjdG9yX2NvdW50PT01NzYwPzB4Zjk6MHhmOCk7IC8qIG1lZGlhIGRlc2NyaXB0b3IgKi8KICAgIHMtPmZhdC5wb2ludGVyWzBdID0gYm9vdHNlY3Rvci0+bWVkaWFfdHlwZTsKICAgIGJvb3RzZWN0b3ItPnNlY3RvcnNfcGVyX2ZhdD1jcHVfdG9fbGUxNihzLT5zZWN0b3JzX3Blcl9mYXQpOwogICAgYm9vdHNlY3Rvci0+c2VjdG9yc19wZXJfdHJhY2s9Y3B1X3RvX2xlMTYocy0+YnMtPnNlY3MpOwogICAgYm9vdHNlY3Rvci0+bnVtYmVyX29mX2hlYWRzPWNwdV90b19sZTE2KHMtPmJzLT5oZWFkcyk7CiAgICBib290c2VjdG9yLT5oaWRkZW5fc2VjdG9ycz1jcHVfdG9fbGUzMihzLT5maXJzdF9zZWN0b3JzX251bWJlcj09MT8wOjB4M2YpOwogICAgYm9vdHNlY3Rvci0+dG90YWxfc2VjdG9ycz1jcHVfdG9fbGUzMihzLT5zZWN0b3JfY291bnQ+MHhmZmZmP3MtPnNlY3Rvcl9jb3VudDowKTsKCiAgICAvKiBMQVRFUiBUT0RPOiBpZiBGQVQzMiwgdGhpcyBpcyB3cm9uZyAqLwogICAgYm9vdHNlY3Rvci0+dS5mYXQxNi5kcml2ZV9udW1iZXI9cy0+ZmF0X3R5cGU9PTEyPzA6MHg4MDsgLyogYXNzdW1lIHRoaXMgaXMgaGRhIChUT0RPKSAqLwogICAgYm9vdHNlY3Rvci0+dS5mYXQxNi5jdXJyZW50X2hlYWQ9MDsKICAgIGJvb3RzZWN0b3ItPnUuZmF0MTYuc2lnbmF0dXJlPTB4Mjk7CiAgICBib290c2VjdG9yLT51LmZhdDE2LmlkPWNwdV90b19sZTMyKDB4ZmFiZTFhZmQpOwoKICAgIG1lbWNweShib290c2VjdG9yLT51LmZhdDE2LnZvbHVtZV9sYWJlbCwiUUVNVSBWVkZBVCAiLDExKTsKICAgIG1lbWNweShib290c2VjdG9yLT5mYXRfdHlwZSwocy0+ZmF0X3R5cGU9PTEyPyJGQVQxMiAgICI6cy0+ZmF0X3R5cGU9PTE2PyJGQVQxNiAgICI6IkZBVDMyICAgIiksOCk7CiAgICBib290c2VjdG9yLT5tYWdpY1swXT0weDU1OyBib290c2VjdG9yLT5tYWdpY1sxXT0weGFhOwoKICAgIHJldHVybiAwOwp9CgojaWZkZWYgREVCVUcKc3RhdGljIEJEUlZWVkZBVFN0YXRlICp2dnYgPSBOVUxMOwojZW5kaWYKCnN0YXRpYyBpbnQgZW5hYmxlX3dyaXRlX3RhcmdldChCRFJWVlZGQVRTdGF0ZSAqcyk7CnN0YXRpYyBpbnQgaXNfY29uc2lzdGVudChCRFJWVlZGQVRTdGF0ZSAqcyk7CgpzdGF0aWMgaW50IHZ2ZmF0X29wZW4oQmxvY2tEcml2ZXJTdGF0ZSAqYnMsIGNvbnN0IGNoYXIqIGRpcm5hbWUsIGludCBmbGFncykKewogICAgQkRSVlZWRkFUU3RhdGUgKnMgPSBicy0+b3BhcXVlOwogICAgaW50IGZsb3BweSA9IDA7CiAgICBpbnQgaTsKCiNpZmRlZiBERUJVRwogICAgdnZ2ID0gczsKI2VuZGlmCgpETE9HKGlmIChzdGRlcnIgPT0gTlVMTCkgewogICAgc3RkZXJyID0gZm9wZW4oInZ2ZmF0LmxvZyIsICJhIik7CiAgICBzZXRidWYoc3RkZXJyLCBOVUxMKTsKfSkKCiAgICBzLT5icyA9IGJzOwoKICAgIHMtPmZhdF90eXBlPTE2OwogICAgLyogTEFURVIgVE9ETzogaWYgRkFUMzIsIGFkanVzdCAqLwogICAgcy0+c2VjdG9yc19wZXJfY2x1c3Rlcj0weDEwOwogICAgLyogNTA0TUIgZGlzayovCiAgICBicy0+Y3lscz0xMDI0OyBicy0+aGVhZHM9MTY7IGJzLT5zZWNzPTYzOwoKICAgIHMtPmN1cnJlbnRfY2x1c3Rlcj0weGZmZmZmZmZmOwoKICAgIHMtPmZpcnN0X3NlY3RvcnNfbnVtYmVyPTB4NDA7CiAgICAvKiByZWFkIG9ubHkgaXMgdGhlIGRlZmF1bHQgZm9yIHNhZmV0eSAqLwogICAgYnMtPnJlYWRfb25seSA9IDE7CiAgICBzLT5xY293ID0gcy0+d3JpdGVfdGFyZ2V0ID0gTlVMTDsKICAgIHMtPnFjb3dfZmlsZW5hbWUgPSBOVUxMOwogICAgcy0+ZmF0MiA9IE5VTEw7CiAgICBzLT5kb3duY2FzZV9zaG9ydF9uYW1lcyA9IDE7CgogICAgaWYgKCFzdHJzdGFydChkaXJuYW1lLCAiZmF0OiIsIE5VTEwpKQoJcmV0dXJuIC0xOwoKICAgIGlmIChzdHJzdHIoZGlybmFtZSwgIjpmbG9wcHk6IikpIHsKCWZsb3BweSA9IDE7CglzLT5mYXRfdHlwZSA9IDEyOwoJcy0+Zmlyc3Rfc2VjdG9yc19udW1iZXIgPSAxOwoJcy0+c2VjdG9yc19wZXJfY2x1c3Rlcj0yOwoJYnMtPmN5bHMgPSA4MDsgYnMtPmhlYWRzID0gMjsgYnMtPnNlY3MgPSAzNjsKICAgIH0KCiAgICBzLT5zZWN0b3JfY291bnQ9YnMtPmN5bHMqYnMtPmhlYWRzKmJzLT5zZWNzOwoKICAgIGlmIChzdHJzdHIoZGlybmFtZSwgIjozMjoiKSkgewoJZnByaW50ZihzdGRlcnIsICJCaWcgZmF0IGdyZWVrIHdhcm5pbmc6IEZBVDMyIGhhcyBub3QgYmVlbiB0ZXN0ZWQuIFlvdSBhcmUgd2VsY29tZSB0byBkbyBzbyFcbiIpOwoJcy0+ZmF0X3R5cGUgPSAzMjsKICAgIH0gZWxzZSBpZiAoc3Ryc3RyKGRpcm5hbWUsICI6MTY6IikpIHsKCXMtPmZhdF90eXBlID0gMTY7CiAgICB9IGVsc2UgaWYgKHN0cnN0cihkaXJuYW1lLCAiOjEyOiIpKSB7CglzLT5mYXRfdHlwZSA9IDEyOwoJcy0+c2VjdG9yX2NvdW50PTI4ODA7CiAgICB9CgogICAgaWYgKHN0cnN0cihkaXJuYW1lLCAiOnJ3OiIpKSB7CglpZiAoZW5hYmxlX3dyaXRlX3RhcmdldChzKSkKCSAgICByZXR1cm4gLTE7Cglicy0+cmVhZF9vbmx5ID0gMDsKICAgIH0KCiAgICBpID0gc3RycmNocihkaXJuYW1lLCAnOicpIC0gZGlybmFtZTsKICAgIGFzc2VydChpID49IDMpOwogICAgaWYgKGRpcm5hbWVbaS0yXSA9PSAnOicgJiYgaXNhbHBoYShkaXJuYW1lW2ktMV0pKQoJLyogd29ya2Fyb3VuZCBmb3IgRE9TIGRyaXZlIG5hbWVzICovCglkaXJuYW1lICs9IGktMTsKICAgIGVsc2UKCWRpcm5hbWUgKz0gaSsxOwoKICAgIGJzLT50b3RhbF9zZWN0b3JzPWJzLT5jeWxzKmJzLT5oZWFkcypicy0+c2VjczsKCiAgICBpZihpbml0X2RpcmVjdG9yaWVzKHMsIGRpcm5hbWUpKQoJcmV0dXJuIC0xOwoKICAgIHMtPnNlY3Rvcl9jb3VudCA9IHMtPmZha2VkX3NlY3RvcnMgKyBzLT5zZWN0b3JzX3Blcl9jbHVzdGVyKnMtPmNsdXN0ZXJfY291bnQ7CgogICAgaWYocy0+Zmlyc3Rfc2VjdG9yc19udW1iZXI9PTB4NDApCglpbml0X21icihzKTsKCiAgICAvKiBmb3Igc29tZSByZWFzb24gb3Igb3RoZXIsIE1TLURPUyBkb2VzIG5vdCBsaWtlIHRvIGtub3cgYWJvdXQgQ0hTLi4uICovCiAgICBpZiAoZmxvcHB5KQoJYnMtPmhlYWRzID0gYnMtPmN5bHMgPSBicy0+c2VjcyA9IDA7CgogICAgLy8gICAgYXNzZXJ0KGlzX2NvbnNpc3RlbnQocykpOwogICAgcmV0dXJuIDA7Cn0KCnN0YXRpYyBpbmxpbmUgdm9pZCB2dmZhdF9jbG9zZV9jdXJyZW50X2ZpbGUoQkRSVlZWRkFUU3RhdGUgKnMpCnsKICAgIGlmKHMtPmN1cnJlbnRfbWFwcGluZykgewoJcy0+Y3VycmVudF9tYXBwaW5nID0gTlVMTDsKCWlmIChzLT5jdXJyZW50X2ZkKSB7CgkJY2xvc2Uocy0+Y3VycmVudF9mZCk7CgkJcy0+Y3VycmVudF9mZCA9IDA7Cgl9CiAgICB9CiAgICBzLT5jdXJyZW50X2NsdXN0ZXIgPSAtMTsKfQoKLyogbWFwcGluZ3MgYmV0d2VlbiBpbmRleDEgYW5kIGluZGV4Mi0xIGFyZSBzdXBwb3NlZCB0byBiZSBvcmRlcmVkCiAqIHJldHVybiB2YWx1ZSBpcyB0aGUgaW5kZXggb2YgdGhlIGxhc3QgbWFwcGluZyBmb3Igd2hpY2ggZW5kPmNsdXN0ZXJfbnVtCiAqLwpzdGF0aWMgaW5saW5lIGludCBmaW5kX21hcHBpbmdfZm9yX2NsdXN0ZXJfYXV4KEJEUlZWVkZBVFN0YXRlKiBzLGludCBjbHVzdGVyX251bSxpbnQgaW5kZXgxLGludCBpbmRleDIpCnsKICAgIGludCBpbmRleDM9aW5kZXgxKzE7CiAgICB3aGlsZSgxKSB7CgltYXBwaW5nX3QqIG1hcHBpbmc7CglpbmRleDM9KGluZGV4MStpbmRleDIpLzI7CgltYXBwaW5nPWFycmF5X2dldCgmKHMtPm1hcHBpbmcpLGluZGV4Myk7Cglhc3NlcnQobWFwcGluZy0+YmVnaW4gPCBtYXBwaW5nLT5lbmQpOwoJaWYobWFwcGluZy0+YmVnaW4+PWNsdXN0ZXJfbnVtKSB7CgkgICAgYXNzZXJ0KGluZGV4MiE9aW5kZXgzIHx8IGluZGV4Mj09MCk7CgkgICAgaWYoaW5kZXgyPT1pbmRleDMpCgkJcmV0dXJuIGluZGV4MTsKCSAgICBpbmRleDI9aW5kZXgzOwoJfSBlbHNlIHsKCSAgICBpZihpbmRleDE9PWluZGV4MykKCQlyZXR1cm4gbWFwcGluZy0+ZW5kPD1jbHVzdGVyX251bSA/IGluZGV4MiA6IGluZGV4MTsKCSAgICBpbmRleDE9aW5kZXgzOwoJfQoJYXNzZXJ0KGluZGV4MTw9aW5kZXgyKTsKCURMT0cobWFwcGluZz1hcnJheV9nZXQoJihzLT5tYXBwaW5nKSxpbmRleDEpOwoJYXNzZXJ0KG1hcHBpbmctPmJlZ2luPD1jbHVzdGVyX251bSk7Cglhc3NlcnQoaW5kZXgyID49IHMtPm1hcHBpbmcubmV4dCB8fAoJCSgobWFwcGluZyA9IGFycmF5X2dldCgmKHMtPm1hcHBpbmcpLGluZGV4MikpICYmCgkJbWFwcGluZy0+ZW5kPmNsdXN0ZXJfbnVtKSkpOwogICAgfQp9CgpzdGF0aWMgaW5saW5lIG1hcHBpbmdfdCogZmluZF9tYXBwaW5nX2Zvcl9jbHVzdGVyKEJEUlZWVkZBVFN0YXRlKiBzLGludCBjbHVzdGVyX251bSkKewogICAgaW50IGluZGV4PWZpbmRfbWFwcGluZ19mb3JfY2x1c3Rlcl9hdXgocyxjbHVzdGVyX251bSwwLHMtPm1hcHBpbmcubmV4dCk7CiAgICBtYXBwaW5nX3QqIG1hcHBpbmc7CiAgICBpZihpbmRleD49cy0+bWFwcGluZy5uZXh0KQoJcmV0dXJuIDA7CiAgICBtYXBwaW5nPWFycmF5X2dldCgmKHMtPm1hcHBpbmcpLGluZGV4KTsKICAgIGlmKG1hcHBpbmctPmJlZ2luPmNsdXN0ZXJfbnVtKQoJcmV0dXJuIDA7CiAgICBhc3NlcnQobWFwcGluZy0+YmVnaW48PWNsdXN0ZXJfbnVtICYmIG1hcHBpbmctPmVuZD5jbHVzdGVyX251bSk7CiAgICByZXR1cm4gbWFwcGluZzsKfQoKLyoKICogVGhpcyBmdW5jdGlvbiBzaW1wbHkgY29tcGFyZXMgcGF0aCA9PSBtYXBwaW5nLT5wYXRoLiBTaW5jZSB0aGUgbWFwcGluZ3MKICogYXJlIHNvcnRlZCBieSBjbHVzdGVyLCB0aGlzIGlzIGV4cGVuc2l2ZTogTyhuKS4KICovCnN0YXRpYyBpbmxpbmUgbWFwcGluZ190KiBmaW5kX21hcHBpbmdfZm9yX3BhdGgoQkRSVlZWRkFUU3RhdGUqIHMsCgljb25zdCBjaGFyKiBwYXRoKQp7CiAgICBpbnQgaTsKCiAgICBmb3IgKGkgPSAwOyBpIDwgcy0+bWFwcGluZy5uZXh0OyBpKyspIHsKCW1hcHBpbmdfdCogbWFwcGluZyA9IGFycmF5X2dldCgmKHMtPm1hcHBpbmcpLCBpKTsKCWlmIChtYXBwaW5nLT5maXJzdF9tYXBwaW5nX2luZGV4IDwgMCAmJgoJCSFzdHJjbXAocGF0aCwgbWFwcGluZy0+cGF0aCkpCgkgICAgcmV0dXJuIG1hcHBpbmc7CiAgICB9CgogICAgcmV0dXJuIE5VTEw7Cn0KCnN0YXRpYyBpbnQgb3Blbl9maWxlKEJEUlZWVkZBVFN0YXRlKiBzLG1hcHBpbmdfdCogbWFwcGluZykKewogICAgaWYoIW1hcHBpbmcpCglyZXR1cm4gLTE7CiAgICBpZighcy0+Y3VycmVudF9tYXBwaW5nIHx8CgkgICAgc3RyY21wKHMtPmN1cnJlbnRfbWFwcGluZy0+cGF0aCxtYXBwaW5nLT5wYXRoKSkgewoJLyogb3BlbiBmaWxlICovCglpbnQgZmQgPSBvcGVuKG1hcHBpbmctPnBhdGgsIE9fUkRPTkxZIHwgT19CSU5BUlkgfCBPX0xBUkdFRklMRSk7CglpZihmZDwwKQoJICAgIHJldHVybiAtMTsKCXZ2ZmF0X2Nsb3NlX2N1cnJlbnRfZmlsZShzKTsKCXMtPmN1cnJlbnRfZmQgPSBmZDsKCXMtPmN1cnJlbnRfbWFwcGluZyA9IG1hcHBpbmc7CiAgICB9CiAgICByZXR1cm4gMDsKfQoKc3RhdGljIGlubGluZSBpbnQgcmVhZF9jbHVzdGVyKEJEUlZWVkZBVFN0YXRlICpzLGludCBjbHVzdGVyX251bSkKewogICAgaWYocy0+Y3VycmVudF9jbHVzdGVyICE9IGNsdXN0ZXJfbnVtKSB7CglpbnQgcmVzdWx0PTA7CglvZmZfdCBvZmZzZXQ7Cglhc3NlcnQoIXMtPmN1cnJlbnRfbWFwcGluZyB8fCBzLT5jdXJyZW50X2ZkIHx8IChzLT5jdXJyZW50X21hcHBpbmctPm1vZGUgJiBNT0RFX0RJUkVDVE9SWSkpOwoJaWYoIXMtPmN1cnJlbnRfbWFwcGluZwoJCXx8IHMtPmN1cnJlbnRfbWFwcGluZy0+YmVnaW4+Y2x1c3Rlcl9udW0KCQl8fCBzLT5jdXJyZW50X21hcHBpbmctPmVuZDw9Y2x1c3Rlcl9udW0pIHsKCSAgICAvKiBiaW5hcnkgc2VhcmNoIG9mIG1hcHBpbmdzIGZvciBmaWxlICovCgkgICAgbWFwcGluZ190KiBtYXBwaW5nPWZpbmRfbWFwcGluZ19mb3JfY2x1c3RlcihzLGNsdXN0ZXJfbnVtKTsKCgkgICAgYXNzZXJ0KCFtYXBwaW5nIHx8IChjbHVzdGVyX251bT49bWFwcGluZy0+YmVnaW4gJiYgY2x1c3Rlcl9udW08bWFwcGluZy0+ZW5kKSk7CgoJICAgIGlmIChtYXBwaW5nICYmIG1hcHBpbmctPm1vZGUgJiBNT0RFX0RJUkVDVE9SWSkgewoJCXZ2ZmF0X2Nsb3NlX2N1cnJlbnRfZmlsZShzKTsKCQlzLT5jdXJyZW50X21hcHBpbmcgPSBtYXBwaW5nOwpyZWFkX2NsdXN0ZXJfZGlyZWN0b3J5OgoJCW9mZnNldCA9IHMtPmNsdXN0ZXJfc2l6ZSooY2x1c3Rlcl9udW0tcy0+Y3VycmVudF9tYXBwaW5nLT5iZWdpbik7CgkJcy0+Y2x1c3RlciA9ICh1bnNpZ25lZCBjaGFyKilzLT5kaXJlY3RvcnkucG9pbnRlcitvZmZzZXQKCQkJKyAweDIwKnMtPmN1cnJlbnRfbWFwcGluZy0+aW5mby5kaXIuZmlyc3RfZGlyX2luZGV4OwoJCWFzc2VydCgoKHMtPmNsdXN0ZXItKHVuc2lnbmVkIGNoYXIqKXMtPmRpcmVjdG9yeS5wb2ludGVyKSVzLT5jbHVzdGVyX3NpemUpPT0wKTsKCQlhc3NlcnQoKGNoYXIqKXMtPmNsdXN0ZXIrcy0+Y2x1c3Rlcl9zaXplIDw9IHMtPmRpcmVjdG9yeS5wb2ludGVyK3MtPmRpcmVjdG9yeS5uZXh0KnMtPmRpcmVjdG9yeS5pdGVtX3NpemUpOwoJCXMtPmN1cnJlbnRfY2x1c3RlciA9IGNsdXN0ZXJfbnVtOwoJCXJldHVybiAwOwoJICAgIH0KCgkgICAgaWYob3Blbl9maWxlKHMsbWFwcGluZykpCgkJcmV0dXJuIC0yOwoJfSBlbHNlIGlmIChzLT5jdXJyZW50X21hcHBpbmctPm1vZGUgJiBNT0RFX0RJUkVDVE9SWSkKCSAgICBnb3RvIHJlYWRfY2x1c3Rlcl9kaXJlY3Rvcnk7CgoJYXNzZXJ0KHMtPmN1cnJlbnRfZmQpOwoKCW9mZnNldD1zLT5jbHVzdGVyX3NpemUqKGNsdXN0ZXJfbnVtLXMtPmN1cnJlbnRfbWFwcGluZy0+YmVnaW4pK3MtPmN1cnJlbnRfbWFwcGluZy0+aW5mby5maWxlLm9mZnNldDsKCWlmKGxzZWVrKHMtPmN1cnJlbnRfZmQsIG9mZnNldCwgU0VFS19TRVQpIT1vZmZzZXQpCgkgICAgcmV0dXJuIC0zOwoJcy0+Y2x1c3Rlcj1zLT5jbHVzdGVyX2J1ZmZlcjsKCXJlc3VsdD1yZWFkKHMtPmN1cnJlbnRfZmQscy0+Y2x1c3RlcixzLT5jbHVzdGVyX3NpemUpOwoJaWYocmVzdWx0PDApIHsKCSAgICBzLT5jdXJyZW50X2NsdXN0ZXIgPSAtMTsKCSAgICByZXR1cm4gLTE7Cgl9CglzLT5jdXJyZW50X2NsdXN0ZXIgPSBjbHVzdGVyX251bTsKICAgIH0KICAgIHJldHVybiAwOwp9CgojaWZkZWYgREVCVUcKc3RhdGljIHZvaWQgaGV4ZHVtcChjb25zdCB2b2lkKiBhZGRyZXNzLCB1aW50MzJfdCBsZW4pCnsKICAgIGNvbnN0IHVuc2lnbmVkIGNoYXIqIHAgPSBhZGRyZXNzOwogICAgaW50IGksIGo7CgogICAgZm9yIChpID0gMDsgaSA8IGxlbjsgaSArPSAxNikgewoJZm9yIChqID0gMDsgaiA8IDE2ICYmIGkgKyBqIDwgbGVuOyBqKyspCgkgICAgZnByaW50ZihzdGRlcnIsICIlMDJ4ICIsIHBbaSArIGpdKTsKCWZvciAoOyBqIDwgMTY7IGorKykKCSAgICBmcHJpbnRmKHN0ZGVyciwgIiAgICIpOwoJZnByaW50ZihzdGRlcnIsICIgIik7Cglmb3IgKGogPSAwOyBqIDwgMTYgJiYgaSArIGogPCBsZW47IGorKykKCSAgICBmcHJpbnRmKHN0ZGVyciwgIiVjIiwgKHBbaSArIGpdIDwgJyAnIHx8IHBbaSArIGpdID4gMHg3ZikgPyAnLicgOiBwW2kgKyBqXSk7CglmcHJpbnRmKHN0ZGVyciwgIlxuIik7CiAgICB9Cn0KCnN0YXRpYyB2b2lkIHByaW50X2RpcmVudHJ5KGNvbnN0IGRpcmVudHJ5X3QqIGRpcmVudHJ5KQp7CiAgICBpbnQgaiA9IDA7CiAgICBjaGFyIGJ1ZmZlclsxMDI0XTsKCiAgICBmcHJpbnRmKHN0ZGVyciwgImRpcmVudHJ5IDB4JXg6ICIsIChpbnQpZGlyZW50cnkpOwogICAgaWYoIWRpcmVudHJ5KQoJcmV0dXJuOwogICAgaWYoaXNfbG9uZ19uYW1lKGRpcmVudHJ5KSkgewoJdW5zaWduZWQgY2hhciogYz0odW5zaWduZWQgY2hhciopZGlyZW50cnk7CglpbnQgaTsKCWZvcihpPTE7aTwxMSAmJiBjW2ldICYmIGNbaV0hPTB4ZmY7aSs9MikKI2RlZmluZSBBRERfQ0hBUihjKSB7YnVmZmVyW2pdID0gKGMpOyBpZiAoYnVmZmVyW2pdIDwgJyAnKSBidWZmZXJbal0gPSAnsCc7IGorKzt9CgkgICAgQUREX0NIQVIoY1tpXSk7Cglmb3IoaT0xNDtpPDI2ICYmIGNbaV0gJiYgY1tpXSE9MHhmZjtpKz0yKQoJICAgIEFERF9DSEFSKGNbaV0pOwoJZm9yKGk9Mjg7aTwzMiAmJiBjW2ldICYmIGNbaV0hPTB4ZmY7aSs9MikKCSAgICBBRERfQ0hBUihjW2ldKTsKCWJ1ZmZlcltqXSA9IDA7CglmcHJpbnRmKHN0ZGVyciwgIiVzXG4iLCBidWZmZXIpOwogICAgfSBlbHNlIHsKCWludCBpOwoJZm9yKGk9MDtpPDExO2krKykKCSAgICBBRERfQ0hBUihkaXJlbnRyeS0+bmFtZVtpXSk7CglidWZmZXJbal0gPSAwOwoJZnByaW50ZihzdGRlcnIsIiVzIGF0dHJpYnV0ZXM9MHglMDJ4IGJlZ2luPSVkIHNpemU9JWRcbiIsCgkJYnVmZmVyLAoJCWRpcmVudHJ5LT5hdHRyaWJ1dGVzLAoJCWJlZ2luX29mX2RpcmVudHJ5KGRpcmVudHJ5KSxsZTMyX3RvX2NwdShkaXJlbnRyeS0+c2l6ZSkpOwogICAgfQp9CgpzdGF0aWMgdm9pZCBwcmludF9tYXBwaW5nKGNvbnN0IG1hcHBpbmdfdCogbWFwcGluZykKewogICAgZnByaW50ZihzdGRlcnIsICJtYXBwaW5nICgweCV4KTogYmVnaW4sIGVuZCA9ICVkLCAlZCwgZGlyX2luZGV4ID0gJWQsIGZpcnN0X21hcHBpbmdfaW5kZXggPSAlZCwgbmFtZSA9ICVzLCBtb2RlID0gMHgleCwgIiAsIChpbnQpbWFwcGluZywgbWFwcGluZy0+YmVnaW4sIG1hcHBpbmctPmVuZCwgbWFwcGluZy0+ZGlyX2luZGV4LCBtYXBwaW5nLT5maXJzdF9tYXBwaW5nX2luZGV4LCBtYXBwaW5nLT5wYXRoLCBtYXBwaW5nLT5tb2RlKTsKICAgIGlmIChtYXBwaW5nLT5tb2RlICYgTU9ERV9ESVJFQ1RPUlkpCglmcHJpbnRmKHN0ZGVyciwgInBhcmVudF9tYXBwaW5nX2luZGV4ID0gJWQsIGZpcnN0X2Rpcl9pbmRleCA9ICVkXG4iLCBtYXBwaW5nLT5pbmZvLmRpci5wYXJlbnRfbWFwcGluZ19pbmRleCwgbWFwcGluZy0+aW5mby5kaXIuZmlyc3RfZGlyX2luZGV4KTsKICAgIGVsc2UKCWZwcmludGYoc3RkZXJyLCAib2Zmc2V0ID0gJWRcbiIsIG1hcHBpbmctPmluZm8uZmlsZS5vZmZzZXQpOwp9CiNlbmRpZgoKc3RhdGljIGludCB2dmZhdF9yZWFkKEJsb2NrRHJpdmVyU3RhdGUgKmJzLCBpbnQ2NF90IHNlY3Rvcl9udW0sCiAgICAgICAgICAgICAgICAgICAgdWludDhfdCAqYnVmLCBpbnQgbmJfc2VjdG9ycykKewogICAgQkRSVlZWRkFUU3RhdGUgKnMgPSBicy0+b3BhcXVlOwogICAgaW50IGk7CgogICAgZm9yKGk9MDtpPG5iX3NlY3RvcnM7aSsrLHNlY3Rvcl9udW0rKykgewoJaWYgKHNlY3Rvcl9udW0gPj0gcy0+c2VjdG9yX2NvdW50KQoJICAgcmV0dXJuIC0xOwoJaWYgKHMtPnFjb3cpIHsKCSAgICBpbnQgbjsKCSAgICBpZiAocy0+cWNvdy0+ZHJ2LT5iZHJ2X2lzX2FsbG9jYXRlZChzLT5xY293LAoJCQlzZWN0b3JfbnVtLCBuYl9zZWN0b3JzLWksICZuKSkgewpETE9HKGZwcmludGYoc3RkZXJyLCAic2VjdG9ycyAlZCslZCBhbGxvY2F0ZWRcbiIsIChpbnQpc2VjdG9yX251bSwgbikpOwoJCWlmIChzLT5xY293LT5kcnYtPmJkcnZfcmVhZChzLT5xY293LCBzZWN0b3JfbnVtLCBidWYraSoweDIwMCwgbikpCgkJICAgIHJldHVybiAtMTsKCQlpICs9IG4gLSAxOwoJCXNlY3Rvcl9udW0gKz0gbiAtIDE7CgkJY29udGludWU7CgkgICAgfQpETE9HKGZwcmludGYoc3RkZXJyLCAic2VjdG9yICVkIG5vdCBhbGxvY2F0ZWRcbiIsIChpbnQpc2VjdG9yX251bSkpOwoJfQoJaWYoc2VjdG9yX251bTxzLT5mYWtlZF9zZWN0b3JzKSB7CgkgICAgaWYoc2VjdG9yX251bTxzLT5maXJzdF9zZWN0b3JzX251bWJlcikKCQltZW1jcHkoYnVmK2kqMHgyMDAsJihzLT5maXJzdF9zZWN0b3JzW3NlY3Rvcl9udW0qMHgyMDBdKSwweDIwMCk7CgkgICAgZWxzZSBpZihzZWN0b3JfbnVtLXMtPmZpcnN0X3NlY3RvcnNfbnVtYmVyPHMtPnNlY3RvcnNfcGVyX2ZhdCkKCQltZW1jcHkoYnVmK2kqMHgyMDAsJihzLT5mYXQucG9pbnRlclsoc2VjdG9yX251bS1zLT5maXJzdF9zZWN0b3JzX251bWJlcikqMHgyMDBdKSwweDIwMCk7CgkgICAgZWxzZSBpZihzZWN0b3JfbnVtLXMtPmZpcnN0X3NlY3RvcnNfbnVtYmVyLXMtPnNlY3RvcnNfcGVyX2ZhdDxzLT5zZWN0b3JzX3Blcl9mYXQpCgkJbWVtY3B5KGJ1ZitpKjB4MjAwLCYocy0+ZmF0LnBvaW50ZXJbKHNlY3Rvcl9udW0tcy0+Zmlyc3Rfc2VjdG9yc19udW1iZXItcy0+c2VjdG9yc19wZXJfZmF0KSoweDIwMF0pLDB4MjAwKTsKCX0gZWxzZSB7CgkgICAgdWludDMyX3Qgc2VjdG9yPXNlY3Rvcl9udW0tcy0+ZmFrZWRfc2VjdG9ycywKCSAgICBzZWN0b3Jfb2Zmc2V0X2luX2NsdXN0ZXI9KHNlY3RvciVzLT5zZWN0b3JzX3Blcl9jbHVzdGVyKSwKCSAgICBjbHVzdGVyX251bT1zZWN0b3Ivcy0+c2VjdG9yc19wZXJfY2x1c3RlcjsKCSAgICBpZihyZWFkX2NsdXN0ZXIocywgY2x1c3Rlcl9udW0pICE9IDApIHsKCQkvKiBMQVRFUiBUT0RPOiBzdHJpY3Q6IHJldHVybiAtMTsgKi8KCQltZW1zZXQoYnVmK2kqMHgyMDAsMCwweDIwMCk7CgkJY29udGludWU7CgkgICAgfQoJICAgIG1lbWNweShidWYraSoweDIwMCxzLT5jbHVzdGVyK3NlY3Rvcl9vZmZzZXRfaW5fY2x1c3RlcioweDIwMCwweDIwMCk7Cgl9CiAgICB9CiAgICByZXR1cm4gMDsKfQoKLyogTEFURVIgVE9ETzogc3RhdGlmeSBhbGwgZnVuY3Rpb25zICovCgovKgogKiBJZGVhIG9mIHRoZSB3cml0ZSBzdXBwb3J0ICh1c2Ugc25hcHNob3QpOgogKgogKiAxLiBjaGVjayBpZiBhbGwgZGF0YSBpcyBjb25zaXN0ZW50LCByZWNvcmRpbmcgcmVuYW1lcywgbW9kaWZpY2F0aW9ucywKICogICAgbmV3IGZpbGVzIGFuZCBkaXJlY3RvcmllcyAoaW4gcy0+Y29tbWl0cykuCiAqCiAqIDIuIGlmIHRoZSBkYXRhIGlzIG5vdCBjb25zaXN0ZW50LCBzdG9wIGNvbW1pdHRpbmcKICoKICogMy4gaGFuZGxlIHJlbmFtZXMsIGFuZCBjcmVhdGUgbmV3IGZpbGVzIGFuZCBkaXJlY3RvcmllcyAoZG8gbm90IHlldAogKiAgICB3cml0ZSB0aGVpciBjb250ZW50cykKICoKICogNC4gd2FsayB0aGUgZGlyZWN0b3JpZXMsIGZpeGluZyB0aGUgbWFwcGluZyBhbmQgZGlyZW50cmllcywgYW5kIG1hcmtpbmcKICogICAgdGhlIGhhbmRsZWQgbWFwcGluZ3MgYXMgbm90IGRlbGV0ZWQKICoKICogNS4gY29tbWl0IHRoZSBjb250ZW50cyBvZiB0aGUgZmlsZXMKICoKICogNi4gaGFuZGxlIGRlbGV0ZWQgZmlsZXMgYW5kIGRpcmVjdG9yaWVzCiAqCiAqLwoKdHlwZWRlZiBzdHJ1Y3QgY29tbWl0X3QgewogICAgY2hhciogcGF0aDsKICAgIHVuaW9uIHsKCXN0cnVjdCB7IHVpbnQzMl90IGNsdXN0ZXI7IH0gcmVuYW1lOwoJc3RydWN0IHsgaW50IGRpcl9pbmRleDsgdWludDMyX3QgbW9kaWZpZWRfb2Zmc2V0OyB9IHdyaXRlb3V0OwoJc3RydWN0IHsgdWludDMyX3QgZmlyc3RfY2x1c3RlcjsgfSBuZXdfZmlsZTsKCXN0cnVjdCB7IHVpbnQzMl90IGNsdXN0ZXI7IH0gbWtkaXI7CiAgICB9IHBhcmFtOwogICAgLyogREVMRVRFcyBhbmQgUk1ESVJzIGFyZSBoYW5kbGVkIGRpZmZlcmVudGx5OiBzZWUgaGFuZGxlX2RlbGV0ZXMoKSAqLwogICAgZW51bSB7CglBQ1RJT05fUkVOQU1FLCBBQ1RJT05fV1JJVEVPVVQsIEFDVElPTl9ORVdfRklMRSwgQUNUSU9OX01LRElSCiAgICB9IGFjdGlvbjsKfSBjb21taXRfdDsKCnN0YXRpYyB2b2lkIGNsZWFyX2NvbW1pdHMoQkRSVlZWRkFUU3RhdGUqIHMpCnsKICAgIGludCBpOwpETE9HKGZwcmludGYoc3RkZXJyLCAiY2xlYXJfY29tbWl0cyAoJWQgY29tbWl0cylcbiIsIHMtPmNvbW1pdHMubmV4dCkpOwogICAgZm9yIChpID0gMDsgaSA8IHMtPmNvbW1pdHMubmV4dDsgaSsrKSB7Cgljb21taXRfdCogY29tbWl0ID0gYXJyYXlfZ2V0KCYocy0+Y29tbWl0cyksIGkpOwoJYXNzZXJ0KGNvbW1pdC0+cGF0aCB8fCBjb21taXQtPmFjdGlvbiA9PSBBQ1RJT05fV1JJVEVPVVQpOwoJaWYgKGNvbW1pdC0+YWN0aW9uICE9IEFDVElPTl9XUklURU9VVCkgewoJICAgIGFzc2VydChjb21taXQtPnBhdGgpOwoJICAgIGZyZWUoY29tbWl0LT5wYXRoKTsKCX0gZWxzZQoJICAgIGFzc2VydChjb21taXQtPnBhdGggPT0gTlVMTCk7CiAgICB9CiAgICBzLT5jb21taXRzLm5leHQgPSAwOwp9CgpzdGF0aWMgdm9pZCBzY2hlZHVsZV9yZW5hbWUoQkRSVlZWRkFUU3RhdGUqIHMsCgl1aW50MzJfdCBjbHVzdGVyLCBjaGFyKiBuZXdfcGF0aCkKewogICAgY29tbWl0X3QqIGNvbW1pdCA9IGFycmF5X2dldF9uZXh0KCYocy0+Y29tbWl0cykpOwogICAgY29tbWl0LT5wYXRoID0gbmV3X3BhdGg7CiAgICBjb21taXQtPnBhcmFtLnJlbmFtZS5jbHVzdGVyID0gY2x1c3RlcjsKICAgIGNvbW1pdC0+YWN0aW9uID0gQUNUSU9OX1JFTkFNRTsKfQoKc3RhdGljIHZvaWQgc2NoZWR1bGVfd3JpdGVvdXQoQkRSVlZWRkFUU3RhdGUqIHMsCglpbnQgZGlyX2luZGV4LCB1aW50MzJfdCBtb2RpZmllZF9vZmZzZXQpCnsKICAgIGNvbW1pdF90KiBjb21taXQgPSBhcnJheV9nZXRfbmV4dCgmKHMtPmNvbW1pdHMpKTsKICAgIGNvbW1pdC0+cGF0aCA9IE5VTEw7CiAgICBjb21taXQtPnBhcmFtLndyaXRlb3V0LmRpcl9pbmRleCA9IGRpcl9pbmRleDsKICAgIGNvbW1pdC0+cGFyYW0ud3JpdGVvdXQubW9kaWZpZWRfb2Zmc2V0ID0gbW9kaWZpZWRfb2Zmc2V0OwogICAgY29tbWl0LT5hY3Rpb24gPSBBQ1RJT05fV1JJVEVPVVQ7Cn0KCnN0YXRpYyB2b2lkIHNjaGVkdWxlX25ld19maWxlKEJEUlZWVkZBVFN0YXRlKiBzLAoJY2hhciogcGF0aCwgdWludDMyX3QgZmlyc3RfY2x1c3RlcikKewogICAgY29tbWl0X3QqIGNvbW1pdCA9IGFycmF5X2dldF9uZXh0KCYocy0+Y29tbWl0cykpOwogICAgY29tbWl0LT5wYXRoID0gcGF0aDsKICAgIGNvbW1pdC0+cGFyYW0ubmV3X2ZpbGUuZmlyc3RfY2x1c3RlciA9IGZpcnN0X2NsdXN0ZXI7CiAgICBjb21taXQtPmFjdGlvbiA9IEFDVElPTl9ORVdfRklMRTsKfQoKc3RhdGljIHZvaWQgc2NoZWR1bGVfbWtkaXIoQkRSVlZWRkFUU3RhdGUqIHMsIHVpbnQzMl90IGNsdXN0ZXIsIGNoYXIqIHBhdGgpCnsKICAgIGNvbW1pdF90KiBjb21taXQgPSBhcnJheV9nZXRfbmV4dCgmKHMtPmNvbW1pdHMpKTsKICAgIGNvbW1pdC0+cGF0aCA9IHBhdGg7CiAgICBjb21taXQtPnBhcmFtLm1rZGlyLmNsdXN0ZXIgPSBjbHVzdGVyOwogICAgY29tbWl0LT5hY3Rpb24gPSBBQ1RJT05fTUtESVI7Cn0KCnR5cGVkZWYgc3RydWN0IHsKICAgIHVuc2lnbmVkIGNoYXIgbmFtZVsxMDI0XTsKICAgIGludCBjaGVja3N1bSwgbGVuOwogICAgaW50IHNlcXVlbmNlX251bWJlcjsKfSBsb25nX2ZpbGVfbmFtZTsKCnN0YXRpYyB2b2lkIGxmbl9pbml0KGxvbmdfZmlsZV9uYW1lKiBsZm4pCnsKICAgbGZuLT5zZXF1ZW5jZV9udW1iZXIgPSBsZm4tPmxlbiA9IDA7CiAgIGxmbi0+Y2hlY2tzdW0gPSAweDEwMDsKfQoKLyogcmV0dXJuIDAgaWYgcGFyc2VkIHN1Y2Nlc3NmdWxseSwgPiAwIGlmIG5vIGxvbmcgbmFtZSwgPCAwIGlmIGVycm9yICovCnN0YXRpYyBpbnQgcGFyc2VfbG9uZ19uYW1lKGxvbmdfZmlsZV9uYW1lKiBsZm4sCgljb25zdCBkaXJlbnRyeV90KiBkaXJlbnRyeSkKewogICAgaW50IGksIGosIG9mZnNldDsKICAgIGNvbnN0IHVuc2lnbmVkIGNoYXIqIHBvaW50ZXIgPSAoY29uc3QgdW5zaWduZWQgY2hhciopZGlyZW50cnk7CgogICAgaWYgKCFpc19sb25nX25hbWUoZGlyZW50cnkpKQoJcmV0dXJuIDE7CgogICAgaWYgKHBvaW50ZXJbMF0gJiAweDQwKSB7CglsZm4tPnNlcXVlbmNlX251bWJlciA9IHBvaW50ZXJbMF0gJiAweDNmOwoJbGZuLT5jaGVja3N1bSA9IHBvaW50ZXJbMTNdOwoJbGZuLT5uYW1lWzBdID0gMDsKICAgIH0gZWxzZSBpZiAoKHBvaW50ZXJbMF0gJiAweDNmKSAhPSAtLWxmbi0+c2VxdWVuY2VfbnVtYmVyKQoJcmV0dXJuIC0xOwogICAgZWxzZSBpZiAocG9pbnRlclsxM10gIT0gbGZuLT5jaGVja3N1bSkKCXJldHVybiAtMjsKICAgIGVsc2UgaWYgKHBvaW50ZXJbMTJdIHx8IHBvaW50ZXJbMjZdIHx8IHBvaW50ZXJbMjddKQoJcmV0dXJuIC0zOwoKICAgIG9mZnNldCA9IDEzICogKGxmbi0+c2VxdWVuY2VfbnVtYmVyIC0gMSk7CiAgICBmb3IgKGkgPSAwLCBqID0gMTsgaSA8IDEzOyBpKyssIGorPTIpIHsKCWlmIChqID09IDExKQoJICAgIGogPSAxNDsKCWVsc2UgaWYgKGogPT0gMjYpCgkgICAgaiA9IDI4OwoKCWlmIChwb2ludGVyW2orMV0gPT0gMCkKCSAgICBsZm4tPm5hbWVbb2Zmc2V0ICsgaV0gPSBwb2ludGVyW2pdOwoJZWxzZSBpZiAocG9pbnRlcltqKzFdICE9IDB4ZmYgfHwgKHBvaW50ZXJbMF0gJiAweDQwKSA9PSAwKQoJICAgIHJldHVybiAtNDsKCWVsc2UKCSAgICBsZm4tPm5hbWVbb2Zmc2V0ICsgaV0gPSAwOwogICAgfQoKICAgIGlmIChwb2ludGVyWzBdICYgMHg0MCkKCWxmbi0+bGVuID0gb2Zmc2V0ICsgc3RybGVuKChjaGFyKilsZm4tPm5hbWUgKyBvZmZzZXQpOwoKICAgIHJldHVybiAwOwp9CgovKiByZXR1cm5zIDAgaWYgc3VjY2Vzc2Z1bCwgPjAgaWYgbm8gc2hvcnRfbmFtZSwgYW5kIDwwIG9uIGVycm9yICovCnN0YXRpYyBpbnQgcGFyc2Vfc2hvcnRfbmFtZShCRFJWVlZGQVRTdGF0ZSogcywKCWxvbmdfZmlsZV9uYW1lKiBsZm4sIGRpcmVudHJ5X3QqIGRpcmVudHJ5KQp7CiAgICBpbnQgaSwgajsKCiAgICBpZiAoIWlzX3Nob3J0X25hbWUoZGlyZW50cnkpKQoJcmV0dXJuIDE7CgogICAgZm9yIChqID0gNzsgaiA+PSAwICYmIGRpcmVudHJ5LT5uYW1lW2pdID09ICcgJzsgai0tKTsKICAgIGZvciAoaSA9IDA7IGkgPD0gajsgaSsrKSB7CglpZiAoZGlyZW50cnktPm5hbWVbaV0gPD0gJyAnIHx8IGRpcmVudHJ5LT5uYW1lW2ldID4gMHg3ZikKCSAgICByZXR1cm4gLTE7CgllbHNlIGlmIChzLT5kb3duY2FzZV9zaG9ydF9uYW1lcykKCSAgICBsZm4tPm5hbWVbaV0gPSB0b2xvd2VyKGRpcmVudHJ5LT5uYW1lW2ldKTsKCWVsc2UKCSAgICBsZm4tPm5hbWVbaV0gPSBkaXJlbnRyeS0+bmFtZVtpXTsKICAgIH0KCiAgICBmb3IgKGogPSAyOyBqID49IDAgJiYgZGlyZW50cnktPmV4dGVuc2lvbltqXSA9PSAnICc7IGotLSk7CiAgICBpZiAoaiA+PSAwKSB7CglsZm4tPm5hbWVbaSsrXSA9ICcuJzsKCWxmbi0+bmFtZVtpICsgaiArIDFdID0gJ1wwJzsKCWZvciAoO2ogPj0gMDsgai0tKSB7CgkgICAgaWYgKGRpcmVudHJ5LT5leHRlbnNpb25bal0gPD0gJyAnIHx8IGRpcmVudHJ5LT5leHRlbnNpb25bal0gPiAweDdmKQoJCXJldHVybiAtMjsKCSAgICBlbHNlIGlmIChzLT5kb3duY2FzZV9zaG9ydF9uYW1lcykKCQlsZm4tPm5hbWVbaSArIGpdID0gdG9sb3dlcihkaXJlbnRyeS0+ZXh0ZW5zaW9uW2pdKTsKCSAgICBlbHNlCgkJbGZuLT5uYW1lW2kgKyBqXSA9IGRpcmVudHJ5LT5leHRlbnNpb25bal07Cgl9CiAgICB9IGVsc2UKCWxmbi0+bmFtZVtpICsgaiArIDFdID0gJ1wwJzsKCiAgICBsZm4tPmxlbiA9IHN0cmxlbigoY2hhciopbGZuLT5uYW1lKTsKCiAgICByZXR1cm4gMDsKfQoKc3RhdGljIGlubGluZSB1aW50MzJfdCBtb2RpZmllZF9mYXRfZ2V0KEJEUlZWVkZBVFN0YXRlKiBzLAoJdW5zaWduZWQgaW50IGNsdXN0ZXIpCnsKICAgIGlmIChjbHVzdGVyIDwgcy0+bGFzdF9jbHVzdGVyX29mX3Jvb3RfZGlyZWN0b3J5KSB7CglpZiAoY2x1c3RlciArIDEgPT0gcy0+bGFzdF9jbHVzdGVyX29mX3Jvb3RfZGlyZWN0b3J5KQoJICAgIHJldHVybiBzLT5tYXhfZmF0X3ZhbHVlOwoJZWxzZQoJICAgIHJldHVybiBjbHVzdGVyICsgMTsKICAgIH0KCiAgICBpZiAocy0+ZmF0X3R5cGU9PTMyKSB7CiAgICAgICAgdWludDMyX3QqIGVudHJ5PSgodWludDMyX3QqKXMtPmZhdDIpK2NsdXN0ZXI7CiAgICAgICAgcmV0dXJuIGxlMzJfdG9fY3B1KCplbnRyeSk7CiAgICB9IGVsc2UgaWYgKHMtPmZhdF90eXBlPT0xNikgewogICAgICAgIHVpbnQxNl90KiBlbnRyeT0oKHVpbnQxNl90KilzLT5mYXQyKStjbHVzdGVyOwogICAgICAgIHJldHVybiBsZTE2X3RvX2NwdSgqZW50cnkpOwogICAgfSBlbHNlIHsKICAgICAgICBjb25zdCB1aW50OF90KiB4PXMtPmZhdDIrY2x1c3RlciozLzI7CiAgICAgICAgcmV0dXJuICgoeFswXXwoeFsxXTw8OCkpPj4oY2x1c3RlciYxPzQ6MCkpJjB4MGZmZjsKICAgIH0KfQoKc3RhdGljIGlubGluZSBpbnQgY2x1c3Rlcl93YXNfbW9kaWZpZWQoQkRSVlZWRkFUU3RhdGUqIHMsIHVpbnQzMl90IGNsdXN0ZXJfbnVtKQp7CiAgICBpbnQgd2FzX21vZGlmaWVkID0gMDsKICAgIGludCBpLCBkdW1teTsKCiAgICBpZiAocy0+cWNvdyA9PSBOVUxMKQoJcmV0dXJuIDA7CgogICAgZm9yIChpID0gMDsgIXdhc19tb2RpZmllZCAmJiBpIDwgcy0+c2VjdG9yc19wZXJfY2x1c3RlcjsgaSsrKQoJd2FzX21vZGlmaWVkID0gcy0+cWNvdy0+ZHJ2LT5iZHJ2X2lzX2FsbG9jYXRlZChzLT5xY293LAoJCWNsdXN0ZXIyc2VjdG9yKHMsIGNsdXN0ZXJfbnVtKSArIGksIDEsICZkdW1teSk7CgogICAgcmV0dXJuIHdhc19tb2RpZmllZDsKfQoKc3RhdGljIGNvbnN0IGNoYXIqIGdldF9iYXNlbmFtZShjb25zdCBjaGFyKiBwYXRoKQp7CiAgICBjaGFyKiBiYXNlbmFtZSA9IHN0cnJjaHIocGF0aCwgJy8nKTsKICAgIGlmIChiYXNlbmFtZSA9PSBOVUxMKQoJcmV0dXJuIHBhdGg7CiAgICBlbHNlCglyZXR1cm4gYmFzZW5hbWUgKyAxOyAvKiBzdHJpcCAnLycgKi8KfQoKLyoKICogVGhlIGFycmF5IHMtPnVzZWRfY2x1c3RlcnMgaG9sZHMgdGhlIHN0YXRlcyBvZiB0aGUgY2x1c3RlcnMuIElmIGl0IGlzCiAqIHBhcnQgb2YgYSBmaWxlLCBpdCBoYXMgYml0IDIgc2V0LCBpbiBjYXNlIG9mIGEgZGlyZWN0b3J5LCBiaXQgMS4gSWYgaXQKICogd2FzIG1vZGlmaWVkLCBiaXQgMyBpcyBzZXQuCiAqIElmIGFueSBjbHVzdGVyIGlzIGFsbG9jYXRlZCwgYnV0IG5vdCBwYXJ0IG9mIGEgZmlsZSBvciBkaXJlY3RvcnksIHRoaXMKICogZHJpdmVyIHJlZnVzZXMgdG8gY29tbWl0LgogKi8KdHlwZWRlZiBlbnVtIHsKICAgICBVU0VEX0RJUkVDVE9SWSA9IDEsIFVTRURfRklMRSA9IDIsIFVTRURfQU5ZID0gMywgVVNFRF9BTExPQ0FURUQgPSA0Cn0gdXNlZF90OwoKLyoKICogZ2V0X2NsdXN0ZXJfY291bnRfZm9yX2RpcmVudHJ5KCkgbm90IG9ubHkgZGV0ZXJtaW5lcyBob3cgbWFueSBjbHVzdGVycwogKiBhcmUgb2NjdXBpZWQgYnkgZGlyZW50cnksIGJ1dCBhbHNvIGlmIGl0IHdhcyByZW5hbWVkIG9yIG1vZGlmaWVkLgogKgogKiBBIGZpbGUgaXMgdGhvdWdodCB0byBiZSByZW5hbWVkICpvbmx5KiBpZiB0aGVyZSBhbHJlYWR5IHdhcyBhIGZpbGUgd2l0aAogKiBleGFjdGx5IHRoZSBzYW1lIGZpcnN0IGNsdXN0ZXIsIGJ1dCBhIGRpZmZlcmVudCBuYW1lLgogKgogKiBGdXJ0aGVyLCB0aGUgZmlsZXMvZGlyZWN0b3JpZXMgaGFuZGxlZCBieSB0aGlzIGZ1bmN0aW9uIGFyZQogKiBhc3N1bWVkIHRvIGJlICpub3QqIGRlbGV0ZWQgKGFuZCAqb25seSogdGhvc2UpLgogKi8Kc3RhdGljIHVpbnQzMl90IGdldF9jbHVzdGVyX2NvdW50X2Zvcl9kaXJlbnRyeShCRFJWVlZGQVRTdGF0ZSogcywKCWRpcmVudHJ5X3QqIGRpcmVudHJ5LCBjb25zdCBjaGFyKiBwYXRoKQp7CiAgICAvKgogICAgICogVGhpcyBpcyBhIGxpdHRsZSBiaXQgdHJpY2t5OgogICAgICogSUYgdGhlIGd1ZXN0IE9TIGp1c3QgaW5zZXJ0cyBhIGNsdXN0ZXIgaW50byB0aGUgZmlsZSBjaGFpbiwKICAgICAqIGFuZCBsZWF2ZXMgdGhlIHJlc3QgYWxvbmUsIChpLmUuIHRoZSBvcmlnaW5hbCBmaWxlIGhhZCBjbHVzdGVycwogICAgICogMTUgLT4gMTYsIGJ1dCBub3cgaGFzIDE1IC0+IDMyIC0+IDE2KSwgdGhlbiB0aGUgZm9sbG93aW5nIGhhcHBlbnM6CiAgICAgKgogICAgICogLSBkb19jb21taXQgd2lsbCB3cml0ZSB0aGUgY2x1c3RlciBpbnRvIHRoZSBmaWxlIGF0IHRoZSBnaXZlbgogICAgICogICBvZmZzZXQsIGJ1dAogICAgICoKICAgICAqIC0gdGhlIGNsdXN0ZXIgd2hpY2ggaXMgb3ZlcndyaXR0ZW4gc2hvdWxkIGJlIG1vdmVkIHRvIGEgbGF0ZXIKICAgICAqICAgcG9zaXRpb24gaW4gdGhlIGZpbGUuCiAgICAgKgogICAgICogSSBhbSBub3QgYXdhcmUgdGhhdCBhbnkgT1MgZG9lcyBzb21ldGhpbmcgYXMgYnJhaW5kZWFkLCBidXQgdGhpcwogICAgICogc2l0dWF0aW9uIGNvdWxkIGhhcHBlbiBhbnl3YXkgd2hlbiBub3QgY29tbWl0dGluZyBmb3IgYSBsb25nIHRpbWUuCiAgICAgKiBKdXN0IHRvIGJlIHN1cmUgdGhhdCB0aGlzIGRvZXMgbm90IGJpdGUgdXMsIGRldGVjdCBpdCwgYW5kIGNvcHkgdGhlCiAgICAgKiBjb250ZW50cyBvZiB0aGUgY2x1c3RlcnMgdG8tYmUtb3ZlcndyaXR0ZW4gaW50byB0aGUgcWNvdy4KICAgICAqLwogICAgaW50IGNvcHlfaXQgPSAwOwogICAgaW50IHdhc19tb2RpZmllZCA9IDA7CiAgICBpbnQzMl90IHJldCA9IDA7CgogICAgdWludDMyX3QgY2x1c3Rlcl9udW0gPSBiZWdpbl9vZl9kaXJlbnRyeShkaXJlbnRyeSk7CiAgICB1aW50MzJfdCBvZmZzZXQgPSAwOwogICAgaW50IGZpcnN0X21hcHBpbmdfaW5kZXggPSAtMTsKICAgIG1hcHBpbmdfdCogbWFwcGluZyA9IE5VTEw7CiAgICBjb25zdCBjaGFyKiBiYXNlbmFtZTIgPSBOVUxMOwoKICAgIHZ2ZmF0X2Nsb3NlX2N1cnJlbnRfZmlsZShzKTsKCiAgICAvKiB0aGUgcm9vdCBkaXJlY3RvcnkgKi8KICAgIGlmIChjbHVzdGVyX251bSA9PSAwKQoJcmV0dXJuIDA7CgogICAgLyogd3JpdGUgc3VwcG9ydCAqLwogICAgaWYgKHMtPnFjb3cpIHsKCWJhc2VuYW1lMiA9IGdldF9iYXNlbmFtZShwYXRoKTsKCgltYXBwaW5nID0gZmluZF9tYXBwaW5nX2Zvcl9jbHVzdGVyKHMsIGNsdXN0ZXJfbnVtKTsKCglpZiAobWFwcGluZykgewoJICAgIGNvbnN0IGNoYXIqIGJhc2VuYW1lOwoKCSAgICBhc3NlcnQobWFwcGluZy0+bW9kZSAmIE1PREVfREVMRVRFRCk7CgkgICAgbWFwcGluZy0+bW9kZSAmPSB+TU9ERV9ERUxFVEVEOwoKCSAgICBiYXNlbmFtZSA9IGdldF9iYXNlbmFtZShtYXBwaW5nLT5wYXRoKTsKCgkgICAgYXNzZXJ0KG1hcHBpbmctPm1vZGUgJiBNT0RFX05PUk1BTCk7CgoJICAgIC8qIHJlbmFtZSAqLwoJICAgIGlmIChzdHJjbXAoYmFzZW5hbWUsIGJhc2VuYW1lMikpCgkJc2NoZWR1bGVfcmVuYW1lKHMsIGNsdXN0ZXJfbnVtLCBzdHJkdXAocGF0aCkpOwoJfSBlbHNlIGlmIChpc19maWxlKGRpcmVudHJ5KSkKCSAgICAvKiBuZXcgZmlsZSAqLwoJICAgIHNjaGVkdWxlX25ld19maWxlKHMsIHN0cmR1cChwYXRoKSwgY2x1c3Rlcl9udW0pOwoJZWxzZSB7CgkgICAgYXNzZXJ0KDApOwoJICAgIHJldHVybiAwOwoJfQogICAgfQoKICAgIHdoaWxlKDEpIHsKCWlmIChzLT5xY293KSB7CgkgICAgaWYgKCFjb3B5X2l0ICYmIGNsdXN0ZXJfd2FzX21vZGlmaWVkKHMsIGNsdXN0ZXJfbnVtKSkgewoJCWlmIChtYXBwaW5nID09IE5VTEwgfHwKCQkJbWFwcGluZy0+YmVnaW4gPiBjbHVzdGVyX251bSB8fAoJCQltYXBwaW5nLT5lbmQgPD0gY2x1c3Rlcl9udW0pCgkJbWFwcGluZyA9IGZpbmRfbWFwcGluZ19mb3JfY2x1c3RlcihzLCBjbHVzdGVyX251bSk7CgoKCQlpZiAobWFwcGluZyAmJgoJCQkobWFwcGluZy0+bW9kZSAmIE1PREVfRElSRUNUT1JZKSA9PSAwKSB7CgoJCSAgICAvKiB3YXMgbW9kaWZpZWQgaW4gcWNvdyAqLwoJCSAgICBpZiAob2Zmc2V0ICE9IG1hcHBpbmctPmluZm8uZmlsZS5vZmZzZXQgKyBzLT5jbHVzdGVyX3NpemUKCQkJICAgICogKGNsdXN0ZXJfbnVtIC0gbWFwcGluZy0+YmVnaW4pKSB7CgkJCS8qIG9mZnNldCBvZiB0aGlzIGNsdXN0ZXIgaW4gZmlsZSBjaGFpbiBoYXMgY2hhbmdlZCAqLwoJCQlhc3NlcnQoMCk7CgkJCWNvcHlfaXQgPSAxOwoJCSAgICB9IGVsc2UgaWYgKG9mZnNldCA9PSAwKSB7CgkJCWNvbnN0IGNoYXIqIGJhc2VuYW1lID0gZ2V0X2Jhc2VuYW1lKG1hcHBpbmctPnBhdGgpOwoKCQkJaWYgKHN0cmNtcChiYXNlbmFtZSwgYmFzZW5hbWUyKSkKCQkJICAgIGNvcHlfaXQgPSAxOwoJCQlmaXJzdF9tYXBwaW5nX2luZGV4ID0gYXJyYXlfaW5kZXgoJihzLT5tYXBwaW5nKSwgbWFwcGluZyk7CgkJICAgIH0KCgkJICAgIGlmIChtYXBwaW5nLT5maXJzdF9tYXBwaW5nX2luZGV4ICE9IGZpcnN0X21hcHBpbmdfaW5kZXgKCQkJICAgICYmIG1hcHBpbmctPmluZm8uZmlsZS5vZmZzZXQgPiAwKSB7CgkJCWFzc2VydCgwKTsKCQkJY29weV9pdCA9IDE7CgkJICAgIH0KCgkJICAgIC8qIG5lZWQgdG8gd3JpdGUgb3V0PyAqLwoJCSAgICBpZiAoIXdhc19tb2RpZmllZCAmJiBpc19maWxlKGRpcmVudHJ5KSkgewoJCQl3YXNfbW9kaWZpZWQgPSAxOwoJCQlzY2hlZHVsZV93cml0ZW91dChzLCBtYXBwaW5nLT5kaXJfaW5kZXgsIG9mZnNldCk7CgkJICAgIH0KCQl9CgkgICAgfQoKCSAgICBpZiAoY29weV9pdCkgewoJCWludCBpLCBkdW1teTsKCQkvKgoJCSAqIFRoaXMgaXMgaG9ycmlibHkgaW5lZmZpY2llbnQsIGJ1dCB0aGF0IGlzIG9rYXksIHNpbmNlCgkJICogaXQgaXMgcmFyZWx5IGV4ZWN1dGVkLCBpZiBhdCBhbGwuCgkJICovCgkJaW50NjRfdCBvZmZzZXQgPSBjbHVzdGVyMnNlY3RvcihzLCBjbHVzdGVyX251bSk7CgoJCXZ2ZmF0X2Nsb3NlX2N1cnJlbnRfZmlsZShzKTsKCQlmb3IgKGkgPSAwOyBpIDwgcy0+c2VjdG9yc19wZXJfY2x1c3RlcjsgaSsrKQoJCSAgICBpZiAoIXMtPnFjb3ctPmRydi0+YmRydl9pc19hbGxvY2F0ZWQocy0+cWNvdywKCQkJCW9mZnNldCArIGksIDEsICZkdW1teSkpIHsKCQkJaWYgKHZ2ZmF0X3JlYWQocy0+YnMsCgkJCQkgICAgb2Zmc2V0LCBzLT5jbHVzdGVyX2J1ZmZlciwgMSkpCgkJCSAgICByZXR1cm4gLTE7CgkJCWlmIChzLT5xY293LT5kcnYtPmJkcnZfd3JpdGUocy0+cWNvdywKCQkJCSAgICBvZmZzZXQsIHMtPmNsdXN0ZXJfYnVmZmVyLCAxKSkKCQkJICAgIHJldHVybiAtMjsKCQkgICAgfQoJICAgIH0KCX0KCglyZXQrKzsKCWlmIChzLT51c2VkX2NsdXN0ZXJzW2NsdXN0ZXJfbnVtXSAmIFVTRURfQU5ZKQoJICAgIHJldHVybiAwOwoJcy0+dXNlZF9jbHVzdGVyc1tjbHVzdGVyX251bV0gPSBVU0VEX0ZJTEU7CgoJY2x1c3Rlcl9udW0gPSBtb2RpZmllZF9mYXRfZ2V0KHMsIGNsdXN0ZXJfbnVtKTsKCglpZiAoZmF0X2VvZihzLCBjbHVzdGVyX251bSkpCgkgICAgcmV0dXJuIHJldDsKCWVsc2UgaWYgKGNsdXN0ZXJfbnVtIDwgMiB8fCBjbHVzdGVyX251bSA+IHMtPm1heF9mYXRfdmFsdWUgLSAxNikKCSAgICByZXR1cm4gLTE7CgoJb2Zmc2V0ICs9IHMtPmNsdXN0ZXJfc2l6ZTsKICAgIH0KfQoKLyoKICogVGhpcyBmdW5jdGlvbiBsb29rcyBhdCB0aGUgbW9kaWZpZWQgZGF0YSAocWNvdykuCiAqIEl0IHJldHVybnMgMCB1cG9uIGluY29uc2lzdGVuY3kgb3IgZXJyb3IsIGFuZCB0aGUgbnVtYmVyIG9mIGNsdXN0ZXJzCiAqIHVzZWQgYnkgdGhlIGRpcmVjdG9yeSwgaXRzIHN1YmRpcmVjdG9yaWVzIGFuZCB0aGVpciBmaWxlcy4KICovCnN0YXRpYyBpbnQgY2hlY2tfZGlyZWN0b3J5X2NvbnNpc3RlbmN5KEJEUlZWVkZBVFN0YXRlICpzLAoJaW50IGNsdXN0ZXJfbnVtLCBjb25zdCBjaGFyKiBwYXRoKQp7CiAgICBpbnQgcmV0ID0gMDsKICAgIHVuc2lnbmVkIGNoYXIqIGNsdXN0ZXIgPSBtYWxsb2Mocy0+Y2x1c3Rlcl9zaXplKTsKICAgIGRpcmVudHJ5X3QqIGRpcmVudHJpZXMgPSAoZGlyZW50cnlfdCopY2x1c3RlcjsKICAgIG1hcHBpbmdfdCogbWFwcGluZyA9IGZpbmRfbWFwcGluZ19mb3JfY2x1c3RlcihzLCBjbHVzdGVyX251bSk7CgogICAgbG9uZ19maWxlX25hbWUgbGZuOwogICAgaW50IHBhdGhfbGVuID0gc3RybGVuKHBhdGgpOwogICAgY2hhciBwYXRoMltQQVRIX01BWF07CgogICAgYXNzZXJ0KHBhdGhfbGVuIDwgUEFUSF9NQVgpOyAvKiBsZW4gd2FzIHRlc3RlZCBiZWZvcmUhICovCiAgICBzdHJjcHkocGF0aDIsIHBhdGgpOwogICAgcGF0aDJbcGF0aF9sZW5dID0gJy8nOwogICAgcGF0aDJbcGF0aF9sZW4gKyAxXSA9ICdcMCc7CgogICAgaWYgKG1hcHBpbmcpIHsKCWNvbnN0IGNoYXIqIGJhc2VuYW1lID0gZ2V0X2Jhc2VuYW1lKG1hcHBpbmctPnBhdGgpOwoJY29uc3QgY2hhciogYmFzZW5hbWUyID0gZ2V0X2Jhc2VuYW1lKHBhdGgpOwoKCWFzc2VydChtYXBwaW5nLT5tb2RlICYgTU9ERV9ESVJFQ1RPUlkpOwoKCWFzc2VydChtYXBwaW5nLT5tb2RlICYgTU9ERV9ERUxFVEVEKTsKCW1hcHBpbmctPm1vZGUgJj0gfk1PREVfREVMRVRFRDsKCglpZiAoc3RyY21wKGJhc2VuYW1lLCBiYXNlbmFtZTIpKQoJICAgIHNjaGVkdWxlX3JlbmFtZShzLCBjbHVzdGVyX251bSwgc3RyZHVwKHBhdGgpKTsKICAgIH0gZWxzZQoJLyogbmV3IGRpcmVjdG9yeSAqLwoJc2NoZWR1bGVfbWtkaXIocywgY2x1c3Rlcl9udW0sIHN0cmR1cChwYXRoKSk7CgogICAgbGZuX2luaXQoJmxmbik7CiAgICBkbyB7CglpbnQgaTsKCWludCBzdWJyZXQgPSAwOwoKCXJldCsrOwoKCWlmIChzLT51c2VkX2NsdXN0ZXJzW2NsdXN0ZXJfbnVtXSAmIFVTRURfQU5ZKSB7CgkgICAgZnByaW50ZihzdGRlcnIsICJjbHVzdGVyICVkIHVzZWQgbW9yZSB0aGFuIG9uY2VcbiIsIChpbnQpY2x1c3Rlcl9udW0pOwoJICAgIHJldHVybiAwOwoJfQoJcy0+dXNlZF9jbHVzdGVyc1tjbHVzdGVyX251bV0gPSBVU0VEX0RJUkVDVE9SWTsKCkRMT0coZnByaW50ZihzdGRlcnIsICJyZWFkIGNsdXN0ZXIgJWQgKHNlY3RvciAlZClcbiIsIChpbnQpY2x1c3Rlcl9udW0sIChpbnQpY2x1c3RlcjJzZWN0b3IocywgY2x1c3Rlcl9udW0pKSk7CglzdWJyZXQgPSB2dmZhdF9yZWFkKHMtPmJzLCBjbHVzdGVyMnNlY3RvcihzLCBjbHVzdGVyX251bSksIGNsdXN0ZXIsCgkJcy0+c2VjdG9yc19wZXJfY2x1c3Rlcik7CglpZiAoc3VicmV0KSB7CgkgICAgZnByaW50ZihzdGRlcnIsICJFcnJvciBmZXRjaGluZyBkaXJlbnRyaWVzXG4iKTsKCWZhaWw6CgkgICAgZnJlZShjbHVzdGVyKTsKCSAgICByZXR1cm4gMDsKCX0KCglmb3IgKGkgPSAwOyBpIDwgMHgxMCAqIHMtPnNlY3RvcnNfcGVyX2NsdXN0ZXI7IGkrKykgewoJICAgIGludCBjbHVzdGVyX2NvdW50OwoKRExPRyhmcHJpbnRmKHN0ZGVyciwgImNoZWNrIGRpcmVudHJ5ICVkOiBcbiIsIGkpOyBwcmludF9kaXJlbnRyeShkaXJlbnRyaWVzICsgaSkpOwoJICAgIGlmIChpc192b2x1bWVfbGFiZWwoZGlyZW50cmllcyArIGkpIHx8IGlzX2RvdChkaXJlbnRyaWVzICsgaSkgfHwKCQkgICAgaXNfZnJlZShkaXJlbnRyaWVzICsgaSkpCgkJY29udGludWU7CgoJICAgIHN1YnJldCA9IHBhcnNlX2xvbmdfbmFtZSgmbGZuLCBkaXJlbnRyaWVzICsgaSk7CgkgICAgaWYgKHN1YnJldCA8IDApIHsKCQlmcHJpbnRmKHN0ZGVyciwgIkVycm9yIGluIGxvbmcgbmFtZVxuIik7CgkJZ290byBmYWlsOwoJICAgIH0KCSAgICBpZiAoc3VicmV0ID09IDAgfHwgaXNfZnJlZShkaXJlbnRyaWVzICsgaSkpCgkJY29udGludWU7CgoJICAgIGlmIChmYXRfY2hrc3VtKGRpcmVudHJpZXMraSkgIT0gbGZuLmNoZWNrc3VtKSB7CgkJc3VicmV0ID0gcGFyc2Vfc2hvcnRfbmFtZShzLCAmbGZuLCBkaXJlbnRyaWVzICsgaSk7CgkJaWYgKHN1YnJldCA8IDApIHsKCQkgICAgZnByaW50ZihzdGRlcnIsICJFcnJvciBpbiBzaG9ydCBuYW1lICglZClcbiIsIHN1YnJldCk7CgkJICAgIGdvdG8gZmFpbDsKCQl9CgkJaWYgKHN1YnJldCA+IDAgfHwgIXN0cmNtcCgoY2hhciopbGZuLm5hbWUsICIuIikKCQkJfHwgIXN0cmNtcCgoY2hhciopbGZuLm5hbWUsICIuLiIpKQoJCSAgICBjb250aW51ZTsKCSAgICB9CgkgICAgbGZuLmNoZWNrc3VtID0gMHgxMDA7IC8qIGNhbm5vdCB1c2UgbG9uZyBuYW1lIHR3aWNlICovCgoJICAgIGlmIChwYXRoX2xlbiArIDEgKyBsZm4ubGVuID49IFBBVEhfTUFYKSB7CgkJZnByaW50ZihzdGRlcnIsICJOYW1lIHRvbyBsb25nOiAlcy8lc1xuIiwgcGF0aCwgbGZuLm5hbWUpOwoJCWdvdG8gZmFpbDsKCSAgICB9CgkgICAgc3RyY3B5KHBhdGgyICsgcGF0aF9sZW4gKyAxLCAoY2hhciopbGZuLm5hbWUpOwoKCSAgICBpZiAoaXNfZGlyZWN0b3J5KGRpcmVudHJpZXMgKyBpKSkgewoJCWlmIChiZWdpbl9vZl9kaXJlbnRyeShkaXJlbnRyaWVzICsgaSkgPT0gMCkgewoJCSAgICBETE9HKGZwcmludGYoc3RkZXJyLCAiaW52YWxpZCBiZWdpbiBmb3IgZGlyZWN0b3J5OiAlc1xuIiwgcGF0aDIpOyBwcmludF9kaXJlbnRyeShkaXJlbnRyaWVzICsgaSkpOwoJCSAgICBnb3RvIGZhaWw7CgkJfQoJCWNsdXN0ZXJfY291bnQgPSBjaGVja19kaXJlY3RvcnlfY29uc2lzdGVuY3kocywKCQkJYmVnaW5fb2ZfZGlyZW50cnkoZGlyZW50cmllcyArIGkpLCBwYXRoMik7CgkJaWYgKGNsdXN0ZXJfY291bnQgPT0gMCkgewoJCSAgICBETE9HKGZwcmludGYoc3RkZXJyLCAicHJvYmxlbSBpbiBkaXJlY3RvcnkgJXM6XG4iLCBwYXRoMik7IHByaW50X2RpcmVudHJ5KGRpcmVudHJpZXMgKyBpKSk7CgkJICAgIGdvdG8gZmFpbDsKCQl9CgkgICAgfSBlbHNlIGlmIChpc19maWxlKGRpcmVudHJpZXMgKyBpKSkgewoJCS8qIGNoZWNrIGZpbGUgc2l6ZSB3aXRoIEZBVCAqLwoJCWNsdXN0ZXJfY291bnQgPSBnZXRfY2x1c3Rlcl9jb3VudF9mb3JfZGlyZW50cnkocywgZGlyZW50cmllcyArIGksIHBhdGgyKTsKCQlpZiAoY2x1c3Rlcl9jb3VudCAhPQoJCQkobGUzMl90b19jcHUoZGlyZW50cmllc1tpXS5zaXplKSArIHMtPmNsdXN0ZXJfc2l6ZQoJCQkgLSAxKSAvIHMtPmNsdXN0ZXJfc2l6ZSkgewoJCSAgICBETE9HKGZwcmludGYoc3RkZXJyLCAiQ2x1c3RlciBjb3VudCBtaXNtYXRjaFxuIikpOwoJCSAgICBnb3RvIGZhaWw7CgkJfQoJICAgIH0gZWxzZQoJCWFzc2VydCgwKTsgLyogY2x1c3Rlcl9jb3VudCA9IDA7ICovCgoJICAgIHJldCArPSBjbHVzdGVyX2NvdW50OwoJfQoKCWNsdXN0ZXJfbnVtID0gbW9kaWZpZWRfZmF0X2dldChzLCBjbHVzdGVyX251bSk7CiAgICB9IHdoaWxlKCFmYXRfZW9mKHMsIGNsdXN0ZXJfbnVtKSk7CgogICAgZnJlZShjbHVzdGVyKTsKICAgIHJldHVybiByZXQ7Cn0KCi8qIHJldHVybnMgMSBvbiBzdWNjZXNzICovCnN0YXRpYyBpbnQgaXNfY29uc2lzdGVudChCRFJWVlZGQVRTdGF0ZSogcykKewogICAgaW50IGksIGNoZWNrOwogICAgaW50IHVzZWRfY2x1c3RlcnNfY291bnQgPSAwOwoKRExPRyhjaGVja3BvaW50KCkpOwogICAgLyoKICAgICAqIC0gZ2V0IG1vZGlmaWVkIEZBVAogICAgICogLSBjb21wYXJlIHRoZSB0d28gRkFUcyAoVE9ETykKICAgICAqIC0gZ2V0IGJ1ZmZlciBmb3IgbWFya2luZyB1c2VkIGNsdXN0ZXJzCiAgICAgKiAtIHJlY3Vyc2UgZGlyZW50cmllcyBmcm9tIHJvb3QgKHVzaW5nIGJzLT5iZHJ2X3JlYWQgdG8gbWFrZQogICAgICogICAgc3VyZSB0byBnZXQgdGhlIG5ldyBkYXRhKQogICAgICogICAtIGNoZWNrIHRoYXQgdGhlIEZBVCBhZ3JlZXMgd2l0aCB0aGUgc2l6ZQogICAgICogICAtIGNvdW50IHRoZSBudW1iZXIgb2YgY2x1c3RlcnMgb2NjdXBpZWQgYnkgdGhpcyBkaXJlY3RvcnkgYW5kCiAgICAgKiAgICAgaXRzIGZpbGVzCiAgICAgKiAtIGNoZWNrIHRoYXQgdGhlIGN1bXVsYXRpdmUgdXNlZCBjbHVzdGVyIGNvdW50IGFncmVlcyB3aXRoIHRoZQogICAgICogICBGQVQKICAgICAqIC0gaWYgYWxsIGlzIGZpbmUsIHJldHVybiBudW1iZXIgb2YgdXNlZCBjbHVzdGVycwogICAgICovCiAgICBpZiAocy0+ZmF0MiA9PSBOVUxMKSB7CglpbnQgc2l6ZSA9IDB4MjAwICogcy0+c2VjdG9yc19wZXJfZmF0OwoJcy0+ZmF0MiA9IG1hbGxvYyhzaXplKTsKCW1lbWNweShzLT5mYXQyLCBzLT5mYXQucG9pbnRlciwgc2l6ZSk7CiAgICB9CiAgICBjaGVjayA9IHZ2ZmF0X3JlYWQocy0+YnMsCgkgICAgcy0+Zmlyc3Rfc2VjdG9yc19udW1iZXIsIHMtPmZhdDIsIHMtPnNlY3RvcnNfcGVyX2ZhdCk7CiAgICBpZiAoY2hlY2spIHsKCWZwcmludGYoc3RkZXJyLCAiQ291bGQgbm90IGNvcHkgZmF0XG4iKTsKCXJldHVybiAwOwogICAgfQogICAgYXNzZXJ0IChzLT51c2VkX2NsdXN0ZXJzKTsKICAgIGZvciAoaSA9IDA7IGkgPCBzZWN0b3IyY2x1c3RlcihzLCBzLT5zZWN0b3JfY291bnQpOyBpKyspCglzLT51c2VkX2NsdXN0ZXJzW2ldICY9IH5VU0VEX0FOWTsKCiAgICBjbGVhcl9jb21taXRzKHMpOwoKICAgIC8qIG1hcmsgZXZlcnkgbWFwcGVkIGZpbGUvZGlyZWN0b3J5IGFzIGRlbGV0ZWQuCiAgICAgKiAoY2hlY2tfZGlyZWN0b3J5X2NvbnNpc3RlbmN5KCkgd2lsbCB1bm1hcmsgdGhvc2Ugc3RpbGwgcHJlc2VudCkuICovCiAgICBpZiAocy0+cWNvdykKCWZvciAoaSA9IDA7IGkgPCBzLT5tYXBwaW5nLm5leHQ7IGkrKykgewoJICAgIG1hcHBpbmdfdCogbWFwcGluZyA9IGFycmF5X2dldCgmKHMtPm1hcHBpbmcpLCBpKTsKCSAgICBpZiAobWFwcGluZy0+Zmlyc3RfbWFwcGluZ19pbmRleCA8IDApCgkJbWFwcGluZy0+bW9kZSB8PSBNT0RFX0RFTEVURUQ7Cgl9CgogICAgdXNlZF9jbHVzdGVyc19jb3VudCA9IGNoZWNrX2RpcmVjdG9yeV9jb25zaXN0ZW5jeShzLCAwLCBzLT5wYXRoKTsKICAgIGlmICh1c2VkX2NsdXN0ZXJzX2NvdW50IDw9IDApIHsKCURMT0coZnByaW50ZihzdGRlcnIsICJwcm9ibGVtIGluIGRpcmVjdG9yeVxuIikpOwoJcmV0dXJuIDA7CiAgICB9CgogICAgY2hlY2sgPSBzLT5sYXN0X2NsdXN0ZXJfb2Zfcm9vdF9kaXJlY3Rvcnk7CiAgICBmb3IgKGkgPSBjaGVjazsgaSA8IHNlY3RvcjJjbHVzdGVyKHMsIHMtPnNlY3Rvcl9jb3VudCk7IGkrKykgewoJaWYgKG1vZGlmaWVkX2ZhdF9nZXQocywgaSkpIHsKCSAgICBpZighcy0+dXNlZF9jbHVzdGVyc1tpXSkgewoJCURMT0coZnByaW50ZihzdGRlcnIsICJGQVQgd2FzIG1vZGlmaWVkICglZCksIGJ1dCBjbHVzdGVyIGlzIG5vdCB1c2VkP1xuIiwgaSkpOwoJCXJldHVybiAwOwoJICAgIH0KCSAgICBjaGVjaysrOwoJfQoKCWlmIChzLT51c2VkX2NsdXN0ZXJzW2ldID09IFVTRURfQUxMT0NBVEVEKSB7CgkgICAgLyogYWxsb2NhdGVkLCBidXQgbm90IHVzZWQuLi4gKi8KCSAgICBETE9HKGZwcmludGYoc3RkZXJyLCAidW51c2VkLCBtb2RpZmllZCBjbHVzdGVyOiAlZFxuIiwgaSkpOwoJICAgIHJldHVybiAwOwoJfQogICAgfQoKICAgIGlmIChjaGVjayAhPSB1c2VkX2NsdXN0ZXJzX2NvdW50KQoJcmV0dXJuIDA7CgogICAgcmV0dXJuIHVzZWRfY2x1c3RlcnNfY291bnQ7Cn0KCnN0YXRpYyBpbmxpbmUgdm9pZCBhZGp1c3RfbWFwcGluZ19pbmRpY2VzKEJEUlZWVkZBVFN0YXRlKiBzLAoJaW50IG9mZnNldCwgaW50IGFkanVzdCkKewogICAgaW50IGk7CgogICAgZm9yIChpID0gMDsgaSA8IHMtPm1hcHBpbmcubmV4dDsgaSsrKSB7CgltYXBwaW5nX3QqIG1hcHBpbmcgPSBhcnJheV9nZXQoJihzLT5tYXBwaW5nKSwgaSk7CgojZGVmaW5lIEFESlVTVF9NQVBQSU5HX0lOREVYKG5hbWUpIFwKCWlmIChtYXBwaW5nLT5uYW1lID49IG9mZnNldCkgXAoJICAgIG1hcHBpbmctPm5hbWUgKz0gYWRqdXN0CgoJQURKVVNUX01BUFBJTkdfSU5ERVgoZmlyc3RfbWFwcGluZ19pbmRleCk7CglpZiAobWFwcGluZy0+bW9kZSAmIE1PREVfRElSRUNUT1JZKQoJICAgIEFESlVTVF9NQVBQSU5HX0lOREVYKGluZm8uZGlyLnBhcmVudF9tYXBwaW5nX2luZGV4KTsKICAgIH0KfQoKLyogaW5zZXJ0IG9yIHVwZGF0ZSBtYXBwaW5nICovCnN0YXRpYyBtYXBwaW5nX3QqIGluc2VydF9tYXBwaW5nKEJEUlZWVkZBVFN0YXRlKiBzLAoJdWludDMyX3QgYmVnaW4sIHVpbnQzMl90IGVuZCkKewogICAgLyoKICAgICAqIC0gZmluZCBtYXBwaW5nIHdoZXJlIG1hcHBpbmctPmJlZ2luID49IGJlZ2luLAogICAgICogLSBpZiBtYXBwaW5nLT5iZWdpbiA+IGJlZ2luOiBpbnNlcnQKICAgICAqICAgLSBhZGp1c3QgYWxsIHJlZmVyZW5jZXMgdG8gbWFwcGluZ3MhCiAgICAgKiAtIGVsc2U6IGFkanVzdAogICAgICogLSByZXBsYWNlIG5hbWUKICAgICAqLwogICAgaW50IGluZGV4ID0gZmluZF9tYXBwaW5nX2Zvcl9jbHVzdGVyX2F1eChzLCBiZWdpbiwgMCwgcy0+bWFwcGluZy5uZXh0KTsKICAgIG1hcHBpbmdfdCogbWFwcGluZyA9IE5VTEw7CiAgICBtYXBwaW5nX3QqIGZpcnN0X21hcHBpbmcgPSBhcnJheV9nZXQoJihzLT5tYXBwaW5nKSwgMCk7CgogICAgaWYgKGluZGV4IDwgcy0+bWFwcGluZy5uZXh0ICYmIChtYXBwaW5nID0gYXJyYXlfZ2V0KCYocy0+bWFwcGluZyksIGluZGV4KSkKCSAgICAmJiBtYXBwaW5nLT5iZWdpbiA8IGJlZ2luKSB7CgltYXBwaW5nLT5lbmQgPSBiZWdpbjsKCWluZGV4Kys7CgltYXBwaW5nID0gYXJyYXlfZ2V0KCYocy0+bWFwcGluZyksIGluZGV4KTsKICAgIH0KICAgIGlmIChpbmRleCA+PSBzLT5tYXBwaW5nLm5leHQgfHwgbWFwcGluZy0+YmVnaW4gPiBiZWdpbikgewoJbWFwcGluZyA9IGFycmF5X2luc2VydCgmKHMtPm1hcHBpbmcpLCBpbmRleCwgMSk7CgltYXBwaW5nLT5wYXRoID0gTlVMTDsKCWFkanVzdF9tYXBwaW5nX2luZGljZXMocywgaW5kZXgsICsxKTsKICAgIH0KCiAgICBtYXBwaW5nLT5iZWdpbiA9IGJlZ2luOwogICAgbWFwcGluZy0+ZW5kID0gZW5kOwoKRExPRyhtYXBwaW5nX3QqIG5leHRfbWFwcGluZzsKYXNzZXJ0KGluZGV4ICsgMSA+PSBzLT5tYXBwaW5nLm5leHQgfHwKKChuZXh0X21hcHBpbmcgPSBhcnJheV9nZXQoJihzLT5tYXBwaW5nKSwgaW5kZXggKyAxKSkgJiYKIG5leHRfbWFwcGluZy0+YmVnaW4gPj0gZW5kKSkpOwoKICAgIGlmIChzLT5jdXJyZW50X21hcHBpbmcgJiYgZmlyc3RfbWFwcGluZyAhPSAobWFwcGluZ190KilzLT5tYXBwaW5nLnBvaW50ZXIpCglzLT5jdXJyZW50X21hcHBpbmcgPSBhcnJheV9nZXQoJihzLT5tYXBwaW5nKSwKCQlzLT5jdXJyZW50X21hcHBpbmcgLSBmaXJzdF9tYXBwaW5nKTsKCiAgICByZXR1cm4gbWFwcGluZzsKfQoKc3RhdGljIGludCByZW1vdmVfbWFwcGluZyhCRFJWVlZGQVRTdGF0ZSogcywgaW50IG1hcHBpbmdfaW5kZXgpCnsKICAgIG1hcHBpbmdfdCogbWFwcGluZyA9IGFycmF5X2dldCgmKHMtPm1hcHBpbmcpLCBtYXBwaW5nX2luZGV4KTsKICAgIG1hcHBpbmdfdCogZmlyc3RfbWFwcGluZyA9IGFycmF5X2dldCgmKHMtPm1hcHBpbmcpLCAwKTsKCiAgICAvKiBmcmVlIG1hcHBpbmcgKi8KICAgIGlmIChtYXBwaW5nLT5maXJzdF9tYXBwaW5nX2luZGV4IDwgMCkKCWZyZWUobWFwcGluZy0+cGF0aCk7CgogICAgLyogcmVtb3ZlIGZyb20gcy0+bWFwcGluZyAqLwogICAgYXJyYXlfcmVtb3ZlKCYocy0+bWFwcGluZyksIG1hcHBpbmdfaW5kZXgpOwoKICAgIC8qIGFkanVzdCBhbGwgcmVmZXJlbmNlcyB0byBtYXBwaW5ncyAqLwogICAgYWRqdXN0X21hcHBpbmdfaW5kaWNlcyhzLCBtYXBwaW5nX2luZGV4LCAtMSk7CgogICAgaWYgKHMtPmN1cnJlbnRfbWFwcGluZyAmJiBmaXJzdF9tYXBwaW5nICE9IChtYXBwaW5nX3QqKXMtPm1hcHBpbmcucG9pbnRlcikKCXMtPmN1cnJlbnRfbWFwcGluZyA9IGFycmF5X2dldCgmKHMtPm1hcHBpbmcpLAoJCXMtPmN1cnJlbnRfbWFwcGluZyAtIGZpcnN0X21hcHBpbmcpOwoKICAgIHJldHVybiAwOwp9CgpzdGF0aWMgdm9pZCBhZGp1c3RfZGlyaW5kaWNlcyhCRFJWVlZGQVRTdGF0ZSogcywgaW50IG9mZnNldCwgaW50IGFkanVzdCkKewogICAgaW50IGk7CiAgICBmb3IgKGkgPSAwOyBpIDwgcy0+bWFwcGluZy5uZXh0OyBpKyspIHsKCW1hcHBpbmdfdCogbWFwcGluZyA9IGFycmF5X2dldCgmKHMtPm1hcHBpbmcpLCBpKTsKCWlmIChtYXBwaW5nLT5kaXJfaW5kZXggPj0gb2Zmc2V0KQoJICAgIG1hcHBpbmctPmRpcl9pbmRleCArPSBhZGp1c3Q7CglpZiAoKG1hcHBpbmctPm1vZGUgJiBNT0RFX0RJUkVDVE9SWSkgJiYKCQltYXBwaW5nLT5pbmZvLmRpci5maXJzdF9kaXJfaW5kZXggPj0gb2Zmc2V0KQoJICAgIG1hcHBpbmctPmluZm8uZGlyLmZpcnN0X2Rpcl9pbmRleCArPSBhZGp1c3Q7CiAgICB9Cn0KCnN0YXRpYyBkaXJlbnRyeV90KiBpbnNlcnRfZGlyZW50cmllcyhCRFJWVlZGQVRTdGF0ZSogcywKCWludCBkaXJfaW5kZXgsIGludCBjb3VudCkKewogICAgLyoKICAgICAqIG1ha2Ugcm9vbSBpbiBzLT5kaXJlY3RvcnksCiAgICAgKiBhZGp1c3RfZGlyaW5kaWNlcwogICAgICovCiAgICBkaXJlbnRyeV90KiByZXN1bHQgPSBhcnJheV9pbnNlcnQoJihzLT5kaXJlY3RvcnkpLCBkaXJfaW5kZXgsIGNvdW50KTsKICAgIGlmIChyZXN1bHQgPT0gTlVMTCkKCXJldHVybiBOVUxMOwogICAgYWRqdXN0X2RpcmluZGljZXMocywgZGlyX2luZGV4LCBjb3VudCk7CiAgICByZXR1cm4gcmVzdWx0Owp9CgpzdGF0aWMgaW50IHJlbW92ZV9kaXJlbnRyaWVzKEJEUlZWVkZBVFN0YXRlKiBzLCBpbnQgZGlyX2luZGV4LCBpbnQgY291bnQpCnsKICAgIGludCByZXQgPSBhcnJheV9yZW1vdmVfc2xpY2UoJihzLT5kaXJlY3RvcnkpLCBkaXJfaW5kZXgsIGNvdW50KTsKICAgIGlmIChyZXQpCglyZXR1cm4gcmV0OwogICAgYWRqdXN0X2RpcmluZGljZXMocywgZGlyX2luZGV4LCAtY291bnQpOwogICAgcmV0dXJuIDA7Cn0KCi8qCiAqIEFkYXB0IHRoZSBtYXBwaW5ncyBvZiB0aGUgY2x1c3RlciBjaGFpbiBzdGFydGluZyBhdCBmaXJzdCBjbHVzdGVyCiAqIChpLmUuIGlmIGEgZmlsZSBzdGFydHMgYXQgZmlyc3RfY2x1c3RlciwgdGhlIGNoYWluIGlzIGZvbGxvd2VkIGFjY29yZGluZwogKiB0byB0aGUgbW9kaWZpZWQgZmF0LCBhbmQgdGhlIGNvcnJlc3BvbmRpbmcgZW50cmllcyBpbiBzLT5tYXBwaW5nIGFyZQogKiBhZGp1c3RlZCkKICovCnN0YXRpYyBpbnQgY29tbWl0X21hcHBpbmdzKEJEUlZWVkZBVFN0YXRlKiBzLAoJdWludDMyX3QgZmlyc3RfY2x1c3RlciwgaW50IGRpcl9pbmRleCkKewogICAgbWFwcGluZ190KiBtYXBwaW5nID0gZmluZF9tYXBwaW5nX2Zvcl9jbHVzdGVyKHMsIGZpcnN0X2NsdXN0ZXIpOwogICAgZGlyZW50cnlfdCogZGlyZW50cnkgPSBhcnJheV9nZXQoJihzLT5kaXJlY3RvcnkpLCBkaXJfaW5kZXgpOwogICAgdWludDMyX3QgY2x1c3RlciA9IGZpcnN0X2NsdXN0ZXI7CgogICAgdnZmYXRfY2xvc2VfY3VycmVudF9maWxlKHMpOwoKICAgIGFzc2VydChtYXBwaW5nKTsKICAgIGFzc2VydChtYXBwaW5nLT5iZWdpbiA9PSBmaXJzdF9jbHVzdGVyKTsKICAgIG1hcHBpbmctPmZpcnN0X21hcHBpbmdfaW5kZXggPSAtMTsKICAgIG1hcHBpbmctPmRpcl9pbmRleCA9IGRpcl9pbmRleDsKICAgIG1hcHBpbmctPm1vZGUgPSAoZGlyX2luZGV4IDw9IDAgfHwgaXNfZGlyZWN0b3J5KGRpcmVudHJ5KSkgPwoJTU9ERV9ESVJFQ1RPUlkgOiBNT0RFX05PUk1BTDsKCiAgICB3aGlsZSAoIWZhdF9lb2YocywgY2x1c3RlcikpIHsKCXVpbnQzMl90IGMsIGMxOwoKCWZvciAoYyA9IGNsdXN0ZXIsIGMxID0gbW9kaWZpZWRfZmF0X2dldChzLCBjKTsgYyArIDEgPT0gYzE7CgkJYyA9IGMxLCBjMSA9IG1vZGlmaWVkX2ZhdF9nZXQocywgYzEpKTsKCgljKys7CglpZiAoYyA+IG1hcHBpbmctPmVuZCkgewoJICAgIGludCBpbmRleCA9IGFycmF5X2luZGV4KCYocy0+bWFwcGluZyksIG1hcHBpbmcpOwoJICAgIGludCBpLCBtYXhfaSA9IHMtPm1hcHBpbmcubmV4dCAtIGluZGV4OwoJICAgIGZvciAoaSA9IDE7IGkgPCBtYXhfaSAmJiBtYXBwaW5nW2ldLmJlZ2luIDwgYzsgaSsrKTsKCSAgICB3aGlsZSAoLS1pID4gMCkKCQlyZW1vdmVfbWFwcGluZyhzLCBpbmRleCArIDEpOwoJfQoJYXNzZXJ0KG1hcHBpbmcgPT0gYXJyYXlfZ2V0KCYocy0+bWFwcGluZyksIHMtPm1hcHBpbmcubmV4dCAtIDEpCgkJfHwgbWFwcGluZ1sxXS5iZWdpbiA+PSBjKTsKCW1hcHBpbmctPmVuZCA9IGM7CgoJaWYgKCFmYXRfZW9mKHMsIGMxKSkgewoJICAgIGludCBpID0gZmluZF9tYXBwaW5nX2Zvcl9jbHVzdGVyX2F1eChzLCBjMSwgMCwgcy0+bWFwcGluZy5uZXh0KTsKCSAgICBtYXBwaW5nX3QqIG5leHRfbWFwcGluZyA9IGkgPj0gcy0+bWFwcGluZy5uZXh0ID8gTlVMTCA6CgkJYXJyYXlfZ2V0KCYocy0+bWFwcGluZyksIGkpOwoKCSAgICBpZiAobmV4dF9tYXBwaW5nID09IE5VTEwgfHwgbmV4dF9tYXBwaW5nLT5iZWdpbiA+IGMxKSB7CgkJaW50IGkxID0gYXJyYXlfaW5kZXgoJihzLT5tYXBwaW5nKSwgbWFwcGluZyk7CgoJCW5leHRfbWFwcGluZyA9IGluc2VydF9tYXBwaW5nKHMsIGMxLCBjMSsxKTsKCgkJaWYgKGMxIDwgYykKCQkgICAgaTErKzsKCQltYXBwaW5nID0gYXJyYXlfZ2V0KCYocy0+bWFwcGluZyksIGkxKTsKCSAgICB9CgoJICAgIG5leHRfbWFwcGluZy0+ZGlyX2luZGV4ID0gbWFwcGluZy0+ZGlyX2luZGV4OwoJICAgIG5leHRfbWFwcGluZy0+Zmlyc3RfbWFwcGluZ19pbmRleCA9CgkJbWFwcGluZy0+Zmlyc3RfbWFwcGluZ19pbmRleCA8IDAgPwoJCWFycmF5X2luZGV4KCYocy0+bWFwcGluZyksIG1hcHBpbmcpIDoKCQltYXBwaW5nLT5maXJzdF9tYXBwaW5nX2luZGV4OwoJICAgIG5leHRfbWFwcGluZy0+cGF0aCA9IG1hcHBpbmctPnBhdGg7CgkgICAgbmV4dF9tYXBwaW5nLT5tb2RlID0gbWFwcGluZy0+bW9kZTsKCSAgICBuZXh0X21hcHBpbmctPnJlYWRfb25seSA9IG1hcHBpbmctPnJlYWRfb25seTsKCSAgICBpZiAobWFwcGluZy0+bW9kZSAmIE1PREVfRElSRUNUT1JZKSB7CgkJbmV4dF9tYXBwaW5nLT5pbmZvLmRpci5wYXJlbnRfbWFwcGluZ19pbmRleCA9CgkJCW1hcHBpbmctPmluZm8uZGlyLnBhcmVudF9tYXBwaW5nX2luZGV4OwoJCW5leHRfbWFwcGluZy0+aW5mby5kaXIuZmlyc3RfZGlyX2luZGV4ID0KCQkJbWFwcGluZy0+aW5mby5kaXIuZmlyc3RfZGlyX2luZGV4ICsKCQkJMHgxMCAqIHMtPnNlY3RvcnNfcGVyX2NsdXN0ZXIgKgoJCQkobWFwcGluZy0+ZW5kIC0gbWFwcGluZy0+YmVnaW4pOwoJICAgIH0gZWxzZQoJCW5leHRfbWFwcGluZy0+aW5mby5maWxlLm9mZnNldCA9IG1hcHBpbmctPmluZm8uZmlsZS5vZmZzZXQgKwoJCQltYXBwaW5nLT5lbmQgLSBtYXBwaW5nLT5iZWdpbjsKCgkgICAgbWFwcGluZyA9IG5leHRfbWFwcGluZzsKCX0KCgljbHVzdGVyID0gYzE7CiAgICB9CgogICAgcmV0dXJuIDA7Cn0KCnN0YXRpYyBpbnQgY29tbWl0X2RpcmVudHJpZXMoQkRSVlZWRkFUU3RhdGUqIHMsCglpbnQgZGlyX2luZGV4LCBpbnQgcGFyZW50X21hcHBpbmdfaW5kZXgpCnsKICAgIGRpcmVudHJ5X3QqIGRpcmVudHJ5ID0gYXJyYXlfZ2V0KCYocy0+ZGlyZWN0b3J5KSwgZGlyX2luZGV4KTsKICAgIHVpbnQzMl90IGZpcnN0X2NsdXN0ZXIgPSBkaXJfaW5kZXggPT0gMCA/IDAgOiBiZWdpbl9vZl9kaXJlbnRyeShkaXJlbnRyeSk7CiAgICBtYXBwaW5nX3QqIG1hcHBpbmcgPSBmaW5kX21hcHBpbmdfZm9yX2NsdXN0ZXIocywgZmlyc3RfY2x1c3Rlcik7CgogICAgaW50IGZhY3RvciA9IDB4MTAgKiBzLT5zZWN0b3JzX3Blcl9jbHVzdGVyOwogICAgaW50IG9sZF9jbHVzdGVyX2NvdW50LCBuZXdfY2x1c3Rlcl9jb3VudDsKICAgIGludCBjdXJyZW50X2Rpcl9pbmRleCA9IG1hcHBpbmctPmluZm8uZGlyLmZpcnN0X2Rpcl9pbmRleDsKICAgIGludCBmaXJzdF9kaXJfaW5kZXggPSBjdXJyZW50X2Rpcl9pbmRleDsKICAgIGludCByZXQsIGk7CiAgICB1aW50MzJfdCBjOwoKRExPRyhmcHJpbnRmKHN0ZGVyciwgImNvbW1pdF9kaXJlbnRyaWVzIGZvciAlcywgcGFyZW50X21hcHBpbmdfaW5kZXggJWRcbiIsIG1hcHBpbmctPnBhdGgsIHBhcmVudF9tYXBwaW5nX2luZGV4KSk7CgogICAgYXNzZXJ0KGRpcmVudHJ5KTsKICAgIGFzc2VydChtYXBwaW5nKTsKICAgIGFzc2VydChtYXBwaW5nLT5iZWdpbiA9PSBmaXJzdF9jbHVzdGVyKTsKICAgIGFzc2VydChtYXBwaW5nLT5pbmZvLmRpci5maXJzdF9kaXJfaW5kZXggPCBzLT5kaXJlY3RvcnkubmV4dCk7CiAgICBhc3NlcnQobWFwcGluZy0+bW9kZSAmIE1PREVfRElSRUNUT1JZKTsKICAgIGFzc2VydChkaXJfaW5kZXggPT0gMCB8fCBpc19kaXJlY3RvcnkoZGlyZW50cnkpKTsKCiAgICBtYXBwaW5nLT5pbmZvLmRpci5wYXJlbnRfbWFwcGluZ19pbmRleCA9IHBhcmVudF9tYXBwaW5nX2luZGV4OwoKICAgIGlmIChmaXJzdF9jbHVzdGVyID09IDApIHsKCW9sZF9jbHVzdGVyX2NvdW50ID0gbmV3X2NsdXN0ZXJfY291bnQgPQoJICAgIHMtPmxhc3RfY2x1c3Rlcl9vZl9yb290X2RpcmVjdG9yeTsKICAgIH0gZWxzZSB7Cglmb3IgKG9sZF9jbHVzdGVyX2NvdW50ID0gMCwgYyA9IGZpcnN0X2NsdXN0ZXI7ICFmYXRfZW9mKHMsIGMpOwoJCWMgPSBmYXRfZ2V0KHMsIGMpKQoJICAgIG9sZF9jbHVzdGVyX2NvdW50Kys7CgoJZm9yIChuZXdfY2x1c3Rlcl9jb3VudCA9IDAsIGMgPSBmaXJzdF9jbHVzdGVyOyAhZmF0X2VvZihzLCBjKTsKCQljID0gbW9kaWZpZWRfZmF0X2dldChzLCBjKSkKCSAgICBuZXdfY2x1c3Rlcl9jb3VudCsrOwogICAgfQoKICAgIGlmIChuZXdfY2x1c3Rlcl9jb3VudCA+IG9sZF9jbHVzdGVyX2NvdW50KSB7CglpZiAoaW5zZXJ0X2RpcmVudHJpZXMocywKCQljdXJyZW50X2Rpcl9pbmRleCArIGZhY3RvciAqIG9sZF9jbHVzdGVyX2NvdW50LAoJCWZhY3RvciAqIChuZXdfY2x1c3Rlcl9jb3VudCAtIG9sZF9jbHVzdGVyX2NvdW50KSkgPT0gTlVMTCkKCSAgICByZXR1cm4gLTE7CiAgICB9IGVsc2UgaWYgKG5ld19jbHVzdGVyX2NvdW50IDwgb2xkX2NsdXN0ZXJfY291bnQpCglyZW1vdmVfZGlyZW50cmllcyhzLAoJCWN1cnJlbnRfZGlyX2luZGV4ICsgZmFjdG9yICogbmV3X2NsdXN0ZXJfY291bnQsCgkJZmFjdG9yICogKG9sZF9jbHVzdGVyX2NvdW50IC0gbmV3X2NsdXN0ZXJfY291bnQpKTsKCiAgICBmb3IgKGMgPSBmaXJzdF9jbHVzdGVyOyAhZmF0X2VvZihzLCBjKTsgYyA9IG1vZGlmaWVkX2ZhdF9nZXQocywgYykpIHsKCXZvaWQqIGRpcmVudHJ5ID0gYXJyYXlfZ2V0KCYocy0+ZGlyZWN0b3J5KSwgY3VycmVudF9kaXJfaW5kZXgpOwoJaW50IHJldCA9IHZ2ZmF0X3JlYWQocy0+YnMsIGNsdXN0ZXIyc2VjdG9yKHMsIGMpLCBkaXJlbnRyeSwKCQlzLT5zZWN0b3JzX3Blcl9jbHVzdGVyKTsKCWlmIChyZXQpCgkgICAgcmV0dXJuIHJldDsKCWFzc2VydCghc3RybmNtcChzLT5kaXJlY3RvcnkucG9pbnRlciwgIlFFTVUiLCA0KSk7CgljdXJyZW50X2Rpcl9pbmRleCArPSBmYWN0b3I7CiAgICB9CgogICAgcmV0ID0gY29tbWl0X21hcHBpbmdzKHMsIGZpcnN0X2NsdXN0ZXIsIGRpcl9pbmRleCk7CiAgICBpZiAocmV0KQoJcmV0dXJuIHJldDsKCiAgICAvKiByZWN1cnNlICovCiAgICBmb3IgKGkgPSAwOyBpIDwgZmFjdG9yICogbmV3X2NsdXN0ZXJfY291bnQ7IGkrKykgewoJZGlyZW50cnkgPSBhcnJheV9nZXQoJihzLT5kaXJlY3RvcnkpLCBmaXJzdF9kaXJfaW5kZXggKyBpKTsKCWlmIChpc19kaXJlY3RvcnkoZGlyZW50cnkpICYmICFpc19kb3QoZGlyZW50cnkpKSB7CgkgICAgbWFwcGluZyA9IGZpbmRfbWFwcGluZ19mb3JfY2x1c3RlcihzLCBmaXJzdF9jbHVzdGVyKTsKCSAgICBhc3NlcnQobWFwcGluZy0+bW9kZSAmIE1PREVfRElSRUNUT1JZKTsKCSAgICByZXQgPSBjb21taXRfZGlyZW50cmllcyhzLCBmaXJzdF9kaXJfaW5kZXggKyBpLAoJCWFycmF5X2luZGV4KCYocy0+bWFwcGluZyksIG1hcHBpbmcpKTsKCSAgICBpZiAocmV0KQoJCXJldHVybiByZXQ7Cgl9CiAgICB9CgogICAgcmV0dXJuIDA7Cn0KCi8qIGNvbW1pdCBvbmUgZmlsZSAoYWRqdXN0IGNvbnRlbnRzLCBhZGp1c3QgbWFwcGluZyksCiAgIHJldHVybiBmaXJzdF9tYXBwaW5nX2luZGV4ICovCnN0YXRpYyBpbnQgY29tbWl0X29uZV9maWxlKEJEUlZWVkZBVFN0YXRlKiBzLAoJaW50IGRpcl9pbmRleCwgdWludDMyX3Qgb2Zmc2V0KQp7CiAgICBkaXJlbnRyeV90KiBkaXJlbnRyeSA9IGFycmF5X2dldCgmKHMtPmRpcmVjdG9yeSksIGRpcl9pbmRleCk7CiAgICB1aW50MzJfdCBjID0gYmVnaW5fb2ZfZGlyZW50cnkoZGlyZW50cnkpOwogICAgdWludDMyX3QgZmlyc3RfY2x1c3RlciA9IGM7CiAgICBtYXBwaW5nX3QqIG1hcHBpbmcgPSBmaW5kX21hcHBpbmdfZm9yX2NsdXN0ZXIocywgYyk7CiAgICB1aW50MzJfdCBzaXplID0gZmlsZXNpemVfb2ZfZGlyZW50cnkoZGlyZW50cnkpOwogICAgY2hhciogY2x1c3RlciA9IG1hbGxvYyhzLT5jbHVzdGVyX3NpemUpOwogICAgdWludDMyX3QgaTsKICAgIGludCBmZCA9IDA7CgogICAgYXNzZXJ0KG9mZnNldCA8IHNpemUpOwogICAgYXNzZXJ0KChvZmZzZXQgJSBzLT5jbHVzdGVyX3NpemUpID09IDApOwoKICAgIGZvciAoaSA9IHMtPmNsdXN0ZXJfc2l6ZTsgaSA8IG9mZnNldDsgaSArPSBzLT5jbHVzdGVyX3NpemUpCgljID0gbW9kaWZpZWRfZmF0X2dldChzLCBjKTsKCiAgICBmZCA9IG9wZW4obWFwcGluZy0+cGF0aCwgT19SRFdSIHwgT19DUkVBVCB8IE9fQklOQVJZLCAwNjY2KTsKICAgIGlmIChmZCA8IDApIHsKCWZwcmludGYoc3RkZXJyLCAiQ291bGQgbm90IG9wZW4gJXMuLi4gKCVzLCAlZClcbiIsIG1hcHBpbmctPnBhdGgsCgkJc3RyZXJyb3IoZXJybm8pLCBlcnJubyk7CglyZXR1cm4gZmQ7CiAgICB9CiAgICBpZiAob2Zmc2V0ID4gMCkKCWlmIChsc2VlayhmZCwgb2Zmc2V0LCBTRUVLX1NFVCkgIT0gb2Zmc2V0KQoJICAgIHJldHVybiAtMzsKCiAgICB3aGlsZSAob2Zmc2V0IDwgc2l6ZSkgewoJdWludDMyX3QgYzE7CglpbnQgcmVzdF9zaXplID0gKHNpemUgLSBvZmZzZXQgPiBzLT5jbHVzdGVyX3NpemUgPwoJCXMtPmNsdXN0ZXJfc2l6ZSA6IHNpemUgLSBvZmZzZXQpOwoJaW50IHJldDsKCgljMSA9IG1vZGlmaWVkX2ZhdF9nZXQocywgYyk7CgoJYXNzZXJ0KChzaXplIC0gb2Zmc2V0ID09IDAgJiYgZmF0X2VvZihzLCBjKSkgfHwKCQkoc2l6ZSA+IG9mZnNldCAmJiBjID49MiAmJiAhZmF0X2VvZihzLCBjKSkpOwoJYXNzZXJ0KHNpemUgPj0gMCk7CgoJcmV0ID0gdnZmYXRfcmVhZChzLT5icywgY2x1c3RlcjJzZWN0b3IocywgYyksCgkgICAgKHVpbnQ4X3QqKWNsdXN0ZXIsIChyZXN0X3NpemUgKyAweDFmZikgLyAweDIwMCk7CgoJaWYgKHJldCA8IDApCgkgICAgcmV0dXJuIHJldDsKCglpZiAod3JpdGUoZmQsIGNsdXN0ZXIsIHJlc3Rfc2l6ZSkgPCAwKQoJICAgIHJldHVybiAtMjsKCglvZmZzZXQgKz0gcmVzdF9zaXplOwoJYyA9IGMxOwogICAgfQoKICAgIGZ0cnVuY2F0ZShmZCwgc2l6ZSk7CiAgICBjbG9zZShmZCk7CgogICAgcmV0dXJuIGNvbW1pdF9tYXBwaW5ncyhzLCBmaXJzdF9jbHVzdGVyLCBkaXJfaW5kZXgpOwp9CgojaWZkZWYgREVCVUcKLyogdGVzdCwgaWYgYWxsIG1hcHBpbmdzIHBvaW50IHRvIHZhbGlkIGRpcmVudHJpZXMgKi8Kc3RhdGljIHZvaWQgY2hlY2sxKEJEUlZWVkZBVFN0YXRlKiBzKQp7CiAgICBpbnQgaTsKICAgIGZvciAoaSA9IDA7IGkgPCBzLT5tYXBwaW5nLm5leHQ7IGkrKykgewoJbWFwcGluZ190KiBtYXBwaW5nID0gYXJyYXlfZ2V0KCYocy0+bWFwcGluZyksIGkpOwoJaWYgKG1hcHBpbmctPm1vZGUgJiBNT0RFX0RFTEVURUQpIHsKCSAgICBmcHJpbnRmKHN0ZGVyciwgImRlbGV0ZWRcbiIpOwoJICAgIGNvbnRpbnVlOwoJfQoJYXNzZXJ0KG1hcHBpbmctPmRpcl9pbmRleCA+PSAwKTsKCWFzc2VydChtYXBwaW5nLT5kaXJfaW5kZXggPCBzLT5kaXJlY3RvcnkubmV4dCk7CglkaXJlbnRyeV90KiBkaXJlbnRyeSA9IGFycmF5X2dldCgmKHMtPmRpcmVjdG9yeSksIG1hcHBpbmctPmRpcl9pbmRleCk7Cglhc3NlcnQobWFwcGluZy0+YmVnaW4gPT0gYmVnaW5fb2ZfZGlyZW50cnkoZGlyZW50cnkpIHx8IG1hcHBpbmctPmZpcnN0X21hcHBpbmdfaW5kZXggPj0gMCk7CglpZiAobWFwcGluZy0+bW9kZSAmIE1PREVfRElSRUNUT1JZKSB7CgkgICAgYXNzZXJ0KG1hcHBpbmctPmluZm8uZGlyLmZpcnN0X2Rpcl9pbmRleCArIDB4MTAgKiBzLT5zZWN0b3JzX3Blcl9jbHVzdGVyICogKG1hcHBpbmctPmVuZCAtIG1hcHBpbmctPmJlZ2luKSA8PSBzLT5kaXJlY3RvcnkubmV4dCk7CgkgICAgYXNzZXJ0KChtYXBwaW5nLT5pbmZvLmRpci5maXJzdF9kaXJfaW5kZXggJSAoMHgxMCAqIHMtPnNlY3RvcnNfcGVyX2NsdXN0ZXIpKSA9PSAwKTsKCX0KICAgIH0KfQoKLyogdGVzdCwgaWYgYWxsIGRpcmVudHJpZXMgaGF2ZSBtYXBwaW5ncyAqLwpzdGF0aWMgdm9pZCBjaGVjazIoQkRSVlZWRkFUU3RhdGUqIHMpCnsKICAgIGludCBpOwogICAgaW50IGZpcnN0X21hcHBpbmcgPSAtMTsKCiAgICBmb3IgKGkgPSAwOyBpIDwgcy0+ZGlyZWN0b3J5Lm5leHQ7IGkrKykgewoJZGlyZW50cnlfdCogZGlyZW50cnkgPSBhcnJheV9nZXQoJihzLT5kaXJlY3RvcnkpLCBpKTsKCglpZiAoaXNfc2hvcnRfbmFtZShkaXJlbnRyeSkgJiYgYmVnaW5fb2ZfZGlyZW50cnkoZGlyZW50cnkpKSB7CgkgICAgbWFwcGluZ190KiBtYXBwaW5nID0gZmluZF9tYXBwaW5nX2Zvcl9jbHVzdGVyKHMsIGJlZ2luX29mX2RpcmVudHJ5KGRpcmVudHJ5KSk7CgkgICAgYXNzZXJ0KG1hcHBpbmcpOwoJICAgIGFzc2VydChtYXBwaW5nLT5kaXJfaW5kZXggPT0gaSB8fCBpc19kb3QoZGlyZW50cnkpKTsKCSAgICBhc3NlcnQobWFwcGluZy0+YmVnaW4gPT0gYmVnaW5fb2ZfZGlyZW50cnkoZGlyZW50cnkpIHx8IGlzX2RvdChkaXJlbnRyeSkpOwoJfQoKCWlmICgoaSAlICgweDEwICogcy0+c2VjdG9yc19wZXJfY2x1c3RlcikpID09IDApIHsKCSAgICAvKiBjbHVzdGVyIHN0YXJ0ICovCgkgICAgaW50IGosIGNvdW50ID0gMDsKCgkgICAgZm9yIChqID0gMDsgaiA8IHMtPm1hcHBpbmcubmV4dDsgaisrKSB7CgkJbWFwcGluZ190KiBtYXBwaW5nID0gYXJyYXlfZ2V0KCYocy0+bWFwcGluZyksIGopOwoJCWlmIChtYXBwaW5nLT5tb2RlICYgTU9ERV9ERUxFVEVEKQoJCSAgICBjb250aW51ZTsKCQlpZiAobWFwcGluZy0+bW9kZSAmIE1PREVfRElSRUNUT1JZKSB7CgkJICAgIGlmIChtYXBwaW5nLT5pbmZvLmRpci5maXJzdF9kaXJfaW5kZXggPD0gaSAmJiBtYXBwaW5nLT5pbmZvLmRpci5maXJzdF9kaXJfaW5kZXggKyAweDEwICogcy0+c2VjdG9yc19wZXJfY2x1c3RlciA+IGkpIHsKCQkJYXNzZXJ0KCsrY291bnQgPT0gMSk7CgkJCWlmIChtYXBwaW5nLT5maXJzdF9tYXBwaW5nX2luZGV4ID09IC0xKQoJCQkgICAgZmlyc3RfbWFwcGluZyA9IGFycmF5X2luZGV4KCYocy0+bWFwcGluZyksIG1hcHBpbmcpOwoJCQllbHNlCgkJCSAgICBhc3NlcnQoZmlyc3RfbWFwcGluZyA9PSBtYXBwaW5nLT5maXJzdF9tYXBwaW5nX2luZGV4KTsKCQkJaWYgKG1hcHBpbmctPmluZm8uZGlyLnBhcmVudF9tYXBwaW5nX2luZGV4IDwgMCkKCQkJICAgIGFzc2VydChqID09IDApOwoJCQllbHNlIHsKCQkJICAgIG1hcHBpbmdfdCogcGFyZW50ID0gYXJyYXlfZ2V0KCYocy0+bWFwcGluZyksIG1hcHBpbmctPmluZm8uZGlyLnBhcmVudF9tYXBwaW5nX2luZGV4KTsKCQkJICAgIGFzc2VydChwYXJlbnQtPm1vZGUgJiBNT0RFX0RJUkVDVE9SWSk7CgkJCSAgICBhc3NlcnQocGFyZW50LT5pbmZvLmRpci5maXJzdF9kaXJfaW5kZXggPCBtYXBwaW5nLT5pbmZvLmRpci5maXJzdF9kaXJfaW5kZXgpOwoJCQl9CgkJICAgIH0KCQl9CgkgICAgfQoJICAgIGlmIChjb3VudCA9PSAwKQoJCWZpcnN0X21hcHBpbmcgPSAtMTsKCX0KICAgIH0KfQojZW5kaWYKCnN0YXRpYyBpbnQgaGFuZGxlX3JlbmFtZXNfYW5kX21rZGlycyhCRFJWVlZGQVRTdGF0ZSogcykKewogICAgaW50IGk7CgojaWZkZWYgREVCVUcKICAgIGZwcmludGYoc3RkZXJyLCAiaGFuZGxlX3JlbmFtZXNcbiIpOwogICAgZm9yIChpID0gMDsgaSA8IHMtPmNvbW1pdHMubmV4dDsgaSsrKSB7Cgljb21taXRfdCogY29tbWl0ID0gYXJyYXlfZ2V0KCYocy0+Y29tbWl0cyksIGkpOwoJZnByaW50ZihzdGRlcnIsICIlZCwgJXMgKCVkLCAlZClcbiIsIGksIGNvbW1pdC0+cGF0aCA/IGNvbW1pdC0+cGF0aCA6ICIobnVsbCkiLCBjb21taXQtPnBhcmFtLnJlbmFtZS5jbHVzdGVyLCBjb21taXQtPmFjdGlvbik7CiAgICB9CiNlbmRpZgoKICAgIGZvciAoaSA9IDA7IGkgPCBzLT5jb21taXRzLm5leHQ7KSB7Cgljb21taXRfdCogY29tbWl0ID0gYXJyYXlfZ2V0KCYocy0+Y29tbWl0cyksIGkpOwoJaWYgKGNvbW1pdC0+YWN0aW9uID09IEFDVElPTl9SRU5BTUUpIHsKCSAgICBtYXBwaW5nX3QqIG1hcHBpbmcgPSBmaW5kX21hcHBpbmdfZm9yX2NsdXN0ZXIocywKCQkgICAgY29tbWl0LT5wYXJhbS5yZW5hbWUuY2x1c3Rlcik7CgkgICAgY2hhciogb2xkX3BhdGggPSBtYXBwaW5nLT5wYXRoOwoKCSAgICBhc3NlcnQoY29tbWl0LT5wYXRoKTsKCSAgICBtYXBwaW5nLT5wYXRoID0gY29tbWl0LT5wYXRoOwoJICAgIGlmIChyZW5hbWUob2xkX3BhdGgsIG1hcHBpbmctPnBhdGgpKQoJCXJldHVybiAtMjsKCgkgICAgaWYgKG1hcHBpbmctPm1vZGUgJiBNT0RFX0RJUkVDVE9SWSkgewoJCWludCBsMSA9IHN0cmxlbihtYXBwaW5nLT5wYXRoKTsKCQlpbnQgbDIgPSBzdHJsZW4ob2xkX3BhdGgpOwoJCWludCBkaWZmID0gbDEgLSBsMjsKCQlkaXJlbnRyeV90KiBkaXJlbnRyeSA9IGFycmF5X2dldCgmKHMtPmRpcmVjdG9yeSksCgkJCW1hcHBpbmctPmluZm8uZGlyLmZpcnN0X2Rpcl9pbmRleCk7CgkJdWludDMyX3QgYyA9IG1hcHBpbmctPmJlZ2luOwoJCWludCBpID0gMDsKCgkJLyogcmVjdXJzZSAqLwoJCXdoaWxlICghZmF0X2VvZihzLCBjKSkgewoJCSAgICBkbyB7CgkJCWRpcmVudHJ5X3QqIGQgPSBkaXJlbnRyeSArIGk7CgoJCQlpZiAoaXNfZmlsZShkKSB8fCAoaXNfZGlyZWN0b3J5KGQpICYmICFpc19kb3QoZCkpKSB7CgkJCSAgICBtYXBwaW5nX3QqIG0gPSBmaW5kX21hcHBpbmdfZm9yX2NsdXN0ZXIocywKCQkJCSAgICBiZWdpbl9vZl9kaXJlbnRyeShkKSk7CgkJCSAgICBpbnQgbCA9IHN0cmxlbihtLT5wYXRoKTsKCQkJICAgIGNoYXIqIG5ld19wYXRoID0gbWFsbG9jKGwgKyBkaWZmICsgMSk7CgoJCQkgICAgYXNzZXJ0KCFzdHJuY21wKG0tPnBhdGgsIG1hcHBpbmctPnBhdGgsIGwyKSk7CgoJCQkgICAgc3RyY3B5KG5ld19wYXRoLCBtYXBwaW5nLT5wYXRoKTsKCQkJICAgIHN0cmNweShuZXdfcGF0aCArIGwxLCBtLT5wYXRoICsgbDIpOwoKCQkJICAgIHNjaGVkdWxlX3JlbmFtZShzLCBtLT5iZWdpbiwgbmV3X3BhdGgpOwoJCQl9CgkJCWkrKzsKCQkgICAgfSB3aGlsZSgoaSAlICgweDEwICogcy0+c2VjdG9yc19wZXJfY2x1c3RlcikpICE9IDApOwoJCSAgICBjID0gZmF0X2dldChzLCBjKTsKCQl9CgkgICAgfQoKCSAgICBmcmVlKG9sZF9wYXRoKTsKCSAgICBhcnJheV9yZW1vdmUoJihzLT5jb21taXRzKSwgaSk7CgkgICAgY29udGludWU7Cgl9IGVsc2UgaWYgKGNvbW1pdC0+YWN0aW9uID09IEFDVElPTl9NS0RJUikgewoJICAgIG1hcHBpbmdfdCogbWFwcGluZzsKCSAgICBpbnQgaiwgcGFyZW50X3BhdGhfbGVuOwoKI2lmZGVmIF9fTUlOR1czMl9fCiAgICAgICAgICAgIGlmIChta2Rpcihjb21taXQtPnBhdGgpKQogICAgICAgICAgICAgICAgcmV0dXJuIC01OwojZWxzZQogICAgICAgICAgICBpZiAobWtkaXIoY29tbWl0LT5wYXRoLCAwNzU1KSkKICAgICAgICAgICAgICAgIHJldHVybiAtNTsKI2VuZGlmCgoJICAgIG1hcHBpbmcgPSBpbnNlcnRfbWFwcGluZyhzLCBjb21taXQtPnBhcmFtLm1rZGlyLmNsdXN0ZXIsCgkJICAgIGNvbW1pdC0+cGFyYW0ubWtkaXIuY2x1c3RlciArIDEpOwoJICAgIGlmIChtYXBwaW5nID09IE5VTEwpCgkJcmV0dXJuIC02OwoKCSAgICBtYXBwaW5nLT5tb2RlID0gTU9ERV9ESVJFQ1RPUlk7CgkgICAgbWFwcGluZy0+cmVhZF9vbmx5ID0gMDsKCSAgICBtYXBwaW5nLT5wYXRoID0gY29tbWl0LT5wYXRoOwoJICAgIGogPSBzLT5kaXJlY3RvcnkubmV4dDsKCSAgICBhc3NlcnQoaik7CgkgICAgaW5zZXJ0X2RpcmVudHJpZXMocywgcy0+ZGlyZWN0b3J5Lm5leHQsCgkJICAgIDB4MTAgKiBzLT5zZWN0b3JzX3Blcl9jbHVzdGVyKTsKCSAgICBtYXBwaW5nLT5pbmZvLmRpci5maXJzdF9kaXJfaW5kZXggPSBqOwoKCSAgICBwYXJlbnRfcGF0aF9sZW4gPSBzdHJsZW4oY29tbWl0LT5wYXRoKQoJCS0gc3RybGVuKGdldF9iYXNlbmFtZShjb21taXQtPnBhdGgpKSAtIDE7CgkgICAgZm9yIChqID0gMDsgaiA8IHMtPm1hcHBpbmcubmV4dDsgaisrKSB7CgkJbWFwcGluZ190KiBtID0gYXJyYXlfZ2V0KCYocy0+bWFwcGluZyksIGopOwoJCWlmIChtLT5maXJzdF9tYXBwaW5nX2luZGV4IDwgMCAmJiBtICE9IG1hcHBpbmcgJiYKCQkJIXN0cm5jbXAobS0+cGF0aCwgbWFwcGluZy0+cGF0aCwgcGFyZW50X3BhdGhfbGVuKSAmJgoJCQlzdHJsZW4obS0+cGF0aCkgPT0gcGFyZW50X3BhdGhfbGVuKQoJCSAgICBicmVhazsKCSAgICB9CgkgICAgYXNzZXJ0KGogPCBzLT5tYXBwaW5nLm5leHQpOwoJICAgIG1hcHBpbmctPmluZm8uZGlyLnBhcmVudF9tYXBwaW5nX2luZGV4ID0gajsKCgkgICAgYXJyYXlfcmVtb3ZlKCYocy0+Y29tbWl0cyksIGkpOwoJICAgIGNvbnRpbnVlOwoJfQoKCWkrKzsKICAgIH0KICAgIHJldHVybiAwOwp9CgovKgogKiBUT0RPOiBtYWtlIHN1cmUgdGhhdCB0aGUgc2hvcnQgbmFtZSBpcyBub3QgbWF0Y2hpbmcgKmFub3RoZXIqIGZpbGUKICovCnN0YXRpYyBpbnQgaGFuZGxlX2NvbW1pdHMoQkRSVlZWRkFUU3RhdGUqIHMpCnsKICAgIGludCBpLCBmYWlsID0gMDsKCiAgICB2dmZhdF9jbG9zZV9jdXJyZW50X2ZpbGUocyk7CgogICAgZm9yIChpID0gMDsgIWZhaWwgJiYgaSA8IHMtPmNvbW1pdHMubmV4dDsgaSsrKSB7Cgljb21taXRfdCogY29tbWl0ID0gYXJyYXlfZ2V0KCYocy0+Y29tbWl0cyksIGkpOwoJc3dpdGNoKGNvbW1pdC0+YWN0aW9uKSB7CgljYXNlIEFDVElPTl9SRU5BTUU6IGNhc2UgQUNUSU9OX01LRElSOgoJICAgIGFzc2VydCgwKTsKCSAgICBmYWlsID0gLTI7CgkgICAgYnJlYWs7CgljYXNlIEFDVElPTl9XUklURU9VVDogewoJICAgIGRpcmVudHJ5X3QqIGVudHJ5ID0gYXJyYXlfZ2V0KCYocy0+ZGlyZWN0b3J5KSwKCQkgICAgY29tbWl0LT5wYXJhbS53cml0ZW91dC5kaXJfaW5kZXgpOwoJICAgIHVpbnQzMl90IGJlZ2luID0gYmVnaW5fb2ZfZGlyZW50cnkoZW50cnkpOwoJICAgIG1hcHBpbmdfdCogbWFwcGluZyA9IGZpbmRfbWFwcGluZ19mb3JfY2x1c3RlcihzLCBiZWdpbik7CgoJICAgIGFzc2VydChtYXBwaW5nKTsKCSAgICBhc3NlcnQobWFwcGluZy0+YmVnaW4gPT0gYmVnaW4pOwoJICAgIGFzc2VydChjb21taXQtPnBhdGggPT0gTlVMTCk7CgoJICAgIGlmIChjb21taXRfb25lX2ZpbGUocywgY29tbWl0LT5wYXJhbS53cml0ZW91dC5kaXJfaW5kZXgsCgkJCWNvbW1pdC0+cGFyYW0ud3JpdGVvdXQubW9kaWZpZWRfb2Zmc2V0KSkKCQlmYWlsID0gLTM7CgoJICAgIGJyZWFrOwoJfQoJY2FzZSBBQ1RJT05fTkVXX0ZJTEU6IHsKCSAgICBpbnQgYmVnaW4gPSBjb21taXQtPnBhcmFtLm5ld19maWxlLmZpcnN0X2NsdXN0ZXI7CgkgICAgbWFwcGluZ190KiBtYXBwaW5nID0gZmluZF9tYXBwaW5nX2Zvcl9jbHVzdGVyKHMsIGJlZ2luKTsKCSAgICBkaXJlbnRyeV90KiBlbnRyeTsKCSAgICBpbnQgaTsKCgkgICAgLyogZmluZCBkaXJlbnRyeSAqLwoJICAgIGZvciAoaSA9IDA7IGkgPCBzLT5kaXJlY3RvcnkubmV4dDsgaSsrKSB7CgkJZW50cnkgPSBhcnJheV9nZXQoJihzLT5kaXJlY3RvcnkpLCBpKTsKCQlpZiAoaXNfZmlsZShlbnRyeSkgJiYgYmVnaW5fb2ZfZGlyZW50cnkoZW50cnkpID09IGJlZ2luKQoJCSAgICBicmVhazsKCSAgICB9CgoJICAgIGlmIChpID49IHMtPmRpcmVjdG9yeS5uZXh0KSB7CgkJZmFpbCA9IC02OwoJCWNvbnRpbnVlOwoJICAgIH0KCgkgICAgLyogbWFrZSBzdXJlIHRoZXJlIGV4aXN0cyBhbiBpbml0aWFsIG1hcHBpbmcgKi8KCSAgICBpZiAobWFwcGluZyAmJiBtYXBwaW5nLT5iZWdpbiAhPSBiZWdpbikgewoJCW1hcHBpbmctPmVuZCA9IGJlZ2luOwoJCW1hcHBpbmcgPSBOVUxMOwoJICAgIH0KCSAgICBpZiAobWFwcGluZyA9PSBOVUxMKSB7CgkJbWFwcGluZyA9IGluc2VydF9tYXBwaW5nKHMsIGJlZ2luLCBiZWdpbisxKTsKCSAgICB9CgkgICAgLyogbW9zdCBtZW1iZXJzIHdpbGwgYmUgZml4ZWQgaW4gY29tbWl0X21hcHBpbmdzKCkgKi8KCSAgICBhc3NlcnQoY29tbWl0LT5wYXRoKTsKCSAgICBtYXBwaW5nLT5wYXRoID0gY29tbWl0LT5wYXRoOwoJICAgIG1hcHBpbmctPnJlYWRfb25seSA9IDA7CgkgICAgbWFwcGluZy0+bW9kZSA9IE1PREVfTk9STUFMOwoJICAgIG1hcHBpbmctPmluZm8uZmlsZS5vZmZzZXQgPSAwOwoKCSAgICBpZiAoY29tbWl0X29uZV9maWxlKHMsIGksIDApKQoJCWZhaWwgPSAtNzsKCgkgICAgYnJlYWs7Cgl9CglkZWZhdWx0OgoJICAgIGFzc2VydCgwKTsKCX0KICAgIH0KICAgIGlmIChpID4gMCAmJiBhcnJheV9yZW1vdmVfc2xpY2UoJihzLT5jb21taXRzKSwgMCwgaSkpCglyZXR1cm4gLTE7CiAgICByZXR1cm4gZmFpbDsKfQoKc3RhdGljIGludCBoYW5kbGVfZGVsZXRlcyhCRFJWVlZGQVRTdGF0ZSogcykKewogICAgaW50IGksIGRlZmVycmVkID0gMSwgZGVsZXRlZCA9IDE7CgogICAgLyogZGVsZXRlIGZpbGVzIGNvcnJlc3BvbmRpbmcgdG8gbWFwcGluZ3MgbWFya2VkIGFzIGRlbGV0ZWQgKi8KICAgIC8qIGhhbmRsZSBERUxFVEVzIGFuZCB1bnVzZWQgbWFwcGluZ3MgKG1vZGlmaWVkX2ZhdF9nZXQocywgbWFwcGluZy0+YmVnaW4pID09IDApICovCiAgICB3aGlsZSAoZGVmZXJyZWQgJiYgZGVsZXRlZCkgewoJZGVmZXJyZWQgPSAwOwoJZGVsZXRlZCA9IDA7CgoJZm9yIChpID0gMTsgaSA8IHMtPm1hcHBpbmcubmV4dDsgaSsrKSB7CgkgICAgbWFwcGluZ190KiBtYXBwaW5nID0gYXJyYXlfZ2V0KCYocy0+bWFwcGluZyksIGkpOwoJICAgIGlmIChtYXBwaW5nLT5tb2RlICYgTU9ERV9ERUxFVEVEKSB7CgkJZGlyZW50cnlfdCogZW50cnkgPSBhcnJheV9nZXQoJihzLT5kaXJlY3RvcnkpLAoJCQltYXBwaW5nLT5kaXJfaW5kZXgpOwoKCQlpZiAoaXNfZnJlZShlbnRyeSkpIHsKCQkgICAgLyogcmVtb3ZlIGZpbGUvZGlyZWN0b3J5ICovCgkJICAgIGlmIChtYXBwaW5nLT5tb2RlICYgTU9ERV9ESVJFQ1RPUlkpIHsKCQkJaW50IGosIG5leHRfZGlyX2luZGV4ID0gcy0+ZGlyZWN0b3J5Lm5leHQsCgkJCWZpcnN0X2Rpcl9pbmRleCA9IG1hcHBpbmctPmluZm8uZGlyLmZpcnN0X2Rpcl9pbmRleDsKCgkJCWlmIChybWRpcihtYXBwaW5nLT5wYXRoKSA8IDApIHsKCQkJICAgIGlmIChlcnJubyA9PSBFTk9URU1QVFkpIHsKCQkJCWRlZmVycmVkKys7CgkJCQljb250aW51ZTsKCQkJICAgIH0gZWxzZQoJCQkJcmV0dXJuIC01OwoJCQl9CgoJCQlmb3IgKGogPSAxOyBqIDwgcy0+bWFwcGluZy5uZXh0OyBqKyspIHsKCQkJICAgIG1hcHBpbmdfdCogbSA9IGFycmF5X2dldCgmKHMtPm1hcHBpbmcpLCBqKTsKCQkJICAgIGlmIChtLT5tb2RlICYgTU9ERV9ESVJFQ1RPUlkgJiYKCQkJCSAgICBtLT5pbmZvLmRpci5maXJzdF9kaXJfaW5kZXggPgoJCQkJICAgIGZpcnN0X2Rpcl9pbmRleCAmJgoJCQkJICAgIG0tPmluZm8uZGlyLmZpcnN0X2Rpcl9pbmRleCA8CgkJCQkgICAgbmV4dF9kaXJfaW5kZXgpCgkJCQluZXh0X2Rpcl9pbmRleCA9CgkJCQkgICAgbS0+aW5mby5kaXIuZmlyc3RfZGlyX2luZGV4OwoJCQl9CgkJCXJlbW92ZV9kaXJlbnRyaWVzKHMsIGZpcnN0X2Rpcl9pbmRleCwKCQkJCW5leHRfZGlyX2luZGV4IC0gZmlyc3RfZGlyX2luZGV4KTsKCgkJCWRlbGV0ZWQrKzsKCQkgICAgfQoJCX0gZWxzZSB7CgkJICAgIGlmICh1bmxpbmsobWFwcGluZy0+cGF0aCkpCgkJCXJldHVybiAtNDsKCQkgICAgZGVsZXRlZCsrOwoJCX0KCQlETE9HKGZwcmludGYoc3RkZXJyLCAiREVMRVRFICglZClcbiIsIGkpOyBwcmludF9tYXBwaW5nKG1hcHBpbmcpOyBwcmludF9kaXJlbnRyeShlbnRyeSkpOwoJCXJlbW92ZV9tYXBwaW5nKHMsIGkpOwoJICAgIH0KCX0KICAgIH0KCiAgICByZXR1cm4gMDsKfQoKLyoKICogc3luY2hyb25pemUgbWFwcGluZyB3aXRoIG5ldyBzdGF0ZToKICoKICogLSBjb3B5IEZBVCAod2l0aCBiZHJ2X3JlYWQpCiAqIC0gbWFyayBhbGwgZmlsZW5hbWVzIGNvcnJlc3BvbmRpbmcgdG8gbWFwcGluZ3MgYXMgZGVsZXRlZAogKiAtIHJlY3Vyc2UgZGlyZW50cmllcyBmcm9tIHJvb3QgKHVzaW5nIGJzLT5iZHJ2X3JlYWQpCiAqIC0gZGVsZXRlIGZpbGVzIGNvcnJlc3BvbmRpbmcgdG8gbWFwcGluZ3MgbWFya2VkIGFzIGRlbGV0ZWQKICovCnN0YXRpYyBpbnQgZG9fY29tbWl0KEJEUlZWVkZBVFN0YXRlKiBzKQp7CiAgICBpbnQgcmV0ID0gMDsKCiAgICAvKiB0aGUgcmVhbCBtZWF0IGFyZSB0aGUgY29tbWl0cy4gTm90aGluZyB0byBkbz8gTW92ZSBhbG9uZyEgKi8KICAgIGlmIChzLT5jb21taXRzLm5leHQgPT0gMCkKCXJldHVybiAwOwoKICAgIHZ2ZmF0X2Nsb3NlX2N1cnJlbnRfZmlsZShzKTsKCiAgICByZXQgPSBoYW5kbGVfcmVuYW1lc19hbmRfbWtkaXJzKHMpOwogICAgaWYgKHJldCkgewoJZnByaW50ZihzdGRlcnIsICJFcnJvciBoYW5kbGluZyByZW5hbWVzICglZClcbiIsIHJldCk7Cglhc3NlcnQoMCk7CglyZXR1cm4gcmV0OwogICAgfQoKICAgIC8qIGNvcHkgRkFUICh3aXRoIGJkcnZfcmVhZCkgKi8KICAgIG1lbWNweShzLT5mYXQucG9pbnRlciwgcy0+ZmF0MiwgMHgyMDAgKiBzLT5zZWN0b3JzX3Blcl9mYXQpOwoKICAgIC8qIHJlY3Vyc2UgZGlyZW50cmllcyBmcm9tIHJvb3QgKHVzaW5nIGJzLT5iZHJ2X3JlYWQpICovCiAgICByZXQgPSBjb21taXRfZGlyZW50cmllcyhzLCAwLCAtMSk7CiAgICBpZiAocmV0KSB7CglmcHJpbnRmKHN0ZGVyciwgIkZhdGFsOiBlcnJvciB3aGlsZSBjb21taXR0aW5nICglZClcbiIsIHJldCk7Cglhc3NlcnQoMCk7CglyZXR1cm4gcmV0OwogICAgfQoKICAgIHJldCA9IGhhbmRsZV9jb21taXRzKHMpOwogICAgaWYgKHJldCkgewoJZnByaW50ZihzdGRlcnIsICJFcnJvciBoYW5kbGluZyBjb21taXRzICglZClcbiIsIHJldCk7Cglhc3NlcnQoMCk7CglyZXR1cm4gcmV0OwogICAgfQoKICAgIHJldCA9IGhhbmRsZV9kZWxldGVzKHMpOwogICAgaWYgKHJldCkgewoJZnByaW50ZihzdGRlcnIsICJFcnJvciBkZWxldGluZ1xuIik7CiAgICAgICAgYXNzZXJ0KDApOwoJcmV0dXJuIHJldDsKICAgIH0KCiAgICBzLT5xY293LT5kcnYtPmJkcnZfbWFrZV9lbXB0eShzLT5xY293KTsKCiAgICBtZW1zZXQocy0+dXNlZF9jbHVzdGVycywgMCwgc2VjdG9yMmNsdXN0ZXIocywgcy0+c2VjdG9yX2NvdW50KSk7CgpETE9HKGNoZWNrcG9pbnQoKSk7CiAgICByZXR1cm4gMDsKfQoKc3RhdGljIGludCB0cnlfY29tbWl0KEJEUlZWVkZBVFN0YXRlKiBzKQp7CiAgICB2dmZhdF9jbG9zZV9jdXJyZW50X2ZpbGUocyk7CkRMT0coY2hlY2twb2ludCgpKTsKICAgIGlmKCFpc19jb25zaXN0ZW50KHMpKQoJcmV0dXJuIC0xOwogICAgcmV0dXJuIGRvX2NvbW1pdChzKTsKfQoKc3RhdGljIGludCB2dmZhdF93cml0ZShCbG9ja0RyaXZlclN0YXRlICpicywgaW50NjRfdCBzZWN0b3JfbnVtLAogICAgICAgICAgICAgICAgICAgIGNvbnN0IHVpbnQ4X3QgKmJ1ZiwgaW50IG5iX3NlY3RvcnMpCnsKICAgIEJEUlZWVkZBVFN0YXRlICpzID0gYnMtPm9wYXF1ZTsKICAgIGludCBpLCByZXQ7CgpETE9HKGNoZWNrcG9pbnQoKSk7CgogICAgdnZmYXRfY2xvc2VfY3VycmVudF9maWxlKHMpOwoKICAgIC8qCiAgICAgKiBTb21lIHNhbml0eSBjaGVja3M6CiAgICAgKiAtIGRvIG5vdCBhbGxvdyB3cml0aW5nIHRvIHRoZSBib290IHNlY3RvcgogICAgICogLSBkbyBub3QgYWxsb3cgdG8gd3JpdGUgbm9uLUFTQ0lJIGZpbGVuYW1lcwogICAgICovCgogICAgaWYgKHNlY3Rvcl9udW0gPCBzLT5maXJzdF9zZWN0b3JzX251bWJlcikKCXJldHVybiAtMTsKCiAgICBmb3IgKGkgPSBzZWN0b3IyY2x1c3RlcihzLCBzZWN0b3JfbnVtKTsKCSAgICBpIDw9IHNlY3RvcjJjbHVzdGVyKHMsIHNlY3Rvcl9udW0gKyBuYl9zZWN0b3JzIC0gMSk7KSB7CgltYXBwaW5nX3QqIG1hcHBpbmcgPSBmaW5kX21hcHBpbmdfZm9yX2NsdXN0ZXIocywgaSk7CglpZiAobWFwcGluZykgewoJICAgIGlmIChtYXBwaW5nLT5yZWFkX29ubHkpIHsKCQlmcHJpbnRmKHN0ZGVyciwgIlRyaWVkIHRvIHdyaXRlIHRvIHdyaXRlLXByb3RlY3RlZCBmaWxlICVzXG4iLAoJCQltYXBwaW5nLT5wYXRoKTsKCQlyZXR1cm4gLTE7CgkgICAgfQoKCSAgICBpZiAobWFwcGluZy0+bW9kZSAmIE1PREVfRElSRUNUT1JZKSB7CgkJaW50IGJlZ2luID0gY2x1c3RlcjJzZWN0b3IocywgaSk7CgkJaW50IGVuZCA9IGJlZ2luICsgcy0+c2VjdG9yc19wZXJfY2x1c3RlciwgazsKCQlpbnQgZGlyX2luZGV4OwoJCWNvbnN0IGRpcmVudHJ5X3QqIGRpcmVudHJpZXM7CgkJbG9uZ19maWxlX25hbWUgbGZuOwoKCQlsZm5faW5pdCgmbGZuKTsKCgkJaWYgKGJlZ2luIDwgc2VjdG9yX251bSkKCQkgICAgYmVnaW4gPSBzZWN0b3JfbnVtOwoJCWlmIChlbmQgPiBzZWN0b3JfbnVtICsgbmJfc2VjdG9ycykKCQkgICAgZW5kID0gc2VjdG9yX251bSArIG5iX3NlY3RvcnM7CgkJZGlyX2luZGV4ICA9IG1hcHBpbmctPmRpcl9pbmRleCArCgkJICAgIDB4MTAgKiAoYmVnaW4gLSBtYXBwaW5nLT5iZWdpbiAqIHMtPnNlY3RvcnNfcGVyX2NsdXN0ZXIpOwoJCWRpcmVudHJpZXMgPSAoZGlyZW50cnlfdCopKGJ1ZiArIDB4MjAwICogKGJlZ2luIC0gc2VjdG9yX251bSkpOwoKCQlmb3IgKGsgPSAwOyBrIDwgKGVuZCAtIGJlZ2luKSAqIDB4MTA7IGsrKykgewoJCSAgICAvKiBkbyBub3QgYWxsb3cgbm9uLUFTQ0lJIGZpbGVuYW1lcyAqLwoJCSAgICBpZiAocGFyc2VfbG9uZ19uYW1lKCZsZm4sIGRpcmVudHJpZXMgKyBrKSA8IDApIHsKCQkJZnByaW50ZihzdGRlcnIsICJXYXJuaW5nOiBub24tQVNDSUkgZmlsZW5hbWVcbiIpOwoJCQlyZXR1cm4gLTE7CgkJICAgIH0KCQkgICAgLyogbm8gYWNjZXNzIHRvIHRoZSBkaXJlbnRyeSBvZiBhIHJlYWQtb25seSBmaWxlICovCgkJICAgIGVsc2UgaWYgKGlzX3Nob3J0X25hbWUoZGlyZW50cmllcytrKSAmJgoJCQkgICAgKGRpcmVudHJpZXNba10uYXR0cmlidXRlcyAmIDEpKSB7CgkJCWlmIChtZW1jbXAoZGlyZW50cmllcyArIGssCgkJCQkgICAgYXJyYXlfZ2V0KCYocy0+ZGlyZWN0b3J5KSwgZGlyX2luZGV4ICsgayksCgkJCQkgICAgc2l6ZW9mKGRpcmVudHJ5X3QpKSkgewoJCQkgICAgZnByaW50ZihzdGRlcnIsICJXYXJuaW5nOiB0cmllZCB0byB3cml0ZSB0byB3cml0ZS1wcm90ZWN0ZWQgZmlsZVxuIik7CgkJCSAgICByZXR1cm4gLTE7CgkJCX0KCQkgICAgfQoJCX0KCSAgICB9CgkgICAgaSA9IG1hcHBpbmctPmVuZDsKCX0gZWxzZQoJICAgIGkrKzsKICAgIH0KCiAgICAvKgogICAgICogVXNlIHFjb3cgYmFja2VuZC4gQ29tbWl0IGxhdGVyLgogICAgICovCkRMT0coZnByaW50ZihzdGRlcnIsICJXcml0ZSB0byBxY293IGJhY2tlbmQ6ICVkICsgJWRcbiIsIChpbnQpc2VjdG9yX251bSwgbmJfc2VjdG9ycykpOwogICAgcmV0ID0gcy0+cWNvdy0+ZHJ2LT5iZHJ2X3dyaXRlKHMtPnFjb3csIHNlY3Rvcl9udW0sIGJ1ZiwgbmJfc2VjdG9ycyk7CiAgICBpZiAocmV0IDwgMCkgewoJZnByaW50ZihzdGRlcnIsICJFcnJvciB3cml0aW5nIHRvIHFjb3cgYmFja2VuZFxuIik7CglyZXR1cm4gcmV0OwogICAgfQoKICAgIGZvciAoaSA9IHNlY3RvcjJjbHVzdGVyKHMsIHNlY3Rvcl9udW0pOwoJICAgIGkgPD0gc2VjdG9yMmNsdXN0ZXIocywgc2VjdG9yX251bSArIG5iX3NlY3RvcnMgLSAxKTsgaSsrKQoJaWYgKGkgPj0gMCkKCSAgICBzLT51c2VkX2NsdXN0ZXJzW2ldIHw9IFVTRURfQUxMT0NBVEVEOwoKRExPRyhjaGVja3BvaW50KCkpOwogICAgLyogVE9ETzogYWRkIHRpbWVvdXQgKi8KICAgIHRyeV9jb21taXQocyk7CgpETE9HKGNoZWNrcG9pbnQoKSk7CiAgICByZXR1cm4gMDsKfQoKc3RhdGljIGludCB2dmZhdF9pc19hbGxvY2F0ZWQoQmxvY2tEcml2ZXJTdGF0ZSAqYnMsCglpbnQ2NF90IHNlY3Rvcl9udW0sIGludCBuYl9zZWN0b3JzLCBpbnQqIG4pCnsKICAgIEJEUlZWVkZBVFN0YXRlKiBzID0gYnMtPm9wYXF1ZTsKICAgICpuID0gcy0+c2VjdG9yX2NvdW50IC0gc2VjdG9yX251bTsKICAgIGlmICgqbiA+IG5iX3NlY3RvcnMpCgkqbiA9IG5iX3NlY3RvcnM7CiAgICBlbHNlIGlmICgqbiA8IDApCglyZXR1cm4gMDsKICAgIHJldHVybiAxOwp9CgpzdGF0aWMgaW50IHdyaXRlX3RhcmdldF9jb21taXQoQmxvY2tEcml2ZXJTdGF0ZSAqYnMsIGludDY0X3Qgc2VjdG9yX251bSwKCWNvbnN0IHVpbnQ4X3QqIGJ1ZmZlciwgaW50IG5iX3NlY3RvcnMpIHsKICAgIEJEUlZWVkZBVFN0YXRlKiBzID0gYnMtPm9wYXF1ZTsKICAgIHJldHVybiB0cnlfY29tbWl0KHMpOwp9CgpzdGF0aWMgdm9pZCB3cml0ZV90YXJnZXRfY2xvc2UoQmxvY2tEcml2ZXJTdGF0ZSAqYnMpIHsKICAgIEJEUlZWVkZBVFN0YXRlKiBzID0gYnMtPm9wYXF1ZTsKICAgIGJkcnZfZGVsZXRlKHMtPnFjb3cpOwogICAgZnJlZShzLT5xY293X2ZpbGVuYW1lKTsKfQoKc3RhdGljIEJsb2NrRHJpdmVyIHZ2ZmF0X3dyaXRlX3RhcmdldCA9IHsKICAgICJ2dmZhdF93cml0ZV90YXJnZXQiLCAwLCBOVUxMLCBOVUxMLCBOVUxMLAogICAgd3JpdGVfdGFyZ2V0X2NvbW1pdCwKICAgIHdyaXRlX3RhcmdldF9jbG9zZSwKICAgIE5VTEwsIE5VTEwsIE5VTEwKfTsKCnN0YXRpYyBpbnQgZW5hYmxlX3dyaXRlX3RhcmdldChCRFJWVlZGQVRTdGF0ZSAqcykKewogICAgaW50IHNpemUgPSBzZWN0b3IyY2x1c3RlcihzLCBzLT5zZWN0b3JfY291bnQpOwogICAgcy0+dXNlZF9jbHVzdGVycyA9IGNhbGxvYyhzaXplLCAxKTsKCiAgICBhcnJheV9pbml0KCYocy0+Y29tbWl0cyksIHNpemVvZihjb21taXRfdCkpOwoKICAgIHMtPnFjb3dfZmlsZW5hbWUgPSBtYWxsb2MoMTAyNCk7CiAgICBnZXRfdG1wX2ZpbGVuYW1lKHMtPnFjb3dfZmlsZW5hbWUsIDEwMjQpOwogICAgaWYgKGJkcnZfY3JlYXRlKCZiZHJ2X3Fjb3csCgkJcy0+cWNvd19maWxlbmFtZSwgcy0+c2VjdG9yX2NvdW50LCAiZmF0OiIsIDApIDwgMCkKCXJldHVybiAtMTsKICAgIHMtPnFjb3cgPSBiZHJ2X25ldygiIik7CiAgICBpZiAocy0+cWNvdyA9PSBOVUxMIHx8IGJkcnZfb3BlbihzLT5xY293LCBzLT5xY293X2ZpbGVuYW1lLCAwKSA8IDApCglyZXR1cm4gLTE7CgojaWZuZGVmIF9XSU4zMgogICAgdW5saW5rKHMtPnFjb3dfZmlsZW5hbWUpOwojZW5kaWYKCiAgICBzLT5icy0+YmFja2luZ19oZCA9IGNhbGxvYyhzaXplb2YoQmxvY2tEcml2ZXJTdGF0ZSksIDEpOwogICAgcy0+YnMtPmJhY2tpbmdfaGQtPmRydiA9ICZ2dmZhdF93cml0ZV90YXJnZXQ7CiAgICBzLT5icy0+YmFja2luZ19oZC0+b3BhcXVlID0gczsKCiAgICByZXR1cm4gMDsKfQoKc3RhdGljIHZvaWQgdnZmYXRfY2xvc2UoQmxvY2tEcml2ZXJTdGF0ZSAqYnMpCnsKICAgIEJEUlZWVkZBVFN0YXRlICpzID0gYnMtPm9wYXF1ZTsKCiAgICB2dmZhdF9jbG9zZV9jdXJyZW50X2ZpbGUocyk7CiAgICBhcnJheV9mcmVlKCYocy0+ZmF0KSk7CiAgICBhcnJheV9mcmVlKCYocy0+ZGlyZWN0b3J5KSk7CiAgICBhcnJheV9mcmVlKCYocy0+bWFwcGluZykpOwogICAgaWYocy0+Y2x1c3Rlcl9idWZmZXIpCiAgICAgICAgZnJlZShzLT5jbHVzdGVyX2J1ZmZlcik7Cn0KCkJsb2NrRHJpdmVyIGJkcnZfdnZmYXQgPSB7CiAgICAidnZmYXQiLAogICAgc2l6ZW9mKEJEUlZWVkZBVFN0YXRlKSwKICAgIE5VTEwsIC8qIG5vIHByb2JlIGZvciBwcm90b2NvbHMgKi8KICAgIHZ2ZmF0X29wZW4sCiAgICB2dmZhdF9yZWFkLAogICAgdnZmYXRfd3JpdGUsCiAgICB2dmZhdF9jbG9zZSwKICAgIE5VTEwsIC8qID8/PyBOb3Qgc3VyZSBpZiB3ZSBjYW4gZG8gYW55IG1lYW5pbmdmdWwgZmx1c2hpbmcuICAqLwogICAgTlVMTCwKICAgIHZ2ZmF0X2lzX2FsbG9jYXRlZCwKICAgIC5wcm90b2NvbF9uYW1lID0gImZhdCIsCn07CgojaWZkZWYgREVCVUcKc3RhdGljIHZvaWQgY2hlY2twb2ludCgpIHsKICAgIGFzc2VydCgoKG1hcHBpbmdfdCopYXJyYXlfZ2V0KCYodnZ2LT5tYXBwaW5nKSwgMCkpLT5lbmQgPT0gMik7CiAgICBjaGVjazEodnZ2KTsKICAgIGNoZWNrMih2dnYpOwogICAgYXNzZXJ0KCF2dnYtPmN1cnJlbnRfbWFwcGluZyB8fCB2dnYtPmN1cnJlbnRfZmQgfHwgKHZ2di0+Y3VycmVudF9tYXBwaW5nLT5tb2RlICYgTU9ERV9ESVJFQ1RPUlkpKTsKI2lmIDAKICAgIGlmICgoKGRpcmVudHJ5X3QqKXZ2di0+ZGlyZWN0b3J5LnBvaW50ZXIpWzFdLmF0dHJpYnV0ZXMgIT0gMHhmKQoJZnByaW50ZihzdGRlcnIsICJOb25vbm8hXG4iKTsKICAgIG1hcHBpbmdfdCogbWFwcGluZzsKICAgIGRpcmVudHJ5X3QqIGRpcmVudHJ5OwogICAgYXNzZXJ0KHZ2di0+bWFwcGluZy5zaXplID49IHZ2di0+bWFwcGluZy5pdGVtX3NpemUgKiB2dnYtPm1hcHBpbmcubmV4dCk7CiAgICBhc3NlcnQodnZ2LT5kaXJlY3Rvcnkuc2l6ZSA+PSB2dnYtPmRpcmVjdG9yeS5pdGVtX3NpemUgKiB2dnYtPmRpcmVjdG9yeS5uZXh0KTsKICAgIGlmICh2dnYtPm1hcHBpbmcubmV4dDw0NykKCXJldHVybjsKICAgIGFzc2VydCgobWFwcGluZyA9IGFycmF5X2dldCgmKHZ2di0+bWFwcGluZyksIDQ3KSkpOwogICAgYXNzZXJ0KG1hcHBpbmctPmRpcl9pbmRleCA8IHZ2di0+ZGlyZWN0b3J5Lm5leHQpOwogICAgZGlyZW50cnkgPSBhcnJheV9nZXQoJih2dnYtPmRpcmVjdG9yeSksIG1hcHBpbmctPmRpcl9pbmRleCk7CiAgICBhc3NlcnQoIW1lbWNtcChkaXJlbnRyeS0+bmFtZSwgIlVTQiAgICAgSCAgIiwgMTEpIHx8IGRpcmVudHJ5LT5uYW1lWzBdPT0wKTsKI2VuZGlmCiAgICByZXR1cm47CiAgICAvKiBhdm9pZCBjb21waWxlciB3YXJuaW5nczogKi8KICAgIGhleGR1bXAoTlVMTCwgMTAwKTsKICAgIHJlbW92ZV9tYXBwaW5nKHZ2diwgTlVMTCk7CiAgICBwcmludF9tYXBwaW5nKE5VTEwpOwogICAgcHJpbnRfZGlyZW50cnkoTlVMTCk7Cn0KI2VuZGlmCgo=