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