LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCiAqIENvcHlyaWdodCAyMDA2IFR1bmdzdGVuIEdyYXBoaWNzLCBJbmMuLCBCaXNtYXJjay4sIE5ELiwgVVNBLgogKiBBbGwgUmlnaHRzIFJlc2VydmVkLgogKgogKiBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYQogKiBjb3B5IG9mIHRoaXMgc29mdHdhcmUgYW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlCiAqICJTb2Z0d2FyZSIpLCB0byBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmcKICogd2l0aG91dCBsaW1pdGF0aW9uIHRoZSByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdlLCBwdWJsaXNoLAogKiBkaXN0cmlidXRlLCBzdWIgbGljZW5zZSwgYW5kL29yIHNlbGwgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvCiAqIHBlcm1pdCBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0bwogKiB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnM6CiAqCiAqIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCAiQVMgSVMiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBSRVNTIE9SCiAqIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlURUQgVE8gVEhFIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZLAogKiBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OLUlORlJJTkdFTUVOVC4gSU4gTk8gRVZFTlQgU0hBTEwKICogVEhFIENPUFlSSUdIVCBIT0xERVJTLCBBVVRIT1JTIEFORC9PUiBJVFMgU1VQUExJRVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLAogKiBEQU1BR0VTIE9SIE9USEVSIExJQUJJTElUWSwgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1IKICogT1RIRVJXSVNFLCBBUklTSU5HIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRQogKiBVU0UgT1IgT1RIRVIgREVBTElOR1MgSU4gVEhFIFNPRlRXQVJFLgogKgogKiBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSAoaW5jbHVkaW5nIHRoZQogKiBuZXh0IHBhcmFncmFwaCkgc2hhbGwgYmUgaW5jbHVkZWQgaW4gYWxsIGNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucwogKiBvZiB0aGUgU29mdHdhcmUuCiAqCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKi8KLyoKICogU2ltcGxlIG1lbW9yeSBtYW5hZ2VyIGludGVyZmFjZSB0aGF0IGtlZXBzIHRyYWNrIG9uIGFsbG9jYXRlIHJlZ2lvbnMgb24gYQogKiBwZXIgIm93bmVyIiBiYXNpcy4gQWxsIHJlZ2lvbnMgYXNzb2NpYXRlZCB3aXRoIGFuICJvd25lciIgY2FuIGJlIHJlbGVhc2VkCiAqIHdpdGggYSBzaW1wbGUgY2FsbC4gVHlwaWNhbGx5IGlmIHRoZSAib3duZXIiIGV4aXN0cy4gVGhlIG93bmVyIGlzIGFueQogKiAidW5zaWduZWQgbG9uZyIgaWRlbnRpZmllci4gQ2FuIHR5cGljYWxseSBiZSBhIHBvaW50ZXIgdG8gYSBmaWxlIHByaXZhdGUKICogc3RydWN0IG9yIGEgY29udGV4dCBpZGVudGlmaWVyLgogKgogKiBBdXRob3JzOgogKiBUaG9tYXMgSGVsbHN0cvZtIDx0aG9tYXMtYXQtdHVuZ3N0ZW5ncmFwaGljcy1kb3QtY29tPgogKi8KCiNpbmNsdWRlICJkcm1fc21hbi5oIgoKdHlwZWRlZiBzdHJ1Y3QgZHJtX293bmVyX2l0ZW0gewoJZHJtX2hhc2hfaXRlbV90IG93bmVyX2hhc2g7CglzdHJ1Y3QgbGlzdF9oZWFkIHNtYW5fbGlzdDsKCXN0cnVjdCBsaXN0X2hlYWQgbWVtX2Jsb2NrczsKfSBkcm1fb3duZXJfaXRlbV90OwoKdm9pZCBkcm1fc21hbl90YWtlZG93bihkcm1fc21hbl90ICogc21hbikKewoJZHJtX2h0X3JlbW92ZSgmc21hbi0+dXNlcl9oYXNoX3RhYik7Cglkcm1faHRfcmVtb3ZlKCZzbWFuLT5vd25lcl9oYXNoX3RhYik7CglpZiAoc21hbi0+bW0pCgkJZHJtX2ZyZWUoc21hbi0+bW0sIHNtYW4tPm51bV9tYW5hZ2VycyAqIHNpemVvZigqc21hbi0+bW0pLAoJCQkgRFJNX01FTV9NTSk7Cn0KCkVYUE9SVF9TWU1CT0woZHJtX3NtYW5fdGFrZWRvd24pOwoKaW50CmRybV9zbWFuX2luaXQoZHJtX3NtYW5fdCAqIHNtYW4sIHVuc2lnbmVkIGludCBudW1fbWFuYWdlcnMsCgkgICAgICB1bnNpZ25lZCBpbnQgdXNlcl9vcmRlciwgdW5zaWduZWQgaW50IG93bmVyX29yZGVyKQp7CglpbnQgcmV0ID0gMDsKCglzbWFuLT5tbSA9IChkcm1fc21hbl9tbV90ICopIGRybV9jYWxsb2MobnVtX21hbmFnZXJzLCBzaXplb2YoKnNtYW4tPm1tKSwKCQkJCQkJRFJNX01FTV9NTSk7CglpZiAoIXNtYW4tPm1tKSB7CgkJcmV0ID0gLUVOT01FTTsKCQlnb3RvIG91dDsKCX0KCXNtYW4tPm51bV9tYW5hZ2VycyA9IG51bV9tYW5hZ2VyczsKCUlOSVRfTElTVF9IRUFEKCZzbWFuLT5vd25lcl9pdGVtcyk7CglyZXQgPSBkcm1faHRfY3JlYXRlKCZzbWFuLT5vd25lcl9oYXNoX3RhYiwgb3duZXJfb3JkZXIpOwoJaWYgKHJldCkKCQlnb3RvIG91dDE7CglyZXQgPSBkcm1faHRfY3JlYXRlKCZzbWFuLT51c2VyX2hhc2hfdGFiLCB1c2VyX29yZGVyKTsKCWlmICghcmV0KQoJCWdvdG8gb3V0OwoKCWRybV9odF9yZW1vdmUoJnNtYW4tPm93bmVyX2hhc2hfdGFiKTsKb3V0MToKCWRybV9mcmVlKHNtYW4tPm1tLCBudW1fbWFuYWdlcnMgKiBzaXplb2YoKnNtYW4tPm1tKSwgRFJNX01FTV9NTSk7Cm91dDoKCXJldHVybiByZXQ7Cn0KCkVYUE9SVF9TWU1CT0woZHJtX3NtYW5faW5pdCk7CgpzdGF0aWMgdm9pZCAqZHJtX3NtYW5fbW1fYWxsb2NhdGUodm9pZCAqcHJpdmF0ZSwgdW5zaWduZWQgbG9uZyBzaXplLAoJCQkJICB1bnNpZ25lZCBhbGlnbm1lbnQpCnsKCWRybV9tbV90ICptbSA9IChkcm1fbW1fdCAqKSBwcml2YXRlOwoJZHJtX21tX25vZGVfdCAqdG1wOwoKCXRtcCA9IGRybV9tbV9zZWFyY2hfZnJlZShtbSwgc2l6ZSwgYWxpZ25tZW50LCAxKTsKCWlmICghdG1wKSB7CgkJcmV0dXJuIE5VTEw7Cgl9Cgl0bXAgPSBkcm1fbW1fZ2V0X2Jsb2NrKHRtcCwgc2l6ZSwgYWxpZ25tZW50KTsKCXJldHVybiB0bXA7Cn0KCnN0YXRpYyB2b2lkIGRybV9zbWFuX21tX2ZyZWUodm9pZCAqcHJpdmF0ZSwgdm9pZCAqcmVmKQp7Cglkcm1fbW1fdCAqbW0gPSAoZHJtX21tX3QgKikgcHJpdmF0ZTsKCWRybV9tbV9ub2RlX3QgKm5vZGUgPSAoZHJtX21tX25vZGVfdCAqKSByZWY7CgoJZHJtX21tX3B1dF9ibG9jayhtbSwgbm9kZSk7Cn0KCnN0YXRpYyB2b2lkIGRybV9zbWFuX21tX2Rlc3Ryb3kodm9pZCAqcHJpdmF0ZSkKewoJZHJtX21tX3QgKm1tID0gKGRybV9tbV90ICopIHByaXZhdGU7Cglkcm1fbW1fdGFrZWRvd24obW0pOwoJZHJtX2ZyZWUobW0sIHNpemVvZigqbW0pLCBEUk1fTUVNX01NKTsKfQoKc3RhdGljIHVuc2lnbmVkIGxvbmcgZHJtX3NtYW5fbW1fb2Zmc2V0KHZvaWQgKnByaXZhdGUsIHZvaWQgKnJlZikKewoJZHJtX21tX25vZGVfdCAqbm9kZSA9IChkcm1fbW1fbm9kZV90ICopIHJlZjsKCXJldHVybiBub2RlLT5zdGFydDsKfQoKaW50CmRybV9zbWFuX3NldF9yYW5nZShkcm1fc21hbl90ICogc21hbiwgdW5zaWduZWQgaW50IG1hbmFnZXIsCgkJICAgdW5zaWduZWQgbG9uZyBzdGFydCwgdW5zaWduZWQgbG9uZyBzaXplKQp7Cglkcm1fc21hbl9tbV90ICpzbWFuX21tOwoJZHJtX21tX3QgKm1tOwoJaW50IHJldDsKCglCVUdfT04obWFuYWdlciA+PSBzbWFuLT5udW1fbWFuYWdlcnMpOwoKCXNtYW5fbW0gPSAmc21hbi0+bW1bbWFuYWdlcl07CgltbSA9IGRybV9jYWxsb2MoMSwgc2l6ZW9mKCptbSksIERSTV9NRU1fTU0pOwoJaWYgKCFtbSkgewoJCXJldHVybiAtRU5PTUVNOwoJfQoJc21hbl9tbS0+cHJpdmF0ZSA9IG1tOwoJcmV0ID0gZHJtX21tX2luaXQobW0sIHN0YXJ0LCBzaXplKTsKCglpZiAocmV0KSB7CgkJZHJtX2ZyZWUobW0sIHNpemVvZigqbW0pLCBEUk1fTUVNX01NKTsKCQlyZXR1cm4gcmV0OwoJfQoKCXNtYW5fbW0tPmFsbG9jYXRlID0gZHJtX3NtYW5fbW1fYWxsb2NhdGU7CglzbWFuX21tLT5mcmVlID0gZHJtX3NtYW5fbW1fZnJlZTsKCXNtYW5fbW0tPmRlc3Ryb3kgPSBkcm1fc21hbl9tbV9kZXN0cm95OwoJc21hbl9tbS0+b2Zmc2V0ID0gZHJtX3NtYW5fbW1fb2Zmc2V0OwoKCXJldHVybiAwOwp9CgpFWFBPUlRfU1lNQk9MKGRybV9zbWFuX3NldF9yYW5nZSk7CgppbnQKZHJtX3NtYW5fc2V0X21hbmFnZXIoZHJtX3NtYW5fdCAqIHNtYW4sIHVuc2lnbmVkIGludCBtYW5hZ2VyLAoJCSAgICAgZHJtX3NtYW5fbW1fdCAqIGFsbG9jYXRvcikKewoJQlVHX09OKG1hbmFnZXIgPj0gc21hbi0+bnVtX21hbmFnZXJzKTsKCXNtYW4tPm1tW21hbmFnZXJdID0gKmFsbG9jYXRvcjsKCglyZXR1cm4gMDsKfQpFWFBPUlRfU1lNQk9MKGRybV9zbWFuX3NldF9tYW5hZ2VyKTsKCnN0YXRpYyBkcm1fb3duZXJfaXRlbV90ICpkcm1fc21hbl9nZXRfb3duZXJfaXRlbShkcm1fc21hbl90ICogc21hbiwKCQkJCQkJIHVuc2lnbmVkIGxvbmcgb3duZXIpCnsKCWludCByZXQ7Cglkcm1faGFzaF9pdGVtX3QgKm93bmVyX2hhc2hfaXRlbTsKCWRybV9vd25lcl9pdGVtX3QgKm93bmVyX2l0ZW07CgoJcmV0ID0gZHJtX2h0X2ZpbmRfaXRlbSgmc21hbi0+b3duZXJfaGFzaF90YWIsIG93bmVyLCAmb3duZXJfaGFzaF9pdGVtKTsKCWlmICghcmV0KSB7CgkJcmV0dXJuIGRybV9oYXNoX2VudHJ5KG93bmVyX2hhc2hfaXRlbSwgZHJtX293bmVyX2l0ZW1fdCwKCQkJCSAgICAgIG93bmVyX2hhc2gpOwoJfQoKCW93bmVyX2l0ZW0gPSBkcm1fY2FsbG9jKDEsIHNpemVvZigqb3duZXJfaXRlbSksIERSTV9NRU1fTU0pOwoJaWYgKCFvd25lcl9pdGVtKQoJCWdvdG8gb3V0OwoKCUlOSVRfTElTVF9IRUFEKCZvd25lcl9pdGVtLT5tZW1fYmxvY2tzKTsKCW93bmVyX2l0ZW0tPm93bmVyX2hhc2gua2V5ID0gb3duZXI7CglpZiAoZHJtX2h0X2luc2VydF9pdGVtKCZzbWFuLT5vd25lcl9oYXNoX3RhYiwgJm93bmVyX2l0ZW0tPm93bmVyX2hhc2gpKQoJCWdvdG8gb3V0MTsKCglsaXN0X2FkZF90YWlsKCZvd25lcl9pdGVtLT5zbWFuX2xpc3QsICZzbWFuLT5vd25lcl9pdGVtcyk7CglyZXR1cm4gb3duZXJfaXRlbTsKCm91dDE6Cglkcm1fZnJlZShvd25lcl9pdGVtLCBzaXplb2YoKm93bmVyX2l0ZW0pLCBEUk1fTUVNX01NKTsKb3V0OgoJcmV0dXJuIE5VTEw7Cn0KCmRybV9tZW1ibG9ja19pdGVtX3QgKmRybV9zbWFuX2FsbG9jKGRybV9zbWFuX3QgKnNtYW4sIHVuc2lnbmVkIGludCBtYW5hZ2VyLAoJCQkJICAgIHVuc2lnbmVkIGxvbmcgc2l6ZSwgdW5zaWduZWQgYWxpZ25tZW50LAoJCQkJICAgIHVuc2lnbmVkIGxvbmcgb3duZXIpCnsKCXZvaWQgKnRtcDsKCWRybV9zbWFuX21tX3QgKnNtYW5fbW07Cglkcm1fb3duZXJfaXRlbV90ICpvd25lcl9pdGVtOwoJZHJtX21lbWJsb2NrX2l0ZW1fdCAqbWVtYmxvY2s7CgoJQlVHX09OKG1hbmFnZXIgPj0gc21hbi0+bnVtX21hbmFnZXJzKTsKCglzbWFuX21tID0gJnNtYW4tPm1tW21hbmFnZXJdOwoJdG1wID0gc21hbl9tbS0+YWxsb2NhdGUoc21hbl9tbS0+cHJpdmF0ZSwgc2l6ZSwgYWxpZ25tZW50KTsKCglpZiAoIXRtcCkgewoJCXJldHVybiBOVUxMOwoJfQoKCW1lbWJsb2NrID0gZHJtX2NhbGxvYygxLCBzaXplb2YoKm1lbWJsb2NrKSwgRFJNX01FTV9NTSk7CgoJaWYgKCFtZW1ibG9jaykKCQlnb3RvIG91dDsKCgltZW1ibG9jay0+bW1faW5mbyA9IHRtcDsKCW1lbWJsb2NrLT5tbSA9IHNtYW5fbW07CgltZW1ibG9jay0+c21hbiA9IHNtYW47CgoJaWYgKGRybV9odF9qdXN0X2luc2VydF9wbGVhc2UKCSAgICAoJnNtYW4tPnVzZXJfaGFzaF90YWIsICZtZW1ibG9jay0+dXNlcl9oYXNoLAoJICAgICAodW5zaWduZWQgbG9uZyltZW1ibG9jaywgMzIsIDAsIDApKQoJCWdvdG8gb3V0MTsKCglvd25lcl9pdGVtID0gZHJtX3NtYW5fZ2V0X293bmVyX2l0ZW0oc21hbiwgb3duZXIpOwoJaWYgKCFvd25lcl9pdGVtKQoJCWdvdG8gb3V0MjsKCglsaXN0X2FkZF90YWlsKCZtZW1ibG9jay0+b3duZXJfbGlzdCwgJm93bmVyX2l0ZW0tPm1lbV9ibG9ja3MpOwoKCXJldHVybiBtZW1ibG9jazsKCm91dDI6Cglkcm1faHRfcmVtb3ZlX2l0ZW0oJnNtYW4tPnVzZXJfaGFzaF90YWIsICZtZW1ibG9jay0+dXNlcl9oYXNoKTsKb3V0MToKCWRybV9mcmVlKG1lbWJsb2NrLCBzaXplb2YoKm1lbWJsb2NrKSwgRFJNX01FTV9NTSk7Cm91dDoKCXNtYW5fbW0tPmZyZWUoc21hbl9tbS0+cHJpdmF0ZSwgdG1wKTsKCglyZXR1cm4gTlVMTDsKfQoKRVhQT1JUX1NZTUJPTChkcm1fc21hbl9hbGxvYyk7CgpzdGF0aWMgdm9pZCBkcm1fc21hbl9mcmVlKGRybV9tZW1ibG9ja19pdGVtX3QgKml0ZW0pCnsKCWRybV9zbWFuX3QgKnNtYW4gPSBpdGVtLT5zbWFuOwoKCWxpc3RfZGVsKCZpdGVtLT5vd25lcl9saXN0KTsKCWRybV9odF9yZW1vdmVfaXRlbSgmc21hbi0+dXNlcl9oYXNoX3RhYiwgJml0ZW0tPnVzZXJfaGFzaCk7CglpdGVtLT5tbS0+ZnJlZShpdGVtLT5tbS0+cHJpdmF0ZSwgaXRlbS0+bW1faW5mbyk7Cglkcm1fZnJlZShpdGVtLCBzaXplb2YoKml0ZW0pLCBEUk1fTUVNX01NKTsKfQoKaW50IGRybV9zbWFuX2ZyZWVfa2V5KGRybV9zbWFuX3QgKnNtYW4sIHVuc2lnbmVkIGludCBrZXkpCnsKCWRybV9oYXNoX2l0ZW1fdCAqaGFzaF9pdGVtOwoJZHJtX21lbWJsb2NrX2l0ZW1fdCAqbWVtYmxvY2tfaXRlbTsKCglpZiAoZHJtX2h0X2ZpbmRfaXRlbSgmc21hbi0+dXNlcl9oYXNoX3RhYiwga2V5LCAmaGFzaF9pdGVtKSkKCQlyZXR1cm4gLUVJTlZBTDsKCgltZW1ibG9ja19pdGVtID0gZHJtX2hhc2hfZW50cnkoaGFzaF9pdGVtLCBkcm1fbWVtYmxvY2tfaXRlbV90LCB1c2VyX2hhc2gpOwoJZHJtX3NtYW5fZnJlZShtZW1ibG9ja19pdGVtKTsKCXJldHVybiAwOwp9CgpFWFBPUlRfU1lNQk9MKGRybV9zbWFuX2ZyZWVfa2V5KTsKCnN0YXRpYyB2b2lkIGRybV9zbWFuX3JlbW92ZV9vd25lcihkcm1fc21hbl90ICpzbWFuLAoJCQkJICBkcm1fb3duZXJfaXRlbV90ICpvd25lcl9pdGVtKQp7CglsaXN0X2RlbCgmb3duZXJfaXRlbS0+c21hbl9saXN0KTsKCWRybV9odF9yZW1vdmVfaXRlbSgmc21hbi0+b3duZXJfaGFzaF90YWIsICZvd25lcl9pdGVtLT5vd25lcl9oYXNoKTsKCWRybV9mcmVlKG93bmVyX2l0ZW0sIHNpemVvZigqb3duZXJfaXRlbSksIERSTV9NRU1fTU0pOwp9CgppbnQgZHJtX3NtYW5fb3duZXJfY2xlYW4oZHJtX3NtYW5fdCAqc21hbiwgdW5zaWduZWQgbG9uZyBvd25lcikKewoKCWRybV9oYXNoX2l0ZW1fdCAqaGFzaF9pdGVtOwoJZHJtX293bmVyX2l0ZW1fdCAqb3duZXJfaXRlbTsKCglpZiAoZHJtX2h0X2ZpbmRfaXRlbSgmc21hbi0+b3duZXJfaGFzaF90YWIsIG93bmVyLCAmaGFzaF9pdGVtKSkgewoJCXJldHVybiAtMTsKCX0KCglvd25lcl9pdGVtID0gZHJtX2hhc2hfZW50cnkoaGFzaF9pdGVtLCBkcm1fb3duZXJfaXRlbV90LCBvd25lcl9oYXNoKTsKCWlmIChvd25lcl9pdGVtLT5tZW1fYmxvY2tzLm5leHQgPT0gJm93bmVyX2l0ZW0tPm1lbV9ibG9ja3MpIHsKCQlkcm1fc21hbl9yZW1vdmVfb3duZXIoc21hbiwgb3duZXJfaXRlbSk7CgkJcmV0dXJuIC0xOwoJfQoKCXJldHVybiAwOwp9CgpFWFBPUlRfU1lNQk9MKGRybV9zbWFuX293bmVyX2NsZWFuKTsKCnN0YXRpYyB2b2lkIGRybV9zbWFuX2RvX293bmVyX2NsZWFudXAoZHJtX3NtYW5fdCAqc21hbiwKCQkJCSAgICAgIGRybV9vd25lcl9pdGVtX3QgKm93bmVyX2l0ZW0pCnsKCWRybV9tZW1ibG9ja19pdGVtX3QgKmVudHJ5LCAqbmV4dDsKCglsaXN0X2Zvcl9lYWNoX2VudHJ5X3NhZmUoZW50cnksIG5leHQsICZvd25lcl9pdGVtLT5tZW1fYmxvY2tzLAoJCQkJIG93bmVyX2xpc3QpIHsKCQlkcm1fc21hbl9mcmVlKGVudHJ5KTsKCX0KCWRybV9zbWFuX3JlbW92ZV9vd25lcihzbWFuLCBvd25lcl9pdGVtKTsKfQoKdm9pZCBkcm1fc21hbl9vd25lcl9jbGVhbnVwKGRybV9zbWFuX3QgKnNtYW4sIHVuc2lnbmVkIGxvbmcgb3duZXIpCnsKCglkcm1faGFzaF9pdGVtX3QgKmhhc2hfaXRlbTsKCWRybV9vd25lcl9pdGVtX3QgKm93bmVyX2l0ZW07CgoJaWYgKGRybV9odF9maW5kX2l0ZW0oJnNtYW4tPm93bmVyX2hhc2hfdGFiLCBvd25lciwgJmhhc2hfaXRlbSkpIHsKCgkJcmV0dXJuOwoJfQoKCW93bmVyX2l0ZW0gPSBkcm1faGFzaF9lbnRyeShoYXNoX2l0ZW0sIGRybV9vd25lcl9pdGVtX3QsIG93bmVyX2hhc2gpOwoJZHJtX3NtYW5fZG9fb3duZXJfY2xlYW51cChzbWFuLCBvd25lcl9pdGVtKTsKfQoKRVhQT1JUX1NZTUJPTChkcm1fc21hbl9vd25lcl9jbGVhbnVwKTsKCnZvaWQgZHJtX3NtYW5fY2xlYW51cChkcm1fc21hbl90ICpzbWFuKQp7Cglkcm1fb3duZXJfaXRlbV90ICplbnRyeSwgKm5leHQ7Cgl1bnNpZ25lZCBpbnQgaTsKCWRybV9zbWFuX21tX3QgKnNtYW5fbW07CgoJbGlzdF9mb3JfZWFjaF9lbnRyeV9zYWZlKGVudHJ5LCBuZXh0LCAmc21hbi0+b3duZXJfaXRlbXMsIHNtYW5fbGlzdCkgewoJCWRybV9zbWFuX2RvX293bmVyX2NsZWFudXAoc21hbiwgZW50cnkpOwoJfQoJaWYgKHNtYW4tPm1tKSB7CgkJZm9yIChpID0gMDsgaSA8IHNtYW4tPm51bV9tYW5hZ2VyczsgKytpKSB7CgkJCXNtYW5fbW0gPSAmc21hbi0+bW1baV07CgkJCWlmIChzbWFuX21tLT5wcml2YXRlKSB7CgkJCQlzbWFuX21tLT5kZXN0cm95KHNtYW5fbW0tPnByaXZhdGUpOwoJCQkJc21hbl9tbS0+cHJpdmF0ZSA9IE5VTEw7CgkJCX0KCQl9Cgl9Cn0KCkVYUE9SVF9TWU1CT0woZHJtX3NtYW5fY2xlYW51cCk7Cg==