dolconf almost done.
authorfredrik <fredrik@959494ce-11ee-0310-bf91-de5d638817bd>
Sun, 6 May 2007 19:58:35 +0000 (19:58 +0000)
committerfredrik <fredrik@959494ce-11ee-0310-bf91-de5d638817bd>
Sun, 6 May 2007 19:58:35 +0000 (19:58 +0000)
git-svn-id: svn+ssh://svn.dolda2000.com/srv/svn/repos/src/doldaconnect@1003 959494ce-11ee-0310-bf91-de5d638817bd

config/dolconf-assistant.desc
config/dolconf-wnd.desc
config/dolconf.c

index 8f29ecf..03fe7ca 100644 (file)
@@ -4,8 +4,8 @@
        :align title: Introduction ptype: INTRO cmpl: TRUE xs: 0 ys: 0 xa: 0 ya: 0
                $lbl wrap: y label: "This assistent will guide you through the steps minimally required for setting up Dolda Connect as a normal Direct Connect client.\\nIf you wish to set up the more advanced features of Dolda Connect, please either use the more complete setup form of this program, which will be available after this assistant is complete, or edit the configuration file (~/.doldacond.conf) manually."
        end
-       :vbox title: "Personal info" var: y name: page1
-               $lbl label: "Please enter your personal information:"
+       :vbox title: "Published info" var: y name: page1
+               $lbl label: "Please enter how you wish to present yourself to the network:"
                :table rows: 2 cols: 2 fill: TRUE
                        $mlbl label: "_Screen name" mwidget: nick tx: 0 ty: 0
                        $text name: nick var: y expand: y fill: y sig: changed tx: 1 ty: 0
@@ -44,7 +44,7 @@
                                $text name: extip var: y fill: y expand: y sig(changed): cb_ast_checkports
                        end
                end
-               $lbl markup: "<i>Specify a port when this computer is behind a NAT router or similar. You will also need to configure your NAT router to forward that port to this computer, and specify what external IP address to use.</i>" wrap: y align: "0:0.5" wpad: "20:0"
+               $lbl markup: "<i>Specify a port when this computer is behind a NAT router or another device blocking incoming connections. You will also need to configure your NAT router to forward that port to this computer, and specify what external IP address to use. Note also that the ports need to be above 1024.</i>" wrap: y align: "0:0.5" wpad: "20:0"
                $radio label: "Passi_ve mode" var: y name: mode_psv group: mode_act
                $lbl markup: "<i>Passive mode can be used as a last resort if you truly cannot use active mode. It is highly likely that using passive mode will lead to impaired performance.</i>" wrap: y align: "0:0.5" wpad: "20:0"
        end
@@ -53,5 +53,9 @@
                :sw fill: TRUE expand: TRUE
                        $textview name: summary var: y editable: FALSE
                end
+               $lbl label: "What do you want to do after confirming?"
+               $radio label: "_Run Dolda Connect normally" var: y name: action_dolcon
+               $radio label: "_Exit this configuration program" var: y name: action_exit group: action_dolcon
+               $radio label: "_Open the complete configuration form" var: y name: action_wnd group: action_dolcon
        end
 end
index e848c6b..35e9314 100644 (file)
@@ -3,23 +3,50 @@
 :wnd name: wnd title: "Dolda Connect configurator" var: y sig(delete_event): astcancel
        :vbox
                :notebook pos: LEFT fill: y expand: y
-                       :table rows: 2 cols: 2 nblabel: "_Personal info"
+                       :table rows: 4 cols: 2 nblabel: "_Published info"
                                $mlbl label: "Screen _name" mwidget: nick tx: 0 ty: 0
                                $text name: nick var: y expandx: y fillx: y tx: 1 ty: 0
                                $mlbl label: "_Description" mwidget: desc tx: 0 ty: 1
                                $text name: desc var: y expandx: y fillx: y tx: 1 ty: 1
