LyoqIGFsbG93cyBvdmVycmlkaW5nIG9mIGEgZ2l2ZW4gb2lkIHdpdGggYSBuZXcgdHlwZSBhbmQgdmFsdWUgKi8KCi8qIFBvcnRpb25zIG9mIHRoaXMgZmlsZSBhcmUgc3ViamVjdCB0byB0aGUgZm9sbG93aW5nIGNvcHlyaWdodChzKS4gIFNlZQogKiB0aGUgTmV0LVNOTVAncyBDT1BZSU5HIGZpbGUgZm9yIG1vcmUgZGV0YWlscyBhbmQgb3RoZXIgY29weXJpZ2h0cwogKiB0aGF0IG1heSBhcHBseToKICovCi8qCiAqIFBvcnRpb25zIG9mIHRoaXMgZmlsZSBhcmUgY29weXJpZ2h0ZWQgYnk6CiAqIENvcHlyaWdodCCpIDIwMDMgU3VuIE1pY3Jvc3lzdGVtcywgSW5jLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBVc2UgaXMgc3ViamVjdCB0byBsaWNlbnNlIHRlcm1zIHNwZWNpZmllZCBpbiB0aGUgQ09QWUlORyBmaWxlCiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhlIE5ldC1TTk1QIHBhY2thZ2UuCiAqLwoKI2luY2x1ZGUgPG5ldC1zbm1wL25ldC1zbm1wLWNvbmZpZy5oPgojaW5jbHVkZSA8bmV0LXNubXAvbmV0LXNubXAtaW5jbHVkZXMuaD4KI2luY2x1ZGUgPG5ldC1zbm1wL2FnZW50L25ldC1zbm1wLWFnZW50LWluY2x1ZGVzLmg+CgojaW5jbHVkZSAidXRpbF9mdW5jcy5oIgoKdHlwZWRlZiBzdHJ1Y3Qgb3ZlcnJpZGVfZGF0YV9zIHsKICAgIGludCAgICAgICAgICAgICB0eXBlOwogICAgdm9pZCAgICAgICAgICAgKnZhbHVlOwogICAgc2l6ZV90ICAgICAgICAgIHZhbHVlX2xlbjsKICAgIHZvaWQgICAgICAgICAgICpzZXRfc3BhY2U7CiAgICBzaXplX3QgICAgICAgICAgc2V0X2xlbjsKfSBvdmVycmlkZV9kYXRhOwoKLyoqIEB0b2RvOiAob3B0aW9uYWxseSkgc2F2ZSB2YWx1ZXMgcGVyc2lzdGVudGx5IHdoZW4gY29uZmlndXJlZCBmb3IKICogIHJlYWQtd3JpdGUgKi8KaW50Cm92ZXJyaWRlX2hhbmRsZXIobmV0c25tcF9taWJfaGFuZGxlciAqaGFuZGxlciwKICAgICAgICAgICAgICAgICBuZXRzbm1wX2hhbmRsZXJfcmVnaXN0cmF0aW9uICpyZWdpbmZvLAogICAgICAgICAgICAgICAgIG5ldHNubXBfYWdlbnRfcmVxdWVzdF9pbmZvICpyZXFpbmZvLAogICAgICAgICAgICAgICAgIG5ldHNubXBfcmVxdWVzdF9pbmZvICpyZXF1ZXN0cykKewoKICAgIG92ZXJyaWRlX2RhdGEgICpkYXRhID0gaGFuZGxlci0+bXl2b2lkOwogICAgdm9pZCAqdG1wcHRyOwoKICAgIGlmICghZGF0YSkgewogICAgICAgIG5ldHNubXBfc2V0X3JlcXVlc3RfZXJyb3IocmVxaW5mbywgcmVxdWVzdHMsIFNOTVBfRVJSX0dFTkVSUik7CiAgICAgICAgcmV0dXJuIFNOTVBfRVJSX05PRVJST1I7CiAgICB9CgogICAgc3dpdGNoIChyZXFpbmZvLT5tb2RlKSB7CiAgICBjYXNlIE1PREVfR0VUOgogICAgICAgIERFQlVHTVNHVEwoKCJvdmVycmlkZSIsICJvdmVycmlkaW5nIG9pZCAiKSk7CiAgICAgICAgREVCVUdNU0dPSUQoKCJvdmVycmlkZSIsIHJlcXVlc3RzLT5yZXF1ZXN0dmItPm5hbWUsCiAgICAgICAgICAgICAgICAgICAgIHJlcXVlc3RzLT5yZXF1ZXN0dmItPm5hbWVfbGVuZ3RoKSk7CiAgICAgICAgREVCVUdNU0coKCJvdmVycmlkZSIsICJcbiIpKTsKICAgICAgICBzbm1wX3NldF92YXJfdHlwZWRfdmFsdWUocmVxdWVzdHMtPnJlcXVlc3R2YiwgKHVfY2hhcilkYXRhLT50eXBlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAodV9jaGFyICopIGRhdGEtPnZhbHVlLCBkYXRhLT52YWx1ZV9sZW4pOwogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgTU9ERV9TRVRfUkVTRVJWRTE6CiAgICAgICAgaWYgKHJlcXVlc3RzLT5yZXF1ZXN0dmItPnR5cGUgIT0gZGF0YS0+dHlwZSkKICAgICAgICAgICAgbmV0c25tcF9zZXRfcmVxdWVzdF9lcnJvcihyZXFpbmZvLCByZXF1ZXN0cywgU05NUF9FUlJfV1JPTkdUWVBFKTsKICAgICAgICBicmVhazsKCiAgICBjYXNlIE1PREVfU0VUX1JFU0VSVkUyOgogICAgICAgIGRhdGEtPnNldF9zcGFjZSA9IG5ldHNubXBfbWVtZHVwKHJlcXVlc3RzLT5yZXF1ZXN0dmItPnZhbC5zdHJpbmcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVxdWVzdHMtPnJlcXVlc3R2Yi0+dmFsX2xlbik7CiAgICAgICAgaWYgKCFkYXRhLT5zZXRfc3BhY2UpCiAgICAgICAgICAgIG5ldHNubXBfc2V0X3JlcXVlc3RfZXJyb3IocmVxaW5mbywgcmVxdWVzdHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU05NUF9FUlJfUkVTT1VSQ0VVTkFWQUlMQUJMRSk7CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSBNT0RFX1NFVF9GUkVFOgogICAgICAgIFNOTVBfRlJFRShkYXRhLT5zZXRfc3BhY2UpOwogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgTU9ERV9TRVRfQUNUSU9OOgogICAgICAgIC8qIHN3YXAgdGhlIHZhbHVlcyBpbiAqLwogICAgICAgIHRtcHB0ciA9IGRhdGEtPnZhbHVlOwogICAgICAgIGRhdGEtPnZhbHVlID0gZGF0YS0+c2V0X3NwYWNlOwogICAgICAgIGRhdGEtPnNldF9zcGFjZSA9IHRtcHB0cjsKCiAgICAgICAgLyogc2V0IHRoZSBsZW5ndGhzICovCiAgICAgICAgZGF0YS0+c2V0X2xlbiA9IGRhdGEtPnZhbHVlX2xlbjsKICAgICAgICBkYXRhLT52YWx1ZV9sZW4gPSByZXF1ZXN0cy0+cmVxdWVzdHZiLT52YWxfbGVuOwogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgTU9ERV9TRVRfVU5ETzoKICAgICAgICBTTk1QX0ZSRUUoZGF0YS0+dmFsdWUpOwogICAgICAgIGRhdGEtPnZhbHVlID0gZGF0YS0+c2V0X3NwYWNlOwogICAgICAgIGRhdGEtPnZhbHVlX2xlbiA9IGRhdGEtPnNldF9sZW47CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSBNT0RFX1NFVF9DT01NSVQ6CiAgICAgICAgU05NUF9GUkVFKGRhdGEtPnNldF9zcGFjZSk7CiAgICAgICAgYnJlYWs7CgogICAgZGVmYXVsdDoKICAgICAgICBzbm1wX2xvZyhMT0dfRVJSLCAidW5zdXBwb3J0ZWQgbW9kZSBpbiBvdmVycmlkZSBoYW5kbGVyXG4iKTsKICAgICAgICBuZXRzbm1wX3NldF9yZXF1ZXN0X2Vycm9yKHJlcWluZm8sIHJlcXVlc3RzLCBTTk1QX0VSUl9HRU5FUlIpOwogICAgICAgIHJldHVybiBTTk1QX0VSUl9HRU5FUlI7CiAgICB9CiAgICByZXR1cm4gU05NUF9FUlJfTk9FUlJPUjsKfQoKI2RlZmluZSBNQUxMT0NfT1JfRElFKHgpIFwKICB0aGVkYXRhLT52YWx1ZSA9IG1hbGxvYyh4KTsgXAogIHRoZWRhdGEtPnZhbHVlX2xlbiA9IHg7IFwKICBpZiAoIXRoZWRhdGEtPnZhbHVlKSB7IFwKICAgICAgZnJlZSh0aGVkYXRhKTsgXAogICAgICBjb25maWdfcGVycm9yKCJtZW1vcnkgYWxsb2NhdGlvbiBmYWlsdXJlIik7IFwKICAgICAgcmV0dXJuOyBcCiAgfQoKdm9pZApuZXRzbm1wX3BhcnNlX292ZXJyaWRlKGNvbnN0IGNoYXIgKnRva2VuLCBjaGFyICpsaW5lKQp7CiAgICBjaGFyICAgICAgICAgICAqY3A7CiAgICBjaGFyICAgICAgICAgICAgYnVmW1NOTVBfTUFYQlVGXSwgbmFtZWJ1ZltTTk1QX01BWEJVRl07CiAgICBpbnQgICAgICAgICAgICAgcmVhZHdyaXRlID0gMDsKICAgIG9pZCAgICAgICAgICAgICBvaWRidWZbTUFYX09JRF9MRU5dOwogICAgc2l6ZV90ICAgICAgICAgIG9pZGJ1Zl9sZW4gPSBNQVhfT0lEX0xFTjsKICAgIGludCAgICAgICAgICAgICB0eXBlOwogICAgb3ZlcnJpZGVfZGF0YSAgKnRoZWRhdGE7CiAgICBuZXRzbm1wX2hhbmRsZXJfcmVnaXN0cmF0aW9uICp0aGVfcmVnOwoKICAgIGNwID0gY29weV9ud29yZChsaW5lLCBuYW1lYnVmLCBzaXplb2YobmFtZWJ1ZikgLSAxKTsKICAgIGlmIChzdHJjbXAobmFtZWJ1ZiwgIi1ydyIpID09IDApIHsKICAgICAgICByZWFkd3JpdGUgPSAxOwogICAgICAgIGNwID0gY29weV9ud29yZChjcCwgbmFtZWJ1Ziwgc2l6ZW9mKG5hbWVidWYpIC0gMSk7CiAgICB9CgogICAgaWYgKCFjcCkgewogICAgICAgIGNvbmZpZ19wZXJyb3IoIm5vIG9pZCBzcGVjaWZpZWQiKTsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgaWYgKCFzbm1wX3BhcnNlX29pZChuYW1lYnVmLCBvaWRidWYsICZvaWRidWZfbGVuKSkgewogICAgICAgIGNvbmZpZ19wZXJyb3IoImlsbGVnYWwgb2lkIik7CiAgICAgICAgcmV0dXJuOwogICAgfQogICAgY3AgPSBjb3B5X253b3JkKGNwLCBidWYsIHNpemVvZihidWYpIC0gMSk7CgogICAgaWYgKCFjcCAmJiBzdHJjbXAoYnVmLCAibnVsbCIpICE9IDApIHsKICAgICAgICBjb25maWdfcGVycm9yKCJubyB2YXJpYWJsZSB2YWx1ZSBzcGVjaWZpZWQiKTsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgewogICAgICAgIHN0cnVjdCB7IGNvbnN0IGNoYXIqIGtleTsgaW50IHZhbHVlOyB9IGNvbnN0IHN0cmluZ3NbXSA9IHsKICAgICAgICAgICAgeyAiY291bnRlciIsIEFTTl9DT1VOVEVSIH0sCiAgICAgICAgICAgIHsgImNvdW50ZXI2NCIsIEFTTl9DT1VOVEVSNjQgfSwKICAgICAgICAgICAgeyAiaW50ZWdlciIsIEFTTl9JTlRFR0VSIH0sCiAgICAgICAgICAgIHsgImlwYWRkcmVzcyIsIEFTTl9JUEFERFJFU1MgfSwKICAgICAgICAgICAgeyAibnNhcCIsIEFTTl9OU0FQIH0sCiAgICAgICAgICAgIHsgIm51bGwiLCBBU05fTlVMTCB9LAogICAgICAgICAgICB7ICJvYmplY3RfaWQiLCBBU05fT0JKRUNUX0lEIH0sCiAgICAgICAgICAgIHsgIm9jdGV0X3N0ciIsIEFTTl9PQ1RFVF9TVFIgfSwKICAgICAgICAgICAgeyAib3BhcXVlIiwgQVNOX09QQVFVRSB9LAojaWZkZWYgTkVUU05NUF9XSVRIX09QQVFVRV9TUEVDSUFMX1RZUEVTCiAgICAgICAgICAgIHsgIm9wYXF1ZV9jb3VudGVyNjQiLCBBU05fT1BBUVVFX0NPVU5URVI2NCB9LAogICAgICAgICAgICB7ICJvcGFxdWVfZG91YmxlIiwgQVNOX09QQVFVRV9ET1VCTEUgfSwKICAgICAgICAgICAgeyAib3BhcXVlX2Zsb2F0IiwgQVNOX09QQVFVRV9GTE9BVCB9LAogICAgICAgICAgICB7ICJvcGFxdWVfaTY0IiwgQVNOX09QQVFVRV9JNjQgfSwKICAgICAgICAgICAgeyAib3BhcXVlX3U2NCIsIEFTTl9PUEFRVUVfVTY0IH0sCiNlbmRpZgogICAgICAgICAgICB7ICJ0aW1ldGlja3MiLCBBU05fVElNRVRJQ0tTIH0sCiAgICAgICAgICAgIHsgInVpbnRlZ2VyIiwgQVNOX0dBVUdFIH0sCiAgICAgICAgICAgIHsgInVuc2lnbmVkIiwgQVNOX1VOU0lHTkVEIH0sCiAgICAgICAgICAgIHsgTlVMTCwgMCB9CiAgICAgICAgfSwgKiBydW47CiAgICAgICAgZm9yKHJ1biA9IHN0cmluZ3M7IHJ1bi0+a2V5ICYmIHN0cmNhc2VjbXAocnVuLT5rZXksIGJ1ZikgPCAwOyArK3J1bik7CiAgICAgICAgaWYocnVuLT5rZXkgJiYgc3RyY2FzZWNtcChydW4tPmtleSwgYnVmKSA9PSAwKQogICAgICAgICAgICB0eXBlID0gcnVuLT52YWx1ZTsKICAgICAgICBlbHNlIHsKICAgICAgICAgICAgY29uZmlnX3BlcnJvcigidW5rbm93biB0eXBlIHNwZWNpZmllZCIpOwogICAgICAgICAgICByZXR1cm47CiAgICAgICAgfQogICAgfQoKICAgIGlmIChjcCkKICAgICAgICBjb3B5X253b3JkKGNwLCBidWYsIHNpemVvZihidWYpIC0gMSk7CiAgICBlbHNlCiAgICAgICAgYnVmWzBdID0gMDsKCiAgICB0aGVkYXRhID0gU05NUF9NQUxMT0NfVFlQRURFRihvdmVycmlkZV9kYXRhKTsKICAgIGlmICghdGhlZGF0YSkgewogICAgICAgIGNvbmZpZ19wZXJyb3IoIm1lbW9yeSBhbGxvY2F0aW9uIGZhaWx1cmUiKTsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgdGhlZGF0YS0+dHlwZSA9IHR5cGU7CgogICAgc3dpdGNoICh0eXBlKSB7CiAgICBjYXNlIEFTTl9JTlRFR0VSOgogICAgICAgIE1BTExPQ19PUl9ESUUoc2l6ZW9mKGxvbmcpKTsKICAgICAgICAqKChsb25nICopIHRoZWRhdGEtPnZhbHVlKSA9IHN0cnRvbChidWYsIE5VTEwsIDApOwogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgQVNOX0NPVU5URVI6CiAgICBjYXNlIEFTTl9USU1FVElDS1M6CiAgICBjYXNlIEFTTl9VTlNJR05FRDoKICAgICAgICBNQUxMT0NfT1JfRElFKHNpemVvZih1X2xvbmcpKTsKICAgICAgICAqKCh1X2xvbmcgKikgdGhlZGF0YS0+dmFsdWUpID0gc3RydG91bChidWYsIE5VTEwsIDApOwogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgQVNOX09DVEVUX1NUUjoKICAgIGNhc2UgQVNOX0JJVF9TVFI6CiAgICAgICAgaWYgKGJ1ZlswXSA9PSAnMCcgJiYgYnVmWzFdID09ICd4JykgewogICAgICAgICAgICAvKgogICAgICAgICAgICAgKiBoZXggCiAgICAgICAgICAgICAqLwogICAgICAgICAgICB0aGVkYXRhLT52YWx1ZV9sZW4gPQogICAgICAgICAgICAgICAgaGV4X3RvX2JpbmFyeTIoYnVmICsgMiwgc3RybGVuKGJ1ZikgLSAyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGNoYXIgKiopICZ0aGVkYXRhLT52YWx1ZSk7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgdGhlZGF0YS0+dmFsdWUgPSBzdHJkdXAoYnVmKTsKICAgICAgICAgICAgdGhlZGF0YS0+dmFsdWVfbGVuID0gc3RybGVuKGJ1Zik7CiAgICAgICAgfQogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgQVNOX09CSkVDVF9JRDoKICAgICAgICByZWFkX2NvbmZpZ19yZWFkX29iamlkKGJ1ZiwgKG9pZCAqKikgJiB0aGVkYXRhLT52YWx1ZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZ0aGVkYXRhLT52YWx1ZV9sZW4pOwogICAgICAgIC8qIFdlIG5lZWQgdGhlIHNpemUgb2YgdGhlIHZhbHVlIGluIGJ5dGVzLCBub3QgaW4gb2lkcyAqLwogICAgICAgIHRoZWRhdGEtPnZhbHVlX2xlbiAqPSBzaXplb2Yob2lkKTsKICAgICAgICBicmVhazsKCiAgICBjYXNlIEFTTl9OVUxMOgogICAgICAgIHRoZWRhdGEtPnZhbHVlX2xlbiA9IDA7CiAgICAgICAgYnJlYWs7CgogICAgZGVmYXVsdDoKICAgICAgICBTTk1QX0ZSRUUodGhlZGF0YSk7CiAgICAgICAgY29uZmlnX3BlcnJvcigiaWxsZWdhbC91bnN1cHBvcnRlZCB0eXBlIHNwZWNpZmllZCIpOwogICAgICAgIHJldHVybjsKICAgIH0KCiAgICBpZiAoIXRoZWRhdGEtPnZhbHVlICYmIHRoZWRhdGEtPnR5cGUgIT0gQVNOX05VTEwpIHsKICAgICAgICBjb25maWdfcGVycm9yKCJtZW1vcnkgYWxsb2NhdGlvbiBmYWlsdXJlIik7CiAgICAgICAgZnJlZSh0aGVkYXRhKTsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgdGhlX3JlZyA9IFNOTVBfTUFMTE9DX1RZUEVERUYobmV0c25tcF9oYW5kbGVyX3JlZ2lzdHJhdGlvbik7CiAgICBpZiAoIXRoZV9yZWcpIHsKICAgICAgICBjb25maWdfcGVycm9yKCJtZW1vcnkgYWxsb2NhdGlvbiBmYWlsdXJlIik7CiAgICAgICAgZnJlZSh0aGVkYXRhKTsKICAgICAgICByZXR1cm47CiAgICB9CgogICAgdGhlX3JlZy0+aGFuZGxlck5hbWUgPSBzdHJkdXAobmFtZWJ1Zik7CiAgICB0aGVfcmVnLT5wcmlvcml0eSA9IDI1NTsKICAgIHRoZV9yZWctPm1vZGVzID0gKHJlYWR3cml0ZSkgPyBIQU5ETEVSX0NBTl9SV1JJVEUgOiBIQU5ETEVSX0NBTl9ST05MWTsKICAgIHRoZV9yZWctPmhhbmRsZXIgPQogICAgICAgIG5ldHNubXBfY3JlYXRlX2hhbmRsZXIoIm92ZXJyaWRlIiwgb3ZlcnJpZGVfaGFuZGxlcik7CiAgICB0aGVfcmVnLT5yb290b2lkID0gbmV0c25tcF9tZW1kdXAob2lkYnVmLCBvaWRidWZfbGVuICogc2l6ZW9mKG9pZCkpOwogICAgdGhlX3JlZy0+cm9vdG9pZF9sZW4gPSBvaWRidWZfbGVuOwogICAgaWYgKCF0aGVfcmVnLT5yb290b2lkIHx8ICF0aGVfcmVnLT5oYW5kbGVyIHx8ICF0aGVfcmVnLT5oYW5kbGVyTmFtZSkgewogICAgICAgIGlmICh0aGVfcmVnLT5oYW5kbGVyKQogICAgICAgICAgICBTTk1QX0ZSRUUodGhlX3JlZy0+aGFuZGxlci0+aGFuZGxlcl9uYW1lKTsKICAgICAgICBTTk1QX0ZSRUUodGhlX3JlZy0+aGFuZGxlcik7CiAgICAgICAgU05NUF9GUkVFKHRoZV9yZWctPmhhbmRsZXJOYW1lKTsKICAgICAgICBTTk1QX0ZSRUUodGhlX3JlZyk7CiAgICAgICAgY29uZmlnX3BlcnJvcigibWVtb3J5IGFsbG9jYXRpb24gZmFpbHVyZSIpOwogICAgICAgIGZyZWUodGhlZGF0YSk7CiAgICAgICAgcmV0dXJuOwogICAgfQogICAgdGhlX3JlZy0+aGFuZGxlci0+bXl2b2lkID0gdGhlZGF0YTsKCiAgICBpZiAobmV0c25tcF9yZWdpc3Rlcl9pbnN0YW5jZSh0aGVfcmVnKSkgewogICAgICAgIGNvbmZpZ19wZXJyb3IoIm9pZCByZWdpc3RyYXRpb24gZmFpbGVkIHdpdGhpbiB0aGUgYWdlbnQiKTsKICAgICAgICBTTk1QX0ZSRUUodGhlZGF0YS0+dmFsdWUpOwogICAgICAgIGZyZWUodGhlZGF0YSk7CiAgICAgICAgcmV0dXJuOwogICAgfQp9CgoKdm9pZAppbml0X292ZXJyaWRlKHZvaWQpCnsKCiAgICBzbm1wZF9yZWdpc3Rlcl9jb25maWdfaGFuZGxlcigib3ZlcnJpZGUiLCBuZXRzbm1wX3BhcnNlX292ZXJyaWRlLCBOVUxMLCAgICAgLyogWFhYOiBmcmVlIGZ1bmMgKi8KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJbLXJ3XSBtaWJub2RlIHR5cGUgdmFsdWUiKTsKfQo=