|
|
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.