/*
Висим на tcp/514 порту, пишем в stdout */
#define _GNU_SOURCE
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <error.h>
#include <netdb.h>
#include <wchar.h>
#include <iconv.h>
#include <pthread.h>
#include <sys/socket.h>
#include <arpa/inet.h>
int Cp866ToUTF8(int fd, char *outbuf) {
char inbuf[128] = {'0'};
char *wrptr = (char *) outbuf;
size_t nread;
iconv_t cd;
ssize_t avail;
char *inptr = inbuf;
cd = iconv_open("UTF-8", "CP866");
nread = read(fd, inbuf, sizeof (inbuf));
iconv(cd, &inptr, &nread, &wrptr, &avail);
iconv_close(cd);
return (char *) wrptr - outbuf;
}
void *server_thread(void *ad) {
char out[128] = {0};
char time_buff[128] = {0};
struct tm tm;
time_t tme;
int fd = (int) (ssize_t) ad;
Cp866ToUTF8(fd, out);
shutdown(fd, SHUT_RD);
(void) close(fd);
tme = time(NULL);
localtime_r(&tme, &tm);
strftime(time_buff, sizeof (time_buff), "%d.%m.%Y %T", &tm);
printf("%s : ", time_buff);
printf("%s\n", out);
return (NULL);
}
int main(void) {
struct addrinfo hints;
struct addrinfo *addr_res;
pthread_attr_t pattr;
pthread_t pth;
int res, fd;
ssize_t th_fd;
hints.ai_family = AF_INET;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_PASSIVE | AI_ADDRCONFIG;
hints.ai_protocol = IPPROTO_TCP;
hints.ai_canonname = NULL;
hints.ai_addr = INADDR_ANY;
hints.ai_next = NULL;
if ((fd = socket(hints.ai_family, hints.ai_socktype, hints.ai_protocol)) < 0) {
perror("socket()");
return (1);
}
if ((res = getaddrinfo(NULL, "syslog", &hints, &addr_res)) != 0) {
fprintf(stderr, "getaddrinfo(): %s\n", gai_strerror(res));
return (2);
}
if (bind(fd, addr_res->ai_addr, addr_res->ai_addrlen) < 0) {
perror("bind()");
freeaddrinfo(addr_res);
return (3);
}
freeaddrinfo(addr_res);
if (listen(fd, SOMAXCONN) < 0) {
perror("listen()");
return (4);
}
if ((errno = pthread_attr_init(&pattr)) != 0) {
perror("pthread_attr_init()");
return (errno);
}
pthread_attr_setdetachstate(&pattr, PTHREAD_CREATE_DETACHED);
while (1) {
if ((th_fd = accept(fd, NULL, NULL)) < 0) {
perror("accept()");
return (6);
}
if ((errno =
pthread_create(&pth, &pattr, server_thread,
(void *) th_fd)) != 0) {
perror("pthread_create()");
return (errno);
}
}
return (0);
}