diff options
author | Sébastien Helleu <flashcode@flashtux.org> | 2018-03-11 09:59:39 +0100 |
---|---|---|
committer | Sébastien Helleu <flashcode@flashtux.org> | 2018-03-11 09:59:39 +0100 |
commit | 805717e9ec3f66c960928bca607eceb871438fae (patch) | |
tree | c1832f0815bd8ade4530ed3948f55f0672103184 /src/gui/curses/headless | |
parent | 0126b03f47db7f7842aff497cdbb0e41a0a5be0a (diff) | |
download | weechat-805717e9ec3f66c960928bca607eceb871438fae.zip |
core: add binary weechat-headless to run WeeChat without interface (closes #1120)
The optional command line option "--daemon" runs WeeChat like a daemon
(fork, new process group, file descriptors closed).
Diffstat (limited to 'src/gui/curses/headless')
-rw-r--r-- | src/gui/curses/headless/CMakeLists.txt | 57 | ||||
-rw-r--r-- | src/gui/curses/headless/Makefile.am | 55 | ||||
-rw-r--r-- | src/gui/curses/headless/main.c | 125 | ||||
-rw-r--r-- | src/gui/curses/headless/ncurses-fake.c | 433 | ||||
-rw-r--r-- | src/gui/curses/headless/ncurses-fake.h | 126 |
5 files changed, 796 insertions, 0 deletions
diff --git a/src/gui/curses/headless/CMakeLists.txt b/src/gui/curses/headless/CMakeLists.txt new file mode 100644 index 000000000..3aa6b4448 --- /dev/null +++ b/src/gui/curses/headless/CMakeLists.txt @@ -0,0 +1,57 @@ +# +# Copyright (C) 2003-2018 Sébastien Helleu <flashcode@flashtux.org> +# +# This file is part of WeeChat, the extensible chat client. +# +# WeeChat is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# WeeChat is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with WeeChat. If not, see <http://www.gnu.org/licenses/>. +# + +add_definitions(-DWEECHAT_HEADLESS) + +# fake ncurses lib (for headless mode and tests) +set(LIB_WEECHAT_NCURSES_FAKE_SRC + ncurses-fake.h + ncurses-fake.c +) +add_library(weechat_ncurses_fake STATIC ${LIB_WEECHAT_NCURSES_FAKE_SRC}) + +set(LIB_GUI_CURSES_SRC + ../gui-curses.h + ../gui-curses-bar-window.c + ../gui-curses-chat.c + ../gui-curses-color.c + ../gui-curses-key.c + ../gui-curses-main.c + ../gui-curses-mouse.c + ../gui-curses-term.c + ../gui-curses-window.c +) + +include_directories(. .. ../../core ../../plugins) + +add_library(weechat_gui_headless STATIC ${LIB_GUI_CURSES_SRC}) + +set(WEECHAT_CURSES_MAIN_HEADLESS_SRC main.c) + +set(EXECUTABLE weechat-headless) + +add_executable(${EXECUTABLE} ${WEECHAT_CURSES_MAIN_HEADLESS_SRC}) + +add_dependencies(${EXECUTABLE} weechat_gui_headless weechat_ncurses_fake) + +# Due to circular references, we must link two times with libweechat_core.a and libweechat_gui_common.a +target_link_libraries(${EXECUTABLE} ${STATIC_LIBS} weechat_gui_headless weechat_ncurses_fake ${EXTRA_LIBS} ${STATIC_LIBS}) + +# Install executable +install(TARGETS ${EXECUTABLE} RUNTIME DESTINATION bin) diff --git a/src/gui/curses/headless/Makefile.am b/src/gui/curses/headless/Makefile.am new file mode 100644 index 000000000..08c2d164e --- /dev/null +++ b/src/gui/curses/headless/Makefile.am @@ -0,0 +1,55 @@ +# +# Copyright (C) 2003-2018 Sébastien Helleu <flashcode@flashtux.org> +# +# This file is part of WeeChat, the extensible chat client. +# +# WeeChat is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# WeeChat is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with WeeChat. If not, see <http://www.gnu.org/licenses/>. +# + +AM_CPPFLAGS = -DLOCALEDIR=\"$(datadir)/locale\" -DWEECHAT_HEADLESS + +noinst_LIBRARIES = lib_weechat_ncurses_fake.a lib_weechat_gui_headless.a + +lib_weechat_ncurses_fake_a_SOURCES = ncurses-fake.c \ + ncurses-fake.h + +lib_weechat_gui_headless_a_SOURCES = ../gui-curses-bar-window.c \ + ../gui-curses-chat.c \ + ../gui-curses-color.c \ + ../gui-curses-key.c \ + ../gui-curses-main.c \ + ../gui-curses-mouse.c \ + ../gui-curses-term.c \ + ../gui-curses-window.c \ + ../gui-curses.h + +bin_PROGRAMS = weechat-headless + +# Due to circular references, we must link two times with libweechat_core.a +# (and with two different path/names to be kept by linker) +weechat_headless_LDADD = ./../../../core/lib_weechat_core.a \ + ../../../plugins/lib_weechat_plugins.a \ + ../../lib_weechat_gui_common.a \ + lib_weechat_gui_headless.a \ + lib_weechat_ncurses_fake.a \ + ../../../core/lib_weechat_core.a \ + $(PLUGINS_LFLAGS) \ + $(GCRYPT_LFLAGS) \ + $(GNUTLS_LFLAGS) \ + $(CURL_LFLAGS) \ + -lm + +weechat_headless_SOURCES = main.c + +EXTRA_DIST = CMakeLists.txt diff --git a/src/gui/curses/headless/main.c b/src/gui/curses/headless/main.c new file mode 100644 index 000000000..481177020 --- /dev/null +++ b/src/gui/curses/headless/main.c @@ -0,0 +1,125 @@ +/* + * main.c - entry point for headless mode (no GUI) + * + * Copyright (C) 2003-2018 Sébastien Helleu <flashcode@flashtux.org> + * + * This file is part of WeeChat, the extensible chat client. + * + * WeeChat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * WeeChat is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with WeeChat. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <stdlib.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <unistd.h> +#include <stdio.h> +#include <string.h> + +#include "../../../core/weechat.h" +#include "../../gui-main.h" +#include "../gui-curses.h" + + +/* + * Daemonizes the process. + */ + +void +daemonize () +{ + pid_t pid; + int fd, i; + + printf (_("Running WeeChat in background...")); + printf (" "); + + pid = fork(); + + if (pid < 0) + { + printf (_("fork error")); + printf ("\n"); + exit (EXIT_FAILURE); + } + + if (pid > 0) + { + /* parent process */ + printf (_("OK")); + printf ("\n"); + exit (EXIT_SUCCESS); + } + + /* child process */ + + /* obtain a new process group */ + setsid (); + + /* close all file descriptors */ + for (i = getdtablesize(); i >= 0; --i) + { + close (i); + } + fd = open ("/dev/null", O_RDWR); + dup (fd); + dup (fd); +} + +/* + * Entry point for WeeChat in headless mode (no GUI). + */ + +int +main (int argc, char *argv[]) +{ + int i, daemon; + + weechat_init_gettext (); + + /* + * Enable a special "headless" mode, where some things are slightly + * different, for example: + * - no read of stdin (keyboard/mouse) + * - don't catch any terminal related signal + */ + weechat_headless = 1; + + /* + * If "--daemon" is received in command line arguments, + * daemonize the process. + */ + daemon = 0; + for (i = 1; i < argc; i++) + { + if (strcmp (argv[i], "--daemon") == 0) + { + daemon = 1; + break; + } + } + if (daemon) + daemonize (); + + /* init, main loop and end */ + weechat_init (argc, argv, &gui_main_init); + gui_main_loop (); + weechat_end (&gui_main_end); + + return EXIT_SUCCESS; +} diff --git a/src/gui/curses/headless/ncurses-fake.c b/src/gui/curses/headless/ncurses-fake.c new file mode 100644 index 000000000..da1e4ac8d --- /dev/null +++ b/src/gui/curses/headless/ncurses-fake.c @@ -0,0 +1,433 @@ +/* + * ncurses-fake.c - fake ncurses lib (for headless mode and tests) + * + * Copyright (C) 2014-2018 Sébastien Helleu <flashcode@flashtux.org> + * + * This file is part of WeeChat, the extensible chat client. + * + * WeeChat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * WeeChat is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with WeeChat. If not, see <http://www.gnu.org/licenses/>. + */ + +#include "ncurses-fake.h" + + +/* simulate 80x25 terminal */ +WINDOW _stdscr = { 0, 0, 24, 79, 0, 0 }; +WINDOW *stdscr = &_stdscr; +chtype acs_map[256]; + + +WINDOW * +initscr () +{ + return stdscr; +} + +int +endwin () +{ + return OK; +} + +WINDOW * +newwin (int nlines, int ncols, int begin_y, int begin_x) +{ + (void) nlines; + (void) ncols; + (void) begin_y; + (void) begin_x; + + return stdscr; +} + +int +delwin (WINDOW *win) +{ + (void) win; + + return OK; +} + +int +move (int y, int x) +{ + (void) y; + (void) x; + + return OK; +} + +int +wmove (WINDOW *win, int y, int x) +{ + (void) win; + (void) y; + (void) x; + + return OK; +} + +int +wattr_on (WINDOW *win, attr_t attrs, void *opts) +{ + (void) win; + (void) attrs; + (void) opts; + + return OK; +} + +int +wattr_off (WINDOW *win, attr_t attrs, void *opts) +{ + (void) win; + (void) attrs; + (void) opts; + + return OK; +} + +int +wattr_get (WINDOW *win, attr_t *attrs, short *pair, void *opts) +{ + (void) win; + (void) attrs; + (void) pair; + (void) opts; + + return OK; +} + +int +wattr_set (WINDOW *win, attr_t attrs, short pair, void *opts) +{ + (void) win; + (void) attrs; + (void) pair; + (void) opts; + + return OK; +} + +int +wattron (WINDOW *win, int attrs) +{ + (void) win; + (void) attrs; + + return OK; +} + +int +wattroff (WINDOW *win, int attrs) +{ + (void) win; + (void) attrs; + + return OK; +} + +int +waddstr (WINDOW *win, const char *str) +{ + (void) win; + (void) str; + + return OK; +} + +int +waddnstr (WINDOW *win, const char *str, int n) +{ + (void) win; + (void) str; + (void) n; + + return OK; +} + +int +mvaddstr (int y, int x, const char *str) +{ + (void) y; + (void) x; + (void) str; + + return OK; +} + +int +mvwaddstr (WINDOW *win, int y, int x, const char *str) +{ + (void) win; + (void) y; + (void) x; + (void) str; + + return OK; +} + +int +wclrtobot (WINDOW *win) +{ + (void) win; + + return OK; +} + +int +refresh () +{ + return OK; +} + +int +wrefresh (WINDOW *win) +{ + (void) win; + + return OK; +} + +int +wnoutrefresh (WINDOW *win) +{ + (void) win; + + return OK; +} + +int +wclrtoeol (WINDOW *win) +{ + (void) win; + + return OK; +} + +int +mvwprintw (WINDOW *win, int y, int x, const char *fmt, ...) +{ + (void) win; + (void) y; + (void) x; + (void) fmt; + + return OK; +} + +int +init_pair (short pair, short f, short b) +{ + (void) pair; + (void) f; + (void) b; + + return OK; +} + +bool +has_colors () +{ + return TRUE; +} + +int +cbreak () +{ + return OK; +} + +int +start_color () +{ + return OK; +} + +int +noecho () +{ + return OK; +} + +int +clear () +{ + return OK; +} + +int +wclear (WINDOW *win) +{ + (void) win; + + return OK; +} + +bool +can_change_color () +{ + /* not supported in WeeChat anyway */ + return FALSE; +} + +int +curs_set (int visibility) +{ + (void) visibility; + + return 1; /* 0 == invisible, 1 == normal, 2 == very visible */ +} + +int +nodelay (WINDOW *win, bool bf) +{ + (void) win; + (void) bf; + + return OK; +} + +int +werase (WINDOW *win) +{ + (void) win; + + return OK; +} + +int +wbkgdset (WINDOW *win, chtype ch) +{ + (void) win; + (void) ch; + + return OK; +} + +void +wchgat (WINDOW *win, int n, attr_t attr, short color, const void *opts) +{ + (void) win; + (void) n; + (void) attr; + (void) color; + (void) opts; +} + +int +mvwchgat (WINDOW *win, int y, int x, int n, attr_t attr, short pair, + const void *opts) +{ + (void) win; + (void) y; + (void) x; + (void) n; + (void) attr; + (void) pair; + (void) opts; + + return OK; +} + + +void +whline (WINDOW *win, chtype ch, int n) +{ + (void) win; + (void) ch; + (void) n; +} + +void +wvline (WINDOW *win, chtype ch, int n) +{ + (void) win; + (void) ch; + (void) n; +} + +int +mvwhline (WINDOW *win, int y, int x, chtype ch, int n) +{ + (void) win; + (void) y; + (void) x; + (void) ch; + (void) n; + + return OK; +} + +int +mvwvline (WINDOW *win, int y, int x, chtype ch, int n) +{ + (void) win; + (void) y; + (void) x; + (void) ch; + (void) n; + + return OK; +} + +int +raw () +{ + return OK; +} + +int +wcolor_set (WINDOW *win, short pair, void *opts) +{ + (void) win; + (void) pair; + (void) opts; + + return OK; +} + +void +cur_term () +{ +} + +int +use_default_colors () +{ + return OK; +} + +int +resizeterm (int lines, int columns) +{ + (void) lines; + (void) columns; + + return OK; +} + +int +getch () +{ + return ERR; +} + +int +wgetch (WINDOW *win) +{ + (void) win; + + return OK; +} diff --git a/src/gui/curses/headless/ncurses-fake.h b/src/gui/curses/headless/ncurses-fake.h new file mode 100644 index 000000000..79ce6fc25 --- /dev/null +++ b/src/gui/curses/headless/ncurses-fake.h @@ -0,0 +1,126 @@ +/* + * Copyright (C) 2014-2018 Sébastien Helleu <flashcode@flashtux.org> + * + * This file is part of WeeChat, the extensible chat client. + * + * WeeChat is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * WeeChat is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with WeeChat. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef WEECHAT_NCURSES_FAKE_H +#define WEECHAT_NCURSES_FAKE_H + +#define ERR (-1) +#define OK (0) + +#define TRUE 1 +#define FALSE 0 + +#define COLS 80 +#define LINES 25 +#define COLORS 256 +#define COLOR_PAIRS 256 + +#define COLOR_PAIR(x) x + +#define COLOR_BLACK 0 +#define COLOR_RED 1 +#define COLOR_GREEN 2 +#define COLOR_YELLOW 3 +#define COLOR_BLUE 4 +#define COLOR_MAGENTA 5 +#define COLOR_CYAN 6 +#define COLOR_WHITE 7 + +#define A_BOLD 0 +#define A_UNDERLINE 0 +#define A_REVERSE 0 +#define A_ITALIC 0 + +#define ACS_HLINE '-' +#define ACS_VLINE '|' + +#define getyx(win, x, y) \ + x = 0; \ + y = 0; + +#define getmaxyx(win, x, y) \ + x = 0; \ + y = 0; + +struct _window +{ + int _cury, _curx; + int _maxy, _maxx; + int _begy, _begx; +}; +typedef struct _window WINDOW; + +typedef unsigned char bool; +typedef int attr_t; +typedef unsigned chtype; + +extern WINDOW *stdscr; +extern chtype acs_map[]; + +extern WINDOW *initscr (); +extern int endwin (); +extern WINDOW *newwin (int nlines, int ncols, int begin_y, int begin_x); +extern int delwin (WINDOW *win); +extern int move (int y, int x); +extern int wmove (WINDOW *win, int y, int x); +extern int wattr_on (WINDOW *win, attr_t attrs, void *opts); +extern int wattr_off (WINDOW *win, attr_t attrs, void *opts); +extern int wattr_get (WINDOW *win, attr_t *attrs, short *pair, void *opts); +extern int wattr_set (WINDOW *win, attr_t attrs, short pair, void *opts); +extern int wattron (WINDOW *win, int attrs); +extern int wattroff (WINDOW *win, int attrs); +extern int waddstr (WINDOW *win, const char *str); +extern int waddnstr (WINDOW *win, const char *str, int n); +extern int mvaddstr (int y, int x, const char *str); +extern int mvwaddstr (WINDOW *win, int y, int x, const char *str); +extern int wclrtobot (WINDOW *win); +extern int refresh (); +extern int wrefresh (WINDOW *win); +extern int wnoutrefresh (WINDOW *win); +extern int wclrtoeol (WINDOW *win); +extern int mvwprintw (WINDOW *win, int y, int x, const char *fmt, ...); +extern int init_pair (short pair, short f, short b); +extern bool has_colors (); +extern int cbreak (); +extern int start_color (); +extern int noecho (); +extern int clear (); +extern int wclear (WINDOW *win); +extern bool can_change_color (); +extern int curs_set (int visibility); +extern int nodelay (WINDOW *win, bool bf); +extern int werase (WINDOW *win); +extern int wbkgdset (WINDOW *win, chtype ch); +extern void wchgat (WINDOW *win, int n, attr_t attr, short color, + const void *opts); +extern int mvwchgat (WINDOW *win, int y, int x, int n, attr_t attr, short pair, + const void *opts); +extern void whline (WINDOW *win, chtype ch, int n); +extern void wvline (WINDOW *win, chtype ch, int n); +extern int mvwhline (WINDOW *win, int y, int x, chtype ch, int n); +extern int mvwvline (WINDOW *win, int y, int x, chtype ch, int n); +extern int raw (); +extern int wcolor_set (WINDOW *win, short pair, void *opts); +extern void cur_term (); +extern int use_default_colors (); +extern int resizeterm (); +extern int getch (); +extern int wgetch (WINDOW *win); + +#endif /* WEECHAT_NCURSES_FAKE_H */ |