From 3cfc218cb5679f381abfa34adab0298a4a56d8b2 Mon Sep 17 00:00:00 2001 From: fritz Date: Sun, 2 Mar 1997 19:41:56 +0000 Subject: [PATCH] Tons of changes. New toplevel Makefile added xisdnload, xmonisdn, toplevel config for isdnload Added new interactive configuration utility using lxdialog. Some adaptions for existing packages. Some corrections in man pages. --- Makefile | 165 ++++- README | 33 +- doc/Configure.help | 130 ++++ doc/Makefile.in | 9 +- icn/Makefile.in | 15 +- icn/icnctrl.man.in | 6 +- imon/Makefile.in | 12 +- iprofd/Makefile.in | 12 +- isdnctrl/Makefile.in | 18 +- isdnlog/Config.in | 12 + pcbit/Makefile.in | 12 +- scripts/Menuconfig | 1138 ++++++++++++++++++++++++++++++ scripts/README.Menuconfig | 184 +++++ scripts/config.in | 57 ++ scripts/defconfig | 45 ++ scripts/lxdialog/BIG.FAT.WARNING | 4 + scripts/lxdialog/Makefile | 46 ++ scripts/lxdialog/checklist.c | 344 +++++++++ scripts/lxdialog/colors.h | 161 +++++ scripts/lxdialog/dialog.h | 166 +++++ scripts/lxdialog/inputbox.c | 232 ++++++ scripts/lxdialog/lxdialog.c | 223 ++++++ scripts/lxdialog/menubox.c | 350 +++++++++ scripts/lxdialog/msgbox.c | 77 ++ scripts/lxdialog/textbox.c | 537 ++++++++++++++ scripts/lxdialog/util.c | 359 ++++++++++ scripts/lxdialog/yesno.c | 110 +++ teles/Makefile.in | 67 +- vbox/Config.in | 8 + vbox/Makefile.in | 8 +- xisdnload/Imakefile | 33 + xisdnload/Makefile.in | 39 + xisdnload/XISDNLoad.ad | 10 + xisdnload/xisdnload.bit | 14 + xisdnload/xisdnload.c | 406 +++++++++++ xisdnload/xisdnload.man | 100 +++ xmonisdn/Imakefile | 17 + xmonisdn/Makefile.in | 61 ++ xmonisdn/Net.c | 743 +++++++++++++++++++ xmonisdn/Net.h | 46 ++ xmonisdn/NetP.h | 59 ++ xmonisdn/README | 68 ++ xmonisdn/netactive | 28 + xmonisdn/netactiveout | 28 + xmonisdn/netinactive | 28 + xmonisdn/netstart | 28 + xmonisdn/netstop | 28 + xmonisdn/netwaiting | 28 + xmonisdn/xmonisdn.c | 94 +++ xmonisdn/xmonisdn.man | 204 ++++++ 50 files changed, 6508 insertions(+), 94 deletions(-) create mode 100644 doc/Configure.help create mode 100644 isdnlog/Config.in create mode 100755 scripts/Menuconfig create mode 100644 scripts/README.Menuconfig create mode 100644 scripts/config.in create mode 100644 scripts/defconfig create mode 100644 scripts/lxdialog/BIG.FAT.WARNING create mode 100644 scripts/lxdialog/Makefile create mode 100644 scripts/lxdialog/checklist.c create mode 100644 scripts/lxdialog/colors.h create mode 100644 scripts/lxdialog/dialog.h create mode 100644 scripts/lxdialog/inputbox.c create mode 100644 scripts/lxdialog/lxdialog.c create mode 100644 scripts/lxdialog/menubox.c create mode 100644 scripts/lxdialog/msgbox.c create mode 100644 scripts/lxdialog/textbox.c create mode 100644 scripts/lxdialog/util.c create mode 100644 scripts/lxdialog/yesno.c create mode 100644 vbox/Config.in create mode 100644 xisdnload/Imakefile create mode 100644 xisdnload/Makefile.in create mode 100644 xisdnload/XISDNLoad.ad create mode 100644 xisdnload/xisdnload.bit create mode 100644 xisdnload/xisdnload.c create mode 100644 xisdnload/xisdnload.man create mode 100644 xmonisdn/Imakefile create mode 100644 xmonisdn/Makefile.in create mode 100644 xmonisdn/Net.c create mode 100644 xmonisdn/Net.h create mode 100644 xmonisdn/NetP.h create mode 100644 xmonisdn/README create mode 100644 xmonisdn/netactive create mode 100644 xmonisdn/netactiveout create mode 100644 xmonisdn/netinactive create mode 100644 xmonisdn/netstart create mode 100644 xmonisdn/netstop create mode 100644 xmonisdn/netwaiting create mode 100644 xmonisdn/xmonisdn.c create mode 100644 xmonisdn/xmonisdn.man diff --git a/Makefile b/Makefile index 8e959df6..84ea7f77 100644 --- a/Makefile +++ b/Makefile @@ -1,53 +1,139 @@ -# $Id: Makefile,v 1.3 1997/02/22 14:58:02 fritz Exp $ +# $Id: Makefile,v 1.4 1997/03/02 19:41:56 fritz Exp $ # # Toplevel Makefile for isdn4k-utils # -export I4LVERSION=2.1 -export I4LCONFDIR=/etc/isdn +#.EXPORT_ALL_VARIABLES: -SUBDIRS=`find . -type d -maxdepth 1` +export I4LVERSION = 2.1 -all: - @set -e; allow_null_glob_expansion=1; \ - NOMAKE=true; \ - for i in */Makefile ; do \ - $(MAKE) -C `dirname $$i` all; \ - NOMAKE=false; \ - done; \ - if $$NOMAKE ; then \ - echo 'Please configure the package with "make config" first!'; \ +all: do-it-all + +# +# Make "config" the default target if there is no configuration file. +# +ifeq (.config,$(wildcard .config)) +include .config +do-it-all: subtargets +else +CONFIGURATION = config +do-it-all: config +endif + +SUBDIRS = #lib +ifeq ($(CONFIG_ISDNCTRL),y) + SUBDIRS := $(SUBDIRS) isdnctrl +endif +ifeq ($(CONFIG_IPROFD),y) + SUBDIRS := $(SUBDIRS) iprofd +endif +ifeq ($(CONFIG_ICNCTRL),y) + SUBDIRS := $(SUBDIRS) icn +endif +ifeq ($(CONFIG_PCBITCTL),y) + SUBDIRS := $(SUBDIRS) pcbit +endif +ifeq ($(CONFIG_TELESCTRL),y) + SUBDIRS := $(SUBDIRS) teles +else + ifeq ($(CONFIG_HISAXCTRL),y) + SUBDIRS := $(SUBDIRS) teles + endif +endif +ifeq ($(CONFIG_IMON),y) + SUBDIRS := $(SUBDIRS) imon +endif +ifeq ($(CONFIG_AREACODE),y) + SUBDIRS := $(SUBDIRS) areacode +endif +ifeq ($(CONFIG_ISDNLOG),y) + SUBDIRS := $(SUBDIRS) isdnlog +endif +ifeq ($(CONFIG_XMONISDN),y) + SUBDIRS := $(SUBDIRS) xmonisdn +endif +ifeq ($(CONFIG_XISDNLOAD),y) + SUBDIRS := $(SUBDIRS) xisdnload +endif +ifeq ($(CONFIG_VBOX),y) + SUBDIRS := $(SUBDIRS) vbox +endif +ifeq ($(CONFIG_GENMAN),y) + SUBDIRS := $(SUBDIRS) doc +endif +ifeq ($(CONFIG_FAQ),y) + SUBDIRS := $(SUBDIRS) FAQ +endif + +subtargets: $(CONFIGURATION) + set -e; for i in $(SUBDIRS); do $(MAKE) -C $$i all; done + +rootperm: + @if [ `id -u` != 0 ] ; then \ + echo -e "\n\n Need root permission for installation!\n\n"; \ + exit 1; \ fi -install: - @set -e; allow_null_glob_expansion=1; \ - for i in */Makefile ; do \ - $(MAKE) -C `dirname $$i` install ;\ - done +install: rootperm + set -e; for i in $(SUBDIRS); do $(MAKE) -C $$i install; done -uninstall: - @set -e; allow_null_glob_expansion=1; \ - for i in */Makefile ; do \ - $(MAKE) -C `dirname $$i` uninstall ;\ - done +uninstall: rootperm + set -e; for i in $(SUBDIRS); do $(MAKE) -C $$i uninstall; done +# +# targets clean and distclean go through ALL directories +# regardless of cofigured options. +# clean: - @set -e; allow_null_glob_expansion=1; \ - for i in */Makefile ; do \ - $(MAKE) -C `dirname $$i` clean ;\ - done - @ rm -f *~ + -$(MAKE) -C scripts/lxdialog clean + -set -e; allow_null_glob_expansion=1; \ + for i in */Makefile; do $(MAKE) -i -C `dirname $$i` clean; done + rm -f *~ *.o distclean: clean - @set -e; allow_null_glob_expansion=1; \ - for i in */Makefile ; do \ - $(MAKE) -C `dirname $$i` distclean ;\ + -set -e; allow_null_glob_expansion=1; \ + for i in */Makefile; do $(MAKE) -i -C `dirname $$i` distclean; done + rm -f *~ .config .config.old scripts/autoconf.h .menuconfig \ + Makefile.tmp .menuconfig.log + +scripts/lxdialog/lxdialog: + @$(MAKE) -C scripts/lxdialog all + +# +# Next target makes three attempts to configure: +# - if a Makefile already exists, make config +# - if a configure script exists, execute it +# - if a Makefile.in exists, make -f Makefile.in config +# +subconfig: + @echo Selected subdirs: $(SUBDIRS) + @set -e; for i in $(SUBDIRS); do \ + if [ -f $$i/Makefile ] ; then \ + echo -e "\nRunning make config in $$i ...\n"; sleep 1; \ + $(MAKE) -C $$i config; \ + else \ + if [ -x $$i/configure ] ; then \ + echo -e "\nRunning configure in $$i ...\n"; sleep 1; \ + (cd $$i; ./configure); \ + else \ + if [ -f $$i/Makefile.in ] ; then \ + echo -e "\nRunning make -f Makefile.in config in $$i ...\n"; sleep 1; \ + $(MAKE) -C $$i -f Makefile.in config; \ + fi; \ + fi; \ + fi; \ done -config: - @set -e; allow_null_glob_expansion=1; \ - for i in */Makefile.in ; do \ - $(MAKE) -C `dirname $$i` -f Makefile.in config ;\ - done +# +# Next target uses a second tempory Makefile +# because new .config has to be re-included. +# +menuconfig: scripts/lxdialog/lxdialog + @scripts/Menuconfig scripts/config.in + @cp Makefile Makefile.tmp + $(MAKE) -f Makefile.tmp subconfig + @rm -f Makefile.tmp + +config: menuconfig mrproper: distclean @@ -56,3 +142,10 @@ archive: distclean mv isdn4k-utils isdn4k-utils-$(I4LVERSION) ;\ tar cvzf distisdn/isdn4k-utils-$(I4LVERSION).tar.gz isdn4k-utils-$(I4LVERSION) ;\ mv isdn4k-utils-$(I4LVERSION) isdn4k-utils ) + +distarch: distclean + @(cd .. ;\ + mv isdn4k-utils isdn4k-utils-$(I4LVERSION) ;\ + tar -cvzf --exclude=CVS distisdn/isdn4k-utils-$(I4LVERSION).tar.gz \ + isdn4k-utils-$(I4LVERSION) ;\ + mv isdn4k-utils-$(I4LVERSION) isdn4k-utils ) diff --git a/README b/README index c354262c..4e7baa5f 100644 --- a/README +++ b/README @@ -1,17 +1,21 @@ # -# $Id: README,v 1.2 1997/02/22 14:46:09 fritz Exp $ +# $Id: README,v 1.3 1997/03/02 19:41:57 fritz Exp $ # This is the README file for the "isdn4k-utils" package from "The i4l-crew". -This package contains the following utilities: +This package contains the following stuff: - isdnctrl, general link-level setup utility. - icnctrl, setup utility for the icn driver. - telesctrl, setup utility for the teles and HiSax driver. - pcbitctl, setup utility for the pcbit driver. - imon, a tty based utility for monitoring ISDN-activities. - isdnlog, a set of utilities for connection logging. - isdnmon, a Tcl/Tk based utility for monitoring ISDN-activities. + isdnctrl, general link-level setup utility. + icnctrl, setup utility for the icn driver. + telesctrl, setup utility for the teles driver. + hisaxctrl, setup utility for the HiSax driver. + pcbitctl, setup utility for the pcbit driver. + imon, a ncurses based utility for monitoring ISDN-activities. + imontty, a tty based utility for monitoring ISDN-activities. + isdnlog, a set of utilities for connection logging. + xmonisdn, a utility for monitoring and controlling ISDN-activity. + xisdnload, an xload-like meter. + isdnmon, a Tcl/Tk based utility for monitoring ISDN-activities. System prerequisites: @@ -31,14 +35,11 @@ System prerequisites: Run "make config" - This will run various configuration-scripts for each sub-package. + This will run an interactive configuration tool and the various + configuration-scripts for each sub-package. (You may know that + tool from kernel menuconfig.) There is a global configuration directory, where most programs - expect their configuration files. The default is /etc/isdn. If - you prefer a different directory, run - - "make I4LCONFDIR=/what/ever/you/want config" - - instead of the above. + expect their configuration files. The default is /etc/isdn. Run "make" diff --git a/doc/Configure.help b/doc/Configure.help new file mode 100644 index 00000000..872ea483 --- /dev/null +++ b/doc/Configure.help @@ -0,0 +1,130 @@ +# +# This file is boorwed from the kernel configuration. +# +# Format of this file: descriptionvariablehelptext. +# If the question being documented is of type "choice", we list +# only the first occurring config variable. The help texts +# must not contain empty lines. No variable should occur twice; if it +# does, only the first occurrence will be used by Configure. The lines +# in a help text should be indented two positions. Lines starting with +# `#' are ignored. To be nice to menuconfig, limit your lines to 70 +# characters. Use emacs' kfill.el to edit this file or you lose. +# +Prompt for development and/or incomplete code +CONFIG_EXPERIMENTAL + Some of the programs in this package may be incomplete or + instable. + Unless you intend to help test and develop a feature that + falls into this category, or you have a situation that requires + using these features you should probably say N here, which will + cause this configure script to present you with fewer choices. If + you say Y here, you will be offered the choice of using features or + that are currently considered to be in the alpha-test phase. + +General configuration directory +CONFIG_I4LCONFDIR + Some of the programs in this package need global configuration + files. This option tells them where to expect these files. + During installation, some sample files may be installed there + also. + +Directory to install binaries +CONFIG_BINDIR + This option tells the installation process, where to put those + programs which are usable for ordinary users. The administrative + programs (those, which are intended for configuration) are + installed in another directory, configurable in the next option. + +Directory to install administrative binaries +CONFIG_SBINDIR + This option tess the installation process, where to put the + administrative programs. All other programs are installed in + another directory, configurable in the previous option. + +Directory to install man pages +CONFIG_MANDIR + This option tells the installation process, where to put the + man pages. This is usually /usr/man or /usr/local/man. The + man pages go into some subdirectory below this directory + depending on the section they belong to. + +Build isdnctrl tool +CONFIG_ISDNCTRL + This program is the main configuration utility for all linklevel + related configuration such as net-devices, mapping, encapsulation + etc. This program is documented in isdnctrl (8). + +Enable debugging features of isdnctrl +CONFIG_ISDNCTRL_DEBUG + If enabled, a special feature 'debug' is available with isdnctrl. + With this feature, isdnctrl is able to dump internal data structures + of the linklevel part. This feature may be helpful when debugging + drivers or the linklevel itself. + +Build iprofd +CONFIG_IPROFD + If enabled, iprofd, a special daemon will be built. This daemon is + used to permanently store profile data from the modem emulator + into a file whenever an AT&W0 command is given on any ttyI. It also + reads this file on startup and initializes the profile from its + contents. + This program is documented in iprofd (8). + +Build telesctrl +CONFIG_TELESCTRL + This program is used to configure the teles driver (mainly debugging + options). For the HiSax driver, there is another tool, called + hisaxctrl. These are essentially the same binary, just with a + different name. + This program is documented in telesctrl (8). + +Build hisaxctrl +CONFIG_HISAXCTRL + This program is used to configure the HiSax driver (mainly debugging + options). For the teles driver, there is another tool, called + telesctrl. These are essentially the same binary, just with a + different name. + This program is documented in hisaxctrl (8). + +Build icnctrl +CONFIG_ICNCTRL + This program is used to configure the ICN driver. With tis tool, you + can add cards, download protocol firmware into cards and configure + ports, memory, leased-line mode etc. + This program is documented in icnctrl (8). + +Enable debugging features of icnctrl +CONFIG_ICNCTRL_DEBUG + If enabled, a special feature 'debug' is available with icnctrl. + With this feature, icnctrl is able to dump internal data structures + of the ICN driver. This feature may be helpful when debugging + the ICN driver. + +Build pcbitctl +CONFIG_PCBITCTL + This program is used to configure the pcbit driver. With this tool, you + can download protocol firmware into cards. + This program is documented in pcbitctl (8). + +Build imon +CONFIG_IMON + This is a userlevel program to monitor the activity of isdn4linux. + It is tty based and uses ncurses to produce a nice screen. + This program is documented in imon (1). + +Install generic man pages +CONFIG_GENMAN + If enabled, in addition to the tool's man pages, the following generic + man pages are installed: + isdninfo.4 ttyI.4 cui.4 isdn_audio.4 isdn_cause.7 + +Generate FAQ +CONFIG_FAQ + If enabled, the FAQ, available as html both unpacked and packed with + zip and gzip are generated. The FAQ is available in English and German. + +Wher to install the FAQ +CONFIG_FAQDIR + Here you can tell where to put the FAQ. + +# need an empty line after last entry, for sed script in Configure. diff --git a/doc/Makefile.in b/doc/Makefile.in index 2ad4864a..30ad44ba 100644 --- a/doc/Makefile.in +++ b/doc/Makefile.in @@ -1,4 +1,4 @@ -# $Id: Makefile.in,v 1.4 1997/02/26 20:05:30 fritz Exp $ +# $Id: Makefile.in,v 1.5 1997/03/02 19:42:02 fritz Exp $ # # Makefile for ISDN manpages # (C) 1997 Fritz Elfert @@ -10,7 +10,12 @@ SED = @SED@ MANPAGES = ttyI.4 isdninfo.4 isdn_audio.4 isdn_cause.7 INSTALL_MAN = @INSTALL@ -o 0 -g 0 -m 0644 prefix = @prefix@ -mandir = @mandir@ +ifeq (../.config,$(wildcard ../.config)) + include ../.config + mandir = $(CONFIG_MANDIR) +else + mandir = @mandir@ +endif %.4: %.man MANDATE=`grep CHECKIN $< | $(AWK) '{print $$4}'`; \ diff --git a/icn/Makefile.in b/icn/Makefile.in index 693c387a..67aa7e61 100644 --- a/icn/Makefile.in +++ b/icn/Makefile.in @@ -1,4 +1,4 @@ -# $Id: Makefile.in,v 1.2 1997/02/22 14:14:43 fritz Exp $ +# $Id: Makefile.in,v 1.3 1997/03/02 19:42:06 fritz Exp $ # # Makefile for icnctrl # (C) 1997 Fritz Elfert @@ -15,8 +15,17 @@ INSTALL_PROGRAM = $(INSTALL) -o 0 -g 0 -m 0750 INSTALL_MAN = $(INSTALL) -o 0 -g 0 -m 0644 prefix = @prefix@ exec_prefix = @exec_prefix@ -SBINDIR = /sbin -mandir = @mandir@ +ifeq (../.config,$(wildcard ../.config)) + include ../.config + ifeq ($(CONFIG_ICNCTRL_DEBUG),y) + CFLAGS += -DDEBUGVAR + endif + SBINDIR = $(CONFIG_SBINDIR) + mandir = $(CONFIG_MANDIR) +else + SBINDIR = /sbin + mandir = @mandir@ +endif MAN8DIR = $(mandir)/man8 CC = @CC@ diff --git a/icn/icnctrl.man.in b/icn/icnctrl.man.in index d0713cf6..07de9abd 100644 --- a/icn/icnctrl.man.in +++ b/icn/icnctrl.man.in @@ -1,6 +1,6 @@ -.\" $Id: icnctrl.man.in,v 1.3 1997/02/22 14:14:00 fritz Exp $ +.\" $Id: icnctrl.man.in,v 1.4 1997/03/02 19:42:07 fritz Exp $ .\" -.\" CHECKIN $Date: 1997/02/22 14:14:00 $ +.\" CHECKIN $Date: 1997/03/02 19:42:07 $ .\" .\" Process this file with .\" groff -man -Tascii icnctrl.1 for ASCII output, or @@ -152,7 +152,7 @@ firmware parameters have to be supplied. The first firmware is used for the upper S0 connector, the second firmware is used for the lower S0 connector (towards the card's slot connector). .TP -dump +.B dump is available if the program is configured using the .B --enable-dump option only. The contents of internal driver variables is dumped on stdout. diff --git a/imon/Makefile.in b/imon/Makefile.in index 3c5a9e62..a5093412 100644 --- a/imon/Makefile.in +++ b/imon/Makefile.in @@ -1,4 +1,4 @@ -# $Id: Makefile.in,v 1.1 1997/02/17 00:08:58 fritz Exp $ +# $Id: Makefile.in,v 1.2 1997/03/02 19:42:12 fritz Exp $ # # Makefile for iMON # @@ -18,8 +18,14 @@ INSTALL_PROGRAM = $(INSTALL) -o 0 -g 0 -m 0750 INSTALL_MAN = $(INSTALL) -o 0 -g 0 -m 0644 prefix = @prefix@ exec_prefix = @exec_prefix@ -SBINDIR = /sbin -mandir = @mandir@ +ifeq (../.config,$(wildcard ../.config)) + include ../.config + SBINDIR = $(CONFIG_SBINDIR) + mandir = $(CONFIG_MANDIR) +else + SBINDIR = /sbin + mandir = @mandir@ +endif MAN8DIR = $(mandir)/man8 CC = @CC@ diff --git a/iprofd/Makefile.in b/iprofd/Makefile.in index 019cb49e..1de2866e 100644 --- a/iprofd/Makefile.in +++ b/iprofd/Makefile.in @@ -1,4 +1,4 @@ -# $Id: Makefile.in,v 1.1 1997/02/17 00:09:08 fritz Exp $ +# $Id: Makefile.in,v 1.2 1997/03/02 19:42:16 fritz Exp $ # # Makefile for iprofd # (C) 1997 Fritz Elfert @@ -15,8 +15,14 @@ INSTALL_PROGRAM = $(INSTALL) -o 0 -g 0 -m 0750 INSTALL_MAN = $(INSTALL) -o 0 -g 0 -m 0644 prefix = @prefix@ exec_prefix = @exec_prefix@ -SBINDIR = /sbin -mandir = @mandir@ +ifeq (../.config,$(wildcard ../.config)) + include ../.config + SBINDIR = $(CONFIG_SBINDIR) + mandir = $(CONFIG_MANDIR) +else + SBINDIR = /sbin + mandir = @mandir@ +endif MAN8DIR = $(mandir)/man8 CC = @CC@ diff --git a/isdnctrl/Makefile.in b/isdnctrl/Makefile.in index ff1c4022..f450a7d4 100644 --- a/isdnctrl/Makefile.in +++ b/isdnctrl/Makefile.in @@ -1,4 +1,4 @@ -# $Id: Makefile.in,v 1.1 1997/02/17 00:09:17 fritz Exp $ +# $Id: Makefile.in,v 1.2 1997/03/02 19:42:21 fritz Exp $ # # Makefile for iprofd # (C) 1997 Fritz Elfert @@ -13,12 +13,18 @@ MANPAGE = isdnctrl.8 INSTALL = @INSTALL@ INSTALL_PROGRAM = $(INSTALL) -o 0 -g 0 -m 0750 INSTALL_MAN = $(INSTALL) -o 0 -g 0 -m 0644 +CC = @CC@ prefix = @prefix@ exec_prefix = @exec_prefix@ -SBINDIR = /sbin -mandir = @mandir@ +ifeq (../.config,$(wildcard ../.config)) + include ../.config + SBINDIR = $(CONFIG_SBINDIR) + mandir = $(CONFIG_MANDIR) +else + SBINDIR = /sbin + mandir = @mandir@ +endif MAN8DIR = $(mandir)/man8 -CC = @CC@ .SUFFIXES: .SUFFIXES: .c .o @@ -32,13 +38,15 @@ $(PROGRAM): $(MODULES) $(CC) $(CFLAGS) $? $(LDFLAGS) -o $@ install-man: isdnctrl.man - mkdir -p $(MAN8DIR) + $(INSTALL) -d $(MAN8DIR) $(INSTALL_MAN) $< $(MAN8DIR)/$(MANPAGE) install: $(PROGRAM) install-man + $(INSTALL) -d $(SBINDIR) $(INSTALL_PROGRAM) $(PROGRAM) $(SBINDIR)/$(PROGRAM) install-strip: $(PROGRAM) + $(INSTALL) -d $(SBINDIR) $(INSTALL_PROGRAM) -s $(PROGRAM) $(SBINDIR)/$(PROGRAM) uninstall: diff --git a/isdnlog/Config.in b/isdnlog/Config.in new file mode 100644 index 00000000..e7e200a5 --- /dev/null +++ b/isdnlog/Config.in @@ -0,0 +1,12 @@ +mainmenu_option next_comment +comment 'Options for isdnlog package' +string 'Old config directory' CONFIG_ISDNLOG_OLDI4LCONFDIR '/etc/isdnlog' +string 'Old config file' CONFIG_ISDNLOG_OLDI4LCONFFILE 'isdnlog.conf' +bool 'Use AreaCode by uz@musoftware.com' CONFIG_ISDNLOG_AREACODE +bool 'Support postgres95 SQL-Database' CONFIG_ISDNLOG_POSTGRES +bool 'Support for old isdn4linux' CONFIG_ISDNLOG_OLD_I4L +choice 'Country specific chargeinfo support' \ + "DE CONFIG_ISDNLOG_DE \ + NL CONFIG_ISDNLOG_NL \ + CH CONFIG_ISDNLOG_CH" DE +endmenu diff --git a/pcbit/Makefile.in b/pcbit/Makefile.in index da4669d2..a49425a7 100644 --- a/pcbit/Makefile.in +++ b/pcbit/Makefile.in @@ -1,4 +1,4 @@ -# $Id: Makefile.in,v 1.1 1997/02/17 00:09:27 fritz Exp $ +# $Id: Makefile.in,v 1.2 1997/03/02 19:42:29 fritz Exp $ # # Makefile for pcbitctl # (C) 1997 Fritz Elfert @@ -15,8 +15,13 @@ INSTALL_PROGRAM = $(INSTALL) -o 0 -g 0 -m 0750 INSTALL_MAN = $(INSTALL) -o 0 -g 0 -m 0644 prefix = @prefix@ exec_prefix = @exec_prefix@ -SBINDIR = /sbin -mandir = @mandir@ +ifeq (../.config,$(widcard ../.config)) + SBINDIR = $(CONFIG_SBINDIR) + mandir = $(CONFIG_MANDIR) +else + SBINDIR = /sbin + mandir = @mandir@ +endif MAN8DIR = $(mandir)/man8 CC = @CC@ @@ -55,4 +60,3 @@ clean: distclean: clean rm -f config.status config.cache config.log Makefile - diff --git a/scripts/Menuconfig b/scripts/Menuconfig new file mode 100755 index 00000000..8481aecf --- /dev/null +++ b/scripts/Menuconfig @@ -0,0 +1,1138 @@ +#! /bin/sh +# +# This script is borrowed from the linux Menuconfig script. +# +# This script attempts to parse the configuration files, which are +# scattered throughout the source tree, and creates a temporary +# set of mini scripts which are in turn used to create nested menus and +# radiolists. +# +# It uses a very modified/mutilated version of the "dialog" utility +# written by Savio Lam (lam836@cs.cuhk.hk). Savio is not responsible +# for this script or the version of dialog used by this script. +# Please do not contact him with questions. The official version of +# dialog is available at sunsite.unc.edu or a sunsite mirror. +# +# Portions of this script were borrowed from the original Configure +# script. +# +#---------------------------------------------------------------------------- + + +# +# Change this to TRUE if you prefer all kernel options listed +# in a single menu rather than the standard menu hierarchy. +# +single_menu_mode= + +# +# Make sure we're really running bash. +# +[ -z "$BASH" ] && { echo "Menuconfig requires bash" 1>&2; exit 1; } + +# +# Cache function definitions, turn off posix compliance +# +set -h +o posix + + + + + +# +# Load the functions used by the config.in files. +# +# I do this because these functions must be redefined depending +# on whether they are being called for interactive use or for +# saving a configuration to a file. +# +# Thank the heavens bash supports nesting function definitions. +# +load_functions () { + +# +# Additional comments +# +function comment () { + comment_ctr=$[ comment_ctr + 1 ] + echo -ne "': $comment_ctr' '--- $1' " >>MCmenu +} + +# +# Don't need this yet, but we don't want to puke either. +# +function set_bool () { + eval $2=\${$2:-'n'} x=\$$2 + + echo "\$1=$1 \$2=$2" >&2 +} + +# +# Don't need this yet, but we don't want to puke either. +# +function define_bool () { + : +} + +# +# Create a boolean (Yes/No) function for our current menu +# which calls our local bool function. +# +function bool () { + eval $2=\${$2:-'n'} x=\$$2 + + case $x in + y|m) flag="*" ;; + n) flag=" " ;; + esac + + echo -ne "'$2' '[$flag] $1' " >>MCmenu + + echo -e "function $2 () { l_bool '$2' \"\$1\" ;}\n" >>MCradiolists +} + +# +# Create a function which is dependent on +# another configuration option. +# +function dep_bool () { + eval $2=\${$2:-'n'} x=\$$3 + + if [ "$x" != "y" ] + then + disabled "$1" "$2" + else + bool "$1" "$2" + fi +} + +# +# Add a menu item which will call our local int function. +# +function int () { + eval $2=\${$2:-"$3"} x=\$$2 + + echo -ne "'$2' '($x) $1' " >>MCmenu + + echo -e "function $2 () { l_int '$1' '$2' '$3' '$x' ;}" >>MCradiolists +} + +# +# Add a menu item which will call our local hex function. +# +function hex () { + eval $2=\${$2:-"$3"} x=\${$2##*[x,X]} + + echo -ne "'$2' '($x) $1' " >>MCmenu + + echo -e "function $2 () { l_hex '$1' '$2' '$3' '$x' ;}" >>MCradiolists +} + +# +# Add a menu item which will call our local string function. +# +function string () { + eval $2=\${"$2":-"$3"} x=\$"$2" + + echo -ne "'$2' '\"$x\" $1' " >>MCmenu + + echo -e "function $2 () { l_string '$1' '$2' '$3' '$x' ;}" >>MCradiolists +} + +# +# Add a menu item which will call our local One-of-Many choice list. +# +function choice () { + # + # Need to remember params cause they're gonna get reset. + # + title=$1 + choices=$2 + default=$3 + current= + + # + # Find out if one of the choices is already set. + # If it's not then make it the default. + # + set -- $choices + firstchoice=$2 + + while [ -n "$2" ] + do + if eval [ "_\$$2" = "_y" ] + then + current=$1 + break + fi + shift ; shift + done + + : ${current:=$default} + + echo -ne "'$firstchoice' '($current) $title' " >>MCmenu + + echo -e " + function $firstchoice () \ + { l_choice '$title' \"$choices\" $current ;}" >>MCradiolists +} + +} # END load_functions() + + + + + +# +# Extract available help for an option from Configure.help +# and send it to standard output. +# +# Most of this function was borrowed from the original kernel +# Configure script. +# +function extract_help () { + if [ -f doc/Configure.help ] + then + #first escape regexp special characters in the argument: + var=$(echo "$1"|sed 's/[][\/.^$*]/\\&/g') + #now pick out the right help text: + text=$(sed -n "/^$var[ ]*\$/,\${ + /^$var[ ]*\$/d + /^#.*/d + /^[ ]*\$/q + s/^ // + p + }" doc/Configure.help) + + if [ -z "$text" ] + then + echo "There is no help available for this option." + return 1 + else + echo "$text" + fi + else + echo "There is no help available for this option." + return 1 + fi +} + +# +# Activate a help dialog. +# +function help () { + if [ "$1" = ":" ] ; then + return 0 + fi + if extract_help $1 >help.out + then + $DIALOG --backtitle "$backtitle" --title "$2"\ + --textbox help.out $ROWS $COLS + else + $DIALOG --backtitle "$backtitle" \ + --textbox help.out $ROWS $COLS + fi + rm help.out +} + +# +# Show the README file. +# +function show_readme () { + $DIALOG --backtitle "$backtitle" \ + --textbox scripts/README.Menuconfig $ROWS $COLS +} + +# +# Begin building the dialog menu command and Initialize the +# Radiolist function file. +# +function menu_name () { + echo -ne "$DIALOG --title '$1'\ + --backtitle '$backtitle' \ + --menu '$menu_instructions' \ + $ROWS $COLS $((ROWS-10)) \ + '$default' " >MCmenu + >MCradiolists +} + +# +# Add a submenu option to the menu currently under construction. +# +function submenu () { + echo -ne "'activate_menu $2' '$1 --->' " >>MCmenu +} + +# +# Handle a boolean (Yes/No) option. +# +function l_bool () { + if [ -n "$2" ] + then + case "$2" in + y|m) eval $1=y ;; + c) eval x=\$$1 + case $x in + y) eval $1=n ;; + n) eval $1=y ;; + esac ;; + *) eval $1=n ;; + esac + else + echo -ne "\007" + fi +} + +# +# Same as bool() except disabled +# +function disabled () { + eval $2=\${$2:-'n'} x=\$$2 + + case $x in + *) flag=' ' ;; + esac + + echo -ne "'$2' '<$flag> $1' " >>MCmenu + + echo -e "function $2 () { l_disabled '$2' \"\$1\" ;}" >>MCradiolists +} + +# +# Same as l_bool() except disabled +# +function l_disabled() { + if [ -n "$2" ] + then + case "$2" in + y) echo -en "\007" + ${DIALOG} --backtitle "$backtitle" \ + --msgbox "\ +This feature depends on another which has been disabled. \ +As a result, this feature will be disabled also." 6 70 + eval $1=n;; + m) eval $1=n ;; + c) eval x=\$$1 + case $x in + m) eval $1=n ;; + n) eval $1=n ;; + esac ;; + *) eval $1=n ;; + esac + else + echo -ne "\007" + fi +} + +# +# Create a dialog for entering an integer into an option. +# +function l_int () { + while true + do + if $DIALOG --title "$1" \ + --backtitle "$backtitle" \ + --inputbox "$inputbox_instructions_int" \ + 10 75 "$4" 2>MCdialog.out + then + answer="`cat MCdialog.out`" + answer="${answer:-$3}" + + if expr $answer : '0$\|-\?[1-9][0-9]*$' >/dev/null + then + eval $2="$answer" + else + eval $2="$3" + echo -en "\007" + ${DIALOG} --backtitle "$backtitle" \ + --msgbox "You have made an invalid entry." 3 43 + fi + + break + fi + + help "$2" "$1" + done +} + +# +# Create a dialog for entering a hexadecimal into an option. +# +function l_hex () { + while true + do + if $DIALOG --title "$1" \ + --backtitle "$backtitle" \ + --inputbox "$inputbox_instructions_hex" \ + 10 75 "$4" 2>MCdialog.out + then + answer="`cat MCdialog.out`" + answer="${answer:-$3}" + answer="${answer##*[x,X]}" + + if expr $answer : '[0-9a-fA-F]\+$' >/dev/null + then + eval $2="$answer" + else + eval $2="$3" + echo -en "\007" + ${DIALOG} --backtitle "$backtitle" \ + --msgbox "You have made an invalid entry." 3 43 + fi + + break + fi + + help "$2" "$1" + done +} + +# +# Create a dialog for entering a string into an option. +# +function l_string () { + while true + do + if $DIALOG --title "$1" \ + --backtitle "$backtitle" \ + --inputbox "$inputbox_instructions_string" \ + 10 75 "$4" 2>MCdialog.out + then + answer="`cat MCdialog.out`" + answer="${answer:-$3}" + + if [ "$answer" != "" ] + then + eval $2='${answer}' + fi + + break + fi + + help "$2" "$1" + done +} + +# +# Handle a on-of-many choice list. +# +function l_choice () { + # + # Need to remember params cause they're gonna get reset. + # + title="$1" + choices="$2" + current="$3" + + # + # Scan current value of choices and set radiolist switches. + # + list= + set -- $choices + firstchoice=$2 + while [ -n "$2" ] + do + case "$1" in + "$current") list="$list $2 $1 ON " ;; + *) list="$list $2 $1 OFF " ;; + esac + + shift ; shift + done + + while true + do + if $DIALOG --title "$title" \ + --backtitle "$backtitle" \ + --radiolist "$radiolist_instructions" \ + 15 70 6 $list 2>MCdialog.out + then + choice=`cat MCdialog.out` + break + fi + + help "$firstchoice" "$title" + done + + # + # Now set the boolean value of each option base on + # the selection made from the radiolist. + # + set -- $choices + while [ -n "$2" ] + do + if [ "$2" = "$choice" ] + then + eval $2="y" + else + eval $2="n" + fi + + shift ; shift + done +} + +# +# A faster awk based recursive parser. (I hope) +# +function parser1 () { +awk ' +BEGIN { + menu_no = 0 + comment_is_option = 0 + parser("'$CONFIG_IN'","MCmenu0") +} + +function parser(ifile,menu) { + + while (getline >menu + + printf( "function MCmenu%s () {\n"\ + "default=$1\n"\ + "menu_name %s\n",\ + menu_no, $0) >"MCmenu"menu_no + + parser(ifile, "MCmenu"menu_no) + } + else if ($1 ~ "endmenu") { + printf("}\n") >>menu + return + } + else if ($0 ~ /^#|\$MAKE|mainmenu_name/) { + printf("") >>menu + } + else if ($1 == "source") { + parser($2,menu) + } + else { + print >>menu + } + } +}' +} + +# +# Secondary parser for single menu mode. +# +function parser2 () { +awk ' +BEGIN { + parser("'$CONFIG_IN'","MCmenu0") +} + +function parser(ifile,menu) { + + while (getline >menu + } + else if ($0 ~ /^#|$MAKE|mainmenu_name/) { + printf("") >>menu + } + else if ($1 == "source") { + parser($2,menu) + } + else { + print >>menu + } + } +}' +} + +# +# Parse all the config.in files into mini scripts. +# +function parse_config_files () { + rm -f MCmenu* + + echo "function MCmenu0 () {" >MCmenu0 + echo 'default=$1' >>MCmenu0 + echo "menu_name 'Main Menu'" >>MCmenu0 + + if [ "_$single_menu_mode" = "_TRUE" ] + then + parser2 + else + parser1 + fi + + echo "comment ''" >>MCmenu0 + echo "g_alt_config" >>MCmenu0 + echo "s_alt_config" >>MCmenu0 + + echo "}" >>MCmenu0 + + # + # These mini scripts must be sourced into the current + # environment in order for all of this to work. Leaving + # them on the disk as executables screws up the recursion + # in activate_menu(), among other things. Once they are + # sourced we can discard them. + # + for i in MCmenu* + do + source ./$i + done + + rm -f MCmenu* +} + +# +# This is the menu tree's bootstrap. +# +# Executes the parsed menus on demand and creates a set of functions, +# one per configuration option. These functions will in turn execute +# dialog commands or recursively call other menus. +# +function activate_menu () { + while true + do + comment_ctr=0 #So comment lines get unique tags + + $1 "$default" #Create the lxdialog menu & functions + + if [ "$?" != "0" ] + then + clear + cat <. You may also +send a problem report to isdn4linux@hub-wue.franken.de or post a +message to the de.alt.comm.isdn4linux news group. + +Please indicate the isdn4k-utils version you are trying to configure and +which menu you were trying to enter when this error occurred. + +EOM + cleanup + exit 1 + fi + + . ./MCradiolists #Source the menu's functions + + . ./MCmenu 2>MCdialog.out #Activate the lxdialog menu + ret=$? + + read selection "*|*"alt_config"*) + show_readme ;; + *) + eval help '$selection' ;; + esac + ;; + 255|1) + break + ;; + 139) + stty sane + clear + cat < or post a message on the de.alt.comm.isdn4linux +news group for additional assistance. + +EOM + cleanup + exit 139 + ;; + esac + done +} + +# +# Create a menu item to load an alternate configuration file. +# +g_alt_config () { + echo -n "get_alt_config 'Load an Alternate Configuration File' "\ + >>MCmenu +} + +# +# Get alternate config file name and load the +# configuration from it. +# +get_alt_config () { + set -f ## Switch file expansion OFF + + while true + do + ALT_CONFIG="${ALT_CONFIG:-$DEFAULTS}" + + $DIALOG --backtitle "$backtitle" \ + --inputbox "\ +Enter the name of the configuration file you wish to load. \ +Accept the name shown to restore the configuration you \ +last retrieved. Leave blank to abort."\ + 11 55 "$ALT_CONFIG" 2>MCdialog.out + + if [ "$?" = "0" ] + then + ALT_CONFIG=`cat MCdialog.out` + + [ "_" = "_$ALT_CONFIG" ] && break + + if eval [ -r "$ALT_CONFIG" ] + then + eval load_config_file "$ALT_CONFIG" + break + else + echo -ne "\007" + $DIALOG --backtitle "$backtitle" \ + --msgbox "File does not exist!" 3 38 + fi + else + cat <help.out + +For various reasons, one may wish to keep several different +configurations available on a single machine. + +If you have saved a previous configuration in a file other than the +default, entering the name of the file here will allow you +to modify that configuration. + +If you are uncertain, then you have probably never used alternate +configuration files. You should therefor leave this blank to abort. + +EOM + $DIALOG --backtitle "$backtitle"\ + --title "Load Alternate Configuration"\ + --textbox help.out $ROWS $COLS + fi + done + + set +f ## Switch file expansion ON + rm -f help.out MCdialog.out +} + +# +# Create a menu item to store an alternate config file. +# +s_alt_config () { + echo -n "save_alt_config 'Save Configuration to an Alternate File' "\ + >>MCmenu +} + +# +# Get an alternate config file name and save the current +# configuration to it. +# +save_alt_config () { + set -f ## Switch file expansion OFF + + while true + do + $DIALOG --backtitle "$backtitle" \ + --inputbox "\ +Enter a filename to which this configuration should be saved \ +as an alternate. Leave blank to abort."\ + 10 55 "$ALT_CONFIG" 2>MCdialog.out + + if [ "$?" = "0" ] + then + ALT_CONFIG=`cat MCdialog.out` + + [ "_" = "_$ALT_CONFIG" ] && break + + if eval touch $ALT_CONFIG 2>/dev/null + then + eval save_configuration $ALT_CONFIG + load_functions ## RELOAD + break + else + echo -ne "\007" + $DIALOG --backtitle "$backtitle" \ + --msgbox "Can't create file! Probably a nonexistent directory." 3 60 + fi + else + cat <help.out + +For various reasons, one may wish to keep different +configurations available on a single machine. + +Entering a file name here will allow you to later retrieve, modify +and use the current configuration as an alternate to whatever +configuration options you have selected at that time. + +If you are uncertain what all this means then you should probably +leave this blank. +EOM + $DIALOG --backtitle "$backtitle"\ + --title "Save Alternate Configuration"\ + --textbox help.out $ROWS $COLS + fi + done + + set +f ## Switch file expansion ON + rm -f help.out MCdialog.out +} + +# +# Load config options from a file. +# Converts all "# OPTION is not set" lines to "OPTION=n" lines +# +function load_config_file () { + awk ' + /# .* is not set.*/ { printf("%s=n\n", $2) } + ! /# .* is not set.*/ { print } + ' $1 >.tmpconfig + + source ./.tmpconfig + rm -f .tmpconfig +} + +# +# Just what it says. +# +save_configuration () { + ${DIALOG} --backtitle "$backtitle" \ + --infobox "Saving your configuration..." 3 40 + + # + # Now, let's redefine the configuration functions for final + # output to the config files. + # + # Nested function definitions, YIPEE! + # + function bool () { + eval define_bool "$2" "\${$2:-n}" + } + + function dep_bool () { + eval x=\${$2:-n} + + if eval [ "_$3" = "_n" ] + then + if [ "$x" = "y" ] + then + x="n" + fi + fi + + #define_bool "$2" "$x" + } + + function int () { + eval x=\${$2:-"$3"} + echo "$2=$x" >>$CONFIG + echo "#define $2 ($x)" >>$CONFIG_H + } + + function string () { + eval x=\${"$2":-"$3"} + echo "$2='$x'" >>$CONFIG + echo "#define $2 \"$x\"" >>$CONFIG_H + } + + function hex () { + eval x=\${$2:-"$3"} + echo "$2=$x" >>$CONFIG + echo "#define $2 0x${x##*[x,X]}" >>$CONFIG_H + } + + function define_bool () { + eval $1="$2" + + case "$2" in + y) + echo "$1=y" >>$CONFIG + echo "#define $1 1" >>$CONFIG_H + ;; + + n) + echo "# $1 is not set" >>$CONFIG + echo "#undef $1" >>$CONFIG_H + ;; + esac + } + + function choice () { + # + # Find the first choice that's already set to 'y' + # + choices="$2" + default="$3" + current= + + set -- $choices + while [ -n "$2" ] + do + if eval [ "_\$$2" = "_y" ] + then + current=$1 + break + fi + shift ; shift + done + + # + # Use the default if none were set. + # + : ${current:=$default} + + # + # Then extract the actual option from the list of choices. + # + current=${choices#*$current} ; set $current + + define_bool "$1" "y" + } + + function mainmenu_name () { + : + } + + function mainmenu_option () { + comment_is_option=TRUE + } + + function endmenu () { + : + } + + function comment () { + if [ "$comment_is_option" ] + then + comment_is_option= + echo >>$CONFIG + echo "#" >>$CONFIG + echo "# $1" >>$CONFIG + echo "#" >>$CONFIG + + echo >>$CONFIG_H + echo "/*" >>$CONFIG_H + echo " * $1" >>$CONFIG_H + echo " */" >>$CONFIG_H + fi + } + + DEF_CONFIG="${1:-.config}" + DEF_CONFIG_H="scripts/autoconf.h" + + CONFIG=.tmpconfig + CONFIG_H=.tmpconfig.h + + echo "#" >$CONFIG + echo "# Automatically generated by make menuconfig: don't edit" >>$CONFIG + echo "#" >>$CONFIG + + echo "/*" >$CONFIG_H + echo " * Automatically generated by make menuconfig: don't edit" >>$CONFIG_H + echo " */" >>$CONFIG_H + echo "#define AUTOCONF_INCLUDED" >> $CONFIG_H + + if . $CONFIG_IN >>.menuconfig.log 2>&1 + then + if [ "$DEF_CONFIG" = ".config" ] + then + mv $CONFIG_H $DEF_CONFIG_H + fi + + if [ -f "$DEF_CONFIG" ] + then + rm -f ${DEF_CONFIG}.old + mv $DEF_CONFIG ${DEF_CONFIG}.old + fi + + mv $CONFIG $DEF_CONFIG + + return 0 + else + return 1 + fi +} + +# +# Remove temporary files +# +cleanup () { + cleanup1 + cleanup2 +} + +cleanup1 () { + rm -f MCmenu* MCradiolists MCdialog.out help.out +} + +cleanup2 () { + rm -f .tmpconfig .tmpconfig.h +} + +set_geometry () { + # Some distributions export these with incorrect values + # which can really screw up some ncurses programs. + LINES= COLUMNS= + + ROWS=${1:-24} COLS=${2:-80} + + # Just in case the nasty rlogin bug returns. + # + [ $ROWS = 0 ] && ROWS=24 + [ $COLS = 0 ] && COLS=80 + + if [ $ROWS -lt 19 -o $COLS -lt 80 ] + then + echo -e "\n\007Your display is too small to run Menuconfig!" + echo "It must be at least 19 lines by 80 columns." + exit 0 + fi + + ROWS=$((ROWS-4)) COLS=$((COLS-5)) +} + + +set_geometry `stty size 2>/dev/null` + +menu_instructions="\ +Arrow keys navigate the menu. \ + selects submenus --->. \ +Highlighted letters are hotkeys. \ +Pressing enables, disables features. \ +Press to exit, for Help. \ +Legend: [*] enabled [ ] disabled" + +radiolist_instructions="\ +Use the arrow keys to navigate this window or \ +press the hotkey of the item you wish to select \ +followed by the . +Press for additional information about this option." + +inputbox_instructions_int="\ +Please enter a decimal value between 1 and 9999. \ +Fractions will not be accepted. \ +Use the key to move from the input field to the buttons below it." + +inputbox_instructions_hex="\ +Please enter a hexadecimal value. \ +Use the key to move from the input field to the buttons below it." + +inputbox_instructions_string="\ +Please enter a string value. Leave blank to abort. \ +Use the key to move from the input field to the buttons below it." + +DIALOG="scripts/lxdialog/lxdialog" + +backtitle="isdn4k-utils Version $I4LVERSION Configuration" + +trap "cleanup ; rm -f .menuconfig ; exit 1" 1 2 15 + + +# +# Locate default files. +# +CONFIG_IN=./config.in +if [ "$1" != "" ] ; then + CONFIG_IN=$1 +fi + +DEFAULTS=scripts/defconfig +if [ -f .config ]; then + DEFAULTS=.config +fi + +if [ -f $DEFAULTS ] +then + echo "#" + echo "# Using defaults found in" $DEFAULTS + echo "#" + load_config_file $DEFAULTS +else + echo "#" + echo "# No defaults found" + echo "#" +fi + + +# Fresh new log. +>.menuconfig.log + +$DIALOG --backtitle "$backtitle" \ + --infobox "Preparing configuration scripts..." 3 40 + +# Load the functions used by the config.in files. +load_functions + +# +# Read config.in files and parse them into one shell function per menu. +# +parse_config_files $CONFIG_IN + +# +# Start the ball rolling from the top. +# +activate_menu MCmenu0 + +# +# All done! +# +cleanup1 + +# +# Confirm and Save +# +if $DIALOG --backtitle "$backtitle" \ + --yesno "Do you wish to save your new configuration?" 5 60 + +then + save_configuration + rm -f .menuconfig.log + + clear + cat < to build it in or to removed it. You may +also press the to cycle through the available options +(ie. Y->N->Y). + +Items beginning with numbers or other text within parenthesis or +double quotes can be changed by highlighting the item and pressing +. Then enter the new parameter into the dialog box that pops up. + + +Some additional keyboard hints: + +Menus +---------- +o Use the Up/Down arrow keys (cursor keys) to highlight the item + you wish to change or submenu wish to select and press . + Submenus are designated by "--->". + + Shortcut: Press the option's highlighted letter (hotkey). + Pressing a hotkey more than once will sequence + through all visible items which use that hotkey. + + You may also use the and keys to scroll + unseen options into view. + +o To exit a menu use the cursor keys to highlight the button + and press . + + Shortcut: Press or or if there is no hotkey + using those letters. You may press a single , but + there is a delayed response which you may find annoying. + + Also, the and cursor keys will cycle between and + + + +Data Entry +----------- +o Enter the requested information and press + If you are entering hexadecimal values, it is not necessary to + add the '0x' prefix to the entry. + +o For help, use the or cursor keys to highlight the help option + and press . You can try as well. + + +Text Box (Help Window) +-------- +o Use the cursor keys to scroll up/down/left/right. The VI editor + keys h,j,k,l function here as do and for those + who are familiar with less and lynx. + +o Press , , or to exit. + + +Final Acceptance +---------------- +YOUR CHANGES ARE NOT FINAL. You will be given a last chance to +confirm them prior to exiting Menuconfig. + +If Menuconfig quits with an error while saving your configuration, +you may look in the file .menuconfig.log for information which may +help you determine the cause. + +Alternate Configuration Files +----------------------------- +Menuconfig supports the use of alternate configuration files for +those who, for various reasons, find it necessary to switch +between different package configurations. + +At the end of the main menu you will find two options. One is +for saving the current configuration to a file of your choosing. +The other option is for loading a previously saved alternate +configuration. + +Even if you don't use alternate configuration files, but you +find during a Menuconfig session that you have completely messed +up your settings, you may use the "Load Alternate..." option to +restore your previously saved settings from ".config" without +restarting Menuconfig. + +Other information +----------------- +The windowing utility, lxdialog, will only be rebuilt if your +source tree is fresh, or changes are patched into it via a +patch or you do 'make mrproper'. If changes to lxdialog are patched +in, most likely the rebuild time will be short. You may force a +complete rebuild of lxdialog by changing to it's directory and doing +'make clean all' + +If you use Menuconfig in an XTERM window make sure you have your +$TERM variable set to point to a xterm definition which supports color. +Otherwise, Menuconfig will look rather bad. Menuconfig will not +display correctly in a RXVT window because rxvt displays only one +intensity of color, bright. + +Menuconfig will display larger menus on screens or xterms which are +set to display more than the standard 25 row by 80 column geometry. +In order for this to work, the "stty size" command must be able to +display the screen's current row and column geometry. I STRONGLY +RECOMMEND that you make sure you do NOT have the shell variables +LINES and COLUMNS exported into your environment. Some distributions +export those variables via /etc/profile. Some ncurses programs can +become confused when those variables (LINES & COLUMNS) don't reflect +the true screen size. + + +NOTICE: lxdialog requires the ncurses libraries to compile. If you + don't already have ncurses you really should get it. + + The makefile for lxdialog attempts to find your ncurses + header file. Although it should find the header for older + versions of ncurses, it is probably a good idea to get the + latest ncurses anyway. + + If you have upgraded your ncurses libraries, MAKE SURE you + remove the old ncurses header files. If you don't you + will most certainly get a segmentation fault. + +WARNING: It is not recommended that you change any defines in + lxdialog's header files. If you have a grayscale display and + are brave, you may tinker with color.h to tune the colors to + your preference. + +COMPATIBILITY ISSUE: + There have been some compatibility problems reported with + older versions of bash and sed. I am trying to work these + out but it is preferable that you upgrade those utilities. + + +******** IMPORTANT, OPTIONAL ALTERNATE PERSONALITY AVAILABLE ******** +******** ******** +If you prefer to have all of the options listed in a single +menu, rather than the default multimenu hierarchy, you may edit the +Menuconfig script and change the line "single_menu_mode=" to +"single_menu_mode=TRUE". + +This mode is not recommended unless you have a fairly fast machine. +********************************************************************* + + +Propaganda +---------- +The windowing support utility (lxdialog) is a VERY modified version of +the dialog utility by Savio Lam . Although lxdialog +is significantly different from dialog, I have left Savio's copyrights +intact. Please DO NOT contact Savio with questions about lxdialog. +He will not be able to assist. +I also made a small modification to support string entries without +being messed up by entering shell-variables or printf-formats. + +Please feel free to send any questions, comments or suggestions to +. + + diff --git a/scripts/config.in b/scripts/config.in new file mode 100644 index 00000000..7c5e5474 --- /dev/null +++ b/scripts/config.in @@ -0,0 +1,57 @@ +# +# The whole configuration stuff is borrowed from the kernel +# configuration. +# +# For a description of the syntax of this configuration file, +# see the Menuconfig script. +# +if [ "`type -p xmkmf`" != "" ]; then +CONFIG_HASX11=y +fi +mainmenu_name "isdn4k-utils Configuration" + +mainmenu_option next_comment +comment 'Code maturity level options' +bool 'Prompt for development and/or incomplete code' CONFIG_EXPERIMENTAL +endmenu +string 'General configuration directory' CONFIG_I4LCONFDIR /etc/isdn +string 'Directory to install binaries' CONFIG_BINDIR /usr/bin +string 'Directory to install admin binaries' CONFIG_SBINDIR /sbin +string 'Directory to install man pages' CONFIG_MANDIR /usr/man +comment 'General configuration tools' +bool 'isdnctrl' CONFIG_ISDNCTRL +if [ "$CONFIG_ISDNCTRL" = "y" ]; then + bool 'Enable isdnctrl debug-option' CONFIG_ISDNCTRL_DEBUG +fi +bool 'iprofd' CONFIG_IPROFD +comment 'Card configuration tools' +bool 'telesctrl' CONFIG_TELESCTRL +bool 'hisaxctrl' CONFIG_HISAXCTRL +bool 'icnctrl' CONFIG_ICNCTRL +if [ "$CONFIG_ICNCTRL" = "y" ]; then + bool 'Enable icnctl debug-option' CONFIG_ICNCTRL_DEBUG +fi +bool 'pcbitctl' CONFIG_PCBITCTL +comment 'Tools for monitoring activity' +bool 'imon' CONFIG_IMON +bool 'isdnlog' CONFIG_ISDNLOG +if [ "$CONFIG_ISDNLOG" = "y" ]; then + source isdnlog/Config.in +fi +dep_bool 'xmonisdn' CONFIG_XMONISDN CONFIG_HASX11 +if [ "$CONFIG_XMONISDN" = "y" ]; then + string 'NetUP command for xmonisdn' CONFIG_XMONISDN_UPCMD '/sbin/netup' + string 'NetDOWN command for xmonisdn' CONFIG_XMONISDN_DOWNCMD '/sbin/netdown' +fi +dep_bool 'xisdnload' CONFIG_XISDNLOAD CONFIG_HASX11 +comment 'Applications' +bool 'vbox' CONFIG_VBOX +if [ "$CONFIG_VBOX" = "y" ]; then + source vbox/Config.in +fi +comment 'General documentation' +bool 'Install generic pages' CONFIG_GENMAN +bool 'Generate FAQ' CONFIG_FAQ +if [ "$CONFIG_FAQ" = "y" ]; then + string 'Directory to install FAQ' CONFIG_FAQDIR /usr/doc/faq/isdn4linux +fi diff --git a/scripts/defconfig b/scripts/defconfig new file mode 100644 index 00000000..5aef9c3f --- /dev/null +++ b/scripts/defconfig @@ -0,0 +1,45 @@ +# +# Code maturity level options +# +# CONFIG_EXPERIMENTAL is not set +CONFIG_I4LCONFDIR='/etc/isdn' +CONFIG_BINDIR='/usr/bin' +CONFIG_SBINDIR='/sbin' +CONFIG_MANDIR='/usr/man' +CONFIG_ISDNCTRL=y +# CONFIG_ISDNCTRL_DEBUG is not set +CONFIG_IPROFD=y +# CONFIG_TELESCTRL is not set +CONFIG_HISAXCTRL=y +CONFIG_ICNCTRL=y +# CONFIG_ICNCTRL_DEBUG is not set +CONFIG_PCBITCTL=y +CONFIG_IMON=y +CONFIG_ISDNLOG=n + +# +# Options for isdnlog package +# +CONFIG_ISDNLOG_OLDI4LCONFDIR='/etc/isdnlog' +CONFIG_ISDNLOG_OLDI4LCONFFILE='isdnlog.conf' +CONFIG_ISDNLOG_AREACODE=y +# CONFIG_ISDNLOG_POSTGRES is not set +# CONFIG_ISDNLOG_OLD_I4L is not set +CONFIG_ISDNLOG_DE=y +CONFIG_XMONISDN=y +CONFIG_XMONISDN_UPCMD='/sbin/netup' +CONFIG_XMONISDN_DOWNCMD='/sbin/netdown' +CONFIG_XISDNLOAD=y +CONFIG_VBOX=n + +# +# Options for vbox package +# +VBOX_SPOOLDIR='/var/spool/vbox' +VBOX_LOGDIR='/var/log/vbox' +VBOX_PIDDIR='/var/run' +VBOX_LOCKDIR='/var/lock' +VBOX_TCL='tcl8.0' +CONFIG_GENMAN=y +CONFIG_FAQ=y +CONFIG_FAQDIR='/usr/doc/faq/isdn4linux' diff --git a/scripts/lxdialog/BIG.FAT.WARNING b/scripts/lxdialog/BIG.FAT.WARNING new file mode 100644 index 00000000..a8999d82 --- /dev/null +++ b/scripts/lxdialog/BIG.FAT.WARNING @@ -0,0 +1,4 @@ +This is NOT the official version of dialog. This version has been +significantly modified from the original. It is for use by the Linux +kernel configuration script. Please do not bother Savio Lam with +questions about this program. diff --git a/scripts/lxdialog/Makefile b/scripts/lxdialog/Makefile new file mode 100644 index 00000000..fc5ee7ff --- /dev/null +++ b/scripts/lxdialog/Makefile @@ -0,0 +1,46 @@ +CC = gcc +CPP = gcc -E +OPTIM = -O2 -Wall -fomit-frame-pointer + +CFLAGS = $(OPTIM) -DLOCALE +LDFLAGS = -s -L . +LDLIBS = -lncurses + +ifeq (/usr/include/ncurses/ncurses.h, $(wildcard /usr/include/ncurses/ncurses.h)) + CFLAGS += -I/usr/include/ncurses -DCURSES_LOC="" +else +ifeq (/usr/include/ncurses/curses.h, $(wildcard /usr/include/ncurses/curses.h)) + CFLAGS += -I/usr/include/ncurses -DCURSES_LOC="" +else +ifeq (/usr/include/ncurses.h, $(wildcard /usr/include/ncurses.h)) + CFLAGS += -DCURSES_LOC="" +else + CFLAGS += -DCURSES_LOC="" +endif +endif +endif + + +OBJS = checklist.o menubox.o textbox.o yesno.o inputbox.o \ + util.o lxdialog.o msgbox.o +SRCS = $(OBJS:.o=.c) + + +all: ncurses lxdialog + +lxdialog: $(OBJS) + +ncurses: + @x=`find /lib/ /usr/lib/ /usr/local/lib/ -maxdepth 1 -name 'libncurses.*'` ;\ + if [ ! "$$x" ]; then \ + echo -e "\007" ;\ + echo ">> Unable to find the Ncurses libraries." ;\ + echo ">>" ;\ + echo ">> You must have Ncurses installed in order" ;\ + echo ">> to use 'make menuconfig'" ;\ + echo ;\ + exit 1 ;\ + fi + +clean: + rm -f core *.o *~ lxdialog diff --git a/scripts/lxdialog/checklist.c b/scripts/lxdialog/checklist.c new file mode 100644 index 00000000..b986b3a2 --- /dev/null +++ b/scripts/lxdialog/checklist.c @@ -0,0 +1,344 @@ +/* + * checklist.c -- implements the checklist box + * + * ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk) + * Stuart Herbert - S.Herbert@sheffield.ac.uk: radiolist extension + * Alessandro Rubini - rubini@ipvvis.unipv.it: merged the two + * MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com) + * + * 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. + */ + +#include "dialog.h" + +static int list_width, check_x, item_x, checkflag; + +/* + * Print list item + */ +static void +print_item (WINDOW * win, const char *item, int status, + int choice, int selected) +{ + int i; + + /* Clear 'residue' of last item */ + wattrset (win, menubox_attr); + wmove (win, choice, 0); + for (i = 0; i < list_width; i++) + waddch (win, ' '); + + wmove (win, choice, check_x); + wattrset (win, selected ? check_selected_attr : check_attr); + if (checkflag == FLAG_CHECK) + wprintw (win, "[%c]", status ? 'X' : ' '); + else + wprintw (win, "(%c)", status ? 'X' : ' '); + + wattrset (win, selected ? tag_selected_attr : tag_attr); + mvwaddch(win, choice, item_x, item[0]); + wattrset (win, selected ? item_selected_attr : item_attr); + waddstr (win, (char *)item+1); +} + +/* + * Print the scroll indicators. + */ +static void +print_arrows (WINDOW * win, int choice, int item_no, int scroll, + int y, int x, int height) +{ + wmove(win, y, x); + + if (scroll > 0) { + wattrset (win, uarrow_attr); + waddch (win, ACS_UARROW); + waddstr (win, "(-)"); + } + else { + wattrset (win, menubox_attr); + waddch (win, ACS_HLINE); + waddch (win, ACS_HLINE); + waddch (win, ACS_HLINE); + waddch (win, ACS_HLINE); + } + + y = y + height + 1; + wmove(win, y, x); + + if ((height < item_no) && (scroll + choice < item_no - 1)) { + wattrset (win, darrow_attr); + waddch (win, ACS_DARROW); + waddstr (win, "(+)"); + } + else { + wattrset (win, menubox_border_attr); + waddch (win, ACS_HLINE); + waddch (win, ACS_HLINE); + waddch (win, ACS_HLINE); + waddch (win, ACS_HLINE); + } +} + +/* + * Display the termination buttons + */ +static void +print_buttons( WINDOW *dialog, int height, int width, int selected) +{ + int x = width / 2 - 11; + int y = height - 2; + + print_button (dialog, "Select", y, x, selected == 0); + print_button (dialog, " Help ", y, x + 14, selected == 1); + + wmove(dialog, y, x+1 + 14*selected); + wrefresh (dialog); +} + +/* + * Display a dialog box with a list of options that can be turned on or off + * The `flag' parameter is used to select between radiolist and checklist. + */ +int +dialog_checklist (const char *title, const char *prompt, int height, int width, + int list_height, int item_no, const char * const * items, int flag) + +{ + int i, x, y, box_x, box_y; + int key = 0, button = 0, choice = 0, scroll = 0, max_choice, *status; + WINDOW *dialog, *list; + + checkflag = flag; + + /* Allocate space for storing item on/off status */ + if ((status = malloc (sizeof (int) * item_no)) == NULL) { + endwin (); + fprintf (stderr, + "\nCan't allocate memory in dialog_checklist().\n"); + exit (-1); + } + + /* Initializes status */ + for (i = 0; i < item_no; i++) { + status[i] = !strcasecmp (items[i * 3 + 2], "on"); + if (!choice && status[i]) + choice = i; + } + + max_choice = MIN (list_height, item_no); + + /* center dialog box on screen */ + x = (COLS - width) / 2; + y = (LINES - height) / 2; + + draw_shadow (stdscr, y, x, height, width); + + dialog = newwin (height, width, y, x); + keypad (dialog, TRUE); + + draw_box (dialog, 0, 0, height, width, dialog_attr, border_attr); + wattrset (dialog, border_attr); + mvwaddch (dialog, height-3, 0, ACS_LTEE); + for (i = 0; i < width - 2; i++) + waddch (dialog, ACS_HLINE); + wattrset (dialog, dialog_attr); + waddch (dialog, ACS_RTEE); + + if (title != NULL) { + wattrset (dialog, title_attr); + mvwaddch (dialog, 0, (width - strlen(title))/2 - 1, ' '); + waddstr (dialog, (char *)title); + waddch (dialog, ' '); + } + + wattrset (dialog, dialog_attr); + print_autowrap (dialog, prompt, width - 2, 1, 3); + + list_width = width - 6; + box_y = height - list_height - 5; + box_x = (width - list_width) / 2 - 1; + + /* create new window for the list */ + list = subwin (dialog, list_height, list_width, y+box_y+1, x+box_x+1); + + keypad (list, TRUE); + + /* draw a box around the list items */ + draw_box (dialog, box_y, box_x, list_height + 2, list_width + 2, + menubox_border_attr, menubox_attr); + + /* Find length of longest item in order to center checklist */ + check_x = 0; + for (i = 0; i < item_no; i++) + check_x = MAX (check_x, + strlen (items[i * 3 + 1]) + 4); + + check_x = (list_width - check_x) / 2; + item_x = check_x + 4; + + /* Print the list */ + for (i = 0; i < max_choice; i++) + print_item (list, items[i * 3 + 1], status[i], i, i == choice); + + wnoutrefresh (list); + + print_arrows(dialog, choice, item_no, scroll, + box_y, box_x + check_x + 5, list_height); + + print_buttons(dialog, height, width, 0); + + while (key != ESC) { + key = wgetch (dialog); + + for (i = 0; i < max_choice; i++) + if (toupper(key) == toupper(items[(scroll+i)*3+1][0])) + break; + + + if ( i < max_choice || key == KEY_UP || key == KEY_DOWN || + key == '+' || key == '-' ) { + if (key == KEY_UP || key == '-') { + if (!choice) { + if (!scroll) + continue; + /* Scroll list down */ + if (list_height > 1) { + /* De-highlight current first item */ + print_item (list, items[scroll * 3 + 1], + status[scroll], 0, FALSE); + scrollok (list, TRUE); + wscrl (list, -1); + scrollok (list, FALSE); + } + scroll--; + print_item (list, items[scroll * 3 + 1], + status[scroll], 0, TRUE); + wnoutrefresh (list); + + print_arrows(dialog, choice, item_no, scroll, + box_y, box_x + check_x + 5, list_height); + + wrefresh (dialog); + + continue; /* wait for another key press */ + } else + i = choice - 1; + } else if (key == KEY_DOWN || key == '+') { + if (choice == max_choice - 1) { + if (scroll + choice >= item_no - 1) + continue; + /* Scroll list up */ + if (list_height > 1) { + /* De-highlight current last item before scrolling up */ + print_item (list, items[(scroll + max_choice - 1) * 3 + 1], + status[scroll + max_choice - 1], + max_choice - 1, FALSE); + scrollok (list, TRUE); + scroll (list); + scrollok (list, FALSE); + } + scroll++; + print_item (list, items[(scroll + max_choice - 1) * 3 + 1], + status[scroll + max_choice - 1], + max_choice - 1, TRUE); + wnoutrefresh (list); + + print_arrows(dialog, choice, item_no, scroll, + box_y, box_x + check_x + 5, list_height); + + wrefresh (dialog); + + continue; /* wait for another key press */ + } else + i = choice + 1; + } + if (i != choice) { + /* De-highlight current item */ + print_item (list, items[(scroll + choice) * 3 + 1], + status[scroll + choice], choice, FALSE); + /* Highlight new item */ + choice = i; + print_item (list, items[(scroll + choice) * 3 + 1], + status[scroll + choice], choice, TRUE); + wnoutrefresh (list); + wrefresh (dialog); + } + continue; /* wait for another key press */ + } + switch (key) { + case 'H': + case 'h': + case '?': + delwin (dialog); + free (status); + return 1; + case TAB: + case KEY_LEFT: + case KEY_RIGHT: + button = ((key == KEY_LEFT ? --button : ++button) < 0) + ? 1 : (button > 1 ? 0 : button); + + print_buttons(dialog, height, width, button); + wrefresh (dialog); + break; + case 'S': + case 's': + case ' ': + case '\n': + if (!button) { + if (flag == FLAG_CHECK) { + status[scroll + choice] = !status[scroll + choice]; + wmove (list, choice, check_x); + wattrset (list, check_selected_attr); + wprintw (list, "[%c]", status[scroll + choice] ? 'X' : ' '); + } else { + if (!status[scroll + choice]) { + for (i = 0; i < item_no; i++) + status[i] = 0; + status[scroll + choice] = 1; + for (i = 0; i < max_choice; i++) + print_item (list, items[(scroll + i) * 3 + 1], + status[scroll + i], i, i == choice); + } + } + wnoutrefresh (list); + wrefresh (dialog); + + for (i = 0; i < item_no; i++) { + if (status[i]) { + if (flag == FLAG_CHECK) { + fprintf (stderr, "\"%s\" ", items[i * 3]); + } else { + fprintf (stderr, "%s", items[i * 3]); + } + + } + } + } + delwin (dialog); + free (status); + return button; + case 'X': + case 'x': + key = ESC; + case ESC: + break; + } + } + + delwin (dialog); + free (status); + return -1; /* ESC pressed */ +} diff --git a/scripts/lxdialog/colors.h b/scripts/lxdialog/colors.h new file mode 100644 index 00000000..d34dd37c --- /dev/null +++ b/scripts/lxdialog/colors.h @@ -0,0 +1,161 @@ +/* + * colors.h -- color attribute definitions + * + * AUTHOR: Savio Lam (lam836@cs.cuhk.hk) + * + * 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. + */ + + +/* + * Default color definitions + * + * *_FG = foreground + * *_BG = background + * *_HL = highlight? + */ +#define SCREEN_FG COLOR_CYAN +#define SCREEN_BG COLOR_BLUE +#define SCREEN_HL TRUE + +#define SHADOW_FG COLOR_BLACK +#define SHADOW_BG COLOR_BLACK +#define SHADOW_HL TRUE + +#define DIALOG_FG COLOR_BLACK +#define DIALOG_BG COLOR_WHITE +#define DIALOG_HL FALSE + +#define TITLE_FG COLOR_YELLOW +#define TITLE_BG COLOR_WHITE +#define TITLE_HL TRUE + +#define BORDER_FG COLOR_WHITE +#define BORDER_BG COLOR_WHITE +#define BORDER_HL TRUE + +#define BUTTON_ACTIVE_FG COLOR_WHITE +#define BUTTON_ACTIVE_BG COLOR_BLUE +#define BUTTON_ACTIVE_HL TRUE + +#define BUTTON_INACTIVE_FG COLOR_BLACK +#define BUTTON_INACTIVE_BG COLOR_WHITE +#define BUTTON_INACTIVE_HL FALSE + +#define BUTTON_KEY_ACTIVE_FG COLOR_WHITE +#define BUTTON_KEY_ACTIVE_BG COLOR_BLUE +#define BUTTON_KEY_ACTIVE_HL TRUE + +#define BUTTON_KEY_INACTIVE_FG COLOR_RED +#define BUTTON_KEY_INACTIVE_BG COLOR_WHITE +#define BUTTON_KEY_INACTIVE_HL FALSE + +#define BUTTON_LABEL_ACTIVE_FG COLOR_YELLOW +#define BUTTON_LABEL_ACTIVE_BG COLOR_BLUE +#define BUTTON_LABEL_ACTIVE_HL TRUE + +#define BUTTON_LABEL_INACTIVE_FG COLOR_BLACK +#define BUTTON_LABEL_INACTIVE_BG COLOR_WHITE +#define BUTTON_LABEL_INACTIVE_HL TRUE + +#define INPUTBOX_FG COLOR_BLACK +#define INPUTBOX_BG COLOR_WHITE +#define INPUTBOX_HL FALSE + +#define INPUTBOX_BORDER_FG COLOR_BLACK +#define INPUTBOX_BORDER_BG COLOR_WHITE +#define INPUTBOX_BORDER_HL FALSE + +#define SEARCHBOX_FG COLOR_BLACK +#define SEARCHBOX_BG COLOR_WHITE +#define SEARCHBOX_HL FALSE + +#define SEARCHBOX_TITLE_FG COLOR_YELLOW +#define SEARCHBOX_TITLE_BG COLOR_WHITE +#define SEARCHBOX_TITLE_HL TRUE + +#define SEARCHBOX_BORDER_FG COLOR_WHITE +#define SEARCHBOX_BORDER_BG COLOR_WHITE +#define SEARCHBOX_BORDER_HL TRUE + +#define POSITION_INDICATOR_FG COLOR_YELLOW +#define POSITION_INDICATOR_BG COLOR_WHITE +#define POSITION_INDICATOR_HL TRUE + +#define MENUBOX_FG COLOR_BLACK +#define MENUBOX_BG COLOR_WHITE +#define MENUBOX_HL FALSE + +#define MENUBOX_BORDER_FG COLOR_WHITE +#define MENUBOX_BORDER_BG COLOR_WHITE +#define MENUBOX_BORDER_HL TRUE + +#define ITEM_FG COLOR_BLACK +#define ITEM_BG COLOR_WHITE +#define ITEM_HL FALSE + +#define ITEM_SELECTED_FG COLOR_WHITE +#define ITEM_SELECTED_BG COLOR_BLUE +#define ITEM_SELECTED_HL TRUE + +#define TAG_FG COLOR_YELLOW +#define TAG_BG COLOR_WHITE +#define TAG_HL TRUE + +#define TAG_SELECTED_FG COLOR_YELLOW +#define TAG_SELECTED_BG COLOR_BLUE +#define TAG_SELECTED_HL TRUE + +#define TAG_KEY_FG COLOR_YELLOW +#define TAG_KEY_BG COLOR_WHITE +#define TAG_KEY_HL TRUE + +#define TAG_KEY_SELECTED_FG COLOR_YELLOW +#define TAG_KEY_SELECTED_BG COLOR_BLUE +#define TAG_KEY_SELECTED_HL TRUE + +#define CHECK_FG COLOR_BLACK +#define CHECK_BG COLOR_WHITE +#define CHECK_HL FALSE + +#define CHECK_SELECTED_FG COLOR_WHITE +#define CHECK_SELECTED_BG COLOR_BLUE +#define CHECK_SELECTED_HL TRUE + +#define UARROW_FG COLOR_GREEN +#define UARROW_BG COLOR_WHITE +#define UARROW_HL TRUE + +#define DARROW_FG COLOR_GREEN +#define DARROW_BG COLOR_WHITE +#define DARROW_HL TRUE + +/* End of default color definitions */ + +#define C_ATTR(x,y) ((x ? A_BOLD : 0) | COLOR_PAIR((y))) +#define COLOR_NAME_LEN 10 +#define COLOR_COUNT 8 + +/* + * Global variables + */ + +typedef struct { + char name[COLOR_NAME_LEN]; + int value; +} color_names_st; + +extern color_names_st color_names[]; +extern int color_table[][3]; diff --git a/scripts/lxdialog/dialog.h b/scripts/lxdialog/dialog.h new file mode 100644 index 00000000..3be5feb2 --- /dev/null +++ b/scripts/lxdialog/dialog.h @@ -0,0 +1,166 @@ + +/* + * dialog.h -- common declarations for all dialog modules + * + * AUTHOR: Savio Lam (lam836@cs.cuhk.hk) + * + * 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. + */ + +#include +#include +#include +#include +#include +#include + +#include CURSES_LOC + +#define ESC 27 +#define TAB 9 +#define MAX_LEN 2048 +#define BUF_SIZE (10*1024) +#define MIN(x,y) (x < y ? x : y) +#define MAX(x,y) (x > y ? x : y) + + +#ifndef ACS_ULCORNER +#define ACS_ULCORNER '+' +#endif +#ifndef ACS_LLCORNER +#define ACS_LLCORNER '+' +#endif +#ifndef ACS_URCORNER +#define ACS_URCORNER '+' +#endif +#ifndef ACS_LRCORNER +#define ACS_LRCORNER '+' +#endif +#ifndef ACS_HLINE +#define ACS_HLINE '-' +#endif +#ifndef ACS_VLINE +#define ACS_VLINE '|' +#endif +#ifndef ACS_LTEE +#define ACS_LTEE '+' +#endif +#ifndef ACS_RTEE +#define ACS_RTEE '+' +#endif +#ifndef ACS_UARROW +#define ACS_UARROW '^' +#endif +#ifndef ACS_DARROW +#define ACS_DARROW 'v' +#endif + +/* + * Attribute names + */ +#define screen_attr attributes[0] +#define shadow_attr attributes[1] +#define dialog_attr attributes[2] +#define title_attr attributes[3] +#define border_attr attributes[4] +#define button_active_attr attributes[5] +#define button_inactive_attr attributes[6] +#define button_key_active_attr attributes[7] +#define button_key_inactive_attr attributes[8] +#define button_label_active_attr attributes[9] +#define button_label_inactive_attr attributes[10] +#define inputbox_attr attributes[11] +#define inputbox_border_attr attributes[12] +#define searchbox_attr attributes[13] +#define searchbox_title_attr attributes[14] +#define searchbox_border_attr attributes[15] +#define position_indicator_attr attributes[16] +#define menubox_attr attributes[17] +#define menubox_border_attr attributes[18] +#define item_attr attributes[19] +#define item_selected_attr attributes[20] +#define tag_attr attributes[21] +#define tag_selected_attr attributes[22] +#define tag_key_attr attributes[23] +#define tag_key_selected_attr attributes[24] +#define check_attr attributes[25] +#define check_selected_attr attributes[26] +#define uarrow_attr attributes[27] +#define darrow_attr attributes[28] + +/* number of attributes */ +#define ATTRIBUTE_COUNT 29 + +/* + * Global variables + */ +extern bool use_colors; +extern bool use_shadow; + +extern chtype attributes[]; + +extern const char *backtitle; + +/* + * Function prototypes + */ +extern void create_rc (const char *filename); +extern int parse_rc (void); + + +void init_dialog (void); +void end_dialog (void); +void attr_clear (WINDOW * win, int height, int width, chtype attr); +void dialog_clear (void); +void color_setup (void); +void print_autowrap (WINDOW * win, const char *prompt, int width, int y, int x); +void print_button (WINDOW * win, const char *label, int y, int x, int selected); +void draw_box (WINDOW * win, int y, int x, int height, int width, chtype box, + chtype border); +void draw_shadow (WINDOW * win, int y, int x, int height, int width); + +int first_alpha (const char *string, const char *exempt); +int dialog_yesno (const char *title, const char *prompt, int height, int width); +int dialog_msgbox (const char *title, const char *prompt, int height, + int width, int pause); +int dialog_textbox (const char *title, const char *file, int height, int width); +int dialog_menu (const char *title, const char *prompt, int height, int width, + int menu_height, const char *choice, int item_no, + const char * const * items); +int dialog_checklist (const char *title, const char *prompt, int height, + int width, int list_height, int item_no, + const char * const * items, int flag); +extern unsigned char dialog_input_result[]; +int dialog_inputbox (const char *title, const char *prompt, int height, + int width, const char *init); + +/* + * This is the base for fictitious keys, which activate + * the buttons. + * + * Mouse-generated keys are the following: + * -- the first 32 are used as numbers, in addition to '0'-'9' + * -- the lowercase are used to signal mouse-enter events (M_EVENT + 'o') + * -- uppercase chars are used to invoke the button (M_EVENT + 'O') + */ +#define M_EVENT (KEY_MAX+1) + + +/* + * The `flag' parameter in checklist is used to select between + * radiolist and checklist + */ +#define FLAG_CHECK 1 +#define FLAG_RADIO 0 diff --git a/scripts/lxdialog/inputbox.c b/scripts/lxdialog/inputbox.c new file mode 100644 index 00000000..1d0200fa --- /dev/null +++ b/scripts/lxdialog/inputbox.c @@ -0,0 +1,232 @@ +/* + * inputbox.c -- implements the input box + * + * ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk) + * MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com) + * + * 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. + */ + +#include "dialog.h" + +unsigned char dialog_input_result[MAX_LEN + 1]; + +/* + * Print the termination buttons + */ +static void +print_buttons(WINDOW *dialog, int height, int width, int selected) +{ + int x = width / 2 - 11; + int y = height - 2; + + print_button (dialog, " Ok ", y, x, selected==0); + print_button (dialog, " Help ", y, x + 14, selected==1); + + wmove(dialog, y, x+1+14*selected); + wrefresh(dialog); +} + +/* + * Display a dialog box for inputing a string + */ +int +dialog_inputbox (const char *title, const char *prompt, int height, int width, + const char *init) +{ + int i, x, y, box_y, box_x, box_width; + int input_x = 0, scroll = 0, key = 0, button = -1; + unsigned char *instr = dialog_input_result; + WINDOW *dialog; + + /* center dialog box on screen */ + x = (COLS - width) / 2; + y = (LINES - height) / 2; + + + draw_shadow (stdscr, y, x, height, width); + + dialog = newwin (height, width, y, x); + keypad (dialog, TRUE); + + draw_box (dialog, 0, 0, height, width, dialog_attr, border_attr); + wattrset (dialog, border_attr); + mvwaddch (dialog, height-3, 0, ACS_LTEE); + for (i = 0; i < width - 2; i++) + waddch (dialog, ACS_HLINE); + wattrset (dialog, dialog_attr); + waddch (dialog, ACS_RTEE); + + if (title != NULL) { + wattrset (dialog, title_attr); + mvwaddch (dialog, 0, (width - strlen(title))/2 - 1, ' '); + waddstr (dialog, (char *)title); + waddch (dialog, ' '); + } + + wattrset (dialog, dialog_attr); + print_autowrap (dialog, prompt, width - 2, 1, 3); + + /* Draw the input field box */ + box_width = width - 6; + getyx (dialog, y, x); + box_y = y + 2; + box_x = (width - box_width) / 2; + draw_box (dialog, y + 1, box_x - 1, 3, box_width + 2, + border_attr, dialog_attr); + + print_buttons(dialog, height, width, 0); + + /* Set up the initial value */ + wmove (dialog, box_y, box_x); + wattrset (dialog, inputbox_attr); + + if (!init) + instr[0] = '\0'; + else + strcpy (instr, init); + + input_x = strlen (instr); + + if (input_x >= box_width) { + scroll = input_x - box_width + 1; + input_x = box_width - 1; + for (i = 0; i < box_width - 1; i++) + waddch (dialog, instr[scroll + i]); + } else + waddstr (dialog, instr); + + wmove (dialog, box_y, box_x + input_x); + + wrefresh (dialog); + + while (key != ESC) { + key = wgetch (dialog); + + if (button == -1) { /* Input box selected */ + switch (key) { + case TAB: + case KEY_UP: + case KEY_DOWN: + break; + case KEY_LEFT: + continue; + case KEY_RIGHT: + continue; + case KEY_BACKSPACE: + case 127: + if (input_x || scroll) { + wattrset (dialog, inputbox_attr); + if (!input_x) { + scroll = scroll < box_width - 1 ? + 0 : scroll - (box_width - 1); + wmove (dialog, box_y, box_x); + for (i = 0; i < box_width; i++) + waddch (dialog, instr[scroll + input_x + i] ? + instr[scroll + input_x + i] : ' '); + input_x = strlen (instr) - scroll; + } else + input_x--; + instr[scroll + input_x] = '\0'; + mvwaddch (dialog, box_y, input_x + box_x, ' '); + wmove (dialog, box_y, input_x + box_x); + wrefresh (dialog); + } + continue; + default: + if (key < 0x100 && isprint (key)) { + if (scroll + input_x < MAX_LEN) { + wattrset (dialog, inputbox_attr); + instr[scroll + input_x] = key; + instr[scroll + input_x + 1] = '\0'; + if (input_x == box_width - 1) { + scroll++; + wmove (dialog, box_y, box_x); + for (i = 0; i < box_width - 1; i++) + waddch (dialog, instr[scroll + i]); + } else { + wmove (dialog, box_y, input_x++ + box_x); + waddch (dialog, key); + } + wrefresh (dialog); + } else + flash (); /* Alarm user about overflow */ + continue; + } + } + } + switch (key) { + case 'O': + case 'o': + delwin (dialog); + return 0; + case 'H': + case 'h': + delwin (dialog); + return 1; + case KEY_UP: + case KEY_LEFT: + switch (button) { + case -1: + button = 1; /* Indicates "Cancel" button is selected */ + print_buttons(dialog, height, width, 1); + break; + case 0: + button = -1; /* Indicates input box is selected */ + print_buttons(dialog, height, width, 0); + wmove (dialog, box_y, box_x + input_x); + wrefresh (dialog); + break; + case 1: + button = 0; /* Indicates "OK" button is selected */ + print_buttons(dialog, height, width, 0); + break; + } + break; + case TAB: + case KEY_DOWN: + case KEY_RIGHT: + switch (button) { + case -1: + button = 0; /* Indicates "OK" button is selected */ + print_buttons(dialog, height, width, 0); + break; + case 0: + button = 1; /* Indicates "Cancel" button is selected */ + print_buttons(dialog, height, width, 1); + break; + case 1: + button = -1; /* Indicates input box is selected */ + print_buttons(dialog, height, width, 0); + wmove (dialog, box_y, box_x + input_x); + wrefresh (dialog); + break; + } + break; + case ' ': + case '\n': + delwin (dialog); + return (button == -1 ? 0 : button); + case 'X': + case 'x': + key = ESC; + case ESC: + break; + } + } + + delwin (dialog); + return -1; /* ESC pressed */ +} diff --git a/scripts/lxdialog/lxdialog.c b/scripts/lxdialog/lxdialog.c new file mode 100644 index 00000000..0c70113c --- /dev/null +++ b/scripts/lxdialog/lxdialog.c @@ -0,0 +1,223 @@ +/* + * dialog - Display simple dialog boxes from shell scripts + * + * ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk) + * MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com) + * + * 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. + */ + +#include "dialog.h" + +static void Usage (const char *name); + +typedef int (jumperFn) (const char *title, int argc, const char * const * argv); + +struct Mode { + char *name; + int argmin, argmax, argmod; + jumperFn *jumper; +}; + +jumperFn j_menu, j_checklist, j_radiolist, j_yesno, j_textbox, j_inputbox; +jumperFn j_msgbox, j_infobox; + +static struct Mode modes[] = +{ + {"--menu", 9, 0, 3, j_menu}, + {"--checklist", 9, 0, 3, j_checklist}, + {"--radiolist", 9, 0, 3, j_radiolist}, + {"--yesno", 5,5,1, j_yesno}, + {"--textbox", 5,5,1, j_textbox}, + {"--inputbox", 5, 6, 1, j_inputbox}, + {"--msgbox", 5, 5, 1, j_msgbox}, + {"--infobox", 5, 5, 1, j_infobox}, + {NULL, 0, 0, 0, NULL} +}; + +static struct Mode *modePtr; + +#ifdef LOCALE +#include +#endif + +int +main (int argc, const char * const * argv) +{ + int offset = 0, clear_screen = 0, end_common_opts = 0, retval; + const char *title = NULL; + +#ifdef LOCALE + (void) setlocale (LC_ALL, ""); +#endif + + if (argc < 2) { + Usage (argv[0]); + exit (-1); + } + + while (offset < argc - 1 && !end_common_opts) { /* Common options */ + if (!strcmp (argv[offset + 1], "--title")) { + if (argc - offset < 3 || title != NULL) { + Usage (argv[0]); + exit (-1); + } else { + title = argv[offset + 2]; + offset += 2; + } + } else if (!strcmp (argv[offset + 1], "--backtitle")) { + if (backtitle != NULL) { + Usage (argv[0]); + exit (-1); + } else { + backtitle = argv[offset + 2]; + offset += 2; + } + } else if (!strcmp (argv[offset + 1], "--clear")) { + if (clear_screen) { /* Hey, "--clear" can't appear twice! */ + Usage (argv[0]); + exit (-1); + } else if (argc == 2) { /* we only want to clear the screen */ + init_dialog (); + refresh (); /* init_dialog() will clear the screen for us */ + end_dialog (); + return 0; + } else { + clear_screen = 1; + offset++; + } + } else /* no more common options */ + end_common_opts = 1; + } + + if (argc - 1 == offset) { /* no more options */ + Usage (argv[0]); + exit (-1); + } + /* use a table to look for the requested mode, to avoid code duplication */ + + for (modePtr = modes; modePtr->name; modePtr++) /* look for the mode */ + if (!strcmp (argv[offset + 1], modePtr->name)) + break; + + if (!modePtr->name) + Usage (argv[0]); + if (argc - offset < modePtr->argmin) + Usage (argv[0]); + if (modePtr->argmax && argc - offset > modePtr->argmax) + Usage (argv[0]); + + + + init_dialog (); + retval = (*(modePtr->jumper)) (title, argc - offset, argv + offset); + + if (clear_screen) { /* clear screen before exit */ + attr_clear (stdscr, LINES, COLS, screen_attr); + refresh (); + } + end_dialog(); + + exit (retval); +} + +/* + * Print program usage + */ +static void +Usage (const char *name) +{ + fprintf (stderr, "\ +\ndialog, by Savio Lam (lam836@cs.cuhk.hk).\ +\n patched by Stuart Herbert (S.Herbert@shef.ac.uk)\ +\n modified/gutted for use as a Linux kernel config tool by \ +\n William Roadcap (roadcapw@cfw.com)\ +\n\ +\n* Display dialog boxes from shell scripts *\ +\n\ +\nUsage: %s --clear\ +\n %s [--title ] [--backtitle <backtitle>] --clear <Box options>\ +\n\ +\nBox options:\ +\n\ +\n --menu <text> <height> <width> <menu height> <tag1> <item1>...\ +\n --checklist <text> <height> <width> <list height> <tag1> <item1> <status1>...\ +\n --radiolist <text> <height> <width> <list height> <tag1> <item1> <status1>...\ +\n --textbox <file> <height> <width>\ +\n --inputbox <text> <height> <width> [<init>]\ +\n --yesno <text> <height> <width>\ +", name, name); + exit (-1); +} + +/* + * These are the program jumpers + */ + +int +j_menu (const char *t, int ac, const char * const * av) +{ + return dialog_menu (t, av[2], atoi (av[3]), atoi (av[4]), + atoi (av[5]), av[6], (ac - 6) / 2, av + 7); +} + +int +j_checklist (const char *t, int ac, const char * const * av) +{ + return dialog_checklist (t, av[2], atoi (av[3]), atoi (av[4]), + atoi (av[5]), (ac - 6) / 3, av + 6, FLAG_CHECK); +} + +int +j_radiolist (const char *t, int ac, const char * const * av) +{ + return dialog_checklist (t, av[2], atoi (av[3]), atoi (av[4]), + atoi (av[5]), (ac - 6) / 3, av + 6, FLAG_RADIO); +} + +int +j_textbox (const char *t, int ac, const char * const * av) +{ + return dialog_textbox (t, av[2], atoi (av[3]), atoi (av[4])); +} + +int +j_yesno (const char *t, int ac, const char * const * av) +{ + return dialog_yesno (t, av[2], atoi (av[3]), atoi (av[4])); +} + +int +j_inputbox (const char *t, int ac, const char * const * av) +{ + int ret = dialog_inputbox (t, av[2], atoi (av[3]), atoi (av[4]), + ac == 6 ? av[5] : (char *) NULL); + if (ret == 0) + fputs(dialog_input_result, stderr); + return ret; +} + +int +j_msgbox (const char *t, int ac, const char * const * av) +{ + return dialog_msgbox (t, av[2], atoi (av[3]), atoi (av[4]), 1); +} + +int +j_infobox (const char *t, int ac, const char * const * av) +{ + return dialog_msgbox (t, av[2], atoi (av[3]), atoi (av[4]), 0); +} + diff --git a/scripts/lxdialog/menubox.c b/scripts/lxdialog/menubox.c new file mode 100644 index 00000000..ad438087 --- /dev/null +++ b/scripts/lxdialog/menubox.c @@ -0,0 +1,350 @@ +/* + * menubox.c -- implements the menu box + * + * ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk) + * MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcapw@cfw.com) + * + * 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. + */ + +#include "dialog.h" + +static int menu_width, item_x; + +/* + * Print menu item + */ +static void +print_item (WINDOW * win, const char *item, int choice, int selected, int hotkey) +{ + int i, j; + char menu_item[menu_width+1]; + + strncpy(menu_item, item, menu_width); + menu_item[menu_width] = 0; + j = first_alpha(menu_item, "YyNnMm"); + + /* Clear 'residue' of last item */ + wattrset (win, menubox_attr); + wmove (win, choice, 0); + for (i = 0; i < menu_width; i++) + waddch (win, ' '); + wattrset (win, selected ? item_selected_attr : item_attr); + mvwaddstr (win, choice, item_x, menu_item); + if (hotkey) { + wattrset (win, selected ? tag_key_selected_attr : tag_key_attr); + mvwaddch(win, choice, item_x+j, menu_item[j]); + } +} + +/* + * Print the scroll indicators. + */ +static void +print_arrows (WINDOW * win, int item_no, int scroll, + int y, int x, int height) +{ + int cur_y, cur_x; + + getyx(win, cur_y, cur_x); + + wmove(win, y, x); + + if (scroll > 0) { + wattrset (win, uarrow_attr); + waddch (win, ACS_UARROW); + waddstr (win, "(-)"); + } + else { + wattrset (win, menubox_attr); + waddch (win, ACS_HLINE); + waddch (win, ACS_HLINE); + waddch (win, ACS_HLINE); + waddch (win, ACS_HLINE); + } + + y = y + height + 1; + wmove(win, y, x); + + if ((height < item_no) && (scroll + height < item_no)) { + wattrset (win, darrow_attr); + waddch (win, ACS_DARROW); + waddstr (win, "(+)"); + } + else { + wattrset (win, menubox_border_attr); + waddch (win, ACS_HLINE); + waddch (win, ACS_HLINE); + waddch (win, ACS_HLINE); + waddch (win, ACS_HLINE); + } + + wmove(win, cur_y, cur_x); +} + +/* + * Display the termination buttons. + */ +static void +print_buttons (WINDOW *win, int height, int width, int selected) +{ + int x = width / 2 - 16; + int y = height - 2; + + print_button (win, "Select", y, x, selected == 0); + print_button (win, " Exit ", y, x + 12, selected == 1); + print_button (win, " Help ", y, x + 24, selected == 2); + + wmove(win, y, x+1+12*selected); + wrefresh (win); +} + +/* + * Display a menu for choosing among a number of options + */ +int +dialog_menu (const char *title, const char *prompt, int height, int width, + int menu_height, const char *current, int item_no, + const char * const * items) + +{ + int i, j, x, y, box_x, box_y; + int key = 0, button = 0, scroll = 0, choice = 0, first_item = 0, max_choice; + WINDOW *dialog, *menu; + + max_choice = MIN (menu_height, item_no); + + /* center dialog box on screen */ + x = (COLS - width) / 2; + y = (LINES - height) / 2; + + draw_shadow (stdscr, y, x, height, width); + + dialog = newwin (height, width, y, x); + keypad (dialog, TRUE); + + draw_box (dialog, 0, 0, height, width, dialog_attr, border_attr); + wattrset (dialog, border_attr); + mvwaddch (dialog, height - 3, 0, ACS_LTEE); + for (i = 0; i < width - 2; i++) + waddch (dialog, ACS_HLINE); + wattrset (dialog, dialog_attr); + waddch (dialog, ACS_RTEE); + + if (title != NULL) { + wattrset (dialog, title_attr); + mvwaddch (dialog, 0, (width - strlen(title))/2 - 1, ' '); + waddstr (dialog, (char *)title); + waddch (dialog, ' '); + } + + wattrset (dialog, dialog_attr); + print_autowrap (dialog, prompt, width - 2, 1, 3); + + menu_width = width - 6; + box_y = height - menu_height - 5; + box_x = (width - menu_width) / 2 - 1; + + /* create new window for the menu */ + menu = subwin (dialog, menu_height, menu_width, + y + box_y + 1, x + box_x + 1); + keypad (menu, TRUE); + + /* draw a box around the menu items */ + draw_box (dialog, box_y, box_x, menu_height + 2, menu_width + 2, + menubox_border_attr, menubox_attr); + + /* + * Find length of longest item in order to center menu. + * Set 'choice' to default item. + */ + item_x = 0; + for (i = 0; i < item_no; i++) { + item_x = MAX (item_x, MIN(menu_width, strlen (items[i * 2 + 1]) + 2)); + if (strcmp(current, items[i*2]) == 0) choice = i; + } + + item_x = (menu_width - item_x) / 2; + + if (choice >= max_choice){ + scroll = first_item = choice - max_choice + 1; + choice = max_choice-1; + } + + /* Print the menu */ + for (i=0; i < max_choice; i++) { + print_item (menu, items[(first_item + i) * 2 + 1], i, i == choice, + (items[(first_item + i)*2][0] != ':')); + } + + wnoutrefresh (menu); + + print_arrows(dialog, item_no, scroll, + box_y, box_x+item_x+1, menu_height); + + print_buttons (dialog, height, width, 0); + + while (key != ESC) { + key = wgetch(dialog); + + if (key < 256 && isalpha(key)) key = tolower(key); + + if (strchr("ynm", key)) + i = max_choice; + else { + for (i = choice+1; i < max_choice; i++) { + j = first_alpha(items[(scroll+i)*2+1], "YyNnMm"); + if (key == tolower(items[(scroll+i)*2+1][j])) + break; + } + if (i == max_choice) + for (i = 0; i < max_choice; i++) { + j = first_alpha(items[(scroll+i)*2+1], "YyNnMm"); + if (key == tolower(items[(scroll+i)*2+1][j])) + break; + } + } + + if (i < max_choice || + key == KEY_UP || key == KEY_DOWN || + key == '-' || key == '+' || + key == KEY_PPAGE || key == KEY_NPAGE) { + + print_item (menu, items[(scroll+choice)*2+1], choice, FALSE, + (items[(scroll+choice)*2][0] != ':')); + + if (key == KEY_UP || key == '-') { + if (choice < 2 && scroll) { + /* Scroll menu down */ + scrollok (menu, TRUE); + wscrl (menu, -1); + scrollok (menu, FALSE); + + scroll--; + + print_item (menu, items[scroll * 2 + 1], 0, FALSE, + (items[scroll*2][0] != ':')); + } else + choice = MAX(choice - 1, 0); + + } else if (key == KEY_DOWN || key == '+') { + + print_item (menu, items[(scroll+choice)*2+1], choice, FALSE, + (items[(scroll+choice)*2][0] != ':')); + + if ((choice > max_choice-3) && + (scroll + max_choice < item_no) + ) { + /* Scroll menu up */ + scrollok (menu, TRUE); + scroll (menu); + scrollok (menu, FALSE); + + scroll++; + + print_item (menu, items[(scroll+max_choice-1)*2+1], + max_choice-1, FALSE, + (items[(scroll+max_choice-1)*2][0] != ':')); + } else + choice = MIN(choice+1, max_choice-1); + + } else if (key == KEY_PPAGE) { + scrollok (menu, TRUE); + for (i=0; (i < max_choice) && (scroll > 0); i++) { + wscrl (menu, -1); + scroll--; + print_item (menu, items[scroll * 2 + 1], 0, FALSE, + (items[scroll*2][0] != ':')); + } + scrollok (menu, FALSE); + choice = 0; + + } else if (key == KEY_NPAGE) { + scrollok (menu, TRUE); + for (i=0; (i < max_choice) && (scroll+max_choice < item_no); i++) { + scroll(menu); + scroll++; + print_item (menu, items[(scroll+max_choice-1)*2+1], + max_choice-1, FALSE, + (items[(scroll+max_choice-1)*2][0] != ':')); + } + scrollok (menu, FALSE); + choice = 0; + + } else + choice = i; + + print_item (menu, items[(scroll+choice)*2+1], choice, TRUE, + (items[(scroll+choice)*2][0] != ':')); + + print_arrows(dialog, item_no, scroll, + box_y, box_x+item_x+1, menu_height); + + wnoutrefresh (menu); + wrefresh (dialog); + + continue; /* wait for another key press */ + } + + switch (key) { + case KEY_LEFT: + case TAB: + case KEY_RIGHT: + button = ((key == KEY_LEFT ? --button : ++button) < 0) + ? 2 : (button > 2 ? 0 : button); + + print_buttons(dialog, height, width, button); + wrefresh (dialog); + break; + case ' ': + case 's': + case 'y': + case 'n': + case 'm': + delwin (dialog); + fprintf(stderr, "%s\n", items[(scroll + choice) * 2]); + switch (key) { + case 's': return 3; + case 'y': return 3; + case 'n': return 4; + case 'm': return 5; + case ' ': return 6; + } + return 0; + case 'h': + case '?': + button = 2; + case '\n': + delwin (dialog); + if (button == 2) + fprintf(stderr, "%s \"%s\"\n", + items[(scroll + choice) * 2], + items[(scroll + choice) * 2 + 1] + + first_alpha(items[(scroll + choice) * 2 + 1],"")); + else + fprintf(stderr, "%s\n", items[(scroll + choice) * 2]); + + return button; + case 'e': + case 'x': + key = ESC; + case ESC: + break; + } + } + + delwin (dialog); + return -1; /* ESC pressed */ +} diff --git a/scripts/lxdialog/msgbox.c b/scripts/lxdialog/msgbox.c new file mode 100644 index 00000000..be17c16d --- /dev/null +++ b/scripts/lxdialog/msgbox.c @@ -0,0 +1,77 @@ +/* + * msgbox.c -- implements the message box and info box + * + * ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk) + * MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcapw@cfw.com) + * + * 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. + */ + +#include "dialog.h" + +/* + * Display a message box. Program will pause and display an "OK" button + * if the parameter 'pause' is non-zero. + */ +int +dialog_msgbox (const char *title, const char *prompt, int height, int width, + int pause) +{ + int i, x, y, key = 0; + WINDOW *dialog; + + /* center dialog box on screen */ + x = (COLS - width) / 2; + y = (LINES - height) / 2; + + draw_shadow (stdscr, y, x, height, width); + + dialog = newwin (height, width, y, x); + keypad (dialog, TRUE); + + draw_box (dialog, 0, 0, height, width, dialog_attr, border_attr); + + if (title != NULL) { + wattrset (dialog, title_attr); + mvwaddch (dialog, 0, (width - strlen(title))/2 - 1, ' '); + waddstr (dialog, (char *)title); + waddch (dialog, ' '); + } + wattrset (dialog, dialog_attr); + print_autowrap (dialog, prompt, width - 2, 1, 2); + + if (pause) { + wattrset (dialog, border_attr); + mvwaddch (dialog, height - 3, 0, ACS_LTEE); + for (i = 0; i < width - 2; i++) + waddch (dialog, ACS_HLINE); + wattrset (dialog, dialog_attr); + waddch (dialog, ACS_RTEE); + + print_button (dialog, " Ok ", + height - 2, width / 2 - 4, TRUE); + + wrefresh (dialog); + while (key != ESC && key != '\n' && key != ' ' && + key != 'O' && key != 'o' && key != 'X' && key != 'x') + key = wgetch (dialog); + } else { + key = '\n'; + wrefresh (dialog); + } + delwin (dialog); + + return key == ESC ? -1 : 0; +} diff --git a/scripts/lxdialog/textbox.c b/scripts/lxdialog/textbox.c new file mode 100644 index 00000000..df50f2c5 --- /dev/null +++ b/scripts/lxdialog/textbox.c @@ -0,0 +1,537 @@ +/* + * textbox.c -- implements the text box + * + * ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk) + * MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com) + * + * 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. + */ + +#include "dialog.h" + +static void back_lines (int n); +static void print_page (WINDOW * win, int height, int width); +static void print_line (WINDOW * win, int row, int width); +static char *get_line (void); +static void print_position (WINDOW * win, int height, int width); + +static int hscroll = 0, fd, file_size, bytes_read; +static int begin_reached = 1, end_reached = 0, page_length; +static char *buf, *page; + +/* + * Display text from a file in a dialog box. + */ +int +dialog_textbox (const char *title, const char *file, int height, int width) +{ + int i, x, y, cur_x, cur_y, fpos, key = 0; + int passed_end; + char search_term[MAX_LEN + 1]; + WINDOW *dialog, *text; + + search_term[0] = '\0'; /* no search term entered yet */ + + /* Open input file for reading */ + if ((fd = open (file, O_RDONLY)) == -1) { + endwin (); + fprintf (stderr, + "\nCan't open input file in dialog_textbox().\n"); + exit (-1); + } + /* Get file size. Actually, 'file_size' is the real file size - 1, + since it's only the last byte offset from the beginning */ + if ((file_size = lseek (fd, 0, SEEK_END)) == -1) { + endwin (); + fprintf (stderr, "\nError getting file size in dialog_textbox().\n"); + exit (-1); + } + /* Restore file pointer to beginning of file after getting file size */ + if (lseek (fd, 0, SEEK_SET) == -1) { + endwin (); + fprintf (stderr, "\nError moving file pointer in dialog_textbox().\n"); + exit (-1); + } + /* Allocate space for read buffer */ + if ((buf = malloc (BUF_SIZE + 1)) == NULL) { + endwin (); + fprintf (stderr, "\nCan't allocate memory in dialog_textbox().\n"); + exit (-1); + } + if ((bytes_read = read (fd, buf, BUF_SIZE)) == -1) { + endwin (); + fprintf (stderr, "\nError reading file in dialog_textbox().\n"); + exit (-1); + } + buf[bytes_read] = '\0'; /* mark end of valid data */ + page = buf; /* page is pointer to start of page to be displayed */ + + /* center dialog box on screen */ + x = (COLS - width) / 2; + y = (LINES - height) / 2; + + + draw_shadow (stdscr, y, x, height, width); + + dialog = newwin (height, width, y, x); + keypad (dialog, TRUE); + + /* Create window for text region, used for scrolling text */ + text = subwin (dialog, height - 4, width - 2, y + 1, x + 1); + + keypad (text, TRUE); + + /* register the new window, along with its borders */ + draw_box (dialog, 0, 0, height, width, dialog_attr, border_attr); + + wattrset (dialog, border_attr); + mvwaddch (dialog, height-3, 0, ACS_LTEE); + for (i = 0; i < width - 2; i++) + waddch (dialog, ACS_HLINE); + wattrset (dialog, dialog_attr); + waddch (dialog, ACS_RTEE); + + if (title != NULL) { + wattrset (dialog, title_attr); + mvwaddch (dialog, 0, (width - strlen(title))/2 - 1, ' '); + waddstr (dialog, (char *)title); + waddch (dialog, ' '); + } + print_button (dialog, " Exit ", height - 2, width / 2 - 4, TRUE); + wnoutrefresh (dialog); + getyx (dialog, cur_y, cur_x); /* Save cursor position */ + + /* Print first page of text */ + attr_clear (text, height - 4, width - 2, dialog_attr); + print_page (text, height - 4, width - 2); + print_position (dialog, height, width); + wmove (dialog, cur_y, cur_x); /* Restore cursor position */ + wrefresh (dialog); + + while ((key != ESC) && (key != '\n')) { + key = wgetch (dialog); + switch (key) { + case 'E': /* Exit */ + case 'e': + case 'X': + case 'x': + delwin (dialog); + free (buf); + close (fd); + return 0; + case 'g': /* First page */ + case KEY_HOME: + if (!begin_reached) { + begin_reached = 1; + /* First page not in buffer? */ + if ((fpos = lseek (fd, 0, SEEK_CUR)) == -1) { + endwin (); + fprintf (stderr, + "\nError moving file pointer in dialog_textbox().\n"); + exit (-1); + } + if (fpos > bytes_read) { /* Yes, we have to read it in */ + if (lseek (fd, 0, SEEK_SET) == -1) { + endwin (); + fprintf (stderr, "\nError moving file pointer in " + "dialog_textbox().\n"); + exit (-1); + } + if ((bytes_read = read (fd, buf, BUF_SIZE)) == -1) { + endwin (); + fprintf (stderr, + "\nError reading file in dialog_textbox().\n"); + exit (-1); + } + buf[bytes_read] = '\0'; + } + page = buf; + print_page (text, height - 4, width - 2); + print_position (dialog, height, width); + wmove (dialog, cur_y, cur_x); /* Restore cursor position */ + wrefresh (dialog); + } + break; + case 'G': /* Last page */ + case KEY_END: + + end_reached = 1; + /* Last page not in buffer? */ + if ((fpos = lseek (fd, 0, SEEK_CUR)) == -1) { + endwin (); + fprintf (stderr, + "\nError moving file pointer in dialog_textbox().\n"); + exit (-1); + } + if (fpos < file_size) { /* Yes, we have to read it in */ + if (lseek (fd, -BUF_SIZE, SEEK_END) == -1) { + endwin (); + fprintf (stderr, + "\nError moving file pointer in dialog_textbox().\n"); + exit (-1); + } + if ((bytes_read = read (fd, buf, BUF_SIZE)) == -1) { + endwin (); + fprintf (stderr, + "\nError reading file in dialog_textbox().\n"); + exit (-1); + } + buf[bytes_read] = '\0'; + } + page = buf + bytes_read; + back_lines (height - 4); + print_page (text, height - 4, width - 2); + print_position (dialog, height, width); + wmove (dialog, cur_y, cur_x); /* Restore cursor position */ + wrefresh (dialog); + break; + case 'K': /* Previous line */ + case 'k': + case KEY_UP: + if (!begin_reached) { + back_lines (page_length + 1); + + /* We don't call print_page() here but use scrolling to ensure + faster screen update. However, 'end_reached' and + 'page_length' should still be updated, and 'page' should + point to start of next page. This is done by calling + get_line() in the following 'for' loop. */ + scrollok (text, TRUE); + wscrl (text, -1); /* Scroll text region down one line */ + scrollok (text, FALSE); + page_length = 0; + passed_end = 0; + for (i = 0; i < height - 4; i++) { + if (!i) { + /* print first line of page */ + print_line (text, 0, width - 2); + wnoutrefresh (text); + } else + /* Called to update 'end_reached' and 'page' */ + get_line (); + if (!passed_end) + page_length++; + if (end_reached && !passed_end) + passed_end = 1; + } + + print_position (dialog, height, width); + wmove (dialog, cur_y, cur_x); /* Restore cursor position */ + wrefresh (dialog); + } + break; + case 'B': /* Previous page */ + case 'b': + case KEY_PPAGE: + if (begin_reached) + break; + back_lines (page_length + height - 4); + print_page (text, height - 4, width - 2); + print_position (dialog, height, width); + wmove (dialog, cur_y, cur_x); + wrefresh (dialog); + break; + case 'J': /* Next line */ + case 'j': + case KEY_DOWN: + if (!end_reached) { + begin_reached = 0; + scrollok (text, TRUE); + scroll (text); /* Scroll text region up one line */ + scrollok (text, FALSE); + print_line (text, height - 5, width - 2); + wnoutrefresh (text); + print_position (dialog, height, width); + wmove (dialog, cur_y, cur_x); /* Restore cursor position */ + wrefresh (dialog); + } + break; + case KEY_NPAGE: /* Next page */ + case ' ': + if (end_reached) + break; + + begin_reached = 0; + print_page (text, height - 4, width - 2); + print_position (dialog, height, width); + wmove (dialog, cur_y, cur_x); + wrefresh (dialog); + break; + case '0': /* Beginning of line */ + case 'H': /* Scroll left */ + case 'h': + case KEY_LEFT: + if (hscroll <= 0) + break; + + if (key == '0') + hscroll = 0; + else + hscroll--; + /* Reprint current page to scroll horizontally */ + back_lines (page_length); + print_page (text, height - 4, width - 2); + wmove (dialog, cur_y, cur_x); + wrefresh (dialog); + break; + case 'L': /* Scroll right */ + case 'l': + case KEY_RIGHT: + if (hscroll >= MAX_LEN) + break; + hscroll++; + /* Reprint current page to scroll horizontally */ + back_lines (page_length); + print_page (text, height - 4, width - 2); + wmove (dialog, cur_y, cur_x); + wrefresh (dialog); + break; + case ESC: + break; + } + } + + delwin (dialog); + free (buf); + close (fd); + return -1; /* ESC pressed */ +} + +/* + * Go back 'n' lines in text file. Called by dialog_textbox(). + * 'page' will be updated to point to the desired line in 'buf'. + */ +static void +back_lines (int n) +{ + int i, fpos; + + begin_reached = 0; + /* We have to distinguish between end_reached and !end_reached + since at end of file, the line is not ended by a '\n'. + The code inside 'if' basically does a '--page' to move one + character backward so as to skip '\n' of the previous line */ + if (!end_reached) { + /* Either beginning of buffer or beginning of file reached? */ + if (page == buf) { + if ((fpos = lseek (fd, 0, SEEK_CUR)) == -1) { + endwin (); + fprintf (stderr, "\nError moving file pointer in " + "back_lines().\n"); + exit (-1); + } + if (fpos > bytes_read) { /* Not beginning of file yet */ + /* We've reached beginning of buffer, but not beginning of + file yet, so read previous part of file into buffer. + Note that we only move backward for BUF_SIZE/2 bytes, + but not BUF_SIZE bytes to avoid re-reading again in + print_page() later */ + /* Really possible to move backward BUF_SIZE/2 bytes? */ + if (fpos < BUF_SIZE / 2 + bytes_read) { + /* No, move less then */ + if (lseek (fd, 0, SEEK_SET) == -1) { + endwin (); + fprintf (stderr, "\nError moving file pointer in " + "back_lines().\n"); + exit (-1); + } + page = buf + fpos - bytes_read; + } else { /* Move backward BUF_SIZE/2 bytes */ + if (lseek (fd, -(BUF_SIZE / 2 + bytes_read), SEEK_CUR) + == -1) { + endwin (); + fprintf (stderr, "\nError moving file pointer " + "in back_lines().\n"); + exit (-1); + } + page = buf + BUF_SIZE / 2; + } + if ((bytes_read = read (fd, buf, BUF_SIZE)) == -1) { + endwin (); + fprintf (stderr, "\nError reading file in back_lines().\n"); + exit (-1); + } + buf[bytes_read] = '\0'; + } else { /* Beginning of file reached */ + begin_reached = 1; + return; + } + } + if (*(--page) != '\n') { /* '--page' here */ + /* Something's wrong... */ + endwin (); + fprintf (stderr, "\nInternal error in back_lines().\n"); + exit (-1); + } + } + /* Go back 'n' lines */ + for (i = 0; i < n; i++) + do { + if (page == buf) { + if ((fpos = lseek (fd, 0, SEEK_CUR)) == -1) { + endwin (); + fprintf (stderr, + "\nError moving file pointer in back_lines().\n"); + exit (-1); + } + if (fpos > bytes_read) { + /* Really possible to move backward BUF_SIZE/2 bytes? */ + if (fpos < BUF_SIZE / 2 + bytes_read) { + /* No, move less then */ + if (lseek (fd, 0, SEEK_SET) == -1) { + endwin (); + fprintf (stderr, "\nError moving file pointer " + "in back_lines().\n"); + exit (-1); + } + page = buf + fpos - bytes_read; + } else { /* Move backward BUF_SIZE/2 bytes */ + if (lseek (fd, -(BUF_SIZE / 2 + bytes_read), + SEEK_CUR) == -1) { + endwin (); + fprintf (stderr, "\nError moving file pointer" + " in back_lines().\n"); + exit (-1); + } + page = buf + BUF_SIZE / 2; + } + if ((bytes_read = read (fd, buf, BUF_SIZE)) == -1) { + endwin (); + fprintf (stderr, "\nError reading file in " + "back_lines().\n"); + exit (-1); + } + buf[bytes_read] = '\0'; + } else { /* Beginning of file reached */ + begin_reached = 1; + return; + } + } + } while (*(--page) != '\n'); + page++; +} + +/* + * Print a new page of text. Called by dialog_textbox(). + */ +static void +print_page (WINDOW * win, int height, int width) +{ + int i, passed_end = 0; + + page_length = 0; + for (i = 0; i < height; i++) { + print_line (win, i, width); + if (!passed_end) + page_length++; + if (end_reached && !passed_end) + passed_end = 1; + } + wnoutrefresh (win); +} + +/* + * Print a new line of text. Called by dialog_textbox() and print_page(). + */ +static void +print_line (WINDOW * win, int row, int width) +{ + int i, y, x; + char *line; + + line = get_line (); + line += MIN (strlen (line), hscroll); /* Scroll horizontally */ + wmove (win, row, 0); /* move cursor to correct line */ + waddch (win, ' '); + waddnstr (win, line, MIN (strlen (line), width - 2)); + + getyx (win, y, x); + /* Clear 'residue' of previous line */ + for (i = 0; i < width - x; i++) + waddch (win, ' '); +} + +/* + * Return current line of text. Called by dialog_textbox() and print_line(). + * 'page' should point to start of current line before calling, and will be + * updated to point to start of next line. + */ +static char * +get_line (void) +{ + int i = 0, fpos; + static char line[MAX_LEN + 1]; + + end_reached = 0; + while (*page != '\n') { + if (*page == '\0') { + /* Either end of file or end of buffer reached */ + if ((fpos = lseek (fd, 0, SEEK_CUR)) == -1) { + endwin (); + fprintf (stderr, "\nError moving file pointer in " + "get_line().\n"); + exit (-1); + } + if (fpos < file_size) { /* Not end of file yet */ + /* We've reached end of buffer, but not end of file yet, + so read next part of file into buffer */ + if ((bytes_read = read (fd, buf, BUF_SIZE)) == -1) { + endwin (); + fprintf (stderr, "\nError reading file in get_line().\n"); + exit (-1); + } + buf[bytes_read] = '\0'; + page = buf; + } else { + if (!end_reached) + end_reached = 1; + break; + } + } else if (i < MAX_LEN) + line[i++] = *(page++); + else { + /* Truncate lines longer than MAX_LEN characters */ + if (i == MAX_LEN) + line[i++] = '\0'; + page++; + } + } + if (i <= MAX_LEN) + line[i] = '\0'; + if (!end_reached) + page++; /* move pass '\n' */ + + return line; +} + +/* + * Print current position + */ +static void +print_position (WINDOW * win, int height, int width) +{ + int fpos, percent; + + if ((fpos = lseek (fd, 0, SEEK_CUR)) == -1) { + endwin (); + fprintf (stderr, "\nError moving file pointer in print_position().\n"); + exit (-1); + } + wattrset (win, position_indicator_attr); + percent = !file_size ? + 100 : ((fpos - bytes_read + page - buf) * 100) / file_size; + wmove (win, height - 3, width - 9); + wprintw (win, "(%3d%%)", percent); +} diff --git a/scripts/lxdialog/util.c b/scripts/lxdialog/util.c new file mode 100644 index 00000000..b3a7af9d --- /dev/null +++ b/scripts/lxdialog/util.c @@ -0,0 +1,359 @@ +/* + * util.c + * + * ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk) + * MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com) + * + * 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. + */ + +#include "dialog.h" + + +/* use colors by default? */ +bool use_colors = 1; + +const char *backtitle = NULL; + +const char *dialog_result; + +/* + * Attribute values, default is for mono display + */ +chtype attributes[] = +{ + A_NORMAL, /* screen_attr */ + A_NORMAL, /* shadow_attr */ + A_NORMAL, /* dialog_attr */ + A_BOLD, /* title_attr */ + A_NORMAL, /* border_attr */ + A_REVERSE, /* button_active_attr */ + A_DIM, /* button_inactive_attr */ + A_REVERSE, /* button_key_active_attr */ + A_BOLD, /* button_key_inactive_attr */ + A_REVERSE, /* button_label_active_attr */ + A_NORMAL, /* button_label_inactive_attr */ + A_NORMAL, /* inputbox_attr */ + A_NORMAL, /* inputbox_border_attr */ + A_NORMAL, /* searchbox_attr */ + A_BOLD, /* searchbox_title_attr */ + A_NORMAL, /* searchbox_border_attr */ + A_BOLD, /* position_indicator_attr */ + A_NORMAL, /* menubox_attr */ + A_NORMAL, /* menubox_border_attr */ + A_NORMAL, /* item_attr */ + A_REVERSE, /* item_selected_attr */ + A_BOLD, /* tag_attr */ + A_REVERSE, /* tag_selected_attr */ + A_BOLD, /* tag_key_attr */ + A_REVERSE, /* tag_key_selected_attr */ + A_BOLD, /* check_attr */ + A_REVERSE, /* check_selected_attr */ + A_BOLD, /* uarrow_attr */ + A_BOLD /* darrow_attr */ +}; + + +#include "colors.h" + +/* + * Table of color values + */ +int color_table[][3] = +{ + {SCREEN_FG, SCREEN_BG, SCREEN_HL}, + {SHADOW_FG, SHADOW_BG, SHADOW_HL}, + {DIALOG_FG, DIALOG_BG, DIALOG_HL}, + {TITLE_FG, TITLE_BG, TITLE_HL}, + {BORDER_FG, BORDER_BG, BORDER_HL}, + {BUTTON_ACTIVE_FG, BUTTON_ACTIVE_BG, BUTTON_ACTIVE_HL}, + {BUTTON_INACTIVE_FG, BUTTON_INACTIVE_BG, BUTTON_INACTIVE_HL}, + {BUTTON_KEY_ACTIVE_FG, BUTTON_KEY_ACTIVE_BG, BUTTON_KEY_ACTIVE_HL}, + {BUTTON_KEY_INACTIVE_FG, BUTTON_KEY_INACTIVE_BG, BUTTON_KEY_INACTIVE_HL}, + {BUTTON_LABEL_ACTIVE_FG, BUTTON_LABEL_ACTIVE_BG, BUTTON_LABEL_ACTIVE_HL}, + {BUTTON_LABEL_INACTIVE_FG, BUTTON_LABEL_INACTIVE_BG, + BUTTON_LABEL_INACTIVE_HL}, + {INPUTBOX_FG, INPUTBOX_BG, INPUTBOX_HL}, + {INPUTBOX_BORDER_FG, INPUTBOX_BORDER_BG, INPUTBOX_BORDER_HL}, + {SEARCHBOX_FG, SEARCHBOX_BG, SEARCHBOX_HL}, + {SEARCHBOX_TITLE_FG, SEARCHBOX_TITLE_BG, SEARCHBOX_TITLE_HL}, + {SEARCHBOX_BORDER_FG, SEARCHBOX_BORDER_BG, SEARCHBOX_BORDER_HL}, + {POSITION_INDICATOR_FG, POSITION_INDICATOR_BG, POSITION_INDICATOR_HL}, + {MENUBOX_FG, MENUBOX_BG, MENUBOX_HL}, + {MENUBOX_BORDER_FG, MENUBOX_BORDER_BG, MENUBOX_BORDER_HL}, + {ITEM_FG, ITEM_BG, ITEM_HL}, + {ITEM_SELECTED_FG, ITEM_SELECTED_BG, ITEM_SELECTED_HL}, + {TAG_FG, TAG_BG, TAG_HL}, + {TAG_SELECTED_FG, TAG_SELECTED_BG, TAG_SELECTED_HL}, + {TAG_KEY_FG, TAG_KEY_BG, TAG_KEY_HL}, + {TAG_KEY_SELECTED_FG, TAG_KEY_SELECTED_BG, TAG_KEY_SELECTED_HL}, + {CHECK_FG, CHECK_BG, CHECK_HL}, + {CHECK_SELECTED_FG, CHECK_SELECTED_BG, CHECK_SELECTED_HL}, + {UARROW_FG, UARROW_BG, UARROW_HL}, + {DARROW_FG, DARROW_BG, DARROW_HL}, +}; /* color_table */ + +/* + * Set window to attribute 'attr' + */ +void +attr_clear (WINDOW * win, int height, int width, chtype attr) +{ + int i, j; + + wattrset (win, attr); + for (i = 0; i < height; i++) { + wmove (win, i, 0); + for (j = 0; j < width; j++) + waddch (win, ' '); + } + touchwin (win); +} + +void dialog_clear (void) +{ + attr_clear (stdscr, LINES, COLS, screen_attr); + /* Display background title if it exists ... - SLH */ + if (backtitle != NULL) { + int i; + + wattrset (stdscr, screen_attr); + mvwaddstr (stdscr, 0, 1, (char *)backtitle); + wmove (stdscr, 1, 1); + for (i = 1; i < COLS - 1; i++) + waddch (stdscr, ACS_HLINE); + } + wnoutrefresh (stdscr); +} + +/* + * Do some initialization for dialog + */ +void +init_dialog (void) +{ + initscr (); /* Init curses */ + keypad (stdscr, TRUE); + cbreak (); + noecho (); + + + if (use_colors) /* Set up colors */ + color_setup (); + + + dialog_clear (); +} + +/* + * Setup for color display + */ +void +color_setup (void) +{ + int i; + + if (has_colors ()) { /* Terminal supports color? */ + start_color (); + + /* Initialize color pairs */ + for (i = 0; i < ATTRIBUTE_COUNT; i++) + init_pair (i + 1, color_table[i][0], color_table[i][1]); + + /* Setup color attributes */ + for (i = 0; i < ATTRIBUTE_COUNT; i++) + attributes[i] = C_ATTR (color_table[i][2], i + 1); + } +} + +/* + * End using dialog functions. + */ +void +end_dialog (void) +{ + endwin (); +} + + +/* + * Print a string of text in a window, automatically wrap around to the + * next line if the string is too long to fit on one line. Newline + * characters '\n' are replaced by spaces. We start on a new line + * if there is no room for at least 4 nonblanks following a double-space. + */ +void +print_autowrap (WINDOW * win, const char *prompt, int width, int y, int x) +{ + int newl, cur_x, cur_y; + int i, prompt_len, room, wlen; + char tempstr[MAX_LEN + 1], *word, *sp, *sp2; + + strcpy (tempstr, prompt); + + prompt_len = strlen(tempstr); + + /* + * Remove newlines + */ + for(i=0; i<prompt_len; i++) { + if(tempstr[i] == '\n') tempstr[i] = ' '; + } + + if (prompt_len <= width - x * 2) { /* If prompt is short */ + wmove (win, y, (width - prompt_len) / 2); + waddstr (win, tempstr); + } else { + cur_x = x; + cur_y = y; + newl = 1; + word = tempstr; + while (word && *word) { + sp = index(word, ' '); + if (sp) + *sp++ = 0; + + /* Wrap to next line if either the word does not fit, + or it is the first word of a new sentence, and it is + short, and the next word does not fit. */ + room = width - cur_x; + wlen = strlen(word); + if (wlen > room || + (newl && wlen < 4 && sp && wlen+1+strlen(sp) > room + && (!(sp2 = index(sp, ' ')) || wlen+1+(sp2-sp) > room))) { + cur_y++; + cur_x = x; + } + wmove (win, cur_y, cur_x); + waddstr (win, word); + getyx (win, cur_y, cur_x); + cur_x++; + if (sp && *sp == ' ') { + cur_x++; /* double space */ + while (*++sp == ' '); + newl = 1; + } else + newl = 0; + word = sp; + } + } +} + +/* + * Print a button + */ +void +print_button (WINDOW * win, const char *label, int y, int x, int selected) +{ + int i, temp; + + wmove (win, y, x); + wattrset (win, selected ? button_active_attr : button_inactive_attr); + waddstr (win, "<"); + temp = strspn (label, " "); + label += temp; + wattrset (win, selected ? button_label_active_attr + : button_label_inactive_attr); + for (i = 0; i < temp; i++) + waddch (win, ' '); + wattrset (win, selected ? button_key_active_attr + : button_key_inactive_attr); + waddch (win, label[0]); + wattrset (win, selected ? button_label_active_attr + : button_label_inactive_attr); + waddstr (win, (char *)label + 1); + wattrset (win, selected ? button_active_attr : button_inactive_attr); + waddstr (win, ">"); + wmove (win, y, x + temp + 1); +} + +/* + * Draw a rectangular box with line drawing characters + */ +void +draw_box (WINDOW * win, int y, int x, int height, int width, + chtype box, chtype border) +{ + int i, j; + + wattrset (win, 0); + for (i = 0; i < height; i++) { + wmove (win, y + i, x); + for (j = 0; j < width; j++) + if (!i && !j) + waddch (win, border | ACS_ULCORNER); + else if (i == height - 1 && !j) + waddch (win, border | ACS_LLCORNER); + else if (!i && j == width - 1) + waddch (win, box | ACS_URCORNER); + else if (i == height - 1 && j == width - 1) + waddch (win, box | ACS_LRCORNER); + else if (!i) + waddch (win, border | ACS_HLINE); + else if (i == height - 1) + waddch (win, box | ACS_HLINE); + else if (!j) + waddch (win, border | ACS_VLINE); + else if (j == width - 1) + waddch (win, box | ACS_VLINE); + else + waddch (win, box | ' '); + } +} + +/* + * Draw shadows along the right and bottom edge to give a more 3D look + * to the boxes + */ +void +draw_shadow (WINDOW * win, int y, int x, int height, int width) +{ + int i; + + if (has_colors ()) { /* Whether terminal supports color? */ + wattrset (win, shadow_attr); + wmove (win, y + height, x + 2); + for (i = 0; i < width; i++) + waddch (win, winch (win) & A_CHARTEXT); + for (i = y + 1; i < y + height + 1; i++) { + wmove (win, i, x + width); + waddch (win, winch (win) & A_CHARTEXT); + waddch (win, winch (win) & A_CHARTEXT); + } + wnoutrefresh (win); + } +} + +/* + * Return the position of the first alphabetic character in a string. + */ +int +first_alpha(const char *string, const char *exempt) +{ + int i, in_paren=0, c; + + for (i = 0; i < strlen(string); i++) { + c = tolower(string[i]); + + if (strchr("<[(", c)) ++in_paren; + if (strchr(">])", c)) --in_paren; + + if ((! in_paren) && isalpha(c) && + strchr(exempt, c) == 0) + return i; + } + + return 0; +} diff --git a/scripts/lxdialog/yesno.c b/scripts/lxdialog/yesno.c new file mode 100644 index 00000000..6f40af64 --- /dev/null +++ b/scripts/lxdialog/yesno.c @@ -0,0 +1,110 @@ +/* + * yesno.c -- implements the yes/no box + * + * ORIGINAL AUTHOR: Savio Lam (lam836@cs.cuhk.hk) + * MODIFIED FOR LINUX KERNEL CONFIG BY: William Roadcap (roadcap@cfw.com) + * + * 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. + */ + +#include "dialog.h" + +/* + * Display termination buttons + */ +static void +print_buttons(WINDOW *dialog, int height, int width, int selected) +{ + int x = width / 2 - 10; + int y = height - 2; + + print_button (dialog, " Yes ", y, x, selected == 0); + print_button (dialog, " No ", y, x + 13, selected == 1); + + wmove(dialog, y, x+1 + 13*selected ); + wrefresh (dialog); +} + +/* + * Display a dialog box with two buttons - Yes and No + */ +int +dialog_yesno (const char *title, const char *prompt, int height, int width) +{ + int i, x, y, key = 0, button = 0; + WINDOW *dialog; + + /* center dialog box on screen */ + x = (COLS - width) / 2; + y = (LINES - height) / 2; + + draw_shadow (stdscr, y, x, height, width); + + dialog = newwin (height, width, y, x); + keypad (dialog, TRUE); + + draw_box (dialog, 0, 0, height, width, dialog_attr, border_attr); + wattrset (dialog, border_attr); + mvwaddch (dialog, height-3, 0, ACS_LTEE); + for (i = 0; i < width - 2; i++) + waddch (dialog, ACS_HLINE); + wattrset (dialog, dialog_attr); + waddch (dialog, ACS_RTEE); + + if (title != NULL) { + wattrset (dialog, title_attr); + mvwaddch (dialog, 0, (width - strlen(title))/2 - 1, ' '); + waddstr (dialog, (char *)title); + waddch (dialog, ' '); + } + + wattrset (dialog, dialog_attr); + print_autowrap (dialog, prompt, width - 2, 1, 3); + + print_buttons(dialog, height, width, 0); + + while (key != ESC) { + key = wgetch (dialog); + switch (key) { + case 'Y': + case 'y': + delwin (dialog); + return 0; + case 'N': + case 'n': + delwin (dialog); + return 1; + + case TAB: + case KEY_LEFT: + case KEY_RIGHT: + button = ((key == KEY_LEFT ? --button : ++button) < 0) + ? 1 : (button > 1 ? 0 : button); + + print_buttons(dialog, height, width, button); + wrefresh (dialog); + break; + case ' ': + case '\n': + delwin (dialog); + return button; + case ESC: + break; + } + } + + delwin (dialog); + return -1; /* ESC pressed */ +} diff --git a/teles/Makefile.in b/teles/Makefile.in index 30bc4701..f81c6e3d 100644 --- a/teles/Makefile.in +++ b/teles/Makefile.in @@ -1,4 +1,4 @@ -# $Id: Makefile.in,v 1.1 1997/02/17 00:09:36 fritz Exp $ +# $Id: Makefile.in,v 1.2 1997/03/02 19:42:53 fritz Exp $ # # Makefile for telesctrl # (C) 1997 Fritz Elfert @@ -7,45 +7,76 @@ SHELL = /bin/sh CFLAGS = -Wall -O2 -I. LDFLAGS = -L../lib @LIBS@ -PROGRAM = telesctrl +PROGRAMS = MODULES = telesctrl.o -MANPAGE = telesctrl.8 +MANPAGES = INSTALL = @INSTALL@ INSTALL_PROGRAM = $(INSTALL) -o 0 -g 0 -m 0750 INSTALL_MAN = $(INSTALL) -o 0 -g 0 -m 0644 prefix = @prefix@ exec_prefix = @exec_prefix@ -SBINDIR = /sbin -mandir = @mandir@ +ifeq (../.config,$(wildcard ../.config)) + include ../.config + SBINDIR = $(CONFIG_SBINDIR) + mandir = $(CONFIG_MANDIR) + ifeq ($(CONFIG_TELESCTRL),y) + PROGRAMS += telesctrl + MANPAGES += telesctrl.8 + endif + ifeq ($(CONFIG_HISAXCTRL),y) + PROGRAMS += hisaxctrl + MANPAGES += hisaxctrl.8 + endif +else + MANPAGES = telesctrl.8 + SBINDIR = /sbin + mandir = @mandir@ +endif MAN8DIR = $(mandir)/man8 CC = @CC@ -.SUFFIXES: -.SUFFIXES: .c .o +#.SUFFIXES: +#.SUFFIXES: .c .o -all: $(PROGRAM) +%.8: %.man + cp $< $@ + +all: $(PROGRAMS) $(MANPAGES) config: @./configure -$(PROGRAM): $(MODULES) +telesctrl: $(MODULES) $(CC) $(CFLAGS) $? $(LDFLAGS) -o $@ -install-man: $(PROGRAM).man +hisaxctrl: $(MODULES) + $(CC) $(CFLAGS) $? $(LDFLAGS) -o $@ + +hisaxctrl.8: telesctrl.8 + cp $< $@ + +install: $(PROGRAMS) $(MANPAGES) + mkdir -p $(SBINDIR) + $(INSTALL_PROGRAM) $(PROGRAMS) $(SBINDIR) mkdir -p $(MAN8DIR) - $(INSTALL_MAN) $< $(MAN8DIR)/$(MANPAGE) + $(INSTALL_MAN) $(MANPAGES) $(MAN8DIR) -install: $(PROGRAM) install-man - $(INSTALL_PROGRAM) $(PROGRAM) $(SBINDIR)/$(PROGRAM) - -install-strip: $(PROGRAM) - $(INSTALL_PROGRAM) -s $(PROGRAM) $(SBINDIR)/$(PROGRAM) +install-strip: $(PROGRAMS) $(MANPAGES) + mkdir -p $(SBINDIR) + $(INSTALL_PROGRAM) -s $(PROGRAMS) $(SBINDIR) + mkdir -p $(MAN8DIR) + $(INSTALL_MAN) $(MANPAGES) $(MAN8DIR) uninstall: - rm -f $(SBINDIR)/$(PROGRAM) $(MAN8DIR)/$(MANPAGE) + @for i in $(PROGRAMS) ; do \ + rm -f $(SBINDIR)/$$i ; \ + done + @for i in $(MANPAGES) ; do \ + rm -f $(MAN8DIR)/$$i ; \ + done clean: - rm -f *.o *~ $(PROGRAM) + rm -f *.o *~ $(PROGRAMS) $(MANPAGES) distclean: clean rm -f config.status config.cache config.log Makefile diff --git a/vbox/Config.in b/vbox/Config.in new file mode 100644 index 00000000..b8eacfdd --- /dev/null +++ b/vbox/Config.in @@ -0,0 +1,8 @@ +mainmenu_option next_comment +comment 'Options for vbox package' +string 'Voice message spool directory' VBOX_SPOOLDIR '/var/spool/vbox' +string 'Log directory' VBOX_LOGDIR '/var/log/vbox' +string 'PID directory' VBOX_PIDDIR '/var/run' +string 'Lock directory' VBOX_LOCKDIR '/var/lock' +string 'Version of Tcl library to use' VBOX_TCL 'tcl8.0' +endmenu diff --git a/vbox/Makefile.in b/vbox/Makefile.in index ade3ad6f..182c6d9a 100644 --- a/vbox/Makefile.in +++ b/vbox/Makefile.in @@ -1,5 +1,5 @@ # -# $Id: Makefile.in,v 1.5 1997/02/27 15:43:39 michael Exp $ +# $Id: Makefile.in,v 1.6 1997/03/02 19:42:58 fritz Exp $ #----------------------------------------------------------------------------# # Things you can change to personalize the Makefile for your own site. # @@ -156,6 +156,12 @@ GOT_LIB_NCURSES = @VBOX_LIB_NCURSES@ all: vbox sedconvert +# +# For isdn4k-utils package compatibility +# +config: + @./configure + #----------------------------------------------------------------------------# # vbox # #----------------------------------------------------------------------------# diff --git a/xisdnload/Imakefile b/xisdnload/Imakefile new file mode 100644 index 00000000..327e1299 --- /dev/null +++ b/xisdnload/Imakefile @@ -0,0 +1,33 @@ +XCOMM $XConsortium: Imakefile,v 1.28 93/07/29 14:01:59 rws Exp $ + DEPLIBS = XawClientDepLibs +LOCAL_LIBRARIES = XawClientLibs +#if defined(SunArchitecture) && defined(i386Architecture) + SYS_LIBRARIES = -lkvm +#endif +#if SystemV4 +#ifdef SonyArchitecture + SYS_LIBRARIES = -lmld +#else + SYS_LIBRARIES = -lelf +#endif +#endif +#ifdef SGIArchitecture + SYS_LIBRARIES = -lmld +#endif +#ifdef BSD386Architecture + SYS_LIBRARIES = -lutil -lkvm +#endif + SRCS = xisdnload.c + OBJS = xisdnload.o + OSMAJORVERSION = OSMajorVersion + OSMINORVERSION = OSMinorVersion + DEFINES = -DOSMAJORVERSION=$(OSMAJORVERSION) -DOSMINORVERSION=$(OSMINORVERSION) + +AllTarget(xisdnload) +NormalProgramTarget(xisdnload,$(OBJS),$(DEPLIBS),$(LOCAL_LIBRARIES),NullParameter) + +InstallProgram(xisdnload,$(BINDIR)) +InstallAppDefaults(XISDNLoad) +InstallManPage(xisdnload,$(MANDIR)) + +DependTarget() diff --git a/xisdnload/Makefile.in b/xisdnload/Makefile.in new file mode 100644 index 00000000..7b771569 --- /dev/null +++ b/xisdnload/Makefile.in @@ -0,0 +1,39 @@ +# +# This Makefile is used for compatibility to the +# isdn4k-utils package. In order to superseede +# the original Makefile, it is called GNUmakefile. +# + +ifeq (../.config,$(wildcard ../.config)) + include ../.config + MAN1DIROPT = MANDIR=$(CONFIG_MANDIR)/man1 + MAN3DIROPT = LIBMANDIR=$(CONFIG_MANDIR)/man3 + MAN5DIROPT = FILEMANDIR=$(CONFIG_MANDIR)/man5 + MANDIROPTS = $(MAN1DIROPT) $(MAN3DIROPT) $(MAN5DIROPT) + BINDIROPT = BINDIR=$(CONFIG_BINDIR) +endif + +all: xisdnload + +xisdnload: + $(MAKE) -f Makefile + +config: + @cp Makefile.in GNUmakefile + @xmkmf + +clean: + $(MAKE) -f Makefile clean + +distclean: clean + rm -f Makefile Makefile.bak GNUmakefile + +install-man: xisdnload.man + $(MAKE) -f Makefile $(MANDIROPTS) install.man + +install: xisdnload install-man + $(MAKE) -f Makefile $(BINDIROPT) install + +uninstall: + rm -f $(CONFIG_BINDIR)/xisdnload + find $(CONFIG_MANDIR)/xisdnload -name "xisdnload.*" -exec rm -f {} \; diff --git a/xisdnload/XISDNLoad.ad b/xisdnload/XISDNLoad.ad new file mode 100644 index 00000000..7761881e --- /dev/null +++ b/xisdnload/XISDNLoad.ad @@ -0,0 +1,10 @@ +XISDNLoad.geometry: 250x100 +*Label*Justify: left +*Label*Label: %7s %3d:%02d %4.0fcps %ldkB +! *minScale: 8 +*minScale: 1 +*JumpScroll: 1 +*update: 1 +*internalBorderWidth: 0 +*showGrip: FALSE +*onlineColor: red diff --git a/xisdnload/xisdnload.bit b/xisdnload/xisdnload.bit new file mode 100644 index 00000000..6a274b2c --- /dev/null +++ b/xisdnload/xisdnload.bit @@ -0,0 +1,14 @@ +#define xisdnload_width 32 +#define xisdnload_height 32 +static unsigned char xisdnload_bits[] = { + 0x00, 0x00, 0xc0, 0x07, 0x1e, 0x00, 0xf0, 0x07, 0x00, 0x00, 0xf8, 0x07, + 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xfc, 0x07, 0x00, 0x00, 0xfe, 0x07, + 0xff, 0xff, 0xff, 0xff, 0x00, 0x80, 0xff, 0x07, 0x00, 0xc0, 0xff, 0x07, + 0xff, 0xff, 0xff, 0xff, 0x00, 0xe0, 0xff, 0x07, 0x00, 0xf0, 0xff, 0x07, + 0xff, 0xff, 0xff, 0xff, 0x00, 0xf8, 0xff, 0x07, 0x00, 0xf8, 0xff, 0x07, + 0xff, 0xff, 0xff, 0xff, 0x00, 0xfc, 0xff, 0x07, 0x00, 0xfc, 0xff, 0x07, + 0xff, 0xff, 0xff, 0xff, 0x00, 0xfe, 0xff, 0x07, 0x00, 0xfe, 0xff, 0x07, + 0xff, 0x1b, 0xb1, 0xfd, 0x00, 0xeb, 0x2d, 0x05, 0x00, 0xeb, 0x2d, 0x04, + 0xff, 0x9b, 0xad, 0xfc, 0x80, 0x7b, 0xad, 0x05, 0xc0, 0x7b, 0xad, 0x05, + 0xff, 0x8b, 0xb1, 0xfd, 0xf8, 0xff, 0xff, 0x07, 0xff, 0xff, 0xff, 0x07, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x07, }; diff --git a/xisdnload/xisdnload.c b/xisdnload/xisdnload.c new file mode 100644 index 00000000..d7a3d124 --- /dev/null +++ b/xisdnload/xisdnload.c @@ -0,0 +1,406 @@ +/* based on: $XConsortium: xload.c,v 1.37 94/04/17 20:43:44 converse Exp $ */ +/* + +Copyright (c) 1989 X Consortium + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of the X Consortium shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from the X Consortium. + +*/ + +/* + * xisdnload - display ISDN load average in a window + * + */ + +#include <stdio.h> +#include <sys/fcntl.h> +#include <sys/time.h> +#include <sys/types.h> +#include <linux/isdn.h> + +#include <X11/Intrinsic.h> +#include <X11/Xatom.h> +#include <X11/StringDefs.h> +#include <X11/Shell.h> + +#include <X11/Xaw/Cardinals.h> +#include <X11/Xaw/Label.h> +#include <X11/Xaw/Paned.h> +#include <X11/Xaw/StripChart.h> +#include <X11/Xmu/SysUtil.h> + +#include "xisdnload.bit" + +char *ProgramName; + +static void quit(); + +/* + * Definition of the Application resources structure. + */ + +typedef struct _XISDNLoadResources { + Boolean show_label; + char *online_color; +} XISDNLoadResources; + +/* + * Command line options table. Only resources are entered here...there is a + * pass over the remaining options after XtParseCommand is let loose. + */ + +static XrmOptionDescRec options[] = { + {"-scale", "*load.minScale", XrmoptionSepArg, NULL}, + {"-update", "*load.update", XrmoptionSepArg, NULL}, + {"-hl", "*load.highlight", XrmoptionSepArg, NULL}, + {"-highlight", "*load.highlight", XrmoptionSepArg, NULL}, + {"-label", "*label.label", XrmoptionSepArg, NULL}, + {"-nolabel", "*showLabel", XrmoptionNoArg, "False"}, + {"-jumpscroll", "*load.jumpScroll", XrmoptionSepArg, NULL}, + {"-online", "*onlineColor", XrmoptionSepArg, NULL}, +}; + +/* + * The structure containing the resource information for the + * Xisdnload application resources. + */ + +#define Offset(field) (XtOffsetOf(XISDNLoadResources, field)) + +static XtResource my_resources[] = { + {"showLabel", XtCBoolean, XtRBoolean, sizeof(Boolean), + Offset(show_label), XtRImmediate, (XtPointer) TRUE}, + {"onlineColor", "OnlineColor", XtRString, sizeof(char *), + Offset(online_color), XtRString, NULL}, +}; + +#undef Offset + +static XISDNLoadResources resources; + +static XtActionsRec xisdnload_actions[] = { + { "quit", quit }, +}; +static Atom wm_delete_window; + +typedef struct { + unsigned long ibytes; + unsigned long obytes; +} Siobytes; + +static Siobytes iobytes[ISDN_MAX_CHANNELS]; +static Pixel onlinecolor, bgcolor; +static long last[ISDN_MAX_CHANNELS]; +static int usageflags[ISDN_MAX_CHANNELS]; +static char phone[ISDN_MAX_CHANNELS][20]; +static int fd; +static Widget label_wid; +static char label_format[80]; +static int online_now, online_last; +static struct timeval tv_start, tv_last; +static long bytes_last, bytes_total, bytes_now; +static int secs_running; +static char num[20]; + +/* + * Exit with message describing command line format. + */ + +void usage() +{ + fprintf (stderr, "usage: %s [-options ...]\n\n", ProgramName); + fprintf (stderr, "where options include:\n"); + fprintf (stderr, + " -display dpy X server on which to display\n"); + fprintf (stderr, + " -geometry geom size and location of window\n"); + fprintf (stderr, + " -fn font font to use in label\n"); + fprintf (stderr, + " -scale number minimum number of scale lines\n"); + fprintf (stderr, + " -update seconds interval between updates\n"); + fprintf (stderr, + " -label string annotation text\n"); + fprintf (stderr, + " -bg color background color\n"); + fprintf (stderr, + " -fg color graph color\n"); + fprintf (stderr, + " -hl color scale and text color\n"); + fprintf (stderr, + " -online color background color when online\n"); + fprintf (stderr, + " -nolabel removes the label from above the chart.\n"); + fprintf (stderr, + " -jumpscroll value number of pixels to scroll on overflow\n"); + fprintf (stderr, "\n"); + exit(1); +} + + + +void +InitLoadPoint() +{ + int i; + + fd = open("/dev/isdninfo", O_RDONLY | O_NDELAY); + if (fd < 0) { + perror("/dev/isdninfo"); + exit(1); + } + + for (i=0; i < ISDN_MAX_CHANNELS; i++) { + iobytes[i].ibytes = 0; + iobytes[i].obytes = 0; + strcpy(phone[i], "???"); + last[i] = 0; + usageflags[i] = 0; + } + online_last = -1; + online_now = -1; + gettimeofday(&tv_last, NULL); + tv_last.tv_sec--; /* avoid devision by zero */ + tv_start = tv_last; + bytes_last = 0; + bytes_total = 0; + bytes_now = 0; + secs_running = 0; + strcpy(num, "???"); +} + + + +void +GetLoadPoint( w, closure, call_data ) +Widget w; +XtPointer closure; +XtPointer call_data; /* pointer to (double) return value */ +{ + double *loadavg = (double *)call_data; + double cps = 0.0; + int idx; + int get_iobytes; + char buf[4096]; + char s[120]; + struct timeval tv_now, tv; + long bytes_delta; + fd_set fds; + int secs_delta; + Arg args[1]; + int res; + + gettimeofday(&tv_now, NULL); + secs_delta = (tv_now.tv_sec + tv_now.tv_usec / 1000000) - + (tv_last.tv_sec + tv_last.tv_usec / 1000000); + tv_last = tv_now; + + if (read(fd, buf, sizeof(buf))> 0) { + sscanf(strstr(buf, "usage:"), + "usage: %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d", + &usageflags[0], &usageflags[1], &usageflags[2], &usageflags[3], + &usageflags[4], &usageflags[5], &usageflags[6], &usageflags[7], + &usageflags[8], &usageflags[9], &usageflags[10], &usageflags[11], + &usageflags[12], &usageflags[13], &usageflags[14], &usageflags[15]); + sscanf(strstr(buf, "phone:"), + "phone: %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s %s", + phone[0], phone[1], phone[2], phone[3], + phone[4], phone[5], phone[6], phone[7], + phone[8], phone[8], phone[10], phone[11], + phone[12], phone[13], phone[14], phone[15]); + + } + get_iobytes = 1; + for (online_now = 0, bytes_now = 0, idx = 0; idx < 16; idx++) { + if (usageflags[idx]) { + online_now = 1; + if (get_iobytes) { + if (ioctl(fd,IIOCGETCPS,&iobytes)) + perror("IIOCGETCPS"); + get_iobytes = 0; + } + bytes_now += iobytes[idx].ibytes + iobytes[idx].obytes; + strcpy(num, phone[idx]); + } + } + + bytes_delta = bytes_now - bytes_last; + bytes_last = bytes_now; + + if (online_now >= 1) { + secs_running = (tv_now.tv_sec + tv_now.tv_usec / 1000000) - + (tv_start.tv_sec + tv_start.tv_usec / 1000000); + cps = (double)bytes_delta / (double)secs_delta; + if (cps < 0.0) cps = 0.0; + if (cps > 8000.0) cps = 8000.0; + bytes_total = bytes_now; + if (online_last != 1) { + tv_start = tv_now; + online_last = 1; + XtSetArg(args[0], XtNbackground, onlinecolor); + XtSetValues(w, args, 1); + } + if (resources.show_label) { + sprintf(s, label_format, num, + secs_running / 60, secs_running % 60, cps, bytes_total / 1024); + XtSetArg (args[0], XtNlabel, s); + XtSetValues (label_wid, args, ONE); + } + } else { + if (online_last != 0) { + online_last = 0; + XtSetArg(args[0], XtNbackground, bgcolor); + XtSetValues(w, args, 1); + if (resources.show_label) { + if (secs_running > 0) { + sprintf(s, label_format, "offline", + secs_running / 60, secs_running % 60, + (double)bytes_total / (double)secs_running, + bytes_total / 1024); + } else { + sprintf(s, "uninitialized"); + } + XtSetArg (args[0], XtNlabel, s); + XtSetValues (label_wid, args, ONE); + } + } + } + + *loadavg = cps / 1000.0; /* unit: 1000Bytes/sec */ + +} + + + +void main(argc, argv) + int argc; + char **argv; +{ + XtAppContext app_con; + Widget toplevel, load, pane, load_parent; + Arg args[1]; + Pixmap icon_pixmap = None; + char *label, host[256]; + XrmValue namein, pixelout; + + + ProgramName = argv[0]; + + /* For security reasons, we reset our uid/gid after doing the necessary + system initialization and before calling any X routines. */ + InitLoadPoint(); + setgid(getgid()); /* reset gid first while still (maybe) root */ + setuid(getuid()); + + toplevel = XtAppInitialize(&app_con, "XISDNLoad", options, + XtNumber(options), + &argc, argv, NULL, NULL, (Cardinal) 0); + if (argc != 1) usage(); + + XtGetApplicationResources( toplevel, (XtPointer) &resources, + my_resources, XtNumber(my_resources), + NULL, (Cardinal) 0); + + /* + * This is a hack so that f.delete will do something useful in this + * single-window application. + */ + XtAppAddActions (app_con, xisdnload_actions, XtNumber(xisdnload_actions)); + XtOverrideTranslations(toplevel, + XtParseTranslationTable ("<Message>WM_PROTOCOLS: quit()")); + + XtSetArg (args[0], XtNiconPixmap, &icon_pixmap); + XtGetValues(toplevel, args, ONE); + if (icon_pixmap == None) { + XtSetArg(args[0], XtNiconPixmap, + XCreateBitmapFromData(XtDisplay(toplevel), + XtScreen(toplevel)->root, + (char *)xisdnload_bits, + xisdnload_width, xisdnload_height)); + XtSetValues (toplevel, args, ONE); + } + + if (resources.show_label) { + pane = XtCreateManagedWidget ("paned", panedWidgetClass, + toplevel, NULL, ZERO); + + label_wid = XtCreateManagedWidget ("label", labelWidgetClass, + pane, NULL, ZERO); + + XtSetArg (args[0], XtNlabel, &label); + XtGetValues(label_wid, args, ONE); + + strcpy(label_format, label); + + XtSetArg (args[0], XtNlabel, "uninitialized"); + XtSetValues (label_wid, args, ONE); + + load_parent = pane; + } + else + load_parent = toplevel; + + load = XtCreateManagedWidget ("load", stripChartWidgetClass, + load_parent, NULL, ZERO); + + XtSetArg (args[0], XtNbackground, &bgcolor); + XtGetValues(toplevel, args, ONE); + + if (resources.online_color) { + namein.addr = resources.online_color; + namein.size = strlen(resources.online_color) + 1; + XtConvert(load, XtRString, &namein, XtRPixel, &pixelout); + onlinecolor = *(Pixel*)(pixelout.addr); + } else { + onlinecolor = bgcolor; + } + + XtAddCallback(load, XtNgetValue, GetLoadPoint, NULL); + + XtRealizeWidget (toplevel); + + wm_delete_window = XInternAtom (XtDisplay(toplevel), "WM_DELETE_WINDOW", + False); + (void) XSetWMProtocols (XtDisplay(toplevel), XtWindow(toplevel), + &wm_delete_window, 1); + + XtAppMainLoop(app_con); +} + +static void quit (w, event, params, num_params) + Widget w; + XEvent *event; + String *params; + Cardinal *num_params; +{ + if (event->type == ClientMessage && + event->xclient.data.l[0] != wm_delete_window) { + XBell (XtDisplay(w), 0); + return; + } + XtDestroyApplicationContext(XtWidgetToApplicationContext(w)); + exit (0); +} diff --git a/xisdnload/xisdnload.man b/xisdnload/xisdnload.man new file mode 100644 index 00000000..7ab5bbf6 --- /dev/null +++ b/xisdnload/xisdnload.man @@ -0,0 +1,100 @@ +.\" based on: $XConsortium: xload.man,v 1.29 94/04/17 20:43:44 matt Exp $ +.TH XISDNLOAD 1 "Release 6" "X Version 11" +.SH NAME +xisdnload \- ISDN load average display for X +.SH SYNOPSIS +.ta 6n +\fBxisdnload\fP [-\fItoolkitoption\fP ...] [-scale \fIinteger\fP] [-update \fIseconds\fP] [-hl \fIcolor\fP] [-highlight \fIcolor\fP] [-online \fIcolor\fP] +.br + [-jumpscroll \fIpixels\fP] [-label \fIstring\fP] [-nolabel] +.SH DESCRIPTION +The +.I xisdnload +program displays a periodically updating histogram of the ISDN load average. +.SH OPTIONS +.PP +.I Xisdnload +accepts all of the standard X Toolkit command line options (see \fIX(1)\fP). +The order of the options in unimportant. \fIxisdnload also accepts the +following additional options: +.PP +.TP 8 +.B \-hl \fIcolor\fP or \-highlight \fIcolor\fP +This option specifies the color of the scale lines. +.TP 8 +.B \-online \fIcolor\fP +This option specifies the background color when one or more ISDN +channels are online. +.TP 8 +.B \-jumpscroll \fPnumber of pixels\fP +The number of pixels to shift the graph to the left when the graph +reaches the right edge of the window. The default value is 1/2 the width +of the current window. Smooth scrolling can be achieved by setting it to 1. +.TP 8 +.B \-label \fIstring\fP +The string to put into the label above the load average when beeing +online. It is interpreted as a standard format string and may contain +the dialed number (%s), the minutes (%d) and seconds (%d) being +online, the actual cps rate (%f) and the amount of kbytes transfered +(%d) in this sequence. +.TP 8 +.B \-nolabel +If this command line option is specified then no label will be +displayed above the load graph. +.TP 8 +.B \-scale \fIinteger\fP +This option specifies the minimum number of tick marks in the histogram, +where one division represents one load average point. If the load goes +above this number, \fIxisdnload\fP will create more divisions, but it will never +use fewer than this number. The default is 1. +.PP +.TP 8 +.B \-update \fIseconds\fP +This option specifies the interval in seconds at which \fIxisdnload\fP +updates its display. The minimum amount of time allowed between updates +is 1 second. The default is 10. +.SH RESOURCES +In addition to the resources available to each of the widgets used by +\fIxisdnload\fP there is one resource defined by the application itself. +.TP 8 +.B showLabel (\fPclass\fB Boolean) +If False then no label will be displayed. +.SH WIDGETS +In order to specify resources, it is useful to know the hierarchy of +the widgets which compose \fIxisdnload\fR. In the notation below, +indentation indicates hierarchical structure. The widget class name +is given first, followed by the widget instance name. +.sp +.nf +.ta .5i 1.0i 1.5i 2.0i +XISDNLoad xisdnload + Paned paned + Label label + StripChart load +.fi +.sp +.SH ENVIRONMENT +.PP +.TP 8 +.B DISPLAY +to get the default host and display number. +.TP 8 +.B XENVIRONMENT +to get the name of a resource file that overrides the global resources +stored in the RESOURCE_MANAGER property. +.SH FILES +<XRoot>/lib/X11/app-defaults/XISDNLoad - specifies required resources +.SH SEE ALSO +X(1), xrdb(1), xload(1), mem(4), Athena StripChart Widget. +.SH BUGS +Certainly a lot. +.SH COPYRIGHT +This program is based on \fIxload\fP +which is Copyright (1988) X Consortium. +See \fIX(1)\fP for a full statement of rights and permissions. +.SH AUTHORS +Besides the basic xload stuff, the ISDN parts are added by +.br +Frank Strauss (escape e.V., Braunschweig, Germany). +.br +strauss@escape.de diff --git a/xmonisdn/Imakefile b/xmonisdn/Imakefile new file mode 100644 index 00000000..7f91be84 --- /dev/null +++ b/xmonisdn/Imakefile @@ -0,0 +1,17 @@ +XCOMM $XConsortium: Imakefile,v 1.12 93/09/20 10:18:26 kaleb Exp $ + DEPLIBS = XawClientDepLibs +LOCAL_LIBRARIES = XawClientLibs + SYS_LIBRARIES = MathLibrary + + SRCS = xmonisdn.c Net.c + OBJS = xmonisdn.o Net.o + HEADERS = NetP.h Net.h + + INSTPGMFLAGS = -m 4755 -s + +ComplexProgramTarget(xmonisdn) + +install.bitmap: + $(INSTALL) $(INSTALLFLAGS) -m 644 netinactive netwaiting netactive netactiveout netstart netstop $(DESTDIR)$(INCROOT)/X11/bitmaps/ + +install.all: install install.man install.bitmap \ No newline at end of file diff --git a/xmonisdn/Makefile.in b/xmonisdn/Makefile.in new file mode 100644 index 00000000..5290387d --- /dev/null +++ b/xmonisdn/Makefile.in @@ -0,0 +1,61 @@ +# +# This Makefile is used for compatibility to the +# isdn4k-utils package. In order to superseede +# the original Makefile, it is called makefile. +# + +# +# Add security check: +# - executed commands must be owned by root +# and only writable by owner. +# +I4LU_DEFINES := -DPARANOIA_CHECK +ifeq (../.config,$(wildcard ../.config)) + include ../.config + ifneq ($(CONFIG_XMONISDN_UPCMD),"") + I4LU_DEFINES += -DNETUP_COMMAND=\\\"$(shell echo $(CONFIG_XMONISDN_UPCMD))\\\" + endif + ifneq ($(CONFIG_XMONISDN_DOWNCMD),"") + I4LU_DEFINES += -DNETDOWN_COMMAND=\\\"$(shell echo $(CONFIG_XMONISDN_DOWNCMD))\\\" + endif + MAN1DIROPT = MANDIR=$(CONFIG_MANDIR)/man1 + MAN3DIROPT = LIBMANDIR=$(CONFIG_MANDIR)/man3 + MAN5DIROPT = FILEMANDIR=$(CONFIG_MANDIR)/man5 + MANDIROPTS = $(MAN1DIROPT) $(MAN3DIROPT) $(MAN5DIROPT) + BINDIROPT = BINDIR=$(CONFIG_BINDIR) +endif + +all: xmonisdn + +# +# Bug in original Makefile: +# Bitmaps are expected to be already installed. +# We create a temporary X11 subdir and add -I. +# instead. +# +xmonisdn: + mkdir -p X11/bitmaps + cp netinactive netwaiting netactive \ + netactiveout netstart netstop X11/bitmaps + $(MAKE) -f Makefile EXTRA_DEFINES="$(I4LU_DEFINES) -I." + rm -rf X11 + +config: + @cp Makefile.in GNUmakefile + @xmkmf + +clean: + $(MAKE) -f Makefile clean + +distclean: clean + rm -f Makefile GNUmakefile Makefile.bak + +install-man: xmonisdn.man + $(MAKE) -f Makefile $(MANDIROPTS) install.man + +install: xmonisdn install-man + $(MAKE) -f Makefile $(BINDIROPT) install + +uninstall: + rm -f $(CONFIG_BINDIR)/xmonisdn + find $(CONFIG_MANDIR)/xmonisdn -name "xmonisdn.*" -exec rm -f {} \; diff --git a/xmonisdn/Net.c b/xmonisdn/Net.c new file mode 100644 index 00000000..62e94de1 --- /dev/null +++ b/xmonisdn/Net.c @@ -0,0 +1,743 @@ +#include <X11/IntrinsicP.h> /* for toolkit stuff */ +#include <X11/StringDefs.h> /* for useful atom names */ +#include <X11/cursorfont.h> /* for cursor constants */ +#include <X11/Xosdefs.h> /* for X_NOT_POSIX def */ +#include <pwd.h> /* for getting username */ +#include <sys/stat.h> /* for stat() ** needs types.h ***/ +#include <stdio.h> /* for printing error messages */ +#include <stdlib.h> +#include <sys/types.h> +#include <sys/time.h> +#include <linux/isdn.h> + +#ifndef X_NOT_POSIX +#ifdef _POSIX_SOURCE +# include <sys/wait.h> +#else +#define _POSIX_SOURCE +# include <sys/wait.h> +#undef _POSIX_SOURCE +#endif +# define waitCode(w) WEXITSTATUS(w) +# define waitSig(w) WIFSIGNALED(w) +typedef int waitType; +# define INTWAITTYPE +#else /* ! X_NOT_POSIX */ +#ifdef SYSV +# define waitCode(w) (((w) >> 8) & 0x7f) +# define waitSig(w) ((w) & 0xff) +typedef int waitType; +# define INTWAITTYPE +#else +# include <sys/wait.h> +# define waitCode(w) ((w).w_T.w_Retcode) +# define waitSig(w) ((w).w_T.w_Termsig) +typedef union wait waitType; +#endif /* SYSV else */ +#endif /* ! X_NOT_POSIX else */ + +#include <X11/bitmaps/netactive> +#include <X11/bitmaps/netinactive> +#include <X11/bitmaps/netwaiting> +#include <X11/bitmaps/netactiveout> +#include <X11/bitmaps/netstart> +#include <X11/bitmaps/netstop> + +#include <X11/Xaw/XawInit.h> +#include "NetP.h" +#include <X11/Xmu/Drawing.h> +#include <X11/extensions/shape.h> + +/* + * The default user interface is to have the netstat turn itself off whenever + * the user presses a button in it. Expert users might want to make this + * happen on EnterWindow. It might be nice to provide support for some sort of + * exit callback so that you can do things like press q to quit. + */ + +static char defaultTranslations[] = + "<ButtonPress>Button2: netup()\n\ + <ButtonPress>Button3: netdown()"; + +static void Check(), NetUp(), NetDown(); + +static XtActionsRec actionsList[] = { + { "check", Check }, + { "netup", NetUp }, + { "netdown",NetDown }, +}; + + +/* Initialization of defaults */ + +#define offset(field) XtOffsetOf(NetstatRec, netstat.field) +#define goffset(field) XtOffsetOf(WidgetRec, core.field) + +static Dimension defDim = 48; +static Pixmap nopix = None; + +static XtResource resources[] = { + { XtNwidth, XtCWidth, XtRDimension, sizeof (Dimension), + goffset (width), XtRDimension, (XtPointer)&defDim }, + { XtNheight, XtCHeight, XtRDimension, sizeof (Dimension), + goffset (height), XtRDimension, (XtPointer)&defDim }, + { XtNupdate, XtCInterval, XtRInt, sizeof (int), + offset (update), XtRString, "5" }, + { XtNforeground, XtCForeground, XtRPixel, sizeof (Pixel), + offset (foreground_pixel), XtRString, XtDefaultForeground }, + { XtNfile, XtCFile, XtRString, sizeof (String), + offset (filename), XtRString, NULL }, + { XtNvolume, XtCVolume, XtRInt, sizeof(int), + offset (volume), XtRString, "33"}, + { XtNactivePixmap, XtCPixmap, XtRBitmap, sizeof(Pixmap), + offset (active.bitmap), XtRString, "netactive" }, + { XtNactivePixmapMask, XtCPixmapMask, XtRBitmap, sizeof(Pixmap), + offset (active.mask), XtRBitmap, (XtPointer) &nopix }, + { XtNactiveoutPixmap, XtCPixmap, XtRBitmap, sizeof(Pixmap), + offset (activeout.bitmap), XtRString, "netactiveout" }, + { XtNactiveoutPixmapMask, XtCPixmapMask, XtRBitmap, sizeof(Pixmap), + offset (activeout.mask), XtRBitmap, (XtPointer) &nopix }, + { XtNwaitingPixmap, XtCPixmap, XtRBitmap, sizeof(Pixmap), + offset (waiting.bitmap), XtRString, "netwaiting" }, + { XtNwaitingPixmapMask, XtCPixmapMask, XtRBitmap, sizeof(Pixmap), + offset (waiting.mask), XtRBitmap, (XtPointer) &nopix }, + { XtNinactivePixmap, XtCPixmap, XtRBitmap, sizeof(Pixmap), + offset (inactive.bitmap), XtRString, "netinactive" }, + { XtNinactivePixmapMask, XtCPixmapMask, XtRBitmap, sizeof(Pixmap), + offset (inactive.mask), XtRBitmap, (XtPointer) &nopix }, + { XtNstartPixmap, XtCPixmap, XtRBitmap, sizeof(Pixmap), + offset (start.bitmap), XtRString, "netstart" }, + { XtNstartPixmapMask, XtCPixmapMask, XtRBitmap, sizeof(Pixmap), + offset (start.mask), XtRBitmap, (XtPointer) &nopix }, + { XtNstopPixmap, XtCPixmap, XtRBitmap, sizeof(Pixmap), + offset (stop.bitmap), XtRString, "netstop" }, + { XtNstopPixmapMask, XtCPixmapMask, XtRBitmap, sizeof(Pixmap), + offset (stop.mask), XtRBitmap, (XtPointer) &nopix }, + { XtNflip, XtCFlip, XtRBoolean, sizeof(Boolean), + offset (flipit), XtRString, "true" }, + { XtNshapeWindow, XtCShapeWindow, XtRBoolean, sizeof(Boolean), + offset (shapeit), XtRString, "false" }, +}; + +#undef offset +#undef goffset + +static void GetNetinfoFile(), CloseDown(); +static void check_netstat(), redraw_netstat(), beep(); +static void Initialize(), Realize(), Destroy(), Redisplay(); +static Boolean SetValues(); +static int parse_info(); + +NetstatClassRec netstatClassRec = { + { /* core fields */ + /* superclass */ (WidgetClass) &simpleClassRec, + /* class_name */ "Netstat", + /* widget_size */ sizeof(NetstatRec), + /* class_initialize */ XawInitializeWidgetSet, + /* class_part_initialize */ NULL, + /* class_inited */ FALSE, + /* initialize */ Initialize, + /* initialize_hook */ NULL, + /* realize */ Realize, + /* actions */ actionsList, + /* num_actions */ XtNumber(actionsList), + /* resources */ resources, + /* resource_count */ XtNumber(resources), + /* xrm_class */ NULLQUARK, + /* compress_motion */ TRUE, + /* compress_exposure */ TRUE, + /* compress_enterleave */ TRUE, + /* visible_interest */ FALSE, + /* destroy */ Destroy, + /* resize */ NULL, + /* expose */ Redisplay, + /* set_values */ SetValues, + /* set_values_hook */ NULL, + /* set_values_almost */ XtInheritSetValuesAlmost, + /* get_values_hook */ NULL, + /* accept_focus */ NULL, + /* version */ XtVersion, + /* callback_private */ NULL, + /* tm_table */ defaultTranslations, + /* query_geometry */ XtInheritQueryGeometry, + /* display_accelerator */ XtInheritDisplayAccelerator, + /* extension */ NULL + }, + { /* simple fields */ + /* change_sensitive */ XtInheritChangeSensitive + }, + { /* netstat fields */ + /* ignore */ 0 + } +}; + +WidgetClass netstatWidgetClass = (WidgetClass) &netstatClassRec; + +static FILE *isdninfo; +static int updownwait = 0; + +/* + * widget initialization + */ + +static GC get_netstat_gc (w) + NetstatWidget w; +{ + XtGCMask valuemask; + XGCValues xgcv; + + valuemask = GCForeground | GCBackground | GCFunction | GCGraphicsExposures; + xgcv.foreground = w->netstat.foreground_pixel; + xgcv.background = w->core.background_pixel; + xgcv.function = GXcopy; + xgcv.graphics_exposures = False; /* this is Bool, not Boolean */ + return (XtGetGC ((Widget) w, valuemask, &xgcv)); +} + + +/* ARGSUSED */ +static void Initialize (request, new, args, num_args) + Widget request, new; + ArgList args; + Cardinal *num_args; +{ + NetstatWidget w = (NetstatWidget) new; + int shape_event_base, shape_error_base; + + if (w->core.width <= 0) w->core.width = 1; + if (w->core.height <= 0) w->core.height = 1; + + if (w->netstat.shapeit && !XShapeQueryExtension (XtDisplay (w), + &shape_event_base, + &shape_error_base)) + w->netstat.shapeit = False; + w->netstat.shape_cache.mask = None; + w->netstat.gc = get_netstat_gc (w); + w->netstat.interval_id = (XtIntervalId) 0; + w->netstat.active.pixmap = None; + w->netstat.inactive.pixmap = None; + w->netstat.waiting.pixmap = None; + w->netstat.activeout.pixmap = None; + w->netstat.start.pixmap = None; + w->netstat.stop.pixmap = None; + w->netstat.state = 0; + if (!w->netstat.filename) GetNetinfoFile (w); + return; +} + + +/* + * action procedures + */ + +/* + * paranoia_check - enhanced security. + * + * refuse execution, if cmd is NOT owned by + * root or writeable by group or world. + * + */ + +/* ARGSUSED */ +static int paranoia_check(cmd) + char *cmd; +{ +#ifdef PARANOIA_CHECK + struct stat stbuf; + + if (stat(cmd, &stbuf)) + /* stat failed, stay on the safe side */ + return 0; + if (stbuf.st_uid != 0) + /* owner is not root */ + return 0; + if (stbuf.st_mode & (S_IWGRP | S_IWOTH)) + /* writable by group or world */ + return 0; +#endif + return 1; +} + +/* ARGSUSED */ +static void NetUp (gw, event, params, nparams) + Widget gw; + XEvent *event; + String *params; + Cardinal *nparams; +{ + NetstatWidget w = (NetstatWidget) gw; + + + if ((w->netstat.state <= 1) && (!updownwait)) { + w->netstat.state = 5; + updownwait = 150 / w->netstat.update; + if (updownwait < 2) updownwait = 2; + redraw_netstat(w); + if (paranoia_check(NETUP_COMMAND)) + system(NETUP_COMMAND); + } + return; +} + + + +/* ARGSUSED */ +static void NetDown (gw, event, params, nparams) + Widget gw; + XEvent *event; + String *params; + Cardinal *nparams; +{ + NetstatWidget w = (NetstatWidget) gw; + + if ((w->netstat.state > 1) && (w->netstat.state < 5) && (!updownwait)) { + w->netstat.state = 6; + redraw_netstat(w); + updownwait = 150 / w->netstat.update; + if (updownwait < 2) updownwait = 2; + if (paranoia_check(NETDOWN_COMMAND)) + system(NETDOWN_COMMAND); + } + return; +} + + + +/* ARGSUSED */ +static void Check (gw, event, params, nparams) + Widget gw; + XEvent *event; + String *params; + Cardinal *nparams; +{ + NetstatWidget w = (NetstatWidget) gw; + + if (!updownwait) { + w->netstat.state = 0; + fclose(isdninfo); + check_netstat (w); + } + + return; +} + + +/* ARGSUSED */ +static void clock_tic (client_data, id) + XtPointer client_data; + XtIntervalId *id; +{ + NetstatWidget w = (NetstatWidget) client_data; + + check_netstat (w); + + /* + * reset the timer + */ + + w->netstat.interval_id = + XtAppAddTimeOut (XtWidgetToApplicationContext((Widget) w), + w->netstat.update * 100, clock_tic, client_data); + + return; +} + +static Pixmap make_pixmap (dpy, w, bitmap, depth, flip, widthp, heightp) + Display *dpy; + NetstatWidget w; + Pixmap bitmap; + Boolean flip; + int depth; + int *widthp, *heightp; +{ + Window root; + int x, y; + unsigned int width, height, bw, dep; + unsigned long fore, back; + + if (!XGetGeometry (dpy, bitmap, &root, &x, &y, &width, &height, &bw, &dep)) + return None; + + *widthp = (int) width; + *heightp = (int) height; + if (flip) { + fore = w->core.background_pixel; + back = w->netstat.foreground_pixel; + } else { + fore = w->netstat.foreground_pixel; + back = w->core.background_pixel; + } + return XmuCreatePixmapFromBitmap (dpy, w->core.window, bitmap, + width, height, depth, fore, back); +} + +static void Realize (gw, valuemaskp, attr) + Widget gw; + XtValueMask *valuemaskp; + XSetWindowAttributes *attr; +{ + NetstatWidget w = (NetstatWidget) gw; + register Display *dpy = XtDisplay (w); + int depth = w->core.depth; + + *valuemaskp |= (CWBitGravity | CWCursor); + attr->bit_gravity = ForgetGravity; + attr->cursor = XCreateFontCursor (dpy, XC_top_left_arrow); + + (*netstatWidgetClass->core_class.superclass->core_class.realize) + (gw, valuemaskp, attr); + + /* + * build up the pixmaps that we'll put into the image + */ + if (w->netstat.active.bitmap == None) { + w->netstat.active.bitmap = + XCreateBitmapFromData (dpy, w->core.window, (char *) netactive_bits, + netactive_width, netactive_height); + } + if (w->netstat.inactive.bitmap == None) { + w->netstat.inactive.bitmap = + XCreateBitmapFromData (dpy, w->core.window, (char *) netinactive_bits, + netinactive_width, netinactive_height); + } + if (w->netstat.waiting.bitmap == None) { + w->netstat.waiting.bitmap = + XCreateBitmapFromData (dpy, w->core.window, (char *) netwaiting_bits, + netwaiting_width, netwaiting_height); + } + if (w->netstat.activeout.bitmap == None) { + w->netstat.activeout.bitmap = + XCreateBitmapFromData (dpy, w->core.window, (char *) netactiveout_bits, + netactiveout_width, netactiveout_height); + } + + if (w->netstat.start.bitmap == None) { + w->netstat.start.bitmap = + XCreateBitmapFromData (dpy, w->core.window, (char *) netstart_bits, + netstart_width, netstart_height); + } + + if (w->netstat.stop.bitmap == None) { + w->netstat.stop.bitmap = + XCreateBitmapFromData (dpy, w->core.window, (char *) netstop_bits, + netstop_width, netstop_height); + } + + w->netstat.inactive.pixmap = make_pixmap (dpy, w, w->netstat.inactive.bitmap, + depth, False, + &w->netstat.inactive.width, + &w->netstat.inactive.height); + w->netstat.active.pixmap = make_pixmap (dpy, w, w->netstat.active.bitmap, + depth, False, + &w->netstat.active.width, + &w->netstat.active.height); + + w->netstat.waiting.pixmap = make_pixmap (dpy, w, w->netstat.waiting.bitmap, + depth, False, + &w->netstat.waiting.width, + &w->netstat.waiting.height); + + w->netstat.activeout.pixmap = make_pixmap (dpy, w, w->netstat.activeout.bitmap, + depth, w->netstat.flipit, + &w->netstat.activeout.width, + &w->netstat.activeout.height); + + w->netstat.start.pixmap = make_pixmap (dpy, w, w->netstat.start.bitmap, + depth, False, + &w->netstat.start.width, + &w->netstat.start.height); + + w->netstat.stop.pixmap = make_pixmap (dpy, w, w->netstat.stop.bitmap, + depth, False, + &w->netstat.stop.width, + &w->netstat.stop.height); + + if (w->netstat.inactive.mask == None || w->netstat.active.mask == None || + w->netstat.waiting.mask == None || w->netstat.activeout.mask == None || + w->netstat.start.mask == None || w->netstat.stop.mask == None) + w->netstat.shapeit = False; + + w->netstat.interval_id = + XtAppAddTimeOut (XtWidgetToApplicationContext((Widget) w), + w->netstat.update * 100, clock_tic, (XtPointer) w); + + w->netstat.shape_cache.mask = None; + + check_netstat (w); + + return; +} + + +static void Destroy (gw) + Widget gw; +{ + NetstatWidget w = (NetstatWidget) gw; + Display *dpy = XtDisplay (gw); + + XtFree (w->netstat.filename); + if (w->netstat.interval_id) XtRemoveTimeOut (w->netstat.interval_id); + XtReleaseGC(gw, w->netstat.gc); +#define freepix(p) if (p) XFreePixmap (dpy, p) + freepix (w->netstat.active.bitmap); + freepix (w->netstat.active.mask); + freepix (w->netstat.active.pixmap); + freepix (w->netstat.inactive.bitmap); + freepix (w->netstat.inactive.mask); + freepix (w->netstat.inactive.pixmap); + freepix (w->netstat.waiting.bitmap); + freepix (w->netstat.waiting.mask); + freepix (w->netstat.waiting.pixmap); + freepix (w->netstat.activeout.bitmap); + freepix (w->netstat.activeout.mask); + freepix (w->netstat.activeout.pixmap); + freepix (w->netstat.start.bitmap); + freepix (w->netstat.start.mask); + freepix (w->netstat.start.pixmap); + freepix (w->netstat.stop.bitmap); + freepix (w->netstat.stop.mask); + freepix (w->netstat.stop.pixmap); + freepix (w->netstat.shape_cache.mask); +#undef freepix + return; +} + + +static void Redisplay (gw, event, region) + Widget gw; + XEvent *event; + Region region; +{ + NetstatWidget w = (NetstatWidget) gw; + + check_netstat (w); + redraw_netstat(w); +} + + +static void check_netstat (w) + NetstatWidget w; +{ + int newstate; + struct timeval timeout; + fd_set fdset; + + if (w->netstat.state >= 5) { /* network start or stop */ + if (updownwait <= 0) { + fclose(isdninfo); + w->netstat.state = 0; + updownwait = 0; + } else updownwait--; + } + + if (w->netstat.state == 0) { /* first invocation */ + if (!w->netstat.filename) GetNetinfoFile(); + if (!(isdninfo = fopen(w->netstat.filename, "r"))) { + fprintf(stderr, "xmonisdn: Can't open %s\n",w->netstat.filename); + CloseDown(w,-1); + } + } + FD_ZERO(&fdset); + FD_SET(fileno(isdninfo),&fdset); + timeout.tv_sec = 0; + timeout.tv_usec = 200; + switch (select(32,&fdset,(fd_set *)0,(fd_set *)0,&timeout)) { + case 0: /* nothing changed */ + if (w->netstat.state == 0) { + fprintf(stderr, "xmonisdn: No info from isdninfo-file after initial poll\n"); + CloseDown(w,-1); + } + return; + case 1: /* read new info */ + newstate = parse_info(); + break; + default: + fprintf(stderr,"xmonisdn: Error in select-statement\n"); + CloseDown(w,-1); + } + + if (newstate == w->netstat.state) return; + else { + if (((w->netstat.state == 4) || (newstate == 4)) && + (w->netstat.state < 5) && (newstate < 5)) beep(w); + w->netstat.state = newstate; + updownwait = 0; + } + + redraw_netstat(w); +} + +static int parse_info() +{ + char infoline[4096]; + char temp[128]; + char *infoptr; + register int i; + int num; + int newstate; + + newstate = 1; + fgets(infoline, 4095, isdninfo); /* idmap */ + fgets(infoline, 4095, isdninfo); /* chmap */ + infoptr = infoline + 7; + for (i=0; i<ISDN_MAX_CHANNELS; i++) { + sscanf(infoptr,"%d",&num); + if (num != -1) newstate = 2; + sscanf(infoptr,"%s",temp); + infoptr = infoptr + strlen(temp) + 1; + } + fgets(infoline, 4095, isdninfo); /* drmap */ + fgets(infoline, 4095, isdninfo); /* usage */ + if (newstate >= 2) { + infoptr = infoline + 7; + for (i=0; i<ISDN_MAX_CHANNELS; i++) { + sscanf(infoptr,"%d",&num); + if ((num&ISDN_USAGE_MASK) == ISDN_USAGE_NET) + if (num&ISDN_USAGE_OUTGOING) newstate = 4; + else if (newstate < 3) newstate = 3; + sscanf(infoptr,"%s",temp); + infoptr = infoptr + strlen(temp) + 1; + } + } + fgets(infoline, 4095, isdninfo); /* flags */ + fgets(infoline, 4095, isdninfo); /* phone */ + + return newstate; +} + +static void GetNetinfoFile (w) + NetstatWidget w; +{ + w->netstat.filename = (String) XtMalloc (strlen (NETINFO_FILE) + 1); + strcpy (w->netstat.filename, NETINFO_FILE); + return; +} + +static void CloseDown (w, status) + NetstatWidget w; + int status; +{ + Display *dpy = XtDisplay (w); + + XtDestroyWidget ((Widget)w); + XCloseDisplay (dpy); + exit (status); +} + + +/* ARGSUSED */ +static Boolean SetValues (gcurrent, grequest, gnew, args, num_args) + Widget gcurrent, grequest, gnew; + ArgList args; + Cardinal *num_args; +{ + NetstatWidget current = (NetstatWidget) gcurrent; + NetstatWidget new = (NetstatWidget) gnew; + Boolean redisplay = FALSE; + + if (current->netstat.update != new->netstat.update) { + if (current->netstat.interval_id) + XtRemoveTimeOut (current->netstat.interval_id); + new->netstat.interval_id = + XtAppAddTimeOut (XtWidgetToApplicationContext(gnew), + new->netstat.update * 100, clock_tic, + (XtPointer) gnew); + } + + if (current->netstat.foreground_pixel != new->netstat.foreground_pixel || + current->core.background_pixel != new->core.background_pixel) { + XtReleaseGC (gcurrent, current->netstat.gc); + new->netstat.gc = get_netstat_gc (new); + redisplay = TRUE; + } + + return (redisplay); +} + + +/* + * drawing code + */ + +static void redraw_netstat (w) + NetstatWidget w; +{ + register Display *dpy = XtDisplay (w); + register Window win = XtWindow (w); + register int x, y; + GC gc = w->netstat.gc; + Pixel back = w->core.background_pixel; + struct _mbimage *im; + + /* center the picture in the window */ + + switch (w->netstat.state) { + case 0: + case 1: + im = &w->netstat.inactive; + break; + case 2: + im = &w->netstat.waiting; + break; + case 3: + im = &w->netstat.active; + break; + case 4: + im = &w->netstat.activeout; + if (w->netstat.flipit) back = w->netstat.foreground_pixel; + break; + case 5: + im = &w->netstat.start; + break; + case 6: + im = &w->netstat.stop; + break; + default: + fprintf(stderr,"xmonisdn: Error in redrawing -- wrong netstat.state:%d\n", w->netstat.state); + CloseDown(w, -1); + } + + x = (((int)w->core.width) - im->width) / 2; + y = (((int)w->core.height) - im->height) / 2; + + XSetWindowBackground (dpy, win, back); + XClearWindow (dpy, win); + XCopyArea (dpy, im->pixmap, win, gc, 0, 0, im->width, im->height, x, y); + + /* + * XXX - temporary hack; walk up widget tree to find top most parent (which + * will be a shell) and mash it to have our shape. This will be replaced + * by a special shell widget. + */ + if (w->netstat.shapeit) { + Widget parent; + + for (parent = (Widget) w; XtParent(parent); + parent = XtParent(parent)) { + x += parent->core.x + parent->core.border_width; + y += parent->core.y + parent->core.border_width; + } + + if (im->mask != w->netstat.shape_cache.mask || + x != w->netstat.shape_cache.x || y != w->netstat.shape_cache.y) { + XShapeCombineMask (XtDisplay(parent), XtWindow(parent), + ShapeBounding, x, y, im->mask, ShapeSet); + w->netstat.shape_cache.mask = im->mask; + w->netstat.shape_cache.x = x; + w->netstat.shape_cache.y = y; + } + } + + return; +} + + +static void beep (w) + NetstatWidget w; +{ + if (w->netstat.volume > 0) + XBell (XtDisplay (w), w->netstat.volume); + return; +} + + diff --git a/xmonisdn/Net.h b/xmonisdn/Net.h new file mode 100644 index 00000000..8a13ceff --- /dev/null +++ b/xmonisdn/Net.h @@ -0,0 +1,46 @@ +#ifndef _XawNetstat_h +#define _XawNetstat_h + +/* + * Netstat widget; looks a lot like the clock widget, don't it... + */ + +/* resource names used by Netstat widget that aren't defined in StringDefs.h */ + +#ifndef _XtStringDefs_h_ +#define XtNupdate "update" +#endif + +#define XtNvolume "volume" +#define XtNactivePixmap "activePixmap" +#define XtNactivePixmapMask "activePixmapMask" +#define XtNactiveoutPixmap "activeoutPixmap" +#define XtNactiveoutPixmapMask "activeoutPixmapMask" +#define XtNwaitingPixmap "waitingPixmap" +#define XtNwaitingPixmapMask "waitingPixmapMask" +#define XtNinactivePixmap "inactivePixmap" +#define XtNinactivePixmapMask "inactivePixmapMask" +#define XtNstartPixmap "startPixmap" +#define XtNstartPixmapMask "startPixmapMask" +#define XtNstopPixmap "stopPixmap" +#define XtNstopPixmapMask "stopPixmapMask" +#define XtNflip "flip" +#define XtNshapeWindow "shapeWindow" + +#define XtCVolume "Volume" +#define XtCPixmapMask "PixmapMask" +#define XtCFlip "Flip" +#define XtCShapeWindow "ShapeWindow" + + +/* structures */ + +typedef struct _NetstatRec *NetstatWidget; /* see NetstatP.h */ +typedef struct _NetstatClassRec *NetstatWidgetClass; /* see NetstatP.h */ + + +extern WidgetClass netstatWidgetClass; + +#endif /* _XawNetstat_h */ +/* DON'T ADD STUFF AFTER THIS #endif */ + diff --git a/xmonisdn/NetP.h b/xmonisdn/NetP.h new file mode 100644 index 00000000..9ac5b563 --- /dev/null +++ b/xmonisdn/NetP.h @@ -0,0 +1,59 @@ +#ifndef _XawNetstatP_h +#define _XawNetstatP_h + +#include "Net.h" +#include <X11/Xaw/SimpleP.h> + +#define NETINFO_FILE "/dev/isdninfo" +#ifndef NETUP_COMMAND +#define NETUP_COMMAND "/sbin/isdnnet start &" +#endif +#ifndef NETDOWN_COMMAND +#define NETDOWN_COMMAND "/sbin/isdnnet stop &" +#endif + + +typedef struct { /* new fields for netstat widget */ + /* resources */ + int update; /* 1/100 seconds between updates */ + Pixel foreground_pixel; /* color index of normal state fg */ + String filename; /* filename to watch */ + Boolean flipit; /* do flip of full pixmap */ + int volume; /* bell volume */ + /* local state */ + GC gc; /* normal GC to use */ + long last_size; /* size in bytes of netstatname */ + XtIntervalId interval_id; /* time between checks */ + Boolean state; /* state of ISDN connection */ + struct _mbimage { + Pixmap bitmap, mask; /* depth 1, describing shape */ + Pixmap pixmap; /* full depth pixmap */ + int width, height; /* geometry of pixmaps */ + } active, waiting, inactive, activeout, start, stop; + Boolean shapeit; /* do shape extension */ + struct { + Pixmap mask; + int x, y; + } shape_cache; /* last set of info */ +} NetstatPart; + +typedef struct _NetstatRec { /* full instance record */ + CorePart core; + SimplePart simple; + NetstatPart netstat; +} NetstatRec; + + +typedef struct { /* new fields for netstat class */ + int dummy; /* stupid C compiler */ +} NetstatClassPart; + +typedef struct _NetstatClassRec { /* full class record declaration */ + CoreClassPart core_class; + SimpleClassPart simple_class; + NetstatClassPart netstat_class; +} NetstatClassRec; + +extern NetstatClassRec netstatClassRec; /* class pointer */ + +#endif /* _XawNetstatP_h */ diff --git a/xmonisdn/README b/xmonisdn/README new file mode 100644 index 00000000..c1633b00 --- /dev/null +++ b/xmonisdn/README @@ -0,0 +1,68 @@ +XMONISDN + +1. Purpose + +After having installed the ISDN system I felt a bit uneasy since the +system can initiate connections by itself. In fact, I have seen +spontaneous connections when Netscape was running. + +For this reason I wanted a monitor that does not consume too much CPU +resource and displays the connection status in a concise way. Further, +I wanted an easy method to control the ISDN connection, which means +shutting down the ISDN subsystem or starting it up -- by clicking on +an icon. + +Using the Xbiff program as a source of inspiration I implemented a tool +that has the functionality described above. + + +2. Monitoring the ISDN Subsystem + +The state of the ISDN subsystem is displayed in a small window showing +appropriate icons: + +- the ISDN subsystem is inactive: one solid terminal in the foreground, + another dashed terminal in the background +- the ISDN subsystem is active, but there is no network connection over + the ISDN line: two terminals connected by dashed arrows +- there is an incoming ISDN network connection or the ISDN system is dialing: + two terminals connected by solid arrows +- there is an outgoing ISDN network connection: two terminals connected + by fat arrows in reverse video. + +When an outgoing connection is established or when the ISDN subsystem +hangs up, the program beeps to signal this important state change. + + +3. Controlling the ISDN Subsystem + +Pressing button 2 in the window while the ISDN system is inactive +executes the command "/sbin/isdnnet start &" and pressing button 3 +executes "/sbin/isdnnet stop". Provided /sbin/isdnnet is a +shell-script that can start and stop the ISDN subsystem and provided +xmonisdn is installed as setuid root, you can startup and stop the +ISDN system in this way. + + +4. Compilation and Installation + +After having installed the source directory type + + xmkmf + make + make install.all + +which compiles and installs all files. Note: xmonisdn is installed +as setiud root! + +Now you only have to setup the shell-script /sbin/isdnnet, which could +simply be a link to the appropriate initialization script. I wrote a +new script that includes a call to "sendmail -q" in order to deliver +all mail that has been queued while the ISDN system was inactive. + +Bernhard Nebel, December 9, 1996 + + + + + diff --git a/xmonisdn/netactive b/xmonisdn/netactive new file mode 100644 index 00000000..2c6329ec --- /dev/null +++ b/xmonisdn/netactive @@ -0,0 +1,28 @@ +#define netactive_width 48 +#define netactive_height 48 +static unsigned char netactive_bits[] = { + 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, + 0x00, 0x00, 0x00, 0xfd, 0xff, 0xbf, 0x00, 0x00, 0x00, 0x05, 0x00, 0xa0, + 0x00, 0x00, 0x00, 0x05, 0x00, 0xa0, 0x00, 0x00, 0x00, 0x05, 0x00, 0xa0, + 0x00, 0x00, 0x78, 0xc5, 0x1f, 0xa0, 0x00, 0x00, 0x46, 0x05, 0x00, 0xa0, + 0x00, 0x80, 0x41, 0x05, 0x00, 0xa0, 0x00, 0x60, 0x70, 0xc5, 0x1f, 0xa0, + 0x00, 0x10, 0x0e, 0x05, 0x00, 0xa0, 0x00, 0x08, 0x01, 0x05, 0x00, 0xa0, + 0x00, 0xc4, 0x00, 0xc5, 0xff, 0xa1, 0x00, 0x22, 0x00, 0x05, 0x00, 0xa0, + 0x00, 0x12, 0x00, 0x05, 0x00, 0xa0, 0x00, 0x11, 0x00, 0xfd, 0xff, 0xbf, + 0x00, 0x09, 0x00, 0x01, 0x00, 0x80, 0x80, 0x04, 0x00, 0x3f, 0x00, 0xfc, + 0x80, 0x04, 0x00, 0xc0, 0xff, 0x03, 0x70, 0x1c, 0x00, 0x00, 0x00, 0x00, + 0x20, 0x08, 0x00, 0xfe, 0xff, 0x7f, 0x40, 0x04, 0x00, 0x55, 0x55, 0x75, + 0x80, 0x02, 0x80, 0xaa, 0xaa, 0x7a, 0x00, 0x01, 0xc0, 0xff, 0xff, 0x1f, + 0xf8, 0xff, 0xff, 0x07, 0x80, 0x00, 0x08, 0x00, 0x00, 0x04, 0x40, 0x01, + 0xe8, 0xff, 0xff, 0x05, 0x20, 0x02, 0x28, 0x00, 0x00, 0x05, 0x10, 0x04, + 0x28, 0x00, 0x00, 0x05, 0x38, 0x0e, 0x28, 0x00, 0x00, 0x05, 0x20, 0x01, + 0x28, 0xfe, 0x01, 0x05, 0x20, 0x01, 0x28, 0x00, 0x00, 0x05, 0x10, 0x01, + 0x28, 0x00, 0x00, 0x05, 0x88, 0x00, 0x28, 0xfe, 0x01, 0x05, 0x48, 0x00, + 0x28, 0x00, 0x00, 0x05, 0x44, 0x00, 0x28, 0x00, 0x00, 0x05, 0x23, 0x00, + 0x28, 0xfe, 0x0f, 0xc5, 0x18, 0x00, 0x28, 0x00, 0x00, 0x35, 0x04, 0x00, + 0x28, 0x00, 0x00, 0x15, 0x03, 0x00, 0xe8, 0xff, 0xff, 0xd5, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x34, 0x00, 0x00, 0xf8, 0x01, 0xe0, 0x07, 0x00, 0x00, + 0x00, 0xfe, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xf0, 0xff, 0xff, 0x03, 0x00, 0x00, 0xa8, 0xaa, 0xaa, 0x03, 0x00, 0x00, + 0x54, 0x55, 0xd5, 0x03, 0x00, 0x00, 0xfe, 0xff, 0xff, 0x00, 0x00, 0x00, + }; diff --git a/xmonisdn/netactiveout b/xmonisdn/netactiveout new file mode 100644 index 00000000..1686e066 --- /dev/null +++ b/xmonisdn/netactiveout @@ -0,0 +1,28 @@ +#define netactiveout_width 48 +#define netactiveout_height 48 +static unsigned char netactiveout_bits[] = { + 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, + 0x00, 0x00, 0x00, 0xfd, 0xff, 0xbf, 0x00, 0x00, 0x00, 0x05, 0x00, 0xa0, + 0x00, 0x00, 0x00, 0x05, 0x00, 0xa0, 0x00, 0x00, 0x00, 0x05, 0x00, 0xa0, + 0x00, 0x00, 0x78, 0xc5, 0x1f, 0xa0, 0x00, 0x00, 0x7e, 0x05, 0x00, 0xa0, + 0x00, 0x80, 0x7f, 0x05, 0x00, 0xa0, 0x00, 0xe0, 0x7f, 0xc5, 0x1f, 0xa0, + 0x00, 0xf0, 0x0f, 0x05, 0x00, 0xa0, 0x00, 0xf8, 0x01, 0x05, 0x00, 0xa0, + 0x00, 0xfc, 0x00, 0xc5, 0xff, 0xa1, 0x00, 0x3e, 0x00, 0x05, 0x00, 0xa0, + 0x00, 0x1e, 0x00, 0x05, 0x00, 0xa0, 0x00, 0x1f, 0x00, 0xfd, 0xff, 0xbf, + 0x00, 0x0f, 0x00, 0x01, 0x00, 0x80, 0x80, 0x07, 0x00, 0x3f, 0x00, 0xfc, + 0x80, 0x07, 0x00, 0xc0, 0xff, 0x03, 0xf0, 0x1f, 0x00, 0x00, 0x00, 0x00, + 0xe0, 0x0f, 0x00, 0xfe, 0xff, 0x7f, 0xc0, 0x07, 0x00, 0x55, 0x55, 0x75, + 0x80, 0x03, 0x80, 0xaa, 0xaa, 0x7a, 0x00, 0x01, 0xc0, 0xff, 0xff, 0x1f, + 0xf8, 0xff, 0xff, 0x07, 0x80, 0x00, 0x08, 0x00, 0x00, 0x04, 0xc0, 0x01, + 0xe8, 0xff, 0xff, 0x05, 0xe0, 0x03, 0x28, 0x00, 0x00, 0x05, 0xf0, 0x07, + 0x28, 0x00, 0x00, 0x05, 0xf8, 0x0f, 0x28, 0x00, 0x00, 0x05, 0xe0, 0x01, + 0x28, 0xfe, 0x01, 0x05, 0xe0, 0x01, 0x28, 0x00, 0x00, 0x05, 0xf0, 0x01, + 0x28, 0x00, 0x00, 0x05, 0xf8, 0x00, 0x28, 0xfe, 0x01, 0x05, 0x78, 0x00, + 0x28, 0x00, 0x00, 0x05, 0x7c, 0x00, 0x28, 0x00, 0x00, 0x05, 0x3f, 0x00, + 0x28, 0xfe, 0x0f, 0xc5, 0x1f, 0x00, 0x28, 0x00, 0x00, 0xf5, 0x07, 0x00, + 0x28, 0x00, 0x00, 0xf5, 0x03, 0x00, 0xe8, 0xff, 0xff, 0xf5, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x34, 0x00, 0x00, 0xf8, 0x01, 0xe0, 0x07, 0x00, 0x00, + 0x00, 0xfe, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xf0, 0xff, 0xff, 0x03, 0x00, 0x00, 0xa8, 0xaa, 0xaa, 0x03, 0x00, 0x00, + 0x54, 0x55, 0xd5, 0x03, 0x00, 0x00, 0xfe, 0xff, 0xff, 0x00, 0x00, 0x00, + }; diff --git a/xmonisdn/netinactive b/xmonisdn/netinactive new file mode 100644 index 00000000..d81d4374 --- /dev/null +++ b/xmonisdn/netinactive @@ -0,0 +1,28 @@ +#define netinactive_width 48 +#define netinactive_height 48 +static unsigned char netinactive_bits[] = { + 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x54, 0x55, 0x95, 0x00, 0x00, 0x00, 0x01, 0x00, 0x20, + 0x00, 0x00, 0x00, 0x04, 0x00, 0x80, 0x00, 0x00, 0x00, 0x01, 0x00, 0x20, + 0x00, 0x00, 0x00, 0x44, 0x15, 0x80, 0x00, 0x00, 0x00, 0x01, 0x00, 0x20, + 0x00, 0x00, 0x00, 0x04, 0x00, 0x80, 0x00, 0x00, 0x00, 0x41, 0x15, 0x20, + 0x00, 0x00, 0x00, 0x04, 0x00, 0x80, 0x00, 0x00, 0x00, 0x01, 0x00, 0x20, + 0x00, 0x00, 0x00, 0x44, 0x55, 0x81, 0x00, 0x00, 0x00, 0x01, 0x00, 0x20, + 0x00, 0x00, 0x00, 0x04, 0x00, 0x80, 0x00, 0x00, 0x00, 0xa9, 0xaa, 0x2a, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x2b, 0x00, 0x54, + 0x00, 0x00, 0x00, 0x80, 0xaa, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x56, 0x55, 0x55, 0x00, 0x00, 0x00, 0x51, 0x04, 0x21, + 0x00, 0x00, 0x00, 0xa8, 0xa2, 0x70, 0x00, 0x00, 0xc0, 0xaa, 0xaa, 0x0a, + 0xf8, 0xff, 0xff, 0x07, 0x00, 0x00, 0x08, 0x00, 0x00, 0x04, 0x00, 0x00, + 0xe8, 0xff, 0xff, 0x05, 0x00, 0x00, 0x28, 0x00, 0x00, 0x05, 0x00, 0x00, + 0x28, 0x00, 0x00, 0x05, 0x00, 0x00, 0x28, 0x00, 0x00, 0x05, 0x00, 0x00, + 0x28, 0xfe, 0x01, 0x05, 0x00, 0x00, 0x28, 0x00, 0x00, 0x05, 0x00, 0x00, + 0x28, 0x00, 0x00, 0x05, 0x00, 0x00, 0x28, 0xfe, 0x01, 0x05, 0x00, 0x00, + 0x28, 0x00, 0x00, 0x05, 0x00, 0x00, 0x28, 0x00, 0x00, 0x05, 0x00, 0x00, + 0x28, 0xfe, 0x0f, 0x05, 0x00, 0x00, 0x28, 0x00, 0x00, 0x05, 0x00, 0x00, + 0x28, 0x00, 0x00, 0x05, 0x00, 0x00, 0xe8, 0xff, 0xff, 0x05, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x04, 0x00, 0x00, 0xf8, 0x01, 0xe0, 0x07, 0x00, 0x00, + 0x00, 0xfe, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xf0, 0xff, 0xff, 0x03, 0x00, 0x00, 0xa8, 0xaa, 0xaa, 0x03, 0x00, 0x00, + 0x54, 0x55, 0xd5, 0x03, 0x00, 0x00, 0xfe, 0xff, 0xff, 0x00, 0x00, 0x00, + }; diff --git a/xmonisdn/netstart b/xmonisdn/netstart new file mode 100644 index 00000000..8c8d5779 --- /dev/null +++ b/xmonisdn/netstart @@ -0,0 +1,28 @@ +#define netstart_width 48 +#define netstart_height 48 +static unsigned char netstart_bits[] = { + 0x00, 0x00, 0x40, 0x54, 0x55, 0x55, 0x00, 0x00, 0xe0, 0x00, 0x00, 0x80, + 0x00, 0x00, 0xf0, 0xa9, 0xaa, 0x2a, 0x00, 0x00, 0xf8, 0x03, 0x00, 0x80, + 0x00, 0x00, 0xfc, 0x07, 0x00, 0x20, 0x00, 0x00, 0xfe, 0x0f, 0x00, 0x80, + 0x00, 0x00, 0xff, 0x1f, 0x15, 0x20, 0x00, 0x80, 0xff, 0x3f, 0x00, 0x80, + 0x00, 0xc0, 0xff, 0x7f, 0x00, 0x20, 0x00, 0xe0, 0xff, 0xff, 0x20, 0x80, + 0x00, 0xf0, 0xff, 0xff, 0x01, 0x20, 0x00, 0xf8, 0xff, 0xff, 0x03, 0x80, + 0x00, 0xfc, 0xff, 0xff, 0x47, 0x21, 0x00, 0xfe, 0xff, 0xff, 0x0f, 0x80, + 0x00, 0xff, 0xff, 0xff, 0x1f, 0x20, 0x80, 0xff, 0xff, 0xff, 0x3f, 0x95, + 0xc0, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0xfe, 0x0f, 0x00, 0xa8, + 0x80, 0x00, 0xfe, 0x8f, 0xaa, 0x02, 0x50, 0x14, 0xfe, 0x0f, 0x00, 0x00, + 0x00, 0x00, 0xfe, 0xaf, 0xaa, 0x2a, 0x40, 0x04, 0xfe, 0x0f, 0x00, 0x40, + 0x00, 0x01, 0xfe, 0x0f, 0x00, 0x20, 0x00, 0x01, 0xfe, 0x5f, 0x55, 0x15, + 0xa8, 0xaa, 0xfe, 0x0f, 0x80, 0x00, 0x00, 0x00, 0xfe, 0x0f, 0x40, 0x01, + 0x48, 0x55, 0xfe, 0x0f, 0x00, 0x00, 0x20, 0x00, 0xfe, 0x0f, 0x10, 0x04, + 0x08, 0x00, 0xfe, 0x0f, 0x08, 0x0a, 0x20, 0x00, 0xfe, 0x0f, 0x20, 0x01, + 0x08, 0xaa, 0xfe, 0x0f, 0x20, 0x00, 0x20, 0x00, 0xfe, 0x0f, 0x00, 0x01, + 0x08, 0x00, 0xfe, 0x0f, 0x08, 0x00, 0x20, 0x54, 0xfe, 0x0f, 0x40, 0x00, + 0x08, 0x00, 0xfe, 0x0f, 0x04, 0x00, 0x20, 0x00, 0xfe, 0x0f, 0x21, 0x00, + 0x08, 0xaa, 0xfe, 0x4f, 0x08, 0x00, 0x20, 0x00, 0xfe, 0x0f, 0x00, 0x00, + 0x08, 0x00, 0xfe, 0x0f, 0x02, 0x00, 0xa0, 0xaa, 0xfe, 0x8f, 0x00, 0x00, + 0x08, 0x00, 0xfe, 0x2f, 0x00, 0x00, 0x50, 0x01, 0xfe, 0x0f, 0x00, 0x00, + 0x00, 0x54, 0xfe, 0x0f, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x0f, 0x00, 0x00, + 0x50, 0x55, 0xfe, 0x0f, 0x00, 0x00, 0x08, 0x00, 0xfe, 0x0f, 0x00, 0x00, + 0x04, 0x00, 0xfe, 0x0f, 0x00, 0x00, 0xaa, 0xaa, 0xfe, 0x0f, 0x00, 0x00, + }; diff --git a/xmonisdn/netstop b/xmonisdn/netstop new file mode 100644 index 00000000..02f77259 --- /dev/null +++ b/xmonisdn/netstop @@ -0,0 +1,28 @@ +#define netstop_width 48 +#define netstop_height 48 +static unsigned char netstop_bits[] = { + 0x00, 0x00, 0xfc, 0x3f, 0x55, 0x55, 0x00, 0x00, 0xfc, 0x3f, 0x00, 0x80, + 0x00, 0x00, 0xfc, 0xbf, 0xaa, 0x2a, 0x00, 0x00, 0xfc, 0x3f, 0x00, 0x80, + 0x00, 0x00, 0xfc, 0x3f, 0x00, 0x20, 0x00, 0x00, 0xfc, 0x3f, 0x00, 0x80, + 0x00, 0x00, 0xfc, 0x3f, 0x15, 0x20, 0x00, 0x00, 0xfc, 0x3f, 0x00, 0x80, + 0x00, 0x80, 0xfc, 0x3f, 0x00, 0x20, 0x00, 0x40, 0xfc, 0xbf, 0x2a, 0x80, + 0x00, 0x10, 0xfc, 0x3f, 0x00, 0x20, 0x00, 0x00, 0xfc, 0x3f, 0x00, 0x80, + 0x00, 0x84, 0xfc, 0x3f, 0x55, 0x21, 0x00, 0x20, 0xfc, 0x3f, 0x00, 0x80, + 0x00, 0x02, 0xfc, 0x3f, 0x00, 0x20, 0x00, 0x10, 0xfc, 0x3f, 0x55, 0x95, + 0x00, 0x01, 0xfc, 0x3f, 0x00, 0x00, 0x00, 0x04, 0xfc, 0x3f, 0x00, 0xa8, + 0x80, 0x00, 0xfc, 0xbf, 0xaa, 0x02, 0x50, 0x14, 0xfc, 0x3f, 0x00, 0x00, + 0x20, 0x08, 0xfc, 0xbf, 0xaa, 0x2a, 0x00, 0x00, 0xfc, 0x3f, 0x00, 0x40, + 0x80, 0x02, 0xfc, 0x3f, 0x00, 0x20, 0x00, 0x01, 0xfc, 0x3f, 0x55, 0x15, + 0xa8, 0xaa, 0xfe, 0x3f, 0x80, 0x00, 0x00, 0x00, 0xfc, 0x3f, 0x40, 0x01, + 0x48, 0x55, 0xfd, 0x3f, 0x00, 0x00, 0x20, 0x00, 0xfc, 0x3f, 0x10, 0x04, + 0x08, 0x00, 0xfc, 0x3f, 0x08, 0x0a, 0x20, 0x00, 0xfc, 0x3f, 0x00, 0x00, + 0x88, 0xff, 0xff, 0xff, 0xff, 0x01, 0x20, 0xff, 0xff, 0xff, 0xff, 0x00, + 0x08, 0xfe, 0xff, 0xff, 0x7f, 0x00, 0x20, 0xfc, 0xff, 0xff, 0x3f, 0x00, + 0x08, 0xf8, 0xff, 0xff, 0x1f, 0x00, 0x20, 0xf0, 0xff, 0xff, 0x0f, 0x00, + 0x08, 0xe2, 0xff, 0xff, 0x07, 0x00, 0x20, 0xe0, 0xff, 0xff, 0x03, 0x00, + 0x08, 0xc0, 0xff, 0xff, 0x01, 0x00, 0xa0, 0x8a, 0xff, 0xff, 0x00, 0x00, + 0x08, 0x00, 0xff, 0x7f, 0x00, 0x00, 0x50, 0x01, 0xfe, 0x3f, 0x00, 0x00, + 0x00, 0x54, 0xfc, 0x1f, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x0f, 0x00, 0x00, + 0x50, 0x55, 0xf1, 0x07, 0x00, 0x00, 0x08, 0x00, 0xe0, 0x03, 0x00, 0x00, + 0x04, 0x00, 0xc0, 0x01, 0x00, 0x00, 0xaa, 0xaa, 0x8a, 0x00, 0x00, 0x00, + }; diff --git a/xmonisdn/netwaiting b/xmonisdn/netwaiting new file mode 100644 index 00000000..c96a17d0 --- /dev/null +++ b/xmonisdn/netwaiting @@ -0,0 +1,28 @@ +#define netwaiting_width 48 +#define netwaiting_height 48 +static unsigned char netwaiting_bits[] = { + 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x01, 0x00, 0x80, + 0x00, 0x00, 0x00, 0xfd, 0xff, 0xbf, 0x00, 0x00, 0x00, 0x05, 0x00, 0xa0, + 0x00, 0x00, 0x00, 0x05, 0x00, 0xa0, 0x00, 0x00, 0x00, 0x05, 0x00, 0xa0, + 0x00, 0x00, 0x50, 0xc5, 0x1f, 0xa0, 0x00, 0x00, 0x04, 0x05, 0x00, 0xa0, + 0x00, 0x00, 0x41, 0x05, 0x00, 0xa0, 0x00, 0x40, 0x20, 0xc5, 0x1f, 0xa0, + 0x00, 0x10, 0x0a, 0x05, 0x00, 0xa0, 0x00, 0x00, 0x00, 0x05, 0x00, 0xa0, + 0x00, 0x84, 0x00, 0xc5, 0xff, 0xa1, 0x00, 0x20, 0x00, 0x05, 0x00, 0xa0, + 0x00, 0x02, 0x00, 0x05, 0x00, 0xa0, 0x00, 0x10, 0x00, 0xfd, 0xff, 0xbf, + 0x00, 0x01, 0x00, 0x01, 0x00, 0x80, 0x00, 0x04, 0x00, 0x3f, 0x00, 0xfc, + 0x80, 0x00, 0x00, 0xc0, 0xff, 0x03, 0x20, 0x14, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0xfe, 0xff, 0x7f, 0x40, 0x04, 0x00, 0x55, 0x55, 0x75, + 0x00, 0x00, 0x80, 0xaa, 0xaa, 0x7a, 0x00, 0x01, 0xc0, 0xff, 0xff, 0x1f, + 0xf8, 0xff, 0xff, 0x07, 0x80, 0x00, 0x08, 0x00, 0x00, 0x04, 0x00, 0x00, + 0xe8, 0xff, 0xff, 0x05, 0x20, 0x02, 0x28, 0x00, 0x00, 0x05, 0x00, 0x00, + 0x28, 0x00, 0x00, 0x05, 0x10, 0x04, 0x28, 0x00, 0x00, 0x05, 0x00, 0x01, + 0x28, 0xfe, 0x01, 0x05, 0x20, 0x00, 0x28, 0x00, 0x00, 0x05, 0x00, 0x01, + 0x28, 0x00, 0x00, 0x05, 0x08, 0x00, 0x28, 0xfe, 0x01, 0x05, 0x40, 0x00, + 0x28, 0x00, 0x00, 0x05, 0x04, 0x00, 0x28, 0x00, 0x00, 0x05, 0x21, 0x00, + 0x28, 0xfe, 0x0f, 0x85, 0x08, 0x00, 0x28, 0x00, 0x00, 0x25, 0x00, 0x00, + 0x28, 0x00, 0x00, 0x15, 0x02, 0x00, 0xe8, 0xff, 0xff, 0x85, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x24, 0x00, 0x00, 0xf8, 0x01, 0xe0, 0x07, 0x00, 0x00, + 0x00, 0xfe, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xf0, 0xff, 0xff, 0x03, 0x00, 0x00, 0xa8, 0xaa, 0xaa, 0x03, 0x00, 0x00, + 0x54, 0x55, 0xd5, 0x03, 0x00, 0x00, 0xfe, 0xff, 0xff, 0x00, 0x00, 0x00, + }; diff --git a/xmonisdn/xmonisdn.c b/xmonisdn/xmonisdn.c new file mode 100644 index 00000000..a61ec6f1 --- /dev/null +++ b/xmonisdn/xmonisdn.c @@ -0,0 +1,94 @@ +#include <stdio.h> +#include <X11/Xatom.h> +#include <X11/Intrinsic.h> +#include <X11/StringDefs.h> +#include "Net.h" +#include <X11/Xaw/Cardinals.h> + +extern void exit(); +static void quit(); + +char *ProgramName; + +static XrmOptionDescRec options[] = { +{ "-update", "*netstat.update", XrmoptionSepArg, (caddr_t) NULL }, +{ "-file", "*netstat.file", XrmoptionSepArg, (caddr_t) NULL }, +{ "-shape", "*netstat.shapeWindow", XrmoptionNoArg, (caddr_t) "on" }, +{ "-volume", "*netstat.volume", XrmoptionSepArg, (caddr_t) NULL }, +}; + +static XtActionsRec xmonisdn_actions[] = { + { "quit", quit }, +}; +static Atom wm_delete_window; + +static void Usage () +{ + static char *help_message[] = { +"where options include:", +" -display host:dpy X server to contact", +" -geometry geom size of Netstat", +" -file file isdninfo-file to watch", +" -update 1/10 of a second how often to check", +" -bg color background color", +" -fg color foreground color", +" -rv reverse video", +" -volume percentage how loud to ring the bell", +" -shape shape the window", +NULL}; + char **cpp; + + fprintf (stderr, "usage: %s [-options ...]\n", ProgramName); + for (cpp = help_message; *cpp; cpp++) { + fprintf (stderr, "%s\n", *cpp); + } + fprintf (stderr, "\n"); + exit (1); +} + + +void main (argc, argv) + int argc; + char **argv; +{ + XtAppContext xtcontext; + Widget toplevel, w; + + ProgramName = argv[0]; + + toplevel = XtAppInitialize(&xtcontext, "xmonisdn", options, XtNumber (options), + &argc, argv, NULL, NULL, 0); + if (argc != 1) Usage (); + + /* + * This is a hack so that f.delete will do something useful in this + * single-window application. + */ + XtAppAddActions (xtcontext, xmonisdn_actions, XtNumber(xmonisdn_actions)); + XtOverrideTranslations(toplevel, + XtParseTranslationTable ("<Message>WM_PROTOCOLS: quit()")); + + w = XtCreateManagedWidget ("netstat", netstatWidgetClass, toplevel, + NULL, 0); + XtRealizeWidget (toplevel); + wm_delete_window = XInternAtom (XtDisplay(toplevel), "WM_DELETE_WINDOW", + False); + (void) XSetWMProtocols (XtDisplay(toplevel), XtWindow(toplevel), + &wm_delete_window, 1); + XtAppMainLoop (xtcontext); +} + +static void quit (w, event, params, num_params) + Widget w; + XEvent *event; + String *params; + Cardinal *num_params; +{ + if (event->type == ClientMessage && + event->xclient.data.l[0] != wm_delete_window) { + XBell (XtDisplay(w), 0); + return; + } + XCloseDisplay (XtDisplay(w)); + exit (0); +} diff --git a/xmonisdn/xmonisdn.man b/xmonisdn/xmonisdn.man new file mode 100644 index 00000000..9405d160 --- /dev/null +++ b/xmonisdn/xmonisdn.man @@ -0,0 +1,204 @@ +.TH XMONISDN 1 "9 December 1996" "X Version 11" "X Tools" +.SH NAME +xmonisdn \- monitor for ISDN network +.SH SYNOPSIS +.B xmonisdn +[ \-\fItoolkitoption\fP ... ] [ \fI\-option\fP ... ] +.SH DESCRIPTION +The +.I xmonisdn +program displays the status of the ISDN network connection and allows +to start and stop the ISDN subsystem. If the ISDN subsystem is not +active, a window showing a terminal in the foreground and a dashed +terminal in the backgorund is displayed. If the ISDN system is active, +but there is no network connection established, two terminals with +dashed arrows between them is displayed. If there is a incoming +connection or there is dialing in progress, the arrows become more +solid. An outgoing network connection is signaled by solid arrows +between the terminals and the window is inverted. +If the ISDN subsystem dials out or hangs up, the program beeps to signal +the state change (this can be changed using the +.I volume +option). +.PP +Pressing button 2 on the window executes the command +.I /sbin/isdnnet start +and pressing button 3 executes +.I /sbin/isdnnet stop. +/sbin/isdnnet +should be a shell script that starts and stops the ISDN subsystem and +xmonisdn must be run as setuid root for this to work. +.SH OPTIONS +.I xmonisdn +accepts all of the standard X Toolkit command line options along with the +additional options listed below: +.TP 8 +.B \-help +This option indicates that a brief summary of the allowed options should be +printed on the standard error. +.TP 8 +.B \-update \fIthenth of a second\fP +This option specifies the frequency in 1/10 of a second at which \fIxmonisdn\fP +should update its display. If the window is obscured and then exposed, +it will be updated immediately. The default is 0.5 seconds. +.TP 8 +.B \-file \fIfilename\fP +This option specifies the name of the file which should be monitored. By +default, it watches /dev/isdninfo. +.TP 8 +.B \-volume \fIpercentage\fP +This option specifies how loud the bell should be rung when there is an important status change. +.TP 8 +.B \-shape +This option indicates that the xmonisdn window should be shaped if masks for +the images are given. +.PP +The following standard X Toolkit command line arguments are commonly used with +.I xmonisdn: +.TP 8 +.B \-display \fIdisplay\fP +This option specifies the X server to contact. +.TP 8 +.B \-geometry \fIgeometry\fP +This option specifies the preferred size and position of the xmonisdn window. +The icon is 48 pixels wide and 48 pixels high and will be centered in +the window. +.TP 8 +.B \-bg \fIcolor\fP +This option specifies the color to use for the background of the window. +.TP 8 +.B \-bd \fIcolor\fP +This option specifies the color to use for the border of the window. +.TP 8 +.B \-bw \fInumber\fP +This option specifies the width in pixels of the border surrounding the window. +.TP 8 +.B \-fg \fIcolor\fP +This option specifies the color to use for the foreground of the window. +.TP 8 +.B \-rv +This option indicates that reverse video should be simulated by swapping +the foreground and background colors. +.TP 8 +.B \-xrm \fIresourcestring\fP +This option specifies a resource string to be used. This is especially +useful for setting resources that do not have separate command line options. +.SH X DEFAULTS +The application class name is xmonisdn. +This program uses the +.I Netstat +widget. +It understands all of the core resource names and +classes as well as: +.PP +.TP 8 +.B file (\fPclass\fB File) +Specifies the name of the file to monitor. The default is to watch +/dev/isdninfo. +.TP 8 +.B width (\fPclass\fB Width) +Specifies the width of the icon. +.TP 8 +.B height (\fPclass\fB Height) +Specifies the height of the icon. +.TP 8 +.B update (\fPclass\fB Interval) +Specifies the frequency in 1/10 of a second at which the isdninfo file should be checked. +The default is 10. +.TP 8 +.B volume (\fPclass\fB Volume) +Specifies how loud the bell should be rung. The default is 33 percent. +.TP 8 +.B foreground (\fPclass\fB Foreground) +Specifies the color for the foreground. +.TP 8 +.B reverseVideo (\fPclass\fB ReverseVideo) +Specifies that the foreground and background should be reversed. +.TP 8 +.B flip (\fPclass\fB Flip) +Specifies whether or not the image that is shown when there is an outgoing network connection +should be inverted. The default is ``true.'' +.TP 8 +.B inactivePixmap (\fPclass\fB Pixmap) +Specifies a bitmap to be shown when the ISDN subsystem is inactive. +The default is netinactive. +.TP 8 +.B waitingPixmap (\fPclass\fB Pixmap) +Specifies a bitmap to be shown when the ISDN subsystem is active, but there is no connection. The default is netwaiting. +.TP 8 +.B activePixmap (\fPclass\fB Pixmap) +Specifies a bitmap to be shown when there is a incoming network connection (or dialing is in progress). The default is netactive. +.TP 8 +.B activeoutPixmap (\fPclass\fB Pixmap) +Specifies a bitmap to be shown when there is a outgoing network connection. +The default is netactiveout. +.TP 8 +.B startPixmap (\fPclass\fB Pixmap) +Specifies a bitmap to be shown when the ISDN network is started up. +The default is netstart. +.TP 8 +.B stopPixmap (\fPclass\fB Pixmap) +Specifies a bitmap to be shown when the ISDN network is stopped. +The default is netstop. +.TP 8 +.B shapeWindow (\fPclass\fB ShapeWindow) +Specifies whether or not the xmonisdn window should be shaped to the +given PixmapMasks. The default is false. +.TP 8 +.B inactivePixmapMask (\fPclass\fB PixmapMask) +Specifies a mask for the bitmap to be shown when the ISDN subsystem is inactive. +The default is none. +.TP 8 +.B waitingPixmapMask (\fPclass\fB PixmapMask) +Specifies a mask for the bitmap to be shown when the ISDN subsystem is active, but there is no connection. +The default is none. +.TP 8 +.B activePixmapMask (\fPclass\fB PixmapMask) +Specifies a mask for the bitmap to be shown when when there is a incoming network connection (or dialing is in progress). +The default is none. +.TP 8 +.B activeoutPixmapMask (\fPclass\fB PixmapMask) +Specifies a mask for the bitmap to be shown when there is a outgoing network connection. +The default is none. +.TP 8 +.B startPixmapMask (\fPclass\fB PixmapMask) +Specifies a mask for the bitmap to be shown when the ISDN network is started up. +The default is none. +.TP 8 +.B stopPixmapMask (\fPclass\fB PixmapMask) +Specifies a mask for the bitmap to be shown when the ISDN network is stopped. +The default is none. +.SH ACTIONS +The \fINetstat\fP widget provides the following actions for use in event +translations: +.TP 8 +.B check() +This action causes the widget to check the isdninfo file and display the appropriate icon. +.TP 8 +.B netdown() +This action causes the widget to execute /sbin/isdnnet stop. +.TP 8 +.B netup() +This action causes the widget to execute /sbin/isdnnet start. +.PP +The default translation is +.sp +.nf + <ButtonPress>Button2: netup() + <ButtonPress>Button3: netdown() +.fi +.sp +.SH ENVIRONMENT +.PP +.TP 8 +.B DISPLAY +to get the default host and display number. +.TP 8 +.B XENVIRONMENT +to get the name of a resource file that overrides the global resources +stored in the RESOURCE_MANAGER property. +.SH AUTHOR +Bernhard Nebel + + +