LyoKICogbG9nZ2luZy5jIC0gZ2VuZXJpYyBsb2dnaW5nIGZvciBzbm1wLWFnZW50CiAqICogQ29udHJpYnV0ZWQgYnkgUmFnbmFyIEtq+HJzdGFkLCB1Y2RAcmFnbmFyay52ZXN0ZGF0YS5ubyAxOTk5LTA2LTI2IAogKi8KLyogUG9ydGlvbnMgb2YgdGhpcyBmaWxlIGFyZSBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29weXJpZ2h0KHMpLiAgU2VlCiAqIHRoZSBOZXQtU05NUCdzIENPUFlJTkcgZmlsZSBmb3IgbW9yZSBkZXRhaWxzIGFuZCBvdGhlciBjb3B5cmlnaHRzCiAqIHRoYXQgbWF5IGFwcGx5OgogKi8KLyoKICogUG9ydGlvbnMgb2YgdGhpcyBmaWxlIGFyZSBjb3B5cmlnaHRlZCBieToKICogQ29weXJpZ2h0IKkgMjAwMyBTdW4gTWljcm9zeXN0ZW1zLCBJbmMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqIFVzZSBpcyBzdWJqZWN0IHRvIGxpY2Vuc2UgdGVybXMgc3BlY2lmaWVkIGluIHRoZSBDT1BZSU5HIGZpbGUKICogZGlzdHJpYnV0ZWQgd2l0aCB0aGUgTmV0LVNOTVAgcGFja2FnZS4KICovCi8qKiBAZGVmZ3JvdXAgc25tcF9sb2dnaW5nIGdlbmVyaWMgbG9nZ2luZyBmb3IgbmV0LXNubXAgCiAqICBAaW5ncm91cCBsaWJyYXJ5CiAqIAogKiAgQHsKICovCiNpbmNsdWRlIDxuZXQtc25tcC9uZXQtc25tcC1jb25maWcuaD4KI2luY2x1ZGUgPHN0ZGlvLmg+CiNpZiBIQVZFX01BTExPQ19ICiNpbmNsdWRlIDxtYWxsb2MuaD4KI2VuZGlmCiNpZiBIQVZFX1NUUklOR19ICiNpbmNsdWRlIDxzdHJpbmcuaD4KI2Vsc2UKI2luY2x1ZGUgPHN0cmluZ3MuaD4KI2VuZGlmCiNpbmNsdWRlIDxjdHlwZS5oPgojaWYgSEFWRV9TVERMSUJfSAojaW5jbHVkZSA8c3RkbGliLmg+CiNlbmRpZgojaW5jbHVkZSA8c3lzL3R5cGVzLmg+CiNpbmNsdWRlIDxzeXMvc3RhdC5oPgojaW5jbHVkZSA8ZmNudGwuaD4KI2luY2x1ZGUgPGVycm5vLmg+CiNpZiBIQVZFX1NZU0xPR19ICiNpbmNsdWRlIDxzeXNsb2cuaD4KI2lmbmRlZiBMT0dfQ09OUyAgICAgICAgICAgICAgICAvKiBJbnRlcmVzdGluZyBVbHRyaXggZmVhdHVyZSAqLwojaW5jbHVkZSA8c3lzL3N5c2xvZy5oPgojZW5kaWYKI2VuZGlmCiNpZiBUSU1FX1dJVEhfU1lTX1RJTUUKIyBpbmNsdWRlIDxzeXMvdGltZS5oPgojIGluY2x1ZGUgPHRpbWUuaD4KI2Vsc2UKIyBpZiBIQVZFX1NZU19USU1FX0gKIyAgaW5jbHVkZSA8c3lzL3RpbWUuaD4KIyBlbHNlCiMgIGluY2x1ZGUgPHRpbWUuaD4KIyBlbmRpZgojZW5kaWYKI2lmIEhBVkVfTkVUSU5FVF9JTl9ICiNpbmNsdWRlIDxuZXRpbmV0L2luLmg+CiNlbmRpZgoKI2luY2x1ZGUgPHN0ZGFyZy5oPgoKI2lmIEhBVkVfVU5JU1REX0gKI2luY2x1ZGUgPHVuaXN0ZC5oPgojZW5kaWYKI2lmIEhBVkVfRE1BTExPQ19ICiNpbmNsdWRlIDxkbWFsbG9jLmg+CiNlbmRpZgoKI2luY2x1ZGUgPG5ldC1zbm1wL3R5cGVzLmg+CiNpbmNsdWRlIDxuZXQtc25tcC9vdXRwdXRfYXBpLmg+CiNpbmNsdWRlIDxuZXQtc25tcC9saWJyYXJ5L3NubXBfbG9nZ2luZy5oPiAgICAgIC8qIEZvciB0aGlzIGZpbGUncyAiaW50ZXJuYWwiIGRlZmluaXRpb25zICovCiNpbmNsdWRlIDxuZXQtc25tcC9jb25maWdfYXBpLmg+CiNpbmNsdWRlIDxuZXQtc25tcC91dGlsaXRpZXMuaD4KCiNpbmNsdWRlIDxuZXQtc25tcC9saWJyYXJ5L2NhbGxiYWNrLmg+CiNkZWZpbmUgTE9HTEVOR1RIIDEwMjQKCiNpZmRlZiB2YV9jb3B5CiNkZWZpbmUgTkVFRF9WQV9FTkRfQUZURVJfVkFfQ09QWQojZWxzZQojaWZkZWYgX192YWNvcHkKI2RlZmluZSB2YWNvcHkgX192YWNvcHkKI2RlZmluZSBORUVEX1ZBX0VORF9BRlRFUl9WQV9DT1BZCiNlbHNlCiNkZWZpbmUgdmFfY29weShkZXN0LCBzcmMpIG1lbWNweSAoJmRlc3QsICZzcmMsIHNpemVvZiAodmFfbGlzdCkpCiNlbmRpZgojZW5kaWYKCi8qCiAqIGxvZ2hfaGVhZDogIEEgbGlzdCBvZiBhbGwgbG9nIGhhbmRsZXJzLCBpbiBpbmNyZWFzaW5nIG9yZGVyIG9mIHByaW9yaXR5CiAqIGxvZ2hfcHJpb3JpdGllczogICdJbmRleGVzJyBpbnRvIHRoaXMgbGlzdCwgYnkgcHJpb3JpdHkKICovCm5ldHNubXBfbG9nX2hhbmRsZXIgKmxvZ2hfaGVhZCA9IE5VTEw7Cm5ldHNubXBfbG9nX2hhbmRsZXIgKmxvZ2hfcHJpb3JpdGllc1tMT0dfREVCVUcrMV07CnN0YXRpYyBpbnQgIGxvZ2hfZW5hYmxlZCA9IDA7CgpzdGF0aWMgY2hhciBzeXNsb2duYW1lWzY0XSA9IERFRkFVTFRfTE9HX0lEOwoKdm9pZApuZXRzbm1wX2Rpc2FibGVfdGhpc19sb2doYW5kbGVyKG5ldHNubXBfbG9nX2hhbmRsZXIgKmxvZ2gpCnsKICAgIGlmICghbG9naCB8fCAoMCA9PSBsb2doLT5lbmFibGVkKSkKICAgICAgICByZXR1cm47CiAgICBsb2doLT5lbmFibGVkID0gMDsKICAgIC0tbG9naF9lbmFibGVkOwogICAgbmV0c25tcF9hc3NlcnQobG9naF9lbmFibGVkID49IDApOwp9Cgp2b2lkCm5ldHNubXBfZW5hYmxlX3RoaXNfbG9naGFuZGxlcihuZXRzbm1wX2xvZ19oYW5kbGVyICpsb2doKQp7CiAgICBpZiAoIWxvZ2ggfHwgKDAgIT0gbG9naC0+ZW5hYmxlZCkpCiAgICAgICAgcmV0dXJuOwogICAgbG9naC0+ZW5hYmxlZCA9IDE7CiAgICArK2xvZ2hfZW5hYmxlZDsKfQoKdm9pZApuZXRzbm1wX2VuYWJsZV9maWxlbG9nKG5ldHNubXBfbG9nX2hhbmRsZXIgKmxvZ2gsIGludCBkb250X3plcm9fbG9nKTsKCiNpZm5kZWYgSEFWRV9WU05QUklOVEYKICAgICAgICAgICAgICAgIC8qCiAgICAgICAgICAgICAgICAgKiBOZWVkIHRvIHVzZSB0aGUgVUNELXByb3ZpZGVkIG9uZSAKICAgICAgICAgICAgICAgICAqLwppbnQgICAgICAgICAgICAgdnNucHJpbnRmKGNoYXIgKnN0ciwgc2l6ZV90IGNvdW50LCBjb25zdCBjaGFyICpmbXQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgdmFfbGlzdCBhcmcpOwojZW5kaWYKCnZvaWQKcGFyc2VfY29uZmlnX2xvZ09wdGlvbihjb25zdCBjaGFyICp0b2tlbiwgY2hhciAqY3B0cikKewogIGludCBteV9hcmdjID0gMCA7CiAgY2hhciAqKm15X2FyZ3YgPSBOVUxMOwoKICBzbm1wX2xvZ19vcHRpb25zKCBjcHRyLCBteV9hcmdjLCBteV9hcmd2ICk7Cn0KCnZvaWQKaW5pdF9zbm1wX2xvZ2dpbmcodm9pZCkKewogICAgbmV0c25tcF9kc19yZWdpc3Rlcl9wcmVtaWIoQVNOX0JPT0xFQU4sICJzbm1wIiwgImxvZ1RpbWVzdGFtcCIsIAoJCQkgTkVUU05NUF9EU19MSUJSQVJZX0lELCBORVRTTk1QX0RTX0xJQl9MT0dfVElNRVNUQU1QKTsKICAgIHJlZ2lzdGVyX3ByZW5ldHNubXBfbWliX2hhbmRsZXIoInNubXAiLCAibG9nT3B0aW9uIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGFyc2VfY29uZmlnX2xvZ09wdGlvbiwgTlVMTCwgInN0cmluZyIpOwoKfQoKdm9pZApzaHV0ZG93bl9zbm1wX2xvZ2dpbmcodm9pZCkKewogICBzbm1wX2Rpc2FibGVfbG9nKCk7CiAgIHdoaWxlKE5VTEwgIT0gbG9naF9oZWFkKQogICAgICBuZXRzbm1wX3JlbW92ZV9sb2doYW5kbGVyKCBsb2doX2hlYWQgKTsKfQoKLyoKICogVGhlc2UgZGVmaW5pdGlvbnMgaGFuZGxlIDQuMiBzeXN0ZW1zIHdpdGhvdXQgYWRkaXRpb25hbCBzeXNsb2cgZmFjaWxpdGllcy4KICovCiNpZm5kZWYgTE9HX0NPTlMKI2RlZmluZSBMT0dfQ09OUwkwICAgICAgIC8qIERvbid0IGJvdGhlciBpZiBub3QgZGVmaW5lZC4uLiAqLwojZW5kaWYKI2lmbmRlZiBMT0dfUElECiNkZWZpbmUgTE9HX1BJRAkJMCAgICAgICAvKiBEb24ndCBib3RoZXIgaWYgbm90IGRlZmluZWQuLi4gKi8KI2VuZGlmCiNpZm5kZWYgTE9HX0xPQ0FMMAojZGVmaW5lIExPR19MT0NBTDAJMAojZW5kaWYKI2lmbmRlZiBMT0dfTE9DQUwxCiNkZWZpbmUgTE9HX0xPQ0FMMQkwCiNlbmRpZgojaWZuZGVmIExPR19MT0NBTDIKI2RlZmluZSBMT0dfTE9DQUwyCTAKI2VuZGlmCiNpZm5kZWYgTE9HX0xPQ0FMMwojZGVmaW5lIExPR19MT0NBTDMJMAojZW5kaWYKI2lmbmRlZiBMT0dfTE9DQUw0CiNkZWZpbmUgTE9HX0xPQ0FMNAkwCiNlbmRpZgojaWZuZGVmIExPR19MT0NBTDUKI2RlZmluZSBMT0dfTE9DQUw1CTAKI2VuZGlmCiNpZm5kZWYgTE9HX0xPQ0FMNgojZGVmaW5lIExPR19MT0NBTDYJMAojZW5kaWYKI2lmbmRlZiBMT0dfTE9DQUw3CiNkZWZpbmUgTE9HX0xPQ0FMNwkwCiNlbmRpZgojaWZuZGVmIExPR19EQUVNT04KI2RlZmluZSBMT0dfREFFTU9OCTAKI2VuZGlmCiNpZm5kZWYgTE9HX1VTRVIKI2RlZmluZSBMT0dfVVNFUgkwCiNlbmRpZgoKLyogU2V0IGxpbmUgYnVmZmVyaW5nIG1vZGUgZm9yIGEgc3RyZWFtLiAqLwp2b2lkCm5ldHNubXBfc2V0X2xpbmVfYnVmZmVyaW5nKEZJTEUgKnN0cmVhbSkKewojaWYgZGVmaW5lZChXSU4zMikKICAgIC8qCiAgICAgKiBBY2NvcmRpbmcgdG8gTVNETiwgdGhlIE1pY3Jvc29mdCBWaXN1YWwgU3R1ZGlvIEMgcnVudGltZSBsaWJyYXJ5IGRvZXMKICAgICAqIG5vdCBzdXBwb3J0IGxpbmUgYnVmZmVyaW5nLCBzbyB0dXJuIG9mZiBidWZmZXJpbmcgY29tcGxldGVseS4KICAgICAqIFNlZSBhbHNvIGh0dHA6Ly9tc2RuLm1pY3Jvc29mdC5jb20vZW4tdXMvbGlicmFyeS84NmNlYmhmcyhWUy43MSkuYXNweC4KICAgICAqLwogICAgc2V0dmJ1ZihzdHJlYW0sIE5VTEwsIF9JT05CRiwgQlVGU0laKTsKI2VsaWYgZGVmaW5lZChIQVZFX1NFVExJTkVCVUYpCiAgICAvKiBzZXRsaW5lZnVuY3Rpb24oKSBpcyBhIGZ1bmN0aW9uIGZyb20gdGhlIEJTRCBVbml4IEFQSS4gKi8KICAgIHNldGxpbmVidWYoc3RyZWFtKTsKI2Vsc2UKICAgIC8qIFNlZSBhbHNvIHRoZSBDODkgb3IgQzk5IHN0YW5kYXJkIGZvciBtb3JlIGluZm9ybWF0aW9uIGFib3V0IHNldHZidWYoKS4gKi8KICAgIHNldHZidWYoc3RyZWFtLCBOVUxMLCBfSU9MQkYsIEJVRlNJWik7CiNlbmRpZgp9CgovKgogKiBEZWNvZGVzIGxvZyBwcmlvcml0eS4KICogQHBhcmFtIG9wdGFyZyAtIElOIC0gcHJpb3JpdHkgdG8gZGVjb2RlLCAiMCIgb3IgIjAtNyIKICogICAgICAgICAgICAgICAgIE9VVCAtIHBvaW50cyB0byBsYXN0IGNoYXJhY3RlciBhZnRlciB0aGUgZGVjb2RlZCBwcmlvcml0eQogKiBAcGFyYW0gcHJpX21heCAtIE9VVCAtIG1heGltdW0gcHJpb3JpdHkgKGkuZS4gMHg3IGZyb20gIjAtNyIpCiAqLwppbnQKZGVjb2RlX3ByaW9yaXR5KCBjaGFyICoqb3B0YXJnLCBpbnQgKnByaV9tYXggKQp7CiAgICBpbnQgcHJpX2xvdyA9IExPR19ERUJVRzsKCiAgICBpZiAoKm9wdGFyZyA9PSBOVUxMKQogICAgICAgIHJldHVybiAtMTsKCiAgICBzd2l0Y2ggKCoqb3B0YXJnKSB7CiAgICAgICAgY2FzZSAnMCc6IAogICAgICAgIGNhc2UgJyEnOiAKICAgICAgICAgICAgcHJpX2xvdyA9IExPR19FTUVSRzsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSAnMSc6IAogICAgICAgIGNhc2UgJ2EnOiAKICAgICAgICBjYXNlICdBJzogCiAgICAgICAgICAgIHByaV9sb3cgPSBMT0dfQUxFUlQ7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgJzInOiAKICAgICAgICBjYXNlICdjJzogCiAgICAgICAgY2FzZSAnQyc6IAogICAgICAgICAgICBwcmlfbG93ID0gTE9HX0NSSVQ7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgJzMnOiAKICAgICAgICBjYXNlICdlJzogCiAgICAgICAgY2FzZSAnRSc6IAogICAgICAgICAgICBwcmlfbG93ID0gTE9HX0VSUjsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSAnNCc6IAogICAgICAgIGNhc2UgJ3cnOiAKICAgICAgICBjYXNlICdXJzogCiAgICAgICAgICAgIHByaV9sb3cgPSBMT0dfV0FSTklORzsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSAnNSc6IAogICAgICAgIGNhc2UgJ24nOiAKICAgICAgICBjYXNlICdOJzogCiAgICAgICAgICAgIHByaV9sb3cgPSBMT0dfTk9USUNFOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlICc2JzogCiAgICAgICAgY2FzZSAnaSc6IAogICAgICAgIGNhc2UgJ0knOiAKICAgICAgICAgICAgcHJpX2xvdyA9IExPR19JTkZPOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlICc3JzogCiAgICAgICAgY2FzZSAnZCc6IAogICAgICAgIGNhc2UgJ0QnOiAKICAgICAgICAgICAgcHJpX2xvdyA9IExPR19ERUJVRzsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgZGVmYXVsdDogCiAgICAgICAgICAgIGZwcmludGYoc3RkZXJyLCAiaW52YWxpZCBwcmlvcml0eTogJWNcbiIsKipvcHRhcmcpOwogICAgICAgICAgICByZXR1cm4gLTE7CiAgICB9CiAgICAqb3B0YXJnID0gKm9wdGFyZysxOwoKICAgIGlmIChwcmlfbWF4ICYmICoqb3B0YXJnPT0nLScpIHsKICAgICAgICAqb3B0YXJnID0gKm9wdGFyZyArIDE7IC8qIHNraXAgJy0nICovCiAgICAgICAgKnByaV9tYXggPSBkZWNvZGVfcHJpb3JpdHkoIG9wdGFyZywgTlVMTCApOwogICAgICAgIGlmICgqcHJpX21heCA9PSAtMSkgcmV0dXJuIC0xOwogICAgICAgIGlmIChwcmlfbG93IDwgKnByaV9tYXgpIHsgCiAgICAgICAgICAgIGludCB0bXAgPSBwcmlfbG93OyAKICAgICAgICAgICAgcHJpX2xvdyA9ICpwcmlfbWF4OyAKICAgICAgICAgICAgKnByaV9tYXggPSB0bXA7IAogICAgICAgIH0KCiAgICB9CiAgICByZXR1cm4gcHJpX2xvdzsKfQoKaW50CmRlY29kZV9mYWNpbGl0eSggY2hhciAqb3B0YXJnICkKewogICAgaWYgKG9wdGFyZyA9PSBOVUxMKQogICAgICAgIHJldHVybiAtMTsKCiAgICBzd2l0Y2ggKCpvcHRhcmcpIHsKICAgIGNhc2UgJ2QnOgogICAgY2FzZSAnRCc6CiAgICAgICAgcmV0dXJuIExPR19EQUVNT047CiAgICBjYXNlICd1JzoKICAgIGNhc2UgJ1UnOgogICAgICAgIHJldHVybiBMT0dfVVNFUjsKICAgIGNhc2UgJzAnOgogICAgICAgIHJldHVybiBMT0dfTE9DQUwwOwogICAgY2FzZSAnMSc6CiAgICAgICAgcmV0dXJuIExPR19MT0NBTDE7CiAgICBjYXNlICcyJzoKICAgICAgICByZXR1cm4gTE9HX0xPQ0FMMjsKICAgIGNhc2UgJzMnOgogICAgICAgIHJldHVybiBMT0dfTE9DQUwzOwogICAgY2FzZSAnNCc6CiAgICAgICAgcmV0dXJuIExPR19MT0NBTDQ7CiAgICBjYXNlICc1JzoKICAgICAgICByZXR1cm4gTE9HX0xPQ0FMNTsKICAgIGNhc2UgJzYnOgogICAgICAgIHJldHVybiBMT0dfTE9DQUw2OwogICAgY2FzZSAnNyc6CiAgICAgICAgcmV0dXJuIExPR19MT0NBTDc7CiAgICBkZWZhdWx0OgogICAgICAgIGZwcmludGYoc3RkZXJyLCAiaW52YWxpZCBzeXNsb2cgZmFjaWxpdHk6ICVjXG4iLCpvcHRhcmcpOwogICAgICAgIHJldHVybiAtMTsKICAgIH0KfQoKaW50CnNubXBfbG9nX29wdGlvbnMoY2hhciAqb3B0YXJnLCBpbnQgYXJnYywgY2hhciAqY29uc3QgKmFyZ3YpCnsKICAgIGNoYXIgICAgICAgICAgICpjcCA9IG9wdGFyZzsKICAgICAgICAvKgoJICogSG1tbS4uLiB0aGlzIGRvZXNuJ3Qgc2VlbSB0byB3b3JrLgoJICogVGhlIG1haW4gYWdlbnQgJ2dldG9wdCcgaGFuZGxpbmcgYXNzdW1lcwoJICogICB0aGF0IHRoZSAtTCBvcHRpb24gdGFrZXMgYW4gYXJndW1lbnQsCgkgKiAgIGFuZCBvYmplY3RzIGlmIHRoaXMgaXMgbWlzc2luZy4KCSAqIFRyeWluZyB0byBkaWZmZXJlbnRpYXRlIGJldHdlZW4KCSAqICAgbmV3LXN0eWxlICItTHgiLCBhbmQgb2xkLXN0eWxlICItTCB4eCIKCSAqICAgaXMgbGlrZWx5IHRvIGJlIGEgbWFqb3IgaGVhZGFjaGUuCgkgKi8KICAgIGNoYXIgICAgICAgICAgICBtaXNzaW5nX29wdCA9ICdlJzsJLyogb2xkIC1MIGlzIG5ldyAtTGUgKi8KICAgIGludCAgICAgICAgICAgICBwcmlvcml0eSA9IExPR19ERUJVRzsKICAgIGludCAgICAgICAgICAgICBwcmlfbWF4ICA9IExPR19FTUVSRzsKICAgIGludCAgICAgICAgICAgICBpbmNfb3B0aW5kID0gMDsKICAgIG5ldHNubXBfbG9nX2hhbmRsZXIgKmxvZ2g7CgogICAgREVCVUdNU0dUKCgibG9nZ2luZzpvcHRpb25zIiwgIm9wdGFyZzogJyVzJywgYXJnYyAlZCwgYXJndiAnJXMnXG4iLAogICAgICAgICAgICAgICBvcHRhcmcsIGFyZ2MsIGFyZ3YgPyBhcmd2WzBdIDogIk5VTEwiKSk7CiAgICBvcHRhcmcrKzsKICAgIGlmICghKmNwKQogICAgICAgIGNwID0gJm1pc3Npbmdfb3B0OwoKICAgIC8qCiAgICAgKiBTdXBwb3J0ICcuLi4gLUx4PXZhbHVlIC4uLi4nIHN5bnRheAogICAgICovCiAgICBpZiAoKm9wdGFyZyA9PSAnPScpIHsKICAgICAgICBvcHRhcmcrKzsKICAgIH0KICAgIC8qCiAgICAgKiBhbmQgJy4uLi4gIi1MeCB2YWx1ZSIgLi4uLicgICgqd2l0aCogdGhlIHF1b3RlcykKICAgICAqLwogICAgd2hpbGUgKCpvcHRhcmcgJiYgaXNzcGFjZSgodW5zaWduZWQgY2hhcikoKm9wdGFyZykpKSB7CiAgICAgICAgb3B0YXJnKys7CiAgICB9CiAgICAvKgogICAgICogRmluYWxseSwgaGFuZGxlICIuLi4uIC1MeCB2YWx1ZSAuLi4uIiBzeW50YXgKICAgICAqICAgKCp3aXRob3V0KiBzdXJyb3VuZGluZyBxdW90ZXMpCiAgICAgKi8KICAgIGlmICgoISpvcHRhcmcpICYmIChOVUxMICE9IGFyZ3YpKSB7CiAgICAgICAgLyoKICAgICAgICAgKiBXZSd2ZSBydW4gb2ZmIHRoZSBlbmQgb2YgdGhlIGFyZ3VtZW50CiAgICAgICAgICogIHNvIG1vdmUgb24gdG8gdGhlIG5leHQuCiAgICAgICAgICogQnV0IHdlIG1pZ2h0IG5vdCBhY3R1YWxseSBuZWVkIGl0LCBzbyBkb24ndAoJICogIGluY3JlbWVudCBvcHRpbmQganVzdCB5ZXQhCiAgICAgICAgICovCiAgICAgICAgb3B0YXJnID0gYXJndltvcHRpbmRdOwogICAgICAgIGluY19vcHRpbmQgPSAxOwogICAgfQoKICAgIERFQlVHTVNHVCgoImxvZ2dpbmc6b3B0aW9ucyIsICIqY3A6ICclYydcbiIsICpjcCkpOwogICAgc3dpdGNoICgqY3ApIHsKCiAgICAvKgogICAgICogTG9nIHRvIFN0YW5kYXJkIEVycm9yCiAgICAgKi8KICAgIGNhc2UgJ0UnOgogICAgICAgIHByaW9yaXR5ID0gZGVjb2RlX3ByaW9yaXR5KCAmb3B0YXJnLCAmcHJpX21heCApOwogICAgICAgIGlmIChwcmlvcml0eSA9PSAtMSkgIHJldHVybiAtMTsKICAgICAgICBpZiAoaW5jX29wdGluZCkKICAgICAgICAgICAgb3B0aW5kKys7CiAgICAgICAgLyogRmFsbHRocm91Z2ggKi8KICAgIGNhc2UgJ2UnOgogICAgICAgIGxvZ2ggPSBuZXRzbm1wX3JlZ2lzdGVyX2xvZ2hhbmRsZXIoTkVUU05NUF9MT0dIQU5ETEVSX1NUREVSUiwgcHJpb3JpdHkpOwogICAgICAgIGlmIChsb2doKSB7CiAgICAgICAgICAgIG5ldHNubXBfc2V0X2xpbmVfYnVmZmVyaW5nKHN0ZGVycik7CiAgICAgICAgICAgIGxvZ2gtPnByaV9tYXggPSBwcmlfbWF4OwogICAgICAgICAgICBsb2doLT50b2tlbiAgID0gc3RyZHVwKCJzdGRlcnIiKTsKCX0KICAgICAgICBicmVhazsKCiAgICAvKgogICAgICogTG9nIHRvIFN0YW5kYXJkIE91dHB1dAogICAgICovCiAgICBjYXNlICdPJzoKICAgICAgICBwcmlvcml0eSA9IGRlY29kZV9wcmlvcml0eSggJm9wdGFyZywgJnByaV9tYXggKTsKICAgICAgICBpZiAocHJpb3JpdHkgPT0gLTEpICByZXR1cm4gLTE7CiAgICAgICAgaWYgKGluY19vcHRpbmQpCiAgICAgICAgICAgIG9wdGluZCsrOwogICAgICAgIC8qIEZhbGx0aHJvdWdoICovCiAgICBjYXNlICdvJzoKICAgICAgICBsb2doID0gbmV0c25tcF9yZWdpc3Rlcl9sb2doYW5kbGVyKE5FVFNOTVBfTE9HSEFORExFUl9TVERFUlIsIHByaW9yaXR5KTsKICAgICAgICBpZiAobG9naCkgewogICAgICAgICAgICBuZXRzbm1wX3NldF9saW5lX2J1ZmZlcmluZyhzdGRvdXQpOwogICAgICAgICAgICBsb2doLT5wcmlfbWF4ID0gcHJpX21heDsKICAgICAgICAgICAgbG9naC0+dG9rZW4gICA9IHN0cmR1cCgic3Rkb3V0Iik7CiAgICAgICAgICAgIGxvZ2gtPmltYWdpYyAgPSAxOwkgICAgLyogc3Rkb3V0LCBub3Qgc3RkZXJyICovCgl9CiAgICAgICAgYnJlYWs7CgogICAgLyoKICAgICAqIExvZyB0byBhIG5hbWVkIGZpbGUKICAgICAqLwogICAgY2FzZSAnRic6CiAgICAgICAgcHJpb3JpdHkgPSBkZWNvZGVfcHJpb3JpdHkoICZvcHRhcmcsICZwcmlfbWF4ICk7CiAgICAgICAgaWYgKHByaW9yaXR5ID09IC0xIHx8ICFhcmd2KSAgcmV0dXJuIC0xOwogICAgICAgIG9wdGFyZyA9IGFyZ3ZbKytvcHRpbmRdOwogICAgICAgIC8qIEZhbGx0aHJvdWdoICovCiAgICBjYXNlICdmJzoKICAgICAgICBpZiAoaW5jX29wdGluZCkKICAgICAgICAgICAgb3B0aW5kKys7CiAgICAgICAgaWYgKCFvcHRhcmcpIHsKICAgICAgICAgICAgZnByaW50ZihzdGRlcnIsICJNaXNzaW5nIGxvZyBmaWxlXG4iKTsKICAgICAgICAgICAgcmV0dXJuIC0xOwogICAgICAgIH0KICAgICAgICBsb2doID0gbmV0c25tcF9yZWdpc3Rlcl9sb2doYW5kbGVyKE5FVFNOTVBfTE9HSEFORExFUl9GSUxFLCBwcmlvcml0eSk7CiAgICAgICAgaWYgKGxvZ2gpIHsKICAgICAgICAgICAgbG9naC0+cHJpX21heCA9IHByaV9tYXg7CiAgICAgICAgICAgIGxvZ2gtPnRva2VuICAgPSBzdHJkdXAob3B0YXJnKTsKICAgICAgICAgICAgbmV0c25tcF9lbmFibGVfZmlsZWxvZyhsb2doLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldHNubXBfZHNfZ2V0X2Jvb2xlYW4oTkVUU05NUF9EU19MSUJSQVJZX0lELAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTkVUU05NUF9EU19MSUJfQVBQRU5EX0xPR0ZJTEVTKSk7Cgl9CiAgICAgICAgYnJlYWs7CgogICAgLyoKICAgICAqIExvZyB0byBzeXNsb2cKICAgICAqLwogICAgY2FzZSAnUyc6CiAgICAgICAgcHJpb3JpdHkgPSBkZWNvZGVfcHJpb3JpdHkoICZvcHRhcmcsICZwcmlfbWF4ICk7CiAgICAgICAgaWYgKHByaW9yaXR5ID09IC0xIHx8ICFhcmd2KSAgcmV0dXJuIC0xOwogICAgICAgIGlmICghb3B0YXJnWzBdKSB7CiAgICAgICAgICAgIC8qIFRoZSBjb21tYW5kIGxpbmUgYXJndW1lbnQgd2l0aCBwcmlvcml0eSBkb2VzIG5vdCBjb250YWluIGxvZwogICAgICAgICAgICAgKiBmYWNpbGl0eS4gVGhlIGZhY2lsaXR5IG11c3QgYmUgaW4gbmV4dCBhcmd1bWVudCB0aGVuLiAqLwogICAgICAgICAgICBvcHRpbmQrKzsKICAgICAgICAgICAgaWYgKG9wdGluZCA8IGFyZ2MpCiAgICAgICAgICAgICAgICBvcHRhcmcgPSBhcmd2W29wdGluZF07CiAgICAgICAgfQogICAgICAgIC8qIEZhbGx0aHJvdWdoICovCiAgICBjYXNlICdzJzoKICAgICAgICBpZiAoaW5jX29wdGluZCkKICAgICAgICAgICAgb3B0aW5kKys7CiAgICAgICAgaWYgKCFvcHRhcmcpIHsKICAgICAgICAgICAgZnByaW50ZihzdGRlcnIsICJNaXNzaW5nIHN5c2xvZyBmYWNpbGl0eVxuIik7CiAgICAgICAgICAgIHJldHVybiAtMTsKICAgICAgICB9CiAgICAgICAgbG9naCA9IG5ldHNubXBfcmVnaXN0ZXJfbG9naGFuZGxlcihORVRTTk1QX0xPR0hBTkRMRVJfU1lTTE9HLCBwcmlvcml0eSk7CiAgICAgICAgaWYgKGxvZ2gpIHsKICAgICAgICAgICAgaW50IGZhY2lsaXR5ID0gZGVjb2RlX2ZhY2lsaXR5KG9wdGFyZyk7CiAgICAgICAgICAgIGlmIChmYWNpbGl0eSA9PSAtMSkgIHJldHVybiAtMTsKICAgICAgICAgICAgbG9naC0+cHJpX21heCA9IHByaV9tYXg7CiAgICAgICAgICAgIGxvZ2gtPnRva2VuICAgPSBzdHJkdXAoc25tcF9sb2dfc3lzbG9nbmFtZShOVUxMKSk7CiAgICAgICAgICAgIGxvZ2gtPm1hZ2ljICAgPSAodm9pZCAqKShpbnRwdHJfdClmYWNpbGl0eTsKCSAgICBzbm1wX2VuYWJsZV9zeXNsb2dfaWRlbnQoc25tcF9sb2dfc3lzbG9nbmFtZShOVUxMKSwgZmFjaWxpdHkpOwoJfQogICAgICAgIGJyZWFrOwoKICAgIC8qCiAgICAgKiBEb24ndCBsb2cgCiAgICAgKi8KICAgIGNhc2UgJ04nOgogICAgICAgIHByaW9yaXR5ID0gZGVjb2RlX3ByaW9yaXR5KCAmb3B0YXJnLCAmcHJpX21heCApOwogICAgICAgIGlmIChwcmlvcml0eSA9PSAtMSkgIHJldHVybiAtMTsKICAgICAgICBpZiAoaW5jX29wdGluZCkKICAgICAgICAgICAgb3B0aW5kKys7CiAgICAgICAgLyogRmFsbHRocm91Z2ggKi8KICAgIGNhc2UgJ24nOgogICAgICAgIC8qCiAgICAgICAgICogZGlzYWJsZSBhbGwgbG9ncyB0byBjbGVhbiB0aGVtIHVwIChjbG9zZSBmaWxlcywgZXRjKSwKICAgICAgICAgKiByZW1vdmUgYWxsIGxvZyBoYW5kbGVycywgdGhlbiByZWdpc3RlciBhIG51bGwgaGFuZGxlci4KICAgICAgICAgKi8KICAgICAgICBzbm1wX2Rpc2FibGVfbG9nKCk7CiAgICAgICAgd2hpbGUoTlVMTCAhPSBsb2doX2hlYWQpCiAgICAgICAgICAgIG5ldHNubXBfcmVtb3ZlX2xvZ2hhbmRsZXIoIGxvZ2hfaGVhZCApOwogICAgICAgIGxvZ2ggPSBuZXRzbm1wX3JlZ2lzdGVyX2xvZ2hhbmRsZXIoTkVUU05NUF9MT0dIQU5ETEVSX05PTkUsIHByaW9yaXR5KTsKICAgICAgICBpZiAobG9naCkgewogICAgICAgICAgICBsb2doLT5wcmlfbWF4ID0gcHJpX21heDsKCX0KICAgICAgICBicmVhazsKCiAgICBkZWZhdWx0OgogICAgICAgIGZwcmludGYoc3RkZXJyLCAiVW5rbm93biBsb2dnaW5nIG9wdGlvbiBwYXNzZWQgdG8gLUw6ICVjLlxuIiwgKmNwKTsKICAgICAgICByZXR1cm4gLTE7CiAgICB9CiAgICByZXR1cm4gMDsKfQoKY2hhciAqCnNubXBfbG9nX3N5c2xvZ25hbWUoY29uc3QgY2hhciAqcHN0cikKewogIGlmIChwc3RyKQogICAgc3RybGNweSAoc3lzbG9nbmFtZSwgcHN0ciwgc2l6ZW9mKHN5c2xvZ25hbWUpKTsKCiAgcmV0dXJuIHN5c2xvZ25hbWU7Cn0KCnZvaWQKc25tcF9sb2dfb3B0aW9uc191c2FnZShjb25zdCBjaGFyICpsZWFkLCBGSUxFICogb3V0ZikKewogICAgY29uc3QgY2hhciAqcHJpMV9tc2cgPSAiIGZvciBsZXZlbCAncHJpJyBhbmQgYWJvdmUiOwogICAgY29uc3QgY2hhciAqcHJpMl9tc2cgPSAiIGZvciBsZXZlbHMgJ3AxJyB0byAncDInIjsKICAgIGZwcmludGYob3V0ZiwgIiVzZTogICAgICAgICAgIGxvZyB0byBzdGFuZGFyZCBlcnJvclxuIiwgbGVhZCk7CiAgICBmcHJpbnRmKG91dGYsICIlc286ICAgICAgICAgICBsb2cgdG8gc3RhbmRhcmQgb3V0cHV0XG4iLCBsZWFkKTsKICAgIGZwcmludGYob3V0ZiwgIiVzbjogICAgICAgICAgIGRvbid0IGxvZyBhdCBhbGxcbiIsIGxlYWQpOwogICAgZnByaW50ZihvdXRmLCAiJXNmIGZpbGU6ICAgICAgbG9nIHRvIHRoZSBzcGVjaWZpZWQgZmlsZVxuIiwgbGVhZCk7CiAgICBmcHJpbnRmKG91dGYsICIlc3MgZmFjaWxpdHk6ICBsb2cgdG8gc3lzbG9nICh2aWEgdGhlIHNwZWNpZmllZCBmYWNpbGl0eSlcbiIsIGxlYWQpOwogICAgZnByaW50ZihvdXRmLCAiXG4lcyh2YXJpYW50cylcbiIsIGxlYWQpOwogICAgZnByaW50ZihvdXRmLCAiJXNbRU9OXSBwcmk6ICAgbG9nIHRvIHN0YW5kYXJkIGVycm9yLCBvdXRwdXQgb3IgL2Rldi9udWxsJXNcbiIsIGxlYWQsIHByaTFfbXNnKTsKICAgIGZwcmludGYob3V0ZiwgIiVzW0VPTl0gcDEtcDI6IGxvZyB0byBzdGFuZGFyZCBlcnJvciwgb3V0cHV0IG9yIC9kZXYvbnVsbCVzXG4iLCBsZWFkLCBwcmkyX21zZyk7CiAgICBmcHJpbnRmKG91dGYsICIlc1tGU10gcHJpIHRva2VuOiAgICBsb2cgdG8gZmlsZS9zeXNsb2clc1xuIiwgbGVhZCwgcHJpMV9tc2cpOwogICAgZnByaW50ZihvdXRmLCAiJXNbRlNdIHAxLXAyIHRva2VuOiAgbG9nIHRvIGZpbGUvc3lzbG9nJXNcbiIsIGxlYWQsIHByaTJfbXNnKTsKfQoKLyoqCiAqIElzIGxvZ2dpbmcgZG9uZT8KICoKICogQHJldHVybiBSZXR1cm5zIDAgaWYgbG9nZ2luZyBpcyBvZmYsIDEgd2hlbiBpdCBpcyBkb25lLgogKgogKi8KaW50CnNubXBfZ2V0X2RvX2xvZ2dpbmcodm9pZCkKewogICAgcmV0dXJuIChsb2doX2VuYWJsZWQgPiAwKTsKfQoKCnN0YXRpYyBjaGFyICAgICoKc3ByaW50Zl9zdGFtcCh0aW1lX3QgKiBub3csIGNoYXIgKnNidWYpCnsKICAgIHRpbWVfdCAgICAgICAgICBOb3c7CiAgICBzdHJ1Y3QgdG0gICAgICAqdG07CgogICAgaWYgKG5vdyA9PSBOVUxMKSB7CiAgICAgICAgbm93ID0gJk5vdzsKICAgICAgICB0aW1lKG5vdyk7CiAgICB9CiAgICB0bSA9IGxvY2FsdGltZShub3cpOwogICAgc3ByaW50ZihzYnVmLCAiJS40ZC0lLjJkLSUuMmQgJS4yZDolLjJkOiUuMmQgIiwKICAgICAgICAgICAgdG0tPnRtX3llYXIgKyAxOTAwLCB0bS0+dG1fbW9uICsgMSwgdG0tPnRtX21kYXksCiAgICAgICAgICAgIHRtLT50bV9ob3VyLCB0bS0+dG1fbWluLCB0bS0+dG1fc2VjKTsKICAgIHJldHVybiBzYnVmOwp9Cgp2b2lkCnNubXBfZGlzYWJsZV9zeXNsb2dfZW50cnkobmV0c25tcF9sb2dfaGFuZGxlciAqbG9naCkKewogICAgaWYgKCFsb2doIHx8ICFsb2doLT5lbmFibGVkIHx8IGxvZ2gtPnR5cGUgIT0gTkVUU05NUF9MT0dIQU5ETEVSX1NZU0xPRykKICAgICAgICByZXR1cm47CgojaWZkZWYgV0lOMzIKICAgIGlmIChsb2doLT5tYWdpYykgewogICAgICAgIEhBTkRMRSBldmVudGxvZ19oID0gKEhBTkRMRSlsb2doLT5tYWdpYzsKICAgICAgICBDbG9zZUV2ZW50TG9nKGV2ZW50bG9nX2gpOwogICAgICAgIGxvZ2gtPm1hZ2ljID0gTlVMTDsKICAgIH0KI2Vsc2UKICAgIGNsb3NlbG9nKCk7CiAgICBsb2doLT5pbWFnaWMgID0gMDsKI2VuZGlmCgogICAgbmV0c25tcF9kaXNhYmxlX3RoaXNfbG9naGFuZGxlcihsb2doKTsKfQoKdm9pZApzbm1wX2Rpc2FibGVfc3lzbG9nKHZvaWQpCnsKICAgIG5ldHNubXBfbG9nX2hhbmRsZXIgKmxvZ2g7CgogICAgZm9yIChsb2doID0gbG9naF9oZWFkOyBsb2doOyBsb2doID0gbG9naC0+bmV4dCkKICAgICAgICBpZiAobG9naC0+ZW5hYmxlZCAmJiBsb2doLT50eXBlID09IE5FVFNOTVBfTE9HSEFORExFUl9TWVNMT0cpCiAgICAgICAgICAgIHNubXBfZGlzYWJsZV9zeXNsb2dfZW50cnkobG9naCk7Cn0KCnZvaWQKc25tcF9kaXNhYmxlX2ZpbGVsb2dfZW50cnkobmV0c25tcF9sb2dfaGFuZGxlciAqbG9naCkKewogICAgaWYgKCFsb2doIC8qIHx8ICFsb2doLT5lbmFibGVkICovIHx8IGxvZ2gtPnR5cGUgIT0gTkVUU05NUF9MT0dIQU5ETEVSX0ZJTEUpCiAgICAgICAgcmV0dXJuOwoKICAgIGlmIChsb2doLT5tYWdpYykgewogICAgICAgIGZwdXRzKCJcbiIsIChGSUxFKilsb2doLT5tYWdpYyk7CS8qIFhYWCAtIHdoeT8gKi8KICAgICAgICBmY2xvc2UoKEZJTEUqKWxvZ2gtPm1hZ2ljKTsKICAgICAgICBsb2doLT5tYWdpYyAgID0gTlVMTDsKICAgIH0KICAgIG5ldHNubXBfZGlzYWJsZV90aGlzX2xvZ2hhbmRsZXIobG9naCk7Cn0KCnZvaWQKc25tcF9kaXNhYmxlX2ZpbGVsb2codm9pZCkKewogICAgbmV0c25tcF9sb2dfaGFuZGxlciAqbG9naDsKCiAgICBmb3IgKGxvZ2ggPSBsb2doX2hlYWQ7IGxvZ2g7IGxvZ2ggPSBsb2doLT5uZXh0KQogICAgICAgIGlmIChsb2doLT5lbmFibGVkICYmIGxvZ2gtPnR5cGUgPT0gTkVUU05NUF9MT0dIQU5ETEVSX0ZJTEUpCiAgICAgICAgICAgIHNubXBfZGlzYWJsZV9maWxlbG9nX2VudHJ5KGxvZ2gpOwp9CgovKgogKiByZXR1cm5zIHRoYXQgc3RhdHVzIG9mIHN0ZGVyciBsb2dnaW5nCiAqCiAqIEByZXR2YWwgMCA6IHN0ZGVyciBsb2dnaW5nIGRpc2FibGVkCiAqIEByZXR2YWwgMSA6IHN0ZGVyciBsb2dnaW5nIGVuYWJsZWQKICovCmludApzbm1wX3N0ZGVycmxvZ19zdGF0dXModm9pZCkKewogICAgbmV0c25tcF9sb2dfaGFuZGxlciAqbG9naDsKCiAgICBmb3IgKGxvZ2ggPSBsb2doX2hlYWQ7IGxvZ2g7IGxvZ2ggPSBsb2doLT5uZXh0KQogICAgICAgIGlmIChsb2doLT5lbmFibGVkICYmIChsb2doLT50eXBlID09IE5FVFNOTVBfTE9HSEFORExFUl9TVERPVVQgfHwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9naC0+dHlwZSA9PSBORVRTTk1QX0xPR0hBTkRMRVJfU1RERVJSKSkgewogICAgICAgICAgICByZXR1cm4gMTsKICAgICAgIH0KCiAgICByZXR1cm4gMDsKfQoKdm9pZApzbm1wX2Rpc2FibGVfc3RkZXJybG9nKHZvaWQpCnsKICAgIG5ldHNubXBfbG9nX2hhbmRsZXIgKmxvZ2g7CgogICAgZm9yIChsb2doID0gbG9naF9oZWFkOyBsb2doOyBsb2doID0gbG9naC0+bmV4dCkKICAgICAgICBpZiAobG9naC0+ZW5hYmxlZCAmJiAobG9naC0+dHlwZSA9PSBORVRTTk1QX0xPR0hBTkRMRVJfU1RET1VUIHx8CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvZ2gtPnR5cGUgPT0gTkVUU05NUF9MT0dIQU5ETEVSX1NUREVSUikpIHsKICAgICAgICAgICAgbmV0c25tcF9kaXNhYmxlX3RoaXNfbG9naGFuZGxlcihsb2doKTsKCX0KfQoKdm9pZApzbm1wX2Rpc2FibGVfY2FsbGxvZyh2b2lkKQp7CiAgICBuZXRzbm1wX2xvZ19oYW5kbGVyICpsb2doOwoKICAgIGZvciAobG9naCA9IGxvZ2hfaGVhZDsgbG9naDsgbG9naCA9IGxvZ2gtPm5leHQpCiAgICAgICAgaWYgKGxvZ2gtPmVuYWJsZWQgJiYgbG9naC0+dHlwZSA9PSBORVRTTk1QX0xPR0hBTkRMRVJfQ0FMTEJBQ0spIHsKICAgICAgICAgICAgbmV0c25tcF9kaXNhYmxlX3RoaXNfbG9naGFuZGxlcihsb2doKTsKCX0KfQoKdm9pZApzbm1wX2Rpc2FibGVfbG9nKHZvaWQpCnsKICAgIG5ldHNubXBfbG9nX2hhbmRsZXIgKmxvZ2g7CgogICAgZm9yIChsb2doID0gbG9naF9oZWFkOyBsb2doOyBsb2doID0gbG9naC0+bmV4dCkgewogICAgICAgIGlmIChsb2doLT50eXBlID09IE5FVFNOTVBfTE9HSEFORExFUl9TWVNMT0cpCiAgICAgICAgICAgIHNubXBfZGlzYWJsZV9zeXNsb2dfZW50cnkobG9naCk7CiAgICAgICAgaWYgKGxvZ2gtPnR5cGUgPT0gTkVUU05NUF9MT0dIQU5ETEVSX0ZJTEUpCiAgICAgICAgICAgIHNubXBfZGlzYWJsZV9maWxlbG9nX2VudHJ5KGxvZ2gpOwogICAgICAgIG5ldHNubXBfZGlzYWJsZV90aGlzX2xvZ2hhbmRsZXIobG9naCk7CiAgICB9Cn0KCi8qCiAqIGNsb3NlIGFuZCByZW9wZW4gYWxsIGZpbGUgYmFzZWQgbG9ncywgdG8gYWxsb3cgbG9nZmlsZQogKiByb3RhdGlvbi4KICovCnZvaWQKbmV0c25tcF9sb2dnaW5nX3Jlc3RhcnQodm9pZCkKewogICAgbmV0c25tcF9sb2dfaGFuZGxlciAqbG9naDsKCiAgICBmb3IgKGxvZ2ggPSBsb2doX2hlYWQ7IGxvZ2g7IGxvZ2ggPSBsb2doLT5uZXh0KSB7CiAgICAgICAgaWYgKDAgPT0gbG9naC0+ZW5hYmxlZCkKICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgaWYgKGxvZ2gtPnR5cGUgPT0gTkVUU05NUF9MT0dIQU5ETEVSX1NZU0xPRykgewogICAgICAgICAgICBzbm1wX2Rpc2FibGVfc3lzbG9nX2VudHJ5KGxvZ2gpOwogICAgICAgICAgICBzbm1wX2VuYWJsZV9zeXNsb2dfaWRlbnQobG9naC0+dG9rZW4sKGludCkoaW50cHRyX3QpbG9naC0+bWFnaWMpOwogICAgICAgIH0KICAgICAgICBlbHNlIGlmIChsb2doLT50eXBlID09IE5FVFNOTVBfTE9HSEFORExFUl9GSUxFKSB7CiAgICAgICAgICAgIHNubXBfZGlzYWJsZV9maWxlbG9nX2VudHJ5KGxvZ2gpOwogICAgICAgICAgICAvKiogaG1tLCBkb24ndCB6ZXJvIHN0YXR1cyBpc24ndCBzYXZlZC4uIGkgdGhpbmsgaXQncwogICAgICAgICAgICAgKiBzYWZlciBub3QgdG8gb3ZlcndyaXRlLCBpbiBjYXNlIGEgaHVwIGlzIGp1c3QgdG8KICAgICAgICAgICAgICogcmUtcmVhZCBjb25maWcgZmlsZXMuLi4KICAgICAgICAgICAgICovCiAgICAgICAgICAgIG5ldHNubXBfZW5hYmxlX2ZpbGVsb2cobG9naCwgMSk7CiAgICAgICAgfQogICAgfQp9CgovKiA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSAqLwoKdm9pZApzbm1wX2VuYWJsZV9zeXNsb2codm9pZCkKewogICAgc25tcF9lbmFibGVfc3lzbG9nX2lkZW50KHNubXBfbG9nX3N5c2xvZ25hbWUoTlVMTCksIExPR19EQUVNT04pOwp9Cgp2b2lkCnNubXBfZW5hYmxlX3N5c2xvZ19pZGVudChjb25zdCBjaGFyICppZGVudCwgY29uc3QgaW50IGZhY2lsaXR5KQp7CiAgICBuZXRzbm1wX2xvZ19oYW5kbGVyICpsb2doOwogICAgaW50ICAgICAgICAgICAgICAgICAgZm91bmQgPSAwOwogICAgaW50ICAgICAgICAgICAgICAgICAgZW5hYmxlID0gMTsKI2lmZGVmIFdJTjMyCiAgICBIQU5ETEUgICAgICAgICAgICAgICBldmVudGxvZ19oOwojZWxzZQogICAgdm9pZCAgICAgICAgICAgICAgICAqZXZlbnRsb2dfaCA9IE5VTEw7CiNlbmRpZgoKICAgIHNubXBfZGlzYWJsZV9zeXNsb2coKTsJLyogPz8/ICovCiNpZmRlZiBXSU4zMgogICAgZXZlbnRsb2dfaCA9IE9wZW5FdmVudExvZyhOVUxMLCBpZGVudCk7CiAgICBpZiAoZXZlbnRsb2dfaCA9PSBOVUxMKSB7CgkgICAgLyoKCSAgICAgKiBIbW1tLi4uLi4KCSAgICAgKiBNYXliZSBkaXNhYmxlIHRoaXMgaGFuZGxlciwgYW5kIGxvZyB0aGUgZXJyb3IgPwoJICAgICAqLwogICAgICAgIGZwcmludGYoc3RkZXJyLCAiQ291bGQgbm90IG9wZW4gZXZlbnQgbG9nIGZvciAlcy4gIgogICAgICAgICAgICAgICAgIkxhc3QgZXJyb3I6IDB4JXhcbiIsIGlkZW50LCBHZXRMYXN0RXJyb3IoKSk7CiAgICAgICAgZW5hYmxlID0gMDsKICAgIH0KI2Vsc2UKICAgIG9wZW5sb2coc25tcF9sb2dfc3lzbG9nbmFtZShpZGVudCksIExPR19DT05TIHwgTE9HX1BJRCwgZmFjaWxpdHkpOwojZW5kaWYKCiAgICBmb3IgKGxvZ2ggPSBsb2doX2hlYWQ7IGxvZ2g7IGxvZ2ggPSBsb2doLT5uZXh0KQogICAgICAgIGlmIChsb2doLT50eXBlID09IE5FVFNOTVBfTE9HSEFORExFUl9TWVNMT0cpIHsKICAgICAgICAgICAgbG9naC0+bWFnaWMgICA9ICh2b2lkKilldmVudGxvZ19oOwogICAgICAgICAgICBsb2doLT5pbWFnaWMgID0gZW5hYmxlOwkvKiBzeXNsb2cgb3BlbiAqLwogICAgICAgICAgICBpZiAobG9naC0+ZW5hYmxlZCAmJiAoMCA9PSBlbmFibGUpKQogICAgICAgICAgICAgICAgbmV0c25tcF9kaXNhYmxlX3RoaXNfbG9naGFuZGxlcihsb2doKTsKICAgICAgICAgICAgZWxzZSBpZiAoKDAgPT0gbG9naC0+ZW5hYmxlZCkgJiYgZW5hYmxlKQogICAgICAgICAgICAgICAgbmV0c25tcF9lbmFibGVfdGhpc19sb2doYW5kbGVyKGxvZ2gpOwogICAgICAgICAgICBmb3VuZCAgICAgICAgID0gMTsKCX0KCiAgICBpZiAoIWZvdW5kKSB7CiAgICAgICAgbG9naCA9IG5ldHNubXBfcmVnaXN0ZXJfbG9naGFuZGxlcihORVRTTk1QX0xPR0hBTkRMRVJfU1lTTE9HLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTE9HX0RFQlVHICk7CiAgICAgICAgaWYgKGxvZ2gpIHsKICAgICAgICAgICAgbG9naC0+bWFnaWMgICAgPSAodm9pZCopZXZlbnRsb2dfaDsKICAgICAgICAgICAgbG9naC0+dG9rZW4gICAgPSBzdHJkdXAoaWRlbnQpOwogICAgICAgICAgICBsb2doLT5pbWFnaWMgICA9IGVuYWJsZTsJLyogc3lzbG9nIG9wZW4gKi8KICAgICAgICAgICAgaWYgKGxvZ2gtPmVuYWJsZWQgJiYgKDAgPT0gZW5hYmxlKSkKICAgICAgICAgICAgICAgIG5ldHNubXBfZGlzYWJsZV90aGlzX2xvZ2hhbmRsZXIobG9naCk7CiAgICAgICAgICAgIGVsc2UgaWYgKCgwID09IGxvZ2gtPmVuYWJsZWQpICYmIGVuYWJsZSkKICAgICAgICAgICAgICAgIG5ldHNubXBfZW5hYmxlX3RoaXNfbG9naGFuZGxlcihsb2doKTsKICAgICAgICB9CiAgICB9Cn0KCnZvaWQKbmV0c25tcF9lbmFibGVfZmlsZWxvZyhuZXRzbm1wX2xvZ19oYW5kbGVyICpsb2doLCBpbnQgZG9udF96ZXJvX2xvZykKewogICAgRklMRSAqbG9nZmlsZTsKCiAgICBpZiAoIWxvZ2gpCiAgICAgICAgcmV0dXJuOwoKICAgIGlmICghbG9naC0+bWFnaWMpIHsKICAgICAgICBsb2dmaWxlID0gZm9wZW4obG9naC0+dG9rZW4sIGRvbnRfemVyb19sb2cgPyAiYSIgOiAidyIpOwogICAgICAgIGlmICghbG9nZmlsZSkgewoJICAgIHNubXBfbG9nX3BlcnJvcihsb2doLT50b2tlbik7CiAgICAgICAgICAgIHJldHVybjsKCX0KICAgICAgICBsb2doLT5tYWdpYyA9ICh2b2lkKilsb2dmaWxlOwogICAgICAgIG5ldHNubXBfc2V0X2xpbmVfYnVmZmVyaW5nKGxvZ2ZpbGUpOwogICAgfQogICAgbmV0c25tcF9lbmFibGVfdGhpc19sb2doYW5kbGVyKGxvZ2gpOwp9Cgp2b2lkCnNubXBfZW5hYmxlX2ZpbGVsb2coY29uc3QgY2hhciAqbG9nZmlsZW5hbWUsIGludCBkb250X3plcm9fbG9nKQp7CiAgICBuZXRzbm1wX2xvZ19oYW5kbGVyICpsb2doOwoKICAgIC8qCiAgICAgKiBkb24ndCBkaXNhYmxlIEFMTCBmaWxlbG9ncyB3aGVuZXZlciBhIG5ldyBvbmUgaXMgZW5hYmxlZC4KICAgICAqIHRoaXMgcHJldmVudHMgJy1MZiBmaWxlJyBmcm9tIHdvcmtpbmcgaW4gc25tcGQsIGFzIHRoZQogICAgICogY2FsbCB0byBzZXQgdXAgL3Zhci9sb2cvc25tcGQubG9nIHdpbGwgZGlzYWJsZSB0aGUgcHJldmlvdXMKICAgICAqIGxvZyBzZXR1cC4KICAgICAqIHNubXBfZGlzYWJsZV9maWxlbG9nKCk7CiAgICAgKi8KCiAgICBpZiAobG9nZmlsZW5hbWUpIHsKICAgICAgICBsb2doID0gbmV0c25tcF9maW5kX2xvZ2hhbmRsZXIoIGxvZ2ZpbGVuYW1lICk7CiAgICAgICAgaWYgKCFsb2doKSB7CiAgICAgICAgICAgIGxvZ2ggPSBuZXRzbm1wX3JlZ2lzdGVyX2xvZ2hhbmRsZXIoTkVUU05NUF9MT0dIQU5ETEVSX0ZJTEUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTE9HX0RFQlVHICk7CiAgICAgICAgICAgIGlmIChsb2doKQogICAgICAgICAgICAgICAgbG9naC0+dG9rZW4gPSBzdHJkdXAobG9nZmlsZW5hbWUpOwoJfQogICAgICAgIGlmIChsb2doKQogICAgICAgICAgICBuZXRzbm1wX2VuYWJsZV9maWxlbG9nKGxvZ2gsIGRvbnRfemVyb19sb2cpOwogICAgfSBlbHNlIHsKICAgICAgICBmb3IgKGxvZ2ggPSBsb2doX2hlYWQ7IGxvZ2g7IGxvZ2ggPSBsb2doLT5uZXh0KQogICAgICAgICAgICBpZiAobG9naC0+dHlwZSA9PSBORVRTTk1QX0xPR0hBTkRMRVJfRklMRSkKICAgICAgICAgICAgICAgIG5ldHNubXBfZW5hYmxlX2ZpbGVsb2cobG9naCwgZG9udF96ZXJvX2xvZyk7CiAgICB9Cn0KCgp2b2lkCnNubXBfZW5hYmxlX3N0ZGVycmxvZyh2b2lkKQp7CiAgICBuZXRzbm1wX2xvZ19oYW5kbGVyICpsb2doOwogICAgaW50ICAgICAgICAgICAgICAgICAgZm91bmQgPSAwOwoKICAgIGZvciAobG9naCA9IGxvZ2hfaGVhZDsgbG9naDsgbG9naCA9IGxvZ2gtPm5leHQpCiAgICAgICAgaWYgKGxvZ2gtPnR5cGUgPT0gTkVUU05NUF9MT0dIQU5ETEVSX1NURE9VVCB8fAogICAgICAgICAgICBsb2doLT50eXBlID09IE5FVFNOTVBfTE9HSEFORExFUl9TVERFUlIpIHsKICAgICAgICAgICAgbmV0c25tcF9lbmFibGVfdGhpc19sb2doYW5kbGVyKGxvZ2gpOwogICAgICAgICAgICBmb3VuZCAgICAgICAgID0gMTsKICAgICAgICB9CgogICAgaWYgKCFmb3VuZCkgewogICAgICAgIGxvZ2ggPSBuZXRzbm1wX3JlZ2lzdGVyX2xvZ2hhbmRsZXIoTkVUU05NUF9MT0dIQU5ETEVSX1NUREVSUiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExPR19ERUJVRyApOwogICAgICAgIGlmIChsb2doKQogICAgICAgICAgICBsb2doLT50b2tlbiAgICA9IHN0cmR1cCgic3RkZXJyIik7CiAgICB9Cn0KCgp2b2lkCnNubXBfZW5hYmxlX2NhbGxsb2codm9pZCkJLyogWFhYIC0gb3IgdGFrZSBhIGNhbGxiYWNrIHJvdXRpbmUgPz8/ICovCnsKICAgIG5ldHNubXBfbG9nX2hhbmRsZXIgKmxvZ2g7CiAgICBpbnQgICAgICAgICAgICAgICAgICBmb3VuZCA9IDA7CgogICAgZm9yIChsb2doID0gbG9naF9oZWFkOyBsb2doOyBsb2doID0gbG9naC0+bmV4dCkKICAgICAgICBpZiAobG9naC0+dHlwZSA9PSBORVRTTk1QX0xPR0hBTkRMRVJfQ0FMTEJBQ0spIHsKICAgICAgICAgICAgbmV0c25tcF9lbmFibGVfdGhpc19sb2doYW5kbGVyKGxvZ2gpOwogICAgICAgICAgICBmb3VuZCAgICAgICAgID0gMTsKCX0KCiAgICBpZiAoIWZvdW5kKSB7CiAgICAgICAgbG9naCA9IG5ldHNubXBfcmVnaXN0ZXJfbG9naGFuZGxlcihORVRTTk1QX0xPR0hBTkRMRVJfQ0FMTEJBQ0ssCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBMT0dfREVCVUcgKTsKICAgICAgICBpZiAobG9naCkKICAgICAgICAgICAgbG9naC0+dG9rZW4gICAgPSBzdHJkdXAoImNhbGxiYWNrIik7CiAgICB9Cn0KCgoKLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSAqLwoKCm5ldHNubXBfbG9nX2hhbmRsZXIgKgpuZXRzbm1wX2ZpbmRfbG9naGFuZGxlciggY29uc3QgY2hhciAqdG9rZW4gKQp7CiAgICBuZXRzbm1wX2xvZ19oYW5kbGVyICpsb2doOwogICAgaWYgKCF0b2tlbikKICAgICAgICByZXR1cm4gTlVMTDsKCiAgICBmb3IgKGxvZ2ggPSBsb2doX2hlYWQ7IGxvZ2g7IGxvZ2ggPSBsb2doLT5uZXh0KQogICAgICAgIGlmIChsb2doLT50b2tlbiAmJiAhc3RyY21wKCB0b2tlbiwgbG9naC0+dG9rZW4gKSkKICAgICAgICAgICAgYnJlYWs7CgogICAgcmV0dXJuIGxvZ2g7Cn0KCmludApuZXRzbm1wX2FkZF9sb2doYW5kbGVyKCBuZXRzbm1wX2xvZ19oYW5kbGVyICpsb2doICkKewogICAgaW50IGk7CiAgICBuZXRzbm1wX2xvZ19oYW5kbGVyICpsb2doMjsKCiAgICBpZiAoIWxvZ2gpCiAgICAgICAgcmV0dXJuIDA7CgogICAgLyoKICAgICAqIEZpbmQgdGhlIGFwcHJvcHJpYXRlIHBvaW50IGZvciB0aGUgbmV3IGVudHJ5Li4uCiAgICAgKiAgIChsb2doMiB3aWxsIHBvaW50IHRvIHRoZSBlbnRyeSBpbW1lZGlhdGVseSBmb2xsb3dpbmcpCiAgICAgKi8KICAgIGZvciAobG9naDIgPSBsb2doX2hlYWQ7IGxvZ2gyOyBsb2doMiA9IGxvZ2gyLT5uZXh0KQogICAgICAgIGlmICggbG9naDItPnByaW9yaXR5ID49IGxvZ2gtPnByaW9yaXR5ICkKICAgICAgICAgICAgYnJlYWs7CgogICAgLyoKICAgICAqIC4uLiBhbmQgbGluayBpdCBpbnRvIHRoZSBtYWluIGxpc3QuCiAgICAgKi8KICAgIGlmIChsb2doMikgewogICAgICAgIGlmIChsb2doMi0+cHJldikKICAgICAgICAgICAgbG9naDItPnByZXYtPm5leHQgPSBsb2doOwogICAgICAgIGVsc2UKICAgICAgICAgICAgbG9naF9oZWFkID0gbG9naDsKICAgICAgICBsb2doLT5uZXh0ICA9IGxvZ2gyOwogICAgICAgIGxvZ2gyLT5wcmV2ID0gbG9naDsKICAgIH0gZWxzZSBpZiAobG9naF9oZWFkICkgewogICAgICAgIC8qCiAgICAgICAgICogSWYgbG9naDIgaXMgTlVMTCwgd2UncmUgdGFnZ2luZyBvbiB0byB0aGUgZW5kCiAgICAgICAgICovCiAgICAgICAgZm9yIChsb2doMiA9IGxvZ2hfaGVhZDsgbG9naDItPm5leHQ7IGxvZ2gyID0gbG9naDItPm5leHQpCiAgICAgICAgICAgIDsKICAgICAgICBsb2doMi0+bmV4dCA9IGxvZ2g7CiAgICB9IGVsc2UgewogICAgICAgIGxvZ2hfaGVhZCA9IGxvZ2g7CiAgICB9CgogICAgLyoKICAgICAqIEFsc28gdHdlYWsgdGhlIHJlbGV2YW50IHByaW9yaXR5LSdpbmRleCcgYXJyYXkuCiAgICAgKi8KICAgIGZvciAoaT1MT0dfRU1FUkc7IGk8PWxvZ2gtPnByaW9yaXR5OyBpKyspCiAgICAgICAgaWYgKCFsb2doX3ByaW9yaXRpZXNbaV0gfHwKICAgICAgICAgICAgIGxvZ2hfcHJpb3JpdGllc1tpXS0+cHJpb3JpdHkgPj0gbG9naC0+cHJpb3JpdHkpCiAgICAgICAgICAgICBsb2doX3ByaW9yaXRpZXNbaV0gPSBsb2doOwoKICAgIHJldHVybiAxOwp9CgpuZXRzbm1wX2xvZ19oYW5kbGVyICoKbmV0c25tcF9yZWdpc3Rlcl9sb2doYW5kbGVyKCBpbnQgdHlwZSwgaW50IHByaW9yaXR5ICkKewogICAgbmV0c25tcF9sb2dfaGFuZGxlciAqbG9naDsKCiAgICBsb2doID0gU05NUF9NQUxMT0NfVFlQRURFRihuZXRzbm1wX2xvZ19oYW5kbGVyKTsKICAgIGlmICghbG9naCkKICAgICAgICByZXR1cm4gTlVMTDsKCiAgICBERUJVR01TR1QoKCJsb2dnaW5nOnJlZ2lzdGVyIiwgInJlZ2lzdGVyaW5nIGxvZyB0eXBlICVkIHdpdGggcHJpICVkXG4iLAogICAgICAgICAgICAgICB0eXBlLCBwcmlvcml0eSkpOwoKICAgIGxvZ2gtPnR5cGUgICAgID0gdHlwZTsKICAgIHN3aXRjaCAoIHR5cGUgKSB7CiAgICBjYXNlIE5FVFNOTVBfTE9HSEFORExFUl9TVERPVVQ6CiAgICAgICAgbG9naC0+aW1hZ2ljICA9IDE7CiAgICAgICAgLyogZmFsbHRocm91Z2ggKi8KICAgIGNhc2UgTkVUU05NUF9MT0dIQU5ETEVSX1NUREVSUjoKICAgICAgICBsb2doLT5oYW5kbGVyID0gbG9nX2hhbmRsZXJfc3Rkb3V0ZXJyOwogICAgICAgIGJyZWFrOwoKICAgIGNhc2UgTkVUU05NUF9MT0dIQU5ETEVSX0ZJTEU6CiAgICAgICAgbG9naC0+aGFuZGxlciA9IGxvZ19oYW5kbGVyX2ZpbGU7CiAgICAgICAgbG9naC0+aW1hZ2ljICA9IDE7CiAgICAgICAgYnJlYWs7CiAgICBjYXNlIE5FVFNOTVBfTE9HSEFORExFUl9TWVNMT0c6CiAgICAgICAgbG9naC0+aGFuZGxlciA9IGxvZ19oYW5kbGVyX3N5c2xvZzsKICAgICAgICBicmVhazsKICAgIGNhc2UgTkVUU05NUF9MT0dIQU5ETEVSX0NBTExCQUNLOgogICAgICAgIGxvZ2gtPmhhbmRsZXIgPSBsb2dfaGFuZGxlcl9jYWxsYmFjazsKICAgICAgICBicmVhazsKICAgIGNhc2UgTkVUU05NUF9MT0dIQU5ETEVSX05PTkU6CiAgICAgICAgbG9naC0+aGFuZGxlciA9IGxvZ19oYW5kbGVyX251bGw7CiAgICAgICAgYnJlYWs7CiAgICBkZWZhdWx0OgogICAgICAgIGZyZWUobG9naCk7CiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICB9CiAgICBsb2doLT5wcmlvcml0eSA9IHByaW9yaXR5OwogICAgbmV0c25tcF9lbmFibGVfdGhpc19sb2doYW5kbGVyKGxvZ2gpOwogICAgbmV0c25tcF9hZGRfbG9naGFuZGxlciggbG9naCApOwogICAgcmV0dXJuIGxvZ2g7Cn0KCgppbnQKbmV0c25tcF9lbmFibGVfbG9naGFuZGxlciggY29uc3QgY2hhciAqdG9rZW4gKQp7CiAgICBuZXRzbm1wX2xvZ19oYW5kbGVyICpsb2doOwoKICAgIGxvZ2ggPSBuZXRzbm1wX2ZpbmRfbG9naGFuZGxlciggdG9rZW4gKTsKICAgIGlmICghbG9naCkKICAgICAgICByZXR1cm4gMDsKICAgIG5ldHNubXBfZW5hYmxlX3RoaXNfbG9naGFuZGxlcihsb2doKTsKICAgIHJldHVybiAxOwp9CgoKaW50Cm5ldHNubXBfZGlzYWJsZV9sb2doYW5kbGVyKCBjb25zdCBjaGFyICp0b2tlbiApCnsKICAgIG5ldHNubXBfbG9nX2hhbmRsZXIgKmxvZ2g7CgogICAgbG9naCA9IG5ldHNubXBfZmluZF9sb2doYW5kbGVyKCB0b2tlbiApOwogICAgaWYgKCFsb2doKQogICAgICAgIHJldHVybiAwOwogICAgbmV0c25tcF9kaXNhYmxlX3RoaXNfbG9naGFuZGxlcihsb2doKTsKICAgIHJldHVybiAxOwp9CgppbnQKbmV0c25tcF9yZW1vdmVfbG9naGFuZGxlciggbmV0c25tcF9sb2dfaGFuZGxlciAqbG9naCApCnsKICAgIGludCBpOwogICAgaWYgKCFsb2doKQogICAgICAgIHJldHVybiAwOwoKICAgIGlmIChsb2doLT5wcmV2KQogICAgICAgIGxvZ2gtPnByZXYtPm5leHQgPSBsb2doLT5uZXh0OwogICAgZWxzZQogICAgICAgIGxvZ2hfaGVhZCA9IGxvZ2gtPm5leHQ7CgogICAgaWYgKGxvZ2gtPm5leHQpCiAgICAgICAgbG9naC0+bmV4dC0+cHJldiA9IGxvZ2gtPnByZXY7CgogICAgZm9yIChpPUxPR19FTUVSRzsgaTw9bG9naC0+cHJpb3JpdHk7IGkrKykKICAgICAgICBsb2doX3ByaW9yaXRpZXNbaV0gPSBOVUxMOwogICAgZnJlZShORVRTTk1QX1JFTU9WRV9DT05TVChjaGFyKiwgbG9naC0+dG9rZW4pKTsKICAgIFNOTVBfRlJFRShsb2doKTsKCiAgICByZXR1cm4gMTsKfQoKLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSAqLwoKaW50CmxvZ19oYW5kbGVyX3N0ZG91dGVyciggIG5ldHNubXBfbG9nX2hhbmRsZXIqIGxvZ2gsIGludCBwcmksIGNvbnN0IGNoYXIgKnN0cikKewogICAgc3RhdGljIGludCAgICAgIG5ld2xpbmUgPSAxOwkgLyogTVRDUklUSUNBTF9SRVNPVVJDRSAqLwogICAgY29uc3QgY2hhciAgICAgKm5ld2xpbmVfcHRyOwogICAgY2hhciAgICAgICAgICAgIHNidWZbNDBdOwoKICAgIGlmIChuZXRzbm1wX2RzX2dldF9ib29sZWFuKE5FVFNOTVBfRFNfTElCUkFSWV9JRCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBORVRTTk1QX0RTX0xJQl9MT0dfVElNRVNUQU1QKSAmJiBuZXdsaW5lKSB7CiAgICAgICAgc3ByaW50Zl9zdGFtcChOVUxMLCBzYnVmKTsKICAgIH0gZWxzZSB7CiAgICAgICAgc3RyY3B5KHNidWYsICIiKTsKICAgIH0KICAgIC8qCiAgICAgKiBSZW1lbWJlciB3aGV0aGVyIG9yIG5vdCB0aGUgY3VycmVudCBsaW5lIGVuZHMgd2l0aCBhIG5ld2xpbmUgZm9yIHRoZQogICAgICogbmV4dCBjYWxsIG9mIGxvZ19oYW5kbGVyX3N0ZG91dGVycigpLgogICAgICovCiAgICBuZXdsaW5lX3B0ciA9IHN0cnJjaHIoc3RyLCAnXG4nKTsKICAgIG5ld2xpbmUgPSBuZXdsaW5lX3B0ciAmJiBuZXdsaW5lX3B0clsxXSA9PSAwOwoKICAgIGlmIChsb2doLT5pbWFnaWMpCiAgICAgICBwcmludGYoICAgICAgICAgIiVzJXMiLCBzYnVmLCBzdHIpOwogICAgZWxzZQogICAgICAgZnByaW50ZihzdGRlcnIsICIlcyVzIiwgc2J1Ziwgc3RyKTsKCiAgICByZXR1cm4gMTsKfQoKCiNpZmRlZiBXSU4zMgppbnQKbG9nX2hhbmRsZXJfc3lzbG9nKCAgbmV0c25tcF9sb2dfaGFuZGxlciogbG9naCwgaW50IHByaSwgY29uc3QgY2hhciAqc3RyKQp7CiAgICBXT1JEICAgICAgICAgICAgZXR5cGU7CiAgICBMUENUU1RSICAgICAgICAgZXZlbnRfbXNnWzJdOwogICAgSEFORExFICAgICAgICAgIGV2ZW50bG9nX2ggPSBsb2doLT5tYWdpYzsKCiAgICAgICAgLyoKICAgICAgICAgKiogIEVWRU5UIFRZUEVTOgogICAgICAgICAqKgogICAgICAgICAqKiAgSW5mb3JtYXRpb24gKEVWRU5UTE9HX0lORk9STUFUSU9OX1RZUEUpCiAgICAgICAgICoqICAgICAgSW5mb3JtYXRpb24gZXZlbnRzIGluZGljYXRlIGluZnJlcXVlbnQgYnV0IHNpZ25pZmljYW50CiAgICAgICAgICoqICAgICAgc3VjY2Vzc2Z1bCBvcGVyYXRpb25zLgogICAgICAgICAqKiAgV2FybmluZyAoRVZFTlRMT0dfV0FSTklOR19UWVBFKQogICAgICAgICAqKiAgICAgIFdhcm5pbmcgZXZlbnRzIGluZGljYXRlIHByb2JsZW1zIHRoYXQgYXJlIG5vdCBpbW1lZGlhdGVseQogICAgICAgICAqKiAgICAgIHNpZ25pZmljYW50LCBidXQgdGhhdCBtYXkgaW5kaWNhdGUgY29uZGl0aW9ucyB0aGF0IGNvdWxkCiAgICAgICAgICoqICAgICAgY2F1c2UgZnV0dXJlIHByb2JsZW1zLiBSZXNvdXJjZSBjb25zdW1wdGlvbiBpcyBhIGdvb2QKICAgICAgICAgKiogICAgICBjYW5kaWRhdGUgZm9yIGEgd2FybmluZyBldmVudC4KICAgICAgICAgKiogIEVycm9yIChFVkVOVExPR19FUlJPUl9UWVBFKQogICAgICAgICAqKiAgICAgIEVycm9yIGV2ZW50cyBpbmRpY2F0ZSBzaWduaWZpY2FudCBwcm9ibGVtcyB0aGF0IHRoZSB1c2VyCiAgICAgICAgICoqICAgICAgc2hvdWxkIGtub3cgYWJvdXQuIEVycm9yIGV2ZW50cyB1c3VhbGx5IGluZGljYXRlIGEgbG9zcyBvZgogICAgICAgICAqKiAgICAgIGZ1bmN0aW9uYWxpdHkgb3IgZGF0YS4KICAgICAgICAgKi8KICAgIHN3aXRjaCAocHJpKSB7CiAgICAgICAgY2FzZSBMT0dfRU1FUkc6CiAgICAgICAgY2FzZSBMT0dfQUxFUlQ6CiAgICAgICAgY2FzZSBMT0dfQ1JJVDoKICAgICAgICBjYXNlIExPR19FUlI6CiAgICAgICAgICAgIGV0eXBlID0gRVZFTlRMT0dfRVJST1JfVFlQRTsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSBMT0dfV0FSTklORzoKICAgICAgICAgICAgZXR5cGUgPSBFVkVOVExPR19XQVJOSU5HX1RZUEU7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgTE9HX05PVElDRToKICAgICAgICBjYXNlIExPR19JTkZPOgogICAgICAgIGNhc2UgTE9HX0RFQlVHOgogICAgICAgICAgICBldHlwZSA9IEVWRU5UTE9HX0lORk9STUFUSU9OX1RZUEU7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIGV0eXBlID0gRVZFTlRMT0dfSU5GT1JNQVRJT05fVFlQRTsKICAgICAgICAgICAgYnJlYWs7CiAgICB9CiAgICBldmVudF9tc2dbMF0gPSBzdHI7CiAgICBldmVudF9tc2dbMV0gPSBOVUxMOwogICAgLyogTk9URTogNHRoIHBhcmFtZXRlciBtdXN0IG1hdGNoIHdpbnNlcnZpY2UubWM6TWVzc2FnZUlkIHZhbHVlICovCiAgICBpZiAoIVJlcG9ydEV2ZW50KGV2ZW50bG9nX2gsIGV0eXBlLCAwLCAxMDAsIE5VTEwsIDEsIDAsIGV2ZW50X21zZywgTlVMTCkpIHsKCSAgICAvKgoJICAgICAqIEhtbW0uLi4uLgoJICAgICAqIE1heWJlIGRpc2FibGUgdGhpcyBoYW5kbGVyLCBhbmQgbG9nIHRoZSBlcnJvciA/CgkgICAgICovCiAgICAgICAgZnByaW50ZihzdGRlcnIsICJDb3VsZCBub3QgcmVwb3J0IGV2ZW50LiAgTGFzdCBlcnJvcjogMHgleFxuIiwKCQkJR2V0TGFzdEVycm9yKCkpOwogICAgICAgIHJldHVybiAwOwogICAgfQogICAgcmV0dXJuIDE7Cn0KI2Vsc2UKaW50CmxvZ19oYW5kbGVyX3N5c2xvZyggIG5ldHNubXBfbG9nX2hhbmRsZXIqIGxvZ2gsIGludCBwcmksIGNvbnN0IGNoYXIgKnN0cikKewoJLyoKCSAqIFhYWAoJICogV2UndmUgZ290IHRocmVlIGl0ZW1zIG9mIGluZm9ybWF0aW9uIHRvIHdvcmsgd2l0aDoKCSAqICAgICBJcyB0aGUgc3lzbG9nIGN1cnJlbnRseSBvcGVuPwoJICogICAgIFdoYXQgaWRlbnQgc3RyaW5nIHRvIHVzZT8KCSAqICAgICBXaGF0IGZhY2lsaXR5IHRvIGxvZyB0bz8KCSAqCgkgKiBXZSd2ZSBnb3QgdHdvICJtYWdpYyIgbG9jYXRpb25zIChpbWFnaWMgJiBtYWdpYykgcGx1cyB0aGUgdG9rZW4KCSAqLwogICAgaWYgKCEobG9naC0+aW1hZ2ljKSkgewogICAgICAgIGNvbnN0IGNoYXIgKmlkZW50ICAgID0gbG9naC0+dG9rZW47CiAgICAgICAgaW50ICAgZmFjaWxpdHkgPSAoaW50KShpbnRwdHJfdClsb2doLT5tYWdpYzsKICAgICAgICBpZiAoIWlkZW50KQogICAgICAgICAgICBpZGVudCA9IG5ldHNubXBfZHNfZ2V0X3N0cmluZyhORVRTTk1QX0RTX0xJQlJBUllfSUQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5FVFNOTVBfRFNfTElCX0FQUFRZUEUpOwogICAgICAgIG9wZW5sb2coaWRlbnQsIExPR19DT05TIHwgTE9HX1BJRCwgZmFjaWxpdHkpOwogICAgICAgIGxvZ2gtPmltYWdpYyA9IDE7CiAgICB9CiAgICBzeXNsb2coIHByaSwgIiVzIiwgc3RyICk7CiAgICByZXR1cm4gMTsKfQojZW5kaWYgLyogIVdJTjMyICovCgoKaW50CmxvZ19oYW5kbGVyX2ZpbGUoICAgIG5ldHNubXBfbG9nX2hhbmRsZXIqIGxvZ2gsIGludCBwcmksIGNvbnN0IGNoYXIgKnN0cikKewogICAgRklMRSAgICAgICAgICAgKmZoYW5kbGU7CiAgICBjaGFyICAgICAgICAgICAgc2J1Zls0MF07CgogICAgLyoKICAgICAqIFdlIHVzZSBpbWFnaWMgdG8gc2F2ZSBpbmZvcm1hdGlvbiBhYm91dCB3aGV0aGVyIHRoZSBuZXh0IG91dHB1dAogICAgICogd2lsbCBzdGFydCBhIG5ldyBsaW5lLCBhbmQgdGh1cyBtaWdodCBuZWVkIGEgdGltZXN0YW1wCiAgICAgKi8KICAgIGlmIChuZXRzbm1wX2RzX2dldF9ib29sZWFuKE5FVFNOTVBfRFNfTElCUkFSWV9JRCwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBORVRTTk1QX0RTX0xJQl9MT0dfVElNRVNUQU1QKSAmJiBsb2doLT5pbWFnaWMpIHsKICAgICAgICBzcHJpbnRmX3N0YW1wKE5VTEwsIHNidWYpOwogICAgfSBlbHNlIHsKICAgICAgICBzdHJjcHkoc2J1ZiwgIiIpOwogICAgfQoKICAgIC8qCiAgICAgKiBJZiB3ZSBoYXZlbid0IGFscmVhZHkgb3BlbmVkIHRoZSBmaWxlLCB0aGVuIGRvIHNvLgogICAgICogU2F2ZSB0aGUgZmlsZWhhbmRsZSBwb2ludGVyIGZvciBuZXh0IHRpbWUuCiAgICAgKgogICAgICogTm90ZSB0aGF0IHRoaXMgc2hvdWxkIHN0aWxsIHdvcmssIGV2ZW4gaWYgdGhlIGZpbGUKICAgICAqIGlzIGNsb3NlZCBpbiB0aGUgbWVhbnRpbWUgKGUuZy4gYSByZWd1bGFyICJjbGVhbnVwIiBzd2VlcCkKICAgICAqLwogICAgZmhhbmRsZSA9IChGSUxFKilsb2doLT5tYWdpYzsKICAgIGlmICghbG9naC0+bWFnaWMpIHsKICAgICAgICBmaGFuZGxlID0gZm9wZW4obG9naC0+dG9rZW4sICJhKyIpOwogICAgICAgIGlmICghZmhhbmRsZSkKICAgICAgICAgICAgcmV0dXJuIDA7CiAgICAgICAgbG9naC0+bWFnaWMgPSAodm9pZCopZmhhbmRsZTsKICAgIH0KICAgIGZwcmludGYoZmhhbmRsZSwgIiVzJXMiLCBzYnVmLCBzdHIpOwogICAgZmZsdXNoKGZoYW5kbGUpOwogICAgbG9naC0+aW1hZ2ljID0gc3RyW3N0cmxlbihzdHIpIC0gMV0gPT0gJ1xuJzsKICAgIHJldHVybiAxOwp9CgppbnQKbG9nX2hhbmRsZXJfY2FsbGJhY2sobmV0c25tcF9sb2dfaGFuZGxlciogbG9naCwgaW50IHByaSwgY29uc3QgY2hhciAqc3RyKQp7CgkvKgoJICogWFhYIC0gcGVyaGFwcyByZXBsYWNlICdzbm1wX2NhbGxfY2FsbGJhY2tzJyBwcm9jZXNzaW5nCgkgKiAgICAgICB3aXRoIGluZGl2aWR1YWwgY2FsbGJhY2sgbG9nX2hhbmRsZXJzID8/CgkgKi8KICAgIHN0cnVjdCBzbm1wX2xvZ19tZXNzYWdlIHNsbTsKICAgIGludCAgICAgICAgICAgICBkb2RlYnVnID0gc25tcF9nZXRfZG9fZGVidWdnaW5nKCk7CgogICAgc2xtLnByaW9yaXR5ID0gcHJpOwogICAgc2xtLm1zZyA9IHN0cjsKICAgIGlmIChkb2RlYnVnKSAgICAgICAgICAgIC8qIHR1cm4gb2ZmIGRlYnVnZ2luZyBpbnNpZGUgdGhlIGNhbGxiYWNrcyBlbHNlIHdpbGwgbG9vcCAqLwogICAgICAgIHNubXBfc2V0X2RvX2RlYnVnZ2luZygwKTsKICAgIHNubXBfY2FsbF9jYWxsYmFja3MoU05NUF9DQUxMQkFDS19MSUJSQVJZLCBTTk1QX0NBTExCQUNLX0xPR0dJTkcsICZzbG0pOwogICAgaWYgKGRvZGVidWcpCiAgICAgICAgc25tcF9zZXRfZG9fZGVidWdnaW5nKGRvZGVidWcpOwogICAgcmV0dXJuIDE7Cn0KCmludApsb2dfaGFuZGxlcl9udWxsKCAgICBuZXRzbm1wX2xvZ19oYW5kbGVyKiBsb2doLCBpbnQgcHJpLCBjb25zdCBjaGFyICpzdHIpCnsKICAgIC8qCiAgICAgKiBEdW1teSBsb2cgaGFuZGxlciAtIGp1c3QgdGhyb3cgYXdheSB0aGUgZXJyb3IgY29tcGxldGVseQogICAgICogWW91IHByb2JhYmx5IGRvbid0IHJlYWxseSB3YW50IHRvIGRvIHRoaXMhCiAgICAgKi8KICAgIHJldHVybiAxOwp9Cgp2b2lkCnNubXBfbG9nX3N0cmluZyhpbnQgcHJpb3JpdHksIGNvbnN0IGNoYXIgKnN0cikKewogICAgc3RhdGljIGludCBzdGRlcnJfZW5hYmxlZCA9IDA7CiAgICBzdGF0aWMgbmV0c25tcF9sb2dfaGFuZGxlciBsaCA9IHsgMSwgMCwgMCwgMCwgInN0ZGVyciIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9nX2hhbmRsZXJfc3Rkb3V0ZXJyLCAwLCBOVUxMLCAgTlVMTCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOVUxMIH07CiAgICBuZXRzbm1wX2xvZ19oYW5kbGVyICpsb2doOwoKICAgIC8qCiAgICAgKiBXZSd2ZSBnb3QgdG8gYmUgYWJsZSB0byBsb2cgbWVzc2FnZXMgKnNvbWV3aGVyZSohCiAgICAgKiBJZiB5b3UgZG9uJ3Qgd2FudCBzdGRlcnIgbG9nZ2luZywgdGhlbiBlbmFibGUgc29tZXRoaW5nIGVsc2UuCiAgICAgKi8KICAgIGlmICgwID09IGxvZ2hfZW5hYmxlZCkgewogICAgICAgIGlmICghc3RkZXJyX2VuYWJsZWQpIHsKICAgICAgICAgICAgKytzdGRlcnJfZW5hYmxlZDsKICAgICAgICAgICAgbmV0c25tcF9zZXRfbGluZV9idWZmZXJpbmcoc3RkZXJyKTsKICAgICAgICAgICAgbG9nX2hhbmRsZXJfc3Rkb3V0ZXJyKCAmbGgsIExPR19XQVJOSU5HLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJObyBsb2cgaGFuZGxpbmcgZW5hYmxlZCAtIHVzaW5nIHN0ZGVyciBsb2dnaW5nXG4iKTsKICAgICAgICB9CiAgICAgICAgbG9nX2hhbmRsZXJfc3Rkb3V0ZXJyKCAmbGgsIHByaW9yaXR5LCBzdHIgKTsKCiAgICAgICAgcmV0dXJuOwogICAgfQogICAgZWxzZSBpZiAoc3RkZXJyX2VuYWJsZWQpIHsKICAgICAgICBzdGRlcnJfZW5hYmxlZCA9IDA7CiAgICAgICAgbG9nX2hhbmRsZXJfc3Rkb3V0ZXJyKCAmbGgsIExPR19JTkZPLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkxvZyBoYW5kbGluZyBkZWZpbmVkIC0gZGlzYWJsaW5nIHN0ZGVyclxuIiApOwogICAgfQogICAgICAgIAoKICAgIC8qCiAgICAgKiBTdGFydCBhdCB0aGUgZ2l2ZW4gcHJpb3JpdHksIGFuZCB3b3JrICJ1cHdhcmRzIi4uLi4KICAgICAqLwogICAgbG9naCA9IGxvZ2hfcHJpb3JpdGllc1twcmlvcml0eV07CiAgICBmb3IgKCA7IGxvZ2g7IGxvZ2ggPSBsb2doLT5uZXh0ICkgewogICAgICAgIC8qCiAgICAgICAgICogLi4uIGJ1dCBza2lwcGluZyBhbnkgaGFuZGxlcnMgd2l0aCBhICJtYXhpbXVtIHByaW9yaXR5IgogICAgICAgICAqICAgICB0aGF0IHdlIGhhdmUgYWxyZWFkeSBleGNlZWRlZC4gQW5kIGRvbid0IGZvcmdldCB0bwogICAgICAgICAqICAgICBlbnN1cmUgdGhpcyBsb2dnaW5nIGlzIHR1cm5lZCBvbiAoc2VlIHNubXBfZGlzYWJsZV9zdGRlcnJsb2cKICAgICAgICAgKiAgICAgYW5kIGl0cyBjb2hvcnRzKS4KICAgICAgICAgKi8KICAgICAgICBpZiAobG9naC0+ZW5hYmxlZCAmJiAocHJpb3JpdHkgPj0gbG9naC0+cHJpX21heCkpCiAgICAgICAgICAgIGxvZ2gtPmhhbmRsZXIoIGxvZ2gsIHByaW9yaXR5LCBzdHIgKTsKICAgIH0KfQoKLyogPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PSAqLwoKCi8qKgogKiBUaGlzIHNubXAgbG9nZ2luZyBmdW5jdGlvbiBhbGxvd3MgdmFyaWFibGUgYXJndW1lbnQgbGlzdCBnaXZlbiB0aGUKICogc3BlY2lmaWVkIHByaW9yaXR5LCBmb3JtYXQgYW5kIGEgcG9wdWxhdGVkIHZhX2xpc3Qgc3RydWN0dXJlLgogKiBUaGUgZGVmYXVsdCBsb2dmaWxlIHRoaXMgZnVuY3Rpb24gd3JpdGVzIHRvIGlzIC92YXIvbG9nL3NubXBkLmxvZy4KICoKICogQHBhcmFtIHByaW9yaXR5IGlzIGFuIGludGVnZXIgcmVwcmVzZW50aW5nIHRoZSB0eXBlIG9mIG1lc3NhZ2UgdG8gYmUgd3JpdHRlbgogKgl0byB0aGUgc25tcCBsb2cgZmlsZS4gIFRoZSB0eXBlcyBhcmUgZXJyb3JzLCB3YXJuaW5nLCBhbmQgaW5mb3JtYXRpb24uCiAqICAgICAgLSBUaGUgZXJyb3IgdHlwZXMgYXJlOgogKiAgICAgICAgLSBMT0dfRU1FUkcgICAgICAgc3lzdGVtIGlzIHVudXNhYmxlIAogKiAgICAgICAgLSBMT0dfQUxFUlQgICAgICAgYWN0aW9uIG11c3QgYmUgdGFrZW4gaW1tZWRpYXRlbHkgCiAqICAgICAgICAtIExPR19DUklUICAgICAgICBjcml0aWNhbCBjb25kaXRpb25zIAogKiAgICAgICAgLSBMT0dfRVJSICAgICAgICAgZXJyb3IgY29uZGl0aW9ucwogKiAgICAgIC0gVGhlIHdhcm5pbmcgdHlwZSBpczoKICogICAgICAgIC0gTE9HX1dBUk5JTkcgICAgIHdhcm5pbmcgY29uZGl0aW9ucyAKICogICAgICAtIFRoZSBpbmZvcm1hdGlvbiB0eXBlcyBhcmU6CiAqICAgICAgICAtIExPR19OT1RJQ0UgICAgICBub3JtYWwgYnV0IHNpZ25pZmljYW50IGNvbmRpdGlvbgogKiAgICAgICAgLSBMT0dfSU5GTyAgICAgICAgaW5mb3JtYXRpb25hbAogKiAgICAgICAgLSBMT0dfREVCVUcgICAgICAgZGVidWctbGV2ZWwgbWVzc2FnZXMKICoKICogQHBhcmFtIGZvcm1hdCBpcyBhIHBvaW50ZXIgdG8gYSBjaGFyIHJlcHJlc2VudGluZyB0aGUgdmFyaWFibGUgYXJndW1lbnQgbGlzdAogKglmb3JtYXQgdXNlZC4KICoKICogQHBhcmFtIGFwIGlzIGEgdmFfbGlzdCB0eXBlIHVzZWQgdG8gdHJhdmVyc2UgdGhlIGxpc3Qgb2YgYXJndW1lbnRzLgogKgogKiBAcmV0dXJuIFJldHVybnMgMCBvbiBzdWNjZXNzLCAtMSB3aGVuIHRoZSBjb2RlIGNvdWxkIG5vdCBmb3JtYXQgdGhlIGxvZy0KICogICAgICAgICBzdHJpbmcsIC0yIHdoZW4gZHluYW1pYyBtZW1vcnkgY291bGQgbm90IGJlIGFsbG9jYXRlZCBpZiB0aGUgbGVuZ3RoCiAqICAgICAgICAgb2YgdGhlIGxvZyBidWZmZXIgaXMgZ3JlYXRlciB0aGVuIDEwMjQgYnl0ZXMuICBGb3IgZWFjaCBvZiB0aGVzZQogKiAgICAgICAgIGVycm9ycyBhIExPR19FUlIgbWVzc2dhZSBpcyB3cml0dGVuIHRvIHRoZSBsb2dmaWxlLgogKgogKiBAc2VlIHNubXBfbG9nCiAqLwppbnQKc25tcF92bG9nKGludCBwcmlvcml0eSwgY29uc3QgY2hhciAqZm9ybWF0LCB2YV9saXN0IGFwKQp7CiAgICBjaGFyICAgICAgICAgICAgYnVmZmVyW0xPR0xFTkdUSF07CiAgICBpbnQgICAgICAgICAgICAgbGVuZ3RoOwogICAgY2hhciAgICAgICAgICAgKmR5bmFtaWM7CiAgICB2YV9saXN0ICAgICAgICAgYXE7CgogICAgdmFfY29weShhcSwgYXApOwogICAgbGVuZ3RoID0gdnNucHJpbnRmKGJ1ZmZlciwgTE9HTEVOR1RILCBmb3JtYXQsIGFwKTsKICAgIHZhX2VuZChhcCk7CgogICAgaWYgKGxlbmd0aCA9PSAwKSB7CiNpZmRlZiBORUVEX1ZBX0VORF9BRlRFUl9WQV9DT1BZCiAgICAgICAgdmFfZW5kKGFxKTsKI2VuZGlmCiAgICAgICAgcmV0dXJuICgwKTsgICAgICAgICAgICAgLyogRW1wdHkgc3RyaW5nICovCiAgICB9CgogICAgaWYgKGxlbmd0aCA9PSAtMSkgewogICAgICAgIHNubXBfbG9nX3N0cmluZyhMT0dfRVJSLCAiQ291bGQgbm90IGZvcm1hdCBsb2ctc3RyaW5nXG4iKTsKI2lmZGVmIE5FRURfVkFfRU5EX0FGVEVSX1ZBX0NPUFkKICAgICAgICB2YV9lbmQoYXEpOwojZW5kaWYKICAgICAgICByZXR1cm4gKC0xKTsKICAgIH0KCiAgICBpZiAobGVuZ3RoIDwgTE9HTEVOR1RIKSB7CiAgICAgICAgc25tcF9sb2dfc3RyaW5nKHByaW9yaXR5LCBidWZmZXIpOwojaWZkZWYgTkVFRF9WQV9FTkRfQUZURVJfVkFfQ09QWQogICAgICAgIHZhX2VuZChhcSk7CiNlbmRpZgogICAgICAgIHJldHVybiAoMCk7CiAgICB9CgogICAgZHluYW1pYyA9IChjaGFyICopIG1hbGxvYyhsZW5ndGggKyAxKTsKICAgIGlmIChkeW5hbWljID09IE5VTEwpIHsKICAgICAgICBzbm1wX2xvZ19zdHJpbmcoTE9HX0VSUiwKICAgICAgICAgICAgICAgICAgICAgICAgIkNvdWxkIG5vdCBhbGxvY2F0ZSBtZW1vcnkgZm9yIGxvZy1tZXNzYWdlXG4iKTsKICAgICAgICBzbm1wX2xvZ19zdHJpbmcocHJpb3JpdHksIGJ1ZmZlcik7CiNpZmRlZiBORUVEX1ZBX0VORF9BRlRFUl9WQV9DT1BZCiAgICAgICAgdmFfZW5kKGFxKTsKI2VuZGlmCiAgICAgICAgcmV0dXJuICgtMik7CiAgICB9CgogICAgdnNucHJpbnRmKGR5bmFtaWMsIGxlbmd0aCArIDEsIGZvcm1hdCwgYXEpOwogICAgc25tcF9sb2dfc3RyaW5nKHByaW9yaXR5LCBkeW5hbWljKTsKICAgIGZyZWUoZHluYW1pYyk7CiAgICB2YV9lbmQoYXEpOwogICAgcmV0dXJuIDA7Cn0KCi8qKgogKiBUaGlzIHNubXAgbG9nZ2luZyBmdW5jdGlvbiBhbGxvd3MgdmFyaWFibGUgYXJndW1lbnQgbGlzdCBnaXZlbiB0aGUKICogc3BlY2lmaWVkIGZvcm1hdCBhbmQgcHJpb3JpdHkuICBDYWxscyB0aGUgc25tcF92bG9nIGZ1bmN0aW9uLgogKiBUaGUgZGVmYXVsdCBsb2dmaWxlIHRoaXMgZnVuY3Rpb24gd3JpdGVzIHRvIGlzIC92YXIvbG9nL3NubXBkLmxvZy4KICoKICogQHNlZSBzbm1wX3Zsb2cKICovCmludApzbm1wX2xvZyhpbnQgcHJpb3JpdHksIGNvbnN0IGNoYXIgKmZvcm1hdCwgLi4uKQp7CiAgICB2YV9saXN0ICAgICAgICAgYXA7CiAgICBpbnQgICAgICAgICAgICAgcmV0OwogICAgdmFfc3RhcnQoYXAsIGZvcm1hdCk7CiAgICByZXQgPSBzbm1wX3Zsb2cocHJpb3JpdHksIGZvcm1hdCwgYXApOwogICAgdmFfZW5kKGFwKTsKICAgIHJldHVybiAocmV0KTsKfQoKLyoKICogbG9nIGEgY3JpdGljYWwgZXJyb3IuCiAqLwp2b2lkCnNubXBfbG9nX3BlcnJvcihjb25zdCBjaGFyICpzKQp7CiAgICBjaGFyICAgICAgICAgICAqZXJyb3IgPSBzdHJlcnJvcihlcnJubyk7CiAgICBpZiAocykgewogICAgICAgIGlmIChlcnJvcikKICAgICAgICAgICAgc25tcF9sb2coTE9HX0VSUiwgIiVzOiAlc1xuIiwgcywgZXJyb3IpOwogICAgICAgIGVsc2UKICAgICAgICAgICAgc25tcF9sb2coTE9HX0VSUiwgIiVzOiBFcnJvciAlZCBvdXQtb2YtcmFuZ2VcbiIsIHMsIGVycm5vKTsKICAgIH0gZWxzZSB7CiAgICAgICAgaWYgKGVycm9yKQogICAgICAgICAgICBzbm1wX2xvZyhMT0dfRVJSLCAiJXNcbiIsIGVycm9yKTsKICAgICAgICBlbHNlCiAgICAgICAgICAgIHNubXBfbG9nKExPR19FUlIsICJFcnJvciAlZCBvdXQtb2YtcmFuZ2VcbiIsIGVycm5vKTsKICAgIH0KfQoKLyogZXh0ZXJuYWwgYWNjZXNzIHRvIGxvZ2hfaGVhZCB2YXJpYWJsZSAqLwpuZXRzbm1wX2xvZ19oYW5kbGVyICAqCmdldF9sb2doX2hlYWQodm9pZCkKewoJcmV0dXJuIGxvZ2hfaGVhZDsKfQoKLyoqICBAfSAqLwo=