LyoKICogQ29weXJpZ2h0IChjKSAxOTgzLCAxOTkzCiAqCVRoZSBSZWdlbnRzIG9mIHRoZSBVbml2ZXJzaXR5IG9mIENhbGlmb3JuaWEuICBBbGwgcmlnaHRzIHJlc2VydmVkLgogKgogKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCiAqIGFyZSBtZXQ6CiAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CiAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluIHRoZQogKiAgICBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUgZGlzdHJpYnV0aW9uLgogKiAzLiBBbGwgYWR2ZXJ0aXNpbmcgbWF0ZXJpYWxzIG1lbnRpb25pbmcgZmVhdHVyZXMgb3IgdXNlIG9mIHRoaXMgc29mdHdhcmUKICogICAgbXVzdCBkaXNwbGF5IHRoZSBmb2xsb3dpbmcgYWNrbm93bGVkZ2VtZW50OgogKglUaGlzIHByb2R1Y3QgaW5jbHVkZXMgc29mdHdhcmUgZGV2ZWxvcGVkIGJ5IHRoZSBVbml2ZXJzaXR5IG9mCiAqCUNhbGlmb3JuaWEsIEJlcmtlbGV5IGFuZCBpdHMgY29udHJpYnV0b3JzLgogKiA0LiBOZWl0aGVyIHRoZSBuYW1lIG9mIHRoZSBVbml2ZXJzaXR5IG5vciB0aGUgbmFtZXMgb2YgaXRzIGNvbnRyaWJ1dG9ycwogKiAgICBtYXkgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUKICogICAgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCiAqCiAqIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIFJFR0VOVFMgQU5EIENPTlRSSUJVVE9SUyBgYEFTIElTJycgQU5ECiAqIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRQogKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRQogKiBBUkUgRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBSRUdFTlRTIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUKICogRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwKICogREFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMKICogT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pCiAqIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUCiAqIExJQUJJTElUWSwgT1IgVE9SVCAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkKICogT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRgogKiBTVUNIIERBTUFHRS4KICoKICogMTk5OS0wMi0yMiBBcmthZGl1c3ogTWm2a2lld2ljeiA8bWlzaWVrQHBsZC5PUkcuUEw+CiAqIC0gYWRkZWQgTmF0aXZlIExhbmd1YWdlIFN1cHBvcnQKICogU3VuIE1hciAyMSAxOTk5IC0gQXJuYWxkbyBDYXJ2YWxobyBkZSBNZWxvIDxhY21lQGNvbmVjdGl2YS5jb20uYnI+CiAqIC0gZml4ZWQgc3RyZXJyKGVycm5vKSBpbiBnZXR0ZXh0IGNhbGxzCiAqLwoKI2luY2x1ZGUgPGVycm5vLmg+CiNpbmNsdWRlIDx1bmlzdGQuaD4KI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8dGltZS5oPgojaW5jbHVkZSA8c3RkaW8uaD4KI2luY2x1ZGUgPGN0eXBlLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUgPHN0cmluZ3MuaD4KI2luY2x1ZGUgPHN5cy90eXBlcy5oPgojaW5jbHVkZSA8c3lzL3NvY2tldC5oPgojaW5jbHVkZSA8c3lzL3VuLmg+CiNpbmNsdWRlICJubHMuaCIKCiNkZWZpbmUJU1lTTE9HX05BTUVTCiNpbmNsdWRlIDxzeXNsb2cuaD4KCmludAlkZWNvZGUgX19QKChjaGFyICosIENPREUgKikpOwppbnQJcGVuY29kZSBfX1AoKGNoYXIgKikpOwp2b2lkCXVzYWdlIF9fUCgodm9pZCkpOwoKc3RhdGljIGludCBvcHRkID0gMDsKCnN0YXRpYyBpbnQKbXlvcGVubG9nKGNvbnN0IGNoYXIgKnNvY2spIHsKICAgICAgIGludCBmZDsKICAgICAgIHN0YXRpYyBzdHJ1Y3Qgc29ja2FkZHJfdW4gc19hZGRyOyAvKiBBRl9VTklYIGFkZHJlc3Mgb2YgbG9jYWwgbG9nZ2VyICovCgogICAgICAgaWYgKHN0cmxlbihzb2NrKSA+PSBzaXplb2Yoc19hZGRyLnN1bl9wYXRoKSkgewoJICAgICAgIHByaW50ZiAoXygibG9nZ2VyOiBvcGVubG9nOiBwYXRobmFtZSB0b28gbG9uZ1xuIikpOwoJICAgICAgIGV4aXQoMSk7CiAgICAgICB9CgogICAgICAgc19hZGRyLnN1bl9mYW1pbHkgPSBBRl9VTklYOwogICAgICAgKHZvaWQpc3RyY3B5KHNfYWRkci5zdW5fcGF0aCwgc29jayk7CgogICAgICAgaWYgKChmZCA9IHNvY2tldChBRl9VTklYLCBvcHRkID8gU09DS19ER1JBTSA6IFNPQ0tfU1RSRUFNLCAwKSkgPT0gLTEpIHsKICAgICAgICAgICAgICAgcHJpbnRmIChfKCJzb2NrZXQ6ICVzLlxuIiksIHN0cmVycm9yKGVycm5vKSk7CiAgICAgICAgICAgICAgIGV4aXQgKDEpOwogICAgICAgfQoKICAgICAgIGlmIChjb25uZWN0KGZkLCAoc3RydWN0IHNvY2thZGRyICopICZzX2FkZHIsIHNpemVvZihzX2FkZHIpKSA9PSAtMSkgewogICAgICAgICAgICAgICBwcmludGYgKF8oImNvbm5lY3Q6ICVzLlxuIiksIHN0cmVycm9yKGVycm5vKSk7CiAgICAgICAgICAgICAgIGV4aXQgKDEpOwogICAgICAgfQogICAgICAgcmV0dXJuIGZkOwp9CgpzdGF0aWMgdm9pZApteXN5c2xvZyhpbnQgZmQsIGludCBsb2dmbGFncywgaW50IHByaSwgY2hhciAqdGFnLCBjaGFyICptc2cpIHsKICAgICAgIGNoYXIgYnVmWzEwMDBdLCBwaWRbMzBdLCAqY3AsICp0cDsKICAgICAgIHRpbWVfdCBub3c7CgogICAgICAgaWYgKGZkID4gLTEpIHsKICAgICAgICAgICAgICAgaWYgKGxvZ2ZsYWdzICYgTE9HX1BJRCkKICAgICAgICAgICAgICAgICAgICAgICBzbnByaW50ZiAocGlkLCBzaXplb2YocGlkKSwgIlslZF0iLCBnZXRwaWQoKSk7CgkgICAgICAgZWxzZQoJCSAgICAgICBwaWRbMF0gPSAwOwogICAgICAgICAgICAgICBpZiAodGFnKQoJCSAgICAgICBjcCA9IHRhZzsKCSAgICAgICBlbHNlIHsKCQkgICAgICAgY3AgPSBnZXRsb2dpbigpOwoJCSAgICAgICBpZiAoIWNwKQoJCQkgICAgICAgY3AgPSAiPHNvbWVvbmU+IjsKCSAgICAgICB9CiAgICAgICAgICAgICAgICh2b2lkKXRpbWUoJm5vdyk7CgkgICAgICAgdHAgPSBjdGltZSgmbm93KSs0OwoKICAgICAgICAgICAgICAgc25wcmludGYoYnVmLCBzaXplb2YoYnVmKSwgIjwlZD4lLjE1cyAlLjIwMHMlczogJS40MDBzIiwKCQkJcHJpLCB0cCwgY3AsIHBpZCwgbXNnKTsKCiAgICAgICAgICAgICAgIGlmICh3cml0ZShmZCwgYnVmLCBzdHJsZW4oYnVmKSsxKSA8IDApCiAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuOyAvKiBlcnJvciAqLwogICAgICAgfQp9CgovKgogKiBsb2dnZXIgLS0gcmVhZCBhbmQgbG9nIHV0aWxpdHkKICoKICoJUmVhZHMgZnJvbSBhbiBpbnB1dCBhbmQgYXJyYW5nZXMgdG8gd3JpdGUgdGhlIHJlc3VsdCBvbiB0aGUgc3lzdGVtCiAqCWxvZy4KICovCmludAptYWluKGludCBhcmdjLCBjaGFyICoqYXJndikgewoJaW50IGNoLCBsb2dmbGFncywgcHJpOwoJY2hhciAqdGFnLCBidWZbMTAyNF07CgljaGFyICp1c29jayA9IE5VTEw7CglpbnQgTG9nU29jayA9IC0xOwoKCXNldGxvY2FsZShMQ19BTEwsICIiKTsKCWJpbmR0ZXh0ZG9tYWluKFBBQ0tBR0UsIExPQ0FMRURJUik7Cgl0ZXh0ZG9tYWluKFBBQ0tBR0UpOwoKCXRhZyA9IE5VTEw7CglwcmkgPSBMT0dfTk9USUNFOwoJbG9nZmxhZ3MgPSAwOwoJd2hpbGUgKChjaCA9IGdldG9wdChhcmdjLCBhcmd2LCAiZjppcDpzdDp1OmQiKSkgIT0gLTEpCgkJc3dpdGNoKChjaGFyKWNoKSB7CgkJY2FzZSAnZic6CQkvKiBmaWxlIHRvIGxvZyAqLwoJCQlpZiAoZnJlb3BlbihvcHRhcmcsICJyIiwgc3RkaW4pID09IE5VTEwpIHsKCQkJCWludCBlcnJzdiA9IGVycm5vOwoJCQkJKHZvaWQpZnByaW50ZihzdGRlcnIsIF8oImxvZ2dlcjogJXM6ICVzLlxuIiksCgkJCQkgICAgb3B0YXJnLCBzdHJlcnJvcihlcnJzdikpOwoJCQkJZXhpdCgxKTsKCQkJfQoJCQlicmVhazsKCQljYXNlICdpJzoJCS8qIGxvZyBwcm9jZXNzIGlkIGFsc28gKi8KCQkJbG9nZmxhZ3MgfD0gTE9HX1BJRDsKCQkJYnJlYWs7CgkJY2FzZSAncCc6CQkvKiBwcmlvcml0eSAqLwoJCQlwcmkgPSBwZW5jb2RlKG9wdGFyZyk7CgkJCWJyZWFrOwoJCWNhc2UgJ3MnOgkJLyogbG9nIHRvIHN0YW5kYXJkIGVycm9yICovCgkJCWxvZ2ZsYWdzIHw9IExPR19QRVJST1I7CgkJCWJyZWFrOwoJCWNhc2UgJ3QnOgkJLyogdGFnICovCgkJCXRhZyA9IG9wdGFyZzsKCQkJYnJlYWs7CgkJY2FzZSAndSc6CQkvKiB1bml4IHNvY2tldCAqLwoJCQl1c29jayA9IG9wdGFyZzsKCQkJYnJlYWs7CgkJY2FzZSAnZCc6CgkJCW9wdGQgPSAxOwkvKiB1c2UgZGF0YWdyYW1zICovCgkJCWJyZWFrOwoJCWNhc2UgJz8nOgoJCWRlZmF1bHQ6CgkJCXVzYWdlKCk7CgkJfQoJYXJnYyAtPSBvcHRpbmQ7Cglhcmd2ICs9IG9wdGluZDsKCgkvKiBzZXR1cCBmb3IgbG9nZ2luZyAqLwoJaWYgKCF1c29jaykKCQlvcGVubG9nKHRhZyA/IHRhZyA6IGdldGxvZ2luKCksIGxvZ2ZsYWdzLCAwKTsKCWVsc2UKCQlMb2dTb2NrID0gbXlvcGVubG9nKHVzb2NrKTsKCgkodm9pZCkgZmNsb3NlKHN0ZG91dCk7CgoJLyogbG9nIGlucHV0IGxpbmUgaWYgYXBwcm9wcmlhdGUgKi8KCWlmIChhcmdjID4gMCkgewoJCXJlZ2lzdGVyIGNoYXIgKnAsICplbmRwOwoJCWludCBsZW47CgoJCWZvciAocCA9IGJ1ZiwgZW5kcCA9IGJ1ZiArIHNpemVvZihidWYpIC0gMjsgKmFyZ3Y7KSB7CgkJCWxlbiA9IHN0cmxlbigqYXJndik7CgkJCWlmIChwICsgbGVuID4gZW5kcCAmJiBwID4gYnVmKSB7CgkJCSAgICBpZiAoIXVzb2NrKQoJCQkJc3lzbG9nKHByaSwgIiVzIiwgYnVmKTsKCQkJICAgIGVsc2UKCQkJCW15c3lzbG9nKExvZ1NvY2ssIGxvZ2ZsYWdzLCBwcmksIHRhZywgYnVmKTsKCQkJCXAgPSBidWY7CgkJCX0KCQkJaWYgKGxlbiA+IHNpemVvZihidWYpIC0gMSkgewoJCQkgICAgaWYgKCF1c29jaykKCQkJCXN5c2xvZyhwcmksICIlcyIsICphcmd2KyspOwoJCQkgICAgZWxzZQoJCQkJbXlzeXNsb2coTG9nU29jaywgbG9nZmxhZ3MsIHByaSwgdGFnLCAqYXJndisrKTsKCQkJfSBlbHNlIHsKCQkJCWlmIChwICE9IGJ1ZikKCQkJCQkqcCsrID0gJyAnOwoJCQkJbWVtbW92ZShwLCAqYXJndisrLCBsZW4pOwoJCQkJKihwICs9IGxlbikgPSAnXDAnOwoJCQl9CgkJfQoJCWlmIChwICE9IGJ1ZikgewoJCSAgICBpZiAoIXVzb2NrKQoJCQlzeXNsb2cocHJpLCAiJXMiLCBidWYpOwoJCSAgICBlbHNlCgkJCW15c3lzbG9nKExvZ1NvY2ssIGxvZ2ZsYWdzLCBwcmksIHRhZywgYnVmKTsKCQl9Cgl9IGVsc2UKCQl3aGlsZSAoZmdldHMoYnVmLCBzaXplb2YoYnVmKSwgc3RkaW4pICE9IE5VTEwpIHsKCQkgICAgLyogZ2xpYmMgaXMgYnVnZ3kgYW5kIGFkZHMgYW4gYWRkaXRpb25hbCBuZXdsaW5lLAoJCSAgICAgICBzbyB3ZSBoYXZlIHRvIHJlbW92ZSBpdCBoZXJlIHVudGlsIGdsaWJjIGlzIGZpeGVkICovCgkJICAgIGludCBsZW4gPSBzdHJsZW4oYnVmKTsKCgkJICAgIGlmIChsZW4gPiAwICYmIGJ1ZltsZW4gLSAxXSA9PSAnXG4nKQoJCQkgICAgYnVmW2xlbiAtIDFdID0gJ1wwJzsKCgkJICAgIGlmICghdXNvY2spCgkJCXN5c2xvZyhwcmksICIlcyIsIGJ1Zik7CgkJICAgIGVsc2UKCQkJbXlzeXNsb2coTG9nU29jaywgbG9nZmxhZ3MsIHByaSwgdGFnLCBidWYpOwoJCX0KCWlmICghdXNvY2spCgkJY2xvc2Vsb2coKTsKCWVsc2UKCQljbG9zZShMb2dTb2NrKTsKCWV4aXQoMCk7Cn0KCi8qCiAqICBEZWNvZGUgYSBzeW1ib2xpYyBuYW1lIHRvIGEgbnVtZXJpYyB2YWx1ZQogKi8KaW50CnBlbmNvZGUocykKCXJlZ2lzdGVyIGNoYXIgKnM7CnsKCWNoYXIgKnNhdmU7CglpbnQgZmFjLCBsZXY7CgoJZm9yIChzYXZlID0gczsgKnMgJiYgKnMgIT0gJy4nOyArK3MpOwoJaWYgKCpzKSB7CgkJKnMgPSAnXDAnOwoJCWZhYyA9IGRlY29kZShzYXZlLCBmYWNpbGl0eW5hbWVzKTsKCQlpZiAoZmFjIDwgMCkgewoJCQkodm9pZClmcHJpbnRmKHN0ZGVyciwKCQkJICAgIF8oImxvZ2dlcjogdW5rbm93biBmYWNpbGl0eSBuYW1lOiAlcy5cbiIpLCBzYXZlKTsKCQkJZXhpdCgxKTsKCQl9CgkJKnMrKyA9ICcuJzsKCX0KCWVsc2UgewoJCWZhYyA9IExPR19VU0VSOwoJCXMgPSBzYXZlOwoJfQoJbGV2ID0gZGVjb2RlKHMsIHByaW9yaXR5bmFtZXMpOwoJaWYgKGxldiA8IDApIHsKCQkodm9pZClmcHJpbnRmKHN0ZGVyciwKCQkgICAgXygibG9nZ2VyOiB1bmtub3duIHByaW9yaXR5IG5hbWU6ICVzLlxuIiksIHNhdmUpOwoJCWV4aXQoMSk7Cgl9CglyZXR1cm4gKChsZXYgJiBMT0dfUFJJTUFTSykgfCAoZmFjICYgTE9HX0ZBQ01BU0spKTsKfQoKaW50CmRlY29kZShuYW1lLCBjb2RldGFiKQoJY2hhciAqbmFtZTsKCUNPREUgKmNvZGV0YWI7CnsKCXJlZ2lzdGVyIENPREUgKmM7CgoJaWYgKGlzZGlnaXQoKm5hbWUpKQoJCXJldHVybiAoYXRvaShuYW1lKSk7CgoJZm9yIChjID0gY29kZXRhYjsgYy0+Y19uYW1lOyBjKyspCgkJaWYgKCFzdHJjYXNlY21wKG5hbWUsIGMtPmNfbmFtZSkpCgkJCXJldHVybiAoYy0+Y192YWwpOwoKCXJldHVybiAoLTEpOwp9Cgp2b2lkCnVzYWdlKCkKewoJKHZvaWQpZnByaW50ZihzdGRlcnIsCgkgICAgXygidXNhZ2U6IGxvZ2dlciBbLWlzXSBbLWYgZmlsZV0gWy1wIHByaV0gWy10IHRhZ10gWy11IHNvY2tldF0gWyBtZXNzYWdlIC4uLiBdXG4iKSk7CglleGl0KDEpOwp9Cg==