1 /*
2  * pager.c -- pager control
3  *
4  * Copyright (C) 1992,1997,1999,2000,2003 by Yoshifumi Mori
5  *
6  * tab:4
7  */
8 
9 #include "cdefs.h"
10 #include "extern.h"
11 
12 #define MAXFOLDLEN	256					/* �ޤ��֤���� */
13 #define MAXFOLDBUF	(MAXFOLDLEN + 8)	/* �ޤ��֤��Хåե� */
14 
15 char	*pager_cmd;
16 char	*pager_outputfile;
17 char	*pager_filelog_path;
18 int		pager_action = TRUE;
19 int		pager_filekeep = FALSE;
20 int		pager_pause = FALSE;
21 int		pager_lastpause = FALSE;
22 
23 #if defined(_T_WINDOWS)
24 char	**textBuf;
25 int		textLines;
26 
27 static int	textLineAlloc;
28 #endif
29 
30 #if defined(_T_HUMAN68K) || defined(_T_MSDOS) || defined(_T_UNIX) || defined(_T_WIN32CONSOLE)
31 static int	line_count;
32 #endif
33 static char	pager_file[_T_MAXPATHNAME];
34 static FILE	*pager_fp = NULL;
35 static int	pager_out_flag;
36 
37 #if defined(_T_WINDOWS)
38 /*
39  * �ƥ����ȥХåե��β���
40  */
pager_text_free(void)41 void pager_text_free(void)
42 {
43 	int	i;
44 
45 	if (textBuf != NULL) {
46 		for (i = 0; i < textLines; i++) {
47 			if (textBuf[i] != NULL) {
48 				free(textBuf[i]);
49 			}
50 		}
51 		free(textBuf);
52 		textBuf = NULL;
53 	}
54 	textLines = 0;
55 	textLineAlloc = 0;
56 }
57 #endif /* _T_WINDOWS */
58 
59 /*
60  * TODAY ���ϥե�����κ���
61  */
pager_init(void)62 void pager_init(void)
63 {
64 #if defined(_T_HUMAN68K) || defined(_T_MSDOS) || defined(_T_UNIX) || defined(_T_WIN32CONSOLE)
65 	char	*tmppath;
66 #if defined(_T_WIN32CONSOLE)
67 	char	szTempPath[MAX_PATH+1];
68 	int		rtc;
69 #endif /* _T_WIN32CONSOLE */
70 	char	*new_path;
71 
72 	line_count = screen_max_rows;
73 	pager_out_flag = FALSE;
74 
75 	if (pager_action == FALSE) {		/* �ڡ����㡼��ư��? */
76 		if (pager_cmd != NULL) {
77 			free(pager_cmd);
78 			pager_cmd = NULL;
79 		}
80 		pager_pause = FALSE;
81 		pager_lastpause = FALSE;
82 	}
83 
84 	if (pager_filekeep == FALSE) {
85 		if (pager_cmd == NULL) {
86 			return;
87 		} else {
88 			if (pager_outputfile != NULL) {
89 				free(pager_outputfile);
90 			}
91 			pager_outputfile = xstrdup(_T_OUTFILE_TMPNAME);
92 		}
93 	} else {
94 		if (pager_outputfile == NULL) {
95 			pager_outputfile = xstrdup(_T_OUTFILE_DEFAULT);
96 		}
97 	}
98 
99 	memset(pager_file, '\0', sizeof(pager_file));
100 	if (pager_filelog_path != NULL) {
101 		strncpy(pager_file, pager_filelog_path, sizeof(pager_file) - 1);
102 #if defined(_T_UNIX)
103 		(void)replace_accesspath(pager_file, sizeof(pager_file));
104 #endif
105 	} else {
106 		tmppath = getenv(_T_TMPENV);
107 		if (tmppath == NULL) {
108 #if defined(_T_TMPENV2)
109 			tmppath = getenv(_T_TMPENV2);
110 			if (tmppath == NULL) {
111 #endif
112 #if defined(_T_WIN32CONSOLE)
113 				rtc = GetTempPath(sizeof(szTempPath), szTempPath);
114 				if (rtc == 0 || rtc > sizeof(szTempPath)) {
115 					tmppath = _T_TMPDIR;	/* use temporary directory */
116 				} else {
117 					tmppath = szTempPath;
118 				}
119 #else /* _T_HUMAN68K || _T_MSDOS || _T_UNIX */
120 				tmppath = _T_TMPDIR;	/* use temporary directory */
121 #endif /* _T_HUMAN68K || _T_MSDOS || _T_UNIX */
122 #if defined(_T_TMPENV2)
123 			}
124 #endif
125 		}
126 		strncpy(pager_file, tmppath, sizeof(pager_file) - 1);
127 	}
128 	new_path = make_accesspath(pager_file);
129 	strncat(new_path, make_filename(pager_outputfile), (sizeof(pager_file) - 1) - strlen(new_path));
130 
131 	pager_fp = fopen(pager_file, "w");
132 	if (pager_fp == NULL) {
133 		errprint(NULL, ERR_ERROR, "can not open pager file %s", pager_file);
134 		if (pager_cmd != NULL) {
135 			errprint(NULL, ERR_INFO, "�ե����뤬�����Ǥ��ʤ��Τǡ���¢�ڡ����㡼����Ѥ��ޤ�");
136 			free(pager_cmd);
137 			pager_cmd = NULL;
138 		}
139 		if (pager_filekeep == TRUE) {
140 			errprint(NULL, ERR_INFO, "�ե����뤬�����Ǥ��ʤ��Τǡ���Ͽ�ե�����Ϻ������ޤ���");
141 		}
142 	}
143 #endif /* _T_HUMAN68K || _T_MSDOS || _T_UNIX || _T_WIN32CONSOLE */
144 #if defined(_T_WINDOWS)
145 	char	*tmppath;
146 	char	szTempPath[MAX_PATH+1];
147 	int		rtc;
148 	char	*new_path;
149 
150 	pager_text_free();
151 	pager_out_flag = FALSE;
152 
153 	if (pager_filekeep == FALSE) {
154 		return ;
155 	}
156 
157 	memset(pager_file, '\0', sizeof(pager_file));
158 	if (pager_filelog_path != NULL) {
159 		strncpy(pager_file, pager_filelog_path, sizeof(pager_file) - 1);
160 	} else {
161 		tmppath = getenv(_T_TMPENV);
162 		if (tmppath == NULL) {
163 			tmppath = getenv(_T_TMPENV2);
164 			if (tmppath == NULL) {
165 				rtc = GetTempPath(sizeof(szTempPath), szTempPath);
166 				if (rtc == 0 || rtc > sizeof(szTempPath)) {
167 					tmppath = _T_TMPDIR;	/* use temporary directory */
168 				} else {
169 					tmppath = szTempPath;
170 				}
171 			}
172 		}
173 		strncpy(pager_file, tmppath, sizeof(pager_file) - 1);
174 	}
175 	if (pager_outputfile == NULL) {
176 		pager_outputfile = xstrdup(_T_OUTFILE_DEFAULT);
177 	}
178 	new_path = make_accesspath(pager_file);
179 	strncat(new_path, make_filename(pager_outputfile), (sizeof(pager_file) - 1) - strlen(new_path));
180 
181 	pager_fp = fopen(pager_file, "w");
182 	if (pager_fp == NULL) {
183 		errprint(NULL, ERR_ERROR, "can not open pager file %s", pager_file);
184 		if (pager_filekeep == TRUE) {
185 			errprint(NULL, ERR_INFO, "�ե����뤬�����Ǥ��ʤ��Τǡ���Ͽ�ե�����Ϻ������ޤ���");
186 		}
187 	}
188 #endif /* _T_WINDOWS */
189 }
190 
191 #if defined(_T_HUMAN68K) || defined(_T_MSDOS) || defined(_T_UNIX) || defined(_T_WIN32CONSOLE)
192 /*
193  * ������
194  *
195  * BUG: unix ��̤���ݡ���
196  *      curses ��Ĥ��äƼ���������ɤ��Τ����ɡ��ޥ����ʤ����餷�ʤ�
197  *      ����ˡ�unix �δĶ��ʤ鳰���ڡ�����������ɤ��Ȼפ�
198  */
199 static
pager_internal_pause(void)200 void pager_internal_pause(void)
201 {
202 #if defined(_T_HUMAN68K) || defined(_T_MSDOS) || defined(_T_WIN32CONSOLE)
203 #if defined(_T_WIN32CONSOLE)
204 #define PRINTF	printf
205 #else
206 #define PRINTF	cprintf
207 #endif
208 
209 	PRINTF("\033[7m--- more ---\033[0m");
210 	while (kbhit() != 0)
211 		getch();
212 	getch();
213 	PRINTF("\033[12D\033[K");
214 #endif /* _T_HUMAN68K || _T_MSDOS || _T_WIN32CONSOLE */
215 }
216 #endif /* _T_HUMAN68K || _T_MSDOS || _T_UNIX || _T_WIN32CONSOLE */
217 
218 /*
219  * �����ڡ����㡼�ε�ư
220  * ���ϥե�����κ��
221  *
222  * ���ϥե������CLOSE(win)
223  */
pager_term(void)224 void pager_term(void)
225 {
226 	if (pager_fp != NULL) {
227 		fclose(pager_fp);
228 		pager_fp = NULL;
229 	}
230 
231 #if defined(_T_HUMAN68K) || defined(_T_MSDOS) || defined(_T_UNIX) || defined(_T_WIN32CONSOLE)
232 	if (pager_cmd == NULL) {
233 		if (pager_lastpause == TRUE) {
234 			pager_internal_pause();
235 		}
236 	} else {
237 #if defined(_T_WIN32CONSOLE)
238 		STARTUPINFO	si;
239 		PROCESS_INFORMATION	pi;
240 		char	cmdbuf[_T_MAXPATHNAME + 128];
241 		const char	*cmdfmt;
242 
243 		ZeroMemory(&si, sizeof(si));
244 		ZeroMemory(&pi, sizeof(pi));
245 		si.cb = sizeof(si);
246 		si.dwFlags = STARTF_USESHOWWINDOW;
247 		si.wShowWindow = SW_SHOWNORMAL;
248 #if 1
249 		cmdfmt = "%s \"%s\"";
250 #else
251 		if (*pager_cmd == '"') {
252 			cmdfmt = "%s \"%s\"";
253 		} else {
254 			cmdfmt = "%s %s";
255 		}
256 #endif
257 		sprintf(cmdbuf, cmdfmt, pager_cmd, pager_file);
258 		if (CreateProcess(NULL, cmdbuf, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi) == FALSE) {
259 			errprint("pager", ERR_ERROR, "%s �����Ĥ���ޤ���", pager_cmd);
260 		} else {
261 			CloseHandle(pi.hThread);
262 			WaitForSingleObject(pi.hProcess, INFINITE);
263 			CloseHandle(pi.hProcess);
264 		}
265 #else /* _T_HUMAN68K || _T_MSDOS || _T_UNIX */
266 		char	*cmdbuf;
267 
268 		cmdbuf = xmalloc(strlen(pager_cmd) + 1 + strlen(pager_file) + 1);
269 		sprintf(cmdbuf, "%s %s", pager_cmd, pager_file);
270 		system(cmdbuf);
271 		free(cmdbuf);
272 #endif
273 	}
274 	if (pager_filekeep == FALSE) {
275 		REMOVE(pager_file);
276 	}
277 #endif /* _T_HUMAN68K || _T_MSDOS || _T_UNIX || _T_WIN32CONSOLE */
278 }
279 
280 /*
281  * �ץ�������ǽ���
282  *
283  * �����ץ���Υե����������
284  * delete_flag == TRUE �ΤȤ��ϥե������������
285  */
pager_clean(int delete_flag)286 void pager_clean(int delete_flag)
287 {
288 	if (pager_fp != NULL) {
289 		fclose(pager_fp);
290 		pager_fp = NULL;
291 		switch (delete_flag) {
292 		case TRUE:
293 			REMOVE(pager_file);
294 			errprint("pager", ERR_INFO, "������ե�����(%s)�������ޤ���", pager_file);
295 			break;
296 		case FALSE:
297 			errprint("pager", ERR_INFO, "������ե�����(%s)������ޤ��ΤǺ�����Ʋ�����", pager_file);
298 			break;
299 		}
300 	}
301 }
302 
303 /*
304  * ��å������Υե�����ؤν��Ф�
305  * �ƥ����ȥХåե��ؤγ�Ǽ
306  */
pager_output(const char * msg,...)307 void pager_output(const char *msg, ...)
308 {
309 	static char	linebuffer[MAXFOLDBUF];
310 	va_list	ap;
311 
312 	va_start(ap, msg);
313 	vsprintf(linebuffer, msg, ap);
314 	va_end(ap);
315 
316 	if (pager_fp != NULL) {
317 		fputs(linebuffer, pager_fp);
318 		if (fputc('\n', pager_fp) == EOF) {
319 			errprint("pager_output", ERR_ERROR, "�ե�����(%s)�˽��ϤǤ��ޤ��� errno = %d", pager_file, errno);
320 #if defined(_T_HUMAN68K) || defined(_T_MSDOS) || defined(_T_UNIX) || defined(_T_WIN32CONSOLE)
321 			terminate_program(TERM_FILEERROR);
322 #else /* _T_WINDOWS */
323 			fclose(pager_fp);
324 			pager_fp = NULL;
325 #endif
326 		}
327 	}
328 
329 	pager_out_flag = TRUE;
330 
331 #if defined(_T_HUMAN68K) || defined(_T_MSDOS) || defined(_T_UNIX) || defined(_T_WIN32CONSOLE)
332 	if (pager_cmd != NULL) {
333 		return ;
334 	}
335 	if (pager_pause == TRUE) {
336 		int	maxline;
337 
338 		maxline = strlen(linebuffer) / screen_max_columns + 1;
339 		line_count -= maxline;
340 		if (line_count <= 0) {
341 			line_count = screen_max_rows;
342 			pager_internal_pause();
343 			line_count -= maxline;
344 		}
345 	}
346 	puts(linebuffer);
347 #endif /* _T_HUMAN68K || _T_MSDOS || _T_UNIX || _T_WIN32CONSOLE */
348 #if defined(_T_WINDOWS)
349 #define TEXTBUFALLOC	16
350 	{
351 		if (textLines >= textLineAlloc) {
352 			textLineAlloc += TEXTBUFALLOC;
353 			textBuf = realloc(textBuf, sizeof(char **) * textLineAlloc);
354 			if (textBuf == NULL) {
355 				textLines = 0;
356 				textLineAlloc = 0;
357 				memerr("pager_output");
358 			}
359 		}
360 		textBuf[textLines++] = xstrdup(linebuffer);
361 	}
362 #endif /* _T_WINDOWS */
363 }
364 
365 /*
366  * 1�Ԥζ���������
367  */
pager_output_skip(void)368 void pager_output_skip(void)
369 {
370 	if (pager_out_flag != FALSE) {
371 		pager_output("");
372 		pager_out_flag = FALSE;
373 	}
374 }
375 
376 /*
377  * ��å���������ꤵ�줿��(width)���ޤ��֤���ɽ������
378  * �ޤ��֤��Ȥ��˶�§������Ԥ�
379  * ���Τ��ᡢ������(width)�Ϻ���ɽ�������� 3 �ʾ塢�������ʤ���Фʤ�ʤ�
380  * �ޤ����ǽ�ιԤ�ɽ���������� start1 �Ĥζ����ɽ������
381  * �����ޤ��֤�����ϡ�start2 �Ĥζ���θ�˥�å�������ɽ������
382  *
383  * BUG: \t, \033 �Ϥ��ޤ�ư��ʤ�����������Ѥ��������
384  */
message_fold(const unsigned char * msg,int width,int start1,int start2)385 void message_fold(const unsigned char *msg, int width, int start1, int start2)
386 {
387 	static unsigned char	tempbuf[MAXFOLDBUF];
388 	unsigned char	*bp;
389 	int	col, ncol;
390 	int	newline_flag;
391 	int	once_flag;
392 
393 	if (width >= (MAXFOLDLEN - 3)) {
394 		errprint("message_fold", ERR_WARN, "width(%d) >= MAXFOLDLEN(%d)", width, MAXFOLDLEN - 3);
395 		width = MAXFOLDLEN - 3;
396 	}
397 
398 	col = 0;
399 	for (bp = tempbuf; start1--; *bp++ = ' ', col++);
400 	*bp = '0';
401 	ncol = col;
402 	newline_flag = FALSE;
403 	once_flag = FALSE;
404 
405 	for (;;) {
406 		unsigned int	c;
407 		int	cbyte, cwidth;
408 
409 		c = getcharcode(msg, &cbyte, &cwidth);
410 		if (cbyte == 0 || c == '\0') {
411 			*bp = '\0';
412 			break;
413 		}
414 		msg += cbyte;
415 		switch (c) {
416 		case '\n':
417 		case '\r':
418 			newline_flag = TRUE;
419 			break;
420 		case '\t':
421 			ncol = (col + 8) & ~7;
422 			break;
423 		default:
424 			{
425 				const unsigned char	*brp, *oip;
426 				unsigned char	*hp;
427 
428 				brp = (const unsigned char *)"�����������ä������������å������������������������������������������������ǡɡˡ͡ϡۡѡӡաס٥����������å��硢��,.:;?!)]}��";
429 
430 				oip = (const unsigned char *)"�ơȡʡ̡ΡڡСҡԡ֡ء���������([{��";
431 
432 				hp = jstrchr(brp, c);
433 				if (hp != NULL && (col + cwidth) > width && once_flag == FALSE) {
434 					col -= cwidth;
435 					once_flag = TRUE;
436 				} else if (hp == NULL) {
437 					hp = jstrchr(oip, c);
438 					if (hp != NULL && col >= (width - cwidth)) {
439 						newline_flag = TRUE;
440 					}
441 				}
442 			}
443 
444 			ncol = col + cwidth;
445 		}
446 
447 		if (ncol > width || newline_flag == TRUE) {
448 			int	spccnt;
449 
450 			*bp = '\0';
451 			pager_output((char *)tempbuf);
452 			col = 0;
453 			for (bp = tempbuf, spccnt = start2; spccnt--; *bp++ = ' ', col++);
454 			*bp = '\0';
455 			newline_flag = FALSE;
456 			once_flag = FALSE;
457 		}
458 
459 		switch (c) {
460 		case '\n':
461 		case '\r':
462 			break;
463 		case '\t':
464 			col = (col + 8) & ~7;
465 			goto set_charcode;
466 		default:
467 			col += cwidth;
468 set_charcode:
469 			bp = putcharcode(bp, c, cbyte);
470 			break;
471 		}
472 	}
473 
474 	if (tempbuf[0] != '\0') {
475 		pager_output((char *)tempbuf);
476 	}
477 }
478