LyogUG9ydGlvbnMgb2YgdGhpcyBmaWxlIGFyZSBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29weXJpZ2h0cy4gIFNlZQogKiB0aGUgTmV0LVNOTVAncyBDT1BZSU5HIGZpbGUgZm9yIG1vcmUgZGV0YWlscyBhbmQgb3RoZXIgY29weXJpZ2h0cwogKiB0aGF0IG1heSBhcHBseToKICovCi8qCiAqIENvcHlyaWdodCCpIDIwMDMgU3VuIE1pY3Jvc3lzdGVtcywgSW5jLiBBbGwgcmlnaHRzIHJlc2VydmVkLgogKiBVc2UgaXMgc3ViamVjdCB0byBsaWNlbnNlIHRlcm1zIHNwZWNpZmllZCBpbiB0aGUgQ09QWUlORyBmaWxlCiAqIGRpc3RyaWJ1dGVkIHdpdGggdGhlIE5ldC1TTk1QIHBhY2thZ2UuCiAqLwojaW5jbHVkZSA8bmV0LXNubXAvbmV0LXNubXAtY29uZmlnLmg+CgojaW5jbHVkZSA8c3lzL3R5cGVzLmg+CiNpbmNsdWRlIDxzeXMvc3RhdC5oPgojaWYgVElNRV9XSVRIX1NZU19USU1FCiMgaW5jbHVkZSA8c3lzL3RpbWUuaD4KIyBpbmNsdWRlIDx0aW1lLmg+CiNlbHNlCiMgaWYgSEFWRV9TWVNfVElNRV9ICiMgIGluY2x1ZGUgPHN5cy90aW1lLmg+CiMgZWxzZQojICBpbmNsdWRlIDx0aW1lLmg+CiMgZW5kaWYKI2VuZGlmCiNpZiBIQVZFX1NUUklOR19ICiNpbmNsdWRlIDxzdHJpbmcuaD4KI2VuZGlmCgojaWYgSEFWRV9TVFJJTkdfSAojaW5jbHVkZSA8c3RyaW5nLmg+CiNlbmRpZgoKI2luY2x1ZGUgPG5ldC1zbm1wL25ldC1zbm1wLWluY2x1ZGVzLmg+CiNpbmNsdWRlIDxuZXQtc25tcC9hZ2VudC9uZXQtc25tcC1hZ2VudC1pbmNsdWRlcy5oPgoKI2luY2x1ZGUgInN0cnVjdC5oIgojaW5jbHVkZSAiZmlsZS5oIgojaW5jbHVkZSAidXRpbF9mdW5jcy9oZWFkZXJfc2ltcGxlX3RhYmxlLmgiCgojZGVmaW5lIE1BWEZJTEUgICAyMAoKc3RydWN0IGZpbGVzdGF0IGZpbGVUYWJsZVtNQVhGSUxFXTsKaW50ICAgICAgICAgICAgIGZpbGVDb3VudDsKCnZvaWQKaW5pdF9maWxlKHZvaWQpCnsKICAgIHN0cnVjdCB2YXJpYWJsZTIgZmlsZV90YWJsZVtdID0gewogICAgICAgIHtGSUxFX0lOREVYLCBBU05fSU5URUdFUiwgTkVUU05NUF9PTERBUElfUk9OTFksCiAgICAgICAgIHZhcl9maWxlX3RhYmxlLCAxLCB7MX19LAogICAgICAgIHtGSUxFX05BTUUsIEFTTl9PQ1RFVF9TVFIsIE5FVFNOTVBfT0xEQVBJX1JPTkxZLAogICAgICAgICB2YXJfZmlsZV90YWJsZSwgMSwgezJ9fSwKICAgICAgICB7RklMRV9TSVpFLCBBU05fSU5URUdFUiwgTkVUU05NUF9PTERBUElfUk9OTFksCiAgICAgICAgIHZhcl9maWxlX3RhYmxlLCAxLCB7M319LAogICAgICAgIHtGSUxFX01BWCwgQVNOX0lOVEVHRVIsIE5FVFNOTVBfT0xEQVBJX1JPTkxZLAogICAgICAgICB2YXJfZmlsZV90YWJsZSwgMSwgezR9fSwKICAgICAgICB7RklMRV9FUlJPUiwgQVNOX0lOVEVHRVIsIE5FVFNOTVBfT0xEQVBJX1JPTkxZLAogICAgICAgICB2YXJfZmlsZV90YWJsZSwgMSwgezEwMH19LAogICAgICAgIHtGSUxFX01TRywgQVNOX09DVEVUX1NUUiwgTkVUU05NUF9PTERBUElfUk9OTFksCiAgICAgICAgIHZhcl9maWxlX3RhYmxlLCAxLCB7MTAxfX0KICAgIH07CgogICAgLyoKICAgICAqIERlZmluZSB0aGUgT0lEIHBvaW50ZXIgdG8gdGhlIHRvcCBvZiB0aGUgbWliIHRyZWUgdGhhdCB3ZSdyZQogICAgICogcmVnaXN0ZXJpbmcgdW5kZXJuZWF0aCAKICAgICAqLwogICAgb2lkICAgICAgICAgICAgIGZpbGVfdmFyaWFibGVzX29pZFtdID0geyBORVRTTk1QX1VDREFWSVNfTUlCLCAxNSwgMSB9OwoKICAgIC8qCiAgICAgKiByZWdpc3RlciBvdXJzZWx2ZXMgd2l0aCB0aGUgYWdlbnQgdG8gaGFuZGxlIG91ciBtaWIgdHJlZSAKICAgICAqLwogICAgUkVHSVNURVJfTUlCKCJ1Y2Qtc25tcC9maWxlIiwgZmlsZV90YWJsZSwgdmFyaWFibGUyLAogICAgICAgICAgICAgICAgIGZpbGVfdmFyaWFibGVzX29pZCk7CgogICAgc25tcGRfcmVnaXN0ZXJfY29uZmlnX2hhbmRsZXIoImZpbGUiLCBmaWxlX3BhcnNlX2NvbmZpZywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGVfZnJlZV9jb25maWcsICJmaWxlIFttYXhzaXplXSIpOwoKfQoKdm9pZApmaWxlX2ZyZWVfY29uZmlnKHZvaWQpCnsKICAgIGZpbGVDb3VudCA9IDA7Cn0KCnZvaWQKZmlsZV9wYXJzZV9jb25maWcoY29uc3QgY2hhciAqdG9rZW4sIGNoYXIgKmNwdHIpCnsKICAgIGNoYXIgKmNwOwoJCiAgICBpZiAoZmlsZUNvdW50IDwgTUFYRklMRSkgewogICAgICAgIGZpbGVUYWJsZVtmaWxlQ291bnRdLm1heCA9IC0xOwoKICAgICAgICBjcCA9IGNvcHlfbndvcmQoY3B0ciwgZmlsZVRhYmxlW2ZpbGVDb3VudF0ubmFtZSwgRklMRV9OQU1FX01BWCk7CgoJaWYgKHN0cmxlbihmaWxlVGFibGVbZmlsZUNvdW50XS5uYW1lKSA+PSBGSUxFX05BTUVfTUFYIC0gMSkgewogICAgICAgICAgICBjb25maWdfcGVycm9yKCJmaWxlIG5hbWUgdG9vIGxvbmciKTsKICAgICAgICAgICAgcmV0dXJuOwoJfQoKICAgICAgICBpZiAoY3ApCiAgICAgICAgICAgIGZpbGVUYWJsZVtmaWxlQ291bnRdLm1heCA9IHN0cnRvdWwoY3AsIE5VTEwsIDEwKTsKICAgICAgICBlbHNlCiAgICAgICAgICAgIGZpbGVUYWJsZVtmaWxlQ291bnRdLm1heCA9IC0xOwoKICAgICAgICBmaWxlQ291bnQrKzsKICAgIH0KfQoKdm9pZAp1cGRhdGVGaWxlKGludCBpaW5kZXgpCnsKICAgIHN0cnVjdCBzdGF0ICAgICBzYjsKCiAgICBpZiAoc3RhdChmaWxlVGFibGVbaWluZGV4XS5uYW1lLCAmc2IpID09IDApCiAgICAgICAgZmlsZVRhYmxlW2lpbmRleF0uc2l6ZSA9IHNiLnN0X3NpemUgPj4gMTA7Cn0KCi8qCiAqIE9JRCBmdW5jdGlvbnMgCiAqLwoKdV9jaGFyICAgICAgICAgKgp2YXJfZmlsZV90YWJsZShzdHJ1Y3QgdmFyaWFibGUgKnZwLAogICAgICAgICAgICAgICBvaWQgKiBuYW1lLAogICAgICAgICAgICAgICBzaXplX3QgKiBsZW5ndGgsCiAgICAgICAgICAgICAgIGludCBleGFjdCwgc2l6ZV90ICogdmFyX2xlbiwgV3JpdGVNZXRob2QgKiogd3JpdGVfbWV0aG9kKQp7CiAgICBzdGF0aWMgbG9uZyAgICAgbG9uZ19yZXQ7CiAgICBzdGF0aWMgY2hhciAgICAgZXJyb3JbMjU2XTsKICAgIGludCAgICAgICAgICAgICBpaW5kZXg7CiAgICBzdHJ1Y3QgZmlsZXN0YXQgKmZpbGU7CgogICAgaWYgKGhlYWRlcl9zaW1wbGVfdGFibGUKICAgICAgICAodnAsIG5hbWUsIGxlbmd0aCwgZXhhY3QsIHZhcl9sZW4sIHdyaXRlX21ldGhvZCwgZmlsZUNvdW50KSkKICAgICAgICByZXR1cm4gKE5VTEwpOwoKICAgIGlpbmRleCA9IG5hbWVbKmxlbmd0aCAtIDFdIC0gMTsKCiAgICB1cGRhdGVGaWxlKGlpbmRleCk7CgogICAgZmlsZSA9ICZmaWxlVGFibGVbaWluZGV4XTsKCiAgICBzd2l0Y2ggKHZwLT5tYWdpYykgewogICAgY2FzZSBGSUxFX0lOREVYOgogICAgICAgIGxvbmdfcmV0ID0gaWluZGV4ICsgMTsKICAgICAgICByZXR1cm4gKHVfY2hhciAqKSAmIGxvbmdfcmV0OwoKICAgIGNhc2UgRklMRV9OQU1FOgogICAgICAgICp2YXJfbGVuID0gc3RybGVuKGZpbGUtPm5hbWUpOwogICAgICAgIHJldHVybiAodV9jaGFyICopIGZpbGUtPm5hbWU7CgogICAgY2FzZSBGSUxFX1NJWkU6CiAgICAgICAgbG9uZ19yZXQgPSBmaWxlLT5zaXplOwogICAgICAgIHJldHVybiAodV9jaGFyICopICYgbG9uZ19yZXQ7CgogICAgY2FzZSBGSUxFX01BWDoKICAgICAgICBsb25nX3JldCA9IGZpbGUtPm1heDsKICAgICAgICByZXR1cm4gKHVfY2hhciAqKSAmIGxvbmdfcmV0OwoKICAgIGNhc2UgRklMRV9FUlJPUjoKICAgICAgICBpZiAoZmlsZS0+bWF4ID49IDAgJiYgZmlsZS0+c2l6ZSA+IGZpbGUtPm1heCkKICAgICAgICAgICAgbG9uZ19yZXQgPSAxOwogICAgICAgIGVsc2UKICAgICAgICAgICAgbG9uZ19yZXQgPSAwOwoKICAgICAgICByZXR1cm4gKHVfY2hhciAqKSAmIGxvbmdfcmV0OwoKICAgIGNhc2UgRklMRV9NU0c6CiAgICAgICAgaWYgKGZpbGUtPm1heCA+PSAwICYmIGZpbGUtPnNpemUgPiBmaWxlLT5tYXgpCiAgICAgICAgICAgIHNucHJpbnRmKGVycm9yLCBzaXplb2YoZXJyb3IpLCBGSUxFX0VSUk9SX01TRywgZmlsZS0+bmFtZSwKCQlmaWxlLT5tYXgsIGZpbGUtPnNpemUpOwogICAgICAgIGVsc2UKICAgICAgICAgICAgc3RyY3B5KGVycm9yLCAiIik7CgogICAgICAgICp2YXJfbGVuID0gc3RybGVuKGVycm9yKTsKICAgICAgICByZXR1cm4gKHVfY2hhciAqKSBlcnJvcjsKCiAgICBkZWZhdWx0OgogICAgICAgIERFQlVHTVNHVEwoKCJzbm1wZCIsICJ1bmtub3duIHN1Yi1pZCAlZCBpbiB2YXJfZmlsZV90YWJsZVxuIiwKICAgICAgICAgICAgICAgICAgICB2cC0+bWFnaWMpKTsKICAgIH0KCiAgICByZXR1cm4gTlVMTDsKfQo=