1*c2c66affSColin Finck /*
2*c2c66affSColin Finck  * TEE.C - external command.
3*c2c66affSColin Finck  *
4*c2c66affSColin Finck  * clone from 4nt tee command
5*c2c66affSColin Finck  *
6*c2c66affSColin Finck  * 01 Sep 1999 - Paolo Pantaleo <paolopan@freemail.it>
7*c2c66affSColin Finck  *     started
8*c2c66affSColin Finck  *
9*c2c66affSColin Finck  *
10*c2c66affSColin Finck  */
11*c2c66affSColin Finck 
12*c2c66affSColin Finck 
13*c2c66affSColin Finck #include <windows.h>
14*c2c66affSColin Finck #include <tchar.h>
15*c2c66affSColin Finck #include <stdio.h>
16*c2c66affSColin Finck #include <malloc.h>
17*c2c66affSColin Finck 
18*c2c66affSColin Finck 
19*c2c66affSColin Finck 
20*c2c66affSColin Finck #define TEE_BUFFER_SIZE 8192
21*c2c66affSColin Finck 
22*c2c66affSColin Finck /*these are function that emulate the ones used in cmd*/
23*c2c66affSColin Finck 
24*c2c66affSColin Finck /*many of them are just copied in this file from their
25*c2c66affSColin Finck original location*/
26*c2c66affSColin Finck 
ConOutPuts(LPTSTR szText)27*c2c66affSColin Finck VOID ConOutPuts (LPTSTR szText)
28*c2c66affSColin Finck {
29*c2c66affSColin Finck 	DWORD dwWritten;
30*c2c66affSColin Finck 
31*c2c66affSColin Finck 	WriteFile (GetStdHandle (STD_OUTPUT_HANDLE), szText, _tcslen(szText), &dwWritten, NULL);
32*c2c66affSColin Finck 	WriteFile (GetStdHandle (STD_OUTPUT_HANDLE), _T("\n"), 1, &dwWritten, NULL);
33*c2c66affSColin Finck }
34*c2c66affSColin Finck 
35*c2c66affSColin Finck 
ConErrPrintf(LPTSTR szFormat,...)36*c2c66affSColin Finck VOID ConErrPrintf (LPTSTR szFormat, ...)
37*c2c66affSColin Finck {
38*c2c66affSColin Finck 	DWORD dwWritten;
39*c2c66affSColin Finck 	TCHAR szOut[4096];
40*c2c66affSColin Finck 	va_list arg_ptr;
41*c2c66affSColin Finck 
42*c2c66affSColin Finck 	va_start (arg_ptr, szFormat);
43*c2c66affSColin Finck 	_vstprintf (szOut, szFormat, arg_ptr);
44*c2c66affSColin Finck 	va_end (arg_ptr);
45*c2c66affSColin Finck 
46*c2c66affSColin Finck 	WriteFile (GetStdHandle (STD_ERROR_HANDLE), szOut, _tcslen(szOut), &dwWritten, NULL);
47*c2c66affSColin Finck }
48*c2c66affSColin Finck 
49*c2c66affSColin Finck 
50*c2c66affSColin Finck 
error_sfile_not_found(LPTSTR f)51*c2c66affSColin Finck VOID error_sfile_not_found (LPTSTR f)
52*c2c66affSColin Finck {
53*c2c66affSColin Finck 	ConErrPrintf (_T("Error opening file") _T(" - %s\n"), f);
54*c2c66affSColin Finck }
55*c2c66affSColin Finck 
56*c2c66affSColin Finck 
57*c2c66affSColin Finck 
58*c2c66affSColin Finck 
ConErrPuts(LPTSTR szText)59*c2c66affSColin Finck VOID ConErrPuts (LPTSTR szText)
60*c2c66affSColin Finck {
61*c2c66affSColin Finck 	ConErrPrintf(_T("%s\n"),szText );
62*c2c66affSColin Finck }
63*c2c66affSColin Finck 
64*c2c66affSColin Finck 
main(int argc,char ** p)65*c2c66affSColin Finck INT main (int argc,char **p)
66*c2c66affSColin Finck {
67*c2c66affSColin Finck 	/*reading/writing buffer*/
68*c2c66affSColin Finck 	TCHAR buff[TEE_BUFFER_SIZE];
69*c2c66affSColin Finck 
70*c2c66affSColin Finck 	/*handle for file and console*/
71*c2c66affSColin Finck 	HANDLE hConsoleIn,hConsoleOut;
72*c2c66affSColin Finck 
73*c2c66affSColin Finck 	/*bytes written by WriteFile and ReadFile*/
74*c2c66affSColin Finck 	DWORD dwRead,dwWritten;
75*c2c66affSColin Finck 
76*c2c66affSColin Finck 
77*c2c66affSColin Finck 	BOOL bRet,bAppend=FALSE;
78*c2c66affSColin Finck 
79*c2c66affSColin Finck 
80*c2c66affSColin Finck 	/*command line parsing stuff*/
81*c2c66affSColin Finck 	LPTSTR tmp;
82*c2c66affSColin Finck 	INT i;
83*c2c66affSColin Finck 	//BOOL bQuote;
84*c2c66affSColin Finck 
85*c2c66affSColin Finck 	/*file list implementation*/
86*c2c66affSColin Finck 	LPTSTR *files;
87*c2c66affSColin Finck 	INT iFileCounter=0;
88*c2c66affSColin Finck 	HANDLE *hFile;
89*c2c66affSColin Finck 
90*c2c66affSColin Finck 	/*used to remove '"' (if any)*/
91*c2c66affSColin Finck 	INT add;
92*c2c66affSColin Finck 
93*c2c66affSColin Finck 	DWORD dw;
94*c2c66affSColin Finck 
95*c2c66affSColin Finck 
96*c2c66affSColin Finck 	if (argc < 2)
97*c2c66affSColin Finck 		return 1;
98*c2c66affSColin Finck 
99*c2c66affSColin Finck 	if (_tcsncmp (p[1], _T("/?"), 2) == 0)
100*c2c66affSColin Finck 	{
101*c2c66affSColin Finck 		ConOutPuts (_T("Copy standard input to both standard output and a file.\n"
102*c2c66affSColin Finck 		               "\n"
103*c2c66affSColin Finck 		               "TEE [/A] file...\n"
104*c2c66affSColin Finck 		               "\n"
105*c2c66affSColin Finck 		               "  file  One or more files that will receive output.\n"
106*c2c66affSColin Finck 		               "  /A    Append output to files.\n"));
107*c2c66affSColin Finck 		return 0;
108*c2c66affSColin Finck 	}
109*c2c66affSColin Finck 
110*c2c66affSColin Finck 	files = malloc(sizeof(LPTSTR)*argc);
111*c2c66affSColin Finck 	hFile = malloc(sizeof(HANDLE)*argc);
112*c2c66affSColin Finck 
113*c2c66affSColin Finck 	hConsoleIn=GetStdHandle(STD_INPUT_HANDLE);
114*c2c66affSColin Finck 	hConsoleOut=GetStdHandle(STD_OUTPUT_HANDLE);
115*c2c66affSColin Finck 
116*c2c66affSColin Finck 	/*parse command line for /a and file name(s)*/
117*c2c66affSColin Finck 	for(i=1;i <argc;i++)
118*c2c66affSColin Finck 	{
119*c2c66affSColin Finck 		//bQuote=FALSE;
120*c2c66affSColin Finck 		add=0;
121*c2c66affSColin Finck 
122*c2c66affSColin Finck 		if(_tcsnicmp(p[i],_T("/a"),2) == 0)
123*c2c66affSColin Finck 		{
124*c2c66affSColin Finck 			bAppend = TRUE;
125*c2c66affSColin Finck 			continue;
126*c2c66affSColin Finck 		}
127*c2c66affSColin Finck 
128*c2c66affSColin Finck 		/*remove quote if any*/
129*c2c66affSColin Finck 		if (p[i][0] == _T('"'))
130*c2c66affSColin Finck 		{
131*c2c66affSColin Finck 			tmp = _tcschr (p[i]+1, _T('"'));
132*c2c66affSColin Finck 			if (tmp != 0)
133*c2c66affSColin Finck 			{
134*c2c66affSColin Finck 				add = 1;
135*c2c66affSColin Finck 				*tmp= _T('\0');
136*c2c66affSColin Finck 			}
137*c2c66affSColin Finck 		}
138*c2c66affSColin Finck 
139*c2c66affSColin Finck 		/*add filename to array of filename*/
140*c2c66affSColin Finck /*
141*c2c66affSColin Finck 		if(  iFileCounter >= sizeof(files) / sizeof(*files)  )
142*c2c66affSColin Finck 		{
143*c2c66affSColin Finck 			ConErrPrintf("too many files, maximum is %d\n",sizeof(files) / sizeof(*files));
144*c2c66affSColin Finck 			return 1;
145*c2c66affSColin Finck 		}
146*c2c66affSColin Finck 		*/
147*c2c66affSColin Finck 
148*c2c66affSColin Finck 		files[iFileCounter++]= p[i]+add;
149*c2c66affSColin Finck 	}
150*c2c66affSColin Finck 
151*c2c66affSColin Finck 	/*open file(s)*/
152*c2c66affSColin Finck 	for(i=0;i<iFileCounter;i++)
153*c2c66affSColin Finck 	{
154*c2c66affSColin Finck 		//l=0;
155*c2c66affSColin Finck 		hFile[i] = CreateFile(files[i],GENERIC_WRITE,
156*c2c66affSColin Finck 			0,NULL,
157*c2c66affSColin Finck 			CREATE_ALWAYS,
158*c2c66affSColin Finck 			FILE_ATTRIBUTE_NORMAL,NULL);
159*c2c66affSColin Finck 
160*c2c66affSColin Finck 		if (hFile[i] == INVALID_HANDLE_VALUE)
161*c2c66affSColin Finck 		{
162*c2c66affSColin Finck 			error_sfile_not_found (files[i]);
163*c2c66affSColin Finck 
164*c2c66affSColin Finck 			for(i=0;i<iFileCounter;i++)
165*c2c66affSColin Finck 				CloseHandle (hFile[i]);
166*c2c66affSColin Finck 
167*c2c66affSColin Finck 			free (files);
168*c2c66affSColin Finck 			free (hFile);
169*c2c66affSColin Finck 
170*c2c66affSColin Finck 			return 1;
171*c2c66affSColin Finck 		}
172*c2c66affSColin Finck 
173*c2c66affSColin Finck 		/*set append mode*/
174*c2c66affSColin Finck 		if (bAppend)
175*c2c66affSColin Finck 		{
176*c2c66affSColin Finck 			if (GetFileType (hFile[i]) == FILE_TYPE_DISK)
177*c2c66affSColin Finck 			{
178*c2c66affSColin Finck 				dw = SetFilePointer (hFile[i],0,NULL,FILE_END);
179*c2c66affSColin Finck 				if (dw == 0xFFFFFFFF)
180*c2c66affSColin Finck 				{
181*c2c66affSColin Finck 					ConErrPrintf(_T("error moving to end of file %s"),files[i]);
182*c2c66affSColin Finck 
183*c2c66affSColin Finck 					for(i=0;i<iFileCounter;i++)
184*c2c66affSColin Finck 						CloseHandle (hFile[i]);
185*c2c66affSColin Finck 
186*c2c66affSColin Finck 					free (files);
187*c2c66affSColin Finck 					free (hFile);
188*c2c66affSColin Finck 
189*c2c66affSColin Finck 					return 1;
190*c2c66affSColin Finck 				}
191*c2c66affSColin Finck 
192*c2c66affSColin Finck 				ConErrPrintf(_T("SetFilePointer() = %d\n"),dw);
193*c2c66affSColin Finck 			}
194*c2c66affSColin Finck 		}
195*c2c66affSColin Finck 	}
196*c2c66affSColin Finck 
197*c2c66affSColin Finck 	/*read and write*/
198*c2c66affSColin Finck 	do
199*c2c66affSColin Finck 	{
200*c2c66affSColin Finck 		bRet = ReadFile(hConsoleIn,buff,sizeof(buff),&dwRead,NULL);
201*c2c66affSColin Finck 
202*c2c66affSColin Finck 		if (dwRead>0 && bRet)
203*c2c66affSColin Finck 		{
204*c2c66affSColin Finck 			for(i=0;i<iFileCounter;i++)
205*c2c66affSColin Finck 				WriteFile(hFile[i],buff,dwRead,&dwWritten,NULL);
206*c2c66affSColin Finck 
207*c2c66affSColin Finck 			WriteFile(hConsoleOut,buff,dwRead,&dwWritten,NULL);
208*c2c66affSColin Finck 		}
209*c2c66affSColin Finck 	} while(dwRead>0 && bRet);
210*c2c66affSColin Finck 
211*c2c66affSColin Finck 	for(i=0;i<iFileCounter;i++)
212*c2c66affSColin Finck 		CloseHandle (hFile[i]);
213*c2c66affSColin Finck 
214*c2c66affSColin Finck 	free (files);
215*c2c66affSColin Finck 	free (hFile);
216*c2c66affSColin Finck 
217*c2c66affSColin Finck 	return 0;
218*c2c66affSColin Finck }
219*c2c66affSColin Finck 
220*c2c66affSColin Finck /* EOF */
221