"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "src/cacaserver.c" between
libcaca-0.99.beta19.tar.gz and libcaca-0.99.beta20.tar.bz2

About: libcaca is a graphics library that outputs text instead of pixels, so that it can work on older video cards or text terminals (something like an advanced AAlib library).

cacaserver.c  (libcaca-0.99.beta19):cacaserver.c  (libcaca-0.99.beta20.tar.bz2)
/* /*
* cacaserver Colour ASCII-Art library * cacaserver Colour ASCII-Art library
* Copyright (c) 2006 Jean-Yves Lamoureux <jylam@lnxscene.org> * Copyright © 2006-2021 Sam Hocevar <sam@hocevar.net>
* 2006-2014 Sam Hocevar <sam@hocevar.net> * 2016 Denis Fondras <ledeuns at github>
* All Rights Reserved * 2006 Jean-Yves Lamoureux <jylam@lnxscene.org>
* All Rights Reserved
* *
* This program is free software. It comes without any warranty, to * This program is free software. It comes without any warranty, to
* the extent permitted by applicable law. You can redistribute it * the extent permitted by applicable law. You can redistribute it
* and/or modify it under the terms of the Do What the Fuck You Want * and/or modify it under the terms of the Do What the Fuck You Want
* to Public License, Version 2, as published by Sam Hocevar. See * to Public License, Version 2, as published by Sam Hocevar. See
* http://www.wtfpl.net/ for more details. * http://www.wtfpl.net/ for more details.
*/ */
#include "config.h" #include "config.h"
skipping to change at line 34 skipping to change at line 35
# define USE_WINSOCK 1 # define USE_WINSOCK 1
#endif #endif
#if defined(HAVE_NETINET_IN_H) #if defined(HAVE_NETINET_IN_H)
# include <netinet/in.h> # include <netinet/in.h>
#endif #endif
#if defined(HAVE_UNISTD_H) #if defined(HAVE_UNISTD_H)
# include <unistd.h> # include <unistd.h>
#endif #endif
#include <sys/types.h> #include <sys/types.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <netdb.h>
#include <fcntl.h> #include <fcntl.h>
#include <signal.h> #include <signal.h>
#include <errno.h> #include <errno.h>
#include <stdarg.h> #include <stdarg.h>
#ifndef USE_WINSOCK #ifndef USE_WINSOCK
# define USE_WINSOCK 0 # define USE_WINSOCK 0
#endif #endif
#include "caca.h" #include "caca.h"
skipping to change at line 97 skipping to change at line 99
struct client struct client
{ {
int fd; int fd;
int ready; int ready;
uint8_t inbuf[INBUFFER]; uint8_t inbuf[INBUFFER];
int inbytes; int inbytes;
uint8_t outbuf[OUTBUFFER]; uint8_t outbuf[OUTBUFFER];
int start, stop; int start, stop;
}; };
#define MAXSOCKS 16
struct sock {
int sockfd;
struct sockaddr_in my_addr;
};
struct server struct server
{ {
unsigned int width, height; unsigned int width, height;
unsigned int port; unsigned int port;
int sockfd; int sock_count;
struct sockaddr_in my_addr; struct sock socks[MAXSOCKS];
socklen_t sin_size;
/* Input buffer */ /* Input buffer */
uint8_t *input; uint8_t *input;
unsigned int read; unsigned int read;
char prefix[sizeof(INIT_PREFIX)]; char prefix[sizeof(INIT_PREFIX)];
caca_canvas_t *canvas; caca_canvas_t *canvas;
void *buffer; void *buffer;
size_t buflen; size_t buflen;
int client_count; int client_count;
struct client *clients; struct client *clients;
RETSIGTYPE (*sigpipe_handler)(int); void (*sigpipe_handler)(int);
}; };
static void manage_connections(struct server *server); void fprint_ip(FILE *stream, struct sockaddr *ai);
static void manage_connections(struct server *server, int sockfd);
static int send_data(struct server *server, struct client *c); static int send_data(struct server *server, struct client *c);
ssize_t nonblock_write(int fd, void *buf, size_t len); ssize_t nonblock_write(int fd, void *buf, size_t len);
int main(void) int main(void)
{ {
int i, yes = 1, flags; int i, yes = 1, flags, fd, error;
struct server *server; struct server *server;
struct addrinfo ai_hints, *ai, *res;
char port_str[6];
char *tmp; char *tmp;
#if USE_WINSOCK #if USE_WINSOCK
WORD winsockVersion; WORD winsockVersion;
WSADATA wsaData; WSADATA wsaData;
winsockVersion = MAKEWORD(1, 1); winsockVersion = MAKEWORD(1, 1);
WSAStartup(winsockVersion, &wsaData); WSAStartup(winsockVersion, &wsaData);
#endif #endif
server = malloc(sizeof(struct server)); server = malloc(sizeof(struct server));
skipping to change at line 155 skipping to change at line 166
server->port = 0xCACA; /* 51914 */ server->port = 0xCACA; /* 51914 */
/* FIXME, handle >255 sizes */ /* FIXME, handle >255 sizes */
memcpy(server->prefix, INIT_PREFIX, sizeof(INIT_PREFIX)); memcpy(server->prefix, INIT_PREFIX, sizeof(INIT_PREFIX));
tmp = strstr(server->prefix, "____"); tmp = strstr(server->prefix, "____");
tmp[0] = (uint8_t) (server->width & 0xff00) >> 8; tmp[0] = (uint8_t) (server->width & 0xff00) >> 8;
tmp[1] = (uint8_t) server->width & 0xff; tmp[1] = (uint8_t) server->width & 0xff;
tmp[2] = (uint8_t) (server->height & 0xff00) >> 8; tmp[2] = (uint8_t) (server->height & 0xff00) >> 8;
tmp[3] = (uint8_t) server->height & 0xff; tmp[3] = (uint8_t) server->height & 0xff;
if((server->sockfd = socket(PF_INET, SOCK_STREAM, 0)) == -1) memset(&ai_hints, 0, sizeof(ai_hints));
ai_hints.ai_family = AF_UNSPEC;
ai_hints.ai_socktype = SOCK_STREAM;
ai_hints.ai_flags = AI_PASSIVE;
memset(port_str, 0, sizeof(port_str));
snprintf(port_str, 6, "%d", server->port);
error = getaddrinfo(NULL, port_str, &ai_hints, &ai);
if (error)
{ {
perror("socket"); perror("getaddrinfo");
return -1; return -1;
} }
if(setsockopt(server->sockfd, SOL_SOCKET, for (res = ai; res && server->sock_count < MAXSOCKS; res = res->ai_next)
SO_REUSEADDR, &yes, sizeof(int)) == -1)
{ {
perror("setsockopt SO_REUSEADDR"); if ((fd = socket(res->ai_addr->sa_family, SOCK_STREAM, 0)) == -1)
return -1; {
} perror("socket");
continue;
server->my_addr.sin_family = AF_INET; }
server-> my_addr.sin_port = htons(server->port); if(setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1)
server->my_addr.sin_addr.s_addr = INADDR_ANY; {
memset(&(server->my_addr.sin_zero), '\0', 8); perror("setsockopt: SO_REUSEADDR");
continue;
}
if (res->ai_addr->sa_family == AF_INET6)
if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &yes, sizeof(int)) ==
-1)
{
perror("setsockopt: IPV6_V6ONLY");
continue;
}
if (bind(fd, res->ai_addr, res->ai_addrlen) == -1)
{
perror("bind");
continue;
}
flags = fcntl(fd, F_GETFL, 0);
fcntl(fd, F_SETFL, flags | O_NONBLOCK);
if(listen(fd, BACKLOG) == -1)
{
perror("listen");
continue;
}
if(bind(server->sockfd, (struct sockaddr *)&server->my_addr, server->socks[server->sock_count].sockfd = fd;
sizeof(struct sockaddr)) == -1) server->sock_count++;
{ fprintf(stderr, "listening on ");
perror("bind"); fprint_ip(stderr, res->ai_addr);
return -1; fprintf(stderr, "\n");
} }
freeaddrinfo(ai);
/* Non blocking socket */ if (server->sock_count == 0)
flags = fcntl(server->sockfd, F_GETFL, 0);
fcntl(server->sockfd, F_SETFL, flags | O_NONBLOCK);
if(listen(server->sockfd, BACKLOG) == -1)
{ {
perror("listen"); fprintf(stderr, "Not listening\n");
return -1; return -1;
} }
server->canvas = caca_create_canvas(0, 0); server->canvas = caca_create_canvas(0, 0);
server->buffer = NULL; server->buffer = NULL;
/* Ignore SIGPIPE */ /* Ignore SIGPIPE */
server->sigpipe_handler = signal(SIGPIPE, SIG_IGN); server->sigpipe_handler = signal(SIGPIPE, SIG_IGN);
fprintf(stderr, "initialised network, listening on port %i\n", fprintf(stderr, "initialised network, listening on port %i\n",
server->port); server->port);
/* Main loop */ /* Main loop */
for(;;) for(;;)
{ {
restart: restart:
/* Manage new connections as this function will be called sometimes /* Manage new connections as this function will be called sometimes
* more often than display */ * more often than display */
manage_connections(server); for (i = 0; i < server->sock_count; i++)
manage_connections(server, server->socks[i].sockfd);
/* Read data from stdin */ /* Read data from stdin */
if(server->read < 12) if(server->read < 12)
{ {
read(0, server->input + server->read, 12 - server->read); read(0, server->input + server->read, 12 - server->read);
server->read = 12; server->read = 12;
} }
while(caca_import_canvas_from_memory(server->canvas, server->input, while(caca_import_canvas_from_memory(server->canvas, server->input,
server->read, "caca") < 0) server->read, "caca") < 0)
skipping to change at line 291 skipping to change at line 326
} }
if(server->buffer) if(server->buffer)
free(server->buffer); free(server->buffer);
caca_free_canvas(server->canvas); caca_free_canvas(server->canvas);
/* Restore SIGPIPE handler */ /* Restore SIGPIPE handler */
signal(SIGPIPE, server->sigpipe_handler); signal(SIGPIPE, server->sigpipe_handler);
for (i = 0; i < server->sock_count; i++)
close(server->socks[i].sockfd);
free(server); free(server);
#if USE_WINSOCK #if USE_WINSOCK
WSACleanup(); WSACleanup();
#endif #endif
return 0; return 0;
} }
/* /*
* XXX: The following functions are local * XXX: The following functions are local
*/ */
static void manage_connections(struct server *server) void fprint_ip(FILE *stream, struct sockaddr *ai)
{
char buffer[INET6_ADDRSTRLEN];
socklen_t len = sizeof(struct sockaddr_in6);
if (ai->sa_family == AF_INET)
len = sizeof(struct sockaddr_in);
int err = getnameinfo(ai, len, buffer, sizeof(buffer), NULL, 0, NI_NUMERICHO
ST);
if (err != 0)
fprintf(stream, "n/a");
else
fprintf(stream, "%s", buffer);
}
static void manage_connections(struct server *server, int sockfd)
{ {
int fd, flags; int fd, flags;
struct sockaddr_in remote_addr; struct sockaddr_in6 remote_addr;
socklen_t len = sizeof(struct sockaddr_in); socklen_t len = sizeof(struct sockaddr_in6);
fd = accept(server->sockfd, (struct sockaddr *)&remote_addr, &len); fd = accept(sockfd, (struct sockaddr*)&remote_addr, &len);
if(fd == -1) if(fd == -1)
return; return;
fprintf(stderr, "[%i] connected from %s\n", fprintf(stderr, "[%i] connected from ", fd);
fd, inet_ntoa(remote_addr.sin_addr)); fprint_ip(stderr, (struct sockaddr*)&remote_addr);
fprintf(stderr, "\n");
/* Non blocking socket */ /* Non blocking socket */
flags = fcntl(fd, F_SETFL, 0); flags = fcntl(fd, F_SETFL, 0);
fcntl(fd, F_SETFL, flags | O_NONBLOCK); fcntl(fd, F_SETFL, flags | O_NONBLOCK);
if(server->clients == NULL) if(server->clients == NULL)
{ {
server->clients = malloc(sizeof(struct client)); server->clients = malloc(sizeof(struct client));
if(server->clients == NULL) if(server->clients == NULL)
{ {
 End of changes. 22 change blocks. 
41 lines changed or deleted 97 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)