LyoKICogKEMpIENvcHlyaWdodCAyMDAyCiAqIFN05HVibGkgRmF2ZXJnZXMgLSA8d3d3LnN0YXVibGkuY29tPgogKiBQaWVycmUgQVVCRVJUICBwLmF1YmVydEBzdGF1YmxpLmNvbQogKgogKiBTZWUgZmlsZSBDUkVESVRTIGZvciBsaXN0IG9mIHBlb3BsZSB3aG8gY29udHJpYnV0ZWQgdG8gdGhpcwogKiBwcm9qZWN0LgogKgogKiBUaGlzIHByb2dyYW0gaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIgdmVyc2lvbiAyIG9mCiAqIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZQogKiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiBhbG9uZyB3aXRoIHRoaXMgcHJvZ3JhbTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQogKiBGb3VuZGF0aW9uLCBJbmMuLCA1OSBUZW1wbGUgUGxhY2UsIFN1aXRlIDMzMCwgQm9zdG9uLAogKiBNQSAwMjExMS0xMzA3IFVTQQogKi8KCi8qCiAqIERvcyBmbG9wcHkgc3VwcG9ydAogKi8KCiNpbmNsdWRlIDxjb21tb24uaD4KI2luY2x1ZGUgPGNvbmZpZy5oPgojaW5jbHVkZSA8Y29tbWFuZC5oPgojaW5jbHVkZSA8ZmRjLmg+CgojaWYgKENPTkZJR19DT01NQU5EUyAmIENGR19DTURfRkRPUykKCi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICogZG9fZmRvc2Jvb3QgLS0KICotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogKi8KaW50IGRvX2Zkb3Nib290KGNtZF90YmxfdCAqY21kdHAsIGludCBmbGFnLCBpbnQgYXJnYywgY2hhciAqYXJndltdKQp7CiAgICBjaGFyICpuYW1lOwogICAgY2hhciAqZXA7CiAgICBpbnQgc2l6ZTsKICAgIGludCByY29kZSA9IDA7CiAgICBjaGFyIGJ1ZiBbMTJdOwogICAgaW50IGRyaXZlID0gQ0ZHX0ZEQ19EUklWRV9OVU1CRVI7CgogICAgLyogcHJlLXNldCBsb2FkX2FkZHIgKi8KICAgIGlmICgoZXAgPSBnZXRlbnYoImxvYWRhZGRyIikpICE9IE5VTEwpIHsKCWxvYWRfYWRkciA9IHNpbXBsZV9zdHJ0b3VsKGVwLCBOVUxMLCAxNik7CiAgICB9CgogICAgLyogcHJlLXNldCBCb290IGZpbGUgbmFtZSAqLwogICAgaWYgKChuYW1lID0gZ2V0ZW52KCJib290ZmlsZSIpKSA9PSBOVUxMKSB7CgluYW1lID0gInVJbWFnZSI7CiAgICB9CgogICAgc3dpdGNoIChhcmdjKSB7CiAgICBjYXNlIDE6CglicmVhazsKICAgIGNhc2UgMjoKCS8qIG9ubHkgb25lIGFyZyAtIGFjY2VwdCB0d28gZm9ybXM6CgkgKiBqdXN0IGxvYWQgYWRkcmVzcywgb3IganVzdCBib290IGZpbGUgbmFtZS4KCSAqIFRoZSBsYXR0ZXIgZm9ybSBtdXN0IGJlIHdyaXR0ZW4gImZpbGVuYW1lIiBoZXJlLgoJICovCglpZiAoYXJndlsxXVswXSA9PSAnIicpIHsJLyoganVzdCBib290IGZpbGVuYW1lICovCgkgICAgbmFtZSA9IGFyZ3YgWzFdOwoJfSBlbHNlIHsJCQkvKiBsb2FkIGFkZHJlc3MJKi8KCSAgICBsb2FkX2FkZHIgPSBzaW1wbGVfc3RydG91bChhcmd2WzFdLCBOVUxMLCAxNik7Cgl9CglicmVhazsKICAgIGNhc2UgMzoKCWxvYWRfYWRkciA9IHNpbXBsZV9zdHJ0b3VsKGFyZ3ZbMV0sIE5VTEwsIDE2KTsKCW5hbWUgPSBhcmd2IFsyXTsKCWJyZWFrOwogICAgZGVmYXVsdDoKCXByaW50ZiAoIlVzYWdlOlxuJXNcbiIsIGNtZHRwLT51c2FnZSk7CglicmVhazsKICAgIH0KCiAgICAvKiBJbml0IHBoeXNpY2FsIGxheWVyICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KICAgIGlmICghZmRjX2Zkb3NfaW5pdCAoZHJpdmUpKSB7CglyZXR1cm4gKC0xKTsKICAgIH0KCiAgICAvKiBPcGVuIGZpbGUgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KICAgIGlmIChkb3Nfb3BlbiAobmFtZSkgPCAwKSB7CglwcmludGYgKCJVbmFibGUgdG8gb3BlbiAlc1xuIiwgbmFtZSk7CglyZXR1cm4gMTsKICAgIH0KICAgIGlmICgoc2l6ZSA9IGRvc19yZWFkIChsb2FkX2FkZHIpKSA8IDApIHsKCXByaW50ZiAoImJvb3QgZXJyb3JcbiIpOwoJcmV0dXJuIDE7CiAgICB9CiAgICBmbHVzaF9jYWNoZSAobG9hZF9hZGRyLCBzaXplKTsKCiAgICBzcHJpbnRmKGJ1ZiwgIiV4Iiwgc2l6ZSk7CiAgICBzZXRlbnYoImZpbGVzaXplIiwgYnVmKTsKCiAgICBwcmludGYoIkZsb3BweSBET1MgbG9hZCBjb21wbGV0ZTogJWQgYnl0ZXMgbG9hZGVkIHRvIDB4JWx4XG4iLAoJICAgc2l6ZSwgbG9hZF9hZGRyKTsKCiAgICAvKiBDaGVjayBpZiB3ZSBzaG91bGQgYXR0ZW1wdCBhbiBhdXRvLXN0YXJ0ICovCiAgICBpZiAoKChlcCA9IGdldGVudigiYXV0b3N0YXJ0IikpICE9IE5VTEwpICYmIChzdHJjbXAoZXAsInllcyIpID09IDApKSB7CgljaGFyICpsb2NhbF9hcmdzWzJdOwoJZXh0ZXJuIGludCBkb19ib290bSAoY21kX3RibF90ICosIGludCwgaW50LCBjaGFyICpbXSk7Cglsb2NhbF9hcmdzWzBdID0gYXJndlswXTsKCWxvY2FsX2FyZ3NbMV0gPSBOVUxMOwoJcHJpbnRmICgiQXV0b21hdGljIGJvb3Qgb2YgaW1hZ2UgYXQgYWRkciAweCUwOGxYIC4uLlxuIiwgbG9hZF9hZGRyKTsKCXJjb2RlID0gZG9fYm9vdG0gKGNtZHRwLCAwLCAxLCBsb2NhbF9hcmdzKTsKICAgIH0KICAgIHJldHVybiByY29kZTsKfQoKLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogKiBkb19mZG9zbHMgLS0KICotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogKi8KaW50IGRvX2Zkb3NscyhjbWRfdGJsX3QgKmNtZHRwLCBpbnQgZmxhZywgaW50IGFyZ2MsIGNoYXIgKmFyZ3ZbXSkKewogICAgY2hhciAqcGF0aCA9ICIiOwogICAgaW50IGRyaXZlID0gQ0ZHX0ZEQ19EUklWRV9OVU1CRVI7CgogICAgc3dpdGNoIChhcmdjKSB7CiAgICBjYXNlIDE6CglicmVhazsKICAgIGNhc2UgMjoKCXBhdGggPSBhcmd2IFsxXTsKCWJyZWFrOwogICAgfQoKICAgIC8qIEluaXQgcGh5c2ljYWwgbGF5ZXIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqLwogICAgaWYgKCFmZGNfZmRvc19pbml0IChkcml2ZSkpIHsKCXJldHVybiAoLTEpOwogICAgfQogICAgLyogT3BlbiBkaXJlY3RvcnkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICovCiAgICBpZiAoZG9zX29wZW4gKHBhdGgpIDwgMCkgewoJcHJpbnRmICgiVW5hYmxlIHRvIG9wZW4gJXNcbiIsIHBhdGgpOwoJcmV0dXJuIDE7CiAgICB9CiAgICByZXR1cm4gKGRvc19kaXIgKCkpOwp9CgpVX0JPT1RfQ01EKAoJZmRvc2Jvb3QsCTMsCTAsCWRvX2Zkb3Nib290LAoJImZkb3Nib290LSBib290IGZyb20gYSBkb3MgZmxvcHB5IGZpbGVcbiIsCgkiW2xvYWRBZGRyXSBbZmlsZW5hbWVdXG4iCik7CgpVX0JPT1RfQ01EKAoJZmRvc2xzLAkyLAkwLAlkb19mZG9zbHMsCgkiZmRvc2xzICAtIGxpc3QgZmlsZXMgaW4gYSBkaXJlY3RvcnlcbiIsCgkiW2RpcmVjdG9yeV1cbiIKKTsKCiNlbmRpZgkvKiBDT05GSUdfQ09NTUFORFMgJiBDRkdfQ01EX0ZET1MgKi8K