LyoKICogJFhGcmVlODY6IHhjL2xpYi9mb250Y29uZmlnL3NyYy9mY2F0b21pYy5jLHYgMS4yIDIwMDIvMDMvMDQgMjE6MTU6MjggdHNpIEV4cCAkCiAqCiAqIENvcHlyaWdodCCpIDIwMDIgS2VpdGggUGFja2FyZCwgbWVtYmVyIG9mIFRoZSBYRnJlZTg2IFByb2plY3QsIEluYy4KICoKICogUGVybWlzc2lvbiB0byB1c2UsIGNvcHksIG1vZGlmeSwgZGlzdHJpYnV0ZSwgYW5kIHNlbGwgdGhpcyBzb2Z0d2FyZSBhbmQgaXRzCiAqIGRvY3VtZW50YXRpb24gZm9yIGFueSBwdXJwb3NlIGlzIGhlcmVieSBncmFudGVkIHdpdGhvdXQgZmVlLCBwcm92aWRlZCB0aGF0CiAqIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFwcGVhciBpbiBhbGwgY29waWVzIGFuZCB0aGF0IGJvdGggdGhhdAogKiBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIGFwcGVhciBpbiBzdXBwb3J0aW5nCiAqIGRvY3VtZW50YXRpb24sIGFuZCB0aGF0IHRoZSBuYW1lIG9mIEtlaXRoIFBhY2thcmQgbm90IGJlIHVzZWQgaW4KICogYWR2ZXJ0aXNpbmcgb3IgcHVibGljaXR5IHBlcnRhaW5pbmcgdG8gZGlzdHJpYnV0aW9uIG9mIHRoZSBzb2Z0d2FyZSB3aXRob3V0CiAqIHNwZWNpZmljLCB3cml0dGVuIHByaW9yIHBlcm1pc3Npb24uICBLZWl0aCBQYWNrYXJkIG1ha2VzIG5vCiAqIHJlcHJlc2VudGF0aW9ucyBhYm91dCB0aGUgc3VpdGFiaWxpdHkgb2YgdGhpcyBzb2Z0d2FyZSBmb3IgYW55IHB1cnBvc2UuICBJdAogKiBpcyBwcm92aWRlZCAiYXMgaXMiIHdpdGhvdXQgZXhwcmVzcyBvciBpbXBsaWVkIHdhcnJhbnR5LgogKgogKiBLRUlUSCBQQUNLQVJEIERJU0NMQUlNUyBBTEwgV0FSUkFOVElFUyBXSVRIIFJFR0FSRCBUTyBUSElTIFNPRlRXQVJFLAogKiBJTkNMVURJTkcgQUxMIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MsIElOIE5PCiAqIEVWRU5UIFNIQUxMIEtFSVRIIFBBQ0tBUkQgQkUgTElBQkxFIEZPUiBBTlkgU1BFQ0lBTCwgSU5ESVJFQ1QgT1IKICogQ09OU0VRVUVOVElBTCBEQU1BR0VTIE9SIEFOWSBEQU1BR0VTIFdIQVRTT0VWRVIgUkVTVUxUSU5HIEZST00gTE9TUyBPRiBVU0UsCiAqIERBVEEgT1IgUFJPRklUUywgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIE5FR0xJR0VOQ0UgT1IgT1RIRVIKICogVE9SVElPVVMgQUNUSU9OLCBBUklTSU5HIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFVTRSBPUgogKiBQRVJGT1JNQU5DRSBPRiBUSElTIFNPRlRXQVJFLgogKi8KCi8qCiAqIGZjYXRvbWljLmMKICoKICogTG9jayBjYWNoZSBhbmQgY29uZmlndXJhdGlvbiBmaWxlcyBmb3IgYXRvbWljIHVwZGF0ZQogKgogKiBVc2VzIG9ubHkgcmVndWxhciBmaWxlc3lzdGVtIGNhbGxzIHNvIGl0IHNob3VsZAogKiB3b3JrIGV2ZW4gaW4gdGhlIGFic2Vuc2Ugb2YgZnVuY3Rpb25pbmcgZmlsZSBsb2NraW5nCiAqCiAqICBGb3VyIGZpbGVzOgogKglmaWxlCSAgICAtIHRoZSBkYXRhIGZpbGUgYWNjZXNzZWQgYnkgb3RoZXIgYXBwcy4KICoJbmV3CSAgICAtIGEgbmV3IHZlcnNpb24gb2YgdGhlIGRhdGEgZmlsZSB3aGlsZSBpdCdzIGJlaW5nIHdyaXR0ZW4KICoJbGNrCSAgICAtIHRoZSBsb2NrIGZpbGUKICoJdG1wCSAgICAtIGEgdGVtcG9yYXJ5IGZpbGUgbWFkZSB1bmlxdWUgd2l0aCBta3N0ZW1wCiAqCiAqICBIZXJlJ3MgaG93IGl0IHdvcmtzOgogKglDcmVhdGUgJ3RtcCcgYW5kIHN0b3JlIG91ciBQSUQgaW4gaXQKICoJQXR0ZW1wdCB0byBsaW5rIGl0IHRvICdsY2snCiAqCVVubGluayAndG1wJwogKglJZiB0aGUgbGluayBzdWNjZWVkZWQsIHRoZSBsb2NrIGlzIGhlbGQKICovCgojaW5jbHVkZSAiZmNpbnQuaCIKI2luY2x1ZGUgPHN5cy90eXBlcy5oPgojaW5jbHVkZSA8c3lzL3N0YXQuaD4KI2luY2x1ZGUgPGZjbnRsLmg+CiNpbmNsdWRlIDx1bmlzdGQuaD4KI2luY2x1ZGUgPHN0ZGxpYi5oPgojaW5jbHVkZSA8dGltZS5oPgoKI2RlZmluZSBORVdfTkFNRQkiLk5FVyIKI2RlZmluZSBMQ0tfTkFNRQkiLkxDSyIKI2RlZmluZSBUTVBfTkFNRQkiLlRNUC1YWFhYWFgiCgpGY0F0b21pYyAqCkZjQXRvbWljQ3JlYXRlIChjb25zdCBGY0NoYXI4ICAgKmZpbGUpCnsKICAgIGludAkgICAgZmlsZV9sZW4gPSBzdHJsZW4gKChjaGFyICopIGZpbGUpOwogICAgaW50CSAgICBuZXdfbGVuID0gZmlsZV9sZW4gKyBzaXplb2YgKE5FV19OQU1FKTsKICAgIGludAkgICAgbGNrX2xlbiA9IGZpbGVfbGVuICsgc2l6ZW9mIChMQ0tfTkFNRSk7CiAgICBpbnQJICAgIHRtcF9sZW4gPSBmaWxlX2xlbiArIHNpemVvZiAoVE1QX05BTUUpOwogICAgaW50CSAgICB0b3RhbF9sZW4gPSAoc2l6ZW9mIChGY0F0b21pYykgKwoJCQkgZmlsZV9sZW4gKyAxICsKCQkJIG5ld19sZW4gKyAxICsKCQkJIGxja19sZW4gKyAxICsKCQkJIHRtcF9sZW4gKyAxKTsKICAgIEZjQXRvbWljCSphdG9taWMgPSBtYWxsb2MgKHRvdGFsX2xlbik7CiAgICBpZiAoIWF0b21pYykKCXJldHVybiAwOwogICAgRmNNZW1BbGxvYyAoRkNfTUVNX0FUT01JQywgdG90YWxfbGVuKTsKICAgIAogICAgYXRvbWljLT5maWxlID0gKEZjQ2hhcjggKikgKGF0b21pYyArIDEpOwogICAgc3RyY3B5ICgoY2hhciAqKSBhdG9taWMtPmZpbGUsIChjaGFyICopIGZpbGUpOwoKICAgIGF0b21pYy0+bmV3ID0gYXRvbWljLT5maWxlICsgZmlsZV9sZW4gKyAxOwogICAgc3RyY3B5ICgoY2hhciAqKSBhdG9taWMtPm5ldywgKGNoYXIgKikgZmlsZSk7CiAgICBzdHJjYXQgKChjaGFyICopIGF0b21pYy0+bmV3LCBORVdfTkFNRSk7CgogICAgYXRvbWljLT5sY2sgPSBhdG9taWMtPm5ldyArIG5ld19sZW4gKyAxOwogICAgc3RyY3B5ICgoY2hhciAqKSBhdG9taWMtPmxjaywgKGNoYXIgKikgZmlsZSk7CiAgICBzdHJjYXQgKChjaGFyICopIGF0b21pYy0+bGNrLCBMQ0tfTkFNRSk7CgogICAgYXRvbWljLT50bXAgPSBhdG9taWMtPmxjayArIGxja19sZW4gKyAxOwoKICAgIHJldHVybiBhdG9taWM7Cn0KCkZjQm9vbApGY0F0b21pY0xvY2sgKEZjQXRvbWljICphdG9taWMpCnsKICAgIGludAkJZmQgPSAtMTsKICAgIEZJTEUJKmYgPSAwOwogICAgaW50CQlyZXQ7CiAgICBzdHJ1Y3Qgc3RhdAlsY2tfc3RhdDsKCiAgICBzdHJjcHkgKChjaGFyICopIGF0b21pYy0+dG1wLCAoY2hhciAqKSBhdG9taWMtPmZpbGUpOwogICAgc3RyY2F0ICgoY2hhciAqKSBhdG9taWMtPnRtcCwgVE1QX05BTUUpOwogICAgZmQgPSBta3N0ZW1wICgoY2hhciAqKSBhdG9taWMtPnRtcCk7CiAgICBpZiAoZmQgPCAwKQoJcmV0dXJuIEZjRmFsc2U7CiAgICBmID0gZmRvcGVuIChmZCwgInciKTsKICAgIGlmICghZikKICAgIHsKICAgIAljbG9zZSAoZmQpOwoJdW5saW5rICgoY2hhciAqKSBhdG9taWMtPnRtcCk7CglyZXR1cm4gRmNGYWxzZTsKICAgIH0KICAgIHJldCA9IGZwcmludGYgKGYsICIlbGRcbiIsIChsb25nKWdldHBpZCgpKTsKICAgIGlmIChyZXQgPD0gMCkKICAgIHsKCWZjbG9zZSAoZik7Cgl1bmxpbmsgKChjaGFyICopIGF0b21pYy0+dG1wKTsKCXJldHVybiBGY0ZhbHNlOwogICAgfQogICAgaWYgKGZjbG9zZSAoZikgPT0gRU9GKQogICAgewoJdW5saW5rICgoY2hhciAqKSBhdG9taWMtPnRtcCk7CglyZXR1cm4gRmNGYWxzZTsKICAgIH0KICAgIHJldCA9IGxpbmsgKChjaGFyICopIGF0b21pYy0+dG1wLCAoY2hhciAqKSBhdG9taWMtPmxjayk7CiAgICAodm9pZCkgdW5saW5rICgoY2hhciAqKSBhdG9taWMtPnRtcCk7CiAgICBpZiAocmV0IDwgMCkKICAgIHsKCS8qCgkgKiBJZiB0aGUgZmlsZSBpcyBhcm91bmQgYW5kIG9sZCAoPiAxMCBtaW51dGVzKSwKCSAqIGFzc3VtZSB0aGUgbG9jayBpcyBzdGFsZS4gIFRoaXMgYXNzdW1lcyB0aGF0IGFueQoJICogbWFjaGluZXMgc2hhcmluZyB0aGUgc2FtZSBmaWxlc3lzdGVtIHdpbGwgaGF2ZSBjbG9ja3MKCSAqIHJlYXNvbmFibHkgY2xvc2UgdG8gZWFjaCBvdGhlci4KCSAqLwoJaWYgKHN0YXQgKChjaGFyICopIGF0b21pYy0+bGNrLCAmbGNrX3N0YXQpID49IDApCgl7CgkgICAgdGltZV90ICBub3cgPSB0aW1lICgwKTsKCSAgICBpZiAoKGxvbmcgaW50KSAobm93IC0gbGNrX3N0YXQuc3RfbXRpbWUpID4gMTAgKiA2MCkKCSAgICB7CgkJaWYgKHVubGluayAoKGNoYXIgKikgYXRvbWljLT5sY2spID09IDApCgkJICAgIHJldHVybiBGY0F0b21pY0xvY2sgKGF0b21pYyk7CgkgICAgfQoJfQoJcmV0dXJuIEZjRmFsc2U7CiAgICB9CiAgICAodm9pZCkgdW5saW5rICgoY2hhciAqKSBhdG9taWMtPm5ldyk7CiAgICByZXR1cm4gRmNUcnVlOwp9CgpGY0NoYXI4ICoKRmNBdG9taWNOZXdGaWxlIChGY0F0b21pYyAqYXRvbWljKQp7CiAgICByZXR1cm4gYXRvbWljLT5uZXc7Cn0KCkZjQ2hhcjggKgpGY0F0b21pY09yaWdGaWxlIChGY0F0b21pYyAqYXRvbWljKQp7CiAgICByZXR1cm4gYXRvbWljLT5maWxlOwp9CgpGY0Jvb2wKRmNBdG9taWNSZXBsYWNlT3JpZyAoRmNBdG9taWMgKmF0b21pYykKewogICAgaWYgKHJlbmFtZSAoKGNoYXIgKikgYXRvbWljLT5uZXcsIChjaGFyICopIGF0b21pYy0+ZmlsZSkgPCAwKQoJcmV0dXJuIEZjRmFsc2U7CiAgICByZXR1cm4gRmNUcnVlOwp9Cgp2b2lkCkZjQXRvbWljRGVsZXRlTmV3IChGY0F0b21pYyAqYXRvbWljKQp7CiAgICB1bmxpbmsgKChjaGFyICopIGF0b21pYy0+bmV3KTsKfQoKdm9pZApGY0F0b21pY1VubG9jayAoRmNBdG9taWMgKmF0b21pYykKewogICAgdW5saW5rICgoY2hhciAqKSBhdG9taWMtPmxjayk7Cn0KCnZvaWQKRmNBdG9taWNEZXN0cm95IChGY0F0b21pYyAqYXRvbWljKQp7CiAgICBGY01lbUZyZWUgKEZDX01FTV9BVE9NSUMsIHNpemVvZiAoRmNBdG9taWMpICsKCSAgICAgICBzdHJsZW4gKChjaGFyICopIGF0b21pYy0+ZmlsZSkgKiA0ICsgMSArCgkgICAgICAgc2l6ZW9mIChORVdfTkFNRSkgKyBzaXplb2YgKExDS19OQU1FKSArIAoJICAgICAgIHNpemVvZiAoVE1QX05BTUUpKTsKCiAgICBmcmVlIChhdG9taWMpOwp9Cg==