1 /* showlog.c - show logfile */
2 #include <ncurses.h>
3 #include <stdlib.h>
4 #include <string.h>
5 #include "huskyui.h"
6 #include "cfg.h"
7 #include "showlog.h"
8 #include "showoutb.h"
9 #include "menu.h"
10 
11 WINDOW *logWin, *logWinBoxed;
12 int logIsActive;
13 FILE *logFile;
14 char **logBuf;
15 char *logLine;
16 int logBufReadPos;
17 int logBufDispPos;
18 int logLineSize;
19 int logWinLen;
20 
logInit(int active)21 void logInit(int active)
22 {
23   logWinLen = (LINES / 3) - 2;
24   logWinBoxed = newwin(LINES / 3, COLS, 0, 0);
25   logWin = newwin(logWinLen, COLS - 4, 1, 2);
26 
27   leaveok(logWin, TRUE);
28   scrollok(logWin, TRUE);
29   nodelay(logWin, TRUE);
30 
31   if (cfg.logName != NULL) logFile = fopen(cfg.logName, "r");
32   else logFile = NULL;
33 
34   logBuf = calloc(cfg.numLogLines, sizeof(char *));
35   logBufReadPos = 0;
36   logBufDispPos = 0;
37   logLineSize = COLS - 5;
38   logLine = malloc(logLineSize);
39 
40   logIsActive = active;
41   logForceDraw();
42   logDraw();
43 }
44 
logSetActive()45 void logSetActive()
46 {
47   logIsActive = 1;
48   logForceDraw();
49 }
50 
logSetInactive()51 void logSetInactive()
52 {
53   logIsActive = 0;
54   logForceDraw();
55 }
56 
logDraw()57 void logDraw()
58 {
59   int logUpdated = 0;
60 
61   if (logFile == NULL) return;
62 
63   clearerr(logFile);
64   while (feof(logFile) == 0)
65   {
66     // get line
67     *logLine = 0;
68     fgets(logLine, logLineSize, logFile);
69 
70     if (*logLine != 0)
71     {
72       logUpdated = 1;
73 
74       // strip LF
75       while ((*logLine != 0) && (logLine[strlen(logLine) - 1] == '\n'))
76 	logLine[strlen(logLine) - 1] = 0;
77 
78       // copy line into buffer
79       nfree(logBuf[logBufReadPos]);
80       logBuf[logBufReadPos] = strdup(logLine);
81       if ((logBufReadPos > logWinLen) &&
82 	  (logBufDispPos < (cfg.numLogLines - logWinLen)))
83 	logBufDispPos = logBufReadPos - logWinLen + 1;
84       logBufReadPos++;
85 
86       // buffer-scroll needed?
87       if (logBufReadPos == cfg.numLogLines)
88       {
89 	int i;
90 
91 	// move whole buffer 1 line up
92 	nfree(logBuf[0]);
93 	logBufReadPos--;
94 	for (i = 0; i < logBufReadPos; i++)
95 	  logBuf[i] = logBuf[i + 1];
96 	logBuf[logBufReadPos] = 0;
97 	logBufDispPos--;
98       }
99 
100     }
101   }
102 
103   if (logUpdated != 0) logForceDraw();
104 }
105 
logForceDraw()106 void logForceDraw()
107 {
108   int i;
109 
110   if (logIsActive == 0)
111   {
112     wborder(logWinBoxed, ACS_VLINE, ACS_VLINE, ACS_HLINE, ACS_HLINE,
113 	    ACS_ULCORNER, ACS_URCORNER, ACS_LLCORNER, ACS_LRCORNER);
114   }
115   else
116   {
117     wborder(logWinBoxed, ACS_BLOCK, ACS_BLOCK, ACS_BLOCK, ACS_BLOCK,
118 	    ACS_BLOCK, ACS_BLOCK, ACS_BLOCK, ACS_BLOCK);
119   }
120   mvwprintw(logWinBoxed, 0, (COLS - 5) / 2, " log ");
121 
122   wmove(logWin, 0, 0);
123 
124   if (logFile == NULL)
125   {
126     wprintw(logWin, "Could not open logfile '%s'!\n", cfg.logName);
127   }
128   else
129   {
130     int maxPos = min(logBufReadPos, logBufDispPos + logWinLen - 1);
131 
132     for (i = logBufDispPos; i <= maxPos; i++)
133     {
134 	if (logBuf[i] != NULL)
135 	{
136 	    if (i < maxPos) wprintw(logWin, "%s\n", logBuf[i]);
137 	    else wprintw(logWin, "%s", logBuf[i]);
138 	}
139     }
140   }
141 
142   wrefresh(logWinBoxed);
143   wrefresh(logWin);
144 }
145 
logShowHelp()146 void logShowHelp()
147 {
148   WINDOW *helpWinBoxed, *helpWin;
149 
150   helpWinBoxed = newwin(LINES, COLS, 0, 0);
151   helpWin = newwin(LINES - 2, COLS - 4, 1, 2);
152 
153   wborder(helpWinBoxed, ACS_BLOCK, ACS_BLOCK, ACS_BLOCK, ACS_BLOCK,
154 	  ACS_BLOCK, ACS_BLOCK, ACS_BLOCK, ACS_BLOCK);
155   mvwprintw(helpWinBoxed, 0, (COLS - 10) / 2, " log help ");
156 
157   mvwprintw(helpWin, 0, 0,
158 	    "\n"
159 	    "<cursor up>   move up 1 line in logfile\n"
160 	    "<cursor down> move down 1 line\n"
161 	    "<page up>     move up 1 page\n"
162 	    "<page down>   move down 1 page\n"
163 	    "<home>        jump to beginning\n"
164 	    "<end>         jump to end\n"
165 	    "\n"
166 	    "<?>           help (this screen)\n"
167 	    "<Tab>         cycle through windows\n"
168 	    "\n"
169 	    "Press any key to continue\n");
170 
171   wrefresh(helpWinBoxed);
172   wrefresh(helpWin);
173 
174   wgetch(helpWin);
175 
176   delwin(helpWin);
177   delwin(helpWinBoxed);
178 
179   touchwin(stdscr); wrefresh(stdscr);
180   logForceDraw();
181   outbForceDraw();
182   menuForceDraw();
183 }
184 
logProcessKey(int key)185 void logProcessKey(int key)
186 {
187   switch (key)
188   {
189   case '?':
190     logShowHelp();
191     break;
192 
193   case KEY_UP:
194     if (logBufDispPos > 0)
195     {
196       logBufDispPos--;
197       logForceDraw();
198       logDraw();
199     }
200     break;
201 
202   case KEY_DOWN:
203     if (logBufDispPos < (logBufReadPos - 1))
204     {
205       logBufDispPos++;
206       logForceDraw();
207       logDraw();
208     }
209     break;
210 
211   case KEY_PPAGE:
212     {
213       if (logBufDispPos > (logWinLen - 1))
214 	logBufDispPos = logBufDispPos - logWinLen + 1;
215       else
216 	logBufDispPos = 0;
217 
218       logForceDraw();
219       logDraw();
220     }
221     break;
222 
223   case KEY_NPAGE:
224     {
225       if (logBufDispPos < (logBufReadPos - 2*logWinLen + 1))
226 	logBufDispPos = logBufDispPos + logWinLen - 1;
227       else
228 	logBufDispPos = logBufReadPos - logWinLen;
229 
230       logForceDraw();
231       logDraw();
232     }
233     break;
234 
235   case KEY_HOME:
236     {
237       logBufDispPos = 0;
238       logForceDraw();
239       logDraw();
240     }
241     break;
242 
243   case KEY_END:
244     {
245       logBufDispPos = logBufReadPos - logWinLen;
246       logForceDraw();
247       logDraw();
248     }
249     break;
250   }
251 }
252 
logDone()253 void logDone()
254 {
255   int i;
256 
257   for (i = 0; i < cfg.numLogLines; i++) nfree(logBuf[i]);
258   nfree(logBuf);
259   nfree(logLine);
260   if (logFile != NULL) fclose(logFile);
261   delwin(logWin);
262   delwin(logWinBoxed);
263 }
264 
265