/* ************************************************************ implementation of 'cat' utility under MS-DOS Author: David Lee Lambert - in my opinion, this program is too short to bother with copyright... ************************************************************ */ #include #include #include /* utility-routines taken from which.c */ struct svec { char **mem; int size; int cap; }; int spush(struct svec * v, char * s) { char **temp; if (! (v->size < v->cap)) { /* double the size if full */ if (v->cap) v->cap *= 2; else v->cap = 1; temp = malloc(sizeof(char *) * v->cap); memcpy(temp, v->mem, v->size*sizeof(char *)); free(v->mem); v->mem = temp; } v->mem[v->size++] = s; return 0; } int sfree(struct svec * v) { int i; for (i = 0; i < v->size; i++) free(v->mem[i]); free(v->mem); return 0; } int sclear(struct svec * v) { v->size = v->cap = 0; return 0; } /* unique code */ const char * help_text = " Concatenate files\n" "\n" "syntax: cat [file [file [...]]] or\n" " cat [wilcard [file...]] etc.\n"; int main(int argc, char *argv[]) { struct svec filelist = {0, 0, 0}; HANDLE hDir; int i; WIN32_FIND_DATA filedata; HANDLE hInFile; char * pBuffer; DWORD bufsize, chunksize; pBuffer = malloc(bufsize = 4088); for (i = 1; i < argc; i++) { if (strcmpi(argv[i], "-h") == 0 || strcmpi(argv[i], "/?") == 0) { printf("%s:\n%s", argv[0], help_text); goto end; } if (strcmpi(argv[i], "-") == 0) { spush(&filelist, strdup("-")); continue; } hDir = FindFirstFile(argv[i], &filedata); if (hDir != INVALID_HANDLE_VALUE) { spush(&filelist, strdup(filedata.cFileName)); while (FindNextFile(argv[i], &filedata)) { spush(&filelist, strdup(filedata.cFileName)); } } else { fprintf(stderr, "%s: File not found, error %ld\n", argv[0], GetLastError()); } } if (filelist.size == 0) spush(&filelist, strdup("-")); for (i = 0; i < filelist.size; i++) { if (strcmp(filelist.mem[i], "-") == 0) { do { chunksize = fread(pBuffer, 1, bufsize, stdin); fwrite(pBuffer, 1, chunksize, stdout); } while (chunksize == bufsize || !feof(stdin)); continue; } hInFile = CreateFile(filelist.mem[i], GENERIC_READ, /* access (read-write) mode */ FILE_SHARE_READ, /* share mode */ 0, /* address of security descriptor */ OPEN_EXISTING, /* how to create */ FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, /* file attributes */ 0 ); if (hInFile != INVALID_HANDLE_VALUE) { while(TRUE == ReadFile(hInFile, pBuffer, bufsize, &chunksize, 0) && chunksize != 0) fwrite(pBuffer, 1, chunksize, stdout); CloseHandle(hInFile); } else fprintf(stderr, "%s: could not open file '%s', error %ld\n", argv[0], filelist.mem[i], GetLastError()); } end: sfree(&filelist); free(pBuffer); return 0; }