Ejemplo n.º 1
0
int status_client_ncurses(struct config *conf, enum action act, const char *sclient)
{
	int fd=0;
        int ret=0;
	int sel=0;
	char *rbuf=NULL;
	char buf[512]="";
	int count=0;
	int details=0;
	char *last_rbuf=NULL;
	int srbr=0;
	char *client=NULL;
	int enterpressed=0;
//	int loop=0;
	int reqdone=0;

#ifdef HAVE_NCURSES_H
	int stdinfd=fileno(stdin);
	actg=act; // So that the sighandler can call endwin().
#else
	if(act==ACTION_STATUS)
	{
		printf("To use the live status monitor, you need to recompile with ncurses support.\n");
		return -1;
	}
#endif

	setup_signals();

	/* NULL == ::1 or 127.0.0.1 */
	if((fd=init_client_socket(NULL, conf->status_port))<0)
		return -1;
	set_non_blocking(fd);

#ifdef HAVE_NCURSES_H
	if(actg==ACTION_STATUS)
	{
		initscr();
		start_color();
		init_pair(1, COLOR_WHITE, COLOR_BLACK);
		init_pair(2, COLOR_WHITE, COLOR_BLACK);
		init_pair(3, COLOR_WHITE, COLOR_BLACK);
		raw();
		keypad(stdscr, TRUE);
		noecho();
		curs_set(0);
		halfdelay(3);
		//nodelay(stdscr, TRUE);
	}
#endif
#ifdef DBFP
	dbfp=fopen("/tmp/dbfp", "w");
#endif

	while(!ret)
	{
		int l;
		int mfd=-1;
		fd_set fsr;
		fd_set fse;
		struct timeval tval;

		// Failsafe to prevent the snapshot ever getting permanently
		// stuck.
		//if(act==ACTION_STATUS_SNAPSHOT && loop++>10000)
		//	break;

		if(sclient && !client)
		{
			client=strdup(sclient);
			details=1;
		}

		if((enterpressed || need_status()) && !reqdone)
		{
			char *req=NULL;
			if(details && client) req=client;
			if(request_status(fd, req, conf))
			{
				ret=-1;
				break;
			}
			enterpressed=0;
			if(act==ACTION_STATUS_SNAPSHOT)
				reqdone++;
		}

		FD_ZERO(&fsr);
		FD_ZERO(&fse);

		tval.tv_sec=1;
		tval.tv_usec=0;

		add_fd_to_sets(fd, &fsr, NULL, &fse, &mfd);
#ifdef HAVE_NCURSES_H
		if(actg==ACTION_STATUS)
			add_fd_to_sets(stdinfd, &fsr, NULL, &fse, &mfd);
#endif

		if(select(mfd+1, &fsr, NULL, &fse, &tval)<0)
		{
			if(errno!=EAGAIN && errno!=EINTR)
			{
				logp("select error: %s\n",
					strerror(errno));
				ret=-1;
				break;
			}
			continue;
		}

		if(FD_ISSET(fd, &fse))
		{
			ret=-1;
			break;
		}

#ifdef HAVE_NCURSES_H
		if(actg==ACTION_STATUS)
		{
			if(FD_ISSET(stdinfd, &fse))
			{
				ret=-1;
				break;
			}
			if(FD_ISSET(stdinfd, &fsr))
			{
				int quit=0;
				
				switch(getch())
				{
					case 'q':
					case 'Q':
						quit++;
						break;
					case KEY_UP:
					case 'k':
					case 'K':
						if(details) break;
						sel--;
						break;
					case KEY_DOWN:
					case 'j':
					case 'J':
						if(details) break;
						sel++;
						break;
					case KEY_ENTER:
					case '\n':
					case ' ':
						if(details) details=0;
						else details++;
						enterpressed++;
						break;
					case KEY_LEFT:
					case 'h':
					case 'H':
						details=0;
						break;
					case KEY_RIGHT:
					case 'l':
					case 'L':
						details++;
						break;
					case KEY_NPAGE:
					{
						int row=0, col=0;
						getmaxyx(stdscr, row, col);
						sel+=row-TOP_SPACE;
						break;
					}
					case KEY_PPAGE:
					{
						int row=0, col=0;
						getmaxyx(stdscr, row, col);
						sel-=row-TOP_SPACE;
						break;
					}
				}
				if(quit) break;

				if(sel<0) sel=0;
				if(sel>=count) sel=count-1;

				// Attempt to print stuff to the screen right
				// now, to give the impression of key strokes
				// being responsive.
				if(!details && !sclient)
				{
				  if((srbr=show_rbuf(last_rbuf,
					conf, sel, &client,
					&count, details, sclient))<0)
				  {
					ret=-1;
					break;
				  }
				  if(!details) print_star(sel);
				
				  refresh();
				}
			}
		}
#endif

		if(FD_ISSET(fd, &fsr))
		{
			// ready to read.
			if((l=read(fd, buf, sizeof(buf)-1))>0)
			{
				size_t r=0;
				buf[l]='\0';
				if(rbuf) r=strlen(rbuf);
				rbuf=(char *)realloc(rbuf, r+l+1);
				if(!r) *rbuf='\0';
				strcat(rbuf+r, buf);
			}
			else
				break;

			if(act==ACTION_STATUS_SNAPSHOT)
			{
				if(rbuf)
				{
					if(!strcmp(rbuf, "\n"))
					{
						// This happens when there are
						// no backup clients.
						break;
					}
					if(strstr(rbuf, "\n-list end-\n"))
					{
						printf("%s", rbuf);
						break;
					}
				}
				continue;
			}

			//if(rbuf) printf("rbuf: %s\n", rbuf);
/*
			if(l<0)
			{
				ret=-1;
				break;
			}
*/
		}

		if((srbr=show_rbuf(rbuf, conf,
			sel, &client, &count, details, sclient))<0)
		{
			ret=-1;
			break;
		}
		else if(srbr)
		{
			// Remember it, so that we can present the detailed
			// screen without delay, above.
			if(last_rbuf) free(last_rbuf);
			last_rbuf=rbuf;
			rbuf=NULL;
		}

		if(sclient) details++;

		usleep(20000);
#ifdef HAVE_NCURSES_H
		if(actg==ACTION_STATUS)
		{
			flushinp();
			continue;
		}
#endif
		if(count)
		{
			printf("\n");
			break;
		}
	}
#ifdef HAVE_NCURSES_H
	if(actg==ACTION_STATUS) endwin();
#endif
	close_fd(&fd);
	if(last_rbuf) free(last_rbuf);
	if(rbuf) free(rbuf);
#ifdef DBFP
	if(dbfp) fclose(dbfp);
#endif
	return ret;
}
Ejemplo n.º 2
0
static
#endif
int status_client_ncurses_main_loop(struct async *as,
	struct asfd *so_asfd, struct sel *sel,
	const char *orig_client)
{
	int ret=-1;
	char *client=NULL;
	int count=0;
	struct asfd *asfd=NULL;
	struct asfd *sfd=NULL; // Server asfd.
	int reqdone=0;

	if(!sel
	  || !as
	  || !(stdout_asfd=so_asfd)
	  || !(sfd=as->asfd))
	{
		logp("parameters not set up correctly in %s\n", __func__);
		goto error;
	}

	sel->page=PAGE_CLIENT_LIST;

	if(orig_client)
	{
		client=strdup_w(orig_client, __func__);
		sel->page=PAGE_BACKUP_LIST;
	}

	if(json_input_init()) goto end;

	while(1)
	{
		if(need_status(sel) && !reqdone)
		{
			char *req=NULL;
			if(sel->page>PAGE_CLIENT_LIST)
			{
				if(client)
					req=client;
				else if(sel->client)
					req=sel->client->name;
			}
			if(request_status(sfd, req, sel))
				goto error;

			// We only want to start on the client the user gave to
			// us. Freeing it will allow the user to browse other
			// clients thereafter.
			free_w(&client);

			if(actg==ACTION_STATUS_SNAPSHOT)
				reqdone=1;
		}

		if(as->read_write(as))
		{
			// FIX THIS - an exception is thrown when the console
			// is resized.
/*
			if(sfd->want_to_remove)
			{
				sfd->want_to_remove=0;
				continue;
			}
*/
			logp("Exiting main loop\n");
			goto error;
		}

		for(asfd=as->asfd; asfd; asfd=asfd->next)
		{
			while(asfd->rbuf->buf)
			{
				switch(parse_data(asfd, sel, count))
				{
					case 0: break;
					case 1: goto end;
					default: goto error;
				}
				iobuf_free_content(asfd->rbuf);
				if(asfd->parse_readbuf(asfd))
					goto error;
			}

			// Select things if they are not already selected.
			if(sel->client)
			{
				if(!sel->backup)
					sel->backup=sel->client->bu;
			}
			else
				sel->client=sel->clist;
		}

#ifdef HAVE_NCURSES
		if(actg==ACTION_STATUS
		  && update_screen(sel))
			goto error;
		refresh();
#endif

		if(actg==ACTION_STATUS_SNAPSHOT
		  && sel->client)
		{
			if(update_screen(sel))
				goto error;
			stdout_asfd->write_str(stdout_asfd, CMD_GEN, "\n");
			break;
		}
	}

end:
	ret=0;
error:
	json_input_free();
	return ret;
}
Ejemplo n.º 3
0
static int main_loop(struct async *as, enum action act, struct conf **confs)
{
	int ret=-1;
	char *client=NULL;
	int count=0;
	struct asfd *asfd=NULL;
	struct asfd *sfd=as->asfd; // Server asfd.
	int reqdone=0;
	struct sel *sel=NULL;
	const char *orig_client=get_string(confs[OPT_ORIG_CLIENT]);

	if(!(sel=(struct sel *)calloc_w(1, sizeof(struct sel), __func__)))
		goto error;
	sel->page=PAGE_CLIENT_LIST;

	if(orig_client && !client)
	{
		client=strdup_w(orig_client, __func__);
		sel->page=PAGE_BACKUP_LIST;
	}

	while(1)
	{
		if(need_status(sel) && !reqdone)
		{
			char *req=NULL;
			if(sel->page>PAGE_CLIENT_LIST)
			{
				if(client) req=client;
				else if(sel->client) req=sel->client->name;
			}
			if(request_status(sfd,
				req, sel, confs)) goto error;
			if(act==ACTION_STATUS_SNAPSHOT)
				reqdone=1;
		}

		if(as->read_write(as))
		{
			// FIX THIS - an exception is thrown when the console
			// is resized.
/*
			if(sfd->want_to_remove)
			{
				sfd->want_to_remove=0;
				continue;
			}
*/
			logp("Exiting main loop\n");
			goto error;
		}

		for(asfd=as->asfd; asfd; asfd=asfd->next)
			while(asfd->rbuf->buf)
		{
			switch(parse_data(asfd, sel, count))
			{
				case 0: break;
				case 1: goto end;
				default: goto error;
			}
			iobuf_free_content(asfd->rbuf);
			if(asfd->parse_readbuf(asfd))
				goto error;
		}

		if(!sel->client) sel->client=sel->clist;
		if(!sel->backup && sel->client) sel->backup=sel->client->bu;

#ifdef HAVE_NCURSES_H
		if(act==ACTION_STATUS
		  && update_screen(sel, confs))
			goto error;
		refresh();
#endif

		if(act==ACTION_STATUS_SNAPSHOT
		  && sel->gotfirstresponse)
		{
			if(update_screen(sel, confs))
				goto error;
			// FIX THIS - should probably set up stdout with an
			// asfd.
			printf("\n");
			break;
		}
	}

end:
	ret=0;
error:
	// FIX THIS: should probably be freeing a bunch of stuff here.
	free_v((void **)&sel);
	return ret;
}