LyoKICogUUVNVSBOVlJBTSBlbXVsYXRpb24gZm9yIERTMTIyNVkgY2hpcAogKgogKiBDb3B5cmlnaHQgKGMpIDIwMDctMjAwOCBIZXJ26SBQb3Vzc2luZWF1CiAqCiAqIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhIGNvcHkKICogb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGUgIlNvZnR3YXJlIiksIHRvIGRlYWwKICogaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cwogKiB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsCiAqIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpcwogKiBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOgogKgogKiBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZCBpbgogKiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS4KICoKICogVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEICJBUyBJUyIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1MgT1IKICogSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFksCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOIE5PIEVWRU5UIFNIQUxMCiAqIFRIRSBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLCBEQU1BR0VTIE9SIE9USEVSCiAqIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1IgT1RIRVJXSVNFLCBBUklTSU5HIEZST00sCiAqIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRSBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU4KICogVEhFIFNPRlRXQVJFLgogKi8KCiNpbmNsdWRlICJody5oIgojaW5jbHVkZSAibWlwcy5oIgojaW5jbHVkZSAibnZyYW0uaCIKCi8vI2RlZmluZSBERUJVR19OVlJBTQoKdHlwZWRlZiBzdHJ1Y3QgZHMxMjI1eV90CnsKICAgIHVpbnQzMl90IGNoaXBfc2l6ZTsKICAgIFFFTVVGaWxlICpmaWxlOwogICAgdWludDhfdCAqY29udGVudHM7CiAgICB1aW50OF90IHByb3RlY3Rpb247Cn0gZHMxMjI1eV90OwoKCnN0YXRpYyB1aW50MzJfdCBudnJhbV9yZWFkYiAodm9pZCAqb3BhcXVlLCB0YXJnZXRfcGh5c19hZGRyX3QgYWRkcikKewogICAgZHMxMjI1eV90ICpzID0gb3BhcXVlOwogICAgdWludDMyX3QgdmFsOwoKICAgIHZhbCA9IHMtPmNvbnRlbnRzW2FkZHJdOwoKI2lmZGVmIERFQlVHX05WUkFNCiAgICBwcmludGYoIm52cmFtOiByZWFkIDB4JXggYXQgIiBUQVJHRVRfRk1UX2x4ICJcbiIsIHZhbCwgYWRkcik7CiNlbmRpZgogICAgcmV0dXJuIHZhbDsKfQoKc3RhdGljIHVpbnQzMl90IG52cmFtX3JlYWR3ICh2b2lkICpvcGFxdWUsIHRhcmdldF9waHlzX2FkZHJfdCBhZGRyKQp7CiAgICB1aW50MzJfdCB2OwogICAgdiA9IG52cmFtX3JlYWRiKG9wYXF1ZSwgYWRkcik7CiAgICB2IHw9IG52cmFtX3JlYWRiKG9wYXF1ZSwgYWRkciArIDEpIDw8IDg7CiAgICByZXR1cm4gdjsKfQoKc3RhdGljIHVpbnQzMl90IG52cmFtX3JlYWRsICh2b2lkICpvcGFxdWUsIHRhcmdldF9waHlzX2FkZHJfdCBhZGRyKQp7CiAgICB1aW50MzJfdCB2OwogICAgdiA9IG52cmFtX3JlYWRiKG9wYXF1ZSwgYWRkcik7CiAgICB2IHw9IG52cmFtX3JlYWRiKG9wYXF1ZSwgYWRkciArIDEpIDw8IDg7CiAgICB2IHw9IG52cmFtX3JlYWRiKG9wYXF1ZSwgYWRkciArIDIpIDw8IDE2OwogICAgdiB8PSBudnJhbV9yZWFkYihvcGFxdWUsIGFkZHIgKyAzKSA8PCAyNDsKICAgIHJldHVybiB2Owp9CgpzdGF0aWMgdm9pZCBudnJhbV93cml0ZWIgKHZvaWQgKm9wYXF1ZSwgdGFyZ2V0X3BoeXNfYWRkcl90IGFkZHIsIHVpbnQzMl90IHZhbCkKewogICAgZHMxMjI1eV90ICpzID0gb3BhcXVlOwoKI2lmZGVmIERFQlVHX05WUkFNCiAgICBwcmludGYoIm52cmFtOiB3cml0ZSAweCV4IGF0ICIgVEFSR0VUX0ZNVF9seCAiXG4iLCB2YWwsIGFkZHIpOwojZW5kaWYKCiAgICBzLT5jb250ZW50c1thZGRyXSA9IHZhbCAmIDB4ZmY7CiAgICBpZiAocy0+ZmlsZSkgewogICAgICAgIHFlbXVfZnNlZWsocy0+ZmlsZSwgYWRkciwgU0VFS19TRVQpOwogICAgICAgIHFlbXVfcHV0X2J5dGUocy0+ZmlsZSwgKGludCl2YWwpOwogICAgICAgIHFlbXVfZmZsdXNoKHMtPmZpbGUpOwogICAgfQp9CgpzdGF0aWMgdm9pZCBudnJhbV93cml0ZXcgKHZvaWQgKm9wYXF1ZSwgdGFyZ2V0X3BoeXNfYWRkcl90IGFkZHIsIHVpbnQzMl90IHZhbCkKewogICAgbnZyYW1fd3JpdGViKG9wYXF1ZSwgYWRkciwgdmFsICYgMHhmZik7CiAgICBudnJhbV93cml0ZWIob3BhcXVlLCBhZGRyICsgMSwgKHZhbCA+PiA4KSAmIDB4ZmYpOwp9CgpzdGF0aWMgdm9pZCBudnJhbV93cml0ZWwgKHZvaWQgKm9wYXF1ZSwgdGFyZ2V0X3BoeXNfYWRkcl90IGFkZHIsIHVpbnQzMl90IHZhbCkKewogICAgbnZyYW1fd3JpdGViKG9wYXF1ZSwgYWRkciwgdmFsICYgMHhmZik7CiAgICBudnJhbV93cml0ZWIob3BhcXVlLCBhZGRyICsgMSwgKHZhbCA+PiA4KSAmIDB4ZmYpOwogICAgbnZyYW1fd3JpdGViKG9wYXF1ZSwgYWRkciArIDIsICh2YWwgPj4gMTYpICYgMHhmZik7CiAgICBudnJhbV93cml0ZWIob3BhcXVlLCBhZGRyICsgMywgKHZhbCA+PiAyNCkgJiAweGZmKTsKfQoKc3RhdGljIHZvaWQgbnZyYW1fd3JpdGViX3Byb3RlY3RlZCAodm9pZCAqb3BhcXVlLCB0YXJnZXRfcGh5c19hZGRyX3QgYWRkciwgdWludDMyX3QgdmFsKQp7CiAgICBkczEyMjV5X3QgKnMgPSBvcGFxdWU7CgogICAgaWYgKHMtPnByb3RlY3Rpb24gIT0gNykgewojaWZkZWYgREVCVUdfTlZSQU0KICAgIHByaW50ZigibnZyYW06IHByZXZlbnQgd3JpdGUgb2YgMHgleCBhdCAiIFRBUkdFVF9GTVRfbHggIlxuIiwgdmFsLCBhZGRyKTsKI2VuZGlmCiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgIG52cmFtX3dyaXRlYihvcGFxdWUsIGFkZHIsIHZhbCk7Cn0KCnN0YXRpYyB2b2lkIG52cmFtX3dyaXRld19wcm90ZWN0ZWQgKHZvaWQgKm9wYXF1ZSwgdGFyZ2V0X3BoeXNfYWRkcl90IGFkZHIsIHVpbnQzMl90IHZhbCkKewogICAgbnZyYW1fd3JpdGViX3Byb3RlY3RlZChvcGFxdWUsIGFkZHIsIHZhbCAmIDB4ZmYpOwogICAgbnZyYW1fd3JpdGViX3Byb3RlY3RlZChvcGFxdWUsIGFkZHIgKyAxLCAodmFsID4+IDgpICYgMHhmZik7Cn0KCnN0YXRpYyB2b2lkIG52cmFtX3dyaXRlbF9wcm90ZWN0ZWQgKHZvaWQgKm9wYXF1ZSwgdGFyZ2V0X3BoeXNfYWRkcl90IGFkZHIsIHVpbnQzMl90IHZhbCkKewogICAgbnZyYW1fd3JpdGViX3Byb3RlY3RlZChvcGFxdWUsIGFkZHIsIHZhbCAmIDB4ZmYpOwogICAgbnZyYW1fd3JpdGViX3Byb3RlY3RlZChvcGFxdWUsIGFkZHIgKyAxLCAodmFsID4+IDgpICYgMHhmZik7CiAgICBudnJhbV93cml0ZWJfcHJvdGVjdGVkKG9wYXF1ZSwgYWRkciArIDIsICh2YWwgPj4gMTYpICYgMHhmZik7CiAgICBudnJhbV93cml0ZWJfcHJvdGVjdGVkKG9wYXF1ZSwgYWRkciArIDMsICh2YWwgPj4gMjQpICYgMHhmZik7Cn0KCnN0YXRpYyBDUFVSZWFkTWVtb3J5RnVuYyAqIGNvbnN0IG52cmFtX3JlYWRbXSA9IHsKICAgICZudnJhbV9yZWFkYiwKICAgICZudnJhbV9yZWFkdywKICAgICZudnJhbV9yZWFkbCwKfTsKCnN0YXRpYyBDUFVXcml0ZU1lbW9yeUZ1bmMgKiBjb25zdCBudnJhbV93cml0ZVtdID0gewogICAgJm52cmFtX3dyaXRlYiwKICAgICZudnJhbV93cml0ZXcsCiAgICAmbnZyYW1fd3JpdGVsLAp9OwoKc3RhdGljIENQVVdyaXRlTWVtb3J5RnVuYyAqIGNvbnN0IG52cmFtX3dyaXRlX3Byb3RlY3RlZFtdID0gewogICAgJm52cmFtX3dyaXRlYl9wcm90ZWN0ZWQsCiAgICAmbnZyYW1fd3JpdGV3X3Byb3RlY3RlZCwKICAgICZudnJhbV93cml0ZWxfcHJvdGVjdGVkLAp9OwoKLyogSW5pdGlhbGlzYXRpb24gcm91dGluZSAqLwp2b2lkICpkczEyMjV5X2luaXQodGFyZ2V0X3BoeXNfYWRkcl90IG1lbV9iYXNlLCBjb25zdCBjaGFyICpmaWxlbmFtZSkKewogICAgZHMxMjI1eV90ICpzOwogICAgaW50IG1lbV9pbmRleFJXLCBtZW1faW5kZXhSUDsKICAgIFFFTVVGaWxlICpmaWxlOwoKICAgIHMgPSBxZW11X21hbGxvY3ooc2l6ZW9mKGRzMTIyNXlfdCkpOwogICAgcy0+Y2hpcF9zaXplID0gMHgyMDAwOyAvKiBGaXhlZCBmb3IgZHMxMjI1eSBjaGlwOiA4IEtpQiAqLwogICAgcy0+Y29udGVudHMgPSBxZW11X21hbGxvY3oocy0+Y2hpcF9zaXplKTsKICAgIHMtPnByb3RlY3Rpb24gPSA3OwoKICAgIC8qIFJlYWQgY3VycmVudCBmaWxlICovCiAgICBmaWxlID0gcWVtdV9mb3BlbihmaWxlbmFtZSwgInJiIik7CiAgICBpZiAoZmlsZSkgewogICAgICAgIC8qIFJlYWQgbnZyYW0gY29udGVudHMgKi8KICAgICAgICBxZW11X2dldF9idWZmZXIoZmlsZSwgcy0+Y29udGVudHMsIHMtPmNoaXBfc2l6ZSk7CiAgICAgICAgcWVtdV9mY2xvc2UoZmlsZSk7CiAgICB9CiAgICBzLT5maWxlID0gcWVtdV9mb3BlbihmaWxlbmFtZSwgIndiIik7CiAgICBpZiAocy0+ZmlsZSkgewogICAgICAgIC8qIFdyaXRlIGJhY2sgY29udGVudHMsIGFzICd3YicgbW9kZSBjbGVhbmVkIHRoZSBmaWxlICovCiAgICAgICAgcWVtdV9wdXRfYnVmZmVyKHMtPmZpbGUsIHMtPmNvbnRlbnRzLCBzLT5jaGlwX3NpemUpOwogICAgICAgIHFlbXVfZmZsdXNoKHMtPmZpbGUpOwogICAgfQoKICAgIC8qIFJlYWQvd3JpdGUgbWVtb3J5ICovCiAgICBtZW1faW5kZXhSVyA9IGNwdV9yZWdpc3Rlcl9pb19tZW1vcnkobnZyYW1fcmVhZCwgbnZyYW1fd3JpdGUsIHMpOwogICAgY3B1X3JlZ2lzdGVyX3BoeXNpY2FsX21lbW9yeShtZW1fYmFzZSwgcy0+Y2hpcF9zaXplLCBtZW1faW5kZXhSVyk7CiAgICAvKiBSZWFkL3dyaXRlIHByb3RlY3RlZCBtZW1vcnkgKi8KICAgIG1lbV9pbmRleFJQID0gY3B1X3JlZ2lzdGVyX2lvX21lbW9yeShudnJhbV9yZWFkLCBudnJhbV93cml0ZV9wcm90ZWN0ZWQsIHMpOwogICAgY3B1X3JlZ2lzdGVyX3BoeXNpY2FsX21lbW9yeShtZW1fYmFzZSArIHMtPmNoaXBfc2l6ZSwgcy0+Y2hpcF9zaXplLCBtZW1faW5kZXhSUCk7CiAgICByZXR1cm4gczsKfQo=