summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--AUTHORS2
-rw-r--r--INSTALL35
-rw-r--r--Makefile58
-rw-r--r--NEWS169
-rw-r--r--README.1st65
-rw-r--r--README.linux107
-rw-r--r--klogd.8441
-rw-r--r--klogd.c1191
-rw-r--r--klogd.h40
-rw-r--r--ksym.c901
-rw-r--r--ksym_mod.c700
-rw-r--r--ksyms.h35
-rw-r--r--oops.c118
-rw-r--r--oops_test.c52
14 files changed, 77 insertions, 3837 deletions
diff --git a/AUTHORS b/AUTHORS
new file mode 100644
index 00000000..4c00f6ce
--- /dev/null
+++ b/AUTHORS
@@ -0,0 +1,2 @@
+Rainer Gerhards <rgerhards@adiscon.com>, Adiscon GmbH
+Michael Meckelein <mmeckelein@hq.adiscon.com>, Adiscon GmbH
diff --git a/INSTALL b/INSTALL
index c7a0ad9e..4c04611b 100644
--- a/INSTALL
+++ b/INSTALL
@@ -1,5 +1,7 @@
-1.) READ the README.linux file and the accompanying man pages. It will
- save you some frustration.
+1.) READ the README.linux file and the accompanying man pages (so it exists ;)).
+ It will save you some frustration. Be sure to review syslogd.conf.sample
+ it currently is the only place that contains information about the new
+ syslogd.conf format!
2.) Edit the Makefile for your installation. NOTE that if you have not
carried out step 1 you may make choices which could render your
@@ -18,20 +20,21 @@
influenced by the choice of conformance with the FSSTND or site
preferences.
-4.) For proper functioning both of these utilities are best run as root.
- This is probably not much of a problem since they will probably be
+4.) For proper functioning the daemon is best run as root.
+ This is probably not much of a problem since it will probably be
started either by init or as part of the rc.* startup process. There
- may be security concerns with running syslogd as root. Please repeat
+ may be security concerns with running it as root. Please repeat
step 1 if you are unsure of why this may be the case.
-5.) If kernel address to symbol translation is desired there is the
- possibility that a new kernel will need to be compiled. The patches
- to delimit kernel addresses requiring translation were added to
- kernel 1.3.43. If this kernel or a newer kernel is used there is
- no need to modify the kernel sources.
-
- If a kernel earlier than this is used the kernel sources will have to
- be patched. The patch to delimit addresses for translation is included
- with the sysklogd sources. The necessary modifications are quite
- generic and should require little modification over a wide range of
- kernel sources.
+5.) YOU NEED TO DECIDE IF YOU WOULD LIKE TO REPLACE THE STANDARD SYSLOGD OR NOT!
+ The is important as it influences the names used. If you call
+ make install
+ it will install this program under the name of rsyslogd. If you call it with
+ make install-replace
+ it will replace the existing syslogd, but save the former one under the name
+ of syslogd-previous. If you run install-replace multiple times, your
+ syslogd-previous will be OVERWRITTEN!
+ In either case, the system startup files will not be touched. If you use
+ install-replace, everthing should work as always, but if it doesn't, you've
+ probably discovered a beta bug ;) In any case, to use the new features, you
+ need to update you syslogd.conf.
diff --git a/Makefile b/Makefile
index f01ff39d..c0e5e621 100644
--- a/Makefile
+++ b/Makefile
@@ -1,4 +1,4 @@
-# Makefile for syslogd and klogd daemons.
+# Makefile for rsyslog
CC= gcc
#CFLAGS= -g -DSYSV -Wall
@@ -20,17 +20,6 @@ LIBS = -lmysqlclient #/var/lib/mysql/mysql
# to try uncommenting the following define.
# LIBS = /usr/lib/libresolv.a
-# A patch was forwarded which provided support for sysklogd under
-# the ALPHA. This patch included a reference to a library which may be
-# specific to the ALPHA. If you are attempting to build this package under
-# an ALPHA and linking fails with unresolved references please try
-# uncommenting the following define.
-# LIBS = ${LIBS} -linux
-
-# Define the following to impart start-up delay in klogd. This is
-# useful if klogd is started simultaneously or in close-proximity to syslogd.
-# KLOGD_START_DELAY = -DKLOGD_DELAY=5
-
# The following define determines whether the package adheres to the
# file system standard.
FSSTND = -DFSSTND
@@ -51,13 +40,12 @@ SYSLOGD_PIDNAME = -DSYSLOGD_PIDNAME=\"syslogd.pid\"
SYSLOGD_FLAGS= -DSYSLOG_INET -DSYSLOG_UNIXAF -DNO_SCCS ${FSSTND} \
${SYSLOGD_PIDNAME}
SYSLOG_FLAGS= -DALLOW_KERNEL_LOGGING
-KLOGD_FLAGS = ${FSSTND} ${KLOGD_START_DELAY}
DEB =
.c.o:
${CC} ${CFLAGS} -c $*.c
-all: syslogd klogd
+all: syslogd
test: syslog_tst ksym oops_test tsyslogd
@@ -66,19 +54,12 @@ install: install_man install_exec
syslogd: syslogd.o pidfile.o template.o stringbuf.o srUtils.o
${CC} ${LDFLAGS} -o syslogd syslogd.o pidfile.o template.o stringbuf.o srUtils.o ${LIBS}
-klogd: klogd.o syslog.o pidfile.o ksym.o ksym_mod.o
- ${CC} ${LDFLAGS} -o klogd klogd.o syslog.o pidfile.o ksym.o \
- ksym_mod.o ${LIBS}
-
syslog_tst: syslog_tst.o
${CC} ${LDFLAGS} -o syslog_tst syslog_tst.o
tsyslogd: syslogd.c version.h template.o stringbuf.o srUtils.o
$(CC) $(CFLAGS) -g -DTESTING $(SYSLOGD_FLAGS) -o tsyslogd syslogd.c pidfile.o template.o stringbuf.o srUtils.o $(LIBS)
-tklogd: klogd.c syslog.c ksym.c ksym_mod.c version.h
- $(CC) $(CFLAGS) -g -DTESTING $(KLOGD_FLAGS) -o tklogd klogd.c syslog.c ksym.c ksym_mod.c
-
srUtils.o: srUtils.c srUtils.h liblogging-stub.h
${CC} ${CFLAGS} ${SYSLOGD_FLAGS} $(DEB) -c srUtils.c
@@ -94,42 +75,21 @@ syslogd.o: syslogd.c version.h template.h
syslog.o: syslog.c
${CC} ${CFLAGS} ${SYSLOG_FLAGS} -c syslog.c
-klogd.o: klogd.c klogd.h version.h
- ${CC} ${CFLAGS} ${KLOGD_FLAGS} $(DEB) -c klogd.c
-
-ksym.o: ksym.c klogd.h
- ${CC} ${CFLAGS} ${KLOGD_FLAGS} -c ksym.c
-
-ksym_mod.o: ksym_mod.c klogd.h
- ${CC} ${CFLAGS} ${KLOGD_FLAGS} -c ksym_mod.c
-
syslog_tst.o: syslog_tst.c
${CC} ${CFLAGS} -c syslog_tst.c
-oops_test: oops.o
- ${CC} ${CFLAGS} -o oops_test oops_test.c
-
-oops.o: oops.c
- ${CC} ${CFLAGS} -D__KERNEL__ -DMODULE -c oops.c
-
-ksym: ksym_test.o ksym_mod.o
- ${CC} ${LDFLAGS} -o ksym ksym_test.o ksym_mod.o
-
-ksym_test.o: ksym.c
- ${CC} ${CFLAGS} -DTEST -o ksym_test.o -c ksym.c
-
clean:
rm -f *.o *.log *~ *.orig
clobber: clean
rm -f syslogd klogd ksym syslog_tst oops_test TAGS tsyslogd tklogd
-install_exec: syslogd klogd
+install_exec: syslogd
${INSTALL} -m 500 -s syslogd ${BINDIR}/syslogd
- ${INSTALL} -m 500 -s klogd ${BINDIR}/klogd
-install_man:
- ${INSTALL} -o ${MAN_OWNER} -g ${MAN_OWNER} -m 644 sysklogd.8 ${MANDIR}/man8/sysklogd.8
- ${INSTALL} -o ${MAN_OWNER} -g ${MAN_OWNER} -m 644 syslogd.8 ${MANDIR}/man8/syslogd.8
- ${INSTALL} -o ${MAN_OWNER} -g ${MAN_OWNER} -m 644 syslog.conf.5 ${MANDIR}/man5/syslog.conf.5
- ${INSTALL} -o ${MAN_OWNER} -g ${MAN_OWNER} -m 644 klogd.8 ${MANDIR}/man8/klogd.8
+# man not yet supported ;)
+#install_man:
+# ${INSTALL} -o ${MAN_OWNER} -g ${MAN_OWNER} -m 644 sysklogd.8 ${MANDIR}/man8/sysklogd.8
+# ${INSTALL} -o ${MAN_OWNER} -g ${MAN_OWNER} -m 644 syslogd.8 ${MANDIR}/man8/syslogd.8
+# ${INSTALL} -o ${MAN_OWNER} -g ${MAN_OWNER} -m 644 syslog.conf.5 ${MANDIR}/man5/syslog.conf.5
+# ${INSTALL} -o ${MAN_OWNER} -g ${MAN_OWNER} -m 644 klogd.8 ${MANDIR}/man8/klogd.8
diff --git a/NEWS b/NEWS
index 94d281c5..d0fd293a 100644
--- a/NEWS
+++ b/NEWS
@@ -1,170 +1,5 @@
-Version 1.3 Patch Level 3
-
-General. ------------------------------------------------------------------
-Update to documentation including klogd.8 manpage to reflect new features.
-
-Included patch for modules-2.0.0 package to provide support for signalling
-klogd of changes in kernel module status.
-
-klogd ---------------------------------------------------------------------
-Provided support for signalling klogd to reload static and kernel module
-symbol information via SIGUSR1 and SIGUSR2.
-
-Implemented -p switch to cause a reload of kernel module symbol information
-whenever a protection fault is detected.
-
-Informative message is printed whenever klogd state change occurs.
-
-Added -i and -I switches to signal the currently executing klogd daemon
-to reload symbold information.
-
-
-Version 1.3 Patch Level 2
-
-General. ------------------------------------------------------------------
-Added oops.c and oops_test.c. Oops.c implements a kernel loadable module
-which will generate a general protection fault. The oops_test.c program
-generates a test program for exercising the loadable module.
-
-syslogd ------------------------------------------------------------------
-Fixed bug resulting in file descriptors being orphaned when syslogd was
-initialized via signal handler.
-
-klogd ---------------------------------------------------------------------
-Bug fix to prevent errors when reading symbol tables with 64 bit addresses.
-
-Added support for debugging of protection faults occuring in kernel
-loadable modules.
-
-
-Version 1.3 Patch Level 1
-
-General. ------------------------------------------------------------------
-Cleanups in the Makefile.
-
-Patches to support compilation in the ALPHA environment. I have not
-been able to test these personally so if anyone has any feedback I
-would be interested in hearing from the Linux ALPHA community.
-
-Spelling and grammar corrections in the man pages.
-
-syslogd ------------------------------------------------------------------
-Patch to fix parsing of hostnames in syslogd.c.
-
-The return value of gethostbyname is now properly checked. This should
-fix the problems with core dumps when name resolution failed.
-
-Bounds error fixed when setting the file descriptors for UNIX domain
-sockets.
-
-klogd ---------------------------------------------------------------------
-Error checking and reporting enhanced. I have a couple of reports
-that klogd is experiencing errors when reading the /proc filesystem.
-Any additional information would be appreciated.
-
-The sys_syslog function has been renamed to ksyslog. This was in a
-set patches for ALPHA support so I am assuming that this is necessary
-for that environment
-
-
-Version 1.3
-
-Numerous changes, performance enhancements, code cleanups and bug fixes.
-Too many to individually summarize. Have a look at the top of each
-source file for more information.
-
-** Default behavior of sysklogd is not to accept any message that
-is sent via syslog/udp. To allow remote reception add -r to the
-command-line arguments.
-
-** Spaces are now accepted in the syslog configuration file. This
-should be a real crowd pleaser.
-
-syslogd now uses dynamic allocation of logging output descriptors.
-There is no longer a static limit on the number of log destinations
-that can be defined.
-
-klogd supports on-the-fly kernel address to symbol translations.
-This requires that a valid kernel symbol map be found at execution.
-
-** The default level for console log messages was changed to 6. This
-means that kernel messages with a priority less than or equal to 5
-(KERN_NOTICE) will be logged to the console.
-
- This item has been flagged because it results in a behavior
- change which will be different if version 1.3 replaces an
- existing 1.2 binary. Linus strongly suggested that this
- behavior be changed and in the 1.3.3x kernels Linus in fact
- made it impossible to set the console log level lower than
- about 5.
-
- There were good reasons from his perspective for doing so.
- The most troublesome being that user's of packaged
- distributions were not able to generate register dumps with
- the kernel debugging keys, most notably altgr-SCRLCK.
-
- If a kernels prior to 1.3.3x are being used the klogd daemon
- invocation must be changed to something like: klogd -c 1
-
- This will turn off logging of kernel messages to the console.
- If you understand the ramifications of this the 1.3.3x kernels
- can be patched to allow the suppression of console log
- messages. It is important to be cognizant of the effects of
- these changes. None the least of which is that Linus and Alan
- will yell at you if you complain about not being able to
- generate kernel debugging information.. :-)
-
----------------------------------------------------------------------------
-Version 1.2
-Fixes to both klogd and syslogd so that the package will compile without
-errors due to the vararg procedures.
-
-Modified pid files produced so that the names of the files are
-klogd.pid and syslogd.pid respectively.
-
-Fixed bug in klogd which prevented output from being directed to a file
-when the program was compiled to auto-background itself. In the
-auto-backgrounding configuration the forked process was closing all its
-file descriptors which was causing the errant behavior.
-
-Modified signal handling in klogd so that all signal are set to ignored
-before establishing specific signal handlers.
-
-Fixed bug in syslogd which was causing a delay in opening of the /dev/log
-UNIX domain socket. This should correct the race condition which was
-preventing klogd from properly logging kernel messages when the two
-daemons were started in rapid succession.
-
-Modified the closing/opening of file descriptors when syslogd was
-compiled with auto-backgrounding support. Closes the potential for
-a somewhat obscure bug caused by the /dev/log socket being opened on
-fd 0.
-
-Changed the names of the man pages from an extension of 1 to 8.
----------------------------------------------------------------------------
-Version 1.1
-Extensive changes and additional functionality added to klogd. Please
-see sources and man-pages for documentation.
-
-Fixed bugs in both syslogd and klogd with respect to fragmented
-message re-assembly. Bootup messages should now be display properly.
-
-Fixed bug in syslogd which prevented proper logging of messages with
-priority classes of none and emerg.
-
-Fixed bug which caused core dump when messages were logged to users.
-Also fixed bug with messages to login type of LOGIN.
-
-Fixed problem with zombies being left when messages were logged to
-multiple users.
-
-Enhanced functionality of syslog_tst program.
-
-Added man-pages.
----------------------------------------------------------------------------
-
---------------------------------------------------------------------------
-Version 1.0
+Version 0.8.0
-Initial release.
+Initial testing release.
---------------------------------------------------------------------------
diff --git a/README.1st b/README.1st
deleted file mode 100644
index 39467563..00000000
--- a/README.1st
+++ /dev/null
@@ -1,65 +0,0 @@
-Very important information before using version 1.3
----------------------------------------------------
-
-The included version of syslogd behaves in a slightly different manner
-to the one in former releases. Please review the following important
-differences:
-
-* By default the syslog daemon doesn't accept any message from the
- syslog/udp port. To enable this add "-r" to the command-line
- arguments. You _have to_ add this on every host that should run as a
- centralized network log server.
-
- You also should take a look at other new command-line arguments:
- "-l" and "-s".
-
- The syslog daemon by default does not forward to a remote host any
- log messages which it received from a remote host. This is an
- attempt to prevent syslog loops. If you desire this behavior the
- -h command-line switch can be used to enable this behavior.
-
-* Syslogd was designed to strip off the local domain from every
- message that comes from any host in the same domain. Unfortunately
- this feature didn't work in every cases. This is now corrected. So
- you might not get the fqdn anymore.
-
- If you use any scripts that analyze logfiles, please bare this in
- mind.
-
-* Syslogd doesn't touch the filemode of any logfile. If it has to
- create one, it will be world-readable. If you do not want this
- (i.e. if auth.* is logged) you have to create the file by hand and
- change permissions.
-
-* If you notice that some of your programs make heavy use of the
- syslog facility and your disks get loud you might want to turn
- fsync()ing after each line off. But note that in doing so you
- increase the likelihood of lost information in the event of a
- system crash.
-
-* If you're going to start klogd or syslogd by init(8), you don't have
- to hack the code anymore. Instead add "-n" to the command-line
- arguments.
-
-* Klogd can now be used to decode EIP addresses if it can determine a
- System.map file (command-line argument "-k"). This is a very useful
- feature if your system crashes, but its usability depends on an
- actual and correct System.map file.
-
-* Both system utilities now check for and respect the existence of .pid
- files. If the utilities are started by configuration scripts on
- stable systems there is the potential that the process ID numbers of
- the utilities will be identical from one system boot to another.
- This will cause both klogd and syslogd to terminate.
-
- Both klogd and syslogd will attempt to remove their .pid files when
- they receive termination signals. The difficulty noted above
- typically occurs when a system crash occurs or an uncatchable signal
- (kill -9) is used to stop the daemons.
-
- The cleanest solution to this problem is to insure that the system
- configuration scripts (rc.*) provide a clean working environment for
- a freshly booted system. As part of the initialization process
- these scripts should remove all old .pid files found in /var/run.
- This will insure that klogd and syslogd start properly even if prior
- executions have been terminated harshly.
diff --git a/README.linux b/README.linux
index bfebf53e..1192f3f7 100644
--- a/README.linux
+++ b/README.linux
@@ -1,72 +1,55 @@
-Welcome to the sysklogd package for Linux. All the utility
-documentation has now been moved into the man pages. Please review
-these carefully before proceeding.
-
-Version 1.3 of the package is the culmination of about two years of
-experience and bug reports on the 1.2 version from both the INTERNET
-and our corporate Linux networks. The utilities in this package should
-provide VERY reliable system logging. Klogd and syslogd have both
-been stress tested in kernel development environments where literally
-hundreds of megabytes of kernel messages have been blasted through
-them. If either utility should fail the development team would
-appreciate debug information so that the bug can be reproduced and
-squashed.
-
-Both utilities (syslogd, klogd) can be either run from init or started
+Welcome to the rsyslog package for Linux. This package has
+been forked from the sysklogd standard package. The goal of the
+rsyslog project is to provide a more configurable and reliable
+syslog deamon. By "reliable", we mean support for reliable transmission
+modes like TCP or RFC 3195 (syslog-reliable).
+We do NOT imply that the sysklogd package is unreliable. In fact, the
+opposite is the case and we assume that for the time being the well-
+used sysklogd package offers better program reliability than our
+brand-new modifications to it. The name "rsyslog" stems back to the
+planned support for syslog-reliable. Ironically, the initial release
+of rsyslog does NEITHER support syslog-reliable NOR tcp based syslog.
+Instead, it contains enhanced configurability and other enhancements
+(like database support). The reason for this is that full support for
+RFC 3195 would require even more changes and especially fundamental architectural
+changes. Also, questions asked on the loganalysis list and at other
+places indicated that RFC3195 is NOT a prime priority for users, but
+rather better control over the output format. So here we are, with
+a rsyslod that covers a lot of enhancements, but not a single one
+of these that made its name ;)
+
+The next enhancement scheduled is support for the new syslog-protocol
+internet draft format, not the least to see how easy/compliated it is
+to implement. We already know that some subleties of syslog-protocol will
+require at least one considerable architectural change to the syslogd
+and this might delay things a little. Our immediate goal is to receive
+feedback and get the bugs out of the current release. Only after that
+we intend to advance the code and introduce new features.
+
+The database support was included so that our web-based syslog interface
+can be used. This is another open source project which can be found
+under http://www.liblogging.org . We highly recommend having a look at
+it. It might not work for you if you expect thousands of messages per
+second (because your database won't be able to provide adequate performace),
+but in many cases it is a very handy analysis and troubleshooting tool.
+
+The utility (syslogd) can be either run from init or started
as part of the rc.* sequence. Caution should be used when starting
-these utilities from init since the default configuration is for both of
-these utilities to auto-background themselves. Depending on the
+it from init since the default configuration is for it
+is to auto-background itself. Depending on the
version of init being used this could either result in the process
table being filled or at least 10 copies of the daemon being started.
If auto-backgrounding is NOT desired the command line option -n should
be used to disable the auto-fork feature.
-I have found work on the sysklogd package to be an interesting example
-of the powers of the INTERNET. Stephen, Juha, Shane, Martin and
-myself have successfully collaborated on the development of this
-package without ever having met each other, in fact we could pass on
-the street without realizing it. What I have developed is a profound
-respect for the personal capabilities of each one of these
-individuals. Perhaps the greatest `Linux Legacy' will be that its
-development/enhancement is truly an example of the powers of
-international cooperation through the worldwide INTERNET.
-
-We would be interested in keeping track of any and all bug
-fixes/changes that are made. At the time that work was started on the
-sysklogd package the syslog(d) sources seemed to have fallen into
-neglect. This work started with and continues the believe that it is
-important to maintain consistent standardized system utilities
-sources. Hopefully the Linux community will find these sources to be
-a useful addition to the software gene pool.
-
There is a mailing list covering this package and syslog in general.
-The lists address is sysklogd@Infodrom.North.DE . To subscribe send a
-mail to Majordomo@Infodrom.North.DE with a line "subscribe sysklogd"
-in the message body.
+The lists address is rsyslog@lists.adiscon.com .
-New versions of this package will be available at Joey's ftp server.
-ftp://ftp.infodrom.north.de/pub/people/joey/sysklogd/
+New versions of this package and additional information will be available
+under www.monitorware.com/rsyslog as well as under the rsyslog project
+on sourceforge.net.
Best regards,
-
-Dr. Wettstein
-Oncology Research Division Computing Facility
-Roger Maris Cancer Center
-Fargo, ND
-greg@wind.enjellic.com
-
-Stephen Tweedie
-Department of Computer Science
-Edinburgh University, Scotland
-
-Juha Virtanen
-jiivee@hut.fi
-
-Shane Alderton
-shane@ion.apana.org.au
-
-Martin Schulze
-Infodrom Oldenburg
-joey@linux.de
-
-And a host of bug reporters whose contributions cannot be underestimated.
+Rainer Gerhards
+Adiscon
+2004-11-26
diff --git a/klogd.8 b/klogd.8
deleted file mode 100644
index 02949dad..00000000
--- a/klogd.8
+++ /dev/null
@@ -1,441 +0,0 @@
-.\" Copyright 1994 Dr. Greg Wettstein, Enjellic Systems Development.
-.\" May be distributed under the GNU General Public License
-.\" Sun Jul 30 01:35:55 MET: Martin Schulze: Updates
-.\" Sun Nov 19 23:22:21 MET: Martin Schulze: Updates
-.\" Mon Aug 19 09:42:08 CDT 1996: Dr. G.W. Wettstein: Updates
-.\"
-.TH KLOGD 8 "21 August, 1999" "Version 1.4" "Linux System Administration"
-.SH NAME
-klogd \- Kernel Log Daemon
-.LP
-.SH SYNOPSIS
-.B klogd
-.RB [ " \-c "
-.I n
-]
-.RB [ " \-d " ]
-.RB [ " \-f "
-.I fname
-]
-.RB [ " \-iI " ]
-.RB [ " \-n " ]
-.RB [ " \-o " ]
-.RB [ " \-p " ]
-.RB [ " \-s " ]
-.RB [ " \-k "
-.I fname
-]
-.RB [ " \-v " ]
-.RB [ " \-x " ]
-.RB [ " \-2 " ]
-.LP
-.SH DESCRIPTION
-.B klogd
-is a system daemon which intercepts and logs Linux kernel
-messages.
-.LP
-.SH OPTIONS
-.TP
-.BI "\-c " n
-Sets the default log level of console messages to \fIn\fR.
-.TP
-.B "\-d"
-Enable debugging mode. This will generate \fBLOTS\fR of output to
-stderr.
-.TP
-.BI "\-f " file
-Log messages to the specified filename rather than to the syslog facility.
-.TP
-.BI "\-i \-I"
-Signal the currently executing klogd daemon. Both of these switches control
-the loading/reloading of symbol information. The \-i switch signals the
-daemon to reload the kernel module symbols. The \-I switch signals for a
-reload of both the static kernel symbols and the kernel module symbols.
-.TP
-.B "\-n"
-Avoid auto-backgrounding. This is needed especially if the
-.B klogd
-is started and controlled by
-.BR init (8).
-.TP
-.B "-o"
-Execute in 'one\-shot' mode. This causes \fBklogd\fP to read and log
-all the messages that are found in the kernel message buffers. After
-a single read and log cycle the daemon exits.
-.TP
-.B "-p"
-Enable paranoia. This option controls when klogd loads kernel module symbol
-information. Setting this switch causes klogd to load the kernel module
-symbol information whenever an Oops string is detected in the kernel message
-stream.
-.TP
-.B "-s"
-Force \fBklogd\fP to use the system call interface to the kernel message
-buffers.
-.TP
-.BI "\-k " file
-Use the specified file as the source of kernel symbol information.
-.TP
-.B "\-v"
-Print version and exit.
-.TP
-.B "\-x"
-Omits EIP translation and therefore doesn't read the System.map file.
-.TP
-.B "\-2"
-When symbols are expanded, print the line twice. Once with addresses
-converted to symbols, once with the raw text. This allows external
-programs such as ksymoops do their own processing on the original
-data.
-.LP
-.SH OVERVIEW
-The functionality of klogd has been typically incorporated into other
-versions of syslogd but this seems to be a poor place for it. In the
-modern Linux kernel a number of kernel messaging issues such as
-sourcing, prioritization and resolution of kernel addresses must be
-addressed. Incorporating kernel logging into a separate process
-offers a cleaner separation of services.
-
-In Linux there are two potential sources of kernel log information: the
-.I /proc
-file system and the syscall (sys_syslog) interface, although
-ultimately they are one and the same. Klogd is designed to choose
-whichever source of information is the most appropriate. It does this
-by first checking for the presence of a mounted
-.I /proc
-file system. If this is found the
-.I /proc/kmsg
-file is used as the source of kernel log
-information. If the proc file system is not mounted
-.B klogd
-uses a
-system call to obtain kernel messages. The command line switch
-.RB ( "\-s" )
-can be used to force klogd to use the system call interface as its
-messaging source.
-
-If kernel messages are directed through the
-.BR syslogd " daemon the " klogd
-daemon, as of version 1.1, has the ability to properly prioritize
-kernel messages. Prioritization of the kernel messages was added to it
-at approximately version 0.99pl13 of the kernel. The raw kernel messages
-are of the form:
-.IP
-\<[0\-7]\>Something said by the kernel.
-.PP
-The priority of the kernel message is encoded as a single numeric
-digit enclosed inside the <> pair. The definitions of these values is
-given in the kernel include file kernel.h. When a message is received
-from the kernel the klogd daemon reads this priority level and assigns
-the appropriate priority level to the syslog message. If file output
-(\fB-f\fR) is used the prioritization sequence is left pre\-pended to the
-kernel message.
-
-The
-.B klogd
-daemon also allows the ability to alter the presentation of
-kernel messages to the system console. Consequent with the
-prioritization of kernel messages was the inclusion of default
-messaging levels for the kernel. In a stock kernel the the default
-console log level is set to 7. Any messages with a priority level
-numerically lower than 7 (higher priority) appear on the console.
-
-Messages of priority level 7 are considered to be 'debug' messages and
-will thus not appear on the console. Many administrators,
-particularly in a multi\-user environment, prefer that all kernel
-messages be handled by klogd and either directed to a file or to
-the syslogd daemon. This prevents 'nuisance' messages such as line
-printer out of paper or disk change detected from cluttering the
-console.
-
-When
-.B \-c
-is given on the commandline the
-.B klogd
-daemon will execute a system call to inhibit all kernel messages from
-being displayed on the console. Former versions always issued this
-system call and defaulted to all kernel messages except for panics.
-This is handled differently nowardays so
-.B klogd
-doesn't need to set this value anymore. The
-argument given to the \fB\-c\fR switch specifies the priority level of
-messages which will be directed to the console. Note that messages of
-a priority value LOWER than the indicated number will be directed to
-the console.
-.IP
-For example, to have the kernel display all messages with a
-priority level of 3
-.BR "" ( KERN_ERR )
-or more severe the following
-command would be executed:
-.IP
-.nf
- klogd \-c 4
-.fi
-.PP
-The definitions of the numeric values for kernel messages are given in
-the file
-.IR kernel.h " which can be found in the " /usr/include/linux
-directory if the kernel sources are installed. These values parallel
-the syslog priority values which are defined in the file
-.IR syslog.h " found in the " /usr/include/sys " sub\-directory."
-
-The klogd daemon can also be used in a 'one\-shot' mode for reading the
-kernel message buffers. One shot mode is selected by specifying the
-\fB\-o\fR switch on the command line. Output will be directed to either the
-syslogd daemon or to an alternate file specified by the \fB-f\fR switch.
-.IP
-For example, to read all the kernel messages after a system
-boot and record them in a file called krnl.msg the following
-command would be given.
-.IP
-.nf
- klogd -o -f ./krnl.msg
-.fi
-.PP
-.SH KERNEL ADDRESS RESOLUTION
-If the kernel detects an internal error condition a general protection
-fault will be triggered. As part of the GPF handling procedure the
-kernel prints out a status report indicating the state of the
-processor at the time of the fault. Included in this display are the
-contents of the microprocessor's registers, the contents of the kernel
-stack and a tracing of what functions were being executed at the time
-of the fault.
-
-This information is
-.B EXTREMELY IMPORTANT
-in determining what caused the internal error condition. The
-difficulty comes when a kernel developer attempts to analyze this
-information. The raw numeric information present in the protection
-fault printout is of very little use to the developers. This is due
-to the fact that kernels are not identical and the addresses of
-variable locations or functions will not be the same in all kernels.
-In order to correctly diagnose the cause of failure a kernel developer
-needs to know what specific kernel functions or variable locations
-were involved in the error.
-
-As part of the kernel compilation process a listing is created which
-specified the address locations of important variables and function in
-the kernel being compiled. This listing is saved in a file called
-System.map in the top of the kernel directory source tree. Using this
-listing a kernel developer can determine exactly what the kernel was
-doing when the error condition occurred.
-
-The process of resolving the numeric addresses from the protection
-fault printout can be done manually or by using the
-.B ksymoops
-program which is included in the kernel sources.
-
-As a convenience
-.B klogd
-will attempt to resolve kernel numeric addresses to their symbolic
-forms if a kernel symbol table is available at execution time. If you
-require the original address of the symbol, use the
-.B -2
-switch to preserve the numeric address. A
-symbol table may be specified by using the \fB\-k\fR switch on the
-command line. If a symbol file is not explicitly specified the
-following filenames will be tried:
-
-.nf
-.I /boot/System.map
-.I /System.map
-.I /usr/src/linux/System.map
-.fi
-
-Version information is supplied in the system maps as of kernel
-1.3.43. This version information is used to direct an intelligent
-search of the list of symbol tables. This feature is useful since it
-provides support for both production and experimental kernels.
-
-For example a production kernel may have its map file stored in
-/boot/System.map. If an experimental or test kernel is compiled with
-the sources in the 'standard' location of /usr/src/linux the system
-map will be found in /usr/src/linux/System.map. When klogd starts
-under the experimental kernel the map in /boot/System.map will be
-bypassed in favor of the map in /usr/src/linux/System.map.
-
-Modern kernels as of 1.3.43 properly format important kernel addresses
-so that they will be recognized and translated by klogd. Earlier
-kernels require a source code patch be applied to the kernel sources.
-This patch is supplied with the sysklogd sources.
-
-The process of analyzing kernel protections faults works very well
-with a static kernel. Additional difficulties are encountered when
-attempting to diagnose errors which occur in loadable kernel modules.
-Loadable kernel modules are used to implement kernel functionality in
-a form which can be loaded or unloaded at will. The use of loadable
-modules is useful from a debugging standpoint and can also be useful
-in decreasing the amount of memory required by a kernel.
-
-The difficulty with diagnosing errors in loadable modules is due to
-the dynamic nature of the kernel modules. When a module is loaded the
-kernel will allocate memory to hold the module, when the module is
-unloaded this memory will be returned back to the kernel. This
-dynamic memory allocation makes it impossible to produce a map file
-which details the addresses of the variable and functions in a kernel
-loadable module. Without this location map it is not possible for a
-kernel developer to determine what went wrong if a protection fault
-involves a kernel module.
-
-.B klogd
-has support for dealing with the problem of diagnosing protection
-faults in kernel loadable modules. At program start time or in
-response to a signal the daemon will interrogate the kernel for a
-listing of all modules loaded and the addresses in memory they are
-loaded at. Individual modules can also register the locations of
-important functions when the module is loaded. The addresses of these
-exported symbols are also determined during this interrogation
-process.
-
-When a protection fault occurs an attempt will be made to resolve
-kernel addresses from the static symbol table. If this fails the
-symbols from the currently loaded modules are examined in an attempt
-to resolve the addresses. At the very minimum this allows klogd to
-indicate which loadable module was responsible for generating the
-protection fault. Additional information may be available if the
-module developer chose to export symbol information from the module.
-
-Proper and accurate resolution of addresses in kernel modules requires
-that
-.B klogd
-be informed whenever the kernel module status changes. The
-.B \-i
-and
-.B \-I
-switches can be used to signal the currently executing daemon that
-symbol information be reloaded. Of most importance to proper
-resolution of module symbols is the
-.B \-i
-switch. Each time a kernel module is loaded or removed from the
-kernel the following command should be executed:
-
-.nf
-.I klogd \-i
-.fi
-
-The
-.B \-p
-switch can also be used to insure that module symbol information is up
-to date. This switch instructs
-.B klogd
-to reload the module symbol information whenever a protection fault
-is detected. Caution should be used before invoking the program in
-\'paranoid\' mode. The stability of the kernel and the operating
-environment is always under question when a protection fault occurs.
-Since the klogd daemon must execute system calls in order to read the
-module symbol information there is the possibility that the system may
-be too unstable to capture useful information. A much better policy
-is to insure that klogd is updated whenever a module is loaded or
-unloaded. Having uptodate symbol information loaded increases the
-probability of properly resolving a protection fault if it should occur.
-
-Included in the sysklogd source distribution is a patch to the
-modules-2.0.0 package which allows the
-.B insmod,
-.B rmmod
-and
-.B modprobe
-utilities to automatically signal
-.B klogd
-whenever a module is inserted or removed from the kernel. Using this
-patch will insure that the symbol information maintained in klogd is
-always consistent with the current kernel state.
-.PP
-.SH SIGNAL HANDLING
-The
-.B klogd
-will respond to eight signals:
-.BR SIGHUP ", " SIGINT ", " SIGKILL ", " SIGTERM ", " SIGTSTP ", "
-.BR SIGUSR1 ", "SIGUSR2 " and " SIGCONT ". The"
-.BR SIGINT ", " SIGKILL ", " SIGTERM " and " SIGHUP
-signals will cause the daemon to close its kernel log sources and
-terminate gracefully.
-
-The
-.BR SIGTSTP " and " SIGCONT
-signals are used to start and stop kernel logging. Upon receipt of a
-.B SIGTSTP
-signal the daemon will close its
-log sources and spin in an idle loop. Subsequent receipt of a
-.B SIGCONT
-signal will cause the daemon to go through its initialization sequence
-and re-choose an input source. Using
-.BR SIGSTOP " and " SIGCONT
-in combination the kernel log input can be re-chosen without stopping and
-restarting the daemon. For example if the \fI/proc\fR file system is to be
-un-mounted the following command sequence should be used:
-.PP
-.PD 0
-.TP
- # kill -TSTP pid
-.TP
- # umount /proc
-.TP
- # kill -CONT pid
-.PD
-.PP
-Notations will be made in the system logs with
-.B LOG_INFO
-priority
-documenting the start/stop of logging.
-
-The
-.BR SIGUSR1 " and " SIGUSR2
-signals are used to initiate loading/reloading of kernel symbol information.
-Receipt of the
-.B SIGUSR1
-signal will cause the kernel module symbols to be reloaded. Signaling the
-daemon with
-.B SIGUSR2
-will cause both the static kernel symbols and the kernel module symbols to
-be reloaded.
-
-Provided that the System.map file is placed in an appropriate location the
-signal of generally greatest usefulness is the
-.B SIGUSR1
-signal. This signal is designed to be used to signal the daemon when kernel
-modules are loaded/unloaded. Sending this signal to the daemon after a
-kernel module state change will insure that proper resolution of symbols will
-occur if a protection fault occurs in the address space occupied by a kernel
-module.
-.LP
-.SH FILES
-.PD 0
-.TP
-.I /proc/kmsg
-One Source for kernel messages
-.B klogd
-.TP
-.I /var/run/klogd.pid
-The file containing the process id of
-.B klogd
-.TP
-.I /boot/System.map, /System.map, /usr/src/linux/System.map
-Default locations for kernel system maps.
-.PD
-.SH BUGS
-Probably numerous. Well formed context diffs appreciated.
-.LP
-.SH AUTHOR
-The
-.B klogd
-was originally written by Steve Lord (lord@cray.com), Greg Wettstein
-made major improvements.
-
-.PD 0
-.TP
-Dr. Greg Wettstein (greg@wind.enjellic.com)
-.TP
-Enjellic Systems Development
-.PD
-.PP
-.PD 0
-.TP
-Oncology Research Divsion Computing Facility
-.TP
-Roger Maris Cancer Center
-.TP
-Fargo, ND 58122
-.PD
-.zZ
diff --git a/klogd.c b/klogd.c
deleted file mode 100644
index 2c8e765e..00000000
--- a/klogd.c
+++ /dev/null
@@ -1,1191 +0,0 @@
-/*
- klogd.c - main program for Linux kernel log daemon.
- Copyright (c) 1995 Dr. G.W. Wettstein <greg@wind.rmcc.com>
-
- This file is part of the sysklogd package, a kernel and system log daemon.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-/*
- * Steve Lord (lord@cray.com) 7th Nov 92
- *
- * Modified to check for kernel info by Dr. G.W. Wettstein 02/17/93.
- *
- * Fri Mar 12 16:53:56 CST 1993: Dr. Wettstein
- * Modified LogLine to use a newline as the line separator in
- * the kernel message buffer.
- *
- * Added debugging code to dump the contents of the kernel message
- * buffer at the start of the LogLine function.
- *
- * Thu Jul 29 11:40:32 CDT 1993: Dr. Wettstein
- * Added syscalls to turn off logging of kernel messages to the
- * console when klogd becomes responsible for kernel messages.
- *
- * klogd now catches SIGTERM and SIGKILL signals. Receipt of these
- * signals cases the clean_up function to be called which shuts down
- * kernel logging and re-enables logging of messages to the console.
- *
- * Sat Dec 11 11:54:22 CST 1993: Dr. Wettstein
- * Added fixes to allow compilation with no complaints with -Wall.
- *
- * When the daemon catches a fatal signal (SIGTERM, SIGKILL) a
- * message is output to the logfile advising that the daemon is
- * going to terminate.
- *
- * Thu Jan 6 11:54:10 CST 1994: Dr. Wettstein
- * Major re-write/re-organization of the code.
- *
- * Klogd now assigns kernel messages to priority levels when output
- * to the syslog facility is requested. The priority level is
- * determined by decoding the prioritization sequence which is
- * tagged onto the start of the kernel messages.
- *
- * Added the following program options: -f arg -c arg -s -o -d
- *
- * The -f switch can be used to specify that output should
- * be written to the named file.
- *
- * The -c switch is used to specify the level of kernel
- * messages which are to be directed to the console.
- *
- * The -s switch causes the program to use the syscall
- * interface to the kernel message facility. This can be
- * used to override the presence of the /proc filesystem.
- *
- * The -o switch causes the program to operate in 'one-shot'
- * mode. A single call will be made to read the complete
- * kernel buffer. The contents of the buffer will be
- * output and the program will terminate.
- *
- * The -d switch causes 'debug' mode to be activated. This
- * will cause the daemon to generate LOTS of output to stderr.
- *
- * The buffer decomposition function (LogLine) was re-written to
- * squash a bug which was causing only partial kernel messages to
- * be written to the syslog facility.
- *
- * The signal handling code was modified to properly differentiate
- * between the STOP and TSTP signals.
- *
- * Added pid saving when the daemon detaches into the background. Thank
- * you to Juha Virtanen (jiivee@hut.fi) for providing this patch.
- *
- * Mon Feb 6 07:31:29 CST 1995: Dr. Wettstein
- * Significant re-organization of the signal handling code. The
- * signal handlers now only set variables. Not earth shaking by any
- * means but aesthetically pleasing to the code purists in the group.
- *
- * Patch to make things more compliant with the file system standards.
- * Thanks to Chris Metcalf for prompting this helpful change.
- *
- * The routines responsible for reading the kernel log sources now
- * initialize the buffers before reading. I think that this will
- * solve problems with non-terminated kernel messages producing
- * output of the form: new old old old
- *
- * This may also help influence the occassional reports of klogd
- * failing under significant load. I think that the jury may still
- * be out on this one though. My thanks to Joerg Ahrens for initially
- * tipping me off to the source of this problem. Also thanks to
- * Michael O'Reilly for tipping me off to the best fix for this problem.
- * And last but not least Mark Lord for prompting me to try this as
- * a means of attacking the stability problem.
- *
- * Specifying a - as the arguement to the -f switch will cause output
- * to be directed to stdout rather than a filename of -. Thanks to
- * Randy Appleton for a patch which prompted me to do this.
- *
- * Wed Feb 22 15:37:37 CST 1995: Dr. Wettstein
- * Added version information to logging startup messages.
- *
- * Wed Jul 26 18:57:23 MET DST 1995: Martin Schulze
- * Added an commandline argument "-n" to avoid forking. This obsoletes
- * the compiler define NO_FORK. It's more useful to have this as an
- * argument as there are many binary versions and one doesn't need to
- * recompile the daemon.
- *
- * Thu Aug 10 19:01:08 MET DST 1995: Martin Schulze
- * Added my pidfile.[ch] to it to perform a better handling with pidfiles.
- * Now both, syslogd and klogd, can only be started once. They check the
- * pidfile.
- *
- * Fri Nov 17 15:05:43 CST 1995: Dr. Wettstein
- * Added support for kernel address translation. This required moving
- * some definitions and includes to the new klogd.h file. Some small
- * code cleanups and modifications.
- *
- * Mon Nov 20 10:03:39 MET 1995
- * Added -v option to print the version and exit.
- *
- * Thu Jan 18 11:19:46 CST 1996: Dr. Wettstein
- * Added suggested patches from beta-testers. These address two
- * two problems. The first is segmentation faults which occur with
- * the ELF libraries. This was caused by passing a null pointer to
- * the strcmp function.
- *
- * Added a second patch to remove the pidfile as part of the
- * termination cleanup sequence. This minimizes the potential for
- * conflicting pidfiles causing immediate termination at boot time.
- *
- * Wed Aug 21 09:13:03 CDT 1996: Dr. Wettstein
- * Added ability to reload static symbols and kernel module symbols
- * under control of SIGUSR1 and SIGUSR2 signals.
- *
- * Added -p switch to select 'paranoid' behavior with respect to the
- * loading of kernel module symbols.
- *
- * Informative line now printed whenever a state change occurs due
- * to signal reception by the daemon.
- *
- * Added the -i and -I command line switches to signal the currently
- * executing daemon.
- *
- * Tue Nov 19 10:15:36 PST 1996: Leland Olds <olds@eskimo.com>
- * Corrected vulnerability to buffer overruns by rewriting LogLine
- * routine. Obscenely long kernel messages will now be broken up
- * into lines no longer than LOG_LINE_LENGTH.
- *
- * The last version of LogLine was vulnerable to buffer overruns:
- * - Kernel messages longer than LOG_LINE_LENGTH caused a buffer
- * overrun.
- * - If a line was determined to be shorter than LOG_LINE_LENGTH,
- * the routine "ExpandKadds" could cause the line grow by
- * an unknown amount and overrun a buffer.
- * I turned these routines into a little parsing state machine that
- * should not have these problems.
- *
- * Sun Jun 15 16:23:29 MET DST 1997: Michael Alan Dorman
- * Some more glibc patches made by <mdorman@debian.org>.
- *
- * Thu Aug 21 12:11:27 MET DST 1997: Martin Schulze <joey@infodrom.north.de>
- * Fixed little mistake which prevented klogd from accepting a
- * console log
- *
- * Fri Jan 9 00:39:52 CET 1998: Martin Schulze <joey@infodrom.north.de>
- * Changed the behaviour of klogd when receiving a terminate
- * signal. Now the program terminates immediately instead of
- * completing the receipt of a kernel message, i.e the read()
- * call. The old behaveiour could result in klogd being
- * recognized as being undead, because it'll only die after a
- * message has been received.
- *
- * Fri Jan 9 11:03:48 CET 1998: Martin Schulze <joey@infodrom.north.de>
- * Corrected some code that caused klogd to dump core when
- * receiving messages containing '%', some of them exist in
- * 2.1.78. Thanks to Chu-yeon Park <kokids@doit.ajou.ac.kr> for
- * informing me.
- *
- * Fri Jan 9 23:38:19 CET 1998: Florian La Roche <florian@knorke.saar.de>
- * Added -x switch to omit EIP translation and System.map evaluation.
- *
- * Sun Jan 25 20:47:46 CET 1998: Martin Schulze <joey@infodrom.north.de>
- * As the bug covering the %'s introduced a problem with
- * unevaluated priorities I've worked out a real fix that strips
- * %'s to an even number which is harmless for printf.
- *
- * Sat Oct 10 20:01:48 CEST 1998: Martin Schulze <joey@infodrom.north.de>
- * Added support for TESTING define which will turn klogd into
- * stdio-mode used for debugging.
- *
- * Mon Apr 13 18:18:45 CEST 1998: Martin Schulze <joey@infodrom.north.de>
- * Modified System.map read function to try all possible map
- * files until a file with matching version is found. Added support for
- * Debian release.
- *
- * Mon Oct 12 13:01:27 MET DST 1998: Martin Schulze <joey@infodrom.north.de>
- * Used unsigned long and strtoul() to resolve kernel oops symbols.
- *
- * Sun Jan 3 18:38:03 CET 1999: Martin Schulze <joey@infodrom.north.de>
- * Shortened LOG_LINE_LENGTH in order to get long lines splitted
- * up earlier and syslogd has a better chance concatenating them
- * together again.
- *
- * Sat Aug 21 12:27:02 CEST 1999: Martin Schulze <joey@infodrom.north.de>
- * Skip newline when reading in messages.
- *
- * Tue Sep 12 22:14:33 CEST 2000: Martin Schulze <joey@infodrom.ffis.de>
- * Don't feed a buffer directly to a printf-type routine, use
- * "%s" as format string instead. Thanks to Jouko Pynnönen
- * <jouko@solutions.fi> for pointing this out.
- *
- * Tue Sep 12 22:44:57 CEST 2000: Martin Schulze <joey@infodrom.ffis.de>
- * Commandline option `-2': When symbols are expanded, print the
- * line twice. Once with addresses converted to symbols, once with the
- * raw text. Allows external programs such as ksymoops do their own
- * processing on the original data. Thanks to Keith Owens
- * <kaos@ocs.com.au> for the patch.
- *
- * Mon Sep 18 09:32:27 CEST 2000: Martin Schulze <joey@infodrom.ffis.de>
- * Added patch to fix priority decoding after moving kernel
- * messgages into "%s". Thanks to Solar Designer
- * <solar@false.com> for the patch.
- *
- * Sun Mar 11 20:23:44 CET 2001: Martin Schulze <joey@infodrom.ffis.de>
- * Stop LogLine() from being called with wrong argument when a
- * former calculation failed already. Thanks to Thomas Roessler
- * <roessler@does-not-exist.org> for providing a patch.
- *
- * Ignore zero bytes, no busy loop is entered anymore. Several
- * people have submitted patches: Troels Walsted Hansen
- * <troels@thule.no>, Wolfgang Oertl <Wolfgang.Oertl@uibk.ac.at>
- * and Thomas Roessler.
- */
-
-
-/* Includes. */
-#include <unistd.h>
-#include <signal.h>
-#include <errno.h>
-#include <sys/fcntl.h>
-#include <sys/stat.h>
-#if !defined(__GLIBC__)
-#include <linux/time.h>
-#endif /* __GLIBC__ */
-#include <stdarg.h>
-#include <paths.h>
-#include <stdlib.h>
-#include "klogd.h"
-#include "ksyms.h"
-#ifndef TESTING
-#include "pidfile.h"
-#endif
-#include "version.h"
-
-#define __LIBRARY__
-#include <linux/unistd.h>
-#if !defined(__GLIBC__)
-# define __NR_ksyslog __NR_syslog
-_syscall3(int,ksyslog,int, type, char *, buf, int, len);
-#else
-#include <sys/klog.h>
-#define ksyslog klogctl
-#endif
-
-#define LOG_BUFFER_SIZE 4096
-#define LOG_LINE_LENGTH 1000
-
-#ifndef TESTING
-#if defined(FSSTND)
-static char *PidFile = _PATH_VARRUN "klogd.pid";
-#else
-static char *PidFile = "/etc/klogd.pid";
-#endif
-#endif
-
-static int kmsg,
- change_state = 0,
- terminate = 0,
- caught_TSTP = 0,
- reload_symbols = 0,
- console_log_level = -1;
-
-static int use_syscall = 0,
- one_shot = 0,
- symbol_lookup = 1,
- no_fork = 0; /* don't fork - don't run in daemon mode */
-
-static char *symfile = (char *) 0,
- log_buffer[LOG_BUFFER_SIZE];
-
-static FILE *output_file = (FILE *) 0;
-
-static enum LOGSRC {none, proc, kernel} logsrc;
-
-int debugging = 0;
-int symbols_twice = 0;
-
-
-/* Function prototypes. */
-extern int ksyslog(int type, char *buf, int len);
-static void CloseLogSrc(void);
-extern void restart(int sig);
-extern void stop_logging(int sig);
-extern void stop_daemon(int sig);
-extern void reload_daemon(int sig);
-static void Terminate(void);
-static void SignalDaemon(int);
-static void ReloadSymbols(void);
-static void ChangeLogging(void);
-static enum LOGSRC GetKernelLogSrc(void);
-static void LogLine(char *ptr, int len);
-static void LogKernelLine(void);
-static void LogProcLine(void);
-extern int main(int argc, char *argv[]);
-
-
-static void CloseLogSrc()
-
-{
- /* Turn on logging of messages to console. */
- ksyslog(7, NULL, 0);
-
- /* Shutdown the log sources. */
- switch ( logsrc )
- {
- case kernel:
- ksyslog(0, 0, 0);
- Syslog(LOG_INFO, "Kernel logging (ksyslog) stopped.");
- break;
- case proc:
- close(kmsg);
- Syslog(LOG_INFO, "Kernel logging (proc) stopped.");
- break;
- case none:
- break;
- }
-
- if ( output_file != (FILE *) 0 )
- fflush(output_file);
- return;
-}
-
-
-void restart(sig)
-
- int sig;
-
-{
- signal(SIGCONT, restart);
- change_state = 1;
- caught_TSTP = 0;
- return;
-}
-
-
-void stop_logging(sig)
-
- int sig;
-
-{
- signal(SIGTSTP, stop_logging);
- change_state = 1;
- caught_TSTP = 1;
- return;
-}
-
-
-void stop_daemon(sig)
-
- int sig;
-
-{
- Terminate();
- return;
-}
-
-
-void reload_daemon(sig)
-
- int sig;
-
-{
- change_state = 1;
- reload_symbols = 1;
-
-
- if ( sig == SIGUSR2 )
- {
- ++reload_symbols;
- signal(SIGUSR2, reload_daemon);
- }
- else
- signal(SIGUSR1, reload_daemon);
-
- return;
-}
-
-
-static void Terminate()
-
-{
- CloseLogSrc();
- Syslog(LOG_INFO, "Kernel log daemon terminating.");
- sleep(1);
- if ( output_file != (FILE *) 0 )
- fclose(output_file);
- closelog();
-#ifndef TESTING
- (void) remove_pid(PidFile);
-#endif
- exit(1);
-}
-
-static void SignalDaemon(sig)
-
- int sig;
-
-{
-#ifndef TESTING
- auto int pid = check_pid(PidFile);
-
- kill(pid, sig);
-#else
- kill(getpid(), sig);
-#endif
- return;
-}
-
-
-static void ReloadSymbols()
-
-{
- if (symbol_lookup) {
- if ( reload_symbols > 1 )
- InitKsyms(symfile);
- InitMsyms();
- }
- reload_symbols = change_state = 0;
- return;
-}
-
-
-static void ChangeLogging(void)
-
-{
- /* Terminate kernel logging. */
- if ( terminate == 1 )
- Terminate();
-
- /* Indicate that something is happening. */
- Syslog(LOG_INFO, "klogd %s.%s, ---------- state change ----------\n", \
- VERSION, PATCHLEVEL);
-
- /* Reload symbols. */
- if ( reload_symbols > 0 )
- {
- ReloadSymbols();
- return;
- }
-
- /* Stop kernel logging. */
- if ( caught_TSTP == 1 )
- {
- CloseLogSrc();
- logsrc = none;
- change_state = 0;
- return;
- }
-
- /*
- * The rest of this function is responsible for restarting
- * kernel logging after it was stopped.
- *
- * In the following section we make a decision based on the
- * kernel log state as to what is causing us to restart. Somewhat
- * groady but it keeps us from creating another static variable.
- */
- if ( logsrc != none )
- {
- Syslog(LOG_INFO, "Kernel logging re-started after SIGSTOP.");
- change_state = 0;
- return;
- }
-
- /* Restart logging. */
- logsrc = GetKernelLogSrc();
- change_state = 0;
- return;
-}
-
-
-static enum LOGSRC GetKernelLogSrc(void)
-
-{
- auto struct stat sb;
-
-
- /* Set level of kernel console messaging.. */
- if ( (console_log_level != -1)
- && (ksyslog(8, NULL, console_log_level) < 0) && \
- (errno == EINVAL) )
- {
- /*
- * An invalid arguement error probably indicates that
- * a pre-0.14 kernel is being run. At this point we
- * issue an error message and simply shut-off console
- * logging completely.
- */
- Syslog(LOG_WARNING, "Cannot set console log level - disabling "
- "console output.");
- ksyslog(6, NULL, 0);
- }
-
- /*
- * First do a stat to determine whether or not the proc based
- * file system is available to get kernel messages from.
- */
- if ( use_syscall ||
- ((stat(_PATH_KLOG, &sb) < 0) && (errno == ENOENT)) )
- {
- /* Initialize kernel logging. */
- ksyslog(1, NULL, 0);
-#ifdef DEBRELEASE
- Syslog(LOG_INFO, "klogd %s.%s#%s, log source = ksyslog "
- "started.", VERSION, PATCHLEVEL, DEBRELEASE);
-#else
- Syslog(LOG_INFO, "klogd %s.%s, log source = ksyslog "
- "started.", VERSION, PATCHLEVEL);
-#endif
- return(kernel);
- }
-
-#ifndef TESTING
- if ( (kmsg = open(_PATH_KLOG, O_RDONLY)) < 0 )
- {
- fprintf(stderr, "klogd: Cannot open proc file system, " \
- "%d - %s.\n", errno, strerror(errno));
- ksyslog(7, NULL, 0);
- exit(1);
- }
-#else
- kmsg = fileno(stdin);
-#endif
-
-#ifdef DEBRELEASE
- Syslog(LOG_INFO, "klogd %s.%s#%s, log source = %s started.", \
- VERSION, PATCHLEVEL, DEBRELEASE, _PATH_KLOG);
-#else
- Syslog(LOG_INFO, "klogd %s.%s, log source = %s started.", \
- VERSION, PATCHLEVEL, _PATH_KLOG);
-#endif
- return(proc);
-}
-
-
-extern void Syslog(int priority, char *fmt, ...)
-
-{
- va_list ap;
- char *argl;
-
- if ( debugging )
- {
- fputs("Logging line:\n", stderr);
- fprintf(stderr, "\tLine: %s\n", fmt);
- fprintf(stderr, "\tPriority: %d\n", priority);
- }
-
- /* Handle output to a file. */
- if ( output_file != (FILE *) 0 )
- {
- va_start(ap, fmt);
- vfprintf(output_file, fmt, ap);
- va_end(ap);
- fputc('\n', output_file);
- fflush(output_file);
- if (!one_shot)
- fsync(fileno(output_file));
- return;
- }
-
- /* Output using syslog. */
- if (!strcmp(fmt, "%s"))
- {
- va_start(ap, fmt);
- argl = va_arg(ap, char *);
- if (argl[0] == '<' && argl[1] && argl[2] == '>')
- {
- switch ( argl[1] )
- {
- case '0':
- priority = LOG_EMERG;
- break;
- case '1':
- priority = LOG_ALERT;
- break;
- case '2':
- priority = LOG_CRIT;
- break;
- case '3':
- priority = LOG_ERR;
- break;
- case '4':
- priority = LOG_WARNING;
- break;
- case '5':
- priority = LOG_NOTICE;
- break;
- case '6':
- priority = LOG_INFO;
- break;
- case '7':
- default:
- priority = LOG_DEBUG;
- }
- argl += 3;
- }
- syslog(priority, fmt, argl);
- va_end(ap);
-#ifdef TESTING
- putchar('\n');
-#endif
- return;
- }
-
- va_start(ap, fmt);
- vsyslog(priority, fmt, ap);
- va_end(ap);
-#ifdef TESTING
- printf ("\n");
-#endif
-
- return;
-}
-
-
-/*
- * Copy characters from ptr to line until a char in the delim
- * string is encountered or until min( space, len ) chars have
- * been copied.
- *
- * Returns the actual number of chars copied.
- */
-static int copyin( char *line, int space,
- const char *ptr, int len,
- const char *delim )
-{
- auto int i;
- auto int count;
-
- count = len < space ? len : space;
-
- for(i=0; i<count && !strchr(delim, *ptr); i++ ) { *line++ = *ptr++; }
-
- return( i );
-}
-
-/*
- * Messages are separated by "\n". Messages longer than
- * LOG_LINE_LENGTH are broken up.
- *
- * Kernel symbols show up in the input buffer as : "[<aaaaaa>]",
- * where "aaaaaa" is the address. These are replaced with
- * "[symbolname+offset/size]" in the output line - symbolname,
- * offset, and size come from the kernel symbol table.
- *
- * If a kernel symbol happens to fall at the end of a message close
- * in length to LOG_LINE_LENGTH, the symbol will not be expanded.
- * (This should never happen, since the kernel should never generate
- * messages that long.
- *
- * To preserve the original addresses, lines containing kernel symbols
- * are output twice. Once with the symbols converted and again with the
- * original text. Just in case somebody wants to run their own Oops
- * analysis on the syslog, e.g. ksymoops.
- */
-static void LogLine(char *ptr, int len)
-{
- enum parse_state_enum {
- PARSING_TEXT,
- PARSING_SYMSTART, /* at < */
- PARSING_SYMBOL,
- PARSING_SYMEND /* at ] */
- };
-
- static char line_buff[LOG_LINE_LENGTH];
-
- static char *line =line_buff;
- static enum parse_state_enum parse_state = PARSING_TEXT;
- static int space = sizeof(line_buff)-1;
-
- static char *sym_start; /* points at the '<' of a symbol */
-
- auto int delta = 0; /* number of chars copied */
- auto int symbols_expanded = 0; /* 1 if symbols were expanded */
- auto int skip_symbol_lookup = 0; /* skip symbol lookup on this pass */
- auto char *save_ptr = ptr; /* save start of input line */
- auto int save_len = len; /* save length at start of input line */
-
- while( len > 0 )
- {
- if( space == 0 ) /* line buffer is full */
- {
- /*
- ** Line too long. Start a new line.
- */
- *line = 0; /* force null terminator */
-
- if ( debugging )
- {
- fputs("Line buffer full:\n", stderr);
- fprintf(stderr, "\tLine: %s\n", line);
- }
-
- Syslog( LOG_INFO, "%s", line_buff );
- line = line_buff;
- space = sizeof(line_buff)-1;
- parse_state = PARSING_TEXT;
- symbols_expanded = 0;
- skip_symbol_lookup = 0;
- save_ptr = ptr;
- save_len = len;
- }
-
- switch( parse_state )
- {
- case PARSING_TEXT:
- 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 == '\0' ) /* zero byte */
- {
- ptr++; /* skip zero byte */
- space -= 1;
- len -= 1;
-
- break;
- }
-
- if( *ptr == '\n' ) /* newline */
- {
- ptr++; /* skip newline */
- space -= 1;
- len -= 1;
-
- *line = 0; /* force null terminator */
- Syslog( LOG_INFO, "%s", line_buff );
- line = line_buff;
- space = sizeof(line_buff)-1;
- if (symbols_twice) {
- if (symbols_expanded) {
- /* reprint this line without symbol lookup */
- symbols_expanded = 0;
- skip_symbol_lookup = 1;
- ptr = save_ptr;
- len = save_len;
- }
- else
- {
- skip_symbol_lookup = 0;
- save_ptr = ptr;
- save_len = len;
- }
- }
- break;
- }
- if( *ptr == '[' ) /* possible kernel symbol */
- {
- *line++ = *ptr++;
- space -= 1;
- len -= 1;
- if (!skip_symbol_lookup)
- parse_state = PARSING_SYMSTART; /* at < */
- break;
- }
- 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:
- */
diff --git a/klogd.h b/klogd.h
deleted file mode 100644
index ef60f088..00000000
--- a/klogd.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- klogd.h - main header file for Linux kernel log daemon.
- Copyright (c) 1995 Dr. G.W. Wettstein <greg@wind.rmcc.com>
-
- This file is part of the sysklogd package, a kernel and system log daemon.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-/*
- * Symbols and definitions needed by klogd.
- *
- * Thu Nov 16 12:45:06 CST 1995: Dr. Wettstein
- * Initial version.
- */
-
-/* Useful include files. */
-#include <stdio.h>
-#include <syslog.h>
-#include <string.h>
-
-
-/* Function prototypes. */
-extern int InitKsyms(char *);
-extern int InitMsyms(void);
-extern char * ExpandKadds(char *, char *);
-extern void SetParanoiaLevel(int);
-extern void Syslog(int priority, char *fmt, ...);
diff --git a/ksym.c b/ksym.c
deleted file mode 100644
index 0a6d7151..00000000
--- a/ksym.c
+++ /dev/null
@@ -1,901 +0,0 @@
-/*
- ksym.c - functions for kernel address->symbol translation
- Copyright (c) 1995, 1996 Dr. G.W. Wettstein <greg@wind.rmcc.com>
- Copyright (c) 1996 Enjellic Systems Development
-
- This file is part of the sysklogd package, a kernel and system log daemon.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-/*
- * This file contains functions which handle the translation of kernel
- * numeric addresses into symbols for the klogd utility.
- *
- * Sat Oct 28 09:00:14 CDT 1995: Dr. Wettstein
- * Initial Version.
- *
- * Fri Nov 24 12:50:52 CST 1995: Dr. Wettstein
- * Added VERBOSE_DEBUGGING define to make debugging output more
- * manageable.
- *
- * Added support for verification of the loaded kernel symbols. If
- * no version information can be be found in the mapfile a warning
- * message is issued but translation will still take place. This
- * will be the default case if kernel versions < 1.3.43 are used.
- *
- * If the symbols in the mapfile are of the same version as the kernel
- * that is running an informative message is issued. If the symbols
- * in the mapfile do not match the current kernel version a warning
- * message is issued and translation is disabled.
- *
- * Wed Dec 6 16:14:11 CST 1995: Dr. Wettstein
- * Added /boot/System.map to the list of symbol maps to search for.
- * Also made this map the first item in the search list. I am open
- * to CONSTRUCTIVE suggestions for any additions or corrections to
- * the list of symbol maps to search for. Be forewarned that the
- * list in use is the consensus agreement between myself, Linus and
- * some package distributers. It is a given that no list will suit
- * everyone's taste. If you have rabid concerns about the list
- * please feel free to edit the system_maps array and compile your
- * own binaries.
- *
- * Added support for searching of the list of symbol maps. This
- * allows support for access to multiple symbol maps. The theory
- * behind this is that a production kernel may have a system map in
- * /boot/System.map. If a test kernel is booted this system map
- * would be skipped in favor of one found in /usr/src/linux.
- *
- * Thu Jan 18 11:18:31 CST 1996: Dr. Wettstein
- * Added patch from beta-testers to allow for reading of both
- * ELF and a.out map files.
- *
- * Wed Aug 21 09:15:49 CDT 1996: Dr. Wettstein
- * Reloading of kernel module symbols is now turned on by the
- * SetParanoiaLevel function. The default behavior is to NOT reload
- * the kernel module symbols when a protection fault is detected.
- *
- * Added support for freeing of the current kernel module symbols.
- * This was necessary to support reloading of the kernel module symbols.
- *
- * When a matching static symbol table is loaded the kernel version
- * number is printed.
- *
- * Mon Jun 9 17:12:42 CST 1997: Martin Schulze
- * Added #1 and #2 to some error messages in order to being able
- * to divide them (ulmo@Q.Net)
- *
- * Fri Jun 13 10:50:23 CST 1997: Martin Schulze
- * Changed definition of LookupSymbol to non-static because it is
- * used in klogd.c, too.
- *
- * Fri Jan 9 23:00:08 CET 1998: Martin Schulze <joey@infodrom.north.de>
- * Fixed bug that caused klogd to die if there is no System.map available.
- *
- * Sun 29 Mar 18:14:07 BST 1998: Mark Simon Phillips <M.S.Phillips@nortel.co.uk>
- * Switched to fgets() as gets() is not buffer overrun secure.
- *
- * Mon Apr 13 18:18:45 CEST 1998: Martin Schulze <joey@infodrom.north.de>
- * Modified loop for detecting the correct system map. Now it won't
- * stop if a file has been found but doesn't contain the correct map.
- * Special thanks go go Mark Simon Phillips for the hint.
- *
- * Mon Oct 12 00:42:30 CEST 1998: Martin Schulze <joey@infodrom.north.de>
- * Modified CheckVersion()
- * . Use shift to decode the kernel version
- * . Compare integers of kernel version
- * . extract major.minor.patch from utsname.release via sscanf()
- * The reason lays in possible use of kernel flavours which
- * modify utsname.release but no the Version_ symbol.
- *
- * Sun Feb 21 22:27:49 EST 1999: Keith Owens <kaos@ocs.com.au>
- * Fixed bug that caused klogd to die if there is no sym_array available.
- *
- * Tue Sep 12 23:48:12 CEST 2000: Martin Schulze <joey@infodrom.ffis.de>
- * Close symbol file in InitKsyms() when an error occurred.
- */
-
-
-/* Includes. */
-#include <stdlib.h>
-#include <malloc.h>
-#include <sys/utsname.h>
-#include "klogd.h"
-#include "ksyms.h"
-
-#define VERBOSE_DEBUGGING 0
-
-
-/* Variables static to this module. */
-struct sym_table
-{
- unsigned long value;
- char *name;
-};
-
-static int num_syms = 0;
-static int i_am_paranoid = 0;
-static char vstring[12];
-static struct sym_table *sym_array = (struct sym_table *) 0;
-
-static char *system_maps[] =
-{
- "/boot/System.map",
- "/System.map",
-#if defined(TEST)
- "./System.map",
-#endif
- (char *) 0
-};
-
-
-#if defined(TEST)
-int debugging;
-#else
-extern int debugging;
-#endif
-
-
-/* Function prototypes. */
-static char * FindSymbolFile(void);
-static int AddSymbol(unsigned long, char*);
-static void FreeSymbols(void);
-static int CheckVersion(char *);
-static int CheckMapVersion(char *);
-
-
-/**************************************************************************
- * Function: InitKsyms
- *
- * Purpose: This function is responsible for initializing and loading
- * the data tables used by the kernel address translations.
- *
- * Arguements: (char *) mapfile
- *
- * mapfile:-> A pointer to a complete path
- * specification of the file containing
- * the kernel map to use.
- *
- * Return: int
- *
- * A boolean style context is returned. The return value will
- * be true if initialization was successful. False if not.
- **************************************************************************/
-
-extern int InitKsyms(mapfile)
-
- char *mapfile;
-
-{
- auto char type,
- sym[512];
-
- auto int version = 0;
-
- auto unsigned long int address;
-
- auto FILE *sym_file;
-
-
- /* Check and make sure that we are starting with a clean slate. */
- if ( num_syms > 0 )
- FreeSymbols();
-
-
- /*
- * Search for and open the file containing the kernel symbols.
- */
- if ( mapfile != (char *) 0 )
- {
- if ( (sym_file = fopen(mapfile, "r")) == (FILE *) 0 )
- {
- Syslog(LOG_WARNING, "Cannot open map file: %s.", \
- mapfile);
- return(0);
- }
- }
- else
- {
- if ( (mapfile = FindSymbolFile()) == (char *) 0 )
- {
- Syslog(LOG_WARNING, "Cannot find map file.");
- if ( debugging )
- fputs("Cannot find map file.\n", stderr);
- return(0);
- }
-
- if ( (sym_file = fopen(mapfile, "r")) == (FILE *) 0 )
- {
- Syslog(LOG_WARNING, "Cannot open map file.");
- if ( debugging )
- fputs("Cannot open map file.\n", stderr);
- return(0);
- }
- }
-
-
- /*
- * Read the kernel symbol table file and add entries for each
- * line. I suspect that the use of fscanf is not really in vogue
- * but it was quick and dirty and IMHO suitable for fixed format
- * data such as this. If anybody doesn't agree with this please
- * e-mail me a diff containing a parser with suitable political
- * correctness -- GW.
- */
- while ( !feof(sym_file) )
- {
- if ( fscanf(sym_file, "%lx %c %s\n", &address, &type, sym)
- != 3 )
- {
- Syslog(LOG_ERR, "Error in symbol table input (#1).");
- fclose(sym_file);
- return(0);
- }
- if ( VERBOSE_DEBUGGING && debugging )
- fprintf(stderr, "Address: %lx, Type: %c, Symbol: %s\n",
- address, type, sym);
-
- if ( AddSymbol(address, sym) == 0 )
- {
- Syslog(LOG_ERR, "Error adding symbol - %s.", sym);
- fclose(sym_file);
- return(0);
- }
-
- if ( version == 0 )
- version = CheckVersion(sym);
- }
-
-
- Syslog(LOG_INFO, "Loaded %d symbols from %s.", num_syms, mapfile);
- switch ( version )
- {
- case -1:
- Syslog(LOG_WARNING, "Symbols do not match kernel version.");
- num_syms = 0;
- break;
-
- case 0:
- Syslog(LOG_WARNING, "Cannot verify that symbols match " \
- "kernel version.");
- break;
-
- case 1:
- Syslog(LOG_INFO, "Symbols match kernel version %s.", vstring);
- break;
- }
-
- fclose(sym_file);
- return(1);
-}
-
-
-/**************************************************************************
- * Function: FindSymbolFile
- *
- * Purpose: This function is responsible for encapsulating the search
- * for a valid symbol file. Encapsulating the search for
- * the map file in this function allows an intelligent search
- * process to be implemented.
- *
- * The list of symbol files will be searched until either a
- * symbol file is found whose version matches the currently
- * executing kernel or the end of the list is encountered. If
- * the end of the list is encountered the first available
- * symbol file is returned to the caller.
- *
- * This strategy allows klogd to locate valid symbol files
- * for both a production and an experimental kernel. For
- * example a map for a production kernel could be installed
- * in /boot. If an experimental kernel is loaded the map
- * in /boot will be skipped and the map in /usr/src/linux would
- * be used if its version number matches the executing kernel.
- *
- * Arguements: None specified.
- *
- * Return: char *
- *
- * If a valid system map cannot be located a null pointer
- * is returned to the caller.
- *
- * If the search is succesful a pointer is returned to the
- * caller which points to the name of the file containing
- * the symbol table to be used.
- **************************************************************************/
-
-static char * FindSymbolFile()
-
-{
- auto char *file = (char *) 0,
- **mf = system_maps;
-
- auto struct utsname utsname;
- static char symfile[100];
-
- auto FILE *sym_file = (FILE *) 0;
-
- if ( uname(&utsname) < 0 )
- {
- Syslog(LOG_ERR, "Cannot get kernel version information.");
- return(0);
- }
-
- if ( debugging )
- fputs("Searching for symbol map.\n", stderr);
-
- for (mf = system_maps; *mf != (char *) 0 && file == (char *) 0; ++mf)
- {
-
- sprintf (symfile, "%s-%s", *mf, utsname.release);
- if ( debugging )
- fprintf(stderr, "Trying %s.\n", symfile);
- if ( (sym_file = fopen(symfile, "r")) != (FILE *) 0 ) {
- if (CheckMapVersion(symfile) == 1)
- file = symfile;
- }
- if (sym_file == (FILE *) 0 || file == (char *) 0) {
- sprintf (symfile, "%s", *mf);
- if ( debugging )
- fprintf(stderr, "Trying %s.\n", symfile);
- if ( (sym_file = fopen(symfile, "r")) != (FILE *) 0 ) {
- if (CheckMapVersion(symfile) == 1)
- file = symfile;
- }
- }
-
- }
-
- /*
- * At this stage of the game we are at the end of the symbol
- * tables.
- */
- if ( debugging )
- fprintf(stderr, "End of search list encountered.\n");
- return(file);
-}
-
-
-/**************************************************************************
- * Function: CheckVersion
- *
- * Purpose: This function is responsible for determining whether or
- * the system map being loaded matches the version of the
- * currently running kernel.
- *
- * The kernel version is checked by examing a variable which
- * is of the form: _Version_66347 (a.out) or Version_66437 (ELF).
- *
- * The suffix of this variable is the current kernel version
- * of the kernel encoded in base 256. For example the
- * above variable would be decoded as:
- *
- * (66347 = 1*65536 + 3*256 + 43 = 1.3.43)
- *
- * (Insert appropriate deities here) help us if Linus ever
- * needs more than 255 patch levels to get a kernel out the
- * door... :-)
- *
- * Arguements: (char *) version
- *
- * version:-> A pointer to the string which
- * is to be decoded as a kernel
- * version variable.
- *
- * Return: int
- *
- * -1:-> The currently running kernel version does
- * not match this version string.
- *
- * 0:-> The string is not a kernel version variable.
- *
- * 1:-> The executing kernel is of the same version
- * as the version string.
- **************************************************************************/
-
-static int CheckVersion(version)
-
- char *version;
-
-
-{
- auto int vnum,
- major,
- minor,
- patch;
-
-#ifndef TESTING
- int kvnum;
- auto struct utsname utsname;
-#endif
-
- static char *prefix = { "Version_" };
-
-
- /* Early return if there is no hope. */
- if ( strncmp(version, prefix, strlen(prefix)) == 0 /* ELF */ ||
- (*version == '_' &&
- strncmp(++version, prefix, strlen(prefix)) == 0 ) /* a.out */ )
- ;
- else
- return(0);
-
-
- /*
- * Since the symbol looks like a kernel version we can start
- * things out by decoding the version string into its component
- * parts.
- */
- vnum = atoi(version + strlen(prefix));
- patch = vnum & 0x000000FF;
- minor = (vnum >> 8) & 0x000000FF;
- major = (vnum >> 16) & 0x000000FF;
- if ( debugging )
- fprintf(stderr, "Version string = %s, Major = %d, " \
- "Minor = %d, Patch = %d.\n", version +
- strlen(prefix), major, minor, \
- patch);
- sprintf(vstring, "%d.%d.%d", major, minor, patch);
-
-#ifndef TESTING
- /*
- * We should now have the version string in the vstring variable in
- * the same format that it is stored in by the kernel. We now
- * ask the kernel for its version information and compare the two
- * values to determine if our system map matches the kernel
- * version level.
- */
- if ( uname(&utsname) < 0 )
- {
- Syslog(LOG_ERR, "Cannot get kernel version information.");
- return(0);
- }
- if ( debugging )
- fprintf(stderr, "Comparing kernel %s with symbol table %s.\n",\
- utsname.release, vstring);
-
- if ( sscanf (utsname.release, "%d.%d.%d", &major, &minor, &patch) < 3 )
- {
- Syslog(LOG_ERR, "Kernel send bogus release string `%s'.",
- utsname.release);
- return(0);
- }
-
- /* Compute the version code from data sent by the kernel */
- kvnum = (major << 16) | (minor << 8) | patch;
-
- /* Failure. */
- if ( vnum != kvnum )
- return(-1);
-
- /* Success. */
-#endif
- return(1);
-}
-
-
-/**************************************************************************
- * Function: CheckMapVersion
- *
- * Purpose: This function is responsible for determining whether or
- * the system map being loaded matches the version of the
- * currently running kernel. It uses CheckVersion as
- * backend.
- *
- * Arguements: (char *) fname
- *
- * fname:-> A pointer to the string which
- * references the system map file to
- * be used.
- *
- * Return: int
- *
- * -1:-> The currently running kernel version does
- * not match the version in the given file.
- *
- * 0:-> No system map file or no version information.
- *
- * 1:-> The executing kernel is of the same version
- * as the version of the map file.
- **************************************************************************/
-
-static int CheckMapVersion(fname)
-
- char *fname;
-
-
-{
- int version;
- FILE *sym_file;
- auto unsigned long int address;
- auto char type,
- sym[512];
-
- if ( (sym_file = fopen(fname, "r")) != (FILE *) 0 ) {
- /*
- * At this point a map file was successfully opened. We
- * now need to search this file and look for version
- * information.
- */
- Syslog(LOG_INFO, "Inspecting %s", fname);
-
- version = 0;
- while ( !feof(sym_file) && (version == 0) )
- {
- if ( fscanf(sym_file, "%lx %c %s\n", &address, \
- &type, sym) != 3 )
- {
- Syslog(LOG_ERR, "Error in symbol table input (#2).");
- fclose(sym_file);
- return(0);
- }
- if ( VERBOSE_DEBUGGING && debugging )
- fprintf(stderr, "Address: %lx, Type: %c, " \
- "Symbol: %s\n", address, type, sym);
-
- version = CheckVersion(sym);
- }
- fclose(sym_file);
-
- switch ( version )
- {
- case -1:
- Syslog(LOG_ERR, "Symbol table has incorrect " \
- "version number.\n");
- break;
-
- case 0:
- if ( debugging )
- fprintf(stderr, "No version information " \
- "found.\n");
- break;
- case 1:
- if ( debugging )
- fprintf(stderr, "Found table with " \
- "matching version number.\n");
- break;
- }
-
- return(version);
- }
-
- return(0);
-}
-
-
-/**************************************************************************
- * Function: AddSymbol
- *
- * Purpose: This function is responsible for adding a symbol name
- * and its address to the symbol table.
- *
- * Arguements: (unsigned long) address, (char *) symbol
- *
- * Return: int
- *
- * A boolean value is assumed. True if the addition is
- * successful. False if not.
- **************************************************************************/
-
-static int AddSymbol(address, symbol)
-
- unsigned long address;
-
- char *symbol;
-
-{
- /* Allocate the the symbol table entry. */
- sym_array = (struct sym_table *) realloc(sym_array, (num_syms+1) * \
- sizeof(struct sym_table));
- if ( sym_array == (struct sym_table *) 0 )
- return(0);
-
- /* Then the space for the symbol. */
- sym_array[num_syms].name = (char *) malloc(strlen(symbol)*sizeof(char)\
- + 1);
- if ( sym_array[num_syms].name == (char *) 0 )
- return(0);
-
- sym_array[num_syms].value = address;
- strcpy(sym_array[num_syms].name, symbol);
- ++num_syms;
- return(1);
-}
-
-
-/**************************************************************************
- * Function: LookupSymbol
- *
- * Purpose: Find the symbol which is related to the given kernel
- * address.
- *
- * Arguements: (long int) value, (struct symbol *) sym
- *
- * value:-> The address to be located.
- *
- * sym:-> A pointer to a structure which will be
- * loaded with the symbol's parameters.
- *
- * Return: (char *)
- *
- * If a match cannot be found a diagnostic string is printed.
- * If a match is found the pointer to the symbolic name most
- * closely matching the address is returned.
- **************************************************************************/
-
-char * LookupSymbol(value, sym)
-
- unsigned long value;
-
- struct symbol *sym;
-
-{
- auto int lp;
-
- auto char *last;
-
- if (!sym_array)
- return((char *) 0);
-
- last = sym_array[0].name;
- sym->offset = 0;
- sym->size = 0;
- if ( value < sym_array[0].value )
- return((char *) 0);
-
- for(lp= 0; lp <= num_syms; ++lp)
- {
- if ( sym_array[lp].value > value )
- {
- sym->offset = value - sym_array[lp-1].value;
- sym->size = sym_array[lp].value - \
- sym_array[lp-1].value;
- return(last);
- }
- last = sym_array[lp].name;
- }
-
- if ( (last = LookupModuleSymbol(value, sym)) != (char *) 0 )
- return(last);
-
- return((char *) 0);
-}
-
-
-/**************************************************************************
- * Function: FreeSymbols
- *
- * Purpose: This function is responsible for freeing all memory which
- * has been allocated to hold the static symbol table. It
- * also initializes the symbol count and in general prepares
- * for a re-read of a static symbol table.
- *
- * Arguements: void
- *
- * Return: void
- **************************************************************************/
-
-static void FreeSymbols()
-
-{
- auto int lp;
-
- /* Free each piece of memory allocated for symbol names. */
- for(lp= 0; lp < num_syms; ++lp)
- free(sym_array[lp].name);
-
- /* Whack the entire array and initialize everything. */
- free(sym_array);
- sym_array = (struct sym_table *) 0;
- num_syms = 0;
-
- return;
-}
-
-
-/**************************************************************************
- * Function: LogExpanded
- *
- * Purpose: This function is responsible for logging a kernel message
- * line after all potential numeric kernel addresses have
- * been resolved symolically.
- *
- * Arguements: (char *) line, (char *) el
- *
- * line:-> A pointer to the buffer containing the kernel
- * message to be expanded and logged.
- *
- * el:-> A pointer to the buffer into which the expanded
- * kernel line will be written.
- *
- * Return: void
- **************************************************************************/
-
-extern char * ExpandKadds(line, el)
-
- char *line;
-
- char *el;
-
-{
- auto char dlm,
- *kp,
- *sl = line,
- *elp = el,
- *symbol;
-
- char num[15];
- auto unsigned long int value;
-
- auto struct symbol sym;
-
-
- /*
- * This is as handy a place to put this as anyplace.
- *
- * Since the insertion of kernel modules can occur in a somewhat
- * dynamic fashion we need some mechanism to insure that the
- * kernel symbol tables get read just prior to when they are
- * needed.
- *
- * To accomplish this we look for the Oops string and use its
- * presence as a signal to load the module symbols.
- *
- * This is not the best solution of course, especially if the
- * kernel is rapidly going out to lunch. What really needs to
- * be done is to somehow generate a callback from the
- * kernel whenever a module is loaded or unloaded. I am
- * open for patches.
- */
- if ( i_am_paranoid &&
- (strstr(line, "Oops:") != (char *) 0) && !InitMsyms() )
- Syslog(LOG_WARNING, "Cannot load kernel module symbols.\n");
-
-
- /*
- * Early return if there do not appear to be any kernel
- * messages in this line.
- */
- if ( (num_syms == 0) ||
- (kp = strstr(line, "[<")) == (char *) 0 )
- {
- strcpy(el, line);
- return(el);
- }
-
- /* Loop through and expand all kernel messages. */
- do
- {
- while ( sl < kp+1 )
- *elp++ = *sl++;
-
- /* Now poised at a kernel delimiter. */
- if ( (kp = strstr(sl, ">]")) == (char *) 0 )
- {
- strcpy(el, sl);
- return(el);
- }
- dlm = *kp;
- strncpy(num,sl+1,kp-sl-1);
- num[kp-sl-1] = '\0';
- value = strtoul(num, (char **) 0, 16);
- if ( (symbol = LookupSymbol(value, &sym)) == (char *) 0 )
- symbol = sl;
-
- strcat(elp, symbol);
- elp += strlen(symbol);
- if ( debugging )
- fprintf(stderr, "Symbol: %s = %lx = %s, %x/%d\n", \
- sl+1, value, \
- (sym.size==0) ? symbol+1 : symbol, \
- sym.offset, sym.size);
-
- value = 2;
- if ( sym.size != 0 )
- {
- --value;
- ++kp;
- elp += sprintf(elp, "+%x/%d", sym.offset, sym.size);
- }
- strncat(elp, kp, value);
- elp += value;
- sl = kp + value;
- if ( (kp = strstr(sl, "[<")) == (char *) 0 )
- strcat(elp, sl);
- }
- while ( kp != (char *) 0);
-
- if ( debugging )
- fprintf(stderr, "Expanded line: %s\n", el);
- return(el);
-}
-
-
-/**************************************************************************
- * Function: SetParanoiaLevel
- *
- * Purpose: This function is an interface function for setting the
- * mode of loadable module symbol lookups. Probably overkill
- * but it does slay another global variable.
- *
- * Arguements: (int) level
- *
- * level:-> The amount of paranoia which is to be
- * present when resolving kernel exceptions.
- * Return: void
- **************************************************************************/
-
-extern void SetParanoiaLevel(level)
-
- int level;
-
-{
- i_am_paranoid = level;
- return;
-}
-
-
-/*
- * Setting the -DTEST define enables the following code fragment to
- * be compiled. This produces a small standalone program which will
- * echo the standard input of the process to stdout while translating
- * all numeric kernel addresses into their symbolic equivalent.
- */
-#if defined(TEST)
-
-#include <stdarg.h>
-
-extern int main(int, char **);
-
-
-extern int main(int argc, char *argv[])
-{
- auto char line[1024], eline[2048];
-
- debugging = 1;
-
-
- if ( !InitKsyms((char *) 0) )
- {
- fputs("ksym: Error loading system map.\n", stderr);
- return(1);
- }
-
- while ( !feof(stdin) )
- {
- fgets(line, sizeof(line), stdin);
- if (line[strlen(line)-1] == '\n') line[strlen(line)-1] = '\0'; /* Trash NL char */
- memset(eline, '\0', sizeof(eline));
- ExpandKadds(line, eline);
- fprintf(stdout, "%s\n", eline);
- }
-
-
- return(0);
-}
-
-extern void Syslog(int priority, char *fmt, ...)
-
-{
- va_list ap;
-
- va_start(ap, fmt);
- fprintf(stdout, "Pr: %d, ", priority);
- vfprintf(stdout, fmt, ap);
- va_end(ap);
- fputc('\n', stdout);
-
- return;
-}
-#endif
diff --git a/ksym_mod.c b/ksym_mod.c
deleted file mode 100644
index 344963b2..00000000
--- a/ksym_mod.c
+++ /dev/null
@@ -1,700 +0,0 @@
-/*
- ksym_mod.c - functions for building symbol lookup tables for klogd
- Copyright (c) 1995, 1996 Dr. G.W. Wettstein <greg@wind.rmcc.com>
- Copyright (c) 1996 Enjellic Systems Development
-
- This file is part of the sysklogd package, a kernel and system log daemon.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-/*
- * This file implements functions which are useful for building
- * a symbol lookup table based on the in kernel symbol table
- * maintained by the Linux kernel.
- *
- * Proper logging of kernel panics generated by loadable modules
- * tends to be difficult. Since the modules are loaded dynamically
- * their addresses are not known at kernel load time. A general
- * protection fault (Oops) cannot be properly deciphered with
- * classic methods using the static symbol map produced at link time.
- *
- * One solution to this problem is to have klogd attempt to translate
- * addresses from module when the fault occurs. By referencing the
- * the kernel symbol table proper resolution of these symbols is made
- * possible.
- *
- * At least that is the plan.
- *
- * Wed Aug 21 09:20:09 CDT 1996: Dr. Wettstein
- * The situation where no module support has been compiled into a
- * kernel is now detected. An informative message is output indicating
- * that the kernel has no loadable module support whenever kernel
- * module symbols are loaded.
- *
- * An informative message is printed indicating the number of kernel
- * modules and the number of symbols loaded from these modules.
- *
- * Sun Jun 15 16:23:29 MET DST 1997: Michael Alan Dorman
- * Some more glibc patches made by <mdorman@debian.org>.
- *
- * Sat Jan 10 15:00:18 CET 1998: Martin Schulze <joey@infodrom.north.de>
- * Fixed problem with klogd not being able to be built on a kernel
- * newer than 2.1.18. It was caused by modified structures
- * inside the kernel that were included. I have worked in a
- * patch from Alessandro Suardi <asuardi@uninetcom.it>.
- *
- * Sun Jan 25 20:57:34 CET 1998: Martin Schulze <joey@infodrom.north.de>
- * Another patch for Linux/alpha by Christopher C Chimelis
- * <chris@classnet.med.miami.edu>.
- *
- * Thu Mar 19 23:39:29 CET 1998: Manuel Rodrigues <pmanuel@cindy.fe.up.pt>
- * Changed lseek() to llseek() in order to support > 2GB address
- * space which provided by kernels > 2.1.70.
- *
- * Mon Apr 13 18:18:45 CEST 1998: Martin Schulze <joey@infodrom.north.de>
- * Removed <sys/module.h> as it's no longer part of recent glibc
- * versions. Added prototyp for llseek() which has been
- * forgotton in <unistd.h> from glibc. Added more log
- * information if problems occurred while reading a system map
- * file, by submission from Mark Simon Phillips <M.S.Phillips@nortel.co.uk>.
- *
- * Sun Jan 3 18:38:03 CET 1999: Martin Schulze <joey@infodrom.north.de>
- * Corrected return value of AddModule if /dev/kmem can't be
- * loaded. This will prevent klogd from segfaulting if /dev/kmem
- * is not available. Patch from Topi Miettinen <tom@medialab.sonera.net>.
- *
- * Tue Sep 12 23:11:13 CEST 2000: Martin Schulze <joey@infodrom.ffis.de>
- * Changed llseek() to lseek64() in order to skip a libc warning.
- */
-
-
-/* Includes. */
-#include <stdlib.h>
-#include <malloc.h>
-#include <unistd.h>
-#include <signal.h>
-#include <errno.h>
-#include <sys/fcntl.h>
-#include <sys/stat.h>
-#if !defined(__GLIBC__)
-#include <linux/time.h>
-#include <linux/module.h>
-#else /* __GLIBC__ */
-#include <linux/module.h>
-extern __off64_t lseek64 __P ((int __fd, __off64_t __offset, int __whence));
-extern int get_kernel_syms __P ((struct kernel_sym *__table));
-#endif /* __GLIBC__ */
-#include <stdarg.h>
-#include <paths.h>
-#include <linux/version.h>
-
-#include "klogd.h"
-#include "ksyms.h"
-
-
-#if !defined(__GLIBC__)
-/*
- * The following bit uses some kernel/library magic to product what
- * looks like a function call to user level code. This function is
- * actually a system call in disguise. The purpose of the getsyms
- * call is to return a current copy of the in-kernel symbol table.
- */
-#define __LIBRARY__
-#include <linux/unistd.h>
-#define __NR_getsyms __NR_get_kernel_syms
-_syscall1(int, getsyms, struct kernel_sym *, syms);
-#undef __LIBRARY__
-extern int getsyms(struct kernel_sym *);
-#else /* __GLIBC__ */
-#define getsyms get_kernel_syms
-#endif /* __GLIBC__ */
-
-/* Variables static to this module. */
-struct sym_table
-{
- unsigned long value;
- char *name;
-};
-
-struct Module
-{
- struct sym_table *sym_array;
- int num_syms;
-
- char *name;
- struct module module;
-#if LINUX_VERSION_CODE >= 0x20112
- struct module_info module_info;
-#endif
-};
-
-static int num_modules = 0;
-struct Module *sym_array_modules = (struct Module *) 0;
-
-static int have_modules = 0;
-
-#if defined(TEST)
-static int debugging = 1;
-#else
-extern int debugging;
-#endif
-
-
-/* Function prototypes. */
-static void FreeModules(void);
-static int AddSymbol(struct Module *mp, unsigned long, char *);
-static int AddModule(unsigned long, char *);
-static int symsort(const void *, const void *);
-
-
-/**************************************************************************
- * Function: InitMsyms
- *
- * Purpose: This function is responsible for building a symbol
- * table which can be used to resolve addresses for
- * loadable modules.
- *
- * Arguements: Void
- *
- * Return: A boolean return value is assumed.
- *
- * A false value indicates that something went wrong.
- *
- * True if loading is successful.
- **************************************************************************/
-
-extern int InitMsyms()
-
-{
- auto int rtn,
- tmp;
-
- auto struct kernel_sym *ksym_table,
- *p;
-
-
- /* Initialize the kernel module symbol table. */
- FreeModules();
-
-
- /*
- * The system call which returns the kernel symbol table has
- * essentialy two modes of operation. Called with a null pointer
- * the system call returns the number of symbols defined in the
- * the table.
- *
- * The second mode of operation is to pass a valid pointer to
- * the call which will then load the current symbol table into
- * the memory provided.
- *
- * Returning the symbol table is essentially an all or nothing
- * proposition so we need to pre-allocate enough memory for the
- * complete table regardless of how many symbols we need.
- *
- * Bummer.
- */
- if ( (rtn = getsyms((struct kernel_sym *) 0)) < 0 )
- {
- if ( errno == ENOSYS )
- Syslog(LOG_INFO, "No module symbols loaded - "
- "kernel modules not enabled.\n");
- else
- Syslog(LOG_ERR, "Error loading kernel symbols " \
- "- %s\n", strerror(errno));
- return(0);
- }
- if ( debugging )
- fprintf(stderr, "Loading kernel module symbols - "
- "Size of table: %d\n", rtn);
-
- ksym_table = (struct kernel_sym *) malloc(rtn * \
- sizeof(struct kernel_sym));
- if ( ksym_table == (struct kernel_sym *) 0 )
- {
- Syslog(LOG_WARNING, " Failed memory allocation for kernel " \
- "symbol table.\n");
- return(0);
- }
- if ( (rtn = getsyms(ksym_table)) < 0 )
- {
- Syslog(LOG_WARNING, "Error reading kernel symbols - %s\n", \
- strerror(errno));
- return(0);
- }
-
-
- /*
- * Build a symbol table compatible with the other one used by
- * klogd.
- */
- tmp = rtn;
- p = ksym_table;
- while ( tmp-- )
- {
- if ( !AddModule(p->value, p->name) )
- {
- Syslog(LOG_WARNING, "Error adding kernel module table "
- "entry.\n");
- free(ksym_table);
- return(0);
- }
- ++p;
- }
-
- /* Sort the symbol tables in each module. */
- for (rtn = tmp= 0; tmp < num_modules; ++tmp)
- {
- rtn += sym_array_modules[tmp].num_syms;
- if ( sym_array_modules[tmp].num_syms < 2 )
- continue;
- qsort(sym_array_modules[tmp].sym_array, \
- sym_array_modules[tmp].num_syms, \
- sizeof(struct sym_table), symsort);
- }
-
- if ( rtn == 0 )
- Syslog(LOG_INFO, "No module symbols loaded.");
- else
- Syslog(LOG_INFO, "Loaded %d %s from %d module%s", rtn, \
- (rtn == 1) ? "symbol" : "symbols", \
- num_modules, (num_modules == 1) ? "." : "s.");
- free(ksym_table);
- return(1);
-}
-
-
-static int symsort(p1, p2)
-
- const void *p1;
-
- const void *p2;
-
-{
- auto const struct sym_table *sym1 = p1,
- *sym2 = p2;
-
- if ( sym1->value < sym2->value )
- return(-1);
- if ( sym1->value == sym2->value )
- return(0);
- return(1);
-}
-
-
-/**************************************************************************
- * Function: FreeModules
- *
- * Purpose: This function is used to free all memory which has been
- * allocated for the modules and their symbols.
- *
- * Arguements: None specified.
- *
- * Return: void
- **************************************************************************/
-
-static void FreeModules()
-
-{
- auto int nmods,
- nsyms;
-
- auto struct Module *mp;
-
-
- /* Check to see if the module symbol tables need to be cleared. */
- have_modules = 0;
- if ( num_modules == 0 )
- return;
-
-
- for (nmods= 0; nmods < num_modules; ++nmods)
- {
- mp = &sym_array_modules[nmods];
- if ( mp->num_syms == 0 )
- continue;
-
- for (nsyms= 0; nsyms < mp->num_syms; ++nsyms)
- free(mp->sym_array[nsyms].name);
- free(mp->sym_array);
- }
-
- free(sym_array_modules);
- sym_array_modules = (struct Module *) 0;
- num_modules = 0;
- return;
-}
-
-
-/**************************************************************************
- * Function: AddModule
- *
- * Purpose: This function is responsible for adding a module to
- * the list of currently loaded modules.
- *
- * Arguements: (unsigned long) address, (char *) symbol
- *
- * address:-> The address of the module.
- *
- * symbol:-> The name of the module.
- *
- * Return: int
- **************************************************************************/
-
-static int AddModule(address, symbol)
-
- unsigned long address;
-
- char *symbol;
-
-{
- auto int memfd;
-
- auto struct Module *mp;
-
-
- /* Return if we have loaded the modules. */
- if ( have_modules )
- return(1);
-
- /*
- * The following section of code is responsible for determining
- * whether or not we are done reading the list of modules.
- */
- if ( symbol[0] == '#' )
- {
-
- if ( symbol[1] == '\0' )
- {
- /*
- * A symbol which consists of a # sign only
- * signifies a a resident kernel segment. When we
- * hit one of these we are done reading the
- * module list.
- */
- have_modules = 1;
- return(1);
- }
- /* Allocate space for the module. */
- sym_array_modules = (struct Module *) \
- realloc(sym_array_modules, \
- (num_modules+1) * sizeof(struct Module));
- if ( sym_array_modules == (struct Module *) 0 )
- {
- Syslog(LOG_WARNING, "Cannot allocate Module array.\n");
- return(0);
- }
- mp = &sym_array_modules[num_modules];
-
- if ( (memfd = open("/dev/kmem", O_RDONLY)) < 0 )
- {
- Syslog(LOG_WARNING, "Error opening /dev/kmem\n");
- return(0);
- }
- if ( lseek64(memfd, address, SEEK_SET) < 0 )
- {
- Syslog(LOG_WARNING, "Error seeking in /dev/kmem\n");
- Syslog(LOG_WARNING, "Symbol %s, value %08x\n", symbol, address);
- return(0);
- }
- if ( read(memfd, \
- (char *)&sym_array_modules[num_modules].module, \
- sizeof(struct module)) < 0 )
- {
- Syslog(LOG_WARNING, "Error reading module "
- "descriptor.\n");
- return(0);
- }
- close(memfd);
-
- /* Save the module name. */
- mp->name = (char *) malloc(strlen(&symbol[1]) + 1);
- if ( mp->name == (char *) 0 )
- return(0);
- strcpy(mp->name, &symbol[1]);
-
- mp->num_syms = 0;
- mp->sym_array = (struct sym_table *) 0;
- ++num_modules;
- return(1);
- }
- else
- {
- if (num_modules > 0)
- mp = &sym_array_modules[num_modules - 1];
- else
- mp = &sym_array_modules[0];
- AddSymbol(mp, address, symbol);
- }
-
-
- return(1);
-}
-
-
-/**************************************************************************
- * Function: AddSymbol
- *
- * Purpose: This function is responsible for adding a symbol name
- * and its address to the symbol table.
- *
- * Arguements: (struct Module *) mp, (unsigned long) address, (char *) symbol
- *
- * mp:-> A pointer to the module which the symbol is
- * to be added to.
- *
- * address:-> The address of the symbol.
- *
- * symbol:-> The name of the symbol.
- *
- * Return: int
- *
- * A boolean value is assumed. True if the addition is
- * successful. False if not.
- **************************************************************************/
-
-static int AddSymbol(mp, address, symbol)
-
- struct Module *mp;
-
- unsigned long address;
-
- char *symbol;
-
-{
- auto int tmp;
-
-
- /* Allocate space for the symbol table entry. */
- mp->sym_array = (struct sym_table *) realloc(mp->sym_array, \
- (mp->num_syms+1) * sizeof(struct sym_table));
- if ( mp->sym_array == (struct sym_table *) 0 )
- return(0);
-
- /* Then the space for the symbol. */
- tmp = strlen(symbol);
- tmp += (strlen(mp->name) + 1);
- mp->sym_array[mp->num_syms].name = (char *) malloc(tmp + 1);
- if ( mp->sym_array[mp->num_syms].name == (char *) 0 )
- return(0);
- memset(mp->sym_array[mp->num_syms].name, '\0', tmp + 1);
-
- /* Stuff interesting information into the module. */
- mp->sym_array[mp->num_syms].value = address;
- strcpy(mp->sym_array[mp->num_syms].name, mp->name);
- strcat(mp->sym_array[mp->num_syms].name, ":");
- strcat(mp->sym_array[mp->num_syms].name, symbol);
- ++mp->num_syms;
-
- return(1);
-}
-
-
-/**************************************************************************
- * Function: LookupModuleSymbol
- *
- * Purpose: Find the symbol which is related to the given address from
- * a kernel module.
- *
- * Arguements: (long int) value, (struct symbol *) sym
- *
- * value:-> The address to be located.
- *
- * sym:-> A pointer to a structure which will be
- * loaded with the symbol's parameters.
- *
- * Return: (char *)
- *
- * If a match cannot be found a diagnostic string is printed.
- * If a match is found the pointer to the symbolic name most
- * closely matching the address is returned.
- **************************************************************************/
-
-extern char * LookupModuleSymbol(value, sym)
-
- unsigned long value;
-
- struct symbol *sym;
-
-{
- auto int nmod,
- nsym;
-
- auto struct sym_table *last;
-
- auto struct Module *mp;
-
-
- sym->size = 0;
- sym->offset = 0;
- if ( num_modules == 0 )
- return((char *) 0);
-
- for(nmod= 0; nmod < num_modules; ++nmod)
- {
- mp = &sym_array_modules[nmod];
-
- /*
- * Run through the list of symbols in this module and
- * see if the address can be resolved.
- */
- for(nsym= 1, last = &mp->sym_array[0];
- nsym < mp->num_syms;
- ++nsym)
- {
- if ( mp->sym_array[nsym].value > value )
- {
- sym->offset = value - last->value;
- sym->size = mp->sym_array[nsym].value - \
- last->value;
- return(last->name);
- }
- last = &mp->sym_array[nsym];
- }
-
-
- /*
- * At this stage of the game we still cannot give up the
- * ghost. There is the possibility that the address is
- * from a module which has no symbols registered with
- * the kernel. The solution is to compare the address
- * against the starting address and extant of the module
- * If it is in this range we can at least return the
- * name of the module.
- */
-#if LINUX_VERSION_CODE < 0x20112
- if ( (void *) value >= mp->module.addr &&
- (void *) value <= (mp->module.addr + \
- mp->module.size * 4096) )
-#else
- if ( value >= mp->module_info.addr &&
- value <= (mp->module_info.addr + \
- mp->module.size * 4096) )
-#endif
- {
- /*
- * A special case needs to be checked for. The above
- * conditional tells us that we are within the
- * extant of this module but symbol lookup has
- * failed.
- *
- * We need to check to see if any symbols have
- * been defined in this module. If there have been
- * symbols defined the assumption must be made that
- * the faulting address lies somewhere beyond the
- * last symbol. About the only thing we can do
- * at this point is use an offset from this
- * symbol.
- */
- if ( mp->num_syms > 0 )
- {
- last = &mp->sym_array[mp->num_syms - 1];
-#if LINUX_VERSION_CODE < 0x20112
- sym->size = (int) mp->module.addr + \
- (mp->module.size * 4096) - value;
-#else
- sym->size = (int) mp->module_info.addr + \
- (mp->module.size * 4096) - value;
-#endif
- sym->offset = value - last->value;
- return(last->name);
- }
-
- /*
- * There were no symbols defined for this module.
- * Return the module name and the offset of the
- * faulting address in the module.
- */
- sym->size = mp->module.size * 4096;
-#if LINUX_VERSION_CODE < 0x20112
- sym->offset = (void *) value - mp->module.addr;
-#else
- sym->offset = value - mp->module_info.addr;
-#endif
- return(mp->name);
- }
- }
-
- /* It has been a hopeless exercise. */
- return((char *) 0);
-}
-
-
-/*
- * Setting the -DTEST define enables the following code fragment to
- * be compiled. This produces a small standalone program which will
- * dump the current kernel symbol table.
- */
-#if defined(TEST)
-
-#include <stdarg.h>
-
-
-extern int main(int, char **);
-
-
-int main(argc, argv)
-
- int argc;
-
- char *argv[];
-
-{
- auto int lp, syms;
-
-
- if ( !InitMsyms() )
- {
- fprintf(stderr, "Cannot load module symbols.\n");
- return(1);
- }
-
- printf("Number of modules: %d\n\n", num_modules);
-
- for(lp= 0; lp < num_modules; ++lp)
- {
- printf("Module #%d = %s, Number of symbols = %d\n", lp + 1, \
- sym_array_modules[lp].name, \
- sym_array_modules[lp].num_syms);
-
- for (syms= 0; syms < sym_array_modules[lp].num_syms; ++syms)
- {
- printf("\tSymbol #%d\n", syms + 1);
- printf("\tName: %s\n", \
- sym_array_modules[lp].sym_array[syms].name);
- printf("\tAddress: %lx\n\n", \
- sym_array_modules[lp].sym_array[syms].value);
- }
- }
-
- FreeModules();
- return(0);
-}
-
-extern void Syslog(int priority, char *fmt, ...)
-
-{
- va_list ap;
-
- va_start(ap, fmt);
- fprintf(stdout, "Pr: %d, ", priority);
- vfprintf(stdout, fmt, ap);
- va_end(ap);
- fputc('\n', stdout);
-
- return;
-}
-
-#endif
diff --git a/ksyms.h b/ksyms.h
deleted file mode 100644
index 4e70ba05..00000000
--- a/ksyms.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- ksym.h - Definitions for symbol table utilities.
- Copyright (c) 1995, 1996 Dr. G.W. Wettstein <greg@wind.rmcc.com>
- Copyright (c) 1996 Enjellic Systems Development
-
- This file is part of the sysklogd package, a kernel and system log daemon.
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-/* Variables, structures and type definitions static to this module. */
-
-struct symbol
-{
- char *name;
- int size;
- int offset;
-};
-
-
-/* Function prototypes. */
-extern char * LookupSymbol(unsigned long, struct symbol *);
-extern char * LookupModuleSymbol(unsigned long int, struct symbol *);
diff --git a/oops.c b/oops.c
deleted file mode 100644
index 14573f0f..00000000
--- a/oops.c
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * Loadable driver which provides the ability to generate a kernel
- * protection fault. Mainly useful for testing the address translation
- * capabilities of klogd.
- *
- * Fri Oct 27 14:34:27 CDT 1995: Dr. Wettstein
- *
- * Initial version.
- */
-
-#define NEW_MODULES
-
-/* Kernel includes. */
-#include <linux/kernel.h>
-#include <linux/config.h>
-#include <linux/errno.h>
-#include <linux/fs.h>
-
-/* Standard module stuff. */
-#if defined(NEW_MODULES)
-#include <linux/module.h>
-#else
-#include <linux/module.h>
-#include <linux/version.h>
-char kernel_version[] = UTS_RELEASE;
-#endif
-
-
-static int major = 32;
-
-
-#ifdef MODULE
-static int oops_ioctl(struct inode *, struct file *, unsigned int cmd, unsigned long arg);
-static int oops_open(struct inode * node, struct file * file);
-static void oops(void);
-
-static struct symbol_table these_symbols = {
-#include <linux/symtab_begin.h>
- X(oops_open),
- X(oops_ioctl),
- X(oops),
-#include <linux/symtab_end.h>
-};
-
-/* driver specific module definitions */
-static struct file_operations oops_fops1 = {
- NULL, /* hw_lseek */
- NULL, /* hw_read */
- NULL, /* write */
- NULL, /* hw_readdir */
- NULL, /* hw_select */
- oops_ioctl, /* hw_ioctl */
- NULL, /* mmap */
- oops_open, /* hw_open */
- NULL, /* hw_release */
- NULL /* fsync */
-};
-
-static int oops_open(struct inode * node, struct file * file)
-{
- printk("Called oops_open.\n");
- return(0);
-}
-
-
-static int oops_ioctl(struct inode * node, struct file * file, \
- unsigned int cmd, unsigned long arg)
-{
-
- printk("Called oops_ioctl.\n");
- printk("Cmd: %d, Arg: %ld\n", cmd, arg);
- if ( cmd == 1 )
- {
- oops();
- }
-
- return(0);
-}
-
-static void oops()
-
-{
- auto unsigned long *p = (unsigned long *) 828282828;
- *p = 5;
- return;
-}
-
-
-int
-init_module(void)
-{
- printk("oops: Module initilization.\n");
- if (register_chrdev(major, "oops", &oops_fops1)) {
- printk("register_chrdev failed.");
- return -EIO;
- }
-
- printk("oops: Registering symbols.\n");
- register_symtab(&these_symbols);
-
- return 0;
-}
-
-
-void
-cleanup_module(void)
-{
- /* driver specific cleanups, ususally "unregister_*()" */
- printk("oops: Module unloadeding.\n");
- if (unregister_chrdev(major, "oops") != 0)
- printk("cleanup_module failed\n");
- else
- printk("cleanup_module succeeded\n");
-
- return;
-
-}
-#endif /* MODULE */
diff --git a/oops_test.c b/oops_test.c
deleted file mode 100644
index f710d4cd..00000000
--- a/oops_test.c
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * This is a small test program for generating a kernel protection fault
- * using the oops loadable module.
- *
- * Fri Apr 26 12:52:43 CDT 1996: Dr. Wettstein
- * Initial version.
- */
-
-
-/* Includes. */
-#include <stdio.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <sys/ioctl.h>
-
-
-/* Function prototypes. */
-extern int main(int, char **);
-
-
-extern int main(argc, argv)
-
- int argc;
-
- char *argv[];
-
-{
- auto int fd;
-
- if ( argc != 2 )
- {
- fprintf(stderr, "No oops device specified.\n");
- return(1);
- }
-
- if ( (fd = open(argv[1], O_RDONLY)) < 0 )
- {
- fprintf(stderr, "Cannot open device: %s.\n", argv[1]);
- return(1);
- }
-
- if ( ioctl(fd, 1, 0) < 0 )
- {
- fprintf(stderr, "Failed on oops.\n");
- return(1);
- }
-
- printf("OOoops\n");
-
- close(fd);
- return(0);
-}