LyoKICogdGFibGUuYyAKICovCgovKiBQb3J0aW9ucyBvZiB0aGlzIGZpbGUgYXJlIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb3B5cmlnaHQocykuICBTZWUKICogdGhlIE5ldC1TTk1QJ3MgQ09QWUlORyBmaWxlIGZvciBtb3JlIGRldGFpbHMgYW5kIG90aGVyIGNvcHlyaWdodHMKICogdGhhdCBtYXkgYXBwbHk6CiAqLwovKgogKiBQb3J0aW9ucyBvZiB0aGlzIGZpbGUgYXJlIGNvcHlyaWdodGVkIGJ5OgogKiBDb3B5cmlnaHQgqSAyMDAzIFN1biBNaWNyb3N5c3RlbXMsIEluYy4gQWxsIHJpZ2h0cyByZXNlcnZlZC4KICogVXNlIGlzIHN1YmplY3QgdG8gbGljZW5zZSB0ZXJtcyBzcGVjaWZpZWQgaW4gdGhlIENPUFlJTkcgZmlsZQogKiBkaXN0cmlidXRlZCB3aXRoIHRoZSBOZXQtU05NUCBwYWNrYWdlLgogKi8KLyoKICogUG9ydGlvbnMgb2YgdGhpcyBmaWxlIGFyZSBjb3B5cmlnaHRlZCBieToKICogQ29weXJpZ2h0IChDKSAyMDA3IEFwcGxlLCBJbmMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIFVzZSBpcyBzdWJqZWN0IHRvIGxpY2Vuc2UgdGVybXMgc3BlY2lmaWVkIGluIHRoZSBDT1BZSU5HIGZpbGUKICogZGlzdHJpYnV0ZWQgd2l0aCB0aGUgTmV0LVNOTVAgcGFja2FnZS4KICovCgojaW5jbHVkZSA8bmV0LXNubXAvbmV0LXNubXAtY29uZmlnLmg+CgojaW5jbHVkZSA8bmV0LXNubXAvbmV0LXNubXAtZmVhdHVyZXMuaD4KI2luY2x1ZGUgPG5ldC1zbm1wL25ldC1zbm1wLWluY2x1ZGVzLmg+CiNpbmNsdWRlIDxuZXQtc25tcC9hZ2VudC9uZXQtc25tcC1hZ2VudC1pbmNsdWRlcy5oPgoKI2luY2x1ZGUgPG5ldC1zbm1wL2FnZW50L3RhYmxlLmg+CgojaWZuZGVmIE5FVFNOTVBfTk9fV1JJVEVfU1VQUE9SVApuZXRzbm1wX2ZlYXR1cmVfcmVxdWlyZShvaWRfc3Rhc2gpCiNlbmRpZiAvKiAhTkVUU05NUF9OT19XUklURV9TVVBQT1JUICovCgojaWYgSEFWRV9TVFJJTkdfSAojaW5jbHVkZSA8c3RyaW5nLmg+CiNlbHNlCiNpbmNsdWRlIDxzdHJpbmdzLmg+CiNlbmRpZgoKI2luY2x1ZGUgPG5ldC1zbm1wL2xpYnJhcnkvc25tcF9hc3NlcnQuaD4KCm5ldHNubXBfZmVhdHVyZV9jaGlsZF9vZih0YWJsZV9hbGwsIG1pYl9oZWxwZXJzKQoKbmV0c25tcF9mZWF0dXJlX2NoaWxkX29mKHRhYmxlX2J1aWxkX3Jlc3VsdCwgdGFibGVfYWxsKQpuZXRzbm1wX2ZlYXR1cmVfY2hpbGRfb2YodGFibGVfZ2V0X29yX2NyZWF0ZV9yb3dfc3Rhc2gsIHRhYmxlX2FsbCkKbmV0c25tcF9mZWF0dXJlX2NoaWxkX29mKHJlZ2lzdHJhdGlvbl9vd25zX3RhYmxlX2luZm8sIHRhYmxlX2FsbCkKbmV0c25tcF9mZWF0dXJlX2NoaWxkX29mKHRhYmxlX3NwYXJzZSwgdGFibGVfYWxsKQoKc3RhdGljIHZvaWQgICAgIHRhYmxlX2hlbHBlcl9jbGVhbnVwKG5ldHNubXBfYWdlbnRfcmVxdWVzdF9pbmZvICpyZXFpbmZvLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9yZXF1ZXN0X2luZm8gKnJlcXVlc3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgc3RhdHVzKTsKc3RhdGljIHZvaWQgICAgIHRhYmxlX2RhdGFfZnJlZV9mdW5jKHZvaWQgKmRhdGEpOwpzdGF0aWMgaW50CnNwYXJzZV90YWJsZV9oZWxwZXJfaGFuZGxlcihuZXRzbm1wX21pYl9oYW5kbGVyICpoYW5kbGVyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9oYW5kbGVyX3JlZ2lzdHJhdGlvbiAqcmVnaW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfYWdlbnRfcmVxdWVzdF9pbmZvICpyZXFpbmZvLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9yZXF1ZXN0X2luZm8gKnJlcXVlc3RzKTsKCi8qKiBAZGVmZ3JvdXAgdGFibGUgdGFibGUKICogIEhlbHBzIHlvdSBpbXBsZW1lbnQgYSB0YWJsZS4KICogIEBpbmdyb3VwIGhhbmRsZXIKICoKICogIFRoaXMgaGFuZGxlciBoZWxwcyB5b3UgaW1wbGVtZW50IGEgdGFibGUgYnkgZG9pbmcgc29tZSBvZiB0aGUKICogIHByb2Nlc3NpbmcgZm9yIHlvdS4KICogIAogKiAgVGhpcyBoYW5kbGVyIHRydWx5IHNob3dzIHRoZSBwb3dlciBvZiB0aGUgbmV3IGhhbmRsZXIgbWVjaGFuaXNtLgogKiAgQnkgY3JlYXRpbmcgYSB0YWJsZSBoYW5kbGVyIGFuZCBpbmplY3RpbmcgaXQgaW50byB5b3VyIGNhbGxpbmcKICogIGNoYWluLCBvciBieSB1c2luZyB0aGUgbmV0c25tcF9yZWdpc3Rlcl90YWJsZSgpIGZ1bmN0aW9uIHRvIHJlZ2lzdGVyIHlvdXIKICogIHRhYmxlLCB5b3UgZ2V0IGFjY2VzcyB0byBzb21lIHByZS1wYXJzZWQgaW5mb3JtYXRpb24uCiAqICBTcGVjaWZpY2FsbHksIHRoZSB0YWJsZSBoYW5kbGVyIHB1bGxzIG91dCB0aGUgY29sdW1uIG51bWJlciBhbmQKICogIGluZGV4ZXMgZnJvbSB0aGUgcmVxdWVzdCBvaWQgc28gdGhhdCB5b3UgZG9uJ3QgaGF2ZSB0byBkbyB0aGUKICogIGNvbXBsZXggd29yayB0byBkbyB0aGF0IHBhcnNpbmcgd2l0aGluIHlvdXIgb3duIGNvZGUuCiAqCiAqICBUbyBkbyB0aGlzLCB0aGUgdGFibGUgaGFuZGxlciBuZWVkcyB0byBrbm93IHVwIGZyb250IGhvdyB5b3VyCiAqICB0YWJsZSBpcyBzdHJ1Y3R1cmVkLiAgVG8gaW5mb3JtIGl0IGFib3V0IHRoaXMsIHlvdSBmaWxsIGluIGEKICogIHRhYmxlX3JlZ2lzdGVyYXRpb25faW5mbyBzdHJ1Y3R1cmUgdGhhdCBpcyBwYXNzZWQgdG8gdGhlIHRhYmxlCiAqICBoYW5kbGVyLiAgSXQgY29udGFpbnMgdGhlIGFzbiBpbmRleCB0eXBlcyBmb3IgdGhlIHRhYmxlIGFzIHdlbGwgYXMKICogIHRoZSBtaW5pbXVtIGFuZCBtYXhpbXVtIGNvbHVtbiB0aGF0IHNob3VsZCBiZSB1c2VkLgogKiAgCiAqICBAewogKi8KCi8qKiBHaXZlbiBhIG5ldHNubXBfdGFibGVfcmVnaXN0cmF0aW9uX2luZm8gb2JqZWN0LCBjcmVhdGVzIGEgdGFibGUgaGFuZGxlci4KICogIFlvdSBjYW4gdXNlIHRoaXMgdGFibGUgaGFuZGxlciBieSBpbmplY3RpbmcgaXQgaW50byBhIGNhbGxpbmcKICogIGNoYWluLiAgV2hlbiB0aGUgaGFuZGxlciBnZXRzIGNhbGxlZCwgaXQnbGwgZG8gcHJvY2Vzc2luZyBhbmQKICogIHN0b3JlIGl0J3MgaW5mb3JtYXRpb24gaW50byB0aGUgcmVxdWVzdC0+cGFyZW50X2RhdGEgc3RydWN0dXJlLgogKgogKiAgVGhlIHRhYmxlIGhlbHBlciBoYW5kbGVyIHB1bGxzIG91dCB0aGUgY29sdW1uIG51bWJlciBhbmQgaW5kZXhlcyBmcm9tIAogKiAgdGhlIHJlcXVlc3Qgb2lkIHNvIHRoYXQgeW91IGRvbid0IGhhdmUgdG8gZG8gdGhlIGNvbXBsZXggd29yayBvZgogKiAgcGFyc2luZyB3aXRoaW4geW91ciBvd24gY29kZS4KICoKICogIEBwYXJhbSB0YWJyZXEgaXMgYSBwb2ludGVyIHRvIGEgbmV0c25tcF90YWJsZV9yZWdpc3RyYXRpb25faW5mbyBzdHJ1Y3QuCiAqCVRoZSB0YWJsZSBoYW5kbGVyIG5lZWRzIHRvIGtub3cgdXAgZnJvbnQgaG93IHlvdXIgdGFibGUgaXMgc3RydWN0dXJlZC4KICoJQSBuZXRzbm1wX3RhYmxlX3JlZ2lzdGVyYXRpb25faW5mbyBzdHJ1Y3R1cmUgdGhhdCBpcyAKICoJcGFzc2VkIHRvIHRoZSB0YWJsZSBoYW5kbGVyIHNob3VsZCBjb250YWluIHRoZSBhc24gaW5kZXggdHlwZXMgZm9yIHRoZSAKICoJdGFibGUgYXMgd2VsbCBhcyB0aGUgbWluaW11bSBhbmQgbWF4aW11bSBjb2x1bW4gdGhhdCBzaG91bGQgYmUgdXNlZC4KICoKICogIEByZXR1cm4gUmV0dXJucyBhIHBvaW50ZXIgdG8gYSBuZXRzbm1wX21pYl9oYW5kbGVyIHN0cnVjdCB3aGljaCBjb250YWlucwogKgl0aGUgaGFuZGxlcidzIG5hbWUgYW5kIHRoZSBhY2Nlc3MgbWV0aG9kCiAqCiAqLwpuZXRzbm1wX21pYl9oYW5kbGVyICoKbmV0c25tcF9nZXRfdGFibGVfaGFuZGxlcihuZXRzbm1wX3RhYmxlX3JlZ2lzdHJhdGlvbl9pbmZvICp0YWJyZXEpCnsKICAgIG5ldHNubXBfbWliX2hhbmRsZXIgKnJldCA9IE5VTEw7CgogICAgaWYgKCF0YWJyZXEpIHsKICAgICAgICBzbm1wX2xvZyhMT0dfSU5GTywgIm5ldHNubXBfZ2V0X3RhYmxlX2hhbmRsZXIoTlVMTCkgY2FsbGVkXG4iKTsKICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0KCiAgICByZXQgPSBuZXRzbm1wX2NyZWF0ZV9oYW5kbGVyKFRBQkxFX0hBTkRMRVJfTkFNRSwgdGFibGVfaGVscGVyX2hhbmRsZXIpOwogICAgaWYgKHJldCkgewogICAgICAgIHJldC0+bXl2b2lkID0gKHZvaWQgKikgdGFicmVxOwogICAgICAgIHRhYnJlcS0+bnVtYmVyX2luZGV4ZXMgPSBjb3VudF92YXJiaW5kcyh0YWJyZXEtPmluZGV4ZXMpOwogICAgfQogICAgcmV0dXJuIHJldDsKfQoKLyoqIENvbmZpZ3VyZXMgYSBoYW5kbGVyIHN1Y2ggdGhhdCB0YWJsZSByZWdpc3RyYXRpb24gaW5mb3JtYXRpb24gaXMgZnJlZWQgYnkKICogIG5ldHNubXBfaGFuZGxlcl9mcmVlKCkuIFNob3VsZCBvbmx5IGJlIGNhbGxlZCBpZiBoYW5kbGVyLT5teXZvaWQgcG9pbnRzIHRvCiAqICBhbiBvYmplY3Qgb2YgdHlwZSBuZXRzbm1wX3RhYmxlX3JlZ2lzdHJhdGlvbl9pbmZvLgogKi8Kdm9pZCBuZXRzbm1wX2hhbmRsZXJfb3duc190YWJsZV9pbmZvKG5ldHNubXBfbWliX2hhbmRsZXIgKmhhbmRsZXIpCnsKICAgIG5ldHNubXBfYXNzZXJ0KGhhbmRsZXIpOwogICAgbmV0c25tcF9hc3NlcnQoaGFuZGxlci0+bXl2b2lkKTsKICAgIGhhbmRsZXItPmRhdGFfY2xvbmUKCT0gKHZvaWQgKigqKSh2b2lkICopKSBuZXRzbm1wX3RhYmxlX3JlZ2lzdHJhdGlvbl9pbmZvX2Nsb25lOwogICAgaGFuZGxlci0+ZGF0YV9mcmVlCgk9ICh2b2lkICgqKSh2b2lkICopKSBuZXRzbm1wX3RhYmxlX3JlZ2lzdHJhdGlvbl9pbmZvX2ZyZWU7Cn0KCi8qKiBDb25maWd1cmVzIGEgaGFuZGxlciBzdWNoIHRoYXQgdGFibGUgcmVnaXN0cmF0aW9uIGluZm9ybWF0aW9uIGlzIGZyZWVkIGJ5CiAqICBuZXRzbm1wX2hhbmRsZXJfZnJlZSgpLiBTaG91bGQgb25seSBiZSBjYWxsZWQgaWYgcmVnLT5oYW5kbGVyLT5teXZvaWQKICogIHBvaW50cyB0byBhbiBvYmplY3Qgb2YgdHlwZSBuZXRzbm1wX3RhYmxlX3JlZ2lzdHJhdGlvbl9pbmZvLgogKi8KI2lmbmRlZiBORVRTTk1QX0ZFQVRVUkVfUkVNT1ZFX1JFR0lTVFJBVElPTl9PV05TX1RBQkxFX0lORk8Kdm9pZCBuZXRzbm1wX3JlZ2lzdHJhdGlvbl9vd25zX3RhYmxlX2luZm8obmV0c25tcF9oYW5kbGVyX3JlZ2lzdHJhdGlvbiAqcmVnKQp7CiAgICBpZiAocmVnKQogICAgICAgIG5ldHNubXBfaGFuZGxlcl9vd25zX3RhYmxlX2luZm8ocmVnLT5oYW5kbGVyKTsKfQojZW5kaWYgLyogTkVUU05NUF9GRUFUVVJFX1JFTU9WRV9SRUdJU1RSQVRJT05fT1dOU19UQUJMRV9JTkZPICovCgovKiogY3JlYXRlcyBhIHRhYmxlIGhhbmRsZXIgZ2l2ZW4gdGhlIG5ldHNubXBfdGFibGVfcmVnaXN0cmF0aW9uX2luZm8gb2JqZWN0LAogKiAgaW5zZXJ0cyBpdCBpbnRvIHRoZSByZXF1ZXN0IGNoYWluIGFuZCB0aGVuIGNhbGxzCiAqICBuZXRzbm1wX3JlZ2lzdGVyX2hhbmRsZXIoKSB0byByZWdpc3RlciB0aGUgdGFibGUgaW50byB0aGUgYWdlbnQuCiAqLwppbnQKbmV0c25tcF9yZWdpc3Rlcl90YWJsZShuZXRzbm1wX2hhbmRsZXJfcmVnaXN0cmF0aW9uICpyZWdpbmZvLAogICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfdGFibGVfcmVnaXN0cmF0aW9uX2luZm8gKnRhYnJlcSkKewogICAgaW50IHJjID0gbmV0c25tcF9pbmplY3RfaGFuZGxlcihyZWdpbmZvLCBuZXRzbm1wX2dldF90YWJsZV9oYW5kbGVyKHRhYnJlcSkpOwogICAgaWYgKFNOTVBFUlJfU1VDQ0VTUyAhPSByYykKICAgICAgICByZXR1cm4gcmM7CgogICAgcmV0dXJuIG5ldHNubXBfcmVnaXN0ZXJfaGFuZGxlcihyZWdpbmZvKTsKfQoKaW50Cm5ldHNubXBfdW5yZWdpc3Rlcl90YWJsZShuZXRzbm1wX2hhbmRsZXJfcmVnaXN0cmF0aW9uICpyZWdpbmZvKQp7CiAgICAvKiBMb2NhdGUgInRoaXMiIHJlZ2luZm8gKi8KICAgIC8qIFNOTVBfRlJFRShyZWdpbmZvLT5teXZvaWQpOyAqLwogICAgcmV0dXJuIG5ldHNubXBfdW5yZWdpc3Rlcl9oYW5kbGVyKHJlZ2luZm8pOwp9CgovKiogRXh0cmFjdHMgdGhlIHByb2Nlc3NlZCB0YWJsZSBpbmZvcm1hdGlvbiBmcm9tIGEgZ2l2ZW4gcmVxdWVzdC4KICogIENhbGwgdGhpcyBmcm9tIHN1YmhhbmRsZXJzIG9uIGEgcmVxdWVzdCB0byBleHRyYWN0IHRoZSBwcm9jZXNzZWQKICogIG5ldHNubXBfcmVxdWVzdF9pbmZvIGluZm9ybWF0aW9uLiAgVGhlIHJlc3VsdGluZyBpbmZvcm1hdGlvbiBpbmNsdWRlcyB0aGUKICogIGluZGV4IHZhbHVlcyBhbmQgdGhlIGNvbHVtbiBudW1iZXIuCiAqCiAqIEBwYXJhbSByZXF1ZXN0IHBvcHVsYXRlZCBuZXRzbm1wIHJlcXVlc3Qgc3RydWN0dXJlCiAqCiAqIEByZXR1cm4gcG9wdWxhdGVkIG5ldHNubXBfdGFibGVfcmVxdWVzdF9pbmZvIHN0cnVjdHVyZQogKi8KTkVUU05NUF9JTkxJTkUgbmV0c25tcF90YWJsZV9yZXF1ZXN0X2luZm8gKgpuZXRzbm1wX2V4dHJhY3RfdGFibGVfaW5mbyhuZXRzbm1wX3JlcXVlc3RfaW5mbyAqcmVxdWVzdCkKewogICAgcmV0dXJuIChuZXRzbm1wX3RhYmxlX3JlcXVlc3RfaW5mbyAqKQogICAgICAgIG5ldHNubXBfcmVxdWVzdF9nZXRfbGlzdF9kYXRhKHJlcXVlc3QsIFRBQkxFX0hBTkRMRVJfTkFNRSk7Cn0KCi8qKiBleHRyYWN0cyB0aGUgcmVnaXN0ZXJlZCBuZXRzbm1wX3RhYmxlX3JlZ2lzdHJhdGlvbl9pbmZvIG9iamVjdCBmcm9tIGEKICogIG5ldHNubXBfaGFuZGxlcl9yZWdpc3RyYXRpb24gb2JqZWN0ICovCm5ldHNubXBfdGFibGVfcmVnaXN0cmF0aW9uX2luZm8gKgpuZXRzbm1wX2ZpbmRfdGFibGVfcmVnaXN0cmF0aW9uX2luZm8obmV0c25tcF9oYW5kbGVyX3JlZ2lzdHJhdGlvbiAqcmVnaW5mbykKewogICAgcmV0dXJuIChuZXRzbm1wX3RhYmxlX3JlZ2lzdHJhdGlvbl9pbmZvICopCiAgICAgICAgbmV0c25tcF9maW5kX2hhbmRsZXJfZGF0YV9ieV9uYW1lKHJlZ2luZm8sIFRBQkxFX0hBTkRMRVJfTkFNRSk7Cn0KCi8qKiBpbXBsZW1lbnRzIHRoZSB0YWJsZSBoZWxwZXIgaGFuZGxlciAqLwppbnQKdGFibGVfaGVscGVyX2hhbmRsZXIobmV0c25tcF9taWJfaGFuZGxlciAqaGFuZGxlciwKICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9oYW5kbGVyX3JlZ2lzdHJhdGlvbiAqcmVnaW5mbywKICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9hZ2VudF9yZXF1ZXN0X2luZm8gKnJlcWluZm8sCiAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfcmVxdWVzdF9pbmZvICpyZXF1ZXN0cykKewoKICAgIG5ldHNubXBfcmVxdWVzdF9pbmZvICpyZXF1ZXN0OwogICAgbmV0c25tcF90YWJsZV9yZWdpc3RyYXRpb25faW5mbyAqdGJsX2luZm87CiAgICBpbnQgICAgICAgICAgICAgb2lkX2luZGV4X3BvczsKICAgIHVuc2lnbmVkIGludCAgICBvaWRfY29sdW1uX3BvczsKICAgIHVuc2lnbmVkIGludCAgICB0bXBfaWR4OwogICAgc3NpemVfdCAJICAgIHRtcF9sZW47CiAgICBpbnQgICAgICAgICAgICAgaW5jb21wbGV0ZSwgb3V0X29mX3JhbmdlOwogICAgaW50ICAgICAgICAgICAgIHN0YXR1cyA9IFNOTVBfRVJSX05PRVJST1IsIG5lZWRfcHJvY2Vzc2luZyA9IDA7CiAgICBvaWQgICAgICAgICAgICAqdG1wX25hbWU7CiAgICBuZXRzbm1wX3RhYmxlX3JlcXVlc3RfaW5mbyAqdGJsX3JlcV9pbmZvOwogICAgbmV0c25tcF92YXJpYWJsZV9saXN0ICp2YjsKCiAgICBpZiAoIXJlZ2luZm8gfHwgIWhhbmRsZXIpCiAgICAgICAgcmV0dXJuIFNOTVBFUlJfR0VORVJSOwoKICAgIG9pZF9pbmRleF9wb3MgID0gcmVnaW5mby0+cm9vdG9pZF9sZW4gKyAyOwogICAgb2lkX2NvbHVtbl9wb3MgPSByZWdpbmZvLT5yb290b2lkX2xlbiArIDE7CiAgICB0YmxfaW5mbyA9IChuZXRzbm1wX3RhYmxlX3JlZ2lzdHJhdGlvbl9pbmZvICopIGhhbmRsZXItPm15dm9pZDsKCiAgICBpZiAoKCFoYW5kbGVyLT5teXZvaWQpIHx8ICghdGJsX2luZm8tPmluZGV4ZXMpKSB7CiAgICAgICAgc25tcF9sb2coTE9HX0VSUiwgImltcHJvcGVybHkgcmVnaXN0ZXJlZCB0YWJsZSBmb3VuZFxuIik7CiAgICAgICAgc25tcF9sb2coTE9HX0VSUiwgIm5hbWU6ICVzLCB0YWJsZSBpbmZvOiAlcCwgaW5kZXhlczogJXBcbiIsCiAgICAgICAgICAgICAgICAgaGFuZGxlci0+aGFuZGxlcl9uYW1lLCBoYW5kbGVyLT5teXZvaWQsIHRibF9pbmZvLT5pbmRleGVzKTsKCiAgICAgICAgLyoKICAgICAgICAgKiBYWFgtcmtzOiB1bnJlZ2lzdGVyIHRhYmxlPyAKICAgICAgICAgKi8KICAgICAgICByZXR1cm4gU05NUF9FUlJfR0VORVJSOwogICAgfQoKICAgIERFQlVHSUYoImhlbHBlcjp0YWJsZTpyZXEiKSB7CiAgICAgICAgREVCVUdNU0dUTCgoImhlbHBlcjp0YWJsZTpyZXEiLAogICAgICAgICAgICAgICAgICAgICJHb3QgJXMgKCVkKSBtb2RlIHJlcXVlc3QgZm9yIGhhbmRsZXIgJXM6IGJhc2Ugb2lkOiIsCiAgICAgICAgICAgICAgICAgICAgc2VfZmluZF9sYWJlbF9pbl9zbGlzdCgiYWdlbnRfbW9kZSIsIHJlcWluZm8tPm1vZGUpLAogICAgICAgICAgICAgICAgICAgIHJlcWluZm8tPm1vZGUsIGhhbmRsZXItPmhhbmRsZXJfbmFtZSkpOwogICAgICAgIERFQlVHTVNHT0lEKCgiaGVscGVyOnRhYmxlOnJlcSIsIHJlZ2luZm8tPnJvb3RvaWQsCiAgICAgICAgICAgICAgICAgICAgIHJlZ2luZm8tPnJvb3RvaWRfbGVuKSk7CiAgICAgICAgREVCVUdNU0coKCJoZWxwZXI6dGFibGU6cmVxIiwgIlxuIikpOwogICAgfQogICAgCiAgICAvKgogICAgICogaWYgdGhlIGFnZW50IHJlcXVlc3QgaW5mbyBoYXMgYSBzdGF0ZSByZWZlcmVuY2UsIHRoZW4gdGhpcyBpcyBhIAogICAgICogbGF0ZXIgcGFzcyBvZiBhIHNldCByZXF1ZXN0IGFuZCB3ZSBjYW4gc2tpcCBhbGwgdGhlIGxvb2t1cCBzdHVmZi4KICAgICAqCiAgICAgKiB4eHgtcmtzOiB0aGlzIG1pZ2h0IGJyZWFrIGZvciBoYW5kbGVycyB3aGljaCBvbmx5IGhhbmRsZSBvbmUgdmFyYmluZAogICAgICogYXQgYSB0aW1lLi4uIHRob3NlIGhhbmRsZXJzIHNob3VsZCBub3Qgc2F2ZSBkYXRhIGJ5IHRoZWlyIGhhbmRsZXJfbmFtZQogICAgICogaW4gdGhlIG5ldHNubXBfYWdlbnRfcmVxdWVzdF9pbmZvLiAKICAgICAqLwogICAgaWYgKG5ldHNubXBfYWdlbnRfZ2V0X2xpc3RfZGF0YShyZXFpbmZvLCBoYW5kbGVyLT5uZXh0LT5oYW5kbGVyX25hbWUpKSB7CiNpZm5kZWYgTkVUU05NUF9OT19XUklURV9TVVBQT1JUCiAgICAgICAgaWYgKE1PREVfSVNfU0VUKHJlcWluZm8tPm1vZGUpKSB7CiAgICAgICAgICAgIHJldHVybiBuZXRzbm1wX2NhbGxfbmV4dF9oYW5kbGVyKGhhbmRsZXIsIHJlZ2luZm8sIHJlcWluZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcXVlc3RzKTsKICAgICAgICB9IGVsc2UgewojZW5kaWYgLyogTkVUU05NUF9OT19XUklURV9TVVBQT1JUICovCi8qKiBYWFgtcmtzOiBtZW1vcnkgbGVhay4gYWRkIGNsZWFudXAgaGFuZGxlcj8gKi8KICAgICAgICAgICAgbmV0c25tcF9mcmVlX2FnZW50X2RhdGFfc2V0cyhyZXFpbmZvKTsKI2lmbmRlZiBORVRTTk1QX05PX1dSSVRFX1NVUFBPUlQKICAgICAgICB9CiNlbmRpZiAvKiBORVRTTk1QX05PX1dSSVRFX1NVUFBPUlQgKi8KICAgIH0KCiNpZm5kZWYgTkVUU05NUF9OT19XUklURV9TVVBQT1JUCiAgICBpZiAoIE1PREVfSVNfU0VUKHJlcWluZm8tPm1vZGUpICYmCiAgICAgICAgIChyZXFpbmZvLT5tb2RlICE9IE1PREVfU0VUX1JFU0VSVkUxKSkgewogICAgICAgIC8qCiAgICAgICAgICogZm9yIGxhdGVyIHNldCBtb2Rlcywgd2UgY2FuIHNraXAgYWxsIHRoZSBpbmRleCBwYXJzaW5nLAogICAgICAgICAqIGFuZCB3ZSBhbHdheXMgbmVlZCB0byBsZXQgY2hpbGQgaGFuZGxlcnMgaGF2ZSBhIGNoYW5jZQogICAgICAgICAqIHRvIGNsZWFuIHVwLCBpZiB0aGV5IHdlcmUgY2FsbGVkIGluIHRoZSBmaXJzdCBwbGFjZSAoaS5lLiBoYXZlCiAgICAgICAgICogYSB2YWxpZCB0YWJsZSBpbmZvIHBvaW50ZXIpLgogICAgICAgICAqLwogICAgICAgIGlmKE5VTEwgPT0gbmV0c25tcF9leHRyYWN0X3RhYmxlX2luZm8ocmVxdWVzdHMpKSB7CiAgICAgICAgICAgIERFQlVHTVNHVEwoKCJoZWxwZXI6dGFibGUiLCJubyB0YWJsZSBpbmZvIGZvciBzZXQgLSBza2lwcGluZ1xuIikpOwogICAgICAgIH0KICAgICAgICBlbHNlCiAgICAgICAgICAgIG5lZWRfcHJvY2Vzc2luZyA9IDE7CiAgICB9CiAgICBlbHNlIHsKI2VuZGlmIC8qIE5FVFNOTVBfTk9fV1JJVEVfU1VQUE9SVCAqLwogICAgICAgIC8qCiAgICAgICAgICogZm9yIEdFVFMsIG9ubHkgY29udGludWUgaWYgd2UgaGF2ZSBhdCBsZWFzdCBvbmUgdmFsaWQgcmVxdWVzdC4KICAgICAgICAgKiBmb3IgUkVTRVJWRTEsIG9ubHkgY29udGludWUgaWYgd2UgaGF2ZSBpbmRleGVzIGZvciBhbGwgcmVxdWVzdHMuCiAgICAgICAgICovCiAgICAgICAgICAgCiAgICAvKgogICAgICogbG9vcCB0aHJvdWdoIHJlcXVlc3RzCiAgICAgKi8KCiAgICBmb3IgKHJlcXVlc3QgPSByZXF1ZXN0czsgcmVxdWVzdDsgcmVxdWVzdCA9IHJlcXVlc3QtPm5leHQpIHsKICAgICAgICBuZXRzbm1wX3ZhcmlhYmxlX2xpc3QgKnZhciA9IHJlcXVlc3QtPnJlcXVlc3R2YjsKCiAgICAgICAgREVCVUdNU0dPSUQoKCJ2ZXJib3NlOnRhYmxlIiwgdmFyLT5uYW1lLCB2YXItPm5hbWVfbGVuZ3RoKSk7CiAgICAgICAgREVCVUdNU0coKCJ2ZXJib3NlOnRhYmxlIiwgIlxuIikpOwoKICAgICAgICBpZiAocmVxdWVzdC0+cHJvY2Vzc2VkKSB7CiAgICAgICAgICAgIERFQlVHTVNHKCgidmVyYm9zZTp0YWJsZSIsICJhbHJlYWR5IHByb2Nlc3NlZFxuIikpOwogICAgICAgICAgICBjb250aW51ZTsKICAgICAgICB9CiAgICAgICAgbmV0c25tcF9hc3NlcnQocmVxdWVzdC0+c3RhdHVzID09IFNOTVBfRVJSX05PRVJST1IpOwoKICAgICAgICAvKgogICAgICAgICAqIHRoaXMgc2hvdWxkIHByb2JhYmx5IGJlIGhhbmRsZWQgZnVydGhlciB1cCAKICAgICAgICAgKi8KICAgICAgICBpZiAoKHJlcWluZm8tPm1vZGUgPT0gTU9ERV9HRVQpICYmICh2YXItPnR5cGUgIT0gQVNOX05VTEwpKSB7CiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIHZhbGlkIHJlcXVlc3QgaWYgQVNOX05VTEwgCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBERUJVR01TR1RMKCgiaGVscGVyOnRhYmxlIiwKICAgICAgICAgICAgICAgICAgICAgICAgIiAgR0VUIHZhciB0eXBlIGlzIG5vdCBBU05fTlVMTFxuIikpOwogICAgICAgICAgICBuZXRzbm1wX3NldF9yZXF1ZXN0X2Vycm9yKHJlcWluZm8sIHJlcXVlc3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU05NUF9FUlJfV1JPTkdUWVBFKTsKICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgfQoKI2lmbmRlZiBORVRTTk1QX05PX1dSSVRFX1NVUFBPUlQKICAgICAgICBpZiAocmVxaW5mby0+bW9kZSA9PSBNT0RFX1NFVF9SRVNFUlZFMSkgewogICAgICAgICAgICBERUJVR0lGKCJoZWxwZXI6dGFibGU6c2V0IikgewogICAgICAgICAgICAgICAgdV9jaGFyICAgICAgICAgKmJ1ZiA9IE5VTEw7CiAgICAgICAgICAgICAgICBzaXplX3QgICAgICAgICAgYnVmX2xlbiA9IDAsIG91dF9sZW4gPSAwOwogICAgICAgICAgICAgICAgREVCVUdNU0dUTCgoImhlbHBlcjp0YWJsZTpzZXQiLCAiIFNFVF9SRVFVRVNUIGZvciBPSUQ6ICIpKTsKICAgICAgICAgICAgICAgIERFQlVHTVNHT0lEKCgiaGVscGVyOnRhYmxlOnNldCIsIHZhci0+bmFtZSwgdmFyLT5uYW1lX2xlbmd0aCkpOwogICAgICAgICAgICAgICAgb3V0X2xlbiA9IDA7CiAgICAgICAgICAgICAgICBpZiAoc3ByaW50X3JlYWxsb2NfYnlfdHlwZSgmYnVmLCAmYnVmX2xlbiwgJm91dF9sZW4sIDEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXIsIE5VTEwsIE5VTEwsIE5VTEwpKSB7CiAgICAgICAgICAgICAgICAgICAgREVCVUdNU0coKCJoZWxwZXI6dGFibGU6c2V0IiwiIHR5cGU9JWQoJTAyeCksIHZhbHVlPSVzXG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXItPnR5cGUsIHZhci0+dHlwZSwgYnVmKSk7CiAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgIGlmIChidWYgIT0gTlVMTCkgewogICAgICAgICAgICAgICAgICAgICAgICBERUJVR01TRygoImhlbHBlcjp0YWJsZTpzZXQiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiB0eXBlPSVkKCUwMngpLCB2YWx1ZT0lcyBbVFJVTkNBVEVEXVxuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhci0+dHlwZSwgdmFyLT50eXBlLCBidWYpKTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICBERUJVR01TRygoImhlbHBlcjp0YWJsZTpzZXQiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIiB0eXBlPSVkKCUwMngpLCB2YWx1ZT1bTklMXSBbVFJVTkNBVEVEXVxuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhci0+dHlwZSwgdmFyLT50eXBlKSk7CiAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgaWYgKGJ1ZiAhPSBOVUxMKSB7CiAgICAgICAgICAgICAgICAgICAgZnJlZShidWYpOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQojZW5kaWYgLyogTkVUU05NUF9OT19XUklURV9TVVBQT1JUICovCgogICAgICAgIC8qCiAgICAgICAgICogY2hlY2sgdG8gbWFrZSBzdXJlIGl0cyBpbiB0YWJsZSByYW5nZSAKICAgICAgICAgKi8KCiAgICAgICAgb3V0X29mX3JhbmdlID0gMDsKICAgICAgICAvKgogICAgICAgICAqIGlmIG91ciByb290IG9pZCBpcyA+IHZhci0+bmFtZSBhbmQgdGhpcyBpcyBub3QgYSBHRVRORVhULCAKICAgICAgICAgKiB0aGVuIHRoZSBvaWQgaXMgb3V0IG9mIHJhbmdlLiAob25seSBjb21wYXJlIHVwIHRvIHNob3J0ZXIgCiAgICAgICAgICogbGVuZ3RoKSAKICAgICAgICAgKi8KICAgICAgICBpZiAocmVnaW5mby0+cm9vdG9pZF9sZW4gPiB2YXItPm5hbWVfbGVuZ3RoKQogICAgICAgICAgICB0bXBfbGVuID0gdmFyLT5uYW1lX2xlbmd0aDsKICAgICAgICBlbHNlCiAgICAgICAgICAgIHRtcF9sZW4gPSByZWdpbmZvLT5yb290b2lkX2xlbjsKICAgICAgICBpZiAoc25tcF9vaWRfY29tcGFyZShyZWdpbmZvLT5yb290b2lkLCByZWdpbmZvLT5yb290b2lkX2xlbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YXItPm5hbWUsIHRtcF9sZW4pID4gMCkgewogICAgICAgICAgICBpZiAocmVxaW5mby0+bW9kZSA9PSBNT0RFX0dFVE5FWFQpIHsKICAgICAgICAgICAgICAgIGlmICh2YXItPm5hbWUgIT0gdmFyLT5uYW1lX2xvYykKICAgICAgICAgICAgICAgICAgICBTTk1QX0ZSRUUodmFyLT5uYW1lKTsKICAgICAgICAgICAgICAgIHNubXBfc2V0X3Zhcl9vYmppZCh2YXIsIHJlZ2luZm8tPnJvb3RvaWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVnaW5mby0+cm9vdG9pZF9sZW4pOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgREVCVUdNU0dUTCgoImhlbHBlcjp0YWJsZSIsICIgIG9pZCBpcyBvdXQgb2YgcmFuZ2UuXG4iKSk7CiAgICAgICAgICAgICAgICBvdXRfb2ZfcmFuZ2UgPSAxOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIC8qCiAgICAgICAgICogaWYgdmFyLT5uYW1lIGlzIGxvbmdlciB0aGFuIHRoZSByb290LCBtYWtlIHN1cmUgaXQgaXMgCiAgICAgICAgICogdGFibGUuMSAodGFibGUuRU5UUlkpLiAgCiAgICAgICAgICovCiAgICAgICAgZWxzZSBpZiAoKHZhci0+bmFtZV9sZW5ndGggPiByZWdpbmZvLT5yb290b2lkX2xlbikgJiYKICAgICAgICAgICAgICAgICAodmFyLT5uYW1lW3JlZ2luZm8tPnJvb3RvaWRfbGVuXSAhPSAxKSkgewogICAgICAgICAgICBpZiAoKHZhci0+bmFtZVtyZWdpbmZvLT5yb290b2lkX2xlbl0gPCAxKSAmJgogICAgICAgICAgICAgICAgKHJlcWluZm8tPm1vZGUgPT0gTU9ERV9HRVRORVhUKSkgewogICAgICAgICAgICAgICAgdmFyLT5uYW1lW3JlZ2luZm8tPnJvb3RvaWRfbGVuXSA9IDE7CiAgICAgICAgICAgICAgICB2YXItPm5hbWVfbGVuZ3RoID0gcmVnaW5mby0+cm9vdG9pZF9sZW47CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICBvdXRfb2ZfcmFuZ2UgPSAxOwogICAgICAgICAgICAgICAgREVCVUdNU0dUTCgoImhlbHBlcjp0YWJsZSIsICIgIG9pZCBpcyBvdXQgb2YgcmFuZ2UuXG4iKSk7CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgLyoKICAgICAgICAgKiBpZiBpdCBpcyBub3QgaW4gcmFuZ2UsIHRoZW4gbWFyayBpdCBpbiB0aGUgcmVxdWVzdCBsaXN0IAogICAgICAgICAqIGJlY2F1c2Ugd2UgY2FuJ3QgcHJvY2VzcyBpdCwgYW5kIHNldCBhbiBlcnJvciBzbwogICAgICAgICAqIG5vYm9keSBlbHNlIHdhc3RlcyB0aW1lIHRyeWluZyB0byBwcm9jZXNzIGl0IGVpdGhlci4gIAogICAgICAgICAqLwogICAgICAgIGlmIChvdXRfb2ZfcmFuZ2UpIHsKICAgICAgICAgICAgREVCVUdNU0dUTCgoImhlbHBlcjp0YWJsZSIsICIgIE5vdCBwcm9jZXNzZWQ6ICIpKTsKICAgICAgICAgICAgREVCVUdNU0dPSUQoKCJoZWxwZXI6dGFibGUiLCB2YXItPm5hbWUsIHZhci0+bmFtZV9sZW5ndGgpKTsKICAgICAgICAgICAgREVCVUdNU0coKCJoZWxwZXI6dGFibGUiLCAiXG4iKSk7CgogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiAgUmVqZWN0IHJlcXVlc3RzIG9mIHRoZSBmb3JtICdteVRhYmxlLk4nICAgKE4gIT0gMSkKICAgICAgICAgICAgICovCiNpZm5kZWYgTkVUU05NUF9OT19XUklURV9TVVBQT1JUCiAgICAgICAgICAgIGlmIChyZXFpbmZvLT5tb2RlID09IE1PREVfU0VUX1JFU0VSVkUxKQogICAgICAgICAgICAgICAgdGFibGVfaGVscGVyX2NsZWFudXAocmVxaW5mbywgcmVxdWVzdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNOTVBfRVJSX05PVFdSSVRBQkxFKTsKICAgICAgICAgICAgZWxzZQojZW5kaWYgLyogTkVUU05NUF9OT19XUklURV9TVVBQT1JUICovCiAgICAgICAgICAgIGlmIChyZXFpbmZvLT5tb2RlID09IE1PREVfR0VUKQogICAgICAgICAgICAgICAgdGFibGVfaGVscGVyX2NsZWFudXAocmVxaW5mbywgcmVxdWVzdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNOTVBfTk9TVUNIT0JKRUNUKTsKICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgfQoKCiAgICAgICAgLyoKICAgICAgICAgKiBDaGVjayBjb2x1bW4gcmFuZ2VzOyBzZXQtdXAgdG8gcHVsbCBvdXQgaW5kZXhlcyBmcm9tIE9JRC4gCiAgICAgICAgICovCgogICAgICAgIGluY29tcGxldGUgPSAwOwogICAgICAgIHRibF9yZXFfaW5mbyA9IG5ldHNubXBfZXh0cmFjdF90YWJsZV9pbmZvKHJlcXVlc3QpOwogICAgICAgIGlmIChOVUxMID09IHRibF9yZXFfaW5mbykgewogICAgICAgICAgICB0YmxfcmVxX2luZm8gPSBTTk1QX01BTExPQ19UWVBFREVGKG5ldHNubXBfdGFibGVfcmVxdWVzdF9pbmZvKTsKICAgICAgICAgICAgaWYgKHRibF9yZXFfaW5mbyA9PSBOVUxMKSB7CiAgICAgICAgICAgICAgICB0YWJsZV9oZWxwZXJfY2xlYW51cChyZXFpbmZvLCByZXF1ZXN0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU05NUF9FUlJfR0VORVJSKTsKICAgICAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHRibF9yZXFfaW5mby0+cmVnX2luZm8gPSB0YmxfaW5mbzsKICAgICAgICAgICAgdGJsX3JlcV9pbmZvLT5pbmRleGVzID0gc25tcF9jbG9uZV92YXJiaW5kKHRibF9pbmZvLT5pbmRleGVzKTsKICAgICAgICAgICAgdGJsX3JlcV9pbmZvLT5udW1iZXJfaW5kZXhlcyA9IDA7ICAgICAgIC8qIG5vbmUgeWV0ICovCiAgICAgICAgICAgIG5ldHNubXBfcmVxdWVzdF9hZGRfbGlzdF9kYXRhKHJlcXVlc3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfY3JlYXRlX2RhdGFfbGlzdAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoVEFCTEVfSEFORExFUl9OQU1FLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHZvaWQgKikgdGJsX3JlcV9pbmZvLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFibGVfZGF0YV9mcmVlX2Z1bmMpKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICBERUJVR01TR1RMKCgiaGVscGVyOnRhYmxlIiwgIiAgdXNpbmcgZXhpc3RpbmcgdGJsX3JlcV9pbmZvXG4gIikpOwogICAgICAgIH0KCiAgICAgICAgLyoKICAgICAgICAgKiBkbyB3ZSBoYXZlIGEgY29sdW1uPwogICAgICAgICAqLwogICAgICAgIGlmICh2YXItPm5hbWVfbGVuZ3RoID4gb2lkX2NvbHVtbl9wb3MpIHsKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogb2lkIGlzIGxvbmcgZW5vdWdoIHRvIGNvbnRhaW4gQ09MVU1OIGluZm8KICAgICAgICAgICAgICovCiAgICAgICAgICAgIERFQlVHTVNHVEwoKCJoZWxwZXI6dGFibGU6Y29sIiwKICAgICAgICAgICAgICAgICAgICAgICAgIiAgaGF2ZSBhdCBsZWFzdCBhIGNvbHVtbiAoJSIgTkVUU05NUF9QUklvICJkKVxuIiwKICAgICAgICAgICAgICAgICAgICAgICAgdmFyLT5uYW1lW29pZF9jb2x1bW5fcG9zXSkpOwogICAgICAgICAgICBpZiAodmFyLT5uYW1lW29pZF9jb2x1bW5fcG9zXSA8IHRibF9pbmZvLT5taW5fY29sdW1uKSB7CiAgICAgICAgICAgICAgICBERUJVR01TR1RMKCgiaGVscGVyOnRhYmxlOmNvbCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiICAgIGJ1dCBpdCdzIGxlc3MgdGhhbiBtaW4gKCVkKVxuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRibF9pbmZvLT5taW5fY29sdW1uKSk7CiAgICAgICAgICAgICAgICBpZiAocmVxaW5mby0+bW9kZSA9PSBNT0RFX0dFVE5FWFQpIHsKICAgICAgICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAgICAgICAqIGZpeCBjb2x1bW4sIHRydW5jYXRlIHVzZWxlc3MgY29sdW1uIGluZm8gCiAgICAgICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICAgICAgdmFyLT5uYW1lX2xlbmd0aCA9IG9pZF9jb2x1bW5fcG9zOwogICAgICAgICAgICAgICAgICAgIHRibF9yZXFfaW5mby0+Y29sbnVtID0gdGJsX2luZm8tPm1pbl9jb2x1bW47CiAgICAgICAgICAgICAgICB9IGVsc2UKICAgICAgICAgICAgICAgICAgICBvdXRfb2ZfcmFuZ2UgPSAxOwogICAgICAgICAgICB9IGVsc2UgaWYgKHZhci0+bmFtZVtvaWRfY29sdW1uX3Bvc10gPiB0YmxfaW5mby0+bWF4X2NvbHVtbikKICAgICAgICAgICAgICAgIG91dF9vZl9yYW5nZSA9IDE7CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHRibF9yZXFfaW5mby0+Y29sbnVtID0gdmFyLT5uYW1lW29pZF9jb2x1bW5fcG9zXTsKCiAgICAgICAgICAgIGlmIChvdXRfb2ZfcmFuZ2UpIHsKICAgICAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAgICAgKiB0aGlzIGlzIG91dCBvZiByYW5nZS4uLiAgcmVtb3ZlIGZyb20gcmVxdWVzdHMsIGZyZWUKICAgICAgICAgICAgICAgICAqIG1lbW9yeSAKICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgREVCVUdNU0dUTCgoImhlbHBlcjp0YWJsZSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiICAgIG9pZCBpcyBvdXQgb2YgcmFuZ2UuIE5vdCBwcm9jZXNzZWQ6ICIpKTsKICAgICAgICAgICAgICAgIERFQlVHTVNHT0lEKCgiaGVscGVyOnRhYmxlIiwgdmFyLT5uYW1lLCB2YXItPm5hbWVfbGVuZ3RoKSk7CiAgICAgICAgICAgICAgICBERUJVR01TRygoImhlbHBlcjp0YWJsZSIsICJcbiIpKTsKCiAgICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAgICogIFJlamVjdCByZXF1ZXN0cyBvZiB0aGUgZm9ybSAnbXlFbnRyeS5OJyAgIChpbnZhbGlkIE4pCiAgICAgICAgICAgICAgICAgKi8KI2lmbmRlZiBORVRTTk1QX05PX1dSSVRFX1NVUFBPUlQKICAgICAgICAgICAgICAgIGlmIChyZXFpbmZvLT5tb2RlID09IE1PREVfU0VUX1JFU0VSVkUxKQogICAgICAgICAgICAgICAgICAgIHRhYmxlX2hlbHBlcl9jbGVhbnVwKHJlcWluZm8sIHJlcXVlc3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU05NUF9FUlJfTk9UV1JJVEFCTEUpOwogICAgICAgICAgICAgICAgZWxzZSBpZiAocmVxaW5mby0+bW9kZSA9PSBNT0RFX0dFVCkKI2VuZGlmIC8qIE5FVFNOTVBfTk9fV1JJVEVfU1VQUE9SVCAqLwogICAgICAgICAgICAgICAgICAgIHRhYmxlX2hlbHBlcl9jbGVhbnVwKHJlcWluZm8sIHJlcXVlc3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU05NUF9OT1NVQ0hPQkpFQ1QpOwogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogdXNlIGNvbHVtbiB2ZXJpZmljYXRpb24gCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBlbHNlIGlmICh0YmxfaW5mby0+dmFsaWRfY29sdW1ucykgewogICAgICAgICAgICAgICAgdGJsX3JlcV9pbmZvLT5jb2xudW0gPQogICAgICAgICAgICAgICAgICAgIG5ldHNubXBfY2xvc2VzdF9jb2x1bW4odmFyLT5uYW1lW29pZF9jb2x1bW5fcG9zXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRibF9pbmZvLT52YWxpZF9jb2x1bW5zKTsKICAgICAgICAgICAgICAgIERFQlVHTVNHVEwoKCJoZWxwZXI6dGFibGU6Y29sIiwgIiAgICBjbG9zZXN0IGNvbHVtbiBpcyAlZFxuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRibF9yZXFfaW5mby0+Y29sbnVtKSk7CiAgICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAgICogeHh4LXJrczogZG9jdW1lbnQgd2h5IHRoZSBjb250aW51ZS4uLgogICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICBpZiAodGJsX3JlcV9pbmZvLT5jb2xudW0gPT0gMCkKICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgIGlmICh0YmxfcmVxX2luZm8tPmNvbG51bSAhPSB2YXItPm5hbWVbb2lkX2NvbHVtbl9wb3NdKSB7CiAgICAgICAgICAgICAgICAgICAgREVCVUdNU0dUTCgoImhlbHBlcjp0YWJsZTpjb2wiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIgICAgd2hpY2ggZG9lc24ndCBtYXRjaCByZXEgIgogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIlIiBORVRTTk1QX1BSSW8gImQgLSB0cnVuY2F0aW5nIGluZGV4IGluZm9cbiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFyLT5uYW1lW29pZF9jb2x1bW5fcG9zXSkpOwogICAgICAgICAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAgICAgICAgICogZGlmZmVyZW50IGNvbHVtbiEgdHJ1bmNhdGUgdXNlbGVzcyBpbmRleCBpbmZvIAogICAgICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgICAgIHZhci0+bmFtZV9sZW5ndGggPSBvaWRfY29sdW1uX3BvcyArIDE7IC8qIHBvcyBpcyAwIGJhc2VkICovCiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogdmFyLT5uYW1lX2xlbmd0aCBtYXkgaGF2ZSBjaGFuZ2VkIC0gY2hlY2sgYWdhaW4gCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBpZiAoKGludCl2YXItPm5hbWVfbGVuZ3RoIDw9IG9pZF9pbmRleF9wb3MpIHsgLyogcG9zIGlzIDAgYmFzZWQgKi8KICAgICAgICAgICAgICAgIERFQlVHTVNHVEwoKCJoZWxwZXI6dGFibGUiLCAiICAgIG5vdCBlbm91Z2ggZm9yIGluZGV4ZXNcbiIpKTsKICAgICAgICAgICAgICAgIHRibF9yZXFfaW5mby0+aW5kZXhfb2lkX2xlbiA9IDA7IC8qKiBub25lIGF2YWlsYWJsZSAqLwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAqIG9pZCBpcyBsb25nIGVub3VnaCB0byBjb250YWluIElOREVYIGluZm8KICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgdGJsX3JlcV9pbmZvLT5pbmRleF9vaWRfbGVuID0KICAgICAgICAgICAgICAgICAgICB2YXItPm5hbWVfbGVuZ3RoIC0gb2lkX2luZGV4X3BvczsKICAgICAgICAgICAgICAgIERFQlVHTVNHVEwoKCJoZWxwZXI6dGFibGUiLCAiICAgIGhhdmUgJWx1IGJ5dGVzIG9mIGluZGV4XG4iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgKHVuc2lnbmVkIGxvbmcpdGJsX3JlcV9pbmZvLT5pbmRleF9vaWRfbGVuKSk7CiAgICAgICAgICAgICAgICBuZXRzbm1wX2Fzc2VydCh0YmxfcmVxX2luZm8tPmluZGV4X29pZF9sZW4gPCBNQVhfT0lEX0xFTik7CiAgICAgICAgICAgICAgICBtZW1jcHkodGJsX3JlcV9pbmZvLT5pbmRleF9vaWQsICZ2YXItPm5hbWVbb2lkX2luZGV4X3Bvc10sCiAgICAgICAgICAgICAgICAgICAgICAgdGJsX3JlcV9pbmZvLT5pbmRleF9vaWRfbGVuICogc2l6ZW9mKG9pZCkpOwogICAgICAgICAgICAgICAgdG1wX25hbWUgPSB0YmxfcmVxX2luZm8tPmluZGV4X29pZDsKICAgICAgICAgICAgfQogICAgICAgIH0gZWxzZSBpZiAocmVxaW5mby0+bW9kZSA9PSBNT0RFX0dFVE5FWFQgfHwKICAgICAgICAgICAgICAgICAgIHJlcWluZm8tPm1vZGUgPT0gTU9ERV9HRVRCVUxLKSB7CiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIG9pZCBpcyBOT1QgbG9uZyBlbm91Z2ggdG8gY29udGFpbiBjb2x1bW4gb3IgaW5kZXggaW5mbywgc28gc3RhcnQKICAgICAgICAgICAgICogYXQgdGhlIG1pbmltdW0gY29sdW1uLiBTZXQgaW5kZXggb2lkIGxlbiB0byAwIGJlY2F1c2Ugd2UgZG9uJ3QKICAgICAgICAgICAgICogaGF2ZSBhbnkgaW5kZXggaW5mbyBpbiB0aGUgT0lELgogICAgICAgICAgICAgKi8KICAgICAgICAgICAgREVCVUdNU0dUTCgoImhlbHBlcjp0YWJsZSIsICIgIG5vIGNvbHVtbi9pbmRleCBpbiByZXF1ZXN0XG4iKSk7CiAgICAgICAgICAgIHRibF9yZXFfaW5mby0+aW5kZXhfb2lkX2xlbiA9IDA7CiAgICAgICAgICAgIHRibF9yZXFfaW5mby0+Y29sbnVtID0gdGJsX2luZm8tPm1pbl9jb2x1bW47CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogb2lkIGlzIE5PVCBsb25nIGVub3VnaCB0byBjb250YWluIGluZGV4IGluZm8sCiAgICAgICAgICAgICAqIHNvIHdlIGNhbid0IGRvIGFueXRoaW5nIHdpdGggaXQuCiAgICAgICAgICAgICAqCiAgICAgICAgICAgICAqIFJlamVjdCByZXF1ZXN0cyBvZiB0aGUgZm9ybSAnbXlUYWJsZScgb3IgJ215RW50cnknCiAgICAgICAgICAgICAqLwogICAgICAgICAgICBpZiAocmVxaW5mby0+bW9kZSA9PSBNT0RFX0dFVCApIHsKICAgICAgICAgICAgICAgIHRhYmxlX2hlbHBlcl9jbGVhbnVwKHJlcWluZm8sIHJlcXVlc3QsIFNOTVBfTk9TVUNIT0JKRUNUKTsKI2lmbmRlZiBORVRTTk1QX05PX1dSSVRFX1NVUFBPUlQKICAgICAgICAgICAgfSBlbHNlIGlmIChyZXFpbmZvLT5tb2RlID09IE1PREVfU0VUX1JFU0VSVkUxICkgewogICAgICAgICAgICAgICAgdGFibGVfaGVscGVyX2NsZWFudXAocmVxaW5mbywgcmVxdWVzdCwgU05NUF9FUlJfTk9UV1JJVEFCTEUpOwojZW5kaWYgLyogTkVUU05NUF9OT19XUklURV9TVVBQT1JUICovCiAgICAgICAgICAgIH0KICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgfQoKICAgICAgICAvKgogICAgICAgICAqIHNldCB1cCB0bXBfbGVuIHRvIGJlIHRoZSBudW1iZXIgb2YgT0lEcyB3ZSBoYXZlIGJleW9uZCB0aGUgY29sdW1uOwogICAgICAgICAqIHRoZXNlIHNob3VsZCBiZSB0aGUgaW5kZXgocykgZm9yIHRoZSB0YWJsZS4gSWYgdGhlIGluZGV4X29pZF9sZW4KICAgICAgICAgKiBpcyAwLCBzZXQgdG1wX2xlbiB0byAtMSBzbyB0aGF0IHdoZW4gd2UgdHJ5IHRvIHBhcnNlIHRoZSBpbmRleCBiZWxvdywKICAgICAgICAgKiB3ZSBqdXN0IHplcm8gZmlsbCBldmVyeXRoaW5nLgogICAgICAgICAqLwogICAgICAgIGlmICh0YmxfcmVxX2luZm8tPmluZGV4X29pZF9sZW4gPT0gMCkgewogICAgICAgICAgICBpbmNvbXBsZXRlID0gMTsKICAgICAgICAgICAgdG1wX2xlbiA9IC0xOwogICAgICAgIH0gZWxzZQogICAgICAgICAgICB0bXBfbGVuID0gdGJsX3JlcV9pbmZvLT5pbmRleF9vaWRfbGVuOwoKCiAgICAgICAgLyoKICAgICAgICAgKiBmb3IgZWFjaCBpbmRleCB0eXBlLCB0cnkgdG8gZXh0cmFjdCB0aGUgaW5kZXggZnJvbSB2YXItPm5hbWUKICAgICAgICAgKi8KICAgICAgICBERUJVR01TR1RMKCgiaGVscGVyOnRhYmxlIiwgIiAgbG9va2luZyBmb3IgJWQgaW5kZXhlc1xuIiwKICAgICAgICAgICAgICAgICAgICB0YmxfaW5mby0+bnVtYmVyX2luZGV4ZXMpKTsKICAgICAgICBmb3IgKHRtcF9pZHggPSAwLCB2YiA9IHRibF9yZXFfaW5mby0+aW5kZXhlczsKICAgICAgICAgICAgIHRtcF9pZHggPCB0YmxfaW5mby0+bnVtYmVyX2luZGV4ZXM7CiAgICAgICAgICAgICArK3RtcF9pZHgsIHZiID0gdmItPm5leHRfdmFyaWFibGUpIHsKICAgICAgICAgICAgc2l6ZV90IHBhcnNlZF9vaWRfbGVuOwoKICAgICAgICAgICAgaWYgKGluY29tcGxldGUgJiYgdG1wX2xlbikgewogICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAqIGluY29tcGxldGUvaWxsZWdhbCBPSUQsIHNldCB1cCBkdW1teSAwIHRvIHBhcnNlIAogICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICBERUJVR01TR1RMKCgiaGVscGVyOnRhYmxlIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICIgIG9pZCBpbmRleGVzIG5vdCBjb21wbGV0ZTogIikpOwogICAgICAgICAgICAgICAgREVCVUdNU0dPSUQoKCJoZWxwZXI6dGFibGUiLCB2YXItPm5hbWUsIHZhci0+bmFtZV9sZW5ndGgpKTsKICAgICAgICAgICAgICAgIERFQlVHTVNHKCgiaGVscGVyOnRhYmxlIiwgIlxuIikpOwoKICAgICAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAgICAgKiBubyBzZW5zZSBpbiB0cnlpbmcgYW55bW9yZSBpZiB0aGlzIGlzIGEgR0VUL1NFVC4gCiAgICAgICAgICAgICAgICAgKgogICAgICAgICAgICAgICAgICogUmVqZWN0IHJlcXVlc3RzIG9mIHRoZSBmb3JtICdteU9iamVjdCcgICAobm8gaW5zdGFuY2UpCiAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgIHRtcF9sZW4gPSAwOwogICAgICAgICAgICAgICAgdG1wX25hbWUgPSBOVUxMOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogdHJ5IGFuZCBwYXJzZSBjdXJyZW50IGluZGV4IAogICAgICAgICAgICAgKi8KICAgICAgICAgICAgbmV0c25tcF9hc3NlcnQodG1wX2xlbiA+PSAwKTsKICAgICAgICAgICAgcGFyc2VkX29pZF9sZW4gPSB0bXBfbGVuOwogICAgICAgICAgICBpZiAocGFyc2Vfb25lX29pZF9pbmRleCgmdG1wX25hbWUsICZwYXJzZWRfb2lkX2xlbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmIsIDEpICE9IFNOTVBFUlJfU1VDQ0VTUykgewogICAgICAgICAgICAgICAgaW5jb21wbGV0ZSA9IDE7CiAgICAgICAgICAgICAgICB0bXBfbGVuID0gLTE7ICAgLyogaXMgdGhpcyBuZWNlc3Nhcnk/IEJldHRlciBzYWZlIHRoYW4KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKiBzb3JyeSAqLwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgdG1wX2xlbiA9IHBhcnNlZF9vaWRfbGVuOwogICAgICAgICAgICAgICAgREVCVUdNU0dUTCgoImhlbHBlcjp0YWJsZSIsICIgIGdvdCAxIChpbmNvbXBsZXRlPSVkKVxuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGluY29tcGxldGUpKTsKICAgICAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAgICAgKiBkbyBub3QgY291bnQgaW5jb21wbGV0ZSBpbmRleGVzIAogICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICBpZiAoaW5jb21wbGV0ZSkKICAgICAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgICAgICsrdGJsX3JlcV9pbmZvLT5udW1iZXJfaW5kZXhlczsgLyoqIGdvdCBvbmUgb2sgKi8KICAgICAgICAgICAgICAgIGlmICh0bXBfbGVuIDw9IDApIHsKICAgICAgICAgICAgICAgICAgICBpbmNvbXBsZXRlID0gMTsKICAgICAgICAgICAgICAgICAgICB0bXBfbGVuID0gLTE7ICAgICAgIC8qIGlzIHRoaXMgbmVjZXNzYXJ5PyBCZXR0ZXIgc2FmZQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICogdGhhbiBzb3JyeSAqLwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfSAgICAgICAgICAgICAgICAgICAgICAgLyoqIGZvciBsb29wICovCgogICAgICAgIERFQlVHSUYoImhlbHBlcjp0YWJsZTpyZXN1bHRzIikgewogICAgICAgICAgICAgICAgdW5zaWduZWQgaW50ICAgIGNvdW50OwogICAgICAgICAgICAgICAgdV9jaGFyICAgICAgICAgKmJ1ZiA9IE5VTEw7CiAgICAgICAgICAgICAgICBzaXplX3QgICAgICAgICAgYnVmX2xlbiA9IDAsIG91dF9sZW4gPSAwOwogICAgICAgICAgICAgICAgREVCVUdNU0dUTCgoImhlbHBlcjp0YWJsZTpyZXN1bHRzIiwgIiAgZm91bmQgJWQgaW5kZXhlc1xuIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRibF9yZXFfaW5mby0+bnVtYmVyX2luZGV4ZXMpKTsKICAgICAgICAgICAgICAgIERFQlVHTVNHVEwoKCJoZWxwZXI6dGFibGU6cmVzdWx0cyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiICBjb2x1bW46ICVkLCBpbmRleGVzOiAlZCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0YmxfcmVxX2luZm8tPmNvbG51bSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRibF9yZXFfaW5mby0+bnVtYmVyX2luZGV4ZXMpKTsKICAgICAgICAgICAgICAgIGZvciAodmIgPSB0YmxfcmVxX2luZm8tPmluZGV4ZXMsIGNvdW50ID0gMDsKICAgICAgICAgICAgICAgICAgICAgdmIgJiYgY291bnQgPCB0YmxfcmVxX2luZm8tPm51bWJlcl9pbmRleGVzOwogICAgICAgICAgICAgICAgICAgICBjb3VudCsrLCB2YiA9IHZiLT5uZXh0X3ZhcmlhYmxlKSB7CiAgICAgICAgICAgICAgICAgICAgb3V0X2xlbiA9IDA7CiAgICAgICAgICAgICAgICAgICAgaWYgKHNwcmludF9yZWFsbG9jX2J5X3R5cGUoJmJ1ZiwgJmJ1Zl9sZW4sICZvdXRfbGVuLCAxLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZiLCBOVUxMLCBOVUxMLCBOVUxMKSkgewogICAgICAgICAgICAgICAgICAgICAgICBERUJVR01TRygoImhlbHBlcjp0YWJsZTpyZXN1bHRzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIgICBpbmRleDogdHlwZT0lZCglMDJ4KSwgdmFsdWU9JXMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmItPnR5cGUsIHZiLT50eXBlLCBidWYpKTsKICAgICAgICAgICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAoYnVmICE9IE5VTEwpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIERFQlVHTVNHKCgiaGVscGVyOnRhYmxlOnJlc3VsdHMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIgICBpbmRleDogdHlwZT0lZCglMDJ4KSwgdmFsdWU9JXMgW1RSVU5DQVRFRF0iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZiLT50eXBlLCB2Yi0+dHlwZSwgYnVmKSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICBERUJVR01TRygoImhlbHBlcjp0YWJsZTpyZXN1bHRzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiICAgaW5kZXg6IHR5cGU9JWQoJTAyeCksIHZhbHVlPVtOSUxdIFtUUlVOQ0FURURdIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2Yi0+dHlwZSwgdmItPnR5cGUpKTsKICAgICAgICAgICAgICAgICAgICAgICAgfQogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmIChidWYgIT0gTlVMTCkgewogICAgICAgICAgICAgICAgICAgIGZyZWUoYnVmKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIERFQlVHTVNHKCgiaGVscGVyOnRhYmxlOnJlc3VsdHMiLCAiXG4iKSk7CiAgICAgICAgfQoKCiAgICAgICAgLyoKICAgICAgICAgKiBkbyB3ZSBoYXZlIHN1ZmZpY2llbnQgaW5kZXggaW5mbyB0byBjb250aW51ZT8KICAgICAgICAgKi8KCiAgICAgICAgaWYgKChyZXFpbmZvLT5tb2RlICE9IE1PREVfR0VUTkVYVCkgJiYKICAgICAgICAgICAgKCh0YmxfcmVxX2luZm8tPm51bWJlcl9pbmRleGVzICE9IHRibF9pbmZvLT5udW1iZXJfaW5kZXhlcykgfHwKICAgICAgICAgICAgICh0bXBfbGVuICE9IC0xKSkpIHsKCiAgICAgICAgICAgIERFQlVHTVNHVEwoKCJoZWxwZXI6dGFibGUiLAogICAgICAgICAgICAgICAgICAgICAgICAiaW52YWxpZCBpbmRleChlcykgZm9yIHRhYmxlIC0gc2tpcHBpbmdcbiIpKTsKCiNpZm5kZWYgTkVUU05NUF9OT19XUklURV9TVVBQT1JUCiAgICAgICAgICAgIGlmICggTU9ERV9JU19TRVQocmVxaW5mby0+bW9kZSkgKSB7CiAgICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAgICogbm8gcG9pbnQgaW4gY29udGludWluZyB3aXRob3V0IGluZGV4ZXMgZm9yIHNldC4KICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgbmV0c25tcF9hc3NlcnQocmVxaW5mby0+bW9kZSA9PSBNT0RFX1NFVF9SRVNFUlZFMSk7CiAgICAgICAgICAgICAgICAvKiogY2xlYXIgZmlyc3QgcmVxdWVzdCBzbyB3ZSB3b250IHRyeSB0byBydW4gRlJFRSBtb2RlICovCiAgICAgICAgICAgICAgICBuZXRzbm1wX2ZyZWVfcmVxdWVzdF9kYXRhX3NldHMocmVxdWVzdHMpOwogICAgICAgICAgICAgICAgLyoqIHNldCBhY3R1YWwgZXJyb3IgKi8KICAgICAgICAgICAgICAgIHRhYmxlX2hlbHBlcl9jbGVhbnVwKHJlcWluZm8sIHJlcXVlc3QsIFNOTVBfRVJSX05PQ1JFQVRJT04pOwogICAgICAgICAgICAgICAgbmVlZF9wcm9jZXNzaW5nID0gMDsgLyogZG9uJ3QgY2FsbCBuZXh0IGhhbmRsZXIgKi8KICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICB9CiNlbmRpZiAvKiBORVRTTk1QX05PX1dSSVRFX1NVUFBPUlQgKi8KICAgICAgICAgICAgdGFibGVfaGVscGVyX2NsZWFudXAocmVxaW5mbywgcmVxdWVzdCwgU05NUF9OT1NVQ0hJTlNUQU5DRSk7CiAgICAgICAgICAgIGNvbnRpbnVlOwogICAgICAgIH0KICAgICAgICBuZXRzbm1wX2Fzc2VydChyZXF1ZXN0LT5zdGF0dXMgPT0gU05NUF9FUlJfTk9FUlJPUik7CiAgICAgICAgCiAgICAgICAgKytuZWVkX3Byb2Nlc3Npbmc7CgogICAgfSAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIGZvciBlYWNoIHJlcXVlc3QgKi8KI2lmbmRlZiBORVRTTk1QX05PX1dSSVRFX1NVUFBPUlQKICAgIH0KI2VuZGlmIC8qIE5FVFNOTVBfTk9fV1JJVEVfU1VQUE9SVCAqLwoKICAgIC8qCiAgICAgKiBiYWlsIGlmIHRoZXJlIGlzIG5vdGhpbmcgZm9yIG91ciBjaGlsZCBoYW5kbGVycwogICAgICovCiAgICBpZiAoMCA9PSBuZWVkX3Byb2Nlc3NpbmcpCiAgICAgICAgcmV0dXJuIHN0YXR1czsKCiAgICAvKgogICAgICogY2FsbCBvdXIgY2hpbGQgYWNjZXNzIGZ1bmN0aW9uIAogICAgICovCiAgICBzdGF0dXMgPQogICAgICAgIG5ldHNubXBfY2FsbF9uZXh0X2hhbmRsZXIoaGFuZGxlciwgcmVnaW5mbywgcmVxaW5mbywgcmVxdWVzdHMpOwoKICAgIC8qCiAgICAgKiBjaGVjayBmb3Igc3BhcnNlIHRhYmxlcwogICAgICovCiAgICBpZiAocmVxaW5mby0+bW9kZSA9PSBNT0RFX0dFVE5FWFQpCiAgICAgICAgc3BhcnNlX3RhYmxlX2hlbHBlcl9oYW5kbGVyKCBoYW5kbGVyLCByZWdpbmZvLCByZXFpbmZvLCByZXF1ZXN0cyApOwoKICAgIHJldHVybiBzdGF0dXM7Cn0KCiNkZWZpbmUgU1BBUlNFX1RBQkxFX0hBTkRMRVJfTkFNRSAic3BhcnNlX3RhYmxlIgoKLyoqIGltcGxlbWVudHMgdGhlIHNwYXJzZSB0YWJsZSBoZWxwZXIgaGFuZGxlcgogKiBAaW50ZXJuYWwKICoKICogQG5vdGUKICogVGhpcyBmdW5jdGlvbiBpcyBzdGF0aWMgdG8gcHJldmVudCBvdGhlcnMgZnJvbSBjYWxsaW5nIGl0CiAqIGRpcmVjdGx5LiBJdCBpdCBhdXRvbWF0aWNhbGx5IGNhbGxlZCBieSB0aGUgdGFibGUgaGVscGVyLAogKiAKICovCnN0YXRpYyBpbnQKc3BhcnNlX3RhYmxlX2hlbHBlcl9oYW5kbGVyKG5ldHNubXBfbWliX2hhbmRsZXIgKmhhbmRsZXIsCiAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfaGFuZGxlcl9yZWdpc3RyYXRpb24gKnJlZ2luZm8sCiAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfYWdlbnRfcmVxdWVzdF9pbmZvICpyZXFpbmZvLAogICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX3JlcXVlc3RfaW5mbyAqcmVxdWVzdHMpCnsKICAgIGludCAgICAgICAgICAgICBzdGF0dXMgPSBTTk1QX0VSUl9OT0VSUk9SOwogICAgbmV0c25tcF9yZXF1ZXN0X2luZm8gKnJlcXVlc3Q7CiAgICBvaWQgICAgICAgICAgICAgY29sb2lkW01BWF9PSURfTEVOXTsKICAgIG5ldHNubXBfdGFibGVfcmVxdWVzdF9pbmZvICp0YWJsZV9pbmZvOwoKICAgIC8qCiAgICAgKiBzaW5jZSB3ZSBkb24ndCBjYWxsIGNoaWxkIGhhbmRsZXJzLCB3YXJuIGlmIG9uZSB3YXMgcmVnaXN0ZXJlZAogICAgICogYmVuZWF0aCB1cy4gQSBzcGVjaWFsIGV4Y2VwdGlvbiBmb3IgdGhlIHRhYmxlIGhlbHBlciwgd2hpY2ggY2FsbHMKICAgICAqIHRoZSBoYW5kbGVyIGRpcmVjdGx5LiBVc2UgaGFuZGxlIGN1c3RvbSBmbGFnIHRvIG9ubHkgbG9nIG9uY2UuCiAgICAgKi8KICAgIGlmKCh0YWJsZV9oZWxwZXJfaGFuZGxlciAhPSBoYW5kbGVyLT5hY2Nlc3NfbWV0aG9kKSAmJgogICAgICAgKE5VTEwgIT0gaGFuZGxlci0+bmV4dCkpIHsKICAgICAgICAvKgogICAgICAgICAqIGFsd2F5cyB3YXJuIGlmIGNhbGxlZCB3aXRob3V0IG91ciBvd24gaGFuZGxlci4gSWYgd2UKICAgICAgICAgKiBoYXZlIG91ciBvd24gaGFuZGxlciwgdXNlIGN1c3RvbSBiaXQgMSB0byBvbmx5IGxvZyBvbmNlLgogICAgICAgICAqLwogICAgICAgIGlmKChzcGFyc2VfdGFibGVfaGVscGVyX2hhbmRsZXIgIT0gaGFuZGxlci0+YWNjZXNzX21ldGhvZCkgfHwKICAgICAgICAgICAhKGhhbmRsZXItPmZsYWdzICYgTUlCX0hBTkRMRVJfQ1VTVE9NMSkpIHsKICAgICAgICAgICAgc25tcF9sb2coTE9HX1dBUk5JTkcsICJoYW5kbGVyICglcykgcmVnaXN0ZXJlZCBhZnRlciBzcGFyc2UgdGFibGUgIgogICAgICAgICAgICAgICAgICAgICAiaGFuZGVyIHdpbGwgbm90IGJlIGNhbGxlZFxuIiwKICAgICAgICAgICAgICAgICAgICAgaGFuZGxlci0+bmV4dC0+aGFuZGxlcl9uYW1lID8KICAgICAgICAgICAgICAgICAgICAgaGFuZGxlci0+bmV4dC0+aGFuZGxlcl9uYW1lIDogIiIgKTsKICAgICAgICAgICAgaWYoc3BhcnNlX3RhYmxlX2hlbHBlcl9oYW5kbGVyID09IGhhbmRsZXItPmFjY2Vzc19tZXRob2QpCiAgICAgICAgICAgICAgICBoYW5kbGVyLT5mbGFncyB8PSBNSUJfSEFORExFUl9DVVNUT00xOwogICAgICAgIH0KICAgIH0KCiAgICBpZiAocmVxaW5mby0+bW9kZSA9PSBNT0RFX0dFVE5FWFQpIHsKICAgICAgICBmb3IocmVxdWVzdCA9IHJlcXVlc3RzIDsgcmVxdWVzdDsgcmVxdWVzdCA9IHJlcXVlc3QtPm5leHQpIHsKICAgICAgICAgICAgaWYgKChyZXF1ZXN0LT5yZXF1ZXN0dmItPnR5cGUgPT0gQVNOX05VTEwgJiYgcmVxdWVzdC0+cHJvY2Vzc2VkKSB8fAogICAgICAgICAgICAgICAgcmVxdWVzdC0+ZGVsZWdhdGVkKQogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIGlmIChyZXF1ZXN0LT5yZXF1ZXN0dmItPnR5cGUgPT0gU05NUF9OT1NVQ0hJTlNUQU5DRSkgewogICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAqIGdldCBuZXh0IHNraXBwZWQgdGhpcyB2YWx1ZSBmb3IgdGhpcyBjb2x1bW4sIHdlCiAgICAgICAgICAgICAgICAgKiBuZWVkIHRvIGtlZXAgc2VhcmNoaW5nIGZvcndhcmQgCiAgICAgICAgICAgICAgICAgKi8KICAgICAgICAgICAgICAgIERFQlVHTVNHVCgoInNwYXJzZSIsICJyZXRyeSBmb3IgTk9TVUNISU5TVEFOQ0VcbiIpKTsKICAgICAgICAgICAgICAgIHJlcXVlc3QtPnJlcXVlc3R2Yi0+dHlwZSA9IEFTTl9QUklWX1JFVFJZOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGlmIChyZXF1ZXN0LT5yZXF1ZXN0dmItPnR5cGUgPT0gU05NUF9OT1NVQ0hPQkpFQ1QgfHwKICAgICAgICAgICAgICAgIHJlcXVlc3QtPnJlcXVlc3R2Yi0+dHlwZSA9PSBTTk1QX0VORE9GTUlCVklFVykgewogICAgICAgICAgICAgICAgLyoKICAgICAgICAgICAgICAgICAqIGdldCBuZXh0IGhhcyBjb21wbGV0ZWx5IGZpbmlzaGVkIHdpdGggdGhpcyBjb2x1bW4sCiAgICAgICAgICAgICAgICAgKiBzbyB3ZSBuZWVkIHRvIHRyeSB3aXRoIHRoZSBuZXh0IGNvbHVtbiAoaWYgYW55KQogICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICBERUJVR01TR1QoKCJzcGFyc2UiLCAicmV0cnkgZm9yIE5PU1VDSE9CSkVDVFxuIikpOwogICAgICAgICAgICAgICAgdGFibGVfaW5mbyA9IG5ldHNubXBfZXh0cmFjdF90YWJsZV9pbmZvKHJlcXVlc3QpOwogICAgICAgICAgICAgICAgdGFibGVfaW5mby0+Y29sbnVtID0gbmV0c25tcF90YWJsZV9uZXh0X2NvbHVtbih0YWJsZV9pbmZvKTsKICAgICAgICAgICAgICAgIGlmICgwICE9IHRhYmxlX2luZm8tPmNvbG51bSkgewogICAgICAgICAgICAgICAgICAgIG1lbWNweShjb2xvaWQsIHJlZ2luZm8tPnJvb3RvaWQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlZ2luZm8tPnJvb3RvaWRfbGVuICogc2l6ZW9mKG9pZCkpOwogICAgICAgICAgICAgICAgICAgIGNvbG9pZFtyZWdpbmZvLT5yb290b2lkX2xlbl0gICA9IDE7ICAgLyogdGFibGUuZW50cnkgbm9kZSAqLwogICAgICAgICAgICAgICAgICAgIGNvbG9pZFtyZWdpbmZvLT5yb290b2lkX2xlbisxXSA9IHRhYmxlX2luZm8tPmNvbG51bTsKICAgICAgICAgICAgICAgICAgICBzbm1wX3NldF92YXJfb2JqaWQocmVxdWVzdC0+cmVxdWVzdHZiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2xvaWQsIHJlZ2luZm8tPnJvb3RvaWRfbGVuICsgMik7CiAgICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICAgcmVxdWVzdC0+cmVxdWVzdHZiLT50eXBlID0gQVNOX1BSSVZfUkVUUlk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAvKgogICAgICAgICAgICAgICAgICAgICAqIElmIHdlIGRvbid0IGhhdmUgY29sdW1uIGluZm8sIHJlc2V0IHRvIG51bGwgc28KICAgICAgICAgICAgICAgICAgICAgKiB0aGUgYWdlbnQgd2lsbCBtb3ZlIG9uIHRvIHRoZSBuZXh0IHRhYmxlLgogICAgICAgICAgICAgICAgICAgICAqLwogICAgICAgICAgICAgICAgICAgIHJlcXVlc3QtPnJlcXVlc3R2Yi0+dHlwZSA9IEFTTl9OVUxMOwogICAgICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQogICAgcmV0dXJuIHN0YXR1czsKfQoKLyoqIGNyZWF0ZSBzcGFyc2UgdGFibGUgaGFuZGxlcgogKi8KI2lmbmRlZiBORVRTTk1QX0ZFQVRVUkVfUkVNT1ZFX1RBQkxFX1NQQVJTRQpuZXRzbm1wX21pYl9oYW5kbGVyICoKbmV0c25tcF9zcGFyc2VfdGFibGVfaGFuZGxlcl9nZXQodm9pZCkKewogICAgcmV0dXJuIG5ldHNubXBfY3JlYXRlX2hhbmRsZXIoU1BBUlNFX1RBQkxFX0hBTkRMRVJfTkFNRSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNwYXJzZV90YWJsZV9oZWxwZXJfaGFuZGxlcik7Cn0KCi8qKiBjcmVhdGVzIGEgdGFibGUgaGFuZGxlciBnaXZlbiB0aGUgbmV0c25tcF90YWJsZV9yZWdpc3RyYXRpb25faW5mbyBvYmplY3QsCiAqICBpbnNlcnRzIGl0IGludG8gdGhlIHJlcXVlc3QgY2hhaW4gYW5kIHRoZW4gY2FsbHMKICogIG5ldHNubXBfcmVnaXN0ZXJfaGFuZGxlcigpIHRvIHJlZ2lzdGVyIHRoZSB0YWJsZSBpbnRvIHRoZSBhZ2VudC4KICovCmludApuZXRzbm1wX3NwYXJzZV90YWJsZV9yZWdpc3RlcihuZXRzbm1wX2hhbmRsZXJfcmVnaXN0cmF0aW9uICpyZWdpbmZvLAogICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfdGFibGVfcmVnaXN0cmF0aW9uX2luZm8gKnRhYnJlcSkKewogICAgbmV0c25tcF9taWJfaGFuZGxlciAqaGFuZGxlcjEsICpoYW5kbGVyMjsKICAgIGludCByYzsKCiAgICBoYW5kbGVyMSA9IG5ldHNubXBfY3JlYXRlX2hhbmRsZXIoU1BBUlNFX1RBQkxFX0hBTkRMRVJfTkFNRSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNwYXJzZV90YWJsZV9oZWxwZXJfaGFuZGxlcik7CiAgICBpZiAoTlVMTCA9PSBoYW5kbGVyMSkKICAgICAgICByZXR1cm4gU05NUF9FUlJfR0VORVJSOwoKICAgIGhhbmRsZXIyID0gbmV0c25tcF9nZXRfdGFibGVfaGFuZGxlcih0YWJyZXEpOwogICAgaWYgKE5VTEwgPT0gaGFuZGxlcjIgKSB7CiAgICAgICAgbmV0c25tcF9oYW5kbGVyX2ZyZWUoaGFuZGxlcjEpOwogICAgICAgIHJldHVybiBTTk1QX0VSUl9HRU5FUlI7CiAgICB9CgogICAgcmMgPSBuZXRzbm1wX2luamVjdF9oYW5kbGVyKHJlZ2luZm8sIGhhbmRsZXIxKTsKICAgIGlmIChTTk1QRVJSX1NVQ0NFU1MgIT0gcmMpIHsKICAgICAgICBuZXRzbm1wX2hhbmRsZXJfZnJlZShoYW5kbGVyMSk7CiAgICAgICAgbmV0c25tcF9oYW5kbGVyX2ZyZWUoaGFuZGxlcjIpOwogICAgICAgIHJldHVybiByYzsKICAgIH0KCiAgICByYyA9IG5ldHNubXBfaW5qZWN0X2hhbmRsZXIocmVnaW5mbywgaGFuZGxlcjIpOwogICAgaWYgKFNOTVBFUlJfU1VDQ0VTUyAhPSByYykgewogICAgICAgIC8qKiBoYW5kbGVyMSBpcyBpbiByZWdpbmZvLi4uIHJlbW92ZSBhbmQgZnJlZT8/ICovCiAgICAgICAgbmV0c25tcF9oYW5kbGVyX2ZyZWUoaGFuZGxlcjIpOwogICAgICAgIHJldHVybiByYzsKICAgIH0KCiAgICAvKiogYm90aCBoYW5kbGVycyBub3cgaW4gcmVnaW5mbywgc28gbm90aGluZyB0byBkbyBvbiBlcnJvciAqLwogICAgcmV0dXJuIG5ldHNubXBfcmVnaXN0ZXJfaGFuZGxlcihyZWdpbmZvKTsKfQojZW5kaWYgLyogTkVUU05NUF9GRUFUVVJFX1JFTU9WRV9UQUJMRV9TUEFSU0UgKi8KCgojaWZuZGVmIE5FVFNOTVBfRkVBVFVSRV9SRU1PVkVfVEFCTEVfQlVJTERfUkVTVUxUCi8qKiBCdWlsZHMgdGhlIHJlc3VsdCB0byBiZSByZXR1cm5lZCB0byB0aGUgYWdlbnQgZ2l2ZW4gdGhlIHRhYmxlIGluZm9ybWF0aW9uLgogKiAgVXNlIHRoaXMgZnVuY3Rpb24gdG8gcmV0dXJuIHJlc3VsdHMgZnJvbSBsb3dlbCBsZXZlbCBoYW5kbGVycyB0bwogKiAgdGhlIGFnZW50LiAgSXQgdGFrZXMgY2FyZSBvZiBidWlsZGluZyB0aGUgcHJvcGVyIHJlc3VsdGluZyBvaWQKICogIChjb250YWluaW5nIHByb3BlciBpbmRleGluZykgYW5kIGluc2VydHMgdGhlIHJlc3VsdCB2YWx1ZSBpbnRvIHRoZQogKiAgcmV0dXJuaW5nIHZhcmJpbmQuCiAqLwppbnQKbmV0c25tcF90YWJsZV9idWlsZF9yZXN1bHQobmV0c25tcF9oYW5kbGVyX3JlZ2lzdHJhdGlvbiAqcmVnaW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9yZXF1ZXN0X2luZm8gKnJlcWluZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfdGFibGVfcmVxdWVzdF9pbmZvICp0YWJsZV9pbmZvLAogICAgICAgICAgICAgICAgICAgICAgICAgICB1X2NoYXIgdHlwZSwgdV9jaGFyICogcmVzdWx0LCBzaXplX3QgcmVzdWx0X2xlbikKewoKICAgIG5ldHNubXBfdmFyaWFibGVfbGlzdCAqdmFyOwoKICAgIGlmICghcmVxaW5mbyB8fCAhdGFibGVfaW5mbykKICAgICAgICByZXR1cm4gU05NUEVSUl9HRU5FUlI7CgogICAgdmFyID0gcmVxaW5mby0+cmVxdWVzdHZiOwoKICAgIGlmICh2YXItPm5hbWUgIT0gdmFyLT5uYW1lX2xvYykKICAgICAgICBmcmVlKHZhci0+bmFtZSk7CiAgICB2YXItPm5hbWUgPSBOVUxMOwoKICAgIGlmIChuZXRzbm1wX3RhYmxlX2J1aWxkX29pZChyZWdpbmZvLCByZXFpbmZvLCB0YWJsZV9pbmZvKSAhPQogICAgICAgIFNOTVBFUlJfU1VDQ0VTUykKICAgICAgICByZXR1cm4gU05NUEVSUl9HRU5FUlI7CgogICAgc25tcF9zZXRfdmFyX3R5cGVkX3ZhbHVlKHZhciwgdHlwZSwgcmVzdWx0LCByZXN1bHRfbGVuKTsKCiAgICByZXR1cm4gU05NUEVSUl9TVUNDRVNTOwp9CgovKiogZ2l2ZW4gYSByZWdpc3RyYXRpb24gaW5mbyBvYmplY3QsIGEgcmVxdWVzdCBvYmplY3QgYW5kIHRoZSB0YWJsZQogKiAgaW5mbyBvYmplY3QgaXQgYnVpbGRzIHRoZSByZXF1ZXN0LT5yZXF1ZXN0dmItPm5hbWUgb2lkIGZyb20gdGhlCiAqICBpbmRleCB2YWx1ZXMgYW5kIGNvbHVtbiBpbmZvcm1hdGlvbiBmb3VuZCBpbiB0aGUgdGFibGVfaW5mbwogKiAgb2JqZWN0LiBJbmRleCB2YWx1ZXMgYXJlIGV4dHJhY3RlZCBmcm9tIHRoZSB0YWJsZV9pbmZvIHZhcmJpbmRzLgogKi8KaW50Cm5ldHNubXBfdGFibGVfYnVpbGRfb2lkKG5ldHNubXBfaGFuZGxlcl9yZWdpc3RyYXRpb24gKnJlZ2luZm8sCiAgICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfcmVxdWVzdF9pbmZvICpyZXFpbmZvLAogICAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX3RhYmxlX3JlcXVlc3RfaW5mbyAqdGFibGVfaW5mbykKewogICAgb2lkICAgICAgICAgICAgIHRtcG9pZFtNQVhfT0lEX0xFTl07CiAgICBuZXRzbm1wX3ZhcmlhYmxlX2xpc3QgKnZhcjsKCiAgICBpZiAoIXJlZ2luZm8gfHwgIXJlcWluZm8gfHwgIXRhYmxlX2luZm8pCiAgICAgICAgcmV0dXJuIFNOTVBFUlJfR0VORVJSOwoKICAgIC8qCiAgICAgKiB4eHgtcmtzOiBpbmVmZmljZW50LiB3ZSBkbyBhIGNvcHkgaGVyZSwgdGhlbiBidWlsZF9vaWQgZG9lcyBpdAogICAgICogICAgICAgICAgYWdhaW4uIGVpdGhlciBjb21lIHVwIHdpdGggYSBuZXcgdXRpbGl0eSByb3V0aW5lLCBvcgogICAgICogICAgICAgICAgZG8gc29tZSBoaWppbmtzIGhlcmUgdG8gZWxpbWluYXRlIGV4dHJhIGNvcHkuCiAgICAgKiAgICAgICAgICBQcm9iYWJseSBjb3VsZCBtYWtlIHN1cmUgYWxsIGNhbGxlcnMgaGF2ZSB0aGUKICAgICAqICAgICAgICAgIGluZGV4ICYgdmFyaWFibGUgbGlzdCB1cGRhdGVkLCBhbmQgdXNlCiAgICAgKiAgICAgICAgICBuZXRzbm1wX3RhYmxlX2J1aWxkX29pZF9mcm9tX2luZGV4KCkgaW5zdGVhZCBvZiBhbGwgdGhpcy4KICAgICAqLwogICAgbWVtY3B5KHRtcG9pZCwgcmVnaW5mby0+cm9vdG9pZCwgcmVnaW5mby0+cm9vdG9pZF9sZW4gKiBzaXplb2Yob2lkKSk7CiAgICB0bXBvaWRbcmVnaW5mby0+cm9vdG9pZF9sZW5dID0gMTsgICAvKiogLkVudHJ5ICovCiAgICB0bXBvaWRbcmVnaW5mby0+cm9vdG9pZF9sZW4gKyAxXSA9IHRhYmxlX2luZm8tPmNvbG51bTsgLyoqIC5jb2x1bW4gKi8KCiAgICB2YXIgPSByZXFpbmZvLT5yZXF1ZXN0dmI7CiAgICBpZiAoYnVpbGRfb2lkKCZ2YXItPm5hbWUsICZ2YXItPm5hbWVfbGVuZ3RoLAogICAgICAgICAgICAgICAgICB0bXBvaWQsIHJlZ2luZm8tPnJvb3RvaWRfbGVuICsgMiwgdGFibGVfaW5mby0+aW5kZXhlcykKICAgICAgICAhPSBTTk1QRVJSX1NVQ0NFU1MpCiAgICAgICAgcmV0dXJuIFNOTVBFUlJfR0VORVJSOwoKICAgIHJldHVybiBTTk1QRVJSX1NVQ0NFU1M7Cn0KI2VuZGlmIC8qIE5FVFNOTVBfRkVBVFVSRV9SRU1PVkVfVEFCTEVfQlVJTERfUkVTVUxUICovCgovKiogZ2l2ZW4gYSByZWdpc3RyYXRpb24gaW5mbyBvYmplY3QsIGEgcmVxdWVzdCBvYmplY3QgYW5kIHRoZSB0YWJsZQogKiAgaW5mbyBvYmplY3QgaXQgYnVpbGRzIHRoZSByZXF1ZXN0LT5yZXF1ZXN0dmItPm5hbWUgb2lkIGZyb20gdGhlCiAqICBpbmRleCB2YWx1ZXMgYW5kIGNvbHVtbiBpbmZvcm1hdGlvbiBmb3VuZCBpbiB0aGUgdGFibGVfaW5mbwogKiAgb2JqZWN0LiAgSW5kZXggdmFsdWVzIGFyZSBleHRyYWN0ZWQgZnJvbSB0aGUgdGFibGVfaW5mbyBpbmRleCBvaWQuCiAqLwppbnQKbmV0c25tcF90YWJsZV9idWlsZF9vaWRfZnJvbV9pbmRleChuZXRzbm1wX2hhbmRsZXJfcmVnaXN0cmF0aW9uICpyZWdpbmZvLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfcmVxdWVzdF9pbmZvICpyZXFpbmZvLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfdGFibGVfcmVxdWVzdF9pbmZvICp0YWJsZV9pbmZvKQp7CiAgICBvaWQgICAgICAgICAgICAgdG1wb2lkW01BWF9PSURfTEVOXTsKICAgIG5ldHNubXBfdmFyaWFibGVfbGlzdCAqdmFyOwogICAgaW50ICAgICAgICAgICAgIGxlbjsKCiAgICBpZiAoIXJlZ2luZm8gfHwgIXJlcWluZm8gfHwgIXRhYmxlX2luZm8pCiAgICAgICAgcmV0dXJuIFNOTVBFUlJfR0VORVJSOwoKICAgIHZhciA9IHJlcWluZm8tPnJlcXVlc3R2YjsKICAgIGxlbiA9IHJlZ2luZm8tPnJvb3RvaWRfbGVuOwogICAgbWVtY3B5KHRtcG9pZCwgcmVnaW5mby0+cm9vdG9pZCwgbGVuICogc2l6ZW9mKG9pZCkpOwogICAgdG1wb2lkW2xlbisrXSA9IDE7ICAgICAgICAgIC8qIC5FbnRyeSAqLwogICAgdG1wb2lkW2xlbisrXSA9IHRhYmxlX2luZm8tPmNvbG51bTsgLyogLmNvbHVtbiAqLwogICAgbWVtY3B5KCZ0bXBvaWRbbGVuXSwgdGFibGVfaW5mby0+aW5kZXhfb2lkLAogICAgICAgICAgIHRhYmxlX2luZm8tPmluZGV4X29pZF9sZW4gKiBzaXplb2Yob2lkKSk7CiAgICBsZW4gKz0gdGFibGVfaW5mby0+aW5kZXhfb2lkX2xlbjsKICAgIHNubXBfc2V0X3Zhcl9vYmppZCggdmFyLCB0bXBvaWQsIGxlbiApOwoKICAgIHJldHVybiBTTk1QRVJSX1NVQ0NFU1M7Cn0KCi8qKiBwYXJzZXMgYW4gT0lEIGludG8gdGFibGUgaW5kZXhzZXMgKi8KaW50Cm5ldHNubXBfdXBkYXRlX3ZhcmlhYmxlX2xpc3RfZnJvbV9pbmRleChuZXRzbm1wX3RhYmxlX3JlcXVlc3RfaW5mbyAqdHJpKQp7CiAgICBpZiAoIXRyaSkKICAgICAgICByZXR1cm4gU05NUEVSUl9HRU5FUlI7CgogICAgLyoKICAgICAqIGZyZWUgYW55IGV4aXN0aW5nIGFsbG9jYXRlZCBtZW1vcnksIHRoZW4gcGFyc2Ugb2lkIGludG8gdmFyYmluZHMKICAgICAqLwogICAgc25tcF9yZXNldF92YXJfYnVmZmVycyggdHJpLT5pbmRleGVzKTsKCiAgICByZXR1cm4gcGFyc2Vfb2lkX2luZGV4ZXModHJpLT5pbmRleF9vaWQsIHRyaS0+aW5kZXhfb2lkX2xlbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0cmktPmluZGV4ZXMpOwp9CgovKiogYnVpbGRzIGFuIG9pZCBnaXZlbiBhIHNldCBvZiBpbmRleGVzLiAqLwppbnQKbmV0c25tcF91cGRhdGVfaW5kZXhlc19mcm9tX3ZhcmlhYmxlX2xpc3QobmV0c25tcF90YWJsZV9yZXF1ZXN0X2luZm8gKnRyaSkKewogICAgaWYgKCF0cmkpCiAgICAgICAgcmV0dXJuIFNOTVBFUlJfR0VORVJSOwoKICAgIHJldHVybiBidWlsZF9vaWRfbm9hbGxvYyh0cmktPmluZGV4X29pZCwgc2l6ZW9mKHRyaS0+aW5kZXhfb2lkKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmdHJpLT5pbmRleF9vaWRfbGVuLCBOVUxMLCAwLCB0cmktPmluZGV4ZXMpOwp9CgovKioKICogY2hlY2tzIHRoZSBvcmlnaW5hbCByZXF1ZXN0IGFnYWluc3QgdGhlIGN1cnJlbnQgZGF0YSBiZWluZyBwYXNzZWQgaW4gaWYgCiAqIGl0cyBncmVhdGVyIHRoYW4gdGhlIHJlcXVlc3Qgb2lkIGJ1dCBsZXNzIHRoYW4gdGhlIGN1cnJlbnQgdmFsaWQKICogcmV0dXJuLCBzZXQgdGhlIGN1cnJlbnQgdmFsaWQgcmV0dXJuIHRvIHRoZSBuZXcgdmFsdWUuCiAqIAogKiByZXR1cm5zIDEgaWYgb3V0dmFyIHdhcyByZXBsYWNlZCB3aXRoIHRoZSBvaWQgZnJvbSBuZXd2YXIgKHN1Y2Nlc3MpLgogKiByZXR1cm5zIDAgaWYgbm90LiAKICovCmludApuZXRzbm1wX2NoZWNrX2dldG5leHRfcmVwbHkobmV0c25tcF9yZXF1ZXN0X2luZm8gKnJlcXVlc3QsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBvaWQgKiBwcmVmaXgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaXplX3QgcHJlZml4X2xlbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfdmFyaWFibGVfbGlzdCAqIG5ld3ZhciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfdmFyaWFibGVfbGlzdCAqKiBvdXR2YXIpCnsKICAgIG9pZCAgICAgIG15bmFtZVtNQVhfT0lEX0xFTl07CiAgICBzaXplX3QgICBteW5hbWVfbGVuOwoKICAgIGJ1aWxkX29pZF9ub2FsbG9jKG15bmFtZSwgTUFYX09JRF9MRU4sICZteW5hbWVfbGVuLAogICAgICAgICAgICAgICAgICAgICAgcHJlZml4LCBwcmVmaXhfbGVuLCBuZXd2YXIpOwogICAgLyoKICAgICAqIGlzIHRoZSBidWlsZCBvZiB0aGUgbmV3IGluZGV4ZXMgbGVzcyB0aGFuIG91ciBjdXJyZW50IHJlc3VsdCAKICAgICAqLwogICAgaWYgKCghKCpvdXR2YXIpIHx8IHNubXBfb2lkX2NvbXBhcmUobXluYW1lICsgcHJlZml4X2xlbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG15bmFtZV9sZW4gLSBwcmVmaXhfbGVuLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKCpvdXR2YXIpLT5uYW1lICsgcHJlZml4X2xlbiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICgqb3V0dmFyKS0+bmFtZV9sZW5ndGggLQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJlZml4X2xlbikgPCAwKSkgewogICAgICAgIC8qCiAgICAgICAgICogYW5kIGdyZWF0ZXIgdGhhbiB0aGUgcmVxdWVzdGVkIG9pZCAKICAgICAgICAgKi8KICAgICAgICBpZiAoc25tcF9vaWRfY29tcGFyZShteW5hbWUsIG15bmFtZV9sZW4sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVxdWVzdC0+cmVxdWVzdHZiLT5uYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcXVlc3QtPnJlcXVlc3R2Yi0+bmFtZV9sZW5ndGgpID4gMCkgewogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiB0aGUgbmV3IHJlc3VsdCBtdXN0IGJlIGJldHRlciB0aGFuIHRoZSBvbGQgCiAgICAgICAgICAgICAqLwojaWZkZWYgT05MWV9XT1JLU19XSVRIX09ORV9WQVJCSU5ECiAgICAgICAgICAgIGlmICghKm91dHZhcikKICAgICAgICAgICAgICAgICpvdXR2YXIgPSBzbm1wX2Nsb25lX3ZhcmJpbmQobmV3dmFyKTsKCSAgICBlbHNlCiAgICAgICAgICAgICAgICAvKiAKICAgICAgICAgICAgICAgICAqIFRPRE86IHdhbGsgdGhlIGZ1bGwgdmFyYmluZCBsaXN0LCBzZXR0aW5nCiAgICAgICAgICAgICAgICAgKiAgICAgICAqYWxsKiB0aGUgdmFsdWVzIC0gbm90IGp1c3QgdGhlIGZpcnN0LgogICAgICAgICAgICAgICAgICovCiAgICAgICAgICAgICAgICBzbm1wX3NldF92YXJfdHlwZWRfdmFsdWUoKm91dHZhciwgbmV3dmFyLT50eXBlLAoJCQkJbmV3dmFyLT52YWwuc3RyaW5nLCBuZXd2YXItPnZhbF9sZW4pOwojZWxzZSAgLyogSW50ZXJpbSByZXBsYWNlbWVudCBhcHByb2FjaCAtIGxlc3MgZWZmaWNpZW50LCBidXQgaXQgd29ya3MhICovCiAgICAgICAgICAgIGlmICgqb3V0dmFyKQogICAgICAgICAgICAgICAgc25tcF9mcmVlX3ZhcmJpbmQoKm91dHZhcik7CiAgICAgICAgICAgICpvdXR2YXIgPSBzbm1wX2Nsb25lX3ZhcmJpbmQobmV3dmFyKTsKI2VuZGlmCiAgICAgICAgICAgIHNubXBfc2V0X3Zhcl9vYmppZCgqb3V0dmFyLCBteW5hbWUsIG15bmFtZV9sZW4pOwoKICAgICAgICAgICAgcmV0dXJuIDE7CiAgICAgICAgfQogICAgfQogICAgcmV0dXJuIDA7Cn0KCm5ldHNubXBfdGFibGVfcmVnaXN0cmF0aW9uX2luZm8gKgpuZXRzbm1wX3RhYmxlX3JlZ2lzdHJhdGlvbl9pbmZvX2Nsb25lKG5ldHNubXBfdGFibGVfcmVnaXN0cmF0aW9uX2luZm8gKnRyaSkKewogICAgbmV0c25tcF90YWJsZV9yZWdpc3RyYXRpb25faW5mbyAqY29weTsKICAgIGNvcHkgPSBtYWxsb2Moc2l6ZW9mKCpjb3B5KSk7CiAgICBpZiAoY29weSkgewogICAgICAgICpjb3B5ID0gKnRyaTsKICAgICAgICBjb3B5LT5pbmRleGVzID0gc25tcF9jbG9uZV92YXJiaW5kKHRyaS0+aW5kZXhlcyk7CiAgICAgICAgaWYgKCFjb3B5LT5pbmRleGVzKSB7CiAgICAgICAgICAgIGZyZWUoY29weSk7CiAgICAgICAgICAgIGNvcHkgPSBOVUxMOwogICAgICAgIH0KICAgIH0KICAgIHJldHVybiBjb3B5Owp9Cgp2b2lkCm5ldHNubXBfdGFibGVfcmVnaXN0cmF0aW9uX2luZm9fZnJlZShuZXRzbm1wX3RhYmxlX3JlZ2lzdHJhdGlvbl9pbmZvICp0cmkpCnsKICAgIGlmIChOVUxMID09IHRyaSkKICAgICAgICByZXR1cm47CgogICAgaWYgKE5VTEwgIT0gdHJpLT5pbmRleGVzKQogICAgICAgIHNubXBfZnJlZV92YXJiaW5kKHRyaS0+aW5kZXhlcyk7CgojaWYgMAogICAgLyoKICAgICAqIHNpZ2guLi4gZXhhbXBsZSB1c2Ugb2YgdmFsaWRfY29sdW1ucyBwb2ludHMgdG8gc3RhdGljIG1lbW9yeSwKICAgICAqIHNvIGZyZWVpbmcgaXQgd291bGQgYmUgYmFkLi4uIHdlJ2xsIGp1c3QgaGF2ZSB0byBsaXZlIHdpdGggYW55CiAgICAgKiBsZWFrcywgZm9yIG5vdy4uLgogICAgICovCiNlbmRpZgoKICAgIGZyZWUodHJpKTsKfQoKLyoqIEB9ICovCgovKgogKiBpbnRlcm5hbCByb3V0aW5lcyAKICovCnZvaWQKdGFibGVfZGF0YV9mcmVlX2Z1bmModm9pZCAqZGF0YSkKewogICAgbmV0c25tcF90YWJsZV9yZXF1ZXN0X2luZm8gKmluZm8gPSAobmV0c25tcF90YWJsZV9yZXF1ZXN0X2luZm8gKikgZGF0YTsKICAgIGlmICghaW5mbykKICAgICAgICByZXR1cm47CiAgICBzbm1wX2ZyZWVfdmFyYmluZChpbmZvLT5pbmRleGVzKTsKICAgIGZyZWUoaW5mbyk7Cn0KCgoKc3RhdGljIHZvaWQKdGFibGVfaGVscGVyX2NsZWFudXAobmV0c25tcF9hZ2VudF9yZXF1ZXN0X2luZm8gKnJlcWluZm8sCiAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfcmVxdWVzdF9pbmZvICpyZXF1ZXN0LCBpbnQgc3RhdHVzKQp7CiAgICBuZXRzbm1wX3NldF9yZXF1ZXN0X2Vycm9yKHJlcWluZm8sIHJlcXVlc3QsIHN0YXR1cyk7CiAgICBuZXRzbm1wX2ZyZWVfcmVxdWVzdF9kYXRhX3NldHMocmVxdWVzdCk7CiAgICBpZiAoIXJlcXVlc3QpCiAgICAgICAgcmV0dXJuOwogICAgcmVxdWVzdC0+cGFyZW50X2RhdGEgPSBOVUxMOwp9CgoKLyoKICogZmluZCB0aGUgY2xvc2VzdCBjb2x1bW4gdG8gY3VycmVudCAod2hpY2ggbWF5IGJlIGN1cnJlbnQpLgogKgogKiBjYWxsZWQgd2hlbiBhIHRhYmxlIHJ1bnMgb3V0IG9mIHJvd3MgZm9yIGNvbHVtbiBYLiBUaGlzCiAqIGZ1bmN0aW9uIGlzIGNhbGxlZCB3aXRoIGN1cnJlbnQgPSBYICsgMSwgdG8gdmVyaWZ5IHRoYXQKICogWCArIDEgaXMgYSB2YWxpZCBjb2x1bW4sIG9yIGZpbmQgdGhlIG5leHQgY2xvc2VzdCBjb2x1bW4gaWYgbm90LgogKgogKiBBbGwgbGlzdCB0eXBlcyBzaG91bGQgYmUgc29ydGVkLCBsb3dlc3QgdG8gaGlnaGVzdC4KICovCnVuc2lnbmVkIGludApuZXRzbm1wX2Nsb3Nlc3RfY29sdW1uKHVuc2lnbmVkIGludCBjdXJyZW50LAogICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfY29sdW1uX2luZm8gKnZhbGlkX2NvbHVtbnMpCnsKICAgIHVuc2lnbmVkIGludCAgICBjbG9zZXN0ID0gMDsKICAgIGludCAgICAgICAgICAgICBpZHg7CgogICAgaWYgKHZhbGlkX2NvbHVtbnMgPT0gTlVMTCkKICAgICAgICByZXR1cm4gMDsKCiAgICBmb3IoIDsgdmFsaWRfY29sdW1uczsgdmFsaWRfY29sdW1ucyA9IHZhbGlkX2NvbHVtbnMtPm5leHQpIHsKCiAgICAgICAgaWYgKHZhbGlkX2NvbHVtbnMtPmlzUmFuZ2UpIHsKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogaWYgY3VycmVudCA8IGxvdyByYW5nZSwgaXQgbWlnaHQgYmUgY2xvc2VzdC4KICAgICAgICAgICAgICogb3RoZXJ3aXNlLCBpZiBpdCdzIDwgaGlnaCByYW5nZSwgY3VycmVudCBpcyBpbgogICAgICAgICAgICAgKiB0aGUgcmFuZ2UsIGFuZCB0aHVzIGlzIGFuIGV4YWN0IG1hdGNoLgogICAgICAgICAgICAgKi8KICAgICAgICAgICAgaWYgKGN1cnJlbnQgPCB2YWxpZF9jb2x1bW5zLT5kZXRhaWxzLnJhbmdlWzBdKSB7CiAgICAgICAgICAgICAgICBpZiAoICh2YWxpZF9jb2x1bW5zLT5kZXRhaWxzLnJhbmdlWzBdIDwgY2xvc2VzdCkgfHwKICAgICAgICAgICAgICAgICAgICAgKDAgPT0gY2xvc2VzdCkpIHsKICAgICAgICAgICAgICAgICAgICBjbG9zZXN0ID0gdmFsaWRfY29sdW1ucy0+ZGV0YWlscy5yYW5nZVswXTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfSBlbHNlIGlmIChjdXJyZW50IDw9IHZhbGlkX2NvbHVtbnMtPmRldGFpbHMucmFuZ2VbMV0pIHsKICAgICAgICAgICAgICAgIGNsb3Nlc3QgPSBjdXJyZW50OwogICAgICAgICAgICAgICAgYnJlYWs7ICAgICAgIC8qIGNhbiBub3QgZ2V0IGFueSBjbG9zZXIhICovCiAgICAgICAgICAgIH0KCiAgICAgICAgfSAvKiByYW5nZSAqLwogICAgICAgIGVsc2UgeyAgICAgICAgICAgICAgICAgIC8qIGxpc3QgKi8KICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogaWYgY3VycmVudCA8IGZpcnN0IGl0ZW0sIG5vIG5lZWQgdG8gaXRlcmF0ZSBvdmVyIGxpc3QuCiAgICAgICAgICAgICAqIHRoYXQgaXRlbSBpcyBlaXRoZXIgY2xvc2VzdCwgb3Igbm90LgogICAgICAgICAgICAgKi8KICAgICAgICAgICAgaWYgKGN1cnJlbnQgPCB2YWxpZF9jb2x1bW5zLT5kZXRhaWxzLmxpc3RbMF0pIHsKICAgICAgICAgICAgICAgIGlmICgodmFsaWRfY29sdW1ucy0+ZGV0YWlscy5saXN0WzBdIDwgY2xvc2VzdCkgfHwKICAgICAgICAgICAgICAgICAgICAoMCA9PSBjbG9zZXN0KSkKICAgICAgICAgICAgICAgICAgICBjbG9zZXN0ID0gdmFsaWRfY29sdW1ucy0+ZGV0YWlscy5saXN0WzBdOwogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8qKiBpZiBjdXJyZW50ID4gbGFzdCBpdGVtIGluIGxpc3QsIG5vIG5lZWQgdG8gaXRlcmF0ZSAqLwogICAgICAgICAgICBpZiAoY3VycmVudCA+CiAgICAgICAgICAgICAgICB2YWxpZF9jb2x1bW5zLT5kZXRhaWxzLmxpc3RbKGludCl2YWxpZF9jb2x1bW5zLT5saXN0X2NvdW50IC0gMV0pCiAgICAgICAgICAgICAgICBjb250aW51ZTsgICAgICAgLyogbm90IGluIGxpc3QgcmFuZ2UuICovCgogICAgICAgICAgICAvKiogc2tpcCBhbnl0aGluZyBsZXNzIHRoYW4gY3VycmVudCovCiAgICAgICAgICAgIGZvciAoaWR4ID0gMDsgdmFsaWRfY29sdW1ucy0+ZGV0YWlscy5saXN0W2lkeF0gPCBjdXJyZW50OyArK2lkeCkKICAgICAgICAgICAgICAgIDsKICAgICAgICAgICAgCiAgICAgICAgICAgIC8qKiBjaGVjayBmb3IgZXhhY3QgbWF0Y2ggKi8KICAgICAgICAgICAgaWYgKGN1cnJlbnQgPT0gdmFsaWRfY29sdW1ucy0+ZGV0YWlscy5saXN0W2lkeF0pIHsKICAgICAgICAgICAgICAgIGNsb3Nlc3QgPSBjdXJyZW50OwogICAgICAgICAgICAgICAgYnJlYWs7ICAgICAgLyogY2FuIG5vdCBnZXQgYW55IGNsb3NlciEgKi8KICAgICAgICAgICAgfQogICAgICAgICAgICAKICAgICAgICAgICAgLyoqIGxpc3RbaWR4XSA+IGN1cnJlbnQ7IGlzIGl0IDwgY2xvc2VzdD8gKi8KICAgICAgICAgICAgaWYgKCh2YWxpZF9jb2x1bW5zLT5kZXRhaWxzLmxpc3RbaWR4XSA8IGNsb3Nlc3QpIHx8CiAgICAgICAgICAgICAgICAoMCA9PSBjbG9zZXN0KSkKICAgICAgICAgICAgICAgIGNsb3Nlc3QgPSB2YWxpZF9jb2x1bW5zLT5kZXRhaWxzLmxpc3RbaWR4XTsKCiAgICAgICAgfSAgICAgICAgICAgICAgICAgICAgICAgLyogbGlzdCAqLwogICAgfSAgICAgICAgICAgICAgICAgICAgICAgICAgIC8qIGZvciAqLwoKICAgIHJldHVybiBjbG9zZXN0Owp9CgovKioKICogVGhpcyBmdW5jdGlvbiBjYW4gYmUgdXNlZCB0byBzZXR1cCB0aGUgdGFibGUncyBkZWZpbml0aW9uIHdpdGhpbgogKiB5b3VyIG1vZHVsZSdzIGluaXRpYWxpemUgZnVuY3Rpb24sIGl0IHRha2VzIGEgdmFyaWFibGUgaW5kZXggcGFyYW1ldGVyIGxpc3QKICogZm9yIGV4YW1wbGU6IHRoZSB0YWJsZV9pbmZvIHN0cnVjdHVyZSBpcyBmb2xsb3dlZCBieSB0d28gaW50ZWdlciBpbmRleCB0eXBlcwogKiBuZXRzbm1wX3RhYmxlX2hlbHBlcl9hZGRfaW5kZXhlcygKICogICAgICAgICAgICAgICAgICB0YWJsZV9pbmZvLCAgIAogKgkgICAgICAgICAgICBBU05fSU5URUdFUiwgIAogKgkJICAgIEFTTl9JTlRFR0VSLCAgCiAqCQkgICAgMCk7CiAqCiAqIEBwYXJhbSB0aW5mbyBpcyBhIHBvaW50ZXIgdG8gYSBuZXRzbm1wX3RhYmxlX3JlZ2lzdHJhdGlvbl9pbmZvIHN0cnVjdC4KICoJVGhlIHRhYmxlIGhhbmRsZXIgbmVlZHMgdG8ga25vdyB1cCBmcm9udCBob3cgeW91ciB0YWJsZSBpcyBzdHJ1Y3R1cmVkLgogKglBIG5ldHNubXBfdGFibGVfcmVnaXN0ZXJhdGlvbl9pbmZvIHN0cnVjdHVyZSB0aGF0IGlzIAogKglwYXNzZWQgdG8gdGhlIHRhYmxlIGhhbmRsZXIgc2hvdWxkIGNvbnRhaW4gdGhlIGFzbiBpbmRleCB0eXBlcyBmb3IgdGhlIAogKgl0YWJsZSBhcyB3ZWxsIGFzIHRoZSBtaW5pbXVtIGFuZCBtYXhpbXVtIGNvbHVtbiB0aGF0IHNob3VsZCBiZSB1c2VkLgogKgogKiBAcmV0dXJuIHZvaWQKICoKICovCnZvaWQKbmV0c25tcF90YWJsZV9oZWxwZXJfYWRkX2luZGV4ZXMobmV0c25tcF90YWJsZV9yZWdpc3RyYXRpb25faW5mbyAqdGluZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC4uLikKewogICAgdmFfbGlzdCAgICAgICAgIGRlYnVnYXJnczsKICAgIGludCAgICAgICAgICAgICB0eXBlOwoKICAgIHZhX3N0YXJ0KGRlYnVnYXJncywgdGluZm8pOwogICAgd2hpbGUgKCh0eXBlID0gdmFfYXJnKGRlYnVnYXJncywgaW50KSkgIT0gMCkgewogICAgICAgIG5ldHNubXBfdGFibGVfaGVscGVyX2FkZF9pbmRleCh0aW5mbywgdHlwZSk7CiAgICB9CiAgICB2YV9lbmQoZGVidWdhcmdzKTsKfQoKI2lmbmRlZiBORVRTTk1QX05PX1dSSVRFX1NVUFBPUlQKc3RhdGljIHZvaWQKX3Jvd19zdGFzaF9kYXRhX2xpc3RfZnJlZSh2b2lkICpwdHIpIHsKICAgIG5ldHNubXBfb2lkX3N0YXNoX25vZGUgKip0bXAgPSAobmV0c25tcF9vaWRfc3Rhc2hfbm9kZSAqKilwdHI7CiAgICBuZXRzbm1wX29pZF9zdGFzaF9mcmVlKHRtcCwgTlVMTCk7CiAgICBmcmVlKHB0cik7Cn0KCiNpZm5kZWYgTkVUU05NUF9GRUFUVVJFX1JFTU9WRV9UQUJMRV9HRVRfT1JfQ1JFQVRFX1JPV19TVEFTSAovKiogcmV0dXJucyBhIHJvdy13aWRlIHBsYWNlIHRvIHN0b3JlIGRhdGEgaW4uCiAgICBAdG9kbyBUaGlzIGZ1bmN0aW9uIHdpbGwgbGlrZWx5IGNoYW5nZSB0byBhZGQgZnJlZSBwb2ludGVyIGZ1bmN0aW9ucy4gKi8KbmV0c25tcF9vaWRfc3Rhc2hfbm9kZSAqKgpuZXRzbm1wX3RhYmxlX2dldF9vcl9jcmVhdGVfcm93X3N0YXNoKG5ldHNubXBfYWdlbnRfcmVxdWVzdF9pbmZvICpyZXFpbmZvLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHVfY2hhciAqIHN0b3JhZ2VfbmFtZSkKewogICAgbmV0c25tcF9vaWRfc3Rhc2hfbm9kZSAqKnN0YXNocCA9IE5VTEw7CiAgICBzdGFzaHAgPSAobmV0c25tcF9vaWRfc3Rhc2hfbm9kZSAqKikKICAgICAgICBuZXRzbm1wX2FnZW50X2dldF9saXN0X2RhdGEocmVxaW5mbywgKGNvbnN0IGNoYXIgKikgc3RvcmFnZV9uYW1lKTsKCiAgICBpZiAoIXN0YXNocCkgewogICAgICAgIC8qCiAgICAgICAgICogaGFzbid0IGJlIGNyZWF0ZWQgeWV0LiAgd2UgY3JlYXRlIGl0IGhlcmUuIAogICAgICAgICAqLwogICAgICAgIHN0YXNocCA9IFNOTVBfTUFMTE9DX1RZUEVERUYobmV0c25tcF9vaWRfc3Rhc2hfbm9kZSAqKTsKCiAgICAgICAgaWYgKCFzdGFzaHApCiAgICAgICAgICAgIHJldHVybiBOVUxMOyAgICAgICAgLyogYWNrLiBvdXQgb2YgbWVtICovCgogICAgICAgIG5ldHNubXBfYWdlbnRfYWRkX2xpc3RfZGF0YShyZXFpbmZvLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX2NyZWF0ZV9kYXRhX2xpc3QoKGNvbnN0IGNoYXIgKikgc3RvcmFnZV9uYW1lLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3Rhc2hwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgX3Jvd19zdGFzaF9kYXRhX2xpc3RfZnJlZSkpOwogICAgfQogICAgcmV0dXJuIHN0YXNocDsKfQojZW5kaWYgLyogTkVUU05NUF9GRUFUVVJFX1JFTU9WRV9UQUJMRV9HRVRfT1JfQ1JFQVRFX1JPV19TVEFTSCAqLwojZW5kaWYgLyogTkVUU05NUF9OT19XUklURV9TVVBQT1JUICovCgovKgogKiBhZHZhbmNlIHRoZSB0YWJsZSBpbmZvIGNvbG51bSB0byB0aGUgbmV4dCBjb2x1bW4sIG9yIDAgaWYgdGhlcmUgYXJlIG5vIG1vcmUKICoKICogQHJldHVybiBuZXcgY29sdW1uLCBvciAwIGlmIHRoZXJlIGFyZSBubyBtb3JlCiAqLwp1bnNpZ25lZCBpbnQKbmV0c25tcF90YWJsZV9uZXh0X2NvbHVtbihuZXRzbm1wX3RhYmxlX3JlcXVlc3RfaW5mbyAqdGFibGVfaW5mbykKewogICAgaWYgKE5VTEwgPT0gdGFibGVfaW5mbykKICAgICAgICByZXR1cm4gMDsKCiAgICAvKgogICAgICogdHJ5IGFuZCB2YWxpZGF0ZSBuZXh0IGNvbHVtbgogICAgICovCiAgICBpZiAodGFibGVfaW5mby0+cmVnX2luZm8tPnZhbGlkX2NvbHVtbnMpCiAgICAgICAgcmV0dXJuIG5ldHNubXBfY2xvc2VzdF9jb2x1bW4odGFibGVfaW5mby0+Y29sbnVtICsgMSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0YWJsZV9pbmZvLT5yZWdfaW5mby0+dmFsaWRfY29sdW1ucyk7CiAgICAKICAgIC8qCiAgICAgKiBjYW4ndCB2YWxpZGF0ZS4gYXNzdW1lIDEuLm1heF9jb2x1bW4gYXJlIHZhbGlkCiAgICAgKi8KICAgIGlmICh0YWJsZV9pbmZvLT5jb2xudW0gPCB0YWJsZV9pbmZvLT5yZWdfaW5mby0+bWF4X2NvbHVtbikKICAgICAgICByZXR1cm4gdGFibGVfaW5mby0+Y29sbnVtICsgMTsKICAgIAogICAgcmV0dXJuIDA7IC8qIG91dCBvZiByYW5nZSAqLwp9Cg==