Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6da7c51d22 |
@@ -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
@@ -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
|
||||
@@ -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.
|
||||
@@ -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...
|
||||
@@ -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.
|
||||
@@ -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.
|
||||
@@ -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.
|
||||
-55
@@ -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
|
||||
@@ -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.
|
||||
@@ -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
File diff suppressed because it is too large
Load Diff
-53
@@ -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
|
||||
@@ -1,2 +0,0 @@
|
||||
Makefile
|
||||
Makefile.in
|
||||
@@ -1,5 +0,0 @@
|
||||
## Process this file with automake to produce Makefile.in
|
||||
|
||||
SUBDIRS = examples lcdexec lcdproc lcdvc metar
|
||||
|
||||
## EOF
|
||||
@@ -1,2 +0,0 @@
|
||||
Makefile
|
||||
Makefile.in
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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__
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -1,4 +0,0 @@
|
||||
.deps
|
||||
Makefile
|
||||
Makefile.in
|
||||
lcdexec
|
||||
@@ -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
|
||||
@@ -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 */
|
||||
@@ -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
|
||||
@@ -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 */
|
||||
@@ -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
|
||||
@@ -1,4 +0,0 @@
|
||||
.deps
|
||||
Makefile
|
||||
Makefile.in
|
||||
lcdproc
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
#ifndef BATT_H
|
||||
#define BATT_H
|
||||
|
||||
int battery_screen(int rep, int display, int *flags_ptr);
|
||||
|
||||
#endif
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -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() */
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
#ifndef CPU_SMP_H
|
||||
#define CPU_SMP_H
|
||||
|
||||
int cpu_smp_screen(int rep, int display, int *flags_ptr);
|
||||
|
||||
#endif
|
||||
@@ -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;
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
#ifndef DISK_H
|
||||
#define DISK_H
|
||||
|
||||
int disk_screen(int rep, int display, int *flags_ptr);
|
||||
|
||||
#endif
|
||||
@@ -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 */
|
||||
}
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
#ifndef CTRL_H
|
||||
#define CTRL_H
|
||||
|
||||
int eyebox_screen(char display, int init);
|
||||
void eyebox_clear(void);
|
||||
|
||||
#endif
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
@@ -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_ */
|
||||
@@ -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__ */
|
||||
@@ -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__ */
|
||||
@@ -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 */
|
||||
@@ -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__ */
|
||||
@@ -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__ */
|
||||
@@ -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 */
|
||||
@@ -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 */
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -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 */
|
||||
@@ -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
|
||||
@@ -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 */
|
||||
@@ -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
|
||||
@@ -1,4 +0,0 @@
|
||||
.deps
|
||||
Makefile
|
||||
Makefile.in
|
||||
lcdvc
|
||||
@@ -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
|
||||
@@ -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");
|
||||
}
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -1,2 +0,0 @@
|
||||
Makefile
|
||||
Makefile.in
|
||||
@@ -1,7 +0,0 @@
|
||||
## Process this file with automake to produce Makefile.in
|
||||
|
||||
bin_SCRIPTS = lcdmetar.pl
|
||||
|
||||
EXTRA_DIST = $(bin_SCRIPTS)
|
||||
|
||||
## EOF
|
||||
@@ -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
@@ -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
|
||||
@@ -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}
|
||||
|
||||
@@ -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
|
||||
@@ -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");
|
||||
}
|
||||
@@ -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 */
|
||||
@@ -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
|
||||
|
||||
@@ -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 */
|
||||
@@ -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 */
|
||||
@@ -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
|
||||
ðer_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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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 */
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
};
|
||||
@@ -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 */
|
||||
|
||||
@@ -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
|
||||
@@ -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 */
|
||||
@@ -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 */
|
||||
@@ -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,...);
|
||||
@@ -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."
|
||||
|
||||
@@ -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
Reference in New Issue
Block a user