+                               $mlbl label: "_Connection type" mwidget: cntype tx: 0 ty: 2
+                               $text name: cntype var: y expandx: y fillx: y tx: 1 ty: 2
+                               $mlbl label: "_E-mail address" mwidget: mail tx: 0 ty: 3
+                               $text name: mail var: y expandx: y fillx: y tx: 1 ty: 3
                        end
-                       :vbox nblabel: "S_hared directories" var: y name: page2
-                               :vbox expand: TRUE fill: TRUE
-                                       :sw expand: TRUE fill: TRUE
-                                               :treeview name: sharelist var: y
-                                                       $tvcol title: Path text: 1 sortcol: 1
-                                               end
+                       :vbox nblabel: "S_hared directories"
+                               :sw expand: TRUE fill: TRUE
+                                       :treeview name: sharelist var: y
+                                               $tvcol title: Path text: 1 sortcol: 1
                                        end
-                                       :hbox
-                                               $sbtn name: shareadd stock: ADD sig: clicked
-                                               $sbtn name: sharerem stock: REMOVE sig: clicked
+                               end
+                               :hbox
+                                       $sbtn name: shareadd stock: ADD sig: clicked
+                                       $sbtn name: sharerem stock: REMOVE sig: clicked
+                               end
+                       end
+                       :vbox nblabel: "Net_work"
+                               $radio label: "_Active mode" var: y name: mode_act sig: toggled
+                               :vbox var: y name: natbox
+                                       $chk name: orport var: y label: "Spe_cify ports" sig: toggled
+                                       :hbox spacing: 10 var: y name: portbox sensitive: FALSE
+                                               $mlbl label: "_TCP port:" mwidget: tcpport
+                                               $text name: tcpport var: y fill: y expand: y
+                                               $mlbl label: "_UDP port:" mwidget: udpport
+                                               $text name: udpport var: y fill: y expand: y
                                        end
+                                       $chk name: oraddr var: y label: "_Override IP address" sig: toggled
+                                       :hbox spacing: 10 var: y name: addrbox sensitive: FALSE
+                                               $mlbl label: "_IP address:" mwidget: extip
+                                               $text name: extip var: y fill: y expand: y
+                                       end
+                               end
+                               $radio label: "Passi_ve mode" var: y name: mode_psv group: mode_act
+                       end
+                       :vbox nblabel: "_Remoting"
+                               $chk label: "_Allow user interfaces to connect remotely" var: y name: uinet sig: toggled
+                               :vbox var: y name: uibox sensitive: FALSE
+                                       $chk label: "_Trust connections without a password" var: y name: authless
+                                       $lbl markup: "<i>Important: The above option is a security hole. It allows you to connect without a password, but it also allows everyone else to do the same, so you should absolutely not use it unless you are sure that everyone who can connect to your computer is trusted.</i>" wrap: y
                                end
                        end
                end
index 84c76c7..3cec63e 100644 (file)
@@ -46,11 +46,36 @@ struct cfvar {
     char *rname;
     char *val;
     struct validation *vld;
+    GtkWidget **astw, **cfww;
 };
 
 char *cfname;
 GtkWindow *rootwnd = NULL;
 GtkListStore *shares;
