LyoKICogIGJpbmZtdF9taXNjLmMKICoKICogIENvcHlyaWdodCAoQykgMTk5NyBSaWNoYXJkIEf8bnRoZXIKICoKICogIGJpbmZtdF9taXNjIGRldGVjdHMgYmluYXJpZXMgdmlhIGEgbWFnaWMgb3IgZmlsZW5hbWUgZXh0ZW5zaW9uIGFuZCBpbnZva2VzCiAqICBhIHNwZWNpZmllZCB3cmFwcGVyLiBUaGlzIHNob3VsZCBvYnNvbGV0ZSBiaW5mbXRfamF2YSwgYmluZm10X2VtODYgYW5kCiAqICBiaW5mbXRfbXouCiAqCiAqICAxOTk3LTA0LTI1IGZpcnN0IHZlcnNpb24KICogIFsuLi5dCiAqICAxOTk3LTA1LTE5IGNsZWFudXAKICogIDE5OTctMDYtMjYgaHBhOiBwYXNzIHRoZSByZWFsIGZpbGVuYW1lIHJhdGhlciB0aGFuIGFyZ3ZbMF0KICogIDE5OTctMDYtMzAgbWlub3IgY2xlYW51cAogKiAgMTk5Ny0wOC0wOSByZW1vdmVkIGV4dGVuc2lvbiBzdHJpcHBpbmcsIGxvY2tpbmcgY2xlYW51cAogKiAgMjAwMS0wMi0yOCBBVjogcmV3cml0dGVuIGludG8gc29tZXRoaW5nIHRoYXQgcmVzZW1ibGVzIEMuIE9yaWdpbmFsIGRpZG4ndC4KICovCgojaW5jbHVkZSA8bGludXgvbW9kdWxlLmg+CiNpbmNsdWRlIDxsaW51eC9pbml0Lmg+CgojaW5jbHVkZSA8bGludXgvYmluZm10cy5oPgojaW5jbHVkZSA8bGludXgvc2xhYi5oPgojaW5jbHVkZSA8bGludXgvY3R5cGUuaD4KI2luY2x1ZGUgPGxpbnV4L2ZpbGUuaD4KI2luY2x1ZGUgPGxpbnV4L3BhZ2VtYXAuaD4KI2luY2x1ZGUgPGxpbnV4L25hbWVpLmg+CiNpbmNsdWRlIDxsaW51eC9tb3VudC5oPgojaW5jbHVkZSA8bGludXgvc3lzY2FsbHMuaD4KCiNpbmNsdWRlIDxhc20vdWFjY2Vzcy5oPgoKZW51bSB7CglWRVJCT1NFX1NUQVRVUyA9IDEgLyogbWFrZSBpdCB6ZXJvIHRvIHNhdmUgNDAwIGJ5dGVzIGtlcm5lbCBtZW1vcnkgKi8KfTsKCnN0YXRpYyBMSVNUX0hFQUQoZW50cmllcyk7CnN0YXRpYyBpbnQgZW5hYmxlZCA9IDE7CgplbnVtIHtFbmFibGVkLCBNYWdpY307CiNkZWZpbmUgTUlTQ19GTVRfUFJFU0VSVkVfQVJHVjAgKDE8PDMxKQojZGVmaW5lIE1JU0NfRk1UX09QRU5fQklOQVJZICgxPDwzMCkKI2RlZmluZSBNSVNDX0ZNVF9DUkVERU5USUFMUyAoMTw8MjkpCgp0eXBlZGVmIHN0cnVjdCB7CglzdHJ1Y3QgbGlzdF9oZWFkIGxpc3Q7Cgl1bnNpZ25lZCBsb25nIGZsYWdzOwkJLyogdHlwZSwgc3RhdHVzLCBldGMuICovCglpbnQgb2Zmc2V0OwkJCS8qIG9mZnNldCBvZiBtYWdpYyAqLwoJaW50IHNpemU7CQkJLyogc2l6ZSBvZiBtYWdpYy9tYXNrICovCgljaGFyICptYWdpYzsJCQkvKiBtYWdpYyBvciBmaWxlbmFtZSBleHRlbnNpb24gKi8KCWNoYXIgKm1hc2s7CQkJLyogbWFzaywgTlVMTCBmb3IgZXhhY3QgbWF0Y2ggKi8KCWNoYXIgKmludGVycHJldGVyOwkJLyogZmlsZW5hbWUgb2YgaW50ZXJwcmV0ZXIgKi8KCWNoYXIgKm5hbWU7CglzdHJ1Y3QgZGVudHJ5ICpkZW50cnk7Cn0gTm9kZTsKCnN0YXRpYyBERUZJTkVfUldMT0NLKGVudHJpZXNfbG9jayk7CnN0YXRpYyBzdHJ1Y3QgZmlsZV9zeXN0ZW1fdHlwZSBibV9mc190eXBlOwpzdGF0aWMgc3RydWN0IHZmc21vdW50ICpibV9tbnQ7CnN0YXRpYyBpbnQgZW50cnlfY291bnQ7CgovKiAKICogQ2hlY2sgaWYgd2Ugc3VwcG9ydCB0aGUgYmluZm10CiAqIGlmIHdlIGRvLCByZXR1cm4gdGhlIG5vZGUsIGVsc2UgTlVMTAogKiBsb2NraW5nIGlzIGRvbmUgaW4gbG9hZF9taXNjX2JpbmFyeQogKi8Kc3RhdGljIE5vZGUgKmNoZWNrX2ZpbGUoc3RydWN0IGxpbnV4X2JpbnBybSAqYnBybSkKewoJY2hhciAqcCA9IHN0cnJjaHIoYnBybS0+aW50ZXJwLCAnLicpOwoJc3RydWN0IGxpc3RfaGVhZCAqbDsKCglsaXN0X2Zvcl9lYWNoKGwsICZlbnRyaWVzKSB7CgkJTm9kZSAqZSA9IGxpc3RfZW50cnkobCwgTm9kZSwgbGlzdCk7CgkJY2hhciAqczsKCQlpbnQgajsKCgkJaWYgKCF0ZXN0X2JpdChFbmFibGVkLCAmZS0+ZmxhZ3MpKQoJCQljb250aW51ZTsKCgkJaWYgKCF0ZXN0X2JpdChNYWdpYywgJmUtPmZsYWdzKSkgewoJCQlpZiAocCAmJiAhc3RyY21wKGUtPm1hZ2ljLCBwICsgMSkpCgkJCQlyZXR1cm4gZTsKCQkJY29udGludWU7CgkJfQoKCQlzID0gYnBybS0+YnVmICsgZS0+b2Zmc2V0OwoJCWlmIChlLT5tYXNrKSB7CgkJCWZvciAoaiA9IDA7IGogPCBlLT5zaXplOyBqKyspCgkJCQlpZiAoKCpzKysgXiBlLT5tYWdpY1tqXSkgJiBlLT5tYXNrW2pdKQoJCQkJCWJyZWFrOwoJCX0gZWxzZSB7CgkJCWZvciAoaiA9IDA7IGogPCBlLT5zaXplOyBqKyspCgkJCQlpZiAoKCpzKysgXiBlLT5tYWdpY1tqXSkpCgkJCQkJYnJlYWs7CgkJfQoJCWlmIChqID09IGUtPnNpemUpCgkJCXJldHVybiBlOwoJfQoJcmV0dXJuIE5VTEw7Cn0KCi8qCiAqIHRoZSBsb2FkZXIgaXRzZWxmCiAqLwpzdGF0aWMgaW50IGxvYWRfbWlzY19iaW5hcnkoc3RydWN0IGxpbnV4X2JpbnBybSAqYnBybSwgc3RydWN0IHB0X3JlZ3MgKnJlZ3MpCnsKCU5vZGUgKmZtdDsKCXN0cnVjdCBmaWxlICogaW50ZXJwX2ZpbGUgPSBOVUxMOwoJY2hhciBpbmFtZVtCSU5QUk1fQlVGX1NJWkVdOwoJY2hhciAqaW5hbWVfYWRkciA9IGluYW1lOwoJaW50IHJldHZhbDsKCWludCBmZF9iaW5hcnkgPSAtMTsKCXN0cnVjdCBmaWxlc19zdHJ1Y3QgKmZpbGVzID0gTlVMTDsKCglyZXR2YWwgPSAtRU5PRVhFQzsKCWlmICghZW5hYmxlZCkKCQlnb3RvIF9yZXQ7CgoJLyogdG8ga2VlcCBsb2NraW5nIHRpbWUgbG93LCB3ZSBjb3B5IHRoZSBpbnRlcnByZXRlciBzdHJpbmcgKi8KCXJlYWRfbG9jaygmZW50cmllc19sb2NrKTsKCWZtdCA9IGNoZWNrX2ZpbGUoYnBybSk7CglpZiAoZm10KQoJCXN0cmxjcHkoaW5hbWUsIGZtdC0+aW50ZXJwcmV0ZXIsIEJJTlBSTV9CVUZfU0laRSk7CglyZWFkX3VubG9jaygmZW50cmllc19sb2NrKTsKCWlmICghZm10KQoJCWdvdG8gX3JldDsKCglpZiAoIShmbXQtPmZsYWdzICYgTUlTQ19GTVRfUFJFU0VSVkVfQVJHVjApKSB7CgkJcmVtb3ZlX2FyZ196ZXJvKGJwcm0pOwoJfQoKCWlmIChmbXQtPmZsYWdzICYgTUlTQ19GTVRfT1BFTl9CSU5BUlkpIHsKCgkJZmlsZXMgPSBjdXJyZW50LT5maWxlczsKCQlyZXR2YWwgPSB1bnNoYXJlX2ZpbGVzKCk7CgkJaWYgKHJldHZhbCA8IDApCgkJCWdvdG8gX3JldDsKCQlpZiAoZmlsZXMgPT0gY3VycmVudC0+ZmlsZXMpIHsKCQkJcHV0X2ZpbGVzX3N0cnVjdChmaWxlcyk7CgkJCWZpbGVzID0gTlVMTDsKCQl9CgkJLyogaWYgdGhlIGJpbmFyeSBzaG91bGQgYmUgb3BlbmVkIG9uIGJlaGFsZiBvZiB0aGUKCQkgKiBpbnRlcnByZXRlciB0aGFuIGtlZXAgaXQgb3BlbiBhbmQgYXNzaWduIGRlc2NyaXB0b3IKCQkgKiB0byBpdCAqLwogCQlmZF9iaW5hcnkgPSBnZXRfdW51c2VkX2ZkKCk7CiAJCWlmIChmZF9iaW5hcnkgPCAwKSB7CiAJCQlyZXR2YWwgPSBmZF9iaW5hcnk7CiAJCQlnb3RvIF91bnNoYXJlOwogCQl9CiAJCWZkX2luc3RhbGwoZmRfYmluYXJ5LCBicHJtLT5maWxlKTsKCgkJLyogaWYgdGhlIGJpbmFyeSBpcyBub3QgcmVhZGFibGUgdGhhbiBlbmZvcmNlIG1tLT5kdW1wYWJsZT0wCgkJICAgcmVnYXJkbGVzcyBvZiB0aGUgaW50ZXJwcmV0ZXIncyBwZXJtaXNzaW9ucyAqLwoJCWlmIChmaWxlX3Blcm1pc3Npb24oYnBybS0+ZmlsZSwgTUFZX1JFQUQpKQoJCQlicHJtLT5pbnRlcnBfZmxhZ3MgfD0gQklOUFJNX0ZMQUdTX0VORk9SQ0VfTk9ORFVNUDsKCgkJYWxsb3dfd3JpdGVfYWNjZXNzKGJwcm0tPmZpbGUpOwoJCWJwcm0tPmZpbGUgPSBOVUxMOwoKCQkvKiBtYXJrIHRoZSBicHJtIHRoYXQgZmQgc2hvdWxkIGJlIHBhc3NlZCB0byBpbnRlcnAgKi8KCQlicHJtLT5pbnRlcnBfZmxhZ3MgfD0gQklOUFJNX0ZMQUdTX0VYRUNGRDsKCQlicHJtLT5pbnRlcnBfZGF0YSA9IGZkX2JpbmFyeTsKCiAJfSBlbHNlIHsKIAkJYWxsb3dfd3JpdGVfYWNjZXNzKGJwcm0tPmZpbGUpOwogCQlmcHV0KGJwcm0tPmZpbGUpOwogCQlicHJtLT5maWxlID0gTlVMTDsKIAl9CgkvKiBtYWtlIGFyZ3ZbMV0gYmUgdGhlIHBhdGggdG8gdGhlIGJpbmFyeSAqLwoJcmV0dmFsID0gY29weV9zdHJpbmdzX2tlcm5lbCAoMSwgJmJwcm0tPmludGVycCwgYnBybSk7CglpZiAocmV0dmFsIDwgMCkKCQlnb3RvIF9lcnJvcjsKCWJwcm0tPmFyZ2MrKzsKCgkvKiBhZGQgdGhlIGludGVycCBhcyBhcmd2WzBdICovCglyZXR2YWwgPSBjb3B5X3N0cmluZ3Nfa2VybmVsICgxLCAmaW5hbWVfYWRkciwgYnBybSk7CglpZiAocmV0dmFsIDwgMCkKCQlnb3RvIF9lcnJvcjsKCWJwcm0tPmFyZ2MgKys7CgoJYnBybS0+aW50ZXJwID0gaW5hbWU7CS8qIGZvciBiaW5mbXRfc2NyaXB0ICovCgoJaW50ZXJwX2ZpbGUgPSBvcGVuX2V4ZWMgKGluYW1lKTsKCXJldHZhbCA9IFBUUl9FUlIgKGludGVycF9maWxlKTsKCWlmIChJU19FUlIgKGludGVycF9maWxlKSkKCQlnb3RvIF9lcnJvcjsKCglicHJtLT5maWxlID0gaW50ZXJwX2ZpbGU7CglpZiAoZm10LT5mbGFncyAmIE1JU0NfRk1UX0NSRURFTlRJQUxTKSB7CgkJLyoKCQkgKiBObyBuZWVkIHRvIGNhbGwgcHJlcGFyZV9iaW5wcm0oKSwgaXQncyBhbHJlYWR5IGJlZW4KCQkgKiBkb25lLiAgYnBybS0+YnVmIGlzIHN0YWxlLCB1cGRhdGUgZnJvbSBpbnRlcnBfZmlsZS4KCQkgKi8KCQltZW1zZXQoYnBybS0+YnVmLCAwLCBCSU5QUk1fQlVGX1NJWkUpOwoJCXJldHZhbCA9IGtlcm5lbF9yZWFkKGJwcm0tPmZpbGUsIDAsIGJwcm0tPmJ1ZiwgQklOUFJNX0JVRl9TSVpFKTsKCX0gZWxzZQoJCXJldHZhbCA9IHByZXBhcmVfYmlucHJtIChicHJtKTsKCglpZiAocmV0dmFsIDwgMCkKCQlnb3RvIF9lcnJvcjsKCglyZXR2YWwgPSBzZWFyY2hfYmluYXJ5X2hhbmRsZXIgKGJwcm0sIHJlZ3MpOwoJaWYgKHJldHZhbCA8IDApCgkJZ290byBfZXJyb3I7CgoJaWYgKGZpbGVzKSB7CgkJcHV0X2ZpbGVzX3N0cnVjdChmaWxlcyk7CgkJZmlsZXMgPSBOVUxMOwoJfQpfcmV0OgoJcmV0dXJuIHJldHZhbDsKX2Vycm9yOgoJaWYgKGZkX2JpbmFyeSA+IDApCgkJc3lzX2Nsb3NlKGZkX2JpbmFyeSk7CglicHJtLT5pbnRlcnBfZmxhZ3MgPSAwOwoJYnBybS0+aW50ZXJwX2RhdGEgPSAwOwpfdW5zaGFyZToKCWlmIChmaWxlcykKCQlyZXNldF9maWxlc19zdHJ1Y3QoY3VycmVudCwgZmlsZXMpOwoJZ290byBfcmV0Owp9CgovKiBDb21tYW5kIHBhcnNlcnMgKi8KCi8qCiAqIHBhcnNlcyBhbmQgY29waWVzIG9uZSBhcmd1bWVudCBlbmNsb3NlZCBpbiBkZWwgZnJvbSAqc3AgdG8gKmRwLAogKiByZWNvZ25pc2luZyB0aGUgXHggc3BlY2lhbC4KICogcmV0dXJucyBwb2ludGVyIHRvIHRoZSBjb3BpZWQgYXJndW1lbnQgb3IgTlVMTCBpbiBjYXNlIG9mIGFuCiAqIGVycm9yIChhbmQgc2V0cyBlcnIpIG9yIG51bGwgYXJndW1lbnQgbGVuZ3RoLgogKi8Kc3RhdGljIGNoYXIgKnNjYW5hcmcoY2hhciAqcywgY2hhciBkZWwpCnsKCWNoYXIgYzsKCgl3aGlsZSAoKGMgPSAqcysrKSAhPSBkZWwpIHsKCQlpZiAoYyA9PSAnXFwnICYmICpzID09ICd4JykgewoJCQlzKys7CgkJCWlmICghaXN4ZGlnaXQoKnMrKykpCgkJCQlyZXR1cm4gTlVMTDsKCQkJaWYgKCFpc3hkaWdpdCgqcysrKSkKCQkJCXJldHVybiBOVUxMOwoJCX0KCX0KCXJldHVybiBzOwp9CgpzdGF0aWMgaW50IHVucXVvdGUoY2hhciAqZnJvbSkKewoJY2hhciBjID0gMCwgKnMgPSBmcm9tLCAqcCA9IGZyb207CgoJd2hpbGUgKChjID0gKnMrKykgIT0gJ1wwJykgewoJCWlmIChjID09ICdcXCcgJiYgKnMgPT0gJ3gnKSB7CgkJCXMrKzsKCQkJYyA9IHRvdXBwZXIoKnMrKyk7CgkJCSpwID0gKGMgLSAoaXNkaWdpdChjKSA/ICcwJyA6ICdBJyAtIDEwKSkgPDwgNDsKCQkJYyA9IHRvdXBwZXIoKnMrKyk7CgkJCSpwKysgfD0gYyAtIChpc2RpZ2l0KGMpID8gJzAnIDogJ0EnIC0gMTApOwoJCQljb250aW51ZTsKCQl9CgkJKnArKyA9IGM7Cgl9CglyZXR1cm4gcCAtIGZyb207Cn0KCnN0YXRpYyBjaGFyICogY2hlY2tfc3BlY2lhbF9mbGFncyAoY2hhciAqIHNmcywgTm9kZSAqIGUpCnsKCWNoYXIgKiBwID0gc2ZzOwoJaW50IGNvbnQgPSAxOwoKCS8qIHNwZWNpYWwgZmxhZ3MgKi8KCXdoaWxlIChjb250KSB7CgkJc3dpdGNoICgqcCkgewoJCQljYXNlICdQJzoKCQkJCXArKzsKCQkJCWUtPmZsYWdzIHw9IE1JU0NfRk1UX1BSRVNFUlZFX0FSR1YwOwoJCQkJYnJlYWs7CgkJCWNhc2UgJ08nOgoJCQkJcCsrOwoJCQkJZS0+ZmxhZ3MgfD0gTUlTQ19GTVRfT1BFTl9CSU5BUlk7CgkJCQlicmVhazsKCQkJY2FzZSAnQyc6CgkJCQlwKys7CgkJCQkvKiB0aGlzIGZsYWdzIGFsc28gaW1wbGllcyB0aGUKCQkJCSAgIG9wZW4tYmluYXJ5IGZsYWcgKi8KCQkJCWUtPmZsYWdzIHw9IChNSVNDX0ZNVF9DUkVERU5USUFMUyB8CgkJCQkJCU1JU0NfRk1UX09QRU5fQklOQVJZKTsKCQkJCWJyZWFrOwoJCQlkZWZhdWx0OgoJCQkJY29udCA9IDA7CgkJfQoJfQoKCXJldHVybiBwOwp9Ci8qCiAqIFRoaXMgcmVnaXN0ZXJzIGEgbmV3IGJpbmFyeSBmb3JtYXQsIGl0IHJlY29nbmlzZXMgdGhlIHN5bnRheAogKiAnOm5hbWU6dHlwZTpvZmZzZXQ6bWFnaWM6bWFzazppbnRlcnByZXRlcjpmbGFncycKICogd2hlcmUgdGhlICc6JyBpcyB0aGUgSUZTLCB0aGF0IGNhbiBiZSBjaG9zZW4gd2l0aCB0aGUgZmlyc3QgY2hhcgogKi8Kc3RhdGljIE5vZGUgKmNyZWF0ZV9lbnRyeShjb25zdCBjaGFyIF9fdXNlciAqYnVmZmVyLCBzaXplX3QgY291bnQpCnsKCU5vZGUgKmU7CglpbnQgbWVtc2l6ZSwgZXJyOwoJY2hhciAqYnVmLCAqcDsKCWNoYXIgZGVsOwoKCS8qIHNvbWUgc2FuaXR5IGNoZWNrcyAqLwoJZXJyID0gLUVJTlZBTDsKCWlmICgoY291bnQgPCAxMSkgfHwgKGNvdW50ID4gMjU2KSkKCQlnb3RvIG91dDsKCgllcnIgPSAtRU5PTUVNOwoJbWVtc2l6ZSA9IHNpemVvZihOb2RlKSArIGNvdW50ICsgODsKCWUgPSBrbWFsbG9jKG1lbXNpemUsIEdGUF9VU0VSKTsKCWlmICghZSkKCQlnb3RvIG91dDsKCglwID0gYnVmID0gKGNoYXIgKillICsgc2l6ZW9mKE5vZGUpOwoKCW1lbXNldChlLCAwLCBzaXplb2YoTm9kZSkpOwoJaWYgKGNvcHlfZnJvbV91c2VyKGJ1ZiwgYnVmZmVyLCBjb3VudCkpCgkJZ290byBFZmF1bHQ7CgoJZGVsID0gKnArKzsJLyogZGVsaW1ldGVyICovCgoJbWVtc2V0KGJ1Zitjb3VudCwgZGVsLCA4KTsKCgllLT5uYW1lID0gcDsKCXAgPSBzdHJjaHIocCwgZGVsKTsKCWlmICghcCkKCQlnb3RvIEVpbnZhbDsKCSpwKysgPSAnXDAnOwoJaWYgKCFlLT5uYW1lWzBdIHx8CgkgICAgIXN0cmNtcChlLT5uYW1lLCAiLiIpIHx8CgkgICAgIXN0cmNtcChlLT5uYW1lLCAiLi4iKSB8fAoJICAgIHN0cmNocihlLT5uYW1lLCAnLycpKQoJCWdvdG8gRWludmFsOwoJc3dpdGNoICgqcCsrKSB7CgkJY2FzZSAnRSc6IGUtPmZsYWdzID0gMTw8RW5hYmxlZDsgYnJlYWs7CgkJY2FzZSAnTSc6IGUtPmZsYWdzID0gKDE8PEVuYWJsZWQpIHwgKDE8PE1hZ2ljKTsgYnJlYWs7CgkJZGVmYXVsdDogZ290byBFaW52YWw7Cgl9CglpZiAoKnArKyAhPSBkZWwpCgkJZ290byBFaW52YWw7CglpZiAodGVzdF9iaXQoTWFnaWMsICZlLT5mbGFncykpIHsKCQljaGFyICpzID0gc3RyY2hyKHAsIGRlbCk7CgkJaWYgKCFzKQoJCQlnb3RvIEVpbnZhbDsKCQkqcysrID0gJ1wwJzsKCQllLT5vZmZzZXQgPSBzaW1wbGVfc3RydG91bChwLCAmcCwgMTApOwoJCWlmICgqcCsrKQoJCQlnb3RvIEVpbnZhbDsKCQllLT5tYWdpYyA9IHA7CgkJcCA9IHNjYW5hcmcocCwgZGVsKTsKCQlpZiAoIXApCgkJCWdvdG8gRWludmFsOwoJCXBbLTFdID0gJ1wwJzsKCQlpZiAoIWUtPm1hZ2ljWzBdKQoJCQlnb3RvIEVpbnZhbDsKCQllLT5tYXNrID0gcDsKCQlwID0gc2NhbmFyZyhwLCBkZWwpOwoJCWlmICghcCkKCQkJZ290byBFaW52YWw7CgkJcFstMV0gPSAnXDAnOwoJCWlmICghZS0+bWFza1swXSkKCQkJZS0+bWFzayA9IE5VTEw7CgkJZS0+c2l6ZSA9IHVucXVvdGUoZS0+bWFnaWMpOwoJCWlmIChlLT5tYXNrICYmIHVucXVvdGUoZS0+bWFzaykgIT0gZS0+c2l6ZSkKCQkJZ290byBFaW52YWw7CgkJaWYgKGUtPnNpemUgKyBlLT5vZmZzZXQgPiBCSU5QUk1fQlVGX1NJWkUpCgkJCWdvdG8gRWludmFsOwoJfSBlbHNlIHsKCQlwID0gc3RyY2hyKHAsIGRlbCk7CgkJaWYgKCFwKQoJCQlnb3RvIEVpbnZhbDsKCQkqcCsrID0gJ1wwJzsKCQllLT5tYWdpYyA9IHA7CgkJcCA9IHN0cmNocihwLCBkZWwpOwoJCWlmICghcCkKCQkJZ290byBFaW52YWw7CgkJKnArKyA9ICdcMCc7CgkJaWYgKCFlLT5tYWdpY1swXSB8fCBzdHJjaHIoZS0+bWFnaWMsICcvJykpCgkJCWdvdG8gRWludmFsOwoJCXAgPSBzdHJjaHIocCwgZGVsKTsKCQlpZiAoIXApCgkJCWdvdG8gRWludmFsOwoJCSpwKysgPSAnXDAnOwoJfQoJZS0+aW50ZXJwcmV0ZXIgPSBwOwoJcCA9IHN0cmNocihwLCBkZWwpOwoJaWYgKCFwKQoJCWdvdG8gRWludmFsOwoJKnArKyA9ICdcMCc7CglpZiAoIWUtPmludGVycHJldGVyWzBdKQoJCWdvdG8gRWludmFsOwoKCglwID0gY2hlY2tfc3BlY2lhbF9mbGFncyAocCwgZSk7CgoJaWYgKCpwID09ICdcbicpCgkJcCsrOwoJaWYgKHAgIT0gYnVmICsgY291bnQpCgkJZ290byBFaW52YWw7CglyZXR1cm4gZTsKCm91dDoKCXJldHVybiBFUlJfUFRSKGVycik7CgpFZmF1bHQ6CglrZnJlZShlKTsKCXJldHVybiBFUlJfUFRSKC1FRkFVTFQpOwpFaW52YWw6CglrZnJlZShlKTsKCXJldHVybiBFUlJfUFRSKC1FSU5WQUwpOwp9CgovKgogKiBTZXQgc3RhdHVzIG9mIGVudHJ5L2JpbmZtdF9taXNjOgogKiAnMScgZW5hYmxlcywgJzAnIGRpc2FibGVzIGFuZCAnLTEnIGNsZWFycyBlbnRyeS9iaW5mbXRfbWlzYwogKi8Kc3RhdGljIGludCBwYXJzZV9jb21tYW5kKGNvbnN0IGNoYXIgX191c2VyICpidWZmZXIsIHNpemVfdCBjb3VudCkKewoJY2hhciBzWzRdOwoKCWlmICghY291bnQpCgkJcmV0dXJuIDA7CglpZiAoY291bnQgPiAzKQoJCXJldHVybiAtRUlOVkFMOwoJaWYgKGNvcHlfZnJvbV91c2VyKHMsIGJ1ZmZlciwgY291bnQpKQoJCXJldHVybiAtRUZBVUxUOwoJaWYgKHNbY291bnQtMV0gPT0gJ1xuJykKCQljb3VudC0tOwoJaWYgKGNvdW50ID09IDEgJiYgc1swXSA9PSAnMCcpCgkJcmV0dXJuIDE7CglpZiAoY291bnQgPT0gMSAmJiBzWzBdID09ICcxJykKCQlyZXR1cm4gMjsKCWlmIChjb3VudCA9PSAyICYmIHNbMF0gPT0gJy0nICYmIHNbMV0gPT0gJzEnKQoJCXJldHVybiAzOwoJcmV0dXJuIC1FSU5WQUw7Cn0KCi8qIGdlbmVyaWMgc3R1ZmYgKi8KCnN0YXRpYyB2b2lkIGVudHJ5X3N0YXR1cyhOb2RlICplLCBjaGFyICpwYWdlKQp7CgljaGFyICpkcDsKCWNoYXIgKnN0YXR1cyA9ICJkaXNhYmxlZCI7Cgljb25zdCBjaGFyICogZmxhZ3MgPSAiZmxhZ3M6ICI7CgoJaWYgKHRlc3RfYml0KEVuYWJsZWQsICZlLT5mbGFncykpCgkJc3RhdHVzID0gImVuYWJsZWQiOwoKCWlmICghVkVSQk9TRV9TVEFUVVMpIHsKCQlzcHJpbnRmKHBhZ2UsICIlc1xuIiwgc3RhdHVzKTsKCQlyZXR1cm47Cgl9CgoJc3ByaW50ZihwYWdlLCAiJXNcbmludGVycHJldGVyICVzXG4iLCBzdGF0dXMsIGUtPmludGVycHJldGVyKTsKCWRwID0gcGFnZSArIHN0cmxlbihwYWdlKTsKCgkvKiBwcmludCB0aGUgc3BlY2lhbCBmbGFncyAqLwoJc3ByaW50ZiAoZHAsICIlcyIsIGZsYWdzKTsKCWRwICs9IHN0cmxlbiAoZmxhZ3MpOwoJaWYgKGUtPmZsYWdzICYgTUlTQ19GTVRfUFJFU0VSVkVfQVJHVjApIHsKCQkqZHAgKysgPSAnUCc7Cgl9CglpZiAoZS0+ZmxhZ3MgJiBNSVNDX0ZNVF9PUEVOX0JJTkFSWSkgewoJCSpkcCArKyA9ICdPJzsKCX0KCWlmIChlLT5mbGFncyAmIE1JU0NfRk1UX0NSRURFTlRJQUxTKSB7CgkJKmRwICsrID0gJ0MnOwoJfQoJKmRwICsrID0gJ1xuJzsKCgoJaWYgKCF0ZXN0X2JpdChNYWdpYywgJmUtPmZsYWdzKSkgewoJCXNwcmludGYoZHAsICJleHRlbnNpb24gLiVzXG4iLCBlLT5tYWdpYyk7Cgl9IGVsc2UgewoJCWludCBpOwoKCQlzcHJpbnRmKGRwLCAib2Zmc2V0ICVpXG5tYWdpYyAiLCBlLT5vZmZzZXQpOwoJCWRwID0gcGFnZSArIHN0cmxlbihwYWdlKTsKCQlmb3IgKGkgPSAwOyBpIDwgZS0+c2l6ZTsgaSsrKSB7CgkJCXNwcmludGYoZHAsICIlMDJ4IiwgMHhmZiAmIChpbnQpIChlLT5tYWdpY1tpXSkpOwoJCQlkcCArPSAyOwoJCX0KCQlpZiAoZS0+bWFzaykgewoJCQlzcHJpbnRmKGRwLCAiXG5tYXNrICIpOwoJCQlkcCArPSA2OwoJCQlmb3IgKGkgPSAwOyBpIDwgZS0+c2l6ZTsgaSsrKSB7CgkJCQlzcHJpbnRmKGRwLCAiJTAyeCIsIDB4ZmYgJiAoaW50KSAoZS0+bWFza1tpXSkpOwoJCQkJZHAgKz0gMjsKCQkJfQoJCX0KCQkqZHArKyA9ICdcbic7CgkJKmRwID0gJ1wwJzsKCX0KfQoKc3RhdGljIHN0cnVjdCBpbm9kZSAqYm1fZ2V0X2lub2RlKHN0cnVjdCBzdXBlcl9ibG9jayAqc2IsIGludCBtb2RlKQp7CglzdHJ1Y3QgaW5vZGUgKiBpbm9kZSA9IG5ld19pbm9kZShzYik7CgoJaWYgKGlub2RlKSB7CgkJaW5vZGUtPmlfbW9kZSA9IG1vZGU7CgkJaW5vZGUtPmlfdWlkID0gMDsKCQlpbm9kZS0+aV9naWQgPSAwOwoJCWlub2RlLT5pX2Jsb2NrcyA9IDA7CgkJaW5vZGUtPmlfYXRpbWUgPSBpbm9kZS0+aV9tdGltZSA9IGlub2RlLT5pX2N0aW1lID0KCQkJY3VycmVudF9mc190aW1lKGlub2RlLT5pX3NiKTsKCX0KCXJldHVybiBpbm9kZTsKfQoKc3RhdGljIHZvaWQgYm1fY2xlYXJfaW5vZGUoc3RydWN0IGlub2RlICppbm9kZSkKewoJa2ZyZWUoaW5vZGUtPmlfcHJpdmF0ZSk7Cn0KCnN0YXRpYyB2b2lkIGtpbGxfbm9kZShOb2RlICplKQp7CglzdHJ1Y3QgZGVudHJ5ICpkZW50cnk7CgoJd3JpdGVfbG9jaygmZW50cmllc19sb2NrKTsKCWRlbnRyeSA9IGUtPmRlbnRyeTsKCWlmIChkZW50cnkpIHsKCQlsaXN0X2RlbF9pbml0KCZlLT5saXN0KTsKCQllLT5kZW50cnkgPSBOVUxMOwoJfQoJd3JpdGVfdW5sb2NrKCZlbnRyaWVzX2xvY2spOwoKCWlmIChkZW50cnkpIHsKCQlkZW50cnktPmRfaW5vZGUtPmlfbmxpbmstLTsKCQlkX2Ryb3AoZGVudHJ5KTsKCQlkcHV0KGRlbnRyeSk7CgkJc2ltcGxlX3JlbGVhc2VfZnMoJmJtX21udCwgJmVudHJ5X2NvdW50KTsKCX0KfQoKLyogLzxlbnRyeT4gKi8KCnN0YXRpYyBzc2l6ZV90CmJtX2VudHJ5X3JlYWQoc3RydWN0IGZpbGUgKiBmaWxlLCBjaGFyIF9fdXNlciAqIGJ1Ziwgc2l6ZV90IG5ieXRlcywgbG9mZl90ICpwcG9zKQp7CglOb2RlICplID0gZmlsZS0+Zl9wYXRoLmRlbnRyeS0+ZF9pbm9kZS0+aV9wcml2YXRlOwoJbG9mZl90IHBvcyA9ICpwcG9zOwoJc3NpemVfdCByZXM7CgljaGFyICpwYWdlOwoJaW50IGxlbjsKCglpZiAoIShwYWdlID0gKGNoYXIqKSBfX2dldF9mcmVlX3BhZ2UoR0ZQX0tFUk5FTCkpKQoJCXJldHVybiAtRU5PTUVNOwoKCWVudHJ5X3N0YXR1cyhlLCBwYWdlKTsKCWxlbiA9IHN0cmxlbihwYWdlKTsKCglyZXMgPSAtRUlOVkFMOwoJaWYgKHBvcyA8IDApCgkJZ290byBvdXQ7CglyZXMgPSAwOwoJaWYgKHBvcyA+PSBsZW4pCgkJZ290byBvdXQ7CglpZiAobGVuIDwgcG9zICsgbmJ5dGVzKQoJCW5ieXRlcyA9IGxlbiAtIHBvczsKCXJlcyA9IC1FRkFVTFQ7CglpZiAoY29weV90b191c2VyKGJ1ZiwgcGFnZSArIHBvcywgbmJ5dGVzKSkKCQlnb3RvIG91dDsKCSpwcG9zID0gcG9zICsgbmJ5dGVzOwoJcmVzID0gbmJ5dGVzOwpvdXQ6CglmcmVlX3BhZ2UoKHVuc2lnbmVkIGxvbmcpIHBhZ2UpOwoJcmV0dXJuIHJlczsKfQoKc3RhdGljIHNzaXplX3QgYm1fZW50cnlfd3JpdGUoc3RydWN0IGZpbGUgKmZpbGUsIGNvbnN0IGNoYXIgX191c2VyICpidWZmZXIsCgkJCQlzaXplX3QgY291bnQsIGxvZmZfdCAqcHBvcykKewoJc3RydWN0IGRlbnRyeSAqcm9vdDsKCU5vZGUgKmUgPSBmaWxlLT5mX3BhdGguZGVudHJ5LT5kX2lub2RlLT5pX3ByaXZhdGU7CglpbnQgcmVzID0gcGFyc2VfY29tbWFuZChidWZmZXIsIGNvdW50KTsKCglzd2l0Y2ggKHJlcykgewoJCWNhc2UgMTogY2xlYXJfYml0KEVuYWJsZWQsICZlLT5mbGFncyk7CgkJCWJyZWFrOwoJCWNhc2UgMjogc2V0X2JpdChFbmFibGVkLCAmZS0+ZmxhZ3MpOwoJCQlicmVhazsKCQljYXNlIDM6IHJvb3QgPSBkZ2V0KGZpbGUtPmZfcGF0aC5tbnQtPm1udF9zYi0+c19yb290KTsKCQkJbXV0ZXhfbG9jaygmcm9vdC0+ZF9pbm9kZS0+aV9tdXRleCk7CgoJCQlraWxsX25vZGUoZSk7CgoJCQltdXRleF91bmxvY2soJnJvb3QtPmRfaW5vZGUtPmlfbXV0ZXgpOwoJCQlkcHV0KHJvb3QpOwoJCQlicmVhazsKCQlkZWZhdWx0OiByZXR1cm4gcmVzOwoJfQoJcmV0dXJuIGNvdW50Owp9CgpzdGF0aWMgY29uc3Qgc3RydWN0IGZpbGVfb3BlcmF0aW9ucyBibV9lbnRyeV9vcGVyYXRpb25zID0gewoJLnJlYWQJCT0gYm1fZW50cnlfcmVhZCwKCS53cml0ZQkJPSBibV9lbnRyeV93cml0ZSwKfTsKCi8qIC9yZWdpc3RlciAqLwoKc3RhdGljIHNzaXplX3QgYm1fcmVnaXN0ZXJfd3JpdGUoc3RydWN0IGZpbGUgKmZpbGUsIGNvbnN0IGNoYXIgX191c2VyICpidWZmZXIsCgkJCSAgICAgICBzaXplX3QgY291bnQsIGxvZmZfdCAqcHBvcykKewoJTm9kZSAqZTsKCXN0cnVjdCBpbm9kZSAqaW5vZGU7CglzdHJ1Y3QgZGVudHJ5ICpyb290LCAqZGVudHJ5OwoJc3RydWN0IHN1cGVyX2Jsb2NrICpzYiA9IGZpbGUtPmZfcGF0aC5tbnQtPm1udF9zYjsKCWludCBlcnIgPSAwOwoKCWUgPSBjcmVhdGVfZW50cnkoYnVmZmVyLCBjb3VudCk7CgoJaWYgKElTX0VSUihlKSkKCQlyZXR1cm4gUFRSX0VSUihlKTsKCglyb290ID0gZGdldChzYi0+c19yb290KTsKCW11dGV4X2xvY2soJnJvb3QtPmRfaW5vZGUtPmlfbXV0ZXgpOwoJZGVudHJ5ID0gbG9va3VwX29uZV9sZW4oZS0+bmFtZSwgcm9vdCwgc3RybGVuKGUtPm5hbWUpKTsKCWVyciA9IFBUUl9FUlIoZGVudHJ5KTsKCWlmIChJU19FUlIoZGVudHJ5KSkKCQlnb3RvIG91dDsKCgllcnIgPSAtRUVYSVNUOwoJaWYgKGRlbnRyeS0+ZF9pbm9kZSkKCQlnb3RvIG91dDI7CgoJaW5vZGUgPSBibV9nZXRfaW5vZGUoc2IsIFNfSUZSRUcgfCAwNjQ0KTsKCgllcnIgPSAtRU5PTUVNOwoJaWYgKCFpbm9kZSkKCQlnb3RvIG91dDI7CgoJZXJyID0gc2ltcGxlX3Bpbl9mcygmYm1fZnNfdHlwZSwgJmJtX21udCwgJmVudHJ5X2NvdW50KTsKCWlmIChlcnIpIHsKCQlpcHV0KGlub2RlKTsKCQlpbm9kZSA9IE5VTEw7CgkJZ290byBvdXQyOwoJfQoKCWUtPmRlbnRyeSA9IGRnZXQoZGVudHJ5KTsKCWlub2RlLT5pX3ByaXZhdGUgPSBlOwoJaW5vZGUtPmlfZm9wID0gJmJtX2VudHJ5X29wZXJhdGlvbnM7CgoJZF9pbnN0YW50aWF0ZShkZW50cnksIGlub2RlKTsKCXdyaXRlX2xvY2soJmVudHJpZXNfbG9jayk7CglsaXN0X2FkZCgmZS0+bGlzdCwgJmVudHJpZXMpOwoJd3JpdGVfdW5sb2NrKCZlbnRyaWVzX2xvY2spOwoKCWVyciA9IDA7Cm91dDI6CglkcHV0KGRlbnRyeSk7Cm91dDoKCW11dGV4X3VubG9jaygmcm9vdC0+ZF9pbm9kZS0+aV9tdXRleCk7CglkcHV0KHJvb3QpOwoKCWlmIChlcnIpIHsKCQlrZnJlZShlKTsKCQlyZXR1cm4gLUVJTlZBTDsKCX0KCXJldHVybiBjb3VudDsKfQoKc3RhdGljIGNvbnN0IHN0cnVjdCBmaWxlX29wZXJhdGlvbnMgYm1fcmVnaXN0ZXJfb3BlcmF0aW9ucyA9IHsKCS53cml0ZQkJPSBibV9yZWdpc3Rlcl93cml0ZSwKfTsKCi8qIC9zdGF0dXMgKi8KCnN0YXRpYyBzc2l6ZV90CmJtX3N0YXR1c19yZWFkKHN0cnVjdCBmaWxlICpmaWxlLCBjaGFyIF9fdXNlciAqYnVmLCBzaXplX3QgbmJ5dGVzLCBsb2ZmX3QgKnBwb3MpCnsKCWNoYXIgKnMgPSBlbmFibGVkID8gImVuYWJsZWQiIDogImRpc2FibGVkIjsKCWludCBsZW4gPSBzdHJsZW4ocyk7Cglsb2ZmX3QgcG9zID0gKnBwb3M7CgoJaWYgKHBvcyA8IDApCgkJcmV0dXJuIC1FSU5WQUw7CglpZiAocG9zID49IGxlbikKCQlyZXR1cm4gMDsKCWlmIChsZW4gPCBwb3MgKyBuYnl0ZXMpCgkJbmJ5dGVzID0gbGVuIC0gcG9zOwoJaWYgKGNvcHlfdG9fdXNlcihidWYsIHMgKyBwb3MsIG5ieXRlcykpCgkJcmV0dXJuIC1FRkFVTFQ7CgkqcHBvcyA9IHBvcyArIG5ieXRlczsKCXJldHVybiBuYnl0ZXM7Cn0KCnN0YXRpYyBzc2l6ZV90IGJtX3N0YXR1c193cml0ZShzdHJ1Y3QgZmlsZSAqIGZpbGUsIGNvbnN0IGNoYXIgX191c2VyICogYnVmZmVyLAoJCXNpemVfdCBjb3VudCwgbG9mZl90ICpwcG9zKQp7CglpbnQgcmVzID0gcGFyc2VfY29tbWFuZChidWZmZXIsIGNvdW50KTsKCXN0cnVjdCBkZW50cnkgKnJvb3Q7CgoJc3dpdGNoIChyZXMpIHsKCQljYXNlIDE6IGVuYWJsZWQgPSAwOyBicmVhazsKCQljYXNlIDI6IGVuYWJsZWQgPSAxOyBicmVhazsKCQljYXNlIDM6IHJvb3QgPSBkZ2V0KGZpbGUtPmZfcGF0aC5tbnQtPm1udF9zYi0+c19yb290KTsKCQkJbXV0ZXhfbG9jaygmcm9vdC0+ZF9pbm9kZS0+aV9tdXRleCk7CgoJCQl3aGlsZSAoIWxpc3RfZW1wdHkoJmVudHJpZXMpKQoJCQkJa2lsbF9ub2RlKGxpc3RfZW50cnkoZW50cmllcy5uZXh0LCBOb2RlLCBsaXN0KSk7CgoJCQltdXRleF91bmxvY2soJnJvb3QtPmRfaW5vZGUtPmlfbXV0ZXgpOwoJCQlkcHV0KHJvb3QpOwoJCWRlZmF1bHQ6IHJldHVybiByZXM7Cgl9CglyZXR1cm4gY291bnQ7Cn0KCnN0YXRpYyBjb25zdCBzdHJ1Y3QgZmlsZV9vcGVyYXRpb25zIGJtX3N0YXR1c19vcGVyYXRpb25zID0gewoJLnJlYWQJCT0gYm1fc3RhdHVzX3JlYWQsCgkud3JpdGUJCT0gYm1fc3RhdHVzX3dyaXRlLAp9OwoKLyogU3VwZXJibG9jayBoYW5kbGluZyAqLwoKc3RhdGljIGNvbnN0IHN0cnVjdCBzdXBlcl9vcGVyYXRpb25zIHNfb3BzID0gewoJLnN0YXRmcwkJPSBzaW1wbGVfc3RhdGZzLAoJLmNsZWFyX2lub2RlCT0gYm1fY2xlYXJfaW5vZGUsCn07CgpzdGF0aWMgaW50IGJtX2ZpbGxfc3VwZXIoc3RydWN0IHN1cGVyX2Jsb2NrICogc2IsIHZvaWQgKiBkYXRhLCBpbnQgc2lsZW50KQp7CglzdGF0aWMgc3RydWN0IHRyZWVfZGVzY3IgYm1fZmlsZXNbXSA9IHsKCQlbMV0gPSB7InN0YXR1cyIsICZibV9zdGF0dXNfb3BlcmF0aW9ucywgU19JV1VTUnxTX0lSVUdPfSwKCQlbMl0gPSB7InJlZ2lzdGVyIiwgJmJtX3JlZ2lzdGVyX29wZXJhdGlvbnMsIFNfSVdVU1J9LAoJCS8qIGxhc3Qgb25lICovIHsiIn0KCX07CglpbnQgZXJyID0gc2ltcGxlX2ZpbGxfc3VwZXIoc2IsIDB4NDI0OTRlNGQsIGJtX2ZpbGVzKTsKCWlmICghZXJyKQoJCXNiLT5zX29wID0gJnNfb3BzOwoJcmV0dXJuIGVycjsKfQoKc3RhdGljIGludCBibV9nZXRfc2Ioc3RydWN0IGZpbGVfc3lzdGVtX3R5cGUgKmZzX3R5cGUsCglpbnQgZmxhZ3MsIGNvbnN0IGNoYXIgKmRldl9uYW1lLCB2b2lkICpkYXRhLCBzdHJ1Y3QgdmZzbW91bnQgKm1udCkKewoJcmV0dXJuIGdldF9zYl9zaW5nbGUoZnNfdHlwZSwgZmxhZ3MsIGRhdGEsIGJtX2ZpbGxfc3VwZXIsIG1udCk7Cn0KCnN0YXRpYyBzdHJ1Y3QgbGludXhfYmluZm10IG1pc2NfZm9ybWF0ID0gewoJLm1vZHVsZSA9IFRISVNfTU9EVUxFLAoJLmxvYWRfYmluYXJ5ID0gbG9hZF9taXNjX2JpbmFyeSwKfTsKCnN0YXRpYyBzdHJ1Y3QgZmlsZV9zeXN0ZW1fdHlwZSBibV9mc190eXBlID0gewoJLm93bmVyCQk9IFRISVNfTU9EVUxFLAoJLm5hbWUJCT0gImJpbmZtdF9taXNjIiwKCS5nZXRfc2IJCT0gYm1fZ2V0X3NiLAoJLmtpbGxfc2IJPSBraWxsX2xpdHRlcl9zdXBlciwKfTsKCnN0YXRpYyBpbnQgX19pbml0IGluaXRfbWlzY19iaW5mbXQodm9pZCkKewoJaW50IGVyciA9IHJlZ2lzdGVyX2ZpbGVzeXN0ZW0oJmJtX2ZzX3R5cGUpOwoJaWYgKCFlcnIpIHsKCQllcnIgPSByZWdpc3Rlcl9iaW5mbXQoJm1pc2NfZm9ybWF0KTsKCQlpZiAoZXJyKQoJCQl1bnJlZ2lzdGVyX2ZpbGVzeXN0ZW0oJmJtX2ZzX3R5cGUpOwoJfQoJcmV0dXJuIGVycjsKfQoKc3RhdGljIHZvaWQgX19leGl0IGV4aXRfbWlzY19iaW5mbXQodm9pZCkKewoJdW5yZWdpc3Rlcl9iaW5mbXQoJm1pc2NfZm9ybWF0KTsKCXVucmVnaXN0ZXJfZmlsZXN5c3RlbSgmYm1fZnNfdHlwZSk7Cn0KCmNvcmVfaW5pdGNhbGwoaW5pdF9taXNjX2JpbmZtdCk7Cm1vZHVsZV9leGl0KGV4aXRfbWlzY19iaW5mbXQpOwpNT0RVTEVfTElDRU5TRSgiR1BMIik7Cg==