mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
420 lines
8.2 KiB
420 lines
8.2 KiB
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#define INCL_NETNMPIPE
|
|
#include <lan.h>
|
|
|
|
#include <share.h>
|
|
#include <fcntl.h>
|
|
#include <io.h>
|
|
#include <errno.h>
|
|
#include <conio.h>
|
|
#include <signal.h>
|
|
|
|
#define Dbgprintf // Disable verbose output
|
|
|
|
#define PIPE_NAME "\\pipe\\rshell"
|
|
|
|
#define PIPE_BUFFER_SIZE 1000
|
|
#define INPUT_BUFFER_SIZE 256
|
|
|
|
#define STDIN 0
|
|
#define STDOUT 1
|
|
#define STDERR 2
|
|
|
|
|
|
//
|
|
// Private prototypes
|
|
//
|
|
|
|
void *
|
|
CtrlCHandler(
|
|
int Signal
|
|
);
|
|
|
|
void far pascal _loadds
|
|
PipeReadFn(
|
|
unsigned long Param
|
|
);
|
|
|
|
|
|
//
|
|
// Globals
|
|
//
|
|
|
|
int SendCtrlC = 0;
|
|
int GotPipeData = 0;
|
|
|
|
|
|
|
|
|
|
//
|
|
// Main function
|
|
//
|
|
|
|
|
|
main(int argc, char **argv)
|
|
{
|
|
char ServerPipeName[_MAX_PATH];
|
|
int PipeHandle;
|
|
unsigned char InputBuffer[INPUT_BUFFER_SIZE];
|
|
int InputBytesRead;
|
|
int BytesWritten;
|
|
int Result;
|
|
int PipeStatus;
|
|
int Done;
|
|
|
|
//
|
|
// Pipe read data
|
|
//
|
|
|
|
unsigned char PipeReadBuffer[PIPE_BUFFER_SIZE];
|
|
unsigned short PipeReadError;
|
|
unsigned short PipeBytesRead;
|
|
|
|
//
|
|
// Check usage
|
|
//
|
|
|
|
if (argc < 2) {
|
|
printf("Usage: rcmd server_name\n");
|
|
printf("Note : server name should include leading '\\\\'s\n");
|
|
return(1);
|
|
}
|
|
|
|
strcpy(ServerPipeName, argv[1]);
|
|
strcat(ServerPipeName, PIPE_NAME);
|
|
|
|
//
|
|
// Install a handler for Ctrl-C. We want to catch it and send
|
|
// the appropriate chars to the server
|
|
//
|
|
|
|
if (signal(SIGINT, CtrlCHandler) == SIG_ERR) {
|
|
printf("Failed to set Ctrl-C handler\n");
|
|
return(1);
|
|
}
|
|
|
|
//
|
|
// Open the server pipe
|
|
//
|
|
|
|
PipeHandle = _sopen(ServerPipeName, O_BINARY | O_RDWR, SH_DENYRW);
|
|
|
|
if (PipeHandle == -1) {
|
|
printf("Error occurred opening pipe <%s>, errno = %d\n", ServerPipeName, errno);
|
|
return(1);
|
|
}
|
|
|
|
//
|
|
// Let the user know how it's going
|
|
//
|
|
|
|
printf("Connected to %s\n\n", argv[1]);
|
|
|
|
|
|
//
|
|
// Initialize pipe read data so we immediately start an async read
|
|
//
|
|
|
|
GotPipeData = 1;
|
|
PipeReadError = 0;
|
|
PipeBytesRead = 0;
|
|
|
|
//
|
|
// Initialize the input buffer data
|
|
//
|
|
|
|
InputBytesRead = 0;
|
|
|
|
|
|
//
|
|
// Loop until we're disconnected or the user presses the exit key.
|
|
//
|
|
|
|
Done = 0;
|
|
|
|
while (!Done) {
|
|
|
|
//
|
|
// See if we got anything from the pipe
|
|
//
|
|
|
|
if (GotPipeData) {
|
|
|
|
//
|
|
// The data is in our pipe read buffer
|
|
//
|
|
|
|
if (PipeReadError != 0) {
|
|
Dbgprintf("Pipe read failed, error = %d\n", PipeReadError);
|
|
Done = 1;
|
|
break;
|
|
}
|
|
|
|
if (PipeBytesRead != 0) {
|
|
|
|
BytesWritten = write(STDOUT, (void *)PipeReadBuffer, PipeBytesRead);
|
|
|
|
if (BytesWritten == -1) {
|
|
printf("Error occurred writing stdout, errno = %d\n", errno);
|
|
Done = 1;
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Restart the async pipe read
|
|
//
|
|
|
|
GotPipeData = 0;
|
|
Result = DosReadAsyncNmPipe(PipeHandle,
|
|
PipeReadFn,
|
|
&PipeReadError,
|
|
PipeReadBuffer,
|
|
sizeof(PipeReadBuffer),
|
|
&PipeBytesRead);
|
|
if (Result != 0) {
|
|
Dbgprintf("Async pipe read failed, error = %d\n", Result);
|
|
Done = 1;
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
//
|
|
// Check for Ctrl-C input
|
|
//
|
|
|
|
if (SendCtrlC) {
|
|
|
|
char c = 0x03;
|
|
|
|
BytesWritten = write(PipeHandle, (void *)&c, sizeof(c));
|
|
|
|
if (BytesWritten == -1) {
|
|
Dbgprintf("Error occurred writing pipe, errno = %d\n", errno);
|
|
Done = 1;
|
|
break;
|
|
}
|
|
|
|
SendCtrlC = 0;
|
|
|
|
//
|
|
// Clear the input buffer
|
|
//
|
|
|
|
InputBytesRead = 0;
|
|
}
|
|
|
|
|
|
//
|
|
// Get input from the keyboard
|
|
//
|
|
|
|
while (_kbhit() && !Done) {
|
|
|
|
//
|
|
// If the input buffer's full, send it
|
|
//
|
|
|
|
if (InputBytesRead >= (sizeof(InputBuffer) - 2)) {
|
|
|
|
//
|
|
// Write out the whole input buffer to the pipe
|
|
//
|
|
|
|
BytesWritten = write(PipeHandle, (void *)InputBuffer, InputBytesRead);
|
|
|
|
if (BytesWritten == -1) {
|
|
Dbgprintf("Error occurred writing pipe, errno = %d\n", errno);
|
|
Done = 1;
|
|
break;
|
|
}
|
|
|
|
InputBytesRead = 0;
|
|
}
|
|
|
|
|
|
//
|
|
// Get the input character and add it to buffer
|
|
//
|
|
|
|
InputBuffer[InputBytesRead++] = (char)_getch();
|
|
|
|
|
|
//
|
|
// Handle special characters
|
|
//
|
|
|
|
switch (InputBuffer[InputBytesRead - 1]) {
|
|
|
|
case '\r':
|
|
|
|
//
|
|
// Convert CR to CRLF
|
|
//
|
|
|
|
InputBuffer[InputBytesRead++] = '\n';
|
|
|
|
//
|
|
// Echo the CRLF
|
|
//
|
|
|
|
BytesWritten = write(STDOUT, &InputBuffer[InputBytesRead-2], 2);
|
|
|
|
if (BytesWritten == -1) {
|
|
Dbgprintf("Error occurred writing stdout, errno = %d\n", errno);
|
|
Done = 1;
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Send the input buffer
|
|
//
|
|
|
|
BytesWritten = write(PipeHandle, (void *)InputBuffer, InputBytesRead);
|
|
|
|
if (BytesWritten == -1) {
|
|
Dbgprintf("Error occurred writing pipe, errno = %d\n", errno);
|
|
Done = 1;
|
|
break;
|
|
}
|
|
|
|
InputBytesRead = 0;
|
|
break;
|
|
|
|
|
|
case '\010':
|
|
|
|
//
|
|
// Delete (Ctrl-H)
|
|
//
|
|
|
|
InputBytesRead --; // Remove the Delete char from buffer
|
|
|
|
if (InputBytesRead > 0) {
|
|
|
|
char *deletestring = "\010 \010";
|
|
|
|
InputBytesRead --; // Remove previous char from buffer
|
|
|
|
//
|
|
// Erase previous character on line
|
|
//
|
|
|
|
BytesWritten = write(STDOUT, (void *)deletestring, strlen(deletestring));
|
|
|
|
if (BytesWritten == -1) {
|
|
Dbgprintf("Error occurred writing stdout, errno = %d\n", errno);
|
|
Done = 1;
|
|
}
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 0:
|
|
case 0xe0:
|
|
|
|
//
|
|
// Cursor/function key - go get the second part of it
|
|
//
|
|
|
|
InputBuffer[InputBytesRead++] = (char)_getch();
|
|
|
|
//
|
|
// Check for our exit key (F3)
|
|
//
|
|
|
|
if (InputBuffer[InputBytesRead-1] == 0x3d) {
|
|
Done = 1;
|
|
break;
|
|
}
|
|
|
|
//
|
|
// Remove the cursor key from the input buffer
|
|
//
|
|
|
|
InputBytesRead -= 2;
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
//
|
|
// Echo the character
|
|
//
|
|
|
|
BytesWritten = write(STDOUT, &InputBuffer[InputBytesRead-1], 1);
|
|
|
|
if (BytesWritten == -1) {
|
|
Dbgprintf("Error occurred writing stdout, errno = %d\n", errno);
|
|
Done = 1;
|
|
}
|
|
break;
|
|
|
|
|
|
|
|
} // switch
|
|
|
|
} // while(kdhit() && !Done)
|
|
|
|
} // while(!Done)
|
|
|
|
|
|
|
|
if (close(PipeHandle) == -1) {
|
|
printf("Error closing pipe, errno = %d\n", errno);
|
|
}
|
|
|
|
|
|
printf("\nDisconnected from %s\n", argv[1]);
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
|
|
//
|
|
// CtrlCHandler
|
|
//
|
|
|
|
void *
|
|
CtrlCHandler(
|
|
int Signal
|
|
)
|
|
{
|
|
//
|
|
// Set our global so we send a Ctrl-C real-soon
|
|
//
|
|
|
|
SendCtrlC = 1;
|
|
|
|
//
|
|
// Re-establish the signal handler
|
|
//
|
|
|
|
signal(SIGINT, CtrlCHandler);
|
|
|
|
return(NULL);
|
|
}
|
|
|
|
|
|
|
|
//
|
|
// Async pipe read completion handler
|
|
//
|
|
|
|
void far pascal _loadds
|
|
PipeReadFn(
|
|
unsigned long Param
|
|
)
|
|
{
|
|
GotPipeData = 1;
|
|
}
|