Calculate the screen size correctly. Allow a file name input.
[reactos.git] / rosapps / cmdutils / more / more.c
1 /*
2 * MORE.C - external command.
3 *
4 * clone from 4nt more command
5 *
6 * 26 Sep 1999 - Paolo Pantaleo <paolopan@freemail.it>
7 * started
8 * Oct 2003 - Timothy Schepens <tischepe at fastmail dot fm>
9 * use window size instead of buffer size.
10 */
11
12 #include <windows.h>
13 #include <malloc.h>
14 #include <tchar.h>
15
16
17 DWORD len;
18 LPTSTR msg = _T("--- continue ---");
19
20
21 /*handle for file and console*/
22 HANDLE hStdIn;
23 HANDLE hStdOut;
24 HANDLE hStdErr;
25 HANDLE hKeyboard;
26
27
28 static VOID
29 GetScreenSize (PSHORT maxx, PSHORT maxy)
30 {
31 CONSOLE_SCREEN_BUFFER_INFO csbi;
32
33 GetConsoleScreenBufferInfo (hStdOut, &csbi);
34 *maxx = (csbi.srWindow.Right - csbi.srWindow.Left) + 1;
35 *maxy = (csbi.srWindow.Bottom - csbi.srWindow.Top) - 4;
36
37 }
38
39
40 static
41 VOID ConOutPuts (LPTSTR szText)
42 {
43 DWORD dwWritten;
44
45 WriteFile (GetStdHandle (STD_OUTPUT_HANDLE), szText, _tcslen(szText), &dwWritten, NULL);
46 WriteFile (GetStdHandle (STD_OUTPUT_HANDLE), "\n", 1, &dwWritten, NULL);
47 }
48
49
50 static VOID
51 ConInKey (VOID)
52 {
53 INPUT_RECORD ir;
54 DWORD dwRead;
55
56 do
57 {
58 ReadConsoleInput (hKeyboard, &ir, 1, &dwRead);
59 if ((ir.EventType == KEY_EVENT) &&
60 (ir.Event.KeyEvent.bKeyDown == TRUE))
61 return;
62 }
63 while (TRUE);
64 }
65
66
67 static VOID
68 WaitForKey (VOID)
69 {
70 DWORD dwWritten;
71
72 WriteFile (hStdErr,msg , len, &dwWritten, NULL);
73
74 ConInKey();
75
76 WriteFile (hStdErr, _T("\n"), 1, &dwWritten, NULL);
77
78 // FlushConsoleInputBuffer (hConsoleIn);
79 }
80
81
82 //INT CommandMore (LPTSTR cmd, LPTSTR param)
83 int main (int argc, char **argv)
84 {
85 SHORT maxx,maxy;
86 SHORT line_count=0,ch_count=0;
87 INT i, last;
88 HANDLE hFile = INVALID_HANDLE_VALUE;
89 TCHAR szFullPath[MAX_PATH];
90
91 /*reading/writing buffer*/
92 TCHAR *buff;
93
94 /*bytes written by WriteFile and ReadFile*/
95 DWORD dwRead,dwWritten;
96
97 /*ReadFile() return value*/
98 BOOL bRet;
99
100 len = _tcslen (msg);
101 hStdIn = GetStdHandle(STD_INPUT_HANDLE);
102 hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
103 hStdErr = GetStdHandle(STD_ERROR_HANDLE);
104
105 if (argc > 1 && _tcsncmp (argv[1], _T("/?"), 2) == 0)
106 {
107 ConOutPuts(_T("Help text still missing!!"));
108 return 0;
109 }
110
111 hKeyboard = CreateFile (_T("CONIN$"), GENERIC_READ,
112 0,NULL,OPEN_ALWAYS,0,0);
113
114 GetScreenSize(&maxx,&maxy);
115
116 buff=malloc(4096);
117
118 FlushConsoleInputBuffer (hKeyboard);
119
120 if(argc > 1)
121 {
122 GetFullPathName(argv[1], MAX_PATH, szFullPath, NULL);
123 hFile = CreateFile (szFullPath, GENERIC_READ,
124 0,NULL,OPEN_ALWAYS,0,0);
125 }
126
127 do
128 {
129 if(hFile != INVALID_HANDLE_VALUE)
130 {
131 bRet = ReadFile(hFile,buff,4096,&dwRead,NULL);
132 }
133 else
134 {
135 bRet = ReadFile(hStdIn,buff,4096,&dwRead,NULL);
136 }
137
138 for(last=i=0;i<dwRead && bRet;i++)
139 {
140 ch_count++;
141 if(buff[i] == _T('\n') || ch_count == maxx)
142 {
143 ch_count=0;
144 line_count++;
145 if (line_count == maxy)
146 {
147 line_count = 0;
148 WriteFile(hStdOut,&buff[last], i-last+1, &dwWritten, NULL);
149 last=i+1;
150 FlushFileBuffers (hStdOut);
151 WaitForKey ();
152 }
153 }
154 }
155 if (last<dwRead && bRet)
156 WriteFile(hStdOut,&buff[last], dwRead-last, &dwWritten, NULL);
157
158 }
159 while(dwRead>0 && bRet);
160
161 free (buff);
162 CloseHandle (hKeyboard);
163 CloseHandle (hFile);
164
165 return 0;
166 }
167
168 /* EOF */