mirror of the now-defunct rocklinux.org
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

118 lines
2.5 KiB

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