+int state;
+int ignoreclose = 0;
+
+void astcancel(GtkWidget *widget, gpointer uudata);
+void astupdate(GtkWidget *widget, GtkWidget *page, gpointer uudata);
+void cb_ast_wnd_apply(GtkWidget *widget, gpointer uudata);
+void cb_ast_nick_changed(GtkWidget *widget, gpointer uudata);
+void cb_ast_shareadd_clicked(GtkWidget *widget, gpointer uudata);
+void cb_ast_sharerem_clicked(GtkWidget *widget, gpointer uudata);
+void cb_ast_checkports(GtkWidget *widget, gpointer uudata);
+void cb_ast_mode_nat_toggled(GtkWidget *widget, gpointer uudata);
+void cb_cfw_mode_act_toggled(GtkWidget *widget, gpointer uudata);
+void cb_cfw_orport_toggled(GtkWidget *widget, gpointer uudata);
+void cb_cfw_oraddr_toggled(GtkWidget *widget, gpointer uudata);
+void cb_cfw_uinet_toggled(GtkWidget *widget, gpointer uudata);
+void cb_cfw_save_clicked(GtkWidget *widget, gpointer uudata);
+void cb_cfw_quit_clicked(GtkWidget *widget, gpointer uudata);
+void cb_cfw_shareadd_clicked(GtkWidget *widget, gpointer uudata);
+void cb_cfw_sharerem_clicked(GtkWidget *widget, gpointer uudata);
+
+#define _(text) gettext(text)
+
+#include "dolconf-assistant.gtk"
+#include "dolconf-wnd.gtk"
 
 int v_nonempty(const char *val)
 {
@@ -97,6 +122,7 @@ int v_ipv4(const char *val)
     return(inet_aton(val, &buf) != 0);
 }
 
+#undef _
 #define _(text) text
 
 struct validation nonempty = {
@@ -130,34 +156,24 @@ struct validation *vldxlate[] = {
 };
 
 struct cfvar config[] = {
-    {"cli.defnick", _("Nickname"), "", &dcstring},
+    {"cli.defnick", _("Screen name"), "", &dcstring, &ast_nick, &cfw_nick},
     {"net.mode", NULL, "0", &natural},
-    {"net.visibleipv4", "IP address", "0.0.0.0", &ipv4},
+    {"net.visibleipv4", "IP address", "0.0.0.0", &ipv4, NULL, &cfw_extip},
     {"ui.onlylocal", NULL, "0", &natural},
     {"ui.port", NULL, "-1", &integer},
     {"auth.authless", NULL, "0", &natural},
     {"transfer.slots", _("Upload slots"), "6", &natural},
-    {"dc.speedstring", _("Connection speed"), "DSL", &dcstring},
-    {"dc.desc", _("Share description"), "", NULL},
-    {"dc.tcpport", _("Direct Connect TCP port"), "0", &natural},
-    {"dc.udpport", _("Direct Connect UDP port"), "0", &natural},
+    {"dc.speedstring", _("Connection speed"), "DSL", &dcstring, NULL, &cfw_cntype},
+    {"dc.email", _("E-mail address"), "spam@spam.net", &dcstring, NULL, &cfw_mail},
+    {"dc.desc", _("Share description"), "", NULL, &ast_desc, &cfw_desc},
+    {"dc.tcpport", _("Direct Connect TCP port"), "0", &natural, NULL, &cfw_tcpport},
+    {"dc.udpport", _("Direct Connect UDP port"), "0", &natural, NULL, &cfw_udpport},
     {NULL}
 };
 
 #undef _
 #define _(text) gettext(text)
 
-void astcancel(GtkWidget *widget, gpointer uudata);
-void astupdate(GtkWidget *widget, GtkWidget *page, gpointer uudata);
-void cb_ast_wnd_apply(GtkWidget *widget, gpointer uudata);
-void cb_ast_nick_changed(GtkWidget *widget, gpointer uudata);
-void cb_ast_shareadd_clicked(GtkWidget *widget, gpointer uudata);
-void cb_ast_sharerem_clicked(GtkWidget *widget, gpointer uudata);
-void cb_ast_checkports(GtkWidget *widget, gpointer uudata);
-void cb_ast_mode_nat_toggled(GtkWidget *widget, gpointer uudata);
-
-#include "dolconf-assistant.gtk"
-
 struct cfvar *findcfvar(char *name)
 {
     struct cfvar *v;
@@ -226,7 +242,7 @@ char *getword(char **p)
     }
     if(p2 == NULL)
        p2 = *p + strlen(*p);
-    len = p2 - *p;
+    len = p2 - *p - ((*p2 == '\"')?1:0);
     buf = smalloc(len + 1);
     memcpy(buf, *p, len);
     buf[len] = 0;
@@ -389,20 +405,36 @@ void writeconfig(void)
     fclose(cf);
 }
 
