From nobody Sat May 4 07:37:05 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1514913148007773.8434703639523; Tue, 2 Jan 2018 09:12:28 -0800 (PST) Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 2E2CC6A7CF; Tue, 2 Jan 2018 17:12:26 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.21]) by smtp.corp.redhat.com (Postfix) with ESMTPS id F26865D96F; Tue, 2 Jan 2018 17:12:25 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id 599924BB79; Tue, 2 Jan 2018 17:12:25 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id w02HCN1N003047 for ; Tue, 2 Jan 2018 12:12:23 -0500 Received: by smtp.corp.redhat.com (Postfix) id 5AEF15C3F8; Tue, 2 Jan 2018 17:12:23 +0000 (UTC) Received: from localhost.localdomain (ovpn-204-45.brq.redhat.com [10.40.204.45]) by smtp.corp.redhat.com (Postfix) with ESMTP id C06AE5C888 for ; Tue, 2 Jan 2018 17:12:22 +0000 (UTC) From: Michal Privoznik To: libvir-list@redhat.com Date: Tue, 2 Jan 2018 18:11:54 +0100 Message-Id: <0a08fdf17fbcd040e5c1401dd4072a2db001fbd3.1514911024.git.mprivozn@redhat.com> In-Reply-To: References: In-Reply-To: References: X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH 01/18] vsh: Drop useless check for opts != NULL X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.27]); Tue, 02 Jan 2018 17:12:26 +0000 (UTC) X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" All our internal *Free() functions are capable of handling NULL. Signed-off-by: Michal Privoznik --- tools/vsh.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/tools/vsh.c b/tools/vsh.c index e878119b9..e38dcec92 100644 --- a/tools/vsh.c +++ b/tools/vsh.c @@ -799,8 +799,7 @@ vshCommandFree(vshCmd *cmd) =20 c =3D c->next; =20 - if (tmp->opts) - vshCommandOptFree(tmp->opts); + vshCommandOptFree(tmp->opts); VIR_FREE(tmp); } } @@ -1581,8 +1580,7 @@ vshCommandParse(vshControl *ctl, vshCommandParser *pa= rser) vshCommandFree(ctl->cmd); ctl->cmd =3D NULL; } - if (first) - vshCommandOptFree(first); + vshCommandOptFree(first); VIR_FREE(tkdata); return false; } --=20 2.13.6 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Sat May 4 07:37:05 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1514913147630714.6548633131471; Tue, 2 Jan 2018 09:12:27 -0800 (PST) Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 6CFBD4E33E; Tue, 2 Jan 2018 17:12:26 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.21]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 48DBB5C543; Tue, 2 Jan 2018 17:12:26 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id CC2C14A467; Tue, 2 Jan 2018 17:12:25 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id w02HCOP5003058 for ; Tue, 2 Jan 2018 12:12:24 -0500 Received: by smtp.corp.redhat.com (Postfix) id 86A7E5C3F8; Tue, 2 Jan 2018 17:12:24 +0000 (UTC) Received: from localhost.localdomain (ovpn-204-45.brq.redhat.com [10.40.204.45]) by smtp.corp.redhat.com (Postfix) with ESMTP id ECC565C888 for ; Tue, 2 Jan 2018 17:12:23 +0000 (UTC) From: Michal Privoznik To: libvir-list@redhat.com Date: Tue, 2 Jan 2018 18:11:55 +0100 Message-Id: <04dbb8cab8fde1b9ed225362e863aeeaf9c386ba.1514911024.git.mprivozn@redhat.com> In-Reply-To: References: In-Reply-To: References: X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH 02/18] vsh: Drop useless check for cmd != NULL X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.38]); Tue, 02 Jan 2018 17:12:26 +0000 (UTC) X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" All our internal *Free() functions are capable of handling NULL. Signed-off-by: Michal Privoznik --- tools/vsh.c | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/tools/vsh.c b/tools/vsh.c index e38dcec92..a21e1d1de 100644 --- a/tools/vsh.c +++ b/tools/vsh.c @@ -1392,10 +1392,8 @@ vshCommandParse(vshControl *ctl, vshCommandParser *p= arser) vshCmd *clast =3D NULL; vshCmdOpt *first =3D NULL; =20 - if (ctl->cmd) { - vshCommandFree(ctl->cmd); - ctl->cmd =3D NULL; - } + vshCommandFree(ctl->cmd); + ctl->cmd =3D NULL; =20 while (1) { vshCmdOpt *last =3D NULL; @@ -1576,10 +1574,8 @@ vshCommandParse(vshControl *ctl, vshCommandParser *p= arser) return true; =20 syntaxError: - if (ctl->cmd) { - vshCommandFree(ctl->cmd); - ctl->cmd =3D NULL; - } + vshCommandFree(ctl->cmd); + ctl->cmd =3D NULL; vshCommandOptFree(first); VIR_FREE(tkdata); return false; --=20 2.13.6 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Sat May 4 07:37:05 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1514913155298944.504737717588; Tue, 2 Jan 2018 09:12:35 -0800 (PST) Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 8C09F802; Tue, 2 Jan 2018 17:12:33 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.20]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 659F81754E; Tue, 2 Jan 2018 17:12:33 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id 2A2EE1801240; Tue, 2 Jan 2018 17:12:33 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id w02HCPUI003068 for ; Tue, 2 Jan 2018 12:12:25 -0500 Received: by smtp.corp.redhat.com (Postfix) id A9B264D71F; Tue, 2 Jan 2018 17:12:25 +0000 (UTC) Received: from localhost.localdomain (ovpn-204-45.brq.redhat.com [10.40.204.45]) by smtp.corp.redhat.com (Postfix) with ESMTP id 0EDAF5C888 for ; Tue, 2 Jan 2018 17:12:24 +0000 (UTC) From: Michal Privoznik To: libvir-list@redhat.com Date: Tue, 2 Jan 2018 18:11:56 +0100 Message-Id: In-Reply-To: References: In-Reply-To: References: X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH 03/18] vshCommandParse: Don't leak @tkdata X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.29]); Tue, 02 Jan 2018 17:12:34 +0000 (UTC) X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" When parsing cmd line which has "--" on it, this is leaked. Problem is, parser->getNextArg() allocates new string and stores it into tkdata. But as soon as "--" is detected 'continue' is issued without any free of the allocated memory. =3D=3D5304=3D=3D 3 bytes in 1 blocks are definitely lost in loss record 1= of 782 =3D=3D5304=3D=3D at 0x4C2AF50: malloc (vg_replace_malloc.c:299) =3D=3D5304=3D=3D by 0x8BB5AA9: strdup (strdup.c:42) =3D=3D5304=3D=3D by 0x55842CA: virStrdup (virstring.c:941) =3D=3D5304=3D=3D by 0x172B21: _vshStrdup (vsh.c:162) =3D=3D5304=3D=3D by 0x175E8E: vshCommandArgvGetArg (vsh.c:1622) =3D=3D5304=3D=3D by 0x17551D: vshCommandParse (vsh.c:1418) =3D=3D5304=3D=3D by 0x175F25: vshCommandArgvParse (vsh.c:1638) =3D=3D5304=3D=3D by 0x130940: virshParseArgv (virsh.c:820) =3D=3D5304=3D=3D by 0x130C49: main (virsh.c:922) Signed-off-by: Michal Privoznik --- tools/vsh.c | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/vsh.c b/tools/vsh.c index a21e1d1de..2366b7b71 100644 --- a/tools/vsh.c +++ b/tools/vsh.c @@ -1491,6 +1491,7 @@ vshCommandParse(vshControl *ctl, vshCommandParser *pa= rser) } } else if (tkdata[0] =3D=3D '-' && tkdata[1] =3D=3D '-' && tkdata[2] =3D=3D '\0') { + VIR_FREE(tkdata); data_only =3D true; continue; } else { --=20 2.13.6 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Sat May 4 07:37:05 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1514913155287866.051572240295; Tue, 2 Jan 2018 09:12:35 -0800 (PST) Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 8DFC27EA8B; Tue, 2 Jan 2018 17:12:33 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.21]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 60754614D0; Tue, 2 Jan 2018 17:12:33 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id 295CC3FCF9; Tue, 2 Jan 2018 17:12:33 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id w02HCQc0003078 for ; Tue, 2 Jan 2018 12:12:26 -0500 Received: by smtp.corp.redhat.com (Postfix) id A672C5C3F8; Tue, 2 Jan 2018 17:12:26 +0000 (UTC) Received: from localhost.localdomain (ovpn-204-45.brq.redhat.com [10.40.204.45]) by smtp.corp.redhat.com (Postfix) with ESMTP id 1966A5C89F for ; Tue, 2 Jan 2018 17:12:25 +0000 (UTC) From: Michal Privoznik To: libvir-list@redhat.com Date: Tue, 2 Jan 2018 18:11:57 +0100 Message-Id: <88ed9c6b9b6efffe5859928225bf6a9a60446f5f.1514911024.git.mprivozn@redhat.com> In-Reply-To: References: In-Reply-To: References: X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH 04/18] vshCommandStringParse: Allow retrieving partial result X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.28]); Tue, 02 Jan 2018 17:12:34 +0000 (UTC) X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" In the future, this function is going to be called from vshReadlineParse() to provide parsed input for completer callbacks. The idea is to allow the callbacks to provide more specific data. For instance, for the following input: virsh # domifaddr --domain fedora --interface the --interface completer callback is going to be called. Now, it is more user friendly if the completer offers only those interfaces found in 'fedora' domain. But in order to do that it needs to be able to retrieve partially parsed result. Signed-off-by: Michal Privoznik --- tools/virsh.c | 4 +- tools/virt-admin.c | 4 +- tools/vsh.c | 111 +++++++++++++++++++++++++++++++++++++------------= ---- tools/vsh.h | 2 +- 4 files changed, 82 insertions(+), 39 deletions(-) diff --git a/tools/virsh.c b/tools/virsh.c index 89a2bea10..933d6b4c9 100644 --- a/tools/virsh.c +++ b/tools/virsh.c @@ -817,7 +817,7 @@ virshParseArgv(vshControl *ctl, int argc, char **argv) ctl->imode =3D false; if (argc - optind =3D=3D 1) { vshDebug(ctl, VSH_ERR_INFO, "commands: \"%s\"\n", argv[optind]= ); - return vshCommandStringParse(ctl, argv[optind]); + return vshCommandStringParse(ctl, argv[optind], NULL); } else { return vshCommandArgvParse(ctl, argc - optind, argv + optind); } @@ -954,7 +954,7 @@ main(int argc, char **argv) #if WITH_READLINE add_history(ctl->cmdstr); #endif - if (vshCommandStringParse(ctl, ctl->cmdstr)) + if (vshCommandStringParse(ctl, ctl->cmdstr, NULL)) vshCommandRun(ctl, ctl->cmd); } VIR_FREE(ctl->cmdstr); diff --git a/tools/virt-admin.c b/tools/virt-admin.c index e529a2891..b8b33af19 100644 --- a/tools/virt-admin.c +++ b/tools/virt-admin.c @@ -1335,7 +1335,7 @@ vshAdmParseArgv(vshControl *ctl, int argc, char **arg= v) ctl->imode =3D false; if (argc - optind =3D=3D 1) { vshDebug(ctl, VSH_ERR_INFO, "commands: \"%s\"\n", argv[optind]= ); - return vshCommandStringParse(ctl, argv[optind]); + return vshCommandStringParse(ctl, argv[optind], NULL); } else { return vshCommandArgvParse(ctl, argc - optind, argv + optind); } @@ -1555,7 +1555,7 @@ main(int argc, char **argv) #if WITH_READLINE add_history(ctl->cmdstr); #endif - if (vshCommandStringParse(ctl, ctl->cmdstr)) + if (vshCommandStringParse(ctl, ctl->cmdstr, NULL)) vshCommandRun(ctl, ctl->cmd); } VIR_FREE(ctl->cmdstr); diff --git a/tools/vsh.c b/tools/vsh.c index 2366b7b71..34eb592ef 100644 --- a/tools/vsh.c +++ b/tools/vsh.c @@ -1386,26 +1386,34 @@ struct _vshCommandParser { }; =20 static bool -vshCommandParse(vshControl *ctl, vshCommandParser *parser) +vshCommandParse(vshControl *ctl, vshCommandParser *parser, vshCmd **partia= l) { char *tkdata =3D NULL; vshCmd *clast =3D NULL; vshCmdOpt *first =3D NULL; + const vshCmdDef *cmd =3D NULL; =20 - vshCommandFree(ctl->cmd); - ctl->cmd =3D NULL; + if (!partial) { + vshCommandFree(ctl->cmd); + ctl->cmd =3D NULL; + } =20 while (1) { vshCmdOpt *last =3D NULL; - const vshCmdDef *cmd =3D NULL; vshCommandToken tk; bool data_only =3D false; uint64_t opts_need_arg =3D 0; uint64_t opts_required =3D 0; uint64_t opts_seen =3D 0; =20 + cmd =3D NULL; first =3D NULL; =20 + if (partial) { + vshCommandFree(*partial); + *partial =3D NULL; + } + while (1) { const vshCmdOptDef *opt =3D NULL; =20 @@ -1422,7 +1430,8 @@ vshCommandParse(vshControl *ctl, vshCommandParser *pa= rser) if (cmd =3D=3D NULL) { /* first token must be command name */ if (!(cmd =3D vshCmddefSearch(tkdata))) { - vshError(ctl, _("unknown command: '%s'"), tkdata); + if (!partial) + vshError(ctl, _("unknown command: '%s'"), tkdata); goto syntaxError; /* ... or ignore this command only= ? */ } =20 @@ -1434,9 +1443,10 @@ vshCommandParse(vshControl *ctl, vshCommandParser *p= arser) } if (vshCmddefOptParse(cmd, &opts_need_arg, &opts_required) < 0) { - vshError(ctl, - _("internal error: bad options in command: '%= s'"), - tkdata); + if (!partial) + vshError(ctl, + _("internal error: bad options in command= : '%s'"), + tkdata); goto syntaxError; } VIR_FREE(tkdata); @@ -1454,7 +1464,7 @@ vshCommandParse(vshControl *ctl, vshCommandParser *pa= rser) /* Special case 'help' to ignore all spurious options */ if (!(opt =3D vshCmddefGetOption(ctl, cmd, tkdata + 2, &opts_seen, &opt_index, - &optstr, true))) { + &optstr, partial =3D=3D NUL= L))) { VIR_FREE(optstr); if (STREQ(cmd->name, "help")) continue; @@ -1471,11 +1481,24 @@ vshCommandParse(vshControl *ctl, vshCommandParser *= parser) if (tk =3D=3D VSH_TK_ERROR) goto syntaxError; if (tk !=3D VSH_TK_ARG) { - vshError(ctl, - _("expected syntax: --%s <%s>"), - opt->name, - opt->type =3D=3D - VSH_OT_INT ? _("number") : _("string")); + if (partial) { + vshCmdOpt *arg =3D vshMalloc(ctl, sizeof(vshCm= dOpt)); + arg->def =3D opt; + arg->data =3D tkdata; + tkdata =3D NULL; + arg->next =3D NULL; + if (!first) + first =3D arg; + if (last) + last->next =3D arg; + last =3D arg; + } else { + vshError(ctl, + _("expected syntax: --%s <%s>"), + opt->name, + opt->type =3D=3D + VSH_OT_INT ? _("number") : _("string"= )); + } goto syntaxError; } if (opt->type !=3D VSH_OT_ARGV) @@ -1483,8 +1506,9 @@ vshCommandParse(vshControl *ctl, vshCommandParser *pa= rser) } else { tkdata =3D NULL; if (optstr) { - vshError(ctl, _("invalid '=3D' after option --%s"), - opt->name); + if (!partial) + vshError(ctl, _("invalid '=3D' after option --= %s"), + opt->name); VIR_FREE(optstr); goto syntaxError; } @@ -1500,7 +1524,8 @@ vshCommandParse(vshControl *ctl, vshCommandParser *pa= rser) if (!(opt =3D vshCmddefGetData(cmd, &opts_need_arg, &opts_seen)) && STRNEQ(cmd->name, "help")) { - vshError(ctl, _("unexpected data '%s'"), tkdata); + if (!partial) + vshError(ctl, _("unexpected data '%s'"), tkdata); goto syntaxError; } } @@ -1519,11 +1544,12 @@ vshCommandParse(vshControl *ctl, vshCommandParser *= parser) last->next =3D arg; last =3D arg; =20 - vshDebug(ctl, VSH_ERR_INFO, "%s: %s(%s): %s\n", - cmd->name, - opt->name, - opt->type !=3D VSH_OT_BOOL ? _("optdata") : _("bo= ol"), - opt->type !=3D VSH_OT_BOOL ? arg->data : _("(none= )")); + if (ctl) + vshDebug(ctl, VSH_ERR_INFO, "%s: %s(%s): %s\n", + cmd->name, + opt->name, + opt->type !=3D VSH_OT_BOOL ? _("optdata") : _= ("bool"), + opt->type !=3D VSH_OT_BOOL ? arg->data : _("(= none)")); } } =20 @@ -1555,17 +1581,24 @@ vshCommandParse(vshControl *ctl, vshCommandParser *= parser) c->opts =3D first; c->def =3D cmd; c->next =3D NULL; + first =3D NULL; =20 - if (vshCommandCheckOpts(ctl, c, opts_required, opts_seen) < 0)= { + if (!partial && + vshCommandCheckOpts(ctl, c, opts_required, opts_seen) < 0)= { VIR_FREE(c); goto syntaxError; } =20 - if (!ctl->cmd) - ctl->cmd =3D c; - if (clast) - clast->next =3D c; - clast =3D c; + if (partial) { + vshCommandFree(*partial); + *partial =3D c; + } else { + if (!ctl->cmd) + ctl->cmd =3D c; + if (clast) + clast->next =3D c; + clast =3D c; + } } =20 if (tk =3D=3D VSH_TK_END) @@ -1575,9 +1608,19 @@ vshCommandParse(vshControl *ctl, vshCommandParser *p= arser) return true; =20 syntaxError: - vshCommandFree(ctl->cmd); - ctl->cmd =3D NULL; - vshCommandOptFree(first); + if (partial) { + vshCmd *tmp; + + tmp =3D vshMalloc(ctl, sizeof(*tmp)); + tmp->opts =3D first; + tmp->def =3D cmd; + + *partial =3D tmp; + } else { + vshCommandFree(ctl->cmd); + ctl->cmd =3D NULL; + vshCommandOptFree(first); + } VIR_FREE(tkdata); return false; } @@ -1612,7 +1655,7 @@ vshCommandArgvParse(vshControl *ctl, int nargs, char = **argv) parser.arg_pos =3D argv; parser.arg_end =3D argv + nargs; parser.getNextArg =3D vshCommandArgvGetArg; - return vshCommandParse(ctl, &parser); + return vshCommandParse(ctl, &parser, NULL); } =20 /* ---------------------- @@ -1684,7 +1727,7 @@ vshCommandStringGetArg(vshControl *ctl, vshCommandPar= ser *parser, char **res, } =20 bool -vshCommandStringParse(vshControl *ctl, char *cmdstr) +vshCommandStringParse(vshControl *ctl, char *cmdstr, vshCmd **partial) { vshCommandParser parser; =20 @@ -1693,7 +1736,7 @@ vshCommandStringParse(vshControl *ctl, char *cmdstr) =20 parser.pos =3D cmdstr; parser.getNextArg =3D vshCommandStringGetArg; - return vshCommandParse(ctl, &parser); + return vshCommandParse(ctl, &parser, partial); } =20 /** diff --git a/tools/vsh.h b/tools/vsh.h index ab755bccf..8f7df9ff8 100644 --- a/tools/vsh.h +++ b/tools/vsh.h @@ -299,7 +299,7 @@ int vshBlockJobOptionBandwidth(vshControl *ctl, unsigned long *bandwidth); bool vshCommandOptBool(const vshCmd *cmd, const char *name); bool vshCommandRun(vshControl *ctl, const vshCmd *cmd); -bool vshCommandStringParse(vshControl *ctl, char *cmdstr); +bool vshCommandStringParse(vshControl *ctl, char *cmdstr, vshCmd **partial= ); =20 const vshCmdOpt *vshCommandOptArgv(vshControl *ctl, const vshCmd *cmd, const vshCmdOpt *opt); --=20 2.13.6 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Sat May 4 07:37:05 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1514913154827482.0807889463765; Tue, 2 Jan 2018 09:12:34 -0800 (PST) Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 865497EA84; Tue, 2 Jan 2018 17:12:33 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.21]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 62CE160C99; Tue, 2 Jan 2018 17:12:33 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id 298E23FCFB; Tue, 2 Jan 2018 17:12:33 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id w02HCVoW003099 for ; Tue, 2 Jan 2018 12:12:31 -0500 Received: by smtp.corp.redhat.com (Postfix) id 97F9E5C3F8; Tue, 2 Jan 2018 17:12:31 +0000 (UTC) Received: from localhost.localdomain (ovpn-204-45.brq.redhat.com [10.40.204.45]) by smtp.corp.redhat.com (Postfix) with ESMTP id 0BF7E5C890 for ; Tue, 2 Jan 2018 17:12:26 +0000 (UTC) From: Michal Privoznik To: libvir-list@redhat.com Date: Tue, 2 Jan 2018 18:11:58 +0100 Message-Id: In-Reply-To: References: In-Reply-To: References: X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH 05/18] vshReadlineParse: Drop code duplication X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.28]); Tue, 02 Jan 2018 17:12:33 +0000 (UTC) X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" Now that we have a way of retrieving partly parsed command we don't need duplicate code that parses the user's input. Yes, this code removes call of opt's completer, but: a) current implementation is broken anyway, and b) it will be added back shortly Signed-off-by: Michal Privoznik --- tools/vsh.c | 214 +++++++-------------------------------------------------= ---- 1 file changed, 24 insertions(+), 190 deletions(-) diff --git a/tools/vsh.c b/tools/vsh.c index 34eb592ef..c3423d6e3 100644 --- a/tools/vsh.c +++ b/tools/vsh.c @@ -2697,216 +2697,50 @@ vshReadlineOptionsGenerator(const char *text, int = state, const vshCmdDef *cmd_pa static char * vshReadlineParse(const char *text, int state) { - static vshCommandParser parser, sanitizer; - vshCommandToken tk; + static vshCmd *partial; static const vshCmdDef *cmd; - const vshCmdOptDef *opt =3D NULL; - char *tkdata, *optstr, *const_tkdata, *completed_name; char *res =3D NULL; - static char *ctext, *sanitized_text; - static char **completed_list; - static unsigned int completed_list_index; - static uint64_t const_opts_need_arg, const_opts_required, const_opts_s= een; - uint64_t opts_seen; - size_t opt_index; - static bool cmd_exists, opts_filled, opt_exists; - static bool non_bool_opt_exists, data_complete; =20 if (!state) { - parser.pos =3D rl_line_buffer; - parser.getNextArg =3D vshCommandStringGetArg; - - ctext =3D vshStrdup(NULL, text); - sanitizer.pos =3D ctext; - sanitizer.getNextArg =3D vshCommandStringGetArg; - - const_tkdata =3D NULL; - tkdata =3D NULL; - sanitized_text =3D NULL; - optstr =3D NULL; - - completed_list =3D NULL; - completed_list_index =3D 0; - - /* Sanitize/de-quote the autocomplete text */ - tk =3D sanitizer.getNextArg(NULL, &sanitizer, &sanitized_text, fal= se); - - /* No autocomplete if sanitized text is a token error or token end= */ - if (tk =3D=3D VSH_TK_ERROR) - goto error; - - tk =3D parser.getNextArg(NULL, &parser, &const_tkdata, false); - - if (tk =3D=3D VSH_TK_ERROR) - goto error; - - /* Free-ing purposes */ - tkdata =3D const_tkdata; - /* Skip leading space */ - virSkipSpaces((const char**)&tkdata); - - /* Handle ';'s */ - while (tk =3D=3D VSH_TK_SUBCMD_END) { - tk =3D parser.getNextArg(NULL, &parser, &const_tkdata, false); - tkdata =3D const_tkdata; - } - - /* Skip trailing space after ;*/ - virSkipSpaces((const char**)&tkdata); - - cmd_exists =3D false; - opts_filled =3D false; - non_bool_opt_exists =3D false; - data_complete =3D false; - - const_opts_need_arg =3D 0; - const_opts_required =3D 0; - const_opts_seen =3D 0; - - opt_index =3D 0; + char *buf =3D vshStrdup(NULL, rl_line_buffer); =20 + vshCommandFree(partial); + partial =3D NULL; cmd =3D NULL; - opt =3D NULL; =20 - /* Parse till text to be auto-completed is reached */ - while (STRNEQ(tkdata, sanitized_text)) { - if (!cmd) { - if (!(cmd =3D vshCmddefSearch(tkdata))) - goto error; - if (cmd->flags & VSH_CMD_FLAG_ALIAS) - cmd =3D vshCmddefSearch(cmd->alias); + *(buf + rl_point) =3D '\0'; =20 - cmd_exists =3D true; - if (vshCmddefOptParse(cmd, &const_opts_need_arg, - &const_opts_required) < 0) - goto error; - opts_seen =3D const_opts_seen; - opts_filled =3D true; - } else if (tkdata[0] =3D=3D '-' && tkdata[1] =3D=3D '-' && - c_isalnum(tkdata[2])) { - /* Command retrieved successfully, move to options */ - optstr =3D strchr(tkdata + 2, '=3D'); - opt_index =3D 0; + vshCommandStringParse(NULL, buf, &partial); =20 - if (optstr) { - *optstr =3D '\0'; - optstr =3D vshStrdup(NULL, optstr + 1); - } + VIR_FREE(buf); =20 - if (!(opt =3D vshCmddefGetOption(NULL, cmd, tkdata + 2, - &opts_seen, &opt_index, - &optstr, false))) { - /* Parsing failed wrt autocomplete */ - VIR_FREE(optstr); - goto error; - } + if (partial) + cmd =3D partial->def; =20 - opts_seen =3D const_opts_seen; - opt_exists =3D true; - VIR_FREE(const_tkdata); - if (opt->type !=3D VSH_OT_BOOL) { - non_bool_opt_exists =3D true; - /* Opt exists and check for option data */ - if (optstr) { - const_tkdata =3D optstr; - tkdata =3D const_tkdata; - } else { - VIR_FREE(const_tkdata); - tk =3D parser.getNextArg(NULL, &parser, &const_tkd= ata, - false); - - if (tk =3D=3D VSH_TK_ERROR) - goto error; - - tkdata =3D const_tkdata; - virSkipSpaces((const char **)&tkdata); - } - if (STREQ(tkdata, sanitized_text)) { - /* auto-complete non-bool option arg */ - data_complete =3D true; - break; - } - non_bool_opt_exists =3D false; - } else { - tkdata =3D NULL; - /* opt type is BOOL */ - if (optstr) { - VIR_FREE(optstr); - goto error; - } - } - } else if (!opt_exists) { - /* No -- option provided and some other token given - * Try to find the default option. - */ - if (!(opt =3D vshCmddefGetData(cmd, &const_opts_need_arg, - &const_opts_seen)) - || opt->type =3D=3D VSH_OT_BOOL) - goto error; - opt_exists =3D true; - opts_seen =3D const_opts_seen; - } else { - /* In every other case, return NULL */ - goto error; - } - - VIR_FREE(const_tkdata); - tk =3D parser.getNextArg(NULL, &parser, &const_tkdata, false); - - if (tk =3D=3D VSH_TK_ERROR) - goto error; - - while (tk =3D=3D VSH_TK_SUBCMD_END) { - cmd =3D NULL; - cmd_exists =3D false; - opts_filled =3D false; - opt =3D NULL; - non_bool_opt_exists =3D false; - tk =3D parser.getNextArg(NULL, &parser, &const_tkdata, fal= se); - } - - tkdata =3D const_tkdata; - - virSkipSpaces((const char**)&tkdata); + if (cmd && STREQ(cmd->name, text)) { + /* Corner case - some commands share prefix (e.g. + * dump and dumpxml). If user typed 'dump', + * then @text =3D "dump" and we want to offer command + * completion. If they typed 'dump ' then + * @text =3D "" (the space after the command) and we + * want to offer options completion for dump command. + */ + cmd =3D NULL; } - VIR_FREE(const_tkdata); } =20 - if (!cmd_exists) { - res =3D vshReadlineCommandGenerator(sanitized_text, state); - } else if (opts_filled && !non_bool_opt_exists) { - res =3D vshReadlineOptionsGenerator(sanitized_text, state, cmd); - } else if (non_bool_opt_exists && data_complete && opt && opt->complet= er) { - if (!completed_list) - completed_list =3D opt->completer(autoCompleteOpaque, - opt->completer_flags); - if (completed_list) { - while ((completed_name =3D completed_list[completed_list_index= ])) { - completed_list_index++; - if (!STRPREFIX(completed_name, sanitized_text)) - continue; - res =3D vshStrdup(NULL, completed_name); - return res; - } - res =3D NULL; - virStringListFree(completed_list); - completed_list_index =3D 0; - } + if (!cmd) { + res =3D vshReadlineCommandGenerator(text, state); + } else { + res =3D vshReadlineOptionsGenerator(text, state, cmd); } =20 if (!res) { - VIR_FREE(sanitized_text); - VIR_FREE(ctext); + vshCommandFree(partial); + partial =3D NULL; } =20 return res; - - error: - VIR_FREE(const_tkdata); - VIR_FREE(sanitized_text); - VIR_FREE(ctext); - return NULL; - } =20 static char ** --=20 2.13.6 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Sat May 4 07:37:05 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1514913158713579.709423994741; Tue, 2 Jan 2018 09:12:38 -0800 (PST) Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 5869F4901B; Tue, 2 Jan 2018 17:12:37 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.20]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 3017B60BE2; Tue, 2 Jan 2018 17:12:37 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id EB329180474F; Tue, 2 Jan 2018 17:12:36 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id w02HCWMr003105 for ; Tue, 2 Jan 2018 12:12:32 -0500 Received: by smtp.corp.redhat.com (Postfix) id B702A171BE; Tue, 2 Jan 2018 17:12:32 +0000 (UTC) Received: from localhost.localdomain (ovpn-204-45.brq.redhat.com [10.40.204.45]) by smtp.corp.redhat.com (Postfix) with ESMTP id 29E115C3F8 for ; Tue, 2 Jan 2018 17:12:31 +0000 (UTC) From: Michal Privoznik To: libvir-list@redhat.com Date: Tue, 2 Jan 2018 18:11:59 +0100 Message-Id: <99f42cc7c98de7be64940caa7ba1d05896b27ecd.1514911024.git.mprivozn@redhat.com> In-Reply-To: References: In-Reply-To: References: X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH 06/18] vshReadlineParse: Escape returned results if needed X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.38]); Tue, 02 Jan 2018 17:12:37 +0000 (UTC) X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" When returning a string that needs escaping there are two scenarios that can happen. Firstly, user already started the string with a quote (or double quote) in which case we don't need to do anything - readline takes care of that. However, if they haven't typed anything yet, we need to escape the string ourselves. Signed-off-by: Michal Privoznik --- tools/vsh.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/tools/vsh.c b/tools/vsh.c index c3423d6e3..bcabf4231 100644 --- a/tools/vsh.c +++ b/tools/vsh.c @@ -2735,6 +2735,14 @@ vshReadlineParse(const char *text, int state) res =3D vshReadlineOptionsGenerator(text, state, cmd); } =20 + if (res && + !rl_completion_quote_character) { + virBuffer buf =3D VIR_BUFFER_INITIALIZER; + virBufferEscapeShell(&buf, res); + VIR_FREE(res); + res =3D virBufferContentAndReset(&buf); + } + if (!res) { vshCommandFree(partial); partial =3D NULL; @@ -2754,6 +2762,16 @@ vshReadlineCompletion(const char *text, return matches; } =20 + +static int +vshReadlineCharIsQuoted(char *line, int idx) +{ + return idx > 0 && + line[idx - 1] =3D=3D '\\' && + !vshReadlineCharIsQuoted(line, idx - 1); +} + + # define HISTSIZE_MAX 500000 =20 static int @@ -2765,6 +2783,7 @@ vshReadlineInit(vshControl *ctl) char *histsize_env =3D NULL; const char *histsize_str =3D NULL; const char *break_characters =3D " \t\n\\`@$><=3D;|&{("; + const char *quote_characters =3D "\"'"; =20 /* Opaque data for autocomplete callbacks. */ autoCompleteOpaque =3D ctl; @@ -2788,6 +2807,14 @@ vshReadlineInit(vshControl *ctl) rl_basic_word_break_characters =3D (char *) break_characters; # endif =20 +# if defined(RL_READLINE_VERSION) && RL_READLINE_VERSION > 0x0402 + rl_completer_quote_characters =3D quote_characters; + rl_char_is_quoted_p =3D vshReadlineCharIsQuoted; +# else + rl_completer_quote_characters =3D (char *) quote_characters; + rl_char_is_quoted_p =3D (Function *) vshReadlineCharIsQuoted; +# endif + if (virAsprintf(&histsize_env, "%s_HISTSIZE", ctl->env_prefix) < 0) goto cleanup; =20 --=20 2.13.6 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Sat May 4 07:37:05 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1514913157820963.4237469328752; Tue, 2 Jan 2018 09:12:37 -0800 (PST) Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 7068D7EA97; Tue, 2 Jan 2018 17:12:36 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.20]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 358A05EE0C; Tue, 2 Jan 2018 17:12:36 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id EA61E180474E; Tue, 2 Jan 2018 17:12:35 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id w02HCXuw003118 for ; Tue, 2 Jan 2018 12:12:33 -0500 Received: by smtp.corp.redhat.com (Postfix) id D4DDD171BE; Tue, 2 Jan 2018 17:12:33 +0000 (UTC) Received: from localhost.localdomain (ovpn-204-45.brq.redhat.com [10.40.204.45]) by smtp.corp.redhat.com (Postfix) with ESMTP id 448765C890 for ; Tue, 2 Jan 2018 17:12:32 +0000 (UTC) From: Michal Privoznik To: libvir-list@redhat.com Date: Tue, 2 Jan 2018 18:12:00 +0100 Message-Id: In-Reply-To: References: In-Reply-To: References: X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH 07/18] vshReadlineParse: Use string list X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.28]); Tue, 02 Jan 2018 17:12:37 +0000 (UTC) X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" It's better to fetch list of either commands or options just once and then iterate over it. Moreover, it makes future completers way simpler as they will return string lists too. Signed-off-by: Michal Privoznik --- tools/vsh.c | 121 ++++++++++++++++++++++++++++++++++++--------------------= ---- 1 file changed, 73 insertions(+), 48 deletions(-) diff --git a/tools/vsh.c b/tools/vsh.c index bcabf4231..ebc8d9cb1 100644 --- a/tools/vsh.c +++ b/tools/vsh.c @@ -2605,25 +2605,25 @@ vshTreePrint(vshControl *ctl, vshTreeLookup lookup,= void *opaque, * ----------------- */ =20 -/* - * Generator function for command completion. STATE lets us - * know whether to start from scratch; without any state - * (i.e. STATE =3D=3D 0), then we start at the top of the list. +/** + * vshReadlineCommandGenerator: + * @text: optional command prefix + * + * Generator function for command completion. + * + * Returns a string list of commands with @text prefix, + * NULL if there's no such command. */ -static char * -vshReadlineCommandGenerator(const char *text, int state) +static char ** +vshReadlineCommandGenerator(const char *text) { - static unsigned int grp_list_index, cmd_list_index; - static size_t len; + size_t grp_list_index =3D 0, cmd_list_index =3D 0; + size_t len =3D strlen(text); const char *name; const vshCmdGrp *grp; const vshCmdDef *cmds; - - if (!state) { - grp_list_index =3D 0; - cmd_list_index =3D 0; - len =3D strlen(text); - } + size_t ret_size =3D 0; + char **ret =3D NULL; =20 grp =3D cmdGroups; =20 @@ -2638,8 +2638,16 @@ vshReadlineCommandGenerator(const char *text, int st= ate) if (cmds[cmd_list_index++].flags & VSH_CMD_FLAG_ALIAS) continue; =20 - if (STREQLEN(name, text, len)) - return vshStrdup(NULL, name); + if (STREQLEN(name, text, len)) { + if (VIR_REALLOC_N(ret, ret_size + 2) < 0) { + virStringListFree(ret); + return NULL; + } + ret[ret_size] =3D vshStrdup(NULL, name); + ret_size++; + /* Terminate the string list properly. */ + ret[ret_size] =3D NULL; + } } } else { cmd_list_index =3D 0; @@ -2647,23 +2655,17 @@ vshReadlineCommandGenerator(const char *text, int s= tate) } } =20 - /* If no names matched, then return NULL. */ - return NULL; + return ret; } =20 -static char * -vshReadlineOptionsGenerator(const char *text, int state, const vshCmdDef *= cmd_parsed) +static char ** +vshReadlineOptionsGenerator(const char *text, const vshCmdDef *cmd) { - static unsigned int list_index; - static size_t len; - static const vshCmdDef *cmd; + size_t list_index =3D 0; + size_t len =3D strlen(text); const char *name; - - if (!state) { - cmd =3D cmd_parsed; - list_index =3D 0; - len =3D strlen(text); - } + size_t ret_size =3D 0; + char **ret =3D NULL; =20 if (!cmd) return NULL; @@ -2672,7 +2674,7 @@ vshReadlineOptionsGenerator(const char *text, int sta= te, const vshCmdDef *cmd_pa return NULL; =20 while ((name =3D cmd->opts[list_index].name)) { - char *res; + size_t name_len; =20 list_index++; =20 @@ -2685,28 +2687,40 @@ vshReadlineOptionsGenerator(const char *text, int s= tate, const vshCmdDef *cmd_pa } else if (STRNEQLEN(text, "--", len)) { return NULL; } - res =3D vshMalloc(NULL, strlen(name) + 3); - snprintf(res, strlen(name) + 3, "--%s", name); - return res; + + if (VIR_REALLOC_N(ret, ret_size + 2) < 0) { + virStringListFree(ret); + return NULL; + } + + name_len =3D strlen(name); + ret[ret_size] =3D vshMalloc(NULL, name_len + 3); + snprintf(ret[ret_size], name_len + 3, "--%s", name); + ret_size++; + /* Terminate the string list properly. */ + ret[ret_size] =3D NULL; } =20 - /* If no names matched, then return NULL. */ - return NULL; + return ret; } =20 static char * vshReadlineParse(const char *text, int state) { static vshCmd *partial; - static const vshCmdDef *cmd; - char *res =3D NULL; + static char **list; + static size_t list_index; + const vshCmdDef *cmd =3D NULL; + char *ret =3D NULL; =20 if (!state) { char *buf =3D vshStrdup(NULL, rl_line_buffer); =20 vshCommandFree(partial); partial =3D NULL; - cmd =3D NULL; + virStringListFree(list); + list =3D NULL; + list_index =3D 0; =20 *(buf + rl_point) =3D '\0'; =20 @@ -2729,26 +2743,37 @@ vshReadlineParse(const char *text, int state) } } =20 - if (!cmd) { - res =3D vshReadlineCommandGenerator(text, state); - } else { - res =3D vshReadlineOptionsGenerator(text, state, cmd); + if (!list) { + if (!cmd) { + list =3D vshReadlineCommandGenerator(text); + } else { + list =3D vshReadlineOptionsGenerator(text, cmd); + } } =20 - if (res && + if (list) { + ret =3D vshStrdup(NULL, list[list_index]); + list_index++; + } + + if (ret && !rl_completion_quote_character) { virBuffer buf =3D VIR_BUFFER_INITIALIZER; - virBufferEscapeShell(&buf, res); - VIR_FREE(res); - res =3D virBufferContentAndReset(&buf); + virBufferEscapeShell(&buf, ret); + VIR_FREE(ret); + ret =3D virBufferContentAndReset(&buf); } =20 - if (!res) { + if (!ret) { vshCommandFree(partial); partial =3D NULL; + virStringListFree(list); + list =3D NULL; + list_index =3D 0; } =20 - return res; + return ret; + } =20 static char ** --=20 2.13.6 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Sat May 4 07:37:05 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1515688747718538.3676526213995; Thu, 11 Jan 2018 08:39:07 -0800 (PST) Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 7EAC46412C; Thu, 11 Jan 2018 16:39:05 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.21]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 1C15460C4B; Thu, 11 Jan 2018 16:39:02 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id 81A033FB18; Thu, 11 Jan 2018 16:38:58 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id w0BGcuNq009745 for ; Thu, 11 Jan 2018 11:38:56 -0500 Received: by smtp.corp.redhat.com (Postfix) id 97AA39098; Thu, 11 Jan 2018 16:38:56 +0000 (UTC) Received: from localhost.localdomain (ovpn-204-118.brq.redhat.com [10.40.204.118]) by smtp.corp.redhat.com (Postfix) with ESMTP id 32B986017B; Thu, 11 Jan 2018 16:38:52 +0000 (UTC) From: Michal Privoznik To: libvir-list@redhat.com Date: Thu, 11 Jan 2018 17:38:50 +0100 Message-Id: <4e9cae0debdce8299f8a960c98bae8c37c98b601.1515688098.git.mprivozn@redhat.com> In-Reply-To: References: X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 X-loop: libvir-list@redhat.com Cc: mkletzan@redhat.com Subject: [libvirt] [PATCH 08/18 v2] vshCommandOpt: Allow caller avoiding assert() X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.39]); Thu, 11 Jan 2018 16:39:06 +0000 (UTC) X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" In the future, completer callbacks will receive partially parsed command (and thus possibly incomplete). However, we still want them to use command options fetching APIs we already have (e.g. vshCommandOpt*()) and at the same time don't report any errors (nor call any asserts). Signed-off-by: Michal Privoznik Reviewed-by: John Ferlan --- tools/vsh.c | 24 ++++++++++++++---------- tools/vsh.h | 3 ++- 2 files changed, 16 insertions(+), 11 deletions(-) diff --git a/tools/vsh.c b/tools/vsh.c index 54e59fff6..b113c8c95 100644 --- a/tools/vsh.c +++ b/tools/vsh.c @@ -815,8 +815,8 @@ vshCommandFree(vshCmd *cmd) * to the option if found, 0 with *OPT set to NULL if the name is * valid and the option is not required, -1 with *OPT set to NULL if * the option is required but not present, and assert if NAME is not - * valid (which indicates a programming error). No error messages are - * issued if a value is returned. + * valid (which indicates a programming error) unless cmd->skipChecks + * is set. No error messages are issued if a value is returned. */ static int vshCommandOpt(const vshCmd *cmd, const char *name, vshCmdOpt **opt, @@ -828,15 +828,19 @@ vshCommandOpt(const vshCmd *cmd, const char *name, vs= hCmdOpt **opt, =20 /* See if option is valid and/or required. */ *opt =3D NULL; - while (valid) { - assert(valid->name); - if (STREQ(name, valid->name)) - break; - valid++; + + if (!cmd->skipChecks) { + while (valid && valid->name) { + if (STREQ(name, valid->name)) + break; + valid++; + } + + assert(valid && (!needData || valid->type !=3D VSH_OT_BOOL)); + + if (valid->flags & VSH_OFLAG_REQ) + ret =3D -1; } - assert(!needData || valid->type !=3D VSH_OT_BOOL); - if (valid->flags & VSH_OFLAG_REQ) - ret =3D -1; =20 /* See if option is present on command line. */ while (candidate) { diff --git a/tools/vsh.h b/tools/vsh.h index 8f7df9ff8..112b1b57d 100644 --- a/tools/vsh.h +++ b/tools/vsh.h @@ -188,7 +188,8 @@ struct _vshCmdDef { struct _vshCmd { const vshCmdDef *def; /* command definition */ vshCmdOpt *opts; /* list of command arguments */ - vshCmd *next; /* next command */ + vshCmd *next; /* next command */ + bool skipChecks; /* skip validity checks when retrieving op= ts */ }; =20 /* --=20 2.13.6 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Sat May 4 07:37:05 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1514913160496175.16580505447314; Tue, 2 Jan 2018 09:12:40 -0800 (PST) Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 3FFC6C060208; Tue, 2 Jan 2018 17:12:39 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.20]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 173D3600CC; Tue, 2 Jan 2018 17:12:39 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id CBE4F1803B20; Tue, 2 Jan 2018 17:12:38 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id w02HCYxv003128 for ; Tue, 2 Jan 2018 12:12:34 -0500 Received: by smtp.corp.redhat.com (Postfix) id DA6FC171BE; Tue, 2 Jan 2018 17:12:34 +0000 (UTC) Received: from localhost.localdomain (ovpn-204-45.brq.redhat.com [10.40.204.45]) by smtp.corp.redhat.com (Postfix) with ESMTP id 4E8705C3F8 for ; Tue, 2 Jan 2018 17:12:34 +0000 (UTC) From: Michal Privoznik To: libvir-list@redhat.com Date: Tue, 2 Jan 2018 18:12:01 +0100 Message-Id: <51284359ef94b281ac6c81017bdc11f4900682d7.1514911024.git.mprivozn@redhat.com> In-Reply-To: References: In-Reply-To: References: X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH 08/18] vshCommandOpt: Allow caller avoiding assert() X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.32]); Tue, 02 Jan 2018 17:12:39 +0000 (UTC) X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" In the future, completer callbacks will receive partially parsed command (and thus possibly incomplete). However, we still want them to use command options fetching APIs we already have (e.g. vshCommandOpt*()) and at the same time don't report any errors (nor call any asserts). Signed-off-by: Michal Privoznik --- tools/vsh.c | 7 ++++--- tools/vsh.h | 3 ++- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/tools/vsh.c b/tools/vsh.c index ebc8d9cb1..d27acb95b 100644 --- a/tools/vsh.c +++ b/tools/vsh.c @@ -815,8 +815,8 @@ vshCommandFree(vshCmd *cmd) * to the option if found, 0 with *OPT set to NULL if the name is * valid and the option is not required, -1 with *OPT set to NULL if * the option is required but not present, and assert if NAME is not - * valid (which indicates a programming error). No error messages are - * issued if a value is returned. + * valid (which indicates a programming error) unless cmd->skipChecks + * is set. No error messages are issued if a value is returned. */ static int vshCommandOpt(const vshCmd *cmd, const char *name, vshCmdOpt **opt, @@ -829,7 +829,8 @@ vshCommandOpt(const vshCmd *cmd, const char *name, vshC= mdOpt **opt, /* See if option is valid and/or required. */ *opt =3D NULL; while (valid) { - assert(valid->name); + if (!cmd->skipChecks) + assert(valid->name); if (STREQ(name, valid->name)) break; valid++; diff --git a/tools/vsh.h b/tools/vsh.h index 8f7df9ff8..112b1b57d 100644 --- a/tools/vsh.h +++ b/tools/vsh.h @@ -188,7 +188,8 @@ struct _vshCmdDef { struct _vshCmd { const vshCmdDef *def; /* command definition */ vshCmdOpt *opts; /* list of command arguments */ - vshCmd *next; /* next command */ + vshCmd *next; /* next command */ + bool skipChecks; /* skip validity checks when retrieving op= ts */ }; =20 /* --=20 2.13.6 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Sat May 4 07:37:05 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1514913161579284.3609947967659; Tue, 2 Jan 2018 09:12:41 -0800 (PST) Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 4AA11C065857; Tue, 2 Jan 2018 17:12:40 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.21]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 245B25EDE4; Tue, 2 Jan 2018 17:12:40 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id E0EBC3FA5B; Tue, 2 Jan 2018 17:12:39 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id w02HCZX8003137 for ; Tue, 2 Jan 2018 12:12:35 -0500 Received: by smtp.corp.redhat.com (Postfix) id D17515C888; Tue, 2 Jan 2018 17:12:35 +0000 (UTC) Received: from localhost.localdomain (ovpn-204-45.brq.redhat.com [10.40.204.45]) by smtp.corp.redhat.com (Postfix) with ESMTP id 41ACA17557 for ; Tue, 2 Jan 2018 17:12:35 +0000 (UTC) From: Michal Privoznik To: libvir-list@redhat.com Date: Tue, 2 Jan 2018 18:12:02 +0100 Message-Id: <837ee22a9b38d408913006d481cbf6a8f38a20bb.1514911024.git.mprivozn@redhat.com> In-Reply-To: References: In-Reply-To: References: X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH 09/18] util: Introduce virStringListMerge X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.32]); Tue, 02 Jan 2018 17:12:40 +0000 (UTC) X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" For two string lists merge one into the other one. Signed-off-by: Michal Privoznik --- src/libvirt_private.syms | 1 + src/util/virstring.c | 36 ++++++++++++++++++++++++++++++++++++ src/util/virstring.h | 3 +++ 3 files changed, 40 insertions(+) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index d5c3b9abb..d807cdca6 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -2764,6 +2764,7 @@ virStringListGetFirstWithPrefix; virStringListHasString; virStringListJoin; virStringListLength; +virStringListMerge; virStringListRemove; virStringMatch; virStringParsePort; diff --git a/src/util/virstring.c b/src/util/virstring.c index b2ebce27f..47d9efba2 100644 --- a/src/util/virstring.c +++ b/src/util/virstring.c @@ -239,6 +239,42 @@ virStringListRemove(char ***strings, } =20 =20 +/** + * virStringListMerge: + * @dst: a NULL-terminated array of strings to expand + * @src: a NULL-terminated array of strings + * + * Merges @src into @dst. Upon successful return from this + * function, @dst is resized to $(dst + src) elements and @src is + * freed. + * + * Returns 0 on success, -1 otherwise. + */ +int +virStringListMerge(char ***dst, + char ***src) +{ + size_t dst_len, src_len, i; + + if (!src || !*src) + return 0; + + dst_len =3D virStringListLength((const char **) *dst); + src_len =3D virStringListLength((const char **) *src); + + if (VIR_REALLOC_N(*dst, dst_len + src_len + 1) < 0) + return -1; + + for (i =3D 0; i <=3D src_len; i++) + (*dst)[i + dst_len] =3D (*src)[i]; + + /* Don't call virStringListFree() as it would free strings in + * @src. */ + VIR_FREE(*src); + return 0; +} + + /** * virStringListCopy: * @dst: where to store the copy of @strings diff --git a/src/util/virstring.h b/src/util/virstring.h index b19abaf9f..f42aaff62 100644 --- a/src/util/virstring.h +++ b/src/util/virstring.h @@ -46,6 +46,9 @@ char **virStringListAdd(const char **strings, void virStringListRemove(char ***strings, const char *item); =20 +int virStringListMerge(char ***dst, + char ***src); + int virStringListCopy(char ***dst, const char **src); =20 --=20 2.13.6 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Sat May 4 07:37:05 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1514913164377385.5500968939847; Tue, 2 Jan 2018 09:12:44 -0800 (PST) Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 194247EA9E; Tue, 2 Jan 2018 17:12:43 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.21]) by smtp.corp.redhat.com (Postfix) with ESMTPS id DDA195D756; Tue, 2 Jan 2018 17:12:42 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id A83EE3D3D3; Tue, 2 Jan 2018 17:12:42 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id w02HCa1a003146 for ; Tue, 2 Jan 2018 12:12:36 -0500 Received: by smtp.corp.redhat.com (Postfix) id E547E1754F; Tue, 2 Jan 2018 17:12:36 +0000 (UTC) Received: from localhost.localdomain (ovpn-204-45.brq.redhat.com [10.40.204.45]) by smtp.corp.redhat.com (Postfix) with ESMTP id 55BCB5C888 for ; Tue, 2 Jan 2018 17:12:36 +0000 (UTC) From: Michal Privoznik To: libvir-list@redhat.com Date: Tue, 2 Jan 2018 18:12:03 +0100 Message-Id: In-Reply-To: References: In-Reply-To: References: X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH 10/18] vsh: Fix vshCompleter signature X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.28]); Tue, 02 Jan 2018 17:12:43 +0000 (UTC) X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" The first argument passed to this function is vshControl *. There's no need to use void pointer. Signed-off-by: Michal Privoznik --- tools/vsh.c | 2 +- tools/vsh.h | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/tools/vsh.c b/tools/vsh.c index d27acb95b..f99d941d9 100644 --- a/tools/vsh.c +++ b/tools/vsh.c @@ -66,7 +66,7 @@ =20 #ifdef WITH_READLINE /* For autocompletion */ -void *autoCompleteOpaque; +vshControl *autoCompleteOpaque; #endif =20 /* NOTE: It would be much nicer to have these two as part of vshControl diff --git a/tools/vsh.h b/tools/vsh.h index 112b1b57d..51f8ef213 100644 --- a/tools/vsh.h +++ b/tools/vsh.h @@ -123,7 +123,8 @@ typedef struct _vshCmdOpt vshCmdOpt; typedef struct _vshCmdOptDef vshCmdOptDef; typedef struct _vshControl vshControl; =20 -typedef char **(*vshCompleter)(void *opaque, unsigned int flags); +typedef char **(*vshCompleter)(vshControl *ctl, + unsigned int flags); =20 /* * vshCmdInfo -- name/value pair for information about command --=20 2.13.6 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Sat May 4 07:37:05 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1514913167037884.0659719835537; Tue, 2 Jan 2018 09:12:47 -0800 (PST) Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id C2D67C0270A6; Tue, 2 Jan 2018 17:12:45 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.20]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 91A8D5D756; Tue, 2 Jan 2018 17:12:45 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id 505051802125; Tue, 2 Jan 2018 17:12:45 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id w02HCec1003171 for ; Tue, 2 Jan 2018 12:12:40 -0500 Received: by smtp.corp.redhat.com (Postfix) id DC7B35C3F8; Tue, 2 Jan 2018 17:12:40 +0000 (UTC) Received: from localhost.localdomain (ovpn-204-45.brq.redhat.com [10.40.204.45]) by smtp.corp.redhat.com (Postfix) with ESMTP id 4E96C5C899 for ; Tue, 2 Jan 2018 17:12:37 +0000 (UTC) From: Michal Privoznik To: libvir-list@redhat.com Date: Tue, 2 Jan 2018 18:12:04 +0100 Message-Id: <9e99d6e9069a3c318aca924d9e2580f81839abc1.1514911024.git.mprivozn@redhat.com> In-Reply-To: References: In-Reply-To: References: X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH 11/18] vsh: Call vshCmdOptDef completer X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.15 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.32]); Tue, 02 Jan 2018 17:12:46 +0000 (UTC) X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" Now that we have everything prepared we can call options' completer again. At the same time, pass partially parsed input to the completer callback - it will help the callbacks to narrow down the list of returned options based on user's input. For instance, if the completer is supposed to return list of interfaces depending on user input it may return just those interfaces defined for already specified domain. Of course, completers might ignore this parameter. Signed-off-by: Michal Privoznik --- tools/vsh.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++-- tools/vsh.h | 1 + 2 files changed, 50 insertions(+), 2 deletions(-) diff --git a/tools/vsh.c b/tools/vsh.c index f99d941d9..10a4ef69c 100644 --- a/tools/vsh.c +++ b/tools/vsh.c @@ -2705,6 +2705,36 @@ vshReadlineOptionsGenerator(const char *text, const = vshCmdDef *cmd) return ret; } =20 + +static const vshCmdOptDef * +vshReadlineCommandFindOpt(const vshCmd *partial, + const char *text) +{ + const vshCmd *tmp =3D partial; + + while (tmp && tmp->next) { + if (tmp->def =3D=3D tmp->next->def && + !tmp->next->opts) + break; + tmp =3D tmp->next; + } + + if (tmp && tmp->opts) { + const vshCmdOpt *opt =3D tmp->opts; + + while (opt) { + if (STREQ_NULLABLE(opt->data, text) || + STREQ_NULLABLE(opt->data, " ")) + return opt->def; + + opt =3D opt->next; + } + } + + return NULL; +} + + static char * vshReadlineParse(const char *text, int state) { @@ -2712,6 +2742,7 @@ vshReadlineParse(const char *text, int state) static char **list; static size_t list_index; const vshCmdDef *cmd =3D NULL; + const vshCmdOptDef *opt =3D NULL; char *ret =3D NULL; =20 if (!state) { @@ -2729,8 +2760,10 @@ vshReadlineParse(const char *text, int state) =20 VIR_FREE(buf); =20 - if (partial) + if (partial) { cmd =3D partial->def; + partial->skipChecks =3D true; + } =20 if (cmd && STREQ(cmd->name, text)) { /* Corner case - some commands share prefix (e.g. @@ -2742,13 +2775,26 @@ vshReadlineParse(const char *text, int state) */ cmd =3D NULL; } + + opt =3D vshReadlineCommandFindOpt(partial, text); } =20 if (!list) { if (!cmd) { list =3D vshReadlineCommandGenerator(text); } else { - list =3D vshReadlineOptionsGenerator(text, cmd); + if (!opt || opt->type !=3D VSH_OT_DATA) + list =3D vshReadlineOptionsGenerator(text, cmd); + + if (opt && opt->completer) { + char **completer_list =3D opt->completer(autoCompleteOpaqu= e, + partial, + opt->completer_flag= s); + if (virStringListMerge(&list, &completer_list) < 0) { + virStringListFree(completer_list); + goto cleanup; + } + } } } =20 @@ -2765,6 +2811,7 @@ vshReadlineParse(const char *text, int state) ret =3D virBufferContentAndReset(&buf); } =20 + cleanup: if (!ret) { vshCommandFree(partial); partial =3D NULL; diff --git a/tools/vsh.h b/tools/vsh.h index 51f8ef213..ae40fb4e8 100644 --- a/tools/vsh.h +++ b/tools/vsh.h @@ -124,6 +124,7 @@ typedef struct _vshCmdOptDef vshCmdOptDef; typedef struct _vshControl vshControl; =20 typedef char **(*vshCompleter)(vshControl *ctl, + const vshCmd *cmd, unsigned int flags); =20 /* --=20 2.13.6 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Sat May 4 07:37:05 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1514913165528370.8433746057724; Tue, 2 Jan 2018 09:12:45 -0800 (PST) Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 51055C05FFEE; Tue, 2 Jan 2018 17:12:44 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.21]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 2CEF760C94; Tue, 2 Jan 2018 17:12:44 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id E9A963D381; Tue, 2 Jan 2018 17:12:43 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id w02HCgU7003182 for ; Tue, 2 Jan 2018 12:12:42 -0500 Received: by smtp.corp.redhat.com (Postfix) id 626585C888; Tue, 2 Jan 2018 17:12:42 +0000 (UTC) Received: from localhost.localdomain (ovpn-204-45.brq.redhat.com [10.40.204.45]) by smtp.corp.redhat.com (Postfix) with ESMTP id C9A785C890 for ; Tue, 2 Jan 2018 17:12:41 +0000 (UTC) From: Michal Privoznik To: libvir-list@redhat.com Date: Tue, 2 Jan 2018 18:12:05 +0100 Message-Id: <508b51052f1d095880382ad37d5b80c1b16319d1.1514911024.git.mprivozn@redhat.com> In-Reply-To: References: In-Reply-To: References: X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH 12/18] vsh: Prune string list returned by completer X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.32]); Tue, 02 Jan 2018 17:12:44 +0000 (UTC) X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" Instead of having completers prune returned string list based on user's input we can do that right after the callback is called. Only strings matching the prefix will be presented to the user then. Signed-off-by: Michal Privoznik --- tools/vsh.c | 43 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/tools/vsh.c b/tools/vsh.c index 10a4ef69c..49e8033bd 100644 --- a/tools/vsh.c +++ b/tools/vsh.c @@ -2735,6 +2735,40 @@ vshReadlineCommandFindOpt(const vshCmd *partial, } =20 =20 +static int +vshCompleterFilter(char ***list, + const char *text) +{ + char **newList =3D NULL; + size_t newList_len =3D 0; + size_t list_len; + size_t i; + + if (!list || !*list) + return -1; + + list_len =3D virStringListLength((const char **) *list); + + if (VIR_ALLOC_N(newList, list_len + 1) < 0) + return -1; + + for (i =3D 0; i < list_len; i++) { + if (!STRPREFIX((*list)[i], text)) { + VIR_FREE((*list)[i]); + continue; + } + + VIR_STEAL_PTR(newList[newList_len], (*list)[i]); + newList_len++; + } + + ignore_value(VIR_REALLOC_N_QUIET(newList, newList_len + 1)); + VIR_FREE(*list); + *list =3D newList; + return 0; +} + + static char * vshReadlineParse(const char *text, int state) { @@ -2790,7 +2824,14 @@ vshReadlineParse(const char *text, int state) char **completer_list =3D opt->completer(autoCompleteOpaqu= e, partial, opt->completer_flag= s); - if (virStringListMerge(&list, &completer_list) < 0) { + + /* For string list returned by completer we have to do + * filtering based on @text because completer returns all + * possible strings. */ + + if (completer_list && + (vshCompleterFilter(&completer_list, text) < 0 || + virStringListMerge(&list, &completer_list) < 0)) { virStringListFree(completer_list); goto cleanup; } --=20 2.13.6 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Sat May 4 07:37:05 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1514913166624127.76919410890036; Tue, 2 Jan 2018 09:12:46 -0800 (PST) Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 5AB8A81DEA; Tue, 2 Jan 2018 17:12:45 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.20]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 2EE0D5D968; Tue, 2 Jan 2018 17:12:45 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id EB5AE1802124; Tue, 2 Jan 2018 17:12:44 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id w02HChhJ003187 for ; Tue, 2 Jan 2018 12:12:43 -0500 Received: by smtp.corp.redhat.com (Postfix) id 55B6A1754E; Tue, 2 Jan 2018 17:12:43 +0000 (UTC) Received: from localhost.localdomain (ovpn-204-45.brq.redhat.com [10.40.204.45]) by smtp.corp.redhat.com (Postfix) with ESMTP id BDD5F17557 for ; Tue, 2 Jan 2018 17:12:42 +0000 (UTC) From: Michal Privoznik To: libvir-list@redhat.com Date: Tue, 2 Jan 2018 18:12:06 +0100 Message-Id: In-Reply-To: References: In-Reply-To: References: X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH 13/18] vsh: Filter --options X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.25]); Tue, 02 Jan 2018 17:12:45 +0000 (UTC) X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" Similarly to the previous commit, once we've presented an --option for a command to the user it makes no sense to offer it again. Therefore, we can prune all already specified options. For instance, after this patch: virsh # migrate --verbose will no longer offer --verbose option. Signed-off-by: Michal Privoznik --- tools/vsh.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++= ++- 1 file changed, 59 insertions(+), 1 deletion(-) diff --git a/tools/vsh.c b/tools/vsh.c index 49e8033bd..f061783e0 100644 --- a/tools/vsh.c +++ b/tools/vsh.c @@ -2769,6 +2769,60 @@ vshCompleterFilter(char ***list, } =20 =20 +static int +vshReadlineOptionsPrune(char ***list, + vshCmd *last) +{ + char **newList =3D NULL; + size_t newList_len =3D 0; + size_t list_len; + size_t i; + + if (!list || !*list) + return -1; + + if (!last->opts) + return 0; + + list_len =3D virStringListLength((const char **) *list); + + if (VIR_ALLOC_N(newList, list_len + 1) < 0) + return -1; + + for (i =3D 0; i < list_len; i++) { + const char *list_opt =3D STRSKIP((*list)[i], "--"); + bool exist =3D false; + vshCmdOpt *opt =3D last->opts; + + /* Should never happen (TM) */ + if (!list_opt) + return -1; + + while (opt) { + if (STREQ(opt->def->name, list_opt)) { + exist =3D true; + break; + } + + opt =3D opt->next; + } + + if (exist) { + VIR_FREE((*list)[i]); + continue; + } + + VIR_STEAL_PTR(newList[newList_len], (*list)[i]); + newList_len++; + } + + ignore_value(VIR_REALLOC_N_QUIET(newList, newList_len + 1)); + VIR_FREE(*list); + *list =3D newList; + return 0; +} + + static char * vshReadlineParse(const char *text, int state) { @@ -2817,9 +2871,13 @@ vshReadlineParse(const char *text, int state) if (!cmd) { list =3D vshReadlineCommandGenerator(text); } else { - if (!opt || opt->type !=3D VSH_OT_DATA) + if (!opt || opt->type !=3D VSH_OT_DATA) { list =3D vshReadlineOptionsGenerator(text, cmd); =20 + if (vshReadlineOptionsPrune(&list, partial) < 0) + goto cleanup; + } + if (opt && opt->completer) { char **completer_list =3D opt->completer(autoCompleteOpaqu= e, partial, --=20 2.13.6 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Sat May 4 07:37:05 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1514913172154281.14521156044475; Tue, 2 Jan 2018 09:12:52 -0800 (PST) Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id E9A6C2C96F7; Tue, 2 Jan 2018 17:12:48 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.20]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 4BDBD60C99; Tue, 2 Jan 2018 17:12:48 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id E8838180212A; Tue, 2 Jan 2018 17:12:47 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id w02HCiQ9003197 for ; Tue, 2 Jan 2018 12:12:44 -0500 Received: by smtp.corp.redhat.com (Postfix) id 4FB295C3F8; Tue, 2 Jan 2018 17:12:44 +0000 (UTC) Received: from localhost.localdomain (ovpn-204-45.brq.redhat.com [10.40.204.45]) by smtp.corp.redhat.com (Postfix) with ESMTP id B25485C888 for ; Tue, 2 Jan 2018 17:12:43 +0000 (UTC) From: Michal Privoznik To: libvir-list@redhat.com Date: Tue, 2 Jan 2018 18:12:07 +0100 Message-Id: <20c758730cdf111548af750e4138a6a6d01ce9fb.1514911024.git.mprivozn@redhat.com> In-Reply-To: References: In-Reply-To: References: X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH 14/18] vsh: Introduce complete command X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.29]); Tue, 02 Jan 2018 17:12:49 +0000 (UTC) X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" This command is going to be called from bash completion script in the following form: virsh complete -- start --domain Its only purpose is to return list of possible strings for completion. Note that this is a 'hidden', unlisted command and therefore there's no documentation to it. Signed-off-by: Michal Privoznik --- tools/virsh.c | 1 + tools/virt-admin.c | 1 + tools/vsh.c | 80 ++++++++++++++++++++++++++++++++++++++++++++++++++= ++++ tools/vsh.h | 14 ++++++++++ 4 files changed, 96 insertions(+) diff --git a/tools/virsh.c b/tools/virsh.c index 933d6b4c9..5f8352e86 100644 --- a/tools/virsh.c +++ b/tools/virsh.c @@ -833,6 +833,7 @@ static const vshCmdDef virshCmds[] =3D { VSH_CMD_PWD, VSH_CMD_QUIT, VSH_CMD_SELF_TEST, + VSH_CMD_COMPLETE, {.name =3D "connect", .handler =3D cmdConnect, .opts =3D opts_connect, diff --git a/tools/virt-admin.c b/tools/virt-admin.c index b8b33af19..ef5bada63 100644 --- a/tools/virt-admin.c +++ b/tools/virt-admin.c @@ -1351,6 +1351,7 @@ static const vshCmdDef vshAdmCmds[] =3D { VSH_CMD_PWD, VSH_CMD_QUIT, VSH_CMD_SELF_TEST, + VSH_CMD_COMPLETE, {.name =3D "uri", .handler =3D cmdURI, .opts =3D NULL, diff --git a/tools/vsh.c b/tools/vsh.c index f061783e0..9f4805b3d 100644 --- a/tools/vsh.c +++ b/tools/vsh.c @@ -3472,3 +3472,83 @@ cmdSelfTest(vshControl *ctl ATTRIBUTE_UNUSED, =20 return true; } + +/* ---------------------- + * Autocompletion command + * ---------------------- */ + +const vshCmdOptDef opts_complete[] =3D { + {.name =3D "string", + .type =3D VSH_OT_ARGV, + .flags =3D VSH_OFLAG_EMPTY_OK, + .help =3D N_("partial string to autocomplete") + }, + {.name =3D NULL} +}; + +const vshCmdInfo info_complete[] =3D { + {.name =3D "help", + .data =3D N_("internal command for autocompletion") + }, + {.name =3D "desc", + .data =3D N_("internal use only") + }, + {.name =3D NULL} +}; + +bool +cmdComplete(vshControl *ctl, const vshCmd *cmd) +{ + bool ret =3D false; +#ifdef WITH_READLINE + const vshClientHooks *hooks =3D ctl->hooks; + int stdin_fileno =3D STDIN_FILENO; + const char *arg =3D ""; + const vshCmdOpt *opt =3D NULL; + char **matches =3D NULL, **iter; + virBuffer buf =3D VIR_BUFFER_INITIALIZER; + + if (vshCommandOptStringQuiet(ctl, cmd, "string", &arg) <=3D 0) + goto cleanup; + + /* This command is flagged VSH_CMD_FLAG_NOCONNECT because we + * need to prevent auth hooks reading any input. Therefore, we + * have to close stdin and then connect ourselves. */ + VIR_FORCE_CLOSE(stdin_fileno); + + if (!(hooks && hooks->connHandler && hooks->connHandler(ctl))) + goto cleanup; + + while ((opt =3D vshCommandOptArgv(ctl, cmd, opt))) { + if (virBufferUse(&buf) !=3D 0) + virBufferAddChar(&buf, ' '); + virBufferAddStr(&buf, opt->data); + arg =3D opt->data; + } + + if (virBufferCheckError(&buf) < 0) + goto cleanup; + + vshReadlineInit(ctl); + + if (!(rl_line_buffer =3D virBufferContentAndReset(&buf)) && + VIR_STRDUP(rl_line_buffer, "") < 0) + goto cleanup; + + /* rl_point is current cursor position in rl_line_buffer. + * In our case it's at the end of the whole line. */ + rl_point =3D strlen(rl_line_buffer); + + if (!(matches =3D vshReadlineCompletion(arg, 0, 0))) + goto cleanup; + + for (iter =3D matches; *iter; iter++) + printf("%s\n", *iter); + + ret =3D true; + cleanup: + virBufferFreeAndReset(&buf); + virStringListFree(matches); +#endif /* WITH_READLINE */ + return ret; +} diff --git a/tools/vsh.h b/tools/vsh.h index ae40fb4e8..6894700d9 100644 --- a/tools/vsh.h +++ b/tools/vsh.h @@ -382,6 +382,8 @@ extern const vshCmdInfo info_echo[]; extern const vshCmdInfo info_pwd[]; extern const vshCmdInfo info_quit[]; extern const vshCmdInfo info_selftest[]; +extern const vshCmdOptDef opts_complete[]; +extern const vshCmdInfo info_complete[]; =20 bool cmdHelp(vshControl *ctl, const vshCmd *cmd); bool cmdCd(vshControl *ctl, const vshCmd *cmd); @@ -389,6 +391,7 @@ bool cmdEcho(vshControl *ctl, const vshCmd *cmd); bool cmdPwd(vshControl *ctl, const vshCmd *cmd); bool cmdQuit(vshControl *ctl, const vshCmd *cmd); bool cmdSelfTest(vshControl *ctl, const vshCmd *cmd); +bool cmdComplete(vshControl *ctl, const vshCmd *cmd); =20 # define VSH_CMD_CD \ { \ @@ -454,6 +457,17 @@ bool cmdSelfTest(vshControl *ctl, const vshCmd *cmd); .alias =3D "self-test" \ } =20 +# define VSH_CMD_COMPLETE \ + { \ + .name =3D "complete", \ + .handler =3D cmdComplete, \ + .opts =3D opts_complete, \ + .info =3D info_complete, \ + .flags =3D VSH_CMD_FLAG_NOCONNECT | VSH_CMD_FLAG_ALIAS, \ + .alias =3D "complete" \ + } + + =20 /* readline */ char * vshReadline(vshControl *ctl, const char *prompt); --=20 2.13.6 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Sat May 4 07:37:05 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1514913173074573.2800825592748; Tue, 2 Jan 2018 09:12:53 -0800 (PST) Received: from smtp.corp.redhat.com (int-mx03.intmail.prod.int.phx2.redhat.com [10.5.11.13]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 10F7B13AAA; Tue, 2 Jan 2018 17:12:49 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.21]) by smtp.corp.redhat.com (Postfix) with ESMTPS id E037360BE3; Tue, 2 Jan 2018 17:12:48 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id AADEF3D384; Tue, 2 Jan 2018 17:12:48 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id w02HCmmB003216 for ; Tue, 2 Jan 2018 12:12:48 -0500 Received: by smtp.corp.redhat.com (Postfix) id 1B2265C3F8; Tue, 2 Jan 2018 17:12:48 +0000 (UTC) Received: from localhost.localdomain (ovpn-204-45.brq.redhat.com [10.40.204.45]) by smtp.corp.redhat.com (Postfix) with ESMTP id 8075B5C890 for ; Tue, 2 Jan 2018 17:12:44 +0000 (UTC) From: Michal Privoznik To: libvir-list@redhat.com Date: Tue, 2 Jan 2018 18:12:08 +0100 Message-Id: <4f2c706f41dceff94a318c798a0802de9ba4fd2f.1514911024.git.mprivozn@redhat.com> In-Reply-To: References: In-Reply-To: References: X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH 15/18] tools: Provide bash autompletion file X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.13 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.29]); Tue, 02 Jan 2018 17:12:49 +0000 (UTC) X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" The only purpose of this file is to be sourced. After that one can use completion even for their bash: # virsh list -- --all --inactive ... Signed-off-by: Michal Privoznik --- configure.ac | 3 ++ libvirt.spec.in | 3 ++ m4/virt-bash-completion.m4 | 74 ++++++++++++++++++++++++++++++++++++++++++= ++++ tools/Makefile.am | 22 ++++++++++++-- tools/bash-completion/vsh | 67 +++++++++++++++++++++++++++++++++++++++++ 5 files changed, 167 insertions(+), 2 deletions(-) create mode 100644 m4/virt-bash-completion.m4 create mode 100644 tools/bash-completion/vsh diff --git a/configure.ac b/configure.ac index fba4e4bf5..06236fad8 100644 --- a/configure.ac +++ b/configure.ac @@ -242,6 +242,7 @@ LIBVIRT_ARG_APPARMOR LIBVIRT_ARG_ATTR LIBVIRT_ARG_AUDIT LIBVIRT_ARG_AVAHI +LIBVIRT_ARG_BASH_COMPLETION LIBVIRT_ARG_BLKID LIBVIRT_ARG_CAPNG LIBVIRT_ARG_CURL @@ -278,6 +279,7 @@ LIBVIRT_CHECK_ATOMIC LIBVIRT_CHECK_ATTR LIBVIRT_CHECK_AUDIT LIBVIRT_CHECK_AVAHI +LIBVIRT_CHECK_BASH_COMPLETION LIBVIRT_CHECK_BLKID LIBVIRT_CHECK_CAPNG LIBVIRT_CHECK_CURL @@ -976,6 +978,7 @@ LIBVIRT_RESULT_APPARMOR LIBVIRT_RESULT_ATTR LIBVIRT_RESULT_AUDIT LIBVIRT_RESULT_AVAHI +LIBVIRT_RESULT_BASH_COMPLETION LIBVIRT_RESULT_BLKID LIBVIRT_RESULT_CAPNG LIBVIRT_RESULT_CURL diff --git a/libvirt.spec.in b/libvirt.spec.in index 7e1b6a27d..d4ef116b2 100644 --- a/libvirt.spec.in +++ b/libvirt.spec.in @@ -306,6 +306,7 @@ BuildRequires: xen-devel BuildRequires: libxml2-devel BuildRequires: libxslt BuildRequires: readline-devel +BuildRequires: bash-completion >=3D 2.0 BuildRequires: ncurses-devel BuildRequires: gettext BuildRequires: libtasn1-devel @@ -2047,6 +2048,8 @@ exit 0 %{_datadir}/systemtap/tapset/libvirt_qemu_probes*.stp %{_datadir}/systemtap/tapset/libvirt_functions.stp =20 +%{_datadir}/bash-completion/completions/vsh + =20 %if %{with_systemd} %{_unitdir}/libvirt-guests.service diff --git a/m4/virt-bash-completion.m4 b/m4/virt-bash-completion.m4 new file mode 100644 index 000000000..e1ef58740 --- /dev/null +++ b/m4/virt-bash-completion.m4 @@ -0,0 +1,74 @@ +dnl Bash completion support +dnl +dnl Copyright (C) 2017 Red Hat, Inc. +dnl +dnl This library is free software; you can redistribute it and/or +dnl modify it under the terms of the GNU Lesser General Public +dnl License as published by the Free Software Foundation; either +dnl version 2.1 of the License, or (at your option) any later version. +dnl +dnl This library is distributed in the hope that it will be useful, +dnl but WITHOUT ANY WARRANTY; without even the implied warranty of +dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +dnl Lesser General Public License for more details. +dnl +dnl You should have received a copy of the GNU Lesser General Public +dnl License along with this library. If not, see +dnl . +dnl +dnl Inspired by libguestfs code. +dnl + +AC_DEFUN([LIBVIRT_ARG_BASH_COMPLETION],[ + LIBVIRT_ARG_WITH_FEATURE([BASH_COMPLETION], [bash-completion], [check], = [2.0]) + LIBVIRT_ARG_WITH([BASH_COMPLETIONS_DIR], + [directory containing bash completions scripts], + [check]) +]) + +AC_DEFUN([LIBVIRT_CHECK_BASH_COMPLETION], [ + AC_REQUIRE([LIBVIRT_CHECK_READLINE]) + + if test "x$with_readline" !=3D "xyes" ; then + if test "x$with_bash_completion" !=3D "xyes" ; then + with_bash_completion=3Dno + else + AC_MSG_ERROR([readline is required for bash completion support]) + fi + else + if test "x$with_bash_completion" =3D "xcheck" ; then + with_bash_completion=3Dyes + fi + fi + + LIBVIRT_CHECK_PKG([BASH_COMPLETION], [bash-completion], [2.0]) + + if test "x$with_bash_completion" =3D "xyes" ; then + if test "x$with_bash_completions_dir" =3D "xcheck"; then + AC_MSG_CHECKING([for bash-completions directory]) + BASH_COMPLETIONS_DIR=3D"$($PKG_CONFIG --variable=3Dcompletionsdir ba= sh-completion)" + AC_MSG_RESULT([$BASH_COMPLETIONS_DIR]) + + dnl Replace bash completions's exec_prefix with our own. + dnl Note that ${exec_prefix} is kept verbatim at this point in time, + dnl and will only be expanded later, when make is called: this makes + dnl it possible to override such prefix at compilation or installati= on + dnl time + bash_completions_prefix=3D"$($PKG_CONFIG --variable=3Dprefix bash-co= mpletion)" + if test "x$bash_completions_prefix" =3D "x" ; then + bash_completions_prefix=3D"/usr" + fi + + BASH_COMPLETIONS_DIR=3D'${exec_prefix}'"${BASH_COMPLETIONS_DIR#$bash= _completions_prefix}" + elif test "x$with_bash_completions_dir" =3D "xno" || test "x$with_bash= _completions_dir" =3D "xyes"; then + AC_MSG_ERROR([bash-completions-dir must be used only with valid path= ]) + else + BASH_COMPLETIONS_DIR=3D$with_bash_completions_dir + fi + AC_SUBST([BASH_COMPLETIONS_DIR]) + fi +]) + +AC_DEFUN([LIBVIRT_RESULT_BASH_COMPLETION],[ + LIBVIRT_RESULT_LIB([BASH_COMPLETION]) +]) diff --git a/tools/Makefile.am b/tools/Makefile.am index fbc73a7c3..1df2a601f 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -73,6 +73,7 @@ EXTRA_DIST =3D \ libvirt-guests.sysconf \ virt-login-shell.conf \ virsh-edit.c \ + bash-completion/vsh \ $(PODFILES) \ $(MANINFILES) \ $(NULL) @@ -326,9 +327,11 @@ POD2MAN =3D pod2man -c "Virtualization Support" -r "$(= PACKAGE)-$(VERSION)" < $< > $@-t && \ mv $@-t $@ =20 -install-data-local: install-init install-systemd install-nss +install-data-local: install-init install-systemd install-nss \ + install-bash-completion =20 -uninstall-local: uninstall-init uninstall-systemd uninstall-nss +uninstall-local: uninstall-init uninstall-systemd uninstall-nss \ + uninstall-bash-completion =20 install-sysconfig: $(MKDIR_P) $(DESTDIR)$(sysconfdir)/sysconfig @@ -414,6 +417,21 @@ libvirt-guests.service: libvirt-guests.service.in $(to= p_builddir)/config.status mv $@-t $@ =20 =20 +if WITH_BASH_COMPLETION +install-bash-completion: + $(MKDIR_P) "$(DESTDIR)$(BASH_COMPLETIONS_DIR)" + $(INSTALL_SCRIPT) $(srcdir)/bash-completion/vsh \ + "$(DESTDIR)$(BASH_COMPLETIONS_DIR)/vsh" + +uninstall-bash-completion: + rm -f $(DESTDIR)$(BASH_COMPLETIONS_DIR)/vsh + rmdir $(DESTDIR)$(BASH_COMPLETIONS_DIR) ||: +else ! WITH_BASH_COMPLETION +install-bash-completion: +uninstall-bash-completion: +endif ! WITH_BASH_COMPLETION + + EXTRA_DIST +=3D \ wireshark/util/genxdrstub.pl \ wireshark/util/make-dissector-reg diff --git a/tools/bash-completion/vsh b/tools/bash-completion/vsh new file mode 100644 index 000000000..8493cad28 --- /dev/null +++ b/tools/bash-completion/vsh @@ -0,0 +1,67 @@ +# +# virsh & virt-admin completion command +# + +_vsh_complete() +{ + local words cword c=3D0 i=3D0 cur RO URI CMDLINE INPUT A + + # Here, $COMP_WORDS is an array of words on the bash + # command line that user wants to complete. However, when + # parsing command line, the default set of word breaks is + # applied. This doesn't work for us as it mangles libvirt + # arguments, e.g. connection URI (with the default set it's + # split into multiple items within the array). Fortunately, + # there's a fixup function for the array. + _get_comp_words_by_ref -n "\"'><=3D;|&(:" -w words -i cword + COMP_WORDS=3D( "${words[@]}" ) + COMP_CWORD=3D${cword} + cur=3D${COMP_WORDS[$COMP_CWORD]} + + # See what URI is user trying to connect to and if they are + # connecting RO. Honour that. + while [ $c -le $COMP_CWORD ]; do + word=3D"${COMP_WORDS[c]}" + case "$word" in + -r|--readonly) RO=3D1 ;; + -c|--connect) c=3D$((++c)); URI=3D${COMP_WORDS[c]} ;; + *) if [ $c -ne 0 ] && [ $i -eq 0 ]; then i=3D$c; break; fi ;; + esac + c=3D$((++c)) + done + + CMDLINE=3D + if [ -n "${RO}" ]; then + CMDLINE=3D"${CMDLINE} -r" + fi + if [ -n "${URI}" ]; then + CMDLINE=3D"${CMDLINE} -c ${URI}" + fi + + INPUT=3D( "${COMP_WORDS[@]:$i:$COMP_CWORD}" ) + + # Uncomment these lines for easy debug. +# echo; +# echo "RO=3D${flag_ro}"; +# echo "URI=3D${URI}"; +# echo "CMDLINE=3D${CMDLINE}"; +# echo "INPUT[${#INPUT[@]}]=3D**${INPUT[@]}**"; +# echo "cur=3D${cur}"; +# echo; +# return 0; + + # Small shortcut here. According to manpage: + # When the function is executed, the first argument ($1) is + # the name of the command whose arguments are being + # completed. + # Therefore, we might just run $1. + A=3D($($1 ${CMDLINE} complete -- "${INPUT[@]}" 2>/dev/null)) + + COMPREPLY=3D($(compgen -W "${A[*]%--}" -- ${cur})) + __ltrim_colon_completions "$cur" + return 0 +} && +complete -o default -o filenames -F _vsh_complete virsh && +complete -o default -o filenames -F _vsh_complete virt-admin + +# vim: ft=3Dsh:et:ts=3D4:sw=3D4:tw=3D80 --=20 2.13.6 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Sat May 4 07:37:05 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1514913173391109.21636547323374; Tue, 2 Jan 2018 09:12:53 -0800 (PST) Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 0D4BB267D8; Tue, 2 Jan 2018 17:12:52 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.21]) by smtp.corp.redhat.com (Postfix) with ESMTPS id D4DAC5D964; Tue, 2 Jan 2018 17:12:51 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id 94BDC3D389; Tue, 2 Jan 2018 17:12:51 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id w02HCnSv003226 for ; Tue, 2 Jan 2018 12:12:49 -0500 Received: by smtp.corp.redhat.com (Postfix) id D3EAB5C3F8; Tue, 2 Jan 2018 17:12:49 +0000 (UTC) Received: from localhost.localdomain (ovpn-204-45.brq.redhat.com [10.40.204.45]) by smtp.corp.redhat.com (Postfix) with ESMTP id DBBCA17560 for ; Tue, 2 Jan 2018 17:12:48 +0000 (UTC) From: Michal Privoznik To: libvir-list@redhat.com Date: Tue, 2 Jan 2018 18:12:09 +0100 Message-Id: In-Reply-To: References: In-Reply-To: References: X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH 16/18] virsh: Introduce virshDomainNameCompleter X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.30]); Tue, 02 Jan 2018 17:12:52 +0000 (UTC) X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" Now that we have everything prepared let the fun begin. This completer is very simple and returns domain names. Moreover, depending on the command it can return just a subset of domains (e.g. only running/paused/transient/.. ones). Signed-off-by: Michal Privoznik --- tools/Makefile.am | 9 +++ tools/virsh-completer.c | 90 +++++++++++++++++++++ tools/virsh-completer.h | 33 ++++++++ tools/virsh-domain-monitor.c | 30 +++---- tools/virsh-domain.c | 182 ++++++++++++++++++++++-----------------= ---- tools/virsh-snapshot.c | 24 +++--- tools/virsh.h | 7 +- 7 files changed, 256 insertions(+), 119 deletions(-) create mode 100644 tools/virsh-completer.c create mode 100644 tools/virsh-completer.h diff --git a/tools/Makefile.am b/tools/Makefile.am index 1df2a601f..7466d8282 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -231,6 +231,15 @@ virsh_SOURCES =3D \ virsh-volume.c virsh-volume.h \ $(NULL) =20 +VIRSH_COMPLETER =3D \ + virsh-completer.c virsh-completer.h + +if WITH_READLINE +virsh_SOURCES +=3D $(VIRSH_COMPLETER) +else ! WITH_READLINE +EXTRA_DIST +=3D $(VIRSH_COMPLETER) +endif ! WITH_READLINE + virsh_LDFLAGS =3D \ $(AM_LDFLAGS) \ $(PIE_LDFLAGS) \ diff --git a/tools/virsh-completer.c b/tools/virsh-completer.c new file mode 100644 index 000000000..4e32b882b --- /dev/null +++ b/tools/virsh-completer.c @@ -0,0 +1,90 @@ +/* + * virsh-completer.c: virsh completer callbacks + * + * Copyright (C) 2017 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * . + * + * Michal Privoznik + * + */ + +#include + +#include "virsh-completer.h" +#include "virsh.h" +#include "virsh-util.h" +#include "internal.h" +#include "viralloc.h" +#include "virstring.h" + + +char ** +virshDomainNameCompleter(vshControl *ctl, + const vshCmd *cmd ATTRIBUTE_UNUSED, + unsigned int flags) +{ + virshControlPtr priv =3D ctl->privData; + virDomainPtr *domains =3D NULL; + int ndomains =3D 0; + size_t i =3D 0; + char **ret =3D NULL; + + virCheckFlags(VIR_CONNECT_LIST_DOMAINS_ACTIVE | + VIR_CONNECT_LIST_DOMAINS_INACTIVE | + VIR_CONNECT_LIST_DOMAINS_PERSISTENT | + VIR_CONNECT_LIST_DOMAINS_TRANSIENT | + VIR_CONNECT_LIST_DOMAINS_RUNNING | + VIR_CONNECT_LIST_DOMAINS_PAUSED | + VIR_CONNECT_LIST_DOMAINS_SHUTOFF | + VIR_CONNECT_LIST_DOMAINS_OTHER | + VIR_CONNECT_LIST_DOMAINS_MANAGEDSAVE | + VIR_CONNECT_LIST_DOMAINS_NO_MANAGEDSAVE | + VIR_CONNECT_LIST_DOMAINS_AUTOSTART | + VIR_CONNECT_LIST_DOMAINS_NO_AUTOSTART | + VIR_CONNECT_LIST_DOMAINS_HAS_SNAPSHOT | + VIR_CONNECT_LIST_DOMAINS_NO_SNAPSHOT, + NULL); + + if (!priv->conn || virConnectIsAlive(priv->conn) <=3D 0) + return NULL; + + if ((ndomains =3D virConnectListAllDomains(priv->conn, &domains, flags= )) < 0) + return NULL; + + if (VIR_ALLOC_N(ret, ndomains + 1) < 0) + goto error; + + for (i =3D 0; i < ndomains; i++) { + const char *name =3D virDomainGetName(domains[i]); + + if (VIR_STRDUP(ret[i], name) < 0) + goto error; + + virshDomainFree(domains[i]); + } + VIR_FREE(domains); + + return ret; + error: + + for (; i < ndomains; i++) + virshDomainFree(domains[i]); + VIR_FREE(domains); + for (i =3D 0; i < ndomains; i++) + VIR_FREE(ret[i]); + VIR_FREE(ret); + return NULL; +} diff --git a/tools/virsh-completer.h b/tools/virsh-completer.h new file mode 100644 index 000000000..288e17909 --- /dev/null +++ b/tools/virsh-completer.h @@ -0,0 +1,33 @@ +/* + * virsh-completer.h: virsh completer callbacks + * + * Copyright (C) 2017 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * . + * + * Michal Privoznik + * + */ + +#ifndef VIRSH_COMPLETER +# define VIRSH_COMPLETER + +# include "vsh.h" + +char ** virshDomainNameCompleter(vshControl *ctl, + const vshCmd *cmd, + unsigned int flags); + +#endif diff --git a/tools/virsh-domain-monitor.c b/tools/virsh-domain-monitor.c index 7b4e320c2..a09eb010c 100644 --- a/tools/virsh-domain-monitor.c +++ b/tools/virsh-domain-monitor.c @@ -40,8 +40,8 @@ #include "virxml.h" #include "virstring.h" =20 -#define VIRSH_COMMON_OPT_DOMAIN_FULL \ - VIRSH_COMMON_OPT_DOMAIN(N_("domain name, id or uuid")) +#define VIRSH_COMMON_OPT_DOMAIN_FULL(cflags) \ + VIRSH_COMMON_OPT_DOMAIN(N_("domain name, id or uuid"), cflags) =20 VIR_ENUM_DECL(virshDomainIOError) VIR_ENUM_IMPL(virshDomainIOError, @@ -278,7 +278,7 @@ static const vshCmdInfo info_dommemstat[] =3D { }; =20 static const vshCmdOptDef opts_dommemstat[] =3D { - VIRSH_COMMON_OPT_DOMAIN_FULL, + VIRSH_COMMON_OPT_DOMAIN_FULL(VIR_CONNECT_LIST_DOMAINS_ACTIVE), {.name =3D "period", .type =3D VSH_OT_INT, .flags =3D VSH_OFLAG_REQ_OPT, @@ -390,7 +390,7 @@ static const vshCmdInfo info_domblkinfo[] =3D { }; =20 static const vshCmdOptDef opts_domblkinfo[] =3D { - VIRSH_COMMON_OPT_DOMAIN_FULL, + VIRSH_COMMON_OPT_DOMAIN_FULL(0), {.name =3D "device", .type =3D VSH_OT_DATA, .flags =3D VSH_OFLAG_REQ, @@ -460,7 +460,7 @@ static const vshCmdInfo info_domblklist[] =3D { }; =20 static const vshCmdOptDef opts_domblklist[] =3D { - VIRSH_COMMON_OPT_DOMAIN_FULL, + VIRSH_COMMON_OPT_DOMAIN_FULL(0), {.name =3D "inactive", .type =3D VSH_OT_BOOL, .help =3D N_("get inactive rather than running configuration") @@ -566,7 +566,7 @@ static const vshCmdInfo info_domiflist[] =3D { }; =20 static const vshCmdOptDef opts_domiflist[] =3D { - VIRSH_COMMON_OPT_DOMAIN_FULL, + VIRSH_COMMON_OPT_DOMAIN_FULL(0), {.name =3D "inactive", .type =3D VSH_OT_BOOL, .help =3D N_("get inactive rather than running configuration") @@ -655,7 +655,7 @@ static const vshCmdInfo info_domif_getlink[] =3D { }; =20 static const vshCmdOptDef opts_domif_getlink[] =3D { - VIRSH_COMMON_OPT_DOMAIN_FULL, + VIRSH_COMMON_OPT_DOMAIN_FULL(0), {.name =3D "interface", .type =3D VSH_OT_DATA, .flags =3D VSH_OFLAG_REQ, @@ -752,7 +752,7 @@ static const vshCmdInfo info_domcontrol[] =3D { }; =20 static const vshCmdOptDef opts_domcontrol[] =3D { - VIRSH_COMMON_OPT_DOMAIN_FULL, + VIRSH_COMMON_OPT_DOMAIN_FULL(VIR_CONNECT_LIST_DOMAINS_ACTIVE), {.name =3D NULL} }; =20 @@ -805,7 +805,7 @@ static const vshCmdInfo info_domblkstat[] =3D { }; =20 static const vshCmdOptDef opts_domblkstat[] =3D { - VIRSH_COMMON_OPT_DOMAIN_FULL, + VIRSH_COMMON_OPT_DOMAIN_FULL(VIR_CONNECT_LIST_DOMAINS_ACTIVE), {.name =3D "device", .type =3D VSH_OT_STRING, .flags =3D VSH_OFLAG_EMPTY_OK, @@ -991,7 +991,7 @@ static const vshCmdInfo info_domifstat[] =3D { }; =20 static const vshCmdOptDef opts_domifstat[] =3D { - VIRSH_COMMON_OPT_DOMAIN_FULL, + VIRSH_COMMON_OPT_DOMAIN_FULL(VIR_CONNECT_LIST_DOMAINS_ACTIVE), {.name =3D "interface", .type =3D VSH_OT_DATA, .flags =3D VSH_OFLAG_REQ, @@ -1064,7 +1064,7 @@ static const vshCmdInfo info_domblkerror[] =3D { }; =20 static const vshCmdOptDef opts_domblkerror[] =3D { - VIRSH_COMMON_OPT_DOMAIN_FULL, + VIRSH_COMMON_OPT_DOMAIN_FULL(VIR_CONNECT_LIST_DOMAINS_ACTIVE), {.name =3D NULL} }; =20 @@ -1125,7 +1125,7 @@ static const vshCmdInfo info_dominfo[] =3D { }; =20 static const vshCmdOptDef opts_dominfo[] =3D { - VIRSH_COMMON_OPT_DOMAIN_FULL, + VIRSH_COMMON_OPT_DOMAIN_FULL(0), {.name =3D NULL} }; =20 @@ -1264,7 +1264,7 @@ static const vshCmdInfo info_domstate[] =3D { }; =20 static const vshCmdOptDef opts_domstate[] =3D { - VIRSH_COMMON_OPT_DOMAIN_FULL, + VIRSH_COMMON_OPT_DOMAIN_FULL(0), {.name =3D "reason", .type =3D VSH_OT_BOOL, .help =3D N_("also print reason for the state") @@ -1316,7 +1316,7 @@ static const vshCmdInfo info_domtime[] =3D { }; =20 static const vshCmdOptDef opts_domtime[] =3D { - VIRSH_COMMON_OPT_DOMAIN_FULL, + VIRSH_COMMON_OPT_DOMAIN_FULL(VIR_CONNECT_LIST_DOMAINS_ACTIVE), {.name =3D "now", .type =3D VSH_OT_BOOL, .help =3D N_("set to the time of the host running virsh") @@ -2145,7 +2145,7 @@ static const vshCmdInfo info_domifaddr[] =3D { }; =20 static const vshCmdOptDef opts_domifaddr[] =3D { - VIRSH_COMMON_OPT_DOMAIN_FULL, + VIRSH_COMMON_OPT_DOMAIN_FULL(VIR_CONNECT_LIST_DOMAINS_ACTIVE), {.name =3D "interface", .type =3D VSH_OT_STRING, .flags =3D VSH_OFLAG_NONE, diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c index 93cb02098..13f8db3dd 100644 --- a/tools/virsh-domain.c +++ b/tools/virsh-domain.c @@ -65,8 +65,8 @@ # define SA_SIGINFO 0 #endif =20 -#define VIRSH_COMMON_OPT_DOMAIN_FULL \ - VIRSH_COMMON_OPT_DOMAIN(N_("domain name, id or uuid")) +#define VIRSH_COMMON_OPT_DOMAIN_FULL(cflags) \ + VIRSH_COMMON_OPT_DOMAIN(N_("domain name, id or uuid"), cflags) =20 #define VIRSH_COMMON_OPT_DOMAIN_PERSISTENT \ {.name =3D "persistent", \ @@ -154,7 +154,7 @@ static const vshCmdInfo info_attach_device[] =3D { }; =20 static const vshCmdOptDef opts_attach_device[] =3D { - VIRSH_COMMON_OPT_DOMAIN_FULL, + VIRSH_COMMON_OPT_DOMAIN_FULL(0), VIRSH_COMMON_OPT_FILE(N_("XML file")), VIRSH_COMMON_OPT_DOMAIN_PERSISTENT, VIRSH_COMMON_OPT_DOMAIN_CONFIG, @@ -236,7 +236,7 @@ static const vshCmdInfo info_attach_disk[] =3D { }; =20 static const vshCmdOptDef opts_attach_disk[] =3D { - VIRSH_COMMON_OPT_DOMAIN_FULL, + VIRSH_COMMON_OPT_DOMAIN_FULL(0), {.name =3D "source", .type =3D VSH_OT_DATA, .flags =3D VSH_OFLAG_REQ | VSH_OFLAG_EMPTY_OK, @@ -727,7 +727,7 @@ static const vshCmdInfo info_attach_interface[] =3D { }; =20 static const vshCmdOptDef opts_attach_interface[] =3D { - VIRSH_COMMON_OPT_DOMAIN_FULL, + VIRSH_COMMON_OPT_DOMAIN_FULL(0), {.name =3D "type", .type =3D VSH_OT_DATA, .flags =3D VSH_OFLAG_REQ, @@ -1037,7 +1037,7 @@ static const vshCmdInfo info_autostart[] =3D { }; =20 static const vshCmdOptDef opts_autostart[] =3D { - VIRSH_COMMON_OPT_DOMAIN_FULL, + VIRSH_COMMON_OPT_DOMAIN_FULL(0), {.name =3D "disable", .type =3D VSH_OT_BOOL, .help =3D N_("disable autostarting") @@ -1089,7 +1089,7 @@ static const vshCmdInfo info_blkdeviotune[] =3D { }; =20 static const vshCmdOptDef opts_blkdeviotune[] =3D { - VIRSH_COMMON_OPT_DOMAIN_FULL, + VIRSH_COMMON_OPT_DOMAIN_FULL(0), {.name =3D "device", .type =3D VSH_OT_DATA, .flags =3D VSH_OFLAG_REQ, @@ -1416,7 +1416,7 @@ static const vshCmdInfo info_blkiotune[] =3D { }; =20 static const vshCmdOptDef opts_blkiotune[] =3D { - VIRSH_COMMON_OPT_DOMAIN_FULL, + VIRSH_COMMON_OPT_DOMAIN_FULL(0), {.name =3D "weight", .type =3D VSH_OT_INT, .help =3D N_("IO Weight") @@ -1885,7 +1885,7 @@ static const vshCmdInfo info_block_commit[] =3D { }; =20 static const vshCmdOptDef opts_block_commit[] =3D { - VIRSH_COMMON_OPT_DOMAIN_FULL, + VIRSH_COMMON_OPT_DOMAIN_FULL(0), {.name =3D "path", .type =3D VSH_OT_DATA, .flags =3D VSH_OFLAG_REQ, @@ -2110,7 +2110,7 @@ static const vshCmdInfo info_block_copy[] =3D { }; =20 static const vshCmdOptDef opts_block_copy[] =3D { - VIRSH_COMMON_OPT_DOMAIN_FULL, + VIRSH_COMMON_OPT_DOMAIN_FULL(0), {.name =3D "path", .type =3D VSH_OT_DATA, .flags =3D VSH_OFLAG_REQ, @@ -2426,7 +2426,7 @@ static const vshCmdInfo info_block_job[] =3D { }; =20 static const vshCmdOptDef opts_block_job[] =3D { - VIRSH_COMMON_OPT_DOMAIN_FULL, + VIRSH_COMMON_OPT_DOMAIN_FULL(0), {.name =3D "path", .type =3D VSH_OT_DATA, .flags =3D VSH_OFLAG_REQ, @@ -2669,7 +2669,7 @@ static const vshCmdInfo info_block_pull[] =3D { }; =20 static const vshCmdOptDef opts_block_pull[] =3D { - VIRSH_COMMON_OPT_DOMAIN_FULL, + VIRSH_COMMON_OPT_DOMAIN_FULL(0), {.name =3D "path", .type =3D VSH_OT_DATA, .flags =3D VSH_OFLAG_REQ, @@ -2815,7 +2815,7 @@ static const vshCmdInfo info_block_resize[] =3D { }; =20 static const vshCmdOptDef opts_block_resize[] =3D { - VIRSH_COMMON_OPT_DOMAIN_FULL, + VIRSH_COMMON_OPT_DOMAIN_FULL(0), {.name =3D "path", .type =3D VSH_OT_DATA, .flags =3D VSH_OFLAG_REQ, @@ -2879,7 +2879,7 @@ static const vshCmdInfo info_console[] =3D { }; =20 static const vshCmdOptDef opts_console[] =3D { - VIRSH_COMMON_OPT_DOMAIN_FULL, + VIRSH_COMMON_OPT_DOMAIN_FULL(VIR_CONNECT_LIST_DOMAINS_ACTIVE), {.name =3D "devname", /* sc_prohibit_devname */ .type =3D VSH_OT_STRING, .help =3D N_("character device name") @@ -2973,7 +2973,7 @@ static const vshCmdInfo info_domif_setlink[] =3D { }; =20 static const vshCmdOptDef opts_domif_setlink[] =3D { - VIRSH_COMMON_OPT_DOMAIN_FULL, + VIRSH_COMMON_OPT_DOMAIN_FULL(0), {.name =3D "interface", .type =3D VSH_OT_DATA, .flags =3D VSH_OFLAG_REQ, @@ -3143,7 +3143,7 @@ static const vshCmdInfo info_domiftune[] =3D { }; =20 static const vshCmdOptDef opts_domiftune[] =3D { - VIRSH_COMMON_OPT_DOMAIN_FULL, + VIRSH_COMMON_OPT_DOMAIN_FULL(0), {.name =3D "interface", .type =3D VSH_OT_DATA, .flags =3D VSH_OFLAG_REQ, @@ -3340,7 +3340,7 @@ static const vshCmdInfo info_suspend[] =3D { }; =20 static const vshCmdOptDef opts_suspend[] =3D { - VIRSH_COMMON_OPT_DOMAIN_FULL, + VIRSH_COMMON_OPT_DOMAIN_FULL(VIR_CONNECT_LIST_DOMAINS_RUNNING), {.name =3D NULL} }; =20 @@ -3382,7 +3382,7 @@ static const vshCmdInfo info_dom_pm_suspend[] =3D { }; =20 static const vshCmdOptDef opts_dom_pm_suspend[] =3D { - VIRSH_COMMON_OPT_DOMAIN_FULL, + VIRSH_COMMON_OPT_DOMAIN_FULL(VIR_CONNECT_LIST_DOMAINS_RUNNING), {.name =3D "target", .type =3D VSH_OT_DATA, .flags =3D VSH_OFLAG_REQ, @@ -3460,7 +3460,7 @@ static const vshCmdInfo info_dom_pm_wakeup[] =3D { }; =20 static const vshCmdOptDef opts_dom_pm_wakeup[] =3D { - VIRSH_COMMON_OPT_DOMAIN_FULL, + VIRSH_COMMON_OPT_DOMAIN_FULL(VIR_CONNECT_LIST_DOMAINS_OTHER), {.name =3D NULL} }; =20 @@ -3505,7 +3505,7 @@ static const vshCmdInfo info_undefine[] =3D { }; =20 static const vshCmdOptDef opts_undefine[] =3D { - VIRSH_COMMON_OPT_DOMAIN_FULL, + VIRSH_COMMON_OPT_DOMAIN_FULL(VIR_CONNECT_LIST_DOMAINS_PERSISTENT), {.name =3D "managed-save", .type =3D VSH_OT_BOOL, .help =3D N_("remove domain managed state file") @@ -3923,7 +3923,8 @@ static const vshCmdInfo info_start[] =3D { }; =20 static const vshCmdOptDef opts_start[] =3D { - VIRSH_COMMON_OPT_DOMAIN(N_("name of the inactive domain")), + VIRSH_COMMON_OPT_DOMAIN(N_("name of the inactive domain"), + VIR_CONNECT_LIST_DOMAINS_SHUTOFF), #ifndef WIN32 {.name =3D "console", .type =3D VSH_OT_BOOL, @@ -4098,7 +4099,7 @@ static const vshCmdInfo info_save[] =3D { }; =20 static const vshCmdOptDef opts_save[] =3D { - VIRSH_COMMON_OPT_DOMAIN_FULL, + VIRSH_COMMON_OPT_DOMAIN_FULL(VIR_CONNECT_LIST_DOMAINS_ACTIVE), VIRSH_COMMON_OPT_FILE(N_("where to save the data")), {.name =3D "bypass-cache", .type =3D VSH_OT_BOOL, @@ -4544,7 +4545,7 @@ static const vshCmdInfo info_managedsave[] =3D { }; =20 static const vshCmdOptDef opts_managedsave[] =3D { - VIRSH_COMMON_OPT_DOMAIN_FULL, + VIRSH_COMMON_OPT_DOMAIN_FULL(VIR_CONNECT_LIST_DOMAINS_ACTIVE), {.name =3D "bypass-cache", .type =3D VSH_OT_BOOL, .help =3D N_("avoid file system cache when saving") @@ -4663,7 +4664,7 @@ static const vshCmdInfo info_managedsaveremove[] =3D { }; =20 static const vshCmdOptDef opts_managedsaveremove[] =3D { - VIRSH_COMMON_OPT_DOMAIN_FULL, + VIRSH_COMMON_OPT_DOMAIN_FULL(0), {.name =3D NULL} }; =20 @@ -4718,7 +4719,7 @@ static const vshCmdInfo info_managed_save_edit[] =3D { }; =20 static const vshCmdOptDef opts_managed_save_edit[] =3D { - VIRSH_COMMON_OPT_DOMAIN_FULL, + VIRSH_COMMON_OPT_DOMAIN_FULL(0), {.name =3D "running", .type =3D VSH_OT_BOOL, .help =3D N_("set domain to be running on start") @@ -4784,7 +4785,7 @@ static const vshCmdInfo info_managed_save_dumpxml[] = =3D { }; =20 static const vshCmdOptDef opts_managed_save_dumpxml[] =3D { - VIRSH_COMMON_OPT_DOMAIN_FULL, + VIRSH_COMMON_OPT_DOMAIN_FULL(0), {.name =3D "security-info", .type =3D VSH_OT_BOOL, .help =3D N_("include security sensitive information in XML dump") @@ -4832,7 +4833,7 @@ static const vshCmdInfo info_managed_save_define[] = =3D { }; =20 static const vshCmdOptDef opts_managed_save_define[] =3D { - VIRSH_COMMON_OPT_DOMAIN_FULL, + VIRSH_COMMON_OPT_DOMAIN_FULL(0), {.name =3D "xml", .type =3D VSH_OT_DATA, .flags =3D VSH_OFLAG_REQ, @@ -4904,7 +4905,7 @@ static const vshCmdInfo info_schedinfo[] =3D { }; =20 static const vshCmdOptDef opts_schedinfo[] =3D { - VIRSH_COMMON_OPT_DOMAIN_FULL, + VIRSH_COMMON_OPT_DOMAIN_FULL(0), {.name =3D "weight", .type =3D VSH_OT_INT, .flags =3D VSH_OFLAG_REQ_OPT, @@ -5215,7 +5216,7 @@ static const vshCmdInfo info_dump[] =3D { }; =20 static const vshCmdOptDef opts_dump[] =3D { - VIRSH_COMMON_OPT_DOMAIN_FULL, + VIRSH_COMMON_OPT_DOMAIN_FULL(VIR_CONNECT_LIST_DOMAINS_ACTIVE), VIRSH_COMMON_OPT_FILE(N_("where to dump the core")), VIRSH_COMMON_OPT_LIVE(N_("perform a live core dump if supported")), {.name =3D "crash", @@ -5387,7 +5388,7 @@ static const vshCmdInfo info_screenshot[] =3D { }; =20 static const vshCmdOptDef opts_screenshot[] =3D { - VIRSH_COMMON_OPT_DOMAIN_FULL, + VIRSH_COMMON_OPT_DOMAIN_FULL(VIR_CONNECT_LIST_DOMAINS_ACTIVE), {.name =3D "file", .type =3D VSH_OT_STRING, .help =3D N_("where to store the screenshot") @@ -5530,7 +5531,7 @@ static const vshCmdInfo info_setLifecycleAction[] =3D= { }; =20 static const vshCmdOptDef opts_setLifecycleAction[] =3D { - VIRSH_COMMON_OPT_DOMAIN_FULL, + VIRSH_COMMON_OPT_DOMAIN_FULL(0), {.name =3D "type", .type =3D VSH_OT_DATA, .flags =3D VSH_OFLAG_REQ, @@ -5626,7 +5627,7 @@ static const vshCmdInfo info_set_user_password[] =3D { }; =20 static const vshCmdOptDef opts_set_user_password[] =3D { - VIRSH_COMMON_OPT_DOMAIN_FULL, + VIRSH_COMMON_OPT_DOMAIN_FULL(VIR_CONNECT_LIST_DOMAINS_ACTIVE), {.name =3D "user", .type =3D VSH_OT_DATA, .flags =3D VSH_OFLAG_REQ, @@ -5690,7 +5691,7 @@ static const vshCmdInfo info_resume[] =3D { }; =20 static const vshCmdOptDef opts_resume[] =3D { - VIRSH_COMMON_OPT_DOMAIN_FULL, + VIRSH_COMMON_OPT_DOMAIN_FULL(VIR_CONNECT_LIST_DOMAINS_PAUSED), {.name =3D NULL} }; =20 @@ -5729,7 +5730,7 @@ static const vshCmdInfo info_shutdown[] =3D { }; =20 static const vshCmdOptDef opts_shutdown[] =3D { - VIRSH_COMMON_OPT_DOMAIN_FULL, + VIRSH_COMMON_OPT_DOMAIN_FULL(VIR_CONNECT_LIST_DOMAINS_ACTIVE), {.name =3D "mode", .type =3D VSH_OT_STRING, .help =3D N_("shutdown mode: acpi|agent|initctl|signal|paravirt") @@ -5813,7 +5814,7 @@ static const vshCmdInfo info_reboot[] =3D { }; =20 static const vshCmdOptDef opts_reboot[] =3D { - VIRSH_COMMON_OPT_DOMAIN_FULL, + VIRSH_COMMON_OPT_DOMAIN_FULL(VIR_CONNECT_LIST_DOMAINS_ACTIVE), {.name =3D "mode", .type =3D VSH_OT_STRING, .help =3D N_("shutdown mode: acpi|agent|initctl|signal|paravirt") @@ -5892,7 +5893,7 @@ static const vshCmdInfo info_reset[] =3D { }; =20 static const vshCmdOptDef opts_reset[] =3D { - VIRSH_COMMON_OPT_DOMAIN_FULL, + VIRSH_COMMON_OPT_DOMAIN_FULL(0), {.name =3D NULL} }; =20 @@ -5931,7 +5932,7 @@ static const vshCmdInfo info_domjobinfo[] =3D { }; =20 static const vshCmdOptDef opts_domjobinfo[] =3D { - VIRSH_COMMON_OPT_DOMAIN_FULL, + VIRSH_COMMON_OPT_DOMAIN_FULL(VIR_CONNECT_LIST_DOMAINS_ACTIVE), {.name =3D "completed", .type =3D VSH_OT_BOOL, .help =3D N_("return statistics of a recently completed job") @@ -6275,7 +6276,7 @@ static const vshCmdInfo info_domjobabort[] =3D { }; =20 static const vshCmdOptDef opts_domjobabort[] =3D { - VIRSH_COMMON_OPT_DOMAIN_FULL, + VIRSH_COMMON_OPT_DOMAIN_FULL(VIR_CONNECT_LIST_DOMAINS_ACTIVE), {.name =3D NULL} }; =20 @@ -6309,7 +6310,7 @@ static const vshCmdInfo info_vcpucount[] =3D { }; =20 static const vshCmdOptDef opts_vcpucount[] =3D { - VIRSH_COMMON_OPT_DOMAIN_FULL, + VIRSH_COMMON_OPT_DOMAIN_FULL(0), {.name =3D "maximum", .type =3D VSH_OT_BOOL, .help =3D N_("get maximum count of vcpus") @@ -6506,7 +6507,7 @@ static const vshCmdInfo info_vcpuinfo[] =3D { }; =20 static const vshCmdOptDef opts_vcpuinfo[] =3D { - VIRSH_COMMON_OPT_DOMAIN_FULL, + VIRSH_COMMON_OPT_DOMAIN_FULL(0), {.name =3D "pretty", .type =3D VSH_OT_BOOL, .help =3D N_("return human readable output") @@ -6755,7 +6756,7 @@ static const vshCmdInfo info_vcpupin[] =3D { }; =20 static const vshCmdOptDef opts_vcpupin[] =3D { - VIRSH_COMMON_OPT_DOMAIN_FULL, + VIRSH_COMMON_OPT_DOMAIN_FULL(0), {.name =3D "vcpu", .type =3D VSH_OT_INT, .help =3D N_("vcpu number") @@ -6972,7 +6973,7 @@ static const vshCmdInfo info_emulatorpin[] =3D { }; =20 static const vshCmdOptDef opts_emulatorpin[] =3D { - VIRSH_COMMON_OPT_DOMAIN_FULL, + VIRSH_COMMON_OPT_DOMAIN_FULL(0), {.name =3D "cpulist", .type =3D VSH_OT_STRING, .flags =3D VSH_OFLAG_EMPTY_OK, @@ -7076,7 +7077,7 @@ static const vshCmdInfo info_setvcpus[] =3D { }; =20 static const vshCmdOptDef opts_setvcpus[] =3D { - VIRSH_COMMON_OPT_DOMAIN_FULL, + VIRSH_COMMON_OPT_DOMAIN_FULL(0), {.name =3D "count", .type =3D VSH_OT_INT, .flags =3D VSH_OFLAG_REQ, @@ -7174,7 +7175,7 @@ static const vshCmdInfo info_guestvcpus[] =3D { }; =20 static const vshCmdOptDef opts_guestvcpus[] =3D { - VIRSH_COMMON_OPT_DOMAIN_FULL, + VIRSH_COMMON_OPT_DOMAIN_FULL(VIR_CONNECT_LIST_DOMAINS_ACTIVE), {.name =3D "cpulist", .type =3D VSH_OT_STRING, .help =3D N_("list of cpus to enable or disable") @@ -7259,7 +7260,7 @@ static const vshCmdInfo info_setvcpu[] =3D { }; =20 static const vshCmdOptDef opts_setvcpu[] =3D { - VIRSH_COMMON_OPT_DOMAIN_FULL, + VIRSH_COMMON_OPT_DOMAIN_FULL(0), {.name =3D "vcpulist", .type =3D VSH_OT_DATA, .flags =3D VSH_OFLAG_REQ, @@ -7342,7 +7343,7 @@ static const vshCmdInfo info_domblkthreshold[] =3D { }; =20 static const vshCmdOptDef opts_domblkthreshold[] =3D { - VIRSH_COMMON_OPT_DOMAIN_FULL, + VIRSH_COMMON_OPT_DOMAIN_FULL(VIR_CONNECT_LIST_DOMAINS_ACTIVE), {.name =3D "dev", .type =3D VSH_OT_DATA, .flags =3D VSH_OFLAG_REQ, @@ -7398,7 +7399,7 @@ static const vshCmdInfo info_iothreadinfo[] =3D { {.name =3D NULL} }; static const vshCmdOptDef opts_iothreadinfo[] =3D { - VIRSH_COMMON_OPT_DOMAIN_FULL, + VIRSH_COMMON_OPT_DOMAIN_FULL(0), VIRSH_COMMON_OPT_DOMAIN_CONFIG, VIRSH_COMMON_OPT_DOMAIN_LIVE, VIRSH_COMMON_OPT_DOMAIN_CURRENT, @@ -7474,7 +7475,7 @@ static const vshCmdInfo info_iothreadpin[] =3D { }; =20 static const vshCmdOptDef opts_iothreadpin[] =3D { - VIRSH_COMMON_OPT_DOMAIN_FULL, + VIRSH_COMMON_OPT_DOMAIN_FULL(0), {.name =3D "iothread", .type =3D VSH_OT_INT, .flags =3D VSH_OFLAG_REQ, @@ -7556,7 +7557,7 @@ static const vshCmdInfo info_iothreadadd[] =3D { }; =20 static const vshCmdOptDef opts_iothreadadd[] =3D { - VIRSH_COMMON_OPT_DOMAIN_FULL, + VIRSH_COMMON_OPT_DOMAIN_FULL(0), {.name =3D "id", .type =3D VSH_OT_INT, .flags =3D VSH_OFLAG_REQ, @@ -7621,7 +7622,7 @@ static const vshCmdInfo info_iothreaddel[] =3D { }; =20 static const vshCmdOptDef opts_iothreaddel[] =3D { - VIRSH_COMMON_OPT_DOMAIN_FULL, + VIRSH_COMMON_OPT_DOMAIN_FULL(0), {.name =3D "id", .type =3D VSH_OT_INT, .flags =3D VSH_OFLAG_REQ, @@ -7897,7 +7898,7 @@ static const vshCmdInfo info_cpu_stats[] =3D { }; =20 static const vshCmdOptDef opts_cpu_stats[] =3D { - VIRSH_COMMON_OPT_DOMAIN_FULL, + VIRSH_COMMON_OPT_DOMAIN_FULL(VIR_CONNECT_LIST_DOMAINS_ACTIVE), {.name =3D "total", .type =3D VSH_OT_BOOL, .help =3D N_("Show total statistics only") @@ -8236,7 +8237,7 @@ static const vshCmdInfo info_destroy[] =3D { }; =20 static const vshCmdOptDef opts_destroy[] =3D { - VIRSH_COMMON_OPT_DOMAIN_FULL, + VIRSH_COMMON_OPT_DOMAIN_FULL(VIR_CONNECT_LIST_DOMAINS_ACTIVE), {.name =3D "graceful", .type =3D VSH_OT_BOOL, .help =3D N_("terminate gracefully") @@ -8289,7 +8290,7 @@ static const vshCmdInfo info_desc[] =3D { }; =20 static const vshCmdOptDef opts_desc[] =3D { - VIRSH_COMMON_OPT_DOMAIN_FULL, + VIRSH_COMMON_OPT_DOMAIN_FULL(0), VIRSH_COMMON_OPT_LIVE(N_("modify/get running state")), VIRSH_COMMON_OPT_CONFIG(N_("modify/get persistent configuration")), VIRSH_COMMON_OPT_CURRENT(N_("modify/get current state configuration")), @@ -8454,7 +8455,7 @@ static const vshCmdInfo info_metadata[] =3D { }; =20 static const vshCmdOptDef opts_metadata[] =3D { - VIRSH_COMMON_OPT_DOMAIN_FULL, + VIRSH_COMMON_OPT_DOMAIN_FULL(0), {.name =3D "uri", .type =3D VSH_OT_DATA, .flags =3D VSH_OFLAG_REQ, @@ -8600,7 +8601,7 @@ static const vshCmdInfo info_inject_nmi[] =3D { }; =20 static const vshCmdOptDef opts_inject_nmi[] =3D { - VIRSH_COMMON_OPT_DOMAIN_FULL, + VIRSH_COMMON_OPT_DOMAIN_FULL(VIR_CONNECT_LIST_DOMAINS_ACTIVE), {.name =3D NULL} }; =20 @@ -8634,7 +8635,7 @@ static const vshCmdInfo info_send_key[] =3D { }; =20 static const vshCmdOptDef opts_send_key[] =3D { - VIRSH_COMMON_OPT_DOMAIN_FULL, + VIRSH_COMMON_OPT_DOMAIN_FULL(VIR_CONNECT_LIST_DOMAINS_ACTIVE), {.name =3D "codeset", .type =3D VSH_OT_STRING, .flags =3D VSH_OFLAG_REQ_OPT, @@ -8730,7 +8731,7 @@ static const vshCmdInfo info_send_process_signal[] = =3D { }; =20 static const vshCmdOptDef opts_send_process_signal[] =3D { - VIRSH_COMMON_OPT_DOMAIN_FULL, + VIRSH_COMMON_OPT_DOMAIN_FULL(VIR_CONNECT_LIST_DOMAINS_ACTIVE), {.name =3D "pid", .type =3D VSH_OT_DATA, .flags =3D VSH_OFLAG_REQ, @@ -8835,7 +8836,7 @@ static const vshCmdInfo info_setmem[] =3D { }; =20 static const vshCmdOptDef opts_setmem[] =3D { - VIRSH_COMMON_OPT_DOMAIN_FULL, + VIRSH_COMMON_OPT_DOMAIN_FULL(0), {.name =3D "kilobytes", .type =3D VSH_OT_ALIAS, .help =3D "size" @@ -8916,7 +8917,7 @@ static const vshCmdInfo info_setmaxmem[] =3D { }; =20 static const vshCmdOptDef opts_setmaxmem[] =3D { - VIRSH_COMMON_OPT_DOMAIN_FULL, + VIRSH_COMMON_OPT_DOMAIN_FULL(0), {.name =3D "kilobytes", .type =3D VSH_OT_ALIAS, .help =3D "size" @@ -9004,7 +9005,7 @@ static const vshCmdInfo info_memtune[] =3D { }; =20 static const vshCmdOptDef opts_memtune[] =3D { - VIRSH_COMMON_OPT_DOMAIN_FULL, + VIRSH_COMMON_OPT_DOMAIN_FULL(0), {.name =3D "hard-limit", .type =3D VSH_OT_INT, .help =3D N_("Max memory, as scaled integer (default KiB)") @@ -9181,7 +9182,7 @@ static const vshCmdInfo info_perf[] =3D { }; =20 static const vshCmdOptDef opts_perf[] =3D { - VIRSH_COMMON_OPT_DOMAIN_FULL, + VIRSH_COMMON_OPT_DOMAIN_FULL(0), {.name =3D "enable", .type =3D VSH_OT_STRING, .help =3D N_("perf events which will be enabled") @@ -9315,7 +9316,7 @@ static const vshCmdInfo info_numatune[] =3D { }; =20 static const vshCmdOptDef opts_numatune[] =3D { - VIRSH_COMMON_OPT_DOMAIN_FULL, + VIRSH_COMMON_OPT_DOMAIN_FULL(0), {.name =3D "mode", .type =3D VSH_OT_STRING, .help =3D N_("NUMA mode, one of strict, preferred and interleave \n" @@ -9450,7 +9451,7 @@ static const vshCmdInfo info_qemu_monitor_command[] = =3D { }; =20 static const vshCmdOptDef opts_qemu_monitor_command[] =3D { - VIRSH_COMMON_OPT_DOMAIN_FULL, + VIRSH_COMMON_OPT_DOMAIN_FULL(VIR_CONNECT_LIST_DOMAINS_ACTIVE), {.name =3D "hmp", .type =3D VSH_OT_BOOL, .help =3D N_("command is in human monitor protocol") @@ -9751,7 +9752,7 @@ static const vshCmdInfo info_qemu_agent_command[] =3D= { }; =20 static const vshCmdOptDef opts_qemu_agent_command[] =3D { - VIRSH_COMMON_OPT_DOMAIN_FULL, + VIRSH_COMMON_OPT_DOMAIN_FULL(VIR_CONNECT_LIST_DOMAINS_ACTIVE), {.name =3D "timeout", .type =3D VSH_OT_INT, .flags =3D VSH_OFLAG_REQ_OPT, @@ -9873,7 +9874,7 @@ static const vshCmdInfo info_lxc_enter_namespace[] = =3D { }; =20 static const vshCmdOptDef opts_lxc_enter_namespace[] =3D { - VIRSH_COMMON_OPT_DOMAIN_FULL, + VIRSH_COMMON_OPT_DOMAIN_FULL(VIR_CONNECT_LIST_DOMAINS_ACTIVE), {.name =3D "noseclabel", .type =3D VSH_OT_BOOL, .help =3D N_("Do not change process security label") @@ -10014,7 +10015,7 @@ static const vshCmdInfo info_dumpxml[] =3D { }; =20 static const vshCmdOptDef opts_dumpxml[] =3D { - VIRSH_COMMON_OPT_DOMAIN_FULL, + VIRSH_COMMON_OPT_DOMAIN_FULL(0), {.name =3D "inactive", .type =3D VSH_OT_BOOL, .help =3D N_("show inactive defined XML") @@ -10223,7 +10224,7 @@ static const vshCmdInfo info_domname[] =3D { }; =20 static const vshCmdOptDef opts_domname[] =3D { - VIRSH_COMMON_OPT_DOMAIN(N_("domain id or uuid")), + VIRSH_COMMON_OPT_DOMAIN(N_("domain id or uuid"), 0), {.name =3D NULL} }; =20 @@ -10255,7 +10256,7 @@ static const vshCmdInfo info_domrename[] =3D { }; =20 static const vshCmdOptDef opts_domrename[] =3D { - VIRSH_COMMON_OPT_DOMAIN_FULL, + VIRSH_COMMON_OPT_DOMAIN_FULL(VIR_CONNECT_LIST_DOMAINS_INACTIVE), {.name =3D "new-name", .type =3D VSH_OT_DATA, .flags =3D VSH_OFLAG_REQ, @@ -10302,7 +10303,8 @@ static const vshCmdInfo info_domid[] =3D { }; =20 static const vshCmdOptDef opts_domid[] =3D { - VIRSH_COMMON_OPT_DOMAIN(N_("domain name or uuid")), + VIRSH_COMMON_OPT_DOMAIN(N_("domain name or uuid"), + VIR_CONNECT_LIST_DOMAINS_ACTIVE), {.name =3D NULL} }; =20 @@ -10339,7 +10341,7 @@ static const vshCmdInfo info_domuuid[] =3D { }; =20 static const vshCmdOptDef opts_domuuid[] =3D { - VIRSH_COMMON_OPT_DOMAIN(N_("domain id or name")), + VIRSH_COMMON_OPT_DOMAIN(N_("domain id or name"), 0), {.name =3D NULL} }; =20 @@ -10376,7 +10378,7 @@ static const vshCmdInfo info_migrate[] =3D { }; =20 static const vshCmdOptDef opts_migrate[] =3D { - VIRSH_COMMON_OPT_DOMAIN_FULL, + VIRSH_COMMON_OPT_DOMAIN_FULL(0), {.name =3D "desturi", .type =3D VSH_OT_DATA, .flags =3D VSH_OFLAG_REQ, @@ -10974,7 +10976,7 @@ static const vshCmdInfo info_migrate_setmaxdowntime= [] =3D { }; =20 static const vshCmdOptDef opts_migrate_setmaxdowntime[] =3D { - VIRSH_COMMON_OPT_DOMAIN_FULL, + VIRSH_COMMON_OPT_DOMAIN_FULL(VIR_CONNECT_LIST_DOMAINS_ACTIVE), {.name =3D "downtime", .type =3D VSH_OT_INT, .flags =3D VSH_OFLAG_REQ, @@ -11025,7 +11027,7 @@ static const vshCmdInfo info_migrate_getmaxdowntime= [] =3D { }; =20 static const vshCmdOptDef opts_migrate_getmaxdowntime[] =3D { - VIRSH_COMMON_OPT_DOMAIN_FULL, + VIRSH_COMMON_OPT_DOMAIN_FULL(VIR_CONNECT_LIST_DOMAINS_ACTIVE), {.name =3D NULL} }; =20 @@ -11066,7 +11068,7 @@ static const vshCmdInfo info_migrate_compcache[] = =3D { }; =20 static const vshCmdOptDef opts_migrate_compcache[] =3D { - VIRSH_COMMON_OPT_DOMAIN_FULL, + VIRSH_COMMON_OPT_DOMAIN_FULL(VIR_CONNECT_LIST_DOMAINS_ACTIVE), {.name =3D "size", .type =3D VSH_OT_INT, .flags =3D VSH_OFLAG_REQ_OPT, @@ -11123,7 +11125,7 @@ static const vshCmdInfo info_migrate_setspeed[] =3D= { }; =20 static const vshCmdOptDef opts_migrate_setspeed[] =3D { - VIRSH_COMMON_OPT_DOMAIN_FULL, + VIRSH_COMMON_OPT_DOMAIN_FULL(VIR_CONNECT_LIST_DOMAINS_ACTIVE), {.name =3D "bandwidth", .type =3D VSH_OT_INT, .flags =3D VSH_OFLAG_REQ, @@ -11169,7 +11171,7 @@ static const vshCmdInfo info_migrate_getspeed[] =3D= { }; =20 static const vshCmdOptDef opts_migrate_getspeed[] =3D { - VIRSH_COMMON_OPT_DOMAIN_FULL, + VIRSH_COMMON_OPT_DOMAIN_FULL(VIR_CONNECT_LIST_DOMAINS_ACTIVE), {.name =3D NULL} }; =20 @@ -11252,7 +11254,7 @@ static const vshCmdInfo info_domdisplay[] =3D { }; =20 static const vshCmdOptDef opts_domdisplay[] =3D { - VIRSH_COMMON_OPT_DOMAIN_FULL, + VIRSH_COMMON_OPT_DOMAIN_FULL(VIR_CONNECT_LIST_DOMAINS_ACTIVE), {.name =3D "include-password", .type =3D VSH_OT_BOOL, .help =3D N_("includes the password into the connection URI if availa= ble") @@ -11533,7 +11535,7 @@ static const vshCmdInfo info_vncdisplay[] =3D { }; =20 static const vshCmdOptDef opts_vncdisplay[] =3D { - VIRSH_COMMON_OPT_DOMAIN_FULL, + VIRSH_COMMON_OPT_DOMAIN_FULL(VIR_CONNECT_LIST_DOMAINS_ACTIVE), {.name =3D NULL} }; =20 @@ -11609,7 +11611,7 @@ static const vshCmdInfo info_ttyconsole[] =3D { }; =20 static const vshCmdOptDef opts_ttyconsole[] =3D { - VIRSH_COMMON_OPT_DOMAIN_FULL, + VIRSH_COMMON_OPT_DOMAIN_FULL(VIR_CONNECT_LIST_DOMAINS_ACTIVE), {.name =3D NULL} }; =20 @@ -11651,7 +11653,7 @@ static const vshCmdInfo info_domhostname[] =3D { }; =20 static const vshCmdOptDef opts_domhostname[] =3D { - VIRSH_COMMON_OPT_DOMAIN_FULL, + VIRSH_COMMON_OPT_DOMAIN_FULL(0), {.name =3D NULL} }; =20 @@ -11810,7 +11812,7 @@ static const vshCmdInfo info_detach_device[] =3D { }; =20 static const vshCmdOptDef opts_detach_device[] =3D { - VIRSH_COMMON_OPT_DOMAIN_FULL, + VIRSH_COMMON_OPT_DOMAIN_FULL(0), VIRSH_COMMON_OPT_FILE(N_("XML file")), VIRSH_COMMON_OPT_DOMAIN_PERSISTENT, VIRSH_COMMON_OPT_DOMAIN_CONFIG, @@ -11891,7 +11893,7 @@ static const vshCmdInfo info_update_device[] =3D { }; =20 static const vshCmdOptDef opts_update_device[] =3D { - VIRSH_COMMON_OPT_DOMAIN_FULL, + VIRSH_COMMON_OPT_DOMAIN_FULL(0), VIRSH_COMMON_OPT_FILE(N_("XML file")), VIRSH_COMMON_OPT_DOMAIN_PERSISTENT, VIRSH_COMMON_OPT_DOMAIN_CONFIG, @@ -11973,7 +11975,7 @@ static const vshCmdInfo info_detach_interface[] =3D= { }; =20 static const vshCmdOptDef opts_detach_interface[] =3D { - VIRSH_COMMON_OPT_DOMAIN_FULL, + VIRSH_COMMON_OPT_DOMAIN_FULL(0), {.name =3D "type", .type =3D VSH_OT_DATA, .flags =3D VSH_OFLAG_REQ, @@ -12416,7 +12418,7 @@ static const vshCmdInfo info_detach_disk[] =3D { }; =20 static const vshCmdOptDef opts_detach_disk[] =3D { - VIRSH_COMMON_OPT_DOMAIN_FULL, + VIRSH_COMMON_OPT_DOMAIN_FULL(0), {.name =3D "target", .type =3D VSH_OT_DATA, .flags =3D VSH_OFLAG_REQ, @@ -12516,7 +12518,7 @@ static const vshCmdInfo info_edit[] =3D { }; =20 static const vshCmdOptDef opts_edit[] =3D { - VIRSH_COMMON_OPT_DOMAIN_FULL, + VIRSH_COMMON_OPT_DOMAIN_FULL(0), {.name =3D "skip-validate", .type =3D VSH_OT_BOOL, .help =3D N_("skip validation of the XML against the schema") @@ -13475,7 +13477,7 @@ static const vshCmdInfo info_change_media[] =3D { }; =20 static const vshCmdOptDef opts_change_media[] =3D { - VIRSH_COMMON_OPT_DOMAIN_FULL, + VIRSH_COMMON_OPT_DOMAIN_FULL(0), {.name =3D "path", .type =3D VSH_OT_DATA, .flags =3D VSH_OFLAG_REQ, @@ -13636,7 +13638,7 @@ static const vshCmdInfo info_domfstrim[] =3D { }; =20 static const vshCmdOptDef opts_domfstrim[] =3D { - VIRSH_COMMON_OPT_DOMAIN_FULL, + VIRSH_COMMON_OPT_DOMAIN_FULL(VIR_CONNECT_LIST_DOMAINS_ACTIVE), {.name =3D "minimum", .type =3D VSH_OT_INT, .help =3D N_("Just a hint to ignore contiguous " @@ -13689,7 +13691,7 @@ static const vshCmdInfo info_domfsfreeze[] =3D { }; =20 static const vshCmdOptDef opts_domfsfreeze[] =3D { - VIRSH_COMMON_OPT_DOMAIN_FULL, + VIRSH_COMMON_OPT_DOMAIN_FULL(VIR_CONNECT_LIST_DOMAINS_ACTIVE), {.name =3D "mountpoint", .type =3D VSH_OT_ARGV, .help =3D N_("mountpoint path to be frozen") @@ -13742,7 +13744,7 @@ static const vshCmdInfo info_domfsthaw[] =3D { }; =20 static const vshCmdOptDef opts_domfsthaw[] =3D { - VIRSH_COMMON_OPT_DOMAIN_FULL, + VIRSH_COMMON_OPT_DOMAIN_FULL(VIR_CONNECT_LIST_DOMAINS_ACTIVE), {.name =3D "mountpoint", .type =3D VSH_OT_ARGV, .help =3D N_("mountpoint path to be thawed") @@ -13795,7 +13797,7 @@ static const vshCmdInfo info_domfsinfo[] =3D { }; =20 static const vshCmdOptDef opts_domfsinfo[] =3D { - VIRSH_COMMON_OPT_DOMAIN_FULL, + VIRSH_COMMON_OPT_DOMAIN_FULL(VIR_CONNECT_LIST_DOMAINS_ACTIVE), {.name =3D NULL} }; =20 diff --git a/tools/virsh-snapshot.c b/tools/virsh-snapshot.c index cd89a414a..c44a36f98 100644 --- a/tools/virsh-snapshot.c +++ b/tools/virsh-snapshot.c @@ -42,8 +42,8 @@ #include "virxml.h" #include "conf/snapshot_conf.h" =20 -#define VIRSH_COMMON_OPT_DOMAIN_FULL \ - VIRSH_COMMON_OPT_DOMAIN(N_("domain name, id or uuid")) +#define VIRSH_COMMON_OPT_DOMAIN_FULL(cflags) \ + VIRSH_COMMON_OPT_DOMAIN(N_("domain name, id or uuid"), cflags) =20 /* Helper for snapshot-create and snapshot-create-as */ static bool @@ -125,7 +125,7 @@ static const vshCmdInfo info_snapshot_create[] =3D { }; =20 static const vshCmdOptDef opts_snapshot_create[] =3D { - VIRSH_COMMON_OPT_DOMAIN_FULL, + VIRSH_COMMON_OPT_DOMAIN_FULL(0), {.name =3D "xmlfile", .type =3D VSH_OT_STRING, .help =3D N_("domain snapshot XML") @@ -319,7 +319,7 @@ static const vshCmdInfo info_snapshot_create_as[] =3D { }; =20 static const vshCmdOptDef opts_snapshot_create_as[] =3D { - VIRSH_COMMON_OPT_DOMAIN_FULL, + VIRSH_COMMON_OPT_DOMAIN_FULL(0), {.name =3D "name", .type =3D VSH_OT_STRING, .help =3D N_("name of snapshot") @@ -508,7 +508,7 @@ static const vshCmdInfo info_snapshot_edit[] =3D { }; =20 static const vshCmdOptDef opts_snapshot_edit[] =3D { - VIRSH_COMMON_OPT_DOMAIN_FULL, + VIRSH_COMMON_OPT_DOMAIN_FULL(0), {.name =3D "snapshotname", .type =3D VSH_OT_STRING, .help =3D N_("snapshot name") @@ -620,7 +620,7 @@ static const vshCmdInfo info_snapshot_current[] =3D { }; =20 static const vshCmdOptDef opts_snapshot_current[] =3D { - VIRSH_COMMON_OPT_DOMAIN_FULL, + VIRSH_COMMON_OPT_DOMAIN_FULL(0), {.name =3D "name", .type =3D VSH_OT_BOOL, .help =3D N_("list the name, rather than the full xml") @@ -851,7 +851,7 @@ static const vshCmdInfo info_snapshot_info[] =3D { }; =20 static const vshCmdOptDef opts_snapshot_info[] =3D { - VIRSH_COMMON_OPT_DOMAIN_FULL, + VIRSH_COMMON_OPT_DOMAIN_FULL(0), {.name =3D "snapshotname", .type =3D VSH_OT_STRING, .help =3D N_("snapshot name") @@ -1401,7 +1401,7 @@ static const vshCmdInfo info_snapshot_list[] =3D { }; =20 static const vshCmdOptDef opts_snapshot_list[] =3D { - VIRSH_COMMON_OPT_DOMAIN_FULL, + VIRSH_COMMON_OPT_DOMAIN_FULL(0), {.name =3D "parent", .type =3D VSH_OT_BOOL, .help =3D N_("add a column showing parent snapshot") @@ -1657,7 +1657,7 @@ static const vshCmdInfo info_snapshot_dumpxml[] =3D { }; =20 static const vshCmdOptDef opts_snapshot_dumpxml[] =3D { - VIRSH_COMMON_OPT_DOMAIN_FULL, + VIRSH_COMMON_OPT_DOMAIN_FULL(0), {.name =3D "snapshotname", .type =3D VSH_OT_DATA, .flags =3D VSH_OFLAG_REQ, @@ -1720,7 +1720,7 @@ static const vshCmdInfo info_snapshot_parent[] =3D { }; =20 static const vshCmdOptDef opts_snapshot_parent[] =3D { - VIRSH_COMMON_OPT_DOMAIN_FULL, + VIRSH_COMMON_OPT_DOMAIN_FULL(0), {.name =3D "snapshotname", .type =3D VSH_OT_STRING, .help =3D N_("find parent of snapshot name") @@ -1779,7 +1779,7 @@ static const vshCmdInfo info_snapshot_revert[] =3D { }; =20 static const vshCmdOptDef opts_snapshot_revert[] =3D { - VIRSH_COMMON_OPT_DOMAIN_FULL, + VIRSH_COMMON_OPT_DOMAIN_FULL(0), {.name =3D "snapshotname", .type =3D VSH_OT_STRING, .help =3D N_("snapshot name") @@ -1863,7 +1863,7 @@ static const vshCmdInfo info_snapshot_delete[] =3D { }; =20 static const vshCmdOptDef opts_snapshot_delete[] =3D { - VIRSH_COMMON_OPT_DOMAIN_FULL, + VIRSH_COMMON_OPT_DOMAIN_FULL(0), {.name =3D "snapshotname", .type =3D VSH_OT_STRING, .help =3D N_("snapshot name") diff --git a/tools/virsh.h b/tools/virsh.h index b353b645a..528e04558 100644 --- a/tools/virsh.h +++ b/tools/virsh.h @@ -38,6 +38,7 @@ # include "virthread.h" # include "virpolkit.h" # include "vsh.h" +# include "virsh-completer.h" =20 # define VIRSH_PROMPT_RW "virsh # " # define VIRSH_PROMPT_RO "virsh > " @@ -70,11 +71,13 @@ .help =3D _helpstr \ } =20 -# define VIRSH_COMMON_OPT_DOMAIN(_helpstr) \ +# define VIRSH_COMMON_OPT_DOMAIN(_helpstr, cflags) \ {.name =3D "domain", \ .type =3D VSH_OT_DATA, \ .flags =3D VSH_OFLAG_REQ, \ - .help =3D _helpstr \ + .help =3D _helpstr, \ + .completer =3D virshDomainNameCompleter, \ + .completer_flags =3D cflags, \ } =20 # define VIRSH_COMMON_OPT_CONFIG(_helpstr) \ --=20 2.13.6 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Sat May 4 07:37:05 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1514913176305985.8965259176375; Tue, 2 Jan 2018 09:12:56 -0800 (PST) Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id E27576A7D2; Tue, 2 Jan 2018 17:12:54 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.20]) by smtp.corp.redhat.com (Postfix) with ESMTPS id B46DD5D967; Tue, 2 Jan 2018 17:12:54 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id 7529C1801243; Tue, 2 Jan 2018 17:12:54 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id w02HCpGm003235 for ; Tue, 2 Jan 2018 12:12:51 -0500 Received: by smtp.corp.redhat.com (Postfix) id 26C161754F; Tue, 2 Jan 2018 17:12:51 +0000 (UTC) Received: from localhost.localdomain (ovpn-204-45.brq.redhat.com [10.40.204.45]) by smtp.corp.redhat.com (Postfix) with ESMTP id 8D4EE17558 for ; Tue, 2 Jan 2018 17:12:50 +0000 (UTC) From: Michal Privoznik To: libvir-list@redhat.com Date: Tue, 2 Jan 2018 18:12:10 +0100 Message-Id: <10eec5bbe0d27e9b4c7aa11d2a28d397e92007be.1514911024.git.mprivozn@redhat.com> In-Reply-To: References: In-Reply-To: References: X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH 17/18] virsh: Introduce virshDomainInterfaceCompleter X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.27]); Tue, 02 Jan 2018 17:12:55 +0000 (UTC) X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" For given domain fetch list of defined interfaces. This can be used for commands like domif-getlink and others. If available, the interface name is returned (e.g. "vnet0", usually available only for running domains), if not the MAC address is returned. Moreover, the detach-interface command requires only MAC address and therefore we have new flag that forces the completer to return just the MAC address. Signed-off-by: Michal Privoznik --- tools/virsh-completer.c | 60 ++++++++++++++++++++++++++++++++++++++++= ++++ tools/virsh-completer.h | 8 ++++++ tools/virsh-domain-monitor.c | 3 +++ tools/virsh-domain.c | 4 +++ 4 files changed, 75 insertions(+) diff --git a/tools/virsh-completer.c b/tools/virsh-completer.c index 4e32b882b..25c3aaa0d 100644 --- a/tools/virsh-completer.c +++ b/tools/virsh-completer.c @@ -29,6 +29,7 @@ #include "internal.h" #include "viralloc.h" #include "virstring.h" +#include "virxml.h" =20 =20 char ** @@ -88,3 +89,62 @@ virshDomainNameCompleter(vshControl *ctl, VIR_FREE(ret); return NULL; } + + +char ** +virshDomainInterfaceCompleter(vshControl *ctl, + const vshCmd *cmd, + unsigned int flags) +{ + virshControlPtr priv =3D ctl->privData; + xmlDocPtr xmldoc =3D NULL; + xmlXPathContextPtr ctxt =3D NULL; + int ninterfaces; + xmlNodePtr *interfaces =3D NULL; + size_t i; + unsigned int domainXMLFlags =3D 0; + char **ret =3D NULL; + + virCheckFlags(VIRSH_DOMAIN_INTERFACE_COMPLETER_MAC, NULL); + + if (!priv->conn || virConnectIsAlive(priv->conn) <=3D 0) + return NULL; + + if (vshCommandOptBool(cmd, "config")) + domainXMLFlags =3D VIR_DOMAIN_XML_INACTIVE; + + if (virshDomainGetXML(ctl, cmd, domainXMLFlags, &xmldoc, &ctxt) < 0) + goto error; + + ninterfaces =3D virXPathNodeSet("./devices/interface", ctxt, &interfac= es); + if (ninterfaces < 0) + goto error; + + if (VIR_ALLOC_N(ret, ninterfaces + 1) < 0) + goto error; + + for (i =3D 0; i < ninterfaces; i++) { + ctxt->node =3D interfaces[i]; + + if (!(flags & VIRSH_DOMAIN_INTERFACE_COMPLETER_MAC) && + (ret[i] =3D virXPathString("string(./target/@dev)", ctxt))) + continue; + + /* In case we are dealing with inactive domain XML there's no + * . Offer MAC addresses then. */ + if (!(ret[i] =3D virXPathString("string(./mac/@address)", ctxt))) + goto error; + } + + VIR_FREE(interfaces); + xmlFreeDoc(xmldoc); + xmlXPathFreeContext(ctxt); + return ret; + + error: + VIR_FREE(interfaces); + xmlFreeDoc(xmldoc); + xmlXPathFreeContext(ctxt); + virStringListFree(ret); + return NULL; +} diff --git a/tools/virsh-completer.h b/tools/virsh-completer.h index 288e17909..680cd12ff 100644 --- a/tools/virsh-completer.h +++ b/tools/virsh-completer.h @@ -30,4 +30,12 @@ char ** virshDomainNameCompleter(vshControl *ctl, const vshCmd *cmd, unsigned int flags); =20 +enum { + VIRSH_DOMAIN_INTERFACE_COMPLETER_MAC =3D 1 << 1, /* Return just MACs */ +}; + +char ** virshDomainInterfaceCompleter(vshControl *ctl, + const vshCmd *cmd, + unsigned int flags); + #endif diff --git a/tools/virsh-domain-monitor.c b/tools/virsh-domain-monitor.c index a09eb010c..32a42707e 100644 --- a/tools/virsh-domain-monitor.c +++ b/tools/virsh-domain-monitor.c @@ -659,6 +659,7 @@ static const vshCmdOptDef opts_domif_getlink[] =3D { {.name =3D "interface", .type =3D VSH_OT_DATA, .flags =3D VSH_OFLAG_REQ, + .completer =3D virshDomainInterfaceCompleter, .help =3D N_("interface device (MAC Address)") }, {.name =3D "persistent", @@ -995,6 +996,7 @@ static const vshCmdOptDef opts_domifstat[] =3D { {.name =3D "interface", .type =3D VSH_OT_DATA, .flags =3D VSH_OFLAG_REQ, + .completer =3D virshDomainInterfaceCompleter, .help =3D N_("interface device specified by name or MAC Address") }, {.name =3D NULL} @@ -2149,6 +2151,7 @@ static const vshCmdOptDef opts_domifaddr[] =3D { {.name =3D "interface", .type =3D VSH_OT_STRING, .flags =3D VSH_OFLAG_NONE, + .completer =3D virshDomainInterfaceCompleter, .help =3D N_("network interface name")}, {.name =3D "full", .type =3D VSH_OT_BOOL, diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c index 13f8db3dd..0f329d6d7 100644 --- a/tools/virsh-domain.c +++ b/tools/virsh-domain.c @@ -2977,6 +2977,7 @@ static const vshCmdOptDef opts_domif_setlink[] =3D { {.name =3D "interface", .type =3D VSH_OT_DATA, .flags =3D VSH_OFLAG_REQ, + .completer =3D virshDomainInterfaceCompleter, .help =3D N_("interface device (MAC Address)") }, {.name =3D "state", @@ -3147,6 +3148,7 @@ static const vshCmdOptDef opts_domiftune[] =3D { {.name =3D "interface", .type =3D VSH_OT_DATA, .flags =3D VSH_OFLAG_REQ, + .completer =3D virshDomainInterfaceCompleter, .help =3D N_("interface device (MAC Address)") }, {.name =3D "inbound", @@ -11983,6 +11985,8 @@ static const vshCmdOptDef opts_detach_interface[] = =3D { }, {.name =3D "mac", .type =3D VSH_OT_STRING, + .completer =3D virshDomainInterfaceCompleter, + .completer_flags =3D VIRSH_DOMAIN_INTERFACE_COMPLETER_MAC, .help =3D N_("MAC address") }, VIRSH_COMMON_OPT_DOMAIN_PERSISTENT, --=20 2.13.6 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list From nobody Sat May 4 07:37:05 2024 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) client-ip=209.132.183.28; envelope-from=libvir-list-bounces@redhat.com; helo=mx1.redhat.com; Authentication-Results: mx.zohomail.com; spf=pass (zoho.com: domain of redhat.com designates 209.132.183.28 as permitted sender) smtp.mailfrom=libvir-list-bounces@redhat.com Return-Path: Received: from mx1.redhat.com (mx1.redhat.com [209.132.183.28]) by mx.zohomail.com with SMTPS id 1514913177300676.6306356813102; Tue, 2 Jan 2018 09:12:57 -0800 (PST) Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id D115919C32F; Tue, 2 Jan 2018 17:12:55 +0000 (UTC) Received: from colo-mx.corp.redhat.com (colo-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.20]) by smtp.corp.redhat.com (Postfix) with ESMTPS id A386D5D964; Tue, 2 Jan 2018 17:12:55 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by colo-mx.corp.redhat.com (Postfix) with ESMTP id 6770B180474F; Tue, 2 Jan 2018 17:12:55 +0000 (UTC) Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id w02HCsSO003296 for ; Tue, 2 Jan 2018 12:12:54 -0500 Received: by smtp.corp.redhat.com (Postfix) id 5E8E217557; Tue, 2 Jan 2018 17:12:54 +0000 (UTC) Received: from localhost.localdomain (ovpn-204-45.brq.redhat.com [10.40.204.45]) by smtp.corp.redhat.com (Postfix) with ESMTP id C635E5C899 for ; Tue, 2 Jan 2018 17:12:51 +0000 (UTC) From: Michal Privoznik To: libvir-list@redhat.com Date: Tue, 2 Jan 2018 18:12:11 +0100 Message-Id: In-Reply-To: References: In-Reply-To: References: X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-loop: libvir-list@redhat.com Subject: [libvirt] [PATCH 18/18] virt-admin: Introduce vshAdmServerCompleter X-BeenThere: libvir-list@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk List-Id: Development discussions about the libvirt library & tools List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Sender: libvir-list-bounces@redhat.com Errors-To: libvir-list-bounces@redhat.com X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.29]); Tue, 02 Jan 2018 17:12:56 +0000 (UTC) X-ZohoMail: RSF_0 Z_629925259 SPT_0 Content-Type: text/plain; charset="utf-8" Signed-off-by: Michal Privoznik --- tools/Makefile.am | 9 ++++++ tools/virt-admin-completer.c | 76 ++++++++++++++++++++++++++++++++++++++++= ++++ tools/virt-admin-completer.h | 33 +++++++++++++++++++ tools/virt-admin.c | 8 +++++ 4 files changed, 126 insertions(+) create mode 100644 tools/virt-admin-completer.c create mode 100644 tools/virt-admin-completer.h diff --git a/tools/Makefile.am b/tools/Makefile.am index 7466d8282..48125f516 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -258,6 +258,15 @@ virt_admin_SOURCES =3D \ virt-admin.c virt-admin.h \ $(NULL) =20 +VIRT_ADMIN_COMPLETER =3D \ + virt-admin-completer.c virt-admin-completer.h + +if WITH_READLINE +virt_admin_SOURCES +=3D $(VIRT_ADMIN_COMPLETER) +else ! WITH_READLINE +EXTRA_DIST +=3D $(VIRT_ADMIN_COMPLETER) +endif ! WITH_READLINE + virt_admin_LDFLAGS =3D \ $(AM_LDFLAGS) \ $(COVERAGE_LDFLAGS) \ diff --git a/tools/virt-admin-completer.c b/tools/virt-admin-completer.c new file mode 100644 index 000000000..2cd471f32 --- /dev/null +++ b/tools/virt-admin-completer.c @@ -0,0 +1,76 @@ +/* + * virt-admin-completer.c: virt-admin completer callbacks + * + * Copyright (C) 2017 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * . + * + * Michal Privoznik + * + */ + +#include + +#include "virt-admin-completer.h" +#include "internal.h" +#include "virt-admin.h" +#include "viralloc.h" +#include "virstring.h" + + +char ** +vshAdmServerCompleter(vshControl *ctl, + const vshCmd *cmd ATTRIBUTE_UNUSED, + unsigned int flags) +{ + vshAdmControlPtr priv =3D ctl->privData; + virAdmServerPtr *srvs =3D NULL; + int nsrvs =3D 0; + size_t i =3D 0; + char **ret =3D NULL; + + virCheckFlags(0, NULL); + + if (!priv->conn || virAdmConnectIsAlive(priv->conn) <=3D 0) + return NULL; + + /* Obtain a list of available servers on the daemon */ + if ((nsrvs =3D virAdmConnectListServers(priv->conn, &srvs, 0)) < 0) + return NULL; + + if (VIR_ALLOC_N(ret, nsrvs + 1) < 0) + goto error; + + for (i =3D 0; i < nsrvs; i++) { + const char *name =3D virAdmServerGetName(srvs[i]); + + if (VIR_STRDUP(ret[i], name) < 0) + goto error; + + virAdmServerFree(srvs[i]); + } + VIR_FREE(srvs); + + return ret; + + error: + for (; i < nsrvs; i++) + virAdmServerFree(srvs[i]); + VIR_FREE(srvs); + for (i =3D 0; i < nsrvs; i++) + VIR_FREE(ret[i]); + VIR_FREE(ret); + return ret; +} diff --git a/tools/virt-admin-completer.h b/tools/virt-admin-completer.h new file mode 100644 index 000000000..7507b95c1 --- /dev/null +++ b/tools/virt-admin-completer.h @@ -0,0 +1,33 @@ +/* + * virt-admin-completer.h: virt-admin completer callbacks + * + * Copyright (C) 2017 Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see + * . + * + * Michal Privoznik + * + */ + +#ifndef VIRT_ADMIN_COMPLETER +# define VIRT_ADMIN_COMPLETER + +# include "vsh.h" + +char ** +vshAdmServerCompleter(vshControl *ctl, + const vshCmd *cmd, + unsigned int flags); +#endif diff --git a/tools/virt-admin.c b/tools/virt-admin.c index ef5bada63..c86b5763a 100644 --- a/tools/virt-admin.c +++ b/tools/virt-admin.c @@ -39,6 +39,7 @@ #include "virthread.h" #include "virgettext.h" #include "virtime.h" +#include "virt-admin-completer.h" =20 /* Gnulib doesn't guarantee SA_SIGINFO support. */ #ifndef SA_SIGINFO @@ -428,6 +429,7 @@ static const vshCmdOptDef opts_srv_threadpool_info[] = =3D { {.name =3D "server", .type =3D VSH_OT_DATA, .flags =3D VSH_OFLAG_REQ, + .completer =3D vshAdmServerCompleter, .help =3D N_("Server to retrieve threadpool attributes from."), }, {.name =3D NULL} @@ -489,6 +491,7 @@ static const vshCmdOptDef opts_srv_threadpool_set[] =3D= { {.name =3D "server", .type =3D VSH_OT_DATA, .flags =3D VSH_OFLAG_REQ, + .completer =3D vshAdmServerCompleter, .help =3D N_("Server to alter threadpool attributes on."), }, {.name =3D "min-workers", @@ -595,6 +598,7 @@ static const vshCmdOptDef opts_srv_clients_list[] =3D { {.name =3D "server", .type =3D VSH_OT_DATA, .flags =3D VSH_OFLAG_REQ, + .completer =3D vshAdmServerCompleter, .help =3D N_("server which to list connected clients from"), }, {.name =3D NULL} @@ -676,6 +680,7 @@ static const vshCmdOptDef opts_client_info[] =3D { {.name =3D "server", .type =3D VSH_OT_DATA, .flags =3D VSH_OFLAG_REQ, + .completer =3D vshAdmServerCompleter, .help =3D N_("server to which is connected to"), }, {.name =3D "client", @@ -763,6 +768,7 @@ static const vshCmdOptDef opts_client_disconnect[] =3D { {.name =3D "server", .type =3D VSH_OT_DATA, .flags =3D VSH_OFLAG_REQ, + .completer =3D vshAdmServerCompleter, .help =3D N_("server which the client is currently connected to"), }, {.name =3D "client", @@ -828,6 +834,7 @@ static const vshCmdOptDef opts_srv_clients_info[] =3D { {.name =3D "server", .type =3D VSH_OT_DATA, .flags =3D VSH_OFLAG_REQ, + .completer =3D vshAdmServerCompleter, .help =3D N_("Server to retrieve the client limits from."), }, {.name =3D NULL} @@ -887,6 +894,7 @@ static const vshCmdOptDef opts_srv_clients_set[] =3D { {.name =3D "server", .type =3D VSH_OT_DATA, .flags =3D VSH_OFLAG_REQ, + .completer =3D vshAdmServerCompleter, .help =3D N_("Server to alter the client-related configuration limits= on."), }, {.name =3D "max-clients", --=20 2.13.6 -- libvir-list mailing list libvir-list@redhat.com https://www.redhat.com/mailman/listinfo/libvir-list