LyoqIGFsbG93cyBvdmVycmlkaW5nIG9mIGEgZ2l2ZW4gb2lkIHdpdGggYSBuZXcgdHlwZSBhbmQgdmFsdWUgKi8KCi8qIFBvcnRpb25zIG9mIHRoaXMgZmlsZSBhcmUgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIGNvcHlyaWdodChzKS4gIFNlZQogKiB0aGUgTmV0LVNOTVAncyBDT1BZSU5HIGZpbGUgZm9yIG1vcmUgZGV0YWlscyBhbmQgb3RoZXIgY29weXJpZ2h0cwogKiB0aGF0IG1heSBhcHBseToKICovCi8qCiAqIFBvcnRpb25zIG9mIHRoaXMgZmlsZSBhcmUgY29weXJpZ2h0ZWQgYnk6CiAqIENvcHlyaWdodCCpIDIwMDMgU3VuIE1pY3Jvc3lzdGVtcywgSW5jLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBVc2UgaXMgc3ViamVjdCB0byBsaWNlbnNlIHRlcm1zIHNwZWNpZmllZCBpbiB0aGUgQ09QWUlORyBmaWxlCiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhlIE5ldC1TTk1QIHBhY2thZ2UuCiAqLwoKI2luY2x1ZGUgPG5ldC1zbm1wL25ldC1zbm1wLWNvbmZpZy5oPgojaW5jbHVkZSA8bmV0LXNubXAvbmV0LXNubXAtaW5jbHVkZXMuaD4KI2luY2x1ZGUgPG5ldC1zbm1wL2FnZW50L25ldC1zbm1wLWFnZW50LWluY2x1ZGVzLmg+Cgp0eXBlZGVmIHN0cnVjdCBvdmVycmlkZV9kYXRhX3MgewogICAgaW50ICAgICAgICAgICAgIHR5cGU7CiAgICB2b2lkICAgICAgICAgICAqdmFsdWU7CiAgICBzaXplX3QgICAgICAgICAgdmFsdWVfbGVuOwogICAgdm9pZCAgICAgICAgICAgKnNldF9zcGFjZTsKICAgIHNpemVfdCAgICAgICAgICBzZXRfbGVuOwp9IG92ZXJyaWRlX2RhdGE7CgovKiogQHRvZG86IChvcHRpb25hbGx5KSBzYXZlIHZhbHVlcyBwZXJzaXN0ZW50bHkgd2hlbiBjb25maWd1cmVkIGZvcgogKiAgcmVhZC13cml0ZSAqLwppbnQKb3ZlcnJpZGVfaGFuZGxlcihuZXRzbm1wX21pYl9oYW5kbGVyICpoYW5kbGVyLAogICAgICAgICAgICAgICAgIG5ldHNubXBfaGFuZGxlcl9yZWdpc3RyYXRpb24gKnJlZ2luZm8sCiAgICAgICAgICAgICAgICAgbmV0c25tcF9hZ2VudF9yZXF1ZXN0X2luZm8gKnJlcWluZm8sCiAgICAgICAgICAgICAgICAgbmV0c25tcF9yZXF1ZXN0X2luZm8gKnJlcXVlc3RzKQp7CgogICAgb3ZlcnJpZGVfZGF0YSAgKmRhdGEgPSBoYW5kbGVyLT5teXZvaWQ7CiAgICB2b2lkICp0bXBwdHI7CgogICAgaWYgKCFkYXRhKSB7CiAgICAgICAgbmV0c25tcF9zZXRfcmVxdWVzdF9lcnJvcihyZXFpbmZvLCByZXF1ZXN0cywgU05NUF9FUlJfR0VORVJSKTsKICAgICAgICByZXR1cm4gU05NUF9FUlJfTk9FUlJPUjsKICAgIH0KCiAgICBzd2l0Y2ggKHJlcWluZm8tPm1vZGUpIHsKICAgIGNhc2UgTU9ERV9HRVQ6CiAgICAgICAgREVCVUdNU0dUTCgoIm92ZXJyaWRlIiwgIm92ZXJyaWRpbmcgb2lkICIpKTsKICAgICAgICBERUJVR01TR09JRCgoIm92ZXJyaWRlIiwgcmVxdWVzdHMtPnJlcXVlc3R2Yi0+bmFtZSwKICAgICAgICAgICAgICAgICAgICAgcmVxdWVzdHMtPnJlcXVlc3R2Yi0+bmFtZV9sZW5ndGgpKTsKICAgICAgICBERUJVR01TRygoIm92ZXJyaWRlIiwgIlxuIikpOwogICAgICAgIHNubXBfc2V0X3Zhcl90eXBlZF92YWx1ZShyZXF1ZXN0cy0+cmVxdWVzdHZiLCAodV9jaGFyKWRhdGEtPnR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh1X2NoYXIgKikgZGF0YS0+dmFsdWUsIGRhdGEtPnZhbHVlX2xlbik7CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSBNT0RFX1NFVF9SRVNFUlZFMToKICAgICAgICBpZiAocmVxdWVzdHMtPnJlcXVlc3R2Yi0+dHlwZSAhPSBkYXRhLT50eXBlKQogICAgICAgICAgICBuZXRzbm1wX3NldF9yZXF1ZXN0X2Vycm9yKHJlcWluZm8sIHJlcXVlc3RzLCBTTk1QX0VSUl9XUk9OR1RZUEUpOwogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgTU9ERV9TRVRfUkVTRVJWRTI6CiAgICAgICAgZGF0YS0+c2V0X3NwYWNlID0gbmV0c25tcF9tZW1kdXAocmVxdWVzdHMtPnJlcXVlc3R2Yi0+dmFsLnN0cmluZywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXF1ZXN0cy0+cmVxdWVzdHZiLT52YWxfbGVuKTsKICAgICAgICBpZiAoIWRhdGEtPnNldF9zcGFjZSkKICAgICAgICAgICAgbmV0c25tcF9zZXRfcmVxdWVzdF9lcnJvcihyZXFpbmZvLCByZXF1ZXN0cywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBTTk1QX0VSUl9SRVNPVVJDRVVOQVZBSUxBQkxFKTsKICAgICAgICBicmVhazsKCiAgICBjYXNlIE1PREVfU0VUX0ZSRUU6CiAgICAgICAgU05NUF9GUkVFKGRhdGEtPnNldF9zcGFjZSk7CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSBNT0RFX1NFVF9BQ1RJT046CiAgICAgICAgLyogc3dhcCB0aGUgdmFsdWVzIGluICovCiAgICAgICAgdG1wcHRyID0gZGF0YS0+dmFsdWU7CiAgICAgICAgZGF0YS0+dmFsdWUgPSBkYXRhLT5zZXRfc3BhY2U7CiAgICAgICAgZGF0YS0+c2V0X3NwYWNlID0gdG1wcHRyOwoKICAgICAgICAvKiBzZXQgdGhlIGxlbmd0aHMgKi8KICAgICAgICBkYXRhLT5zZXRfbGVuID0gZGF0YS0+dmFsdWVfbGVuOwogICAgICAgIGRhdGEtPnZhbHVlX2xlbiA9IHJlcXVlc3RzLT5yZXF1ZXN0dmItPnZhbF9sZW47CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSBNT0RFX1NFVF9VTkRPOgogICAgICAgIFNOTVBfRlJFRShkYXRhLT52YWx1ZSk7CiAgICAgICAgZGF0YS0+dmFsdWUgPSBkYXRhLT5zZXRfc3BhY2U7CiAgICAgICAgZGF0YS0+dmFsdWVfbGVuID0gZGF0YS0+c2V0X2xlbjsKICAgICAgICBicmVhazsKCiAgICBjYXNlIE1PREVfU0VUX0NPTU1JVDoKICAgICAgICBTTk1QX0ZSRUUoZGF0YS0+c2V0X3NwYWNlKTsKICAgICAgICBicmVhazsKCiAgICBkZWZhdWx0OgogICAgICAgIHNubXBfbG9nKExPR19FUlIsICJ1bnN1cHBvcnRlZCBtb2RlIGluIG92ZXJyaWRlIGhhbmRsZXJcbiIpOwogICAgICAgIG5ldHNubXBfc2V0X3JlcXVlc3RfZXJyb3IocmVxaW5mbywgcmVxdWVzdHMsIFNOTVBfRVJSX0dFTkVSUik7CiAgICAgICAgcmV0dXJuIFNOTVBfRVJSX0dFTkVSUjsKICAgIH0KICAgIHJldHVybiBTTk1QX0VSUl9OT0VSUk9SOwp9CgojZGVmaW5lIE1BTExPQ19PUl9ESUUoeCkgXAogIHRoZWRhdGEtPnZhbHVlID0gbWFsbG9jKHgpOyBcCiAgdGhlZGF0YS0+dmFsdWVfbGVuID0geDsgXAogIGlmICghdGhlZGF0YS0+dmFsdWUpIHsgXAogICAgICBmcmVlKHRoZWRhdGEpOyBcCiAgICAgIGNvbmZpZ19wZXJyb3IoIm1lbW9yeSBhbGxvY2F0aW9uIGZhaWx1cmUiKTsgXAogICAgICByZXR1cm47IFwKICB9Cgp2b2lkCm5ldHNubXBfcGFyc2Vfb3ZlcnJpZGUoY29uc3QgY2hhciAqdG9rZW4sIGNoYXIgKmxpbmUpCnsKICAgIGNoYXIgICAgICAgICAgICpjcDsKICAgIGNoYXIgICAgICAgICAgICBidWZbU05NUF9NQVhCVUZdLCBuYW1lYnVmW1NOTVBfTUFYQlVGXTsKICAgIGludCAgICAgICAgICAgICByZWFkd3JpdGUgPSAwOwogICAgb2lkICAgICAgICAgICAgIG9pZGJ1ZltNQVhfT0lEX0xFTl07CiAgICBzaXplX3QgICAgICAgICAgb2lkYnVmX2xlbiA9IE1BWF9PSURfTEVOOwogICAgaW50ICAgICAgICAgICAgIHR5cGU7CiAgICBvdmVycmlkZV9kYXRhICAqdGhlZGF0YTsKICAgIG5ldHNubXBfaGFuZGxlcl9yZWdpc3RyYXRpb24gKnRoZV9yZWc7CgogICAgY3AgPSBjb3B5X253b3JkKGxpbmUsIG5hbWVidWYsIHNpemVvZihuYW1lYnVmKSAtIDEpOwogICAgaWYgKHN0cmNtcChuYW1lYnVmLCAiLXJ3IikgPT0gMCkgewogICAgICAgIHJlYWR3cml0ZSA9IDE7CiAgICAgICAgY3AgPSBjb3B5X253b3JkKGNwLCBuYW1lYnVmLCBzaXplb2YobmFtZWJ1ZikgLSAxKTsKICAgIH0KCiAgICBpZiAoIWNwKSB7CiAgICAgICAgY29uZmlnX3BlcnJvcigibm8gb2lkIHNwZWNpZmllZCIpOwogICAgICAgIHJldHVybjsKICAgIH0KCiAgICBpZiAoIXNubXBfcGFyc2Vfb2lkKG5hbWVidWYsIG9pZGJ1ZiwgJm9pZGJ1Zl9sZW4pKSB7CiAgICAgICAgY29uZmlnX3BlcnJvcigiaWxsZWdhbCBvaWQiKTsKICAgICAgICByZXR1cm47CiAgICB9CiAgICBjcCA9IGNvcHlfbndvcmQoY3AsIGJ1Ziwgc2l6ZW9mKGJ1ZikgLSAxKTsKCiAgICBpZiAoIWNwICYmIHN0cmNtcChidWYsICJudWxsIikgIT0gMCkgewogICAgICAgIGNvbmZpZ19wZXJyb3IoIm5vIHZhcmlhYmxlIHZhbHVlIHNwZWNpZmllZCIpOwogICAgICAgIHJldHVybjsKICAgIH0KCiAgICB7CiAgICAgICAgc3RydWN0IHsgY29uc3QgY2hhcioga2V5OyBpbnQgdmFsdWU7IH0gY29uc3Qgc3RyaW5nc1tdID0gewogICAgICAgICAgICB7ICJjb3VudGVyIiwgQVNOX0NPVU5URVIgfSwKICAgICAgICAgICAgeyAiY291bnRlcjY0IiwgQVNOX0NPVU5URVI2NCB9LAogICAgICAgICAgICB7ICJpbnRlZ2VyIiwgQVNOX0lOVEVHRVIgfSwKICAgICAgICAgICAgeyAiaXBhZGRyZXNzIiwgQVNOX0lQQUREUkVTUyB9LAogICAgICAgICAgICB7ICJuc2FwIiwgQVNOX05TQVAgfSwKICAgICAgICAgICAgeyAibnVsbCIsIEFTTl9OVUxMIH0sCiAgICAgICAgICAgIHsgIm9iamVjdF9pZCIsIEFTTl9PQkpFQ1RfSUQgfSwKICAgICAgICAgICAgeyAib2N0ZXRfc3RyIiwgQVNOX09DVEVUX1NUUiB9LAogICAgICAgICAgICB7ICJvcGFxdWUiLCBBU05fT1BBUVVFIH0sCiNpZmRlZiBORVRTTk1QX1dJVEhfT1BBUVVFX1NQRUNJQUxfVFlQRVMKICAgICAgICAgICAgeyAib3BhcXVlX2NvdW50ZXI2NCIsIEFTTl9PUEFRVUVfQ09VTlRFUjY0IH0sCiAgICAgICAgICAgIHsgIm9wYXF1ZV9kb3VibGUiLCBBU05fT1BBUVVFX0RPVUJMRSB9LAogICAgICAgICAgICB7ICJvcGFxdWVfZmxvYXQiLCBBU05fT1BBUVVFX0ZMT0FUIH0sCiAgICAgICAgICAgIHsgIm9wYXF1ZV9pNjQiLCBBU05fT1BBUVVFX0k2NCB9LAogICAgICAgICAgICB7ICJvcGFxdWVfdTY0IiwgQVNOX09QQVFVRV9VNjQgfSwKI2VuZGlmCiAgICAgICAgICAgIHsgInRpbWV0aWNrcyIsIEFTTl9USU1FVElDS1MgfSwKICAgICAgICAgICAgeyAidWludGVnZXIiLCBBU05fR0FVR0UgfSwKICAgICAgICAgICAgeyAidW5zaWduZWQiLCBBU05fVU5TSUdORUQgfSwKICAgICAgICAgICAgeyBOVUxMLCAwIH0KICAgICAgICB9LCAqIHJ1bjsKICAgICAgICBmb3IocnVuID0gc3RyaW5nczsgcnVuLT5rZXkgJiYgc3RyY2FzZWNtcChydW4tPmtleSwgYnVmKSA8IDA7ICsrcnVuKTsKICAgICAgICBpZihydW4tPmtleSAmJiBzdHJjYXNlY21wKHJ1bi0+a2V5LCBidWYpID09IDApCiAgICAgICAgICAgIHR5cGUgPSBydW4tPnZhbHVlOwogICAgICAgIGVsc2UgewogICAgICAgICAgICBjb25maWdfcGVycm9yKCJ1bmtub3duIHR5cGUgc3BlY2lmaWVkIik7CiAgICAgICAgICAgIHJldHVybjsKICAgICAgICB9CiAgICB9CgogICAgaWYgKGNwKQogICAgICAgIGNvcHlfbndvcmQoY3AsIGJ1Ziwgc2l6ZW9mKGJ1ZikgLSAxKTsKICAgIGVsc2UKICAgICAgICBidWZbMF0gPSAwOwoKICAgIHRoZWRhdGEgPSBTTk1QX01BTExPQ19UWVBFREVGKG92ZXJyaWRlX2RhdGEpOwogICAgaWYgKCF0aGVkYXRhKSB7CiAgICAgICAgY29uZmlnX3BlcnJvcigibWVtb3J5IGFsbG9jYXRpb24gZmFpbHVyZSIpOwogICAgICAgIHJldHVybjsKICAgIH0KICAgIHRoZWRhdGEtPnR5cGUgPSB0eXBlOwoKICAgIHN3aXRjaCAodHlwZSkgewogICAgY2FzZSBBU05fSU5URUdFUjoKICAgICAgICBNQUxMT0NfT1JfRElFKHNpemVvZihsb25nKSk7CiAgICAgICAgKigobG9uZyAqKSB0aGVkYXRhLT52YWx1ZSkgPSBzdHJ0b2woYnVmLCBOVUxMLCAwKTsKICAgICAgICBicmVhazsKCiAgICBjYXNlIEFTTl9DT1VOVEVSOgogICAgY2FzZSBBU05fVElNRVRJQ0tTOgogICAgY2FzZSBBU05fVU5TSUdORUQ6CiAgICAgICAgTUFMTE9DX09SX0RJRShzaXplb2YodV9sb25nKSk7CiAgICAgICAgKigodV9sb25nICopIHRoZWRhdGEtPnZhbHVlKSA9IHN0cnRvdWwoYnVmLCBOVUxMLCAwKTsKICAgICAgICBicmVhazsKCiAgICBjYXNlIEFTTl9PQ1RFVF9TVFI6CiAgICBjYXNlIEFTTl9CSVRfU1RSOgogICAgICAgIGlmIChidWZbMF0gPT0gJzAnICYmIGJ1ZlsxXSA9PSAneCcpIHsKICAgICAgICAgICAgLyoKICAgICAgICAgICAgICogaGV4IAogICAgICAgICAgICAgKi8KICAgICAgICAgICAgdGhlZGF0YS0+dmFsdWVfbGVuID0KICAgICAgICAgICAgICAgIGhleF90b19iaW5hcnkyKGJ1ZiArIDIsIHN0cmxlbihidWYpIC0gMiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIChjaGFyICoqKSAmdGhlZGF0YS0+dmFsdWUpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHRoZWRhdGEtPnZhbHVlID0gc3RyZHVwKGJ1Zik7CiAgICAgICAgICAgIHRoZWRhdGEtPnZhbHVlX2xlbiA9IHN0cmxlbihidWYpOwogICAgICAgIH0KICAgICAgICBicmVhazsKCiAgICBjYXNlIEFTTl9PQkpFQ1RfSUQ6CiAgICAgICAgcmVhZF9jb25maWdfcmVhZF9vYmppZChidWYsIChvaWQgKiopICYgdGhlZGF0YS0+dmFsdWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmdGhlZGF0YS0+dmFsdWVfbGVuKTsKICAgICAgICAvKiBXZSBuZWVkIHRoZSBzaXplIG9mIHRoZSB2YWx1ZSBpbiBieXRlcywgbm90IGluIG9pZHMgKi8KICAgICAgICB0aGVkYXRhLT52YWx1ZV9sZW4gKj0gc2l6ZW9mKG9pZCk7CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSBBU05fTlVMTDoKICAgICAgICB0aGVkYXRhLT52YWx1ZV9sZW4gPSAwOwogICAgICAgIGJyZWFrOwoKICAgIGRlZmF1bHQ6CiAgICAgICAgU05NUF9GUkVFKHRoZWRhdGEpOwogICAgICAgIGNvbmZpZ19wZXJyb3IoImlsbGVnYWwvdW5zdXBwb3J0ZWQgdHlwZSBzcGVjaWZpZWQiKTsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgaWYgKCF0aGVkYXRhLT52YWx1ZSAmJiB0aGVkYXRhLT50eXBlICE9IEFTTl9OVUxMKSB7CiAgICAgICAgY29uZmlnX3BlcnJvcigibWVtb3J5IGFsbG9jYXRpb24gZmFpbHVyZSIpOwogICAgICAgIGZyZWUodGhlZGF0YSk7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgIHRoZV9yZWcgPSBTTk1QX01BTExPQ19UWVBFREVGKG5ldHNubXBfaGFuZGxlcl9yZWdpc3RyYXRpb24pOwogICAgaWYgKCF0aGVfcmVnKSB7CiAgICAgICAgY29uZmlnX3BlcnJvcigibWVtb3J5IGFsbG9jYXRpb24gZmFpbHVyZSIpOwogICAgICAgIGZyZWUodGhlZGF0YSk7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgIHRoZV9yZWctPmhhbmRsZXJOYW1lID0gc3RyZHVwKG5hbWVidWYpOwogICAgdGhlX3JlZy0+cHJpb3JpdHkgPSAyNTU7CiAgICB0aGVfcmVnLT5tb2RlcyA9IChyZWFkd3JpdGUpID8gSEFORExFUl9DQU5fUldSSVRFIDogSEFORExFUl9DQU5fUk9OTFk7CiAgICB0aGVfcmVnLT5oYW5kbGVyID0KICAgICAgICBuZXRzbm1wX2NyZWF0ZV9oYW5kbGVyKCJvdmVycmlkZSIsIG92ZXJyaWRlX2hhbmRsZXIpOwogICAgdGhlX3JlZy0+cm9vdG9pZCA9IHNubXBfZHVwbGljYXRlX29iamlkKG9pZGJ1Ziwgb2lkYnVmX2xlbik7CiAgICB0aGVfcmVnLT5yb290b2lkX2xlbiA9IG9pZGJ1Zl9sZW47CiAgICBpZiAoIXRoZV9yZWctPnJvb3RvaWQgfHwgIXRoZV9yZWctPmhhbmRsZXIgfHwgIXRoZV9yZWctPmhhbmRsZXJOYW1lKSB7CiAgICAgICAgaWYgKHRoZV9yZWctPmhhbmRsZXIpCiAgICAgICAgICAgIFNOTVBfRlJFRSh0aGVfcmVnLT5oYW5kbGVyLT5oYW5kbGVyX25hbWUpOwogICAgICAgIFNOTVBfRlJFRSh0aGVfcmVnLT5oYW5kbGVyKTsKICAgICAgICBTTk1QX0ZSRUUodGhlX3JlZy0+aGFuZGxlck5hbWUpOwogICAgICAgIFNOTVBfRlJFRSh0aGVfcmVnKTsKICAgICAgICBjb25maWdfcGVycm9yKCJtZW1vcnkgYWxsb2NhdGlvbiBmYWlsdXJlIik7CiAgICAgICAgZnJlZSh0aGVkYXRhKTsKICAgICAgICByZXR1cm47CiAgICB9CiAgICB0aGVfcmVnLT5oYW5kbGVyLT5teXZvaWQgPSB0aGVkYXRhOwoKICAgIGlmIChuZXRzbm1wX3JlZ2lzdGVyX2luc3RhbmNlKHRoZV9yZWcpKSB7CiAgICAgICAgY29uZmlnX3BlcnJvcigib2lkIHJlZ2lzdHJhdGlvbiBmYWlsZWQgd2l0aGluIHRoZSBhZ2VudCIpOwogICAgICAgIFNOTVBfRlJFRSh0aGVkYXRhLT52YWx1ZSk7CiAgICAgICAgZnJlZSh0aGVkYXRhKTsKICAgICAgICByZXR1cm47CiAgICB9Cn0KCgp2b2lkCmluaXRfb3ZlcnJpZGUodm9pZCkKewoKICAgIHNubXBkX3JlZ2lzdGVyX2NvbmZpZ19oYW5kbGVyKCJvdmVycmlkZSIsIG5ldHNubXBfcGFyc2Vfb3ZlcnJpZGUsIE5VTEwsICAgICAvKiBYWFg6IGZyZWUgZnVuYyAqLwogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlstcnddIG1pYm5vZGUgdHlwZSB2YWx1ZSIpOwp9Cg==