--- /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