LyogQ29weXJpZ2h0IDIwMDQtMjAwNSBUaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24gb3IgaXRzIGxpY2Vuc29ycywgYXMKICogYXBwbGljYWJsZS4KICoKICogTGljZW5zZWQgdW5kZXIgdGhlIEFwYWNoZSBMaWNlbnNlLCBWZXJzaW9uIDIuMCAodGhlICJMaWNlbnNlIik7CiAqIHlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2Ugd2l0aCB0aGUgTGljZW5zZS4KICogWW91IG1heSBvYnRhaW4gYSBjb3B5IG9mIHRoZSBMaWNlbnNlIGF0CiAqCiAqICAgICBodHRwOi8vd3d3LmFwYWNoZS5vcmcvbGljZW5zZXMvTElDRU5TRS0yLjAKICoKICogVW5sZXNzIHJlcXVpcmVkIGJ5IGFwcGxpY2FibGUgbGF3IG9yIGFncmVlZCB0byBpbiB3cml0aW5nLCBzb2Z0d2FyZQogKiBkaXN0cmlidXRlZCB1bmRlciB0aGUgTGljZW5zZSBpcyBkaXN0cmlidXRlZCBvbiBhbiAiQVMgSVMiIEJBU0lTLAogKiBXSVRIT1VUIFdBUlJBTlRJRVMgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZWl0aGVyIGV4cHJlc3Mgb3IgaW1wbGllZC4KICogU2VlIHRoZSBMaWNlbnNlIGZvciB0aGUgc3BlY2lmaWMgbGFuZ3VhZ2UgZ292ZXJuaW5nIHBlcm1pc3Npb25zIGFuZAogKiBsaW1pdGF0aW9ucyB1bmRlciB0aGUgTGljZW5zZS4KICovCgovKgogKiBtb2RfdmVyc2lvbi5jCiAqIEFsbG93IGNvbmRpdGlvbmFsIGNvbmZpZ3VyYXRpb24gZGVwZW5kaW5nIG9uIHRoZSBodHRwZCB2ZXJzaW9uCiAqCiAqIEFuZHLpIE1hbG8gKG5kL3BlcmxpZy5kZSksIEphbnVhcnkgMjAwNAogKgogKiBTb21lIHN0dWZmIGNvZGVkIGhlcmUgaXMgaGVhdmlseSBiYXNlZCBvbiB0aGUgY29yZSA8SWZNb2R1bGU+CiAqIGNvbnRhaW5lcnMuCiAqCiAqIFRoZSBtb2R1bGUgbWFrZXMgdGhlIGZvbGxvd2luZyBjb25mZ3VyYXRpb25zIHBvc3NpYmxlOgogKgogKiA8SWZWZXJzaW9uIG9wIG1ham9yLm1pbm9yLnBhdGNoPgogKiAgICAgIyBjb25kaXRpb25hbCBjb25maWcgaGVyZSAuLi4KICo8L0lmVmVyc2lvbj4KICoKICogd2hlcmUgIm9wIiBpcyBvbmUgb2Y6CiAqID0gLyA9PSAgICAgICBlcXVhbAogKiA+ICAgICAgICAgICAgZ3JlYXRlciB0aGFuCiAqID49ICAgICAgICAgICBncmVhdGVyIG9yIGVxdWFsCiAqIDwgICAgICAgICAgICBsZXNzIHRoYW4KICogPD0gICAgICAgICAgIGxlc3Mgb3IgZXF1YWwKICoKICogSWYgbWlub3IgdmVyc2lvbiBhbmQgcGF0Y2ggbGV2ZWwgYXJlIG9taXR0ZWQgdGhleSBhcmUgYXNzdW1lZCB0byBiZSAwLgogKgogKiBBbHRlcm5hdGl2ZWx5IHlvdSBjYW4gbWF0Y2ggdGhlIHdob2xlIHZlcnNpb24gKGluY2x1ZGluZyBzb21lIHZlbmRvci1hZGRlZAogKiBzdHJpbmcgb2YgdGhlIENPUkUgdmVyc2lvbiwgc2VlIGFwX3JlbGVhc2UuaCkgYWdhaW5zdCBhIHJlZ3VsYXIgZXhwcmVzc2lvbjoKICoKICogPElmVmVyc2lvbiBvcCByZWdleD4KICogICAgICMgY29uZGl0aW9uYWwgY29uZmlnIGhlcmUgLi4uCiAqPC9JZlZlcnNpb24+CiAqCiAqIHdoZXJlICJvcCIgaXMgb25lIG9mOgogKiA9IC8gPT0gICAgICAgbWF0Y2g7IHJlZ2V4IG11c3QgYmUgc3Vycm91bmRlZCBieSBzbGFzaGVzCiAqIH4gICAgICAgICAgICBtYXRjaDsgcmVnZXggTUFZIE5PVCBiZSBzdXJyb3VuZGVkIGJ5IHNsYXNoZXMKICoKICogTm90ZSB0aGF0IGFsbCBvcGVyYXRvcnMgbWF5IGJlIHByZWNlZWRlZCBieSBhbiBleGNsYW1hdGlvbiBtYXJrCiAqICh3aXRob3V0IHNwYWNlcykgaW4gb3JkZXIgdG8gcmV2ZXJzZSB0aGVpciBtZWFuaW5nLgogKgogKi8KCiNpbmNsdWRlICJhcHIuaCIKI2luY2x1ZGUgImFwcl9zdHJpbmdzLmgiCiNpbmNsdWRlICJhcHJfbGliLmgiCgojaW5jbHVkZSAiaHR0cGQuaCIKI2luY2x1ZGUgImh0dHBfY29uZmlnLmgiCiNpbmNsdWRlICJodHRwX2xvZy5oIgoKCi8qIG1vZHVsZSBzdHJ1Y3R1cmUgKi8KbW9kdWxlIEFQX01PRFVMRV9ERUNMQVJFX0RBVEEgdmVyc2lvbl9tb2R1bGU7CgovKiBxdWVyaWVkIGh0dHBkIHZlcnNpb24gKi8Kc3RhdGljIGFwX3ZlcnNpb25fdCBodHRwZF92ZXJzaW9uOwoKCi8qCiAqIGNvbXBhcmUgdGhlIHN1cHBsaWVkIHZlcnNpb24gd2l0aCB0aGUgY29yZSBvbmUKICovCnN0YXRpYyBpbnQgY29tcGFyZV92ZXJzaW9uKGNoYXIgKnZlcnNpb25fc3RyaW5nLCBjb25zdCBjaGFyICoqZXJyb3IpCnsKICAgIGNoYXIgKnAgPSB2ZXJzaW9uX3N0cmluZywgKmVwOwogICAgaW50IHZlcnNpb25bM10gPSB7MCwgMCwgMH07CiAgICBpbnQgYyA9IDA7CgogICAgKmVycm9yID0gIlZlcnNpb24gYXBwZWFycyB0byBiZSBpbnZhbGlkLiBJdCBtdXN0IGhhdmUgdGhlIGZvcm1hdCAiCiAgICAgICAgICAgICAibWFqb3JbLm1pbm9yWy5wYXRjaF1dIHdoZXJlIG1ham9yLCBtaW5vciBhbmQgcGF0Y2ggYXJlICIKICAgICAgICAgICAgICJudW1iZXJzLiI7CgogICAgaWYgKCFhcHJfaXNkaWdpdCgqcCkpIHsKICAgICAgICByZXR1cm4gMDsKICAgIH0KCiAgICAvKiBwYXJzZSBzdXBwbGllZCB2ZXJzaW9uICovCiAgICBlcCA9IHZlcnNpb25fc3RyaW5nICsgc3RybGVuKHZlcnNpb25fc3RyaW5nKTsKICAgIHdoaWxlIChwIDw9IGVwICYmIGMgPCAzKSB7CiAgICAgICAgaWYgKCpwID09ICcuJykgewogICAgICAgICAgICAqcCA9ICdcMCc7CiAgICAgICAgfQoKICAgICAgICBpZiAoISpwKSB7CiAgICAgICAgICAgIHZlcnNpb25bYysrXSA9IGF0b2kodmVyc2lvbl9zdHJpbmcpOwogICAgICAgICAgICB2ZXJzaW9uX3N0cmluZyA9ICsrcDsKICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgfQoKICAgICAgICBpZiAoIWFwcl9pc2RpZ2l0KCpwKSkgewogICAgICAgICAgICBicmVhazsKICAgICAgICB9CgogICAgICAgICsrcDsKICAgIH0KCiAgICBpZiAocCA8IGVwKSB7IC8qIHN5bnRheCBlcnJvciAqLwogICAgICAgIHJldHVybiAwOwogICAgfQoKICAgICplcnJvciA9IE5VTEw7CgogICAgaWYgICAgICAoaHR0cGRfdmVyc2lvbi5tYWpvciA+IHZlcnNpb25bMF0pIHsKICAgICAgICByZXR1cm4gMTsKICAgIH0KICAgIGVsc2UgaWYgKGh0dHBkX3ZlcnNpb24ubWFqb3IgPCB2ZXJzaW9uWzBdKSB7CiAgICAgICAgcmV0dXJuIC0xOwogICAgfQogICAgZWxzZSBpZiAoaHR0cGRfdmVyc2lvbi5taW5vciA+IHZlcnNpb25bMV0pIHsKICAgICAgICByZXR1cm4gMTsKICAgIH0KICAgIGVsc2UgaWYgKGh0dHBkX3ZlcnNpb24ubWlub3IgPCB2ZXJzaW9uWzFdKSB7CiAgICAgICAgcmV0dXJuIC0xOwogICAgfQogICAgZWxzZSBpZiAoaHR0cGRfdmVyc2lvbi5wYXRjaCA+IHZlcnNpb25bMl0pIHsKICAgICAgICByZXR1cm4gMTsKICAgIH0KICAgIGVsc2UgaWYgKGh0dHBkX3ZlcnNpb24ucGF0Y2ggPCB2ZXJzaW9uWzJdKSB7CiAgICAgICAgcmV0dXJuIC0xOwogICAgfQoKICAgIC8qIHNlZW1zIHRvIGJlIHRoZSBzYW1lICovCiAgICByZXR1cm4gMDsKfQoKLyoKICogbWF0Y2ggdmVyc2lvbiBhZ2FpbnN0IGEgcmVndWxhciBleHByZXNzaW9uCiAqLwpzdGF0aWMgaW50IG1hdGNoX3ZlcnNpb24oYXByX3Bvb2xfdCAqcG9vbCwgY2hhciAqdmVyc2lvbl9zdHJpbmcsCiAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjaGFyICoqZXJyb3IpCnsKICAgIGFwX3JlZ2V4X3QgKmNvbXBpbGVkOwogICAgY29uc3QgY2hhciAqdG9fbWF0Y2g7CiAgICBpbnQgcmM7CgogICAgY29tcGlsZWQgPSBhcF9wcmVnY29tcChwb29sLCB2ZXJzaW9uX3N0cmluZywgQVBfUkVHX0VYVEVOREVEKTsKICAgIGlmICghY29tcGlsZWQpIHsKICAgICAgICAqZXJyb3IgPSAiVW5hYmxlIHRvIGNvbXBpbGUgcmVndWxhciBleHByZXNzaW9uIjsKICAgICAgICByZXR1cm4gMDsKICAgIH0KCiAgICAqZXJyb3IgPSBOVUxMOwoKICAgIHRvX21hdGNoID0gYXByX3BzcHJpbnRmKHBvb2wsICIlZC4lZC4lZCVzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGh0dHBkX3ZlcnNpb24ubWFqb3IsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBodHRwZF92ZXJzaW9uLm1pbm9yLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgaHR0cGRfdmVyc2lvbi5wYXRjaCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGh0dHBkX3ZlcnNpb24uYWRkX3N0cmluZyk7CgogICAgcmMgPSAhYXBfcmVnZXhlYyhjb21waWxlZCwgdG9fbWF0Y2gsIDAsIE5VTEwsIDApOwoKICAgIGFwX3ByZWdmcmVlKHBvb2wsIGNvbXBpbGVkKTsKICAgIHJldHVybiByYzsKfQoKLyoKICogSW1wbGVtZW50cyB0aGUgPElmVmVyc2lvbj4gY29udGFpbmVyCiAqLwpzdGF0aWMgY29uc3QgY2hhciAqc3RhcnRfaWZ2ZXJzaW9uKGNtZF9wYXJtcyAqY21kLCB2b2lkICptY29uZmlnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgKmFyZzEsIGNvbnN0IGNoYXIgKmFyZzIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciAqYXJnMykKewogICAgY29uc3QgY2hhciAqZW5kcDsKICAgIGludCByZXZlcnNlID0gMCwgZG9uZSA9IDAsIG1hdGNoID0gMCwgY29tcGFyZTsKICAgIGNvbnN0IGNoYXIgKnAsICplcnJvcjsKICAgIGNoYXIgYzsKCiAgICAvKiBzdXBwbHlpbmcgb25lIGFyZ3VtZW50IGlzIHBvc3NpYmxlLCB3ZSBhc3N1bWUgYW4gZXF1YWxpdHkgY2hlY2sgdGhlbiAqLwogICAgaWYgKCFhcmcyKSB7CiAgICAgICAgYXJnMiA9IGFyZzE7CiAgICAgICAgYXJnMSA9ICI9IjsKICAgIH0KCiAgICAvKiBzdXJyb3VuZGluZyBxdW90ZXMgd2l0aG91dCBvcGVyYXRvciAqLwogICAgaWYgKCFhcmczICYmICphcmcyID09ICc+JyAmJiAhYXJnMlsxXSkgewogICAgICAgIGFyZzMgPSAiPiI7CiAgICAgICAgYXJnMiA9IGFyZzE7CiAgICAgICAgYXJnMSA9ICI9IjsKICAgIH0KCiAgICAvKiB0aGUgdGhpcmQgYXJndW1lbnQgbWFrZXMgdmVyc2lvbiBzdXJyb3VuZGluZyBxdW90ZXMgcGx1cyBvcGVyYXRvcgogICAgICogcG9zc2libGUuCiAgICAgKi8KICAgIGVuZHAgPSBhcmcyICsgc3RybGVuKGFyZzIpOwogICAgaWYgKCAgIGVuZHAgPT0gYXJnMgogICAgICAgIHx8ICghKGFyZzMgJiYgKmFyZzMgPT0gJz4nICYmICFhcmczWzFdKSAmJiAqLS1lbmRwICE9ICc+JykpIHsKICAgICAgICByZXR1cm4gYXByX3BzdHJjYXQoY21kLT5wb29sLCBjbWQtPmNtZC0+bmFtZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIj4gZGlyZWN0aXZlIG1pc3NpbmcgY2xvc2luZyAnPiciLCBOVUxMKTsKICAgIH0KCiAgICBwID0gYXJnMTsKICAgIGlmICgqcCA9PSAnIScpIHsKICAgICAgICByZXZlcnNlID0gMTsKICAgICAgICBpZiAocFsxXSkgewogICAgICAgICAgICArK3A7CiAgICAgICAgfQogICAgfQoKICAgIGMgPSAqcCsrOwogICAgaWYgKCEqcCB8fCAoKnAgPT0gJz0nICYmICFwWzFdICYmIGMgIT0gJ34nKSkgewogICAgICAgIGlmICghaHR0cGRfdmVyc2lvbi5tYWpvcikgewogICAgICAgICAgICBhcF9nZXRfc2VydmVyX3JldmlzaW9uKCZodHRwZF92ZXJzaW9uKTsKICAgICAgICB9CgogICAgICAgIGRvbmUgPSAxOwogICAgICAgIHN3aXRjaCAoYykgewogICAgICAgIGNhc2UgJz0nOgogICAgICAgICAgICAvKiBub3JtYWwgY29tcGFyaXNvbiAqLwogICAgICAgICAgICBpZiAoKmFyZzIgIT0gJy8nKSB7CiAgICAgICAgICAgICAgICBjb21wYXJlID0gY29tcGFyZV92ZXJzaW9uKGFwcl9wc3RybWVtZHVwKGNtZC0+cG9vbCwgYXJnMiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZW5kcC1hcmcyKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJmVycm9yKTsKICAgICAgICAgICAgICAgIGlmIChlcnJvcikgewogICAgICAgICAgICAgICAgICAgIHJldHVybiBlcnJvcjsKICAgICAgICAgICAgICAgIH0KCiAgICAgICAgICAgICAgICBtYXRjaCA9ICFjb21wYXJlOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KCiAgICAgICAgICAgIC8qIHJlZ2V4cCBvdGhlcndpc2UgKi8KICAgICAgICAgICAgaWYgKGVuZHAgPT0gKythcmcyIHx8ICotLWVuZHAgIT0gJy8nKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gIk1pc3NpbmcgZGVsaW1pdGluZyAvIG9mIHJlZ3VsYXIgZXhwcmVzc2lvbi4iOwogICAgICAgICAgICB9CgogICAgICAgIGNhc2UgJ34nOgogICAgICAgICAgICAvKiByZWd1bGFyIGV4cHJlc3Npb24gKi8KICAgICAgICAgICAgbWF0Y2ggPSBtYXRjaF92ZXJzaW9uKGNtZC0+cG9vbCwgYXByX3BzdHJtZW1kdXAoY21kLT5wb29sLCBhcmcyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbmRwLWFyZzIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJmVycm9yKTsKICAgICAgICAgICAgaWYgKGVycm9yKSB7CiAgICAgICAgICAgICAgICByZXR1cm4gZXJyb3I7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgYnJlYWs7CgogICAgICAgIGNhc2UgJzwnOgogICAgICAgICAgICBjb21wYXJlID0gY29tcGFyZV92ZXJzaW9uKGFwcl9wc3RybWVtZHVwKGNtZC0+cG9vbCwgYXJnMiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbmRwLWFyZzIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICZlcnJvcik7CiAgICAgICAgICAgIGlmIChlcnJvcikgewogICAgICAgICAgICAgICAgcmV0dXJuIGVycm9yOwogICAgICAgICAgICB9CgogICAgICAgICAgICBtYXRjaCA9ICgoLTEgPT0gY29tcGFyZSkgfHwgKCpwICYmICFjb21wYXJlKSk7CiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBjYXNlICc+JzoKICAgICAgICAgICAgY29tcGFyZSA9IGNvbXBhcmVfdmVyc2lvbihhcHJfcHN0cm1lbWR1cChjbWQtPnBvb2wsIGFyZzIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZW5kcC1hcmcyKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmZXJyb3IpOwogICAgICAgICAgICBpZiAoZXJyb3IpIHsKICAgICAgICAgICAgICAgIHJldHVybiBlcnJvcjsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgbWF0Y2ggPSAoKDEgPT0gY29tcGFyZSkgfHwgKCpwICYmICFjb21wYXJlKSk7CiAgICAgICAgICAgIGJyZWFrOwoKICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICBkb25lID0gMDsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgfQogICAgfQoKICAgIGlmICghZG9uZSkgewogICAgICAgIHJldHVybiBhcHJfcHN0cmNhdChjbWQtPnBvb2wsICJ1bnJlY29nbml6ZWQgb3BlcmF0b3IgJyIsIGFyZzEsICInIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgTlVMTCk7CiAgICB9CgogICAgaWYgKCghcmV2ZXJzZSAmJiBtYXRjaCkgfHwgKHJldmVyc2UgJiYgIW1hdGNoKSkgewogICAgICAgIGFwX2RpcmVjdGl2ZV90ICpwYXJlbnQgPSBOVUxMOwogICAgICAgIGFwX2RpcmVjdGl2ZV90ICpjdXJyZW50ID0gTlVMTDsKICAgICAgICBjb25zdCBjaGFyICpyZXR2YWw7CgogICAgICAgIHJldHZhbCA9IGFwX2J1aWxkX2NvbnRfY29uZmlnKGNtZC0+cG9vbCwgY21kLT50ZW1wX3Bvb2wsIGNtZCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAmY3VycmVudCwgJnBhcmVudCwgIjxJZlZlcnNpb24iKTsKICAgICAgICAqKGFwX2RpcmVjdGl2ZV90ICoqKW1jb25maWcgPSBjdXJyZW50OwogICAgICAgIHJldHVybiByZXR2YWw7CiAgICB9CgogICAgKihhcF9kaXJlY3RpdmVfdCAqKiltY29uZmlnID0gTlVMTDsKICAgIHJldHVybiBhcF9zb2FrX2VuZF9jb250YWluZXIoY21kLCAiPElmVmVyc2lvbiIpOwp9CgpzdGF0aWMgY29uc3QgY29tbWFuZF9yZWMgdmVyc2lvbl9jbWRzW10gPSB7CiAgICBBUF9JTklUX1RBS0UxMjMoIjxJZlZlcnNpb24iLCBzdGFydF9pZnZlcnNpb24sIE5VTEwsIEVYRUNfT05fUkVBRCB8IE9SX0FMTCwKICAgICAgICAgICAgICAgICAgICAiYSBjb21wYXJpc29uIG9wZXJhdG9yLCBhIHZlcnNpb24gKGFuZCBhIGRlbGltaXRlcikiKSwKICAgIHsgTlVMTCB9Cn07Cgptb2R1bGUgQVBfTU9EVUxFX0RFQ0xBUkVfREFUQSB2ZXJzaW9uX21vZHVsZSA9CnsKICAgIFNUQU5EQVJEMjBfTU9EVUxFX1NUVUZGLAogICAgTlVMTCwgICAgICAgICAgICAgLyogZGlyIGNvbmZpZyBjcmVhdGVyICovCiAgICBOVUxMLCAgICAgICAgICAgICAvKiBkaXIgbWVyZ2VyIC0tLSBkZWZhdWx0IGlzIHRvIG92ZXJyaWRlICovCiAgICBOVUxMLCAgICAgICAgICAgICAvKiBzZXJ2ZXIgY29uZmlnICovCiAgICBOVUxMLCAgICAgICAgICAgICAvKiBtZXJnZSBzZXJ2ZXIgY29uZmlncyAqLwogICAgdmVyc2lvbl9jbWRzLCAgICAgLyogY29tbWFuZCBhcHJfdGFibGVfdCAqLwogICAgTlVMTCwgICAgICAgICAgICAgLyogcmVnaXN0ZXIgaG9va3MgKi8KfTsK