partager/main.c

253 lines
5.4 KiB
C

#include <curses.h>
#include <errno.h>
#include <ncurses.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <unistd.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <asm-generic/socket.h>
#include <pthread.h>
#include <bits/pthreadtypes.h>
#include <wchar.h>
#include "args.h"
#include "term.h"
#include "common.h"
#define DA_IMPLEMENTATION
#include "da.h"
#define bufferLen 256
#define PORT 12123
enum {
SENDER = 0,
RECEIVER = 1,
THREAD_COUNT = 2,
};
void * sender(void * arg)
{
fd_t * connFd = arg;
(void) connFd;
return NULL;
}
void * receiver(void * arg)
{
char buffer[bufferLen] = {0};
fd_t * connFd = arg;
while (1)
{
read(*connFd, buffer, bufferLen);
printf("\033[A");
printf("\n");
printf("%s", buffer);
if (strcmp(buffer, "e\n") == 0) break;
bzero(buffer, bufferLen);
}
return NULL;
}
void serve()
{
int sockFd, connFd;
struct sockaddr_in server, client;
bzero(&server, sizeof(server));
bzero(&client, sizeof(client));
sockFd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (sockFd < 0)
{
fprintf(stderr, "ERROR:%d:%s\n", errno, strerror(errno));
exit(1);
}
server.sin_family = AF_INET;
server.sin_addr.s_addr = inet_addr("0.0.0.0");
server.sin_port = htons(PORT);
if (bind(sockFd, (struct sockaddr *) &server, sizeof(server)) < 0)
{
fprintf(stderr, "ERROR:%d:%s\n", errno, strerror(errno));
exit(1);
}
if (listen(sockFd, 0) < 0)
{
fprintf(stderr, "ERROR:%d:%s\n", errno, strerror(errno));
exit(1);
}
socklen_t len = sizeof(client);
connFd = accept(sockFd, (struct sockaddr *) &client, &len);
if (connFd < 0)
{
fprintf(stderr, "ERROR:%d:%s\n", errno, strerror(errno));
exit(1);
}
pthread_t threads[THREAD_COUNT];
int threadError = 0;
threadError = pthread_create(&threads[SENDER], NULL, sender, &connFd);
if (threadError)
{
fprintf(stderr, "ERROR:Couldn't create SENDER Thread\n");
exit(1);
}
threadError = pthread_create(&threads[RECEIVER], NULL, receiver, &connFd);
if (threadError)
{
fprintf(stderr, "ERROR:Couldn't create RECEIVER Thread\n");
exit(1);
}
for (size_t i = 0; i < THREAD_COUNT; ++i)
pthread_join(threads[i], NULL);
close(sockFd);
}
void draw(State * state)
{
size_t x, y;
getmaxyx(stdscr, y, x);
if (state->term.termX != x ||
state->term.termY != y)
{
recreateWindows(&state->term);
}
wmove(state->term.chat, 1, 2);
wmove(state->term.input, state->term.inputY, state->term.inputX);
for (size_t i = 0; i < daSize(state->messages); ++i)
{
wprintw(state->term.chat, "%s", state->messages[i]);
wmove(state->term.chat, 2 + i, 2);
}
wrefresh(state->term.chat);
wrefresh(state->term.extra);
wrefresh(state->term.input);
}
void loop(State * state)
{
initNcurses();
state->term = createTerm();
draw(state);
dynarr(char) buffer = daCreate(char, 128);
heapstr msg = NULL;
int key = 0;
while ((key = getch()) != 27 /* ESC */)
{
switch (key)
{
case 10: /* ENTER */
msg = daToCStr(buffer);
daPush(state->messages, msg);
daBzero(buffer);
state->term.inputX = 1;
for (int i = 1; i < getmaxx(state->term.input) - 1; ++i)
mvwprintw(state->term.input, state->term.inputY, i, " ");
break;
case KEY_LEFT:
if (state->term.inputX > 1)
state->term.inputX -= 1;
break;
case KEY_RIGHT:
if (state->term.inputX < getmaxx(state->term.input) - 2)
state->term.inputX += 1;
break;
case KEY_UP:
case KEY_DOWN:
case KEY_RESIZE:
break;
case KEY_BACKSPACE:
if (state->term.inputX > 1)
{
state->term.inputX -= 1;
wmove(state->term.input, state->term.inputY, state->term.inputX);
wprintw(state->term.input, " ");
if (daSize(buffer))
daPopDiscard(buffer);
}
break;
case KEY_F(1):
recreateWindows(&state->term);
break;
default:
if (state->term.inputX < getmaxx(state->term.input) - 2)
{
wprintw(state->term.input, "%c", key);
daPush(buffer, key);
state->term.inputX += 1;
}
}
draw(state);
}
deinitNcurses();
daFree(buffer);
}
int main(int argc, char ** argv)
{
int ret = 0;
State state = createDefaultState();
partresult result = parseArgs(argc, argv, &state);
if (result < 0)
{
fprintf(stderr, "ERROR: Parsing of command line arguments failed!\n");
ret = 1;
goto exit;
}
printf("IP: %s\n", state.conf.ip);
printf("PORT: %d\n", state.conf.port);
printf("MODE: %d\n", state.conf.mode);
// loop(&state);
// for (size_t i = 0; i < daSize(state.messages); ++i)
// {
// free(state.messages[i]);
// }
exit:
daFree(state.messages);
return ret;
}