diff --git a/Changelog b/Changelog index edaa34c24..3694a2ffb 100644 --- a/Changelog +++ b/Changelog @@ -16,6 +16,7 @@ which blocked reboots. * Added a prelinary du implementation. Some parameter parsing stuff still needs to be added. -beppu + * Implemented tee -beppu -Erik Andrsen diff --git a/applets/busybox.c b/applets/busybox.c index c050acc9c..4ac907665 100644 --- a/applets/busybox.c +++ b/applets/busybox.c @@ -182,6 +182,9 @@ static const struct Applet applets[] = { #ifdef BB_TAR //bin {"tar", tar_main}, #endif +#ifdef BB_TEE //bin + {"tee", tee_main}, +#endif #ifdef BB_TOUCH //usr/bin {"touch", touch_main}, #endif diff --git a/busybox.c b/busybox.c index c050acc9c..4ac907665 100644 --- a/busybox.c +++ b/busybox.c @@ -182,6 +182,9 @@ static const struct Applet applets[] = { #ifdef BB_TAR //bin {"tar", tar_main}, #endif +#ifdef BB_TEE //bin + {"tee", tee_main}, +#endif #ifdef BB_TOUCH //usr/bin {"touch", touch_main}, #endif diff --git a/busybox.def.h b/busybox.def.h index efab4941c..cd3447f15 100644 --- a/busybox.def.h +++ b/busybox.def.h @@ -59,8 +59,9 @@ #define BB_SWAPONOFF #define BB_SYNC #define BB_SYSLOGD -#define BB_TAR #define BB_TAIL +#define BB_TAR +#define BB_TEE #define BB_TOUCH #define BB_TRUE_FALSE #define BB_UMOUNT diff --git a/coreutils/tee.c b/coreutils/tee.c new file mode 100644 index 000000000..fe444fcc4 --- /dev/null +++ b/coreutils/tee.c @@ -0,0 +1,147 @@ +/* + * Mini tee implementation for busybox + * + * + * Copyright (C) 1999 by Lineo, inc. + * Written by John Beppu + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include +#include + +/* FileList _______________________________________________________________ */ + +#define FL_MAX 1024 +static FILE *FileList[FL_MAX]; +static int FL_end; + +typedef void (FL_Function)(FILE *file, char c); + +/* initialize FileList */ +static void +FL_init() +{ + FL_end = 0; + FileList[0] = stdout; +} + +/* add a file to FileList */ +static int +FL_add(const char *filename, char *opt_open) +{ + FILE *file; + + file = fopen(filename, opt_open); + if (!file) { return 0; }; + if (FL_end < FL_MAX) { + FileList[++FL_end] = file; + } + return 1; +} + +/* apply a function to everything in FileList */ +static void +FL_apply(FL_Function *f, char c) +{ + int i; + for (i = 0; i <= FL_end; i++) { + f(FileList[i], c); + } +} + +/* ________________________________________________________________________ */ + +/* FL_Function for writing to files*/ +static void +tee_fwrite(FILE *file, char c) +{ + fputc(c, file); +} + +/* FL_Function for closing files */ +static void +tee_fclose(FILE *file, char c) +{ + fclose(file); +} + +/* help message */ +static void +tee_usage() +{ + fprintf ( + stdout, + "%s\n%s\n%s\n%s\n%s\n", + "Usage: tee [OPTION]... [FILE]...", + "Copy standard input to each FILE, and also to standard output.\n", + " -a, append to the given FILEs, do not overwrite", + " -i, ignore interrupt signals", + " -h, this help message" + ); + exit(1); +} + +/* BusyBoxed tee(1) */ +int +tee_main(int argc, char **argv) +{ + int i; + char c; + char opt; + char opt_fopen[2] = "w"; + + /* parse argv[] */ + for (i = 1; i < argc; i++) { + if (argv[i][0] == '-') { + opt = argv[i][1]; + switch (opt) { + case 'a': + opt_fopen[0] = 'a'; + break; + case 'i': + fprintf(stderr, "ingore interrupt not implemented\n"); + break; + case 'h': + tee_usage(); + break; + default: + fprintf(stderr, "tee: invalid option -- %c\n", opt); + tee_usage(); + } + } else { + break; + } + } + + /* init FILE pointers */ + FL_init(); + for ( ; i < argc; i++) { + FL_add(argv[i], opt_fopen); + } + + /* read and redirect */ + while ((c = (char) getchar()) && (!feof(stdin))) { + FL_apply(tee_fwrite, c); + } + + /* clean up */ + FL_apply(tee_fclose, 0); + exit(0); +} + +/* $Id: tee.c,v 1.1 1999/12/10 05:27:16 beppu Exp $ */ diff --git a/internal.h b/internal.h index de13bb202..4bde46612 100644 --- a/internal.h +++ b/internal.h @@ -112,6 +112,7 @@ extern int syslogd_main(int argc, char **argv); extern int logger_main(int argc, char **argv); extern int tar_main(int argc, char** argv); extern int tail_main(int argc, char** argv); +extern int tee_main(int argc, char** argv); extern int touch_main(int argc, char** argv); extern int tput_main(int argc, char** argv); extern int true_main(int argc, char** argv); diff --git a/tee.c b/tee.c new file mode 100644 index 000000000..fe444fcc4 --- /dev/null +++ b/tee.c @@ -0,0 +1,147 @@ +/* + * Mini tee implementation for busybox + * + * + * Copyright (C) 1999 by Lineo, inc. + * Written by John Beppu + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include +#include + +/* FileList _______________________________________________________________ */ + +#define FL_MAX 1024 +static FILE *FileList[FL_MAX]; +static int FL_end; + +typedef void (FL_Function)(FILE *file, char c); + +/* initialize FileList */ +static void +FL_init() +{ + FL_end = 0; + FileList[0] = stdout; +} + +/* add a file to FileList */ +static int +FL_add(const char *filename, char *opt_open) +{ + FILE *file; + + file = fopen(filename, opt_open); + if (!file) { return 0; }; + if (FL_end < FL_MAX) { + FileList[++FL_end] = file; + } + return 1; +} + +/* apply a function to everything in FileList */ +static void +FL_apply(FL_Function *f, char c) +{ + int i; + for (i = 0; i <= FL_end; i++) { + f(FileList[i], c); + } +} + +/* ________________________________________________________________________ */ + +/* FL_Function for writing to files*/ +static void +tee_fwrite(FILE *file, char c) +{ + fputc(c, file); +} + +/* FL_Function for closing files */ +static void +tee_fclose(FILE *file, char c) +{ + fclose(file); +} + +/* help message */ +static void +tee_usage() +{ + fprintf ( + stdout, + "%s\n%s\n%s\n%s\n%s\n", + "Usage: tee [OPTION]... [FILE]...", + "Copy standard input to each FILE, and also to standard output.\n", + " -a, append to the given FILEs, do not overwrite", + " -i, ignore interrupt signals", + " -h, this help message" + ); + exit(1); +} + +/* BusyBoxed tee(1) */ +int +tee_main(int argc, char **argv) +{ + int i; + char c; + char opt; + char opt_fopen[2] = "w"; + + /* parse argv[] */ + for (i = 1; i < argc; i++) { + if (argv[i][0] == '-') { + opt = argv[i][1]; + switch (opt) { + case 'a': + opt_fopen[0] = 'a'; + break; + case 'i': + fprintf(stderr, "ingore interrupt not implemented\n"); + break; + case 'h': + tee_usage(); + break; + default: + fprintf(stderr, "tee: invalid option -- %c\n", opt); + tee_usage(); + } + } else { + break; + } + } + + /* init FILE pointers */ + FL_init(); + for ( ; i < argc; i++) { + FL_add(argv[i], opt_fopen); + } + + /* read and redirect */ + while ((c = (char) getchar()) && (!feof(stdin))) { + FL_apply(tee_fwrite, c); + } + + /* clean up */ + FL_apply(tee_fclose, 0); + exit(0); +} + +/* $Id: tee.c,v 1.1 1999/12/10 05:27:16 beppu Exp $ */