[TRANSLATION]
[reactos.git] / base / applications / 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 <stdio.h>
13 #include <malloc.h>
14 #include <tchar.h>
15
16 #include <windef.h>
17 #include <winbase.h>
18 #include <winuser.h>
19 #include <wincon.h>
20
21 #include "resource.h"
22
23 static TCHAR szCont[128];
24 static DWORD szContLength;
25 static HINSTANCE hApp;
26
27 /*handle for file and console*/
28 HANDLE hStdIn;
29 HANDLE hStdOut;
30 HANDLE hStdErr;
31 HANDLE hKeyboard;
32
33
34 static VOID
35 GetScreenSize (PSHORT maxx, PSHORT maxy)
36 {
37 CONSOLE_SCREEN_BUFFER_INFO csbi;
38
39 GetConsoleScreenBufferInfo (hStdOut, &csbi);
40 *maxx = (csbi.srWindow.Right - csbi.srWindow.Left) + 1;
41 *maxy = (csbi.srWindow.Bottom - csbi.srWindow.Top) - 4;
42
43 }
44
45
46 static
47 VOID ConOutPuts (LPTSTR szText)
48 {
49 DWORD dwWritten;
50
51 WriteFile (GetStdHandle (STD_OUTPUT_HANDLE), szText, _tcslen(szText), &dwWritten, NULL);
52 WriteFile (GetStdHandle (STD_OUTPUT_HANDLE), "\n", 1, &dwWritten, NULL);
53 }
54
55
56 static VOID
57 ConInKey (VOID)
58 {
59 INPUT_RECORD ir;
60 DWORD dwRead;
61
62 do
63 {
64 ReadConsoleInput (hKeyboard, &ir, 1, &dwRead);
65 if ((ir.EventType == KEY_EVENT) &&
66 (ir.Event.KeyEvent.bKeyDown == TRUE))
67 return;
68 }
69 while (TRUE);
70 }
71
72
73 static VOID
74 WaitForKey (VOID)
75 {
76 DWORD dwWritten;
77
78 WriteFile (hStdErr, szCont , szContLength, &dwWritten, NULL);
79
80 ConInKey();
81
82 WriteFile (hStdErr, _T("\n"), 1, &dwWritten, NULL);
83
84 // FlushConsoleInputBuffer (hConsoleIn);
85 }
86
87
88 //INT CommandMore (LPTSTR cmd, LPTSTR param)
89 int main (int argc, char **argv)
90 {
91 SHORT maxx,maxy;
92 SHORT line_count=0,ch_count=0;
93 DWORD i, last;
94 HANDLE hFile = INVALID_HANDLE_VALUE;
95 TCHAR szFullPath[MAX_PATH];
96 TCHAR szMsg[1024];
97 /*reading/writing buffer*/
98 TCHAR *buff;
99
100 /*bytes written by WriteFile and ReadFile*/
101 DWORD dwRead,dwWritten;
102
103 /*ReadFile() return value*/
104 BOOL bRet;
105
106
107 hStdIn = GetStdHandle(STD_INPUT_HANDLE);
108 hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
109 hStdErr = GetStdHandle(STD_ERROR_HANDLE);
110 hApp = GetModuleHandle(NULL);
111
112 buff=malloc(4096);
113 if (!buff)
114 {
115 ConOutPuts(_T("Error: no memory"));
116 return 1;
117 }
118
119 if (argc > 1 && _tcsncmp (argv[1], _T("/?"), 2) == 0)
120 {
121 if (LoadString(hApp, IDS_USAGE, buff, 4096 / sizeof(TCHAR)) < (int)(4096 / sizeof(TCHAR)))
122 {
123 CharToOem(buff, buff);
124 ConOutPuts(buff);
125 }
126
127 free(buff);
128 return 0;
129 }
130
131 hKeyboard = CreateFile (_T("CONIN$"), GENERIC_READ|GENERIC_WRITE,
132 0,NULL,OPEN_ALWAYS,0,0);
133
134 GetScreenSize(&maxx,&maxy);
135
136
137
138 FlushConsoleInputBuffer (hKeyboard);
139
140 if(argc > 1)
141 {
142 GetFullPathNameA(argv[1], MAX_PATH, szFullPath, NULL);
143 hFile = CreateFile (szFullPath,
144 GENERIC_READ,
145 0,
146 NULL,
147 OPEN_EXISTING,
148 0,
149 0);
150 if (hFile == INVALID_HANDLE_VALUE)
151 {
152 if (LoadString(hApp, IDS_FILE_ACCESS, szMsg, sizeof(szMsg) / sizeof(TCHAR)) < (int)(sizeof(szMsg) / sizeof(TCHAR)))
153 {
154 _stprintf(buff, szMsg, szFullPath);
155 CharToOem(buff, buff);
156 ConOutPuts(buff);
157 }
158
159 free(buff);
160 return 0;
161 }
162 }
163 else
164 {
165 hFile = hStdIn;
166 }
167
168 if (!LoadString(hApp, IDS_CONTINUE, szCont, sizeof(szCont) / sizeof(TCHAR)))
169 {
170 /* Shouldn't happen, so exit */
171 free(buff);
172 return 1;
173 }
174 szContLength = _tcslen(szCont);
175
176
177
178 do
179 {
180 bRet = ReadFile(hFile,buff,4096,&dwRead,NULL);
181
182 for(last=i=0;i<dwRead && bRet;i++)
183 {
184 ch_count++;
185 if(buff[i] == _T('\n') || ch_count == maxx)
186 {
187 ch_count=0;
188 line_count++;
189 if (line_count == maxy)
190 {
191 line_count = 0;
192 WriteFile(hStdOut,&buff[last], i-last+1, &dwWritten, NULL);
193 last=i+1;
194 FlushFileBuffers (hStdOut);
195 WaitForKey ();
196 }
197 }
198 }
199 if (last<dwRead && bRet)
200 WriteFile(hStdOut,&buff[last], dwRead-last, &dwWritten, NULL);
201
202 }
203 while(dwRead>0 && bRet);
204
205 free (buff);
206 CloseHandle (hKeyboard);
207 if (hFile != hStdIn)
208 CloseHandle (hFile);
209
210 return 0;
211 }
212
213 /* EOF */