LyoKICogZnNjay5taW5peC5jIC0gYSBmaWxlIHN5c3RlbSBjb25zaXN0ZW5jeSBjaGVja2VyIGZvciBMaW51eC4KICoKICogKEMpIDE5OTEsIDE5OTIgTGludXMgVG9ydmFsZHMuIFRoaXMgZmlsZSBtYXkgYmUgcmVkaXN0cmlidXRlZAogKiBhcyBwZXIgdGhlIEdOVSBjb3B5bGVmdC4KICovCgovKgogKiAwOS4xMS45MSAgLSAgbWFkZSB0aGUgZmlyc3QgcnVkaW1ldGFyeSBmdW5jdGlvbnMKICoKICogMTAuMTEuOTEgIC0gIHVwZGF0ZWQsIGRvZXMgY2hlY2tpbmcsIG5vIHJlcGFpcnMgeWV0LgogKgkJU2VudCBvdXQgdG8gdGhlIG1haWxpbmctbGlzdCBmb3IgdGVzdGluZy4KICoKICogMTQuMTEuOTEgIC0JVGVzdGluZyBzZWVtcyB0byBoYXZlIGdvbmUgd2VsbC4gQWRkZWQgc29tZQogKgkJY29ycmVjdGlvbi1jb2RlLCBhbmQgY2hhbmdlZCBzb21lIGZ1bmN0aW9ucy4KICoKICogMTUuMTEuOTEgIC0gIE1vcmUgY29ycmVjdGlvbiBjb2RlLiBIb3BlZnVsbHkgaXQgbm90aWNlcyBtb3N0CiAqCQljYXNlcyBub3csIGFuZCB0cmllcyB0byBkbyBzb21ldGhpbmcgYWJvdXQgdGhlbS4KICoKICogMTYuMTEuOTEgIC0gIE1vcmUgY29ycmVjdGlvbnMgKHRoYW5rcyB0byBNaWthIEphbGF2YSkuIE1vc3QKICoJCXRoaW5ncyBzZWVtIHRvIHdvcmsgbm93LiBZZWFoLCBzdXJlLgogKgogKgogKiAxOS4wNC45MiAgLQlIYWQgdG8gc3RhcnQgb3ZlciBhZ2FpbiBmcm9tIHRoaXMgb2xkIHZlcnNpb24sIGFzIGEKICoJCWtlcm5lbCBidWcgYXRlIG15IGVuaGFuY2VkIGZzY2sgaW4gZmVicnVhcnkuCiAqCiAqIDI4LjAyLjkzICAtCWFkZGVkIHN1cHBvcnQgZm9yIGRpZmZlcmVudCBkaXJlY3RvcnkgZW50cnkgc2l6ZXMuLgogKgogKiBTYXQgTWFyICA2IDE4OjU5OjQyIDE5OTMsIGZhaXRoQGNzLnVuYy5lZHU6IE91dHB1dCBuYW1lbGVuIHdpdGgKICogICAgICAgICAgICAgICAgICAgICAgICAgICBzdXBlci1ibG9jayBpbmZvcm1hdGlvbgogKgogKiBTYXQgT2N0ICA5IDExOjE3OjExIDE5OTMsIGZhaXRoQGNzLnVuYy5lZHU6IG1ha2UgZXhpdCBzdGF0dXMgY29uZm9ybQogKiAgICAgICAgICAgICAgICAgICAgICAgICAgIHRvIHRoYXQgcmVxdWlyZWQgYnkgZnN1dGlsCiAqCiAqIE1vbiBKYW4gIDMgMTE6MDY6NTIgMTk5NCAtIERyLiBXZXR0c3RlaW4gKGdyZWcld2luZC51dWNwQHBsYWlucy5ub2Rhay5lZHUpCiAqCQkJICAgICAgQWRkZWQgc3VwcG9ydCBmb3IgZmlsZSBzeXN0ZW0gdmFsaWQgZmxhZy4gIEFsc28KICoJCQkgICAgICBhZGRlZCBwcm9ncmFtX3ZlcnNpb24gdmFyaWFibGUgYW5kIG91dHB1dCBvZgogKgkJCSAgICAgIHByb2dyYW0gbmFtZSBhbmQgdmVyc2lvbiBudW1iZXIgd2hlbiBwcm9ncmFtCiAqCQkJICAgICAgaXMgZXhlY3V0ZWQuCiAqCiAqIDMwLjEwLjk0IC0gYWRkZWQgc3VwcG9ydCBmb3IgdjIgZmlsZXN5c3RlbQogKiAgICAgICAgICAgIChBbmRyZWFzIFNjaHdhYiwgc2Nod2FiQGlzc2FuLmluZm9ybWF0aWsudW5pLWRvcnRtdW5kLmRlKQogKgogKiAxMC4xMi45NCAgLSAgYWRkZWQgdGVzdCB0byBwcmV2ZW50IGNoZWNraW5nIG9mIG1vdW50ZWQgZnMgYWRhcHRlZAogKiAgICAgICAgICAgICAgZnJvbSBUaGVvZG9yZSBUcydvJ3MgKHR5dHNvQGF0aGVuYS5taXQuZWR1KSBlMmZzY2sKICogICAgICAgICAgICAgIHByb2dyYW0uICAoRGFuaWVsIFF1aW5sYW4sIHF1aW5sYW5AeWdnZHJhc2lsLmNvbSkKICoKICogMDEuMDcuOTYgIC0gRml4ZWQgdGhlIHYyIGZzIHN0dWZmIHRvIHVzZSB0aGUgcmlnaHQgI2RlZmluZXMgYW5kIHN1Y2gKICoJICAgICAgIGZvciBtb2Rlcm4gbGliY3MgKGphbmxAbWF0aC51aW8ubm8sIE5pY29sYWkgTGFuZ2ZlbGR0KQogKgogKiAwMi4wNy45NiAgLSBBZGRlZCBDIGJpdCBmaWRkbGluZyByb3V0aW5lcyBmcm9tIHJta0BlY3Muc290b24uYWMudWsgCiAqICAgICAgICAgICAgIChSdXNzZWxsIEtpbmcpLiAgSGUgbWFkZSB0aGVtIGZvciBBUk0uICBJdCB3b3VsZCBzZWVtCiAqCSAgICAgICB0aGF0IHRoZSBBUk0gaXMgcG93ZXJmdWwgZW5vdWdoIHRvIGRvIHRoaXMgaW4gQyB3aGVyZWFzCiAqICAgICAgICAgICAgIGkzODYgYW5kIG02NGsgbXVzdCB1c2UgYXNzZW1ibHkgdG8gZ2V0IGl0IGZhc3QgPjotKQogKgkgICAgICAgVGhpcyBzaG91bGQgbWFrZSBtaW5peCBmc2NrIHN5c3RlbWluZGVwZW5kZW50LgogKgkgICAgICAgKGphbmxAbWF0aC51aW8ubm8sIE5pY29sYWkgTGFuZ2ZlbGR0KQogKgogKiAwNC4xMS45NiAgLSBBZGRlZCBtaW5vciBmaXhlcyBmcm9tIEFuZHJlYXMgU2Nod2FiIHRvIGF2b2lkIGNvbXBpbGVyCiAqICAgICAgICAgICAgIHdhcm5pbmdzLiAgQWRkZWQgbWM2OGsgYml0b3BzIGZyb20gCiAqCSAgICAgICBKb2VyZyBEb3JjaGFpbiA8ZG9yY2hhaW5AbXBpLXNiLm1wZy5kZT4uCiAqCiAqIDA2LjExLjk2ICAtIEFkZGVkIHYyIGNvZGUgc3VibWl0dGVkIGJ5IEpvZXJnIERvcmNoYWluLCBidXQgd3JpdHRlbiBieQogKiAgICAgICAgICAgICBBbmRyZWFzIFNjaHdhYi4KICoKICogMTk5OS0wMi0yMiBBcmthZGl1c3ogTWm2a2lld2ljeiA8bWlzaWVrQHBsZC5PUkcuUEw+CiAqIC0gYWRkZWQgTmF0aXZlIExhbmd1YWdlIFN1cHBvcnQKICoKICogMjAwOC0wNC0wNiBKYW1lcyBZb3VuZ21hbiA8amF5QGdudS5vcmc+CiAqIC0gSXNzdWUgYmV0dGVyIGVycm9yIG1lc3NhZ2UgaWYgd2UgZmFpbCB0byBvcGVuIHRoZSBkZXZpY2UuCiAqIC0gUmVzdG9yZSB0ZXJtaW5hbCBzdGF0ZSBpZiB3ZSBnZXQgYSBmYXRhbCBzaWduYWwuCiAqCiAqCiAqIEkndmUgaGFkIG5vIHRpbWUgdG8gYWRkIGNvbW1lbnRzIC0gaG9wZWZ1bGx5IHRoZSBmdW5jdGlvbiBuYW1lcwogKiBhcmUgY29tbWVudHMgZW5vdWdoLiBBcyB3aXRoIGFsbCBmaWxlIHN5c3RlbSBjaGVja2VycywgdGhpcyBhc3N1bWVzCiAqIHRoZSBmaWxlIHN5c3RlbSBpcyBxdWllc2NlbnQgLSBkb24ndCB1c2UgaXQgb24gYSBtb3VudGVkIGRldmljZQogKiB1bmxlc3MgeW91IGNhbiBiZSBzdXJlIG5vYm9keSBpcyB3cml0aW5nIHRvIGl0IChhbmQgcmVtZW1iZXIgdGhhdCB0aGUKICoga2VybmVsIGNhbiB3cml0ZSB0byBpdCB3aGVuIGl0IHNlYXJjaGVzIGZvciBmaWxlcykuCiAqCiAqIFVzdWFnZTogZnNjayBbLWxhcnZzbV0gZGV2aWNlCiAqCS1sIGZvciBhIGxpc3Rpbmcgb2YgYWxsIHRoZSBmaWxlbmFtZXMKICoJLWEgZm9yIGF1dG9tYXRpYyByZXBhaXJzIChub3QgaW1wbGVtZW50ZWQpCiAqCS1yIGZvciByZXBhaXJzIChpbnRlcmFjdGl2ZSkgKG5vdCBpbXBsZW1lbnRlZCkKICoJLXYgZm9yIHZlcmJvc2UgKHRlbGxzIGhvdyBtYW55IGZpbGVzKQogKgktcyBmb3Igc3VwZXItYmxvY2sgaW5mbwogKgktbSBmb3IgbWluaXgtbGlrZSAibW9kZSBub3QgY2xlYXJlZCIgd2FybmluZ3MKICoJLWYgZm9yY2UgZmlsZXN5c3RlbSBjaGVjayBldmVuIGlmIGZpbGVzeXN0ZW0gbWFya2VkIGFzIHZhbGlkCiAqCiAqIFRoZSBkZXZpY2UgbWF5IGJlIGEgYmxvY2sgZGV2aWNlIG9yIGEgaW1hZ2Ugb2Ygb25lLCBidXQgdGhpcyBpc24ndAogKiBlbmZvcmNlZCAoYnV0IGl0J3Mgbm90IG11Y2ggZnVuIG9uIGEgY2hhcmFjdGVyIGRldmljZSA6LSkuIAogKi8KCiNpbmNsdWRlIDxzdGRpby5oPgojaW5jbHVkZSA8c3RkYXJnLmg+CiNpbmNsdWRlIDxlcnJuby5oPgojaW5jbHVkZSA8dW5pc3RkLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUgPGZjbnRsLmg+CiNpbmNsdWRlIDxjdHlwZS5oPgojaW5jbHVkZSA8c3RkbGliLmg+CiNpbmNsdWRlIDx0ZXJtaW9zLmg+CiNpbmNsdWRlIDxtbnRlbnQuaD4KI2luY2x1ZGUgPHN5cy9zdGF0Lmg+CiNpbmNsdWRlIDxzaWduYWwuaD4KCiNpbmNsdWRlICJtaW5peC5oIgojaW5jbHVkZSAibmxzLmgiCiNpbmNsdWRlICJwYXRobmFtZXMuaCIKI2luY2x1ZGUgImJpdG9wcy5oIgoKI2RlZmluZSBST09UX0lOTyAxCgojZGVmaW5lIFVQUEVSKHNpemUsbikgKChzaXplKygobiktMSkpLyhuKSkKI2RlZmluZSBJTk9ERV9TSVpFIChzaXplb2Yoc3RydWN0IG1pbml4X2lub2RlKSkKI2RlZmluZSBJTk9ERV9TSVpFMiAoc2l6ZW9mKHN0cnVjdCBtaW5peDJfaW5vZGUpKQojZGVmaW5lIElOT0RFX0JMT0NLUyBVUFBFUihJTk9ERVMsICh2ZXJzaW9uMiA/IE1JTklYMl9JTk9ERVNfUEVSX0JMT0NLIFwKCQkJCSAgICA6IE1JTklYX0lOT0RFU19QRVJfQkxPQ0spKQojZGVmaW5lIElOT0RFX0JVRkZFUl9TSVpFIChJTk9ERV9CTE9DS1MgKiBCTE9DS19TSVpFKQoKI2RlZmluZSBCSVRTX1BFUl9CTE9DSyAoQkxPQ0tfU0laRTw8MykKCnN0YXRpYyBjaGFyICogcHJvZ3JhbV9uYW1lID0gImZzY2subWluaXgiOwpzdGF0aWMgY2hhciAqIGRldmljZV9uYW1lID0gTlVMTDsKc3RhdGljIGludCBJTjsKc3RhdGljIGludCByZXBhaXI9MCwgYXV0b21hdGljPTAsIHZlcmJvc2U9MCwgbGlzdD0wLCBzaG93PTAsIHdhcm5fbW9kZT0wLCAKCWZvcmNlPTA7CnN0YXRpYyBpbnQgZGlyZWN0b3J5PTAsIHJlZ3VsYXI9MCwgYmxvY2tkZXY9MCwgY2hhcmRldj0wLCBsaW5rcz0wLAoJCXN5bWxpbmtzPTAsIHRvdGFsPTA7CgpzdGF0aWMgaW50IGNoYW5nZWQgPSAwOyAvKiBmbGFncyBpZiB0aGUgZmlsZXN5c3RlbSBoYXMgYmVlbiBjaGFuZ2VkICovCnN0YXRpYyBpbnQgZXJyb3JzX3VuY29ycmVjdGVkID0gMDsgLyogZmxhZyBpZiBzb21lIGVycm9yIHdhcyBub3QgY29ycmVjdGVkICovCnN0YXRpYyBpbnQgZGlyc2l6ZSA9IDE2OwpzdGF0aWMgaW50IG5hbWVsZW4gPSAxNDsKc3RhdGljIGludCB2ZXJzaW9uMiA9IDA7CnN0YXRpYyBzdHJ1Y3QgdGVybWlvcyB0ZXJtaW9zOwpzdGF0aWMgdm9sYXRpbGUgc2lnX2F0b21pY190IHRlcm1pb3Nfc2V0ID0gMDsKCi8qIEZpbGUtbmFtZSBkYXRhICovCiNkZWZpbmUgTUFYX0RFUFRIIDUwCnN0YXRpYyBpbnQgbmFtZV9kZXB0aCA9IDA7CnN0YXRpYyBjaGFyIG5hbWVfbGlzdFtNQVhfREVQVEhdW05BTUVfTUFYKzFdOwovKiBDb3B5IG9mIHRoZSBwcmV2aW91cywganVzdCBmb3IgZXJyb3IgcmVwb3J0aW5nIC0gc2VlIGdldF9jdXJyZW50X25hbWUgKi8KLyogVGhpcyBpcyBhIHdhc3RlIG9mIDEya0Igb3Igc28uICovCnN0YXRpYyBjaGFyIGN1cnJlbnRfbmFtZVtNQVhfREVQVEgqKE5BTUVfTUFYKzEpKzFdOwoKc3RhdGljIGNoYXIgKiBpbm9kZV9idWZmZXIgPSBOVUxMOwojZGVmaW5lIElub2RlICgoKHN0cnVjdCBtaW5peF9pbm9kZSAqKSBpbm9kZV9idWZmZXIpLTEpCiNkZWZpbmUgSW5vZGUyICgoKHN0cnVjdCBtaW5peDJfaW5vZGUgKikgaW5vZGVfYnVmZmVyKS0xKQoKc3RhdGljIGNoYXIgKnN1cGVyX2Jsb2NrX2J1ZmZlcjsKI2RlZmluZSBTdXBlciAoKihzdHJ1Y3QgbWluaXhfc3VwZXJfYmxvY2sgKilzdXBlcl9ibG9ja19idWZmZXIpCiNkZWZpbmUgSU5PREVTICgodW5zaWduZWQgbG9uZylTdXBlci5zX25pbm9kZXMpCiNkZWZpbmUgWk9ORVMgKCh1bnNpZ25lZCBsb25nKSh2ZXJzaW9uMiA/IFN1cGVyLnNfem9uZXMgOiBTdXBlci5zX256b25lcykpCiNkZWZpbmUgSU1BUFMgKCh1bnNpZ25lZCBsb25nKVN1cGVyLnNfaW1hcF9ibG9ja3MpCiNkZWZpbmUgWk1BUFMgKCh1bnNpZ25lZCBsb25nKVN1cGVyLnNfem1hcF9ibG9ja3MpCiNkZWZpbmUgRklSU1RaT05FICgodW5zaWduZWQgbG9uZylTdXBlci5zX2ZpcnN0ZGF0YXpvbmUpCiNkZWZpbmUgWk9ORVNJWkUgKCh1bnNpZ25lZCBsb25nKVN1cGVyLnNfbG9nX3pvbmVfc2l6ZSkKI2RlZmluZSBNQVhTSVpFICgodW5zaWduZWQgbG9uZylTdXBlci5zX21heF9zaXplKQojZGVmaW5lIE1BR0lDIChTdXBlci5zX21hZ2ljKQojZGVmaW5lIE5PUk1fRklSU1RaT05FICgyK0lNQVBTK1pNQVBTK0lOT0RFX0JMT0NLUykKCnN0YXRpYyBjaGFyICppbm9kZV9tYXA7CnN0YXRpYyBjaGFyICp6b25lX21hcDsKCnN0YXRpYyB1bnNpZ25lZCBjaGFyICogaW5vZGVfY291bnQgPSBOVUxMOwpzdGF0aWMgdW5zaWduZWQgY2hhciAqIHpvbmVfY291bnQgPSBOVUxMOwoKc3RhdGljIHZvaWQgcmVjdXJzaXZlX2NoZWNrKHVuc2lnbmVkIGludCBpbm8pOwpzdGF0aWMgdm9pZCByZWN1cnNpdmVfY2hlY2syKHVuc2lnbmVkIGludCBpbm8pOwoKI2RlZmluZSBpbm9kZV9pbl91c2UoeCkgKGlzc2V0KGlub2RlX21hcCwoeCkpICE9IDApCiNkZWZpbmUgem9uZV9pbl91c2UoeCkgKGlzc2V0KHpvbmVfbWFwLCh4KS1GSVJTVFpPTkUrMSkgIT0gMCkKCiNkZWZpbmUgbWFya19pbm9kZSh4KSAoc2V0Yml0KGlub2RlX21hcCwoeCkpLGNoYW5nZWQ9MSkKI2RlZmluZSB1bm1hcmtfaW5vZGUoeCkgKGNscmJpdChpbm9kZV9tYXAsKHgpKSxjaGFuZ2VkPTEpCgojZGVmaW5lIG1hcmtfem9uZSh4KSAoc2V0Yml0KHpvbmVfbWFwLCh4KS1GSVJTVFpPTkUrMSksY2hhbmdlZD0xKQojZGVmaW5lIHVubWFya196b25lKHgpIChjbHJiaXQoem9uZV9tYXAsKHgpLUZJUlNUWk9ORSsxKSxjaGFuZ2VkPTEpCgpzdGF0aWMgdm9pZApyZXNldCh2b2lkKSB7CglpZiAodGVybWlvc19zZXQpCgkJdGNzZXRhdHRyKDAsIFRDU0FOT1csICZ0ZXJtaW9zKTsKfQoKCnN0YXRpYyB2b2lkCmZhdGFsc2lnKGludCBzaWcpIHsKCS8qIFdlIHJlY2VpdmVkIGEgZmF0YWwgc2lnbmFsLiAgUmVzZXQgdGhlIHRlcm1pbmFsLgoJICogQWxzbyByZXNldCB0aGUgc2lnbmFsIGhhbmRsZXIgYW5kIHJlLXNlbmQgdGhlIHNpZ25hbCwKCSAqIHNvIHRoYXQgdGhlIHBhcmVudCBwcm9jZXNzIGtub3dzIHdoaWNoIHNpZ25hbCBhY3R1YWxseQoJICogY2F1c2VkIG91ciBkZWF0aC4KCSAqLwoJc2lnbmFsKHNpZywgU0lHX0RGTCk7CglyZXNldCgpOwoJcmFpc2Uoc2lnKTsKfQoKc3RhdGljIHZvaWQKbGVhdmUoaW50IHN0YXR1cykgewogICAgICAgIHJlc2V0KCk7CglleGl0KHN0YXR1cyk7Cn0KCnN0YXRpYyB2b2lkCnVzYWdlKHZvaWQpIHsKCWZwcmludGYoc3RkZXJyLAoJCV8oIlVzYWdlOiAlcyBbLWxhcnZzbWZdIC9kZXYvbmFtZVxuIiksCgkJcHJvZ3JhbV9uYW1lKTsKCWxlYXZlKDE2KTsKfQoKc3RhdGljIHZvaWQgZGllKGNvbnN0IGNoYXIgKmZtdCwgLi4uKQoJX19hdHRyaWJ1dGVfXyAoKF9fZm9ybWF0X18gKF9fcHJpbnRmX18sIDEsIDIpKSk7CgpzdGF0aWMgdm9pZApkaWUoY29uc3QgY2hhciAqZm10LCAuLi4pIHsKCXZhX2xpc3QgYXA7CgoJZnByaW50ZihzdGRlcnIsICIlczogIiwgcHJvZ3JhbV9uYW1lKTsKCXZhX3N0YXJ0KGFwLCBmbXQpOwoJdmZwcmludGYoc3RkZXJyLCBmbXQsIGFwKTsKCXZhX2VuZCAoYXApOwoJZnB1dGMoJ1xuJywgc3RkZXJyKTsKCWxlYXZlKDgpOwp9CgovKgogKiBUaGlzIHNpbXBseSBnb2VzIHRocm91Z2ggdGhlIGZpbGUtbmFtZSBkYXRhIGFuZCBwcmludHMgb3V0IHRoZQogKiBjdXJyZW50IGZpbGUuCiAqLwpzdGF0aWMgdm9pZApnZXRfY3VycmVudF9uYW1lKHZvaWQpIHsKCWludCBpID0gMCwgY3Q7CgljaGFyICpwLCAqcTsKCglxID0gY3VycmVudF9uYW1lOwoJd2hpbGUgKGkgPCBuYW1lX2RlcHRoKSB7CgkJcCA9IG5hbWVfbGlzdFtpKytdOwoJCWN0ID0gbmFtZWxlbjsKCQkqcSsrID0gJy8nOwoJCXdoaWxlIChjdC0tICYmICpwKQoJCQkqcSsrID0gKnArKzsKCX0KCWlmIChpID09IDApCgkJKnErKyA9ICcvJzsKCSpxID0gMDsKfQoKc3RhdGljIGludAphc2soY29uc3QgY2hhciAqIHN0cmluZywgaW50IGRlZikgewoJaW50IGM7CgoJaWYgKCFyZXBhaXIpIHsKCQlwcmludGYoIlxuIik7CgkJZXJyb3JzX3VuY29ycmVjdGVkID0gMTsKCQlyZXR1cm4gMDsKCX0KCWlmIChhdXRvbWF0aWMpIHsKCQlwcmludGYoIlxuIik7CgkJaWYgKCFkZWYpCgkJICAgICAgZXJyb3JzX3VuY29ycmVjdGVkID0gMTsKCQlyZXR1cm4gZGVmOwoJfQoJcHJpbnRmKGRlZj8iJXMgKHkvbik/ICI6IiVzIChuL3kpPyAiLHN0cmluZyk7Cglmb3IgKDs7KSB7CgkJZmZsdXNoKHN0ZG91dCk7CgkJaWYgKChjPWdldGNoYXIoKSk9PUVPRikgewoJCSAgICAgICAgaWYgKCFkZWYpCgkJCSAgICAgIGVycm9yc191bmNvcnJlY3RlZCA9IDE7CgkJCXJldHVybiBkZWY7CgkJfQoJCWM9dG91cHBlcihjKTsKCQlpZiAoYyA9PSAnWScpIHsKCQkJZGVmID0gMTsKCQkJYnJlYWs7CgkJfSBlbHNlIGlmIChjID09ICdOJykgewoJCQlkZWYgPSAwOwoJCQlicmVhazsKCQl9IGVsc2UgaWYgKGMgPT0gJyAnIHx8IGMgPT0gJ1xuJykKCQkJYnJlYWs7Cgl9CglpZiAoZGVmKQoJCXByaW50ZigieVxuIik7CgllbHNlIHsKCQlwcmludGYoIm5cbiIpOwoJCWVycm9yc191bmNvcnJlY3RlZCA9IDE7CgkgICAgIH0KCXJldHVybiBkZWY7Cn0KCi8qCiAqIE1ha2UgY2VydGFpbiB0aGF0IHdlIGFyZW4ndCBjaGVja2luZyBhIGZpbGVzeXN0ZW0gdGhhdCBpcyBvbiBhCiAqIG1vdW50ZWQgcGFydGl0aW9uLiAgQ29kZSBhZGFwdGVkIGZyb20gZTJmc2NrLCBDb3B5cmlnaHQgKEMpIDE5OTMsCiAqIDE5OTQgVGhlb2RvcmUgVHMnby4gIEFsc28gbGljZW5zZWQgdW5kZXIgR1BMLgogKi8Kc3RhdGljIHZvaWQKY2hlY2tfbW91bnQodm9pZCkgewoJRklMRSAqIGY7CglzdHJ1Y3QgbW50ZW50ICogbW50OwoJaW50IGNvbnQ7CglpbnQgZmQ7CgoJaWYgKChmID0gc2V0bW50ZW50IChfUEFUSF9NT1VOVEVELCAiciIpKSA9PSBOVUxMKQoJCXJldHVybjsKCXdoaWxlICgobW50ID0gZ2V0bW50ZW50IChmKSkgIT0gTlVMTCkKCQlpZiAoc3RyY21wIChkZXZpY2VfbmFtZSwgbW50LT5tbnRfZnNuYW1lKSA9PSAwKQoJCQlicmVhazsKCWVuZG1udGVudCAoZik7CglpZiAoIW1udCkKCQlyZXR1cm47CgoJLyoKCSAqIElmIHRoZSByb290IGlzIG1vdW50ZWQgcmVhZC1vbmx5LCB0aGVuIC9ldGMvbXRhYiBpcwoJICogcHJvYmFibHkgbm90IGNvcnJlY3Q7IHNvIHdlIHdvbid0IGlzc3VlIGEgd2FybmluZyBiYXNlZCBvbgoJICogaXQuCgkgKi8KCWZkID0gb3BlbihfUEFUSF9NT1VOVEVELCBPX1JEV1IpOwoJaWYgKGZkIDwgMCAmJiBlcnJubyA9PSBFUk9GUykKCQlyZXR1cm47CgllbHNlCgkJY2xvc2UoZmQpOwoJCglwcmludGYgKF8oIiVzIGlzIG1vdW50ZWQuCSAiKSwgZGV2aWNlX25hbWUpOwoJaWYgKGlzYXR0eSgwKSAmJiBpc2F0dHkoMSkpCgkJY29udCA9IGFzayhfKCJEbyB5b3UgcmVhbGx5IHdhbnQgdG8gY29udGludWUiKSwgMCk7CgllbHNlCgkJY29udCA9IDA7CglpZiAoIWNvbnQpIHsKCQlwcmludGYgKF8oImNoZWNrIGFib3J0ZWQuXG4iKSk7CgkJZXhpdCAoMCk7Cgl9CglyZXR1cm47Cn0KCi8qCiAqIGNoZWNrX3pvbmVfbnIgY2hlY2tzIHRvIHNlZSB0aGF0ICpuciBpcyBhIHZhbGlkIHpvbmUgbnIuIElmIGl0CiAqIGlzbid0LCBpdCB3aWxsIHBvc3NpYmx5IGJlIHJlcGFpcmVkLiBDaGVja196b25lX25yIHNldHMgKmNvcnJlY3RlZAogKiBpZiBhbiBlcnJvciB3YXMgY29ycmVjdGVkLCBhbmQgcmV0dXJucyB0aGUgem9uZSAoMCBmb3Igbm8gem9uZQogKiBvciBhIGJhZCB6b25lLW51bWJlcikuCiAqLwpzdGF0aWMgaW50CmNoZWNrX3pvbmVfbnIodW5zaWduZWQgc2hvcnQgKiBuciwgaW50ICogY29ycmVjdGVkKSB7CglpZiAoISpucikKCQlyZXR1cm4gMDsKCglpZiAoKm5yIDwgRklSU1RaT05FKSB7CgkJZ2V0X2N1cnJlbnRfbmFtZSgpOwoJCXByaW50ZihfKCJab25lIG5yIDwgRklSU1RaT05FIGluIGZpbGUgYCVzJy4iKSwKCQkgICAgICAgY3VycmVudF9uYW1lKTsKCX0gZWxzZSBpZiAoKm5yID49IFpPTkVTKSB7CgkJZ2V0X2N1cnJlbnRfbmFtZSgpOwoJCXByaW50ZihfKCJab25lIG5yID49IFpPTkVTIGluIGZpbGUgYCVzJy4iKSwKCQkgICAgICAgY3VycmVudF9uYW1lKTsKCX0gZWxzZQoJCXJldHVybiAqbnI7CgoJaWYgKGFzayhfKCJSZW1vdmUgYmxvY2siKSwxKSkgewoJCSpuciA9IDA7CgkJKmNvcnJlY3RlZCA9IDE7Cgl9CglyZXR1cm4gMDsKfQoKc3RhdGljIGludApjaGVja196b25lX25yMiAodW5zaWduZWQgaW50ICpuciwgaW50ICpjb3JyZWN0ZWQpIHsKCWlmICghKm5yKQoJCXJldHVybiAwOwoKCWlmICgqbnIgPCBGSVJTVFpPTkUpIHsKCQlnZXRfY3VycmVudF9uYW1lKCk7CgkJcHJpbnRmIChfKCJab25lIG5yIDwgRklSU1RaT05FIGluIGZpbGUgYCVzJy4iKSwKCQkJY3VycmVudF9uYW1lKTsKCX0gZWxzZSBpZiAoKm5yID49IFpPTkVTKSB7CgkJZ2V0X2N1cnJlbnRfbmFtZSgpOwoJCXByaW50ZiAoXygiWm9uZSBuciA+PSBaT05FUyBpbiBmaWxlIGAlcycuIiksCgkJCWN1cnJlbnRfbmFtZSk7Cgl9IGVsc2UKCQlyZXR1cm4gKm5yOwoKCWlmIChhc2sgKF8oIlJlbW92ZSBibG9jayIpLCAxKSkgewoJCSpuciA9IDA7CgkJKmNvcnJlY3RlZCA9IDE7Cgl9CglyZXR1cm4gMDsKfQoKLyoKICogcmVhZC1ibG9jayByZWFkcyBibG9jayBuciBpbnRvIHRoZSBidWZmZXIgYXQgYWRkci4KICovCnN0YXRpYyB2b2lkCnJlYWRfYmxvY2sodW5zaWduZWQgaW50IG5yLCBjaGFyICogYWRkcikgewoJaWYgKCFucikgewoJCW1lbXNldChhZGRyLDAsQkxPQ0tfU0laRSk7CgkJcmV0dXJuOwoJfQoJaWYgKEJMT0NLX1NJWkUqbnIgIT0gbHNlZWsoSU4sIEJMT0NLX1NJWkUqbnIsIFNFRUtfU0VUKSkgewoJCWdldF9jdXJyZW50X25hbWUoKTsKCQlwcmludGYoXygiUmVhZCBlcnJvcjogdW5hYmxlIHRvIHNlZWsgdG8gYmxvY2sgaW4gZmlsZSAnJXMnXG4iKSwKCQkgICAgICAgY3VycmVudF9uYW1lKTsKCQltZW1zZXQoYWRkciwwLEJMT0NLX1NJWkUpOwoJCWVycm9yc191bmNvcnJlY3RlZCA9IDE7Cgl9IGVsc2UgaWYgKEJMT0NLX1NJWkUgIT0gcmVhZChJTiwgYWRkciwgQkxPQ0tfU0laRSkpIHsKCQlnZXRfY3VycmVudF9uYW1lKCk7CgkJcHJpbnRmKF8oIlJlYWQgZXJyb3I6IGJhZCBibG9jayBpbiBmaWxlICclcydcbiIpLAoJCSAgICAgICBjdXJyZW50X25hbWUpOwoJCW1lbXNldChhZGRyLDAsQkxPQ0tfU0laRSk7CgkJZXJyb3JzX3VuY29ycmVjdGVkID0gMTsKCX0KfQoKLyoKICogd3JpdGVfYmxvY2sgd3JpdGVzIGJsb2NrIG5yIHRvIGRpc2suCiAqLwpzdGF0aWMgdm9pZAp3cml0ZV9ibG9jayh1bnNpZ25lZCBpbnQgbnIsIGNoYXIgKiBhZGRyKSB7CglpZiAoIW5yKQoJCXJldHVybjsKCWlmIChuciA8IEZJUlNUWk9ORSB8fCBuciA+PSBaT05FUykgewoJCXByaW50ZihfKCJJbnRlcm5hbCBlcnJvcjogdHJ5aW5nIHRvIHdyaXRlIGJhZCBibG9ja1xuIgoJCSJXcml0ZSByZXF1ZXN0IGlnbm9yZWRcbiIpKTsKCQllcnJvcnNfdW5jb3JyZWN0ZWQgPSAxOwoJCXJldHVybjsKCX0KCWlmIChCTE9DS19TSVpFKm5yICE9IGxzZWVrKElOLCBCTE9DS19TSVpFKm5yLCBTRUVLX1NFVCkpCgkJZGllKF8oInNlZWsgZmFpbGVkIGluIHdyaXRlX2Jsb2NrIikpOwoJaWYgKEJMT0NLX1NJWkUgIT0gd3JpdGUoSU4sIGFkZHIsIEJMT0NLX1NJWkUpKSB7CgkJZ2V0X2N1cnJlbnRfbmFtZSgpOwoJCXByaW50ZihfKCJXcml0ZSBlcnJvcjogYmFkIGJsb2NrIGluIGZpbGUgJyVzJ1xuIiksCgkJICAgICAgIGN1cnJlbnRfbmFtZSk7CgkJZXJyb3JzX3VuY29ycmVjdGVkID0gMTsKCX0KfQoKLyoKICogbWFwLWJsb2NrIGNhbGN1bGF0ZXMgdGhlIGFic29sdXRlIGJsb2NrIG5yIG9mIGEgYmxvY2sgaW4gYSBmaWxlLgogKiBJdCBzZXRzICdjaGFuZ2VkJyBpZiB0aGUgaW5vZGUgaGFzIG5lZWRlZCBjaGFuZ2luZywgYW5kIHJlLXdyaXRlcwogKiBhbnkgaW5kaXJlY3QgYmxvY2tzIHdpdGggZXJyb3JzLgogKi8Kc3RhdGljIGludAptYXBfYmxvY2soc3RydWN0IG1pbml4X2lub2RlICogaW5vZGUsIHVuc2lnbmVkIGludCBibGtucikgewoJdW5zaWduZWQgc2hvcnQgaW5kW0JMT0NLX1NJWkU+PjFdOwoJdW5zaWduZWQgc2hvcnQgZGluZFtCTE9DS19TSVpFPj4xXTsKCWludCBibGtfY2hnLCBibG9jaywgcmVzdWx0OwoKCWlmIChibGtucjw3KQoJCXJldHVybiBjaGVja196b25lX25yKGlub2RlLT5pX3pvbmUgKyBibGtuciwgJmNoYW5nZWQpOwoJYmxrbnIgLT0gNzsKCWlmIChibGtucjw1MTIpIHsKCQlibG9jayA9IGNoZWNrX3pvbmVfbnIoaW5vZGUtPmlfem9uZSArIDcsICZjaGFuZ2VkKTsKCQlyZWFkX2Jsb2NrKGJsb2NrLCAoY2hhciAqKSBpbmQpOwoJCWJsa19jaGcgPSAwOwoJCXJlc3VsdCA9IGNoZWNrX3pvbmVfbnIoYmxrbnIgKyBpbmQsICZibGtfY2hnKTsKCQlpZiAoYmxrX2NoZykKCQkJd3JpdGVfYmxvY2soYmxvY2ssIChjaGFyICopIGluZCk7CgkJcmV0dXJuIHJlc3VsdDsKCX0KCWJsa25yIC09IDUxMjsKCWJsb2NrID0gY2hlY2tfem9uZV9ucihpbm9kZS0+aV96b25lICsgOCwgJmNoYW5nZWQpOwoJcmVhZF9ibG9jayhibG9jaywgKGNoYXIgKikgZGluZCk7CglibGtfY2hnID0gMDsKCXJlc3VsdCA9IGNoZWNrX3pvbmVfbnIoZGluZCArIChibGtuci81MTIpLCAmYmxrX2NoZyk7CglpZiAoYmxrX2NoZykKCQl3cml0ZV9ibG9jayhibG9jaywgKGNoYXIgKikgZGluZCk7CglibG9jayA9IHJlc3VsdDsKCXJlYWRfYmxvY2soYmxvY2ssIChjaGFyICopIGluZCk7CglibGtfY2hnID0gMDsKCXJlc3VsdCA9IGNoZWNrX3pvbmVfbnIoaW5kICsgKGJsa25yJTUxMiksICZibGtfY2hnKTsKCWlmIChibGtfY2hnKQoJCXdyaXRlX2Jsb2NrKGJsb2NrLCAoY2hhciAqKSBpbmQpOwoJcmV0dXJuIHJlc3VsdDsKfQoKc3RhdGljIGludAptYXBfYmxvY2syIChzdHJ1Y3QgbWluaXgyX2lub2RlICppbm9kZSwgdW5zaWduZWQgaW50IGJsa25yKSB7CiAgCXVuc2lnbmVkIGludCBpbmRbQkxPQ0tfU0laRSA+PiAyXTsKCXVuc2lnbmVkIGludCBkaW5kW0JMT0NLX1NJWkUgPj4gMl07Cgl1bnNpZ25lZCBpbnQgdGluZFtCTE9DS19TSVpFID4+IDJdOwoJaW50IGJsa19jaGcsIGJsb2NrLCByZXN1bHQ7CgoJaWYgKGJsa25yIDwgNykKCQlyZXR1cm4gY2hlY2tfem9uZV9ucjIgKGlub2RlLT5pX3pvbmUgKyBibGtuciwgJmNoYW5nZWQpOwoJYmxrbnIgLT0gNzsKCWlmIChibGtuciA8IDI1NikgewoJCWJsb2NrID0gY2hlY2tfem9uZV9ucjIgKGlub2RlLT5pX3pvbmUgKyA3LCAmY2hhbmdlZCk7CgkJcmVhZF9ibG9jayAoYmxvY2ssIChjaGFyICopIGluZCk7CgkJYmxrX2NoZyA9IDA7CgkJcmVzdWx0ID0gY2hlY2tfem9uZV9ucjIgKGJsa25yICsgaW5kLCAmYmxrX2NoZyk7CgkJaWYgKGJsa19jaGcpCgkJCXdyaXRlX2Jsb2NrIChibG9jaywgKGNoYXIgKikgaW5kKTsKCQlyZXR1cm4gcmVzdWx0OwoJfQoJYmxrbnIgLT0gMjU2OwoJaWYgKGJsa25yID49IDI1NiAqIDI1NikgewoJCWJsb2NrID0gY2hlY2tfem9uZV9ucjIgKGlub2RlLT5pX3pvbmUgKyA4LCAmY2hhbmdlZCk7CgkJcmVhZF9ibG9jayAoYmxvY2ssIChjaGFyICopIGRpbmQpOwoJCWJsa19jaGcgPSAwOwoJCXJlc3VsdCA9IGNoZWNrX3pvbmVfbnIyIChkaW5kICsgYmxrbnIgLyAyNTYsICZibGtfY2hnKTsKCQlpZiAoYmxrX2NoZykKCQkJd3JpdGVfYmxvY2sgKGJsb2NrLCAoY2hhciAqKSBkaW5kKTsKCQlibG9jayA9IHJlc3VsdDsKCQlyZWFkX2Jsb2NrIChibG9jaywgKGNoYXIgKikgaW5kKTsKCQlibGtfY2hnID0gMDsKCQlyZXN1bHQgPSBjaGVja196b25lX25yMiAoaW5kICsgYmxrbnIgJSAyNTYsICZibGtfY2hnKTsKCQlpZiAoYmxrX2NoZykKCQkJd3JpdGVfYmxvY2sgKGJsb2NrLCAoY2hhciAqKSBpbmQpOwoJCXJldHVybiByZXN1bHQ7Cgl9CglibGtuciAtPSAyNTYgKiAyNTY7CglibG9jayA9IGNoZWNrX3pvbmVfbnIyIChpbm9kZS0+aV96b25lICsgOSwgJmNoYW5nZWQpOwoJcmVhZF9ibG9jayAoYmxvY2ssIChjaGFyICopIHRpbmQpOwoJYmxrX2NoZyA9IDA7CglyZXN1bHQgPSBjaGVja196b25lX25yMiAodGluZCArIGJsa25yIC8gKDI1NiAqIDI1NiksICZibGtfY2hnKTsKCWlmIChibGtfY2hnKQoJCXdyaXRlX2Jsb2NrIChibG9jaywgKGNoYXIgKikgdGluZCk7CglibG9jayA9IHJlc3VsdDsKCXJlYWRfYmxvY2sgKGJsb2NrLCAoY2hhciAqKSBkaW5kKTsKCWJsa19jaGcgPSAwOwoJcmVzdWx0ID0gY2hlY2tfem9uZV9ucjIgKGRpbmQgKyAoYmxrbnIgLyAyNTYpICUgMjU2LCAmYmxrX2NoZyk7CglpZiAoYmxrX2NoZykKCQl3cml0ZV9ibG9jayAoYmxvY2ssIChjaGFyICopIGRpbmQpOwoJYmxvY2sgPSByZXN1bHQ7CglyZWFkX2Jsb2NrIChibG9jaywgKGNoYXIgKikgaW5kKTsKCWJsa19jaGcgPSAwOwoJcmVzdWx0ID0gY2hlY2tfem9uZV9ucjIgKGluZCArIGJsa25yICUgMjU2LCAmYmxrX2NoZyk7CglpZiAoYmxrX2NoZykKCQl3cml0ZV9ibG9jayAoYmxvY2ssIChjaGFyICopIGluZCk7CglyZXR1cm4gcmVzdWx0Owp9CgpzdGF0aWMgdm9pZAp3cml0ZV9zdXBlcl9ibG9jayh2b2lkKSB7CgkvKgoJICogU2V0IHRoZSBzdGF0ZSBvZiB0aGUgZmlsZXN5c3RlbSBiYXNlZCBvbiB3aGV0aGVyIG9yIG5vdCB0aGVyZQoJICogYXJlIHVuY29ycmVjdGVkIGVycm9ycy4gIFRoZSBmaWxlc3lzdGVtIHZhbGlkIGZsYWcgaXMKCSAqIHVuY29uZGl0aW9uYWxseSBzZXQgaWYgd2UgZ2V0IHRoaXMgZmFyLgoJICovCglTdXBlci5zX3N0YXRlIHw9IE1JTklYX1ZBTElEX0ZTOwoJaWYgKCBlcnJvcnNfdW5jb3JyZWN0ZWQgKQoJCVN1cGVyLnNfc3RhdGUgfD0gTUlOSVhfRVJST1JfRlM7CgllbHNlCgkJU3VwZXIuc19zdGF0ZSAmPSB+TUlOSVhfRVJST1JfRlM7CgkKCWlmIChCTE9DS19TSVpFICE9IGxzZWVrKElOLCBCTE9DS19TSVpFLCBTRUVLX1NFVCkpCgkJZGllKF8oInNlZWsgZmFpbGVkIGluIHdyaXRlX3N1cGVyX2Jsb2NrIikpOwoJaWYgKEJMT0NLX1NJWkUgIT0gd3JpdGUoSU4sIHN1cGVyX2Jsb2NrX2J1ZmZlciwgQkxPQ0tfU0laRSkpCgkJZGllKF8oInVuYWJsZSB0byB3cml0ZSBzdXBlci1ibG9jayIpKTsKCglyZXR1cm47Cn0KCnN0YXRpYyB2b2lkCndyaXRlX3RhYmxlcyh2b2lkKSB7Cgl3cml0ZV9zdXBlcl9ibG9jaygpOwoKCWlmIChJTUFQUypCTE9DS19TSVpFICE9IHdyaXRlKElOLGlub2RlX21hcCxJTUFQUypCTE9DS19TSVpFKSkKCQlkaWUoXygiVW5hYmxlIHRvIHdyaXRlIGlub2RlIG1hcCIpKTsKCWlmIChaTUFQUypCTE9DS19TSVpFICE9IHdyaXRlKElOLHpvbmVfbWFwLFpNQVBTKkJMT0NLX1NJWkUpKQoJCWRpZShfKCJVbmFibGUgdG8gd3JpdGUgem9uZSBtYXAiKSk7CglpZiAoSU5PREVfQlVGRkVSX1NJWkUgIT0gd3JpdGUoSU4saW5vZGVfYnVmZmVyLElOT0RFX0JVRkZFUl9TSVpFKSkKCQlkaWUoXygiVW5hYmxlIHRvIHdyaXRlIGlub2RlcyIpKTsKfQoKc3RhdGljIHZvaWQKZ2V0X2RpcnNpemUgKHZvaWQpIHsKCWludCBibG9jazsKCWNoYXIgYmxrW0JMT0NLX1NJWkVdOwoJaW50IHNpemU7CgoJaWYgKHZlcnNpb24yKQoJCWJsb2NrID0gSW5vZGUyW1JPT1RfSU5PXS5pX3pvbmVbMF07CgllbHNlCgkJYmxvY2sgPSBJbm9kZVtST09UX0lOT10uaV96b25lWzBdOwoJcmVhZF9ibG9jayAoYmxvY2ssIGJsayk7Cglmb3IgKHNpemUgPSAxNjsgc2l6ZSA8IEJMT0NLX1NJWkU7IHNpemUgPDw9IDEpIHsKCQlpZiAoc3RyY21wIChibGsgKyBzaXplICsgMiwgIi4uIikgPT0gMCkgewoJCQlkaXJzaXplID0gc2l6ZTsKCQkJbmFtZWxlbiA9IHNpemUgLSAyOwoJCQlyZXR1cm47CgkJfQoJfQoJLyogdXNlIGRlZmF1bHRzICovCn0KCnN0YXRpYyB2b2lkCnJlYWRfc3VwZXJibG9jayh2b2lkKSB7CglpZiAoQkxPQ0tfU0laRSAhPSBsc2VlayhJTiwgQkxPQ0tfU0laRSwgU0VFS19TRVQpKQoJCWRpZShfKCJzZWVrIGZhaWxlZCIpKTsKCglzdXBlcl9ibG9ja19idWZmZXIgPSBjYWxsb2MoMSwgQkxPQ0tfU0laRSk7CglpZiAoIXN1cGVyX2Jsb2NrX2J1ZmZlcikKCQlkaWUoXygidW5hYmxlIHRvIGFsbG9jIGJ1ZmZlciBmb3Igc3VwZXJibG9jayIpKTsKCglpZiAoQkxPQ0tfU0laRSAhPSByZWFkKElOLCBzdXBlcl9ibG9ja19idWZmZXIsIEJMT0NLX1NJWkUpKQoJCWRpZShfKCJ1bmFibGUgdG8gcmVhZCBzdXBlciBibG9jayIpKTsKCWlmIChNQUdJQyA9PSBNSU5JWF9TVVBFUl9NQUdJQykgewoJCW5hbWVsZW4gPSAxNDsKCQlkaXJzaXplID0gMTY7CgkJdmVyc2lvbjIgPSAwOwoJfSBlbHNlIGlmIChNQUdJQyA9PSBNSU5JWF9TVVBFUl9NQUdJQzIpIHsKCQluYW1lbGVuID0gMzA7CgkJZGlyc2l6ZSA9IDMyOwoJCXZlcnNpb24yID0gMDsKCX0gZWxzZSBpZiAoTUFHSUMgPT0gTUlOSVgyX1NVUEVSX01BR0lDKSB7CgkJbmFtZWxlbiA9IDE0OwoJCWRpcnNpemUgPSAxNjsKCQl2ZXJzaW9uMiA9IDE7Cgl9IGVsc2UgaWYgKE1BR0lDID09IE1JTklYMl9TVVBFUl9NQUdJQzIpIHsKCQluYW1lbGVuID0gMzA7CgkJZGlyc2l6ZSA9IDMyOwoJCXZlcnNpb24yID0gMTsKCX0gZWxzZQoJCWRpZShfKCJiYWQgbWFnaWMgbnVtYmVyIGluIHN1cGVyLWJsb2NrIikpOwoJaWYgKFpPTkVTSVpFICE9IDAgfHwgQkxPQ0tfU0laRSAhPSAxMDI0KQoJCWRpZShfKCJPbmx5IDFrIGJsb2Nrcy96b25lcyBzdXBwb3J0ZWQiKSk7CglpZiAoSU1BUFMgKiBCTE9DS19TSVpFICogOCA8IElOT0RFUyArIDEpCgkJZGllKF8oImJhZCBzX2ltYXBfYmxvY2tzIGZpZWxkIGluIHN1cGVyLWJsb2NrIikpOwoJaWYgKFpNQVBTICogQkxPQ0tfU0laRSAqIDggPCBaT05FUyAtIEZJUlNUWk9ORSArIDEpCgkJZGllKF8oImJhZCBzX3ptYXBfYmxvY2tzIGZpZWxkIGluIHN1cGVyLWJsb2NrIikpOwp9CgpzdGF0aWMgdm9pZApyZWFkX3RhYmxlcyh2b2lkKSB7Cglpbm9kZV9tYXAgPSBtYWxsb2MoSU1BUFMgKiBCTE9DS19TSVpFKTsKCWlmICghaW5vZGVfbWFwKQoJCWRpZShfKCJVbmFibGUgdG8gYWxsb2NhdGUgYnVmZmVyIGZvciBpbm9kZSBtYXAiKSk7Cgl6b25lX21hcCA9IG1hbGxvYyhaTUFQUyAqIEJMT0NLX1NJWkUpOwoJaWYgKCFpbm9kZV9tYXApCgkJZGllKF8oIlVuYWJsZSB0byBhbGxvY2F0ZSBidWZmZXIgZm9yIHpvbmUgbWFwIikpOwoJbWVtc2V0KGlub2RlX21hcCwwLHNpemVvZihpbm9kZV9tYXApKTsKCW1lbXNldCh6b25lX21hcCwwLHNpemVvZih6b25lX21hcCkpOwoJaW5vZGVfYnVmZmVyID0gbWFsbG9jKElOT0RFX0JVRkZFUl9TSVpFKTsKCWlmICghaW5vZGVfYnVmZmVyKQoJCWRpZShfKCJVbmFibGUgdG8gYWxsb2NhdGUgYnVmZmVyIGZvciBpbm9kZXMiKSk7Cglpbm9kZV9jb3VudCA9IG1hbGxvYyhJTk9ERVMgKyAxKTsKCWlmICghaW5vZGVfY291bnQpCgkJZGllKF8oIlVuYWJsZSB0byBhbGxvY2F0ZSBidWZmZXIgZm9yIGlub2RlIGNvdW50IikpOwoJem9uZV9jb3VudCA9IG1hbGxvYyhaT05FUyk7CglpZiAoIXpvbmVfY291bnQpCgkJZGllKF8oIlVuYWJsZSB0byBhbGxvY2F0ZSBidWZmZXIgZm9yIHpvbmUgY291bnQiKSk7CglpZiAoSU1BUFMqQkxPQ0tfU0laRSAhPSByZWFkKElOLGlub2RlX21hcCxJTUFQUypCTE9DS19TSVpFKSkKCQlkaWUoXygiVW5hYmxlIHRvIHJlYWQgaW5vZGUgbWFwIikpOwoJaWYgKFpNQVBTKkJMT0NLX1NJWkUgIT0gcmVhZChJTix6b25lX21hcCxaTUFQUypCTE9DS19TSVpFKSkKCQlkaWUoXygiVW5hYmxlIHRvIHJlYWQgem9uZSBtYXAiKSk7CglpZiAoSU5PREVfQlVGRkVSX1NJWkUgIT0gcmVhZChJTixpbm9kZV9idWZmZXIsSU5PREVfQlVGRkVSX1NJWkUpKQoJCWRpZShfKCJVbmFibGUgdG8gcmVhZCBpbm9kZXMiKSk7CglpZiAoTk9STV9GSVJTVFpPTkUgIT0gRklSU1RaT05FKSB7CgkJcHJpbnRmKF8oIldhcm5pbmc6IEZpcnN0em9uZSAhPSBOb3JtX2ZpcnN0em9uZVxuIikpOwoJCWVycm9yc191bmNvcnJlY3RlZCA9IDE7Cgl9CglnZXRfZGlyc2l6ZSAoKTsKCWlmIChzaG93KSB7CgkJcHJpbnRmKF8oIiVsZCBpbm9kZXNcbiIpLElOT0RFUyk7CgkJcHJpbnRmKF8oIiVsZCBibG9ja3NcbiIpLFpPTkVTKTsKCQlwcmludGYoXygiRmlyc3RkYXRhem9uZT0lbGQgKCVsZClcbiIpLEZJUlNUWk9ORSxOT1JNX0ZJUlNUWk9ORSk7CgkJcHJpbnRmKF8oIlpvbmVzaXplPSVkXG4iKSxCTE9DS19TSVpFPDxaT05FU0laRSk7CgkJcHJpbnRmKF8oIk1heHNpemU9JWxkXG4iKSxNQVhTSVpFKTsKCQlwcmludGYoXygiRmlsZXN5c3RlbSBzdGF0ZT0lZFxuIiksIFN1cGVyLnNfc3RhdGUpOwoJCXByaW50ZihfKCJuYW1lbGVuPSVkXG5cbiIpLG5hbWVsZW4pOwoJfQp9CgpzdGF0aWMgc3RydWN0IG1pbml4X2lub2RlICoKZ2V0X2lub2RlKHVuc2lnbmVkIGludCBucikgewoJc3RydWN0IG1pbml4X2lub2RlICogaW5vZGU7CgoJaWYgKCFuciB8fCBuciA+IElOT0RFUykKCQlyZXR1cm4gTlVMTDsKCXRvdGFsKys7Cglpbm9kZSA9IElub2RlICsgbnI7CglpZiAoIWlub2RlX2NvdW50W25yXSkgewoJCWlmICghaW5vZGVfaW5fdXNlKG5yKSkgewoJCQlnZXRfY3VycmVudF9uYW1lKCk7CgkJCXByaW50ZihfKCJJbm9kZSAlZCBtYXJrZWQgdW51c2VkLCAiCgkJCQkgImJ1dCB1c2VkIGZvciBmaWxlICclcydcbiIpLAoJCQkgICAgICAgbnIsIGN1cnJlbnRfbmFtZSk7CgkJCWlmIChyZXBhaXIpIHsKCQkJCWlmIChhc2soXygiTWFyayBpbiB1c2UiKSwxKSkKCQkJCQltYXJrX2lub2RlKG5yKTsKCQkJfSBlbHNlIHsKCQkJICAgICAgICBlcnJvcnNfdW5jb3JyZWN0ZWQgPSAxOwoJCQl9CgkJfQoJCWlmIChTX0lTRElSKGlub2RlLT5pX21vZGUpKQoJCQlkaXJlY3RvcnkrKzsKCQllbHNlIGlmIChTX0lTUkVHKGlub2RlLT5pX21vZGUpKQoJCQlyZWd1bGFyKys7CgkJZWxzZSBpZiAoU19JU0NIUihpbm9kZS0+aV9tb2RlKSkKCQkJY2hhcmRldisrOwoJCWVsc2UgaWYgKFNfSVNCTEsoaW5vZGUtPmlfbW9kZSkpCgkJCWJsb2NrZGV2Kys7CgkJZWxzZSBpZiAoU19JU0xOSyhpbm9kZS0+aV9tb2RlKSkKCQkJc3ltbGlua3MrKzsKCQllbHNlIGlmIChTX0lTU09DSyhpbm9kZS0+aV9tb2RlKSkKCQkJOwoJCWVsc2UgaWYgKFNfSVNGSUZPKGlub2RlLT5pX21vZGUpKQoJCQk7CgkJZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgIGdldF9jdXJyZW50X25hbWUoKTsKICAgICAgICAgICAgICAgICAgICAgICAgcHJpbnRmKF8oIlRoZSBmaWxlIGAlcycgaGFzIG1vZGUgJTA1b1xuIiksCgkJCSAgICAgICBjdXJyZW50X25hbWUsIGlub2RlLT5pX21vZGUpOwogICAgICAgICAgICAgICAgfQoKCX0gZWxzZQoJCWxpbmtzKys7CglpZiAoISsraW5vZGVfY291bnRbbnJdKSB7CgkJcHJpbnRmKF8oIldhcm5pbmc6IGlub2RlIGNvdW50IHRvbyBiaWcuXG4iKSk7CgkJaW5vZGVfY291bnRbbnJdLS07CgkJZXJyb3JzX3VuY29ycmVjdGVkID0gMTsKCX0KCXJldHVybiBpbm9kZTsKfQoKc3RhdGljIHN0cnVjdCBtaW5peDJfaW5vZGUgKgpnZXRfaW5vZGUyICh1bnNpZ25lZCBpbnQgbnIpIHsKCXN0cnVjdCBtaW5peDJfaW5vZGUgKmlub2RlOwoKCWlmICghbnIgfHwgbnIgPiBJTk9ERVMpCgkJcmV0dXJuIE5VTEw7Cgl0b3RhbCsrOwoJaW5vZGUgPSBJbm9kZTIgKyBucjsKCWlmICghaW5vZGVfY291bnRbbnJdKSB7CgkJaWYgKCFpbm9kZV9pbl91c2UgKG5yKSkgewoJCQlnZXRfY3VycmVudF9uYW1lKCk7CgkJCXByaW50ZiAoXygiSW5vZGUgJWQgbWFya2VkIHVudXNlZCwgIgoJCQkJICAiYnV0IHVzZWQgZm9yIGZpbGUgJyVzJ1xuIiksCgkJCQluciwgY3VycmVudF9uYW1lKTsKCQkJaWYgKHJlcGFpcikgewoJCQkJaWYgKGFzayAoXygiTWFyayBpbiB1c2UiKSwgMSkpCgkJCQkJbWFya19pbm9kZSAobnIpOwoJCQkJZWxzZQoJCQkJCWVycm9yc191bmNvcnJlY3RlZCA9IDE7CgkJCX0KCQl9CgkJaWYgKFNfSVNESVIgKGlub2RlLT5pX21vZGUpKQoJCQlkaXJlY3RvcnkrKzsKCQllbHNlIGlmIChTX0lTUkVHIChpbm9kZS0+aV9tb2RlKSkKCQkJcmVndWxhcisrOwoJCWVsc2UgaWYgKFNfSVNDSFIgKGlub2RlLT5pX21vZGUpKQoJCQljaGFyZGV2Kys7CgkJZWxzZSBpZiAoU19JU0JMSyAoaW5vZGUtPmlfbW9kZSkpCgkJCWJsb2NrZGV2Kys7CgkJZWxzZSBpZiAoU19JU0xOSyAoaW5vZGUtPmlfbW9kZSkpCgkJCXN5bWxpbmtzKys7CgkJZWxzZSBpZiAoU19JU1NPQ0sgKGlub2RlLT5pX21vZGUpKTsKCQllbHNlIGlmIChTX0lTRklGTyAoaW5vZGUtPmlfbW9kZSkpOwoJCWVsc2UgewoJCQlnZXRfY3VycmVudF9uYW1lICgpOwoJCQlwcmludGYgKF8oIlRoZSBmaWxlIGAlcycgaGFzIG1vZGUgJTA1b1xuIiksCgkJCQljdXJyZW50X25hbWUsIGlub2RlLT5pX21vZGUpOwoJCX0KCX0gZWxzZQoJCWxpbmtzKys7CglpZiAoISsraW5vZGVfY291bnRbbnJdKSB7CgkJcHJpbnRmIChfKCJXYXJuaW5nOiBpbm9kZSBjb3VudCB0b28gYmlnLlxuIikpOwoJCWlub2RlX2NvdW50W25yXS0tOwoJCWVycm9yc191bmNvcnJlY3RlZCA9IDE7Cgl9CglyZXR1cm4gaW5vZGU7Cn0KCnN0YXRpYyB2b2lkCmNoZWNrX3Jvb3Qodm9pZCkgewoJc3RydWN0IG1pbml4X2lub2RlICogaW5vZGUgPSBJbm9kZSArIFJPT1RfSU5POwoKCWlmICghaW5vZGUgfHwgIVNfSVNESVIoaW5vZGUtPmlfbW9kZSkpCgkJZGllKF8oInJvb3QgaW5vZGUgaXNuJ3QgYSBkaXJlY3RvcnkiKSk7Cn0KCnN0YXRpYyB2b2lkCmNoZWNrX3Jvb3QyICh2b2lkKSB7CglzdHJ1Y3QgbWluaXgyX2lub2RlICppbm9kZSA9IElub2RlMiArIFJPT1RfSU5POwoKCWlmICghaW5vZGUgfHwgIVNfSVNESVIgKGlub2RlLT5pX21vZGUpKQoJCWRpZShfKCJyb290IGlub2RlIGlzbid0IGEgZGlyZWN0b3J5IikpOwp9CgpzdGF0aWMgaW50CmFkZF96b25lKHVuc2lnbmVkIHNob3J0ICogem5yLCBpbnQgKiBjb3JyZWN0ZWQpIHsKCWludCByZXN1bHQ7CglpbnQgYmxvY2s7CgoJcmVzdWx0ID0gMDsKCWJsb2NrID0gY2hlY2tfem9uZV9ucih6bnIsIGNvcnJlY3RlZCk7CglpZiAoIWJsb2NrKQoJCXJldHVybiAwOwoJaWYgKHpvbmVfY291bnRbYmxvY2tdKSB7CgkJZ2V0X2N1cnJlbnRfbmFtZSgpOwoJCXByaW50ZihfKCJCbG9jayBoYXMgYmVlbiB1c2VkIGJlZm9yZS4gTm93IGluIGZpbGUgYCVzJy4iKSwKCQkgICAgICAgY3VycmVudF9uYW1lKTsKCQlpZiAoYXNrKF8oIkNsZWFyIiksMSkpIHsKCQkJKnpuciA9IDA7CgkJCWJsb2NrID0gMDsKCQkJKmNvcnJlY3RlZCA9IDE7CgkJfQoJfQoJaWYgKCFibG9jaykKCQlyZXR1cm4gMDsKCWlmICghem9uZV9pbl91c2UoYmxvY2spKSB7CgkJZ2V0X2N1cnJlbnRfbmFtZSgpOwoJCXByaW50ZihfKCJCbG9jayAlZCBpbiBmaWxlIGAlcycgaXMgbWFya2VkIG5vdCBpbiB1c2UuIiksCgkJICAgICAgIGJsb2NrLCBjdXJyZW50X25hbWUpOwoJCWlmIChhc2soXygiQ29ycmVjdCIpLDEpKQoJCQltYXJrX3pvbmUoYmxvY2spOwoJfQoJaWYgKCErK3pvbmVfY291bnRbYmxvY2tdKQoJCXpvbmVfY291bnRbYmxvY2tdLS07CglyZXR1cm4gYmxvY2s7Cn0KCnN0YXRpYyBpbnQKYWRkX3pvbmUyICh1bnNpZ25lZCBpbnQgKnpuciwgaW50ICpjb3JyZWN0ZWQpIHsKCWludCByZXN1bHQ7CglpbnQgYmxvY2s7CgoJcmVzdWx0ID0gMDsKCWJsb2NrID0gY2hlY2tfem9uZV9ucjIgKHpuciwgY29ycmVjdGVkKTsKCWlmICghYmxvY2spCgkJcmV0dXJuIDA7CglpZiAoem9uZV9jb3VudFtibG9ja10pIHsKCQlnZXRfY3VycmVudF9uYW1lKCk7CgkJcHJpbnRmIChfKCJCbG9jayBoYXMgYmVlbiB1c2VkIGJlZm9yZS4gTm93IGluIGZpbGUgYCVzJy4iKSwKCQkJY3VycmVudF9uYW1lKTsKCQlpZiAoYXNrIChfKCJDbGVhciIpLCAxKSkgewoJCQkqem5yID0gMDsKCQkJYmxvY2sgPSAwOwoJCQkqY29ycmVjdGVkID0gMTsKCQl9Cgl9CglpZiAoIWJsb2NrKQoJCXJldHVybiAwOwoJaWYgKCF6b25lX2luX3VzZSAoYmxvY2spKSB7CgkJZ2V0X2N1cnJlbnRfbmFtZSgpOwoJCXByaW50ZiAoXygiQmxvY2sgJWQgaW4gZmlsZSBgJXMnIGlzIG1hcmtlZCBub3QgaW4gdXNlLiIpLAoJCQlibG9jaywgY3VycmVudF9uYW1lKTsKCQlpZiAoYXNrIChfKCJDb3JyZWN0IiksIDEpKQoJCQltYXJrX3pvbmUgKGJsb2NrKTsKCX0KCWlmICghKyt6b25lX2NvdW50W2Jsb2NrXSkKCQl6b25lX2NvdW50W2Jsb2NrXS0tOwoJcmV0dXJuIGJsb2NrOwp9CgpzdGF0aWMgdm9pZAphZGRfem9uZV9pbmQodW5zaWduZWQgc2hvcnQgKiB6bnIsIGludCAqIGNvcnJlY3RlZCkgewoJc3RhdGljIGNoYXIgYmxrW0JMT0NLX1NJWkVdOwoJaW50IGksIGNoZ19ibGs9MDsKCWludCBibG9jazsKCglibG9jayA9IGFkZF96b25lKHpuciwgY29ycmVjdGVkKTsKCWlmICghYmxvY2spCgkJcmV0dXJuOwoJcmVhZF9ibG9jayhibG9jaywgYmxrKTsKCWZvciAoaT0wIDsgaSA8IChCTE9DS19TSVpFPj4xKSA7IGkrKykKCQlhZGRfem9uZShpICsgKHVuc2lnbmVkIHNob3J0ICopIGJsaywgJmNoZ19ibGspOwoJaWYgKGNoZ19ibGspCgkJd3JpdGVfYmxvY2soYmxvY2ssIGJsayk7Cn0KCnN0YXRpYyB2b2lkCmFkZF96b25lX2luZDIgKHVuc2lnbmVkIGludCAqem5yLCBpbnQgKmNvcnJlY3RlZCkgewoJc3RhdGljIGNoYXIgYmxrW0JMT0NLX1NJWkVdOwoJaW50IGksIGNoZ19ibGsgPSAwOwoJaW50IGJsb2NrOwoKCWJsb2NrID0gYWRkX3pvbmUyICh6bnIsIGNvcnJlY3RlZCk7CglpZiAoIWJsb2NrKQoJCXJldHVybjsKCXJlYWRfYmxvY2sgKGJsb2NrLCBibGspOwoJZm9yIChpID0gMDsgaSA8IEJMT0NLX1NJWkUgPj4gMjsgaSsrKQoJCWFkZF96b25lMiAoaSArICh1bnNpZ25lZCBpbnQgKikgYmxrLCAmY2hnX2Jsayk7CglpZiAoY2hnX2JsaykKCQl3cml0ZV9ibG9jayAoYmxvY2ssIGJsayk7Cn0KCnN0YXRpYyB2b2lkCmFkZF96b25lX2RpbmQodW5zaWduZWQgc2hvcnQgKiB6bnIsIGludCAqIGNvcnJlY3RlZCkgewoJc3RhdGljIGNoYXIgYmxrW0JMT0NLX1NJWkVdOwoJaW50IGksIGJsa19jaGc9MDsKCWludCBibG9jazsKCglibG9jayA9IGFkZF96b25lKHpuciwgY29ycmVjdGVkKTsKCWlmICghYmxvY2spCgkJcmV0dXJuOwoJcmVhZF9ibG9jayhibG9jaywgYmxrKTsKCWZvciAoaT0wIDsgaSA8IChCTE9DS19TSVpFPj4xKSA7IGkrKykKCQlhZGRfem9uZV9pbmQoaSArICh1bnNpZ25lZCBzaG9ydCAqKSBibGssICZibGtfY2hnKTsKCWlmIChibGtfY2hnKQoJCXdyaXRlX2Jsb2NrKGJsb2NrLCBibGspOwp9CgpzdGF0aWMgdm9pZAphZGRfem9uZV9kaW5kMiAodW5zaWduZWQgaW50ICp6bnIsIGludCAqY29ycmVjdGVkKSB7CglzdGF0aWMgY2hhciBibGtbQkxPQ0tfU0laRV07CglpbnQgaSwgYmxrX2NoZyA9IDA7CglpbnQgYmxvY2s7CgoJYmxvY2sgPSBhZGRfem9uZTIgKHpuciwgY29ycmVjdGVkKTsKCWlmICghYmxvY2spCgkJcmV0dXJuOwoJcmVhZF9ibG9jayAoYmxvY2ssIGJsayk7Cglmb3IgKGkgPSAwOyBpIDwgQkxPQ0tfU0laRSA+PiAyOyBpKyspCgkJYWRkX3pvbmVfaW5kMiAoaSArICh1bnNpZ25lZCBpbnQgKikgYmxrLCAmYmxrX2NoZyk7CglpZiAoYmxrX2NoZykKCQl3cml0ZV9ibG9jayAoYmxvY2ssIGJsayk7Cn0KCnN0YXRpYyB2b2lkCmFkZF96b25lX3RpbmQyICh1bnNpZ25lZCBpbnQgKnpuciwgaW50ICpjb3JyZWN0ZWQpIHsKCXN0YXRpYyBjaGFyIGJsa1tCTE9DS19TSVpFXTsKCWludCBpLCBibGtfY2hnID0gMDsKCWludCBibG9jazsKCglibG9jayA9IGFkZF96b25lMiAoem5yLCBjb3JyZWN0ZWQpOwoJaWYgKCFibG9jaykKCQlyZXR1cm47CglyZWFkX2Jsb2NrIChibG9jaywgYmxrKTsKCWZvciAoaSA9IDA7IGkgPCBCTE9DS19TSVpFID4+IDI7IGkrKykKCQlhZGRfem9uZV9kaW5kMiAoaSArICh1bnNpZ25lZCBpbnQgKikgYmxrLCAmYmxrX2NoZyk7CglpZiAoYmxrX2NoZykKCQl3cml0ZV9ibG9jayAoYmxvY2ssIGJsayk7Cn0KCnN0YXRpYyB2b2lkCmNoZWNrX3pvbmVzKHVuc2lnbmVkIGludCBpKSB7CglzdHJ1Y3QgbWluaXhfaW5vZGUgKiBpbm9kZTsKCglpZiAoIWkgfHwgaSA+IElOT0RFUykKCQlyZXR1cm47CglpZiAoaW5vZGVfY291bnRbaV0gPiAxKQkvKiBoYXZlIHdlIGNvdW50ZWQgdGhpcyBmaWxlIGFscmVhZHk/ICovCgkJcmV0dXJuOwoJaW5vZGUgPSBJbm9kZSArIGk7CglpZiAoIVNfSVNESVIoaW5vZGUtPmlfbW9kZSkgJiYgIVNfSVNSRUcoaW5vZGUtPmlfbW9kZSkgJiYKCSAgICAhU19JU0xOSyhpbm9kZS0+aV9tb2RlKSkKCQlyZXR1cm47Cglmb3IgKGk9MCA7IGk8NyA7IGkrKykKCQlhZGRfem9uZShpICsgaW5vZGUtPmlfem9uZSwgJmNoYW5nZWQpOwoJYWRkX3pvbmVfaW5kKDcgKyBpbm9kZS0+aV96b25lLCAmY2hhbmdlZCk7CglhZGRfem9uZV9kaW5kKDggKyBpbm9kZS0+aV96b25lLCAmY2hhbmdlZCk7Cn0KCnN0YXRpYyB2b2lkCmNoZWNrX3pvbmVzMiAodW5zaWduZWQgaW50IGkpIHsKCXN0cnVjdCBtaW5peDJfaW5vZGUgKmlub2RlOwoKCWlmICghaSB8fCBpID4gSU5PREVTKQoJCXJldHVybjsKCWlmIChpbm9kZV9jb3VudFtpXSA+IDEpCS8qIGhhdmUgd2UgY291bnRlZCB0aGlzIGZpbGUgYWxyZWFkeT8gKi8KCQlyZXR1cm47Cglpbm9kZSA9IElub2RlMiArIGk7CglpZiAoIVNfSVNESVIgKGlub2RlLT5pX21vZGUpICYmICFTX0lTUkVHIChpbm9kZS0+aV9tb2RlKQoJICAgICYmICFTX0lTTE5LIChpbm9kZS0+aV9tb2RlKSkKCQlyZXR1cm47Cglmb3IgKGkgPSAwOyBpIDwgNzsgaSsrKQoJCWFkZF96b25lMiAoaSArIGlub2RlLT5pX3pvbmUsICZjaGFuZ2VkKTsKCWFkZF96b25lX2luZDIgKDcgKyBpbm9kZS0+aV96b25lLCAmY2hhbmdlZCk7CglhZGRfem9uZV9kaW5kMiAoOCArIGlub2RlLT5pX3pvbmUsICZjaGFuZ2VkKTsKCWFkZF96b25lX3RpbmQyICg5ICsgaW5vZGUtPmlfem9uZSwgJmNoYW5nZWQpOwp9CgpzdGF0aWMgdm9pZApjaGVja19maWxlKHN0cnVjdCBtaW5peF9pbm9kZSAqIGRpciwgdW5zaWduZWQgaW50IG9mZnNldCkgewoJc3RhdGljIGNoYXIgYmxrW0JMT0NLX1NJWkVdOwoJc3RydWN0IG1pbml4X2lub2RlICogaW5vZGU7CglpbnQgaW5vOwoJY2hhciAqIG5hbWU7CglpbnQgYmxvY2s7CgoJYmxvY2sgPSBtYXBfYmxvY2soZGlyLG9mZnNldC9CTE9DS19TSVpFKTsKCXJlYWRfYmxvY2soYmxvY2ssIGJsayk7CgluYW1lID0gYmxrICsgKG9mZnNldCAlIEJMT0NLX1NJWkUpICsgMjsKCWlubyA9ICogKHVuc2lnbmVkIHNob3J0ICopIChuYW1lLTIpOwoJaWYgKGlubyA+IElOT0RFUykgewoJCWdldF9jdXJyZW50X25hbWUoKTsKCQlwcmludGYoXygiVGhlIGRpcmVjdG9yeSAnJXMnIGNvbnRhaW5zIGEgYmFkIGlub2RlIG51bWJlciAiCgkJCSAiZm9yIGZpbGUgJyUuKnMnLiIpLAoJCSAgICAgICBjdXJyZW50X25hbWUsIG5hbWVsZW4sIG5hbWUpOwoJCWlmIChhc2soXygiIFJlbW92ZSIpLDEpKSB7CgkJCSoodW5zaWduZWQgc2hvcnQgKikobmFtZS0yKSA9IDA7CgkJCXdyaXRlX2Jsb2NrKGJsb2NrLCBibGspOwoJCX0KCQlpbm8gPSAwOwoJfQkKCWlmIChuYW1lX2RlcHRoIDwgTUFYX0RFUFRIKQoJCXN0cm5jcHkgKG5hbWVfbGlzdFtuYW1lX2RlcHRoXSwgbmFtZSwgbmFtZWxlbik7CgluYW1lX2RlcHRoKys7Cglpbm9kZSA9IGdldF9pbm9kZShpbm8pOwoJbmFtZV9kZXB0aC0tOwoJaWYgKCFvZmZzZXQpIHsKCQlpZiAoIWlub2RlIHx8IHN0cmNtcCgiLiIsbmFtZSkpIHsKCQkJZ2V0X2N1cnJlbnRfbmFtZSgpOwoJCQlwcmludGYoXygiJXM6IGJhZCBkaXJlY3Rvcnk6ICcuJyBpc24ndCBmaXJzdFxuIiksCgkJCSAgICAgICBjdXJyZW50X25hbWUpOwoJCQllcnJvcnNfdW5jb3JyZWN0ZWQgPSAxOwoJCX0gZWxzZSByZXR1cm47Cgl9CglpZiAob2Zmc2V0ID09IGRpcnNpemUpIHsKCQlpZiAoIWlub2RlIHx8IHN0cmNtcCgiLi4iLG5hbWUpKSB7CgkJCWdldF9jdXJyZW50X25hbWUoKTsKCQkJcHJpbnRmKF8oIiVzOiBiYWQgZGlyZWN0b3J5OiAnLi4nIGlzbid0IHNlY29uZFxuIiksCgkJCSAgICAgICBjdXJyZW50X25hbWUpOwoJCQllcnJvcnNfdW5jb3JyZWN0ZWQgPSAxOwoJCX0gZWxzZSByZXR1cm47Cgl9CglpZiAoIWlub2RlKQoJCXJldHVybjsKCWlmIChuYW1lX2RlcHRoIDwgTUFYX0RFUFRIKQoJCXN0cm5jcHkobmFtZV9saXN0W25hbWVfZGVwdGhdLCBuYW1lLCBuYW1lbGVuKTsKCW5hbWVfZGVwdGgrKzsJCglpZiAobGlzdCkgewoJCWlmICh2ZXJib3NlKQoJCQlwcmludGYoIiU2ZCAlMDdvICUzZCAiLCBpbm8sCgkJCSAgICAgICBpbm9kZS0+aV9tb2RlLCBpbm9kZS0+aV9ubGlua3MpOwoJCWdldF9jdXJyZW50X25hbWUoKTsKCQlwcmludGYoIiVzIiwgY3VycmVudF9uYW1lKTsKCQlpZiAoU19JU0RJUihpbm9kZS0+aV9tb2RlKSkKCQkJcHJpbnRmKCI6XG4iKTsKCQllbHNlCgkJCXByaW50ZigiXG4iKTsKCX0KCWNoZWNrX3pvbmVzKGlubyk7CglpZiAoaW5vZGUgJiYgU19JU0RJUihpbm9kZS0+aV9tb2RlKSkKCQlyZWN1cnNpdmVfY2hlY2soaW5vKTsKCW5hbWVfZGVwdGgtLTsKCXJldHVybjsKfQoKc3RhdGljIHZvaWQKY2hlY2tfZmlsZTIgKHN0cnVjdCBtaW5peDJfaW5vZGUgKmRpciwgdW5zaWduZWQgaW50IG9mZnNldCkgewoJc3RhdGljIGNoYXIgYmxrW0JMT0NLX1NJWkVdOwoJc3RydWN0IG1pbml4Ml9pbm9kZSAqaW5vZGU7CglpbnQgaW5vOwoJY2hhciAqbmFtZTsKCWludCBibG9jazsKCglibG9jayA9IG1hcF9ibG9jazIgKGRpciwgb2Zmc2V0IC8gQkxPQ0tfU0laRSk7CglyZWFkX2Jsb2NrIChibG9jaywgYmxrKTsKCW5hbWUgPSBibGsgKyAob2Zmc2V0ICUgQkxPQ0tfU0laRSkgKyAyOwoJaW5vID0gKih1bnNpZ25lZCBzaG9ydCAqKSAobmFtZSAtIDIpOwoJaWYgKGlubyA+IElOT0RFUykgewoJCWdldF9jdXJyZW50X25hbWUoKTsKCQlwcmludGYoXygiVGhlIGRpcmVjdG9yeSAnJXMnIGNvbnRhaW5zIGEgYmFkIGlub2RlIG51bWJlciAiCgkJCSAiZm9yIGZpbGUgJyUuKnMnLiIpLAoJCQkgIGN1cnJlbnRfbmFtZSwgbmFtZWxlbiwgbmFtZSk7CgkJaWYgKGFzayAoXygiIFJlbW92ZSIpLCAxKSkgewoJCQkqKHVuc2lnbmVkIHNob3J0ICopIChuYW1lIC0gMikgPSAwOwoJCQl3cml0ZV9ibG9jayAoYmxvY2ssIGJsayk7CgkJfQoJCWlubyA9IDA7Cgl9CglpZiAobmFtZV9kZXB0aCA8IE1BWF9ERVBUSCkKCQlzdHJuY3B5IChuYW1lX2xpc3RbbmFtZV9kZXB0aF0sIG5hbWUsIG5hbWVsZW4pOwoJbmFtZV9kZXB0aCsrOwoJaW5vZGUgPSBnZXRfaW5vZGUyIChpbm8pOwoJbmFtZV9kZXB0aC0tOwoJaWYgKCFvZmZzZXQpIHsKCQlpZiAoIWlub2RlIHx8IHN0cmNtcCAoIi4iLCBuYW1lKSkgewoJCQlnZXRfY3VycmVudF9uYW1lICgpOwoJCQlwcmludGYgKF8oIiVzOiBiYWQgZGlyZWN0b3J5OiAnLicgaXNuJ3QgZmlyc3RcbiIpLAoJCQkJY3VycmVudF9uYW1lKTsKCQkJZXJyb3JzX3VuY29ycmVjdGVkID0gMTsKCQl9IGVsc2UKCQkJcmV0dXJuOwoJfQoJaWYgKG9mZnNldCA9PSBkaXJzaXplKSB7CgkJaWYgKCFpbm9kZSB8fCBzdHJjbXAgKCIuLiIsIG5hbWUpKSB7CgkJCWdldF9jdXJyZW50X25hbWUgKCk7CgkJCXByaW50ZiAoXygiJXM6IGJhZCBkaXJlY3Rvcnk6ICcuLicgaXNuJ3Qgc2Vjb25kXG4iKSwKCQkJCWN1cnJlbnRfbmFtZSk7CgkJCWVycm9yc191bmNvcnJlY3RlZCA9IDE7CgkJfSBlbHNlCgkJCXJldHVybjsKCX0KCWlmICghaW5vZGUpCgkJcmV0dXJuOwoJbmFtZV9kZXB0aCsrOwoJaWYgKGxpc3QpIHsKCQlpZiAodmVyYm9zZSkKCQkJcHJpbnRmICgiJTZkICUwN28gJTNkICIsIGlubywgaW5vZGUtPmlfbW9kZSwKCQkJCWlub2RlLT5pX25saW5rcyk7CgkJZ2V0X2N1cnJlbnRfbmFtZSAoKTsKCQlwcmludGYoIiVzIiwgY3VycmVudF9uYW1lKTsKCQlpZiAoU19JU0RJUiAoaW5vZGUtPmlfbW9kZSkpCgkJCXByaW50ZiAoIjpcbiIpOwoJCWVsc2UKCQkJcHJpbnRmICgiXG4iKTsKCX0KCWNoZWNrX3pvbmVzMiAoaW5vKTsKCWlmIChpbm9kZSAmJiBTX0lTRElSIChpbm9kZS0+aV9tb2RlKSkKCQlyZWN1cnNpdmVfY2hlY2syIChpbm8pOwoJbmFtZV9kZXB0aC0tOwoJcmV0dXJuOwp9CgpzdGF0aWMgdm9pZApyZWN1cnNpdmVfY2hlY2sodW5zaWduZWQgaW50IGlubykgewoJc3RydWN0IG1pbml4X2lub2RlICogZGlyOwoJdW5zaWduZWQgaW50IG9mZnNldDsKCglkaXIgPSBJbm9kZSArIGlubzsKCWlmICghU19JU0RJUihkaXItPmlfbW9kZSkpCgkJZGllKF8oImludGVybmFsIGVycm9yIikpOwoJaWYgKGRpci0+aV9zaXplIDwgMiAqIGRpcnNpemUpIHsKCQlnZXRfY3VycmVudF9uYW1lKCk7CgkJcHJpbnRmKF8oIiVzOiBiYWQgZGlyZWN0b3J5OiBzaXplIDwgMzIiKSwKCQkgICAgICAgY3VycmVudF9uYW1lKTsKCQllcnJvcnNfdW5jb3JyZWN0ZWQgPSAxOwoJfQoJZm9yIChvZmZzZXQgPSAwIDsgb2Zmc2V0IDwgZGlyLT5pX3NpemUgOyBvZmZzZXQgKz0gZGlyc2l6ZSkKCQljaGVja19maWxlKGRpcixvZmZzZXQpOwp9CgpzdGF0aWMgdm9pZApyZWN1cnNpdmVfY2hlY2syICh1bnNpZ25lZCBpbnQgaW5vKSB7CglzdHJ1Y3QgbWluaXgyX2lub2RlICpkaXI7Cgl1bnNpZ25lZCBpbnQgb2Zmc2V0OwoKCWRpciA9IElub2RlMiArIGlubzsKCWlmICghU19JU0RJUiAoZGlyLT5pX21vZGUpKQoJCWRpZShfKCJpbnRlcm5hbCBlcnJvciIpKTsKCWlmIChkaXItPmlfc2l6ZSA8IDIgKiBkaXJzaXplKSB7CgkJZ2V0X2N1cnJlbnRfbmFtZSAoKTsKCQlwcmludGYgKF8oIiVzOiBiYWQgZGlyZWN0b3J5OiBzaXplIDwgMzIiKSwKCQkJY3VycmVudF9uYW1lKTsKCQllcnJvcnNfdW5jb3JyZWN0ZWQgPSAxOwoJfQoJZm9yIChvZmZzZXQgPSAwOyBvZmZzZXQgPCBkaXItPmlfc2l6ZTsgb2Zmc2V0ICs9IGRpcnNpemUpCgkJY2hlY2tfZmlsZTIgKGRpciwgb2Zmc2V0KTsKfQoKc3RhdGljIGludApiYWRfem9uZShpbnQgaSkgewoJY2hhciBidWZmZXJbMTAyNF07CgoJaWYgKEJMT0NLX1NJWkUqaSAhPSBsc2VlayhJTiwgQkxPQ0tfU0laRSppLCBTRUVLX1NFVCkpCgkJZGllKF8oInNlZWsgZmFpbGVkIGluIGJhZF96b25lIikpOwoJcmV0dXJuIChCTE9DS19TSVpFICE9IHJlYWQoSU4sIGJ1ZmZlciwgQkxPQ0tfU0laRSkpOwp9CgpzdGF0aWMgdm9pZApjaGVja19jb3VudHModm9pZCkgewoJaW50IGk7CgoJZm9yIChpPTEgOyBpIDw9IElOT0RFUyA7IGkrKykgewoJCWlmICghaW5vZGVfaW5fdXNlKGkpICYmIElub2RlW2ldLmlfbW9kZSAmJiB3YXJuX21vZGUpIHsKCQkJcHJpbnRmKF8oIklub2RlICVkIG1vZGUgbm90IGNsZWFyZWQuIiksaSk7CgkJCWlmIChhc2soXygiQ2xlYXIiKSwxKSkgewoJCQkJSW5vZGVbaV0uaV9tb2RlID0gMDsKCQkJCWNoYW5nZWQgPSAxOwoJCQl9CgkJfQoJCWlmICghaW5vZGVfY291bnRbaV0pIHsKCQkJaWYgKCFpbm9kZV9pbl91c2UoaSkpCgkJCQljb250aW51ZTsKCQkJcHJpbnRmKF8oIklub2RlICVkIG5vdCB1c2VkLCBtYXJrZWQgdXNlZCBpbiB0aGUgYml0bWFwLiIpLGkpOwoJCQlpZiAoYXNrKF8oIkNsZWFyIiksMSkpCgkJCQl1bm1hcmtfaW5vZGUoaSk7CgkJCWNvbnRpbnVlOwoJCX0KCQlpZiAoIWlub2RlX2luX3VzZShpKSkgewoJCQlwcmludGYoXygiSW5vZGUgJWQgdXNlZCwgbWFya2VkIHVudXNlZCBpbiB0aGUgYml0bWFwLiIpLAoJCQkJaSk7CgkJCWlmIChhc2soXygiU2V0IiksMSkpCgkJCQltYXJrX2lub2RlKGkpOwoJCX0KCQlpZiAoSW5vZGVbaV0uaV9ubGlua3MgIT0gaW5vZGVfY291bnRbaV0pIHsKCQkJcHJpbnRmKF8oIklub2RlICVkIChtb2RlID0gJTA3byksIGlfbmxpbmtzPSVkLCBjb3VudGVkPSVkLiIpLAoJCQkJaSxJbm9kZVtpXS5pX21vZGUsSW5vZGVbaV0uaV9ubGlua3MsaW5vZGVfY291bnRbaV0pOwoJCQlpZiAoYXNrKF8oIlNldCBpX25saW5rcyB0byBjb3VudCIpLDEpKSB7CgkJCQlJbm9kZVtpXS5pX25saW5rcz1pbm9kZV9jb3VudFtpXTsKCQkJCWNoYW5nZWQ9MTsKCQkJfQoJCX0KCX0KCWZvciAoaT1GSVJTVFpPTkUgOyBpIDwgWk9ORVMgOyBpKyspIHsKCQlpZiAoem9uZV9pbl91c2UoaSkgPT0gem9uZV9jb3VudFtpXSkKCQkJY29udGludWU7CgkJaWYgKCF6b25lX2NvdW50W2ldKSB7CgkJCWlmIChiYWRfem9uZShpKSkKCQkJCWNvbnRpbnVlOwoJCQlwcmludGYoXygiWm9uZSAlZDogbWFya2VkIGluIHVzZSwgbm8gZmlsZSB1c2VzIGl0LiIpLGkpOwoJCQlpZiAoYXNrKF8oIlVubWFyayIpLDEpKQoJCQkJdW5tYXJrX3pvbmUoaSk7CgkJCWNvbnRpbnVlOwoJCX0KCQlpZiAoem9uZV9pbl91c2UoaSkpCgkJCXByaW50ZihfKCJab25lICVkOiBpbiB1c2UsIGNvdW50ZWQ9JWRcbiIpLAoJCQkgICAgICAgaSwgem9uZV9jb3VudFtpXSk7CgkJZWxzZQoJCQlwcmludGYoXygiWm9uZSAlZDogbm90IGluIHVzZSwgY291bnRlZD0lZFxuIiksCgkJCSAgICAgICBpLCB6b25lX2NvdW50W2ldKTsKCX0KfQoKc3RhdGljIHZvaWQKY2hlY2tfY291bnRzMiAodm9pZCkgewoJaW50IGk7CgoJZm9yIChpID0gMTsgaSA8PSBJTk9ERVM7IGkrKykgewoJCWlmICghaW5vZGVfaW5fdXNlIChpKSAmJiBJbm9kZTJbaV0uaV9tb2RlICYmIHdhcm5fbW9kZSkgewoJCQlwcmludGYgKF8oIklub2RlICVkIG1vZGUgbm90IGNsZWFyZWQuIiksIGkpOwoJCQlpZiAoYXNrIChfKCJDbGVhciIpLCAxKSkgewoJCQkJSW5vZGUyW2ldLmlfbW9kZSA9IDA7CgkJCQljaGFuZ2VkID0gMTsKCQkJfQoJCX0KCQlpZiAoIWlub2RlX2NvdW50W2ldKSB7CgkJCWlmICghaW5vZGVfaW5fdXNlIChpKSkKCQkJCWNvbnRpbnVlOwoJCQlwcmludGYgKF8oIklub2RlICVkIG5vdCB1c2VkLCBtYXJrZWQgdXNlZCBpbiB0aGUgYml0bWFwLiIpLCBpKTsKCQkJaWYgKGFzayAoXygiQ2xlYXIiKSwgMSkpCgkJCQl1bm1hcmtfaW5vZGUgKGkpOwoJCQljb250aW51ZTsKCQl9CgkJaWYgKCFpbm9kZV9pbl91c2UgKGkpKSB7CgkJCXByaW50ZiAoXygiSW5vZGUgJWQgdXNlZCwgbWFya2VkIHVudXNlZCBpbiB0aGUgYml0bWFwLiIpLCBpKTsKCQkJaWYgKGFzayAoXygiU2V0IiksIDEpKQoJCQkJbWFya19pbm9kZSAoaSk7CgkJfQoJCWlmIChJbm9kZTJbaV0uaV9ubGlua3MgIT0gaW5vZGVfY291bnRbaV0pIHsKCQkJcHJpbnRmIChfKCJJbm9kZSAlZCAobW9kZSA9ICUwN28pLCBpX25saW5rcz0lZCwgY291bnRlZD0lZC4iKSwKCQkJCWksIElub2RlMltpXS5pX21vZGUsIElub2RlMltpXS5pX25saW5rcywgaW5vZGVfY291bnRbaV0pOwoJCQlpZiAoYXNrIChfKCJTZXQgaV9ubGlua3MgdG8gY291bnQiKSwgMSkpIHsKCQkJCUlub2RlMltpXS5pX25saW5rcyA9IGlub2RlX2NvdW50W2ldOwoJCQkJY2hhbmdlZCA9IDE7CgkJCX0KCQl9Cgl9Cglmb3IgKGkgPSBGSVJTVFpPTkU7IGkgPCBaT05FUzsgaSsrKSB7CgkJaWYgKHpvbmVfaW5fdXNlIChpKSA9PSB6b25lX2NvdW50W2ldKQoJCQljb250aW51ZTsKCQlpZiAoIXpvbmVfY291bnRbaV0pIHsKCQkJaWYgKGJhZF96b25lIChpKSkKCQkJCWNvbnRpbnVlOwoJCQlwcmludGYgKF8oIlpvbmUgJWQ6IG1hcmtlZCBpbiB1c2UsIG5vIGZpbGUgdXNlcyBpdC4iKSwKCQkJCWkpOwoJCQlpZiAoYXNrIChfKCJVbm1hcmsiKSwgMSkpCgkJCQl1bm1hcmtfem9uZSAoaSk7CgkJCWNvbnRpbnVlOwoJCX0KCQlpZiAoem9uZV9pbl91c2UgKGkpKQoJCQlwcmludGYgKF8oIlpvbmUgJWQ6IGluIHVzZSwgY291bnRlZD0lZFxuIiksCgkJCQlpLCB6b25lX2NvdW50W2ldKTsKCQllbHNlCgkJCXByaW50ZiAoXygiWm9uZSAlZDogbm90IGluIHVzZSwgY291bnRlZD0lZFxuIiksCgkJCQlpLCB6b25lX2NvdW50W2ldKTsKCX0KfQoKc3RhdGljIHZvaWQKY2hlY2sodm9pZCkgewoJbWVtc2V0KGlub2RlX2NvdW50LDAsKElOT0RFUyArIDEpICogc2l6ZW9mKCppbm9kZV9jb3VudCkpOwoJbWVtc2V0KHpvbmVfY291bnQsMCxaT05FUypzaXplb2YoKnpvbmVfY291bnQpKTsKCWNoZWNrX3pvbmVzKFJPT1RfSU5PKTsKCXJlY3Vyc2l2ZV9jaGVjayhST09UX0lOTyk7CgljaGVja19jb3VudHMoKTsKfQoKc3RhdGljIHZvaWQKY2hlY2syICh2b2lkKSB7CgltZW1zZXQgKGlub2RlX2NvdW50LCAwLCAoSU5PREVTICsgMSkgKiBzaXplb2YgKCppbm9kZV9jb3VudCkpOwoJbWVtc2V0ICh6b25lX2NvdW50LCAwLCBaT05FUyAqIHNpemVvZiAoKnpvbmVfY291bnQpKTsKCWNoZWNrX3pvbmVzMiAoUk9PVF9JTk8pOwoJcmVjdXJzaXZlX2NoZWNrMiAoUk9PVF9JTk8pOwoJY2hlY2tfY291bnRzMiAoKTsKfQoKaW50Cm1haW4oaW50IGFyZ2MsIGNoYXIgKiogYXJndikgewoJc3RydWN0IHRlcm1pb3MgdG1wOwoJaW50IGNvdW50OwoJaW50IHJldGNvZGUgPSAwOwoJY2hhciAqcDsKCglwcm9ncmFtX25hbWUgPSAoYXJnYyAmJiAqYXJndikgPyBhcmd2WzBdIDogImZzY2subWluaXgiOwoJaWYgKChwID0gc3RycmNocihwcm9ncmFtX25hbWUsICcvJykpICE9IE5VTEwpCgkJcHJvZ3JhbV9uYW1lID0gcCsxOwoKCXNldGxvY2FsZShMQ19BTEwsICIiKTsKCWJpbmR0ZXh0ZG9tYWluKFBBQ0tBR0UsIExPQ0FMRURJUik7Cgl0ZXh0ZG9tYWluKFBBQ0tBR0UpOwoKCWlmIChhcmdjID09IDIgJiYKCSAgICAoIXN0cmNtcChhcmd2WzFdLCAiLVYiKSB8fCAhc3RyY21wKGFyZ3ZbMV0sICItLXZlcnNpb24iKSkpIHsKCQlwcmludGYoXygiJXMgKCVzKVxuIiksIHByb2dyYW1fbmFtZSwgUEFDS0FHRV9TVFJJTkcpOwoJCWV4aXQoMCk7Cgl9CgoJaWYgKElOT0RFX1NJWkUgKiBNSU5JWF9JTk9ERVNfUEVSX0JMT0NLICE9IEJMT0NLX1NJWkUpCgkJZGllKF8oImJhZCBpbm9kZSBzaXplIikpOwoJaWYgKElOT0RFX1NJWkUyICogTUlOSVgyX0lOT0RFU19QRVJfQkxPQ0sgIT0gQkxPQ0tfU0laRSkKCQlkaWUoXygiYmFkIHYyIGlub2RlIHNpemUiKSk7CgoJd2hpbGUgKGFyZ2MtLSA+IDEpIHsKCQlhcmd2Kys7CgkJaWYgKGFyZ3ZbMF1bMF0gIT0gJy0nKSB7CgkJCWlmIChkZXZpY2VfbmFtZSkKCQkJCXVzYWdlKCk7CgkJCWVsc2UKCQkJCWRldmljZV9uYW1lID0gYXJndlswXTsKCQl9IGVsc2Ugd2hpbGUgKCorK2FyZ3ZbMF0pCgkJCXN3aXRjaCAoYXJndlswXVswXSkgewoJCQkJY2FzZSAnbCc6IGxpc3Q9MTsgYnJlYWs7CgkJCQljYXNlICdhJzogYXV0b21hdGljPTE7IHJlcGFpcj0xOyBicmVhazsKCQkJCWNhc2UgJ3InOiBhdXRvbWF0aWM9MDsgcmVwYWlyPTE7IGJyZWFrOwoJCQkJY2FzZSAndic6IHZlcmJvc2U9MTsgYnJlYWs7CgkJCQljYXNlICdzJzogc2hvdz0xOyBicmVhazsKCQkJCWNhc2UgJ20nOiB3YXJuX21vZGU9MTsgYnJlYWs7CgkJCQljYXNlICdmJzogZm9yY2U9MTsgYnJlYWs7CgkJCQlkZWZhdWx0OiB1c2FnZSgpOwoJCQl9Cgl9CglpZiAoIWRldmljZV9uYW1lKQoJCXVzYWdlKCk7CgljaGVja19tb3VudCgpOwkJLyogdHJ5aW5nIHRvIGNoZWNrIGEgbW91bnRlZCBmaWxlc3lzdGVtPyAqLwoJaWYgKHJlcGFpciAmJiAhYXV0b21hdGljKSB7CgkJaWYgKCFpc2F0dHkoMCkgfHwgIWlzYXR0eSgxKSkKCQkJZGllKF8oIm5lZWQgdGVybWluYWwgZm9yIGludGVyYWN0aXZlIHJlcGFpcnMiKSk7Cgl9CglJTiA9IG9wZW4oZGV2aWNlX25hbWUscmVwYWlyP09fUkRXUjpPX1JET05MWSk7CglpZiAoSU4gPCAwKQoJCWRpZShfKCJ1bmFibGUgdG8gb3BlbiAnJXMnOiAlcyIpLCBkZXZpY2VfbmFtZSwgc3RyZXJyb3IoZXJybm8pKTsKCWZvciAoY291bnQ9MCA7IGNvdW50PDMgOyBjb3VudCsrKQoJCXN5bmMoKTsKCXJlYWRfc3VwZXJibG9jaygpOwoKCS8qCgkgKiBEZXRlcm1pbmUgd2hldGhlciBvciBub3Qgd2Ugc2hvdWxkIGNvbnRpbnVlIHdpdGggdGhlIGNoZWNraW5nLgoJICogVGhpcyBpcyBiYXNlZCBvbiB0aGUgc3RhdHVzIG9mIHRoZSBmaWxlc3lzdGVtIHZhbGlkIGFuZCBlcnJvcgoJICogZmxhZ3MgYW5kIHdoZXRoZXIgb3Igbm90IHRoZSAtZiBzd2l0Y2ggd2FzIHNwZWNpZmllZCBvbiB0aGUgCgkgKiBjb21tYW5kIGxpbmUuCgkgKi8KCWlmICggIShTdXBlci5zX3N0YXRlICYgTUlOSVhfRVJST1JfRlMpICYmIAoJICAgICAgKFN1cGVyLnNfc3RhdGUgJiBNSU5JWF9WQUxJRF9GUykgJiYgCgkgICAgICAhZm9yY2UgKSB7CgkJaWYgKHJlcGFpcikKCQkJcHJpbnRmKF8oIiVzIGlzIGNsZWFuLCBubyBjaGVjay5cbiIpLCBkZXZpY2VfbmFtZSk7CgkJcmV0dXJuIHJldGNvZGU7Cgl9CgllbHNlIGlmIChmb3JjZSkKCQlwcmludGYoXygiRm9yY2luZyBmaWxlc3lzdGVtIGNoZWNrIG9uICVzLlxuIiksIGRldmljZV9uYW1lKTsKCWVsc2UgaWYgKHJlcGFpcikKCQlwcmludGYoXygiRmlsZXN5c3RlbSBvbiAlcyBpcyBkaXJ0eSwgbmVlZHMgY2hlY2tpbmcuXG4iKSxcCgkJCWRldmljZV9uYW1lKTsKCglyZWFkX3RhYmxlcygpOwoKCS8qIFJlc3RvcmUgdGhlIHRlcm1pbmFsIHN0YXRlIG9uIGZhdGFsIHNpZ25hbHMuCgkgKiBXZSBkb24ndCBkbyB0aGlzIGZvciBTSUdBTFJNLCBTSUdVU1IxIG9yIFNJR1VTUjIuCgkgKi8KCXNpZ25hbChTSUdJTlQsIGZhdGFsc2lnKTsKCXNpZ25hbChTSUdRVUlULCBmYXRhbHNpZyk7CglzaWduYWwoU0lHVEVSTSwgZmF0YWxzaWcpOwoKCWlmIChyZXBhaXIgJiYgIWF1dG9tYXRpYykgewoJCXRjZ2V0YXR0cigwLCZ0ZXJtaW9zKTsKCQl0bXAgPSB0ZXJtaW9zOwoJCXRtcC5jX2xmbGFnICY9IH4oSUNBTk9OfEVDSE8pOwoJCXRjc2V0YXR0cigwLFRDU0FOT1csJnRtcCk7CgkJdGVybWlvc19zZXQgPSAxOwoJfQoKCWlmICh2ZXJzaW9uMikgewoJCWNoZWNrX3Jvb3QyICgpOwoJCWNoZWNrMiAoKTsKCX0gZWxzZSB7CgkJY2hlY2tfcm9vdCgpOwoJCWNoZWNrKCk7Cgl9CglpZiAodmVyYm9zZSkgewoJCWludCBpLCBmcmVlOwoKCQlmb3IgKGk9MSxmcmVlPTAgOyBpIDw9IElOT0RFUyA7IGkrKykKCQkJaWYgKCFpbm9kZV9pbl91c2UoaSkpCgkJCQlmcmVlKys7CgkJcHJpbnRmKF8oIlxuJTZsZCBpbm9kZXMgdXNlZCAoJWxkJSUpXG4iKSwoSU5PREVTLWZyZWUpLAoJCQkxMDAqKElOT0RFUy1mcmVlKS9JTk9ERVMpOwoJCWZvciAoaT1GSVJTVFpPTkUsZnJlZT0wIDsgaSA8IFpPTkVTIDsgaSsrKQoJCQlpZiAoIXpvbmVfaW5fdXNlKGkpKQoJCQkJZnJlZSsrOwoJCXByaW50ZihfKCIlNmxkIHpvbmVzIHVzZWQgKCVsZCUlKVxuIiksKFpPTkVTLWZyZWUpLAoJCQkxMDAqKFpPTkVTLWZyZWUpL1pPTkVTKTsKCQlwcmludGYoXygiXG4lNmQgcmVndWxhciBmaWxlc1xuIgoJCSIlNmQgZGlyZWN0b3JpZXNcbiIKCQkiJTZkIGNoYXJhY3RlciBkZXZpY2UgZmlsZXNcbiIKCQkiJTZkIGJsb2NrIGRldmljZSBmaWxlc1xuIgoJCSIlNmQgbGlua3NcbiIKCQkiJTZkIHN5bWJvbGljIGxpbmtzXG4iCgkJIi0tLS0tLVxuIgoJCSIlNmQgZmlsZXNcbiIpLAoJCXJlZ3VsYXIsZGlyZWN0b3J5LGNoYXJkZXYsYmxvY2tkZXYsCgkJbGlua3MtMipkaXJlY3RvcnkrMSxzeW1saW5rcyx0b3RhbC0yKmRpcmVjdG9yeSsxKTsKCX0KCWlmIChjaGFuZ2VkKSB7CgkJd3JpdGVfdGFibGVzKCk7CgkJcHJpbnRmKF8oCSItLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4iCgkJCSJGSUxFIFNZU1RFTSBIQVMgQkVFTiBDSEFOR0VEXG4iCgkJCSItLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4iKSk7CgkJZm9yIChjb3VudD0wIDsgY291bnQ8MyA7IGNvdW50KyspCgkJCXN5bmMoKTsKCX0KCWVsc2UgaWYgKCByZXBhaXIgKQoJCXdyaXRlX3N1cGVyX2Jsb2NrKCk7CgkKCWlmIChyZXBhaXIgJiYgIWF1dG9tYXRpYykKCQl0Y3NldGF0dHIoMCxUQ1NBTk9XLCZ0ZXJtaW9zKTsKCglpZiAoY2hhbmdlZCkKCSAgICAgIHJldGNvZGUgKz0gMzsKCWlmIChlcnJvcnNfdW5jb3JyZWN0ZWQpCgkgICAgICByZXRjb2RlICs9IDQ7CglyZXR1cm4gcmV0Y29kZTsKfQo=