?? klogd.c
字號:
if( *ptr == '%' ) /* dangerous printf marker */ { delta = 0; while (len && *ptr == '%') { *line++ = *ptr++; /* copy it in */ space -= 1; len -= 1; delta++; } if (delta % 2) /* odd amount of %'s */ { if (space) { *line++ = '%'; /* so simply add one */ space -= 1; } else { *line++ = '\0'; /* remove the last one / terminate the string */ } } } break; case PARSING_SYMSTART: if( *ptr != '<' ) { parse_state = PARSING_TEXT; /* not a symbol */ break; } /* ** Save this character for now. If this turns out to ** be a valid symbol, this char will be replaced later. ** If not, we'll just leave it there. */ sym_start = line; /* this will point at the '<' */ *line++ = *ptr++; space -= 1; len -= 1; parse_state = PARSING_SYMBOL; /* symbol... */ break; case PARSING_SYMBOL: delta = copyin( line, space, ptr, len, ">\n[" ); line += delta; ptr += delta; space -= delta; len -= delta; if( space == 0 || len == 0 ) { break; /* full line_buff or end of input buffer */ } if( *ptr != '>' ) { parse_state = PARSING_TEXT; break; } *line++ = *ptr++; /* copy the '>' */ space -= 1; len -= 1; parse_state = PARSING_SYMEND; break; case PARSING_SYMEND: if( *ptr != ']' ) { parse_state = PARSING_TEXT; /* not a symbol */ break; } /* ** It's really a symbol! Replace address with the ** symbol text. */ { auto int sym_space; unsigned long value; auto struct symbol sym; auto char *symbol; *(line-1) = 0; /* null terminate the address string */ value = strtoul(sym_start+1, (char **) 0, 16); *(line-1) = '>'; /* put back delim */ symbol = LookupSymbol(value, &sym); if ( !symbol_lookup || symbol == (char *) 0 ) { parse_state = PARSING_TEXT; break; } /* ** verify there is room in the line buffer */ sym_space = space + ( line - sym_start ); if( sym_space < strlen(symbol) + 30 ) /*(30 should be overkill)*/ { parse_state = PARSING_TEXT; /* not enough space */ break; } delta = sprintf( sym_start, "%s+%d/%d]", symbol, sym.offset, sym.size ); space = sym_space + delta; line = sym_start + delta; symbols_expanded = 1; } ptr++; len--; parse_state = PARSING_TEXT; break; default: /* Can't get here! */ parse_state = PARSING_TEXT; } } return;}static void LogKernelLine(void){ auto int rdcnt; /* * Zero-fill the log buffer. This should cure a multitude of * problems with klogd logging the tail end of the message buffer * which will contain old messages. Then read the kernel log * messages into this fresh buffer. */ memset(log_buffer, '\0', sizeof(log_buffer)); if ( (rdcnt = ksyslog(2, log_buffer, sizeof(log_buffer))) < 0 ) { if ( errno == EINTR ) return; fprintf(stderr, "klogd: Error return from sys_sycall: " \ "%d - %s\n", errno, strerror(errno)); } else LogLine(log_buffer, rdcnt); return;}static void LogProcLine(void){ auto int rdcnt; /* * Zero-fill the log buffer. This should cure a multitude of * problems with klogd logging the tail end of the message buffer * which will contain old messages. Then read the kernel messages * from the message pseudo-file into this fresh buffer. */ memset(log_buffer, '\0', sizeof(log_buffer)); if ( (rdcnt = read(kmsg, log_buffer, sizeof(log_buffer)-1)) < 0 ) { if ( errno == EINTR ) return; Syslog(LOG_ERR, "Cannot read proc file system: %d - %s.", \ errno, strerror(errno)); } else LogLine(log_buffer, rdcnt); return;}int main(argc, argv) int argc; char *argv[];{ auto int ch, use_output = 0; auto char *log_level = (char *) 0, *output = (char *) 0;#ifndef TESTING chdir ("/");#endif /* Parse the command-line. */ while ((ch = getopt(argc, argv, "c:df:iIk:nopsvx2")) != EOF) switch((char)ch) { case '2': /* Print lines with symbols twice. */ symbols_twice = 1; break; case 'c': /* Set console message level. */ log_level = optarg; break; case 'd': /* Activity debug mode. */ debugging = 1; break; case 'f': /* Define an output file. */ output = optarg; use_output++; break; case 'i': /* Reload module symbols. */ SignalDaemon(SIGUSR1); return(0); case 'I': SignalDaemon(SIGUSR2); return(0); case 'k': /* Kernel symbol file. */ symfile = optarg; break; case 'n': /* don't fork */ no_fork++; break; case 'o': /* One-shot mode. */ one_shot = 1; break; case 'p': SetParanoiaLevel(1); /* Load symbols on oops. */ break; case 's': /* Use syscall interface. */ use_syscall = 1; break; case 'v': printf("klogd %s.%s\n", VERSION, PATCHLEVEL); exit (1); case 'x': symbol_lookup = 0; break; } /* Set console logging level. */ if ( log_level != (char *) 0 ) { if ( (strlen(log_level) > 1) || \ (strchr("12345678", *log_level) == (char *) 0) ) { fprintf(stderr, "klogd: Invalid console logging " "level <%s> specified.\n", log_level); return(1); } console_log_level = *log_level - '0'; } #ifndef TESTING /* * The following code allows klogd to auto-background itself. * What happens is that the program forks and the parent quits. * The child closes all its open file descriptors, and issues a * call to setsid to establish itself as an independent session * immune from control signals. * * fork() is only called if it should run in daemon mode, fork is * not disabled with the command line argument and there's no * such process running. */ if ( (!one_shot) && (!no_fork) ) { if (!check_pid(PidFile)) { if ( fork() == 0 ) { auto int fl; int num_fds = getdtablesize(); /* This is the child closing its file descriptors. */ for (fl= 0; fl <= num_fds; ++fl) { if ( fileno(stdout) == fl && use_output ) if ( strcmp(output, "-") == 0 ) continue; close(fl); } setsid(); } else exit(0); } else { fputs("klogd: Already running.\n", stderr); exit(1); } } /* tuck my process id away */ if (!check_pid(PidFile)) { if (!write_pid(PidFile)) Terminate(); } else { fputs("klogd: Already running.\n", stderr); Terminate(); }#endif /* Signal setups. */ for (ch= 1; ch < NSIG; ++ch) signal(ch, SIG_IGN); signal(SIGINT, stop_daemon); signal(SIGKILL, stop_daemon); signal(SIGTERM, stop_daemon); signal(SIGHUP, stop_daemon); signal(SIGTSTP, stop_logging); signal(SIGCONT, restart); signal(SIGUSR1, reload_daemon); signal(SIGUSR2, reload_daemon); /* Open outputs. */ if ( use_output ) { if ( strcmp(output, "-") == 0 ) output_file = stdout; else if ( (output_file = fopen(output, "w")) == (FILE *) 0 ) { fprintf(stderr, "klogd: Cannot open output file " \ "%s - %s\n", output, strerror(errno)); return(1); } } else openlog("kernel", 0, LOG_KERN); /* Handle one-shot logging. */ if ( one_shot ) { if (symbol_lookup) { InitKsyms(symfile); InitMsyms(); } if ( (logsrc = GetKernelLogSrc()) == kernel ) LogKernelLine(); else LogProcLine(); Terminate(); } /* Determine where kernel logging information is to come from. */#if defined(KLOGD_DELAY) sleep(KLOGD_DELAY);#endif logsrc = GetKernelLogSrc(); if (symbol_lookup) { InitKsyms(symfile); InitMsyms(); } /* The main loop. */ while (1) { if ( change_state ) ChangeLogging(); switch ( logsrc ) { case kernel: LogKernelLine(); break; case proc: LogProcLine(); break; case none: pause(); break; } }}/* * Local variables: * c-indent-level: 8 * c-basic-offset: 8 * tab-width: 8 * End: */
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -