LyoqIGFsbG93cyBvdmVycmlkaW5nIG9mIGEgZ2l2ZW4gb2lkIHdpdGggYSBuZXcgdHlwZSBhbmQgdmFsdWUgKi8KCi8qIFBvcnRpb25zIG9mIHRoaXMgZmlsZSBhcmUgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIGNvcHlyaWdodChzKS4gIFNlZQogKiB0aGUgTmV0LVNOTVAncyBDT1BZSU5HIGZpbGUgZm9yIG1vcmUgZGV0YWlscyBhbmQgb3RoZXIgY29weXJpZ2h0cwogKiB0aGF0IG1heSBhcHBseToKICovCi8qCiAqIFBvcnRpb25zIG9mIHRoaXMgZmlsZSBhcmUgY29weXJpZ2h0ZWQgYnk6CiAqIENvcHlyaWdodCCpIDIwMDMgU3VuIE1pY3Jvc3lzdGVtcywgSW5jLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBVc2UgaXMgc3ViamVjdCB0byBsaWNlbnNlIHRlcm1zIHNwZWNpZmllZCBpbiB0aGUgQ09QWUlORyBmaWxlCiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhlIE5ldC1TTk1QIHBhY2thZ2UuCiAqLwoKI2luY2x1ZGUgPG5ldC1zbm1wL25ldC1zbm1wLWNvbmZpZy5oPgojaW5jbHVkZSA8bmV0LXNubXAvbmV0LXNubXAtaW5jbHVkZXMuaD4KI2luY2x1ZGUgPG5ldC1zbm1wL2FnZW50L25ldC1zbm1wLWFnZW50LWluY2x1ZGVzLmg+Cgp0eXBlZGVmIHN0cnVjdCBvdmVycmlkZV9kYXRhX3MgewogICAgaW50ICAgICAgICAgICAgIHR5cGU7CiAgICB2b2lkICAgICAgICAgICAqdmFsdWU7CiAgICBzaXplX3QgICAgICAgICAgdmFsdWVfbGVuOwogICAgdm9pZCAgICAgICAgICAgKnNldF9zcGFjZTsKICAgIHNpemVfdCAgICAgICAgICBzZXRfbGVuOwp9IG92ZXJyaWRlX2RhdGE7CgovKiogQHRvZG86IChvcHRpb25hbGx5KSBzYXZlIHZhbHVlcyBwZXJzaXN0ZW50bHkgd2hlbiBjb25maWd1cmVkIGZvcgogKiAgcmVhZC13cml0ZSAqLwppbnQKb3ZlcnJpZGVfaGFuZGxlcihuZXRzbm1wX21pYl9oYW5kbGVyICpoYW5kbGVyLAogICAgICAgICAgICAgICAgIG5ldHNubXBfaGFuZGxlcl9yZWdpc3RyYXRpb24gKnJlZ2luZm8sCiAgICAgICAgICAgICAgICAgbmV0c25tcF9hZ2VudF9yZXF1ZXN0X2luZm8gKnJlcWluZm8sCiAgICAgICAgICAgICAgICAgbmV0c25tcF9yZXF1ZXN0X2luZm8gKnJlcXVlc3RzKQp7CgogICAgb3ZlcnJpZGVfZGF0YSAgKmRhdGEgPSBoYW5kbGVyLT5teXZvaWQ7CiAgICB2b2lkICp0bXBwdHI7CgogICAgaWYgKCFkYXRhKSB7CiAgICAgICAgbmV0c25tcF9zZXRfcmVxdWVzdF9lcnJvcihyZXFpbmZvLCByZXF1ZXN0cywgU05NUF9FUlJfR0VORVJSKTsKICAgICAgICByZXR1cm4gU05NUF9FUlJfTk9FUlJPUjsKICAgIH0KCiAgICBzd2l0Y2ggKHJlcWluZm8tPm1vZGUpIHsKICAgIGNhc2UgTU9ERV9HRVQ6CiAgICAgICAgREVCVUdNU0dUTCgoIm92ZXJyaWRlIiwgIm92ZXJyaWRpbmcgb2lkICIpKTsKICAgICAgICBERUJVR01TR09JRCgoIm92ZXJyaWRlIiwgcmVxdWVzdHMtPnJlcXVlc3R2Yi0+bmFtZSwKICAgICAgICAgICAgICAgICAgICAgcmVxdWVzdHMtPnJlcXVlc3R2Yi0+bmFtZV9sZW5ndGgpKTsKICAgICAgICBERUJVR01TRygoIm92ZXJyaWRlIiwgIlxuIikpOwogICAgICAgIHNubXBfc2V0X3Zhcl90eXBlZF92YWx1ZShyZXF1ZXN0cy0+cmVxdWVzdHZiLCAodV9jaGFyKWRhdGEtPnR5cGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICh1X2NoYXIgKikgZGF0YS0+dmFsdWUsIGRhdGEtPnZhbHVlX2xlbik7CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSBNT0RFX1NFVF9SRVNFUlZFMToKICAgICAgICBpZiAocmVxdWVzdHMtPnJlcXVlc3R2Yi0+dHlwZSAhPSBkYXRhLT50eXBlKQogICAgICAgICAgICBuZXRzbm1wX3NldF9yZXF1ZXN0X2Vycm9yKHJlcWluZm8sIHJlcXVlc3RzLCBTTk1QX0VSUl9XUk9OR1RZUEUpOwogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgTU9ERV9TRVRfUkVTRVJWRTI6CiAgICAgICAgaWYgKG1lbWR1cCgodV9jaGFyICoqKSAmZGF0YS0+c2V0X3NwYWNlLAogICAgICAgICAgICAgICAgICAgcmVxdWVzdHMtPnJlcXVlc3R2Yi0+dmFsLnN0cmluZywKICAgICAgICAgICAgICAgICAgIHJlcXVlc3RzLT5yZXF1ZXN0dmItPnZhbF9sZW4pID09IFNOTVBFUlJfR0VORVJSKQogICAgICAgICAgICBuZXRzbm1wX3NldF9yZXF1ZXN0X2Vycm9yKHJlcWluZm8sIHJlcXVlc3RzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNOTVBfRVJSX1JFU09VUkNFVU5BVkFJTEFCTEUpOwogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgTU9ERV9TRVRfRlJFRToKICAgICAgICBTTk1QX0ZSRUUoZGF0YS0+c2V0X3NwYWNlKTsKICAgICAgICBicmVhazsKCiAgICBjYXNlIE1PREVfU0VUX0FDVElPTjoKICAgICAgICAvKiBzd2FwIHRoZSB2YWx1ZXMgaW4gKi8KICAgICAgICB0bXBwdHIgPSBkYXRhLT52YWx1ZTsKICAgICAgICBkYXRhLT52YWx1ZSA9IGRhdGEtPnNldF9zcGFjZTsKICAgICAgICBkYXRhLT5zZXRfc3BhY2UgPSB0bXBwdHI7CgogICAgICAgIC8qIHNldCB0aGUgbGVuZ3RocyAqLwogICAgICAgIGRhdGEtPnNldF9sZW4gPSBkYXRhLT52YWx1ZV9sZW47CiAgICAgICAgZGF0YS0+dmFsdWVfbGVuID0gcmVxdWVzdHMtPnJlcXVlc3R2Yi0+dmFsX2xlbjsKICAgICAgICBicmVhazsKCiAgICBjYXNlIE1PREVfU0VUX1VORE86CiAgICAgICAgU05NUF9GUkVFKGRhdGEtPnZhbHVlKTsKICAgICAgICBkYXRhLT52YWx1ZSA9IGRhdGEtPnNldF9zcGFjZTsKICAgICAgICBkYXRhLT52YWx1ZV9sZW4gPSBkYXRhLT5zZXRfbGVuOwogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgTU9ERV9TRVRfQ09NTUlUOgogICAgICAgIFNOTVBfRlJFRShkYXRhLT5zZXRfc3BhY2UpOwogICAgICAgIGJyZWFrOwoKICAgIGRlZmF1bHQ6CiAgICAgICAgc25tcF9sb2coTE9HX0VSUiwgInVuc3VwcG9ydGVkIG1vZGUgaW4gb3ZlcnJpZGUgaGFuZGxlclxuIik7CiAgICAgICAgbmV0c25tcF9zZXRfcmVxdWVzdF9lcnJvcihyZXFpbmZvLCByZXF1ZXN0cywgU05NUF9FUlJfR0VORVJSKTsKICAgICAgICByZXR1cm4gU05NUF9FUlJfR0VORVJSOwogICAgfQogICAgcmV0dXJuIFNOTVBfRVJSX05PRVJST1I7Cn0KCiNkZWZpbmUgTUFMTE9DX09SX0RJRSh4KSBcCiAgdGhlZGF0YS0+dmFsdWUgPSBtYWxsb2MoeCk7IFwKICB0aGVkYXRhLT52YWx1ZV9sZW4gPSB4OyBcCiAgaWYgKCF0aGVkYXRhLT52YWx1ZSkgeyBcCiAgICAgIGZyZWUodGhlZGF0YSk7IFwKICAgICAgY29uZmlnX3BlcnJvcigibWVtb3J5IGFsbG9jYXRpb24gZmFpbHVyZSIpOyBcCiAgICAgIHJldHVybjsgXAogIH0KCnZvaWQKbmV0c25tcF9wYXJzZV9vdmVycmlkZShjb25zdCBjaGFyICp0b2tlbiwgY2hhciAqbGluZSkKewogICAgY2hhciAgICAgICAgICAgKmNwOwogICAgY2hhciAgICAgICAgICAgIGJ1ZltTTk1QX01BWEJVRl0sIG5hbWVidWZbU05NUF9NQVhCVUZdOwogICAgaW50ICAgICAgICAgICAgIHJlYWR3cml0ZSA9IDA7CiAgICBvaWQgICAgICAgICAgICAgb2lkYnVmW01BWF9PSURfTEVOXTsKICAgIHNpemVfdCAgICAgICAgICBvaWRidWZfbGVuID0gTUFYX09JRF9MRU47CiAgICBpbnQgICAgICAgICAgICAgdHlwZTsKICAgIG92ZXJyaWRlX2RhdGEgICp0aGVkYXRhOwogICAgbmV0c25tcF9oYW5kbGVyX3JlZ2lzdHJhdGlvbiAqdGhlX3JlZzsKCiAgICBjcCA9IGNvcHlfbndvcmQobGluZSwgbmFtZWJ1Ziwgc2l6ZW9mKG5hbWVidWYpIC0gMSk7CiAgICBpZiAoc3RyY21wKG5hbWVidWYsICItcnciKSA9PSAwKSB7CiAgICAgICAgcmVhZHdyaXRlID0gMTsKICAgICAgICBjcCA9IGNvcHlfbndvcmQoY3AsIG5hbWVidWYsIHNpemVvZihuYW1lYnVmKSAtIDEpOwogICAgfQoKICAgIGlmICghY3ApIHsKICAgICAgICBjb25maWdfcGVycm9yKCJubyBvaWQgc3BlY2lmaWVkIik7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgIGlmICghc25tcF9wYXJzZV9vaWQobmFtZWJ1Ziwgb2lkYnVmLCAmb2lkYnVmX2xlbikpIHsKICAgICAgICBjb25maWdfcGVycm9yKCJpbGxlZ2FsIG9pZCIpOwogICAgICAgIHJldHVybjsKICAgIH0KICAgIGNwID0gY29weV9ud29yZChjcCwgYnVmLCBzaXplb2YoYnVmKSAtIDEpOwoKICAgIGlmICghY3AgJiYgc3RyY21wKGJ1ZiwgIm51bGwiKSAhPSAwKSB7CiAgICAgICAgY29uZmlnX3BlcnJvcigibm8gdmFyaWFibGUgdmFsdWUgc3BlY2lmaWVkIik7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgIHsKICAgICAgICBzdHJ1Y3QgeyBjb25zdCBjaGFyKiBrZXk7IGludCB2YWx1ZTsgfSBjb25zdCBzdHJpbmdzW10gPSB7CiAgICAgICAgICAgIHsgImNvdW50ZXIiLCBBU05fQ09VTlRFUiB9LAogICAgICAgICAgICB7ICJjb3VudGVyNjQiLCBBU05fQ09VTlRFUjY0IH0sCiAgICAgICAgICAgIHsgImludGVnZXIiLCBBU05fSU5URUdFUiB9LAogICAgICAgICAgICB7ICJpcGFkZHJlc3MiLCBBU05fSVBBRERSRVNTIH0sCiAgICAgICAgICAgIHsgIm5zYXAiLCBBU05fTlNBUCB9LAogICAgICAgICAgICB7ICJudWxsIiwgQVNOX05VTEwgfSwKICAgICAgICAgICAgeyAib2JqZWN0X2lkIiwgQVNOX09CSkVDVF9JRCB9LAogICAgICAgICAgICB7ICJvY3RldF9zdHIiLCBBU05fT0NURVRfU1RSIH0sCiAgICAgICAgICAgIHsgIm9wYXF1ZSIsIEFTTl9PUEFRVUUgfSwKI2lmZGVmIE5FVFNOTVBfV0lUSF9PUEFRVUVfU1BFQ0lBTF9UWVBFUwogICAgICAgICAgICB7ICJvcGFxdWVfY291bnRlcjY0IiwgQVNOX09QQVFVRV9DT1VOVEVSNjQgfSwKICAgICAgICAgICAgeyAib3BhcXVlX2RvdWJsZSIsIEFTTl9PUEFRVUVfRE9VQkxFIH0sCiAgICAgICAgICAgIHsgIm9wYXF1ZV9mbG9hdCIsIEFTTl9PUEFRVUVfRkxPQVQgfSwKICAgICAgICAgICAgeyAib3BhcXVlX2k2NCIsIEFTTl9PUEFRVUVfSTY0IH0sCiAgICAgICAgICAgIHsgIm9wYXF1ZV91NjQiLCBBU05fT1BBUVVFX1U2NCB9LAojZW5kaWYKICAgICAgICAgICAgeyAidGltZXRpY2tzIiwgQVNOX1RJTUVUSUNLUyB9LAogICAgICAgICAgICB7ICJ1aW50ZWdlciIsIEFTTl9HQVVHRSB9LAogICAgICAgICAgICB7ICJ1bnNpZ25lZCIsIEFTTl9VTlNJR05FRCB9LAogICAgICAgICAgICB7IE5VTEwsIDAgfQogICAgICAgIH0sICogcnVuOwogICAgICAgIGZvcihydW4gPSBzdHJpbmdzOyBydW4tPmtleSAmJiBzdHJjYXNlY21wKHJ1bi0+a2V5LCBidWYpIDwgMDsgKytydW4pOwogICAgICAgIGlmKHJ1bi0+a2V5ICYmIHN0cmNhc2VjbXAocnVuLT5rZXksIGJ1ZikgPT0gMCkKICAgICAgICAgICAgdHlwZSA9IHJ1bi0+dmFsdWU7CiAgICAgICAgZWxzZSB7CiAgICAgICAgICAgIGNvbmZpZ19wZXJyb3IoInVua25vd24gdHlwZSBzcGVjaWZpZWQiKTsKICAgICAgICAgICAgcmV0dXJuOwogICAgICAgIH0KICAgIH0KCiAgICBpZiAoY3ApCiAgICAgICAgY29weV9ud29yZChjcCwgYnVmLCBzaXplb2YoYnVmKSAtIDEpOwogICAgZWxzZQogICAgICAgIGJ1ZlswXSA9IDA7CgogICAgdGhlZGF0YSA9IFNOTVBfTUFMTE9DX1RZUEVERUYob3ZlcnJpZGVfZGF0YSk7CiAgICBpZiAoIXRoZWRhdGEpIHsKICAgICAgICBjb25maWdfcGVycm9yKCJtZW1vcnkgYWxsb2NhdGlvbiBmYWlsdXJlIik7CiAgICAgICAgcmV0dXJuOwogICAgfQogICAgdGhlZGF0YS0+dHlwZSA9IHR5cGU7CgogICAgc3dpdGNoICh0eXBlKSB7CiAgICBjYXNlIEFTTl9JTlRFR0VSOgogICAgICAgIE1BTExPQ19PUl9ESUUoc2l6ZW9mKGxvbmcpKTsKICAgICAgICAqKChsb25nICopIHRoZWRhdGEtPnZhbHVlKSA9IHN0cnRvbChidWYsIE5VTEwsIDApOwogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgQVNOX0NPVU5URVI6CiAgICBjYXNlIEFTTl9USU1FVElDS1M6CiAgICBjYXNlIEFTTl9VTlNJR05FRDoKICAgICAgICBNQUxMT0NfT1JfRElFKHNpemVvZih1X2xvbmcpKTsKICAgICAgICAqKCh1X2xvbmcgKikgdGhlZGF0YS0+dmFsdWUpID0gc3RydG91bChidWYsIE5VTEwsIDApOwogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgQVNOX09DVEVUX1NUUjoKICAgIGNhc2UgQVNOX0JJVF9TVFI6CiAgICAgICAgaWYgKGJ1ZlswXSA9PSAnMCcgJiYgYnVmWzFdID09ICd4JykgewogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBoZXggCiAgICAgICAgICAgICAqLwogICAgICAgICAgICB0aGVkYXRhLT52YWx1ZV9sZW4gPQogICAgICAgICAgICAgICAgaGV4X3RvX2JpbmFyeTIoYnVmICsgMiwgc3RybGVuKGJ1ZikgLSAyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGNoYXIgKiopICZ0aGVkYXRhLT52YWx1ZSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgdGhlZGF0YS0+dmFsdWUgPSBzdHJkdXAoYnVmKTsKICAgICAgICAgICAgdGhlZGF0YS0+dmFsdWVfbGVuID0gc3RybGVuKGJ1Zik7CiAgICAgICAgfQogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgQVNOX09CSkVDVF9JRDoKICAgICAgICByZWFkX2NvbmZpZ19yZWFkX29iamlkKGJ1ZiwgKG9pZCAqKikgJiB0aGVkYXRhLT52YWx1ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZ0aGVkYXRhLT52YWx1ZV9sZW4pOwogICAgICAgIC8qIFdlIG5lZWQgdGhlIHNpemUgb2YgdGhlIHZhbHVlIGluIGJ5dGVzLCBub3QgaW4gb2lkcyAqLwogICAgICAgIHRoZWRhdGEtPnZhbHVlX2xlbiAqPSBzaXplb2Yob2lkKTsKICAgICAgICBicmVhazsKCiAgICBjYXNlIEFTTl9OVUxMOgogICAgICAgIHRoZWRhdGEtPnZhbHVlX2xlbiA9IDA7CiAgICAgICAgYnJlYWs7CgogICAgZGVmYXVsdDoKICAgICAgICBTTk1QX0ZSRUUodGhlZGF0YSk7CiAgICAgICAgY29uZmlnX3BlcnJvcigiaWxsZWdhbC91bnN1cHBvcnRlZCB0eXBlIHNwZWNpZmllZCIpOwogICAgICAgIHJldHVybjsKICAgIH0KCiAgICBpZiAoIXRoZWRhdGEtPnZhbHVlICYmIHRoZWRhdGEtPnR5cGUgIT0gQVNOX05VTEwpIHsKICAgICAgICBjb25maWdfcGVycm9yKCJtZW1vcnkgYWxsb2NhdGlvbiBmYWlsdXJlIik7CiAgICAgICAgZnJlZSh0aGVkYXRhKTsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgdGhlX3JlZyA9IFNOTVBfTUFMTE9DX1RZUEVERUYobmV0c25tcF9oYW5kbGVyX3JlZ2lzdHJhdGlvbik7CiAgICBpZiAoIXRoZV9yZWcpIHsKICAgICAgICBjb25maWdfcGVycm9yKCJtZW1vcnkgYWxsb2NhdGlvbiBmYWlsdXJlIik7CiAgICAgICAgZnJlZSh0aGVkYXRhKTsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgdGhlX3JlZy0+aGFuZGxlck5hbWUgPSBzdHJkdXAobmFtZWJ1Zik7CiAgICB0aGVfcmVnLT5wcmlvcml0eSA9IDI1NTsKICAgIHRoZV9yZWctPm1vZGVzID0gKHJlYWR3cml0ZSkgPyBIQU5ETEVSX0NBTl9SV1JJVEUgOiBIQU5ETEVSX0NBTl9ST05MWTsKICAgIHRoZV9yZWctPmhhbmRsZXIgPQogICAgICAgIG5ldHNubXBfY3JlYXRlX2hhbmRsZXIoIm92ZXJyaWRlIiwgb3ZlcnJpZGVfaGFuZGxlcik7CiAgICB0aGVfcmVnLT5yb290b2lkID0gc25tcF9kdXBsaWNhdGVfb2JqaWQob2lkYnVmLCBvaWRidWZfbGVuKTsKICAgIHRoZV9yZWctPnJvb3RvaWRfbGVuID0gb2lkYnVmX2xlbjsKICAgIGlmICghdGhlX3JlZy0+cm9vdG9pZCB8fCAhdGhlX3JlZy0+aGFuZGxlciB8fCAhdGhlX3JlZy0+aGFuZGxlck5hbWUpIHsKICAgICAgICBpZiAodGhlX3JlZy0+aGFuZGxlcikKICAgICAgICAgICAgU05NUF9GUkVFKHRoZV9yZWctPmhhbmRsZXItPmhhbmRsZXJfbmFtZSk7CiAgICAgICAgU05NUF9GUkVFKHRoZV9yZWctPmhhbmRsZXIpOwogICAgICAgIFNOTVBfRlJFRSh0aGVfcmVnLT5oYW5kbGVyTmFtZSk7CiAgICAgICAgU05NUF9GUkVFKHRoZV9yZWcpOwogICAgICAgIGNvbmZpZ19wZXJyb3IoIm1lbW9yeSBhbGxvY2F0aW9uIGZhaWx1cmUiKTsKICAgICAgICBmcmVlKHRoZWRhdGEpOwogICAgICAgIHJldHVybjsKICAgIH0KICAgIHRoZV9yZWctPmhhbmRsZXItPm15dm9pZCA9IHRoZWRhdGE7CgogICAgaWYgKG5ldHNubXBfcmVnaXN0ZXJfaW5zdGFuY2UodGhlX3JlZykpIHsKICAgICAgICBjb25maWdfcGVycm9yKCJvaWQgcmVnaXN0cmF0aW9uIGZhaWxlZCB3aXRoaW4gdGhlIGFnZW50Iik7CiAgICAgICAgU05NUF9GUkVFKHRoZWRhdGEtPnZhbHVlKTsKICAgICAgICBmcmVlKHRoZWRhdGEpOwogICAgICAgIHJldHVybjsKICAgIH0KfQoKCnZvaWQKaW5pdF9vdmVycmlkZSh2b2lkKQp7CgogICAgc25tcGRfcmVnaXN0ZXJfY29uZmlnX2hhbmRsZXIoIm92ZXJyaWRlIiwgbmV0c25tcF9wYXJzZV9vdmVycmlkZSwgTlVMTCwgICAgIC8qIFhYWDogZnJlZSBmdW5jICovCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiWy1yd10gbWlibm9kZSB0eXBlIHZhbHVlIik7Cn0K