LyoKICogaXBjcm0uYyAtLSB1dGlsaXR5IHRvIGFsbG93IHJlbW92YWwgb2YgSVBDIG9iamVjdHMgYW5kIGRhdGEgc3RydWN0dXJlcy4KICoKICogMDEgU2VwdCAyMDA0IC0gUm9kbmV5IFJhZGZvcmQgPHJyYWRmb3JkQG1pbmRzcHJpbmcuY29tPgogKiBBZGFwdGVkIGZvciBidXN5Ym94IGZyb20gdXRpbC1saW51eC0yLjEyYS4KICoKICogVGhpcyBwcm9ncmFtIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkKICogaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkKICogdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyIHZlcnNpb24gMiBvZiB0aGUgTGljZW5zZSwgb3IKICogKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KICoKICogVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mCiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gU2VlIHRoZSBHTlUKICogR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiBhbG9uZyB3aXRoIHRoaXMgcHJvZ3JhbTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQogKiBGb3VuZGF0aW9uLCBJbmMuLCA1OSBUZW1wbGUgUGxhY2UsIFN1aXRlIDMzMCwgQm9zdG9uLCBNQSAwMjExMS0xMzA3IFVTQQogKgogKiAtLS0gUHJlLWJ1c3lib3ggaGlzdG9yeSBmcm9tIHV0aWwtbGludXgtMi4xMmEgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAqCiAqIDE5OTktMDQtMDIgZnJhbmsgemFnbwogKiAtIGNhbiBub3cgcmVtb3ZlIHNldmVyYWwgaWQncyBpbiB0aGUgc2FtZSBjYWxsCiAqCiAqIDE5OTktMDItMjIgQXJrYWRpdXN6IE1p/2tpZXdpY3ogPG1pc2lla0BwbGQuT1JHLlBMPgogKiAtIGFkZGVkIE5hdGl2ZSBMYW5ndWFnZSBTdXBwb3J0CiAqCiAqIE9yaWdpbmFsIGF1dGhvciAtIGtyaXNobmEgYmFsYXN1YnJhbWFuaWFuIDE5OTMKICovCgojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlIDxlcnJuby5oPgoKI2luY2x1ZGUgPHN5cy90eXBlcy5oPgojaW5jbHVkZSA8c3lzL2lwYy5oPgojaW5jbHVkZSA8c3lzL3NobS5oPgojaW5jbHVkZSA8c3lzL21zZy5oPgojaW5jbHVkZSA8c3lzL3NlbS5oPgoKLyogWC9PUEVOIHRlbGxzIHVzIHRvIHVzZSA8c3lzL3t0eXBlcyxpcGMsc2VtfS5oPiBmb3Igc2VtY3RsKCkgKi8KLyogWC9PUEVOIHRlbGxzIHVzIHRvIHVzZSA8c3lzL3t0eXBlcyxpcGMsbXNnfS5oPiBmb3IgbXNnY3RsKCkgKi8KLyogZm9yIGdldG9wdCAqLwojaW5jbHVkZSA8dW5pc3RkLmg+CgovKiBmb3IgdG9sb3dlciBhbmQgaXN1cHBlciAqLwojaW5jbHVkZSA8Y3R5cGUuaD4KCiNpbmNsdWRlICJidXN5Ym94LmgiCgojaWYgZGVmaW5lZCAoX19HTlVfTElCUkFSWV9fKSAmJiAhZGVmaW5lZChfU0VNX1NFTVVOX1VOREVGSU5FRCkKLyogdW5pb24gc2VtdW4gaXMgZGVmaW5lZCBieSBpbmNsdWRpbmcgPHN5cy9zZW0uaD4gKi8KI2Vsc2UKLyogYWNjb3JkaW5nIHRvIFgvT1BFTiB3ZSBoYXZlIHRvIGRlZmluZSBpdCBvdXJzZWx2ZXMgKi8KdW5pb24gc2VtdW4gewoJaW50IHZhbDsKCXN0cnVjdCBzZW1pZF9kcyAqYnVmOwoJdW5zaWduZWQgc2hvcnQgaW50ICphcnJheTsKCXN0cnVjdCBzZW1pbmZvICpfX2J1ZjsKfTsKI2VuZGlmCgp0eXBlZGVmIGVudW0gdHlwZV9pZCB7CglTSE0sCglTRU0sCglNU0cKfSB0eXBlX2lkOwoKc3RhdGljIGludApyZW1vdmVfaWRzKHR5cGVfaWQgdHlwZSwgaW50IGFyZ2MsIGNoYXIgKiphcmd2KSB7CglpbnQgaWQ7CglpbnQgcmV0ID0gMDsJCS8qIGZvciBnY2MgKi8KCWNoYXIgKmVuZDsKCWludCBuYl9lcnJvcnMgPSAwOwoJdW5pb24gc2VtdW4gYXJnOwoKCWFyZy52YWwgPSAwOwoKCXdoaWxlKGFyZ2MpIHsKCgkJaWQgPSBzdHJ0b3VsKGFyZ3ZbMF0sICZlbmQsIDEwKTsKCgkJaWYgKCplbmQgIT0gMCkgewoJCQliYl9wcmludGYgKCJpbnZhbGlkIGlkOiAlc1xuIiwgYXJndlswXSk7CgkJCW5iX2Vycm9ycyArKzsKCQl9IGVsc2UgewoJCQlzd2l0Y2godHlwZSkgewoJCQljYXNlIFNFTToKCQkJCXJldCA9IHNlbWN0bCAoaWQsIDAsIElQQ19STUlELCBhcmcpOwoJCQkJYnJlYWs7CgoJCQljYXNlIE1TRzoKCQkJCXJldCA9IG1zZ2N0bCAoaWQsIElQQ19STUlELCBOVUxMKTsKCQkJCWJyZWFrOwoJCQkJCgkJCWNhc2UgU0hNOgoJCQkJcmV0ID0gc2htY3RsIChpZCwgSVBDX1JNSUQsIE5VTEwpOwoJCQkJYnJlYWs7CgkJCX0KCgkJCWlmIChyZXQpIHsKCQkJCWJiX3ByaW50ZiAoImNhbm5vdCByZW1vdmUgaWQgJXMgKCVzKVxuIiwKCQkJCQlhcmd2WzBdLCBzdHJlcnJvcihlcnJubykpOwoJCQkJbmJfZXJyb3JzICsrOwoJCQl9CgkJfQoJCWFyZ2MtLTsKCQlhcmd2Kys7Cgl9CgkKCXJldHVybihuYl9lcnJvcnMpOwp9CgpzdGF0aWMgaW50IGRlcHJlY2F0ZWRfbWFpbihpbnQgYXJnYywgY2hhciAqKmFyZ3YpCnsKCWlmIChhcmdjIDwgMykgewoJCWJiX3Nob3dfdXNhZ2UoKTsKCQliYl9mZmx1c2hfc3Rkb3V0X2FuZF9leGl0KDEpOwoJfQoJCglpZiAoIXN0cmNtcChhcmd2WzFdLCAic2htIikpIHsKCQlpZiAocmVtb3ZlX2lkcyhTSE0sIGFyZ2MtMiwgJmFyZ3ZbMl0pKQoJCQliYl9mZmx1c2hfc3Rkb3V0X2FuZF9leGl0KDEpOwoJfQoJZWxzZSBpZiAoIXN0cmNtcChhcmd2WzFdLCAibXNnIikpIHsKCQlpZiAocmVtb3ZlX2lkcyhNU0csIGFyZ2MtMiwgJmFyZ3ZbMl0pKQoJCQliYl9mZmx1c2hfc3Rkb3V0X2FuZF9leGl0KDEpOwoJfSAKCWVsc2UgaWYgKCFzdHJjbXAoYXJndlsxXSwgInNlbSIpKSB7CgkJaWYgKHJlbW92ZV9pZHMoU0VNLCBhcmdjLTIsICZhcmd2WzJdKSkKCQkJYmJfZmZsdXNoX3N0ZG91dF9hbmRfZXhpdCgxKTsKCX0KCWVsc2UgewoJCWJiX3ByaW50ZiAoInVua25vd24gcmVzb3VyY2UgdHlwZTogJXNcbiIsIGFyZ3ZbMV0pOwoJCWJiX3Nob3dfdXNhZ2UoKTsKCQliYl9mZmx1c2hfc3Rkb3V0X2FuZF9leGl0KDEpOwoJfQoKCWJiX3ByaW50ZiAoInJlc291cmNlKHMpIGRlbGV0ZWRcbiIpOwoJcmV0dXJuIDA7Cn0KCgppbnQgaXBjcm1fbWFpbihpbnQgYXJnYywgY2hhciAqKmFyZ3YpCnsKCWludCAgIGM7CglpbnQgICBlcnJvciA9IDA7CgljaGFyICpwcm9nID0gYXJndlswXTsKCgkvKiBpZiB0aGUgY29tbWFuZCBpcyBleGVjdXRlZCB3aXRob3V0IHBhcmFtZXRlcnMsIGRvIG5vdGhpbmcgKi8KCWlmIChhcmdjID09IDEpCgkJcmV0dXJuIDA7CgoJLyogY2hlY2sgdG8gc2VlIGlmIHRoZSBjb21tYW5kIGlzIGJlaW5nIGludm9rZWQgaW4gdGhlIG9sZCB3YXkgaWYgc28KCSAgIHRoZW4gcnVuIHRoZSBvbGQgY29kZSAqLwoJaWYgKHN0cmNtcChhcmd2WzFdLCAic2htIikgPT0gMCB8fAoJCXN0cmNtcChhcmd2WzFdLCAibXNnIikgPT0gMCB8fAoJCXN0cmNtcChhcmd2WzFdLCAic2VtIikgPT0gMCkKCQlyZXR1cm4gZGVwcmVjYXRlZF9tYWluKGFyZ2MsIGFyZ3YpOwoKCS8qIHByb2Nlc3MgbmV3IHN5bnRheCB0byBjb25mb3JtIHdpdGggU1lTViBpcGNybSAqLwoJd2hpbGUgKChjID0gZ2V0b3B0KGFyZ2MsIGFyZ3YsICJxOm06czpROk06UzpoPyIpKSAhPSAtMSkgewoJCWludCByZXN1bHQ7CgkJaW50IGlkID0gMDsKCQlpbnQgaXNrZXkgPSBpc3VwcGVyKGMpOwoKCQkvKiBuZWVkZWQgdG8gZGVsZXRlIHNlbWFwaG9yZXMgKi8KCQl1bmlvbiBzZW11biBhcmc7CgkJYXJnLnZhbCA9IDA7CgoJCWlmICgoYyA9PSAnPycpIHx8IChjID09ICdoJykpCgkJewoJCQliYl9zaG93X3VzYWdlKCk7CgkJCXJldHVybiAwOwoJCX0KCgkJLyogd2UgZG9uJ3QgbmVlZCBjYXNlIGluZm9ybWF0aW9uIGFueSBtb3JlICovCgkJYyA9IHRvbG93ZXIoYyk7CgoJCS8qIG1ha2Ugc3VyZSB0aGUgb3B0aW9uIGlzIGluIHJhbmdlICovCgkJaWYgKGMgIT0gJ3EnICYmIGMgIT0gJ20nICYmIGMgIT0gJ3MnKSB7CgkJCWJiX3Nob3dfdXNhZ2UoKTsKCQkJZXJyb3IrKzsKCQkJcmV0dXJuIGVycm9yOwoJCX0KCgkJaWYgKGlza2V5KSB7CgkJCS8qIGtleXMgYXJlIGluIGhleCBvciBkZWNpbWFsICovCgkJCWtleV90IGtleSA9IHN0cnRvdWwob3B0YXJnLCBOVUxMLCAwKTsKCQkJaWYgKGtleSA9PSBJUENfUFJJVkFURSkgewoJCQkJZXJyb3IrKzsKCQkJCWJiX2ZwcmludGYoc3RkZXJyLCAiJXM6IGlsbGVnYWwga2V5ICglcylcbiIsCgkJCQkJcHJvZywgb3B0YXJnKTsKCQkJCWNvbnRpbnVlOwoJCQl9CgoJCQkvKiBjb252ZXJ0IGtleSB0byBpZCAqLwoJCQlpZCA9ICgoYyA9PSAncScpID8gbXNnZ2V0KGtleSwgMCkgOgoJCQkJICAoYyA9PSAnbScpID8gc2htZ2V0KGtleSwgMCwgMCkgOgoJCQkJICBzZW1nZXQoa2V5LCAwLCAwKSk7CgoJCQlpZiAoaWQgPCAwKSB7CgkJCQljaGFyICplcnJtc2c7CgkJCQllcnJvcisrOwoJCQkJc3dpdGNoKGVycm5vKSB7CgkJCQljYXNlIEVBQ0NFUzoKCQkJCQllcnJtc2cgPSAicGVybWlzc2lvbiBkZW5pZWQgZm9yIGtleSI7CgkJCQkJYnJlYWs7CgkJCQljYXNlIEVJRFJNOgoJCQkJCWVycm1zZyA9ICJhbHJlYWR5IHJlbW92ZWQga2V5IjsKCQkJCQlicmVhazsKCQkJCWNhc2UgRU5PRU5UOgoJCQkJCWVycm1zZyA9ICJpbnZhbGlkIGtleSI7CgkJCQkJYnJlYWs7CgkJCQlkZWZhdWx0OgoJCQkJCWVycm1zZyA9ICJ1bmtub3duIGVycm9yIGluIGtleSI7CgkJCQkJYnJlYWs7CgkJCQl9CgkJCQliYl9mcHJpbnRmKHN0ZGVyciwgIiVzOiAlcyAoJXMpXG4iLAoJCQkJCXByb2csIGVycm1zZywgb3B0YXJnKTsKCQkJCWNvbnRpbnVlOwoJCQl9CgkJfSBlbHNlIHsKCQkJLyogaWRzIGFyZSBpbiBkZWNpbWFsICovCgkJCWlkID0gc3RydG91bChvcHRhcmcsIE5VTEwsIDEwKTsKCQl9CgoJCXJlc3VsdCA9ICgoYyA9PSAncScpID8gbXNnY3RsKGlkLCBJUENfUk1JRCwgTlVMTCkgOgoJCQkgIChjID09ICdtJykgPyBzaG1jdGwoaWQsIElQQ19STUlELCBOVUxMKSA6IAoJCQkgIHNlbWN0bChpZCwgMCwgSVBDX1JNSUQsIGFyZykpOwoKCQlpZiAocmVzdWx0IDwgMCkgewoJCQljaGFyICplcnJtc2c7CgkJCWVycm9yKys7CgkJCXN3aXRjaChlcnJubykgewoJCQljYXNlIEVBQ0NFUzoKCQkJY2FzZSBFUEVSTToKCQkJCWVycm1zZyA9IGlza2V5CgkJCQkJPyAicGVybWlzc2lvbiBkZW5pZWQgZm9yIGtleSIKCQkJCQk6ICJwZXJtaXNzaW9uIGRlbmllZCBmb3IgaWQiOwoJCQkJYnJlYWs7CgkJCWNhc2UgRUlOVkFMOgoJCQkJZXJybXNnID0gaXNrZXkKCQkJCQk/ICJpbnZhbGlkIGtleSIKCQkJCQk6ICJpbnZhbGlkIGlkIjsKCQkJCWJyZWFrOwoJCQljYXNlIEVJRFJNOgoJCQkJZXJybXNnID0gaXNrZXkKCQkJCQk/ICJhbHJlYWR5IHJlbW92ZWQga2V5IgoJCQkJCTogImFscmVhZHkgcmVtb3ZlZCBpZCI7CgkJCQlicmVhazsKCQkJZGVmYXVsdDoKCQkJCWVycm1zZyA9IGlza2V5CgkJCQkJPyAidW5rbm93biBlcnJvciBpbiBrZXkiCgkJCQkJOiAidW5rbm93biBlcnJvciBpbiBpZCI7CgkJCQlicmVhazsKCQkJfQoJCQliYl9mcHJpbnRmKHN0ZGVyciwgIiVzOiAlcyAoJXMpXG4iLAoJCQkJcHJvZywgZXJybXNnLCBvcHRhcmcpOwoJCQljb250aW51ZTsKCQl9Cgl9CgoJLyogcHJpbnQgdXNhZ2UgaWYgd2Ugc3RpbGwgaGF2ZSBzb21lIGFyZ3VtZW50cyBsZWZ0IG92ZXIgKi8KCWlmIChvcHRpbmQgIT0gYXJnYykgewoJCWJiX3Nob3dfdXNhZ2UoKTsKCX0KCgkvKiBleGl0IHZhbHVlIHJlZmxlY3RzIHRoZSBudW1iZXIgb2YgZXJyb3JzIGVuY291bnRlcmVkICovCglyZXR1cm4gZXJyb3I7Cn0K