#include #include #include #include #include #include #include #define DEBUG 0 /* Value of 1 is minimum for both constants. */ #define DEFAULT_BUFSIZE 50000 #define DEFAULT_TIMEOUT 100 #define exit(n) { free(buf); exit(n); } /*** __discolor ************************************************/ #ifndef __discolor #define __discolor #include #ifndef __strdel #define __strdel char*strdel(char*s){ register int k=-1; while(++k,s[k]!='\0')s[k]=s[k+1]; return(s); } #endif // #ifndef __strdel char *discolor(char *s) { register int i = 0; while (s[i] != '\0'){ if (s[i] == '\033' && s[i+1] == '[') { while (s[i] != '\0' && !isalpha(s[i])) strdel(s+i); if (s[i] != '\0') strdel(s+i); } else i++; } return s; } int discolor_data(char *s, int size) { register int i; for (i = 0; i < size + 1; ) { if (s[i] == '\033' && s[i + 1] == '[') { /* while (i < size && !isalpha(s[i])) { memmove(s + i, s + i + 1, size - i - 1); size--; } if (i < size) { memmove(s + i, s + i + 1, size - i - 1); size--; } */ register char*tmp_s; tmp_s = memchr(s + i, 'm', size - i); if (tmp_s != NULL) { memmove(s + i, tmp_s + 1, size - (tmp_s - s)); size -= (tmp_s + 1) - (s + i); } else { i++; } } else { i++; } } return size; } #endif int main(int argc, char**argv) { fd_set rfds; struct timeval tv; char *buf = NULL; register int retval, datasize, written, f_ending_eoln; register int timeout = 0, bufsize = 0; if (argc > 1) { register int cur = 1; while (cur < argc) { if (!strcmp(argv[cur], "-h") || !strcmp(argv[cur], "--help")) { printf("TBUFFER - timeout buffering v1.0 / %s %s\n", __DATE__, __TIME__); printf("Programmed by Ondrej Jombik, " "e-mail: Nepto@pobox.sk, " "Web: http://Nepto.w3.to\n" "(c) Copyright 2001 Platon Software Development Group, " "All rights reserved."); printf("\n\nUsage: tbuffer\n" " [ -h | --help ]\n" " [ -t | --timeout ]\n" " [ -b | --bufsize ]\n"); return 1; } if (!strcmp(argv[cur], "-t") || !strcmp(argv[cur], "--timeout")) { cur++; timeout = atoi(argv[cur]); if (timeout <= 0) { fprintf(stderr, "tbuffer: bad timeout defined [%d]\n", timeout); return 1; } cur++; break; } if (!strcmp(argv[cur], "-b") || !strcmp(argv[cur], "--bufsize")) { cur++; bufsize = atoi(argv[cur]); if (bufsize <= 1) { fprintf(stderr, "tbuffer: bad buffer size defined [%d]\n", bufsize); return 1; } cur++; break; } fprintf(stderr, "tbuffer: invalid parameter '%s'\n", argv[cur]); return 1; } } if (bufsize > 1) fprintf(stderr, "tbuffer: using choosen buffer size of %d bytes\n", bufsize); else { bufsize = DEFAULT_BUFSIZE; fprintf(stderr, "tbuffer: using default buffer size of %d bytes\n", bufsize); } if (timeout != 0) fprintf(stderr, "tbuffer: using choosen timeout %d miliseconds\n", timeout); else { timeout = DEFAULT_TIMEOUT; fprintf(stderr, "tbuffer: using default timeout %d miliseconds\n", timeout); } f_ending_eoln = 1; buf = (char*) malloc(bufsize * sizeof(char)); if (buf == NULL) { fprintf(stderr, "tbuffer: not enough memory to allocate " "buffer of size %d bytes\n", bufsize); return 1; } while(1) { /* Watch stdin (fd 0) to see when it has input. */ FD_ZERO(&rfds); FD_SET(0, &rfds); /* Wait up to five seconds. */ tv.tv_sec = 0; tv.tv_usec = timeout; retval = select(1, &rfds, NULL, NULL, &tv); switch (retval) { /* Error */ case -1: fprintf(stderr, "tbuffer: select() failure: %s\n", strerror(errno)); exit(1); break; /* Timeout expired */ case 0: if (f_ending_eoln == 0) { f_ending_eoln = 1; //switch (write(1, "<]\n[>", 5)) { switch (write(1, "\n", 1)) { /* Error */ case -1: fprintf(stderr, "tbuffer: write() failure: %s", strerror(errno)); exit(1); break; /* unknow situation */ case 0: fprintf(stderr, "tbuffer: write() = 0, " "all OK, terminating...\n"); exit(0); break; default: break; }; } break; default: /* This should be 1. * It means number of changed descriptors in select(). */ /* Read data to descriptor 0. */ /* ssize_t read(int fd, void *buf, size_t count); */ /* * We must use bufsize - 1 cause we need last character * to append '\0' and make normal NUL terminated string. */ datasize = read(0, buf, bufsize - 1); switch (datasize) { /* Error */ case -1: fprintf(stderr, "tbuffer: read() failure: %s\n", strerror(errno)); exit(1); break; /* unknown situation */ case 0: fprintf(stderr, "tbuffer: read() = 0, " "all OK, terminating...\n"); exit(0); break; default: #if DEBUG { char tmpbuf[100]; sprintf(tmpbuf, "\n\033[01;34mtbuffer-debug:" " \033[0mread() OK, datasize = %d\n", datasize); write(1, tmpbuf, strlen(tmpbuf)); } #endif /* Write data to descriptor 1 */ written = write(1, buf, datasize); if (written != datasize) { char tmpbuf[100]; sprintf(tmpbuf, "tbuffer-warning: " "written != datasize (%d != %d)\n", written, datasize); write(1, tmpbuf, strlen(tmpbuf)); } switch (written) { /* Error */ case -1: fprintf(stderr, "tbuffer: write() failure: %s\n", strerror(errno)); exit(1); break; /* unknown situation */ case 0: fprintf(stderr, "tbuffer: write() = 0, " "all OK, terminating...\n"); exit(0); break; default: #if DEBUG { char tmpbuf[200]; register int k; sprintf(tmpbuf, "\n\033[01;34m" "tbuffer-debug:\033[0m " "write() OK, datasize = %d\n", datasize); write(1, tmpbuf, strlen(tmpbuf)); #endif #if 0 buf[datasize] = '\0'; discolor(buf); datasize = strlen(buf); #else datasize = discolor_data(buf, datasize); //write(1, buf, datasize); #endif #if DEBUG sprintf(tmpbuf, "\033[01;34mtbuffer-debug:" "\033[0m " "datasize after discolor() = " "%d\n", datasize); write(1, tmpbuf, strlen(tmpbuf)); #endif if (datasize > 0) { if (buf[datasize-1] == '\n') f_ending_eoln = 1; else f_ending_eoln = 0; } /* // Toto tu nechceme else f_ending_eoln = 0; */ #if DEBUG strcpy(tmpbuf, "\033[01;34mtbuffer-debug:" "\033[0m [BEG]"); for (k = datasize-9 > 0 ? datasize-9 : 0; k < datasize; k++) { sprintf(strchr(tmpbuf, '\0'), "[%X:%c]", buf[k],buf[k]>=32?buf[k]:'_'); } strcat(tmpbuf, "[END]\n"); write(1, tmpbuf, strlen(tmpbuf)); } #endif break; }; /* switch(write()) */ break; }; /* switch(read()) */ break; }; /* switch (select()) */ } return 0; }