From 21565c6228026a868bee04c073bdc30d4e1d6c0a Mon Sep 17 00:00:00 2001 From: ebelcrom Date: Mon, 21 May 2018 00:08:42 +0200 Subject: [PATCH] source added --- deb/make_deb.sh | 34 + deb/shgen-0.1/Makefile | 1 + deb/shgen-0.1/debian/changelog | 5 + deb/shgen-0.1/debian/compat | 1 + deb/shgen-0.1/debian/control | 13 + deb/shgen-0.1/debian/copyright | 26 + deb/shgen-0.1/debian/rules | 26 + deb/shgen-0.1/debian/shgen-docs.docs | 2 + deb/shgen-0.1/debian/source/format | 1 + deb/shgen-0.1/shgen.c | 1 + deb/shgen-0.1/usr_share_shgen | 1 + src/Makefile | 34 + src/debian/changelog | 5 + src/debian/compat | 1 + src/debian/control | 13 + src/debian/copyright | 26 + src/debian/rules | 26 + src/debian/shgen-docs.docs | 2 + src/debian/source/format | 1 + src/shgen.c | 981 +++++++++++++++++++++++++++ src/usr_share_shgen/GPLv2 | 14 + src/usr_share_shgen/GPLv3 | 12 + src/usr_share_shgen/custom | 1 + src/usr_share_shgen/help | 42 ++ src/usr_share_shgen/lib | 13 + src/usr_share_shgen/shgen.sh | 352 ++++++++++ src/usr_share_shgen/skeleton | 28 + 27 files changed, 1662 insertions(+) create mode 100755 deb/make_deb.sh create mode 120000 deb/shgen-0.1/Makefile create mode 100644 deb/shgen-0.1/debian/changelog create mode 100644 deb/shgen-0.1/debian/compat create mode 100644 deb/shgen-0.1/debian/control create mode 100644 deb/shgen-0.1/debian/copyright create mode 100755 deb/shgen-0.1/debian/rules create mode 100644 deb/shgen-0.1/debian/shgen-docs.docs create mode 100644 deb/shgen-0.1/debian/source/format create mode 120000 deb/shgen-0.1/shgen.c create mode 120000 deb/shgen-0.1/usr_share_shgen create mode 100644 src/Makefile create mode 100644 src/debian/changelog create mode 100644 src/debian/compat create mode 100644 src/debian/control create mode 100644 src/debian/copyright create mode 100755 src/debian/rules create mode 100644 src/debian/shgen-docs.docs create mode 100644 src/debian/source/format create mode 100644 src/shgen.c create mode 100644 src/usr_share_shgen/GPLv2 create mode 100644 src/usr_share_shgen/GPLv3 create mode 100644 src/usr_share_shgen/custom create mode 100644 src/usr_share_shgen/help create mode 100644 src/usr_share_shgen/lib create mode 100755 src/usr_share_shgen/shgen.sh create mode 100644 src/usr_share_shgen/skeleton diff --git a/deb/make_deb.sh b/deb/make_deb.sh new file mode 100755 index 0000000..9283591 --- /dev/null +++ b/deb/make_deb.sh @@ -0,0 +1,34 @@ +#!/bin/bash +set -e +set -x + +SRC_DIR=shgen-0.1 + +# go to the dir of this script +cd $(dirname $0) +# install needed packages for build up a debian package +sudo apt-get install build-essential debhelper dh-make quilt fakeroot lintian +# tar source for dh_make +tar -czf $SRC_DIR.tar.gz $SRC_DIR +pushd $SRC_DIR +# run dh_make +set +e +dh_make -s -y -f ../shgen-0.1.tar.gz +set -e +# package source +dpkg-buildpackage -S -us -uc +# install needed packages for build up a ncurses/cdk application +sudo apt-get install libcdk5 libcdk5-dev +# package binary of current architecture +dpkg-buildpackage -us -uc +# build for i386 on a amd64 machine +if [ "$(uname -m)" == "x86_64" ]; then + # install needed packages for build up a ncurses/cdk application + sudo apt-get install libcdk5:i386 libcdk5-dev:i386 + # package binary of current architecture + export CC="gcc -m32" + dpkg-buildpackage -us -uc + unset CC +fi +popd + diff --git a/deb/shgen-0.1/Makefile b/deb/shgen-0.1/Makefile new file mode 120000 index 0000000..50be211 --- /dev/null +++ b/deb/shgen-0.1/Makefile @@ -0,0 +1 @@ +../../src/Makefile \ No newline at end of file diff --git a/deb/shgen-0.1/debian/changelog b/deb/shgen-0.1/debian/changelog new file mode 100644 index 0000000..6f7f324 --- /dev/null +++ b/deb/shgen-0.1/debian/changelog @@ -0,0 +1,5 @@ +shgen (0.1-1) lucid; urgency=low + + * Initial release + + -- dragan Thu, 17 May 2018 23:01:27 +0200 diff --git a/deb/shgen-0.1/debian/compat b/deb/shgen-0.1/debian/compat new file mode 100644 index 0000000..ec63514 --- /dev/null +++ b/deb/shgen-0.1/debian/compat @@ -0,0 +1 @@ +9 diff --git a/deb/shgen-0.1/debian/control b/deb/shgen-0.1/debian/control new file mode 100644 index 0000000..f784bbc --- /dev/null +++ b/deb/shgen-0.1/debian/control @@ -0,0 +1,13 @@ +Source: shgen +Section: misc +Priority: optional +Maintainer: dragan +Build-Depends: debhelper (>= 9) +Standards-Version: 3.9.6 +Homepage: https://binomiant.duckdns.org/MpqU9XX8/shgen.git + +Package: shgen +Architecture: any +Depends: libc6 (>= 2.4), libncurses5 (>= 5.0), libcdk5 (>= 5.0) +Description: Console shell script generator. + Ncurses based shell script generator for execution in a console. diff --git a/deb/shgen-0.1/debian/copyright b/deb/shgen-0.1/debian/copyright new file mode 100644 index 0000000..4c5d211 --- /dev/null +++ b/deb/shgen-0.1/debian/copyright @@ -0,0 +1,26 @@ +Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ +Upstream-Name: shgen +Source: https://binomiant.duckdns.org/MpqU9XX8/shgen.git + +Files: * +Copyright: 2018 dragan +License: GPL-2+ + +Files: debian/* +Copyright: 2018 dragan +License: GPL-2+ + This package 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; either version 2 of the License, or + (at your option) any later version. + . + This package 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, see + . + On Debian systems, the complete text of the GNU General + Public License version 2 can be found in "/usr/share/common-licenses/GPL-2". diff --git a/deb/shgen-0.1/debian/rules b/deb/shgen-0.1/debian/rules new file mode 100755 index 0000000..4ebc141 --- /dev/null +++ b/deb/shgen-0.1/debian/rules @@ -0,0 +1,26 @@ +#!/usr/bin/make -f +# See debhelper(7) (uncomment to enable) +# output every command that modifies files on the build system. +#export DH_VERBOSE = 1 + + +# see FEATURE AREAS in dpkg-buildflags(1) +#export DEB_BUILD_MAINT_OPTIONS = hardening=+all + +# see ENVIRONMENT in dpkg-buildflags(1) +# package maintainers to append CFLAGS +#export DEB_CFLAGS_MAINT_APPEND = -Wall -pedantic +# package maintainers to append LDFLAGS +#export DEB_LDFLAGS_MAINT_APPEND = -Wl,--as-needed + + +%: + dh $@ + + +# dh_make generated override targets +# This is example for Cmake (See https://bugs.debian.org/641051 ) +#override_dh_auto_configure: +# dh_auto_configure -- # -DCMAKE_LIBRARY_PATH=$(DEB_HOST_MULTIARCH) + +override_dh_strip: diff --git a/deb/shgen-0.1/debian/shgen-docs.docs b/deb/shgen-0.1/debian/shgen-docs.docs new file mode 100644 index 0000000..7319041 --- /dev/null +++ b/deb/shgen-0.1/debian/shgen-docs.docs @@ -0,0 +1,2 @@ +README.source +README.Debian diff --git a/deb/shgen-0.1/debian/source/format b/deb/shgen-0.1/debian/source/format new file mode 100644 index 0000000..163aaf8 --- /dev/null +++ b/deb/shgen-0.1/debian/source/format @@ -0,0 +1 @@ +3.0 (quilt) diff --git a/deb/shgen-0.1/shgen.c b/deb/shgen-0.1/shgen.c new file mode 120000 index 0000000..a303924 --- /dev/null +++ b/deb/shgen-0.1/shgen.c @@ -0,0 +1 @@ +../../src/shgen.c \ No newline at end of file diff --git a/deb/shgen-0.1/usr_share_shgen b/deb/shgen-0.1/usr_share_shgen new file mode 120000 index 0000000..4bf4081 --- /dev/null +++ b/deb/shgen-0.1/usr_share_shgen @@ -0,0 +1 @@ +../../src/usr_share_shgen \ No newline at end of file diff --git a/src/Makefile b/src/Makefile new file mode 100644 index 0000000..9df0f82 --- /dev/null +++ b/src/Makefile @@ -0,0 +1,34 @@ +CC ?= gcc +STRIP ?= strip +CFLAGS = -O2 -Wall -I/usr/include/cdk +LDFLAGS = -lcdk -lncurses + +EXE = shgen +MISC = usr_share_shgen + +default: $(EXE) + +%.o: %.c + @echo ' [CC] $^' + @$(CC) $(CFLAGS) -c -o $@ $< + +$(EXE): %: %.o + @echo ' [LD] $<' + @$(CC) -o $@ $< $(LDFLAGS) + @echo ' [STRIP] $<' + @$(STRIP) $@ + +install: $(EXE) + @echo ' [INSTALL] $<' + @mkdir -p $(DESTDIR)/usr/bin + @install -m 755 $(EXE) $(DESTDIR)/usr/bin + @mkdir -p $(DESTDIR)/usr/share/$(EXE) + @install -m 644 -t $(DESTDIR)/usr/share/$(EXE) $(MISC)/GPLv2 $(MISC)/GPLv3\ + $(MISC)/custom $(MISC)/help $(MISC)/lib $(MISC)/skeleton + @install -m 755 $(MISC)/shgen.sh $(DESTDIR)/usr/share/$(EXE) + +clean: + @echo ' [CLEAN]' + @rm -f $(EXE) *.o + +.PHONY: clean default install diff --git a/src/debian/changelog b/src/debian/changelog new file mode 100644 index 0000000..6f7f324 --- /dev/null +++ b/src/debian/changelog @@ -0,0 +1,5 @@ +shgen (0.1-1) lucid; urgency=low + + * Initial release + + -- dragan Thu, 17 May 2018 23:01:27 +0200 diff --git a/src/debian/compat b/src/debian/compat new file mode 100644 index 0000000..ec63514 --- /dev/null +++ b/src/debian/compat @@ -0,0 +1 @@ +9 diff --git a/src/debian/control b/src/debian/control new file mode 100644 index 0000000..f784bbc --- /dev/null +++ b/src/debian/control @@ -0,0 +1,13 @@ +Source: shgen +Section: misc +Priority: optional +Maintainer: dragan +Build-Depends: debhelper (>= 9) +Standards-Version: 3.9.6 +Homepage: https://binomiant.duckdns.org/MpqU9XX8/shgen.git + +Package: shgen +Architecture: any +Depends: libc6 (>= 2.4), libncurses5 (>= 5.0), libcdk5 (>= 5.0) +Description: Console shell script generator. + Ncurses based shell script generator for execution in a console. diff --git a/src/debian/copyright b/src/debian/copyright new file mode 100644 index 0000000..4c5d211 --- /dev/null +++ b/src/debian/copyright @@ -0,0 +1,26 @@ +Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ +Upstream-Name: shgen +Source: https://binomiant.duckdns.org/MpqU9XX8/shgen.git + +Files: * +Copyright: 2018 dragan +License: GPL-2+ + +Files: debian/* +Copyright: 2018 dragan +License: GPL-2+ + This package 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; either version 2 of the License, or + (at your option) any later version. + . + This package 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, see + . + On Debian systems, the complete text of the GNU General + Public License version 2 can be found in "/usr/share/common-licenses/GPL-2". diff --git a/src/debian/rules b/src/debian/rules new file mode 100755 index 0000000..4ebc141 --- /dev/null +++ b/src/debian/rules @@ -0,0 +1,26 @@ +#!/usr/bin/make -f +# See debhelper(7) (uncomment to enable) +# output every command that modifies files on the build system. +#export DH_VERBOSE = 1 + + +# see FEATURE AREAS in dpkg-buildflags(1) +#export DEB_BUILD_MAINT_OPTIONS = hardening=+all + +# see ENVIRONMENT in dpkg-buildflags(1) +# package maintainers to append CFLAGS +#export DEB_CFLAGS_MAINT_APPEND = -Wall -pedantic +# package maintainers to append LDFLAGS +#export DEB_LDFLAGS_MAINT_APPEND = -Wl,--as-needed + + +%: + dh $@ + + +# dh_make generated override targets +# This is example for Cmake (See https://bugs.debian.org/641051 ) +#override_dh_auto_configure: +# dh_auto_configure -- # -DCMAKE_LIBRARY_PATH=$(DEB_HOST_MULTIARCH) + +override_dh_strip: diff --git a/src/debian/shgen-docs.docs b/src/debian/shgen-docs.docs new file mode 100644 index 0000000..7319041 --- /dev/null +++ b/src/debian/shgen-docs.docs @@ -0,0 +1,2 @@ +README.source +README.Debian diff --git a/src/debian/source/format b/src/debian/source/format new file mode 100644 index 0000000..163aaf8 --- /dev/null +++ b/src/debian/source/format @@ -0,0 +1 @@ +3.0 (quilt) diff --git a/src/shgen.c b/src/shgen.c new file mode 100644 index 0000000..050947e --- /dev/null +++ b/src/shgen.c @@ -0,0 +1,981 @@ +#include +#include + +/* + * TODO: + * sha bang: /bin/sh|bash + * header: comment, license + * lib.sh: log, error, warning + * BASH_XTRACEFD, debug file + * - check defined + * name and directory + * - parameters... + */ + +static int x_size = 0; +static int y_size = 0; + +static WINDOW* window; +static CDKSCREEN* screen; +static CDKLABEL* title_label; +static CDKLABEL* options_label; +static CDKLABEL* commands_label; +static char* shabang_opts[] = { " /bin/sh", " /bin/bash" }; +static CDKRADIO* shabang_radio; +static CDKLABEL* shabang_label; +static CDKSELECTION* header_selection; +static CDKLABEL* header_label; +static CDKLABEL* description_label; +static CDKENTRY* description_entry; +static char* license_opts[] = { " none", " GPLv2", " GPLv3", " custom" }; +static CDKRADIO* license_radio; +static CDKLABEL* license_label; +static CDKLABEL* script_label; +static CDKBUTTON* script_button; +static CDKENTRY* script_entry; +static CDKSELECTION* debug_selection; +static CDKLABEL* debug_label; +static CDKLABEL* dfile_label; +static CDKBUTTON* dfile_button; +static CDKENTRY* dfile_entry; +static char* common_opts[] = { " usage()", " log()", " error()", " warning()" }; +static CDKSELECTION* common_selection; +static CDKLABEL* common_label; +static CDKSELECTION* lib_selection; +static CDKLABEL* lib_label; +static CDKLABEL* lfile_label; +static CDKBUTTON* lfile_button; +static CDKENTRY* lfile_entry; +static CDKBUTTON* generate_button; + +static char* default_opts = " - Abort - Next"; +static char* enable_opts = " - Abort - Next" + " - Choose"; +static char* select_opts = " - Abort - Next" + " - Select - Choose"; +static char* button_opts = " - Abort - Enter"; +static char* gen_opts = " - Abort - Generate"; +static char* help_opts = " - Abort - Quit help" + " - Line up - Line down"; +static char* commands_msg; + +static const char* settings = ".shgen/settings"; +static const char* exec_script = "/usr/share/shgen/shgen.sh"; +static const char* help_file = "/usr/share/shgen/help"; +static const char* opt_create = " -c 2>&1"; +static const char* opt_generate = " -g 2>&1"; +static struct s_exec_res +{ + int status; + char message[1024]; +} exec_result; + +static struct s_data +{ + char* shabang; + boolean header; + char* description; + char* license; + char* script; + boolean debug; + char* dfile; + char* common[4]; + boolean lib; + char* lfile; +} data = +{ + NULL, + FALSE, + NULL, + NULL, + NULL, + FALSE, + NULL, + { NULL, NULL, NULL, NULL }, + FALSE, + NULL +}; + +static void create_button(CDKSCREEN* screen); +static void create_common(CDKSCREEN* screen); +static void create_controls(void); +static void create_debug(CDKSCREEN* screen); +static void create_header(CDKSCREEN* screen); +static void create_help(CDKSCREEN* screen); +static void create_lib(CDKSCREEN* screen); +static void create_script(CDKSCREEN* screen); +static void create_shabang(CDKSCREEN* screen); +static void create_titlebar(CDKSCREEN* screen); +static void destroy_controls(void); +static void dimension_check(void); +static int process_common(void); +static int process_debug(void); +static int process_gen(void); +static int process_header(void); +static int process_lib(void); +static int process_script(void); +static int process_shabang(void); +static void update_options(char* options); +static void write_settings(int view); +static int help(EObjectType cdktype, void* object, void* clientdata, chtype key); +static int quit(EObjectType cdktype, void* object, void* clientdata, chtype key); + +/* generation button */ +static void create_button(CDKSCREEN* screen) +{ + char* generate_text[] = { " Generate " }; + generate_button = newCDKButton(screen, x_size / 2 + 14, + getbegy(lfile_entry->win) + 2, generate_text[0], NULL, FALSE, FALSE); + setCDKButtonBackgroundAttrib(generate_button, A_REVERSE); + drawCDKButton(generate_button, FALSE); +} + +/* common function */ +static void create_common(CDKSCREEN* screen) +{ + char* common_text[] = { "Functions: " }; + char* common_choices[] = { "[ ]", "[X]" }; + common_selection = newCDKSelection(screen, getbegx(debug_selection->win), + getbegy(dfile_entry->win) + 2, NONE, 4, 13, NULL, common_opts, 4, + common_choices, 2, NONE, FALSE, FALSE); + common_label = newCDKLabel(screen, getbegx(common_selection->win) - + strlen(common_text[0]), getbegy(common_selection->win), common_text, 1, FALSE, + FALSE); + drawCDKLabel(common_label, FALSE); + drawCDKSelection(common_selection, FALSE); +} + +/* create controls */ +static void create_controls(void) +{ + create_titlebar(screen); + create_shabang(screen); + create_header(screen); + create_script(screen); + create_debug(screen); + create_common(screen); + create_lib(screen); + create_button(screen); + create_help(screen); +} + +/* bash xtrace fd / debug option */ +static void create_debug(CDKSCREEN* screen) +{ + char* debug_text[] = { "Debug: " }; + char* debug_choices[] = { "[ ]", "[X]" }; + char* debug_opts[] = { " enable" }; + debug_selection = newCDKSelection(screen, x_size / 2 + 14, + getmaxy(title_label->win) + 1, NONE, 1, 10, NULL, debug_opts, 1, debug_choices, + 2, NONE, FALSE, FALSE); + debug_label = newCDKLabel(screen, getbegx(debug_selection->win) - + strlen(debug_text[0]), getbegy(debug_selection->win), debug_text, 1, FALSE, + FALSE); + drawCDKLabel(debug_label, FALSE); + drawCDKSelection(debug_selection, FALSE); + + /* debug file */ + char* dfile_text[] = { "Debug file name and path: " }; + dfile_label = newCDKLabel(screen, x_size / 2 + 1, + getbegy(debug_selection->win) + 2, dfile_text, 1, FALSE, FALSE); + drawCDKLabel(dfile_label, FALSE); + + dfile_text[0] = " Enter "; + dfile_button = newCDKButton(screen, x_size / 2 + 40 - strlen(dfile_text[0]) - 1, + getbegy(dfile_label->win), dfile_text[0], NULL, FALSE, FALSE); + setCDKButtonBackgroundAttrib(dfile_button, A_REVERSE); + drawCDKButton(dfile_button, FALSE); + + dfile_entry = newCDKEntry(screen, getbegx(dfile_label->win), + getbegy(dfile_label->win) + 2, NULL, NULL, A_NORMAL, '.', vMIXED, 38, 0, 256, + FALSE, FALSE); + drawCDKEntry(dfile_entry, FALSE); +} + +/* program description and license */ +static void create_header(CDKSCREEN* screen) +{ + /* header activation */ + char* header_text[] = { "Header: " }; + char* header_opts[] = { " enable" }; + char* header_choices[] = { "[ ]", "[X]" }; + header_selection = newCDKSelection(screen, getbegx(shabang_radio->win), + getbegy(shabang_radio->win) + 3, NONE, 1, 10, NULL, header_opts, 1, + header_choices, 2, NONE, FALSE, FALSE); + header_label = newCDKLabel(screen, getbegx(header_selection->win) - + strlen(header_text[0]), getbegy(header_selection->win), header_text, 1, FALSE, + FALSE); + drawCDKLabel(header_label, FALSE); + drawCDKSelection(header_selection, FALSE); + + /* description */ + char* description_text[] = { "Description: " }; + description_label = newCDKLabel(screen, 1, getbegy(header_selection->win) + + 2, description_text, 1, FALSE, FALSE); + drawCDKLabel(description_label, FALSE); + description_entry = newCDKEntry(screen, 1, getbegy(description_label->win) + + 2, NULL, NULL, A_NORMAL, '.', vMIXED, 38, 0, 256, FALSE, FALSE); + drawCDKEntry(description_entry, FALSE); + + /* license choice */ + char* license_text[] = { "License: " }; + license_radio = newCDKRadio(screen, getbegx(header_selection->win), + getbegy(description_entry->win) + 2, NONE, 4, 5, NULL, license_opts, 4, 'X', 1, + NONE, FALSE, FALSE); + setCDKRadioLeftBrace(license_radio, '('); + setCDKRadioRightBrace(license_radio, ')'); + license_label = newCDKLabel(screen, getbegx(license_radio->win) - + strlen(license_text[0]), getbegy(license_radio->win), license_text, 1, FALSE, + FALSE); + drawCDKLabel(license_label, FALSE); + drawCDKRadio(license_radio, FALSE); +} + +/* help viewer */ +static void create_help(CDKSCREEN* screen) +{ +} + +/* lib activation */ +static void create_lib(CDKSCREEN* screen) +{ + /* lib activation */ + char* lib_text[] = { "lib.sh: " }; + char* lib_choices[] = { "[ ]", "[X]" }; + char* lib_opts[] = { " enable" }; + lib_selection = newCDKSelection(screen, getbegx(debug_selection->win), + getbegy(common_selection->win) + 5, NONE, 1, 10, NULL, lib_opts, 1, lib_choices, + 2, NONE, FALSE, FALSE); + lib_label = newCDKLabel(screen, getbegx(lib_selection->win) - + strlen(lib_text[0]), getbegy(lib_selection->win), lib_text, 1, FALSE, + FALSE); + drawCDKLabel(lib_label, FALSE); + drawCDKSelection(lib_selection, FALSE); + + /* lib file */ + char* lfile_text[] = { "lib.sh path: " }; + lfile_label = newCDKLabel(screen, x_size / 2 + 1, + getbegy(lib_selection->win) + 2, lfile_text, 1, FALSE, FALSE); + drawCDKLabel(lfile_label, FALSE); + + lfile_text[0] = " Enter "; + lfile_button = newCDKButton(screen, x_size / 2 + 40 - strlen(lfile_text[0]) - 1, + getbegy(lfile_label->win), lfile_text[0], NULL, FALSE, FALSE); + setCDKButtonBackgroundAttrib(lfile_button, A_REVERSE); + drawCDKButton(lfile_button, FALSE); + + lfile_entry = newCDKEntry(screen, getbegx(lfile_label->win), + getbegy(lfile_label->win) + 2, NULL, NULL, A_NORMAL, '.', vMIXED, 38, 0, 256, + FALSE, FALSE); + drawCDKEntry(lfile_entry, FALSE); +} + +/* script name and dir */ +static void create_script(CDKSCREEN* screen) +{ + char* script_text[] = { "Script name and path: " }; + script_label = newCDKLabel(screen, 1, getbegy(license_radio->win) + 5, + script_text, 1, FALSE, FALSE); + drawCDKLabel(script_label, FALSE); + + script_text[0] = " Enter "; + script_button = newCDKButton(screen, 40 - strlen(script_text[0]) - 1, + getbegy(script_label->win), script_text[0], NULL, FALSE, FALSE); + setCDKButtonBackgroundAttrib(script_button, A_REVERSE); + drawCDKButton(script_button, FALSE); + + script_entry = newCDKEntry(screen, 1, getbegy(script_label->win) + 2, NULL, + NULL, A_NORMAL, '.', vMIXED, 38, 0, 256, FALSE, FALSE); + drawCDKEntry(script_entry, FALSE); +} + +/* shabang choice */ +static void create_shabang(CDKSCREEN* screen) +{ + char* shabang_text[] = { "Shabang: " }; + shabang_radio = newCDKRadio(screen, 14, getmaxy(title_label->win) + 1, + NONE, 2, 8, NULL, shabang_opts, 2, 'X', 1, NONE, FALSE, FALSE); + setCDKRadioLeftBrace(shabang_radio, '('); + setCDKRadioRightBrace(shabang_radio, ')'); + shabang_label = newCDKLabel(screen, getbegx(shabang_radio->win) - + strlen(shabang_text[0]), getbegy(shabang_radio->win), shabang_text, 1, FALSE, FALSE); + drawCDKLabel(shabang_label, FALSE); + drawCDKRadio(shabang_radio, FALSE); +} + +/* program title and general options on top with hline below */ +static void create_titlebar(CDKSCREEN* screen) +{ + char hline_text[12]; + snprintf(hline_text, 12, "<#HL(%i)>", x_size); + char* title_text[] = { " Shell script generator v0.1", hline_text }; + title_label = newCDKLabel(screen, LEFT, TOP, title_text, 2, FALSE, FALSE); + drawCDKLabel(title_label, FALSE); + char* options_text[] = { " - Help - Quit " }; + options_label = newCDKLabel(screen, RIGHT, TOP, options_text, 1, FALSE, + FALSE); + drawCDKLabel(options_label, FALSE); +} + +/* destroy controls */ +static void destroy_controls(void) +{ + destroyCDKLabel(title_label); + destroyCDKLabel(options_label); + destroyCDKLabel(commands_label); + destroyCDKLabel(shabang_label); + destroyCDKRadio(shabang_radio); + destroyCDKLabel(header_label); + destroyCDKSelection(header_selection); + destroyCDKLabel(description_label); + destroyCDKEntry(description_entry); + destroyCDKLabel(license_label); + destroyCDKRadio(license_radio); + destroyCDKLabel(script_label); + destroyCDKButton(script_button); + destroyCDKEntry(script_entry); + destroyCDKLabel(debug_label); + destroyCDKSelection(debug_selection); + destroyCDKLabel(dfile_label); + destroyCDKButton(dfile_button); + destroyCDKEntry(dfile_entry); + destroyCDKLabel(common_label); + destroyCDKSelection(common_selection); + destroyCDKLabel(lib_label); + destroyCDKSelection(lib_selection); + destroyCDKLabel(lfile_label); + destroyCDKButton(lfile_button); + destroyCDKEntry(lfile_entry); + destroyCDKButton(generate_button); +} + +/* dimension check */ +static void dimension_check(void) +{ + initscr(); + endwin(); + getmaxyx(stdscr, y_size, x_size); + + if (x_size < 80 || y_size < 24) + { + fprintf(stderr, "Minimal screen size must be at leaset 80x24. Aborting.\n"); + exit(1); + } +} + +static void execute(const char* option) +{ + char exec_str[strlen(exec_script) + strlen(option) + 1]; + snprintf(exec_str, sizeof(exec_str), "%s%s", exec_script, option); + + FILE* exec_pipe = popen(exec_str, "r"); + if (exec_pipe != NULL) + { + char* pbuf; + + while (TRUE) + { + pbuf = fgets(exec_result.message, sizeof(exec_result.message), exec_pipe); + if (pbuf == NULL) + { + break; + } + } + + int status = pclose(exec_pipe); + exec_result.status = WEXITSTATUS(status); + } + else + { + strerror_r(errno, exec_result.message, sizeof(exec_result.message)); + } +} + +/* process common selection */ +static int process_common(void) +{ + update_options(select_opts); + activateCDKSelection(common_selection, NULL); + if (common_selection->exitType == vNORMAL) + { + /* register choice */ + int i; + for (i = 0; i < sizeof(data.common); i++) + { + if (common_selection->selections[i]) + { + data.common[i] = common_opts[i] + 1; + } + } + } + else + { + return 1; + } + + return 0; +} + +/* process debug selection */ +static int process_debug(void) +{ + update_options(enable_opts); + activateCDKSelection(debug_selection, NULL); + if (debug_selection->exitType == vNORMAL) + { + /* register choice */ + data.debug = debug_selection->selections[0]; + + if (debug_selection->selections[0] == TRUE) + { + /* process debug button and entry */ +DFILE: + update_options(button_opts); + activateCDKButton(dfile_button, NULL); + if (dfile_button->exitType == vNORMAL) + { + char* dfile_title = + "Navigate to a directory and enter a new file name below: "; + CDKFSELECT* dfile_fselect = newCDKFselect(screen, CENTER, CENTER, 18, + 60, dfile_title, NULL, A_NORMAL, ' ', A_REVERSE, "", "", + "", "", TRUE, FALSE); + + char* filename = activateCDKFselect(dfile_fselect, NULL); + if (filename != NULL && strlen(filename) > 0) + { + /* register choice */ + if (data.dfile != NULL) + { + free(data.dfile); + } + data.dfile = (char*) malloc(strlen(filename) + 1); + snprintf(data.dfile, strlen(filename) + 1, "%s", filename); + + setCDKEntryValue(dfile_entry, data.dfile); + destroyCDKFselect(dfile_fselect); + refreshCDKScreen(screen); + } + else + { + destroyCDKFselect(dfile_fselect); + refreshCDKScreen(screen); + goto DFILE; + } + } + else + { + return 1; + } + } + } + else + { + return 1; + } + + return 0; +} + +/* process generate button */ +static int process_gen(void) +{ + update_options(gen_opts); + activateCDKButton(generate_button, NULL); + if (generate_button->exitType == vNORMAL) + { + //write_settings(1); + + char* gen_title = "Generation progress"; + char* gen_hl = "<#HL(34)>"; + char* gen_1lp = "Create local directory [ pending ]"; + char* gen_1lr = "Create local directory [ running ]"; + char* gen_1ld = "Create local directory [ ready ]"; + char* gen_1le = "Create local directory [ error ]"; + char* gen_2lp = "Write settings [ pending ]"; + char* gen_2lr = "Write settings [ running ]"; + char* gen_2ld = "Write settings [ ready ]"; + char* gen_2le = "Write settings [ error ]"; + char* gen_3lp = "Generate script [ pending ]"; + char* gen_3lr = "Generate script [ running ]"; + char* gen_3ld = "Generate script [ ready ]"; + char* gen_3le = "Generate script [ error ]"; + char* gen_err = "Error occurred:"; + + char* init_text[] = { gen_title, gen_hl, gen_1lp, gen_2lp, gen_3lp }; + CDKLABEL* progress_label = newCDKLabel(screen, CENTER, CENTER, init_text, 5, + TRUE, FALSE); + drawCDKLabel(progress_label, TRUE); + + /* create local directory */ + char* create_text[] = { gen_title, gen_hl, gen_1lr, gen_2lp, gen_3lp }; + setCDKLabel(progress_label, create_text, 5, TRUE); + sleep(1); + execute(opt_create); + if (exec_result.status > 0) + { + char* failed_text[] = { gen_title, gen_hl, gen_1le, gen_2lp, gen_3lp }; + setCDKLabel(progress_label, failed_text, 5, TRUE); + char* error_text[] = { gen_err, exec_result.message }; + popupLabel(screen, error_text, 2); + destroyCDKLabel(progress_label); + refreshCDKScreen(screen); + return 1; + } + + /* write settings to local directory */ + char* settings_text[] = { gen_title, gen_hl, gen_1ld, gen_2lr, gen_3lp }; + setCDKLabel(progress_label, settings_text, 5, TRUE); + sleep(1); + write_settings(0); + if (exec_result.status > 0) + { + char* failed_text[] = { gen_title, gen_hl, gen_1ld, gen_2le, gen_3lp }; + setCDKLabel(progress_label, failed_text, 5, TRUE); + char* error_text[] = { gen_err, exec_result.message }; + popupLabel(screen, error_text, 2); + destroyCDKLabel(progress_label); + refreshCDKScreen(screen); + return 1; + } + + /* generate shell script(s) */ + char* generate_text[] = { gen_title, gen_hl, gen_1ld, gen_2ld, gen_3lr }; + setCDKLabel(progress_label, generate_text, 5, TRUE); + sleep(1); + execute(opt_generate); + if (exec_result.status > 0) + { + char* failed_text[] = { gen_title, gen_hl, gen_1ld, gen_2ld, gen_3le }; + setCDKLabel(progress_label, failed_text, 5, TRUE); + char* error_text[] = { gen_err, exec_result.message }; + popupLabel(screen, error_text, 2); + destroyCDKLabel(progress_label); + refreshCDKScreen(screen); + return 1; + } + + char* exit_text[] = { gen_title, gen_hl, gen_1ld, gen_2ld, gen_3ld }; + setCDKLabel(progress_label, exit_text, 5, TRUE); + sleep(1); + destroyCDKLabel(progress_label); + refreshCDKScreen(screen); + } + else + { + return 1; + } + + return 0; +} + +/* process header selection */ +static int process_header(void) +{ + int ch_num; + char* ch_str; + + update_options(enable_opts); + ch_num = activateCDKSelection(header_selection, NULL); + if (header_selection->exitType == vNORMAL) + { + /* register choice */ + data.header = header_selection->selections[0]; + + if (header_selection->selections[0] == TRUE) + { + /* process decription entry */ + update_options(default_opts); + ch_str = activateCDKEntry(description_entry, NULL); + if (description_entry->exitType == vNORMAL) + { + /* register choice */ + data.description = ch_str; + } + else + { + return 1; + } + + /* process license radio */ + update_options(select_opts); + ch_num = activateCDKRadio(license_radio, NULL); + if (license_radio->exitType == vNORMAL) + { + /* register choice */ + data.license = license_opts[ch_num] + 1; + } + else + { + return 1; + } + } + } + else + { + return 1; + } + + return 0; +} + +/* process lib selection */ +static int process_lib(void) +{ + update_options(enable_opts); + activateCDKSelection(lib_selection, NULL); + if (lib_selection->exitType == vNORMAL) + { + /* register choice */ + data.lib = lib_selection->selections[0]; + + if (lib_selection->selections[0] == TRUE) + { + /* process lib button and entry */ +LFILE: + update_options(default_opts); + activateCDKButton(lfile_button, NULL); + if (lfile_button->exitType == vNORMAL) + { + char* lfile_title = + "Navigate to a directory and enter a new file name below: "; + CDKFSELECT* lfile_fselect = newCDKFselect(screen, CENTER, CENTER, 18, + 60, lfile_title, NULL, A_NORMAL, ' ', A_REVERSE, "", "", + "", "", TRUE, FALSE); + + char* filename = activateCDKFselect(lfile_fselect, NULL); + if (filename != NULL && strlen(filename) > 0) + { + /* register choice */ + if (data.lfile != NULL) + { + free(data.lfile); + } + data.lfile = (char*) malloc(strlen(filename) + 1); + snprintf(data.lfile, strlen(filename) + 1, "%s", filename); + + setCDKEntryValue(lfile_entry, data.lfile); + destroyCDKFselect(lfile_fselect); + refreshCDKScreen(screen); + } + else + { + destroyCDKFselect(lfile_fselect); + refreshCDKScreen(screen); + goto LFILE; + } + } + else + { + return 1; + } + } + } + else + { + return 1; + } + + return 0; +} + +/* process script button and entry */ +static int process_script(void) +{ +SCRIPT: + update_options(button_opts); + activateCDKButton(script_button, NULL); + if (script_button->exitType == vNORMAL) + { + char* script_title = "Navigate to a directory and enter a new file name below: "; + CDKFSELECT* script_fselect = newCDKFselect(screen, CENTER, CENTER, 18, 60, script_title, + NULL, A_NORMAL, ' ', A_REVERSE, "", "", "", "", TRUE, FALSE); + + char* filename = activateCDKFselect(script_fselect, NULL); + if (filename != NULL && strlen(filename) > 0) + { + /* register choice */ + if (data.script != NULL) + { + free(data.script); + } + data.script = (char*) malloc(strlen(filename) + 1); + snprintf(data.script, strlen(filename) + 1, "%s", filename); + + setCDKEntryValue(script_entry, data.script); + destroyCDKFselect(script_fselect); + refreshCDKScreen(screen); + } + else + { + destroyCDKFselect(script_fselect); + refreshCDKScreen(screen); + goto SCRIPT; + } + } + else + { + return 1; + } + + return 0; +} + +/* process shabang radio */ +static int process_shabang(void) +{ + int ch_num; + + update_options(select_opts); + ch_num = activateCDKRadio(shabang_radio, NULL); + if (shabang_radio->exitType == vNORMAL) + { + /* register choice */ + data.shabang = shabang_opts[ch_num] + 1; + } + else + { + return 1; + } + + return 0; +} + +/* update option line */ +static void update_options(char* options) +{ + char hline_cmd[12]; + snprintf(hline_cmd, 12, "<#HL(%i)>", x_size); + commands_msg = options; + char* commands_text[] = { hline_cmd, options }; + if (commands_label != NULL) + { + destroyCDKLabel(commands_label); + } + commands_label = newCDKLabel(screen, CENTER, BOTTOM, commands_text, 2, + FALSE, FALSE); + drawCDKLabel(commands_label, FALSE); +} + +static void write_settings(int view) +{ + char* shabang = data.shabang; +// boolean header; + char header[2]; + char* description = data.description; + char* license = data.license; + char* script = data.script; +// boolean debug; + char debug[2]; + char* dfile = data.dfile; +// char* common[4]; + char common[64]; +// boolean lib; + char lib[2]; + char* lfile = data.lfile; + + if (data.shabang == NULL) + shabang = "NULL"; + snprintf(header, sizeof(header), "%i", data.header); + if (data.description == NULL) + description = "NULL"; + if (data.license == NULL) + license = "NULL"; + if (data.script == NULL) + script = "NULL"; + snprintf(debug, sizeof(debug), "%i", data.debug); + if (data.dfile == NULL) + dfile = "NULL"; + int written = 0; + if (data.common[0] == NULL) + written += snprintf(common + written, sizeof(common) - written, "NULL, "); + else + written += snprintf(common + written, sizeof(common) - written, "%s, ", data.common[0]); + if (data.common[1] == NULL) + written += snprintf(common + written, sizeof(common) - written, "NULL, "); + else + written += snprintf(common + written, sizeof(common) - written, "%s, ", data.common[1]); + if (data.common[2] == NULL) + written += snprintf(common + written, sizeof(common) - written, "NULL, "); + else + written += snprintf(common + written, sizeof(common) - written, "%s, ", data.common[2]); + if (data.common[3] == NULL) + written += snprintf(common + written, sizeof(common) - written, "NULL"); + else + written += snprintf(common + written, sizeof(common) - written, "%s", data.common[3]); + snprintf(lib, sizeof(lib), "%i", data.lib); + if (data.lfile == NULL) + lfile = "NULL"; + + if (view) + { + char* msg[] = { shabang, header, description, license, script, + debug, dfile, common, lib, lfile }; + + popupLabel(screen, msg, 10); + } + else + { + char* home = getenv("HOME"); + if (!home) + { + exec_result.status = 1; + snprintf(exec_result.message, sizeof(exec_result.message), "no home dir" + "found"); + return; + } + + char spath[strlen(home) + strlen(settings) + 2]; + snprintf(spath, sizeof(spath), "%s/%s", home, settings); + FILE* fsettings = fopen(spath, "w"); + if (!fsettings) + { + exec_result.status = errno; + strerror_r(errno, exec_result.message, sizeof(exec_result.message)); + return; + } + + const char* fstring = "shabang=%s\nheader=%i\ndescription=\"%s\"\nlicense=%s\n" + "script=%s\ndebug=%i\ndfile=%s\ncommon1=\"%s\"\ncommon2=\"%s\"\ncommon3=\"%s\"\n" + "common4=\"%s\"\nlib=%i\nlfile=%s\n"; + int res = fprintf(fsettings, fstring, data.shabang, data.header, data.description, + data.license, data.script, data.debug, data.dfile, data.common[0], data.common[1], + data.common[2], data.common[3], data.lib, data.lfile); + fclose(fsettings); + if (res < 0) + { + exec_result.status = 1; + snprintf(exec_result.message, sizeof(exec_result.message), "writing settings" + "failed"); + return; + } + } +} + +static int help(EObjectType cdktype, void* object, void* clientdata, chtype key) +{ + char* buttons[] = { " OK " }; + char** info = (char**) calloc(2, sizeof(char*)); + info[0] = (char*) malloc(5 + strlen(help_file)); + snprintf(info[0], 5 + strlen(help_file), "", help_file); + + char* text = commands_msg; + update_options(help_opts); + CDKSCREEN* screen = (CDKSCREEN*) clientdata; + CDKVIEWER* help_viewer = newCDKViewer(screen, CENTER, CENTER, y_size - 4, x_size - 2, + buttons, 1, A_REVERSE, TRUE, FALSE); + setCDKViewer(help_viewer, "Help", info, -1, A_REVERSE, TRUE, FALSE, FALSE); + activateCDKViewer(help_viewer, NULL); + destroyCDKViewer(help_viewer); + update_options(text); + refreshCDKScreen(screen); + + return TRUE; +} + +static int quit(EObjectType cdktype, void* object, void* clientdata, chtype key) +{ + char* buttons[] = { " OK ", " Cancel " }; + char* msg[] = { "Realy quit?" }; + char* text = commands_msg; + update_options(button_opts); + int res = popupDialog(screen, msg, 1, buttons, 2); + if (res == 0) + { + destroy_controls(); + destroyCDKScreen(screen); + endCDK(); + exit(EXIT_SUCCESS); + } + update_options(text); + + return TRUE; +} + +void sig_int(int signo) +{ + quit(0, NULL, NULL, 0); +} + +int main(int argc, char* argv[]) +{ + dimension_check(); + + window = initscr(); + screen = initCDKScreen(window); + initCDKColor(); + + create_controls(); + + bindCDKObject(vRADIO, shabang_radio, '?', help, screen); + bindCDKObject(vSELECTION, header_selection, '?', help, screen); + bindCDKObject(vENTRY, description_entry, '?', help, screen); + bindCDKObject(vRADIO, license_radio, '?', help, screen); + bindCDKObject(vBUTTON, script_button, '?', help, screen); + bindCDKObject(vENTRY, script_entry, '?', help, screen); + bindCDKObject(vSELECTION, debug_selection, '?', help, screen); + bindCDKObject(vBUTTON, dfile_button, '?', help, screen); + bindCDKObject(vENTRY, dfile_entry, '?', help, screen); + bindCDKObject(vSELECTION, common_selection, '?', help, screen); + bindCDKObject(vSELECTION, lib_selection, '?', help, screen); + bindCDKObject(vBUTTON, lfile_button, '?', help, screen); + bindCDKObject(vENTRY, lfile_entry, '?', help, screen); + bindCDKObject(vBUTTON, generate_button, '?', help, screen); + + bindCDKObject(vRADIO, shabang_radio, KEY_F10, quit, screen); + bindCDKObject(vSELECTION, header_selection, KEY_F10, quit, screen); + bindCDKObject(vENTRY, description_entry, KEY_F10, quit, screen); + bindCDKObject(vRADIO, license_radio, KEY_F10, quit, screen); + bindCDKObject(vBUTTON, script_button, KEY_F10, quit, screen); + bindCDKObject(vENTRY, script_entry, KEY_F10, quit, screen); + bindCDKObject(vSELECTION, debug_selection, KEY_F10, quit, screen); + bindCDKObject(vBUTTON, dfile_button, KEY_F10, quit, screen); + bindCDKObject(vENTRY, dfile_entry, KEY_F10, quit, screen); + bindCDKObject(vSELECTION, common_selection, KEY_F10, quit, screen); + bindCDKObject(vSELECTION, lib_selection, KEY_F10, quit, screen); + bindCDKObject(vBUTTON, lfile_button, KEY_F10, quit, screen); + bindCDKObject(vENTRY, lfile_entry, KEY_F10, quit, screen); + bindCDKObject(vBUTTON, generate_button, KEY_F10, quit, screen); + + signal(SIGINT, sig_int); + + int res; + while (TRUE) + { + res = process_shabang(); + if (res) + continue; + + res = process_header(); + if (res) + continue; + + res = process_script(); + if (res) + continue; + + res = process_debug(); + if (res) + continue; + + res = process_common(); + if (res) + continue; + + res = process_lib(); + if (res) + continue; + + res = process_gen(); + if (res) + continue; + + break; + } + + destroy_controls(); + + destroyCDKScreen(screen); + endCDK(); + + return 0; +} diff --git a/src/usr_share_shgen/GPLv2 b/src/usr_share_shgen/GPLv2 new file mode 100644 index 0000000..6cf5064 --- /dev/null +++ b/src/usr_share_shgen/GPLv2 @@ -0,0 +1,14 @@ +# 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; either version 2 +# of the License, or (at your option) any later version. +# +# 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., 51 Franklin Street, Fifth Floor, Boston, +# MA 02110-1301, USA. diff --git a/src/usr_share_shgen/GPLv3 b/src/usr_share_shgen/GPLv3 new file mode 100644 index 0000000..5c296cf --- /dev/null +++ b/src/usr_share_shgen/GPLv3 @@ -0,0 +1,12 @@ +# 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, either version 3 of the License, or +# (at your option) any later version. +# +# 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, see . diff --git a/src/usr_share_shgen/custom b/src/usr_share_shgen/custom new file mode 100644 index 0000000..3b9f63e --- /dev/null +++ b/src/usr_share_shgen/custom @@ -0,0 +1 @@ +# This is a custom license... diff --git a/src/usr_share_shgen/help b/src/usr_share_shgen/help new file mode 100644 index 0000000..bd86e49 --- /dev/null +++ b/src/usr_share_shgen/help @@ -0,0 +1,42 @@ +GENERAL COMMANDS + + - Show this help. + - Quit the application. + +Context commands are shown in the line at the bottom. They change when you +change to an other generation option. + +GENERATION OPTIONS AND SETTINGS + +Shabang - Choose one for the type of shell script. Keep in mind different shell +capabilities. + +Header - Activates header. The header contains sctipt author and year of +creation as well as a description line and the licence text. If this option is +not set the following two options have no effect. + +Description - A short desctiption of what the generated sctipt is intended to +do. + +License - Choose a license option that comes up with the header. Since the +application creates the ~/.shgen directory the custom license file goes there. +Modify it to get your license text into the header. + +Script name and path - Choose where to generate the shell script. Navigate to +the destination first and then enter a name. + +Debug - Activates debug output. Your shell script is then using set -x and the +output is going to a file. This option activates the next one. + +Debug file name and path - Choose where debug output is going to. Navigate to +the destination first and then enter a name. + +Functions - Choosing usage() gives your sctipt the -h option and prints info +about script usage. log(), error() and warning() are functions you can use to +print log output to stdout. error() terminates script execution after its call. + +lib.sh - Activates generation of a common script where log(), error() and +warning() are going to. This options activates the next one. + +lib.sh path - Choose location of lib.sh. Navigate to the destination first and +then enter a name. diff --git a/src/usr_share_shgen/lib b/src/usr_share_shgen/lib new file mode 100644 index 0000000..5df564c --- /dev/null +++ b/src/usr_share_shgen/lib @@ -0,0 +1,13 @@ +%shabang% +# +# Library functions and definitions. +%copyright% +# +%license% + +LANG=C +%debug% + +%common2% +%common3% +%common4% diff --git a/src/usr_share_shgen/shgen.sh b/src/usr_share_shgen/shgen.sh new file mode 100755 index 0000000..5f78d00 --- /dev/null +++ b/src/usr_share_shgen/shgen.sh @@ -0,0 +1,352 @@ +#!/bin/bash + +INSTALL_DIR=/usr/share/shgen +LOCAL_DIR=~/.shgen +SETTINGS=$LOCAL_DIR/settings + +ERR_FILE=/tmp/shgen.tmp + +E_NOARGS=1 +E_CREATE_DIR=2 +E_GENERATE=3 + +LANG=C + +create_dir() +{ + if ! [ -e $LOCAL_DIR ]; then + # create local dir + mkdir $LOCAL_DIR 2>$ERR_FILE 1>/dev/null ||\ + error "creating local dir failed" $E_CREATE_DIR $ERR_FILE + # copy files and set permisson + cp $INSTALL_DIR/skeleton $INSTALL_DIR/custom $INSTALL_DIR/GPLv*\ + $INSTALL_DIR/lib $LOCAL_DIR/ 2>$ERR_FILE 1>/dev/null ||\ + error "copying files failed" $E_CREATE_DIR $ERR_FILE + fi +} + +error() +{ + echo -n "Error: $1" 1>&2 + [ -z $3 ] && echo "" || echo -e ":\n$(cat $3)" 1>&2 + exit $2 +} + +generate() +{ + # read/source settings file + . $SETTINGS + + # generate main script according to the settings + cp $LOCAL_DIR/skeleton $script 2>$ERR_FILE 1>/dev/null ||\ + error "creating script failed" $E_GENERATE $ERR_FILE + chmod +x $script 2>$ERR_FILE 1>/dev/null ||\ + error "setting script permisson failed" $E_GENERATE $ERR_FILE + + ################################################### + # lib + ################################################### + if [ $lib -eq 1 ]; then + # generate lib script according to the settings + cp $LOCAL_DIR/lib $lfile 2>$ERR_FILE 1>/dev/null ||\ + error "creating lib failed" $E_GENERATE $ERR_FILE + chmod +x $lfile 2>$ERR_FILE 1>/dev/null ||\ + error "setting lib permisson failed" $E_GENERATE $ERR_FILE + # write settings + sed "s:%lib%:. $lfile:" -i $script 2>$ERR_FILE\ + 1>/dev/null || error "writing lib failed" $E_GENERATE $ERR_FILE + else + # delete placeholder + sed "/%lib%/d" -i $script 2>$ERR_FILE 1>/dev/null || error\ + "deleting lib placeholder failed" $E_GENERATE $ERR_FILE + fi + + ################################################### + # shabang + ################################################### + sed "s:%shabang%:#!$shabang:" -i $script 2>$ERR_FILE 1>/dev/null ||\ + error "writing shabang failed" $E_GENERATE $ERR_FILE + if [ $lib -eq 1 ]; then + sed "s:%shabang%:#!$shabang:" -i $lfile 2>$ERR_FILE\ + 1>/dev/null || error "writing shabang in lib failed" $E_GENERATE\ + $ERR_FILE + fi + + ################################################### + # header + ################################################### + if [ $header -eq 1 ]; then + # description, copyright + local copyright="# Copyright (C) $(date +%Y) $USER" + sed -e "s/%description%/# $description/" -e\ + "s/%copyright%/$copyright/" -i $script 2>$ERR_FILE 1>/dev/null\ + || error "writing header failed" $E_GENERATE $ERR_FILE + # same to lib + if [ $lib -eq 1 ]; then + sed "s/%copyright%/$copyright/" -i $lfile 2>$ERR_FILE\ + 1>/dev/null || error "writing header in lib failed"\ + $E_GENERATE $ERR_FILE + fi + + # license + case $license in + GPLv2|GPLv3|custom) + sed "/%license%/r $LOCAL_DIR/$license" -i $script\ + 2>$ERR_FILE 1>/dev/null || error "writing header failed"\ + $E_GENERATE $ERR_FILE + # same to lib + if [ $lib -eq 1 ]; then + sed "/%license%/r $LOCAL_DIR/$license" -i $lfile\ + 2>$ERR_FILE 1>/dev/null || error\ + "writing header in lib failed" $E_GENERATE $ERR_FILE + fi + ;; + esac + sed "/%license%/d" -i $script 2>$ERR_FILE 1>/dev/null || error\ + "deleting header placeholder failed" $E_GENERATE $ERR_FILE + # same to lib + if [ $lib -eq 1 ]; then + sed "/%license%/d" -i $lfile 2>$ERR_FILE 1>/dev/null || error\ + "deleting header placeholder in lib failed" $E_GENERATE\ + $ERR_FILE + fi + else + # delete placeholder + sed -e "/%description%/d" -e "/%copyright%/d" -e "/%license%/d"\ + -i $script 2>$ERR_FILE 1>/dev/null || error\ + "deleting header placeholder failed" $E_GENERATE $ERR_FILE + # same to lib + if [ $lib -eq 1 ]; then + sed -e "/%copyright%/d" -e "/%license%/d" -i $lfile 2>$ERR_FILE\ + 1>/dev/null || error "deleting header placeholder in lib failed"\ + $E_GENERATE $ERR_FILE + fi + fi + + # create temp file + local tmpf=$(mktemp 2>$ERR_FILE) + [ -e $tmpf ] || error "creating tmpfile failed" $E_GENERATE $ERR_FILE + + ################################################### + # debug + ################################################### + if [ $debug -eq 1 ]; then + cat << EOF >/$tmpf +exec 3>$dfile +BASH_XTRACEFD=3 +set -x +EOF + if [ $lib -eq 1 ]; then + sed -e "/%debug%/r $tmpf" -e "/%debug%/d" -i $lfile\ + 2>$ERR_FILE 1>/dev/null || error\ + "writing debug in lib failed" $E_GENERATE $ERR_FILE + # delete placeholder in script + sed "/%debug%/d" -i $script 2>$ERR_FILE 1>/dev/null ||\ + error "deleting debug placeholder failed" $E_GENERATE\ + $ERR_FILE + else + sed -e "/%debug%/r $tmpf" -e "/%debug%/d" -i $script\ + 2>$ERR_FILE 1>/dev/null || error "writing debug failed"\ + $E_GENERATE $ERR_FILE + fi + else + # delete placeholder + sed "/%debug%/d" -i $script 2>$ERR_FILE 1>/dev/null ||\ + error "deleting debug placeholder failed" $E_GENERATE $ERR_FILE + fi + + ################################################### + # usage() + ################################################### + if [ "$common1" == "usage()" ]; then + cat << _EOF >/$tmpf +usage() +{ + cat << EOF +Usage: \$0 [-h] + +Options: -h show help (resp. this message) +EOF +} + +_EOF + # place description if available + if [ $header -eq 1 ]; then + sed -e "4i$description" -i $tmpf + fi + sed -e "/%common1%/r $tmpf" -e "/%common1%/d" -i $script 2>$ERR_FILE\ + 1>/dev/null || error "writing common1 in lib failed" $E_GENERATE\ + $ERR_FILE + else + # delete placeholder + if [ $debug -eq 1 ]; then + sed "/%common1%/d" -i $lfile 2>$ERR_FILE 1>/dev/null || error\ + "deleting common2 placeholder in lib failed" $E_GENERATE $ERR_FILE + fi + sed "/%common1%/d" -i $script 2>$ERR_FILE 1>/dev/null || error\ + "deleting common1 placeholder failed" $E_GENERATE $ERR_FILE + fi + + ################################################### + # log() + ################################################### + if [ "$common2" == "log()" ]; then + cat << _EOF >/$tmpf +log() +{ + echo -n "\$(basename \$0): LOG: \$1" + [ -z \$2 ] || { echo; echo "\$2"; } && { echo; } +} + +_EOF + if [ $lib -eq 1 ]; then + sed -e "/%common2%/r $tmpf" -e "/%common2%/d" -i $lfile\ + 2>$ERR_FILE 1>/dev/null || error "writing common2 failed"\ + $E_GENERATE $ERR_FILE + # delete placeholder in script + sed "/%common2%/d" -i $script 2>$ERR_FILE 1>/dev/null ||\ + error "deleting common2 placeholder failed" $E_GENERATE\ + $ERR_FILE + else + sed -e "/%common2%/r $tmpf" -e "/%common2%/d" -i $script\ + 2>$ERR_FILE 1>/dev/null || error "writing common2 in lib failed"\ + $E_GENERATE $ERR_FILE + fi + else + # delete placeholder + if [ $debug -eq 1 ]; then + sed "/%common2%/d" -i $lfile 2>$ERR_FILE 1>/dev/null || error\ + "deleting common2 placeholder in lib failed" $E_GENERATE $ERR_FILE + fi + sed "/%common2%/d" -i $script 2>$ERR_FILE 1>/dev/null || error\ + "deleting common2 placeholder failed" $E_GENERATE $ERR_FILE + fi + + ################################################### + # error() + ################################################### + if [ "$common3" == "error()" ]; then + cat << _EOF >/$tmpf +error() +{ + echo -n "\$(basename \$0): ERROR: \$1" + [ -z \$2 ] || { echo; echo "\$2"; } && { echo; } + exit 1 +} + +_EOF + if [ $lib -eq 1 ]; then + sed -e "/%common3%/r $tmpf" -e "/%common3%/d" -i $lfile\ + 2>$ERR_FILE 1>/dev/null || error "writing common3 failed"\ + $E_GENERATE $ERR_FILE + # delete placeholder in script + sed "/%common3%/d" -i $script 2>$ERR_FILE 1>/dev/null ||\ + error "deleting common3 placeholder failed" $E_GENERATE\ + $ERR_FILE + else + sed -e "/%common3%/r $tmpf" -e "/%common3%/d" -i $script\ + 2>$ERR_FILE 1>/dev/null || error "writing common3 in lib failed"\ + $E_GENERATE $ERR_FILE + fi + else + # delete placeholder + if [ $debug -eq 1 ]; then + sed "/%common3%/d" -i $lfile 2>$ERR_FILE 1>/dev/null || error\ + "deleting common3 placeholder in lib failed" $E_GENERATE $ERR_FILE + fi + sed "/%common3%/d" -i $script 2>$ERR_FILE 1>/dev/null || error\ + "deleting common3 placeholder failed" $E_GENERATE $ERR_FILE + fi + + ################################################### + # warning() + ################################################### + if [ "$common4" == "warning()" ]; then + cat << _EOF >/$tmpf +log() +{ + echo -n "\$(basename \$0): WARNING: \$1" + [ -z \$2 ] || { echo; echo "\$2"; } && { echo; } +} + +_EOF + if [ $lib -eq 1 ]; then + sed -e "/%common4%/r $tmpf" -e "/%common4%/d" -i $lfile\ + 2>$ERR_FILE 1>/dev/null || error "writing common4 failed"\ + $E_GENERATE $ERR_FILE + # delete placeholder in script + sed "/%common4%/d" -i $script 2>$ERR_FILE 1>/dev/null ||\ + error "deleting common4 placeholder failed" $E_GENERATE\ + $ERR_FILE + else + sed -e "/%common4%/r $tmpf" -e "/%common4%/d" -i $script\ + 2>$ERR_FILE 1>/dev/null || error "writing common4 in lib failed"\ + $E_GENERATE $ERR_FILE + fi + else + # delete placeholder + if [ $debug -eq 1 ]; then + sed "/%common4%/d" -i $lfile 2>$ERR_FILE 1>/dev/null || error\ + "deleting common4 placeholder in lib failed" $E_GENERATE $ERR_FILE + fi + sed "/%common4%/d" -i $script 2>$ERR_FILE 1>/dev/null || error\ + "deleting common4 placeholder failed" $E_GENERATE $ERR_FILE + fi + + # delete temp file + rm $tmpf &>/dev/null + + ################################################### + # option processing + ################################################### + if [ "$common1" == "usage()" ]; then + cat << _EOF >/$tmpf +while getopts ":h" opt; do + case \$opt in + h) + usage + ;; + *) + usage + ;; + esac +done +_EOF + sed -e "/%options%/r $tmpf" -e "/%options%/d" -i $script 2>$ERR_FILE\ + 1>/dev/null || error "writing options failed" $E_GENERATE $ERR_FILE + else + # delete placeholder + sed "/%options%/d" -i $script 2>$ERR_FILE 1>/dev/null || error\ + "deleting options placeholder failed" $E_GENERATE $ERR_FILE + fi + + # delete temp file + rm $tmpf &>/dev/null +} + +usage() +{ + cat < + +Options: -c create the local directory ~/.shgen + -g generate shell scripts according to the settings +EOF + exit $E_NOARGS +} + +[ $# -eq 0 ] && usage + +while getopts ":cg" opt; do + case $opt in + c) + create_dir + ;; + g) + generate + ;; + *) + usage + ;; + esac +done diff --git a/src/usr_share_shgen/skeleton b/src/usr_share_shgen/skeleton new file mode 100644 index 0000000..e4f4450 --- /dev/null +++ b/src/usr_share_shgen/skeleton @@ -0,0 +1,28 @@ +%shabang% +# +%description% +%copyright% +# +%license% + +LANG=C +STDERR=$(mktemp) +%debug% + +%lib% + +%common1% +%common2% +%common3% +%common4% +%options% + +# +# Your code goes here. +# Using the generated error function a sample instruction looks as follows: +# +# mkdir what_a_nice_dir 1>/dev/null 2>$STDERR ||\ +# error "mkdir failed" "$(cat $STDERR)" +# + +exit 0 -- 2.30.2