LyoKICogJElkJAogKgogKiBDb3B5cmlnaHQgqSAyMDAzIEtlaXRoIFBhY2thcmQKICoKICogUGVybWlzc2lvbiB0byB1c2UsIGNvcHksIG1vZGlmeSwgZGlzdHJpYnV0ZSwgYW5kIHNlbGwgdGhpcyBzb2Z0d2FyZSBhbmQgaXRzCiAqIGRvY3VtZW50YXRpb24gZm9yIGFueSBwdXJwb3NlIGlzIGhlcmVieSBncmFudGVkIHdpdGhvdXQgZmVlLCBwcm92aWRlZCB0aGF0CiAqIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFwcGVhciBpbiBhbGwgY29waWVzIGFuZCB0aGF0IGJvdGggdGhhdAogKiBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIGFwcGVhciBpbiBzdXBwb3J0aW5nCiAqIGRvY3VtZW50YXRpb24sIGFuZCB0aGF0IHRoZSBuYW1lIG9mIEtlaXRoIFBhY2thcmQgbm90IGJlIHVzZWQgaW4KICogYWR2ZXJ0aXNpbmcgb3IgcHVibGljaXR5IHBlcnRhaW5pbmcgdG8gZGlzdHJpYnV0aW9uIG9mIHRoZSBzb2Z0d2FyZSB3aXRob3V0CiAqIHNwZWNpZmljLCB3cml0dGVuIHByaW9yIHBlcm1pc3Npb24uICBLZWl0aCBQYWNrYXJkIG1ha2VzIG5vCiAqIHJlcHJlc2VudGF0aW9ucyBhYm91dCB0aGUgc3VpdGFiaWxpdHkgb2YgdGhpcyBzb2Z0d2FyZSBmb3IgYW55IHB1cnBvc2UuICBJdAogKiBpcyBwcm92aWRlZCAiYXMgaXMiIHdpdGhvdXQgZXhwcmVzcyBvciBpbXBsaWVkIHdhcnJhbnR5LgogKgogKiBLRUlUSCBQQUNLQVJEIERJU0NMQUlNUyBBTEwgV0FSUkFOVElFUyBXSVRIIFJFR0FSRCBUTyBUSElTIFNPRlRXQVJFLAogKiBJTkNMVURJTkcgQUxMIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MsIElOIE5PCiAqIEVWRU5UIFNIQUxMIEtFSVRIIFBBQ0tBUkQgQkUgTElBQkxFIEZPUiBBTlkgU1BFQ0lBTCwgSU5ESVJFQ1QgT1IKICogQ09OU0VRVUVOVElBTCBEQU1BR0VTIE9SIEFOWSBEQU1BR0VTIFdIQVRTT0VWRVIgUkVTVUxUSU5HIEZST00gTE9TUyBPRiBVU0UsCiAqIERBVEEgT1IgUFJPRklUUywgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIE5FR0xJR0VOQ0UgT1IgT1RIRVIKICogVE9SVElPVVMgQUNUSU9OLCBBUklTSU5HIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFVTRSBPUgogKiBQRVJGT1JNQU5DRSBPRiBUSElTIFNPRlRXQVJFLgogKi8KCiNpbmNsdWRlIDxzdGRpby5oPgojaW5jbHVkZSA8c3RkbGliLmg+CiNpbmNsdWRlIDxjdHlwZS5oPgoKdHlwZWRlZiBlbnVtIHsgRmFsc2UsIFRydWUgfSBCb29sOwoKdHlwZWRlZiBzdHJ1Y3QgewogICAgY2hhciAgICAqYnVmOwogICAgaW50CSAgICBzaXplOwogICAgaW50CSAgICBsZW47Cn0gU3RyaW5nOwoKI2RlZmluZSBTVFJJTkdfSU5JVCAxMjgKCnZvaWQgKgpOZXcgKGludCBzaXplKQp7CiAgICB2b2lkICAgICptID0gbWFsbG9jIChzaXplKTsKICAgIGlmICghbSkKCWFib3J0ICgpOwogICAgcmV0dXJuIG07Cn0KCnZvaWQgKgpSZWFsbG9jYXRlICh2b2lkICpwLCBpbnQgc2l6ZSkKewogICAgdm9pZCAgICAqciA9IHJlYWxsb2MgKHAsIHNpemUpOwoKICAgIGlmICghcikKCWFib3J0ICgpOwogICAgcmV0dXJuIHI7Cn0KCnZvaWQKRGlzcG9zZSAodm9pZCAqcCkKewogICAgZnJlZSAocCk7Cn0KClN0cmluZyAqClN0cmluZ05ldyAodm9pZCkKewogICAgU3RyaW5nICAqczsKCiAgICBzID0gTmV3IChzaXplb2YgKFN0cmluZykpOwogICAgcy0+YnVmID0gTmV3IChTVFJJTkdfSU5JVCk7CiAgICBzLT5zaXplID0gU1RSSU5HX0lOSVQgLSAxOwogICAgcy0+YnVmWzBdID0gJ1wwJzsKICAgIHMtPmxlbiA9IDA7CiAgICByZXR1cm4gczsKfQoKdm9pZApTdHJpbmdBZGQgKFN0cmluZyAqcywgY2hhciBjKQp7CiAgICBpZiAocy0+bGVuID09IHMtPnNpemUpCglzLT5idWYgPSBSZWFsbG9jYXRlIChzLT5idWYsIChzLT5zaXplICo9IDIpICsgMSk7CiAgICBzLT5idWZbcy0+bGVuKytdID0gYzsKICAgIHMtPmJ1ZltzLT5sZW5dID0gJ1wwJzsKfQoKdm9pZApTdHJpbmdBZGRTdHJpbmcgKFN0cmluZyAqcywgY2hhciAqYnVmKQp7CiAgICB3aGlsZSAoKmJ1ZikKCVN0cmluZ0FkZCAocywgKmJ1ZisrKTsKfQoKU3RyaW5nICoKU3RyaW5nTWFrZSAoY2hhciAqYnVmKQp7CiAgICBTdHJpbmcgICpzID0gU3RyaW5nTmV3ICgpOwogICAgU3RyaW5nQWRkU3RyaW5nIChzLCBidWYpOwogICAgcmV0dXJuIHM7Cn0KCnZvaWQKU3RyaW5nRGVsIChTdHJpbmcgKnMpCnsKICAgIGlmIChzLT5sZW4pCglzLT5idWZbLS1zLT5sZW5dID0gJ1wwJzsKfQoKdm9pZApTdHJpbmdQdXQgKEZJTEUgKmYsIFN0cmluZyAqcykKewogICAgY2hhciAgICAqYiA9IHMtPmJ1ZjsKCiAgICB3aGlsZSAoKmIpCglwdXRjICgqYisrLCBmKTsKfQoKI2RlZmluZSBTdHJpbmdMYXN0KHMpCSgocyktPmxlbiA/IChzKS0+YnVmWyhzKS0+bGVuIC0gMV0gOiAnXDAnKQoKdm9pZApTdHJpbmdEaXNwb3NlIChTdHJpbmcgKnMpCnsKICAgIERpc3Bvc2UgKHMtPmJ1Zik7CiAgICBEaXNwb3NlIChzKTsKfQoKdHlwZWRlZiBzdHJ1Y3QgewogICAgU3RyaW5nICAqdGFnOwogICAgU3RyaW5nICAqdGV4dDsKfSBSZXBsYWNlOwoKUmVwbGFjZSAqClJlcGxhY2VOZXcgKHZvaWQpCnsKICAgIFJlcGxhY2UgKnIgPSBOZXcgKHNpemVvZiAoUmVwbGFjZSkpOwogICAgci0+dGFnID0gU3RyaW5nTmV3ICgpOwogICAgci0+dGV4dCA9IFN0cmluZ05ldyAoKTsKICAgIHJldHVybiByOwp9Cgp2b2lkClJlcGxhY2VEaXNwb3NlIChSZXBsYWNlICpyKQp7CiAgICBTdHJpbmdEaXNwb3NlIChyLT50YWcpOwogICAgU3RyaW5nRGlzcG9zZSAoci0+dGV4dCk7CiAgICBEaXNwb3NlIChyKTsKfQoKdm9pZApCYWlsIChjaGFyICpmb3JtYXQsIGNoYXIgKmFyZykKewogICAgZnByaW50ZiAoc3RkZXJyLCAiZmF0YWw6ICIpOwogICAgZnByaW50ZiAoc3RkZXJyLCBmb3JtYXQsIGFyZyk7CiAgICBmcHJpbnRmIChzdGRlcnIsICJcbiIpOwogICAgZXhpdCAoMSk7Cn0KClJlcGxhY2UgKgpSZXBsYWNlUmVhZCAoRklMRSAqZikKewogICAgaW50CSAgICBjOwogICAgUmVwbGFjZSAqcjsKCiAgICB3aGlsZSAoKGMgPSBnZXRjIChmKSkgIT0gJ0AnKQogICAgewoJaWYgKGMgPT0gRU9GKQoJICAgIHJldHVybiAwOwogICAgfQogICAgciA9IFJlcGxhY2VOZXcoKTsKICAgIHdoaWxlICgoYyA9IGdldGMgKGYpKSAhPSAnQCcpCiAgICB7CglpZiAoYyA9PSBFT0YpCgl7CgkgICAgUmVwbGFjZURpc3Bvc2UgKHIpOwoJICAgIHJldHVybiAwOwoJfQoJaWYgKGlzc3BhY2UgKGMpKQoJICAgIEJhaWwgKCJpbnZhbGlkIGNoYXJhY3RlciBhZnRlciB0YWcgJXMiLCByLT50YWctPmJ1Zik7CglTdHJpbmdBZGQgKHItPnRhZywgYyk7CiAgICB9CiAgICBpZiAoci0+dGFnLT5idWZbMF0gPT0gJ1wwJykKICAgIHsKCVJlcGxhY2VEaXNwb3NlIChyKTsKCXJldHVybiAwOwogICAgfQogICAgd2hpbGUgKGlzc3BhY2UgKChjID0gZ2V0YyAoZikpKSkKCTsKICAgIHVuZ2V0YyAoYywgZik7CiAgICB3aGlsZSAoKGMgPSBnZXRjIChmKSkgIT0gJ0AnICYmIGMgIT0gRU9GKQoJU3RyaW5nQWRkIChyLT50ZXh0LCBjKTsKICAgIGlmIChjID09ICdAJykKCXVuZ2V0YyAoYywgZik7CiAgICB3aGlsZSAoaXNzcGFjZSAoU3RyaW5nTGFzdCAoci0+dGV4dCkpKQoJU3RyaW5nRGVsIChyLT50ZXh0KTsKICAgIHJldHVybiByOwp9Cgp0eXBlZGVmIHN0cnVjdCBfcmVwbGFjZUxpc3QgewogICAgc3RydWN0IF9yZXBsYWNlTGlzdAkqbmV4dDsKICAgIFJlcGxhY2UJCSpyOwp9IFJlcGxhY2VMaXN0OwoKUmVwbGFjZUxpc3QgKgpSZXBsYWNlTGlzdE5ldyAoUmVwbGFjZSAqciwgUmVwbGFjZUxpc3QgKm5leHQpCnsKICAgIFJlcGxhY2VMaXN0CSpsID0gTmV3IChzaXplb2YgKFJlcGxhY2VMaXN0KSk7CiAgICBsLT5yID0gcjsKICAgIGwtPm5leHQgPSBuZXh0OwogICAgcmV0dXJuIGw7Cn0KCnZvaWQKUmVwbGFjZUxpc3REaXNwb3NlIChSZXBsYWNlTGlzdCAqbCkKewogICAgaWYgKGwpCiAgICB7CglSZXBsYWNlTGlzdERpc3Bvc2UgKGwtPm5leHQpOwoJUmVwbGFjZURpc3Bvc2UgKGwtPnIpOwoJRGlzcG9zZSAobCk7CiAgICB9Cn0KCnR5cGVkZWYgc3RydWN0IHsKICAgIFJlcGxhY2VMaXN0CSpoZWFkOwp9IFJlcGxhY2VTZXQ7CgpSZXBsYWNlU2V0ICoKUmVwbGFjZVNldE5ldyAodm9pZCkKewogICAgUmVwbGFjZVNldAkqcyA9IE5ldyAoc2l6ZW9mIChSZXBsYWNlU2V0KSk7CiAgICBzLT5oZWFkID0gMDsKICAgIHJldHVybiBzOwp9Cgp2b2lkClJlcGxhY2VTZXREaXNwb3NlIChSZXBsYWNlU2V0ICpzKQp7CiAgICBSZXBsYWNlTGlzdERpc3Bvc2UgKHMtPmhlYWQpOwogICAgRGlzcG9zZSAocyk7Cn0KCnZvaWQKUmVwbGFjZVNldEFkZCAoUmVwbGFjZVNldCAqcywgUmVwbGFjZSAqcikKewogICAgcy0+aGVhZCA9IFJlcGxhY2VMaXN0TmV3IChyLCBzLT5oZWFkKTsKfQoKUmVwbGFjZSAqClJlcGxhY2VTZXRGaW5kIChSZXBsYWNlU2V0ICpzLCBjaGFyICp0YWcpCnsKICAgIFJlcGxhY2VMaXN0CSpsOwoKICAgIGZvciAobCA9IHMtPmhlYWQ7IGw7IGwgPSBsLT5uZXh0KQoJaWYgKCFzdHJjbXAgKHRhZywgbC0+ci0+dGFnLT5idWYpKQoJICAgIHJldHVybiBsLT5yOwogICAgcmV0dXJuIDA7Cn0KClJlcGxhY2VTZXQgKgpSZXBsYWNlU2V0UmVhZCAoRklMRSAqZikKewogICAgUmVwbGFjZVNldAkqcyA9IFJlcGxhY2VTZXROZXcgKCk7CiAgICBSZXBsYWNlCSpyOwoKICAgIHdoaWxlICgociA9IFJlcGxhY2VSZWFkIChmKSkpCiAgICB7Cgl3aGlsZSAoUmVwbGFjZVNldEZpbmQgKHMsIHItPnRhZy0+YnVmKSkKCSAgICBTdHJpbmdBZGQgKHItPnRhZywgJysnKTsKCVJlcGxhY2VTZXRBZGQgKHMsIHIpOwogICAgfQogICAgaWYgKCFzLT5oZWFkKQogICAgewoJUmVwbGFjZVNldERpc3Bvc2UgKHMpOwoJcyA9IDA7CiAgICB9CiAgICByZXR1cm4gczsKfQoKdHlwZWRlZiBzdHJ1Y3QgX3NraXBTdGFjayB7CiAgICBzdHJ1Y3QgX3NraXBTdGFjawkqcHJldjsKICAgIGludAkJCXNraXBwaW5nOwp9IFNraXBTdGFjazsKClNraXBTdGFjayAqClNraXBTdGFja1B1c2ggKFNraXBTdGFjayAqcHJldiwgaW50IHNraXBwaW5nKQp7CiAgICBTa2lwU3RhY2sJKnNzID0gTmV3IChzaXplb2YgKFNraXBTdGFjaykpOwogICAgc3MtPnByZXYgPSBwcmV2OwogICAgc3MtPnNraXBwaW5nID0gc2tpcHBpbmc7CiAgICByZXR1cm4gc3M7Cn0KClNraXBTdGFjayAqClNraXBTdGFja1BvcCAoU2tpcFN0YWNrICpwcmV2KQp7CiAgICBTa2lwU3RhY2sJKnNzID0gcHJldi0+cHJldjsKICAgIERpc3Bvc2UgKHByZXYpOwogICAgcmV0dXJuIHNzOwp9Cgp0eXBlZGVmIHN0cnVjdCBfbG9vcFN0YWNrIHsKICAgIHN0cnVjdCBfbG9vcFN0YWNrCSpwcmV2OwogICAgU3RyaW5nCQkqdGFnOwogICAgU3RyaW5nCQkqZXh0cmE7CiAgICBsb25nCQlwb3M7Cn0gTG9vcFN0YWNrOwoKTG9vcFN0YWNrICoKTG9vcFN0YWNrUHVzaCAoTG9vcFN0YWNrICpwcmV2LCBGSUxFICpmLCBjaGFyICp0YWcpCnsKICAgIExvb3BTdGFjawkqbHMgPSBOZXcgKHNpemVvZiAoTG9vcFN0YWNrKSk7CiAgICBscy0+cHJldiA9IHByZXY7CiAgICBscy0+dGFnID0gU3RyaW5nTWFrZSAodGFnKTsKICAgIGxzLT5leHRyYSA9IFN0cmluZ05ldyAoKTsKICAgIGxzLT5wb3MgPSBmdGVsbCAoZik7CiAgICByZXR1cm4gbHM7Cn0KCkxvb3BTdGFjayAqCkxvb3BTdGFja0xvb3AgKFJlcGxhY2VTZXQgKnJzLCBMb29wU3RhY2sgKmxzLCBGSUxFICpmKQp7CiAgICBTdHJpbmcJKnMgPSBTdHJpbmdNYWtlIChscy0+dGFnLT5idWYpOwogICAgTG9vcFN0YWNrCSpyZXQgPSBsczsKICAgIEJvb2wJbG9vcDsKCiAgICBTdHJpbmdBZGQgKGxzLT5leHRyYSwgJysnKTsKICAgIFN0cmluZ0FkZFN0cmluZyAocywgbHMtPmV4dHJhLT5idWYpOwogICAgbG9vcCA9IFJlcGxhY2VTZXRGaW5kIChycywgcy0+YnVmKSAhPSAwOwogICAgU3RyaW5nRGlzcG9zZSAocyk7CiAgICBpZiAobG9vcCkKCWZzZWVrIChmLCBscy0+cG9zLCBTRUVLX1NFVCk7CiAgICBlbHNlCiAgICB7CglyZXQgPSBscy0+cHJldjsKCVN0cmluZ0Rpc3Bvc2UgKGxzLT50YWcpOwoJU3RyaW5nRGlzcG9zZSAobHMtPmV4dHJhKTsKCURpc3Bvc2UgKGxzKTsKICAgIH0KICAgIHJldHVybiByZXQ7Cn0KCnZvaWQKTGluZVNraXAgKEZJTEUgKmYpCnsKICAgIGludAljOwoKICAgIHdoaWxlICgoYyA9IGdldGMgKGYpKSA9PSAnXG4nKQoJOwogICAgdW5nZXRjIChjLCBmKTsKfQoKdm9pZApEb1JlcGxhY2UgKEZJTEUgKmYsIFJlcGxhY2VTZXQgKnMpCnsKICAgIGludAkJYzsKICAgIFN0cmluZwkqdGFnOwogICAgUmVwbGFjZQkqcjsKICAgIFNraXBTdGFjawkqc3MgPSAwOwogICAgTG9vcFN0YWNrCSpscyA9IDA7CiAgICBpbnQJCXNraXBwaW5nID0gMDsKCiAgICB3aGlsZSAoKGMgPSBnZXRjIChmKSkgIT0gRU9GKQogICAgewoJaWYgKGMgPT0gJ0AnKQoJewoJICAgIHRhZyA9IFN0cmluZ05ldyAoKTsKCSAgICB3aGlsZSAoKGMgPSBnZXRjIChmKSkgIT0gJ0AnKQoJICAgIHsKCQlpZiAoYyA9PSBFT0YpCgkJICAgIGFib3J0ICgpOwoJCVN0cmluZ0FkZCAodGFnLCBjKTsKCSAgICB9CgkgICAgaWYgKGxzKQoJCVN0cmluZ0FkZFN0cmluZyAodGFnLCBscy0+ZXh0cmEtPmJ1Zik7CgkgICAgc3dpdGNoICh0YWctPmJ1ZlswXSkgewoJICAgIGNhc2UgJz8nOgoJCXNzID0gU2tpcFN0YWNrUHVzaCAoc3MsIHNraXBwaW5nKTsKCQlpZiAoIVJlcGxhY2VTZXRGaW5kIChzLCB0YWctPmJ1ZiArIDEpKQoJCSAgICBza2lwcGluZysrOwoJCUxpbmVTa2lwIChmKTsKCQlicmVhazsKCSAgICBjYXNlICc6JzoKCQlpZiAoIXNzKQoJCSAgICBhYm9ydCAoKTsKCQlpZiAoc3MtPnNraXBwaW5nID09IHNraXBwaW5nKQoJCSAgICArK3NraXBwaW5nOwoJCWVsc2UKCQkgICAgLS1za2lwcGluZzsKCQlMaW5lU2tpcCAoZik7CgkJYnJlYWs7CgkgICAgY2FzZSAnOyc6CgkJc2tpcHBpbmcgPSBzcy0+c2tpcHBpbmc7CgkJc3MgPSBTa2lwU3RhY2tQb3AgKHNzKTsKCQlMaW5lU2tpcCAoZik7CgkJYnJlYWs7CgkgICAgY2FzZSAneyc6CgkJbHMgPSBMb29wU3RhY2tQdXNoIChscywgZiwgdGFnLT5idWYgKyAxKTsKCQlMaW5lU2tpcCAoZik7CgkJYnJlYWs7CgkgICAgY2FzZSAnfSc6CgkJbHMgPSBMb29wU3RhY2tMb29wIChzLCBscywgZik7CgkJTGluZVNraXAgKGYpOwoJCWJyZWFrOwoJICAgIGRlZmF1bHQ6CgkJciA9IFJlcGxhY2VTZXRGaW5kIChzLCB0YWctPmJ1Zik7CgkJaWYgKHIgJiYgIXNraXBwaW5nKQoJCSAgICBTdHJpbmdQdXQgKHN0ZG91dCwgci0+dGV4dCk7CgkJYnJlYWs7CgkgICAgfQoJICAgIFN0cmluZ0Rpc3Bvc2UgKHRhZyk7Cgl9CgllbHNlIGlmICghc2tpcHBpbmcpCgkgICAgcHV0Y2hhciAoYyk7CiAgICB9Cn0KCmludAptYWluIChpbnQgYXJnYywgY2hhciAqKmFyZ3YpCnsKICAgIEZJTEUJKmY7CiAgICBSZXBsYWNlU2V0CSpzOwoKICAgIGlmICghYXJndlsxXSkKCUJhaWwgKCJ1c2FnZTogJXMgPHRlbXBsYXRlLnNnbWw+IiwgYXJndlswXSk7CiAgICBmID0gZm9wZW4gKGFyZ3ZbMV0sICJyIik7CiAgICBpZiAoIWYpCiAgICB7CglCYWlsICgiY2FuJ3Qgb3BlbiBmaWxlICVzIiwgYXJndlsxXSk7CglleGl0ICgxKTsKICAgIH0KICAgIHdoaWxlICgocyA9IFJlcGxhY2VTZXRSZWFkIChzdGRpbikpKQogICAgewoJRG9SZXBsYWNlIChmLCBzKTsKCVJlcGxhY2VTZXREaXNwb3NlIChzKTsKCXJld2luZCAoZik7CiAgICB9CiAgICBpZiAoZmVycm9yIChzdGRvdXQpKQoJQmFpbCAoIiVzIiwgImVycm9yIHdyaXRpbmcgb3V0cHV0Iik7CiAgICBleGl0ICgwKTsKfQo=