-void astcancel(GtkWidget *widget, gpointer uudata)
+void fillcfw(void)
 {
-    gtk_main_quit();
+    struct cfvar *var;
+    
+    for(var = config; var->name != NULL; var++) {
+       if(var->cfww != NULL)
+           gtk_entry_set_text(GTK_ENTRY(*(var->cfww)), var->val);
+    }
+    if(atoi(findcfvar("dc.tcpport")->val) || atoi(findcfvar("dc.udpport")->val))
+       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(cfw_orport), TRUE);
+    else
+       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(cfw_orport), FALSE);
+    if(strcmp(findcfvar("net.visibleipv4")->val, "0.0.0.0"))
+       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(cfw_oraddr), TRUE);
+    else
+       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(cfw_oraddr), FALSE);
+    if(strcmp(findcfvar("ui.port")->val, "-1")) {
+       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(cfw_uinet), TRUE);
+       if(strcmp(findcfvar("auth.authless")->val, "1"))
+           gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(cfw_authless), FALSE);
+       else
+           gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(cfw_authless), TRUE);
+    } else {
+       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(cfw_uinet), FALSE);
+       gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(cfw_authless), FALSE);
+    }
 }
 
-#define bufcats(buf, str) bufcat(buf, str, strlen(str))
-
-void astupdate(GtkWidget *widget, GtkWidget *page, gpointer uudata)
+void ast2conf(void)
 {
-    char *s, *buf;
-    size_t sdata, ssize;
-    struct cfvar *var;
-    GtkTreeIter iter;
-    
     setcfvar("cli.defnick", gtk_entry_get_text(GTK_ENTRY(ast_nick)));
     setcfvar("dc.desc", gtk_entry_get_text(GTK_ENTRY(ast_desc)));
     if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(ast_mode_psv))) {
@@ -419,6 +451,60 @@ void astupdate(GtkWidget *widget, GtkWidget *page, gpointer uudata)
            setcfvar("dc.udpport", "0");
        }
     }
+}
+
+void cfw2conf(void)
+{
+    struct cfvar *var;
+    
+    for(var = config; var->name != NULL; var++) {
+       if(var->cfww != NULL) {
+           free(var->val);
+           var->val = sstrdup(gtk_entry_get_text(GTK_ENTRY(*(var->cfww))));
+       }
+    }
+    if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(cfw_mode_act))) {
+       setcfvar("net.mode", "0");
+       if(!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(cfw_orport))) {
+           setcfvar("dc.tcpport", "0");
+           setcfvar("dc.udpport", "0");
+       }
+       if(!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(cfw_oraddr))) {
+           setcfvar("net.visibleipv4", "0.0.0.0");
+       }
+    } else {
+       setcfvar("net.mode", "1");
+    }
+    if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(cfw_uinet))) {
+       setcfvar("ui.port", "1500");
+       if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(cfw_authless)))
+           setcfvar("auth.authless", "1");
+       else
+           setcfvar("auth.authless", "0");
+    } else {
+       setcfvar("ui.port", "-1");
+       setcfvar("auth.authless", "0");
+    }
+}
+
+void astcancel(GtkWidget *widget, gpointer uudata)
+{
+    if(ignoreclose)
+       return;
+    gtk_main_quit();
+    state = -1;
+}
+
+#define bufcats(buf, str) bufcat(buf, str, strlen(str))
+
+void astupdate(GtkWidget *widget, GtkWidget *page, gpointer uudata)
+{
+    char *s, *buf;
+    size_t sdata, ssize;
+    struct cfvar *var;
+    GtkTreeIter iter;
+    
+    ast2conf();
     s = NULL;
     sdata = ssize = 0;
     for(var = config; var->name != NULL; var++) {
@@ -448,6 +534,13 @@ void cb_ast_wnd_apply(GtkWidget *widget, gpointer uudata)
 {
     writeconfig();
     gtk_main_quit();
+    if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(ast_action_dolcon)))
+       state = 2;
+    else if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(ast_action_exit)))
+       state = -1;
+    else
+       state = 0;
+    ignoreclose = 1;
 }
 
 void cb_ast_nick_changed(GtkWidget *widget, gpointer uudata)
