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