Author SHA1 Message Date
William Ferrell 6da7c51d22 Initial commit to create branch. 2016-07-22 07:12:29 -04:00
517 changed files with 2 additions and 125144 deletions
-17
View File
@@ -1,17 +0,0 @@
# Auto detect text files and perform LF normalization
* text=auto
# Custom for Visual Studio
*.cs diff=csharp
# Standard to msysgit
*.doc diff=astextplain
*.DOC diff=astextplain
*.docx diff=astextplain
*.DOCX diff=astextplain
*.dot diff=astextplain
*.DOT diff=astextplain
*.pdf diff=astextplain
*.PDF diff=astextplain
*.rtf diff=astextplain
*.RTF diff=astextplain
-235
View File
@@ -1,235 +0,0 @@
#################
## Eclipse
#################
*.pydevproject
.project
.metadata
bin/
tmp/
*.tmp
*.bak
*.swp
*~.nib
local.properties
.classpath
.settings/
.loadpath
# External tool builders
.externalToolBuilders/
# Locally stored "Eclipse launch configurations"
*.launch
# CDT-specific
.cproject
# PDT-specific
.buildpath
#################
## Visual Studio
#################
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
# User-specific files
*.suo
*.user
*.sln.docstates
# Build results
[Dd]ebug/
[Rr]elease/
x64/
build/
[Bb]in/
[Oo]bj/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
*_i.c
*_p.c
*.ilk
*.meta
*.obj
*.pch
*.pdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.log
*.scc
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opensdf
*.sdf
*.cachefile
# Visual Studio profiler
*.psess
*.vsp
*.vspx
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# NCrunch
*.ncrunch*
.*crunch*.local.xml
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.Publish.xml
*.pubxml
*.publishproj
# NuGet Packages Directory
## TODO: If you have NuGet Package Restore enabled, uncomment the next line
#packages/
# Windows Azure Build Output
csx
*.build.csdef
# Windows Store app package directory
AppPackages/
# Others
sql/
*.Cache
ClientBin/
[Ss]tyle[Cc]op.*
~$*
*~
*.dbmdl
*.[Pp]ublish.xml
*.pfx
*.publishsettings
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file to a newer
# Visual Studio version. Backup files are not needed, because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
# SQL Server files
App_Data/*.mdf
App_Data/*.ldf
#############
## Windows detritus
#############
# Windows image file caches
Thumbs.db
ehthumbs.db
# Folder config file
Desktop.ini
# Recycle Bin used on file shares
$RECYCLE.BIN/
# Mac crap
.DS_Store
#############
## Python
#############
*.py[cod]
# Packages
*.egg
*.egg-info
dist/
build/
eggs/
parts/
var/
sdist/
develop-eggs/
.installed.cfg
# Installer logs
pip-log.txt
# Unit test / coverage reports
.coverage
.tox
#Translations
*.mo
#Mr Developer
.mr.developer.cfg
Makefile
Makefile.in
aclocal.m4
autom4te.cache
compile
config.guess
config.h
config.h.in
config.log
config.status
config.sub
configure
depcomp
install-sh
missing
mkinstalldirs
stamp-h1
tags
-33
View File
@@ -1,33 +0,0 @@
Hey, thanks for reading this first! :)
*** NOTICE ****************************************************
This is a development version of LCDproc, straight from the Git
repository.
THIS VERSION OF LCDproc IS *NOT* GUARANTEED TO RUN, OR EVEN
COMPILE! YOU'VE BEEN WARNED!
***************************************************************
With that out of the way, welcome to the bleeding edge of LCDproc.
To build and run this version, you'll need autoconf 2.59 or higher
and friends installed.
Run:
$ sh ./autogen.sh
This produces the configure script and supporting files. Once the above
command has run, the rest is pretty standard:
$ ./configure --help
[read about the options, figure out what to use]
$ ./configure --prefix=/usr/local --enable-drivers=curses,CFontz
[replace curses,CFontz with comma-separated list of drivers you want]
$ make
$ su
$ make install
[make install is OPTIONAL ... might not want to replace a stable
version of LCDproc with a development release]
Patches and suggestions are welcome! Join the mailing list to get
started. See http://lcdproc.org/ for more information.
-24
View File
@@ -1,24 +0,0 @@
Known Bugs:
--------------
V0.5dev:
- If vBars are used together with ICON_BLOCK_FILLED on the same screen and
that icon is implemented as a custom char, it sometimes is replaced with
a non full block from the vBar. Affected drivers: IOWarrior, CwLinux
- On Solaris the mtc_s16209x driver fails to compile. Configure LCDproc to
exclude this driver.
- The lcdproc client currently ignores errors from the machine dependent
functions. This may result in strange behaviour of the screens or core
dumps.
Bugs in previous versions (not checked if the still exist):
-----------------------------------------------------------
- A client may cause the connection to LCDd to break or even crash
LCDd by not reading the replies from LCDd
See one of the example clients (clients/examples) for details.
- MtxOrb driver
- "lcdproc K" does not display properly in between digit.
- The server tends to crash if the joystick driver is the last one loaded.
Specifically, if the "E" key is pressed...
-52
View File
@@ -1,52 +0,0 @@
# Code of Merit
1. The project creators, lead developers, core team, constitute
the managing members of the project and have final say in every decision
of the project, technical or otherwise, including overruling previous decisions.
There are no limitations to this decisional power.
2. Contributions are an expected result of your membership on the project.
Don't expect others to do your work or help you with your work forever.
3. All members have the same opportunities to seek any challenge they want
within the project.
4. Authority or position in the project will be proportional
to the accrued contribution. Seniority must be earned.
5. Software is evolutive: the better implementations must supersede lesser
implementations. Technical advantage is the primary evaluation metric.
6. This is a space for technical prowess; topics outside of the project
will not be tolerated.
7. Non technical conflicts will be discussed in a separate space. Disruption
of the project will not be allowed.
8. Individual characteristics, including but not limited to,
body, sex, sexual preference, race, language, religion, nationality,
or political preferences are irrelevant in the scope of the project and
will not be taken into account concerning your value or that of your contribution
to the project.
9. Discuss or debate the idea, not the person.
10. There is no room for ambiguity: Ambiguity will be met with questioning;
further ambiguity will be met with silence. It is the responsibility
of the originator to provide requested context.
11. If something is illegal outside the scope of the project, it is illegal
in the scope of the project. This Code of Merit does not take precedence over
governing law.
12. This Code of Merit governs the technical procedures of the project not the
activities outside of it.
13. Participation on the project equates to agreement of this Code of Merit.
14. No objectives beyond the stated objectives of this project are relevant
to the project. Any intent to deviate the project from its original purpose
of existence will constitute grounds for remedial action which may include
expulsion from the project.
This document is the Code of Merit (http://code-of-merit.org), version 1.0.
-339
View File
@@ -1,339 +0,0 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
675 Mass Ave, Cambridge, MA 02139, 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) 19yy <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., 675 Mass Ave, Cambridge, MA 02139, 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) 19yy 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.
-300
View File
@@ -1,300 +0,0 @@
-- REALLY-QUICK START --------------------------------------------------
If you're in a desperate hurry type:
./configure --enable-drivers=all
make
And if you start wondering why it doesn't work, come back and read the
rest of the file. 8)
-- PREREQUISITES -----------------------------------------------------
First read the README if you haven't already.
Please take a few minutes to read the user guide located at
http://lcdproc.sourceforge.net/docs/
For the details on supported platforms, see the PLATFORM SPECIFIC section
of this file.
In order to compile LCDproc, you'll need the following programs:
* A C compiler which supports C99, we recommend GCC. Most Linux or BSD systems
come with GCC.
* GNU Make. It is available for all major distributions. If you want to
compile it yourself, see http://www.gnu.org/software/make/make.html .
* The GNU autotools, that is automake and autoconf. They are only required
if you want to build LCdproc directory from CVS.
The GNU autotools are available for all major distributions. If you want
to compile them yourself, see
http://www.gnu.org/software/autoconf/ and
http://www.gnu.org/software/automake/.
Depending on the ./configure options and your choice of drivers, you will
need some additional programs or libraries installed:
* DocBook XML converter "xmlto" if you want to create the documentation
or Doxygen when used with --enable-doxygen, also see
http://cyberelk.net/tim/software/xmlto/ and
http://www.stack.nl/~dimitri/doxygen/
* libusb if you --enable-libusb, see http://libusb.sourceforge.net/
* G15daemon, libg15 and libg15render (>= 1.1.1) for use with the 'g15' driver,
see http://www.g15tools.com/
* GraphLCD and GLCDprocDriver for use with the 'glcdlib' driver, see
http://projects.vdr-developer.org/projects/graphlcd/ and
http://lucianm.github.com/GLCDprocDriver/
* libirman for use with the 'irman' driver, see
http://www.evation.com/libirman/libirman.html for the home page and
http://www.lirc.org/software/snapshots/ for current downloads
* LIRC for use with the 'lirc' driver, see http://www.lirc.org/
* ncurses for use with the 'curses' driver, see
http://www.gnu.org/software/ncurses/
* svgalib for use with the 'svga' driver, see http://www.svgalib.org/
* libftdi and libusb for use with the 'ula200', 'lis', and 'i2500vfd' driver,
see http://www.intra2net.com/en/developer/libftdi/ and
http://libusb.sourceforge.net/
* XOSD for use with the 'xosd' driver, see http://sourceforge.net/projects/libxosd/ ,
as well as an x11 implementation, more precisely libX11 and libXext.
-- DISPLAYS -----------------------------------------------------------
Many different displays (or better said: output devices) are supported.
Some of these devices also support input, for example with a keypad.
There are drivers for input-only devices, too.
For LCDd (the server) to use the device, it needs to load a driver. The
drivers are so called 'shared modules', that usually have an extension
of .so . The drivers to be loaded should be specified in the config file
(by one or more Driver= lines), or on the command line. The command line
should only be used to override things in the config file. The drivers
should be in a directory that is indicated by the DriverPath= line in
the configfile.
Depending on what kind of LCD display that you have, there are several
sources for information. If your LCD display came with a manual, this
is a great place to start. If you don't have a manual, then you must
find out what kind of display this is, and check the related
information:
HD44780 and compatible:
read the HD44780 section in the LCDproc User's Guide (docs/lcdproc-user)
or alternatively see http://www.robijn.net/lcdproc/
If you still have problems you could take a look at the comments in the
driver source code in server/drivers/. You may have some good indications
there.
You may want to take a look at LCDproc's hardware page at
http://lcdproc.org/hardware.php3 for details. Several
different types of displays are now supported.
-- BUILDING LCDPROC -------------------------------------------------
--- Preparing a CVS distro ---
If you retrieved these files from the CVS, you will first need to run:
sh ./autogen.sh
--- Configuration ---
The simplest way of doing it is with:
./configure
But it may not do what you want, so please take a few seconds to type:
./configure --help
And read the available options, especially --enable-drivers
--- Compilation ---
Run make to build the server and all clients
make
If you only want to compile the clients, you can omit to compile the
server:
make clients
Similarly, if you only want to compile the server, you can omit to
compile the clients:
make server
Depending on your system, LCDproc will build in a few seconds to a
few minutes. It's not very big.
If you want to, you can install it (if you're root) by typing:
make install
This will install the binaries and the man pages in the directory you
specified in configure.
You may have to copy the configuration file (LCDd.conf) to /etc
(or /usr/local/etc) manually.
-- CREATING DISTRIBUTION SPECIFIC PACKAGES --------------------------
Instead of manually configuring, compiling and installing LCDproc you
may use the support files in the LCDproc source tree to create an
installation package specific to your distribution
Debian:
- Rename the .tgz file with the sources to lcdproc_VERSION.orig.tar.gz
cp lcdproc-VERSION.tgz lcdproc_VERSION.orig.tar.gz
- Extract the source tar ball
tar xvzf lcdproc_VERSION.orig.tar.gz
- Copy the debian/ directory below scripts/ to the root of the
source tree
cp -a lcdproc-VERSION/scripts/debian lcdproc-VERSION/
- Generate .deb debian package
cd lcdproc-VERSION/
dpkg-buildpackage -rfakeroot -sd
cd ..
This creates a file named lcdproc_VERSION-RELEASE_ARCH.deb
that contains the LCDproc suite as a regular Debian package.
-- PLATFORM SPECIFIC ------------------------------------------------
The lcdproc crew has tried to support a number of platforms. Platforms
that are very non-standard are not and probably will never be supported.
Both, the server with its drivers and the clients, have their own
difficulties in porting. Here's are the prerequisites for both:
--- Client ---
The client should run on any POSIX compliant system.
It has been successfully tested on:
Linux 2.2.x - 2.6.x, FreeBSD 6.x - 8.1, NetBSD 1.5 & 3.x, OpenBSD 3.0,
Darwin, Solaris and MacOS.
--- Server ---
The server needs to talk to the LCD display. At this time, it works
on very little more than on the Intel i386 (PC Compatible)
architecture. It has been successfully tested on:
Linux 2.2.x - 2.6.x, FreeBSD 6.x - 8.1, NetBSD 1.5 & 3.x, OpenBSD 3.0,
Darwin, Solaris and MacOS.
Here are some comments specific to each platform that LCDproc has been
tested on.
--- Linux ---
Nothing special to say, everything should go well.
You may not be able to compile all drivers on something else than i386
if your linux installation does not have ioperm, inb and outb commands.
./configure should leave all drivers that need those functions out
(drivers for parallel port displays), so that LCDd should compile anyway.
--- NetBSD ---
You need to use GNU Make instead of NetBSD's make.
Remember to type gmake instead of make to compile LCDproc.
The server will probably only compile on NetBSD/i386.
If you try to run LCDd and you get this error:
Bus error (core dumped)
It is likely that you did not have the right permission to access the ports.
Try starting the program as root.
--- OpenBSD ---
You need to use GNU Make instead of OpenBSD's make.
Remember to type gmake instead of make to compile LCDproc.
The server will probably only compile on OpenBSD/i386.
--- FreeBSD ---
It should compile fine on i386. Must be started as root to be able to use
parallel and USB ports.
--- Other platforms ---
If the build process fails, but you do know how to link a loadable
module by hand, you can add the appropriate flags et cetera into
acinclude.m4. Experience required. Please let us know if you got it
working on a previously unsupported system, so we can include it in a
next release.
-- RUNNING LCDPROC -----------------------------------------------------
--- Configuration file ---
The first thing that you need to do is to modify the configuration file
for your server. A example file (LCDd.conf) is available in the tarball.
The comments present in this file should give you indications on what
to do.
--- Starting the server ---
If you're in the LCDproc source directory, and have just built it, run:
server/LCDd -c path/to/config/file
For security reasons, LCDd by default only accepts connections from
localhost (127.0.0.1), it will not accept connections from other computers on
your network / the Internet. You can change this behaviour in the
configuration file.
--- Starting the client(s) ---
Then, you'll need some clients. LCDproc comes with a few, of which the
'lcdproc' client is the main client:
clients/lcdproc/lcdproc -f C M T L
This will run the LCDproc client, with the [C]pu, [M]emory,
[T]ime, and [L]oad screens. The option "-f" causes it not to daemonize,
but run in the foreground.
By default, the client tries to connect to a server located on localhost
and listening to port 13666. To change this, use the -s and -p options.
-- PUTTING LCDPROC IN SYSTEM STARTUP -----------------------------------
It's nice to have LCDproc start when the computer boots, so here's how
to do it:
WARNING: Make sure you have modified the configuration file (/etc/LCDd.conf)
so that LCDd enters the background mode.
Otherwise LCDd will lock your system.
Slackware:
Add lines to your /etc/rc.d/rc.local, such as the following:
echo "Starting LCDd..."
/usr/local/sbin/LCDd -c /etc/LCDd.conf
echo "Starting lcdproc..."
/usr/local/bin/lcdproc C M X &
Debian: (the hard way)
- Copy (as root) the debian init script from the scripts/ directory of the
sources to /etc/init.d
(cp scripts/init-LCDd.debian /etc/init.d/LCDd && \
cp scripts/init-lcdproc.debian /etc/init.d/lcdproc)
- Run (as root): update-rc.d LCDd defaults
This will create symlinks to start and stop the daemon, resp.
from /etc/rc[2-5].d/S50LCDd to /etc/init.d/LCDd, and from
/etc/rc[016].d/K50LCDd to /etc/init.d/LCDd.
- Run (as root): update-rc.d lcdproc defaults
This will create symlinks to start and stop the lcdproc client, resp.
from /etc/rc[2-5].d/S50lcdproc to /etc/init.d/lcdproc, and from
/etc/rc[016].d/K50lcdproc to /etc/init.d/lcdproc.
Debian: (the easy way)
- Install the previously created .deb package (as root)
dpkg -i lcdproc_VERSION-RELEASE_ARCH.deb
Redhat / Mandrake:
- Copy the scripts:
cp scripts/init-lcdd.rpm /etc/rc.d/init.d/lcdd && \
cp scripts/init-lcdproc.rpm /etc/rc.d/init.d/lcdproc)
- enable the scripts with e.g. linuxconf or create the symlinks manually
FreeBSD:
- If you install from the ports collection startup script are
installed by default.
That's all the OS's we've actually done this with so far.
-1367
View File
File diff suppressed because it is too large Load Diff
-55
View File
@@ -1,55 +0,0 @@
## Process this file with automake to produce Makefile.in
## set automake strictness to 'foreign'
AUTOMAKE_OPTIONS = foreign
SUBDIRS = shared clients server docs scripts
sysconf_DATA = LCDd.conf
EXTRA_DIST = $(sysconf_DATA) CREDITS contrib
dist-hook:
rm -rf `find $(distdir)/contrib -name CVS`
## convenience targets
.PHONY: $(SUBDIRS) install-server install-clients
$(SUBDIRS):
$(MAKE) -C $@
clients server: shared
install-server: server
$(MAKE) -C server install
$(MAKE) -C docs install-server-man
install-clients: clients
$(MAKE) -C clients install
$(MAKE) -C docs install-client-man
.PHONY: install-html-guides install-html-developerguide install-html-userguide
install-html-guides: install-html-developerguide install-html-userguide
install-html-developerguide:
$(MAKE) -C docs $@
install-html-userguide:
$(MAKE) -C docs $@
.PHONY: dox topleveltags
dox:
$(MAKE) -C docs $@
topleveltags:
$(CTAGS) --format=1 -f - --languages=C --c-kinds=f --recurse=yes server shared clients \
| perl -p -e 's/^([^\t]+)\t[^\t]+\/([^\t\/]+)\t(.*)$/$1\t$2\t$3/' > tags
## EOF
-101
View File
@@ -1,101 +0,0 @@
This is the official repository for the LCDproc project.
_Note: this project is currently being migrated from Sourceforge. Documentation
is still being updated to reflect this and we're still getting our bearings here
on GitHub, so please excuse the dust while we set up shop._
# Introduction
LCDproc is a client/server suite including drivers for all kinds of nifty LCD
devices. The server works with different display sizes and supports several
serial devices: Matrix Orbital, Crystal Fontz, Bayrad, LB216, LCDM001
(kernelconcepts.de), Wirz-SLI and PIC-an-LCD; some devices connected to
the parallel port: HD44780, STV5730, T6963, SED1520 and SED1330; and also
some displays connected via USB: CFontzPacket, CwLnx, IOWarrior, LIS2 and
BWCT.
Various clients are available that display things like CPU load, system load,
memory usage, uptime, and a lot more.
LCDproc also supports key or remote control input for controlling the clients.
The client and the server use a TCP connection to communicate, so it is
possible to have a client on a box in Sweden showing its stats on a LCD
display in the United States.
Visit our [website](http://lcdproc.org/) for more information. The project's
repository, issue tracking and pull request management can be found at
http://github.com/lcdproc/lcdproc.
LCDproc was originally written by [William Ferrell](mailto:willfe@gmail.com)
and [Selene Scriven](lcdproc@toykeeper.net).
# Installation
Refer to the INSTALL file included with this archive for installation
instructions (including how to connect the LCD to your system).
# Changes
Woow... a lot. :)
See the ChangeLog file for more details.
# Contributing
If you've found a bug or want to add new functionality to LCDproc, feel free
to fork the repository, make your changes and send us a pull request. They're
always welcome!
If you want to help but need some inspiration, take a look at the TODO
file to see what we think that needs to be done.
To learn more about how LCDproc works, first have a look at the docs/
directory. Some important things are documented there, but because this is
still somewhat a big hacking project, some documentation will be missing ;)
## Code of Merit
This project adopts the Code of Merit, version 1.0, originally published
at http://code-of-merit.org/. Refer to CODE_OF_MERIT.md in this project's
source tree for a copy of this document.
In short, let's focus on writing software and leave the politics out of it.
# Special Thanks
LCDproc wouldn't be possible without the ongoing patience and efforts by its
amazing community of developers and users. We'd like to recognize everyone's
contributions to the project, and we've tried to list them all in the CREDITS
file. If we've overlooked your contributions, please let us know so we can
attribute your work immediately!
_From William Ferrell, original developer:_ This project is almost twenty years
old as I write this, and I'm so proud of what it's become over the years thanks
in no small part to the people (past and present) who not only contributed their
work and ideas to the project, but helped to manage and maintain it when I
couldn't. To see this project start as a small single-system utility program
supporting a single type of device and flourish into a client/server daemon used
around the world to drive all sorts of display devices is beyond anything I could
have ever hoped for, and I'm eternally grateful to everyone who's contributed
over the years. Thank you all for being part of this project and for making it
amazing. Here's to another twenty years! :)
# Legal Stuff
LCDproc is Copyright (C) 1998-2016
William Ferrell, Selene Scriven and many other contributors.
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.
The file COPYING contains the GNU General Public License.
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-60
View File
@@ -1,60 +0,0 @@
NOTE: Use of this TODO list is obsolete! A list of things to be done is
automatically created by Doxygen. You may create the Doxygen documentation
yourself by running the doxygen command from the docs/ directory.
Ideas for new features can be entered at the IdeaTorrent:
http://sourceforge.net/apps/ideatorrent/lcdproc/
------------------------------------------------------------------------------
Stuff planned for future releases... (in no particular order)
Feel free to help out with any of this stuff! :)
Please send a message to the mailing list if you have any question.
Things for the short term
=========================
- Use non-standard serial baud rates (57600 and higher) only optional.
Things for the longer term
==========================
lcdproc client
--------------
- allow more than one instance of a screen with different configuration
sections (implementation should be possible similar to the one with
the drivers in LCDd where File=... points to the original driver file)
- more options in the config file (clocks with offsets from localtime, ...)
- more options changeable in the lcdproc client menu
- rewrite machine_get_fs() in machine_Linux.c to use functions from mntent.h
- get rid of MTAB_FILE compile time definition (for Linux & SunOS)
lcdexec client
--------------
more flexbibility: do not just only execute commands, but
maybe also display their result in a screen, get a command's
parameters interactively using the builtin input menus,
confirmation of commands, jumping between commands depending
on the output of a command (wizards), ...
Client driver
-------------
An LCDproc client can connect, request the "client" driver, then get
all screen information sent to it! This allows things such as logging
in remotely and starting up a curses display of LCDproc. It also
gives another method for writing drivers. In a sense, it could even
let you write and link in new drivers without having to recompile and
restart LCDproc...
Another bonus is that LCDproc will come with a client which can, for
example, start up a "client" driver to send "keypresses" from the
command line. Or,
lcdtool -key A
would have the same result as pressing a key on the keypad.
-1181
View File
File diff suppressed because it is too large Load Diff
-53
View File
@@ -1,53 +0,0 @@
#!/bin/sh
# Run this to generate all the initial makefiles, etc.
# set default values for variables
: ${AUTOCONF:=autoconf}
: ${AUTOHEADER:=autoheader}
: ${AUTOMAKE:=automake}
: ${ACLOCAL:=aclocal}
DIE=0
($AUTOCONF --version) < /dev/null > /dev/null 2>&1 || {
echo
echo "**Error**: You must have \`autoconf' installed."
echo "Download the appropriate package for your distribution,"
echo "or get the source tarball at ftp://ftp.gnu.org/pub/gnu/"
DIE=1
}
($AUTOMAKE --version) < /dev/null > /dev/null 2>&1 || {
echo
echo "**Error**: You must have \`automake' installed."
echo "Get ftp://ftp.gnu.org/pub/gnu/automake-1.3.tar.gz"
echo "(or a newer version if it is available)"
DIE=1
NO_AUTOMAKE=yes
}
# if no automake, don't bother testing for aclocal
test -n "$NO_AUTOMAKE" || ($ACLOCAL --version) < /dev/null > /dev/null 2>&1 || {
echo
echo "**Error**: Missing \`aclocal'. The version of \`automake'"
echo "installed doesn't appear recent enough."
echo "Get ftp://ftp.gnu.org/pub/gnu/automake-1.3.tar.gz"
echo "(or a newer version if it is available)"
DIE=1
}
if test "$DIE" -eq 1; then
exit 1
fi
echo "Running aclocal ..."
$ACLOCAL
if grep "^A[CM]_CONFIG_HEADER" configure.ac >/dev/null; then
echo "Running autoheader..."
$AUTOHEADER
fi
echo "Running automake ..."
$AUTOMAKE --add-missing --copy
echo "Running autoconf ..."
$AUTOCONF
-2
View File
@@ -1,2 +0,0 @@
Makefile
Makefile.in
-5
View File
@@ -1,5 +0,0 @@
## Process this file with automake to produce Makefile.in
SUBDIRS = examples lcdexec lcdproc lcdvc metar
## EOF
-2
View File
@@ -1,2 +0,0 @@
Makefile
Makefile.in
-7
View File
@@ -1,7 +0,0 @@
## Process this file with automake to produce Makefile.in
bin_SCRIPTS = fortune.pl iosock.pl tail.pl x11amp.pl lcdident.pl
EXTRA_DIST = $(bin_SCRIPTS)
## EOF
-276
View File
@@ -1,276 +0,0 @@
#!/usr/bin/perl -w
# fortune.pl - an example client for LCDproc
# This is just a small example of a client for LCDd the
# LCDproc server
#
# Copyright (c) 1999, William Ferrell, Selene Scriven
# 2001, David Glaude
# 2002, Jonathan Oxer
# 2002, Rene Wagner <reenoo@gmx.de>
# 2006, Peter Marschall
#
# This file 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
# any later version.
#
# This file 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 file; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
#
use 5.005;
use strict;
use Getopt::Std;
use IO::Socket;
use Fcntl;
############################################################
# Configurable part. Set it according your setup.
############################################################
# Path to `fortune' program.
my $FORTUNE = "fortune";
# Host which runs lcdproc daemon (LCDd)
my $SERVER = "localhost";
# Port on which LCDd listens to requests
my $PORT = "13666";
############################################################
# End of user configurable parts
############################################################
my $progname = $0;
$progname =~ s#.*/(.*?)$#$1#;
# declare functions
sub update_text($);
sub error($@);
sub usage($);
## main routine ##
my %opt = ();
# get options #
if (getopts('F:s:p:hV', \%opt) == 0) {
usage(1);
}
# check options
usage(0) if ($opt{h});
if ($opt{V}) {
print STDERR $progname ." version 1.1\n";
exit(0);
}
# check number of arguments
usage(1) if ($#ARGV >= 0);
# set variables
$SERVER = defined($opt{s}) ? $opt{s} : $SERVER;
$PORT = defined($opt{p}) ? $opt{p} : $PORT;
$FORTUNE = defined($opt{F}) ? $opt{F} : $FORTUNE;
# Connect to the server...
my $remote = IO::Socket::INET->new(
Proto => 'tcp',
PeerAddr => $SERVER,
PeerPort => $PORT,
)
or error(1, "cannot connect to LCDd daemon at $SERVER:$PORT");
# Make sure our messages get there right away
$remote->autoflush(1);
sleep 1; # Give server plenty of time to notice us...
print $remote "hello\n";
# Note: it's good practice to listen for a response after a print to the
# server even if there isn't meant to be one. If you don't, you may find
# your program crashes after running for a while when the buffers fill up:
my $lcdresponse = <$remote>;
#print $lcdresponse;
# Turn off blocking mode...
fcntl($remote, F_SETFL, O_NONBLOCK);
# Set up some screen widgets...
print $remote "client_set name {$progname}\n";
$lcdresponse = <$remote>;
print $remote "screen_add fortune\n";
$lcdresponse = <$remote>;
print $remote "screen_set fortune name {Fortune}\n";
$lcdresponse = <$remote>;
print $remote "widget_add fortune title title\n";
$lcdresponse = <$remote>;
print $remote "widget_set fortune title {Fortune}\n";
$lcdresponse = <$remote>;
print $remote "widget_add fortune text scroller\n";
$lcdresponse = <$remote>;
update_text($remote);
# Forever, we should do stuff...
while (1)
{
# Handle input... (spew it to the console)
# Also, certain keys scroll the display
while (defined(my $input = <$remote>)) {
#print $input;
# Make sure we handle each line...
my @lines = split(/\n/, $input);
foreach my $line (@lines) {
next if ( $line =~ /^success$/ );
# Update just after disappearing
if ($line =~ /^ignore (\S)/) {
update_text($remote);
}
}
}
# And wait a little while before we check for input again.
sleep 1;
}
close($remote) or error(1, "close() failed: $!");
exit;
# update text on LCD
sub update_text($)
{
my $remote = shift;
my $text;
# Grab some text
$text = `$FORTUNE` || error(1, "error running `$FORTUNE'.\nPlease check that the path is correct.");
# replace new-line by slashes
$text =~ s,\n, / ,g;
# Now, show a fortune...
print $remote "widget_set fortune text 1 2 20 4 v 16 {$text}\n";
$text = <$remote>;
}
## print out error message and eventually exit ##
# Synopsis: error($status, $message)
sub error($@)
{
my $status = shift;
my @msg = @_;
print STDERR $progname . ": " . join(" ", @msg) . "\n";
exit($status) if ($status);
}
## print out usage message and exit ##
# Synopsis: usage($status)
sub usage($)
{
my $status = shift;
print STDERR "Usage: $progname [<options>]\n";
if (!$status) {
print STDERR " where <options> are\n" .
" -s <server> connect to <server> (default: $SERVER)\n" .
" -p <port> connect to <port> on <server> (default: $PORT)\n" .
" -F <fortune> use <fortune> as fortune program (default: $FORTUNE)\n" .
" -h show this help page\n" .
" -V display version number\n";
}
else {
print STDERR "For help, type: $progname -h\n";
}
exit($status);
}
__END__
=pod
=head1 NAME
fortune.pl -- display fortune messages on the LCD
=head1 SYNOPSIS
B<fortune.pl>
[B<-s> I<server>]
[B<-p> I<port>]
[B<-F> I<fortune>]
[B<-h>]
[B<-V>]
=head1 DESCRIPTION
B<fortune.pl> is a small example client for LCDd, the lcdproc server.
It connects to the LCDd daemon and displays fortune cookies as delivered
by the well known fortune program.
=head1 OPTIONS
=over 4
=item B<-s> I<server>
Connect to the LCDd daemon at host I<server> instead of the default C<localhost>.
=item B<-p> I<port>
Use port I<port> when connecting to the LCDd server instead of the default
LCDd port C<13666>.
=item B<-F> I<fortune>
Use I<fortune> as the program generation fortune messages instead of the
default C<fortune>
=item B<-h>
Display a short help page and exit.
=item B<-V>
Display fortune.pl's version number and exit.
=back
=head1 SEE ALSO
L<fortune(6)>,
L<LCDd(8)>
=head1 AUTHORS
fortune.pl was written by various members of the LCDproc project team;
this manual page was written by Peter Marschall.
=cut
# EOF
-283
View File
@@ -1,283 +0,0 @@
#!/usr/bin/perl -w
use 5.005;
use strict;
use Getopt::Std;
use IO::Socket;
use Fcntl;
# iosock.pl - an example client for LCDproc
#
# This LCDproc client takes a list of machines to ping and and reports
# number of those which ping and number of those which do not and their list
#
#
# Copyright (c) 1999, William Ferrell, Selene Scriven
# 2001, David Glaude
# 2001, Jarda Benkovsky
# 2002, Jonathan Oxer
# 2002, Rene Wagner <reenoo@gmx.de>
# 2006, Peter Marschall
#
# This file 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
# any later version.
#
# This file 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 file; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
#
############################################################
# Configurable part. Set it according your setup.
############################################################
# Host which runs lcdproc daemon (LCDd)
my $SERVER = "localhost";
# Port on which LCDd listens to requests
my $PORT = "13666";
# Path to `ping' command
my $PING = "ping";
# list of hosts to be ping'ed
my @MACHINES = ("lcdproc.omnipotent.net",
"www.linux.org",
"www.daemonnews.org",
"127.0.0.1",
"seurat",
"rodin",
"matisse",
);
############################################################
# End of user configurable parts
############################################################
my $progname = $0;
$progname =~ s#.*/(.*?)$#$1#;
# declare functions
sub error($@);
sub usage($);
## main routine ##
my %opt = ();
# get options #
if (getopts('F:s:p:P:hV', \%opt) == 0) {
usage(1);
}
# check options
usage(0) if ($opt{h});
if ($opt{V}) {
print STDERR $progname ." version 1.1\n";
exit(0);
}
# check number of arguments
#usage(1) if ($#ARGV >= 0);
# set variables
$SERVER = defined($opt{s}) ? $opt{s} : $SERVER;
$PORT = defined($opt{p}) ? $opt{p} : $PORT;
$PING = defined($opt{P}) ? $opt{P} : $PING;
@MACHINES = ($#ARGV >= 0) ? @ARGV : @MACHINES;
# Connect to the server...
my $remote = IO::Socket::INET->new(
Proto => 'tcp',
PeerAddr => $SERVER,
PeerPort => $PORT,
)
or error(1, "cannot connect to LCDd daemon at $SERVER:$PORT");
# Make sure our messages get there right away
$remote->autoflush(1);
sleep (1); # Give server plenty of time to notice us...
print $remote "hello\n";
# Note: it's good practice to listen for a response after a print to the
# server even if there isn't meant to be one. If you don't, you may find
# your program crashes after running for a while when the buffers fill up:
my $lcdresponse = <$remote>;
#print $lcdresponse;
# Turn off blocking mode...
fcntl($remote, F_SETFL, O_NONBLOCK);
# Set up some screen widgets...
print $remote "client_set name {$progname}\n";
$lcdresponse = <$remote>;
print $remote "screen_add pings\n";
$lcdresponse = <$remote>;
print $remote "screen_set pings name {Ping Status}\n";
$lcdresponse = <$remote>;
print $remote "widget_add pings title title\n";
$lcdresponse = <$remote>;
print $remote "widget_set pings title {Ping Status}\n";
$lcdresponse = <$remote>;
print $remote "widget_add pings one string\n";
$lcdresponse = <$remote>;
print $remote "widget_add pings two string\n";
$lcdresponse = <$remote>;
print $remote "widget_set pings one 1 2 {Checking machines...}\n";
$lcdresponse = <$remote>;
while (1) {
my %pingstatus = (); # pingstatus{host} = 1 <=> host is up
my @list;
#print "Main loop...\n";
# Handle input... (just spew it to the console)
while (defined(my $line = <$remote>)) {
next if ($line =~ /^success$/o);
print $line;
}
foreach my $machine (@MACHINES) {
`$PING -c 1 $machine`;
$pingstatus{$machine} = ($?) ? 0 : 1;
}
# count reachablei (up) machines
@list = grep { $pingstatus{$_} == 1 } @MACHINES;
print $remote "widget_set pings one 1 2 {Machines Up: ",scalar(@list),"}\n";
my $lcdresponse = <$remote>;
# count unreachable (down) machines
@list = grep { $pingstatus{$_} == 0 } @MACHINES;
print $remote "widget_set pings two 1 3 {Down (",scalar(@list),"): ",join(", ", @list),"}\n";
$lcdresponse = <$remote>;
# wait a bit
sleep(1);
}
close($remote) or error(1, "close() failed: $!");
exit;
## print out error message and eventually exit ##
# Synopsis: error($status, $message)
sub error($@)
{
my $status = shift;
my @msg = @_;
print STDERR $progname . ": " . join(" ", @msg) . "\n";
exit($status) if ($status);
}
## print out usage message and exit ##
# Synopsis: usage($status)
sub usage($)
{
my $status = shift;
print STDERR "Usage: $progname [<options>] [<host> ...]\n";
if (!$status) {
print STDERR " where <options> are\n" .
" -s <server> connect to <server> (default: $SERVER)\n" .
" -p <port> connect to <port> on <server> (default: $PORT)\n" .
" -P <ping> use <ping> as the ping cmmand (default: $PING)\n" .
" -h show this help page\n" .
" -V display version number\n";
}
else {
print STDERR "For help, type: $progname -h\n";
}
exit($status);
}
__END__
=pod
=head1 NAME
iosock.pl -- show reachability of hosts and display it on the LCD
=head1 SYNOPSIS
B<iosock.pl>
[B<-s> I<server>]
[B<-p> I<port>]
[B<-P> I<ping>]
[B<-h>]
[B<-V>]
[I<host> ...]
=head1 DESCRIPTION
B<iosock.pl> is a small example client for LCDd, the lcdproc server.
It tries to ping the servers given as parameters and displays on the LCD
whether they are reachable or not.
If no hosts are given as parameters a built-in list of default machines will be checked.
=head1 OPTIONS
=over 4
=item B<-s> I<server>
Connect to the LCDd daemon at host I<server> instead of the default C<localhost>.
=item B<-p> I<port>
Use port I<port> when connecting to the LCDd server instead of the default
LCDd port C<13666>.
=item B<-P> I<ping>
Use I<ping> as the command to check whether the remote hosts are reachable
instead of the default C<ping>.
Any I<ping> given using this options must understand the C<-c 1>
command line option of the default C<ping>.
=item B<-h>
Display a short help page and exit.
=item B<-V>
Display iosock.pl's version number and exit.
=back
=head1 SEE ALSO
L<LCDd(8)>
=head1 AUTHORS
iosock.pl was written by various members of the LCDproc project team;
this manual page was written by Peter Marschall.
=cut
# EOF
-296
View File
@@ -1,296 +0,0 @@
#!/usr/bin/perl -w
# Copyright (c) 2008, Ethan Dicks <ethan.dicks@gmail.com>
#
# This file 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
# any later version.
#
# This file 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 file; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
#
# Following is the POD documentation, type perldoc lcdident.pl to read it.
=head1 NAME
lcdident - identify LCDproc displays
=head1 SYNOPSIS
B<lcdident.pl>
[B<-s> I<server>]
[B<-p> I<port>]
[B<-t> I<seconds>]
[B<-v> I<verbosity>]
[B<-h>]
[B<-V>]
=head1 DESCRIPTION
B<lcdident> is a simple LCDproc client program that writes a port
number and display geometry to a particular instance of B<LCDd>. For
systems with multiple display modules and multiple B<LCDd> processes,
it can be quite handy to know which TCP port is associated with
which physical module.
B<lcdident> is also an example of how to code for different display
geometries. In particular, it differentiates between 2-line and
more-than-2-line (typically 4-line) displays.
=head1 OPTIONS
-s <server>
connect to <server>.
-p <port>
connect to port <port>
-t <seconds>
how long to keep this client running (default is 5 seconds).
-v <verbosity>
set logging verbosity level to <verbosity>.
-V
display the present version number of lcdident.
-h
print out a list of the available program options and exit.
=head1 DIAGNOSTICS
=over 4
=item Cannot connect to LCDproc port
By default, lcdident tries to connect to localhost port 13666, but by using
the B<-s> and B<-p> options, you can point B<lcdident> at other servers and
other ports. If you get this error, that means that there was a problem
opening up the requested port on the requested machine. Typically this
means that B<LCDd> is not listening on that particular port. The two most
common causes of this are because B<LCDd> was configured to listen on a
different port, or because B<LCDd> is not running at all.
=back
=head1 REQUIRES
Perl 5.004;
=head1 DISCLAMER
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License version 2 as
published by the Free Software Foundation.
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.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
=head1 SEE ALSO
L<LCDd>
=head1 BUGS
Yes, there might be some. Please report any you find to LCDproc's mailing list.
See the website for more information.
=head1 AUTHORS
B<lcdident> was written by Ethan Dicks <ethan.dicks@gmail.com>
=head1 WEBSITE
Visit B<http://www.lcdproc.org/> for more info and the lastest version.
=cut
use 5.004;
use strict;
use IO::Socket;
use Getopt::Std;
use Fcntl;
############################################################
# Configurable part. Set it according your setup
# or use input args.
############################################################
# Verbose
# 0 : None (only fatal errors)
# 1 : Warnings
# 5 : Explain every step.
my $verbose = 0;
# Host which runs lcdproc daemon (LCDd)
my $server = "localhost";
# Port on which LCDd listens to requests
my $port = "13666";
# wait-time (in seconds) when we are all done
my $waittime = 5;
############################################################
# End of user configurable parts
############################################################
$SIG{INT} = \&grace;
$SIG{TERM} = \&grace;
my $progname = $0;
$progname =~ s#.*/(.*?)$#$1#;
# declare functions
sub grace();
sub usage($);
# Process input arguments
my %opt = ();
# get options #
if (getopts('s:p:v:t:hV', \%opt) == 0) {
usage(1);
}
# check options
usage(0) if ($opt{h});
if ($opt{V}) {
print STDERR $progname ." version 1.05\n";
exit(0);
}
# check number of arguments
usage(1) if ($#ARGV >= 0);
# set variables
$server = defined($opt{s}) ? $opt{s} : $server;
$port = defined($opt{p}) ? $opt{p} : $port;
$verbose = defined($opt{v}) ? $opt{v} : $verbose;
$waittime= defined($opt{t}) ? $opt{t} : $waittime;
# Connect to the server...
print "Connecting to LCDproc at $server\n" if ($verbose >= 5);
my $remote = IO::Socket::INET->new(
Proto => "tcp",
PeerAddr => $server,
PeerPort => $port,
) or die "Cannot connect to LCDproc port ($server:$port)\n";
# Make sure our messages get there right away
$remote->autoflush(1);
sleep 1; # Give server plenty of time to notice us...
print $remote "hello\n";
my $lcdconnect = <$remote>;
print $lcdconnect if ($verbose >= 5);
# connect LCDproc 0.5.2 protocol 0.3 lcd wid 20 hgt 4 cellwid 5 cellhgt 8
($lcdconnect =~ /lcd.+wid\s+(\d+)\s+hgt\s+(\d+)/);
my $lcdwidth = $1; my $lcdheight= $2;
print "Detected LCD size of $lcdwidth x $lcdheight\n" if ($verbose >= 5);
# Turn off blocking mode...
fcntl($remote, F_SETFL, O_NONBLOCK);
# Set up some screen widgets...
print $remote "client_set name {lcdident}\n";
print $remote "screen_add lcdident\n";
print $remote "screen_set lcdident name {lcdident}\n";
print $remote "widget_add lcdident title title\n";
print $remote "widget_set lcdident title {lcdident}\n";
print $remote "widget_add lcdident ident1 string\n";
print $remote "widget_add lcdident ident2 string\n";
# Compose the ident message(s) and calculate where to render it/them
my $ident1;
my $ident2;
my $ident2_y = $lcdheight; # put the second bit on the bottom line
my $ident1_y = $ident2_y - 1; # put the first bit one line up from the second
# check for 2-line displays to see if we have to put all the info on one line
if ($lcdheight > 2) {
$ident1 = "Port ${port}";
$ident2 = "Geom ${lcdwidth}x${lcdheight}";
} else {
$ident1 = "Port $port ${lcdwidth}x${lcdheight}";
$ident2 = "";
$ident1_y = $lcdheight; # use the bottom line
}
# Display the ident message(s)
if ($ident1) {
my $cmd = sprintf("widget_set lcdident ident1 1 %d {%s}", $ident1_y, $ident1);
print "Cmd is '$cmd'\n" if ($verbose >= 5);
print $remote $cmd, "\n";
}
if ($ident2) {
my $cmd = sprintf("widget_set lcdident ident2 1 %d {%s}", $ident2_y, $ident2);
print "Cmd is '$cmd'\n" if ($verbose >= 5);
print $remote $cmd, "\n";
}
# hold the client screen up for as long as we were asked (default 5 seconds);
print "Keeping screen up for $waittime seconds\n" if ($verbose >= 5);
sleep($waittime);
# eat all input from LCDd
while(defined(my $input = <$remote>)) { }
# all done
grace();
# send a SIGINT or SIGTERM to exit nicely.
# To be called on exit and on SIGINT or SIGTERM.
sub grace() {
print "Exiting...\n" if ($verbose >= 5);
close($remote);
exit;
}
## print out usage message and exit ##
# Synopsis: usage($status)
sub usage($)
{
my $status = shift;
print STDERR "Usage: $progname [<options>]\n";
if (!$status) {
print STDERR " where <options> are\n" .
" -s <server> connect to <server> (default: $server)\n" .
" -p <port> connect to <port> on <server> (default: $port)\n" .
" -t <seconds> how long to hold the client screen up (default: $waittime seconds).\n" .
" -v <verbosity> verbosity level (default: $verbose, max verbosity: 5)\n" .
" -h show this help page\n" .
" -V display version number\n";
}
else {
print STDERR "For help, type: $progname -h\n";
}
exit($status);
}
__END__
-342
View File
@@ -1,342 +0,0 @@
#!/usr/bin/perl -w
# tail.pl - an example client for LCDproc
#
# This client for LCDproc displays the tail of a specified file.
# It's possible to change the visible part of the file with LCDproc
# controlled keys
#
#
# Copyright (c) 1999, William Ferrell, Selene Scriven
# 2001, David Glaude
# 2001, Jarda Benkovsky
# 2002, Jonathan Oxer
# 2002, Rene Wagner <reenoo@gmx.de>
# 2008, Peter Marschall
#
# This file 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
# any later version.
#
# This file 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 file; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
#
use 5.005;
use strict;
use Getopt::Std;
use IO::Socket;
use Fcntl;
############################################################
# Configurable part. Set it according your setup.
############################################################
# Host which runs LCDproc daemon (LCDd)
my $SERVER = "localhost";
# Port on which LCDd listens to requests
my $PORT = "13666";
############################################################
# End of user configurable parts
############################################################
# These define the visible part of the file...
my $top = 3; # How far from the end of the file should we start by default?
my $lines = 3; # How many lines to display by default ?
my $left = 1; # Left/right scrolling position,
my $width = 20; # and number of characters per line to show
my $progname = $0;
$progname =~ s#.*/(.*?)$#$1#;
# declare functions
sub error($@);
sub usage($);
## main routine ##
my %opt = ();
# get options #
if (getopts('F:s:p:hV', \%opt) == 0) {
usage(1);
}
# check options
usage(0) if ($opt{h});
if ($opt{V}) {
print STDERR $progname ." version 1.1\n";
exit(0);
}
# check number of arguments
usage(1) if ($#ARGV != 0);
# set variables
$SERVER = defined($opt{s}) ? $opt{s} : $SERVER;
$PORT = defined($opt{p}) ? $opt{p} : $PORT;
my $filename = shift @ARGV;
my $slow = 1; # Should we pause after the current frame?
# Connect to the server...
my $remote = IO::Socket::INET->new(
Proto => 'tcp',
PeerAddr => $SERVER,
PeerPort => $PORT,
)
or error(1, "cannot connect to LCDd daemon at $SERVER:$PORT");
# Make sure our messages get there right away
$remote->autoflush(1);
sleep 1; # Give server plenty of time to notice us...
print $remote "hello\n";
# Note: it's good practice to listen for a response after a print to the
# server even if there isn't meant to be one. If you don't, you may find
# your program crashes after running for a while when the buffers fill up.
my $lcdresponse = <$remote>;
#print $lcdresponse;
# get width & height from server's greet message
if ($lcdresponse =~ /\bwid\s+(\d+)\b/) {
$width = 0 + $1;
}
if ($lcdresponse =~ /\bhgt\s+(\d+)\b/) {
$lines = (0 + $1) - 1;
$top = $lines;
}
# Turn off blocking mode...
fcntl($remote, F_SETFL, O_NONBLOCK);
# Set up some screen widgets...
print $remote "client_set name {$progname}\n";
$lcdresponse = <$remote>;
print $remote "screen_add tail\n";
$lcdresponse = <$remote>;
print $remote "screen_set tail name {Tail $filename}\n";
$lcdresponse = <$remote>;
print $remote "widget_add tail title title\n";
$lcdresponse = <$remote>;
print $remote "widget_set tail title {Tail: $filename}\n";
$lcdresponse = <$remote>;
# create one widget called lineX (x in {1,2,...}) per line
for (my $i = 1; $i <= $lines; $i++) {
print $remote "widget_add tail line$i string\n";
$lcdresponse = <$remote>;
}
# NOTE: You have to ask LCDd to send you keys you want to handle
print $remote "client_add_key Left\n";
$lcdresponse = <$remote>;
print $remote "client_add_key Right\n";
$lcdresponse = <$remote>;
print $remote "client_add_key Up\n";
$lcdresponse = <$remote>;
print $remote "client_add_key Down\n";
$lcdresponse = <$remote>;
# Forever, we should do stuff...
while (1) {
# Handle input... (spew it to the console)
# Also, certain keys scroll the display
while(defined(my $input = <$remote>)) {
next if ($input =~ /^success$/o);
#print $input;
$slow = -10;
# Make sure we handle each line...
my @lines = split(/\n/, $input);
foreach my $line (@lines) {
if ($line =~ /^key (\S+)/) { # Keypresses are useful.
my $key = $1;
if ($key eq 'Down') {
$top-- if ($top > $lines);
}
elsif ($key eq 'Up') {
$top++;
}
elsif ($key eq 'Right') {
$left++;
}
elsif ($key eq 'Left') {
$left-- if ($left > 1);
}
}
}
}
# Now, show what the file contains, if anything...
if ( -f $filename ) {
# Grab some text.
my $right = $left + $width - 1;
# get the data by calling external programs tail, head & cut
my $text = `tail -$top $filename | head -$lines | cut -c$left-$right`;
my @lines = split(/\n/, $text);
# Now, display that text...
for (my $i = 0; $i < $lines; $i++) {
my $j = $i + 1;
my $k = $i + 2;
# Avoid blank lines
my $line = ($#lines < $i) ? " " : $lines[$i];
$line = " " if ($line =~ /^\s*$/o);
# expand tabs to spaces
while ((my $idx = index($line, "\t")) >= 0) {
use integer; # calculate integers like in C
my $w = 8 + 8 * ($idx / 8) - $idx;
my $subst = " " x $w;
$line =~ s/\t/" " x $w/e;
}
# write to the display
print $remote "widget_set tail line$j 1 $k {$line}\n";
my $lcdresponse = <$remote>;
}
}
else { # If the file is unreadable, show an error
print $remote "widget_set tail line1 1 2 {$filename}\n";
$lcdresponse = <$remote>;
print $remote "widget_set tail line2 1 3 {doesn't exist.}\n";
$lcdresponse = <$remote>;
print $remote "widget_set tail line3 1 4 { }\n";
$lcdresponse = <$remote>;
}
# And wait a little while before we show stuff again.
if ($slow > 0) { sleep 1; $slow++; }
elsif ($slow > 4) { sleep 2; $slow++; }
elsif ($slow > 64) { sleep 4; }
else { $slow++; }
# The "slow" thing just lets us have a better response time
# while the user is pressing keys... But while the user
# is inactive, it gradually decreases update frequency.
}
close ($remote) or error(1, "close() failed");
exit;
## print out error message and eventually exit ##
# Synopsis: error($status, $message)
sub error($@)
{
my $status = shift;
my @msg = @_;
print STDERR $progname . ": " . join(" ", @msg) . "\n";
exit($status) if ($status);
}
## print out usage message and exit ##
# Synopsis: usage($status)
sub usage($)
{
my $status = shift;
print STDERR "Usage: $progname [<options>] <file>\n";
if (!$status) {
print STDERR " where <options> are\n" .
" -s <server> connect to <server> (default: $SERVER)\n" .
" -p <port> connect to <port> on <server> (default: $PORT)\n" .
" -h show this help page\n" .
" -V display version number\n";
}
else {
print STDERR "For help, type: $progname -h\n";
}
exit($status);
}
__END__
=pod
=head1 NAME
tail.pl -- show tail of a file on LCD
=head1 SYNOPSIS
B<tail.pl>
[B<-s> I<server>]
[B<-p> I<port>]
[B<-h>]
[B<-V>]
I<file>
=head1 DESCRIPTION
B<tail.pl> is a small example client for LCDd, the LCDproc server.
It shows the tail of th file given as parameter on the LCD.
If the LCD supports keys you can use the keys mapped to C<Up>, C<Down>,
C<Left> and C<Right> to scroll the contents shown on the screen.
=head1 OPTIONS
=over 4
=item B<-s> I<server>
Connect to the LCDd daemon at host I<server> instead of the default C<localhost>.
=item B<-p> I<port>
Use port I<port> when connecting to the LCDd server instead of the default
LCDd port C<13666>.
=item B<-h>
Display a short help page and exit.
=item B<-V>
Display tail.pl's version number and exit.
=back
=head1 SEE ALSO
L<tail(1)>,
L<LCDd(8)>
=head1 AUTHORS
tail.pl was written by various members of the LCDproc project team;
this manual page was written by Peter Marschall.
=cut
# EOF
-338
View File
@@ -1,338 +0,0 @@
#!/usr/bin/perl -w
# x11amp.pl - an example client for LCDproc
#
# Simple client for LCDproc which controls XMMS/X11AMP MP3 player
# from the keyboard controlled by LCDproc. It can only rewind to
# previous song and skip forward to previous one.
#
#
# Copyright (c) 1999, William Ferrell, Selene Scriven
# 2001, David Glaude
# 2001, Jarda Benkovsky
# 2002, Jonathan Oxer
# 2002, Rene Wagner <reenoo@gmx.de>
# 2006, Peter Marschall
# 2006, Ethan Dicks
#
# This file 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
# any later version.
#
# This file 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 file; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
#
# NOTE: This is just a test! It's simple, cheesy, and doesn't do much
# or even look very nice.
#
# However, it demonstrates one way to handle input from the server.
use 5.005;
use strict;
use Getopt::Std;
use IO::Socket;
use Fcntl;
############################################################
# Configurable part. Set it according your setup.
############################################################
# Verbose
# 0 : None (only fatal errors)
# 1 : Warnings
# 5 : Explain every step.
my $default_verbosity = 0;
my $verbose;
# Host which runs lcdproc daemon (LCDd)
my $SERVER = "localhost";
# Port on which LCDd listens to requests
my $PORT = "13666";
# Path to command which controls XMMS/X11AMP
my $XMMS = "xmms";
# Commands to set to previous / next song
my $XMMS_FORWARD = "$XMMS --fwd";
my $XMMS_REWIND = "$XMMS --rew";
my $XMMS_PLAY_PAUSE = "$XMMS --play-pause";
############################################################
# End of user configurable parts
############################################################
# catch SIGINT and SIGTERM to invoke our cleanup routine
$SIG{INT} = \&grace;
$SIG{TERM} = \&grace;
my $progname = $0;
$progname =~ s#.*/(.*?)$#$1#;
# declare functions
sub error($@);
sub usage($);
## main routine ##
my %opt = ();
# get options #
if (getopts('s:p:v:hV', \%opt) == 0) {
usage(1);
}
# check options
usage(0) if ($opt{h});
if ($opt{V}) {
print STDERR $progname ." version 1.2\n";
exit(0);
}
# check number of arguments
usage(1) if ($#ARGV >= 0);
# set variables
$SERVER = defined($opt{s}) ? $opt{s} : $SERVER;
$PORT = defined($opt{p}) ? $opt{p} : $PORT;
$verbose = defined($opt{v}) ? $opt{v} : $default_verbosity;
# Connect to the server...
my $remote = IO::Socket::INET->new(
Proto => 'tcp',
PeerAddr => $SERVER,
PeerPort => $PORT,
)
|| die "Cannot connect to LCDproc port\n";
# Make sure our messages get there right away
$remote->autoflush(1);
sleep 1; # Give server plenty of time to notice us...
print $remote "hello\n";
# Note: it's good practice to listen for a response after a print to the
# server even if there isn't meant to be one. If you don't, you may find
# your program crashes after running for a while when the buffers fill up:
my $lcdresponse = <$remote>;
print $lcdresponse if ($verbose >= 5);
# determine LCD size (not needed here, but useful for other clients)
($lcdresponse =~ /lcd.+wid\s+(\d+)\s+hgt\s+(\d+)/);
my $lcdwidth = $1; my $lcdheight= $2;
print "Detected LCD size of $lcdwidth x $lcdheight\n" if ($verbose >= 5);
# Turn off blocking mode...
fcntl($remote, F_SETFL, O_NONBLOCK);
# Set up some screen widgets...
print $remote "client_set name {X11AMP}\n";
$lcdresponse = <$remote>;
print $remote "screen_add x11amp\n";
$lcdresponse = <$remote>;
print $remote "screen_set x11amp name {X11AMP test}\n";
$lcdresponse = <$remote>;
print $remote "widget_add x11amp title title\n";
$lcdresponse = <$remote>;
print $remote "widget_set x11amp title {$XMMS test}\n";
$lcdresponse = <$remote>;
print $remote "widget_add x11amp one string\n";
$lcdresponse = <$remote>;
print $remote "widget_set x11amp one 1 2 {[<<] [>|] [>>]}\n";
$lcdresponse = <$remote>;
# NOTE: You have to ask LCDd to send you keys you want to handle
print $remote "client_add_key Left\n";
$lcdresponse = <$remote>;
print $remote "client_add_key Right\n";
$lcdresponse = <$remote>;
print $remote "client_add_key Enter\n";
$lcdresponse = <$remote>;
while(1) {
# Handle input...
while (defined(my $line = <$remote>)) {
chomp $line;
print "Received '$line'\n" if ($verbose >= 5);
my @items = split(/ /, $line);
my $command = shift @items;
# Use input to change songs...
if ($command eq 'key') {
my $key = shift @items;
if ($key eq 'Left') {
system($XMMS_REWIND);
}
elsif ($key eq 'Right') {
system($XMMS_FORWARD);
}
elsif ($key eq 'Enter') {
system($XMMS_PLAY_PAUSE);
}
}
# And ignore everything else
elsif ($command eq 'connect') {
}
elsif ($command eq 'listen') {
}
elsif ($command eq 'ignore') {
}
elsif ($command eq 'success') {
}
else {
error(0, "Huh?", $line)
if ($line !~ /^\s*$/o);
}
}
# wait a bit
sleep 1;
}
# To be called on exit and on SIGINT or SIGTERM.
sub grace() {
print "Exiting...\n" if ($verbose >= 5);
# release keys
print $remote "client_del_key Left\n";
$lcdresponse = <$remote>;
print $remote "client_del_key Right\n";
$lcdresponse = <$remote>;
print $remote "client_del_key Enter\n";
$lcdresponse = <$remote>;
# close socket
close($remote);
exit;
}
## print out error message and eventually exit ##
# Synopsis: error($status, $message)
sub error($@)
{
my $status = shift;
my @msg = @_;
print STDERR $progname . ": " . join(" ", @msg) . "\n";
exit($status) if ($status);
}
## print out usage message and exit ##
# Synopsis: usage($status)
sub usage($)
{
my $status = shift;
print STDERR "Usage: $progname [<options>]\n";
if (!$status) {
print STDERR " where <options> are\n" .
" -s <server> connect to <server> (default: $SERVER)\n" .
" -p <port> connect to <port> on <server> (default: $PORT)\n" .
" -v <verbosity> verbosity level (default: $default_verbosity, max verbosity: 5)\n" .
" -h show this help page\n" .
" -V display version number\n";
}
else {
print STDERR "For help, type: $progname -h\n";
}
exit($status);
}
__END__
=pod
=head1 NAME
x11amp.pl - LCDproc client controlling XMMS/X11AMP
=head1 SYNOPSIS
B<x11amp.pl>
[B<-s> I<server>]
[B<-p> I<port>]
[B<-v> I<verbosity>]
[B<-h>]
[B<-V>]
=head1 DESCRIPTION
B<x11amp.pl> is a simple client for LCDproc which controls an XMMS/X11AMP
MP3 player from the keypad controlled by LCDproc.
It can only rewind to the previous song, skip forward to the next song, and switch between pause and play.
=head1 OPTIONS
=over 4
=item B<-s> I<server>
Connect to the LCDd daemon at host I<server> instead of the default C<localhost>.
=item B<-p> I<port>
Use port I<port> when connecting to the LCDd server instead of the default
LCDd port C<13666>.
=item B<-v> I<verbosity>
Set message verbosity (0 is silent, 1 is warnings only, 5 describes events in detail).
=item B<-h>
Display a short help page and exit.
=item B<-V>
Display x11amp's version number and exit.
=back
=head1 SEE ALSO
L<xmms(6)>,
L<LCDd(8)>
=head1 AUTHORS
x11amp.pl was written by various members of the LCDproc project team;
this manual page was written by Peter Marschall.
=head1 BUGS
Yes, there might be some. Please report any you find to LCDproc's mailing list.
See the website for more information.
=head1 WEBSITE
Visit B<http://www.lcdproc.org/> for more info and the latest version.
=cut
# EOF
-4
View File
@@ -1,4 +0,0 @@
.deps
Makefile
Makefile.in
lcdexec
-16
View File
@@ -1,16 +0,0 @@
## Process this file with automake to produce Makefile.in
sysconf_DATA = lcdexec.conf
bin_PROGRAMS = lcdexec
lcdexec_SOURCES = lcdexec.c menu.c menu.h
lcdexec_LDADD = ../../shared/libLCDstuff.a
AM_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/shared -DSYSCONFDIR=\"$(sysconfdir)\" -DPIDFILEDIR=\"$(pidfiledir)\"
EXTRA_DIST = $(sysconf_DATA)
## EOF
-753
View File
@@ -1,753 +0,0 @@
/** \file clients/lcdexec/lcdexec.c
* Main file for \c lcdexec, the program starter in the LCDproc suite.
*/
/* This file is part of lcdexec, an LCDproc client.
*
* This file is released under the GNU General Public License. Refer to the
* COPYING file distributed with this package.
*
* Copyright (c) 2002, Joris Robijn
* 2006-2008, Peter Marschall
*/
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <strings.h>
#include <errno.h>
#include <sys/utsname.h>
#include <signal.h>
#include <time.h>
#include <sys/wait.h>
#include <stdlib.h>
#include "getopt.h"
#include "shared/str.h"
#include "shared/report.h"
#include "shared/configfile.h"
#include "shared/sockets.h"
#include "menu.h"
#if !defined(SYSCONFDIR)
# define SYSCONFDIR "/etc"
#endif
#if !defined(PIDFILEDIR)
# define PIDFILEDIR "/var/run"
#endif
#define DEFAULT_CONFIGFILE SYSCONFDIR "/lcdexec.conf"
#define DEFAULT_PIDFILE PIDFILEDIR "/lcdexec.pid"
/** information about a process started by lcdexec */
typedef struct ProcInfo {
struct ProcInfo *next; /**< pointer to the next ProcInfo entry */
const MenuEntry *cmd; /**< pointer to the corresponding menu entry */
pid_t pid; /**< PID the process was started with */
time_t starttime; /**< start time of the process */
time_t endtime; /**< finishing time of the process */
int status; /**< exit status of the process */
int feedback; /**< what info to show to the user */
int shown; /**< tell if the info has been shown to the user */
} ProcInfo;
char * help_text =
"lcdexec - LCDproc client to execute commands from the LCDd menu\n"
"\n"
"Copyright (c) 2002, Joris Robijn, 2006-2008 Peter Marschall.\n"
"This program is released under the terms of the GNU General Public License.\n"
"\n"
"Usage: lcdexec [<options>]\n"
" where <options> are:\n"
" -c <file> Specify configuration file ["DEFAULT_CONFIGFILE"]\n"
" -a <address> DNS name or IP address of the LCDd server [localhost]\n"
" -p <port> port of the LCDd server [13666]\n"
" -f Run in foreground\n"
" -r <level> Set reporting level (0-5) [2: errors and warnings]\n"
" -s <0|1> Report to syslog (1) or stderr (0, default)\n"
" -h Show this help\n";
char *progname = "lcdexec";
/* Variables set by config */
#define UNSET_INT -1
#define UNSET_STR "\01"
char *configfile = NULL;
char *address = NULL;
int port = UNSET_INT;
int foreground = FALSE;
static int report_level = UNSET_INT;
static int report_dest = UNSET_INT;
char *pidfile = NULL;
int pidfile_written = FALSE;
char *displayname = NULL;
char *default_shell = NULL;
/* Other global variables */
MenuEntry *main_menu = NULL; /**< pointer to the main menu */
ProcInfo *proc_queue = NULL; /**< pointer to the list of executed processes */
int lcd_wid = 0; /**< LCD display width reported by the server */
int lcd_hgt = 0; /**< LCD display height reported by the server */
int sock = -1; /**< socket to connect to server */
int Quit = 0; /**< indicate end of main loop */
/* Function prototypes */
static void exit_program(int val);
static void sigchld_handler(int signal);
static int process_command_line(int argc, char **argv);
static int process_configfile(char * configfile);
static int connect_and_setup(void);
static int process_response(char *str);
static int exec_command(MenuEntry *cmd);
static int show_procinfo_msg(ProcInfo *p);
static int main_loop(void);
#define CHAIN(e,f) { if (e>=0) { e=(f); }}
#define CHAIN_END(e) { if (e<0) { report(RPT_CRIT,"Critical error, abort"); exit(e); }}
int main(int argc, char **argv)
{
int error = 0;
struct sigaction sa;
CHAIN(error, process_command_line(argc, argv));
if (configfile == NULL)
configfile = DEFAULT_CONFIGFILE;
CHAIN(error, process_configfile(configfile));
if (report_dest == UNSET_INT || report_level == UNSET_INT) {
report_dest = RPT_DEST_STDERR;
report_level = RPT_ERR;
}
set_reporting(progname, report_level, report_dest);
CHAIN_END(error);
CHAIN(error, connect_and_setup());
CHAIN_END(error);
if(foreground != TRUE) {
if (daemon(1,1) != 0) {
report(RPT_ERR, "Error: daemonize failed");
}
if (pidfile != NULL) {
FILE *pidf = fopen(pidfile, "w");
if (pidf) {
fprintf(pidf, "%d\n", (int) getpid());
fclose(pidf);
pidfile_written = TRUE;
} else {
fprintf(stderr, "Error creating pidfile %s: %s\n",
pidfile, strerror(errno));
return(EXIT_FAILURE);
}
}
}
/* setup signal handlers for common signals */
sigemptyset(&sa.sa_mask);
#ifdef HAVE_SA_RESTART
sa.sa_flags = SA_RESTART;
#endif
sa.sa_handler = exit_program;
sigaction(SIGINT, &sa, NULL); // Ctrl-C
sigaction(SIGTERM, &sa, NULL); // "regular" kill
sigaction(SIGHUP, &sa, NULL); // kill -HUP
sigaction(SIGPIPE, &sa, NULL); // write to closed socket
sigaction(SIGKILL, &sa, NULL); // kill -9 [cannot be trapped; but ...]
/* setup signal handler for children to avoid zombies */
sigemptyset(&sa.sa_mask);
sa.sa_flags = SA_RESTART | SA_NOCLDSTOP;
sa.sa_handler = sigchld_handler;
sigaction(SIGCHLD, &sa, NULL);
main_loop();
exit_program(EXIT_SUCCESS);
/* NOTREACHED */
return EXIT_SUCCESS;
}
static void exit_program(int val)
{
//printf("exit program\n");
Quit = 1;
sock_close(sock);
if ((foreground != TRUE) && (pidfile != NULL) && (pidfile_written == TRUE))
unlink(pidfile);
exit(val);
}
/* the grim reaper ;-) */
static void sigchld_handler(int signal)
{
pid_t pid;
int status;
/* wait for the child that was signalled as finished */
if ((pid = wait(&status)) != -1) {
ProcInfo *p;
/* fill the procinfo structure with the necessary information */
for (p = proc_queue; p != NULL; p = p->next) {
if (p->pid == pid) {
p->status = status;
p->endtime = time(NULL);
}
}
}
}
static int process_command_line(int argc, char **argv)
{
int c;
int error = 0;
/* No error output from getopt */
opterr = 0;
while ((c = getopt(argc, argv, "c:a:p:fr:s:h")) > 0) {
char *end;
int temp_int;
switch(c) {
case 'c':
configfile = strdup(optarg);
break;
case 'a':
address = strdup(optarg);
break;
case 'p':
temp_int = strtol(optarg, &end, 0);
if ((*optarg != '\0') && (*end == '\0') &&
(temp_int > 0) && (temp_int <= 0xFFFF)) {
port = temp_int;
} else {
report(RPT_ERR, "Illegal port value %s", optarg);
error = -1;
}
break;
case 'f':
foreground = TRUE;
break;
case 'r':
temp_int = strtol(optarg, &end, 0);
if ((*optarg != '\0') && (*end == '\0') && (temp_int >= 0)) {
report_level = temp_int;
} else {
report(RPT_ERR, "Illegal report level value %s", optarg);
error = -1;
}
break;
case 's':
temp_int = strtol(optarg, &end, 0);
if ((*optarg != '\0') && (*end == '\0') && (temp_int >= 0)) {
report_dest = (temp_int ? RPT_DEST_SYSLOG : RPT_DEST_STDERR);
} else {
report(RPT_ERR, "Illegal log destination value %s", optarg);
error = -1;
}
break;
case 'h':
fprintf(stderr, "%s", help_text);
exit(EXIT_SUCCESS);
/* NOTREACHED */
case ':':
report(RPT_ERR, "Missing option argument for %c", optopt);
error = -1;
break;
case '?':
default:
report(RPT_ERR, "Unknown option: %c", optopt);
error = -1;
break;
}
}
return error;
}
static int process_configfile(char *configfile)
{
const char *tmp;
if (configfile == NULL)
configfile = DEFAULT_CONFIGFILE;
if (config_read_file(configfile) < 0) {
report(RPT_WARNING, "Could not read config file: %s", configfile);
}
if (address == NULL) {
address = strdup(config_get_string(progname, "Address", 0, "localhost"));
}
if (port == UNSET_INT) {
port = config_get_int(progname, "Port", 0, 13666);
}
if (report_level == UNSET_INT) {
report_level = config_get_int(progname, "ReportLevel", 0, RPT_WARNING);
}
if (report_dest == UNSET_INT) {
report_dest = (config_get_bool(progname, "ReportToSyslog", 0, 0))
? RPT_DEST_SYSLOG
: RPT_DEST_STDERR;
}
if (foreground != TRUE) {
foreground = config_get_bool(progname, "Foreground", 0, FALSE);
}
if (pidfile == NULL) {
pidfile = strdup(config_get_string(progname, "PidFile", 0, DEFAULT_PIDFILE));
}
if ((tmp = config_get_string(progname, "DisplayName", 0, NULL)) != NULL)
displayname = strdup(tmp);
/* try to find a shell that understands the -c COMMAND syntax */
if ((tmp = config_get_string(progname, "Shell", 0, NULL)) != NULL)
default_shell = strdup(tmp);
else {
/* 1st fallback: SHELL environment variable */
report(RPT_WARNING, "Shell not set in configuration, falling back to variable SHELL");
default_shell = getenv("SHELL");
/* 2nd fallback: /bin/sh */
if (default_shell == NULL) {
report(RPT_WARNING, "variable SHELL not set, falling back to /bin/sh");
default_shell = "/bin/sh";
}
}
main_menu = menu_read(NULL, "MainMenu");
#if defined(DEBUG)
menu_dump(main_menu);
#endif
// fail on non-existent main menu;
if (main_menu == NULL) {
report(RPT_ERR, "no main menu found in configuration");
return -1;
}
return 0;
}
static int connect_and_setup(void)
{
report(RPT_INFO, "Connecting to %s:%d", address, port);
sock = sock_connect(address, port);
if (sock < 0) {
return -1;
}
/* init connection and set client name */
sock_send_string(sock, "hello\n");
if (displayname != NULL) {
sock_printf(sock, "client_set -name {%s}\n", displayname);
}
else {
struct utsname unamebuf;
if (uname(&unamebuf) == 0)
sock_printf(sock, "client_set -name {%s %s}\n", progname, unamebuf.nodename);
else
sock_printf(sock, "client_set -name {%s}\n", progname);
}
/* Create our menu */
if (menu_sock_send(main_menu, NULL, sock) < 0) {
return -1;
}
return 0;
}
static int process_response(char *str)
{
char *argv[20];
int argc;
char *str2 = strdup(str); /* get_args modifies str2 */
report(RPT_DEBUG, "Server said: \"%s\"", str);
/* Check what the server just said to us... */
argc = get_args(argv, str2, sizeof(argv)/sizeof(argv[0]));
if (argc < 1) {
free(str2);
return 0;
}
if (strcmp(argv[0], "menuevent") == 0) {
/* Ah, this is what we were waiting for ! */
if (argc < 2) {
report(RPT_WARNING, "Server gave invalid response");
free(str2);
return -1;
}
if ((strcmp(argv[1], "select") == 0) ||
(strcmp(argv[1], "leave") == 0)) {
MenuEntry *entry;
if (argc < 3) {
report(RPT_WARNING, "Server gave invalid response");
free(str2);
return -1;
}
/* Find the entry by id */
entry = menu_find_by_id(main_menu, atoi(argv[2]));
if (entry == NULL) {
report(RPT_WARNING, "Could not find the item id given by the server");
free(str2);
return -1;
}
/* The id has been found.
* We trigger on the following conditions:
* - command entry without args
* - last arg of a command entry with args */
if (((entry->type == MT_EXEC) && (entry->children == NULL)) ||
((entry->type & MT_ARGUMENT) && (entry->next == NULL))) {
// last arg => get parent entry
if ((entry->type & MT_ARGUMENT) && (entry->next == NULL))
entry = entry->parent;
if (entry->type == MT_EXEC)
exec_command(entry);
}
}
else if ((strcmp(argv[1], "plus") == 0) ||
(strcmp(argv[1], "minus") == 0) ||
(strcmp(argv[1], "update") == 0)) {
MenuEntry *entry;
if (argc < 4) {
report(RPT_WARNING, "Server gave invalid response");
free(str2);
return -1;
}
/* Find the entry by id */
entry = menu_find_by_id(main_menu, atoi(argv[2]));
if (entry == NULL) {
report(RPT_WARNING, "Could not find the item id given by the server");
free(str2);
return -1;
}
switch (entry->type) {
case MT_ARG_SLIDER:
entry->data.slider.value = atoi(argv[3]);
break;
case MT_ARG_RING:
entry->data.ring.value = atoi(argv[3]);
break;
case MT_ARG_NUMERIC:
entry->data.numeric.value = atoi(argv[3]);
break;
case MT_ARG_ALPHA:
entry->data.alpha.value = realloc(entry->data.alpha.value,
strlen(argv[3]));
strcpy(entry->data.alpha.value, argv[3]);
break;
case MT_ARG_IP:
entry->data.ip.value = realloc(entry->data.ip.value,
strlen(argv[3]));
strcpy(entry->data.ip.value, argv[3]);
break;
case MT_ARG_CHECKBOX:
if ((entry->data.checkbox.allow_gray) &&
(strcasecmp(argv[3], "gray") == 0))
entry->data.checkbox.value = 2;
else if (strcasecmp(argv[3], "on") == 0)
entry->data.checkbox.value = 1;
else
entry->data.checkbox.value = 0;
break;
default:
report(RPT_WARNING, "Illegal menu entry type for event");
free(str2);
return -1;
}
}
else {
; /* Ignore other menuevents */
}
}
else if (strcmp(argv[0], "connect") == 0) {
int a;
/* determine display height and width */
for (a = 1; a < argc; a++) {
if (strcmp(argv[a], "wid") == 0)
lcd_wid = atoi(argv[++a]);
else if (strcmp(argv[a], "hgt") == 0)
lcd_hgt = atoi(argv[++a]);
}
}
else if (strcmp(argv[0], "bye") == 0) {
// TODO: make it better
report(RPT_INFO, "Server said: \"%s\"", str);
exit_program(EXIT_SUCCESS);
}
else if (strcmp(argv[0], "huh?") == 0) {
/* Report errors */
report(RPT_WARNING, "Server said: \"%s\"", str);
}
else {
; /* Ignore all other responses */
}
free(str2);
return 0;
}
static int exec_command(MenuEntry *cmd)
{
if ((cmd != NULL) && (menu_command(cmd) != NULL)) {
const char *command = menu_command(cmd);
const char *argv[4];
pid_t pid;
ProcInfo *p;
char *envp[cmd->numChildren+1];
MenuEntry *arg;
int i;
/* set argument vector */
argv[0] = default_shell;
argv[1] = "-c";
argv[2] = command;
argv[3] = NULL;
/* set environment vector: allocate & fill contents */
for (arg = cmd->children, i = 0; arg != NULL; arg = arg->next, i++) {
char buf[1025];
switch (arg->type) {
case MT_ARG_SLIDER:
snprintf(buf, sizeof(buf)-1, "%s=%d",
arg->name, arg->data.slider.value);
break;
case MT_ARG_RING:
snprintf(buf, sizeof(buf)-1, "%s=%s", arg->name,
arg->data.ring.strings[arg->data.ring.value]);
break;
case MT_ARG_NUMERIC:
snprintf(buf, sizeof(buf)-1, "%s=%d",
arg->name, arg->data.numeric.value);
break;
case MT_ARG_ALPHA:
snprintf(buf, sizeof(buf)-1, "%s=%s",
arg->name, arg->data.alpha.value);
break;
case MT_ARG_IP:
snprintf(buf, sizeof(buf)-1, "%s=%s",
arg->name, arg->data.ip.value);
break;
case MT_ARG_CHECKBOX:
if (arg->data.checkbox.map[arg->data.checkbox.value] != NULL)
strncpy(buf, arg->data.checkbox.map[arg->data.checkbox.value],
sizeof(buf)-1);
else
snprintf(buf, sizeof(buf)-1, "%s=%d",
arg->name, arg->data.checkbox.value);
break;
default:
/* error ? */
break;
}
buf[sizeof(buf)-1] ='\0';
envp[i] = strdup(buf);
debug(RPT_DEBUG, "Environment: %s", envp[i]);
}
envp[cmd->numChildren] = NULL;
debug(RPT_DEBUG, "Executing '%s' via Shell %s", command, default_shell);
switch (pid = fork()) {
case 0:
/* We're the child: execute the command */
execve(argv[0], (char **) argv, envp);
exit(EXIT_SUCCESS);
break;
default:
/* We're the parent: setup the ProcInfo structure */
p = calloc(1, sizeof(ProcInfo));
if (p != NULL) {
p->cmd = cmd;
p->pid = pid;
p->starttime = time(NULL);
p->feedback = cmd->data.exec.feedback;
/* prepend it to existing queue atomically */
p->next = proc_queue;
proc_queue = p;
}
break;
case -1:
report(RPT_ERR, "Could not fork");
return -1;
}
/* free envp's contents */
for (i = 0; envp[i] != NULL; i++)
free(envp[i]);
return 0;
}
return -1;
}
static int show_procinfo_msg(ProcInfo *p)
{
if ((p != NULL) && (lcd_wid > 0) && (lcd_hgt > 0)) {
if (p->endtime > 0) {
/* nothing to do => the quick way out (successful) */
if ((p->shown) || (!p->feedback))
return 1;
sock_printf(sock, "screen_add [%u]\n", p->pid);
sock_printf(sock, "screen_set [%u] -name {lcdexec [%u]}"
" -priority alert -timeout %d"
" -heartbeat off\n",
p->pid, p->pid, 6*8);
if (lcd_hgt > 2) {
sock_printf(sock, "widget_add [%u] t title\n", p->pid);
sock_printf(sock, "widget_set [%u] t {%s}\n", p->pid, p->cmd->displayname);
sock_printf(sock, "widget_add [%u] s1 string\n", p->pid);
sock_printf(sock, "widget_add [%u] s2 string\n", p->pid);
sock_printf(sock, "widget_add [%u] s3 string\n", p->pid);
sock_printf(sock, "widget_set [%u] s1 1 2 {[%u] finished%s}\n",
p->pid, p->pid, (WIFSIGNALED(p->status) ? "," : ""));
if (WIFEXITED(p->status)) {
if (WEXITSTATUS(p->status) == EXIT_SUCCESS) {
sock_printf(sock, "widget_set [%u] s2 1 3 {successfully.}\n",
p->pid);
}
else {
sock_printf(sock, "widget_set [%u] s2 1 3 {with code 0x%02X.}\n",
p->pid, WEXITSTATUS(p->status));
}
}
else if (WIFSIGNALED(p->status)) {
sock_printf(sock, "widget_set [%u] s2 1 3 {killed by SIG %d.}\n",
p->pid, WTERMSIG(p->status));
}
if (lcd_hgt > 3)
sock_printf(sock, "widget_set [%u] s3 1 4 {Exec time: %lds}\n",
p->pid, p->endtime - p->starttime);
}
else {
sock_printf(sock, "widget_add [%u] s1 string\n", p->pid);
sock_printf(sock, "widget_add [%u] s2 string\n", p->pid);
sock_printf(sock, "widget_set [%u] s1 1 1 {%s}\n",
p->pid, p->cmd->displayname);
if (WIFEXITED(p->status)) {
if (WEXITSTATUS(p->status) == EXIT_SUCCESS) {
sock_printf(sock, "widget_set [%u] s2 1 2 {succeeded}\n",
p->pid, p->status);
}
else {
sock_printf(sock, "widget_set [%u] s2 1 2 {finished (0x%02X)}\n",
p->pid, p->status);
}
}
else if (WIFSIGNALED(p->status)) {
sock_printf(sock, "widget_set [%u] s2 1 2 {killed by SIG %d}\n",
p->pid, WTERMSIG(p->status));
}
}
return 1;
}
}
return 0;
}
static int main_loop(void)
{
int num_bytes;
char buf[100];
int keepalive_delay = 0;
int status_delay = 0;
/* Continuously check if we get a menu event... */
while (!Quit && ((num_bytes = sock_recv_string(sock, buf, sizeof(buf)-1)) >= 0)) {
if (num_bytes == 0) {
ProcInfo *p;
/* wait for 1/10th of a second */
usleep(100000);
/* send an empty line every 3 seconds to make sure the server still exists */
if (keepalive_delay++ >= 30) {
keepalive_delay = 0;
if (sock_send_string(sock, "\n") < 0) {
break; /* Out of while loop */
}
}
/* check for a screen to show and procinfo deletion every second */
if (status_delay++ >= 10) {
status_delay = 0;
/* delete the ProcInfo from the queue */
for (p = proc_queue; p != NULL; p = p->next) {
ProcInfo *pn = p->next;
if ((pn != NULL) && (pn->shown)) {
p->next = pn->next;
free(pn);
}
}
/* deleting queue head is special */
if ((proc_queue != NULL) && (proc_queue->shown)) {
p = proc_queue;
proc_queue = proc_queue->next;
free(p);
}
/* look for a process to display, display it & mark it as shown */
for (p = proc_queue; p != NULL; p = p->next) {
p->shown |= show_procinfo_msg(p);
}
}
}
else {
process_response(buf);
}
}
if (!Quit)
report(RPT_ERR, "Server disconnected (or connection error)");
return 0;
}
/* EOF */
-139
View File
@@ -1,139 +0,0 @@
# lcdexec LCDproc client configuration file
## general options for lcdexec ##
[lcdexec]
# address of the LCDd server to connect to
Address=localhost
# Port of the server to connect to
Port=13666
# set reporting level
ReportLevel=2
# report to to syslog ?
ReportToSyslog=false
# run in foreground [default: false; legal: true, false]
Foreground=false
# PidFile location when running as daemon [default: /var/run/lcdexec.pid]
#PidFile=/var/run/lcdexec.pid
# shell to use for executing programsi
# [default: $SHELL or /bin/sh; legal: any shell that understands: -c COMMAND]
#Shell=/bin/sh
# display name for the main menu [default: lcdexec HOST]
#DisplayName=lcdexec
# main menu definition
[MainMenu]
# the Entry=... lines (one for each menu entry) tell it is a menu definition
Entry=CmdA
Entry=CmdB
Entry=MenuC
# definition of a command
[CmdA]
# name to display in the menu instead of the section name
DisplayName="You can say A"
# the exec=... line tells that it is a command
Exec="echo a"
# show a temporary feedback screen upon completion [default: no; legal: yes, no]
Feedback= yes
[CmdB]
DisplayName="Or you can say B"
Exec="echo b"
# definition of a menu
# a menu contains an Entry=... line for each menu entry
[MenuC]
DisplayName="A menu"
Entry=CmdP
Entry=CmdQ
[CmdP]
DisplayName=P
Exec="echo P"
[CmdQ]
DisplayName="Show environment"
Exec="env"
# Now you can change parameters for commands within lcdexec.
# Parameters are handed to the program as environment variables;
# so they can be easily used in the Exec=... line as $XXX
# (e.g. "echo $SLIDER_ARG").
# Please note: commands with parameters get an action entry
# added to end of the parameter menu automatically.
# Activating this action named "Apply!" will execute the program.
# This is IMHO not ideal, but the best idea I could come up with.
# I'm open for ideas to improve it.
# Here's how paramters get defined:
Parameter=SLIDER_ARG
Parameter=RING_ARG
Parameter=NUMERIC_ARG
Parameter=ALPHA_ARG
Parameter=CHECKBOX_ARG
Parameter=IP_ARG
[SLIDER_ARG]
DisplayName="Slider"
# Type of argument widget [legal: Slider, Checkbox, Ring, Numeric, Alpha, IP]
Type=Slider
# inital value of the argument
Value=5
# options depending on the widget type
MinValue=0
MaxValue=10
[CHECKBOX_ARG]
DisplayName="Checkbox"
Type=Checkbox
Value=on
AllowGray=yes
# replacement texts for the possible values
OffText="off"
OnText="on"
GrayText="gray"
[RING_ARG]
DisplayName="Ring"
Type=Ring
Value=0
# list of alternative strings to choose from
String=Eins
String=Zwei
String=Drei
[NUMERIC_ARG]
DisplayName="Numeric"
Type=Numeric
Value=5
MinValue=0
MaxValue=10
[ALPHA_ARG]
DisplayName="Alpha"
Type=Alpha
# range of characters allowed [default: "ABCDEFGHIJKLMNOPQRSTUVWXYZ"]
AllowedChars = "+-0123456789ABCDEF"
Value=5
MinLength=0
MaxLength=10
[IP_ARG]
DisplayName="IP"
Type=IP
Value=10.230.2.2
v6=no
# Ideas for further extensions (patches welcome):
# - shell selectable in command sections
# - display configurable result of a command on the display
# - jump to other menus depending on the output/result of a command
# EOF
-641
View File
@@ -1,641 +0,0 @@
/** \file clients/lcdexec/menu.c
* Menu parsing and building functions for the \c lcdexec client
*/
/* This file is part of lcdexec, an LCDproc client.
*
* This file is released under the GNU General Public License. Refer to the
* COPYING file distributed with this package.
*
* Copyright (c) 2002, Joris Robijn
* Copyright (c) 2006-7, Peter Marschall
*/
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <strings.h>
#include <stdlib.h>
#include "shared/report.h"
#include "shared/configfile.h"
#include "shared/sockets.h"
#include "menu.h"
/* names for boolean and tristate values */
static char *boolValueName[] = { "false", "true" };
static char *triGrayValueName[] = { "off", "on", "gray" };
/** recursively read the menu hierarchy */
MenuEntry *menu_read(MenuEntry *parent, const char *name)
{
static int id = 0;
if ((name != NULL) && (config_has_section(name))) {
MenuEntry *me = calloc(1, sizeof(MenuEntry)); // auto-NULL elements
if (me == NULL)
return NULL;
// set common entries
me->id = id++;
me->name = strdup(name);
if (me->name == NULL) {
//menu_free(me);
return NULL;
}
me->displayname = strdup(config_get_string(name, "DisplayName", 0, name));
if (me->displayname == NULL) {
//menu_free(me);
return NULL;
}
me->parent = parent;
me->next = NULL;
me->children = NULL;
me->numChildren = 0;
if (config_get_string(name, "Entry", 0, NULL) != NULL) {
MenuEntry **addr = &me->children;
const char *entryname;
// it is a sub-menu
me->type = MT_MENU;
// read menu entries
while ((entryname = config_get_string(name, "Entry", me->numChildren, NULL)) != NULL) {
MenuEntry *entry = menu_read(me, entryname);
if (entry == NULL) {
//menu_free(me);
return NULL;
}
me->numChildren++;
*addr = entry;
addr = &entry->next;
}
}
else if (config_get_string(name, "Exec", 0, NULL) != NULL) {
MenuEntry **addr = &me->children;
const char *entryname;
// it's a command to execute
me->type = MT_EXEC;
me->data.exec.command = strdup(config_get_string(name, "Exec", 0, ""));
if (me->data.exec.command == NULL) {
//menu_free(me);
return NULL;
}
me->data.exec.feedback = config_get_bool(name, "Feedback", 0, 0);
// try to read parameters
while ((entryname = config_get_string(name, "Parameter", me->numChildren, NULL)) != NULL) {
MenuEntry *entry = menu_read(me, entryname);
if (entry == NULL) {
//menu_free(me);
return NULL;
}
me->numChildren++;
*addr = entry;
addr = &entry->next;
}
// automagically add an "Apply ?" action
if ((me->numChildren > 0) && (addr != NULL))
*addr = menu_read(me, NULL);
}
else if (config_get_string(name, "Type", 0, NULL) != NULL) {
// it's a command parameter
const char *type;
type = config_get_string(name, "Type", 0, "");
if (strcasecmp(type, "slider") == 0) {
char buf[35];
me->type = MT_ARG_SLIDER;
me->data.slider.value = config_get_int(name, "Value", 0, 0);
me->data.slider.minval = config_get_int(name, "MinValue", 0, 0);
me->data.slider.maxval = config_get_int(name, "MaxValue", 0, 1000);
sprintf(buf, "%d", me->data.slider.minval);
me->data.slider.mintext = strdup(config_get_string(name, "MinText", 0, buf));
sprintf(buf, "%d", me->data.slider.maxval);
me->data.slider.maxtext = strdup(config_get_string(name, "MaxText", 0, buf));
me->data.slider.stepsize = config_get_int(name, "StepSize", 0, 1);
}
else if (strcasecmp(type, "ring") == 0) {
const char *tmp;
int numStrings = 0;
int i = 0;
me->type = MT_ARG_RING;
me->data.ring.value = config_get_int(name, "Value", 0, 0);
numStrings = config_has_key(name, "String");
me->data.ring.strings = calloc(sizeof(char *), numStrings+1);
me->data.ring.strings[numStrings] = NULL;
while ((tmp = config_get_string(name, "String", i, NULL)) != NULL) {
me->data.ring.strings[i] = strdup(tmp);
i++;
}
me->data.ring.strings[i] = NULL;
}
else if (strcasecmp(type, "numeric") == 0) {
me->type = MT_ARG_NUMERIC;
me->data.numeric.value = config_get_int(name, "Value", 0, 0);
me->data.numeric.minval = config_get_int(name, "MinValue", 0, 0);
me->data.numeric.maxval = config_get_int(name, "MaxValue", 0, 1000);
}
else if (strcasecmp(type, "alpha") == 0) {
me->type = MT_ARG_ALPHA;
me->data.alpha.value = strdup(config_get_string(name, "Value", 0, ""));
me->data.alpha.minlen = config_get_int(name, "MinLength", 0, 0);
me->data.alpha.maxlen = config_get_int(name, "MaxLength", 0, 100);
me->data.alpha.allowed = strdup(config_get_string(name, "AllowedChars", 0,
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"));
}
else if (strcasecmp(type, "ip") == 0) {
me->type = MT_ARG_IP;
me->data.ip.value = strdup(config_get_string(name, "Value", 0, ""));
me->data.ip.v6 = config_get_bool(name, "Value", 0, 0);
}
else if (strcasecmp(type, "checkbox") == 0) {
const char *tmp;
me->type = MT_ARG_CHECKBOX;
me->data.checkbox.allow_gray = config_get_bool(name, "AllowGray", 0, 0);
me->data.checkbox.value = (me->data.checkbox.allow_gray)
? config_get_tristate(name, "Value", 0, "gray", 0)
: config_get_bool(name, "Value", 0, 0);
// get replacement strings for different values
tmp = config_get_string(name, "OffText", 0, NULL);
me->data.checkbox.map[0] = (tmp != NULL) ? strdup(tmp) : NULL;
tmp = config_get_string(name, "OnText", 0, NULL);
me->data.checkbox.map[1] = (tmp != NULL) ? strdup(tmp) : NULL;
tmp = config_get_string(name, "GrayText", 0, NULL);
me->data.checkbox.map[2] = (tmp != NULL) ? strdup(tmp) : NULL;
}
else {
report(RPT_DEBUG, "illegal parameter type");
//menu_free(me);
return NULL;
}
}
else {
report(RPT_DEBUG, "unknown menu entry type");
//menu_free(me);
return NULL;
}
return me;
}
else {
/* the magic stuff: if name is NULL and parent is an EXEC entry,
* then generate an Action entry with the name "Apply" */
if ((name == NULL) && (parent != NULL) && (parent->type = MT_EXEC)) {
MenuEntry *me = calloc(1, sizeof(MenuEntry)); // auto-NULL elements
if (me == NULL)
return NULL;
// set common entries
me->id = id++;
me->name = malloc(strlen(parent->name) + 10);
if (me->name == NULL) {
//menu_free(me);
return NULL;
}
strcpy(me->name, "Apply_");
strcat(me->name, parent->name);
me->displayname = strdup("Apply!");
if (me->displayname == NULL) {
//menu_free(me);
return NULL;
}
me->parent = parent;
me->next = NULL;
me->children = NULL;
me->numChildren = 0;
me->type = MT_ARG_ACTION | MT_AUTOMATIC;
return me;
}
}
return NULL;
}
/** create LCDproc commands for the menu entry hierarchy and send it to the server */
int menu_sock_send(MenuEntry *me, MenuEntry *parent, int sock)
{
if ((me != NULL) && (sock > 0)) {
char parent_id[12];
// set parent_id depending on the parent given
if ((parent != NULL) && (parent->id != 0))
sprintf(parent_id, "%d", parent->id);
else
strcpy(parent_id, "");
switch (me->type) {
MenuEntry *entry;
case MT_MENU:
// don't create a separate entry for the main menu
if ((parent != NULL) && (me->id != 0)) {
if (sock_printf(sock, "menu_add_item \"%s\" \"%d\" menu \"%s\"\n",
parent_id, me->id, me->displayname) < 0)
return -1;
}
// recursively do it for the menu's sub-menus
for (entry = me->children; entry != NULL; entry = entry->next) {
if (menu_sock_send(entry, me, sock) < 0)
return -1;
}
break;
case MT_EXEC:
if (me->children == NULL) {
if (sock_printf(sock, "menu_add_item \"%s\" \"%d\" action \"%s\"\n",
parent_id, me->id, me->displayname) < 0)
return -1;
if (sock_printf(sock, "menu_set_item \"%s\" \"%d\" -menu_result quit\n",
parent_id, me->id) < 0)
return -1;
}
else {
if ((parent != NULL) && (me->id != 0)) {
if (sock_printf(sock, "menu_add_item \"%s\" \"%d\" menu \"%s\"\n",
parent_id, me->id, me->displayname) < 0)
return -1;
}
// (recursively) do it for the entry's parameters
for (entry = me->children; entry != NULL; entry = entry->next) {
if (menu_sock_send(entry, me, sock) < 0)
return -1;
}
}
break;
case MT_ARG_SLIDER:
if (sock_printf(sock, "menu_add_item \"%s\" \"%d\" slider -text \"%s\""
" -value %d -minvalue %d -maxvalue %d"
" -mintext \"%s\" -maxtext \"%s\" -stepsize %d\n",
parent_id, me->id, me->displayname,
me->data.slider.value,
me->data.slider.minval,
me->data.slider.maxval,
me->data.slider.mintext,
me->data.slider.maxtext,
me->data.slider.stepsize) <0)
return -1;
if (me->next == NULL) {
if (sock_printf(sock, "menu_set_item \"%s\" \"%d\" -next _quit_\n",
parent_id, me->id) < 0)
return -1;
}
break;
case MT_ARG_RING:
{
int i;
char *tmp = strdup("");
// join all strings with TAB as separator
for (i = 0; me->data.ring.strings[i] != NULL; i++) {
tmp = realloc(tmp, strlen(tmp) + 1 +
strlen(me->data.ring.strings[i]) + 1);
if (tmp[0] != '\0')
strcat(tmp, "\t");
strcat(tmp, me->data.ring.strings[i]);
}
if (sock_printf(sock, "menu_add_item \"%s\" \"%d\" ring -text \"%s\""
" -value %d -strings \"%s\"\n",
parent_id, me->id, me->displayname,
me->data.ring.value,
tmp) < 0)
return -1;
}
if (me->next == NULL) {
if (sock_printf(sock, "menu_set_item \"%s\" \"%d\" -next _quit_\n",
parent_id, me->id) < 0)
return -1;
}
break;
case MT_ARG_NUMERIC:
if (sock_printf(sock, "menu_add_item \"%s\" \"%d\" numeric -text \"%s\""
" -value %d -minvalue %d -maxvalue %d\n",
parent_id, me->id, me->displayname,
me->data.numeric.value,
me->data.numeric.minval,
me->data.numeric.maxval) < 0)
return -1;
if (me->next == NULL) {
if (sock_printf(sock, "menu_set_item \"%s\" \"%d\" -next _quit_\n",
parent_id, me->id) < 0)
return -1;
}
break;
case MT_ARG_ALPHA:
if (sock_printf(sock, "menu_add_item \"%s\" \"%d\" alpha -text \"%s\""
" -value \"%s\" -minlength %d -maxlength %d"
" -allow_caps false -allow_noncaps false"
" -allow_numbers false -allowed_extra \"%s\"\n",
parent_id, me->id, me->displayname,
me->data.alpha.value,
me->data.alpha.minlen,
me->data.alpha.maxlen,
me->data.alpha.allowed) <0)
return -1;
if (me->next == NULL) {
if (sock_printf(sock, "menu_set_item \"%s\" \"%d\" -next _quit_\n",
parent_id, me->id) < 0)
return -1;
}
break;
case MT_ARG_IP:
if (sock_printf(sock, "menu_add_item \"%s\" \"%d\" ip -text \"%s\""
" -value \"%s\" -v6 %s\n",
parent_id, me->id, me->displayname,
me->data.ip.value,
boolValueName[me->data.ip.v6]) < 0)
return -1;
if (me->next == NULL) {
if (sock_printf(sock, "menu_set_item \"%s\" \"%d\" -next _quit_\n",
parent_id, me->id) < 0)
return -1;
}
break;
case MT_ARG_CHECKBOX:
if (sock_printf(sock, "menu_add_item \"%s\" \"%d\" checkbox -text \"%s\""
" -value %s -allow_gray %s\n",
parent_id, me->id, me->displayname,
triGrayValueName[me->data.checkbox.value],
boolValueName[me->data.checkbox.allow_gray]) < 0)
return -1;
if (me->next == NULL) {
if (sock_printf(sock, "menu_set_item \"%s\" \"%d\" -next _quit_\n",
parent_id, me->id) < 0)
return -1;
}
break;
case MT_AUTOMATIC:
case MT_ARG_ACTION:
if (sock_printf(sock, "menu_add_item \"%s\" \"%d\" action \"%s\"\n",
parent_id, me->id, me->displayname) < 0)
return -1;
if (sock_printf(sock, "menu_set_item \"%s\" \"%d\" -menu_result quit\n",
parent_id, me->id) < 0)
return -1;
break;
default:
return -1;
}
return 0;
}
return -1;
}
/** find menu entry by its id */
MenuEntry *menu_find_by_id(MenuEntry *me, int id)
{
if (me != NULL) {
if (me->id == id)
return me;
if ((me->type == MT_MENU) || (me->type == MT_EXEC)) {
MenuEntry *entry;
for (entry = me->children; entry != NULL; entry = entry->next) {
MenuEntry *result = menu_find_by_id(entry, id);
if (result != NULL)
return result;
}
}
}
return NULL;
}
/** return command of a menu entry */
const char *menu_command(MenuEntry *me)
{
if ((me != NULL) && (me->type == MT_EXEC))
return me->data.exec.command;
return NULL;
}
/** free menu entry hierarchy */
void menu_free(MenuEntry *me)
{
if (me != NULL) {
MenuEntry *entry;
int i;
switch (me->type) {
case MT_EXEC:
if (me->data.exec.command != NULL)
free(me->data.exec.command);
me->data.exec.command = NULL;
/* fall through */
case MT_MENU:
for (entry = me->children; entry != NULL; ) {
MenuEntry *old = entry;
entry = entry->next;
old->next = NULL;
menu_free(old);
}
me->children = NULL;
break;
case MT_ARG_SLIDER:
if (me->data.slider.mintext != NULL)
free(me->data.slider.mintext);
me->data.slider.mintext = NULL;
if (me->data.slider.maxtext != NULL)
free(me->data.slider.maxtext);
me->data.slider.maxtext = NULL;
break;
case MT_ARG_RING:
if (me->data.ring.strings != NULL) {
int i;
for (i = 0; me->data.ring.strings[i] != NULL; i++)
free(me->data.ring.strings[i]);
free(me->data.ring.strings);
me->data.ring.strings = NULL;
}
break;
case MT_ARG_ALPHA:
if (me->data.alpha.value != NULL)
free(me->data.alpha.value);
me->data.alpha.value = NULL;
if (me->data.alpha.allowed != NULL)
free(me->data.alpha.allowed);
me->data.alpha.allowed = NULL;
break;
case MT_ARG_IP:
if (me->data.ip.value != NULL)
free(me->data.ip.value);
me->data.ip.value = NULL;
break;
case MT_ARG_CHECKBOX:
for (i = 0; i < sizeof(me->data.checkbox.map)/sizeof(me->data.checkbox.map[0]); i++) {
if (me->data.checkbox.map[i] != NULL) {
free(me->data.checkbox.map[i]);
me->data.checkbox.map[i] = NULL;
}
}
default:
break;
}
if (me->name != NULL)
free(me->name);
me->name = NULL;
if (me->displayname != NULL)
free(me->displayname);
me->displayname = NULL;
me->type = MT_UNKNOWN;
free(me);
}
}
#if defined(DEBUG)
/** dump menu entry hierarchy to screen */
void menu_dump(MenuEntry *me)
{
if (me != NULL) {
/* the quick way out */
if (me->type & MT_AUTOMATIC)
return;
report(RPT_DEBUG, "# menu ID: %d", me->id);
report(RPT_DEBUG, "[%s]", me->name);
if (me->displayname != NULL)
report(RPT_DEBUG, "DisplayName=\"%s\"", me->displayname);
switch (me->type) {
MenuEntry *entry;
case MT_MENU:
// dump menu entry references
for (entry = me->children; entry != NULL; entry = entry->next)
report(RPT_DEBUG, "Entry=%s", entry->name);
report(RPT_DEBUG, "");
// recursively walk through sub-menus
for (entry = me->children; entry != NULL; entry = entry->next)
menu_dump(entry);
break;
case MT_EXEC:
report(RPT_DEBUG, "Exec=\"%s\"", me->data.exec.command);
report(RPT_DEBUG, "Feedback=%s", boolValueName[me->data.exec.feedback]);
// dump entry's parameter referencess
for (entry = me->children; entry != NULL; entry = entry->next)
report(RPT_DEBUG, "Parameter=%s", entry->name);
report(RPT_DEBUG, "");
// dump entry's parameters
for (entry = me->children; entry != NULL; entry = entry->next)
menu_dump(entry);
break;
case MT_ARG_SLIDER:
report(RPT_DEBUG, "Type=slider");
report(RPT_DEBUG, "Value=%d", me->data.slider.value);
report(RPT_DEBUG, "MinValue=%d", me->data.slider.minval);
report(RPT_DEBUG, "MaxValue=%d", me->data.slider.maxval);
report(RPT_DEBUG, "Stepsize=%d", me->data.slider.stepsize);
report(RPT_DEBUG, "MinText=%s", me->data.slider.mintext);
report(RPT_DEBUG, "MaxText=%s", me->data.slider.maxtext);
report(RPT_DEBUG, "");
break;
case MT_ARG_RING:
report(RPT_DEBUG, "Type=ring");
report(RPT_DEBUG, "Value: %d", me->data.ring.value);
{
int i;
for (i = 0; me->data.ring.strings[i] != NULL; i++)
report(RPT_DEBUG, "String=\"%s\"", me->data.ring.strings[i]);
}
report(RPT_DEBUG, "");
break;
case MT_ARG_NUMERIC:
report(RPT_DEBUG, "Type=numeric");
report(RPT_DEBUG, "Value=%d", me->data.numeric.value);
report(RPT_DEBUG, "MinValue=%d", me->data.numeric.minval);
report(RPT_DEBUG, "MaxValue=%d", me->data.numeric.maxval);
report(RPT_DEBUG, "");
break;
case MT_ARG_ALPHA:
report(RPT_DEBUG, "Type:=lpha");
report(RPT_DEBUG, "Value=\"%s\"", me->data.alpha.value);
report(RPT_DEBUG, "AllowedChars=\"%s\"", me->data.alpha.allowed);
report(RPT_DEBUG, "");
break;
case MT_ARG_IP:
report(RPT_DEBUG, "Type=ip");
report(RPT_DEBUG, "Value=\"%s\"", me->data.ip.value);
report(RPT_DEBUG, "V6=%s", boolValueName[me->data.ip.v6]);
report(RPT_DEBUG, "");
break;
case MT_ARG_CHECKBOX:
report(RPT_DEBUG, "Type=ip");
report(RPT_DEBUG, "Value=%s", triGrayValueName[me->data.checkbox.value]);
report(RPT_DEBUG, "AllowGray=%s", boolValueName[me->data.checkbox.allow_gray]);
if (me->data.checkbox.map[0] != NULL)
report(RPT_DEBUG, "OffText=%s", me->data.checkbox.map[0]);
if (me->data.checkbox.map[1] != NULL)
report(RPT_DEBUG, "OnText=%s", me->data.checkbox.map[1]);
if (me->data.checkbox.map[2] != NULL)
report(RPT_DEBUG, "GrayText=%s", me->data.checkbox.map[2]);
report(RPT_DEBUG, "");
break;
default:
report(RPT_DEBUG, "ERROR: unknown menu entry type");
break;
}
}
}
#endif
/* EOF */
-105
View File
@@ -1,105 +0,0 @@
/** \file clients/lcdexec/menu.h
* Declare constants, data types and functions for menu functions in clients/lcdexec/menu.c.
*/
/* This file is part of lcdexec, an LCDproc client.
*
* This file is released under the GNU General Public License. Refer to the
* COPYING file distributed with this package.
*
* Copyright (c) 2002, Joris Robijn
* Copyright (c) 2006-7, Peter Marschall
*/
#ifndef LCDEXEC_MENU_H
#define LCDEXEC_MENU_H
/* boolean values */
#ifndef TRUE
# define TRUE 1
#endif
#ifndef FALSE
# define FALSE 0
#endif
/** Symbolic names for the types of a MenuEntry */
typedef enum {
MT_UNKNOWN = 0x00, /**< Unknown MenuEntry type. */
MT_MENU = 0x10, /**< MenuEntry representing a menu. */
MT_EXEC = 0x20, /**< MenuEntry representing an executable command. */
MT_ARGUMENT = 0x40, /**< Mask denoting a parameter of any type */
MT_AUTOMATIC = 0x80, /**< BitFlag denoting automatically generated entries */
MT_ARG_SLIDER = 0x41, /**< MenuEntry representing a slider parameter. */
MT_ARG_RING = 0x42, /**< MenuEntry representing a ring parameter. */
MT_ARG_NUMERIC = 0x43, /**< MenuEntry representing a numeric input parameter. */
MT_ARG_ALPHA = 0x44, /**< MenuEntry representing a alpha input parameter. */
MT_ARG_IP = 0x45, /**< MenuEntry representing a IP input parameter. */
MT_ARG_CHECKBOX = 0x46, /**< MenuEntry representing a checkbox input parameter. */
MT_ARG_ACTION = 0x47, /**< MenuEntry representing a checkbox input parameter. */
} MenuType;
/** Data structure to hold a menu entry in \c lcdexec */
typedef struct menu_entry {
// Variables necessary for multiple/all types
char *name; /**< Name of the menu entry (from section name). */
char *displayname; /**< Visible name of the entry. */
int id; /**< Internal ID of the entry. */
MenuType type; /**< Type of the entry. */
struct menu_entry *parent; /**< Parent menu entry. */
int numChildren; /**< # of child entries. */
struct menu_entry *children; /**< Subordinate menu entries (for type \c MT_MENU & \c MT_EXEC). */
struct menu_entry *next; /**< Next sibling menu entry (for type \c MT_MENU). */
// Variables specific to one special type
union data {
struct exec{ // elements necessary for type MT_EXEC
char *command; /**< Command to execute. */
int feedback; /**< Feedback flag. */
} exec;
struct slider { // elements necessary for type MT_ARG_SLIDER
int value; /**< Numeric value of slider. */
int minval; /**< Minimal allowed value. */
int maxval; /**< Maximal allowed value. */
int stepsize; /**< Increments/decrement for value. */
char *mintext; /**< Label for the min. value. */
char *maxtext; /**< Label for the max. value. */
} slider;
struct ring { // elements necessary for type MT_ARG_RING
int value; /**< Index into list of alternatives. */
char **strings; /**< List of alternatives. */
} ring;
struct numeric { // elements necessary for type MT_ARG_NUMERIC
int value; /**< Numeric input value. */
int minval; /**< Minimal allowed value. */
int maxval; /**< Maximal allowed value. */
} numeric;
struct alpha { // elements necessary for type MT_ARG_ALPHA
char *value; /**< Text value. */
int minlen; /**< Maximal allowed length. */
int maxlen; /**< Minimal required length. */
char *allowed; /**< Characters allowed in input. */
} alpha;
struct ip { // elements necessary for type MT_ARG_IP
char *value; /**< IP address value. */
int v6; /**< Flag: use IPv6 editing logic. */
} ip;
struct checkbox { // elements necessary for type MT_ARG_CHECKBOX
int value; /**< Checkbox value. */
int allow_gray; /**< Flag for tristate chechboxes. */
char *map[3]; /**< Replacement strings for each value. */
} checkbox;
} data;
} MenuEntry;
MenuEntry *menu_read(MenuEntry *parent, const char *name);
int menu_sock_send(MenuEntry *me, MenuEntry *parent, int sock);
MenuEntry *menu_find_by_id(MenuEntry *me, int id);
const char *menu_command(MenuEntry *me);
void menu_free(MenuEntry *me);
void menu_dump(MenuEntry *me);
#endif
-4
View File
@@ -1,4 +0,0 @@
.deps
Makefile
Makefile.in
lcdproc
-20
View File
@@ -1,20 +0,0 @@
## Process this file with automake to produce Makefile.in
sysconf_DATA = lcdproc.conf
bin_PROGRAMS = lcdproc
lcdproc_SOURCES = main.c main.h mode.c mode.h batt.c batt.h chrono.c chrono.h cpu.c cpu.h cpu_smp.c cpu_smp.h disk.c disk.h load.c load.h mem.c mem.h eyebox.c eyebox.h machine.h machine_Linux.c machine_OpenBSD.c machine_FreeBSD.c machine_NetBSD.c machine_Darwin.c machine_SunOS.c util.c util.h iface.c iface.h
lcdproc_LDADD = ../../shared/libLCDstuff.a
if DARWIN
AM_LDFLAGS = -framework CoreFoundation -framework IOKit
endif
AM_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/shared -DSYSCONFDIR=\"$(sysconfdir)\" -DPIDFILEDIR=\"$(pidfiledir)\"
EXTRA_DIST = $(sysconf_DATA)
## EOF
-158
View File
@@ -1,158 +0,0 @@
/** \file clients/lcdproc/batt.c
* Implements the 'battery' screen showing the APM battery status.
*/
/*-
* This file is part of lcdproc, the lcdproc client.
*
* This file is released under the GNU General Public License.
* Refer to the COPYING file distributed with this package.
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/utsname.h>
#include "shared/sockets.h"
#include "main.h"
#include "mode.h"
#include "batt.h"
#include "machine.h"
/** Map status code > status text */
typedef struct {
int status;
const char *name;
} NameTable;
/**
* Converts a numeric AC power status into a status text.
*
* \param status Numeric status as returned by machine_get_battstat
* \return Name of the status
*/
static const char *
ac_status(int status)
{
const NameTable ac_table[] = {
{ LCDP_AC_OFF, "Off" },
{ LCDP_AC_ON, "On" },
{ LCDP_AC_BACKUP, "Backup" },
{ LCDP_AC_UNKNOWN, "Unknown" },
{ 0, NULL }
};
int i;
for (i = 0; ac_table[i].name != NULL; i++)
if (status == ac_table[i].status)
return ac_table[i].name;
return ac_table[LCDP_AC_UNKNOWN].name;
}
/**
* Converts a numeric battery status into a status text.
*
* \param status Numeric status as returned by machine_get_battstat
* \return Name of the status
*/
static const char *
battery_status(int status)
{
const NameTable batt_table[] = {
{ LCDP_BATT_HIGH, "High" },
{ LCDP_BATT_LOW, "Low" },
{ LCDP_BATT_CRITICAL, "Critical" },
{ LCDP_BATT_CHARGING, "Charging" },
{ LCDP_BATT_ABSENT, "Absent" },
{ LCDP_BATT_UNKNOWN, "Unknown" },
{ 0, NULL }
};
int i;
for (i = 0; batt_table[i].name != NULL; i++)
if (status == batt_table[i].status)
return batt_table[i].name;
return batt_table[LCDP_AC_UNKNOWN].name;
}
/**
* Battery Screen shows apm battery status...
*
*\verbatim
*
* +--------------------+ +--------------------+
* |## AC: 100%: myho #@| |## AC: 100%: myho #@|
* |AC: On | |AC, Batt: Absent |
* |Batt: Absent | +--------------------+
* |E------------------F|
* +--------------------+
*
*\endverbatim
*
* \param rep Time since last screen update
* \param display 1 if screen is visible or data should be updated
* \param flags_ptr Mode flags
* \return Always 0
*/
int
battery_screen(int rep, int display, int *flags_ptr)
{
int acstat = 0, battstat = 0, percent = 0;
int gauge_wid = lcd_wid - 2;
if ((*flags_ptr & INITIALIZED) == 0) {
*flags_ptr |= INITIALIZED;
sock_send_string(sock, "screen_add B\n");
sock_printf(sock, "screen_set B -name {APM stats: %s}\n", get_hostname());
sock_send_string(sock, "widget_add B title title\n");
sock_printf(sock, "widget_set B title {LCDPROC %s}\n", version);
sock_send_string(sock, "widget_add B one string\n");
if (lcd_hgt >= 4) {
sock_send_string(sock, "widget_add B two string\n");
sock_send_string(sock, "widget_add B three string\n");
sock_send_string(sock, "widget_add B gauge hbar\n");
sock_send_string(sock, "widget_set B one 1 2 {AC: Unknown}\n");
sock_send_string(sock, "widget_set B two 1 3 {Batt: Unknown}\n");
sock_printf(sock, "widget_set B three 1 4 {E%*sF}\n", gauge_wid, "");
sock_send_string(sock, "widget_set B gauge 2 4 0\n");
}
}
machine_get_battstat(&acstat, &battstat, &percent);
if (display) {
char tmp[20];
if (percent >= 0)
sprintf(tmp, "%d%%", percent);
else
sprintf(tmp, "??%%");
sock_printf(sock, "widget_set B title {%s: %s: %s}\n",
(acstat == LCDP_AC_ON && battstat == LCDP_BATT_ABSENT) ? "AC" : "Batt",
tmp, get_hostname());
if (lcd_hgt >= 4) { /* 4-line version of the screen */
sock_printf(sock, "widget_set B one 1 2 {AC: %s}\n", ac_status(acstat));
sock_printf(sock, "widget_set B two 1 3 {Batt: %s}\n", battery_status(battstat));
if (percent > 0)
sock_printf(sock, "widget_set B gauge 2 4 %d\n",
(percent * gauge_wid * lcd_cellwid) / 100);
}
else { /* two-line version of the screen */
sock_printf(sock, "widget_set B one 1 2 {%sBatt: %s}\n",
(acstat == LCDP_AC_ON) ? "AC, " : "",
battery_status(battstat));
}
}
return 0;
}
-6
View File
@@ -1,6 +0,0 @@
#ifndef BATT_H
#define BATT_H
int battery_screen(int rep, int display, int *flags_ptr);
#endif
-528
View File
@@ -1,528 +0,0 @@
/** \file clients/lcdproc/chrono.c
* Implements the 'OldTime', 'TimeDate', 'Uptime', 'MiniClock', and 'BigClock'
* screens.
*/
/*-
* This file is part of lcdproc, the lcdproc client.
*
* This file is released under the GNU General Public License.
* Refer to the COPYING file distributed with this package.
*/
#include <sys/types.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/utsname.h>
#include <limits.h>
#include <sys/param.h>
#include <errno.h>
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#if TIME_WITH_SYS_TIME
# include <sys/time.h>
# include <time.h>
#else
# if HAVE_SYS_TIME_H
# include <sys/time.h>
# else
# include <time.h>
# endif
#endif
#include "shared/configfile.h"
#include "shared/sockets.h"
#include "main.h"
#include "mode.h"
#include "machine.h"
#include "chrono.h"
static char *tickTime(char *time, int heartbeat);
/**
* TimeDate Screen displays current time and date, uptime, OS ver...
*
*\verbatim
*
* +--------------------+ +--------------------+
* |## Linux 2.6.11 ###@| |### TIME: myhost ##@|
* |Up xxx days hh:mm:ss| |17.05.2005 11:32:57a|
* | Wed May 17, 1998 | +--------------------+
* |11:32:57a 100% idle|
* +--------------------+
*
*\endverbatim
*
* \param rep Time since last screen update
* \param display 1 if screen is visible or data should be updated
* \param flags_ptr Mode flags
* \return Always 0
*/
int
time_screen(int rep, int display, int *flags_ptr)
{
char now[40];
char today[40];
int xoffs;
int days, hour, min, sec;
static int heartbeat = 0;
static const char *timeFormat = NULL;
static const char *dateFormat = NULL;
time_t thetime;
struct tm *rtime;
double uptime, idle;
if ((*flags_ptr & INITIALIZED) == 0) {
*flags_ptr |= INITIALIZED;
/* get config values */
timeFormat = config_get_string("TimeDate", "TimeFormat", 0, "%H:%M:%S");
dateFormat = config_get_string("TimeDate", "DateFormat", 0, "%b %d %Y");
sock_send_string(sock, "screen_add T\n");
sock_printf(sock, "screen_set T -name {Time Screen: %s}\n", get_hostname());
sock_send_string(sock, "widget_add T title title\n");
sock_send_string(sock, "widget_add T one string\n");
if (lcd_hgt >= 4) {
sock_send_string(sock, "widget_add T two string\n");
sock_send_string(sock, "widget_add T three string\n");
/* write title bar: OS name, OS version, hostname */
sock_printf(sock, "widget_set T title {%s %s: %s}\n",
get_sysname(), get_sysrelease(), get_hostname());
}
else {
/* write title bar: hostname */
sock_printf(sock, "widget_set T title {TIME: %s}\n", get_hostname());
}
}
/* toggle colon display */
heartbeat ^= 1;
time(&thetime);
rtime = localtime(&thetime);
if (strftime(today, sizeof(today), dateFormat, rtime) == 0)
*today = '\0';
if (strftime(now, sizeof(now), timeFormat, rtime) == 0)
*now = '\0';
tickTime(now, heartbeat);
if (lcd_hgt >= 4) {
char tmp[40]; /* should be large enough */
machine_get_uptime(&uptime, &idle);
/* display the uptime... */
days = (int) uptime / 86400;
hour = ((int) uptime % 86400) / 3600;
min = ((int) uptime % 3600) / 60;
sec = ((int) uptime % 60);
if (lcd_wid >= 20)
sprintf(tmp, "Up %3d day%s %02d:%02d:%02d",
days, ((days != 1) ? "s" : ""), hour, min, sec);
else
sprintf(tmp, "Up %dd %02d:%02d:%02d", days, hour, min, sec);
xoffs = (lcd_wid > strlen(tmp)) ? ((lcd_wid - strlen(tmp)) / 2) + 1 : 1;
if (display)
sock_printf(sock, "widget_set T one %i 2 {%s}\n", xoffs, tmp);
/* display the date */
xoffs = (lcd_wid > strlen(today)) ? ((lcd_wid - strlen(today)) / 2) + 1 : 1;
if (display)
sock_printf(sock, "widget_set T two %i 3 {%s}\n", xoffs, today);
/* display the time & idle time... */
sprintf(tmp, "%s %3i%% idle", now, (int) idle);
xoffs = (lcd_wid > strlen(tmp)) ? ((lcd_wid - strlen(tmp)) / 2) + 1 : 1;
if (display)
sock_printf(sock, "widget_set T three %i 4 {%s}\n", xoffs, tmp);
}
else { /* 2 line version of the screen */
xoffs = (lcd_wid > (strlen(today) + strlen(now) + 1))
? ((lcd_wid - ((strlen(today) + strlen(now) + 1))) / 2) + 1 : 1;
if (display)
sock_printf(sock, "widget_set T one %i 2 {%s %s}\n", xoffs, today, now);
}
return 0;
} /* End time_screen() */
/**
* OldTime Screen displays current time and date...
*
*\verbatim
*
* +--------------------+ +--------------------+
* |## DATE & TIME ####@| |### TIME: myhost ##@|
* | myhost | |2005-05-17 11:32:57a|
* |11:32:75a Wednesday,| +--------------------+
* | May 17, 2005 |
* +--------------------+
*
* Alternate 2-line version without the title bar:
*
* +----------------+
* | 2012-12-27 @|
* | 15:07:01 |
* +----------------+
*
*\endverbatim
*
* \param rep Time since last screen update
* \param display 1 if screen is visible or data should be updated
* \param flags_ptr Mode flags
* \return Always 0
*/
int
clock_screen(int rep, int display, int *flags_ptr)
{
char now[40];
char today[40];
int xoffs;
static int heartbeat = 0;
static int showTitle = 1;
static const char *timeFormat = NULL;
static const char *dateFormat = NULL;
time_t thetime;
struct tm *rtime;
if ((*flags_ptr & INITIALIZED) == 0) {
char tmp[257]; /* should be large enough for host name */
*flags_ptr |= INITIALIZED;
/* get config values */
timeFormat = config_get_string("OldTime", "TimeFormat", 0, "%H:%M:%S");
dateFormat = config_get_string("OldTime", "DateFormat", 0, "%b %d %Y");
showTitle = config_get_bool("OldTime", "ShowTitle", 0, 1);
sock_send_string(sock, "screen_add O\n");
sock_printf(sock, "screen_set O -name {Old Clock Screen: %s}\n", get_hostname());
if (!showTitle)
sock_send_string(sock, "screen_set O -heartbeat off\n");
sock_send_string(sock, "widget_add O one string\n");
if (lcd_hgt >= 4) {
sock_send_string(sock, "widget_add O title title\n");
sock_send_string(sock, "widget_add O two string\n");
sock_send_string(sock, "widget_add O three string\n");
sock_printf(sock, "widget_set O title {DATE & TIME}\n");
sprintf(tmp, "%s", get_hostname());
xoffs = (lcd_wid > strlen(tmp)) ? (((lcd_wid - strlen(tmp)) / 2) + 1) : 1;
sock_printf(sock, "widget_set O one %i 2 {%s}\n", xoffs, tmp);
}
else {
if (showTitle) {
sock_send_string(sock, "widget_add O title title\n");
sock_printf(sock, "widget_set O title {TIME: %s}\n", get_hostname());
}
else {
sock_send_string(sock, "widget_add O two string\n");
}
}
}
/* toggle colon display */
heartbeat ^= 1;
time(&thetime);
rtime = localtime(&thetime);
if (strftime(today, sizeof(today), dateFormat, rtime) == 0)
*today = '\0';
if (strftime(now, sizeof(now), timeFormat, rtime) == 0)
*now = '\0';
tickTime(now, heartbeat);
if (lcd_hgt >= 4) { /* 4-line version of the screen */
xoffs = (lcd_wid > strlen(today)) ? ((lcd_wid - strlen(today)) / 2) + 1 : 1;
if (display)
sock_printf(sock, "widget_set O two %i 3 {%s}\n", xoffs, today);
xoffs = (lcd_wid > strlen(now)) ? ((lcd_wid - strlen(now)) / 2) + 1 : 1;
if (display)
sock_printf(sock, "widget_set O three %i 4 {%s}\n", xoffs, now);
}
else { /* 2-line version of the screen */
if (showTitle) {
xoffs = (lcd_wid > (strlen(today) + strlen(now) + 1))
? ((lcd_wid - ((strlen(today) + strlen(now) + 1))) / 2) + 1 : 1;
if (display)
sock_printf(sock, "widget_set O one %i 2 {%s %s}\n", xoffs, today, now);
}
else {
xoffs = (lcd_wid > strlen(today)) ? ((lcd_wid - strlen(today)) / 2) + 1 : 1;
if (display)
sock_printf(sock, "widget_set O one %i 1 {%s}\n", xoffs, today);
xoffs = (lcd_wid > strlen(now)) ? ((lcd_wid - strlen(now)) / 2) + 1 : 1;
if (display)
sock_printf(sock, "widget_set O two %i 2 {%s}\n", xoffs, now);
}
}
return 0;
} /* End clock_screen() */
/**
* Uptime Screen shows info about system uptime and OS version
*
*\verbatim
*
* +--------------------+ +--------------------+
* |## SYSTEM UPTIME ##@| |# Linux 2.6.11: my#@|
* | myhost | | xxx days hh:mm:ss |
* | xxx days hh:mm:ss | +--------------------+
* | Linux 2.6.11 |
* +--------------------+
*
*\endverbatim
*
* \param rep Time since last screen update
* \param display 1 if screen is visible or data should be updated
* \param flags_ptr Mode flags
* \return Always 0
*/
int
uptime_screen(int rep, int display, int *flags_ptr)
{
int xoffs;
int days, hour, min, sec;
double uptime, idle;
static int heartbeat = 0;
char tmp[257]; /* should be large enough for host name */
if ((*flags_ptr & INITIALIZED) == 0) {
*flags_ptr |= INITIALIZED;
sock_send_string(sock, "screen_add U\n");
sock_printf(sock, "screen_set U -name {Uptime Screen: %s}\n", get_hostname());
sock_send_string(sock, "widget_add U title title\n");
if (lcd_hgt >= 4) {
sock_send_string(sock, "widget_add U one string\n");
sock_send_string(sock, "widget_add U two string\n");
sock_send_string(sock, "widget_add U three string\n");
sock_send_string(sock, "widget_set U title {SYSTEM UPTIME}\n");
sprintf(tmp, "%s", get_hostname());
xoffs = (lcd_wid > strlen(tmp)) ? (((lcd_wid - strlen(tmp)) / 2) + 1) : 1;
sock_printf(sock, "widget_set U one %i 2 {%s}\n", xoffs, tmp);
sprintf(tmp, "%s %s", get_sysname(), get_sysrelease());
xoffs = (lcd_wid > strlen(tmp)) ? (((lcd_wid - strlen(tmp)) / 2) + 1) : 1;
sock_printf(sock, "widget_set U three %i 4 {%s}\n", xoffs, tmp);
}
else {
sock_send_string(sock, "widget_add U one string\n");
sock_printf(sock, "widget_set U title {%s %s: %s}\n",
get_sysname(), get_sysrelease(), get_hostname());
}
}
/* toggle colon display */
heartbeat ^= 1;
machine_get_uptime(&uptime, &idle);
days = (int) uptime / 86400;
hour = ((int) uptime % 86400) / 3600;
min = ((int) uptime % 3600) / 60;
sec = ((int) uptime % 60);
if (lcd_wid >= 20)
sprintf(tmp, "%d day%s %02d:%02d:%02d",
days, ((days != 1) ? "s" : ""), hour, min, sec);
else
sprintf(tmp, "%dd %02d:%02d:%02d", days, hour, min, sec);
if (display) {
xoffs = (lcd_wid > strlen(tmp)) ? (((lcd_wid - strlen(tmp)) / 2) + 1) : 1;
if (lcd_hgt >= 4)
sock_printf(sock, "widget_set U two %d 3 {%s}\n", xoffs, tmp);
else
sock_printf(sock, "widget_set U one %d 2 {%s}\n", xoffs, tmp);
}
return 0;
} /* End uptime_screen() */
/**
* Big Clock Screen displays current time...
*
*\verbatim
*
* +--------------------+
* | _ _ _ _ |
* | ||_ . _||_|. _| ||
* | ||_|. _| |.|_ ||
* | |
* +--------------------+
*
*\endverbatim
*
* \param rep Time since last screen update
* \param display 1 if screen is visible or data should be updated
* \param flags_ptr Mode flags
* \return Always 0
*/
int
big_clock_screen(int rep, int display, int *flags_ptr)
{
time_t thetime;
struct tm *rtime;
int pos[] = {1, 4, 8, 11, 15, 18};
char fulltxt[16];
static char old_fulltxt[16];
static int heartbeat = 0;
static int TwentyFourHour = 1;
int j = 0;
int digits = (lcd_wid >= 20) ? 6 : 4;
int xoffs = (lcd_wid + 1 - (pos[digits - 1] + 2)) / 2;
/* toggle colon display */
heartbeat ^= 1;
if ((*flags_ptr & INITIALIZED) == 0) {
*flags_ptr |= INITIALIZED;
sock_send_string(sock, "screen_add K\n");
sock_send_string(sock, "screen_set K -name {Big Clock Screen} -heartbeat off\n");
sock_send_string(sock, "widget_add K d0 num\n");
sock_send_string(sock, "widget_add K d1 num\n");
sock_send_string(sock, "widget_add K d2 num\n");
sock_send_string(sock, "widget_add K d3 num\n");
sock_send_string(sock, "widget_add K c0 num\n");
if (digits > 4) {
sock_send_string(sock, "widget_add K d4 num\n");
sock_send_string(sock, "widget_add K d5 num\n");
sock_send_string(sock, "widget_add K c1 num\n");
}
strcpy(old_fulltxt, " ");
}
time(&thetime);
rtime = localtime(&thetime);
sprintf(fulltxt, "%02d%02d%02d",
((TwentyFourHour) ? rtime->tm_hour : (((rtime->tm_hour + 11) % 12) + 1)),
rtime->tm_min, rtime->tm_sec);
for (j = 0; j < digits; j++) {
if (fulltxt[j] != old_fulltxt[j]) {
sock_printf(sock, "widget_set K d%d %d %c\n", j, xoffs+pos[j], fulltxt[j]);
old_fulltxt[j] = fulltxt[j];
}
}
if (heartbeat) { /* 10 means: colon */
sock_printf(sock, "widget_set K c0 %d 10\n", xoffs + 7);
if (digits > 4)
sock_printf(sock, "widget_set K c1 %d 10\n", xoffs + 14);
}
else { /* kludge: use illegal number to clear colon display */
sock_printf(sock, "widget_set K c0 %d 11\n", xoffs + 7);
if (digits > 4)
sock_printf(sock, "widget_set K c1 %d 11\n", xoffs + 14);
}
return 0;
} /* End big_clock_screen() */
/**
* MiniClock Screen displays the current time with hours & minutes only
*
*\verbatim
*
* +--------------------+ +--------------------+
* | | | 11:32 |
* | 11:32 | | |
* | | +--------------------+
* | |
* +--------------------+
*
*\endverbatim
*
* \param rep Time since last screen update
* \param display 1 if screen is visible or data should be updated
* \param flags_ptr Mode flags
* \return Always 0
*/
int
mini_clock_screen(int rep, int display, int *flags_ptr)
{
char now[40];
time_t thetime;
struct tm *rtime;
static const char *timeFormat = NULL;
static int heartbeat = 0;
int xoffs;
/* toggle colon display */
heartbeat ^= 1;
if ((*flags_ptr & INITIALIZED) == 0) {
*flags_ptr |= INITIALIZED;
/* get config values */
timeFormat = config_get_string("MiniClock", "TimeFormat", 0, "%H:%M");
sock_send_string(sock, "screen_add N\n");
sock_send_string(sock, "screen_set N -name {Mini Clock Screen} -heartbeat off\n");
sock_send_string(sock, "widget_add N one string\n");
}
time(&thetime);
rtime = localtime(&thetime);
if (strftime(now, sizeof(now), timeFormat, rtime) == 0)
*now = '\0';
tickTime(now, heartbeat);
xoffs = (lcd_wid > strlen(now)) ? (((lcd_wid - strlen(now)) / 2) + 1) : 1;
sock_printf(sock, "widget_set N one %d %d {%s}\n", xoffs, (lcd_hgt / 2), now);
return 0;
} /* End mini_clock_screen() */
/** Helper function: toggle between ':' and ' ' in time strings.
* \note The time string passed is modified directly!
* \param time String containing a formatted time value.
* \param heartbeat Even numbers to display ':', odd to display ' '.
* \return Pointer to the modfied time string.
*/
static char *
tickTime(char *time, int heartbeat)
{
if (time != NULL) {
static char colon[] = {':', ' '};
char *ptr = time;
for (heartbeat %= 2; *ptr != '\0'; ptr++) {
if (*ptr == colon[0])
*ptr = colon[heartbeat];
}
}
return (time);
}
-10
View File
@@ -1,10 +0,0 @@
#ifndef CHRONO_H
#define CHRONO_H
int clock_screen(int rep, int display, int *flags_ptr);
int uptime_screen(int rep, int display, int *flags_ptr);
int time_screen(int rep, int display, int *flags_ptr);
int big_clock_screen(int rep, int display, int *flags_ptr);
int mini_clock_screen(int rep, int display, int *flags_ptr);
#endif
-286
View File
@@ -1,286 +0,0 @@
/** \file clients/lcdproc/cpu.c
* Implements the 'CPU' and 'CPUGraph' screens.
*/
/*-
* This file is part of lcdproc, the lcdproc client.
*
* This file is released under the GNU General Public License.
* Refer to the COPYING file distributed with this package.
*/
#include <sys/types.h>
#include <sys/param.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <limits.h>
#include <errno.h>
#include "shared/sockets.h"
#include "main.h"
#include "mode.h"
#include "machine.h"
#include "cpu.h"
#include "util.h"
/**
* CPU screen shows info about percentage of the CPU being used
*
*\verbatim
*
* +--------------------+ +--------------------+
* |## CPU 51.9%: myh #@| |CPU [---- ]48.1%@|
* |Usr 46.0% Nice 0.0%| |U-- S- N I--- |
* |Sys 5.9% Idle 48.1%| +--------------------+
* |0%-------- 100%|
* +--------------------+
*
*\endverbatim
*
* \param rep Time since last screen update
* \param display 1 if screen is visible or data should be updated
* \param flags_ptr Mode flags
* \return Always 0
*/
int
cpu_screen(int rep, int display, int *flags_ptr)
{
#undef CPU_BUF_SIZE
#define CPU_BUF_SIZE 4
static double cpu[CPU_BUF_SIZE + 1][5]; /* last buffer is scratch */
static int gauge_wid = 0;
static int usni_wid = 0;
int i, j, n;
double value;
load_type load;
char tmp[25]; /* should be large enough */
if ((*flags_ptr & INITIALIZED) == 0) {
*flags_ptr |= INITIALIZED;
sock_send_string(sock, "screen_add C\n");
sock_printf(sock, "screen_set C -name {CPU Use: %s}\n", get_hostname());
if (lcd_hgt >= 4) {
gauge_wid = lcd_wid - 6; /* room between 0%...100% */
sock_send_string(sock, "widget_add C title title\n");
sock_send_string(sock, "widget_set C title {CPU LOAD}\n");
sock_send_string(sock, "widget_add C one string\n");
sock_send_string(sock, "widget_add C two string\n");
sock_send_string(sock, "widget_add C three string\n");
sock_printf(sock, "widget_set C one 1 2 {%-*s%-*s}\n",
lcd_wid / 2, "Usr", lcd_wid / 2, "Nice");
sock_printf(sock, "widget_set C two 1 3 {%-*s%-*s}\n",
lcd_wid / 2, "Sys", lcd_wid / 2, "Idle");
sock_printf(sock, "widget_set C three 1 4 {0%%%*s100%%}\n", gauge_wid, "");
sock_send_string(sock, "widget_add C usr string\n");
sock_send_string(sock, "widget_add C nice string\n");
sock_send_string(sock, "widget_add C idle string\n");
sock_send_string(sock, "widget_add C sys string\n");
sock_send_string(sock, "widget_add C bar hbar\n");
sock_send_string(sock, "widget_set C bar 3 4 0\n");
}
else {
usni_wid = (lcd_wid - 4) / 4; /* 4 gauges + 1 letter for each */
gauge_wid = lcd_wid - 12; /* room between [...] */
sock_send_string(sock, "widget_add C cpu string\n");
sock_printf(sock, "widget_set C cpu 1 1 {CPU [%*s]}\n", gauge_wid, "");
sock_send_string(sock, "widget_add C cpu% string\n");
sock_printf(sock, "widget_set C cpu%% 1 %d { 0.0%%}\n", lcd_wid - 5);
sock_send_string(sock, "widget_add C usni string\n");
sock_printf(sock, "widget_set C usni 1 2 {U%*sS%*sN%*sI%*s}\n",
usni_wid, "", usni_wid, "", usni_wid, "", usni_wid, "");
sock_send_string(sock, "widget_add C usr hbar\n");
sock_send_string(sock, "widget_add C sys hbar\n");
sock_send_string(sock, "widget_add C nice hbar\n");
sock_send_string(sock, "widget_add C idle hbar\n");
sock_send_string(sock, "widget_add C total hbar\n");
sock_send_string(sock, "widget_set C total 6 1 0\n");
}
return (0);
}
machine_get_load(&load);
/* Shift values over by one */
for (i = 0; i < (CPU_BUF_SIZE - 1); i++)
for (j = 0; j < 5; j++)
cpu[i][j] = cpu[i + 1][j];
/* Read new data */
if (load.total > 0L) {
cpu[CPU_BUF_SIZE - 1][0] = 100.0 * ((double) load.user / (double) load.total);
cpu[CPU_BUF_SIZE - 1][1] = 100.0 * ((double) load.system / (double) load.total);
cpu[CPU_BUF_SIZE - 1][2] = 100.0 * ((double) load.nice / (double) load.total);
cpu[CPU_BUF_SIZE - 1][3] = 100.0 * ((double) load.idle / (double) load.total);
cpu[CPU_BUF_SIZE - 1][4] = 100.0 * (((double) load.user + (double) load.system + (double) load.nice) / (double) load.total);
}
else {
cpu[CPU_BUF_SIZE - 1][0] = 0.0;
cpu[CPU_BUF_SIZE - 1][1] = 0.0;
cpu[CPU_BUF_SIZE - 1][2] = 0.0;
cpu[CPU_BUF_SIZE - 1][3] = 0.0;
cpu[CPU_BUF_SIZE - 1][4] = 0.0;
}
/* Average values for final result */
for (i = 0; i < 5; i++) {
value = 0.0;
for (j = 0; j < CPU_BUF_SIZE; j++)
value += cpu[j][i];
value /= CPU_BUF_SIZE;
cpu[CPU_BUF_SIZE][i] = value;
}
if (!display)
return (0);
if (lcd_hgt >= 4) { /* 4-line display */
sprintf_percent(tmp, cpu[CPU_BUF_SIZE][4]);
sock_printf(sock, "widget_set C title {CPU %5s: %s}\n", tmp, get_hostname());
sprintf_percent(tmp, cpu[CPU_BUF_SIZE][0]);
sock_printf(sock, "widget_set C usr %i 2 {%5s}\n", (lcd_wid / 2) - 5, tmp);
sprintf_percent(tmp, cpu[CPU_BUF_SIZE][1]);
sock_printf(sock, "widget_set C sys %i 3 {%5s}\n", (lcd_wid / 2) - 5, tmp);
sprintf_percent(tmp, cpu[CPU_BUF_SIZE][2]);
sock_printf(sock, "widget_set C nice %i 2 {%5s}\n", lcd_wid - 4, tmp);
sprintf_percent(tmp, cpu[CPU_BUF_SIZE][3]);
sock_printf(sock, "widget_set C idle %i 3 {%5s}\n", lcd_wid - 4, tmp);
n = (int) ((cpu[CPU_BUF_SIZE][4] * lcd_cellwid * gauge_wid) / 100.0);
sock_printf(sock, "widget_set C bar 3 4 %d\n", n);
}
else { /* 2-line display */
sprintf_percent(tmp, cpu[CPU_BUF_SIZE][4]);
sock_printf(sock, "widget_set C cpu%% %d 1 {%5s}\n", lcd_wid - 5, tmp);
n = (int) ((cpu[CPU_BUF_SIZE][4] * lcd_cellwid * gauge_wid) / 100.0);
sock_printf(sock, "widget_set C total 6 1 %d\n", n);
n = (int) ((cpu[CPU_BUF_SIZE][0] * lcd_cellwid * usni_wid) / 100.0);
sock_printf(sock, "widget_set C usr %d 2 %d\n", 0 * (usni_wid + 1) + 2, n);
n = (int) ((cpu[CPU_BUF_SIZE][1] * lcd_cellwid * usni_wid) / 100.0);
sock_printf(sock, "widget_set C sys %d 2 %d\n", 1 * (usni_wid + 1) + 2, n);
n = (int) ((cpu[CPU_BUF_SIZE][2] * lcd_cellwid * usni_wid) / 100.0);
sock_printf(sock, "widget_set C nice %d 2 %d\n", 2 * (usni_wid + 1) + 2, n);
n = (int) ((cpu[CPU_BUF_SIZE][3] * lcd_cellwid * usni_wid) / 100.0);
sock_printf(sock, "widget_set C idle %d 2 %d\n", 3 * (usni_wid + 1) + 2, n);
}
return (0);
} /* End cpu_screen() */
/**
* Cpu Graph Screen shows a quick-moving histogram of CPU use.
*
*\verbatim
*
* +--------------------+ +--------------------+
* |## CPU: myhost ####@| |CPU: myhos|| @|
* | || | | |||| |
* | ||| | +--------------------+
* | |||| |
* +--------------------+
*
*\endverbatim
*
* \param rep Time since last screen update
* \param display 1 if screen is visible or data should be updated
* \param flags_ptr Mode flags
* \return Always 0
*/
int
cpu_graph_screen(int rep, int display, int *flags_ptr)
{
#undef CPU_BUF_SIZE
#define CPU_BUF_SIZE 2
static double cpu[CPU_BUF_SIZE];
static int cpu_past[LCD_MAX_WIDTH];
static int gauge_hgt = 0;
int i, n = 0;
double value;
load_type load;
if ((*flags_ptr & INITIALIZED) == 0) {
*flags_ptr |= INITIALIZED;
gauge_hgt = (lcd_hgt > 2) ? (lcd_hgt - 1) : lcd_hgt;
sock_send_string(sock, "screen_add G\n");
sock_printf(sock, "screen_set G -name {CPU Graph: %s}\n", get_hostname());
if (lcd_hgt >= 4) {
sock_send_string(sock, "widget_add G title title\n");
sock_printf(sock, "widget_set G title {CPU: %s}\n", get_hostname());
}
else {
sock_send_string(sock, "widget_add G title string\n");
sock_printf(sock, "widget_set G title 1 1 {CPU: %s}\n", get_hostname());
}
for (i = 1; i <= lcd_wid; i++) {
sock_printf(sock, "widget_add G bar%d vbar\n", i);
sock_printf(sock, "widget_set G bar%d %d %d 0\n", i, i, lcd_hgt);
cpu_past[i - 1] = 0;
};
/* Clear out CPU averaging array */
for (i = 0; i < CPU_BUF_SIZE; i++)
cpu[i] = 0.;
}
/* Shift values over by one */
for (i = 0; i < (CPU_BUF_SIZE - 1); i++)
cpu[i] = cpu[i + 1];
/* Read and save new data */
machine_get_load(&load);
cpu[CPU_BUF_SIZE-1] = (load.total > 0L)
? ((double) load.user + (double) load.system + (double) load.nice) / (double) load.total
: 0;
/* Average values for final result */
value = 0.0;
for (i = 0; i < CPU_BUF_SIZE; i++)
value += cpu[i];
value /= CPU_BUF_SIZE;
/* Scale result to available height (leave 1st line free when height > 2) */
n = (int) (value * lcd_cellhgt * gauge_hgt);
/* Shift and update display the graph */
for (i = 0; i < lcd_wid - 1; i++) {
cpu_past[i] = cpu_past[i + 1];
if (display) {
sock_printf(sock, "widget_set G bar%d %d %d %d\n",
i + 1, i + 1, lcd_hgt, cpu_past[i]);
}
}
/* Save the newest entry and display it */
cpu_past[lcd_wid - 1] = n;
if (display) {
sock_printf(sock, "widget_set G bar%d %d %d %d\n", lcd_wid, lcd_wid, lcd_hgt, n);
}
return (0);
} /* End cpu_graph_screen() */
-7
View File
@@ -1,7 +0,0 @@
#ifndef CPU_H
#define CPU_H
int cpu_screen(int rep, int display, int *flags_ptr);
int cpu_graph_screen(int rep, int display, int *flags_ptr);
#endif
-133
View File
@@ -1,133 +0,0 @@
/** \file clients/lcdproc/cpu_smp.c
* Display cpu info for multi-processor machines.
*
* Adapted from cpu.c.
*
* Really boring for the moment, it only shows a current usage percentage graph
* for each CPU.
*
* It will handle up to 2xlcd_hgt or 8 CPUs, whichever is less. If there are
* more CPUs than lines on the LCD, it puts 2 CPUs per line, splitting the line
* in half. Otherwise, it uses one line per CPU.
*
* If the number of lines used to display the bar graphs for the CPUs is smaller
* than the LCD's height, a title line is introduced, so that the screen looks
* similar to other lcdproc screens.
* In all other cases (i.e. \#CPUs == LCD height or \#CPUs >= 2 * LCD height),
* the title is left out to display as many CPUs graphs as possible.
*/
/*-
* Copyright (C) 2000 J Robert Ray
* Copyright (C) 2006,2007 Peter Marschall
*
* This file is part of lcdproc, the lcdproc client.
*
* This file is released under the GNU General Public License.
* Refer to the COPYING file distributed with this package.
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <ctype.h>
#include "shared/sockets.h"
#include "main.h"
#include "mode.h"
#include "machine.h"
#include "cpu_smp.h"
/**
* CPU screen shows info about percentage of the CPU being used
*
* \param rep Time since last screen update
* \param display 1 if screen is visible or data should be updated
* \param flags_ptr Mode flags
* \return Always 0
*/
int
cpu_smp_screen (int rep, int display, int *flags_ptr)
{
#undef CPU_BUF_SIZE
#define CPU_BUF_SIZE 4
int z;
static float cpu[MAX_CPUS][CPU_BUF_SIZE + 1]; /* last buffer is scratch */
load_type load[MAX_CPUS];
int num_cpus = MAX_CPUS;
int bar_size;
int lines_used;
/* get SMP load - inform about max #CPUs allowed */
machine_get_smpload(load, &num_cpus);
/* restrict num_cpus to max. twice the display height */
if (num_cpus > 2 * lcd_hgt)
num_cpus = 2 * lcd_hgt;
/* 2 CPUs per line if more CPUs than lines */
bar_size = (num_cpus > lcd_hgt) ? (lcd_wid / 2 - 6) : (lcd_wid - 6);
lines_used = (num_cpus > lcd_hgt) ? (num_cpus + 1) / 2 : num_cpus;
if ((*flags_ptr & INITIALIZED) == 0) {
*flags_ptr |= INITIALIZED;
sock_send_string(sock, "screen_add P\n");
/* print title if he have room for it */
if (lines_used < lcd_hgt) {
sock_send_string(sock, "widget_add P title title\n");
sock_printf(sock, "widget_set P title {SMP CPU %s}\n", get_hostname());
}
else {
sock_send_string(sock, "screen_set P -heartbeat off\n");
}
sock_printf(sock, "screen_set P -name {CPU Use: %s}\n", get_hostname());
for (z = 0; z < num_cpus; z++) {
int y_offs = (lines_used < lcd_hgt) ? 2 : 1;
int x = (num_cpus > lcd_hgt) ? ((z % 2) * (lcd_wid/2) + 1) : 1;
int y = (num_cpus > lcd_hgt) ? (z/2 + y_offs) : (z + y_offs);
sock_printf(sock, "widget_add P cpu%d_title string\n", z);
sock_printf(sock, "widget_set P cpu%d_title %d %d \"CPU%d[%*s]\"\n",
z, x, y, z, bar_size, "");
sock_printf(sock, "widget_add P cpu%d_bar hbar\n", z);
}
return 0;
}
for (z = 0; z < num_cpus; z++) {
int y_offs = (lines_used < lcd_hgt) ? 2 : 1;
int x = (num_cpus > lcd_hgt) ? ((z % 2) * (lcd_wid/2) + 6) : 6;
int y = (num_cpus > lcd_hgt) ? (z/2 + y_offs) : (z + y_offs);
float value = 0.0;
int i, n;
/* Shift values over by one */
for (i = 0; i < (CPU_BUF_SIZE - 1); i++)
cpu[z][i] = cpu[z][i + 1];
/* Read new data */
cpu[z][CPU_BUF_SIZE-1] = (load[z].total > 0L)
? (((float) load[z].user + (float) load[z].system + (float) load[z].nice) / (float) load[z].total) * 100.0
: 0.0;
/* Average values for final result */
for (i = 0; i < CPU_BUF_SIZE; i++) {
value += cpu[z][i];
}
value /= CPU_BUF_SIZE;
n = (int) ((value * lcd_cellwid * bar_size) / 100.0 + 0.5);
sock_printf(sock, "widget_set P cpu%d_bar %d %d %d\n", z, x, y, n);
}
return 0;
}
-6
View File
@@ -1,6 +0,0 @@
#ifndef CPU_SMP_H
#define CPU_SMP_H
int cpu_smp_screen(int rep, int display, int *flags_ptr);
#endif
-158
View File
@@ -1,158 +0,0 @@
/** \file clients/lcdproc/disk.c
* Implements the 'Disk' screen.
*/
/*-
* This file is part of lcdproc, the lcdproc client.
*
* This file is released under the GNU General Public License.
* Refer to the COPYING file distributed with this package.
*/
#include <sys/types.h>
#include <sys/param.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "shared/sockets.h"
#include "main.h"
#include "mode.h"
#include "machine.h"
#include "disk.h"
#include "util.h"
/**
* Gives disk stats.
* Stays onscreen until it is done; rolls over all mounted file systems
*
*\verbatim
*
* +--------------------+ +--------------------+
* |## DISKS: myhost ##@| |## DISKS: myhost ##@|
* |/ 18.3G E-- F| |-local 18.3G E--- F|
* |-local 18.3G E--- F| +--------------------+
* |/boot 949.6M E- F|
* +--------------------+
*
*\endverbatim
*
* \param rep Time since last screen update
* \param display 1 if screen is visible or data should be updated
* \param flags_ptr Mode flags
* \return Always 0
*/
int
disk_screen(int rep, int display, int *flags_ptr)
{
static mounts_type mnt[256];
static int count = 0;
/* Holds info to display (avoid recalculating it) */
struct disp {
char dev[16];
char cap[8];
int full;
} table[256];
int i;
static int num_disks = 0;
static int dev_wid = 6;
static int gauge_wid = 6;
#define huge long long int
huge size;
if ((*flags_ptr & INITIALIZED) == 0) {
*flags_ptr |= INITIALIZED;
dev_wid = (lcd_wid >= 20) ? (lcd_wid - 8) / 2 : (lcd_wid / 2) - 1;
gauge_wid = (lcd_wid >= 20) ? (lcd_wid - dev_wid - 10) : (lcd_wid - dev_wid - 3);
sock_send_string(sock, "screen_add D\n");
sock_printf(sock, "screen_set D -name {Disk Use: %s}\n", get_hostname());
sock_send_string(sock, "widget_add D title title\n");
sock_printf(sock, "widget_set D title {DISKS: %s}\n", get_hostname());
sock_send_string(sock, "widget_add D f frame\n");
sock_printf(sock, "widget_set D f 1 2 %i %i %i %i v 12\n", lcd_wid, lcd_hgt, lcd_wid, lcd_hgt - 1);
sock_send_string(sock, "widget_add D err1 string\n");
sock_send_string(sock, "widget_add D err2 string\n");
sock_send_string(sock, "widget_set D err1 5 2 { Reading }\n");
sock_send_string(sock, "widget_set D err2 5 3 {Filesystems}\n");
}
/* Get rid of old, unmounted filesystems... */
machine_get_fs(mnt, &count);
/* Fill the display structure... */
if (count) {
sock_send_string(sock, "widget_set D err1 0 0 .\n");
sock_send_string(sock, "widget_set D err2 0 0 .\n");
for (i = 0; i < count; i++) {
if (strlen(mnt[i].mpoint) > dev_wid)
sprintf(table[i].dev, "-%s", (mnt[i].mpoint) + (strlen(mnt[i].mpoint) - (dev_wid - 1)));
else
sprintf(table[i].dev, "%s", mnt[i].mpoint);
table[i].full = (huge) (lcd_cellwid * gauge_wid)
* (huge) (mnt[i].blocks - mnt[i].bfree)
/ (huge) mnt[i].blocks;
size = (huge) mnt[i].bsize * (huge) mnt[i].blocks;
memset(table[i].cap, '\0', 8);
sprintf_memory(table[i].cap, (double) size, 1);
}
}
else {
sock_send_string(sock, "widget_set D err1 1 2 {Error Retrieving}\n");
sock_send_string(sock, "widget_set D err2 1 3 {Filesystem Stats}\n");
return 0;
}
/*
* Display stuff... (show for two seconds, then scroll once per
* second, then hold at the end for two seconds)
*/
sock_printf(sock, "widget_set D f 1 2 %i %i %i %i v 12\n", lcd_wid, lcd_hgt, lcd_wid, count);
for (i = 0; i < count; i++) {
char tmp[lcd_wid + 1]; /* should be large enough */
if (table[i].dev[0] == '\0')
continue;
if (i >= num_disks) { /* Make sure we have enough lines... */
sock_printf(sock, "widget_add D s%i string -in f\n", i);
sock_printf(sock, "widget_add D h%i hbar -in f\n", i);
}
if (lcd_wid >= 20) { /* 20+x columns */
sprintf(tmp, "%-*s %6s E%*sF", dev_wid, table[i].dev, table[i].cap, gauge_wid, "");
sock_printf(sock, "widget_set D s%i 1 %i {%s}\n", i, i + 1, tmp);
sock_printf(sock, "widget_set D h%i %i %i %i\n", i, 10 + dev_wid, i + 1, table[i].full);
}
else { /* < 20 columns */
sprintf(tmp, "%-*s E%*sF", dev_wid, table[i].dev, gauge_wid, "");
sock_printf(sock, "widget_set D s%i 1 %i {%s}\n", i, i + 1, tmp);
sock_printf(sock, "widget_set D h%i %i %i %i\n", i, 3 + dev_wid, i + 1, table[i].full);
}
}
/* Now remove extra widgets... */
for (; i < num_disks; i++) {
sock_printf(sock, "widget_del D s%i\n", i);
sock_printf(sock, "widget_del D h%i\n", i);
}
num_disks = count;
#undef huge
return 0;
}
-6
View File
@@ -1,6 +0,0 @@
#ifndef DISK_H
#define DISK_H
int disk_screen(int rep, int display, int *flags_ptr);
#endif
-123
View File
@@ -1,123 +0,0 @@
/** \file clients/lcdproc/eyebox.c
* This is the LCDproc client module for EyeboxOne devices
*
* This allows to use leds, one as a free CPU meter, and one as a free RAM
* meter.
*/
/*-
* Copyright (C) 2006 Cedric TESSIER (aka NeZetiC) http://www.nezetic.info
*
* This file is released under the GNU General Public License.
* Refer to the COPYING file distributed with this package.
*/
#include <sys/types.h>
#include <sys/param.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <limits.h>
#include <errno.h>
#include "shared/sockets.h"
#include "main.h"
#include "mode.h"
#include "machine.h"
#include "eyebox.h"
#include "util.h"
int
eyebox_screen(char display, int init)
{
#undef CPU_BUF_SIZE
#define CPU_BUF_SIZE 4
int i, j;
double value;
static double cpu[CPU_BUF_SIZE + 1][5]; /* last buffer is scratch */
meminfo_type mem[2];
load_type load;
if (init == 0) {
sock_printf(sock, "widget_add %c eyebo_cpu string\n", display);
sock_printf(sock, "widget_add %c eyebo_mem string\n", display);
return 0;
}
machine_get_load(&load);
machine_get_meminfo(mem);
/* Shift values over by one */
for (i = 0; i < (CPU_BUF_SIZE - 1); i++)
for (j = 0; j < 5; j++)
cpu[i][j] = cpu[i + 1][j];
/* Read new data */
if (load.total > 0L) {
cpu[CPU_BUF_SIZE - 1][0] = 100.0 * ((double) load.user / (double) load.total);
cpu[CPU_BUF_SIZE - 1][1] = 100.0 * ((double) load.system / (double) load.total);
cpu[CPU_BUF_SIZE - 1][2] = 100.0 * ((double) load.nice / (double) load.total);
cpu[CPU_BUF_SIZE - 1][3] = 100.0 * ((double) load.idle / (double) load.total);
cpu[CPU_BUF_SIZE - 1][4] = 100.0 * (((double) load.user + (double) load.system + (double) load.nice) / (double) load.total);
}
else {
cpu[CPU_BUF_SIZE - 1][0] = 0.0;
cpu[CPU_BUF_SIZE - 1][1] = 0.0;
cpu[CPU_BUF_SIZE - 1][2] = 0.0;
cpu[CPU_BUF_SIZE - 1][3] = 0.0;
cpu[CPU_BUF_SIZE - 1][4] = 0.0;
}
/* Average values for final result */
for (i = 0; i < 5; i++) {
value = 0.0;
for (j = 0; j < CPU_BUF_SIZE; j++)
value += cpu[j][i];
value /= CPU_BUF_SIZE;
cpu[CPU_BUF_SIZE][i] = value;
}
/*-
* /xBab = Use Bar
* a = Bar ID
* b = Level
*/
sock_printf(sock, "widget_set %c eyebo_cpu 1 2 {/xB%d%d}\n",
display, 2,(int)(cpu[CPU_BUF_SIZE][4]/10));
/*-
* /xBab = Use Bas
* a = Bar ID
* b = Level
*/
value = 1.0 - (double) (mem[0].free + mem[0].buffers + mem[0].cache)
/ (double) mem[0].total;
sock_printf(sock, "widget_set %c eyebo_mem 1 3 {/xB%d%d}\n", display, 1, (int) (value * 10));
return 0;
}
void
eyebox_clear(void)
{
/* Clear LEDs before exit */
sock_send_string(sock, "screen_add OFF\n");
sock_send_string(sock, "screen_set OFF -priority alert -name {EyeBO}\n");
sock_send_string(sock, "widget_add OFF title title\n");
sock_send_string(sock, "widget_set OFF title {EYEBOX ONE}\n");
sock_send_string(sock, "widget_add OFF text string\n");
sock_send_string(sock, "widget_add OFF about string\n");
sock_send_string(sock, "widget_add OFF cpu string\n");
sock_send_string(sock, "widget_add OFF mem string\n");
sock_send_string(sock, "widget_set OFF text 1 2 {Reseting Leds...}\n");
sock_send_string(sock, "widget_set OFF about 5 4 {EyeBO by NeZetiC}\n");
sock_printf(sock, "widget_set OFF cpu 1 2 {/xB%d%d}\n", 2, 0);
sock_printf(sock, "widget_set OFF mem 1 3 {/xB%d%d}\n", 1, 0);
usleep(2000000); /* Wait last order execution */
}
-7
View File
@@ -1,7 +0,0 @@
#ifndef CTRL_H
#define CTRL_H
int eyebox_screen(char display, int init);
void eyebox_clear(void);
#endif
-519
View File
@@ -1,519 +0,0 @@
/** \file clients/lcdproc/iface.c
* Shows networks statistics. Imported from netlcdclient.
*/
/*-
* Copyright (C) 2002 Luis Llorente Campo <luisllorente@luisllorente.com>
*
* Multi-interface extension by Stephan Skrodzki <skrodzki@stevekist.de>
* Adaptions to lcdproc by Andrew Foss with fixes by M. Dolze
* Cleanup, reorganization by Peter Marschall
*
* This file is released under the GNU General Public License.
* Refer to the COPYING file distributed with this package.
*/
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <time.h>
#include "shared/sockets.h"
#include "shared/report.h"
#include "shared/configfile.h"
#include "main.h"
#include "machine.h"
#include "util.h"
#include "iface.h"
#define UNSET_INT -1
#define UNSET_STR "\01"
static int iface_count = 0; /* number of interfaces */
static char unit_label[10] = "B"; /* default unit label is Bytes */
static int transfer_screen = 0; /* by default, transfer screen is not shown */
/** Reads and parses configuration file.
* \return 0 on success, -1 on error
*/
static int
iface_process_configfile(void)
{
const char *unit;
debug(RPT_DEBUG, "%s()", __FUNCTION__);
/* Read config settings */
for (iface_count = 0; iface_count < MAX_INTERFACES; iface_count++) {
char iface_label[12];
sprintf(iface_label, "Interface%i", iface_count);
debug(RPT_DEBUG, "Label %s count %i", iface_label, iface_count);
iface[iface_count].name = strdup(config_get_string("Iface", iface_label, 0, ""));
if (iface[iface_count].name == NULL) {
report(RPT_CRIT, "malloc failure");
return -1;
}
if (*iface[iface_count].name == '\0')
break;
sprintf(iface_label, "Alias%i", iface_count);
iface[iface_count].alias = strdup(config_get_string("Iface", iface_label, 0, iface[iface_count].name));
if (iface[iface_count].alias == NULL)
/*
* make alias the same as the interface name in case
* strdup() failed
*/
iface[iface_count].alias = iface[iface_count].name;
debug(RPT_DEBUG, "Interface %i: %s alias %s",
iface_count, iface[iface_count].name, iface[iface_count].alias);
}
unit = config_get_string("Iface", "Unit", 0, "byte");
if ((strcasecmp(unit, "byte") == 0) ||
(strcasecmp(unit, "bytes") == 0))
strncpy(unit_label, "B", sizeof(unit_label));
else if ((strcasecmp(unit, "bit") == 0) ||
(strcasecmp(unit, "bits") == 0))
strncpy(unit_label, "b", sizeof(unit_label));
else if ((strcasecmp(unit, "packet") == 0) ||
(strcasecmp(unit, "packets") == 0))
strncpy(unit_label, "pkt", sizeof(unit_label));
else {
report(RPT_ERR, "illegal Unit value: %s", unit);
return -1;
}
unit_label[sizeof(unit_label) - 1] = '\0';
transfer_screen = config_get_bool("Iface", "Transfer", 0, 0);
return 0;
}
/**
* IFace screen shows info about percentage of the Network interface usage /
* throughput.
*
*\verbatim
*
* +--------------------+ +--------------------+
* |## Net Load: LAN ##@| |### Net Load ######@|
* |UL: 123.456 Kb| |LAN: U: 34kb D: 56Mb|
* |DL: 654.321 Kb| +--------------------+
* |Total: 777.777 Kb|
* +--------------------+
*
*\endverbatim
*
* \param rep Time since last screen update
* \param display 1 if screen is visible or data should be updated
* \param flags_ptr Mode flags
* \return Always 0
*/
int
iface_screen(int rep, int display, int *flags_ptr)
{
/* interval since last update */
unsigned int interval = difftime(time(NULL), iface[0].last_online);
int iface_nmbr;
if (!interval)
return 0; /* need at least 1 second, no divide by 0 */
if ((*flags_ptr & INITIALIZED) == 0) {
*flags_ptr |= INITIALIZED;
/* get configuration options */
iface_process_configfile();
/* set initial speed screen with widgets */
initialize_speed_screen();
/* set initial transfer screen if needed */
if (transfer_screen) {
initialize_transfer_screen();
}
/* initialize all interface structs */
for (iface_nmbr = 0; iface_nmbr < iface_count; iface_nmbr++) {
iface[iface_nmbr].last_online = 0;
iface[iface_nmbr].status = down;
}
return 0;
}
/* for each interface do */
for (iface_nmbr = 0; iface_nmbr < iface_count; iface_nmbr++) {
/* read iface_parameter stats */
if (!machine_get_iface_stats(&iface[iface_nmbr])) {
/* there was an error, so we exit the loop */
break;
}
/* actualize speed values in display */
actualize_speed_screen(&iface[iface_nmbr], interval, iface_nmbr);
/* if needed, actualize transfer values in display */
if (transfer_screen)
actualize_transfer_screen(&iface[iface_nmbr], iface_nmbr);
/* Actual values are the old ones in the next loop */
iface[iface_nmbr].rc_byte_old = iface[iface_nmbr].rc_byte;
iface[iface_nmbr].tr_byte_old = iface[iface_nmbr].tr_byte;
iface[iface_nmbr].rc_pkt_old = iface[iface_nmbr].rc_pkt;
iface[iface_nmbr].tr_pkt_old = iface[iface_nmbr].tr_pkt;
}
return 0;
}
/**
* Send commands to server to add speed screen with all required widgets.
*/
void
initialize_speed_screen(void)
{
int iface_nmbr; /* interface number */
sock_send_string(sock, "screen_add I\n");
sock_send_string(sock, "screen_set I name {Load}\n");
sock_send_string(sock, "widget_add I title title\n");
/* Single interface mode */
if ((iface_count == 1) && (lcd_hgt >= 4 )) {
sock_printf(sock, "widget_set I title {Net Load: %s}\n", iface[0].alias);
sock_send_string(sock, "widget_add I dl string\n");
sock_send_string(sock, "widget_set I dl 1 2 {DL:}\n");
sock_send_string(sock, "widget_add I ul string\n");
sock_send_string(sock, "widget_set I ul 1 3 {UL:}\n");
sock_send_string(sock, "widget_add I total string\n");
sock_send_string(sock, "widget_set I total 1 4 {Total:}\n");
}
/* multi-interfaces mode: one line per interface */
else {
/* Set title */
if (strstr(unit_label, "B")) {
sock_printf(sock, "widget_set I title {Net Load (bytes)}\n");
}
else {
if (strstr(unit_label, "b")) {
sock_printf(sock, "widget_set I title {Net Load (bits)}\n");
}
else {
sock_printf(sock, "widget_set I title {Net Load (packets)}\n");
}
}
/* frame from (2, left) to (width, height) that is iface_count lines high */
sock_send_string (sock, "widget_add I f frame\n");
sock_printf(sock, "widget_set I f 1 2 %d %d %d %d v 16\n",
lcd_wid, lcd_hgt, lcd_wid, iface_count,
/* scroll rate: 1 line every X ticks (=1/8 sec) */
((lcd_hgt >= 4) ? 8 : 16));
/* Add interfaces to frame */
for (iface_nmbr = 0; iface_nmbr < iface_count; iface_nmbr++) {
sock_printf(sock, "widget_add I i%1d string -in f\n", iface_nmbr);
sock_printf(sock, "widget_set I i%1d 1 %1d {%5.5s NA (never)}\n",
iface_nmbr, iface_nmbr+1, iface[iface_nmbr].alias);
}
}
}
/**
* Format the value (in bytes) passed as parameter according to its scale,
* adding the proper suffix. Store the formatted value string in the
* variable 'buff' passed as pointer.
* \param buff Pointer to target buffer
* \param value Number of bytes
* \param unit String describing the unit. If this contains 'b', \c value is
* converted to bits. If this contains 'B', value is converted
* to binary multiples (1024 bytes = 1 KiB).
*/
void
format_value (char *buff, double value, char *unit)
{
char *mag;
/* Convert bytes to bits, if necessary */
if (strstr(unit, "b"))
value *= 8;
/* If units are bytes, then divide by 2^10, otherwise by 10^3 */
mag = convert_double(&value, (strstr(unit, "B")) ? 1024 : 1000, 1.0f);
/*-
* Formatting rules:
* - if original value was < 1000, output decimal value only
* - otherwise format with 3 precision
*/
if (mag[0] == 0)
sprintf(buff, "%8ld %s", (long) value, unit);
else
sprintf(buff, "%7.3f %s%s", value, mag, unit);
}
/**
* Format the value (in bytes) passed as parameter according to its scale,
* adding the proper suffix. Store the formatted value string in the
* variable 'buff' passed as pointer. Version for multi-interfaces mode.
* \param buff Pointer to target buffer
* \param value Number of bytes
* \param unit String describing the unit. If this contains 'b', \c value is
* converted to bits. If this contains 'B', value is converted
* to binary multiples (1024 bytes = 1 KiB).
*/
void
format_value_multi_interface(char *buff, double value, char *unit)
{
char *mag;
if (strstr(unit, "b"))
value *= 8;
mag = convert_double(&value, (strstr(unit, "B")) ? 1024 : 1000, 1.0f);
/*-
* Formatting rules:
* - if original value was < 1000, output decimal value only
* - with 1 precision if <10
* - decimal value with magnitude otherwise
*/
if (mag[0] == 0)
sprintf(buff, "%4ld", (long) value);
else if (value < 10)
sprintf(buff, "%3.1f%s", value, mag);
else
sprintf(buff, "%3.0f%s", value, mag);
}
/**
* Format the time in ASCII, depending on the elapsed time.
* \param buff Pointer to buffer for storing result
* \param last_online Time value
*/
void
get_time_string(char *buff, time_t last_online)
{
time_t act_time; /* actual time */
char timebuff[30];
act_time = time(NULL);
if (last_online == 0) { /* never was online */
sprintf(buff, "never");
return;
}
/* Transform Unix time format to UTC time format */
strcpy(timebuff, ctime(&last_online));
/* 86400 = 24 * 60 * 60. Is it more than 24 hours? */
if ((act_time - last_online) > 86400 ) {
timebuff[10] = '\0';
sprintf(buff, "%s", &timebuff[4]);
return;
}
else {
timebuff[19] = '\0';
sprintf(buff, "%s", &timebuff[11]);
return;
}
}
/**
* Actualize values in display, calculating speeds in the defined interval
* of time and sending proper commands to server. If measure unit is
* 'pkt', we don't format this speed. Is always XXXX pkt/s.
* \param iface Pointer to interface data
* \param interval Time of last update
* \param index Interface index
*/
void
actualize_speed_screen(IfaceInfo *iface, unsigned int interval, int index)
{
char speed[20]; /* buffer to store the formated speed string */
double rc_speed;
double tr_speed;
/* single interface mode */
if ((iface_count == 1) && ( lcd_hgt >= 4)) {
if (iface->status == up) {
/* Calculate and actualize download speed */
if (strstr(unit_label, "pkt")) {
rc_speed = (iface->rc_pkt - iface->rc_pkt_old) / interval;
sprintf(speed, "%8ld %s", (long) rc_speed, unit_label);
}
else {
rc_speed = (iface->rc_byte - iface->rc_byte_old) / interval;
format_value(speed, rc_speed, unit_label);
}
sock_printf(sock, "widget_set I dl 1 2 {DL: %*s/s}\n", lcd_wid - 6, speed);
/* Calculate and actualize upload speed */
if (strstr(unit_label, "pkt")) {
tr_speed = (iface->tr_pkt - iface->tr_pkt_old) / interval;
sprintf(speed, "%8ld %s", (long)tr_speed, unit_label);
}
else {
tr_speed = (iface->tr_byte - iface->tr_byte_old) / interval;
format_value(speed, tr_speed, unit_label);
}
sock_printf(sock, "widget_set I ul 1 3 {UL: %*s/s}\n", lcd_wid - 6, speed);
/* Calculate and actualize total speed */
if (strstr(unit_label, "pkt")) {
sprintf(speed, "%7ld %s", (long)(rc_speed + tr_speed), unit_label);
}
else {
format_value(speed, rc_speed + tr_speed, unit_label);
}
sock_printf(sock, "widget_set I total 1 4 {Total: %*s/s}\n", lcd_wid - 9, speed);
}
else {
get_time_string(speed, iface->last_online);
sock_printf(sock, "widget_set I dl 1 2 {NA (%s)}\n", speed);
sock_send_string(sock, "widget_set I ul 1 3 {}\n");
sock_send_string(sock, "widget_set I total 1 4 {}\n");
}
}
/* multi-interfaces mode: 1 line per interface */
else {
char speed1[20]; /* buffer to store the formated speed string */
if (iface->status == up) {
if (strstr(unit_label, "pkt")) {
rc_speed = (iface->rc_pkt - iface->rc_pkt_old) / interval;
tr_speed = (iface->tr_pkt - iface->tr_pkt_old) / interval;
}
else {
rc_speed = (iface->rc_byte - iface->rc_byte_old) / interval;
tr_speed = (iface->tr_byte - iface->tr_byte_old) / interval;
}
format_value_multi_interface(speed, rc_speed, unit_label);
format_value_multi_interface(speed1, tr_speed, unit_label);
if (lcd_wid > 16)
sock_printf(sock, "widget_set I i%1d 1 %1d {%5.5s U:%.4s D:%.4s}\n",
index, index+1, iface->alias, speed1, speed);
else
sock_printf(sock, "widget_set I i%1d 1 %1d {%4.4s ^%.4s v%.4s}\n",
index, index+1, iface->alias, speed1, speed);
}
else {
get_time_string(speed, iface->last_online);
sock_printf(sock, "widget_set I i%1d 1 %1d {%5.5s NA (%s)}\n",
index, index+1, iface->alias, speed);
}
}
}
/**
* Send commands to server to add transfer screen with all required widgets.
*/
void
initialize_transfer_screen(void)
{
int iface_nmbr; /* interface number */
sock_send_string(sock, "screen_add NT\n");
sock_send_string(sock, "screen_set NT name {Transfer}\n");
sock_send_string(sock, "widget_add NT title title\n");
/* single interface mode */
if ((iface_count == 1) && (lcd_hgt >= 4)) {
sock_printf(sock, "widget_set NT title {Transfer: %s}\n", iface[0].alias);
sock_send_string(sock, "widget_add NT dl string\n");
sock_send_string(sock, "widget_set NT dl 1 2 {DL:}\n");
sock_send_string(sock, "widget_add NT ul string\n");
sock_send_string(sock, "widget_set NT ul 1 3 {UL:}\n");
sock_send_string(sock, "widget_add NT total string\n");
sock_send_string(sock, "widget_set NT total 1 4 {Total:}\n");
}
/* multi-interfaces mode: one line per interface */
else {
/* Set title (transfer screen is always in "bytes") */
sock_send_string(sock, "widget_set NT title {Net Transfer (bytes)}\n");
/* frame from (2, left) to (width, height) that is iface_count lines high */
sock_send_string(sock, "widget_add NT f frame\n");
sock_printf(sock, "widget_set NT f 1 2 %d %d %d %d v 16\n",
lcd_wid, lcd_hgt, lcd_wid, iface_count,
/* scroll rate: 1 line every X ticks (=1/8 sec) */
((lcd_hgt >= 4) ? 8 : 16));
/* Add interfaces */
for (iface_nmbr = 0; iface_nmbr < iface_count; iface_nmbr++) {
sock_printf(sock, "widget_add NT i%1d string -in f\n", iface_nmbr);
sock_printf(sock, "widget_set NT i%1d 1 %1d {%5.5s NA (never)}\n",
iface_nmbr, iface_nmbr+1, iface[iface_nmbr].alias);
}
}
}
/**
* Actualize values in display, formatting transfer measures and sending
* proper commands to server. Traffic is shown in "bytes" unit.
* \param iface Pointer to interface data
* \param index Interface index
*/
void
actualize_transfer_screen(IfaceInfo *iface, int index)
{
char transfer[20]; /* buffer to store the formated traffic string */
/* single interface mode */
if ((iface_count == 1) && (lcd_hgt >= 4)) {
if (iface->status == up) {
/* download traffic */
format_value(transfer, iface->rc_byte, "B");
sock_printf(sock, "widget_set NT dl 1 2 {DL: %*s}\n", lcd_wid - 4, transfer);
/* upload traffic */
format_value(transfer, iface->tr_byte, "B");
sock_printf(sock, "widget_set NT ul 1 3 {UL: %*s}\n", lcd_wid - 4, transfer);
/* total traffic */
format_value(transfer, iface->rc_byte + iface->tr_byte, "B");
sock_printf(sock, "widget_set NT total 1 4 {Total: %*s}\n", lcd_wid - 7, transfer);
}
else {
get_time_string(transfer, iface->last_online);
sock_printf(sock, "widget_set NT dl 1 2 {NA (%s)}\n", transfer);
sock_send_string(sock, "widget_set NT ul 1 3 {}\n");
sock_send_string(sock, "widget_set NT total 1 4 {}\n");
}
}
/* multi-interfaces mode: one line per interface */
else {
char transfer1[20]; /* buffer to store the formated traffic string */
if (iface->status == up) {
format_value_multi_interface(transfer, iface->rc_byte, "B");
format_value_multi_interface(transfer1, iface->tr_byte, "B");
if (lcd_wid > 16)
sock_printf(sock, "widget_set NT i%1d 1 %1d {%5.5s U:%.4s D:%.4s}\n",
index, index+1, iface->alias, transfer1, transfer);
else
sock_printf(sock, "widget_set NT i%1d 1 %1d {%4.4s ^%.4s v%.4s}\n",
index, index+1, iface->alias, transfer1, transfer);
}
else {
get_time_string(transfer, iface->last_online);
sock_printf(sock, "widget_set NT i%1d 1 %1d {%5.5s NA (%s)}\n",
index, index+1, iface->alias, transfer);
}
}
}
-43
View File
@@ -1,43 +0,0 @@
/** \file clients/lcdproc/iface.h
* Definitions and function prototypes for \c iface.c.
* Imported from \c netlcdclient.h.
*/
/*-
* Copyright (C) 2002 Luis Llorente Campo
*
* 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, or (at your option)
* any later version.
*/
#ifndef IFACE_H
#define IFACE_H
/** max number of interfaces in multi-interface mode */
#define MAX_INTERFACES 3
IfaceInfo iface[MAX_INTERFACES]; /* interface info */
/** Update screen content */
int iface_screen(int rep, int display, int *flags_ptr);
/** read interface stats from /proc/net/dev */
int get_iface_stats(IfaceInfo *interface);
/** send initial commands to server to add the speed screen */
void initialize_speed_screen(void);
/** send initial commands to server to add the transfer screen */
void initialize_transfer_screen(void);
/** format the time in ASCII */
void get_time_string(char *buff, time_t last_online);
/** format value, scaling value and adding proper suffixes */
void format_value(char *buff, double value, char *unit);
/** format value, scaling value and adding proper suffixes (for multi-interface
* mode) */
void format_value_multi_interface(char *buff, double value, char *unit);
/** actualize widgets values in speed screen */
void actualize_speed_screen(IfaceInfo *iface, unsigned int interval, int index);
/** actualize widgets values in transfer screen */
void actualize_transfer_screen(IfaceInfo *iface, int index);
#endif
-148
View File
@@ -1,148 +0,0 @@
# LCDproc client configuration file
## general options ##
[lcdproc]
# address of the LCDd server to connect to
Server=localhost
# Port of the server to connect to
Port=13666
# set reporting level
ReportLevel=2
# report to to syslog ?
ReportToSyslog=false
# run in foreground [default: false; legal: true, false]
#Foreground=true
# PidFile location when running as daemon [default: /var/run/lcdproc.pid]
#PidFile=/var/run/lcdproc.pid
# slow down initial announcement of modes (in 1/100s)
#delay=2
# display name for the main menu [default: LCDproc HOST]
#DisplayName=lcdproc
## screen specific configuration options ##
[CPU]
# Show screen
Active=True
OnTime=1
OffTime=2
ShowInvisible=false
[Iface]
# Show screen
Active=True
# Show stats for Interface0
Interface0=eth0
# Interface alias name to display [default: <interface name>]
Alias0=LAN
# Show stats for Interface1
#Interface1=eth1
#Alias1=WAN
# Show stats for Interface2
#Interface2=eth2
#Alias2=MGMT
# for more than 3 interfaces change MAX_INTERFACES in iface.h and rebuild
# Units to display [default: byte; legal: byte, bit, packet]
unit=bit
# add screen with transferred traffic
#transfer=TRUE
[Memory]
# Show screen
Active=True
[Load]
# Show screen
Active=True
# Min Load Avg at which the backlight will be turned off [default: 0.05]
LowLoad=0.05
# Max Load Avg at which the backlight will start blinking [default: 1.3]
HighLoad=1.3
[TimeDate]
# Show screen
Active=True
# time format [default: %H:%M:%S; legal: see strftime(3)]
TimeFormat="%H:%M:%S"
# date format [default: %x; legal: see strftime(3)]
DateFormat="%x"
[About]
# Show screen
Active=false
[SMP-CPU]
# Show screen
Active=false
[OldTime]
# Show screen
Active=false
# time format [default: %H:%M:%S; legal: see strftime(3)]
TimeFormat="%H:%M:%S"
# date format [default: %x; legal: see strftime(3)]
DateFormat="%x"
# Display the title bar in two-line mode. Note that with four lines or more
# the title is always shown. [default: true; legal: true, false]
#ShowTitle=false
[BigClock]
# Show screen
Active=false
[Uptime]
# Show screen
Active=false
[Battery]
# Show screen
Active=false
[CPUGraph]
# Show screen
Active=false
[ProcSize]
# Show screen
Active=false
[Disk]
# Show screen
Active=false
[MiniClock]
# Show screen
Active=True
# time format [default: %H:%M; legal: see strftime(3)]
TimeFormat="%H:%M"
# EOF
-137
View File
@@ -1,137 +0,0 @@
/** \file clients/lcdproc/load.c
* Implements the 'Load' screen.
*/
/*-
* This file is part of lcdproc, the lcdproc client.
*
* This file is released under the GNU General Public License.
* Refer to the COPYING file distributed with this package.
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include "shared/configfile.h"
#include "shared/sockets.h"
#include "main.h"
#include "mode.h"
#include "machine.h"
#include "load.h"
/**
* Shows a display very similar to "xload"'s histogram.
*
*\verbatim
*
* +--------------------+ +--------------------+
* |## LOAD 0.44: myh #@| |myhost 0.24 1|
* | 1| | |||||||||||0|
* | |||||| | +--------------------+
* | |||| |||||||| 0|
* +--------------------+
*
*\endverbatim
*
* \param rep Time since last screen update
* \param display 1 if screen is visible or data should be updated
* \param flags_ptr Mode flags
* \return The backlight state
*/
int
xload_screen(int rep, int display, int *flags_ptr)
{
static int gauge_hgt = 0;
static double loads[LCD_MAX_WIDTH];
static double lowLoad = LOAD_MIN;
static double highLoad = LOAD_MAX;
int loadtop, i;
double loadmax = 0, factor;
int status = BACKLIGHT_ON;
if ((*flags_ptr & INITIALIZED) == 0) {
*flags_ptr |= INITIALIZED;
/* get config values */
lowLoad = config_get_float("Load", "LowLoad", 0, LOAD_MIN);
highLoad = config_get_float("Load", "HighLoad", 0, LOAD_MAX);
gauge_hgt = (lcd_hgt > 2) ? (lcd_hgt - 1) : lcd_hgt;
memset(loads, '\0', sizeof(double) * LCD_MAX_WIDTH);
sock_send_string(sock, "screen_add L\n");
sock_printf(sock, "screen_set L -name {Load: %s}\n", get_hostname());
/* Add the vbars... */
for (i = 1; i < lcd_wid; i++) {
sock_printf(sock, "widget_add L bar%i vbar\n", i);
sock_printf(sock, "widget_set L bar%i %i %i 0\n", i, i, lcd_hgt);
}
/* And add a title... */
if (lcd_hgt > 2) {
sock_send_string(sock, "widget_add L title title\n");
sock_send_string(sock, "widget_set L title {LOAD }\n");
} else {
sock_send_string(sock, "widget_add L title string\n");
sock_send_string(sock, "widget_set L title 1 1 {LOAD}\n");
sock_send_string(sock, "screen_set L -heartbeat off\n");
}
sock_send_string(sock, "widget_add L zero string\n");
sock_send_string(sock, "widget_add L top string\n");
sock_printf(sock, "widget_set L zero %i %i 0\n", lcd_wid, lcd_hgt);
sock_printf(sock, "widget_set L top %i %i 1\n", lcd_wid, (lcd_hgt + 1 - gauge_hgt));
}
/* shift load history */
for (i = 0; i < (lcd_wid - 2); i++)
loads[i] = loads[i + 1];
/*
* get new load value, ignore failure: the shift above makes sure we
* still have the previous value
*/
machine_get_loadavg(&(loads[lcd_wid - 2]));
/* determine max. load from history */
for (i = 0; i < lcd_wid - 1; i++)
loadmax = max(loadmax, loads[i]);
/* poor man's ceil() */
loadtop = (int) loadmax;
if (loadtop < loadmax)
loadtop++;
loadtop = max(1, loadtop);
factor = (double) (lcd_cellhgt * gauge_hgt) / (double) loadtop;
/* display load */
sock_printf(sock, "widget_set L top %i %i %i\n", lcd_wid, (lcd_hgt + 1 - gauge_hgt), loadtop);
for (i = 0; i < lcd_wid - 1; i++) {
double x = loads[i] * factor;
sock_printf(sock, "widget_set L bar%i %i %i %i\n", i + 1, i + 1, lcd_hgt, (int) x);
}
/* And now the title... */
if (lcd_hgt > 2)
sock_printf(sock, "widget_set L title {LOAD %2.2f: %s}\n", loads[lcd_wid - 2], get_hostname());
else
sock_printf(sock, "widget_set L title 1 1 {%s %2.2f}\n", get_hostname(), loads[lcd_wid - 2]);
/* set return status depending on max & current load */
if (lowLoad < highLoad) {
status = (loadmax > lowLoad) ? BACKLIGHT_ON : BACKLIGHT_OFF;
if (loads[lcd_wid - 2] > highLoad)
status = BLINK_ON;
}
return status;
}
-13
View File
@@ -1,13 +0,0 @@
#ifndef LOAD_H
#define LOAD_H
#ifndef LOAD_MAX
#define LOAD_MAX 1.3
#endif
#ifndef LOAD_MIN
#define LOAD_MIN 0.05
#endif
int xload_screen(int rep, int display, int *flags_ptr);
#endif
-208
View File
@@ -1,208 +0,0 @@
/** \file clients/lcdproc/machine.h
* Common data types and function declarations
* for OS specific sources in \c machine_{Darwin,Linux,SunOS,*BSD}.c.
*
* In order to port the \e lcdproc client to a new operating system,
* a new file \c machine_XXX.c (where \c XXX = OS name) needs to be
* created, that provides functions to the function declarations below.
* The aleady existing \c machine_*.c files can be used as examples.
*
*/
#ifndef _lcdproc_machine_h_
#define _lcdproc_machine_h_
#include "shared/LL.h"
#ifndef LOADAVG_NSTATS
# define LOADAVG_NSTATS 3 /**< size of loadavg[] parameter to getloadavg() */
#endif
#ifndef LOADAVG_1MIN
# define LOADAVG_1MIN 0 /**< index in loadavg[] parameter to getloadavg() for 1 minute load average */
#endif
#ifndef LOADAVG_5MIN
# define LOADAVG_5MIN 1 /**< index in loadavg[] parameter to getloadavg() for 5 minute load average */
#endif
#ifndef LOADAVG_15MIN
# define LOADAVG_15MIN 2 /**< index in loadavg[] parameter to getloadavg() for 15 minute load average */
#endif
#ifndef MAX_CPUS
# define MAX_CPUS 16 /**< maximal number of CPUs for which load history is kept */
#endif
/** Information about CPU load */
typedef struct
{
unsigned long total; /**< total time (in USER_HZ; since last call) */
unsigned long user; /**< time in user mode (in USER_HZ; since last call) */
unsigned long system; /**< time in kernel mode (in USER_HZ; since last call) */
unsigned long nice; /**< time in 'niced' user mode (in USER_HZ; since last call) */
unsigned long idle; /**< time idling (in USER_HZ; since last call) */
} load_type;
/** Information about mounted file systems */
typedef struct
{
char dev[256]; /**< device name */
char type[64]; /**< file system type (as string) */
char mpoint[256]; /**< mount point name */
long bsize; /**< transfer block size */
long blocks; /**< total data blocks in file system */
long bfree; /**< free blocks in fs */
long files; /**< total file nodes in file system */
long ffree; /**< free file nodes in fs */
} mounts_type;
/** Information about memory status */
typedef struct
{
long total; /**< total memory (in kB) */
long cache; /**< memory in page cache (in kB) */
long buffers; /**< memory in buffer cache (in kB) */
long free; /**< free memory (in kB) */
long shared; /**< ??? (in kB) */
} meminfo_type;
/** Information about processes and their size */
typedef struct
{
char name[16]; /**< process name */
long totl; /**< process memory usage (in kB) */
int number; /**< incstances of the process */
} procinfo_type;
/** Status definitions for network interfaces */
typedef enum {
down = 0,
up = 1,
} IfaceStatus;
/* Network Interface information */
typedef struct iface_info
{
char *name; /**< physical interface name */
char *alias; /**< displayed name of interface */
IfaceStatus status; /**< status of the interface */
time_t last_online;
double rc_byte; /**< currently received bytes */
double rc_byte_old; /**< previously received bytes */
double tr_byte; /**< currently sent bytes */
double tr_byte_old; /**< previously sent bytes */
double rc_pkt; /**< currently received packages */
double rc_pkt_old; /**< previously received packages */
double tr_pkt; /**< currently sent packages */
double tr_pkt_old; /**< previously sent packages */
} IfaceInfo;
/**
* Set up OS specific functions.
* \retval FALSE Error
* \retval TRUE OK
*/
int machine_init(void);
/**
* Tear down (clean up) OS specific functions.
* \retval FALSE Error
* \retval TRUE OK
*/
int machine_close(void);
/**
* Get battery information.
* \param acstat Pointer to information whether the system runs on AC power or on battery.
* \param battflag Pointer to information about the battery load status.
* \param percent Pointer to the battery fill state.
* \retval FALSE Error, do not trust the contents of the parameter pointers.
* \retval TRUE OK, parameter pointers are filled with sensible data.
*/
int machine_get_battstat(int *acstat, int *battflag, int *percent);
/**
* get information about mounted file systems.
* \param fs Pointer to array where file system information gets stored.
* \param cnt Number of mounted file systems.
* \retval FALSE Error, do not trust the contents of the parameter pointers.
* \retval TRUE OK, parameter pointers are filled with sensible data.
*/
int machine_get_fs(mounts_type fs[], int *cnt);
/**
* Get total CPU load (added over all CPUs).
* \param cur_load Pointer where to store current load information.
* \retval FALSE Error, do not trust the contents of the parameter pointers.
* \retval TRUE OK, parameter pointers are filled with sensible data.
*/
int machine_get_load(load_type *cur_load);
/**
* Get load 1min load average.
* \param load Pointer where to store the current 1min load average.
* \retval FALSE Error, do not trust the contents of the parameter pointers.
* \retval TRUE OK, parameter pointers are filled with sensible data.
*/
int machine_get_loadavg(double *load);
/**
* Get information about memory.
* \param result Pointer where meminfo is to be stored.
* \retval FALSE Error, do not trust the contents of the parameter pointers.
* \retval TRUE OK, parameter pointers are filled with sensible data.
*/
int machine_get_meminfo(meminfo_type *result);
/**
* Get list of processes and their sizes.
* \param procs Pointer where to store the linked List of processes.
* \retval FALSE Error, do not trust the contents of the parameter pointers.
* \retval TRUE OK, parameter pointers are filled with sensible data.
*/
int machine_get_procs(LinkedList *procs);
/**
* Get CPU load split up for each CPU.
* \param result Pointer to array of CPU load info.
* \param numcpus Number of CPUs found.
* \retval FALSE Error, do not trust the contents of the parameter pointers.
* \retval TRUE OK, parameter pointers are filled with sensible data.
*/
int machine_get_smpload(load_type *result, int *numcpus);
/**
* Get uptime.
* \param up Pointer to store the uptime in seconds.
* \param idle Pointer to store the percentage in which the CPUs idled since boot.
* \retval FALSE Error, do not trust the contents of the parameter pointers.
* \retval TRUE OK, parameter pointers are filled with sensible data.
*/
int machine_get_uptime(double *up, double *idle);
/**
* Read network interface statistics for a single interface from system and
* store results in the struct IfaceInfo.
*
* \param interface Pointer where to store interface info.
* \retval FALSE Error, do not trust the contents of the parameter pointers.
* \retval TRUE OK, parameter pointers are filled with sensible data.
*/
int machine_get_iface_stats(IfaceInfo *interface);
#endif /* _lcdproc_machine_h_ */
-549
View File
@@ -1,549 +0,0 @@
/** \file clients/lcdproc/machine_Darwin.c
* Collects system information on MacOS / Darwin.
*/
/*-
* Copyright (c) 2003 Thomas Runge (coto@core.de)
*
* Mach and Darwin specific code is:
* Copyright (c) 2006 Eric Pooch (epooch@tenon.com)
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the author nor the names of its contributors
* may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifdef __APPLE__
#include <sys/types.h>
#include <sys/param.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <sys/sysctl.h>
#include <sys/dkstat.h>
#include <sys/ucred.h>
#include <sys/mount.h>
#include <sys/time.h>
#include <sys/user.h>
#include <errno.h>
#include <sys/socket.h>
#include <net/if.h>
#include <net/if_mib.h>
#include <mach/mach.h>
#include "main.h"
#include "machine.h"
#include "config.h"
#include "shared/LL.h"
#include <CoreFoundation/CoreFoundation.h>
#include <IOKit/ps/IOPowerSources.h>
#include <IOKit/ps/IOPSKeys.h>
static int pageshift;
#define pagetok(size) ((size) << pageshift)
static int swapmode(int *rettotal, int *retfree);
static mach_port_t lcdproc_port;
int
machine_init(void)
{
/*
* get the page size with "getpagesize" and calculate pageshift from
* it
*/
unsigned int pagesize = 0;
pageshift = 0;
lcdproc_port = mach_host_self();
host_page_size(lcdproc_port, &pagesize);
while (pagesize > 1) {
pageshift++;
pagesize >>= 1;
}
/* we only need the amount of log(2)1024 for our conversion */
pageshift -= 10;
return (TRUE);
}
int
machine_close(void)
{
return (TRUE);
}
int
machine_get_battstat(int *acstat, int *battflag, int *percent)
{
CFTypeRef blob = IOPSCopyPowerSourcesInfo();
CFArrayRef sources = IOPSCopyPowerSourcesList(blob);
int i;
CFDictionaryRef pSource = NULL;
const void *psValue;
*acstat = LCDP_AC_ON;
*battflag = LCDP_BATT_ABSENT;
*percent = 100;
if (CFArrayGetCount(sources) == 0)
return (FALSE);
for (i = 0; i < CFArrayGetCount(sources); i++) {
pSource = IOPSGetPowerSourceDescription(blob, CFArrayGetValueAtIndex(sources, i));
if (!pSource)
break;
psValue = (CFStringRef) CFDictionaryGetValue(pSource, CFSTR(kIOPSNameKey));
if (CFDictionaryGetValueIfPresent(pSource, CFSTR(kIOPSIsPresentKey), &psValue) && (CFBooleanGetValue(psValue) > 0)) {
psValue = (CFStringRef) CFDictionaryGetValue(pSource, CFSTR(kIOPSPowerSourceStateKey));
if (CFStringCompare(psValue, CFSTR(kIOPSBatteryPowerValue), 0) == kCFCompareEqualTo) {
/* We are running on a battery power source. */
*battflag = LCDP_BATT_UNKNOWN;
*acstat = LCDP_AC_OFF;
}
else if (CFDictionaryGetValueIfPresent(pSource, CFSTR(kIOPSIsChargingKey), &psValue)) {
/*
* We are running on an AC power source, but
* we also have a battery power source
* present.
*/
if (CFBooleanGetValue(psValue) > 0)
*battflag = LCDP_BATT_CHARGING;
else
*battflag = LCDP_BATT_UNKNOWN;
}
if (*battflag != LCDP_BATT_ABSENT) {
int curCapacity = 0;
int maxCapacity = 0;
psValue = CFDictionaryGetValue(pSource, CFSTR(kIOPSCurrentCapacityKey));
CFNumberGetValue(psValue, kCFNumberSInt32Type, &curCapacity);
psValue = CFDictionaryGetValue(pSource, CFSTR(kIOPSMaxCapacityKey));
CFNumberGetValue(psValue, kCFNumberSInt32Type, &maxCapacity);
*percent = (int)((double)curCapacity / (double)maxCapacity * 100);
/*
* There is a way to check this through the
* IOKit, but I am not sure what gets
* returned for kIOPSLowWarnLevelKey and
* kIOPSDeadWarnLevelKey, and this is easier.
*/
if (*battflag == LCDP_BATT_UNKNOWN) {
if (*percent > 50)
*battflag = LCDP_BATT_HIGH;
else if (*percent > 2)
*battflag = LCDP_BATT_LOW;
else
*battflag = LCDP_BATT_CRITICAL;
}
/* printf ("powerSource %d of %d: percent: %d/%d %d\n", i, CFArrayGetCount(sources), curCapacity, maxCapacity, *percent);*/
}
}
}
CFRelease(blob);
CFRelease(sources);
return (TRUE);
}
int
machine_get_fs(mounts_type fs[], int *cnt)
{
struct statfs *mntbuf;
struct statfs *pp;
int statcnt, fscnt, i;
fscnt = getmntinfo(&mntbuf, MNT_WAIT);
if (fscnt == 0) {
perror("getmntinfo");
return (FALSE);
}
for (statcnt = 0, pp = mntbuf, i = 0; i < fscnt; pp++, i++) {
if (strcmp(pp->f_fstypename, "procfs")
&& strcmp(pp->f_fstypename, "kernfs")
&& strcmp(pp->f_fstypename, "linprocfs")
#ifndef STAT_NFS
&& strcmp(pp->f_fstypename, "nfs")
#endif
#ifndef STAT_SMBFS
&& strcmp(pp->f_fstypename, "smbfs")
#endif
) {
snprintf(fs[statcnt].dev, 255, "%s", pp->f_mntfromname);
snprintf(fs[statcnt].mpoint, 255, "%s", pp->f_mntonname);
snprintf(fs[statcnt].type, 63, "%s", pp->f_fstypename);
fs[statcnt].blocks = pp->f_blocks;
if (fs[statcnt].blocks > 0) {
fs[statcnt].bsize = pp->f_bsize;
fs[statcnt].bfree = pp->f_bfree;
fs[statcnt].files = pp->f_files;
fs[statcnt].ffree = pp->f_ffree;
}
statcnt++;
}
}
*cnt = statcnt;
return (TRUE);
}
int
machine_get_load(load_type * curr_load)
{
static load_type last_load = {0, 0, 0, 0, 0};
static load_type last_ret_load;
load_type load;
host_cpu_load_info_data_t load_info;
mach_msg_type_number_t info_count;
info_count = HOST_CPU_LOAD_INFO_COUNT;
if (host_statistics(lcdproc_port, HOST_CPU_LOAD_INFO, (host_info_t) & load_info, &info_count)) {
perror("host_statistics");
return (FALSE);
}
load.user = (unsigned long)(load_info.cpu_ticks[CPU_STATE_USER]);
load.nice = (unsigned long)(load_info.cpu_ticks[CPU_STATE_NICE]);
load.system = (unsigned long)(load_info.cpu_ticks[CPU_STATE_SYSTEM]);
load.idle = (unsigned long)(load_info.cpu_ticks[CPU_STATE_IDLE]);
load.total = load.user + load.nice + load.system + load.idle;
if (load.total != last_load.total) {
curr_load->user = load.user - last_load.user;
curr_load->nice = load.nice - last_load.nice;
curr_load->system = load.system - last_load.system;
curr_load->idle = load.idle - last_load.idle;
curr_load->total = load.total - last_load.total;
last_ret_load = *curr_load;
last_load = load;
}
else {
*curr_load = last_ret_load;
}
return TRUE;
}
int
machine_get_loadavg(double *load)
{
double loadavg[LOADAVG_NSTATS];
if (getloadavg(loadavg, LOADAVG_NSTATS) <= LOADAVG_1MIN)
return (FALSE);
*load = loadavg[LOADAVG_1MIN];
return (TRUE);
}
int
machine_get_meminfo(meminfo_type * result)
{
int total_pages, free_pages;
vm_statistics_data_t vm_info;
mach_msg_type_number_t info_count;
info_count = HOST_VM_INFO_COUNT;
if (host_statistics(lcdproc_port, HOST_VM_INFO, (host_info_t) & vm_info, &info_count)) {
perror("host_statistics");
return (FALSE);
}
result[0].total = pagetok(vm_info.active_count + vm_info.inactive_count +
vm_info.free_count + vm_info.wire_count);
result[0].free = pagetok(vm_info.free_count);
result[0].buffers = 0;
result[0].cache = 0;
result[0].shared = 0;
/* swap */
result[1].total = 0;
result[1].free = 0;
if (swapmode(&total_pages, &free_pages) != -1) {
result[1].total = total_pages;
result[1].free = free_pages;
}
return (TRUE);
}
int
machine_get_procs(LinkedList * procs)
{
struct kinfo_proc *kprocs;
procinfo_type *p;
int nproc, i;
int mib[] = {CTL_KERN, KERN_PROC, KERN_PROC_ALL, 0};
size_t size = 0;
/* Call sysctl with a NULL buffer as a dry run. */
if (sysctl(mib, 4, NULL, &size, NULL, 0) < 0) {
perror("Failure calling sysctl");
return FALSE;
}
/* Allocate a buffer based on previous results of sysctl. */
kprocs = (struct kinfo_proc *)alloca(size);
if (kprocs == NULL) {
perror("mem_alloca");
return FALSE;
}
/* Call sysctl again with the new buffer. */
if (sysctl(mib, 4, kprocs, &size, NULL, 0) < 0) {
perror("Failure calling sysctl");
return FALSE;
}
nproc = size / sizeof(struct kinfo_proc);
for (i = 0; i < nproc; i++, kprocs++) {
mach_port_t task;
unsigned int status = kprocs->kp_proc.p_stat;
if (status == SIDL || status == SZOMB)
continue;
p = malloc(sizeof(procinfo_type));
if (!p) {
perror("mem_malloc");
continue;
}
strncpy(p->name, kprocs->kp_proc.p_comm, 15);
p->name[15] = '\0';
p->number = kprocs->kp_proc.p_pid;
LL_Push(procs, (void *)p);
/* Normal user can't get tasks for processes owned by root. */
if (kprocs->kp_eproc.e_pcred.p_ruid == 0)
continue;
/* Get the memory data for each pid from Mach. */
if (task_for_pid(mach_task_self(), kprocs->kp_proc.p_pid, &task) == KERN_SUCCESS) {
task_basic_info_data_t info;
mach_msg_type_number_t count = TASK_BASIC_INFO_COUNT;
if (task_info(task, TASK_BASIC_INFO, (task_info_t) & info, &count) == KERN_SUCCESS) {
p->totl = (unsigned long)( /* info.virtual_size */ info.resident_size / 1024);
}
}
else {
/*
* This error pops up very often because of Mac OS X
* security fixes. It might pop up all of the time on
* an intel Mac. Basically, we cannot get many tasks
* unless we are root.
*/
/* perror("task_for_pid"); */
p->totl = 0;
}
}
kprocs -= i;
return (TRUE);
}
int
machine_get_smpload(load_type * result, int *numcpus)
{
int i, num;
size_t size;
load_type curr_load;
size = sizeof(int);
if (sysctlbyname("hw.ncpu", &num, &size, NULL, 0) < 0) {
perror("sysctl hw.ncpu");
return (FALSE);
}
if (machine_get_load(&curr_load) == FALSE)
return (FALSE);
if (numcpus == NULL)
return (FALSE);
/* restrict #CPUs to max. *numcpus */
num = (*numcpus >= num) ? num : *numcpus;
*numcpus = num;
/* Don't know how to get per-cpu-load values */
for (i = 0; i < num; i++) {
result[i] = curr_load;
}
return (TRUE);
}
int
machine_get_uptime(double *up, double *idle)
{
size_t size;
time_t now;
struct timeval boottime;
load_type curr_load;
int mib[2];
mib[0] = CTL_KERN;
mib[1] = KERN_BOOTTIME;
size = sizeof(boottime);
time(&now);
if (sysctl(mib, 2, &boottime, &size, NULL, 0) != -1 &&
boottime.tv_sec != 0)
*up = (double)(now - boottime.tv_sec);
if (machine_get_load(&curr_load) == FALSE)
*idle = 100.;
else
*idle = 100. * curr_load.idle / curr_load.total;
return (TRUE);
}
static int
swapmode(int *rettotal, int *retfree)
{
#ifdef VM_SWAPUSAGE
size_t size;
struct xsw_usage xsu;
int mib[2];
mib[0] = CTL_VM;
mib[1] = VM_SWAPUSAGE;
size = sizeof(xsu);
*rettotal = 0;
*retfree = 0;
if (sysctl(mib, 2, &xsu, &size, NULL, 0) != 0) {
perror("sysctl");
return (FALSE);
}
*rettotal = (xsu.xsu_total / 1024);
*retfree = ((xsu.xsu_total - xsu.xsu_used) / 1024);
return (TRUE);
#endif
*rettotal = 0;
*retfree = 0;
return (FALSE);
}
/* Get network statistics */
int
machine_get_iface_stats(IfaceInfo * interface)
{
int rows;
int name[6] = {CTL_NET, PF_LINK, NETLINK_GENERIC, IFMIB_SYSTEM, IFMIB_IFCOUNT};
size_t len;
struct ifmibdata ifmd; /* ifmibdata contains the network statistics */
len = sizeof(rows);
/* get number of interfaces */
if (sysctl(name, 5, &rows, &len, 0, 0) == 0) {
interface->status = down; /* set status down by default */
name[3] = IFMIB_IFDATA;
name[4] = 0;
name[5] = IFDATA_GENERAL;
len = sizeof(ifmd);
/*
* walk through all interfaces in the ifmib table from last
* to first
*/
for (; rows > 0; rows--) {
name[4] = rows; /* set the interface index */
/* retrive the ifmibdata for the current index */
if (sysctl(name, 6, &ifmd, &len, NULL, 0) == -1) {
perror("read sysctl");
break;
}
/* check if its interface name matches */
if (strcmp(ifmd.ifmd_name, interface->name) == 0) {
interface->rc_byte = ifmd.ifmd_data.ifi_ibytes;
interface->tr_byte = ifmd.ifmd_data.ifi_obytes;
interface->rc_pkt = ifmd.ifmd_data.ifi_ipackets;
interface->tr_pkt = ifmd.ifmd_data.ifi_opackets;
if (interface->last_online == 0) {
interface->rc_byte_old = interface->rc_byte;
interface->tr_byte_old = interface->tr_byte;
interface->rc_pkt_old = interface->rc_pkt;
interface->tr_pkt_old = interface->tr_pkt;
}
if ((ifmd.ifmd_flags & IFF_UP) == IFF_UP) {
interface->status = up; /* is up */
interface->last_online = time(NULL); /* save actual time */
}
return (TRUE);
}
}
/* if we are here there is no interface with the given name */
return (TRUE);
}
else {
perror("read sysctl IFMIB_IFCOUNT");
return (FALSE);
}
}
#endif /* __APPLE__ */
-536
View File
@@ -1,536 +0,0 @@
/** \file clients/lcdproc/machine_FreeBSD.c
* Collects system information on FreeBSD.
*/
/*-
* Copyright (c) 2003 Thomas Runge (coto@core.de)
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the author nor the names of its contributors
* may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifdef __FreeBSD__
#include <sys/types.h>
#include <sys/param.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <sys/sysctl.h>
#include <sys/dkstat.h>
#include <sys/ucred.h>
#include <sys/mount.h>
#include <sys/time.h>
#include <sys/user.h>
#include <kvm.h>
#include <errno.h>
#include <sys/socket.h>
#include <net/if.h>
#include <net/if_mib.h>
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#ifdef HAVE_MACHINE_APM_BIOS_H
# include <machine/apm_bios.h>
#endif
#ifdef HAVE_SYS_PCPU_H
# include <sys/pcpu.h>
#endif
#include "main.h"
#include "machine.h"
#include "shared/LL.h"
static int pageshift;
static kvm_t *kvmd;
#define pagetok(size) ((size) << pageshift)
static int swapmode(int *retavail, int *retfree);
int
machine_init(void)
{
/*
* get the page size with "getpagesize" and calculate pageshift from
* it
*/
int pagesize = getpagesize();
pageshift = 0;
while (pagesize > 1) {
pageshift++;
pagesize >>= 1;
}
/* we only need the amount of log(2)1024 for our conversion */
pageshift -= 10;
/* open kernel virtual memory */
if ((kvmd = kvm_open(NULL, NULL, NULL, O_RDONLY, "kvm_open")) == NULL) {
perror("kvm_open failed");
return (FALSE);
}
return (TRUE);
}
int
machine_close(void)
{
if (kvmd != NULL) {
kvm_close(kvmd);
kvmd = NULL;
}
return (TRUE);
}
int
machine_get_battstat(int *acstat, int *battflag, int *percent)
{
*acstat = LCDP_AC_ON;
*battflag = LCDP_BATT_ABSENT;
*percent = 100;
#ifdef HAVE_MACHINE_APM_BIOS_H
int apmd;
struct apm_info aip;
if ((apmd = open("/dev/apm", O_RDONLY)) == -1) {
perror("get_battstat_open");
return (TRUE);
}
if (ioctl(apmd, APMIO_GETINFO, &aip) == -1) {
perror("get_battstat_ioctl");
return (FALSE);
}
switch (aip.ai_acline) {
case 0:
*acstat = LCDP_AC_OFF;
break;
case 1:
*acstat = LCDP_AC_ON;
break;
default:
*acstat = LCDP_AC_UNKNOWN;
break;
}
switch (aip.ai_batt_stat) {
case 0:
*battflag = LCDP_BATT_HIGH;
break;
case 1:
*battflag = LCDP_BATT_LOW;
break;
case 2:
*battflag = LCDP_BATT_CRITICAL;
break;
case 3:
*battflag = LCDP_BATT_CHARGING;
break;
default:
*battflag = LCDP_BATT_UNKNOWN;
break;
}
*percent = aip.ai_batt_life;
if (*percent == 255)
*percent = -1;
close(apmd);
#endif
return (TRUE);
}
int
machine_get_fs(mounts_type fs[], int *cnt)
{
struct statfs *mntbuf;
struct statfs *pp;
int statcnt, fscnt, i;
fscnt = getmntinfo(&mntbuf, MNT_WAIT);
if (fscnt == 0) {
perror("getmntinfo");
return (FALSE);
}
for (statcnt = 0, pp = mntbuf, i = 0; i < fscnt; pp++, i++) {
if (strcmp(pp->f_fstypename, "procfs")
&& strcmp(pp->f_fstypename, "devfs")
&& strcmp(pp->f_fstypename, "kernfs")
&& strcmp(pp->f_fstypename, "linprocfs")
#ifndef STAT_NFS
&& strcmp(pp->f_fstypename, "nfs")
#endif
#ifndef STAT_SMBFS
&& strcmp(pp->f_fstypename, "smbfs")
#endif
) {
snprintf(fs[statcnt].dev, 255, "%s", pp->f_mntfromname);
snprintf(fs[statcnt].mpoint, 255, "%s", pp->f_mntonname);
snprintf(fs[statcnt].type, 63, "%s", pp->f_fstypename);
fs[statcnt].blocks = pp->f_blocks;
if (fs[statcnt].blocks > 0) {
fs[statcnt].bsize = pp->f_bsize;
fs[statcnt].bfree = pp->f_bfree;
fs[statcnt].files = pp->f_files;
fs[statcnt].ffree = pp->f_ffree;
}
statcnt++;
}
}
*cnt = statcnt;
return (TRUE);
}
int
machine_get_load(load_type * curr_load)
{
static load_type last_load = {0, 0, 0, 0, 0};
static load_type last_ret_load;
load_type load;
long cp_time[CPUSTATES];
size_t size;
size = sizeof(cp_time);
if (sysctlbyname("kern.cp_time", cp_time, &size, NULL, 0) < 0) {
perror("sysctl kern.cp_time failed");
return (FALSE);
}
load.user = (unsigned long)(cp_time[CP_USER]);
load.nice = (unsigned long)(cp_time[CP_NICE]);
load.system = (unsigned long)(cp_time[CP_SYS] + cp_time[CP_INTR]);
load.idle = (unsigned long)(cp_time[CP_IDLE]);
load.total = load.user + load.nice + load.system + load.idle;
if (load.total != last_load.total) {
curr_load->user = load.user - last_load.user;
curr_load->nice = load.nice - last_load.nice;
curr_load->system = load.system - last_load.system;
curr_load->idle = load.idle - last_load.idle;
curr_load->total = load.total - last_load.total;
last_ret_load = *curr_load;
last_load = load;
}
else {
*curr_load = last_ret_load;
}
return (TRUE);
}
int
machine_get_loadavg(double *load)
{
double loadavg[LOADAVG_NSTATS];
if (getloadavg(loadavg, LOADAVG_NSTATS) <= LOADAVG_1MIN)
return (FALSE);
*load = loadavg[LOADAVG_1MIN];
return (TRUE);
}
int
machine_get_meminfo(meminfo_type * result)
{
int total_pages, free_pages;
size_t size;
size = sizeof(int);
if (sysctlbyname("vm.stats.vm.v_page_count", &total_pages, &size, NULL, 0) < 0) {
perror("sysctl vm.stats.vm.v_page_count");
return (FALSE);
}
if (sysctlbyname("vm.stats.vm.v_free_count", &free_pages, &size, NULL, 0) < 0) {
perror("sysctl vm.stats.vm.v_free_count");
return (FALSE);
}
/* memory */
result[0].total = pagetok(total_pages);
result[0].free = pagetok(free_pages);
/* unused anyway */
result[0].shared = 0;
result[0].buffers = 0;
result[0].cache = 0;
/* swap */
result[1].total = 0;
result[1].free = 0;
if (swapmode(&total_pages, &free_pages) != -1) {
result[1].total = total_pages;
result[1].free = free_pages;
}
return (TRUE);
}
int
machine_get_procs(LinkedList * procs)
{
struct kinfo_proc *kprocs;
int nproc, i;
procinfo_type *p;
if (kvmd == NULL)
return (FALSE);
kprocs = kvm_getprocs(kvmd, KERN_PROC_PROC, 0, &nproc);
if (kprocs == NULL) {
perror("kvm_getprocs");
return (FALSE);
}
for (i = 0; i < nproc; i++) {
p = malloc(sizeof(procinfo_type));
if (!p) {
perror("mem_top_malloc");
return (FALSE);
}
#if (__FreeBSD_version > 500000)
strncpy(p->name, kprocs->ki_comm, 15);
#else
strncpy(p->name, kprocs->kp_proc.p_comm, 15);
#endif
p->name[15] = '\0';
#if (__FreeBSD_version > 500000)
p->totl = kprocs->ki_size / 1024;
p->number = kprocs->ki_pid;
#else
p->totl = kprocs->kp_eproc.e_vm.vm_map.size / 1024;
p->number = kprocs->kp_proc.p_pid;
#endif
LL_Push(procs, (void *)p);
kprocs++;
}
return (TRUE);
}
int
machine_get_smpload(load_type * result, int *numcpus)
{
int i, num;
size_t size;
load_type load;
#ifdef HAVE_SYS_PCPU_H
static load_type last_load[MAX_CPUS];
struct pcpu *pcpudata;
if (kvmd == NULL)
return (FALSE);
#endif
if (numcpus == NULL)
return (FALSE);
size = sizeof(int);
if (sysctlbyname("hw.ncpu", &num, &size, NULL, 0) < 0) {
perror("sysctl hw.ncpu");
return (FALSE);
}
/* restrict #CPUs to max. *numcpus */
num = (*numcpus >= num) ? num : *numcpus;
*numcpus = num;
#ifndef HAVE_SYS_PCPU_H
if (machine_get_load(&load) == FALSE)
return (FALSE);
#endif
for (i = 0; i < num; i++) {
#ifdef HAVE_SYS_PCPU_H
pcpudata = kvm_getpcpu(kvmd, i);
if (pcpudata == NULL || pcpudata == (void *)-1)
return (FALSE);
/* extract the data for single CPU */
load.user = (unsigned long)(pcpudata->pc_cp_time[CP_USER]);
load.nice = (unsigned long)(pcpudata->pc_cp_time[CP_NICE]);
load.system = (unsigned long)(pcpudata->pc_cp_time[CP_SYS] +
pcpudata->pc_cp_time[CP_INTR]);
load.idle = (unsigned long)(pcpudata->pc_cp_time[CP_IDLE]);
load.total = load.user + load.nice + load.system + load.idle;
/* store difference in result */
result[i].user = load.user - last_load[i].user;
result[i].nice = load.nice - last_load[i].nice;
result[i].system = load.system - last_load[i].system;
result[i].idle = load.idle - last_load[i].idle;
result[i].total = load.total - last_load[i].total;
/* store current value for next round */
last_load[i].user = load.user;
last_load[i].nice = load.nice;
last_load[i].system = load.system;
last_load[i].idle = load.idle;
last_load[i].total = load.total;
/* free pcpu buffer */
free(pcpudata);
#else
result[i] = load;
#endif
}
return (TRUE);
}
int
machine_get_uptime(double *up, double *idle)
{
size_t size;
time_t now;
struct timeval boottime;
load_type curr_load;
size = sizeof(boottime);
time(&now);
if (sysctlbyname("kern.boottime", &boottime, &size, NULL, 0) < 0) {
perror("sysctl kern.cp_time failed");
return (FALSE);
}
*up = (double)(now - boottime.tv_sec);
if (machine_get_load(&curr_load) == FALSE)
*idle = 100.;
else
*idle = 100. * curr_load.idle / curr_load.total;
return (TRUE);
}
/**
* Reads info about swap space from system and returns it in parameters passed.
* \param retavail Total available swap space
* \param retfree Free swap space
* \return -1 on error, otherwise number of swap areas (typically 0 for total)
*/
static int
swapmode(int *retavail, int *retfree)
{
int n;
struct kvm_swap swapary[1];
*retavail = 0;
*retfree = 0;
if (kvmd == NULL)
return -1;
n = kvm_getswapinfo(kvmd, swapary, 1, 0);
if (n < 0 || swapary[0].ksw_total == 0) {
/* strange */
}
else {
*retavail = pagetok(swapary[0].ksw_total);
*retfree = pagetok(swapary[0].ksw_total - swapary[0].ksw_used);
}
return (n);
}
int
machine_get_iface_stats(IfaceInfo * interface)
{
int rows;
int name[6] = {CTL_NET, PF_LINK, NETLINK_GENERIC, IFMIB_IFDATA, 0, IFDATA_GENERAL};
size_t len;
struct ifmibdata ifmd; /* ifmibdata contains the network statistics */
len = sizeof(rows);
/* get number of interfaces */
if (sysctlbyname("net.link.generic.system.ifcount", &rows, &len, NULL, 0) == 0) {
interface->status = down; /* set status down by default */
len = sizeof(ifmd);
/*
* walk through all interfaces in the ifmib table from last
* to first
*/
for (; rows > 0; rows--) {
name[4] = rows; /* set the interface index */
/* retrive the ifmibdata for the current index */
if (sysctl(name, 6, &ifmd, &len, NULL, 0) == -1) {
perror("read sysctl");
break;
}
/* check if its interface name matches */
if (strcmp(ifmd.ifmd_name, interface->name) == 0) {
interface->rc_byte = ifmd.ifmd_data.ifi_ibytes;
interface->tr_byte = ifmd.ifmd_data.ifi_obytes;
interface->rc_pkt = ifmd.ifmd_data.ifi_ipackets;
interface->tr_pkt = ifmd.ifmd_data.ifi_opackets;
if (interface->last_online == 0) {
interface->rc_byte_old = interface->rc_byte;
interface->tr_byte_old = interface->tr_byte;
interface->rc_pkt_old = interface->rc_pkt;
interface->tr_pkt_old = interface->tr_pkt;
}
if ((ifmd.ifmd_flags & IFF_UP) == IFF_UP) {
interface->status = up; /* is up */
interface->last_online = time(NULL); /* save actual time */
}
return (TRUE);
}
}
/* if we are here there is no interface with the given name */
return (TRUE);
}
else {
perror("read sysctlbyname");
return (FALSE);
}
}
#endif /* __FreeBSD__ */
-631
View File
@@ -1,631 +0,0 @@
/** \file clients/lcdproc/machine_Linux.c
* Collects system information on Linux.
*/
/*-
* This file is part of lcdproc, the lcdproc client.
*
* This file is released under the GNU General Public License.
* Refer to the COPYING file distributed with this package.
*/
#ifdef linux
#include <sys/types.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <ctype.h>
#include <string.h>
#include <fcntl.h>
#include <dirent.h>
#include <sys/param.h>
#include <sys/utsname.h>
#include <sys/stat.h>
#include <sys/statvfs.h>
#include <errno.h>
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#if TIME_WITH_SYS_TIME
# include <sys/time.h>
# include <time.h>
#else
# if HAVE_SYS_TIME_H
# include <sys/time.h>
# else
# include <time.h>
# endif
#endif
#ifdef HAVE_GETLOADAVG
# define USE_GETLOADAVG
#endif
#ifdef USE_GETLOADAVG
# ifdef HAVE_SYS_LOADAVG_H
# include <sys/loadavg.h>
# endif
#endif
#ifdef HAVE_PROCFS_H
# include <procfs.h>
#endif
#ifdef HAVE_SYS_PROCFS_H
# include <sys/procfs.h>
#endif
#include "main.h"
#include "mode.h"
#include "machine.h"
#include "shared/LL.h"
static int batt_fd;
static int load_fd;
static int loadavg_fd;
static int meminfo_fd;
static int uptime_fd;
static char procbuf[1024]; /* TODO ugly hack! */
static FILE *mtab_fd;
int
machine_init(void)
{
uptime_fd = -1;
batt_fd = -1;
load_fd = -1;
loadavg_fd = -1;
meminfo_fd = -1;
if (uptime_fd < 0) {
uptime_fd = open("/proc/uptime", O_RDONLY);
if (uptime_fd < 0) {
perror("open /proc/uptime");
return (FALSE);
}
}
if (load_fd < 0) {
load_fd = open("/proc/stat", O_RDONLY);
if (load_fd < 0) {
perror("open /proc/stat");
return (FALSE);
}
}
#ifndef USE_GETLOADAVG
if (loadavg_fd < 0) {
loadavg_fd = open("/proc/loadavg", O_RDONLY);
if (loadavg_fd < 0) {
perror("open /proc/loadavg");
return (FALSE);
}
}
#endif
if (meminfo_fd < 0) {
meminfo_fd = open("/proc/meminfo", O_RDONLY);
if (meminfo_fd < 0) {
perror("open /proc/meminfo");
return (FALSE);
}
}
if (batt_fd < 0) {
batt_fd = open("/proc/apm", O_RDONLY);
if (batt_fd < 0) {
/* allow opening /proc/apm to fail */
batt_fd = -1;
}
}
return (TRUE);
}
int
machine_close(void)
{
if (batt_fd >= 0)
close(batt_fd);
batt_fd = -1;
if (load_fd >= 0)
close(load_fd);
load_fd = -1;
#ifndef USE_GETLOADAVG
if (loadavg_fd >= 0)
close(loadavg_fd);
loadavg_fd = -1;
#endif
if (meminfo_fd >= 0)
close(meminfo_fd);
meminfo_fd = -1;
if (uptime_fd >= 0)
close(uptime_fd);
uptime_fd = -1;
return (TRUE);
}
static void
reread(int f, char *errmsg)
{
if (lseek(f, 0L, 0) == 0 && read(f, procbuf, sizeof(procbuf) - 1) > 0)
return;
perror(errmsg);
exit(1);
}
static int
getentry(const char *tag, const char *bufptr, long *value)
{
char *tail;
int len = strlen(tag);
long val;
while (bufptr != NULL) {
if (*bufptr == '\n')
bufptr++;
if (!strncmp(tag, bufptr, len)) {
errno = 0;
val = strtol(bufptr + len, &tail, 10);
if ((errno == 0) && (tail != bufptr + len)) {
*value = val;
return TRUE;
}
else
return FALSE;
}
bufptr = strchr(bufptr, '\n');
}
return FALSE;
}
int
machine_get_battstat(int *acstat, int *battflag, int *percent)
{
char str[64];
int battstat;
/* no battery status available: fake one ;-) */
if (batt_fd < 0) {
*acstat = LCDP_AC_ON;
*battflag = LCDP_BATT_ABSENT;
*percent = 100;
return (TRUE);
}
if (lseek(batt_fd, 0, 0) != 0)
return (FALSE);
if (read(batt_fd, str, sizeof(str) - 1) < 0)
return (FALSE);
if (3 > sscanf(str + 13, "0x%x 0x%x 0x%x %d", acstat, &battstat, battflag, percent))
return (FALSE);
if (*battflag == 0xff)
*battflag = LCDP_BATT_UNKNOWN;
else {
if (*battflag & 1)
*battflag = LCDP_BATT_HIGH;
if (*battflag & 2)
*battflag = LCDP_BATT_LOW;
if (*battflag & 4)
*battflag = LCDP_BATT_CRITICAL;
if (*battflag & 8 || battstat == 3)
*battflag = LCDP_BATT_CHARGING;
if (*battflag & 128)
*battflag = LCDP_BATT_ABSENT;
}
switch (*acstat) {
case 0:
*acstat = LCDP_AC_OFF;
break;
case 1:
*acstat = LCDP_AC_ON;
break;
case 2:
*acstat = LCDP_AC_BACKUP;
break;
default:
*acstat = LCDP_AC_UNKNOWN;
break;
}
return (TRUE);
}
int
machine_get_fs(mounts_type fs[], int *cnt)
{
#ifdef STAT_STATVFS
struct statvfs fsinfo;
#else
struct statfs fsinfo;
#endif
char line[256];
int x = 0, y;
#ifdef MTAB_FILE
mtab_fd = fopen(MTAB_FILE, "r");
#else
#error "Can't find your mounted filesystem table file."
#endif
/* Get rid of old, unmounted filesystems... */
memset(fs, 0, sizeof(mounts_type) * 256);
while (x < 256) {
if (fgets(line, 256, mtab_fd) == NULL) {
fclose(mtab_fd);
*cnt = x;
return (FALSE);
}
sscanf(line, "%s %s %s", fs[x].dev, fs[x].mpoint, fs[x].type);
if (strcmp(fs[x].type, "proc")
&& strcmp(fs[x].type, "tmpfs")
#ifndef STAT_NFS
&& strcmp(fs[x].type, "nfs")
#endif
#ifndef STAT_SMBFS
&& strcmp(fs[x].type, "smbfs")
#endif
) {
#ifdef STAT_STATVFS
y = statvfs(fs[x].mpoint, &fsinfo);
#elif STAT_STATFS2_BSIZE
y = statfs(fs[x].mpoint, &fsinfo);
#elif STAT_STATFS4
y = statfs(fs[x].mpoint, &fsinfo, sizeof(fsinfo), 0);
#else
#error "statfs for this system not yet supported"
#endif
fs[x].blocks = fsinfo.f_blocks;
if (fs[x].blocks > 0) {
fs[x].bsize = fsinfo.f_bsize;
fs[x].bfree = fsinfo.f_bfree;
fs[x].files = fsinfo.f_files;
fs[x].ffree = fsinfo.f_ffree;
x++;
}
}
}
fclose(mtab_fd);
*cnt = x;
return (TRUE);
}
int
machine_get_load(load_type * curr_load)
{
static load_type last_load = {0, 0, 0, 0, 0};
load_type load;
int ret;
unsigned long load_iowait, load_irq, load_softirq;
reread(load_fd, "get_load");
ret = sscanf(procbuf, "cpu %lu %lu %lu %lu %lu %lu %lu",
&load.user, &load.nice, &load.system, &load.idle,
&load_iowait, &load_irq, &load_softirq);
if (ret >= 5)
load.idle += load_iowait;
if (ret >= 6)
load.system += load_irq;
if (ret >= 7)
load.system += load_softirq;
load.total = load.user + load.nice + load.system + load.idle;
curr_load->user = load.user - last_load.user;
curr_load->nice = load.nice - last_load.nice;
curr_load->system = load.system - last_load.system;
curr_load->idle = load.idle - last_load.idle;
curr_load->total = load.total - last_load.total;
/* struct assignment is legal in C89 */
last_load = load;
return (TRUE);
}
int
machine_get_loadavg(double *load)
{
#ifdef USE_GETLOADAVG
double loadavg[LOADAVG_NSTATS];
if (getloadavg(loadavg, LOADAVG_NSTATS) <= LOADAVG_1MIN) {
perror("getloadavg"); /* ToDo: correct error reporting */
return (FALSE);
}
*load = loadavg[LOADAVG_1MIN];
#else
reread(loadavg_fd, "get_loadavg");
sscanf(procbuf, "%lf", load);
#endif
return (TRUE);
}
int
machine_get_meminfo(meminfo_type * result)
{
long tmp;
reread(meminfo_fd, "get_meminfo");
result[0].total = (getentry("MemTotal:", procbuf, &tmp) == TRUE) ? tmp : 0L;
result[0].free = (getentry("MemFree:", procbuf, &tmp) == TRUE) ? tmp : 0L;
result[0].shared = (getentry("MemShared:", procbuf, &tmp) == TRUE) ? tmp : 0L;
result[0].buffers = (getentry("Buffers:", procbuf, &tmp) == TRUE) ? tmp : 0L;
result[0].cache = (getentry("Cached:", procbuf, &tmp) == TRUE) ? tmp : 0L;
result[1].total = (getentry("SwapTotal:", procbuf, &tmp) == TRUE) ? tmp : 0L;
result[1].free = (getentry("SwapFree:", procbuf, &tmp) == TRUE) ? tmp : 0L;
return (TRUE);
}
int
machine_get_procs(LinkedList * procs)
{
/* Much of this code was ripped from "gmemusage" */
DIR *proc;
FILE *StatusFile;
struct dirent *procdir;
char procName[16];
int procSize, procRSS, procData, procStk, procExe;
const char
*NameLine = "Name:",
*VmSizeLine = "VmSize:",
*VmRSSLine = "VmRSS",
*VmDataLine = "VmData",
*VmStkLine = "VmStk",
*VmExeLine = "VmExe";
const int
NameLineLen = strlen(NameLine),
VmSizeLineLen = strlen(VmSizeLine),
VmDataLineLen = strlen(VmDataLine),
VmStkLineLen = strlen(VmStkLine),
VmExeLineLen = strlen(VmExeLine),
VmRSSLineLen = strlen(VmRSSLine);
int threshold = 400, unique;
if ((proc = opendir("/proc")) == NULL) {
/* ToDo: correct error reporting */
perror("mem_top_screen: unable to open /proc");
return (FALSE);
}
while ((procdir = readdir(proc))) {
char buf[128];
/* ignore everything in proc except process ids */
if (!strchr("1234567890", procdir->d_name[0]))
continue;
sprintf(buf, "/proc/%s/status", procdir->d_name);
if ((StatusFile = fopen(buf, "r")) == NULL) {
/*
* Not a serious error; process has finished before
* we could examine it:
*/
continue;
}
procRSS = procSize = procData = procStk = procExe = 0;
while (fgets(buf, sizeof(buf), StatusFile)) {
if (!strncmp(buf, NameLine, NameLineLen)) {
/* Name: procName */
sscanf(buf, "%*s %s", procName);
}
else if (!strncmp(buf, VmSizeLine, VmSizeLineLen)) {
/* VmSize: procSize kB */
sscanf(buf, "%*s %d", &procSize);
}
else if (!strncmp(buf, VmRSSLine, VmRSSLineLen)) {
/* VmRSS: procRSS kB */
sscanf(buf, "%*s %d", &procRSS);
}
else if (!strncmp(buf, VmDataLine, VmDataLineLen)) {
/* VmData: procData kB */
sscanf(buf, "%*s %d", &procData);
}
else if (!strncmp(buf, VmStkLine, VmStkLineLen)) {
/* VmStk: procStk kB */
sscanf(buf, "%*s %d", &procStk);
}
else if (!strncmp(buf, VmExeLine, VmExeLineLen)) {
/* VmExe: procExe kB */
sscanf(buf, "%*s %d", &procExe);
}
}
fclose(StatusFile);
if (procSize > threshold) {
/* Figure out if it's sharing any memory... */
unique = 1;
LL_Rewind(procs);
do {
procinfo_type *p = LL_Get(procs);
if ((p != NULL) && (0 == strcmp(p->name, procName))) {
unique = 0;
p->number++;
p->totl += procData + procStk + procExe;
}
} while (LL_Next(procs) == 0);
/* If this is the first one by this name... */
if (unique) {
procinfo_type *p = malloc(sizeof(procinfo_type));
if (p == NULL) {
perror("mem_top_screen: Error allocating process entry");
break;
}
strcpy(p->name, procName);
p->totl = procData + procStk + procExe;
p->number = 1;
/* TODO: Check for errors here? */
LL_Push(procs, (void *)p);
}
}
}
closedir(proc);
return (TRUE);
}
int
machine_get_smpload(load_type * result, int *numcpus)
{
char *token;
static load_type last_load[MAX_CPUS];
load_type curr_load[MAX_CPUS];
int ncpu = 0;
int ret;
unsigned long load_iowait, load_irq, load_softirq;
reread(load_fd, "get_load");
/* Look for lines starting with "cpu0", "cpu1", etc. */
token = strtok(procbuf, "\n");
while (token != NULL) {
if ((strlen(token) > 3) && (!strncmp(token, "cpu", 3)) && isdigit(token[3])) {
ret = sscanf(token, "cpu%*d %lu %lu %lu %lu %lu %lu %lu",
&curr_load[ncpu].user, &curr_load[ncpu].nice, &curr_load[ncpu].system,
&curr_load[ncpu].idle, &load_iowait, &load_irq, &load_softirq);
if (ret >= 5)
curr_load[ncpu].idle += load_iowait;
if (ret >= 6)
curr_load[ncpu].system += load_irq;
if (ret >= 7)
curr_load[ncpu].system += load_softirq;
curr_load[ncpu].total = curr_load[ncpu].user + curr_load[ncpu].nice +
curr_load[ncpu].system + curr_load[ncpu].idle;
result[ncpu].total = curr_load[ncpu].total - last_load[ncpu].total;
result[ncpu].user = curr_load[ncpu].user - last_load[ncpu].user;
result[ncpu].nice = curr_load[ncpu].nice - last_load[ncpu].nice;
result[ncpu].system = curr_load[ncpu].system - last_load[ncpu].system;
result[ncpu].idle = curr_load[ncpu].idle - last_load[ncpu].idle;
/* struct assignment is legal in C89 */
last_load[ncpu] = curr_load[ncpu];
/* restrict # CPUs to min(*numcpus, MAX_CPUS) */
ncpu++;
if ((ncpu >= *numcpus) || (ncpu >= MAX_CPUS))
break;
}
token = strtok(NULL, "\n");
}
*numcpus = ncpu;
return (TRUE);
}
int
machine_get_uptime(double *up, double *idle)
{
double local_up, local_idle;
reread(uptime_fd, "get_uptime");
sscanf(procbuf, "%lf %lf", &local_up, &local_idle);
if (up != NULL)
*up = local_up;
if (idle != NULL)
*idle = (local_up != 0)
? 100 * local_idle / local_up
: 100;
return (TRUE);
}
int
machine_get_iface_stats(IfaceInfo * interface)
{
FILE *file; /* file handler */
char buffer[1024]; /* buffer to work with the file */
static int first_time = 1; /* is it first time we call this
* function? */
char *ch_pointer = NULL;/* pointer to where interface values are in
* file */
/* Open the file in read-only mode and parse */
if ((file = fopen("/proc/net/dev", "r")) != NULL) {
/* Skip first 2 header lines of file */
fgets(buffer, sizeof(buffer), file);
fgets(buffer, sizeof(buffer), file);
/* By default, treat interface as down */
interface->status = down;
/* Search iface_name and scan values */
while ((fgets(buffer, sizeof(buffer), file) != NULL)) {
if (strstr(buffer, interface->name)) {
/* interface exists */
interface->status = up; /* is up */
interface->last_online = time(NULL); /* save actual time */
/* search ':' and skip over it */
ch_pointer = strchr(buffer, ':');
ch_pointer++;
/*
* Now ch_pointer points to values of
* iface_name
*/
/* Scan values from here */
sscanf(ch_pointer, "%lf %lf %*s %*s %*s %*s %*s %*s %lf %lf",
&interface->rc_byte,
&interface->rc_pkt,
&interface->tr_byte,
&interface->tr_pkt);
/*
* if is the first time we call this
* function, old values are the same as new
* so we don't get big speeds when
* calculating
*/
if (first_time) {
interface->rc_byte_old = interface->rc_byte;
interface->tr_byte_old = interface->tr_byte;
interface->rc_pkt_old = interface->rc_pkt;
interface->tr_pkt_old = interface->tr_pkt;
first_time = 0; /* now it isn't first
* time */
}
}
}
fclose(file);
return (TRUE);
}
else { /* error when opening the file */
perror("Error: Could not open DEVFILE");
return (FALSE);
}
}
#endif /* linux */
-427
View File
@@ -1,427 +0,0 @@
/** \file clients/lcdproc/machine_NetBSD.c
* Collects system information on NetBSD.
*/
/*-
* Copyright (c) 2003 Thomas Runge (coto@core.de)
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the author nor the names of its contributors
* may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifdef __NetBSD__
#include <sys/types.h>
#include <sys/param.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <kvm.h>
#include <sys/utsname.h>
#include <sys/fcntl.h>
#include <sys/ioctl.h>
#include <sys/sysctl.h>
#include <sys/stat.h>
#include <sys/ucred.h>
#include <sys/mount.h>
#include <sys/dkstat.h>
#include <sched.h>
#include <uvm/uvm_extern.h>
#include <machine/apmvar.h>
#include <errno.h>
#include <sys/socket.h>
#include <net/if.h>
#include <ifaddrs.h>
#if (__NetBSD_Version__ >= 300000000)
# include <sys/statvfs.h>
#endif
#include "machine.h"
#include "main.h"
#include "config.h"
#include "shared/LL.h"
static int pageshift;
#define pagetok(size) ((size) << pageshift)
#define PROCSIZE(pp) ((pp)->p_vm_tsize + (pp)->p_vm_dsize + (pp)->p_vm_ssize)
int
machine_init(void)
{
/*
* get the page size with "getpagesize" and calculate pageshift from
* it
*/
int pagesize = getpagesize();
pageshift = 0;
while (pagesize > 1) {
pageshift++;
pagesize >>= 1;
}
/* we only need the amount of log(2)1024 for our conversion */
pageshift -= 10;
return (TRUE);
}
int
machine_close(void)
{
return (TRUE);
}
int
machine_get_battstat(int *acstat, int *battflag, int *percent)
{
int apmd;
struct apm_power_info apmi;
if ((apmd = open("/dev/apm", O_RDONLY)) == -1) {
*acstat = LCDP_AC_ON;
*battflag = LCDP_BATT_ABSENT;
*percent = 100;
return (TRUE);
}
memset(&apmi, 0, sizeof(apmi));
if (ioctl(apmd, APM_IOC_GETPOWER, &apmi) == -1) {
perror("APM_IOC_GETPOWER failed in get_batt_stat()");
return (FALSE);
}
switch (apmi.ac_state) {
case APM_AC_OFF:
*acstat = LCDP_AC_OFF;
break;
case APM_AC_ON:
*acstat = LCDP_AC_ON;
break;
case APM_AC_BACKUP:
*acstat = LCDP_AC_BACKUP;
break;
default:
*acstat = LCDP_AC_UNKNOWN;
break;
}
*battflag = apmi.battery_state;
*percent = apmi.battery_life;
close(apmd);
return (TRUE);
}
int
machine_get_fs(mounts_type fs[], int *cnt)
{
#if (__NetBSD_Version__ >= 300000000)
struct statvfs *mntbuf;
struct statvfs *pp;
#else
struct statfs *mntbuf;
struct statfs *pp;
#endif
int statcnt, fscnt, i;
fscnt = getmntinfo(&mntbuf, MNT_WAIT);
if (fscnt == 0) {
perror("getmntinfo");
return (FALSE);
}
for (statcnt = 0, pp = mntbuf, i = 0; i < fscnt; pp++, i++) {
if (strcmp(pp->f_fstypename, "procfs")
&& strcmp(pp->f_fstypename, "kernfs")
&& strcmp(pp->f_fstypename, "linprocfs")
#ifndef STAT_NFS
&& strcmp(pp->f_fstypename, "nfs")
#endif
#ifndef STAT_SMBFS
&& strcmp(pp->f_fstypename, "smbfs")
#endif
) {
snprintf(fs[statcnt].dev, 255, "%s", pp->f_mntfromname);
snprintf(fs[statcnt].mpoint, 255, "%s", pp->f_mntonname);
snprintf(fs[statcnt].type, 63, "%s", pp->f_fstypename);
fs[statcnt].blocks = pp->f_blocks;
if (fs[statcnt].blocks > 0) {
fs[statcnt].bsize = pp->f_bsize;
fs[statcnt].bfree = pp->f_bfree;
fs[statcnt].files = pp->f_files;
fs[statcnt].ffree = pp->f_ffree;
}
statcnt++;
}
}
*cnt = statcnt;
return (TRUE);
}
int
machine_get_load(load_type * curr_load)
{
static load_type last_load = {0, 0, 0, 0, 0};
static load_type last_ret_load;
load_type load;
u_int64_t cp_time[CPUSTATES];
size_t size;
int mib[2];
mib[0] = CTL_KERN;
mib[1] = KERN_CP_TIME;
size = sizeof(cp_time);
if (sysctl(mib, 2, cp_time, &size, NULL, 0) < 0) {
perror("sysctl kern.cp_time failed");
return (FALSE);
}
load.user = (unsigned long)(cp_time[CP_USER]);
load.nice = (unsigned long)(cp_time[CP_NICE]);
load.system = (unsigned long)(cp_time[CP_SYS] + cp_time[CP_INTR]);
load.idle = (unsigned long)(cp_time[CP_IDLE]);
load.total = load.user + load.nice + load.system + load.idle;
if (load.total != last_load.total) {
curr_load->user = load.user - last_load.user;
curr_load->nice = load.nice - last_load.nice;
curr_load->system = load.system - last_load.system;
curr_load->idle = load.idle - last_load.idle;
curr_load->total = load.total - last_load.total;
last_ret_load = *curr_load;
last_load = load;
}
else {
*curr_load = last_ret_load;
}
return (TRUE);
}
int
machine_get_loadavg(double *load)
{
double loadavg[LOADAVG_NSTATS];
if (getloadavg(loadavg, LOADAVG_NSTATS) <= LOADAVG_1MIN)
return (FALSE);
*load = loadavg[LOADAVG_1MIN];
return (TRUE);
}
int
machine_get_meminfo(meminfo_type * result)
{
size_t size;
int mib[2];
struct uvmexp_sysctl uvmexp;
mib[0] = CTL_VM;
mib[1] = VM_UVMEXP2;
size = sizeof(uvmexp);
if (sysctl(mib, 2, &uvmexp, &size, NULL, 0) < 0) {
perror("sysctl vm.uvmexp2 failed");
return (FALSE);
}
/* memory */
result[0].total = pagetok(uvmexp.npages);
result[0].free = pagetok(uvmexp.free);
/* not really */
result[0].shared = pagetok(uvmexp.wired);
result[0].buffers = pagetok(uvmexp.execpages);
result[0].cache = pagetok(uvmexp.filepages);
/* swap */
result[1].total = pagetok(uvmexp.swpages);
result[1].free = pagetok(uvmexp.swpginuse);
result[1].free = result[1].total - result[1].free;
return (TRUE);
}
int
machine_get_procs(LinkedList * procs)
{
int nproc, i;
kvm_t *kvmd;
struct kinfo_proc2 *kprocs;
procinfo_type *p;
kprocs = NULL;
if ((kvmd = kvm_open(NULL, NULL, NULL, KVM_NO_FILES, "kvm_open")) == NULL) {
perror("kvm_openfiles");
return (FALSE);
}
kprocs = kvm_getproc2(kvmd, KERN_PROC_ALL, 0, sizeof(struct kinfo_proc2), &nproc);
if (kprocs == NULL) {
perror("kvm_getproc2");
return (FALSE);
}
for (i = 0; i < nproc; i++) {
p = malloc(sizeof(procinfo_type));
if (!p) {
perror("mem_top_malloc");
kvm_close(kvmd);
return (FALSE);
}
strncpy(p->name, kprocs->p_comm, 15);
p->name[15] = '\0';
p->totl = pagetok(PROCSIZE(kprocs));
p->number = kprocs->p_pid;
LL_Push(procs, (void *)p);
kprocs++;
}
kvm_close(kvmd);
return (TRUE);
}
int
machine_get_smpload(load_type * result, int *numcpus)
{
int mib[2], i, num;
size_t size;
load_type curr_load;
mib[0] = CTL_HW;
mib[1] = HW_NCPU;
size = sizeof(int);
if (sysctl(mib, 2, &num, &size, NULL, 0) < 0) {
perror("sysctl hw.ncpu");
return (FALSE);
}
if (machine_get_load(&curr_load) == FALSE)
return (FALSE);
if (numcpus == NULL)
return (FALSE);
/* restrict #CPUs to max. *numcpus */
num = (*numcpus >= num) ? num : *numcpus;
*numcpus = num;
/* Don't know how to get per-cpu-load values */
for (i = 0; i < num; i++) {
result[i] = curr_load;
}
return (TRUE);
}
int
machine_get_uptime(double *up, double *idle)
{
size_t size;
time_t now;
struct timeval boottime;
load_type curr_load;
int mib[2];
mib[0] = CTL_KERN;
mib[1] = KERN_BOOTTIME;
size = sizeof(boottime);
time(&now);
if (sysctl(mib, 2, &boottime, &size, NULL, 0) < 0) {
perror("sysctl kern.boottime failed");
return (FALSE);
}
*up = (double)(now - boottime.tv_sec);
if (machine_get_load(&curr_load) == FALSE)
*idle = 100.;
else
*idle = 100. * curr_load.idle / curr_load.total;
return (TRUE);
}
/* Get network statistics */
int
machine_get_iface_stats(IfaceInfo * interface)
{
struct ifaddrs *ifa, *ifa_ptr;
struct if_data *ifd;
/* get first interface */
if (getifaddrs(&ifa) == -1)
perror("getifaddr failed");
/* loop through all interfaces */
for (ifa_ptr = ifa; ifa_ptr != NULL; ifa_ptr = ifa_ptr->ifa_next) {
interface->status = down; /* set status down by default */
/* check if we got the right interface and if it is Link type */
if ((strcmp(ifa_ptr->ifa_name, interface->name) == 0) &&
(ifa_ptr->ifa_addr->sa_family == AF_LINK)) {
ifd = (struct if_data *)ifa_ptr->ifa_data;
interface->rc_byte = ifd->ifi_ibytes;
interface->tr_byte = ifd->ifi_obytes;
interface->rc_pkt = ifd->ifi_ipackets;
interface->tr_pkt = ifd->ifi_opackets;
if (interface->last_online == 0) {
interface->rc_byte_old = interface->rc_byte;
interface->tr_byte_old = interface->tr_byte;
interface->rc_pkt_old = interface->rc_pkt;
interface->tr_pkt_old = interface->tr_pkt;
}
if ((ifa_ptr->ifa_flags & IFF_UP) == IFF_UP) {
interface->status = up; /* is up */
interface->last_online = time(NULL); /* save actual time */
}
return (TRUE);
}
}
freeifaddrs(ifa);
/* if we are here there is no interface with the given name */
return (TRUE);
}
#endif /* __NetBSD__ */
-406
View File
@@ -1,406 +0,0 @@
/** \file clients/lcdproc/machine_OpenBSD.c
* Collects system information on OpenBSD.
*/
/*-
* Copyright (c) 2003 Thomas Runge (coto@core.de)
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the author nor the names of its contributors
* may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifdef __OpenBSD__
#include <sys/types.h>
#include <sys/param.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/sysctl.h>
#include <sys/dkstat.h>
#include <sys/ucred.h>
#include <sys/mount.h>
#include <sys/time.h>
#include <sys/user.h>
#include <machine/apmvar.h>
#include <kvm.h>
#include <errno.h>
#include "main.h"
#include "machine.h"
#include "config.h"
#include "shared/LL.h"
static int pageshift;
#define pagetok(size) ((size) << pageshift)
#if OpenBSD >= 201111
#define PROCSIZE(pp) ((pp)->p_vm_tsize + (pp)->p_vm_dsize + (pp)->p_vm_ssize)
#else
#define PROCSIZE(pp) ((pp).vm_tsize + (pp).vm_dsize + (pp).vm_ssize)
#endif
int
machine_init(void)
{
/*
* get the page size with "getpagesize" and calculate pageshift from
* it
*/
int pagesize = getpagesize();
pageshift = 0;
while (pagesize > 1) {
pageshift++;
pagesize >>= 1;
}
/* we only need the amount of log(2)1024 for our conversion */
pageshift -= 10;
return (TRUE);
}
int
machine_close(void)
{
return (TRUE);
}
int
machine_get_battstat(int *acstat, int *battflag, int *percent)
{
int apmd;
struct apm_power_info api;
*acstat = LCDP_AC_ON;
*battflag = LCDP_BATT_ABSENT;
*percent = 100;
if ((apmd = open("/dev/apm", O_RDONLY)) == -1) {
perror("get_battstat_open");
return (TRUE);
}
if (ioctl(apmd, APM_IOC_GETPOWER, &api) == -1) {
perror("get_battstat_ioctl");
return (FALSE);
}
switch (api.ac_state) {
case APM_AC_OFF:
*acstat = LCDP_AC_OFF;
break;
case APM_AC_ON:
*acstat = LCDP_AC_ON;
break;
default:
*acstat = LCDP_AC_UNKNOWN;
break;
}
switch (api.battery_state) {
case APM_BATT_HIGH:
*battflag = LCDP_BATT_HIGH;
break;
case APM_BATT_LOW:
*battflag = LCDP_BATT_LOW;
break;
case APM_BATT_CRITICAL:
*battflag = LCDP_BATT_CRITICAL;
break;
case APM_BATT_CHARGING:
*battflag = LCDP_BATT_CHARGING;
break;
case APM_BATTERY_ABSENT:
*battflag = LCDP_BATT_ABSENT;
break;
default:
*battflag = LCDP_BATT_UNKNOWN;
break;
}
*percent = api.battery_life;
close(apmd);
return (TRUE);
}
int
machine_get_fs(mounts_type fs[], int *cnt)
{
struct statfs *mntbuf;
struct statfs *pp;
int statcnt, fscnt, i;
fscnt = getmntinfo(&mntbuf, MNT_WAIT);
if (fscnt == 0) {
perror("getmntinfo");
return (FALSE);
}
for (statcnt = 0, pp = mntbuf, i = 0; i < fscnt; pp++, i++) {
if (strcmp(pp->f_fstypename, "procfs")
&& strcmp(pp->f_fstypename, "kernfs")
&& strcmp(pp->f_fstypename, "linprocfs")
#ifndef STAT_NFS
&& strcmp(pp->f_fstypename, "nfs")
#endif
#ifndef STAT_SMBFS
&& strcmp(pp->f_fstypename, "smbfs")
#endif
) {
snprintf(fs[statcnt].dev, 255, "%s", pp->f_mntfromname);
snprintf(fs[statcnt].mpoint, 255, "%s", pp->f_mntonname);
snprintf(fs[statcnt].type, 63, "%s", pp->f_fstypename);
fs[statcnt].blocks = pp->f_blocks;
if (fs[statcnt].blocks > 0) {
fs[statcnt].bsize = pp->f_bsize;
fs[statcnt].bfree = pp->f_bfree;
fs[statcnt].files = pp->f_files;
fs[statcnt].ffree = pp->f_ffree;
}
statcnt++;
}
}
*cnt = statcnt;
return (TRUE);
}
int
machine_get_load(load_type * curr_load)
{
static load_type last_load = {0, 0, 0, 0, 0};
static load_type last_ret_load;
load_type load;
long cp_time[CPUSTATES];
size_t size;
int mib[2];
mib[0] = CTL_KERN;
mib[1] = KERN_CPTIME;
size = sizeof(cp_time);
if (sysctl(mib, 2, cp_time, &size, NULL, 0) < 0) {
perror("sysctl kern.cp_time failed");
return (FALSE);
}
load.user = (unsigned long)(cp_time[CP_USER]);
load.nice = (unsigned long)(cp_time[CP_NICE]);
load.system = (unsigned long)(cp_time[CP_SYS] + cp_time[CP_INTR]);
load.idle = (unsigned long)(cp_time[CP_IDLE]);
load.total = load.user + load.nice + load.system + load.idle;
if (load.total != last_load.total) {
curr_load->user = load.user - last_load.user;
curr_load->nice = load.nice - last_load.nice;
curr_load->system = load.system - last_load.system;
curr_load->idle = load.idle - last_load.idle;
curr_load->total = load.total - last_load.total;
last_ret_load = *curr_load;
last_load = load;
}
else {
*curr_load = last_ret_load;
}
return (TRUE);
}
int
machine_get_loadavg(double *load)
{
double loadavg[LOADAVG_NSTATS];
if (getloadavg(loadavg, LOADAVG_NSTATS) <= LOADAVG_1MIN)
return (FALSE);
*load = loadavg[LOADAVG_1MIN];
return (TRUE);
}
int
machine_get_meminfo(meminfo_type * result)
{
size_t size;
int mib[2];
struct uvmexp suvm;
mib[0] = CTL_VM;
mib[1] = VM_UVMEXP;
size = sizeof(suvm);
if (sysctl(mib, 2, &suvm, &size, NULL, 0) < 0) {
perror("sysctl vm.uvmexp failed");
return (FALSE);
}
/* memory */
result[0].total = pagetok(suvm.npages);
result[0].free = pagetok(suvm.free);
/* not used anyway */
result[0].shared = 0;
result[0].buffers = 0;
result[0].cache = 0;
/* swap */
result[1].total = suvm.pagesize * suvm.swpages;
result[1].free = suvm.pagesize * suvm.swpginuse;
result[1].free = result[1].total - result[1].free;
return (TRUE);
}
int
machine_get_procs(LinkedList * procs)
{
struct kinfo_proc *kprocs;
int nproc, i;
procinfo_type *p;
kvm_t *kvmd;
if ((kvmd = kvm_open(NULL, NULL, NULL, O_RDONLY, "kvm_open")) == NULL) {
perror("kvm_open");
return (FALSE);
}
#if OpenBSD >= 201111
kprocs = kvm_getprocs(kvmd, KERN_PROC_ALL, 0, sizeof(struct kinfo_proc), &nproc);
#else
kprocs = kvm_getprocs(kvmd, KERN_PROC_ALL, 0, &nproc);
#endif
if (kprocs == NULL) {
perror("kvm_getprocs");
kvm_close(kvmd);
return (FALSE);
}
for (i = 0; i < nproc; i++) {
p = malloc(sizeof(procinfo_type));
if (!p) {
perror("mem_top_malloc");
kvm_close(kvmd);
return (FALSE);
}
#if OpenBSD >= 201111
strncpy(p->name, kprocs->p_comm, 15);
p->name[15] = '\0';
p->totl = pagetok(PROCSIZE(kprocs));
p->number = kprocs->p_pid;
#else
strncpy(p->name, kprocs->kp_proc.p_comm, 15);
p->name[15] = '\0';
p->totl = pagetok(PROCSIZE(kprocs->kp_eproc.e_vm));
p->number = kprocs->kp_proc.p_pid;
#endif
LL_Push(procs, (void *)p);
kprocs++;
}
kvm_close(kvmd);
return (TRUE);
}
int
machine_get_smpload(load_type * result, int *numcpus)
{
int mib[2], i, num;
size_t size;
load_type curr_load;
mib[0] = CTL_HW;
mib[1] = HW_NCPU;
size = sizeof(int);
if (sysctl(mib, 2, &num, &size, NULL, 0) < 0) {
perror("sysctl hw.ncpu");
return (FALSE);
}
if (machine_get_load(&curr_load) == FALSE)
return (FALSE);
if (numcpus == NULL)
return (FALSE);
/* restrict #CPUs to max. *numcpus */
num = (*numcpus >= num) ? num : *numcpus;
*numcpus = num;
/* Don't know how to get per-cpu-load values */
for (i = 0; i < num; i++) {
result[i] = curr_load;
}
return (TRUE);
}
int
machine_get_uptime(double *up, double *idle)
{
size_t size;
time_t now;
struct timeval boottime;
int mib[2];
load_type curr_load;
mib[0] = CTL_KERN;
mib[1] = KERN_BOOTTIME;
size = sizeof(boottime);
time(&now);
if (sysctl(mib, 2, &boottime, &size, NULL, 0) < 0) {
perror("sysctl kern.boottime failed");
return (FALSE);
}
*up = (double)(now - boottime.tv_sec);
if (machine_get_load(&curr_load) == FALSE)
*idle = 100.;
else
*idle = 100. * curr_load.idle / curr_load.total;
return (TRUE);
}
/* Get network statistics */
int
machine_get_iface_stats(IfaceInfo * interface)
{
/* Implementation missing */
return 0;
}
#endif /* __OpenBSD__ */
-441
View File
@@ -1,441 +0,0 @@
/** \file clients/lcdproc/machine_SunOS.c
* Collects system information on Solaris.
*/
/*-
* This file is part of lcdproc, the lcdproc client.
*
* This file is released under the GNU General Public License.
* Refer to the COPYING file distributed with this package.
*/
#ifdef sun
#include <sys/types.h>
#include <sys/param.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <strings.h>
#include <fcntl.h>
#include <dirent.h>
#include <utmpx.h>
#include <procfs.h>
#include <kstat.h>
#include <errno.h>
#include <sys/utsname.h>
#include <sys/fcntl.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/loadavg.h>
#include <sys/mount.h>
#include <sys/cpuvar.h>
#include <sys/swap.h>
#include <sys/statvfs.h>
#include "machine.h"
#include "main.h"
#include "config.h"
#include "shared/LL.h"
static kstat_ctl_t *kc;
int
machine_init(void)
{
kc = NULL;
kc = kstat_open();
if (kc == NULL) {
perror("kstat_open");
return (FALSE);
}
return (TRUE);
}
int
machine_close(void)
{
if (kc != NULL) {
kstat_close(kc);
kc = NULL;
}
return (TRUE);
}
int
machine_get_battstat(int *acstat, int *battflag, int *percent)
{
*acstat = LCDP_AC_ON;
*battflag = LCDP_BATT_ABSENT;
*percent = 100;
return (TRUE);
}
int
machine_get_fs(mounts_type fs[], int *cnt)
{
FILE *mtab_fd;
char line[256];
int x = 0, y;
#ifdef STAT_STATVFS
struct statvfs fsinfo;
#else
struct statfs fsinfo;
#endif
#ifdef MTAB_FILE
mtab_fd = fopen(MTAB_FILE, "r");
#else
#error "Can't find your mounted filesystem table file."
#endif
/* Get rid of old, unmounted filesystems... */
memset(fs, 0, sizeof(mounts_type) * 256);
while (x < 256) {
if (fgets(line, 256, mtab_fd) == NULL) {
fclose(mtab_fd);
*cnt = x;
break;
}
sscanf(line, "%s %s %s", fs[x].dev, fs[x].mpoint, fs[x].type);
if (strcmp(fs[x].type, "proc")
#ifndef STAT_NFS
&& strcmp(fs[x].type, "nfs")
#endif
#ifndef STAT_SMBFS
&& strcmp(fs[x].type, "smbfs")
#endif
) {
#ifdef STAT_STATVFS
y = statvfs(fs[x].mpoint, &fsinfo);
#elif STAT_STATFS2_BSIZE
y = statfs(fs[x].mpoint, &fsinfo);
#elif STAT_STATFS4
y = statfs(fs[x].mpoint, &fsinfo, sizeof(fsinfo), 0);
#else
#error "statfs for this system noy yet supported"
#endif
fs[x].blocks = fsinfo.f_blocks;
if (fs[x].blocks > 0) {
fs[x].bsize = fsinfo.f_bsize;
fs[x].bfree = fsinfo.f_bfree;
fs[x].files = fsinfo.f_files;
fs[x].ffree = fsinfo.f_ffree;
x++;
}
}
}
fclose(mtab_fd);
*cnt = x;
return (TRUE);
}
int
machine_get_load(load_type * curr_load)
{
static load_type last_load = {0, 0, 0, 0, 0};
load_type load;
kstat_t *k_space;
struct cpu_stat cinfo;
k_space = kstat_lookup(kc, "cpu_stat", 0, "cpu_stat0");
if (k_space == NULL) {
fprintf(stderr, "kstat lookup error\n");
return (FALSE);
}
if (kstat_read(kc, k_space, NULL) == -1) {
fprintf(stderr, "kstat read error\n");
return (FALSE);
}
k_space = kstat_lookup(kc, "cpu_stat", -1, "cpu_stat0");
if (k_space == NULL) {
fprintf(stderr, "kstat lookup error\n");
return (FALSE);
}
if (kstat_read(kc, k_space, &cinfo) == -1) {
fprintf(stderr, "kstat read error\n");
return (FALSE);
}
load.idle = cinfo.cpu_sysinfo.cpu[CPU_IDLE];
load.user = cinfo.cpu_sysinfo.cpu[CPU_USER];
load.system = cinfo.cpu_sysinfo.cpu[CPU_KERNEL];
load.nice = cinfo.cpu_sysinfo.cpu[CPU_WAIT];
load.total = load.user + load.nice + load.system + load.idle;
curr_load->user = load.user - last_load.user;
curr_load->nice = load.nice - last_load.nice;
curr_load->system = load.system - last_load.system;
curr_load->idle = load.idle - last_load.idle;
curr_load->total = load.total - last_load.total;
/* struct assingment is legal in C89 */
last_load = load;
return (TRUE);
}
int
machine_get_loadavg(double *load)
{
double loadavg[LOADAVG_NSTATS];
if (getloadavg(loadavg, LOADAVG_NSTATS) <= LOADAVG_1MIN)
return (FALSE);
*load = loadavg[LOADAVG_1MIN];
return (TRUE);
}
int
machine_get_meminfo(meminfo_type * result)
{
#define MAXSTRSIZE 80
swaptbl_t *s;
int i, n, num;
char *strtab; /* string table for path names */
s = NULL;
result[0].total = sysconf(_SC_PHYS_PAGES) * sysconf(_SC_PAGESIZE) / 1024;
result[0].free = sysconf(_SC_AVPHYS_PAGES) * sysconf(_SC_PAGESIZE) / 1024;
result[0].shared = 0;
result[0].buffers = 0;
result[0].cache = 0;
again:
if ((num = swapctl(SC_GETNSWP, 0)) == -1) {
perror("swapctl: GETNSWP");
return (FALSE);
}
if (num == 0) {
fprintf(stderr, "No Swap Devices Configured\n");
return (FALSE);
}
/* allocate swaptable for num+1 entries */
if ((s = (swaptbl_t *) malloc(num * sizeof(swapent_t) + sizeof(struct swaptable))) == NULL) {
perror("malloc swap");
return (FALSE);
}
/* allocate num+1 string holders */
if ((strtab = (char *)malloc((num + 1) * MAXSTRSIZE)) == NULL) {
perror("malloc string holder");
return (FALSE);
}
/* initialize string pointers */
for (i = 0; i < (num + 1); i++) {
s->swt_ent[i].ste_path = strtab + (i * MAXSTRSIZE);
}
s->swt_n = num + 1;
if ((n = swapctl(SC_LIST, s)) < 0) {
perror("swapctl");
return (FALSE);
}
/* more were added */
if (n > num) {
free(s);
free(strtab);
goto again;
}
result[1].total = 0;
result[1].free = 0;
for (i = 0; i < n; i++) {
result[1].total = result[1].total + s->swt_ent[i].ste_pages * sysconf(_SC_PAGESIZE) / 1024;
result[1].free = result[1].free + s->swt_ent[i].ste_free * sysconf(_SC_PAGESIZE) / 1024;
}
return (TRUE);
}
int
machine_get_procs(LinkedList * procs)
{
char buf[128];
DIR *proc;
FILE *StatusFile;
struct dirent *procdir;
procinfo_type *p;
char procName[16];
int procSize, procRSS, procData, procStk, procExe;
int threshold = 400, unique;
if ((proc = opendir("/proc")) == NULL) {
perror("open /proc");
return (FALSE);
}
while ((procdir = readdir(proc))) {
psinfo_t psinfo;
if (!strchr("1234567890", procdir->d_name[0]))
continue;
sprintf(buf, "/proc/%s/psinfo", procdir->d_name);
if ((StatusFile = fopen(buf, "r")) == NULL) {
/*
* Not a serious error; process has finished before
* we could examine it:
*/
continue;
}
procRSS = procSize = procData = procStk = procExe = 0;
fread(&psinfo, sizeof(psinfo), 1, StatusFile);
strcpy(procName, psinfo.pr_fname);
procSize = psinfo.pr_size;
procRSS = psinfo.pr_rssize;
/*
* Following values not accurate, not sure what needs to be
* set to
*/
procData = psinfo.pr_size;
procStk = 0;
procExe = 0;
fclose(StatusFile);
if (procSize > threshold) {
/* Figure out if it's sharing any memory... */
unique = 1;
LL_Rewind(procs);
do {
p = LL_Get(procs);
if (p) {
if (0 == strcmp(p->name, procName)) {
unique = 0;
p->number++;
p->totl += procData + procStk + procExe;
}
}
} while (LL_Next(procs) == 0);
/* If this is the first one by this name... */
if (unique) {
p = malloc(sizeof(procinfo_type));
if (p == NULL) {
perror("allocating process entry");
goto end;
}
strcpy(p->name, procName);
p->totl = procData + procStk + procExe;
p->number = 1;
/* TODO: Check for errors here? */
LL_Push(procs, (void *)p);
}
}
}
end:
closedir(proc);
return (TRUE);
}
int
machine_get_smpload(load_type * result, int *numcpus)
{
static load_type last_load[MAX_CPUS];
load_type curr_load[MAX_CPUS];
int ncpu = 0;
int max_cpu, count;
max_cpu = sysconf(_SC_NPROCESSORS_CONF);
for (count = 0; count < max_cpu; count++) {
kstat_t *k_space;
char buffer[16];
sprintf(buffer, "cpu_stat%d", count);
k_space = kstat_lookup(kc, "cpu_stat", count, buffer);
if ((k_space != NULL) && (kstat_read(kc, k_space, NULL) != -1)) {
struct cpu_stat cinfo;
k_space = kstat_lookup(kc, "cpu_stat", -1, buffer);
kstat_read(kc, k_space, &cinfo);
curr_load[ncpu].idle = cinfo.cpu_sysinfo.cpu[CPU_IDLE];
curr_load[ncpu].user = cinfo.cpu_sysinfo.cpu[CPU_USER];
curr_load[ncpu].system = cinfo.cpu_sysinfo.cpu[CPU_KERNEL];
curr_load[ncpu].nice = cinfo.cpu_sysinfo.cpu[CPU_WAIT];
curr_load[ncpu].total = curr_load[ncpu].user + curr_load[ncpu].nice +
curr_load[ncpu].system + curr_load[ncpu].idle;
result[ncpu].total = curr_load[ncpu].total - last_load[ncpu].total;
result[ncpu].user = curr_load[ncpu].user - last_load[ncpu].user;
result[ncpu].nice = curr_load[ncpu].nice - last_load[ncpu].nice;
result[ncpu].system = curr_load[ncpu].system - last_load[ncpu].system;
result[ncpu].idle = curr_load[ncpu].idle - last_load[ncpu].idle;
/* struct assignment is legal in C89 */
last_load[ncpu] = curr_load[ncpu];
/* restrict # CPUs to min(*numcpus, MAX_CPUS) */
ncpu++;
if ((ncpu >= *numcpus) || (ncpu >= MAX_CPUS))
break;
}
}
*numcpus = ncpu;
return (TRUE);
}
/* TODO get idle time! */
int
machine_get_uptime(double *up, double *idle)
{
struct utmpx *u, id;
load_type curr_load;
*up = 0;
*idle = 0;
id.ut_type = BOOT_TIME;
u = getutxid(&id);
if (u == NULL)
return (FALSE);
*up = time(0) - u->ut_xtime;
if (machine_get_load(&curr_load) == FALSE)
*idle = 100.;
else
*idle = 100. * curr_load.idle / curr_load.total;
return (TRUE);
}
/* Get network statistics */
int
machine_get_iface_stats(IfaceInfo * interface)
{
/* Implementation missing */
return 0;
}
#endif /* sun */
-709
View File
@@ -1,709 +0,0 @@
/** \file clients/lcdproc/main.c
* Contains main(), plus signal callback functions and a help screen.
*
* Program init, command-line handling, and the main loop are
* implemented here.
*/
/*-
* This file is part of lcdproc, the lcdproc client.
*
* This file is released under the GNU General Public License.
* Refer to the COPYING file distributed with this package.
*/
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <fcntl.h>
#include <termios.h>
#include <errno.h>
#include <locale.h>
#include <signal.h>
#include <netdb.h>
#include <ctype.h>
#include <sys/stat.h>
#include <sys/utsname.h>
#include <sys/param.h>
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include "main.h"
#include "mode.h"
#include "shared/sockets.h"
#include "shared/report.h"
#include "shared/configfile.h"
#include "getopt.h" /* This is our local getopt.h! */
/* Import screens */
#include "batt.h"
#include "chrono.h"
#include "cpu.h"
#include "cpu_smp.h"
#include "disk.h"
#include "load.h"
#include "mem.h"
#include "machine.h"
#include "iface.h"
#ifdef LCDPROC_EYEBOXONE
# include "eyebox.h"
#endif
/* The following 8 variables are defined 'external' in main.h! */
int Quit = 0;
int sock = -1;
char *version = VERSION;
char *build_date = __DATE__;
int lcd_wid = 0;
int lcd_hgt = 0;
int lcd_cellwid = 0;
int lcd_cellhgt = 0;
static struct utsname unamebuf;
/* local prototypes */
static void HelpScreen(int exit_state);
static void exit_program(int val);
static void main_loop(void);
static int process_configfile(char *cfgfile);
#define TIME_UNIT 125000 /**< 1/8th second is a single time unit. */
#if !defined(SYSCONFDIR)
# define SYSCONFDIR "/etc"
#endif
#if !defined(PIDFILEDIR)
# define PIDFILEDIR "/var/run"
#endif
#define UNSET_INT -1
#define UNSET_STR "\01"
#define DEFAULT_SERVER "127.0.0.1"
#define DEFAULT_CONFIGFILE SYSCONFDIR "/lcdproc.conf"
#define DEFAULT_PIDFILE PIDFILEDIR "/lcdproc.pid"
#define DEFAULT_REPORTDEST RPT_DEST_STDERR
#define DEFAULT_REPORTLEVEL RPT_WARNING
/** list of screen modes to run */
ScreenMode sequence[] =
{
/* flags default ACTIVE will run by default */
/* longname which on off inv timer flags */
{ "CPU", 'C', 1, 2, 0, 0xffff, ACTIVE, cpu_screen }, // [C]PU
{ "Iface", 'I', 1, 2, 0, 0xffff, 0, iface_screen }, // [I]face
{ "Memory", 'M', 4, 16, 0, 0xffff, ACTIVE, mem_screen }, // [M]emory
{ "Load", 'L', 64, 128, 1, 0xffff, ACTIVE, xload_screen }, // [L]oad (load histogram)
{ "TimeDate", 'T', 4, 64, 0, 0xffff, ACTIVE, time_screen }, // [T]ime/Date
{ "About", 'A', 999, 9999, 0, 0xffff, ACTIVE, credit_screen }, // [A]bout (credits)
{ "SMP-CPU", 'P', 1, 2, 0, 0xffff, 0, cpu_smp_screen }, // CPU_SM[P]
{ "OldTime", 'O', 4, 64, 0, 0xffff, 0, clock_screen }, // [O]ld Timescreen
{ "BigClock", 'K', 4, 64, 0, 0xffff, 0, big_clock_screen }, // big cloc[K]
{ "Uptime", 'U', 4, 128, 0, 0xffff, 0, uptime_screen }, // Old [U]ptime Screen
{ "Battery", 'B', 32, 256, 1, 0xffff, 0, battery_screen }, // [B]attery Status
{ "CPUGraph", 'G', 1, 2, 0, 0xffff, 0, cpu_graph_screen }, // CPU histogram [G]raph
{ "ProcSize", 'S', 16, 256, 1, 0xffff, 0, mem_top_screen }, // [S]ize of biggest processes
{ "Disk", 'D', 256, 256, 1, 0xffff, 0, disk_screen }, // [D]isk stats
{ "MiniClock", 'N', 4, 64, 0, 0xffff, 0, mini_clock_screen }, // Mi[n]i clock
{ NULL, 0, 0, 0, 0, 0, 0, NULL}, // No more.. all done.
};
/* All variables are set to 'unset' values */
static int islow = -1; /**< pause after mode update (in 1/100s) */
char *progname = "lcdproc";
char *server = NULL;
int port = LCDPORT;
int foreground = FALSE;
static int report_level = UNSET_INT;
static int report_dest = UNSET_INT;
char *configfile = NULL;
char *pidfile = NULL;
int pidfile_written = FALSE;
char *displayname = NULL; /**< display name for the main menu */
/** Returns the network name of this machine */
const char *
get_hostname(void)
{
return (unamebuf.nodename);
}
/** Returns the name of the client's OS */
const char *
get_sysname(void)
{
return (unamebuf.sysname);
}
/** Returns the release version of the client's OS */
const char *
get_sysrelease(void)
{
return (unamebuf.release);
}
/** Enables or disables (and deletes) a screen */
static int
set_mode(int shortname, char *longname, int state)
{
int k;
for (k = 0; sequence[k].which != 0; k++) {
if (((sequence[k].longname != NULL) &&
(0 == strcasecmp(longname, sequence[k].longname))) ||
(toupper(shortname) == sequence[k].which)) {
if (!state) {
/*
* clean both the active and initialized bits
* since we delete the screen
*/
sequence[k].flags &= (~ACTIVE & ~INITIALIZED);
/* delete the screen if we are connected */
if (sock >= 0) {
sock_printf(sock, "screen_del %c\n", sequence[k].which);
}
}
else
sequence[k].flags |= ACTIVE;
return 1; /* found */
}
}
return 0; /* not found */
}
/** Sets all screens inactive */
static void
clear_modes(void)
{
int k;
for (k = 0; sequence[k].which != 0; k++) {
sequence[k].flags &= (~ACTIVE);
}
}
int
main(int argc, char **argv)
{
int cfgresult;
int c;
/* set locale for cwdate & time formatting in chrono.c */
setlocale(LC_TIME, "");
/* get uname information */
if (uname(&unamebuf) == -1) {
perror("uname");
return (EXIT_FAILURE);
}
/* setup error handlers */
signal(SIGINT, exit_program); /* Ctrl-C */
signal(SIGTERM, exit_program); /* "regular" kill */
signal(SIGHUP, exit_program); /* kill -HUP */
signal(SIGPIPE, exit_program); /* write to closed socket */
signal(SIGKILL, exit_program); /* kill -9 [cannot be trapped; but ...] */
/* No error output from getopt */
opterr = 0;
/* get options from command line */
while ((c = getopt(argc, argv, "s:p:e:c:fhv")) > 0) {
char *end;
switch (c) {
/* c is for config file */
case 'c':
configfile = optarg;
break;
/* s is for server */
case 's':
server = optarg;
break;
/* p is for port */
case 'p':
port = strtol(optarg, &end, 0);
if ((*optarg == '\0') || (*end != '\0') ||
(port <= 0) || (port >= 0xFFFF)) {
fprintf(stderr, "Illegal port value %s\n", optarg);
exit(EXIT_FAILURE);
}
break;
case 'e':
islow = strtol(optarg, &end, 0);
if ((*optarg == '\0') || (*end != '\0') || (islow < 0)) {
fprintf(stderr, "Illegal delay value %s\n", optarg);
exit(EXIT_FAILURE);
}
break;
case 'f':
foreground = TRUE;
break;
case 'h':
HelpScreen(EXIT_SUCCESS);
break;
case 'v':
fprintf(stderr, "LCDproc %s\n", version);
exit(EXIT_SUCCESS);
break;
/* otherwise... Get help! */
case '?': /* unknown option or missing argument */
/* FALLTHROUGH */
default:
HelpScreen(EXIT_FAILURE);
break;
}
}
/* Read config file */
cfgresult = process_configfile(configfile);
if (cfgresult < 0) {
fprintf(stderr, "Error reading config file\n");
exit(EXIT_FAILURE);
}
/* Set default reporting options */
if (report_dest == UNSET_INT)
report_dest = DEFAULT_REPORTDEST;
if (report_level == UNSET_INT)
report_level = DEFAULT_REPORTLEVEL;
/* Set reporting settings */
set_reporting("lcdproc", report_level, report_dest);
/* parse non-option arguments: modes to add/delete */
if (argc > max(optind, 1)) {
int i;
/*
* if no config file was read, ignore hard coded default
* modes
*/
if (cfgresult == 0)
clear_modes();
/* turn additional options on or off (using ! as prefix) */
for (i = max(optind, 1); i < argc; i++) {
int state = (*argv[i] == '!') ? 0 : 1;
char *name = (state) ? argv[i] : argv[i] + 1;
int shortname = (strlen(name) == 1) ? name[0] : '\0';
int found = set_mode(shortname, name, state);
if (!found) {
fprintf(stderr, "Invalid Screen: %s\n", name);
return (EXIT_FAILURE);
}
}
}
if (server == NULL)
server = DEFAULT_SERVER;
/* Connect to the server... */
sock = sock_connect(server, port);
if (sock < 0) {
fprintf(stderr, "Error connecting to LCD server %s on port %d.\n"
"Check to see that the server is running and operating normally.\n",
server, port);
return (EXIT_FAILURE);
}
sock_send_string(sock, "hello\n");
usleep(500000); /* wait for the server to say hi. */
/* We grab the real values below, from the "connect" line. */
lcd_wid = 20;
lcd_hgt = 4;
lcd_cellwid = 5;
lcd_cellhgt = 8;
if (foreground != TRUE) {
if (daemon(1, 0) != 0) {
fprintf(stderr, "Error: daemonize failed\n");
return (EXIT_FAILURE);
}
if (pidfile != NULL) {
FILE *pidf = fopen(pidfile, "w");
if (pidf) {
fprintf(pidf, "%d\n", (int)getpid());
fclose(pidf);
pidfile_written = TRUE;
}
else {
fprintf(stderr, "Error creating pidfile %s: %s\n",
pidfile, strerror(errno));
return (EXIT_FAILURE);
}
}
}
/* Init the status gatherers... */
mode_init();
/* And spew stuff! */
main_loop();
exit_program(EXIT_SUCCESS);
/* NOTREACHED */
return EXIT_SUCCESS;
}
/**
* Reads and parses configuration file.
* \param configfile The configfile to read or NULL for the default config.
* \retval 1 if configfile was read,
* \retval 0 if default configfile doesn't exist
* \retval <0 on error
*/
static int
process_configfile(char *configfile)
{
int k;
const char *tmp;
debug(RPT_DEBUG, "%s(%s)", __FUNCTION__, (configfile) ? configfile : "<null>");
/* Read config settings */
if (configfile == NULL) {
struct stat statbuf;
/*
* if default config file does not exist, do not consider
* this an error and continue
*/
if ((lstat(DEFAULT_CONFIGFILE, &statbuf) == -1) && (errno = ENOENT))
return 0;
configfile = DEFAULT_CONFIGFILE;
}
if (config_read_file(configfile) != 0) {
report(RPT_CRIT, "Could not read config file: %s", configfile);
return -1;
}
if (server == NULL) {
server = strdup(config_get_string(progname, "Server", 0, DEFAULT_SERVER));
}
if (port == UNSET_INT) {
port = config_get_int(progname, "Port", 0, LCDPORT);
}
if (report_level == UNSET_INT) {
report_level = config_get_int(progname, "ReportLevel", 0, RPT_WARNING);
}
if (report_dest == UNSET_INT) {
if (config_get_bool(progname, "ReportToSyslog", 0, 0)) {
report_dest = RPT_DEST_SYSLOG;
}
else {
report_dest = RPT_DEST_STDERR;
}
}
if (foreground != TRUE) {
foreground = config_get_bool(progname, "Foreground", 0, FALSE);
}
if (pidfile == NULL) {
pidfile = strdup(config_get_string(progname, "PidFile", 0, DEFAULT_PIDFILE));
}
if (islow < 0) {
islow = config_get_int(progname, "Delay", 0, -1);
}
if ((tmp = config_get_string(progname, "DisplayName", 0, NULL)) != NULL)
displayname = strdup(tmp);
/*
* check for config file variables to override all the sequence
* defaults
*/
for (k = 0; sequence[k].which != 0; k++) {
if (sequence[k].longname != NULL) {
sequence[k].on_time = config_get_int(sequence[k].longname, "OnTime", 0, sequence[k].on_time);
sequence[k].off_time = config_get_int(sequence[k].longname, "OffTime", 0, sequence[k].off_time);
sequence[k].show_invisible = config_get_bool(sequence[k].longname, "ShowInvisible", 0, sequence[k].show_invisible);
if (config_get_bool(sequence[k].longname, "Active", 0, sequence[k].flags & ACTIVE))
sequence[k].flags |= ACTIVE;
else
sequence[k].flags &= (~ACTIVE);
}
}
return 1;
}
/** Print help screen and exit */
void
HelpScreen(int exit_state)
{
fprintf(stderr,
"lcdproc - LCDproc system status information viewer\n"
"\n"
"Copyright (c) 1999-2014 Selene Scriven, William Ferrell, and misc. contributors.\n"
"This program is released under the terms of the GNU General Public License.\n"
"\n"
"Usage: lcdproc [<options>] [<screens> ...]\n"
" where <options> are\n"
" -s <host> connect to LCDd daemon on <host>\n"
" -p <port> connect to LCDd daemon using <port>\n"
" -f run in foreground\n"
" -e <delay> slow down initial announcement of screens (in 1/100s)\n"
" -c <config> use a configuration file other than %s\n"
" -h show this help screen\n"
" -v display program version\n"
" and <screens> are\n"
" C CPU detailed CPU usage\n"
" P SMP-CPU CPU usage overview (one line per CPU)\n"
" G CPUGraph CPU usage histogram\n"
" L Load load histogram\n"
" M Memory memory & swap usage\n"
" S ProcSize biggest processes size\n"
" D Disk filling level of mounted file systems\n"
" I Iface network interface usage\n"
" B Battery battery status\n"
" T TimeDate time & date information\n"
" O OldTime old time screen\n"
" U Uptime uptime screen\n"
" K BigClock big clock\n"
" N MiniClock minimal clock\n"
" A About credits page\n"
"\n"
"Example:\n"
" lcdproc -s my.lcdproc.server.com -p 13666 C M L\n"
, DEFAULT_CONFIGFILE);
exit(exit_state);
}
/** Called upon TERM and INTR signals. Also removes the pid-file. */
void
exit_program(int val)
{
#ifdef LCDPROC_EYEBOXONE
/*
* Clear Eyebox Leds
*/
eyebox_clear();
#endif
Quit = 1;
sock_close(sock);
mode_close();
if ((foreground != TRUE) && (pidfile != NULL) && (pidfile_written == TRUE))
unlink(pidfile);
exit(val);
}
#ifdef LCDPROC_MENUS
int
menus_init()
{
int k;
for (k = 0; sequence[k].which; k++) {
if (sequence[k].longname) {
sock_printf(sock, "menu_add_item {} %c checkbox {%s} -value %s\n",
sequence[k].which, sequence[k].longname,
(sequence[k].flags & ACTIVE) ? "on" : "off");
}
}
#ifdef LCDPROC_CLIENT_TESTMENUS
/*
* to be entered on escape from test_menu (but overwritten for
* test_{checkbox,ring}
*/
sock_send_string(sock, "menu_add_item {} ask menu {Leave menus?} -is_hidden true\n");
sock_send_string(sock, "menu_add_item {ask} ask_yes action {Yes} -next _quit_\n");
sock_send_string(sock, "menu_add_item {ask} ask_no action {No} -next _close_\n");
sock_send_string(sock, "menu_add_item {} test menu {Test}\n");
sock_send_string(sock, "menu_add_item {test} test_action action {Action}\n");
sock_send_string(sock, "menu_add_item {test} test_checkbox checkbox {Checkbox}\n");
sock_send_string(sock, "menu_add_item {test} test_ring ring {Ring} -strings {one\ttwo\tthree}\n");
sock_send_string(sock, "menu_add_item {test} test_slider slider {Slider} -mintext < -maxtext > -value 50\n");
sock_send_string(sock, "menu_add_item {test} test_numeric numeric {Numeric} -value 42\n");
sock_send_string(sock, "menu_add_item {test} test_alpha alpha {Alpha} -value abc\n");
sock_send_string(sock, "menu_add_item {test} test_ip ip {IP} -v6 false -value 192.168.1.1\n");
sock_send_string(sock, "menu_add_item {test} test_menu menu {Menu}\n");
sock_send_string(sock, "menu_add_item {test_menu} test_menu_action action {Submenu's action}\n");
/*
* no successor for menus. Since test_checkbox and test_ring have
* their own predecessors defined the "ask" rule will not work for
* them.
*/
sock_send_string(sock, "menu_set_item {} test -prev {ask}\n");
sock_send_string(sock, "menu_set_item {test} test_action -next {test_checkbox}\n");
sock_send_string(sock, "menu_set_item {test} test_checkbox -next {test_ring} -prev test_action\n");
sock_send_string(sock, "menu_set_item {test} test_ring -next {test_slider} -prev {test_checkbox}\n");
sock_send_string(sock, "menu_set_item {test} test_slider -next {test_numeric} -prev {test_ring}\n");
sock_send_string(sock, "menu_set_item {test} test_numeric -next {test_alpha} -prev {test_slider}\n");
sock_send_string(sock, "menu_set_item {test} test_alpha -next {test_ip} -prev {test_numeric}\n");
sock_send_string(sock, "menu_set_item {test} test_ip -next {test_menu} -prev {test_alpha}\n");
sock_send_string(sock, "menu_set_item {test} test_menu_action -next {_close_}\n");
#endif /* LCDPROC_CLIENT_TESTMENUS */
return 0;
}
#endif /* LCDPROC_MENUS */
/** Main program loop... */
void
main_loop(void)
{
int i = 0, j;
int connected = 0;
char buf[8192];
char *argv[256];
int argc, newtoken;
int len;
while (!Quit) {
/* Check for server input... */
len = sock_recv(sock, buf, 8000);
/* Handle server input... */
while (len > 0) {
/* Now split the string into tokens... */
argc = 0;
newtoken = 1;
for (i = 0; i < len; i++) {
switch (buf[i]) {
case ' ':
newtoken = 1;
buf[i] = 0;
break;
default: /* regular chars, keep
* tokenizing */
if (newtoken)
argv[argc++] = buf + i;
newtoken = 0;
break;
case '\0':
case '\n':
buf[i] = 0;
if (argc > 0) {
if (0 == strcmp(argv[0], "listen")) {
for (j = 0; sequence[j].which; j++) {
if (sequence[j].which == argv[1][0]) {
sequence[j].flags |= VISIBLE;
debug(RPT_DEBUG, "Listen %s", argv[1]);
}
}
}
else if (0 == strcmp(argv[0], "ignore")) {
for (j = 0; sequence[j].which; j++) {
if (sequence[j].which == argv[1][0]) {
sequence[j].flags &= ~VISIBLE;
debug(RPT_DEBUG, "Ignore %s", argv[1]);
}
}
}
else if (0 == strcmp(argv[0], "key")) {
debug(RPT_DEBUG, "Key %s", argv[1]);
}
#ifdef LCDPROC_MENUS
else if (0 == strcmp(argv[0], "menuevent")) {
if (argc == 4 && (0 == strcmp(argv[1], "update"))) {
set_mode(argv[2][0], "", strcmp(argv[3], "off"));
}
}
#else
else if (0 == strcmp(argv[0], "menu")) {
}
#endif
else if (0 == strcmp(argv[0], "connect")) {
int a;
for (a = 1; a < argc; a++) {
if (0 == strcmp(argv[a], "wid"))
lcd_wid = atoi(argv[++a]);
else if (0 == strcmp(argv[a], "hgt"))
lcd_hgt = atoi(argv[++a]);
else if (0 == strcmp(argv[a], "cellwid"))
lcd_cellwid = atoi(argv[++a]);
else if (0 == strcmp(argv[a], "cellhgt"))
lcd_cellhgt = atoi(argv[++a]);
}
connected = 1;
if (displayname != NULL)
sock_printf(sock, "client_set -name \"%s\"\n", displayname);
else
sock_printf(sock, "client_set -name {LCDproc %s}\n", get_hostname());
#ifdef LCDPROC_MENUS
menus_init();
#endif
}
else if (0 == strcmp(argv[0], "bye")) {
exit_program(EXIT_SUCCESS);
}
else if (0 == strcmp(argv[0], "success")) {
}
else {
/*
int j;
for (j = 0; j < argc; j++)
printf("%s ", argv[j]);
printf("\n");
*/
}
}
/* Restart tokenizing */
argc = 0;
newtoken = 1;
break;
} /* switch( buf[i] ) */
}
len = sock_recv(sock, buf, 8000);
}
/* Gather stats and update screens */
if (connected) {
for (i = 0; sequence[i].which > 0; i++) {
sequence[i].timer++;
if (!(sequence[i].flags & ACTIVE))
continue;
if (sequence[i].flags & VISIBLE) {
if (sequence[i].timer >= sequence[i].on_time) {
sequence[i].timer = 0;
/* Now, update the screen... */
update_screen(&sequence[i], 1);
}
}
else {
if (sequence[i].timer >= sequence[i].off_time) {
sequence[i].timer = 0;
/* Now, update the screen... */
update_screen(&sequence[i], sequence[i].show_invisible);
}
}
if (islow > 0)
usleep(islow * 10000);
}
}
/* Now sleep... */
usleep(TIME_UNIT);
}
}
/* EOF */
-78
View File
@@ -1,78 +0,0 @@
/** \file clients/lcdproc/main.h
* Contains mode related defines and structures.
*/
/*-
* This file is part of lcdproc, the lcdproc client.
*
* This file is released under the GNU General Public License.
* Refer to the COPYING file distributed with this package.
*/
#ifndef MAIN_H
#define MAIN_H
#include "shared/defines.h"
#ifndef TRUE
# define TRUE 1
#endif
#ifndef FALSE
# define FALSE 0
#endif
#define LCDP_BATT_HIGH 0x00
#define LCDP_BATT_LOW 0x01
#define LCDP_BATT_CRITICAL 0x02
#define LCDP_BATT_CHARGING 0x03
#define LCDP_BATT_ABSENT 0x04
#define LCDP_BATT_UNKNOWN 0xFF
#define LCDP_AC_OFF 0x00
#define LCDP_AC_ON 0x01
#define LCDP_AC_BACKUP 0x02
#define LCDP_AC_UNKNOWN 0x03
extern int Quit;
extern int sock;
extern char *version;
extern char *build_date;
extern int lcd_wid;
extern int lcd_hgt;
extern int lcd_cellwid;
extern int lcd_cellhgt;
/** Screen data structure */
typedef struct _screen_mode
{
char *longname; /**< Which screen is it (long name)? */
char which; /**< Which screen is it (short name)? */
int on_time; /**< How often to update while visible? */
int off_time; /**< How often to get stats while not visible? */
int show_invisible; /**< Send stats while not visible? */
int timer; /**< Time since last update */
int flags; /**< See mode flags defines */
int (*func)(int,int,int *); /**< Pointer to init / update function */
} ScreenMode;
/* mode flags */
#define VISIBLE 0x00000001 /**< currently visible */
#define ACTIVE 0x00000002 /**< selected for display */
#define INITIALIZED 0x00000004 /**< screen had already been initialized */
#define BLINK_ON 0x10
#define BLINK_OFF 0x11
#define BACKLIGHT_OFF 0x20
#define BACKLIGHT_ON 0x21
#define HOLD_SCREEN 0x30
#define CONTINUE 0x31
#define LCD_MAX_WIDTH 80
#define LCD_MAX_HEIGHT 80
const char *get_hostname(void);
const char *get_sysname(void);
const char *get_sysrelease(void);
#endif
-346
View File
@@ -1,346 +0,0 @@
/** \file clients/lcdproc/mem.c
* Implements the 'Memory' and 'ProcSize' screens.
*/
/*-
* This file is part of lcdproc, the lcdproc client.
*
* This file is released under the GNU General Public License.
* Refer to the COPYING file distributed with this package.
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#ifdef IRIX
#include <strings.h>
#endif
#include <unistd.h>
#include <fcntl.h>
#include <dirent.h>
#include "shared/sockets.h"
#include "shared/LL.h"
#include "main.h"
#include "mode.h"
#include "machine.h"
#include "mem.h"
#include "util.h"
/**
* Mem Screen displays info about memory and swap usage...
*
*\verbatim
*
* +--------------------+ +--------------------+
* |## MEM #### SWAP #@| |M 758.3M [- ] 35.3%@|
* | 758.3M Totl 1.884G | |S 1.884G [ ] 0.1% |
* | 490.8M Free 1.882G | +--------------------+
* |E--- F E F|
* +--------------------+
*
*\endverbatim
*
* \param rep Time since last screen update
* \param display 1 if screen is visible or data should be updated
* \param flags_ptr Mode flags
* \return Always 0
*/
int
mem_screen(int rep, int display, int *flags_ptr)
{
static int which_title = 0;
static int gauge_wid = 0;
static int gauge_offs = 0;
meminfo_type mem[2];
if ((*flags_ptr & INITIALIZED) == 0) {
*flags_ptr |= INITIALIZED;
sock_send_string(sock, "screen_add M\n");
sock_printf(sock, "screen_set M -name {Memory & Swap: %s}\n", get_hostname());
if (lcd_hgt >= 4) {
gauge_wid = (lcd_wid >= 18)
? (lcd_wid - 6) / 2 /* room for E..F pairs and 2 spaces in between */
: (lcd_wid - 4) / 2; /* leave room for the E...F pairs */
sock_send_string(sock, "widget_add M title title\n");
sock_send_string(sock, "widget_set M title { MEM}\n");
sock_send_string(sock, "widget_add M subtitle string\n");
sock_printf(sock, "widget_set M subtitle %i 1 { SWAP }\n", lcd_wid - 6);
sock_send_string(sock, "widget_add M totl string\n");
sock_send_string(sock, "widget_add M used string\n");
sock_printf(sock, "widget_set M totl %i 2 Totl\n", lcd_wid/2 - 1);
sock_printf(sock, "widget_set M used %i 3 Free\n", lcd_wid/2 - 1);
sock_send_string(sock, "widget_add M EFmem string\n");
sock_printf(sock, "widget_set M EFmem 1 4 {E%*sF}\n", gauge_wid, "");
sock_send_string(sock, "widget_add M EFswap string\n");
sock_printf(sock, "widget_set M EFswap %i 4 {E%*sF}\n",
lcd_wid - gauge_wid - 1, gauge_wid, "");
sock_send_string(sock, "widget_add M memused string\n");
sock_send_string(sock, "widget_add M swapused string\n");
}
else {
gauge_wid = (lcd_wid >= 18) ? max(2, lcd_wid - 18) : 0;
gauge_offs = (lcd_wid - gauge_wid) / 2 + 2;
sock_send_string(sock, "widget_add M m string\n");
sock_send_string(sock, "widget_add M s string\n");
if (gauge_wid > 0) {
sock_printf(sock, "widget_set M m 1 1 {M%*s[%*s]}\n",
gauge_offs - 3, "", gauge_wid, "");
sock_printf(sock, "widget_set M s 1 2 {S%*s[%*s]}\n",
gauge_offs - 3, "", gauge_wid, "");
}
else {
sock_send_string(sock, "widget_set M m 1 1 {M }\n");
sock_send_string(sock, "widget_set M s 1 2 {S }\n");
}
sock_send_string(sock, "widget_add M mem% string\n");
sock_send_string(sock, "widget_add M swap% string\n");
}
sock_send_string(sock, "widget_add M memtotl string\n");
sock_send_string(sock, "widget_add M swaptotl string\n");
sock_send_string(sock, "widget_add M memgauge hbar\n");
sock_send_string(sock, "widget_add M swapgauge hbar\n");
}
machine_get_meminfo(mem);
if (lcd_hgt >= 4) {
char tmp[12]; /* should be sufficient */
/* flip the title back and forth... (every 4 updates) */
if (which_title & 4) {
sock_printf(sock, "widget_set M subtitle %i 1 {}\n", lcd_wid - 7);
sock_printf(sock, "widget_set M title {%s}\n", get_hostname());
}
else {
sock_send_string(sock, "widget_set M title { MEM}\n");
sock_printf(sock, "widget_set M subtitle %i 1 { SWAP }\n", lcd_wid - 7);
}
which_title = (which_title + 1) & 7;
/* Total memory */
sprintf_memory(tmp, mem[0].total * 1024.0, 1);
if (display)
sock_printf(sock, "widget_set M memtotl 1 2 {%7s}\n", tmp);
/* Free memory (plus buffers and cache) */
sprintf_memory(tmp, (mem[0].free + mem[0].buffers + mem[0].cache) * 1024.0, 1);
if (display)
sock_printf(sock, "widget_set M memused 1 3 {%7s}\n", tmp);
/* Total swap */
sprintf_memory(tmp, mem[1].total * 1024.0, 1);
if (display)
sock_printf(sock, "widget_set M swaptotl %i 2 {%7s}\n", lcd_wid - 7, tmp);
/* Free swap */
sprintf_memory(tmp, mem[1].free * 1024.0, 1);
if (display)
sock_printf(sock, "widget_set M swapused %i 3 {%7s}\n", lcd_wid - 7, tmp);
if (gauge_wid > 0) {
/* Free memory graph */
if (mem[0].total > 0) {
double value = 1.0 - (double) (mem[0].free + mem[0].buffers + mem[0].cache)
/ (double) mem[0].total;
/* printf(".0f", val) only prints the integer part */
if (display)
sock_printf(sock, "widget_set M memgauge 2 4 %.0f\n",
lcd_cellwid * gauge_wid * value);
}
/* Free swap graph */
if (mem[1].total > 0) {
double value = 1.0 - ((double) mem[1].free / (double) mem[1].total);
/* printf(".0f", val) only prints the integer part */
if (display)
sock_printf(sock, "widget_set M swapgauge %i 4 %.0f\n",
lcd_wid - gauge_wid, lcd_cellwid * gauge_wid * value);
}
}
}
else {
char tmp[12]; /* should be sufficient */
/* Total memory */
sprintf_memory(tmp, mem[0].total * 1024.0, 1);
if (display)
sock_printf(sock, "widget_set M memtotl 3 1 {%6s}\n", tmp);
/* Total swap */
sprintf_memory(tmp, mem[1].total * 1024.0, 1);
if (display)
sock_printf(sock, "widget_set M swaptotl 3 2 {%6s}\n", tmp);
/* Free memory graph */
strcpy(tmp, "N/A");
if (mem[0].total > 0) {
double value = 1.0 - (double) (mem[0].free + mem[0].buffers + mem[0].cache)
/ (double) mem[0].total;
if (gauge_wid > 0) {
/* printf(".0f", val) only prints the integer part */
if (display)
sock_printf(sock, "widget_set M memgauge %i 1 %.0f\n",
gauge_offs, lcd_cellwid * gauge_wid * value);
}
sprintf_percent(tmp, value * 100);
}
if (display)
sock_printf(sock, "widget_set M mem%% %i 1 {%5s}\n", lcd_wid - 5, tmp);
/* Free swap graph */
strcpy(tmp, "N/A");
if (mem[1].total > 0) {
double value = 1.0 - ((double) mem[1].free / (double) mem[1].total);
if (gauge_wid > 0) {
/* printf(".0f", val) only prints the integer part */
if (display)
sock_printf(sock, "widget_set M swapgauge %i 2 %.0f\n",
gauge_offs, lcd_cellwid * gauge_wid * value);
}
sprintf_percent(tmp, value * 100);
}
if (display)
sock_printf(sock, "widget_set M swap%% %i 2 {%5s}\n", lcd_wid - 5, tmp);
}
return 0;
}
/**
* Compares memory usage two procinfo structures and returns 1 (true) if the
* second one's is larger than the first one's, 0 (false) otherwise.
*/
static int
sort_procs(void *a, void *b)
{
procinfo_type *one, *two;
if ((a == NULL) || (b == NULL))
return 0;
one = (procinfo_type *) a;
two = (procinfo_type *) b;
return (two->totl > one->totl);
}
/**
* Mem Top Screen displays info about top 5 memory hogs...
*
*\verbatim
*
* +--------------------+ +--------------------+
* |## TOP MEM: myhos #@| |## TOP MEM: myhos #@|
* |1 110.4M mysqld | |1 110.4M mysqld |
* |2 35.38M konqueror(2| +--------------------+
* |3 29.21M XFree86 |
* +--------------------+
*
*\endverbatim
*
* \param rep Time since last screen update
* \param display 1 if screen is visible or data should be updated
* \param flags_ptr Mode flags
* \return Always 0
*/
int
mem_top_screen(int rep, int display, int *flags_ptr)
{
LinkedList *procs;
int i;
if ((*flags_ptr & INITIALIZED) == 0) {
*flags_ptr |= INITIALIZED;
sock_send_string(sock, "screen_add S\n");
sock_printf(sock, "screen_set S -name {Top Memory Use: %s}\n", get_hostname());
sock_send_string(sock, "widget_add S title title\n");
sock_printf(sock, "widget_set S title {TOP MEM: %s}\n", get_hostname());
/* frame from (2nd line, left) to (last line, right) */
sock_send_string(sock, "widget_add S f frame\n");
/* scroll rate: 1 line every X ticks (= 1/8 sec) */
sock_printf(sock, "widget_set S f 1 2 %i %i %i 5 v %i\n",
lcd_wid, lcd_hgt, lcd_wid,
((lcd_hgt >= 4) ? 8 : 12));
/* frame contents */
for (i = 1; i <= 5; i++) {
sock_printf(sock, "widget_add S %i string -in f\n", i);
}
sock_send_string(sock, "widget_set S 1 1 1 Checking...\n");
}
/* Create a new process list */
procs = LL_new();
if (procs == NULL) {
fprintf(stderr, "mem_top_screen: Error allocating list\n");
return -1;
}
machine_get_procs(procs);
/*
* Ignore if machine_get_procs returns an errror. The list will be
* empty then and all process info will be shown empty, too.
*/
/* Now, print some info... */
LL_Rewind(procs);
LL_Sort(procs, sort_procs);
LL_Rewind(procs);
for (i = 1; i <= 5; i++) {
procinfo_type *p = LL_Get(procs);
if (p != NULL) {
char mem[10];
sprintf_memory(mem, (double) p->totl * 1024.0, 1);
if (display) {
if (p->number > 1)
sock_printf(sock, "widget_set S %i 1 %i {%i %5s %s(%i)}\n",
i, i, i, mem, p->name, p->number);
else
sock_printf(sock, "widget_set S %i 1 %i {%i %5s %s}\n",
i, i, i, mem, p->name);
}
}
else {
if (display)
sock_printf(sock, "widget_set S %i 1 %i { }\n", i, i);
}
LL_Next(procs);
}
/* Delete the process list */
LL_Rewind(procs);
do {
procinfo_type *p = (procinfo_type *) LL_Get(procs);
if (p != NULL) {
free(p);
}
} while (LL_Next(procs) == 0);
LL_Destroy(procs);
return 0;
}
-7
View File
@@ -1,7 +0,0 @@
#ifndef MEM_H
#define MEM_H
int mem_screen(int rep, int display, int *flags_ptr);
int mem_top_screen(int rep, int display, int *flags_ptr);
#endif
-216
View File
@@ -1,216 +0,0 @@
/** \file clients/lcdproc/mode.c
* Implements the 'About' screen and contains wrappers for machine dependend
* initialization / closing.
*/
/*-
* This file is part of lcdproc, the lcdproc client.
*
* This file is released under the GNU General Public License.
* Refer to the COPYING file distributed with this package.
*/
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/utsname.h>
#include <string.h>
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#if defined( IRIX ) || defined( SOLARIS )
# include <strings.h>
#endif
#include "shared/sockets.h"
#include "main.h"
#include "mode.h"
#include "machine.h"
#ifdef LCDPROC_EYEBOXONE
# include "eyebox.h"
#endif
/** Initialize mode specific things. */
int
mode_init(void)
{
machine_init();
return (0);
}
/** Clean up modes on exit */
void
mode_close(void)
{
machine_close();
}
/**
* Calls the mode specific screen init / update function and updates the Eyebox
* screen as well. Sets the backlight state according to return value of the
* mode specific screen function.
*
* \param m The screen mode
* \param display Flag whether to update screen even if not visible.
* \return Backlight state
*/
int
update_screen(ScreenMode *m, int display)
{
static int status = -1;
int old_status = status;
if (m && m->func) {
#ifdef LCDPROC_EYEBOXONE
/* Save the initialized flag (may be modified by m->func) */
int init_flag = (m->flags & INITIALIZED);
#endif
status = m->func(m->timer, display, &(m->flags));
#ifdef LCDPROC_EYEBOXONE
/* Eyebox Init */
if (init_flag == 0)
eyebox_screen(m->which, 0);
/* Eyebox Flush */
eyebox_screen(m->which, 1);
#endif
}
if (status != old_status) {
if (status == BACKLIGHT_OFF)
sock_send_string(sock, "backlight off\n");
if (status == BACKLIGHT_ON)
sock_send_string(sock, "backlight on\n");
if (status == BLINK_ON)
sock_send_string(sock, "backlight blink\n");
}
return (status);
}
/**
* Credit Screen shows who wrote this...
*
* \param rep Time since last screen update
* \param display 1 if screen is visible or data should be updated
* \param flags_ptr Mode flags
* \return Always 0
*/
int
credit_screen(int rep, int display, int *flags_ptr)
{
/*
* List of persons who contributed to LCDproc. Keep in sync with
* CREDITS file (ordered by appearance)
*/
const char *contributors[] = {
"William Ferrell",
"Selene Scriven",
"Gareth Watts",
"Lorand Bruhacs",
"Benjamin Tse",
"Matthias Prinke",
"Richard Rognlie",
"Tom Wheeley",
"Bjoern Andersson",
"Andrew McMeikan",
"David Glaude",
"Todd Porter",
"Bjoern Andersson",
"Jason Dale Woodward",
"Ethan Dicks",
"Michael Reinelt",
"Simon Harrison",
"Charles Steinkuehler",
"Harald Klein",
"Philip Pokorny",
"Glen Gray",
"David Douthitt",
"Eddie Sheldrake",
"Rene Wagner",
"Andre Breiler",
"Joris Robijn",
"Guillaume Filion",
"Chris Debenham",
"Mark Haemmerling",
"Robin Adams",
"Manuel Stahl",
"Mike Patnode",
"Peter Marschall",
"Markus Dolze",
"Volker Boerchers",
"Lucian Muresan",
"Matteo Pillon",
"Laurent Arnal",
"Simon Funke",
"Matthias Goebl",
"Stefan Herdler",
"Bernhard Walle",
"Andrew Foss",
"Anthony J. Mirabella",
"Cedric Tessier",
"John Sanders",
"Eric Pooch",
"Benjamin Wiedmann",
"Frank Jepsen",
"Karsten Festag",
"Gatewood Green",
"Dave Platt",
"Nicu Pavel",
"Daryl Fonseca-Holt",
"Thien Vu",
"Thomas Jarosch",
"Christian Jodar",
"Mariusz Bialonczyk",
"Jack Cleaver",
"Aron Parsons",
"Malte Poeggel",
"Dean Harding",
"Christian Leuschen",
"Jonathan Kyler",
NULL
};
int contr_num = 0;
int i;
if ((*flags_ptr & INITIALIZED) == 0) {
*flags_ptr |= INITIALIZED;
/* get number of contributors */
for (contr_num = 0; contributors[contr_num] != NULL; contr_num++)
; /* NADA */
sock_send_string(sock, "screen_add A\n");
sock_send_string(sock, "screen_set A -name {Credits for LCDproc}\n");
sock_send_string(sock, "widget_add A title title\n");
sock_printf(sock, "widget_set A title {LCDPROC %s}\n", version);
if (lcd_hgt >= 4) {
sock_send_string(sock, "widget_add A text scroller\n");
sock_printf(sock, "widget_set A text 1 2 %d 2 h 8 {%s}\n",
lcd_wid, "LCDproc was brought to you by:");
}
/* frame from (2nd/3rd line, left) to (last line, right) */
sock_send_string(sock, "widget_add A f frame\n");
sock_printf(sock, "widget_set A f 1 %i %i %i %i %i v %i\n",
((lcd_hgt >= 4) ? 3 : 2), lcd_wid, lcd_hgt, lcd_wid, contr_num,
/* scroll rate: 1 line every X ticks (= 1/8 sec) */
((lcd_hgt >= 4) ? 8 : 12));
/* frame contents */
for (i = 1; i < contr_num; i++) {
sock_printf(sock, "widget_add A c%i string -in f\n", i);
sock_printf(sock, "widget_set A c%i 1 %i {%s}\n", i, i, contributors[i]);
}
}
return 0;
}
/* EOF */
-9
View File
@@ -1,9 +0,0 @@
#ifndef MODE_H
#define MODE_H
int mode_init(void);
void mode_close(void);
int update_screen(ScreenMode *m, int display);
int credit_screen(int rep, int display, int *flags_ptr);
#endif
-100
View File
@@ -1,100 +0,0 @@
/** \file clients/lcdproc/util.c
* Utility functions to print some numerical values in a nice fashion
*/
/*-
* Copyright (C) 2005 Peter Marschall
*
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301.
*/
#include "util.h"
/** Print a memory value with the correct unit to a given string.
* \param *dst String to print the value to.
* \param value Value to print.
* \param roundlimit Set < 1.0 if precision of original input value is not sufficient.
* \return dst
*/
char *
sprintf_memory(char *dst, double value, double roundlimit)
{
if (dst != NULL) {
char *format = "%.1f%s";
char *unit = convert_double(&value, 1024, roundlimit);
if (value < 100)
format = "%.2f%s";
if (value < 10)
format = "%.3f%s";
sprintf(dst, format, value, unit);
}
return dst;
}
/** Print a percentage value to a given string.
* \param *dst String to print the percentage value to.
* \param percent Value to print.
* \return dst
*/
char *
sprintf_percent(char *dst, double percent)
{
if (dst != NULL) {
if (percent > 99.9)
strcpy(dst, "100%");
else
sprintf(dst, "%.1f%%", (percent >= 0) ? percent : 0);
}
return dst;
}
/** Convert a value with unit value.
* does not do formatting
* \param *value Pointer to the value to be scaled
* \param base Base used for scaling (e.g. 1000 for decimal, 1024 for binary units)
* \param roundlimit Set < 1.0 if precision of original input value is not sufficient
* \return Unit string to be used when displaying value
*/
char *
convert_double(double *value, int base, double roundlimit)
{
static char *units[] = {"", "k", "M", "G", "T", "P", "E", "Z", "Y", NULL};
int off = 0;
if ((roundlimit <= 0.0) || (roundlimit > 1.0))
roundlimit = 0.5;
/* Get value's order of magnitude */
while (units[off] != NULL) {
/*
* Note: the check for 1000 is to idenfity the number of
* characters in the output needed, not to decide if to scale
* value.
*/
if (*value < 1000 * roundlimit)
break;
off++;
*value /= base;
}
return units[off];
}
/* EOF */
-29
View File
@@ -1,29 +0,0 @@
/** \file clients/lcdproc/util.h
* Header file for \c util.c
*/
/*-
* Copyright (C) 2005 Peter Marschall
*
* This file is part of lcdproc, the lcdproc client.
*
* This file is released under the GNU General Public License.
* Refer to the COPYING file distributed with this package.
*/
#ifndef LCDPROC_UTIL_H
#define LCDPROC_UTIL_H
#include <stdio.h>
#include <string.h>
/** print a memory value with the correct unit to a given string */
char *sprintf_memory(char *dst, double value, double roundlimit);
/** print a percentage value to a given string */
char *sprintf_percent(char *dst, double percent);
/** converts value into power-of-x representation */
char *convert_double(double *value, int base, double roundlimit);
#endif
-4
View File
@@ -1,4 +0,0 @@
.deps
Makefile
Makefile.in
lcdvc
-23
View File
@@ -1,23 +0,0 @@
## Process this file with automake to produce Makefile.in
sysconf_DATA = lcdvc.conf
bin_PROGRAMS = lcdvc
lcdvc_SOURCES = lcdvc.c lcdvc.h lcd_link.c lcd_link.h vc_link.c vc_link.h
lcdvc_LDADD = ../../shared/libLCDstuff.a
if DARWIN
AM_LDFLAGS = -framework CoreFoundation -framework IOKit
endif
AM_CPPFLAGS = -I$(top_srcdir) -I$(top_srcdir)/shared -DSYSCONFDIR=\"$(sysconfdir)\" -DPIDFILEDIR=\"$(pidfiledir)\"
#AM_CFLAGS = -g -O0
#AM_LDFLAGS = -g
EXTRA_DIST = $(sysconf_DATA)
## EOF
-379
View File
@@ -1,379 +0,0 @@
/** \file clients/lcdvc/lcd_link.c
* Functions to build and update the display and to handle server input.
*/
/*-
* This file is part of lcdvc, an LCDproc client.
*
* This file is released under the GNU General Public License. Refer to the
* COPYING file distributed with this package.
*
* Copyright (c) 2002, Joris Robijn
* 2006-2008, Peter Marschall
*/
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <stdlib.h>
#include "lcd_link.h"
#include "vc_link.h"
#include "lcdvc.h"
#include "shared/report.h"
#include "shared/str.h"
#include "shared/sockets.h"
char *address = UNSET_STR;
int port = UNSET_INT;
short autoscroll = 1;
int sock;
short listening = 0;
short scroll_x = 0, scroll_y = 0;
short lcd_cursor_x, lcd_cursor_y;
short lcd_width = 0, lcd_height = 0;
char *lcd_buf = NULL;
short last_vc_cursor_y = 0;
short last_vc_cursor_x = 0;
short last_lcd_cursor_x = 0;
short last_lcd_cursor_y = 0;
static int read_connect_string(void);
static int split(char *str, char delim, char *parts[], int maxparts);
int setup_connection(void)
{
char buf[200];
int i;
int e = 0;
short line;
report(RPT_INFO, "Connecting to %s:%d", address, port);
sock = sock_connect(address, port);
if (sock < 0) {
report(RPT_ERR, "Connecting to %s:%d failed", address, port);
return -1;
}
/* Create our menu */
sock_send_string(sock, "hello\n");
if (read_connect_string() < 0) {
return -1;
}
snprintf(buf, sizeof(buf)-1, "client_set -name \"%s\"\n", progname);
sock_send_string(sock, buf);
/* Create screen */
CHAIN(e, sock_send_string(sock, "screen_add console\n"));
for (line = 0; line < lcd_height; line++) {
snprintf(buf, sizeof(buf)-1, "widget_add console line%d string\n", line);
buf[sizeof(buf)-1] = 0;
CHAIN(e, sock_send_string(sock, buf));
}
/* Add menu items */
CHAIN(e, sock_send_string(sock, "menu_add_item \"\" autoscroll checkbox \"Auto scroll\"\n"));
CHAIN(e, sock_send_string(sock, "menu_set_item \"\" autoscroll -value on\n"));
/* Reserve keys */
for (i = 0; i < 4; i++) {
snprintf(buf, sizeof(buf)-1, "client_add_key \"%s\"\n", keys[i]);
CHAIN(e, sock_send_string(sock, buf));
}
if (e < 0) {
report(RPT_ERR, "Could not send to to LCDd");
return -1;
}
return 0;
}
int teardown_connection(void)
{
sock_close(sock);
return 0;
}
static int read_connect_string(void)
{
char buf[8192];
int len = 0;
int a;
char *argv[20];
int argc;
short received = 0;
short timeout = 50; /* Give the server 5 secs to respond */
buf[0] = '\0';
while (!received && timeout > 0) {
len = sock_recv_string(sock, buf, sizeof(buf));
if (len == 0) {
usleep(100000);
timeout --;
} else {
received = 1;
}
}
report(RPT_INFO, "Received: %s", buf);
if (len <= 0) {
report(RPT_ERR, "Did not receive LCDd connect response.");
return -1;
}
argc = split(buf, ' ', argv, 20);
for (a = 1; a < argc; a++) {
if (0 == strcmp(argv[a], "wid"))
lcd_width = atoi(argv[++a]);
else if (0 == strcmp(argv[a], "hgt"))
lcd_height = atoi(argv[++a]);
}
if (argc <= 0 || strcmp(argv[0], "connect") != 0
|| lcd_width == 0 || lcd_width == 0) {
report(RPT_ERR, "Received invalid LCDd connect response.");
return -1;
}
return 0;
}
/**
* Splits a string into parts, to which pointers will be returned in &parts.
* The return value is the number of parts.
* maxparts is the maximum number of parts returned. If more parts exist
* they are (unsplit) in the last part.
* The parts are split at the character delim.
* No new space will be allocated, the string str will be mutated !
*/
static int split(char *str, char delim, char *parts[], int maxparts)
{
char *p1 = str;
char *p2;
int part_nr = 0;
/* Find the delim char to end the current part */
while (part_nr < maxparts - 1 && (p2 = strchr(p1, delim))) {
/* subsequent parts... */
*p2 = 0;
parts[part_nr] = p1;
p1 = p2 + 1; /* Just after the delim char */
part_nr ++;
}
/* and the last part... */
parts[part_nr] = p1;
part_nr ++;
return part_nr;
}
int read_response(char *buf, int maxsize)
{
return sock_recv_string(sock, buf, maxsize);
}
int process_response(char *str)
{
char *argv[10];
int argc;
//int i;
//char *p;
char *str2 = strdup(str); /* get_args modifies str2 */
report(RPT_DEBUG, "Server said: \"%s\"", str);
/* Check what the server just said to us... */
argc = get_args(argv, str2, 10);
if (argc < 1) {
free(str2);
return 0;
}
if (strcmp(argv[0], "listen") == 0) {
listening = 1;
}
else if (strcmp(argv[0], "ignore") == 0) {
listening = 0;
}
else if (strcmp(argv[0], "menuevent") == 0) {
/* Ah, this is what we were waiting for ! */
if (argc < 2) {
report(RPT_WARNING, "Server gave invalid response");
free(str2);
return -1;
}
else if (strcmp(argv[1], "update") == 0) {
if (argc < 4) {
report(RPT_WARNING, "Server gave invalid response");
free(str2);
return -1;
}
if (strcmp(argv[2], "autoscroll") == 0) {
if (strcmp(argv[3], "on") == 0) {
autoscroll = 1;
} else if (strcmp(argv[3], "off") == 0) {
autoscroll = 0;
}
report(RPT_INFO, "Autoscroll set to %d", autoscroll);
}
}
else {
; /* Ignore other menuevents */
}
}
else if (strcmp(argv[0], "key") == 0) {
if (argc < 2) {
report(RPT_WARNING, "Server gave invalid response");
free(str2);
return -1;
}
if (strcmp(argv[1], keys[0]) == 0) {
if (scroll_y > 0) scroll_y --;
} else if (strcmp(argv[1], keys[1]) == 0) {
if (scroll_y + lcd_height < vc_height) scroll_y ++;
} else if (strcmp(argv[1], keys[2]) == 0) {
if (scroll_x > 0) scroll_x --;
} else if (strcmp(argv[1], keys[3]) == 0) {
if (scroll_x + lcd_width < vc_width) scroll_x ++;
}
}
else if (strcmp(argv[0], "huh?") == 0) {
/* Report errors */
report(RPT_WARNING, "Server said: \"%s\"", str);
}
else {
; /* Ignore all other responses */
}
free(str2);
return 0;
}
int update_display(void)
{
//int bytes_read;
short line;
int e = 0;
char buf[80];
char *str_buf;
short num_lines;
num_lines = min(lcd_height, vc_height);
if (!listening)
return 0;
if (!lcd_buf) {
/* Not yet allocated */
lcd_buf = malloc(lcd_width * lcd_height);
memset(lcd_buf, ' ', lcd_width * lcd_height);
}
if (autoscroll
&& (last_vc_cursor_x != vc_cursor_x || last_vc_cursor_y != vc_cursor_y)) {
last_vc_cursor_x = vc_cursor_x;
last_vc_cursor_y = vc_cursor_y;
/* Adjust scroll position */
if (scroll_x > vc_cursor_x)
scroll_x = vc_cursor_x;
if (scroll_x < vc_cursor_x - lcd_width + 1)
scroll_x = vc_cursor_x - lcd_width + 1;
if (scroll_y > vc_cursor_y)
scroll_y = vc_cursor_y;
if (scroll_y < vc_cursor_y - lcd_height + 1)
scroll_y = vc_cursor_y - lcd_height + 1;
}
lcd_cursor_x = vc_cursor_x - scroll_x + 1;
lcd_cursor_y = vc_cursor_y - scroll_y + 1;
if (lcd_cursor_x != last_lcd_cursor_x || lcd_cursor_y != last_lcd_cursor_y) {
last_lcd_cursor_x = lcd_cursor_x;
last_lcd_cursor_y = lcd_cursor_y;
/* New scroll positions, send the cursor command */
if (lcd_cursor_x < 1 || lcd_cursor_x > lcd_width
|| lcd_cursor_y < 1 || lcd_cursor_y > lcd_height) {
snprintf(buf, sizeof(buf)-1, "screen_set console -cursor off\n");
} else {
snprintf(buf, sizeof(buf)-1, "screen_set console -cursor on -cursor_x %d -cursor_y %d\n",
lcd_cursor_x, lcd_cursor_y);
}
buf[sizeof(buf)-1] = 0;
CHAIN(e, sock_send_string(sock, buf));
}
/* Send all (changed) lines */
str_buf = malloc(80 + 2 * lcd_width);
for (line = 0; line < num_lines; line++) {
char *vc_p;
char *lcd_p;
short line_width;
line_width = min(lcd_width, vc_width);
/* Where does the data for this line come from ? */
vc_p = vc_buf + vc_width * (scroll_y + line) + scroll_x;
lcd_p = lcd_buf + lcd_width * line;
/* Has the line data changed ? */
if (memcmp(vc_p, lcd_p, line_width) != 0) {
/* Yes, so send it */
char *a;
short pos;
/* Format/escape the data */
snprintf(str_buf, 80, "widget_set console line%d 1 %d \"", line, line+1);
a = str_buf + strlen(str_buf); /* start just after the " */
for (pos = 0; pos < line_width; pos++) {
if (vc_p[pos] == '\\' || vc_p[pos] == '\"') {
*a++ = '\\'; /* add escape char */
}
if ((signed char) vc_p[pos] >= 32) {
*a++ = vc_p[pos]; /* add char */
} else {
*a++ = '?';
}
}
*a++ = '\"'; /* end string */
*a++ = '\n'; /* newline */
*a = 0; /* terminate */
CHAIN(e, sock_send_string(sock, str_buf));
/* And store the new data */
memcpy(lcd_p, vc_p, line_width);
}
}
free(str_buf);
if (e < 0) {
report(RPT_ERR, "Error while sending data to LCDd");
return -1;
}
return 0;
}
int send_nop(void)
{
return sock_send_string(sock, "\n");
}
-14
View File
@@ -1,14 +0,0 @@
#ifndef LCD_LINK_H
#define LCD_LINK_H
extern char *address;
extern int port;
int setup_connection(void);
int teardown_connection(void);
int read_response(char *str, int maxsize);
int process_response(char *str);
int update_display(void);
int send_nop(void);
#endif
-300
View File
@@ -1,300 +0,0 @@
/** \file clients/lcdvc/lcdvc.c
* Main file for \c lcdvc, the LCDproc virtual console.
*/
/*-
* This file is part of lcdvc, an LCDproc client.
*
* This file is released under the GNU General Public License. Refer to the
* COPYING file distributed with this package.
*
* Copyright (c) 2002, Joris Robijn
* 2006-2008, Peter Marschall
*/
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <signal.h>
#include <fcntl.h>
#include <errno.h>
#include <stdlib.h>
#include "getopt.h"
#include "shared/report.h"
#include "shared/configfile.h"
#include "shared/sockets.h"
#include "lcd_link.h"
#include "vc_link.h"
#include "lcdvc.h"
#if !defined(SYSCONFDIR)
# define SYSCONFDIR "/etc"
#endif
#if !defined(PIDFILEDIR)
# define PIDFILEDIR "/var/run"
#endif
#define DEFAULT_CONFIGFILE SYSCONFDIR "/lcdvc.conf"
#define DEFAULT_PIDFILE PIDFILEDIR "/lcdvc.pid"
char *help_text =
"lcdvc - LCDproc virtual console\n"
"\n"
"Copyright (c) 2002, Joris Robijn, 2006-2008 Peter Marschall.\n"
"This program is released under the terms of the GNU General Public License.\n"
"\n"
"Usage: lcdvc [<options>]\n"
" where <options> are:\n"
" -c <file> Specify configuration file ["DEFAULT_CONFIGFILE"]\n"
" -a <address> DNS name or IP address of the LCDd server [localhost]\n"
" -p <port> port of the LCDd server [13666]\n"
" -f Run in foreground\n"
" -r <level> Set reporting level (0-5) [2: errors and warnings]\n"
" -s <0|1> Report to syslog (1) or stderr (0, default)\n"
" -h Show this help\n";
/* Variables set by config */
int foreground = FALSE;
static int report_level = UNSET_INT;
static int report_dest = UNSET_INT;
char *vcsa_device = UNSET_STR;
char *vcs_device = UNSET_STR;
char *keys[4];
/* Other global variables */
char *progname = "lcdvc";
char *configfile = UNSET_STR;
char *pidfile = NULL;
int pidfile_written = FALSE;
int Quit = 0; /**< indicate end of main loop */
/* Function prototypes */
static void exit_program(int val);
static int process_command_line(int argc, char **argv);
static int process_configfile(char *configfile);
static int main_loop(void);
int main(int argc, char **argv)
{
int e = 0;
struct sigaction sa;
CHAIN( e, process_command_line( argc, argv ));
if (strcmp( configfile, UNSET_STR ) == 0) {
configfile = DEFAULT_CONFIGFILE;
}
CHAIN( e, process_configfile( configfile ));
if (report_dest == UNSET_INT || report_level == UNSET_INT) {
report_dest = RPT_DEST_STDERR;
report_level = RPT_ERR;
}
set_reporting( progname, report_level, report_dest );
CHAIN( e, open_vcs() );
CHAIN( e, setup_connection() );
CHAIN_END( e );
if (foreground != TRUE) {
if (daemon(1,1) != 0) {
report(RPT_ERR, "Error: daemonize failed");
}
if (pidfile != NULL) {
FILE *pidf = fopen(pidfile, "w");
if (pidf) {
fprintf(pidf, "%d\n", (int) getpid());
fclose(pidf);
pidfile_written = TRUE;
} else {
fprintf(stderr, "Error creating pidfile %s: %s\n",
pidfile, strerror(errno));
return(EXIT_FAILURE);
}
}
}
/* setup signal handlers for common signals */
sigemptyset(&sa.sa_mask);
#ifdef HAVE_SA_RESTART
sa.sa_flags = SA_RESTART;
#endif
sa.sa_handler = exit_program;
sigaction(SIGINT, &sa, NULL); // Ctrl-C
sigaction(SIGTERM, &sa, NULL); // "regular" kill
sigaction(SIGHUP, &sa, NULL); // kill -HUP
sigaction(SIGPIPE, &sa, NULL); // write to closed socket
sigaction(SIGKILL, &sa, NULL); // kill -9 [cannot be trapped; but ...]
main_loop();
exit_program(EXIT_SUCCESS);
/* NOTREACHED */
return EXIT_SUCCESS;
}
static void exit_program(int val)
{
//printf("exit program\n");
Quit = 1;
teardown_connection();
if ((foreground != TRUE) && (pidfile != NULL) && (pidfile_written == TRUE))
unlink(pidfile);
exit(val);
}
static int process_command_line(int argc, char **argv)
{
int c;
int error = 0;
/* No error output from getopt */
opterr = 0;
while ((c = getopt(argc, argv, "hc:a:p:fr:s:")) > 0) {
char *end;
int temp_int;
switch (c) {
case 'h':
fprintf(stderr, "%s", help_text);
exit(EXIT_SUCCESS);
/* NOTREACHED */
case 'c':
configfile = strdup(optarg);
break;
case 'a':
address = strdup(optarg);
break;
case 'p':
temp_int = strtol(optarg, &end, 0);
if ((*optarg != '\0') && (*end == '\0') &&
(temp_int > 0) && (temp_int <= 0xFFFF)) {
port = temp_int;
} else {
report(RPT_ERR, "Illegal port value %s", optarg);
error = -1;
}
break;
case 'f':
foreground = TRUE;
break;
case 'r':
temp_int = strtol(optarg, &end, 0);
if ((*optarg != '\0') && (*end == '\0') && (temp_int >= 0)) {
report_level = temp_int;
} else {
report(RPT_ERR, "Illegal report level value %s", optarg);
error = -1;
}
break;
case 's':
temp_int = strtol(optarg, &end, 0);
if ((*optarg != '\0') && (*end == '\0') && (temp_int >= 0)) {
report_dest = (temp_int ? RPT_DEST_SYSLOG : RPT_DEST_STDERR);
} else {
report(RPT_ERR, "Illegal log destination value %s", optarg);
error = -1;
}
break;
case ':':
report(RPT_ERR, "Missing option argument for %c", optopt);
error = -1;
break;
case '?':
default:
report(RPT_ERR, "Unknown option: %c", optopt);
error = -1;
break;
}
}
return error;
}
static int process_configfile(char *configfile)
{
if (strcmp(configfile, UNSET_STR) == 0) {
configfile = DEFAULT_CONFIGFILE;
}
if (config_read_file( configfile ) < 0) {
report( RPT_WARNING, "Could not read config file: %s", configfile);
}
if (strcmp(address, UNSET_STR ) == 0) {
address = strdup(config_get_string( progname, "Address", 0, "localhost"));
}
if (port == UNSET_INT) {
port = config_get_int(progname, "Port", 0, 13666);
}
if (report_level == UNSET_INT ) {
report_level = config_get_int(progname, "ReportLevel", 0, RPT_WARNING);
}
if (report_dest == UNSET_INT) {
if (config_get_bool(progname, "ReportToSyslog", 0, 0)) {
report_dest = RPT_DEST_SYSLOG;
} else {
report_dest = RPT_DEST_STDERR;
}
}
if (foreground != TRUE) {
foreground = config_get_bool(progname, "Foreground", 0, FALSE);
}
if (pidfile == NULL) {
pidfile = strdup(config_get_string(progname, "PidFile", 0, DEFAULT_PIDFILE));
}
vcs_device = strdup(config_get_string(progname, "vcsDevice", 0, "/dev/vcs"));
vcsa_device = strdup(config_get_string(progname, "vcsaDevice", 0, "/dev/vcsa"));
keys[0] = strdup(config_get_string( progname, "UpKey", 0, "Up"));
keys[1] = strdup(config_get_string( progname, "DownKey", 0, "Down"));
keys[2] = strdup(config_get_string( progname, "LeftKey", 0, "Left"));
keys[3] = strdup(config_get_string( progname, "RightKey", 0, "Right"));
return 0;
}
static int main_loop(void)
{
int num_bytes;
char buf[80];
short w = 0;
/* Continuously check if we get a menu event... */
while (!Quit && ((num_bytes = read_response(buf, sizeof(buf)-1)) >= 0)) {
if (num_bytes != 0) {
process_response(buf);
}
else {
read_vcdata();
update_display();
/* Send an empty line every 3 seconds to make sure the server still exists */
if (w++ >= 60) {
w = 0;
if (send_nop() < 0) {
break; /* Out of while loop */
}
}
usleep(50000);
}
}
if (!Quit)
report(RPT_WARNING, "Server disconnected %d", num_bytes);
return 0;
}
-34
View File
@@ -1,34 +0,0 @@
# lcdvc client configuration file
## general options ##
[lcdvc]
# Address of the LCDd server
#Address=127.0.0.1
# Port to attach to LCDd server
#Port=13666
#If false, report to stderr. If true, to syslog.
#ReportToSyslog=true
# Same as with LCDd.
#ReportLevel=4
# run in foreground [default: false; legal: true, false]
#Foreground=false
# PidFile location when running as daemon [default: /var/run/lcdvc.pid]
#PidFile=/var/run/lcdvc.pid
# Keys to move the visible area around the screen.
#UpKey=Up
#DownKey=Down
#LeftKey=Left
#RightKey=Right
# VC devices to use [default: /dev/vcs, /dev/vcsa]
vcsDevice=/dev/vcs
vcsaDevice=/dev/vcsa
# EOF
-26
View File
@@ -1,26 +0,0 @@
#ifndef LCDVC_H
#define LCDVC_H
#include "shared/defines.h"
#define CHAIN(e,f) { if( e>=0 ) { e=(f); }}
#define CHAIN_END(e) { if( e<0 ) { report( RPT_CRIT,"Critical error, abort"); exit(e); }}
#define UNSET_INT -1
#define UNSET_STR "\01"
#ifndef TRUE
# define TRUE 1
#endif
#ifndef FALSE
# define FALSE 0
#endif
extern char *vcs_device;
extern char *vcsa_device;
extern char *keys[4];
extern char *progname;
#endif
-97
View File
@@ -1,97 +0,0 @@
/** \file clients/lcdvc/vc_link.c
* Functions to handle a virtual console.
*/
/*-
* This file is part of lcdvc, an LCDproc client.
*
* This file is released under the GNU General Public License. Refer to the
* COPYING file distributed with this package.
*
* Copyright (c) 2002, Joris Robijn
* 2006-2008, Peter Marschall
*/
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <stdlib.h>
#include "lcdvc.h"
#include "vc_link.h"
#include "shared/report.h"
#include "shared/sockets.h"
int vcs0, vcsa;
unsigned short vc_width = 0, vc_height = 0;
unsigned short vc_cursor_x = 0, vc_cursor_y = 0;
char *vc_buf = NULL;
int open_vcs(void)
{
/* Open the /dev/vcsX and /dev/vcsaX devices */
vcs0 = open(vcs_device, O_RDONLY);
if (vcs0 < 0) {
report(RPT_ERR, "Could not open %s: %s", vcs_device, strerror(errno));
return -1;
}
vcsa = open(vcsa_device, O_RDONLY);
if (vcsa < 0) {
report(RPT_ERR, "Could not open %s: %s", vcsa_device, strerror(errno));
return -1;
}
return 0;
}
int read_vcdata(void)
{
unsigned short new_vc_height;
unsigned short new_vc_width;
int bytes_read;
unsigned char buf[20];
/* Read size and cursor position from /dev/vcsa */
lseek(vcsa, 0, SEEK_SET);
bytes_read = read(vcsa, buf, 4);
if (bytes_read != 4) {
report(RPT_ERR, "Could not read from %s", vcsa_device);
return -1;
}
new_vc_height = buf[0];
new_vc_width = buf[1];
vc_cursor_x = buf[2];
vc_cursor_y = buf[3];
/* Screen resize or initial buffer allocation ? */
if ((new_vc_width != vc_width) || (new_vc_height != vc_height)) {
vc_width = new_vc_width;
vc_height = new_vc_height;
if (vc_width * vc_height > 0) {
vc_buf = realloc(vc_buf, vc_width * vc_height);
if (vc_buf == NULL) {
report(RPT_ERR, "malloc failure: %s", strerror(errno));
return -1;
}
memset(vc_buf, ' ', vc_width * vc_height);
}
}
/* Read characters from /dev/cvs0 */
lseek(vcs0, 0, SEEK_SET);
bytes_read = read(vcs0, vc_buf, vc_width * vc_height);
if (bytes_read != vc_width * vc_height) {
report(RPT_ERR, "Could not read from %s", vcs_device);
return -1;
}
return 0;
}
-11
View File
@@ -1,11 +0,0 @@
#ifndef VC_LINK_H
#define VC_LINK_H
extern unsigned short vc_width, vc_height;
extern unsigned short vc_cursor_x, vc_cursor_y;
extern char *vc_buf;
int open_vcs(void);
int read_vcdata(void);
#endif
-2
View File
@@ -1,2 +0,0 @@
Makefile
Makefile.in
-7
View File
@@ -1,7 +0,0 @@
## Process this file with automake to produce Makefile.in
bin_SCRIPTS = lcdmetar.pl
EXTRA_DIST = $(bin_SCRIPTS)
## EOF
-260
View File
@@ -1,260 +0,0 @@
#!/usr/bin/perl -w
# Following is the POD documentation, type perldoc lcdmetar.pl to read it.
=pod
=head1 NAME
lcdMetar - Fetches METAR Weather information and send it to LCDproc.
=head1 SYNOPSIS
B<lcdmetar.pl> [I<METAR-Code>]
=head1 DESCRIPTION
B<lcdMetar> is a program to fetch METAR Weather information (e.g.
temperature) from a nearby (or not) airport using Geo::METAR and the
LWP modules.
Given an airport site code on the command line, lcdMetar
fetches the current weather observations,
and displays them via LCDproc (http://lcdproc.omnipotent.net/)
=head1 OPTIONS
=over 4
=item B<METAR-Code>
The METAR code related of the city you want weather observations.
For fun, here are some example METAR codes:
LA : KLAX
Dallas : KDFW
Detroit: KDTW
Chicago: KMDW
Graz/Austria (Thalerhof) : LOWG
Quebec City: CYQB
More informations about METAR codes is available at:
http://www.nws.noaa.gov/oso/oso1/oso12/metar.htm
=back
=head1 DIAGNOSTICS
=over 4
=item Cannot connect to LCDproc port
By default, lcdMetar tries to connect to localhost port 13666. If you get this
error, that means that this is not possible to connect to this port. You can change
the port lcdMetar connects to by modifying the script's variables $host and $port.
=item METAR is too short! Something went wrong.
The METAR data we received is not what we expected, check out NOOA's web site
(http://weather.noaa.gov/) to see if something has changed.
=item Can't connect to METAR source
lcdMetar tried to fetch weather observations from NOAA's web site and failed. It
will retry in 15 minutes.
=back
=head1 REQUIRES
Perl 5.004, Geo::METAR, LWP::Simple;
These are all available on CPAN: http://www.cpan.org/
=head1 DISCLAMER
Data distribution via the Internet is not considered an operational
delivery mechanism by the NWS due to our inability to insure access
to this service, therefore, the information available here shall not
be used for flight planning or other operational purposes.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License version 2 as
published by the Free Software Foundation.
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.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
=head1 BUGS
Yes, there might be some. Please report any one you find to LCDproc's mailing list.
See the website for more informations.
=head1 WEBSITE
Visit B<http://www.lcdproc.org/> for more infos and the lastest version.
=cut
use strict;
use Geo::METAR;
use LWP::Simple;
use IO::Socket;
use Fcntl;
############################################################
# Configurable part. Set it according your setup.
############################################################
# Verbose
# 0 : None (only fatal errors)
# 1 : Warnings
# 5 : Explain every step.
my $verbose = 1;
# METAR Code for your city/region.
my $site_code;
# Host which runs lcdproc daemon (LCDd)
my $host = "localhost";
# Port on which LCDd listens to requests
my $port = "13666";
# Metric or English data system?
# Can be either "metric", "nautical" or "english"
my $datasystem = "metric";
############################################################
# End of user configurable parts
############################################################
$SIG{INT} = \&grace;
$SIG{TERM} = \&grace;
# Get the site code.
$site_code = shift @ARGV || $site_code;
die "Usage: $0 <site_code>\n" unless $site_code;
# Connect to the server...
print "Connecting to LCDproc at $host\n" if ($verbose >= 5);
my $remote = IO::Socket::INET->new(
Proto => "tcp",
PeerAddr => $host,
PeerPort => $port,
) or die "Cannot connect to LCDproc port\n";
# Make sure our messages get there right away
$remote->autoflush(1);
sleep 1; # Give server plenty of time to notice us...
print $remote "hello\n";
my $lcdconnect = <$remote>;
print $lcdconnect if ($verbose >= 5);
# connect LCDproc 0.4.2 protocol 0.3 lcd wid 20 hgt 4 cellwid 5 cellhgt 8
($lcdconnect =~ /lcd.+wid\s+(\d+)\s+hgt\s+(\d+)/);
my $lcdwidth = $1; my $lcdheight= $2;
print "Detected LCD size of $lcdwidth x $lcdheight\n" if ($verbose >= 5);
# Turn off blocking mode...
fcntl($remote, F_SETFL, O_NONBLOCK);
# Set up some screen widgets...
print $remote "client_set name {Metar}\n";
print $remote "screen_add metar\n";
print $remote "screen_set metar name {Metar}\n";
print $remote "widget_add metar title title\n";
print $remote "widget_set metar title {Weather $site_code}\n";
print $remote "widget_add metar temp string\n";
print $remote "widget_add metar wind string\n";
print $remote "widget_add metar visib scroller\n";
print $remote "widget_add metar cloud string\n" if ($lcdheight > 4);
while (1) {
# fetch weather information
print "Fetching weather information\n" if ($verbose >= 5);
my $data = get("http://weather.noaa.gov/cgi-bin/mgetmetar.pl?cccc=$site_code");
if (not $data) {
warn "Can't connect to METAR source." if ($verbose >= 1);
} else {
# Yep, get the data and find the METAR.
my $m = new Geo::METAR;
$data =~ s/\n//go; # remove newlines
$data =~ m/($site_code\s\d+Z.*?)</go; # find the METAR string
my $metar = $1; # keep it
# Sanity check
die "METAR is too short! Something went wrong." if (length($metar)<1);
# pass the data to the METAR module.
# print("$metar\n");
$m->metar($metar);
# ask for the temperature(s)
my $temp; my $temp_u; my $dew; my $dew_u; my $wind; my $wind_u; my $wind_dir;
if ($datasystem eq "nautical") {
$temp = $m->C_TEMP;
$temp_u = "C";
$dew = $m->C_DEW;
$dew_u = "C";
$wind = $m->WIND_KTS;
$wind_u = " Knots";
$wind_dir = $m->WIND_DIR_DEG ."deg";
} elsif ($datasystem eq "english") {
$temp = $m->F_TEMP;
$temp_u = "F";
$dew = $m->F_DEW;
$dew_u = "F";
$wind = $m->WIND_MPH;
$wind_u = "mph";
$wind_dir = $m->WIND_DIR_ENG;
} else {
# Default: metric system (aka: international system)
$temp = $m->C_TEMP;
$temp_u = "C";
$dew = $m->C_DEW;
$dew_u = "C";
$wind = $m->WIND_MPH * 1.609344;
$wind_u = "km/h";
$wind_dir = $m->WIND_DIR_ENG;
}
my $metartime = $m->TIME;
my $sky = $m->SKY;
my $visibility = $m->VISIBILITY;
print $remote sprintf("widget_set metar title {Weather %s %s}\n", $site_code, $metartime);
print $remote sprintf("widget_set metar temp 1 2 {Temp %i%s (%i%s Dew)}\n", $temp, $temp_u, $dew, $dew_u) if ($temp and $dew);
print $remote sprintf("widget_set metar wind 1 3 {Wind %i%s, %s}\n", $wind, $wind_u, $wind_dir) if ($wind_dir and $wind);
print $remote sprintf("widget_set metar visib 1 %i %i %i h 3 {Visibility %s}\n", $lcdheight, $lcdwidth, $lcdheight, $visibility ) if ($visibility);
print $remote sprintf("widget_set metar cloud 1 4 {Sky %s}\n", join(',', @{$m->{sky}}) ) if ($m->{sky} and ($lcdheight>4));
} # end else
# eat all input from LCDd
while(defined(my $input = <$remote>)) { }
print "Sleeping for 15 minutes.\n" if ($verbose >= 5);
sleep 900;
}
# Should never go there since above is an infinite loop,
# send a SIGINT or SIGTERM to exit nicely.
# To be called on exit and on SIGINT or SIGTERM.
sub grace() {
print "Exiting...\n" if ($verbose >= 5);
close($remote);
exit;
}
__END__
-531
View File
@@ -1,531 +0,0 @@
# -*- mode: m4; -*-
dnl Process this file with autoconf 2.61 (or higher) to produce a configure script.
AC_PREREQ(2.61)
AC_INIT([lcdproc], [0.5dev], [lcdproc@lists.omnipotent.net])
AC_CONFIG_SRCDIR([clients/lcdproc/batt.c])
AM_INIT_AUTOMAKE
AC_CONFIG_HEADERS(config.h)
AC_CANONICAL_HOST
case "$host" in
*-*-*linux*) dnl i586-pc-linux-gnu
AC_DEFINE([LINUX],[1],[Define if you're using Linux.])
ac_system_host=Linux
;;
*-*-*solaris*)
AC_DEFINE([SOLARIS],[1],[Define if you're using Solaris.])
ac_system_host=Solaris
;;
*-*-*openbsd*) dnl i386-unknown-openbsd3.0
AC_DEFINE([OPENBSD],[1],[Define if you're using OpenBSD.])
ac_system_host=OpenBSD
;;
*-*-*netbsd*)
AC_DEFINE([NETBSD],[1],[Define if you're using NetBSD.])
ac_system_host=NetBSD
;;
*-*-*freebsd*)
AC_DEFINE([FREEBSD],[1],[Define if you're using FreeBSD.])
ac_system_host=FreeBSD
;;
*-*-*darwin*)
AC_DEFINE([DARWIN],[1],[Define if you're using Darwin/Mac OS X.])
ac_system_host=Darwin
;;
esac
AC_DEFINE_UNQUOTED([SYSTEM_HOST], [$ac_system_host], [Set this to your system host (Linux, Solaris, OpenBSD, NetBSD, FreeBSD or Darwin)])
dnl treat Darwin special in Makefiles
AM_CONDITIONAL(DARWIN, test x$ac_system_host = xDarwin)
AC_MSG_CHECKING([whether to enable debugging])
AC_ARG_ENABLE(debug,
[AS_HELP_STRING([--enable-debug], [show debug information])],
[ if test "$enableval" != "no"; then
AC_DEFINE(DEBUG, [1], [Define to 1 to show debug information])
debug="yes"
else
debug="no"
fi ],
[ debug=no ]
)
AC_MSG_RESULT($debug)
if test $debug = "yes"; then
dnl Enable debugging information with minimal optimisation if not set differently
dnl (the spaces before $CFLAGS and -O are significant)
CFLAGS="$CFLAGS -g"
if ! echo " $CFLAGS" | grep -q -- " -O" ; then
CFLAGS="$CFLAGS -O"
fi
else
dnl Maximum optimisation if not already set
dnl (the spaces before $CFLAGS and -O are significant)
if ! echo " $CFLAGS" | grep -q -- " -O" ; then
CFLAGS="$CFLAGS -O3"
fi
fi
dnl Checks for programs used in building
AC_PROG_CC
AC_PROG_CPP
AC_PROG_INSTALL
AC_PROG_RANLIB
AM_PROG_CC_C_O
AC_PATH_PROG([XMLTO], [xmlto], [no])
dnl Avoid unused static function warnings
CFLAGS="-Wall $CFLAGS"
AX_CFLAGS_GCC_OPTION(-Wno-unused-function)
AX_CFLAGS_GCC_OPTION(-ftrampolines)
export CFLAGS
dnl Solaris
AC_CHECK_FUNC(gethostbyname,,[AC_CHECK_LIB(nsl,gethostbyname)])
AC_CHECK_FUNC(connect,,[AC_CHECK_LIB(socket,connect)])
AC_CHECK_FUNC(inet_aton,,[AC_CHECK_LIB(resolv,inet_aton)])
AC_CHECK_LIB(kstat, kstat_open)
AC_CHECK_LIB(posix4, nanosleep)
AC_CHECK_FUNCS(getloadavg swapctl)
AC_CHECK_HEADERS(procfs.h sys/procfs.h sys/loadavg.h utmpx.h)
dnl Some versions of Solaris require -lelf for -lkvm
AC_CHECK_LIB(kvm, kvm_open,[
LIBS="-lkvm $LIBS"
],[AC_MSG_CHECKING([for kvm_open in -lkvm with -lelf])
AC_CACHE_VAL(ac_cv_lib_kvm_with_elf,
[ac_save_LIBS="$LIBS"
LIBS="-lkvm -lelf $LIBS"
AC_LINK_IFELSE([AC_LANG_PROGRAM([[char kvm_open();]], [[kvm_open()]])],[ac_cv_lib_kvm_with_elf=yes],[ac_cv_lib_kvm_with_elf=no])
LIBS="$ac_save_LIBS"
])
if test "$ac_cv_lib_kvm_with_elf" = "yes"; then
AC_MSG_RESULT(yes)
LIBS="-lkvm -lelf $LIBS"
else
AC_MSG_RESULT(no)
fi
])
dnl NetBSD, OpenBSD and FreeBSD
AC_CHECK_HEADERS(sched.h sys/types.h machine/pio.h machine/sysarch.h sys/cpuvar.h machine/apm_bios.h)
ETR_SYSV_IPC
ETR_UNION_SEMUN
dnl machine/cpufunc.h needs additional header on FreeBSD
AC_CHECK_HEADERS([machine/cpufunc.h], [], [],
[[#if HAVE_SYS_TYPES_H
# include <sys/types.h>
#endif
]])
dnl sched_setscheduler on OpenBSD
AC_CHECK_FUNCS(sched_setscheduler)
AC_CHECK_LIB(posix4, sched_setscheduler, [
AC_DEFINE([HAVE_SCHED_SETSCHEDULER], [1],
[Define if you have the sched_setscheduler function.])
])
AC_CHECK_LIB(rt, sched_setscheduler, [
AC_DEFINE([HAVE_SCHED_SETSCHEDULER], [1],
[Define if you have the sched_setscheduler function.])
])
dnl i386_get_ioperm on NetBSD&OpenBSD
AC_CHECK_LIB(i386, i386_get_ioperm,
LIBS="-li386 $LIBS"
AC_DEFINE([HAVE_I386_IOPERM_NETBSD], [1],
[Define if you have the NetBSD&OpenBSD version of i386_ioperm functions.]),[
dnl i386_get_ioperm on FreeBSD
AC_CHECK_LIB(c, i386_get_ioperm,
AC_DEFINE([HAVE_I386_IOPERM_FREEBSD],[1],
[Define if you have the FreeBSD version of the i386_ioperm functions.]),
[])]
)
AC_CHECK_FUNCS(iopl)
AC_CHECK_FUNCS(ioperm)
AC_CHECK_HEADERS(sys/io.h)
dnl Check if we support this parallel (LPT) port
dnl IMPORTANT: we must do all the checks used in port.h before doing this test!
AC_CACHE_CHECK([for a parallel port], ac_cv_port_have_lpt,
[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include "${srcdir}/server/drivers/port.h"]],
[[char val = port_in(0x350)]])],
[ac_cv_port_have_lpt=yes],[ac_cv_port_have_lpt=no])])
if test "$ac_cv_port_have_lpt" = yes; then
AC_DEFINE([HAVE_PCSTYLE_LPT_CONTROL], [1],
[Define if you have a parallel port and LCDproc knows how to talk to it.])
else
AC_MSG_WARN([Cannot talk to the parallel port, disabling drivers that use it.])
fi
x_ac_have_i2c=no
AC_CHECK_HEADERS([linux/i2c-dev.h dev/iicbus/iic.h], [x_ac_have_i2c=yes])
if test "$x_ac_have_i2c" = yes; then
AC_DEFINE(HAVE_I2C,[1],[Define to 1 if you have the i2c headers])
fi
x_ac_have_spi=no
AC_CHECK_HEADERS([linux/spi/spidev.h], [x_ac_have_spi=yes])
if test "$x_ac_have_spi" = yes; then
AC_DEFINE(HAVE_SPI,[1],[Define to 1 if you have the spi headers])
fi
dnl Checks for header files.
AC_HEADER_DIRENT
AC_HEADER_STDC
AC_CHECK_HEADERS(fcntl.h sys/ioctl.h sys/time.h unistd.h sys/io.h errno.h)
AC_CHECK_HEADERS(limits.h kvm.h sys/param.h sys/dkstat.h stdbool.h)
dnl check sys/sysctl.h seperately, as it requires other headers on at least OpenBSD
AC_CHECK_HEADERS([sys/sysctl.h], [], [],
[[#if HAVE_SYS_PARAM_H
# include <sys/param.h>
#endif
]])
dnl On FreeBSD >= 8 checking sys/pcpu.h fails without sys/param.h and kvm.h
AC_CHECK_HEADERS([sys/pcpu.h], [], [],
[[#if HAVE_SYS_PARAM_H
# include <sys/param.h>
#endif
#if HAVE_KVM_H
# include <kvm.h>
#endif
]])
dnl Check for particular preprocessor macros
LCD_SA_RESTART
dnl Checks for typedefs, structures, and compiler characteristics.
AC_C_CONST
AC_C_INLINE
AC_TYPE_SIZE_T
AC_HEADER_TIME
AC_STRUCT_TM
AC_TYPE_UID_T
dnl Checks for library functions.
AC_PROG_GCC_TRADITIONAL
AC_TYPE_SIGNAL
AC_CHECK_FUNCS(select socket strdup strerror strtol uname cfmakeraw snprintf)
dnl Many people on non-GNU/Linux systems don't have getopt
AC_CONFIG_LIBOBJ_DIR(shared)
AC_CHECK_FUNC(getopt,
[
AC_ARG_WITH(included-getopt,
[AS_HELP_STRING([--with-included-getopt], [Use the included getopt rather than glibc's])],
with_getopt=$withval,
with_getopt=$no)
if test "x$with_getopt" = xyes; then
AC_LIBOBJ(getopt)
AC_LIBOBJ(getopt1)
fi
],
[
AC_LIBOBJ(getopt)
AC_LIBOBJ(getopt1)
])
dnl Check how to find the mtab file and how to get filesystem staticstics
AC_FIND_MTAB_FILE
AC_GET_FS_INFO
dnl Check for various defines and features
AC_ARG_WITH(lcdport,
[AS_HELP_STRING([--with-lcdport=<port>], [the server port [13666]])],
LCDPORT=$withval,
LCDPORT="13666"
)
AC_DEFINE_UNQUOTED(LCDPORT, $LCDPORT, [Set default port where LCDd should listen])
AC_DEFINE_UNQUOTED(PROTOCOL_VERSION, "0.3", [Define version of lcdproc client-server protocol])
AC_DEFINE_UNQUOTED(API_VERSION, "0.5", [Define version of lcdproc API])
dnl Check compiler flags to dynamically load modules
AC_MODULES_INFO
dnl ######################################################################
dnl libusb support
dnl ######################################################################
AC_MSG_CHECKING([if libusb support has been enabled]);
AC_ARG_ENABLE(libusb,
[AS_HELP_STRING([--disable-libusb],[disable USB support using libusb])],
[ if test "$enableval" != "no"; then
enable_libusb=yes
fi ],
[ enable_libusb=yes ]
)
AC_MSG_RESULT($enable_libusb)
if test "$enable_libusb" = "yes"; then
ifdef([PKG_CHECK_MODULES],
[PKG_CHECK_MODULES(LIBUSB, libusb,
[AC_DEFINE(HAVE_LIBUSB, [1], [Define to 1 if you have libusb])],
[ enable_libusb=no ])],
[AC_MSG_WARN([pkg-config not (fully) installed; drivers requiring libusb may not be built])])
fi
AC_SUBST(LIBUSB_LIBS)
AC_SUBST(LIBUSB_CFLAGS)
dnl ######################################################################
dnl libusb-1.0 support
dnl ######################################################################
AC_MSG_CHECKING([if libusb-1-0 support has been enabled]);
AC_ARG_ENABLE(libusb_1_0,
[AS_HELP_STRING([--disable-libusb-1-0],[disable USB support using libusb-1.0])],
[ if test "$enableval" != "no"; then
enable_libusb_1_0="yes"
fi ],
[ enable_libusb_1_0=yes ]
)
AC_MSG_RESULT($enable_libusb_1_0)
if test "$enable_libusb_1_0" = "yes"; then
ifdef([PKG_CHECK_MODULES],
[PKG_CHECK_MODULES(LIBUSB_1_0, libusb-1.0 >= 1.0,
[AC_DEFINE(HAVE_LIBUSB_1_0, [1], [Define to 1 if you have libusb-1.0])],
[ enable_libusb_1_0=no ])],
[AC_MSG_WARN([pkg-config not (fully) installed; drivers requiring libusb-1.0 may not be built])])
fi
AC_SUBST(LIBUSB_1_0_LIBS)
AC_SUBST(LIBUSB_1_0_CFLAGS)
dnl ######################################################################
dnl libftdi support
dnl ######################################################################
AC_MSG_CHECKING([if libftdi support has been enabled]);
AC_ARG_ENABLE(libftdi,
[AS_HELP_STRING([--disable-libftdi],[disable FTDI support using libftdi])],
[ if test "$enableval" != "no"; then
enable_libftdi=yes
fi ],
[ enable_libftdi=yes ]
)
AC_MSG_RESULT($enable_libftdi)
if test "$enable_libftdi" = "yes"; then
ifdef([PKG_CHECK_MODULES],
[PKG_CHECK_MODULES(LIBFTDI, libftdi >= 0.8,
[AC_DEFINE(HAVE_LIBFTDI, [1], [Define to 1 if you have libftdi])],
[ enable_libftdi=no ])],
[AC_MSG_WARN([pkg-config not (fully) installed; drivers requiring libftdi may not be built])])
fi
AC_SUBST(LIBFTDI_LIBS)
AC_SUBST(LIBFTDI_CFLAGS)
dnl ######################################################################
dnl X11 library support
dnl ######################################################################
AC_MSG_CHECKING([if X11 support has been enabled]);
AC_ARG_ENABLE(libX11,
[AS_HELP_STRING([--disable-libX11],[disable X11 support])],
[ if test "$enableval" != "no"; then
enable_libX11=yes
fi ],
[ enable_libX11=yes ]
)
AC_MSG_RESULT($enable_libX11)
if test "$enable_libX11" = "yes"; then
ifdef([PKG_CHECK_MODULES],
[PKG_CHECK_MODULES([LIBX11], [x11],
[AC_DEFINE(HAVE_LIBX11, [1], [Define to 1 if you have X11 library])],
[ enable_libX11=no ])],
[AC_MSG_WARN([pkg-config not (fully) installed; drivers requiring X11 may not be built])])
fi
AC_SUBST(LIBX11_LIBS)
AC_SUBST(LIBX11_CFLAGS)
dnl ######################################################################
dnl libhid support
dnl ######################################################################
AC_MSG_CHECKING([if libhid support has been enabled]);
AC_ARG_ENABLE(libhid,
[AS_HELP_STRING([--disable-libhid],[disable HID support using libhid])],
[ if test "$enableval" != "no"; then
enable_libhid=yes
fi ],
[ enable_libhid=yes ]
)
AC_MSG_RESULT($enable_libhid)
if test "$enable_libhid" = "yes"; then
ifdef([PKG_CHECK_MODULES],
[PKG_CHECK_MODULES(LIBHID, libhid >= 0.2.16,
[AC_DEFINE(HAVE_LIBHID, [1], [Define to 1 if you have libhid])],
[ enable_libhid=no ])],
[AC_MSG_WARN([pkg-config not (fully) installed; drivers requiring libhid may not be built])])
fi
AC_SUBST(LIBHID_LIBS)
AC_SUBST(LIBHID_CFLAGS)
# PNG library
LCD_PNG_LIB
dnl ######################################################################
dnl freetype support
dnl ######################################################################
AC_MSG_CHECKING([if freetype support has been enabled]);
AC_ARG_ENABLE(freetype,
[AS_HELP_STRING([--disable-freetype],[disable freetype support])],
[ if test "$enableval" != "no"; then
enable_freetype=yes
fi ],
[ enable_freetype=yes ]
)
AC_MSG_RESULT($enable_freetype)
if test "$enable_freetype" = "yes"; then
ifdef([AC_CHECK_FT2],
[AC_CHECK_FT2([],
[AC_DEFINE(HAVE_FT2, [1], [Define to 1 if you have freetype])],
[enable_freetype=no])],
[AC_MSG_WARN([freetype does not seem to be installed])])
fi
AC_SUBST([FT2_CFLAGS])
AC_SUBST([FT2_LIBS])
dnl ######################################################################
dnl ethlcd support
dnl ######################################################################
AC_MSG_CHECKING([if ethlcd support has been enabled]);
AC_ARG_ENABLE(ethlcd,
[AS_HELP_STRING([--disable-ethlcd],[disable ethlcd connection type for HD44780])],
[ if test "$enableval" != "no"; then
enable_ethlcd=yes
fi ],
[ enable_ethlcd=yes ]
)
AC_MSG_RESULT($enable_ethlcd)
# check for doxygen
BB_ENABLE_DOXYGEN
# Select drivers to build
LCD_DRIVERS_SELECT
# directory for PID files
pidfiledir=/var/run
# make sure the directory exists
if test ! -d $pidfiledir ; then
pidfiledir=`eval echo ${sysconfdir}`
case $pidfiledir in
NONE/*) pidfiledir=`echo $pidfiledir | sed "s~NONE~$ac_default_prefix~"` ;;
esac
fi
AC_ARG_WITH(pidfile-dir,
[AS_HELP_STRING([--with-pidfile-dir=PATH], [specify location of pid files [/var/run]])],
[ if test -n "$withval" && test "x$withval" != "xno" && \
test "x${withval}" != "xyes"; then
pidfiledir=$withval
if test ! -d $pidfiledir ; then
AC_MSG_WARN([** no $pidfiledir directory on this system **])
fi
fi ]
)
AC_SUBST(pidfiledir)
# Features applicable to the server
AC_ARG_ENABLE(seamless-hbars,
[AS_HELP_STRING([--enable-seamless-hbars], [no gaps in horizontal bar graphs (if HW supports it)])],
[ if test "$enableval" != "no" ; then
AC_DEFINE(SEAMLESS_HBARS, [1],
[Define to 1 to avoid gaps in horizontal bar graphs (if HW supports it)])
fi ]
)
AC_ARG_ENABLE(testmenus,
[AS_HELP_STRING([--enable-testmenus], [enable server test menus])],
[ if test "$enableval" != "no" ; then
AC_DEFINE(LCDPROC_TESTMENUS, [1],
[Define to 1 to enable server test menus])
fi ]
)
AC_ARG_ENABLE(permissive_menu_goto,
[AS_HELP_STRING([--enable-permissive-menu-goto], [allow transitions between different client's menus])],
[ if test "$enableval" != "no" ; then
AC_DEFINE(LCDPROC_PERMISSIVE_MENU_GOTO, [1],
[Define to 1 to allow transitions between different client's menus])
fi ]
)
dnl Features applicable to the lcdproc client
AC_ARG_ENABLE(lcdproc-menus,
[AS_HELP_STRING([--enable-lcdproc-menus], [enable menu support in lcdproc client])],
[ if test "$enableval" != "no" ; then
AC_DEFINE(LCDPROC_MENUS, [1],
[Define to 1 to enable menu support in lcdproc client])
fi ]
)
AC_ARG_ENABLE(stat-nfs,
[AS_HELP_STRING([--enable-stat-nfs], [display NFS filesystem stats in lcdproc client])],
[ if test "$enableval" != "no" ; then
AC_DEFINE(STAT_NFS, [1],
[Define to 1 to display NFS filesystem stats in lcdproc client])
fi ]
)
AC_ARG_ENABLE(stat-smbfs,
[AS_HELP_STRING([--enable-stat-smbfs], [display SMBFS filesystem stats in lcdproc client])],
[ if test "$enableval" != "no" ; then
AC_DEFINE(STAT_SMBFS, [1],
[Define to 1 to display SMBFS filesystem stats in lcdproc client])
fi ]
)
AC_ARG_ENABLE(extra-charmaps,
[AS_HELP_STRING([--enable-extra-charmaps],
[enable additional character mapping tables in drivers])],
[ if test "$enableval" != "no" ; then
AC_DEFINE(EXTRA_CHARMAPS, [1],
[Define to 1 to enable additional charmaps in drivers])
fi ]
)
AC_CONFIG_FILES([Makefile
shared/Makefile
server/Makefile
server/commands/Makefile
server/drivers/Makefile
clients/Makefile
clients/lcdproc/Makefile
clients/lcdexec/Makefile
clients/lcdvc/Makefile
clients/examples/Makefile
clients/metar/Makefile
docs/Makefile
docs/Doxyfile
docs/lcdproc-dev/Makefile
docs/lcdproc-user/Makefile
docs/lcdproc-user/drivers/Makefile
scripts/Makefile
scripts/init-LCDd.LSB
scripts/init-lcdproc.LSB
scripts/init-lcdexec.LSB
scripts/init-lcdvc.LSB
scripts/init-LCDd.debian
scripts/init-lcdproc.debian
scripts/init-lcdexec.debian
scripts/init-lcdvc.debian
scripts/init-LCDd.rpm
scripts/init-lcdproc.rpm])
AC_OUTPUT
-21
View File
@@ -1,21 +0,0 @@
CFLAGS=-Wall -g -MD
LDFLAGS=
CC=gcc
TARGET = if_demo
MEMBERS=${TARGET} lib-myconnect lib-mylcd interface af sockets nstrcmp util hw unix inet loopback ether tunnel ppp frame arcnet
DEPS = $(patsubst %,%.d,$(MEMBERS))
OBJECTS = $(patsubst %,%.o,$(MEMBERS))
all: ${TARGET}
${TARGET}: ${OBJECTS}
${CC} -o ${TARGET} ${OBJECTS} ${CFLAGS} ${LDFLAGS}
clean:
rm *.o *.d ${TARGET}
-include ${DEPS}
-16
View File
@@ -1,16 +0,0 @@
From: Thomas Riewe <thomas.riewe@pyramid.de>
may be someone else will find our little testing setup also helpful ?!
i attached it to this mail (since it's just 28K though i didn't clean up the files ...)
and one can download it from the "Test/demo" link at
http://www.pyramid.de/en/products/programmable_lcd.php
respectively
http://www.pyramid.de/upload/files/divers/demo_for_pylcd-lcdproc.tgz
AFAIK it will be quite easy to adapt it to other LCDs
HTH & keep up the good work
regards,
thomas
-345
View File
@@ -1,345 +0,0 @@
/*
* lib/af.c This file contains the top-level part of the protocol
* support functions module for the NET-2 base distribution.
*
* Version: $Id$
*
* Author: Fred N. van Kempen, <waltje@uwalt.nl.mugnet.org>
* Copyright 1993 MicroWalt Corporation
*
* 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.
*/
#include <sys/types.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <ctype.h>
#include <string.h>
#include <unistd.h>
#include "config.h"
#include "net-support.h"
#include "pathnames.h"
#include "intl.h"
#include "util.h"
int flag_unx;
int flag_ipx;
int flag_ax25;
int flag_ddp;
int flag_netrom;
int flag_inet;
int flag_inet6;
int flag_econet;
int flag_x25 = 0;
int flag_ash;
struct aftrans_t {
char *alias;
char *name;
int *flag;
} aftrans[] = {
{
"ax25", "ax25", &flag_ax25
},
{
"ip", "inet", &flag_inet
},
{
"ip6", "inet6", &flag_inet6
},
{
"ipx", "ipx", &flag_ipx
},
{
"appletalk", "ddp", &flag_ddp
},
{
"netrom", "netrom", &flag_netrom
},
{
"inet", "inet", &flag_inet
},
{
"inet6", "inet6", &flag_inet6
},
{
"ddp", "ddp", &flag_ddp
},
{
"unix", "unix", &flag_unx
},
{
"tcpip", "inet", &flag_inet
},
{
"econet", "ec", &flag_econet
},
{
"x25", "x25", &flag_x25
},
{
"ash", "ash", &flag_ash
},
{
0, 0, 0
}
};
char afname[256] = "";
extern struct aftype unspec_aftype;
extern struct aftype unix_aftype;
extern struct aftype inet_aftype;
extern struct aftype inet6_aftype;
extern struct aftype ax25_aftype;
extern struct aftype netrom_aftype;
extern struct aftype ipx_aftype;
extern struct aftype ddp_aftype;
extern struct aftype ec_aftype;
extern struct aftype x25_aftype;
extern struct aftype rose_aftype;
extern struct aftype ash_aftype;
static short sVafinit = 0;
struct aftype *aftypes[] =
{
#if HAVE_AFUNIX
&unix_aftype,
#endif
#if HAVE_AFINET
&inet_aftype,
#endif
#if HAVE_AFINET6
&inet6_aftype,
#endif
#if HAVE_AFAX25
&ax25_aftype,
#endif
#if HAVE_AFNETROM
&netrom_aftype,
#endif
#if HAVE_AFROSE
&rose_aftype,
#endif
#if HAVE_AFIPX
&ipx_aftype,
#endif
#if HAVE_AFATALK
&ddp_aftype,
#endif
#if HAVE_AFECONET
&ec_aftype,
#endif
#if HAVE_AFASH
&ash_aftype,
#endif
#if HAVE_AFX25
&x25_aftype,
#endif
&unspec_aftype,
NULL
};
void afinit()
{
unspec_aftype.title = _("UNSPEC");
#if HAVE_AFUNIX
unix_aftype.title = _("UNIX Domain");
#endif
#if HAVE_AFINET
inet_aftype.title = _("DARPA Internet");
#endif
#if HAVE_AFINET6
inet6_aftype.title = _("IPv6");
#endif
#if HAVE_AFAX25
ax25_aftype.title = _("AMPR AX.25");
#endif
#if HAVE_AFNETROM
netrom_aftype.title = _("AMPR NET/ROM");
#endif
#if HAVE_AFIPX
ipx_aftype.title = _("Novell IPX");
#endif
#if HAVE_AFATALK
ddp_aftype.title = _("Appletalk DDP");
#endif
#if HAVE_AFECONET
ec_aftype.title = _("Econet");
#endif
#if HAVE_AFX25
x25_aftype.title = _("CCITT X.25");
#endif
#if HAVE_AFROSE
rose_aftype.title = _("AMPR ROSE");
#endif
#if HAVE_AFASH
ash_aftype.title = _("Ash");
#endif
sVafinit = 1;
}
/* set the default AF list from the program name or a constant value */
void aftrans_def(char *tool, char *argv0, char *dflt)
{
char *tmp;
char *buf;
strcpy(afname, dflt);
if (!(tmp = strrchr(argv0, '/')))
tmp = argv0; /* no slash?! */
else
tmp++;
if (!(buf = strdup(tmp)))
return;
if (strlen(tool) >= strlen(tmp)) {
free(buf);
return;
}
tmp = buf + (strlen(tmp) - strlen(tool));
if (strcmp(tmp, tool) != 0) {
free(buf);
return;
}
*tmp = '\0';
if ((tmp = strchr(buf, '_')))
*tmp = '\0';
afname[0] = '\0';
if (aftrans_opt(buf))
strcpy(afname, buf);
free(buf);
}
/* Check our protocol family table for this family. */
struct aftype *get_aftype(const char *name)
{
struct aftype **afp;
if (!sVafinit)
afinit();
afp = aftypes;
while (*afp != NULL) {
if (!strcmp((*afp)->name, name))
return (*afp);
afp++;
}
if (index(name, ','))
fprintf(stderr, _("Please don't supply more than one address family.\n"));
return (NULL);
}
/* Check our protocol family table for this family. */
struct aftype *get_afntype(int af)
{
struct aftype **afp;
if (!sVafinit)
afinit();
afp = aftypes;
while (*afp != NULL) {
if ((*afp)->af == af)
return (*afp);
afp++;
}
return (NULL);
}
/* Check our protocol family table for this family and return its socket */
int get_socket_for_af(int af)
{
struct aftype **afp;
if (!sVafinit)
afinit();
afp = aftypes;
while (*afp != NULL) {
if ((*afp)->af == af)
return (*afp)->fd;
afp++;
}
return -1;
}
int aftrans_opt(const char *arg)
{
struct aftrans_t *paft;
char *tmp1, *tmp2;
char buf[256];
safe_strncpy(buf, arg, sizeof(buf));
tmp1 = buf;
while (tmp1) {
tmp2 = index(tmp1, ',');
if (tmp2)
*(tmp2++) = '\0';
paft = aftrans;
for (paft = aftrans; paft->alias; paft++) {
if (strcmp(tmp1, paft->alias))
continue;
if (strlen(paft->name) + strlen(afname) + 1 >= sizeof(afname)) {
fprintf(stderr, _("Too much address family arguments.\n"));
return (0);
}
if (paft->flag)
(*paft->flag)++;
if (afname[0])
strcat(afname, ",");
strcat(afname, paft->name);
break;
}
if (!paft->alias) {
fprintf(stderr, _("Unknown address family `%s'.\n"), tmp1);
return (1);
}
tmp1 = tmp2;
}
return (0);
}
/* type: 0=all, 1=getroute */
void print_aflist(int type) {
int count = 0;
char * txt;
struct aftype **afp;
if (!sVafinit)
afinit();
afp = aftypes;
while (*afp != NULL) {
if ((type == 1 && ((*afp)->rprint == NULL)) || ((*afp)->af == 0)) {
afp++; continue;
}
if ((count % 3) == 0) fprintf(stderr,count?"\n ":" ");
txt = (*afp)->name; if (!txt) txt = "..";
fprintf(stderr,"%s (%s) ",txt,(*afp)->title);
count++;
afp++;
}
fprintf(stderr,"\n");
}
-129
View File
@@ -1,129 +0,0 @@
/*
* lib/arcnet.c This file contains an implementation of the "ARCnet"
* support functions for the NET-2 base distribution.
*
* Version: $Id$
*
* Author: Fred N. van Kempen, <waltje@uwalt.nl.mugnet.org>
* Copyright 1993 MicroWalt Corporation
*
* 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.
*/
#include "config.h"
#if HAVE_HWARC
#include <sys/types.h>
#include <sys/socket.h>
#include <net/if_arp.h>
#include <linux/if_ether.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <ctype.h>
#include <string.h>
#include <unistd.h>
#include "net-support.h"
#include "pathnames.h"
#include "intl.h"
#include "util.h"
extern struct hwtype arcnet_hwtype;
/* Display an ARCnet address in readable format. */
static char *pr_arcnet(unsigned char *ptr)
{
static char buff[64];
snprintf(buff, sizeof(buff), "%02X", (ptr[0] & 0377));
return (buff);
}
/* Input an ARCnet address and convert to binary. */
static int in_arcnet(char *bufp, struct sockaddr *sap)
{
unsigned char *ptr;
char c, *orig;
int i, val;
sap->sa_family = arcnet_hwtype.type;
ptr = sap->sa_data;
i = 0;
orig = bufp;
while ((*bufp != '\0') && (i < 1)) {
val = 0;
c = *bufp++;
if (isdigit(c))
val = c - '0';
else if (c >= 'a' && c <= 'f')
val = c - 'a' + 10;
else if (c >= 'A' && c <= 'F')
val = c - 'A' + 10;
else {
#ifdef DEBUG
fprintf(stderr, _("in_arcnet(%s): invalid arcnet address!\n"), orig);
#endif
errno = EINVAL;
return (-1);
}
val <<= 4;
c = *bufp++;
if (isdigit(c))
val |= c - '0';
else if (c >= 'a' && c <= 'f')
val |= c - 'a' + 10;
else if (c >= 'A' && c <= 'F')
val |= c - 'A' + 10;
else {
#ifdef DEBUG
fprintf(stderr, _("in_arcnet(%s): invalid arcnet address!\n"), orig);
#endif
errno = EINVAL;
return (-1);
}
*ptr++ = (unsigned char) (val & 0377);
i++;
/* We might get a semicolon here - not required. */
if (*bufp == ':') {
if (i == ETH_ALEN) {
#ifdef DEBUG
fprintf(stderr, _("in_arcnet(%s): trailing : ignored!\n"),
orig)
#endif
; /* nothing */
}
bufp++;
}
}
/* That's it. Any trailing junk? */
if ((i == ETH_ALEN) && (*bufp != '\0')) {
#ifdef DEBUG
fprintf(stderr, _("in_arcnet(%s): trailing junk!\n"), orig);
errno = EINVAL;
return (-1);
#endif
}
#ifdef DEBUG
fprintf(stderr, "in_arcnet(%s): %s\n", orig, pr_arcnet(sap->sa_data));
#endif
return (0);
}
struct hwtype arcnet_hwtype =
{
"arcnet", NULL, /*"2.5Mbps ARCnet", */ ARPHRD_ARCNET, 1,
pr_arcnet, in_arcnet, NULL
};
#endif /* HAVE_HWARC */
-76
View File
@@ -1,76 +0,0 @@
/*
* config.h Automatically generated configuration includefile
*
* NET-TOOLS A collection of programs that form the base set of the
* NET-3 Networking Distribution for the LINUX operating
* system.
*
* DO NOT EDIT DIRECTLY
*
*/
/*
*
* Internationalization
*
* The net-tools package has currently been translated to French,
* German and Brazilian Portugese. Other translations are, of
* course, welcome. Answer `n' here if you have no support for
* internationalization on your system.
*
*/
#define I18N 0
/*
*
* Protocol Families.
*
*/
#define HAVE_AFUNIX 1
#define HAVE_AFINET 1
#define HAVE_AFINET6 0
#define HAVE_AFIPX 0
#define HAVE_AFATALK 0
#define HAVE_AFAX25 0
#define HAVE_AFNETROM 0
#define HAVE_AFROSE 0
#define HAVE_AFX25 0
#define HAVE_AFECONET 0
#define HAVE_AFDECnet 0
#define HAVE_AFASH 0
/*
*
* Device Hardware types.
*
*/
#define HAVE_HWETHER 1
#define HAVE_HWARC 1
#define HAVE_HWSLIP 0
#define HAVE_HWPPP 1
#define HAVE_HWTUNNEL 1
#define HAVE_HWSTRIP 0
#define HAVE_HWTR 0
#define HAVE_HWAX25 0
#define HAVE_HWROSE 0
#define HAVE_HWNETROM 0
#define HAVE_HWX25 0
#define HAVE_HWFR 1
#define HAVE_HWSIT 0
#define HAVE_HWFDDI 0
#define HAVE_HWHIPPI 0
#define HAVE_HWASH 0
#define HAVE_HWHDLCLAPB 0
#define HAVE_HWIRDA 0
#define HAVE_HWEC 0
#define HAVE_HWEUI64 0
/*
*
* Other Features.
*
*/
#define HAVE_FW_MASQUERADE 0
#define HAVE_IP_TOOLS 0
#define HAVE_MII 0
-137
View File
@@ -1,137 +0,0 @@
/*
* lib/ether.c This file contains an implementation of the "Ethernet"
* support functions.
*
* Version: $Id$
*
* Author: Fred N. van Kempen, <waltje@uwalt.nl.mugnet.org>
* Copyright 1993 MicroWalt Corporation
*
* 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.
*/
#include "config.h"
#if HAVE_HWETHER
#include <sys/types.h>
#include <sys/socket.h>
#include <net/if_arp.h>
#include <linux/if_ether.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <ctype.h>
#include <string.h>
#include <unistd.h>
#include "net-support.h"
#include "pathnames.h"
#include "intl.h"
#include "util.h"
extern struct hwtype ether_hwtype;
/* Display an Ethernet address in readable format. */
static char *pr_ether(unsigned char *ptr)
{
static char buff[64];
snprintf(buff, sizeof(buff), "%02X:%02X:%02X:%02X:%02X:%02X",
(ptr[0] & 0377), (ptr[1] & 0377), (ptr[2] & 0377),
(ptr[3] & 0377), (ptr[4] & 0377), (ptr[5] & 0377)
);
return (buff);
}
/* Input an Ethernet address and convert to binary. */
static int in_ether(char *bufp, struct sockaddr *sap)
{
unsigned char *ptr;
char c, *orig;
int i;
unsigned val;
sap->sa_family = ether_hwtype.type;
ptr = sap->sa_data;
i = 0;
orig = bufp;
while ((*bufp != '\0') && (i < ETH_ALEN)) {
val = 0;
c = *bufp++;
if (isdigit(c))
val = c - '0';
else if (c >= 'a' && c <= 'f')
val = c - 'a' + 10;
else if (c >= 'A' && c <= 'F')
val = c - 'A' + 10;
else {
#ifdef DEBUG
fprintf(stderr, _("in_ether(%s): invalid ether address!\n"), orig);
#endif
errno = EINVAL;
return (-1);
}
val <<= 4;
c = *bufp;
if (isdigit(c))
val |= c - '0';
else if (c >= 'a' && c <= 'f')
val |= c - 'a' + 10;
else if (c >= 'A' && c <= 'F')
val |= c - 'A' + 10;
else if (c == ':' || c == 0)
val >>= 4;
else {
#ifdef DEBUG
fprintf(stderr, _("in_ether(%s): invalid ether address!\n"), orig);
#endif
errno = EINVAL;
return (-1);
}
if (c != 0)
bufp++;
*ptr++ = (unsigned char) (val & 0377);
i++;
/* We might get a semicolon here - not required. */
if (*bufp == ':') {
if (i == ETH_ALEN) {
#ifdef DEBUG
fprintf(stderr, _("in_ether(%s): trailing : ignored!\n"),
orig)
#endif
; /* nothing */
}
bufp++;
}
}
/* That's it. Any trailing junk? */
if ((i == ETH_ALEN) && (*bufp != '\0')) {
#ifdef DEBUG
fprintf(stderr, _("in_ether(%s): trailing junk!\n"), orig);
errno = EINVAL;
return (-1);
#endif
}
#ifdef DEBUG
fprintf(stderr, "in_ether(%s): %s\n", orig, pr_ether(sap->sa_data));
#endif
return (0);
}
struct hwtype ether_hwtype =
{
"ether", NULL, /*"10Mbps Ethernet", */ ARPHRD_ETHER, ETH_ALEN,
pr_ether, in_ether, NULL
};
#endif /* HAVE_HWETHER */
-59
View File
@@ -1,59 +0,0 @@
/*
* lib/frame.c This file contains the Frame Relay support.
*
* Version: $Id$
*
* Maintainer: Bernd 'eckes' Eckenfels, <net-tools@lina.inka.de>
*
* Author: Mike McLagan <mike.mclagan@linux.org>
*
* Changes:
*
*962303 {0.01} Mike McLagan : creation
*960413 {0.02} Bernd Eckenfels : included in net-lib
*
* 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.
*/
#include "config.h"
#if HAVE_HWFR
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <net/if_arp.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>
#include "net-support.h"
#include "pathnames.h"
char *pr_dlci(unsigned char *ptr)
{
static char buf[12];
snprintf(buf, sizeof(buf), "%i", *(short *) ptr);
return (buf);
}
struct hwtype dlci_hwtype =
{
"dlci", NULL, /*"Frame Relay DLCI", */ ARPHRD_DLCI, 3,
pr_dlci, NULL, NULL, 0
};
struct hwtype frad_hwtype =
{
"frad", NULL, /*"Frame Relay Access Device", */ ARPHRD_FRAD, 0,
NULL, NULL, NULL, 0
};
#endif /* HAVE_HWFR */
-298
View File
@@ -1,298 +0,0 @@
/*
* lib/hw.c This file contains the top-level part of the hardware
* support functions module.
*
* Version: $Id$
*
* Maintainer: Bernd 'eckes' Eckenfels, <net-tools@lina.inka.de>
*
* Author: Fred N. van Kempen, <waltje@uwalt.nl.mugnet.org>
* Copyright 1993 MicroWalt Corporation
*
*980701 {1.21} Arnaldo C. Melo GNU gettext instead of catgets
*
* 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.
*/
#include <sys/types.h>
#include <sys/socket.h>
#include <net/if_arp.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <ctype.h>
#include <string.h>
#include <unistd.h>
#include "config.h"
#include "net-support.h"
#include "pathnames.h"
#include "intl.h"
extern struct hwtype unspec_hwtype;
extern struct hwtype loop_hwtype;
extern struct hwtype slip_hwtype;
extern struct hwtype cslip_hwtype;
extern struct hwtype slip6_hwtype;
extern struct hwtype cslip6_hwtype;
extern struct hwtype adaptive_hwtype;
extern struct hwtype strip_hwtype;
extern struct hwtype ether_hwtype;
extern struct hwtype fddi_hwtype;
extern struct hwtype hippi_hwtype;
extern struct hwtype tr_hwtype;
#ifdef ARPHRD_IEEE802_TR
extern struct hwtype tr_hwtype1;
#endif
extern struct hwtype ax25_hwtype;
extern struct hwtype rose_hwtype;
extern struct hwtype netrom_hwtype;
extern struct hwtype x25_hwtype;
extern struct hwtype tunnel_hwtype;
extern struct hwtype ash_hwtype;
extern struct hwtype ppp_hwtype;
extern struct hwtype arcnet_hwtype;
extern struct hwtype dlci_hwtype;
extern struct hwtype frad_hwtype;
extern struct hwtype hdlc_hwtype;
extern struct hwtype lapb_hwtype;
extern struct hwtype sit_hwtype;
extern struct hwtype irda_hwtype;
extern struct hwtype ec_hwtype;
extern struct hwtype eui64_hwtype;
static struct hwtype *hwtypes[] =
{
&loop_hwtype,
#if HAVE_HWSLIP
&slip_hwtype,
&cslip_hwtype,
&slip6_hwtype,
&cslip6_hwtype,
&adaptive_hwtype,
#endif
#if HAVE_HWSTRIP
&strip_hwtype,
#endif
#if HAVE_HWASH
&ash_hwtype,
#endif
#if HAVE_HWETHER
&ether_hwtype,
#endif
#if HAVE_HWTR
&tr_hwtype,
#ifdef ARPHRD_IEEE802_TR
&tr_hwtype1,
#endif
#endif
#if HAVE_HWAX25
&ax25_hwtype,
#endif
#if HAVE_HWNETROM
&netrom_hwtype,
#endif
#if HAVE_HWROSE
&rose_hwtype,
#endif
#if HAVE_HWTUNNEL
&tunnel_hwtype,
#endif
#if HAVE_HWPPP
&ppp_hwtype,
#endif
#if HAVE_HWHDLCLAPB
&hdlc_hwtype,
&lapb_hwtype,
#endif
#if HAVE_HWARC
&arcnet_hwtype,
#endif
#if HAVE_HWFR
&dlci_hwtype,
&frad_hwtype,
#endif
#if HAVE_HWSIT
&sit_hwtype,
#endif
#if HAVE_HWFDDI
&fddi_hwtype,
#endif
#if HAVE_HWHIPPI
&hippi_hwtype,
#endif
#if HAVE_HWIRDA
&irda_hwtype,
#endif
#if HAVE_HWEC
&ec_hwtype,
#endif
#if HAVE_HWX25
&x25_hwtype,
#endif
#if HAVE_HWEUI64
&eui64_hwtype,
#endif
&unspec_hwtype,
NULL
};
static short sVhwinit = 0;
void hwinit()
{
loop_hwtype.title = _("Local Loopback");
unspec_hwtype.title = _("UNSPEC");
#if HAVE_HWSLIP
slip_hwtype.title = _("Serial Line IP");
cslip_hwtype.title = _("VJ Serial Line IP");
slip6_hwtype.title = _("6-bit Serial Line IP");
cslip6_hwtype.title = _("VJ 6-bit Serial Line IP");
adaptive_hwtype.title = _("Adaptive Serial Line IP");
#endif
#if HAVE_HWETHER
ether_hwtype.title = _("Ethernet");
#endif
#if HAVE_HWASH
ash_hwtype.title = _("Ash");
#endif
#if HAVE_HWFDDI
fddi_hwtype.title = _("Fiber Distributed Data Interface");
#endif
#if HAVE_HWHIPPI
hippi_hwtype.title = _("HIPPI");
#endif
#if HAVE_HWAX25
ax25_hwtype.title = _("AMPR AX.25");
#endif
#if HAVE_HWROSE
rose_hwtype.title = _("AMPR ROSE");
#endif
#if HAVE_HWNETROM
netrom_hwtype.title = _("AMPR NET/ROM");
#endif
#if HAVE_HWX25
x25_hwtype.title = _("generic X.25");
#endif
#if HAVE_HWTUNNEL
tunnel_hwtype.title = _("IPIP Tunnel");
#endif
#if HAVE_HWPPP
ppp_hwtype.title = _("Point-to-Point Protocol");
#endif
#if HAVE_HWHDLCLAPB
hdlc_hwtype.title = _("(Cisco)-HDLC");
lapb_hwtype.title = _("LAPB");
#endif
#if HAVE_HWARC
arcnet_hwtype.title = _("ARCnet");
#endif
#if HAVE_HWFR
dlci_hwtype.title = _("Frame Relay DLCI");
frad_hwtype.title = _("Frame Relay Access Device");
#endif
#if HAVE_HWSIT
sit_hwtype.title = _("IPv6-in-IPv4");
#endif
#if HAVE_HWIRDA
irda_hwtype.title = _("IrLAP");
#endif
#if HAVE_HWTR
tr_hwtype.title = _("16/4 Mbps Token Ring");
#ifdef ARPHRD_IEEE802_TR
tr_hwtype1.title = _("16/4 Mbps Token Ring (New)") ;
#endif
#endif
#if HAVE_HWEC
ec_hwtype.title = _("Econet");
#endif
#if HAVE_HWEUI64
eui64_hwtype.title = _("Generic EUI-64");
#endif
sVhwinit = 1;
}
/* Check our hardware type table for this type. */
struct hwtype *get_hwtype(const char *name)
{
struct hwtype **hwp;
if (!sVhwinit)
hwinit();
hwp = hwtypes;
while (*hwp != NULL) {
if (!strcmp((*hwp)->name, name))
return (*hwp);
hwp++;
}
return (NULL);
}
/* Check our hardware type table for this type. */
struct hwtype *get_hwntype(int type)
{
struct hwtype **hwp;
if (!sVhwinit)
hwinit();
hwp = hwtypes;
while (*hwp != NULL) {
if ((*hwp)->type == type)
return (*hwp);
hwp++;
}
return (NULL);
}
/* type: 0=all, 1=ARPable */
void print_hwlist(int type) {
int count = 0;
char * txt;
struct hwtype **hwp;
if (!sVhwinit)
hwinit();
hwp = hwtypes;
while (*hwp != NULL) {
if (((type == 1) && ((*hwp)->alen == 0)) || ((*hwp)->type == -1)) {
hwp++; continue;
}
if ((count % 3) == 0) fprintf(stderr,count?"\n ":" ");
txt = (*hwp)->name; if (!txt) txt = "..";
fprintf(stderr,"%s (%s) ",txt,(*hwp)->title);
count++;
hwp++;
}
fprintf(stderr,"\n");
}
/* return 1 if address is all zeros */
int hw_null_address(struct hwtype *hw, void *ap)
{
unsigned int i;
unsigned char *address = (unsigned char *)ap;
for (i = 0; i < hw->alen; i++)
if (address[i])
return 0;
return 1;
}
-590
View File
@@ -1,590 +0,0 @@
/* if_demo.c
interfacedemo for "pyramid" LCD device.
*/
/*
Copyright (C) 2005 Silvan Marco Fin <silvan@kernelconcepts.de>
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
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
#include <string.h>
#include <netdb.h>
#include <errno.h>
#include <wait.h>
#include <net/if.h>
#include <sys/socket.h>
#include "lib-myconnect.h"
#include "lib-mylcd.h"
#include "interface.h"
#include "sockets.h"
#include "net-support.h"
#define DEBUG 0
#define SUCC_DUR 10 /* Duration in sec. how long a success-message is displayed */
/* External programs to be called. */
#define INTERFACE_SCRIPT "./scripts/MyIPSet"
#define REBOOT_SCRIPT "./scripts/MyReboot"
#define HALT_SCRIPT "./scripts/MyHalt"
/* Modes for action */
#define BLANK 0
#define UPDATE 1
#define IFSELECTED 2
#define IPCHANGED 3
#define NMCHANGED 4
#define GWCHANGED 5
#define MENULEFT 6
#define SELECT 7
struct iftype
{
char name[32];
char ip[16];
char netmask[16];
char gateway[16];
};
struct
{
unsigned int sIF;
unsigned int IFnum;
struct iftype IFdata[32];
} status;
int skfd;
void print_help()
{
printf("Usage:\n");
printf(" [-p #] specify Portnumber (defaults to 13666).\n");
printf(" -d ... specify comma separated list of devices to manage.\n");
printf("\n");
printf("Example: if_demo -d eth0,wlan0 -p 12345\n\n");
}
void init_screen(int SD)
{
char *buffer;
buffer=basic_send(SD, "hello");
buffer=basic_send(SD, "client_set -name {Managment}");
buffer=basic_send(SD, "screen_add main");
buffer=basic_send(SD, "screen_set main -name {main}");
buffer=basic_send(SD, "screen_set main -heartbeat off");
buffer=basic_send(SD, "screen_set main -priority foreground");
/* buffer=basic_send(SD, "screen_set main -duration 80"); */
/* buffer=basic_send(SD, "screen_set main -cursor on"); */
}
void alert_screen(int SD, char *line1, char *line2, int duration)
{
char *buffer;
char mesg[255];
/* buffer=basic_send(SD, "widget_del main mainscroller"); */
buffer=basic_send(SD, "screen_add info");
buffer=basic_send(SD, "screen_set info -priority alert");
sprintf(mesg, "screen_set info -timeout %d", duration);
buffer=basic_send(SD, mesg);
buffer=basic_send(SD, "widget_add info infostring1 string");
buffer=basic_send(SD, "widget_add info infostring2 string");
sprintf(mesg, "widget_set info infostring1 1 1 {%s}", line1);
buffer=basic_send(SD, mesg);
sprintf(mesg, "widget_set info infostring2 1 2 {%s}", line2);
buffer=basic_send(SD, mesg);
}
void interfaces(int SD, char *cs_iflist)
{
char *buffer;
char *retval;
char *next=cs_iflist;
char mesg[255];
unsigned int orig_len=strlen(cs_iflist);
unsigned int i=0;
/* Now we fill the interfaces to the status variable. */
while (1)
{
retval=strtok(next, ",");
next=NULL;
if (retval==NULL)
break; /* or return? */
strcpy(status.IFdata[i].name, retval);
/* If interface is up, then get it's numbers and use them, else set to default-Values */
/* Default values: */
sprintf(status.IFdata[i].ip, "000.000.000.000");
sprintf(status.IFdata[i].netmask, "255.255.255.255");
sprintf(status.IFdata[i].gateway, "000.000.000.000");
if (DEBUG)
printf("IF %s: IP=%s, NM=%s, GW=%s\n", status.IFdata[i].name, status.IFdata[i].ip, status.IFdata[i].netmask, status.IFdata[i].gateway);
sprintf(mesg, "menu_add_item SIF %d action {sel. %s} -next CHSET", i, status.IFdata[i].name);
buffer=basic_send(SD, mesg);
i++;
}
status.IFnum=i+1;
/* now prepare cs_iflist so that we can generate a menu entry. */
for (i=0; i<orig_len; i++)
if (cs_iflist[i]=='\0') cs_iflist[i]='\t';
/* sprintf(mesg, "menu_add_item SIF selection ring {IF:} -strings {%s}", cs_iflist); */ /* For use of a selection ring */
/* buffer=basic_send(SD, mesg); */
status.sIF=0;
}
void old_autointerfaces(int SD)
{
struct if_nameindex *if_list;
char buffer[1000]="";
int i;
if_list=if_nameindex();
for (i=0; if_list[i].if_name!=NULL; i++)
{
if (strcmp(if_list[i].if_name, "lo")==0)
continue;
if (strlen(buffer)==0)
sprintf(buffer, "%s", if_list[i].if_name);
else
sprintf(buffer, "%s,%s", buffer, if_list[i].if_name);
}
interfaces(SD, buffer);
}
int do_if_action(int SD, struct interface *ife, void *cookie)
{
int *opt_a = (int *) cookie;
int res;
struct aftype *ap;
static unsigned int i=0;
char mesg[255];
char *buffer;
res = do_if_fetch(ife);
if (strcmp(ife->name, "lo")==0)
return 0;
if (res >= 0) {
if ((ife->flags & IFF_UP) || *opt_a)
{
ap = get_afntype(ife->addr.sa_family);
strcpy(status.IFdata[i].name, ife->name);
if (ife->has_ip)
{
sprintf(status.IFdata[i].ip, "%s", ap->sprint(&ife->addr, 1));
sprintf(status.IFdata[i].netmask, "%s", ap->sprint(&ife->netmask, 1));
sprintf(status.IFdata[i].gateway, "%s", ap->sprint(&ife->addr, 1));
} else
{
sprintf(status.IFdata[i].ip, "000.000.000.000");
sprintf(status.IFdata[i].netmask, "255.255.255.255");
sprintf(status.IFdata[i].gateway, "000.000.000.000");
}
sprintf(mesg, "menu_add_item SIF %d action {sel. %s} -next CHSET", i, status.IFdata[i].name);
buffer=basic_send(SD, mesg);
}
}
i++;
return res;
}
void autointerfaces(int SD)
{
int res;
int opt_a=0;
/* Create a channel to the NET kernel. */
if ((skfd = sockets_open(0)) < 0) {
perror("socket");
exit(1);
}
res=for_all_interfaces(SD, do_if_action, &opt_a);
close(skfd);
}
void set_main_info(int SD, char *ifname, char *ip, char *netmask, char *gateway)
{
char *buffer;
char mesg[255];
sprintf(mesg, "widget_set main mainscroller 1 1 16 2 v 10 {%*s%*s%*s%*s%*s%*s%*s%*s}",
16, " Watching IF: ",
16, ifname,
16, " IP-Address: ",
16, ip,
16, " Netmask: ",
16, netmask,
16, " Gateway: ",
16, gateway);
buffer=basic_send(SD, mesg);
}
void CHSET_menus_add(int SD)
{
char *buffer;
char mesg[255];
sprintf(mesg, "menu_add_item CHSET CHIP ip {%s IP} -v6 false -value {%s}",
status.IFdata[status.sIF].name, status.IFdata[status.sIF].ip);
buffer=basic_send(SD, mesg);
sprintf(mesg, "menu_add_item CHSET CHNM ip {%s netmask} -v6 false -value {%s}",
status.IFdata[status.sIF].name, status.IFdata[status.sIF].netmask);
buffer=basic_send(SD, mesg);
sprintf(mesg, "menu_add_item CHSET CHGW ip {%s gateway} -v6 false -value {%s}",
status.IFdata[status.sIF].name, status.IFdata[status.sIF].gateway);
buffer=basic_send(SD, mesg);
buffer=basic_send(SD, "menu_set_item CHSET CHIP -next CHNM");
buffer=basic_send(SD, "menu_set_item CHSET CHNM -next CHGW");
set_main_info(SD, status.IFdata[status.sIF].name, status.IFdata[status.sIF].ip, status.IFdata[status.sIF].netmask, status.IFdata[status.sIF].gateway);
}
void CHSET_menus(int SD)
{
char *buffer;
char mesg[255];
sprintf(mesg, "menu_set_item CHSET CHIP -text {%s IP} -v6 false -value {%s}",
status.IFdata[status.sIF].name, status.IFdata[status.sIF].ip);
buffer=basic_send(SD, mesg);
sprintf(mesg, "menu_set_item CHSET CHNM -text {%s netmask} -v6 false -value {%s}",
status.IFdata[status.sIF].name, status.IFdata[status.sIF].netmask);
buffer=basic_send(SD, mesg);
sprintf(mesg, "menu_set_item CHSET CHGW -text {%s gateway} -v6 false -value {%s}",
status.IFdata[status.sIF].name, status.IFdata[status.sIF].gateway);
buffer=basic_send(SD, mesg);
set_main_info(SD, status.IFdata[status.sIF].name, status.IFdata[status.sIF].ip, status.IFdata[status.sIF].netmask, status.IFdata[status.sIF].gateway);
}
void action(int SD, char *input)
{
char *next=input;
char *retstr;
int len=0;
int mode=0;
int myid;
if(DEBUG)
printf("Eingabe: %s\n", input);
while (1)
{
retstr=strtok(next, " \n");
next=NULL;
if (retstr==NULL)
{
input[0]=0; /* wofür war das? */
break;
}
len+=strlen(retstr)+1;
/* key detected? */
switch (mode)
{
case BLANK:
{
if (strcmp(retstr, "update")==0) mode=UPDATE;
if (strcmp(retstr, "leave")==0) mode=MENULEFT;
if (strcmp(retstr, "select")==0) mode=SELECT;
break;
}
case UPDATE:
{
/* if (strcmp(retstr, "sIF")==0) mode=IFSELECTED; */
if (strcmp(retstr, "CHIP")==0) mode=IPCHANGED;
if (strcmp(retstr, "CHNM")==0) mode=NMCHANGED;
if (strcmp(retstr, "CHGW")==0) mode=GWCHANGED;
break;
}
case IFSELECTED:
{
status.sIF=atoi(retstr);
CHSET_menus(SD);
mode=BLANK;
break;
}
case IPCHANGED:
{
strcpy(status.IFdata[status.sIF].ip, retstr);
mode=BLANK;
break;
}
case NMCHANGED:
{
strcpy(status.IFdata[status.sIF].netmask, retstr);
mode=BLANK;
break;
}
case GWCHANGED:
{
strcpy(status.IFdata[status.sIF].gateway, retstr);
mode=BLANK;
break;
}
case MENULEFT:
{
CHSET_menus(SD);
mode=BLANK;
break;
}
case SELECT:
/* Now it gets a bit difficult: If we want to call the
external script, we have to do the fork twice of
wait for the child process (which we don't want to).
The approach ist repeated for every call to external
programm. */
{
if (strcmp(retstr, "APPLY")==0)
{
char mesg[17];
myid=fork();
switch (myid)
{
int mynewid;
case 0:
mynewid=fork();
switch (mynewid)
{
case 0: /* Child of the child */
close(SD);
execl(INTERFACE_SCRIPT,
INTERFACE_SCRIPT,
status.IFdata[status.sIF].name,
status.IFdata[status.sIF].ip,
status.IFdata[status.sIF].netmask,
status.IFdata[status.sIF].gateway,
NULL);
break;
case -1:
sprintf(mesg, "Error %d", errno);
alert_screen(SD, mesg, "during apply.", SUCC_DUR);
exit(0);
break;
default: /* At this point, the child exits and the grandchild's parent is set to "1". */
exit(0);
break;
}
break;
case -1:
sprintf(mesg, "Error %d", errno);
alert_screen(SD, mesg, "during apply.", SUCC_DUR);
break;
default:
sprintf(mesg, "for IF %s", status.IFdata[status.sIF].name);
alert_screen(SD, "Settings applied", mesg, 160);
waitpid(myid, NULL, 0); /* the child's exitstate is read, but we don't need it. */
break;
}
} else if (strcmp(retstr, "HALT")==0)
{
char mesg[17];
myid=fork();
switch (myid)
{
int mynewid;
case 0:
mynewid=fork();
switch(mynewid)
{
case 0:
close(SD);
execl(HALT_SCRIPT,
HALT_SCRIPT,
NULL);
break;
case -1:
sprintf(mesg, "Error %d", errno);
alert_screen(SD, mesg, "during halt.", SUCC_DUR);
exit(0);
break;
default:
exit(0);
break;
}
break;
case -1:
sprintf(mesg, "Error %d", errno);
alert_screen(SD, mesg, "during halt.", SUCC_DUR);
break;
default:
alert_screen(SD, "Going down for", "halt now.", 160);
waitpid(myid, NULL, 0);
break;
}
} else if (strcmp(retstr, "REBOOT")==0)
{
char mesg[17];
myid=fork();
switch (myid)
{
int mynewid;
case 0:
mynewid=fork();
switch (mynewid)
{
case 0:
close(SD);
execl(REBOOT_SCRIPT,
REBOOT_SCRIPT,
NULL);
break;
case -1:
sprintf(mesg, "Error %d", errno);
alert_screen(SD, mesg, "during reboot.", SUCC_DUR);
exit(0);
break;
default:
exit(0);
break;
}
break;
case -1:
sprintf(mesg, "Error %d", errno);
alert_screen(SD, mesg, "during reboot.", SUCC_DUR);
break;
default:
alert_screen(SD, "Going down for", "reboot now.", 160);
waitpid(myid, NULL, 0);
break;
}
} else /* Assume the Selection is a number and refers to the Index of an interface */
{
status.sIF=atoi(retstr);
CHSET_menus(SD);
}
mode=BLANK;
break;
}
}
}
return;
}
int main(int argc, char *argv[])
{
int SD;
int conn_port=13666;
int i;
int j;
char *buffer;
int starttime;
int nowtime;
int devpos=-1;
int manualif=0;
for(i = 1, j = 0; i < argc; i++)
{
if(argv[i][0] == '-')
{
switch(argv[i][1])
{
/* Port number specified */
case 'p':
{
if(argc < i + 1)
print_help();
conn_port = atoi(argv[++i]);
if(conn_port < 1 && conn_port > 0xffff)
fprintf(stderr, "Warning: Port %d outside of standard range\n", conn_port);
break;
}
/* List of devices */
case 'd':
{
devpos=i+1;
manualif=1;
break;
}
/* otherwise... Get help!*/
default:
{
print_help();
exit(0);
break;
}
}
}
}
if (manualif && devpos<1)
{
printf("No interfaces specified, exiting (use -h for usage information).\n");
close(SD);
exit(1);
}
SD=get_connection("localhost", conn_port);
if (SD<0)
exit(0);
init_screen(SD);
buffer=basic_send(SD, "menu_add_item {} SIF menu {Current IF}");
buffer=basic_send(SD, "menu_add_item {} CHSET menu {IF setting}");
if (manualif)
interfaces(SD, argv[devpos]);
else
autointerfaces(SD);
/* buffer=basic_send(SD, "menu_set_item {} SIF -next CHSET"); */ /* Doesn't work like that */
buffer=basic_send(SD, "menu_set_main {}");
/* buffer=basic_send(SD, "widget_add main maintitle title");
buffer=basic_send(SD, "widget_set main maintitle {IF-Status}"); */
buffer=basic_send(SD, "widget_add main mainscroller scroller");
buffer=basic_send(SD, "widget_set main mainscroller 1 1 16 2 v 4 {Please stand by. }");
CHSET_menus_add(SD); /* Remember to set the status.sIF to a valid value before call to CHSET_menus*() (e.g. done by interfaces()). */
buffer=basic_send(SD, "menu_add_item CHSET APPLY action {Apply settings} -next _quit_");
buffer=basic_send(SD, "menu_set_item CHSET CHGW -next APPLY");
buffer=basic_send(SD, "menu_add_item {} ASKREBOOT menu {Confirm reboot?} -is_hidden true");
buffer=basic_send(SD, "menu_add_item ASKREBOOT REBOOT action { [Yes][No]} -next _quit_");
buffer=basic_send(SD, "menu_add_item {} ASKHALT menu {Really halt?} -is_hidden true");
buffer=basic_send(SD, "menu_add_item ASKHALT HALT action { [Yes][No]} -next _quit_");
buffer=basic_send(SD, "menu_add_item {} SHUTDOWN menu {Shutdown}");
buffer=basic_send(SD, "menu_add_item SHUTDOWN DOHALT action {Halt system} -next ASKHALT");
buffer=basic_send(SD, "menu_add_item SHUTDOWN DOREBOOT action {Reboot system} -next ASKREBOOT");
starttime=time(NULL);
while (1)
{
nowtime=time(NULL);
/* sprintf(cmd, "widget_set main c0 1 2 \"%ld\"\n", nowtime-starttime); */
/* if nothing else to do, send noop, so we know for sure, that basic_send gets something to read */
/* buffer=basic_send(SD, "noop\n"); */
buffer=basic_read(SD);
action(SD, buffer);
usleep(250000);
} /* while ((nowtime-starttime)<500); */
close(SD);
return 0;
}
-451
View File
@@ -1,451 +0,0 @@
/*
* lib/inet.c This file contains an implementation of the "INET"
* support functions for the net-tools.
* (NET-3 base distribution).
*
* Version: $Id$
*
* Author: Fred N. van Kempen, <waltje@uwalt.nl.mugnet.org>
* Copyright 1993 MicroWalt Corporation
*
* Modified:
*960113 {1.21} Bernd Eckenfels : rresolve cache bug.
*960128 {1.22} Bernd Eckenfels : endian bug in print
*960203 {1.23} Bernd Eckenfels : net-features support
*960217 {1.24} Bernd Eckenfels : get_sname
*960219 {1.25} Bernd Eckenfels : extern int h_errno
*960329 {1.26} Bernd Eckenfels : resolve 255.255.255.255
*980101 {1.27} Bernd Eckenfels : resolve raw sockets in /etc/protocols
*990302 {1.28} Phil Blundell : add netmask to INET_rresolve
*991007 Kurt Garloff : rresolve, resolve: may be hosts
* <garloff@suse.de> store type (host?) in cache
*
* 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.
*/
#include "config.h"
/* FIXME. Split this file into inet4.c for the IPv4 specific parts
and inet.c for those shared between IPv4 and IPv6. */
#if HAVE_AFINET || HAVE_AFINET6
#include <netinet/in.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <arpa/nameser.h>
#include <ctype.h>
#include <errno.h>
#include <netdb.h>
#include <resolv.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include "version.h"
#include "net-support.h"
#include "pathnames.h"
#include "intl.h"
#include "util.h"
extern int h_errno; /* some netdb.h versions don't export this */
/* cache */
struct addr {
struct sockaddr_in addr;
char *name;
int host;
struct addr *next;
};
struct service {
int number;
char *name;
struct service *next;
};
static struct service *tcp_name = NULL, *udp_name = NULL, *raw_name = NULL;
#if HAVE_AFINET
static struct addr *INET_nn = NULL; /* addr-to-name cache */
static int INET_resolve(char *name, struct sockaddr_in *sin, int hostfirst)
{
struct hostent *hp;
struct netent *np;
/* Grmpf. -FvK */
sin->sin_family = AF_INET;
sin->sin_port = 0;
/* Default is special, meaning 0.0.0.0. */
if (!strcmp(name, "default")) {
sin->sin_addr.s_addr = INADDR_ANY;
return (1);
}
/* Look to see if it's a dotted quad. */
if (inet_aton(name, &sin->sin_addr)) {
return 0;
}
/* If we expect this to be a hostname, try hostname database first */
#ifdef DEBUG
if (hostfirst) fprintf (stderr, "gethostbyname (%s)\n", name);
#endif
if (hostfirst &&
(hp = gethostbyname(name)) != (struct hostent *) NULL) {
memcpy((char *) &sin->sin_addr, (char *) hp->h_addr_list[0],
sizeof(struct in_addr));
return 0;
}
/* Try the NETWORKS database to see if this is a known network. */
#ifdef DEBUG
fprintf (stderr, "getnetbyname (%s)\n", name);
#endif
if ((np = getnetbyname(name)) != (struct netent *) NULL) {
sin->sin_addr.s_addr = htonl(np->n_net);
return 1;
}
if (hostfirst) {
/* Don't try again */
errno = h_errno;
return -1;
}
#ifdef DEBUG
res_init();
_res.options |= RES_DEBUG;
#endif
#ifdef DEBUG
fprintf (stderr, "gethostbyname (%s)\n", name);
#endif
if ((hp = gethostbyname(name)) == (struct hostent *) NULL) {
errno = h_errno;
return -1;
}
memcpy((char *) &sin->sin_addr, (char *) hp->h_addr_list[0],
sizeof(struct in_addr));
return 0;
}
/* numeric: & 0x8000: default instead of *,
* & 0x4000: host instead of net,
* & 0x0fff: don't resolve
*/
static int INET_rresolve(char *name, size_t len, struct sockaddr_in *sin,
int numeric, unsigned int netmask)
{
struct hostent *ent;
struct netent *np;
struct addr *pn;
u_int32_t ad, host_ad;
int host = 0;
/* Grmpf. -FvK */
if (sin->sin_family != AF_INET) {
#ifdef DEBUG
fprintf(stderr, _("rresolve: unsupport address family %d !\n"), sin->sin_family);
#endif
errno = EAFNOSUPPORT;
return (-1);
}
ad = sin->sin_addr.s_addr;
#ifdef DEBUG
fprintf (stderr, "rresolve: %08lx, mask %08x, num %08x \n", ad, netmask, numeric);
#endif
if (ad == INADDR_ANY) {
if ((numeric & 0x0FFF) == 0) {
if (numeric & 0x8000)
safe_strncpy(name, "default", len);
else
safe_strncpy(name, "*", len);
return (0);
}
}
if (numeric & 0x0FFF) {
safe_strncpy(name, inet_ntoa(sin->sin_addr), len);
return (0);
}
if ((ad & (~netmask)) != 0 || (numeric & 0x4000))
host = 1;
#if 0
INET_nn = NULL;
#endif
pn = INET_nn;
while (pn != NULL) {
if (pn->addr.sin_addr.s_addr == ad && pn->host == host) {
safe_strncpy(name, pn->name, len);
#ifdef DEBUG
fprintf (stderr, "rresolve: found %s %08lx in cache\n", (host? "host": "net"), ad);
#endif
return (0);
}
pn = pn->next;
}
host_ad = ntohl(ad);
np = NULL;
ent = NULL;
if (host) {
#ifdef DEBUG
fprintf (stderr, "gethostbyaddr (%08lx)\n", ad);
#endif
ent = gethostbyaddr((char *) &ad, 4, AF_INET);
if (ent != NULL)
safe_strncpy(name, ent->h_name, len);
} else {
#ifdef DEBUG
fprintf (stderr, "getnetbyaddr (%08lx)\n", host_ad);
#endif
np = getnetbyaddr(host_ad, AF_INET);
if (np != NULL)
safe_strncpy(name, np->n_name, len);
}
if ((ent == NULL) && (np == NULL))
safe_strncpy(name, inet_ntoa(sin->sin_addr), len);
pn = (struct addr *) malloc(sizeof(struct addr));
pn->addr = *sin;
pn->next = INET_nn;
pn->host = host;
pn->name = (char *) malloc(strlen(name) + 1);
strcpy(pn->name, name);
INET_nn = pn;
return (0);
}
static void INET_reserror(char *text)
{
herror(text);
}
/* Display an Internet socket address. */
static char *INET_print(unsigned char *ptr)
{
return (inet_ntoa((*(struct in_addr *) ptr)));
}
/* Display an Internet socket address. */
static char *INET_sprint(struct sockaddr *sap, int numeric)
{
static char buff[128];
if (sap->sa_family == 0xFFFF || sap->sa_family == 0)
return safe_strncpy(buff, _("[NONE SET]"), sizeof(buff));
if (INET_rresolve(buff, sizeof(buff), (struct sockaddr_in *) sap,
numeric, 0xffffff00) != 0)
return (NULL);
return (buff);
}
char *INET_sprintmask(struct sockaddr *sap, int numeric,
unsigned int netmask)
{
static char buff[128];
if (sap->sa_family == 0xFFFF || sap->sa_family == 0)
return safe_strncpy(buff, _("[NONE SET]"), sizeof(buff));
if (INET_rresolve(buff, sizeof(buff), (struct sockaddr_in *) sap,
numeric, netmask) != 0)
return (NULL);
return (buff);
}
static int INET_getsock(char *bufp, struct sockaddr *sap)
{
char *sp = bufp, *bp;
unsigned int i;
unsigned val;
struct sockaddr_in *sin;
sin = (struct sockaddr_in *) sap;
sin->sin_family = AF_INET;
sin->sin_port = 0;
val = 0;
bp = (char *) &val;
for (i = 0; i < sizeof(sin->sin_addr.s_addr); i++) {
*sp = toupper(*sp);
if ((*sp >= 'A') && (*sp <= 'F'))
bp[i] |= (int) (*sp - 'A') + 10;
else if ((*sp >= '0') && (*sp <= '9'))
bp[i] |= (int) (*sp - '0');
else
return (-1);
bp[i] <<= 4;
sp++;
*sp = toupper(*sp);
if ((*sp >= 'A') && (*sp <= 'F'))
bp[i] |= (int) (*sp - 'A') + 10;
else if ((*sp >= '0') && (*sp <= '9'))
bp[i] |= (int) (*sp - '0');
else
return (-1);
sp++;
}
sin->sin_addr.s_addr = htonl(val);
return (sp - bufp);
}
static int INET_input(int type, char *bufp, struct sockaddr *sap)
{
switch (type) {
case 1:
return (INET_getsock(bufp, sap));
case 256:
return (INET_resolve(bufp, (struct sockaddr_in *) sap, 1));
default:
return (INET_resolve(bufp, (struct sockaddr_in *) sap, 0));
}
}
static int INET_getnetmask(char *adr, struct sockaddr *m, char *name)
{
struct sockaddr_in *mask = (struct sockaddr_in *) m;
char *slash, *end;
int prefix;
if ((slash = strchr(adr, '/')) == NULL)
return 0;
*slash++ = '\0';
prefix = strtoul(slash, &end, 0);
if (*end != '\0')
return -1;
if (name) {
sprintf(name, "/%d", prefix);
}
mask->sin_family = AF_INET;
mask->sin_addr.s_addr = htonl(~(0xffffffffU >> prefix));
return 1;
}
struct aftype inet_aftype =
{
"inet", NULL, /*"DARPA Internet", */ AF_INET, sizeof(unsigned long),
INET_print, INET_sprint, INET_input, INET_reserror,
NULL /*INET_rprint */ , NULL /*INET_rinput */ ,
INET_getnetmask,
-1,
NULL
};
#endif /* HAVE_AFINET */
static void add2list(struct service **namebase, struct service *item)
{
if (*namebase == NULL) {
*namebase = item;
item->next = NULL;
} else {
item->next = *namebase;
*namebase = item;
}
}
static struct service *searchlist(struct service *servicebase, int number)
{
struct service *item;
for (item = servicebase; item != NULL; item = item->next) {
if (item->number == number)
return (item);
}
return (NULL);
}
static int read_services(void)
{
struct servent *se;
struct protoent *pe;
struct service *item;
setservent(1);
while ((se = getservent())) {
/* Allocate a service entry. */
item = (struct service *) malloc(sizeof(struct service));
if (item == NULL)
perror("netstat");
item->name = strdup(se->s_name);
item->number = se->s_port;
/* Fill it in. */
if (!strcmp(se->s_proto, "tcp")) {
add2list(&tcp_name, item);
} else if (!strcmp(se->s_proto, "udp")) {
add2list(&udp_name, item);
} else if (!strcmp(se->s_proto, "raw")) {
add2list(&raw_name, item);
}
}
endservent();
setprotoent(1);
while ((pe = getprotoent())) {
/* Allocate a service entry. */
item = (struct service *) malloc(sizeof(struct service));
if (item == NULL)
perror("netstat");
item->name = strdup(pe->p_name);
item->number = htons(pe->p_proto);
add2list(&raw_name, item);
}
endprotoent();
return (0);
}
char *get_sname(int socknumber, char *proto, int numeric)
{
static char buffer[64], init = 0;
struct service *item;
if (socknumber == 0)
return ("*");
if (numeric) {
sprintf(buffer, "%d", ntohs(socknumber));
return (buffer);
}
if (!init) {
(void) read_services();
init = 1;
}
buffer[0] = '\0';
if (!strcmp(proto, "tcp")) {
if ((item = searchlist(tcp_name, socknumber)) != NULL)
sprintf(buffer, "%s", item->name);
} else if (!strcmp(proto, "udp")) {
if ((item = searchlist(udp_name, socknumber)) != NULL)
sprintf(buffer, "%s", item->name);
} else if (!strcmp(proto, "raw")) {
if ((item = searchlist(raw_name, socknumber)) != NULL)
sprintf(buffer, "%s", item->name);
}
if (!buffer[0])
sprintf(buffer, "%d", ntohs(socknumber));
return (buffer);
}
#endif /* HAVE_AFINET || HAVE_AFINET6 */
-935
View File
@@ -1,935 +0,0 @@
/* Code to manipulate interface information, shared between ifconfig and
netstat.
10/1998 partly rewriten by Andi Kleen to support an interface list.
I don't claim that the list operations are efficient @).
8/2000 Andi Kleen make the list operations a bit more efficient.
People are crazy enough to use thousands of aliases now.
*/
#include "config.h"
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <netinet/in.h>
#include <net/if.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <ctype.h>
#include <string.h>
#if HAVE_AFIPX
#if (__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1)
#include <netipx/ipx.h>
#else
#include "ipx.h"
#endif
#endif
#if HAVE_AFECONET
#include <neteconet/ec.h>
#endif
#ifdef HAVE_HWSLIP
#include <linux/if_slip.h>
#include <net/if_arp.h>
#endif
#include "net-support.h"
#include "pathnames.h"
#include "version.h"
#include "proc.h"
#include "interface.h"
#include "sockets.h"
#include "util.h"
#include "intl.h"
#ifdef IFF_PORTSEL
const char *if_port_text[][4] =
{
/* Keep in step with <linux/netdevice.h> */
{"unknown", NULL, NULL, NULL},
{"10base2", "bnc", "coax", NULL},
{"10baseT", "utp", "tpe", NULL},
{"AUI", "thick", "db15", NULL},
{"100baseT", NULL, NULL, NULL},
{"100baseTX", NULL, NULL, NULL},
{"100baseFX", NULL, NULL, NULL},
{NULL, NULL, NULL, NULL},
};
#endif
#define IPV6_ADDR_ANY 0x0000U
#define IPV6_ADDR_UNICAST 0x0001U
#define IPV6_ADDR_MULTICAST 0x0002U
#define IPV6_ADDR_ANYCAST 0x0004U
#define IPV6_ADDR_LOOPBACK 0x0010U
#define IPV6_ADDR_LINKLOCAL 0x0020U
#define IPV6_ADDR_SITELOCAL 0x0040U
#define IPV6_ADDR_COMPATv4 0x0080U
#define IPV6_ADDR_SCOPE_MASK 0x00f0U
#define IPV6_ADDR_MAPPED 0x1000U
#define IPV6_ADDR_RESERVED 0x2000U /* reserved address space */
int procnetdev_vsn = 1;
int ife_short;
int if_list_all = 0; /* do we have requested the complete proc list, yet? */
static struct interface *int_list, *int_last;
static int if_readlist_proc(char *);
static struct interface *if_cache_add(char *name)
{
struct interface *ife, **nextp, *new;
if (!int_list)
int_last = NULL;
/* the cache is sorted, so if we hit a smaller if, exit */
for (ife = int_last; ife; ife = ife->prev) {
int n = nstrcmp(ife->name, name);
if (n == 0)
return ife;
if (n < 0)
break;
}
new(new);
safe_strncpy(new->name, name, IFNAMSIZ);
nextp = ife ? &ife->next : &int_list; // keep sorting
new->prev = ife;
new->next = *nextp;
if (new->next)
new->next->prev = new;
else
int_last = new;
*nextp = new;
return new;
}
struct interface *lookup_interface(char *name)
{
/* if we have read all, use it */
if (if_list_all)
return if_cache_add(name);
/* otherwise we read a limited list */
if (if_readlist_proc(name) < 0)
return NULL;
return if_cache_add(name);
}
int for_all_interfaces(int SD, int (*doit) (int, struct interface *, void *), void *cookie)
{
struct interface *ife;
if (!if_list_all && (if_readlist() < 0))
return -1;
for (ife = int_list; ife; ife = ife->next) {
int err = doit(SD, ife, cookie);
if (err)
return err;
}
return 0;
}
int if_cache_free(void)
{
struct interface *ife;
while ((ife = int_list) != NULL) {
int_list = ife->next;
free(ife);
}
int_last = NULL;
if_list_all = 0;
return 0;
}
static int if_readconf(void)
{
int numreqs = 30;
struct ifconf ifc;
struct ifreq *ifr;
int n, err = -1;
int skfd;
/* SIOCGIFCONF currently seems to only work properly on AF_INET sockets
(as of 2.1.128) */
skfd = get_socket_for_af(AF_INET);
if (skfd < 0) {
fprintf(stderr, _("warning: no inet socket available: %s\n"),
strerror(errno));
/* Try to soldier on with whatever socket we can get hold of. */
skfd = sockets_open(0);
if (skfd < 0)
return -1;
}
ifc.ifc_buf = NULL;
for (;;) {
ifc.ifc_len = sizeof(struct ifreq) * numreqs;
ifc.ifc_buf = xrealloc(ifc.ifc_buf, ifc.ifc_len);
if (ioctl(skfd, SIOCGIFCONF, &ifc) < 0) {
perror("SIOCGIFCONF");
goto out;
}
if (ifc.ifc_len == sizeof(struct ifreq) * numreqs) {
/* assume it overflowed and try again */
numreqs *= 2;
continue;
}
break;
}
ifr = ifc.ifc_req;
for (n = 0; n < ifc.ifc_len; n += sizeof(struct ifreq)) {
if_cache_add(ifr->ifr_name);
ifr++;
}
err = 0;
out:
free(ifc.ifc_buf);
return err;
}
char *get_name(char *name, char *p)
{
while (isspace(*p))
p++;
while (*p) {
if (isspace(*p))
break;
if (*p == ':') { /* could be an alias */
char *dot = p++;
while (*p && isdigit(*p)) p++;
if (*p == ':') {
/* Yes it is, backup and copy it. */
p = dot;
*name++ = *p++;
while (*p && isdigit(*p)) {
*name++ = *p++;
}
} else {
/* No, it isn't */
p = dot;
}
p++;
break;
}
*name++ = *p++;
}
*name++ = '\0';
return p;
}
int procnetdev_version(char *buf)
{
if (strstr(buf, "compressed"))
return 3;
if (strstr(buf, "bytes"))
return 2;
return 1;
}
int get_dev_fields(char *bp, struct interface *ife)
{
switch (procnetdev_vsn) {
case 3:
sscanf(bp,
"%Lu %Lu %lu %lu %lu %lu %lu %lu %Lu %Lu %lu %lu %lu %lu %lu %lu",
&ife->stats.rx_bytes,
&ife->stats.rx_packets,
&ife->stats.rx_errors,
&ife->stats.rx_dropped,
&ife->stats.rx_fifo_errors,
&ife->stats.rx_frame_errors,
&ife->stats.rx_compressed,
&ife->stats.rx_multicast,
&ife->stats.tx_bytes,
&ife->stats.tx_packets,
&ife->stats.tx_errors,
&ife->stats.tx_dropped,
&ife->stats.tx_fifo_errors,
&ife->stats.collisions,
&ife->stats.tx_carrier_errors,
&ife->stats.tx_compressed);
break;
case 2:
sscanf(bp, "%Lu %Lu %lu %lu %lu %lu %Lu %Lu %lu %lu %lu %lu %lu",
&ife->stats.rx_bytes,
&ife->stats.rx_packets,
&ife->stats.rx_errors,
&ife->stats.rx_dropped,
&ife->stats.rx_fifo_errors,
&ife->stats.rx_frame_errors,
&ife->stats.tx_bytes,
&ife->stats.tx_packets,
&ife->stats.tx_errors,
&ife->stats.tx_dropped,
&ife->stats.tx_fifo_errors,
&ife->stats.collisions,
&ife->stats.tx_carrier_errors);
ife->stats.rx_multicast = 0;
break;
case 1:
sscanf(bp, "%Lu %lu %lu %lu %lu %Lu %lu %lu %lu %lu %lu",
&ife->stats.rx_packets,
&ife->stats.rx_errors,
&ife->stats.rx_dropped,
&ife->stats.rx_fifo_errors,
&ife->stats.rx_frame_errors,
&ife->stats.tx_packets,
&ife->stats.tx_errors,
&ife->stats.tx_dropped,
&ife->stats.tx_fifo_errors,
&ife->stats.collisions,
&ife->stats.tx_carrier_errors);
ife->stats.rx_bytes = 0;
ife->stats.tx_bytes = 0;
ife->stats.rx_multicast = 0;
break;
}
return 0;
}
static int if_readlist_proc(char *target)
{
FILE *fh;
char buf[512];
struct interface *ife;
int err;
fh = fopen(_PATH_PROCNET_DEV, "r");
if (!fh) {
fprintf(stderr, _("Warning: cannot open %s (%s). Limited output.\n"),
_PATH_PROCNET_DEV, strerror(errno));
return -2;
}
fgets(buf, sizeof buf, fh); /* eat line */
fgets(buf, sizeof buf, fh);
#if 0 /* pretty, but can't cope with missing fields */
fmt = proc_gen_fmt(_PATH_PROCNET_DEV, 1, fh,
"face", "", /* parsed separately */
"bytes", "%lu",
"packets", "%lu",
"errs", "%lu",
"drop", "%lu",
"fifo", "%lu",
"frame", "%lu",
"compressed", "%lu",
"multicast", "%lu",
"bytes", "%lu",
"packets", "%lu",
"errs", "%lu",
"drop", "%lu",
"fifo", "%lu",
"colls", "%lu",
"carrier", "%lu",
"compressed", "%lu",
NULL);
if (!fmt)
return -1;
#else
procnetdev_vsn = procnetdev_version(buf);
#endif
err = 0;
while (fgets(buf, sizeof buf, fh)) {
char *s, name[IFNAMSIZ];
s = get_name(name, buf);
ife = if_cache_add(name);
get_dev_fields(s, ife);
ife->statistics_valid = 1;
if (target && !strcmp(target,name))
break;
}
if (ferror(fh)) {
perror(_PATH_PROCNET_DEV);
err = -1;
}
#if 0
free(fmt);
#endif
fclose(fh);
return err;
}
int if_readlist(void)
{
/* caller will/should check not to call this too often
* (i.e. only if if_list_all == 0
*/
int err = 0;
err |= if_readlist_proc(NULL);
err |= if_readconf();
if_list_all = 1;
return err;
}
/* Support for fetching an IPX address */
#if HAVE_AFIPX
static int ipx_getaddr(int sock, int ft, struct ifreq *ifr)
{
((struct sockaddr_ipx *) &ifr->ifr_addr)->sipx_type = ft;
return ioctl(sock, SIOCGIFADDR, ifr);
}
#endif
/* Fetch the interface configuration from the kernel. */
int if_fetch(struct interface *ife)
{
struct ifreq ifr;
int fd;
char *ifname = ife->name;
strcpy(ifr.ifr_name, ifname);
if (ioctl(skfd, SIOCGIFFLAGS, &ifr) < 0)
return (-1);
ife->flags = ifr.ifr_flags;
strcpy(ifr.ifr_name, ifname);
if (ioctl(skfd, SIOCGIFHWADDR, &ifr) < 0)
memset(ife->hwaddr, 0, 32);
else
memcpy(ife->hwaddr, ifr.ifr_hwaddr.sa_data, 8);
ife->type = ifr.ifr_hwaddr.sa_family;
strcpy(ifr.ifr_name, ifname);
if (ioctl(skfd, SIOCGIFMETRIC, &ifr) < 0)
ife->metric = 0;
else
ife->metric = ifr.ifr_metric;
strcpy(ifr.ifr_name, ifname);
if (ioctl(skfd, SIOCGIFMTU, &ifr) < 0)
ife->mtu = 0;
else
ife->mtu = ifr.ifr_mtu;
#ifdef HAVE_HWSLIP
if (ife->type == ARPHRD_SLIP || ife->type == ARPHRD_CSLIP ||
ife->type == ARPHRD_SLIP6 || ife->type == ARPHRD_CSLIP6 ||
ife->type == ARPHRD_ADAPT) {
#ifdef SIOCGOUTFILL
strcpy(ifr.ifr_name, ifname);
if (ioctl(skfd, SIOCGOUTFILL, &ifr) < 0)
ife->outfill = 0;
else
ife->outfill = (unsigned int) ifr.ifr_data;
#endif
#ifdef SIOCGKEEPALIVE
strcpy(ifr.ifr_name, ifname);
if (ioctl(skfd, SIOCGKEEPALIVE, &ifr) < 0)
ife->keepalive = 0;
else
ife->keepalive = (unsigned int) ifr.ifr_data;
#endif
}
#endif
strcpy(ifr.ifr_name, ifname);
if (ioctl(skfd, SIOCGIFMAP, &ifr) < 0)
memset(&ife->map, 0, sizeof(struct ifmap));
else
memcpy(&ife->map, &ifr.ifr_map, sizeof(struct ifmap));
strcpy(ifr.ifr_name, ifname);
if (ioctl(skfd, SIOCGIFMAP, &ifr) < 0)
memset(&ife->map, 0, sizeof(struct ifmap));
else
ife->map = ifr.ifr_map;
#ifdef HAVE_TXQUEUELEN
strcpy(ifr.ifr_name, ifname);
if (ioctl(skfd, SIOCGIFTXQLEN, &ifr) < 0)
ife->tx_queue_len = -1; /* unknown value */
else
ife->tx_queue_len = ifr.ifr_qlen;
#else
ife->tx_queue_len = -1; /* unknown value */
#endif
#if HAVE_AFINET
/* IPv4 address? */
fd = get_socket_for_af(AF_INET);
if (fd >= 0) {
strcpy(ifr.ifr_name, ifname);
ifr.ifr_addr.sa_family = AF_INET;
if (ioctl(fd, SIOCGIFADDR, &ifr) == 0) {
ife->has_ip = 1;
ife->addr = ifr.ifr_addr;
strcpy(ifr.ifr_name, ifname);
if (ioctl(fd, SIOCGIFDSTADDR, &ifr) < 0)
memset(&ife->dstaddr, 0, sizeof(struct sockaddr));
else
ife->dstaddr = ifr.ifr_dstaddr;
strcpy(ifr.ifr_name, ifname);
if (ioctl(fd, SIOCGIFBRDADDR, &ifr) < 0)
memset(&ife->broadaddr, 0, sizeof(struct sockaddr));
else
ife->broadaddr = ifr.ifr_broadaddr;
strcpy(ifr.ifr_name, ifname);
if (ioctl(fd, SIOCGIFNETMASK, &ifr) < 0)
memset(&ife->netmask, 0, sizeof(struct sockaddr));
else
ife->netmask = ifr.ifr_netmask;
} else
memset(&ife->addr, 0, sizeof(struct sockaddr));
}
#endif
#if HAVE_AFATALK
/* DDP address maybe ? */
fd = get_socket_for_af(AF_APPLETALK);
if (fd >= 0) {
strcpy(ifr.ifr_name, ifname);
if (ioctl(fd, SIOCGIFADDR, &ifr) == 0) {
ife->ddpaddr = ifr.ifr_addr;
ife->has_ddp = 1;
}
}
#endif
#if HAVE_AFIPX
/* Look for IPX addresses with all framing types */
fd = get_socket_for_af(AF_IPX);
if (fd >= 0) {
strcpy(ifr.ifr_name, ifname);
if (!ipx_getaddr(fd, IPX_FRAME_ETHERII, &ifr)) {
ife->has_ipx_bb = 1;
ife->ipxaddr_bb = ifr.ifr_addr;
}
strcpy(ifr.ifr_name, ifname);
if (!ipx_getaddr(fd, IPX_FRAME_SNAP, &ifr)) {
ife->has_ipx_sn = 1;
ife->ipxaddr_sn = ifr.ifr_addr;
}
strcpy(ifr.ifr_name, ifname);
if (!ipx_getaddr(fd, IPX_FRAME_8023, &ifr)) {
ife->has_ipx_e3 = 1;
ife->ipxaddr_e3 = ifr.ifr_addr;
}
strcpy(ifr.ifr_name, ifname);
if (!ipx_getaddr(fd, IPX_FRAME_8022, &ifr)) {
ife->has_ipx_e2 = 1;
ife->ipxaddr_e2 = ifr.ifr_addr;
}
}
#endif
#if HAVE_AFECONET
/* Econet address maybe? */
fd = get_socket_for_af(AF_ECONET);
if (fd >= 0) {
strcpy(ifr.ifr_name, ifname);
if (ioctl(fd, SIOCGIFADDR, &ifr) == 0) {
ife->ecaddr = ifr.ifr_addr;
ife->has_econet = 1;
}
}
#endif
return 0;
}
int do_if_fetch(struct interface *ife)
{
if (if_fetch(ife) < 0) {
char *errmsg;
if (errno == ENODEV) {
/* Give better error message for this case. */
errmsg = _("Device not found");
} else {
errmsg = strerror(errno);
}
fprintf(stderr, _("%s: error fetching interface information: %s\n"),
ife->name, errmsg);
return -1;
}
return 0;
}
int do_if_print(struct interface *ife, void *cookie)
{
int *opt_a = (int *) cookie;
int res;
res = do_if_fetch(ife);
if (res >= 0) {
if ((ife->flags & IFF_UP) || *opt_a)
ife_print(ife);
}
return res;
}
void ife_print_short(struct interface *ptr)
{
printf("%-5.5s ", ptr->name);
printf("%5d %-2d ", ptr->mtu, ptr->metric);
/* If needed, display the interface statistics. */
if (ptr->statistics_valid) {
printf("%8llu %6lu %6lu %6lu ",
ptr->stats.rx_packets, ptr->stats.rx_errors,
ptr->stats.rx_dropped, ptr->stats.rx_fifo_errors);
printf("%8llu %6lu %6lu %6lu ",
ptr->stats.tx_packets, ptr->stats.tx_errors,
ptr->stats.tx_dropped, ptr->stats.tx_fifo_errors);
} else {
printf("%-56s", _(" - no statistics available -"));
}
/* DONT FORGET TO ADD THE FLAGS IN ife_print_long, too */
if (ptr->flags == 0)
printf(_("[NO FLAGS]"));
if (ptr->flags & IFF_ALLMULTI)
printf("A");
if (ptr->flags & IFF_BROADCAST)
printf("B");
if (ptr->flags & IFF_DEBUG)
printf("D");
if (ptr->flags & IFF_LOOPBACK)
printf("L");
if (ptr->flags & IFF_MULTICAST)
printf("M");
#ifdef HAVE_DYNAMIC
if (ptr->flags & IFF_DYNAMIC)
printf("d");
#endif
if (ptr->flags & IFF_PROMISC)
printf("P");
if (ptr->flags & IFF_NOTRAILERS)
printf("N");
if (ptr->flags & IFF_NOARP)
printf("O");
if (ptr->flags & IFF_POINTOPOINT)
printf("P");
if (ptr->flags & IFF_SLAVE)
printf("s");
if (ptr->flags & IFF_MASTER)
printf("m");
if (ptr->flags & IFF_RUNNING)
printf("R");
if (ptr->flags & IFF_UP)
printf("U");
/* DONT FORGET TO ADD THE FLAGS IN ife_print_long, too */
printf("\n");
}
void ife_print_long(struct interface *ptr)
{
struct aftype *ap;
struct hwtype *hw;
int hf;
int can_compress = 0;
unsigned long long rx, tx, short_rx, short_tx;
const char *Rext = "b";
const char *Text = "b";
#if HAVE_AFIPX
static struct aftype *ipxtype = NULL;
#endif
#if HAVE_AFECONET
static struct aftype *ectype = NULL;
#endif
#if HAVE_AFATALK
static struct aftype *ddptype = NULL;
#endif
#if HAVE_AFINET6
FILE *f;
char addr6[40], devname[20];
struct sockaddr_in6 sap;
int plen, scope, dad_status, if_idx;
extern struct aftype inet6_aftype;
char addr6p[8][5];
#endif
ap = get_afntype(ptr->addr.sa_family);
if (ap == NULL)
ap = get_afntype(0);
hf = ptr->type;
if (hf == ARPHRD_CSLIP || hf == ARPHRD_CSLIP6)
can_compress = 1;
hw = get_hwntype(hf);
if (hw == NULL)
hw = get_hwntype(-1);
printf(_("%-9.9s Link encap:%s "), ptr->name, hw->title);
/* For some hardware types (eg Ash, ATM) we don't print the
hardware address if it's null. */
if (hw->print != NULL && (! (hw_null_address(hw, ptr->hwaddr) &&
hw->suppress_null_addr)))
printf(_("HWaddr %s "), hw->print(ptr->hwaddr));
#ifdef IFF_PORTSEL
if (ptr->flags & IFF_PORTSEL) {
printf(_("Media:%s"), if_port_text[ptr->map.port][0]);
if (ptr->flags & IFF_AUTOMEDIA)
printf(_("(auto)"));
}
#endif
printf("\n");
#if HAVE_AFINET
if (ptr->has_ip) {
printf(_(" %s addr:%s "), ap->name,
ap->sprint(&ptr->addr, 1));
if (ptr->flags & IFF_POINTOPOINT) {
printf(_(" P-t-P:%s "), ap->sprint(&ptr->dstaddr, 1));
}
if (ptr->flags & IFF_BROADCAST) {
printf(_(" Bcast:%s "), ap->sprint(&ptr->broadaddr, 1));
}
printf(_(" Mask:%s\n"), ap->sprint(&ptr->netmask, 1));
}
#endif
#if HAVE_AFINET6
/* FIXME: should be integrated into interface.c. */
if ((f = fopen(_PATH_PROCNET_IFINET6, "r")) != NULL) {
while (fscanf(f, "%4s%4s%4s%4s%4s%4s%4s%4s %02x %02x %02x %02x %20s\n",
addr6p[0], addr6p[1], addr6p[2], addr6p[3],
addr6p[4], addr6p[5], addr6p[6], addr6p[7],
&if_idx, &plen, &scope, &dad_status, devname) != EOF) {
if (!strcmp(devname, ptr->name)) {
sprintf(addr6, "%s:%s:%s:%s:%s:%s:%s:%s",
addr6p[0], addr6p[1], addr6p[2], addr6p[3],
addr6p[4], addr6p[5], addr6p[6], addr6p[7]);
inet6_aftype.input(1, addr6, (struct sockaddr *) &sap);
printf(_(" inet6 addr: %s/%d"),
inet6_aftype.sprint((struct sockaddr *) &sap, 1), plen);
printf(_(" Scope:"));
switch (scope) {
case 0:
printf(_("Global"));
break;
case IPV6_ADDR_LINKLOCAL:
printf(_("Link"));
break;
case IPV6_ADDR_SITELOCAL:
printf(_("Site"));
break;
case IPV6_ADDR_COMPATv4:
printf(_("Compat"));
break;
case IPV6_ADDR_LOOPBACK:
printf(_("Host"));
break;
default:
printf(_("Unknown"));
}
printf("\n");
}
}
fclose(f);
}
#endif
#if HAVE_AFIPX
if (ipxtype == NULL)
ipxtype = get_afntype(AF_IPX);
if (ipxtype != NULL) {
if (ptr->has_ipx_bb)
printf(_(" IPX/Ethernet II addr:%s\n"),
ipxtype->sprint(&ptr->ipxaddr_bb, 1));
if (ptr->has_ipx_sn)
printf(_(" IPX/Ethernet SNAP addr:%s\n"),
ipxtype->sprint(&ptr->ipxaddr_sn, 1));
if (ptr->has_ipx_e2)
printf(_(" IPX/Ethernet 802.2 addr:%s\n"),
ipxtype->sprint(&ptr->ipxaddr_e2, 1));
if (ptr->has_ipx_e3)
printf(_(" IPX/Ethernet 802.3 addr:%s\n"),
ipxtype->sprint(&ptr->ipxaddr_e3, 1));
}
#endif
#if HAVE_AFATALK
if (ddptype == NULL)
ddptype = get_afntype(AF_APPLETALK);
if (ddptype != NULL) {
if (ptr->has_ddp)
printf(_(" EtherTalk Phase 2 addr:%s\n"), ddptype->sprint(&ptr->ddpaddr, 1));
}
#endif
#if HAVE_AFECONET
if (ectype == NULL)
ectype = get_afntype(AF_ECONET);
if (ectype != NULL) {
if (ptr->has_econet)
printf(_(" econet addr:%s\n"), ectype->sprint(&ptr->ecaddr, 1));
}
#endif
printf(" ");
/* DONT FORGET TO ADD THE FLAGS IN ife_print_short, too */
if (ptr->flags == 0)
printf(_("[NO FLAGS] "));
if (ptr->flags & IFF_UP)
printf(_("UP "));
if (ptr->flags & IFF_BROADCAST)
printf(_("BROADCAST "));
if (ptr->flags & IFF_DEBUG)
printf(_("DEBUG "));
if (ptr->flags & IFF_LOOPBACK)
printf(_("LOOPBACK "));
if (ptr->flags & IFF_POINTOPOINT)
printf(_("POINTOPOINT "));
if (ptr->flags & IFF_NOTRAILERS)
printf(_("NOTRAILERS "));
if (ptr->flags & IFF_RUNNING)
printf(_("RUNNING "));
if (ptr->flags & IFF_NOARP)
printf(_("NOARP "));
if (ptr->flags & IFF_PROMISC)
printf(_("PROMISC "));
if (ptr->flags & IFF_ALLMULTI)
printf(_("ALLMULTI "));
if (ptr->flags & IFF_SLAVE)
printf(_("SLAVE "));
if (ptr->flags & IFF_MASTER)
printf(_("MASTER "));
if (ptr->flags & IFF_MULTICAST)
printf(_("MULTICAST "));
#ifdef HAVE_DYNAMIC
if (ptr->flags & IFF_DYNAMIC)
printf(_("DYNAMIC "));
#endif
/* DONT FORGET TO ADD THE FLAGS IN ife_print_short */
printf(_(" MTU:%d Metric:%d"),
ptr->mtu, ptr->metric ? ptr->metric : 1);
#ifdef SIOCSKEEPALIVE
if (ptr->outfill || ptr->keepalive)
printf(_(" Outfill:%d Keepalive:%d"),
ptr->outfill, ptr->keepalive);
#endif
printf("\n");
/* If needed, display the interface statistics. */
if (ptr->statistics_valid) {
/* XXX: statistics are currently only printed for the primary address,
* not for the aliases, although strictly speaking they're shared
* by all addresses.
*/
printf(" ");
printf(_("RX packets:%llu errors:%lu dropped:%lu overruns:%lu frame:%lu\n"),
ptr->stats.rx_packets, ptr->stats.rx_errors,
ptr->stats.rx_dropped, ptr->stats.rx_fifo_errors,
ptr->stats.rx_frame_errors);
if (can_compress)
printf(_(" compressed:%lu\n"), ptr->stats.rx_compressed);
rx = ptr->stats.rx_bytes;
tx = ptr->stats.tx_bytes;
short_rx = rx * 10;
short_tx = tx * 10;
if (rx > 1125899906842624ull) {
short_rx /= 1125899906842624ull;
Rext = "PiB";
} else if (rx > 1099511627776ull) {
short_rx /= 1099511627776ull;
Rext = "TiB";
} else if (rx > 1073741824ull) {
short_rx /= 1073741824ull;
Rext = "GiB";
} else if (rx > 1048576) {
short_rx /= 1048576;
Rext = "MiB";
} else if (rx > 1024) {
short_rx /= 1024;
Rext = "KiB";
}
if (tx > 1125899906842624ull) {
short_tx /= 1125899906842624ull;
Text = "PiB";
} else if (tx > 1099511627776ull) {
short_tx /= 1099511627776ull;
Text = "TiB";
} else if (tx > 1073741824ull) {
short_tx /= 1073741824ull;
Text = "GiB";
} else if (tx > 1048576) {
short_tx /= 1048576;
Text = "MiB";
} else if (tx > 1024) {
short_tx /= 1024;
Text = "KiB";
}
printf(" ");
printf(_("TX packets:%llu errors:%lu dropped:%lu overruns:%lu carrier:%lu\n"),
ptr->stats.tx_packets, ptr->stats.tx_errors,
ptr->stats.tx_dropped, ptr->stats.tx_fifo_errors,
ptr->stats.tx_carrier_errors);
printf(_(" collisions:%lu "), ptr->stats.collisions);
if (can_compress)
printf(_("compressed:%lu "), ptr->stats.tx_compressed);
if (ptr->tx_queue_len != -1)
printf(_("txqueuelen:%d "), ptr->tx_queue_len);
printf("\n ");
printf(_("RX bytes:%llu (%lu.%lu %s) TX bytes:%llu (%lu.%lu %s)\n"),
rx, (unsigned long)(short_rx / 10),
(unsigned long)(short_rx % 10), Rext,
tx, (unsigned long)(short_tx / 10),
(unsigned long)(short_tx % 10), Text);
}
if ((ptr->map.irq || ptr->map.mem_start || ptr->map.dma ||
ptr->map.base_addr >= 0x100)) {
printf(" ");
if (ptr->map.irq)
printf(_("Interrupt:%d "), ptr->map.irq);
if (ptr->map.base_addr >= 0x100) /* Only print devices using it for
I/O maps */
printf(_("Base address:0x%x "), ptr->map.base_addr);
if (ptr->map.mem_start) {
printf(_("Memory:%lx-%lx "), ptr->map.mem_start, ptr->map.mem_end);
}
if (ptr->map.dma)
printf(_("DMA chan:%x "), ptr->map.dma);
printf("\n");
}
printf("\n");
}
void ife_print(struct interface *i)
{
if (ife_short)
ife_print_short(i);
else
ife_print_long(i);
}
-100
View File
@@ -1,100 +0,0 @@
struct user_net_device_stats {
unsigned long long rx_packets; /* total packets received */
unsigned long long tx_packets; /* total packets transmitted */
unsigned long long rx_bytes; /* total bytes received */
unsigned long long tx_bytes; /* total bytes transmitted */
unsigned long rx_errors; /* bad packets received */
unsigned long tx_errors; /* packet transmit problems */
unsigned long rx_dropped; /* no space in linux buffers */
unsigned long tx_dropped; /* no space available in linux */
unsigned long rx_multicast; /* multicast packets received */
unsigned long rx_compressed;
unsigned long tx_compressed;
unsigned long collisions;
/* detailed rx_errors: */
unsigned long rx_length_errors;
unsigned long rx_over_errors; /* receiver ring buff overflow */
unsigned long rx_crc_errors; /* recved pkt with crc error */
unsigned long rx_frame_errors; /* recv'd frame alignment error */
unsigned long rx_fifo_errors; /* recv'r fifo overrun */
unsigned long rx_missed_errors; /* receiver missed packet */
/* detailed tx_errors */
unsigned long tx_aborted_errors;
unsigned long tx_carrier_errors;
unsigned long tx_fifo_errors;
unsigned long tx_heartbeat_errors;
unsigned long tx_window_errors;
};
struct interface {
struct interface *next, *prev;
char name[IFNAMSIZ]; /* interface name */
short type; /* if type */
short flags; /* various flags */
int metric; /* routing metric */
int mtu; /* MTU value */
int tx_queue_len; /* transmit queue length */
struct ifmap map; /* hardware setup */
struct sockaddr addr; /* IP address */
struct sockaddr dstaddr; /* P-P IP address */
struct sockaddr broadaddr; /* IP broadcast address */
struct sockaddr netmask; /* IP network mask */
struct sockaddr ipxaddr_bb; /* IPX network address */
struct sockaddr ipxaddr_sn; /* IPX network address */
struct sockaddr ipxaddr_e3; /* IPX network address */
struct sockaddr ipxaddr_e2; /* IPX network address */
struct sockaddr ddpaddr; /* Appletalk DDP address */
struct sockaddr ecaddr; /* Econet address */
int has_ip;
int has_ipx_bb;
int has_ipx_sn;
int has_ipx_e3;
int has_ipx_e2;
int has_ax25;
int has_ddp;
int has_econet;
char hwaddr[32]; /* HW address */
int statistics_valid;
struct user_net_device_stats stats; /* statistics */
int keepalive; /* keepalive value for SLIP */
int outfill; /* outfill value for SLIP */
};
extern int if_fetch(struct interface *ife);
extern int for_all_interfaces(int, int (*)(int, struct interface *, void *), void *);
extern int if_cache_free(void);
extern struct interface *lookup_interface(char *name);
extern int if_readlist(void);
extern int do_if_fetch(struct interface *ife);
extern int do_if_print(struct interface *ife, void *cookie);
extern int procnetdev_version(char *buf);
extern int get_dev_fields(char *bp, struct interface *ife);
extern char * get_name(char *name, char *p);
extern void ife_print(struct interface *ptr);
extern int ife_short;
extern const char *if_port_text[][4];
/* Defines for poor glibc2.0 users, the feature check is done at runtime */
#if !defined(SIOCSIFTXQLEN)
#define SIOCSIFTXQLEN 0x8943
#define SIOCGIFTXQLEN 0x8942
#endif
#if !defined(ifr_qlen)
/* Actually it is ifru_ivalue, but that is not present in 2.0 kernel headers */
#define ifr_qlen ifr_ifru.ifru_mtu
#endif
#define HAVE_TXQUEUELEN
#define HAVE_DYNAMIC
#ifndef IFF_DYNAMIC
#define IFF_DYNAMIC 0x8000 /* dialup device with changing addresses */
#endif
-12
View File
@@ -1,12 +0,0 @@
/* Dummy header for libintl.h */
#if I18N
#include <locale.h>
#undef __OPTIMIZE__
#include <libintl.h>
#define _(String) gettext((String))
#define N_(String) (String)
#else
#define _(String) (String)
#define N_(String) (String)
#endif
-85
View File
@@ -1,85 +0,0 @@
/* lib-myconnect.c:
used by interfacedemo for "pyramid" LCD device.
*/
/*
Copyright (C) 2005 Silvan Marco Fin <silvan@kernelconcepts.de>
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
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
*/
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <stdio.h>
#include <string.h>
/* TCP connection to given host/port
*/
int get_connection(char *peername, int peerport)
{
struct sockaddr_in peeraddr;
int SocketDescriptor;
struct hostent *HostEntry;
HostEntry=gethostbyname(peername);
if (HostEntry==NULL)
{
switch (h_errno)
{
case HOST_NOT_FOUND:
printf("Host not found.\n");
return -1;
break;
case NO_ADDRESS:
printf("No IP found for valid hostname.\n");
return -1;
break;
case NO_RECOVERY:
printf("Name service error.\n");
return -1;
break;
case TRY_AGAIN:
printf("Temporary error in name resolution.\n");
return -1;
break;
default:
break;
}
}
/* peeraddr must contain information to reach the server */
memset(&peeraddr, 0, sizeof(peeraddr));
peeraddr.sin_family = AF_INET;
peeraddr.sin_port = htons(peerport);
peeraddr.sin_addr = *(struct in_addr *) HostEntry->h_addr;
SocketDescriptor=socket(PF_INET, SOCK_STREAM, 0);
if (SocketDescriptor==-1)
{
printf("Error creating socket\n");
return -1;
}
if (connect(SocketDescriptor, (struct sockaddr *) &peeraddr, sizeof(peeraddr))==-1)
{
perror("Error connecting");
return -1;
}
return SocketDescriptor;
}
-40
View File
@@ -1,40 +0,0 @@
/* lib-myconnect.h
used by interfacedemo for "pyramid" LCD device.
*/
/*
Copyright (C) 2005 Silvan Marco Fin <silvan@kernelconcepts.de>
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
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
*/
#ifndef LIB_MYCONNECT
#define LIB_MYCONNECT
/*
lib-myconnect.c:
used by interfacedemo to connect to a TCP socket.
*/
/* TCP connection to given host/port
*/
int get_connection(char *peername, int peerport);
#endif
-133
View File
@@ -1,133 +0,0 @@
/* lib-mylcd.h
used by interfacedemo for "pyramid" LCD device.
*/
/*
Copyright (C) 2005 Silvan Marco Fin <silvan@kernelconcepts.de>
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
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
*/
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include "lib-mylcd.h"
#define DEBUG 0
/* Request information from LCDd */
int get_integer(int SD, char *request)
{
static char output[MAXREAD];
write(SD, request, strlen(request));
read(SD, output, MAXREAD-1);
return atoi(output);
}
/* Used to parse the reply from the hello-msg.
*/
void parse_hello(char *input)
{
char *next=input;
char *retval;
while (1)
{
retval=strtok(next, " ");
next=NULL;
if (retval==NULL)
break;
if (strcmp(retval, "wid")==0)
screen.width=atoi(strtok(next, " "));
if (strcmp(retval, "hgt")==0)
screen.height=atoi(strtok(next, " "));
}
}
int parse_reply(char *input)
{
char *next=input;
char *retstr;
int retint=UNKNOWNKEY;
int inputlen=strlen(input);
int len=0;
printf("Eingabe: %s\n", input);
while (1)
{
retstr=strtok(next, " \n");
next=NULL;
if (retstr==NULL)
{
input[0]=0; /* wofür war das? */
break;
}
len+=strlen(retstr)+1;
/* key detected? */
if (strcmp(retstr, "key")==0)
{
retstr=strtok(next, " \n");
len+=strlen(retstr)+1;
if (strcmp(retstr, "Escape")==0)
retint=ESCAPEKEY;
if (strcmp(retstr, "Down")==0)
retint=DOWNKEY;
if (strcmp(retstr, "Right")==0)
retint=RIGHTKEY;
if (strcmp(retstr, "Enter")==0)
retint=ENTERKEY;
input=strncpy(input, &input[len], inputlen-len+1);
return retint;
}
}
return NOKEY;
}
char *basic_send(int SD, char *request)
{
static char answer[MAXREAD];
if (DEBUG)
printf("Sending command: %s\n", request);
memset(answer, 0, MAXREAD);
write(SD, request, strlen(request));
write(SD, "\n", strlen("\n"));
read(SD, answer, MAXREAD);
if (DEBUG)
printf("Answer to command to LCDproc: %s\n", answer);
return answer;
}
char *basic_read(int SD)
{
static char answer[MAXREAD];
memset(answer, 0, MAXREAD);
if (DEBUG)
printf("Going for read!\n");
read(SD, answer, MAXREAD);
if (DEBUG)
printf("Read returned: %s\n", answer);
return answer;
}
-59
View File
@@ -1,59 +0,0 @@
/* lib-mylcd.h
used by interfacedemo for "pyramid" LCD device.
*/
/*
Copyright (C) 2005 Silvan Marco Fin <silvan@kernelconcepts.de>
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
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
*/
#ifndef LIB_MYLCD_H
#define LIB_MYLCD_H
#define MAXREAD 1024
/* Keys */
#define UNKNOWNKEY -1
#define NOKEY 0
#define DOWNKEY 1
#define ENTERKEY 2
#define RIGHTKEY 3
#define ESCAPEKEY 4
struct
{
int width;
int height;
} screen;
/* Request information from LCDd
*/
int get_integer(int SD, char *request);
/* Used to parse the reply from the hello-msg.
*/
void parse_hello(char *input);
int parse_reply(char *input);
char *basic_send(int SD, char *request);
char *basic_read(int SD);
#endif
-59
View File
@@ -1,59 +0,0 @@
/*
* lib/loopback.c This file contains the general hardware types.
*
* Version: $Id$
*
* Author: Fred N. van Kempen, <waltje@uwalt.nl.mugnet.org>
* Copyright 1993 MicroWalt Corporation
*
* Modifications:
* 1998-07-01 - Arnaldo Carvalho de Melo - GNU gettext instead of catgets
*
* 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.
*/
#include "config.h"
#include <sys/types.h>
#include <sys/socket.h>
#include <net/if_arp.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <ctype.h>
#include <string.h>
#include <unistd.h>
#include "net-support.h"
#include "pathnames.h"
#include "intl.h"
#include "util.h"
/* Display an UNSPEC address. */
static char *pr_unspec(unsigned char *ptr)
{
static char buff[64];
char *pos;
unsigned int i;
pos = buff;
for (i = 0; i < sizeof(struct sockaddr); i++) {
pos += sprintf(pos, "%02X-", (*ptr++ & 0377));
}
buff[strlen(buff) - 1] = '\0';
return (buff);
}
struct hwtype unspec_hwtype =
{
"unspec", NULL, /*"UNSPEC", */ -1, 0,
pr_unspec, NULL, NULL
};
struct hwtype loop_hwtype =
{
"loop", NULL, /*"Local Loopback", */ ARPHRD_LOOPBACK, 0,
NULL, NULL, NULL
};
-244
View File
@@ -1,244 +0,0 @@
/*
* lib/support.h This file contains the definitions of what is in the
* support library. Most of all, it defines structures
* for accessing support modules, and the function proto-
* types.
*
* NET-LIB A collection of functions used from the base set of the
* NET-3 Networking Distribution for the LINUX operating
* system. (net-tools, net-drivers)
*
* Version: lib/net-support.h 1.35 (1996-01-01)
*
* Maintainer: Bernd 'eckes' Eckenfels, <net-tools@lina.inka.de>
*
* Author: Fred N. van Kempen, <waltje@uwalt.nl.mugnet.org>
* Copyright 1993 MicroWalt Corporation
*
* Modifications:
*960125 {1.20} Bernd Eckenfels: reformated, layout
*960202 {1.30} Bernd Eckenfels: rprint in aftype
*960206 {1.31} Bernd Eckenfels: route_init
*960219 {1.32} Bernd Eckenfels: type for ap->input()
*960322 {1.33} Bernd Eckenfels: activate_ld and const in get_hwtype
*960413 {1.34} Bernd Eckenfels: new RTACTION suport
*990101 {1.35} Bernd Eckenfels: print_(hw|af)list support, added kerneldefines
*
* 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.
*/
#include <sys/socket.h>
/* This structure defines protocol families and their handlers. */
struct aftype {
char *name;
char *title;
int af;
int alen;
char *(*print) (unsigned char *);
char *(*sprint) (struct sockaddr *, int numeric);
int (*input) (int type, char *bufp, struct sockaddr *);
void (*herror) (char *text);
int (*rprint) (int options);
int (*rinput) (int typ, int ext, char **argv);
/* may modify src */
int (*getmask) (char *src, struct sockaddr * mask, char *name);
int fd;
char *flag_file;
};
extern struct aftype *aftypes[];
/* This structure defines hardware protocols and their handlers. */
struct hwtype {
char *name;
char *title;
int type;
int alen;
char *(*print) (unsigned char *);
int (*input) (char *, struct sockaddr *);
int (*activate) (int fd);
int suppress_null_addr;
};
extern struct hwtype *get_hwtype(const char *name);
extern struct hwtype *get_hwntype(int type);
extern void print_hwlist(int type);
extern struct aftype *get_aftype(const char *name);
extern struct aftype *get_afntype(int type);
extern void print_aflist(int type);
extern int hw_null_address(struct hwtype *hw, void *addr);
extern int getargs(char *string, char *arguments[]);
extern int get_socket_for_af(int af);
extern void getroute_init(void);
extern void setroute_init(void);
extern void activate_init(void);
extern int route_info(const char *afname, int flags);
extern int route_edit(int action, const char *afname, int flags, char **argv);
extern int activate_ld(const char *hwname, int fd);
#define RTACTION_ADD 1
#define RTACTION_DEL 2
#define RTACTION_HELP 3
#define RTACTION_FLUSH 4
#define RTACTION_SHOW 5
#define FLAG_EXT 3 /* AND-Mask */
#define FLAG_NUM_HOST 4
#define FLAG_NUM_PORT 8
#define FLAG_NUM_USER 16
#define FLAG_NUM (FLAG_NUM_HOST|FLAG_NUM_PORT|FLAG_NUM_USER)
#define FLAG_SYM 32
#define FLAG_CACHE 64
#define FLAG_FIB 128
#define FLAG_VERBOSE 256
extern int ip_masq_info(int numeric_host, int numeric_port, int ext);
extern int INET_rprint(int options);
extern int INET6_rprint(int options);
extern int DDP_rprint(int options);
extern int IPX_rprint(int options);
extern int NETROM_rprint(int options);
extern int AX25_rprint(int options);
extern int X25_rprint(int options);
extern int INET_rinput(int action, int flags, char **argv);
extern int INET6_rinput(int action, int flags, char **argv);
extern int DDP_rinput(int action, int flags, char **argv);
extern int IPX_rinput(int action, int flags, char **argv);
extern int NETROM_rinput(int action, int flags, char **argv);
extern int AX25_rinput(int action, int flags, char **argv);
extern int X25_rinput(int action, int flags, char **argv);
extern int aftrans_opt(const char *arg);
extern void aftrans_def(char *tool, char *argv0, char *dflt);
extern char *get_sname(int socknumber, char *proto, int numeric);
extern int flag_unx;
extern int flag_ipx;
extern int flag_ax25;
extern int flag_ddp;
extern int flag_netrom;
extern int flag_x25;
extern int flag_inet;
extern int flag_inet6;
extern char afname[];
#define AFTRANS_OPTS \
{"ax25", 0, 0, 1}, \
{"x25", 0, 0, 1}, \
{"ip", 0, 0, 1}, \
{"ipx", 0, 0, 1}, \
{"appletalk", 0, 0, 1}, \
{"netrom", 0, 0, 1}, \
{"inet", 0, 0, 1}, \
{"inet6", 0, 0, 1}, \
{"ddp", 0, 0, 1}, \
{"unix", 0, 0, 1}, \
{"tcpip", 0, 0, 1}
#define AFTRANS_CNT 11
#define EINTERN(file, text) fprintf(stderr, \
_("%s: Internal Error `%s'.\n"),file,text);
#define ENOSUPP(A,B) fprintf(stderr,\
_("%s: feature `%s' not supported.\n" \
"Please recompile `net-tools' with "\
"newer kernel source or full configuration.\n"),A,B)
#define ESYSNOT(A,B) fprintf(stderr, _("%s: no support for `%s' on this system.\n"),A,B)
#define E_NOTFOUND 8
#define E_SOCK 7
#define E_LOOKUP 6
#define E_VERSION 5
#define E_USAGE 4
#define E_OPTERR 3
#define E_INTERN 2
#define E_NOSUPP 1
/* ========== Kernel Defines =============
* Since it is not a good idea to depend on special kernel sources for the headers
* and since the libc6 Headers are not always up to date, we keep a copy of the
* most often used Flags in this file. We realy need a way to keep them up-to-date.
* Perhaps anybody knows how the glibc2 folk is doing it? -ecki
*/
/* Keep this ins sync with /usr/src/linux/include/linux/rtnetlink.h */
#define RTNH_F_DEAD 1 /* Nexthop is dead (used by multipath) */
#define RTNH_F_PERVASIVE 2 /* Do recursive gateway lookup */
#define RTNH_F_ONLINK 4 /* Gateway is forced on link */
/* Keep this in sync with /usr/src/linux/include/linux/in_route.h */
#define RTCF_DEAD RTNH_F_DEAD
#define RTCF_ONLINK RTNH_F_ONLINK
/* #define RTCF_NOPMTUDISC RTM_F_NOPMTUDISC */
#define RTCF_NOTIFY 0x00010000
#define RTCF_DIRECTDST 0x00020000
#define RTCF_REDIRECTED 0x00040000
#define RTCF_TPROXY 0x00080000
#define RTCF_FAST 0x00200000
#define RTCF_MASQ 0x00400000
#define RTCF_SNAT 0x00800000
#define RTCF_DOREDIRECT 0x01000000
#define RTCF_DIRECTSRC 0x04000000
#define RTCF_DNAT 0x08000000
#define RTCF_BROADCAST 0x10000000
#define RTCF_MULTICAST 0x20000000
#define RTCF_REJECT 0x40000000
#define RTCF_LOCAL 0x80000000
/* Keep this in sync with /usr/src/linux/include/linux/ipv6_route.h */
#ifndef RTF_DEFAULT
#define RTF_DEFAULT 0x00010000 /* default - learned via ND */
#endif
#define RTF_ALLONLINK 0x00020000 /* fallback, no routers on link */
#ifndef RTF_ADDRCONF
#define RTF_ADDRCONF 0x00040000 /* addrconf route - RA */
#endif
#define RTF_NONEXTHOP 0x00200000 /* route with no nexthop */
#define RTF_EXPIRES 0x00400000
#define RTF_CACHE 0x01000000 /* cache entry */
#define RTF_FLOW 0x02000000 /* flow significant route */
#define RTF_POLICY 0x04000000 /* policy route */
#define RTF_LOCAL 0x80000000
/* Keep this in sync with /usr/src/linux/include/linux/route.h */
#define RTF_UP 0x0001 /* route usable */
#define RTF_GATEWAY 0x0002 /* destination is a gateway */
#define RTF_HOST 0x0004 /* host entry (net otherwise) */
#define RTF_REINSTATE 0x0008 /* reinstate route after tmout */
#define RTF_DYNAMIC 0x0010 /* created dyn. (by redirect) */
#define RTF_MODIFIED 0x0020 /* modified dyn. (by redirect) */
#define RTF_MTU 0x0040 /* specific MTU for this route */
#ifndef RTF_MSS
#define RTF_MSS RTF_MTU /* Compatibility :-( */
#endif
#define RTF_WINDOW 0x0080 /* per route window clamping */
#define RTF_IRTT 0x0100 /* Initial round trip time */
#define RTF_REJECT 0x0200 /* Reject route */
/* this is a 2.0.36 flag from /usr/src/linux/include/linux/route.h */
#define RTF_NOTCACHED 0x0400 /* this route isn't cached */
#ifdef HAVE_AFECONET
#ifndef AF_ECONET
#define AF_ECONET 19 /* Acorn Econet */
#endif
#endif
/* End of lib/support.h */
-156
View File
@@ -1,156 +0,0 @@
/* Copyright 1998 by Andi Kleen. Subject to the GPL. */
/* rewritten by bernd eckenfels because of complicated alias semantic */
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include "util.h"
/* return numerical :999 suffix or null. sideeffect: replace ':' with \0 */
char* cutalias(char* name)
{
int digit = 0;
int pos;
for(pos=strlen(name); pos>0; pos--)
{
if (name[pos-1]==':' && digit)
{
name[pos-1]='\0';
return name+pos;
}
if (!isdigit(name[pos-1]))
break;
digit = 1;
}
return NULL;
}
/* return index of last non digit or -1 if it does not end with digits */
int rindex_nondigit(char *name)
{
int pos = strlen(name);
for(pos=strlen(name); pos>0; pos--)
{
if (!isdigit(name[pos-1]))
return pos;
}
return 0;
}
/* like strcmp(), but knows about numbers and ':' alias suffix */
int nstrcmp(const char *ap, const char *bp)
{
char *a = (char*)strdup(ap);
char *b = (char*)strdup(bp);
char *an, *bn;
int av = 0, bv = 0;
char *aalias=cutalias(a);
char *balias=cutalias(b);
int aindex=rindex_nondigit(a);
int bindex=rindex_nondigit(b);
int complen=(aindex<bindex)?aindex:bindex;
int res = strncmp(a, b, complen);
if (res != 0)
{ free(a); free(b); return res; }
if (aindex > bindex)
{ free(a); free(b); return 1; }
if (aindex < bindex)
{ free(a); free(b); return -1; }
an = a+aindex;
bn = b+bindex;
av = atoi(an);
bv = atoi(bn);
if (av < bv)
{ free(a); free(b); return -1; }
if (av > bv)
{ free(a); free(b); return 1; }
av = -1;
if (aalias != NULL)
av = atoi(aalias);
bv = -1;
if (balias != NULL)
bv = atoi(balias);
free(a); free(b);
if (av < bv)
return -1;
if (av > bv)
return 1;
return 0;
}
#ifdef NSTRCMP_TEST
int cs(int s)
{
if (s < 0) return -1;
if (s > 0) return 1;
return 0;
}
int dotest(char* a, char* b, int exp)
{
int res = nstrcmp(a, b);
int err = (cs(res) != cs(exp));
printf("nstrcmp(\"%s\", \"%s\")=%d %d %s\n", a, b, res, exp, err?"WRONG":"OK");
return err;
}
int main()
{
int err = 0;
err |= dotest("eth1", "eth1", 0);
err |= dotest("eth0:1", "eth0:1", 0);
err |= dotest("lan", "lan", 0);
err |= dotest("100", "100", 0);
err |= dotest("", "", 0);
err |= dotest(":", ":", 0);
err |= dotest("a:b:c", "a:b:c", 0);
err |= dotest("a:", "a:", 0);
err |= dotest(":a", ":a", 0);
err |= dotest("a", "aa", -1);
err |= dotest("eth0", "eth1", -1);
err |= dotest("eth1", "eth20", -1);
err |= dotest("eth20", "eth100", -1);
err |= dotest("eth1", "eth13", -1);
err |= dotest("eth", "eth2", -1);
err |= dotest("eth0:1", "eth0:2", -1);
err |= dotest("eth1:10", "eth13:10", -1);
err |= dotest("eth1:1", "eth1:13", -1);
err |= dotest("a", "a:", -1);
err |= dotest("aa", "a", 1);
err |= dotest("eth2", "eth1", 1);
err |= dotest("eth13", "eth1", 1);
err |= dotest("eth2", "eth", 1);
err |= dotest("eth2:10", "eth2:1", 1);
err |= dotest("eth2:5", "eth2:4", 1);
err |= dotest("eth3:2", "eth2:3", 1);
err |= dotest("eth13:1", "eth1:0", 1);
err |= dotest("a:", "a", 1);
err |= dotest("a1b12", "a1b2", 1);
return err;
}
#endif
-52
View File
@@ -1,52 +0,0 @@
/*
* lib/pathnames.h This file contains the definitions of the path
* names used by the NET-LIB.
*
* NET-LIB
*
* Version: lib/pathnames.h 1.37 (1997-08-23)
*
* Author: Fred N. van Kempen, <waltje@uwalt.nl.mugnet.org>
*/
/* pathnames of the procfs files used by NET. */
#define _PATH_PROCNET_IGMP "/proc/net/igmp"
#define _PATH_PROCNET_IGMP6 "/proc/net/igmp6"
#define _PATH_PROCNET_TCP "/proc/net/tcp"
#define _PATH_PROCNET_TCP6 "/proc/net/tcp6"
#define _PATH_PROCNET_UDP "/proc/net/udp"
#define _PATH_PROCNET_UDP6 "/proc/net/udp6"
#define _PATH_PROCNET_RAW "/proc/net/raw"
#define _PATH_PROCNET_RAW6 "/proc/net/raw6"
#define _PATH_PROCNET_UNIX "/proc/net/unix"
#define _PATH_PROCNET_ROUTE "/proc/net/route"
#define _PATH_PROCNET_ROUTE6 "/proc/net/ipv6_route"
#define _PATH_PROCNET_RTCACHE "/proc/net/rt_cache"
#define _PATH_PROCNET_AX25_ROUTE "/proc/net/ax25_route"
#define _PATH_PROCNET_NR "/proc/net/nr"
#define _PATH_PROCNET_NR_NEIGH "/proc/net/nr_neigh"
#define _PATH_PROCNET_NR_NODES "/proc/net/nr_nodes"
#define _PATH_PROCNET_ARP "/proc/net/arp"
#define _PATH_PROCNET_AX25 "/proc/net/ax25"
#define _PATH_PROCNET_IPX "/proc/net/ipx"
#define _PATH_PROCNET_IPX_ROUTE "/proc/net/ipx_route"
#define _PATH_PROCNET_ATALK "/proc/net/appletalk"
#define _PATH_PROCNET_IP_BLK "/proc/net/ip_block"
#define _PATH_PROCNET_IP_FWD "/proc/net/ip_forward"
#define _PATH_PROCNET_IP_ACC "/proc/net/ip_acct"
#define _PATH_PROCNET_IP_MASQ "/proc/net/ip_masquerade"
#define _PATH_PROCNET_NDISC "/proc/net/ndisc"
#define _PATH_PROCNET_IFINET6 "/proc/net/if_inet6"
#define _PATH_PROCNET_DEV "/proc/net/dev"
#define _PATH_PROCNET_RARP "/proc/net/rarp"
#define _PATH_ETHERS "/etc/ethers"
#define _PATH_PROCNET_ROSE_ROUTE "/proc/net/rose_routes"
#define _PATH_PROCNET_X25 "/proc/net/x25"
#define _PATH_PROCNET_X25_ROUTE "/proc/net/x25_routes"
#define _PATH_PROCNET_DEV_MCAST "/proc/net/dev_mcast"
#define _PATH_PROCNET_ATALK_ROUTE "/proc/net/atalk_route"
/* pathname for the netlink device */
#define _PATH_DEV_ROUTE "/dev/route"
/* End of pathnames.h */
-56
View File
@@ -1,56 +0,0 @@
/*
* lib/ppp.c This file contains the SLIP support for the NET-2 base
* distribution.
*
* Version: $Id$
*
* Author: Fred N. van Kempen, <waltje@uwalt.nl.mugnet.org>
* Copyright 1993 MicroWalt Corporation
*
* Modified by Alan Cox, May 94 to cover NET-3
*
* Changes:
* 980701 {1.12} Arnaldo Carvalho de Melo - GNU gettext instead of catgets
*
* 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.
*/
#include "config.h"
#if HAVE_HWPPP
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <net/if_arp.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>
#include "net-support.h"
#include "pathnames.h"
#include "intl.h"
/* Start the PPP encapsulation on the file descriptor. */
static int do_ppp(int fd)
{
fprintf(stderr, _("You cannot start PPP with this program.\n"));
return -1;
}
struct hwtype ppp_hwtype =
{
"ppp", NULL, /*"Point-Point Protocol", */ ARPHRD_PPP, 0,
NULL, NULL, do_ppp, 0
};
#endif /* HAVE_PPP */
-5
View File
@@ -1,5 +0,0 @@
/* Generate a suitable scanf format for a column title line */
char *proc_gen_fmt(char *name, int more, FILE * fh,...);
int proc_guess_fmt(char *name, FILE* fh,...);
-25
View File
@@ -1,25 +0,0 @@
#!/bin/sh
### MyHalt ###
#
# used by interfacedemo for "pyramid" LCD device.
#
# Copyright (C) 2005 Silvan Marco Fin <silvan@kernelconcepts.de>
#
# 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
# 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
#
echo -e "Externel halt-script calld: Halt requested, simulating halt."
-24
View File
@@ -1,24 +0,0 @@
#!/bin/sh
### MyIpSet ###
#
# used by interfacedemo for "pyramid" LCD device.
#
# Copyright (C) 2005 Silvan Marco Fin <silvan@kernelconcepts.de>
#
# 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
# 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
#
echo -e "External Skript to configure interface called for: $1 set to\nIP: $2\nNetmask: $3\nGateway: $4"

Some files were not shown because too many files have changed in this diff Show More