@@ -476,9 +569,9 @@ int hasshare(int col, char *name)
     return(0);
 }
 
-void cb_ast_shareadd_clicked(GtkWidget *widget, gpointer uudata)
+int shareadd(void)
 {
-    int i;
+    int i, ret;
     GSList *fns, *next;
     char *fn, *sn, *p;
     GtkTreeIter iter;
@@ -491,8 +584,9 @@ void cb_ast_shareadd_clicked(GtkWidget *widget, gpointer uudata)
     resp = gtk_dialog_run(GTK_DIALOG(chd));
     if(resp != GTK_RESPONSE_ACCEPT) {
        gtk_widget_destroy(chd);
-       return;
+       return(0);
     }
+    ret = 0;
     fns = gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER(chd));
     gtk_widget_destroy(chd);
     while(fns != NULL) {
@@ -514,13 +608,25 @@ void cb_ast_shareadd_clicked(GtkWidget *widget, gpointer uudata)
            gtk_list_store_append(shares, &iter);
            gtk_list_store_set(shares, &iter, 0, sn, 1, fn, -1);
            free(sn);
-           gtk_assistant_set_page_complete(GTK_ASSISTANT(ast_wnd), ast_page2, TRUE);
+           ret = 1;
        }
        g_free(fn);
        next = fns->next;
        g_slist_free_1(fns);
        fns = next;
     }
+    return(ret);
+}
+
+void cb_ast_shareadd_clicked(GtkWidget *widget, gpointer uudata)
+{
+    if(shareadd())
+       gtk_assistant_set_page_complete(GTK_ASSISTANT(ast_wnd), ast_page2, TRUE);
+}
+
+void cb_cfw_shareadd_clicked(GtkWidget *widget, gpointer uudata)
+{
+    shareadd();
 }
 
 void cb_ast_sharerem_clicked(GtkWidget *widget, gpointer uudata)
@@ -533,11 +639,21 @@ void cb_ast_sharerem_clicked(GtkWidget *widget, gpointer uudata)
        gtk_assistant_set_page_complete(GTK_ASSISTANT(ast_wnd), ast_page2, FALSE);
 }
 
+void cb_cfw_sharerem_clicked(GtkWidget *widget, gpointer uudata)
+{
+    GtkTreeIter iter;
+    
+    if(gtk_tree_selection_get_selected(gtk_tree_view_get_selection(GTK_TREE_VIEW(cfw_sharelist)), NULL, &iter))
+       gtk_list_store_remove(shares, &iter);
+}
+
 void cb_ast_checkports(GtkWidget *widget, gpointer uudata)
 {
     gtk_assistant_set_page_complete(GTK_ASSISTANT(ast_wnd), ast_page3,
                                    v_natural(gtk_entry_get_text(GTK_ENTRY(ast_tcpport))) &&
+                                   (atoi(gtk_entry_get_text(GTK_ENTRY(ast_tcpport))) >= 1024) &&
                                    v_natural(gtk_entry_get_text(GTK_ENTRY(ast_udpport))) &&
+                                   (atoi(gtk_entry_get_text(GTK_ENTRY(ast_udpport))) >= 1024) &&
                                    v_ipv4(gtk_entry_get_text(GTK_ENTRY(ast_extip))));
 }
 
@@ -552,9 +668,54 @@ void cb_ast_mode_nat_toggled(GtkWidget *widget, gpointer uudata)
     }
 }
 
