LyoKICogKEMpCUNvcHlyaWdodCAyMDAxCiAqIFN05HVibGkgRmF2ZXJnZXMgLSA8d3d3LnN0YXVibGkuY29tPgogKiBQaWVycmUgQVVCRVJUICBwLmF1YmVydEBzdGF1YmxpLmNvbQogKiBVLUJvb3QgcG9ydCBvbiBSUFhDbGFzc2ljIExGIChDTExGX0JXMzEpIGJvYXJkCiAqCiAqIChDKSBDb3B5cmlnaHQgMjAwMAogKiBXb2xmZ2FuZyBEZW5rLCBERU5YIFNvZnR3YXJlIEVuZ2luZWVyaW5nLCB3ZEBkZW54LmRlLgogKgogKiBTZWUgZmlsZSBDUkVESVRTIGZvciBsaXN0IG9mIHBlb3BsZSB3aG8gY29udHJpYnV0ZWQgdG8gdGhpcwogKiBwcm9qZWN0LgogKgogKiBUaGlzIHByb2dyYW0gaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzCiAqIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIgdmVyc2lvbiAyIG9mCiAqIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLgkgU2VlIHRoZQogKiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiBhbG9uZyB3aXRoIHRoaXMgcHJvZ3JhbTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQogKiBGb3VuZGF0aW9uLCBJbmMuLCA1OSBUZW1wbGUgUGxhY2UsIFN1aXRlIDMzMCwgQm9zdG9uLAogKiBNQSAwMjExMS0xMzA3IFVTQQogKi8KCiNpbmNsdWRlIDxjb21tb24uaD4KI2luY2x1ZGUgPGkyYy5oPgojaW5jbHVkZSA8Y29uZmlnLmg+CiNpbmNsdWRlIDxtcGM4eHguaD4KCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KCnN0YXRpYyBsb25nIGludCBkcmFtX3NpemUgKGxvbmcgaW50LCBsb25nIGludCAqLCBsb25nIGludCk7CnN0YXRpYyB1bnNpZ25lZCBjaGFyIGFzY2hleF90b19ieXRlICh1bnNpZ25lZCBjaGFyICpjcCk7CgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgojZGVmaW5lIF9OT1RfVVNFRF8JMHhGRkZGQ0MyNQoKY29uc3QgdWludCBzZHJhbV90YWJsZVtdID0KewoJLyoKCSAqIFNpbmdsZSBSZWFkLiAoT2Zmc2V0IDAwaCBpbiBVUE1BIFJBTSkKCSAqLwoJMHhDRkZGQ0MyNCwgMHgwRkZGQ0MwNCwgMFgwQ0FGQ0MwNCwgMFgwM0FGQ0MwOCwKCTB4M0ZCRkNDMjcsIC8qIGxhc3QgKi8KCV9OT1RfVVNFRF8sIF9OT1RfVVNFRF8sIF9OT1RfVVNFRF8sCgoJLyoKCSAqIEJ1cnN0IFJlYWQuIChPZmZzZXQgMDhoIGluIFVQTUEgUkFNKQoJICovCgkweENGRkZDQzI0LCAweDBGRkZDQzA0LCAweDBDQUZDQzg0LCAweDAzQUZDQzg4LAoJMHgzRkJGQ0MyNywgLyogbGFzdCAqLwoJX05PVF9VU0VEXywgX05PVF9VU0VEXywgX05PVF9VU0VEXywgX05PVF9VU0VEXywKCV9OT1RfVVNFRF8sIF9OT1RfVVNFRF8sIF9OT1RfVVNFRF8sIF9OT1RfVVNFRF8sCglfTk9UX1VTRURfLCBfTk9UX1VTRURfLCBfTk9UX1VTRURfLAoKCS8qCgkgKiBTaW5nbGUgV3JpdGUuIChPZmZzZXQgMThoIGluIFVQTUEgUkFNKQoJICovCgkweENGRkZDQzI0LCAweDBGRkZDQzA0LCAweDBDRkZDQzA0LCAweDAzRkZDQzAwLAoJMHgzRkZGQ0MyNywgLyogbGFzdCAqLwoJX05PVF9VU0VEXywgX05PVF9VU0VEXywgX05PVF9VU0VEXywKCgkvKgoJICogQnVyc3QgV3JpdGUuIChPZmZzZXQgMjBoIGluIFVQTUEgUkFNKQoJICovCgkweENGRkZDQzI0LCAweDBGRkZDQzA0LCAweDBDRkZDQzgwLCAweDAzRkZDQzhDLAoJMHgwQ0ZGQ0MwMCwgMHgzM0ZGQ0MyNywgLyogbGFzdCAqLwoJX05PVF9VU0VEXywgX05PVF9VU0VEXywgX05PVF9VU0VEXywgX05PVF9VU0VEXywKCV9OT1RfVVNFRF8sIF9OT1RfVVNFRF8sIF9OT1RfVVNFRF8sIF9OT1RfVVNFRF8sCglfTk9UX1VTRURfLCBfTk9UX1VTRURfLAoKCS8qCgkgKiBSZWZyZXNoLiAoT2Zmc2V0IDMwaCBpbiBVUE1BIFJBTSkKCSAqLwoJMHhDMEZGQ0MyNCwgMHgwM0ZGQ0MyNCwgMHgwRkZGQ0MyNCwgMHgwRkZGQ0MyNCwKCTB4M0ZGRkNDMjcsIC8qIGxhc3QgKi8KCV9OT1RfVVNFRF8sIF9OT1RfVVNFRF8sIF9OT1RfVVNFRF8sIF9OT1RfVVNFRF8sCglfTk9UX1VTRURfLCBfTk9UX1VTRURfLCBfTk9UX1VTRURfLAoKCS8qCgkgKiBFeGNlcHRpb24uIChPZmZzZXQgM0NoIGluIFVQTUEgUkFNKQoJICovCglfTk9UX1VTRURfLCBfTk9UX1VTRURfLCBfTk9UX1VTRURfLCBfTk9UX1VTRURfCn07CgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgoKLyoKICogQ2hlY2sgQm9hcmQgSWRlbnRpdHk6CiAqLwoKaW50IGNoZWNrYm9hcmQgKHZvaWQpCnsKCXB1dHMgKCJCb2FyZDogUlBYQ2xhc3NpY1xuIik7CglyZXR1cm4gKDApOwp9CgovKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAqIGJvYXJkX2dldF9lbmV0YWRkciAtLSBSZWFkIHRoZSBNQUMgQWRkcmVzcyBpbiB0aGUgSTJDIEVFUFJPTQogKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAqLwp2b2lkIGJvYXJkX2dldF9lbmV0YWRkciAodWNoYXIgKiBlbmV0KQp7CglpbnQgaTsKCWNoYXIgYnVmZlsyNTZdLCAqY3A7CgoJLyogSW5pdGlhbGl6ZSBJMkMJCQkJCSovCglpMmNfaW5pdCAoQ0ZHX0kyQ19TUEVFRCwgQ0ZHX0kyQ19TTEFWRSk7CgoJLyogUmVhZCAyNTYgYnl0ZXMgaW4gRUVQUk9NCQkJCSovCglpMmNfcmVhZCAoMHg1NCwgMCwgMSwgKHVjaGFyICopYnVmZiwgMTI4KTsKCWkyY19yZWFkICgweDU0LCAxMjgsIDEsICh1Y2hhciAqKWJ1ZmYgKyAxMjgsIDEyOCk7CgoJLyogUmV0cmlldmUgTUFDIGFkZHJlc3MgaW4gYnVmZmVyIChrZXkgRUEpCQkqLwoJZm9yIChjcCA9IGJ1ZmY7OykgewoJCWlmIChjcFswXSA9PSAnRScgJiYgY3BbMV0gPT0gJ0EnKSB7CgkJCWNwICs9IDM7CgkJCS8qIFJlYWQgTUFDIGFkZHJlc3MJCQkqLwoJCQlmb3IgKGkgPSAwOyBpIDwgNjsgaSsrLCBjcCArPSAyKSB7CgkJCQllbmV0W2ldID0gYXNjaGV4X3RvX2J5dGUgKCh1bnNpZ25lZCBjaGFyICopY3ApOwoJCQl9CgkJfQoJCS8qIFNjYW4gdG8gdGhlIGVuZCBvZiB0aGUgcmVjb3JkCQkqLwoJCXdoaWxlICgoKmNwICE9ICdcbicpICYmICgqY3AgIT0gKGNoYXIpMHhmZikpIHsKCQkJY3ArKzsKCQl9CgkJLyogSWYgdGhlIG5leHQgY2hhcmFjdGVyIGlzIGEgXG4sIDAgb3IgZmYsIHdlIGFyZSBkb25lLgkqLwoJCWNwKys7CgkJaWYgKCgqY3AgPT0gJ1xuJykgfHwgKCpjcCA9PSAwKSB8fCAoKmNwID09IChjaGFyKTB4ZmYpKQoJCQlicmVhazsKCX0KCiNpZmRlZiBDT05GSUdfRkVDX0VORVQKCS8qIFRoZSBNQUMgYWRkcmVzcyBpcyB0aGUgc2FtZSBhcyBub3JtYWwgZXRoZXJuZXQgZXhjZXB0IHRoZSAzcmQgYnl0ZQkgKi8KCS8qIChTZWUgdGhlIEUuUC4gUGxhbmV0IENvcmUgT3ZlcnZpZXcgbWFudWFsCQkqLwoJZW5ldFszXSB8PSAweDgwOwojZW5kaWYKCglwcmludGYgKCJNQUMgYWRkcmVzcyA9ICUwMng6JTAyeDolMDJ4OiUwMng6JTAyeDolMDJ4XG4iLAoJCWVuZXRbMF0sIGVuZXRbMV0sIGVuZXRbMl0sIGVuZXRbM10sIGVuZXRbNF0sIGVuZXRbNV0pOwoKfQoKdm9pZCBycHhjbGFzc2ljX2luaXQgKHZvaWQpCnsKCS8qIEVuYWJsZSBOVlJBTSAqLwoJKigodWNoYXIgKikgQkNTUjApIHw9IEJDU1IwX0VOTlZSQU07CgojaWZkZWYgQ09ORklHX0ZFQ19FTkVUCgoJLyogVmFsaWRhdGUgdGhlIGZhc3QgZXRoZXJuZXQgdHJhbmNlaXZlciAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKi8KCSooKHZvbGF0aWxlIHVjaGFyICopIEJDU1IyKSAmPSB+QkNTUjJfTUlJQ1RMOwoJKigodm9sYXRpbGUgdWNoYXIgKikgQkNTUjIpICY9IH5CQ1NSMl9NSUlQV1JEV047CgkqKCh2b2xhdGlsZSB1Y2hhciAqKSBCQ1NSMikgfD0gQkNTUjJfTUlJUlNUOwoJKigodm9sYXRpbGUgdWNoYXIgKikgQkNTUjIpIHw9IEJDU1IyX01JSVBXUkRXTjsKI2VuZGlmCgp9CgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgpsb25nIGludCBpbml0ZHJhbSAoaW50IGJvYXJkX3R5cGUpCnsKCXZvbGF0aWxlIGltbWFwX3QgKmltbWFwID0gKGltbWFwX3QgKikgQ0ZHX0lNTVI7Cgl2b2xhdGlsZSBtZW1jdGw4eHhfdCAqbWVtY3RsID0gJmltbWFwLT5pbV9tZW1jdGw7Cglsb25nIGludCBzaXplMTA7CgoJdXBtY29uZmlnIChVUE1BLCAodWludCAqKSBzZHJhbV90YWJsZSwKCQkJICAgc2l6ZW9mIChzZHJhbV90YWJsZSkgLyBzaXplb2YgKHVpbnQpKTsKCgkvKiBSZWZyZXNoIGNsb2NrIHByZXNjYWxhciAqLwoJbWVtY3RsLT5tZW1jX21wdHByID0gQ0ZHX01QVFBSOwoKCW1lbWN0bC0+bWVtY19tYXIgPSAweDAwMDAwMDAwOwoKCS8qIE1hcCBjb250cm9sbGVyIGJhbmtzIDEgdG8gdGhlIFNEUkFNIGJhbmsgKi8KCW1lbWN0bC0+bWVtY19vcjEgPSBDRkdfT1IxX1BSRUxJTTsKCW1lbWN0bC0+bWVtY19icjEgPSBDRkdfQlIxX1BSRUxJTTsKCgltZW1jdGwtPm1lbWNfbWFtciA9IENGR19NQU1SXzEwQ09MICYgKH4oTUFNUl9QVEFFKSk7CS8qIG5vIHJlZnJlc2ggeWV0ICovCgoJdWRlbGF5ICgyMDApOwoKCS8qIHBlcmZvcm0gU0RSQU0gaW5pdGlhbGl6c2F0aW9uIHNlcXVlbmNlICovCgoJbWVtY3RsLT5tZW1jX21jciA9IDB4ODAwMDIyMzA7CS8qIFNEUkFNIGJhbmsgMCAtIHJlZnJlc2ggdHdpY2UgKi8KCXVkZWxheSAoMSk7CgoJbWVtY3RsLT5tZW1jX21hbXIgfD0gTUFNUl9QVEFFOyAvKiBlbmFibGUgcmVmcmVzaCAqLwoKCXVkZWxheSAoMTAwMCk7CgoJLyogQ2hlY2sgQmFuayAwIE1lbW9yeSBTaXplCgkgKiB0cnkgMTAgY29sdW1uIG1vZGUKCSAqLwoKCXNpemUxMCA9IGRyYW1fc2l6ZSAoQ0ZHX01BTVJfMTBDT0wsIFNEUkFNX0JBU0VfUFJFTElNLAoJCQkJCQlTRFJBTV9NQVhfU0laRSk7CgoJcmV0dXJuIChzaXplMTApOwp9CgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgovKgogKiBDaGVjayBtZW1vcnkgcmFuZ2UgZm9yIHZhbGlkIFJBTS4gQSBzaW1wbGUgbWVtb3J5IHRlc3QgZGV0ZXJtaW5lcwogKiB0aGUgYWN0dWFsbHkgYXZhaWxhYmxlIFJBTSBzaXplIGJldHdlZW4gYWRkcmVzc2VzIGBiYXNlJyBhbmQKICogYGJhc2UgKyBtYXhzaXplJy4gU29tZSAobm90IGFsbCkgaGFyZHdhcmUgZXJyb3JzIGFyZSBkZXRlY3RlZDoKICogLSBzaG9ydCBiZXR3ZWVuIGFkZHJlc3MgbGluZXMKICogLSBzaG9ydCBiZXR3ZWVuIGRhdGEgbGluZXMKICovCgpzdGF0aWMgbG9uZyBpbnQgZHJhbV9zaXplIChsb25nIGludCBtYW1yX3ZhbHVlLCBsb25nIGludCAqYmFzZSwgbG9uZyBpbnQgbWF4c2l6ZSkKewoJdm9sYXRpbGUgaW1tYXBfdCAqaW1tYXAgPSAoaW1tYXBfdCAqKSBDRkdfSU1NUjsKCXZvbGF0aWxlIG1lbWN0bDh4eF90ICptZW1jdGwgPSAmaW1tYXAtPmltX21lbWN0bDsKCgltZW1jdGwtPm1lbWNfbWFtciA9IG1hbXJfdmFsdWU7CgoJcmV0dXJuIChnZXRfcmFtX3NpemUoYmFzZSwgbWF4c2l6ZSkpOwp9Ci8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KICogYXNjaGV4X3RvX2J5dGUgLS0KICotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogKi8Kc3RhdGljIHVuc2lnbmVkIGNoYXIgYXNjaGV4X3RvX2J5dGUgKHVuc2lnbmVkIGNoYXIgKmNwKQp7Cgl1X2NoYXIgYnl0ZSwgYzsKCgljID0gKmNwKys7CgoJaWYgKChjID49ICdBJykgJiYgKGMgPD0gJ0YnKSkgewoJCWMgLT0gJ0EnOwoJCWMgKz0gMTA7Cgl9IGVsc2UgaWYgKChjID49ICdhJykgJiYgKGMgPD0gJ2YnKSkgewoJCWMgLT0gJ2EnOwoJCWMgKz0gMTA7Cgl9IGVsc2UgewoJCWMgLT0gJzAnOwoJfQoKCWJ5dGUgPSBjICogMTY7CgoJYyA9ICpjcDsKCglpZiAoKGMgPj0gJ0EnKSAmJiAoYyA8PSAnRicpKSB7CgkJYyAtPSAnQSc7CgkJYyArPSAxMDsKCX0gZWxzZSBpZiAoKGMgPj0gJ2EnKSAmJiAoYyA8PSAnZicpKSB7CgkJYyAtPSAnYSc7CgkJYyArPSAxMDsKCX0gZWxzZSB7CgkJYyAtPSAnMCc7Cgl9CgoJYnl0ZSArPSBjOwoKCXJldHVybiAoYnl0ZSk7Cn0K