From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1IRB5J-0002Bz-AZ for qemu-devel@nongnu.org; Fri, 31 Aug 2007 14:19:09 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1IRB5E-0002BS-97 for qemu-devel@nongnu.org; Fri, 31 Aug 2007 14:19:08 -0400 Received: from [199.232.76.173] (helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1IRB5D-0002BF-V4 for qemu-devel@nongnu.org; Fri, 31 Aug 2007 14:19:03 -0400 Received: from nz-out-0506.google.com ([64.233.162.237]) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1IRB5D-00038m-Hm for qemu-devel@nongnu.org; Fri, 31 Aug 2007 14:19:03 -0400 Received: by nz-out-0506.google.com with SMTP id f1so2475187nzc for ; Fri, 31 Aug 2007 11:19:01 -0700 (PDT) Message-ID: <59abf66e0708311119p2b83fcffg31fac1c298cfc10a@mail.gmail.com> Date: Fri, 31 Aug 2007 15:19:00 -0300 From: "=?ISO-8859-1?Q?Jorge_Luc=E1ngeli_Obes?=" MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="----=_Part_10346_10086061.1188584340615" Subject: [Qemu-devel] [PATCH][RFC] Allowing QEMU to directly execute a directory (and storing command line options in it) Reply-To: qemu-devel@nongnu.org List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org, kvm-devel@lists.sourceforge.net ------=_Part_10346_10086061.1188584340615 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable Content-Disposition: inline Hi all, The last time this issue was discussed, the executable-directory idea gained more consensus than the snapshot-based idea. This patch implements my perception of the first idea. Non-Windows for now, as I can't test on a Windows system. Suggestions and constructive criticism more than welcome. Cheers, Jorge This patch allows QEMU to execute a directory with a special format. This patch allows storing command line options in a configuration file insi= de a directory and then directly executing that directory. A simple check is included to prevent the configuration file to access image files outside the executed directory. Extra command line options can be passed on invocat= ion, which will take precedence over the ones stored in the configuration file. The configuration file specifies, on its first line, the image file to use. The rest of the file specifies command line options separated by spaces or newlines. Careful reconstruction of the command line makes sure the spefici= ed image file gets executed even if other image files were included later in t= he configuration file. Signed-off-by: Jorge Luc=E1ngeli Obes --- diff --git a/qemu/vl.c b/qemu/vl.c index fcc899b..88cefd2 100644 --- a/qemu/vl.c +++ b/qemu/vl.c @@ -42,8 +42,8 @@ #include #include #include -#ifdef _BSD #include +#ifdef _BSD #ifndef __APPLE__ #include #endif @@ -6367,9 +6367,16 @@ int main_loop(void) void help(void) { printf("QEMU PC emulator version " QEMU_VERSION ", Copyright (c) 2003-2007 Fabrice Bellard\n" - "usage: %s [options] [disk_image]\n" + "usage: %s [options] [disk_image|folder]\n" "\n" +#ifdef _WIN32 "'disk_image' is a raw hard image image for IDE hard disk 0\n" +#else + "'disk_image' is a raw hard image image for IDE hard disk 0 or\= n" + "'folder' is a folder with a file 'config' containing in the first line\n" + "the name of an image file inside the folder and in the rest of the file\n" + "options separated by ' ' or '\\n'\n" +#endif "\n" "Standard options:\n" "-M machine select emulated machine (-M ? for list)\n" @@ -6892,6 +6899,20 @@ void qemu_get_launch_info(int *argc, char ***argv, int *opt_daemonize, const cha *opt_incoming =3D incoming; } +char *dir_file_cat(const char *folder, const char *file) { + int foldlen =3D strlen(folder); + int filelen =3D strlen(file); + int reslen =3D foldlen + 1 + filelen + 1; + + char *res =3D malloc(sizeof(char) * reslen); + + pstrcpy(res, reslen, folder); + strncat(res, "/", 1); + strncat(res, file, filelen); + + return res; +} + int main(int argc, char **argv) { #ifdef CONFIG_GDBSTUB @@ -7003,7 +7024,120 @@ int main(int argc, char **argv) nb_nics =3D 0; /* default mac address of the first network interface */ + +#ifndef _WIN32 +#define DIR_CMDLINE_SIZE 1<<13 + int hd_found =3D 0; + char *dir, *opts; + struct stat *s =3D NULL; + + optind =3D 1; + for(;;) { + if (optind >=3D argc) + break; + + dir =3D argv[optind++]; + + if (dir[0] !=3D '-') { + hd_found =3D 1; + break; + } + } + if (hd_found) { + s =3D malloc(sizeof(*s)); + + if (stat(dir, s) < 0) { + /* Error */ + fprintf(stderr, "unable to stat: '%s'\n", + dir); + exit(1); + } + + if (S_ISDIR(s->st_mode)) { + /* The user specified a directory, search for ./config */ + int configlen =3D strlen(dir); + configlen +=3D 8; /* "/config\0" */ + char *config =3D malloc(sizeof(char) * configlen); + + pstrcpy(config, configlen, dir); + strncat(config, "/config", 7); + + int fd_config; + + if ((fd_config =3D open(config, 0)) < 0) { + /* Error */ + if (errno =3D=3D ENOENT) + fprintf(stderr, "config file not found: '%s'\n", + config); + else + fprintf(stderr, "unable to open config file: '%s'\n", + config); + exit(1); + } + + opts =3D malloc(sizeof(char) * (DIR_CMDLINE_SIZE)); + + ssize_t readb =3D read(fd_config, opts, (DIR_CMDLINE_SIZE) - 1= ); + + opts[readb] =3D '\0'; + + char *filename =3D strsep(&opts, "\n"); + + if (filename =3D=3D NULL) { + /* Error */ + fprintf(stderr, "malformed configuration file: '%s'\n", + config); + exit(1); + } else if (strchr(filename, '/') !=3D NULL) { + /* Error */ + fprintf(stderr, "'%s' may point outside folder '%s'\n" + "avoid using '/' in config file\n", + filename, dir); + exit(1); + } + + char tmpopts[DIR_CMDLINE_SIZE]; + int done =3D 0; + unsigned int nbtoks =3D 0; + char *tok; + + pstrcpy(tmpopts, DIR_CMDLINE_SIZE, opts); + + do { + tok =3D strtok(nbtoks =3D=3D 0? tmpopts : NULL, " \n"); + + if (tok !=3D NULL) + nbtoks++; + else + done =3D 1; + } while (!done); + + if (nbtoks > 0) { + char **argvprime =3D malloc((nbtoks + argc + 1) * sizeof(c= har*)); + + argvprime[0] =3D argv[0]; + + for (i =3D 0; i < nbtoks; i++) + argvprime[i + 1] =3D strtok(i =3D=3D 0? opts : NULL, "= \n"); + + for (i =3D 1; i < argc; i++) + argvprime[nbtoks + i] =3D argv[i]; + + argvprime[nbtoks + argc] =3D dir_file_cat(dir, filename); + + argv =3D argvprime; + argc =3D nbtoks + argc + 1; + + for (i =3D 0; i < argc; i++) + printf("argv[%d] =3D %s\n", i, argv[i]); + } + } + } + + free(s); +#endif + optind =3D 1; for(;;) { if (optind >=3D argc) @@ -7773,5 +7907,10 @@ int main(int argc, char **argv) main_loop(); quit_timers(); + + /* argv was overwritten when parsing config file */ + if (hd_found) + =09free(argv); + return 0; } ------=_Part_10346_10086061.1188584340615 Content-Type: text/x-patch; name="exec_dir.patch" Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="exec_dir.patch"; filename="exec_dir.patch"; filename="exec_dir.patch" X-Attachment-Id: f_f610cggs VGhpcyBwYXRjaCBhbGxvd3MgUUVNVSB0byBleGVjdXRlIGEgZGlyZWN0b3J5IHdpdGggYSBzcGVj aWFsIGZvcm1hdC4gICAgICAgCgpUaGlzIHBhdGNoIGFsbG93cyBzdG9yaW5nIGNvbW1hbmQgbGlu ZSBvcHRpb25zIGluIGEgY29uZmlndXJhdGlvbiBmaWxlIGluc2lkZSAgCmEgZGlyZWN0b3J5IGFu ZCB0aGVuIGRpcmVjdGx5IGV4ZWN1dGluZyB0aGF0IGRpcmVjdG9yeS4gQSBzaW1wbGUgY2hlY2sg aXMKaW5jbHVkZWQgdG8gcHJldmVudCB0aGUgY29uZmlndXJhdGlvbiBmaWxlIHRvIGFjY2VzcyBp bWFnZSBmaWxlcyBvdXRzaWRlCnRoZSBleGVjdXRlZCBkaXJlY3RvcnkuIEV4dHJhIGNvbW1hbmQg bGluZSBvcHRpb25zIGNhbiBiZSBwYXNzZWQgb24gaW52b2NhdGlvbiwKd2hpY2ggd2lsbCB0YWtl IHByZWNlZGVuY2Ugb3ZlciB0aGUgb25lcyBzdG9yZWQgaW4gdGhlIGNvbmZpZ3VyYXRpb24gZmls ZS4KClRoZSBjb25maWd1cmF0aW9uIGZpbGUgc3BlY2lmaWVzLCBvbiBpdHMgZmlyc3QgbGluZSwg dGhlIGltYWdlIGZpbGUgdG8gdXNlLgpUaGUgcmVzdCBvZiB0aGUgZmlsZSBzcGVjaWZpZXMgY29t bWFuZCBsaW5lIG9wdGlvbnMgc2VwYXJhdGVkIGJ5IHNwYWNlcyBvcgpuZXdsaW5lcy4gQ2FyZWZ1 bCByZWNvbnN0cnVjdGlvbiBvZiB0aGUgY29tbWFuZCBsaW5lIG1ha2VzIHN1cmUgdGhlIHNwZWZp Y2llZAppbWFnZSBmaWxlIGdldHMgZXhlY3V0ZWQgZXZlbiBpZiBvdGhlciBpbWFnZSBmaWxlcyB3 ZXJlIGluY2x1ZGVkIGxhdGVyIGluIHRoZQpjb25maWd1cmF0aW9uIGZpbGUuCgpTaWduZWQtb2Zm LWJ5OiBKb3JnZSBMdWPDoW5nZWxpIE9iZXMKLS0tCmRpZmYgLS1naXQgYS9xZW11L3ZsLmMgYi9x ZW11L3ZsLmMKaW5kZXggZmNjODk5Yi4uODhjZWZkMiAxMDA2NDQKLS0tIGEvcWVtdS92bC5jCisr KyBiL3FlbXUvdmwuYwpAQCAtNDIsOCArNDIsOCBAQAogI2luY2x1ZGUgPG5ldGluZXQvaW4uaD4K ICNpbmNsdWRlIDxkaXJlbnQuaD4KICNpbmNsdWRlIDxuZXRkYi5oPgotI2lmZGVmIF9CU0QKICNp bmNsdWRlIDxzeXMvc3RhdC5oPgorI2lmZGVmIF9CU0QKICNpZm5kZWYgX19BUFBMRV9fCiAjaW5j bHVkZSA8bGlidXRpbC5oPgogI2VuZGlmCkBAIC02MzY3LDkgKzYzNjcsMTYgQEAgaW50IG1haW5f bG9vcCh2b2lkKQogdm9pZCBoZWxwKHZvaWQpCiB7CiAgICAgcHJpbnRmKCJRRU1VIFBDIGVtdWxh dG9yIHZlcnNpb24gIiBRRU1VX1ZFUlNJT04gIiwgQ29weXJpZ2h0IChjKSAyMDAzLTIwMDcgRmFi cmljZSBCZWxsYXJkXG4iCi0gICAgICAgICAgICJ1c2FnZTogJXMgW29wdGlvbnNdIFtkaXNrX2lt YWdlXVxuIgorICAgICAgICAgICAidXNhZ2U6ICVzIFtvcHRpb25zXSBbZGlza19pbWFnZXxmb2xk ZXJdXG4iCiAgICAgICAgICAgICJcbiIKKyNpZmRlZiBfV0lOMzIKICAgICAgICAgICAgIidkaXNr X2ltYWdlJyBpcyBhIHJhdyBoYXJkIGltYWdlIGltYWdlIGZvciBJREUgaGFyZCBkaXNrIDBcbiIK KyNlbHNlCisgICAgICAgICAgICInZGlza19pbWFnZScgaXMgYSByYXcgaGFyZCBpbWFnZSBpbWFn ZSBmb3IgSURFIGhhcmQgZGlzayAwIG9yXG4iCisgICAgICAgICAgICInZm9sZGVyJyBpcyBhIGZv bGRlciB3aXRoIGEgZmlsZSAnY29uZmlnJyBjb250YWluaW5nIGluIHRoZSBmaXJzdCBsaW5lXG4i CisgICAgICAgICAgICJ0aGUgbmFtZSBvZiBhbiBpbWFnZSBmaWxlIGluc2lkZSB0aGUgZm9sZGVy IGFuZCBpbiB0aGUgcmVzdCBvZiB0aGUgZmlsZVxuIgorICAgICAgICAgICAib3B0aW9ucyBzZXBh cmF0ZWQgYnkgJyAnIG9yICdcXG4nXG4iCisjZW5kaWYKICAgICAgICAgICAgIlxuIgogICAgICAg ICAgICAiU3RhbmRhcmQgb3B0aW9uczpcbiIKICAgICAgICAgICAgIi1NIG1hY2hpbmUgICAgICBz ZWxlY3QgZW11bGF0ZWQgbWFjaGluZSAoLU0gPyBmb3IgbGlzdClcbiIKQEAgLTY4OTIsNiArNjg5 OSwyMCBAQCB2b2lkIHFlbXVfZ2V0X2xhdW5jaF9pbmZvKGludCAqYXJnYywgY2hhciAqKiphcmd2 LCBpbnQgKm9wdF9kYWVtb25pemUsIGNvbnN0IGNoYQogICAgICpvcHRfaW5jb21pbmcgPSBpbmNv bWluZzsKIH0KIAorY2hhciAqZGlyX2ZpbGVfY2F0KGNvbnN0IGNoYXIgKmZvbGRlciwgY29uc3Qg Y2hhciAqZmlsZSkgeworICAgIGludCBmb2xkbGVuID0gc3RybGVuKGZvbGRlcik7CisgICAgaW50 IGZpbGVsZW4gPSBzdHJsZW4oZmlsZSk7CisgICAgaW50IHJlc2xlbiA9IGZvbGRsZW4gKyAxICsg ZmlsZWxlbiArIDE7CisKKyAgICBjaGFyICpyZXMgPSBtYWxsb2Moc2l6ZW9mKGNoYXIpICogcmVz bGVuKTsKKworICAgIHBzdHJjcHkocmVzLCByZXNsZW4sIGZvbGRlcik7CisgICAgc3RybmNhdChy ZXMsICIvIiwgMSk7CisgICAgc3RybmNhdChyZXMsIGZpbGUsIGZpbGVsZW4pOworCisgICAgcmV0 dXJuIHJlczsKK30KKwogaW50IG1haW4oaW50IGFyZ2MsIGNoYXIgKiphcmd2KQogewogI2lmZGVm IENPTkZJR19HREJTVFVCCkBAIC03MDAzLDcgKzcwMjQsMTIwIEBAIGludCBtYWluKGludCBhcmdj LCBjaGFyICoqYXJndikKIAogICAgIG5iX25pY3MgPSAwOwogICAgIC8qIGRlZmF1bHQgbWFjIGFk ZHJlc3Mgb2YgdGhlIGZpcnN0IG5ldHdvcmsgaW50ZXJmYWNlICovCisKKyNpZm5kZWYgX1dJTjMy CisjZGVmaW5lIERJUl9DTURMSU5FX1NJWkUgMTw8MTMKKyAgICBpbnQgaGRfZm91bmQgPSAwOwor ICAgIGNoYXIgKmRpciwgKm9wdHM7CisgICAgc3RydWN0IHN0YXQgKnMgPSBOVUxMOworCisgICAg b3B0aW5kID0gMTsKKyAgICBmb3IoOzspIHsKKyAgICAgICAgaWYgKG9wdGluZCA+PSBhcmdjKQor ICAgICAgICAgICAgYnJlYWs7CisKKyAgICAgICAgZGlyID0gYXJndltvcHRpbmQrK107CisKKyAg ICAgICAgaWYgKGRpclswXSAhPSAnLScpIHsKKyAgICAgICAgICAgIGhkX2ZvdW5kID0gMTsKKyAg ICAgICAgICAgIGJyZWFrOworICAgICAgICB9CisgICAgfQogICAgIAorICAgIGlmIChoZF9mb3Vu ZCkgeworICAgICAgICBzID0gbWFsbG9jKHNpemVvZigqcykpOworCisgICAgICAgIGlmIChzdGF0 KGRpciwgcykgPCAwKSB7CisgICAgICAgICAgICAvKiBFcnJvciAqLworICAgICAgICAgICAgZnBy aW50ZihzdGRlcnIsICJ1bmFibGUgdG8gc3RhdDogJyVzJ1xuIiwKKyAgICAgICAgICAgICAgICAg ICAgZGlyKTsKKyAgICAgICAgICAgIGV4aXQoMSk7CisgICAgICAgIH0KKworICAgICAgICBpZiAo U19JU0RJUihzLT5zdF9tb2RlKSkgeworICAgICAgICAgICAgLyogVGhlIHVzZXIgc3BlY2lmaWVk IGEgZGlyZWN0b3J5LCBzZWFyY2ggZm9yIC4vY29uZmlnICovCisgICAgICAgICAgICBpbnQgY29u ZmlnbGVuID0gc3RybGVuKGRpcik7CisgICAgICAgICAgICBjb25maWdsZW4gKz0gODsgLyogIi9j b25maWdcMCIgKi8KKyAgICAgICAgICAgIGNoYXIgKmNvbmZpZyA9IG1hbGxvYyhzaXplb2YoY2hh cikgKiBjb25maWdsZW4pOworCisgICAgICAgICAgICBwc3RyY3B5KGNvbmZpZywgY29uZmlnbGVu LCBkaXIpOworICAgICAgICAgICAgc3RybmNhdChjb25maWcsICIvY29uZmlnIiwgNyk7CisKKyAg ICAgICAgICAgIGludCBmZF9jb25maWc7CisKKyAgICAgICAgICAgIGlmICgoZmRfY29uZmlnID0g b3Blbihjb25maWcsIDApKSA8IDApIHsKKyAgICAgICAgICAgICAgICAvKiBFcnJvciAqLworICAg ICAgICAgICAgICAgIGlmIChlcnJubyA9PSBFTk9FTlQpCisgICAgICAgICAgICAgICAgICAgIGZw cmludGYoc3RkZXJyLCAiY29uZmlnIGZpbGUgbm90IGZvdW5kOiAnJXMnXG4iLAorICAgICAgICAg ICAgICAgICAgICAgICAgICAgIGNvbmZpZyk7CisgICAgICAgICAgICAgICAgZWxzZQorICAgICAg ICAgICAgICAgICAgICBmcHJpbnRmKHN0ZGVyciwgInVuYWJsZSB0byBvcGVuIGNvbmZpZyBmaWxl OiAnJXMnXG4iLAorICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbmZpZyk7CisgICAgICAg ICAgICAgICAgZXhpdCgxKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgb3B0cyA9IG1h bGxvYyhzaXplb2YoY2hhcikgKiAoRElSX0NNRExJTkVfU0laRSkpOworCisgICAgICAgICAgICBz c2l6ZV90IHJlYWRiID0gcmVhZChmZF9jb25maWcsIG9wdHMsIChESVJfQ01ETElORV9TSVpFKSAt IDEpOworCisgICAgICAgICAgICBvcHRzW3JlYWRiXSA9ICdcMCc7CisKKyAgICAgICAgICAgIGNo YXIgKmZpbGVuYW1lID0gc3Ryc2VwKCZvcHRzLCAiXG4iKTsKKworICAgICAgICAgICAgaWYgKGZp bGVuYW1lID09IE5VTEwpIHsKKyAgICAgICAgICAgICAgICAvKiBFcnJvciAqLworICAgICAgICAg ICAgICAgIGZwcmludGYoc3RkZXJyLCAibWFsZm9ybWVkIGNvbmZpZ3VyYXRpb24gZmlsZTogJyVz J1xuIiwKKyAgICAgICAgICAgICAgICAgICAgICAgIGNvbmZpZyk7CisgICAgICAgICAgICAgICAg ZXhpdCgxKTsKKyAgICAgICAgICAgIH0gZWxzZSBpZiAoc3RyY2hyKGZpbGVuYW1lLCAnLycpICE9 IE5VTEwpIHsKKyAgICAgICAgICAgICAgICAvKiBFcnJvciAqLworICAgICAgICAgICAgICAgIGZw cmludGYoc3RkZXJyLCAiJyVzJyBtYXkgcG9pbnQgb3V0c2lkZSBmb2xkZXIgJyVzJ1xuIgorICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiYXZvaWQgdXNpbmcgJy8nIGluIGNvbmZpZyBm aWxlXG4iLAorICAgICAgICAgICAgICAgICAgICAgICAgZmlsZW5hbWUsIGRpcik7CisgICAgICAg ICAgICAgICAgZXhpdCgxKTsKKyAgICAgICAgICAgIH0KKworICAgICAgICAgICAgY2hhciB0bXBv cHRzW0RJUl9DTURMSU5FX1NJWkVdOworICAgICAgICAgICAgaW50IGRvbmUgPSAwOworICAgICAg ICAgICAgdW5zaWduZWQgaW50IG5idG9rcyA9IDA7CisgICAgICAgICAgICBjaGFyICp0b2s7Cisg CisgICAgICAgICAgICBwc3RyY3B5KHRtcG9wdHMsIERJUl9DTURMSU5FX1NJWkUsIG9wdHMpOwor CisgICAgICAgICAgICBkbyB7CisgICAgICAgICAgICAgICAgdG9rID0gc3RydG9rKG5idG9rcyA9 PSAwPyB0bXBvcHRzIDogTlVMTCwgIiBcbiIpOworCisgICAgICAgICAgICAgICAgaWYgKHRvayAh PSBOVUxMKQorICAgICAgICAgICAgICAgICAgICBuYnRva3MrKzsKKyAgICAgICAgICAgICAgICBl bHNlCisgICAgICAgICAgICAgICAgICAgIGRvbmUgPSAxOworICAgICAgICAgICAgfSB3aGlsZSAo IWRvbmUpOworCisgICAgICAgICAgICBpZiAobmJ0b2tzID4gMCkgeworICAgICAgICAgICAgICAg IGNoYXIgKiphcmd2cHJpbWUgPSBtYWxsb2MoKG5idG9rcyArIGFyZ2MgKyAxKSAqIHNpemVvZihj aGFyKikpOworCisgICAgICAgICAgICAgICAgYXJndnByaW1lWzBdID0gYXJndlswXTsKKworICAg ICAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCBuYnRva3M7IGkrKykKKyAgICAgICAgICAgICAg ICAgICAgYXJndnByaW1lW2kgKyAxXSA9IHN0cnRvayhpID09IDA/IG9wdHMgOiBOVUxMLCAiIFxu Iik7CisKKyAgICAgICAgICAgICAgICBmb3IgKGkgPSAxOyBpIDwgYXJnYzsgaSsrKQorICAgICAg ICAgICAgICAgICAgICBhcmd2cHJpbWVbbmJ0b2tzICsgaV0gPSBhcmd2W2ldOworCisgICAgICAg ICAgICAgICAgYXJndnByaW1lW25idG9rcyArIGFyZ2NdID0gZGlyX2ZpbGVfY2F0KGRpciwgZmls ZW5hbWUpOworCisgICAgICAgICAgICAgICAgYXJndiA9IGFyZ3ZwcmltZTsKKyAgICAgICAgICAg ICAgICBhcmdjID0gbmJ0b2tzICsgYXJnYyArIDE7CisKKyAgICAgICAgICAgICAgICBmb3IgKGkg PSAwOyBpIDwgYXJnYzsgaSsrKQorICAgICAgICAgICAgICAgICAgICBwcmludGYoImFyZ3ZbJWRd ID0gJXNcbiIsIGksIGFyZ3ZbaV0pOworICAgICAgICAgICAgfQorICAgICAgICB9CisgICAgfQor CisgICAgZnJlZShzKTsKKyNlbmRpZgorCiAgICAgb3B0aW5kID0gMTsKICAgICBmb3IoOzspIHsK ICAgICAgICAgaWYgKG9wdGluZCA+PSBhcmdjKQpAQCAtNzc3Myw1ICs3OTA3LDEwIEBAIGludCBt YWluKGludCBhcmdjLCBjaGFyICoqYXJndikKIAogICAgIG1haW5fbG9vcCgpOwogICAgIHF1aXRf dGltZXJzKCk7CisKKyAgICAvKiBhcmd2IHdhcyBvdmVyd3JpdHRlbiB3aGVuIHBhcnNpbmcgY29u ZmlnIGZpbGUgKi8KKyAgICBpZiAoaGRfZm91bmQpCisgICAgCWZyZWUoYXJndik7CisKICAgICBy ZXR1cm4gMDsKIH0K ------=_Part_10346_10086061.1188584340615--