LyogCiAqIGFjY291bnRpbmcgbWF0Y2ggaGVscGVyIChsaWJpcHRfYWNjb3VudC5jKQogKiAoQykgMjAwMywyMDA0IGJ5IFBpb3RyIEdhc2lks28gKHF1YWtlckBiYXJiYXJhLmV1Lm9yZykKICoKICogVmVyc2lvbjogMC4xLjYKICoKICogVGhpcyBzb2Z0d2FyZSBpcyBkaXN0cmlidXRlZCB1bmRlciB0aGUgdGVybXMgb2YgR05VIEdQTAogKi8KCiNpbmNsdWRlIDxzdGRpby5oPgojaW5jbHVkZSA8c3RkbGliLmg+CiNpbmNsdWRlIDxpcHRhYmxlcy5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlIDxnZXRvcHQuaD4KCiNpbmNsdWRlIDxsaW51eC9uZXRmaWx0ZXJfaXB2NC9pcHRfYWNjb3VudC5oPgoKI2lmbmRlZiBISVBRVUFECiNkZWZpbmUgSElQUVVBRChhZGRyKSBcCgkoKHVuc2lnbmVkIGNoYXIgKikmYWRkcilbM10sIFwKCSgodW5zaWduZWQgY2hhciAqKSZhZGRyKVsyXSwgXAoJKCh1bnNpZ25lZCBjaGFyICopJmFkZHIpWzFdLCBcCgkoKHVuc2lnbmVkIGNoYXIgKikmYWRkcilbMF0KI2VuZGlmCgkJCQkKc3RhdGljIHZvaWQgaGVscCh2b2lkKSB7CglwcmludGYoCgkJCSJhY2NvdW50IHYlcyBvcHRpb25zOlxuIgoJCQkiLS1hYWRkciBuZXR3b3JrL25ldG1hc2tcbiIKCQkJIglkZWZpbmVzIG5ldHdvcmsvbmV0bWFzayBmb3Igd2hpY2ggbWFrZSBzdGF0aXN0aWNzLlxuIgoJCQkiLS1hbmFtZSBuYW1lXG4iCgkJCSIJZGVmaW5lcyBuYW1lIG9mIGxpc3Qgd2hlcmUgc3RhdGlzdGljcyB3aWxsIGJlIGtlcHQuIElmIG5vIGlzXG4iCgkJCSIJc3BlY2lmaWVkIERFRkFVTFQgd2lsbCBiZSB1c2VkLlxuIgoJCQkiLS1hc2hvcnRcbiIKCQkJIiAgICAgICB0YWJsZSB3aWxsIGNvbGVjdCBvbmx5IHNob3J0IHN0YXRpc3RpY3MgKG9ubHkgdG90YWwgY291bnRlcnNcbiIKCQkJIiAgICAgICB3aXRob3V0IHNwbGl0dGluZyBpdCBpbnRvIHByb3RvY29scy5cbiIKCSwgCglJUFRBQkxFU19WRVJTSU9OKTsKfTsKCnN0YXRpYyBzdHJ1Y3Qgb3B0aW9uIG9wdHNbXSA9IHsKCXsgLm5hbWUgPSAiYWFkZHIiLCAgLmhhc19hcmcgPSAxLCAuZmxhZyA9IE5VTEwsIC52YWwgPSAyMDEgfSwKCXsgLm5hbWUgPSAiYW5hbWUiLCAgLmhhc19hcmcgPSAxLCAuZmxhZyA9IE5VTEwsIC52YWwgPSAyMDIgfSwKCXsgLm5hbWUgPSAiYXNob3J0IiwgLmhhc19hcmcgPSAwLCAuZmxhZyA9IE5VTEwsIC52YWwgPSAyMDMgfSwKCXsgLm5hbWUgPSAwLCAuaGFzX2FyZyA9IDAsIC5mbGFnID0gMCwgLnZhbCA9IDAgfQp9OwoKLyogSGVscGVyIGZ1bmN0aW9ucyBmb3IgcGFyc2VfbmV0d29yayAqLwppbnQgcGFyc2VpcChjb25zdCBjaGFyICpwYXJhbWV0ZXIsIHVfaW50MzJfdCAqaXApIHsKCQoJY2hhciBidWZmZXJbMTZdLCAqYnVmZmVycHRyLCAqZG90OwoJdW5zaWduZWQgaW50IGksIHNoaWZ0LCBwYXJ0OwoKCWlmIChzdHJsZW4ocGFyYW1ldGVyKSA+IDE1KQoJCXJldHVybiAwOwoKCXN0cm5jcHkoYnVmZmVyLCBwYXJhbWV0ZXIsIDE1KTsKCWJ1ZmZlclsxNV0gPSAwOwoKCWJ1ZmZlcnB0ciA9IGJ1ZmZlcjsKCglmb3IgKGkgPSAwLCBzaGlmdCA9IDI0LCAqaXAgPSAwOyBpIDwgMzsgaSsrLCBzaGlmdCAtPSA4KSB7CgkJLyogbm8gZG90ICovCgkJaWYgKChkb3QgPSBzdHJjaHIoYnVmZmVycHRyLCAnLicpKSA9PSBOVUxMKQoJCQlyZXR1cm4gMDsKCQkvKiBub3QgYSBudW1iZXIgKi8KCQlpZiAoKHBhcnQgPSBzdHJ0b2woYnVmZmVycHRyLCAoY2hhcioqKU5VTEwsIDEwKSkgPCAwKSAKCQkJcmV0dXJuIDA7CQoJCS8qIHRvIGJpZyBudW1iZXIgKi8KCQlpZiAocGFydCA+IDI1NSkKCQkJcmV0dXJuIDA7CgkJKmlwIHw9IHBhcnQgPDwgc2hpZnQ7CQkKCQlidWZmZXJwdHIgPSBkb3QgKyAxOwoJfQoJLyogbm90IGEgbnVtYmVyICovCglpZiAoKHBhcnQgPSBzdHJ0b2woYnVmZmVycHRyLCAoY2hhcioqKU5VTEwsIDEwKSkgPCAwKSAKCQlyZXR1cm4gMDsKCS8qIHRvIGJpZyBudW1iZXIgKi8KCWlmIChwYXJ0ID4gMjU1KQoJCXJldHVybiAwOwoJKmlwIHw9IHBhcnQ7CglyZXR1cm4gMTsKfQoKc3RhdGljIHZvaWQgcGFyc2VuZXR3b3JrKGNvbnN0IGNoYXIgKnBhcmFtZXRlciwgdV9pbnQzMl90ICpuZXR3b3JrKSB7CglpZiAoIXBhcnNlaXAocGFyYW1ldGVyLCBuZXR3b3JrKSkKCQlleGl0X2Vycm9yKFBBUkFNRVRFUl9QUk9CTEVNLCAiYWNjb3VudDogd3JvbmcgaXAgaW4gbmV0d29yayIpOwp9CgpzdGF0aWMgdm9pZCBwYXJzZW5ldG1hc2thc2JpdHMoY29uc3QgY2hhciAqcGFyYW1ldGVyLCB1X2ludDMyX3QgKm5ldG1hc2spIHsKCQoJdV9pbnQzMl90IGJpdHM7CgkKCWlmICgoYml0cyA9IHN0cnRvbChwYXJhbWV0ZXIsIChjaGFyICoqKU5VTEwsIDEwKSkgPCAwIHx8IGJpdHMgPiAzMikKCQlleGl0X2Vycm9yKFBBUkFNRVRFUl9QUk9CTEVNLCAiYWNjb3VudDogd3JvbmcgbmV0bWFzayIpOwoKCSpuZXRtYXNrID0gMHhmZmZmZmZmZiA8PCAoMzIgLSBiaXRzKTsKfQoKc3RhdGljIHZvaWQgcGFyc2VuZXRtYXNrYXNpcChjb25zdCBjaGFyICpwYXJhbWV0ZXIsIHVfaW50MzJfdCAqbmV0bWFzaykgewoJaWYgKCFwYXJzZWlwKHBhcmFtZXRlciwgbmV0bWFzaykpCgkJZXhpdF9lcnJvcihQQVJBTUVURVJfUFJPQkxFTSwgImFjY291bnQ6IHdyb25nIGlwIGluIG5ldG1hc2siKTsKfQoKc3RhdGljIHZvaWQgcGFyc2VuZXRtYXNrKGNvbnN0IGNoYXIgKnBhcmFtZXRlciwgdV9pbnQzMl90ICpuZXRtYXNrKSAKewoJaWYgKHN0cmNocihwYXJhbWV0ZXIsICcuJykgIT0gTlVMTCkKCQlwYXJzZW5ldG1hc2thc2lwKHBhcmFtZXRlciwgbmV0bWFzayk7CgllbHNlCgkJcGFyc2VuZXRtYXNrYXNiaXRzKHBhcmFtZXRlciwgbmV0bWFzayk7Cn0KCnN0YXRpYyB2b2lkIHBhcnNlbmV0d29ya2FuZG5ldG1hc2soY29uc3QgY2hhciAqcGFyYW1ldGVyLCB1X2ludDMyX3QgKm5ldHdvcmssIHVfaW50MzJfdCAqbmV0bWFzaykgCnsKCQoJY2hhciBidWZmZXJbMzJdLCAqc2xhc2g7CgoJaWYgKHN0cmxlbihwYXJhbWV0ZXIpID4gMzEpCgkJLyogdGV4dCBpcyB0byBsb25nLCBldmVuIGZvciAyNTUuMjU1LjI1NS4yNTUvMjU1LjI1NS4yNTUuMjU1ICovCgkJZXhpdF9lcnJvcihQQVJBTUVURVJfUFJPQkxFTSwgImFjY291bnQ6IHdyb25nIG5ldHdvcmsvbmV0bWFzayIpOwoKCXN0cm5jcHkoYnVmZmVyLCBwYXJhbWV0ZXIsIDMxKTsKCWJ1ZmZlclszMV0gPSAwOwoKCS8qIGNoZWNrIHdoZXRoZXIgbmV0bWFzayBpcyBnaXZlbiAqLwoJaWYgKChzbGFzaCA9IHN0cmNocihidWZmZXIsICcvJykpICE9IE5VTEwpIHsKCQlwYXJzZW5ldG1hc2soc2xhc2ggKyAxLCBuZXRtYXNrKTsKCQkqc2xhc2ggPSAwOwoJfSBlbHNlCgkJKm5ldG1hc2sgPSAweGZmZmZmZmZmOwoJcGFyc2VuZXR3b3JrKGJ1ZmZlciwgbmV0d29yayk7CgoJaWYgKCgqbmV0d29yayAmICpuZXRtYXNrKSAhPSAqbmV0d29yaykKCQlleGl0X2Vycm9yKFBBUkFNRVRFUl9QUk9CTEVNLCAiYWNjb3VudDogd3JvbmcgbmV0d29yay9uZXRtYXNrIik7Cn0KCgovKiBGdW5jdGlvbiBnZXRzIG5ldHdvcmsgJiBuZXRtYXNrIGZyb20gYXJndW1lbnQgYWZ0ZXIgLS1hYWRkciAqLwpzdGF0aWMgdm9pZCBwYXJzZV9uZXR3b3JrKGNvbnN0IGNoYXIgKnBhcmFtZXRlciwgc3RydWN0IHRfaXB0X2FjY291bnRfaW5mbyAqaW5mbykgewoKCXBhcnNlbmV0d29ya2FuZG5ldG1hc2socGFyYW1ldGVyLCAmaW5mby0+bmV0d29yaywgJmluZm8tPm5ldG1hc2spOwoJCn0KCi8qIHZhbGlkYXRlIG5ldG1hc2sgKi8KaW5saW5lIGludCB2YWxpZF9uZXRtYXNrKHVfaW50MzJfdCBuZXRtYXNrKSB7Cgl3aGlsZSAobmV0bWFzayAmIDB4ODAwMDAwMDApCgkJbmV0bWFzayA8PD0gMTsKCWlmIChuZXRtYXNrICE9IDApCgkJcmV0dXJuIDA7CiAgICAgICAgcmV0dXJuIDE7Cn0KCi8qIHZhbGlkYXRlIG5ldHdvcmsvbmV0bWFzayBwYWlyICovCmlubGluZSBpbnQgdmFsaWRfbmV0d29ya19hbmRfbmV0bWFzayhzdHJ1Y3QgdF9pcHRfYWNjb3VudF9pbmZvICppbmZvKSB7CglpZiAoIXZhbGlkX25ldG1hc2soaW5mby0+bmV0bWFzaykpCgkJcmV0dXJuIDA7CglpZiAoKGluZm8tPm5ldHdvcmsgJiBpbmZvLT5uZXRtYXNrKSAhPSBpbmZvLT5uZXR3b3JrKQoJCXJldHVybiAwOwoJcmV0dXJuIDE7Cn0KCgoKLyogRnVuY3Rpb24gaW5pdGlhbGl6ZXMgbWF0Y2ggKi8Kc3RhdGljIHZvaWQgaW5pdChzdHJ1Y3QgaXB0X2VudHJ5X21hdGNoICptYXRjaCwgCgkJIHVuc2lnbmVkIGludCAqbmZjYWNoZSkgewoJCglzdHJ1Y3QgdF9pcHRfYWNjb3VudF9pbmZvICppbmZvID0gKHN0cnVjdCB0X2lwdF9hY2NvdW50X2luZm8gKikobWF0Y2gpLT5kYXRhOwoKCgkvKiBzZXQgZGVmYXVsdCB0YWJsZSBuYW1lIHRvIERFRkFVTFQgKi8KCXN0cm5jcHkoaW5mby0+bmFtZSwgIkRFRkFVTFQiLCBJUFRfQUNDT1VOVF9OQU1FX0xFTik7CglpbmZvLT5zaG9ydGxpc3RpbmcgPSAwOwoJCn0KCi8qIEZ1bmN0aW9uIHBhcnNlcyBtYXRjaCdzIGFyZ3VtZW50cyAqLwpzdGF0aWMgaW50IHBhcnNlKGludCBjLCBjaGFyICoqYXJndiwgCgkJICBpbnQgaW52ZXJ0LCAKCQkgIHVuc2lnbmVkIGludCAqZmxhZ3MsCiAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cnVjdCBpcHRfZW50cnkgKmVudHJ5LAogICAgICAgICAgICAgICAgICB1bnNpZ25lZCBpbnQgKm5mY2FjaGUsCiAgICAgICAgICAgICAgICAgIHN0cnVjdCBpcHRfZW50cnlfbWF0Y2ggKiptYXRjaCkgewoJCglzdHJ1Y3QgdF9pcHRfYWNjb3VudF9pbmZvICppbmZvID0gKHN0cnVjdCB0X2lwdF9hY2NvdW50X2luZm8gKikoKm1hdGNoKS0+ZGF0YTsKCglzd2l0Y2ggKGMpIHsKCQkKCQkvKiAtLWFhZGRyICovCgkJY2FzZSAyMDE6CgkJCXBhcnNlX25ldHdvcmsob3B0YXJnLCBpbmZvKTsKCQkJaWYgKCF2YWxpZF9uZXR3b3JrX2FuZF9uZXRtYXNrKGluZm8pKQoJCQkJZXhpdF9lcnJvcihQQVJBTUVURVJfUFJPQkxFTSwgImFjY291bnQ6IHdyb25nIG5ldHdvcmsvbmV0bWFzayIpOwoJCQkqZmxhZ3MgPSAxOwoJCQlicmVhazsKCQkJCgkJLyogLS1hbmFtZSAqLwoJCWNhc2UgMjAyOgoJCQlpZiAoc3RybGVuKG9wdGFyZykgPCBJUFRfQUNDT1VOVF9OQU1FX0xFTikKCQkJCXN0cm5jcHkoaW5mby0+bmFtZSwgb3B0YXJnLCBJUFRfQUNDT1VOVF9OQU1FX0xFTik7CgkJCWVsc2UKCQkJCWV4aXRfZXJyb3IoUEFSQU1FVEVSX1BST0JMRU0sICJhY2NvdW50OiBUb28gbG9uZyB0YWJsZSBuYW1lIik7CQkJCgkJCWJyZWFrOwkKCQkvKiAtLWFzaG9ydCAqLwoJCWNhc2UgMjAzOgoJCQlpbmZvLT5zaG9ydGxpc3RpbmcgPSAxOwoJCQlicmVhazsKCQlkZWZhdWx0OgoJCQlyZXR1cm4gMDsJCQkKCX0KCXJldHVybiAxOwkKfQoKLyogRmluYWwgY2hlY2sgd2hldGhlciBuZXR3b3JrL25ldG1hc2sgd2FzIHNwZWNpZmllZCAqLwpzdGF0aWMgdm9pZCBmaW5hbF9jaGVjayh1bnNpZ25lZCBpbnQgZmxhZ3MpIHsKCWlmICghZmxhZ3MpCgkJZXhpdF9lcnJvcihQQVJBTUVURVJfUFJPQkxFTSwgImFjY291bnQ6IFlvdSBuZWVkIHNwZWNpZnkgJy0tYWFkZHInIHBhcmFtZXRlciIpOwp9CgovKiBGdW5jdGlvbiB1c2VkIGZvciBwcmludGluZyBydWxlIHdpdGggYWNjb3VudCBtYXRjaCBmb3IgaXB0YWJsZXMgLUwgKi8Kc3RhdGljIHZvaWQgcHJpbnQoY29uc3Qgc3RydWN0IGlwdF9pcCAqaXAsCiAgICAgICAgICAgICAgICAgIGNvbnN0IHN0cnVjdCBpcHRfZW50cnlfbWF0Y2ggKm1hdGNoLCAKCQkgIGludCBudW1lcmljKSB7CgkKCXN0cnVjdCB0X2lwdF9hY2NvdW50X2luZm8gKmluZm8gPSAoc3RydWN0IHRfaXB0X2FjY291bnRfaW5mbyAqKW1hdGNoLT5kYXRhOwoJCglwcmludGYoImFjY291bnQ6ICIpOwoJcHJpbnRmKCJuZXR3b3JrL25ldG1hc2s6ICIpOwoJcHJpbnRmKCIldS4ldS4ldS4ldS8ldS4ldS4ldS4ldSAiLAoJCQlISVBRVUFEKGluZm8tPm5ldHdvcmspLAoJCQlISVBRVUFEKGluZm8tPm5ldG1hc2spCgkgICAgICApOwoJCglwcmludGYoIm5hbWU6ICVzICIsIGluZm8tPm5hbWUpOwoJaWYgKGluZm8tPnNob3J0bGlzdGluZykKCQlwcmludGYoInNob3J0LWxpc3RpbmcgIik7Cn0KCi8qIEZ1bmN0aW9uIHVzZWQgZm9yIHNhdmluZyBydWxlIGNvbnRhaW5pbmcgYWNjb3VudCBtYXRjaCAqLwpzdGF0aWMgdm9pZCBzYXZlKGNvbnN0IHN0cnVjdCBpcHRfaXAgKmlwLCAKCQkgY29uc3Qgc3RydWN0IGlwdF9lbnRyeV9tYXRjaCAqbWF0Y2gpIHsKCglzdHJ1Y3QgdF9pcHRfYWNjb3VudF9pbmZvICppbmZvID0gKHN0cnVjdCB0X2lwdF9hY2NvdW50X2luZm8gKiltYXRjaC0+ZGF0YTsKCQoJcHJpbnRmKCItLWFhZGRyICIpOwoJcHJpbnRmKCIldS4ldS4ldS4ldS8ldS4ldS4ldS4ldSAiLAoJCQkgSElQUVVBRChpbmZvLT5uZXR3b3JrKSwKCQkJIEhJUFFVQUQoaW5mby0+bmV0bWFzaykKCSAgICAgICApOwoJCglwcmludGYoIi0tYW5hbWUgJXMgIiwgaW5mby0+bmFtZSk7CglpZiAoaW5mby0+c2hvcnRsaXN0aW5nKQoJCXByaW50ZigiLS1hc2hvcnQgIik7Cn0KCQpzdGF0aWMgc3RydWN0IGlwdGFibGVzX21hdGNoIGFjY291bnQgPSB7CgkubmV4dCA9IE5VTEwsCgkubmFtZSA9ICJhY2NvdW50IiwKCS52ZXJzaW9uID0gSVBUQUJMRVNfVkVSU0lPTiwKCS5zaXplID0gSVBUX0FMSUdOKHNpemVvZihzdHJ1Y3QgdF9pcHRfYWNjb3VudF9pbmZvKSksCgkudXNlcnNwYWNlc2l6ZSA9IElQVF9BTElHTihzaXplb2Yoc3RydWN0IHRfaXB0X2FjY291bnRfaW5mbykpLAoJLmhlbHAgPSAmaGVscCwKCS5pbml0ID0gJmluaXQsCgkucGFyc2UgPSAmcGFyc2UsCgkuZmluYWxfY2hlY2sgPSAmZmluYWxfY2hlY2ssCgkucHJpbnQgPSAmcHJpbnQsCgkuc2F2ZSA9ICZzYXZlLAoJLmV4dHJhX29wdHMgPSBvcHRzCn07CgovKiBGdW5jdGlvbiB3aGljaCByZWdpc3RlcnMgbWF0Y2ggKi8Kdm9pZCBfaW5pdCh2b2lkKQp7CglyZWdpc3Rlcl9tYXRjaCgmYWNjb3VudCk7Cn0KCQo=