#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <string.h>

#define FIFO_FILE_WRITE "fifo_file_read"
#define FIFO_FILE_READ "fifo_file_write"
#define BLOCK_SIZE 4096
#define BUF_LEN BLOCK_SIZE

int main () {

    char buf[BUF_LEN];
    int fd, ffr, ffw, len;

    ffw = mkfifo  (FIFO_FILE_WRITE, 0777);
    if (ffw == -1) {
	perror ("mkfifo()");
	exit (1);
    }

    ffr = mkfifo  (FIFO_FILE_READ, 0777);
    if (ffr == -1) {
	perror ("mkfifo()");
	exit (1);
    }
    ffw = open (FIFO_FILE_WRITE, O_WRONLY);
    if (ffw == -1) {
	perror ("open()");
	exit (1);
    }

    ffr = open (FIFO_FILE_READ, O_RDONLY);
    if (ffr == -1) {
	perror ("open()");
	exit (1);
    }

    //read filename from the fifo file.
    //client has to write it first.
    len = read (ffr, buf, BUF_LEN);
    if (len == -1) {
	perror ("read()");
	exit (1);
    }

    //assuming filename is not longer than BUF_LEN

    close (ffr);

    buf[len] = '\0';
    fd = open (buf, O_RDONLY);
    //strictly speaking, client must be notified of the error.
    if (fd == -1) {
	perror ("open()");
	exit (1);
    }

    //start writing the file to the fifo.
    while (1) {
	len = read (fd, buf, BLOCK_SIZE);
	if (len == -1) {
	    perror ("read()");
	    exit (1);
	}
	if (write (ffw, buf, len) < len) {
	    perror ("write()");
	    exit (1);
	}

	if (len < BLOCK_SIZE) {
	    //nothing more to read from file.
	    unlink (FIFO_FILE_READ);
	    unlink (FIFO_FILE_WRITE);
	    close (ffw);
	    close (fd);
	    exit (0);
	}
	//else, read another BLOCK_SIZE bytes.
    }

    return 0;
}

