#!/usr/bin/python

import os
import sys

#def no_eol(line):
#    if sys.line[-1:] == '\n':
#        return line[:-1]
#    else:
#        return line

def usage(retval):
    sys.stderr.write('%s sets up multiple pipes and sends a copy of stdin to each of them\n' % sys.argv[0])
    sys.stderr.write('\n')
    sys.stderr.write('Usage: %s [-f file_of_commands1] [-f file_of_commands2] ... [-f file_of_commandsn] [-h] [--] command1 command2 ... commandn\n' % sys.argv[0])
    sys.stderr.write('\n')
    sys.stderr.write('-h shows this help message\n')
    sys.stderr.write('-- signals the end of options, so that commands may start with a "-"\n')
    sys.stderr.write('-f filename reads commands to set up pipes with, one command per line\n')
    sys.stderr.write('-q says to operate quietly\n')
    sys.stderr.write('commandx says to use commandx to set up a pipe\n')
    sys.exit(retval)

commands = []
quiet = 0

class Pipe(object):
    def __init__(self, command):
        self.command = command
        self.pipe = os.popen(self.command, 'w')
        self.active = True

    def write(self, string):
        return self.pipe.write(string)


while sys.argv[1:] and sys.argv[1][0:1] == '-':
    if sys.argv[1] == '--':
        del sys.argv[1]
        break
    elif sys.argv[1] == '-f' and sys.argv[2:]:
        filename = sys.argv[2]
        commands += open(filename, 'rb').readlines()
        del sys.argv[1]
    elif sys.argv[1] == '-h':
        usage(0)
    elif sys.argv[1] == '-q':
        quiet = 1
    else:
        sys.stderr.write('%s: Illegal option: %s\n' % (sys.argv[0], sys.argv[1]))
        usage(1)
    del sys.argv[1]

commands += sys.argv[1:]

# Bourne shell (or bash, as the case may be) doesn't care about leading and trailing whitespace anyway
commands = [ command.strip() for command in commands ]

pipes=[]
if not quiet:
    sys.stderr.write('Creating %d pipes\n' % len(commands))
for index, command in enumerate(commands):
    if not quiet:
        sys.stderr.write('popening command %d: %s\n' % (index, command))
    pipes.append(Pipe(command))

eof = False
while True:
    at_least_one_pipe_remains=False
    buf = sys.stdin.read(1024 * 1024)
    if not buf:
        eof = True
        break
    for pipeno, pipe in enumerate(pipes):
        if pipe.active:
            try:
                pipe.write(buf)
                at_least_one_pipe_remains = True
            except:
                if not quiet:
                    sys.stderr.write('terminated: %s\n' % commands[pipeno])
                pipes[pipeno].active = False
    if not at_least_one_pipe_remains:
        break

if eof:
    for pipe in pipes:
        if pipe.active:
            pipe.pipe.close()