121c1c48aSSascha Wildner /* 221c1c48aSSascha Wildner * Copyright (c)2004 Cat's Eye Technologies. All rights reserved. 321c1c48aSSascha Wildner * 421c1c48aSSascha Wildner * Redistribution and use in source and binary forms, with or without 521c1c48aSSascha Wildner * modification, are permitted provided that the following conditions 621c1c48aSSascha Wildner * are met: 721c1c48aSSascha Wildner * 821c1c48aSSascha Wildner * Redistributions of source code must retain the above copyright 921c1c48aSSascha Wildner * notice, this list of conditions and the following disclaimer. 1021c1c48aSSascha Wildner * 1121c1c48aSSascha Wildner * Redistributions in binary form must reproduce the above copyright 1221c1c48aSSascha Wildner * notice, this list of conditions and the following disclaimer in 1321c1c48aSSascha Wildner * the documentation and/or other materials provided with the 1421c1c48aSSascha Wildner * distribution. 1521c1c48aSSascha Wildner * 1621c1c48aSSascha Wildner * Neither the name of Cat's Eye Technologies nor the names of its 1721c1c48aSSascha Wildner * contributors may be used to endorse or promote products derived 1821c1c48aSSascha Wildner * from this software without specific prior written permission. 1921c1c48aSSascha Wildner * 2021c1c48aSSascha Wildner * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 2121c1c48aSSascha Wildner * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 2221c1c48aSSascha Wildner * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 2321c1c48aSSascha Wildner * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 2421c1c48aSSascha Wildner * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 2521c1c48aSSascha Wildner * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 2621c1c48aSSascha Wildner * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 2721c1c48aSSascha Wildner * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2821c1c48aSSascha Wildner * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 2921c1c48aSSascha Wildner * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 3021c1c48aSSascha Wildner * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 3121c1c48aSSascha Wildner * OF THE POSSIBILITY OF SUCH DAMAGE. 3221c1c48aSSascha Wildner */ 3321c1c48aSSascha Wildner 3421c1c48aSSascha Wildner /* 3521c1c48aSSascha Wildner * main.c 3621c1c48aSSascha Wildner * Main program for dfuife_curses. 3721c1c48aSSascha Wildner * $Id: main.c,v 1.21 2005/03/25 04:51:10 cpressey Exp $ 3821c1c48aSSascha Wildner */ 3921c1c48aSSascha Wildner 4021c1c48aSSascha Wildner #include <ctype.h> 4121c1c48aSSascha Wildner #include <ncurses.h> 4221c1c48aSSascha Wildner #include <signal.h> 4321c1c48aSSascha Wildner #include <stdlib.h> 4421c1c48aSSascha Wildner #include <string.h> 4521c1c48aSSascha Wildner #include <term.h> 4621c1c48aSSascha Wildner #include <unistd.h> 4721c1c48aSSascha Wildner 4821c1c48aSSascha Wildner #ifdef ENABLE_NLS 4921c1c48aSSascha Wildner #include <libintl.h> 5021c1c48aSSascha Wildner #include "libdfui/lang.h" 5121c1c48aSSascha Wildner #define _(String) gettext (String) 5221c1c48aSSascha Wildner extern int _nl_msg_cat_cntr; 5321c1c48aSSascha Wildner #else 5421c1c48aSSascha Wildner #define _(String) (String) 5521c1c48aSSascha Wildner #endif 5621c1c48aSSascha Wildner 5721c1c48aSSascha Wildner #include "libaura/mem.h" 5821c1c48aSSascha Wildner 5921c1c48aSSascha Wildner #include "libdfui/dfui.h" 6021c1c48aSSascha Wildner #ifdef DEBUG 6121c1c48aSSascha Wildner #include "libdfui/dump.h" 6221c1c48aSSascha Wildner #endif 6321c1c48aSSascha Wildner #include "libdfui/system.h" 6421c1c48aSSascha Wildner 6521c1c48aSSascha Wildner #include "curses_form.h" 6621c1c48aSSascha Wildner #include "curses_widget.h" 6721c1c48aSSascha Wildner #include "curses_bar.h" 6821c1c48aSSascha Wildner #include "curses_util.h" 6921c1c48aSSascha Wildner #include "curses_xlat.h" 7021c1c48aSSascha Wildner 7121c1c48aSSascha Wildner /*** GLOBALS ***/ 7221c1c48aSSascha Wildner 7321c1c48aSSascha Wildner struct curses_bar *menubar, *statusbar; 7421c1c48aSSascha Wildner 7521c1c48aSSascha Wildner /*** SIGNAL HANDLING ***/ 7621c1c48aSSascha Wildner 7721c1c48aSSascha Wildner #ifdef SIGNAL_HANDLING 7821c1c48aSSascha Wildner volatile sig_atomic_t caught_signal; 7921c1c48aSSascha Wildner 8021c1c48aSSascha Wildner void signal_handler(int signo) 8121c1c48aSSascha Wildner { 8221c1c48aSSascha Wildner caught_signal = signo; 8321c1c48aSSascha Wildner } 8421c1c48aSSascha Wildner 8521c1c48aSSascha Wildner void 8621c1c48aSSascha Wildner abort_frontend(struct dfui_connection *c) 8721c1c48aSSascha Wildner { 8821c1c48aSSascha Wildner dfui_fe_abort(c); 8921c1c48aSSascha Wildner 9021c1c48aSSascha Wildner clear(); 9121c1c48aSSascha Wildner refresh(); 9221c1c48aSSascha Wildner endwin(); 9321c1c48aSSascha Wildner exit(1); 9421c1c48aSSascha Wildner } 9521c1c48aSSascha Wildner #endif 9621c1c48aSSascha Wildner 9721c1c48aSSascha Wildner static struct dfui_response * 9821c1c48aSSascha Wildner #ifdef SIGNAL_HANDLING 9921c1c48aSSascha Wildner present_form(struct dfui_connection *c, struct dfui_form *f) 10021c1c48aSSascha Wildner #else 10121c1c48aSSascha Wildner present_form(struct dfui_connection *c __unused, struct dfui_form *f) 10221c1c48aSSascha Wildner #endif 10321c1c48aSSascha Wildner { 10421c1c48aSSascha Wildner struct dfui_response *r = NULL; 10521c1c48aSSascha Wildner struct curses_form *cf; 10621c1c48aSSascha Wildner struct curses_widget *cw; 10721c1c48aSSascha Wildner 10821c1c48aSSascha Wildner cf = curses_form_construct_from_dfui_form(f); 10921c1c48aSSascha Wildner curses_form_draw(cf); 11021c1c48aSSascha Wildner curses_form_refresh(cf); 11121c1c48aSSascha Wildner cw = curses_form_frob(cf); 11221c1c48aSSascha Wildner #ifdef SIGNAL_HANDLING 11321c1c48aSSascha Wildner if (caught_signal) abort_frontend(c); 11421c1c48aSSascha Wildner #endif 11521c1c48aSSascha Wildner r = response_construct_from_curses_form(f, cf, cw); 11621c1c48aSSascha Wildner curses_form_free(cf); 11721c1c48aSSascha Wildner curses_form_refresh(NULL); 11821c1c48aSSascha Wildner return(r); 11921c1c48aSSascha Wildner } 12021c1c48aSSascha Wildner 12121c1c48aSSascha Wildner static void 12221c1c48aSSascha Wildner usage(char **argv) 12321c1c48aSSascha Wildner { 12421c1c48aSSascha Wildner fprintf(stderr, _("Usage: %s " 125*8f8e1dafSSascha Wildner "[-b backdrop] [-r rendezvous] [-t npipe|tcp]\n"), 12621c1c48aSSascha Wildner argv[0]); 12721c1c48aSSascha Wildner exit(1); 12821c1c48aSSascha Wildner } 12921c1c48aSSascha Wildner 13021c1c48aSSascha Wildner /* 13121c1c48aSSascha Wildner * dfuife_curses 13221c1c48aSSascha Wildner * DFUI Curses frontend. 13321c1c48aSSascha Wildner */ 13421c1c48aSSascha Wildner int 13521c1c48aSSascha Wildner main(int argc, char **argv) 13621c1c48aSSascha Wildner { 13721c1c48aSSascha Wildner struct dfui_connection *c; 13821c1c48aSSascha Wildner struct dfui_form *f; 13921c1c48aSSascha Wildner struct dfui_response *r; 14021c1c48aSSascha Wildner struct dfui_progress *pr; 14121c1c48aSSascha Wildner struct dfui_property *gp; 14221c1c48aSSascha Wildner 14321c1c48aSSascha Wildner struct curses_form *pf = NULL; 14421c1c48aSSascha Wildner struct curses_widget *pbar = NULL, *plab = NULL, *pcan = NULL; 14521c1c48aSSascha Wildner struct curses_widget *w; 14621c1c48aSSascha Wildner 14721c1c48aSSascha Wildner void *payload; 14821c1c48aSSascha Wildner int done = 0; 14921c1c48aSSascha Wildner char msgtype; 15021c1c48aSSascha Wildner int opt; 15121c1c48aSSascha Wildner char last_message[80]; 15221c1c48aSSascha Wildner int is_streaming = 0; 15321c1c48aSSascha Wildner int ch; 15421c1c48aSSascha Wildner char *bdropfn = NULL; 15521c1c48aSSascha Wildner char *rendezvous = NULL; 15621c1c48aSSascha Wildner int transport = 0; 15721c1c48aSSascha Wildner int force_monochrome = 0; 15821c1c48aSSascha Wildner 15921c1c48aSSascha Wildner /* 16021c1c48aSSascha Wildner * Get command-line arguments. 16121c1c48aSSascha Wildner */ 16221c1c48aSSascha Wildner while ((opt = getopt(argc, argv, "b:mr:t:")) != -1) { 16321c1c48aSSascha Wildner switch(opt) { 16421c1c48aSSascha Wildner case 'b': 16521c1c48aSSascha Wildner bdropfn = aura_strdup(optarg); 16621c1c48aSSascha Wildner break; 16721c1c48aSSascha Wildner case 'm': 16821c1c48aSSascha Wildner force_monochrome = 1; 16921c1c48aSSascha Wildner break; 17021c1c48aSSascha Wildner case 'r': 17121c1c48aSSascha Wildner rendezvous = aura_strdup(optarg); 17221c1c48aSSascha Wildner break; 17321c1c48aSSascha Wildner case 't': 17421c1c48aSSascha Wildner transport = user_get_transport(optarg); 17521c1c48aSSascha Wildner break; 17621c1c48aSSascha Wildner case '?': 17721c1c48aSSascha Wildner default: 17821c1c48aSSascha Wildner usage(argv); 17921c1c48aSSascha Wildner } 18021c1c48aSSascha Wildner } 18121c1c48aSSascha Wildner argc -= optind; 18221c1c48aSSascha Wildner argv += optind; 18321c1c48aSSascha Wildner 18421c1c48aSSascha Wildner if (!transport) 18521c1c48aSSascha Wildner transport = user_get_transport("tcp"); 18621c1c48aSSascha Wildner 18721c1c48aSSascha Wildner if (rendezvous == NULL) { 18821c1c48aSSascha Wildner if (transport == DFUI_TRANSPORT_TCP) { 18921c1c48aSSascha Wildner rendezvous = aura_strdup("9999"); 19021c1c48aSSascha Wildner } else { 19121c1c48aSSascha Wildner rendezvous = aura_strdup("test"); 19221c1c48aSSascha Wildner } 19321c1c48aSSascha Wildner } 19421c1c48aSSascha Wildner 19521c1c48aSSascha Wildner #ifdef ENABLE_NLS 19621c1c48aSSascha Wildner setlocale (LC_ALL, ""); 19721c1c48aSSascha Wildner bindtextdomain (PACKAGE, LOCALEDIR); 19821c1c48aSSascha Wildner textdomain (PACKAGE); 19921c1c48aSSascha Wildner #endif 20021c1c48aSSascha Wildner 20121c1c48aSSascha Wildner /* 20221c1c48aSSascha Wildner * Set up screen. 20321c1c48aSSascha Wildner */ 20421c1c48aSSascha Wildner 20521c1c48aSSascha Wildner initscr(); 20621c1c48aSSascha Wildner 20721c1c48aSSascha Wildner #ifdef SIGNAL_HANDLING 20821c1c48aSSascha Wildner signal(SIGINT, signal_handler); 20921c1c48aSSascha Wildner signal(SIGTERM, signal_handler); 21021c1c48aSSascha Wildner #endif 21121c1c48aSSascha Wildner 21221c1c48aSSascha Wildner curses_colors_init(force_monochrome); 21321c1c48aSSascha Wildner cbreak(); 21421c1c48aSSascha Wildner noecho(); 21521c1c48aSSascha Wildner nonl(); 21621c1c48aSSascha Wildner keypad(stdscr, TRUE); 21721c1c48aSSascha Wildner curs_set(0); 21821c1c48aSSascha Wildner 21921c1c48aSSascha Wildner getmaxyx(stdscr, ymax, xmax); 22021c1c48aSSascha Wildner 22121c1c48aSSascha Wildner if (bdropfn == NULL) { 22221c1c48aSSascha Wildner curses_colors_set(stdscr, CURSES_COLORS_BACKDROP); 22321c1c48aSSascha Wildner curses_window_blank(stdscr); 22421c1c48aSSascha Wildner } else { 22521c1c48aSSascha Wildner curses_load_backdrop(stdscr, bdropfn); 22621c1c48aSSascha Wildner } 22721c1c48aSSascha Wildner 22821c1c48aSSascha Wildner menubar = curses_bar_new(0, 0, 0, 1, CURSES_COLORS_MENUBAR, 22921c1c48aSSascha Wildner CURSES_BAR_WIDEN); 23021c1c48aSSascha Wildner statusbar = curses_bar_new(0, 0, 0, 1, CURSES_COLORS_STATUSBAR, 23121c1c48aSSascha Wildner CURSES_BAR_WIDEN | CURSES_BAR_BOTTOM); 23221c1c48aSSascha Wildner 23321c1c48aSSascha Wildner curses_bar_set_text(menubar, _("F10=Refresh Display")); 23421c1c48aSSascha Wildner curses_bar_set_text(statusbar, _("Waiting for backend...")); 23521c1c48aSSascha Wildner 23621c1c48aSSascha Wildner update_panels(); 23721c1c48aSSascha Wildner doupdate(); 23821c1c48aSSascha Wildner 23921c1c48aSSascha Wildner #ifdef DEBUG 24021c1c48aSSascha Wildner dfui_debug_file = fopen("/tmp/dfuife_curses_debug.log", "w"); 24121c1c48aSSascha Wildner #endif 24221c1c48aSSascha Wildner 24321c1c48aSSascha Wildner c = dfui_connection_new(transport, rendezvous); 24421c1c48aSSascha Wildner dfui_fe_connect(c); 24521c1c48aSSascha Wildner 24621c1c48aSSascha Wildner curses_bar_set_text(statusbar, _("Connected")); 24721c1c48aSSascha Wildner 24821c1c48aSSascha Wildner while (!done) { 24921c1c48aSSascha Wildner dfui_fe_receive(c, &msgtype, &payload); 25021c1c48aSSascha Wildner switch (msgtype) { 25121c1c48aSSascha Wildner case DFUI_BE_MSG_PRESENT: 25221c1c48aSSascha Wildner f = (struct dfui_form *)payload; 25321c1c48aSSascha Wildner r = present_form(c, f); 25421c1c48aSSascha Wildner #ifdef SIGNAL_HANDLING 25521c1c48aSSascha Wildner if (caught_signal) abort_frontend(c); 25621c1c48aSSascha Wildner #endif 25721c1c48aSSascha Wildner dfui_fe_submit(c, r); 25821c1c48aSSascha Wildner dfui_form_free(f); 25921c1c48aSSascha Wildner dfui_response_free(r); 26021c1c48aSSascha Wildner break; 26121c1c48aSSascha Wildner case DFUI_BE_MSG_PROG_BEGIN: 26221c1c48aSSascha Wildner pr = (struct dfui_progress *)payload; 26321c1c48aSSascha Wildner if (pf != NULL) 26421c1c48aSSascha Wildner curses_form_free(pf); 26521c1c48aSSascha Wildner is_streaming = dfui_progress_get_streaming(pr); 26621c1c48aSSascha Wildner strncpy(last_message, dfui_info_get_short_desc( 26721c1c48aSSascha Wildner dfui_progress_get_info(pr)), 79); 26821c1c48aSSascha Wildner pf = curses_form_construct_from_dfui_progress(pr, 26921c1c48aSSascha Wildner &pbar, &plab, &pcan); 27021c1c48aSSascha Wildner curses_form_draw(pf); 27121c1c48aSSascha Wildner curses_form_refresh(pf); 27221c1c48aSSascha Wildner dfui_progress_free(pr); 27321c1c48aSSascha Wildner nodelay(stdscr, TRUE); 27421c1c48aSSascha Wildner dfui_fe_progress_continue(c); 27521c1c48aSSascha Wildner break; 27621c1c48aSSascha Wildner case DFUI_BE_MSG_PROG_UPDATE: 27721c1c48aSSascha Wildner pr = (struct dfui_progress *)payload; 27821c1c48aSSascha Wildner if (pf != NULL) { 27921c1c48aSSascha Wildner curses_widgets_update_from_dfui_progress(pr, 28021c1c48aSSascha Wildner pbar, plab, pcan); 28121c1c48aSSascha Wildner } 28221c1c48aSSascha Wildner dfui_progress_free(pr); 28321c1c48aSSascha Wildner ch = getch(); 28421c1c48aSSascha Wildner if (ch == ' ' || ch == '\n' || ch == '\r') { 28521c1c48aSSascha Wildner dfui_fe_progress_cancel(c); 28621c1c48aSSascha Wildner } else if (ch == KEY_F(10)) { 28721c1c48aSSascha Wildner redrawwin(stdscr); 28821c1c48aSSascha Wildner curses_form_refresh(NULL); 28921c1c48aSSascha Wildner dfui_fe_progress_continue(c); 29021c1c48aSSascha Wildner } else { 29121c1c48aSSascha Wildner dfui_fe_progress_continue(c); 29221c1c48aSSascha Wildner } 29321c1c48aSSascha Wildner break; 29421c1c48aSSascha Wildner case DFUI_BE_MSG_PROG_END: 29521c1c48aSSascha Wildner if (pf != NULL) { 29621c1c48aSSascha Wildner if (is_streaming) { 29721c1c48aSSascha Wildner w = curses_form_widget_add(pf, 0, pf->int_height, 0, 29821c1c48aSSascha Wildner CURSES_BUTTON, "OK", -1, 29921c1c48aSSascha Wildner CURSES_WIDGET_CENTER | CURSES_WIDGET_WIDEN); 30021c1c48aSSascha Wildner pf->int_height++; 30121c1c48aSSascha Wildner curses_widget_set_click_cb(w, cb_click_close_form); 30221c1c48aSSascha Wildner pf->widget_focus = w; 30321c1c48aSSascha Wildner curses_form_widget_ensure_visible(w); 30421c1c48aSSascha Wildner curses_widget_draw(w); 30521c1c48aSSascha Wildner curses_form_refresh(pf); 30621c1c48aSSascha Wildner curses_form_frob(pf); 30721c1c48aSSascha Wildner } 30821c1c48aSSascha Wildner curses_form_free(pf); 30921c1c48aSSascha Wildner curses_form_refresh(NULL); 31021c1c48aSSascha Wildner } 31121c1c48aSSascha Wildner pf = NULL; 31221c1c48aSSascha Wildner plab = pbar = pcan = NULL; 31321c1c48aSSascha Wildner nodelay(stdscr, FALSE); 31421c1c48aSSascha Wildner dfui_fe_progress_continue(c); 31521c1c48aSSascha Wildner break; 31621c1c48aSSascha Wildner case DFUI_BE_MSG_SET_GLOBAL: 31721c1c48aSSascha Wildner gp = (struct dfui_property *)payload; 31821c1c48aSSascha Wildner 31921c1c48aSSascha Wildner #ifdef ENABLE_NLS 32021c1c48aSSascha Wildner /* 32121c1c48aSSascha Wildner * Check for a change to the "lang" setting... 32221c1c48aSSascha Wildner */ 32321c1c48aSSascha Wildner if (strcmp(dfui_property_get_name(gp), "lang") == 0) { 32421c1c48aSSascha Wildner set_lang_envars(dfui_property_get_value(gp)); 32521c1c48aSSascha Wildner 32621c1c48aSSascha Wildner /* let gettext know about changes */ 32721c1c48aSSascha Wildner ++_nl_msg_cat_cntr; 32821c1c48aSSascha Wildner 32921c1c48aSSascha Wildner /* BEGIN: reinit curses to use new TERM */ 33021c1c48aSSascha Wildner curses_bar_free(menubar); 33121c1c48aSSascha Wildner curses_bar_free(statusbar); 33221c1c48aSSascha Wildner 33321c1c48aSSascha Wildner endwin(); 33421c1c48aSSascha Wildner newterm(getenv("TERM"), stdout, stdin); 33521c1c48aSSascha Wildner 33621c1c48aSSascha Wildner curses_colors_init(force_monochrome); 33721c1c48aSSascha Wildner cbreak(); 33821c1c48aSSascha Wildner noecho(); 33921c1c48aSSascha Wildner nonl(); 34021c1c48aSSascha Wildner keypad(stdscr, TRUE); 34121c1c48aSSascha Wildner curs_set(0); 34221c1c48aSSascha Wildner 34321c1c48aSSascha Wildner update_panels(); 34421c1c48aSSascha Wildner doupdate(); 34521c1c48aSSascha Wildner 34621c1c48aSSascha Wildner if (bdropfn == NULL) { 34721c1c48aSSascha Wildner curses_colors_set(stdscr, 34821c1c48aSSascha Wildner CURSES_COLORS_BACKDROP); 34921c1c48aSSascha Wildner curses_window_blank(stdscr); 35021c1c48aSSascha Wildner } else { 35121c1c48aSSascha Wildner curses_load_backdrop(stdscr, bdropfn); 35221c1c48aSSascha Wildner } 35321c1c48aSSascha Wildner 35421c1c48aSSascha Wildner menubar = curses_bar_new(0, 0, 0, 1, 35521c1c48aSSascha Wildner CURSES_COLORS_MENUBAR, CURSES_BAR_WIDEN); 35621c1c48aSSascha Wildner statusbar = curses_bar_new(0, 0, 0, 1, 35721c1c48aSSascha Wildner CURSES_COLORS_STATUSBAR, 35821c1c48aSSascha Wildner CURSES_BAR_WIDEN | CURSES_BAR_BOTTOM); 35921c1c48aSSascha Wildner /* END: reinit curses to use new TERM */ 36021c1c48aSSascha Wildner 36121c1c48aSSascha Wildner curses_bar_set_text(menubar, 36221c1c48aSSascha Wildner _("F1=Help F10=Refresh Display")); 36321c1c48aSSascha Wildner } 36421c1c48aSSascha Wildner #endif 36521c1c48aSSascha Wildner 36621c1c48aSSascha Wildner dfui_fe_confirm_set_global(c); 36721c1c48aSSascha Wildner dfui_property_free(gp); 36821c1c48aSSascha Wildner break; 36921c1c48aSSascha Wildner case DFUI_BE_MSG_STOP: 37021c1c48aSSascha Wildner dfui_fe_confirm_stop(c); 37121c1c48aSSascha Wildner done = 1; 37221c1c48aSSascha Wildner break; 37321c1c48aSSascha Wildner } 37421c1c48aSSascha Wildner } 37521c1c48aSSascha Wildner 37621c1c48aSSascha Wildner dfui_fe_disconnect(c); 37721c1c48aSSascha Wildner 37821c1c48aSSascha Wildner #ifdef DEBUG 37921c1c48aSSascha Wildner fclose(dfui_debug_file); 38021c1c48aSSascha Wildner #endif 38121c1c48aSSascha Wildner 38221c1c48aSSascha Wildner curses_bar_free(menubar); 38321c1c48aSSascha Wildner curses_bar_free(statusbar); 38421c1c48aSSascha Wildner 38521c1c48aSSascha Wildner clear(); 38621c1c48aSSascha Wildner refresh(); 38721c1c48aSSascha Wildner endwin(); 38821c1c48aSSascha Wildner 38921c1c48aSSascha Wildner if (rendezvous != NULL) 39021c1c48aSSascha Wildner free(rendezvous); 39121c1c48aSSascha Wildner if (bdropfn != NULL) 39221c1c48aSSascha Wildner free(bdropfn); 39321c1c48aSSascha Wildner 39421c1c48aSSascha Wildner exit(0); 39521c1c48aSSascha Wildner } 396