LyoKICogIGVidGFibGVzCiAqCiAqICBBdXRob3I6CiAqICBCYXJ0IERlIFNjaHV5bWVyCQk8YmRzY2h1eW1AcGFuZG9yYS5iZT4KICoKICogIGVidGFibGVzLmMsdiAyLjAsIEp1bHksIDIwMDIKICoKICogIFRoaXMgY29kZSBpcyBzdG9uZ2x5IGluc3BpcmVkIG9uIHRoZSBpcHRhYmxlcyBjb2RlIHdoaWNoIGlzCiAqICBDb3B5cmlnaHQgKEMpIDE5OTkgUGF1bCBgUnVzdHknIFJ1c3NlbGwgJiBNaWNoYWVsIEouIE5ldWxpbmcKICoKICogIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqICBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyIHZlcnNpb24KICogIDIgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqLwoKLyogdXNlZCBmb3IgcHJpbnRfc3RyaW5nICovCiNpbmNsdWRlIDxsaW51eC9zY2hlZC5oPgojaW5jbHVkZSA8bGludXgvdHR5Lmg+CgojaW5jbHVkZSA8bGludXgva21vZC5oPgojaW5jbHVkZSA8bGludXgvbW9kdWxlLmg+CiNpbmNsdWRlIDxsaW51eC92bWFsbG9jLmg+CiNpbmNsdWRlIDxsaW51eC9uZXRmaWx0ZXJfYnJpZGdlL2VidGFibGVzLmg+CiNpbmNsdWRlIDxsaW51eC9zcGlubG9jay5oPgojaW5jbHVkZSA8bGludXgvbXV0ZXguaD4KI2luY2x1ZGUgPGFzbS91YWNjZXNzLmg+CiNpbmNsdWRlIDxsaW51eC9zbXAuaD4KI2luY2x1ZGUgPGxpbnV4L2NwdW1hc2suaD4KI2luY2x1ZGUgPG5ldC9zb2NrLmg+Ci8qIG5lZWRlZCBmb3IgbG9naWNhbCBbaW4sb3V0XS1kZXYgZmlsdGVyaW5nICovCiNpbmNsdWRlICIuLi9icl9wcml2YXRlLmgiCgojZGVmaW5lIEJVR1BSSU5UKGZvcm1hdCwgYXJncy4uLikgcHJpbnRrKCJrZXJuZWwgbXNnOiBlYnRhYmxlcyBidWc6IHBsZWFzZSAiXAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJyZXBvcnQgdG8gYXV0aG9yOiAiZm9ybWF0LCAjIyBhcmdzKQovKiAjZGVmaW5lIEJVR1BSSU5UKGZvcm1hdCwgYXJncy4uLikgKi8KI2RlZmluZSBNRU1QUklOVChmb3JtYXQsIGFyZ3MuLi4pIHByaW50aygia2VybmVsIG1zZzogZWJ0YWJsZXMgIlwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiOiBvdXQgb2YgbWVtb3J5OiAiZm9ybWF0LCAjIyBhcmdzKQovKiAjZGVmaW5lIE1FTVBSSU5UKGZvcm1hdCwgYXJncy4uLikgKi8KCgoKLyoKICogRWFjaCBjcHUgaGFzIGl0cyBvd24gc2V0IG9mIGNvdW50ZXJzLCBzbyB0aGVyZSBpcyBubyBuZWVkIGZvciB3cml0ZV9sb2NrIGluCiAqIHRoZSBzb2Z0aXJxCiAqIEZvciByZWFkaW5nIG9yIHVwZGF0aW5nIHRoZSBjb3VudGVycywgdGhlIHVzZXIgY29udGV4dCBuZWVkcyB0bwogKiBnZXQgYSB3cml0ZV9sb2NrCiAqLwoKLyogVGhlIHNpemUgb2YgZWFjaCBzZXQgb2YgY291bnRlcnMgaXMgYWx0ZXJlZCB0byBnZXQgY2FjaGUgYWxpZ25tZW50ICovCiNkZWZpbmUgU01QX0FMSUdOKHgpICgoKHgpICsgU01QX0NBQ0hFX0JZVEVTLTEpICYgfihTTVBfQ0FDSEVfQllURVMtMSkpCiNkZWZpbmUgQ09VTlRFUl9PRkZTRVQobikgKFNNUF9BTElHTihuICogc2l6ZW9mKHN0cnVjdCBlYnRfY291bnRlcikpKQojZGVmaW5lIENPVU5URVJfQkFTRShjLCBuLCBjcHUpICgoc3RydWN0IGVidF9jb3VudGVyICopKCgoY2hhciAqKWMpICsgXAogICBDT1VOVEVSX09GRlNFVChuKSAqIGNwdSkpCgoKCnN0YXRpYyBERUZJTkVfTVVURVgoZWJ0X211dGV4KTsKc3RhdGljIExJU1RfSEVBRChlYnRfdGFibGVzKTsKc3RhdGljIExJU1RfSEVBRChlYnRfdGFyZ2V0cyk7CnN0YXRpYyBMSVNUX0hFQUQoZWJ0X21hdGNoZXMpOwpzdGF0aWMgTElTVF9IRUFEKGVidF93YXRjaGVycyk7CgpzdGF0aWMgc3RydWN0IGVidF90YXJnZXQgZWJ0X3N0YW5kYXJkX3RhcmdldCA9Cnsge05VTEwsIE5VTEx9LCBFQlRfU1RBTkRBUkRfVEFSR0VULCBOVUxMLCBOVUxMLCBOVUxMLCBOVUxMfTsKCnN0YXRpYyBpbmxpbmUgaW50IGVidF9kb193YXRjaGVyIChzdHJ1Y3QgZWJ0X2VudHJ5X3dhdGNoZXIgKncsCiAgIGNvbnN0IHN0cnVjdCBza19idWZmICpza2IsIHVuc2lnbmVkIGludCBob29rbnIsIGNvbnN0IHN0cnVjdCBuZXRfZGV2aWNlICppbiwKICAgY29uc3Qgc3RydWN0IG5ldF9kZXZpY2UgKm91dCkKewoJdy0+dS53YXRjaGVyLT53YXRjaGVyKHNrYiwgaG9va25yLCBpbiwgb3V0LCB3LT5kYXRhLAoJICAgdy0+d2F0Y2hlcl9zaXplKTsKCS8qIHdhdGNoZXJzIGRvbid0IGdpdmUgYSB2ZXJkaWN0ICovCglyZXR1cm4gMDsKfQoKc3RhdGljIGlubGluZSBpbnQgZWJ0X2RvX21hdGNoIChzdHJ1Y3QgZWJ0X2VudHJ5X21hdGNoICptLAogICBjb25zdCBzdHJ1Y3Qgc2tfYnVmZiAqc2tiLCBjb25zdCBzdHJ1Y3QgbmV0X2RldmljZSAqaW4sCiAgIGNvbnN0IHN0cnVjdCBuZXRfZGV2aWNlICpvdXQpCnsKCXJldHVybiBtLT51Lm1hdGNoLT5tYXRjaChza2IsIGluLCBvdXQsIG0tPmRhdGEsCgkgICBtLT5tYXRjaF9zaXplKTsKfQoKc3RhdGljIGlubGluZSBpbnQgZWJ0X2Rldl9jaGVjayhjaGFyICplbnRyeSwgY29uc3Qgc3RydWN0IG5ldF9kZXZpY2UgKmRldmljZSkKewoJaW50IGkgPSAwOwoJY2hhciAqZGV2bmFtZSA9IGRldmljZS0+bmFtZTsKCglpZiAoKmVudHJ5ID09ICdcMCcpCgkJcmV0dXJuIDA7CglpZiAoIWRldmljZSkKCQlyZXR1cm4gMTsKCS8qIDEgaXMgdGhlIHdpbGRjYXJkIHRva2VuICovCgl3aGlsZSAoZW50cnlbaV0gIT0gJ1wwJyAmJiBlbnRyeVtpXSAhPSAxICYmIGVudHJ5W2ldID09IGRldm5hbWVbaV0pCgkJaSsrOwoJcmV0dXJuIChkZXZuYW1lW2ldICE9IGVudHJ5W2ldICYmIGVudHJ5W2ldICE9IDEpOwp9CgojZGVmaW5lIEZXSU5WMihib29sLGludmZsZykgKChib29sKSBeICEhKGUtPmludmZsYWdzICYgaW52ZmxnKSkKLyogcHJvY2VzcyBzdGFuZGFyZCBtYXRjaGVzICovCnN0YXRpYyBpbmxpbmUgaW50IGVidF9iYXNpY19tYXRjaChzdHJ1Y3QgZWJ0X2VudHJ5ICplLCBzdHJ1Y3QgZXRoaGRyICpoLAogICBjb25zdCBzdHJ1Y3QgbmV0X2RldmljZSAqaW4sIGNvbnN0IHN0cnVjdCBuZXRfZGV2aWNlICpvdXQpCnsKCWludCB2ZXJkaWN0LCBpOwoKCWlmIChlLT5iaXRtYXNrICYgRUJUXzgwMl8zKSB7CgkJaWYgKEZXSU5WMihudG9ocyhoLT5oX3Byb3RvKSA+PSAxNTM2LCBFQlRfSVBST1RPKSkKCQkJcmV0dXJuIDE7Cgl9IGVsc2UgaWYgKCEoZS0+Yml0bWFzayAmIEVCVF9OT1BST1RPKSAmJgoJICAgRldJTlYyKGUtPmV0aHByb3RvICE9IGgtPmhfcHJvdG8sIEVCVF9JUFJPVE8pKQoJCXJldHVybiAxOwoKCWlmIChGV0lOVjIoZWJ0X2Rldl9jaGVjayhlLT5pbiwgaW4pLCBFQlRfSUlOKSkKCQlyZXR1cm4gMTsKCWlmIChGV0lOVjIoZWJ0X2Rldl9jaGVjayhlLT5vdXQsIG91dCksIEVCVF9JT1VUKSkKCQlyZXR1cm4gMTsKCWlmICgoIWluIHx8ICFpbi0+YnJfcG9ydCkgPyAwIDogRldJTlYyKGVidF9kZXZfY2hlY2soCgkgICBlLT5sb2dpY2FsX2luLCBpbi0+YnJfcG9ydC0+YnItPmRldiksIEVCVF9JTE9HSUNBTElOKSkKCQlyZXR1cm4gMTsKCWlmICgoIW91dCB8fCAhb3V0LT5icl9wb3J0KSA/IDAgOiBGV0lOVjIoZWJ0X2Rldl9jaGVjaygKCSAgIGUtPmxvZ2ljYWxfb3V0LCBvdXQtPmJyX3BvcnQtPmJyLT5kZXYpLCBFQlRfSUxPR0lDQUxPVVQpKQoJCXJldHVybiAxOwoKCWlmIChlLT5iaXRtYXNrICYgRUJUX1NPVVJDRU1BQykgewoJCXZlcmRpY3QgPSAwOwoJCWZvciAoaSA9IDA7IGkgPCA2OyBpKyspCgkJCXZlcmRpY3QgfD0gKGgtPmhfc291cmNlW2ldIF4gZS0+c291cmNlbWFjW2ldKSAmCgkJCSAgIGUtPnNvdXJjZW1za1tpXTsKCQlpZiAoRldJTlYyKHZlcmRpY3QgIT0gMCwgRUJUX0lTT1VSQ0UpICkKCQkJcmV0dXJuIDE7Cgl9CglpZiAoZS0+Yml0bWFzayAmIEVCVF9ERVNUTUFDKSB7CgkJdmVyZGljdCA9IDA7CgkJZm9yIChpID0gMDsgaSA8IDY7IGkrKykKCQkJdmVyZGljdCB8PSAoaC0+aF9kZXN0W2ldIF4gZS0+ZGVzdG1hY1tpXSkgJgoJCQkgICBlLT5kZXN0bXNrW2ldOwoJCWlmIChGV0lOVjIodmVyZGljdCAhPSAwLCBFQlRfSURFU1QpICkKCQkJcmV0dXJuIDE7Cgl9CglyZXR1cm4gMDsKfQoKLyogRG8gc29tZSBmaXJld2FsbGluZyAqLwp1bnNpZ25lZCBpbnQgZWJ0X2RvX3RhYmxlICh1bnNpZ25lZCBpbnQgaG9vaywgc3RydWN0IHNrX2J1ZmYgKipwc2tiLAogICBjb25zdCBzdHJ1Y3QgbmV0X2RldmljZSAqaW4sIGNvbnN0IHN0cnVjdCBuZXRfZGV2aWNlICpvdXQsCiAgIHN0cnVjdCBlYnRfdGFibGUgKnRhYmxlKQp7CglpbnQgaSwgbmVudHJpZXM7CglzdHJ1Y3QgZWJ0X2VudHJ5ICpwb2ludDsKCXN0cnVjdCBlYnRfY291bnRlciAqY291bnRlcl9iYXNlLCAqY2JfYmFzZTsKCXN0cnVjdCBlYnRfZW50cnlfdGFyZ2V0ICp0OwoJaW50IHZlcmRpY3QsIHNwID0gMDsKCXN0cnVjdCBlYnRfY2hhaW5zdGFjayAqY3M7CglzdHJ1Y3QgZWJ0X2VudHJpZXMgKmNoYWluaW5mbzsKCWNoYXIgKmJhc2U7CglzdHJ1Y3QgZWJ0X3RhYmxlX2luZm8gKnByaXZhdGU7CgoJcmVhZF9sb2NrX2JoKCZ0YWJsZS0+bG9jayk7Cglwcml2YXRlID0gdGFibGUtPnByaXZhdGU7CgljYl9iYXNlID0gQ09VTlRFUl9CQVNFKHByaXZhdGUtPmNvdW50ZXJzLCBwcml2YXRlLT5uZW50cmllcywKCSAgIHNtcF9wcm9jZXNzb3JfaWQoKSk7CglpZiAocHJpdmF0ZS0+Y2hhaW5zdGFjaykKCQljcyA9IHByaXZhdGUtPmNoYWluc3RhY2tbc21wX3Byb2Nlc3Nvcl9pZCgpXTsKCWVsc2UKCQljcyA9IE5VTEw7CgljaGFpbmluZm8gPSBwcml2YXRlLT5ob29rX2VudHJ5W2hvb2tdOwoJbmVudHJpZXMgPSBwcml2YXRlLT5ob29rX2VudHJ5W2hvb2tdLT5uZW50cmllczsKCXBvaW50ID0gKHN0cnVjdCBlYnRfZW50cnkgKikocHJpdmF0ZS0+aG9va19lbnRyeVtob29rXS0+ZGF0YSk7Cgljb3VudGVyX2Jhc2UgPSBjYl9iYXNlICsgcHJpdmF0ZS0+aG9va19lbnRyeVtob29rXS0+Y291bnRlcl9vZmZzZXQ7CgkvKiBiYXNlIGZvciBjaGFpbiBqdW1wcyAqLwoJYmFzZSA9IHByaXZhdGUtPmVudHJpZXM7CglpID0gMDsKCXdoaWxlIChpIDwgbmVudHJpZXMpIHsKCQlpZiAoZWJ0X2Jhc2ljX21hdGNoKHBvaW50LCBldGhfaGRyKCpwc2tiKSwgaW4sIG91dCkpCgkJCWdvdG8gbGV0c2NvbnRpbnVlOwoKCQlpZiAoRUJUX01BVENIX0lURVJBVEUocG9pbnQsIGVidF9kb19tYXRjaCwgKnBza2IsIGluLCBvdXQpICE9IDApCgkJCWdvdG8gbGV0c2NvbnRpbnVlOwoKCQkvKiBpbmNyZWFzZSBjb3VudGVyICovCgkJKCooY291bnRlcl9iYXNlICsgaSkpLnBjbnQrKzsKCQkoKihjb3VudGVyX2Jhc2UgKyBpKSkuYmNudCs9KCoqcHNrYikubGVuOwoKCQkvKiB0aGVzZSBzaG91bGQgb25seSB3YXRjaDogbm90IG1vZGlmeSwgbm9yIHRlbGwgdXMKCQkgICB3aGF0IHRvIGRvIHdpdGggdGhlIHBhY2tldCAqLwoJCUVCVF9XQVRDSEVSX0lURVJBVEUocG9pbnQsIGVidF9kb193YXRjaGVyLCAqcHNrYiwgaG9vaywgaW4sCgkJICAgb3V0KTsKCgkJdCA9IChzdHJ1Y3QgZWJ0X2VudHJ5X3RhcmdldCAqKQoJCSAgICgoKGNoYXIgKilwb2ludCkgKyBwb2ludC0+dGFyZ2V0X29mZnNldCk7CgkJLyogc3RhbmRhcmQgdGFyZ2V0ICovCgkJaWYgKCF0LT51LnRhcmdldC0+dGFyZ2V0KQoJCQl2ZXJkaWN0ID0gKChzdHJ1Y3QgZWJ0X3N0YW5kYXJkX3RhcmdldCAqKXQpLT52ZXJkaWN0OwoJCWVsc2UKCQkJdmVyZGljdCA9IHQtPnUudGFyZ2V0LT50YXJnZXQocHNrYiwgaG9vaywKCQkJICAgaW4sIG91dCwgdC0+ZGF0YSwgdC0+dGFyZ2V0X3NpemUpOwoJCWlmICh2ZXJkaWN0ID09IEVCVF9BQ0NFUFQpIHsKCQkJcmVhZF91bmxvY2tfYmgoJnRhYmxlLT5sb2NrKTsKCQkJcmV0dXJuIE5GX0FDQ0VQVDsKCQl9CgkJaWYgKHZlcmRpY3QgPT0gRUJUX0RST1ApIHsKCQkJcmVhZF91bmxvY2tfYmgoJnRhYmxlLT5sb2NrKTsKCQkJcmV0dXJuIE5GX0RST1A7CgkJfQoJCWlmICh2ZXJkaWN0ID09IEVCVF9SRVRVUk4pIHsKbGV0c3JldHVybjoKI2lmZGVmIENPTkZJR19ORVRGSUxURVJfREVCVUcKCQkJaWYgKHNwID09IDApIHsKCQkJCUJVR1BSSU5UKCJSRVRVUk4gb24gYmFzZSBjaGFpbiIpOwoJCQkJLyogYWN0IGxpa2UgdGhpcyBpcyBFQlRfQ09OVElOVUUgKi8KCQkJCWdvdG8gbGV0c2NvbnRpbnVlOwoJCQl9CiNlbmRpZgoJCQlzcC0tOwoJCQkvKiBwdXQgYWxsIHRoZSBsb2NhbCB2YXJpYWJsZXMgcmlnaHQgKi8KCQkJaSA9IGNzW3NwXS5uOwoJCQljaGFpbmluZm8gPSBjc1tzcF0uY2hhaW5pbmZvOwoJCQluZW50cmllcyA9IGNoYWluaW5mby0+bmVudHJpZXM7CgkJCXBvaW50ID0gY3Nbc3BdLmU7CgkJCWNvdW50ZXJfYmFzZSA9IGNiX2Jhc2UgKwoJCQkgICBjaGFpbmluZm8tPmNvdW50ZXJfb2Zmc2V0OwoJCQljb250aW51ZTsKCQl9CgkJaWYgKHZlcmRpY3QgPT0gRUJUX0NPTlRJTlVFKQoJCQlnb3RvIGxldHNjb250aW51ZTsKI2lmZGVmIENPTkZJR19ORVRGSUxURVJfREVCVUcKCQlpZiAodmVyZGljdCA8IDApIHsKCQkJQlVHUFJJTlQoImJvZ3VzIHN0YW5kYXJkIHZlcmRpY3RcbiIpOwoJCQlyZWFkX3VubG9ja19iaCgmdGFibGUtPmxvY2spOwoJCQlyZXR1cm4gTkZfRFJPUDsKCQl9CiNlbmRpZgoJCS8qIGp1bXAgdG8gYSB1ZGMgKi8KCQljc1tzcF0ubiA9IGkgKyAxOwoJCWNzW3NwXS5jaGFpbmluZm8gPSBjaGFpbmluZm87CgkJY3Nbc3BdLmUgPSAoc3RydWN0IGVidF9lbnRyeSAqKQoJCSAgICgoKGNoYXIgKilwb2ludCkgKyBwb2ludC0+bmV4dF9vZmZzZXQpOwoJCWkgPSAwOwoJCWNoYWluaW5mbyA9IChzdHJ1Y3QgZWJ0X2VudHJpZXMgKikgKGJhc2UgKyB2ZXJkaWN0KTsKI2lmZGVmIENPTkZJR19ORVRGSUxURVJfREVCVUcKCQlpZiAoY2hhaW5pbmZvLT5kaXN0aW5ndWlzaGVyKSB7CgkJCUJVR1BSSU5UKCJqdW1wIHRvIG5vbi1jaGFpblxuIik7CgkJCXJlYWRfdW5sb2NrX2JoKCZ0YWJsZS0+bG9jayk7CgkJCXJldHVybiBORl9EUk9QOwoJCX0KI2VuZGlmCgkJbmVudHJpZXMgPSBjaGFpbmluZm8tPm5lbnRyaWVzOwoJCXBvaW50ID0gKHN0cnVjdCBlYnRfZW50cnkgKiljaGFpbmluZm8tPmRhdGE7CgkJY291bnRlcl9iYXNlID0gY2JfYmFzZSArIGNoYWluaW5mby0+Y291bnRlcl9vZmZzZXQ7CgkJc3ArKzsKCQljb250aW51ZTsKbGV0c2NvbnRpbnVlOgoJCXBvaW50ID0gKHN0cnVjdCBlYnRfZW50cnkgKikKCQkgICAoKChjaGFyICopcG9pbnQpICsgcG9pbnQtPm5leHRfb2Zmc2V0KTsKCQlpKys7Cgl9CgoJLyogSSBhY3R1YWxseSBsaWtlIHRoaXMgOikgKi8KCWlmIChjaGFpbmluZm8tPnBvbGljeSA9PSBFQlRfUkVUVVJOKQoJCWdvdG8gbGV0c3JldHVybjsKCWlmIChjaGFpbmluZm8tPnBvbGljeSA9PSBFQlRfQUNDRVBUKSB7CgkJcmVhZF91bmxvY2tfYmgoJnRhYmxlLT5sb2NrKTsKCQlyZXR1cm4gTkZfQUNDRVBUOwoJfQoJcmVhZF91bmxvY2tfYmgoJnRhYmxlLT5sb2NrKTsKCXJldHVybiBORl9EUk9QOwp9CgovKiBJZiBpdCBzdWNjZWVkcywgcmV0dXJucyBlbGVtZW50IGFuZCBsb2NrcyBtdXRleCAqLwpzdGF0aWMgaW5saW5lIHZvaWQgKgpmaW5kX2lubGlzdF9sb2NrX25vbG9hZChzdHJ1Y3QgbGlzdF9oZWFkICpoZWFkLCBjb25zdCBjaGFyICpuYW1lLCBpbnQgKmVycm9yLAogICBzdHJ1Y3QgbXV0ZXggKm11dGV4KQp7CglzdHJ1Y3QgewoJCXN0cnVjdCBsaXN0X2hlYWQgbGlzdDsKCQljaGFyIG5hbWVbRUJUX0ZVTkNUSU9OX01BWE5BTUVMRU5dOwoJfSAqZTsKCgkqZXJyb3IgPSBtdXRleF9sb2NrX2ludGVycnVwdGlibGUobXV0ZXgpOwoJaWYgKCplcnJvciAhPSAwKQoJCXJldHVybiBOVUxMOwoKCWxpc3RfZm9yX2VhY2hfZW50cnkoZSwgaGVhZCwgbGlzdCkgewoJCWlmIChzdHJjbXAoZS0+bmFtZSwgbmFtZSkgPT0gMCkKCQkJcmV0dXJuIGU7Cgl9CgkqZXJyb3IgPSAtRU5PRU5UOwoJbXV0ZXhfdW5sb2NrKG11dGV4KTsKCXJldHVybiBOVUxMOwp9CgojaWZuZGVmIENPTkZJR19LTU9ECiNkZWZpbmUgZmluZF9pbmxpc3RfbG9jayhoLG4scCxlLG0pIGZpbmRfaW5saXN0X2xvY2tfbm9sb2FkKChoKSwobiksKGUpLChtKSkKI2Vsc2UKc3RhdGljIHZvaWQgKgpmaW5kX2lubGlzdF9sb2NrKHN0cnVjdCBsaXN0X2hlYWQgKmhlYWQsIGNvbnN0IGNoYXIgKm5hbWUsIGNvbnN0IGNoYXIgKnByZWZpeCwKICAgaW50ICplcnJvciwgc3RydWN0IG11dGV4ICptdXRleCkKewoJdm9pZCAqcmV0OwoKCXJldCA9IGZpbmRfaW5saXN0X2xvY2tfbm9sb2FkKGhlYWQsIG5hbWUsIGVycm9yLCBtdXRleCk7CglpZiAoIXJldCkgewoJCXJlcXVlc3RfbW9kdWxlKCIlcyVzIiwgcHJlZml4LCBuYW1lKTsKCQlyZXQgPSBmaW5kX2lubGlzdF9sb2NrX25vbG9hZChoZWFkLCBuYW1lLCBlcnJvciwgbXV0ZXgpOwoJfQoJcmV0dXJuIHJldDsKfQojZW5kaWYKCnN0YXRpYyBpbmxpbmUgc3RydWN0IGVidF90YWJsZSAqCmZpbmRfdGFibGVfbG9jayhjb25zdCBjaGFyICpuYW1lLCBpbnQgKmVycm9yLCBzdHJ1Y3QgbXV0ZXggKm11dGV4KQp7CglyZXR1cm4gZmluZF9pbmxpc3RfbG9jaygmZWJ0X3RhYmxlcywgbmFtZSwgImVidGFibGVfIiwgZXJyb3IsIG11dGV4KTsKfQoKc3RhdGljIGlubGluZSBzdHJ1Y3QgZWJ0X21hdGNoICoKZmluZF9tYXRjaF9sb2NrKGNvbnN0IGNoYXIgKm5hbWUsIGludCAqZXJyb3IsIHN0cnVjdCBtdXRleCAqbXV0ZXgpCnsKCXJldHVybiBmaW5kX2lubGlzdF9sb2NrKCZlYnRfbWF0Y2hlcywgbmFtZSwgImVidF8iLCBlcnJvciwgbXV0ZXgpOwp9CgpzdGF0aWMgaW5saW5lIHN0cnVjdCBlYnRfd2F0Y2hlciAqCmZpbmRfd2F0Y2hlcl9sb2NrKGNvbnN0IGNoYXIgKm5hbWUsIGludCAqZXJyb3IsIHN0cnVjdCBtdXRleCAqbXV0ZXgpCnsKCXJldHVybiBmaW5kX2lubGlzdF9sb2NrKCZlYnRfd2F0Y2hlcnMsIG5hbWUsICJlYnRfIiwgZXJyb3IsIG11dGV4KTsKfQoKc3RhdGljIGlubGluZSBzdHJ1Y3QgZWJ0X3RhcmdldCAqCmZpbmRfdGFyZ2V0X2xvY2soY29uc3QgY2hhciAqbmFtZSwgaW50ICplcnJvciwgc3RydWN0IG11dGV4ICptdXRleCkKewoJcmV0dXJuIGZpbmRfaW5saXN0X2xvY2soJmVidF90YXJnZXRzLCBuYW1lLCAiZWJ0XyIsIGVycm9yLCBtdXRleCk7Cn0KCnN0YXRpYyBpbmxpbmUgaW50CmVidF9jaGVja19tYXRjaChzdHJ1Y3QgZWJ0X2VudHJ5X21hdGNoICptLCBzdHJ1Y3QgZWJ0X2VudHJ5ICplLAogICBjb25zdCBjaGFyICpuYW1lLCB1bnNpZ25lZCBpbnQgaG9va21hc2ssIHVuc2lnbmVkIGludCAqY250KQp7CglzdHJ1Y3QgZWJ0X21hdGNoICptYXRjaDsKCWludCByZXQ7CgoJaWYgKCgoY2hhciAqKW0pICsgbS0+bWF0Y2hfc2l6ZSArIHNpemVvZihzdHJ1Y3QgZWJ0X2VudHJ5X21hdGNoKSA+CgkgICAoKGNoYXIgKillKSArIGUtPndhdGNoZXJzX29mZnNldCkKCQlyZXR1cm4gLUVJTlZBTDsKCW1hdGNoID0gZmluZF9tYXRjaF9sb2NrKG0tPnUubmFtZSwgJnJldCwgJmVidF9tdXRleCk7CglpZiAoIW1hdGNoKQoJCXJldHVybiByZXQ7CgltLT51Lm1hdGNoID0gbWF0Y2g7CglpZiAoIXRyeV9tb2R1bGVfZ2V0KG1hdGNoLT5tZSkpIHsKCQltdXRleF91bmxvY2soJmVidF9tdXRleCk7CgkJcmV0dXJuIC1FTk9FTlQ7Cgl9CgltdXRleF91bmxvY2soJmVidF9tdXRleCk7CglpZiAobWF0Y2gtPmNoZWNrICYmCgkgICBtYXRjaC0+Y2hlY2sobmFtZSwgaG9va21hc2ssIGUsIG0tPmRhdGEsIG0tPm1hdGNoX3NpemUpICE9IDApIHsKCQlCVUdQUklOVCgibWF0Y2gtPmNoZWNrIGZhaWxlZFxuIik7CgkJbW9kdWxlX3B1dChtYXRjaC0+bWUpOwoJCXJldHVybiAtRUlOVkFMOwoJfQoJKCpjbnQpKys7CglyZXR1cm4gMDsKfQoKc3RhdGljIGlubGluZSBpbnQKZWJ0X2NoZWNrX3dhdGNoZXIoc3RydWN0IGVidF9lbnRyeV93YXRjaGVyICp3LCBzdHJ1Y3QgZWJ0X2VudHJ5ICplLAogICBjb25zdCBjaGFyICpuYW1lLCB1bnNpZ25lZCBpbnQgaG9va21hc2ssIHVuc2lnbmVkIGludCAqY250KQp7CglzdHJ1Y3QgZWJ0X3dhdGNoZXIgKndhdGNoZXI7CglpbnQgcmV0OwoKCWlmICgoKGNoYXIgKil3KSArIHctPndhdGNoZXJfc2l6ZSArIHNpemVvZihzdHJ1Y3QgZWJ0X2VudHJ5X3dhdGNoZXIpID4KCSAgICgoY2hhciAqKWUpICsgZS0+dGFyZ2V0X29mZnNldCkKCQlyZXR1cm4gLUVJTlZBTDsKCXdhdGNoZXIgPSBmaW5kX3dhdGNoZXJfbG9jayh3LT51Lm5hbWUsICZyZXQsICZlYnRfbXV0ZXgpOwoJaWYgKCF3YXRjaGVyKQoJCXJldHVybiByZXQ7Cgl3LT51LndhdGNoZXIgPSB3YXRjaGVyOwoJaWYgKCF0cnlfbW9kdWxlX2dldCh3YXRjaGVyLT5tZSkpIHsKCQltdXRleF91bmxvY2soJmVidF9tdXRleCk7CgkJcmV0dXJuIC1FTk9FTlQ7Cgl9CgltdXRleF91bmxvY2soJmVidF9tdXRleCk7CglpZiAod2F0Y2hlci0+Y2hlY2sgJiYKCSAgIHdhdGNoZXItPmNoZWNrKG5hbWUsIGhvb2ttYXNrLCBlLCB3LT5kYXRhLCB3LT53YXRjaGVyX3NpemUpICE9IDApIHsKCQlCVUdQUklOVCgid2F0Y2hlci0+Y2hlY2sgZmFpbGVkXG4iKTsKCQltb2R1bGVfcHV0KHdhdGNoZXItPm1lKTsKCQlyZXR1cm4gLUVJTlZBTDsKCX0KCSgqY250KSsrOwoJcmV0dXJuIDA7Cn0KCi8qCiAqIHRoaXMgb25lIGlzIHZlcnkgY2FyZWZ1bCwgYXMgaXQgaXMgdGhlIGZpcnN0IGZ1bmN0aW9uCiAqIHRvIHBhcnNlIHRoZSB1c2Vyc3BhY2UgZGF0YQogKi8Kc3RhdGljIGlubGluZSBpbnQKZWJ0X2NoZWNrX2VudHJ5X3NpemVfYW5kX2hvb2tzKHN0cnVjdCBlYnRfZW50cnkgKmUsCiAgIHN0cnVjdCBlYnRfdGFibGVfaW5mbyAqbmV3aW5mbywgY2hhciAqYmFzZSwgY2hhciAqbGltaXQsCiAgIHN0cnVjdCBlYnRfZW50cmllcyAqKmhvb2tfZW50cmllcywgdW5zaWduZWQgaW50ICpuLCB1bnNpZ25lZCBpbnQgKmNudCwKICAgdW5zaWduZWQgaW50ICp0b3RhbGNudCwgdW5zaWduZWQgaW50ICp1ZGNfY250LCB1bnNpZ25lZCBpbnQgdmFsaWRfaG9va3MpCnsKCWludCBpOwoKCWZvciAoaSA9IDA7IGkgPCBORl9CUl9OVU1IT09LUzsgaSsrKSB7CgkJaWYgKCh2YWxpZF9ob29rcyAmICgxIDw8IGkpKSA9PSAwKQoJCQljb250aW51ZTsKCQlpZiAoIChjaGFyICopaG9va19lbnRyaWVzW2ldIC0gYmFzZSA9PQoJCSAgIChjaGFyICopZSAtIG5ld2luZm8tPmVudHJpZXMpCgkJCWJyZWFrOwoJfQoJLyogYmVnaW5uaW5nIG9mIGEgbmV3IGNoYWluCgkgICBpZiBpID09IE5GX0JSX05VTUhPT0tTIGl0IG11c3QgYmUgYSB1c2VyIGRlZmluZWQgY2hhaW4gKi8KCWlmIChpICE9IE5GX0JSX05VTUhPT0tTIHx8ICEoZS0+Yml0bWFzayAmIEVCVF9FTlRSWV9PUl9FTlRSSUVTKSkgewoJCWlmICgoZS0+Yml0bWFzayAmIEVCVF9FTlRSWV9PUl9FTlRSSUVTKSAhPSAwKSB7CgkJCS8qIHdlIG1ha2UgdXNlcnNwYWNlIHNldCB0aGlzIHJpZ2h0LAoJCQkgICBzbyB0aGVyZSBpcyBubyBtaXN1bmRlcnN0YW5kaW5nICovCgkJCUJVR1BSSU5UKCJFQlRfRU5UUllfT1JfRU5UUklFUyBzaG91bGRuJ3QgYmUgc2V0ICIKCQkJICAgICAgICAgImluIGRpc3Rpbmd1aXNoZXJcbiIpOwoJCQlyZXR1cm4gLUVJTlZBTDsKCQl9CgkJLyogdGhpcyBjaGVja3MgaWYgdGhlIHByZXZpb3VzIGNoYWluIGhhcyBhcyBtYW55IGVudHJpZXMKCQkgICBhcyBpdCBzYWlkIGl0IGhhcyAqLwoJCWlmICgqbiAhPSAqY250KSB7CgkJCUJVR1BSSU5UKCJuZW50cmllcyBkb2VzIG5vdCBlcXVhbCB0aGUgbnIgb2YgZW50cmllcyAiCgkJICAgICAgICAgICAgICAgICAiaW4gdGhlIGNoYWluXG4iKTsKCQkJcmV0dXJuIC1FSU5WQUw7CgkJfQoJCS8qIGJlZm9yZSB3ZSBsb29rIGF0IHRoZSBzdHJ1Y3QsIGJlIHN1cmUgaXQgaXMgbm90IHRvbyBiaWcgKi8KCQlpZiAoKGNoYXIgKilob29rX2VudHJpZXNbaV0gKyBzaXplb2Yoc3RydWN0IGVidF9lbnRyaWVzKQoJCSAgID4gbGltaXQpIHsKCQkJQlVHUFJJTlQoImVudHJpZXNfc2l6ZSB0b28gc21hbGxcbiIpOwoJCQlyZXR1cm4gLUVJTlZBTDsKCQl9CgkJaWYgKCgoc3RydWN0IGVidF9lbnRyaWVzICopZSktPnBvbGljeSAhPSBFQlRfRFJPUCAmJgoJCSAgICgoc3RydWN0IGVidF9lbnRyaWVzICopZSktPnBvbGljeSAhPSBFQlRfQUNDRVBUKSB7CgkJCS8qIG9ubHkgUkVUVVJOIGZyb20gdWRjICovCgkJCWlmIChpICE9IE5GX0JSX05VTUhPT0tTIHx8CgkJCSAgICgoc3RydWN0IGVidF9lbnRyaWVzICopZSktPnBvbGljeSAhPSBFQlRfUkVUVVJOKSB7CgkJCQlCVUdQUklOVCgiYmFkIHBvbGljeVxuIik7CgkJCQlyZXR1cm4gLUVJTlZBTDsKCQkJfQoJCX0KCQlpZiAoaSA9PSBORl9CUl9OVU1IT09LUykgLyogaXQncyBhIHVzZXIgZGVmaW5lZCBjaGFpbiAqLwoJCQkoKnVkY19jbnQpKys7CgkJZWxzZQoJCQluZXdpbmZvLT5ob29rX2VudHJ5W2ldID0gKHN0cnVjdCBlYnRfZW50cmllcyAqKWU7CgkJaWYgKCgoc3RydWN0IGVidF9lbnRyaWVzICopZSktPmNvdW50ZXJfb2Zmc2V0ICE9ICp0b3RhbGNudCkgewoJCQlCVUdQUklOVCgiY291bnRlcl9vZmZzZXQgIT0gdG90YWxjbnQiKTsKCQkJcmV0dXJuIC1FSU5WQUw7CgkJfQoJCSpuID0gKChzdHJ1Y3QgZWJ0X2VudHJpZXMgKillKS0+bmVudHJpZXM7CgkJKmNudCA9IDA7CgkJcmV0dXJuIDA7Cgl9CgkvKiBhIHBsYWluIG9sZCBlbnRyeSwgaGVoICovCglpZiAoc2l6ZW9mKHN0cnVjdCBlYnRfZW50cnkpID4gZS0+d2F0Y2hlcnNfb2Zmc2V0IHx8CgkgICBlLT53YXRjaGVyc19vZmZzZXQgPiBlLT50YXJnZXRfb2Zmc2V0IHx8CgkgICBlLT50YXJnZXRfb2Zmc2V0ID49IGUtPm5leHRfb2Zmc2V0KSB7CgkJQlVHUFJJTlQoImVudHJ5IG9mZnNldHMgbm90IGluIHJpZ2h0IG9yZGVyXG4iKTsKCQlyZXR1cm4gLUVJTlZBTDsKCX0KCS8qIHRoaXMgaXMgbm90IGNoZWNrZWQgYW55d2hlcmUgZWxzZSAqLwoJaWYgKGUtPm5leHRfb2Zmc2V0IC0gZS0+dGFyZ2V0X29mZnNldCA8IHNpemVvZihzdHJ1Y3QgZWJ0X2VudHJ5X3RhcmdldCkpIHsKCQlCVUdQUklOVCgidGFyZ2V0IHNpemUgdG9vIHNtYWxsXG4iKTsKCQlyZXR1cm4gLUVJTlZBTDsKCX0KCgkoKmNudCkrKzsKCSgqdG90YWxjbnQpKys7CglyZXR1cm4gMDsKfQoKc3RydWN0IGVidF9jbF9zdGFjawp7CglzdHJ1Y3QgZWJ0X2NoYWluc3RhY2sgY3M7CglpbnQgZnJvbTsKCXVuc2lnbmVkIGludCBob29rbWFzazsKfTsKCi8qCiAqIHdlIG5lZWQgdGhlc2UgcG9zaXRpb25zIHRvIGNoZWNrIHRoYXQgdGhlIGp1bXBzIHRvIGEgZGlmZmVyZW50IHBhcnQgb2YgdGhlCiAqIGVudHJpZXMgaXMgYSBqdW1wIHRvIHRoZSBiZWdpbm5pbmcgb2YgYSBuZXcgY2hhaW4uCiAqLwpzdGF0aWMgaW5saW5lIGludAplYnRfZ2V0X3VkY19wb3NpdGlvbnMoc3RydWN0IGVidF9lbnRyeSAqZSwgc3RydWN0IGVidF90YWJsZV9pbmZvICpuZXdpbmZvLAogICBzdHJ1Y3QgZWJ0X2VudHJpZXMgKipob29rX2VudHJpZXMsIHVuc2lnbmVkIGludCAqbiwgdW5zaWduZWQgaW50IHZhbGlkX2hvb2tzLAogICBzdHJ1Y3QgZWJ0X2NsX3N0YWNrICp1ZGMpCnsKCWludCBpOwoKCS8qIHdlJ3JlIG9ubHkgaW50ZXJlc3RlZCBpbiBjaGFpbiBzdGFydHMgKi8KCWlmIChlLT5iaXRtYXNrICYgRUJUX0VOVFJZX09SX0VOVFJJRVMpCgkJcmV0dXJuIDA7Cglmb3IgKGkgPSAwOyBpIDwgTkZfQlJfTlVNSE9PS1M7IGkrKykgewoJCWlmICgodmFsaWRfaG9va3MgJiAoMSA8PCBpKSkgPT0gMCkKCQkJY29udGludWU7CgkJaWYgKG5ld2luZm8tPmhvb2tfZW50cnlbaV0gPT0gKHN0cnVjdCBlYnRfZW50cmllcyAqKWUpCgkJCWJyZWFrOwoJfQoJLyogb25seSBjYXJlIGFib3V0IHVkYyAqLwoJaWYgKGkgIT0gTkZfQlJfTlVNSE9PS1MpCgkJcmV0dXJuIDA7CgoJdWRjWypuXS5jcy5jaGFpbmluZm8gPSAoc3RydWN0IGVidF9lbnRyaWVzICopZTsKCS8qIHRoZXNlIGluaXRpYWxpc2F0aW9ucyBhcmUgZGVwZW5kZWQgb24gbGF0ZXIgaW4gY2hlY2tfY2hhaW5sb29wcygpICovCgl1ZGNbKm5dLmNzLm4gPSAwOwoJdWRjWypuXS5ob29rbWFzayA9IDA7CgoJKCpuKSsrOwoJcmV0dXJuIDA7Cn0KCnN0YXRpYyBpbmxpbmUgaW50CmVidF9jbGVhbnVwX21hdGNoKHN0cnVjdCBlYnRfZW50cnlfbWF0Y2ggKm0sIHVuc2lnbmVkIGludCAqaSkKewoJaWYgKGkgJiYgKCppKS0tID09IDApCgkJcmV0dXJuIDE7CglpZiAobS0+dS5tYXRjaC0+ZGVzdHJveSkKCQltLT51Lm1hdGNoLT5kZXN0cm95KG0tPmRhdGEsIG0tPm1hdGNoX3NpemUpOwoJbW9kdWxlX3B1dChtLT51Lm1hdGNoLT5tZSk7CgoJcmV0dXJuIDA7Cn0KCnN0YXRpYyBpbmxpbmUgaW50CmVidF9jbGVhbnVwX3dhdGNoZXIoc3RydWN0IGVidF9lbnRyeV93YXRjaGVyICp3LCB1bnNpZ25lZCBpbnQgKmkpCnsKCWlmIChpICYmICgqaSktLSA9PSAwKQoJCXJldHVybiAxOwoJaWYgKHctPnUud2F0Y2hlci0+ZGVzdHJveSkKCQl3LT51LndhdGNoZXItPmRlc3Ryb3kody0+ZGF0YSwgdy0+d2F0Y2hlcl9zaXplKTsKCW1vZHVsZV9wdXQody0+dS53YXRjaGVyLT5tZSk7CgoJcmV0dXJuIDA7Cn0KCnN0YXRpYyBpbmxpbmUgaW50CmVidF9jbGVhbnVwX2VudHJ5KHN0cnVjdCBlYnRfZW50cnkgKmUsIHVuc2lnbmVkIGludCAqY250KQp7CglzdHJ1Y3QgZWJ0X2VudHJ5X3RhcmdldCAqdDsKCglpZiAoKGUtPmJpdG1hc2sgJiBFQlRfRU5UUllfT1JfRU5UUklFUykgPT0gMCkKCQlyZXR1cm4gMDsKCS8qIHdlJ3JlIGRvbmUgKi8KCWlmIChjbnQgJiYgKCpjbnQpLS0gPT0gMCkKCQlyZXR1cm4gMTsKCUVCVF9XQVRDSEVSX0lURVJBVEUoZSwgZWJ0X2NsZWFudXBfd2F0Y2hlciwgTlVMTCk7CglFQlRfTUFUQ0hfSVRFUkFURShlLCBlYnRfY2xlYW51cF9tYXRjaCwgTlVMTCk7Cgl0ID0gKHN0cnVjdCBlYnRfZW50cnlfdGFyZ2V0ICopKCgoY2hhciAqKWUpICsgZS0+dGFyZ2V0X29mZnNldCk7CglpZiAodC0+dS50YXJnZXQtPmRlc3Ryb3kpCgkJdC0+dS50YXJnZXQtPmRlc3Ryb3kodC0+ZGF0YSwgdC0+dGFyZ2V0X3NpemUpOwoJbW9kdWxlX3B1dCh0LT51LnRhcmdldC0+bWUpOwoKCXJldHVybiAwOwp9CgpzdGF0aWMgaW5saW5lIGludAplYnRfY2hlY2tfZW50cnkoc3RydWN0IGVidF9lbnRyeSAqZSwgc3RydWN0IGVidF90YWJsZV9pbmZvICpuZXdpbmZvLAogICBjb25zdCBjaGFyICpuYW1lLCB1bnNpZ25lZCBpbnQgKmNudCwgdW5zaWduZWQgaW50IHZhbGlkX2hvb2tzLAogICBzdHJ1Y3QgZWJ0X2NsX3N0YWNrICpjbF9zLCB1bnNpZ25lZCBpbnQgdWRjX2NudCkKewoJc3RydWN0IGVidF9lbnRyeV90YXJnZXQgKnQ7CglzdHJ1Y3QgZWJ0X3RhcmdldCAqdGFyZ2V0OwoJdW5zaWduZWQgaW50IGksIGosIGhvb2sgPSAwLCBob29rbWFzayA9IDA7CglpbnQgcmV0OwoKCS8qIGRvbid0IG1lc3Mgd2l0aCB0aGUgc3RydWN0IGVidF9lbnRyaWVzICovCglpZiAoKGUtPmJpdG1hc2sgJiBFQlRfRU5UUllfT1JfRU5UUklFUykgPT0gMCkKCQlyZXR1cm4gMDsKCglpZiAoZS0+Yml0bWFzayAmIH5FQlRfRl9NQVNLKSB7CgkJQlVHUFJJTlQoIlVua25vd24gZmxhZyBmb3IgYml0bWFza1xuIik7CgkJcmV0dXJuIC1FSU5WQUw7Cgl9CglpZiAoZS0+aW52ZmxhZ3MgJiB+RUJUX0lOVl9NQVNLKSB7CgkJQlVHUFJJTlQoIlVua25vd24gZmxhZyBmb3IgaW52IGJpdG1hc2tcbiIpOwoJCXJldHVybiAtRUlOVkFMOwoJfQoJaWYgKCAoZS0+Yml0bWFzayAmIEVCVF9OT1BST1RPKSAmJiAoZS0+Yml0bWFzayAmIEVCVF84MDJfMykgKSB7CgkJQlVHUFJJTlQoIk5PUFJPVE8gJiA4MDJfMyBub3QgYWxsb3dlZFxuIik7CgkJcmV0dXJuIC1FSU5WQUw7Cgl9CgkvKiB3aGF0IGhvb2sgZG8gd2UgYmVsb25nIHRvPyAqLwoJZm9yIChpID0gMDsgaSA8IE5GX0JSX05VTUhPT0tTOyBpKyspIHsKCQlpZiAoKHZhbGlkX2hvb2tzICYgKDEgPDwgaSkpID09IDApCgkJCWNvbnRpbnVlOwoJCWlmICgoY2hhciAqKW5ld2luZm8tPmhvb2tfZW50cnlbaV0gPCAoY2hhciAqKWUpCgkJCWhvb2sgPSBpOwoJCWVsc2UKCQkJYnJlYWs7Cgl9CgkvKiAoMSA8PCBORl9CUl9OVU1IT09LUykgdGVsbHMgdGhlIGNoZWNrIGZ1bmN0aW9ucyB0aGUgcnVsZSBpcyBvbgoJICAgYSBiYXNlIGNoYWluICovCglpZiAoaSA8IE5GX0JSX05VTUhPT0tTKQoJCWhvb2ttYXNrID0gKDEgPDwgaG9vaykgfCAoMSA8PCBORl9CUl9OVU1IT09LUyk7CgllbHNlIHsKCQlmb3IgKGkgPSAwOyBpIDwgdWRjX2NudDsgaSsrKQoJCQlpZiAoKGNoYXIgKikoY2xfc1tpXS5jcy5jaGFpbmluZm8pID4gKGNoYXIgKillKQoJCQkJYnJlYWs7CgkJaWYgKGkgPT0gMCkKCQkJaG9va21hc2sgPSAoMSA8PCBob29rKSB8ICgxIDw8IE5GX0JSX05VTUhPT0tTKTsKCQllbHNlCgkJCWhvb2ttYXNrID0gY2xfc1tpIC0gMV0uaG9va21hc2s7Cgl9CglpID0gMDsKCXJldCA9IEVCVF9NQVRDSF9JVEVSQVRFKGUsIGVidF9jaGVja19tYXRjaCwgZSwgbmFtZSwgaG9va21hc2ssICZpKTsKCWlmIChyZXQgIT0gMCkKCQlnb3RvIGNsZWFudXBfbWF0Y2hlczsKCWogPSAwOwoJcmV0ID0gRUJUX1dBVENIRVJfSVRFUkFURShlLCBlYnRfY2hlY2tfd2F0Y2hlciwgZSwgbmFtZSwgaG9va21hc2ssICZqKTsKCWlmIChyZXQgIT0gMCkKCQlnb3RvIGNsZWFudXBfd2F0Y2hlcnM7Cgl0ID0gKHN0cnVjdCBlYnRfZW50cnlfdGFyZ2V0ICopKCgoY2hhciAqKWUpICsgZS0+dGFyZ2V0X29mZnNldCk7Cgl0YXJnZXQgPSBmaW5kX3RhcmdldF9sb2NrKHQtPnUubmFtZSwgJnJldCwgJmVidF9tdXRleCk7CglpZiAoIXRhcmdldCkKCQlnb3RvIGNsZWFudXBfd2F0Y2hlcnM7CglpZiAoIXRyeV9tb2R1bGVfZ2V0KHRhcmdldC0+bWUpKSB7CgkJbXV0ZXhfdW5sb2NrKCZlYnRfbXV0ZXgpOwoJCXJldCA9IC1FTk9FTlQ7CgkJZ290byBjbGVhbnVwX3dhdGNoZXJzOwoJfQoJbXV0ZXhfdW5sb2NrKCZlYnRfbXV0ZXgpOwoKCXQtPnUudGFyZ2V0ID0gdGFyZ2V0OwoJaWYgKHQtPnUudGFyZ2V0ID09ICZlYnRfc3RhbmRhcmRfdGFyZ2V0KSB7CgkJaWYgKGUtPnRhcmdldF9vZmZzZXQgKyBzaXplb2Yoc3RydWN0IGVidF9zdGFuZGFyZF90YXJnZXQpID4KCQkgICBlLT5uZXh0X29mZnNldCkgewoJCQlCVUdQUklOVCgiU3RhbmRhcmQgdGFyZ2V0IHNpemUgdG9vIGJpZ1xuIik7CgkJCXJldCA9IC1FRkFVTFQ7CgkJCWdvdG8gY2xlYW51cF93YXRjaGVyczsKCQl9CgkJaWYgKCgoc3RydWN0IGVidF9zdGFuZGFyZF90YXJnZXQgKil0KS0+dmVyZGljdCA8CgkJICAgLU5VTV9TVEFOREFSRF9UQVJHRVRTKSB7CgkJCUJVR1BSSU5UKCJJbnZhbGlkIHN0YW5kYXJkIHRhcmdldFxuIik7CgkJCXJldCA9IC1FRkFVTFQ7CgkJCWdvdG8gY2xlYW51cF93YXRjaGVyczsKCQl9Cgl9IGVsc2UgaWYgKChlLT50YXJnZXRfb2Zmc2V0ICsgdC0+dGFyZ2V0X3NpemUgKwoJICAgc2l6ZW9mKHN0cnVjdCBlYnRfZW50cnlfdGFyZ2V0KSA+IGUtPm5leHRfb2Zmc2V0KSB8fAoJICAgKHQtPnUudGFyZ2V0LT5jaGVjayAmJgoJICAgdC0+dS50YXJnZXQtPmNoZWNrKG5hbWUsIGhvb2ttYXNrLCBlLCB0LT5kYXRhLCB0LT50YXJnZXRfc2l6ZSkgIT0gMCkpewoJCW1vZHVsZV9wdXQodC0+dS50YXJnZXQtPm1lKTsKCQlyZXQgPSAtRUZBVUxUOwoJCWdvdG8gY2xlYW51cF93YXRjaGVyczsKCX0KCSgqY250KSsrOwoJcmV0dXJuIDA7CmNsZWFudXBfd2F0Y2hlcnM6CglFQlRfV0FUQ0hFUl9JVEVSQVRFKGUsIGVidF9jbGVhbnVwX3dhdGNoZXIsICZqKTsKY2xlYW51cF9tYXRjaGVzOgoJRUJUX01BVENIX0lURVJBVEUoZSwgZWJ0X2NsZWFudXBfbWF0Y2gsICZpKTsKCXJldHVybiByZXQ7Cn0KCi8qCiAqIGNoZWNrcyBmb3IgbG9vcHMgYW5kIHNldHMgdGhlIGhvb2sgbWFzayBmb3IgdWRjCiAqIHRoZSBob29rIG1hc2sgZm9yIHVkYyB0ZWxscyB1cyBmcm9tIHdoaWNoIGJhc2UgY2hhaW5zIHRoZSB1ZGMgY2FuIGJlCiAqIGFjY2Vzc2VkLiBUaGlzIG1hc2sgaXMgYSBwYXJhbWV0ZXIgdG8gdGhlIGNoZWNrKCkgZnVuY3Rpb25zIG9mIHRoZSBleHRlbnNpb25zCiAqLwpzdGF0aWMgaW50IGNoZWNrX2NoYWlubG9vcHMoc3RydWN0IGVidF9lbnRyaWVzICpjaGFpbiwgc3RydWN0IGVidF9jbF9zdGFjayAqY2xfcywKICAgdW5zaWduZWQgaW50IHVkY19jbnQsIHVuc2lnbmVkIGludCBob29rbnIsIGNoYXIgKmJhc2UpCnsKCWludCBpLCBjaGFpbl9uciA9IC0xLCBwb3MgPSAwLCBuZW50cmllcyA9IGNoYWluLT5uZW50cmllcywgdmVyZGljdDsKCXN0cnVjdCBlYnRfZW50cnkgKmUgPSAoc3RydWN0IGVidF9lbnRyeSAqKWNoYWluLT5kYXRhOwoJc3RydWN0IGVidF9lbnRyeV90YXJnZXQgKnQ7CgoJd2hpbGUgKHBvcyA8IG5lbnRyaWVzIHx8IGNoYWluX25yICE9IC0xKSB7CgkJLyogZW5kIG9mIHVkYywgZ28gYmFjayBvbmUgJ3JlY3Vyc2lvbicgc3RlcCAqLwoJCWlmIChwb3MgPT0gbmVudHJpZXMpIHsKCQkJLyogcHV0IGJhY2sgdmFsdWVzIG9mIHRoZSB0aW1lIHdoZW4gdGhpcyBjaGFpbiB3YXMgY2FsbGVkICovCgkJCWUgPSBjbF9zW2NoYWluX25yXS5jcy5lOwoJCQlpZiAoY2xfc1tjaGFpbl9ucl0uZnJvbSAhPSAtMSkKCQkJCW5lbnRyaWVzID0KCQkJCWNsX3NbY2xfc1tjaGFpbl9ucl0uZnJvbV0uY3MuY2hhaW5pbmZvLT5uZW50cmllczsKCQkJZWxzZQoJCQkJbmVudHJpZXMgPSBjaGFpbi0+bmVudHJpZXM7CgkJCXBvcyA9IGNsX3NbY2hhaW5fbnJdLmNzLm47CgkJCS8qIG1ha2Ugc3VyZSB3ZSB3b24ndCBzZWUgYSBsb29wIHRoYXQgaXNuJ3Qgb25lICovCgkJCWNsX3NbY2hhaW5fbnJdLmNzLm4gPSAwOwoJCQljaGFpbl9uciA9IGNsX3NbY2hhaW5fbnJdLmZyb207CgkJCWlmIChwb3MgPT0gbmVudHJpZXMpCgkJCQljb250aW51ZTsKCQl9CgkJdCA9IChzdHJ1Y3QgZWJ0X2VudHJ5X3RhcmdldCAqKQoJCSAgICgoKGNoYXIgKillKSArIGUtPnRhcmdldF9vZmZzZXQpOwoJCWlmIChzdHJjbXAodC0+dS5uYW1lLCBFQlRfU1RBTkRBUkRfVEFSR0VUKSkKCQkJZ290byBsZXRzY29udGludWU7CgkJaWYgKGUtPnRhcmdldF9vZmZzZXQgKyBzaXplb2Yoc3RydWN0IGVidF9zdGFuZGFyZF90YXJnZXQpID4KCQkgICBlLT5uZXh0X29mZnNldCkgewoJCQlCVUdQUklOVCgiU3RhbmRhcmQgdGFyZ2V0IHNpemUgdG9vIGJpZ1xuIik7CgkJCXJldHVybiAtMTsKCQl9CgkJdmVyZGljdCA9ICgoc3RydWN0IGVidF9zdGFuZGFyZF90YXJnZXQgKil0KS0+dmVyZGljdDsKCQlpZiAodmVyZGljdCA+PSAwKSB7IC8qIGp1bXAgdG8gYW5vdGhlciBjaGFpbiAqLwoJCQlzdHJ1Y3QgZWJ0X2VudHJpZXMgKmhscDIgPQoJCQkgICAoc3RydWN0IGVidF9lbnRyaWVzICopKGJhc2UgKyB2ZXJkaWN0KTsKCQkJZm9yIChpID0gMDsgaSA8IHVkY19jbnQ7IGkrKykKCQkJCWlmIChobHAyID09IGNsX3NbaV0uY3MuY2hhaW5pbmZvKQoJCQkJCWJyZWFrOwoJCQkvKiBiYWQgZGVzdGluYXRpb24gb3IgbG9vcCAqLwoJCQlpZiAoaSA9PSB1ZGNfY250KSB7CgkJCQlCVUdQUklOVCgiYmFkIGRlc3RpbmF0aW9uXG4iKTsKCQkJCXJldHVybiAtMTsKCQkJfQoJCQlpZiAoY2xfc1tpXS5jcy5uKSB7CgkJCQlCVUdQUklOVCgibG9vcFxuIik7CgkJCQlyZXR1cm4gLTE7CgkJCX0KCQkJLyogdGhpcyBjYW4ndCBiZSAwLCBzbyB0aGUgYWJvdmUgdGVzdCBpcyBjb3JyZWN0ICovCgkJCWNsX3NbaV0uY3MubiA9IHBvcyArIDE7CgkJCXBvcyA9IDA7CgkJCWNsX3NbaV0uY3MuZSA9ICgodm9pZCAqKWUgKyBlLT5uZXh0X29mZnNldCk7CgkJCWUgPSAoc3RydWN0IGVidF9lbnRyeSAqKShobHAyLT5kYXRhKTsKCQkJbmVudHJpZXMgPSBobHAyLT5uZW50cmllczsKCQkJY2xfc1tpXS5mcm9tID0gY2hhaW5fbnI7CgkJCWNoYWluX25yID0gaTsKCQkJLyogdGhpcyB1ZGMgaXMgYWNjZXNzaWJsZSBmcm9tIHRoZSBiYXNlIGNoYWluIGZvciBob29rbnIgKi8KCQkJY2xfc1tpXS5ob29rbWFzayB8PSAoMSA8PCBob29rbnIpOwoJCQljb250aW51ZTsKCQl9CmxldHNjb250aW51ZToKCQllID0gKHZvaWQgKillICsgZS0+bmV4dF9vZmZzZXQ7CgkJcG9zKys7Cgl9CglyZXR1cm4gMDsKfQoKLyogZG8gdGhlIHBhcnNpbmcgb2YgdGhlIHRhYmxlL2NoYWlucy9lbnRyaWVzL21hdGNoZXMvd2F0Y2hlcnMvdGFyZ2V0cywgaGVoICovCnN0YXRpYyBpbnQgdHJhbnNsYXRlX3RhYmxlKHN0cnVjdCBlYnRfcmVwbGFjZSAqcmVwbCwKICAgc3RydWN0IGVidF90YWJsZV9pbmZvICpuZXdpbmZvKQp7Cgl1bnNpZ25lZCBpbnQgaSwgaiwgaywgdWRjX2NudDsKCWludCByZXQ7CglzdHJ1Y3QgZWJ0X2NsX3N0YWNrICpjbF9zID0gTlVMTDsgLyogdXNlZCBpbiB0aGUgY2hlY2tpbmcgZm9yIGNoYWluIGxvb3BzICovCgoJaSA9IDA7Cgl3aGlsZSAoaSA8IE5GX0JSX05VTUhPT0tTICYmICEocmVwbC0+dmFsaWRfaG9va3MgJiAoMSA8PCBpKSkpCgkJaSsrOwoJaWYgKGkgPT0gTkZfQlJfTlVNSE9PS1MpIHsKCQlCVUdQUklOVCgiTm8gdmFsaWQgaG9va3Mgc3BlY2lmaWVkXG4iKTsKCQlyZXR1cm4gLUVJTlZBTDsKCX0KCWlmIChyZXBsLT5ob29rX2VudHJ5W2ldICE9IChzdHJ1Y3QgZWJ0X2VudHJpZXMgKilyZXBsLT5lbnRyaWVzKSB7CgkJQlVHUFJJTlQoIkNoYWlucyBkb24ndCBzdGFydCBhdCBiZWdpbm5pbmdcbiIpOwoJCXJldHVybiAtRUlOVkFMOwoJfQoJLyogbWFrZSBzdXJlIGNoYWlucyBhcmUgb3JkZXJlZCBhZnRlciBlYWNoIG90aGVyIGluIHNhbWUgb3JkZXIKCSAgIGFzIHRoZWlyIGNvcnJlc3BvbmRpbmcgaG9va3MgKi8KCWZvciAoaiA9IGkgKyAxOyBqIDwgTkZfQlJfTlVNSE9PS1M7IGorKykgewoJCWlmICghKHJlcGwtPnZhbGlkX2hvb2tzICYgKDEgPDwgaikpKQoJCQljb250aW51ZTsKCQlpZiAoIHJlcGwtPmhvb2tfZW50cnlbal0gPD0gcmVwbC0+aG9va19lbnRyeVtpXSApIHsKCQkJQlVHUFJJTlQoIkhvb2sgb3JkZXIgbXVzdCBiZSBmb2xsb3dlZFxuIik7CgkJCXJldHVybiAtRUlOVkFMOwoJCX0KCQlpID0gajsKCX0KCglmb3IgKGkgPSAwOyBpIDwgTkZfQlJfTlVNSE9PS1M7IGkrKykKCQluZXdpbmZvLT5ob29rX2VudHJ5W2ldID0gTlVMTDsKCgluZXdpbmZvLT5lbnRyaWVzX3NpemUgPSByZXBsLT5lbnRyaWVzX3NpemU7CgluZXdpbmZvLT5uZW50cmllcyA9IHJlcGwtPm5lbnRyaWVzOwoKCS8qIGRvIHNvbWUgZWFybHkgY2hlY2tpbmdzIGFuZCBpbml0aWFsaXplIHNvbWUgdGhpbmdzICovCglpID0gMDsgLyogaG9sZHMgdGhlIGV4cGVjdGVkIG5yLiBvZiBlbnRyaWVzIGZvciB0aGUgY2hhaW4gKi8KCWogPSAwOyAvKiBob2xkcyB0aGUgdXAgdG8gbm93IGNvdW50ZWQgZW50cmllcyBmb3IgdGhlIGNoYWluICovCglrID0gMDsgLyogaG9sZHMgdGhlIHRvdGFsIG5yLiBvZiBlbnRyaWVzLCBzaG91bGQgZXF1YWwKCSAgICAgICAgICBuZXdpbmZvLT5uZW50cmllcyBhZnRlcndhcmRzICovCgl1ZGNfY250ID0gMDsgLyogd2lsbCBob2xkIHRoZSBuci4gb2YgdXNlciBkZWZpbmVkIGNoYWlucyAodWRjKSAqLwoJcmV0ID0gRUJUX0VOVFJZX0lURVJBVEUobmV3aW5mby0+ZW50cmllcywgbmV3aW5mby0+ZW50cmllc19zaXplLAoJICAgZWJ0X2NoZWNrX2VudHJ5X3NpemVfYW5kX2hvb2tzLCBuZXdpbmZvLCByZXBsLT5lbnRyaWVzLAoJICAgcmVwbC0+ZW50cmllcyArIHJlcGwtPmVudHJpZXNfc2l6ZSwgcmVwbC0+aG9va19lbnRyeSwgJmksICZqLCAmaywKCSAgICZ1ZGNfY250LCByZXBsLT52YWxpZF9ob29rcyk7CgoJaWYgKHJldCAhPSAwKQoJCXJldHVybiByZXQ7CgoJaWYgKGkgIT0gaikgewoJCUJVR1BSSU5UKCJuZW50cmllcyBkb2VzIG5vdCBlcXVhbCB0aGUgbnIgb2YgZW50cmllcyBpbiB0aGUgIgoJCSAgICAgICAgICIobGFzdCkgY2hhaW5cbiIpOwoJCXJldHVybiAtRUlOVkFMOwoJfQoJaWYgKGsgIT0gbmV3aW5mby0+bmVudHJpZXMpIHsKCQlCVUdQUklOVCgiVG90YWwgbmVudHJpZXMgaXMgd3JvbmdcbiIpOwoJCXJldHVybiAtRUlOVkFMOwoJfQoKCS8qIGNoZWNrIGlmIGFsbCB2YWxpZCBob29rcyBoYXZlIGEgY2hhaW4gKi8KCWZvciAoaSA9IDA7IGkgPCBORl9CUl9OVU1IT09LUzsgaSsrKSB7CgkJaWYgKG5ld2luZm8tPmhvb2tfZW50cnlbaV0gPT0gTlVMTCAmJgoJCSAgIChyZXBsLT52YWxpZF9ob29rcyAmICgxIDw8IGkpKSkgewoJCQlCVUdQUklOVCgiVmFsaWQgaG9vayB3aXRob3V0IGNoYWluXG4iKTsKCQkJcmV0dXJuIC1FSU5WQUw7CgkJfQoJfQoKCS8qIGdldCB0aGUgbG9jYXRpb24gb2YgdGhlIHVkYywgcHV0IHRoZW0gaW4gYW4gYXJyYXkKCSAgIHdoaWxlIHdlJ3JlIGF0IGl0LCBhbGxvY2F0ZSB0aGUgY2hhaW5zdGFjayAqLwoJaWYgKHVkY19jbnQpIHsKCQkvKiB0aGlzIHdpbGwgZ2V0IGZyZWUnZCBpbiBkb19yZXBsYWNlKCkvZWJ0X3JlZ2lzdGVyX3RhYmxlKCkKCQkgICBpZiBhbiBlcnJvciBvY2N1cnMgKi8KCQluZXdpbmZvLT5jaGFpbnN0YWNrID0KCQkJdm1hbGxvYygoaGlnaGVzdF9wb3NzaWJsZV9wcm9jZXNzb3JfaWQoKSsxKQoJCQkJICAgCSogc2l6ZW9mKCoobmV3aW5mby0+Y2hhaW5zdGFjaykpKTsKCQlpZiAoIW5ld2luZm8tPmNoYWluc3RhY2spCgkJCXJldHVybiAtRU5PTUVNOwoJCWZvcl9lYWNoX3Bvc3NpYmxlX2NwdShpKSB7CgkJCW5ld2luZm8tPmNoYWluc3RhY2tbaV0gPQoJCQkgIHZtYWxsb2ModWRjX2NudCAqIHNpemVvZigqKG5ld2luZm8tPmNoYWluc3RhY2tbMF0pKSk7CgkJCWlmICghbmV3aW5mby0+Y2hhaW5zdGFja1tpXSkgewoJCQkJd2hpbGUgKGkpCgkJCQkJdmZyZWUobmV3aW5mby0+Y2hhaW5zdGFja1stLWldKTsKCQkJCXZmcmVlKG5ld2luZm8tPmNoYWluc3RhY2spOwoJCQkJbmV3aW5mby0+Y2hhaW5zdGFjayA9IE5VTEw7CgkJCQlyZXR1cm4gLUVOT01FTTsKCQkJfQoJCX0KCgkJY2xfcyA9IHZtYWxsb2ModWRjX2NudCAqIHNpemVvZigqY2xfcykpOwoJCWlmICghY2xfcykKCQkJcmV0dXJuIC1FTk9NRU07CgkJaSA9IDA7IC8qIHRoZSBpJ3RoIHVkYyAqLwoJCUVCVF9FTlRSWV9JVEVSQVRFKG5ld2luZm8tPmVudHJpZXMsIG5ld2luZm8tPmVudHJpZXNfc2l6ZSwKCQkgICBlYnRfZ2V0X3VkY19wb3NpdGlvbnMsIG5ld2luZm8sIHJlcGwtPmhvb2tfZW50cnksICZpLAoJCSAgIHJlcGwtPnZhbGlkX2hvb2tzLCBjbF9zKTsKCQkvKiBzYW5pdHkgY2hlY2sgKi8KCQlpZiAoaSAhPSB1ZGNfY250KSB7CgkJCUJVR1BSSU5UKCJpICE9IHVkY19jbnRcbiIpOwoJCQl2ZnJlZShjbF9zKTsKCQkJcmV0dXJuIC1FRkFVTFQ7CgkJfQoJfQoKCS8qIENoZWNrIGZvciBsb29wcyAqLwoJZm9yIChpID0gMDsgaSA8IE5GX0JSX05VTUhPT0tTOyBpKyspCgkJaWYgKHJlcGwtPnZhbGlkX2hvb2tzICYgKDEgPDwgaSkpCgkJCWlmIChjaGVja19jaGFpbmxvb3BzKG5ld2luZm8tPmhvb2tfZW50cnlbaV0sCgkJCSAgIGNsX3MsIHVkY19jbnQsIGksIG5ld2luZm8tPmVudHJpZXMpKSB7CgkJCQl2ZnJlZShjbF9zKTsKCQkJCXJldHVybiAtRUlOVkFMOwoJCQl9CgoJLyogd2Ugbm93IGtub3cgdGhlIGZvbGxvd2luZyAoYWxvbmcgd2l0aCBFPW1jsik6CgkgICAtIHRoZSBuciBvZiBlbnRyaWVzIGluIGVhY2ggY2hhaW4gaXMgcmlnaHQKCSAgIC0gdGhlIHNpemUgb2YgdGhlIGFsbG9jYXRlZCBzcGFjZSBpcyByaWdodAoJICAgLSBhbGwgdmFsaWQgaG9va3MgaGF2ZSBhIGNvcnJlc3BvbmRpbmcgY2hhaW4KCSAgIC0gdGhlcmUgYXJlIG5vIGxvb3BzCgkgICAtIHdyb25nIGRhdGEgY2FuIHN0aWxsIGJlIG9uIHRoZSBsZXZlbCBvZiBhIHNpbmdsZSBlbnRyeQoJICAgLSBjb3VsZCBiZSB0aGVyZSBhcmUganVtcHMgdG8gcGxhY2VzIHRoYXQgYXJlIG5vdCB0aGUKCSAgICAgYmVnaW5uaW5nIG9mIGEgY2hhaW4uIFRoaXMgY2FuIG9ubHkgb2NjdXIgaW4gY2hhaW5zIHRoYXQKCSAgICAgYXJlIG5vdCBhY2Nlc3NpYmxlIGZyb20gYW55IGJhc2UgY2hhaW5zLCBzbyB3ZSBkb24ndCBjYXJlLiAqLwoKCS8qIHVzZWQgdG8ga25vdyB3aGF0IHdlIG5lZWQgdG8gY2xlYW4gdXAgaWYgc29tZXRoaW5nIGdvZXMgd3JvbmcgKi8KCWkgPSAwOwoJcmV0ID0gRUJUX0VOVFJZX0lURVJBVEUobmV3aW5mby0+ZW50cmllcywgbmV3aW5mby0+ZW50cmllc19zaXplLAoJICAgZWJ0X2NoZWNrX2VudHJ5LCBuZXdpbmZvLCByZXBsLT5uYW1lLCAmaSwgcmVwbC0+dmFsaWRfaG9va3MsCgkgICBjbF9zLCB1ZGNfY250KTsKCWlmIChyZXQgIT0gMCkgewoJCUVCVF9FTlRSWV9JVEVSQVRFKG5ld2luZm8tPmVudHJpZXMsIG5ld2luZm8tPmVudHJpZXNfc2l6ZSwKCQkgICBlYnRfY2xlYW51cF9lbnRyeSwgJmkpOwoJfQoJdmZyZWUoY2xfcyk7CglyZXR1cm4gcmV0Owp9CgovKiBjYWxsZWQgdW5kZXIgd3JpdGVfbG9jayAqLwpzdGF0aWMgdm9pZCBnZXRfY291bnRlcnMoc3RydWN0IGVidF9jb3VudGVyICpvbGRjb3VudGVycywKICAgc3RydWN0IGVidF9jb3VudGVyICpjb3VudGVycywgdW5zaWduZWQgaW50IG5lbnRyaWVzKQp7CglpbnQgaSwgY3B1OwoJc3RydWN0IGVidF9jb3VudGVyICpjb3VudGVyX2Jhc2U7CgoJLyogY291bnRlcnMgb2YgY3B1IDAgKi8KCW1lbWNweShjb3VudGVycywgb2xkY291bnRlcnMsCgkgICAgICAgc2l6ZW9mKHN0cnVjdCBlYnRfY291bnRlcikgKiBuZW50cmllcyk7CgoJLyogYWRkIG90aGVyIGNvdW50ZXJzIHRvIHRob3NlIG9mIGNwdSAwICovCglmb3JfZWFjaF9wb3NzaWJsZV9jcHUoY3B1KSB7CgkJaWYgKGNwdSA9PSAwKQoJCQljb250aW51ZTsKCQljb3VudGVyX2Jhc2UgPSBDT1VOVEVSX0JBU0Uob2xkY291bnRlcnMsIG5lbnRyaWVzLCBjcHUpOwoJCWZvciAoaSA9IDA7IGkgPCBuZW50cmllczsgaSsrKSB7CgkJCWNvdW50ZXJzW2ldLnBjbnQgKz0gY291bnRlcl9iYXNlW2ldLnBjbnQ7CgkJCWNvdW50ZXJzW2ldLmJjbnQgKz0gY291bnRlcl9iYXNlW2ldLmJjbnQ7CgkJfQoJfQp9CgovKiByZXBsYWNlIHRoZSB0YWJsZSAqLwpzdGF0aWMgaW50IGRvX3JlcGxhY2Uodm9pZCBfX3VzZXIgKnVzZXIsIHVuc2lnbmVkIGludCBsZW4pCnsKCWludCByZXQsIGksIGNvdW50ZXJzaXplOwoJc3RydWN0IGVidF90YWJsZV9pbmZvICpuZXdpbmZvOwoJc3RydWN0IGVidF9yZXBsYWNlIHRtcDsKCXN0cnVjdCBlYnRfdGFibGUgKnQ7CglzdHJ1Y3QgZWJ0X2NvdW50ZXIgKmNvdW50ZXJzdG1wID0gTlVMTDsKCS8qIHVzZWQgdG8gYmUgYWJsZSB0byB1bmxvY2sgZWFybGllciAqLwoJc3RydWN0IGVidF90YWJsZV9pbmZvICp0YWJsZTsKCglpZiAoY29weV9mcm9tX3VzZXIoJnRtcCwgdXNlciwgc2l6ZW9mKHRtcCkpICE9IDApCgkJcmV0dXJuIC1FRkFVTFQ7CgoJaWYgKGxlbiAhPSBzaXplb2YodG1wKSArIHRtcC5lbnRyaWVzX3NpemUpIHsKCQlCVUdQUklOVCgiV3JvbmcgbGVuIGFyZ3VtZW50XG4iKTsKCQlyZXR1cm4gLUVJTlZBTDsKCX0KCglpZiAodG1wLmVudHJpZXNfc2l6ZSA9PSAwKSB7CgkJQlVHUFJJTlQoIkVudHJpZXNfc2l6ZSBuZXZlciB6ZXJvXG4iKTsKCQlyZXR1cm4gLUVJTlZBTDsKCX0KCS8qIG92ZXJmbG93IGNoZWNrICovCglpZiAodG1wLm5lbnRyaWVzID49ICgoSU5UX01BWCAtIHNpemVvZihzdHJ1Y3QgZWJ0X3RhYmxlX2luZm8pKSAvIE5SX0NQVVMgLQoJCQlTTVBfQ0FDSEVfQllURVMpIC8gc2l6ZW9mKHN0cnVjdCBlYnRfY291bnRlcikpCgkJcmV0dXJuIC1FTk9NRU07CglpZiAodG1wLm51bV9jb3VudGVycyA+PSBJTlRfTUFYIC8gc2l6ZW9mKHN0cnVjdCBlYnRfY291bnRlcikpCgkJcmV0dXJuIC1FTk9NRU07CgoJY291bnRlcnNpemUgPSBDT1VOVEVSX09GRlNFVCh0bXAubmVudHJpZXMpICogCgkJCQkJKGhpZ2hlc3RfcG9zc2libGVfcHJvY2Vzc29yX2lkKCkrMSk7CgluZXdpbmZvID0gdm1hbGxvYyhzaXplb2YoKm5ld2luZm8pICsgY291bnRlcnNpemUpOwoJaWYgKCFuZXdpbmZvKQoJCXJldHVybiAtRU5PTUVNOwoKCWlmIChjb3VudGVyc2l6ZSkKCQltZW1zZXQobmV3aW5mby0+Y291bnRlcnMsIDAsIGNvdW50ZXJzaXplKTsKCgluZXdpbmZvLT5lbnRyaWVzID0gdm1hbGxvYyh0bXAuZW50cmllc19zaXplKTsKCWlmICghbmV3aW5mby0+ZW50cmllcykgewoJCXJldCA9IC1FTk9NRU07CgkJZ290byBmcmVlX25ld2luZm87Cgl9CglpZiAoY29weV9mcm9tX3VzZXIoCgkgICBuZXdpbmZvLT5lbnRyaWVzLCB0bXAuZW50cmllcywgdG1wLmVudHJpZXNfc2l6ZSkgIT0gMCkgewoJCUJVR1BSSU5UKCJDb3VsZG4ndCBjb3B5IGVudHJpZXMgZnJvbSB1c2Vyc3BhY2VcbiIpOwoJCXJldCA9IC1FRkFVTFQ7CgkJZ290byBmcmVlX2VudHJpZXM7Cgl9CgoJLyogdGhlIHVzZXIgd2FudHMgY291bnRlcnMgYmFjawoJICAgdGhlIGNoZWNrIG9uIHRoZSBzaXplIGlzIGRvbmUgbGF0ZXIsIHdoZW4gd2UgaGF2ZSB0aGUgbG9jayAqLwoJaWYgKHRtcC5udW1fY291bnRlcnMpIHsKCQljb3VudGVyc3RtcCA9IHZtYWxsb2ModG1wLm51bV9jb3VudGVycyAqIHNpemVvZigqY291bnRlcnN0bXApKTsKCQlpZiAoIWNvdW50ZXJzdG1wKSB7CgkJCXJldCA9IC1FTk9NRU07CgkJCWdvdG8gZnJlZV9lbnRyaWVzOwoJCX0KCX0KCWVsc2UKCQljb3VudGVyc3RtcCA9IE5VTEw7CgoJLyogdGhpcyBjYW4gZ2V0IGluaXRpYWxpemVkIGJ5IHRyYW5zbGF0ZV90YWJsZSgpICovCgluZXdpbmZvLT5jaGFpbnN0YWNrID0gTlVMTDsKCXJldCA9IHRyYW5zbGF0ZV90YWJsZSgmdG1wLCBuZXdpbmZvKTsKCglpZiAocmV0ICE9IDApCgkJZ290byBmcmVlX2NvdW50ZXJzdG1wOwoKCXQgPSBmaW5kX3RhYmxlX2xvY2sodG1wLm5hbWUsICZyZXQsICZlYnRfbXV0ZXgpOwoJaWYgKCF0KSB7CgkJcmV0ID0gLUVOT0VOVDsKCQlnb3RvIGZyZWVfaXRlcmF0ZTsKCX0KCgkvKiB0aGUgdGFibGUgZG9lc24ndCBsaWtlIGl0ICovCglpZiAodC0+Y2hlY2sgJiYgKHJldCA9IHQtPmNoZWNrKG5ld2luZm8sIHRtcC52YWxpZF9ob29rcykpKQoJCWdvdG8gZnJlZV91bmxvY2s7CgoJaWYgKHRtcC5udW1fY291bnRlcnMgJiYgdG1wLm51bV9jb3VudGVycyAhPSB0LT5wcml2YXRlLT5uZW50cmllcykgewoJCUJVR1BSSU5UKCJXcm9uZyBuci4gb2YgY291bnRlcnMgcmVxdWVzdGVkXG4iKTsKCQlyZXQgPSAtRUlOVkFMOwoJCWdvdG8gZnJlZV91bmxvY2s7Cgl9CgoJLyogd2UgaGF2ZSB0aGUgbXV0ZXggbG9jaywgc28gbm8gZGFuZ2VyIGluIHJlYWRpbmcgdGhpcyBwb2ludGVyICovCgl0YWJsZSA9IHQtPnByaXZhdGU7CgkvKiBtYWtlIHN1cmUgdGhlIHRhYmxlIGNhbiBvbmx5IGJlIHJtbW9kJ2VkIGlmIGl0IGNvbnRhaW5zIG5vIHJ1bGVzICovCglpZiAoIXRhYmxlLT5uZW50cmllcyAmJiBuZXdpbmZvLT5uZW50cmllcyAmJiAhdHJ5X21vZHVsZV9nZXQodC0+bWUpKSB7CgkJcmV0ID0gLUVOT0VOVDsKCQlnb3RvIGZyZWVfdW5sb2NrOwoJfSBlbHNlIGlmICh0YWJsZS0+bmVudHJpZXMgJiYgIW5ld2luZm8tPm5lbnRyaWVzKQoJCW1vZHVsZV9wdXQodC0+bWUpOwoJLyogd2UgbmVlZCBhbiBhdG9taWMgc25hcHNob3Qgb2YgdGhlIGNvdW50ZXJzICovCgl3cml0ZV9sb2NrX2JoKCZ0LT5sb2NrKTsKCWlmICh0bXAubnVtX2NvdW50ZXJzKQoJCWdldF9jb3VudGVycyh0LT5wcml2YXRlLT5jb3VudGVycywgY291bnRlcnN0bXAsCgkJICAgdC0+cHJpdmF0ZS0+bmVudHJpZXMpOwoKCXQtPnByaXZhdGUgPSBuZXdpbmZvOwoJd3JpdGVfdW5sb2NrX2JoKCZ0LT5sb2NrKTsKCW11dGV4X3VubG9jaygmZWJ0X211dGV4KTsKCS8qIHNvLCBhIHVzZXIgY2FuIGNoYW5nZSB0aGUgY2hhaW5zIHdoaWxlIGhhdmluZyBtZXNzZWQgdXAgaGVyIGNvdW50ZXIKCSAgIGFsbG9jYXRpb24uIE9ubHkgcmVhc29uIHdoeSB0aGlzIGlzIGRvbmUgaXMgYmVjYXVzZSB0aGlzIHdheSB0aGUgbG9jawoJICAgaXMgaGVsZCBvbmx5IG9uY2UsIHdoaWxlIHRoaXMgZG9lc24ndCBicmluZyB0aGUga2VybmVsIGludG8gYQoJICAgZGFuZ2Vyb3VzIHN0YXRlLiAqLwoJaWYgKHRtcC5udW1fY291bnRlcnMgJiYKCSAgIGNvcHlfdG9fdXNlcih0bXAuY291bnRlcnMsIGNvdW50ZXJzdG1wLAoJICAgdG1wLm51bV9jb3VudGVycyAqIHNpemVvZihzdHJ1Y3QgZWJ0X2NvdW50ZXIpKSkgewoJCUJVR1BSSU5UKCJDb3VsZG4ndCBjb3B5IGNvdW50ZXJzIHRvIHVzZXJzcGFjZVxuIik7CgkJcmV0ID0gLUVGQVVMVDsKCX0KCWVsc2UKCQlyZXQgPSAwOwoKCS8qIGRlY3JlYXNlIG1vZHVsZSBjb3VudCBhbmQgZnJlZSByZXNvdXJjZXMgKi8KCUVCVF9FTlRSWV9JVEVSQVRFKHRhYmxlLT5lbnRyaWVzLCB0YWJsZS0+ZW50cmllc19zaXplLAoJICAgZWJ0X2NsZWFudXBfZW50cnksIE5VTEwpOwoKCXZmcmVlKHRhYmxlLT5lbnRyaWVzKTsKCWlmICh0YWJsZS0+Y2hhaW5zdGFjaykgewoJCWZvcl9lYWNoX3Bvc3NpYmxlX2NwdShpKQoJCQl2ZnJlZSh0YWJsZS0+Y2hhaW5zdGFja1tpXSk7CgkJdmZyZWUodGFibGUtPmNoYWluc3RhY2spOwoJfQoJdmZyZWUodGFibGUpOwoKCXZmcmVlKGNvdW50ZXJzdG1wKTsKCXJldHVybiByZXQ7CgpmcmVlX3VubG9jazoKCW11dGV4X3VubG9jaygmZWJ0X211dGV4KTsKZnJlZV9pdGVyYXRlOgoJRUJUX0VOVFJZX0lURVJBVEUobmV3aW5mby0+ZW50cmllcywgbmV3aW5mby0+ZW50cmllc19zaXplLAoJICAgZWJ0X2NsZWFudXBfZW50cnksIE5VTEwpOwpmcmVlX2NvdW50ZXJzdG1wOgoJdmZyZWUoY291bnRlcnN0bXApOwoJLyogY2FuIGJlIGluaXRpYWxpemVkIGluIHRyYW5zbGF0ZV90YWJsZSgpICovCglpZiAobmV3aW5mby0+Y2hhaW5zdGFjaykgewoJCWZvcl9lYWNoX3Bvc3NpYmxlX2NwdShpKQoJCQl2ZnJlZShuZXdpbmZvLT5jaGFpbnN0YWNrW2ldKTsKCQl2ZnJlZShuZXdpbmZvLT5jaGFpbnN0YWNrKTsKCX0KZnJlZV9lbnRyaWVzOgoJdmZyZWUobmV3aW5mby0+ZW50cmllcyk7CmZyZWVfbmV3aW5mbzoKCXZmcmVlKG5ld2luZm8pOwoJcmV0dXJuIHJldDsKfQoKaW50IGVidF9yZWdpc3Rlcl90YXJnZXQoc3RydWN0IGVidF90YXJnZXQgKnRhcmdldCkKewoJc3RydWN0IGVidF90YXJnZXQgKnQ7CglpbnQgcmV0OwoKCXJldCA9IG11dGV4X2xvY2tfaW50ZXJydXB0aWJsZSgmZWJ0X211dGV4KTsKCWlmIChyZXQgIT0gMCkKCQlyZXR1cm4gcmV0OwoJbGlzdF9mb3JfZWFjaF9lbnRyeSh0LCAmZWJ0X3RhcmdldHMsIGxpc3QpIHsKCQlpZiAoc3RyY21wKHQtPm5hbWUsIHRhcmdldC0+bmFtZSkgPT0gMCkgewoJCQltdXRleF91bmxvY2soJmVidF9tdXRleCk7CgkJCXJldHVybiAtRUVYSVNUOwoJCX0KCX0KCWxpc3RfYWRkKCZ0YXJnZXQtPmxpc3QsICZlYnRfdGFyZ2V0cyk7CgltdXRleF91bmxvY2soJmVidF9tdXRleCk7CgoJcmV0dXJuIDA7Cn0KCnZvaWQgZWJ0X3VucmVnaXN0ZXJfdGFyZ2V0KHN0cnVjdCBlYnRfdGFyZ2V0ICp0YXJnZXQpCnsKCW11dGV4X2xvY2soJmVidF9tdXRleCk7CglsaXN0X2RlbCgmdGFyZ2V0LT5saXN0KTsKCW11dGV4X3VubG9jaygmZWJ0X211dGV4KTsKfQoKaW50IGVidF9yZWdpc3Rlcl9tYXRjaChzdHJ1Y3QgZWJ0X21hdGNoICptYXRjaCkKewoJc3RydWN0IGVidF9tYXRjaCAqbTsKCWludCByZXQ7CgoJcmV0ID0gbXV0ZXhfbG9ja19pbnRlcnJ1cHRpYmxlKCZlYnRfbXV0ZXgpOwoJaWYgKHJldCAhPSAwKQoJCXJldHVybiByZXQ7CglsaXN0X2Zvcl9lYWNoX2VudHJ5KG0sICZlYnRfbWF0Y2hlcywgbGlzdCkgewoJCWlmIChzdHJjbXAobS0+bmFtZSwgbWF0Y2gtPm5hbWUpID09IDApIHsKCQkJbXV0ZXhfdW5sb2NrKCZlYnRfbXV0ZXgpOwoJCQlyZXR1cm4gLUVFWElTVDsKCQl9Cgl9CglsaXN0X2FkZCgmbWF0Y2gtPmxpc3QsICZlYnRfbWF0Y2hlcyk7CgltdXRleF91bmxvY2soJmVidF9tdXRleCk7CgoJcmV0dXJuIDA7Cn0KCnZvaWQgZWJ0X3VucmVnaXN0ZXJfbWF0Y2goc3RydWN0IGVidF9tYXRjaCAqbWF0Y2gpCnsKCW11dGV4X2xvY2soJmVidF9tdXRleCk7CglsaXN0X2RlbCgmbWF0Y2gtPmxpc3QpOwoJbXV0ZXhfdW5sb2NrKCZlYnRfbXV0ZXgpOwp9CgppbnQgZWJ0X3JlZ2lzdGVyX3dhdGNoZXIoc3RydWN0IGVidF93YXRjaGVyICp3YXRjaGVyKQp7CglzdHJ1Y3QgZWJ0X3dhdGNoZXIgKnc7CglpbnQgcmV0OwoKCXJldCA9IG11dGV4X2xvY2tfaW50ZXJydXB0aWJsZSgmZWJ0X211dGV4KTsKCWlmIChyZXQgIT0gMCkKCQlyZXR1cm4gcmV0OwoJbGlzdF9mb3JfZWFjaF9lbnRyeSh3LCAmZWJ0X3dhdGNoZXJzLCBsaXN0KSB7CgkJaWYgKHN0cmNtcCh3LT5uYW1lLCB3YXRjaGVyLT5uYW1lKSA9PSAwKSB7CgkJCW11dGV4X3VubG9jaygmZWJ0X211dGV4KTsKCQkJcmV0dXJuIC1FRVhJU1Q7CgkJfQoJfQoJbGlzdF9hZGQoJndhdGNoZXItPmxpc3QsICZlYnRfd2F0Y2hlcnMpOwoJbXV0ZXhfdW5sb2NrKCZlYnRfbXV0ZXgpOwoKCXJldHVybiAwOwp9Cgp2b2lkIGVidF91bnJlZ2lzdGVyX3dhdGNoZXIoc3RydWN0IGVidF93YXRjaGVyICp3YXRjaGVyKQp7CgltdXRleF9sb2NrKCZlYnRfbXV0ZXgpOwoJbGlzdF9kZWwoJndhdGNoZXItPmxpc3QpOwoJbXV0ZXhfdW5sb2NrKCZlYnRfbXV0ZXgpOwp9CgppbnQgZWJ0X3JlZ2lzdGVyX3RhYmxlKHN0cnVjdCBlYnRfdGFibGUgKnRhYmxlKQp7CglzdHJ1Y3QgZWJ0X3RhYmxlX2luZm8gKm5ld2luZm87CglzdHJ1Y3QgZWJ0X3RhYmxlICp0OwoJaW50IHJldCwgaSwgY291bnRlcnNpemU7CgoJaWYgKCF0YWJsZSB8fCAhdGFibGUtPnRhYmxlIHx8IXRhYmxlLT50YWJsZS0+ZW50cmllcyB8fAoJICAgIHRhYmxlLT50YWJsZS0+ZW50cmllc19zaXplID09IDAgfHwKCSAgICB0YWJsZS0+dGFibGUtPmNvdW50ZXJzIHx8IHRhYmxlLT5wcml2YXRlKSB7CgkJQlVHUFJJTlQoIkJhZCB0YWJsZSBkYXRhIGZvciBlYnRfcmVnaXN0ZXJfdGFibGUhISFcbiIpOwoJCXJldHVybiAtRUlOVkFMOwoJfQoKCWNvdW50ZXJzaXplID0gQ09VTlRFUl9PRkZTRVQodGFibGUtPnRhYmxlLT5uZW50cmllcykgKgoJCQkJCShoaWdoZXN0X3Bvc3NpYmxlX3Byb2Nlc3Nvcl9pZCgpKzEpOwoJbmV3aW5mbyA9IHZtYWxsb2Moc2l6ZW9mKCpuZXdpbmZvKSArIGNvdW50ZXJzaXplKTsKCXJldCA9IC1FTk9NRU07CglpZiAoIW5ld2luZm8pCgkJcmV0dXJuIC1FTk9NRU07CgoJbmV3aW5mby0+ZW50cmllcyA9IHZtYWxsb2ModGFibGUtPnRhYmxlLT5lbnRyaWVzX3NpemUpOwoJaWYgKCEobmV3aW5mby0+ZW50cmllcykpCgkJZ290byBmcmVlX25ld2luZm87CgoJbWVtY3B5KG5ld2luZm8tPmVudHJpZXMsIHRhYmxlLT50YWJsZS0+ZW50cmllcywKCSAgIHRhYmxlLT50YWJsZS0+ZW50cmllc19zaXplKTsKCglpZiAoY291bnRlcnNpemUpCgkJbWVtc2V0KG5ld2luZm8tPmNvdW50ZXJzLCAwLCBjb3VudGVyc2l6ZSk7CgoJLyogZmlsbCBpbiBuZXdpbmZvIGFuZCBwYXJzZSB0aGUgZW50cmllcyAqLwoJbmV3aW5mby0+Y2hhaW5zdGFjayA9IE5VTEw7CglyZXQgPSB0cmFuc2xhdGVfdGFibGUodGFibGUtPnRhYmxlLCBuZXdpbmZvKTsKCWlmIChyZXQgIT0gMCkgewoJCUJVR1BSSU5UKCJUcmFuc2xhdGVfdGFibGUgZmFpbGVkXG4iKTsKCQlnb3RvIGZyZWVfY2hhaW5zdGFjazsKCX0KCglpZiAodGFibGUtPmNoZWNrICYmIHRhYmxlLT5jaGVjayhuZXdpbmZvLCB0YWJsZS0+dmFsaWRfaG9va3MpKSB7CgkJQlVHUFJJTlQoIlRoZSB0YWJsZSBkb2Vzbid0IGxpa2UgaXRzIG93biBpbml0aWFsIGRhdGEsIGxvbFxuIik7CgkJcmV0dXJuIC1FSU5WQUw7Cgl9CgoJdGFibGUtPnByaXZhdGUgPSBuZXdpbmZvOwoJcndsb2NrX2luaXQoJnRhYmxlLT5sb2NrKTsKCXJldCA9IG11dGV4X2xvY2tfaW50ZXJydXB0aWJsZSgmZWJ0X211dGV4KTsKCWlmIChyZXQgIT0gMCkKCQlnb3RvIGZyZWVfY2hhaW5zdGFjazsKCglsaXN0X2Zvcl9lYWNoX2VudHJ5KHQsICZlYnRfdGFibGVzLCBsaXN0KSB7CgkJaWYgKHN0cmNtcCh0LT5uYW1lLCB0YWJsZS0+bmFtZSkgPT0gMCkgewoJCQlyZXQgPSAtRUVYSVNUOwoJCQlCVUdQUklOVCgiVGFibGUgbmFtZSBhbHJlYWR5IGV4aXN0c1xuIik7CgkJCWdvdG8gZnJlZV91bmxvY2s7CgkJfQoJfQoKCS8qIEhvbGQgYSByZWZlcmVuY2UgY291bnQgaWYgdGhlIGNoYWlucyBhcmVuJ3QgZW1wdHkgKi8KCWlmIChuZXdpbmZvLT5uZW50cmllcyAmJiAhdHJ5X21vZHVsZV9nZXQodGFibGUtPm1lKSkgewoJCXJldCA9IC1FTk9FTlQ7CgkJZ290byBmcmVlX3VubG9jazsKCX0KCWxpc3RfYWRkKCZ0YWJsZS0+bGlzdCwgJmVidF90YWJsZXMpOwoJbXV0ZXhfdW5sb2NrKCZlYnRfbXV0ZXgpOwoJcmV0dXJuIDA7CmZyZWVfdW5sb2NrOgoJbXV0ZXhfdW5sb2NrKCZlYnRfbXV0ZXgpOwpmcmVlX2NoYWluc3RhY2s6CglpZiAobmV3aW5mby0+Y2hhaW5zdGFjaykgewoJCWZvcl9lYWNoX3Bvc3NpYmxlX2NwdShpKQoJCQl2ZnJlZShuZXdpbmZvLT5jaGFpbnN0YWNrW2ldKTsKCQl2ZnJlZShuZXdpbmZvLT5jaGFpbnN0YWNrKTsKCX0KCXZmcmVlKG5ld2luZm8tPmVudHJpZXMpOwpmcmVlX25ld2luZm86Cgl2ZnJlZShuZXdpbmZvKTsKCXJldHVybiByZXQ7Cn0KCnZvaWQgZWJ0X3VucmVnaXN0ZXJfdGFibGUoc3RydWN0IGVidF90YWJsZSAqdGFibGUpCnsKCWludCBpOwoKCWlmICghdGFibGUpIHsKCQlCVUdQUklOVCgiUmVxdWVzdCB0byB1bnJlZ2lzdGVyIE5VTEwgdGFibGUhISFcbiIpOwoJCXJldHVybjsKCX0KCW11dGV4X2xvY2soJmVidF9tdXRleCk7CglsaXN0X2RlbCgmdGFibGUtPmxpc3QpOwoJbXV0ZXhfdW5sb2NrKCZlYnRfbXV0ZXgpOwoJdmZyZWUodGFibGUtPnByaXZhdGUtPmVudHJpZXMpOwoJaWYgKHRhYmxlLT5wcml2YXRlLT5jaGFpbnN0YWNrKSB7CgkJZm9yX2VhY2hfcG9zc2libGVfY3B1KGkpCgkJCXZmcmVlKHRhYmxlLT5wcml2YXRlLT5jaGFpbnN0YWNrW2ldKTsKCQl2ZnJlZSh0YWJsZS0+cHJpdmF0ZS0+Y2hhaW5zdGFjayk7Cgl9Cgl2ZnJlZSh0YWJsZS0+cHJpdmF0ZSk7Cn0KCi8qIHVzZXJzcGFjZSBqdXN0IHN1cHBsaWVkIHVzIHdpdGggY291bnRlcnMgKi8Kc3RhdGljIGludCB1cGRhdGVfY291bnRlcnModm9pZCBfX3VzZXIgKnVzZXIsIHVuc2lnbmVkIGludCBsZW4pCnsKCWludCBpLCByZXQ7CglzdHJ1Y3QgZWJ0X2NvdW50ZXIgKnRtcDsKCXN0cnVjdCBlYnRfcmVwbGFjZSBobHA7CglzdHJ1Y3QgZWJ0X3RhYmxlICp0OwoKCWlmIChjb3B5X2Zyb21fdXNlcigmaGxwLCB1c2VyLCBzaXplb2YoaGxwKSkpCgkJcmV0dXJuIC1FRkFVTFQ7CgoJaWYgKGxlbiAhPSBzaXplb2YoaGxwKSArIGhscC5udW1fY291bnRlcnMgKiBzaXplb2Yoc3RydWN0IGVidF9jb3VudGVyKSkKCQlyZXR1cm4gLUVJTlZBTDsKCWlmIChobHAubnVtX2NvdW50ZXJzID09IDApCgkJcmV0dXJuIC1FSU5WQUw7CgoJaWYgKCEodG1wID0gdm1hbGxvYyhobHAubnVtX2NvdW50ZXJzICogc2l6ZW9mKCp0bXApKSkpIHsKCQlNRU1QUklOVCgiVXBkYXRlX2NvdW50ZXJzICYmIG5vbWVtb3J5XG4iKTsKCQlyZXR1cm4gLUVOT01FTTsKCX0KCgl0ID0gZmluZF90YWJsZV9sb2NrKGhscC5uYW1lLCAmcmV0LCAmZWJ0X211dGV4KTsKCWlmICghdCkKCQlnb3RvIGZyZWVfdG1wOwoKCWlmIChobHAubnVtX2NvdW50ZXJzICE9IHQtPnByaXZhdGUtPm5lbnRyaWVzKSB7CgkJQlVHUFJJTlQoIldyb25nIG5yIG9mIGNvdW50ZXJzXG4iKTsKCQlyZXQgPSAtRUlOVkFMOwoJCWdvdG8gdW5sb2NrX211dGV4OwoJfQoKCWlmICggY29weV9mcm9tX3VzZXIodG1wLCBobHAuY291bnRlcnMsCgkgICBobHAubnVtX2NvdW50ZXJzICogc2l6ZW9mKHN0cnVjdCBlYnRfY291bnRlcikpICkgewoJCUJVR1BSSU5UKCJVcGRhdGFfY291bnRlcnMgJiYgIWNmdVxuIik7CgkJcmV0ID0gLUVGQVVMVDsKCQlnb3RvIHVubG9ja19tdXRleDsKCX0KCgkvKiB3ZSB3YW50IGFuIGF0b21pYyBhZGQgb2YgdGhlIGNvdW50ZXJzICovCgl3cml0ZV9sb2NrX2JoKCZ0LT5sb2NrKTsKCgkvKiB3ZSBhZGQgdG8gdGhlIGNvdW50ZXJzIG9mIHRoZSBmaXJzdCBjcHUgKi8KCWZvciAoaSA9IDA7IGkgPCBobHAubnVtX2NvdW50ZXJzOyBpKyspIHsKCQl0LT5wcml2YXRlLT5jb3VudGVyc1tpXS5wY250ICs9IHRtcFtpXS5wY250OwoJCXQtPnByaXZhdGUtPmNvdW50ZXJzW2ldLmJjbnQgKz0gdG1wW2ldLmJjbnQ7Cgl9CgoJd3JpdGVfdW5sb2NrX2JoKCZ0LT5sb2NrKTsKCXJldCA9IDA7CnVubG9ja19tdXRleDoKCW11dGV4X3VubG9jaygmZWJ0X211dGV4KTsKZnJlZV90bXA6Cgl2ZnJlZSh0bXApOwoJcmV0dXJuIHJldDsKfQoKc3RhdGljIGlubGluZSBpbnQgZWJ0X21ha2VfbWF0Y2huYW1lKHN0cnVjdCBlYnRfZW50cnlfbWF0Y2ggKm0sCiAgIGNoYXIgKmJhc2UsIGNoYXIgKnViYXNlKQp7CgljaGFyICpobHAgPSB1YmFzZSAtIGJhc2UgKyAoY2hhciAqKW07CglpZiAoY29weV90b191c2VyKGhscCwgbS0+dS5tYXRjaC0+bmFtZSwgRUJUX0ZVTkNUSU9OX01BWE5BTUVMRU4pKQoJCXJldHVybiAtRUZBVUxUOwoJcmV0dXJuIDA7Cn0KCnN0YXRpYyBpbmxpbmUgaW50IGVidF9tYWtlX3dhdGNoZXJuYW1lKHN0cnVjdCBlYnRfZW50cnlfd2F0Y2hlciAqdywKICAgY2hhciAqYmFzZSwgY2hhciAqdWJhc2UpCnsKCWNoYXIgKmhscCA9IHViYXNlIC0gYmFzZSArIChjaGFyICopdzsKCWlmIChjb3B5X3RvX3VzZXIoaGxwICwgdy0+dS53YXRjaGVyLT5uYW1lLCBFQlRfRlVOQ1RJT05fTUFYTkFNRUxFTikpCgkJcmV0dXJuIC1FRkFVTFQ7CglyZXR1cm4gMDsKfQoKc3RhdGljIGlubGluZSBpbnQgZWJ0X21ha2VfbmFtZXMoc3RydWN0IGVidF9lbnRyeSAqZSwgY2hhciAqYmFzZSwgY2hhciAqdWJhc2UpCnsKCWludCByZXQ7CgljaGFyICpobHA7CglzdHJ1Y3QgZWJ0X2VudHJ5X3RhcmdldCAqdDsKCglpZiAoKGUtPmJpdG1hc2sgJiBFQlRfRU5UUllfT1JfRU5UUklFUykgPT0gMCkKCQlyZXR1cm4gMDsKCglobHAgPSB1YmFzZSAtIGJhc2UgKyAoY2hhciAqKWUgKyBlLT50YXJnZXRfb2Zmc2V0OwoJdCA9IChzdHJ1Y3QgZWJ0X2VudHJ5X3RhcmdldCAqKSgoKGNoYXIgKillKSArIGUtPnRhcmdldF9vZmZzZXQpOwoJCglyZXQgPSBFQlRfTUFUQ0hfSVRFUkFURShlLCBlYnRfbWFrZV9tYXRjaG5hbWUsIGJhc2UsIHViYXNlKTsKCWlmIChyZXQgIT0gMCkKCQlyZXR1cm4gcmV0OwoJcmV0ID0gRUJUX1dBVENIRVJfSVRFUkFURShlLCBlYnRfbWFrZV93YXRjaGVybmFtZSwgYmFzZSwgdWJhc2UpOwoJaWYgKHJldCAhPSAwKQoJCXJldHVybiByZXQ7CglpZiAoY29weV90b191c2VyKGhscCwgdC0+dS50YXJnZXQtPm5hbWUsIEVCVF9GVU5DVElPTl9NQVhOQU1FTEVOKSkKCQlyZXR1cm4gLUVGQVVMVDsKCXJldHVybiAwOwp9CgovKiBjYWxsZWQgd2l0aCBlYnRfbXV0ZXggbG9ja2VkICovCnN0YXRpYyBpbnQgY29weV9ldmVyeXRoaW5nX3RvX3VzZXIoc3RydWN0IGVidF90YWJsZSAqdCwgdm9pZCBfX3VzZXIgKnVzZXIsCiAgIGludCAqbGVuLCBpbnQgY21kKQp7CglzdHJ1Y3QgZWJ0X3JlcGxhY2UgdG1wOwoJc3RydWN0IGVidF9jb3VudGVyICpjb3VudGVyc3RtcCwgKm9sZGNvdW50ZXJzOwoJdW5zaWduZWQgaW50IGVudHJpZXNfc2l6ZSwgbmVudHJpZXM7CgljaGFyICplbnRyaWVzOwoKCWlmIChjbWQgPT0gRUJUX1NPX0dFVF9FTlRSSUVTKSB7CgkJZW50cmllc19zaXplID0gdC0+cHJpdmF0ZS0+ZW50cmllc19zaXplOwoJCW5lbnRyaWVzID0gdC0+cHJpdmF0ZS0+bmVudHJpZXM7CgkJZW50cmllcyA9IHQtPnByaXZhdGUtPmVudHJpZXM7CgkJb2xkY291bnRlcnMgPSB0LT5wcml2YXRlLT5jb3VudGVyczsKCX0gZWxzZSB7CgkJZW50cmllc19zaXplID0gdC0+dGFibGUtPmVudHJpZXNfc2l6ZTsKCQluZW50cmllcyA9IHQtPnRhYmxlLT5uZW50cmllczsKCQllbnRyaWVzID0gdC0+dGFibGUtPmVudHJpZXM7CgkJb2xkY291bnRlcnMgPSB0LT50YWJsZS0+Y291bnRlcnM7Cgl9CgoJaWYgKGNvcHlfZnJvbV91c2VyKCZ0bXAsIHVzZXIsIHNpemVvZih0bXApKSkgewoJCUJVR1BSSU5UKCJDZnUgZGlkbid0IHdvcmtcbiIpOwoJCXJldHVybiAtRUZBVUxUOwoJfQoKCWlmICgqbGVuICE9IHNpemVvZihzdHJ1Y3QgZWJ0X3JlcGxhY2UpICsgZW50cmllc19zaXplICsKCSAgICh0bXAubnVtX2NvdW50ZXJzPyBuZW50cmllcyAqIHNpemVvZihzdHJ1Y3QgZWJ0X2NvdW50ZXIpOiAwKSkgewoJCUJVR1BSSU5UKCJXcm9uZyBzaXplXG4iKTsKCQlyZXR1cm4gLUVJTlZBTDsKCX0KCglpZiAodG1wLm5lbnRyaWVzICE9IG5lbnRyaWVzKSB7CgkJQlVHUFJJTlQoIk5lbnRyaWVzIHdyb25nXG4iKTsKCQlyZXR1cm4gLUVJTlZBTDsKCX0KCglpZiAodG1wLmVudHJpZXNfc2l6ZSAhPSBlbnRyaWVzX3NpemUpIHsKCQlCVUdQUklOVCgiV3Jvbmcgc2l6ZVxuIik7CgkJcmV0dXJuIC1FSU5WQUw7Cgl9CgoJLyogdXNlcnNwYWNlIG1pZ2h0IG5vdCBuZWVkIHRoZSBjb3VudGVycyAqLwoJaWYgKHRtcC5udW1fY291bnRlcnMpIHsKCQlpZiAodG1wLm51bV9jb3VudGVycyAhPSBuZW50cmllcykgewoJCQlCVUdQUklOVCgiTnVtX2NvdW50ZXJzIHdyb25nXG4iKTsKCQkJcmV0dXJuIC1FSU5WQUw7CgkJfQoJCWNvdW50ZXJzdG1wID0gdm1hbGxvYyhuZW50cmllcyAqIHNpemVvZigqY291bnRlcnN0bXApKTsKCQlpZiAoIWNvdW50ZXJzdG1wKSB7CgkJCU1FTVBSSU5UKCJDb3VsZG4ndCBjb3B5IGNvdW50ZXJzLCBvdXQgb2YgbWVtb3J5XG4iKTsKCQkJcmV0dXJuIC1FTk9NRU07CgkJfQoJCXdyaXRlX2xvY2tfYmgoJnQtPmxvY2spOwoJCWdldF9jb3VudGVycyhvbGRjb3VudGVycywgY291bnRlcnN0bXAsIG5lbnRyaWVzKTsKCQl3cml0ZV91bmxvY2tfYmgoJnQtPmxvY2spOwoKCQlpZiAoY29weV90b191c2VyKHRtcC5jb3VudGVycywgY291bnRlcnN0bXAsCgkJICAgbmVudHJpZXMgKiBzaXplb2Yoc3RydWN0IGVidF9jb3VudGVyKSkpIHsKCQkJQlVHUFJJTlQoIkNvdWxkbid0IGNvcHkgY291bnRlcnMgdG8gdXNlcnNwYWNlXG4iKTsKCQkJdmZyZWUoY291bnRlcnN0bXApOwoJCQlyZXR1cm4gLUVGQVVMVDsKCQl9CgkJdmZyZWUoY291bnRlcnN0bXApOwoJfQoKCWlmIChjb3B5X3RvX3VzZXIodG1wLmVudHJpZXMsIGVudHJpZXMsIGVudHJpZXNfc2l6ZSkpIHsKCQlCVUdQUklOVCgiQ291bGRuJ3QgY29weSBlbnRyaWVzIHRvIHVzZXJzcGFjZVxuIik7CgkJcmV0dXJuIC1FRkFVTFQ7Cgl9CgkvKiBzZXQgdGhlIG1hdGNoL3dhdGNoZXIvdGFyZ2V0IG5hbWVzIHJpZ2h0ICovCglyZXR1cm4gRUJUX0VOVFJZX0lURVJBVEUoZW50cmllcywgZW50cmllc19zaXplLAoJICAgZWJ0X21ha2VfbmFtZXMsIGVudHJpZXMsIHRtcC5lbnRyaWVzKTsKfQoKc3RhdGljIGludCBkb19lYnRfc2V0X2N0bChzdHJ1Y3Qgc29jayAqc2ssCglpbnQgY21kLCB2b2lkIF9fdXNlciAqdXNlciwgdW5zaWduZWQgaW50IGxlbikKewoJaW50IHJldDsKCglzd2l0Y2goY21kKSB7CgljYXNlIEVCVF9TT19TRVRfRU5UUklFUzoKCQlyZXQgPSBkb19yZXBsYWNlKHVzZXIsIGxlbik7CgkJYnJlYWs7CgljYXNlIEVCVF9TT19TRVRfQ09VTlRFUlM6CgkJcmV0ID0gdXBkYXRlX2NvdW50ZXJzKHVzZXIsIGxlbik7CgkJYnJlYWs7CglkZWZhdWx0OgoJCXJldCA9IC1FSU5WQUw7CiAgfQoJcmV0dXJuIHJldDsKfQoKc3RhdGljIGludCBkb19lYnRfZ2V0X2N0bChzdHJ1Y3Qgc29jayAqc2ssIGludCBjbWQsIHZvaWQgX191c2VyICp1c2VyLCBpbnQgKmxlbikKewoJaW50IHJldDsKCXN0cnVjdCBlYnRfcmVwbGFjZSB0bXA7CglzdHJ1Y3QgZWJ0X3RhYmxlICp0OwoKCWlmIChjb3B5X2Zyb21fdXNlcigmdG1wLCB1c2VyLCBzaXplb2YodG1wKSkpCgkJcmV0dXJuIC1FRkFVTFQ7CgoJdCA9IGZpbmRfdGFibGVfbG9jayh0bXAubmFtZSwgJnJldCwgJmVidF9tdXRleCk7CglpZiAoIXQpCgkJcmV0dXJuIHJldDsKCglzd2l0Y2goY21kKSB7CgljYXNlIEVCVF9TT19HRVRfSU5GTzoKCWNhc2UgRUJUX1NPX0dFVF9JTklUX0lORk86CgkJaWYgKCpsZW4gIT0gc2l6ZW9mKHN0cnVjdCBlYnRfcmVwbGFjZSkpewoJCQlyZXQgPSAtRUlOVkFMOwoJCQltdXRleF91bmxvY2soJmVidF9tdXRleCk7CgkJCWJyZWFrOwoJCX0KCQlpZiAoY21kID09IEVCVF9TT19HRVRfSU5GTykgewoJCQl0bXAubmVudHJpZXMgPSB0LT5wcml2YXRlLT5uZW50cmllczsKCQkJdG1wLmVudHJpZXNfc2l6ZSA9IHQtPnByaXZhdGUtPmVudHJpZXNfc2l6ZTsKCQkJdG1wLnZhbGlkX2hvb2tzID0gdC0+dmFsaWRfaG9va3M7CgkJfSBlbHNlIHsKCQkJdG1wLm5lbnRyaWVzID0gdC0+dGFibGUtPm5lbnRyaWVzOwoJCQl0bXAuZW50cmllc19zaXplID0gdC0+dGFibGUtPmVudHJpZXNfc2l6ZTsKCQkJdG1wLnZhbGlkX2hvb2tzID0gdC0+dGFibGUtPnZhbGlkX2hvb2tzOwoJCX0KCQltdXRleF91bmxvY2soJmVidF9tdXRleCk7CgkJaWYgKGNvcHlfdG9fdXNlcih1c2VyLCAmdG1wLCAqbGVuKSAhPSAwKXsKCQkJQlVHUFJJTlQoImMydSBEaWRuJ3Qgd29ya1xuIik7CgkJCXJldCA9IC1FRkFVTFQ7CgkJCWJyZWFrOwoJCX0KCQlyZXQgPSAwOwoJCWJyZWFrOwoKCWNhc2UgRUJUX1NPX0dFVF9FTlRSSUVTOgoJY2FzZSBFQlRfU09fR0VUX0lOSVRfRU5UUklFUzoKCQlyZXQgPSBjb3B5X2V2ZXJ5dGhpbmdfdG9fdXNlcih0LCB1c2VyLCBsZW4sIGNtZCk7CgkJbXV0ZXhfdW5sb2NrKCZlYnRfbXV0ZXgpOwoJCWJyZWFrOwoKCWRlZmF1bHQ6CgkJbXV0ZXhfdW5sb2NrKCZlYnRfbXV0ZXgpOwoJCXJldCA9IC1FSU5WQUw7Cgl9CgoJcmV0dXJuIHJldDsKfQoKc3RhdGljIHN0cnVjdCBuZl9zb2Nrb3B0X29wcyBlYnRfc29ja29wdHMgPQp7CgkucGYJCT0gUEZfSU5FVCwKCS5zZXRfb3B0bWluCT0gRUJUX0JBU0VfQ1RMLAoJLnNldF9vcHRtYXgJPSBFQlRfU09fU0VUX01BWCArIDEsCgkuc2V0CQk9IGRvX2VidF9zZXRfY3RsLAoJLmdldF9vcHRtaW4JPSBFQlRfQkFTRV9DVEwsCgkuZ2V0X29wdG1heAk9IEVCVF9TT19HRVRfTUFYICsgMSwKCS5nZXQJCT0gZG9fZWJ0X2dldF9jdGwsCn07CgpzdGF0aWMgaW50IF9faW5pdCBlYnRhYmxlc19pbml0KHZvaWQpCnsKCWludCByZXQ7CgoJbXV0ZXhfbG9jaygmZWJ0X211dGV4KTsKCWxpc3RfYWRkKCZlYnRfc3RhbmRhcmRfdGFyZ2V0Lmxpc3QsICZlYnRfdGFyZ2V0cyk7CgltdXRleF91bmxvY2soJmVidF9tdXRleCk7CglpZiAoKHJldCA9IG5mX3JlZ2lzdGVyX3NvY2tvcHQoJmVidF9zb2Nrb3B0cykpIDwgMCkKCQlyZXR1cm4gcmV0OwoKCXByaW50ayhLRVJOX05PVElDRSAiRWJ0YWJsZXMgdjIuMCByZWdpc3RlcmVkXG4iKTsKCXJldHVybiAwOwp9CgpzdGF0aWMgdm9pZCBfX2V4aXQgZWJ0YWJsZXNfZmluaSh2b2lkKQp7CgluZl91bnJlZ2lzdGVyX3NvY2tvcHQoJmVidF9zb2Nrb3B0cyk7CglwcmludGsoS0VSTl9OT1RJQ0UgIkVidGFibGVzIHYyLjAgdW5yZWdpc3RlcmVkXG4iKTsKfQoKRVhQT1JUX1NZTUJPTChlYnRfcmVnaXN0ZXJfdGFibGUpOwpFWFBPUlRfU1lNQk9MKGVidF91bnJlZ2lzdGVyX3RhYmxlKTsKRVhQT1JUX1NZTUJPTChlYnRfcmVnaXN0ZXJfbWF0Y2gpOwpFWFBPUlRfU1lNQk9MKGVidF91bnJlZ2lzdGVyX21hdGNoKTsKRVhQT1JUX1NZTUJPTChlYnRfcmVnaXN0ZXJfd2F0Y2hlcik7CkVYUE9SVF9TWU1CT0woZWJ0X3VucmVnaXN0ZXJfd2F0Y2hlcik7CkVYUE9SVF9TWU1CT0woZWJ0X3JlZ2lzdGVyX3RhcmdldCk7CkVYUE9SVF9TWU1CT0woZWJ0X3VucmVnaXN0ZXJfdGFyZ2V0KTsKRVhQT1JUX1NZTUJPTChlYnRfZG9fdGFibGUpOwptb2R1bGVfaW5pdChlYnRhYmxlc19pbml0KTsKbW9kdWxlX2V4aXQoZWJ0YWJsZXNfZmluaSk7Ck1PRFVMRV9MSUNFTlNFKCJHUEwiKTsK