Ly8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQovLyBKUEVHIExvYWRlciBhbmQgd3JpdGVyCi8vIEJhc2VkIG9uIGNvZGUgZGV2ZWxvcGVkIGJ5IFRoZSBJbmRlcGVuZGVudCBKUEVHIEdyb3VwCi8vCi8vIERlc2lnbiBhbmQgaW1wbGVtZW50YXRpb24gYnkKLy8gLSBGbG9yaXMgdmFuIGRlbiBCZXJnIChmbHZkYmVyZ0B3eHMubmwpCi8vIC0gSmFuIEwuIE5hdXRhIChqbG5AbWFnZW50YW1tdC5jb20pCi8vIC0gTWFya3VzIExvaWJsIChtYXJrdXMubG9pYmxAZXBvc3QuZGUpCi8vIC0gS2FybC1IZWlueiBCdXNzaWFuIChraGJ1c3NpYW5AbW9zcy5kZSkKLy8gLSBIZXJ26SBEcm9sb24gKGRyb2xvbkBpbmZvbmllLmZyKQovLyAtIEphc2NoYSBXZXR6ZWwgKGphc2NoYUBtYWluaWEuZGUpCi8vCi8vIFRoaXMgZmlsZSBpcyBwYXJ0IG9mIEZyZWVJbWFnZSAzCi8vCi8vIENPVkVSRUQgQ09ERSBJUyBQUk9WSURFRCBVTkRFUiBUSElTIExJQ0VOU0UgT04gQU4gIkFTIElTIiBCQVNJUywgV0lUSE9VVCBXQVJSQU5UWQovLyBPRiBBTlkgS0lORCwgRUlUSEVSIEVYUFJFU1NFRCBPUiBJTVBMSUVELCBJTkNMVURJTkcsIFdJVEhPVVQgTElNSVRBVElPTiwgV0FSUkFOVElFUwovLyBUSEFUIFRIRSBDT1ZFUkVEIENPREUgSVMgRlJFRSBPRiBERUZFQ1RTLCBNRVJDSEFOVEFCTEUsIEZJVCBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UKLy8gT1IgTk9OLUlORlJJTkdJTkcuIFRIRSBFTlRJUkUgUklTSyBBUyBUTyBUSEUgUVVBTElUWSBBTkQgUEVSRk9STUFOQ0UgT0YgVEhFIENPVkVSRUQKLy8gQ09ERSBJUyBXSVRIIFlPVS4gU0hPVUxEIEFOWSBDT1ZFUkVEIENPREUgUFJPVkUgREVGRUNUSVZFIElOIEFOWSBSRVNQRUNULCBZT1UgKE5PVAovLyBUSEUgSU5JVElBTCBERVZFTE9QRVIgT1IgQU5ZIE9USEVSIENPTlRSSUJVVE9SKSBBU1NVTUUgVEhFIENPU1QgT0YgQU5ZIE5FQ0VTU0FSWQovLyBTRVJWSUNJTkcsIFJFUEFJUiBPUiBDT1JSRUNUSU9OLiBUSElTIERJU0NMQUlNRVIgT0YgV0FSUkFOVFkgQ09OU1RJVFVURVMgQU4gRVNTRU5USUFMCi8vIFBBUlQgT0YgVEhJUyBMSUNFTlNFLiBOTyBVU0UgT0YgQU5ZIENPVkVSRUQgQ09ERSBJUyBBVVRIT1JJWkVEIEhFUkVVTkRFUiBFWENFUFQgVU5ERVIKLy8gVEhJUyBESVNDTEFJTUVSLgovLwovLyBVc2UgYXQgeW91ciBvd24gcmlzayEKLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQoKI2lmZGVmIF9NU0NfVkVSIAojcHJhZ21hIHdhcm5pbmcgKGRpc2FibGUgOiA0Nzg2KSAvLyBpZGVudGlmaWVyIHdhcyB0cnVuY2F0ZWQgdG8gJ251bWJlcicgY2hhcmFjdGVycwojZW5kaWYKCmV4dGVybiAiQyIgewojZGVmaW5lIFhNRF9ICiN1bmRlZiBGQVIKI2luY2x1ZGUgPHNldGptcC5oPgoKI2luY2x1ZGUgIi4uL0xpYkpQRUcvamluY2x1ZGUuaCIKI2luY2x1ZGUgIi4uL0xpYkpQRUcvanBlZ2xpYi5oIgojaW5jbHVkZSAiLi4vTGliSlBFRy9qZXJyb3IuaCIKfQoKI2luY2x1ZGUgIkZyZWVJbWFnZS5oIgojaW5jbHVkZSAiVXRpbGl0aWVzLmgiCgojaW5jbHVkZSAiLi4vTWV0YWRhdGEvRnJlZUltYWdlVGFnLmgiCgoKLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQovLyBQbHVnaW4gSW50ZXJmYWNlCi8vID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KCnN0YXRpYyBpbnQgc19mb3JtYXRfaWQ7CgovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi8vICAgQ29uc3RhbnQgZGVjbGFyYXRpb25zCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiNkZWZpbmUgSU5QVVRfQlVGX1NJWkUgIDQwOTYJLy8gY2hvb3NlIGFuIGVmZmljaWVudGx5IGZyZWFkJ2FibGUgc2l6ZSAKI2RlZmluZSBPVVRQVVRfQlVGX1NJWkUgNDA5NiAgICAvLyBjaG9vc2UgYW4gZWZmaWNpZW50bHkgZndyaXRlJ2FibGUgc2l6ZQoKI2RlZmluZSBFWElGX01BUktFUgkJKEpQRUdfQVBQMCsxKQkvLyBFWElGIG1hcmtlciAvIEFkb2JlIFhNUCBtYXJrZXIKI2RlZmluZSBJQ0NfTUFSS0VSCQkoSlBFR19BUFAwKzIpCS8vIElDQyBwcm9maWxlIG1hcmtlcgojZGVmaW5lIElQVENfTUFSS0VSCQkoSlBFR19BUFAwKzEzKQkvLyBJUFRDIG1hcmtlciAvIEJJTSBtYXJrZXIgCgojZGVmaW5lIElDQ19IRUFERVJfU0laRSAxNAkJCQkvLyBzaXplIG9mIG5vbi1wcm9maWxlIGRhdGEgaW4gQVBQMgojZGVmaW5lIE1BWF9CWVRFU19JTl9NQVJLRVIgNjU1MzNMCQkvLyBtYXhpbXVtIGRhdGEgbGVuZ3RoIG9mIGEgSlBFRyBtYXJrZXIKI2RlZmluZSBNQVhfREFUQV9CWVRFU19JTl9NQVJLRVIgNjU1MTlMCS8vIG1heGltdW0gZGF0YSBsZW5ndGggb2YgYSBKUEVHIEFQUDIgbWFya2VyCgovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi8vICAgVHlwZWRlZiBkZWNsYXJhdGlvbnMKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKdHlwZWRlZiBzdHJ1Y3QgdGFnRXJyb3JNYW5hZ2VyIHsKCS8vLyAicHVibGljIiBmaWVsZHMKCXN0cnVjdCBqcGVnX2Vycm9yX21nciBwdWI7CgkvLy8gZm9yIHJldHVybiB0byBjYWxsZXIKCWptcF9idWYgc2V0am1wX2J1ZmZlcjsKfSBFcnJvck1hbmFnZXI7Cgp0eXBlZGVmIHN0cnVjdCB0YWdTb3VyY2VNYW5hZ2VyIHsKCS8vLyBwdWJsaWMgZmllbGRzCglzdHJ1Y3QganBlZ19zb3VyY2VfbWdyIHB1YjsKCS8vLyBzb3VyY2Ugc3RyZWFtCglmaV9oYW5kbGUgaW5maWxlOwoJRnJlZUltYWdlSU8gKm1faW87CgkvLy8gc3RhcnQgb2YgYnVmZmVyCglKT0NURVQgKiBidWZmZXI7CgkvLy8gaGF2ZSB3ZSBnb3R0ZW4gYW55IGRhdGEgeWV0ID8KCWJvb2xlYW4gc3RhcnRfb2ZfZmlsZTsKfSBTb3VyY2VNYW5hZ2VyOwoKdHlwZWRlZiBzdHJ1Y3QgdGFnRGVzdGluYXRpb25NYW5hZ2VyIHsKCS8vLyBwdWJsaWMgZmllbGRzCglzdHJ1Y3QganBlZ19kZXN0aW5hdGlvbl9tZ3IgcHViOwoJLy8vIGRlc3RpbmF0aW9uIHN0cmVhbQoJZmlfaGFuZGxlIG91dGZpbGU7CglGcmVlSW1hZ2VJTyAqbV9pbzsKCS8vLyBzdGFydCBvZiBidWZmZXIKCUpPQ1RFVCAqIGJ1ZmZlcjsKfSBEZXN0aW5hdGlvbk1hbmFnZXI7Cgp0eXBlZGVmIFNvdXJjZU1hbmFnZXIqCQlmcmVlaW1hZ2Vfc3JjX3B0cjsKdHlwZWRlZiBEZXN0aW5hdGlvbk1hbmFnZXIqIGZyZWVpbWFnZV9kc3RfcHRyOwp0eXBlZGVmIEVycm9yTWFuYWdlcioJCWZyZWVpbWFnZV9lcnJvcl9wdHI7CgovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi8vICAgRXJyb3IgaGFuZGxpbmcKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKLyoqCglSZWNlaXZlcyBjb250cm9sIGZvciBhIGZhdGFsIGVycm9yLiAgSW5mb3JtYXRpb24gc3VmZmljaWVudCB0bwoJZ2VuZXJhdGUgdGhlIGVycm9yIG1lc3NhZ2UgaGFzIGJlZW4gc3RvcmVkIGluIGNpbmZvLT5lcnI7IGNhbGwKCW91dHB1dF9tZXNzYWdlIHRvIGRpc3BsYXkgaXQuICBDb250cm9sIG11c3QgTk9UIHJldHVybiB0byB0aGUgY2FsbGVyOwoJZ2VuZXJhbGx5IHRoaXMgcm91dGluZSB3aWxsIGV4aXQoKSBvciBsb25nam1wKCkgc29tZXdoZXJlLgoqLwpNRVRIT0RERUYodm9pZCkKanBlZ19lcnJvcl9leGl0IChqX2NvbW1vbl9wdHIgY2luZm8pIHsKCS8vIGFsd2F5cyBkaXNwbGF5IHRoZSBtZXNzYWdlCgkoKmNpbmZvLT5lcnItPm91dHB1dF9tZXNzYWdlKShjaW5mbyk7CgoJLy8gYWxsb3cgSlBFRyB3aXRoIGEgcHJlbWF0dXJlIGVuZCBvZiBmaWxlCglpZigoY2luZm8pLT5lcnItPm1zZ19wYXJtLmlbMF0gIT0gMTMpIHsKCQoJCS8vIGxldCB0aGUgbWVtb3J5IG1hbmFnZXIgZGVsZXRlIGFueSB0ZW1wIGZpbGVzIGJlZm9yZSB3ZSBkaWUKCQlqcGVnX2Rlc3Ryb3koY2luZm8pOwoJCQoJCXRocm93IHNfZm9ybWF0X2lkOwoJfQp9CgovKioKCUFjdHVhbCBvdXRwdXQgb2YgYW55IEpQRUcgbWVzc2FnZS4gIE5vdGUgdGhhdCB0aGlzIG1ldGhvZCBkb2VzIG5vdCBrbm93Cglob3cgdG8gZ2VuZXJhdGUgYSBtZXNzYWdlLCBvbmx5IHdoZXJlIHRvIHNlbmQgaXQuCiovCk1FVEhPRERFRih2b2lkKQpqcGVnX291dHB1dF9tZXNzYWdlIChqX2NvbW1vbl9wdHIgY2luZm8pIHsKCWNoYXIgYnVmZmVyW0pNU0dfTEVOR1RIX01BWF07CgoJLy8gY3JlYXRlIHRoZSBtZXNzYWdlCgkoKmNpbmZvLT5lcnItPmZvcm1hdF9tZXNzYWdlKShjaW5mbywgYnVmZmVyKTsKCS8vIHNlbmQgaXQgdG8gdXNlcidzIG1lc3NhZ2UgcHJvYwoJRnJlZUltYWdlX091dHB1dE1lc3NhZ2VQcm9jKHNfZm9ybWF0X2lkLCBidWZmZXIpOwp9CgovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi8vICAgRGVzdGluYXRpb24gbWFuYWdlcgovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgovKioKCUluaXRpYWxpemUgZGVzdGluYXRpb24uICBUaGlzIGlzIGNhbGxlZCBieSBqcGVnX3N0YXJ0X2NvbXByZXNzKCkKCWJlZm9yZSBhbnkgZGF0YSBpcyBhY3R1YWxseSB3cml0dGVuLiBJdCBtdXN0IGluaXRpYWxpemUKCW5leHRfb3V0cHV0X2J5dGUgYW5kIGZyZWVfaW5fYnVmZmVyLiBmcmVlX2luX2J1ZmZlciBtdXN0IGJlCglpbml0aWFsaXplZCB0byBhIHBvc2l0aXZlIHZhbHVlLgoqLwpNRVRIT0RERUYodm9pZCkKaW5pdF9kZXN0aW5hdGlvbiAoal9jb21wcmVzc19wdHIgY2luZm8pIHsKCWZyZWVpbWFnZV9kc3RfcHRyIGRlc3QgPSAoZnJlZWltYWdlX2RzdF9wdHIpIGNpbmZvLT5kZXN0OwoKCWRlc3QtPmJ1ZmZlciA9IChKT0NURVQgKikKCSAgKCpjaW5mby0+bWVtLT5hbGxvY19zbWFsbCkgKChqX2NvbW1vbl9wdHIpIGNpbmZvLCBKUE9PTF9JTUFHRSwKCQkJCSAgT1VUUFVUX0JVRl9TSVpFICogU0laRU9GKEpPQ1RFVCkpOwoKCWRlc3QtPnB1Yi5uZXh0X291dHB1dF9ieXRlID0gZGVzdC0+YnVmZmVyOwoJZGVzdC0+cHViLmZyZWVfaW5fYnVmZmVyID0gT1VUUFVUX0JVRl9TSVpFOwp9CgovKioKCVRoaXMgaXMgY2FsbGVkIHdoZW5ldmVyIHRoZSBidWZmZXIgaGFzIGZpbGxlZCAoZnJlZV9pbl9idWZmZXIKCXJlYWNoZXMgemVybykuIEluIHR5cGljYWwgYXBwbGljYXRpb25zLCBpdCBzaG91bGQgd3JpdGUgb3V0IHRoZQoJKmVudGlyZSogYnVmZmVyICh1c2UgdGhlIHNhdmVkIHN0YXJ0IGFkZHJlc3MgYW5kIGJ1ZmZlciBsZW5ndGg7CglpZ25vcmUgdGhlIGN1cnJlbnQgc3RhdGUgb2YgbmV4dF9vdXRwdXRfYnl0ZSBhbmQgZnJlZV9pbl9idWZmZXIpLgoJVGhlbiByZXNldCB0aGUgcG9pbnRlciAmIGNvdW50IHRvIHRoZSBzdGFydCBvZiB0aGUgYnVmZmVyLCBhbmQKCXJldHVybiBUUlVFIGluZGljYXRpbmcgdGhhdCB0aGUgYnVmZmVyIGhhcyBiZWVuIGR1bXBlZC4KCWZyZWVfaW5fYnVmZmVyIG11c3QgYmUgc2V0IHRvIGEgcG9zaXRpdmUgdmFsdWUgd2hlbiBUUlVFIGlzCglyZXR1cm5lZC4gIEEgRkFMU0UgcmV0dXJuIHNob3VsZCBvbmx5IGJlIHVzZWQgd2hlbiBJL08gc3VzcGVuc2lvbiBpcwoJZGVzaXJlZC4KKi8KTUVUSE9EREVGKGJvb2xlYW4pCmVtcHR5X291dHB1dF9idWZmZXIgKGpfY29tcHJlc3NfcHRyIGNpbmZvKSB7CglmcmVlaW1hZ2VfZHN0X3B0ciBkZXN0ID0gKGZyZWVpbWFnZV9kc3RfcHRyKSBjaW5mby0+ZGVzdDsKCglpZiAoZGVzdC0+bV9pby0+d3JpdGVfcHJvYyhkZXN0LT5idWZmZXIsIDEsIE9VVFBVVF9CVUZfU0laRSwgZGVzdC0+b3V0ZmlsZSkgIT0gT1VUUFVUX0JVRl9TSVpFKQoJCXRocm93KGNpbmZvLCBKRVJSX0ZJTEVfV1JJVEUpOwoKCWRlc3QtPnB1Yi5uZXh0X291dHB1dF9ieXRlID0gZGVzdC0+YnVmZmVyOwoJZGVzdC0+cHViLmZyZWVfaW5fYnVmZmVyID0gT1VUUFVUX0JVRl9TSVpFOwoKCXJldHVybiBUUlVFOwp9CgovKioKCVRlcm1pbmF0ZSBkZXN0aW5hdGlvbiAtLS0gY2FsbGVkIGJ5IGpwZWdfZmluaXNoX2NvbXByZXNzKCkgYWZ0ZXIgYWxsCglkYXRhIGhhcyBiZWVuIHdyaXR0ZW4uICBJbiBtb3N0IGFwcGxpY2F0aW9ucywgdGhpcyBtdXN0IGZsdXNoIGFueQoJZGF0YSByZW1haW5pbmcgaW4gdGhlIGJ1ZmZlci4gIFVzZSBlaXRoZXIgbmV4dF9vdXRwdXRfYnl0ZSBvcgoJZnJlZV9pbl9idWZmZXIgdG8gZGV0ZXJtaW5lIGhvdyBtdWNoIGRhdGEgaXMgaW4gdGhlIGJ1ZmZlci4KKi8KTUVUSE9EREVGKHZvaWQpCnRlcm1fZGVzdGluYXRpb24gKGpfY29tcHJlc3NfcHRyIGNpbmZvKSB7CglmcmVlaW1hZ2VfZHN0X3B0ciBkZXN0ID0gKGZyZWVpbWFnZV9kc3RfcHRyKSBjaW5mby0+ZGVzdDsKCglzaXplX3QgZGF0YWNvdW50ID0gT1VUUFVUX0JVRl9TSVpFIC0gZGVzdC0+cHViLmZyZWVfaW5fYnVmZmVyOwoKCS8vIHdyaXRlIGFueSBkYXRhIHJlbWFpbmluZyBpbiB0aGUgYnVmZmVyCgoJaWYgKGRhdGFjb3VudCA+IDApIHsKCQlpZiAoZGVzdC0+bV9pby0+d3JpdGVfcHJvYyhkZXN0LT5idWZmZXIsIDEsICh1bnNpZ25lZCBpbnQpZGF0YWNvdW50LCBkZXN0LT5vdXRmaWxlKSAhPSBkYXRhY291bnQpCgkJICB0aHJvdyhjaW5mbywgSkVSUl9GSUxFX1dSSVRFKTsKCX0KfQoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQovLyAgIFNvdXJjZSBtYW5hZ2VyCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCi8qKgoJSW5pdGlhbGl6ZSBzb3VyY2UuICBUaGlzIGlzIGNhbGxlZCBieSBqcGVnX3JlYWRfaGVhZGVyKCkgYmVmb3JlIGFueQoJZGF0YSBpcyBhY3R1YWxseSByZWFkLiBVbmxpa2UgaW5pdF9kZXN0aW5hdGlvbigpLCBpdCBtYXkgbGVhdmUKCWJ5dGVzX2luX2J1ZmZlciBzZXQgdG8gMCAoaW4gd2hpY2ggY2FzZSBhIGZpbGxfaW5wdXRfYnVmZmVyKCkgY2FsbAoJd2lsbCBvY2N1ciBpbW1lZGlhdGVseSkuCiovCk1FVEhPRERFRih2b2lkKQppbml0X3NvdXJjZSAoal9kZWNvbXByZXNzX3B0ciBjaW5mbykgewoJZnJlZWltYWdlX3NyY19wdHIgc3JjID0gKGZyZWVpbWFnZV9zcmNfcHRyKSBjaW5mby0+c3JjOwoKCS8qIFdlIHJlc2V0IHRoZSBlbXB0eS1pbnB1dC1maWxlIGZsYWcgZm9yIGVhY2ggaW1hZ2UsCiAJICogYnV0IHdlIGRvbid0IGNsZWFyIHRoZSBpbnB1dCBidWZmZXIuCgkgKiBUaGlzIGlzIGNvcnJlY3QgYmVoYXZpb3IgZm9yIHJlYWRpbmcgYSBzZXJpZXMgb2YgaW1hZ2VzIGZyb20gb25lIHNvdXJjZS4KCSovCgoJc3JjLT5zdGFydF9vZl9maWxlID0gVFJVRTsKfQoKLyoqCglUaGlzIGlzIGNhbGxlZCB3aGVuZXZlciBieXRlc19pbl9idWZmZXIgaGFzIHJlYWNoZWQgemVybyBhbmQgbW9yZQoJZGF0YSBpcyB3YW50ZWQuICBJbiB0eXBpY2FsIGFwcGxpY2F0aW9ucywgaXQgc2hvdWxkIHJlYWQgZnJlc2ggZGF0YQoJaW50byB0aGUgYnVmZmVyIChpZ25vcmluZyB0aGUgY3VycmVudCBzdGF0ZSBvZiBuZXh0X2lucHV0X2J5dGUgYW5kCglieXRlc19pbl9idWZmZXIpLCByZXNldCB0aGUgcG9pbnRlciAmIGNvdW50IHRvIHRoZSBzdGFydCBvZiB0aGUKCWJ1ZmZlciwgYW5kIHJldHVybiBUUlVFIGluZGljYXRpbmcgdGhhdCB0aGUgYnVmZmVyIGhhcyBiZWVuIHJlbG9hZGVkLgoJSXQgaXMgbm90IG5lY2Vzc2FyeSB0byBmaWxsIHRoZSBidWZmZXIgZW50aXJlbHksIG9ubHkgdG8gb2J0YWluIGF0CglsZWFzdCBvbmUgbW9yZSBieXRlLiAgYnl0ZXNfaW5fYnVmZmVyIE1VU1QgYmUgc2V0IHRvIGEgcG9zaXRpdmUgdmFsdWUKCWlmIFRSVUUgaXMgcmV0dXJuZWQuICBBIEZBTFNFIHJldHVybiBzaG91bGQgb25seSBiZSB1c2VkIHdoZW4gSS9PCglzdXNwZW5zaW9uIGlzIGRlc2lyZWQuCiovCk1FVEhPRERFRihib29sZWFuKQpmaWxsX2lucHV0X2J1ZmZlciAoal9kZWNvbXByZXNzX3B0ciBjaW5mbykgewoJZnJlZWltYWdlX3NyY19wdHIgc3JjID0gKGZyZWVpbWFnZV9zcmNfcHRyKSBjaW5mby0+c3JjOwoKCXNpemVfdCBuYnl0ZXMgPSBzcmMtPm1faW8tPnJlYWRfcHJvYyhzcmMtPmJ1ZmZlciwgMSwgSU5QVVRfQlVGX1NJWkUsIHNyYy0+aW5maWxlKTsKCglpZiAobmJ5dGVzIDw9IDApIHsKCQlpZiAoc3JjLT5zdGFydF9vZl9maWxlKQkvKiBUcmVhdCBlbXB0eSBpbnB1dCBmaWxlIGFzIGZhdGFsIGVycm9yICovCgkJCXRocm93KGNpbmZvLCBKRVJSX0lOUFVUX0VNUFRZKTsKCgkJV0FSTk1TKGNpbmZvLCBKV1JOX0pQRUdfRU9GKTsKCgkJLyogSW5zZXJ0IGEgZmFrZSBFT0kgbWFya2VyICovCgoJCXNyYy0+YnVmZmVyWzBdID0gKEpPQ1RFVCkgMHhGRjsKCQlzcmMtPmJ1ZmZlclsxXSA9IChKT0NURVQpIEpQRUdfRU9JOwoKCQluYnl0ZXMgPSAyOwoJfQoKCXNyYy0+cHViLm5leHRfaW5wdXRfYnl0ZSA9IHNyYy0+YnVmZmVyOwoJc3JjLT5wdWIuYnl0ZXNfaW5fYnVmZmVyID0gbmJ5dGVzOwoJc3JjLT5zdGFydF9vZl9maWxlID0gRkFMU0U7CgoJcmV0dXJuIFRSVUU7Cn0KCi8qKgoJU2tpcCBudW1fYnl0ZXMgd29ydGggb2YgZGF0YS4gIFRoZSBidWZmZXIgcG9pbnRlciBhbmQgY291bnQgc2hvdWxkCgliZSBhZHZhbmNlZCBvdmVyIG51bV9ieXRlcyBpbnB1dCBieXRlcywgcmVmaWxsaW5nIHRoZSBidWZmZXIgYXMKCW5lZWRlZC4gVGhpcyBpcyB1c2VkIHRvIHNraXAgb3ZlciBhIHBvdGVudGlhbGx5IGxhcmdlIGFtb3VudCBvZgoJdW5pbnRlcmVzdGluZyBkYXRhIChzdWNoIGFzIGFuIEFQUG4gbWFya2VyKS4gSW4gc29tZSBhcHBsaWNhdGlvbnMKCWl0IG1heSBiZSBwb3NzaWJsZSB0byBvcHRpbWl6ZSBhd2F5IHRoZSByZWFkaW5nIG9mIHRoZSBza2lwcGVkIGRhdGEsCglidXQgaXQncyBub3QgY2xlYXIgdGhhdCBiZWluZyBzbWFydCBpcyB3b3J0aCBtdWNoIHRyb3VibGU7IGxhcmdlCglza2lwcyBhcmUgdW5jb21tb24uICBieXRlc19pbl9idWZmZXIgbWF5IGJlIHplcm8gb24gcmV0dXJuLgoJQSB6ZXJvIG9yIG5lZ2F0aXZlIHNraXAgY291bnQgc2hvdWxkIGJlIHRyZWF0ZWQgYXMgYSBuby1vcC4KKi8KTUVUSE9EREVGKHZvaWQpCnNraXBfaW5wdXRfZGF0YSAoal9kZWNvbXByZXNzX3B0ciBjaW5mbywgbG9uZyBudW1fYnl0ZXMpIHsKCWZyZWVpbWFnZV9zcmNfcHRyIHNyYyA9IChmcmVlaW1hZ2Vfc3JjX3B0cikgY2luZm8tPnNyYzsKCgkvKiBKdXN0IGEgZHVtYiBpbXBsZW1lbnRhdGlvbiBmb3Igbm93LiAgQ291bGQgdXNlIGZzZWVrKCkgZXhjZXB0CiAgICAgKiBpdCBkb2Vzbid0IHdvcmsgb24gcGlwZXMuICBOb3QgY2xlYXIgdGhhdCBiZWluZyBzbWFydCBpcyB3b3J0aAoJICogYW55IHRyb3VibGUgYW55d2F5IC0tLSBsYXJnZSBza2lwcyBhcmUgaW5mcmVxdWVudC4KCSovCgoJaWYgKG51bV9ieXRlcyA+IDApIHsKCQl3aGlsZSAobnVtX2J5dGVzID4gKGxvbmcpIHNyYy0+cHViLmJ5dGVzX2luX2J1ZmZlcikgewoJCSAgbnVtX2J5dGVzIC09IChsb25nKSBzcmMtPnB1Yi5ieXRlc19pbl9idWZmZXI7CgoJCSAgKHZvaWQpIGZpbGxfaW5wdXRfYnVmZmVyKGNpbmZvKTsKCgkJICAvKiBub3RlIHdlIGFzc3VtZSB0aGF0IGZpbGxfaW5wdXRfYnVmZmVyIHdpbGwgbmV2ZXIgcmV0dXJuIEZBTFNFLAoJCSAgICogc28gc3VzcGVuc2lvbiBuZWVkIG5vdCBiZSBoYW5kbGVkLgoJCSAgICovCgkJfQoKCQlzcmMtPnB1Yi5uZXh0X2lucHV0X2J5dGUgKz0gKHNpemVfdCkgbnVtX2J5dGVzOwoJCXNyYy0+cHViLmJ5dGVzX2luX2J1ZmZlciAtPSAoc2l6ZV90KSBudW1fYnl0ZXM7Cgl9Cn0KCi8qKgoJVGVybWluYXRlIHNvdXJjZSAtLS0gY2FsbGVkIGJ5IGpwZWdfZmluaXNoX2RlY29tcHJlc3MKCWFmdGVyIGFsbCBkYXRhIGhhcyBiZWVuIHJlYWQuICBPZnRlbiBhIG5vLW9wLgoKCU5COiAqbm90KiBjYWxsZWQgYnkganBlZ19hYm9ydCBvciBqcGVnX2Rlc3Ryb3k7IHN1cnJvdW5kaW5nCglhcHBsaWNhdGlvbiBtdXN0IGRlYWwgd2l0aCBhbnkgY2xlYW51cCB0aGF0IHNob3VsZCBoYXBwZW4gZXZlbgoJZm9yIGVycm9yIGV4aXQuCiovCk1FVEhPRERFRih2b2lkKQp0ZXJtX3NvdXJjZSAoal9kZWNvbXByZXNzX3B0ciBjaW5mbykgewogIC8vIG5vIHdvcmsgbmVjZXNzYXJ5IGhlcmUKfQoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQovLyAgIFNvdXJjZSBtYW5hZ2VyICYgRGVzdGluYXRpb24gbWFuYWdlciBzZXR1cAovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgovKioKCVByZXBhcmUgZm9yIGlucHV0IGZyb20gYSBzdGRpbyBzdHJlYW0uCglUaGUgY2FsbGVyIG11c3QgaGF2ZSBhbHJlYWR5IG9wZW5lZCB0aGUgc3RyZWFtLCBhbmQgaXMgcmVzcG9uc2libGUKCWZvciBjbG9zaW5nIGl0IGFmdGVyIGZpbmlzaGluZyBkZWNvbXByZXNzaW9uLgoqLwpHTE9CQUwodm9pZCkKanBlZ19mcmVlaW1hZ2Vfc3JjIChqX2RlY29tcHJlc3NfcHRyIGNpbmZvLCBmaV9oYW5kbGUgaW5maWxlLCBGcmVlSW1hZ2VJTyAqaW8pIHsKCWZyZWVpbWFnZV9zcmNfcHRyIHNyYzsKCgkvLyBhbGxvY2F0ZSBtZW1vcnkgZm9yIHRoZSBidWZmZXIuIGlzIHJlbGVhc2VkIGF1dG9tYXRpY2FsbHkgaW4gdGhlIGVuZAoKCWlmIChjaW5mby0+c3JjID09IE5VTEwpIHsKCQljaW5mby0+c3JjID0gKHN0cnVjdCBqcGVnX3NvdXJjZV9tZ3IgKikgKCpjaW5mby0+bWVtLT5hbGxvY19zbWFsbCkKCQkJKChqX2NvbW1vbl9wdHIpIGNpbmZvLCBKUE9PTF9QRVJNQU5FTlQsIFNJWkVPRihTb3VyY2VNYW5hZ2VyKSk7CgoJCXNyYyA9IChmcmVlaW1hZ2Vfc3JjX3B0cikgY2luZm8tPnNyYzsKCgkJc3JjLT5idWZmZXIgPSAoSk9DVEVUICopICgqY2luZm8tPm1lbS0+YWxsb2Nfc21hbGwpCgkJCSgoal9jb21tb25fcHRyKSBjaW5mbywgSlBPT0xfUEVSTUFORU5ULCBJTlBVVF9CVUZfU0laRSAqIFNJWkVPRihKT0NURVQpKTsKCX0KCgkvLyBpbml0aWFsaXplIHRoZSBqcGVnIHBvaW50ZXIgc3RydWN0IHdpdGggcG9pbnRlcnMgdG8gZnVuY3Rpb25zCgoJc3JjID0gKGZyZWVpbWFnZV9zcmNfcHRyKSBjaW5mby0+c3JjOwoJc3JjLT5wdWIuaW5pdF9zb3VyY2UgPSBpbml0X3NvdXJjZTsKCXNyYy0+cHViLmZpbGxfaW5wdXRfYnVmZmVyID0gZmlsbF9pbnB1dF9idWZmZXI7CglzcmMtPnB1Yi5za2lwX2lucHV0X2RhdGEgPSBza2lwX2lucHV0X2RhdGE7CglzcmMtPnB1Yi5yZXN5bmNfdG9fcmVzdGFydCA9IGpwZWdfcmVzeW5jX3RvX3Jlc3RhcnQ7IC8vIHVzZSBkZWZhdWx0IG1ldGhvZCAKCXNyYy0+cHViLnRlcm1fc291cmNlID0gdGVybV9zb3VyY2U7CglzcmMtPmluZmlsZSA9IGluZmlsZTsKCXNyYy0+bV9pbyA9IGlvOwoJc3JjLT5wdWIuYnl0ZXNfaW5fYnVmZmVyID0gMDsJCS8vIGZvcmNlcyBmaWxsX2lucHV0X2J1ZmZlciBvbiBmaXJzdCByZWFkIAoJc3JjLT5wdWIubmV4dF9pbnB1dF9ieXRlID0gTlVMTDsJLy8gdW50aWwgYnVmZmVyIGxvYWRlZCAKfQoKLyoqCglQcmVwYXJlIGZvciBvdXRwdXQgdG8gYSBzdGRpbyBzdHJlYW0uCglUaGUgY2FsbGVyIG11c3QgaGF2ZSBhbHJlYWR5IG9wZW5lZCB0aGUgc3RyZWFtLCBhbmQgaXMgcmVzcG9uc2libGUKCWZvciBjbG9zaW5nIGl0IGFmdGVyIGZpbmlzaGluZyBjb21wcmVzc2lvbi4KKi8KR0xPQkFMKHZvaWQpCmpwZWdfZnJlZWltYWdlX2RzdCAoal9jb21wcmVzc19wdHIgY2luZm8sIGZpX2hhbmRsZSBvdXRmaWxlLCBGcmVlSW1hZ2VJTyAqaW8pIHsKCWZyZWVpbWFnZV9kc3RfcHRyIGRlc3Q7CgoJaWYgKGNpbmZvLT5kZXN0ID09IE5VTEwpIHsKCQljaW5mby0+ZGVzdCA9IChzdHJ1Y3QganBlZ19kZXN0aW5hdGlvbl9tZ3IgKikoKmNpbmZvLT5tZW0tPmFsbG9jX3NtYWxsKQoJCQkoKGpfY29tbW9uX3B0cikgY2luZm8sIEpQT09MX1BFUk1BTkVOVCwgU0laRU9GKERlc3RpbmF0aW9uTWFuYWdlcikpOwoJfQoKCWRlc3QgPSAoZnJlZWltYWdlX2RzdF9wdHIpIGNpbmZvLT5kZXN0OwoJZGVzdC0+cHViLmluaXRfZGVzdGluYXRpb24gPSBpbml0X2Rlc3RpbmF0aW9uOwoJZGVzdC0+cHViLmVtcHR5X291dHB1dF9idWZmZXIgPSBlbXB0eV9vdXRwdXRfYnVmZmVyOwoJZGVzdC0+cHViLnRlcm1fZGVzdGluYXRpb24gPSB0ZXJtX2Rlc3RpbmF0aW9uOwoJZGVzdC0+b3V0ZmlsZSA9IG91dGZpbGU7CglkZXN0LT5tX2lvID0gaW87Cn0KCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLy8gICBTcGVjaWFsIG1hcmtlcnMgcmVhZCBmdW5jdGlvbnMKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKLyoqCglSZWFkIEpQRUdfQ09NIG1hcmtlciAoY29tbWVudCkKKi8Kc3RhdGljIEJPT0wgCmpwZWdfcmVhZF9jb21tZW50KEZJQklUTUFQICpkaWIsIGNvbnN0IEJZVEUgKmRhdGFwdHIsIHVuc2lnbmVkIGludCBkYXRhbGVuKSB7CglzaXplX3QgbGVuZ3RoID0gZGF0YWxlbjsKCUJZVEUgKnByb2ZpbGUgPSAoQllURSopZGF0YXB0cjsKCgkvLyByZWFkIHRoZSBjb21tZW50CgljaGFyICp2YWx1ZSA9IChjaGFyKiltYWxsb2MoKGxlbmd0aCArIDEpICogc2l6ZW9mKGNoYXIpKTsKCWlmKHZhbHVlID09IE5VTEwpIHJldHVybiBGQUxTRTsKCW1lbWNweSh2YWx1ZSwgcHJvZmlsZSwgbGVuZ3RoKTsKCXZhbHVlW2xlbmd0aF0gPSAnXDAnOwoKCS8vIGNyZWF0ZSBhIHRhZwoJRklUQUcgKnRhZyA9IEZyZWVJbWFnZV9DcmVhdGVUYWcoKTsKCWlmKHRhZykgewoJCXVuc2lnbmVkIGludCBjb3VudCA9ICh1bnNpZ25lZCBpbnQpbGVuZ3RoICsgMTsJLy8gaW5jbHVkZXMgdGhlIG51bGwgdmFsdWUKCgkJRnJlZUltYWdlX1NldFRhZ0lEKHRhZywgSlBFR19DT00pOwoJCUZyZWVJbWFnZV9TZXRUYWdLZXkodGFnLCAiQ29tbWVudCIpOwoJCUZyZWVJbWFnZV9TZXRUYWdMZW5ndGgodGFnLCBjb3VudCk7CgkJRnJlZUltYWdlX1NldFRhZ0NvdW50KHRhZywgY291bnQpOwoJCUZyZWVJbWFnZV9TZXRUYWdUeXBlKHRhZywgRklEVF9BU0NJSSk7CgkJRnJlZUltYWdlX1NldFRhZ1ZhbHVlKHRhZywgdmFsdWUpOwoJCQoJCS8vIHN0b3JlIHRoZSB0YWcKCQlGcmVlSW1hZ2VfU2V0TWV0YWRhdGEoRklNRF9DT01NRU5UUywgZGliLCBGcmVlSW1hZ2VfR2V0VGFnS2V5KHRhZyksIHRhZyk7CgoJCS8vIGRlc3Ryb3kgdGhlIHRhZwoJCUZyZWVJbWFnZV9EZWxldGVUYWcodGFnKTsKCX0KCglmcmVlKHZhbHVlKTsKCglyZXR1cm4gVFJVRTsKfQoKLyoqIAoJUmVhZCBKUEVHX0FQUDIgbWFya2VyIChJQ0MgcHJvZmlsZSkKKi8KCi8qKgpIYW5keSBzdWJyb3V0aW5lIHRvIHRlc3Qgd2hldGhlciBhIHNhdmVkIG1hcmtlciBpcyBhbiBJQ0MgcHJvZmlsZSBtYXJrZXIuCiovCnN0YXRpYyBCT09MIAptYXJrZXJfaXNfaWNjKGpwZWdfc2F2ZWRfbWFya2VyX3B0ciBtYXJrZXIpIHsKICAgIC8vIG1hcmtlciBpZGVudGlmeWluZyBzdHJpbmcgIklDQ19QUk9GSUxFIiAobnVsbC10ZXJtaW5hdGVkKQoJY29uc3QgQllURSBpY2Nfc2lnbmF0dXJlWzEyXSA9IHsgMHg0OSwgMHg0MywgMHg0MywgMHg1RiwgMHg1MCwgMHg1MiwgMHg0RiwgMHg0NiwgMHg0OSwgMHg0QywgMHg0NSwgMHgwMCB9OwoKCWlmKG1hcmtlci0+bWFya2VyID09IElDQ19NQVJLRVIpIHsKCQkvLyB2ZXJpZnkgdGhlIGlkZW50aWZ5aW5nIHN0cmluZwoJCWlmKG1hcmtlci0+ZGF0YV9sZW5ndGggPj0gSUNDX0hFQURFUl9TSVpFKSB7CgkJCWlmKG1lbWNtcChpY2Nfc2lnbmF0dXJlLCBtYXJrZXItPmRhdGEsIHNpemVvZihpY2Nfc2lnbmF0dXJlKSkgPT0gMCkgewoJCQkJcmV0dXJuIFRSVUU7CgkJCX0KCQl9Cgl9CgoJcmV0dXJuIEZBTFNFOwp9CgovKioKICBTZWUgaWYgdGhlcmUgd2FzIGFuIElDQyBwcm9maWxlIGluIHRoZSBKUEVHIGZpbGUgYmVpbmcgcmVhZDsKICBpZiBzbywgcmVhc3NlbWJsZSBhbmQgcmV0dXJuIHRoZSBwcm9maWxlIGRhdGEuCgogIFRSVUUgaXMgcmV0dXJuZWQgaWYgYW4gSUNDIHByb2ZpbGUgd2FzIGZvdW5kLCBGQUxTRSBpZiBub3QuCiAgSWYgVFJVRSBpcyByZXR1cm5lZCwgKmljY19kYXRhX3B0ciBpcyBzZXQgdG8gcG9pbnQgdG8gdGhlCiAgcmV0dXJuZWQgZGF0YSwgYW5kICppY2NfZGF0YV9sZW4gaXMgc2V0IHRvIGl0cyBsZW5ndGguCiAgCiAgSU1QT1JUQU5UOiB0aGUgZGF0YSBhdCAqKmljY19kYXRhX3B0ciBoYXMgYmVlbiBhbGxvY2F0ZWQgd2l0aCBtYWxsb2MoKQogIGFuZCBtdXN0IGJlIGZyZWVkIGJ5IHRoZSBjYWxsZXIgd2l0aCBmcmVlKCkgd2hlbiB0aGUgY2FsbGVyIG5vIGxvbmdlcgogIG5lZWRzIGl0LiAgKEFsdGVybmF0aXZlbHksIHdlIGNvdWxkIHdyaXRlIHRoaXMgcm91dGluZSB0byB1c2UgdGhlCiAgSUpHIGxpYnJhcnkncyBtZW1vcnkgYWxsb2NhdG9yLCBzbyB0aGF0IHRoZSBkYXRhIHdvdWxkIGJlIGZyZWVkIGltcGxpY2l0bHkKICBhdCBqcGVnX2ZpbmlzaF9kZWNvbXByZXNzKCkgdGltZS4gIEJ1dCBpdCBzZWVtcyBsaWtlbHkgdGhhdCBtYW55IGFwcHMKICB3aWxsIHByZWZlciB0byBoYXZlIHRoZSBkYXRhIHN0aWNrIGFyb3VuZCBhZnRlciBkZWNvbXByZXNzaW9uIGZpbmlzaGVzLikKICAKICBOT1RFOiBpZiB0aGUgZmlsZSBjb250YWlucyBpbnZhbGlkIElDQyBBUFAyIG1hcmtlcnMsIHdlIGp1c3Qgc2lsZW50bHkKICByZXR1cm4gRkFMU0UuICBZb3UgbWlnaHQgd2FudCB0byBpc3N1ZSBhbiBlcnJvciBtZXNzYWdlIGluc3RlYWQuCiovCnN0YXRpYyBCT09MIApqcGVnX3JlYWRfaWNjX3Byb2ZpbGUoal9kZWNvbXByZXNzX3B0ciBjaW5mbywgSk9DVEVUICoqaWNjX2RhdGFfcHRyLCB1bnNpZ25lZCAqaWNjX2RhdGFfbGVuKSB7CglqcGVnX3NhdmVkX21hcmtlcl9wdHIgbWFya2VyOwoJaW50IG51bV9tYXJrZXJzID0gMDsKCWludCBzZXFfbm87CglKT0NURVQgKmljY19kYXRhOwoJdW5zaWduZWQgdG90YWxfbGVuZ3RoOwoKCWNvbnN0IGludCBNQVhfU0VRX05PID0gMjU1OwkJCS8vIHN1ZmZpY2llbnQgc2luY2UgbWFya2VyIG51bWJlcnMgYXJlIGJ5dGVzCglCWVRFIG1hcmtlcl9wcmVzZW50W01BWF9TRVFfTk8rMV07CS8vIDEgaWYgbWFya2VyIGZvdW5kCgl1bnNpZ25lZCBkYXRhX2xlbmd0aFtNQVhfU0VRX05PKzFdOwkvLyBzaXplIG9mIHByb2ZpbGUgZGF0YSBpbiBtYXJrZXIKCXVuc2lnbmVkIGRhdGFfb2Zmc2V0W01BWF9TRVFfTk8rMV07CS8vIG9mZnNldCBmb3IgZGF0YSBpbiBtYXJrZXIKCQoJKmljY19kYXRhX3B0ciA9IE5VTEw7CQkvLyBhdm9pZCBjb25mdXNpb24gaWYgRkFMU0UgcmV0dXJuCgkqaWNjX2RhdGFfbGVuID0gMDsKCQoJLyoqCgl0aGlzIGZpcnN0IHBhc3Mgb3ZlciB0aGUgc2F2ZWQgbWFya2VycyBkaXNjb3ZlcnMgd2hldGhlciB0aGVyZSBhcmUKCWFueSBJQ0MgbWFya2VycyBhbmQgdmVyaWZpZXMgdGhlIGNvbnNpc3RlbmN5IG9mIHRoZSBtYXJrZXIgbnVtYmVyaW5nLgoJKi8KCQoJbWVtc2V0KG1hcmtlcl9wcmVzZW50LCAwLCAoTUFYX1NFUV9OTyArIDEpKTsKCQoJZm9yKG1hcmtlciA9IGNpbmZvLT5tYXJrZXJfbGlzdDsgbWFya2VyICE9IE5VTEw7IG1hcmtlciA9IG1hcmtlci0+bmV4dCkgewoJCWlmIChtYXJrZXJfaXNfaWNjKG1hcmtlcikpIHsKCQkJaWYgKG51bV9tYXJrZXJzID09IDApIHsKCQkJCS8vIG51bWJlciBvZiBtYXJrZXJzCgkJCQludW1fbWFya2VycyA9IEdFVEpPQ1RFVChtYXJrZXItPmRhdGFbMTNdKTsKCQkJfQoJCQllbHNlIGlmIChudW1fbWFya2VycyAhPSBHRVRKT0NURVQobWFya2VyLT5kYXRhWzEzXSkpIHsKCQkJCXJldHVybiBGQUxTRTsJCS8vIGluY29uc2lzdGVudCBudW1fbWFya2VycyBmaWVsZHMgCgkJCX0KCQkJLy8gc2VxdWVuY2UgbnVtYmVyCgkJCXNlcV9ubyA9IEdFVEpPQ1RFVChtYXJrZXItPmRhdGFbMTJdKTsKCQkJaWYgKHNlcV9ubyA8PSAwIHx8IHNlcV9ubyA+IG51bV9tYXJrZXJzKSB7CgkJCQlyZXR1cm4gRkFMU0U7CQkvLyBib2d1cyBzZXF1ZW5jZSBudW1iZXIgCgkJCX0KCQkJaWYgKG1hcmtlcl9wcmVzZW50W3NlcV9ub10pIHsKCQkJCXJldHVybiBGQUxTRTsJCS8vIGR1cGxpY2F0ZSBzZXF1ZW5jZSBudW1iZXJzIAoJCQl9CgkJCW1hcmtlcl9wcmVzZW50W3NlcV9ub10gPSAxOwoJCQlkYXRhX2xlbmd0aFtzZXFfbm9dID0gbWFya2VyLT5kYXRhX2xlbmd0aCAtIElDQ19IRUFERVJfU0laRTsKCQl9Cgl9CgkKCWlmIChudW1fbWFya2VycyA9PSAwKQoJCXJldHVybiBGQUxTRTsKCQkKCS8qKgoJY2hlY2sgZm9yIG1pc3NpbmcgbWFya2VycywgY291bnQgdG90YWwgc3BhY2UgbmVlZGVkLAoJY29tcHV0ZSBvZmZzZXQgb2YgZWFjaCBtYXJrZXIncyBwYXJ0IG9mIHRoZSBkYXRhLgoJKi8KCQoJdG90YWxfbGVuZ3RoID0gMDsKCWZvcihzZXFfbm8gPSAxOyBzZXFfbm8gPD0gbnVtX21hcmtlcnM7IHNlcV9ubysrKSB7CgkJaWYgKG1hcmtlcl9wcmVzZW50W3NlcV9ub10gPT0gMCkgewoJCQlyZXR1cm4gRkFMU0U7CQkvLyBtaXNzaW5nIHNlcXVlbmNlIG51bWJlcgoJCX0KCQlkYXRhX29mZnNldFtzZXFfbm9dID0gdG90YWxfbGVuZ3RoOwoJCXRvdGFsX2xlbmd0aCArPSBkYXRhX2xlbmd0aFtzZXFfbm9dOwoJfQoJCglpZiAodG90YWxfbGVuZ3RoIDw9IDApCgkJcmV0dXJuIEZBTFNFOwkJLy8gZm91bmQgb25seSBlbXB0eSBtYXJrZXJzID8KCQoJLy8gYWxsb2NhdGUgc3BhY2UgZm9yIGFzc2VtYmxlZCBkYXRhIAoJaWNjX2RhdGEgPSAoSk9DVEVUICopIG1hbGxvYyh0b3RhbF9sZW5ndGggKiBzaXplb2YoSk9DVEVUKSk7CglpZiAoaWNjX2RhdGEgPT0gTlVMTCkKCQlyZXR1cm4gRkFMU0U7CQkvLyBvdXQgb2YgbWVtb3J5CgkKCS8vIGFuZCBmaWxsIGl0IGluCglmb3IgKG1hcmtlciA9IGNpbmZvLT5tYXJrZXJfbGlzdDsgbWFya2VyICE9IE5VTEw7IG1hcmtlciA9IG1hcmtlci0+bmV4dCkgewoJCWlmIChtYXJrZXJfaXNfaWNjKG1hcmtlcikpIHsKCQkJSk9DVEVUIEZBUiAqc3JjX3B0cjsKCQkJSk9DVEVUICpkc3RfcHRyOwoJCQl1bnNpZ25lZCBsZW5ndGg7CgkJCXNlcV9ubyA9IEdFVEpPQ1RFVChtYXJrZXItPmRhdGFbMTJdKTsKCQkJZHN0X3B0ciA9IGljY19kYXRhICsgZGF0YV9vZmZzZXRbc2VxX25vXTsKCQkJc3JjX3B0ciA9IG1hcmtlci0+ZGF0YSArIElDQ19IRUFERVJfU0laRTsKCQkJbGVuZ3RoID0gZGF0YV9sZW5ndGhbc2VxX25vXTsKCQkJd2hpbGUgKGxlbmd0aC0tKSB7CgkJCQkqZHN0X3B0cisrID0gKnNyY19wdHIrKzsKCQkJfQoJCX0KCX0KCQoJKmljY19kYXRhX3B0ciA9IGljY19kYXRhOwoJKmljY19kYXRhX2xlbiA9IHRvdGFsX2xlbmd0aDsKCQoJcmV0dXJuIFRSVUU7Cn0KCi8qKgoJUmVhZCBKUEVHX0FQUEQgbWFya2VyIChJUFRDIG9yIEFkb2JlIFBob3Rvc2hvcCBwcm9maWxlKQoqLwpCT09MIApqcGVnX3JlYWRfaXB0Y19wcm9maWxlKEZJQklUTUFQICpkaWIsIGNvbnN0IEJZVEUgKmRhdGFwdHIsIHVuc2lnbmVkIGludCBkYXRhbGVuKSB7CglyZXR1cm4gcmVhZF9pcHRjX3Byb2ZpbGUoZGliLCBkYXRhcHRyLCBkYXRhbGVuKTsKfQoKLyoqCglSZWFkIEpQRUdfQVBQMSBtYXJrZXIgKFhNUCBwcm9maWxlKQoJQHBhcmFtIGRpYiBJbnB1dCBGSUJJVE1BUAoJQHBhcmFtIGRhdGFwdHIgUG9pbnRlciB0byB0aGUgQVBQMSBtYXJrZXIKCUBwYXJhbSBkYXRhbGVuIEFQUDEgbWFya2VyIGxlbmd0aAoJQHJldHVybiBSZXR1cm5zIFRSVUUgaWYgc3VjY2Vzc2Z1bCwgRkFMU0Ugb3RoZXJ3aXNlCiovCnN0YXRpYyBCT09MICAKanBlZ19yZWFkX3htcF9wcm9maWxlKEZJQklUTUFQICpkaWIsIGNvbnN0IEJZVEUgKmRhdGFwdHIsIHVuc2lnbmVkIGludCBkYXRhbGVuKSB7CgkvLyBtYXJrZXIgaWRlbnRpZnlpbmcgc3RyaW5nIGZvciBYTVAgKG51bGwgdGVybWluYXRlZCkKCWNoYXIgKnhtcF9zaWduYXR1cmUgPSAiaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyI7CgoJc2l6ZV90IGxlbmd0aCA9IGRhdGFsZW47CglCWVRFICpwcm9maWxlID0gKEJZVEUqKWRhdGFwdHI7CgoJLy8gdmVyaWZ5IHRoZSBpZGVudGlmeWluZyBzdHJpbmcKCglpZihtZW1jbXAoeG1wX3NpZ25hdHVyZSwgcHJvZmlsZSwgc3RybGVuKHhtcF9zaWduYXR1cmUpKSA9PSAwKSB7CgkJLy8gWE1QIHByb2ZpbGUKCgkJc2l6ZV90IG9mZnNldCA9IHN0cmxlbih4bXBfc2lnbmF0dXJlKSArIDE7CgkJcHJvZmlsZSArPSBvZmZzZXQ7CgkJbGVuZ3RoICAtPSBvZmZzZXQ7CgoJCS8vIGNyZWF0ZSBhIHRhZwoJCUZJVEFHICp0YWcgPSBGcmVlSW1hZ2VfQ3JlYXRlVGFnKCk7CgkJaWYodGFnKSB7CgkJCUZyZWVJbWFnZV9TZXRUYWdJRCh0YWcsIEpQRUdfQVBQMCsxKTsJLy8gMHhGRkUxCgkJCUZyZWVJbWFnZV9TZXRUYWdLZXkodGFnLCBnX1RhZ0xpYl9YTVBGaWVsZE5hbWUpOwoJCQlGcmVlSW1hZ2VfU2V0VGFnTGVuZ3RoKHRhZywgKERXT1JEKWxlbmd0aCk7CgkJCUZyZWVJbWFnZV9TZXRUYWdDb3VudCh0YWcsIChEV09SRClsZW5ndGgpOwoJCQlGcmVlSW1hZ2VfU2V0VGFnVHlwZSh0YWcsIEZJRFRfQVNDSUkpOwoJCQlGcmVlSW1hZ2VfU2V0VGFnVmFsdWUodGFnLCBwcm9maWxlKTsKCQkJCgkJCS8vIHN0b3JlIHRoZSB0YWcKCQkJRnJlZUltYWdlX1NldE1ldGFkYXRhKEZJTURfWE1QLCBkaWIsIEZyZWVJbWFnZV9HZXRUYWdLZXkodGFnKSwgdGFnKTsKCgkJCS8vIGRlc3Ryb3kgdGhlIHRhZwoJCQlGcmVlSW1hZ2VfRGVsZXRlVGFnKHRhZyk7CgkJfQoKCQlyZXR1cm4gVFJVRTsKCX0KCglyZXR1cm4gRkFMU0U7Cn0KCi8qKgoJUmVhZCBKUEVHIHNwZWNpYWwgbWFya2VycwoqLwpzdGF0aWMgQk9PTCAKcmVhZF9tYXJrZXJzKGpfZGVjb21wcmVzc19wdHIgY2luZm8sIEZJQklUTUFQICpkaWIpIHsKCWpwZWdfc2F2ZWRfbWFya2VyX3B0ciBtYXJrZXI7CgoJZm9yKG1hcmtlciA9IGNpbmZvLT5tYXJrZXJfbGlzdDsgbWFya2VyICE9IE5VTEw7IG1hcmtlciA9IG1hcmtlci0+bmV4dCkgewoJCXN3aXRjaChtYXJrZXItPm1hcmtlcikgewoJCQljYXNlIEpQRUdfQ09NOgoJCQkJLy8gSlBFRyBjb21tZW50CgkJCQlqcGVnX3JlYWRfY29tbWVudChkaWIsIG1hcmtlci0+ZGF0YSwgbWFya2VyLT5kYXRhX2xlbmd0aCk7CgkJCQlicmVhazsKCQkJY2FzZSBFWElGX01BUktFUjoKCQkJCS8vIEV4aWYgb3IgQWRvYmUgWE1QIHByb2ZpbGUKCQkJCWpwZWdfcmVhZF9leGlmX3Byb2ZpbGUoZGliLCBtYXJrZXItPmRhdGEsIG1hcmtlci0+ZGF0YV9sZW5ndGgpOwoJCQkJanBlZ19yZWFkX3htcF9wcm9maWxlKGRpYiwgbWFya2VyLT5kYXRhLCBtYXJrZXItPmRhdGFfbGVuZ3RoKTsKCQkJCWJyZWFrOwoJCQljYXNlIElQVENfTUFSS0VSOgoJCQkJLy8gSVBUQy9OQUEgb3IgQWRvYmUgUGhvdG9zaG9wIHByb2ZpbGUKCQkJCWpwZWdfcmVhZF9pcHRjX3Byb2ZpbGUoZGliLCBtYXJrZXItPmRhdGEsIG1hcmtlci0+ZGF0YV9sZW5ndGgpOwoJCQkJYnJlYWs7CgkJfQoJfQoKCS8vIElDQyBwcm9maWxlCglCWVRFICppY2NfcHJvZmlsZSA9IE5VTEw7Cgl1bnNpZ25lZCBpY2NfbGVuZ3RoID0gMDsKCglpZigganBlZ19yZWFkX2ljY19wcm9maWxlKGNpbmZvLCAmaWNjX3Byb2ZpbGUsICZpY2NfbGVuZ3RoKSApIHsKCQkvLyBjb3B5IElDQyBwcm9maWxlIGRhdGEKCQlGcmVlSW1hZ2VfQ3JlYXRlSUNDUHJvZmlsZShkaWIsIGljY19wcm9maWxlLCBpY2NfbGVuZ3RoKTsKCQkvLyBjbGVhbiB1cAoJCWZyZWUoaWNjX3Byb2ZpbGUpOwoJfQoKCXJldHVybiBUUlVFOwp9CgovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi8vICAgU3BlY2lhbCBtYXJrZXJzIHdyaXRlIGZ1bmN0aW9ucwovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgovKioKCVdyaXRlIEpQRUdfQ09NIG1hcmtlciAoY29tbWVudCkKKi8Kc3RhdGljIEJPT0wgCmpwZWdfd3JpdGVfY29tbWVudChqX2NvbXByZXNzX3B0ciBjaW5mbywgRklCSVRNQVAgKmRpYikgewoJRklUQUcgKnRhZyA9IE5VTEw7CgoJLy8gd3JpdGUgdXNlciBjb21tZW50IGFzIGEgSlBFR19DT00gbWFya2VyCglGcmVlSW1hZ2VfR2V0TWV0YWRhdGEoRklNRF9DT01NRU5UUywgZGliLCAiQ29tbWVudCIsICZ0YWcpOwoJaWYodGFnKSB7CgkJY29uc3QgY2hhciAqdGFnX3ZhbHVlID0gKGNoYXIqKUZyZWVJbWFnZV9HZXRUYWdWYWx1ZSh0YWcpOwoKCQlpZihOVUxMICE9IHRhZ192YWx1ZSkgewoJCQlmb3IobG9uZyBpID0gMDsgaSA8IChsb25nKXN0cmxlbih0YWdfdmFsdWUpOyBpKz0gTUFYX0JZVEVTX0lOX01BUktFUikgewoJCQkJanBlZ193cml0ZV9tYXJrZXIoY2luZm8sIEpQRUdfQ09NLCAoQllURSopdGFnX3ZhbHVlICsgaSwgTUlOKChsb25nKXN0cmxlbih0YWdfdmFsdWUgKyBpKSwgTUFYX0JZVEVTX0lOX01BUktFUikpOwoJCQl9CgkJCXJldHVybiBUUlVFOwoJCX0KCX0KCXJldHVybiBGQUxTRTsKfQoKLyoqIAoJV3JpdGUgSlBFR19BUFAyIG1hcmtlciAoSUNDIHByb2ZpbGUpCiovCnN0YXRpYyBCT09MIApqcGVnX3dyaXRlX2ljY19wcm9maWxlKGpfY29tcHJlc3NfcHRyIGNpbmZvLCBGSUJJVE1BUCAqZGliKSB7CiAgICAvLyBtYXJrZXIgaWRlbnRpZnlpbmcgc3RyaW5nICJJQ0NfUFJPRklMRSIgKG51bGwtdGVybWluYXRlZCkKCUJZVEUgaWNjX3NpZ25hdHVyZVsxMl0gPSB7IDB4NDksIDB4NDMsIDB4NDMsIDB4NUYsIDB4NTAsIDB4NTIsIDB4NEYsIDB4NDYsIDB4NDksIDB4NEMsIDB4NDUsIDB4MDAgfTsKCglGSUlDQ1BST0ZJTEUgKmljY1Byb2ZpbGUgPSBGcmVlSW1hZ2VfR2V0SUNDUHJvZmlsZShkaWIpOwoKCWlmIChpY2NQcm9maWxlLT5zaXplICYmIGljY1Byb2ZpbGUtPmRhdGEpIHsKCQkvLyBJQ0NfSEVBREVSX1NJWkU6IElDQyBzaWduYXR1cmUgaXMgJ0lDQ19QUk9GSUxFJyArIDIgYnl0ZXMKCgkJQllURSAqcHJvZmlsZSA9IChCWVRFKiltYWxsb2MoKGljY1Byb2ZpbGUtPnNpemUgKyBJQ0NfSEVBREVSX1NJWkUpICogc2l6ZW9mKEJZVEUpKTsKCQlpZihwcm9maWxlID09IE5VTEwpIHJldHVybiBGQUxTRTsKCQltZW1jcHkocHJvZmlsZSwgaWNjX3NpZ25hdHVyZSwgMTIpOwoKCQlmb3IobG9uZyBpID0gMDsgaSA8IChsb25nKWljY1Byb2ZpbGUtPnNpemU7IGkgKz0gTUFYX0RBVEFfQllURVNfSU5fTUFSS0VSKSB7CgkJCXVuc2lnbmVkIGxlbmd0aCA9IE1JTigobG9uZykoaWNjUHJvZmlsZS0+c2l6ZSAtIGkpLCBNQVhfREFUQV9CWVRFU19JTl9NQVJLRVIpOwoJCQkvLyBzZXF1ZW5jZSBudW1iZXIKCQkJcHJvZmlsZVsxMl0gPSAoQllURSkgKChpIC8gTUFYX0RBVEFfQllURVNfSU5fTUFSS0VSKSArIDEpOwoJCQkvLyBudW1iZXIgb2YgbWFya2VycwoJCQlwcm9maWxlWzEzXSA9IChCWVRFKSAoaWNjUHJvZmlsZS0+c2l6ZSAvIE1BWF9EQVRBX0JZVEVTX0lOX01BUktFUiArIDEpOwoKCQkJbWVtY3B5KHByb2ZpbGUgKyBJQ0NfSEVBREVSX1NJWkUsIChCWVRFKilpY2NQcm9maWxlLT5kYXRhICsgaSwgbGVuZ3RoKTsKCQkJanBlZ193cml0ZV9tYXJrZXIoY2luZm8sIElDQ19NQVJLRVIsIHByb2ZpbGUsIChsZW5ndGggKyBJQ0NfSEVBREVSX1NJWkUpKTsKICAgICAgICB9CgoJCWZyZWUocHJvZmlsZSk7CgoJCXJldHVybiBUUlVFOwkJCgl9CgkKCXJldHVybiBGQUxTRTsKfQoKLyoqIAoJV3JpdGUgSlBFR19BUFBEIG1hcmtlciAoSVBUQyBvciBBZG9iZSBQaG90b3Nob3AgcHJvZmlsZSkKCUByZXR1cm4gUmV0dXJucyBUUlVFIGlmIHN1Y2Nlc3NmdWwsIEZBTFNFIG90aGVyd2lzZQoqLwpzdGF0aWMgQk9PTCAgCmpwZWdfd3JpdGVfaXB0Y19wcm9maWxlKGpfY29tcHJlc3NfcHRyIGNpbmZvLCBGSUJJVE1BUCAqZGliKSB7CgkvL2NvbnN0IGNoYXIgKnBzX2hlYWRlciA9ICJQaG90b3Nob3AgMy4wXHgwOEJJTVx4MDRceDA0XHgwXHgwXHgwXHgwIjsKCWNvbnN0IHVuc2lnbmVkIHRhZ19sZW5ndGggPSAyNjsKCglpZihGcmVlSW1hZ2VfR2V0TWV0YWRhdGFDb3VudChGSU1EX0lQVEMsIGRpYikpIHsKCQlCWVRFICpwcm9maWxlID0gTlVMTDsKCQl1bnNpZ25lZCBwcm9maWxlX3NpemUgPSAwOwoKCQkvLyBjcmVhdGUgYSBiaW5hcnkgcHJvZmlsZQoJCWlmKHdyaXRlX2lwdGNfcHJvZmlsZShkaWIsICZwcm9maWxlLCAmcHJvZmlsZV9zaXplKSkgewoKCQkJLy8gd3JpdGUgdGhlIHByb2ZpbGUKCQkJZm9yKGxvbmcgaSA9IDA7IGkgPCAobG9uZylwcm9maWxlX3NpemU7IGkgKz0gNjU1MTdMKSB7CgkJCQl1bnNpZ25lZCBsZW5ndGggPSBNSU4oKGxvbmcpcHJvZmlsZV9zaXplIC0gaSwgNjU1MTdMKTsKCQkJCXVuc2lnbmVkIHJvdW5kdXAgPSBsZW5ndGggJiAweDAxOwkvLyBuZWVkZWQgZm9yIFBob3Rvc2hvcAoJCQkJQllURSAqaXB0Y19wcm9maWxlID0gKEJZVEUqKW1hbGxvYyhsZW5ndGggKyByb3VuZHVwICsgdGFnX2xlbmd0aCk7CgkJCQlpZihpcHRjX3Byb2ZpbGUgPT0gTlVMTCkgYnJlYWs7CgkJCQkvLyBQaG90b3Nob3AgaWRlbnRpZmljYXRpb24gc3RyaW5nCgkJCQltZW1jcHkoJmlwdGNfcHJvZmlsZVswXSwgIlBob3Rvc2hvcCAzLjBceDAiLCAxNCk7CgkJCQkvLyA4QklNIHNlZ21lbnQgdHlwZQoJCQkJbWVtY3B5KCZpcHRjX3Byb2ZpbGVbMTRdLCAiOEJJTVx4MDRceDA0XHgwXHgwXHgwXHgwIiwgMTApOwoJCQkJLy8gc2VnbWVudCBzaXplCgkJCQlpcHRjX3Byb2ZpbGVbMjRdID0gKEJZVEUpKGxlbmd0aCA+PiA4KTsKCQkJCWlwdGNfcHJvZmlsZVsyNV0gPSAoQllURSkobGVuZ3RoICYgMHhGRik7CgkJCQkvLyBzZWdtZW50IGRhdGEKCQkJCW1lbWNweSgmaXB0Y19wcm9maWxlW3RhZ19sZW5ndGhdLCAmcHJvZmlsZVtpXSwgbGVuZ3RoKTsKCQkJCWlmKHJvdW5kdXApCgkJCQkJaXB0Y19wcm9maWxlW2xlbmd0aCArIHRhZ19sZW5ndGhdID0gMDsKCQkJCWpwZWdfd3JpdGVfbWFya2VyKGNpbmZvLCBJUFRDX01BUktFUiwgaXB0Y19wcm9maWxlLCBsZW5ndGggKyByb3VuZHVwICsgdGFnX2xlbmd0aCk7CgkJCQlmcmVlKGlwdGNfcHJvZmlsZSk7CgkJCX0KCgkJCS8vIHJlbGVhc2UgcHJvZmlsZQoJCQlmcmVlKHByb2ZpbGUpOwoKCQkJcmV0dXJuIFRSVUU7CgkJfQoJfQoKCXJldHVybiBGQUxTRTsKfQoKLyoqIAoJV3JpdGUgSlBFR19BUFAxIG1hcmtlciAoWE1QIHByb2ZpbGUpCglAcmV0dXJuIFJldHVybnMgVFJVRSBpZiBzdWNjZXNzZnVsLCBGQUxTRSBvdGhlcndpc2UKKi8Kc3RhdGljIEJPT0wgIApqcGVnX3dyaXRlX3htcF9wcm9maWxlKGpfY29tcHJlc3NfcHRyIGNpbmZvLCBGSUJJVE1BUCAqZGliKSB7CgkvLyBtYXJrZXIgaWRlbnRpZnlpbmcgc3RyaW5nIGZvciBYTVAgKG51bGwgdGVybWluYXRlZCkKCWNoYXIgKnhtcF9zaWduYXR1cmUgPSAiaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyI7CgoJRklUQUcgKnRhZ194bXAgPSBOVUxMOwoJRnJlZUltYWdlX0dldE1ldGFkYXRhKEZJTURfWE1QLCBkaWIsIGdfVGFnTGliX1hNUEZpZWxkTmFtZSwgJnRhZ194bXApOwoKCWlmKHRhZ194bXApIHsKCQljb25zdCBCWVRFICp0YWdfdmFsdWUgPSAoQllURSopRnJlZUltYWdlX0dldFRhZ1ZhbHVlKHRhZ194bXApOwoKCQlpZihOVUxMICE9IHRhZ192YWx1ZSkgewoJCQkvLyBYTVAgc2lnbmF0dXJlIGlzIDI5IGJ5dGVzIGxvbmcKCQkJdW5zaWduZWQgaW50IHhtcF9oZWFkZXJfc2l6ZSA9ICh1bnNpZ25lZCBpbnQpc3RybGVuKHhtcF9zaWduYXR1cmUpICsgMTsKCgkJCURXT1JEIHRhZ19sZW5ndGggPSBGcmVlSW1hZ2VfR2V0VGFnTGVuZ3RoKHRhZ194bXApOwoKCQkJQllURSAqcHJvZmlsZSA9IChCWVRFKiltYWxsb2MoKHRhZ19sZW5ndGggKyB4bXBfaGVhZGVyX3NpemUpICogc2l6ZW9mKEJZVEUpKTsKCQkJaWYocHJvZmlsZSA9PSBOVUxMKSByZXR1cm4gRkFMU0U7CgkJCW1lbWNweShwcm9maWxlLCB4bXBfc2lnbmF0dXJlLCB4bXBfaGVhZGVyX3NpemUpOwoKCQkJZm9yKERXT1JEIGkgPSAwOyBpIDwgdGFnX2xlbmd0aDsgaSArPSA2NTUwNEwpIHsKCQkJCXVuc2lnbmVkIGxlbmd0aCA9IE1JTigobG9uZykodGFnX2xlbmd0aCAtIGkpLCA2NTUwNEwpOwoJCQkJCgkJCQltZW1jcHkocHJvZmlsZSArIHhtcF9oZWFkZXJfc2l6ZSwgdGFnX3ZhbHVlICsgaSwgbGVuZ3RoKTsKCQkJCWpwZWdfd3JpdGVfbWFya2VyKGNpbmZvLCBFWElGX01BUktFUiwgcHJvZmlsZSwgKGxlbmd0aCArIHhtcF9oZWFkZXJfc2l6ZSkpOwoJCQl9CgoJCQlmcmVlKHByb2ZpbGUpOwoKCQkJcmV0dXJuIFRSVUU7CQoJCX0KCX0KCglyZXR1cm4gRkFMU0U7Cn0KCi8qKgoJV3JpdGUgSlBFRyBzcGVjaWFsIG1hcmtlcnMKKi8Kc3RhdGljIEJPT0wgCndyaXRlX21hcmtlcnMoal9jb21wcmVzc19wdHIgY2luZm8sIEZJQklUTUFQICpkaWIpIHsKCgkvLyB3cml0ZSB1c2VyIGNvbW1lbnQgYXMgYSBKUEVHX0NPTSBtYXJrZXIKCWpwZWdfd3JpdGVfY29tbWVudChjaW5mbywgZGliKTsKCgkvLyB3cml0ZSBJQ0MgcHJvZmlsZQoJanBlZ193cml0ZV9pY2NfcHJvZmlsZShjaW5mbywgZGliKTsKCgkvLyB3cml0ZSBJUFRDIHByb2ZpbGUKCWpwZWdfd3JpdGVfaXB0Y19wcm9maWxlKGNpbmZvLCBkaWIpOwoKCS8vIHdyaXRlIEFkb2JlIFhNUCBwcm9maWxlCglqcGVnX3dyaXRlX3htcF9wcm9maWxlKGNpbmZvLCBkaWIpOwoKCXJldHVybiBUUlVFOwp9CgovLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KLy8gICBLZWVwIG9yaWdpbmFsIHNpemUgaW5mbyB3aGVuIHVzaW5nIHNjYWxlIG9wdGlvbiBvbiBsb2FkaW5nCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQpzdGF0aWMgdm9pZCAKc3RvcmVfc2l6ZV9pbmZvKEZJQklUTUFQICpkaWIsIEpESU1FTlNJT04gd2lkdGgsIEpESU1FTlNJT04gaGVpZ2h0KSB7CgljaGFyIGJ1ZmZlclsyNTZdOwoJLy8gY3JlYXRlIGEgdGFnCglGSVRBRyAqdGFnID0gRnJlZUltYWdlX0NyZWF0ZVRhZygpOwoJaWYodGFnKSB7CgkJc2l6ZV90IGxlbmd0aCA9IDA7CgkJLy8gc2V0IHRoZSBvcmlnaW5hbCB3aWR0aAoJCXNwcmludGYoYnVmZmVyLCAiJWQiLCAoaW50KXdpZHRoKTsKCQlsZW5ndGggPSBzdHJsZW4oYnVmZmVyKSArIDE7CS8vIGluY2x1ZGUgdGhlIE5VTEwvMCB2YWx1ZQoJCUZyZWVJbWFnZV9TZXRUYWdLZXkodGFnLCAiT3JpZ2luYWxKUEVHV2lkdGgiKTsKCQlGcmVlSW1hZ2VfU2V0VGFnTGVuZ3RoKHRhZywgKERXT1JEKWxlbmd0aCk7CgkJRnJlZUltYWdlX1NldFRhZ0NvdW50KHRhZywgKERXT1JEKWxlbmd0aCk7CgkJRnJlZUltYWdlX1NldFRhZ1R5cGUodGFnLCBGSURUX0FTQ0lJKTsKCQlGcmVlSW1hZ2VfU2V0VGFnVmFsdWUodGFnLCBidWZmZXIpOwoJCUZyZWVJbWFnZV9TZXRNZXRhZGF0YShGSU1EX0NPTU1FTlRTLCBkaWIsIEZyZWVJbWFnZV9HZXRUYWdLZXkodGFnKSwgdGFnKTsKCQkvLyBzZXQgdGhlIG9yaWdpbmFsIGhlaWdodAoJCXNwcmludGYoYnVmZmVyLCAiJWQiLCAoaW50KWhlaWdodCk7CgkJbGVuZ3RoID0gc3RybGVuKGJ1ZmZlcikgKyAxOwkvLyBpbmNsdWRlIHRoZSBOVUxMLzAgdmFsdWUKCQlGcmVlSW1hZ2VfU2V0VGFnS2V5KHRhZywgIk9yaWdpbmFsSlBFR0hlaWdodCIpOwoJCUZyZWVJbWFnZV9TZXRUYWdMZW5ndGgodGFnLCAoRFdPUkQpbGVuZ3RoKTsKCQlGcmVlSW1hZ2VfU2V0VGFnQ291bnQodGFnLCAoRFdPUkQpbGVuZ3RoKTsKCQlGcmVlSW1hZ2VfU2V0VGFnVHlwZSh0YWcsIEZJRFRfQVNDSUkpOwoJCUZyZWVJbWFnZV9TZXRUYWdWYWx1ZSh0YWcsIGJ1ZmZlcik7CgkJRnJlZUltYWdlX1NldE1ldGFkYXRhKEZJTURfQ09NTUVOVFMsIGRpYiwgRnJlZUltYWdlX0dldFRhZ0tleSh0YWcpLCB0YWcpOwoJCS8vIGRlc3Ryb3kgdGhlIHRhZwoJCUZyZWVJbWFnZV9EZWxldGVUYWcodGFnKTsKCX0KfQoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCi8vICAgUm90YXRlIGEgZGliIGFjY29yZGluZyB0byBFeGlmIGluZm8KLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCgpzdGF0aWMgdm9pZCAKcm90YXRlX2V4aWYoRklCSVRNQVAgKipkaWIpIHsKCS8vIGNoZWNrIGZvciBFeGlmIHJvdGF0aW9uCglpZihGcmVlSW1hZ2VfR2V0TWV0YWRhdGFDb3VudChGSU1EX0VYSUZfTUFJTiwgKmRpYikpIHsKCQlGSUJJVE1BUCAqcm90YXRlZCA9IE5VTEw7CgkJLy8gcHJvY2VzcyBFeGlmIHJvdGF0aW9uCgkJRklUQUcgKnRhZyA9IE5VTEw7CgkJRnJlZUltYWdlX0dldE1ldGFkYXRhKEZJTURfRVhJRl9NQUlOLCAqZGliLCAiT3JpZW50YXRpb24iLCAmdGFnKTsKCQlpZih0YWcgIT0gTlVMTCkgewoJCQlpZihGcmVlSW1hZ2VfR2V0VGFnSUQodGFnKSA9PSBUQUdfT1JJRU5UQVRJT04pIHsKCQkJCXVuc2lnbmVkIHNob3J0IG9yaWVudGF0aW9uID0gKigodW5zaWduZWQgc2hvcnQgKilGcmVlSW1hZ2VfR2V0VGFnVmFsdWUodGFnKSk7CgkJCQlzd2l0Y2ggKG9yaWVudGF0aW9uKSB7CgkJCQkJY2FzZSAxOgkJLy8gInRvcCwgbGVmdCBzaWRlIiA9PiAwsAoJCQkJCQlicmVhazsKCQkJCQljYXNlIDI6CQkvLyAidG9wLCByaWdodCBzaWRlIiA9PiBmbGlwIGxlZnQtcmlnaHQKCQkJCQkJRnJlZUltYWdlX0ZsaXBIb3Jpem9udGFsKCpkaWIpOwoJCQkJCQlicmVhazsKCQkJCQljYXNlIDM6CQkvLyAiYm90dG9tLCByaWdodCBzaWRlIjsgPT4gLTE4MLAKCQkJCQkJcm90YXRlZCA9IEZyZWVJbWFnZV9Sb3RhdGUoKmRpYiwgMTgwKTsKCQkJCQkJRnJlZUltYWdlX1VubG9hZCgqZGliKTsKCQkJCQkJKmRpYiA9IHJvdGF0ZWQ7CgkJCQkJCWJyZWFrOwoJCQkJCWNhc2UgNDoJCS8vICJib3R0b20sIGxlZnQgc2lkZSIgPT4gZmxpcCB1cC1kb3duCgkJCQkJCUZyZWVJbWFnZV9GbGlwVmVydGljYWwoKmRpYik7CgkJCQkJCWJyZWFrOwoJCQkJCWNhc2UgNToJCS8vICJsZWZ0IHNpZGUsIHRvcCIgPT4gKzkwsCArIGZsaXAgdXAtZG93bgoJCQkJCQlyb3RhdGVkID0gRnJlZUltYWdlX1JvdGF0ZSgqZGliLCA5MCk7CgkJCQkJCUZyZWVJbWFnZV9VbmxvYWQoKmRpYik7CgkJCQkJCSpkaWIgPSByb3RhdGVkOwoJCQkJCQlGcmVlSW1hZ2VfRmxpcFZlcnRpY2FsKCpkaWIpOwoJCQkJCQlicmVhazsKCQkJCQljYXNlIDY6CQkvLyAicmlnaHQgc2lkZSwgdG9wIiA9PiAtOTCwCgkJCQkJCXJvdGF0ZWQgPSBGcmVlSW1hZ2VfUm90YXRlKCpkaWIsIC05MCk7CgkJCQkJCUZyZWVJbWFnZV9VbmxvYWQoKmRpYik7CgkJCQkJCSpkaWIgPSByb3RhdGVkOwoJCQkJCQlicmVhazsKCQkJCQljYXNlIDc6CQkvLyAicmlnaHQgc2lkZSwgYm90dG9tIiA9PiAtOTCwICsgZmxpcCB1cC1kb3duCgkJCQkJCXJvdGF0ZWQgPSBGcmVlSW1hZ2VfUm90YXRlKCpkaWIsIC05MCk7CgkJCQkJCUZyZWVJbWFnZV9VbmxvYWQoKmRpYik7CgkJCQkJCSpkaWIgPSByb3RhdGVkOwoJCQkJCQlGcmVlSW1hZ2VfRmxpcFZlcnRpY2FsKCpkaWIpOwoJCQkJCQlicmVhazsKCQkJCQljYXNlIDg6CQkvLyAibGVmdCBzaWRlLCBib3R0b20iID0+ICs5MLAKCQkJCQkJcm90YXRlZCA9IEZyZWVJbWFnZV9Sb3RhdGUoKmRpYiwgOTApOwoJCQkJCQlGcmVlSW1hZ2VfVW5sb2FkKCpkaWIpOwoJCQkJCQkqZGliID0gcm90YXRlZDsKCQkJCQkJYnJlYWs7CgkJCQkJZGVmYXVsdDoKCQkJCQkJYnJlYWs7CgkJCQl9CgkJCX0KCQl9Cgl9Cn0KCgovLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09Ci8vIFBsdWdpbiBJbXBsZW1lbnRhdGlvbgovLyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CgpzdGF0aWMgY29uc3QgY2hhciAqIERMTF9DQUxMQ09OVgpGb3JtYXQoKSB7CglyZXR1cm4gIkpQRUciOwp9CgpzdGF0aWMgY29uc3QgY2hhciAqIERMTF9DQUxMQ09OVgpEZXNjcmlwdGlvbigpIHsKCXJldHVybiAiSlBFRyAtIEpGSUYgQ29tcGxpYW50IjsKfQoKc3RhdGljIGNvbnN0IGNoYXIgKiBETExfQ0FMTENPTlYKRXh0ZW5zaW9uKCkgewoJcmV0dXJuICJqcGcsamlmLGpwZWcsanBlIjsKfQoKc3RhdGljIGNvbnN0IGNoYXIgKiBETExfQ0FMTENPTlYKUmVnRXhwcigpIHsKCXJldHVybiAiXlwzNzdcMzMwXDM3NyI7Cn0KCnN0YXRpYyBjb25zdCBjaGFyICogRExMX0NBTExDT05WCk1pbWVUeXBlKCkgewoJcmV0dXJuICJpbWFnZS9qcGVnIjsKfQoKc3RhdGljIEJPT0wgRExMX0NBTExDT05WClZhbGlkYXRlKEZyZWVJbWFnZUlPICppbywgZmlfaGFuZGxlIGhhbmRsZSkgewoJQllURSBqcGVnX3NpZ25hdHVyZVtdID0geyAweEZGLCAweEQ4IH07CglCWVRFIHNpZ25hdHVyZVsyXSA9IHsgMCwgMCB9OwoKCWlvLT5yZWFkX3Byb2Moc2lnbmF0dXJlLCAxLCBzaXplb2YoanBlZ19zaWduYXR1cmUpLCBoYW5kbGUpOwoKCXJldHVybiAobWVtY21wKGpwZWdfc2lnbmF0dXJlLCBzaWduYXR1cmUsIHNpemVvZihqcGVnX3NpZ25hdHVyZSkpID09IDApOwp9CgpzdGF0aWMgQk9PTCBETExfQ0FMTENPTlYKU3VwcG9ydHNFeHBvcnREZXB0aChpbnQgZGVwdGgpIHsKCXJldHVybiAoCgkJCShkZXB0aCA9PSA4KSB8fAoJCQkoZGVwdGggPT0gMjQpCgkJKTsKfQoKc3RhdGljIEJPT0wgRExMX0NBTExDT05WIApTdXBwb3J0c0V4cG9ydFR5cGUoRlJFRV9JTUFHRV9UWVBFIHR5cGUpIHsKCXJldHVybiAodHlwZSA9PSBGSVRfQklUTUFQKSA/IFRSVUUgOiBGQUxTRTsKfQoKc3RhdGljIEJPT0wgRExMX0NBTExDT05WClN1cHBvcnRzSUNDUHJvZmlsZXMoKSB7CglyZXR1cm4gVFJVRTsKfQoKLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKCi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCnN0YXRpYyBGSUJJVE1BUCAqIERMTF9DQUxMQ09OVgpMb2FkKEZyZWVJbWFnZUlPICppbywgZmlfaGFuZGxlIGhhbmRsZSwgaW50IHBhZ2UsIGludCBmbGFncywgdm9pZCAqZGF0YSkgewoJaWYgKGhhbmRsZSkgewoJCUZJQklUTUFQICpkaWIgPSBOVUxMOwoKCQl0cnkgewoJCQkvLyBzZXQgdXAgdGhlIGpwZWdsaWIgc3RydWN0dXJlcwoKCQkJc3RydWN0IGpwZWdfZGVjb21wcmVzc19zdHJ1Y3QgY2luZm87CgkJCXN0cnVjdCBqcGVnX2Vycm9yX21nciBqZXJyOwoKCQkJLy8gc3RlcCAxOiBhbGxvY2F0ZSBhbmQgaW5pdGlhbGl6ZSBKUEVHIGRlY29tcHJlc3Npb24gb2JqZWN0CgoJCQljaW5mby5lcnIgPSBqcGVnX3N0ZF9lcnJvcigmamVycik7CgoJCQlqZXJyLmVycm9yX2V4aXQgICAgID0ganBlZ19lcnJvcl9leGl0OwoJCQlqZXJyLm91dHB1dF9tZXNzYWdlID0ganBlZ19vdXRwdXRfbWVzc2FnZTsKCgkJCWpwZWdfY3JlYXRlX2RlY29tcHJlc3MoJmNpbmZvKTsKCgkJCS8vIHN0ZXAgMmE6IHNwZWNpZnkgZGF0YSBzb3VyY2UgKGVnLCBhIGhhbmRsZSkKCgkJCWpwZWdfZnJlZWltYWdlX3NyYygmY2luZm8sIGhhbmRsZSwgaW8pOwoKCQkJLy8gc3RlcCAyYjogc2F2ZSBzcGVjaWFsIG1hcmtlcnMgZm9yIGxhdGVyIHJlYWRpbmcKCQkJCgkJCWpwZWdfc2F2ZV9tYXJrZXJzKCZjaW5mbywgSlBFR19DT00sIDB4RkZGRik7CgkJCWZvcihpbnQgbSA9IDA7IG0gPCAxNjsgbSsrKSB7CgkJCQlqcGVnX3NhdmVfbWFya2VycygmY2luZm8sIEpQRUdfQVBQMCArIG0sIDB4RkZGRik7CgkJCX0KCgkJCS8vIHN0ZXAgMzogcmVhZCBoYW5kbGUgcGFyYW1ldGVycyB3aXRoIGpwZWdfcmVhZF9oZWFkZXIoKQoKCQkJanBlZ19yZWFkX2hlYWRlcigmY2luZm8sIFRSVUUpOwoKCQkJLy8gc3RlcCA0OiBzZXQgcGFyYW1ldGVycyBmb3IgZGVjb21wcmVzc2lvbgoKCQkJdW5zaWduZWQgaW50IHNjYWxlX2Rlbm9tID0gMTsJCS8vIGZyYWN0aW9uIGJ5IHdoaWNoIHRvIHNjYWxlIGltYWdlCgkJCWludAlyZXF1ZXN0ZWRfc2l6ZSA9IGZsYWdzID4+IDE2OwkvLyByZXF1ZXN0ZWQgdXNlciBzaXplIGluIHBpeGVscwoJCQlpZihyZXF1ZXN0ZWRfc2l6ZSA+IDApIHsKCQkJCS8vIHRoZSBKUEVHIGNvZGVjIGNhbiBwZXJmb3JtIHgyLCB4NCBvciB4OCBzY2FsaW5nIG9uIGxvYWRpbmcKCQkJCS8vIHRyeSB0byBmaW5kIHRoZSBtb3JlIGFwcHJvcHJpYXRlIHNjYWxpbmcgYWNjb3JkaW5nIHRvIHVzZXIncyBuZWVkCgkJCQlkb3VibGUgc2NhbGUgPSBNQVgoKGRvdWJsZSljaW5mby5pbWFnZV93aWR0aCwgKGRvdWJsZSljaW5mby5pbWFnZV9oZWlnaHQpIC8gKGRvdWJsZSlyZXF1ZXN0ZWRfc2l6ZTsKCQkJCWlmKHNjYWxlID49IDgpIHsKCQkJCQlzY2FsZV9kZW5vbSA9IDg7CgkJCQl9IGVsc2UgaWYoc2NhbGUgPj0gNCkgewoJCQkJCXNjYWxlX2Rlbm9tID0gNDsKCQkJCX0gZWxzZSBpZihzY2FsZSA+PSAyKSB7CgkJCQkJc2NhbGVfZGVub20gPSAyOwoJCQkJfQoJCQl9CgkJCWNpbmZvLnNjYWxlX251bSA9IDE7CgkJCWNpbmZvLnNjYWxlX2Rlbm9tID0gc2NhbGVfZGVub207CgoJCQlpZiAoKGZsYWdzICYgSlBFR19BQ0NVUkFURSkgIT0gSlBFR19BQ0NVUkFURSkgewoJCQkJY2luZm8uZGN0X21ldGhvZCAgICAgICAgICA9IEpEQ1RfSUZBU1Q7CgkJCQljaW5mby5kb19mYW5jeV91cHNhbXBsaW5nID0gRkFMU0U7CgkJCX0KCgkJCS8vIHN0ZXAgNWE6IHN0YXJ0IGRlY29tcHJlc3NvciBhbmQgY2FsY3VsYXRlIG91dHB1dCB3aWR0aCBhbmQgaGVpZ2h0CgoJCQlqcGVnX3N0YXJ0X2RlY29tcHJlc3MoJmNpbmZvKTsKCgkJCS8vIHN0ZXAgNWI6IGFsbG9jYXRlIGRpYiBhbmQgaW5pdCBoZWFkZXIKCgkJCWlmKChjaW5mby5udW1fY29tcG9uZW50cyA9PSA0KSAmJiAoY2luZm8ub3V0X2NvbG9yX3NwYWNlID09IEpDU19DTVlLKSkgewoJCQkJLy8gQ01ZSyBpbWFnZQoJCQkJaWYoKGZsYWdzICYgSlBFR19DTVlLKSA9PSBKUEVHX0NNWUspIHsKCQkJCQkvLyBsb2FkIGFzIENNWUsKCQkJCQlkaWIgPSBGcmVlSW1hZ2VfQWxsb2NhdGUoY2luZm8ub3V0cHV0X3dpZHRoLCBjaW5mby5vdXRwdXRfaGVpZ2h0LCAzMiwgRklfUkdCQV9SRURfTUFTSywgRklfUkdCQV9HUkVFTl9NQVNLLCBGSV9SR0JBX0JMVUVfTUFTSyk7CgkJCQkJaWYoIWRpYikgcmV0dXJuIE5VTEw7CgkJCQkJRnJlZUltYWdlX0dldElDQ1Byb2ZpbGUoZGliKS0+ZmxhZ3MgfD0gRklJQ0NfQ09MT1JfSVNfQ01ZSzsKCQkJCX0gZWxzZSB7CgkJCQkJLy8gbG9hZCBhcyBDTVlLIGFuZCBjb252ZXJ0IHRvIFJHQgoJCQkJCWRpYiA9IEZyZWVJbWFnZV9BbGxvY2F0ZShjaW5mby5vdXRwdXRfd2lkdGgsIGNpbmZvLm91dHB1dF9oZWlnaHQsIDI0LCBGSV9SR0JBX1JFRF9NQVNLLCBGSV9SR0JBX0dSRUVOX01BU0ssIEZJX1JHQkFfQkxVRV9NQVNLKTsKCQkJCQlpZighZGliKSByZXR1cm4gTlVMTDsKCQkJCX0KCQkJfSBlbHNlIHsKCQkJCS8vIFJHQiBvciBncmV5c2NhbGUgaW1hZ2UKCQkJCWRpYiA9IEZyZWVJbWFnZV9BbGxvY2F0ZShjaW5mby5vdXRwdXRfd2lkdGgsIGNpbmZvLm91dHB1dF9oZWlnaHQsIDggKiBjaW5mby5udW1fY29tcG9uZW50cywgRklfUkdCQV9SRURfTUFTSywgRklfUkdCQV9HUkVFTl9NQVNLLCBGSV9SR0JBX0JMVUVfTUFTSyk7CgkJCQlpZighZGliKSByZXR1cm4gTlVMTDsKCgkJCQlpZiAoY2luZm8ubnVtX2NvbXBvbmVudHMgPT0gMSkgewoJCQkJCS8vIGJ1aWxkIGEgZ3JleXNjYWxlIHBhbGV0dGUKCQkJCQlSR0JRVUFEICpjb2xvcnMgPSBGcmVlSW1hZ2VfR2V0UGFsZXR0ZShkaWIpOwoKCQkJCQlmb3IgKGludCBpID0gMDsgaSA8IDI1NjsgaSsrKSB7CgkJCQkJCWNvbG9yc1tpXS5yZ2JSZWQgICA9IChCWVRFKWk7CgkJCQkJCWNvbG9yc1tpXS5yZ2JHcmVlbiA9IChCWVRFKWk7CgkJCQkJCWNvbG9yc1tpXS5yZ2JCbHVlICA9IChCWVRFKWk7CgkJCQkJfQoJCQkJfQoJCQl9CgkJCWlmKHNjYWxlX2Rlbm9tICE9IDEpIHsKCQkJCS8vIHN0b3JlIG9yaWdpbmFsIHNpemUgaW5mbyBpZiBhIHNjYWxpbmcgd2FzIHJlcXVlc3RlZAoJCQkJc3RvcmVfc2l6ZV9pbmZvKGRpYiwgY2luZm8uaW1hZ2Vfd2lkdGgsIGNpbmZvLmltYWdlX2hlaWdodCk7CgkJCX0KCgkJCS8vIHN0ZXAgNWM6IGhhbmRsZSBtZXRyaWNlcwoKCQkJaWYgKGNpbmZvLmRlbnNpdHlfdW5pdCA9PSAxKSB7CgkJCQkvLyBkb3RzL2luY2gKCQkJCUZyZWVJbWFnZV9TZXREb3RzUGVyTWV0ZXJYKGRpYiwgKHVuc2lnbmVkKSAoKChmbG9hdCljaW5mby5YX2RlbnNpdHkpIC8gMC4wMjU0MDAwICsgMC41KSk7CgkJCQlGcmVlSW1hZ2VfU2V0RG90c1Blck1ldGVyWShkaWIsICh1bnNpZ25lZCkgKCgoZmxvYXQpY2luZm8uWV9kZW5zaXR5KSAvIDAuMDI1NDAwMCArIDAuNSkpOwoJCQl9IGVsc2UgaWYgKGNpbmZvLmRlbnNpdHlfdW5pdCA9PSAyKSB7CgkJCQkvLyBkb3RzL2NtCgkJCQlGcmVlSW1hZ2VfU2V0RG90c1Blck1ldGVyWChkaWIsICh1bnNpZ25lZCkgKGNpbmZvLlhfZGVuc2l0eSAqIDEwMCkpOwoJCQkJRnJlZUltYWdlX1NldERvdHNQZXJNZXRlclkoZGliLCAodW5zaWduZWQpIChjaW5mby5ZX2RlbnNpdHkgKiAxMDApKTsKCQkJfQoKCQkJLy8gc3RlcCA2YTogd2hpbGUgKHNjYW4gbGluZXMgcmVtYWluIHRvIGJlIHJlYWQpIGpwZWdfcmVhZF9zY2FubGluZXMoLi4uKTsKCgkJCWlmKChjaW5mby5vdXRfY29sb3Jfc3BhY2UgPT0gSkNTX0NNWUspICYmICgoZmxhZ3MgJiBKUEVHX0NNWUspICE9IEpQRUdfQ01ZSykpIHsKCQkJCS8vIGNvbnZlcnQgZnJvbSBDTVlLIHRvIFJHQgoKCQkJCUpTQU1QQVJSQVkgYnVmZmVyOwkJLy8gb3V0cHV0IHJvdyBidWZmZXIKCQkJCXVuc2lnbmVkIHJvd19zdHJpZGU7CS8vIHBoeXNpY2FsIHJvdyB3aWR0aCBpbiBvdXRwdXQgYnVmZmVyCgoJCQkJLy8gSlNBTVBMRXMgcGVyIHJvdyBpbiBvdXRwdXQgYnVmZmVyCgkJCQlyb3dfc3RyaWRlID0gY2luZm8ub3V0cHV0X3dpZHRoICogY2luZm8ub3V0cHV0X2NvbXBvbmVudHM7CgkJCQkvLyBtYWtlIGEgb25lLXJvdy1oaWdoIHNhbXBsZSBhcnJheSB0aGF0IHdpbGwgZ28gYXdheSB3aGVuIGRvbmUgd2l0aCBpbWFnZQoJCQkJYnVmZmVyID0gKCpjaW5mby5tZW0tPmFsbG9jX3NhcnJheSkoKGpfY29tbW9uX3B0cikgJmNpbmZvLCBKUE9PTF9JTUFHRSwgcm93X3N0cmlkZSwgMSk7CgoJCQkJd2hpbGUgKGNpbmZvLm91dHB1dF9zY2FubGluZSA8IGNpbmZvLm91dHB1dF9oZWlnaHQpIHsKCQkJCQlKU0FNUFJPVyBzcmMgPSBidWZmZXJbMF07CgkJCQkJSlNBTVBST1cgZHN0ID0gRnJlZUltYWdlX0dldFNjYW5MaW5lKGRpYiwgY2luZm8ub3V0cHV0X2hlaWdodCAtIGNpbmZvLm91dHB1dF9zY2FubGluZSAtIDEpOwoKCQkJCQlqcGVnX3JlYWRfc2NhbmxpbmVzKCZjaW5mbywgYnVmZmVyLCAxKTsKCgkJCQkJZm9yKHVuc2lnbmVkIHggPSAwOyB4IDwgRnJlZUltYWdlX0dldFdpZHRoKGRpYik7IHgrKykgewoJCQkJCQlXT1JEIEsgPSAoV09SRClzcmNbM107CgkJCQkJCWRzdFtGSV9SR0JBX1JFRF0gICA9IChCWVRFKSgoSyAqIHNyY1swXSkgLyAyNTUpOwoJCQkJCQlkc3RbRklfUkdCQV9HUkVFTl0gPSAoQllURSkoKEsgKiBzcmNbMV0pIC8gMjU1KTsKCQkJCQkJZHN0W0ZJX1JHQkFfQkxVRV0gID0gKEJZVEUpKChLICogc3JjWzJdKSAvIDI1NSk7CgkJCQkJCXNyYyArPSA0OwoJCQkJCQlkc3QgKz0gMzsKCQkJCQl9CgkJCQl9CgkJCX0gZWxzZSB7CgkJCQkvLyBub3JtYWwgY2FzZSAoUkdCIG9yIGdyZXlzY2FsZSBpbWFnZSkKCgkJCQl3aGlsZSAoY2luZm8ub3V0cHV0X3NjYW5saW5lIDwgY2luZm8ub3V0cHV0X2hlaWdodCkgewoJCQkJCUpTQU1QUk9XIGRzdCA9IEZyZWVJbWFnZV9HZXRTY2FuTGluZShkaWIsIGNpbmZvLm91dHB1dF9oZWlnaHQgLSBjaW5mby5vdXRwdXRfc2NhbmxpbmUgLSAxKTsKCgkJCQkJanBlZ19yZWFkX3NjYW5saW5lcygmY2luZm8sICZkc3QsIDEpOwoJCQkJfQoKCQkJCS8vIHN0ZXAgNmI6IHN3YXAgcmVkIGFuZCBibHVlIGNvbXBvbmVudHMgKHNlZSBMaWJKUEVHL2ptb3JlY2ZnLmg6ICNkZWZpbmUgUkdCX1JFRCwgLi4uKQoJCQkJLy8gVGhlIGRlZmF1bHQgYmVoYXZpb3Igb2YgdGhlIEpQRUcgbGlicmFyeSBpcyBrZXB0ICJhcyBpcyIgYmVjYXVzZSBMaWJUSUZGIHVzZXMgCgkJCQkvLyBMaWJKUEVHICJhcyBpcyIuCgojaWYgRlJFRUlNQUdFX0NPTE9ST1JERVIgPT0gRlJFRUlNQUdFX0NPTE9ST1JERVJfQkdSCgkJCQlpZihjaW5mby5udW1fY29tcG9uZW50cyA9PSAzKSB7CgkJCQkJZm9yKHVuc2lnbmVkIHkgPSAwOyB5IDwgRnJlZUltYWdlX0dldEhlaWdodChkaWIpOyB5KyspIHsKCQkJCQkJQllURSAqdGFyZ2V0ID0gRnJlZUltYWdlX0dldFNjYW5MaW5lKGRpYiwgeSk7CgkJCQkJCWZvcih1bnNpZ25lZCB4ID0gMDsgeCA8IEZyZWVJbWFnZV9HZXRXaWR0aChkaWIpOyB4KyspIHsKCQkJCQkJCUlOUExBQ0VTV0FQKHRhcmdldFswXSwgdGFyZ2V0WzJdKTsKCQkJCQkJCXRhcmdldCArPSAzOwoJCQkJCQl9CgkJCQkJfQoJCQkJfQojZW5kaWYKCQkJfQoKCQkJLy8gc3RlcCA3OiByZWFkIHNwZWNpYWwgbWFya2VycwoKCQkJcmVhZF9tYXJrZXJzKCZjaW5mbywgZGliKTsKCgkJCS8vIHN0ZXAgODogZmluaXNoIGRlY29tcHJlc3Npb24KCgkJCWpwZWdfZmluaXNoX2RlY29tcHJlc3MoJmNpbmZvKTsKCgkJCS8vIHN0ZXAgOTogcmVsZWFzZSBKUEVHIGRlY29tcHJlc3Npb24gb2JqZWN0CgoJCQlqcGVnX2Rlc3Ryb3lfZGVjb21wcmVzcygmY2luZm8pOwoKCQkJLy8gY2hlY2sgZm9yIGF1dG9tYXRpYyBFeGlmIHJvdGF0aW9uCgkJCWlmKChmbGFncyAmIEpQRUdfRVhJRlJPVEFURSkgPT0gSlBFR19FWElGUk9UQVRFKSB7CgkJCQlyb3RhdGVfZXhpZigmZGliKTsKCQkJfQoKCQkJLy8gZXZlcnl0aGluZyB3ZW50IHdlbGwuIHJldHVybiB0aGUgbG9hZGVkIGRpYgoKCQkJcmV0dXJuIChGSUJJVE1BUCAqKWRpYjsKCQl9IGNhdGNoICguLi4pIHsKCQkJaWYoTlVMTCAhPSBkaWIpIHsKCQkJCUZyZWVJbWFnZV9VbmxvYWQoZGliKTsKCQkJfQoJCX0KCX0KCglyZXR1cm4gTlVMTDsKfQoKc3RhdGljIEJPT0wgRExMX0NBTExDT05WClNhdmUoRnJlZUltYWdlSU8gKmlvLCBGSUJJVE1BUCAqZGliLCBmaV9oYW5kbGUgaGFuZGxlLCBpbnQgcGFnZSwgaW50IGZsYWdzLCB2b2lkICpkYXRhKSB7CglpZiAoKGRpYikgJiYgKGhhbmRsZSkpIHsKCQl0cnkgewoJCQkvLyBDaGVjayBkaWIgZm9ybWF0CgoJCQljb25zdCBjaGFyICpzRXJyb3IgPSAib25seSAyNC1iaXQgaGlnaGNvbG9yIG9yIDgtYml0IGdyZXlzY2FsZS9wYWxldHRlIGJpdG1hcHMgY2FuIGJlIHNhdmVkIGFzIEpQRUciOwoKCQkJRlJFRV9JTUFHRV9DT0xPUl9UWVBFIGNvbG9yX3R5cGUgPSBGcmVlSW1hZ2VfR2V0Q29sb3JUeXBlKGRpYik7CgkJCVdPUkQgYnBwID0gKFdPUkQpRnJlZUltYWdlX0dldEJQUChkaWIpOwoKCQkJaWYgKChicHAgIT0gMjQpICYmIChicHAgIT0gOCkpCgkJCQl0aHJvdyBzRXJyb3I7CgoJCQlpZihicHAgPT0gOCkgewoJCQkJLy8gYWxsb3cgZ3JleSwgcmV2ZXJzZSBncmV5IGFuZCBwYWxldHRlIAoJCQkJaWYgKChjb2xvcl90eXBlICE9IEZJQ19NSU5JU0JMQUNLKSAmJiAoY29sb3JfdHlwZSAhPSBGSUNfTUlOSVNXSElURSkgJiYgKGNvbG9yX3R5cGUgIT0gRklDX1BBTEVUVEUpKQoJCQkJCXRocm93IHNFcnJvcjsKCQkJfQoKCgkJCXN0cnVjdCBqcGVnX2NvbXByZXNzX3N0cnVjdCBjaW5mbzsKCQkJc3RydWN0IGpwZWdfZXJyb3JfbWdyIGplcnI7CgoJCQkvLyBTdGVwIDE6IGFsbG9jYXRlIGFuZCBpbml0aWFsaXplIEpQRUcgY29tcHJlc3Npb24gb2JqZWN0CgoJCQljaW5mby5lcnIgPSBqcGVnX3N0ZF9lcnJvcigmamVycik7CgoJCQlqZXJyLmVycm9yX2V4aXQgICAgID0ganBlZ19lcnJvcl9leGl0OwoJCQlqZXJyLm91dHB1dF9tZXNzYWdlID0ganBlZ19vdXRwdXRfbWVzc2FnZTsKCgkJCS8vIE5vdyB3ZSBjYW4gaW5pdGlhbGl6ZSB0aGUgSlBFRyBjb21wcmVzc2lvbiBvYmplY3QKCgkJCWpwZWdfY3JlYXRlX2NvbXByZXNzKCZjaW5mbyk7CgoJCQkvLyBTdGVwIDI6IHNwZWNpZnkgZGF0YSBkZXN0aW5hdGlvbiAoZWcsIGEgZmlsZSkKCgkJCWpwZWdfZnJlZWltYWdlX2RzdCgmY2luZm8sIGhhbmRsZSwgaW8pOwoKCQkJLy8gU3RlcCAzOiBzZXQgcGFyYW1ldGVycyBmb3IgY29tcHJlc3Npb24gCgoJCQljaW5mby5pbWFnZV93aWR0aCA9IEZyZWVJbWFnZV9HZXRXaWR0aChkaWIpOwoJCQljaW5mby5pbWFnZV9oZWlnaHQgPSBGcmVlSW1hZ2VfR2V0SGVpZ2h0KGRpYik7CgoJCQlzd2l0Y2goY29sb3JfdHlwZSkgewoJCQkJY2FzZSBGSUNfTUlOSVNCTEFDSyA6CgkJCQljYXNlIEZJQ19NSU5JU1dISVRFIDoKCQkJCQljaW5mby5pbl9jb2xvcl9zcGFjZSA9IEpDU19HUkFZU0NBTEU7CgkJCQkJY2luZm8uaW5wdXRfY29tcG9uZW50cyA9IDE7CgkJCQkJYnJlYWs7CgoJCQkJZGVmYXVsdCA6CgkJCQkJY2luZm8uaW5fY29sb3Jfc3BhY2UgPSBKQ1NfUkdCOwoJCQkJCWNpbmZvLmlucHV0X2NvbXBvbmVudHMgPSAzOwoJCQkJCWJyZWFrOwoJCQl9CgoJCQlqcGVnX3NldF9kZWZhdWx0cygmY2luZm8pOwoKCQkgICAgLy8gcHJvZ3Jlc3NpdmUtSlBFRyBzdXBwb3J0CgkJCWlmKChmbGFncyAmIEpQRUdfUFJPR1JFU1NJVkUpID09IEpQRUdfUFJPR1JFU1NJVkUpIHsKCQkJCWpwZWdfc2ltcGxlX3Byb2dyZXNzaW9uKCZjaW5mbyk7CgkJCX0KCgkJCS8vIFNldCBKRklGIGRlbnNpdHkgcGFyYW1ldGVycyBmcm9tIHRoZSBESUIgZGF0YQoKCQkJY2luZm8uWF9kZW5zaXR5ID0gKFVJTlQxNikgKDAuNSArIDAuMDI1NCAqIEZyZWVJbWFnZV9HZXREb3RzUGVyTWV0ZXJYKGRpYikpOwoJCQljaW5mby5ZX2RlbnNpdHkgPSAoVUlOVDE2KSAoMC41ICsgMC4wMjU0ICogRnJlZUltYWdlX0dldERvdHNQZXJNZXRlclkoZGliKSk7CgkJCWNpbmZvLmRlbnNpdHlfdW5pdCA9IDE7CS8vIGRvdHMgLyBpbmNoCgoJCQkvLyBzZXQgc3Vic2FtcGxpbmcgb3B0aW9ucyBpZiByZXF1aXJlZAoKCQkJaWYoY2luZm8uaW5fY29sb3Jfc3BhY2UgPT0gSkNTX1JHQikgewoJCQkJaWYoKGZsYWdzICYgSlBFR19TVUJTQU1QTElOR180MTEpID09IEpQRUdfU1VCU0FNUExJTkdfNDExKSB7IAoJCQkJCS8vIDQ6MToxICg0eDEgMXgxIDF4MSkgLSBDckggMjUlIC0gQ2JIIDI1JSAtIENyViAxMDAlIC0gQ2JWIDEwMCUKCQkJCQkvLyB0aGUgaG9yaXpvbnRhbCBjb2xvciByZXNvbHV0aW9uIGlzIHF1YXJ0ZXJlZAoJCQkJCWNpbmZvLmNvbXBfaW5mb1swXS5oX3NhbXBfZmFjdG9yID0gNDsJLy8gWSAKCQkJCQljaW5mby5jb21wX2luZm9bMF0udl9zYW1wX2ZhY3RvciA9IDE7IAoJCQkJCWNpbmZvLmNvbXBfaW5mb1sxXS5oX3NhbXBfZmFjdG9yID0gMTsJLy8gQ2IgCgkJCQkJY2luZm8uY29tcF9pbmZvWzFdLnZfc2FtcF9mYWN0b3IgPSAxOyAKCQkJCQljaW5mby5jb21wX2luZm9bMl0uaF9zYW1wX2ZhY3RvciA9IDE7CS8vIENyIAoJCQkJCWNpbmZvLmNvbXBfaW5mb1syXS52X3NhbXBfZmFjdG9yID0gMTsgCgkJCQl9IGVsc2UgaWYoKGZsYWdzICYgSlBFR19TVUJTQU1QTElOR180MjApID09IEpQRUdfU1VCU0FNUExJTkdfNDIwKSB7CgkJCQkJLy8gNDoyOjAgKDJ4MiAxeDEgMXgxKSAtIENySCA1MCUgLSBDYkggNTAlIC0gQ3JWIDUwJSAtIENiViA1MCUKCQkJCQkvLyB0aGUgY2hyb21pbmFuY2UgcmVzb2x1dGlvbiBpbiBib3RoIHRoZSBob3Jpem9udGFsIGFuZCB2ZXJ0aWNhbCBkaXJlY3Rpb25zIGlzIGN1dCBpbiBoYWxmCgkJCQkJY2luZm8uY29tcF9pbmZvWzBdLmhfc2FtcF9mYWN0b3IgPSAyOwkvLyBZCgkJCQkJY2luZm8uY29tcF9pbmZvWzBdLnZfc2FtcF9mYWN0b3IgPSAyOyAKCQkJCQljaW5mby5jb21wX2luZm9bMV0uaF9zYW1wX2ZhY3RvciA9IDE7CS8vIENiCgkJCQkJY2luZm8uY29tcF9pbmZvWzFdLnZfc2FtcF9mYWN0b3IgPSAxOyAKCQkJCQljaW5mby5jb21wX2luZm9bMl0uaF9zYW1wX2ZhY3RvciA9IDE7CS8vIENyCgkJCQkJY2luZm8uY29tcF9pbmZvWzJdLnZfc2FtcF9mYWN0b3IgPSAxOyAKCQkJCX0gZWxzZSBpZigoZmxhZ3MgJiBKUEVHX1NVQlNBTVBMSU5HXzQyMikgPT0gSlBFR19TVUJTQU1QTElOR180MjIpeyAvLzJ4MSAobG93KSAKCQkJCQkvLyA0OjI6MiAoMngxIDF4MSAxeDEpIC0gQ3JIIDUwJSAtIENiSCA1MCUgLSBDclYgMTAwJSAtIENiViAxMDAlCgkJCQkJLy8gaGFsZiBvZiB0aGUgaG9yaXpvbnRhbCByZXNvbHV0aW9uIGluIHRoZSBjaHJvbWluYW5jZSBpcyBkcm9wcGVkIChDYiAmIENyKSwgCgkJCQkJLy8gd2hpbGUgdGhlIGZ1bGwgcmVzb2x1dGlvbiBpcyByZXRhaW5lZCBpbiB0aGUgdmVydGljYWwgZGlyZWN0aW9uLCB3aXRoIHJlc3BlY3QgdG8gdGhlIGx1bWluYW5jZQoJCQkJCWNpbmZvLmNvbXBfaW5mb1swXS5oX3NhbXBfZmFjdG9yID0gMjsJLy8gWSAKCQkJCQljaW5mby5jb21wX2luZm9bMF0udl9zYW1wX2ZhY3RvciA9IDE7IAoJCQkJCWNpbmZvLmNvbXBfaW5mb1sxXS5oX3NhbXBfZmFjdG9yID0gMTsJLy8gQ2IgCgkJCQkJY2luZm8uY29tcF9pbmZvWzFdLnZfc2FtcF9mYWN0b3IgPSAxOyAKCQkJCQljaW5mby5jb21wX2luZm9bMl0uaF9zYW1wX2ZhY3RvciA9IDE7CS8vIENyIAoJCQkJCWNpbmZvLmNvbXBfaW5mb1syXS52X3NhbXBfZmFjdG9yID0gMTsgCgkJCQl9IAoJCQkJZWxzZSBpZigoZmxhZ3MgJiBKUEVHX1NVQlNBTVBMSU5HXzQ0NCkgPT0gSlBFR19TVUJTQU1QTElOR180NDQpeyAvLzF4MSAobm8gc3Vic2FtcGxpbmcpIAoJCQkJCS8vIDQ6NDo0ICgxeDEgMXgxIDF4MSkgLSBDckggMTAwJSAtIENiSCAxMDAlIC0gQ3JWIDEwMCUgLSBDYlYgMTAwJQoJCQkJCS8vIHRoZSByZXNvbHV0aW9uIG9mIGNocm9taW5hbmNlIGluZm9ybWF0aW9uIChDYiAmIENyKSBpcyBwcmVzZXJ2ZWQgCgkJCQkJLy8gYXQgdGhlIHNhbWUgcmF0ZSBhcyB0aGUgbHVtaW5hbmNlIChZKSBpbmZvcm1hdGlvbgoJCQkJCWNpbmZvLmNvbXBfaW5mb1swXS5oX3NhbXBfZmFjdG9yID0gMTsJLy8gWSAKCQkJCQljaW5mby5jb21wX2luZm9bMF0udl9zYW1wX2ZhY3RvciA9IDE7IAoJCQkJCWNpbmZvLmNvbXBfaW5mb1sxXS5oX3NhbXBfZmFjdG9yID0gMTsJLy8gQ2IgCgkJCQkJY2luZm8uY29tcF9pbmZvWzFdLnZfc2FtcF9mYWN0b3IgPSAxOyAKCQkJCQljaW5mby5jb21wX2luZm9bMl0uaF9zYW1wX2ZhY3RvciA9IDE7CS8vIENyIAoJCQkJCWNpbmZvLmNvbXBfaW5mb1syXS52X3NhbXBfZmFjdG9yID0gMTsgIAoJCQkJfSAKCQkJfQoKCQkJLy8gU3RlcCA0OiBzZXQgcXVhbGl0eQoJCQkvLyB0aGUgZmlyc3QgNyBiaXRzIGFyZSByZXNlcnZlZCBmb3IgbG93IGxldmVsIHF1YWxpdHkgc2V0dGluZ3MKCQkJLy8gdGhlIG90aGVyIGJpdHMgYXJlIGhpZ2ggbGV2ZWwgKGkuZS4gZW51bS1pc2gpCgoJCQlpbnQgcXVhbGl0eTsKCgkJCWlmICgoZmxhZ3MgJiBKUEVHX1FVQUxJVFlCQUQpID09IEpQRUdfUVVBTElUWUJBRCkgewoJCQkJcXVhbGl0eSA9IDEwOwoJCQl9IGVsc2UgaWYgKChmbGFncyAmIEpQRUdfUVVBTElUWUFWRVJBR0UpID09IEpQRUdfUVVBTElUWUFWRVJBR0UpIHsKCQkJCXF1YWxpdHkgPSAyNTsKCQkJfSBlbHNlIGlmICgoZmxhZ3MgJiBKUEVHX1FVQUxJVFlOT1JNQUwpID09IEpQRUdfUVVBTElUWU5PUk1BTCkgewoJCQkJcXVhbGl0eSA9IDUwOwoJCQl9IGVsc2UgaWYgKChmbGFncyAmIEpQRUdfUVVBTElUWUdPT0QpID09IEpQRUdfUVVBTElUWUdPT0QpIHsKCQkJCXF1YWxpdHkgPSA3NTsKCQkJfSBlbHNlIAlpZiAoKGZsYWdzICYgSlBFR19RVUFMSVRZU1VQRVJCKSA9PSBKUEVHX1FVQUxJVFlTVVBFUkIpIHsKCQkJCXF1YWxpdHkgPSAxMDA7CgkJCX0gZWxzZSB7CgkJCQlpZiAoKGZsYWdzICYgMHg3RikgPT0gMCkgewoJCQkJCXF1YWxpdHkgPSA3NTsKCQkJCX0gZWxzZSB7CgkJCQkJcXVhbGl0eSA9IGZsYWdzICYgMHg3RjsKCQkJCX0KCQkJfQoKCQkJanBlZ19zZXRfcXVhbGl0eSgmY2luZm8sIHF1YWxpdHksIFRSVUUpOyAvKiBsaW1pdCB0byBiYXNlbGluZS1KUEVHIHZhbHVlcyAqLwoKCQkJLy8gU3RlcCA1OiBTdGFydCBjb21wcmVzc29yIAoKCQkJanBlZ19zdGFydF9jb21wcmVzcygmY2luZm8sIFRSVUUpOwoKCQkJLy8gU3RlcCA2OiBXcml0ZSBzcGVjaWFsIG1hcmtlcnMKCgkJCXdyaXRlX21hcmtlcnMoJmNpbmZvLCBkaWIpOwoKCQkJLy8gU3RlcCA3OiB3aGlsZSAoc2NhbiBsaW5lcyByZW1haW4gdG8gYmUgd3JpdHRlbikgCgoJCQlpZihjb2xvcl90eXBlID09IEZJQ19SR0IpIHsKCQkJCS8vIDI0LWJpdCBSR0IgaW1hZ2UgOiBuZWVkIHRvIHN3YXAgcmVkIGFuZCBibHVlIGNoYW5uZWxzCgkJCQl1bnNpZ25lZCBwaXRjaCA9IEZyZWVJbWFnZV9HZXRQaXRjaChkaWIpOwoJCQkJQllURSAqdGFyZ2V0ID0gKEJZVEUqKW1hbGxvYyhwaXRjaCAqIHNpemVvZihCWVRFKSk7CgkJCQlpZiAodGFyZ2V0ID09IE5VTEwpIHsKCQkJCQl0aHJvdyBGSV9NU0dfRVJST1JfTUVNT1JZOwoJCQkJfQoKCQkJCXdoaWxlIChjaW5mby5uZXh0X3NjYW5saW5lIDwgY2luZm8uaW1hZ2VfaGVpZ2h0KSB7CgkJCQkJLy8gZ2V0IGEgY29weSBvZiB0aGUgc2NhbmxpbmUKCQkJCQltZW1jcHkodGFyZ2V0LCBGcmVlSW1hZ2VfR2V0U2NhbkxpbmUoZGliLCBGcmVlSW1hZ2VfR2V0SGVpZ2h0KGRpYikgLSBjaW5mby5uZXh0X3NjYW5saW5lIC0gMSksIHBpdGNoKTsKI2lmIEZSRUVJTUFHRV9DT0xPUk9SREVSID09IEZSRUVJTUFHRV9DT0xPUk9SREVSX0JHUgoJCQkJCS8vIHN3YXAgUiBhbmQgQiBjaGFubmVscwoJCQkJCUJZVEUgKnRhcmdldF9wID0gdGFyZ2V0OwoJCQkJCWZvcih1bnNpZ25lZCB4ID0gMDsgeCA8IGNpbmZvLmltYWdlX3dpZHRoOyB4KyspIHsKCQkJCQkJSU5QTEFDRVNXQVAodGFyZ2V0X3BbMF0sIHRhcmdldF9wWzJdKTsKCQkJCQkJdGFyZ2V0X3AgKz0gMzsKCQkJCQl9CiNlbmRpZgoJCQkJCS8vIHdyaXRlIHRoZSBzY2FubGluZQoJCQkJCWpwZWdfd3JpdGVfc2NhbmxpbmVzKCZjaW5mbywgJnRhcmdldCwgMSk7CgkJCQl9CgkJCQlmcmVlKHRhcmdldCk7CgkJCX0KCQkJZWxzZSBpZihjb2xvcl90eXBlID09IEZJQ19NSU5JU0JMQUNLKSB7CgkJCQkvLyA4LWJpdCBzdGFuZGFyZCBncmV5c2NhbGUgaW1hZ2VzCgkJCQl3aGlsZSAoY2luZm8ubmV4dF9zY2FubGluZSA8IGNpbmZvLmltYWdlX2hlaWdodCkgewoJCQkJCUpTQU1QUk9XIGIgPSBGcmVlSW1hZ2VfR2V0U2NhbkxpbmUoZGliLCBGcmVlSW1hZ2VfR2V0SGVpZ2h0KGRpYikgLSBjaW5mby5uZXh0X3NjYW5saW5lIC0gMSk7CgoJCQkJCWpwZWdfd3JpdGVfc2NhbmxpbmVzKCZjaW5mbywgJmIsIDEpOwoJCQkJfQoJCQl9CgkJCWVsc2UgaWYoY29sb3JfdHlwZSA9PSBGSUNfUEFMRVRURSkgewoJCQkJLy8gOC1iaXQgcGFsZXR0aXplZCBpbWFnZXMgYXJlIGNvbnZlcnRlZCB0byAyNC1iaXQgaW1hZ2VzCgkJCQlSR0JRVUFEICpwYWxldHRlID0gRnJlZUltYWdlX0dldFBhbGV0dGUoZGliKTsKCQkJCUJZVEUgKnRhcmdldCA9IChCWVRFKiltYWxsb2MoY2luZm8uaW1hZ2Vfd2lkdGggKiAzKTsKCQkJCWlmICh0YXJnZXQgPT0gTlVMTCkgewoJCQkJCXRocm93IEZJX01TR19FUlJPUl9NRU1PUlk7CgkJCQl9CgoJCQkJd2hpbGUgKGNpbmZvLm5leHRfc2NhbmxpbmUgPCBjaW5mby5pbWFnZV9oZWlnaHQpIHsKCQkJCQlCWVRFICpzb3VyY2UgPSBGcmVlSW1hZ2VfR2V0U2NhbkxpbmUoZGliLCBGcmVlSW1hZ2VfR2V0SGVpZ2h0KGRpYikgLSBjaW5mby5uZXh0X3NjYW5saW5lIC0gMSk7CgkJCQkJRnJlZUltYWdlX0NvbnZlcnRMaW5lOFRvMjQodGFyZ2V0LCBzb3VyY2UsIGNpbmZvLmltYWdlX3dpZHRoLCBwYWxldHRlKTsKCiNpZiBGUkVFSU1BR0VfQ09MT1JPUkRFUiA9PSBGUkVFSU1BR0VfQ09MT1JPUkRFUl9CR1IKCQkJCQkvLyBzd2FwIFIgYW5kIEIgY2hhbm5lbHMKCQkJCQlCWVRFICp0YXJnZXRfcCA9IHRhcmdldDsKCQkJCQlmb3IodW5zaWduZWQgeCA9IDA7IHggPCBjaW5mby5pbWFnZV93aWR0aDsgeCsrKSB7CgkJCQkJCUlOUExBQ0VTV0FQKHRhcmdldF9wWzBdLCB0YXJnZXRfcFsyXSk7CgkJCQkJCXRhcmdldF9wICs9IDM7CgkJCQkJfQojZW5kaWYKCgoJCQkJCWpwZWdfd3JpdGVfc2NhbmxpbmVzKCZjaW5mbywgJnRhcmdldCwgMSk7CgkJCQl9CgoJCQkJZnJlZSh0YXJnZXQpOwoJCQl9CgkJCWVsc2UgaWYoY29sb3JfdHlwZSA9PSBGSUNfTUlOSVNXSElURSkgewoJCQkJLy8gcmV2ZXJzZSA4LWJpdCBncmV5c2NhbGUgaW1hZ2UsIHNvIHJldmVyc2UgZ3JleSB2YWx1ZSBvbiB0aGUgZmx5CgkJCQl1bnNpZ25lZCBpOwoJCQkJQllURSByZXZlcnNlWzI1Nl07CgkJCQlCWVRFICp0YXJnZXQgPSAoQllURSAqKW1hbGxvYyhjaW5mby5pbWFnZV93aWR0aCk7CgkJCQlpZiAodGFyZ2V0ID09IE5VTEwpIHsKCQkJCQl0aHJvdyBGSV9NU0dfRVJST1JfTUVNT1JZOwoJCQkJfQoKCQkJCWZvcihpID0gMDsgaSA8IDI1NjsgaSsrKSB7CgkJCQkJcmV2ZXJzZVtpXSA9IChCWVRFKSgyNTUgLSBpKTsKCQkJCX0KCgkJCQl3aGlsZShjaW5mby5uZXh0X3NjYW5saW5lIDwgY2luZm8uaW1hZ2VfaGVpZ2h0KSB7CgkJCQkJQllURSAqc291cmNlID0gRnJlZUltYWdlX0dldFNjYW5MaW5lKGRpYiwgRnJlZUltYWdlX0dldEhlaWdodChkaWIpIC0gY2luZm8ubmV4dF9zY2FubGluZSAtIDEpOwoJCQkJCWZvcihpID0gMDsgaSA8IGNpbmZvLmltYWdlX3dpZHRoOyBpKyspIHsKCQkJCQkJdGFyZ2V0W2ldID0gcmV2ZXJzZVsgc291cmNlW2ldIF07CgkJCQkJfQoJCQkJCWpwZWdfd3JpdGVfc2NhbmxpbmVzKCZjaW5mbywgJnRhcmdldCwgMSk7CgkJCQl9CgoJCQkJZnJlZSh0YXJnZXQpOwoJCQl9CgoJCQkvLyBTdGVwIDg6IEZpbmlzaCBjb21wcmVzc2lvbiAKCgkJCWpwZWdfZmluaXNoX2NvbXByZXNzKCZjaW5mbyk7CgoJCQkvLyBTdGVwIDk6IHJlbGVhc2UgSlBFRyBjb21wcmVzc2lvbiBvYmplY3QgCgoJCQlqcGVnX2Rlc3Ryb3lfY29tcHJlc3MoJmNpbmZvKTsKCgkJCXJldHVybiBUUlVFOwoKCQl9IGNhdGNoIChjb25zdCBjaGFyICp0ZXh0KSB7CgkJCUZyZWVJbWFnZV9PdXRwdXRNZXNzYWdlUHJvYyhzX2Zvcm1hdF9pZCwgdGV4dCk7CgkJCXJldHVybiBGQUxTRTsKCQl9IGNhdGNoIChGUkVFX0lNQUdFX0ZPUk1BVCkgewoJCQlyZXR1cm4gRkFMU0U7CgkJfQoJfQoKCXJldHVybiBGQUxTRTsKfQoKLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQovLyAgIEluaXQKLy8gPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQoKdm9pZCBETExfQ0FMTENPTlYKSW5pdEpQRUcoUGx1Z2luICpwbHVnaW4sIGludCBmb3JtYXRfaWQpIHsKCXNfZm9ybWF0X2lkID0gZm9ybWF0X2lkOwoKCXBsdWdpbi0+Zm9ybWF0X3Byb2MgPSBGb3JtYXQ7CglwbHVnaW4tPmRlc2NyaXB0aW9uX3Byb2MgPSBEZXNjcmlwdGlvbjsKCXBsdWdpbi0+ZXh0ZW5zaW9uX3Byb2MgPSBFeHRlbnNpb247CglwbHVnaW4tPnJlZ2V4cHJfcHJvYyA9IFJlZ0V4cHI7CglwbHVnaW4tPm9wZW5fcHJvYyA9IE5VTEw7CglwbHVnaW4tPmNsb3NlX3Byb2MgPSBOVUxMOwoJcGx1Z2luLT5wYWdlY291bnRfcHJvYyA9IE5VTEw7CglwbHVnaW4tPnBhZ2VjYXBhYmlsaXR5X3Byb2MgPSBOVUxMOwoJcGx1Z2luLT5sb2FkX3Byb2MgPSBMb2FkOwoJcGx1Z2luLT5zYXZlX3Byb2MgPSBTYXZlOwoJcGx1Z2luLT52YWxpZGF0ZV9wcm9jID0gVmFsaWRhdGU7CglwbHVnaW4tPm1pbWVfcHJvYyA9IE1pbWVUeXBlOwoJcGx1Z2luLT5zdXBwb3J0c19leHBvcnRfYnBwX3Byb2MgPSBTdXBwb3J0c0V4cG9ydERlcHRoOwoJcGx1Z2luLT5zdXBwb3J0c19leHBvcnRfdHlwZV9wcm9jID0gU3VwcG9ydHNFeHBvcnRUeXBlOwoJcGx1Z2luLT5zdXBwb3J0c19pY2NfcHJvZmlsZXNfcHJvYyA9IFN1cHBvcnRzSUNDUHJvZmlsZXM7Cn0K