LyogUG9ydGlvbnMgb2YgdGhpcyBmaWxlIGFyZSBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29weXJpZ2h0KHMpLiAgU2VlCiAqIHRoZSBOZXQtU05NUCdzIENPUFlJTkcgZmlsZSBmb3IgbW9yZSBkZXRhaWxzIGFuZCBvdGhlciBjb3B5cmlnaHRzCiAqIHRoYXQgbWF5IGFwcGx5OgogKi8KLyoKICogUG9ydGlvbnMgb2YgdGhpcyBmaWxlIGFyZSBjb3B5cmlnaHRlZCBieToKICogQ29weXJpZ2h0IKkgMjAwMyBTdW4gTWljcm9zeXN0ZW1zLCBJbmMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIFVzZSBpcyBzdWJqZWN0IHRvIGxpY2Vuc2UgdGVybXMgc3BlY2lmaWVkIGluIHRoZSBDT1BZSU5HIGZpbGUKICogZGlzdHJpYnV0ZWQgd2l0aCB0aGUgTmV0LVNOTVAgcGFja2FnZS4KICovCiNpbmNsdWRlIDxuZXQtc25tcC9uZXQtc25tcC1jb25maWcuaD4KCiNpbmNsdWRlIDxuZXQtc25tcC9uZXQtc25tcC1pbmNsdWRlcy5oPgojaW5jbHVkZSA8bmV0LXNubXAvYWdlbnQvbmV0LXNubXAtYWdlbnQtaW5jbHVkZXMuaD4KCiNpbmNsdWRlIDxuZXQtc25tcC9hZ2VudC9tb2RlX2VuZF9jYWxsLmg+CgovKiogQGRlZmdyb3VwIG1vZGVfZW5kX2NhbGwgbW9kZV9lbmRfY2FsbAogKiAgQXQgdGhlIGVuZCBvZiBhIHNlcmllcyBvZiByZXF1ZXN0cywgY2FsbCBhbm90aGVyIGhhbmRsZXIgaG9vay4KICogIEhhbmRsZXJzIHRoYXQgd2FudCB0byBsb29wIHRocm91Z2ggYSBzZXJpZXMgb2YgcmVxdWVzdHMgYW5kIHRoZW4KICogIHJlY2VpdmUgYSBjYWxsYmFjayBhdCB0aGUgZW5kIG9mIGEgcGFydGljdWxhciBNT0RFIGNhbiB1c2UgdGhpcwogKiAgaGVscGVyIHRvIG1ha2UgdGhpcyBwb3NzaWJsZS4gIEZvciBtb3N0IG1vZHVsZXMsIHRoaXMgaXMgbm90CiAqICBuZWVkZWQgYXMgdGhlIGhhbmRsZXIgaXRzZWxmIGNvdWxkIHBlcmZvcm0gYSBmb3IoKSBsb29wIGFyb3VuZCB0aGUKICogIHJlcXVlc3QgbGlzdCBhbmQgdGhlbiBwZXJmb3JtIGl0cyBhY3Rpb25zIGFmdGVyd2FyZHMuICBIb3dldmVyLCBpZgogKiAgc29tZXRoaW5nIGxpa2UgdGhlIHNlcmlhbGl6ZSBoZWxwZXIgaXMgaW4gdXNlIHRoaXMgaXNuJ3QgcG9zc2libGUKICogIGJlY2F1c2Ugbm90IGFsbCB0aGUgcmVxdWVzdHMgZm9yIGEgZ2l2ZW4gaGFuZGxlciBhcmUgYmVpbmcgcGFzc2VkCiAqICBkb3dud2FyZCBpbiBhIHNpbmdsZSBncm91cC4gIFRodXMsIHRoaXMgaGVscGVyICptdXN0KiBiZSBhZGRlZAogKiAgYWJvdmUgb3RoZXIgaGVscGVycyBsaWtlIHRoZSBzZXJpYWxpemUgaGVscGVyIHRvIGJlIHVzZWZ1bC4KICoKICogIE11bHRpcGxlIG1vZGUgc3BlY2lmaWMgaGFuZGxlcnMgY2FuIGJlIHJlZ2lzdGVyZWQgYW5kIHdpbGwgYmUKICogIGNhbGxlZCBpbiB0aGUgb3JkZXIgdGhleSB3ZXJlIHJlZ2VzdGVyZWQgaW4uICBDYWxsYmFja3MgcmVnZXN0ZXJkCiAqICB3aXRoIGEgbW9kZSBvZiBORVRTTk1QX01PREVfRU5EX0FMTF9NT0RFUyB3aWxsIGJlIGNhbGxlZCBmb3IgYWxsCiAqICBtb2Rlcy4KICogCiAqICBAaW5ncm91cCB1dGlsaXRpZXMKICogIEB7CiAqLwoKLyoqIHJldHVybnMgYSBtb2RlX2VuZF9jYWxsIGhhbmRsZXIgdGhhdCBjYW4gYmUgaW5qZWN0ZWQgaW50byBhIGdpdmVuCiAqICBoYW5kbGVyIGNoYWluLgogKiBAcGFyYW0gZW5kbGlzdCBUaGUgY2FsbGJhY2sgbGlzdCBmb3IgdGhlIGhhbmRsZXIgdG8gbWFrZSB1c2Ugb2YuCiAqIEByZXR1cm4gQW4gaW5qZWN0YWJsZSBOZXQtU05NUCBoYW5kbGVyLgogKi8KbmV0c25tcF9taWJfaGFuZGxlciAqCm5ldHNubXBfZ2V0X21vZGVfZW5kX2NhbGxfaGFuZGxlcihuZXRzbm1wX21vZGVfaGFuZGxlcl9saXN0ICplbmRsaXN0KQp7CiAgICBuZXRzbm1wX21pYl9oYW5kbGVyICptZSA9CiAgICAgICAgbmV0c25tcF9jcmVhdGVfaGFuZGxlcigibW9kZV9lbmRfY2FsbCIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX21vZGVfZW5kX2NhbGxfaGVscGVyKTsKCiAgICBpZiAoIW1lKQogICAgICAgIHJldHVybiBOVUxMOwoKICAgIG1lLT5teXZvaWQgPSBlbmRsaXN0OwogICAgcmV0dXJuIG1lOwp9CgovKiogYWRkcyBhIG1vZGUgc3BlY2lmaWMgY2FsbGJhY2sgdG8gdGhlIGNhbGxiYWNrIGxpc3QuCiAqIEBwYXJhbSBlbmRsaXN0IHRoZSBpbmZvcm1hdGlvbiBzdHJ1Y3R1cmUgZm9yIHRoZSBtb2RlX2VuZF9jYWxsIGhlbHBlci4gIENhbiBiZSBOVUxMIHRvIGNyZWF0ZSBhIG5ldyBsaXN0LgogKiBAcGFyYW0gbW9kZSB0aGUgbW9kZSB0byBiZSBjYWxsZWQgdXBvbi4gIEEgbW9kZSBvZiBORVRTTk1QX01PREVfRU5EX0FMTF9NT0RFUyA9IGFsbCBtb2Rlcy4KICogQHBhcmFtIGNhbGxiYWNraCB0aGUgbmV0c25tcF9taWJfaGFuZGxlciBjYWxsYmFjayB0byBjYWxsLgogKiBAcmV0dXJuIHRoZSBuZXcgcmVnaXN0cmF0aW9uIGluZm9ybWF0aW9uIGxpc3QgdXBvbiBzdWNjZXNzLgogKi8KbmV0c25tcF9tb2RlX2hhbmRsZXJfbGlzdCAqCm5ldHNubXBfbW9kZV9lbmRfY2FsbF9hZGRfbW9kZV9jYWxsYmFjayhuZXRzbm1wX21vZGVfaGFuZGxlcl9saXN0ICplbmRsaXN0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IG1vZGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX21pYl9oYW5kbGVyICpjYWxsYmFja2gpIHsKICAgIG5ldHNubXBfbW9kZV9oYW5kbGVyX2xpc3QgKnB0ciwgKnB0cjI7CiAgICBwdHIgPSBTTk1QX01BTExPQ19UWVBFREVGKG5ldHNubXBfbW9kZV9oYW5kbGVyX2xpc3QpOwogICAgaWYgKCFwdHIpCiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICAKICAgIHB0ci0+bW9kZSA9IG1vZGU7CiAgICBwdHItPmNhbGxiYWNrX2hhbmRsZXIgPSBjYWxsYmFja2g7CiAgICBwdHItPm5leHQgPSBOVUxMOwoKICAgIGlmICghZW5kbGlzdCkKICAgICAgICByZXR1cm4gcHRyOwoKICAgIC8qIGdldCB0byBlbmQgKi8KICAgIGZvcihwdHIyID0gZW5kbGlzdDsgcHRyMi0+bmV4dCAhPSBOVUxMOyBwdHIyID0gcHRyMi0+bmV4dCk7CgogICAgcHRyMi0+bmV4dCA9IHB0cjsKICAgIHJldHVybiBlbmRsaXN0Owp9CiAgICAKLyoqIEBpbnRlcm5hbCBJbXBsZW1lbnRzIHRoZSBtb2RlX2VuZF9jYWxsIGhhbmRsZXIgKi8KaW50Cm5ldHNubXBfbW9kZV9lbmRfY2FsbF9oZWxwZXIobmV0c25tcF9taWJfaGFuZGxlciAqaGFuZGxlciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfaGFuZGxlcl9yZWdpc3RyYXRpb24gKnJlZ2luZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX2FnZW50X3JlcXVlc3RfaW5mbyAqcmVxaW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfcmVxdWVzdF9pbmZvICpyZXF1ZXN0cykKewoKICAgIGludCAgICAgICAgICAgICByZXQ7CiAgICBpbnQgICAgICAgICAgICAgcmV0MiA9IFNOTVBfRVJSX05PRVJST1I7CiAgICBuZXRzbm1wX21vZGVfaGFuZGxlcl9saXN0ICpwdHI7CgogICAgLyogYWx3YXlzIGNhbGwgdGhlIHJlYWwgaGFuZGxlcnMgZmlyc3QgKi8KICAgIHJldCA9IG5ldHNubXBfY2FsbF9uZXh0X2hhbmRsZXIoaGFuZGxlciwgcmVnaW5mbywgcmVxaW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVxdWVzdHMpOwoKICAgIC8qIHRoZW4gY2FsbCB0aGUgY2FsbGJhY2sgaGFuZGxlcnMgKi8KICAgIGZvciAocHRyID0gKG5ldHNubXBfbW9kZV9oYW5kbGVyX2xpc3QqKWhhbmRsZXItPm15dm9pZDsgcHRyOyBwdHIgPSBwdHItPm5leHQpIHsKICAgICAgICBpZiAocHRyLT5tb2RlID09IE5FVFNOTVBfTU9ERV9FTkRfQUxMX01PREVTIHx8CiAgICAgICAgICAgIHJlcWluZm8tPm1vZGUgPT0gcHRyLT5tb2RlKSB7CiAgICAgICAgICAgIHJldDIgPSBuZXRzbm1wX2NhbGxfaGFuZGxlcihwdHItPmNhbGxiYWNrX2hhbmRsZXIsIHJlZ2luZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcWluZm8sIHJlcXVlc3RzKTsKICAgICAgICAgICAgaWYgKHJldCAhPSBTTk1QX0VSUl9OT0VSUk9SKQogICAgICAgICAgICAgICAgcmV0ID0gcmV0MjsKICAgICAgICB9CiAgICB9CiAgICAKICAgIHJldHVybiByZXQyOwp9Ci8qKiAgQH0gKi8KCg==