LyogUG9ydGlvbnMgb2YgdGhpcyBmaWxlIGFyZSBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29weXJpZ2h0KHMpLiAgU2VlCiAqIHRoZSBOZXQtU05NUCdzIENPUFlJTkcgZmlsZSBmb3IgbW9yZSBkZXRhaWxzIGFuZCBvdGhlciBjb3B5cmlnaHRzCiAqIHRoYXQgbWF5IGFwcGx5OgogKi8KLyoKICogUG9ydGlvbnMgb2YgdGhpcyBmaWxlIGFyZSBjb3B5cmlnaHRlZCBieToKICogQ29weXJpZ2h0IKkgMjAwMyBTdW4gTWljcm9zeXN0ZW1zLCBJbmMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIFVzZSBpcyBzdWJqZWN0IHRvIGxpY2Vuc2UgdGVybXMgc3BlY2lmaWVkIGluIHRoZSBDT1BZSU5HIGZpbGUKICogZGlzdHJpYnV0ZWQgd2l0aCB0aGUgTmV0LVNOTVAgcGFja2FnZS4KICovCiNpbmNsdWRlIDxuZXQtc25tcC9uZXQtc25tcC1jb25maWcuaD4KI2luY2x1ZGUgPG5ldC1zbm1wL25ldC1zbm1wLWluY2x1ZGVzLmg+CiNpbmNsdWRlIDxuZXQtc25tcC9hZ2VudC9uZXQtc25tcC1hZ2VudC1pbmNsdWRlcy5oPgoKI2luY2x1ZGUgPG5ldC1zbm1wL2FnZW50L2RlYnVnX2hhbmRsZXIuaD4KCi8qKiBAZGVmZ3JvdXAgZGVidWcgZGVidWcKICogIFByaW50IG91dCBkZWJ1Z2dpbmcgaW5mb3JtYXRpb24gYWJvdXQgdGhlIGhhbmRsZXIgY2hhaW4gYmVpbmcgY2FsbGVkLgogKiAgVGhpcyBpcyBhIHVzZWZ1bCBtb2R1bGUgZm9yIHJ1bi10aW1lCiAqICBkZWJ1Z2dpbmcgb2YgcmVxdWVzdHMgYXMgdGhlIHBhc3MgdGhpcyBoYW5kbGVyIGluIGEgY2FsbGluZyBjaGFpbi4KICogIEFsbCBkZWJ1Z2dpbmcgb3V0cHV0IGlzIGRvbmUgdmlhIHRoZSBzdGFuZGFyZCBkZWJ1Z2dpbmcgcm91dGluZXMKICogIHdpdGggYSB0b2tlbiBuYW1lIG9mICJoZWxwZXI6ZGVidWciLCBzbyB1c2UgdGhlIC1EaGVscGVyOmRlYnVnCiAqICBjb21tYW5kIGxpbmUgZmxhZyB0byBzZWUgdGhlIG91dHB1dCB3aGVuIHJ1bm5pbmcgdGhlIHNubXBkCiAqICBkZW1vbi4gSXQncyBub3QgcmVjb21tZW5kZWQgeW91IGNvbXBpbGUgdGhpcyBpbnRvIGEgaGFuZGxlciBjaGFpbgogKiAgZHVyaW5nIGNvbXBpbGUgdGltZSwgYnV0IGluc3RlYWQgdXNlIHRoZSAiaW5qZWN0SGFuZGxlciIgdG9rZW4gaW4KICogIHRoZSBzbm1wZC5jb25mIGZpbGUgKG9yIHNpbWlsYXIpIHRvIGFkZCBpdCB0byB0aGUgY2hhaW4gbGF0ZXI6CiAqCiAqICAgICBpbmplY3RIYW5kbGVyIGRlYnVnIG15X21vZHVsZV9uYW1lCiAqCiAqICB0byBzZWUgYW4gZXhhbXBsZSBvdXRwdXQsIHRyeToKICoKICogICAgIGluamVjdEhhbmRsZXIgZGVidWcgbWliSUkvc3lzdGVtCiAqCiAqICBhbmQgdGhlbiBydW4gc25tcHdhbGsgb24gdGhlICJzeXN0ZW0iIGdyb3VwLgogKgogKiAgQGluZ3JvdXAgdXRpbGl0aWVzCiAqICBAewogKi8KCi8qKiByZXR1cm5zIGEgZGVidWcgaGFuZGxlciB0aGF0IGNhbiBiZSBpbmplY3RlZCBpbnRvIGEgZ2l2ZW4KICogIGhhbmRsZXIgY2hhaW4uCiAqLwpuZXRzbm1wX21pYl9oYW5kbGVyICoKbmV0c25tcF9nZXRfZGVidWdfaGFuZGxlcih2b2lkKQp7CiAgICByZXR1cm4gbmV0c25tcF9jcmVhdGVfaGFuZGxlcigiZGVidWciLCBuZXRzbm1wX2RlYnVnX2hlbHBlcik7Cn0KCiNpZmRlZiBORVRTTk1QX05PX0RFQlVHR0lORwoKI2RlZmluZSBkZWJ1Z19wcmludF9yZXF1ZXN0cyh4KQoKI2Vsc2UgLyogTkVUU05NUF9OT19ERUJVR0dJTkcgKi8KCi8qKiBAaW50ZXJuYWwgZGVidWcgcHJpbnQgdmFyaWFibGVzIGluIGEgY2hhaW4gKi8Kc3RhdGljIHZvaWQKZGVidWdfcHJpbnRfcmVxdWVzdHMobmV0c25tcF9yZXF1ZXN0X2luZm8gKnJlcXVlc3RzKQp7CiAgICBuZXRzbm1wX3JlcXVlc3RfaW5mbyAqcmVxdWVzdDsKCiAgICBmb3IgKHJlcXVlc3QgPSByZXF1ZXN0czsgcmVxdWVzdDsgcmVxdWVzdCA9IHJlcXVlc3QtPm5leHQpIHsKICAgICAgICBERUJVR01TR1RMKCgiaGVscGVyOmRlYnVnIiwgIiAgICAgICMlMmQ6ICIsIHJlcXVlc3QtPmluZGV4KSk7CiAgICAgICAgREVCVUdNU0dWQVIoKCJoZWxwZXI6ZGVidWciLCByZXF1ZXN0LT5yZXF1ZXN0dmIpKTsKICAgICAgICBERUJVR01TRygoImhlbHBlcjpkZWJ1ZyIsICJcbiIpKTsKCiAgICAgICAgaWYgKHJlcXVlc3QtPnByb2Nlc3NlZCkKICAgICAgICAgICAgREVCVUdNU0dUTCgoImhlbHBlcjpkZWJ1ZyIsICIgICAgICAgIFtwcm9jZXNzZWRdXG4iKSk7CiAgICAgICAgaWYgKHJlcXVlc3QtPmRlbGVnYXRlZCkKICAgICAgICAgICAgREVCVUdNU0dUTCgoImhlbHBlcjpkZWJ1ZyIsICIgICAgICAgIFtkZWxlZ2F0ZWRdXG4iKSk7CiAgICAgICAgaWYgKHJlcXVlc3QtPnN0YXR1cykKICAgICAgICAgICAgREVCVUdNU0dUTCgoImhlbHBlcjpkZWJ1ZyIsICIgICAgICAgIFtzdGF0dXMgPSAlZF1cbiIsCiAgICAgICAgICAgICAgICAgICAgICAgIHJlcXVlc3QtPnN0YXR1cykpOwogICAgICAgIGlmIChyZXF1ZXN0LT5wYXJlbnRfZGF0YSkgewogICAgICAgICAgICBuZXRzbm1wX2RhdGFfbGlzdCAqbHN0OwogICAgICAgICAgICBERUJVR01TR1RMKCgiaGVscGVyOmRlYnVnIiwgIiAgICAgICAgW3BhcmVudCBkYXRhID0iKSk7CiAgICAgICAgICAgIGZvciAobHN0ID0gcmVxdWVzdC0+cGFyZW50X2RhdGE7IGxzdDsgbHN0ID0gbHN0LT5uZXh0KSB7CiAgICAgICAgICAgICAgICBERUJVR01TRygoImhlbHBlcjpkZWJ1ZyIsICIgJXMiLCBsc3QtPm5hbWUpKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBERUJVR01TRygoImhlbHBlcjpkZWJ1ZyIsICJdXG4iKSk7CiAgICAgICAgfQogICAgfQp9CgojZW5kaWYgLyogTkVUU05NUF9OT19ERUJVR0dJTkcgKi8KCi8qKiBAaW50ZXJuYWwgSW1wbGVtZW50cyB0aGUgZGVidWcgaGFuZGxlciAqLwppbnQKbmV0c25tcF9kZWJ1Z19oZWxwZXIobmV0c25tcF9taWJfaGFuZGxlciAqaGFuZGxlciwKICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9oYW5kbGVyX3JlZ2lzdHJhdGlvbiAqcmVnaW5mbywKICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9hZ2VudF9yZXF1ZXN0X2luZm8gKnJlcWluZm8sCiAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfcmVxdWVzdF9pbmZvICpyZXF1ZXN0cykKewogICAgaW50IHJldDsKCiAgICBERUJVR0lGKCJoZWxwZXI6ZGVidWciKSB7CiAgICAgICAgbmV0c25tcF9taWJfaGFuZGxlciAqaHB0cjsKICAgICAgICBjaGFyICAgICAgICAgICAgICAgICpjcDsKICAgICAgICBpbnQgICAgICAgICAgICAgICAgICBpLCBjb3VudDsKCiAgICAgICAgREVCVUdNU0dUTCgoImhlbHBlcjpkZWJ1ZyIsICJFbnRlcmluZyBEZWJ1Z2dpbmcgSGVscGVyOlxuIikpOwogICAgICAgIERFQlVHTVNHVEwoKCJoZWxwZXI6ZGVidWciLCAiICBIYW5kbGVyIFJlZ2lzdHJhdGlvbiBJbmZvOlxuIikpOwogICAgICAgIERFQlVHTVNHVEwoKCJoZWxwZXI6ZGVidWciLCAiICAgIE5hbWU6ICAgICAgICAlc1xuIiwKICAgICAgICAgICAgICAgICAgICByZWdpbmZvLT5oYW5kbGVyTmFtZSkpOwogICAgICAgIERFQlVHTVNHVEwoKCJoZWxwZXI6ZGVidWciLCAiICAgIENvbnRleHQ6ICAgICAlc1xuIiwKICAgICAgICAgICAgICAgICAgICBTTk1QX1NUUk9STlVMTChyZWdpbmZvLT5jb250ZXh0TmFtZSkpKTsKICAgICAgICBERUJVR01TR1RMKCgiaGVscGVyOmRlYnVnIiwgIiAgICBCYXNlIE9JRDogICAgIikpOwogICAgICAgIERFQlVHTVNHT0lEKCgiaGVscGVyOmRlYnVnIiwgcmVnaW5mby0+cm9vdG9pZCwgcmVnaW5mby0+cm9vdG9pZF9sZW4pKTsKICAgICAgICBERUJVR01TRygoImhlbHBlcjpkZWJ1ZyIsICJcbiIpKTsKCiAgICAgICAgREVCVUdNU0dUTCgoImhlbHBlcjpkZWJ1ZyIsICIgICAgTW9kZXM6ICAgICAgIDB4JXggPSAiLAogICAgICAgICAgICAgICAgICAgIHJlZ2luZm8tPm1vZGVzKSk7CiAgICAgICAgZm9yIChjb3VudCA9IDAsIGkgPSByZWdpbmZvLT5tb2RlczsgaTsgaSA9IGkgPj4gMSwgY291bnQrKykgewogICAgICAgICAgICBpZiAoaSAmIDB4MDEpIHsKICAgICAgICAgICAgICAgIGNwID0gc2VfZmluZF9sYWJlbF9pbl9zbGlzdCgiaGFuZGxlcl9jYW5fbW9kZSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMHgwMSA8PCBjb3VudCk7CiAgICAgICAgICAgICAgICBERUJVR01TRygoImhlbHBlcjpkZWJ1ZyIsICIlcyB8ICIsIFNOTVBfU1RST1JOVUxMKGNwKSkpOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIERFQlVHTVNHKCgiaGVscGVyOmRlYnVnIiwgIlxuIikpOwoKICAgICAgICBERUJVR01TR1RMKCgiaGVscGVyOmRlYnVnIiwgIiAgICBQcmlvcml0eTogICAgJWRcbiIsCiAgICAgICAgICAgICAgICAgICAgcmVnaW5mby0+cHJpb3JpdHkpKTsKCiAgICAgICAgREVCVUdNU0dUTCgoImhlbHBlcjpkZWJ1ZyIsICIgIEhhbmRsZXIgQ2FsbGluZyBDaGFpbjpcbiIpKTsKICAgICAgICBERUJVR01TR1RMKCgiaGVscGVyOmRlYnVnIiwgIiAgICIpKTsKICAgICAgICBmb3IgKGhwdHIgPSByZWdpbmZvLT5oYW5kbGVyOyBocHRyOyBocHRyID0gaHB0ci0+bmV4dCkgewogICAgICAgICAgICBERUJVR01TRygoImhlbHBlcjpkZWJ1ZyIsICIgLT4gJXMiLCBocHRyLT5oYW5kbGVyX25hbWUpKTsKICAgICAgICAgICAgaWYgKGhwdHItPm15dm9pZCkKICAgICAgICAgICAgICAgIERFQlVHTVNHKCgiaGVscGVyOmRlYnVnIiwgIiBbbXl2b2lkID0gJXBdIiwgaHB0ci0+bXl2b2lkKSk7CiAgICAgICAgfQogICAgICAgIERFQlVHTVNHKCgiaGVscGVyOmRlYnVnIiwgIlxuIikpOwoKICAgICAgICBERUJVR01TR1RMKCgiaGVscGVyOmRlYnVnIiwgIiAgUmVxdWVzdCBpbmZvcm1hdGlvbjpcbiIpKTsKICAgICAgICBERUJVR01TR1RMKCgiaGVscGVyOmRlYnVnIiwgIiAgICBNb2RlOiAgICAgICAgJXMgKCVkID0gMHgleClcbiIsCiAgICAgICAgICAgICAgICAgICAgc2VfZmluZF9sYWJlbF9pbl9zbGlzdCgiYWdlbnRfbW9kZSIsIHJlcWluZm8tPm1vZGUpLAogICAgICAgICAgICAgICAgICAgIHJlcWluZm8tPm1vZGUsIHJlcWluZm8tPm1vZGUpKTsKICAgICAgICBERUJVR01TR1RMKCgiaGVscGVyOmRlYnVnIiwgIiAgICBSZXF1ZXN0IFZhcmlhYmxlczpcbiIpKTsKICAgICAgICBkZWJ1Z19wcmludF9yZXF1ZXN0cyhyZXF1ZXN0cyk7CgogICAgICAgIERFQlVHTVNHVEwoKCJoZWxwZXI6ZGVidWciLCAiICAtLS0gY2FsbGluZyBuZXh0IGhhbmRsZXIgLS0tIFxuIikpOwogICAgfQoKICAgIHJldCA9IG5ldHNubXBfY2FsbF9uZXh0X2hhbmRsZXIoaGFuZGxlciwgcmVnaW5mbywgcmVxaW5mbywgcmVxdWVzdHMpOwoKICAgIERFQlVHSUYoImhlbHBlcjpkZWJ1ZyIpIHsKICAgICAgICBERUJVR01TR1RMKCgiaGVscGVyOmRlYnVnIiwgIiAgUmVzdWx0czpcbiIpKTsKICAgICAgICBERUJVR01TR1RMKCgiaGVscGVyOmRlYnVnIiwgIiAgICBSZXR1cm5lZCBjb2RlOiAlZFxuIiwgcmV0KSk7CiAgICAgICAgREVCVUdNU0dUTCgoImhlbHBlcjpkZWJ1ZyIsICIgICAgUmV0dXJuZWQgVmFyaWFibGVzOlxuIikpOwogICAgICAgIGRlYnVnX3ByaW50X3JlcXVlc3RzKHJlcXVlc3RzKTsKCiAgICAgICAgREVCVUdNU0dUTCgoImhlbHBlcjpkZWJ1ZyIsICJFeGl0aW5nIERlYnVnZ2luZyBIZWxwZXI6XG4iKSk7CiAgICB9CgogICAgcmV0dXJuIHJldDsKfQoKLyoqIGluaXRpYWxpemVzIHRoZSBkZWJ1ZyBoZWxwZXIgd2hpY2ggdGhlbiByZWdpc3RlcnMgYSBkZWJ1ZwogKiAgaGFuZGxlciBhcyBhIHJ1bi10aW1lIGluamVjdGFibGUgaGFuZGxlciBmb3IgY29uZmlndXJhdGlvbiBmaWxlCiAqICB1c2UuCiAqLwp2b2lkCm5ldHNubXBfaW5pdF9kZWJ1Z19oZWxwZXIodm9pZCkKewogICAgbmV0c25tcF9yZWdpc3Rlcl9oYW5kbGVyX2J5X25hbWUoImRlYnVnIiwgbmV0c25tcF9nZXRfZGVidWdfaGFuZGxlcigpKTsKfQovKiogIEB9ICovCg==