LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCiAqIENvcHlyaWdodCCpIDIwMDcgUmVkIEhhdCBJbmMuCiAqIENvcHlyaWdodCCpIDIwMDctMjAxMiBJbnRlbCBDb3Jwb3JhdGlvbgogKiBDb3B5cmlnaHQgMjAwNiBUdW5nc3RlbiBHcmFwaGljcywgSW5jLiwgQmlzbWFyY2ssIE5ELiwgVVNBCiAqIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqCiAqIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhCiAqIGNvcHkgb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGUKICogIlNvZnR3YXJlIiksIHRvIGRlYWwgaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZwogKiB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsCiAqIGRpc3RyaWJ1dGUsIHN1YiBsaWNlbnNlLCBhbmQvb3Igc2VsbCBjb3BpZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8KICogcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGUgU29mdHdhcmUgaXMgZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvCiAqIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczoKICoKICogVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEICJBUyBJUyIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1MgT1IKICogSU1QTElFRCwgSU5DTFVESU5HIEJVVCBOT1QgTElNSVRFRCBUTyBUSEUgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFksCiAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFIEFORCBOT04tSU5GUklOR0VNRU5ULiBJTiBOTyBFVkVOVCBTSEFMTAogKiBUSEUgQ09QWVJJR0hUIEhPTERFUlMsIEFVVEhPUlMgQU5EL09SIElUUyBTVVBQTElFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sCiAqIERBTUFHRVMgT1IgT1RIRVIgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUgogKiBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSwgT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFCiAqIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTiBUSEUgU09GVFdBUkUuCiAqCiAqIFRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIChpbmNsdWRpbmcgdGhlCiAqIG5leHQgcGFyYWdyYXBoKSBzaGFsbCBiZSBpbmNsdWRlZCBpbiBhbGwgY29waWVzIG9yIHN1YnN0YW50aWFsIHBvcnRpb25zCiAqIG9mIHRoZSBTb2Z0d2FyZS4KICoKICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwovKgogKiBBdXRob3JzOiBUaG9tYXMgSGVsbHN0cvZtIDx0aG9tYXMtYXQtdHVuZ3N0ZW5ncmFwaGljcy1kb3QtY29tPgogKiAgICAgICAgICBLZWl0aCBXaGl0d2VsbCA8a2VpdGh3LWF0LXR1bmdzdGVuZ3JhcGhpY3MtZG90LWNvbT4KICoJICAgIEVyaWMgQW5ob2x0IDxlcmljQGFuaG9sdC5uZXQ+CiAqCSAgICBEYXZlIEFpcmxpZSA8YWlybGllZEBsaW51eC5pZT4KICovCgojaWZkZWYgSEFWRV9DT05GSUdfSAojaW5jbHVkZSAiY29uZmlnLmgiCiNlbmRpZgoKI2luY2x1ZGUgPHhmODZkcm0uaD4KI2luY2x1ZGUgPHhmODZhdG9taWMuaD4KI2luY2x1ZGUgPGZjbnRsLmg+CiNpbmNsdWRlIDxzdGRpby5oPgojaW5jbHVkZSA8c3RkbGliLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUgPHVuaXN0ZC5oPgojaW5jbHVkZSA8YXNzZXJ0Lmg+CiNpbmNsdWRlIDxwdGhyZWFkLmg+CiNpbmNsdWRlIDxzeXMvaW9jdGwuaD4KI2luY2x1ZGUgPHN5cy9zdGF0Lmg+CiNpbmNsdWRlIDxzeXMvdHlwZXMuaD4KI2luY2x1ZGUgPHN0ZGJvb2wuaD4KCiNpbmNsdWRlICJlcnJuby5oIgojaWZuZGVmIEVUSU1FCiNkZWZpbmUgRVRJTUUgRVRJTUVET1VUCiNlbmRpZgojaW5jbHVkZSAibGliZHJtLmgiCiNpbmNsdWRlICJsaWJkcm1fbGlzdHMuaCIKI2luY2x1ZGUgImludGVsX2J1Zm1nci5oIgojaW5jbHVkZSAiaW50ZWxfYnVmbWdyX3ByaXYuaCIKI2luY2x1ZGUgImludGVsX2NoaXBzZXQuaCIKI2luY2x1ZGUgImludGVsX2F1Yi5oIgojaW5jbHVkZSAic3RyaW5nLmgiCgojaW5jbHVkZSAiaTkxNV9kcm0uaCIKCiNpZmRlZiBIQVZFX1ZBTEdSSU5ECiNpbmNsdWRlIDx2YWxncmluZC5oPgojaW5jbHVkZSA8bWVtY2hlY2suaD4KI2RlZmluZSBWRyh4KSB4CiNlbHNlCiNkZWZpbmUgVkcoeCkKI2VuZGlmCgojZGVmaW5lIFZHX0NMRUFSKHMpIFZHKG1lbXNldCgmcywgMCwgc2l6ZW9mKHMpKSkKCiNkZWZpbmUgREJHKC4uLikgZG8gewkJCQkJXAoJaWYgKGJ1Zm1ncl9nZW0tPmJ1Zm1nci5kZWJ1ZykJCQlcCgkJZnByaW50ZihzdGRlcnIsIF9fVkFfQVJHU19fKTsJCVwKfSB3aGlsZSAoMCkKCiNkZWZpbmUgQVJSQVlfU0laRSh4KSAoc2l6ZW9mKHgpIC8gc2l6ZW9mKCh4KVswXSkpCgp0eXBlZGVmIHN0cnVjdCBfZHJtX2ludGVsX2JvX2dlbSBkcm1faW50ZWxfYm9fZ2VtOwoKc3RydWN0IGRybV9pbnRlbF9nZW1fYm9fYnVja2V0IHsKCWRybU1NTGlzdEhlYWQgaGVhZDsKCXVuc2lnbmVkIGxvbmcgc2l6ZTsKfTsKCnR5cGVkZWYgc3RydWN0IF9kcm1faW50ZWxfYnVmbWdyX2dlbSB7Cglkcm1faW50ZWxfYnVmbWdyIGJ1Zm1ncjsKCglhdG9taWNfdCByZWZjb3VudDsKCglpbnQgZmQ7CgoJaW50IG1heF9yZWxvY3M7CgoJcHRocmVhZF9tdXRleF90IGxvY2s7CgoJc3RydWN0IGRybV9pOTE1X2dlbV9leGVjX29iamVjdCAqZXhlY19vYmplY3RzOwoJc3RydWN0IGRybV9pOTE1X2dlbV9leGVjX29iamVjdDIgKmV4ZWMyX29iamVjdHM7Cglkcm1faW50ZWxfYm8gKipleGVjX2JvczsKCWludCBleGVjX3NpemU7CglpbnQgZXhlY19jb3VudDsKCgkvKiogQXJyYXkgb2YgbGlzdHMgb2YgY2FjaGVkIGdlbSBvYmplY3RzIG9mIHBvd2VyLW9mLXR3byBzaXplcyAqLwoJc3RydWN0IGRybV9pbnRlbF9nZW1fYm9fYnVja2V0IGNhY2hlX2J1Y2tldFsxNCAqIDRdOwoJaW50IG51bV9idWNrZXRzOwoJdGltZV90IHRpbWU7CgoJZHJtTU1MaXN0SGVhZCBtYW5hZ2VyczsKCglkcm1NTUxpc3RIZWFkIG5hbWVkOwoJZHJtTU1MaXN0SGVhZCB2bWFfY2FjaGU7CglpbnQgdm1hX2NvdW50LCB2bWFfb3Blbiwgdm1hX21heDsKCgl1aW50NjRfdCBndHRfc2l6ZTsKCWludCBhdmFpbGFibGVfZmVuY2VzOwoJaW50IHBjaV9kZXZpY2U7CglpbnQgZ2VuOwoJdW5zaWduZWQgaW50IGhhc19ic2QgOiAxOwoJdW5zaWduZWQgaW50IGhhc19ibHQgOiAxOwoJdW5zaWduZWQgaW50IGhhc19yZWxheGVkX2ZlbmNpbmcgOiAxOwoJdW5zaWduZWQgaW50IGhhc19sbGMgOiAxOwoJdW5zaWduZWQgaW50IGhhc193YWl0X3RpbWVvdXQgOiAxOwoJdW5zaWduZWQgaW50IGJvX3JldXNlIDogMTsKCXVuc2lnbmVkIGludCBub19leGVjIDogMTsKCXVuc2lnbmVkIGludCBoYXNfdmVib3ggOiAxOwoJYm9vbCBmZW5jZWRfcmVsb2NzOwoKCWNoYXIgKmF1Yl9maWxlbmFtZTsKCUZJTEUgKmF1Yl9maWxlOwoJdWludDMyX3QgYXViX29mZnNldDsKfSBkcm1faW50ZWxfYnVmbWdyX2dlbTsKCiNkZWZpbmUgRFJNX0lOVEVMX1JFTE9DX0ZFTkNFICgxPDwwKQoKdHlwZWRlZiBzdHJ1Y3QgX2RybV9pbnRlbF9yZWxvY190YXJnZXRfaW5mbyB7Cglkcm1faW50ZWxfYm8gKmJvOwoJaW50IGZsYWdzOwp9IGRybV9pbnRlbF9yZWxvY190YXJnZXQ7CgpzdHJ1Y3QgX2RybV9pbnRlbF9ib19nZW0gewoJZHJtX2ludGVsX2JvIGJvOwoKCWF0b21pY190IHJlZmNvdW50OwoJdWludDMyX3QgZ2VtX2hhbmRsZTsKCWNvbnN0IGNoYXIgKm5hbWU7CgoJLyoqCgkgKiBLZW5lbC1hc3NpZ25lZCBnbG9iYWwgbmFtZSBmb3IgdGhpcyBvYmplY3QKICAgICAgICAgKgogICAgICAgICAqIExpc3QgY29udGFpbnMgYm90aCBmbGluayBuYW1lZCBhbmQgcHJpbWUgZmQnZCBvYmplY3RzCgkgKi8KCXVuc2lnbmVkIGludCBnbG9iYWxfbmFtZTsKCWRybU1NTGlzdEhlYWQgbmFtZV9saXN0OwoKCS8qKgoJICogSW5kZXggb2YgdGhlIGJ1ZmZlciB3aXRoaW4gdGhlIHZhbGlkYXRpb24gbGlzdCB3aGlsZSBwcmVwYXJpbmcgYQoJICogYmF0Y2hidWZmZXIgZXhlY3V0aW9uLgoJICovCglpbnQgdmFsaWRhdGVfaW5kZXg7CgoJLyoqCgkgKiBDdXJyZW50IHRpbGluZyBtb2RlCgkgKi8KCXVpbnQzMl90IHRpbGluZ19tb2RlOwoJdWludDMyX3Qgc3dpenpsZV9tb2RlOwoJdW5zaWduZWQgbG9uZyBzdHJpZGU7CgoJdGltZV90IGZyZWVfdGltZTsKCgkvKiogQXJyYXkgcGFzc2VkIHRvIHRoZSBEUk0gY29udGFpbmluZyByZWxvY2F0aW9uIGluZm9ybWF0aW9uLiAqLwoJc3RydWN0IGRybV9pOTE1X2dlbV9yZWxvY2F0aW9uX2VudHJ5ICpyZWxvY3M7CgkvKioKCSAqIEFycmF5IG9mIGluZm8gc3RydWN0cyBjb3JyZXNwb25kaW5nIHRvIHJlbG9jc1tpXS50YXJnZXRfaGFuZGxlIGV0YwoJICovCglkcm1faW50ZWxfcmVsb2NfdGFyZ2V0ICpyZWxvY190YXJnZXRfaW5mbzsKCS8qKiBOdW1iZXIgb2YgZW50cmllcyBpbiByZWxvY3MgKi8KCWludCByZWxvY19jb3VudDsKCS8qKiBNYXBwZWQgYWRkcmVzcyBmb3IgdGhlIGJ1ZmZlciwgc2F2ZWQgYWNyb3NzIG1hcC91bm1hcCBjeWNsZXMgKi8KCXZvaWQgKm1lbV92aXJ0dWFsOwoJLyoqIEdUVCB2aXJ0dWFsIGFkZHJlc3MgZm9yIHRoZSBidWZmZXIsIHNhdmVkIGFjcm9zcyBtYXAvdW5tYXAgY3ljbGVzICovCgl2b2lkICpndHRfdmlydHVhbDsKCS8qKgoJICogVmlydHVhbCBhZGRyZXNzIG9mIHRoZSBidWZmZXIgYWxsb2NhdGVkIGJ5IHVzZXIsIHVzZWQgZm9yIHVzZXJwdHIKCSAqIG9iamVjdHMgb25seS4KCSAqLwoJdm9pZCAqdXNlcl92aXJ0dWFsOwoJaW50IG1hcF9jb3VudDsKCWRybU1NTGlzdEhlYWQgdm1hX2xpc3Q7CgoJLyoqIEJPIGNhY2hlIGxpc3QgKi8KCWRybU1NTGlzdEhlYWQgaGVhZDsKCgkvKioKCSAqIEJvb2xlYW4gb2Ygd2hldGhlciB0aGlzIEJPIGFuZCBpdHMgY2hpbGRyZW4gaGF2ZSBiZWVuIGluY2x1ZGVkIGluCgkgKiB0aGUgY3VycmVudCBkcm1faW50ZWxfYnVmbWdyX2NoZWNrX2FwZXJ0dXJlX3NwYWNlKCkgdG90YWwuCgkgKi8KCWJvb2wgaW5jbHVkZWRfaW5fY2hlY2tfYXBlcnR1cmU7CgoJLyoqCgkgKiBCb29sZWFuIG9mIHdoZXRoZXIgdGhpcyBidWZmZXIgaGFzIGJlZW4gdXNlZCBhcyBhIHJlbG9jYXRpb24KCSAqIHRhcmdldCBhbmQgaGFkIGl0cyBzaXplIGFjY291bnRlZCBmb3IsIGFuZCB0aHVzIGNhbid0IGhhdmUgYW55CgkgKiBmdXJ0aGVyIHJlbG9jYXRpb25zIGFkZGVkIHRvIGl0LgoJICovCglib29sIHVzZWRfYXNfcmVsb2NfdGFyZ2V0OwoKCS8qKgoJICogQm9vbGVhbiBvZiB3aGV0aGVyIHdlIGhhdmUgZW5jb3VudGVyZWQgYW4gZXJyb3Igd2hpbHN0IGJ1aWxkaW5nIHRoZSByZWxvY2F0aW9uIHRyZWUuCgkgKi8KCWJvb2wgaGFzX2Vycm9yOwoKCS8qKgoJICogQm9vbGVhbiBvZiB3aGV0aGVyIHRoaXMgYnVmZmVyIGNhbiBiZSByZS11c2VkCgkgKi8KCWJvb2wgcmV1c2FibGU7CgoJLyoqCgkgKiBCb29sZWFuIG9mIHdoZXRoZXIgdGhlIEdQVSBpcyBkZWZpbml0ZWx5IG5vdCBhY2Nlc3NpbmcgdGhlIGJ1ZmZlci4KCSAqCgkgKiBUaGlzIGlzIG9ubHkgdmFsaWQgd2hlbiByZXVzYWJsZSwgc2luY2Ugbm9uLXJldXNhYmxlCgkgKiBidWZmZXJzIGFyZSB0aG9zZSB0aGF0IGhhdmUgYmVlbiBzaGFyZWQgd3RoIG90aGVyCgkgKiBwcm9jZXNzZXMsIHNvIHdlIGRvbid0IGtub3cgdGhlaXIgc3RhdGUuCgkgKi8KCWJvb2wgaWRsZTsKCgkvKioKCSAqIEJvb2xlYW4gb2Ygd2hldGhlciB0aGlzIGJ1ZmZlciB3YXMgYWxsb2NhdGVkIHdpdGggdXNlcnB0cgoJICovCglib29sIGlzX3VzZXJwdHI7CgoJLyoqCgkgKiBTaXplIGluIGJ5dGVzIG9mIHRoaXMgYnVmZmVyIGFuZCBpdHMgcmVsb2NhdGlvbiBkZXNjZW5kZW50cy4KCSAqCgkgKiBVc2VkIHRvIGF2b2lkIGNvc3RseSB0cmVlIHdhbGtpbmcgaW4KCSAqIGRybV9pbnRlbF9idWZtZ3JfY2hlY2tfYXBlcnR1cmUgaW4gdGhlIGNvbW1vbiBjYXNlLgoJICovCglpbnQgcmVsb2NfdHJlZV9zaXplOwoKCS8qKgoJICogTnVtYmVyIG9mIHBvdGVudGlhbCBmZW5jZSByZWdpc3RlcnMgcmVxdWlyZWQgYnkgdGhpcyBidWZmZXIgYW5kIGl0cwoJICogcmVsb2NhdGlvbnMuCgkgKi8KCWludCByZWxvY190cmVlX2ZlbmNlczsKCgkvKiogRmxhZ3MgdGhhdCB3ZSBtYXkgbmVlZCB0byBkbyB0aGUgU1dfRklOU0lIIGlvY3RsIG9uIHVubWFwLiAqLwoJYm9vbCBtYXBwZWRfY3B1X3dyaXRlOwoKCXVpbnQzMl90IGF1Yl9vZmZzZXQ7CgoJZHJtX2ludGVsX2F1Yl9hbm5vdGF0aW9uICphdWJfYW5ub3RhdGlvbnM7Cgl1bnNpZ25lZCBhdWJfYW5ub3RhdGlvbl9jb3VudDsKfTsKCnN0YXRpYyB1bnNpZ25lZCBpbnQKZHJtX2ludGVsX2dlbV9lc3RpbWF0ZV9iYXRjaF9zcGFjZShkcm1faW50ZWxfYm8gKiogYm9fYXJyYXksIGludCBjb3VudCk7CgpzdGF0aWMgdW5zaWduZWQgaW50CmRybV9pbnRlbF9nZW1fY29tcHV0ZV9iYXRjaF9zcGFjZShkcm1faW50ZWxfYm8gKiogYm9fYXJyYXksIGludCBjb3VudCk7CgpzdGF0aWMgaW50CmRybV9pbnRlbF9nZW1fYm9fZ2V0X3RpbGluZyhkcm1faW50ZWxfYm8gKmJvLCB1aW50MzJfdCAqIHRpbGluZ19tb2RlLAoJCQkgICAgdWludDMyX3QgKiBzd2l6emxlX21vZGUpOwoKc3RhdGljIGludApkcm1faW50ZWxfZ2VtX2JvX3NldF90aWxpbmdfaW50ZXJuYWwoZHJtX2ludGVsX2JvICpibywKCQkJCSAgICAgdWludDMyX3QgdGlsaW5nX21vZGUsCgkJCQkgICAgIHVpbnQzMl90IHN0cmlkZSk7CgpzdGF0aWMgdm9pZCBkcm1faW50ZWxfZ2VtX2JvX3VucmVmZXJlbmNlX2xvY2tlZF90aW1lZChkcm1faW50ZWxfYm8gKmJvLAoJCQkJCQkgICAgICB0aW1lX3QgdGltZSk7CgpzdGF0aWMgdm9pZCBkcm1faW50ZWxfZ2VtX2JvX3VucmVmZXJlbmNlKGRybV9pbnRlbF9ibyAqYm8pOwoKc3RhdGljIHZvaWQgZHJtX2ludGVsX2dlbV9ib19mcmVlKGRybV9pbnRlbF9ibyAqYm8pOwoKc3RhdGljIHVuc2lnbmVkIGxvbmcKZHJtX2ludGVsX2dlbV9ib190aWxlX3NpemUoZHJtX2ludGVsX2J1Zm1ncl9nZW0gKmJ1Zm1ncl9nZW0sIHVuc2lnbmVkIGxvbmcgc2l6ZSwKCQkJICAgdWludDMyX3QgKnRpbGluZ19tb2RlKQp7Cgl1bnNpZ25lZCBsb25nIG1pbl9zaXplLCBtYXhfc2l6ZTsKCXVuc2lnbmVkIGxvbmcgaTsKCglpZiAoKnRpbGluZ19tb2RlID09IEk5MTVfVElMSU5HX05PTkUpCgkJcmV0dXJuIHNpemU7CgoJLyogOTY1KyBqdXN0IG5lZWQgbXVsdGlwbGVzIG9mIHBhZ2Ugc2l6ZSBmb3IgdGlsaW5nICovCglpZiAoYnVmbWdyX2dlbS0+Z2VuID49IDQpCgkJcmV0dXJuIFJPVU5EX1VQX1RPKHNpemUsIDQwOTYpOwoKCS8qIE9sZGVyIGNoaXBzIG5lZWQgcG93ZXJzIG9mIHR3bywgb2YgYXQgbGVhc3QgNTEyayBvciAxTSAqLwoJaWYgKGJ1Zm1ncl9nZW0tPmdlbiA9PSAzKSB7CgkJbWluX3NpemUgPSAxMDI0KjEwMjQ7CgkJbWF4X3NpemUgPSAxMjgqMTAyNCoxMDI0OwoJfSBlbHNlIHsKCQltaW5fc2l6ZSA9IDUxMioxMDI0OwoJCW1heF9zaXplID0gNjQqMTAyNCoxMDI0OwoJfQoKCWlmIChzaXplID4gbWF4X3NpemUpIHsKCQkqdGlsaW5nX21vZGUgPSBJOTE1X1RJTElOR19OT05FOwoJCXJldHVybiBzaXplOwoJfQoKCS8qIERvIHdlIG5lZWQgdG8gYWxsb2NhdGUgZXZlcnkgcGFnZSBmb3IgdGhlIGZlbmNlPyAqLwoJaWYgKGJ1Zm1ncl9nZW0tPmhhc19yZWxheGVkX2ZlbmNpbmcpCgkJcmV0dXJuIFJPVU5EX1VQX1RPKHNpemUsIDQwOTYpOwoKCWZvciAoaSA9IG1pbl9zaXplOyBpIDwgc2l6ZTsgaSA8PD0gMSkKCQk7CgoJcmV0dXJuIGk7Cn0KCi8qCiAqIFJvdW5kIGEgZ2l2ZW4gcGl0Y2ggdXAgdG8gdGhlIG1pbmltdW0gcmVxdWlyZWQgZm9yIFggdGlsaW5nIG9uIGEKICogZ2l2ZW4gY2hpcC4gIFdlIHVzZSA1MTIgYXMgdGhlIG1pbmltdW0gdG8gYWxsb3cgZm9yIGEgbGF0ZXIgdGlsaW5nCiAqIGNoYW5nZS4KICovCnN0YXRpYyB1bnNpZ25lZCBsb25nCmRybV9pbnRlbF9nZW1fYm9fdGlsZV9waXRjaChkcm1faW50ZWxfYnVmbWdyX2dlbSAqYnVmbWdyX2dlbSwKCQkJICAgIHVuc2lnbmVkIGxvbmcgcGl0Y2gsIHVpbnQzMl90ICp0aWxpbmdfbW9kZSkKewoJdW5zaWduZWQgbG9uZyB0aWxlX3dpZHRoOwoJdW5zaWduZWQgbG9uZyBpOwoKCS8qIElmIHVudGlsZWQsIHRoZW4ganVzdCBhbGlnbiBpdCBzbyB0aGF0IHdlIGNhbiBkbyByZW5kZXJpbmcKCSAqIHRvIGl0IHdpdGggdGhlIDNEIGVuZ2luZS4KCSAqLwoJaWYgKCp0aWxpbmdfbW9kZSA9PSBJOTE1X1RJTElOR19OT05FKQoJCXJldHVybiBBTElHTihwaXRjaCwgNjQpOwoKCWlmICgqdGlsaW5nX21vZGUgPT0gSTkxNV9USUxJTkdfWAoJCQl8fCAoSVNfOTE1KGJ1Zm1ncl9nZW0tPnBjaV9kZXZpY2UpCgkJCSAgICAmJiAqdGlsaW5nX21vZGUgPT0gSTkxNV9USUxJTkdfWSkpCgkJdGlsZV93aWR0aCA9IDUxMjsKCWVsc2UKCQl0aWxlX3dpZHRoID0gMTI4OwoKCS8qIDk2NSBpcyBmbGV4aWJsZSAqLwoJaWYgKGJ1Zm1ncl9nZW0tPmdlbiA+PSA0KQoJCXJldHVybiBST1VORF9VUF9UTyhwaXRjaCwgdGlsZV93aWR0aCk7CgoJLyogVGhlIG9sZGVyIGhhcmR3YXJlIGhhcyBhIG1heGltdW0gcGl0Y2ggb2YgODE5MiB3aXRoIHRpbGVkCgkgKiBzdXJmYWNlcywgc28gZmFsbGJhY2sgdG8gdW50aWxlZCBpZiBpdCdzIHRvbyBsYXJnZS4KCSAqLwoJaWYgKHBpdGNoID4gODE5MikgewoJCSp0aWxpbmdfbW9kZSA9IEk5MTVfVElMSU5HX05PTkU7CgkJcmV0dXJuIEFMSUdOKHBpdGNoLCA2NCk7Cgl9CgoJLyogUHJlLTk2NSBuZWVkcyBwb3dlciBvZiB0d28gdGlsZSB3aWR0aCAqLwoJZm9yIChpID0gdGlsZV93aWR0aDsgaSA8IHBpdGNoOyBpIDw8PSAxKQoJCTsKCglyZXR1cm4gaTsKfQoKc3RhdGljIHN0cnVjdCBkcm1faW50ZWxfZ2VtX2JvX2J1Y2tldCAqCmRybV9pbnRlbF9nZW1fYm9fYnVja2V0X2Zvcl9zaXplKGRybV9pbnRlbF9idWZtZ3JfZ2VtICpidWZtZ3JfZ2VtLAoJCQkJIHVuc2lnbmVkIGxvbmcgc2l6ZSkKewoJaW50IGk7CgoJZm9yIChpID0gMDsgaSA8IGJ1Zm1ncl9nZW0tPm51bV9idWNrZXRzOyBpKyspIHsKCQlzdHJ1Y3QgZHJtX2ludGVsX2dlbV9ib19idWNrZXQgKmJ1Y2tldCA9CgkJICAgICZidWZtZ3JfZ2VtLT5jYWNoZV9idWNrZXRbaV07CgkJaWYgKGJ1Y2tldC0+c2l6ZSA+PSBzaXplKSB7CgkJCXJldHVybiBidWNrZXQ7CgkJfQoJfQoKCXJldHVybiBOVUxMOwp9CgpzdGF0aWMgdm9pZApkcm1faW50ZWxfZ2VtX2R1bXBfdmFsaWRhdGlvbl9saXN0KGRybV9pbnRlbF9idWZtZ3JfZ2VtICpidWZtZ3JfZ2VtKQp7CglpbnQgaSwgajsKCglmb3IgKGkgPSAwOyBpIDwgYnVmbWdyX2dlbS0+ZXhlY19jb3VudDsgaSsrKSB7CgkJZHJtX2ludGVsX2JvICpibyA9IGJ1Zm1ncl9nZW0tPmV4ZWNfYm9zW2ldOwoJCWRybV9pbnRlbF9ib19nZW0gKmJvX2dlbSA9IChkcm1faW50ZWxfYm9fZ2VtICopIGJvOwoKCQlpZiAoYm9fZ2VtLT5yZWxvY3MgPT0gTlVMTCkgewoJCQlEQkcoIiUyZDogJWQgKCVzKVxuIiwgaSwgYm9fZ2VtLT5nZW1faGFuZGxlLAoJCQkgICAgYm9fZ2VtLT5uYW1lKTsKCQkJY29udGludWU7CgkJfQoKCQlmb3IgKGogPSAwOyBqIDwgYm9fZ2VtLT5yZWxvY19jb3VudDsgaisrKSB7CgkJCWRybV9pbnRlbF9ibyAqdGFyZ2V0X2JvID0gYm9fZ2VtLT5yZWxvY190YXJnZXRfaW5mb1tqXS5ibzsKCQkJZHJtX2ludGVsX2JvX2dlbSAqdGFyZ2V0X2dlbSA9CgkJCSAgICAoZHJtX2ludGVsX2JvX2dlbSAqKSB0YXJnZXRfYm87CgoJCQlEQkcoIiUyZDogJWQgKCVzKUAweCUwOGxseCAtPiAiCgkJCSAgICAiJWQgKCVzKUAweCUwOGx4ICsgMHglMDh4XG4iLAoJCQkgICAgaSwKCQkJICAgIGJvX2dlbS0+Z2VtX2hhbmRsZSwgYm9fZ2VtLT5uYW1lLAoJCQkgICAgKHVuc2lnbmVkIGxvbmcgbG9uZylib19nZW0tPnJlbG9jc1tqXS5vZmZzZXQsCgkJCSAgICB0YXJnZXRfZ2VtLT5nZW1faGFuZGxlLAoJCQkgICAgdGFyZ2V0X2dlbS0+bmFtZSwKCQkJICAgIHRhcmdldF9iby0+b2Zmc2V0NjQsCgkJCSAgICBib19nZW0tPnJlbG9jc1tqXS5kZWx0YSk7CgkJfQoJfQp9CgpzdGF0aWMgaW5saW5lIHZvaWQKZHJtX2ludGVsX2dlbV9ib19yZWZlcmVuY2UoZHJtX2ludGVsX2JvICpibykKewoJZHJtX2ludGVsX2JvX2dlbSAqYm9fZ2VtID0gKGRybV9pbnRlbF9ib19nZW0gKikgYm87CgoJYXRvbWljX2luYygmYm9fZ2VtLT5yZWZjb3VudCk7Cn0KCi8qKgogKiBBZGRzIHRoZSBnaXZlbiBidWZmZXIgdG8gdGhlIGxpc3Qgb2YgYnVmZmVycyB0byBiZSB2YWxpZGF0ZWQgKG1vdmVkIGludG8gdGhlCiAqIGFwcHJvcHJpYXRlIG1lbW9yeSB0eXBlKSB3aXRoIHRoZSBuZXh0IGJhdGNoIHN1Ym1pc3Npb24uCiAqCiAqIElmIGEgYnVmZmVyIGlzIHZhbGlkYXRlZCBtdWx0aXBsZSB0aW1lcyBpbiBhIGJhdGNoIHN1Ym1pc3Npb24sIGl0IGVuZHMgdXAKICogd2l0aCB0aGUgaW50ZXJzZWN0aW9uIG9mIHRoZSBtZW1vcnkgdHlwZSBmbGFncyBhbmQgdGhlIHVuaW9uIG9mIHRoZQogKiBhY2Nlc3MgZmxhZ3MuCiAqLwpzdGF0aWMgdm9pZApkcm1faW50ZWxfYWRkX3ZhbGlkYXRlX2J1ZmZlcihkcm1faW50ZWxfYm8gKmJvKQp7Cglkcm1faW50ZWxfYnVmbWdyX2dlbSAqYnVmbWdyX2dlbSA9IChkcm1faW50ZWxfYnVmbWdyX2dlbSAqKSBiby0+YnVmbWdyOwoJZHJtX2ludGVsX2JvX2dlbSAqYm9fZ2VtID0gKGRybV9pbnRlbF9ib19nZW0gKikgYm87CglpbnQgaW5kZXg7CgoJaWYgKGJvX2dlbS0+dmFsaWRhdGVfaW5kZXggIT0gLTEpCgkJcmV0dXJuOwoKCS8qIEV4dGVuZCB0aGUgYXJyYXkgb2YgdmFsaWRhdGlvbiBlbnRyaWVzIGFzIG5lY2Vzc2FyeS4gKi8KCWlmIChidWZtZ3JfZ2VtLT5leGVjX2NvdW50ID09IGJ1Zm1ncl9nZW0tPmV4ZWNfc2l6ZSkgewoJCWludCBuZXdfc2l6ZSA9IGJ1Zm1ncl9nZW0tPmV4ZWNfc2l6ZSAqIDI7CgoJCWlmIChuZXdfc2l6ZSA9PSAwKQoJCQluZXdfc2l6ZSA9IDU7CgoJCWJ1Zm1ncl9nZW0tPmV4ZWNfb2JqZWN0cyA9CgkJICAgIHJlYWxsb2MoYnVmbWdyX2dlbS0+ZXhlY19vYmplY3RzLAoJCQkgICAgc2l6ZW9mKCpidWZtZ3JfZ2VtLT5leGVjX29iamVjdHMpICogbmV3X3NpemUpOwoJCWJ1Zm1ncl9nZW0tPmV4ZWNfYm9zID0KCQkgICAgcmVhbGxvYyhidWZtZ3JfZ2VtLT5leGVjX2JvcywKCQkJICAgIHNpemVvZigqYnVmbWdyX2dlbS0+ZXhlY19ib3MpICogbmV3X3NpemUpOwoJCWJ1Zm1ncl9nZW0tPmV4ZWNfc2l6ZSA9IG5ld19zaXplOwoJfQoKCWluZGV4ID0gYnVmbWdyX2dlbS0+ZXhlY19jb3VudDsKCWJvX2dlbS0+dmFsaWRhdGVfaW5kZXggPSBpbmRleDsKCS8qIEZpbGwgaW4gYXJyYXkgZW50cnkgKi8KCWJ1Zm1ncl9nZW0tPmV4ZWNfb2JqZWN0c1tpbmRleF0uaGFuZGxlID0gYm9fZ2VtLT5nZW1faGFuZGxlOwoJYnVmbWdyX2dlbS0+ZXhlY19vYmplY3RzW2luZGV4XS5yZWxvY2F0aW9uX2NvdW50ID0gYm9fZ2VtLT5yZWxvY19jb3VudDsKCWJ1Zm1ncl9nZW0tPmV4ZWNfb2JqZWN0c1tpbmRleF0ucmVsb2NzX3B0ciA9ICh1aW50cHRyX3QpIGJvX2dlbS0+cmVsb2NzOwoJYnVmbWdyX2dlbS0+ZXhlY19vYmplY3RzW2luZGV4XS5hbGlnbm1lbnQgPSAwOwoJYnVmbWdyX2dlbS0+ZXhlY19vYmplY3RzW2luZGV4XS5vZmZzZXQgPSAwOwoJYnVmbWdyX2dlbS0+ZXhlY19ib3NbaW5kZXhdID0gYm87CglidWZtZ3JfZ2VtLT5leGVjX2NvdW50Kys7Cn0KCnN0YXRpYyB2b2lkCmRybV9pbnRlbF9hZGRfdmFsaWRhdGVfYnVmZmVyMihkcm1faW50ZWxfYm8gKmJvLCBpbnQgbmVlZF9mZW5jZSkKewoJZHJtX2ludGVsX2J1Zm1ncl9nZW0gKmJ1Zm1ncl9nZW0gPSAoZHJtX2ludGVsX2J1Zm1ncl9nZW0gKiliby0+YnVmbWdyOwoJZHJtX2ludGVsX2JvX2dlbSAqYm9fZ2VtID0gKGRybV9pbnRlbF9ib19nZW0gKilibzsKCWludCBpbmRleDsKCglpZiAoYm9fZ2VtLT52YWxpZGF0ZV9pbmRleCAhPSAtMSkgewoJCWlmIChuZWVkX2ZlbmNlKQoJCQlidWZtZ3JfZ2VtLT5leGVjMl9vYmplY3RzW2JvX2dlbS0+dmFsaWRhdGVfaW5kZXhdLmZsYWdzIHw9CgkJCQlFWEVDX09CSkVDVF9ORUVEU19GRU5DRTsKCQlyZXR1cm47Cgl9CgoJLyogRXh0ZW5kIHRoZSBhcnJheSBvZiB2YWxpZGF0aW9uIGVudHJpZXMgYXMgbmVjZXNzYXJ5LiAqLwoJaWYgKGJ1Zm1ncl9nZW0tPmV4ZWNfY291bnQgPT0gYnVmbWdyX2dlbS0+ZXhlY19zaXplKSB7CgkJaW50IG5ld19zaXplID0gYnVmbWdyX2dlbS0+ZXhlY19zaXplICogMjsKCgkJaWYgKG5ld19zaXplID09IDApCgkJCW5ld19zaXplID0gNTsKCgkJYnVmbWdyX2dlbS0+ZXhlYzJfb2JqZWN0cyA9CgkJCXJlYWxsb2MoYnVmbWdyX2dlbS0+ZXhlYzJfb2JqZWN0cywKCQkJCXNpemVvZigqYnVmbWdyX2dlbS0+ZXhlYzJfb2JqZWN0cykgKiBuZXdfc2l6ZSk7CgkJYnVmbWdyX2dlbS0+ZXhlY19ib3MgPQoJCQlyZWFsbG9jKGJ1Zm1ncl9nZW0tPmV4ZWNfYm9zLAoJCQkJc2l6ZW9mKCpidWZtZ3JfZ2VtLT5leGVjX2JvcykgKiBuZXdfc2l6ZSk7CgkJYnVmbWdyX2dlbS0+ZXhlY19zaXplID0gbmV3X3NpemU7Cgl9CgoJaW5kZXggPSBidWZtZ3JfZ2VtLT5leGVjX2NvdW50OwoJYm9fZ2VtLT52YWxpZGF0ZV9pbmRleCA9IGluZGV4OwoJLyogRmlsbCBpbiBhcnJheSBlbnRyeSAqLwoJYnVmbWdyX2dlbS0+ZXhlYzJfb2JqZWN0c1tpbmRleF0uaGFuZGxlID0gYm9fZ2VtLT5nZW1faGFuZGxlOwoJYnVmbWdyX2dlbS0+ZXhlYzJfb2JqZWN0c1tpbmRleF0ucmVsb2NhdGlvbl9jb3VudCA9IGJvX2dlbS0+cmVsb2NfY291bnQ7CglidWZtZ3JfZ2VtLT5leGVjMl9vYmplY3RzW2luZGV4XS5yZWxvY3NfcHRyID0gKHVpbnRwdHJfdClib19nZW0tPnJlbG9jczsKCWJ1Zm1ncl9nZW0tPmV4ZWMyX29iamVjdHNbaW5kZXhdLmFsaWdubWVudCA9IDA7CglidWZtZ3JfZ2VtLT5leGVjMl9vYmplY3RzW2luZGV4XS5vZmZzZXQgPSAwOwoJYnVmbWdyX2dlbS0+ZXhlY19ib3NbaW5kZXhdID0gYm87CglidWZtZ3JfZ2VtLT5leGVjMl9vYmplY3RzW2luZGV4XS5mbGFncyA9IDA7CglidWZtZ3JfZ2VtLT5leGVjMl9vYmplY3RzW2luZGV4XS5yc3ZkMSA9IDA7CglidWZtZ3JfZ2VtLT5leGVjMl9vYmplY3RzW2luZGV4XS5yc3ZkMiA9IDA7CglpZiAobmVlZF9mZW5jZSkgewoJCWJ1Zm1ncl9nZW0tPmV4ZWMyX29iamVjdHNbaW5kZXhdLmZsYWdzIHw9CgkJCUVYRUNfT0JKRUNUX05FRURTX0ZFTkNFOwoJfQoJYnVmbWdyX2dlbS0+ZXhlY19jb3VudCsrOwp9CgojZGVmaW5lIFJFTE9DX0JVRl9TSVpFKHgpICgoSTkxNV9SRUxPQ19IRUFERVIgKyB4ICogSTkxNV9SRUxPQzBfU1RSSURFKSAqIFwKCXNpemVvZih1aW50MzJfdCkpCgpzdGF0aWMgdm9pZApkcm1faW50ZWxfYm9fZ2VtX3NldF9pbl9hcGVydHVyZV9zaXplKGRybV9pbnRlbF9idWZtZ3JfZ2VtICpidWZtZ3JfZ2VtLAoJCQkJICAgICAgZHJtX2ludGVsX2JvX2dlbSAqYm9fZ2VtKQp7CglpbnQgc2l6ZTsKCglhc3NlcnQoIWJvX2dlbS0+dXNlZF9hc19yZWxvY190YXJnZXQpOwoKCS8qIFRoZSBvbGRlciBjaGlwc2V0cyBhcmUgZmFyLWxlc3MgZmxleGlibGUgaW4gdGVybXMgb2YgdGlsaW5nLAoJICogYW5kIHJlcXVpcmUgdGlsZWQgYnVmZmVyIHRvIGJlIHNpemUgYWxpZ25lZCBpbiB0aGUgYXBlcnR1cmUuCgkgKiBUaGlzIG1lYW5zIHRoYXQgaW4gdGhlIHdvcnN0IHBvc3NpYmxlIGNhc2Ugd2Ugd2lsbCBuZWVkIGEgaG9sZQoJICogdHdpY2UgYXMgbGFyZ2UgYXMgdGhlIG9iamVjdCBpbiBvcmRlciBmb3IgaXQgdG8gZml0IGludG8gdGhlCgkgKiBhcGVydHVyZS4gT3B0aW1hbCBwYWNraW5nIGlzIGZvciB3aW1wcy4KCSAqLwoJc2l6ZSA9IGJvX2dlbS0+Ym8uc2l6ZTsKCWlmIChidWZtZ3JfZ2VtLT5nZW4gPCA0ICYmIGJvX2dlbS0+dGlsaW5nX21vZGUgIT0gSTkxNV9USUxJTkdfTk9ORSkgewoJCWludCBtaW5fc2l6ZTsKCgkJaWYgKGJ1Zm1ncl9nZW0tPmhhc19yZWxheGVkX2ZlbmNpbmcpIHsKCQkJaWYgKGJ1Zm1ncl9nZW0tPmdlbiA9PSAzKQoJCQkJbWluX3NpemUgPSAxMDI0KjEwMjQ7CgkJCWVsc2UKCQkJCW1pbl9zaXplID0gNTEyKjEwMjQ7CgoJCQl3aGlsZSAobWluX3NpemUgPCBzaXplKQoJCQkJbWluX3NpemUgKj0gMjsKCQl9IGVsc2UKCQkJbWluX3NpemUgPSBzaXplOwoKCQkvKiBBY2NvdW50IGZvciB3b3JzdC1jYXNlIGFsaWdubWVudC4gKi8KCQlzaXplID0gMiAqIG1pbl9zaXplOwoJfQoKCWJvX2dlbS0+cmVsb2NfdHJlZV9zaXplID0gc2l6ZTsKfQoKc3RhdGljIGludApkcm1faW50ZWxfc2V0dXBfcmVsb2NfbGlzdChkcm1faW50ZWxfYm8gKmJvKQp7Cglkcm1faW50ZWxfYm9fZ2VtICpib19nZW0gPSAoZHJtX2ludGVsX2JvX2dlbSAqKSBibzsKCWRybV9pbnRlbF9idWZtZ3JfZ2VtICpidWZtZ3JfZ2VtID0gKGRybV9pbnRlbF9idWZtZ3JfZ2VtICopIGJvLT5idWZtZ3I7Cgl1bnNpZ25lZCBpbnQgbWF4X3JlbG9jcyA9IGJ1Zm1ncl9nZW0tPm1heF9yZWxvY3M7CgoJaWYgKGJvLT5zaXplIC8gNCA8IG1heF9yZWxvY3MpCgkJbWF4X3JlbG9jcyA9IGJvLT5zaXplIC8gNDsKCglib19nZW0tPnJlbG9jcyA9IG1hbGxvYyhtYXhfcmVsb2NzICoKCQkJCXNpemVvZihzdHJ1Y3QgZHJtX2k5MTVfZ2VtX3JlbG9jYXRpb25fZW50cnkpKTsKCWJvX2dlbS0+cmVsb2NfdGFyZ2V0X2luZm8gPSBtYWxsb2MobWF4X3JlbG9jcyAqCgkJCQkJICAgc2l6ZW9mKGRybV9pbnRlbF9yZWxvY190YXJnZXQpKTsKCWlmIChib19nZW0tPnJlbG9jcyA9PSBOVUxMIHx8IGJvX2dlbS0+cmVsb2NfdGFyZ2V0X2luZm8gPT0gTlVMTCkgewoJCWJvX2dlbS0+aGFzX2Vycm9yID0gdHJ1ZTsKCgkJZnJlZSAoYm9fZ2VtLT5yZWxvY3MpOwoJCWJvX2dlbS0+cmVsb2NzID0gTlVMTDsKCgkJZnJlZSAoYm9fZ2VtLT5yZWxvY190YXJnZXRfaW5mbyk7CgkJYm9fZ2VtLT5yZWxvY190YXJnZXRfaW5mbyA9IE5VTEw7CgoJCXJldHVybiAxOwoJfQoKCXJldHVybiAwOwp9CgpzdGF0aWMgaW50CmRybV9pbnRlbF9nZW1fYm9fYnVzeShkcm1faW50ZWxfYm8gKmJvKQp7Cglkcm1faW50ZWxfYnVmbWdyX2dlbSAqYnVmbWdyX2dlbSA9IChkcm1faW50ZWxfYnVmbWdyX2dlbSAqKSBiby0+YnVmbWdyOwoJZHJtX2ludGVsX2JvX2dlbSAqYm9fZ2VtID0gKGRybV9pbnRlbF9ib19nZW0gKikgYm87CglzdHJ1Y3QgZHJtX2k5MTVfZ2VtX2J1c3kgYnVzeTsKCWludCByZXQ7CgoJaWYgKGJvX2dlbS0+cmV1c2FibGUgJiYgYm9fZ2VtLT5pZGxlKQoJCXJldHVybiBmYWxzZTsKCglWR19DTEVBUihidXN5KTsKCWJ1c3kuaGFuZGxlID0gYm9fZ2VtLT5nZW1faGFuZGxlOwoKCXJldCA9IGRybUlvY3RsKGJ1Zm1ncl9nZW0tPmZkLCBEUk1fSU9DVExfSTkxNV9HRU1fQlVTWSwgJmJ1c3kpOwoJaWYgKHJldCA9PSAwKSB7CgkJYm9fZ2VtLT5pZGxlID0gIWJ1c3kuYnVzeTsKCQlyZXR1cm4gYnVzeS5idXN5OwoJfSBlbHNlIHsKCQlyZXR1cm4gZmFsc2U7Cgl9CglyZXR1cm4gKHJldCA9PSAwICYmIGJ1c3kuYnVzeSk7Cn0KCnN0YXRpYyBpbnQKZHJtX2ludGVsX2dlbV9ib19tYWR2aXNlX2ludGVybmFsKGRybV9pbnRlbF9idWZtZ3JfZ2VtICpidWZtZ3JfZ2VtLAoJCQkJICBkcm1faW50ZWxfYm9fZ2VtICpib19nZW0sIGludCBzdGF0ZSkKewoJc3RydWN0IGRybV9pOTE1X2dlbV9tYWR2aXNlIG1hZHY7CgoJVkdfQ0xFQVIobWFkdik7CgltYWR2LmhhbmRsZSA9IGJvX2dlbS0+Z2VtX2hhbmRsZTsKCW1hZHYubWFkdiA9IHN0YXRlOwoJbWFkdi5yZXRhaW5lZCA9IDE7Cglkcm1Jb2N0bChidWZtZ3JfZ2VtLT5mZCwgRFJNX0lPQ1RMX0k5MTVfR0VNX01BRFZJU0UsICZtYWR2KTsKCglyZXR1cm4gbWFkdi5yZXRhaW5lZDsKfQoKc3RhdGljIGludApkcm1faW50ZWxfZ2VtX2JvX21hZHZpc2UoZHJtX2ludGVsX2JvICpibywgaW50IG1hZHYpCnsKCXJldHVybiBkcm1faW50ZWxfZ2VtX2JvX21hZHZpc2VfaW50ZXJuYWwKCQkoKGRybV9pbnRlbF9idWZtZ3JfZ2VtICopIGJvLT5idWZtZ3IsCgkJIChkcm1faW50ZWxfYm9fZ2VtICopIGJvLAoJCSBtYWR2KTsKfQoKLyogZHJvcCB0aGUgb2xkZXN0IGVudHJpZXMgdGhhdCBoYXZlIGJlZW4gcHVyZ2VkIGJ5IHRoZSBrZXJuZWwgKi8Kc3RhdGljIHZvaWQKZHJtX2ludGVsX2dlbV9ib19jYWNoZV9wdXJnZV9idWNrZXQoZHJtX2ludGVsX2J1Zm1ncl9nZW0gKmJ1Zm1ncl9nZW0sCgkJCQkgICAgc3RydWN0IGRybV9pbnRlbF9nZW1fYm9fYnVja2V0ICpidWNrZXQpCnsKCXdoaWxlICghRFJNTElTVEVNUFRZKCZidWNrZXQtPmhlYWQpKSB7CgkJZHJtX2ludGVsX2JvX2dlbSAqYm9fZ2VtOwoKCQlib19nZW0gPSBEUk1MSVNURU5UUlkoZHJtX2ludGVsX2JvX2dlbSwKCQkJCSAgICAgIGJ1Y2tldC0+aGVhZC5uZXh0LCBoZWFkKTsKCQlpZiAoZHJtX2ludGVsX2dlbV9ib19tYWR2aXNlX2ludGVybmFsCgkJICAgIChidWZtZ3JfZ2VtLCBib19nZW0sIEk5MTVfTUFEVl9ET05UTkVFRCkpCgkJCWJyZWFrOwoKCQlEUk1MSVNUREVMKCZib19nZW0tPmhlYWQpOwoJCWRybV9pbnRlbF9nZW1fYm9fZnJlZSgmYm9fZ2VtLT5ibyk7Cgl9Cn0KCnN0YXRpYyBkcm1faW50ZWxfYm8gKgpkcm1faW50ZWxfZ2VtX2JvX2FsbG9jX2ludGVybmFsKGRybV9pbnRlbF9idWZtZ3IgKmJ1Zm1nciwKCQkJCWNvbnN0IGNoYXIgKm5hbWUsCgkJCQl1bnNpZ25lZCBsb25nIHNpemUsCgkJCQl1bnNpZ25lZCBsb25nIGZsYWdzLAoJCQkJdWludDMyX3QgdGlsaW5nX21vZGUsCgkJCQl1bnNpZ25lZCBsb25nIHN0cmlkZSkKewoJZHJtX2ludGVsX2J1Zm1ncl9nZW0gKmJ1Zm1ncl9nZW0gPSAoZHJtX2ludGVsX2J1Zm1ncl9nZW0gKikgYnVmbWdyOwoJZHJtX2ludGVsX2JvX2dlbSAqYm9fZ2VtOwoJdW5zaWduZWQgaW50IHBhZ2Vfc2l6ZSA9IGdldHBhZ2VzaXplKCk7CglpbnQgcmV0OwoJc3RydWN0IGRybV9pbnRlbF9nZW1fYm9fYnVja2V0ICpidWNrZXQ7Cglib29sIGFsbG9jX2Zyb21fY2FjaGU7Cgl1bnNpZ25lZCBsb25nIGJvX3NpemU7Cglib29sIGZvcl9yZW5kZXIgPSBmYWxzZTsKCglpZiAoZmxhZ3MgJiBCT19BTExPQ19GT1JfUkVOREVSKQoJCWZvcl9yZW5kZXIgPSB0cnVlOwoKCS8qIFJvdW5kIHRoZSBhbGxvY2F0ZWQgc2l6ZSB1cCB0byBhIHBvd2VyIG9mIHR3byBudW1iZXIgb2YgcGFnZXMuICovCglidWNrZXQgPSBkcm1faW50ZWxfZ2VtX2JvX2J1Y2tldF9mb3Jfc2l6ZShidWZtZ3JfZ2VtLCBzaXplKTsKCgkvKiBJZiB3ZSBkb24ndCBoYXZlIGNhY2hpbmcgYXQgdGhpcyBzaXplLCBkb24ndCBhY3R1YWxseSByb3VuZCB0aGUKCSAqIGFsbG9jYXRpb24gdXAuCgkgKi8KCWlmIChidWNrZXQgPT0gTlVMTCkgewoJCWJvX3NpemUgPSBzaXplOwoJCWlmIChib19zaXplIDwgcGFnZV9zaXplKQoJCQlib19zaXplID0gcGFnZV9zaXplOwoJfSBlbHNlIHsKCQlib19zaXplID0gYnVja2V0LT5zaXplOwoJfQoKCXB0aHJlYWRfbXV0ZXhfbG9jaygmYnVmbWdyX2dlbS0+bG9jayk7CgkvKiBHZXQgYSBidWZmZXIgb3V0IG9mIHRoZSBjYWNoZSBpZiBhdmFpbGFibGUgKi8KcmV0cnk6CglhbGxvY19mcm9tX2NhY2hlID0gZmFsc2U7CglpZiAoYnVja2V0ICE9IE5VTEwgJiYgIURSTUxJU1RFTVBUWSgmYnVja2V0LT5oZWFkKSkgewoJCWlmIChmb3JfcmVuZGVyKSB7CgkJCS8qIEFsbG9jYXRlIG5ldyByZW5kZXItdGFyZ2V0IEJPcyBmcm9tIHRoZSB0YWlsIChNUlUpCgkJCSAqIG9mIHRoZSBsaXN0LCBhcyBpdCB3aWxsIGxpa2VseSBiZSBob3QgaW4gdGhlIEdQVQoJCQkgKiBjYWNoZSBhbmQgaW4gdGhlIGFwZXJ0dXJlIGZvciB1cy4KCQkJICovCgkJCWJvX2dlbSA9IERSTUxJU1RFTlRSWShkcm1faW50ZWxfYm9fZ2VtLAoJCQkJCSAgICAgIGJ1Y2tldC0+aGVhZC5wcmV2LCBoZWFkKTsKCQkJRFJNTElTVERFTCgmYm9fZ2VtLT5oZWFkKTsKCQkJYWxsb2NfZnJvbV9jYWNoZSA9IHRydWU7CgkJfSBlbHNlIHsKCQkJLyogRm9yIG5vbi1yZW5kZXItdGFyZ2V0IEJPcyAod2hlcmUgd2UncmUgcHJvYmFibHkKCQkJICogZ29pbmcgdG8gbWFwIGl0IGZpcnN0IHRoaW5nIGluIG9yZGVyIHRvIGZpbGwgaXQKCQkJICogd2l0aCBkYXRhKSwgY2hlY2sgaWYgdGhlIGxhc3QgQk8gaW4gdGhlIGNhY2hlIGlzCgkJCSAqIHVuYnVzeSwgYW5kIG9ubHkgcmV1c2UgaW4gdGhhdCBjYXNlLiBPdGhlcndpc2UsCgkJCSAqIGFsbG9jYXRpbmcgYSBuZXcgYnVmZmVyIGlzIHByb2JhYmx5IGZhc3RlciB0aGFuCgkJCSAqIHdhaXRpbmcgZm9yIHRoZSBHUFUgdG8gZmluaXNoLgoJCQkgKi8KCQkJYm9fZ2VtID0gRFJNTElTVEVOVFJZKGRybV9pbnRlbF9ib19nZW0sCgkJCQkJICAgICAgYnVja2V0LT5oZWFkLm5leHQsIGhlYWQpOwoJCQlpZiAoIWRybV9pbnRlbF9nZW1fYm9fYnVzeSgmYm9fZ2VtLT5ibykpIHsKCQkJCWFsbG9jX2Zyb21fY2FjaGUgPSB0cnVlOwoJCQkJRFJNTElTVERFTCgmYm9fZ2VtLT5oZWFkKTsKCQkJfQoJCX0KCgkJaWYgKGFsbG9jX2Zyb21fY2FjaGUpIHsKCQkJaWYgKCFkcm1faW50ZWxfZ2VtX2JvX21hZHZpc2VfaW50ZXJuYWwKCQkJICAgIChidWZtZ3JfZ2VtLCBib19nZW0sIEk5MTVfTUFEVl9XSUxMTkVFRCkpIHsKCQkJCWRybV9pbnRlbF9nZW1fYm9fZnJlZSgmYm9fZ2VtLT5ibyk7CgkJCQlkcm1faW50ZWxfZ2VtX2JvX2NhY2hlX3B1cmdlX2J1Y2tldChidWZtZ3JfZ2VtLAoJCQkJCQkJCSAgICBidWNrZXQpOwoJCQkJZ290byByZXRyeTsKCQkJfQoKCQkJaWYgKGRybV9pbnRlbF9nZW1fYm9fc2V0X3RpbGluZ19pbnRlcm5hbCgmYm9fZ2VtLT5ibywKCQkJCQkJCQkgdGlsaW5nX21vZGUsCgkJCQkJCQkJIHN0cmlkZSkpIHsKCQkJCWRybV9pbnRlbF9nZW1fYm9fZnJlZSgmYm9fZ2VtLT5ibyk7CgkJCQlnb3RvIHJldHJ5OwoJCQl9CgkJfQoJfQoJcHRocmVhZF9tdXRleF91bmxvY2soJmJ1Zm1ncl9nZW0tPmxvY2spOwoKCWlmICghYWxsb2NfZnJvbV9jYWNoZSkgewoJCXN0cnVjdCBkcm1faTkxNV9nZW1fY3JlYXRlIGNyZWF0ZTsKCgkJYm9fZ2VtID0gY2FsbG9jKDEsIHNpemVvZigqYm9fZ2VtKSk7CgkJaWYgKCFib19nZW0pCgkJCXJldHVybiBOVUxMOwoKCQlib19nZW0tPmJvLnNpemUgPSBib19zaXplOwoKCQlWR19DTEVBUihjcmVhdGUpOwoJCWNyZWF0ZS5zaXplID0gYm9fc2l6ZTsKCgkJcmV0ID0gZHJtSW9jdGwoYnVmbWdyX2dlbS0+ZmQsCgkJCSAgICAgICBEUk1fSU9DVExfSTkxNV9HRU1fQ1JFQVRFLAoJCQkgICAgICAgJmNyZWF0ZSk7CgkJYm9fZ2VtLT5nZW1faGFuZGxlID0gY3JlYXRlLmhhbmRsZTsKCQlib19nZW0tPmJvLmhhbmRsZSA9IGJvX2dlbS0+Z2VtX2hhbmRsZTsKCQlpZiAocmV0ICE9IDApIHsKCQkJZnJlZShib19nZW0pOwoJCQlyZXR1cm4gTlVMTDsKCQl9CgkJYm9fZ2VtLT5iby5idWZtZ3IgPSBidWZtZ3I7CgoJCWJvX2dlbS0+dGlsaW5nX21vZGUgPSBJOTE1X1RJTElOR19OT05FOwoJCWJvX2dlbS0+c3dpenpsZV9tb2RlID0gSTkxNV9CSVRfNl9TV0laWkxFX05PTkU7CgkJYm9fZ2VtLT5zdHJpZGUgPSAwOwoKCQkvKiBkcm1faW50ZWxfZ2VtX2JvX2ZyZWUgY2FsbHMgRFJNTElTVERFTCgpIGZvciBhbiB1bmluaXRpYWxpemVkCgkJICAgbGlzdCAodm1hX2xpc3QpLCBzbyBiZXR0ZXIgc2V0IHRoZSBsaXN0IGhlYWQgaGVyZSAqLwoJCURSTUlOSVRMSVNUSEVBRCgmYm9fZ2VtLT5uYW1lX2xpc3QpOwoJCURSTUlOSVRMSVNUSEVBRCgmYm9fZ2VtLT52bWFfbGlzdCk7CgkJaWYgKGRybV9pbnRlbF9nZW1fYm9fc2V0X3RpbGluZ19pbnRlcm5hbCgmYm9fZ2VtLT5ibywKCQkJCQkJCSB0aWxpbmdfbW9kZSwKCQkJCQkJCSBzdHJpZGUpKSB7CgkJICAgIGRybV9pbnRlbF9nZW1fYm9fZnJlZSgmYm9fZ2VtLT5ibyk7CgkJICAgIHJldHVybiBOVUxMOwoJCX0KCX0KCglib19nZW0tPm5hbWUgPSBuYW1lOwoJYXRvbWljX3NldCgmYm9fZ2VtLT5yZWZjb3VudCwgMSk7Cglib19nZW0tPnZhbGlkYXRlX2luZGV4ID0gLTE7Cglib19nZW0tPnJlbG9jX3RyZWVfZmVuY2VzID0gMDsKCWJvX2dlbS0+dXNlZF9hc19yZWxvY190YXJnZXQgPSBmYWxzZTsKCWJvX2dlbS0+aGFzX2Vycm9yID0gZmFsc2U7Cglib19nZW0tPnJldXNhYmxlID0gdHJ1ZTsKCWJvX2dlbS0+YXViX2Fubm90YXRpb25zID0gTlVMTDsKCWJvX2dlbS0+YXViX2Fubm90YXRpb25fY291bnQgPSAwOwoKCWRybV9pbnRlbF9ib19nZW1fc2V0X2luX2FwZXJ0dXJlX3NpemUoYnVmbWdyX2dlbSwgYm9fZ2VtKTsKCglEQkcoImJvX2NyZWF0ZTogYnVmICVkICglcykgJWxkYlxuIiwKCSAgICBib19nZW0tPmdlbV9oYW5kbGUsIGJvX2dlbS0+bmFtZSwgc2l6ZSk7CgoJcmV0dXJuICZib19nZW0tPmJvOwp9CgpzdGF0aWMgZHJtX2ludGVsX2JvICoKZHJtX2ludGVsX2dlbV9ib19hbGxvY19mb3JfcmVuZGVyKGRybV9pbnRlbF9idWZtZ3IgKmJ1Zm1nciwKCQkJCSAgY29uc3QgY2hhciAqbmFtZSwKCQkJCSAgdW5zaWduZWQgbG9uZyBzaXplLAoJCQkJICB1bnNpZ25lZCBpbnQgYWxpZ25tZW50KQp7CglyZXR1cm4gZHJtX2ludGVsX2dlbV9ib19hbGxvY19pbnRlcm5hbChidWZtZ3IsIG5hbWUsIHNpemUsCgkJCQkJICAgICAgIEJPX0FMTE9DX0ZPUl9SRU5ERVIsCgkJCQkJICAgICAgIEk5MTVfVElMSU5HX05PTkUsIDApOwp9CgpzdGF0aWMgZHJtX2ludGVsX2JvICoKZHJtX2ludGVsX2dlbV9ib19hbGxvYyhkcm1faW50ZWxfYnVmbWdyICpidWZtZ3IsCgkJICAgICAgIGNvbnN0IGNoYXIgKm5hbWUsCgkJICAgICAgIHVuc2lnbmVkIGxvbmcgc2l6ZSwKCQkgICAgICAgdW5zaWduZWQgaW50IGFsaWdubWVudCkKewoJcmV0dXJuIGRybV9pbnRlbF9nZW1fYm9fYWxsb2NfaW50ZXJuYWwoYnVmbWdyLCBuYW1lLCBzaXplLCAwLAoJCQkJCSAgICAgICBJOTE1X1RJTElOR19OT05FLCAwKTsKfQoKc3RhdGljIGRybV9pbnRlbF9ibyAqCmRybV9pbnRlbF9nZW1fYm9fYWxsb2NfdGlsZWQoZHJtX2ludGVsX2J1Zm1nciAqYnVmbWdyLCBjb25zdCBjaGFyICpuYW1lLAoJCQkgICAgIGludCB4LCBpbnQgeSwgaW50IGNwcCwgdWludDMyX3QgKnRpbGluZ19tb2RlLAoJCQkgICAgIHVuc2lnbmVkIGxvbmcgKnBpdGNoLCB1bnNpZ25lZCBsb25nIGZsYWdzKQp7Cglkcm1faW50ZWxfYnVmbWdyX2dlbSAqYnVmbWdyX2dlbSA9IChkcm1faW50ZWxfYnVmbWdyX2dlbSAqKWJ1Zm1ncjsKCXVuc2lnbmVkIGxvbmcgc2l6ZSwgc3RyaWRlOwoJdWludDMyX3QgdGlsaW5nOwoKCWRvIHsKCQl1bnNpZ25lZCBsb25nIGFsaWduZWRfeSwgaGVpZ2h0X2FsaWdubWVudDsKCgkJdGlsaW5nID0gKnRpbGluZ19tb2RlOwoKCQkvKiBJZiB3ZSdyZSB0aWxlZCwgb3VyIGFsbG9jYXRpb25zIGFyZSBpbiA4IG9yIDMyLXJvdyBibG9ja3MsCgkJICogc28gZmFpbHVyZSB0byBhbGlnbiBvdXIgaGVpZ2h0IG1lYW5zIHRoYXQgd2Ugd29uJ3QgYWxsb2NhdGUKCQkgKiBlbm91Z2ggcGFnZXMuCgkJICoKCQkgKiBJZiB3ZSdyZSB1bnRpbGVkLCB3ZSBzdGlsbCBoYXZlIHRvIGFsaWduIHRvIDIgcm93cyBoaWdoCgkJICogYmVjYXVzZSB0aGUgZGF0YSBwb3J0IGFjY2Vzc2VzIDJ4MiBibG9ja3MgZXZlbiBpZiB0aGUKCQkgKiBib3R0b20gcm93IGlzbid0IHRvIGJlIHJlbmRlcmVkLCBzbyBmYWlsdXJlIHRvIGFsaWduIG1lYW5zCgkJICogd2UgY291bGQgd2FsayBvZmYgdGhlIGVuZCBvZiB0aGUgR1RUIGFuZCBmYXVsdC4gIFRoaXMgaXMKCQkgKiBkb2N1bWVudGVkIG9uIDk2NSwgYW5kIG1heSBiZSB0aGUgY2FzZSBvbiBvbGRlciBjaGlwc2V0cwoJCSAqIHRvbyBzbyB3ZSB0cnkgdG8gYmUgY2FyZWZ1bC4KCQkgKi8KCQlhbGlnbmVkX3kgPSB5OwoJCWhlaWdodF9hbGlnbm1lbnQgPSAyOwoKCQlpZiAoKGJ1Zm1ncl9nZW0tPmdlbiA9PSAyKSAmJiB0aWxpbmcgIT0gSTkxNV9USUxJTkdfTk9ORSkKCQkJaGVpZ2h0X2FsaWdubWVudCA9IDE2OwoJCWVsc2UgaWYgKHRpbGluZyA9PSBJOTE1X1RJTElOR19YCgkJCXx8IChJU185MTUoYnVmbWdyX2dlbS0+cGNpX2RldmljZSkKCQkJICAgICYmIHRpbGluZyA9PSBJOTE1X1RJTElOR19ZKSkKCQkJaGVpZ2h0X2FsaWdubWVudCA9IDg7CgkJZWxzZSBpZiAodGlsaW5nID09IEk5MTVfVElMSU5HX1kpCgkJCWhlaWdodF9hbGlnbm1lbnQgPSAzMjsKCQlhbGlnbmVkX3kgPSBBTElHTih5LCBoZWlnaHRfYWxpZ25tZW50KTsKCgkJc3RyaWRlID0geCAqIGNwcDsKCQlzdHJpZGUgPSBkcm1faW50ZWxfZ2VtX2JvX3RpbGVfcGl0Y2goYnVmbWdyX2dlbSwgc3RyaWRlLCB0aWxpbmdfbW9kZSk7CgkJc2l6ZSA9IHN0cmlkZSAqIGFsaWduZWRfeTsKCQlzaXplID0gZHJtX2ludGVsX2dlbV9ib190aWxlX3NpemUoYnVmbWdyX2dlbSwgc2l6ZSwgdGlsaW5nX21vZGUpOwoJfSB3aGlsZSAoKnRpbGluZ19tb2RlICE9IHRpbGluZyk7CgkqcGl0Y2ggPSBzdHJpZGU7CgoJaWYgKHRpbGluZyA9PSBJOTE1X1RJTElOR19OT05FKQoJCXN0cmlkZSA9IDA7CgoJcmV0dXJuIGRybV9pbnRlbF9nZW1fYm9fYWxsb2NfaW50ZXJuYWwoYnVmbWdyLCBuYW1lLCBzaXplLCBmbGFncywKCQkJCQkgICAgICAgdGlsaW5nLCBzdHJpZGUpOwp9CgpzdGF0aWMgZHJtX2ludGVsX2JvICoKZHJtX2ludGVsX2dlbV9ib19hbGxvY191c2VycHRyKGRybV9pbnRlbF9idWZtZ3IgKmJ1Zm1nciwKCQkJCWNvbnN0IGNoYXIgKm5hbWUsCgkJCQl2b2lkICphZGRyLAoJCQkJdWludDMyX3QgdGlsaW5nX21vZGUsCgkJCQl1aW50MzJfdCBzdHJpZGUsCgkJCQl1bnNpZ25lZCBsb25nIHNpemUsCgkJCQl1bnNpZ25lZCBsb25nIGZsYWdzKQp7Cglkcm1faW50ZWxfYnVmbWdyX2dlbSAqYnVmbWdyX2dlbSA9IChkcm1faW50ZWxfYnVmbWdyX2dlbSAqKSBidWZtZ3I7Cglkcm1faW50ZWxfYm9fZ2VtICpib19nZW07CglpbnQgcmV0OwoJc3RydWN0IGRybV9pOTE1X2dlbV91c2VycHRyIHVzZXJwdHI7CgoJLyogVGlsaW5nIHdpdGggdXNlcnB0ciBzdXJmYWNlcyBpcyBub3Qgc3VwcG9ydGVkCgkgKiBvbiBhbGwgaGFyZHdhcmUgc28gcmVmdXNlIGl0IGZvciB0aW1lIGJlaW5nLgoJICovCglpZiAodGlsaW5nX21vZGUgIT0gSTkxNV9USUxJTkdfTk9ORSkKCQlyZXR1cm4gTlVMTDsKCglib19nZW0gPSBjYWxsb2MoMSwgc2l6ZW9mKCpib19nZW0pKTsKCWlmICghYm9fZ2VtKQoJCXJldHVybiBOVUxMOwoKCWJvX2dlbS0+Ym8uc2l6ZSA9IHNpemU7CgoJVkdfQ0xFQVIodXNlcnB0cik7Cgl1c2VycHRyLnVzZXJfcHRyID0gKF9fdTY0KSgodW5zaWduZWQgbG9uZylhZGRyKTsKCXVzZXJwdHIudXNlcl9zaXplID0gc2l6ZTsKCXVzZXJwdHIuZmxhZ3MgPSBmbGFnczsKCglyZXQgPSBkcm1Jb2N0bChidWZtZ3JfZ2VtLT5mZCwKCQkJRFJNX0lPQ1RMX0k5MTVfR0VNX1VTRVJQVFIsCgkJCSZ1c2VycHRyKTsKCWlmIChyZXQgIT0gMCkgewoJCURCRygiYm9fY3JlYXRlX3VzZXJwdHI6ICIKCQkgICAgImlvY3RsIGZhaWxlZCB3aXRoIHVzZXIgcHRyICVwIHNpemUgMHglbHgsICIKCQkgICAgInVzZXIgZmxhZ3MgMHglbHhcbiIsIGFkZHIsIHNpemUsIGZsYWdzKTsKCQlmcmVlKGJvX2dlbSk7CgkJcmV0dXJuIE5VTEw7Cgl9CgoJYm9fZ2VtLT5nZW1faGFuZGxlID0gdXNlcnB0ci5oYW5kbGU7Cglib19nZW0tPmJvLmhhbmRsZSA9IGJvX2dlbS0+Z2VtX2hhbmRsZTsKCWJvX2dlbS0+Ym8uYnVmbWdyICAgID0gYnVmbWdyOwoJYm9fZ2VtLT5pc191c2VycHRyICAgPSB0cnVlOwoJYm9fZ2VtLT5iby52aXJ0dWFsICAgPSBhZGRyOwoJLyogU2F2ZSB0aGUgYWRkcmVzcyBwcm92aWRlZCBieSB1c2VyICovCglib19nZW0tPnVzZXJfdmlydHVhbCA9IGFkZHI7Cglib19nZW0tPnRpbGluZ19tb2RlICA9IEk5MTVfVElMSU5HX05PTkU7Cglib19nZW0tPnN3aXp6bGVfbW9kZSA9IEk5MTVfQklUXzZfU1dJWlpMRV9OT05FOwoJYm9fZ2VtLT5zdHJpZGUgICAgICAgPSAwOwoKCURSTUlOSVRMSVNUSEVBRCgmYm9fZ2VtLT5uYW1lX2xpc3QpOwoJRFJNSU5JVExJU1RIRUFEKCZib19nZW0tPnZtYV9saXN0KTsKCglib19nZW0tPm5hbWUgPSBuYW1lOwoJYXRvbWljX3NldCgmYm9fZ2VtLT5yZWZjb3VudCwgMSk7Cglib19nZW0tPnZhbGlkYXRlX2luZGV4ID0gLTE7Cglib19nZW0tPnJlbG9jX3RyZWVfZmVuY2VzID0gMDsKCWJvX2dlbS0+dXNlZF9hc19yZWxvY190YXJnZXQgPSBmYWxzZTsKCWJvX2dlbS0+aGFzX2Vycm9yID0gZmFsc2U7Cglib19nZW0tPnJldXNhYmxlID0gZmFsc2U7CgoJZHJtX2ludGVsX2JvX2dlbV9zZXRfaW5fYXBlcnR1cmVfc2l6ZShidWZtZ3JfZ2VtLCBib19nZW0pOwoKCURCRygiYm9fY3JlYXRlX3VzZXJwdHI6ICIKCSAgICAicHRyICVwIGJ1ZiAlZCAoJXMpIHNpemUgJWxkYiwgc3RyaWRlIDB4JXgsIHRpbGUgbW9kZSAlZFxuIiwKCQlhZGRyLCBib19nZW0tPmdlbV9oYW5kbGUsIGJvX2dlbS0+bmFtZSwKCQlzaXplLCBzdHJpZGUsIHRpbGluZ19tb2RlKTsKCglyZXR1cm4gJmJvX2dlbS0+Ym87Cn0KCi8qKgogKiBSZXR1cm5zIGEgZHJtX2ludGVsX2JvIHdyYXBwaW5nIHRoZSBnaXZlbiBidWZmZXIgb2JqZWN0IGhhbmRsZS4KICoKICogVGhpcyBjYW4gYmUgdXNlZCB3aGVuIG9uZSBhcHBsaWNhdGlvbiBuZWVkcyB0byBwYXNzIGEgYnVmZmVyIG9iamVjdAogKiB0byBhbm90aGVyLgogKi8KZHJtX3B1YmxpYyBkcm1faW50ZWxfYm8gKgpkcm1faW50ZWxfYm9fZ2VtX2NyZWF0ZV9mcm9tX25hbWUoZHJtX2ludGVsX2J1Zm1nciAqYnVmbWdyLAoJCQkJICBjb25zdCBjaGFyICpuYW1lLAoJCQkJICB1bnNpZ25lZCBpbnQgaGFuZGxlKQp7Cglkcm1faW50ZWxfYnVmbWdyX2dlbSAqYnVmbWdyX2dlbSA9IChkcm1faW50ZWxfYnVmbWdyX2dlbSAqKSBidWZtZ3I7Cglkcm1faW50ZWxfYm9fZ2VtICpib19nZW07CglpbnQgcmV0OwoJc3RydWN0IGRybV9nZW1fb3BlbiBvcGVuX2FyZzsKCXN0cnVjdCBkcm1faTkxNV9nZW1fZ2V0X3RpbGluZyBnZXRfdGlsaW5nOwoJZHJtTU1MaXN0SGVhZCAqbGlzdDsKCgkvKiBBdCB0aGUgbW9tZW50IG1vc3QgYXBwbGljYXRpb25zIG9ubHkgaGF2ZSBhIGZldyBuYW1lZCBiby4KCSAqIEZvciBpbnN0YW5jZSwgaW4gYSBEUkkgY2xpZW50IG9ubHkgdGhlIHJlbmRlciBidWZmZXJzIHBhc3NlZAoJICogYmV0d2VlbiBYIGFuZCB0aGUgY2xpZW50IGFyZSBuYW1lZC4gQW5kIHNpbmNlIFggcmV0dXJucyB0aGUKCSAqIGFsdGVybmF0aW5nIG5hbWVzIGZvciB0aGUgZnJvbnQvYmFjayBidWZmZXIgYSBsaW5lYXIgc2VhcmNoCgkgKiBwcm92aWRlcyBhIHN1ZmZpY2llbnRseSBmYXN0IG1hdGNoLgoJICovCglwdGhyZWFkX211dGV4X2xvY2soJmJ1Zm1ncl9nZW0tPmxvY2spOwoJZm9yIChsaXN0ID0gYnVmbWdyX2dlbS0+bmFtZWQubmV4dDsKCSAgICAgbGlzdCAhPSAmYnVmbWdyX2dlbS0+bmFtZWQ7CgkgICAgIGxpc3QgPSBsaXN0LT5uZXh0KSB7CgkJYm9fZ2VtID0gRFJNTElTVEVOVFJZKGRybV9pbnRlbF9ib19nZW0sIGxpc3QsIG5hbWVfbGlzdCk7CgkJaWYgKGJvX2dlbS0+Z2xvYmFsX25hbWUgPT0gaGFuZGxlKSB7CgkJCWRybV9pbnRlbF9nZW1fYm9fcmVmZXJlbmNlKCZib19nZW0tPmJvKTsKCQkJcHRocmVhZF9tdXRleF91bmxvY2soJmJ1Zm1ncl9nZW0tPmxvY2spOwoJCQlyZXR1cm4gJmJvX2dlbS0+Ym87CgkJfQoJfQoKCVZHX0NMRUFSKG9wZW5fYXJnKTsKCW9wZW5fYXJnLm5hbWUgPSBoYW5kbGU7CglyZXQgPSBkcm1Jb2N0bChidWZtZ3JfZ2VtLT5mZCwKCQkgICAgICAgRFJNX0lPQ1RMX0dFTV9PUEVOLAoJCSAgICAgICAmb3Blbl9hcmcpOwoJaWYgKHJldCAhPSAwKSB7CgkJREJHKCJDb3VsZG4ndCByZWZlcmVuY2UgJXMgaGFuZGxlIDB4JTA4eDogJXNcbiIsCgkJICAgIG5hbWUsIGhhbmRsZSwgc3RyZXJyb3IoZXJybm8pKTsKCQlwdGhyZWFkX211dGV4X3VubG9jaygmYnVmbWdyX2dlbS0+bG9jayk7CgkJcmV0dXJuIE5VTEw7Cgl9CiAgICAgICAgLyogTm93IHNlZSBpZiBzb21lb25lIGhhcyB1c2VkIGEgcHJpbWUgaGFuZGxlIHRvIGdldCB0aGlzCiAgICAgICAgICogb2JqZWN0IGZyb20gdGhlIGtlcm5lbCBiZWZvcmUgYnkgbG9va2luZyB0aHJvdWdoIHRoZSBsaXN0CiAgICAgICAgICogYWdhaW4gZm9yIGEgbWF0Y2hpbmcgZ2VtX2hhbmRsZQogICAgICAgICAqLwoJZm9yIChsaXN0ID0gYnVmbWdyX2dlbS0+bmFtZWQubmV4dDsKCSAgICAgbGlzdCAhPSAmYnVmbWdyX2dlbS0+bmFtZWQ7CgkgICAgIGxpc3QgPSBsaXN0LT5uZXh0KSB7CgkJYm9fZ2VtID0gRFJNTElTVEVOVFJZKGRybV9pbnRlbF9ib19nZW0sIGxpc3QsIG5hbWVfbGlzdCk7CgkJaWYgKGJvX2dlbS0+Z2VtX2hhbmRsZSA9PSBvcGVuX2FyZy5oYW5kbGUpIHsKCQkJZHJtX2ludGVsX2dlbV9ib19yZWZlcmVuY2UoJmJvX2dlbS0+Ym8pOwoJCQlwdGhyZWFkX211dGV4X3VubG9jaygmYnVmbWdyX2dlbS0+bG9jayk7CgkJCXJldHVybiAmYm9fZ2VtLT5ibzsKCQl9Cgl9CgoJYm9fZ2VtID0gY2FsbG9jKDEsIHNpemVvZigqYm9fZ2VtKSk7CglpZiAoIWJvX2dlbSkgewoJCXB0aHJlYWRfbXV0ZXhfdW5sb2NrKCZidWZtZ3JfZ2VtLT5sb2NrKTsKCQlyZXR1cm4gTlVMTDsKCX0KCglib19nZW0tPmJvLnNpemUgPSBvcGVuX2FyZy5zaXplOwoJYm9fZ2VtLT5iby5vZmZzZXQgPSAwOwoJYm9fZ2VtLT5iby5vZmZzZXQ2NCA9IDA7Cglib19nZW0tPmJvLnZpcnR1YWwgPSBOVUxMOwoJYm9fZ2VtLT5iby5idWZtZ3IgPSBidWZtZ3I7Cglib19nZW0tPm5hbWUgPSBuYW1lOwoJYXRvbWljX3NldCgmYm9fZ2VtLT5yZWZjb3VudCwgMSk7Cglib19nZW0tPnZhbGlkYXRlX2luZGV4ID0gLTE7Cglib19nZW0tPmdlbV9oYW5kbGUgPSBvcGVuX2FyZy5oYW5kbGU7Cglib19nZW0tPmJvLmhhbmRsZSA9IG9wZW5fYXJnLmhhbmRsZTsKCWJvX2dlbS0+Z2xvYmFsX25hbWUgPSBoYW5kbGU7Cglib19nZW0tPnJldXNhYmxlID0gZmFsc2U7CgoJVkdfQ0xFQVIoZ2V0X3RpbGluZyk7CglnZXRfdGlsaW5nLmhhbmRsZSA9IGJvX2dlbS0+Z2VtX2hhbmRsZTsKCXJldCA9IGRybUlvY3RsKGJ1Zm1ncl9nZW0tPmZkLAoJCSAgICAgICBEUk1fSU9DVExfSTkxNV9HRU1fR0VUX1RJTElORywKCQkgICAgICAgJmdldF90aWxpbmcpOwoJaWYgKHJldCAhPSAwKSB7CgkJZHJtX2ludGVsX2dlbV9ib191bnJlZmVyZW5jZSgmYm9fZ2VtLT5ibyk7CgkJcHRocmVhZF9tdXRleF91bmxvY2soJmJ1Zm1ncl9nZW0tPmxvY2spOwoJCXJldHVybiBOVUxMOwoJfQoJYm9fZ2VtLT50aWxpbmdfbW9kZSA9IGdldF90aWxpbmcudGlsaW5nX21vZGU7Cglib19nZW0tPnN3aXp6bGVfbW9kZSA9IGdldF90aWxpbmcuc3dpenpsZV9tb2RlOwoJLyogWFhYIHN0cmlkZSBpcyB1bmtub3duICovCglkcm1faW50ZWxfYm9fZ2VtX3NldF9pbl9hcGVydHVyZV9zaXplKGJ1Zm1ncl9nZW0sIGJvX2dlbSk7CgoJRFJNSU5JVExJU1RIRUFEKCZib19nZW0tPnZtYV9saXN0KTsKCURSTUxJU1RBRERUQUlMKCZib19nZW0tPm5hbWVfbGlzdCwgJmJ1Zm1ncl9nZW0tPm5hbWVkKTsKCXB0aHJlYWRfbXV0ZXhfdW5sb2NrKCZidWZtZ3JfZ2VtLT5sb2NrKTsKCURCRygiYm9fY3JlYXRlX2Zyb21faGFuZGxlOiAlZCAoJXMpXG4iLCBoYW5kbGUsIGJvX2dlbS0+bmFtZSk7CgoJcmV0dXJuICZib19nZW0tPmJvOwp9CgpzdGF0aWMgdm9pZApkcm1faW50ZWxfZ2VtX2JvX2ZyZWUoZHJtX2ludGVsX2JvICpibykKewoJZHJtX2ludGVsX2J1Zm1ncl9nZW0gKmJ1Zm1ncl9nZW0gPSAoZHJtX2ludGVsX2J1Zm1ncl9nZW0gKikgYm8tPmJ1Zm1ncjsKCWRybV9pbnRlbF9ib19nZW0gKmJvX2dlbSA9IChkcm1faW50ZWxfYm9fZ2VtICopIGJvOwoJc3RydWN0IGRybV9nZW1fY2xvc2UgY2xvc2U7CglpbnQgcmV0OwoKCURSTUxJU1RERUwoJmJvX2dlbS0+dm1hX2xpc3QpOwoJaWYgKGJvX2dlbS0+bWVtX3ZpcnR1YWwpIHsKCQlWRyhWQUxHUklORF9GUkVFTElLRV9CTE9DSyhib19nZW0tPm1lbV92aXJ0dWFsLCAwKSk7CgkJZHJtX211bm1hcChib19nZW0tPm1lbV92aXJ0dWFsLCBib19nZW0tPmJvLnNpemUpOwoJCWJ1Zm1ncl9nZW0tPnZtYV9jb3VudC0tOwoJfQoJaWYgKGJvX2dlbS0+Z3R0X3ZpcnR1YWwpIHsKCQlkcm1fbXVubWFwKGJvX2dlbS0+Z3R0X3ZpcnR1YWwsIGJvX2dlbS0+Ym8uc2l6ZSk7CgkJYnVmbWdyX2dlbS0+dm1hX2NvdW50LS07Cgl9CgoJLyogQ2xvc2UgdGhpcyBvYmplY3QgKi8KCVZHX0NMRUFSKGNsb3NlKTsKCWNsb3NlLmhhbmRsZSA9IGJvX2dlbS0+Z2VtX2hhbmRsZTsKCXJldCA9IGRybUlvY3RsKGJ1Zm1ncl9nZW0tPmZkLCBEUk1fSU9DVExfR0VNX0NMT1NFLCAmY2xvc2UpOwoJaWYgKHJldCAhPSAwKSB7CgkJREJHKCJEUk1fSU9DVExfR0VNX0NMT1NFICVkIGZhaWxlZCAoJXMpOiAlc1xuIiwKCQkgICAgYm9fZ2VtLT5nZW1faGFuZGxlLCBib19nZW0tPm5hbWUsIHN0cmVycm9yKGVycm5vKSk7Cgl9CglmcmVlKGJvX2dlbS0+YXViX2Fubm90YXRpb25zKTsKCWZyZWUoYm8pOwp9CgpzdGF0aWMgdm9pZApkcm1faW50ZWxfZ2VtX2JvX21hcmtfbW1hcHNfaW5jb2hlcmVudChkcm1faW50ZWxfYm8gKmJvKQp7CiNpZiBIQVZFX1ZBTEdSSU5ECglkcm1faW50ZWxfYm9fZ2VtICpib19nZW0gPSAoZHJtX2ludGVsX2JvX2dlbSAqKSBibzsKCglpZiAoYm9fZ2VtLT5tZW1fdmlydHVhbCkKCQlWQUxHUklORF9NQUtFX01FTV9OT0FDQ0VTUyhib19nZW0tPm1lbV92aXJ0dWFsLCBiby0+c2l6ZSk7CgoJaWYgKGJvX2dlbS0+Z3R0X3ZpcnR1YWwpCgkJVkFMR1JJTkRfTUFLRV9NRU1fTk9BQ0NFU1MoYm9fZ2VtLT5ndHRfdmlydHVhbCwgYm8tPnNpemUpOwojZW5kaWYKfQoKLyoqIEZyZWVzIGFsbCBjYWNoZWQgYnVmZmVycyBzaWduaWZpY2FudGx5IG9sZGVyIHRoYW4gQHRpbWUuICovCnN0YXRpYyB2b2lkCmRybV9pbnRlbF9nZW1fY2xlYW51cF9ib19jYWNoZShkcm1faW50ZWxfYnVmbWdyX2dlbSAqYnVmbWdyX2dlbSwgdGltZV90IHRpbWUpCnsKCWludCBpOwoKCWlmIChidWZtZ3JfZ2VtLT50aW1lID09IHRpbWUpCgkJcmV0dXJuOwoKCWZvciAoaSA9IDA7IGkgPCBidWZtZ3JfZ2VtLT5udW1fYnVja2V0czsgaSsrKSB7CgkJc3RydWN0IGRybV9pbnRlbF9nZW1fYm9fYnVja2V0ICpidWNrZXQgPQoJCSAgICAmYnVmbWdyX2dlbS0+Y2FjaGVfYnVja2V0W2ldOwoKCQl3aGlsZSAoIURSTUxJU1RFTVBUWSgmYnVja2V0LT5oZWFkKSkgewoJCQlkcm1faW50ZWxfYm9fZ2VtICpib19nZW07CgoJCQlib19nZW0gPSBEUk1MSVNURU5UUlkoZHJtX2ludGVsX2JvX2dlbSwKCQkJCQkgICAgICBidWNrZXQtPmhlYWQubmV4dCwgaGVhZCk7CgkJCWlmICh0aW1lIC0gYm9fZ2VtLT5mcmVlX3RpbWUgPD0gMSkKCQkJCWJyZWFrOwoKCQkJRFJNTElTVERFTCgmYm9fZ2VtLT5oZWFkKTsKCgkJCWRybV9pbnRlbF9nZW1fYm9fZnJlZSgmYm9fZ2VtLT5ibyk7CgkJfQoJfQoKCWJ1Zm1ncl9nZW0tPnRpbWUgPSB0aW1lOwp9CgpzdGF0aWMgdm9pZCBkcm1faW50ZWxfZ2VtX2JvX3B1cmdlX3ZtYV9jYWNoZShkcm1faW50ZWxfYnVmbWdyX2dlbSAqYnVmbWdyX2dlbSkKewoJaW50IGxpbWl0OwoKCURCRygiJXM6IGNhY2hlZD0lZCwgb3Blbj0lZCwgbGltaXQ9JWRcbiIsIF9fRlVOQ1RJT05fXywKCSAgICBidWZtZ3JfZ2VtLT52bWFfY291bnQsIGJ1Zm1ncl9nZW0tPnZtYV9vcGVuLCBidWZtZ3JfZ2VtLT52bWFfbWF4KTsKCglpZiAoYnVmbWdyX2dlbS0+dm1hX21heCA8IDApCgkJcmV0dXJuOwoKCS8qIFdlIG1heSBuZWVkIHRvIGV2aWN0IGEgZmV3IGVudHJpZXMgaW4gb3JkZXIgdG8gY3JlYXRlIG5ldyBtbWFwcyAqLwoJbGltaXQgPSBidWZtZ3JfZ2VtLT52bWFfbWF4IC0gMipidWZtZ3JfZ2VtLT52bWFfb3BlbjsKCWlmIChsaW1pdCA8IDApCgkJbGltaXQgPSAwOwoKCXdoaWxlIChidWZtZ3JfZ2VtLT52bWFfY291bnQgPiBsaW1pdCkgewoJCWRybV9pbnRlbF9ib19nZW0gKmJvX2dlbTsKCgkJYm9fZ2VtID0gRFJNTElTVEVOVFJZKGRybV9pbnRlbF9ib19nZW0sCgkJCQkgICAgICBidWZtZ3JfZ2VtLT52bWFfY2FjaGUubmV4dCwKCQkJCSAgICAgIHZtYV9saXN0KTsKCQlhc3NlcnQoYm9fZ2VtLT5tYXBfY291bnQgPT0gMCk7CgkJRFJNTElTVERFTElOSVQoJmJvX2dlbS0+dm1hX2xpc3QpOwoKCQlpZiAoYm9fZ2VtLT5tZW1fdmlydHVhbCkgewoJCQlkcm1fbXVubWFwKGJvX2dlbS0+bWVtX3ZpcnR1YWwsIGJvX2dlbS0+Ym8uc2l6ZSk7CgkJCWJvX2dlbS0+bWVtX3ZpcnR1YWwgPSBOVUxMOwoJCQlidWZtZ3JfZ2VtLT52bWFfY291bnQtLTsKCQl9CgkJaWYgKGJvX2dlbS0+Z3R0X3ZpcnR1YWwpIHsKCQkJZHJtX211bm1hcChib19nZW0tPmd0dF92aXJ0dWFsLCBib19nZW0tPmJvLnNpemUpOwoJCQlib19nZW0tPmd0dF92aXJ0dWFsID0gTlVMTDsKCQkJYnVmbWdyX2dlbS0+dm1hX2NvdW50LS07CgkJfQoJfQp9CgpzdGF0aWMgdm9pZCBkcm1faW50ZWxfZ2VtX2JvX2Nsb3NlX3ZtYShkcm1faW50ZWxfYnVmbWdyX2dlbSAqYnVmbWdyX2dlbSwKCQkJCSAgICAgICBkcm1faW50ZWxfYm9fZ2VtICpib19nZW0pCnsKCWJ1Zm1ncl9nZW0tPnZtYV9vcGVuLS07CglEUk1MSVNUQUREVEFJTCgmYm9fZ2VtLT52bWFfbGlzdCwgJmJ1Zm1ncl9nZW0tPnZtYV9jYWNoZSk7CglpZiAoYm9fZ2VtLT5tZW1fdmlydHVhbCkKCQlidWZtZ3JfZ2VtLT52bWFfY291bnQrKzsKCWlmIChib19nZW0tPmd0dF92aXJ0dWFsKQoJCWJ1Zm1ncl9nZW0tPnZtYV9jb3VudCsrOwoJZHJtX2ludGVsX2dlbV9ib19wdXJnZV92bWFfY2FjaGUoYnVmbWdyX2dlbSk7Cn0KCnN0YXRpYyB2b2lkIGRybV9pbnRlbF9nZW1fYm9fb3Blbl92bWEoZHJtX2ludGVsX2J1Zm1ncl9nZW0gKmJ1Zm1ncl9nZW0sCgkJCQkgICAgICBkcm1faW50ZWxfYm9fZ2VtICpib19nZW0pCnsKCWJ1Zm1ncl9nZW0tPnZtYV9vcGVuKys7CglEUk1MSVNUREVMKCZib19nZW0tPnZtYV9saXN0KTsKCWlmIChib19nZW0tPm1lbV92aXJ0dWFsKQoJCWJ1Zm1ncl9nZW0tPnZtYV9jb3VudC0tOwoJaWYgKGJvX2dlbS0+Z3R0X3ZpcnR1YWwpCgkJYnVmbWdyX2dlbS0+dm1hX2NvdW50LS07Cglkcm1faW50ZWxfZ2VtX2JvX3B1cmdlX3ZtYV9jYWNoZShidWZtZ3JfZ2VtKTsKfQoKc3RhdGljIHZvaWQKZHJtX2ludGVsX2dlbV9ib191bnJlZmVyZW5jZV9maW5hbChkcm1faW50ZWxfYm8gKmJvLCB0aW1lX3QgdGltZSkKewoJZHJtX2ludGVsX2J1Zm1ncl9nZW0gKmJ1Zm1ncl9nZW0gPSAoZHJtX2ludGVsX2J1Zm1ncl9nZW0gKikgYm8tPmJ1Zm1ncjsKCWRybV9pbnRlbF9ib19nZW0gKmJvX2dlbSA9IChkcm1faW50ZWxfYm9fZ2VtICopIGJvOwoJc3RydWN0IGRybV9pbnRlbF9nZW1fYm9fYnVja2V0ICpidWNrZXQ7CglpbnQgaTsKCgkvKiBVbnJlZmVyZW5jZSBhbGwgdGhlIHRhcmdldCBidWZmZXJzICovCglmb3IgKGkgPSAwOyBpIDwgYm9fZ2VtLT5yZWxvY19jb3VudDsgaSsrKSB7CgkJaWYgKGJvX2dlbS0+cmVsb2NfdGFyZ2V0X2luZm9baV0uYm8gIT0gYm8pIHsKCQkJZHJtX2ludGVsX2dlbV9ib191bnJlZmVyZW5jZV9sb2NrZWRfdGltZWQoYm9fZ2VtLT4KCQkJCQkJCQkgIHJlbG9jX3RhcmdldF9pbmZvW2ldLmJvLAoJCQkJCQkJCSAgdGltZSk7CgkJfQoJfQoJYm9fZ2VtLT5yZWxvY19jb3VudCA9IDA7Cglib19nZW0tPnVzZWRfYXNfcmVsb2NfdGFyZ2V0ID0gZmFsc2U7CgoJREJHKCJib191bnJlZmVyZW5jZSBmaW5hbDogJWQgKCVzKVxuIiwKCSAgICBib19nZW0tPmdlbV9oYW5kbGUsIGJvX2dlbS0+bmFtZSk7CgoJLyogcmVsZWFzZSBtZW1vcnkgYXNzb2NpYXRlZCB3aXRoIHRoaXMgb2JqZWN0ICovCglpZiAoYm9fZ2VtLT5yZWxvY190YXJnZXRfaW5mbykgewoJCWZyZWUoYm9fZ2VtLT5yZWxvY190YXJnZXRfaW5mbyk7CgkJYm9fZ2VtLT5yZWxvY190YXJnZXRfaW5mbyA9IE5VTEw7Cgl9CglpZiAoYm9fZ2VtLT5yZWxvY3MpIHsKCQlmcmVlKGJvX2dlbS0+cmVsb2NzKTsKCQlib19nZW0tPnJlbG9jcyA9IE5VTEw7Cgl9CgoJLyogQ2xlYXIgYW55IGxlZnQtb3ZlciBtYXBwaW5ncyAqLwoJaWYgKGJvX2dlbS0+bWFwX2NvdW50KSB7CgkJREJHKCJibyBmcmVlZCB3aXRoIG5vbi16ZXJvIG1hcC1jb3VudCAlZFxuIiwgYm9fZ2VtLT5tYXBfY291bnQpOwoJCWJvX2dlbS0+bWFwX2NvdW50ID0gMDsKCQlkcm1faW50ZWxfZ2VtX2JvX2Nsb3NlX3ZtYShidWZtZ3JfZ2VtLCBib19nZW0pOwoJCWRybV9pbnRlbF9nZW1fYm9fbWFya19tbWFwc19pbmNvaGVyZW50KGJvKTsKCX0KCglEUk1MSVNUREVMKCZib19nZW0tPm5hbWVfbGlzdCk7CgoJYnVja2V0ID0gZHJtX2ludGVsX2dlbV9ib19idWNrZXRfZm9yX3NpemUoYnVmbWdyX2dlbSwgYm8tPnNpemUpOwoJLyogUHV0IHRoZSBidWZmZXIgaW50byBvdXIgaW50ZXJuYWwgY2FjaGUgZm9yIHJldXNlIGlmIHdlIGNhbi4gKi8KCWlmIChidWZtZ3JfZ2VtLT5ib19yZXVzZSAmJiBib19nZW0tPnJldXNhYmxlICYmIGJ1Y2tldCAhPSBOVUxMICYmCgkgICAgZHJtX2ludGVsX2dlbV9ib19tYWR2aXNlX2ludGVybmFsKGJ1Zm1ncl9nZW0sIGJvX2dlbSwKCQkJCQkgICAgICBJOTE1X01BRFZfRE9OVE5FRUQpKSB7CgkJYm9fZ2VtLT5mcmVlX3RpbWUgPSB0aW1lOwoKCQlib19nZW0tPm5hbWUgPSBOVUxMOwoJCWJvX2dlbS0+dmFsaWRhdGVfaW5kZXggPSAtMTsKCgkJRFJNTElTVEFERFRBSUwoJmJvX2dlbS0+aGVhZCwgJmJ1Y2tldC0+aGVhZCk7Cgl9IGVsc2UgewoJCWRybV9pbnRlbF9nZW1fYm9fZnJlZShibyk7Cgl9Cn0KCnN0YXRpYyB2b2lkIGRybV9pbnRlbF9nZW1fYm9fdW5yZWZlcmVuY2VfbG9ja2VkX3RpbWVkKGRybV9pbnRlbF9ibyAqYm8sCgkJCQkJCSAgICAgIHRpbWVfdCB0aW1lKQp7Cglkcm1faW50ZWxfYm9fZ2VtICpib19nZW0gPSAoZHJtX2ludGVsX2JvX2dlbSAqKSBibzsKCglhc3NlcnQoYXRvbWljX3JlYWQoJmJvX2dlbS0+cmVmY291bnQpID4gMCk7CglpZiAoYXRvbWljX2RlY19hbmRfdGVzdCgmYm9fZ2VtLT5yZWZjb3VudCkpCgkJZHJtX2ludGVsX2dlbV9ib191bnJlZmVyZW5jZV9maW5hbChibywgdGltZSk7Cn0KCnN0YXRpYyB2b2lkIGRybV9pbnRlbF9nZW1fYm9fdW5yZWZlcmVuY2UoZHJtX2ludGVsX2JvICpibykKewoJZHJtX2ludGVsX2JvX2dlbSAqYm9fZ2VtID0gKGRybV9pbnRlbF9ib19nZW0gKikgYm87CgoJYXNzZXJ0KGF0b21pY19yZWFkKCZib19nZW0tPnJlZmNvdW50KSA+IDApOwoKCWlmIChhdG9taWNfYWRkX3VubGVzcygmYm9fZ2VtLT5yZWZjb3VudCwgLTEsIDEpKSB7CgkJZHJtX2ludGVsX2J1Zm1ncl9nZW0gKmJ1Zm1ncl9nZW0gPQoJCSAgICAoZHJtX2ludGVsX2J1Zm1ncl9nZW0gKikgYm8tPmJ1Zm1ncjsKCQlzdHJ1Y3QgdGltZXNwZWMgdGltZTsKCgkJY2xvY2tfZ2V0dGltZShDTE9DS19NT05PVE9OSUMsICZ0aW1lKTsKCgkJcHRocmVhZF9tdXRleF9sb2NrKCZidWZtZ3JfZ2VtLT5sb2NrKTsKCgkJaWYgKGF0b21pY19kZWNfYW5kX3Rlc3QoJmJvX2dlbS0+cmVmY291bnQpKSB7CgkJCWRybV9pbnRlbF9nZW1fYm9fdW5yZWZlcmVuY2VfZmluYWwoYm8sIHRpbWUudHZfc2VjKTsKCQkJZHJtX2ludGVsX2dlbV9jbGVhbnVwX2JvX2NhY2hlKGJ1Zm1ncl9nZW0sIHRpbWUudHZfc2VjKTsKCQl9CgoJCXB0aHJlYWRfbXV0ZXhfdW5sb2NrKCZidWZtZ3JfZ2VtLT5sb2NrKTsKCX0KfQoKc3RhdGljIGludCBkcm1faW50ZWxfZ2VtX2JvX21hcChkcm1faW50ZWxfYm8gKmJvLCBpbnQgd3JpdGVfZW5hYmxlKQp7Cglkcm1faW50ZWxfYnVmbWdyX2dlbSAqYnVmbWdyX2dlbSA9IChkcm1faW50ZWxfYnVmbWdyX2dlbSAqKSBiby0+YnVmbWdyOwoJZHJtX2ludGVsX2JvX2dlbSAqYm9fZ2VtID0gKGRybV9pbnRlbF9ib19nZW0gKikgYm87CglzdHJ1Y3QgZHJtX2k5MTVfZ2VtX3NldF9kb21haW4gc2V0X2RvbWFpbjsKCWludCByZXQ7CgoJaWYgKGJvX2dlbS0+aXNfdXNlcnB0cikgewoJCS8qIFJldHVybiB0aGUgc2FtZSB1c2VyIHB0ciAqLwoJCWJvLT52aXJ0dWFsID0gYm9fZ2VtLT51c2VyX3ZpcnR1YWw7CgkJcmV0dXJuIDA7Cgl9CgoJcHRocmVhZF9tdXRleF9sb2NrKCZidWZtZ3JfZ2VtLT5sb2NrKTsKCglpZiAoYm9fZ2VtLT5tYXBfY291bnQrKyA9PSAwKQoJCWRybV9pbnRlbF9nZW1fYm9fb3Blbl92bWEoYnVmbWdyX2dlbSwgYm9fZ2VtKTsKCglpZiAoIWJvX2dlbS0+bWVtX3ZpcnR1YWwpIHsKCQlzdHJ1Y3QgZHJtX2k5MTVfZ2VtX21tYXAgbW1hcF9hcmc7CgoJCURCRygiYm9fbWFwOiAlZCAoJXMpLCBtYXBfY291bnQ9JWRcbiIsCgkJICAgIGJvX2dlbS0+Z2VtX2hhbmRsZSwgYm9fZ2VtLT5uYW1lLCBib19nZW0tPm1hcF9jb3VudCk7CgoJCVZHX0NMRUFSKG1tYXBfYXJnKTsKCQltbWFwX2FyZy5oYW5kbGUgPSBib19nZW0tPmdlbV9oYW5kbGU7CgkJbW1hcF9hcmcub2Zmc2V0ID0gMDsKCQltbWFwX2FyZy5zaXplID0gYm8tPnNpemU7CgkJcmV0ID0gZHJtSW9jdGwoYnVmbWdyX2dlbS0+ZmQsCgkJCSAgICAgICBEUk1fSU9DVExfSTkxNV9HRU1fTU1BUCwKCQkJICAgICAgICZtbWFwX2FyZyk7CgkJaWYgKHJldCAhPSAwKSB7CgkJCXJldCA9IC1lcnJubzsKCQkJREJHKCIlczolZDogRXJyb3IgbWFwcGluZyBidWZmZXIgJWQgKCVzKTogJXMgLlxuIiwKCQkJICAgIF9fRklMRV9fLCBfX0xJTkVfXywgYm9fZ2VtLT5nZW1faGFuZGxlLAoJCQkgICAgYm9fZ2VtLT5uYW1lLCBzdHJlcnJvcihlcnJubykpOwoJCQlpZiAoLS1ib19nZW0tPm1hcF9jb3VudCA9PSAwKQoJCQkJZHJtX2ludGVsX2dlbV9ib19jbG9zZV92bWEoYnVmbWdyX2dlbSwgYm9fZ2VtKTsKCQkJcHRocmVhZF9tdXRleF91bmxvY2soJmJ1Zm1ncl9nZW0tPmxvY2spOwoJCQlyZXR1cm4gcmV0OwoJCX0KCQlWRyhWQUxHUklORF9NQUxMT0NMSUtFX0JMT0NLKG1tYXBfYXJnLmFkZHJfcHRyLCBtbWFwX2FyZy5zaXplLCAwLCAxKSk7CgkJYm9fZ2VtLT5tZW1fdmlydHVhbCA9ICh2b2lkICopKHVpbnRwdHJfdCkgbW1hcF9hcmcuYWRkcl9wdHI7Cgl9CglEQkcoImJvX21hcDogJWQgKCVzKSAtPiAlcFxuIiwgYm9fZ2VtLT5nZW1faGFuZGxlLCBib19nZW0tPm5hbWUsCgkgICAgYm9fZ2VtLT5tZW1fdmlydHVhbCk7Cgliby0+dmlydHVhbCA9IGJvX2dlbS0+bWVtX3ZpcnR1YWw7CgoJVkdfQ0xFQVIoc2V0X2RvbWFpbik7CglzZXRfZG9tYWluLmhhbmRsZSA9IGJvX2dlbS0+Z2VtX2hhbmRsZTsKCXNldF9kb21haW4ucmVhZF9kb21haW5zID0gSTkxNV9HRU1fRE9NQUlOX0NQVTsKCWlmICh3cml0ZV9lbmFibGUpCgkJc2V0X2RvbWFpbi53cml0ZV9kb21haW4gPSBJOTE1X0dFTV9ET01BSU5fQ1BVOwoJZWxzZQoJCXNldF9kb21haW4ud3JpdGVfZG9tYWluID0gMDsKCXJldCA9IGRybUlvY3RsKGJ1Zm1ncl9nZW0tPmZkLAoJCSAgICAgICBEUk1fSU9DVExfSTkxNV9HRU1fU0VUX0RPTUFJTiwKCQkgICAgICAgJnNldF9kb21haW4pOwoJaWYgKHJldCAhPSAwKSB7CgkJREJHKCIlczolZDogRXJyb3Igc2V0dGluZyB0byBDUFUgZG9tYWluICVkOiAlc1xuIiwKCQkgICAgX19GSUxFX18sIF9fTElORV9fLCBib19nZW0tPmdlbV9oYW5kbGUsCgkJICAgIHN0cmVycm9yKGVycm5vKSk7Cgl9CgoJaWYgKHdyaXRlX2VuYWJsZSkKCQlib19nZW0tPm1hcHBlZF9jcHVfd3JpdGUgPSB0cnVlOwoKCWRybV9pbnRlbF9nZW1fYm9fbWFya19tbWFwc19pbmNvaGVyZW50KGJvKTsKCVZHKFZBTEdSSU5EX01BS0VfTUVNX0RFRklORUQoYm9fZ2VtLT5tZW1fdmlydHVhbCwgYm8tPnNpemUpKTsKCXB0aHJlYWRfbXV0ZXhfdW5sb2NrKCZidWZtZ3JfZ2VtLT5sb2NrKTsKCglyZXR1cm4gMDsKfQoKc3RhdGljIGludAptYXBfZ3R0KGRybV9pbnRlbF9ibyAqYm8pCnsKCWRybV9pbnRlbF9idWZtZ3JfZ2VtICpidWZtZ3JfZ2VtID0gKGRybV9pbnRlbF9idWZtZ3JfZ2VtICopIGJvLT5idWZtZ3I7Cglkcm1faW50ZWxfYm9fZ2VtICpib19nZW0gPSAoZHJtX2ludGVsX2JvX2dlbSAqKSBibzsKCWludCByZXQ7CgoJaWYgKGJvX2dlbS0+aXNfdXNlcnB0cikKCQlyZXR1cm4gLUVJTlZBTDsKCglpZiAoYm9fZ2VtLT5tYXBfY291bnQrKyA9PSAwKQoJCWRybV9pbnRlbF9nZW1fYm9fb3Blbl92bWEoYnVmbWdyX2dlbSwgYm9fZ2VtKTsKCgkvKiBHZXQgYSBtYXBwaW5nIG9mIHRoZSBidWZmZXIgaWYgd2UgaGF2ZW4ndCBiZWZvcmUuICovCglpZiAoYm9fZ2VtLT5ndHRfdmlydHVhbCA9PSBOVUxMKSB7CgkJc3RydWN0IGRybV9pOTE1X2dlbV9tbWFwX2d0dCBtbWFwX2FyZzsKCgkJREJHKCJib19tYXBfZ3R0OiBtbWFwICVkICglcyksIG1hcF9jb3VudD0lZFxuIiwKCQkgICAgYm9fZ2VtLT5nZW1faGFuZGxlLCBib19nZW0tPm5hbWUsIGJvX2dlbS0+bWFwX2NvdW50KTsKCgkJVkdfQ0xFQVIobW1hcF9hcmcpOwoJCW1tYXBfYXJnLmhhbmRsZSA9IGJvX2dlbS0+Z2VtX2hhbmRsZTsKCgkJLyogR2V0IHRoZSBmYWtlIG9mZnNldCBiYWNrLi4uICovCgkJcmV0ID0gZHJtSW9jdGwoYnVmbWdyX2dlbS0+ZmQsCgkJCSAgICAgICBEUk1fSU9DVExfSTkxNV9HRU1fTU1BUF9HVFQsCgkJCSAgICAgICAmbW1hcF9hcmcpOwoJCWlmIChyZXQgIT0gMCkgewoJCQlyZXQgPSAtZXJybm87CgkJCURCRygiJXM6JWQ6IEVycm9yIHByZXBhcmluZyBidWZmZXIgbWFwICVkICglcyk6ICVzIC5cbiIsCgkJCSAgICBfX0ZJTEVfXywgX19MSU5FX18sCgkJCSAgICBib19nZW0tPmdlbV9oYW5kbGUsIGJvX2dlbS0+bmFtZSwKCQkJICAgIHN0cmVycm9yKGVycm5vKSk7CgkJCWlmICgtLWJvX2dlbS0+bWFwX2NvdW50ID09IDApCgkJCQlkcm1faW50ZWxfZ2VtX2JvX2Nsb3NlX3ZtYShidWZtZ3JfZ2VtLCBib19nZW0pOwoJCQlyZXR1cm4gcmV0OwoJCX0KCgkJLyogYW5kIG1tYXAgaXQgKi8KCQlib19nZW0tPmd0dF92aXJ0dWFsID0gZHJtX21tYXAoMCwgYm8tPnNpemUsIFBST1RfUkVBRCB8IFBST1RfV1JJVEUsCgkJCQkJICAgICAgIE1BUF9TSEFSRUQsIGJ1Zm1ncl9nZW0tPmZkLAoJCQkJCSAgICAgICBtbWFwX2FyZy5vZmZzZXQpOwoJCWlmIChib19nZW0tPmd0dF92aXJ0dWFsID09IE1BUF9GQUlMRUQpIHsKCQkJYm9fZ2VtLT5ndHRfdmlydHVhbCA9IE5VTEw7CgkJCXJldCA9IC1lcnJubzsKCQkJREJHKCIlczolZDogRXJyb3IgbWFwcGluZyBidWZmZXIgJWQgKCVzKTogJXMgLlxuIiwKCQkJICAgIF9fRklMRV9fLCBfX0xJTkVfXywKCQkJICAgIGJvX2dlbS0+Z2VtX2hhbmRsZSwgYm9fZ2VtLT5uYW1lLAoJCQkgICAgc3RyZXJyb3IoZXJybm8pKTsKCQkJaWYgKC0tYm9fZ2VtLT5tYXBfY291bnQgPT0gMCkKCQkJCWRybV9pbnRlbF9nZW1fYm9fY2xvc2Vfdm1hKGJ1Zm1ncl9nZW0sIGJvX2dlbSk7CgkJCXJldHVybiByZXQ7CgkJfQoJfQoKCWJvLT52aXJ0dWFsID0gYm9fZ2VtLT5ndHRfdmlydHVhbDsKCglEQkcoImJvX21hcF9ndHQ6ICVkICglcykgLT4gJXBcbiIsIGJvX2dlbS0+Z2VtX2hhbmRsZSwgYm9fZ2VtLT5uYW1lLAoJICAgIGJvX2dlbS0+Z3R0X3ZpcnR1YWwpOwoKCXJldHVybiAwOwp9Cgpkcm1fcHVibGljIGludApkcm1faW50ZWxfZ2VtX2JvX21hcF9ndHQoZHJtX2ludGVsX2JvICpibykKewoJZHJtX2ludGVsX2J1Zm1ncl9nZW0gKmJ1Zm1ncl9nZW0gPSAoZHJtX2ludGVsX2J1Zm1ncl9nZW0gKikgYm8tPmJ1Zm1ncjsKCWRybV9pbnRlbF9ib19nZW0gKmJvX2dlbSA9IChkcm1faW50ZWxfYm9fZ2VtICopIGJvOwoJc3RydWN0IGRybV9pOTE1X2dlbV9zZXRfZG9tYWluIHNldF9kb21haW47CglpbnQgcmV0OwoKCXB0aHJlYWRfbXV0ZXhfbG9jaygmYnVmbWdyX2dlbS0+bG9jayk7CgoJcmV0ID0gbWFwX2d0dChibyk7CglpZiAocmV0KSB7CgkJcHRocmVhZF9tdXRleF91bmxvY2soJmJ1Zm1ncl9nZW0tPmxvY2spOwoJCXJldHVybiByZXQ7Cgl9CgoJLyogTm93IG1vdmUgaXQgdG8gdGhlIEdUVCBkb21haW4gc28gdGhhdCB0aGUgR1BVIGFuZCBDUFUKCSAqIGNhY2hlcyBhcmUgZmx1c2hlZCBhbmQgdGhlIEdQVSBpc24ndCBhY3RpdmVseSB1c2luZyB0aGUKCSAqIGJ1ZmZlci4KCSAqCgkgKiBUaGUgcGFnZWZhdWx0IGhhbmRsZXIgZG9lcyB0aGlzIGRvbWFpbiBjaGFuZ2UgZm9yIHVzIHdoZW4KCSAqIGl0IGhhcyB1bmJvdW5kIHRoZSBCTyBmcm9tIHRoZSBHVFQsIGJ1dCBpdCdzIHVwIHRvIHVzIHRvCgkgKiB0ZWxsIGl0IHdoZW4gd2UncmUgYWJvdXQgdG8gdXNlIHRoaW5ncyBpZiB3ZSBoYWQgZG9uZQoJICogcmVuZGVyaW5nIGFuZCBpdCBzdGlsbCBoYXBwZW5zIHRvIGJlIGJvdW5kIHRvIHRoZSBHVFQuCgkgKi8KCVZHX0NMRUFSKHNldF9kb21haW4pOwoJc2V0X2RvbWFpbi5oYW5kbGUgPSBib19nZW0tPmdlbV9oYW5kbGU7CglzZXRfZG9tYWluLnJlYWRfZG9tYWlucyA9IEk5MTVfR0VNX0RPTUFJTl9HVFQ7CglzZXRfZG9tYWluLndyaXRlX2RvbWFpbiA9IEk5MTVfR0VNX0RPTUFJTl9HVFQ7CglyZXQgPSBkcm1Jb2N0bChidWZtZ3JfZ2VtLT5mZCwKCQkgICAgICAgRFJNX0lPQ1RMX0k5MTVfR0VNX1NFVF9ET01BSU4sCgkJICAgICAgICZzZXRfZG9tYWluKTsKCWlmIChyZXQgIT0gMCkgewoJCURCRygiJXM6JWQ6IEVycm9yIHNldHRpbmcgZG9tYWluICVkOiAlc1xuIiwKCQkgICAgX19GSUxFX18sIF9fTElORV9fLCBib19nZW0tPmdlbV9oYW5kbGUsCgkJICAgIHN0cmVycm9yKGVycm5vKSk7Cgl9CgoJZHJtX2ludGVsX2dlbV9ib19tYXJrX21tYXBzX2luY29oZXJlbnQoYm8pOwoJVkcoVkFMR1JJTkRfTUFLRV9NRU1fREVGSU5FRChib19nZW0tPmd0dF92aXJ0dWFsLCBiby0+c2l6ZSkpOwoJcHRocmVhZF9tdXRleF91bmxvY2soJmJ1Zm1ncl9nZW0tPmxvY2spOwoKCXJldHVybiAwOwp9CgovKioKICogUGVyZm9ybXMgYSBtYXBwaW5nIG9mIHRoZSBidWZmZXIgb2JqZWN0IGxpa2UgdGhlIG5vcm1hbCBHVFQKICogbWFwcGluZywgYnV0IGF2b2lkcyB3YWl0aW5nIGZvciB0aGUgR1BVIHRvIGJlIGRvbmUgcmVhZGluZyBmcm9tIG9yCiAqIHJlbmRlcmluZyB0byB0aGUgYnVmZmVyLgogKgogKiBUaGlzIGlzIHVzZWQgaW4gdGhlIGltcGxlbWVudGF0aW9uIG9mIEdMX0FSQl9tYXBfYnVmZmVyX3JhbmdlOiBUaGUKICogdXNlciBhc2tzIHRvIGNyZWF0ZSBhIGJ1ZmZlciwgdGhlbiBkb2VzIGEgbWFwcGluZywgZmlsbHMgc29tZQogKiBzcGFjZSwgcnVucyBhIGRyYXdpbmcgY29tbWFuZCwgdGhlbiBhc2tzIHRvIG1hcCBpdCBhZ2FpbiB3aXRob3V0CiAqIHN5bmNocm9uaXppbmcgYmVjYXVzZSBpdCBndWFyYW50ZWVzIHRoYXQgaXQgd29uJ3Qgd3JpdGUgb3ZlciB0aGUKICogZGF0YSB0aGF0IHRoZSBHUFUgaXMgYnVzeSB1c2luZyAob3IsIG1vcmUgc3BlY2lmaWNhbGx5LCB0aGF0IGlmIGl0CiAqIGRvZXMgd3JpdGUgb3ZlciB0aGUgZGF0YSwgaXQgYWNrbm93bGVkZ2VzIHRoYXQgcmVuZGVyaW5nIGlzCiAqIHVuZGVmaW5lZCkuCiAqLwoKZHJtX3B1YmxpYyBpbnQKZHJtX2ludGVsX2dlbV9ib19tYXBfdW5zeW5jaHJvbml6ZWQoZHJtX2ludGVsX2JvICpibykKewoJZHJtX2ludGVsX2J1Zm1ncl9nZW0gKmJ1Zm1ncl9nZW0gPSAoZHJtX2ludGVsX2J1Zm1ncl9nZW0gKikgYm8tPmJ1Zm1ncjsKI2lmZGVmIEhBVkVfVkFMR1JJTkQKCWRybV9pbnRlbF9ib19nZW0gKmJvX2dlbSA9IChkcm1faW50ZWxfYm9fZ2VtICopIGJvOwojZW5kaWYKCWludCByZXQ7CgoJLyogSWYgdGhlIENQVSBjYWNoZSBpc24ndCBjb2hlcmVudCB3aXRoIHRoZSBHVFQsIHRoZW4gdXNlIGEKCSAqIHJlZ3VsYXIgc3luY2hyb25pemVkIG1hcHBpbmcuICBUaGUgcHJvYmxlbSBpcyB0aGF0IHdlIGRvbid0CgkgKiB0cmFjayB3aGVyZSB0aGUgYnVmZmVyIHdhcyBsYXN0IHVzZWQgb24gdGhlIENQVSBzaWRlIGluCgkgKiB0ZXJtcyBvZiBkcm1faW50ZWxfYm9fbWFwIHZzIGRybV9pbnRlbF9nZW1fYm9fbWFwX2d0dCwgc28KCSAqIHdlIHdvdWxkIHBvdGVudGlhbGx5IGNvcnJ1cHQgdGhlIGJ1ZmZlciBldmVuIHdoZW4gdGhlIHVzZXIKCSAqIGRvZXMgcmVhc29uYWJsZSB0aGluZ3MuCgkgKi8KCWlmICghYnVmbWdyX2dlbS0+aGFzX2xsYykKCQlyZXR1cm4gZHJtX2ludGVsX2dlbV9ib19tYXBfZ3R0KGJvKTsKCglwdGhyZWFkX211dGV4X2xvY2soJmJ1Zm1ncl9nZW0tPmxvY2spOwoKCXJldCA9IG1hcF9ndHQoYm8pOwoJaWYgKHJldCA9PSAwKSB7CgkJZHJtX2ludGVsX2dlbV9ib19tYXJrX21tYXBzX2luY29oZXJlbnQoYm8pOwoJCVZHKFZBTEdSSU5EX01BS0VfTUVNX0RFRklORUQoYm9fZ2VtLT5ndHRfdmlydHVhbCwgYm8tPnNpemUpKTsKCX0KCglwdGhyZWFkX211dGV4X3VubG9jaygmYnVmbWdyX2dlbS0+bG9jayk7CgoJcmV0dXJuIHJldDsKfQoKc3RhdGljIGludCBkcm1faW50ZWxfZ2VtX2JvX3VubWFwKGRybV9pbnRlbF9ibyAqYm8pCnsKCWRybV9pbnRlbF9idWZtZ3JfZ2VtICpidWZtZ3JfZ2VtOwoJZHJtX2ludGVsX2JvX2dlbSAqYm9fZ2VtID0gKGRybV9pbnRlbF9ib19nZW0gKikgYm87CglpbnQgcmV0ID0gMDsKCglpZiAoYm8gPT0gTlVMTCkKCQlyZXR1cm4gMDsKCglpZiAoYm9fZ2VtLT5pc191c2VycHRyKQoJCXJldHVybiAwOwoKCWJ1Zm1ncl9nZW0gPSAoZHJtX2ludGVsX2J1Zm1ncl9nZW0gKikgYm8tPmJ1Zm1ncjsKCglwdGhyZWFkX211dGV4X2xvY2soJmJ1Zm1ncl9nZW0tPmxvY2spOwoKCWlmIChib19nZW0tPm1hcF9jb3VudCA8PSAwKSB7CgkJREJHKCJhdHRlbXB0ZWQgdG8gdW5tYXAgYW4gdW5tYXBwZWQgYm9cbiIpOwoJCXB0aHJlYWRfbXV0ZXhfdW5sb2NrKCZidWZtZ3JfZ2VtLT5sb2NrKTsKCQkvKiBQcmVzZXJ2ZSB0aGUgb2xkIGJlaGF2aW91ciBvZiBqdXN0IHRyZWF0aW5nIHRoaXMgYXMgYQoJCSAqIG5vLW9wIHJhdGhlciB0aGFuIHJlcG9ydGluZyB0aGUgZXJyb3IuCgkJICovCgkJcmV0dXJuIDA7Cgl9CgoJaWYgKGJvX2dlbS0+bWFwcGVkX2NwdV93cml0ZSkgewoJCXN0cnVjdCBkcm1faTkxNV9nZW1fc3dfZmluaXNoIHN3X2ZpbmlzaDsKCgkJLyogQ2F1c2UgYSBmbHVzaCB0byBoYXBwZW4gaWYgdGhlIGJ1ZmZlcidzIHBpbm5lZCBmb3IKCQkgKiBzY2Fub3V0LCBzbyB0aGUgcmVzdWx0cyBzaG93IHVwIGluIGEgdGltZWx5IG1hbm5lci4KCQkgKiBVbmxpa2UgR1RUIHNldCBkb21haW5zLCB0aGlzIG9ubHkgZG9lcyB3b3JrIGlmIHRoZQoJCSAqIGJ1ZmZlciBzaG91bGQgYmUgc2Nhbm91dC1yZWxhdGVkLgoJCSAqLwoJCVZHX0NMRUFSKHN3X2ZpbmlzaCk7CgkJc3dfZmluaXNoLmhhbmRsZSA9IGJvX2dlbS0+Z2VtX2hhbmRsZTsKCQlyZXQgPSBkcm1Jb2N0bChidWZtZ3JfZ2VtLT5mZCwKCQkJICAgICAgIERSTV9JT0NUTF9JOTE1X0dFTV9TV19GSU5JU0gsCgkJCSAgICAgICAmc3dfZmluaXNoKTsKCQlyZXQgPSByZXQgPT0gLTEgPyAtZXJybm8gOiAwOwoKCQlib19nZW0tPm1hcHBlZF9jcHVfd3JpdGUgPSBmYWxzZTsKCX0KCgkvKiBXZSBuZWVkIHRvIHVubWFwIGFmdGVyIGV2ZXJ5IGlubm92YXRpb24gYXMgd2UgY2Fubm90IHRyYWNrCgkgKiBhbiBvcGVuIHZtYSBmb3IgZXZlcnkgYm8gYXMgdGhhdCB3aWxsIGV4aGFhc3V0IHRoZSBzeXN0ZW0KCSAqIGxpbWl0cyBhbmQgY2F1c2UgbGF0ZXIgZmFpbHVyZXMuCgkgKi8KCWlmICgtLWJvX2dlbS0+bWFwX2NvdW50ID09IDApIHsKCQlkcm1faW50ZWxfZ2VtX2JvX2Nsb3NlX3ZtYShidWZtZ3JfZ2VtLCBib19nZW0pOwoJCWRybV9pbnRlbF9nZW1fYm9fbWFya19tbWFwc19pbmNvaGVyZW50KGJvKTsKCQliby0+dmlydHVhbCA9IE5VTEw7Cgl9CglwdGhyZWFkX211dGV4X3VubG9jaygmYnVmbWdyX2dlbS0+bG9jayk7CgoJcmV0dXJuIHJldDsKfQoKZHJtX3B1YmxpYyBpbnQKZHJtX2ludGVsX2dlbV9ib191bm1hcF9ndHQoZHJtX2ludGVsX2JvICpibykKewoJcmV0dXJuIGRybV9pbnRlbF9nZW1fYm9fdW5tYXAoYm8pOwp9CgpzdGF0aWMgaW50CmRybV9pbnRlbF9nZW1fYm9fc3ViZGF0YShkcm1faW50ZWxfYm8gKmJvLCB1bnNpZ25lZCBsb25nIG9mZnNldCwKCQkJIHVuc2lnbmVkIGxvbmcgc2l6ZSwgY29uc3Qgdm9pZCAqZGF0YSkKewoJZHJtX2ludGVsX2J1Zm1ncl9nZW0gKmJ1Zm1ncl9nZW0gPSAoZHJtX2ludGVsX2J1Zm1ncl9nZW0gKikgYm8tPmJ1Zm1ncjsKCWRybV9pbnRlbF9ib19nZW0gKmJvX2dlbSA9IChkcm1faW50ZWxfYm9fZ2VtICopIGJvOwoJc3RydWN0IGRybV9pOTE1X2dlbV9wd3JpdGUgcHdyaXRlOwoJaW50IHJldDsKCglpZiAoYm9fZ2VtLT5pc191c2VycHRyKQoJCXJldHVybiAtRUlOVkFMOwoKCVZHX0NMRUFSKHB3cml0ZSk7Cglwd3JpdGUuaGFuZGxlID0gYm9fZ2VtLT5nZW1faGFuZGxlOwoJcHdyaXRlLm9mZnNldCA9IG9mZnNldDsKCXB3cml0ZS5zaXplID0gc2l6ZTsKCXB3cml0ZS5kYXRhX3B0ciA9ICh1aW50NjRfdCkgKHVpbnRwdHJfdCkgZGF0YTsKCXJldCA9IGRybUlvY3RsKGJ1Zm1ncl9nZW0tPmZkLAoJCSAgICAgICBEUk1fSU9DVExfSTkxNV9HRU1fUFdSSVRFLAoJCSAgICAgICAmcHdyaXRlKTsKCWlmIChyZXQgIT0gMCkgewoJCXJldCA9IC1lcnJubzsKCQlEQkcoIiVzOiVkOiBFcnJvciB3cml0aW5nIGRhdGEgdG8gYnVmZmVyICVkOiAoJWQgJWQpICVzIC5cbiIsCgkJICAgIF9fRklMRV9fLCBfX0xJTkVfXywgYm9fZ2VtLT5nZW1faGFuZGxlLCAoaW50KW9mZnNldCwKCQkgICAgKGludClzaXplLCBzdHJlcnJvcihlcnJubykpOwoJfQoKCXJldHVybiByZXQ7Cn0KCnN0YXRpYyBpbnQKZHJtX2ludGVsX2dlbV9nZXRfcGlwZV9mcm9tX2NydGNfaWQoZHJtX2ludGVsX2J1Zm1nciAqYnVmbWdyLCBpbnQgY3J0Y19pZCkKewoJZHJtX2ludGVsX2J1Zm1ncl9nZW0gKmJ1Zm1ncl9nZW0gPSAoZHJtX2ludGVsX2J1Zm1ncl9nZW0gKikgYnVmbWdyOwoJc3RydWN0IGRybV9pOTE1X2dldF9waXBlX2Zyb21fY3J0Y19pZCBnZXRfcGlwZV9mcm9tX2NydGNfaWQ7CglpbnQgcmV0OwoKCVZHX0NMRUFSKGdldF9waXBlX2Zyb21fY3J0Y19pZCk7CglnZXRfcGlwZV9mcm9tX2NydGNfaWQuY3J0Y19pZCA9IGNydGNfaWQ7CglyZXQgPSBkcm1Jb2N0bChidWZtZ3JfZ2VtLT5mZCwKCQkgICAgICAgRFJNX0lPQ1RMX0k5MTVfR0VUX1BJUEVfRlJPTV9DUlRDX0lELAoJCSAgICAgICAmZ2V0X3BpcGVfZnJvbV9jcnRjX2lkKTsKCWlmIChyZXQgIT0gMCkgewoJCS8qIFdlIHJldHVybiAtMSBoZXJlIHRvIHNpZ25hbCB0aGF0IHdlIGRvbid0CgkJICoga25vdyB3aGljaCBwaXBlIGlzIGFzc29jaWF0ZWQgd2l0aCB0aGlzIGNydGMuCgkJICogVGhpcyBsZXRzIHRoZSBjYWxsZXIga25vdyB0aGF0IHRoaXMgaW5mb3JtYXRpb24KCQkgKiBpc24ndCBhdmFpbGFibGU7IHVzaW5nIHRoZSB3cm9uZyBwaXBlIGZvcgoJCSAqIHZibGFuayB3YWl0aW5nIGNhbiBjYXVzZSB0aGUgY2hpcHNldCB0byBsb2NrIHVwCgkJICovCgkJcmV0dXJuIC0xOwoJfQoKCXJldHVybiBnZXRfcGlwZV9mcm9tX2NydGNfaWQucGlwZTsKfQoKc3RhdGljIGludApkcm1faW50ZWxfZ2VtX2JvX2dldF9zdWJkYXRhKGRybV9pbnRlbF9ibyAqYm8sIHVuc2lnbmVkIGxvbmcgb2Zmc2V0LAoJCQkgICAgIHVuc2lnbmVkIGxvbmcgc2l6ZSwgdm9pZCAqZGF0YSkKewoJZHJtX2ludGVsX2J1Zm1ncl9nZW0gKmJ1Zm1ncl9nZW0gPSAoZHJtX2ludGVsX2J1Zm1ncl9nZW0gKikgYm8tPmJ1Zm1ncjsKCWRybV9pbnRlbF9ib19nZW0gKmJvX2dlbSA9IChkcm1faW50ZWxfYm9fZ2VtICopIGJvOwoJc3RydWN0IGRybV9pOTE1X2dlbV9wcmVhZCBwcmVhZDsKCWludCByZXQ7CgoJaWYgKGJvX2dlbS0+aXNfdXNlcnB0cikKCQlyZXR1cm4gLUVJTlZBTDsKCglWR19DTEVBUihwcmVhZCk7CglwcmVhZC5oYW5kbGUgPSBib19nZW0tPmdlbV9oYW5kbGU7CglwcmVhZC5vZmZzZXQgPSBvZmZzZXQ7CglwcmVhZC5zaXplID0gc2l6ZTsKCXByZWFkLmRhdGFfcHRyID0gKHVpbnQ2NF90KSAodWludHB0cl90KSBkYXRhOwoJcmV0ID0gZHJtSW9jdGwoYnVmbWdyX2dlbS0+ZmQsCgkJICAgICAgIERSTV9JT0NUTF9JOTE1X0dFTV9QUkVBRCwKCQkgICAgICAgJnByZWFkKTsKCWlmIChyZXQgIT0gMCkgewoJCXJldCA9IC1lcnJubzsKCQlEQkcoIiVzOiVkOiBFcnJvciByZWFkaW5nIGRhdGEgZnJvbSBidWZmZXIgJWQ6ICglZCAlZCkgJXMgLlxuIiwKCQkgICAgX19GSUxFX18sIF9fTElORV9fLCBib19nZW0tPmdlbV9oYW5kbGUsIChpbnQpb2Zmc2V0LAoJCSAgICAoaW50KXNpemUsIHN0cmVycm9yKGVycm5vKSk7Cgl9CgoJcmV0dXJuIHJldDsKfQoKLyoqIFdhaXRzIGZvciBhbGwgR1BVIHJlbmRlcmluZyB3aXRoIHRoZSBvYmplY3QgdG8gaGF2ZSBjb21wbGV0ZWQuICovCnN0YXRpYyB2b2lkCmRybV9pbnRlbF9nZW1fYm9fd2FpdF9yZW5kZXJpbmcoZHJtX2ludGVsX2JvICpibykKewoJZHJtX2ludGVsX2dlbV9ib19zdGFydF9ndHRfYWNjZXNzKGJvLCAxKTsKfQoKLyoqCiAqIFdhaXRzIG9uIGEgQk8gZm9yIHRoZSBnaXZlbiBhbW91bnQgb2YgdGltZS4KICoKICogQGJvOiBidWZmZXIgb2JqZWN0IHRvIHdhaXQgZm9yCiAqIEB0aW1lb3V0X25zOiBhbW91bnQgb2YgdGltZSB0byB3YWl0IGluIG5hbm9zZWNvbmRzLgogKiAgIElmIHZhbHVlIGlzIGxlc3MgdGhhbiAwLCBhbiBpbmZpbml0ZSB3YWl0IHdpbGwgb2NjdXIuCiAqCiAqIFJldHVybnMgMCBpZiB0aGUgd2FpdCB3YXMgc3VjY2Vzc2Z1bCBpZS4gdGhlIGxhc3QgYmF0Y2ggcmVmZXJlbmNpbmcgdGhlCiAqIG9iamVjdCBoYXMgY29tcGxldGVkIHdpdGhpbiB0aGUgYWxsb3R0ZWQgdGltZS4gT3RoZXJ3aXNlIHNvbWUgbmVnYXRpdmUgcmV0dXJuCiAqIHZhbHVlIGRlc2NyaWJlcyB0aGUgZXJyb3IuIE9mIHBhcnRpY3VsYXIgaW50ZXJlc3QgaXMgLUVUSU1FIHdoZW4gdGhlIHdhaXQgaGFzCiAqIGZhaWxlZCB0byB5aWVsZCB0aGUgZGVzaXJlZCByZXN1bHQuCiAqCiAqIFNpbWlsYXIgdG8gZHJtX2ludGVsX2dlbV9ib193YWl0X3JlbmRlcmluZyBleGNlcHQgYSB0aW1lb3V0IHBhcmFtZXRlciBhbGxvd3MKICogdGhlIG9wZXJhdGlvbiB0byBnaXZlIHVwIGFmdGVyIGEgY2VydGFpbiBhbW91bnQgb2YgdGltZS4gQW5vdGhlciBzdWJ0bGUKICogZGlmZmVyZW5jZSBpcyB0aGUgaW50ZXJuYWwgbG9ja2luZyBzZW1hbnRpY3MgYXJlIGRpZmZlcmVudCAodGhpcyB2YXJpYW50IGRvZXMKICogbm90IGhvbGQgdGhlIGxvY2sgZm9yIHRoZSBkdXJhdGlvbiBvZiB0aGUgd2FpdCkuIFRoaXMgbWFrZXMgdGhlIHdhaXQgc3ViamVjdAogKiB0byBhIGxhcmdlciB1c2Vyc3BhY2UgcmFjZSB3aW5kb3cuCiAqCiAqIFRoZSBpbXBsZW1lbnRhdGlvbiBzaGFsbCB3YWl0IHVudGlsIHRoZSBvYmplY3QgaXMgbm8gbG9uZ2VyIGFjdGl2ZWx5CiAqIHJlZmVyZW5jZWQgd2l0aGluIGEgYmF0Y2ggYnVmZmVyIGF0IHRoZSB0aW1lIG9mIHRoZSBjYWxsLiBUaGUgd2FpdCB3aWxsCiAqIG5vdCBndWFyYW50ZWUgdGhhdCB0aGUgYnVmZmVyIGlzIHJlLWlzc3VlZCB2aWEgYW5vdGhlciB0aHJlYWQsIG9yIGFuIGZsaW5rZWQKICogaGFuZGxlLiBVc2Vyc3BhY2UgbXVzdCBtYWtlIHN1cmUgdGhpcyByYWNlIGRvZXMgbm90IG9jY3VyIGlmIHN1Y2ggcHJlY2lzaW9uCiAqIGlzIGltcG9ydGFudC4KICovCmRybV9wdWJsaWMgaW50CmRybV9pbnRlbF9nZW1fYm9fd2FpdChkcm1faW50ZWxfYm8gKmJvLCBpbnQ2NF90IHRpbWVvdXRfbnMpCnsKCWRybV9pbnRlbF9idWZtZ3JfZ2VtICpidWZtZ3JfZ2VtID0gKGRybV9pbnRlbF9idWZtZ3JfZ2VtICopIGJvLT5idWZtZ3I7Cglkcm1faW50ZWxfYm9fZ2VtICpib19nZW0gPSAoZHJtX2ludGVsX2JvX2dlbSAqKSBibzsKCXN0cnVjdCBkcm1faTkxNV9nZW1fd2FpdCB3YWl0OwoJaW50IHJldDsKCglpZiAoIWJ1Zm1ncl9nZW0tPmhhc193YWl0X3RpbWVvdXQpIHsKCQlEQkcoIiVzOiVkOiBUaW1lZCB3YWl0IGlzIG5vdCBzdXBwb3J0ZWQuIEZhbGxpbmcgYmFjayB0byAiCgkJICAgICJpbmZpbml0ZSB3YWl0XG4iLCBfX0ZJTEVfXywgX19MSU5FX18pOwoJCWlmICh0aW1lb3V0X25zKSB7CgkJCWRybV9pbnRlbF9nZW1fYm9fd2FpdF9yZW5kZXJpbmcoYm8pOwoJCQlyZXR1cm4gMDsKCQl9IGVsc2UgewoJCQlyZXR1cm4gZHJtX2ludGVsX2dlbV9ib19idXN5KGJvKSA/IC1FVElNRSA6IDA7CgkJfQoJfQoKCXdhaXQuYm9faGFuZGxlID0gYm9fZ2VtLT5nZW1faGFuZGxlOwoJd2FpdC50aW1lb3V0X25zID0gdGltZW91dF9uczsKCXdhaXQuZmxhZ3MgPSAwOwoJcmV0ID0gZHJtSW9jdGwoYnVmbWdyX2dlbS0+ZmQsIERSTV9JT0NUTF9JOTE1X0dFTV9XQUlULCAmd2FpdCk7CglpZiAocmV0ID09IC0xKQoJCXJldHVybiAtZXJybm87CgoJcmV0dXJuIHJldDsKfQoKLyoqCiAqIFNldHMgdGhlIG9iamVjdCB0byB0aGUgR1RUIHJlYWQgYW5kIHBvc3NpYmx5IHdyaXRlIGRvbWFpbiwgdXNlZCBieSB0aGUgWAogKiAyRCBkcml2ZXIgaW4gdGhlIGFic2VuY2Ugb2Yga2VybmVsIHN1cHBvcnQgdG8gZG8gZHJtX2ludGVsX2dlbV9ib19tYXBfZ3R0KCkuCiAqCiAqIEluIGNvbWJpbmF0aW9uIHdpdGggZHJtX2ludGVsX2dlbV9ib19waW4oKSBhbmQgbWFudWFsIGZlbmNlIG1hbmFnZW1lbnQsIHdlCiAqIGNhbiBkbyB0aWxlZCBwaXhtYXBzIHRoaXMgd2F5LgogKi8KZHJtX3B1YmxpYyB2b2lkCmRybV9pbnRlbF9nZW1fYm9fc3RhcnRfZ3R0X2FjY2Vzcyhkcm1faW50ZWxfYm8gKmJvLCBpbnQgd3JpdGVfZW5hYmxlKQp7Cglkcm1faW50ZWxfYnVmbWdyX2dlbSAqYnVmbWdyX2dlbSA9IChkcm1faW50ZWxfYnVmbWdyX2dlbSAqKSBiby0+YnVmbWdyOwoJZHJtX2ludGVsX2JvX2dlbSAqYm9fZ2VtID0gKGRybV9pbnRlbF9ib19nZW0gKikgYm87CglzdHJ1Y3QgZHJtX2k5MTVfZ2VtX3NldF9kb21haW4gc2V0X2RvbWFpbjsKCWludCByZXQ7CgoJVkdfQ0xFQVIoc2V0X2RvbWFpbik7CglzZXRfZG9tYWluLmhhbmRsZSA9IGJvX2dlbS0+Z2VtX2hhbmRsZTsKCXNldF9kb21haW4ucmVhZF9kb21haW5zID0gSTkxNV9HRU1fRE9NQUlOX0dUVDsKCXNldF9kb21haW4ud3JpdGVfZG9tYWluID0gd3JpdGVfZW5hYmxlID8gSTkxNV9HRU1fRE9NQUlOX0dUVCA6IDA7CglyZXQgPSBkcm1Jb2N0bChidWZtZ3JfZ2VtLT5mZCwKCQkgICAgICAgRFJNX0lPQ1RMX0k5MTVfR0VNX1NFVF9ET01BSU4sCgkJICAgICAgICZzZXRfZG9tYWluKTsKCWlmIChyZXQgIT0gMCkgewoJCURCRygiJXM6JWQ6IEVycm9yIHNldHRpbmcgbWVtb3J5IGRvbWFpbnMgJWQgKCUwOHggJTA4eCk6ICVzIC5cbiIsCgkJICAgIF9fRklMRV9fLCBfX0xJTkVfXywgYm9fZ2VtLT5nZW1faGFuZGxlLAoJCSAgICBzZXRfZG9tYWluLnJlYWRfZG9tYWlucywgc2V0X2RvbWFpbi53cml0ZV9kb21haW4sCgkJICAgIHN0cmVycm9yKGVycm5vKSk7Cgl9Cn0KCnN0YXRpYyB2b2lkCmRybV9pbnRlbF9idWZtZ3JfZ2VtX2Rlc3Ryb3koZHJtX2ludGVsX2J1Zm1nciAqYnVmbWdyKQp7Cglkcm1faW50ZWxfYnVmbWdyX2dlbSAqYnVmbWdyX2dlbSA9IChkcm1faW50ZWxfYnVmbWdyX2dlbSAqKSBidWZtZ3I7CglpbnQgaTsKCglmcmVlKGJ1Zm1ncl9nZW0tPmV4ZWMyX29iamVjdHMpOwoJZnJlZShidWZtZ3JfZ2VtLT5leGVjX29iamVjdHMpOwoJZnJlZShidWZtZ3JfZ2VtLT5leGVjX2Jvcyk7CglmcmVlKGJ1Zm1ncl9nZW0tPmF1Yl9maWxlbmFtZSk7CgoJcHRocmVhZF9tdXRleF9kZXN0cm95KCZidWZtZ3JfZ2VtLT5sb2NrKTsKCgkvKiBGcmVlIGFueSBjYWNoZWQgYnVmZmVyIG9iamVjdHMgd2Ugd2VyZSBnb2luZyB0byByZXVzZSAqLwoJZm9yIChpID0gMDsgaSA8IGJ1Zm1ncl9nZW0tPm51bV9idWNrZXRzOyBpKyspIHsKCQlzdHJ1Y3QgZHJtX2ludGVsX2dlbV9ib19idWNrZXQgKmJ1Y2tldCA9CgkJICAgICZidWZtZ3JfZ2VtLT5jYWNoZV9idWNrZXRbaV07CgkJZHJtX2ludGVsX2JvX2dlbSAqYm9fZ2VtOwoKCQl3aGlsZSAoIURSTUxJU1RFTVBUWSgmYnVja2V0LT5oZWFkKSkgewoJCQlib19nZW0gPSBEUk1MSVNURU5UUlkoZHJtX2ludGVsX2JvX2dlbSwKCQkJCQkgICAgICBidWNrZXQtPmhlYWQubmV4dCwgaGVhZCk7CgkJCURSTUxJU1RERUwoJmJvX2dlbS0+aGVhZCk7CgoJCQlkcm1faW50ZWxfZ2VtX2JvX2ZyZWUoJmJvX2dlbS0+Ym8pOwoJCX0KCX0KCglmcmVlKGJ1Zm1ncik7Cn0KCi8qKgogKiBBZGRzIHRoZSB0YXJnZXQgYnVmZmVyIHRvIHRoZSB2YWxpZGF0aW9uIGxpc3QgYW5kIGFkZHMgdGhlIHJlbG9jYXRpb24KICogdG8gdGhlIHJlbG9jX2J1ZmZlcidzIHJlbG9jYXRpb24gbGlzdC4KICoKICogVGhlIHJlbG9jYXRpb24gZW50cnkgYXQgdGhlIGdpdmVuIG9mZnNldCBtdXN0IGFscmVhZHkgY29udGFpbiB0aGUKICogcHJlY29tcHV0ZWQgcmVsb2NhdGlvbiB2YWx1ZSwgYmVjYXVzZSB0aGUga2VybmVsIHdpbGwgb3B0aW1pemUgb3V0CiAqIHRoZSByZWxvY2F0aW9uIGVudHJ5IHdyaXRlIHdoZW4gdGhlIGJ1ZmZlciBoYXNuJ3QgbW92ZWQgZnJvbSB0aGUKICogbGFzdCBrbm93biBvZmZzZXQgaW4gdGFyZ2V0X2JvLgogKi8Kc3RhdGljIGludApkb19ib19lbWl0X3JlbG9jKGRybV9pbnRlbF9ibyAqYm8sIHVpbnQzMl90IG9mZnNldCwKCQkgZHJtX2ludGVsX2JvICp0YXJnZXRfYm8sIHVpbnQzMl90IHRhcmdldF9vZmZzZXQsCgkJIHVpbnQzMl90IHJlYWRfZG9tYWlucywgdWludDMyX3Qgd3JpdGVfZG9tYWluLAoJCSBib29sIG5lZWRfZmVuY2UpCnsKCWRybV9pbnRlbF9idWZtZ3JfZ2VtICpidWZtZ3JfZ2VtID0gKGRybV9pbnRlbF9idWZtZ3JfZ2VtICopIGJvLT5idWZtZ3I7Cglkcm1faW50ZWxfYm9fZ2VtICpib19nZW0gPSAoZHJtX2ludGVsX2JvX2dlbSAqKSBibzsKCWRybV9pbnRlbF9ib19nZW0gKnRhcmdldF9ib19nZW0gPSAoZHJtX2ludGVsX2JvX2dlbSAqKSB0YXJnZXRfYm87Cglib29sIGZlbmNlZF9jb21tYW5kOwoKCWlmIChib19nZW0tPmhhc19lcnJvcikKCQlyZXR1cm4gLUVOT01FTTsKCglpZiAodGFyZ2V0X2JvX2dlbS0+aGFzX2Vycm9yKSB7CgkJYm9fZ2VtLT5oYXNfZXJyb3IgPSB0cnVlOwoJCXJldHVybiAtRU5PTUVNOwoJfQoKCS8qIFdlIG5ldmVyIHVzZSBIVyBmZW5jZXMgZm9yIHJlbmRlcmluZyBvbiA5NjUrICovCglpZiAoYnVmbWdyX2dlbS0+Z2VuID49IDQpCgkJbmVlZF9mZW5jZSA9IGZhbHNlOwoKCWZlbmNlZF9jb21tYW5kID0gbmVlZF9mZW5jZTsKCWlmICh0YXJnZXRfYm9fZ2VtLT50aWxpbmdfbW9kZSA9PSBJOTE1X1RJTElOR19OT05FKQoJCW5lZWRfZmVuY2UgPSBmYWxzZTsKCgkvKiBDcmVhdGUgYSBuZXcgcmVsb2NhdGlvbiBsaXN0IGlmIG5lZWRlZCAqLwoJaWYgKGJvX2dlbS0+cmVsb2NzID09IE5VTEwgJiYgZHJtX2ludGVsX3NldHVwX3JlbG9jX2xpc3QoYm8pKQoJCXJldHVybiAtRU5PTUVNOwoKCS8qIENoZWNrIG92ZXJmbG93ICovCglhc3NlcnQoYm9fZ2VtLT5yZWxvY19jb3VudCA8IGJ1Zm1ncl9nZW0tPm1heF9yZWxvY3MpOwoKCS8qIENoZWNrIGFyZ3MgKi8KCWFzc2VydChvZmZzZXQgPD0gYm8tPnNpemUgLSA0KTsKCWFzc2VydCgod3JpdGVfZG9tYWluICYgKHdyaXRlX2RvbWFpbiAtIDEpKSA9PSAwKTsKCgkvKiBBbiBvYmplY3QgbmVlZGluZyBhIGZlbmNlIGlzIGEgdGlsZWQgYnVmZmVyLCBzbyBpdCB3b24ndCBoYXZlCgkgKiByZWxvY3MgdG8gb3RoZXIgYnVmZmVycy4KCSAqLwoJaWYgKG5lZWRfZmVuY2UpIHsKCQlhc3NlcnQodGFyZ2V0X2JvX2dlbS0+cmVsb2NfY291bnQgPT0gMCk7CgkJdGFyZ2V0X2JvX2dlbS0+cmVsb2NfdHJlZV9mZW5jZXMgPSAxOwoJfQoKCS8qIE1ha2Ugc3VyZSB0aGF0IHdlJ3JlIG5vdCBhZGRpbmcgYSByZWxvYyB0byBzb21ldGhpbmcgd2hvc2Ugc2l6ZSBoYXMKCSAqIGFscmVhZHkgYmVlbiBhY2NvdW50ZWQgZm9yLgoJICovCglhc3NlcnQoIWJvX2dlbS0+dXNlZF9hc19yZWxvY190YXJnZXQpOwoJaWYgKHRhcmdldF9ib19nZW0gIT0gYm9fZ2VtKSB7CgkJdGFyZ2V0X2JvX2dlbS0+dXNlZF9hc19yZWxvY190YXJnZXQgPSB0cnVlOwoJCWJvX2dlbS0+cmVsb2NfdHJlZV9zaXplICs9IHRhcmdldF9ib19nZW0tPnJlbG9jX3RyZWVfc2l6ZTsKCQlib19nZW0tPnJlbG9jX3RyZWVfZmVuY2VzICs9IHRhcmdldF9ib19nZW0tPnJlbG9jX3RyZWVfZmVuY2VzOwoJfQoKCWJvX2dlbS0+cmVsb2NzW2JvX2dlbS0+cmVsb2NfY291bnRdLm9mZnNldCA9IG9mZnNldDsKCWJvX2dlbS0+cmVsb2NzW2JvX2dlbS0+cmVsb2NfY291bnRdLmRlbHRhID0gdGFyZ2V0X29mZnNldDsKCWJvX2dlbS0+cmVsb2NzW2JvX2dlbS0+cmVsb2NfY291bnRdLnRhcmdldF9oYW5kbGUgPQoJICAgIHRhcmdldF9ib19nZW0tPmdlbV9oYW5kbGU7Cglib19nZW0tPnJlbG9jc1tib19nZW0tPnJlbG9jX2NvdW50XS5yZWFkX2RvbWFpbnMgPSByZWFkX2RvbWFpbnM7Cglib19nZW0tPnJlbG9jc1tib19nZW0tPnJlbG9jX2NvdW50XS53cml0ZV9kb21haW4gPSB3cml0ZV9kb21haW47Cglib19nZW0tPnJlbG9jc1tib19nZW0tPnJlbG9jX2NvdW50XS5wcmVzdW1lZF9vZmZzZXQgPSB0YXJnZXRfYm8tPm9mZnNldDY0OwoKCWJvX2dlbS0+cmVsb2NfdGFyZ2V0X2luZm9bYm9fZ2VtLT5yZWxvY19jb3VudF0uYm8gPSB0YXJnZXRfYm87CglpZiAodGFyZ2V0X2JvICE9IGJvKQoJCWRybV9pbnRlbF9nZW1fYm9fcmVmZXJlbmNlKHRhcmdldF9ibyk7CglpZiAoZmVuY2VkX2NvbW1hbmQpCgkJYm9fZ2VtLT5yZWxvY190YXJnZXRfaW5mb1tib19nZW0tPnJlbG9jX2NvdW50XS5mbGFncyA9CgkJCURSTV9JTlRFTF9SRUxPQ19GRU5DRTsKCWVsc2UKCQlib19nZW0tPnJlbG9jX3RhcmdldF9pbmZvW2JvX2dlbS0+cmVsb2NfY291bnRdLmZsYWdzID0gMDsKCglib19nZW0tPnJlbG9jX2NvdW50Kys7CgoJcmV0dXJuIDA7Cn0KCnN0YXRpYyBpbnQKZHJtX2ludGVsX2dlbV9ib19lbWl0X3JlbG9jKGRybV9pbnRlbF9ibyAqYm8sIHVpbnQzMl90IG9mZnNldCwKCQkJICAgIGRybV9pbnRlbF9ibyAqdGFyZ2V0X2JvLCB1aW50MzJfdCB0YXJnZXRfb2Zmc2V0LAoJCQkgICAgdWludDMyX3QgcmVhZF9kb21haW5zLCB1aW50MzJfdCB3cml0ZV9kb21haW4pCnsKCWRybV9pbnRlbF9idWZtZ3JfZ2VtICpidWZtZ3JfZ2VtID0gKGRybV9pbnRlbF9idWZtZ3JfZ2VtICopYm8tPmJ1Zm1ncjsKCglyZXR1cm4gZG9fYm9fZW1pdF9yZWxvYyhibywgb2Zmc2V0LCB0YXJnZXRfYm8sIHRhcmdldF9vZmZzZXQsCgkJCQlyZWFkX2RvbWFpbnMsIHdyaXRlX2RvbWFpbiwKCQkJCSFidWZtZ3JfZ2VtLT5mZW5jZWRfcmVsb2NzKTsKfQoKc3RhdGljIGludApkcm1faW50ZWxfZ2VtX2JvX2VtaXRfcmVsb2NfZmVuY2UoZHJtX2ludGVsX2JvICpibywgdWludDMyX3Qgb2Zmc2V0LAoJCQkJICBkcm1faW50ZWxfYm8gKnRhcmdldF9ibywKCQkJCSAgdWludDMyX3QgdGFyZ2V0X29mZnNldCwKCQkJCSAgdWludDMyX3QgcmVhZF9kb21haW5zLCB1aW50MzJfdCB3cml0ZV9kb21haW4pCnsKCXJldHVybiBkb19ib19lbWl0X3JlbG9jKGJvLCBvZmZzZXQsIHRhcmdldF9ibywgdGFyZ2V0X29mZnNldCwKCQkJCXJlYWRfZG9tYWlucywgd3JpdGVfZG9tYWluLCB0cnVlKTsKfQoKZHJtX3B1YmxpYyBpbnQKZHJtX2ludGVsX2dlbV9ib19nZXRfcmVsb2NfY291bnQoZHJtX2ludGVsX2JvICpibykKewoJZHJtX2ludGVsX2JvX2dlbSAqYm9fZ2VtID0gKGRybV9pbnRlbF9ib19nZW0gKikgYm87CgoJcmV0dXJuIGJvX2dlbS0+cmVsb2NfY291bnQ7Cn0KCi8qKgogKiBSZW1vdmVzIGV4aXN0aW5nIHJlbG9jYXRpb24gZW50cmllcyBpbiB0aGUgQk8gYWZ0ZXIgInN0YXJ0Ii4KICoKICogVGhpcyBhbGxvd3MgYSB1c2VyIHRvIGF2b2lkIGEgdHdvLXN0ZXAgcHJvY2VzcyBmb3Igc3RhdGUgc2V0dXAgd2l0aAogKiBjb3VudGluZyB1cCBhbGwgdGhlIGJ1ZmZlciBvYmplY3RzIGFuZCBkb2luZyBhCiAqIGRybV9pbnRlbF9idWZtZ3JfY2hlY2tfYXBlcnR1cmVfc3BhY2UoKSBiZWZvcmUgZW1pdHRpbmcgYW55IG9mIHRoZQogKiByZWxvY2F0aW9ucyBmb3IgdGhlIHN0YXRlIHNldHVwLiAgSW5zdGVhZCwgc2F2ZSB0aGUgc3RhdGUgb2YgdGhlCiAqIGJhdGNoYnVmZmVyIGluY2x1ZGluZyBkcm1faW50ZWxfZ2VtX2dldF9yZWxvY19jb3VudCgpLCBlbWl0IGFsbCB0aGUKICogc3RhdGUsIGFuZCB0aGVuIGNoZWNrIGlmIGl0IHN0aWxsIGZpdHMgaW4gdGhlIGFwZXJ0dXJlLgogKgogKiBBbnkgZnVydGhlciBkcm1faW50ZWxfYnVmbWdyX2NoZWNrX2FwZXJ0dXJlX3NwYWNlKCkgcXVlcmllcwogKiBpbnZvbHZpbmcgdGhpcyBidWZmZXIgaW4gdGhlIHRyZWUgYXJlIHVuZGVmaW5lZCBhZnRlciB0aGlzIGNhbGwuCiAqLwpkcm1fcHVibGljIHZvaWQKZHJtX2ludGVsX2dlbV9ib19jbGVhcl9yZWxvY3MoZHJtX2ludGVsX2JvICpibywgaW50IHN0YXJ0KQp7Cglkcm1faW50ZWxfYnVmbWdyX2dlbSAqYnVmbWdyX2dlbSA9IChkcm1faW50ZWxfYnVmbWdyX2dlbSAqKSBiby0+YnVmbWdyOwoJZHJtX2ludGVsX2JvX2dlbSAqYm9fZ2VtID0gKGRybV9pbnRlbF9ib19nZW0gKikgYm87CglpbnQgaTsKCXN0cnVjdCB0aW1lc3BlYyB0aW1lOwoKCWNsb2NrX2dldHRpbWUoQ0xPQ0tfTU9OT1RPTklDLCAmdGltZSk7CgoJYXNzZXJ0KGJvX2dlbS0+cmVsb2NfY291bnQgPj0gc3RhcnQpOwoKCS8qIFVucmVmZXJlbmNlIHRoZSBjbGVhcmVkIHRhcmdldCBidWZmZXJzICovCglwdGhyZWFkX211dGV4X2xvY2soJmJ1Zm1ncl9nZW0tPmxvY2spOwoKCWZvciAoaSA9IHN0YXJ0OyBpIDwgYm9fZ2VtLT5yZWxvY19jb3VudDsgaSsrKSB7CgkJZHJtX2ludGVsX2JvX2dlbSAqdGFyZ2V0X2JvX2dlbSA9IChkcm1faW50ZWxfYm9fZ2VtICopIGJvX2dlbS0+cmVsb2NfdGFyZ2V0X2luZm9baV0uYm87CgkJaWYgKCZ0YXJnZXRfYm9fZ2VtLT5ibyAhPSBibykgewoJCQlib19nZW0tPnJlbG9jX3RyZWVfZmVuY2VzIC09IHRhcmdldF9ib19nZW0tPnJlbG9jX3RyZWVfZmVuY2VzOwoJCQlkcm1faW50ZWxfZ2VtX2JvX3VucmVmZXJlbmNlX2xvY2tlZF90aW1lZCgmdGFyZ2V0X2JvX2dlbS0+Ym8sCgkJCQkJCQkJICB0aW1lLnR2X3NlYyk7CgkJfQoJfQoJYm9fZ2VtLT5yZWxvY19jb3VudCA9IHN0YXJ0OwoKCXB0aHJlYWRfbXV0ZXhfdW5sb2NrKCZidWZtZ3JfZ2VtLT5sb2NrKTsKCn0KCi8qKgogKiBXYWxrIHRoZSB0cmVlIG9mIHJlbG9jYXRpb25zIHJvb3RlZCBhdCBCTyBhbmQgYWNjdW11bGF0ZSB0aGUgbGlzdCBvZgogKiB2YWxpZGF0aW9ucyB0byBiZSBwZXJmb3JtZWQgYW5kIHVwZGF0ZSB0aGUgcmVsb2NhdGlvbiBidWZmZXJzIHdpdGgKICogaW5kZXggdmFsdWVzIGludG8gdGhlIHZhbGlkYXRpb24gbGlzdC4KICovCnN0YXRpYyB2b2lkCmRybV9pbnRlbF9nZW1fYm9fcHJvY2Vzc19yZWxvYyhkcm1faW50ZWxfYm8gKmJvKQp7Cglkcm1faW50ZWxfYm9fZ2VtICpib19nZW0gPSAoZHJtX2ludGVsX2JvX2dlbSAqKSBibzsKCWludCBpOwoKCWlmIChib19nZW0tPnJlbG9jcyA9PSBOVUxMKQoJCXJldHVybjsKCglmb3IgKGkgPSAwOyBpIDwgYm9fZ2VtLT5yZWxvY19jb3VudDsgaSsrKSB7CgkJZHJtX2ludGVsX2JvICp0YXJnZXRfYm8gPSBib19nZW0tPnJlbG9jX3RhcmdldF9pbmZvW2ldLmJvOwoKCQlpZiAodGFyZ2V0X2JvID09IGJvKQoJCQljb250aW51ZTsKCgkJZHJtX2ludGVsX2dlbV9ib19tYXJrX21tYXBzX2luY29oZXJlbnQoYm8pOwoKCQkvKiBDb250aW51ZSB3YWxraW5nIHRoZSB0cmVlIGRlcHRoLWZpcnN0LiAqLwoJCWRybV9pbnRlbF9nZW1fYm9fcHJvY2Vzc19yZWxvYyh0YXJnZXRfYm8pOwoKCQkvKiBBZGQgdGhlIHRhcmdldCB0byB0aGUgdmFsaWRhdGUgbGlzdCAqLwoJCWRybV9pbnRlbF9hZGRfdmFsaWRhdGVfYnVmZmVyKHRhcmdldF9ibyk7Cgl9Cn0KCnN0YXRpYyB2b2lkCmRybV9pbnRlbF9nZW1fYm9fcHJvY2Vzc19yZWxvYzIoZHJtX2ludGVsX2JvICpibykKewoJZHJtX2ludGVsX2JvX2dlbSAqYm9fZ2VtID0gKGRybV9pbnRlbF9ib19nZW0gKilibzsKCWludCBpOwoKCWlmIChib19nZW0tPnJlbG9jcyA9PSBOVUxMKQoJCXJldHVybjsKCglmb3IgKGkgPSAwOyBpIDwgYm9fZ2VtLT5yZWxvY19jb3VudDsgaSsrKSB7CgkJZHJtX2ludGVsX2JvICp0YXJnZXRfYm8gPSBib19nZW0tPnJlbG9jX3RhcmdldF9pbmZvW2ldLmJvOwoJCWludCBuZWVkX2ZlbmNlOwoKCQlpZiAodGFyZ2V0X2JvID09IGJvKQoJCQljb250aW51ZTsKCgkJZHJtX2ludGVsX2dlbV9ib19tYXJrX21tYXBzX2luY29oZXJlbnQoYm8pOwoKCQkvKiBDb250aW51ZSB3YWxraW5nIHRoZSB0cmVlIGRlcHRoLWZpcnN0LiAqLwoJCWRybV9pbnRlbF9nZW1fYm9fcHJvY2Vzc19yZWxvYzIodGFyZ2V0X2JvKTsKCgkJbmVlZF9mZW5jZSA9IChib19nZW0tPnJlbG9jX3RhcmdldF9pbmZvW2ldLmZsYWdzICYKCQkJICAgICAgRFJNX0lOVEVMX1JFTE9DX0ZFTkNFKTsKCgkJLyogQWRkIHRoZSB0YXJnZXQgdG8gdGhlIHZhbGlkYXRlIGxpc3QgKi8KCQlkcm1faW50ZWxfYWRkX3ZhbGlkYXRlX2J1ZmZlcjIodGFyZ2V0X2JvLCBuZWVkX2ZlbmNlKTsKCX0KfQoKCnN0YXRpYyB2b2lkCmRybV9pbnRlbF91cGRhdGVfYnVmZmVyX29mZnNldHMoZHJtX2ludGVsX2J1Zm1ncl9nZW0gKmJ1Zm1ncl9nZW0pCnsKCWludCBpOwoKCWZvciAoaSA9IDA7IGkgPCBidWZtZ3JfZ2VtLT5leGVjX2NvdW50OyBpKyspIHsKCQlkcm1faW50ZWxfYm8gKmJvID0gYnVmbWdyX2dlbS0+ZXhlY19ib3NbaV07CgkJZHJtX2ludGVsX2JvX2dlbSAqYm9fZ2VtID0gKGRybV9pbnRlbF9ib19nZW0gKikgYm87CgoJCS8qIFVwZGF0ZSB0aGUgYnVmZmVyIG9mZnNldCAqLwoJCWlmIChidWZtZ3JfZ2VtLT5leGVjX29iamVjdHNbaV0ub2Zmc2V0ICE9IGJvLT5vZmZzZXQ2NCkgewoJCQlEQkcoIkJPICVkICglcykgbWlncmF0ZWQ6IDB4JTA4bHggLT4gMHglMDhsbHhcbiIsCgkJCSAgICBib19nZW0tPmdlbV9oYW5kbGUsIGJvX2dlbS0+bmFtZSwgYm8tPm9mZnNldDY0LAoJCQkgICAgKHVuc2lnbmVkIGxvbmcgbG9uZylidWZtZ3JfZ2VtLT5leGVjX29iamVjdHNbaV0uCgkJCSAgICBvZmZzZXQpOwoJCQliby0+b2Zmc2V0NjQgPSBidWZtZ3JfZ2VtLT5leGVjX29iamVjdHNbaV0ub2Zmc2V0OwoJCQliby0+b2Zmc2V0ID0gYnVmbWdyX2dlbS0+ZXhlY19vYmplY3RzW2ldLm9mZnNldDsKCQl9Cgl9Cn0KCnN0YXRpYyB2b2lkCmRybV9pbnRlbF91cGRhdGVfYnVmZmVyX29mZnNldHMyIChkcm1faW50ZWxfYnVmbWdyX2dlbSAqYnVmbWdyX2dlbSkKewoJaW50IGk7CgoJZm9yIChpID0gMDsgaSA8IGJ1Zm1ncl9nZW0tPmV4ZWNfY291bnQ7IGkrKykgewoJCWRybV9pbnRlbF9ibyAqYm8gPSBidWZtZ3JfZ2VtLT5leGVjX2Jvc1tpXTsKCQlkcm1faW50ZWxfYm9fZ2VtICpib19nZW0gPSAoZHJtX2ludGVsX2JvX2dlbSAqKWJvOwoKCQkvKiBVcGRhdGUgdGhlIGJ1ZmZlciBvZmZzZXQgKi8KCQlpZiAoYnVmbWdyX2dlbS0+ZXhlYzJfb2JqZWN0c1tpXS5vZmZzZXQgIT0gYm8tPm9mZnNldDY0KSB7CgkJCURCRygiQk8gJWQgKCVzKSBtaWdyYXRlZDogMHglMDhseCAtPiAweCUwOGxseFxuIiwKCQkJICAgIGJvX2dlbS0+Z2VtX2hhbmRsZSwgYm9fZ2VtLT5uYW1lLCBiby0+b2Zmc2V0NjQsCgkJCSAgICAodW5zaWduZWQgbG9uZyBsb25nKWJ1Zm1ncl9nZW0tPmV4ZWMyX29iamVjdHNbaV0ub2Zmc2V0KTsKCQkJYm8tPm9mZnNldDY0ID0gYnVmbWdyX2dlbS0+ZXhlYzJfb2JqZWN0c1tpXS5vZmZzZXQ7CgkJCWJvLT5vZmZzZXQgPSBidWZtZ3JfZ2VtLT5leGVjMl9vYmplY3RzW2ldLm9mZnNldDsKCQl9Cgl9Cn0KCnN0YXRpYyB2b2lkCmF1Yl9vdXQoZHJtX2ludGVsX2J1Zm1ncl9nZW0gKmJ1Zm1ncl9nZW0sIHVpbnQzMl90IGRhdGEpCnsKCWZ3cml0ZSgmZGF0YSwgMSwgNCwgYnVmbWdyX2dlbS0+YXViX2ZpbGUpOwp9CgpzdGF0aWMgdm9pZAphdWJfb3V0X2RhdGEoZHJtX2ludGVsX2J1Zm1ncl9nZW0gKmJ1Zm1ncl9nZW0sIHZvaWQgKmRhdGEsIHNpemVfdCBzaXplKQp7Cglmd3JpdGUoZGF0YSwgMSwgc2l6ZSwgYnVmbWdyX2dlbS0+YXViX2ZpbGUpOwp9CgpzdGF0aWMgdm9pZAphdWJfd3JpdGVfYm9fZGF0YShkcm1faW50ZWxfYm8gKmJvLCB1aW50MzJfdCBvZmZzZXQsIHVpbnQzMl90IHNpemUpCnsKCWRybV9pbnRlbF9idWZtZ3JfZ2VtICpidWZtZ3JfZ2VtID0gKGRybV9pbnRlbF9idWZtZ3JfZ2VtICopIGJvLT5idWZtZ3I7Cglkcm1faW50ZWxfYm9fZ2VtICpib19nZW0gPSAoZHJtX2ludGVsX2JvX2dlbSAqKSBibzsKCXVpbnQzMl90ICpkYXRhOwoJdW5zaWduZWQgaW50IGk7CgoJZGF0YSA9IG1hbGxvYyhiby0+c2l6ZSk7Cglkcm1faW50ZWxfYm9fZ2V0X3N1YmRhdGEoYm8sIG9mZnNldCwgc2l6ZSwgZGF0YSk7CgoJLyogRWFzeSBtb2RlOiB3cml0ZSBvdXQgYm8gd2l0aCBubyByZWxvY2F0aW9ucyAqLwoJaWYgKCFib19nZW0tPnJlbG9jX2NvdW50KSB7CgkJYXViX291dF9kYXRhKGJ1Zm1ncl9nZW0sIGRhdGEsIHNpemUpOwoJCWZyZWUoZGF0YSk7CgkJcmV0dXJuOwoJfQoKCS8qIE90aGVyd2lzZSwgaGFuZGxlIHRoZSByZWxvY2F0aW9ucyB3aGlsZSB3cml0aW5nLiAqLwoJZm9yIChpID0gMDsgaSA8IHNpemUgLyA0OyBpKyspIHsKCQlpbnQgcjsKCQlmb3IgKHIgPSAwOyByIDwgYm9fZ2VtLT5yZWxvY19jb3VudDsgcisrKSB7CgkJCXN0cnVjdCBkcm1faTkxNV9nZW1fcmVsb2NhdGlvbl9lbnRyeSAqcmVsb2M7CgkJCWRybV9pbnRlbF9yZWxvY190YXJnZXQgKmluZm87CgoJCQlyZWxvYyA9ICZib19nZW0tPnJlbG9jc1tyXTsKCQkJaW5mbyA9ICZib19nZW0tPnJlbG9jX3RhcmdldF9pbmZvW3JdOwoKCQkJaWYgKHJlbG9jLT5vZmZzZXQgPT0gb2Zmc2V0ICsgaSAqIDQpIHsKCQkJCWRybV9pbnRlbF9ib19nZW0gKnRhcmdldF9nZW07CgkJCQl1aW50MzJfdCB2YWw7CgoJCQkJdGFyZ2V0X2dlbSA9IChkcm1faW50ZWxfYm9fZ2VtICopaW5mby0+Ym87CgoJCQkJdmFsID0gcmVsb2MtPmRlbHRhOwoJCQkJdmFsICs9IHRhcmdldF9nZW0tPmF1Yl9vZmZzZXQ7CgoJCQkJYXViX291dChidWZtZ3JfZ2VtLCB2YWwpOwoJCQkJZGF0YVtpXSA9IHZhbDsKCQkJCWJyZWFrOwoJCQl9CgkJfQoJCWlmIChyID09IGJvX2dlbS0+cmVsb2NfY291bnQpIHsKCQkJLyogbm8gcmVsb2NhdGlvbiwganVzdCB0aGUgZGF0YSAqLwoJCQlhdWJfb3V0KGJ1Zm1ncl9nZW0sIGRhdGFbaV0pOwoJCX0KCX0KCglmcmVlKGRhdGEpOwp9CgpzdGF0aWMgdm9pZAphdWJfYm9fZ2V0X2FkZHJlc3MoZHJtX2ludGVsX2JvICpibykKewoJZHJtX2ludGVsX2J1Zm1ncl9nZW0gKmJ1Zm1ncl9nZW0gPSAoZHJtX2ludGVsX2J1Zm1ncl9nZW0gKikgYm8tPmJ1Zm1ncjsKCWRybV9pbnRlbF9ib19nZW0gKmJvX2dlbSA9IChkcm1faW50ZWxfYm9fZ2VtICopIGJvOwoKCS8qIEdpdmUgdGhlIG9iamVjdCBhIGdyYXBoaWNzIGFkZHJlc3MgaW4gdGhlIEFVQiBmaWxlLiAgV2UKCSAqIGRvbid0IGp1c3QgdXNlIHRoZSBHRU0gb2JqZWN0IGFkZHJlc3MgYmVjYXVzZSB3ZSBkbyBBVUIKCSAqIGR1bXBpbmcgYmVmb3JlIGV4ZWN1dGlvbiAtLSB3ZSB3YW50IHRvIHN1Y2Nlc3NmdWxseSBsb2cKCSAqIHdoZW4gdGhlIGhhcmR3YXJlIG1pZ2h0IGhhbmcsIGFuZCB3ZSBtaWdodCBldmVuIHdhbnQgdG8gYXViCgkgKiBjYXB0dXJlIGZvciBhIGRyaXZlciB0cnlpbmcgdG8gZXhlY3V0ZSBvbiBhIGRpZmZlcmVudAoJICogZ2VuZXJhdGlvbiBvZiBoYXJkd2FyZSBieSBkaXNhYmxpbmcgdGhlIGFjdHVhbCBrZXJuZWwgZXhlYwoJICogY2FsbC4KCSAqLwoJYm9fZ2VtLT5hdWJfb2Zmc2V0ID0gYnVmbWdyX2dlbS0+YXViX29mZnNldDsKCWJ1Zm1ncl9nZW0tPmF1Yl9vZmZzZXQgKz0gYm8tPnNpemU7CgkvKiBYWFg6IEhhbmRsZSBhcGVydHVyZSBvdmVyZmxvdy4gKi8KCWFzc2VydChidWZtZ3JfZ2VtLT5hdWJfb2Zmc2V0IDwgMjU2ICogMTAyNCAqIDEwMjQpOwp9CgpzdGF0aWMgdm9pZAphdWJfd3JpdGVfdHJhY2VfYmxvY2soZHJtX2ludGVsX2JvICpibywgdWludDMyX3QgdHlwZSwgdWludDMyX3Qgc3VidHlwZSwKCQkgICAgICB1aW50MzJfdCBvZmZzZXQsIHVpbnQzMl90IHNpemUpCnsKCWRybV9pbnRlbF9idWZtZ3JfZ2VtICpidWZtZ3JfZ2VtID0gKGRybV9pbnRlbF9idWZtZ3JfZ2VtICopIGJvLT5idWZtZ3I7Cglkcm1faW50ZWxfYm9fZ2VtICpib19nZW0gPSAoZHJtX2ludGVsX2JvX2dlbSAqKSBibzsKCglhdWJfb3V0KGJ1Zm1ncl9nZW0sCgkJQ01EX0FVQl9UUkFDRV9IRUFERVJfQkxPQ0sgfAoJCSgoYnVmbWdyX2dlbS0+Z2VuID49IDggPyA2IDogNSkgLSAyKSk7CglhdWJfb3V0KGJ1Zm1ncl9nZW0sCgkJQVVCX1RSQUNFX01FTVRZUEVfR1RUIHwgdHlwZSB8IEFVQl9UUkFDRV9PUF9EQVRBX1dSSVRFKTsKCWF1Yl9vdXQoYnVmbWdyX2dlbSwgc3VidHlwZSk7CglhdWJfb3V0KGJ1Zm1ncl9nZW0sIGJvX2dlbS0+YXViX29mZnNldCArIG9mZnNldCk7CglhdWJfb3V0KGJ1Zm1ncl9nZW0sIHNpemUpOwoJaWYgKGJ1Zm1ncl9nZW0tPmdlbiA+PSA4KQoJCWF1Yl9vdXQoYnVmbWdyX2dlbSwgMCk7CglhdWJfd3JpdGVfYm9fZGF0YShibywgb2Zmc2V0LCBzaXplKTsKfQoKLyoqCiAqIEJyZWFrIHVwIGxhcmdlIG9iamVjdHMgaW50byBtdWx0aXBsZSB3cml0ZXMuICBPdGhlcndpc2UgYSAxMjhrYiBWQk8KICogd291bGQgb3ZlcmZsb3cgdGhlIDE2IGJpdHMgb2Ygc2l6ZSBmaWVsZCBpbiB0aGUgcGFja2V0IGhlYWRlciBhbmQKICogZXZlcnl0aGluZyBnb2VzIGJhZGx5IGFmdGVyIHRoYXQuCiAqLwpzdGF0aWMgdm9pZAphdWJfd3JpdGVfbGFyZ2VfdHJhY2VfYmxvY2soZHJtX2ludGVsX2JvICpibywgdWludDMyX3QgdHlwZSwgdWludDMyX3Qgc3VidHlwZSwKCQkJICAgIHVpbnQzMl90IG9mZnNldCwgdWludDMyX3Qgc2l6ZSkKewoJdWludDMyX3QgYmxvY2tfc2l6ZTsKCXVpbnQzMl90IHN1Yl9vZmZzZXQ7CgoJZm9yIChzdWJfb2Zmc2V0ID0gMDsgc3ViX29mZnNldCA8IHNpemU7IHN1Yl9vZmZzZXQgKz0gYmxvY2tfc2l6ZSkgewoJCWJsb2NrX3NpemUgPSBzaXplIC0gc3ViX29mZnNldDsKCgkJaWYgKGJsb2NrX3NpemUgPiA4ICogNDA5NikKCQkJYmxvY2tfc2l6ZSA9IDggKiA0MDk2OwoKCQlhdWJfd3JpdGVfdHJhY2VfYmxvY2soYm8sIHR5cGUsIHN1YnR5cGUsIG9mZnNldCArIHN1Yl9vZmZzZXQsCgkJCQkgICAgICBibG9ja19zaXplKTsKCX0KfQoKc3RhdGljIHZvaWQKYXViX3dyaXRlX2JvKGRybV9pbnRlbF9ibyAqYm8pCnsKCWRybV9pbnRlbF9ib19nZW0gKmJvX2dlbSA9IChkcm1faW50ZWxfYm9fZ2VtICopIGJvOwoJdWludDMyX3Qgb2Zmc2V0ID0gMDsKCXVuc2lnbmVkIGk7CgoJYXViX2JvX2dldF9hZGRyZXNzKGJvKTsKCgkvKiBXcml0ZSBvdXQgZWFjaCBhbm5vdGF0ZWQgc2VjdGlvbiBzZXBhcmF0ZWx5LiAqLwoJZm9yIChpID0gMDsgaSA8IGJvX2dlbS0+YXViX2Fubm90YXRpb25fY291bnQ7ICsraSkgewoJCWRybV9pbnRlbF9hdWJfYW5ub3RhdGlvbiAqYW5ub3RhdGlvbiA9CgkJCSZib19nZW0tPmF1Yl9hbm5vdGF0aW9uc1tpXTsKCQl1aW50MzJfdCBlbmRpbmdfb2Zmc2V0ID0gYW5ub3RhdGlvbi0+ZW5kaW5nX29mZnNldDsKCQlpZiAoZW5kaW5nX29mZnNldCA+IGJvLT5zaXplKQoJCQllbmRpbmdfb2Zmc2V0ID0gYm8tPnNpemU7CgkJaWYgKGVuZGluZ19vZmZzZXQgPiBvZmZzZXQpIHsKCQkJYXViX3dyaXRlX2xhcmdlX3RyYWNlX2Jsb2NrKGJvLCBhbm5vdGF0aW9uLT50eXBlLAoJCQkJCQkgICAgYW5ub3RhdGlvbi0+c3VidHlwZSwKCQkJCQkJICAgIG9mZnNldCwKCQkJCQkJICAgIGVuZGluZ19vZmZzZXQgLSBvZmZzZXQpOwoJCQlvZmZzZXQgPSBlbmRpbmdfb2Zmc2V0OwoJCX0KCX0KCgkvKiBXcml0ZSBvdXQgYW55IHJlbWFpbmluZyB1bmFubm90YXRlZCBkYXRhICovCglpZiAob2Zmc2V0IDwgYm8tPnNpemUpIHsKCQlhdWJfd3JpdGVfbGFyZ2VfdHJhY2VfYmxvY2soYm8sIEFVQl9UUkFDRV9UWVBFX05PVFlQRSwgMCwKCQkJCQkgICAgb2Zmc2V0LCBiby0+c2l6ZSAtIG9mZnNldCk7Cgl9Cn0KCi8qCiAqIE1ha2UgYSByaW5nYnVmZmVyIG9uIGZseSBhbmQgZHVtcCBpdAogKi8Kc3RhdGljIHZvaWQKYXViX2J1aWxkX2R1bXBfcmluZ2J1ZmZlcihkcm1faW50ZWxfYnVmbWdyX2dlbSAqYnVmbWdyX2dlbSwKCQkJICB1aW50MzJfdCBiYXRjaF9idWZmZXIsIGludCByaW5nX2ZsYWcpCnsKCXVpbnQzMl90IHJpbmdidWZmZXJbNDA5Nl07CglpbnQgcmluZyA9IEFVQl9UUkFDRV9UWVBFX1JJTkdfUFJCMDsgLyogVGhlIGRlZmF1bHQgcmluZyAqLwoJaW50IHJpbmdfY291bnQgPSAwOwoKCWlmIChyaW5nX2ZsYWcgPT0gSTkxNV9FWEVDX0JTRCkKCQlyaW5nID0gQVVCX1RSQUNFX1RZUEVfUklOR19QUkIxOwoJZWxzZSBpZiAocmluZ19mbGFnID09IEk5MTVfRVhFQ19CTFQpCgkJcmluZyA9IEFVQl9UUkFDRV9UWVBFX1JJTkdfUFJCMjsKCgkvKiBNYWtlIGEgcmluZyBidWZmZXIgdG8gZXhlY3V0ZSBvdXIgYmF0Y2hidWZmZXIuICovCgltZW1zZXQocmluZ2J1ZmZlciwgMCwgc2l6ZW9mKHJpbmdidWZmZXIpKTsKCWlmIChidWZtZ3JfZ2VtLT5nZW4gPj0gOCkgewoJCXJpbmdidWZmZXJbcmluZ19jb3VudCsrXSA9IEFVQl9NSV9CQVRDSF9CVUZGRVJfU1RBUlQgfCAoMyAtIDIpOwoJCXJpbmdidWZmZXJbcmluZ19jb3VudCsrXSA9IGJhdGNoX2J1ZmZlcjsKCQlyaW5nYnVmZmVyW3JpbmdfY291bnQrK10gPSAwOwoJfSBlbHNlIHsKCQlyaW5nYnVmZmVyW3JpbmdfY291bnQrK10gPSBBVUJfTUlfQkFUQ0hfQlVGRkVSX1NUQVJUOwoJCXJpbmdidWZmZXJbcmluZ19jb3VudCsrXSA9IGJhdGNoX2J1ZmZlcjsKCX0KCgkvKiBXcml0ZSBvdXQgdGhlIHJpbmcuICBUaGlzIGFwcGVhcnMgdG8gdHJpZ2dlciBleGVjdXRpb24gb2YKCSAqIHRoZSByaW5nIGluIHRoZSBzaW11bGF0b3IuCgkgKi8KCWF1Yl9vdXQoYnVmbWdyX2dlbSwKCQlDTURfQVVCX1RSQUNFX0hFQURFUl9CTE9DSyB8CgkJKChidWZtZ3JfZ2VtLT5nZW4gPj0gOCA/IDYgOiA1KSAtIDIpKTsKCWF1Yl9vdXQoYnVmbWdyX2dlbSwKCQlBVUJfVFJBQ0VfTUVNVFlQRV9HVFQgfCByaW5nIHwgQVVCX1RSQUNFX09QX0NPTU1BTkRfV1JJVEUpOwoJYXViX291dChidWZtZ3JfZ2VtLCAwKTsgLyogZ2VuZXJhbC9zdXJmYWNlIHN1YnR5cGUgKi8KCWF1Yl9vdXQoYnVmbWdyX2dlbSwgYnVmbWdyX2dlbS0+YXViX29mZnNldCk7CglhdWJfb3V0KGJ1Zm1ncl9nZW0sIHJpbmdfY291bnQgKiA0KTsKCWlmIChidWZtZ3JfZ2VtLT5nZW4gPj0gOCkKCQlhdWJfb3V0KGJ1Zm1ncl9nZW0sIDApOwoKCS8qIEZJWE1FOiBOZWVkIHNvbWUgZmx1c2ggb3BlcmF0aW9ucyBoZXJlPyAqLwoJYXViX291dF9kYXRhKGJ1Zm1ncl9nZW0sIHJpbmdidWZmZXIsIHJpbmdfY291bnQgKiA0KTsKCgkvKiBVcGRhdGUgb2Zmc2V0IHBvaW50ZXIgKi8KCWJ1Zm1ncl9nZW0tPmF1Yl9vZmZzZXQgKz0gNDA5NjsKfQoKZHJtX3B1YmxpYyB2b2lkCmRybV9pbnRlbF9nZW1fYm9fYXViX2R1bXBfYm1wKGRybV9pbnRlbF9ibyAqYm8sCgkJCSAgICAgIGludCB4MSwgaW50IHkxLCBpbnQgd2lkdGgsIGludCBoZWlnaHQsCgkJCSAgICAgIGVudW0gYXViX2R1bXBfYm1wX2Zvcm1hdCBmb3JtYXQsCgkJCSAgICAgIGludCBwaXRjaCwgaW50IG9mZnNldCkKewoJZHJtX2ludGVsX2J1Zm1ncl9nZW0gKmJ1Zm1ncl9nZW0gPSAoZHJtX2ludGVsX2J1Zm1ncl9nZW0gKikgYm8tPmJ1Zm1ncjsKCWRybV9pbnRlbF9ib19nZW0gKmJvX2dlbSA9IChkcm1faW50ZWxfYm9fZ2VtICopYm87Cgl1aW50MzJfdCBjcHA7CgoJc3dpdGNoIChmb3JtYXQpIHsKCWNhc2UgQVVCX0RVTVBfQk1QX0ZPUk1BVF84QklUOgoJCWNwcCA9IDE7CgkJYnJlYWs7CgljYXNlIEFVQl9EVU1QX0JNUF9GT1JNQVRfQVJHQl80NDQ0OgoJCWNwcCA9IDI7CgkJYnJlYWs7CgljYXNlIEFVQl9EVU1QX0JNUF9GT1JNQVRfQVJHQl8wODg4OgoJY2FzZSBBVUJfRFVNUF9CTVBfRk9STUFUX0FSR0JfODg4ODoKCQljcHAgPSA0OwoJCWJyZWFrOwoJZGVmYXVsdDoKCQlwcmludGYoIlVua25vd24gQVVCIGR1bXAgZm9ybWF0ICVkXG4iLCBmb3JtYXQpOwoJCXJldHVybjsKCX0KCglpZiAoIWJ1Zm1ncl9nZW0tPmF1Yl9maWxlKQoJCXJldHVybjsKCglhdWJfb3V0KGJ1Zm1ncl9nZW0sIENNRF9BVUJfRFVNUF9CTVAgfCA0KTsKCWF1Yl9vdXQoYnVmbWdyX2dlbSwgKHkxIDw8IDE2KSB8IHgxKTsKCWF1Yl9vdXQoYnVmbWdyX2dlbSwKCQkoZm9ybWF0IDw8IDI0KSB8CgkJKGNwcCA8PCAxOSkgfAoJCXBpdGNoIC8gNCk7CglhdWJfb3V0KGJ1Zm1ncl9nZW0sIChoZWlnaHQgPDwgMTYpIHwgd2lkdGgpOwoJYXViX291dChidWZtZ3JfZ2VtLCBib19nZW0tPmF1Yl9vZmZzZXQgKyBvZmZzZXQpOwoJYXViX291dChidWZtZ3JfZ2VtLAoJCSgoYm9fZ2VtLT50aWxpbmdfbW9kZSAhPSBJOTE1X1RJTElOR19OT05FKSA/ICgxIDw8IDIpIDogMCkgfAoJCSgoYm9fZ2VtLT50aWxpbmdfbW9kZSA9PSBJOTE1X1RJTElOR19ZKSA/ICgxIDw8IDMpIDogMCkpOwp9CgpzdGF0aWMgdm9pZAphdWJfZXhlYyhkcm1faW50ZWxfYm8gKmJvLCBpbnQgcmluZ19mbGFnLCBpbnQgdXNlZCkKewoJZHJtX2ludGVsX2J1Zm1ncl9nZW0gKmJ1Zm1ncl9nZW0gPSAoZHJtX2ludGVsX2J1Zm1ncl9nZW0gKikgYm8tPmJ1Zm1ncjsKCWRybV9pbnRlbF9ib19nZW0gKmJvX2dlbSA9IChkcm1faW50ZWxfYm9fZ2VtICopIGJvOwoJaW50IGk7Cglib29sIGJhdGNoX2J1ZmZlcl9uZWVkc19hbm5vdGF0aW9uczsKCglpZiAoIWJ1Zm1ncl9nZW0tPmF1Yl9maWxlKQoJCXJldHVybjsKCgkvKiBJZiBiYXRjaCBidWZmZXIgaXMgbm90IGFubm90YXRlZCwgYW5ub3RhdGUgaXQgdGhlIGJlc3Qgd2UKCSAqIGNhbi4KCSAqLwoJYmF0Y2hfYnVmZmVyX25lZWRzX2Fubm90YXRpb25zID0gYm9fZ2VtLT5hdWJfYW5ub3RhdGlvbl9jb3VudCA9PSAwOwoJaWYgKGJhdGNoX2J1ZmZlcl9uZWVkc19hbm5vdGF0aW9ucykgewoJCWRybV9pbnRlbF9hdWJfYW5ub3RhdGlvbiBhbm5vdGF0aW9uc1syXSA9IHsKCQkJeyBBVUJfVFJBQ0VfVFlQRV9CQVRDSCwgMCwgdXNlZCB9LAoJCQl7IEFVQl9UUkFDRV9UWVBFX05PVFlQRSwgMCwgYm8tPnNpemUgfQoJCX07CgkJZHJtX2ludGVsX2J1Zm1ncl9nZW1fc2V0X2F1Yl9hbm5vdGF0aW9ucyhibywgYW5ub3RhdGlvbnMsIDIpOwoJfQoKCS8qIFdyaXRlIG91dCBhbGwgYnVmZmVycyB0byBBVUIgbWVtb3J5ICovCglmb3IgKGkgPSAwOyBpIDwgYnVmbWdyX2dlbS0+ZXhlY19jb3VudDsgaSsrKSB7CgkJYXViX3dyaXRlX2JvKGJ1Zm1ncl9nZW0tPmV4ZWNfYm9zW2ldKTsKCX0KCgkvKiBSZW1vdmUgYW55IGFubm90YXRpb25zIHdlIGFkZGVkICovCglpZiAoYmF0Y2hfYnVmZmVyX25lZWRzX2Fubm90YXRpb25zKQoJCWRybV9pbnRlbF9idWZtZ3JfZ2VtX3NldF9hdWJfYW5ub3RhdGlvbnMoYm8sIE5VTEwsIDApOwoKCS8qIER1bXAgcmluZyBidWZmZXIgKi8KCWF1Yl9idWlsZF9kdW1wX3JpbmdidWZmZXIoYnVmbWdyX2dlbSwgYm9fZ2VtLT5hdWJfb2Zmc2V0LCByaW5nX2ZsYWcpOwoKCWZmbHVzaChidWZtZ3JfZ2VtLT5hdWJfZmlsZSk7CgoJLyoKCSAqIE9uZSBmcmFtZSBoYXMgYmVlbiBkdW1wZWQuIFNvIHJlc2V0IHRoZSBhdWJfb2Zmc2V0IGZvciB0aGUgbmV4dCBmcmFtZS4KCSAqCgkgKiBGSVhNRTogQ2FuIHdlIGRvIHRoaXM/CgkgKi8KCWJ1Zm1ncl9nZW0tPmF1Yl9vZmZzZXQgPSAweDEwMDAwOwp9CgpzdGF0aWMgaW50CmRybV9pbnRlbF9nZW1fYm9fZXhlYyhkcm1faW50ZWxfYm8gKmJvLCBpbnQgdXNlZCwKCQkgICAgICBkcm1fY2xpcF9yZWN0X3QgKiBjbGlwcmVjdHMsIGludCBudW1fY2xpcHJlY3RzLCBpbnQgRFI0KQp7Cglkcm1faW50ZWxfYnVmbWdyX2dlbSAqYnVmbWdyX2dlbSA9IChkcm1faW50ZWxfYnVmbWdyX2dlbSAqKSBiby0+YnVmbWdyOwoJZHJtX2ludGVsX2JvX2dlbSAqYm9fZ2VtID0gKGRybV9pbnRlbF9ib19nZW0gKikgYm87CglzdHJ1Y3QgZHJtX2k5MTVfZ2VtX2V4ZWNidWZmZXIgZXhlY2J1ZjsKCWludCByZXQsIGk7CgoJaWYgKGJvX2dlbS0+aGFzX2Vycm9yKQoJCXJldHVybiAtRU5PTUVNOwoKCXB0aHJlYWRfbXV0ZXhfbG9jaygmYnVmbWdyX2dlbS0+bG9jayk7CgkvKiBVcGRhdGUgaW5kaWNlcyBhbmQgc2V0IHVwIHRoZSB2YWxpZGF0ZSBsaXN0LiAqLwoJZHJtX2ludGVsX2dlbV9ib19wcm9jZXNzX3JlbG9jKGJvKTsKCgkvKiBBZGQgdGhlIGJhdGNoIGJ1ZmZlciB0byB0aGUgdmFsaWRhdGlvbiBsaXN0LiAgVGhlcmUgYXJlIG5vCgkgKiByZWxvY2F0aW9ucyBwb2ludGluZyB0byBpdC4KCSAqLwoJZHJtX2ludGVsX2FkZF92YWxpZGF0ZV9idWZmZXIoYm8pOwoKCVZHX0NMRUFSKGV4ZWNidWYpOwoJZXhlY2J1Zi5idWZmZXJzX3B0ciA9ICh1aW50cHRyX3QpIGJ1Zm1ncl9nZW0tPmV4ZWNfb2JqZWN0czsKCWV4ZWNidWYuYnVmZmVyX2NvdW50ID0gYnVmbWdyX2dlbS0+ZXhlY19jb3VudDsKCWV4ZWNidWYuYmF0Y2hfc3RhcnRfb2Zmc2V0ID0gMDsKCWV4ZWNidWYuYmF0Y2hfbGVuID0gdXNlZDsKCWV4ZWNidWYuY2xpcHJlY3RzX3B0ciA9ICh1aW50cHRyX3QpIGNsaXByZWN0czsKCWV4ZWNidWYubnVtX2NsaXByZWN0cyA9IG51bV9jbGlwcmVjdHM7CglleGVjYnVmLkRSMSA9IDA7CglleGVjYnVmLkRSNCA9IERSNDsKCglyZXQgPSBkcm1Jb2N0bChidWZtZ3JfZ2VtLT5mZCwKCQkgICAgICAgRFJNX0lPQ1RMX0k5MTVfR0VNX0VYRUNCVUZGRVIsCgkJICAgICAgICZleGVjYnVmKTsKCWlmIChyZXQgIT0gMCkgewoJCXJldCA9IC1lcnJubzsKCQlpZiAoZXJybm8gPT0gRU5PU1BDKSB7CgkJCURCRygiRXhlY2J1ZmZlciBmYWlscyB0byBwaW4uICIKCQkJICAgICJFc3RpbWF0ZTogJXUuIEFjdHVhbDogJXUuIEF2YWlsYWJsZTogJXVcbiIsCgkJCSAgICBkcm1faW50ZWxfZ2VtX2VzdGltYXRlX2JhdGNoX3NwYWNlKGJ1Zm1ncl9nZW0tPmV4ZWNfYm9zLAoJCQkJCQkJICAgICAgIGJ1Zm1ncl9nZW0tPgoJCQkJCQkJICAgICAgIGV4ZWNfY291bnQpLAoJCQkgICAgZHJtX2ludGVsX2dlbV9jb21wdXRlX2JhdGNoX3NwYWNlKGJ1Zm1ncl9nZW0tPmV4ZWNfYm9zLAoJCQkJCQkJICAgICAgYnVmbWdyX2dlbS0+CgkJCQkJCQkgICAgICBleGVjX2NvdW50KSwKCQkJICAgICh1bnNpZ25lZCBpbnQpYnVmbWdyX2dlbS0+Z3R0X3NpemUpOwoJCX0KCX0KCWRybV9pbnRlbF91cGRhdGVfYnVmZmVyX29mZnNldHMoYnVmbWdyX2dlbSk7CgoJaWYgKGJ1Zm1ncl9nZW0tPmJ1Zm1nci5kZWJ1ZykKCQlkcm1faW50ZWxfZ2VtX2R1bXBfdmFsaWRhdGlvbl9saXN0KGJ1Zm1ncl9nZW0pOwoKCWZvciAoaSA9IDA7IGkgPCBidWZtZ3JfZ2VtLT5leGVjX2NvdW50OyBpKyspIHsKCQlkcm1faW50ZWxfYm8gKmJvID0gYnVmbWdyX2dlbS0+ZXhlY19ib3NbaV07CgkJZHJtX2ludGVsX2JvX2dlbSAqYm9fZ2VtID0gKGRybV9pbnRlbF9ib19nZW0gKikgYm87CgoJCWJvX2dlbS0+aWRsZSA9IGZhbHNlOwoKCQkvKiBEaXNjb25uZWN0IHRoZSBidWZmZXIgZnJvbSB0aGUgdmFsaWRhdGUgbGlzdCAqLwoJCWJvX2dlbS0+dmFsaWRhdGVfaW5kZXggPSAtMTsKCQlidWZtZ3JfZ2VtLT5leGVjX2Jvc1tpXSA9IE5VTEw7Cgl9CglidWZtZ3JfZ2VtLT5leGVjX2NvdW50ID0gMDsKCXB0aHJlYWRfbXV0ZXhfdW5sb2NrKCZidWZtZ3JfZ2VtLT5sb2NrKTsKCglyZXR1cm4gcmV0Owp9CgpzdGF0aWMgaW50CmRvX2V4ZWMyKGRybV9pbnRlbF9ibyAqYm8sIGludCB1c2VkLCBkcm1faW50ZWxfY29udGV4dCAqY3R4LAoJIGRybV9jbGlwX3JlY3RfdCAqY2xpcHJlY3RzLCBpbnQgbnVtX2NsaXByZWN0cywgaW50IERSNCwKCSB1bnNpZ25lZCBpbnQgZmxhZ3MpCnsKCWRybV9pbnRlbF9idWZtZ3JfZ2VtICpidWZtZ3JfZ2VtID0gKGRybV9pbnRlbF9idWZtZ3JfZ2VtICopYm8tPmJ1Zm1ncjsKCXN0cnVjdCBkcm1faTkxNV9nZW1fZXhlY2J1ZmZlcjIgZXhlY2J1ZjsKCWludCByZXQgPSAwOwoJaW50IGk7CgoJc3dpdGNoIChmbGFncyAmIDB4NykgewoJZGVmYXVsdDoKCQlyZXR1cm4gLUVJTlZBTDsKCWNhc2UgSTkxNV9FWEVDX0JMVDoKCQlpZiAoIWJ1Zm1ncl9nZW0tPmhhc19ibHQpCgkJCXJldHVybiAtRUlOVkFMOwoJCWJyZWFrOwoJY2FzZSBJOTE1X0VYRUNfQlNEOgoJCWlmICghYnVmbWdyX2dlbS0+aGFzX2JzZCkKCQkJcmV0dXJuIC1FSU5WQUw7CgkJYnJlYWs7CgljYXNlIEk5MTVfRVhFQ19WRUJPWDoKCQlpZiAoIWJ1Zm1ncl9nZW0tPmhhc192ZWJveCkKCQkJcmV0dXJuIC1FSU5WQUw7CgkJYnJlYWs7CgljYXNlIEk5MTVfRVhFQ19SRU5ERVI6CgljYXNlIEk5MTVfRVhFQ19ERUZBVUxUOgoJCWJyZWFrOwoJfQoKCXB0aHJlYWRfbXV0ZXhfbG9jaygmYnVmbWdyX2dlbS0+bG9jayk7CgkvKiBVcGRhdGUgaW5kaWNlcyBhbmQgc2V0IHVwIHRoZSB2YWxpZGF0ZSBsaXN0LiAqLwoJZHJtX2ludGVsX2dlbV9ib19wcm9jZXNzX3JlbG9jMihibyk7CgoJLyogQWRkIHRoZSBiYXRjaCBidWZmZXIgdG8gdGhlIHZhbGlkYXRpb24gbGlzdC4gIFRoZXJlIGFyZSBubyByZWxvY2F0aW9ucwoJICogcG9pbnRpbmcgdG8gaXQuCgkgKi8KCWRybV9pbnRlbF9hZGRfdmFsaWRhdGVfYnVmZmVyMihibywgMCk7CgoJVkdfQ0xFQVIoZXhlY2J1Zik7CglleGVjYnVmLmJ1ZmZlcnNfcHRyID0gKHVpbnRwdHJfdClidWZtZ3JfZ2VtLT5leGVjMl9vYmplY3RzOwoJZXhlY2J1Zi5idWZmZXJfY291bnQgPSBidWZtZ3JfZ2VtLT5leGVjX2NvdW50OwoJZXhlY2J1Zi5iYXRjaF9zdGFydF9vZmZzZXQgPSAwOwoJZXhlY2J1Zi5iYXRjaF9sZW4gPSB1c2VkOwoJZXhlY2J1Zi5jbGlwcmVjdHNfcHRyID0gKHVpbnRwdHJfdCljbGlwcmVjdHM7CglleGVjYnVmLm51bV9jbGlwcmVjdHMgPSBudW1fY2xpcHJlY3RzOwoJZXhlY2J1Zi5EUjEgPSAwOwoJZXhlY2J1Zi5EUjQgPSBEUjQ7CglleGVjYnVmLmZsYWdzID0gZmxhZ3M7CglpZiAoY3R4ID09IE5VTEwpCgkJaTkxNV9leGVjYnVmZmVyMl9zZXRfY29udGV4dF9pZChleGVjYnVmLCAwKTsKCWVsc2UKCQlpOTE1X2V4ZWNidWZmZXIyX3NldF9jb250ZXh0X2lkKGV4ZWNidWYsIGN0eC0+Y3R4X2lkKTsKCWV4ZWNidWYucnN2ZDIgPSAwOwoKCWF1Yl9leGVjKGJvLCBmbGFncywgdXNlZCk7CgoJaWYgKGJ1Zm1ncl9nZW0tPm5vX2V4ZWMpCgkJZ290byBza2lwX2V4ZWN1dGlvbjsKCglyZXQgPSBkcm1Jb2N0bChidWZtZ3JfZ2VtLT5mZCwKCQkgICAgICAgRFJNX0lPQ1RMX0k5MTVfR0VNX0VYRUNCVUZGRVIyLAoJCSAgICAgICAmZXhlY2J1Zik7CglpZiAocmV0ICE9IDApIHsKCQlyZXQgPSAtZXJybm87CgkJaWYgKHJldCA9PSAtRU5PU1BDKSB7CgkJCURCRygiRXhlY2J1ZmZlciBmYWlscyB0byBwaW4uICIKCQkJICAgICJFc3RpbWF0ZTogJXUuIEFjdHVhbDogJXUuIEF2YWlsYWJsZTogJXVcbiIsCgkJCSAgICBkcm1faW50ZWxfZ2VtX2VzdGltYXRlX2JhdGNoX3NwYWNlKGJ1Zm1ncl9nZW0tPmV4ZWNfYm9zLAoJCQkJCQkJICAgICAgIGJ1Zm1ncl9nZW0tPmV4ZWNfY291bnQpLAoJCQkgICAgZHJtX2ludGVsX2dlbV9jb21wdXRlX2JhdGNoX3NwYWNlKGJ1Zm1ncl9nZW0tPmV4ZWNfYm9zLAoJCQkJCQkJICAgICAgYnVmbWdyX2dlbS0+ZXhlY19jb3VudCksCgkJCSAgICAodW5zaWduZWQgaW50KSBidWZtZ3JfZ2VtLT5ndHRfc2l6ZSk7CgkJfQoJfQoJZHJtX2ludGVsX3VwZGF0ZV9idWZmZXJfb2Zmc2V0czIoYnVmbWdyX2dlbSk7Cgpza2lwX2V4ZWN1dGlvbjoKCWlmIChidWZtZ3JfZ2VtLT5idWZtZ3IuZGVidWcpCgkJZHJtX2ludGVsX2dlbV9kdW1wX3ZhbGlkYXRpb25fbGlzdChidWZtZ3JfZ2VtKTsKCglmb3IgKGkgPSAwOyBpIDwgYnVmbWdyX2dlbS0+ZXhlY19jb3VudDsgaSsrKSB7CgkJZHJtX2ludGVsX2JvICpibyA9IGJ1Zm1ncl9nZW0tPmV4ZWNfYm9zW2ldOwoJCWRybV9pbnRlbF9ib19nZW0gKmJvX2dlbSA9IChkcm1faW50ZWxfYm9fZ2VtICopYm87CgoJCWJvX2dlbS0+aWRsZSA9IGZhbHNlOwoKCQkvKiBEaXNjb25uZWN0IHRoZSBidWZmZXIgZnJvbSB0aGUgdmFsaWRhdGUgbGlzdCAqLwoJCWJvX2dlbS0+dmFsaWRhdGVfaW5kZXggPSAtMTsKCQlidWZtZ3JfZ2VtLT5leGVjX2Jvc1tpXSA9IE5VTEw7Cgl9CglidWZtZ3JfZ2VtLT5leGVjX2NvdW50ID0gMDsKCXB0aHJlYWRfbXV0ZXhfdW5sb2NrKCZidWZtZ3JfZ2VtLT5sb2NrKTsKCglyZXR1cm4gcmV0Owp9CgpzdGF0aWMgaW50CmRybV9pbnRlbF9nZW1fYm9fZXhlYzIoZHJtX2ludGVsX2JvICpibywgaW50IHVzZWQsCgkJICAgICAgIGRybV9jbGlwX3JlY3RfdCAqY2xpcHJlY3RzLCBpbnQgbnVtX2NsaXByZWN0cywKCQkgICAgICAgaW50IERSNCkKewoJcmV0dXJuIGRvX2V4ZWMyKGJvLCB1c2VkLCBOVUxMLCBjbGlwcmVjdHMsIG51bV9jbGlwcmVjdHMsIERSNCwKCQkJSTkxNV9FWEVDX1JFTkRFUik7Cn0KCnN0YXRpYyBpbnQKZHJtX2ludGVsX2dlbV9ib19tcmJfZXhlYzIoZHJtX2ludGVsX2JvICpibywgaW50IHVzZWQsCgkJCWRybV9jbGlwX3JlY3RfdCAqY2xpcHJlY3RzLCBpbnQgbnVtX2NsaXByZWN0cywgaW50IERSNCwKCQkJdW5zaWduZWQgaW50IGZsYWdzKQp7CglyZXR1cm4gZG9fZXhlYzIoYm8sIHVzZWQsIE5VTEwsIGNsaXByZWN0cywgbnVtX2NsaXByZWN0cywgRFI0LAoJCQlmbGFncyk7Cn0KCmRybV9wdWJsaWMgaW50CmRybV9pbnRlbF9nZW1fYm9fY29udGV4dF9leGVjKGRybV9pbnRlbF9ibyAqYm8sIGRybV9pbnRlbF9jb250ZXh0ICpjdHgsCgkJCSAgICAgIGludCB1c2VkLCB1bnNpZ25lZCBpbnQgZmxhZ3MpCnsKCXJldHVybiBkb19leGVjMihibywgdXNlZCwgY3R4LCBOVUxMLCAwLCAwLCBmbGFncyk7Cn0KCnN0YXRpYyBpbnQKZHJtX2ludGVsX2dlbV9ib19waW4oZHJtX2ludGVsX2JvICpibywgdWludDMyX3QgYWxpZ25tZW50KQp7Cglkcm1faW50ZWxfYnVmbWdyX2dlbSAqYnVmbWdyX2dlbSA9IChkcm1faW50ZWxfYnVmbWdyX2dlbSAqKSBiby0+YnVmbWdyOwoJZHJtX2ludGVsX2JvX2dlbSAqYm9fZ2VtID0gKGRybV9pbnRlbF9ib19nZW0gKikgYm87CglzdHJ1Y3QgZHJtX2k5MTVfZ2VtX3BpbiBwaW47CglpbnQgcmV0OwoKCVZHX0NMRUFSKHBpbik7CglwaW4uaGFuZGxlID0gYm9fZ2VtLT5nZW1faGFuZGxlOwoJcGluLmFsaWdubWVudCA9IGFsaWdubWVudDsKCglyZXQgPSBkcm1Jb2N0bChidWZtZ3JfZ2VtLT5mZCwKCQkgICAgICAgRFJNX0lPQ1RMX0k5MTVfR0VNX1BJTiwKCQkgICAgICAgJnBpbik7CglpZiAocmV0ICE9IDApCgkJcmV0dXJuIC1lcnJubzsKCgliby0+b2Zmc2V0NjQgPSBwaW4ub2Zmc2V0OwoJYm8tPm9mZnNldCA9IHBpbi5vZmZzZXQ7CglyZXR1cm4gMDsKfQoKc3RhdGljIGludApkcm1faW50ZWxfZ2VtX2JvX3VucGluKGRybV9pbnRlbF9ibyAqYm8pCnsKCWRybV9pbnRlbF9idWZtZ3JfZ2VtICpidWZtZ3JfZ2VtID0gKGRybV9pbnRlbF9idWZtZ3JfZ2VtICopIGJvLT5idWZtZ3I7Cglkcm1faW50ZWxfYm9fZ2VtICpib19nZW0gPSAoZHJtX2ludGVsX2JvX2dlbSAqKSBibzsKCXN0cnVjdCBkcm1faTkxNV9nZW1fdW5waW4gdW5waW47CglpbnQgcmV0OwoKCVZHX0NMRUFSKHVucGluKTsKCXVucGluLmhhbmRsZSA9IGJvX2dlbS0+Z2VtX2hhbmRsZTsKCglyZXQgPSBkcm1Jb2N0bChidWZtZ3JfZ2VtLT5mZCwgRFJNX0lPQ1RMX0k5MTVfR0VNX1VOUElOLCAmdW5waW4pOwoJaWYgKHJldCAhPSAwKQoJCXJldHVybiAtZXJybm87CgoJcmV0dXJuIDA7Cn0KCnN0YXRpYyBpbnQKZHJtX2ludGVsX2dlbV9ib19zZXRfdGlsaW5nX2ludGVybmFsKGRybV9pbnRlbF9ibyAqYm8sCgkJCQkgICAgIHVpbnQzMl90IHRpbGluZ19tb2RlLAoJCQkJICAgICB1aW50MzJfdCBzdHJpZGUpCnsKCWRybV9pbnRlbF9idWZtZ3JfZ2VtICpidWZtZ3JfZ2VtID0gKGRybV9pbnRlbF9idWZtZ3JfZ2VtICopIGJvLT5idWZtZ3I7Cglkcm1faW50ZWxfYm9fZ2VtICpib19nZW0gPSAoZHJtX2ludGVsX2JvX2dlbSAqKSBibzsKCXN0cnVjdCBkcm1faTkxNV9nZW1fc2V0X3RpbGluZyBzZXRfdGlsaW5nOwoJaW50IHJldDsKCglpZiAoYm9fZ2VtLT5nbG9iYWxfbmFtZSA9PSAwICYmCgkgICAgdGlsaW5nX21vZGUgPT0gYm9fZ2VtLT50aWxpbmdfbW9kZSAmJgoJICAgIHN0cmlkZSA9PSBib19nZW0tPnN0cmlkZSkKCQlyZXR1cm4gMDsKCgltZW1zZXQoJnNldF90aWxpbmcsIDAsIHNpemVvZihzZXRfdGlsaW5nKSk7CglkbyB7CgkJLyogc2V0X3RpbGluZyBpcyBzbGlnaHRseSBicm9rZW4gYW5kIG92ZXJ3cml0ZXMgdGhlCgkJICogaW5wdXQgb24gdGhlIGVycm9yIHBhdGgsIHNvIHdlIGhhdmUgdG8gb3BlbiBjb2RlCgkJICogcm1Jb2N0bC4KCQkgKi8KCQlzZXRfdGlsaW5nLmhhbmRsZSA9IGJvX2dlbS0+Z2VtX2hhbmRsZTsKCQlzZXRfdGlsaW5nLnRpbGluZ19tb2RlID0gdGlsaW5nX21vZGU7CgkJc2V0X3RpbGluZy5zdHJpZGUgPSBzdHJpZGU7CgoJCXJldCA9IGlvY3RsKGJ1Zm1ncl9nZW0tPmZkLAoJCQkgICAgRFJNX0lPQ1RMX0k5MTVfR0VNX1NFVF9USUxJTkcsCgkJCSAgICAmc2V0X3RpbGluZyk7Cgl9IHdoaWxlIChyZXQgPT0gLTEgJiYgKGVycm5vID09IEVJTlRSIHx8IGVycm5vID09IEVBR0FJTikpOwoJaWYgKHJldCA9PSAtMSkKCQlyZXR1cm4gLWVycm5vOwoKCWJvX2dlbS0+dGlsaW5nX21vZGUgPSBzZXRfdGlsaW5nLnRpbGluZ19tb2RlOwoJYm9fZ2VtLT5zd2l6emxlX21vZGUgPSBzZXRfdGlsaW5nLnN3aXp6bGVfbW9kZTsKCWJvX2dlbS0+c3RyaWRlID0gc2V0X3RpbGluZy5zdHJpZGU7CglyZXR1cm4gMDsKfQoKc3RhdGljIGludApkcm1faW50ZWxfZ2VtX2JvX3NldF90aWxpbmcoZHJtX2ludGVsX2JvICpibywgdWludDMyX3QgKiB0aWxpbmdfbW9kZSwKCQkJICAgIHVpbnQzMl90IHN0cmlkZSkKewoJZHJtX2ludGVsX2J1Zm1ncl9nZW0gKmJ1Zm1ncl9nZW0gPSAoZHJtX2ludGVsX2J1Zm1ncl9nZW0gKikgYm8tPmJ1Zm1ncjsKCWRybV9pbnRlbF9ib19nZW0gKmJvX2dlbSA9IChkcm1faW50ZWxfYm9fZ2VtICopIGJvOwoJaW50IHJldDsKCgkvKiBUaWxpbmcgd2l0aCB1c2VycHRyIHN1cmZhY2VzIGlzIG5vdCBzdXBwb3J0ZWQKCSAqIG9uIGFsbCBoYXJkd2FyZSBzbyByZWZ1c2UgaXQgZm9yIHRpbWUgYmVpbmcuCgkgKi8KCWlmIChib19nZW0tPmlzX3VzZXJwdHIpCgkJcmV0dXJuIC1FSU5WQUw7CgoJLyogTGluZWFyIGJ1ZmZlcnMgaGF2ZSBubyBzdHJpZGUuIEJ5IGVuc3VyaW5nIHRoYXQgd2Ugb25seSBldmVyIHVzZQoJICogc3RyaWRlIDAgd2l0aCBsaW5lYXIgYnVmZmVycywgd2Ugc2ltcGxpZnkgb3VyIGNvZGUuCgkgKi8KCWlmICgqdGlsaW5nX21vZGUgPT0gSTkxNV9USUxJTkdfTk9ORSkKCQlzdHJpZGUgPSAwOwoKCXJldCA9IGRybV9pbnRlbF9nZW1fYm9fc2V0X3RpbGluZ19pbnRlcm5hbChibywgKnRpbGluZ19tb2RlLCBzdHJpZGUpOwoJaWYgKHJldCA9PSAwKQoJCWRybV9pbnRlbF9ib19nZW1fc2V0X2luX2FwZXJ0dXJlX3NpemUoYnVmbWdyX2dlbSwgYm9fZ2VtKTsKCgkqdGlsaW5nX21vZGUgPSBib19nZW0tPnRpbGluZ19tb2RlOwoJcmV0dXJuIHJldDsKfQoKc3RhdGljIGludApkcm1faW50ZWxfZ2VtX2JvX2dldF90aWxpbmcoZHJtX2ludGVsX2JvICpibywgdWludDMyX3QgKiB0aWxpbmdfbW9kZSwKCQkJICAgIHVpbnQzMl90ICogc3dpenpsZV9tb2RlKQp7Cglkcm1faW50ZWxfYm9fZ2VtICpib19nZW0gPSAoZHJtX2ludGVsX2JvX2dlbSAqKSBibzsKCgkqdGlsaW5nX21vZGUgPSBib19nZW0tPnRpbGluZ19tb2RlOwoJKnN3aXp6bGVfbW9kZSA9IGJvX2dlbS0+c3dpenpsZV9tb2RlOwoJcmV0dXJuIDA7Cn0KCmRybV9wdWJsaWMgZHJtX2ludGVsX2JvICoKZHJtX2ludGVsX2JvX2dlbV9jcmVhdGVfZnJvbV9wcmltZShkcm1faW50ZWxfYnVmbWdyICpidWZtZ3IsIGludCBwcmltZV9mZCwgaW50IHNpemUpCnsKCWRybV9pbnRlbF9idWZtZ3JfZ2VtICpidWZtZ3JfZ2VtID0gKGRybV9pbnRlbF9idWZtZ3JfZ2VtICopIGJ1Zm1ncjsKCWludCByZXQ7Cgl1aW50MzJfdCBoYW5kbGU7Cglkcm1faW50ZWxfYm9fZ2VtICpib19nZW07CglzdHJ1Y3QgZHJtX2k5MTVfZ2VtX2dldF90aWxpbmcgZ2V0X3RpbGluZzsKCWRybU1NTGlzdEhlYWQgKmxpc3Q7CgoJcmV0ID0gZHJtUHJpbWVGRFRvSGFuZGxlKGJ1Zm1ncl9nZW0tPmZkLCBwcmltZV9mZCwgJmhhbmRsZSk7CgoJLyoKCSAqIFNlZSBpZiB0aGUga2VybmVsIGhhcyBhbHJlYWR5IHJldHVybmVkIHRoaXMgYnVmZmVyIHRvIHVzLiBKdXN0IGFzCgkgKiBmb3IgbmFtZWQgYnVmZmVycywgd2UgbXVzdCBub3QgY3JlYXRlIHR3byBibydzIHBvaW50aW5nIGF0IHRoZSBzYW1lCgkgKiBrZXJuZWwgb2JqZWN0CgkgKi8KCXB0aHJlYWRfbXV0ZXhfbG9jaygmYnVmbWdyX2dlbS0+bG9jayk7Cglmb3IgKGxpc3QgPSBidWZtZ3JfZ2VtLT5uYW1lZC5uZXh0OwoJICAgICBsaXN0ICE9ICZidWZtZ3JfZ2VtLT5uYW1lZDsKCSAgICAgbGlzdCA9IGxpc3QtPm5leHQpIHsKCQlib19nZW0gPSBEUk1MSVNURU5UUlkoZHJtX2ludGVsX2JvX2dlbSwgbGlzdCwgbmFtZV9saXN0KTsKCQlpZiAoYm9fZ2VtLT5nZW1faGFuZGxlID09IGhhbmRsZSkgewoJCQlkcm1faW50ZWxfZ2VtX2JvX3JlZmVyZW5jZSgmYm9fZ2VtLT5ibyk7CgkJCXB0aHJlYWRfbXV0ZXhfdW5sb2NrKCZidWZtZ3JfZ2VtLT5sb2NrKTsKCQkJcmV0dXJuICZib19nZW0tPmJvOwoJCX0KCX0KCglpZiAocmV0KSB7CgkgIGZwcmludGYoc3RkZXJyLCJyZXQgaXMgJWQgJWRcbiIsIHJldCwgZXJybm8pOwoJICBwdGhyZWFkX211dGV4X3VubG9jaygmYnVmbWdyX2dlbS0+bG9jayk7CgkJcmV0dXJuIE5VTEw7Cgl9CgoJYm9fZ2VtID0gY2FsbG9jKDEsIHNpemVvZigqYm9fZ2VtKSk7CglpZiAoIWJvX2dlbSkgewoJCXB0aHJlYWRfbXV0ZXhfdW5sb2NrKCZidWZtZ3JfZ2VtLT5sb2NrKTsKCQlyZXR1cm4gTlVMTDsKCX0KCS8qIERldGVybWluZSBzaXplIG9mIGJvLiAgVGhlIGZkLXRvLWhhbmRsZSBpb2N0bCByZWFsbHkgc2hvdWxkCgkgKiByZXR1cm4gdGhlIHNpemUsIGJ1dCBpdCBkb2Vzbid0LiAgSWYgd2UgaGF2ZSBrZXJuZWwgMy4xMiBvcgoJICogbGF0ZXIsIHdlIGNhbiBsc2VlayBvbiB0aGUgcHJpbWUgZmQgdG8gZ2V0IHRoZSBzaXplLiAgT2xkZXIKCSAqIGtlcm5lbHMgd2lsbCBqdXN0IGZhaWwsIGluIHdoaWNoIGNhc2Ugd2UgZmFsbCBiYWNrIHRvIHRoZQoJICogcHJvdmlkZWQgKGVzdGltYXRlZCBvciBndWVzcyBzaXplKS4gKi8KCXJldCA9IGxzZWVrKHByaW1lX2ZkLCAwLCBTRUVLX0VORCk7CglpZiAocmV0ICE9IC0xKQoJCWJvX2dlbS0+Ym8uc2l6ZSA9IHJldDsKCWVsc2UKCQlib19nZW0tPmJvLnNpemUgPSBzaXplOwoKCWJvX2dlbS0+Ym8uaGFuZGxlID0gaGFuZGxlOwoJYm9fZ2VtLT5iby5idWZtZ3IgPSBidWZtZ3I7CgoJYm9fZ2VtLT5nZW1faGFuZGxlID0gaGFuZGxlOwoKCWF0b21pY19zZXQoJmJvX2dlbS0+cmVmY291bnQsIDEpOwoKCWJvX2dlbS0+bmFtZSA9ICJwcmltZSI7Cglib19nZW0tPnZhbGlkYXRlX2luZGV4ID0gLTE7Cglib19nZW0tPnJlbG9jX3RyZWVfZmVuY2VzID0gMDsKCWJvX2dlbS0+dXNlZF9hc19yZWxvY190YXJnZXQgPSBmYWxzZTsKCWJvX2dlbS0+aGFzX2Vycm9yID0gZmFsc2U7Cglib19nZW0tPnJldXNhYmxlID0gZmFsc2U7CgoJRFJNSU5JVExJU1RIRUFEKCZib19nZW0tPnZtYV9saXN0KTsKCURSTUxJU1RBRERUQUlMKCZib19nZW0tPm5hbWVfbGlzdCwgJmJ1Zm1ncl9nZW0tPm5hbWVkKTsKCXB0aHJlYWRfbXV0ZXhfdW5sb2NrKCZidWZtZ3JfZ2VtLT5sb2NrKTsKCglWR19DTEVBUihnZXRfdGlsaW5nKTsKCWdldF90aWxpbmcuaGFuZGxlID0gYm9fZ2VtLT5nZW1faGFuZGxlOwoJcmV0ID0gZHJtSW9jdGwoYnVmbWdyX2dlbS0+ZmQsCgkJICAgICAgIERSTV9JT0NUTF9JOTE1X0dFTV9HRVRfVElMSU5HLAoJCSAgICAgICAmZ2V0X3RpbGluZyk7CglpZiAocmV0ICE9IDApIHsKCQlkcm1faW50ZWxfZ2VtX2JvX3VucmVmZXJlbmNlKCZib19nZW0tPmJvKTsKCQlyZXR1cm4gTlVMTDsKCX0KCWJvX2dlbS0+dGlsaW5nX21vZGUgPSBnZXRfdGlsaW5nLnRpbGluZ19tb2RlOwoJYm9fZ2VtLT5zd2l6emxlX21vZGUgPSBnZXRfdGlsaW5nLnN3aXp6bGVfbW9kZTsKCS8qIFhYWCBzdHJpZGUgaXMgdW5rbm93biAqLwoJZHJtX2ludGVsX2JvX2dlbV9zZXRfaW5fYXBlcnR1cmVfc2l6ZShidWZtZ3JfZ2VtLCBib19nZW0pOwoKCXJldHVybiAmYm9fZ2VtLT5ibzsKfQoKZHJtX3B1YmxpYyBpbnQKZHJtX2ludGVsX2JvX2dlbV9leHBvcnRfdG9fcHJpbWUoZHJtX2ludGVsX2JvICpibywgaW50ICpwcmltZV9mZCkKewoJZHJtX2ludGVsX2J1Zm1ncl9nZW0gKmJ1Zm1ncl9nZW0gPSAoZHJtX2ludGVsX2J1Zm1ncl9nZW0gKikgYm8tPmJ1Zm1ncjsKCWRybV9pbnRlbF9ib19nZW0gKmJvX2dlbSA9IChkcm1faW50ZWxfYm9fZ2VtICopIGJvOwoKCXB0aHJlYWRfbXV0ZXhfbG9jaygmYnVmbWdyX2dlbS0+bG9jayk7CiAgICAgICAgaWYgKERSTUxJU1RFTVBUWSgmYm9fZ2VtLT5uYW1lX2xpc3QpKQogICAgICAgICAgICAgICAgRFJNTElTVEFERFRBSUwoJmJvX2dlbS0+bmFtZV9saXN0LCAmYnVmbWdyX2dlbS0+bmFtZWQpOwoJcHRocmVhZF9tdXRleF91bmxvY2soJmJ1Zm1ncl9nZW0tPmxvY2spOwoKCWlmIChkcm1QcmltZUhhbmRsZVRvRkQoYnVmbWdyX2dlbS0+ZmQsIGJvX2dlbS0+Z2VtX2hhbmRsZSwKCQkJICAgICAgIERSTV9DTE9FWEVDLCBwcmltZV9mZCkgIT0gMCkKCQlyZXR1cm4gLWVycm5vOwoKCWJvX2dlbS0+cmV1c2FibGUgPSBmYWxzZTsKCglyZXR1cm4gMDsKfQoKc3RhdGljIGludApkcm1faW50ZWxfZ2VtX2JvX2ZsaW5rKGRybV9pbnRlbF9ibyAqYm8sIHVpbnQzMl90ICogbmFtZSkKewoJZHJtX2ludGVsX2J1Zm1ncl9nZW0gKmJ1Zm1ncl9nZW0gPSAoZHJtX2ludGVsX2J1Zm1ncl9nZW0gKikgYm8tPmJ1Zm1ncjsKCWRybV9pbnRlbF9ib19nZW0gKmJvX2dlbSA9IChkcm1faW50ZWxfYm9fZ2VtICopIGJvOwoJaW50IHJldDsKCglpZiAoIWJvX2dlbS0+Z2xvYmFsX25hbWUpIHsKCQlzdHJ1Y3QgZHJtX2dlbV9mbGluayBmbGluazsKCgkJVkdfQ0xFQVIoZmxpbmspOwoJCWZsaW5rLmhhbmRsZSA9IGJvX2dlbS0+Z2VtX2hhbmRsZTsKCgkJcHRocmVhZF9tdXRleF9sb2NrKCZidWZtZ3JfZ2VtLT5sb2NrKTsKCgkJcmV0ID0gZHJtSW9jdGwoYnVmbWdyX2dlbS0+ZmQsIERSTV9JT0NUTF9HRU1fRkxJTkssICZmbGluayk7CgkJaWYgKHJldCAhPSAwKSB7CgkJCXB0aHJlYWRfbXV0ZXhfdW5sb2NrKCZidWZtZ3JfZ2VtLT5sb2NrKTsKCQkJcmV0dXJuIC1lcnJubzsKCQl9CgoJCWJvX2dlbS0+Z2xvYmFsX25hbWUgPSBmbGluay5uYW1lOwoJCWJvX2dlbS0+cmV1c2FibGUgPSBmYWxzZTsKCiAgICAgICAgICAgICAgICBpZiAoRFJNTElTVEVNUFRZKCZib19nZW0tPm5hbWVfbGlzdCkpCiAgICAgICAgICAgICAgICAgICAgICAgIERSTUxJU1RBRERUQUlMKCZib19nZW0tPm5hbWVfbGlzdCwgJmJ1Zm1ncl9nZW0tPm5hbWVkKTsKCQlwdGhyZWFkX211dGV4X3VubG9jaygmYnVmbWdyX2dlbS0+bG9jayk7Cgl9CgoJKm5hbWUgPSBib19nZW0tPmdsb2JhbF9uYW1lOwoJcmV0dXJuIDA7Cn0KCi8qKgogKiBFbmFibGVzIHVubGltaXRlZCBjYWNoaW5nIG9mIGJ1ZmZlciBvYmplY3RzIGZvciByZXVzZS4KICoKICogVGhpcyBpcyBwb3RlbnRpYWxseSB2ZXJ5IG1lbW9yeSBleHBlbnNpdmUsIGFzIHRoZSBjYWNoZSBhdCBlYWNoIGJ1Y2tldAogKiBzaXplIGlzIG9ubHkgYm91bmRlZCBieSBob3cgbWFueSBidWZmZXJzIG9mIHRoYXQgc2l6ZSB3ZSd2ZSBtYW5hZ2VkIHRvIGhhdmUKICogaW4gZmxpZ2h0IGF0IG9uY2UuCiAqLwpkcm1fcHVibGljIHZvaWQKZHJtX2ludGVsX2J1Zm1ncl9nZW1fZW5hYmxlX3JldXNlKGRybV9pbnRlbF9idWZtZ3IgKmJ1Zm1ncikKewoJZHJtX2ludGVsX2J1Zm1ncl9nZW0gKmJ1Zm1ncl9nZW0gPSAoZHJtX2ludGVsX2J1Zm1ncl9nZW0gKikgYnVmbWdyOwoKCWJ1Zm1ncl9nZW0tPmJvX3JldXNlID0gdHJ1ZTsKfQoKLyoqCiAqIEVuYWJsZSB1c2Ugb2YgZmVuY2VkIHJlbG9jIHR5cGUuCiAqCiAqIE5ldyBjb2RlIHNob3VsZCBlbmFibGUgdGhpcyB0byBhdm9pZCB1bm5lY2Vzc2FyeSBmZW5jZSByZWdpc3RlcgogKiBhbGxvY2F0aW9uLiAgSWYgdGhpcyBvcHRpb24gaXMgbm90IGVuYWJsZWQsIGFsbCByZWxvY3Mgd2lsbCBoYXZlIGZlbmNlCiAqIHJlZ2lzdGVyIGFsbG9jYXRlZC4KICovCmRybV9wdWJsaWMgdm9pZApkcm1faW50ZWxfYnVmbWdyX2dlbV9lbmFibGVfZmVuY2VkX3JlbG9jcyhkcm1faW50ZWxfYnVmbWdyICpidWZtZ3IpCnsKCWRybV9pbnRlbF9idWZtZ3JfZ2VtICpidWZtZ3JfZ2VtID0gKGRybV9pbnRlbF9idWZtZ3JfZ2VtICopYnVmbWdyOwoKCWlmIChidWZtZ3JfZ2VtLT5idWZtZ3IuYm9fZXhlYyA9PSBkcm1faW50ZWxfZ2VtX2JvX2V4ZWMyKQoJCWJ1Zm1ncl9nZW0tPmZlbmNlZF9yZWxvY3MgPSB0cnVlOwp9CgovKioKICogUmV0dXJuIHRoZSBhZGRpdGlvbmFsIGFwZXJ0dXJlIHNwYWNlIHJlcXVpcmVkIGJ5IHRoZSB0cmVlIG9mIGJ1ZmZlciBvYmplY3RzCiAqIHJvb3RlZCBhdCBiby4KICovCnN0YXRpYyBpbnQKZHJtX2ludGVsX2dlbV9ib19nZXRfYXBlcnR1cmVfc3BhY2UoZHJtX2ludGVsX2JvICpibykKewoJZHJtX2ludGVsX2JvX2dlbSAqYm9fZ2VtID0gKGRybV9pbnRlbF9ib19nZW0gKikgYm87CglpbnQgaTsKCWludCB0b3RhbCA9IDA7CgoJaWYgKGJvID09IE5VTEwgfHwgYm9fZ2VtLT5pbmNsdWRlZF9pbl9jaGVja19hcGVydHVyZSkKCQlyZXR1cm4gMDsKCgl0b3RhbCArPSBiby0+c2l6ZTsKCWJvX2dlbS0+aW5jbHVkZWRfaW5fY2hlY2tfYXBlcnR1cmUgPSB0cnVlOwoKCWZvciAoaSA9IDA7IGkgPCBib19nZW0tPnJlbG9jX2NvdW50OyBpKyspCgkJdG90YWwgKz0KCQkgICAgZHJtX2ludGVsX2dlbV9ib19nZXRfYXBlcnR1cmVfc3BhY2UoYm9fZ2VtLT4KCQkJCQkJCXJlbG9jX3RhcmdldF9pbmZvW2ldLmJvKTsKCglyZXR1cm4gdG90YWw7Cn0KCi8qKgogKiBDb3VudCB0aGUgbnVtYmVyIG9mIGJ1ZmZlcnMgaW4gdGhpcyBsaXN0IHRoYXQgbmVlZCBhIGZlbmNlIHJlZwogKgogKiBJZiB0aGUgY291bnQgaXMgZ3JlYXRlciB0aGFuIHRoZSBudW1iZXIgb2YgYXZhaWxhYmxlIHJlZ3MsIHdlJ2xsIGhhdmUKICogdG8gYXNrIHRoZSBjYWxsZXIgdG8gcmVzdWJtaXQgYSBiYXRjaCB3aXRoIGZld2VyIHRpbGVkIGJ1ZmZlcnMuCiAqCiAqIFRoaXMgZnVuY3Rpb24gb3Zlci1jb3VudHMgaWYgdGhlIHNhbWUgYnVmZmVyIGlzIHVzZWQgbXVsdGlwbGUgdGltZXMuCiAqLwpzdGF0aWMgdW5zaWduZWQgaW50CmRybV9pbnRlbF9nZW1fdG90YWxfZmVuY2VzKGRybV9pbnRlbF9ibyAqKiBib19hcnJheSwgaW50IGNvdW50KQp7CglpbnQgaTsKCXVuc2lnbmVkIGludCB0b3RhbCA9IDA7CgoJZm9yIChpID0gMDsgaSA8IGNvdW50OyBpKyspIHsKCQlkcm1faW50ZWxfYm9fZ2VtICpib19nZW0gPSAoZHJtX2ludGVsX2JvX2dlbSAqKSBib19hcnJheVtpXTsKCgkJaWYgKGJvX2dlbSA9PSBOVUxMKQoJCQljb250aW51ZTsKCgkJdG90YWwgKz0gYm9fZ2VtLT5yZWxvY190cmVlX2ZlbmNlczsKCX0KCXJldHVybiB0b3RhbDsKfQoKLyoqCiAqIENsZWFyIHRoZSBmbGFnIHNldCBieSBkcm1faW50ZWxfZ2VtX2JvX2dldF9hcGVydHVyZV9zcGFjZSgpIHNvIHdlJ3JlIHJlYWR5CiAqIGZvciB0aGUgbmV4dCBkcm1faW50ZWxfYnVmbWdyX2NoZWNrX2FwZXJ0dXJlX3NwYWNlKCkgY2FsbC4KICovCnN0YXRpYyB2b2lkCmRybV9pbnRlbF9nZW1fYm9fY2xlYXJfYXBlcnR1cmVfc3BhY2VfZmxhZyhkcm1faW50ZWxfYm8gKmJvKQp7Cglkcm1faW50ZWxfYm9fZ2VtICpib19nZW0gPSAoZHJtX2ludGVsX2JvX2dlbSAqKSBibzsKCWludCBpOwoKCWlmIChibyA9PSBOVUxMIHx8ICFib19nZW0tPmluY2x1ZGVkX2luX2NoZWNrX2FwZXJ0dXJlKQoJCXJldHVybjsKCglib19nZW0tPmluY2x1ZGVkX2luX2NoZWNrX2FwZXJ0dXJlID0gZmFsc2U7CgoJZm9yIChpID0gMDsgaSA8IGJvX2dlbS0+cmVsb2NfY291bnQ7IGkrKykKCQlkcm1faW50ZWxfZ2VtX2JvX2NsZWFyX2FwZXJ0dXJlX3NwYWNlX2ZsYWcoYm9fZ2VtLT4KCQkJCQkJCSAgIHJlbG9jX3RhcmdldF9pbmZvW2ldLmJvKTsKfQoKLyoqCiAqIFJldHVybiBhIGNvbnNlcnZhdGl2ZSBlc3RpbWF0ZSBmb3IgdGhlIGFtb3VudCBvZiBhcGVydHVyZSByZXF1aXJlZAogKiBmb3IgYSBjb2xsZWN0aW9uIG9mIGJ1ZmZlcnMuIFRoaXMgbWF5IGRvdWJsZS1jb3VudCBzb21lIGJ1ZmZlcnMuCiAqLwpzdGF0aWMgdW5zaWduZWQgaW50CmRybV9pbnRlbF9nZW1fZXN0aW1hdGVfYmF0Y2hfc3BhY2UoZHJtX2ludGVsX2JvICoqYm9fYXJyYXksIGludCBjb3VudCkKewoJaW50IGk7Cgl1bnNpZ25lZCBpbnQgdG90YWwgPSAwOwoKCWZvciAoaSA9IDA7IGkgPCBjb3VudDsgaSsrKSB7CgkJZHJtX2ludGVsX2JvX2dlbSAqYm9fZ2VtID0gKGRybV9pbnRlbF9ib19nZW0gKikgYm9fYXJyYXlbaV07CgkJaWYgKGJvX2dlbSAhPSBOVUxMKQoJCQl0b3RhbCArPSBib19nZW0tPnJlbG9jX3RyZWVfc2l6ZTsKCX0KCXJldHVybiB0b3RhbDsKfQoKLyoqCiAqIFJldHVybiB0aGUgYW1vdW50IG9mIGFwZXJ0dXJlIG5lZWRlZCBmb3IgYSBjb2xsZWN0aW9uIG9mIGJ1ZmZlcnMuCiAqIFRoaXMgYXZvaWRzIGRvdWJsZSBjb3VudGluZyBhbnkgYnVmZmVycywgYXQgdGhlIGNvc3Qgb2YgbG9va2luZwogKiBhdCBldmVyeSBidWZmZXIgaW4gdGhlIHNldC4KICovCnN0YXRpYyB1bnNpZ25lZCBpbnQKZHJtX2ludGVsX2dlbV9jb21wdXRlX2JhdGNoX3NwYWNlKGRybV9pbnRlbF9ibyAqKmJvX2FycmF5LCBpbnQgY291bnQpCnsKCWludCBpOwoJdW5zaWduZWQgaW50IHRvdGFsID0gMDsKCglmb3IgKGkgPSAwOyBpIDwgY291bnQ7IGkrKykgewoJCXRvdGFsICs9IGRybV9pbnRlbF9nZW1fYm9fZ2V0X2FwZXJ0dXJlX3NwYWNlKGJvX2FycmF5W2ldKTsKCQkvKiBGb3IgdGhlIGZpcnN0IGJ1ZmZlciBvYmplY3QgaW4gdGhlIGFycmF5LCB3ZSBnZXQgYW4KCQkgKiBhY2N1cmF0ZSBjb3VudCBiYWNrIGZvciBpdHMgcmVsb2NfdHJlZSBzaXplIChzaW5jZSBub3RoaW5nCgkJICogaGFkIGJlZW4gZmxhZ2dlZCBhcyBiZWluZyBjb3VudGVkIHlldCkuICBXZSBjYW4gc2F2ZSB0aGF0CgkJICogdmFsdWUgb3V0IGFzIGEgbW9yZSBjb25zZXJ2YXRpdmUgcmVsb2NfdHJlZV9zaXplIHRoYXQKCQkgKiBhdm9pZHMgZG91YmxlLWNvdW50aW5nIHRhcmdldCBidWZmZXJzLiAgU2luY2UgdGhlIGZpcnN0CgkJICogYnVmZmVyIGhhcHBlbnMgdG8gdXN1YWxseSBiZSB0aGUgYmF0Y2ggYnVmZmVyIGluIG91cgoJCSAqIGNhbGxlcnMsIHRoaXMgY2FuIHB1bGwgdXMgYmFjayBmcm9tIGRvaW5nIHRoZSB0cmVlCgkJICogd2FsayBvbiBldmVyeSBuZXcgYmF0Y2ggZW1pdC4KCQkgKi8KCQlpZiAoaSA9PSAwKSB7CgkJCWRybV9pbnRlbF9ib19nZW0gKmJvX2dlbSA9CgkJCSAgICAoZHJtX2ludGVsX2JvX2dlbSAqKSBib19hcnJheVtpXTsKCQkJYm9fZ2VtLT5yZWxvY190cmVlX3NpemUgPSB0b3RhbDsKCQl9Cgl9CgoJZm9yIChpID0gMDsgaSA8IGNvdW50OyBpKyspCgkJZHJtX2ludGVsX2dlbV9ib19jbGVhcl9hcGVydHVyZV9zcGFjZV9mbGFnKGJvX2FycmF5W2ldKTsKCXJldHVybiB0b3RhbDsKfQoKLyoqCiAqIFJldHVybiAtMSBpZiB0aGUgYmF0Y2hidWZmZXIgc2hvdWxkIGJlIGZsdXNoZWQgYmVmb3JlIGF0dGVtcHRpbmcgdG8KICogZW1pdCByZW5kZXJpbmcgcmVmZXJlbmNpbmcgdGhlIGJ1ZmZlcnMgcG9pbnRlZCB0byBieSBib19hcnJheS4KICoKICogVGhpcyBpcyByZXF1aXJlZCBiZWNhdXNlIGlmIHdlIHRyeSB0byBlbWl0IGEgYmF0Y2hidWZmZXIgd2l0aCByZWxvY2F0aW9ucwogKiB0byBhIHRyZWUgb2YgYnVmZmVycyB0aGF0IHdvbid0IHNpbXVsdGFuZW91c2x5IGZpdCBpbiB0aGUgYXBlcnR1cmUsCiAqIHRoZSByZW5kZXJpbmcgd2lsbCByZXR1cm4gYW4gZXJyb3IgYXQgYSBwb2ludCB3aGVyZSB0aGUgc29mdHdhcmUgaXMgbm90CiAqIHByZXBhcmVkIHRvIHJlY292ZXIgZnJvbSBpdC4KICoKICogSG93ZXZlciwgd2UgYWxzbyB3YW50IHRvIGVtaXQgdGhlIGJhdGNoYnVmZmVyIHNpZ25pZmljYW50bHkgYmVmb3JlIHdlIHJlYWNoCiAqIHRoZSBsaW1pdCwgYXMgYSBzZXJpZXMgb2YgYmF0Y2hidWZmZXJzIGVhY2ggb2Ygd2hpY2ggcmVmZXJlbmNlcyBidWZmZXJzCiAqIGNvdmVyaW5nIGFsbW9zdCBhbGwgb2YgdGhlIGFwZXJ0dXJlIG1lYW5zIHRoYXQgYXQgZWFjaCBlbWl0IHdlIGVuZCB1cAogKiB3YWl0aW5nIHRvIGV2aWN0IGEgYnVmZmVyIGZyb20gdGhlIGxhc3QgcmVuZGVyaW5nLCBhbmQgd2UgZ2V0IHN5bmNocm9ub3VzCiAqIHBlcmZvcm1hbmNlLiAgQnkgZW1pdHRpbmcgc21hbGxlciBiYXRjaGJ1ZmZlcnMsIHdlIGVhdCBzb21lIENQVSBvdmVyaGVhZCB0bwogKiBnZXQgYmV0dGVyIHBhcmFsbGVsaXNtLgogKi8Kc3RhdGljIGludApkcm1faW50ZWxfZ2VtX2NoZWNrX2FwZXJ0dXJlX3NwYWNlKGRybV9pbnRlbF9ibyAqKmJvX2FycmF5LCBpbnQgY291bnQpCnsKCWRybV9pbnRlbF9idWZtZ3JfZ2VtICpidWZtZ3JfZ2VtID0KCSAgICAoZHJtX2ludGVsX2J1Zm1ncl9nZW0gKikgYm9fYXJyYXlbMF0tPmJ1Zm1ncjsKCXVuc2lnbmVkIGludCB0b3RhbCA9IDA7Cgl1bnNpZ25lZCBpbnQgdGhyZXNob2xkID0gYnVmbWdyX2dlbS0+Z3R0X3NpemUgKiAzIC8gNDsKCWludCB0b3RhbF9mZW5jZXM7CgoJLyogQ2hlY2sgZm9yIGZlbmNlIHJlZyBjb25zdHJhaW50cyBpZiBuZWNlc3NhcnkgKi8KCWlmIChidWZtZ3JfZ2VtLT5hdmFpbGFibGVfZmVuY2VzKSB7CgkJdG90YWxfZmVuY2VzID0gZHJtX2ludGVsX2dlbV90b3RhbF9mZW5jZXMoYm9fYXJyYXksIGNvdW50KTsKCQlpZiAodG90YWxfZmVuY2VzID4gYnVmbWdyX2dlbS0+YXZhaWxhYmxlX2ZlbmNlcykKCQkJcmV0dXJuIC1FTk9TUEM7Cgl9CgoJdG90YWwgPSBkcm1faW50ZWxfZ2VtX2VzdGltYXRlX2JhdGNoX3NwYWNlKGJvX2FycmF5LCBjb3VudCk7CgoJaWYgKHRvdGFsID4gdGhyZXNob2xkKQoJCXRvdGFsID0gZHJtX2ludGVsX2dlbV9jb21wdXRlX2JhdGNoX3NwYWNlKGJvX2FycmF5LCBjb3VudCk7CgoJaWYgKHRvdGFsID4gdGhyZXNob2xkKSB7CgkJREJHKCJjaGVja19zcGFjZTogb3ZlcmZsb3dlZCBhdmFpbGFibGUgYXBlcnR1cmUsICIKCQkgICAgIiVka2IgdnMgJWRrYlxuIiwKCQkgICAgdG90YWwgLyAxMDI0LCAoaW50KWJ1Zm1ncl9nZW0tPmd0dF9zaXplIC8gMTAyNCk7CgkJcmV0dXJuIC1FTk9TUEM7Cgl9IGVsc2UgewoJCURCRygiZHJtX2NoZWNrX3NwYWNlOiB0b3RhbCAlZGtiIHZzIGJ1ZmdyICVka2JcbiIsIHRvdGFsIC8gMTAyNCwKCQkgICAgKGludClidWZtZ3JfZ2VtLT5ndHRfc2l6ZSAvIDEwMjQpOwoJCXJldHVybiAwOwoJfQp9CgovKgogKiBEaXNhYmxlIGJ1ZmZlciByZXVzZSBmb3Igb2JqZWN0cyB3aGljaCBhcmUgc2hhcmVkIHdpdGggdGhlIGtlcm5lbAogKiBhcyBzY2Fub3V0IGJ1ZmZlcnMKICovCnN0YXRpYyBpbnQKZHJtX2ludGVsX2dlbV9ib19kaXNhYmxlX3JldXNlKGRybV9pbnRlbF9ibyAqYm8pCnsKCWRybV9pbnRlbF9ib19nZW0gKmJvX2dlbSA9IChkcm1faW50ZWxfYm9fZ2VtICopIGJvOwoKCWJvX2dlbS0+cmV1c2FibGUgPSBmYWxzZTsKCXJldHVybiAwOwp9CgpzdGF0aWMgaW50CmRybV9pbnRlbF9nZW1fYm9faXNfcmV1c2FibGUoZHJtX2ludGVsX2JvICpibykKewoJZHJtX2ludGVsX2JvX2dlbSAqYm9fZ2VtID0gKGRybV9pbnRlbF9ib19nZW0gKikgYm87CgoJcmV0dXJuIGJvX2dlbS0+cmV1c2FibGU7Cn0KCnN0YXRpYyBpbnQKX2RybV9pbnRlbF9nZW1fYm9fcmVmZXJlbmNlcyhkcm1faW50ZWxfYm8gKmJvLCBkcm1faW50ZWxfYm8gKnRhcmdldF9ibykKewoJZHJtX2ludGVsX2JvX2dlbSAqYm9fZ2VtID0gKGRybV9pbnRlbF9ib19nZW0gKikgYm87CglpbnQgaTsKCglmb3IgKGkgPSAwOyBpIDwgYm9fZ2VtLT5yZWxvY19jb3VudDsgaSsrKSB7CgkJaWYgKGJvX2dlbS0+cmVsb2NfdGFyZ2V0X2luZm9baV0uYm8gPT0gdGFyZ2V0X2JvKQoJCQlyZXR1cm4gMTsKCQlpZiAoYm8gPT0gYm9fZ2VtLT5yZWxvY190YXJnZXRfaW5mb1tpXS5ibykKCQkJY29udGludWU7CgkJaWYgKF9kcm1faW50ZWxfZ2VtX2JvX3JlZmVyZW5jZXMoYm9fZ2VtLT5yZWxvY190YXJnZXRfaW5mb1tpXS5ibywKCQkJCQkJdGFyZ2V0X2JvKSkKCQkJcmV0dXJuIDE7Cgl9CgoJcmV0dXJuIDA7Cn0KCi8qKiBSZXR1cm4gdHJ1ZSBpZiB0YXJnZXRfYm8gaXMgcmVmZXJlbmNlZCBieSBibydzIHJlbG9jYXRpb24gdHJlZS4gKi8Kc3RhdGljIGludApkcm1faW50ZWxfZ2VtX2JvX3JlZmVyZW5jZXMoZHJtX2ludGVsX2JvICpibywgZHJtX2ludGVsX2JvICp0YXJnZXRfYm8pCnsKCWRybV9pbnRlbF9ib19nZW0gKnRhcmdldF9ib19nZW0gPSAoZHJtX2ludGVsX2JvX2dlbSAqKSB0YXJnZXRfYm87CgoJaWYgKGJvID09IE5VTEwgfHwgdGFyZ2V0X2JvID09IE5VTEwpCgkJcmV0dXJuIDA7CglpZiAodGFyZ2V0X2JvX2dlbS0+dXNlZF9hc19yZWxvY190YXJnZXQpCgkJcmV0dXJuIF9kcm1faW50ZWxfZ2VtX2JvX3JlZmVyZW5jZXMoYm8sIHRhcmdldF9ibyk7CglyZXR1cm4gMDsKfQoKc3RhdGljIHZvaWQKYWRkX2J1Y2tldChkcm1faW50ZWxfYnVmbWdyX2dlbSAqYnVmbWdyX2dlbSwgaW50IHNpemUpCnsKCXVuc2lnbmVkIGludCBpID0gYnVmbWdyX2dlbS0+bnVtX2J1Y2tldHM7CgoJYXNzZXJ0KGkgPCBBUlJBWV9TSVpFKGJ1Zm1ncl9nZW0tPmNhY2hlX2J1Y2tldCkpOwoKCURSTUlOSVRMSVNUSEVBRCgmYnVmbWdyX2dlbS0+Y2FjaGVfYnVja2V0W2ldLmhlYWQpOwoJYnVmbWdyX2dlbS0+Y2FjaGVfYnVja2V0W2ldLnNpemUgPSBzaXplOwoJYnVmbWdyX2dlbS0+bnVtX2J1Y2tldHMrKzsKfQoKc3RhdGljIHZvaWQKaW5pdF9jYWNoZV9idWNrZXRzKGRybV9pbnRlbF9idWZtZ3JfZ2VtICpidWZtZ3JfZ2VtKQp7Cgl1bnNpZ25lZCBsb25nIHNpemUsIGNhY2hlX21heF9zaXplID0gNjQgKiAxMDI0ICogMTAyNDsKCgkvKiBPSywgc28gcG93ZXIgb2YgdHdvIGJ1Y2tldHMgd2FzIHRvbyB3YXN0ZWZ1bCBvZiBtZW1vcnkuCgkgKiBHaXZlIDMgb3RoZXIgc2l6ZXMgYmV0d2VlbiBlYWNoIHBvd2VyIG9mIHR3bywgdG8gaG9wZWZ1bGx5CgkgKiBjb3ZlciB0aGluZ3MgYWNjdXJhdGVseSBlbm91Z2guICAoVGhlIGFsdGVybmF0aXZlIGlzCgkgKiBwcm9iYWJseSB0byBqdXN0IGdvIGZvciBleGFjdCBtYXRjaGluZyBvZiBzaXplcywgYW5kIGFzc3VtZQoJICogdGhhdCBmb3IgdGhpbmdzIGxpa2UgY29tcG9zaXRlZCB3aW5kb3cgcmVzaXplIHRoZSB0aWxlZAoJICogd2lkdGgvaGVpZ2h0IGFsaWdubWVudCBhbmQgcm91bmRpbmcgb2Ygc2l6ZXMgdG8gcGFnZXMgd2lsbAoJICogZ2V0IHVzIHVzZWZ1bCBjYWNoZSBoaXQgcmF0ZXMgYW55d2F5KQoJICovCglhZGRfYnVja2V0KGJ1Zm1ncl9nZW0sIDQwOTYpOwoJYWRkX2J1Y2tldChidWZtZ3JfZ2VtLCA0MDk2ICogMik7CglhZGRfYnVja2V0KGJ1Zm1ncl9nZW0sIDQwOTYgKiAzKTsKCgkvKiBJbml0aWFsaXplIHRoZSBsaW5rZWQgbGlzdHMgZm9yIEJPIHJldXNlIGNhY2hlLiAqLwoJZm9yIChzaXplID0gNCAqIDQwOTY7IHNpemUgPD0gY2FjaGVfbWF4X3NpemU7IHNpemUgKj0gMikgewoJCWFkZF9idWNrZXQoYnVmbWdyX2dlbSwgc2l6ZSk7CgoJCWFkZF9idWNrZXQoYnVmbWdyX2dlbSwgc2l6ZSArIHNpemUgKiAxIC8gNCk7CgkJYWRkX2J1Y2tldChidWZtZ3JfZ2VtLCBzaXplICsgc2l6ZSAqIDIgLyA0KTsKCQlhZGRfYnVja2V0KGJ1Zm1ncl9nZW0sIHNpemUgKyBzaXplICogMyAvIDQpOwoJfQp9Cgpkcm1fcHVibGljIHZvaWQKZHJtX2ludGVsX2J1Zm1ncl9nZW1fc2V0X3ZtYV9jYWNoZV9zaXplKGRybV9pbnRlbF9idWZtZ3IgKmJ1Zm1nciwgaW50IGxpbWl0KQp7Cglkcm1faW50ZWxfYnVmbWdyX2dlbSAqYnVmbWdyX2dlbSA9IChkcm1faW50ZWxfYnVmbWdyX2dlbSAqKWJ1Zm1ncjsKCglidWZtZ3JfZ2VtLT52bWFfbWF4ID0gbGltaXQ7CgoJZHJtX2ludGVsX2dlbV9ib19wdXJnZV92bWFfY2FjaGUoYnVmbWdyX2dlbSk7Cn0KCi8qKgogKiBHZXQgdGhlIFBDSSBJRCBmb3IgdGhlIGRldmljZS4gIFRoaXMgY2FuIGJlIG92ZXJyaWRkZW4gYnkgc2V0dGluZyB0aGUKICogSU5URUxfREVWSURfT1ZFUlJJREUgZW52aXJvbm1lbnQgdmFyaWFibGUgdG8gdGhlIGRlc2lyZWQgSUQuCiAqLwpzdGF0aWMgaW50CmdldF9wY2lfZGV2aWNlX2lkKGRybV9pbnRlbF9idWZtZ3JfZ2VtICpidWZtZ3JfZ2VtKQp7CgljaGFyICpkZXZpZF9vdmVycmlkZTsKCWludCBkZXZpZDsKCWludCByZXQ7Cglkcm1faTkxNV9nZXRwYXJhbV90IGdwOwoKCWlmIChnZXRldWlkKCkgPT0gZ2V0dWlkKCkpIHsKCQlkZXZpZF9vdmVycmlkZSA9IGdldGVudigiSU5URUxfREVWSURfT1ZFUlJJREUiKTsKCQlpZiAoZGV2aWRfb3ZlcnJpZGUpIHsKCQkJYnVmbWdyX2dlbS0+bm9fZXhlYyA9IHRydWU7CgkJCXJldHVybiBzdHJ0b2QoZGV2aWRfb3ZlcnJpZGUsIE5VTEwpOwoJCX0KCX0KCglWR19DTEVBUihkZXZpZCk7CglWR19DTEVBUihncCk7CglncC5wYXJhbSA9IEk5MTVfUEFSQU1fQ0hJUFNFVF9JRDsKCWdwLnZhbHVlID0gJmRldmlkOwoJcmV0ID0gZHJtSW9jdGwoYnVmbWdyX2dlbS0+ZmQsIERSTV9JT0NUTF9JOTE1X0dFVFBBUkFNLCAmZ3ApOwoJaWYgKHJldCkgewoJCWZwcmludGYoc3RkZXJyLCAiZ2V0IGNoaXAgaWQgZmFpbGVkOiAlZCBbJWRdXG4iLCByZXQsIGVycm5vKTsKCQlmcHJpbnRmKHN0ZGVyciwgInBhcmFtOiAlZCwgdmFsOiAlZFxuIiwgZ3AucGFyYW0sICpncC52YWx1ZSk7Cgl9CglyZXR1cm4gZGV2aWQ7Cn0KCmRybV9wdWJsaWMgaW50CmRybV9pbnRlbF9idWZtZ3JfZ2VtX2dldF9kZXZpZChkcm1faW50ZWxfYnVmbWdyICpidWZtZ3IpCnsKCWRybV9pbnRlbF9idWZtZ3JfZ2VtICpidWZtZ3JfZ2VtID0gKGRybV9pbnRlbF9idWZtZ3JfZ2VtICopYnVmbWdyOwoKCXJldHVybiBidWZtZ3JfZ2VtLT5wY2lfZGV2aWNlOwp9CgovKioKICogU2V0cyB0aGUgQVVCIGZpbGVuYW1lLgogKgogKiBUaGlzIGZ1bmN0aW9uIGhhcyB0byBiZSBjYWxsZWQgYmVmb3JlIGRybV9pbnRlbF9idWZtZ3JfZ2VtX3NldF9hdWJfZHVtcCgpCiAqIGZvciBpdCB0byBoYXZlIGFueSBlZmZlY3QuCiAqLwpkcm1fcHVibGljIHZvaWQKZHJtX2ludGVsX2J1Zm1ncl9nZW1fc2V0X2F1Yl9maWxlbmFtZShkcm1faW50ZWxfYnVmbWdyICpidWZtZ3IsCgkJCQkgICAgICBjb25zdCBjaGFyICpmaWxlbmFtZSkKewoJZHJtX2ludGVsX2J1Zm1ncl9nZW0gKmJ1Zm1ncl9nZW0gPSAoZHJtX2ludGVsX2J1Zm1ncl9nZW0gKilidWZtZ3I7CgoJZnJlZShidWZtZ3JfZ2VtLT5hdWJfZmlsZW5hbWUpOwoJaWYgKGZpbGVuYW1lKQoJCWJ1Zm1ncl9nZW0tPmF1Yl9maWxlbmFtZSA9IHN0cmR1cChmaWxlbmFtZSk7Cn0KCi8qKgogKiBTZXRzIHVwIEFVQiBkdW1waW5nLgogKgogKiBUaGlzIGlzIGEgdHJhY2UgZmlsZSBmb3JtYXQgdGhhdCBjYW4gYmUgdXNlZCB3aXRoIHRoZSBzaW11bGF0b3IuCiAqIFBhY2tldHMgYXJlIGVtaXR0ZWQgaW4gYSBmb3JtYXQgc29tZXdoYXQgbGlrZSBHUFUgY29tbWFuZCBwYWNrZXRzLgogKiBZb3UgY2FuIHNldCB1cCBhIEdUVCBhbmQgdXBsb2FkIHlvdXIgb2JqZWN0cyBpbnRvIHRoZSByZWZlcmVuY2VkCiAqIHNwYWNlLCB0aGVuIHNlbmQgb2ZmIGJhdGNoYnVmZmVycyBhbmQgZ2V0IEJNUHMgb3V0IHRoZSBvdGhlciBlbmQuCiAqLwpkcm1fcHVibGljIHZvaWQKZHJtX2ludGVsX2J1Zm1ncl9nZW1fc2V0X2F1Yl9kdW1wKGRybV9pbnRlbF9idWZtZ3IgKmJ1Zm1nciwgaW50IGVuYWJsZSkKewoJZHJtX2ludGVsX2J1Zm1ncl9nZW0gKmJ1Zm1ncl9nZW0gPSAoZHJtX2ludGVsX2J1Zm1ncl9nZW0gKilidWZtZ3I7CglpbnQgZW50cnkgPSAweDIwMDAwMzsKCWludCBpOwoJaW50IGd0dF9zaXplID0gMHgxMDAwMDsKCWNvbnN0IGNoYXIgKmZpbGVuYW1lOwoKCWlmICghZW5hYmxlKSB7CgkJaWYgKGJ1Zm1ncl9nZW0tPmF1Yl9maWxlKSB7CgkJCWZjbG9zZShidWZtZ3JfZ2VtLT5hdWJfZmlsZSk7CgkJCWJ1Zm1ncl9nZW0tPmF1Yl9maWxlID0gTlVMTDsKCQl9CgkJcmV0dXJuOwoJfQoKCWlmIChnZXRldWlkKCkgIT0gZ2V0dWlkKCkpCgkJcmV0dXJuOwoKCWlmIChidWZtZ3JfZ2VtLT5hdWJfZmlsZW5hbWUpCgkJZmlsZW5hbWUgPSBidWZtZ3JfZ2VtLT5hdWJfZmlsZW5hbWU7CgllbHNlCgkJZmlsZW5hbWUgPSAiaW50ZWwuYXViIjsKCWJ1Zm1ncl9nZW0tPmF1Yl9maWxlID0gZm9wZW4oZmlsZW5hbWUsICJ3KyIpOwoJaWYgKCFidWZtZ3JfZ2VtLT5hdWJfZmlsZSkKCQlyZXR1cm47CgoJLyogU3RhcnQgYWxsb2NhdGluZyBvYmplY3RzIGZyb20ganVzdCBhZnRlciB0aGUgR1RULiAqLwoJYnVmbWdyX2dlbS0+YXViX29mZnNldCA9IGd0dF9zaXplOwoKCS8qIFN0YXJ0IHdpdGggYSAocmVxdWlyZWQpIHZlcnNpb24gcGFja2V0LiAqLwoJYXViX291dChidWZtZ3JfZ2VtLCBDTURfQVVCX0hFQURFUiB8ICgxMyAtIDIpKTsKCWF1Yl9vdXQoYnVmbWdyX2dlbSwKCQkoNCA8PCBBVUJfSEVBREVSX01BSk9SX1NISUZUKSB8CgkJKDAgPDwgQVVCX0hFQURFUl9NSU5PUl9TSElGVCkpOwoJZm9yIChpID0gMDsgaSA8IDg7IGkrKykgewoJCWF1Yl9vdXQoYnVmbWdyX2dlbSwgMCk7IC8qIGFwcCBuYW1lICovCgl9CglhdWJfb3V0KGJ1Zm1ncl9nZW0sIDApOyAvKiB0aW1lc3RhbXAgKi8KCWF1Yl9vdXQoYnVmbWdyX2dlbSwgMCk7IC8qIHRpbWVzdGFtcCAqLwoJYXViX291dChidWZtZ3JfZ2VtLCAwKTsgLyogY29tbWVudCBsZW4gKi8KCgkvKiBTZXQgdXAgdGhlIEdUVC4gVGhlIG1heCB3ZSBjYW4gaGFuZGxlIGlzIDI1Nk0gKi8KCWF1Yl9vdXQoYnVmbWdyX2dlbSwgQ01EX0FVQl9UUkFDRV9IRUFERVJfQkxPQ0sgfCAoKGJ1Zm1ncl9nZW0tPmdlbiA+PSA4ID8gNiA6IDUpIC0gMikpOwoJLyogTmVlZCB0byB1c2UgR1RUX0VOVFJZIHR5cGUgZm9yIHJlY2VudCBlbXVsYXRvciAqLwoJYXViX291dChidWZtZ3JfZ2VtLCBBVUJfVFJBQ0VfTUVNVFlQRV9HVFRfRU5UUlkgfCAwIHwgQVVCX1RSQUNFX09QX0RBVEFfV1JJVEUpOwoJYXViX291dChidWZtZ3JfZ2VtLCAwKTsgLyogc3VidHlwZSAqLwoJYXViX291dChidWZtZ3JfZ2VtLCAwKTsgLyogb2Zmc2V0ICovCglhdWJfb3V0KGJ1Zm1ncl9nZW0sIGd0dF9zaXplKTsgLyogc2l6ZSAqLwoJaWYgKGJ1Zm1ncl9nZW0tPmdlbiA+PSA4KQoJCWF1Yl9vdXQoYnVmbWdyX2dlbSwgMCk7Cglmb3IgKGkgPSAweDAwMDsgaSA8IGd0dF9zaXplOyBpICs9IDQsIGVudHJ5ICs9IDB4MTAwMCkgewoJCWF1Yl9vdXQoYnVmbWdyX2dlbSwgZW50cnkpOwoJfQp9Cgpkcm1fcHVibGljIGRybV9pbnRlbF9jb250ZXh0ICoKZHJtX2ludGVsX2dlbV9jb250ZXh0X2NyZWF0ZShkcm1faW50ZWxfYnVmbWdyICpidWZtZ3IpCnsKCWRybV9pbnRlbF9idWZtZ3JfZ2VtICpidWZtZ3JfZ2VtID0gKGRybV9pbnRlbF9idWZtZ3JfZ2VtICopYnVmbWdyOwoJc3RydWN0IGRybV9pOTE1X2dlbV9jb250ZXh0X2NyZWF0ZSBjcmVhdGU7Cglkcm1faW50ZWxfY29udGV4dCAqY29udGV4dCA9IE5VTEw7CglpbnQgcmV0OwoKCWNvbnRleHQgPSBjYWxsb2MoMSwgc2l6ZW9mKCpjb250ZXh0KSk7CglpZiAoIWNvbnRleHQpCgkJcmV0dXJuIE5VTEw7CgoJVkdfQ0xFQVIoY3JlYXRlKTsKCXJldCA9IGRybUlvY3RsKGJ1Zm1ncl9nZW0tPmZkLCBEUk1fSU9DVExfSTkxNV9HRU1fQ09OVEVYVF9DUkVBVEUsICZjcmVhdGUpOwoJaWYgKHJldCAhPSAwKSB7CgkJREJHKCJEUk1fSU9DVExfSTkxNV9HRU1fQ09OVEVYVF9DUkVBVEUgZmFpbGVkOiAlc1xuIiwKCQkgICAgc3RyZXJyb3IoZXJybm8pKTsKCQlmcmVlKGNvbnRleHQpOwoJCXJldHVybiBOVUxMOwoJfQoKCWNvbnRleHQtPmN0eF9pZCA9IGNyZWF0ZS5jdHhfaWQ7Cgljb250ZXh0LT5idWZtZ3IgPSBidWZtZ3I7CgoJcmV0dXJuIGNvbnRleHQ7Cn0KCmRybV9wdWJsaWMgdm9pZApkcm1faW50ZWxfZ2VtX2NvbnRleHRfZGVzdHJveShkcm1faW50ZWxfY29udGV4dCAqY3R4KQp7Cglkcm1faW50ZWxfYnVmbWdyX2dlbSAqYnVmbWdyX2dlbTsKCXN0cnVjdCBkcm1faTkxNV9nZW1fY29udGV4dF9kZXN0cm95IGRlc3Ryb3k7CglpbnQgcmV0OwoKCWlmIChjdHggPT0gTlVMTCkKCQlyZXR1cm47CgoJVkdfQ0xFQVIoZGVzdHJveSk7CgoJYnVmbWdyX2dlbSA9IChkcm1faW50ZWxfYnVmbWdyX2dlbSAqKWN0eC0+YnVmbWdyOwoJZGVzdHJveS5jdHhfaWQgPSBjdHgtPmN0eF9pZDsKCXJldCA9IGRybUlvY3RsKGJ1Zm1ncl9nZW0tPmZkLCBEUk1fSU9DVExfSTkxNV9HRU1fQ09OVEVYVF9ERVNUUk9ZLAoJCSAgICAgICAmZGVzdHJveSk7CglpZiAocmV0ICE9IDApCgkJZnByaW50ZihzdGRlcnIsICJEUk1fSU9DVExfSTkxNV9HRU1fQ09OVEVYVF9ERVNUUk9ZIGZhaWxlZDogJXNcbiIsCgkJCXN0cmVycm9yKGVycm5vKSk7CgoJZnJlZShjdHgpOwp9Cgpkcm1fcHVibGljIGludApkcm1faW50ZWxfZ2V0X3Jlc2V0X3N0YXRzKGRybV9pbnRlbF9jb250ZXh0ICpjdHgsCgkJCSAgdWludDMyX3QgKnJlc2V0X2NvdW50LAoJCQkgIHVpbnQzMl90ICphY3RpdmUsCgkJCSAgdWludDMyX3QgKnBlbmRpbmcpCnsKCWRybV9pbnRlbF9idWZtZ3JfZ2VtICpidWZtZ3JfZ2VtOwoJc3RydWN0IGRybV9pOTE1X3Jlc2V0X3N0YXRzIHN0YXRzOwoJaW50IHJldDsKCglpZiAoY3R4ID09IE5VTEwpCgkJcmV0dXJuIC1FSU5WQUw7CgoJbWVtc2V0KCZzdGF0cywgMCwgc2l6ZW9mKHN0YXRzKSk7CgoJYnVmbWdyX2dlbSA9IChkcm1faW50ZWxfYnVmbWdyX2dlbSAqKWN0eC0+YnVmbWdyOwoJc3RhdHMuY3R4X2lkID0gY3R4LT5jdHhfaWQ7CglyZXQgPSBkcm1Jb2N0bChidWZtZ3JfZ2VtLT5mZCwKCQkgICAgICAgRFJNX0lPQ1RMX0k5MTVfR0VUX1JFU0VUX1NUQVRTLAoJCSAgICAgICAmc3RhdHMpOwoJaWYgKHJldCA9PSAwKSB7CgkJaWYgKHJlc2V0X2NvdW50ICE9IE5VTEwpCgkJCSpyZXNldF9jb3VudCA9IHN0YXRzLnJlc2V0X2NvdW50OwoKCQlpZiAoYWN0aXZlICE9IE5VTEwpCgkJCSphY3RpdmUgPSBzdGF0cy5iYXRjaF9hY3RpdmU7CgoJCWlmIChwZW5kaW5nICE9IE5VTEwpCgkJCSpwZW5kaW5nID0gc3RhdHMuYmF0Y2hfcGVuZGluZzsKCX0KCglyZXR1cm4gcmV0Owp9Cgpkcm1fcHVibGljIGludApkcm1faW50ZWxfcmVnX3JlYWQoZHJtX2ludGVsX2J1Zm1nciAqYnVmbWdyLAoJCSAgIHVpbnQzMl90IG9mZnNldCwKCQkgICB1aW50NjRfdCAqcmVzdWx0KQp7Cglkcm1faW50ZWxfYnVmbWdyX2dlbSAqYnVmbWdyX2dlbSA9IChkcm1faW50ZWxfYnVmbWdyX2dlbSAqKWJ1Zm1ncjsKCXN0cnVjdCBkcm1faTkxNV9yZWdfcmVhZCByZWdfcmVhZDsKCWludCByZXQ7CgoJVkdfQ0xFQVIocmVnX3JlYWQpOwoJcmVnX3JlYWQub2Zmc2V0ID0gb2Zmc2V0OwoKCXJldCA9IGRybUlvY3RsKGJ1Zm1ncl9nZW0tPmZkLCBEUk1fSU9DVExfSTkxNV9SRUdfUkVBRCwgJnJlZ19yZWFkKTsKCgkqcmVzdWx0ID0gcmVnX3JlYWQudmFsOwoJcmV0dXJuIHJldDsKfQoKCi8qKgogKiBBbm5vdGF0ZSB0aGUgZ2l2ZW4gYm8gZm9yIHVzZSBpbiBhdWIgZHVtcGluZy4KICoKICogXHBhcmFtIGFubm90YXRpb25zIGlzIGFuIGFycmF5IG9mIGRybV9pbnRlbF9hdWJfYW5ub3RhdGlvbiBvYmplY3RzCiAqIGRlc2NyaWJpbmcgdGhlIHR5cGUgb2YgZGF0YSBpbiB2YXJpb3VzIHNlY3Rpb25zIG9mIHRoZSBiby4gIEVhY2gKICogZWxlbWVudCBvZiB0aGUgYXJyYXkgc3BlY2lmaWVzIHRoZSB0eXBlIGFuZCBzdWJ0eXBlIG9mIGEgc2VjdGlvbiBvZgogKiB0aGUgYm8sIGFuZCB0aGUgcGFzdC10aGUtZW5kIG9mZnNldCBvZiB0aGF0IHNlY3Rpb24uICBUaGUgZWxlbWVudHMKICogb2YgXGMgYW5ub3RhdGlvbnMgbXVzdCBiZSBzb3J0ZWQgc28gdGhhdCBlbmRpbmdfb2Zmc2V0IGlzCiAqIGluY3JlYXNpbmcuCiAqCiAqIFxwYXJhbSBjb3VudCBpcyB0aGUgbnVtYmVyIG9mIGVsZW1lbnRzIGluIHRoZSBcYyBhbm5vdGF0aW9ucyBhcnJheS4KICogSWYgXGMgY291bnQgaXMgemVybywgdGhlbiBcYyBhbm5vdGF0aW9ucyB3aWxsIG5vdCBiZSBkZXJlZmVyZW5jZWQuCiAqCiAqIEFubm90YXRpb25zIGFyZSBjb3BpZWQgaW50byBhIHByaXZhdGUgZGF0YSBzdHJ1Y3R1cmUsIHNvIGNhbGxlciBtYXkKICogcmUtdXNlIHRoZSBtZW1vcnkgcG9pbnRlZCB0byBieSBcYyBhbm5vdGF0aW9ucyBhZnRlciB0aGUgY2FsbAogKiByZXR1cm5zLgogKgogKiBBbm5vdGF0aW9ucyBhcmUgc3RvcmVkIGZvciB0aGUgbGlmZXRpbWUgb2YgdGhlIGJvOyB0byByZXNldCB0byB0aGUKICogZGVmYXVsdCBzdGF0ZSAobm8gYW5ub3RhdGlvbnMpLCBjYWxsIHRoaXMgZnVuY3Rpb24gd2l0aCBhIFxjIGNvdW50CiAqIG9mIHplcm8uCiAqLwpkcm1fcHVibGljIHZvaWQKZHJtX2ludGVsX2J1Zm1ncl9nZW1fc2V0X2F1Yl9hbm5vdGF0aW9ucyhkcm1faW50ZWxfYm8gKmJvLAoJCQkJCSBkcm1faW50ZWxfYXViX2Fubm90YXRpb24gKmFubm90YXRpb25zLAoJCQkJCSB1bnNpZ25lZCBjb3VudCkKewoJZHJtX2ludGVsX2JvX2dlbSAqYm9fZ2VtID0gKGRybV9pbnRlbF9ib19nZW0gKikgYm87Cgl1bnNpZ25lZCBzaXplID0gc2l6ZW9mKCphbm5vdGF0aW9ucykgKiBjb3VudDsKCWRybV9pbnRlbF9hdWJfYW5ub3RhdGlvbiAqbmV3X2Fubm90YXRpb25zID0KCQljb3VudCA+IDAgPyByZWFsbG9jKGJvX2dlbS0+YXViX2Fubm90YXRpb25zLCBzaXplKSA6IE5VTEw7CglpZiAobmV3X2Fubm90YXRpb25zID09IE5VTEwpIHsKCQlmcmVlKGJvX2dlbS0+YXViX2Fubm90YXRpb25zKTsKCQlib19nZW0tPmF1Yl9hbm5vdGF0aW9ucyA9IE5VTEw7CgkJYm9fZ2VtLT5hdWJfYW5ub3RhdGlvbl9jb3VudCA9IDA7CgkJcmV0dXJuOwoJfQoJbWVtY3B5KG5ld19hbm5vdGF0aW9ucywgYW5ub3RhdGlvbnMsIHNpemUpOwoJYm9fZ2VtLT5hdWJfYW5ub3RhdGlvbnMgPSBuZXdfYW5ub3RhdGlvbnM7Cglib19nZW0tPmF1Yl9hbm5vdGF0aW9uX2NvdW50ID0gY291bnQ7Cn0KCnN0YXRpYyBwdGhyZWFkX211dGV4X3QgYnVmbWdyX2xpc3RfbXV0ZXggPSBQVEhSRUFEX01VVEVYX0lOSVRJQUxJWkVSOwpzdGF0aWMgZHJtTU1MaXN0SGVhZCBidWZtZ3JfbGlzdCA9IHsgJmJ1Zm1ncl9saXN0LCAmYnVmbWdyX2xpc3QgfTsKCnN0YXRpYyBkcm1faW50ZWxfYnVmbWdyX2dlbSAqCmRybV9pbnRlbF9idWZtZ3JfZ2VtX2ZpbmQoaW50IGZkKQp7Cglkcm1faW50ZWxfYnVmbWdyX2dlbSAqYnVmbWdyX2dlbTsKCglEUk1MSVNURk9SRUFDSEVOVFJZKGJ1Zm1ncl9nZW0sICZidWZtZ3JfbGlzdCwgbWFuYWdlcnMpIHsKCQlpZiAoYnVmbWdyX2dlbS0+ZmQgPT0gZmQpIHsKCQkJYXRvbWljX2luYygmYnVmbWdyX2dlbS0+cmVmY291bnQpOwoJCQlyZXR1cm4gYnVmbWdyX2dlbTsKCQl9Cgl9CgoJcmV0dXJuIE5VTEw7Cn0KCnN0YXRpYyB2b2lkCmRybV9pbnRlbF9idWZtZ3JfZ2VtX3VucmVmKGRybV9pbnRlbF9idWZtZ3IgKmJ1Zm1ncikKewoJZHJtX2ludGVsX2J1Zm1ncl9nZW0gKmJ1Zm1ncl9nZW0gPSAoZHJtX2ludGVsX2J1Zm1ncl9nZW0gKilidWZtZ3I7CgoJaWYgKGF0b21pY19hZGRfdW5sZXNzKCZidWZtZ3JfZ2VtLT5yZWZjb3VudCwgLTEsIDEpKSB7CgkJcHRocmVhZF9tdXRleF9sb2NrKCZidWZtZ3JfbGlzdF9tdXRleCk7CgoJCWlmIChhdG9taWNfZGVjX2FuZF90ZXN0KCZidWZtZ3JfZ2VtLT5yZWZjb3VudCkpIHsKCQkJRFJNTElTVERFTCgmYnVmbWdyX2dlbS0+bWFuYWdlcnMpOwoJCQlkcm1faW50ZWxfYnVmbWdyX2dlbV9kZXN0cm95KGJ1Zm1ncik7CgkJfQoKCQlwdGhyZWFkX211dGV4X3VubG9jaygmYnVmbWdyX2xpc3RfbXV0ZXgpOwoJfQp9CgpzdGF0aWMgYm9vbApoYXNfdXNlcnB0cihkcm1faW50ZWxfYnVmbWdyX2dlbSAqYnVmbWdyX2dlbSkKewoJaW50IHJldDsKCXZvaWQgKnB0cjsKCWxvbmcgcGdzejsKCXN0cnVjdCBkcm1faTkxNV9nZW1fdXNlcnB0ciB1c2VycHRyOwoJc3RydWN0IGRybV9nZW1fY2xvc2UgY2xvc2VfYm87CgoJcGdzeiA9IHN5c2NvbmYoX1NDX1BBR0VTSVpFKTsKCWFzc2VydChwZ3N6ID4gMCk7CgoJcmV0ID0gcG9zaXhfbWVtYWxpZ24oJnB0ciwgcGdzeiwgcGdzeik7CglpZiAocmV0KSB7CgkJREJHKCJGYWlsZWQgdG8gZ2V0IGEgcGFnZSAoJWxkKSBmb3IgdXNlcnB0ciBkZXRlY3Rpb24hXG4iLAoJCQlwZ3N6KTsKCQlyZXR1cm4gZmFsc2U7Cgl9CgoJbWVtc2V0KCZ1c2VycHRyLCAwLCBzaXplb2YodXNlcnB0cikpOwoJdXNlcnB0ci51c2VyX3B0ciA9IChfX3U2NCkodW5zaWduZWQgbG9uZylwdHI7Cgl1c2VycHRyLnVzZXJfc2l6ZSA9IHBnc3o7CgpyZXRyeToKCXJldCA9IGRybUlvY3RsKGJ1Zm1ncl9nZW0tPmZkLCBEUk1fSU9DVExfSTkxNV9HRU1fVVNFUlBUUiwgJnVzZXJwdHIpOwoJaWYgKHJldCkgewoJCWlmIChlcnJubyA9PSBFTk9ERVYgJiYgdXNlcnB0ci5mbGFncyA9PSAwKSB7CgkJCXVzZXJwdHIuZmxhZ3MgPSBJOTE1X1VTRVJQVFJfVU5TWU5DSFJPTklaRUQ7CgkJCWdvdG8gcmV0cnk7CgkJfQoJCWZyZWUocHRyKTsKCQlyZXR1cm4gZmFsc2U7Cgl9CgoJY2xvc2VfYm8uaGFuZGxlID0gdXNlcnB0ci5oYW5kbGU7CglyZXQgPSBkcm1Jb2N0bChidWZtZ3JfZ2VtLT5mZCwgRFJNX0lPQ1RMX0dFTV9DTE9TRSwgJmNsb3NlX2JvKTsKCWZyZWUocHRyKTsKCWlmIChyZXQpIHsKCQlmcHJpbnRmKHN0ZGVyciwgIkZhaWxlZCB0byByZWxlYXNlIHRlc3QgdXNlcnB0ciBvYmplY3QhICglZCkgIgoJCQkJImk5MTUga2VybmVsIGRyaXZlciBtYXkgbm90IGJlIHNhbmUhXG4iLCBlcnJubyk7CgkJcmV0dXJuIGZhbHNlOwoJfQoKCXJldHVybiB0cnVlOwp9CgovKioKICogSW5pdGlhbGl6ZXMgdGhlIEdFTSBidWZmZXIgbWFuYWdlciwgd2hpY2ggdXNlcyB0aGUga2VybmVsIHRvIGFsbG9jYXRlLCBtYXAsCiAqIGFuZCBtYW5hZ2UgbWFwIGJ1ZmZlciBvYmplY3Rpb25zLgogKgogKiBccGFyYW0gZmQgRmlsZSBkZXNjcmlwdG9yIG9mIHRoZSBvcGVuZWQgRFJNIGRldmljZS4KICovCmRybV9wdWJsaWMgZHJtX2ludGVsX2J1Zm1nciAqCmRybV9pbnRlbF9idWZtZ3JfZ2VtX2luaXQoaW50IGZkLCBpbnQgYmF0Y2hfc2l6ZSkKewoJZHJtX2ludGVsX2J1Zm1ncl9nZW0gKmJ1Zm1ncl9nZW07CglzdHJ1Y3QgZHJtX2k5MTVfZ2VtX2dldF9hcGVydHVyZSBhcGVydHVyZTsKCWRybV9pOTE1X2dldHBhcmFtX3QgZ3A7CglpbnQgcmV0LCB0bXA7Cglib29sIGV4ZWMyID0gZmFsc2U7CgoJcHRocmVhZF9tdXRleF9sb2NrKCZidWZtZ3JfbGlzdF9tdXRleCk7CgoJYnVmbWdyX2dlbSA9IGRybV9pbnRlbF9idWZtZ3JfZ2VtX2ZpbmQoZmQpOwoJaWYgKGJ1Zm1ncl9nZW0pCgkJZ290byBleGl0OwoKCWJ1Zm1ncl9nZW0gPSBjYWxsb2MoMSwgc2l6ZW9mKCpidWZtZ3JfZ2VtKSk7CglpZiAoYnVmbWdyX2dlbSA9PSBOVUxMKQoJCWdvdG8gZXhpdDsKCglidWZtZ3JfZ2VtLT5mZCA9IGZkOwoJYXRvbWljX3NldCgmYnVmbWdyX2dlbS0+cmVmY291bnQsIDEpOwoKCWlmIChwdGhyZWFkX211dGV4X2luaXQoJmJ1Zm1ncl9nZW0tPmxvY2ssIE5VTEwpICE9IDApIHsKCQlmcmVlKGJ1Zm1ncl9nZW0pOwoJCWJ1Zm1ncl9nZW0gPSBOVUxMOwoJCWdvdG8gZXhpdDsKCX0KCglyZXQgPSBkcm1Jb2N0bChidWZtZ3JfZ2VtLT5mZCwKCQkgICAgICAgRFJNX0lPQ1RMX0k5MTVfR0VNX0dFVF9BUEVSVFVSRSwKCQkgICAgICAgJmFwZXJ0dXJlKTsKCglpZiAocmV0ID09IDApCgkJYnVmbWdyX2dlbS0+Z3R0X3NpemUgPSBhcGVydHVyZS5hcGVyX2F2YWlsYWJsZV9zaXplOwoJZWxzZSB7CgkJZnByaW50ZihzdGRlcnIsICJEUk1fSU9DVExfSTkxNV9HRU1fQVBFUlRVUkUgZmFpbGVkOiAlc1xuIiwKCQkJc3RyZXJyb3IoZXJybm8pKTsKCQlidWZtZ3JfZ2VtLT5ndHRfc2l6ZSA9IDEyOCAqIDEwMjQgKiAxMDI0OwoJCWZwcmludGYoc3RkZXJyLCAiQXNzdW1pbmcgJWRrQiBhdmFpbGFibGUgYXBlcnR1cmUgc2l6ZS5cbiIKCQkJIk1heSBsZWFkIHRvIHJlZHVjZWQgcGVyZm9ybWFuY2Ugb3IgaW5jb3JyZWN0ICIKCQkJInJlbmRlcmluZy5cbiIsCgkJCShpbnQpYnVmbWdyX2dlbS0+Z3R0X3NpemUgLyAxMDI0KTsKCX0KCglidWZtZ3JfZ2VtLT5wY2lfZGV2aWNlID0gZ2V0X3BjaV9kZXZpY2VfaWQoYnVmbWdyX2dlbSk7CgoJaWYgKElTX0dFTjIoYnVmbWdyX2dlbS0+cGNpX2RldmljZSkpCgkJYnVmbWdyX2dlbS0+Z2VuID0gMjsKCWVsc2UgaWYgKElTX0dFTjMoYnVmbWdyX2dlbS0+cGNpX2RldmljZSkpCgkJYnVmbWdyX2dlbS0+Z2VuID0gMzsKCWVsc2UgaWYgKElTX0dFTjQoYnVmbWdyX2dlbS0+cGNpX2RldmljZSkpCgkJYnVmbWdyX2dlbS0+Z2VuID0gNDsKCWVsc2UgaWYgKElTX0dFTjUoYnVmbWdyX2dlbS0+cGNpX2RldmljZSkpCgkJYnVmbWdyX2dlbS0+Z2VuID0gNTsKCWVsc2UgaWYgKElTX0dFTjYoYnVmbWdyX2dlbS0+cGNpX2RldmljZSkpCgkJYnVmbWdyX2dlbS0+Z2VuID0gNjsKCWVsc2UgaWYgKElTX0dFTjcoYnVmbWdyX2dlbS0+cGNpX2RldmljZSkpCgkJYnVmbWdyX2dlbS0+Z2VuID0gNzsKCWVsc2UgaWYgKElTX0dFTjgoYnVmbWdyX2dlbS0+cGNpX2RldmljZSkpCgkJYnVmbWdyX2dlbS0+Z2VuID0gODsKCWVsc2UgaWYgKElTX0dFTjkoYnVmbWdyX2dlbS0+cGNpX2RldmljZSkpCgkJYnVmbWdyX2dlbS0+Z2VuID0gOTsKCWVsc2UgewoJCWZyZWUoYnVmbWdyX2dlbSk7CgkJYnVmbWdyX2dlbSA9IE5VTEw7CgkJZ290byBleGl0OwoJfQoKCWlmIChJU19HRU4zKGJ1Zm1ncl9nZW0tPnBjaV9kZXZpY2UpICYmCgkgICAgYnVmbWdyX2dlbS0+Z3R0X3NpemUgPiAyNTYqMTAyNCoxMDI0KSB7CgkJLyogVGhlIHVubWFwcGFibGUgcGFydCBvZiBndHQgb24gZ2VuIDMgKGkuZS4gYWJvdmUgMjU2TUIpIGNhbid0CgkJICogYmUgdXNlZCBmb3IgdGlsZWQgYmxpdHMuIFRvIHNpbXBsaWZ5IHRoZSBhY2NvdW50aW5nLCBqdXN0CgkJICogc3Vic3RyYWN0IHRoZSB1bm1hcHBhYmxlIHBhcnQgKGZpeGVkIHRvIDI1Nk1CIG9uIGFsbCBrbm93bgoJCSAqIGdlbjMgZGV2aWNlcykgaWYgdGhlIGtlcm5lbCBhZHZlcnRpc2VzIGl0LiAqLwoJCWJ1Zm1ncl9nZW0tPmd0dF9zaXplIC09IDI1NioxMDI0KjEwMjQ7Cgl9CgoJVkdfQ0xFQVIoZ3ApOwoJZ3AudmFsdWUgPSAmdG1wOwoKCWdwLnBhcmFtID0gSTkxNV9QQVJBTV9IQVNfRVhFQ0JVRjI7CglyZXQgPSBkcm1Jb2N0bChidWZtZ3JfZ2VtLT5mZCwgRFJNX0lPQ1RMX0k5MTVfR0VUUEFSQU0sICZncCk7CglpZiAoIXJldCkKCQlleGVjMiA9IHRydWU7CgoJZ3AucGFyYW0gPSBJOTE1X1BBUkFNX0hBU19CU0Q7CglyZXQgPSBkcm1Jb2N0bChidWZtZ3JfZ2VtLT5mZCwgRFJNX0lPQ1RMX0k5MTVfR0VUUEFSQU0sICZncCk7CglidWZtZ3JfZ2VtLT5oYXNfYnNkID0gcmV0ID09IDA7CgoJZ3AucGFyYW0gPSBJOTE1X1BBUkFNX0hBU19CTFQ7CglyZXQgPSBkcm1Jb2N0bChidWZtZ3JfZ2VtLT5mZCwgRFJNX0lPQ1RMX0k5MTVfR0VUUEFSQU0sICZncCk7CglidWZtZ3JfZ2VtLT5oYXNfYmx0ID0gcmV0ID09IDA7CgoJZ3AucGFyYW0gPSBJOTE1X1BBUkFNX0hBU19SRUxBWEVEX0ZFTkNJTkc7CglyZXQgPSBkcm1Jb2N0bChidWZtZ3JfZ2VtLT5mZCwgRFJNX0lPQ1RMX0k5MTVfR0VUUEFSQU0sICZncCk7CglidWZtZ3JfZ2VtLT5oYXNfcmVsYXhlZF9mZW5jaW5nID0gcmV0ID09IDA7CgoJaWYgKGhhc191c2VycHRyKGJ1Zm1ncl9nZW0pKQoJCWJ1Zm1ncl9nZW0tPmJ1Zm1nci5ib19hbGxvY191c2VycHRyID0KCQkJZHJtX2ludGVsX2dlbV9ib19hbGxvY191c2VycHRyOwoKCWdwLnBhcmFtID0gSTkxNV9QQVJBTV9IQVNfV0FJVF9USU1FT1VUOwoJcmV0ID0gZHJtSW9jdGwoYnVmbWdyX2dlbS0+ZmQsIERSTV9JT0NUTF9JOTE1X0dFVFBBUkFNLCAmZ3ApOwoJYnVmbWdyX2dlbS0+aGFzX3dhaXRfdGltZW91dCA9IHJldCA9PSAwOwoKCWdwLnBhcmFtID0gSTkxNV9QQVJBTV9IQVNfTExDOwoJcmV0ID0gZHJtSW9jdGwoYnVmbWdyX2dlbS0+ZmQsIERSTV9JT0NUTF9JOTE1X0dFVFBBUkFNLCAmZ3ApOwoJaWYgKHJldCAhPSAwKSB7CgkJLyogS2VybmVsIGRvZXMgbm90IHN1cHBvcnRzIEhBU19MTEMgcXVlcnksIGZhbGxiYWNrIHRvIEdQVQoJCSAqIGdlbmVyYXRpb24gZGV0ZWN0aW9uIGFuZCBhc3N1bWUgdGhhdCB3ZSBoYXZlIExMQyBvbiBHRU42LzcKCQkgKi8KCQlidWZtZ3JfZ2VtLT5oYXNfbGxjID0gKElTX0dFTjYoYnVmbWdyX2dlbS0+cGNpX2RldmljZSkgfAoJCQkJSVNfR0VONyhidWZtZ3JfZ2VtLT5wY2lfZGV2aWNlKSk7Cgl9IGVsc2UKCQlidWZtZ3JfZ2VtLT5oYXNfbGxjID0gKmdwLnZhbHVlOwoKCWdwLnBhcmFtID0gSTkxNV9QQVJBTV9IQVNfVkVCT1g7CglyZXQgPSBkcm1Jb2N0bChidWZtZ3JfZ2VtLT5mZCwgRFJNX0lPQ1RMX0k5MTVfR0VUUEFSQU0sICZncCk7CglidWZtZ3JfZ2VtLT5oYXNfdmVib3ggPSAocmV0ID09IDApICYgKCpncC52YWx1ZSA+IDApOwoKCWlmIChidWZtZ3JfZ2VtLT5nZW4gPCA0KSB7CgkJZ3AucGFyYW0gPSBJOTE1X1BBUkFNX05VTV9GRU5DRVNfQVZBSUw7CgkJZ3AudmFsdWUgPSAmYnVmbWdyX2dlbS0+YXZhaWxhYmxlX2ZlbmNlczsKCQlyZXQgPSBkcm1Jb2N0bChidWZtZ3JfZ2VtLT5mZCwgRFJNX0lPQ1RMX0k5MTVfR0VUUEFSQU0sICZncCk7CgkJaWYgKHJldCkgewoJCQlmcHJpbnRmKHN0ZGVyciwgImdldCBmZW5jZXMgZmFpbGVkOiAlZCBbJWRdXG4iLCByZXQsCgkJCQllcnJubyk7CgkJCWZwcmludGYoc3RkZXJyLCAicGFyYW06ICVkLCB2YWw6ICVkXG4iLCBncC5wYXJhbSwKCQkJCSpncC52YWx1ZSk7CgkJCWJ1Zm1ncl9nZW0tPmF2YWlsYWJsZV9mZW5jZXMgPSAwOwoJCX0gZWxzZSB7CgkJCS8qIFhYWCBUaGUga2VybmVsIHJlcG9ydHMgdGhlIHRvdGFsIG51bWJlciBvZiBmZW5jZXMsCgkJCSAqIGluY2x1ZGluZyBhbnkgdGhhdCBtYXkgYmUgcGlubmVkLgoJCQkgKgoJCQkgKiBXZSBwcmVzdW1lIHRoYXQgdGhlcmUgd2lsbCBiZSBhdCBsZWFzdCBvbmUgcGlubmVkCgkJCSAqIGZlbmNlIGZvciB0aGUgc2Nhbm91dCBidWZmZXIsIGJ1dCB0aGVyZSBtYXkgYmUgbW9yZQoJCQkgKiB0aGFuIG9uZSBzY2Fub3V0IGFuZCB0aGUgdXNlciBtYXkgYmUgbWFudWFsbHkKCQkJICogcGlubmluZyBidWZmZXJzLiBMZXQncyBtb3ZlIHRvIGV4ZWNidWZmZXIyIGFuZAoJCQkgKiB0aGVyZWJ5IGZvcmdldCB0aGUgaW5zYW5pdHkgb2YgdXNpbmcgZmVuY2VzLi4uCgkJCSAqLwoJCQlidWZtZ3JfZ2VtLT5hdmFpbGFibGVfZmVuY2VzIC09IDI7CgkJCWlmIChidWZtZ3JfZ2VtLT5hdmFpbGFibGVfZmVuY2VzIDwgMCkKCQkJCWJ1Zm1ncl9nZW0tPmF2YWlsYWJsZV9mZW5jZXMgPSAwOwoJCX0KCX0KCgkvKiBMZXQncyBnbyB3aXRoIG9uZSByZWxvY2F0aW9uIHBlciBldmVyeSAyIGR3b3JkcyAoYnV0IHJvdW5kIGRvd24gYSBiaXQKCSAqIHNpbmNlIGEgcG93ZXIgb2YgdHdvIHdpbGwgbWVhbiBhbiBleHRyYSBwYWdlIGFsbG9jYXRpb24gZm9yIHRoZSByZWxvYwoJICogYnVmZmVyKS4KCSAqCgkgKiBFdmVyeSA0IHdhcyB0b28gZmV3IGZvciB0aGUgYmxlbmRlciBiZW5jaG1hcmsuCgkgKi8KCWJ1Zm1ncl9nZW0tPm1heF9yZWxvY3MgPSBiYXRjaF9zaXplIC8gc2l6ZW9mKHVpbnQzMl90KSAvIDIgLSAyOwoKCWJ1Zm1ncl9nZW0tPmJ1Zm1nci5ib19hbGxvYyA9IGRybV9pbnRlbF9nZW1fYm9fYWxsb2M7CglidWZtZ3JfZ2VtLT5idWZtZ3IuYm9fYWxsb2NfZm9yX3JlbmRlciA9CgkgICAgZHJtX2ludGVsX2dlbV9ib19hbGxvY19mb3JfcmVuZGVyOwoJYnVmbWdyX2dlbS0+YnVmbWdyLmJvX2FsbG9jX3RpbGVkID0gZHJtX2ludGVsX2dlbV9ib19hbGxvY190aWxlZDsKCWJ1Zm1ncl9nZW0tPmJ1Zm1nci5ib19yZWZlcmVuY2UgPSBkcm1faW50ZWxfZ2VtX2JvX3JlZmVyZW5jZTsKCWJ1Zm1ncl9nZW0tPmJ1Zm1nci5ib191bnJlZmVyZW5jZSA9IGRybV9pbnRlbF9nZW1fYm9fdW5yZWZlcmVuY2U7CglidWZtZ3JfZ2VtLT5idWZtZ3IuYm9fbWFwID0gZHJtX2ludGVsX2dlbV9ib19tYXA7CglidWZtZ3JfZ2VtLT5idWZtZ3IuYm9fdW5tYXAgPSBkcm1faW50ZWxfZ2VtX2JvX3VubWFwOwoJYnVmbWdyX2dlbS0+YnVmbWdyLmJvX3N1YmRhdGEgPSBkcm1faW50ZWxfZ2VtX2JvX3N1YmRhdGE7CglidWZtZ3JfZ2VtLT5idWZtZ3IuYm9fZ2V0X3N1YmRhdGEgPSBkcm1faW50ZWxfZ2VtX2JvX2dldF9zdWJkYXRhOwoJYnVmbWdyX2dlbS0+YnVmbWdyLmJvX3dhaXRfcmVuZGVyaW5nID0gZHJtX2ludGVsX2dlbV9ib193YWl0X3JlbmRlcmluZzsKCWJ1Zm1ncl9nZW0tPmJ1Zm1nci5ib19lbWl0X3JlbG9jID0gZHJtX2ludGVsX2dlbV9ib19lbWl0X3JlbG9jOwoJYnVmbWdyX2dlbS0+YnVmbWdyLmJvX2VtaXRfcmVsb2NfZmVuY2UgPSBkcm1faW50ZWxfZ2VtX2JvX2VtaXRfcmVsb2NfZmVuY2U7CglidWZtZ3JfZ2VtLT5idWZtZ3IuYm9fcGluID0gZHJtX2ludGVsX2dlbV9ib19waW47CglidWZtZ3JfZ2VtLT5idWZtZ3IuYm9fdW5waW4gPSBkcm1faW50ZWxfZ2VtX2JvX3VucGluOwoJYnVmbWdyX2dlbS0+YnVmbWdyLmJvX2dldF90aWxpbmcgPSBkcm1faW50ZWxfZ2VtX2JvX2dldF90aWxpbmc7CglidWZtZ3JfZ2VtLT5idWZtZ3IuYm9fc2V0X3RpbGluZyA9IGRybV9pbnRlbF9nZW1fYm9fc2V0X3RpbGluZzsKCWJ1Zm1ncl9nZW0tPmJ1Zm1nci5ib19mbGluayA9IGRybV9pbnRlbF9nZW1fYm9fZmxpbms7CgkvKiBVc2UgdGhlIG5ldyBvbmUgaWYgYXZhaWxhYmxlICovCglpZiAoZXhlYzIpIHsKCQlidWZtZ3JfZ2VtLT5idWZtZ3IuYm9fZXhlYyA9IGRybV9pbnRlbF9nZW1fYm9fZXhlYzI7CgkJYnVmbWdyX2dlbS0+YnVmbWdyLmJvX21yYl9leGVjID0gZHJtX2ludGVsX2dlbV9ib19tcmJfZXhlYzI7Cgl9IGVsc2UKCQlidWZtZ3JfZ2VtLT5idWZtZ3IuYm9fZXhlYyA9IGRybV9pbnRlbF9nZW1fYm9fZXhlYzsKCWJ1Zm1ncl9nZW0tPmJ1Zm1nci5ib19idXN5ID0gZHJtX2ludGVsX2dlbV9ib19idXN5OwoJYnVmbWdyX2dlbS0+YnVmbWdyLmJvX21hZHZpc2UgPSBkcm1faW50ZWxfZ2VtX2JvX21hZHZpc2U7CglidWZtZ3JfZ2VtLT5idWZtZ3IuZGVzdHJveSA9IGRybV9pbnRlbF9idWZtZ3JfZ2VtX3VucmVmOwoJYnVmbWdyX2dlbS0+YnVmbWdyLmRlYnVnID0gMDsKCWJ1Zm1ncl9nZW0tPmJ1Zm1nci5jaGVja19hcGVydHVyZV9zcGFjZSA9CgkgICAgZHJtX2ludGVsX2dlbV9jaGVja19hcGVydHVyZV9zcGFjZTsKCWJ1Zm1ncl9nZW0tPmJ1Zm1nci5ib19kaXNhYmxlX3JldXNlID0gZHJtX2ludGVsX2dlbV9ib19kaXNhYmxlX3JldXNlOwoJYnVmbWdyX2dlbS0+YnVmbWdyLmJvX2lzX3JldXNhYmxlID0gZHJtX2ludGVsX2dlbV9ib19pc19yZXVzYWJsZTsKCWJ1Zm1ncl9nZW0tPmJ1Zm1nci5nZXRfcGlwZV9mcm9tX2NydGNfaWQgPQoJICAgIGRybV9pbnRlbF9nZW1fZ2V0X3BpcGVfZnJvbV9jcnRjX2lkOwoJYnVmbWdyX2dlbS0+YnVmbWdyLmJvX3JlZmVyZW5jZXMgPSBkcm1faW50ZWxfZ2VtX2JvX3JlZmVyZW5jZXM7CgoJRFJNSU5JVExJU1RIRUFEKCZidWZtZ3JfZ2VtLT5uYW1lZCk7Cglpbml0X2NhY2hlX2J1Y2tldHMoYnVmbWdyX2dlbSk7CgoJRFJNSU5JVExJU1RIRUFEKCZidWZtZ3JfZ2VtLT52bWFfY2FjaGUpOwoJYnVmbWdyX2dlbS0+dm1hX21heCA9IC0xOyAvKiB1bmxpbWl0ZWQgYnkgZGVmYXVsdCAqLwoKCURSTUxJU1RBREQoJmJ1Zm1ncl9nZW0tPm1hbmFnZXJzLCAmYnVmbWdyX2xpc3QpOwoKZXhpdDoKCXB0aHJlYWRfbXV0ZXhfdW5sb2NrKCZidWZtZ3JfbGlzdF9tdXRleCk7CgoJcmV0dXJuIGJ1Zm1ncl9nZW0gIT0gTlVMTCA/ICZidWZtZ3JfZ2VtLT5idWZtZ3IgOiBOVUxMOwp9Cg==