LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBfICAgXyBfX19fICBfCiAqICBQcm9qZWN0ICAgICAgICAgICAgICAgICAgICAgX19ffCB8IHwgfCAgXyBcfCB8CiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvIF9ffCB8IHwgfCB8XykgfCB8CiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgIHwgKF9ffCB8X3wgfCAgXyA8fCB8X19fCiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcX19ffFxfX18vfF98IFxfXF9fX19ffAogKgogKiBDb3B5cmlnaHQgKEMpIDE5OTggLSAyMDEwLCBEYW5pZWwgU3RlbmJlcmcsIDxkYW5pZWxAaGF4eC5zZT4sIGV0IGFsLgogKgogKiBUaGlzIHNvZnR3YXJlIGlzIGxpY2Vuc2VkIGFzIGRlc2NyaWJlZCBpbiB0aGUgZmlsZSBDT1BZSU5HLCB3aGljaAogKiB5b3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYXMgcGFydCBvZiB0aGlzIGRpc3RyaWJ1dGlvbi4gVGhlIHRlcm1zCiAqIGFyZSBhbHNvIGF2YWlsYWJsZSBhdCBodHRwOi8vY3VybC5oYXh4LnNlL2RvY3MvY29weXJpZ2h0Lmh0bWwuCiAqCiAqIFlvdSBtYXkgb3B0IHRvIHVzZSwgY29weSwgbW9kaWZ5LCBtZXJnZSwgcHVibGlzaCwgZGlzdHJpYnV0ZSBhbmQvb3Igc2VsbAogKiBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXMKICogZnVybmlzaGVkIHRvIGRvIHNvLCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIENPUFlJTkcgZmlsZS4KICoKICogVGhpcyBzb2Z0d2FyZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIGJhc2lzLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWQogKiBLSU5ELCBlaXRoZXIgZXhwcmVzcyBvciBpbXBsaWVkLgogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKLyoqKgoKClJFQ0VJVklORyBDT09LSUUgSU5GT1JNQVRJT04KPT09PT09PT09PT09PT09PT09PT09PT09PT09PQoKc3RydWN0IENvb2tpZUluZm8gKmNvb2tpZV9pbml0KGNoYXIgKmZpbGUpOwoKICAgICAgICBJbml0cyBhIGNvb2tpZSBzdHJ1Y3QgdG8gc3RvcmUgZGF0YSBpbiBhIGxvY2FsIGZpbGUuIFRoaXMgaXMgYWx3YXlzCiAgICAgICAgY2FsbGVkIGJlZm9yZSBhbnkgY29va2llcyBhcmUgc2V0LgoKaW50IGNvb2tpZXNfc2V0KHN0cnVjdCBDb29raWVJbmZvICpjb29raWUsIGNoYXIgKmNvb2tpZV9saW5lKTsKCiAgICAgICAgVGhlICdjb29raWVfbGluZScgcGFyYW1ldGVyIGlzIGEgZnVsbCAiU2V0LWNvb2tpZToiIGxpbmUgYXMKICAgICAgICByZWNlaXZlZCBmcm9tIGEgc2VydmVyLgoKICAgICAgICBUaGUgZnVuY3Rpb24gbmVlZCB0byByZXBsYWNlIHByZXZpb3VzbHkgc3RvcmVkIGxpbmVzIHRoYXQgdGhpcyBuZXcKICAgICAgICBsaW5lIHN1cGVyY2VlZHMuCgogICAgICAgIEl0IG1heSByZW1vdmUgbGluZXMgdGhhdCBhcmUgZXhwaXJlZC4KCiAgICAgICAgSXQgc2hvdWxkIHJldHVybiBhbiBpbmRpY2F0aW9uIG9mIHN1Y2Nlc3MvZXJyb3IuCgoKU0VORElORyBDT09LSUUgSU5GT1JNQVRJT04KPT09PT09PT09PT09PT09PT09PT09PT09PT0KCnN0cnVjdCBDb29raWVzICpjb29raWVfZ2V0bGlzdChzdHJ1Y3QgQ29va2llSW5mbyAqY29va2llLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hhciAqaG9zdCwgY2hhciAqcGF0aCwgYm9vbCBzZWN1cmUpOwoKICAgICAgICBGb3IgYSBnaXZlbiBob3N0IGFuZCBwYXRoLCByZXR1cm4gYSBsaW5rZWQgbGlzdCBvZiBjb29raWVzIHRoYXQKICAgICAgICB0aGUgY2xpZW50IHNob3VsZCBzZW5kIHRvIHRoZSBzZXJ2ZXIgaWYgdXNlZCBub3cuIFRoZSBzZWN1cmUKICAgICAgICBib29sZWFuIGluZm9ybXMgdGhlIGNvb2tpZSBpZiBhIHNlY3VyZSBjb25uZWN0aW9uIGlzIGFjaGlldmVkIG9yCiAgICAgICAgbm90LgoKICAgICAgICBJdCBzaGFsbCBvbmx5IHJldHVybiBjb29raWVzIHRoYXQgaGF2ZW4ndCBleHBpcmVkLgoKCkV4YW1wbGUgc2V0IG9mIGNvb2tpZXM6CgogICAgU2V0LWNvb2tpZTogUFJPRFVDVElORk89d2VieHByZXNzOyBkb21haW49LmZpZGVsaXR5LmNvbTsgcGF0aD0vOyBzZWN1cmUKICAgIFNldC1jb29raWU6IFBFUlNPTkFMSVpFPW5vbmU7ZXhwaXJlcz1Nb25kYXksIDEzLUp1bi0xOTg4IDAzOjA0OjU1IEdNVDsKICAgIGRvbWFpbj0uZmlkZWxpdHkuY29tOyBwYXRoPS9mdGd3OyBzZWN1cmUKICAgIFNldC1jb29raWU6IEZpZEhpc3Q9bm9uZTtleHBpcmVzPU1vbmRheSwgMTMtSnVuLTE5ODggMDM6MDQ6NTUgR01UOwogICAgZG9tYWluPS5maWRlbGl0eS5jb207IHBhdGg9Lzsgc2VjdXJlCiAgICBTZXQtY29va2llOiBGaWRPcmRlcj1ub25lO2V4cGlyZXM9TW9uZGF5LCAxMy1KdW4tMTk4OCAwMzowNDo1NSBHTVQ7CiAgICBkb21haW49LmZpZGVsaXR5LmNvbTsgcGF0aD0vOyBzZWN1cmUKICAgIFNldC1jb29raWU6IERpc1BlbmQ9bm9uZTtleHBpcmVzPU1vbmRheSwgMTMtSnVuLTE5ODggMDM6MDQ6NTUgR01UOwogICAgZG9tYWluPS5maWRlbGl0eS5jb207IHBhdGg9Lzsgc2VjdXJlCiAgICBTZXQtY29va2llOiBGaWREaXM9bm9uZTtleHBpcmVzPU1vbmRheSwgMTMtSnVuLTE5ODggMDM6MDQ6NTUgR01UOwogICAgZG9tYWluPS5maWRlbGl0eS5jb207IHBhdGg9Lzsgc2VjdXJlCiAgICBTZXQtY29va2llOgogICAgU2Vzc2lvbl9LZXlANjc5MWE5ZTAtOTAxYS0xMWQwLWExYzgtOWIwMTJjODhhYTc3PW5vbmU7ZXhwaXJlcz1Nb25kYXksCiAgICAxMy1KdW4tMTk4OCAwMzowNDo1NSBHTVQ7IGRvbWFpbj0uZmlkZWxpdHkuY29tOyBwYXRoPS87IHNlY3VyZQoqKioqLwoKCiNpbmNsdWRlICJzZXR1cC5oIgoKI2lmICFkZWZpbmVkKENVUkxfRElTQUJMRV9IVFRQKSAmJiAhZGVmaW5lZChDVVJMX0RJU0FCTEVfQ09PS0lFUykKCiNpbmNsdWRlIDxzdGRsaWIuaD4KI2luY2x1ZGUgPHN0cmluZy5oPgoKI2RlZmluZSBfTVBSSU5URl9SRVBMQUNFIC8qIHdpdGhvdXQgdGhpcyBvbiB3aW5kb3dzIE9TIHdlIGdldCB1bmRlZmluZWQgcmVmZXJlbmNlIHRvIHNucHJpbnRmICovCiNpbmNsdWRlIDxjdXJsL21wcmludGYuaD4KCiNpbmNsdWRlICJ1cmxkYXRhLmgiCiNpbmNsdWRlICJjb29raWUuaCIKI2luY2x1ZGUgInN0cmVxdWFsLmgiCiNpbmNsdWRlICJzdHJ0b2suaCIKI2luY2x1ZGUgInNlbmRmLmgiCiNpbmNsdWRlICJjdXJsX21lbW9yeS5oIgojaW5jbHVkZSAic2hhcmUuaCIKI2luY2x1ZGUgInN0cnRvb2ZmdC5oIgojaW5jbHVkZSAicmF3c3RyLmgiCiNpbmNsdWRlICJjdXJsX21lbXJjaHIuaCIKCi8qIFRoZSBsYXN0ICNpbmNsdWRlIGZpbGUgc2hvdWxkIGJlOiAqLwojaW5jbHVkZSAibWVtZGVidWcuaCIKCgpzdGF0aWMgdm9pZCBmcmVlY29va2llKHN0cnVjdCBDb29raWUgKmNvKQp7CiAgaWYoY28tPmV4cGlyZXN0cikKICAgIGZyZWUoY28tPmV4cGlyZXN0cik7CiAgaWYoY28tPmRvbWFpbikKICAgIGZyZWUoY28tPmRvbWFpbik7CiAgaWYoY28tPnBhdGgpCiAgICBmcmVlKGNvLT5wYXRoKTsKICBpZihjby0+bmFtZSkKICAgIGZyZWUoY28tPm5hbWUpOwogIGlmKGNvLT52YWx1ZSkKICAgIGZyZWUoY28tPnZhbHVlKTsKICBpZihjby0+bWF4YWdlKQogICAgZnJlZShjby0+bWF4YWdlKTsKICBpZihjby0+dmVyc2lvbikKICAgIGZyZWUoY28tPnZlcnNpb24pOwoKICBmcmVlKGNvKTsKfQoKc3RhdGljIGJvb2wgdGFpbG1hdGNoKGNvbnN0IGNoYXIgKmxpdHRsZSwgY29uc3QgY2hhciAqYmlnb25lKQp7CiAgc2l6ZV90IGxpdHRsZWxlbiA9IHN0cmxlbihsaXR0bGUpOwogIHNpemVfdCBiaWdsZW4gPSBzdHJsZW4oYmlnb25lKTsKCiAgaWYobGl0dGxlbGVuID4gYmlnbGVuKQogICAgcmV0dXJuIEZBTFNFOwoKICByZXR1cm4gKGJvb2wpQ3VybF9yYXdfZXF1YWwobGl0dGxlLCBiaWdvbmUrYmlnbGVuLWxpdHRsZWxlbik7Cn0KCi8qCiAqIExvYWQgY29va2llcyBmcm9tIGFsbCBnaXZlbiBjb29raWUgZmlsZXMgKENVUkxPUFRfQ09PS0lFRklMRSkuCiAqLwp2b2lkIEN1cmxfY29va2llX2xvYWRmaWxlcyhzdHJ1Y3QgU2Vzc2lvbkhhbmRsZSAqZGF0YSkKewogIHN0cnVjdCBjdXJsX3NsaXN0ICpsaXN0ID0gZGF0YS0+Y2hhbmdlLmNvb2tpZWxpc3Q7CiAgaWYobGlzdCkgewogICAgQ3VybF9zaGFyZV9sb2NrKGRhdGEsIENVUkxfTE9DS19EQVRBX0NPT0tJRSwgQ1VSTF9MT0NLX0FDQ0VTU19TSU5HTEUpOwogICAgd2hpbGUobGlzdCkgewogICAgICBkYXRhLT5jb29raWVzID0gQ3VybF9jb29raWVfaW5pdChkYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsaXN0LT5kYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhLT5jb29raWVzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhLT5zZXQuY29va2llc2Vzc2lvbik7CiAgICAgIGxpc3QgPSBsaXN0LT5uZXh0OwogICAgfQogICAgQ3VybF9zaGFyZV91bmxvY2soZGF0YSwgQ1VSTF9MT0NLX0RBVEFfQ09PS0lFKTsKICAgIGN1cmxfc2xpc3RfZnJlZV9hbGwoZGF0YS0+Y2hhbmdlLmNvb2tpZWxpc3QpOyAvKiBjbGVhbiB1cCBsaXN0ICovCiAgICBkYXRhLT5jaGFuZ2UuY29va2llbGlzdCA9IE5VTEw7IC8qIGRvbid0IGRvIHRoaXMgYWdhaW4hICovCiAgfQp9CgovKgogKiBzdHJzdG9yZSgpIG1ha2VzIGEgc3RyZHVwKCkgb24gdGhlICduZXdzdHInIGFuZCBpZiAnKnN0cicgaXMgbm9uLU5VTEwKICogdGhhdCB3aWxsIGJlIGZyZWVkIGJlZm9yZSB0aGUgYWxsb2NhdGVkIHN0cmluZyBpcyBzdG9yZWQgdGhlcmUuCiAqCiAqIEl0IGlzIG1lYW50IHRvIGVhc2lseSByZXBsYWNlIHN0cmR1cCgpCiAqLwpzdGF0aWMgdm9pZCBzdHJzdG9yZShjaGFyICoqc3RyLCBjb25zdCBjaGFyICpuZXdzdHIpCnsKICBpZigqc3RyKQogICAgZnJlZSgqc3RyKTsKICAqc3RyID0gc3RyZHVwKG5ld3N0cik7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgogKiBDdXJsX2Nvb2tpZV9hZGQoKQogKgogKiBBZGQgYSBzaW5nbGUgY29va2llIGxpbmUgdG8gdGhlIGNvb2tpZSBrZWVwaW5nIG9iamVjdC4KICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KCnN0cnVjdCBDb29raWUgKgpDdXJsX2Nvb2tpZV9hZGQoc3RydWN0IFNlc3Npb25IYW5kbGUgKmRhdGEsCiAgICAgICAgICAgICAgICAvKiBUaGUgJ2RhdGEnIHBvaW50ZXIgaGVyZSBtYXkgYmUgTlVMTCBhdCB0aW1lcywgYW5kIHRodXMKICAgICAgICAgICAgICAgICAgIG11c3Qgb25seSBiZSB1c2VkIHZlcnkgY2FyZWZ1bGx5IGZvciB0aGluZ3MgdGhhdCBjYW4gZGVhbAogICAgICAgICAgICAgICAgICAgd2l0aCBkYXRhIGJlaW5nIE5VTEwuIFN1Y2ggYXMgaW5mb2YoKSBhbmQgc2ltaWxhciAqLwoKICAgICAgICAgICAgICAgIHN0cnVjdCBDb29raWVJbmZvICpjLAogICAgICAgICAgICAgICAgYm9vbCBodHRwaGVhZGVyLCAvKiBUUlVFIGlmIEhUVFAgaGVhZGVyLXN0eWxlIGxpbmUgKi8KICAgICAgICAgICAgICAgIGNoYXIgKmxpbmVwdHIsICAgLyogZmlyc3QgY2hhcmFjdGVyIG9mIHRoZSBsaW5lICovCiAgICAgICAgICAgICAgICBjb25zdCBjaGFyICpkb21haW4sIC8qIGRlZmF1bHQgZG9tYWluICovCiAgICAgICAgICAgICAgICBjb25zdCBjaGFyICpwYXRoKSAgIC8qIGZ1bGwgcGF0aCB1c2VkIHdoZW4gdGhpcyBjb29raWUgaXMgc2V0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB1c2VkIHRvIGdldCBkZWZhdWx0IHBhdGggZm9yIHRoZSBjb29raWUKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5sZXNzIHNldCAqLwp7CiAgc3RydWN0IENvb2tpZSAqY2xpc3Q7CiAgY2hhciBuYW1lW01BWF9OQU1FXTsKICBzdHJ1Y3QgQ29va2llICpjbzsKICBzdHJ1Y3QgQ29va2llICpsYXN0Yz1OVUxMOwogIHRpbWVfdCBub3cgPSB0aW1lKE5VTEwpOwogIGJvb2wgcmVwbGFjZV9vbGQgPSBGQUxTRTsKICBib29sIGJhZGNvb2tpZSA9IEZBTFNFOyAvKiBjb29raWVzIGFyZSBnb29kIGJ5IGRlZmF1bHQuIG1tbW1tIHl1bW15ICovCgojaWZkZWYgQ1VSTF9ESVNBQkxFX1ZFUkJPU0VfU1RSSU5HUwogICh2b2lkKWRhdGE7CiNlbmRpZgoKICAvKiBGaXJzdCwgYWxsb2MgYW5kIGluaXQgYSBuZXcgc3RydWN0IGZvciBpdCAqLwogIGNvID0gY2FsbG9jKDEsIHNpemVvZihzdHJ1Y3QgQ29va2llKSk7CiAgaWYoIWNvKQogICAgcmV0dXJuIE5VTEw7IC8qIGJhaWwgb3V0IGlmIHdlJ3JlIHRoaXMgbG93IG9uIG1lbW9yeSAqLwoKICBpZihodHRwaGVhZGVyKSB7CiAgICAvKiBUaGlzIGxpbmUgd2FzIHJlYWQgb2ZmIGEgSFRUUC1oZWFkZXIgKi8KICAgIGNvbnN0IGNoYXIgKnB0cjsKICAgIGNvbnN0IGNoYXIgKnNlcDsKICAgIGNvbnN0IGNoYXIgKnNlbWlwdHI7CiAgICBjaGFyICp3aGF0OwoKICAgIHdoYXQgPSBtYWxsb2MoTUFYX0NPT0tJRV9MSU5FKTsKICAgIGlmKCF3aGF0KSB7CiAgICAgIGZyZWUoY28pOwogICAgICByZXR1cm4gTlVMTDsKICAgIH0KCiAgICBzZW1pcHRyPXN0cmNocihsaW5lcHRyLCAnOycpOyAvKiBmaXJzdCwgZmluZCBhIHNlbWljb2xvbiAqLwoKICAgIHdoaWxlKCpsaW5lcHRyICYmIElTQkxBTksoKmxpbmVwdHIpKQogICAgICBsaW5lcHRyKys7CgogICAgcHRyID0gbGluZXB0cjsKICAgIGRvIHsKICAgICAgLyogd2UgaGF2ZSBhIDx3aGF0Pj08dGhpcz4gcGFpciBvciBhICdzZWN1cmUnIHdvcmQgaGVyZSAqLwogICAgICBzZXAgPSBzdHJjaHIocHRyLCAnPScpOwogICAgICBpZihzZXAgJiYgKCFzZW1pcHRyIHx8IChzZW1pcHRyPnNlcCkpICkgewogICAgICAgIC8qCiAgICAgICAgICogVGhlcmUgaXMgYSA9IHNpZ24gYW5kIGlmIHRoZXJlIHdhcyBhIHNlbWljb2xvbiB0b28sIHdoaWNoIG1ha2Ugc3VyZQogICAgICAgICAqIHRoYXQgdGhlIHNlbWljb2xvbiBjb21lcyBfYWZ0ZXJfIHRoZSBlcXVhbCBzaWduLgogICAgICAgICAqLwoKICAgICAgICBuYW1lWzBdPXdoYXRbMF09MDsgLyogaW5pdCB0aGUgYnVmZmVycyAqLwogICAgICAgIGlmKDEgPD0gc3NjYW5mKHB0ciwgIiUiIE1BWF9OQU1FX1RYVCAiW147PV09JSIKICAgICAgICAgICAgICAgICAgICAgICBNQVhfQ09PS0lFX0xJTkVfVFhUICJbXjtcclxuXSIsCiAgICAgICAgICAgICAgICAgICAgICAgbmFtZSwgd2hhdCkpIHsKICAgICAgICAgIC8qIHRoaXMgaXMgYSA8bmFtZT49PHdoYXQ+IHBhaXIuIFdlIHVzZSBzdHJzdG9yZSgpIGJlbG93IHRvIHByb3Blcmx5CiAgICAgICAgICAgICBkZWFsIHdpdGggcmVjZWl2ZWQgY29va2llIGhlYWRlcnMgdGhhdCBoYXZlIHRoZSBzYW1lIHN0cmluZwogICAgICAgICAgICAgcHJvcGVydHkgc2V0IG1vcmUgdGhhbiBvbmNlLCBhbmQgdGhlbiB3ZSB1c2UgdGhlIGxhc3Qgb25lLiAqLwoKICAgICAgICAgIGNvbnN0IGNoYXIgKndoYXRwdHI7CgogICAgICAgICAgLyogU3RyaXAgb2ZmIHRyYWlsaW5nIHdoaXRlc3BhY2UgZnJvbSB0aGUgJ3doYXQnICovCiAgICAgICAgICBzaXplX3QgbGVuPXN0cmxlbih3aGF0KTsKICAgICAgICAgIHdoaWxlKGxlbiAmJiBJU0JMQU5LKHdoYXRbbGVuLTFdKSkgewogICAgICAgICAgICB3aGF0W2xlbi0xXT0wOwogICAgICAgICAgICBsZW4tLTsKICAgICAgICAgIH0KCiAgICAgICAgICAvKiBTa2lwIGxlYWRpbmcgd2hpdGVzcGFjZSBmcm9tIHRoZSAnd2hhdCcgKi8KICAgICAgICAgIHdoYXRwdHI9d2hhdDsKICAgICAgICAgIHdoaWxlKCp3aGF0cHRyICYmIElTQkxBTksoKndoYXRwdHIpKSB7CiAgICAgICAgICAgIHdoYXRwdHIrKzsKICAgICAgICAgIH0KCiAgICAgICAgICBpZihDdXJsX3Jhd19lcXVhbCgicGF0aCIsIG5hbWUpKSB7CiAgICAgICAgICAgIHN0cnN0b3JlKCZjby0+cGF0aCwgd2hhdHB0cik7CiAgICAgICAgICAgIGlmKCFjby0+cGF0aCkgewogICAgICAgICAgICAgIGJhZGNvb2tpZSA9IFRSVUU7IC8qIG91dCBvZiBtZW1vcnkgYmFkICovCiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICAgIH0KICAgICAgICAgIGVsc2UgaWYoQ3VybF9yYXdfZXF1YWwoImRvbWFpbiIsIG5hbWUpKSB7CiAgICAgICAgICAgIC8qIG5vdGUgdGhhdCB0aGlzIG5hbWUgbWF5IG9yIG1heSBub3QgaGF2ZSBhIHByZWNlZWRpbmcgZG90LCBidXQKICAgICAgICAgICAgICAgd2UgZG9uJ3QgY2FyZSBhYm91dCB0aGF0LCB3ZSB0cmVhdCB0aGUgbmFtZXMgdGhlIHNhbWUgYW55d2F5ICovCgogICAgICAgICAgICBjb25zdCBjaGFyICpkb21wdHI9d2hhdHB0cjsKICAgICAgICAgICAgY29uc3QgY2hhciAqbmV4dHB0cjsKICAgICAgICAgICAgaW50IGRvdGNvdW50PTE7CgogICAgICAgICAgICAvKiBDb3VudCB0aGUgZG90cywgd2UgbmVlZCB0byBtYWtlIHN1cmUgdGhhdCB0aGVyZSBhcmUgZW5vdWdoCiAgICAgICAgICAgICAgIG9mIHRoZW0uICovCgogICAgICAgICAgICBpZignLicgPT0gd2hhdHB0clswXSkKICAgICAgICAgICAgICAvKiBkb24ndCBjb3VudCB0aGUgaW5pdGlhbCBkb3QsIGFzc3VtZSBpdCAqLwogICAgICAgICAgICAgIGRvbXB0cisrOwoKICAgICAgICAgICAgZG8gewogICAgICAgICAgICAgIG5leHRwdHIgPSBzdHJjaHIoZG9tcHRyLCAnLicpOwogICAgICAgICAgICAgIGlmKG5leHRwdHIpIHsKICAgICAgICAgICAgICAgIGlmKGRvbXB0ciAhPSBuZXh0cHRyKQogICAgICAgICAgICAgICAgICBkb3Rjb3VudCsrOwogICAgICAgICAgICAgICAgZG9tcHRyID0gbmV4dHB0cisxOwogICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSB3aGlsZShuZXh0cHRyKTsKCiAgICAgICAgICAgIC8qIFRoZSBvcmlnaW5hbCBOZXRzY2FwZSBjb29raWUgc3BlYyBkZWZpbmVkIHRoYXQgdGhpcyBkb21haW4gbmFtZQogICAgICAgICAgICAgICBNVVNUIGhhdmUgdGhyZWUgZG90cyAob3IgdHdvIGlmIG9uZSBvZiB0aGUgc2V2ZW4gaG9seSBUTERzKSwKICAgICAgICAgICAgICAgYnV0IGl0IHNlZW1zIHRoYXQgdGhlc2Uga2luZHMgb2YgY29va2llcyBhcmUgaW4gdXNlICJvdXQgdGhlcmUiCiAgICAgICAgICAgICAgIHNvIHdlIGNhbm5vdCBiZSB0aGF0IHN0cmljdC4gSSd2ZSB0aGVyZWZvcmUgbG93ZXJlZCB0aGUgY2hlY2sKICAgICAgICAgICAgICAgdG8gbm90IGFsbG93IGxlc3MgdGhhbiB0d28gZG90cy4gKi8KCiAgICAgICAgICAgIGlmKGRvdGNvdW50IDwgMikgewogICAgICAgICAgICAgIC8qIFJlY2VpdmVkIGFuZCBza2lwcGVkIGEgY29va2llIHdpdGggYSBkb21haW4gdXNpbmcgdG9vIGZldwogICAgICAgICAgICAgICAgIGRvdHMuICovCiAgICAgICAgICAgICAgYmFkY29va2llPVRSVUU7IC8qIG1hcmsgdGhpcyBhcyBhIGJhZCBjb29raWUgKi8KICAgICAgICAgICAgICBpbmZvZihkYXRhLCAic2tpcHBlZCBjb29raWUgd2l0aCBpbGxlZ2FsIGRvdGNvdW50IGRvbWFpbjogJXNcbiIsCiAgICAgICAgICAgICAgICAgICAgd2hhdHB0cik7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgLyogTm93LCB3ZSBtYWtlIHN1cmUgdGhhdCBvdXIgaG9zdCBpcyB3aXRoaW4gdGhlIGdpdmVuIGRvbWFpbiwKICAgICAgICAgICAgICAgICBvciB0aGUgZ2l2ZW4gZG9tYWluIGlzIG5vdCB2YWxpZCBhbmQgdGh1cyBjYW5ub3QgYmUgc2V0LiAqLwoKICAgICAgICAgICAgICBpZignLicgPT0gd2hhdHB0clswXSkKICAgICAgICAgICAgICAgIHdoYXRwdHIrKzsgLyogaWdub3JlIHByZWNlZWRpbmcgZG90ICovCgogICAgICAgICAgICAgIGlmKCFkb21haW4gfHwgdGFpbG1hdGNoKHdoYXRwdHIsIGRvbWFpbikpIHsKICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgKnRhaWxwdHI9d2hhdHB0cjsKICAgICAgICAgICAgICAgIGlmKHRhaWxwdHJbMF0gPT0gJy4nKQogICAgICAgICAgICAgICAgICB0YWlscHRyKys7CiAgICAgICAgICAgICAgICBzdHJzdG9yZSgmY28tPmRvbWFpbiwgdGFpbHB0cik7IC8qIGRvbid0IHByZWZpeCB3L2RvdHMKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50ZXJuYWxseSAqLwogICAgICAgICAgICAgICAgaWYoIWNvLT5kb21haW4pIHsKICAgICAgICAgICAgICAgICAgYmFkY29va2llID0gVFJVRTsKICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBjby0+dGFpbG1hdGNoPVRSVUU7IC8qIHdlIGFsd2F5cyBkbyB0aGF0IGlmIHRoZSBkb21haW4gbmFtZSB3YXMKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2l2ZW4gKi8KICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgICAgICAvKiB3ZSBkaWQgbm90IGdldCBhIHRhaWxtYXRjaCBhbmQgdGhlbiB0aGUgYXR0ZW1wdGVkIHNldCBkb21haW4KICAgICAgICAgICAgICAgICAgIGlzIG5vdCBhIGRvbWFpbiB0byB3aGljaCB0aGUgY3VycmVudCBob3N0IGJlbG9uZ3MuIE1hcmsgYXMKICAgICAgICAgICAgICAgICAgIGJhZC4gKi8KICAgICAgICAgICAgICAgIGJhZGNvb2tpZT1UUlVFOwogICAgICAgICAgICAgICAgaW5mb2YoZGF0YSwgInNraXBwZWQgY29va2llIHdpdGggYmFkIHRhaWxtYXRjaCBkb21haW46ICVzXG4iLAogICAgICAgICAgICAgICAgICAgICAgd2hhdHB0cik7CiAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgICBlbHNlIGlmKEN1cmxfcmF3X2VxdWFsKCJ2ZXJzaW9uIiwgbmFtZSkpIHsKICAgICAgICAgICAgc3Ryc3RvcmUoJmNvLT52ZXJzaW9uLCB3aGF0cHRyKTsKICAgICAgICAgICAgaWYoIWNvLT52ZXJzaW9uKSB7CiAgICAgICAgICAgICAgYmFkY29va2llID0gVFJVRTsKICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgICAgfQogICAgICAgICAgZWxzZSBpZihDdXJsX3Jhd19lcXVhbCgibWF4LWFnZSIsIG5hbWUpKSB7CiAgICAgICAgICAgIC8qIERlZmluZWQgaW4gUkZDMjEwOToKCiAgICAgICAgICAgICAgIE9wdGlvbmFsLiAgVGhlIE1heC1BZ2UgYXR0cmlidXRlIGRlZmluZXMgdGhlIGxpZmV0aW1lIG9mIHRoZQogICAgICAgICAgICAgICBjb29raWUsIGluIHNlY29uZHMuICBUaGUgZGVsdGEtc2Vjb25kcyB2YWx1ZSBpcyBhIGRlY2ltYWwgbm9uLQogICAgICAgICAgICAgICBuZWdhdGl2ZSBpbnRlZ2VyLiAgQWZ0ZXIgZGVsdGEtc2Vjb25kcyBzZWNvbmRzIGVsYXBzZSwgdGhlCiAgICAgICAgICAgICAgIGNsaWVudCBzaG91bGQgZGlzY2FyZCB0aGUgY29va2llLiAgQSB2YWx1ZSBvZiB6ZXJvIG1lYW5zIHRoZQogICAgICAgICAgICAgICBjb29raWUgc2hvdWxkIGJlIGRpc2NhcmRlZCBpbW1lZGlhdGVseS4KCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBzdHJzdG9yZSgmY28tPm1heGFnZSwgd2hhdHB0cik7CiAgICAgICAgICAgIGlmKCFjby0+bWF4YWdlKSB7CiAgICAgICAgICAgICAgYmFkY29va2llID0gVFJVRTsKICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgICAgICBjby0+ZXhwaXJlcyA9CiAgICAgICAgICAgICAgc3RydG9sKCgqY28tPm1heGFnZT09J1wiJyk/JmNvLT5tYXhhZ2VbMV06JmNvLT5tYXhhZ2VbMF0sTlVMTCwxMCkKICAgICAgICAgICAgICAgICsgKGxvbmcpbm93OwogICAgICAgICAgfQogICAgICAgICAgZWxzZSBpZihDdXJsX3Jhd19lcXVhbCgiZXhwaXJlcyIsIG5hbWUpKSB7CiAgICAgICAgICAgIHN0cnN0b3JlKCZjby0+ZXhwaXJlc3RyLCB3aGF0cHRyKTsKICAgICAgICAgICAgaWYoIWNvLT5leHBpcmVzdHIpIHsKICAgICAgICAgICAgICBiYWRjb29raWUgPSBUUlVFOwogICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgICAgIC8qIE5vdGUgdGhhdCBpZiB0aGUgZGF0ZSBjb3VsZG4ndCBnZXQgcGFyc2VkIGZvciB3aGF0ZXZlciByZWFzb24sCiAgICAgICAgICAgICAgIHRoZSBjb29raWUgd2lsbCBiZSB0cmVhdGVkIGFzIGEgc2Vzc2lvbiBjb29raWUgKi8KICAgICAgICAgICAgY28tPmV4cGlyZXMgPSBjdXJsX2dldGRhdGUod2hhdCwgJm5vdyk7CgogICAgICAgICAgICAvKiBTZXNzaW9uIGNvb2tpZXMgaGF2ZSBleHBpcmVzIHNldCB0byAwIHNvIGlmIHdlIGdldCB0aGF0IGJhY2sKICAgICAgICAgICAgICAgZnJvbSB0aGUgZGF0ZSBwYXJzZXIgbGV0J3MgYWRkIGEgc2Vjb25kIHRvIG1ha2UgaXQgYQogICAgICAgICAgICAgICBub24tc2Vzc2lvbiBjb29raWUgKi8KICAgICAgICAgICAgaWYgKGNvLT5leHBpcmVzID09IDApCiAgICAgICAgICAgICAgY28tPmV4cGlyZXMgPSAxOwogICAgICAgICAgICBlbHNlIGlmKCBjby0+ZXhwaXJlcyA8IDAgKQogICAgICAgICAgICAgICAgY28tPmV4cGlyZXMgPSAwOwogICAgICAgICAgfQogICAgICAgICAgZWxzZSBpZighY28tPm5hbWUpIHsKICAgICAgICAgICAgY28tPm5hbWUgPSBzdHJkdXAobmFtZSk7CiAgICAgICAgICAgIGNvLT52YWx1ZSA9IHN0cmR1cCh3aGF0cHRyKTsKICAgICAgICAgICAgaWYoIWNvLT5uYW1lIHx8ICFjby0+dmFsdWUpIHsKICAgICAgICAgICAgICBiYWRjb29raWUgPSBUUlVFOwogICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgICAvKgogICAgICAgICAgICBlbHNlIHRoaXMgaXMgdGhlIHNlY29uZCAob3IgbW9yZSkgbmFtZSB3ZSBkb24ndCBrbm93CiAgICAgICAgICAgIGFib3V0ISAqLwogICAgICAgIH0KICAgICAgICBlbHNlIHsKICAgICAgICAgIC8qIHRoaXMgaXMgYW4gImlsbGVnYWwiIDx3aGF0Pj08dGhpcz4gcGFpciAqLwogICAgICAgIH0KICAgICAgfQogICAgICBlbHNlIHsKICAgICAgICBpZihzc2NhbmYocHRyLCAiJSIgTUFYX0NPT0tJRV9MSU5FX1RYVCAiW147XHJcbl0iLAogICAgICAgICAgICAgICAgICB3aGF0KSkgewogICAgICAgICAgaWYoQ3VybF9yYXdfZXF1YWwoInNlY3VyZSIsIHdoYXQpKSB7CiAgICAgICAgICAgIGNvLT5zZWN1cmUgPSBUUlVFOwogICAgICAgICAgfQogICAgICAgICAgZWxzZSBpZiAoQ3VybF9yYXdfZXF1YWwoImh0dHBvbmx5Iiwgd2hhdCkpIHsKICAgICAgICAgICAgY28tPmh0dHBvbmx5ID0gVFJVRTsKICAgICAgICAgIH0KICAgICAgICAgIC8qIGVsc2UsCiAgICAgICAgICAgICB1bnN1cHBvcnRlZCBrZXl3b3JkIHdpdGhvdXQgYXNzaWduISAqLwoKICAgICAgICB9CiAgICAgIH0KICAgICAgaWYoIXNlbWlwdHIgfHwgISpzZW1pcHRyKSB7CiAgICAgICAgLyogd2UgYWxyZWFkeSBrbm93IHRoZXJlIGFyZSBubyBtb3JlIGNvb2tpZXMgKi8KICAgICAgICBzZW1pcHRyID0gTlVMTDsKICAgICAgICBjb250aW51ZTsKICAgICAgfQoKICAgICAgcHRyPXNlbWlwdHIrMTsKICAgICAgd2hpbGUoKnB0ciAmJiBJU0JMQU5LKCpwdHIpKQogICAgICAgIHB0cisrOwogICAgICBzZW1pcHRyPXN0cmNocihwdHIsICc7Jyk7IC8qIG5vdywgZmluZCB0aGUgbmV4dCBzZW1pY29sb24gKi8KCiAgICAgIGlmKCFzZW1pcHRyICYmICpwdHIpCiAgICAgICAgLyogVGhlcmUgYXJlIG5vIG1vcmUgc2VtaWNvbG9ucywgYnV0IHRoZXJlJ3MgYSBmaW5hbCBuYW1lPXZhbHVlIHBhaXIKICAgICAgICAgICBjb21pbmcgdXAgKi8KICAgICAgICBzZW1pcHRyPXN0cmNocihwdHIsICdcMCcpOwogICAgfSB3aGlsZShzZW1pcHRyKTsKCiAgICBpZighYmFkY29va2llICYmICFjby0+ZG9tYWluKSB7CiAgICAgIGlmKGRvbWFpbikgewogICAgICAgIC8qIG5vIGRvbWFpbiB3YXMgZ2l2ZW4gaW4gdGhlIGhlYWRlciBsaW5lLCBzZXQgdGhlIGRlZmF1bHQgKi8KICAgICAgICBjby0+ZG9tYWluPXN0cmR1cChkb21haW4pOwogICAgICAgIGlmKCFjby0+ZG9tYWluKQogICAgICAgICAgYmFkY29va2llID0gVFJVRTsKICAgICAgfQogICAgfQoKICAgIGlmKCFiYWRjb29raWUgJiYgIWNvLT5wYXRoICYmIHBhdGgpIHsKICAgICAgLyogTm8gcGF0aCB3YXMgZ2l2ZW4gaW4gdGhlIGhlYWRlciBsaW5lLCBzZXQgdGhlIGRlZmF1bHQuCiAgICAgICAgIE5vdGUgdGhhdCB0aGUgcGFzc2VkLWluIHBhdGggdG8gdGhpcyBmdW5jdGlvbiBNQVkgaGF2ZSBhICc/JyBhbmQKICAgICAgICAgZm9sbG93aW5nIHBhcnQgdGhhdCBNVVNUIG5vdCBiZSBzdG9yZWQgYXMgcGFydCBvZiB0aGUgcGF0aC4gKi8KICAgICAgY2hhciAqcXVlcnlwID0gc3RyY2hyKHBhdGgsICc/Jyk7CgogICAgICAvKiBxdWVyeXAgaXMgd2hlcmUgdGhlIGludGVyZXN0aW5nIHBhcnQgb2YgdGhlIHBhdGggZW5kcywgc28gbm93IHdlCiAgICAgICAgIHdhbnQgdG8gdGhlIGZpbmQgdGhlIGxhc3QgKi8KICAgICAgY2hhciAqZW5kc2xhc2g7CiAgICAgIGlmKCFxdWVyeXApCiAgICAgICAgZW5kc2xhc2ggPSBzdHJyY2hyKHBhdGgsICcvJyk7CiAgICAgIGVsc2UKICAgICAgICBlbmRzbGFzaCA9IG1lbXJjaHIocGF0aCwgJy8nLCAoc2l6ZV90KShxdWVyeXAgLSBwYXRoKSk7CiAgICAgIGlmKGVuZHNsYXNoKSB7CiAgICAgICAgc2l6ZV90IHBhdGhsZW4gPSAoc2l6ZV90KShlbmRzbGFzaC1wYXRoKzEpOyAvKiBpbmNsdWRlIGVuZGluZyBzbGFzaCAqLwogICAgICAgIGNvLT5wYXRoPW1hbGxvYyhwYXRobGVuKzEpOyAvKiBvbmUgZXh0cmEgZm9yIHRoZSB6ZXJvIGJ5dGUgKi8KICAgICAgICBpZihjby0+cGF0aCkgewogICAgICAgICAgbWVtY3B5KGNvLT5wYXRoLCBwYXRoLCBwYXRobGVuKTsKICAgICAgICAgIGNvLT5wYXRoW3BhdGhsZW5dPTA7IC8qIHplcm8gdGVybWluYXRlICovCiAgICAgICAgfQogICAgICAgIGVsc2UKICAgICAgICAgIGJhZGNvb2tpZSA9IFRSVUU7CiAgICAgIH0KICAgIH0KCiAgICBmcmVlKHdoYXQpOwoKICAgIGlmKGJhZGNvb2tpZSB8fCAhY28tPm5hbWUpIHsKICAgICAgLyogd2UgZGlkbid0IGdldCBhIGNvb2tpZSBuYW1lIG9yIGEgYmFkIG9uZSwKICAgICAgICAgdGhpcyBpcyBhbiBpbGxlZ2FsIGxpbmUsIGJhaWwgb3V0ICovCiAgICAgIGZyZWVjb29raWUoY28pOwogICAgICByZXR1cm4gTlVMTDsKICAgIH0KCiAgfQogIGVsc2UgewogICAgLyogVGhpcyBsaW5lIGlzIE5PVCBhIEhUVFAgaGVhZGVyIHN0eWxlIGxpbmUsIHdlIGRvIG9mZmVyIHN1cHBvcnQgZm9yCiAgICAgICByZWFkaW5nIHRoZSBvZGQgbmV0c2NhcGUgY29va2llcy1maWxlIGZvcm1hdCBoZXJlICovCiAgICBjaGFyICpwdHI7CiAgICBjaGFyICpmaXJzdHB0cjsKICAgIGNoYXIgKnRva19idWY9TlVMTDsKICAgIGludCBmaWVsZHM7CgogICAgLyogSUUgaW50cm9kdWNlZCBIVFRQLW9ubHkgY29va2llcyB0byBwcmV2ZW50IFhTUyBhdHRhY2tzLiBDb29raWVzCiAgICAgICBtYXJrZWQgd2l0aCBodHRwT25seSBhZnRlciB0aGUgZG9tYWluIG5hbWUgYXJlIG5vdCBhY2Nlc3NpYmxlCiAgICAgICBmcm9tIGphdmFzY3JpcHRzLCBidXQgc2luY2UgY3VybCBkb2VzIG5vdCBvcGVyYXRlIGF0IGphdmFzY3JpcHQKICAgICAgIGxldmVsLCB3ZSBpbmNsdWRlIHRoZW0gYW55d2F5LiBJbiBGaXJlZm94J3MgY29va2llIGZpbGVzLCB0aGVzZQogICAgICAgbGluZXMgYXJlIHByZWNlZWRlZCB3aXRoICNIdHRwT25seV8gYW5kIHRoZW4gZXZlcnl0aGluZyBpcwogICAgICAgYXMgdXN1YWwsIHNvIHdlIHNraXAgMTAgY2hhcmFjdGVycyBvZiB0aGUgbGluZS4uCiAgICAqLwogICAgaWYgKHN0cm5jbXAobGluZXB0ciwgIiNIdHRwT25seV8iLCAxMCkgPT0gMCkgewogICAgICBsaW5lcHRyICs9IDEwOwogICAgICBjby0+aHR0cG9ubHkgPSBUUlVFOwogICAgfQoKICAgIGlmKGxpbmVwdHJbMF09PScjJykgewogICAgICAvKiBkb24ndCBldmVuIHRyeSB0aGUgY29tbWVudHMgKi8KICAgICAgZnJlZShjbyk7CiAgICAgIHJldHVybiBOVUxMOwogICAgfQogICAgLyogc3RyaXAgb2ZmIHRoZSBwb3NzaWJsZSBlbmQtb2YtbGluZSBjaGFyYWN0ZXJzICovCiAgICBwdHI9c3RyY2hyKGxpbmVwdHIsICdccicpOwogICAgaWYocHRyKQogICAgICAqcHRyPTA7IC8qIGNsZWFyIGl0ICovCiAgICBwdHI9c3RyY2hyKGxpbmVwdHIsICdcbicpOwogICAgaWYocHRyKQogICAgICAqcHRyPTA7IC8qIGNsZWFyIGl0ICovCgogICAgZmlyc3RwdHI9c3RydG9rX3IobGluZXB0ciwgIlx0IiwgJnRva19idWYpOyAvKiB0b2tlbml6ZSBpdCBvbiB0aGUgVEFCICovCgogICAgLyogSGVyZSdzIGEgcXVpY2sgY2hlY2sgdG8gZWxpbWluYXRlIG5vcm1hbCBIVFRQLWhlYWRlcnMgZnJvbSB0aGlzICovCiAgICBpZighZmlyc3RwdHIgfHwgc3RyY2hyKGZpcnN0cHRyLCAnOicpKSB7CiAgICAgIGZyZWUoY28pOwogICAgICByZXR1cm4gTlVMTDsKICAgIH0KCiAgICAvKiBOb3cgbG9vcCB0aHJvdWdoIHRoZSBmaWVsZHMgYW5kIGluaXQgdGhlIHN0cnVjdCB3ZSBhbHJlYWR5IGhhdmUKICAgICAgIGFsbG9jYXRlZCAqLwogICAgZm9yKHB0cj1maXJzdHB0ciwgZmllbGRzPTA7IHB0ciAmJiAhYmFkY29va2llOwogICAgICAgIHB0cj1zdHJ0b2tfcihOVUxMLCAiXHQiLCAmdG9rX2J1ZiksIGZpZWxkcysrKSB7CiAgICAgIHN3aXRjaChmaWVsZHMpIHsKICAgICAgY2FzZSAwOgogICAgICAgIGlmKHB0clswXT09Jy4nKSAvKiBza2lwIHByZWNlZWRpbmcgZG90cyAqLwogICAgICAgICAgcHRyKys7CiAgICAgICAgY28tPmRvbWFpbiA9IHN0cmR1cChwdHIpOwogICAgICAgIGlmKCFjby0+ZG9tYWluKQogICAgICAgICAgYmFkY29va2llID0gVFJVRTsKICAgICAgICBicmVhazsKICAgICAgY2FzZSAxOgogICAgICAgIC8qIFRoaXMgZmllbGQgZ290IGl0cyBleHBsYW5hdGlvbiBvbiB0aGUgMjNyZCBvZiBNYXkgMjAwMSBieQogICAgICAgICAgIEFuZHLpcyBHYXJj7WE6CgogICAgICAgICAgIGZsYWc6IEEgVFJVRS9GQUxTRSB2YWx1ZSBpbmRpY2F0aW5nIGlmIGFsbCBtYWNoaW5lcyB3aXRoaW4gYSBnaXZlbgogICAgICAgICAgIGRvbWFpbiBjYW4gYWNjZXNzIHRoZSB2YXJpYWJsZS4gVGhpcyB2YWx1ZSBpcyBzZXQgYXV0b21hdGljYWxseSBieQogICAgICAgICAgIHRoZSBicm93c2VyLCBkZXBlbmRpbmcgb24gdGhlIHZhbHVlIHlvdSBzZXQgZm9yIHRoZSBkb21haW4uCgogICAgICAgICAgIEFzIGZhciBhcyBJIGNhbiBzZWUsIGl0IGlzIHNldCB0byB0cnVlIHdoZW4gdGhlIGNvb2tpZSBzYXlzCiAgICAgICAgICAgLmRvbWFpbi5jb20gYW5kIHRvIGZhbHNlIHdoZW4gdGhlIGRvbWFpbiBpcyBjb21wbGV0ZSB3d3cuZG9tYWluLmNvbQogICAgICAgICovCiAgICAgICAgY28tPnRhaWxtYXRjaD0oYm9vbClDdXJsX3Jhd19lcXVhbChwdHIsICJUUlVFIik7IC8qIHN0b3JlIGluZm9ybWF0aW9uICovCiAgICAgICAgYnJlYWs7CiAgICAgIGNhc2UgMjoKICAgICAgICAvKiBJdCB0dXJucyBvdXQsIHRoYXQgc29tZXRpbWVzIHRoZSBmaWxlIGZvcm1hdCBhbGxvd3MgdGhlIHBhdGgKICAgICAgICAgICBmaWVsZCB0byByZW1haW4gbm90IGZpbGxlZCBpbiwgd2UgdHJ5IHRvIGRldGVjdCB0aGlzIGFuZCB3b3JrCiAgICAgICAgICAgYXJvdW5kIGl0ISBBbmRy6XMgR2FyY+1hIG1hZGUgdXMgYXdhcmUgb2YgdGhpcy4uLiAqLwogICAgICAgIGlmKHN0cmNtcCgiVFJVRSIsIHB0cikgJiYgc3RyY21wKCJGQUxTRSIsIHB0cikpIHsKICAgICAgICAgIC8qIG9ubHkgaWYgdGhlIHBhdGggZG9lc24ndCBsb29rIGxpa2UgYSBib29sZWFuIG9wdGlvbiEgKi8KICAgICAgICAgIGNvLT5wYXRoID0gc3RyZHVwKHB0cik7CiAgICAgICAgICBpZighY28tPnBhdGgpCiAgICAgICAgICAgIGJhZGNvb2tpZSA9IFRSVUU7CiAgICAgICAgICBicmVhazsKICAgICAgICB9CiAgICAgICAgLyogdGhpcyBkb2Vzbid0IGxvb2sgbGlrZSBhIHBhdGgsIG1ha2Ugb25lIHVwISAqLwogICAgICAgIGNvLT5wYXRoID0gc3RyZHVwKCIvIik7CiAgICAgICAgaWYoIWNvLT5wYXRoKQogICAgICAgICAgYmFkY29va2llID0gVFJVRTsKICAgICAgICBmaWVsZHMrKzsgLyogYWRkIGEgZmllbGQgYW5kIGZhbGwgZG93biB0byBzZWN1cmUgKi8KICAgICAgICAvKiBGQUxMVEhST1VHSCAqLwogICAgICBjYXNlIDM6CiAgICAgICAgY28tPnNlY3VyZSA9IChib29sKUN1cmxfcmF3X2VxdWFsKHB0ciwgIlRSVUUiKTsKICAgICAgICBicmVhazsKICAgICAgY2FzZSA0OgogICAgICAgIGNvLT5leHBpcmVzID0gY3VybHhfc3RydG9vZmZ0KHB0ciwgTlVMTCwgMTApOwogICAgICAgIGJyZWFrOwogICAgICBjYXNlIDU6CiAgICAgICAgY28tPm5hbWUgPSBzdHJkdXAocHRyKTsKICAgICAgICBpZighY28tPm5hbWUpCiAgICAgICAgICBiYWRjb29raWUgPSBUUlVFOwogICAgICAgIGJyZWFrOwogICAgICBjYXNlIDY6CiAgICAgICAgY28tPnZhbHVlID0gc3RyZHVwKHB0cik7CiAgICAgICAgaWYoIWNvLT52YWx1ZSkKICAgICAgICAgIGJhZGNvb2tpZSA9IFRSVUU7CiAgICAgICAgYnJlYWs7CiAgICAgIH0KICAgIH0KICAgIGlmKDYgPT0gZmllbGRzKSB7CiAgICAgIC8qIHdlIGdvdCBhIGNvb2tpZSB3aXRoIGJsYW5rIGNvbnRlbnRzLCBmaXggaXQgKi8KICAgICAgY28tPnZhbHVlID0gc3RyZHVwKCIiKTsKICAgICAgaWYoIWNvLT52YWx1ZSkKICAgICAgICBiYWRjb29raWUgPSBUUlVFOwogICAgICBlbHNlCiAgICAgICAgZmllbGRzKys7CiAgICB9CgogICAgaWYoIWJhZGNvb2tpZSAmJiAoNyAhPSBmaWVsZHMpKQogICAgICAvKiB3ZSBkaWQgbm90IGZpbmQgdGhlIHN1ZmZpY2llbnQgbnVtYmVyIG9mIGZpZWxkcyAqLwogICAgICBiYWRjb29raWUgPSBUUlVFOwoKICAgIGlmKGJhZGNvb2tpZSkgewogICAgICBmcmVlY29va2llKGNvKTsKICAgICAgcmV0dXJuIE5VTEw7CiAgICB9CgogIH0KCiAgaWYoIWMtPnJ1bm5pbmcgJiYgICAgLyogcmVhZCBmcm9tIGEgZmlsZSAqLwogICAgIGMtPm5ld3Nlc3Npb24gJiYgIC8qIGNsZWFuIHNlc3Npb24gY29va2llcyAqLwogICAgICFjby0+ZXhwaXJlcykgeyAgIC8qIHRoaXMgaXMgYSBzZXNzaW9uIGNvb2tpZSBzaW5jZSBpdCBkb2Vzbid0IGV4cGlyZSEgKi8KICAgIGZyZWVjb29raWUoY28pOwogICAgcmV0dXJuIE5VTEw7CiAgfQoKICBjby0+bGl2ZWNvb2tpZSA9IGMtPnJ1bm5pbmc7CgogIC8qIG5vdywgd2UgaGF2ZSBwYXJzZWQgdGhlIGluY29taW5nIGxpbmUsIHdlIG11c3Qgbm93IGNoZWNrIGlmIHRoaXMKICAgICBzdXBlcmNlZWRzIGFuIGFscmVhZHkgZXhpc3RpbmcgY29va2llLCB3aGljaCBpdCBtYXkgaWYgdGhlIHByZXZpb3VzIGhhdmUKICAgICB0aGUgc2FtZSBkb21haW4gYW5kIHBhdGggYXMgdGhpcyAqLwoKICBjbGlzdCA9IGMtPmNvb2tpZXM7CiAgcmVwbGFjZV9vbGQgPSBGQUxTRTsKICB3aGlsZShjbGlzdCkgewogICAgaWYoQ3VybF9yYXdfZXF1YWwoY2xpc3QtPm5hbWUsIGNvLT5uYW1lKSkgewogICAgICAvKiB0aGUgbmFtZXMgYXJlIGlkZW50aWNhbCAqLwoKICAgICAgaWYoY2xpc3QtPmRvbWFpbiAmJiBjby0+ZG9tYWluKSB7CiAgICAgICAgaWYoQ3VybF9yYXdfZXF1YWwoY2xpc3QtPmRvbWFpbiwgY28tPmRvbWFpbikpCiAgICAgICAgICAvKiBUaGUgZG9tYWlucyBhcmUgaWRlbnRpY2FsICovCiAgICAgICAgICByZXBsYWNlX29sZD1UUlVFOwogICAgICB9CiAgICAgIGVsc2UgaWYoIWNsaXN0LT5kb21haW4gJiYgIWNvLT5kb21haW4pCiAgICAgICAgcmVwbGFjZV9vbGQgPSBUUlVFOwoKICAgICAgaWYocmVwbGFjZV9vbGQpIHsKICAgICAgICAvKiB0aGUgZG9tYWlucyB3ZXJlIGlkZW50aWNhbCAqLwoKICAgICAgICBpZihjbGlzdC0+cGF0aCAmJiBjby0+cGF0aCkgewogICAgICAgICAgaWYoQ3VybF9yYXdfZXF1YWwoY2xpc3QtPnBhdGgsIGNvLT5wYXRoKSkgewogICAgICAgICAgICByZXBsYWNlX29sZCA9IFRSVUU7CiAgICAgICAgICB9CiAgICAgICAgICBlbHNlCiAgICAgICAgICAgIHJlcGxhY2Vfb2xkID0gRkFMU0U7CiAgICAgICAgfQogICAgICAgIGVsc2UgaWYoIWNsaXN0LT5wYXRoICYmICFjby0+cGF0aCkKICAgICAgICAgIHJlcGxhY2Vfb2xkID0gVFJVRTsKICAgICAgICBlbHNlCiAgICAgICAgICByZXBsYWNlX29sZCA9IEZBTFNFOwoKICAgICAgfQoKICAgICAgaWYocmVwbGFjZV9vbGQgJiYgIWNvLT5saXZlY29va2llICYmIGNsaXN0LT5saXZlY29va2llKSB7CiAgICAgICAgLyogQm90aCBjb29raWVzIG1hdGNoZWQgZmluZSwgZXhjZXB0IHRoYXQgdGhlIGFscmVhZHkgcHJlc2VudAogICAgICAgICAgIGNvb2tpZSBpcyAibGl2ZSIsIHdoaWNoIG1lYW5zIGl0IHdhcyBzZXQgZnJvbSBhIGhlYWRlciwgd2hpbGUKICAgICAgICAgICB0aGUgbmV3IG9uZSBpc24ndCAibGl2ZSIgYW5kIHRodXMgb25seSByZWFkIGZyb20gYSBmaWxlLiBXZSBsZXQKICAgICAgICAgICBsaXZlIGNvb2tpZXMgc3RheSBhbGl2ZSAqLwoKICAgICAgICAvKiBGcmVlIHRoZSBuZXdjb21lciBhbmQgZ2V0IG91dCBvZiBoZXJlISAqLwogICAgICAgIGZyZWVjb29raWUoY28pOwogICAgICAgIHJldHVybiBOVUxMOwogICAgICB9CgogICAgICBpZihyZXBsYWNlX29sZCkgewogICAgICAgIGNvLT5uZXh0ID0gY2xpc3QtPm5leHQ7IC8qIGdldCB0aGUgbmV4dC1wb2ludGVyIGZpcnN0ICovCgogICAgICAgIC8qIHRoZW4gZnJlZSBhbGwgdGhlIG9sZCBwb2ludGVycyAqLwogICAgICAgIGZyZWUoY2xpc3QtPm5hbWUpOwogICAgICAgIGlmKGNsaXN0LT52YWx1ZSkKICAgICAgICAgIGZyZWUoY2xpc3QtPnZhbHVlKTsKICAgICAgICBpZihjbGlzdC0+ZG9tYWluKQogICAgICAgICAgZnJlZShjbGlzdC0+ZG9tYWluKTsKICAgICAgICBpZihjbGlzdC0+cGF0aCkKICAgICAgICAgIGZyZWUoY2xpc3QtPnBhdGgpOwogICAgICAgIGlmKGNsaXN0LT5leHBpcmVzdHIpCiAgICAgICAgICBmcmVlKGNsaXN0LT5leHBpcmVzdHIpOwoKICAgICAgICBpZihjbGlzdC0+dmVyc2lvbikKICAgICAgICAgIGZyZWUoY2xpc3QtPnZlcnNpb24pOwogICAgICAgIGlmKGNsaXN0LT5tYXhhZ2UpCiAgICAgICAgICBmcmVlKGNsaXN0LT5tYXhhZ2UpOwoKICAgICAgICAqY2xpc3QgPSAqY287ICAvKiB0aGVuIHN0b3JlIGFsbCB0aGUgbmV3IGRhdGEgKi8KCiAgICAgICAgZnJlZShjbyk7ICAgLyogZnJlZSB0aGUgbmV3bHkgYWxsb2NlZCBtZW1vcnkgKi8KICAgICAgICBjbyA9IGNsaXN0OyAvKiBwb2ludCB0byB0aGUgcHJldmlvdXMgc3RydWN0IGluc3RlYWQgKi8KCiAgICAgICAgLyogV2UgaGF2ZSByZXBsYWNlZCBhIGNvb2tpZSwgbm93IHNraXAgdGhlIHJlc3Qgb2YgdGhlIGxpc3QgYnV0CiAgICAgICAgICAgbWFrZSBzdXJlIHRoZSAnbGFzdGMnIHBvaW50ZXIgaXMgcHJvcGVybHkgc2V0ICovCiAgICAgICAgZG8gewogICAgICAgICAgbGFzdGMgPSBjbGlzdDsKICAgICAgICAgIGNsaXN0ID0gY2xpc3QtPm5leHQ7CiAgICAgICAgfSB3aGlsZShjbGlzdCk7CiAgICAgICAgYnJlYWs7CiAgICAgIH0KICAgIH0KICAgIGxhc3RjID0gY2xpc3Q7CiAgICBjbGlzdCA9IGNsaXN0LT5uZXh0OwogIH0KCiAgaWYoYy0+cnVubmluZykKICAgIC8qIE9ubHkgc2hvdyB0aGlzIHdoZW4gTk9UIHJlYWRpbmcgdGhlIGNvb2tpZXMgZnJvbSBhIGZpbGUgKi8KICAgIGluZm9mKGRhdGEsICIlcyBjb29raWUgJXM9XCIlc1wiIGZvciBkb21haW4gJXMsIHBhdGggJXMsICIKICAgICAgICAgICJleHBpcmUgJSIgRk9STUFUX09GRl9UICJcbiIsCiAgICAgICAgICByZXBsYWNlX29sZD8iUmVwbGFjZWQiOiJBZGRlZCIsIGNvLT5uYW1lLCBjby0+dmFsdWUsCiAgICAgICAgICBjby0+ZG9tYWluLCBjby0+cGF0aCwgY28tPmV4cGlyZXMpOwoKICBpZighcmVwbGFjZV9vbGQpIHsKICAgIC8qIHRoZW4gbWFrZSB0aGUgbGFzdCBpdGVtIHBvaW50IG9uIHRoaXMgbmV3IG9uZSAqLwogICAgaWYobGFzdGMpCiAgICAgIGxhc3RjLT5uZXh0ID0gY287CiAgICBlbHNlCiAgICAgIGMtPmNvb2tpZXMgPSBjbzsKICB9CgogIGMtPm51bWNvb2tpZXMrKzsgLyogb25lIG1vcmUgY29va2llIGluIHRoZSBqYXIgKi8KICByZXR1cm4gY287Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgogKiBDdXJsX2Nvb2tpZV9pbml0KCkKICoKICogSW5pdHMgYSBjb29raWUgc3RydWN0IHRvIHJlYWQgZGF0YSBmcm9tIGEgbG9jYWwgZmlsZS4gVGhpcyBpcyBhbHdheXMKICogY2FsbGVkIGJlZm9yZSBhbnkgY29va2llcyBhcmUgc2V0LiBGaWxlIG1heSBiZSBOVUxMLgogKgogKiBJZiAnbmV3c2Vzc2lvbicgaXMgVFJVRSwgZGlzY2FyZCBhbGwgInNlc3Npb24gY29va2llcyIgb24gcmVhZCBmcm9tIGZpbGUuCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwpzdHJ1Y3QgQ29va2llSW5mbyAqQ3VybF9jb29raWVfaW5pdChzdHJ1Y3QgU2Vzc2lvbkhhbmRsZSAqZGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciAqZmlsZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RydWN0IENvb2tpZUluZm8gKmluYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYm9vbCBuZXdzZXNzaW9uKQp7CiAgc3RydWN0IENvb2tpZUluZm8gKmM7CiAgRklMRSAqZnA7CiAgYm9vbCBmcm9tZmlsZT1UUlVFOwoKICBpZihOVUxMID09IGluYykgewogICAgLyogd2UgZGlkbid0IGdldCBhIHN0cnVjdCwgY3JlYXRlIG9uZSAqLwogICAgYyA9IGNhbGxvYygxLCBzaXplb2Yoc3RydWN0IENvb2tpZUluZm8pKTsKICAgIGlmKCFjKQogICAgICByZXR1cm4gTlVMTDsgLyogZmFpbGVkIHRvIGdldCBtZW1vcnkgKi8KICAgIGMtPmZpbGVuYW1lID0gc3RyZHVwKGZpbGU/ZmlsZToibm9uZSIpOyAvKiBjb3B5IHRoZSBuYW1lIGp1c3QgaW4gY2FzZSAqLwogIH0KICBlbHNlIHsKICAgIC8qIHdlIGdvdCBhbiBhbHJlYWR5IGV4aXN0aW5nIG9uZSwgdXNlIHRoYXQgKi8KICAgIGMgPSBpbmM7CiAgfQogIGMtPnJ1bm5pbmcgPSBGQUxTRTsgLyogdGhpcyBpcyBub3QgcnVubmluZywgdGhpcyBpcyBpbml0ICovCgogIGlmKGZpbGUgJiYgc3RyZXF1YWwoZmlsZSwgIi0iKSkgewogICAgZnAgPSBzdGRpbjsKICAgIGZyb21maWxlPUZBTFNFOwogIH0KICBlbHNlIGlmKGZpbGUgJiYgISpmaWxlKSB7CiAgICAvKiBwb2ludHMgdG8gYSAiIiBzdHJpbmcgKi8KICAgIGZwID0gTlVMTDsKICB9CiAgZWxzZQogICAgZnAgPSBmaWxlP2ZvcGVuKGZpbGUsICJyIik6TlVMTDsKCiAgYy0+bmV3c2Vzc2lvbiA9IG5ld3Nlc3Npb247IC8qIG5ldyBzZXNzaW9uPyAqLwoKICBpZihmcCkgewogICAgY2hhciAqbGluZXB0cjsKICAgIGJvb2wgaGVhZGVybGluZTsKCiAgICBjaGFyICpsaW5lID0gbWFsbG9jKE1BWF9DT09LSUVfTElORSk7CiAgICBpZihsaW5lKSB7CiAgICAgIHdoaWxlKGZnZXRzKGxpbmUsIE1BWF9DT09LSUVfTElORSwgZnApKSB7CiAgICAgICAgaWYoY2hlY2twcmVmaXgoIlNldC1Db29raWU6IiwgbGluZSkpIHsKICAgICAgICAgIC8qIFRoaXMgaXMgYSBjb29raWUgbGluZSwgZ2V0IGl0ISAqLwogICAgICAgICAgbGluZXB0cj0mbGluZVsxMV07CiAgICAgICAgICBoZWFkZXJsaW5lPVRSVUU7CiAgICAgICAgfQogICAgICAgIGVsc2UgewogICAgICAgICAgbGluZXB0cj1saW5lOwogICAgICAgICAgaGVhZGVybGluZT1GQUxTRTsKICAgICAgICB9CiAgICAgICAgd2hpbGUoKmxpbmVwdHIgJiYgSVNCTEFOSygqbGluZXB0cikpCiAgICAgICAgICBsaW5lcHRyKys7CgogICAgICAgIEN1cmxfY29va2llX2FkZChkYXRhLCBjLCBoZWFkZXJsaW5lLCBsaW5lcHRyLCBOVUxMLCBOVUxMKTsKICAgICAgfQogICAgICBmcmVlKGxpbmUpOyAvKiBmcmVlIHRoZSBsaW5lIGJ1ZmZlciAqLwogICAgfQogICAgaWYoZnJvbWZpbGUpCiAgICAgIGZjbG9zZShmcCk7CiAgfQoKICBjLT5ydW5uaW5nID0gVFJVRTsgICAgICAgICAgLyogbm93LCB3ZSdyZSBydW5uaW5nICovCgogIHJldHVybiBjOwp9CgovKiBzb3J0IHRoaXMgc28gdGhhdCB0aGUgbG9uZ2VzdCBwYXRoIGdldHMgYmVmb3JlIHRoZSBzaG9ydGVyIHBhdGggKi8Kc3RhdGljIGludCBjb29raWVfc29ydChjb25zdCB2b2lkICpwMSwgY29uc3Qgdm9pZCAqcDIpCnsKICBzdHJ1Y3QgQ29va2llICpjMSA9ICooc3RydWN0IENvb2tpZSAqKilwMTsKICBzdHJ1Y3QgQ29va2llICpjMiA9ICooc3RydWN0IENvb2tpZSAqKilwMjsKCiAgc2l6ZV90IGwxID0gYzEtPnBhdGg/c3RybGVuKGMxLT5wYXRoKTowOwogIHNpemVfdCBsMiA9IGMyLT5wYXRoP3N0cmxlbihjMi0+cGF0aCk6MDsKCiAgcmV0dXJuIChsMiA+IGwxKSA/IDEgOiAobDIgPCBsMSkgPyAtMSA6IDAgOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoKICogQ3VybF9jb29raWVfZ2V0bGlzdCgpCiAqCiAqIEZvciBhIGdpdmVuIGhvc3QgYW5kIHBhdGgsIHJldHVybiBhIGxpbmtlZCBsaXN0IG9mIGNvb2tpZXMgdGhhdCB0aGUKICogY2xpZW50IHNob3VsZCBzZW5kIHRvIHRoZSBzZXJ2ZXIgaWYgdXNlZCBub3cuIFRoZSBzZWN1cmUgYm9vbGVhbiBpbmZvcm1zCiAqIHRoZSBjb29raWUgaWYgYSBzZWN1cmUgY29ubmVjdGlvbiBpcyBhY2hpZXZlZCBvciBub3QuCiAqCiAqIEl0IHNoYWxsIG9ubHkgcmV0dXJuIGNvb2tpZXMgdGhhdCBoYXZlbid0IGV4cGlyZWQuCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKc3RydWN0IENvb2tpZSAqQ3VybF9jb29raWVfZ2V0bGlzdChzdHJ1Y3QgQ29va2llSW5mbyAqYywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyICpob3N0LCBjb25zdCBjaGFyICpwYXRoLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2wgc2VjdXJlKQp7CiAgc3RydWN0IENvb2tpZSAqbmV3Y287CiAgc3RydWN0IENvb2tpZSAqY287CiAgdGltZV90IG5vdyA9IHRpbWUoTlVMTCk7CiAgc3RydWN0IENvb2tpZSAqbWFpbmNvPU5VTEw7CiAgc2l6ZV90IG1hdGNoZXMgPSAwOwoKICBpZighYyB8fCAhYy0+Y29va2llcykKICAgIHJldHVybiBOVUxMOyAvKiBubyBjb29raWUgc3RydWN0IG9yIG5vIGNvb2tpZXMgaW4gdGhlIHN0cnVjdCAqLwoKICBjbyA9IGMtPmNvb2tpZXM7CgogIHdoaWxlKGNvKSB7CiAgICAvKiBvbmx5IHByb2Nlc3MgdGhpcyBjb29raWUgaWYgaXQgaXMgbm90IGV4cGlyZWQgb3IgaGFkIG5vIGV4cGlyZQogICAgICAgZGF0ZSBBTkQgdGhhdCBpZiB0aGUgY29va2llIHJlcXVpcmVzIHdlJ3JlIHNlY3VyZSB3ZSBtdXN0IG9ubHkKICAgICAgIGNvbnRpbnVlIGlmIHdlIGFyZSEgKi8KICAgIGlmKCAoIWNvLT5leHBpcmVzIHx8IChjby0+ZXhwaXJlcyA+IG5vdykpICYmCiAgICAgICAgKGNvLT5zZWN1cmU/c2VjdXJlOlRSVUUpICkgewoKICAgICAgLyogbm93IGNoZWNrIGlmIHRoZSBkb21haW4gaXMgY29ycmVjdCAqLwogICAgICBpZighY28tPmRvbWFpbiB8fAogICAgICAgICAoY28tPnRhaWxtYXRjaCAmJiB0YWlsbWF0Y2goY28tPmRvbWFpbiwgaG9zdCkpIHx8CiAgICAgICAgICghY28tPnRhaWxtYXRjaCAmJiBDdXJsX3Jhd19lcXVhbChob3N0LCBjby0+ZG9tYWluKSkgKSB7CiAgICAgICAgLyogdGhlIHJpZ2h0IHBhcnQgb2YgdGhlIGhvc3QgbWF0Y2hlcyB0aGUgZG9tYWluIHN0dWZmIGluIHRoZQogICAgICAgICAgIGNvb2tpZSBkYXRhICovCgogICAgICAgIC8qIG5vdyBjaGVjayB0aGUgbGVmdCBwYXJ0IG9mIHRoZSBwYXRoIHdpdGggdGhlIGNvb2tpZXMgcGF0aAogICAgICAgICAgIHJlcXVpcmVtZW50ICovCiAgICAgICAgaWYoIWNvLT5wYXRoIHx8CiAgICAgICAgICAgLyogbm90IHVzaW5nIGNoZWNrcHJlZml4KCkgYmVjYXVzZSBtYXRjaGluZyBzaG91bGQgYmUKICAgICAgICAgICAgICBjYXNlLXNlbnNpdGl2ZSAqLwogICAgICAgICAgICFzdHJuY21wKGNvLT5wYXRoLCBwYXRoLCBzdHJsZW4oY28tPnBhdGgpKSApIHsKCiAgICAgICAgICAvKiBhbmQgbm93LCB3ZSBrbm93IHRoaXMgaXMgYSBtYXRjaCBhbmQgd2Ugc2hvdWxkIGNyZWF0ZSBhbgogICAgICAgICAgICAgZW50cnkgZm9yIHRoZSByZXR1cm4tbGlua2VkLWxpc3QgKi8KCiAgICAgICAgICBuZXdjbyA9IG1hbGxvYyhzaXplb2Yoc3RydWN0IENvb2tpZSkpOwogICAgICAgICAgaWYobmV3Y28pIHsKICAgICAgICAgICAgLyogZmlyc3QsIGNvcHkgdGhlIHdob2xlIHNvdXJjZSBjb29raWU6ICovCiAgICAgICAgICAgIG1lbWNweShuZXdjbywgY28sIHNpemVvZihzdHJ1Y3QgQ29va2llKSk7CgogICAgICAgICAgICAvKiB0aGVuIG1vZGlmeSBvdXIgbmV4dCAqLwogICAgICAgICAgICBuZXdjby0+bmV4dCA9IG1haW5jbzsKCiAgICAgICAgICAgIC8qIHBvaW50IHRoZSBtYWluIHRvIHVzICovCiAgICAgICAgICAgIG1haW5jbyA9IG5ld2NvOwoKICAgICAgICAgICAgbWF0Y2hlcysrOwogICAgICAgICAgfQogICAgICAgICAgZWxzZSB7CiAgICAgICAgICAgIGZhaWw6CiAgICAgICAgICAgIC8qIGZhaWx1cmUsIGNsZWFyIHVwIHRoZSBhbGxvY2F0ZWQgY2hhaW4gYW5kIHJldHVybiBOVUxMICovCiAgICAgICAgICAgIHdoaWxlKG1haW5jbykgewogICAgICAgICAgICAgIGNvID0gbWFpbmNvLT5uZXh0OwogICAgICAgICAgICAgIGZyZWUobWFpbmNvKTsKICAgICAgICAgICAgICBtYWluY28gPSBjbzsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgcmV0dXJuIE5VTEw7CiAgICAgICAgICB9CiAgICAgICAgfQogICAgICB9CiAgICB9CiAgICBjbyA9IGNvLT5uZXh0OwogIH0KCiAgaWYobWF0Y2hlcykgewogICAgLyogTm93IHdlIG5lZWQgdG8gbWFrZSBzdXJlIHRoYXQgaWYgdGhlcmUgaXMgYSBuYW1lIGFwcGVhcmluZyBtb3JlIHRoYW4KICAgICAgIG9uY2UsIHRoZSBsb25nZXN0IHNwZWNpZmllZCBwYXRoIHZlcnNpb24gY29tZXMgZmlyc3QuIFRvIG1ha2UgdGhpcwogICAgICAgdGhlIHN3aWZ0ZXN0IHdheSwgd2UganVzdCBzb3J0IHRoZW0gYWxsIGJhc2VkIG9uIHBhdGggbGVuZ3RoLiAqLwogICAgc3RydWN0IENvb2tpZSAqKmFycmF5OwogICAgc2l6ZV90IGk7CgogICAgLyogYWxsb2MgYW4gYXJyYXkgYW5kIHN0b3JlIGFsbCBjb29raWUgcG9pbnRlcnMgKi8KICAgIGFycmF5ID0gKHN0cnVjdCBDb29raWUgKiopbWFsbG9jKHNpemVvZihzdHJ1Y3QgQ29va2llICopICogbWF0Y2hlcyk7CiAgICBpZighYXJyYXkpCiAgICAgIGdvdG8gZmFpbDsKCiAgICBjbyA9IG1haW5jbzsKCiAgICBmb3IoaT0wOyBjbzsgY28gPSBjby0+bmV4dCkKICAgICAgYXJyYXlbaSsrXSA9IGNvOwoKICAgIC8qIG5vdyBzb3J0IHRoZSBjb29raWUgcG9pbnRlcnMgaW4gcGF0aCBsZW50aCBvcmRlciAqLwogICAgcXNvcnQoYXJyYXksIG1hdGNoZXMsIHNpemVvZihzdHJ1Y3QgQ29va2llICopLCBjb29raWVfc29ydCk7CgogICAgLyogcmVtYWtlIHRoZSBsaW5rZWQgbGlzdCBvcmRlciBhY2NvcmRpbmcgdG8gdGhlIG5ldyBvcmRlciAqLwoKICAgIG1haW5jbyA9IGFycmF5WzBdOyAvKiBzdGFydCBoZXJlICovCiAgICBmb3IoaT0wOyBpPG1hdGNoZXMtMTsgaSsrKQogICAgICBhcnJheVtpXS0+bmV4dCA9IGFycmF5W2krMV07CiAgICBhcnJheVttYXRjaGVzLTFdLT5uZXh0ID0gTlVMTDsgLyogdGVybWluYXRlIHRoZSBsaXN0ICovCgogICAgZnJlZShhcnJheSk7IC8qIHJlbW92ZSB0aGUgdGVtcG9yYXJ5IGRhdGEgYWdhaW4gKi8KICB9CgogIHJldHVybiBtYWluY287IC8qIHJldHVybiB0aGUgbmV3IGxpc3QgKi8KfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCiAqIEN1cmxfY29va2llX2NsZWFyYWxsKCkKICoKICogQ2xlYXIgYWxsIGV4aXN0aW5nIGNvb2tpZXMgYW5kIHJlc2V0IHRoZSBjb3VudGVyLgogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kdm9pZCBDdXJsX2Nvb2tpZV9jbGVhcmFsbChzdHJ1Y3QgQ29va2llSW5mbyAqY29va2llcykKewogIGlmKGNvb2tpZXMpIHsKICAgIEN1cmxfY29va2llX2ZyZWVsaXN0KGNvb2tpZXMtPmNvb2tpZXMsIFRSVUUpOwogICAgY29va2llcy0+Y29va2llcyA9IE5VTEw7CiAgICBjb29raWVzLT5udW1jb29raWVzID0gMDsKICB9Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgogKiBDdXJsX2Nvb2tpZV9mcmVlbGlzdCgpCiAqCiAqIEZyZWUgYSBsaXN0IG9mIGNvb2tpZXMgcHJldmlvdXNseSByZXR1cm5lZCBieSBDdXJsX2Nvb2tpZV9nZXRsaXN0KCk7CiAqCiAqIFRoZSAnY29va2llc3RvbycgYXJndW1lbnQgdGVsbHMgdGhpcyBmdW5jdGlvbiB3aGV0aGVyIHRvIGp1c3QgZnJlZSB0aGUKICogbGlzdCBvciBhY3R1YWxseSBhbHNvIGZyZWUgYWxsIGNvb2tpZXMgd2l0aGluIHRoZSBsaXN0IGFzIHdlbGwuCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKdm9pZCBDdXJsX2Nvb2tpZV9mcmVlbGlzdChzdHJ1Y3QgQ29va2llICpjbywgYm9vbCBjb29raWVzdG9vKQp7CiAgc3RydWN0IENvb2tpZSAqbmV4dDsKICBpZihjbykgewogICAgd2hpbGUoY28pIHsKICAgICAgbmV4dCA9IGNvLT5uZXh0OwogICAgICBpZihjb29raWVzdG9vKQogICAgICAgIGZyZWVjb29raWUoY28pOwogICAgICBlbHNlCiAgICAgICAgZnJlZShjbyk7IC8qIHdlIG9ubHkgZnJlZSB0aGUgc3RydWN0IHNpbmNlIHRoZSAibWVtYmVycyIgYXJlIGFsbCBqdXN0CiAgICAgICAgICAgICAgICAgICAgIHBvaW50ZWQgb3V0IGluIHRoZSBtYWluIGNvb2tpZSBsaXN0ISAqLwogICAgICBjbyA9IG5leHQ7CiAgICB9CiAgfQp9CgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCiAqIEN1cmxfY29va2llX2NsZWFyc2VzcygpCiAqCiAqIEZyZWUgYWxsIHNlc3Npb24gY29va2llcyBpbiB0aGUgY29va2llcyBsaXN0LgogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8Kdm9pZCBDdXJsX2Nvb2tpZV9jbGVhcnNlc3Moc3RydWN0IENvb2tpZUluZm8gKmNvb2tpZXMpCnsKICBzdHJ1Y3QgQ29va2llICpmaXJzdCwgKmN1cnIsICpuZXh0LCAqcHJldiA9IE5VTEw7CgogIGlmKCFjb29raWVzIHx8ICFjb29raWVzLT5jb29raWVzKQogICAgcmV0dXJuOwoKICBmaXJzdCA9IGN1cnIgPSBwcmV2ID0gY29va2llcy0+Y29va2llczsKCiAgZm9yKDsgY3VycjsgY3VyciA9IG5leHQpIHsKICAgIG5leHQgPSBjdXJyLT5uZXh0OwogICAgaWYoIWN1cnItPmV4cGlyZXMpIHsKICAgICAgaWYoZmlyc3QgPT0gY3VycikKICAgICAgICBmaXJzdCA9IG5leHQ7CgogICAgICBpZihwcmV2ID09IGN1cnIpCiAgICAgICAgcHJldiA9IG5leHQ7CiAgICAgIGVsc2UKICAgICAgICBwcmV2LT5uZXh0ID0gbmV4dDsKCiAgICAgIGZyZWVjb29raWUoY3Vycik7CiAgICAgIGNvb2tpZXMtPm51bWNvb2tpZXMtLTsKICAgIH0KICAgIGVsc2UKICAgICAgcHJldiA9IGN1cnI7CiAgfQoKICBjb29raWVzLT5jb29raWVzID0gZmlyc3Q7Cn0KCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoKICogQ3VybF9jb29raWVfY2xlYW51cCgpCiAqCiAqIEZyZWUgYSAiY29va2llIG9iamVjdCIgcHJldmlvdXMgY3JlYXRlZCB3aXRoIGNvb2tpZV9pbml0KCkuCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwp2b2lkIEN1cmxfY29va2llX2NsZWFudXAoc3RydWN0IENvb2tpZUluZm8gKmMpCnsKICBzdHJ1Y3QgQ29va2llICpjbzsKICBzdHJ1Y3QgQ29va2llICpuZXh0OwogIGlmKGMpIHsKICAgIGlmKGMtPmZpbGVuYW1lKQogICAgICBmcmVlKGMtPmZpbGVuYW1lKTsKICAgIGNvID0gYy0+Y29va2llczsKCiAgICB3aGlsZShjbykgewogICAgICBuZXh0ID0gY28tPm5leHQ7CiAgICAgIGZyZWVjb29raWUoY28pOwogICAgICBjbyA9IG5leHQ7CiAgICB9CiAgICBmcmVlKGMpOyAvKiBmcmVlIHRoZSBiYXNlIHN0cnVjdCBhcyB3ZWxsICovCiAgfQp9CgovKiBnZXRfbmV0c2NhcGVfZm9ybWF0KCkKICoKICogRm9ybWF0cyBhIHN0cmluZyBmb3IgTmV0c2NhcGUgb3V0cHV0IGZpbGUsIHcvbyBhIG5ld2xpbmUgYXQgdGhlIGVuZC4KICoKICogRnVuY3Rpb24gcmV0dXJucyBhIGNoYXIgKiB0byBhIGZvcm1hdHRlZCBsaW5lLiBIYXMgdG8gYmUgZnJlZSgpZAoqLwpzdGF0aWMgY2hhciAqZ2V0X25ldHNjYXBlX2Zvcm1hdChjb25zdCBzdHJ1Y3QgQ29va2llICpjbykKewogIHJldHVybiBhcHJpbnRmKAogICAgIiVzIiAgICAgLyogaHR0cG9ubHkgcHJlYW1ibGUgKi8KICAgICIlcyVzXHQiIC8qIGRvbWFpbiAqLwogICAgIiVzXHQiICAgLyogdGFpbG1hdGNoICovCiAgICAiJXNcdCIgICAvKiBwYXRoICovCiAgICAiJXNcdCIgICAvKiBzZWN1cmUgKi8KICAgICIlIiBGT1JNQVRfT0ZGX1QgIlx0IiAgIC8qIGV4cGlyZXMgKi8KICAgICIlc1x0IiAgIC8qIG5hbWUgKi8KICAgICIlcyIsICAgIC8qIHZhbHVlICovCiAgICBjby0+aHR0cG9ubHk/IiNIdHRwT25seV8iOiIiLAogICAgLyogTWFrZSBzdXJlIGFsbCBkb21haW5zIGFyZSBwcmVmaXhlZCB3aXRoIGEgZG90IGlmIHRoZXkgYWxsb3cKICAgICAgIHRhaWxtYXRjaGluZy4gVGhpcyBpcyBNb3ppbGxhLXN0eWxlLiAqLwogICAgKGNvLT50YWlsbWF0Y2ggJiYgY28tPmRvbWFpbiAmJiBjby0+ZG9tYWluWzBdICE9ICcuJyk/ICIuIjoiIiwKICAgIGNvLT5kb21haW4/Y28tPmRvbWFpbjoidW5rbm93biIsCiAgICBjby0+dGFpbG1hdGNoPyJUUlVFIjoiRkFMU0UiLAogICAgY28tPnBhdGg/Y28tPnBhdGg6Ii8iLAogICAgY28tPnNlY3VyZT8iVFJVRSI6IkZBTFNFIiwKICAgIGNvLT5leHBpcmVzLAogICAgY28tPm5hbWUsCiAgICBjby0+dmFsdWU/Y28tPnZhbHVlOiIiKTsKfQoKLyoKICogQ3VybF9jb29raWVfb3V0cHV0KCkKICoKICogV3JpdGVzIGFsbCBpbnRlcm5hbGx5IGtub3duIGNvb2tpZXMgdG8gdGhlIHNwZWNpZmllZCBmaWxlLiBTcGVjaWZ5CiAqICItIiBhcyBmaWxlIG5hbWUgdG8gd3JpdGUgdG8gc3Rkb3V0LgogKgogKiBUaGUgZnVuY3Rpb24gcmV0dXJucyBub24temVybyBvbiB3cml0ZSBmYWlsdXJlLgogKi8KaW50IEN1cmxfY29va2llX291dHB1dChzdHJ1Y3QgQ29va2llSW5mbyAqYywgY29uc3QgY2hhciAqZHVtcGhlcmUpCnsKICBzdHJ1Y3QgQ29va2llICpjbzsKICBGSUxFICpvdXQ7CiAgYm9vbCB1c2Vfc3Rkb3V0PUZBTFNFOwoKICBpZigoTlVMTCA9PSBjKSB8fCAoMCA9PSBjLT5udW1jb29raWVzKSkKICAgIC8qIElmIHRoZXJlIGFyZSBubyBrbm93biBjb29raWVzLCB3ZSBkb24ndCB3cml0ZSBvciBldmVuIGNyZWF0ZSBhbnkKICAgICAgIGRlc3RpbmF0aW9uIGZpbGUgKi8KICAgIHJldHVybiAwOwoKICBpZihzdHJlcXVhbCgiLSIsIGR1bXBoZXJlKSkgewogICAgLyogdXNlIHN0ZG91dCAqLwogICAgb3V0ID0gc3Rkb3V0OwogICAgdXNlX3N0ZG91dD1UUlVFOwogIH0KICBlbHNlIHsKICAgIG91dCA9IGZvcGVuKGR1bXBoZXJlLCAidyIpOwogICAgaWYoIW91dCkKICAgICAgcmV0dXJuIDE7IC8qIGZhaWx1cmUgKi8KICB9CgogIGlmKGMpIHsKICAgIGNoYXIgKmZvcm1hdF9wdHI7CgogICAgZnB1dHMoIiMgTmV0c2NhcGUgSFRUUCBDb29raWUgRmlsZVxuIgogICAgICAgICAgIiMgaHR0cDovL2N1cmwuaGF4eC5zZS9yZmMvY29va2llX3NwZWMuaHRtbFxuIgogICAgICAgICAgIiMgVGhpcyBmaWxlIHdhcyBnZW5lcmF0ZWQgYnkgbGliY3VybCEgRWRpdCBhdCB5b3VyIG93biByaXNrLlxuXG4iLAogICAgICAgICAgb3V0KTsKICAgIGNvID0gYy0+Y29va2llczsKCiAgICB3aGlsZShjbykgewogICAgICBmb3JtYXRfcHRyID0gZ2V0X25ldHNjYXBlX2Zvcm1hdChjbyk7CiAgICAgIGlmKGZvcm1hdF9wdHIgPT0gTlVMTCkgewogICAgICAgIGZwcmludGYob3V0LCAiI1xuIyBGYXRhbCBsaWJjdXJsIGVycm9yXG4iKTsKICAgICAgICBpZighdXNlX3N0ZG91dCkKICAgICAgICAgIGZjbG9zZShvdXQpOwogICAgICAgIHJldHVybiAxOwogICAgICB9CiAgICAgIGZwcmludGYob3V0LCAiJXNcbiIsIGZvcm1hdF9wdHIpOwogICAgICBmcmVlKGZvcm1hdF9wdHIpOwogICAgICBjbz1jby0+bmV4dDsKICAgIH0KICB9CgogIGlmKCF1c2Vfc3Rkb3V0KQogICAgZmNsb3NlKG91dCk7CgogIHJldHVybiAwOwp9CgpzdHJ1Y3QgY3VybF9zbGlzdCAqQ3VybF9jb29raWVfbGlzdChzdHJ1Y3QgU2Vzc2lvbkhhbmRsZSAqZGF0YSkKewogIHN0cnVjdCBjdXJsX3NsaXN0ICpsaXN0ID0gTlVMTDsKICBzdHJ1Y3QgY3VybF9zbGlzdCAqYmVnOwogIHN0cnVjdCBDb29raWUgKmM7CiAgY2hhciAqbGluZTsKCiAgaWYoKGRhdGEtPmNvb2tpZXMgPT0gTlVMTCkgfHwKICAgICAgKGRhdGEtPmNvb2tpZXMtPm51bWNvb2tpZXMgPT0gMCkpCiAgICByZXR1cm4gTlVMTDsKCiAgYyA9IGRhdGEtPmNvb2tpZXMtPmNvb2tpZXM7CgogIGJlZyA9IGxpc3Q7CiAgd2hpbGUoYykgewogICAgLyogZmlsbCB0aGUgbGlzdCB3aXRoIF9hbGxfIHRoZSBjb29raWVzIHdlIGtub3cgKi8KICAgIGxpbmUgPSBnZXRfbmV0c2NhcGVfZm9ybWF0KGMpOwogICAgaWYobGluZSA9PSBOVUxMKSB7CiAgICAgIGN1cmxfc2xpc3RfZnJlZV9hbGwoYmVnKTsKICAgICAgcmV0dXJuIE5VTEw7CiAgICB9CiAgICBsaXN0ID0gY3VybF9zbGlzdF9hcHBlbmQobGlzdCwgbGluZSk7CiAgICBmcmVlKGxpbmUpOwogICAgaWYobGlzdCA9PSBOVUxMKSB7CiAgICAgIGN1cmxfc2xpc3RfZnJlZV9hbGwoYmVnKTsKICAgICAgcmV0dXJuIE5VTEw7CiAgICB9CiAgICBlbHNlIGlmKGJlZyA9PSBOVUxMKSB7CiAgICAgIGJlZyA9IGxpc3Q7CiAgICB9CiAgICBjID0gYy0+bmV4dDsKICB9CgogIHJldHVybiBsaXN0Owp9CgojZW5kaWYgLyogQ1VSTF9ESVNBQkxFX0hUVFAgfHwgQ1VSTF9ESVNBQkxFX0NPT0tJRVMgKi8K