LyoKICogUUVNVSBOVlJBTSBlbXVsYXRpb24gZm9yIERTMTIyNVkgY2hpcAogKgogKiBDb3B5cmlnaHQgKGMpIDIwMDctMjAwOCBIZXJ26SBQb3Vzc2luZWF1CiAqCiAqIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhIGNvcHkKICogb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGUgIlNvZnR3YXJlIiksIHRvIGRlYWwKICogaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cwogKiB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsCiAqIGNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpcwogKiBmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOgogKgogKiBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZCBpbgogKiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zIG9mIHRoZSBTb2Z0d2FyZS4KICoKICogVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEICJBUyBJUyIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1MgT1IKICogSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFksCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOIE5PIEVWRU5UIFNIQUxMCiAqIFRIRSBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLCBEQU1BR0VTIE9SIE9USEVSCiAqIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1IgT1RIRVJXSVNFLCBBUklTSU5HIEZST00sCiAqIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRSBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU4KICogVEhFIFNPRlRXQVJFLgogKi8KCiNpbmNsdWRlICJody5oIgojaW5jbHVkZSAibWlwcy5oIgojaW5jbHVkZSAibnZyYW0uaCIKCi8vI2RlZmluZSBERUJVR19OVlJBTQoKdHlwZWRlZiBzdHJ1Y3QgZHMxMjI1eV90CnsKICAgIHRhcmdldF9waHlzX2FkZHJfdCBtZW1fYmFzZTsKICAgIHVpbnQzMl90IGNoaXBfc2l6ZTsKICAgIFFFTVVGaWxlICpmaWxlOwogICAgdWludDhfdCAqY29udGVudHM7CiAgICB1aW50OF90IHByb3RlY3Rpb247Cn0gZHMxMjI1eV90OwoKCnN0YXRpYyB1aW50MzJfdCBudnJhbV9yZWFkYiAodm9pZCAqb3BhcXVlLCB0YXJnZXRfcGh5c19hZGRyX3QgYWRkcikKewogICAgZHMxMjI1eV90ICpzID0gb3BhcXVlOwogICAgaW50NjRfdCBwb3M7CiAgICB1aW50MzJfdCB2YWw7CgogICAgcG9zID0gYWRkciAtIHMtPm1lbV9iYXNlOwogICAgaWYgKHBvcyA+PSBzLT5jaGlwX3NpemUpCiAgICAgICAgcG9zIC09IHMtPmNoaXBfc2l6ZTsKCiAgICB2YWwgPSBzLT5jb250ZW50c1twb3NdOwoKI2lmZGVmIERFQlVHX05WUkFNCiAgICBwcmludGYoIm52cmFtOiByZWFkIDB4JXggYXQgIiBUQVJHRVRfRk1UX2x4ICJcbiIsIHZhbCwgYWRkcik7CiNlbmRpZgogICAgcmV0dXJuIHZhbDsKfQoKc3RhdGljIHVpbnQzMl90IG52cmFtX3JlYWR3ICh2b2lkICpvcGFxdWUsIHRhcmdldF9waHlzX2FkZHJfdCBhZGRyKQp7CiAgICB1aW50MzJfdCB2OwogICAgdiA9IG52cmFtX3JlYWRiKG9wYXF1ZSwgYWRkcik7CiAgICB2IHw9IG52cmFtX3JlYWRiKG9wYXF1ZSwgYWRkciArIDEpIDw8IDg7CiAgICByZXR1cm4gdjsKfQoKc3RhdGljIHVpbnQzMl90IG52cmFtX3JlYWRsICh2b2lkICpvcGFxdWUsIHRhcmdldF9waHlzX2FkZHJfdCBhZGRyKQp7CiAgICB1aW50MzJfdCB2OwogICAgdiA9IG52cmFtX3JlYWRiKG9wYXF1ZSwgYWRkcik7CiAgICB2IHw9IG52cmFtX3JlYWRiKG9wYXF1ZSwgYWRkciArIDEpIDw8IDg7CiAgICB2IHw9IG52cmFtX3JlYWRiKG9wYXF1ZSwgYWRkciArIDIpIDw8IDE2OwogICAgdiB8PSBudnJhbV9yZWFkYihvcGFxdWUsIGFkZHIgKyAzKSA8PCAyNDsKICAgIHJldHVybiB2Owp9CgpzdGF0aWMgdm9pZCBudnJhbV93cml0ZWIgKHZvaWQgKm9wYXF1ZSwgdGFyZ2V0X3BoeXNfYWRkcl90IGFkZHIsIHVpbnQzMl90IHZhbCkKewogICAgZHMxMjI1eV90ICpzID0gb3BhcXVlOwogICAgaW50NjRfdCBwb3M7CgojaWZkZWYgREVCVUdfTlZSQU0KICAgIHByaW50ZigibnZyYW06IHdyaXRlIDB4JXggYXQgIiBUQVJHRVRfRk1UX2x4ICJcbiIsIHZhbCwgYWRkcik7CiNlbmRpZgoKICAgIHBvcyA9IGFkZHIgLSBzLT5tZW1fYmFzZTsKICAgIHMtPmNvbnRlbnRzW3Bvc10gPSB2YWwgJiAweGZmOwogICAgaWYgKHMtPmZpbGUpIHsKICAgICAgICBxZW11X2ZzZWVrKHMtPmZpbGUsIHBvcywgU0VFS19TRVQpOwogICAgICAgIHFlbXVfcHV0X2J5dGUocy0+ZmlsZSwgKGludCl2YWwpOwogICAgICAgIHFlbXVfZmZsdXNoKHMtPmZpbGUpOwogICAgfQp9CgpzdGF0aWMgdm9pZCBudnJhbV93cml0ZXcgKHZvaWQgKm9wYXF1ZSwgdGFyZ2V0X3BoeXNfYWRkcl90IGFkZHIsIHVpbnQzMl90IHZhbCkKewogICAgbnZyYW1fd3JpdGViKG9wYXF1ZSwgYWRkciwgdmFsICYgMHhmZik7CiAgICBudnJhbV93cml0ZWIob3BhcXVlLCBhZGRyICsgMSwgKHZhbCA+PiA4KSAmIDB4ZmYpOwp9CgpzdGF0aWMgdm9pZCBudnJhbV93cml0ZWwgKHZvaWQgKm9wYXF1ZSwgdGFyZ2V0X3BoeXNfYWRkcl90IGFkZHIsIHVpbnQzMl90IHZhbCkKewogICAgbnZyYW1fd3JpdGViKG9wYXF1ZSwgYWRkciwgdmFsICYgMHhmZik7CiAgICBudnJhbV93cml0ZWIob3BhcXVlLCBhZGRyICsgMSwgKHZhbCA+PiA4KSAmIDB4ZmYpOwogICAgbnZyYW1fd3JpdGViKG9wYXF1ZSwgYWRkciArIDIsICh2YWwgPj4gMTYpICYgMHhmZik7CiAgICBudnJhbV93cml0ZWIob3BhcXVlLCBhZGRyICsgMywgKHZhbCA+PiAyNCkgJiAweGZmKTsKfQoKc3RhdGljIHZvaWQgbnZyYW1fd3JpdGViX3Byb3RlY3RlZCAodm9pZCAqb3BhcXVlLCB0YXJnZXRfcGh5c19hZGRyX3QgYWRkciwgdWludDMyX3QgdmFsKQp7CiAgICBkczEyMjV5X3QgKnMgPSBvcGFxdWU7CgogICAgaWYgKHMtPnByb3RlY3Rpb24gIT0gNykgewojaWZkZWYgREVCVUdfTlZSQU0KICAgIHByaW50ZigibnZyYW06IHByZXZlbnQgd3JpdGUgb2YgMHgleCBhdCAiIFRBUkdFVF9GTVRfbHggIlxuIiwgdmFsLCBhZGRyKTsKI2VuZGlmCiAgICAgICAgcmV0dXJuOwogICAgfQoKICAgIG52cmFtX3dyaXRlYihvcGFxdWUsIGFkZHIgLSBzLT5jaGlwX3NpemUsIHZhbCk7Cn0KCnN0YXRpYyB2b2lkIG52cmFtX3dyaXRld19wcm90ZWN0ZWQgKHZvaWQgKm9wYXF1ZSwgdGFyZ2V0X3BoeXNfYWRkcl90IGFkZHIsIHVpbnQzMl90IHZhbCkKewogICAgbnZyYW1fd3JpdGViX3Byb3RlY3RlZChvcGFxdWUsIGFkZHIsIHZhbCAmIDB4ZmYpOwogICAgbnZyYW1fd3JpdGViX3Byb3RlY3RlZChvcGFxdWUsIGFkZHIgKyAxLCAodmFsID4+IDgpICYgMHhmZik7Cn0KCnN0YXRpYyB2b2lkIG52cmFtX3dyaXRlbF9wcm90ZWN0ZWQgKHZvaWQgKm9wYXF1ZSwgdGFyZ2V0X3BoeXNfYWRkcl90IGFkZHIsIHVpbnQzMl90IHZhbCkKewogICAgbnZyYW1fd3JpdGViX3Byb3RlY3RlZChvcGFxdWUsIGFkZHIsIHZhbCAmIDB4ZmYpOwogICAgbnZyYW1fd3JpdGViX3Byb3RlY3RlZChvcGFxdWUsIGFkZHIgKyAxLCAodmFsID4+IDgpICYgMHhmZik7CiAgICBudnJhbV93cml0ZWJfcHJvdGVjdGVkKG9wYXF1ZSwgYWRkciArIDIsICh2YWwgPj4gMTYpICYgMHhmZik7CiAgICBudnJhbV93cml0ZWJfcHJvdGVjdGVkKG9wYXF1ZSwgYWRkciArIDMsICh2YWwgPj4gMjQpICYgMHhmZik7Cn0KCnN0YXRpYyBDUFVSZWFkTWVtb3J5RnVuYyAqbnZyYW1fcmVhZFtdID0gewogICAgJm52cmFtX3JlYWRiLAogICAgJm52cmFtX3JlYWR3LAogICAgJm52cmFtX3JlYWRsLAp9OwoKc3RhdGljIENQVVdyaXRlTWVtb3J5RnVuYyAqbnZyYW1fd3JpdGVbXSA9IHsKICAgICZudnJhbV93cml0ZWIsCiAgICAmbnZyYW1fd3JpdGV3LAogICAgJm52cmFtX3dyaXRlbCwKfTsKCnN0YXRpYyBDUFVXcml0ZU1lbW9yeUZ1bmMgKm52cmFtX3dyaXRlX3Byb3RlY3RlZFtdID0gewogICAgJm52cmFtX3dyaXRlYl9wcm90ZWN0ZWQsCiAgICAmbnZyYW1fd3JpdGV3X3Byb3RlY3RlZCwKICAgICZudnJhbV93cml0ZWxfcHJvdGVjdGVkLAp9OwoKLyogSW5pdGlhbGlzYXRpb24gcm91dGluZSAqLwp2b2lkICpkczEyMjV5X2luaXQodGFyZ2V0X3BoeXNfYWRkcl90IG1lbV9iYXNlLCBjb25zdCBjaGFyICpmaWxlbmFtZSkKewogICAgZHMxMjI1eV90ICpzOwogICAgaW50IG1lbV9pbmRleFJXLCBtZW1faW5kZXhSUDsKICAgIFFFTVVGaWxlICpmaWxlOwoKICAgIHMgPSBxZW11X21hbGxvY3ooc2l6ZW9mKGRzMTIyNXlfdCkpOwogICAgaWYgKCFzKQogICAgICAgIHJldHVybiBOVUxMOwogICAgcy0+Y2hpcF9zaXplID0gMHgyMDAwOyAvKiBGaXhlZCBmb3IgZHMxMjI1eSBjaGlwOiA4IEtpQiAqLwogICAgcy0+Y29udGVudHMgPSBxZW11X21hbGxvY3oocy0+Y2hpcF9zaXplKTsKICAgIGlmICghcy0+Y29udGVudHMpIHsKICAgICAgICByZXR1cm4gTlVMTDsKICAgIH0KICAgIHMtPm1lbV9iYXNlID0gbWVtX2Jhc2U7CiAgICBzLT5wcm90ZWN0aW9uID0gNzsKCiAgICAvKiBSZWFkIGN1cnJlbnQgZmlsZSAqLwogICAgZmlsZSA9IHFlbXVfZm9wZW4oZmlsZW5hbWUsICJyYiIpOwogICAgaWYgKGZpbGUpIHsKICAgICAgICAvKiBSZWFkIG52cmFtIGNvbnRlbnRzICovCiAgICAgICAgcWVtdV9nZXRfYnVmZmVyKGZpbGUsIHMtPmNvbnRlbnRzLCBzLT5jaGlwX3NpemUpOwogICAgICAgIHFlbXVfZmNsb3NlKGZpbGUpOwogICAgfQogICAgcy0+ZmlsZSA9IHFlbXVfZm9wZW4oZmlsZW5hbWUsICJ3YiIpOwogICAgaWYgKHMtPmZpbGUpIHsKICAgICAgICAvKiBXcml0ZSBiYWNrIGNvbnRlbnRzLCBhcyAnd2InIG1vZGUgY2xlYW5lZCB0aGUgZmlsZSAqLwogICAgICAgIHFlbXVfcHV0X2J1ZmZlcihzLT5maWxlLCBzLT5jb250ZW50cywgcy0+Y2hpcF9zaXplKTsKICAgICAgICBxZW11X2ZmbHVzaChzLT5maWxlKTsKICAgIH0KCiAgICAvKiBSZWFkL3dyaXRlIG1lbW9yeSAqLwogICAgbWVtX2luZGV4UlcgPSBjcHVfcmVnaXN0ZXJfaW9fbWVtb3J5KDAsIG52cmFtX3JlYWQsIG52cmFtX3dyaXRlLCBzKTsKICAgIGNwdV9yZWdpc3Rlcl9waHlzaWNhbF9tZW1vcnkobWVtX2Jhc2UsIHMtPmNoaXBfc2l6ZSwgbWVtX2luZGV4UlcpOwogICAgLyogUmVhZC93cml0ZSBwcm90ZWN0ZWQgbWVtb3J5ICovCiAgICBtZW1faW5kZXhSUCA9IGNwdV9yZWdpc3Rlcl9pb19tZW1vcnkoMCwgbnZyYW1fcmVhZCwgbnZyYW1fd3JpdGVfcHJvdGVjdGVkLCBzKTsKICAgIGNwdV9yZWdpc3Rlcl9waHlzaWNhbF9tZW1vcnkobWVtX2Jhc2UgKyBzLT5jaGlwX3NpemUsIHMtPmNoaXBfc2l6ZSwgbWVtX2luZGV4UlApOwogICAgcmV0dXJuIHM7Cn0K