/* cat.c -- program to concatenate named files and/or stdin onto stdout */ /* version 2 */ #include #include #include #include #include "support.h" /* parameters */ enum { U }; /* concat - return a buffer of size new_size containing s1 and s2 concatenated. */ char *concat(char *a1, char *a2, int a1_size, int a2_size) { char *newbuf; newbuf = 0; if( !(newbuf = malloc(a1_size+a2_size))) { throw(MALLOC_FAIL, "concat: couldn't create buffer"); } if(a1_size) { mid_mempcpy(newbuf, a1, a1_size, 0); } if(a2_size) { mid_mempcpy(newbuf, a2, a2_size, a1_size); } return(newbuf); } int main(int argc, char **argv) { int i, c, bufsize, newbufsize; char *buf, *newbuf; char pars[1] = {0}; FILE *fd; i = c = bufsize = newbufsize = 0; buf = newbuf = 0; fd = 0; /* process our parameters */ for(; (c = getopt(argc, argv, "u")) != -1; c = 0) { switch(c) { case 'u': pars[U] = 1; break; case ':': case '?': default: throw(NEEDARG_FAIL, mastrcat(argv[0], " [-u] [file ...]")); break; } } i = optind; /* i < argc is obvious; steps through all provided args. */ /* !argc-optind && !c is a little less so - it allows this loop to run once if the user provides no paths */ do { if( !(fd = file_open(argv[i], "r"))) { throw(FOPEN_FAIL, mastrcat(argv[0], mastrcat(": could not open file ", argv[i]))); } if(pars[U]) { for(; (c = fgetc(fd)) != EOF; c = 0) { fputc(c, stdout); } } else { newbuf = file_read(fd, &newbufsize); buf = concat(buf, newbuf, bufsize, newbufsize); bufsize += newbufsize; free(newbuf); } i++, newbufsize = 0; } while((i < argc) || (((argc - optind) == 0) && !c)); if(!pars[U]) { fwrite(buf, sizeof(char), bufsize, stdout); } exit(0); }