From patchwork Tue Dec 18 04:19:46 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sam Mendoza-Jonas X-Patchwork-Id: 1014972 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [203.11.71.2]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 43JlF40WHVz9sBZ for ; Tue, 18 Dec 2018 15:20:40 +1100 (AEDT) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=mendozajonas.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=mendozajonas.com header.i=@mendozajonas.com header.b="IMtU5dEa"; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=messagingengine.com header.i=@messagingengine.com header.b="aSxtYVZJ"; dkim-atps=neutral Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 43JlF34W23zDqXM for ; Tue, 18 Dec 2018 15:20:39 +1100 (AEDT) Authentication-Results: lists.ozlabs.org; dmarc=none (p=none dis=none) header.from=mendozajonas.com Authentication-Results: lists.ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=mendozajonas.com header.i=@mendozajonas.com header.b="IMtU5dEa"; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=messagingengine.com header.i=@messagingengine.com header.b="aSxtYVZJ"; dkim-atps=neutral X-Original-To: petitboot@lists.ozlabs.org Delivered-To: petitboot@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=mendozajonas.com (client-ip=66.111.4.25; helo=out1-smtp.messagingengine.com; envelope-from=sam@mendozajonas.com; receiver=) Authentication-Results: lists.ozlabs.org; dmarc=none (p=none dis=none) header.from=mendozajonas.com Authentication-Results: lists.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=mendozajonas.com header.i=@mendozajonas.com header.b="IMtU5dEa"; dkim=pass (2048-bit key; unprotected) header.d=messagingengine.com header.i=@messagingengine.com header.b="aSxtYVZJ"; dkim-atps=neutral Received: from out1-smtp.messagingengine.com (out1-smtp.messagingengine.com [66.111.4.25]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 43JlDR49wwzDqWp for ; Tue, 18 Dec 2018 15:20:07 +1100 (AEDT) Received: from compute2.internal (compute2.nyi.internal [10.202.2.42]) by mailout.nyi.internal (Postfix) with ESMTP id 21CF822380; Mon, 17 Dec 2018 23:20:05 -0500 (EST) Received: from mailfrontend2 ([10.202.2.163]) by compute2.internal (MEProxy); Mon, 17 Dec 2018 23:20:05 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= mendozajonas.com; h=from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; s=fm1; bh=H5EgjVFl75AX6JWGk5AWOxd7pcAdRfOiPKvVO0Sw454=; b=IMtU5 dEa8iTY5rDgLjTWranIjtsqaIaU4ZIyvDdirS0oTGu22zJuQIGtfDlxJ6NLHbspn +L6PCEhNgIz6zZvhhkAX/kMxG5EVDWMaAZS7n+5LL8RNlSA2Dyjwmblqu8+9L6BQ FvGXQ7K38AT39VFvNNzeFg7k9ewY13WljQJvZ/tfAQM6r+l0DRMjUjtwC+C1FE3k Fkqyk49hk+6q/usLZjFfgbiauLHuj17uYCGQ2H2Ub6rwRXQwJdgUqy8nDeOLG/Bn IdOiWM9XMR9lDT3vOq0DE8f7oHtOCgia1xBxatfkQWgCCcE0PrhybKA49aKp2LbR KLO1rEk0Iiw7lhXlA== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-transfer-encoding:date:from :in-reply-to:message-id:mime-version:references:subject:to :x-me-proxy:x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s= fm1; bh=H5EgjVFl75AX6JWGk5AWOxd7pcAdRfOiPKvVO0Sw454=; b=aSxtYVZJ vpcaf6cj3Tihj2/+zRQezCh3vTRG4oHnVQD5Orq7o3Gls57Qm3K0L47jMdXOuRbD J70uhQEnNB1RFj19iYnB9yho0m16wIZHdNA/F2t5lhQyRXc/WYn+fzNhUV1eSjAK UjcnBA9ATw6FmLIrksS2hzmBNSnryF3ddwA2MAcpS1JZGMlFWnPzkfzlly4YCqme zinDqv0otmvmf7G3UZMeaVVrAjHWgokz0xvIp0y7p/zlJb3K8iFl/d+B+CucysNf 0E8I7LXnli5Rsp/Lcbkzdb5ir4OXHCl7DYMt7FmduwDj1+bMWjoR0Kf8se/U0J3l XlzqJ60fmGXxMA== X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedtkedrudeigedgjeduucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfquhhtnecuuegrihhlohhuthemucef tddtnecunecujfgurhephffvufffkffojghfggfgsedtkeertdertddtnecuhfhrohhmpe furghmuhgvlhcuofgvnhguohiirgdqlfhonhgrshcuoehsrghmsehmvghnughoiigrjhho nhgrshdrtghomheqnecuffhomhgrihhnpehgihhthhhusgdrtghomhdpughotghsrdhrsh enucfkphepuddvvddrleelrdekvddruddtnecurfgrrhgrmhepmhgrihhlfhhrohhmpehs rghmsehmvghnughoiigrjhhonhgrshdrtghomhenucevlhhushhtvghrufhiiigvpedt X-ME-Proxy: Received: from v4.ozlabs.ibm.com (unknown [122.99.82.10]) by mail.messagingengine.com (Postfix) with ESMTPA id 2A3B110341; Mon, 17 Dec 2018 23:20:02 -0500 (EST) From: Samuel Mendoza-Jonas To: petitboot@lists.ozlabs.org Subject: [RFC PATCH 1/8] rust: Add rust interface for parsing JSON Date: Tue, 18 Dec 2018 15:19:46 +1100 Message-Id: <20181218041953.8960-2-sam@mendozajonas.com> X-Mailer: git-send-email 2.20.0 In-Reply-To: <20181218041953.8960-1-sam@mendozajonas.com> References: <20181218041953.8960-1-sam@mendozajonas.com> MIME-Version: 1.0 X-BeenThere: petitboot@lists.ozlabs.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Petitboot bootloader development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Samuel Mendoza-Jonas Errors-To: petitboot-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Petitboot" For plugin commands the command definitions are stored in a JSON file as part of the plugin. Instead of doing even more string parsing in C the Rust library provides an interface to the popular Serde library. The Rust interface provides a few FFI-safe definitions to pass data back and forth but does all the parsing itself. The library is built statically, but some extra work is done in build.rs to help it link into the existing Autoconf more easily. This is heavily based on the libtool crate[0] with some improvements. [0] https://docs.rs/libtool/0.1.1/libtool/ Signed-off-by: Samuel Mendoza-Jonas --- Makefile.am | 1 - configure.ac | 9 ++ lib/Makefile.am | 9 +- lib/rust/Cargo.lock | 117 ++++++++++++++++++++++ lib/rust/Cargo.toml | 20 ++++ lib/rust/Makefile.am | 30 ++++++ lib/rust/build.rs | 70 +++++++++++++ lib/rust/rustlibs.c | 109 ++++++++++++++++++++ lib/rust/rustlibs.h | 11 +++ lib/rust/src/lib.rs | 230 +++++++++++++++++++++++++++++++++++++++++++ lib/types/types.h | 30 ++++++ 11 files changed, 634 insertions(+), 2 deletions(-) create mode 100644 lib/rust/Cargo.lock create mode 100644 lib/rust/Cargo.toml create mode 100644 lib/rust/Makefile.am create mode 100644 lib/rust/build.rs create mode 100644 lib/rust/rustlibs.c create mode 100644 lib/rust/rustlibs.h create mode 100644 lib/rust/src/lib.rs diff --git a/Makefile.am b/Makefile.am index 63456ca4..c0e5c8c2 100644 --- a/Makefile.am +++ b/Makefile.am @@ -72,4 +72,3 @@ include ui/test/Makefile.am include man/Makefile.am include utils/Makefile.am - diff --git a/configure.ac b/configure.ac index 4151b002..3d7e9964 100644 --- a/configure.ac +++ b/configure.ac @@ -450,6 +450,15 @@ esac AC_DEFINE_UNQUOTED(TFTP_TYPE, $tftp_type, [tftp client type]) +AC_ARG_VAR( + [CARGO_OPTS], + [Arguments to cargo] +) +AC_ARG_VAR( + [RUSTC_TARGET_NAME], + [Target as passed to cargo] +) + default_cflags="--std=gnu99 -g \ -Wall -W -Wunused -Wstrict-prototypes -Wmissing-prototypes \ -Wmissing-declarations -Wredundant-decls" diff --git a/lib/Makefile.am b/lib/Makefile.am index 69a66c37..87fe38d6 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -12,6 +12,8 @@ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # +include lib/rust/Makefile.am + core_lib = lib/libpbcore.la noinst_LTLIBRARIES += $(core_lib) @@ -70,7 +72,12 @@ lib_libpbcore_la_SOURCES = \ lib/efi/efivar.h \ lib/efi/efivar.c \ lib/param_list/param_list.c \ - lib/param_list/param_list.h + lib/param_list/param_list.h \ + lib/rust/rustlibs.c \ + lib/rust/rustlibs.c + +lib_libpbcore_la_LIBADD = \ + $(rust_lib) if ENABLE_MTD lib_libpbcore_la_SOURCES += \ diff --git a/lib/rust/Cargo.lock b/lib/rust/Cargo.lock new file mode 100644 index 00000000..5b375927 --- /dev/null +++ b/lib/rust/Cargo.lock @@ -0,0 +1,117 @@ +[[package]] +name = "dtoa" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "itoa" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "libc" +version = "0.2.43" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "libtool" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "num-traits" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "proc-macro2" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "quote" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "rustlibs" +version = "0.1.0" +dependencies = [ + "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)", + "libtool 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "serde" +version = "1.0.28" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[[package]] +name = "serde_derive" +version = "1.0.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_derive_internals 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.12.13 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "serde_derive_internals" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.12.13 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "serde_json" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "itoa 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)", + "num-traits 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "syn" +version = "0.12.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + +[[package]] +name = "unicode-xid" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + +[metadata] +"checksum dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "09c3753c3db574d215cba4ea76018483895d7bff25a31b49ba45db21c48e50ab" +"checksum itoa 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "8324a32baf01e2ae060e9de58ed0bc2320c9a2833491ee36cd3b4c414de4db8c" +"checksum libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)" = "76e3a3ef172f1a0b9a9ff0dd1491ae5e6c948b94479a3021819ba7d860c8645d" +"checksum libtool 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f576520ad5e2848b26568964320a4073984db2a11147ac4f9c2fc7be1f93b8d2" +"checksum num-traits 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "0b3c2bd9b9d21e48e956b763c9f37134dc62d9e95da6edb3f672cacb6caf3cd3" +"checksum proc-macro2 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cd07deb3c6d1d9ff827999c7f9b04cdfd66b1b17ae508e14fe47b620f2282ae0" +"checksum quote 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1eca14c727ad12702eb4b6bfb5a232287dcf8385cb8ca83a3eeaf6519c44c408" +"checksum serde 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)" = "e928fecdb00fe608c96f83a012633383564e730962fc7a0b79225a6acf056798" +"checksum serde_derive 1.0.28 (registry+https://github.com/rust-lang/crates.io-index)" = "95f666a2356d87ce4780ea15b14b13532785579a5cad2dcba5292acc75f6efe2" +"checksum serde_derive_internals 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1fc848d073be32cd982380c06587ea1d433bc1a4c4a111de07ec2286a3ddade8" +"checksum serde_json 1.0.10 (registry+https://github.com/rust-lang/crates.io-index)" = "57781ed845b8e742fc2bf306aba8e3b408fe8c366b900e3769fbc39f49eb8b39" +"checksum syn 0.12.13 (registry+https://github.com/rust-lang/crates.io-index)" = "517f6da31bc53bf080b9a77b29fbd0ff8da2f5a2ebd24c73c2238274a94ac7cb" +"checksum unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" diff --git a/lib/rust/Cargo.toml b/lib/rust/Cargo.toml new file mode 100644 index 00000000..c335d1bb --- /dev/null +++ b/lib/rust/Cargo.toml @@ -0,0 +1,20 @@ +[package] +name = "rustlibs" +build = "build.rs" +version = "0.1.0" +authors = ["Samuel Mendoza-Jonas "] + +[dependencies] +serde = "1.0" +serde_derive = "1.0" +serde_json = "1.0" +libc = "0.2" + +[lib] +crate-type = ["staticlib"] + +[build-dependencies] +libtool = "0.1" + +[profile.release] +lto = true diff --git a/lib/rust/Makefile.am b/lib/rust/Makefile.am new file mode 100644 index 00000000..add42ff2 --- /dev/null +++ b/lib/rust/Makefile.am @@ -0,0 +1,30 @@ +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; version 2 of the License. +# +# This program 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# + +rust_lib = librustlibs.la + +noinst_LTLIBRARIES += $(rust_lib) + +librustlibs_la_SOURCES = "" + +CARGO_TARGET_DIR := $(abs_top_builddir)/lib/rust + +$(rust_lib): + CARGO_TARGET_DIR=$(CARGO_TARGET_DIR) cargo build --release --manifest-path $(top_srcdir)/lib/rust/Cargo.toml $(CARGO_OPTS) + ln -sf $(CARGO_TARGET_DIR)/$(RUSTC_TARGET_NAME)/release/librustlibs.a + ln -sf $(CARGO_TARGET_DIR)/$(RUSTC_TARGET_NAME)/release/librustlibs.la + ln -sf $(CARGO_TARGET_DIR)/$(RUSTC_TARGET_NAME)/release/.libs + +clean-local: + CARGO_TARGET_DIR=$(CARGO_TARGET_DIR) cargo clean --manifest-path $(top_srcdir)/lib/rust/Cargo.toml diff --git a/lib/rust/build.rs b/lib/rust/build.rs new file mode 100644 index 00000000..513e119f --- /dev/null +++ b/lib/rust/build.rs @@ -0,0 +1,70 @@ +/* + * From https://docs.rs/libtool/0.1.1/libtool/ + * Upstream doesn't handle some of the directory structure we use in Petitboot, + * use a few extra environment variables to properly determine the target paths. + */ + +use std::env; +use std::fs::File; +use std::fs; +use std::io::prelude::*; +use std::os::unix::fs::symlink; +use std::path::PathBuf; + +/// Generate libtool archive file ${lib}.la +pub fn generate_convenience_lib(lib: &str) -> std::io::Result<()> { + let self_version = env!("CARGO_PKG_VERSION"); + let profile = env::var("PROFILE").unwrap(); + let target_arch = env::var("TARGET").unwrap(); + let target_dir_env = env::var("CARGO_TARGET_DIR").unwrap(); + + /* Check if the output directory will include the arch */ + let target_dir = if PathBuf::from(format!("{}/{}", + target_dir_env, target_arch)).exists() { + format!("{}/{}/{}", target_dir_env, target_arch, profile) + } else { + format!("{}/{}", target_dir_env, profile) + }; + + /* Location of original static library */ + let old_lib_path = PathBuf::from(format!("{}/{}.a", + target_dir, lib)); + /* Paths for new .la file and symlinks */ + let libs_dir = format!("{}/.libs", target_dir); + let libs_path = PathBuf::from(&libs_dir); + let la_path = PathBuf::from(format!("{}/{}.la", + target_dir, lib)); + let new_lib_path = PathBuf::from(format!("{}/{}.a", libs_dir, lib)); + + match fs::create_dir_all(&libs_path) { + Ok(()) => println!("libs_path created"), + _ => panic!("Failed to create libs_path"), + } + + if la_path.exists() { + fs::remove_file(&la_path)?; + } + + /* PathBuf.exists() traverses symlinks so just try and remove it */ + match fs::remove_file(&new_lib_path) { + Ok(_v) => {}, + Err(e) => println!("Error removing symlink: {:?}", e), + } + + let mut file = File::create(&la_path)?; + writeln!(file, "# {}.la - a libtool library file", lib)?; + writeln!(file, "# Generated by libtool-rust {}", self_version)?; + writeln!(file, "dlname=''")?; + writeln!(file, "library_names=''")?; + writeln!(file, "old_library='{}.a'", lib)?; + writeln!(file, "inherited_linker_flags=' -pthread -lm -ldl'")?; + writeln!(file, "installed=no")?; + writeln!(file, "shouldnotlink=no")?; + + symlink(&old_lib_path, &new_lib_path)?; + Ok(()) +} + +fn main() { + generate_convenience_lib("librustlibs").unwrap(); +} diff --git a/lib/rust/rustlibs.c b/lib/rust/rustlibs.c new file mode 100644 index 00000000..fe686bef --- /dev/null +++ b/lib/rust/rustlibs.c @@ -0,0 +1,109 @@ +/* + * Copyright (C) 2018 IBM Corporation + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program 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 General Public License for more details. + * + */ + +#include +#include + +#include "rustlibs.h" + +enum field_type { + FIELD_STR, + FIELD_I64, + FIELD_F64, +}; + +/* Internal FFI Structs */ +struct ArgumentRaw { + char *name; + enum field_type type; + int64_t arg_i64; + double arg_f64; + char *arg_str; +}; + +struct CommandRaw { + char *platform; + char *name; + char *cmd; + char *args_fmt; + struct ArgumentRaw *args; + size_t n_args; + char *help; +}; + +struct CommandArray { + struct CommandRaw *commands; + size_t len; +}; + +/* Provided by librustlibs */ +struct CommandArray *parse_json(const char *filename); +void free_command_array(struct CommandArray *commands); + +int parse_command_file(void *ctx, const char *path, struct command **commands) +{ + struct CommandArray *raw_commands; + struct CommandRaw *tmp; + struct command *new; + struct argument *arg; + unsigned int i, j, len; + + raw_commands = parse_json(path); + if (!raw_commands) { + pb_log("Failed to parse machine command\n"); + return 0; + } + + len = raw_commands->len; + new = talloc_zero_array(ctx, struct command, len); + for (i = 0; i < len; i++) { + tmp = &raw_commands->commands[i]; + new[i].platform = talloc_strdup(new, tmp->platform); + new[i].name = talloc_strdup(new, tmp->name); + new[i].cmd = talloc_strdup(new, tmp->cmd); + new[i].args_fmt = talloc_strdup(new, tmp->args_fmt); + + new[i].n_args = tmp->n_args; + new[i].args = talloc_zero_array(new, struct argument, + new[i].n_args); + for (j = 0; j < tmp->n_args; j++) { + arg = &new[i].args[j]; + arg->name = talloc_strdup(new, tmp->args[j].name); + arg->type = tmp->args[j].type; + switch (tmp->args[j].type) { + case FIELD_STR: + arg->arg_str = talloc_strdup(new, + tmp->args[j].arg_str); + break; + case FIELD_I64: + arg->arg_i64 = tmp->args[j].arg_i64; + break; + case FIELD_F64: + arg->arg_f64 = tmp->args[j].arg_f64; + break; + default: + pb_log_fn("Unknown field type %d for arg '%s'\n", + tmp->args[j].type, tmp->args[j].name); + break; + } + } + + new[i].help = talloc_strdup(new, tmp->help); + } + + free_command_array(raw_commands); + + *commands = new; + return len; +} diff --git a/lib/rust/rustlibs.h b/lib/rust/rustlibs.h new file mode 100644 index 00000000..0246657b --- /dev/null +++ b/lib/rust/rustlibs.h @@ -0,0 +1,11 @@ +#ifndef __RUST_LIBS__ +#define __RUST_LIBS__ + +#include +#include + +#include + +int parse_command_file(void *ctx, const char *path, struct command **commands); + +#endif /* __RUST_LIBS__ */ diff --git a/lib/rust/src/lib.rs b/lib/rust/src/lib.rs new file mode 100644 index 00000000..5f4b484b --- /dev/null +++ b/lib/rust/src/lib.rs @@ -0,0 +1,230 @@ +#[macro_use] +extern crate serde_derive; + +extern crate serde; +extern crate serde_json; +extern crate libc; + +use std::ffi::CString; +use std::ffi::CStr; +use std::os::raw::c_char; +use std::fs::File; +use std::path::Path; +use std::ptr; +use std::mem; +use libc::{c_long, c_double}; + +/* Rust representations */ +#[derive(Serialize, Deserialize, Debug)] +pub struct Command { + platform: CString, + name: CString, + cmd: CString, + arg_fmt: CString, + args: Vec, + help: CString, +} + +#[derive(Serialize, Deserialize, Debug)] +enum FieldType { + FieldString(CString), + // TODO Commands which display as yes/no that hide some actual command? + // FieldBool(Bool), + FieldInt(i64), + FieldFloat(f64), +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct Argument { + name: CString, + arg: FieldType, +} + +/* FFI respresentations */ +#[repr(C)] +pub struct CommandArray { + bytes: *mut CommandRaw, + len: usize, +} + +#[repr(C)] +pub struct CommandRaw { + platform: *mut c_char, + name: *mut c_char, + cmd: *mut c_char, + arg_fmt: *mut c_char, + args: *mut ArgumentRaw, + n_args: usize, + help: *mut c_char, +} + +impl CommandRaw { + /* + * We need to convert several fields into FFI-suitable types and we + * don't want to 'partially forget' the Command structs, so we + * clone the various fields and forget them. The vec is then shrunk + * and forgotten so it can be passed as an array C will recognise. + */ + fn new(command: &Command) -> CommandRaw { + CommandRaw { + platform: command.platform.clone().into_raw(), + name: command.name.clone().into_raw(), + cmd: command.cmd.clone().into_raw(), + arg_fmt: command.arg_fmt.clone().into_raw(), + args: CommandRaw::args_into_raw(&command.args), + n_args: command.args.len(), + help: command.help.clone().into_raw() + } + } + + fn args_into_raw(args: &Vec) -> *mut ArgumentRaw { + + let mut args_raw = Vec::::new(); + + for arg in args { + let raw_arg = ArgumentRaw::new(&arg); + args_raw.push(raw_arg); + } + + args_raw.shrink_to_fit(); + let ptr = args_raw.as_mut_ptr(); + mem::forget(args_raw); + + return ptr; + } +} + +#[repr(C)] +/* + * Rust enums are not C enums and Rust doesn't have a 'union' concept like in C + * so we just declare all the fields here and set them based on arg_type. + */ +pub struct ArgumentRaw { + name: *mut c_char, + arg_type: FieldTypeRaw, + arg_i64: c_long, + arg_f64: c_double, + arg_str: *mut c_char, +} + +impl ArgumentRaw { + fn new(arg: &Argument) -> ArgumentRaw { + let raw_arg = match arg.arg { + FieldType::FieldString(ref s) => { + ArgumentRaw { + name: arg.name.clone().into_raw(), + arg_type: FieldTypeRaw::RawString, + arg_i64: 0, + arg_f64: 0.0, + arg_str: s.clone().into_raw(), + } + }, + FieldType::FieldInt(i) => { + ArgumentRaw { + name: arg.name.clone().into_raw(), + arg_type: FieldTypeRaw::RawInt, + arg_i64: i, + arg_f64: 0.0, + arg_str: ptr::null_mut(), + } + }, + FieldType::FieldFloat(f) => { + ArgumentRaw { + name: arg.name.clone().into_raw(), + arg_type: FieldTypeRaw::RawFloat, + arg_i64: 0, + arg_f64: f, + arg_str: ptr::null_mut(), + } + }, + }; + return raw_arg; + } +} + +#[repr(C)] +#[derive(PartialEq)] +enum FieldTypeRaw { + RawString = 0, + RawInt, + RawFloat, +} + +/* + * Take a CommandArray pointer from C and reclaim the CommandRaw + * structs and their members/ + * We can't avoid the unsafe {} invocations since we're reading arbitrary + * memory, but it's contained to this function. + */ +#[no_mangle] +pub extern fn free_command_array(commands: *mut CommandArray) { + + let ptr = unsafe { Box::from_raw(commands) }; + let raw_vec = unsafe { Vec::from_raw_parts(ptr.bytes, + ptr.len, + ptr.len) }; + for raw_command in raw_vec.iter() { + unsafe { + let _platform = CString::from_raw(raw_command.platform); + let _name = CString::from_raw(raw_command.name); + let _cmd = CString::from_raw(raw_command.cmd); + let _arg_fmt = CString::from_raw(raw_command.arg_fmt); + /* n_args */ + let arg_vec = Vec::from_raw_parts(raw_command.args, + raw_command.n_args, + raw_command.n_args); + for raw_arg in arg_vec.iter() { + let _name = CString::from_raw(raw_arg.name); + if raw_arg.arg_type == FieldTypeRaw::RawString { + let _arg_str = CString::from_raw(raw_arg.arg_str); + } + } + let _help = CString::from_raw(raw_command.help); + } + } + + /* Frees once it goes out of scope */ + println!("Rust reclaimed {} command structs", raw_vec.len()); +} + +#[no_mangle] +pub extern fn parse_json(filename: *const c_char) -> *mut CommandArray { + + let file: String; + unsafe { + /* Can't trust the promise of a string from C */ + file = CStr::from_ptr(filename).to_string_lossy().into_owned(); + } + + let json_path = Path::new(&file); + let json_file = match File::open(json_path) { + Err(e) => { + println!("Could not open file: {}", e); + return ptr::null_mut(); + } + Ok(f) => f, + }; + + let commands: Vec = match serde_json::from_reader(json_file) { + Err(e) => { + println!("Could not parse JSON: {}", e); + return ptr::null_mut(); + } + Ok(c) => c, + }; + + /* Convert commands into a form more easily passed to C */ + let mut ffi_vec = Vec::::new(); + for command in commands.iter() { + let raw_command = CommandRaw::new(&command); + ffi_vec.push(raw_command); + } + + let len = ffi_vec.len(); + ffi_vec.shrink_to_fit(); + let ffi_ptr = ffi_vec.as_mut_ptr(); + mem::forget(ffi_vec); + + let wrapper = Box::new(CommandArray { bytes: ffi_ptr, len: len }); + return Box::into_raw(wrapper); +} diff --git a/lib/types/types.h b/lib/types/types.h index 9d83d87d..6e5fb7d3 100644 --- a/lib/types/types.h +++ b/lib/types/types.h @@ -66,6 +66,32 @@ struct boot_option { } type; }; +enum cmd_arg_type { + ARG_STR, + ARG_I64, + ARG_F64, +}; + +struct argument { + char *name; + enum cmd_arg_type type; + union { + char *arg_str; + int64_t arg_i64; + double arg_f64; + }; +}; + +struct command { + char *platform; + char *name; + char *cmd; + char *args_fmt; + unsigned int n_args; + struct argument *args; + char *help; +}; + struct plugin_option { char *id; char *name; @@ -74,10 +100,14 @@ struct plugin_option { char *version; char *date; char *plugin_file; + char *command_file; unsigned int n_executables; char **executables; + unsigned int n_commands; + struct command *commands; + void *ui_info; }; From patchwork Tue Dec 18 04:19:47 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sam Mendoza-Jonas X-Patchwork-Id: 1014973 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [203.11.71.2]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 43JlFM0cxzz9sC7 for ; Tue, 18 Dec 2018 15:20:55 +1100 (AEDT) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=mendozajonas.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=mendozajonas.com header.i=@mendozajonas.com header.b="xXkp1YAt"; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=messagingengine.com header.i=@messagingengine.com header.b="Y9B3G+w9"; dkim-atps=neutral Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 43JlFL63P7zDqXZ for ; Tue, 18 Dec 2018 15:20:54 +1100 (AEDT) Authentication-Results: lists.ozlabs.org; dmarc=none (p=none dis=none) header.from=mendozajonas.com Authentication-Results: lists.ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=mendozajonas.com header.i=@mendozajonas.com header.b="xXkp1YAt"; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=messagingengine.com header.i=@messagingengine.com header.b="Y9B3G+w9"; dkim-atps=neutral X-Original-To: petitboot@lists.ozlabs.org Delivered-To: petitboot@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=mendozajonas.com (client-ip=66.111.4.25; helo=out1-smtp.messagingengine.com; envelope-from=sam@mendozajonas.com; receiver=) Authentication-Results: lists.ozlabs.org; dmarc=none (p=none dis=none) header.from=mendozajonas.com Authentication-Results: lists.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=mendozajonas.com header.i=@mendozajonas.com header.b="xXkp1YAt"; dkim=pass (2048-bit key; unprotected) header.d=messagingengine.com header.i=@messagingengine.com header.b="Y9B3G+w9"; dkim-atps=neutral Received: from out1-smtp.messagingengine.com (out1-smtp.messagingengine.com [66.111.4.25]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 43JlDT2TZBzDqWr for ; Tue, 18 Dec 2018 15:20:09 +1100 (AEDT) Received: from compute2.internal (compute2.nyi.internal [10.202.2.42]) by mailout.nyi.internal (Postfix) with ESMTP id BCE6521F5F; Mon, 17 Dec 2018 23:20:06 -0500 (EST) Received: from mailfrontend2 ([10.202.2.163]) by compute2.internal (MEProxy); Mon, 17 Dec 2018 23:20:06 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= mendozajonas.com; h=from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; s=fm1; bh=/ChlXzr6apGacIDaIy77duXXtB1j95cwDICEmRREyqc=; b=xXkp1 YAt+BPXa8DMJctUf3wUaiWSVB1i89TXHdG+keXF+mBVUWt1Ox06gNXBWOCEQfmVc XwU2vfMZeur0RvpskBW7wF0WYdtoOONxYdnubrmYyD/wtdGZ4PEbzS2vugCkZimB BcRWlfAHn8EBwHjtsVsH/LDhvQkSiynjiLrj8DHoG3Bh/WPq6NJrnTKm1lDhUKHG fnCQ2fmKPffkIs01/CjudvYYqJ4vsGEVVCE0X5Xpu/iVnV0a7r2ihLfpLEWHBf+3 4cSZ8q1LMYt0rA6F0jNM9+dAJBwYO5a7afDaorEOrFf4NKlBnqbg4JCxpppYOklO dBs8h+znuQOT+LWtA== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-transfer-encoding:date:from :in-reply-to:message-id:mime-version:references:subject:to :x-me-proxy:x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s= fm1; bh=/ChlXzr6apGacIDaIy77duXXtB1j95cwDICEmRREyqc=; b=Y9B3G+w9 cW+OgFhrg1MY8dCeAhYzIgXuTyUFVfUJZ0HHLaqSDX7dw6W67cJkci3sbR15j+Kc kkC3NgFqbvL4HRLNJ+bbKxd7S9JhqmB0iETa5O3teI+7nYStFrP+vFhTqXJ0MC8E T7lgZcehQkPyaULIhHMZlt5oHLuIb3oHeazzlXeaZuxYIC1qjqnSdRdkQ3dZygkJ Ix8ZRj7vIBahNbf1vyW5eV1G7fdRKadOpf0vcrruVNV0vewMdiqUdfGOJ8DRzl6w iea4uAozbaq1txluEpfg9T0mN5AVaZgMRQvpER5sL8NzTkPRP72PW5qC+/iS3cv7 j8wVusMEElDS0w== X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedtkedrudeigedgjeduucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfquhhtnecuuegrihhlohhuthemucef tddtnecunecujfgurhephffvufffkffojghfggfgsedtkeertdertddtnecuhfhrohhmpe furghmuhgvlhcuofgvnhguohiirgdqlfhonhgrshcuoehsrghmsehmvghnughoiigrjhho nhgrshdrtghomheqnecukfhppeduvddvrdelledrkedvrddutdenucfrrghrrghmpehmrg hilhhfrhhomhepshgrmhesmhgvnhguohiirghjohhnrghsrdgtohhmnecuvehluhhsthgv rhfuihiivgeptd X-ME-Proxy: Received: from v4.ozlabs.ibm.com (unknown [122.99.82.10]) by mail.messagingengine.com (Postfix) with ESMTPA id 3F1DC100E5; Mon, 17 Dec 2018 23:20:05 -0500 (EST) From: Samuel Mendoza-Jonas To: petitboot@lists.ozlabs.org Subject: [RFC PATCH 2/8] lib/pb-protocol: Reflect additions to plugin_option Date: Tue, 18 Dec 2018 15:19:47 +1100 Message-Id: <20181218041953.8960-3-sam@mendozajonas.com> X-Mailer: git-send-email 2.20.0 In-Reply-To: <20181218041953.8960-1-sam@mendozajonas.com> References: <20181218041953.8960-1-sam@mendozajonas.com> MIME-Version: 1.0 X-BeenThere: petitboot@lists.ozlabs.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Petitboot bootloader development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Samuel Mendoza-Jonas Errors-To: petitboot-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Petitboot" Plus add test-protocol which validates the serialisation and de-serialisation of the command structs. Signed-off-by: Samuel Mendoza-Jonas --- lib/pb-protocol/pb-protocol.c | 168 ++++++++++++++++++++++++++++++++++ lib/pb-protocol/pb-protocol.h | 6 ++ test/lib/Makefile.am | 3 +- test/lib/test-protocol.c | 158 ++++++++++++++++++++++++++++++++ 4 files changed, 334 insertions(+), 1 deletion(-) create mode 100644 test/lib/test-protocol.c diff --git a/lib/pb-protocol/pb-protocol.c b/lib/pb-protocol/pb-protocol.c index b4138bbf..a3c4a031 100644 --- a/lib/pb-protocol/pb-protocol.c +++ b/lib/pb-protocol/pb-protocol.c @@ -346,6 +346,41 @@ int pb_protocol_url_len(const char *url) return 4 + optional_strlen(url); } +int pb_protocol_command_len(const struct command *cmd) +{ + unsigned int i, len = 0; + + len += 4 + optional_strlen(cmd->platform); + len += 4 + optional_strlen(cmd->name); + len += 4 + optional_strlen(cmd->cmd); + len += 4 + optional_strlen(cmd->args_fmt); + len += 4; /* n_args */ + + for (i = 0; i < cmd->n_args; i++) { + len += 4 + optional_strlen(cmd->args[i].name); + len += 4; /* type */ + switch(cmd->args[i].type) { + case ARG_STR: + len += 4 + optional_strlen(cmd->args[i].arg_str); + break; + case ARG_I64: + len += sizeof(cmd->args[i].arg_i64); + break; + case ARG_F64: + len += sizeof(cmd->args[i].arg_f64); + break; + default: + pb_log("Argument %s has unknown field type %d\n", + cmd->args[i].name, + cmd->args[i].type); + break; + } + } + + len += 4 + optional_strlen(cmd->help); + + return len; +} int pb_protocol_plugin_option_len(const struct plugin_option *opt) { @@ -363,6 +398,10 @@ int pb_protocol_plugin_option_len(const struct plugin_option *opt) for (i = 0; i < opt->n_executables; i++) len += 4 + optional_strlen(opt->executables[i]); + len += 4; /* command options */ + for (i = 0; i < opt->n_commands; i++) + len += pb_protocol_command_len(&opt->commands[i]); + return len; } @@ -682,6 +721,51 @@ int pb_protocol_serialise_url(const char *url, char *buf, int buf_len) return 0; } +int pb_protocol_serialise_command(char *buf, + const struct command *config) +{ + char *pos = buf; + unsigned int i; + + pos += pb_protocol_serialise_string(pos, config->platform); + pos += pb_protocol_serialise_string(pos, config->name); + pos += pb_protocol_serialise_string(pos, config->cmd); + pos += pb_protocol_serialise_string(pos, config->args_fmt); + + *(uint32_t *)pos = __cpu_to_be32(config->n_args); + pos += 4; + + for (i = 0; i < config->n_args; i++) { + pos += pb_protocol_serialise_string(pos, config->args[i].name); + *(enum cmd_arg_type *)pos = config->args[i].type; + pos += sizeof(enum cmd_arg_type); + + switch(config->args[i].type) { + case ARG_STR: + pos += pb_protocol_serialise_string(pos, + config->args[i].arg_str); + break; + case ARG_I64: + *(int64_t *)pos = __cpu_to_be64(config->args[i].arg_i64); + pos += sizeof(int64_t); + break; + case ARG_F64: + memcpy(pos, &config->args[i].arg_f64, sizeof(double)); + pos += sizeof(double); + break; + default: + pb_log("Argument %s with unknown field type %d skipped\n", + config->args[i].name, + config->args[i].type); + break; + } + } + + pos += pb_protocol_serialise_string(pos, config->help); + + return pos - buf; +} + int pb_protocol_serialise_plugin_option(const struct plugin_option *opt, char *buf, int buf_len) { @@ -702,6 +786,13 @@ int pb_protocol_serialise_plugin_option(const struct plugin_option *opt, for (i = 0; i < opt->n_executables; i++) pos += pb_protocol_serialise_string(pos, opt->executables[i]); + *(uint32_t *)pos = __cpu_to_be32(opt->n_commands); + pos += 4; + + for (i = 0; i < opt->n_commands; i++) + pos += pb_protocol_serialise_command(pos, + &opt->commands[i]); + assert(pos <= buf + buf_len); (void)buf_len; @@ -1318,6 +1409,71 @@ out: return rc; } +int pb_protocol_deserialise_command(void *ctx, const char **pos, + unsigned int *len, struct command *cmd) +{ + unsigned int i; + char *str; + int rc = -1; + + if (read_string(ctx, pos, len, &str)) + goto out; + cmd->platform = str; + + if (read_string(ctx, pos, len, &str)) + goto out; + cmd->name = str; + + if (read_string(ctx, pos, len, &str)) + goto out; + cmd->cmd = str; + + if (read_string(ctx, pos, len, &str)) + goto out; + cmd->args_fmt = str; + + if (read_u32(pos, len, &cmd->n_args)) + goto out; + + cmd->args = talloc_zero_array(ctx, struct argument, cmd->n_args); + for (i = 0; i < cmd->n_args; i++) { + if (read_string(ctx, pos, len, &str)) + goto out; + cmd->args[i].name = str; + + cmd->args[i].type = *(enum cmd_arg_type *)*pos; + *pos += sizeof(enum cmd_arg_type); + + switch (cmd->args[i].type) { + case ARG_STR: + if (read_string(ctx, pos, len, &str)) + goto out; + cmd->args[i].arg_str = str; + break; + case ARG_I64: + cmd->args[i].arg_i64 = __be64_to_cpu(*(int64_t *)(*pos)); + *pos += sizeof(int64_t); + break; + case ARG_F64: + memcpy(&cmd->args[i].arg_f64, *pos, sizeof(double)); + *pos += sizeof(double); + break; + default: + pb_log("Unknown field type %d for argument %s\n", + cmd->args[i].type, + cmd->args[i].name); + } + } + + if (read_string(ctx, pos, len, &str)) + goto out; + cmd->help = str; + + rc = 0; +out: + return rc; +} + int pb_protocol_deserialise_plugin_option(struct plugin_option *opt, const struct pb_protocol_message *message) { @@ -1371,6 +1527,18 @@ int pb_protocol_deserialise_plugin_option(struct plugin_option *opt, opt->executables[i] = talloc_strdup(opt, str); } + if (read_u32(&pos, &len, &tmp)) + goto out; + opt->n_commands = tmp; + + opt->commands = talloc_zero_array(opt, struct command, opt->n_commands); + if (!opt->commands) + goto out; + + for (i = 0; i < opt->n_commands; i++) + pb_protocol_deserialise_command(opt, &pos, &len, + &opt->commands[i]); + rc = 0; out: return rc; diff --git a/lib/pb-protocol/pb-protocol.h b/lib/pb-protocol/pb-protocol.h index 1d6c0485..38b241ce 100644 --- a/lib/pb-protocol/pb-protocol.h +++ b/lib/pb-protocol/pb-protocol.h @@ -63,6 +63,7 @@ int pb_protocol_boot_status_len(const struct status *status); int pb_protocol_system_info_len(const struct system_info *sysinfo); int pb_protocol_config_len(const struct config *config); int pb_protocol_url_len(const char *url); +int pb_protocol_command_len(const struct command *command); int pb_protocol_plugin_option_len(const struct plugin_option *opt); int pb_protocol_temp_autoboot_len(const struct autoboot_option *opt); int pb_protocol_authenticate_len(struct auth_message *msg); @@ -88,6 +89,8 @@ int pb_protocol_serialise_system_info(const struct system_info *sysinfo, int pb_protocol_serialise_config(const struct config *config, char *buf, int buf_len); int pb_protocol_serialise_url(const char *url, char *buf, int buf_len); +int pb_protocol_serialise_command(char *buf, + const struct command *command); int pb_protocol_serialise_plugin_option(const struct plugin_option *opt, char *buf, int buf_len); int pb_protocol_serialise_temp_autoboot(const struct autoboot_option *opt, @@ -120,6 +123,9 @@ int pb_protocol_deserialise_system_info(struct system_info *sysinfo, int pb_protocol_deserialise_config(struct config *config, const struct pb_protocol_message *message); +int pb_protocol_deserialise_command(void *ctx, const char **pos, + unsigned int *len, struct command *command); + int pb_protocol_deserialise_plugin_option(struct plugin_option *opt, const struct pb_protocol_message *message); diff --git a/test/lib/Makefile.am b/test/lib/Makefile.am index 65991a55..1f49bbce 100644 --- a/test/lib/Makefile.am +++ b/test/lib/Makefile.am @@ -24,7 +24,8 @@ lib_TESTS = \ test/lib/test-process-both \ test/lib/test-process-stdout-eintr \ test/lib/test-fold \ - test/lib/test-efivar + test/lib/test-efivar \ + test/lib/test-protocol if WITH_OPENSSL lib_TESTS += \ diff --git a/test/lib/test-protocol.c b/test/lib/test-protocol.c new file mode 100644 index 00000000..18cb7f5d --- /dev/null +++ b/test/lib/test-protocol.c @@ -0,0 +1,158 @@ + +#define _GNU_SOURCE + +#include +#include +#include + +#include +#include +#include + +static int test_command_protocol(void *ctx) +{ + unsigned int len, write_len, read_len; + struct command *write, *read; + const char *read_buf; + char *buf, *pos; + + write = talloc_zero(ctx, struct command); + if (!write) + return -1; + + write->platform = talloc_asprintf(ctx, "platform"); + write->name = talloc_asprintf(ctx, "test config"); + write->cmd = talloc_asprintf(ctx, "command"); + write->args_fmt = talloc_asprintf(ctx, "{} {} {}"); + write->n_args = 3; + write->args = talloc_zero_array(write, struct argument, write->n_args); + + write->args[0].name = talloc_asprintf(write, "arg 0"); + write->args[0].type = ARG_STR; + write->args[0].arg_str = talloc_asprintf(write, "string arg"); + + write->args[1].name = talloc_asprintf(write, "arg 1"); + write->args[1].type = ARG_I64; + write->args[1].arg_i64 = 5; + + write->args[2].name = talloc_asprintf(write, "arg 2"); + write->args[2].type = ARG_F64; + write->args[2].arg_f64 = 4.4; + + write->help = talloc_asprintf(write, "good luck"); + + len = pb_protocol_command_len(write); + fprintf(stderr, "write config is %d bytes\n", len); + + buf = talloc_array(ctx, char, len); + pos = buf; + + write_len = pb_protocol_serialise_command(pos, write); + if (write_len != len) { + fprintf(stderr, "Failed to serialise machine config\n"); + fprintf(stderr, "Serialised length does not match expected (%lu vs %d)\n", + pos - buf, write_len); + return -1; + } + + read_buf = talloc_memdup(ctx, buf, write_len); + read_len = write_len; + read = talloc_zero(ctx, struct command); + if (pb_protocol_deserialise_command(ctx, &read_buf, &read_len, read)) { + fprintf(stderr, "Failed to deserialise machine config\n"); + return -1; + } + + if (strcmp(write->platform, read->platform)) { + fprintf(stderr, "platform field does not match: %s vs %s\n", + write->platform, read->platform); + return -1; + } + if (strcmp(write->name, read->name)) { + fprintf(stderr, "name field does not match: %s vs %s\n", + write->name, read->name); + return -1; + } + if (strcmp(write->cmd, read->cmd)) { + fprintf(stderr, "cmd field does not match: %s vs %s\n", + write->cmd, read->cmd); + return -1; + } + if (strcmp(write->args_fmt, read->args_fmt)) { + fprintf(stderr, "args_fmt field does not match: %s vs %s\n", + write->args_fmt, read->args_fmt); + return -1; + } + + if (write->n_args != read->n_args) { + fprintf(stderr, "n_args mismatch: %u vs %u\n", write->n_args, + read->n_args); + return -1; + } + + if (strcmp(write->args[0].name, read->args[0].name)) { + fprintf(stderr, "arg 0 name does not match: %s vs %s\n", + write->args[0].name, read->args[0].name); + return -1; + } + if (write->args[0].type != read->args[0].type) { + fprintf(stderr, "arg 0 field type does not match: %d vs %d\n", + write->args[0].type, read->args[0].type); + return -1; + } + if (strcmp(write->args[0].arg_str, read->args[0].arg_str)) { + fprintf(stderr, "arg 0 arg does not match: %s vs %s\n", + write->args[0].arg_str, read->args[0].arg_str); + return -1; + } + + if (strcmp(write->args[1].name, read->args[1].name)) { + fprintf(stderr, "arg 1 name does not match: %s vs %s\n", + write->args[1].name, read->args[1].name); + return -1; + } + if (write->args[1].type != read->args[1].type) { + fprintf(stderr, "arg 1 field type does not match: %d vs %d\n", + write->args[1].type, read->args[1].type); + return -1; + } + if (write->args[1].arg_i64 != read->args[1].arg_i64) { + fprintf(stderr, "arg 1 field arg does not match: %ld vs %ld\n", + write->args[1].arg_i64, read->args[1].arg_i64); + return -1; + } + + if (strcmp(write->args[2].name, read->args[2].name)) { + fprintf(stderr, "arg 2 name does not match: %s vs %s\n", + write->args[2].name, read->args[2].name); + return -1; + } + if (write->args[2].type != read->args[2].type) { + fprintf(stderr, "arg 2 field type does not match: %d vs %d\n", + write->args[2].type, read->args[2].type); + return -1; + } + if (write->args[2].arg_f64 != read->args[2].arg_f64) { + fprintf(stderr, "arg 2 field arg does not match: %f vs %f\n", + write->args[2].arg_f64, read->args[2].arg_f64); + return -1; + } + + return 0; +} + +int main(void) +{ + void *ctx; + int rc = 0; + + ctx = talloc_new(NULL); + + rc = test_command_protocol(ctx); + if (rc) + printf("FAIL: test_command\n"); + + talloc_free(ctx); + + return rc ? EXIT_FAILURE : EXIT_SUCCESS; +} From patchwork Tue Dec 18 04:19:48 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sam Mendoza-Jonas X-Patchwork-Id: 1014968 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [203.11.71.2]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 43JlDh1tN2z9sC7 for ; Tue, 18 Dec 2018 15:20:20 +1100 (AEDT) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=mendozajonas.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=mendozajonas.com header.i=@mendozajonas.com header.b="ecRgGZvV"; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=messagingengine.com header.i=@messagingengine.com header.b="UA14DFuf"; dkim-atps=neutral Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 43JlDg5SgtzDqXP for ; Tue, 18 Dec 2018 15:20:19 +1100 (AEDT) Authentication-Results: lists.ozlabs.org; dmarc=none (p=none dis=none) header.from=mendozajonas.com Authentication-Results: lists.ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=mendozajonas.com header.i=@mendozajonas.com header.b="ecRgGZvV"; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=messagingengine.com header.i=@messagingengine.com header.b="UA14DFuf"; dkim-atps=neutral X-Original-To: petitboot@lists.ozlabs.org Delivered-To: petitboot@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=mendozajonas.com (client-ip=66.111.4.25; helo=out1-smtp.messagingengine.com; envelope-from=sam@mendozajonas.com; receiver=) Authentication-Results: lists.ozlabs.org; dmarc=none (p=none dis=none) header.from=mendozajonas.com Authentication-Results: lists.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=mendozajonas.com header.i=@mendozajonas.com header.b="ecRgGZvV"; dkim=pass (2048-bit key; unprotected) header.d=messagingengine.com header.i=@messagingengine.com header.b="UA14DFuf"; dkim-atps=neutral Received: from out1-smtp.messagingengine.com (out1-smtp.messagingengine.com [66.111.4.25]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 43JlDV74XwzDqWs for ; Tue, 18 Dec 2018 15:20:10 +1100 (AEDT) Received: from compute2.internal (compute2.nyi.internal [10.202.2.42]) by mailout.nyi.internal (Postfix) with ESMTP id 4B2D022AD6; Mon, 17 Dec 2018 23:20:08 -0500 (EST) Received: from mailfrontend2 ([10.202.2.163]) by compute2.internal (MEProxy); Mon, 17 Dec 2018 23:20:08 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= mendozajonas.com; h=from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; s=fm1; bh=l2Sox6JXhQxSozbS70lfe52ti78FG7K/HShevIwYPIA=; b=ecRgG ZvV4MgYNeJsvWU1Mvpo1g4gWB3jSAIfQ6fzA/mtvu2D5ikywueUxnDdTPQ9dZ/he tBBSL+rGZM/Q/Eq6VNflYt5ThsDYjhqa48GLBFQAnhnmGflFqQ8x6Ga8RcRq2RgV Ays1QBfyuqkRcg2mt7sVcmS0STP2hjh5ELqAoZmTprZ4Q7UPgDne3gaT9hJMsi43 3TthClaPYYmJh8LiW41sbWFU8SWIwEjQN58jLaY0gNZcKu19Yh+KC8cNHo0/saID 2MCvjkd2baHR1FjQ3aBi9iQFnGa4jEOqgzciPo+WksjxFV509U55oF2igIzF+rR1 tIEZwfhIOdVp+l/Zg== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-transfer-encoding:date:from :in-reply-to:message-id:mime-version:references:subject:to :x-me-proxy:x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s= fm1; bh=l2Sox6JXhQxSozbS70lfe52ti78FG7K/HShevIwYPIA=; b=UA14DFuf UXVgOmRdGGYbpIvX7+UTmHs/+qtGJWxb70jLc2l4s0rkHhH8vztSwxAmPft8SyCD v1yIK+4fLwpne/2lRSYrm3bohfI5iRzjO+nMT6E5TbuSLxyH6hfkKeOgeSCnIThf xYP8golzXEOQ8cdvjteyhjVW3vv2Md4B8gq4bDRx22V1mSiSTetrxkMhH9p+rm8n 5hzIbIwkBWcBafdUzqr1yRaxLJz7E4cOAKwScgnM17k8/dHu3dde6jXWafoo9d5q EtyglQWMxZSnbWK3Ta4tKmsqnWIRRV/IAb6AEf3bFuhd4xJcrWSEvJX7jloBSavJ nNX4UCAT1FMSeg== X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedtkedrudeigedgjeduucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfquhhtnecuuegrihhlohhuthemucef tddtnecunecujfgurhephffvufffkffojghfggfgsedtkeertdertddtnecuhfhrohhmpe furghmuhgvlhcuofgvnhguohiirgdqlfhonhgrshcuoehsrghmsehmvghnughoiigrjhho nhgrshdrtghomheqnecukfhppeduvddvrdelledrkedvrddutdenucfrrghrrghmpehmrg hilhhfrhhomhepshgrmhesmhgvnhguohiirghjohhnrghsrdgtohhmnecuvehluhhsthgv rhfuihiivgeptd X-ME-Proxy: Received: from v4.ozlabs.ibm.com (unknown [122.99.82.10]) by mail.messagingengine.com (Postfix) with ESMTPA id D878B100E5; Mon, 17 Dec 2018 23:20:06 -0500 (EST) From: Samuel Mendoza-Jonas To: petitboot@lists.ozlabs.org Subject: [RFC PATCH 3/8] utils: Add plugin_commands parameter Date: Tue, 18 Dec 2018 15:19:48 +1100 Message-Id: <20181218041953.8960-4-sam@mendozajonas.com> X-Mailer: git-send-email 2.20.0 In-Reply-To: <20181218041953.8960-1-sam@mendozajonas.com> References: <20181218041953.8960-1-sam@mendozajonas.com> MIME-Version: 1.0 X-BeenThere: petitboot@lists.ozlabs.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Petitboot bootloader development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Samuel Mendoza-Jonas Errors-To: petitboot-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Petitboot" This points to an optional JSON file providing detailed command examples. The format is an array of command objects which define a platform name if appropriate, command name, command executable, argument format string, and an array of arguments containing name and arguments. At the moment three argument types are recognised: FieldString, FieldInt, and FieldFloat (string, int64_t, and double respectively). For example: [ { "platform": "any", "name": "Set NVRAM parameter", "cmd": "nvram", "arg_fmt": "-p {} --update-config {}={}", "args": [ { "name": "Partition", "arg": { "FieldString": "common" } }, { "name": "Parameter", "arg": { "FieldString": "some" } }, { "name": "Value", "arg": { "FieldString": "value" } } ], "help": "Example: Set an NVRAM parameter" }, { "platform": "witherspoon", "name": "Foo Memory Allocation", "cmd": "nvram", "arg_fmt": "-p {} --update-config foo_mem_amt={}", "args": [ { "name": "Partition", "arg": { "FieldString": "ibm,skiboot" } }, { "name": "Amount (MB)", "arg": { "FieldInt": 0 } } ], "help": "Memory to be allocated for some feature" } ] Signed-off-by: Samuel Mendoza-Jonas --- discover/user-event.c | 2 ++ utils/pb-plugin | 8 +++++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/discover/user-event.c b/discover/user-event.c index d3d4a5e8..cbbec1a0 100644 --- a/discover/user-event.c +++ b/discover/user-event.c @@ -601,6 +601,8 @@ static int user_event_plugin(struct user_event *uev, struct event *event) opt->date = talloc_strdup(opt, event_get_param(event, "date")); opt->plugin_file = talloc_strdup(opt, event_get_param(event, "source_file")); + opt->command_file = talloc_strdup(opt, + event_get_param(event, "plugin_commands")); executables = talloc_strdup(opt, event_get_param(event, "executables")); if (!executables) { diff --git a/utils/pb-plugin b/utils/pb-plugin index a42d0515..b162f4b9 100755 --- a/utils/pb-plugin +++ b/utils/pb-plugin @@ -2,7 +2,7 @@ __dest=/ __pb_mount_dir=/var/petitboot/mnt/dev/ -plugin_abi=1 +plugin_abi=2 plugin_ext=pb-plugin plugin_meta=pb-plugin.conf plugin_meta_dir=etc/preboot-plugins/ @@ -235,6 +235,7 @@ do_install() name=$PLUGIN_NAME id=$PLUGIN_ID version=$PLUGIN_VERSION \ vendor=$PLUGIN_VENDOR vendor_id=$PLUGIN_VENDOR_ID \ date=$PLUGIN_DATE executables="$PLUGIN_EXECUTABLES" \ + plugin_commands="${__dest}/${PLUGIN_COMMANDS}" \ source_file=$url installed="yes" echo "Plugin installed" @@ -364,6 +365,10 @@ shell environment (eg, /usr/bin/my-raid-config). If multiple executables are provided, separate with a space. EOF read executables +cat < X-Patchwork-Id: 1014977 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [203.11.71.2]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 43JlFj3JCBz9sBZ for ; Tue, 18 Dec 2018 15:21:13 +1100 (AEDT) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=mendozajonas.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=mendozajonas.com header.i=@mendozajonas.com header.b="vtiMWUks"; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=messagingengine.com header.i=@messagingengine.com header.b="fp+H0M9e"; dkim-atps=neutral Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 43JlFj0BT2zDqQB for ; Tue, 18 Dec 2018 15:21:13 +1100 (AEDT) Authentication-Results: lists.ozlabs.org; dmarc=none (p=none dis=none) header.from=mendozajonas.com Authentication-Results: lists.ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=mendozajonas.com header.i=@mendozajonas.com header.b="vtiMWUks"; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=messagingengine.com header.i=@messagingengine.com header.b="fp+H0M9e"; dkim-atps=neutral X-Original-To: petitboot@lists.ozlabs.org Delivered-To: petitboot@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=mendozajonas.com (client-ip=66.111.4.25; helo=out1-smtp.messagingengine.com; envelope-from=sam@mendozajonas.com; receiver=) Authentication-Results: lists.ozlabs.org; dmarc=none (p=none dis=none) header.from=mendozajonas.com Authentication-Results: lists.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=mendozajonas.com header.i=@mendozajonas.com header.b="vtiMWUks"; dkim=pass (2048-bit key; unprotected) header.d=messagingengine.com header.i=@messagingengine.com header.b="fp+H0M9e"; dkim-atps=neutral Received: from out1-smtp.messagingengine.com (out1-smtp.messagingengine.com [66.111.4.25]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 43JlDX2ZLLzDqWm for ; Tue, 18 Dec 2018 15:20:12 +1100 (AEDT) Received: from compute2.internal (compute2.nyi.internal [10.202.2.42]) by mailout.nyi.internal (Postfix) with ESMTP id E4A9C22B97; Mon, 17 Dec 2018 23:20:09 -0500 (EST) Received: from mailfrontend2 ([10.202.2.163]) by compute2.internal (MEProxy); Mon, 17 Dec 2018 23:20:09 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= mendozajonas.com; h=from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; s=fm1; bh=aArxCSxW8ayr4R1BDu3ijnovRKLPMYJYgTCWlT6bF0I=; b=vtiMW UksCLbHSQnG5/67SxQ5k6zLQMF8GjFBc6cK+WzvMEC0YB/vGakHZJRJy+3X7aQoG c3LvguD0IndQpUr2ksRgmNjPzsqI5JYXEuleZgRzvPQj3s9MMB670nJuEMKmCila M6Q8rJQReuQhQywqycuOsQMq00VS1JvW73jC+Bg9HregZmqCWVBQV2520gK2H5O3 Tu7C6AF281Oj2mTyN8a5mgiQbV5vF6vt8jfa1a5jtITmjxIL9h4DEW/0I+0cDhKK yx5ggmuO6tMbH3UoE9Yiq4EwDH9Flmnti2szBhCxhngh5FX1p13R502IDXh/GHfl ZljB8nPnhMC1sVOsg== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-transfer-encoding:date:from :in-reply-to:message-id:mime-version:references:subject:to :x-me-proxy:x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s= fm1; bh=aArxCSxW8ayr4R1BDu3ijnovRKLPMYJYgTCWlT6bF0I=; b=fp+H0M9e aa+Si/rnj3wGgvBdoSl2F2970n7lL0rc02ZHNrD+TyZSJjPjibQ42O0pXhAM+h0P Ko4NnimrXQtH8stxhKOwOPMYHaTJ/c1LUfqZ3eijc/WeuqBIyqGEklnBQSoZ6BmQ oV/B3jGDcBzjDcuyVK9Dki3hiG15d7xkdcU8KPwx53DvHpwUDpP+dce5GGHphffj qi3Wudfue6seFdNqhdgbyUTLlt1NCn4ffuL9LEuiMO3f/vlHV1ZUbaX1t0z929wf QgNIdCwE0MfUXDGZnfNLJruJkhP+iTZN0SUu7jEv1khXqBsXvUQltzsyxzQB3jgK H43NVrvNRJp3/Q== X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedtkedrudeigedgjeduucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfquhhtnecuuegrihhlohhuthemucef tddtnecunecujfgurhephffvufffkffojghfggfgsedtkeertdertddtnecuhfhrohhmpe furghmuhgvlhcuofgvnhguohiirgdqlfhonhgrshcuoehsrghmsehmvghnughoiigrjhho nhgrshdrtghomheqnecukfhppeduvddvrdelledrkedvrddutdenucfrrghrrghmpehmrg hilhhfrhhomhepshgrmhesmhgvnhguohiirghjohhnrghsrdgtohhmnecuvehluhhsthgv rhfuihiivgeptd X-ME-Proxy: Received: from v4.ozlabs.ibm.com (unknown [122.99.82.10]) by mail.messagingengine.com (Postfix) with ESMTPA id 6BC81100E5; Mon, 17 Dec 2018 23:20:08 -0500 (EST) From: Samuel Mendoza-Jonas To: petitboot@lists.ozlabs.org Subject: [RFC PATCH 4/8] utils/pb-exec: Prepend sudo if normal user Date: Tue, 18 Dec 2018 15:19:49 +1100 Message-Id: <20181218041953.8960-5-sam@mendozajonas.com> X-Mailer: git-send-email 2.20.0 In-Reply-To: <20181218041953.8960-1-sam@mendozajonas.com> References: <20181218041953.8960-1-sam@mendozajonas.com> MIME-Version: 1.0 X-BeenThere: petitboot@lists.ozlabs.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Petitboot bootloader development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Samuel Mendoza-Jonas Errors-To: petitboot-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Petitboot" Signed-off-by: Samuel Mendoza-Jonas --- utils/pb-exec | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/utils/pb-exec b/utils/pb-exec index bfe13f6b..c5cc8d10 100755 --- a/utils/pb-exec +++ b/utils/pb-exec @@ -1,7 +1,13 @@ #!/bin/sh +if [[ "$(id -u)" != "0" ]]; then + PREFIX="sudo" +else + PREFIX="" +fi + # Run a program specified by Petitboot. -$@ +$PREFIX $@ echo "$0 ran '$@'" # Wait for the user to exit back to Petitboot. From patchwork Tue Dec 18 04:19:50 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sam Mendoza-Jonas X-Patchwork-Id: 1014978 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 43JlFx2JWPz9sBZ for ; Tue, 18 Dec 2018 15:21:25 +1100 (AEDT) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=mendozajonas.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=mendozajonas.com header.i=@mendozajonas.com header.b="HTAyA85p"; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=messagingengine.com header.i=@messagingengine.com header.b="buD5ZVar"; dkim-atps=neutral Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 43JlFw5951zDq5Z for ; Tue, 18 Dec 2018 15:21:24 +1100 (AEDT) Authentication-Results: lists.ozlabs.org; dmarc=none (p=none dis=none) header.from=mendozajonas.com Authentication-Results: lists.ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=mendozajonas.com header.i=@mendozajonas.com header.b="HTAyA85p"; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=messagingengine.com header.i=@messagingengine.com header.b="buD5ZVar"; dkim-atps=neutral X-Original-To: petitboot@lists.ozlabs.org Delivered-To: petitboot@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=mendozajonas.com (client-ip=66.111.4.25; helo=out1-smtp.messagingengine.com; envelope-from=sam@mendozajonas.com; receiver=) Authentication-Results: lists.ozlabs.org; dmarc=none (p=none dis=none) header.from=mendozajonas.com Authentication-Results: lists.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=mendozajonas.com header.i=@mendozajonas.com header.b="HTAyA85p"; dkim=pass (2048-bit key; unprotected) header.d=messagingengine.com header.i=@messagingengine.com header.b="buD5ZVar"; dkim-atps=neutral Received: from out1-smtp.messagingengine.com (out1-smtp.messagingengine.com [66.111.4.25]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 43JlDZ53GHzDqWn for ; Tue, 18 Dec 2018 15:20:14 +1100 (AEDT) Received: from compute2.internal (compute2.nyi.internal [10.202.2.42]) by mailout.nyi.internal (Postfix) with ESMTP id 7B0312246E; Mon, 17 Dec 2018 23:20:11 -0500 (EST) Received: from mailfrontend2 ([10.202.2.163]) by compute2.internal (MEProxy); Mon, 17 Dec 2018 23:20:11 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= mendozajonas.com; h=from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; s=fm1; bh=qCUWKU50ZDh4HPexy4uYvgzn7yTqzl7COUMVvF2Nx4k=; b=HTAyA 85p8mwrENFba5vIetfo4TsTsQdLvLOFjMpExALN9lYyxMTk24SXFY1+LuZDAoemi 9YLAdJu3M03WmcENMselegvxAQ2CDT4ccrbmF2H3ErNlrSDuKdVBQYPez28Q1e6P gp04iN5tob/uwKEpNSoo6vgEFVGkg61TVUhdJZuPZSQ+f/UFzQ+QaNHpKjpr8mk3 1hSRBUZrJjJRZjqoea1cHHwuXm7ax4LU3w/HVy68hfvLm6Sjl3ausLXPs+YwZQD+ wXvOME/7tR2zM8WqMt9cj9NtYXji3PLPM2R5Fy+vmKAMLkkOVUD9xfhQZfLiBqXJ mqw9vRy9Dmxv/vFVQ== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-transfer-encoding:date:from :in-reply-to:message-id:mime-version:references:subject:to :x-me-proxy:x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s= fm1; bh=qCUWKU50ZDh4HPexy4uYvgzn7yTqzl7COUMVvF2Nx4k=; b=buD5ZVar Jz4JIUE1eFdv0lvw6w3pmwUh/I0MvR0JtWCNoKXWQKEVERoDPjycECHYJ5suBkW1 BYYeL+UcKWvyidyfrlA/N+NQhEbD2Gg5u4EsjyaWn2I4fV8/yNJTuGd99DkU7ZSl /jzAtYGkUtl9cUno6zFS/WOULDk3ErzJWdHHFgVCfzhWLDQGArWUC8RlKlYpExgr EyIC6otiBvewDpEeY75wqeSdWl4YEGYE9L8IxG6pxyZDs1xXj7kSrV1dUyadPtqC cXwwl03ypi2UmVlVoUSItSa2gbvvVA6gmJUzBCQnpUU7K9hOrCO3N5p6rn1aQwqM NLlLzYMa47yl/g== X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedtkedrudeigedgjeduucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfquhhtnecuuegrihhlohhuthemucef tddtnecunecujfgurhephffvufffkffojghfggfgsedtkeertdertddtnecuhfhrohhmpe furghmuhgvlhcuofgvnhguohiirgdqlfhonhgrshcuoehsrghmsehmvghnughoiigrjhho nhgrshdrtghomheqnecukfhppeduvddvrdelledrkedvrddutdenucfrrghrrghmpehmrg hilhhfrhhomhepshgrmhesmhgvnhguohiirghjohhnrghsrdgtohhmnecuvehluhhsthgv rhfuihiivgeptd X-ME-Proxy: Received: from v4.ozlabs.ibm.com (unknown [122.99.82.10]) by mail.messagingengine.com (Postfix) with ESMTPA id 0CC8E10084; Mon, 17 Dec 2018 23:20:09 -0500 (EST) From: Samuel Mendoza-Jonas To: petitboot@lists.ozlabs.org Subject: [RFC PATCH 5/8] discover/device-handler: Read command files if present Date: Tue, 18 Dec 2018 15:19:50 +1100 Message-Id: <20181218041953.8960-6-sam@mendozajonas.com> X-Mailer: git-send-email 2.20.0 In-Reply-To: <20181218041953.8960-1-sam@mendozajonas.com> References: <20181218041953.8960-1-sam@mendozajonas.com> MIME-Version: 1.0 X-BeenThere: petitboot@lists.ozlabs.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Petitboot bootloader development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Samuel Mendoza-Jonas Errors-To: petitboot-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Petitboot" Signed-off-by: Samuel Mendoza-Jonas --- discover/device-handler.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/discover/device-handler.c b/discover/device-handler.c index e75f4123..05d8df11 100644 --- a/discover/device-handler.c +++ b/discover/device-handler.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -1845,6 +1846,13 @@ void device_handler_add_plugin_option(struct device_handler *handler, } } + if (opt->command_file) { + opt->n_commands = parse_command_file(opt, opt->command_file, + &opt->commands); + pb_log("Plugin %s included %d command definitions\n", + opt->name, opt->n_commands); + } + handler->plugins = talloc_realloc(handler, handler->plugins, struct plugin_option *, handler->n_plugins + 1); if (!handler->plugins) { From patchwork Tue Dec 18 04:19:51 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sam Mendoza-Jonas X-Patchwork-Id: 1014979 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 43JlG51gncz9sBZ for ; Tue, 18 Dec 2018 15:21:33 +1100 (AEDT) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=mendozajonas.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=mendozajonas.com header.i=@mendozajonas.com header.b="ow0IKf+4"; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=messagingengine.com header.i=@messagingengine.com header.b="fLxMouTp"; dkim-atps=neutral Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 43JlG5036pzDqYh for ; Tue, 18 Dec 2018 15:21:33 +1100 (AEDT) Authentication-Results: lists.ozlabs.org; dmarc=none (p=none dis=none) header.from=mendozajonas.com Authentication-Results: lists.ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=mendozajonas.com header.i=@mendozajonas.com header.b="ow0IKf+4"; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=messagingengine.com header.i=@messagingengine.com header.b="fLxMouTp"; dkim-atps=neutral X-Original-To: petitboot@lists.ozlabs.org Delivered-To: petitboot@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=mendozajonas.com (client-ip=66.111.4.25; helo=out1-smtp.messagingengine.com; envelope-from=sam@mendozajonas.com; receiver=) Authentication-Results: lists.ozlabs.org; dmarc=none (p=none dis=none) header.from=mendozajonas.com Authentication-Results: lists.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=mendozajonas.com header.i=@mendozajonas.com header.b="ow0IKf+4"; dkim=pass (2048-bit key; unprotected) header.d=messagingengine.com header.i=@messagingengine.com header.b="fLxMouTp"; dkim-atps=neutral Received: from out1-smtp.messagingengine.com (out1-smtp.messagingengine.com [66.111.4.25]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 43JlDb29NHzDqWm for ; Tue, 18 Dec 2018 15:20:15 +1100 (AEDT) Received: from compute2.internal (compute2.nyi.internal [10.202.2.42]) by mailout.nyi.internal (Postfix) with ESMTP id 09E6F22AD6; Mon, 17 Dec 2018 23:20:13 -0500 (EST) Received: from mailfrontend2 ([10.202.2.163]) by compute2.internal (MEProxy); Mon, 17 Dec 2018 23:20:13 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= mendozajonas.com; h=from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; s=fm1; bh=oXustAMm02xFiXG7g1jcapa92yQzRr3GKTIhqbwd3hs=; b=ow0IK f+4i1iEtgo3EnPyDI8tAP1YulAn7QgUFYQmziCcnWmtNyk71DjuvZCMt9PgNQsd+ WtGx75chMFRoF8Nce3Pi52AxGBiGxUed2jJ8I1c2pN6u/d1WY8ee+lYCpinr8egA 0/OHCDbyqFkY6wKvvXsflIzSHcfRkNk0GIulipbWsmU33YQ8/rtY1rbAj8mr7rvp LJUfZek+5KngUWJuPMh0Pc8PJ8rUxql5+B8LIfn91lTUvY8qs0LwFT5OsA0Xpgcf AXqQF4XXv7rsUxlE25CGkGGSPfekBCp66dPSzKskYD7kkH+KhdnRewbq/vcprQNC Y8jvCs3EEJB1BtnAw== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-transfer-encoding:date:from :in-reply-to:message-id:mime-version:references:subject:to :x-me-proxy:x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s= fm1; bh=oXustAMm02xFiXG7g1jcapa92yQzRr3GKTIhqbwd3hs=; b=fLxMouTp R335MVMjzHyyDMAkqQs5PNAvvBi63T5Rw6VgtMRMYOs69zxnjDmJ6jobmxqkk3Pr IT7t6BPUoT0KCwOQ7mXUolFXP4OlxIARYnyE4B2nNKy75zOszW5/OsU2wceXpOKu geMxv1eal4cTz/oajGJOX9nMkcjS4ZXp2jE/jpudvjLr0AEY2Aeq57RJV/zPUwTy kYn/OHTRWXShmJd0+ruM4cKfbKhZM4mxSoDqmUV/avw9B5i6LQFw79p4J85fF/sO hOK9RtA1F26HMnodQ6AaYLtUNawwbZAhkYBHGze1lIgAcy6zqtn45Ed/7L2L2QWI GpOPToPzncmlDg== X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedtkedrudeigedgjeduucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfquhhtnecuuegrihhlohhuthemucef tddtnecunecujfgurhephffvufffkffojghfggfgsedtkeertdertddtnecuhfhrohhmpe furghmuhgvlhcuofgvnhguohiirgdqlfhonhgrshcuoehsrghmsehmvghnughoiigrjhho nhgrshdrtghomheqnecukfhppeduvddvrdelledrkedvrddutdenucfrrghrrghmpehmrg hilhhfrhhomhepshgrmhesmhgvnhguohiirghjohhnrghsrdgtohhmnecuvehluhhsthgv rhfuihiivgepge X-ME-Proxy: Received: from v4.ozlabs.ibm.com (unknown [122.99.82.10]) by mail.messagingengine.com (Postfix) with ESMTPA id 98DDA10084; Mon, 17 Dec 2018 23:20:11 -0500 (EST) From: Samuel Mendoza-Jonas To: petitboot@lists.ozlabs.org Subject: [RFC PATCH 6/8] ui/ncurses: Don't post screen after command Date: Tue, 18 Dec 2018 15:19:51 +1100 Message-Id: <20181218041953.8960-7-sam@mendozajonas.com> X-Mailer: git-send-email 2.20.0 In-Reply-To: <20181218041953.8960-1-sam@mendozajonas.com> References: <20181218041953.8960-1-sam@mendozajonas.com> MIME-Version: 1.0 X-BeenThere: petitboot@lists.ozlabs.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Petitboot bootloader development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Samuel Mendoza-Jonas Errors-To: petitboot-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Petitboot" Leave the post command to the calling screen so widgets can be properly reinitialised if needed. Signed-off-by: Samuel Mendoza-Jonas --- ui/ncurses/nc-cui.c | 1 - 1 file changed, 1 deletion(-) diff --git a/ui/ncurses/nc-cui.c b/ui/ncurses/nc-cui.c index d80e2c3e..9fe4ba5c 100644 --- a/ui/ncurses/nc-cui.c +++ b/ui/ncurses/nc-cui.c @@ -262,7 +262,6 @@ int cui_run_cmd(struct cui *cui, const char **cmd_argv) refresh(); redrawwin(cui->current->main_ncw); - nc_scr_post(cui->current); if (result) { pb_log_fn("failed: '%s'\n", cmd_argv[0]); From patchwork Tue Dec 18 04:19:52 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sam Mendoza-Jonas X-Patchwork-Id: 1014981 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [203.11.71.2]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 43JlGF1qNHz9sC7 for ; Tue, 18 Dec 2018 15:21:41 +1100 (AEDT) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=mendozajonas.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=mendozajonas.com header.i=@mendozajonas.com header.b="kOlj/yAf"; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=messagingengine.com header.i=@messagingengine.com header.b="CDfzdP8x"; dkim-atps=neutral Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 43JlGD6yZpzDq5Z for ; Tue, 18 Dec 2018 15:21:40 +1100 (AEDT) Authentication-Results: lists.ozlabs.org; dmarc=none (p=none dis=none) header.from=mendozajonas.com Authentication-Results: lists.ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=mendozajonas.com header.i=@mendozajonas.com header.b="kOlj/yAf"; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=messagingengine.com header.i=@messagingengine.com header.b="CDfzdP8x"; dkim-atps=neutral X-Original-To: petitboot@lists.ozlabs.org Delivered-To: petitboot@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=mendozajonas.com (client-ip=66.111.4.25; helo=out1-smtp.messagingengine.com; envelope-from=sam@mendozajonas.com; receiver=) Authentication-Results: lists.ozlabs.org; dmarc=none (p=none dis=none) header.from=mendozajonas.com Authentication-Results: lists.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=mendozajonas.com header.i=@mendozajonas.com header.b="kOlj/yAf"; dkim=pass (2048-bit key; unprotected) header.d=messagingengine.com header.i=@messagingengine.com header.b="CDfzdP8x"; dkim-atps=neutral Received: from out1-smtp.messagingengine.com (out1-smtp.messagingengine.com [66.111.4.25]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 43JlDd05hXzDqWs for ; Tue, 18 Dec 2018 15:20:17 +1100 (AEDT) Received: from compute2.internal (compute2.nyi.internal [10.202.2.42]) by mailout.nyi.internal (Postfix) with ESMTP id 9EEE522BF5; Mon, 17 Dec 2018 23:20:14 -0500 (EST) Received: from mailfrontend2 ([10.202.2.163]) by compute2.internal (MEProxy); Mon, 17 Dec 2018 23:20:14 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= mendozajonas.com; h=from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; s=fm1; bh=kCbpN6l3KkW6dHMxTNU6TtweZSLYqZxrTfiwtUeVtWk=; b=kOlj/ yAffr+HKVkR8owX7kbjIbHEDxmmzg4MtcGtYV9RDM5BV32rNcbHs+KRO3YjprHlV vUqfY0vt2SwcCgD0MWtu03lvD2l3WRWUBm0L7JVAcmnsTrTSH7kSR+aqdtURpgfq ZyShzxZNu7oeBQwrwgsSkAUX/hOMjlfTdCfkn6IZKQWsUpuwcVJPdH8ockacF593 WxWX2wUUJkNzvHyNJogZwL9Uu04in/fI77go/dGtNEsQO0lmZyXMyD8RlbqE+f8g NkNexSQMpJGF9qmiP+EFFqr5v5kZ5qgSFf8yQuMrdufPQPwuclJe4agKw69XuXHS 6tQ5rxbWY0l6sRJEQ== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-transfer-encoding:date:from :in-reply-to:message-id:mime-version:references:subject:to :x-me-proxy:x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s= fm1; bh=kCbpN6l3KkW6dHMxTNU6TtweZSLYqZxrTfiwtUeVtWk=; b=CDfzdP8x JKeZ9GPf23bbfcC4QeUYSc46xe1E0+ktNfpsn7k3LMI0J4/Qm06BGaW1OLd35MQy khk3BN+sqSmLY5/OMRCl2iZNkXU8nL2HDQY+lXCTzY2JHLLqF6TmWJ35kmAJ+WgK RHgf7eimVWGdz0yExtv2jvJvjgsC2yEH9+XL9TB+rNK+AiKMVuLxRuuH4Lye9yzL flxocAfnoVgTlF8x9iy03Yo4PeGngL7I6PD3ZNcnkmdimTmZV36H+mUDLhbyqt2C YTPNQ7Mhc/XCIoetEhSDSQHRiyoLAztFA56MZFk7xUBxmiFXllvJeqGadtpSujac 58LevcxeiYALew== X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedtkedrudeigedgjeduucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfquhhtnecuuegrihhlohhuthemucef tddtnecunecujfgurhephffvufffkffojghfggfgsedtkeertdertddtnecuhfhrohhmpe furghmuhgvlhcuofgvnhguohiirgdqlfhonhgrshcuoehsrghmsehmvghnughoiigrjhho nhgrshdrtghomheqnecukfhppeduvddvrdelledrkedvrddutdenucfrrghrrghmpehmrg hilhhfrhhomhepshgrmhesmhgvnhguohiirghjohhnrghsrdgtohhmnecuvehluhhsthgv rhfuihiivgepge X-ME-Proxy: Received: from v4.ozlabs.ibm.com (unknown [122.99.82.10]) by mail.messagingengine.com (Postfix) with ESMTPA id 37BC210084; Mon, 17 Dec 2018 23:20:12 -0500 (EST) From: Samuel Mendoza-Jonas To: petitboot@lists.ozlabs.org Subject: [RFC PATCH 7/8] ui/ncurses: Add current_field accessor Date: Tue, 18 Dec 2018 15:19:52 +1100 Message-Id: <20181218041953.8960-8-sam@mendozajonas.com> X-Mailer: git-send-email 2.20.0 In-Reply-To: <20181218041953.8960-1-sam@mendozajonas.com> References: <20181218041953.8960-1-sam@mendozajonas.com> MIME-Version: 1.0 X-BeenThere: petitboot@lists.ozlabs.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Petitboot bootloader development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Samuel Mendoza-Jonas Errors-To: petitboot-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Petitboot" Signed-off-by: Samuel Mendoza-Jonas --- ui/ncurses/nc-widgets.c | 13 +++++++++++++ ui/ncurses/nc-widgets.h | 1 + 2 files changed, 14 insertions(+) diff --git a/ui/ncurses/nc-widgets.c b/ui/ncurses/nc-widgets.c index afd56d71..86587bc8 100644 --- a/ui/ncurses/nc-widgets.c +++ b/ui/ncurses/nc-widgets.c @@ -1402,3 +1402,16 @@ int widget_focus_y(struct nc_widget *widget) return widget->focus_y; } +struct nc_widget *current_widget(struct nc_widgetset *set) +{ + FIELD *f; + + f = current_field(set->form); + + if (!f) { + pb_debug_fn("No field is selected!\n"); + return NULL; + } + + return field_userptr(f); +} diff --git a/ui/ncurses/nc-widgets.h b/ui/ncurses/nc-widgets.h index ce3b0386..88ca2125 100644 --- a/ui/ncurses/nc-widgets.h +++ b/ui/ncurses/nc-widgets.h @@ -90,6 +90,7 @@ int widget_width(struct nc_widget *widget); int widget_y(struct nc_widget *widget); int widget_x(struct nc_widget *widget); int widget_focus_y(struct nc_widget *widget); +struct nc_widget *current_widget(struct nc_widgetset *set); /* widgetset API */ typedef void (*widget_focus_cb)(struct nc_widget *widget, void *arg); From patchwork Tue Dec 18 04:19:53 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sam Mendoza-Jonas X-Patchwork-Id: 1014982 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 43JlGQ2X6lz9sBZ for ; Tue, 18 Dec 2018 15:21:50 +1100 (AEDT) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=mendozajonas.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=mendozajonas.com header.i=@mendozajonas.com header.b="FCiiBrz1"; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=messagingengine.com header.i=@messagingengine.com header.b="Ma31LWzU"; dkim-atps=neutral Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 43JlGQ0gDNzDqYh for ; Tue, 18 Dec 2018 15:21:50 +1100 (AEDT) Authentication-Results: lists.ozlabs.org; dmarc=none (p=none dis=none) header.from=mendozajonas.com Authentication-Results: lists.ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=mendozajonas.com header.i=@mendozajonas.com header.b="FCiiBrz1"; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=messagingengine.com header.i=@messagingengine.com header.b="Ma31LWzU"; dkim-atps=neutral X-Original-To: petitboot@lists.ozlabs.org Delivered-To: petitboot@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=mendozajonas.com (client-ip=66.111.4.25; helo=out1-smtp.messagingengine.com; envelope-from=sam@mendozajonas.com; receiver=) Authentication-Results: lists.ozlabs.org; dmarc=none (p=none dis=none) header.from=mendozajonas.com Authentication-Results: lists.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=mendozajonas.com header.i=@mendozajonas.com header.b="FCiiBrz1"; dkim=pass (2048-bit key; unprotected) header.d=messagingengine.com header.i=@messagingengine.com header.b="Ma31LWzU"; dkim-atps=neutral Received: from out1-smtp.messagingengine.com (out1-smtp.messagingengine.com [66.111.4.25]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 43JlDf3vmPzDqXK for ; Tue, 18 Dec 2018 15:20:18 +1100 (AEDT) Received: from compute2.internal (compute2.nyi.internal [10.202.2.42]) by mailout.nyi.internal (Postfix) with ESMTP id 499CF2246E; Mon, 17 Dec 2018 23:20:16 -0500 (EST) Received: from mailfrontend2 ([10.202.2.163]) by compute2.internal (MEProxy); Mon, 17 Dec 2018 23:20:16 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= mendozajonas.com; h=from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; s=fm1; bh=qIctfd2U7QoGGLZXc2b+d1AXjn5euWKPrsAsMl+kbEc=; b=FCiiB rz1a4En0C1Rg/jIdNrBPodfI9JoSqWv3KDRo3lIyyXIUSBGdaVugZkUTyMUrQneC grwyd5S40fSyUBnufRzFT/WEU+VppK/FrFj0VqpKPbxKRncN+LiidhoBRN0kHMzr s/RjraUTDZkykz9MSvAFtywJtREfAvidSrPf8+vQ92Cg0oaX+xlBP2QRwdrHcIfX 1RiS/QQ/INrCanS+g9dKyf0XDplJzzYVOuHwoyG8CSM+B2XP4+I8cOYvQDgZlQwo dGZTh9U2zSyjXJXoITtEHbdMPnEX0JN/2duCgwYapUg2fzgP/TqnA+2ocrr25z+6 3zmTTRrW1OG+rwxvQ== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-transfer-encoding:date:from :in-reply-to:message-id:mime-version:references:subject:to :x-me-proxy:x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s= fm1; bh=qIctfd2U7QoGGLZXc2b+d1AXjn5euWKPrsAsMl+kbEc=; b=Ma31LWzU ETWiLov1S+Y7WxqoYznFs95jf+qhD5Qs99Ye25dzRF9jGdLdp9xaVA3qpTkALOtj DpBBMRdidqrnLV1OiPbiTfi9FrpWUNLB5xQ+2+ahMB/IhM5BrQnTG059ijd4uHoi /bj2f04B7n9DUQjgfXov7ZumEyd6/Zq96p+V0U9HMlZ9tm6OC+Gc1AC7H/SqAQZ8 fFcoj/E4h7LEoUW285I7kKO/EBORHE4NxwgXhLMQsaK0MAox6aWlAOE1PDh0jRhd X0qXDFxjZaL1rxbNCkrfs03gqZLXOhpjzPooufnix2rb+cjCxMB8H/TpM2CWntDf UOjA4RGVhNKQ3Q== X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedtkedrudeigedgjeduucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfquhhtnecuuegrihhlohhuthemucef tddtnecunecujfgurhephffvufffkffojghfggfgsedtkeertdertddtnecuhfhrohhmpe furghmuhgvlhcuofgvnhguohiirgdqlfhonhgrshcuoehsrghmsehmvghnughoiigrjhho nhgrshdrtghomheqnecukfhppeduvddvrdelledrkedvrddutdenucfrrghrrghmpehmrg hilhhfrhhomhepshgrmhesmhgvnhguohiirghjohhnrghsrdgtohhmnecuvehluhhsthgv rhfuihiivgepge X-ME-Proxy: Received: from v4.ozlabs.ibm.com (unknown [122.99.82.10]) by mail.messagingengine.com (Postfix) with ESMTPA id C2B7F10084; Mon, 17 Dec 2018 23:20:14 -0500 (EST) From: Samuel Mendoza-Jonas To: petitboot@lists.ozlabs.org Subject: [RFC PATCH 8/8] ui/ncurses: Present plugin commands in nc-plugin Date: Tue, 18 Dec 2018 15:19:53 +1100 Message-Id: <20181218041953.8960-9-sam@mendozajonas.com> X-Mailer: git-send-email 2.20.0 In-Reply-To: <20181218041953.8960-1-sam@mendozajonas.com> References: <20181218041953.8960-1-sam@mendozajonas.com> MIME-Version: 1.0 X-BeenThere: petitboot@lists.ozlabs.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Petitboot bootloader development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Samuel Mendoza-Jonas Errors-To: petitboot-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Petitboot" Update the Plugin screen to present commands and their arguments if available. The user may modify the arguments and run the commands as displayed in the same way an executable may have been run previously. An extra field is also added to provide arbitrary arguments to a given plugin executable. Signed-off-by: Samuel Mendoza-Jonas --- ui/ncurses/nc-plugin.c | 256 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 237 insertions(+), 19 deletions(-) diff --git a/ui/ncurses/nc-plugin.c b/ui/ncurses/nc-plugin.c index f897cc8e..84e811a4 100644 --- a/ui/ncurses/nc-plugin.c +++ b/ui/ncurses/nc-plugin.c @@ -36,12 +36,22 @@ #include "process/process.h" #include "system/system.h" -#define N_FIELDS 15 +#define N_FIELDS 17 extern const struct help_text plugin_help_text; static void plugin_run_command(void *arg); +struct command_option { + // TODO If platform doesn't match a) warn, or b) hide? + struct nc_widget_label *name_l; + struct nc_widget_button *cmd_b; /* cmd + args_fmt */ + unsigned int n_args; + struct nc_widget_label **arg_l; + struct nc_widget_textbox **arg_f; + struct nc_widget_label *help_l; +}; + struct plugin_screen { struct nc_scr scr; struct cui *cui; @@ -76,9 +86,13 @@ struct plugin_screen { struct nc_widget_label *commands_l; struct nc_widget_select *commands_f; - + struct nc_widget_label *exec_args_l; + struct nc_widget_textbox *exec_args_f; struct nc_widget_button *run_b; } widgets; + + struct command_option *commands; + unsigned int n_commands; }; static void plugin_screen_draw(struct plugin_screen *screen, @@ -203,7 +217,116 @@ static void plugin_screen_resize(struct nc_scr *scr) plugin_screen_post(scr); } +static void update_arguments(struct plugin_screen *screen, int cmd_idx) +{ + struct command_option *opt; + struct command *cmd; + unsigned int i; + char *field; + + opt = &screen->commands[cmd_idx]; + cmd = &screen->opt->commands[cmd_idx]; + + for (i = 0; i < opt->n_args; i++) { + field = widget_textbox_get_value(opt->arg_f[i]); + + switch (cmd->args[i].type) { + case ARG_STR: + talloc_free(cmd->args[i].arg_str); + cmd->args[i].arg_str = talloc_strdup(screen, field); + break; + case ARG_I64: + { + int64_t val; + val = strtol(field, NULL, 10); + if (!errno) + cmd->args[i].arg_i64 = val; + break; + } + case ARG_F64: + { + double val; + val = strtod(field, NULL); + if (!errno) + cmd->args[i].arg_f64 = val; + break; + } + } + } +} + static void plugin_run_command(void *arg) +{ + struct plugin_screen *screen = arg; + struct nc_widget *current; + struct command_option *opt; + int result, n_var; + unsigned int idx; + char *fmt, *args, *var, *cmd_str; + + + /* Get selected command */ + current = current_widget(screen->widgetset); + if (!current) { + pb_log_fn("No command selected!\n"); + return; + } + + opt = NULL; + for (idx = 0; idx < screen->n_commands; idx++) { + if (widget_button_base(screen->commands[idx].cmd_b) == current) { + opt = &screen->commands[idx]; + break; + } + } + + if (!opt) { + pb_log_fn("Could not find current option\n"); + return; + } + + fmt = talloc_strdup(screen, screen->opt->commands[idx].args_fmt); + cmd_str = talloc_asprintf(screen, "%s ", screen->opt->commands[idx].cmd); + n_var = 0; + args = fmt; + while (args) { + var = strstr(args, "{}"); + if (var) + *var = '\0'; + cmd_str = talloc_asprintf_append(cmd_str, "%s%s", + args, var ? widget_textbox_get_value( + opt->arg_f[n_var++]) : ""); + + args = var ? var + 2 : NULL; + } + + const char *argv[] = { + pb_system_apps.pb_exec, + cmd_str, + NULL, + }; + + /* Drop our pad before running plugin */ + delwin(screen->pad); + screen->pad = NULL; + + result = cui_run_cmd(screen->cui, argv); + + if (result) + pb_log("Failed to run command option %s\n", argv[1]); + else { + update_arguments(screen, idx); + nc_scr_status_printf(screen->cui->current, _("Finished: %s"), + argv[1]); + } + + talloc_free(fmt); + talloc_free(cmd_str); + + plugin_screen_draw(screen, NULL); +} + +static void plugin_run_command_single(void *arg) { struct plugin_screen *screen = arg; char *cmd; @@ -222,6 +345,7 @@ static void plugin_run_command(void *arg) const char *argv[] = { pb_system_apps.pb_exec, cmd, + widget_textbox_get_value(screen->widgets.exec_args_f), NULL }; @@ -246,7 +370,7 @@ static void plugin_run_command_check(void *arg) struct plugin_screen *screen = arg; if (discover_client_authenticated(screen->cui->client)) { - plugin_run_command(screen); + plugin_run_command_single(screen); return; } @@ -283,17 +407,81 @@ static void plugin_screen_setup_widgets(struct plugin_screen *screen) screen->widgets.date_l = widget_new_label(set, 0, 0, _("Date")); screen->widgets.date_f = widget_new_label(set, 0, 0, opt->date); - screen->widgets.commands_l = widget_new_label(set, 0, 0, - _("Commands:")); screen->widgets.commands_f = widget_new_select(set, 0, 0, COLS - screen->field_x - 1); - for (i = 0; i < opt->n_executables; i++) { - widget_select_add_option(screen->widgets.commands_f, i, - basename(opt->executables[i]), i == 0); + if (opt->n_executables) { + screen->widgets.commands_l = widget_new_label(set, 0, 0, + _("Executables:")); + for (i = 0; i < opt->n_executables; i++) { + widget_select_add_option(screen->widgets.commands_f, i, + basename(opt->executables[i]), i == 0); + } + + screen->widgets.exec_args_l = widget_new_label(set, 0, 0, + _("Arguments:")); + screen->widgets.exec_args_f = widget_new_textbox(set, 0, 0, 30, + ""); + + screen->widgets.run_b = widget_new_button(set, 0, 0, 30, + _("Run selected executable"), + plugin_run_command_check, screen); + } + + screen->n_commands = opt->n_commands; + screen->commands = talloc_array(screen, struct command_option, + screen->n_commands); + for (i = 0; i < opt->n_commands; i++) { + unsigned int j; + char *label; + screen->commands[i].name_l = widget_new_label(set, 0, 0, + opt->commands[i].name); + label = talloc_asprintf(screen, "%s %s", + opt->commands[i].cmd, + opt->commands[i].args_fmt); + screen->commands[i].cmd_b = widget_new_button(set, 0, 0, 45, + label, plugin_run_command, screen); + screen->commands[i].n_args = opt->commands[i].n_args; + screen->commands[i].arg_l = talloc_zero_array(screen, + struct nc_widget_label *, + screen->commands[i].n_args); + screen->commands[i].arg_f = talloc_zero_array(screen, + struct nc_widget_textbox *, + screen->commands[i].n_args); + for (j = 0; j < screen->commands[i].n_args; j++) { + screen->commands[i].arg_l[j] = widget_new_label(set, + 0, 0, + opt->commands[i].args[j].name); + switch (opt->commands[i].args[j].type) { + case ARG_STR: + screen->commands[i].arg_f[j] = + widget_new_textbox(set, 0, 0, 20, + opt->commands[i].args[j].arg_str); + break; + case ARG_I64: + label = talloc_asprintf(screen, "%ld", + opt->commands[i].args[j].arg_i64); + screen->commands[i].arg_f[j] = + widget_new_textbox(set, 0, 0, 20, + label); + break; + case ARG_F64: + label = talloc_asprintf(screen, "%f", + opt->commands[i].args[j].arg_f64); + screen->commands[i].arg_f[j] = + widget_new_textbox(set, 0, 0, 20, + label); + break; + default: + label = talloc_asprintf(screen, ""); + screen->commands[i].arg_f[j] = + widget_new_textbox(set, 0, 0, 20, + label); + } + } + screen->commands[i].help_l = widget_new_label(set, 0, 0, + opt->commands[i].help); } - screen->widgets.run_b = widget_new_button(set, 0, 0, 30, - _("Run selected command"), plugin_run_command_check, screen); } static int layout_pair(struct plugin_screen *screen, int y, @@ -308,7 +496,7 @@ static int layout_pair(struct plugin_screen *screen, int y, static void plugin_screen_layout_widgets(struct plugin_screen *screen) { - unsigned int y; + unsigned int y, i; /* list of details (static) */ @@ -329,15 +517,45 @@ static void plugin_screen_layout_widgets(struct plugin_screen *screen) y += 1; - /* available commands */ - widget_move(widget_label_base(screen->widgets.commands_l), y, - screen->label_x); - widget_move(widget_select_base(screen->widgets.commands_f), y, - screen->field_x); + if (widget_select_get_value(screen->widgets.commands_f) != -1) { + /* available executables */ + widget_move(widget_label_base(screen->widgets.commands_l), y, + screen->label_x); + widget_move(widget_select_base(screen->widgets.commands_f), y, + screen->field_x); - y += 2; + y += 1; + + layout_pair(screen, y++, screen->widgets.exec_args_l, + widget_textbox_base(screen->widgets.exec_args_f)); + widget_move(widget_button_base(screen->widgets.run_b), y++, + screen->field_x); + + y += 2; + } + + + for (i = 0; i < screen->n_commands; i++) { + unsigned int j; + widget_move(widget_label_base(screen->commands[i].name_l), y++, + screen->label_x); + widget_move(widget_button_base(screen->commands[i].cmd_b), y++, + screen->field_x); + + for (j = 0; j < screen->commands[i].n_args; j++) { + widget_move(widget_label_base(screen->commands[i].arg_l[j]), + y, screen->field_x); + widget_move(widget_textbox_base(screen->commands[i].arg_f[j]), + y, screen->field_x * 2); + y += 1; + } + + widget_move(widget_label_base(screen->commands[i].help_l), y++, + screen->label_x); + y += 1; + } - widget_move(widget_button_base(screen->widgets.run_b), y++, screen->field_x); + y += 2; } @@ -402,7 +620,7 @@ struct plugin_screen *plugin_screen_init(struct cui *cui, screen->cui = cui; screen->on_exit = on_exit; screen->label_x = 2; - screen->field_x = 25; + screen->field_x = 15; screen->scr.frame.ltitle = talloc_strdup(screen, _("Petitboot Plugin"));