LyoKICogJElkJAogKgogKiBDb3B5cmlnaHQgqSAyMDAzIEtlaXRoIFBhY2thcmQKICoKICogUGVybWlzc2lvbiB0byB1c2UsIGNvcHksIG1vZGlmeSwgZGlzdHJpYnV0ZSwgYW5kIHNlbGwgdGhpcyBzb2Z0d2FyZSBhbmQgaXRzCiAqIGRvY3VtZW50YXRpb24gZm9yIGFueSBwdXJwb3NlIGlzIGhlcmVieSBncmFudGVkIHdpdGhvdXQgZmVlLCBwcm92aWRlZCB0aGF0CiAqIHRoZSBhYm92ZSBjb3B5cmlnaHQgbm90aWNlIGFwcGVhciBpbiBhbGwgY29waWVzIGFuZCB0aGF0IGJvdGggdGhhdAogKiBjb3B5cmlnaHQgbm90aWNlIGFuZCB0aGlzIHBlcm1pc3Npb24gbm90aWNlIGFwcGVhciBpbiBzdXBwb3J0aW5nCiAqIGRvY3VtZW50YXRpb24sIGFuZCB0aGF0IHRoZSBuYW1lIG9mIEtlaXRoIFBhY2thcmQgbm90IGJlIHVzZWQgaW4KICogYWR2ZXJ0aXNpbmcgb3IgcHVibGljaXR5IHBlcnRhaW5pbmcgdG8gZGlzdHJpYnV0aW9uIG9mIHRoZSBzb2Z0d2FyZSB3aXRob3V0CiAqIHNwZWNpZmljLCB3cml0dGVuIHByaW9yIHBlcm1pc3Npb24uICBLZWl0aCBQYWNrYXJkIG1ha2VzIG5vCiAqIHJlcHJlc2VudGF0aW9ucyBhYm91dCB0aGUgc3VpdGFiaWxpdHkgb2YgdGhpcyBzb2Z0d2FyZSBmb3IgYW55IHB1cnBvc2UuICBJdAogKiBpcyBwcm92aWRlZCAiYXMgaXMiIHdpdGhvdXQgZXhwcmVzcyBvciBpbXBsaWVkIHdhcnJhbnR5LgogKgogKiBLRUlUSCBQQUNLQVJEIERJU0NMQUlNUyBBTEwgV0FSUkFOVElFUyBXSVRIIFJFR0FSRCBUTyBUSElTIFNPRlRXQVJFLAogKiBJTkNMVURJTkcgQUxMIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MsIElOIE5PCiAqIEVWRU5UIFNIQUxMIEtFSVRIIFBBQ0tBUkQgQkUgTElBQkxFIEZPUiBBTlkgU1BFQ0lBTCwgSU5ESVJFQ1QgT1IKICogQ09OU0VRVUVOVElBTCBEQU1BR0VTIE9SIEFOWSBEQU1BR0VTIFdIQVRTT0VWRVIgUkVTVUxUSU5HIEZST00gTE9TUyBPRiBVU0UsCiAqIERBVEEgT1IgUFJPRklUUywgV0hFVEhFUiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIE5FR0xJR0VOQ0UgT1IgT1RIRVIKICogVE9SVElPVVMgQUNUSU9OLCBBUklTSU5HIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFVTRSBPUgogKiBQRVJGT1JNQU5DRSBPRiBUSElTIFNPRlRXQVJFLgogKi8KCiNpbmNsdWRlIDxzdGRpby5oPgojaW5jbHVkZSA8c3RkbGliLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUgPGN0eXBlLmg+Cgp0eXBlZGVmIGVudW0geyBGYWxzZSwgVHJ1ZSB9IEJvb2w7Cgp0eXBlZGVmIHN0cnVjdCB7CiAgICBjaGFyICAgICpidWY7CiAgICBpbnQJICAgIHNpemU7CiAgICBpbnQJICAgIGxlbjsKfSBTdHJpbmc7CgojZGVmaW5lIFNUUklOR19JTklUIDEyOAoKdm9pZCAqCk5ldyAoaW50IHNpemUpCnsKICAgIHZvaWQgICAgKm0gPSBtYWxsb2MgKHNpemUpOwogICAgaWYgKCFtKQoJYWJvcnQgKCk7CiAgICByZXR1cm4gbTsKfQoKdm9pZCAqClJlYWxsb2NhdGUgKHZvaWQgKnAsIGludCBzaXplKQp7CiAgICB2b2lkICAgICpyID0gcmVhbGxvYyAocCwgc2l6ZSk7CgogICAgaWYgKCFyKQoJYWJvcnQgKCk7CiAgICByZXR1cm4gcjsKfQoKdm9pZApEaXNwb3NlICh2b2lkICpwKQp7CiAgICBmcmVlIChwKTsKfQoKU3RyaW5nICoKU3RyaW5nTmV3ICh2b2lkKQp7CiAgICBTdHJpbmcgICpzOwoKICAgIHMgPSBOZXcgKHNpemVvZiAoU3RyaW5nKSk7CiAgICBzLT5idWYgPSBOZXcgKFNUUklOR19JTklUKTsKICAgIHMtPnNpemUgPSBTVFJJTkdfSU5JVCAtIDE7CiAgICBzLT5idWZbMF0gPSAnXDAnOwogICAgcy0+bGVuID0gMDsKICAgIHJldHVybiBzOwp9Cgp2b2lkClN0cmluZ0FkZCAoU3RyaW5nICpzLCBjaGFyIGMpCnsKICAgIGlmIChzLT5sZW4gPT0gcy0+c2l6ZSkKCXMtPmJ1ZiA9IFJlYWxsb2NhdGUgKHMtPmJ1ZiwgKHMtPnNpemUgKj0gMikgKyAxKTsKICAgIHMtPmJ1ZltzLT5sZW4rK10gPSBjOwogICAgcy0+YnVmW3MtPmxlbl0gPSAnXDAnOwp9Cgp2b2lkClN0cmluZ0FkZFN0cmluZyAoU3RyaW5nICpzLCBjaGFyICpidWYpCnsKICAgIHdoaWxlICgqYnVmKQoJU3RyaW5nQWRkIChzLCAqYnVmKyspOwp9CgpTdHJpbmcgKgpTdHJpbmdNYWtlIChjaGFyICpidWYpCnsKICAgIFN0cmluZyAgKnMgPSBTdHJpbmdOZXcgKCk7CiAgICBTdHJpbmdBZGRTdHJpbmcgKHMsIGJ1Zik7CiAgICByZXR1cm4gczsKfQoKdm9pZApTdHJpbmdEZWwgKFN0cmluZyAqcykKewogICAgaWYgKHMtPmxlbikKCXMtPmJ1ZlstLXMtPmxlbl0gPSAnXDAnOwp9Cgp2b2lkClN0cmluZ1B1dCAoRklMRSAqZiwgU3RyaW5nICpzKQp7CiAgICBjaGFyICAgICpiID0gcy0+YnVmOwoKICAgIHdoaWxlICgqYikKCXB1dGMgKCpiKyssIGYpOwp9CgojZGVmaW5lIFN0cmluZ0xhc3QocykJKChzKS0+bGVuID8gKHMpLT5idWZbKHMpLT5sZW4gLSAxXSA6ICdcMCcpCgp2b2lkClN0cmluZ0Rpc3Bvc2UgKFN0cmluZyAqcykKewogICAgRGlzcG9zZSAocy0+YnVmKTsKICAgIERpc3Bvc2UgKHMpOwp9Cgp0eXBlZGVmIHN0cnVjdCB7CiAgICBTdHJpbmcgICp0YWc7CiAgICBTdHJpbmcgICp0ZXh0Owp9IFJlcGxhY2U7CgpSZXBsYWNlICoKUmVwbGFjZU5ldyAodm9pZCkKewogICAgUmVwbGFjZSAqciA9IE5ldyAoc2l6ZW9mIChSZXBsYWNlKSk7CiAgICByLT50YWcgPSBTdHJpbmdOZXcgKCk7CiAgICByLT50ZXh0ID0gU3RyaW5nTmV3ICgpOwogICAgcmV0dXJuIHI7Cn0KCnZvaWQKUmVwbGFjZURpc3Bvc2UgKFJlcGxhY2UgKnIpCnsKICAgIFN0cmluZ0Rpc3Bvc2UgKHItPnRhZyk7CiAgICBTdHJpbmdEaXNwb3NlIChyLT50ZXh0KTsKICAgIERpc3Bvc2UgKHIpOwp9Cgp2b2lkCkJhaWwgKGNoYXIgKmZvcm1hdCwgY2hhciAqYXJnKQp7CiAgICBmcHJpbnRmIChzdGRlcnIsICJmYXRhbDogIik7CiAgICBmcHJpbnRmIChzdGRlcnIsIGZvcm1hdCwgYXJnKTsKICAgIGZwcmludGYgKHN0ZGVyciwgIlxuIik7CiAgICBleGl0ICgxKTsKfQoKUmVwbGFjZSAqClJlcGxhY2VSZWFkIChGSUxFICpmKQp7CiAgICBpbnQJICAgIGM7CiAgICBSZXBsYWNlICpyOwoKICAgIHdoaWxlICgoYyA9IGdldGMgKGYpKSAhPSAnQCcpCiAgICB7CglpZiAoYyA9PSBFT0YpCgkgICAgcmV0dXJuIDA7CiAgICB9CiAgICByID0gUmVwbGFjZU5ldygpOwogICAgd2hpbGUgKChjID0gZ2V0YyAoZikpICE9ICdAJykKICAgIHsKCWlmIChjID09IEVPRikKCXsKCSAgICBSZXBsYWNlRGlzcG9zZSAocik7CgkgICAgcmV0dXJuIDA7Cgl9CglpZiAoaXNzcGFjZSAoYykpCgkgICAgQmFpbCAoImludmFsaWQgY2hhcmFjdGVyIGFmdGVyIHRhZyAlcyIsIHItPnRhZy0+YnVmKTsKCVN0cmluZ0FkZCAoci0+dGFnLCBjKTsKICAgIH0KICAgIGlmIChyLT50YWctPmJ1ZlswXSA9PSAnXDAnKQogICAgewoJUmVwbGFjZURpc3Bvc2UgKHIpOwoJcmV0dXJuIDA7CiAgICB9CiAgICB3aGlsZSAoaXNzcGFjZSAoKGMgPSBnZXRjIChmKSkpKQoJOwogICAgdW5nZXRjIChjLCBmKTsKICAgIHdoaWxlICgoYyA9IGdldGMgKGYpKSAhPSAnQCcgJiYgYyAhPSBFT0YpCglTdHJpbmdBZGQgKHItPnRleHQsIGMpOwogICAgaWYgKGMgPT0gJ0AnKQoJdW5nZXRjIChjLCBmKTsKICAgIHdoaWxlIChpc3NwYWNlIChTdHJpbmdMYXN0IChyLT50ZXh0KSkpCglTdHJpbmdEZWwgKHItPnRleHQpOwogICAgcmV0dXJuIHI7Cn0KCnR5cGVkZWYgc3RydWN0IF9yZXBsYWNlTGlzdCB7CiAgICBzdHJ1Y3QgX3JlcGxhY2VMaXN0CSpuZXh0OwogICAgUmVwbGFjZQkJKnI7Cn0gUmVwbGFjZUxpc3Q7CgpSZXBsYWNlTGlzdCAqClJlcGxhY2VMaXN0TmV3IChSZXBsYWNlICpyLCBSZXBsYWNlTGlzdCAqbmV4dCkKewogICAgUmVwbGFjZUxpc3QJKmwgPSBOZXcgKHNpemVvZiAoUmVwbGFjZUxpc3QpKTsKICAgIGwtPnIgPSByOwogICAgbC0+bmV4dCA9IG5leHQ7CiAgICByZXR1cm4gbDsKfQoKdm9pZApSZXBsYWNlTGlzdERpc3Bvc2UgKFJlcGxhY2VMaXN0ICpsKQp7CiAgICBpZiAobCkKICAgIHsKCVJlcGxhY2VMaXN0RGlzcG9zZSAobC0+bmV4dCk7CglSZXBsYWNlRGlzcG9zZSAobC0+cik7CglEaXNwb3NlIChsKTsKICAgIH0KfQoKdHlwZWRlZiBzdHJ1Y3QgewogICAgUmVwbGFjZUxpc3QJKmhlYWQ7Cn0gUmVwbGFjZVNldDsKClJlcGxhY2VTZXQgKgpSZXBsYWNlU2V0TmV3ICh2b2lkKQp7CiAgICBSZXBsYWNlU2V0CSpzID0gTmV3IChzaXplb2YgKFJlcGxhY2VTZXQpKTsKICAgIHMtPmhlYWQgPSAwOwogICAgcmV0dXJuIHM7Cn0KCnZvaWQKUmVwbGFjZVNldERpc3Bvc2UgKFJlcGxhY2VTZXQgKnMpCnsKICAgIFJlcGxhY2VMaXN0RGlzcG9zZSAocy0+aGVhZCk7CiAgICBEaXNwb3NlIChzKTsKfQoKdm9pZApSZXBsYWNlU2V0QWRkIChSZXBsYWNlU2V0ICpzLCBSZXBsYWNlICpyKQp7CiAgICBzLT5oZWFkID0gUmVwbGFjZUxpc3ROZXcgKHIsIHMtPmhlYWQpOwp9CgpSZXBsYWNlICoKUmVwbGFjZVNldEZpbmQgKFJlcGxhY2VTZXQgKnMsIGNoYXIgKnRhZykKewogICAgUmVwbGFjZUxpc3QJKmw7CgogICAgZm9yIChsID0gcy0+aGVhZDsgbDsgbCA9IGwtPm5leHQpCglpZiAoIXN0cmNtcCAodGFnLCBsLT5yLT50YWctPmJ1ZikpCgkgICAgcmV0dXJuIGwtPnI7CiAgICByZXR1cm4gMDsKfQoKUmVwbGFjZVNldCAqClJlcGxhY2VTZXRSZWFkIChGSUxFICpmKQp7CiAgICBSZXBsYWNlU2V0CSpzID0gUmVwbGFjZVNldE5ldyAoKTsKICAgIFJlcGxhY2UJKnI7CgogICAgd2hpbGUgKChyID0gUmVwbGFjZVJlYWQgKGYpKSkKICAgIHsKCXdoaWxlIChSZXBsYWNlU2V0RmluZCAocywgci0+dGFnLT5idWYpKQoJICAgIFN0cmluZ0FkZCAoci0+dGFnLCAnKycpOwoJUmVwbGFjZVNldEFkZCAocywgcik7CiAgICB9CiAgICBpZiAoIXMtPmhlYWQpCiAgICB7CglSZXBsYWNlU2V0RGlzcG9zZSAocyk7CglzID0gMDsKICAgIH0KICAgIHJldHVybiBzOwp9Cgp0eXBlZGVmIHN0cnVjdCBfc2tpcFN0YWNrIHsKICAgIHN0cnVjdCBfc2tpcFN0YWNrCSpwcmV2OwogICAgaW50CQkJc2tpcHBpbmc7Cn0gU2tpcFN0YWNrOwoKU2tpcFN0YWNrICoKU2tpcFN0YWNrUHVzaCAoU2tpcFN0YWNrICpwcmV2LCBpbnQgc2tpcHBpbmcpCnsKICAgIFNraXBTdGFjawkqc3MgPSBOZXcgKHNpemVvZiAoU2tpcFN0YWNrKSk7CiAgICBzcy0+cHJldiA9IHByZXY7CiAgICBzcy0+c2tpcHBpbmcgPSBza2lwcGluZzsKICAgIHJldHVybiBzczsKfQoKU2tpcFN0YWNrICoKU2tpcFN0YWNrUG9wIChTa2lwU3RhY2sgKnByZXYpCnsKICAgIFNraXBTdGFjawkqc3MgPSBwcmV2LT5wcmV2OwogICAgRGlzcG9zZSAocHJldik7CiAgICByZXR1cm4gc3M7Cn0KCnR5cGVkZWYgc3RydWN0IF9sb29wU3RhY2sgewogICAgc3RydWN0IF9sb29wU3RhY2sJKnByZXY7CiAgICBTdHJpbmcJCSp0YWc7CiAgICBTdHJpbmcJCSpleHRyYTsKICAgIGxvbmcJCXBvczsKfSBMb29wU3RhY2s7CgpMb29wU3RhY2sgKgpMb29wU3RhY2tQdXNoIChMb29wU3RhY2sgKnByZXYsIEZJTEUgKmYsIGNoYXIgKnRhZykKewogICAgTG9vcFN0YWNrCSpscyA9IE5ldyAoc2l6ZW9mIChMb29wU3RhY2spKTsKICAgIGxzLT5wcmV2ID0gcHJldjsKICAgIGxzLT50YWcgPSBTdHJpbmdNYWtlICh0YWcpOwogICAgbHMtPmV4dHJhID0gU3RyaW5nTmV3ICgpOwogICAgbHMtPnBvcyA9IGZ0ZWxsIChmKTsKICAgIHJldHVybiBsczsKfQoKTG9vcFN0YWNrICoKTG9vcFN0YWNrTG9vcCAoUmVwbGFjZVNldCAqcnMsIExvb3BTdGFjayAqbHMsIEZJTEUgKmYpCnsKICAgIFN0cmluZwkqcyA9IFN0cmluZ01ha2UgKGxzLT50YWctPmJ1Zik7CiAgICBMb29wU3RhY2sJKnJldCA9IGxzOwogICAgQm9vbAlsb29wOwoKICAgIFN0cmluZ0FkZCAobHMtPmV4dHJhLCAnKycpOwogICAgU3RyaW5nQWRkU3RyaW5nIChzLCBscy0+ZXh0cmEtPmJ1Zik7CiAgICBsb29wID0gUmVwbGFjZVNldEZpbmQgKHJzLCBzLT5idWYpICE9IDA7CiAgICBTdHJpbmdEaXNwb3NlIChzKTsKICAgIGlmIChsb29wKQoJZnNlZWsgKGYsIGxzLT5wb3MsIFNFRUtfU0VUKTsKICAgIGVsc2UKICAgIHsKCXJldCA9IGxzLT5wcmV2OwoJU3RyaW5nRGlzcG9zZSAobHMtPnRhZyk7CglTdHJpbmdEaXNwb3NlIChscy0+ZXh0cmEpOwoJRGlzcG9zZSAobHMpOwogICAgfQogICAgcmV0dXJuIHJldDsKfQoKdm9pZApMaW5lU2tpcCAoRklMRSAqZikKewogICAgaW50CWM7CgogICAgd2hpbGUgKChjID0gZ2V0YyAoZikpID09ICdcbicpCgk7CiAgICB1bmdldGMgKGMsIGYpOwp9Cgp2b2lkCkRvUmVwbGFjZSAoRklMRSAqZiwgUmVwbGFjZVNldCAqcykKewogICAgaW50CQljOwogICAgU3RyaW5nCSp0YWc7CiAgICBSZXBsYWNlCSpyOwogICAgU2tpcFN0YWNrCSpzcyA9IDA7CiAgICBMb29wU3RhY2sJKmxzID0gMDsKICAgIGludAkJc2tpcHBpbmcgPSAwOwoKICAgIHdoaWxlICgoYyA9IGdldGMgKGYpKSAhPSBFT0YpCiAgICB7CglpZiAoYyA9PSAnQCcpCgl7CgkgICAgdGFnID0gU3RyaW5nTmV3ICgpOwoJICAgIHdoaWxlICgoYyA9IGdldGMgKGYpKSAhPSAnQCcpCgkgICAgewoJCWlmIChjID09IEVPRikKCQkgICAgYWJvcnQgKCk7CgkJU3RyaW5nQWRkICh0YWcsIGMpOwoJICAgIH0KCSAgICBpZiAobHMpCgkJU3RyaW5nQWRkU3RyaW5nICh0YWcsIGxzLT5leHRyYS0+YnVmKTsKCSAgICBzd2l0Y2ggKHRhZy0+YnVmWzBdKSB7CgkgICAgY2FzZSAnPyc6CgkJc3MgPSBTa2lwU3RhY2tQdXNoIChzcywgc2tpcHBpbmcpOwoJCWlmICghUmVwbGFjZVNldEZpbmQgKHMsIHRhZy0+YnVmICsgMSkpCgkJICAgIHNraXBwaW5nKys7CgkJTGluZVNraXAgKGYpOwoJCWJyZWFrOwoJICAgIGNhc2UgJzonOgoJCWlmICghc3MpCgkJICAgIGFib3J0ICgpOwoJCWlmIChzcy0+c2tpcHBpbmcgPT0gc2tpcHBpbmcpCgkJICAgICsrc2tpcHBpbmc7CgkJZWxzZQoJCSAgICAtLXNraXBwaW5nOwoJCUxpbmVTa2lwIChmKTsKCQlicmVhazsKCSAgICBjYXNlICc7JzoKCQlza2lwcGluZyA9IHNzLT5za2lwcGluZzsKCQlzcyA9IFNraXBTdGFja1BvcCAoc3MpOwoJCUxpbmVTa2lwIChmKTsKCQlicmVhazsKCSAgICBjYXNlICd7JzoKCQlscyA9IExvb3BTdGFja1B1c2ggKGxzLCBmLCB0YWctPmJ1ZiArIDEpOwoJCUxpbmVTa2lwIChmKTsKCQlicmVhazsKCSAgICBjYXNlICd9JzoKCQlscyA9IExvb3BTdGFja0xvb3AgKHMsIGxzLCBmKTsKCQlMaW5lU2tpcCAoZik7CgkJYnJlYWs7CgkgICAgZGVmYXVsdDoKCQlyID0gUmVwbGFjZVNldEZpbmQgKHMsIHRhZy0+YnVmKTsKCQlpZiAociAmJiAhc2tpcHBpbmcpCgkJICAgIFN0cmluZ1B1dCAoc3Rkb3V0LCByLT50ZXh0KTsKCQlicmVhazsKCSAgICB9CgkgICAgU3RyaW5nRGlzcG9zZSAodGFnKTsKCX0KCWVsc2UgaWYgKCFza2lwcGluZykKCSAgICBwdXRjaGFyIChjKTsKICAgIH0KfQoKaW50Cm1haW4gKGludCBhcmdjLCBjaGFyICoqYXJndikKewogICAgRklMRQkqZjsKICAgIFJlcGxhY2VTZXQJKnM7CgogICAgaWYgKCFhcmd2WzFdKQoJQmFpbCAoInVzYWdlOiAlcyA8dGVtcGxhdGUuc2dtbD4iLCBhcmd2WzBdKTsKICAgIGYgPSBmb3BlbiAoYXJndlsxXSwgInIiKTsKICAgIGlmICghZikKICAgIHsKCUJhaWwgKCJjYW4ndCBvcGVuIGZpbGUgJXMiLCBhcmd2WzFdKTsKCWV4aXQgKDEpOwogICAgfQogICAgd2hpbGUgKChzID0gUmVwbGFjZVNldFJlYWQgKHN0ZGluKSkpCiAgICB7CglEb1JlcGxhY2UgKGYsIHMpOwoJUmVwbGFjZVNldERpc3Bvc2UgKHMpOwoJcmV3aW5kIChmKTsKICAgIH0KICAgIGlmIChmZXJyb3IgKHN0ZG91dCkpCglCYWlsICgiJXMiLCAiZXJyb3Igd3JpdGluZyBvdXRwdXQiKTsKICAgIGV4aXQgKDApOwp9Cg==