mirror of
https://github.com/reactos/reactos.git
synced 2024-11-20 14:30:57 +00:00
External TEE command.
svn path=/trunk/; revision=658
This commit is contained in:
parent
037d59aef7
commit
5249698af3
2 changed files with 269 additions and 0 deletions
46
rosapps/cmdutils/makefile
Normal file
46
rosapps/cmdutils/makefile
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
#
|
||||||
|
# ReactOS cmdutils makefile
|
||||||
|
#
|
||||||
|
|
||||||
|
TARGET=tee.exe
|
||||||
|
|
||||||
|
all: $(TARGET)
|
||||||
|
|
||||||
|
OBJECTS = tee.o
|
||||||
|
|
||||||
|
CLEAN_FILES = *.o *.exe *.sym *.coff
|
||||||
|
|
||||||
|
|
||||||
|
tee.exe: tee.o
|
||||||
|
$(CC) tee.o -lkernel32 -lcrtdll -o tee.exe
|
||||||
|
$(NM) --numeric-sort tee.exe > tee.sym
|
||||||
|
|
||||||
|
|
||||||
|
clean: $(CLEAN_FILES:%=%_clean)
|
||||||
|
|
||||||
|
$(CLEAN_FILES:%=%_clean): %_clean:
|
||||||
|
- $(RM) $*
|
||||||
|
|
||||||
|
.phony: clean $(CLEAN_FILES:%=%_clean)
|
||||||
|
|
||||||
|
|
||||||
|
floppy: $(TARGET:%=$(FLOPPY_DIR)/apps/%)
|
||||||
|
|
||||||
|
$(TARGET:%=$(FLOPPY_DIR)/apps/%): $(FLOPPY_DIR)/apps/%: %
|
||||||
|
ifeq ($(DOSCLI),yes)
|
||||||
|
$(CP) $* $(FLOPPY_DIR)\apps\$*
|
||||||
|
else
|
||||||
|
$(CP) $* $(FLOPPY_DIR)/apps/$*
|
||||||
|
endif
|
||||||
|
|
||||||
|
|
||||||
|
dist: $(TARGET:%=../$(DIST_DIR)/%)
|
||||||
|
|
||||||
|
$(TARGET:%=../$(DIST_DIR)/%): ../$(DIST_DIR)/%: %
|
||||||
|
ifeq ($(DOSCLI),yes)
|
||||||
|
$(CP) $* ..\$(DIST_DIR)\$*
|
||||||
|
else
|
||||||
|
$(CP) $* ../$(DIST_DIR)/$*
|
||||||
|
endif
|
||||||
|
|
||||||
|
include ../rules.mak
|
223
rosapps/cmdutils/tee.c
Normal file
223
rosapps/cmdutils/tee.c
Normal file
|
@ -0,0 +1,223 @@
|
||||||
|
/*
|
||||||
|
* TEE.C - external command.
|
||||||
|
*
|
||||||
|
* clone from 4nt tee command
|
||||||
|
*
|
||||||
|
* 01 Sep 1999 - Dr.F <dfaustus@freemail.it>
|
||||||
|
* started
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
#include <tchar.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <malloc.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#define TEE_BUFFER_SIZE 8192
|
||||||
|
|
||||||
|
/*these are function that emulate the ones used in cmd*/
|
||||||
|
|
||||||
|
/*many of them are just copied in this file from their
|
||||||
|
original location*/
|
||||||
|
|
||||||
|
VOID ConOutPuts (LPTSTR szText)
|
||||||
|
{
|
||||||
|
DWORD dwWritten;
|
||||||
|
|
||||||
|
WriteFile (GetStdHandle (STD_OUTPUT_HANDLE), szText, _tcslen(szText), &dwWritten, NULL);
|
||||||
|
#if 0
|
||||||
|
WriteFile (GetStdHandle (STD_OUTPUT_HANDLE), "\x0a\x0d", 2, &dwWritten, NULL);
|
||||||
|
#endif
|
||||||
|
WriteFile (GetStdHandle (STD_OUTPUT_HANDLE), "\n", 1, &dwWritten, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
VOID ConErrPrintf (LPTSTR szFormat, ...)
|
||||||
|
{
|
||||||
|
DWORD dwWritten;
|
||||||
|
TCHAR szOut[4096];
|
||||||
|
va_list arg_ptr;
|
||||||
|
|
||||||
|
va_start (arg_ptr, szFormat);
|
||||||
|
_vstprintf (szOut, szFormat, arg_ptr);
|
||||||
|
va_end (arg_ptr);
|
||||||
|
|
||||||
|
WriteFile (GetStdHandle (STD_ERROR_HANDLE), szOut, _tcslen(szOut), &dwWritten, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
VOID error_sfile_not_found (LPTSTR f)
|
||||||
|
{
|
||||||
|
ConErrPrintf (_T("Error opening file") _T(" - %s\n"), f);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
VOID ConErrPuts (LPTSTR szText)
|
||||||
|
{
|
||||||
|
ConErrPrintf("%s\n",szText );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
INT main (int argc,char **p)
|
||||||
|
{
|
||||||
|
/*reading/writing buffer*/
|
||||||
|
TCHAR buff[TEE_BUFFER_SIZE];
|
||||||
|
|
||||||
|
/*handle for file and console*/
|
||||||
|
HANDLE hConsoleIn,hConsoleOut;
|
||||||
|
|
||||||
|
/*bytes written by WriteFile and ReadFile*/
|
||||||
|
DWORD dwRead,dwWritten;
|
||||||
|
|
||||||
|
|
||||||
|
BOOL bRet,bAppend=FALSE;
|
||||||
|
|
||||||
|
|
||||||
|
/*command line parsing stuff*/
|
||||||
|
LPTSTR tmp;
|
||||||
|
INT i;
|
||||||
|
BOOL bQuote;
|
||||||
|
|
||||||
|
/*file list implementation*/
|
||||||
|
LPTSTR *files;
|
||||||
|
INT iFileCounter=0;
|
||||||
|
HANDLE *hFile;
|
||||||
|
|
||||||
|
/*used to remove '"' (if any)*/
|
||||||
|
INT add;
|
||||||
|
|
||||||
|
DWORD dw;
|
||||||
|
|
||||||
|
|
||||||
|
if (argc < 2)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
if (_tcsncmp (p[1], _T("/?"), 2) == 0)
|
||||||
|
{
|
||||||
|
ConOutPuts (_T("Copy standard input to both standard output and a file.\n"
|
||||||
|
"\n"
|
||||||
|
"TEE [/A] file...\n"
|
||||||
|
"\n"
|
||||||
|
" file One or more files that will receive output.\n"
|
||||||
|
" /A Append output to files.\n"));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
files = malloc(sizeof(LPTSTR)*argc);
|
||||||
|
hFile = malloc(sizeof(HANDLE)*argc);
|
||||||
|
|
||||||
|
hConsoleIn=GetStdHandle(STD_INPUT_HANDLE);
|
||||||
|
hConsoleOut=GetStdHandle(STD_OUTPUT_HANDLE);
|
||||||
|
|
||||||
|
/*parse command line for /a and file name(s)*/
|
||||||
|
for(i=1;i <argc;i++)
|
||||||
|
{
|
||||||
|
bQuote=FALSE;
|
||||||
|
add=0;
|
||||||
|
|
||||||
|
if(_tcsnicmp(p[i],_T("/a"),2) == 0)
|
||||||
|
{
|
||||||
|
bAppend = TRUE;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*remove quote if any*/
|
||||||
|
if (p[i][0] == _T('"'))
|
||||||
|
{
|
||||||
|
tmp = _tcschr (p[i]+1, _T('"'));
|
||||||
|
if (tmp != 0)
|
||||||
|
{
|
||||||
|
add = 1;
|
||||||
|
*tmp= _T('\0');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*add filename to array of filename*/
|
||||||
|
/*
|
||||||
|
if( iFileCounter >= sizeof(files) / sizeof(*files) )
|
||||||
|
{
|
||||||
|
ConErrPrintf("too many files, maximum is %d\n",sizeof(files) / sizeof(*files));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
files[iFileCounter++]= p[i]+add;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*open file(s)*/
|
||||||
|
for(i=0;i<iFileCounter;i++)
|
||||||
|
{
|
||||||
|
//l=0;
|
||||||
|
hFile[i] = CreateFile(files[i],GENERIC_WRITE,
|
||||||
|
0,NULL,
|
||||||
|
OPEN_ALWAYS,
|
||||||
|
FILE_ATTRIBUTE_NORMAL,NULL);
|
||||||
|
|
||||||
|
if (hFile[i] == INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
error_sfile_not_found (files[i]);
|
||||||
|
|
||||||
|
for(i=0;i<iFileCounter;i++)
|
||||||
|
CloseHandle (hFile[i]);
|
||||||
|
|
||||||
|
free (files);
|
||||||
|
free (hFile);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*set append mode*/
|
||||||
|
if (bAppend)
|
||||||
|
{
|
||||||
|
if (GetFileType (hFile[i]) == FILE_TYPE_DISK)
|
||||||
|
{
|
||||||
|
dw = SetFilePointer (hFile[i],0,NULL,FILE_END);
|
||||||
|
if (dw == 0xFFFFFFFF)
|
||||||
|
{
|
||||||
|
ConErrPrintf(_T("error moving to end of file %s"),files[i]);
|
||||||
|
|
||||||
|
for(i=0;i<iFileCounter;i++)
|
||||||
|
CloseHandle (hFile[i]);
|
||||||
|
|
||||||
|
free (files);
|
||||||
|
free (hFile);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
ConErrPrintf(_T("SetFilePointer() = %d\n"),dw);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*read and write*/
|
||||||
|
do
|
||||||
|
{
|
||||||
|
bRet = ReadFile(hConsoleIn,buff,sizeof(buff),&dwRead,NULL);
|
||||||
|
|
||||||
|
if (dwRead>0 && bRet)
|
||||||
|
{
|
||||||
|
for(i=0;i<iFileCounter;i++)
|
||||||
|
WriteFile(hFile[i],buff,dwRead,&dwWritten,NULL);
|
||||||
|
|
||||||
|
WriteFile(hConsoleOut,buff,dwRead,&dwWritten,NULL);
|
||||||
|
}
|
||||||
|
} while(dwRead>0 && bRet);
|
||||||
|
|
||||||
|
for(i=0;i<iFileCounter;i++)
|
||||||
|
CloseHandle (hFile[i]);
|
||||||
|
|
||||||
|
free (files);
|
||||||
|
free (hFile);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* EOF */
|
Loading…
Reference in a new issue