--- /dev/null
+#include <cdk.h>
+#include <signal.h>
+
+/*
+ * 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 = "<C></B><ESCAPE><!B> - Abort </B><TAB|RETURN><!B> - Next";
+static char* enable_opts = "<C></B><ESCAPE><!B> - Abort </B><TAB|RETURN><!B> - Next"
+ " </B><SPACE><!B> - Choose";
+static char* select_opts = "<C></B><ESCAPE><!B> - Abort </B><TAB|RETURN><!B> - Next"
+ " </B><UP|DOWN><!B> - Select </B><SPACE><!B> - Choose";
+static char* button_opts = "<C></B><ESCAPE><!B> - Abort </B><RETURN><!B> - Enter";
+static char* gen_opts = "<C></B><ESCAPE><!B> - Abort </B><RETURN><!B> - Generate";
+static char* help_opts = "<C></B><ESCAPE><!B> - Abort </B><RETURN><!B> - Quit help"
+ " </B><UP><!B> - Line up </B><DOWN><!B> - 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[] = { "<L></B> Shell script generator v0.1<!B>", hline_text };
+ title_label = newCDKLabel(screen, LEFT, TOP, title_text, 2, FALSE, FALSE);
+ drawCDKLabel(title_label, FALSE);
+ char* options_text[] = { "<R></B><?><!B> - Help </B><F10><!B> - 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, "</N>", "</N>",
+ "</N>", "</N>", 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 = "<C></B>Generation progress<!B>";
+ char* gen_hl = "<#HL(34)>";
+ char* gen_1lp = "Create local directory [</B></00> pending <!00><!B>]";
+ char* gen_1lr = "Create local directory [</B></32> running <!32><!B>]";
+ char* gen_1ld = "Create local directory [</B></24> ready <!24><!B>]";
+ char* gen_1le = "Create local directory [</B></16> error <!16><!B>]";
+ char* gen_2lp = "Write settings [</B></00> pending <!00><!B>]";
+ char* gen_2lr = "Write settings [</B></32> running <!32><!B>]";
+ char* gen_2ld = "Write settings [</B></24> ready <!24><!B>]";
+ char* gen_2le = "Write settings [</B></16> error <!16><!B>]";
+ char* gen_3lp = "Generate script [</B></00> pending <!00><!B>]";
+ char* gen_3lr = "Generate script [</B></32> running <!32><!B>]";
+ char* gen_3ld = "Generate script [</B></24> ready <!24><!B>]";
+ char* gen_3le = "Generate script [</B></16> error <!16><!B>]";
+ char* gen_err = "</B></16>Error occurred:<!16><!B>";
+
+ 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, "</N>", "</N>",
+ "</N>", "</N>", 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, "</N>", "</N>", "</N>", "</N>", 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), "<F=%s>", 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, "</C></B>Help<!B><!C>", 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;
+}
--- /dev/null
+#!/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 <<EOF
+Usage: $0 -<c|g>
+
+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