LyoJJE9wZW5CU0Q6IGNvbmYuYyx2IDEuNTUgMjAwMy8wNi8wMyAxNDoyODoxNiBobyBFeHAgJAkqLwovKgkkRU9NOiBjb25mLmMsdiAxLjQ4IDIwMDAvMTIvMDQgMDI6MDQ6MjkgYW5nZWxvcyBFeHAgJAkqLwoKLyoKICogQ29weXJpZ2h0IChjKSAxOTk4LCAxOTk5LCAyMDAwLCAyMDAxIE5pa2xhcyBIYWxscXZpc3QuICBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBDb3B5cmlnaHQgKGMpIDIwMDAsIDIwMDEsIDIwMDIgSOVrYW4gT2xzc29uLiAgQWxsIHJpZ2h0cyByZXNlcnZlZC4KICoKICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CiAqIG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRoZSBmb2xsb3dpbmcgY29uZGl0aW9ucwogKiBhcmUgbWV0OgogKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAogKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCiAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0CiAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbiB0aGUKICogICAgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlIGRpc3RyaWJ1dGlvbi4KICoKICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQVVUSE9SIGBgQVMgSVMnJyBBTkQgQU5ZIEVYUFJFU1MgT1IKICogSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUwogKiBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFSRSBESVNDTEFJTUVELgogKiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsCiAqIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVAogKiBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCiAqIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQogKiBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUCiAqIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRSBPRgogKiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0ggREFNQUdFLgogKi8KCi8qCiAqIFRoaXMgY29kZSB3YXMgd3JpdHRlbiB1bmRlciBmdW5kaW5nIGJ5IEVyaWNzc29uIFJhZGlvIFN5c3RlbXMuCiAqLwoKI2luY2x1ZGUgPHN5cy9wYXJhbS5oPgojaW5jbHVkZSA8c3lzL21tYW4uaD4KI2luY2x1ZGUgPHN5cy9zb2NrZXQuaD4KI2luY2x1ZGUgPHN5cy9zdGF0Lmg+CiNpbmNsdWRlIDxuZXRpbmV0L2luLmg+CiNpbmNsdWRlIDxhcnBhL2luZXQuaD4KI2luY2x1ZGUgPGN0eXBlLmg+CiNpbmNsdWRlIDxmY250bC5oPgojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlIDx1bmlzdGQuaD4KI2luY2x1ZGUgPGVycm5vLmg+CiNpbmNsdWRlIDxlcnIuaD4KI2luY2x1ZGUgPHN5c2xvZy5oPgoKI2luY2x1ZGUgImNvbmZmaWxlLmgiCiNpbmNsdWRlICJ4bG9nLmgiCgojcHJhZ21hIEdDQyB2aXNpYmlsaXR5IHB1c2goaGlkZGVuKQoKc3RhdGljIHZvaWQgY29uZl9sb2FkX2RlZmF1bHRzKHZvaWQpOwpzdGF0aWMgaW50IGNvbmZfc2V0KGludCAsIGNoYXIgKiwgY2hhciAqLCBjaGFyICosIAoJY2hhciAqLCBpbnQgLCBpbnQgKTsKCnN0cnVjdCBjb25mX3RyYW5zIHsKCVRBSUxRX0VOVFJZIChjb25mX3RyYW5zKSBsaW5rOwoJaW50IHRyYW5zOwoJZW51bSBjb25mX29wIHsgQ09ORl9TRVQsIENPTkZfUkVNT1ZFLCBDT05GX1JFTU9WRV9TRUNUSU9OIH0gb3A7CgljaGFyICpzZWN0aW9uOwoJY2hhciAqYXJnOwoJY2hhciAqdGFnOwoJY2hhciAqdmFsdWU7CglpbnQgb3ZlcnJpZGU7CglpbnQgaXNfZGVmYXVsdDsKfTsKClRBSUxRX0hFQUQgKGNvbmZfdHJhbnNfaGVhZCwgY29uZl90cmFucykgY29uZl90cmFuc19xdWV1ZTsKCi8qCiAqIFJhZGl4LTY0IEVuY29kaW5nLgogKi8Kc3RhdGljIGNvbnN0IHVfaW50OF90IGJpbjJhc2NbXQogID0gIkFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXowMTIzNDU2Nzg5Ky8iOwoKc3RhdGljIGNvbnN0IHVfaW50OF90IGFzYzJiaW5bXSA9CnsKICAyNTUsIDI1NSwgMjU1LCAyNTUsIDI1NSwgMjU1LCAyNTUsIDI1NSwKICAyNTUsIDI1NSwgMjU1LCAyNTUsIDI1NSwgMjU1LCAyNTUsIDI1NSwKICAyNTUsIDI1NSwgMjU1LCAyNTUsIDI1NSwgMjU1LCAyNTUsIDI1NSwKICAyNTUsIDI1NSwgMjU1LCAyNTUsIDI1NSwgMjU1LCAyNTUsIDI1NSwKICAyNTUsIDI1NSwgMjU1LCAyNTUsIDI1NSwgMjU1LCAyNTUsIDI1NSwKICAyNTUsIDI1NSwgMjU1LCAgNjIsIDI1NSwgMjU1LCAyNTUsICA2MywKICAgNTIsICA1MywgIDU0LCAgNTUsICA1NiwgIDU3LCAgNTgsICA1OSwKICAgNjAsICA2MSwgMjU1LCAyNTUsIDI1NSwgMjU1LCAyNTUsIDI1NSwKICAyNTUsICAgMCwgICAxLCAgIDIsICAgMywgICA0LCAgIDUsICAgNiwKICAgIDcsICAgOCwgICA5LCAgMTAsICAxMSwgIDEyLCAgMTMsICAxNCwKICAgMTUsICAxNiwgIDE3LCAgMTgsICAxOSwgIDIwLCAgMjEsICAyMiwKICAgMjMsICAyNCwgIDI1LCAyNTUsIDI1NSwgMjU1LCAyNTUsIDI1NSwKICAyNTUsICAyNiwgIDI3LCAgMjgsICAyOSwgIDMwLCAgMzEsICAzMiwKICAgMzMsICAzNCwgIDM1LCAgMzYsICAzNywgIDM4LCAgMzksICA0MCwKICAgNDEsICA0MiwgIDQzLCAgNDQsICA0NSwgIDQ2LCAgNDcsICA0OCwKICAgNDksICA1MCwgIDUxLCAyNTUsIDI1NSwgMjU1LCAyNTUsIDI1NQp9OwoKc3RydWN0IGNvbmZfYmluZGluZyB7CiAgTElTVF9FTlRSWSAoY29uZl9iaW5kaW5nKSBsaW5rOwogIGNoYXIgKnNlY3Rpb247CiAgY2hhciAqYXJnOwogIGNoYXIgKnRhZzsKICBjaGFyICp2YWx1ZTsKICBpbnQgaXNfZGVmYXVsdDsKfTsKCmNoYXIgKmNvbmZfcGF0aDsKTElTVF9IRUFEIChjb25mX2JpbmRpbmdzLCBjb25mX2JpbmRpbmcpIGNvbmZfYmluZGluZ3NbMjU2XTsKCnN0YXRpYyBjaGFyICpjb25mX2FkZHI7CgpzdGF0aWMgX19pbmxpbmVfXyB1X2ludDhfdApjb25mX2hhc2goY2hhciAqcykKewoJdV9pbnQ4X3QgaGFzaCA9IDA7CgoJd2hpbGUgKCpzKSB7CgkJaGFzaCA9ICgoaGFzaCA8PCAxKSB8IChoYXNoID4+IDcpKSBeIHRvbG93ZXIgKCpzKTsKCQlzKys7Cgl9CglyZXR1cm4gaGFzaDsKfQoKLyoKICogSW5zZXJ0IGEgdGFnLXZhbHVlIGNvbWJpbmF0aW9uIGZyb20gTElORSAodGhlIGVxdWFsIHNpZ24gaXMgYXQgUE9TKQogKi8Kc3RhdGljIGludApjb25mX3JlbW92ZV9ub3coY2hhciAqc2VjdGlvbiwgY2hhciAqdGFnKQp7CglzdHJ1Y3QgY29uZl9iaW5kaW5nICpjYiwgKm5leHQ7CgoJY2IgPSBMSVNUX0ZJUlNUKCZjb25mX2JpbmRpbmdzW2NvbmZfaGFzaCAoc2VjdGlvbildKTsKCWZvciAoOyBjYjsgY2IgPSBuZXh0KSB7CgkJbmV4dCA9IExJU1RfTkVYVChjYiwgbGluayk7CgkJaWYgKHN0cmNhc2VjbXAoY2ItPnNlY3Rpb24sIHNlY3Rpb24pID09IDAKCQkJCSYmIHN0cmNhc2VjbXAoY2ItPnRhZywgdGFnKSA9PSAwKSB7CgkJCUxJU1RfUkVNT1ZFKGNiLCBsaW5rKTsKCQkJeGxvZyhMT0dfSU5GTywiWyVzXTolcy0+JXMgcmVtb3ZlZCIsIHNlY3Rpb24sIHRhZywgY2ItPnZhbHVlKTsKCQkJZnJlZShjYi0+c2VjdGlvbik7CgkJCWZyZWUoY2ItPmFyZyk7CgkJCWZyZWUoY2ItPnRhZyk7CgkJCWZyZWUoY2ItPnZhbHVlKTsKCQkJZnJlZShjYik7CgkJCXJldHVybiAwOwoJCX0KCX0KCXJldHVybiAxOwp9CgpzdGF0aWMgaW50CmNvbmZfcmVtb3ZlX3NlY3Rpb25fbm93KGNoYXIgKnNlY3Rpb24pCnsKICBzdHJ1Y3QgY29uZl9iaW5kaW5nICpjYiwgKm5leHQ7CiAgaW50IHVuc2VlbiA9IDE7CgoJY2IgPSBMSVNUX0ZJUlNUKCZjb25mX2JpbmRpbmdzW2NvbmZfaGFzaCAoc2VjdGlvbildKTsKCWZvciAoOyBjYjsgY2IgPSBuZXh0KSB7CgkJbmV4dCA9IExJU1RfTkVYVChjYiwgbGluayk7CgkJaWYgKHN0cmNhc2VjbXAoY2ItPnNlY3Rpb24sIHNlY3Rpb24pID09IDApIHsKCQkJdW5zZWVuID0gMDsKCQkJTElTVF9SRU1PVkUoY2IsIGxpbmspOwoJCQl4bG9nKExPR19JTkZPLCAiWyVzXTolcy0+JXMgcmVtb3ZlZCIsIHNlY3Rpb24sIGNiLT50YWcsIGNiLT52YWx1ZSk7CgkJCWZyZWUoY2ItPnNlY3Rpb24pOwoJCQlmcmVlKGNiLT5hcmcpOwoJCQlmcmVlKGNiLT50YWcpOwoJCQlmcmVlKGNiLT52YWx1ZSk7CgkJCWZyZWUoY2IpOwoJCQl9CgkJfQoJcmV0dXJuIHVuc2VlbjsKfQoKLyoKICogSW5zZXJ0IGEgdGFnLXZhbHVlIGNvbWJpbmF0aW9uIGZyb20gTElORSAodGhlIGVxdWFsIHNpZ24gaXMgYXQgUE9TKQogKiBpbnRvIFNFQ1RJT04gb2Ygb3VyIGNvbmZpZ3VyYXRpb24gZGF0YWJhc2UuCiAqLwpzdGF0aWMgaW50CmNvbmZfc2V0X25vdyhjaGFyICpzZWN0aW9uLCBjaGFyICphcmcsIGNoYXIgKnRhZywgCgljaGFyICp2YWx1ZSwgaW50IG92ZXJyaWRlLCBpbnQgaXNfZGVmYXVsdCkKewoJc3RydWN0IGNvbmZfYmluZGluZyAqbm9kZSA9IDA7CgoJaWYgKG92ZXJyaWRlKQoJCWNvbmZfcmVtb3ZlX25vdyhzZWN0aW9uLCB0YWcpOwoJZWxzZSBpZiAoY29uZl9nZXRfc2VjdGlvbihzZWN0aW9uLCBhcmcsIHRhZykpIHsKCQlpZiAoIWlzX2RlZmF1bHQpIHsKCQkJeGxvZyhMT0dfSU5GTywgImNvbmZfc2V0OiBkdXBsaWNhdGUgdGFnIFslc106JXMsIGlnbm9yaW5nLi4uXG4iLCAKCQkJCXNlY3Rpb24sIHRhZyk7CgkJfQoJCXJldHVybiAxOwoJfQoJbm9kZSA9IGNhbGxvYygxLCBzaXplb2YgKm5vZGUpOwoJaWYgKCFub2RlKSB7CgkJeGxvZ193YXJuKCJjb25mX3NldDogY2FsbG9jICgxLCAlbHUpIGZhaWxlZCIsICh1bnNpZ25lZCBsb25nKXNpemVvZiAqbm9kZSk7CgkJcmV0dXJuIDE7Cgl9Cglub2RlLT5zZWN0aW9uID0gc3RyZHVwKHNlY3Rpb24pOwoJaWYgKGFyZykKCQlub2RlLT5hcmcgPSBzdHJkdXAoYXJnKTsKCW5vZGUtPnRhZyA9IHN0cmR1cCh0YWcpOwoJbm9kZS0+dmFsdWUgPSBzdHJkdXAodmFsdWUpOwoJbm9kZS0+aXNfZGVmYXVsdCA9IGlzX2RlZmF1bHQ7CgoJTElTVF9JTlNFUlRfSEVBRCgmY29uZl9iaW5kaW5nc1tjb25mX2hhc2ggKHNlY3Rpb24pXSwgbm9kZSwgbGluayk7CglyZXR1cm4gMDsKfQoKLyoKICogUGFyc2UgdGhlIGxpbmUgTElORSBvZiBTWiBieXRlcy4gIFNraXAgQ29tbWVudHMsIHJlY29nbml6ZSBzZWN0aW9uCiAqIGhlYWRlcnMgYW5kIGZlZWQgdGFnLXZhbHVlIHBhaXJzIGludG8gb3VyIGNvbmZpZ3VyYXRpb24gZGF0YWJhc2UuCiAqLwpzdGF0aWMgdm9pZApjb25mX3BhcnNlX2xpbmUoaW50IHRyYW5zLCBjaGFyICpsaW5lLCBzaXplX3Qgc3opCnsKCWNoYXIgKnZhbCwgKnB0cjsKCXNpemVfdCBpLCB2YWxzaXplOwoJc2l6ZV90IGo7CglzdGF0aWMgY2hhciAqc2VjdGlvbiA9IDA7CglzdGF0aWMgY2hhciAqYXJnID0gMDsKCXN0YXRpYyBpbnQgbG4gPSAwOwoKCS8qIExpbmVzIHN0YXJ0aW5nIHdpdGggJyMnIG9yICc7JyBhcmUgY29tbWVudHMuICAqLwoJbG4rKzsKCS8qIElnbm9yZSBibGFuayBsaW5lcyAqLwoJaWYgKCpsaW5lID09ICdcMCcpCgkJcmV0dXJuOwoKCS8qIFN0cmlwIG9mZiBhbnkgbGVhZGluZyBibGFua3MgKi8KCXdoaWxlIChpc2JsYW5rKCpsaW5lKSkgCgkJbGluZSsrOwoKCWlmICgqbGluZSA9PSAnIycgfHwgKmxpbmUgPT0gJzsnKQoJCXJldHVybjsKCgkvKiAnW3NlY3Rpb25dJyBwYXJzaW5nLi4uICAqLwoJaWYgKCpsaW5lID09ICdbJykgewoJCWxpbmUrKzsKCQkvKiBTdHJpcCBvZmYgYW55IGJsYW5rcyBhZnRlciAnWycgKi8KCQl3aGlsZSAoaXNibGFuaygqbGluZSkpIAoJCQlsaW5lKys7CgkJZm9yIChpID0gMDsgaSA8IHN6OyBpKyspIHsKCQkJaWYgKGxpbmVbaV0gPT0gJ10nKSB7CgkJCQlicmVhazsKCQkJfQoJCX0KCQlpZiAoc2VjdGlvbikKCQkJZnJlZShzZWN0aW9uKTsKCQlpZiAoaSA9PSBzeikgewoJCQl4bG9nX3dhcm4oImNvbmZpZyBmaWxlIGVycm9yOiBsaW5lICVkOiAiCiAJCQkJIm5vbi1tYXRjaGVkICddJywgaWdub3JpbmcgdW50aWwgbmV4dCBzZWN0aW9uIiwgbG4pOwoJCQlzZWN0aW9uID0gMDsKCQkJcmV0dXJuOwoJCX0KCQkvKiBTdHJpcCBvZmYgYW55IGJsYW5rcyBiZWZvcmUgJ10nICovCgkJdmFsID0gbGluZTsKCQlqPTA7CgkJd2hpbGUgKCp2YWwgJiYgIWlzYmxhbmsoKnZhbCkpIAoJCQl2YWwrKywgaisrOwoJCWlmICgqdmFsKQoJCQlpID0gajsKCQlzZWN0aW9uID0gbWFsbG9jKGkrMSk7CgkJaWYgKCFzZWN0aW9uKSB7CgkJCXhsb2dfd2FybigiY29uZl9wYXJzZV9saW5lOiAlZDogbWFsbG9jICglbHUpIGZhaWxlZCIsIGxuLAoJCQkJCQkodW5zaWduZWQgbG9uZylpKTsKCQkJcmV0dXJuOwoJCX0KCQlzdHJuY3B5KHNlY3Rpb24sIGxpbmUsIGkpOwoJCXNlY3Rpb25baV0gPSAnXDAnOwoKCQlpZiAoYXJnKSAKCQkJZnJlZShhcmcpOwoJCWFyZyA9IDA7CgoJCXB0ciA9IHN0cmNocih2YWwsICciJyk7CgkJaWYgKHB0ciA9PSBOVUxMKQoJCQlyZXR1cm47CgkJbGluZSA9ICsrcHRyOwoJCXdoaWxlICgqcHRyICYmICpwdHIgIT0gJyInICYmICpwdHIgIT0gJ10nKQoJCQlwdHIrKzsKCQlpZiAoKnB0ciA9PSAnXDAnIHx8ICpwdHIgPT0gJ10nKSB7CgkJCXhsb2dfd2FybigiY29uZmlnIGZpbGUgZXJyb3I6IGxpbmUgJWQ6ICIKIAkJCQkibm9uLW1hdGNoZWQgJ1wiJywgaWdub3JpbmcgdW50aWwgbmV4dCBzZWN0aW9uIiwgbG4pOwoJCX0gIGVsc2UgewoJCQkqcHRyID0gJ1wwJzsKCQkJYXJnID0gc3RyZHVwKGxpbmUpOwoJCQlpZiAoIWFyZykgCgkJCQl4bG9nX3dhcm4oImNvbmZfcGFyc2VfbGluZTogJWQ6IG1hbGxvYyBhcmcgZmFpbGVkIiwgbG4pOwoJCX0KCQlyZXR1cm47Cgl9CgoJLyogRGVhbCB3aXRoIGFzc2lnbm1lbnRzLiAgKi8KCWZvciAoaSA9IDA7IGkgPCBzejsgaSsrKSB7CgkJaWYgKGxpbmVbaV0gPT0gJz0nKSB7CgkJCS8qIElmIG5vIHNlY3Rpb24sIHdlIGFyZSBpZ25vcmluZyB0aGUgbGluZXMuICAqLwoJCQlpZiAoIXNlY3Rpb24pIHsKCQkJeGxvZ193YXJuKCJjb25maWcgZmlsZSBlcnJvcjogbGluZSAlZDogIgoJCQkJImlnbm9yaW5nIGxpbmUgZHVlIHRvIG5vIHNlY3Rpb24iLCBsbik7CgkJCQlyZXR1cm47CgkJCX0KCQkJbGluZVtzdHJjc3BuIChsaW5lLCAiIFx0PSIpXSA9ICdcMCc7CgkJCXZhbCA9IGxpbmUgKyBpICsgMSArIHN0cnNwbiAobGluZSArIGkgKyAxLCAiIFx0Iik7CgkJCXZhbHNpemUgPSAwOwoJCQl3aGlsZSAodmFsW3ZhbHNpemUrK10pOwoKCQkJLyogU2tpcCB0cmFpbGluZyBzcGFjZXMgYW5kIGNvbW1lbnRzICovCgkJCWZvciAoaiA9IDA7IGogPCB2YWxzaXplOyBqKyspIHsKCQkJCWlmICh2YWxbal0gPT0gJyMnIHx8IHZhbFtqXSA9PSAnOycgfHwgaXNzcGFjZSh2YWxbal0pKSB7CgkJCQkJdmFsW2pdID0gJ1wwJzsKCQkJCQlicmVhazsKCQkJCX0KCQkJfQoJCQkvKiBYWFggUGVyaGFwcyBzaG91bGQgd2Ugbm90IGlnbm9yZSBlcnJvcnM/ICAqLwoJCQljb25mX3NldCh0cmFucywgc2VjdGlvbiwgYXJnLCBsaW5lLCB2YWwsIDAsIDApOwoJCQlyZXR1cm47CgkJfQoJfQoJLyogT3RoZXIgbm9uLWVtcHR5IGxpbmVzIGFyZSB3ZWlyZC4gICovCglpID0gc3Ryc3BuKGxpbmUsICIgXHQiKTsKCWlmIChsaW5lW2ldKQoJCXhsb2dfd2FybigiY29uZmlnIGZpbGUgZXJyb3I6IGxpbmUgJWQ6IiwgbG4pOwoKCXJldHVybjsKfQoKLyogUGFyc2UgdGhlIG1hcHBlZCBjb25maWd1cmF0aW9uIGZpbGUuICAqLwpzdGF0aWMgdm9pZApjb25mX3BhcnNlKGludCB0cmFucywgY2hhciAqYnVmLCBzaXplX3Qgc3opCnsKCWNoYXIgKmNwID0gYnVmOwoJY2hhciAqYnVmZW5kID0gYnVmICsgc3o7CgljaGFyICpsaW5lOwoKCWxpbmUgPSBjcDsKCXdoaWxlIChjcCA8IGJ1ZmVuZCkgewoJCWlmICgqY3AgPT0gJ1xuJykgewoJCQkvKiBDaGVjayBmb3IgZXNjYXBlZCBuZXdsaW5lcy4gICovCgkJCWlmIChjcCA+IGJ1ZiAmJiAqKGNwIC0gMSkgPT0gJ1xcJykKCQkJCSooY3AgLSAxKSA9ICpjcCA9ICcgJzsKCQkJZWxzZSB7CgkJCQkqY3AgPSAnXDAnOwoJCQkJY29uZl9wYXJzZV9saW5lKHRyYW5zLCBsaW5lLCBjcCAtIGxpbmUpOwoJCQkJbGluZSA9IGNwICsgMTsKCQkJfQoJCX0KCQljcCsrOwoJfQoJaWYgKGNwICE9IGxpbmUpCgkJeGxvZ193YXJuKCJjb25mX3BhcnNlOiBsYXN0IGxpbmUgbm9uLXRlcm1pbmF0ZWQsIGlnbm9yZWQuIik7Cn0KCnN0YXRpYyB2b2lkCmNvbmZfbG9hZF9kZWZhdWx0cyh2b2lkKQp7CgkvKiBObyBkZWZhdWx0cyAqLwoJcmV0dXJuOwp9Cgp2b2lkCmNvbmZfaW5pdCAodm9pZCkKewoJdW5zaWduZWQgaW50IGk7CgoJZm9yIChpID0gMDsgaSA8IHNpemVvZiBjb25mX2JpbmRpbmdzIC8gc2l6ZW9mIGNvbmZfYmluZGluZ3NbMF07IGkrKykKCQlMSVNUX0lOSVQgKCZjb25mX2JpbmRpbmdzW2ldKTsKCglUQUlMUV9JTklUICgmY29uZl90cmFuc19xdWV1ZSk7Cgljb25mX3JlaW5pdCgpOwp9CgovKiBPcGVuIHRoZSBjb25maWcgZmlsZSBhbmQgbWFwIGl0IGludG8gb3VyIGFkZHJlc3Mgc3BhY2UsIHRoZW4gcGFyc2UgaXQuICAqLwp2b2lkCmNvbmZfcmVpbml0KHZvaWQpCnsKCXN0cnVjdCBjb25mX2JpbmRpbmcgKmNiID0gMDsKCWludCBmZCwgdHJhbnM7Cgl1bnNpZ25lZCBpbnQgaTsKCXNpemVfdCBzejsKCWNoYXIgKm5ld19jb25mX2FkZHIgPSAwOwoJc3RydWN0IHN0YXQgc2I7CgoJaWYgKChzdGF0IChjb25mX3BhdGgsICZzYikgPT0gMCkgfHwgKGVycm5vICE9IEVOT0VOVCkpIHsKCQlzeiA9IHNiLnN0X3NpemU7CgkJZmQgPSBvcGVuIChjb25mX3BhdGgsIE9fUkRPTkxZLCAwKTsKCQlpZiAoZmQgPT0gLTEpIHsKCQkJeGxvZ193YXJuKCJjb25mX3JlaW5pdDogb3BlbiAoXCIlc1wiLCBPX1JET05MWSkgZmFpbGVkIiwgY29uZl9wYXRoKTsKCQkJcmV0dXJuOwoJCX0KCgkJbmV3X2NvbmZfYWRkciA9IG1hbGxvYyhzeik7CgkJaWYgKCFuZXdfY29uZl9hZGRyKSB7CgkJCXhsb2dfd2FybigiY29uZl9yZWluaXQ6IG1hbGxvYyAoJWx1KSBmYWlsZWQiLCAodW5zaWduZWQgbG9uZylzeik7CgkJCWdvdG8gZmFpbDsKCQl9CgoJCS8qIFhYWCBJIGFzc3VtZSBzaG9ydCByZWFkcyB3b24ndCBoYXBwZW4gaGVyZS4gICovCgkJaWYgKHJlYWQgKGZkLCBuZXdfY29uZl9hZGRyLCBzeikgIT0gKGludClzeikgewoJCQl4bG9nX3dhcm4oImNvbmZfcmVpbml0OiByZWFkICglZCwgJXAsICVsdSkgZmFpbGVkIiwKICAgCQkJCWZkLCBuZXdfY29uZl9hZGRyLCAodW5zaWduZWQgbG9uZylzeik7CgkJCWdvdG8gZmFpbDsKCQl9CgkJY2xvc2UoZmQpOwoKCQl0cmFucyA9IGNvbmZfYmVnaW4oKTsKCQkvKiBYWFggU2hvdWxkIHdlIG5vdCBjYXJlIGFib3V0IGVycm9ycyBhbmQgcm9sbGJhY2s/ICAqLwoJCWNvbmZfcGFyc2UodHJhbnMsIG5ld19jb25mX2FkZHIsIHN6KTsKCX0KCWVsc2UKCQl0cmFucyA9IGNvbmZfYmVnaW4oKTsKCgkvKiBMb2FkIGRlZmF1bHQgY29uZmlndXJhdGlvbiB2YWx1ZXMuICAqLwoJY29uZl9sb2FkX2RlZmF1bHRzKCk7CgoJLyogRnJlZSBwb3RlbnRpYWwgZXhpc3RpbmcgY29uZmlndXJhdGlvbi4gICovCglpZiAoY29uZl9hZGRyKSB7CgkJZm9yIChpID0gMDsgaSA8IHNpemVvZiBjb25mX2JpbmRpbmdzIC8gc2l6ZW9mIGNvbmZfYmluZGluZ3NbMF07IGkrKykgewoJCQljYiA9IExJU1RfRklSU1QgKCZjb25mX2JpbmRpbmdzW2ldKTsKCQkJZm9yICg7IGNiOyBjYiA9IExJU1RfRklSU1QgKCZjb25mX2JpbmRpbmdzW2ldKSkKCQkJCWNvbmZfcmVtb3ZlX25vdyhjYi0+c2VjdGlvbiwgY2ItPnRhZyk7CgkJfQoJCWZyZWUgKGNvbmZfYWRkcik7Cgl9CgoJY29uZl9lbmQodHJhbnMsIDEpOwoJY29uZl9hZGRyID0gbmV3X2NvbmZfYWRkcjsKCXJldHVybjsKCmZhaWw6CglpZiAobmV3X2NvbmZfYWRkcikKCQlmcmVlKG5ld19jb25mX2FkZHIpOwoJY2xvc2UgKGZkKTsKfQoKLyoKICogUmV0dXJuIHRoZSBudW1lcmljIHZhbHVlIGRlbm90ZWQgYnkgVEFHIGluIHNlY3Rpb24gU0VDVElPTiBvciBERUYKICogaWYgdGhhdCB0YWcgZG9lcyBub3QgZXhpc3QuCiAqLwppbnQKY29uZl9nZXRfbnVtKGNoYXIgKnNlY3Rpb24sIGNoYXIgKnRhZywgaW50IGRlZikKewoJY2hhciAqdmFsdWUgPSBjb25mX2dldF9zdHIoc2VjdGlvbiwgdGFnKTsKCglpZiAodmFsdWUpCgkJcmV0dXJuIGF0b2kodmFsdWUpOwoKCXJldHVybiBkZWY7Cn0KCi8qIFZhbGlkYXRlIFggYWNjb3JkaW5nIHRvIHRoZSByYW5nZSBkZW5vdGVkIGJ5IFRBRyBpbiBzZWN0aW9uIFNFQ1RJT04uICAqLwppbnQKY29uZl9tYXRjaF9udW0oY2hhciAqc2VjdGlvbiwgY2hhciAqdGFnLCBpbnQgeCkKewoJY2hhciAqdmFsdWUgPSBjb25mX2dldF9zdHIgKHNlY3Rpb24sIHRhZyk7CglpbnQgdmFsLCBtaW4sIG1heCwgbjsKCglpZiAoIXZhbHVlKQoJCXJldHVybiAwOwoJbiA9IHNzY2FuZiAodmFsdWUsICIlZCwlZDolZCIsICZ2YWwsICZtaW4sICZtYXgpOwoJc3dpdGNoIChuKSB7CgljYXNlIDE6CgkJeGxvZyhMT0dfSU5GTywgImNvbmZfbWF0Y2hfbnVtOiAlczolcyAlZD09JWQ/Iiwgc2VjdGlvbiwgdGFnLCB2YWwsIHgpOwoJCXJldHVybiB4ID09IHZhbDsKCWNhc2UgMzoKCQl4bG9nKExPR19JTkZPLCAiY29uZl9tYXRjaF9udW06ICVzOiVzICVkPD0lZDw9JWQ/Iiwgc2VjdGlvbiwgCgkJCXRhZywgbWluLCB4LCBtYXgpOwoJCXJldHVybiBtaW4gPD0geCAmJiBtYXggPj0geDsKCWRlZmF1bHQ6CgkJeGxvZyhMT0dfSU5GTywgImNvbmZfbWF0Y2hfbnVtOiBzZWN0aW9uICVzIHRhZyAlczogaW52YWxpZCBudW1iZXIgc3BlYyAlcyIsCgkJCXNlY3Rpb24sIHRhZywgdmFsdWUpOwoJfQoJcmV0dXJuIDA7Cn0KCi8qIFJldHVybiB0aGUgc3RyaW5nIHZhbHVlIGRlbm90ZWQgYnkgVEFHIGluIHNlY3Rpb24gU0VDVElPTi4gICovCmNoYXIgKgpjb25mX2dldF9zdHIoY2hhciAqc2VjdGlvbiwgY2hhciAqdGFnKQp7CglzdHJ1Y3QgY29uZl9iaW5kaW5nICpjYjsKCgljYiA9IExJU1RfRklSU1QgKCZjb25mX2JpbmRpbmdzW2NvbmZfaGFzaCAoc2VjdGlvbildKTsKCWZvciAoOyBjYjsgY2IgPSBMSVNUX05FWFQgKGNiLCBsaW5rKSkgewoJCWlmIChzdHJjYXNlY21wIChzZWN0aW9uLCBjYi0+c2VjdGlvbikgPT0gMAoJCQkJJiYgc3RyY2FzZWNtcCAodGFnLCBjYi0+dGFnKSA9PSAwKQoJCQlyZXR1cm4gY2ItPnZhbHVlOwoJfQoJcmV0dXJuIDA7Cn0KLyoKICogRmluZCBhIHNlY3Rpb24gdGhhdCBtYXkgb3IgbWF5IG5vdCBoYXZlIGFuIGFyZ3VtZW50CiAqLwpjaGFyICoKY29uZl9nZXRfc2VjdGlvbihjaGFyICpzZWN0aW9uLCBjaGFyICphcmcsIGNoYXIgKnRhZykKewoJc3RydWN0IGNvbmZfYmluZGluZyAqY2I7CgoJY2IgPSBMSVNUX0ZJUlNUICgmY29uZl9iaW5kaW5nc1tjb25mX2hhc2ggKHNlY3Rpb24pXSk7Cglmb3IgKDsgY2I7IGNiID0gTElTVF9ORVhUIChjYiwgbGluaykpIHsKCQlpZiAoc3RyY2FzZWNtcChzZWN0aW9uLCBjYi0+c2VjdGlvbikgIT0gMCkKCQkJY29udGludWU7CgkJaWYgKGFyZyAmJiBzdHJjYXNlY21wKGFyZywgY2ItPmFyZykgIT0gMCkKCQkJY29udGludWU7CgkJaWYgKHN0cmNhc2VjbXAodGFnLCBjYi0+dGFnKSAhPSAwKQoJCQljb250aW51ZTsKCQlyZXR1cm4gY2ItPnZhbHVlOwoJfQoJcmV0dXJuIDA7Cn0KCi8qCiAqIEJ1aWxkIGEgbGlzdCBvZiBzdHJpbmcgdmFsdWVzIG91dCBvZiB0aGUgY29tbWEgc2VwYXJhdGVkIHZhbHVlIGRlbm90ZWQgYnkKICogVEFHIGluIFNFQ1RJT04uCiAqLwpzdHJ1Y3QgY29uZl9saXN0ICoKY29uZl9nZXRfbGlzdChjaGFyICpzZWN0aW9uLCBjaGFyICp0YWcpCnsKCWNoYXIgKmxpc3RzdHIgPSAwLCAqcCwgKmZpZWxkLCAqdDsKCXN0cnVjdCBjb25mX2xpc3QgKmxpc3QgPSAwOwoJc3RydWN0IGNvbmZfbGlzdF9ub2RlICpub2RlOwoKCWxpc3QgPSBtYWxsb2MgKHNpemVvZiAqbGlzdCk7CglpZiAoIWxpc3QpCgkJZ290byBjbGVhbnVwOwoJVEFJTFFfSU5JVCAoJmxpc3QtPmZpZWxkcyk7CglsaXN0LT5jbnQgPSAwOwoJbGlzdHN0ciA9IGNvbmZfZ2V0X3N0cihzZWN0aW9uLCB0YWcpOwoJaWYgKCFsaXN0c3RyKQoJCWdvdG8gY2xlYW51cDsKCWxpc3RzdHIgPSBzdHJkdXAgKGxpc3RzdHIpOwoJaWYgKCFsaXN0c3RyKQoJCWdvdG8gY2xlYW51cDsKCXAgPSBsaXN0c3RyOwoJd2hpbGUgKChmaWVsZCA9IHN0cnNlcCAoJnAsICIsIikpICE9IE5VTEwpIHsKCQkvKiBTa2lwIGxlYWRpbmcgd2hpdGVzcGFjZSAqLwoJCXdoaWxlIChpc3NwYWNlICgqZmllbGQpKQoJCQlmaWVsZCsrOwoJCS8qIFNraXAgdHJhaWxpbmcgd2hpdGVzcGFjZSAqLwoJCWlmIChwKSB7CgkJCWZvciAodCA9IHAgLSAxOyB0ID4gZmllbGQgJiYgaXNzcGFjZSAoKnQpOyB0LS0pCgkJCQkqdCA9ICdcMCc7CgkJfQoJCWlmICgqZmllbGQgPT0gJ1wwJykgewoJCQl4bG9nKExPR19JTkZPLCAiY29uZl9nZXRfbGlzdDogZW1wdHkgZmllbGQsIGlnbm9yaW5nLi4uIik7CgkJCWNvbnRpbnVlOwoJCX0KCQlsaXN0LT5jbnQrKzsKCQlub2RlID0gY2FsbG9jICgxLCBzaXplb2YgKm5vZGUpOwoJCWlmICghbm9kZSkKCQkJZ290byBjbGVhbnVwOwoJCW5vZGUtPmZpZWxkID0gc3RyZHVwIChmaWVsZCk7CgkJaWYgKCFub2RlLT5maWVsZCkgewoJCQlmcmVlKG5vZGUpOwoJCQlnb3RvIGNsZWFudXA7CgkJfQoJCVRBSUxRX0lOU0VSVF9UQUlMICgmbGlzdC0+ZmllbGRzLCBub2RlLCBsaW5rKTsKCX0KCWZyZWUgKGxpc3RzdHIpOwoJcmV0dXJuIGxpc3Q7CgpjbGVhbnVwOgoJaWYgKGxpc3QpCgkJY29uZl9mcmVlX2xpc3QobGlzdCk7CglpZiAobGlzdHN0cikKCQlmcmVlKGxpc3RzdHIpOwoJcmV0dXJuIDA7Cn0KCnN0cnVjdCBjb25mX2xpc3QgKgpjb25mX2dldF90YWdfbGlzdChjaGFyICpzZWN0aW9uLCBjaGFyICphcmcpCnsKCXN0cnVjdCBjb25mX2xpc3QgKmxpc3QgPSAwOwoJc3RydWN0IGNvbmZfbGlzdF9ub2RlICpub2RlOwoJc3RydWN0IGNvbmZfYmluZGluZyAqY2I7CgoJbGlzdCA9IG1hbGxvYyhzaXplb2YgKmxpc3QpOwoJaWYgKCFsaXN0KQoJCWdvdG8gY2xlYW51cDsKCVRBSUxRX0lOSVQoJmxpc3QtPmZpZWxkcyk7CglsaXN0LT5jbnQgPSAwOwoJY2IgPSBMSVNUX0ZJUlNUKCZjb25mX2JpbmRpbmdzW2NvbmZfaGFzaCAoc2VjdGlvbildKTsKCWZvciAoOyBjYjsgY2IgPSBMSVNUX05FWFQoY2IsIGxpbmspKSB7CgkJaWYgKHN0cmNhc2VjbXAgKHNlY3Rpb24sIGNiLT5zZWN0aW9uKSA9PSAwKSB7CgkJCWlmIChhcmcgIT0gTlVMTCAmJiBzdHJjYXNlY21wKGFyZywgY2ItPmFyZykgIT0gMCkKCQkJCWNvbnRpbnVlOwoJCQlsaXN0LT5jbnQrKzsKCQkJbm9kZSA9IGNhbGxvYygxLCBzaXplb2YgKm5vZGUpOwoJCQlpZiAoIW5vZGUpCgkJCQlnb3RvIGNsZWFudXA7CgkJCW5vZGUtPmZpZWxkID0gc3RyZHVwKGNiLT50YWcpOwoJCQlpZiAoIW5vZGUtPmZpZWxkKSB7CgkJCQlmcmVlKG5vZGUpOwoJCQkJZ290byBjbGVhbnVwOwoJCQl9CgkJCVRBSUxRX0lOU0VSVF9UQUlMKCZsaXN0LT5maWVsZHMsIG5vZGUsIGxpbmspOwoJCX0KCX0KCXJldHVybiBsaXN0OwoKY2xlYW51cDoKCWlmIChsaXN0KQoJCWNvbmZfZnJlZV9saXN0KGxpc3QpOwoJcmV0dXJuIDA7Cn0KCi8qIERlY29kZSBhIFBFTSBlbmNvZGVkIGJ1ZmZlci4gICovCmludApjb25mX2RlY29kZV9iYXNlNjQgKHVfaW50OF90ICpvdXQsIHVfaW50MzJfdCAqbGVuLCB1X2NoYXIgKmJ1ZikKewoJdV9pbnQzMl90IGMgPSAwOwoJdV9pbnQ4X3QgYzEsIGMyLCBjMywgYzQ7CgoJd2hpbGUgKCpidWYpIHsKCQlpZiAoKmJ1ZiA+IDEyNyB8fCAoYzEgPSBhc2MyYmluWypidWZdKSA9PSAyNTUpCgkJCXJldHVybiAwOwoKCQlidWYrKzsKCQlpZiAoKmJ1ZiA+IDEyNyB8fCAoYzIgPSBhc2MyYmluWypidWZdKSA9PSAyNTUpCgkJCXJldHVybiAwOwoKCQlidWYrKzsKCQlpZiAoKmJ1ZiA9PSAnPScpIHsKCQkJYzMgPSBjNCA9IDA7CgkJCWMrKzsKCgkJCS8qIENoZWNrIGxhc3QgZm91ciBiaXQgKi8KCQkJaWYgKGMyICYgMHhGKQoJCQkJcmV0dXJuIDA7CgoJCQlpZiAoc3RyY21wKChjaGFyICopYnVmLCAiPT0iKSA9PSAwKQoJCQkJYnVmKys7CgkJCWVsc2UKCQkJCXJldHVybiAwOwoJCX0gZWxzZSBpZiAoKmJ1ZiA+IDEyNyB8fCAoYzMgPSBhc2MyYmluWypidWZdKSA9PSAyNTUpCgkJCXJldHVybiAwOwoJCWVsc2UgewoJCQlpZiAoKisrYnVmID09ICc9JykgewoJCQkJYzQgPSAwOwoJCQkJYyArPSAyOwoKCQkJCS8qIENoZWNrIGxhc3QgdHdvIGJpdCAqLwoJCQkJaWYgKGMzICYgMykKCQkJCQlyZXR1cm4gMDsKCgkJCWlmIChzdHJjbXAoKGNoYXIgKilidWYsICI9IikpCgkJCQlyZXR1cm4gMDsKCQkJfSBlbHNlIGlmICgqYnVmID4gMTI3IHx8IChjNCA9IGFzYzJiaW5bKmJ1Zl0pID09IDI1NSkKCQkJCXJldHVybiAwOwoJCQllbHNlCgkJCQljICs9IDM7CgkJfQoKCQlidWYrKzsKCQkqb3V0KysgPSAoYzEgPDwgMikgfCAoYzIgPj4gNCk7CgkJKm91dCsrID0gKGMyIDw8IDQpIHwgKGMzID4+IDIpOwoJCSpvdXQrKyA9IChjMyA8PCA2KSB8IGM0OwoJfQoKCSpsZW4gPSBjOwoJcmV0dXJuIDE7Cn0KCnZvaWQKY29uZl9mcmVlX2xpc3Qoc3RydWN0IGNvbmZfbGlzdCAqbGlzdCkKewoJc3RydWN0IGNvbmZfbGlzdF9ub2RlICpub2RlID0gVEFJTFFfRklSU1QoJmxpc3QtPmZpZWxkcyk7CgoJd2hpbGUgKG5vZGUpIHsKCQlUQUlMUV9SRU1PVkUoJmxpc3QtPmZpZWxkcywgbm9kZSwgbGluayk7CgkJaWYgKG5vZGUtPmZpZWxkKQoJCQlmcmVlKG5vZGUtPmZpZWxkKTsKCQlmcmVlIChub2RlKTsKCQlub2RlID0gVEFJTFFfRklSU1QoJmxpc3QtPmZpZWxkcyk7Cgl9CglmcmVlIChsaXN0KTsKfQoKaW50CmNvbmZfYmVnaW4odm9pZCkKewogIHN0YXRpYyBpbnQgc2VxID0gMDsKCiAgcmV0dXJuICsrc2VxOwp9CgpzdGF0aWMgc3RydWN0IGNvbmZfdHJhbnMgKgpjb25mX3RyYW5zX25vZGUoaW50IHRyYW5zYWN0aW9uLCBlbnVtIGNvbmZfb3Agb3ApCnsKCXN0cnVjdCBjb25mX3RyYW5zICpub2RlOwoKCW5vZGUgPSBjYWxsb2MgKDEsIHNpemVvZiAqbm9kZSk7CglpZiAoIW5vZGUpIHsKCQl4bG9nX3dhcm4oImNvbmZfdHJhbnNfbm9kZTogY2FsbG9jICgxLCAlbHUpIGZhaWxlZCIsCgkJKHVuc2lnbmVkIGxvbmcpc2l6ZW9mICpub2RlKTsKCQlyZXR1cm4gMDsKCX0KCW5vZGUtPnRyYW5zID0gdHJhbnNhY3Rpb247Cglub2RlLT5vcCA9IG9wOwoJVEFJTFFfSU5TRVJUX1RBSUwgKCZjb25mX3RyYW5zX3F1ZXVlLCBub2RlLCBsaW5rKTsKCXJldHVybiBub2RlOwp9CgovKiBRdWV1ZSBhIHNldCBvcGVyYXRpb24uICAqLwpzdGF0aWMgaW50CmNvbmZfc2V0KGludCB0cmFuc2FjdGlvbiwgY2hhciAqc2VjdGlvbiwgY2hhciAqYXJnLAoJY2hhciAqdGFnLCBjaGFyICp2YWx1ZSwgaW50IG92ZXJyaWRlLCBpbnQgaXNfZGVmYXVsdCkKewoJc3RydWN0IGNvbmZfdHJhbnMgKm5vZGU7CgoJbm9kZSA9IGNvbmZfdHJhbnNfbm9kZSh0cmFuc2FjdGlvbiwgQ09ORl9TRVQpOwoJaWYgKCFub2RlKQoJCXJldHVybiAxOwoJbm9kZS0+c2VjdGlvbiA9IHN0cmR1cChzZWN0aW9uKTsKCWlmICghbm9kZS0+c2VjdGlvbikgewoJCXhsb2dfd2FybigiY29uZl9zZXQ6IHN0cmR1cChcIiVzXCIpIGZhaWxlZCIsIHNlY3Rpb24pOwoJCWdvdG8gZmFpbDsKCX0KCS8qIE1ha2UgU2VjdGlvbiBuYW1lcyBjYXNlLWluc2Vuc2l0aXZlICovCgl1cHBlcjJsb3dlcihub2RlLT5zZWN0aW9uKTsKCglpZiAoYXJnKSB7CgkJbm9kZS0+YXJnID0gc3RyZHVwKGFyZyk7CgkJaWYgKCFub2RlLT5hcmcpIHsKCQkJeGxvZ193YXJuKCJjb25mX3NldDogc3RyZHVwKFwiJXNcIikgZmFpbGVkIiwgYXJnKTsKCQkJZ290byBmYWlsOwoJCX0KCX0gZWxzZQoJCW5vZGUtPmFyZyA9IE5VTEw7CgoJbm9kZS0+dGFnID0gc3RyZHVwKHRhZyk7CglpZiAoIW5vZGUtPnRhZykgewoJCXhsb2dfd2FybigiY29uZl9zZXQ6IHN0cmR1cChcIiVzXCIpIGZhaWxlZCIsIHRhZyk7CgkJZ290byBmYWlsOwoJfQoJbm9kZS0+dmFsdWUgPSBzdHJkdXAodmFsdWUpOwoJaWYgKCFub2RlLT52YWx1ZSkgewoJCXhsb2dfd2FybigiY29uZl9zZXQ6IHN0cmR1cChcIiVzXCIpIGZhaWxlZCIsIHZhbHVlKTsKCQlnb3RvIGZhaWw7Cgl9Cglub2RlLT5vdmVycmlkZSA9IG92ZXJyaWRlOwoJbm9kZS0+aXNfZGVmYXVsdCA9IGlzX2RlZmF1bHQ7CglyZXR1cm4gMDsKCmZhaWw6CglpZiAobm9kZS0+dGFnKQoJCWZyZWUobm9kZS0+dGFnKTsKCWlmIChub2RlLT5zZWN0aW9uKQoJCWZyZWUobm9kZS0+c2VjdGlvbik7CglpZiAobm9kZSkKCQlmcmVlKG5vZGUpOwoJcmV0dXJuIDE7Cn0KCi8qIFF1ZXVlIGEgcmVtb3ZlIG9wZXJhdGlvbi4gICovCmludApjb25mX3JlbW92ZShpbnQgdHJhbnNhY3Rpb24sIGNoYXIgKnNlY3Rpb24sIGNoYXIgKnRhZykKewoJc3RydWN0IGNvbmZfdHJhbnMgKm5vZGU7CgoJbm9kZSA9IGNvbmZfdHJhbnNfbm9kZSh0cmFuc2FjdGlvbiwgQ09ORl9SRU1PVkUpOwoJaWYgKCFub2RlKQoJCWdvdG8gZmFpbDsKCW5vZGUtPnNlY3Rpb24gPSBzdHJkdXAoc2VjdGlvbik7CglpZiAoIW5vZGUtPnNlY3Rpb24pIHsKCQl4bG9nX3dhcm4oImNvbmZfcmVtb3ZlOiBzdHJkdXAoXCIlc1wiKSBmYWlsZWQiLCBzZWN0aW9uKTsKCQlnb3RvIGZhaWw7Cgl9Cglub2RlLT50YWcgPSBzdHJkdXAodGFnKTsKCWlmICghbm9kZS0+dGFnKSB7CgkJeGxvZ193YXJuKCJjb25mX3JlbW92ZTogc3RyZHVwKFwiJXNcIikgZmFpbGVkIiwgdGFnKTsKCQlnb3RvIGZhaWw7Cgl9CglyZXR1cm4gMDsKCmZhaWw6CglpZiAobm9kZSAmJiBub2RlLT5zZWN0aW9uKQoJCWZyZWUgKG5vZGUtPnNlY3Rpb24pOwoJaWYgKG5vZGUpCgkJZnJlZSAobm9kZSk7CglyZXR1cm4gMTsKfQoKLyogUXVldWUgYSByZW1vdmUgc2VjdGlvbiBvcGVyYXRpb24uICAqLwppbnQKY29uZl9yZW1vdmVfc2VjdGlvbihpbnQgdHJhbnNhY3Rpb24sIGNoYXIgKnNlY3Rpb24pCnsKCXN0cnVjdCBjb25mX3RyYW5zICpub2RlOwoKCW5vZGUgPSBjb25mX3RyYW5zX25vZGUodHJhbnNhY3Rpb24sIENPTkZfUkVNT1ZFX1NFQ1RJT04pOwoJaWYgKCFub2RlKQoJCWdvdG8gZmFpbDsKCW5vZGUtPnNlY3Rpb24gPSBzdHJkdXAoc2VjdGlvbik7CglpZiAoIW5vZGUtPnNlY3Rpb24pIHsKCQl4bG9nX3dhcm4oImNvbmZfcmVtb3ZlX3NlY3Rpb246IHN0cmR1cChcIiVzXCIpIGZhaWxlZCIsIHNlY3Rpb24pOwoJCWdvdG8gZmFpbDsKCX0KCXJldHVybiAwOwoKZmFpbDoKCWlmIChub2RlKQoJCWZyZWUobm9kZSk7CglyZXR1cm4gMTsKfQoKLyogRXhlY3V0ZSBhbGwgcXVldWVkIG9wZXJhdGlvbnMgZm9yIHRoaXMgdHJhbnNhY3Rpb24uICBDbGVhbnVwLiAgKi8KaW50CmNvbmZfZW5kKGludCB0cmFuc2FjdGlvbiwgaW50IGNvbW1pdCkKewoJc3RydWN0IGNvbmZfdHJhbnMgKm5vZGUsICpuZXh0OwoKCWZvciAobm9kZSA9IFRBSUxRX0ZJUlNUKCZjb25mX3RyYW5zX3F1ZXVlKTsgbm9kZTsgbm9kZSA9IG5leHQpIHsKCQluZXh0ID0gVEFJTFFfTkVYVChub2RlLCBsaW5rKTsKCQlpZiAobm9kZS0+dHJhbnMgPT0gdHJhbnNhY3Rpb24pIHsKCQkJaWYgKGNvbW1pdCkgewoJCQkJc3dpdGNoIChub2RlLT5vcCkgewoJCQkJY2FzZSBDT05GX1NFVDoKCQkJCQljb25mX3NldF9ub3cobm9kZS0+c2VjdGlvbiwgbm9kZS0+YXJnLCAKCQkJCQkJbm9kZS0+dGFnLCBub2RlLT52YWx1ZSwgbm9kZS0+b3ZlcnJpZGUsIAoJCQkJCQlub2RlLT5pc19kZWZhdWx0KTsKCQkJCQlicmVhazsKCQkJCWNhc2UgQ09ORl9SRU1PVkU6CgkJCQkJY29uZl9yZW1vdmVfbm93KG5vZGUtPnNlY3Rpb24sIG5vZGUtPnRhZyk7CgkJCQkJYnJlYWs7CgkJCQljYXNlIENPTkZfUkVNT1ZFX1NFQ1RJT046CgkJCQkJY29uZl9yZW1vdmVfc2VjdGlvbl9ub3cobm9kZS0+c2VjdGlvbik7CgkJCQkJYnJlYWs7CgkJCQlkZWZhdWx0OgoJCQkJCXhsb2coTE9HX0lORk8sICJjb25mX2VuZDogdW5rbm93biBvcGVyYXRpb246ICVkIiwgbm9kZS0+b3ApOwoJCQkJfQoJCQl9CgkJCVRBSUxRX1JFTU9WRSAoJmNvbmZfdHJhbnNfcXVldWUsIG5vZGUsIGxpbmspOwoJCQlpZiAobm9kZS0+c2VjdGlvbikKCQkJCWZyZWUobm9kZS0+c2VjdGlvbik7CgkJCWlmIChub2RlLT50YWcpCgkJCQlmcmVlKG5vZGUtPnRhZyk7CgkJCWlmIChub2RlLT52YWx1ZSkKCQkJCWZyZWUobm9kZS0+dmFsdWUpOwoJCQlmcmVlIChub2RlKTsKCQl9Cgl9CglyZXR1cm4gMDsKfQoKLyoKICogRHVtcCBydW5uaW5nIGNvbmZpZ3VyYXRpb24gdXBvbiBTSUdVU1IxLgogKiBDb25maWd1cmF0aW9uIGlzICJzdG9yZWQgaW4gcmV2ZXJzZSBvcmRlciIsIHNvIHJldmVyc2UgaXQgYWdhaW4uCiAqLwpzdHJ1Y3QgZHVtcGVyIHsKCWNoYXIgKnMsICp2OwoJc3RydWN0IGR1bXBlciAqbmV4dDsKfTsKCnN0YXRpYyB2b2lkCmNvbmZfcmVwb3J0X2R1bXAoc3RydWN0IGR1bXBlciAqbm9kZSkKewoJLyogUmVjdXJzaXZlLCBjbGVhbnVwIHdoZW4gd2UncmUgZG9uZS4gICovCglpZiAobm9kZS0+bmV4dCkKCQljb25mX3JlcG9ydF9kdW1wKG5vZGUtPm5leHQpOwoKCWlmIChub2RlLT52KQoJCXhsb2coTE9HX0lORk8sICIlcz1cdCVzIiwgbm9kZS0+cywgbm9kZS0+dik7CgllbHNlIGlmIChub2RlLT5zKSB7CgkJeGxvZyhMT0dfSU5GTywgIiVzIiwgbm9kZS0+cyk7CgkJaWYgKHN0cmxlbihub2RlLT5zKSA+IDApCgkJCWZyZWUobm9kZS0+cyk7Cgl9CgoJZnJlZSAobm9kZSk7Cn0KCnZvaWQKY29uZl9yZXBvcnQgKHZvaWQpCnsKCXN0cnVjdCBjb25mX2JpbmRpbmcgKmNiLCAqbGFzdCA9IDA7Cgl1bnNpZ25lZCBpbnQgaSwgbGVuLCBkaWZmX2FyZyA9IDA7CgljaGFyICpjdXJyZW50X3NlY3Rpb24gPSAoY2hhciAqKTA7CgljaGFyICpjdXJyZW50X2FyZyA9IChjaGFyICopMDsKCXN0cnVjdCBkdW1wZXIgKmR1bXBlciwgKmRub2RlOwoKCWR1bXBlciA9IGRub2RlID0gKHN0cnVjdCBkdW1wZXIgKiljYWxsb2MoMSwgc2l6ZW9mICpkdW1wZXIpOwoJaWYgKCFkdW1wZXIpCgkJZ290byBtZW1fZmFpbDsKCgl4bG9nKExPR19JTkZPLCAiY29uZl9yZXBvcnQ6IGR1bXBpbmcgcnVubmluZyBjb25maWd1cmF0aW9uIik7CgoJZm9yIChpID0gMDsgaSA8IHNpemVvZiBjb25mX2JpbmRpbmdzIC8gc2l6ZW9mIGNvbmZfYmluZGluZ3NbMF07IGkrKykKCQlmb3IgKGNiID0gTElTVF9GSVJTVCgmY29uZl9iaW5kaW5nc1tpXSk7IGNiOyBjYiA9IExJU1RfTkVYVChjYiwgbGluaykpIHsKCQkJaWYgKCFjYi0+aXNfZGVmYXVsdCkgewoJCQkJLyogTWFrZSBzdXJlIHRoZSBTZWN0aW9uIGFydWdtZW50IGlzIHRoZSBzYW1lICovCgkJCQlpZiAoY3VycmVudF9hcmcgJiYgY3VycmVudF9zZWN0aW9uICYmIGNiLT5hcmcpIHsKCQkJCQlpZiAoc3RyY21wKGNiLT5zZWN0aW9uLCBjdXJyZW50X3NlY3Rpb24pID09IDAgJiYKCQkJCQkJc3RyY21wKGNiLT5hcmcsIGN1cnJlbnRfYXJnKSAhPSAwKQoJCQkJCWRpZmZfYXJnID0gMTsKCQkJCX0KCQkJCS8qIER1bXAgdGhpcyBlbnRyeS4gICovCgkJCQlpZiAoIWN1cnJlbnRfc2VjdGlvbiB8fCBzdHJjbXAoY2ItPnNlY3Rpb24sIGN1cnJlbnRfc2VjdGlvbikgCgkJCQkJCQl8fCBkaWZmX2FyZykgewoJCQkJCWlmIChjdXJyZW50X3NlY3Rpb24gfHwgZGlmZl9hcmcpIHsKCQkJCQkJbGVuID0gc3RybGVuIChjdXJyZW50X3NlY3Rpb24pICsgMzsKCQkJCQkJaWYgKGN1cnJlbnRfYXJnKQoJCQkJCQkJbGVuICs9IHN0cmxlbihjdXJyZW50X2FyZykgKyAzOwoJCQkJCQlkbm9kZS0+cyA9IG1hbGxvYyhsZW4pOwoJCQkJCQlpZiAoIWRub2RlLT5zKQoJCQkJCQkJZ290byBtZW1fZmFpbDsKCgkJCQkJCWlmIChjdXJyZW50X2FyZykKCQkJCQkJCXNucHJpbnRmKGRub2RlLT5zLCBsZW4sICJbJXMgXCIlc1wiXSIsIAoJCQkJCQkJCWN1cnJlbnRfc2VjdGlvbiwgY3VycmVudF9hcmcpOwoJCQkJCQllbHNlCgkJCQkJCQlzbnByaW50Zihkbm9kZS0+cywgbGVuLCAiWyVzXSIsIGN1cnJlbnRfc2VjdGlvbik7CgoJCQkJCQlkbm9kZS0+bmV4dCA9IAoJCQkJCQkJKHN0cnVjdCBkdW1wZXIgKiljYWxsb2MoMSwgc2l6ZW9mIChzdHJ1Y3QgZHVtcGVyKSk7CgkJCQkJCWRub2RlID0gZG5vZGUtPm5leHQ7CgkJCQkJCWlmICghZG5vZGUpCgkJCQkJCQlnb3RvIG1lbV9mYWlsOwoKCQkJCQkJZG5vZGUtPnMgPSAiIjsKCQkJCQkJZG5vZGUtPm5leHQgPSAKCQkJCQkJCShzdHJ1Y3QgZHVtcGVyICopY2FsbG9jKDEsIHNpemVvZiAoc3RydWN0IGR1bXBlcikpOwoJCQkJCQlkbm9kZSA9IGRub2RlLT5uZXh0OwoJCQkJCQlpZiAoIWRub2RlKQoJCQkJCQlnb3RvIG1lbV9mYWlsOwoJCQkJCX0KCQkJCQljdXJyZW50X3NlY3Rpb24gPSBjYi0+c2VjdGlvbjsKCQkJCQljdXJyZW50X2FyZyA9IGNiLT5hcmc7CgkJCQkJZGlmZl9hcmcgPSAwOwoJCQkJfQoJCQkJZG5vZGUtPnMgPSBjYi0+dGFnOwoJCQkJZG5vZGUtPnYgPSBjYi0+dmFsdWU7CgkJCQlkbm9kZS0+bmV4dCA9IChzdHJ1Y3QgZHVtcGVyICopY2FsbG9jICgxLCBzaXplb2YgKHN0cnVjdCBkdW1wZXIpKTsKCQkJCWRub2RlID0gZG5vZGUtPm5leHQ7CgkJCQlpZiAoIWRub2RlKQoJCQkJCWdvdG8gbWVtX2ZhaWw7CgkJCQlsYXN0ID0gY2I7CgkJfQoJfQoKCWlmIChsYXN0KSB7CgkJbGVuID0gc3RybGVuKGxhc3QtPnNlY3Rpb24pICsgMzsKCQlpZiAobGFzdC0+YXJnKQoJCQlsZW4gKz0gc3RybGVuKGxhc3QtPmFyZykgKyAzOwoJCWRub2RlLT5zID0gbWFsbG9jKGxlbik7CgkJaWYgKCFkbm9kZS0+cykKCQkJZ290byBtZW1fZmFpbDsKCQlpZiAobGFzdC0+YXJnKQoJCQlzbnByaW50Zihkbm9kZS0+cywgbGVuLCAiWyVzIFwiJXNcIl0iLCBsYXN0LT5zZWN0aW9uLCBsYXN0LT5hcmcpOwoJCWVsc2UKCQkJc25wcmludGYoZG5vZGUtPnMsIGxlbiwgIlslc10iLCBsYXN0LT5zZWN0aW9uKTsKCX0KCWNvbmZfcmVwb3J0X2R1bXAoZHVtcGVyKTsKCXJldHVybjsKCm1lbV9mYWlsOgoJeGxvZ193YXJuKCJjb25mX3JlcG9ydDogbWFsbG9jL2NhbGxvYyBmYWlsZWQiKTsKCXdoaWxlICgoZG5vZGUgPSBkdW1wZXIpICE9IDApIHsKCQlkdW1wZXIgPSBkdW1wZXItPm5leHQ7CgkJaWYgKGRub2RlLT5zKQoJCQlmcmVlKGRub2RlLT5zKTsKCQlmcmVlKGRub2RlKTsKCX0KCXJldHVybjsKfQo=