* Copyright 2003-2013, Axel DΓΆrfler, axeld@pinc-software.de.
* Distributed under the terms of the MIT License.
*/
#include <boot/vfs.h>
#include <boot/stdio.h>
#include <boot/net/NetStack.h>
#include <boot/net/UDP.h>
#include <errno.h>
#include <stdarg.h>
#include <string.h>
#include <algorithm>
#undef errno
int errno;
int*
_errnop(void)
{
return &errno;
}
#ifdef ENABLE_SYSLOG
static UDPSocket *sSyslogSocket = NULL;
static void
sendToSyslog(const char *message, int length)
{
if (sSyslogSocket == NULL) {
if (NetStack::Default() != NULL) {
sSyslogSocket = new(std::nothrow) UDPSocket;
sSyslogSocket->Bind(INADDR_ANY, 60514);
}
}
if (sSyslogSocket == NULL)
return;
while (length > 0) {
if (message[length - 1] != '\n'
&& message[length - 1] != '\r') {
break;
}
length--;
}
if (length <= 0)
return;
char buffer[1500];
const int facility = 0;
int severity = 7;
int offset = snprintf(buffer, sizeof(buffer),
"<%d>1 - - Haiku - - - \xEF\xBB\xBF",
facility * 8 + severity);
length = std::min(length, (int)sizeof(buffer) - offset);
memcpy(buffer + offset, message, length);
sSyslogSocket->Send(INADDR_BROADCAST, 514, buffer, offset + length);
}
#endif
int
vfprintf(FILE *file, const char *format, va_list list)
{
ConsoleNode *node = (ConsoleNode *)file;
char buffer[512];
int length = vsnprintf(buffer, sizeof(buffer), format, list);
length = std::min(length, (int)sizeof(buffer) - 1);
if (length > 0) {
node->Write(buffer, length);
#ifdef ENABLE_SYSLOG
sendToSyslog(buffer, length);
#endif
}
return length;
}
int
vprintf(const char *format, va_list args)
{
return vfprintf(stdout, format, args);
}
int
printf(const char *format, ...)
{
va_list args;
va_start(args, format);
int status = vfprintf(stdout, format, args);
va_end(args);
return status;
}
int
fprintf(FILE *file, const char *format, ...)
{
va_list args;
va_start(args, format);
int status = vfprintf(file, format, args);
va_end(args);
return status;
}
int
fputc(int c, FILE *file)
{
if (file == NULL)
return B_FILE_ERROR;
status_t status;
char character = (char)c;
status = ((ConsoleNode *)file)->Write(&character, 1);
#ifdef ENABLE_SYSLOG
sendToSyslog(&character, 1);
#endif
if (status > 0)
return character;
return status;
}
int
fputs(const char *string, FILE *file)
{
if (file == NULL)
return B_FILE_ERROR;
status_t status = ((ConsoleNode *)file)->Write(string, strlen(string));
fputc('\n', file);
#ifdef ENABLE_SYSLOG
sendToSyslog(string, strlen(string));
#endif
return status;
}
int
putc(int character)
{
return fputc(character, stdout);
}
int
putchar(int character)
{
return fputc(character, stdout);
}
int
puts(const char *string)
{
return fputs(string, stdout);
}