+void cb_cfw_mode_act_toggled(GtkWidget *widget, gpointer uudata)
+{
+    gtk_widget_set_sensitive(GTK_WIDGET(cfw_natbox), gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)));
+}
+
+void cb_cfw_orport_toggled(GtkWidget *widget, gpointer uudata)
+{
+    gtk_widget_set_sensitive(GTK_WIDGET(cfw_portbox), gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)));
+}
+
+void cb_cfw_oraddr_toggled(GtkWidget *widget, gpointer uudata)
+{
+    gtk_widget_set_sensitive(GTK_WIDGET(cfw_addrbox), gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)));
+}
+
+void cb_cfw_uinet_toggled(GtkWidget *widget, gpointer uudata)
+{
+    gtk_widget_set_sensitive(GTK_WIDGET(cfw_uibox), gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)));
+}
+
+void cb_cfw_save_clicked(GtkWidget *widget, gpointer uudata)
+{
+    struct cfvar *cv;
+    
+    for(cv = config; cv->name != NULL; cv++) {
+       if((cv->vld != NULL) && !cv->vld->check(cv->val)) {
+           if(cv->rname) {
+               msgbox(GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, cv->vld->invmsg, cv->rname);
+           } else {
+               msgbox(GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, _("Internal error (Auto-generated variable %s has an invalid value \"%s\")"), cv->name, cv->val);
+           }
+           return;
+       }
+    }
+    cfw2conf();
+    writeconfig();
+}
+
+void cb_cfw_quit_clicked(GtkWidget *widget, gpointer uudata)
+{
+    gtk_main_quit();
+    state = -1;
+}
+
 int main(int argc, char **argv)
 {
     struct passwd *pwd;
+    int i;
     
     setlocale(LC_ALL, "");
     bindtextdomain(PACKAGE, LOCALEDIR);
@@ -563,8 +724,10 @@ int main(int argc, char **argv)
     
     gtk_init(&argc, &argv);
     create_ast_wnd();
+    create_cfw_wnd();
     shares = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_STRING);
     gtk_tree_view_set_model(GTK_TREE_VIEW(ast_sharelist), GTK_TREE_MODEL(shares));
+    gtk_tree_view_set_model(GTK_TREE_VIEW(cfw_sharelist), GTK_TREE_MODEL(shares));
     
     cfname = NULL;
     if(getenv("HOME") != NULL) {
@@ -580,15 +743,44 @@ int main(int argc, char **argv)
     
     if(access(cfname, F_OK)) {
        if(msgbox(GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO, _("It appears that you have not run this setup program before. Would you like to run the first-time setup assistant?")) == GTK_RESPONSE_YES) {
-           gtk_window_set_default_size(GTK_WINDOW(ast_wnd), 500, 350);
-           gtk_widget_show(ast_wnd);
+           state = 1;
+       } else {
+           state = 0;
        }
     } else {
+       state = 0;
        if(readconfig() == 1) {
            if(msgbox(GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO, _("The configuration file appears to have been edited outside the control of this program. If you continue using this program, all settings not handled by it will be lost. Do you wish to continue?")) == GTK_RESPONSE_NO)
                exit(1);
        }
     }
-    gtk_main();
+    while(state != -1) {
+       if(state == 0) {
+           gtk_window_set_default_size(GTK_WINDOW(cfw_wnd), 500, 350);
+           gtk_widget_show(cfw_wnd);
+           fillcfw();
+           rootwnd = GTK_WINDOW(cfw_wnd);
+           gtk_main();
+           gtk_widget_hide(cfw_wnd);
+           rootwnd = NULL;
+       } else if(state == 1) {
+           gtk_window_set_default_size(GTK_WINDOW(ast_wnd), 500, 350);
+           gtk_widget_show(ast_wnd);
+           rootwnd = GTK_WINDOW(ast_wnd);
+           gtk_main();
+           gtk_widget_hide(ast_wnd);
+           ignoreclose = 0;
+           rootwnd = NULL;
+       } else if(state == 2) {
+           for(i = 3; i < FD_SETSIZE; i++)
+               close(i);
+           execlp("dolcon", "dolcon", NULL);
+           perror("dolcon");
+           exit(127);
+       } else {
+           msgbox(GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, _("Internal error (Unknown state)"));
+           abort();
+       }
+    }
     return(0);
 }