/*
 * Copyright (C) 2013  Christian T. Lange <clange dot b0red.de>
 *
 * 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 3 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, see <http://www.gnu.org/licenses/>
 */

#define _GNU_SOURCE
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/select.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>

#include <stdio.h>

int main(int argc, char *argv[]) {
   if(argc < 2 || argc > 3) {
      printf("usage: %s pipeFile pidFile\r\n", argv[0]);
      return 1;
   }

   char *pipeFile = argv[1];
   char *pidFile = (argc == 3) ? argv[2] : NULL;

   if(pidFile) {
      int fpp = open(pidFile, O_CREAT|O_TRUNC|O_WRONLY, S_IWUSR|S_IRUSR);
      if(fpp < 0) {
         perror("open");
         return 1;
      }
      char buf[1024];
      sprintf(buf, "%d", getpid());
      write(fpp, buf, strlen(buf));
      close(fpp);
   }

   int fp = open(pipeFile, O_SYNC|O_NONBLOCK|O_RDONLY);
   if(fp < 0) {
      perror("open");
      return 1;
   }

   fd_set r_set;
   FD_ZERO(&r_set);
   FD_SET(fp, &r_set);
   int old_fp = -1;

   while(1==1) {
      fd_set rs = r_set;
      int s = select(1024, &rs, NULL, NULL, NULL);
      if(s < 0) {
         perror("select");
         return 0;
      }
      else if(s) {
         int sock = -1;
         if(old_fp != -1 && FD_ISSET(old_fp, &rs)) {
            sock = old_fp;
         }
         else if(FD_ISSET(fp, &rs)) {
            sock = fp;
         }
         char buf[1024];
         int len = read(sock,buf,sizeof(buf)-1);
         if(len < 0) {
            perror("read");
            return 0;
         }
         if(len == 0 && old_fp != sock) {
            old_fp = fp;
            fp = open(pipeFile, O_SYNC|O_NONBLOCK|O_RDONLY);
            if(fp < 0) {
               perror("open");
               return 1;
            }
            FD_SET(fp, &r_set);
         }
         else if(len == 0) {
            FD_CLR(old_fp, &r_set);
            close(old_fp);
            old_fp = -1;
         }
         if(len > 0) {
            write(0, buf, len);
//            buf[len] = 0;
//            printf("Data: %s\r\n", buf);
         }
      }
      else {
         printf("empty select\r\n");
      }
   }

   return 0;
}
