Annotation of qemu/roms/ipxe/src/net/udp/syslog.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (C) 2011 Michael Brown <[email protected]>.
                      3:  *
                      4:  * This program is free software; you can redistribute it and/or
                      5:  * modify it under the terms of the GNU General Public License as
                      6:  * published by the Free Software Foundation; either version 2 of the
                      7:  * License, or any later version.
                      8:  *
                      9:  * This program is distributed in the hope that it will be useful, but
                     10:  * WITHOUT ANY WARRANTY; without even the implied warranty of
                     11:  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
                     12:  * General Public License for more details.
                     13:  *
                     14:  * You should have received a copy of the GNU General Public License
                     15:  * along with this program; if not, write to the Free Software
                     16:  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
                     17:  */
                     18: 
                     19: FILE_LICENCE ( GPL2_OR_LATER );
                     20: 
                     21: /** @file
                     22:  *
                     23:  * Syslog protocol
                     24:  *
                     25:  */
                     26: 
                     27: #include <stdint.h>
                     28: #include <byteswap.h>
                     29: #include <ipxe/xfer.h>
                     30: #include <ipxe/open.h>
                     31: #include <ipxe/tcpip.h>
                     32: #include <ipxe/dhcp.h>
                     33: #include <ipxe/settings.h>
                     34: #include <ipxe/console.h>
                     35: #include <ipxe/ansiesc.h>
                     36: #include <ipxe/syslog.h>
                     37: 
                     38: /** The syslog server */
                     39: static struct sockaddr_tcpip logserver = {
                     40:        .st_port = htons ( SYSLOG_PORT ),
                     41: };
                     42: 
                     43: /** Syslog UDP interface operations */
                     44: static struct interface_operation syslogger_operations[] = {};
                     45: 
                     46: /** Syslog UDP interface descriptor */
                     47: static struct interface_descriptor syslogger_desc =
                     48:        INTF_DESC_PURE ( syslogger_operations );
                     49: 
                     50: /** The syslog UDP interface */
                     51: static struct interface syslogger = INTF_INIT ( syslogger_desc );
                     52: 
                     53: /******************************************************************************
                     54:  *
                     55:  * Console driver
                     56:  *
                     57:  ******************************************************************************
                     58:  */
                     59: 
                     60: /** Syslog line buffer */
                     61: static char syslog_buffer[SYSLOG_BUFSIZE];
                     62: 
                     63: /** Index into syslog line buffer */
                     64: static unsigned int syslog_idx;
                     65: 
                     66: /** Syslog recursion marker */
                     67: static int syslog_entered;
                     68: 
                     69: /** Syslog ANSI escape sequence handlers */
                     70: static struct ansiesc_handler syslog_ansiesc_handlers[] = {
                     71:        { 0, NULL }
                     72: };
                     73: 
                     74: /** Syslog ANSI escape sequence context */
                     75: static struct ansiesc_context syslog_ansiesc_ctx = {
                     76:        .handlers = syslog_ansiesc_handlers,
                     77: };
                     78: 
                     79: /**
                     80:  * Print a character to syslog console
                     81:  *
                     82:  * @v character                Character to be printed
                     83:  */
                     84: static void syslog_putchar ( int character ) {
                     85:        int rc;
                     86: 
                     87:        /* Do nothing if we have no log server */
                     88:        if ( ! logserver.st_family )
                     89:                return;
                     90: 
                     91:        /* Ignore if we are already mid-logging */
                     92:        if ( syslog_entered )
                     93:                return;
                     94: 
                     95:        /* Strip ANSI escape sequences */
                     96:        character = ansiesc_process ( &syslog_ansiesc_ctx, character );
                     97:        if ( character < 0 )
                     98:                return;
                     99: 
                    100:        /* Ignore carriage return */
                    101:        if ( character == '\r' )
                    102:                return;
                    103: 
                    104:        /* Treat newline as a terminator */
                    105:        if ( character == '\n' )
                    106:                character = 0;
                    107: 
                    108:        /* Add character to buffer */
                    109:        syslog_buffer[syslog_idx++] = character;
                    110: 
                    111:        /* Do nothing more unless we reach end-of-line (or end-of-buffer) */
                    112:        if ( ( character != 0 ) &&
                    113:             ( syslog_idx < ( sizeof ( syslog_buffer ) - 1 /* NUL */ ) ) ) {
                    114:                return;
                    115:        }
                    116: 
                    117:        /* Reset to start of buffer */
                    118:        syslog_idx = 0;
                    119: 
                    120:        /* Guard against re-entry */
                    121:        syslog_entered = 1;
                    122: 
                    123:        /* Send log message */
                    124:        if ( ( rc = xfer_printf ( &syslogger, "<%d>ipxe: %s",
                    125:                                  SYSLOG_PRIORITY ( SYSLOG_FACILITY,
                    126:                                                    SYSLOG_SEVERITY ),
                    127:                                  syslog_buffer ) ) != 0 ) {
                    128:                DBG ( "SYSLOG could not send log message: %s\n",
                    129:                      strerror ( rc ) );
                    130:        }
                    131: 
                    132:        /* Clear re-entry flag */
                    133:        syslog_entered = 0;
                    134: }
                    135: 
                    136: /** Syslog console driver */
                    137: struct console_driver syslog_console __console_driver = {
                    138:        .putchar = syslog_putchar,
                    139: };
                    140: 
                    141: /******************************************************************************
                    142:  *
                    143:  * Settings
                    144:  *
                    145:  ******************************************************************************
                    146:  */
                    147: 
                    148: /** Syslog server setting */
                    149: struct setting syslog_setting __setting ( SETTING_MISC ) = {
                    150:        .name = "syslog",
                    151:        .description = "Syslog server",
                    152:        .tag = DHCP_LOG_SERVERS,
                    153:        .type = &setting_type_ipv4,
                    154: };
                    155: 
                    156: /**
                    157:  * Apply syslog settings
                    158:  *
                    159:  * @ret rc             Return status code
                    160:  */
                    161: static int apply_syslog_settings ( void ) {
                    162:        struct sockaddr_in *sin_logserver =
                    163:                ( struct sockaddr_in * ) &logserver;
                    164:        struct in_addr old_addr;
                    165:        int len;
                    166:        int rc;
                    167: 
                    168:        /* Fetch log server */
                    169:        old_addr.s_addr = sin_logserver->sin_addr.s_addr;
                    170:        logserver.st_family = 0;
                    171:        if ( ( len = fetch_ipv4_setting ( NULL, &syslog_setting,
                    172:                                          &sin_logserver->sin_addr ) ) >= 0 ) {
                    173:                sin_logserver->sin_family = AF_INET;
                    174:        }
                    175: 
                    176:        /* Do nothing unless log server has changed */
                    177:        if ( sin_logserver->sin_addr.s_addr == old_addr.s_addr )
                    178:                return 0;
                    179: 
                    180:        /* Reset syslog connection */
                    181:        intf_restart ( &syslogger, 0 );
                    182: 
                    183:        /* Do nothing unless we have a log server */
                    184:        if ( ! logserver.st_family ) {
                    185:                DBG ( "SYSLOG has no log server\n" );
                    186:                return 0;
                    187:        }
                    188: 
                    189:        /* Connect to log server */
                    190:        if ( ( rc = xfer_open_socket ( &syslogger, SOCK_DGRAM,
                    191:                                       ( ( struct sockaddr * ) &logserver ),
                    192:                                       NULL ) ) != 0 ) {
                    193:                DBG ( "SYSLOG cannot connect to log server: %s\n",
                    194:                      strerror ( rc ) );
                    195:                return rc;
                    196:        }
                    197:        DBG ( "SYSLOG using log server %s\n",
                    198:              inet_ntoa ( sin_logserver->sin_addr ) );
                    199: 
                    200:        return 0;
                    201: }
                    202: 
                    203: /** Syslog settings applicator */
                    204: struct settings_applicator syslog_applicator __settings_applicator = {
                    205:        .apply = apply_syslog_settings,
                    206: };

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.