/*
 * chat.c
 * 
 * Copyright 2022 grchere <grchere@grcnet>
 * 
 * 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., 51 Franklin Street, Fifth Floor, Boston,
 * MA 02110-1301, USA.
 * 
 * Implementacion de chat con fifos utilizando proceso padre e hijo
 * uno es lector y otro es escritor
 * Forma de ejecucion posible:
 *  $ ./chat [prompt] [fifo en donde escribo] [fifo de donde leo]
 * 
 *  $ ./chat c1 fifo1 fifo2
 *  $ ./chat c2 fifo2 fifo1
 * 
 *  donde el proceso padre es siempre escritor y el proceso hijo es 
 *  siempre lector 
 */

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

void enviarMsg(int fd,const char *);
void recibirMsg(int fd,char *dest,int size,const char *);

int main(int argc, char **argv)
{
	if ( argc != 4 ) {
		printf("Forma de uso:\n$ ./char [fifo escritura] [fifo lectura]\n");
		return 1;
	}
	if ( access(argv[2],F_OK) != 0 ) mkfifo(argv[2],0777);
	if ( access(argv[3],F_OK) != 0 ) mkfifo(argv[3],0777);
	
	char buffer[256];
	pid_t pid = fork();
	if ( pid == 0 ) {
		// lector 
		char lprompt[100];
		snprintf(lprompt,100,"%s<",argv[1]);
		int fd1 = open(argv[3],O_RDONLY);
		do {
			recibirMsg(fd1,buffer,256,lprompt);
		} while( strncmp(buffer,"chau",4) != 0 );
		close(fd1);
		printf("fin lector %s!\n",argv[1]);
	} else {
		// escritor
		int fd1 = open(argv[2],O_WRONLY);
		do {
			printf("%s>",argv[1]);
			fgets(buffer,256,stdin);
			enviarMsg(fd1,buffer);
		} while( strncmp(buffer,"chau",4) != 0 );
		close(fd1);
		printf("fin escritor %s en wait!\n",argv[1]);
		wait(0); // espera x lector
	}
	remove(argv[2]);
	remove(argv[3]);
	return 0;
}

void enviarMsg(int fd,const char *msg) {
	int bytes = write(fd,msg,strlen(msg)+1);
	printf("Envie %d bytes al proceso hijo!\n",bytes);
}

void recibirMsg(int fd,char *dest,int size,const char *prompt) {
	int bytes = read(fd,dest,size);
	if ( bytes > 0 ) printf("%s%s",prompt,dest);
	else printf("No Recibi nada!\n");
}
