LyoKICoga3Jpc2huYSBiYWxhc3VicmFtYW5pYW4gMTk5MwogKgogKiAxOTk5LTAyLTIyIEFya2FkaXVzeiBNabZraWV3aWN6IDxtaXNpZWtAcGxkLk9SRy5QTD4KICogLSBhZGRlZCBOYXRpdmUgTGFuZ3VhZ2UgU3VwcG9ydAogKgogKiAxOTk5LTA0LTAyIGZyYW5rIHphZ28KICogLSBjYW4gbm93IHJlbW92ZSBzZXZlcmFsIGlkJ3MgaW4gdGhlIHNhbWUgY2FsbAogKgogKi8KCiNpbmNsdWRlIDxzdGRpby5oPgojaW5jbHVkZSA8c3RkbGliLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUgPGVycm5vLmg+CgojaW5jbHVkZSA8c3lzL3R5cGVzLmg+CiNpbmNsdWRlIDxzeXMvaXBjLmg+CiNpbmNsdWRlIDxzeXMvc2htLmg+CiNpbmNsdWRlIDxzeXMvbXNnLmg+CiNpbmNsdWRlIDxzeXMvc2VtLmg+CiNpbmNsdWRlICJubHMuaCIKCi8qIGZvciBnZXRvcHQgKi8KI2luY2x1ZGUgPHVuaXN0ZC5oPgovKiBmb3IgdG9sb3dlciBhbmQgaXN1cHBlciAqLwojaW5jbHVkZSA8Y3R5cGUuaD4KCiNpZm5kZWYgSEFWRV9VTklPTl9TRU1VTgovKiBhY2NvcmRpbmcgdG8gWC9PUEVOIHdlIGhhdmUgdG8gZGVmaW5lIGl0IG91cnNlbHZlcyAqLwp1bmlvbiBzZW11biB7CglpbnQgdmFsOwoJc3RydWN0IHNlbWlkX2RzICpidWY7Cgl1bnNpZ25lZCBzaG9ydCBpbnQgKmFycmF5OwoJc3RydWN0IHNlbWluZm8gKl9fYnVmOwp9OwojZW5kaWYKCnN0YXRpYyB2b2lkIHVzYWdlKGNoYXIgKik7CgpjaGFyICpleGVjbmFtZTsKCnR5cGVkZWYgZW51bSB0eXBlX2lkIHsKCVNITSwKCVNFTSwKCU1TRwp9IHR5cGVfaWQ7CgpzdGF0aWMgaW50CnJlbW92ZV9pZHModHlwZV9pZCB0eXBlLCBpbnQgYXJnYywgY2hhciAqKmFyZ3YpIHsKCWludCBpZDsKCWludCByZXQgPSAwOwkJLyogZm9yIGdjYyAqLwoJY2hhciAqZW5kOwoJaW50IG5iX2Vycm9ycyA9IDA7Cgl1bmlvbiBzZW11biBhcmc7CgoJYXJnLnZhbCA9IDA7CgoJd2hpbGUoYXJnYykgewoKCQlpZCA9IHN0cnRvdWwoYXJndlswXSwgJmVuZCwgMTApOwoKCQlpZiAoKmVuZCAhPSAwKSB7CgkJCXByaW50ZiAoXygiaW52YWxpZCBpZDogJXNcbiIpLCBhcmd2WzBdKTsKCQkJbmJfZXJyb3JzICsrOwoJCX0gZWxzZSB7CgkJCXN3aXRjaCh0eXBlKSB7CgkJCWNhc2UgU0VNOgoJCQkJcmV0ID0gc2VtY3RsIChpZCwgMCwgSVBDX1JNSUQsIGFyZyk7CgkJCQlicmVhazsKCgkJCWNhc2UgTVNHOgoJCQkJcmV0ID0gbXNnY3RsIChpZCwgSVBDX1JNSUQsIE5VTEwpOwoJCQkJYnJlYWs7CgkJCQkKCQkJY2FzZSBTSE06CgkJCQlyZXQgPSBzaG1jdGwgKGlkLCBJUENfUk1JRCwgTlVMTCk7CgkJCQlicmVhazsKCQkJfQoKCQkJaWYgKHJldCkgewoJCQkJcHJpbnRmIChfKCJjYW5ub3QgcmVtb3ZlIGlkICVzICglcylcbiIpLAoJCQkJCWFyZ3ZbMF0sIHN0cmVycm9yKGVycm5vKSk7CgkJCQluYl9lcnJvcnMgKys7CgkJCX0KCQl9CgkJYXJnYy0tOwoJCWFyZ3YrKzsKCX0KCQoJcmV0dXJuKG5iX2Vycm9ycyk7Cn0KCnN0YXRpYyB2b2lkIGRlcHJlY2F0ZV9kaXNwbGF5X3VzYWdlKHZvaWQpCnsKCXVzYWdlKGV4ZWNuYW1lKTsKCXByaW50ZiAoXygiZGVwcmVjYXRlZCB1c2FnZTogJXMge3NobSB8IG1zZyB8IHNlbX0gaWQgLi4uXG4iKSwKCQlleGVjbmFtZSk7Cn0KCnN0YXRpYyBpbnQgZGVwcmVjYXRlZF9tYWluKGludCBhcmdjLCBjaGFyICoqYXJndikKewoJZXhlY25hbWUgPSBhcmd2WzBdOwoKCWlmIChhcmdjIDwgMykgewoJCWRlcHJlY2F0ZV9kaXNwbGF5X3VzYWdlKCk7CgkJZXhpdCgxKTsKCX0KCQoJaWYgKCFzdHJjbXAoYXJndlsxXSwgInNobSIpKSB7CgkJaWYgKHJlbW92ZV9pZHMoU0hNLCBhcmdjLTIsICZhcmd2WzJdKSkKCQkJZXhpdCgxKTsKCX0KCWVsc2UgaWYgKCFzdHJjbXAoYXJndlsxXSwgIm1zZyIpKSB7CgkJaWYgKHJlbW92ZV9pZHMoTVNHLCBhcmdjLTIsICZhcmd2WzJdKSkKCQkJZXhpdCgxKTsKCX0gCgllbHNlIGlmICghc3RyY21wKGFyZ3ZbMV0sICJzZW0iKSkgewoJCWlmIChyZW1vdmVfaWRzKFNFTSwgYXJnYy0yLCAmYXJndlsyXSkpCgkJCWV4aXQoMSk7Cgl9CgllbHNlIHsKCQlkZXByZWNhdGVfZGlzcGxheV91c2FnZSgpOwoJCXByaW50ZiAoXygidW5rbm93biByZXNvdXJjZSB0eXBlOiAlc1xuIiksIGFyZ3ZbMV0pOwoJCWV4aXQoMSk7Cgl9CgoJcHJpbnRmIChfKCJyZXNvdXJjZShzKSBkZWxldGVkXG4iKSk7CglyZXR1cm4gMDsKfQoKCi8qIHByaW50IHRoZSBuZXcgdXNhZ2UgKi8Kc3RhdGljIHZvaWQKdXNhZ2UoY2hhciAqcHJvZ25hbWUpCnsKCWZwcmludGYoc3RkZXJyLAoJCV8oInVzYWdlOiAlcyBbIFstcSBtc3FpZF0gWy1tIHNobWlkXSBbLXMgc2VtaWRdXG4iCgkJICAiICAgICAgICAgIFstUSBtc2drZXldIFstTSBzaG1rZXldIFstUyBzZW1rZXldIC4uLiBdXG4iKSwKCQlwcm9nbmFtZSk7Cn0KCmludCBtYWluKGludCBhcmdjLCBjaGFyICoqYXJndikKewoJaW50ICAgYzsKCWludCAgIGVycm9yID0gMDsKCWNoYXIgKnByb2cgPSBhcmd2WzBdOwoKCS8qIGlmIHRoZSBjb21tYW5kIGlzIGV4ZWN1dGVkIHdpdGhvdXQgcGFyYW1ldGVycywgZG8gbm90aGluZyAqLwoJaWYgKGFyZ2MgPT0gMSkKCQlyZXR1cm4gMDsKCglzZXRsb2NhbGUoTENfQUxMLCAiIik7CgliaW5kdGV4dGRvbWFpbihQQUNLQUdFLCBMT0NBTEVESVIpOwoJdGV4dGRvbWFpbihQQUNLQUdFKTsKCgkvKiBjaGVjayB0byBzZWUgaWYgdGhlIGNvbW1hbmQgaXMgYmVpbmcgaW52b2tlZCBpbiB0aGUgb2xkIHdheSBpZiBzbwoJICAgdGhlbiBydW4gdGhlIG9sZCBjb2RlICovCglpZiAoc3RyY21wKGFyZ3ZbMV0sICJzaG0iKSA9PSAwIHx8CgkgICAgc3RyY21wKGFyZ3ZbMV0sICJtc2ciKSA9PSAwIHx8CgkgICAgc3RyY21wKGFyZ3ZbMV0sICJzZW0iKSA9PSAwKQoJCXJldHVybiBkZXByZWNhdGVkX21haW4oYXJnYywgYXJndik7CgoJLyogcHJvY2VzcyBuZXcgc3ludGF4IHRvIGNvbmZvcm0gd2l0aCBTWVNWIGlwY3JtICovCgl3aGlsZSAoKGMgPSBnZXRvcHQoYXJnYywgYXJndiwgInE6bTpzOlE6TTpTOiIpKSAhPSAtMSkgewoJCWludCByZXN1bHQ7CgkJaW50IGlkID0gMDsKCQlpbnQgaXNrZXkgPSBpc3VwcGVyKGMpOwoKCQkvKiBuZWVkZWQgdG8gZGVsZXRlIHNlbWFwaG9yZXMgKi8KCQl1bmlvbiBzZW11biBhcmc7CgkJYXJnLnZhbCA9IDA7CgoJCS8qIHdlIGRvbid0IG5lZWQgY2FzZSBpbmZvcm1hdGlvbiBhbnkgbW9yZSAqLwoJCWMgPSB0b2xvd2VyKGMpOwoKCQkvKiBtYWtlIHN1cmUgdGhlIG9wdGlvbiBpcyBpbiByYW5nZSAqLwoJCWlmIChjICE9ICdxJyAmJiBjICE9ICdtJyAmJiBjICE9ICdzJykgewoJCQlmcHJpbnRmKHN0ZGVyciwgXygiJXM6IGlsbGVnYWwgb3B0aW9uIC0tICVjXG4iKSwKCQkJCXByb2csIGMpOwoJCQl1c2FnZShwcm9nKTsKCQkJZXJyb3IrKzsKCQkJcmV0dXJuIGVycm9yOwoJCX0KCgkJaWYgKGlza2V5KSB7CgkJCS8qIGtleXMgYXJlIGluIGhleCBvciBkZWNpbWFsICovCgkJCWtleV90IGtleSA9IHN0cnRvdWwob3B0YXJnLCBOVUxMLCAwKTsKCQkJaWYgKGtleSA9PSBJUENfUFJJVkFURSkgewoJCQkJZXJyb3IrKzsKCQkJCWZwcmludGYoc3RkZXJyLCBfKCIlczogaWxsZWdhbCBrZXkgKCVzKVxuIiksCgkJCQkJcHJvZywgb3B0YXJnKTsKCQkJCWNvbnRpbnVlOwoJCQl9CgoJCQkvKiBjb252ZXJ0IGtleSB0byBpZCAqLwoJCQlpZCA9ICgoYyA9PSAncScpID8gbXNnZ2V0KGtleSwgMCkgOgoJCQkgICAgICAoYyA9PSAnbScpID8gc2htZ2V0KGtleSwgMCwgMCkgOgoJCQkgICAgICBzZW1nZXQoa2V5LCAwLCAwKSk7CgoJCQlpZiAoaWQgPCAwKSB7CgkJCQljaGFyICplcnJtc2c7CgkJCQllcnJvcisrOwoJCQkJc3dpdGNoKGVycm5vKSB7CgkJCQljYXNlIEVBQ0NFUzoKCQkJCQllcnJtc2cgPSBfKCJwZXJtaXNzaW9uIGRlbmllZCBmb3Iga2V5Iik7CgkJCQkJYnJlYWs7CgkJCQljYXNlIEVJRFJNOgoJCQkJCWVycm1zZyA9IF8oImFscmVhZHkgcmVtb3ZlZCBrZXkiKTsKCQkJCQlicmVhazsKCQkJCWNhc2UgRU5PRU5UOgoJCQkJCWVycm1zZyA9IF8oImludmFsaWQga2V5Iik7CgkJCQkJYnJlYWs7CgkJCQlkZWZhdWx0OgoJCQkJCWVycm1zZyA9IF8oInVua25vd24gZXJyb3IgaW4ga2V5Iik7CgkJCQkJYnJlYWs7CgkJCQl9CgkJCQlmcHJpbnRmKHN0ZGVyciwgIiVzOiAlcyAoJXMpXG4iLAoJCQkJCXByb2csIGVycm1zZywgb3B0YXJnKTsKCQkJCWNvbnRpbnVlOwoJCQl9CgkJfSBlbHNlIHsKCQkJLyogaWRzIGFyZSBpbiBkZWNpbWFsICovCgkJCWlkID0gc3RydG91bChvcHRhcmcsIE5VTEwsIDEwKTsKCQl9CgoJCXJlc3VsdCA9ICgoYyA9PSAncScpID8gbXNnY3RsKGlkLCBJUENfUk1JRCwgTlVMTCkgOgoJCQkgIChjID09ICdtJykgPyBzaG1jdGwoaWQsIElQQ19STUlELCBOVUxMKSA6IAoJCQkgIHNlbWN0bChpZCwgMCwgSVBDX1JNSUQsIGFyZykpOwoKCQlpZiAocmVzdWx0IDwgMCkgewoJCQljaGFyICplcnJtc2c7CgkJCWVycm9yKys7CgkJCXN3aXRjaChlcnJubykgewoJCQljYXNlIEVBQ0NFUzoKCQkJY2FzZSBFUEVSTToKCQkJCWVycm1zZyA9IGlza2V5CgkJCQkJPyBfKCJwZXJtaXNzaW9uIGRlbmllZCBmb3Iga2V5IikKCQkJCQk6IF8oInBlcm1pc3Npb24gZGVuaWVkIGZvciBpZCIpOwoJCQkJYnJlYWs7CgkJCWNhc2UgRUlOVkFMOgoJCQkJZXJybXNnID0gaXNrZXkKCQkJCQk/IF8oImludmFsaWQga2V5IikKCQkJCQk6IF8oImludmFsaWQgaWQiKTsKCQkJCWJyZWFrOwoJCQljYXNlIEVJRFJNOgoJCQkJZXJybXNnID0gaXNrZXkKCQkJCQk/IF8oImFscmVhZHkgcmVtb3ZlZCBrZXkiKQoJCQkJCTogXygiYWxyZWFkeSByZW1vdmVkIGlkIik7CgkJCQlicmVhazsKCQkJZGVmYXVsdDoKCQkJCWVycm1zZyA9IGlza2V5CgkJCQkJPyBfKCJ1bmtub3duIGVycm9yIGluIGtleSIpCgkJCQkJOiBfKCJ1bmtub3duIGVycm9yIGluIGlkIik7CgkJCQlicmVhazsKCQkJfQoJCQlmcHJpbnRmKHN0ZGVyciwgXygiJXM6ICVzICglcylcbiIpLAoJCQkJcHJvZywgZXJybXNnLCBvcHRhcmcpOwoJCQljb250aW51ZTsKCQl9Cgl9CgoJLyogcHJpbnQgdXNhZ2UgaWYgd2Ugc3RpbGwgaGF2ZSBzb21lIGFyZ3VtZW50cyBsZWZ0IG92ZXIgKi8KCWlmIChvcHRpbmQgIT0gYXJnYykgewoJCWZwcmludGYoc3RkZXJyLCBfKCIlczogdW5rbm93biBhcmd1bWVudDogJXNcbiIpLAoJCQlwcm9nLCBhcmd2W29wdGluZF0pOwoJCXVzYWdlKHByb2cpOwoJfQoKCS8qIGV4aXQgdmFsdWUgcmVmbGVjdHMgdGhlIG51bWJlciBvZiBlcnJvcnMgZW5jb3VudGVyZWQgKi8KCXJldHVybiBlcnJvcjsKfQo=