LyoKICogQ29weXJpZ2h0IDIwMDIgTWljaGFlbCBH/G5uZXdpZwogKgogKiBUaGlzIGxpYnJhcnkgaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBMZXNzZXIgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyCiAqIHZlcnNpb24gMi4xIG9mIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIGxpYnJhcnkgaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZSBHTlUKICogTGVzc2VyIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFsb25nIHdpdGggdGhpcyBsaWJyYXJ5OyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSwgU3VpdGUgMzMwLCBCb3N0b24sIE1BICAwMjExMS0xMzA3ICBVU0EKICovCgojZGVmaW5lIENPTV9OT19XSU5ET1dTX0gKI2luY2x1ZGUgPGFzc2VydC5oPgoKI2luY2x1ZGUgImV4dHJhY2h1bmsuaCIKI2luY2x1ZGUgIndpbmJhc2UuaCIKI2luY2x1ZGUgIndpbmdkaS5oIgojaW5jbHVkZSAid2ludXNlci5oIgojaW5jbHVkZSAid2luZG93c3guaCIKI2luY2x1ZGUgInZmdy5oIgoKI2luY2x1ZGUgIndpbmUvZGVidWcuaCIKCldJTkVfREVGQVVMVF9ERUJVR19DSEFOTkVMKGF2aWZpbGUpOwoKLyogcmVhZHMgYSBjaHVuayBvdXRvZiB0aGUgZXh0cmFjaHVuay1zdHJ1Y3R1cmUgKi8KSFJFU1VMVCBSZWFkRXh0cmFDaHVuayhMUEVYVFJBQ0hVTktTIGV4dHJhLEZPVVJDQyBja2lkLExQVk9JRCBscERhdGEsCgkJICAgICAgIExQTE9ORyBzaXplKQp7CiAgTFBCWVRFIGxwOwogIERXT1JEICBjYjsKCiAgLyogcHJlLWNvbmRpdGlvbnMgKi8KICBhc3NlcnQoZXh0cmEgIT0gTlVMTCk7CiAgYXNzZXJ0KHNpemUgIT0gTlVMTCk7CgogIGxwID0gZXh0cmEtPmxwOwogIGNiID0gZXh0cmEtPmNiOwoKICBpZiAobHAgIT0gTlVMTCkgewogICAgd2hpbGUgKGNiID4gMCkgewogICAgICBpZiAoKChGT1VSQ0MqKWxwKVswXSA9PSBja2lkKSB7CgkvKiBmb3VuZCBjb3JyZWN0IGNodW5rICovCglpZiAobHBEYXRhICE9IE5VTEwgJiYgKnNpemUgPiAwKQoJICBtZW1jcHkobHBEYXRhLCBscCArIDIgKiBzaXplb2YoRFdPUkQpLAoJCSBtaW4oKChMUERXT1JEKWxwKVsxXSwgKihMUERXT1JEKXNpemUpKTsKCgkqKExQRFdPUkQpc2l6ZSA9ICgoTFBEV09SRClscClbMV07CgoJcmV0dXJuIEFWSUVSUl9PSzsKICAgICAgfSBlbHNlIHsKCS8qIHNraXAgdG8gbmV4dCBjaHVuayAqLwoJY2IgLT0gKChMUERXT1JEKWxwKVsxXSArIDIgKiBzaXplb2YoRFdPUkQpOwoJbHAgKz0gKChMUERXT1JEKWxwKVsxXSArIDIgKiBzaXplb2YoRFdPUkQpOwogICAgICB9CiAgICB9CiAgfQoKICAvKiB3YW50ZWQgY2h1bmsgZG9lc24ndCBleGlzdCAqLwogICpzaXplID0gMDsKCiAgcmV0dXJuIEFWSUVSUl9OT0RBVEE7Cn0KCi8qIHdyaXRlcyBhIGNodW5rIGludG8gdGhlIGV4dHJhY2h1bmstc3RydWN0dXJlICovCkhSRVNVTFQgV3JpdGVFeHRyYUNodW5rKExQRVhUUkFDSFVOS1MgZXh0cmEsRk9VUkNDIGNraWQsTFBWT0lEIGxwRGF0YSwKCQkJTE9ORyBzaXplKQp7CiAgTFBEV09SRCBscDsKCiAgLyogcHJlLWNvbmRpdGlvbnMgKi8KICBhc3NlcnQoZXh0cmEgIT0gTlVMTCk7CiAgYXNzZXJ0KGxwRGF0YSAhPSBOVUxMKTsKICBhc3NlcnQoc2l6ZSA+IDApOwoKICBpZiAoZXh0cmEtPmxwKQogICAgbHAgPSAoTFBEV09SRClHbG9iYWxSZUFsbG9jUHRyKGV4dHJhLT5scCwgZXh0cmEtPmNiICsgc2l6ZSArIDIgKiBzaXplb2YoRFdPUkQpLCBHSE5EKTsKICBlbHNlCiAgICBscCA9IChMUERXT1JEKUdsb2JhbEFsbG9jUHRyKEdITkQsIHNpemUgKyAyICogc2l6ZW9mKERXT1JEKSk7CgogIGlmIChscCA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9NRU1PUlk7CgogIGV4dHJhLT5scCAgPSBscDsKICBscCA9IChMUERXT1JEKSAoKExQQllURSlscCArIGV4dHJhLT5jYik7CiAgZXh0cmEtPmNiICs9IHNpemUgKyAyICogc2l6ZW9mKERXT1JEKTsKCiAgLyogaW5zZXJ0IGNodW5rLWhlYWRlciBpbiBibG9jayAqLwogIGxwWzBdID0gY2tpZDsKICBscFsxXSA9IHNpemU7CgogIGlmIChscERhdGEgIT0gTlVMTCAmJiBzaXplID4gMCkKICAgIG1lbWNweShscCArIDIsIGxwRGF0YSwgc2l6ZSk7CgogIHJldHVybiBBVklFUlJfT0s7Cn0KCi8qIHJlYWRzIGEgY2h1bmsgZm9tciB0aGUgSE1NSU8gaW50byB0aGUgZXh0cmFjaHVuay1zdHJ1Y3R1cmUgKi8KSFJFU1VMVCBSZWFkQ2h1bmtJbnRvRXh0cmEoTFBFWFRSQUNIVU5LUyBleHRyYSxITU1JTyBobW1pbyxNTUNLSU5GTyAqbHBjaykKewogIExQRFdPUkQgbHA7CiAgRFdPUkQgICBjYjsKCiAgLyogcHJlLWNvbmRpdGlvbnMgKi8KICBhc3NlcnQoZXh0cmEgIT0gTlVMTCk7CiAgYXNzZXJ0KGhtbWlvICE9IE5VTEwpOwogIGFzc2VydChscGNrICAhPSBOVUxMKTsKCiAgY2IgID0gbHBjay0+Y2tzaXplICsgMiAqIHNpemVvZihEV09SRCk7CiAgY2IgKz0gKGNiICYgMSk7CgogIGlmIChleHRyYS0+bHAgIT0gTlVMTCkgewogICAgbHAgPSAoTFBEV09SRClHbG9iYWxSZUFsbG9jUHRyKGV4dHJhLT5scCwgZXh0cmEtPmNiICsgY2IsIEdITkQpOwogIH0gZWxzZQogICAgbHAgPSAoTFBEV09SRClHbG9iYWxBbGxvY1B0cihHSE5ELCBjYik7CgogIGlmIChscCA9PSBOVUxMKQogICAgcmV0dXJuIEFWSUVSUl9NRU1PUlk7CgogIGV4dHJhLT5scCAgPSBscDsKICBscCA9IChMUERXT1JEKSAoKExQQllURSlscCArIGV4dHJhLT5jYik7CiAgZXh0cmEtPmNiICs9IGNiOwoKICAvKiBpbnNlcnQgY2h1bmstaGVhZGVyIGluIGJsb2NrICovCiAgbHBbMF0gPSBscGNrLT5ja2lkOwogIGxwWzFdID0gbHBjay0+Y2tzaXplOwoKICBpZiAobHBjay0+Y2tzaXplID4gMCkgewogICAgaWYgKG1taW9TZWVrKGhtbWlvLCBscGNrLT5kd0RhdGFPZmZzZXQsIFNFRUtfU0VUKSA9PSAtMSkKICAgICAgcmV0dXJuIEFWSUVSUl9GSUxFUkVBRDsKICAgIGlmIChtbWlvUmVhZChobW1pbywgKEhQU1RSKSZscFsyXSwgbHBjay0+Y2tzaXplKSAhPSAoTE9ORylscGNrLT5ja3NpemUpCiAgICAgIHJldHVybiBBVklFUlJfRklMRVJFQUQ7CiAgfQoKICByZXR1cm4gQVZJRVJSX09LOwp9CgovKiByZWFkcyBhbGwgbm9uLWp1bmsgY2h1bmtzIGludG8gdGhlIGV4dHJhY2h1bmstc3RydWN0dXJlIHVudGlsIGl0IGZpbmRzCiAqIHRoZSBnaXZlbiBjaHVuayBvciB0aGUgb3B0aW9uYWwgcGFyZW50LWNodW5rIGlzIGF0IHRoZSBlbmQgKi8KSFJFU1VMVCBGaW5kQ2h1bmtBbmRLZWVwRXh0cmFzKExQRVhUUkFDSFVOS1MgZXh0cmEsSE1NSU8gaG1taW8sTU1DS0lORk8gKmxwY2ssCgkJCSAgICAgICBNTUNLSU5GTyAqbHBja1BhcmVudCxVSU5UIGZsYWdzKQp7CiAgRk9VUkNDICBja2lkOwogIEZPVVJDQyAgZmNjVHlwZTsKICBIUkVTVUxUIGhyOwoKICAvKiBwcmUtY29uZGl0aW9ucyAqLwogIGFzc2VydChleHRyYSAhPSBOVUxMKTsKICBhc3NlcnQoaG1taW8gIT0gTlVMTCk7CiAgYXNzZXJ0KGxwY2sgICE9IE5VTEwpOwoKICBUUkFDRSgiKHslcCwlbHV9LCVwLCVwLCVwLDB4JVgpXG4iLCBleHRyYS0+bHAsIGV4dHJhLT5jYiwgaG1taW8sIGxwY2ssCglscGNrUGFyZW50LCBmbGFncyk7CgogIC8qIHdoYXQgY2h1bmsgaWQgYW5kIGZvcm0vbGlzdCB0eXBlIHNob3VsZCB3ZSBzZWFyY2g/ICovCiAgaWYgKGZsYWdzICYgTU1JT19GSU5EQ0hVTkspIHsKICAgIGNraWQgICAgPSBscGNrLT5ja2lkOwogICAgZmNjVHlwZSA9IDA7CiAgfSBlbHNlIGlmIChmbGFncyAmIE1NSU9fRklORExJU1QpIHsKICAgIGNraWQgICAgPSBGT1VSQ0NfTElTVDsKICAgIGZjY1R5cGUgPSBscGNrLT5mY2NUeXBlOwogIH0gZWxzZSBpZiAoZmxhZ3MgJiBNTUlPX0ZJTkRSSUZGKSB7CiAgICBja2lkICAgID0gRk9VUkNDX1JJRkY7CiAgICBmY2NUeXBlID0gbHBjay0+ZmNjVHlwZTsKICB9IGVsc2UKICAgIGNraWQgPSBmY2NUeXBlID0gKEZPVVJDQyktMTsgLyogY29sbGVjdCBldmVyeXRoaW5nIGludG8gZXh0cmEhICovCgogIFRSQUNFKCI6IGZpbmQgY2tpZD0weCUwOGxYIGZjY1R5cGU9MHglMDhsWFxuIiwgY2tpZCwgZmNjVHlwZSk7CgogIGZvciAoOzspIHsKICAgIGhyID0gbW1pb0Rlc2NlbmQoaG1taW8sIGxwY2ssIGxwY2tQYXJlbnQsIDApOwogICAgaWYgKGhyICE9IFNfT0spIHsKICAgICAgLyogTm8gZXh0cmEgY2h1bmtzIGluIGZyb250IG9mIGRlc2lyZWQgY2h1bms/ICovCiAgICAgIGlmIChmbGFncyA9PSAwICYmIGhyID09IE1NSU9FUlJfQ0hVTktOT1RGT1VORCkKCWhyID0gQVZJRVJSX09LOwogICAgICByZXR1cm4gaHI7CiAgICB9CgogICAgLyogSGF2ZSB3ZSBmb3VuZCB3aGF0IHdlIHNlYXJjaCBmb3I/ICovCiAgICBpZiAoKGxwY2stPmNraWQgPT0gY2tpZCkgJiYKCShmY2NUeXBlID09IChGT1VSQ0MpMCB8fCBscGNrLT5mY2NUeXBlID09IGZjY1R5cGUpKQogICAgICByZXR1cm4gQVZJRVJSX09LOwoKICAgIC8qIFNraXAgcGFkZGluZyBjaHVua3MsIHRoZSBvdGhlcnMgcHV0IGludG8gdGhlIGV4dHJhY2h1bmstc3RydWN0dXJlICovCiAgICBpZiAobHBjay0+Y2tpZCA9PSBja2lkQVZJUEFERElORyB8fAoJbHBjay0+Y2tpZCA9PSBtbWlvRk9VUkNDKCdwJywnYScsJ2QnLCdkJykpCiAgICAgIGhyID0gbW1pb0FzY2VuZChobW1pbywgbHBjaywgMCk7CiAgICBlbHNlCiAgICAgIGhyID0gUmVhZENodW5rSW50b0V4dHJhKGV4dHJhLCBobW1pbywgbHBjayk7CiAgICBpZiAoRkFJTEVEKGhyKSkKICAgICAgcmV0dXJuIGhyOwogIH0KfQo=