1 /* 2 * COPYRIGHT: See COPYING in the top level directory 3 * PROJECT: ReactOS conCATenation tool 4 * FILE: cmdutils/cat/cat.c 5 * PURPOSE: Concatenates STDIN or an arbitrary number of files to STDOUT 6 * PROGRAMMERS: David Welch 7 * Semyon Novikov (tappak) 8 * Herm�s B�lusca - Ma�to 9 */ 10 11 #include <stdio.h> 12 13 #ifdef _WIN32 14 #include <string.h> // Required for _stricmp() 15 #include <fcntl.h> // Required for _setmode flags 16 #include <io.h> // Required for _setmode() 17 #else 18 #include <strings.h> // Required for strcasecmp() 19 #define O_TEXT 0x4000 20 #define O_BINARY 0x8000 21 #define _setmode(fd, mode) // This function is useless in *nix world 22 #define _stricmp strcasecmp 23 #endif 24 25 #define ARRAYSIZE(a) (sizeof(a) / sizeof((a)[0])) 26 27 void help(void) 28 { 29 fprintf(stdout, 30 "\n" 31 "ReactOS File Concatenation Tool\n" 32 "\n" 33 "Usage: cat [options] [file [...]]\n" 34 "options - Currently ignored\n"); 35 } 36 37 int main(int argc, char* argv[]) 38 { 39 int i; 40 FILE* in; 41 unsigned char buff[512]; 42 size_t cnt, readcnt; 43 44 if (argc >= 2) 45 { 46 if (_stricmp(argv[1], "-h" ) == 0 || 47 _stricmp(argv[1], "--help") == 0 || 48 _stricmp(argv[1], "/?" ) == 0 || 49 _stricmp(argv[1], "/help" ) == 0) 50 { 51 help(); 52 return 0; 53 } 54 } 55 56 /* Set STDOUT to binary */ 57 _setmode(_fileno(stdout), O_BINARY); 58 59 /* Special case where we run 'cat' without any argument: we use STDIN */ 60 if (argc <= 1) 61 { 62 unsigned int ch; 63 64 /* Set STDIN to binary */ 65 _setmode(_fileno(stdin), O_BINARY); 66 67 #if 0 // Version using feof() 68 ch = fgetc(stdin); 69 while (!feof(stdin)) 70 { 71 putchar(ch); 72 ch = fgetc(stdin); 73 } 74 #else 75 while ((ch = fgetc(stdin)) != EOF) 76 { 77 putchar(ch); 78 } 79 #endif 80 81 return 0; 82 } 83 84 /* We have files: read them and output them to STDOUT */ 85 for (i = 1; i < argc; i++) 86 { 87 /* Open the file in binary read mode */ 88 in = fopen(argv[i], "rb"); 89 if (in == NULL) 90 { 91 fprintf(stderr, "Failed to open file '%s'\n", argv[i]); 92 return -1; 93 } 94 95 /* Dump the file to STDOUT */ 96 cnt = 0; readcnt = 0; 97 while (readcnt == cnt) 98 { 99 /* Read data from the input file */ 100 cnt = ARRAYSIZE(buff); 101 readcnt = fread(&buff, sizeof(buff[0]), cnt, in); 102 if (readcnt != cnt) 103 { 104 /* 105 * The real number of read bytes differs from the number of bytes 106 * we wanted to read, so either a reading error occurred, or EOF 107 * was reached while reading. Bail out if it is a reading error. 108 */ 109 if (!feof(in)) 110 { 111 fprintf(stderr, "Error while reading file '%s'\n", argv[i]); 112 fclose(in); 113 return -1; 114 } 115 } 116 117 /* Nothing to be read anymore, so we can gracefully break */ 118 if (readcnt == 0) break; 119 120 /* Write data to STDOUT */ 121 fwrite(&buff, sizeof(buff[0]), readcnt, stdout); 122 } 123 124 /* Finally close the file */ 125 fclose(in); 126 } 127 128 return 0; 129 } 130 131 /* EOF */ 132