LyoqIGFsbG93cyBvdmVycmlkaW5nIG9mIGEgZ2l2ZW4gb2lkIHdpdGggYSBuZXcgdHlwZSBhbmQgdmFsdWUgKi8KCi8qIFBvcnRpb25zIG9mIHRoaXMgZmlsZSBhcmUgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIGNvcHlyaWdodChzKS4gIFNlZQogKiB0aGUgTmV0LVNOTVAncyBDT1BZSU5HIGZpbGUgZm9yIG1vcmUgZGV0YWlscyBhbmQgb3RoZXIgY29weXJpZ2h0cwogKiB0aGF0IG1heSBhcHBseToKICovCi8qCiAqIFBvcnRpb25zIG9mIHRoaXMgZmlsZSBhcmUgY29weXJpZ2h0ZWQgYnk6CiAqIENvcHlyaWdodCCpIDIwMDMgU3VuIE1pY3Jvc3lzdGVtcywgSW5jLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBVc2UgaXMgc3ViamVjdCB0byBsaWNlbnNlIHRlcm1zIHNwZWNpZmllZCBpbiB0aGUgQ09QWUlORyBmaWxlCiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhlIE5ldC1TTk1QIHBhY2thZ2UuCiAqLwoKI2luY2x1ZGUgPG5ldC1zbm1wL25ldC1zbm1wLWNvbmZpZy5oPgojaW5jbHVkZSA8bmV0LXNubXAvbmV0LXNubXAtaW5jbHVkZXMuaD4KI2luY2x1ZGUgPG5ldC1zbm1wL2FnZW50L25ldC1zbm1wLWFnZW50LWluY2x1ZGVzLmg+Cgp0eXBlZGVmIHN0cnVjdCBvdmVycmlkZV9kYXRhX3MgewogICAgaW50ICAgICAgICAgICAgIHR5cGU7CiAgICB2b2lkICAgICAgICAgICAqdmFsdWU7CiAgICBzaXplX3QgICAgICAgICAgdmFsdWVfbGVuOwogICAgdm9pZCAgICAgICAgICAgKnNldF9zcGFjZTsKICAgIHNpemVfdCAgICAgICAgICBzZXRfbGVuOwp9IG92ZXJyaWRlX2RhdGE7CgovKiogQHRvZG86IChvcHRpb25hbGx5KSBzYXZlIHZhbHVlcyBwZXJzaXN0ZW50bHkgd2hlbiBjb25maWd1cmVkIGZvcgogKiAgcmVhZC13cml0ZSAqLwppbnQKb3ZlcnJpZGVfaGFuZGxlcihuZXRzbm1wX21pYl9oYW5kbGVyICpoYW5kbGVyLAogICAgICAgICAgICAgICAgIG5ldHNubXBfaGFuZGxlcl9yZWdpc3RyYXRpb24gKnJlZ2luZm8sCiAgICAgICAgICAgICAgICAgbmV0c25tcF9hZ2VudF9yZXF1ZXN0X2luZm8gKnJlcWluZm8sCiAgICAgICAgICAgICAgICAgbmV0c25tcF9yZXF1ZXN0X2luZm8gKnJlcXVlc3RzKQp7CgogICAgb3ZlcnJpZGVfZGF0YSAgKmRhdGEgPSAob3ZlcnJpZGVfZGF0YSopaGFuZGxlci0+bXl2b2lkOwogICAgdm9pZCAqdG1wcHRyOwoKICAgIGlmICghZGF0YSkgewogICAgICAgIG5ldHNubXBfc2V0X3JlcXVlc3RfZXJyb3IocmVxaW5mbywgcmVxdWVzdHMsIFNOTVBfRVJSX0dFTkVSUik7CiAgICAgICAgcmV0dXJuIFNOTVBfRVJSX05PRVJST1I7CiAgICB9CgogICAgc3dpdGNoIChyZXFpbmZvLT5tb2RlKSB7CiAgICBjYXNlIE1PREVfR0VUOgogICAgICAgIERFQlVHTVNHVEwoKCJvdmVycmlkZSIsICJvdmVycmlkaW5nIG9pZCAiKSk7CiAgICAgICAgREVCVUdNU0dPSUQoKCJvdmVycmlkZSIsIHJlcXVlc3RzLT5yZXF1ZXN0dmItPm5hbWUsCiAgICAgICAgICAgICAgICAgICAgIHJlcXVlc3RzLT5yZXF1ZXN0dmItPm5hbWVfbGVuZ3RoKSk7CiAgICAgICAgREVCVUdNU0coKCJvdmVycmlkZSIsICJcbiIpKTsKICAgICAgICBzbm1wX3NldF92YXJfdHlwZWRfdmFsdWUocmVxdWVzdHMtPnJlcXVlc3R2YiwgKHVfY2hhcilkYXRhLT50eXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodV9jaGFyICopIGRhdGEtPnZhbHVlLCBkYXRhLT52YWx1ZV9sZW4pOwogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgTU9ERV9TRVRfUkVTRVJWRTE6CiAgICAgICAgaWYgKHJlcXVlc3RzLT5yZXF1ZXN0dmItPnR5cGUgIT0gZGF0YS0+dHlwZSkKICAgICAgICAgICAgbmV0c25tcF9zZXRfcmVxdWVzdF9lcnJvcihyZXFpbmZvLCByZXF1ZXN0cywgU05NUF9FUlJfV1JPTkdUWVBFKTsKICAgICAgICBicmVhazsKCiAgICBjYXNlIE1PREVfU0VUX1JFU0VSVkUyOgogICAgICAgIGRhdGEtPnNldF9zcGFjZSA9IG5ldHNubXBfbWVtZHVwKHJlcXVlc3RzLT5yZXF1ZXN0dmItPnZhbC5zdHJpbmcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVxdWVzdHMtPnJlcXVlc3R2Yi0+dmFsX2xlbik7CiAgICAgICAgaWYgKCFkYXRhLT5zZXRfc3BhY2UpCiAgICAgICAgICAgIG5ldHNubXBfc2V0X3JlcXVlc3RfZXJyb3IocmVxaW5mbywgcmVxdWVzdHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU05NUF9FUlJfUkVTT1VSQ0VVTkFWQUlMQUJMRSk7CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSBNT0RFX1NFVF9GUkVFOgogICAgICAgIFNOTVBfRlJFRShkYXRhLT5zZXRfc3BhY2UpOwogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgTU9ERV9TRVRfQUNUSU9OOgogICAgICAgIC8qIHN3YXAgdGhlIHZhbHVlcyBpbiAqLwogICAgICAgIHRtcHB0ciA9IGRhdGEtPnZhbHVlOwogICAgICAgIGRhdGEtPnZhbHVlID0gZGF0YS0+c2V0X3NwYWNlOwogICAgICAgIGRhdGEtPnNldF9zcGFjZSA9IHRtcHB0cjsKCiAgICAgICAgLyogc2V0IHRoZSBsZW5ndGhzICovCiAgICAgICAgZGF0YS0+c2V0X2xlbiA9IGRhdGEtPnZhbHVlX2xlbjsKICAgICAgICBkYXRhLT52YWx1ZV9sZW4gPSByZXF1ZXN0cy0+cmVxdWVzdHZiLT52YWxfbGVuOwogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgTU9ERV9TRVRfVU5ETzoKICAgICAgICBTTk1QX0ZSRUUoZGF0YS0+dmFsdWUpOwogICAgICAgIGRhdGEtPnZhbHVlID0gZGF0YS0+c2V0X3NwYWNlOwogICAgICAgIGRhdGEtPnZhbHVlX2xlbiA9IGRhdGEtPnNldF9sZW47CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSBNT0RFX1NFVF9DT01NSVQ6CiAgICAgICAgU05NUF9GUkVFKGRhdGEtPnNldF9zcGFjZSk7CiAgICAgICAgYnJlYWs7CgogICAgZGVmYXVsdDoKICAgICAgICBzbm1wX2xvZyhMT0dfRVJSLCAidW5zdXBwb3J0ZWQgbW9kZSBpbiBvdmVycmlkZSBoYW5kbGVyXG4iKTsKICAgICAgICBuZXRzbm1wX3NldF9yZXF1ZXN0X2Vycm9yKHJlcWluZm8sIHJlcXVlc3RzLCBTTk1QX0VSUl9HRU5FUlIpOwogICAgICAgIHJldHVybiBTTk1QX0VSUl9HRU5FUlI7CiAgICB9CiAgICByZXR1cm4gU05NUF9FUlJfTk9FUlJPUjsKfQoKI2RlZmluZSBNQUxMT0NfT1JfRElFKHgpIFwKICB0aGVkYXRhLT52YWx1ZSA9IG1hbGxvYyh4KTsgXAogIHRoZWRhdGEtPnZhbHVlX2xlbiA9IHg7IFwKICBpZiAoIXRoZWRhdGEtPnZhbHVlKSB7IFwKICAgICAgZnJlZSh0aGVkYXRhKTsgXAogICAgICBjb25maWdfcGVycm9yKCJtZW1vcnkgYWxsb2NhdGlvbiBmYWlsdXJlIik7IFwKICAgICAgcmV0dXJuOyBcCiAgfQoKdm9pZApuZXRzbm1wX3BhcnNlX292ZXJyaWRlKGNvbnN0IGNoYXIgKnRva2VuLCBjaGFyICpsaW5lKQp7CiAgICBjaGFyICAgICAgICAgICAqY3A7CiAgICBjaGFyICAgICAgICAgICAgYnVmW1NOTVBfTUFYQlVGXSwgbmFtZWJ1ZltTTk1QX01BWEJVRl07CiAgICBpbnQgICAgICAgICAgICAgcmVhZHdyaXRlID0gMDsKICAgIG9pZCAgICAgICAgICAgICBvaWRidWZbTUFYX09JRF9MRU5dOwogICAgc2l6ZV90ICAgICAgICAgIG9pZGJ1Zl9sZW4gPSBNQVhfT0lEX0xFTjsKICAgIGludCAgICAgICAgICAgICB0eXBlOwogICAgb3ZlcnJpZGVfZGF0YSAgKnRoZWRhdGE7CiAgICBuZXRzbm1wX2hhbmRsZXJfcmVnaXN0cmF0aW9uICp0aGVfcmVnOwoKICAgIGNwID0gY29weV9ud29yZChsaW5lLCBuYW1lYnVmLCBzaXplb2YobmFtZWJ1ZikgLSAxKTsKICAgIGlmIChzdHJjbXAobmFtZWJ1ZiwgIi1ydyIpID09IDApIHsKICAgICAgICByZWFkd3JpdGUgPSAxOwogICAgICAgIGNwID0gY29weV9ud29yZChjcCwgbmFtZWJ1Ziwgc2l6ZW9mKG5hbWVidWYpIC0gMSk7CiAgICB9CgogICAgaWYgKCFjcCkgewogICAgICAgIGNvbmZpZ19wZXJyb3IoIm5vIG9pZCBzcGVjaWZpZWQiKTsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgaWYgKCFzbm1wX3BhcnNlX29pZChuYW1lYnVmLCBvaWRidWYsICZvaWRidWZfbGVuKSkgewogICAgICAgIGNvbmZpZ19wZXJyb3IoImlsbGVnYWwgb2lkIik7CiAgICAgICAgcmV0dXJuOwogICAgfQogICAgY3AgPSBjb3B5X253b3JkKGNwLCBidWYsIHNpemVvZihidWYpIC0gMSk7CgogICAgaWYgKCFjcCAmJiBzdHJjbXAoYnVmLCAibnVsbCIpICE9IDApIHsKICAgICAgICBjb25maWdfcGVycm9yKCJubyB2YXJpYWJsZSB2YWx1ZSBzcGVjaWZpZWQiKTsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgewogICAgICAgIHN0cnVjdCB7IGNvbnN0IGNoYXIqIGtleTsgaW50IHZhbHVlOyB9IGNvbnN0IHN0cmluZ3NbXSA9IHsKICAgICAgICAgICAgeyAiY291bnRlciIsIEFTTl9DT1VOVEVSIH0sCiAgICAgICAgICAgIHsgImNvdW50ZXI2NCIsIEFTTl9DT1VOVEVSNjQgfSwKICAgICAgICAgICAgeyAiaW50ZWdlciIsIEFTTl9JTlRFR0VSIH0sCiAgICAgICAgICAgIHsgImlwYWRkcmVzcyIsIEFTTl9JUEFERFJFU1MgfSwKICAgICAgICAgICAgeyAibnNhcCIsIEFTTl9OU0FQIH0sCiAgICAgICAgICAgIHsgIm51bGwiLCBBU05fTlVMTCB9LAogICAgICAgICAgICB7ICJvYmplY3RfaWQiLCBBU05fT0JKRUNUX0lEIH0sCiAgICAgICAgICAgIHsgIm9jdGV0X3N0ciIsIEFTTl9PQ1RFVF9TVFIgfSwKICAgICAgICAgICAgeyAib3BhcXVlIiwgQVNOX09QQVFVRSB9LAojaWZkZWYgTkVUU05NUF9XSVRIX09QQVFVRV9TUEVDSUFMX1RZUEVTCiAgICAgICAgICAgIHsgIm9wYXF1ZV9jb3VudGVyNjQiLCBBU05fT1BBUVVFX0NPVU5URVI2NCB9LAogICAgICAgICAgICB7ICJvcGFxdWVfZG91YmxlIiwgQVNOX09QQVFVRV9ET1VCTEUgfSwKICAgICAgICAgICAgeyAib3BhcXVlX2Zsb2F0IiwgQVNOX09QQVFVRV9GTE9BVCB9LAogICAgICAgICAgICB7ICJvcGFxdWVfaTY0IiwgQVNOX09QQVFVRV9JNjQgfSwKICAgICAgICAgICAgeyAib3BhcXVlX3U2NCIsIEFTTl9PUEFRVUVfVTY0IH0sCiNlbmRpZgogICAgICAgICAgICB7ICJ0aW1ldGlja3MiLCBBU05fVElNRVRJQ0tTIH0sCiAgICAgICAgICAgIHsgInVpbnRlZ2VyIiwgQVNOX0dBVUdFIH0sCiAgICAgICAgICAgIHsgInVuc2lnbmVkIiwgQVNOX1VOU0lHTkVEIH0sCiAgICAgICAgICAgIHsgTlVMTCwgMCB9CiAgICAgICAgfSwgKiBydW47CiAgICAgICAgZm9yKHJ1biA9IHN0cmluZ3M7IHJ1bi0+a2V5ICYmIHN0cmNhc2VjbXAocnVuLT5rZXksIGJ1ZikgPCAwOyArK3J1bik7CiAgICAgICAgaWYocnVuLT5rZXkgJiYgc3RyY2FzZWNtcChydW4tPmtleSwgYnVmKSA9PSAwKQogICAgICAgICAgICB0eXBlID0gcnVuLT52YWx1ZTsKICAgICAgICBlbHNlIHsKICAgICAgICAgICAgY29uZmlnX3BlcnJvcigidW5rbm93biB0eXBlIHNwZWNpZmllZCIpOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgfQoKICAgIGlmIChjcCkKICAgICAgICBjb3B5X253b3JkKGNwLCBidWYsIHNpemVvZihidWYpIC0gMSk7CiAgICBlbHNlCiAgICAgICAgYnVmWzBdID0gMDsKCiAgICB0aGVkYXRhID0gU05NUF9NQUxMT0NfVFlQRURFRihvdmVycmlkZV9kYXRhKTsKICAgIGlmICghdGhlZGF0YSkgewogICAgICAgIGNvbmZpZ19wZXJyb3IoIm1lbW9yeSBhbGxvY2F0aW9uIGZhaWx1cmUiKTsKICAgICAgICByZXR1cm47CiAgICB9CiAgICB0aGVkYXRhLT50eXBlID0gdHlwZTsKCiAgICBzd2l0Y2ggKHR5cGUpIHsKICAgIGNhc2UgQVNOX0lOVEVHRVI6CiAgICAgICAgTUFMTE9DX09SX0RJRShzaXplb2YobG9uZykpOwogICAgICAgICooKGxvbmcgKikgdGhlZGF0YS0+dmFsdWUpID0gc3RydG9sKGJ1ZiwgTlVMTCwgMCk7CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSBBU05fQ09VTlRFUjoKICAgIGNhc2UgQVNOX1RJTUVUSUNLUzoKICAgIGNhc2UgQVNOX1VOU0lHTkVEOgogICAgICAgIE1BTExPQ19PUl9ESUUoc2l6ZW9mKHVfbG9uZykpOwogICAgICAgICooKHVfbG9uZyAqKSB0aGVkYXRhLT52YWx1ZSkgPSBzdHJ0b3VsKGJ1ZiwgTlVMTCwgMCk7CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSBBU05fT0NURVRfU1RSOgogICAgY2FzZSBBU05fQklUX1NUUjoKICAgICAgICBpZiAoYnVmWzBdID09ICcwJyAmJiBidWZbMV0gPT0gJ3gnKSB7CiAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAqIGhleCAKICAgICAgICAgICAgICovCiAgICAgICAgICAgIHRoZWRhdGEtPnZhbHVlX2xlbiA9CiAgICAgICAgICAgICAgICBoZXhfdG9fYmluYXJ5MigodV9jaGFyICopKGJ1ZiArIDIpLCBzdHJsZW4oYnVmKSAtIDIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAoY2hhciAqKikgJnRoZWRhdGEtPnZhbHVlKTsKICAgICAgICB9IGVsc2UgewogICAgICAgICAgICB0aGVkYXRhLT52YWx1ZSA9IHN0cmR1cChidWYpOwogICAgICAgICAgICB0aGVkYXRhLT52YWx1ZV9sZW4gPSBzdHJsZW4oYnVmKTsKICAgICAgICB9CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSBBU05fT0JKRUNUX0lEOgogICAgICAgIHJlYWRfY29uZmlnX3JlYWRfb2JqaWQoYnVmLCAob2lkICoqKSAmIHRoZWRhdGEtPnZhbHVlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJnRoZWRhdGEtPnZhbHVlX2xlbik7CiAgICAgICAgLyogV2UgbmVlZCB0aGUgc2l6ZSBvZiB0aGUgdmFsdWUgaW4gYnl0ZXMsIG5vdCBpbiBvaWRzICovCiAgICAgICAgdGhlZGF0YS0+dmFsdWVfbGVuICo9IHNpemVvZihvaWQpOwogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgQVNOX05VTEw6CiAgICAgICAgdGhlZGF0YS0+dmFsdWVfbGVuID0gMDsKICAgICAgICBicmVhazsKCiAgICBkZWZhdWx0OgogICAgICAgIFNOTVBfRlJFRSh0aGVkYXRhKTsKICAgICAgICBjb25maWdfcGVycm9yKCJpbGxlZ2FsL3Vuc3VwcG9ydGVkIHR5cGUgc3BlY2lmaWVkIik7CiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgIGlmICghdGhlZGF0YS0+dmFsdWUgJiYgdGhlZGF0YS0+dHlwZSAhPSBBU05fTlVMTCkgewogICAgICAgIGNvbmZpZ19wZXJyb3IoIm1lbW9yeSBhbGxvY2F0aW9uIGZhaWx1cmUiKTsKICAgICAgICBmcmVlKHRoZWRhdGEpOwogICAgICAgIHJldHVybjsKICAgIH0KCiAgICB0aGVfcmVnID0gU05NUF9NQUxMT0NfVFlQRURFRihuZXRzbm1wX2hhbmRsZXJfcmVnaXN0cmF0aW9uKTsKICAgIGlmICghdGhlX3JlZykgewogICAgICAgIGNvbmZpZ19wZXJyb3IoIm1lbW9yeSBhbGxvY2F0aW9uIGZhaWx1cmUiKTsKICAgICAgICBmcmVlKHRoZWRhdGEpOwogICAgICAgIHJldHVybjsKICAgIH0KCiAgICB0aGVfcmVnLT5oYW5kbGVyTmFtZSA9IHN0cmR1cChuYW1lYnVmKTsKICAgIHRoZV9yZWctPnByaW9yaXR5ID0gMjU1OwogICAgdGhlX3JlZy0+bW9kZXMgPSAocmVhZHdyaXRlKSA/IEhBTkRMRVJfQ0FOX1JXUklURSA6IEhBTkRMRVJfQ0FOX1JPTkxZOwogICAgdGhlX3JlZy0+aGFuZGxlciA9CiAgICAgICAgbmV0c25tcF9jcmVhdGVfaGFuZGxlcigib3ZlcnJpZGUiLCBvdmVycmlkZV9oYW5kbGVyKTsKICAgIHRoZV9yZWctPnJvb3RvaWQgPSBzbm1wX2R1cGxpY2F0ZV9vYmppZChvaWRidWYsIG9pZGJ1Zl9sZW4pOwogICAgdGhlX3JlZy0+cm9vdG9pZF9sZW4gPSBvaWRidWZfbGVuOwogICAgaWYgKCF0aGVfcmVnLT5yb290b2lkIHx8ICF0aGVfcmVnLT5oYW5kbGVyIHx8ICF0aGVfcmVnLT5oYW5kbGVyTmFtZSkgewogICAgICAgIGlmICh0aGVfcmVnLT5oYW5kbGVyKQogICAgICAgICAgICBTTk1QX0ZSRUUodGhlX3JlZy0+aGFuZGxlci0+aGFuZGxlcl9uYW1lKTsKICAgICAgICBTTk1QX0ZSRUUodGhlX3JlZy0+aGFuZGxlcik7CiAgICAgICAgU05NUF9GUkVFKHRoZV9yZWctPmhhbmRsZXJOYW1lKTsKICAgICAgICBTTk1QX0ZSRUUodGhlX3JlZyk7CiAgICAgICAgY29uZmlnX3BlcnJvcigibWVtb3J5IGFsbG9jYXRpb24gZmFpbHVyZSIpOwogICAgICAgIGZyZWUodGhlZGF0YSk7CiAgICAgICAgcmV0dXJuOwogICAgfQogICAgdGhlX3JlZy0+aGFuZGxlci0+bXl2b2lkID0gdGhlZGF0YTsKCiAgICBpZiAobmV0c25tcF9yZWdpc3Rlcl9pbnN0YW5jZSh0aGVfcmVnKSkgewogICAgICAgIGNvbmZpZ19wZXJyb3IoIm9pZCByZWdpc3RyYXRpb24gZmFpbGVkIHdpdGhpbiB0aGUgYWdlbnQiKTsKICAgICAgICBTTk1QX0ZSRUUodGhlZGF0YS0+dmFsdWUpOwogICAgICAgIGZyZWUodGhlZGF0YSk7CiAgICAgICAgcmV0dXJuOwogICAgfQp9CgoKdm9pZAppbml0X292ZXJyaWRlKHZvaWQpCnsKCiAgICBzbm1wZF9yZWdpc3Rlcl9jb25maWdfaGFuZGxlcigib3ZlcnJpZGUiLCBuZXRzbm1wX3BhcnNlX292ZXJyaWRlLCBOVUxMLCAgICAgLyogWFhYOiBmcmVlIGZ1bmMgKi8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJbLXJ3XSBtaWJub2RlIHR5cGUgdmFsdWUiKTsKfQo=