LyoKICogUlBDIGVuZHBvaW50IG1hcHBlciBzZXJ2ZXIKICoKICogQ29weXJpZ2h0IChDKSAyMDAxIE92ZSBL5XZlbiwgVHJhbnNHYW1pbmcgVGVjaG5vbG9naWVzIEluYywKICogQ29weXJpZ2h0IChDKSAyMDAyIEdyZWcgVHVybmVyCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKICogdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTkgVGVtcGxlIFBsYWNlLCBTdWl0ZSAzMzAsIEJvc3RvbiwgTUEgIDAyMTExLTEzMDcgIFVTQQogKi8KCiNpbmNsdWRlIDxhc3NlcnQuaD4KI2luY2x1ZGUgPHN0cmluZy5oPgoKI2luY2x1ZGUgInJwY3NzLmgiCiNpbmNsdWRlICJycGMuaCIKI2luY2x1ZGUgIndpbmUvZGVidWcuaCIKCldJTkVfREVGQVVMVF9ERUJVR19DSEFOTkVMKG9sZSk7CgpzdHJ1Y3QgZXBtYXBfZW50cnkKewogICAgc3RydWN0IGVwbWFwX2VudHJ5ICpuZXh0OwogICAgUlBDX1NZTlRBWF9JREVOVElGSUVSIGlmYWNlOwogICAgVVVJRCBvYmplY3Q7CiAgICBjaGFyICpwcm90c2VxOwogICAgY2hhciAqZW5kcG9pbnQ7Cn07CgpzdGF0aWMgc3RydWN0IGVwbWFwX2VudHJ5ICplcG1hcDsKCnN0YXRpYyBjb25zdCBVVUlEIG5pbF9vYmplY3Q7CgpjaGFyICpteXN0cmR1cChjb25zdCBjaGFyICpzdHIpIHsKICAgIGNoYXIgKnJ2YWw7CiAgICBydmFsID0gTG9jYWxBbGxvYyhMUFRSLCBzdHJsZW4oc3RyKSsxKTsKICAgIENvcHlNZW1vcnkocnZhbCwgc3RyLCBzdHJsZW4oc3RyKSsxKTsKICAgIHJldHVybiBydmFsOwp9CgpzdGF0aWMgc3RydWN0IGVwbWFwX2VudHJ5ICpmaW5kX2VuZHBvaW50KGNvbnN0IFJQQ19TWU5UQVhfSURFTlRJRklFUiAqaWZhY2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciAqcHJvdHNlcSwgY29uc3QgVVVJRCAqb2JqZWN0KQp7CiAgICBzdHJ1Y3QgZXBtYXBfZW50cnkgKm1hcDsKICAgIGZvciAobWFwPWVwbWFwOyBtYXA7IG1hcD1tYXAtPm5leHQpIHsKICAgICAgICBpZiAobWVtY21wKCZtYXAtPmlmYWNlLCBpZmFjZSwgc2l6ZW9mKFJQQ19TWU5UQVhfSURFTlRJRklFUikpKSBjb250aW51ZTsKICAgICAgICBpZiAobWVtY21wKCZtYXAtPm9iamVjdCwgb2JqZWN0LCBzaXplb2YoVVVJRCkpKSBjb250aW51ZTsKICAgICAgICBpZiAoc3RyY21wKG1hcC0+cHJvdHNlcSwgcHJvdHNlcSkpIGNvbnRpbnVlOwoJV0lORV9UUkFDRSgiZm91bmQuXG4iKTsKICAgICAgICByZXR1cm4gbWFwOwogICAgfQogICAgV0lORV9UUkFDRSgibm90IGZvdW5kLlxuIik7CiAgICByZXR1cm4gTlVMTDsKfQoKc3RhdGljIHZvaWQgcmVnaXN0ZXJfZW5kcG9pbnQoY29uc3QgUlBDX1NZTlRBWF9JREVOVElGSUVSICppZmFjZSwgY29uc3QgY2hhciAqcHJvdHNlcSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2hhciAqZW5kcG9pbnQsIGNvbnN0IFVVSUQgKm9iamVjdHMsIGludCBvYmpjb3VudCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IG5vX3JlcGxhY2UpCnsKICAgIGludCBjOwoKICAgIFdJTkVfVFJBQ0UoIihwcm90c2VxID09ICVzLCBlbmRwb2ludCA9PSAlcywgb2JqY291bnQgPT0gJWksIG5vX3JlcGxhY2UgPT0gJWkpXG4iLAogICAgICB3aW5lX2RiZ3N0cl9hKHByb3RzZXEpLCB3aW5lX2RiZ3N0cl9hKGVuZHBvaW50KSwgb2JqY291bnQsIG5vX3JlcGxhY2UpOwoKICAgIGlmICghb2JqY291bnQpIHsKICAgICAgICBvYmplY3RzID0gJm5pbF9vYmplY3Q7CiAgICAgICAgb2JqY291bnQgPSAxOwogICAgfQoKICAgIGZvciAoYz0wOyBjPG9iamNvdW50OyBjKyspIHsKICAgICAgICBzdHJ1Y3QgZXBtYXBfZW50cnkgKm1hcCA9IE5VTEw7CiAgICAgICAgaWYgKCFub19yZXBsYWNlKQogICAgICAgICAgICBtYXAgPSBmaW5kX2VuZHBvaW50KGlmYWNlLCBwcm90c2VxLCAmb2JqZWN0c1tjXSk7CiAgICAgICAgaWYgKG1hcCkgewogICAgICAgICAgICBMb2NhbEZyZWUobWFwLT5lbmRwb2ludCk7CiAgICAgICAgfQogICAgICAgIGVsc2UgewogICAgICAgICAgICBtYXAgPSBMb2NhbEFsbG9jKExQVFIsIHNpemVvZihzdHJ1Y3QgZXBtYXBfZW50cnkpKTsKICAgICAgICAgICAgbWVtY3B5KCZtYXAtPmlmYWNlLCBpZmFjZSwgc2l6ZW9mKFJQQ19TWU5UQVhfSURFTlRJRklFUikpOwogICAgICAgICAgICBtZW1jcHkoJm1hcC0+b2JqZWN0LCAmb2JqZWN0c1tjXSwgc2l6ZW9mKFVVSUQpKTsKICAgICAgICAgICAgbWFwLT5wcm90c2VxID0gbXlzdHJkdXAocHJvdHNlcSk7CiAgICAgICAgICAgIG1hcC0+bmV4dCA9IGVwbWFwOwogICAgICAgICAgICBlcG1hcCA9IG1hcDsKICAgICAgICB9CiAgICAgICAgV0lORV9UUkFDRSgiICBtYXBwaW5nIGVuZHBvaW50IChwcm90c2VxID09ICVzLCBlbmRwb2ludCA9PSAlcywgdXVpZCA9PSAlcylcbiIsCgkgIHdpbmVfZGJnc3RyX2EocHJvdHNlcSksIHdpbmVfZGJnc3RyX2EoZW5kcG9pbnQpLCB3aW5lX2RiZ3N0cl9ndWlkKCZvYmplY3RzW2NdKSk7CiAgICAgICAgbWFwLT5lbmRwb2ludCA9IG15c3RyZHVwKGVuZHBvaW50KTsKICAgIH0KfQoKc3RhdGljIHZvaWQgdW5yZWdpc3Rlcl9lbmRwb2ludChjb25zdCBSUENfU1lOVEFYX0lERU5USUZJRVIgKmlmYWNlLCBjb25zdCBjaGFyICpwcm90c2VxLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNoYXIgKmVuZHBvaW50LCBjb25zdCBVVUlEICpvYmplY3RzLCBpbnQgb2JqY291bnQpCnsKICAgIHN0cnVjdCBlcG1hcF9lbnRyeSAqbWFwLCAqcHJldiwgKm5wcmV2LCAqbmV4dDsKICAgIGludCBjOwogICAgCiAgICBXSU5FX1RSQUNFKCIocHJvdHNlcSA9PSAlcywgZW5kcG9pbnQgPT0gJXMsIG9iamNvdW50ID09ICVpKVxuIiwgCiAgICAgIHdpbmVfZGJnc3RyX2EocHJvdHNlcSksIHdpbmVfZGJnc3RyX2EoZW5kcG9pbnQpLCBvYmpjb3VudCk7CiAgICAKICAgIGlmICghb2JqY291bnQpIHsKICAgICAgICBvYmplY3RzID0gJm5pbF9vYmplY3Q7CiAgICAgICAgb2JqY291bnQgPSAxOwogICAgfQogICAgcHJldj1OVUxMOwogICAgbnByZXY9TlVMTDsKICAgIG1hcD1lcG1hcDsKICAgIHdoaWxlKG1hcCkgewogICAgICAgIG5leHQgPSBtYXAtPm5leHQ7CiAgICAgICAgbnByZXYgPSBtYXA7CiAgICAgICAgaWYgKG1lbWNtcCgmbWFwLT5pZmFjZSwgaWZhY2UsIHNpemVvZihSUENfU1lOVEFYX0lERU5USUZJRVIpKSkgZ290byBjb250OwogICAgICAgIGZvciAoYz0wOyBjPG9iamNvdW50OyBjKyspCiAgICAgICAgICAgIGlmICghbWVtY21wKCZtYXAtPm9iamVjdCwgJm9iamVjdHNbY10sIHNpemVvZihVVUlEKSkpIGJyZWFrOwogICAgICAgIGlmIChjPT1vYmpjb3VudCkgZ290byBjb250OwogICAgICAgIGlmIChzdHJjbXAobWFwLT5wcm90c2VxLCBwcm90c2VxKSkgZ290byBjb250OwogICAgICAgIAogICAgICAgIFdJTkVfVFJBQ0UoIiAgdW5tYXBwaW5nOiAocHJvdHNlcSA9PSAlcywgZW5kcG9pbnQgPT0gJXMsIHV1aWQgPT0gJXMpXG4iLAoJICB3aW5lX2RiZ3N0cl9hKG1hcC0+cHJvdHNlcSksIHdpbmVfZGJnc3RyX2EobWFwLT5lbmRwb2ludCksCgkgIHdpbmVfZGJnc3RyX2d1aWQoJm1hcC0+b2JqZWN0KSk7CiAgICAgICAgCiAgICAgICAgaWYgKHByZXYpIHByZXYtPm5leHQgPSBtYXAtPm5leHQ7CiAgICAgICAgZWxzZSBlcG1hcCA9IG1hcC0+bmV4dDsKICAgICAgICBucHJldiA9IHByZXY7CgogICAgICAgIExvY2FsRnJlZShtYXAtPnByb3RzZXEpOwogICAgICAgIExvY2FsRnJlZShtYXAtPmVuZHBvaW50KTsKICAgICAgICBMb2NhbEZyZWUobWFwKTsKCiAgICAgICAgY29udDoKCglwcmV2ID0gbnByZXY7CgltYXAgPSBuZXh0OwogICAgfQp9CgpzdGF0aWMgdm9pZCByZXNvbHZlX2VuZHBvaW50KGNvbnN0IFJQQ19TWU5UQVhfSURFTlRJRklFUiAqaWZhY2UsIGNvbnN0IGNoYXIgKnByb3RzZXEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgVVVJRCAqb2JqZWN0LCBjaGFyICpyc2x0X2VwKQp7CiAgICBzaXplX3QgbGVuOwogICAgc3RydWN0IGVwbWFwX2VudHJ5ICptYXA7CgogICAgaWYgKCEobWFwID0gZmluZF9lbmRwb2ludChpZmFjZSwgcHJvdHNlcSwgb2JqZWN0KSkpIHJldHVybjsKCiAgICBsZW4gPSBtaW4oIE1BWF9SUENTU19OUF9SRVBMWV9TVFJJTkdfTEVOLCBzdHJsZW4obWFwLT5lbmRwb2ludCkrMSApOwogICAgaWYgKGxlbikgbWVtY3B5KHJzbHRfZXAsIG1hcC0+ZW5kcG9pbnQsIGxlbik7Cn0KCnN0YXRpYyBjb25zdCBjaGFyICpnZXRfc3RyaW5nKGNvbnN0IGNoYXIqKnB0ciwgY29uc3QgY2hhciplbmQpCnsKICAgIGNvbnN0IGNoYXIgKnN0ciA9ICpwdHIsICpucHRyID0gc3RyOwoKICAgIHdoaWxlIChucHRyIDwgZW5kICYmICpucHRyKSBucHRyKys7CiAgICBpZiAobnB0ciA9PSBlbmQpCiAgICAgICAgcmV0dXJuIE5VTEw7CiAgICAqcHRyID0gbnB0ciArIDE7CiAgICByZXR1cm4gc3RyOwp9CgpCT09MIFJQQ1NTX0VwbWFwRW1wdHkodm9pZCkKewogIHJldHVybiAoIWVwbWFwKTsKfQoKdm9pZCBSUENTU19SZWdpc3RlclJwY0VuZHBvaW50cyhSUENfU1lOVEFYX0lERU5USUZJRVIgaWZhY2UsIGludCBvYmplY3RfY291bnQsIAogIGludCBiaW5kaW5nX2NvdW50LCBpbnQgbm9fcmVwbGFjZSwgY2hhciAqdmFyZGF0YSwgbG9uZyB2YXJkYXRhX3NpemUpCnsKICAgIGNvbnN0IGNoYXIgKmRhdGEgPSB2YXJkYXRhOwogICAgY29uc3QgY2hhciAqZW5kID0gZGF0YSArIHZhcmRhdGFfc2l6ZTsKICAgIFVVSUQgKm9iamVjdHMgPSAoVVVJRCAqKWRhdGE7CiAgICBpbnQgYzsKCiAgICBkYXRhICs9IG9iamVjdF9jb3VudCAqIHNpemVvZihVVUlEKTsKICAgIGZvciAoYz0wOyBjIDwgYmluZGluZ19jb3VudDsgYysrKSB7CiAgICAgICAgY29uc3QgY2hhciAqcHJvdHNlcSA9IGdldF9zdHJpbmcoJmRhdGEsIGVuZCk7CiAgICAgICAgY29uc3QgY2hhciAqZW5kcG9pbnQgPSBnZXRfc3RyaW5nKCZkYXRhLCBlbmQpOwogICAgICAgIGlmIChwcm90c2VxICYmIGVuZHBvaW50KQogICAgICAgICAgICByZWdpc3Rlcl9lbmRwb2ludCgmaWZhY2UsIHByb3RzZXEsIGVuZHBvaW50LCBvYmplY3RzLCBvYmplY3RfY291bnQsIG5vX3JlcGxhY2UpOwogICAgfQp9Cgp2b2lkIFJQQ1NTX1VucmVnaXN0ZXJScGNFbmRwb2ludHMoUlBDX1NZTlRBWF9JREVOVElGSUVSIGlmYWNlLCBpbnQgb2JqZWN0X2NvdW50LAogIGludCBiaW5kaW5nX2NvdW50LCBjaGFyICp2YXJkYXRhLCBsb25nIHZhcmRhdGFfc2l6ZSkKewogICAgY29uc3QgY2hhciAqZGF0YSA9IHZhcmRhdGE7CiAgICBjb25zdCBjaGFyICplbmQgPSBkYXRhICsgdmFyZGF0YV9zaXplOwogICAgY29uc3QgVVVJRCAqb2JqZWN0cyA9IChVVUlEICopZGF0YTsKICAgIGludCBjOwoKICAgIGRhdGEgKz0gb2JqZWN0X2NvdW50ICogc2l6ZW9mKFVVSUQpOwogICAgZm9yIChjPTA7IGMgPCBiaW5kaW5nX2NvdW50OyBjKyspIHsKICAgICAgICBjb25zdCBjaGFyICpwcm90c2VxID0gZ2V0X3N0cmluZygmZGF0YSwgZW5kKTsKICAgICAgICBjb25zdCBjaGFyICplbmRwb2ludCA9IGdldF9zdHJpbmcoJmRhdGEsIGVuZCk7CiAgICAgICAgaWYgKHByb3RzZXEgJiYgZW5kcG9pbnQpCiAgICAgICAgICAgIHVucmVnaXN0ZXJfZW5kcG9pbnQoJmlmYWNlLCBwcm90c2VxLCBlbmRwb2ludCwgb2JqZWN0cywgb2JqZWN0X2NvdW50KTsKICAgIH0KfQoKdm9pZCBSUENTU19SZXNvbHZlUnBjRW5kcG9pbnRzKFJQQ19TWU5UQVhfSURFTlRJRklFUiBpZmFjZSwgVVVJRCBvYmplY3QsIGNoYXIgKnByb3RzZXEsIGNoYXIgKnJzbHRfZXApCnsKICAgIHJlc29sdmVfZW5kcG9pbnQoJmlmYWNlLCBwcm90c2VxLCAmb2JqZWN0LCByc2x0X2VwKTsKfQo=