2022-08-13 23:43:46 +00:00
|
|
|
/* cat.c -- provides a routine to output the contents of the named files in either a buffered or unbuffered fashion. */
|
|
|
|
/* Accepts the following parameters: */
|
|
|
|
/* -u: Output should be unbuffered. */
|
|
|
|
|
|
|
|
/* Returns the following values: */
|
|
|
|
/* 0: All files were printed successfully. */
|
|
|
|
/* 1: One or more files could not be opened. */
|
|
|
|
|
|
|
|
|
|
|
|
#include "common.h"
|
|
|
|
|
|
|
|
/* If mode is set to zero, return a null pointer and print characters directly. Otherwise, return a pointer to a buffer containing */
|
|
|
|
/* the contents of the file pointed to by fp. */
|
|
|
|
char *cat(FILE *fp, const int mode)
|
|
|
|
{
|
|
|
|
char c;
|
|
|
|
|
|
|
|
if(!mode)
|
|
|
|
{
|
|
|
|
int i, buflen;
|
|
|
|
buflen = 4096;
|
|
|
|
char *arr = malloc(4096);
|
|
|
|
char *newarr = 0;
|
|
|
|
|
|
|
|
for(i = 0; (c = fgetc(fp)) != EOF; i++)
|
|
|
|
{
|
|
|
|
if(i >= buflen)
|
|
|
|
{
|
|
|
|
buflen *= 2;
|
|
|
|
newarr = malloc(buflen);
|
|
|
|
strcpy(newarr, arr);
|
|
|
|
free(arr);
|
|
|
|
arr = newarr;
|
|
|
|
}
|
|
|
|
|
|
|
|
arr[i] = c;
|
|
|
|
}
|
|
|
|
arr[i] = '\0';
|
|
|
|
|
|
|
|
return arr;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
for(;(c = fgetc(fp)) != EOF;)
|
|
|
|
{
|
|
|
|
putchar(c);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
int main(int argc, char **argv)
|
|
|
|
{
|
|
|
|
char *buf, *newbuf, *tmpbuf;
|
|
|
|
int i, upresence, fppresence;
|
|
|
|
i = upresence = fppresence = 0;
|
|
|
|
long unsigned int buflen;
|
|
|
|
buflen = 4096;
|
|
|
|
FILE *fp;
|
|
|
|
fp = 0;
|
|
|
|
buf = malloc(buflen);
|
|
|
|
|
|
|
|
if((upresence = (getopt(argc, argv, ":u") == 'u')))
|
|
|
|
{
|
|
|
|
i++;
|
|
|
|
}
|
|
|
|
|
|
|
|
for(i++;argv[i] != NULL; i++)
|
|
|
|
{
|
|
|
|
if(!strcmp(argv[i], "-"))
|
|
|
|
{
|
|
|
|
fppresence++;
|
2022-08-13 23:52:56 +00:00
|
|
|
newbuf = cat(stdin, upresence);
|
2022-08-13 23:43:46 +00:00
|
|
|
}
|
|
|
|
else if((fp = fopen(argv[i], "r")) != NULL)
|
|
|
|
{
|
|
|
|
fppresence++;
|
|
|
|
newbuf = cat(fp, upresence);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
fprintf(stderr, "%s: failed to open %s. Aborting.\n", argv[0], argv[i]);
|
|
|
|
exit(1);
|
|
|
|
}
|
|
|
|
|
|
|
|
if(!upresence and (2 * (strlen(buf) + strlen(newbuf)) >= buflen))
|
|
|
|
{
|
2022-08-14 00:16:54 +00:00
|
|
|
/* Rewrite this bit to use realloc and/or memcpy? */
|
2022-08-13 23:43:46 +00:00
|
|
|
tmpbuf = malloc(2 * (strlen(buf) + strlen(newbuf)));
|
|
|
|
strcpy(tmpbuf, buf);
|
|
|
|
free(buf);
|
|
|
|
buf = tmpbuf;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(!upresence)
|
|
|
|
{
|
|
|
|
strcat(buf, newbuf);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if(!fppresence)
|
|
|
|
{
|
2022-08-13 23:52:56 +00:00
|
|
|
buf = cat(stdin, upresence);
|
2022-08-13 23:43:46 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if(!upresence)
|
|
|
|
{
|
|
|
|
printf("%s", buf);
|
|
|
|
}
|
|
|
|
|
|
|
|
exit(0);
|
|
|
|
}
|