LyoKRGF0YSBzdHJ1Y3R1cmVzIGZvciBlbmNvZGluZyB0cmFuc2Zvcm1hdGlvbnMuCgpQZXJsIHdvcmtzIGludGVybmFsbHkgaW4gZWl0aGVyIGEgbmF0aXZlICdieXRlJyBlbmNvZGluZyBvcgppbiBVVEYtOCBlbmNvZGVkIFVuaWNvZGUuICBXZSBoYXZlIG5vIGltbWVkaWF0ZSBuZWVkIGZvciBhICJ3Y2hhcl90IgpyZXByZXNlbnRhdGlvbi4gV2hlbiB3ZSBkbyB3ZSBjYW4gdXNlIHV0ZjhfdG9fdXYoKS4KCk1vc3QgY2hhcmFjdGVyIGVuY29kaW5ncyBhcmUgZWl0aGVyIHNpbXBsZSBieXRlIG1hcHBpbmdzIG9yCnZhcmlhYmxlIGxlbmd0aCBtdWx0aS1ieXRlIGVuY29kaW5ncy4gVVRGLTggY2FuIGJlIHZpZXdlZCBhcyBhCnJhdGhlciBleHRyZW1lIGNhc2Ugb2YgdGhlIGxhdHRlci4KClNvIHRvIHNvbHZlIGFuIGltcG9ydGFudCBwYXJ0IG9mIHBlcmwncyBlbmNvZGUgbmVlZHMgd2UgbmVlZCB0byBzb2x2ZSB0aGUKIm11bHRpLWJ5dGUgLT4gbXVsdGktYnl0ZSIgY2FzZS4gVGhlIHNpbXBsZSBieXRlIGZvcm1zIGFyZSB0aGVuIGp1c3QgZGVnZW5lcmF0ZQpjYXNlLiAoV2hlcmUgb25lIG9mIG11bHRpLWJ5dGVzIHdpbGwgdXN1YWxseSBiZSBVVEYtOC4pCgpUaGUgb3RoZXIgdHlwZSBvZiBlbmNvZGluZyBpcyBhIHNoaWZ0IGVuY29kaW5nIHdoZXJlIGEgcHJlZml4IHNlcXVlbmNlCmRldGVybWluZXMgd2hhdCBzdWJzZXF1ZW50IGJ5dGVzIG1lYW4uIFN1Y2ggZW5jb2RpbmdzIGhhdmUgc3RhdGUuCgpXZSBhbHNvIG5lZWQgdG8gaGFuZGxlIGNhc2Ugd2hlcmUgYSBjaGFyYWN0ZXIgaW4gb25lIGVuY29kaW5nIGhhcyB0byBiZQpyZXByZXNlbnRlZCBhcyBtdWx0aXBsZSBjaGFyYWN0ZXJzIGluIHRoZSBvdGhlci4gZS5nLiBsZXR0ZXIrZGlhY3JpdGljLgoKVGhlIHByb2Nlc3MgY2FuIGJlIGNvbnNpZGVyZWQgYXMgcHNldWRvIHBlcmw6CgpteSAkZHN0ID0gJyc7CndoaWxlIChsZW5ndGgoJHNyYykpCiB7CiAgbXkgJHNpemUgICAgPSAkY291bnQoJHNyYyk7CiAgbXkgJGluX3NlcSAgPSBzdWJzdHIoJHNyYywwLCRzaXplLCcnKTsKICBteSAkb3V0X3NlcSA9ICRzMmRfaGFzaHskaW5fc2VxfTsKICBpZiAoZGVmaW5lZCAkb3V0X3NlcSkKICAgewogICAgJGRzdCAuPSAkb3V0X3NlcTsKICAgfQogIGVsc2UKICAgewogICAgIyBhbiBlcnJvciBjb25kaXRpb24KICAgfQogfQpyZXR1cm4gJGRzdDsKClRoYXQgaGFzIHRoZSBmb2xsb3dpbmcgY29tcG9uZW50czoKICZzcmNfY291bnQgLSBhICJydWxlIiBmb3IgaG93IG1hbnkgYnl0ZXMgbWFrZSB1cCB0aGUgbmV4dCBjaGFyYWN0ZXIgaW4gdGhlCiAgICAgICAgICAgICAgc291cmNlLgogJXMyZF9oYXNoICAtIGEgbWFwcGluZyBmcm9tIGlucHV0IHNlcXVlbmNlcyB0byBvdXRwdXQgc2VxdWVuY2VzCgpUaGUgcHJvYmxlbSB3aXRoIHRoYXQgc2NoZW1lIGlzIHRoYXQgaXQgZG9lcyBub3QgYWxsb3cgdGhlIG91dHB1dApjaGFyYWN0ZXIgcmVwZXJ0b2lyZSB0byBhZmZlY3QgdGhlIGNoYXJhY3RlcnMgY29uc2lkZXJlZCBmcm9tIHRoZQppbnB1dC4KClNvIHdlIHVzZSBhICJ0cmllIiByZXByZXNlbnRhdGlvbiB3aGljaCBjYW4gYWxzbyBiZSBjb25zaWRlcmVkCmEgc3RhdGUgbWFjaGluZToKCm15ICRkc3QgICA9ICcnOwpteSAkc2VxICAgPSBcQHMyZF9zZXE7Cm15ICRuZXh0ICA9IFxAczJkX25leHQ7CndoaWxlIChsZW5ndGgoJHNyYykpCiB7CiAgbXkgJGJ5dGUgICAgPSAkc3Vic3RyKCRzcmMsMCwxLCcnKTsKICBteSAkb3V0X3NlcSA9ICRzZXEtPlskYnl0ZV07CiAgaWYgKGRlZmluZWQgJG91dF9zZXEpCiAgIHsKICAgICRkc3QgLj0gJG91dF9zZXE7CiAgIH0KICBlbHNlCiAgIHsKICAgICMgYW4gZXJyb3IgY29uZGl0aW9uCiAgIH0KICAoJG5leHQsJHNlcSkgPSBAJG5leHQtPlskYnl0ZV0gaWYgJG5leHQ7CiB9CnJldHVybiAkZHN0OwoKVGhlcmUgaXMgbm93IGEgcGFpciBvZiBkYXRhIHN0cnVjdHVyZXMgdG8gcmVwcmVzZW50IGV2ZXJ5dGhpbmcuCkl0IGlzIHZhbGlkIGZvciBvdXRwdXQgc2VxdWVuY2UgYXQgYSBwYXJ0aWN1bGFyIHBvaW50IHRvCmJlIGRlZmluZWQgYnV0IHplcm8gbGVuZ3RoLCB0aGF0IGp1c3QgbWVhbnMgImRvbid0IGtub3cgeWV0Ii4KRm9yIHRoZSBzaW5nbGUgYnl0ZSBjYXNlIHRoZXJlIGlzIG5vICduZXh0JyBzbyBuZXcgdGFibGVzIHdpbGwgYmUgdGhlIHNhbWUgYXMKdGhlIG9yaWdpbmFsIHRhYmxlcy4gRm9yIGEgbXVsdGktYnl0ZSBjYXNlIGEgcHJlZml4IGJ5dGUgd2lsbCBmbGlwIHRvIHRoZSB0YWJsZXMKZm9yICB0aGUgbmV4dCBwYWdlIChhZGRpbmcgbm90aGluZyB0byB0aGUgb3V0cHV0KSwgdGhlbiB0aGUgdGFibGVzIGZvciB0aGUgcGFnZQp3aWxsIHByb3ZpZGUgdGhlIGFjdHVhbCBvdXRwdXQgYW5kIHNldCB0YWJsZXMgYmFjayB0byBvcmlnaW5hbCBiYXNlIHBhZ2UuCgpUaGlzIHNjaGVtZSBjYW4gYWxzbyBoYW5kbGUgc2hpZnQgZW5jb2RpbmdzLgoKQSBzbGlnaHQgZW5oYW5jZW1lbnQgdG8gdGhlIHNjaGVtZSBhbHNvIGFsbG93cyBmb3IgbG9vay1haGVhZCAtIGlmCndlIGFkZCBhIGZsYWcgdG8gcmUtYWRkIHRoZSByZW1vdmVkIGJ5dGUgdG8gdGhlIHNvdXJjZSB3ZSBjb3VsZCBoYW5kbGUKICBhIiAtPiDkCiAgYWIgLT4gYSAoYW5kIHRha2UgYiBiYWNrIHBsZWFzZSkKCiovCgojaW5jbHVkZSA8RVhURVJOLmg+CiNpbmNsdWRlIDxwZXJsLmg+CiNkZWZpbmUgVTggVTgKI2luY2x1ZGUgImVuY29kZS5oIgoKaW50CmRvX2VuY29kZShjb25zdCBlbmNwYWdlX3QgKiBlbmMsIGNvbnN0IFU4ICogc3JjLCBTVFJMRU4gKiBzbGVuLCBVOCAqIGRzdCwKICAgICAgU1RSTEVOIGRsZW4sIFNUUkxFTiAqIGRvdXQsIGludCBhcHByb3gsIGNvbnN0IFU4ICp0ZXJtLCBTVFJMRU4gdGxlbikKewogICAgY29uc3QgVTggKnMgPSBzcmM7CiAgICBjb25zdCBVOCAqc2VuZCA9IHMgKyAqc2xlbjsKICAgIGNvbnN0IFU4ICpsYXN0ID0gczsKICAgIFU4ICpkID0gZHN0OwogICAgVTggKmRlbmQgPSBkICsgZGxlbiwgKmRsYXN0ID0gZDsKICAgIGludCBjb2RlID0gMDsKICAgIHdoaWxlIChzIDwgc2VuZCkgewogICAgY29uc3QgZW5jcGFnZV90ICplID0gZW5jOwogICAgVTggYnl0ZSA9ICpzOwogICAgd2hpbGUgKGJ5dGUgPiBlLT5tYXgpCiAgICAgICAgZSsrOwogICAgaWYgKGJ5dGUgPj0gZS0+bWluICYmIGUtPnNsZW4gJiYgKGFwcHJveCB8fCAhKGUtPnNsZW4gJiAweDgwKSkpIHsKICAgICAgICBjb25zdCBVOCAqY2VuZCA9IHMgKyAoZS0+c2xlbiAmIDB4N2YpOwogICAgICAgIGlmIChjZW5kIDw9IHNlbmQpIHsKICAgICAgICBTVFJMRU4gbjsKICAgICAgICBpZiAoKG4gPSBlLT5kbGVuKSkgewogICAgICAgICAgICBjb25zdCBVOCAqb3V0ID0gZS0+c2VxICsgbiAqIChieXRlIC0gZS0+bWluKTsKICAgICAgICAgICAgVTggKm9lbmQgPSBkICsgbjsKICAgICAgICAgICAgaWYgKGRzdCkgewogICAgICAgICAgICBpZiAob2VuZCA8PSBkZW5kKSB7CiAgICAgICAgICAgICAgICB3aGlsZSAoZCA8IG9lbmQpCiAgICAgICAgICAgICAgICAqZCsrID0gKm91dCsrOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UgewogICAgICAgICAgICAgICAgLyogT3V0IG9mIHNwYWNlICovCiAgICAgICAgICAgICAgICBjb2RlID0gRU5DT0RFX05PU1BBQ0U7CiAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgfQogICAgICAgICAgICB9CiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgZCA9IG9lbmQ7CiAgICAgICAgfQogICAgICAgIGVuYyA9IGUtPm5leHQ7CiAgICAgICAgcysrOwogICAgICAgIGlmIChzID09IGNlbmQpIHsKICAgICAgICAgICAgaWYgKGFwcHJveCAmJiAoZS0+c2xlbiAmIDB4ODApKQogICAgICAgICAgICBjb2RlID0gRU5DT0RFX0ZBTExCQUNLOwogICAgICAgICAgICBsYXN0ID0gczsKICAgICAgICAgICAgaWYgKHRlcm0gJiYgKFNUUkxFTikoZC1kbGFzdCkgPT0gdGxlbiAmJiBtZW1FUShkbGFzdCwgdGVybSwgdGxlbikpIHsKICAgICAgICAgICAgICBjb2RlID0gRU5DT0RFX0ZPVU5EX1RFUk07CiAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZGxhc3QgPSBkOwogICAgICAgIH0KICAgICAgICB9CiAgICAgICAgZWxzZSB7CiAgICAgICAgLyogcGFydGlhbCBzb3VyY2UgY2hhcmFjdGVyICovCiAgICAgICAgY29kZSA9IEVOQ09ERV9QQVJUSUFMOwogICAgICAgIGJyZWFrOwogICAgICAgIH0KICAgIH0KICAgIGVsc2UgewogICAgICAgIC8qIENhbm5vdCByZXByZXNlbnQgKi8KICAgICAgICBjb2RlID0gRU5DT0RFX05PUkVQOwogICAgICAgIGJyZWFrOwogICAgfQogICAgfQogICAgKnNsZW4gPSBsYXN0IC0gc3JjOwogICAgKmRvdXQgPSBkIC0gZHN0OwogICAgcmV0dXJuIGNvZGU7Cn0K