initial checkin of new hdw-linux development cvs repository
[hdw-linux/hdw-linux.git] / misc / hdw-tools / btee.c
1 /*  btee.c, a buffered tee clone   -   written for ROCK Linux
2
3     Copyright (C) 1998, 1999, 2001  Clifford Wolf
4
5     This program is free software; you can redistribute it and/or modify
6     it under the terms of the GNU General Public License as published by
7     the Free Software Foundation; either version 2 of the License, or
8     (at your option) any later version.
9
10     This program is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13     GNU General Public License for more details.
14
15     You should have received a copy of the GNU General Public License
16     along with this program; if not, write to the Free Software
17     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19
20 #define _GNU_SOURCE
21
22 #include <stdio.h>
23 #include <unistd.h>
24 #include <sys/types.h>
25 #include <sys/stat.h>
26 #include <fcntl.h>
27
28 #define BUFFER_SIZE (8*1024-1)
29 static char buffer[BUFFER_SIZE+1];
30
31 #define EOT 004
32
33 int main(int argc, char ** argv) {
34         int rc,mode,x,y;
35         int remove_zeros=0;
36         int pos=0,loop=1;
37         
38         if ( argc!=3 || (argv[1][0]!='a' && argv[1][0]!='t') ) {
39                 printf("Usage: %s {a|t} [file]\n",argv[0]);
40                 return 1;
41         }
42         
43         if (argv[1][0]=='a')
44                 mode=O_WRONLY|O_CREAT|O_APPEND;
45         else
46                 mode=O_WRONLY|O_CREAT|O_TRUNC;
47         
48         while (loop) {
49                 if (pos >= BUFFER_SIZE) {
50                         fprintf(stderr,"%s: Buffer is full -> drop data!\n",argv[0]);
51                         pos=0;
52                 }
53                 
54                 rc=read(0,buffer+pos,BUFFER_SIZE-pos);
55                 if (rc <= 0) return 0;
56                 buffer[pos+rc+1]=0;
57
58                 if (rc>0) {
59                         write(1,buffer+pos,rc);
60
61                         for (x=0; x<rc; x++) {
62                                 if (buffer[pos+x]==EOT) { loop=0; rc=x; break; }
63                                 if (buffer[pos+x]=='\r' &&
64                                     buffer[pos+x+1]!='\n') {
65                                         for (y=pos+x; y>=0; y--) {
66                                                 if (buffer[y]=='\n') break;
67                                                 buffer[y]=0;
68                                         }
69                                         remove_zeros=1;
70                                 }
71                         }
72
73                         pos+=rc;
74
75                         if (remove_zeros) {
76                                 for (x=y=0; x<pos; x++) {
77                                         if (buffer[x])
78                                                 buffer[y++]=buffer[x];
79                                 }
80                                 pos=y; remove_zeros=0;
81                         }
82
83                         rc=open(argv[2],mode,0666);
84                         if (rc>=0) {
85                                 write(rc,buffer,pos);
86                                 close(rc);
87                                 pos=0;
88                                 mode=O_WRONLY|O_APPEND;
89                         }
90                 }
91         }
92         
93         return 0;
94 }