📄 log.c
字号:
/*Copyright (c) 2003,2004 Jeremy Kerr & Rusty RussellThis file is part of nfsim.nfsim is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation; either version 2 of the License, or(at your option) any later version.nfsim is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with nfsim; if not, write to the Free SoftwareFoundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA*/#define _GNU_SOURCE#include "core.h"#include "tui.h"#include "expect.h"#include "utils.h"#include <list.h>static struct { enum log_type type; char * name;} log_names[] = { { LOG_KERNEL, "kernel" }, { LOG_UI, "ui" }, { LOG_ROUTE, "route" }, { LOG_PROTOCOL, "protocol" }, { LOG_USERSPACE,"userspace" }, { LOG_PACKET, "packet" }, { LOG_HOOK, "hook" }, { 0, NULL }};static FILE *logstream;static int typemask = 0;static int describe_packets;#define PRINTK_BUFSIZ 4096/* Rusty says: only hippies need two pointers. */static char printk_buf[PRINTK_BUFSIZ];int log_describe_packets(void){ return describe_packets;}bool nfsim_log(enum log_type type, const char *format, ...){ va_list ap; char *line; bool ret; va_start(ap, format); line = talloc_vasprintf(NULL, format, ap); va_end(ap); if (!type || (type & typemask)) fprintf(logstream ?: stderr, "%s\n", line); ret = expect_log_hook(line); talloc_free(line); return ret;}static void nfsim_log_partial_v(enum log_type type, char *buf, unsigned bufsize, const char *format, va_list ap){ char *ptr; int len = strlen(buf); /* write to the end of buffer */ if (vsnprintf(buf + len, bufsize - len - 1, format, ap) > bufsize - len - 1) nfsim_log(LOG_ALWAYS, "nfsim_log_partial buffer is full!"); ptr = buf; /* print each bit that ends in a newline */ for (len = strcspn(ptr, "\n"); *(ptr + len); ptr += len, len = strcspn(ptr, "\n")) { nfsim_log(type, "%.*s", len++, ptr); } /* if we've printed, copy any remaining (non-newlined) parts (including the \0) to the front of buf */ memmove(buf, ptr, strlen(ptr) + 1);}void nfsim_log_partial(enum log_type type, char *buf, unsigned bufsize, const char *format, ...){ va_list ap; va_start(ap, format); nfsim_log_partial_v(type, buf, bufsize, format, ap); va_end(ap);}void printk(const char *format, ...){ va_list ap; va_start(ap, format); nfsim_log_partial_v(LOG_KERNEL, printk_buf, PRINTK_BUFSIZ, format, ap); va_end(ap);}static inline int parsetype(const char *type){ int i; for (i = 0; log_names[i].type; i++) if (streq(log_names[i].name, type)) return log_names[i].type; return 0;}static bool log_admin(int argc, char **argv){ char *logname; int i; if (argc == 1) { nfsim_log(LOG_ALWAYS, "current log types:", typemask); i = 0; while ((logname = log_names[i].name)) { if (typemask & log_names[i].type) nfsim_log(LOG_ALWAYS, "\t%s", log_names[i].name); i++; } return true; } if ((argc == 2 || argc == 3) && !strcasecmp(argv[1], "describe_packets")) { if (argc == 3) { describe_packets = !strcasecmp(argv[2], "on") || !strcasecmp(argv[2], "true"); } nfsim_log(argc == 2 ? LOG_ALWAYS : LOG_UI, "packet descriptions are %s", describe_packets ? "on" : "off"); return false; } if (argc > 1 && !strcmp(*argv[1] == 't' ? argv[1] : argv[1]+1, "types") ) { int newtypemask = 0; for (i = 2; i < argc; i++) { int type; if (!(type = parsetype(argv[i]))) { nfsim_log(LOG_ALWAYS, "no such type %s", argv[i]); return false; } newtypemask |= type; } switch (*argv[1]) { case 't': case '=': typemask = newtypemask; break; case '-': typemask &= ~newtypemask; break; case '+': typemask |= newtypemask; break; default: nfsim_log(LOG_ALWAYS, "unknown modifer: %c", *argv[1]); return false; } return true; } nfsim_log(LOG_ALWAYS, "meep"); return 1; }static void log_admin_help(int agc, char **argv){#include "log-help:log"/*** XML Help: <section id="c:log"> <title><command>log</command></title> <para>Manage logging settings</para> <cmdsynopsis> <command>log</command> <group choice="opt"> <arg choice="plain">=</arg> <arg choice="plain">+</arg> <arg choice="plain">-</arg> </group> <arg choice="req"><replaceable>type, ...</replaceable></arg> </cmdsynopsis> <para>Each log message is classified into one of the following types:</para> <variablelist> <varlistentry> <term>KERNEL</term> <listitem> <para>Kernel messages (including <function>printk()</function> calls) </para> </listitem> </varlistentry> <varlistentry> <term>UI</term> <listitem> <para>Messages from the user interface (deprecated?)</para> </listitem> </varlistentry> <varlistentry> <term>ROUTE</term> <listitem> <para>Routing information</para> </listitem> </varlistentry> <varlistentry> <term>PROTOCOL</term> <listitem> <para>Information from the protocol (IPv4) layer</para> </listitem> </varlistentry> <varlistentry> <term>PACKET</term> <listitem> <para>Information about packet movements (including netfilter hook results)</para> </listitem> </varlistentry> </variablelist> <para>The <command>log</command> command allows you to select which messages are displayed. By default, all messages will be shown.</para> <para>If the <replaceable>types</replaceable> argument is prefixed with a +, - or = character, those types will be added, removed or set as the current types of messages to be logged (repectively). If none of these characters is specified, = is assumed (the types are set to only those specified)</para> <para>Messages generated as a result of user input are always logged. </para> </section>*/}static void log_init(void){ logstream = stdout; if (!tui_quiet) typemask = -1; describe_packets = 1; memset(printk_buf, 0, PRINTK_BUFSIZ); tui_register_command("log", log_admin, log_admin_help);}init_call(log_init);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -