From patchwork Tue Oct 8 06:44:55 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Masatake YAMATO X-Patchwork-Id: 11178859 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id BBD6A1747 for ; Tue, 8 Oct 2019 06:53:50 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 9D586217D7 for ; Tue, 8 Oct 2019 06:53:50 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730129AbfJHGxu (ORCPT ); Tue, 8 Oct 2019 02:53:50 -0400 Received: from mx3-rdu2.redhat.com ([66.187.233.73]:50730 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1730123AbfJHGxu (ORCPT ); Tue, 8 Oct 2019 02:53:50 -0400 X-Greylist: delayed 523 seconds by postgrey-1.27 at vger.kernel.org; Tue, 08 Oct 2019 02:53:49 EDT Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.rdu2.redhat.com [10.11.54.5]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id C0E9C402302B for ; Tue, 8 Oct 2019 06:45:10 +0000 (UTC) Received: from slave.localdomain.com (unknown [10.64.193.217]) by smtp.corp.redhat.com (Postfix) with ESMTP id 04BB5178BF; Tue, 8 Oct 2019 06:45:09 +0000 (UTC) From: Masatake YAMATO To: selinux@vger.kernel.org Cc: yamato@redhat.com Subject: [PATCH 1/5] dispol: extend usage() to take error code as an argument Date: Tue, 8 Oct 2019 15:44:55 +0900 Message-Id: <20191008064500.8651-2-yamato@redhat.com> In-Reply-To: <20191008064500.8651-1-yamato@redhat.com> References: <20191008064500.8651-1-yamato@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.11.54.5 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.6]); Tue, 08 Oct 2019 06:45:10 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.6]); Tue, 08 Oct 2019 06:45:10 +0000 (UTC) for IP:'10.11.54.5' DOMAIN:'int-mx05.intmail.prod.int.rdu2.redhat.com' HELO:'smtp.corp.redhat.com' FROM:'yamato@redhat.com' RCPT:'' Sender: selinux-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: selinux@vger.kernel.org This allows dispol command to exit successfully after printing help messages. Signed-off-by: Masatake YAMATO --- checkpolicy/test/dispol.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/checkpolicy/test/dispol.c b/checkpolicy/test/dispol.c index d72d9fb3..1d9556f4 100644 --- a/checkpolicy/test/dispol.c +++ b/checkpolicy/test/dispol.c @@ -36,10 +36,11 @@ static policydb_t policydb; -static __attribute__((__noreturn__)) void usage(const char *progname) +static __attribute__((__noreturn__)) void usage(const char *progname, + int status) { printf("usage: %s binary_pol_file\n\n", progname); - exit(1); + exit(status); } int render_access_mask(uint32_t mask, avtab_key_t * key, policydb_t * p, @@ -395,7 +396,7 @@ int main(int argc, char **argv) struct policy_file pf; if (argc != 2) - usage(argv[0]); + usage(argv[0], 1); fd = open(argv[1], O_RDONLY); if (fd < 0) { From patchwork Tue Oct 8 06:44:57 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Masatake YAMATO X-Patchwork-Id: 11178861 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id E238718B7 for ; Tue, 8 Oct 2019 06:53:50 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id C47BA217D7 for ; Tue, 8 Oct 2019 06:53:50 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730123AbfJHGxu (ORCPT ); Tue, 8 Oct 2019 02:53:50 -0400 Received: from mx3-rdu2.redhat.com ([66.187.233.73]:50734 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1730131AbfJHGxu (ORCPT ); Tue, 8 Oct 2019 02:53:50 -0400 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.rdu2.redhat.com [10.11.54.5]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 9D0FB4023031 for ; Tue, 8 Oct 2019 06:45:18 +0000 (UTC) Received: from slave.localdomain.com (unknown [10.64.193.217]) by smtp.corp.redhat.com (Postfix) with ESMTP id D6441178BA; Tue, 8 Oct 2019 06:45:17 +0000 (UTC) From: Masatake YAMATO To: selinux@vger.kernel.org Cc: yamato@redhat.com Subject: [PATCH 2/5] dispol: add an option for printing the command usage Date: Tue, 8 Oct 2019 15:44:57 +0900 Message-Id: <20191008064500.8651-4-yamato@redhat.com> In-Reply-To: <20191008064500.8651-1-yamato@redhat.com> References: <20191008064500.8651-1-yamato@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.11.54.5 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.6]); Tue, 08 Oct 2019 06:45:18 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.6]); Tue, 08 Oct 2019 06:45:18 +0000 (UTC) for IP:'10.11.54.5' DOMAIN:'int-mx05.intmail.prod.int.rdu2.redhat.com' HELO:'smtp.corp.redhat.com' FROM:'yamato@redhat.com' RCPT:'' Sender: selinux-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: selinux@vger.kernel.org Signed-off-by: Masatake YAMATO --- checkpolicy/test/dispol.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/checkpolicy/test/dispol.c b/checkpolicy/test/dispol.c index 1d9556f4..37b22cf8 100644 --- a/checkpolicy/test/dispol.c +++ b/checkpolicy/test/dispol.c @@ -39,7 +39,7 @@ static policydb_t policydb; static __attribute__((__noreturn__)) void usage(const char *progname, int status) { - printf("usage: %s binary_pol_file\n\n", progname); + printf("usage: %s [-h] binary_pol_file\n\n", progname); exit(status); } @@ -395,7 +395,11 @@ int main(int argc, char **argv) int state; struct policy_file pf; - if (argc != 2) + if (argc <= 1) + usage(argv[0], 1); + else if (strcmp(argv[1], "-h") == 0) + usage(argv[0], 0); + else if (argc != 2) usage(argv[0], 1); fd = open(argv[1], O_RDONLY); From patchwork Tue Oct 8 06:44:58 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Masatake YAMATO X-Patchwork-Id: 11178869 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 6DB931747 for ; Tue, 8 Oct 2019 06:54:59 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 5882220867 for ; Tue, 8 Oct 2019 06:54:59 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730129AbfJHGy6 (ORCPT ); Tue, 8 Oct 2019 02:54:58 -0400 Received: from mx3-rdu2.redhat.com ([66.187.233.73]:45024 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1730054AbfJHGy6 (ORCPT ); Tue, 8 Oct 2019 02:54:58 -0400 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.rdu2.redhat.com [10.11.54.5]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 9ABE3804BBA5 for ; Tue, 8 Oct 2019 06:45:20 +0000 (UTC) Received: from slave.localdomain.com (unknown [10.64.193.217]) by smtp.corp.redhat.com (Postfix) with ESMTP id D41C6178BA; Tue, 8 Oct 2019 06:45:19 +0000 (UTC) From: Masatake YAMATO To: selinux@vger.kernel.org Cc: yamato@redhat.com Subject: [PATCH 3/5] dispol: introduce a local variable representing the input file Date: Tue, 8 Oct 2019 15:44:58 +0900 Message-Id: <20191008064500.8651-5-yamato@redhat.com> In-Reply-To: <20191008064500.8651-1-yamato@redhat.com> References: <20191008064500.8651-1-yamato@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.11.54.5 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.8]); Tue, 08 Oct 2019 06:45:20 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.8]); Tue, 08 Oct 2019 06:45:20 +0000 (UTC) for IP:'10.11.54.5' DOMAIN:'int-mx05.intmail.prod.int.rdu2.redhat.com' HELO:'smtp.corp.redhat.com' FROM:'yamato@redhat.com' RCPT:'' Sender: selinux-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: selinux@vger.kernel.org Signed-off-by: Masatake YAMATO --- checkpolicy/test/dispol.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/checkpolicy/test/dispol.c b/checkpolicy/test/dispol.c index 37b22cf8..26bbba7a 100644 --- a/checkpolicy/test/dispol.c +++ b/checkpolicy/test/dispol.c @@ -394,6 +394,7 @@ int main(int argc, char **argv) char *name; int state; struct policy_file pf; + char *pf_name; if (argc <= 1) usage(argv[0], 1); @@ -401,23 +402,24 @@ int main(int argc, char **argv) usage(argv[0], 0); else if (argc != 2) usage(argv[0], 1); + pf_name = argv[1]; - fd = open(argv[1], O_RDONLY); + fd = open(pf_name, O_RDONLY); if (fd < 0) { fprintf(stderr, "Can't open '%s': %s\n", - argv[1], strerror(errno)); + pf_name, strerror(errno)); exit(1); } if (fstat(fd, &sb) < 0) { fprintf(stderr, "Can't stat '%s': %s\n", - argv[1], strerror(errno)); + pf_name, strerror(errno)); exit(1); } map = mmap(NULL, sb.st_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); if (map == MAP_FAILED) { fprintf(stderr, "Can't map '%s': %s\n", - argv[1], strerror(errno)); + pf_name, strerror(errno)); exit(1); } From patchwork Tue Oct 8 06:44:59 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Masatake YAMATO X-Patchwork-Id: 11178867 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 4E8811747 for ; Tue, 8 Oct 2019 06:54:29 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 393F020867 for ; Tue, 8 Oct 2019 06:54:29 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730131AbfJHGy2 (ORCPT ); Tue, 8 Oct 2019 02:54:28 -0400 Received: from mx3-rdu2.redhat.com ([66.187.233.73]:42894 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1730140AbfJHGy2 (ORCPT ); Tue, 8 Oct 2019 02:54:28 -0400 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.rdu2.redhat.com [10.11.54.5]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 450424074C88 for ; Tue, 8 Oct 2019 06:45:23 +0000 (UTC) Received: from slave.localdomain.com (unknown [10.64.193.217]) by smtp.corp.redhat.com (Postfix) with ESMTP id 7E2D6178BF; Tue, 8 Oct 2019 06:45:22 +0000 (UTC) From: Masatake YAMATO To: selinux@vger.kernel.org Cc: yamato@redhat.com Subject: [PATCH 4/5] dispol: introduce -b option to run commands in batch Date: Tue, 8 Oct 2019 15:44:59 +0900 Message-Id: <20191008064500.8651-6-yamato@redhat.com> In-Reply-To: <20191008064500.8651-1-yamato@redhat.com> References: <20191008064500.8651-1-yamato@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.11.54.5 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.5]); Tue, 08 Oct 2019 06:45:23 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.5]); Tue, 08 Oct 2019 06:45:23 +0000 (UTC) for IP:'10.11.54.5' DOMAIN:'int-mx05.intmail.prod.int.rdu2.redhat.com' HELO:'smtp.corp.redhat.com' FROM:'yamato@redhat.com' RCPT:'' Sender: selinux-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: selinux@vger.kernel.org dispol command requires interaction. It not suitable for using in a script. This change introduces -b that is for running dispol in non-interactively. An example: $ ./dispol -b 1 /sys/fs/selinux/policy allow deltacloudd_log_t tmp_t : filesystem { associate }; allow kern_unconfined sysctl_type : lnk_file { ioctl read ... ... Signed-off-by: Masatake YAMATO --- checkpolicy/test/dispol.c | 49 ++++++++++++++++++++++++++++++--------- 1 file changed, 38 insertions(+), 11 deletions(-) diff --git a/checkpolicy/test/dispol.c b/checkpolicy/test/dispol.c index 26bbba7a..0eaa830a 100644 --- a/checkpolicy/test/dispol.c +++ b/checkpolicy/test/dispol.c @@ -39,7 +39,7 @@ static policydb_t policydb; static __attribute__((__noreturn__)) void usage(const char *progname, int status) { - printf("usage: %s [-h] binary_pol_file\n\n", progname); + printf("usage: %s [-h] [-b cmds] binary_pol_file\n\n", progname); exit(status); } @@ -395,14 +395,21 @@ int main(int argc, char **argv) int state; struct policy_file pf; char *pf_name; + char *cmds = NULL; if (argc <= 1) usage(argv[0], 1); else if (strcmp(argv[1], "-h") == 0) usage(argv[0], 0); - else if (argc != 2) + else if (strcmp(argv[1], "-b") == 0) { + if (argc != 4) + usage(argv[0], 1); + cmds = argv[2]; + pf_name = argv[3]; + } else if (argc == 2) + pf_name = argv[1]; + else usage(argv[0], 1); - pf_name = argv[1]; fd = open(pf_name, O_RDONLY); if (fd < 0) { @@ -424,7 +431,8 @@ int main(int argc, char **argv) } /* read the binary policy */ - fprintf(out_fp, "Reading policy...\n"); + if (!cmds) + fprintf(out_fp, "Reading policy...\n"); policy_file_init(&pf); pf.type = PF_USE_MEMORY; pf.data = map; @@ -433,7 +441,7 @@ int main(int argc, char **argv) fprintf(stderr, "%s: Out of memory!\n", argv[0]); exit(1); } - ret = policydb_read(&policydb, &pf, 1); + ret = policydb_read(&policydb, &pf, cmds == NULL); if (ret) { fprintf(stderr, "%s: error(s) encountered while parsing configuration\n", @@ -441,16 +449,30 @@ int main(int argc, char **argv) exit(1); } - fprintf(stdout, "binary policy file loaded\n\n"); + if (!cmds) + fprintf(stdout, "binary policy file loaded\n\n"); close(fd); - menu(); + if (!cmds) + menu(); for (;;) { - printf("\nCommand (\'m\' for menu): "); - if (fgets(ans, sizeof(ans), stdin) == NULL) { - fprintf(stderr, "fgets failed at line %d: %s\n", __LINE__, + if (cmds) { + ans[0] = *cmds++; + if (ans[0] == '\0') + ans[0] = 'q'; + else if (strchr("7fm", ans[0])) { + fprintf(stderr, + "Unacceptable command in batch mode: %c\n", + ans[0]); + exit(1); + } + } else { + printf("\nCommand (\'m\' for menu): "); + if (fgets(ans, sizeof(ans), stdin) == NULL) { + fprintf(stderr, "fgets failed at line %d: %s\n", __LINE__, strerror(errno)); - continue; + continue; + } } switch (ans[0]) { @@ -551,6 +573,11 @@ int main(int argc, char **argv) menu(); break; default: + if (cmds) { + fprintf(stderr, + "Invalid command: %c\n", ans[0]); + exit(1); + } printf("\nInvalid choice\n"); menu(); break; From patchwork Tue Oct 8 06:45:00 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Masatake YAMATO X-Patchwork-Id: 11178857 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 944D215AB for ; Tue, 8 Oct 2019 06:53:50 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 7F1DC2173B for ; Tue, 8 Oct 2019 06:53:50 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730134AbfJHGxu (ORCPT ); Tue, 8 Oct 2019 02:53:50 -0400 Received: from mx3-rdu2.redhat.com ([66.187.233.73]:50732 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1730129AbfJHGxt (ORCPT ); Tue, 8 Oct 2019 02:53:49 -0400 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.rdu2.redhat.com [10.11.54.5]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 51B294023035 for ; Tue, 8 Oct 2019 06:45:25 +0000 (UTC) Received: from slave.localdomain.com (unknown [10.64.193.217]) by smtp.corp.redhat.com (Postfix) with ESMTP id 83BB2178BA; Tue, 8 Oct 2019 06:45:24 +0000 (UTC) From: Masatake YAMATO To: selinux@vger.kernel.org Cc: yamato@redhat.com Subject: [PATCH 5/5] dispol: add the list of commands for batch mode to help message Date: Tue, 8 Oct 2019 15:45:00 +0900 Message-Id: <20191008064500.8651-7-yamato@redhat.com> In-Reply-To: <20191008064500.8651-1-yamato@redhat.com> References: <20191008064500.8651-1-yamato@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.11.54.5 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.6]); Tue, 08 Oct 2019 06:45:25 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.6]); Tue, 08 Oct 2019 06:45:25 +0000 (UTC) for IP:'10.11.54.5' DOMAIN:'int-mx05.intmail.prod.int.rdu2.redhat.com' HELO:'smtp.corp.redhat.com' FROM:'yamato@redhat.com' RCPT:'' Sender: selinux-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: selinux@vger.kernel.org Signed-off-by: Masatake YAMATO --- checkpolicy/test/dispol.c | 29 +++++++++++++++++++---------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/checkpolicy/test/dispol.c b/checkpolicy/test/dispol.c index 0eaa830a..f6e6a26a 100644 --- a/checkpolicy/test/dispol.c +++ b/checkpolicy/test/dispol.c @@ -36,10 +36,14 @@ static policydb_t policydb; +int menu(int interactive); + static __attribute__((__noreturn__)) void usage(const char *progname, int status) { printf("usage: %s [-h] [-b cmds] binary_pol_file\n\n", progname); + printf("acceptable commands for -b option:\n"); + menu(0); exit(status); } @@ -361,25 +365,30 @@ static void display_filename_trans(policydb_t *p, FILE *fp) hashtab_map(p->filename_trans, filenametr_display, &args); } -int menu(void) +int menu(int interactive) { - printf("\nSelect a command:\n"); + if (interactive) + printf("\nSelect a command:\n"); printf("1) display unconditional AVTAB\n"); printf("2) display conditional AVTAB (entirely)\n"); printf("3) display conditional AVTAB (only ENABLED rules)\n"); printf("4) display conditional AVTAB (only DISABLED rules)\n"); printf("5) display conditional bools\n"); printf("6) display conditional expressions\n"); - printf("7) change a boolean value\n"); + if (interactive) + printf("7) change a boolean value\n"); printf("8) display role transitions\n"); - printf("\n"); + if (interactive) + printf("\n"); printf("c) display policy capabilities\n"); printf("p) display the list of permissive types\n"); printf("u) display unknown handling setting\n"); printf("F) display filename_trans rules\n"); - printf("\n"); - printf("f) set output file\n"); - printf("m) display menu\n"); + if (interactive) { + printf("\n"); + printf("f) set output file\n"); + printf("m) display menu\n"); + } printf("q) quit\n"); return 0; } @@ -454,7 +463,7 @@ int main(int argc, char **argv) close(fd); if (!cmds) - menu(); + menu(cmds == NULL); for (;;) { if (cmds) { ans[0] = *cmds++; @@ -570,7 +579,7 @@ int main(int argc, char **argv) exit(0); break; case 'm': - menu(); + menu(1); break; default: if (cmds) { @@ -579,7 +588,7 @@ int main(int argc, char **argv) exit(1); } printf("\nInvalid choice\n"); - menu(); + menu(1); break; }