LyogUG9ydGlvbnMgb2YgdGhpcyBmaWxlIGFyZSBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29weXJpZ2h0KHMpLiAgU2VlCiAqIHRoZSBOZXQtU05NUCdzIENPUFlJTkcgZmlsZSBmb3IgbW9yZSBkZXRhaWxzIGFuZCBvdGhlciBjb3B5cmlnaHRzCiAqIHRoYXQgbWF5IGFwcGx5OgogKi8KLyoKICogUG9ydGlvbnMgb2YgdGhpcyBmaWxlIGFyZSBjb3B5cmlnaHRlZCBieToKICogQ29weXJpZ2h0IKkgMjAwMyBTdW4gTWljcm9zeXN0ZW1zLCBJbmMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIFVzZSBpcyBzdWJqZWN0IHRvIGxpY2Vuc2UgdGVybXMgc3BlY2lmaWVkIGluIHRoZSBDT1BZSU5HIGZpbGUKICogZGlzdHJpYnV0ZWQgd2l0aCB0aGUgTmV0LVNOTVAgcGFja2FnZS4KICovCiNpbmNsdWRlIDxuZXQtc25tcC9uZXQtc25tcC1jb25maWcuaD4KI2luY2x1ZGUgPG5ldC1zbm1wL25ldC1zbm1wLWZlYXR1cmVzLmg+CgojaW5jbHVkZSA8bmV0LXNubXAvbmV0LXNubXAtaW5jbHVkZXMuaD4KI2luY2x1ZGUgPG5ldC1zbm1wL2FnZW50L25ldC1zbm1wLWFnZW50LWluY2x1ZGVzLmg+CgojaW5jbHVkZSA8bmV0LXNubXAvYWdlbnQvbW9kZV9lbmRfY2FsbC5oPgoKbmV0c25tcF9mZWF0dXJlX3Byb3ZpZGUobW9kZV9lbmRfY2FsbCkKbmV0c25tcF9mZWF0dXJlX2NoaWxkX29mKG1vZGVfZW5kX2NhbGwsIG1pYl9oZWxwZXJzKQoKI2lmbmRlZiBORVRTTk1QX0ZFQVRVUkVfUkVNT1ZFX01PREVfRU5EX0NBTEwKLyoqIEBkZWZncm91cCBtb2RlX2VuZF9jYWxsIG1vZGVfZW5kX2NhbGwKICogIEF0IHRoZSBlbmQgb2YgYSBzZXJpZXMgb2YgcmVxdWVzdHMsIGNhbGwgYW5vdGhlciBoYW5kbGVyIGhvb2suCiAqICBIYW5kbGVycyB0aGF0IHdhbnQgdG8gbG9vcCB0aHJvdWdoIGEgc2VyaWVzIG9mIHJlcXVlc3RzIGFuZCB0aGVuCiAqICByZWNlaXZlIGEgY2FsbGJhY2sgYXQgdGhlIGVuZCBvZiBhIHBhcnRpY3VsYXIgTU9ERSBjYW4gdXNlIHRoaXMKICogIGhlbHBlciB0byBtYWtlIHRoaXMgcG9zc2libGUuICBGb3IgbW9zdCBtb2R1bGVzLCB0aGlzIGlzIG5vdAogKiAgbmVlZGVkIGFzIHRoZSBoYW5kbGVyIGl0c2VsZiBjb3VsZCBwZXJmb3JtIGEgZm9yKCkgbG9vcCBhcm91bmQgdGhlCiAqICByZXF1ZXN0IGxpc3QgYW5kIHRoZW4gcGVyZm9ybSBpdHMgYWN0aW9ucyBhZnRlcndhcmRzLiAgSG93ZXZlciwgaWYKICogIHNvbWV0aGluZyBsaWtlIHRoZSBzZXJpYWxpemUgaGVscGVyIGlzIGluIHVzZSB0aGlzIGlzbid0IHBvc3NpYmxlCiAqICBiZWNhdXNlIG5vdCBhbGwgdGhlIHJlcXVlc3RzIGZvciBhIGdpdmVuIGhhbmRsZXIgYXJlIGJlaW5nIHBhc3NlZAogKiAgZG93bndhcmQgaW4gYSBzaW5nbGUgZ3JvdXAuICBUaHVzLCB0aGlzIGhlbHBlciAqbXVzdCogYmUgYWRkZWQKICogIGFib3ZlIG90aGVyIGhlbHBlcnMgbGlrZSB0aGUgc2VyaWFsaXplIGhlbHBlciB0byBiZSB1c2VmdWwuCiAqCiAqICBNdWx0aXBsZSBtb2RlIHNwZWNpZmljIGhhbmRsZXJzIGNhbiBiZSByZWdpc3RlcmVkIGFuZCB3aWxsIGJlCiAqICBjYWxsZWQgaW4gdGhlIG9yZGVyIHRoZXkgd2VyZSByZWdlc3RlcmVkIGluLiAgQ2FsbGJhY2tzIHJlZ2VzdGVyZAogKiAgd2l0aCBhIG1vZGUgb2YgTkVUU05NUF9NT0RFX0VORF9BTExfTU9ERVMgd2lsbCBiZSBjYWxsZWQgZm9yIGFsbAogKiAgbW9kZXMuCiAqIAogKiAgQGluZ3JvdXAgdXRpbGl0aWVzCiAqICBAewogKi8KCi8qKiByZXR1cm5zIGEgbW9kZV9lbmRfY2FsbCBoYW5kbGVyIHRoYXQgY2FuIGJlIGluamVjdGVkIGludG8gYSBnaXZlbgogKiAgaGFuZGxlciBjaGFpbi4KICogQHBhcmFtIGVuZGxpc3QgVGhlIGNhbGxiYWNrIGxpc3QgZm9yIHRoZSBoYW5kbGVyIHRvIG1ha2UgdXNlIG9mLgogKiBAcmV0dXJuIEFuIGluamVjdGFibGUgTmV0LVNOTVAgaGFuZGxlci4KICovCm5ldHNubXBfbWliX2hhbmRsZXIgKgpuZXRzbm1wX2dldF9tb2RlX2VuZF9jYWxsX2hhbmRsZXIobmV0c25tcF9tb2RlX2hhbmRsZXJfbGlzdCAqZW5kbGlzdCkKewogICAgbmV0c25tcF9taWJfaGFuZGxlciAqbWUgPQogICAgICAgIG5ldHNubXBfY3JlYXRlX2hhbmRsZXIoIm1vZGVfZW5kX2NhbGwiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9tb2RlX2VuZF9jYWxsX2hlbHBlcik7CgogICAgaWYgKCFtZSkKICAgICAgICByZXR1cm4gTlVMTDsKCiAgICBtZS0+bXl2b2lkID0gZW5kbGlzdDsKICAgIHJldHVybiBtZTsKfQoKLyoqIGFkZHMgYSBtb2RlIHNwZWNpZmljIGNhbGxiYWNrIHRvIHRoZSBjYWxsYmFjayBsaXN0LgogKiBAcGFyYW0gZW5kbGlzdCB0aGUgaW5mb3JtYXRpb24gc3RydWN0dXJlIGZvciB0aGUgbW9kZV9lbmRfY2FsbCBoZWxwZXIuICBDYW4gYmUgTlVMTCB0byBjcmVhdGUgYSBuZXcgbGlzdC4KICogQHBhcmFtIG1vZGUgdGhlIG1vZGUgdG8gYmUgY2FsbGVkIHVwb24uICBBIG1vZGUgb2YgTkVUU05NUF9NT0RFX0VORF9BTExfTU9ERVMgPSBhbGwgbW9kZXMuCiAqIEBwYXJhbSBjYWxsYmFja2ggdGhlIG5ldHNubXBfbWliX2hhbmRsZXIgY2FsbGJhY2sgdG8gY2FsbC4KICogQHJldHVybiB0aGUgbmV3IHJlZ2lzdHJhdGlvbiBpbmZvcm1hdGlvbiBsaXN0IHVwb24gc3VjY2Vzcy4KICovCm5ldHNubXBfbW9kZV9oYW5kbGVyX2xpc3QgKgpuZXRzbm1wX21vZGVfZW5kX2NhbGxfYWRkX21vZGVfY2FsbGJhY2sobmV0c25tcF9tb2RlX2hhbmRsZXJfbGlzdCAqZW5kbGlzdCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBtb2RlLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9taWJfaGFuZGxlciAqY2FsbGJhY2toKSB7CiAgICBuZXRzbm1wX21vZGVfaGFuZGxlcl9saXN0ICpwdHIsICpwdHIyOwogICAgcHRyID0gU05NUF9NQUxMT0NfVFlQRURFRihuZXRzbm1wX21vZGVfaGFuZGxlcl9saXN0KTsKICAgIGlmICghcHRyKQogICAgICAgIHJldHVybiBOVUxMOwogICAgCiAgICBwdHItPm1vZGUgPSBtb2RlOwogICAgcHRyLT5jYWxsYmFja19oYW5kbGVyID0gY2FsbGJhY2toOwogICAgcHRyLT5uZXh0ID0gTlVMTDsKCiAgICBpZiAoIWVuZGxpc3QpCiAgICAgICAgcmV0dXJuIHB0cjsKCiAgICAvKiBnZXQgdG8gZW5kICovCiAgICBmb3IocHRyMiA9IGVuZGxpc3Q7IHB0cjItPm5leHQgIT0gTlVMTDsgcHRyMiA9IHB0cjItPm5leHQpOwoKICAgIHB0cjItPm5leHQgPSBwdHI7CiAgICByZXR1cm4gZW5kbGlzdDsKfQogICAgCi8qKiBAaW50ZXJuYWwgSW1wbGVtZW50cyB0aGUgbW9kZV9lbmRfY2FsbCBoYW5kbGVyICovCmludApuZXRzbm1wX21vZGVfZW5kX2NhbGxfaGVscGVyKG5ldHNubXBfbWliX2hhbmRsZXIgKmhhbmRsZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX2hhbmRsZXJfcmVnaXN0cmF0aW9uICpyZWdpbmZvLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9hZ2VudF9yZXF1ZXN0X2luZm8gKnJlcWluZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX3JlcXVlc3RfaW5mbyAqcmVxdWVzdHMpCnsKCiAgICBpbnQgICAgICAgICAgICAgcmV0OwogICAgaW50ICAgICAgICAgICAgIHJldDIgPSBTTk1QX0VSUl9OT0VSUk9SOwogICAgbmV0c25tcF9tb2RlX2hhbmRsZXJfbGlzdCAqcHRyOwoKICAgIC8qIGFsd2F5cyBjYWxsIHRoZSByZWFsIGhhbmRsZXJzIGZpcnN0ICovCiAgICByZXQgPSBuZXRzbm1wX2NhbGxfbmV4dF9oYW5kbGVyKGhhbmRsZXIsIHJlZ2luZm8sIHJlcWluZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcXVlc3RzKTsKCiAgICAvKiB0aGVuIGNhbGwgdGhlIGNhbGxiYWNrIGhhbmRsZXJzICovCiAgICBmb3IgKHB0ciA9IChuZXRzbm1wX21vZGVfaGFuZGxlcl9saXN0KiloYW5kbGVyLT5teXZvaWQ7IHB0cjsgcHRyID0gcHRyLT5uZXh0KSB7CiAgICAgICAgaWYgKHB0ci0+bW9kZSA9PSBORVRTTk1QX01PREVfRU5EX0FMTF9NT0RFUyB8fAogICAgICAgICAgICByZXFpbmZvLT5tb2RlID09IHB0ci0+bW9kZSkgewogICAgICAgICAgICByZXQyID0gbmV0c25tcF9jYWxsX2hhbmRsZXIocHRyLT5jYWxsYmFja19oYW5kbGVyLCByZWdpbmZvLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByZXFpbmZvLCByZXF1ZXN0cyk7CiAgICAgICAgICAgIGlmIChyZXQgIT0gU05NUF9FUlJfTk9FUlJPUikKICAgICAgICAgICAgICAgIHJldCA9IHJldDI7CiAgICAgICAgfQogICAgfQogICAgCiAgICByZXR1cm4gcmV0MjsKfQojZWxzZQpuZXRzbm1wX2ZlYXR1cmVfdW51c2VkKG1vZGVfZW5kX2NhbGwpOwojZW5kaWYgLyogTkVUU05NUF9GRUFUVVJFX1JFTU9WRV9NT0RFX0VORF9DQUxMICovCgoKLyoqICBAfSAqLwoK