|
|
1.1 root 1:
2: #include <stdio.h>
3: #include <stdlib.h>
4: #include <string.h>
5:
6: #define INCL_NETNMPIPE
7: #include <lan.h>
8:
9: #include <share.h>
10: #include <fcntl.h>
11: #include <io.h>
12: #include <errno.h>
13: #include <conio.h>
14: #include <signal.h>
15:
16: #define Dbgprintf // Disable verbose output
17:
18: #define PIPE_NAME "\\pipe\\rshell"
19:
20: #define PIPE_BUFFER_SIZE 1000
21: #define INPUT_BUFFER_SIZE 256
22:
23: #define STDIN 0
24: #define STDOUT 1
25: #define STDERR 2
26:
27:
28: //
29: // Private prototypes
30: //
31:
32: void *
33: CtrlCHandler(
34: int Signal
35: );
36:
37: void far pascal _loadds
38: PipeReadFn(
39: unsigned long Param
40: );
41:
42:
43: //
44: // Globals
45: //
46:
47: int SendCtrlC = 0;
48: int GotPipeData = 0;
49:
50:
51:
52:
53: //
54: // Main function
55: //
56:
57:
58: main(int argc, char **argv)
59: {
60: char ServerPipeName[_MAX_PATH];
61: int PipeHandle;
62: unsigned char InputBuffer[INPUT_BUFFER_SIZE];
63: int InputBytesRead;
64: int BytesWritten;
65: int Result;
66: int PipeStatus;
67: int Done;
68:
69: //
70: // Pipe read data
71: //
72:
73: unsigned char PipeReadBuffer[PIPE_BUFFER_SIZE];
74: unsigned short PipeReadError;
75: unsigned short PipeBytesRead;
76:
77: //
78: // Check usage
79: //
80:
81: if (argc < 2) {
82: printf("Usage: rcmd server_name\n");
83: printf("Note : server name should include leading '\\\\'s\n");
84: return(1);
85: }
86:
87: strcpy(ServerPipeName, argv[1]);
88: strcat(ServerPipeName, PIPE_NAME);
89:
90: //
91: // Install a handler for Ctrl-C. We want to catch it and send
92: // the appropriate chars to the server
93: //
94:
95: if (signal(SIGINT, CtrlCHandler) == SIG_ERR) {
96: printf("Failed to set Ctrl-C handler\n");
97: return(1);
98: }
99:
100: //
101: // Open the server pipe
102: //
103:
104: PipeHandle = sopen(ServerPipeName, O_BINARY | O_RDWR, SH_DENYRW);
105:
106: if (PipeHandle == -1) {
107: printf("Error occurred opening pipe <%s>, errno = %d\n", ServerPipeName, errno);
108: return(1);
109: }
110:
111: //
112: // Let the user know how it's going
113: //
114:
115: printf("Connected to %s\n\n", argv[1]);
116:
117:
118: //
119: // Initialize pipe read data so we immediately start an async read
120: //
121:
122: GotPipeData = 1;
123: PipeReadError = 0;
124: PipeBytesRead = 0;
125:
126: //
127: // Initialize the input buffer data
128: //
129:
130: InputBytesRead = 0;
131:
132:
133: //
134: // Loop until we're disconnected or the user presses the exit key.
135: //
136:
137: Done = 0;
138:
139: while (!Done) {
140:
141: //
142: // See if we got anything from the pipe
143: //
144:
145: if (GotPipeData) {
146:
147: //
148: // The data is in our pipe read buffer
149: //
150:
151: if (PipeReadError != 0) {
152: Dbgprintf("Pipe read failed, error = %d\n", PipeReadError);
153: Done = 1;
154: break;
155: }
156:
157: if (PipeBytesRead != 0) {
158:
159: BytesWritten = write(STDOUT, (void *)PipeReadBuffer, PipeBytesRead);
160:
161: if (BytesWritten == -1) {
162: printf("Error occurred writing stdout, errno = %d\n", errno);
163: Done = 1;
164: break;
165: }
166: }
167:
168: //
169: // Restart the async pipe read
170: //
171:
172: GotPipeData = 0;
173: Result = DosReadAsyncNmPipe(PipeHandle,
174: PipeReadFn,
175: &PipeReadError,
176: PipeReadBuffer,
177: sizeof(PipeReadBuffer),
178: &PipeBytesRead);
179: if (Result != 0) {
180: Dbgprintf("Async pipe read failed, error = %d\n", Result);
181: Done = 1;
182: break;
183: }
184: }
185:
186:
187: //
188: // Check for Ctrl-C input
189: //
190:
191: if (SendCtrlC) {
192:
193: char c = 0x03;
194:
195: BytesWritten = write(PipeHandle, (void *)&c, sizeof(c));
196:
197: if (BytesWritten == -1) {
198: Dbgprintf("Error occurred writing pipe, errno = %d\n", errno);
199: Done = 1;
200: break;
201: }
202:
203: SendCtrlC = 0;
204:
205: //
206: // Clear the input buffer
207: //
208:
209: InputBytesRead = 0;
210: }
211:
212:
213: //
214: // Get input from the keyboard
215: //
216:
217: while (kbhit() && !Done) {
218:
219: //
220: // If the input buffer's full, send it
221: //
222:
223: if (InputBytesRead >= (sizeof(InputBuffer) - 2)) {
224:
225: //
226: // Write out the whole input buffer to the pipe
227: //
228:
229: BytesWritten = write(PipeHandle, (void *)InputBuffer, InputBytesRead);
230:
231: if (BytesWritten == -1) {
232: Dbgprintf("Error occurred writing pipe, errno = %d\n", errno);
233: Done = 1;
234: break;
235: }
236:
237: InputBytesRead = 0;
238: }
239:
240:
241: //
242: // Get the input character and add it to buffer
243: //
244:
245: InputBuffer[InputBytesRead++] = (char)getch();
246:
247:
248: //
249: // Handle special characters
250: //
251:
252: switch (InputBuffer[InputBytesRead - 1]) {
253:
254: case '\r':
255:
256: //
257: // Convert CR to CRLF
258: //
259:
260: InputBuffer[InputBytesRead++] = '\n';
261:
262: //
263: // Echo the CRLF
264: //
265:
266: BytesWritten = write(STDOUT, &InputBuffer[InputBytesRead-2], 2);
267:
268: if (BytesWritten == -1) {
269: Dbgprintf("Error occurred writing stdout, errno = %d\n", errno);
270: Done = 1;
271: break;
272: }
273:
274: //
275: // Send the input buffer
276: //
277:
278: BytesWritten = write(PipeHandle, (void *)InputBuffer, InputBytesRead);
279:
280: if (BytesWritten == -1) {
281: Dbgprintf("Error occurred writing pipe, errno = %d\n", errno);
282: Done = 1;
283: break;
284: }
285:
286: InputBytesRead = 0;
287: break;
288:
289:
290: case '\010':
291:
292: //
293: // Delete (Ctrl-H)
294: //
295:
296: InputBytesRead --; // Remove the Delete char from buffer
297:
298: if (InputBytesRead > 0) {
299:
300: char *deletestring = "\010 \010";
301:
302: InputBytesRead --; // Remove previous char from buffer
303:
304: //
305: // Erase previous character on line
306: //
307:
308: BytesWritten = write(STDOUT, (void *)deletestring, strlen(deletestring));
309:
310: if (BytesWritten == -1) {
311: Dbgprintf("Error occurred writing stdout, errno = %d\n", errno);
312: Done = 1;
313: }
314: }
315:
316: break;
317:
318:
319:
320: case 0:
321: case 0xe0:
322:
323: //
324: // Cursor/function key - go get the second part of it
325: //
326:
327: InputBuffer[InputBytesRead++] = (char)getch();
328:
329: //
330: // Check for our exit key (F3)
331: //
332:
333: if (InputBuffer[InputBytesRead-1] == 0x3d) {
334: Done = 1;
335: break;
336: }
337:
338: //
339: // Remove the cursor key from the input buffer
340: //
341:
342: InputBytesRead -= 2;
343:
344: break;
345:
346:
347:
348: default:
349:
350: //
351: // Echo the character
352: //
353:
354: BytesWritten = write(STDOUT, &InputBuffer[InputBytesRead-1], 1);
355:
356: if (BytesWritten == -1) {
357: Dbgprintf("Error occurred writing stdout, errno = %d\n", errno);
358: Done = 1;
359: }
360: break;
361:
362:
363:
364: } // switch
365:
366: } // while(kdhit() && !Done)
367:
368: } // while(!Done)
369:
370:
371:
372: if (close(PipeHandle) == -1) {
373: printf("Error closing pipe, errno = %d\n", errno);
374: }
375:
376:
377: printf("\nDisconnected from %s\n", argv[1]);
378:
379: return 0;
380: }
381:
382:
383:
384: //
385: // CtrlCHandler
386: //
387:
388: void *
389: CtrlCHandler(
390: int Signal
391: )
392: {
393: //
394: // Set our global so we send a Ctrl-C real-soon
395: //
396:
397: SendCtrlC = 1;
398:
399: //
400: // Re-establish the signal handler
401: //
402:
403: signal(SIGINT, CtrlCHandler);
404:
405: return(NULL);
406: }
407:
408:
409:
410: //
411: // Async pipe read completion handler
412: //
413:
414: void far pascal _loadds
415: PipeReadFn(
416: unsigned long Param
417: )
418: {
419: GotPipeData = 1;
420: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.