LyoKICogaXBjcm0uYyAtLSB1dGlsaXR5IHRvIGFsbG93IHJlbW92YWwgb2YgSVBDIG9iamVjdHMgYW5kIGRhdGEgc3RydWN0dXJlcy4KICoKICogMDEgU2VwdCAyMDA0IC0gUm9kbmV5IFJhZGZvcmQgPHJyYWRmb3JkQG1pbmRzcHJpbmcuY29tPgogKiBBZGFwdGVkIGZvciBidXN5Ym94IGZyb20gdXRpbC1saW51eC0yLjEyYS4KICoKICogVGhpcyBwcm9ncmFtIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkKICogaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkKICogdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyIHZlcnNpb24gMiBvZiB0aGUgTGljZW5zZSwgb3IKICogKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KICoKICogVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gU2VlIHRoZSBHTlUKICogR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiBhbG9uZyB3aXRoIHRoaXMgcHJvZ3JhbTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQogKiBGb3VuZGF0aW9uLCBJbmMuLCA1OSBUZW1wbGUgUGxhY2UsIFN1aXRlIDMzMCwgQm9zdG9uLCBNQSAwMjExMS0xMzA3IFVTQQogKgogKiAtLS0gUHJlLWJ1c3lib3ggaGlzdG9yeSBmcm9tIHV0aWwtbGludXgtMi4xMmEgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAqCiAqIDE5OTktMDQtMDIgZnJhbmsgemFnbwogKiAtIGNhbiBub3cgcmVtb3ZlIHNldmVyYWwgaWQncyBpbiB0aGUgc2FtZSBjYWxsCiAqCiAqIDE5OTktMDItMjIgQXJrYWRpdXN6IE1p/2tpZXdpY3ogPG1pc2lla0BwbGQuT1JHLlBMPgogKiAtIGFkZGVkIE5hdGl2ZSBMYW5ndWFnZSBTdXBwb3J0CiAqCiAqIE9yaWdpbmFsIGF1dGhvciAtIGtyaXNobmEgYmFsYXN1YnJhbWFuaWFuIDE5OTMKICovCgojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlIDxlcnJuby5oPgoKI2luY2x1ZGUgPHN5cy90eXBlcy5oPgojaW5jbHVkZSA8c3lzL2lwYy5oPgojaW5jbHVkZSA8c3lzL3NobS5oPgojaW5jbHVkZSA8c3lzL21zZy5oPgojaW5jbHVkZSA8c3lzL3NlbS5oPgoKLyogWC9PUEVOIHRlbGxzIHVzIHRvIHVzZSA8c3lzL3t0eXBlcyxpcGMsc2VtfS5oPiBmb3Igc2VtY3RsKCkgKi8KLyogWC9PUEVOIHRlbGxzIHVzIHRvIHVzZSA8c3lzL3t0eXBlcyxpcGMsbXNnfS5oPiBmb3IgbXNnY3RsKCkgKi8KLyogZm9yIGdldG9wdCAqLwojaW5jbHVkZSA8dW5pc3RkLmg+CgovKiBmb3IgdG9sb3dlciBhbmQgaXN1cHBlciAqLwojaW5jbHVkZSA8Y3R5cGUuaD4KCiNpbmNsdWRlICJidXN5Ym94LmgiCgojaWYgZGVmaW5lZCAoX19HTlVfTElCUkFSWV9fKSAmJiAhZGVmaW5lZChfU0VNX1NFTVVOX1VOREVGSU5FRCkKLyogdW5pb24gc2VtdW4gaXMgZGVmaW5lZCBieSBpbmNsdWRpbmcgPHN5cy9zZW0uaD4gKi8KI2Vsc2UKLyogYWNjb3JkaW5nIHRvIFgvT1BFTiB3ZSBoYXZlIHRvIGRlZmluZSBpdCBvdXJzZWx2ZXMgKi8KdW5pb24gc2VtdW4gewoJaW50IHZhbDsKCXN0cnVjdCBzZW1pZF9kcyAqYnVmOwoJdW5zaWduZWQgc2hvcnQgaW50ICphcnJheTsKCXN0cnVjdCBzZW1pbmZvICpfX2J1ZjsKfTsKI2VuZGlmCgp0eXBlZGVmIGVudW0gdHlwZV9pZCB7CglTSE0sCglTRU0sCglNU0cKfSB0eXBlX2lkOwoKc3RhdGljIGludApyZW1vdmVfaWRzKHR5cGVfaWQgdHlwZSwgaW50IGFyZ2MsIGNoYXIgKiphcmd2KSB7CglpbnQgaWQ7CglpbnQgcmV0ID0gMDsJCS8qIGZvciBnY2MgKi8KCWNoYXIgKmVuZDsKCWludCBuYl9lcnJvcnMgPSAwOwoJdW5pb24gc2VtdW4gYXJnOwoKCWFyZy52YWwgPSAwOwoKCXdoaWxlKGFyZ2MpIHsKCgkJaWQgPSBzdHJ0b3VsKGFyZ3ZbMF0sICZlbmQsIDEwKTsKCgkJaWYgKCplbmQgIT0gMCkgewoJCQliYl9wcmludGYgKCJpbnZhbGlkIGlkOiAlc1xuIiwgYXJndlswXSk7CgkJCW5iX2Vycm9ycyArKzsKCQl9IGVsc2UgewoJCQlzd2l0Y2godHlwZSkgewoJCQljYXNlIFNFTToKCQkJCXJldCA9IHNlbWN0bCAoaWQsIDAsIElQQ19STUlELCBhcmcpOwoJCQkJYnJlYWs7CgoJCQljYXNlIE1TRzoKCQkJCXJldCA9IG1zZ2N0bCAoaWQsIElQQ19STUlELCBOVUxMKTsKCQkJCWJyZWFrOwoKCQkJY2FzZSBTSE06CgkJCQlyZXQgPSBzaG1jdGwgKGlkLCBJUENfUk1JRCwgTlVMTCk7CgkJCQlicmVhazsKCQkJfQoKCQkJaWYgKHJldCkgewoJCQkJYmJfcHJpbnRmICgiY2Fubm90IHJlbW92ZSBpZCAlcyAoJXMpXG4iLAoJCQkJCWFyZ3ZbMF0sIHN0cmVycm9yKGVycm5vKSk7CgkJCQluYl9lcnJvcnMgKys7CgkJCX0KCQl9CgkJYXJnYy0tOwoJCWFyZ3YrKzsKCX0KCglyZXR1cm4obmJfZXJyb3JzKTsKfQoKc3RhdGljIGludCBkZXByZWNhdGVkX21haW4oaW50IGFyZ2MsIGNoYXIgKiphcmd2KQp7CglpZiAoYXJnYyA8IDMpIHsKCQliYl9zaG93X3VzYWdlKCk7CgkJYmJfZmZsdXNoX3N0ZG91dF9hbmRfZXhpdCgxKTsKCX0KCglpZiAoIXN0cmNtcChhcmd2WzFdLCAic2htIikpIHsKCQlpZiAocmVtb3ZlX2lkcyhTSE0sIGFyZ2MtMiwgJmFyZ3ZbMl0pKQoJCQliYl9mZmx1c2hfc3Rkb3V0X2FuZF9leGl0KDEpOwoJfQoJZWxzZSBpZiAoIXN0cmNtcChhcmd2WzFdLCAibXNnIikpIHsKCQlpZiAocmVtb3ZlX2lkcyhNU0csIGFyZ2MtMiwgJmFyZ3ZbMl0pKQoJCQliYl9mZmx1c2hfc3Rkb3V0X2FuZF9leGl0KDEpOwoJfQoJZWxzZSBpZiAoIXN0cmNtcChhcmd2WzFdLCAic2VtIikpIHsKCQlpZiAocmVtb3ZlX2lkcyhTRU0sIGFyZ2MtMiwgJmFyZ3ZbMl0pKQoJCQliYl9mZmx1c2hfc3Rkb3V0X2FuZF9leGl0KDEpOwoJfQoJZWxzZSB7CgkJYmJfcHJpbnRmICgidW5rbm93biByZXNvdXJjZSB0eXBlOiAlc1xuIiwgYXJndlsxXSk7CgkJYmJfc2hvd191c2FnZSgpOwoJCWJiX2ZmbHVzaF9zdGRvdXRfYW5kX2V4aXQoMSk7Cgl9CgoJYmJfcHJpbnRmICgicmVzb3VyY2UocykgZGVsZXRlZFxuIik7CglyZXR1cm4gMDsKfQoKCmludCBpcGNybV9tYWluKGludCBhcmdjLCBjaGFyICoqYXJndikKewoJaW50ICAgYzsKCWludCAgIGVycm9yID0gMDsKCWNoYXIgKnByb2cgPSBhcmd2WzBdOwoKCS8qIGlmIHRoZSBjb21tYW5kIGlzIGV4ZWN1dGVkIHdpdGhvdXQgcGFyYW1ldGVycywgZG8gbm90aGluZyAqLwoJaWYgKGFyZ2MgPT0gMSkKCQlyZXR1cm4gMDsKCgkvKiBjaGVjayB0byBzZWUgaWYgdGhlIGNvbW1hbmQgaXMgYmVpbmcgaW52b2tlZCBpbiB0aGUgb2xkIHdheSBpZiBzbwoJICAgdGhlbiBydW4gdGhlIG9sZCBjb2RlICovCglpZiAoc3RyY21wKGFyZ3ZbMV0sICJzaG0iKSA9PSAwIHx8CgkJc3RyY21wKGFyZ3ZbMV0sICJtc2ciKSA9PSAwIHx8CgkJc3RyY21wKGFyZ3ZbMV0sICJzZW0iKSA9PSAwKQoJCXJldHVybiBkZXByZWNhdGVkX21haW4oYXJnYywgYXJndik7CgoJLyogcHJvY2VzcyBuZXcgc3ludGF4IHRvIGNvbmZvcm0gd2l0aCBTWVNWIGlwY3JtICovCgl3aGlsZSAoKGMgPSBnZXRvcHQoYXJnYywgYXJndiwgInE6bTpzOlE6TTpTOmg/IikpICE9IC0xKSB7CgkJaW50IHJlc3VsdDsKCQlpbnQgaWQgPSAwOwoJCWludCBpc2tleSA9IGlzdXBwZXIoYyk7CgoJCS8qIG5lZWRlZCB0byBkZWxldGUgc2VtYXBob3JlcyAqLwoJCXVuaW9uIHNlbXVuIGFyZzsKCQlhcmcudmFsID0gMDsKCgkJaWYgKChjID09ICc/JykgfHwgKGMgPT0gJ2gnKSkKCQl7CgkJCWJiX3Nob3dfdXNhZ2UoKTsKCQkJcmV0dXJuIDA7CgkJfQoKCQkvKiB3ZSBkb24ndCBuZWVkIGNhc2UgaW5mb3JtYXRpb24gYW55IG1vcmUgKi8KCQljID0gdG9sb3dlcihjKTsKCgkJLyogbWFrZSBzdXJlIHRoZSBvcHRpb24gaXMgaW4gcmFuZ2UgKi8KCQlpZiAoYyAhPSAncScgJiYgYyAhPSAnbScgJiYgYyAhPSAncycpIHsKCQkJYmJfc2hvd191c2FnZSgpOwoJCQllcnJvcisrOwoJCQlyZXR1cm4gZXJyb3I7CgkJfQoKCQlpZiAoaXNrZXkpIHsKCQkJLyoga2V5cyBhcmUgaW4gaGV4IG9yIGRlY2ltYWwgKi8KCQkJa2V5X3Qga2V5ID0gc3RydG91bChvcHRhcmcsIE5VTEwsIDApOwoJCQlpZiAoa2V5ID09IElQQ19QUklWQVRFKSB7CgkJCQllcnJvcisrOwoJCQkJYmJfZnByaW50ZihzdGRlcnIsICIlczogaWxsZWdhbCBrZXkgKCVzKVxuIiwKCQkJCQlwcm9nLCBvcHRhcmcpOwoJCQkJY29udGludWU7CgkJCX0KCgkJCS8qIGNvbnZlcnQga2V5IHRvIGlkICovCgkJCWlkID0gKChjID09ICdxJykgPyBtc2dnZXQoa2V5LCAwKSA6CgkJCQkgIChjID09ICdtJykgPyBzaG1nZXQoa2V5LCAwLCAwKSA6CgkJCQkgIHNlbWdldChrZXksIDAsIDApKTsKCgkJCWlmIChpZCA8IDApIHsKCQkJCWNoYXIgKmVycm1zZzsKCQkJCWVycm9yKys7CgkJCQlzd2l0Y2goZXJybm8pIHsKCQkJCWNhc2UgRUFDQ0VTOgoJCQkJCWVycm1zZyA9ICJwZXJtaXNzaW9uIGRlbmllZCBmb3Iga2V5IjsKCQkJCQlicmVhazsKCQkJCWNhc2UgRUlEUk06CgkJCQkJZXJybXNnID0gImFscmVhZHkgcmVtb3ZlZCBrZXkiOwoJCQkJCWJyZWFrOwoJCQkJY2FzZSBFTk9FTlQ6CgkJCQkJZXJybXNnID0gImludmFsaWQga2V5IjsKCQkJCQlicmVhazsKCQkJCWRlZmF1bHQ6CgkJCQkJZXJybXNnID0gInVua25vd24gZXJyb3IgaW4ga2V5IjsKCQkJCQlicmVhazsKCQkJCX0KCQkJCWJiX2ZwcmludGYoc3RkZXJyLCAiJXM6ICVzICglcylcbiIsCgkJCQkJcHJvZywgZXJybXNnLCBvcHRhcmcpOwoJCQkJY29udGludWU7CgkJCX0KCQl9IGVsc2UgewoJCQkvKiBpZHMgYXJlIGluIGRlY2ltYWwgKi8KCQkJaWQgPSBzdHJ0b3VsKG9wdGFyZywgTlVMTCwgMTApOwoJCX0KCgkJcmVzdWx0ID0gKChjID09ICdxJykgPyBtc2djdGwoaWQsIElQQ19STUlELCBOVUxMKSA6CgkJCSAgKGMgPT0gJ20nKSA/IHNobWN0bChpZCwgSVBDX1JNSUQsIE5VTEwpIDoKCQkJICBzZW1jdGwoaWQsIDAsIElQQ19STUlELCBhcmcpKTsKCgkJaWYgKHJlc3VsdCA8IDApIHsKCQkJY2hhciAqZXJybXNnOwoJCQllcnJvcisrOwoJCQlzd2l0Y2goZXJybm8pIHsKCQkJY2FzZSBFQUNDRVM6CgkJCWNhc2UgRVBFUk06CgkJCQllcnJtc2cgPSBpc2tleQoJCQkJCT8gInBlcm1pc3Npb24gZGVuaWVkIGZvciBrZXkiCgkJCQkJOiAicGVybWlzc2lvbiBkZW5pZWQgZm9yIGlkIjsKCQkJCWJyZWFrOwoJCQljYXNlIEVJTlZBTDoKCQkJCWVycm1zZyA9IGlza2V5CgkJCQkJPyAiaW52YWxpZCBrZXkiCgkJCQkJOiAiaW52YWxpZCBpZCI7CgkJCQlicmVhazsKCQkJY2FzZSBFSURSTToKCQkJCWVycm1zZyA9IGlza2V5CgkJCQkJPyAiYWxyZWFkeSByZW1vdmVkIGtleSIKCQkJCQk6ICJhbHJlYWR5IHJlbW92ZWQgaWQiOwoJCQkJYnJlYWs7CgkJCWRlZmF1bHQ6CgkJCQllcnJtc2cgPSBpc2tleQoJCQkJCT8gInVua25vd24gZXJyb3IgaW4ga2V5IgoJCQkJCTogInVua25vd24gZXJyb3IgaW4gaWQiOwoJCQkJYnJlYWs7CgkJCX0KCQkJYmJfZnByaW50ZihzdGRlcnIsICIlczogJXMgKCVzKVxuIiwKCQkJCXByb2csIGVycm1zZywgb3B0YXJnKTsKCQkJY29udGludWU7CgkJfQoJfQoKCS8qIHByaW50IHVzYWdlIGlmIHdlIHN0aWxsIGhhdmUgc29tZSBhcmd1bWVudHMgbGVmdCBvdmVyICovCglpZiAob3B0aW5kICE9IGFyZ2MpIHsKCQliYl9zaG93X3VzYWdlKCk7Cgl9CgoJLyogZXhpdCB2YWx1ZSByZWZsZWN0cyB0aGUgbnVtYmVyIG9mIGVycm9ycyBlbmNvdW50ZXJlZCAqLwoJcmV0dXJuIGVycm9yOwp9Cg==