Beispiel #1
0
int
console_init()
{
	int fd;

	/* Clean up */
	ioctl(0, TIOCNOTTY, 0);
	close(0);
	close(1);
	close(2);
	setsid();

	/* Reopen console */
	if ((fd = open(_PATH_CONSOLE, O_RDWR)) < 0) {
		perror(_PATH_CONSOLE);
		return errno;
	}
	dup2(fd, 0);
	dup2(fd, 1);
	dup2(fd, 2);

	ioctl(0, TIOCSCTTY, 1);
	tcsetpgrp(0, getpgrp());
	set_term(0);

	return 0;
}
Beispiel #2
0
SCREEN *_terminfo_new_screen(const char *term_type, FILE *out, FILE *in)
{
	SCREEN *_newscr;
	ggLock(ncurses_lock);
        if ( term_type == NULL ) {
                term_type = getenv("TERM");
                if ( term_type == NULL ) {
                        term_type = "vt100";
                }
        }
	{ char *temp;
		temp = (char *)malloc(sizeof(char) * ( strlen(term_type) + 1 ));
		strcpy(temp, term_type);
		_newscr = newterm(temp, out, in);
		free(temp);
	}
	if ( _newscr == NULL ) {
		ggUnlock(ncurses_lock);
	} else {
		ncurses_screen = _newscr;
		set_term(_newscr);
		start_color();
		cbreak();
		noecho();
		nonl();
		timeout(0);
		meta(stdscr, TRUE);
		keypad(stdscr, TRUE);
	}
	return _newscr;
}
Beispiel #3
0
static void
cleanup(int sig)
{
    /*
     * Actually, doing any sort of I/O from within an signal handler is
     * "unsafe".  But we'll _try_ to clean up the screen and terminal
     * settings on the way out.
     */
    if (!_nc_globals.cleanup_nested++
	&& (sig == SIGINT
	    || sig == SIGQUIT)) {
#if HAVE_SIGACTION || HAVE_SIGVEC
	sigaction_t act;
	sigemptyset(&act.sa_mask);
	act.sa_flags = 0;
	act.sa_handler = SIG_IGN;
	if (sigaction(sig, &act, NULL) == 0)
#else
	if (signal(sig, SIG_IGN) != SIG_ERR)
#endif
	{
	    SCREEN *scan;
	    for (each_screen(scan)) {
		if (scan->_ofp != 0
		    && isatty(fileno(scan->_ofp))) {
		    scan->_cleanup = TRUE;
		    scan->_outch = _nc_outch;
		}
		set_term(scan);
		endwin();
		if (SP)
		    SP->_endwin = FALSE;	/* in case we have an atexit! */
	    }
	}
Beispiel #4
0
/* Add the IN->OUT mapping to TBL.  OUT is potentially stored in the table.
   IN is used only here, so it need not be kept live afterwards.  */
static void
add_bytes (struct convtable *tbl, const struct charseq *in, struct charseq *out)
{
  int n = 0;
  unsigned int byte;

  assert (in->nbytes > 0);

  byte = ((unsigned char *) in->bytes)[n];
  while (n + 1 < in->nbytes)
    {
      if (is_term (tbl, byte) || tbl->val[byte].sub == NULL)
	{
	  /* Note that we simply ignore a definition for a byte sequence
	     which is also the prefix for a longer one.  */
	  clear_term (tbl, byte);
	  tbl->val[byte].sub =
	    (struct convtable *) xcalloc (1, sizeof (struct convtable));
	}

      tbl = tbl->val[byte].sub;

      byte = ((unsigned char *) in->bytes)[++n];
    }

  /* Only add the new sequence if there is none yet and the byte sequence
     is not part of an even longer one.  */
  if (! is_term (tbl, byte) && tbl->val[byte].sub == NULL)
    {
      set_term (tbl, byte);
      tbl->val[byte].out = out;
    }
}
Beispiel #5
0
/** \brief Show help file
 *
 * Read 'help.txt' and display it via 'less'.
 * Local 'help.txt' in actual directory overrides default file
 * in PKG_DATA_DIR
 */
int show_help(void) {
    int rc;
    char filename[] = "help.txt";
    char *helpfile;
    char *cmdstr;

    if (g_access(filename, R_OK) == 0) {
	helpfile = g_strdup(filename);
    } else {
	helpfile = g_strconcat(PACKAGE_DATA_DIR, G_DIR_SEPARATOR_S,
		filename, NULL);
	if (g_access(helpfile, R_OK) != 0) {
	    g_free(helpfile);
	    return -1;
	}
    }

    cmdstr = g_strdup_printf("less %s", helpfile);

    endwin();
    rc=system("clear");
    rc=system(cmdstr);
    rc=system("clear");

    g_free(helpfile);
    g_free(cmdstr);

    set_term(mainscreen);
    clear_display();
    return 0;
}
Beispiel #6
0
static int console_init(void)
{
	int fd;

	/* Clean up */
	ioctl(0, TIOCNOTTY, 0);
	close(0);
	close(1);
	close(2);
	setsid();

	/* Reopen console */
	if ((fd = open(_PATH_CONSOLE, O_RDWR)) < 0) {
		/* Avoid debug messages is redirected to socket packet if no exist a UART chip, added by honor, 2003-12-04 */
		open("/dev/null", O_RDONLY);
		open("/dev/null", O_WRONLY);
		open("/dev/null", O_WRONLY);
		perror(_PATH_CONSOLE);
		return errno;
	}
	dup2(fd, 0);
	dup2(fd, 1);
	dup2(fd, 2);

	ioctl(0, TIOCSCTTY, 1);
	tcsetpgrp(0, getpgrp());
	set_term(0);

	return 0;
}
Beispiel #7
0
void split_open(void)
{
  int i;
#if DEBUG
  printf("split_open()\n");
#endif
  LineCount = -1;
  for (i=0; i<MAX_LINE_COUNT; i++) {
    strcpy(Lines[i], "");
  }
#ifndef NO_CURSES
  FILE *stdout2 = fopen("/dev/tty", "w");
  if (!stdout2)
    fprintf(stderr, "split_open(): fopen() failed\n");
  else {
    SCREEN *screen;
    if ((screen = newterm(NULL, stdout2, stdin))) {
      set_term(screen);
      raw();
      noecho();
    } else
      fprintf(stderr, "split_open(): newterm() failed\n");
  }
#endif
}
Beispiel #8
0
static void cleanup(int sig)
{
	/*
	 * Actually, doing any sort of I/O from within an signal handler is
	 * "unsafe".  But we'll _try_ to clean up the screen and terminal
	 * settings on the way out.
	 */
	if (sig == SIGINT
	 || sig == SIGQUIT) {
#if HAVE_SIGACTION || HAVE_SIGVEC
		sigaction_t act;
		sigemptyset(&act.sa_mask);
		act.sa_flags = 0;
		act.sa_handler = SIG_IGN;
		if (sigaction(sig, &act, (sigaction_t *)0) == 0)
#else
		if (signal(sig, SIG_IGN) != SIG_ERR)
#endif
		{
		    SCREEN *scan = _nc_screen_chain;
		    while(scan)
		    {
			set_term(scan);
			endwin();
			SP->_endwin = FALSE; /* in case we have an atexit! */
			scan = scan->_next_screen;
		    }
		}
	}
	exit(EXIT_FAILURE);
}
Beispiel #9
0
/*
 * initscr --
 *	Initialize the current and standard screen.
 */
WINDOW *
initscr(void)
{
	const char *sp;

	/*
	 * If My_term is set, or can't find a terminal in the environment,
	 * use Def_term.
	 */
	if (My_term || (sp = getenv("TERM")) == NULL)
		sp = Def_term;

	/* LINTED const castaway; newterm does not modify sp! */
	if ((_cursesi_screen = newterm((char *) sp, stdout, stdin)) == NULL)
		return NULL;

	__echoit = _cursesi_screen->echoit;
        __pfast = _cursesi_screen->pfast;
	__rawmode = _cursesi_screen->rawmode;
	__noqch = _cursesi_screen->noqch;
	COLS = _cursesi_screen->COLS;
	LINES = _cursesi_screen->LINES;
	COLORS = _cursesi_screen->COLORS;
	COLOR_PAIRS = _cursesi_screen->COLOR_PAIRS;
	__GT = _cursesi_screen->GT;
	__NONL = _cursesi_screen->NONL;
	__UPPERCASE = _cursesi_screen->UPPERCASE;

	set_term(_cursesi_screen);
	wrefresh(curscr);

	return (stdscr);
}
Beispiel #10
0
/*
 * Allocates and initializes a new Screen.
 */
Screen *ScreenInit(Model *model)
{
	const char *tty = "/dev/tty";
	const char *term_type = 0;

	Screen *self = pg_malloc(sizeof(Screen));
	memset(self, 0, sizeof(Screen));

	self->model = model;
	memset(&self->key, 0, sizeof(Row));

	/*
	 * Open /dev/tty and set that up as the ncurses terminal. We use newterm
	 * instead of initscr so that we can read row events from stdin.
	 */

	term_type = getenv("TERM");

	if (term_type == NULL || *term_type == '\0') {
		term_type = "unknown";
	}

	self->term_in = fopen(tty, "r");

	if (self->term_in == NULL) {
		FATAL_ERROR("could not open %s", tty);
	}

	self->fd = fileno(self->term_in);
	self->nterm = newterm(term_type, stdout, self->term_in);
	set_term(self->nterm);

	/* make ncurses non blocking */
	timeout(0);

	/* clear the tty internal state */
	clear();

	/* disable character echo */
	noecho();

	/* disable input line buffering */
	cbreak();

	/* hide cursor */
	curs_set(0);

	/* enable extra keys */
	keypad(stdscr, TRUE);

	/* updates the screen (should be blank now) */
	refresh();

	self->x_pos = 0;
	self->x_col = 0;
	self->pause = 0;

	return self;
}
Beispiel #11
0
void _terminfo_select_screen(SCREEN *scr)
{
	ggLock(ncurses_lock);
	if ( ncurses_screen != scr ) {
		set_term(scr);
		ncurses_screen = scr;
	}
}
Beispiel #12
0
void		handle_sigcont(int sig)
{
	if (sig == SIGCONT)
		ft_init();
	else
	{
		set_term(ft_glob(NULL)->sauv);
		signal(SIGTSTP, SIG_DFL);
	}
}
Beispiel #13
0
static PyObject* py_set_term(PyObject *self, PyObject *args){
  SCREEN *screen;
  if (!PyArg_ParseTuple(args, "l", &screen))
    return NULL;

  Py_BEGIN_ALLOW_THREADS
  screen = set_term(screen);
  Py_END_ALLOW_THREADS

  return PyLong_FromVoidPtr(screen);
}
Beispiel #14
0
static void setup_ncurses() {
    SCREEN* main_screen = newterm(term_type, stdout, term_in);
    set_term(main_screen);
    scrollok(stdscr, TRUE);  // If enabled the window is scrolled up one line when reaching bottom
    idlok(stdscr, TRUE);     // Use the hardware insert/delete line feature of terminals so equipped
    ncurses_active = TRUE;
    //printf("\t\t\t\t\tncurses set up.\n");
    if (signal(SIGWINCH, catch_sigwinch) == SIG_ERR) {
        fputs("\t\t\t\t\tAn error occurred when setting up SIGWINCH signal handler.\n", stderr);
    }
}    // Done setting up ncurses
Beispiel #15
0
struct data_t *handle_request_vote(struct data_t *params[], int nparams, char **err, void *data) {
    struct server_context_t *s = (struct server_context_t *)data;
    struct request_vote_input_t *input = get_request_vote_input_params(params, nparams);
    if(!input) {
        *err = u_strdup("error while parsing input parameters");
        log_fatal_and_exit(s, 
            "RequestVote: error while parsing input parameters");
        return NULL;
    }

    struct request_vote_output_t output;
    if(input->term < s->current_term) {
        //candidate has older term hence reject request`
        output.term = s->current_term;
        output.vote_granted = 0;
    } else {
        if(s->last_entry &&
            (input->last_log_term < s->last_entry->term
                || (input->last_log_term == s->last_entry->term &&
                    input->last_log_index < s->last_entry->index))) {
            //candidate log is not up-to-date $5.4.1
            //candidate is not up-to-date if its last 
            //logs term is older or if they are equal 
            //then this server has longer log 
            output.term = s->current_term;
            output.vote_granted = 0;
        } else {
            if(input->term > s->current_term) {
                set_term(s, input->term);
                s->voted_for = input->candidate_id;
                save_state(s);
                output.term = s->current_term;
                output.vote_granted = 1;
            } else if(s->voted_for == 0) {
                //terms are equal mark the candidate
                //and this server didnt vote in this
                //election
                s->voted_for = input->candidate_id;
                save_state(s);
                output.term = s->current_term;
                output.vote_granted = 1;
            } else {
                //candidate has already voted in this term
                output.term = input->term;
                output.vote_granted = 0;
            }
        }
    }

    free(input);

    return make_request_vote_rpc_response(&output);
}
Beispiel #16
0
use_screen(SCREEN *screen, NCURSES_SCREEN_CB func, void *data)
{
    SCREEN *save_SP;
    int code = OK;

    T((T_CALLED("use_screen(%p,%p,%p)"), screen, func, data));

    /*
     * FIXME - add a flag so a given thread can check if _it_ has already
     * recurred through this point, return an error if so.
     */
    _nc_lock_global(curses);
    save_SP = SP;
    set_term(screen);

    code = func(screen, data);

    set_term(save_SP);
    _nc_unlock_global(curses);
    returnCode(code);
}
Beispiel #17
0
Nscreen::Nscreen(){
    //default constructor uses stdin and out
    this->numwindows = 1;
    scrptr = newterm("xterm",stdin,stdout);    
    set_term(scrptr);
    getmaxyx(stdscr,MAX_Y, MAX_X);

    start_color();
    init_pair(1,COLOR_WHITE,COLOR_BLUE);

    init_windows();
    cw=0;
}
Beispiel #18
0
static void request_vote_cb(struct data_t *result, char *err, void *data) {
    struct server_context_t *s = (struct server_context_t *)data;
    if(err) {
        //what should we do with bysentine errors?
        //LOG: fatal error. TODO: exit?
        return;
    }
    if(s->state != CANDIDATE) {
        return;
    }
    struct request_vote_output_t *vote = get_request_vote_output(result);
    if(!vote) {
        log_fatal_and_exit(s, 
            "RequestVoteCallback: Response parsing failed");
        return;
    }
    int pair_vote = vote->vote_granted;
    uint64_t pair_term = vote->term;
    free(vote);
    if(pair_vote && pair_term == s->current_term
        && s->state == CANDIDATE) {
        s->current_votes++;
    } else {
        if(pair_term > s->current_term) {
            set_term(s, pair_term);
            s->voted_for = 0;
            save_state(s);
        }
        return;
    }

    int votes_needed = s->quoram_size/2 + 1;
    if(s->current_votes == votes_needed) {
        s->state = LEADER;
        s->current_leader = s->id;
        DBG_LOG(LOG_INFO, "[%s][%d] Server is elected as the leader", ss[s->state], s->current_term);
        save_state(s);
        //reset timer such that election timeout does not occur 
        //and heartbeat timeout occurs
        reset_timers(s, false, true);
        for(int i = 0; i < s->quoram_size - 1; i++) {
            if(s->last_entry) {
                s->next_index[i] = s->last_entry->index + 1;
            } else {
                s->next_index[i] = 1;
            }
            s->match_index[i] = 0;
        }
        send_heartbeat(s);
    }
}
Beispiel #19
0
char		init_window(t_wrk *wrk)
{
  if ((wrk->screen = newterm(NULL, stderr, stdin)) == NULL)
    return (1);
  set_term(wrk->screen);
  wrk->selecta = 0;
  curs_set(0);
  keypad(stdscr, TRUE);
  wrk->arg->cursor = 1;
  wrk->cur = wrk->arg;
  wrk->x = 0;
  wrk->y = 0;
  wrk->pos = 0;
  return (0);
}
Beispiel #20
0
int main(void)
{
	SCREEN *s;

	s = newterm(NULL, stdout, stdin);
	set_term(s);

	addstr("Hello!");

	refresh();
	getch();

	endwin();
	return 0;
}
Beispiel #21
0
void packet_init() {
    if (nopacket == 1)
	packetinterface = 0;

    set_term(mainscreen);

    // really needed?
    refreshp();

    if ((nopacket == 0) && (packetinterface != 0)) {
	if (init_packet() == 0)
	    packet();
	else
	    cleanup_telnet();
    }
}
Beispiel #22
0
static void
cleanup(int sig)
{
    /*
     * XXX signal race.
     *
     * 1) Walking the SCREEN list is unsafe, since all list management
     *    is done without any signal blocking.
     * 2) On systems which have REENTRANT turned on, set_term() uses
     *    _nc_lock_global() which could deadlock or misbehave in other ways.
     * 3) endwin() calls all sorts of stuff, many of which use stdio or
     *    other library functions which are clearly unsafe.
     * 4) The comment about atexit() is wrong.  atexit() should never be
     *    called, because ...
     * 5) The call to exit() at the bottom is unsafe:  exit() depends
     *    depends on stdio being coherent (obviously it is not).  stdio
     *    could call free(), and also calls atexit() and dtor handlers,
     *    which are probably not written to be safe.  The signal handler
     *    should be calling _exit().
     */
    if (!_nc_globals.cleanup_nested++
	&& (sig == SIGINT
	    || sig == SIGQUIT)) {
#if HAVE_SIGACTION || HAVE_SIGVEC
	sigaction_t act;
	sigemptyset(&act.sa_mask);
	act.sa_flags = 0;
	act.sa_handler = SIG_IGN;
	if (sigaction(sig, &act, NULL) == 0)
#else
	if (signal(sig, SIG_IGN) != SIG_ERR)
#endif
	{
	    SCREEN *scan;
	    for (each_screen(scan)) {
		if (scan->_ofp != 0
		    && isatty(fileno(scan->_ofp))) {
		    scan->_cleanup = TRUE;
		    scan->_outch = _nc_outch;
		}
		set_term(scan);
		endwin();
		if (SP)
		    SP->_endwin = FALSE;	/* in case we have an atexit! */
	    }
	}
Beispiel #23
0
bool nCurse::Activate() {
    if (running) refresh();
    else {
        s = newterm((char *) 0,stdout,stdin);
        if (s != NULL) {
            set_term(s);
            width = COLS;
            height = LINES;
            curs_set(0); //uncomment it to get rid of the cursor
            noecho();
            cbreak();// Line buffering disabled. pass on everything
            nodelay(stdscr,1);
            keypad(stdscr, TRUE);
            running = true;
        }
    }
    return running;
}
Beispiel #24
0
// setup
void setup() {
  fdfile = fopen("/dev/lft0", "r+");
  fullScreen=newterm("linux", fdfile, fdfile);
  set_term(fullScreen);

  simWin = newwin(SIMWINHEIGHT, 400, ySimPos, xSimPos);
  scrollok(simWin, TRUE);
  waddstr(simWin, "** Hang on a sec... just waiting for the uvm boat anchor demo to compile\n");
  wmove(simWin, ++ySimPos, xSimPos);
  waddstr(simWin, "** and start running. You'll see something happen shortly...\n\n");
  wmove(simWin, ++ySimPos, xSimPos);
  wrefresh(simWin);

  guiWin = newwin(GUIWINHEIGHT, 400, SIMWINHEIGHT+1, xSimPos);
  boat_anchor.setWindow(guiWin);
  boat_anchor.startingScene();
  wrefresh(guiWin);
}
Beispiel #25
0
int
vdk_screen_resume(vdk_screen_t *screen)
{
    int             raster_type;

    if(screen == NULL) return -1;
    raster_type = vdk_object_get_raster_type(VDK_OBJECT(screen));

    if(raster_type != VDK_RASTER_SCR) return -1;

    // check to see if screen is already active
    if(!(screen->state & VDK_SCREEN_PAUSED)) return -1;

    screen->state &= ~VDK_SCREEN_PAUSED;
    set_term(*(SCREEN**)screen);
    refresh();

    _vdk_screen_update_metrics(VDK_OBJECT(screen));

    return 0;
}
Beispiel #26
0
int main(void)
{
	FILE *termin,*termout;
	SCREEN *tp1,*tp2;
	char name[81];

/* Open terminal one for reading
   Open terminal two for writing */
	termin = fopen(INTERM,"r");
	termout = fopen(OUTTERM,"w");
	if( termin==NULL || termout==NULL )
	{
			puts("Unable to open terminal.");
			return(1);
	}

/* set up the new terminal in NCurses */
	tp2 = newterm(NULL,termout,termin);
	if( tp2 == NULL)
	{ 
		puts("Unable to open terminal window.");
		return(2);
	}

/* NCurses is now started for the new terminal */
	tp1 = set_term(tp2);
	printw("Welcome to Curses output on terminal %s.\n",OUTTERM);
	printw("You can type on terminal %s, and see it here.\n",INTERM);
	addstr("What is your name: ");
	refresh();
	getnstr(name,80);
	printw("%s, glad to have you aboard!",name);
	refresh();
	getch();

	endwin();
	return 0;
}
Beispiel #27
0
static int
_vdk_screen_dtor(vdk_object_t *object)
{
    vdk_raster_t    *raster;
    int             raster_type;
    int             retval;

    if(object == NULL) return -1;

    raster_type = vdk_object_get_raster_type(VDK_OBJECT(object));
    if(raster_type != VDK_RASTER_SCR) return -1;

    raster = VDK_RASTER(object);

    // in order to tear down the screen it must first be activated
    set_term(raster->primitive.screen);
    endwin();
    delscreen(raster->primitive.screen);

    // call the parent klass destructor
    retval = VDK_OBJECT(VDK_CONTEXT_KLASS)->dtor(object);

    return retval;
}
Beispiel #28
0
/**
 * Ncurses Text User Interface
 * open_ncurses	    - open text window
 * close_ncurses    - close text window
 */
int open_ncurses() {
#ifdef HAVE_LIBNCURSESW
	int debug = 1;

	FILE *in = fopen( "/dev/stderr", "r" );
	FILE *out = fopen( "/dev/stderr", "w" );
	int terminal_x = 0;
	int terminal_y = 0;

	ptclscr = newterm(NULL, out, in);
	refresh();
	if (!ptclscr)
		log_mesg(0, 1, 1, debug, "partclone ncurses initial error\n");
	if (!set_term(ptclscr))
		log_mesg(0, 1, 1, debug, "partclone ncurses set term error\n");
	ptclscr_win = newwin(LINES, COLS, 0, 0);

	// check terminal width and height
	getmaxyx(ptclscr_win, terminal_y, terminal_x);

	// set window position
	int log_line = 12;
	int log_row = 60;
	int log_y_pos = (terminal_y-24)/2+2;
	int log_x_pos = (terminal_x-log_row)/2;
	int gap = 0;
	int p_line = 8;
	int p_row = log_row;
	int p_y_pos = log_y_pos+log_line+gap;
	int p_x_pos = log_x_pos;

	int size_ok = 1;

	if (terminal_y < (log_line+gap+p_line+3))
		size_ok = 0;
	if (terminal_x < (log_row+2))
		size_ok = 0;

	if (size_ok == 0) {
		log_mesg(0, 0, 0, debug, "Terminal width(%i) or height(%i) too small\n", terminal_x, terminal_y);
		return 0;
	}

	/// check color pair
	if (!has_colors()) {
		log_mesg(0, 0, 0, debug, "Terminal color error\n");
		return 0;
	}

	if (start_color() != OK){
		log_mesg(0, 0, 0, debug, "Terminal can't start color mode\n");
		return 0;
	}

	/// define color
	init_pair(1, COLOR_WHITE, COLOR_BLUE); ///stdscr
	init_pair(2, COLOR_RED, COLOR_WHITE); ///sub window
	init_pair(3, COLOR_BLUE, COLOR_WHITE); ///sub window

	/// write background color
	bkgd(COLOR_PAIR(1));
	wbkgd(ptclscr_win,COLOR_PAIR(2));
	touchwin(ptclscr_win);
	refresh();

	/// init main box
	attrset(COLOR_PAIR(2));
	box_win = subwin(ptclscr_win, (log_line+gap+p_line+2), log_row+2, log_y_pos-1, log_x_pos-1);
	box(box_win, ACS_VLINE, ACS_HLINE);
	wrefresh(box_win);
	wbkgd(box_win, COLOR_PAIR(2));
	mvprintw((log_y_pos-1), ((terminal_x-9)/2), " Partclone ");
	attroff(COLOR_PAIR(2));

	attrset(COLOR_PAIR(3));

	/// init log window
	log_win = subwin(ptclscr_win, log_line, log_row, log_y_pos, log_x_pos);
	wbkgd(log_win, COLOR_PAIR(3));
	touchwin(log_win);
	refresh();

	// init progress window
	p_win = subwin(ptclscr_win, p_line, p_row, p_y_pos, p_x_pos);
	wbkgd(p_win, COLOR_PAIR(3));
	touchwin(p_win);
	refresh();

	// init progress window
	bar_win = subwin(ptclscr_win, 1, p_row-10, p_y_pos+4, p_x_pos);
	wbkgd(bar_win, COLOR_PAIR(1));
	touchwin(bar_win);
	refresh();

	// init total block progress window
	tbar_win = subwin(ptclscr_win, 1, p_row-10, p_y_pos+7, p_x_pos);
	wbkgd(tbar_win, COLOR_PAIR(1));
	touchwin(tbar_win);
	refresh();

	scrollok(log_win, TRUE);

	if (touchwin(ptclscr_win) == ERR)
		return 0;

	refresh();

#endif
	return 1;
}
Beispiel #29
0
static void election_timeout_callback(int fd, short event, void *arg) {
    struct server_context_t *s = (struct server_context_t *)arg;
    if(event & EV_TIMEOUT) {
        DBG_LOG(LOG_INFO, "[%s][%d] election timeout occurred", ss[s->state], s->current_term);
        //election timeout occurred -- do the candidate activities
        s->state = CANDIDATE;    
        s->current_leader = -1;
        s->voted_for = s->id;
        s->current_term++;
        save_state(s);

        s->current_votes = 1;

        //reset the previous election timer and add new one such that
        //if split vote occurs we have one more election
        reset_timers(s, true, false);

        //check if quoram_size already equal to required majoriy
        int votes_needed = s->quoram_size/2 + 1;
        if(votes_needed == s->current_votes) {
            s->state = LEADER;
            s->current_leader = s->id;
            save_state(s);
        } else {
            //send RequestVote RPC to pairs
            struct request_vote_input_t *input = (struct request_vote_input_t *)
                malloc(sizeof(struct request_vote_input_t));
            if(!input) {
                set_term(s, s->current_term - 1);
                return;
            }
            input->term = s->current_term;
            input->candidate_id = s->id;
            if(s->last_entry) {
                input->last_log_index = s->last_entry->index;
                input->last_log_term = s->last_entry->term;
            } else {
                input->last_log_index = 0; 
                input->last_log_term = 0;
            }

            struct method_t *rpc = make_request_vote_rpc_method(input);
            if(!rpc) {
                free(input);
                set_term(s, s->current_term - 1);
                return;
            }

            for(int i = 0; i < s->quoram_size - 1; i++) {
                if(rpc_call(s->rpc_c, s->peers[i]->dest, 
                            rpc, request_vote_cb, s)) {
                    //just log warning, as peers might go down
                    DBG_LOG(LOG_WARN, "[%s][%d] RPC call failed for peer %d", 
                            ss[s->state], s->current_term, s->peers[i]->id);
                }
            }
            free(input);
            free_method_t(rpc);
        } //end else-if
    }
}
Beispiel #30
0
static void append_entries_cb(struct data_t *result, char *err, void *data) {
    /* TODO: why we need to create and then free the data, cant we just
     * reuse the slots, especially in case of heartbeat message? */
    struct append_entries_cb_data_t *cb_data = 
            (struct append_entries_cb_data_t *)data;
    struct server_context_t *s = cb_data->s;
    int peer_index = cb_data->index;
    uint64_t first_index = cb_data->first_index;
    uint64_t last_index = cb_data->last_index;
    
    free(cb_data);

    if(err) {
        //LOG: fatal error. TODO: exit?
        DBG_LOG(LOG_DEBUG, "[%s][%d] FAIL append_entries_cb from peer_id = %d with err = %s"
                , ss[s->state], s->current_term, peer_index, err);
        return;
    }

    struct append_entries_output_t *res = get_append_entries_output(result);
    if(!res) {
        log_fatal_and_exit(s, 
            "AppendEntriesCallback: Response parsing failed");
        return;
    }
    uint64_t pair_term = res->term;
    int pair_success = res->success;
    free(res);
    if(pair_term > s->current_term) {
        set_term(s, pair_term);
        s->voted_for = 0;
        save_state(s);
        return;
    }

    if(s->state != LEADER) {
        return;
    } 
    
    if(!pair_success) {
        DBG_LOG(LOG_DEBUG, "[%s][%d] FAIL append_entries_cb from peer_id = %d"
                , ss[s->state], s->current_term, peer_index);
        //TODO: send the client prev entry
        s->next_index[peer_index] = first_index - 1;
    } else {
        DBG_LOG(LOG_DEBUG, "[%s][%d] OK append_entries_cb from peer_id = %d"
                , ss[s->state], s->current_term, peer_index);
        s->next_index[peer_index] = last_index + 1;
        s->match_index[peer_index] = last_index;

        //If there exists an N such that N > commitIndex, a majority
        //of matchIndex[i] ≥ N, and log[N].term == currentTerm: 
        //set commitIndex = N (§5.3, §5.4).
        if(s->match_index[peer_index] > s->commit_index) {
            int nOK[s->quoram_size - 1];
            for(int i = 0; i < s->quoram_size - 1; i++) {
                nOK[i] = 0;
            }
            for(int i = 0; i < s->quoram_size - 1; i++) {
                for(int j = 0; j < s->quoram_size - 1; j++) {
                    if(s->match_index[i] <= s->match_index[j]) {
                        nOK[i]++;
                    }
                }
            }
            int majority = (s->quoram_size/2);
            uint64_t N = s->commit_index;
            int minOKs = s->quoram_size;
            for(int i = 0; i < s->quoram_size - 1; i++) {
                if(nOK[i] >= majority && nOK[i] < minOKs) {
                    minOKs = nOK[i];
                    if(s->match_index[i] > N) {
                        N = s->match_index[i];
                    }
                }
            }
            if(N > s->commit_index) {
                struct log_entry_t *entryN = get_log_entry_at(s->log, N);
                //never commit entry from previous term (§5.4.2)
                if(entryN && (entryN->term == s->current_term)) {
                    s->commit_index = N;
                    commit_unapplied_entries(s, N);
                }
            }
        }
    }
    if(s->last_entry && s->last_entry->index >= s->next_index[peer_index]) {
        //send all the entries since next_index till some threshold
        //to this server
        if(send_append_entries(s, s->next_index[peer_index], peer_index)) {
            //LOG: fatal error. TODO: exit?
        }
    }
}