diff --git a/sensors/and/CHANGELOG b/sensors/and/CHANGELOG
new file mode 100644
index 0000000000000000000000000000000000000000..4d448c866a65c9c97c7dac762f5e74230607c8f5
--- /dev/null
+++ b/sensors/and/CHANGELOG
@@ -0,0 +1,74 @@
+Changelog for Auto Nice Daemon
+------------------------------
+
+Changes in 1.2.1
+- take into account not only usr but also sys time (Linux only; other
+  Unixes already did this)
+
+Changes in 1.2.0
+- more robust signal handling/config reload
+- startup script fixed for Tru64 killall
+- proper daemon mode
+- improved 64bit hardness
+- verbosity handling now in and_printf()
+- additional criterion: parent process (parent=.../ancestor=...)
+  (thanks to Dr. Hans Ekkehard Plesser, NLH, for idea and testing)
+- additional criterion: minimum user/group id
+  (again thanks to Dr. Hans Ekkehard Plesser)
+
+Changes in 1.0.9
+- fix broken zombie fix (Linux only)
+- fix ultra-long running (248+ days) processes (thanks to Marcelo
+  Matus, UA)
+- clean up signed/unsigned time vars
+- compiled for AMD Opteron
+
+Changes in 1.0.8
+- leave zombies alone (Linux only)
+
+Changes in 1.0.7
+- port to FreeBSD (thanks to a guy who calls himself quake2)
+- version and date are now compiled in
+- make doc target to bump version number in man pages
+
+Changes in 1.0.6
+- stop overwriting existing configuration when make install
+- small docs improvement (command name and regexes)
+- changed misleading log message (seemingly negative nice level)
+- added gtop to default config file
+- fix LICENSE (still GPL, but the file was truncated)
+- port to IRIX, IRIX64 and SunOS (thanks to Dan Stromberg, UCI)
+
+Changes in 1.0.5
+- fix format string vulnerability (please UPDATE!)
+  (thanks to INTEXXIA.com)
+
+Changes in 1.0.4
+- makefile improvements, esp. for Debian (thanks to Andras Bali
+  and Mikael Andersson)
+- include LICENSE
+
+Changes in 1.0.3
+- bug fix Linux/AXP: jiffies to seconds fixed (thanks to Markus
+  Lischka, TUM)
+- in config files, "on" hostname is now an extended regex
+  (thanks to Markus Lischka, TUM)
+- new commandline switch -s for output to stdout
+- documentation updates
+
+Changes in 1.0.2
+- minor documentation updates
+- improved default configuration
+- distribution-independend spec file for source rpms (thanks to
+  Terje Rosten for his help)
+- improved build process to support distribution-independend
+  spec file
+- fix logging: in -x mode (default), log via syslog; in -t mode (test),
+  log to ./debug.and
+- added chkconfig hook in SysV init script
+
+Changes in 1.0.1
+- fix status check in SysV init script
+
+Changes in 1.0.0
+- first official release
diff --git a/sensors/and/LICENSE b/sensors/and/LICENSE
new file mode 100644
index 0000000000000000000000000000000000000000..5b6e7c66c276e7610d4a73c70ec1a1f7c1003259
--- /dev/null
+++ b/sensors/and/LICENSE
@@ -0,0 +1,340 @@
+		    GNU GENERAL PUBLIC LICENSE
+		       Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+                       59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+			    Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+		    GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+			    NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+		     END OF TERMS AND CONDITIONS
+
+	    How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) year name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Library General
+Public License instead of this License.
diff --git a/sensors/and/Makefile b/sensors/and/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..5bf4f78052c8f66514f1fc46620b61ecda814564
--- /dev/null
+++ b/sensors/and/Makefile
@@ -0,0 +1,279 @@
+#
+# Makefile for auto nice daemon
+#
+# 1999-2004 Patrick Schemitz <schemitz@users.sourceforge.net>
+# http://and.sourceforge.net/
+#
+
+
+#######################################################################
+# Edit here to adapt to your system!                                  #
+#######################################################################
+
+
+#
+# Init script. 
+# (and.init.debian for Debian GNU/Linux or and.init for others;
+# leave empty for BSD!)
+#
+INITSCRIPT=and.init
+
+#
+# Target directories. Examples for common configurations are
+# given below.
+#
+PREFIX=/usr/local
+INSTALL_ETC=$(PREFIX)/etc
+INSTALL_INITD=/etc/init.d
+INSTALL_SBIN=$(PREFIX)/sbin
+INSTALL_MAN=$(PREFIX)/man
+
+# typical OpenBSD or FreeBSD configuration
+#PREFIX=/usr/local
+#INSTALL_ETC=/etc
+#INSTALL_INITD=
+#INSTALL_SBIN=$(PREFIX)/sbin
+#INSTALL_MAN=$(PREFIX)/man
+
+# typical Debian or SuSE 7.x configuration
+#PREFIX=/usr
+#INSTALL_ETC=/etc
+#INSTALL_INITD=/etc/init.d
+#INSTALL_SBIN=$(PREFIX)/sbin
+#INSTALL_MAN=$(PREFIX)/share/man
+
+# typical SuSE 6.x configuration
+#PREFIX=/usr
+#INSTALL_ETC=/etc
+#INSTALL_INITD=/sbin/init.d
+#INSTALL_SBIN=$(PREFIX)/sbin
+#INSTALL_MAN=$(PREFIX)/man
+
+# typical Redhat / Mandrake configuration
+#PREFIX=/usr
+#INSTALL_ETC=/etc
+#INSTALL_INITD=/etc/rc.d/init.d
+#INSTALL_SBIN=$(PREFIX)/sbin
+#INSTALL_MAN=$(PREFIX)/share/man
+
+# typical OSF/1 / Digital UNIX 4 configuration
+#PREFIX=/usr/local
+#INSTALL_ETC=/etc
+#INSTALL_INITD=/sbin/init.d
+#INSTALL_SBIN=$(PREFIX)/sbin
+#INSTALL_MAN=$(PREFIX)/man
+
+#
+# Install program
+#
+INSTALL=install
+
+
+#######################################################################
+# Stop editing here!                                                  #
+#######################################################################
+
+default: and $(INITSCRIPT) doc
+
+#
+# Version and date
+#
+VERSION=1.2.1
+DATE="09 Sep 2004"
+
+#
+# Man pages
+#
+MANPAGES=and.8 and.conf.5 and.priorities.5
+
+#
+# Determine architecture from uname(1)
+#
+ARCH=$(shell uname)
+
+#
+# Architecture-dependent settings: ANSI C compiler and linker
+#
+ifeq (${ARCH},Linux)
+  CC = gcc -ansi -pedantic -Wall -g
+  LD = gcc
+  LIBS =
+else
+ifeq (${ARCH},OSF1)
+  CC = cc -ansi
+  LD = cc
+  LIBS =
+else
+ifeq (${ARCH},OpenBSD)
+  CC = gcc
+  LD = gcc
+  LIBS = -lkvm
+else
+ifeq (${ARCH},FreeBSD)
+  CC = gcc -Wall
+  LD = gcc
+  LIBS = -lkvm
+else
+ifeq (${ARCH},SunOS)
+  CC = cc -D__SunOS__
+  LD = cc
+else
+ifeq (${ARCH},IRIX)
+  CC = cc
+  LD = cc
+else
+ifeq (${ARCH},IRIX64)
+  CC = cc
+  LD = cc
+else
+  # unsupported architecture
+  CC = false
+  LD = false
+  LIBS =
+endif
+endif
+endif
+endif
+endif
+endif
+endif
+
+
+#
+# Build the auto-nice daemon.
+#
+and: and.o and-$(ARCH).o
+	$(LD) and.o and-$(ARCH).o -o and $(LIBS)
+
+
+#
+# Independent part: configuration management, priority database.
+#
+and.o: and.c and.h
+	$(CC) -DDEFAULT_INTERVAL=60 -DDEFAULT_NICE=0 \
+	  -DDEFAULT_CONFIG_FILE=\"$(INSTALL_ETC)/and.conf\" \
+	  -DDEFAULT_DATABASE_FILE=\"$(INSTALL_ETC)/and.priorities\" \
+	  -DAND_VERSION=\"$(VERSION)\" -DAND_DATE=\"$(DATE)\" -c and.c
+
+
+#
+# Unix variant specific stuff
+#
+and-Linux.o: and.h and-Linux.c
+	$(CC) -c and-Linux.c
+
+and-OpenBSD.o: and.h and-OpenBSD.c
+	$(CC) -c and-OpenBSD.c
+
+and-FreeBSD.o: and.h and-OpenBSD.c
+	$(CC) -c and-OpenBSD.c -o and-FreeBSD.o
+
+and-OSF1.o: and.h and-OSF1.c
+	$(CC) -c and-OSF1.c
+
+and-IRIX.o: and.h and-OSF1.c
+	$(CC) -c and-OSF1.c -o and-IRIX.o
+
+and-IRIX64.o: and.h and-OSF1.c
+	$(CC) -c and-OSF1.c -o and-IRIX64.o
+
+and-SunOS.o: and.h and-OSF1.c
+	$(CC) -c and-OSF1.c -o and-SunOS.o
+
+
+
+#
+# Create script for SysV init
+#
+and.init: and.startup
+	sed s:INSTALL_SBIN:$(INSTALL_SBIN):g < and.startup > and.init
+	chmod +x and.init
+
+
+#
+# Man pages
+#
+doc:	$(MANPAGES)
+
+and.8:	and.8.man
+	cat $< | \
+		sed s/__VERSION__/$(VERSION)/g | \
+		sed s/__DATE__/$(DATE)/g > $@
+
+and.conf.5:	and.conf.5.man
+	cat $< | \
+		sed s/__VERSION__/$(VERSION)/g | \
+		sed s/__DATE__/$(DATE)/g > $@
+
+and.priorities.5:	and.priorities.5.man
+	cat $< | \
+		sed s/__VERSION__/$(VERSION)/g | \
+		sed s/__DATE__/$(DATE)/g > $@
+
+
+#
+# Install and under $(PREFIX)/bin etc.
+#
+install: and $(INITSCRIPT)
+	strip and
+#-mkdir $(PREFIX)
+	-mkdir -p $(DESTDIR)$(INSTALL_SBIN)
+	-mkdir -p $(DESTDIR)$(INSTALL_ETC)
+	-mkdir -p $(DESTDIR)$(INSTALL_INITD)
+	-mkdir -p $(DESTDIR)$(INSTALL_MAN)/man5
+	-mkdir -p $(DESTDIR)$(INSTALL_MAN)/man8
+	$(INSTALL) -m 0755 and $(DESTDIR)$(INSTALL_SBIN)
+	test -e $(DESTDIR)$(INSTALL_ETC)/and.conf || \
+	   $(INSTALL) -m 0644 and.conf $(DESTDIR)$(INSTALL_ETC)
+	test -e $(DESTDIR)$(INSTALL_ETC)/and.priorities || \
+	   $(INSTALL) -m 0644 and.priorities $(DESTDIR)$(INSTALL_ETC)
+ifneq (${INITSCRIPT},)
+ifneq (${INSTALL_INITD},)
+	@echo "Installing SysV script in $(DESTDIR)$(INSTALL_INITD)"
+	$(INSTALL) -m 0755 $(INITSCRIPT) $(DESTDIR)$(INSTALL_INITD)/and
+else
+	@echo "Installing SysV script in $(DESTDIR)$(INSTALL_SBIN)"
+	$(INSTALL) -m 0755 $(INITSCRIPT) $(DESTDIR)$(INSTALL_SBIN)
+	@echo "Installing SysV init.d finder in $(DESTDIR)$(INSTALL_SBIN)"
+	$(INSTALL) -m 0755 and-find-init.d $(DESTDIR)$(INSTALL_SBIN)
+endif
+endif
+	$(INSTALL) -m 0644 and.8 $(DESTDIR)$(INSTALL_MAN)/man8
+	$(INSTALL) -m 0644 and.conf.5 $(DESTDIR)$(INSTALL_MAN)/man5
+	$(INSTALL) -m 0644 and.priorities.5 $(DESTDIR)$(INSTALL_MAN)/man5
+
+simpleinstall: and and.init
+	strip and
+	mkdir -p $(DESTDIR)$(INSTALL_SBIN) $(DESTDIR)$(INSTALL_ETC)
+	mkdir -p $(DESTDIR)$(INSTALL_INITD)
+	mkdir -p $(DESTDIR)$(INSTALL_MAN)/man5 $(DESTDIR)$(INSTALL_MAN)/man8
+	cp and $(DESTDIR)$(INSTALL_SBIN)
+	test -e $(DESTDIR)$(INSTALL_ETC)/and.conf || \
+	   cp and.conf $(DESTDIR)$(INSTALL_ETC)
+	test -e $(DESTDIR)$(INSTALL_ETC)/and.priorities || \
+	   cp and.priorities $(DESTDIR)$(INSTALL_ETC)
+ifneq (${INITSCRIPT},) # on SysV only
+	cp $(INITSCRIPT) $(DESTDIR)$(INSTALL_INITD)/and
+endif
+	cp and.8 $(DESTDIR)$(INSTALL_MAN)/man8
+	cp and.conf.5 $(DESTDIR)$(INSTALL_MAN)/man5
+	cp and.priorities.5 $(DESTDIR)$(INSTALL_MAN)/man5
+
+uninstall:
+	rm -f $(DESTDIR)$(INSTALL_SBIN)/and
+	rm -f $(DESTDIR)$(INSTALL_INITD)/and
+	rm -f $(DESTDIR)$(INSTALL_ETC)/and.conf
+	rm -f $(DESTDIR)$(INSTALL_ETC)/and.priorities
+	rm -f $(DESTDIR)$(INSTALL_MAN)/man8/and.8
+	rm -f $(DESTDIR)$(INSTALL_MAN)/man5/and.conf.5
+	rm -f $(DESTDIR)$(INSTALL_MAN)/man5/and.priorities.5
+
+
+#
+# Clean up generated files.
+#
+clean:
+	rm -f *.o and and.init $(MANPAGES)
+
+distclean: clean
+	find . -name \*~ -exec rm \{\} \;
diff --git a/sensors/and/README b/sensors/and/README
new file mode 100644
index 0000000000000000000000000000000000000000..6efbe68412c131e3ea9ed9e411974cb75f2d48e0
--- /dev/null
+++ b/sensors/and/README
@@ -0,0 +1,90 @@
+README for the Auto Nice Daemon, AND
+------------------------------------
+
+The auto nice daemon will renice or even kill jobs according to a priority
+database, after they take up too much CPU time. (You define what "too much"
+actually means.) Refer to the man pages, and(8), and.conf(5), and
+and.priorities(5), for details and instructions, and check the home page,
+http://and.sourceforge.net/.
+
+
+Platforms:
+
+   Digital UNIX 4.0, 5.1
+   FreeBSD 4.x
+   IRIX and IRIX64
+   Linux 2.2.x and 2.4.x
+   OpenBSD 2.7+
+   Solaris 5.6
+
+Requires:
+
+   GNU make
+   ANSI C Compiler
+
+Documentation and Download:
+
+   http://and.sourceforge.net/
+
+Author:
+
+   Patrick Schemitz <schemitz@users.sourceforge.net>
+
+Credits:
+
+   SRPM spec file help by Terje Rosten <terjeros@phys.ntnu.no>
+
+   Linux/AXP jiffies to seconds fix by Markus Lischka
+   <Markus_Lischka@physik.tu-muenchen.de>
+
+   Debian package, Debian init script, Debian Makefile patches
+   by Andras Bali <bali@debian.org>
+
+   Debian Makefile patch by Mikael Andersson <mikan@mikan.net>
+
+   The guys at INTEXXIA, http://www.intexxia.com, noticed a
+   format string vulnerability and provided me with a patch.
+
+   Pauli K. Borodulin <boro@fixel.net> pointed out that overwriting
+   existing config files when doing make install was rude. He is
+   right.
+
+   Janet Casey <jcasey@gnu.org> noticed and reported that the LICENSE
+   file was truncated.
+
+   Dan Stromberg <strombrg@nis.acs.uci.edu> pointed out that
+   the Digital UNIX version, and-OSF1.c, works virtually unchanged
+   on IRIX, IRIX64 and Solaris (SunOS).
+
+   "Quake2" <quake2@vladimir.eso.nu> pointed out that
+   the OpenBSD version works virtually unchanged on FreeBSD.
+
+   Marcelo Matus <mmatus@dinha.acms.arizona.edu> sent a patch for
+   problems with very long running processes (alread longer than 248
+   days when auto nice daemon is started), and other issues.
+
+   Dr. Hans Ekkehard Plesser <hans.ekkehard.plesser@nlh.no> came up with
+   the idea of also examining a process' parent, as well as with the
+   minuid and mingid configuration options.
+
+   Both xavier@rootshell.be and Jerome Warnier <jwarnier@beeznest.net>
+   noticed that the Linux version accounted for usr time only; Xavier
+   also provided a (one-line) fix. (Solaris, IRIX, and Tru 64 already
+   did this.)
+
+Installation:
+
+   Edit the Makefile, which is well documented. (g)make. (g)make install.
+   (make simpleinstall if you don't have install(1) (which you really
+   should). Edit the configuration files, /etc/and.conf and
+   /etc/and.priorities. Start /usr/local/sbin/and. You must run it as
+   root if you want it to renice or kill any jobs but your own; on all
+   platforms but Linux, not even dummy mode will work for mortal users.
+   That's due to the way process information is accessible under these
+   Unices. (Linux is more generous here, which can be seen as both an
+   advantage and a security flaw. I'm not conclusive on this topic.)
+
+Last updated:
+
+   This document was last updated 2004/03/06 by Patrick Schemitz
+   <schemitz@users.sourceforge.net>
diff --git a/sensors/and/and-Linux.c b/sensors/and/and-Linux.c
new file mode 100644
index 0000000000000000000000000000000000000000..25657afa81915471879af6d844ef838b44526a81
--- /dev/null
+++ b/sensors/and/and-Linux.c
@@ -0,0 +1,135 @@
+/*
+
+    AND auto nice daemon - renice programs according to their CPU usage.
+    Copyright (C) 1999-2003 Patrick Schemitz <schemitz@users.sourceforge.net>
+    http://and.sourceforge.net/
+
+    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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <limits.h>
+#include <unistd.h>
+#include <string.h>
+#include <dirent.h>
+#include <ctype.h>
+#include <syslog.h>
+#include <sys/stat.h>
+#include <signal.h>
+#include <asm/param.h> /* kernel interrupt frequency: HZ */
+
+
+#include "and.h"
+
+
+/*
+
+  AND -- auto-nice daemon/Linux version.
+  
+  Linux-specific AND version. Makes excessive use of the Linux
+  /proc filesystem and is not portable.
+  
+  1999-2003 Patrick Schemitz, <schemitz@users.sourceforge.net>
+  http://and.sourceforge.net/
+  
+*/
+
+
+static DIR *linux_procdir = 0;
+
+
+static struct and_procent linux_proc;
+
+
+int linux_readproc (char *fn)
+{
+  /* Scan /proc/<pid>/stat file. Format described in proc(5).
+     l1: pid comm state ppid 
+     l2: pgrp session tty tpgid
+     l3: flags minflt cminflt majflt cmajflt
+     l4: utime stime cutime cstime
+     l5: counter priority
+  */
+  FILE* f;
+  int i;
+  long li;
+  long unsigned u, ujf, sjf;
+  char state;
+  char buffer [1024];
+  if (!(f = fopen(fn,"rt"))) return 0;
+  fscanf(f,"%d %1023s %c %d",&(linux_proc.pid),buffer,&state,&(linux_proc.ppid));
+  fscanf(f,"%d %d %d %d",&i,&i,&i,&i);
+  fscanf(f,"%lu %lu %lu %lu %lu",&u,&u,&u,&u,&u);
+  fscanf(f,"%lu %lu %ld %ld",&ujf,&sjf,&li,&li);
+  fscanf(f,"%ld %d",&li,&(linux_proc.nice));
+  i = feof(f);
+  fclose(f);
+  if (i) return 0;
+  if (state == 'Z') return 0; /* ignore zombies */
+  ujf += sjf;  /* take into account both usr and sys time */
+  ujf /= HZ;   /* convert jiffies to seconds */
+  linux_proc.utime = ujf > INT_MAX ? INT_MAX: (int) ujf;
+  buffer[strlen(buffer)-1] = 0;   /* remove () around command name */
+  strncpy(linux_proc.command,&buffer[1],1023);
+  linux_proc.command[1023] = 0;
+  and_printf(3, "Linux: process %s pid: %d ppid: %d\n", 
+             linux_proc.command, linux_proc.pid, linux_proc.ppid);
+  return 1;
+}
+
+
+struct and_procent *linux_getnext ()
+{
+  char name [1024];
+  struct dirent *entry;
+  struct stat dirstat;
+  if (!linux_procdir) return NULL;
+  while ((entry = readdir(linux_procdir)) != NULL) { /* omit . .. apm bus... */
+    if (isdigit(entry->d_name[0])) break;
+  }
+  if (!entry) return NULL;
+  snprintf(name, 1024, "/proc/%s/stat",entry->d_name);
+  /* stat() file to get uid/gid */
+  if (stat(name,&dirstat)) return linux_getnext();
+  /* read the job's stat "file" to get command, nice level, etc */
+  if (!linux_readproc(name)) return linux_getnext();
+  linux_proc.uid = dirstat.st_uid;
+  linux_proc.gid = dirstat.st_gid;
+  return &linux_proc;
+}
+
+
+struct and_procent *linux_getfirst ()
+{
+  if (linux_procdir) {
+    rewinddir(linux_procdir);
+  } else {
+    linux_procdir = opendir("/proc");
+    if (!linux_procdir) {
+      and_printf(0,"cannot open /proc, aborting.\n");
+      abort();
+    }
+  }
+  return linux_getnext();
+}
+
+
+int main (int argc, char** argv)
+{
+  and_setprocreader(&linux_getfirst,&linux_getnext);
+  return and_main(argc,argv);
+}
diff --git a/sensors/and/and-OSF1.c b/sensors/and/and-OSF1.c
new file mode 100644
index 0000000000000000000000000000000000000000..558c098b806506e23d9042042cde785975f82488
--- /dev/null
+++ b/sensors/and/and-OSF1.c
@@ -0,0 +1,139 @@
+/*
+
+    AND auto nice daemon - renice programs according to their CPU usage.
+    Copyright (C) 1999-2001 Patrick Schemitz <schemitz@users.sourceforge.net>
+    http://and.sourceforge.net/
+
+    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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+*/
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include <sys/types.h>
+#include <dirent.h>
+#include <limits.h>
+#include <sys/ioctl.h>
+#include <sys/procfs.h>
+#include <sys/times.h>
+#include <sys/file.h>
+#include <sys/resource.h>
+#include <sys/utsname.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <syslog.h>
+#include <signal.h>
+#include <math.h>
+#include <sys/stat.h>
+
+#include "and.h"
+
+
+/*
+
+  AND -- auto-nice daemon/Digital UNIX(OSF/1) version.
+
+  OSF/1-specific AND version. Makes reasonable use of the OSF/1
+  /proc filesystem and seems to be more portable than I thought.
+
+  Also works for Solaris (SunOS 5) and IRIX/IRIX64. (Thanks to
+  Dan Stromberg for telling me.)
+
+  2000, 2001 Patrick Schemitz, <schemitz@users.sourceforge.net>
+  http://and.sourceforge.net/
+  
+*/
+
+
+static DIR *digitalunix_procdir = 0;
+
+
+static struct and_procent digitalunix_proc;
+
+
+int digitalunix_readproc (char *fn)
+{
+  prpsinfo_t ps;
+  double cputime;
+  int res, fd;
+  if ((fd = open(fn, O_RDONLY)) < 0) return 0;
+  res = ioctl(fd, PIOCPSINFO, &ps);
+  close(fd);
+  if (res < 0) return 0;
+  digitalunix_proc.uid = ps.pr_uid;
+  digitalunix_proc.gid = ps.pr_gid;
+  digitalunix_proc.ppid = ps.pr_ppid;
+  strncpy(digitalunix_proc.command,ps.pr_fname,1022);
+  digitalunix_proc.command[1023] = 0;
+  cputime = (double)ps.pr_time.tv_sec + (double)ps.pr_time.tv_nsec / 1.0E9;
+  digitalunix_proc.utime = (int)cputime;
+  digitalunix_proc.pid = ps.pr_pid;
+  digitalunix_proc.nice = getpriority(PRIO_PROCESS, ps.pr_pid);
+  /*
+    printf("%5i  %-20s  %5i  %3i\n", digitalunix_proc.pid,
+    digitalunix_proc.command, digitalunix_proc.utime,
+    digitalunix_proc.nice);
+  */
+  and_printf(3, "OSF/1: process: %s pid: %d ppid: %d\n", 
+             digitalunix_proc.command, 
+             digitalunix_proc.pid, 
+             digitalunix_proc.ppid);
+  return 1;
+}
+
+
+struct and_procent *digitalunix_getnext ()
+{
+  char name [1024];
+  struct dirent* entry;
+  struct stat dirstat;
+  if (!digitalunix_procdir) return NULL;
+  while ((entry = readdir(digitalunix_procdir)) != NULL) {
+    if (!isdigit(entry->d_name[0])) continue;
+    sprintf(name,"/proc/%s",entry->d_name);
+    if (access(name, R_OK) < 0) {
+      and_printf(0,"read access denied: /proc/%s\n",entry->d_name);
+      continue;
+    }
+    break;
+  }
+  if (!entry) return NULL;
+  if (!digitalunix_readproc(name)) return NULL;
+  return &digitalunix_proc;
+}
+
+
+struct and_procent *digitalunix_getfirst ()
+{
+  if (digitalunix_procdir) {
+    rewinddir(digitalunix_procdir);
+  } else {
+    digitalunix_procdir = opendir("/proc");
+    if (!digitalunix_procdir) {
+      and_printf(0,"/proc: cannot open /proc. Aborting.\n");
+      abort();
+    }
+  }
+  return digitalunix_getnext();
+}
+
+
+int main (int argc, char** argv)
+{
+  and_setprocreader(&digitalunix_getfirst,&digitalunix_getnext);
+  return and_main(argc,argv);
+}
diff --git a/sensors/and/and-OpenBSD.c b/sensors/and/and-OpenBSD.c
new file mode 100644
index 0000000000000000000000000000000000000000..fb4565041a5e6022a3174a66b21d5f22ae66fc9c
--- /dev/null
+++ b/sensors/and/and-OpenBSD.c
@@ -0,0 +1,142 @@
+/*
+
+    AND auto nice daemon - renice programs according to their CPU usage.
+    Copyright (C) 1999-2001 Patrick Schemitz <schemitz@users.sourceforge.net>
+    http://and.sourceforge.net/
+
+    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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+*/
+
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <kvm.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <sys/param.h>
+#include <sys/sysctl.h>
+#include <sys/proc.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <sys/resourcevar.h>
+
+#ifdef __FreeBSD__
+#include <sys/user.h>
+#endif
+
+
+#include "and.h"
+
+
+/*
+
+  AND -- auto-nice daemon/OpenBSD version.
+  
+  OpenBSD-specific AND version. Makes excessive use of the OpenBSD
+  kernel memory interface, kvm, but also works for FreeBSD.
+  
+  2000, 2002 Patrick Schemitz, <schemitz@users.sourceforge.net>
+  http://and.sourceforge.net/
+  
+*/
+
+
+static kvm_t *openbsd_kvm = NULL;
+static struct kinfo_proc *openbsd_pt = NULL;
+static int openbsd_nproc = 0;
+static int openbsd_next = 0;
+static long openbsd_hz = -1;
+
+
+static struct and_procent openbsd_proc;
+
+
+static int openbsd_init ()
+{
+  struct nlist nlst [] = {
+    { "_hz" },
+    { 0 }
+  };
+  kvm_nlist(openbsd_kvm,nlst);
+  if (nlst[0].n_type == 0) {
+    and_printf(0,"KVM: nlist failed. Aborting.\n");
+    abort();
+  }
+  if (kvm_read(openbsd_kvm,nlst[0].n_value,(char*)(&openbsd_hz),
+	       sizeof(openbsd_hz)) != sizeof(openbsd_hz)) {
+    and_printf(0,"KVM: hz symbol empty. Aborting.\n");
+    abort();
+  }
+  return 1;
+}
+
+
+struct and_procent *openbsd_getnext ()
+{
+  if (!openbsd_pt) {
+    and_printf(0,"KVM: no process table (late detection). Aborting.\n");
+    abort();
+  }
+  if (openbsd_next >= openbsd_nproc) return NULL;
+  strncpy(openbsd_proc.command,openbsd_pt[openbsd_next].kp_proc.p_comm,1023);
+  openbsd_proc.command[1023] = 0;
+  openbsd_proc.pid = openbsd_pt[openbsd_next].kp_proc.p_pid;
+  openbsd_proc.ppid = openbsd_pt[openbsd_next].kp_proc.p_ppid; /* FIXME that correct? */
+  openbsd_proc.nice = openbsd_pt[openbsd_next].kp_proc.p_nice-20;
+  openbsd_proc.uid = openbsd_pt[openbsd_next].kp_eproc.e_pcred.p_ruid;
+  openbsd_proc.gid = openbsd_pt[openbsd_next].kp_eproc.e_pcred.p_rgid;
+  /* Adapted from top(1) port, as found in the misc@openbsd.org archive */
+  openbsd_proc.utime = (openbsd_pt[openbsd_next].kp_proc.p_uticks +
+			openbsd_pt[openbsd_next].kp_proc.p_sticks +
+			openbsd_pt[openbsd_next].kp_proc.p_iticks)
+    / openbsd_hz;
+  /*
+    printf("%-20s  %5i  %3i  %i\n",openbsd_proc.command,openbsd_proc.pid,
+    openbsd_proc.nice,openbsd_proc.utime);
+  */
+  and_printf(3, "OpenBSD: process %s pid: %d ppid: %d\n", 
+             openbsd_proc.command, openbsd_proc.pid, openbsd_proc.ppid);
+  openbsd_next++;
+  return &openbsd_proc;
+}
+
+
+struct and_procent *openbsd_getfirst ()
+{
+  char errmsg [_POSIX2_LINE_MAX];
+  if (!openbsd_kvm) {
+    openbsd_kvm = kvm_openfiles(NULL,NULL,NULL,O_RDONLY,errmsg);
+    if (!openbsd_kvm) {
+      and_printf(0,"KVM: cannot open (\"%s\"). Aborting.\n",errmsg);
+      abort();
+    }
+    openbsd_init();
+  }
+  openbsd_pt = kvm_getprocs(openbsd_kvm,KERN_PROC_ALL,0,&openbsd_nproc);
+  if (!openbsd_pt) {
+    and_printf(0,"KVM: cannot retrieve process table. Aborting.\n");
+    abort();
+  }
+  openbsd_next = 0;
+  return openbsd_getnext();
+}
+
+
+int main (int argc, char** argv)
+{
+  and_setprocreader(&openbsd_getfirst,&openbsd_getnext);
+  return and_main(argc,argv);
+}
diff --git a/sensors/and/and.8.man b/sensors/and/and.8.man
new file mode 100644
index 0000000000000000000000000000000000000000..418177615b87bc6677b6bcacaff5a6d2bdeba392
--- /dev/null
+++ b/sensors/and/and.8.man
@@ -0,0 +1,146 @@
+.TH AND 8 "__DATE__" "Unix" "Administrator's Tools"
+
+.SH "NAME"
+and \- auto nice daemon
+
+.SH "SYNOPSIS"
+.B and
+.RB [ \-htvsx ]
+.RB [ \-i
+.IR interval ]
+.RB [ \-c
+.IR /path/to/and.conf ]
+.RB [ \-d
+.IR /path/to/and.priorities ]
+
+
+.SH "VERSION"
+This manual page documents
+.B and
+version __VERSION__.
+
+.SH "DESCRIPTION"
+The auto nice daemon activates itself in certain intervals and renices and
+even kills jobs according to their priority and CPU usage.
+
+Renice levels and kill signals can be defined in terms of users, groups,
+and commands. Wildcards can be specified for any of these. In addition,
+commands can be specified using POSIX regular expressions. To allow for
+network-wide configuration and priority files, a mechanism for hostname-based
+evaluation is provided, again supporting regular expressions for specifying
+host names.
+
+Jobs owned by root are left alone. Jobs are never increased in their priority.
+
+Here are some real-world examples:
+
+A certain user is notorious for wasting CPU with next-to-irrelevant jobs.
+One line is sufficient to renice all of his jobs to about 19.
+This is a typical situation for a LART (Luser's Attitude Readjustment Tool)
+like
+.B and.
+
+A CPU server is dedicated to a certain group, but others may also use
+it when it's idle. Just define default nice levels of e.g. 18 and a lower
+nice level for the privilegued group, say nice level 12.
+
+A certain web browser who shall remain unnamed tends to go berserk once
+in a while. You can configure 
+.B and
+to kill -9 it after e.g. 20 CPU minutes.
+
+
+.SH "COMMAND\-LINE OPTIONS"
+
+.TP 0.5i
+.B \-c /path/to/and.conf
+Specifies the configuration file. If this flag is omitted,
+.I /etc/and.conf
+is used instead.
+
+.TP 0.5i
+.B \-d /path/to/and.priorities
+Specifies the priority database file. If this flag is omitted,
+.I /etc/and.priorities
+is used instead.
+
+.TP 0.5i
+.B \-h
+Produces a short help text.
+
+.TP 0.5i
+.B \-i interval
+Sets the interval between nice level checks. This flag overrides the
+interval specified in the configuration file, if any. The default interval of
+.I 60
+seconds is used if neither -i nor an interval directive in the configuration
+file is given.
+
+.TP 0.5i
+.B \-s
+Log to stdout. Without this switch, logging goes to syslog (normal
+operations) or
+.I ./debug.and
+(test mode). Useful for debugging config files.
+
+.TP 0.5i
+.B \-t
+Run in test mode only, i.e. don't really renice or kill anything.
+In this mode, logging goes into
+.I ./debug.and
+instead of syslog.
+
+.TP 0.5i
+.B \-v
+Increase verbosity. For maximum verbosity, this flag can be specified
+multiple times. Be warned that this will blow up your log files, so
+you should use it in test mode only.
+
+.TP 0.5i
+.B \-x
+Run in full operational mode, i.e. really renice or kill things.
+This is the default.
+
+.SH "SIGNALS"
+
+On
+.B kill -HUP
+the auto nice daemon will reload its configuration file and priority
+database.
+
+
+.SH "FILES"
+
+.TP 0.5i
+.B  /etc/and.conf
+General configuration file. Stores default nice level, default interval,
+the "time zones" and the database lookup affinity.
+
+.TP 0.5i
+.B /etc/and.priorities
+The priority database (in plain text). Contains the (user, group, command,
+nicelevels) tuples.
+
+.TP 0.5i
+Both files have their own manual pages.
+
+.TP 0.5i
+.B ./debug.and
+Contains logging and status information for debugging purposes. 
+Used in test mode only.
+
+.SH "SEE ALSO"
+.BR and.conf (5),
+.BR and.priorities (5),
+.BR kill (1),
+.BR regex (7),
+.BR renice (8)
+
+
+.SH "INTERNET"
+.B http://and.sourceforge.net/
+
+
+.SH "AUTHOR"
+The auto nice daemon and this manual page were written by
+Patrick Schemitz <schemitz@users.sourceforge.net>
diff --git a/sensors/and/and.c b/sensors/and/and.c
new file mode 100644
index 0000000000000000000000000000000000000000..54933b785a251e4148478874a070872f9317f115
--- /dev/null
+++ b/sensors/and/and.c
@@ -0,0 +1,993 @@
+/*
+
+    AND auto nice daemon - renice programs according to their CPU usage.
+    Copyright (C) 1999-2004 Patrick Schemitz <schemitz@users.sourceforge.net>
+    http://and.sourceforge.net/
+
+    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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+*/
+
+/************************************************************************
+ *                                                                      *
+ * and.c -- AND library for platform-independent code.                  *
+ *                                                                      *
+ * Automatically renice jobs when they use too much CPU time.           *
+ *                                                                      *
+ * 1999-2004 Patrick Schemitz <schemitz@users.sourceforge.net>          *
+ * http://and.sourceforge.net/                                          *
+ *                                                                      *
+ ***********************************************************************/
+
+#include <stdio.h>
+#include <stdarg.h>
+#include <assert.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <limits.h>
+#include <pwd.h>
+#include <grp.h>
+#include <syslog.h>
+#include <time.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <sys/types.h>
+#include <signal.h>
+#include <regex.h>
+#include <values.h>
+
+#define DEBUG 0
+
+/* OpenBSD getopt() is in unistd.h; Linux and Digital UNIX have getopt.h */
+#if !defined(__OpenBSD__) && !defined(__FreeBSD__) && !defined(__svr4__) && !defined(__SunOS__)
+#include <getopt.h>
+#endif
+
+/* GNU C library forgets to declare this one: */
+#ifdef __GNUC__
+int vsnprintf (char *str, size_t n, const char *format, va_list ap);
+#define HAVE_VSNPRINTF
+#endif
+
+#include "and.h"
+
+
+
+#ifndef DEFAULT_NICE
+#define DEFAULT_NICE 0
+#endif
+
+#ifndef LOG_PERROR
+#define LOG_PERROR 0
+#endif
+
+#ifndef DEFAULT_INTERVAL
+#define DEFAULT_INTERVAL 60
+#endif
+
+#ifndef DEFAULT_CONFIG_FILE
+#define DEFAULT_CONFIG_FILE "/etc/and.conf"
+#endif
+
+#ifndef DEFAULT_DATABASE_FILE
+#define DEFAULT_DATABASE_FILE "/etc/and.priorities"
+#endif
+
+#ifndef AND_VERSION
+#define AND_VERSION "1.0.7 or above (not compiled in)"
+#endif
+
+#ifndef AND_DATE
+#define AND_DATE "27 Jan 2002 or later (not compiled in)"
+#endif
+
+
+#define bool  char
+#define false (0)
+#define true  (!false)
+
+
+/* Maximum entries in priority database. You may change this,
+   if you have a really large priority database. However, you
+   shouldn't make too large databases since the get_priority()
+   function takes too long otherwise. */
+
+#define PRI_MAXENTRIES 100
+
+
+/* Indices for the weight array when resolving a user/group/command/parent
+   tuple to get the correct priority database entry. These are
+   constants. Never ever change them! Change the affinity in the
+   config file instead. */
+
+enum {
+  PRI_U, PRI_G, PRI_C, PRI_P, PRI_N
+};
+
+
+/* Priority database entry record. Consists of the user ID, the
+   group ID, the command (string and compiled regexp), the parent
+   (string and compiled regexp), and three nice levels. */
+
+#define PARENT_ONLY 0
+#define PARENT_AND_ANCHESTORS 1
+
+#define PARENT_ONLY_KEYWORD "parent="
+#define PARENT_AND_ANCHESTORS_KEYWORD "ancestor="
+
+struct priority_db_entry {
+  int uid;
+  int gid;
+  char command_str [128];
+  regex_t *command;
+  char parent_str [128];
+  regex_t *parent;
+  int parentmode;
+  int nl [3];
+};
+
+
+/* Global variables for priority database (db), configuration (conf),
+   and other arguments (args). */
+
+struct{
+  int n;
+  struct priority_db_entry entry [PRI_MAXENTRIES];
+} and_db;
+
+
+
+/* AND configuration data. Some of this is compiled in; for some things
+   there are command-line options, and some is read from and.conf */
+
+struct {
+  char hostname [512];
+  int test;
+  char *program;
+  char *config_file;
+  char *database_file;
+  int verbose;
+  int to_stdout;
+  int nice_default;
+  bool lock_interval;
+  unsigned interval;
+  unsigned time_mark [3];
+  char affinity [5];
+  int weight [PRI_N];
+  int min_uid;
+  int min_gid;
+} and_config;
+
+
+
+/* Initialise configuration parameters. Some are later over-
+   ridden by command-line arguments and and.conf. */
+
+void set_defaults (int argc, char **argv)
+{
+  and_config.test = 0;
+  and_config.verbose = 0;
+  and_config.to_stdout = 0;
+  and_config.program = argv[0];
+  and_config.lock_interval = false;
+  and_config.interval = DEFAULT_INTERVAL;
+  and_config.config_file = DEFAULT_CONFIG_FILE;
+  and_config.database_file = DEFAULT_DATABASE_FILE;
+  and_config.nice_default = DEFAULT_NICE;
+  and_config.min_uid = 0;
+  and_config.min_gid = 0;
+  gethostname(and_config.hostname,511);
+  and_config.hostname[511] = 0;
+}
+
+
+
+/* Log AND messages (to ./debug.and if in test mode, syslog() otherwise).
+   If available, uses non-ANSI function vsnprintf() to avoid possible
+   buffer overflow. */
+
+void and_printf (int required_verbosity, char *fmt, ...)
+{
+  va_list args;
+  static int syslog_open = 0;
+  static FILE *out = NULL;
+  char buffer [2048];
+  time_t t;
+  va_start(args,fmt);
+  if (and_config.verbose >= required_verbosity)
+  {
+    if (and_config.test) {
+      /* in test mode, create log file; use stderr on failure */
+      if (!and_config.to_stdout && !out) {
+        out = fopen("./debug.and","wt");
+        if (!out) {
+          out = stderr;
+        }
+      }
+      /* write time stamp to ./debug.and */
+      t = time(NULL);
+      strncpy(buffer,ctime(&t),2047);
+      buffer[strlen(buffer)-1] = ' ';
+      if (and_config.to_stdout)
+        fputs(buffer,stdout);
+      else
+        fputs(buffer,out);
+    }
+    /* build actual log message */
+#ifdef HAVE_VSNPRINTF
+    vsnprintf(buffer,2048,fmt,args);
+#else
+    vsprintf(buffer,fmt,args); /* ... and hope for the best :( */
+    buffer[2047] = 0;
+#endif
+    if (and_config.to_stdout) {
+      fputs(buffer,stdout);
+      fflush(stdout);
+    } else {
+      if (and_config.test) {
+        /* log to ./debug.and in test mode */
+        fputs(buffer,out);
+        fflush(out);
+      } else {
+        /* write to syslog if in full operations */
+        if (!syslog_open) {
+          openlog(and_config.program,LOG_PERROR|LOG_PID,LOG_DAEMON);
+          syslog_open = 1;
+        }
+        syslog(LOG_WARNING,"%s",buffer);
+      }
+    }
+  }
+  va_end(args);
+}
+
+
+/* Print priority database. */
+
+void print_priorities ()
+{
+  int i;
+  and_printf(0,"Priority database:\n");
+  and_printf(0,"UID:   GID:   Command               Parent:                             NLs:\n");
+  for (i=0; i<and_db.n; i++) {
+    and_printf(0,"%5i  %5i  %-20s  %-20s %-13s  %2i,%2i,%2i\n",
+	       and_db.entry[i].uid, and_db.entry[i].gid,
+	       and_db.entry[i].command_str, 
+               and_db.entry[i].parent_str,
+               (and_db.entry[i].parentmode == PARENT_ONLY ? "(parent)" : "(ancestors)"),
+               and_db.entry[i].nl[0],
+	       and_db.entry[i].nl[1], and_db.entry[i].nl[2]);
+  }
+  and_printf(0,"%i entries.\n\n",and_db.n);
+}
+
+
+/* Print configuration parameters. */
+
+void print_config ()
+{
+  and_printf(0,"Configuration parameters:\n"
+	     "host name:            %s\n"
+	     "operational mode:     %s\n"
+	     "verbosity:             %2i\n"
+	     "default nicelevel:     %2i\n"
+	     "interval     [sec]:   %3u\n"
+	     "level 0 from [sec]:   %3u\n"
+	     "level 1 from [sec]:   %3u\n"
+	     "level 2 from [sec]:   %3u\n"
+             "minimum uid:          %i\n"
+             "minimum gid:          %i\n"
+	     "affinity:             %s\n"
+	     "          U: %i\n"
+	     "          G: %i\n"
+	     "          C: %i\n"
+	     "          P: %i\n\n",
+	     and_config.hostname, 
+	     (and_config.test?"just checkin'":"I'm serious."),
+	     and_config.verbose,
+	     and_config.nice_default, and_config.interval,
+	     and_config.time_mark[0], and_config.time_mark[1],
+	     and_config.time_mark[2], 
+             and_config.min_uid, and_config.min_gid,
+             and_config.affinity,
+	     and_config.weight[PRI_U], and_config.weight[PRI_G],
+	     and_config.weight[PRI_C], and_config.weight[PRI_P]);
+}
+
+
+/* Parse one line of the priority database */
+
+void read_priorities ()
+{
+  FILE *priority;
+  int bad_count, line_count;
+  char buffer [1024];
+  /* entry field */
+  int uid;
+  char uid_s [1024];
+  int gid;
+  char gid_s [1024];
+  char command [1024];
+  int parentmode;
+  char parent [1024];
+  char parent_s [1024];
+  int nl0, nl1, nl2;
+  /* auxillary structs */
+  struct passwd *lookup_p;
+  struct group *lookup_g;
+  int error;
+  char error_msg [1024];
+  int i, entry;
+  int linelen;
+  regex_t *rex;
+  bool section_matches = true;
+
+  if ((priority = fopen(and_config.database_file,"rt")) == 0) {
+    and_printf(0,"Priority database %s not found. Aborting.\n",
+	       and_config.database_file);
+    abort();
+  }
+  and_printf(0,"Priority database is: %s\n", and_config.database_file);
+  /* Read file line by line */
+  line_count = bad_count = 0;
+  and_db.n = 0;
+  while (!feof(priority)) {
+    memset(buffer,0,1024);
+    if (fgets(buffer,1022,priority) == 0) break;
+    line_count++;
+    /* Intercept empty lines, comments, and overflows */
+    linelen = strlen(buffer);
+    if (linelen == 0) {
+      continue;
+    }
+    if (buffer[0] == 10 || buffer[0] == 13 || buffer[0] == '#') {
+      continue;
+    }
+    if (linelen > 1022) {
+      and_printf(0,"Priority database line %i too long: %s\n",
+		 line_count, buffer);
+      bad_count++;
+      continue;
+    }
+    /* Handle host-specific parts */
+    if ((buffer[0] == 'o') && (buffer[1] == 'n') && (buffer[2] == ' ')) {
+      while (buffer[strlen(buffer)-1] < 32) {
+	buffer[strlen(buffer)-1] = 0;
+      }
+      rex = (regex_t*)malloc(sizeof(regex_t));
+      regcomp(rex,&buffer[3],REG_NOSUB|REG_EXTENDED);
+      section_matches = (regexec(rex,and_config.hostname,0,0,0) == 0);
+      and_printf(0,"Priority database line %i: section for host(s) %s will be %s.\n",
+		 line_count, &buffer[3], (section_matches?"read":"skipped"));
+      regfree(rex);
+      continue;
+    }
+    if (!section_matches) {
+      continue;
+    }
+    i = sscanf(buffer, "%s %s %s %s %i %i %i",
+	       uid_s, gid_s, command, parent_s, &nl0, &nl1, &nl2);
+    if (i != 7) {
+      and_printf(0,"Priority database line %i is invalid: %s\n",
+		 line_count, buffer);
+      bad_count++;
+      continue;
+    }
+    /* Identify UID */
+    if (strcmp(uid_s,"*") == 0) {
+      uid = -1;
+    } else if ((lookup_p = getpwnam(uid_s)) != 0) {
+      uid = lookup_p->pw_uid;
+    } else if ((i = atoi(uid_s)) > 0) {
+      uid = i;
+    } else {
+      and_printf(0,"Priority database line %i with invalid UID: %s\n",
+		 line_count, uid_s);
+      bad_count++;
+      continue;
+    }
+    /* Identify GID */
+    if (strcmp(gid_s,"*") == 0) {
+      gid = -1;
+    } else if ((lookup_g = getgrnam(gid_s)) != 0) {
+      gid = lookup_g->gr_gid;
+    } else if ((i = atoi(gid_s)) > 0) {
+      gid = i;
+    } else {
+      and_printf(0,"Priority database line %i with invalid GID: %s\n",
+		 line_count, gid_s);
+      bad_count++;
+      continue;
+    }
+    /* figure parent mode */
+    if (strcmp(parent_s,"*") == 0) {
+      strcpy(parent,"*");
+      parentmode = PARENT_ONLY;
+    } else if (strncmp(parent_s,PARENT_ONLY_KEYWORD,
+                strlen(PARENT_ONLY_KEYWORD)) == 0) {
+      strcpy(parent,&parent_s[strlen(PARENT_ONLY_KEYWORD)]);
+      parentmode = PARENT_ONLY;
+    } else if (strncmp(parent_s,PARENT_AND_ANCHESTORS_KEYWORD,
+                       strlen(PARENT_AND_ANCHESTORS_KEYWORD)) == 0) {
+      strcpy(parent,&parent_s[strlen(PARENT_AND_ANCHESTORS_KEYWORD)]);
+      parentmode = PARENT_AND_ANCHESTORS;
+    } else {
+      and_printf(0,"Priority database line %i with bad parent keyword: %s\n",
+		 line_count, parent_s);
+      bad_count++;
+      continue;
+    }
+    /* Find entry in database */
+    entry = and_db.n;
+    for (i=0; i<and_db.n; ++i) {
+      if (and_db.entry[i].uid == uid && and_db.entry[i].gid == gid
+	  && strcmp(and_db.entry[i].command_str,command) == 0
+          && strcmp(and_db.entry[i].parent_str,parent) == 0) {
+	entry = i;
+	break;
+      }
+    }
+    /* If not recycling an entry (i.e. overwriting the priorities),
+       rebuild the regular expression */
+    if (!and_db.entry[entry].command) {
+      and_db.entry[entry].uid = uid;
+      and_db.entry[entry].gid = gid;
+      and_db.entry[entry].command = (regex_t*)malloc(sizeof(regex_t));
+      error = regcomp(and_db.entry[entry].command,command,REG_NOSUB);
+      if (error) {
+	regerror(error,and_db.entry[entry].command,error_msg,1023);
+	regfree(and_db.entry[entry].command);
+	free(and_db.entry[entry].command);
+	and_db.entry[entry].command = NULL;
+	and_printf(0,"Priority database line %i with bad command regexp %s (%s)\n",
+		   line_count, command, error_msg);
+	bad_count++;
+	continue;
+      }
+      strncpy(and_db.entry[entry].command_str,command,127);
+      and_db.entry[entry].command_str[127] = 0;
+      and_db.entry[entry].parent = (regex_t*)malloc(sizeof(regex_t));
+      error = regcomp(and_db.entry[entry].parent,parent,REG_NOSUB);
+      if (error) {
+	regerror(error,and_db.entry[entry].parent,error_msg,1023);
+	regfree(and_db.entry[entry].parent);
+	free(and_db.entry[entry].parent);
+	and_db.entry[entry].parent = NULL;
+	and_printf(0,"Priority database line %i with bad parent regexp %s (%s)\n",
+		   line_count, parent, error_msg);
+	bad_count++;
+	continue;
+      }
+      strncpy(and_db.entry[entry].parent_str,parent,127);
+      and_db.entry[entry].parent_str[127] = 0;
+      and_db.entry[entry].parentmode = parentmode;
+    }
+    and_db.entry[entry].nl[0] = nl0;
+    and_db.entry[entry].nl[1] = nl1;
+    and_db.entry[entry].nl[2] = nl2;
+    if (entry == and_db.n) {
+      and_db.n++;
+    }
+  }
+  /* cleanup */
+  fclose(priority);
+  if (and_config.verbose > 1) {
+    print_priorities();
+  }
+  if (bad_count) {
+    and_printf(0,"Priority database contains %i bad lines. Aborting.\n",
+	       bad_count);
+    abort();
+  }
+}
+
+
+void read_config ()
+{
+  FILE *f;
+  int i, val, bad, bad_f, line, u, g, c, p;
+  unsigned uval;
+  char buffer [1024];
+  char param [1024];
+  char value [1024];
+  regex_t *rex;
+  bool section_matches = true;
+  if ((f = fopen(and_config.config_file,"rt")) == 0) {
+    and_printf(0,"Configuration file %s not found. Aborting.\n",
+	       and_config.config_file);
+    abort();
+  }
+  and_printf(0,"Configuration file is: %s\n", and_config.config_file);
+  /* Set defaults */
+  strcpy(and_config.affinity,"ugcp");
+  and_config.weight[PRI_U] = 8;
+  and_config.weight[PRI_G] = 4;
+  and_config.weight[PRI_C] = 2;
+  and_config.weight[PRI_P] = 1;
+  and_config.time_mark[0] = 120;   /*  2 min */
+  and_config.time_mark[1] = 1200;  /* 20 min */
+  and_config.time_mark[2] = 3600;  /* 60 min */
+  /* Read file line by line */
+  line = 0;
+  bad = 0;
+  fgets(buffer,1023,f);
+  while (!feof(f)) {
+    ++line;
+    if (buffer[0] == 10 || buffer[0] == 13 || buffer[0] == '#') {
+      memset(buffer,0,1024);
+      if (fgets(buffer,1022,f) == 0) break;
+      continue;
+    }
+    if ((buffer[0] == 'o') && (buffer[1] == 'n') && (buffer[2] == ' ')) {
+      while (buffer[strlen(buffer)-1] < 32) {
+	buffer[strlen(buffer)-1] = 0;
+      }
+      rex = (regex_t*)malloc(sizeof(regex_t));
+      regcomp(rex,&buffer[3],REG_NOSUB|REG_EXTENDED);
+      section_matches = (regexec(rex,and_config.hostname,0,0,0) == 0);
+      and_printf(0,"Configuration file line %i: section for host(s) %s will be %s.\n",
+		 line, &buffer[3], (section_matches?"read":"skipped"));
+      regfree(rex);
+      buffer[0] = '#'; /* trigger read next line */
+      continue;
+    }
+    if (!section_matches) {
+      buffer[0] = '#'; /* trigger read next line */
+      continue;
+    }
+    if (sscanf(buffer,"%s %s",param,value) != 2) {
+      ++bad;
+      and_printf(0,"Configuration file line %i is invalid: %s\n",
+		 line, buffer);
+      memset(buffer,0,1024);
+      if (fgets(buffer,1022,f) == 0) break;
+      continue;
+    }
+    if (sscanf(value,"%i",&val) != 1) val = -1;
+    if (sscanf(value,"%u",&uval) != 1) uval = UINT_MAX;
+    if (strcmp(param,"defaultnice")==0) {
+	if (val > -1) /* Prohibits a default is kill policy */
+	and_config.nice_default = val;
+      else {
+	++bad;
+	and_printf(0,"Configuration file line %i has invalid value for defaultnice: %s.\n",
+		   line, value);
+      }
+    } else if (strcmp(param,"interval")==0) {
+      if (and_config.lock_interval) {
+	and_printf(0,"Configuration file line %i: interval locked by -i command-line option.\n",
+		   line);
+      } else {
+	if (uval < UINT_MAX)
+	  and_config.interval = uval;
+	else {
+	  ++bad;
+	  and_printf(0,"Configuration file line %i has invalid value for interval: %s.\n",
+		     line, value);
+	}
+      }
+    } else if (strcmp(param,"minuid")==0) {
+      if (uval < UINT_MAX)
+	and_config.min_uid = uval;
+      else {
+	++bad;
+	and_printf(0,"Configuration file line %i has invalid value for minuid: %s.\n",
+		   line, value);
+      }
+    } else if (strcmp(param,"mingid")==0) {
+      if (uval < UINT_MAX)
+	and_config.min_gid = uval;
+      else {
+	++bad;
+	and_printf(0,"Configuration file line %i has invalid value for mingid: %s.\n",
+		   line, value);
+      }
+    } else if (strcmp(param,"lv1time")==0) {
+      if (uval < UINT_MAX)
+	and_config.time_mark[0] = uval;
+      else {
+	++bad;
+	and_printf(0,"Configuration file line %i has invalid value for lv1time: %s.\n",
+		   line, value);
+      }
+    } else if (strcmp(param,"lv2time")==0) {
+      if (uval < UINT_MAX)
+	and_config.time_mark[1] = uval;
+      else {
+	++bad;
+	and_printf(0,"Configuration file line %i has invalid value for lv2time: %s.\n",
+		   line, value);
+      }
+    } else if (strcmp(param,"lv3time")==0) {
+      if (uval < UINT_MAX)
+	and_config.time_mark[2] = uval;
+      else {
+	++bad;
+	and_printf(0,"Configuration file line %i has invalid value for lv3time: %s.\n",
+		   line, value);
+      }
+    } else if (strcmp(param,"affinity")==0) {
+      bad_f = -1;
+      u = g = c = p = 0;
+      if (strlen(value) != 4) {
+	  and_printf(0,"Configuration file line %i has invalid affinity: %s.\n",
+		     line, value);
+        ++bad;
+      } else {
+        for (i=0; i<4; i++) {
+          switch(value[3-i]) {
+	  case 'u':
+	    if (!u) u = and_config.weight[PRI_U] = 1 << i;
+	    else bad_f = i;
+	    break;
+	  case 'g':
+	    if (!g) g = and_config.weight[PRI_G] = 1 << i;
+	    else bad_f = i;
+	    break;
+	  case 'c':
+	    if (!c) c = and_config.weight[PRI_C] = 1 << i;
+	    else bad_f = i;
+	    break;
+	  case 'p':
+	    if (!p) p = and_config.weight[PRI_P] = 1 << i;
+	    else bad_f = i;
+	    break;
+	  default:
+	    bad_f = 3-i;
+	  }
+        }
+        if (bad_f > -1) {
+          and_printf(0,"Configuration file line %i has invalid affinity: %s[%i]=%c.\n",
+                     line, value, bad_f, value[bad_f]);
+          ++bad;
+        } else {
+          strncpy(and_config.affinity,value,4);
+          and_config.affinity[4] = 0;
+        }
+      }
+    } else {
+      ++bad;
+      and_printf(0,"Configuration file line %i has invalid parameter: %s.\n",
+		 line, param);
+    }
+    memset(buffer,0,1024);
+    if (fgets(buffer,1022,f) == 0) break;
+  }
+  /* Cleanup, exit on errors. */
+  fclose(f);
+  if (and_config.verbose > 1) print_config();
+  if (bad) {
+    and_printf(0,"Configuration file contains %i bad lines. Aborting.\n",
+	       bad);
+    abort();
+  }
+}
+
+
+/* Compute new nice level for given command/uid/gid/utime */
+
+int and_getnice (int uid, int gid, char *command, struct and_procent *parent, unsigned cpu_seconds)
+{
+  int i, level, entry, exact = -1, last;
+  struct and_procent *par;
+  int exactness [PRI_MAXENTRIES];
+  if (!command) {
+    and_printf(0,"Process without command string encountered. Aborting.\n");
+    abort();
+  }
+  if (uid == 0) {
+    and_printf(3,"root is untouchable: %s\n", command);
+    return 0;
+  }
+  if (uid < and_config.min_uid) {
+    and_printf(3,"uid %i is untouchable: %s\n", uid, command);
+    return 0;
+  }
+  if (gid < and_config.min_gid) {
+    and_printf(3,"gid %i is untouchable: %s\n", gid, command);
+    return 0;
+  }
+  
+  /* Strategy: each priority database accumulates accuracy points
+     for every aspect: user, group, command, parent. An exact hit is 
+     worth the configured weight of the aspect (1, 2, 4, 8); a joker
+     is worth 0; and a miss is with -MAXINT, effectively eliminating
+     the entry (veto). At the end, the highest rated entry is
+      used to determine the new nice level. */
+  for (i=0; i<and_db.n; i++) {
+    /* user id */
+    if (uid == and_db.entry[i].uid) {
+      exactness[i] = and_config.weight[PRI_U];
+    } else if (and_db.entry[i].uid == -1) {
+      exactness[i] = 0;
+    } else {
+      exactness[i] = -MAXINT;
+    }
+    /* group id */
+    if (gid == and_db.entry[i].gid) {
+      exactness[i] += and_config.weight[PRI_G];
+    } else if (and_db.entry[i].gid == -1) {
+      exactness[i] += 0;
+    } else {
+      exactness[i] = -MAXINT;
+    }
+    /* command */
+    if (command!=NULL && regexec(and_db.entry[i].command,command,0,0,0) == 0) {
+      exactness[i] += and_config.weight[PRI_C];
+    } else if (strcmp(and_db.entry[i].command_str,"*") == 0) {
+      exactness[i] += 0;
+    } else {
+      exactness[i] = -MAXINT;
+    }
+    /* parent */
+    par = parent;
+    while (par != NULL)
+    {
+      last = (and_db.entry[i].parentmode == PARENT_ONLY || 
+              par->parent == NULL);
+      if (regexec(and_db.entry[i].parent,par->command,0,0,0) == 0) {
+        exactness[i] += and_config.weight[PRI_P];
+        break;
+      } else if (last && strcmp(and_db.entry[i].parent_str,"*") == 0) {
+        exactness[i] += 0;
+        break;
+      } else if (last) {
+        exactness[i] = -MAXINT;
+        break;
+      }
+      par = par->parent;
+    }
+  }
+  entry = 0;
+  exact = -1;
+  for (i=0; i<and_db.n; i++) {
+    if (exactness[i] >= exact) { 
+      /* >exact -> first entry wins, >=exact -> last entry wins */
+      entry = i;
+      exact = exactness[i];
+    }
+  }
+  if (exact < 0) {
+    and_printf(2,"no match for uid=%i gid=%i cmd=%s\n par=%s\n",
+               uid, gid, command, (parent!=NULL?parent->command:"(orphan)"));
+    return and_config.nice_default;
+  }
+  level = 2;
+  while (level >= 0 && and_config.time_mark[level] > cpu_seconds) {
+    --level;
+  }
+  and_printf(2,"command=%s (%i,%i,%s) hit on entry=%i, exactness=%i, level=%i.\n",
+             command, uid, gid, (parent!=NULL?parent->command:"(orphan)"), 
+             entry, exact, level);
+  return (level >= 0 ? and_db.entry[entry].nl[level] : 0);
+}
+
+
+
+/**********************************************************************
+
+ **********************************************************************/
+
+
+
+static struct and_procent *(*and_getfirst)() = NULL;
+static struct and_procent *(*and_getnext)() = NULL;
+
+
+void and_setprocreader (struct and_procent *(*getfirst)(), 
+			struct and_procent *(*getnext)())
+{
+  and_getfirst = getfirst;
+  and_getnext = getnext;
+}
+
+
+struct and_procent* and_find_proc (struct and_procent *head, int ppid)
+{
+  struct and_procent *current = head;
+  while (current != NULL)
+  {
+    if (current->pid == ppid)
+      return current;
+    current = current->next;
+  }
+  and_printf(1,"no parent for ppid: %d\n", ppid);
+  return NULL;
+}
+
+
+void and_loop ()
+{
+  struct and_procent *head, *current, *new, *proc;
+  int newnice;
+  int njobs = 0;
+  assert(and_getfirst != NULL);
+  assert(and_getnext != NULL);
+  head = NULL;
+  current = NULL;
+  proc = and_getfirst();
+  while (proc != NULL) {
+    new = (struct and_procent*)malloc(sizeof(struct and_procent));
+    memcpy(new,proc,sizeof(struct and_procent));
+    new->next = NULL;
+    if (current != NULL) {
+      current->next = new;
+    } else {
+      head = new;
+    }
+    current = new;
+    proc = and_getnext();
+  }
+  current = head;
+  while (current != NULL) {
+    if (current->pid != current->ppid)
+      current->parent = and_find_proc(head,current->ppid);
+    else
+      current->parent = NULL;
+    and_printf(2, "process %s parent : %s\n", current->command,
+             (current->parent != NULL ? current->parent->command : "(none)"));
+    current = current->next;
+  }
+  current = head;
+  while (current != NULL) {
+    njobs++;
+    newnice = and_getnice(current->uid,current->gid,current->command,
+                          current->parent,current->utime);
+    if (current->uid != 0) {
+      if (newnice) {
+	if (newnice > 0) {
+	  if (newnice > current->nice) {
+	    if (and_config.test)
+	      and_printf(0,"would renice to %i: %i (%s)\n",newnice,current->pid,
+			 current->command);
+	    else {
+	      and_printf(1,"renice to %i: %i (%s)\n",newnice,current->pid,
+			 current->command);
+	      setpriority(PRIO_PROCESS,current->pid,newnice);
+	    }
+	  }
+	} else {
+	  if (and_config.test)
+	    and_printf(0,"would kill %i %i (%s)\n",newnice,current->pid,
+		       current->command);
+	  else {
+	    and_printf(1,"kill %i %i (%s)\n",newnice,current->pid,
+                       current->command);
+	    kill(current->pid,-newnice);
+	  }
+	}
+      }
+    }
+    current = current->next;
+  }
+  current = head;
+  while (current != NULL) {
+    proc = current;
+    current = current->next;
+    free(proc);
+  }
+}
+
+
+void and_getopt (int argc, char** argv)
+{
+#define OPTIONS "c:d:i:vstxh"
+  int opt, value;
+  opt = getopt(argc,argv,OPTIONS);
+  while (opt != -1) {
+    switch(opt) {
+    case 'c':
+      and_config.config_file = (char*)malloc(strlen(optarg)+1);
+      assert(and_config.config_file);
+      strcpy(and_config.config_file,optarg);
+      break;
+    case 'd':
+      and_config.database_file = (char*)malloc(strlen(optarg)+1);
+      assert(and_config.database_file);
+      strcpy(and_config.database_file,optarg);
+      break;
+    case 'i':
+      value = atoi(optarg);
+      if (value > 0) {
+	and_config.lock_interval = true;
+	and_config.interval = value;
+      } else {
+	fprintf(stderr,"%s: illegal interval: %s\n",argv[0],optarg);
+	exit(1);
+      }
+      break;
+    case 's':
+      and_config.to_stdout = 1;
+      break;
+    case 'v':
+      ++and_config.verbose;
+      break;
+    case 't':
+      and_config.test = 1;
+      break;
+    case 'x':
+      and_config.test = 0;
+      break;
+    case 'h':
+      printf("auto nice daemon version %s (%s)\n"
+	     "%s [-v] [-s]  [-t] [-x] [-c configfile] [-d databasefile] [-i interval]\n"
+	     "-v: verbosity -v, -vv, -vvv etc\n"
+	     "-s: log to stdout (default is syslog, or debug.and)\n"
+	     "-x: really execute renices and kills (default)\n"
+	     "-t: test configuration (don't really renice)\n"
+	     "-i interval: loop interval in seconds (default %i)\n"
+	     "-c configfile: specify config file (default %s)\n"
+	     "-d databasefile: specify priority database file (default %s)\n"
+	     ,AND_VERSION,AND_DATE,argv[0],
+	     DEFAULT_INTERVAL, DEFAULT_CONFIG_FILE, DEFAULT_DATABASE_FILE);
+      exit(1);
+    default:
+      fprintf(stderr,"Try %s -h for help.\n", argv[0]);
+      exit(1);
+    }
+    opt = getopt(argc,argv,OPTIONS);
+  }
+#undef OPTIONS
+}
+
+
+static int g_reload_conf;
+
+
+void and_trigger_readconf (int sig)
+{
+  g_reload_conf = (sig == SIGHUP);
+}
+
+
+void and_readconf ()
+{
+  and_printf(0,"Re-reading configuration and priority database...\n");
+  read_config();
+  read_priorities();
+  g_reload_conf = 0;
+}
+
+
+void and_worker ()
+{
+  read_config();
+  read_priorities();
+  signal(SIGHUP,and_trigger_readconf);
+  and_printf(0,"AND ready.\n");
+  g_reload_conf = 0;
+  while (1) {
+    if (g_reload_conf) {
+      and_readconf();
+    }
+    and_loop();
+    sleep(and_config.interval);
+  }
+}
+
+
+int and_main (int argc, char** argv)
+{
+  set_defaults(argc,argv);
+  and_getopt(argc,argv);
+  if (and_config.test) {
+    and_worker();
+  } else {
+    if (fork() == 0) and_worker();
+  }
+  return 0;
+}
+
diff --git a/sensors/and/and.conf b/sensors/and/and.conf
new file mode 100644
index 0000000000000000000000000000000000000000..e8e38e61e8133e9e6e0372dd2402287bb1c3964b
--- /dev/null
+++ b/sensors/and/and.conf
@@ -0,0 +1,61 @@
+#
+# Sample configuration file for the auto nice daemon, /etc/and.conf
+#
+# Comments must have the # in the *first* column!
+#
+# Read and.conf(5) for details.
+#
+# 1999, 2000, 2004 Patrick Schemitz, schemitz@users.sourceforge.net
+# 
+
+#
+# Nice level for jobs that are not in and.priorities.
+# 0 = do not renice.
+#
+defaultnice 0
+
+#
+# Time interval between renice cycles, in seconds. Default is
+# 60 seconds.
+#
+interval 60
+
+#
+# Ranges for the nice levels. Jobs with less than lv1time seconds
+# CPU time are not reniced; jobs between lv1time and lv2time seconds
+# are reniced to the first level in an.priorities; jobs between
+# lv2time and lv3time seconds to the second level; jobs with more
+# than lv3time seconds are reniced to the third level.
+#
+lv1time 120
+lv2time 1200
+lv3time 3600
+
+#
+# Hosts molasses, snail, and snore are pretty slow, so be gentle when
+# renicing, since a CPU minute isn't really very much computations here.
+#
+#on (molasses|snail|snore)
+#lv1time 300
+#lv2time 1800
+#lv3time 3600
+#on .*
+
+#
+# Strategy for picking the right priority entry for a user/group/job
+# triple. The strategy is a permutation of "cgu", "c"ommand, "g"roup,
+# "u"ser. The order specifies the affinity of the priority lookup
+# method. "cug" means an exact match of the command has priority
+# over an exact match of the user or group. See the documentation
+# for more details.
+#
+affinity cpug
+
+#
+# Minimum user/group id to be even considered for renicing. Processes
+# with lower user/group id are ignored. This does not affect root
+# (user id 0), which is never, ever reniced.
+#
+minuid 1
+mingid 1
+
diff --git a/sensors/and/and.conf.5.man b/sensors/and/and.conf.5.man
new file mode 100644
index 0000000000000000000000000000000000000000..ac575734888f8cf4751c7786651fe2d6af6b2c9a
--- /dev/null
+++ b/sensors/and/and.conf.5.man
@@ -0,0 +1,241 @@
+.TH AND.CONF 5 "__DATE__" "Unix" "File Formats"
+
+.SH "NAME"
+/etc/and.conf \- general configuration parameters for the
+auto nice daemon.
+
+
+.SH "VERSION"
+This manual page documents and.conf for
+.B and
+version __VERSION__.
+
+
+.SH "DESCRIPTION"
+This is the general configuration file for
+.B and.
+It stores settings like the default nice level, the renice intervals,
+the three stages of renicing, and the affinity of the priority database,
+i.e. the weight of (user, group, command) when resolving nice levels
+from the database. These settings are described below.
+
+Comments start with a # in the
+.B first column.
+Empty lines are ignored. Unlike with other configuration files, lines
+.B cannot be concatenated
+with a backslash. Furthermore, this file is
+.B case sensitive.
+
+.B and
+allows for host-specific sections in the configuration file. These work
+as lines of the form
+.I on somehost
+and work as follows: the parser determines if the host name (as returned
+by gethostname) matches the extended regular expression that follows the
+.I on
+keyword. If it does, it just keeps processing the file as if nothing had
+happened. If it does not match, however, everything up to the next
+.I on
+keyword is skipped. So if you want to end a host-specific section, you
+must write
+.I on .*
+(which matches all hosts) to switch back to normal.
+
+Don't forget to
+.B kill -HUP
+the auto nice daemon to enable the changes.
+
+
+.SH "SETTINGS"
+
+.TP 0.5i
+.B defaultnice
+The default nice level. A number between 0 and 19. Jobs for which no
+entry can be found in
+.I /etc/and.priorities
+are reniced to this level, regardless of the CPU time they've used
+so far. If you prefer to renice unknown jobs gradually, you can do
+so by supplying three asterisks as (user, group, command) tuple in
+.I /etc/and.priorities.
+The default nice level is
+.I 0
+
+.TP 0.5i
+.B interval
+The default interval between nice checks of the auto nice daemon,
+in seconds. This value can be overridden by the
+.I -i
+command-line option of
+.B and.
+The default interval is
+.I 60
+seconds.
+
+.TP 0.5i
+.B lv1time
+.TP 0.5i
+.B lv2time
+.TP 0.5i
+.B lv3time
+Ranges for the nice levels. Jobs with less than lv1time seconds
+CPU time are not reniced; jobs between lv1time and lv2time seconds
+are reniced to the first level in an.priorities; jobs between
+lv2time and lv3time seconds to the second level; jobs with more
+than lv3time seconds are reniced to the third level.
+Defaults are
+.I 120
+,
+.I 1200
+, and
+.I 3600
+seconds.
+
+.TP 0.5i
+.B minuid, mingid
+Minimum user id and group id to be considered for renicing. 
+Processes whose user id is below 
+.I minuid
+are left alone, as are processes with a group id of below 
+.I mingid.
+(Note that even if you set minuid to zero, root processes are
+left alone.)
+
+.TP 0.5i
+.B affinity
+Strategy for picking the right priority entry for a user/group/job
+triple. The strategy is a permutation of "cgu", "c"ommand, "g"roup,
+"u"ser. The order specifies the affinity of the priority lookup
+method. Suppose you have an entry for all jobs of user
+.I foo,
+another entry for all jobs of group
+.I bar,
+and yet another entry for the command
+.I baz.
+Furthermore suppose user
+.I foo
+(who happens to belong to group
+.I bar
+) starts a job named
+.I baz
+-- which entry should be chosen? This is what the affinity setting
+means, for example "cug" means an exact match of the command has priority
+over both an exact match of the user and the group. The default affinity is
+"cug", which is probably sensible for most cases, since it's the job
+which takes up CPU time, not the user or group ID.
+
+
+.SH "EXAMPLES"
+
+.TP 0.5i
+.B Default Configuration
+# This is the default configuration:
+.br
+default 0
+.br
+interval 60
+.br
+lv1time 300
+.br
+lv2time 1800
+.br
+lv3time 3600
+.br
+affinity cug
+.br
+minuid 0
+.br
+mingid 0
+.br
+
+.TP 0.5i
+.B Default Configuration, with terminals
+# Normal default configuration for all
+.br
+default 0
+.br
+interval 60
+.br
+lv1time 300
+.br
+lv2time 1800
+.br
+lv3time 3600
+.br
+# Hosts foo, bar, baz are terminals and must
+.br
+# be more responsive, so earlier renice.
+.br
+on (foo|bar)
+.br
+lv1time 120
+.br
+lv2time 600
+.br
+lv3time 1200
+.br
+on .*
+.br
+# This is for all hosts again
+.br
+affinity cug
+.br
+
+.TP 0.5i
+.B Group-specific Hosts
+.br
+default 0
+.br
+interval 60
+.br
+lv1time 300
+.br
+lv2time 1800
+.br
+lv3time 3600
+.br
+# Normal affinity for all hosts.
+.br
+affinity cug
+.br
+# Hosts bar, baz belong to group foo, which
+.br
+# is privilegued on these hosts, so override
+.br
+# affinity. (Note regexp!)
+.br
+on ba[rz]
+.br
+affinity guc
+.br
+on .*
+.br
+minuid 500
+.br
+mingid 100
+.br
+
+
+.SH "FILES"
+
+.TP 0.5i
+.B  /etc/and.conf
+General configuration file. Stores default nice level, default interval,
+the "time zones" and the database lookup affinity. This is what this
+manual page is about.
+
+
+.SH "SEE ALSO"
+.BR and (8),
+.BR and.priorities (5),
+.BR kill (1),
+.BR regex (7),
+.BR renice (8)
+
+
+.SH "INTERNET"
+.B http://and.sourceforge.net/
+
+
+.SH "AUTHOR"
+The auto nice daemon and this manual page were written by
+Patrick Schemitz <schemitz@users.sourceforge.net>
diff --git a/sensors/and/and.h b/sensors/and/and.h
new file mode 100644
index 0000000000000000000000000000000000000000..7b1108f462cb0bb9db385eadae7101f2dc85b8ce
--- /dev/null
+++ b/sensors/and/and.h
@@ -0,0 +1,93 @@
+/*
+
+    AND auto nice daemon - renice programs according to their CPU usage.
+    Copyright (C) 1999-2004 Patrick Schemitz <schemitz@users.sourceforge.net>
+    http://and.sourceforge.net/
+
+    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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+*/
+
+#ifndef AND_H
+#define AND_H
+
+
+/************************************************************************
+ *                                                                      *
+ * and.h -- AND library for platform-independent code.                  *
+ *                                                                      *
+ * 1999, 2004 Patrick Schemitz <schemitz@users.sourceforge.net>         *
+ * http://and.sourceforge.net/                                          *
+ *                                                                      *
+ ***********************************************************************/
+
+
+/*
+ * and_procent -- process entry.
+ *
+ * AND-relevant information on a process.
+ */
+struct and_procent {
+  /* to be filled by and-$OS.c: */
+  int pid;
+  int ppid;
+  int uid;
+  int gid;
+  int nice;
+  unsigned utime;
+  char command [1024];
+  /* to be filled by and.c: */
+  struct and_procent *parent; 
+  struct and_procent *next;
+};
+
+
+/*
+ * and_printf() - log message.
+ *
+ * Logs a message (in printf() format), either to stderr, or to syslog(),
+ * depending on AND operational mode. In test mode (and -t), stderr is
+ * used; syslog() otherwise. Use this to report any O/S-specific problems.
+ * Log is suppressed if the current verbosity level is below the required
+ * one.
+ */
+void and_printf (int required_verbosity, char *fmt, ...);
+
+
+/*
+ * and_setprocreader() -- set O/S specific handler for reading processes.
+ *
+ * getfirst and getnext are two functions returning a pointer to an
+ * and_procent, or NULL if no more processes are available. The implementation
+ * of these two functions are O/S specific. For Linux, reading through the
+ * /proc filesystem is most suitable. See and-linux.c for a sample
+ * implementation.
+ *
+ * Note: it is getfirst's task to also clean up any remainders of former
+ * calls to getfirst and getnext, such as open DIR*.
+ */
+void and_setprocreader (struct and_procent *(*getfirst)(),
+			struct and_procent *(*getnext)());
+
+
+/*
+ * and_main() -- start the AND.
+ *
+ * Takes over control. Call this after setting the and_procreader().
+ */
+int and_main (int argc, char** argv);
+
+
+#endif
diff --git a/sensors/and/and.init.debian b/sensors/and/and.init.debian
new file mode 100644
index 0000000000000000000000000000000000000000..c09deee5ff411fd2894201f39ea674bedea08713
--- /dev/null
+++ b/sensors/and/and.init.debian
@@ -0,0 +1,55 @@
+#! /bin/sh
+#
+# and      Launch auto nice daemon
+#
+# Written by Miquel van Smoorenburg <miquels@cistron.nl>.
+# Modified for Debian GNU/Linux	by Ian Murdock <imurdock@gnu.ai.mit.edu>.
+# Modified for and by Andras Bali <bali@debian.org>
+#
+
+PATH=/sbin:/bin:/usr/sbin:/usr/bin
+DAEMON=/usr/sbin/and
+NAME=and
+DESC="auto nice daemon"
+
+test -f $DAEMON || exit 0
+
+set -e
+
+case "$1" in
+  start)
+	echo -n "Starting $DESC: "
+	start-stop-daemon --start --quiet --background --nicelevel -19 \
+		--make-pidfile --pidfile /var/run/$NAME.pid \
+		--exec $DAEMON >/dev/null 2>&1
+	echo "$NAME."
+	;;
+  stop)
+	echo -n "Stopping $DESC: "
+	start-stop-daemon --stop --quiet --pidfile /var/run/$NAME.pid \
+			  --exec $DAEMON && rm -f /var/run/$NAME.pid
+	echo "$NAME."
+	;;
+  reload|force-reload)
+	echo "Reloading $DESC configuration files."
+	start-stop-daemon --stop --signal 1 --quiet --pidfile \
+		/var/run/$NAME.pid --exec $DAEMON >/dev/null 2>&1
+	;;
+  restart)
+	echo -n "Restarting $DESC: "
+	start-stop-daemon --stop --quiet --pidfile /var/run/$NAME.pid \
+			  --exec $DAEMON && rm -f /var/run/$NAME.pid
+	sleep 1
+	start-stop-daemon --start --quiet --background --nicelevel -19 \
+		--make-pidfile --pidfile /var/run/$NAME.pid \
+		--exec $DAEMON >/dev/null 2>&1
+	echo "$NAME."
+	;;
+  *)
+	N=/etc/init.d/$NAME
+	echo "Usage: $N {start|stop|restart|reload|force-reload}" >&2
+	exit 1
+	;;
+esac
+
+exit 0
diff --git a/sensors/and/and.priorities b/sensors/and/and.priorities
new file mode 100644
index 0000000000000000000000000000000000000000..7724e84d29f5554d83091e2a12800e9eaf6fad26
--- /dev/null
+++ b/sensors/and/and.priorities
@@ -0,0 +1,108 @@
+#
+# Sample priority database for the auto-nice daemon, /etc/and.priorities
+#
+# Comments must have the # in the _first_ column!
+#
+# File format:
+#    user group job parent nice1 nice2 nice3
+# - user: user name or user id or * for all
+# - group: group name or group id or * for all
+# - job: executable (without path; may be a regexp) or * for all
+# - parent: keyword "parent=" or "ancestor=" followed by the 
+#   executable (without path; may be a regexp), or * for all
+# - nice1, nice2, nice3: nice levels for CPU usage ranges.
+#
+# At least one of user or group must be an asterisk *.
+#
+# After /etc/and.conf:lv1time seconds matching jobs are niced to nice1,
+# after /etc/and.conf:lv2time to nice2 and after /etc/and.conf:lv3time
+# to nice3.
+#
+# Read and.priorities(5) for details.
+#
+# 1999, 2000, 2004 Patrick Schemitz, schemitz@users.sourceforge.net
+#
+
+#
+# Philosophy:
+#
+# Hold down notorious troublemakers (Netscape, colourful screensavers, ...)
+# and leave other jobs alone. (Within reason, that is.)
+# Note that a perceptive user might rename his jobs' executables to
+# obtain higher privilegue. So the values must be sensible to that.
+# For instance, noone with his mind right would rename his computation-
+# intensive job to "gcc" to avoid renicing after two minutes, since
+# gcc is reniced to 19 after just another 18 minutes...
+#
+
+#
+# Default entry -- moderate renicing, priority always above screen savers.
+#
+*	*	*       *	4	8	12
+
+#
+# Jobs started by the Grid master process always run on 10. If someone
+# else besides User grid starts a (fake, presumably) Grid master, kill it
+# at once: it's a fraud! The real Grid master, of course, is left alone.
+#
+#*       *       *       ancestor=grid_nanny      10      10      10	
+#*       *       grid_nanny      *       -9      -9      -9
+#grid    *       grid_nanny      *       0       0       0
+
+#
+# Jobs of the local user are treated more nicely. The local user is
+# identified by the fact that her programs are started by the login
+# screen, kdm or xdm in this case.
+#
+*       *       *       ancestor=[xk]dm   2       2       2
+
+#
+# The hosts bar and baz are reserved for the foo group, so
+# prefer them over other groups.
+#
+#on (bar|baz)
+#*	foo	*       *	4	8	12
+#*	*	*	*	12	16	18
+#on .*
+
+#
+# Our special friend, user dau, tends to thresh machines with long-
+# running unniced jobs... we do not appreciate this behaviour. A little
+# punishment might be in order.
+#
+#dau	*	*	*	12	16	18
+
+#
+# Netscape -- more than 20 minutes probably means it's running berserk,
+# so we just kill it off.
+#
+*	*	.*netscape.*	*       2	-9	-9
+
+#
+# Compilers -- don't renice them the first 20 minutes, but then...
+# After an hour of compilation for one single source file, there
+# *is* something wrong.
+# ld and make shouldn't use more than 2 minutes themselves, so we
+# just leave them to the default.
+#
+*	*	gcc	*	0	19	-9
+*	*	g++	*	0	19	-9
+*	*	g77	*	0	19	-9
+*	*	cc1	*	0	19	-9
+
+#
+# Screen savers -- low priority from the beginning, but enough to log in.
+# KDE screen savers all end with .kss.
+#
+*	*	xlock.*	        *	15	15	15
+*	*	.*\.kss	        *	15	15	15
+
+#
+# System monitors -- don't monitor the system useless.
+#
+*	*	.*top	        *	15	15	15
+*	*	.*xosview.*     *	15	15	15
+*	*	.*xps	        *	15	15	15
+*	*	.*qps   	*	15	15	15
+*	*	.*ktop		*       15	15	15
+*	*	.*gtop		*       15	15	15
diff --git a/sensors/and/and.priorities.5.man b/sensors/and/and.priorities.5.man
new file mode 100644
index 0000000000000000000000000000000000000000..c3fd799e23b67d66ea394da356cf68e33b286f93
--- /dev/null
+++ b/sensors/and/and.priorities.5.man
@@ -0,0 +1,209 @@
+.TH AND.PRIORITIES 5 "__DATE__" "Unix" "File Formats"
+
+.SH "NAME"
+/etc/and.priorities \- priority database for the auto nice daemon.
+
+
+.SH "VERSION"
+This manual page documents and.priorities for
+.B and
+version __VERSION__.
+
+
+.SH "DESCRIPTION"
+This is the priority database file for
+.B and.
+It stores (user, group, command, parent, nicelevels) tuples (hereafter called
+entries) to determine the new nice level (or the kill signal, for that
+matter) when a job reaches one of the time limits defined in
+.I /etc/and.conf.
+(See lv1time, lv2time, and lv3time on the and.conf manual page for
+details.) See the
+.B affinity
+setting in 
+.I /etc/and.conf
+for how ambiguities between the fields (user, group, command, parent) 
+are dealt with when searching the database to determine the new nice 
+level for a job.
+Note that if more than one entry matches with the same accuracy (e.g.
+with a parent= entry and an ancestor= entry), the 
+.B last entry wins!
+
+Comments start with a # in the
+.B first column.
+Empty lines are ignored. Unlike with other configuration files, lines
+.B cannot be concatenated
+with a backslash. Furthermore, this file is
+.B case sensitive.
+
+.B and
+allows for host-specific sections in the configuration file. These work
+as lines of the form 
+.I on somehost
+and work as follows: the parser determines if the host name (as returned
+by gethostname) matches the extended regular expression that follows the
+.I on
+keyword. If it does, it just keeps processing the file as if nothing had
+happened. If it does not match, however, everything up to the next
+.I on
+keyword is skipped. So if you want to end a host-specific section, you
+must write 
+.I on .*
+(which matches all hosts) to switch back to normal.
+
+Don't forget to
+.B kill -HUP
+the auto nice daemon to enable the changes.
+
+
+.SH "SETTINGS"
+
+A valid entry consists of a line of six columns, separated by one or
+more spaces. These columns are: (in that order)
+
+.TP 0.5i
+.B user
+The user ID the command is running under. May be a user name (which will
+be looked up in the password file and, if enabled, via NIS), or a numeric
+user ID, or an asterisk for any user.
+
+.TP 0.5i
+.B group
+The group ID the command is running under. May be a group name (which will
+be looked up in the group file and again, if enabled, via NIS), or a numeric
+group ID, or an asterisk for any group.
+
+.TP 0.5i
+.B command
+The name of the command, without path. May be a command, a regular
+expression to match multiple commands, or an asterisk for any command.
+Note that "foobar" will
+.B not
+match "/usr/bin/foobar" - you probably mean ".*foobar" or even ".*foobar.*".
+
+.TP 0.5i
+.B parent
+There are two modes of operation for the parent field, determined by a
+keyword:
+.B parent=foobar
+will match if a process' direct parent process matches the command or regular
+expression after the equal sign, whereas
+.B ancestor=foobar
+will match if 
+.I any 
+ancestor process matches. After the keyword and the equal sign goes the 
+name of the parent process, without path. May be a command, a regular
+expression to match multiple commands, or an asterisk for any command.
+(You can just use the asterisk if you want to ignore parents for this
+entry.) Note that again "foobar" will
+.B not
+match "/usr/bin/foobar", as with command.
+
+.TP 0.5i
+.B nicelevel 1
+The nice level after lv1time CPU time was used by the command. Positive
+numbers and 0 are interpreted as nice levels; negative numbers are
+interpreted as signals to be sent to the command. A "nice level" of
+19 will almost stop the job, -9 will actually kill it. (Like in kill -9.)
+lv1time can be set in
+.I /etc/and.conf
+
+.TP 0.5i
+.B nicelevel 2
+Same but after lv2time.
+
+.TP 0.5i
+.B nicelevel 3
+Same but after lv3time.
+
+
+.SH "EXAMPLES"
+
+Here are some entries from the real world (i.e. from "my" cluster
+at the Institute). As lv[123]time, 5 min., 20 min., and 1 hour is
+assumed. (Which is the default. See
+.I /etc/and.conf
+for details.) You might also check the default priority database
+that comes with
+.B and.
+
+
+# A finer default nice level
+.br
+* * * * 4 8 12
+.br
+
+# User dau is an idiot, so treat him like accordingly
+.br
+dau * * * 19 19 19
+.br
+
+# Netscape sometimes goes berserk, we must stop it
+.br
+* * netscape * 4 -9 -9
+.br
+
+# Most hosts are free for everyone but some are
+.br
+# especially for the FOO group
+.br
+* * * * 4 8 12
+.br
+on (bar|baz)
+.br
+* * * * 8 12 16
+.br
+# ... or, more radical: * * * * -9 -9 -9
+.br
+* foo * * 4 8 12
+.br
+on .*
+.br
+
+# KDE screen savers...
+.br
+* * .*kss * 16 16 16
+.br
+
+# Grid jobs (assuming they are started by a master
+.br
+# process)
+.br
+* * * ancestor=grid_master 10 10 10
+.br
+# Now some clever yet deceitful user might start all
+.br
+# his jobs using a shell script named grid_master.
+.br
+# He shall regret... whereas the original grid_master
+.br
+# (owned by grid) is left alone.
+.br
+* * grid_master * -9 -9 -9
+.br
+grid * grid_master * 0 0 0
+.br
+
+.SH "FILES"
+
+.TP 0.5i
+.B  /etc/and.priorities
+The priority database (in plain text). Contains the (user, group, command,
+nicelevels) tuples. This is what this manual page is about.
+
+
+.SH "SEE ALSO"
+.BR and (8),
+.BR and.conf (5),
+.BR kill (1),
+.BR regex (7),
+.BR renice (8)
+
+
+.SH "INTERNET"
+.B http://and.sourceforge.net/
+
+
+.SH "AUTHOR"
+The auto nice daemon and this manual page were written by
+Patrick Schemitz <schemitz@users.sourceforge.net>
diff --git a/sensors/and/and.spec b/sensors/and/and.spec
new file mode 100644
index 0000000000000000000000000000000000000000..20123e5f6e39e3338980a1c900d1992c9aece109
--- /dev/null
+++ b/sensors/and/and.spec
@@ -0,0 +1,64 @@
+Name:      and
+Version:   1.2.0
+Release:   1
+Summary:   Auto nice daemon
+Vendor:    Patrick Schemitz <schemitz@users.sourceforge.net>
+Copyright: GPL
+Group:     Daemons
+Buildroot: /var/tmp/%{name}-buildroot
+Source:    http://and.sourceforge.net/%{name}-%{version}.tar.gz
+URL:       http://and.sourceforge.net
+Prefix:    %{_prefix}
+ExclusiveOS: linux
+
+%description
+The auto nice daemon renices and even kills jobs according to their CPU time,
+owner, and command name. This is especially useful on production machines with
+lots of concurrent CPU-intensive jobs and users that tend to forget to
+nice their jobs.
+
+%prep            
+rm -rf %{buildroot}
+%setup -q
+make PREFIX=%{_prefix} \
+     INSTALL_ETC=/etc \
+     INSTALL_INITD= \
+     INSTALL_SBIN=%{_sbindir} \
+     INSTALL_MAN=%{_mandir}
+
+%install
+mkdir -p %{buildroot}/etc
+mkdir -p %{buildroot}$initddir
+mkdir -p %{buildroot}%{_sbindir}
+mkdir -p %{buildroot}%{_mandir}/man8
+mkdir -p %{buildroot}%{_mandir}/man5
+make PREFIX=%{buildroot}%{_prefix} \
+     INSTALL_ETC=%{buildroot}/etc \
+     INSTALL_INITD= \
+     INSTALL_SBIN=%{buildroot}%{_sbindir} \
+     INSTALL_MAN=%{buildroot}%{_mandir} install 
+
+%clean
+rm -rf %{buildroot}
+
+%pre
+
+%post
+initddir=`%{_sbindir}/and-find-init.d`
+ln -sf %{_sbindir}/and.init $initddir/and
+/sbin/chkconfig --add and
+
+%preun
+%{_sbindir}/and.init stop > /dev/null 2>&1 
+/sbin/chkconfig --del and
+initddir=`%{_sbindir}/and-find-init.d`
+rm -f $initddir/and
+
+%postun
+
+%files
+%defattr(-,root,root)
+%doc README LICENSE CHANGELOG
+%config(noreplace)  /etc/and.*
+%{_sbindir}/*
+%{_mandir}/*/*
diff --git a/sensors/and/and.startup b/sensors/and/and.startup
new file mode 100644
index 0000000000000000000000000000000000000000..ea4d968b51ee35e2543dea22f03dad8973748ac2
--- /dev/null
+++ b/sensors/and/and.startup
@@ -0,0 +1,57 @@
+#!/bin/sh
+#
+# /etc/rc.d/init.d/and, /sbin/init.d/and, /etc/init.d/and
+#
+# SysV init.d compliant startup script for auto nice daemon.
+#
+# 1999, 2000, 2001 Patrick Schemitz <schemitz@users.sourceforge.net>
+# http://and.sourceforge.net/
+# 
+# chkconfig: 2345 90 10
+# description: automatically renice and kill jobs.
+#
+# processname: and
+# config: /etc/and.conf
+#
+
+AND_FLAGS=""
+test -r /etc/rc.config && . /etc/rc.config
+
+case "$1" in
+    start)
+	echo -n "Starting auto nice daemon:"
+	INSTALL_SBIN/and $AND_FLAGS >&/dev/null
+	ps axuw | grep -v grep | grep INSTALL_SBIN/and >/dev/null
+	if [ $? = 0 ]; then
+	    echo " done"
+	    exit 0
+	else
+	    echo " failed"
+	    exit 1
+	fi
+	;;
+    stop)
+	echo -n "Shutting down auto nice daemon:"
+        uname | grep OSF1 >/dev/null || killall INSTALL_SBIN/and
+	echo " done"
+	exit 0
+	;;
+    restart)
+	$0 stop  &&  $0 start
+	exit 0
+	;;
+    status)
+	echo -n "Checking for auto nice daemon: "
+	ps axuw | grep -v grep | grep INSTALL_SBIN/and >/dev/null
+	if [ $? = 0 ]; then
+	    echo "running"
+	    exit 0
+	else
+	    echo "no process"
+	    exit 1
+	fi
+	;;
+    *)
+	echo "Usage: $0 {start|stop|status|restart}"
+	exit 1
+esac