LyogUG9ydGlvbnMgb2YgdGhpcyBmaWxlIGFyZSBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29weXJpZ2h0KHMpLiAgU2VlCiAqIHRoZSBOZXQtU05NUCdzIENPUFlJTkcgZmlsZSBmb3IgbW9yZSBkZXRhaWxzIGFuZCBvdGhlciBjb3B5cmlnaHRzCiAqIHRoYXQgbWF5IGFwcGx5OgogKi8KLyoKICogUG9ydGlvbnMgb2YgdGhpcyBmaWxlIGFyZSBjb3B5cmlnaHRlZCBieToKICogQ29weXJpZ2h0IKkgMjAwMyBTdW4gTWljcm9zeXN0ZW1zLCBJbmMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIFVzZSBpcyBzdWJqZWN0IHRvIGxpY2Vuc2UgdGVybXMgc3BlY2lmaWVkIGluIHRoZSBDT1BZSU5HIGZpbGUKICogZGlzdHJpYnV0ZWQgd2l0aCB0aGUgTmV0LVNOTVAgcGFja2FnZS4KICovCiNpbmNsdWRlIDxuZXQtc25tcC9uZXQtc25tcC1jb25maWcuaD4KCiNpbmNsdWRlIDxzdGRsaWIuaD4KI2lmIEhBVkVfU1RSSU5HX0gKI2luY2x1ZGUgPHN0cmluZy5oPgojZWxzZQojaW5jbHVkZSA8c3RyaW5ncy5oPgojZW5kaWYKCiNpbmNsdWRlIDxuZXQtc25tcC9uZXQtc25tcC1pbmNsdWRlcy5oPgojaW5jbHVkZSA8bmV0LXNubXAvYWdlbnQvbmV0LXNubXAtYWdlbnQtaW5jbHVkZXMuaD4KCiNpbmNsdWRlIDxuZXQtc25tcC9hZ2VudC9zY2FsYXIuaD4KI2luY2x1ZGUgPG5ldC1zbm1wL2FnZW50L2luc3RhbmNlLmg+CiNpbmNsdWRlIDxuZXQtc25tcC9hZ2VudC9zZXJpYWxpemUuaD4KI2luY2x1ZGUgPG5ldC1zbm1wL2FnZW50L3JlYWRfb25seS5oPgoKLyoqIEBkZWZncm91cCBzY2FsYXIgc2NhbGFyCiAqICBQcm9jZXNzIHNjYWxhcnMgZWFzaWx5LgogKiAgQGluZ3JvdXAgbGVhZgogKiAgQHsKICovCgovKioKICogQ3JlYXRlcyBhIHNjYWxhciBoYW5kbGVyIGNhbGxpbmcgbmV0c25tcF9jcmVhdGVfaGFuZGxlciB3aXRoIGEKICogaGFuZGxlciBuYW1lIGRlZmF1bHRlZCB0byAic2NhbGFyIiBhbmQgYWNjZXNzIG1ldGhvZCwgCiAqIG5ldHNubXBfc2NhbGFyX2hlbHBlcl9oYW5kbGVyLgogKgogKiBAcmV0dXJuIFJldHVybnMgYSBwb2ludGVyIHRvIGEgbmV0c25tcF9taWJfaGFuZGxlciBzdHJ1Y3Qgd2hpY2ggY29udGFpbnMKICoJdGhlIGhhbmRsZXIncyBuYW1lIGFuZCB0aGUgYWNjZXNzIG1ldGhvZAogKgogKiBAc2VlIG5ldHNubXBfZ2V0X3NjYWxhcl9oYW5kbGVyCiAqIEBzZWUgbmV0c25tcF9yZWdpc3Rlcl9zY2FsYXIKICovCm5ldHNubXBfbWliX2hhbmRsZXIgKgpuZXRzbm1wX2dldF9zY2FsYXJfaGFuZGxlcih2b2lkKQp7CiAgICByZXR1cm4gbmV0c25tcF9jcmVhdGVfaGFuZGxlcigic2NhbGFyIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfc2NhbGFyX2hlbHBlcl9oYW5kbGVyKTsKfQoKLyoqCiAqIFRoaXMgZnVuY3Rpb24gcmVnaXN0ZXJzIGEgc2NhbGFyIGhlbHBlciBoYW5kbGVyLiAgVGhlIHJlZ2lzdGVyZWQgT0lELCAKICogcmVnaW5mby0+cm9vdG9pZCwgc3BhY2UgaXMgZXh0ZW5kZWQgZm9yIHRoZSBpbnN0YW5jZSBzdWJpZCB1c2luZyAKICogcmVhbGxvYygpIGJ1dCB0aGUgcmVnaW5mby0+cm9vdG9pZF9sZW4gbGVuZ3RoIGlzIG5vdCBleHRlbmRlZCBqdXN0IHlldC4KICogLlRoaXMgZnVuY3Rpb24gc3Vic2VxdWVudGx5IGluamVjdHMgdGhlIGluc3RhbmNlLCBzY2FsYXIsIGFuZCBzZXJpYWxpemUKICogaGVscGVyIGhhbmRsZXJzIGJlZm9yZSBhY3R1YWxseSByZWdpc3RlcmluZyByZWdpbmZvLgogKgogKiBFYWNoIGhhbmRsZXIgaXMgaW5qZWN0ZWQvcHVzaGVkIHRvIHRoZSB0b3Agb2YgdGhlIGhhbmRsZXIgY2hhaW4gbGlzdCAKICogYW5kIHdpbGwgYmUgcHJvY2Vzc2VkIGxhc3QgaW4gZmlyc3Qgb3V0LCBMSUZPLgogKgogKiBAcGFyYW0gcmVnaW5mbyBhIGhhbmRsZXIgcmVnaXN0cmF0aW9uIHN0cnVjdHVyZSB3aGljaCBjb3VsZCBnZXQgY3JlYXRlZAogKiAgICAgICAgICAgICAgICB1c2luZyBuZXRzbm1wX2NyZWF0ZV9oYW5kbGVyX3JlZ2lzdHJhdGlvbi4gIFVzZWQgdG8gcmVnaXN0ZXIKICogICAgICAgICAgICAgICAgYSBzY2FsYXIgaGVscGVyIGhhbmRsZXIuCiAqCiAqIEByZXR1cm4gTUlCX1JFR0lTVEVSRURfT0sgaXMgcmV0dXJuZWQgaWYgdGhlIHJlZ2lzdHJhdGlvbiB3YXMgYSBzdWNjZXNzLgogKglGYWlsdXJlcyBhcmUgTUlCX1JFR0lTVFJBVElPTl9GQUlMVVJFIGFuZCBNSUJfRFVQTElDQVRFX1JFR0lTVFJBVElPTi4KICoKICogQHNlZSBuZXRzbm1wX3JlZ2lzdGVyX3JlYWRfb25seV9zY2FsYXIKICogQHNlZSBuZXRzbm1wX2dldF9zY2FsYXJfaGFuZGxlcgogKi8KCmludApuZXRzbm1wX3JlZ2lzdGVyX3NjYWxhcihuZXRzbm1wX2hhbmRsZXJfcmVnaXN0cmF0aW9uICpyZWdpbmZvKQp7CiAgICAvKgogICAgICogRXh0ZW5kIHRoZSByZWdpc3RlcmVkIE9JRCB3aXRoIHNwYWNlIGZvciB0aGUgaW5zdGFuY2Ugc3ViaWQKICAgICAqIChidXQgZG9uJ3QgZXh0ZW5kIHRoZSBsZW5ndGgganVzdCB5ZXQhKQogICAgICovCiAgICByZWdpbmZvLT5yb290b2lkID0gcmVhbGxvYyhyZWdpbmZvLT5yb290b2lkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAocmVnaW5mby0+cm9vdG9pZF9sZW4rMSkgKiBzaXplb2Yob2lkKSApOwogICAgcmVnaW5mby0+cm9vdG9pZFsgcmVnaW5mby0+cm9vdG9pZF9sZW4gXSA9IDA7CgogICAgbmV0c25tcF9pbmplY3RfaGFuZGxlcihyZWdpbmZvLCBuZXRzbm1wX2dldF9pbnN0YW5jZV9oYW5kbGVyKCkpOwogICAgbmV0c25tcF9pbmplY3RfaGFuZGxlcihyZWdpbmZvLCBuZXRzbm1wX2dldF9zY2FsYXJfaGFuZGxlcigpKTsKICAgIHJldHVybiBuZXRzbm1wX3JlZ2lzdGVyX3NlcmlhbGl6ZShyZWdpbmZvKTsKfQoKCi8qKgogKiBUaGlzIGZ1bmN0aW9uIHJlZ2lzdGVycyBhIHJlYWQgb25seSBzY2FsYXIgaGVscGVyIGhhbmRsZXIuIFRoaXMgCiAqIGZ1bmN0aW9uIGlzIHZlcnkgc2ltaWxhciB0byBuZXRzbm1wX3JlZ2lzdGVyX3NjYWxhciB0aGUgb25seSBhZGRpdGlvbgogKiBpcyB0aGF0IHRoZSAicmVhZF9vbmx5IiBoYW5kbGVyIGlzIGluamVjdGVkIGludG8gdGhlIGhhbmRsZXIgY2hhaW4KICogcHJpb3IgdG8gaW5qZWN0aW5nIHRoZSBzZXJpYWxpemUgaGFuZGxlciBhbmQgcmVnaXN0ZXJpbmcgcmVnaW5mby4KICoKICogQHBhcmFtIHJlZ2luZm8gYSBoYW5kbGVyIHJlZ2lzdHJhdGlvbiBzdHJ1Y3R1cmUgd2hpY2ggY291bGQgZ2V0IGNyZWF0ZWQKICogICAgICAgICAgICAgICAgdXNpbmcgbmV0c25tcF9jcmVhdGVfaGFuZGxlcl9yZWdpc3RyYXRpb24uICBVc2VkIHRvIHJlZ2lzdGVyCiAqICAgICAgICAgICAgICAgIGEgcmVhZCBvbmx5IHNjYWxhciBoZWxwZXIgaGFuZGxlci4KICoKICogQHJldHVybiAgTUlCX1JFR0lTVEVSRURfT0sgaXMgcmV0dXJuZWQgaWYgdGhlIHJlZ2lzdHJhdGlvbiB3YXMgYSBzdWNjZXNzLgogKiAgCUZhaWx1cmVzIGFyZSBNSUJfUkVHSVNUUkFUSU9OX0ZBSUxVUkUgYW5kIE1JQl9EVVBMSUNBVEVfUkVHSVNUUkFUSU9OLgogKgogKiBAc2VlIG5ldHNubXBfcmVnaXN0ZXJfc2NhbGFyCiAqIEBzZWUgbmV0c25tcF9nZXRfc2NhbGFyX2hhbmRsZXIKICoKICovCiAKaW50Cm5ldHNubXBfcmVnaXN0ZXJfcmVhZF9vbmx5X3NjYWxhcihuZXRzbm1wX2hhbmRsZXJfcmVnaXN0cmF0aW9uICpyZWdpbmZvKQp7CiAgICAvKgogICAgICogRXh0ZW5kIHRoZSByZWdpc3RlcmVkIE9JRCB3aXRoIHNwYWNlIGZvciB0aGUgaW5zdGFuY2Ugc3ViaWQKICAgICAqIChidXQgZG9uJ3QgZXh0ZW5kIHRoZSBsZW5ndGgganVzdCB5ZXQhKQogICAgICovCiAgICByZWdpbmZvLT5yb290b2lkID0gcmVhbGxvYyhyZWdpbmZvLT5yb290b2lkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAocmVnaW5mby0+cm9vdG9pZF9sZW4rMSkgKiBzaXplb2Yob2lkKSApOwogICAgcmVnaW5mby0+cm9vdG9pZFsgcmVnaW5mby0+cm9vdG9pZF9sZW4gXSA9IDA7CgogICAgbmV0c25tcF9pbmplY3RfaGFuZGxlcihyZWdpbmZvLCBuZXRzbm1wX2dldF9pbnN0YW5jZV9oYW5kbGVyKCkpOwogICAgbmV0c25tcF9pbmplY3RfaGFuZGxlcihyZWdpbmZvLCBuZXRzbm1wX2dldF9zY2FsYXJfaGFuZGxlcigpKTsKICAgIG5ldHNubXBfaW5qZWN0X2hhbmRsZXIocmVnaW5mbywgbmV0c25tcF9nZXRfcmVhZF9vbmx5X2hhbmRsZXIoKSk7CiAgICByZXR1cm4gbmV0c25tcF9yZWdpc3Rlcl9zZXJpYWxpemUocmVnaW5mbyk7Cn0KCgoKaW50Cm5ldHNubXBfc2NhbGFyX2hlbHBlcl9oYW5kbGVyKG5ldHNubXBfbWliX2hhbmRsZXIgKmhhbmRsZXIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV0c25tcF9oYW5kbGVyX3JlZ2lzdHJhdGlvbiAqcmVnaW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX2FnZW50X3JlcXVlc3RfaW5mbyAqcmVxaW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXRzbm1wX3JlcXVlc3RfaW5mbyAqcmVxdWVzdHMpCnsKCiAgICBuZXRzbm1wX3ZhcmlhYmxlX2xpc3QgKnZhciA9IHJlcXVlc3RzLT5yZXF1ZXN0dmI7CgogICAgaW50ICAgICAgICAgICAgIHJldCwgY21wOwogICAgaW50ICAgICAgICAgICAgIG5hbWVsZW47CgogICAgREVCVUdNU0dUTCgoImhlbHBlcjpzY2FsYXIiLCAiR290IHJlcXVlc3Q6XG4iKSk7CiAgICBuYW1lbGVuID0gU05NUF9NSU4ocmVxdWVzdHMtPnJlcXVlc3R2Yi0+bmFtZV9sZW5ndGgsCiAgICAgICAgICAgICAgICAgICAgICAgcmVnaW5mby0+cm9vdG9pZF9sZW4pOwogICAgY21wID0gc25tcF9vaWRfY29tcGFyZShyZXF1ZXN0cy0+cmVxdWVzdHZiLT5uYW1lLCBuYW1lbGVuLAogICAgICAgICAgICAgICAgICAgICAgICAgICByZWdpbmZvLT5yb290b2lkLCByZWdpbmZvLT5yb290b2lkX2xlbik7CgogICAgREVCVUdNU0dUTCgoImhlbHBlcjpzY2FsYXIiLCAiICBvaWQ6IikpOwogICAgREVCVUdNU0dPSUQoKCJoZWxwZXI6c2NhbGFyIiwgdmFyLT5uYW1lLCB2YXItPm5hbWVfbGVuZ3RoKSk7CiAgICBERUJVR01TRygoImhlbHBlcjpzY2FsYXIiLCAiXG4iKSk7CgogICAgc3dpdGNoIChyZXFpbmZvLT5tb2RlKSB7CiAgICBjYXNlIE1PREVfR0VUOgogICAgICAgIGlmIChjbXAgIT0gMCkgewogICAgICAgICAgICBuZXRzbm1wX3NldF9yZXF1ZXN0X2Vycm9yKHJlcWluZm8sIHJlcXVlc3RzLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFNOTVBfTk9TVUNIT0JKRUNUKTsKICAgICAgICAgICAgcmV0dXJuIFNOTVBfRVJSX05PRVJST1I7CiAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgcmVnaW5mby0+cm9vdG9pZFtyZWdpbmZvLT5yb290b2lkX2xlbisrXSA9IDA7CiAgICAgICAgICAgIHJldCA9IG5ldHNubXBfY2FsbF9uZXh0X2hhbmRsZXIoaGFuZGxlciwgcmVnaW5mbywgcmVxaW5mbywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVxdWVzdHMpOwogICAgICAgICAgICByZWdpbmZvLT5yb290b2lkX2xlbi0tOwogICAgICAgICAgICByZXR1cm4gcmV0OwogICAgICAgIH0KICAgICAgICBicmVhazsKCiAgICBjYXNlIE1PREVfU0VUX1JFU0VSVkUxOgogICAgY2FzZSBNT0RFX1NFVF9SRVNFUlZFMjoKICAgIGNhc2UgTU9ERV9TRVRfQUNUSU9OOgogICAgY2FzZSBNT0RFX1NFVF9DT01NSVQ6CiAgICBjYXNlIE1PREVfU0VUX1VORE86CiAgICBjYXNlIE1PREVfU0VUX0ZSRUU6CiAgICAgICAgaWYgKGNtcCAhPSAwKSB7CiAgICAgICAgICAgIG5ldHNubXBfc2V0X3JlcXVlc3RfZXJyb3IocmVxaW5mbywgcmVxdWVzdHMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU05NUF9FUlJfTk9DUkVBVElPTik7CiAgICAgICAgICAgIHJldHVybiBTTk1QX0VSUl9OT0VSUk9SOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIHJlZ2luZm8tPnJvb3RvaWRbcmVnaW5mby0+cm9vdG9pZF9sZW4rK10gPSAwOwogICAgICAgICAgICByZXQgPSBuZXRzbm1wX2NhbGxfbmV4dF9oYW5kbGVyKGhhbmRsZXIsIHJlZ2luZm8sIHJlcWluZm8sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJlcXVlc3RzKTsKICAgICAgICAgICAgcmVnaW5mby0+cm9vdG9pZF9sZW4tLTsKICAgICAgICAgICAgcmV0dXJuIHJldDsKICAgICAgICB9CiAgICAgICAgYnJlYWs7CgogICAgY2FzZSBNT0RFX0dFVE5FWFQ6CiAgICAgICAgcmVnaW5mby0+cm9vdG9pZFtyZWdpbmZvLT5yb290b2lkX2xlbisrXSA9IDA7CiAgICAgICAgcmV0ID0gbmV0c25tcF9jYWxsX25leHRfaGFuZGxlcihoYW5kbGVyLCByZWdpbmZvLCByZXFpbmZvLCByZXF1ZXN0cyk7CiAgICAgICAgcmVnaW5mby0+cm9vdG9pZF9sZW4tLTsKICAgICAgICByZXR1cm4gcmV0OwogICAgfQogICAgLyoKICAgICAqIGdvdCBoZXJlIG9ubHkgaWYgaWxsZWdhbCBtb2RlIGZvdW5kIAogICAgICovCiAgICByZXR1cm4gU05NUF9FUlJfR0VORVJSOwp9CgovKiogQH0gCiAqLwo=