Compare commits
No commits in common. "debian" and "docker" have entirely different histories.
|
@ -1,113 +0,0 @@
|
|||
*.o
|
||||
*.sq3
|
||||
*.core
|
||||
magicka
|
||||
msgs/*
|
||||
node*/*
|
||||
nodeinuse.*
|
||||
doors/*
|
||||
last10.dat
|
||||
ansis/*
|
||||
config/*
|
||||
illusion/*
|
||||
scripts/*
|
||||
logs/*
|
||||
files/*
|
||||
*.a
|
||||
deps/lua/lua
|
||||
deps/lua/luac
|
||||
netmail.out
|
||||
echomail.out
|
||||
deps/odoors/libs-*
|
||||
deps/odoors/exe-*
|
||||
deps/odoors/objs-*
|
||||
utils/magiedit/magiedit
|
||||
msgserial
|
||||
whitelist.ip
|
||||
blacklist.ip
|
||||
.DS_Store
|
||||
cdk-config
|
||||
config.log
|
||||
config.status
|
||||
deps/cdk-5.0-20161210/Makefile
|
||||
deps/cdk-5.0-20161210/cli/Makefile
|
||||
deps/cdk-5.0-20161210/demos/Makefile
|
||||
deps/cdk-5.0-20161210/examples/Makefile
|
||||
cdk_config.h
|
||||
cdk_version.h
|
||||
utils/ticproc/ticproc
|
||||
utils/mgpost/mgpost
|
||||
deps/cdk-5.0-20161210/dscale.c
|
||||
deps/cdk-5.0-20161210/fscale.c
|
||||
deps/cdk-5.0-20161210/fslider.c
|
||||
deps/cdk-5.0-20161210/scale.c
|
||||
deps/cdk-5.0-20161210/slider.c
|
||||
deps/cdk-5.0-20161210/uscale.c
|
||||
deps/cdk-5.0-20161210/uslider.c
|
||||
deps/cdk-5.0-20161210/include/dscale.h
|
||||
deps/cdk-5.0-20161210/include/fscale.h
|
||||
deps/cdk-5.0-20161210/include/fslider.h
|
||||
deps/cdk-5.0-20161210/include/scale.h
|
||||
deps/cdk-5.0-20161210/include/slider.h
|
||||
deps/cdk-5.0-20161210/include/uscale.h
|
||||
deps/cdk-5.0-20161210/include/uslider.h
|
||||
deps/libb64-1.2/base64/base64
|
||||
deps/libb64-1.2/base64/depend
|
||||
deps/libb64-1.2/src/depend
|
||||
utils/fileapprove/fileapprove
|
||||
utils/magichat/magichat
|
||||
utils/magiftpd/magiftpd
|
||||
utils/magimail/bin/magiexport
|
||||
utils/magimail/bin/magigetnode
|
||||
utils/magimail/bin/magilist
|
||||
utils/magimail/bin/magilistout
|
||||
utils/magimail/bin/magimail
|
||||
utils/magimail/bin/magimaint
|
||||
utils/magimail/bin/magistats
|
||||
utils/magimail/bin/magiwrite
|
||||
keys/ssh_host_dsa_key
|
||||
magicka.strings
|
||||
www
|
||||
keys/ssh_host_dsa_key.pub
|
||||
keys/ssh_host_rsa_key
|
||||
keys/ssh_host_rsa_key.pub
|
||||
menus/doors.mnu
|
||||
menus/file.mnu
|
||||
menus/logoff.mnu
|
||||
menus/mail.mnu
|
||||
menus/main.mnu
|
||||
core
|
||||
docs/site
|
||||
utils/reset_pass/reset_pass
|
||||
.vscode
|
||||
last10v2.dat
|
||||
utils/filecenter/filecenter
|
||||
utils/dosbox_shim/shim
|
||||
deps/libuuid/Makefile
|
||||
deps/libuuid/config.h
|
||||
deps/libuuid/libtool
|
||||
deps/libuuid/libuuid.la
|
||||
deps/libuuid/stamp-h1
|
||||
deps/libuuid/uuid.pc
|
||||
mail.out
|
||||
mnet/*
|
||||
deps/libuuid/autom4te.cache
|
||||
utils/mnetftpd/mnetftpd
|
||||
deps/ftplib-4.0-1/src/qftp.static
|
||||
deps/ftplib-4.0-1/src/libftp.so
|
||||
deps/ftplib-4.0-1/src/libftp.so.4
|
||||
deps/ftplib-4.0-1/src/libftp.so.4.0
|
||||
deps/ftplib-4.0-1/src/qftp
|
||||
deps/libuuid/configure
|
||||
deps/libuuid/Makefile.in
|
||||
deps/libuuid/aclocal.m4
|
||||
deps/libuuid/ltmain.sh
|
||||
utils/qwknet/qwktoss
|
||||
deps/libuuid/config.h.in~
|
||||
deps/libuuid/compile
|
||||
deps/libuuid/config.guess
|
||||
deps/libuuid/config.sub
|
||||
deps/libuuid/config.h.in
|
||||
deps/libuuid/depcomp
|
||||
deps/libuuid/install-sh
|
||||
deps/libuuid/missing
|
|
@ -1,70 +1,63 @@
|
|||
image: docker:latest
|
||||
|
||||
stages:
|
||||
- test
|
||||
- build
|
||||
- deploy
|
||||
|
||||
variables:
|
||||
VERSION: "0.12"
|
||||
DOCKER_HOST: tcp://docker:2375
|
||||
|
||||
services:
|
||||
- docker:dind
|
||||
|
||||
before_script:
|
||||
- env|sort
|
||||
- pwd
|
||||
- apk add curl
|
||||
- docker info
|
||||
- docker version
|
||||
- echo "$CI_JOB_TOKEN" | docker login -u "$CI_REGISTRY_USER" "$CI_REGISTRY" --password-stdin
|
||||
|
||||
test:
|
||||
stage: test
|
||||
script:
|
||||
- cat /etc/hosts
|
||||
- env|sort
|
||||
- docker build -t ${CI_REGISTRY_IMAGE}:${VERSION} .
|
||||
- docker images
|
||||
tags:
|
||||
- docker
|
||||
only:
|
||||
- debug
|
||||
|
||||
build:x86_64:
|
||||
image: ${CI_REGISTRY}/leenooks/ci-apt:x86_64
|
||||
variables:
|
||||
CACHETAG: build-x86_64
|
||||
VERSION: 0.12-alpha-x86_64
|
||||
stage: build
|
||||
script:
|
||||
- apt-get update
|
||||
- apt-get install -y zip unzip dos2unix libbz2-dev zlib1g-dev libgeoip-dev libncurses5-dev libhunspell-dev libsqlite3-dev libreadline-dev libssl1.0-dev libssh-dev libmicrohttpd-dev libdbd-sqlite3-perl libmosquitto-dev m4 sed
|
||||
- git archive --format=tar HEAD |gzip -9 > ../${CI_PROJECT_NAME}_${VERSION}.orig.tar.gz
|
||||
- dpkg-buildpackage -us -uc
|
||||
- mkdir build
|
||||
- ls -al ../
|
||||
- mv ../${CI_PROJECT_NAME}*.deb build
|
||||
- if [ -f init ]; then chmod 500 init; fi
|
||||
- docker pull ${CI_REGISTRY_IMAGE}:${CACHETAG} || true
|
||||
- docker build --cache-from ${CI_REGISTRY_IMAGE}:${CACHETAG} -t ${CI_REGISTRY_IMAGE}:${VERSION} -t ${CI_REGISTRY_IMAGE}:${CACHETAG} .
|
||||
- docker push ${CI_REGISTRY_IMAGE}:${VERSION}
|
||||
- docker push ${CI_REGISTRY_IMAGE}:${CACHETAG}
|
||||
tags:
|
||||
- apt
|
||||
- docker
|
||||
- x86_64
|
||||
only:
|
||||
- debian
|
||||
artifacts:
|
||||
paths:
|
||||
- build/*deb
|
||||
expire_in: 1 week
|
||||
|
||||
deploy:x86_64:
|
||||
stage: deploy
|
||||
dependencies:
|
||||
- build:x86_64
|
||||
script:
|
||||
- reprepro -b /apt includedeb $(awk -F"[)(]+" '/VERSION=/ {print $2}' /etc/os-release) build/${CI_PROJECT_NAME}_${VERSION}*.deb
|
||||
tags:
|
||||
- reprepro
|
||||
- docker
|
||||
|
||||
build:armv7l:
|
||||
image: ${CI_REGISTRY}/leenooks/ci-apt:armv7l
|
||||
variables:
|
||||
CACHETAG: build-armv7l
|
||||
VERSION: 0.12-alpha-armv7l
|
||||
stage: build
|
||||
script:
|
||||
- apt-get update
|
||||
- apt-get install -y zip unzip dos2unix libbz2-dev zlib1g-dev libgeoip-dev libncurses5-dev libhunspell-dev libsqlite3-dev libreadline-dev libssl1.0-dev libssh-dev libmicrohttpd-dev libdbd-sqlite3-perl libmosquitto-dev m4 sed
|
||||
- git archive --format=tar HEAD |gzip -9 > ../${CI_PROJECT_NAME}_${VERSION}.orig.tar.gz
|
||||
- dpkg-buildpackage -us -uc
|
||||
- mkdir build
|
||||
- ls -al ../
|
||||
- mv ../${CI_PROJECT_NAME}*.deb build
|
||||
- if [ -f init ]; then chmod 500 init; fi
|
||||
- docker pull ${CI_REGISTRY_IMAGE}:${CACHETAG} || true
|
||||
- docker build --cache-from ${CI_REGISTRY_IMAGE}:${CACHETAG} -t ${CI_REGISTRY_IMAGE}:${VERSION} -t ${CI_REGISTRY_IMAGE}:${CACHETAG} .
|
||||
- docker push ${CI_REGISTRY_IMAGE}:${VERSION}
|
||||
- docker push ${CI_REGISTRY_IMAGE}:${CACHETAG}
|
||||
tags:
|
||||
- apt
|
||||
- docker
|
||||
- armv7l
|
||||
only:
|
||||
- debian
|
||||
artifacts:
|
||||
paths:
|
||||
- build/*deb
|
||||
expire_in: 1 week
|
||||
|
||||
deploy:armv7l:
|
||||
stage: deploy
|
||||
dependencies:
|
||||
- build:armv7l
|
||||
script:
|
||||
- reprepro -b /apt includedeb $(awk -F"[)(]+" '/VERSION=/ {print $2}' /etc/os-release) build/${CI_PROJECT_NAME}_${VERSION}*.deb
|
||||
tags:
|
||||
- reprepro
|
||||
- docker
|
||||
|
|
|
@ -1,3 +0,0 @@
|
|||
[submodule "utils/mnet"]
|
||||
path = utils/mnet
|
||||
url = git://git.magickabbs.com/MagiNet
|
|
@ -0,0 +1,40 @@
|
|||
# NAME leenooks/magicka
|
||||
# VERSION 0.12-4
|
||||
|
||||
FROM debian:stretch-slim
|
||||
|
||||
MAINTAINER Deon George <deon@leenooks.net>
|
||||
|
||||
# Pre-requisites
|
||||
# + Base application requires unzip zip curl
|
||||
RUN apt-get update \
|
||||
&& apt-get install -yqq unzip zip curl \
|
||||
&& rm -rf /var/lib/apt/lists/* /tmp/*
|
||||
|
||||
# Set timezone to Melbourne
|
||||
RUN ln -sf /usr/share/zoneinfo/Australia/Melbourne /etc/localtime
|
||||
|
||||
# Add in Leenooks' apt repository
|
||||
RUN curl -s http://apt.leenooks.net/setup.sh | sh
|
||||
|
||||
RUN apt-get update \
|
||||
&& apt-get install -y --allow-unauthenticated magicka openssh-server binkd supervisor inotify-tools \
|
||||
&& apt-get -y autoremove \
|
||||
&& apt-get clean \
|
||||
&& rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* #3
|
||||
|
||||
ADD binkd.conf /opt/magicka/etc/
|
||||
ADD magimail.prefs /opt/magicka/etc/
|
||||
ADD ticproc.ini /opt/magicka/etc/magicka/
|
||||
ADD *.sh /opt/magicka/bin/
|
||||
RUN ln -sf magitoss.sh /opt/magicka/bin/magiscan.sh
|
||||
|
||||
WORKDIR /opt/magicka
|
||||
EXPOSE 22 23 80 24554
|
||||
|
||||
COPY init /sbin/init
|
||||
COPY supervisord.d /etc/supervisor/conf.d/
|
||||
|
||||
VOLUME [ "/opt/magicka/data" ]
|
||||
ENTRYPOINT [ "/sbin/init" ]
|
||||
CMD ["/usr/bin/supervisord", "-c", "/etc/supervisor/supervisord.conf", "-n"]
|
21
GNUmakefile
21
GNUmakefile
|
@ -1,21 +0,0 @@
|
|||
ifdef MUSL
|
||||
OS=linux-musl
|
||||
else
|
||||
OS=$(shell uname -s | tr '[A-Z]' '[a-z]' | sed 's/darwin/osx/')
|
||||
endif
|
||||
|
||||
all: magicka
|
||||
|
||||
.PHONY: magicka www clean cleanwww
|
||||
|
||||
magicka:
|
||||
cd src && $(MAKE) -f GNUmakefile.$(OS)
|
||||
|
||||
www:
|
||||
cd src && $(MAKE) -f GNUmakefile.$(OS) www
|
||||
|
||||
clean:
|
||||
cd src && $(MAKE) -f GNUmakefile.$(OS) clean
|
||||
|
||||
cleanwww:
|
||||
cd src && $(MAKE) -f GNUmakefile.$(OS) clean
|
|
@ -1,152 +0,0 @@
|
|||
ifdef PREFIX
|
||||
prefix := $(PREFIX)
|
||||
else
|
||||
prefix := /opt/magicka
|
||||
endif
|
||||
|
||||
exec_prefix := $(prefix)
|
||||
datarootdir = $(prefix)/share
|
||||
datadir = $(datarootdir)
|
||||
bindir = $(exec_prefix)/bin
|
||||
localstatedir = $(prefix)/var
|
||||
sysconfdir = $(prefix)/etc
|
||||
|
||||
user := magicka
|
||||
|
||||
all: magicka
|
||||
|
||||
.PHONY: magicka www clean cleanwww install
|
||||
|
||||
magicka:
|
||||
cd src && $(MAKE) -f GNUmakefile.debian MAGIEDIT_ANSI_PATH="$(datarootdir)/magicka/ansis/" MAGIEDIT_DRAFT_PATH="$(datarootdir)/magicka/ansis/"
|
||||
|
||||
www:
|
||||
cd src && $(MAKE) -f GNUmakefile.debian MAGIEDIT_ANSI_PATH="$(datarootdir)/magicka/ansis/" MAGIEDIT_DRAFT_PATH="$(datarootdir)/magicka/ansis/" www
|
||||
|
||||
clean:
|
||||
cd src && $(MAKE) -f GNUmakefile.debian clean
|
||||
|
||||
cleanwww:
|
||||
cd src && $(MAKE) -f GNUmakefile.debian clean
|
||||
|
||||
install:
|
||||
install -m755 -d ${DESTDIR}${bindir}
|
||||
install -m755 -d ${DESTDIR}${datarootdir}/doc/magicka
|
||||
install -m755 -d ${DESTDIR}${localstatedir}/magicka
|
||||
install -m755 -d ${DESTDIR}${sysconfdir}/magicka
|
||||
install -m755 -d ${DESTDIR}${datarootdir}/magicka
|
||||
install -m755 -d ${DESTDIR}${localstatedir}/magicka/logs
|
||||
install -m755 -d ${DESTDIR}${localstatedir}/magicka/msgs
|
||||
install -m755 -d ${DESTDIR}${localstatedir}/magicka/files/misc
|
||||
install -m755 -d ${DESTDIR}${datarootdir}/magicka/scripts/data
|
||||
install -m755 -d ${DESTDIR}${datarootdir}/magicka/ansis
|
||||
install -m755 -d ${DESTDIR}${datarootdir}/magicka/www/static/fonts
|
||||
install -m755 -d ${DESTDIR}${datarootdir}/magicka/menus
|
||||
|
||||
install -m755 magicka ${DESTDIR}${bindir}/magicka
|
||||
install -m755 utils/dosbox_shim/shim ${DESTDIR}${bindir}/magi_shim
|
||||
install -m755 utils/filecenter/filecenter ${DESTDIR}${bindir}/magi_filecenter
|
||||
install -m755 utils/magichat/magichat ${DESTDIR}${bindir}/magichat
|
||||
install -m755 utils/magiedit/magiedit ${DESTDIR}${bindir}/magiedit
|
||||
install -m755 utils/magiftpd/magiftpd ${DESTDIR}${bindir}/magiftpd
|
||||
install -m755 utils/magimail/bin/magiexport ${DESTDIR}${bindir}/magiexport
|
||||
install -m755 utils/magimail/bin/magigetnode ${DESTDIR}${bindir}/magigetnode
|
||||
install -m755 utils/magimail/bin/magilist ${DESTDIR}${bindir}/magilist
|
||||
install -m755 utils/magimail/bin/magilistout ${DESTDIR}${bindir}/magilistout
|
||||
install -m755 utils/magimail/bin/magimail ${DESTDIR}${bindir}/magimail
|
||||
install -m755 utils/magimail/bin/magimaint ${DESTDIR}${bindir}/magimaint
|
||||
install -m755 utils/magimail/bin/magistats ${DESTDIR}${bindir}/magistats
|
||||
install -m755 utils/magimail/bin/magiwrite ${DESTDIR}${bindir}/magiwrite
|
||||
install -m755 utils/massupload/massupload.pl ${DESTDIR}${bindir}/magi_massupload.pl
|
||||
install -m755 utils/mgpost/mgpost ${DESTDIR}${bindir}/mgpost
|
||||
install -m755 utils/nodelistp/nodelistp.pl ${DESTDIR}${bindir}/magi_nodelistp.pl
|
||||
install -m755 utils/reset_pass/reset_pass ${DESTDIR}${bindir}/magi_reset_pass
|
||||
install -m755 utils/ticproc/ticproc ${DESTDIR}${bindir}/magi_ticproc
|
||||
|
||||
install -m644 dist/config/bbs.ini ${DESTDIR}${sysconfdir}/magicka/bbs.ini
|
||||
sed -i "s@__CONFIGPREFIX__@${sysconfdir}/magicka@g" ${DESTDIR}${sysconfdir}/magicka/bbs.ini
|
||||
sed -i "s@__LOCALSTATEPREFIX__@${localstatedir}/magicka@g" ${DESTDIR}${sysconfdir}/magicka/bbs.ini
|
||||
sed -i "s@__SHAREPREFIX__@${datarootdir}/magicka@g" ${DESTDIR}${sysconfdir}/magicka/bbs.ini
|
||||
sed -i "s@__EXECPREFIX__@${bindir}@g" ${DESTDIR}${sysconfdir}/magicka/bbs.ini
|
||||
|
||||
install -m644 dist/config/archivers.ini ${DESTDIR}${sysconfdir}/magicka/archivers.ini
|
||||
install -m644 dist/config/doors.ini ${DESTDIR}${sysconfdir}/magicka/doors.ini
|
||||
install -m644 dist/config/protocols.ini ${DESTDIR}${sysconfdir}/magicka/protocols.ini
|
||||
install -m644 dist/config/s10.ini ${DESTDIR}${sysconfdir}/magicka/s10.ini
|
||||
|
||||
install -m644 dist/config/filesgen.ini ${DESTDIR}${sysconfdir}/magicka/filesgen.ini
|
||||
sed -i "s@__LOCALSTATEPREFIX__@$${localstatedir}/magicka@g" ${DESTDIR}${sysconfdir}/magicka/filesgen.ini
|
||||
|
||||
|
||||
install -m644 dist/config/happynet.ini ${DESTDIR}${sysconfdir}/magicka/happynet.ini
|
||||
sed -i "s@__LOCALSTATEPREFIX__@${localstatedir}/magicka@g" ${DESTDIR}${sysconfdir}/magicka/happynet.ini
|
||||
|
||||
install -m644 dist/config/localmail.ini ${DESTDIR}${sysconfdir}/magicka/localmail.ini
|
||||
sed -i "s@__LOCALSTATEPREFIX__@${localstatedir}/magicka@g" ${DESTDIR}${sysconfdir}/magicka/localmail.ini
|
||||
|
||||
install -m755 utils/magiedit/magiedit.sh ${DESTDIR}${bindir}/magiedit.sh
|
||||
sed -i "s@__LOCALSTATEPREFIX__@${localstatedir}/magicka@g" ${DESTDIR}${bindir}/magiedit.sh
|
||||
sed -i "s@__EXECPREFIX__@${bindir}@g" ${DESTDIR}${bindir}/magiedit.sh
|
||||
|
||||
install -m644 dist/magicka.strings ${DESTDIR}${datarootdir}/magicka/magicka.strings
|
||||
|
||||
install -m644 dist/scripts/doors.lua ${DESTDIR}${datarootdir}/magicka/scripts/doors.lua
|
||||
install -m644 dist/scripts/filemenu.lua ${DESTDIR}${datarootdir}/magicka/scripts/filemenu.lua
|
||||
install -m644 dist/scripts/login_stanza.lua ${DESTDIR}${datarootdir}/magicka/scripts/login_stanza.lua
|
||||
|
||||
sed -i "s@__SHAREPREFIX__@${datarootdir}/magicka@g" ${DESTDIR}${datarootdir}/magicka/scripts/login_stanza.lua
|
||||
|
||||
install -m644 dist/scripts/logoff.lua ${DESTDIR}${datarootdir}/magicka/scripts/logoff.lua
|
||||
install -m644 dist/scripts/logout_stanza.lua ${DESTDIR}${datarootdir}/magicka/scripts/logout_stanza.lua
|
||||
install -m644 dist/scripts/mailmenu.lua ${DESTDIR}${datarootdir}/magicka/scripts/mailmenu.lua
|
||||
install -m644 dist/scripts/mainmenu.lua ${DESTDIR}${datarootdir}/magicka/scripts/mainmenu.lua
|
||||
install -m644 dist/scripts/data/taglines.txt ${DESTDIR}${datarootdir}/magicka/scripts/data/taglines.txt
|
||||
|
||||
install -m644 dist/ansis/bulletin0.ans ${DESTDIR}${datarootdir}/magicka/ansis/bulletin0.ans
|
||||
install -m644 dist/ansis/bulletin1.ans ${DESTDIR}${datarootdir}/magicka/ansis/bulletin1.ans
|
||||
install -m644 dist/ansis/doors.ans ${DESTDIR}${datarootdir}/magicka/ansis/doors.ans
|
||||
install -m644 dist/ansis/filemenu.ans ${DESTDIR}${datarootdir}/magicka/ansis/filemenu.ans
|
||||
install -m644 dist/ansis/goodbye.ans ${DESTDIR}${datarootdir}/magicka/ansis/goodbye.ans
|
||||
install -m644 dist/ansis/issue.ans ${DESTDIR}${datarootdir}/magicka/ansis/issue.ans
|
||||
install -m644 dist/ansis/logoff.ans ${DESTDIR}${datarootdir}/magicka/ansis/logoff.ans
|
||||
install -m644 dist/ansis/mailmenu.ans ${DESTDIR}${datarootdir}/magicka/ansis/mailmenu.ans
|
||||
install -m644 dist/ansis/mainmenu.ans ${DESTDIR}${datarootdir}/magicka/ansis/mainmenu.ans
|
||||
install -m644 dist/ansis/newuser.ans ${DESTDIR}${datarootdir}/magicka/ansis/newuser.ans
|
||||
install -m644 utils/magiedit/magiedit.ans ${DESTDIR}${datarootdir}/magicka/ansis/magiedit.ans
|
||||
install -m644 utils/magiedit/magiquote.ans ${DESTDIR}${datarootdir}/magicka/ansis/magiquote.ans
|
||||
|
||||
install -m644 dist/www-bootstrap/401.tpl ${DESTDIR}${datarootdir}/magicka/www/401.tpl
|
||||
install -m644 dist/www-bootstrap/403.tpl ${DESTDIR}${datarootdir}/magicka/www/403.tpl
|
||||
install -m644 dist/www-bootstrap/404.tpl ${DESTDIR}${datarootdir}/magicka/www/404.tpl
|
||||
install -m644 dist/www-bootstrap/footer.tpl ${DESTDIR}${datarootdir}/magicka/www/footer.tpl
|
||||
install -m644 dist/www-bootstrap/header.tpl ${DESTDIR}${datarootdir}/magicka/www/header.tpl
|
||||
install -m644 dist/www-bootstrap/index.tpl ${DESTDIR}${datarootdir}/magicka/www/index.tpl
|
||||
install -m644 dist/www-bootstrap/mime.types ${DESTDIR}${datarootdir}/magicka/www/mime.types
|
||||
|
||||
install -m644 dist/www-bootstrap/static/delete.png ${DESTDIR}${datarootdir}/magicka/www/static/delete.png
|
||||
install -m644 dist/www-bootstrap/static/flag.png ${DESTDIR}${datarootdir}/magicka/www/static/flag.png
|
||||
install -m644 dist/www-bootstrap/static/header-m.png ${DESTDIR}${datarootdir}/magicka/www/static/header-m.png
|
||||
install -m644 dist/www-bootstrap/static/header.png ${DESTDIR}${datarootdir}/magicka/www/static/header.png
|
||||
install -m644 dist/www-bootstrap/static/newuser.png ${DESTDIR}${datarootdir}/magicka/www/static/newuser.png
|
||||
install -m644 dist/www-bootstrap/static/style.css ${DESTDIR}${datarootdir}/magicka/www/static/style.css
|
||||
install -m644 dist/www-bootstrap/static/style-mobile.css ${DESTDIR}${datarootdir}/magicka/www/static/style-mobile.css
|
||||
|
||||
install -m644 dist/www-bootstrap/static/fonts/LICENSE.TXT ${DESTDIR}${datarootdir}/magicka/www/static/fonts/LICENSE.TXT
|
||||
install -m644 dist/www-bootstrap/static/fonts/pxplus_ibm_vga8-webfont.svg ${DESTDIR}${datarootdir}/magicka/www/static/fonts/pxplus_ibm_vga8-webfont.svg
|
||||
install -m644 dist/www-bootstrap/static/fonts/pxplus_ibm_vga8-webfont.woff ${DESTDIR}${datarootdir}/magicka/www/static/fonts/pxplus_ibm_vga8-webfont.woff
|
||||
install -m644 dist/www-bootstrap/static/fonts/pxplus_ibm_vga8-webfont.woff2 ${DESTDIR}${datarootdir}/magicka/www/static/fonts/pxplus_ibm_vga8-webfont.woff2
|
||||
|
||||
install -m644 dist/menus/doors.mnu ${DESTDIR}${datarootdir}/magicka/menus/doors.mnu
|
||||
install -m644 dist/menus/main.mnu ${DESTDIR}${datarootdir}/magicka/menus/main.mnu
|
||||
install -m644 dist/menus/file.mnu ${DESTDIR}${datarootdir}/magicka/menus/file.mnu
|
||||
install -m644 dist/menus/logoff.mnu ${DESTDIR}${datarootdir}/magicka/menus/logoff.mnu
|
||||
install -m644 dist/menus/mail.mnu ${DESTDIR}${datarootdir}/magicka/menus/mail.mnu
|
||||
|
||||
echo "You should now create a user to run magicka"
|
||||
echo "and assuming that user is magicka:
|
||||
echo " "
|
||||
echo " chown -R magicka:magicka ${datarootdir}/magicka/scripts/data"
|
||||
echo " chown -R magicka:magicka ${localstatedir}/magicka"
|
||||
echo " "
|
||||
echo "Then configure ${sysconfdir}/magicka/bbs.ini to your liking"
|
||||
|
27
LICENSE.txt
27
LICENSE.txt
|
@ -1,27 +0,0 @@
|
|||
|
||||
MagickaBBS is distributed under the New BSD license:
|
||||
|
||||
Copyright (c) 2016, Andrew Pamment
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of Andrew Pamment nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software
|
||||
without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY ANDREW PAMMENT ''AS IS'' AND ANY
|
||||
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL ANDREW PAMMENT BE LIABLE FOR ANY
|
||||
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
50
README.md
50
README.md
|
@ -1,5 +1,49 @@
|
|||
# MagickaBBS
|
||||
# Magicka BBS (Bulletin Board Software)
|
||||
----
|
||||
## What is Magicka BBS?
|
||||
see [MagickaBBS](https://magickabbs.com)
|
||||
|
||||
A Bulletin Board System for UN*X like platforms.
|
||||
> MagickaBBS is a Bulletin Board System (BBS) for Linux, macOS, FreeBSD, NetBSD, OpenIndiana, DragonFlyBSD and OpenBSD
|
||||
|
||||
For documentation, see [http://wiki.magickabbs.com/](http://wiki.magickabbs.com/)
|
||||
> Magicka contains both Telnet & SSH servers, an FTP server and a HTTP server. It is able to run both native and DOS doors (via DosBox or Dosemu). It comes with an external full screen editor, a mail tosser/scanner and bluewave offline mail. It has internal ZModem, and works with external protocols like LRZSZ. Magicka is also easily configurable via ini files, and a configuration utility is in the works.
|
||||
|
||||
----
|
||||
## About this Docker Container
|
||||
This Docker Container represents a completed installation of MagickaBBS. It is ready to configure and personalise.
|
||||
|
||||
To use this container:
|
||||
|
||||
1. Docker pull it from my registry. (Actually you can skip this step, but its worth doing it anyway!)
|
||||
|
||||
docker pull registry.leenooks.net/bbs/magicka:0.12-alpha-x86_64 (armv7l is available too!)
|
||||
|
||||
2. Create a directory to hold your BBS data. (I use */srv/docker/magicka*).
|
||||
|
||||
mkdir -p /srv/magicka/data
|
||||
|
||||
3. Start the container.
|
||||
|
||||
docker run -d -v /srv/magicka/data:/opt/magicka/data -p 10022:2024 -p 10023:2023 -p 24554:24554 registry.leenooks.net/bbs/magicka:0.12-alpha-x86_64
|
||||
|
||||
Explanation of these parameters:
|
||||
|
||||
| Parameter | Value |
|
||||
| :- | :-- |
|
||||
| -d | Detached mode: run the container in the background and print the new container ID. |
|
||||
| --name= | Give your container a specific name. (optional) |
|
||||
| -p | Map host ports to container ports. (may be required, otherwise recommended) |
|
||||
| -v | Map a path on the host into the container (optional but recommended). |
|
||||
|
||||
(There are other useful parameters you can use, like --restart, etc. If you dont pass in a data volume for /opt/magicka/data, docker will create one and preserve it if you start subsequent containers a specific way (beyond the scope of this README - so its recommended you do this in first instance anyway.)
|
||||
|
||||
Remember your container ID *(your number will be different)*.
|
||||
|
||||
ca219a461376...
|
||||
|
||||
4. You can connect to your container and run any commands inside it.
|
||||
|
||||
docker exec -it ca219a461376 <COMMAND>
|
||||
|
||||
5. You can now start to play. If you externalised your telnet port, then you can telnet in.
|
||||
|
||||
You can also run this in a swarm (I do)!
|
||||
|
|
253
STRINGS.CHANGES
253
STRINGS.CHANGES
|
@ -1,253 +0,0 @@
|
|||
New / Changed Strings in dist/magicka.strings
|
||||
--------------------------------------------------------------
|
||||
If you are using your own custom strings file, you will need
|
||||
to add / modify the new string on the line specified. Be sure
|
||||
to remove the start and end quotation marks.
|
||||
|
||||
|
||||
Changes from v0.11-alpha -> v0.12-alpha
|
||||
--------------------------------------------------------------
|
||||
|
||||
LINE 127 MODIFIED
|
||||
OLDSTRING: "\e[2J\e[1;1H\e[1;37;44m[MSG#] Subject From To Date \r\n\e[0m"
|
||||
NEWSTRING: "\e[1;37;44m[MSG#] Subject From To Date \r\n\e[0m"
|
||||
|
||||
LINE 64 MODIFIED
|
||||
OLDSTRING: "\e[2J\e[1;1H\e[1;37;44m[MSG#] Subject From Date \r\n\e[0m"
|
||||
NEWSTRING: "\e[1;37;44m[MSG#] Subject From Date \r\n\e[0m"
|
||||
|
||||
Changes from v0.10-alpha -> v0.11-alpha
|
||||
--------------------------------------------------------------
|
||||
|
||||
LINE 287 NEW
|
||||
OLDSTRING: (NONE)
|
||||
NEWSTRING: "\e[1;30m[\e[1;34;44m%5d\e[1;30;40m]\e[1;31m!\e[1;37m%-24.24s \e[1;32m%-15.15s \e[1;33m%-15.15s \e[1;35m%02d:%02d %02d-%02d-%02d\e[K\e[0m\r\n"
|
||||
|
||||
LINE 288 NEW
|
||||
OLDSTRING: (NONE)
|
||||
NEWSTRING: "\e[1;30m[\e[1;34m%5d\e[1;30m]\e[1;31m!\e[1;37m%-24.24s \e[1;32m%-15.15s \e[1;33m%-15.15s \e[1;35m%02d:%02d %02d-%02d-%02d\e[K\e[0m\r\n"
|
||||
|
||||
LINE 111 MODIFIED
|
||||
OLDSTRING: "\e[1;32mAttribs : \e[1;37m%s\r\n"
|
||||
NEWSTRING: "\e[1;32mAttribs : \e[1;37m%s \e[1;31m%s\r\n"
|
||||
|
||||
LINE 289 NEW
|
||||
OLDSTRING: (NONE)
|
||||
NEWSTRING: "\e[2J\e[1;1H\e[1;32mFrom : \e[1;37m%s (@%d)\r\n"
|
||||
|
||||
LINE 290 NEW
|
||||
OLDSTRING: (NONE)
|
||||
NEWSTRING: "\e[2J\e[1;1H\e[1;32mFrom : \e[1;37m%s (%s)\r\n"
|
||||
|
||||
Changes from v0.9-alpha -> v0.10-alpha
|
||||
--------------------------------------------------------------
|
||||
|
||||
LINE: 275 NEW
|
||||
OLDSTRING: (NONE)
|
||||
NEWSTRING: "\r\n\e[1;31mError executing archiver.\r\n\e[0m"
|
||||
|
||||
LINE: 276 NEW
|
||||
OLDSTRING: (NONE)
|
||||
NEWSTRING: "\r\n\r\n\e[1;37m(\e[1;32mV\e[1;37m)iew or \e[1;37m(\e[1;32mU\e[1;37m)pdate Automessage or \e[1;37m(\e[1;31mQ\e[1;37m)uit: \e[0m"
|
||||
|
||||
LINE: 204 MODIFIED
|
||||
OLDSTRING: "\e[1;31mUser not found! Assuming new user...\e[0m\r\n\r\n"
|
||||
NEWSTRING: "\r\n\e[1;31mUser not found!\e[0m\r\n\r\n"
|
||||
|
||||
LINE: 277 NEW
|
||||
OLDSTRING: (NONE)
|
||||
NEWSTRING: "\r\nScan for new personal mail? (Y/N/S): "
|
||||
|
||||
LINE: 278 NEW
|
||||
OLDSTRING: (NONE)
|
||||
NEWSTRING: "\e[1;32mConference: \e[1;37m%d. %s\e[0m\r\n"
|
||||
|
||||
LINE: 279 NEW
|
||||
OLDSTRING: (NONE)
|
||||
NEWSTRING: "\e[1;32m Area: \e[1;37m%d. %s \e[1;33m(%d New Messages)\e[0m\r\n\r\n"
|
||||
|
||||
LINE: 280 NEW
|
||||
OLDSTRING: (NONE)
|
||||
NEWSTRING: "Read Now ? (Y / N): "
|
||||
|
||||
LINE: 5 MODIFIED
|
||||
OLDSTRING: "\e[1;37m%-16s \e[1;36m%-32s \e[1;32m%02d:%02d %02d-%02d-%02d\e[0m\r\n"
|
||||
NEWSTRING: "\e[1;37m%-16s \e[1;36m%-32s \e[1;32m%02d:%02d %02d-%02d-%02d \e[1;33m%c\e[0m\r\n"
|
||||
|
||||
LINE: 281 NEW
|
||||
OLDSTRING: (NONE)
|
||||
NEWSTRING: "\e[1;33mSystem Blog\e[0m\r\n"
|
||||
|
||||
LINE: 282 NEW
|
||||
OLDSTRING: (NONE)
|
||||
NEWSTRING: "\e[1;30m-------------------------------------------------------------------------------\e[0m\r\n"
|
||||
|
||||
LINE: 283 NEW
|
||||
OLDSTRING: (NONE)
|
||||
NEWSTRING: "\e[0mNo Entries...\r\n"
|
||||
|
||||
LINE: 284 NEW
|
||||
OLDSTRING: (NONE)
|
||||
NEWSTRING: "\e[1;37m%s (by \e[1;36m%s\e[1;37m)\r\n"
|
||||
|
||||
LINE: 285 NEW
|
||||
OLDSTRING: (NONE)
|
||||
NEWSTRING: "\e[1;35m%d:%02d%s %s, %s %d %d\r\n"
|
||||
|
||||
LINE: 286 NEW
|
||||
OLDSTRING: (NONE)
|
||||
NEWSTRING: "\r\n\r\n\e[1;37mEnter a title:\e[0m "
|
||||
|
||||
LINE 128 MODIFIED
|
||||
OLDSTRING: "\e[1;30m[\e[1;34m%4d\e[1;30m]\e[1;32m*\e[1;37m%-25.25s \e[1;32m%-15.15s \e[1;33m%-15.15s \e[1;35m%02d:%02d %02d-%02d-%02d\e[K\e[0m\r\n"
|
||||
NEWSTRING: "\e[1;30m[\e[1;34m%5d\e[1;30m]\e[1;32m*\e[1;37m%-24.24s \e[1;32m%-15.15s \e[1;33m%-15.15s \e[1;35m%02d:%02d %02d-%02d-%02d\e[K\e[0m\r\n"
|
||||
|
||||
LINE 129 MODIFIED
|
||||
OLDSTRING: "\e[1;30m[\e[1;34m%4d\e[1;30m] \e[1;37m%-25.25s \e[1;32m%-15.15s \e[1;33m%-15.15s \e[1;35m%02d:%02d %02d-%02d-%02d\e[K\e[0m\r\n"
|
||||
NEWSTRING: "\e[1;30m[\e[1;34m%5d\e[1;30m] \e[1;37m%-24.24s \e[1;32m%-15.15s \e[1;33m%-15.15s \e[1;35m%02d:%02d %02d-%02d-%02d\e[K\e[0m\r\n"
|
||||
|
||||
LINE 189 MODIFIED
|
||||
OLDSTRING: "\e[1;30m[\e[1;34;44m%4d\e[1;30;40m]\e[1;32m*\e[1;37m%-25.25s \e[1;32m%-15.15s \e[1;33m%-15.15s \e[1;35m%02d:%02d %02d-%02d-%02d\e[K\e[0m\r\n"
|
||||
NEWSTRING: "\e[1;30m[\e[1;34;44m%5d\e[1;30;40m]\e[1;32m*\e[1;37m%-24.24s \e[1;32m%-15.15s \e[1;33m%-15.15s \e[1;35m%02d:%02d %02d-%02d-%02d\e[K\e[0m\r\n"
|
||||
|
||||
LINE 190 MODIFIED
|
||||
OLDSTRING: "\e[1;30m[\e[1;34;44m%4d\e[1;30;40m] \e[1;37m%-25.25s \e[1;32m%-15.15s \e[1;33m%-15.15s \e[1;35m%02d:%02d %02d-%02d-%02d\e[K\e[0m\r\n"
|
||||
NEWSTRING: "\e[1;30m[\e[1;34;44m%5d\e[1;30;40m] \e[1;37m%-24.24s \e[1;32m%-15.15s \e[1;33m%-15.15s \e[1;35m%02d:%02d %02d-%02d-%02d\e[K\e[0m\r\n"
|
||||
|
||||
LINE 115 MODIFIED
|
||||
OLDSTRING: "\r\n\r\nReplying to: %s\r\n"
|
||||
NEWSTRING: "\r\n\r\n\e[1;32m To: \e[0m"
|
||||
|
||||
LINE 116 MODIFIED
|
||||
OLDSTRING: "Change Subject? (Y/N) "
|
||||
NEWSTRING: "\r\n\e[1;32mSubject: \e[0m"
|
||||
|
||||
Changes from v0.8-alpha -> v0.9-alpha
|
||||
--------------------------------------------------------------
|
||||
LINE: 255 NEW
|
||||
OLDSTRING: (NONE)
|
||||
NEWSTRING: "\r\n\e[1;37mSending file %s...\r\n"
|
||||
|
||||
LINE 256 NEW
|
||||
OLDSTRING: (NONE)
|
||||
NEWSTRING: "\r\n\e[1;34mFilename\e[1;30m: \e[1;37m%s\e[0m\r\n"
|
||||
|
||||
LINE 257 NEW
|
||||
OLDSTRING: (NONE)
|
||||
NEWSTRING: " \e[1;34mURL\e[1;30m: \e[1;37m%s\e[0m\r\n"
|
||||
|
||||
LINE 258 NEW
|
||||
OLDSTRING: (NONE)
|
||||
NEWSTRING: "\r\n\e[1;31mError creating URL!\e[0m\r\n"
|
||||
|
||||
LINE 259 NEW
|
||||
OLDSTRING: (NONE)
|
||||
NEWSTRING: "\e[1;33mSorry this BBS does not have the webserver enabled.\e[0m\r\n"
|
||||
|
||||
LINE 260 NEW
|
||||
OLDSTRING: (NONE)
|
||||
NEWSTRING: "\e[%d;1H\e[1;30;40m[\e[1;34;44m%4d\e[1;30;40m]\e[1;32m*\e[1;37m%s\e[K"
|
||||
|
||||
LINE 261 NEW
|
||||
OLDSTRING: (NONE)
|
||||
NEWSTRING: "\e[%d;1H\e[1;30;40m[\e[1;34m%4d\e[1;30;40m]\e[1;32m*\e[1;37m%s\e[K"
|
||||
|
||||
LINE 230 MODIFIED
|
||||
OLDSTRING: "\r\n\e[1;37mAre you sure you want to reset all messages in %s to unread? \e[0m"
|
||||
NEWSTRING: "\r\n\r\n\e[1;37mReset pointers to All (\e[1;33mR\e[1;37m)ead, All (\e[1;33mU\e[1;37m)nread? or Msg #: "
|
||||
|
||||
LINE 231 MODIFIED
|
||||
OLDSTRING: "\r\n\e[1;37mAre you sure you want to reset \e[1;31mall messages \e[1;37min all bases to unread? \e[0m"
|
||||
NEWSTRING: "\r\n\r\n\e[1;37mReset \e[1;31mALL\e[1;37m pointers in \e[1;31mALL \e[1;37mareas to (\e[1;33mR\e[1;37m)ead, (\e[1;33mU\e[1;37m)nread? \e[0m"
|
||||
|
||||
LINE 167 MODIFIED
|
||||
OLDSTRING: "\r\nWhat is your login name: "
|
||||
NEWSTRING: "\r\n\e[0mWhat is your login name: "
|
||||
|
||||
LINE 144 MODIFIED
|
||||
OLDSTRING: "\r\n\e[1;32mText Files Collection\r\n"
|
||||
NEWSTRING: "\e[1;37;44mChoose a Text file to view\e[K"
|
||||
|
||||
LINE 145 MODIFIED
|
||||
OLDSTRING: "\e[1;30m-------------------------------------------------------------------------------\e[0m\r\n"
|
||||
NEWSTRING: "\e[24;1H\e[1;37;44mUp / Down to Select, Enter to View, Q to Quit\e[K"
|
||||
|
||||
LINE 146 CLEARED
|
||||
OLDSTRING: "\e[1;30m[\e[1;34m%3d\e[1;30m] \e[1;37m%s\r\n"
|
||||
NEWSTRING: ""
|
||||
|
||||
LINE 147 CLEARED
|
||||
OLDSTRING: "\e[1;30m-------------------------------------------------------------------------------\e[0m\r\n"
|
||||
NEWSTRING: ""
|
||||
|
||||
LINE 148 CLEARED
|
||||
OLDSTRING: "Enter the number of a text file to display or Q to quit:"
|
||||
NEWSTRING: ""
|
||||
|
||||
LINE 124 MODIFIED
|
||||
OLDSTRING: "\r\nMailing to %d:%d/%d.%d\r\n"
|
||||
NEWSTRING: "\r\nMailing to %d:%d/%d.%d (%s)\r\n"
|
||||
|
||||
LINE 146 MODIFIED
|
||||
OLDSTRING: ""
|
||||
NEWSTRING: "\e[1;37;44mNodelist Browser\e[K"
|
||||
|
||||
LINE 147 MODIFIED
|
||||
OLDSTRING: ""
|
||||
NEWSTRING: "\e[24;1H\e[1;37;44mUp / Down to Select, Enter to View Details, Q to Quit\e[K"
|
||||
|
||||
LINE 148 MODIFIED
|
||||
OLDSTRING: ""
|
||||
NEWSTRING: "\e[%d;1H\e[1;30;40m[\e[1;34;44m%4d\e[1;30;40m] \e[1;37m%-15.15s %s\e[K"
|
||||
|
||||
LINE 262 NEW
|
||||
OLDSTRING: (NONE)
|
||||
NEWSTRING: "\e[%d;1H\e[1;30;40m[\e[1;34m%4d\e[1;30;40m] \e[1;37m%-15.15s %s\e[K"
|
||||
|
||||
LINE 263 NEW
|
||||
OLDSTRING: (NONE)
|
||||
NEWSTRING: "\e[1;37mNode Details for \e[1;33m%s\r\n"
|
||||
|
||||
LINE 264 NEW
|
||||
OLDSTRING: (NONE)
|
||||
NEWSTRING: "\e[1;30m-------------------------------------------------------------------------------\e[0m\r\n"
|
||||
|
||||
LINE 265 NEW
|
||||
OLDSTRING: (NONE)
|
||||
NEWSTRING: " \e[1;32mSystem Name : \e[1;37m%s\r\n"
|
||||
|
||||
LINE 266 NEW
|
||||
OLDSTRING: (NONE)
|
||||
NEWSTRING: " \e[1;32mSysop Name : \e[1;37m%s\r\n"
|
||||
|
||||
LINE 267 NEW
|
||||
OLDSTRING: (NONE)
|
||||
NEWSTRING: " \e[1;32mLocation : \e[1;37m%s\r\n"
|
||||
|
||||
LINE 268 NEW
|
||||
OLDSTRING: (NONE)
|
||||
NEWSTRING: "\e[1;30m-------------------------------------------------------------------------------\e[0m\r\n"
|
||||
|
||||
LINE 269 NEW
|
||||
OLDSTRING: (NONE)
|
||||
NEWSTRING: "\e[%d;1H\e[1;30;40m[\e[1;34m%3d\e[1;30;40m] \e[1;37m%-18.18s \e[1;33m%-16.16s \e[1;32m%-37.37s\e[K"
|
||||
|
||||
LINE 270 NEW
|
||||
OLDSTRING: (NONE)
|
||||
NEWSTRING: "\e[%d;1H\e[1;30;40m[\e[1;34;44m%3d\e[1;30;40m] \e[1;37m%-18.18s \e[1;33m%-16.16s \e[1;32m%-37.37s\e[K"
|
||||
|
||||
LINE 271 NEW
|
||||
OLDSTRING: (NONE)
|
||||
NEWSTRING: "\e[1;37;44mBBS Listing\e[K"
|
||||
|
||||
LINE 272 NEW
|
||||
OLDSTRING: (NONE)
|
||||
NEWSTRING: "\e[24;1H\e[1;37;44mUp / Down to Select, A to Add, D to Delete, Q to Quit\e[K"
|
||||
|
||||
LINE 273 NEW
|
||||
OLDSTRING: (NONE)
|
||||
NEWSTRING: "\e[8;28H\e[1;31;40mNo BBSes in the list!"
|
||||
|
||||
LINE 274 NEW
|
||||
OLDSTRING: (NONE)
|
||||
NEWSTRING: "\e[10;22H\e[1;37mPress \e[1;33mA \e[1;37m to Add yours or \e[1;33mQ \e[1;37mto Quit\e[0m"
|
|
@ -0,0 +1,53 @@
|
|||
# Number @ end is the root zone
|
||||
domain private /opt/magicka/data/ftn/out 10
|
||||
#domain fsxnet /opt/magicka/data/ftn/fsxnet 21
|
||||
|
||||
# Our Private address
|
||||
address 10:10/999@private
|
||||
|
||||
# Our FSXNet Address
|
||||
#address 21:21/999@fsxnet
|
||||
|
||||
sysname "My Magicka BBS"
|
||||
location "Virtualised in Docker"
|
||||
sysop "Docker Daemon"
|
||||
|
||||
nodeinfo 115200,TCP,BINKP
|
||||
try 10
|
||||
hold 600
|
||||
send-if-pwd
|
||||
|
||||
log /opt/magicka/data/var/magicka/logs/binkd.log
|
||||
loglevel 4
|
||||
conlog 4
|
||||
percents
|
||||
printq
|
||||
backresolv
|
||||
|
||||
inbound /opt/magicka/data/ftn/in_sec
|
||||
inbound-nonsecure /opt/magicka/data/ftn/in
|
||||
temp-inbound /opt/magicka/data/ftn/in_temp
|
||||
|
||||
minfree 2048
|
||||
minfree-nonsecure 2048
|
||||
|
||||
kill-dup-partial-files
|
||||
kill-old-partial-files 86400
|
||||
|
||||
prescan
|
||||
|
||||
# Private HUB
|
||||
node 10:1/0@private -md hub.private.ftn:24554 CHANGEME c
|
||||
# FSXNet HUB
|
||||
#node 21:1/100@fsxnet -md ipv4.agency.bbs.geek.nz:24556 LETMEIN c
|
||||
|
||||
# our listening port (default=24554)
|
||||
iport 24554
|
||||
|
||||
pid-file /opt/magicka/var/magicka/binkd.pid
|
||||
|
||||
exec "/opt/magicka/bin/magitoss.sh" *.[mwtfs][oehrau][0-9a-zA-Z] *.pkt
|
||||
exec "/opt/magicka/bin/ticproc.sh" *.tic *.TIC
|
||||
|
||||
# nuke old .bsy/.csy files after 24 hours
|
||||
kill-old-bsy 43200
|
|
@ -1,20 +0,0 @@
|
|||
magicka (0.12-4) UNRELEASED; urgency=low
|
||||
|
||||
* Upstream update
|
||||
|
||||
-- Deon George <deon@leenooks.net> Tue, 6 Nov 2018 21:30:00 +1100
|
||||
magicka (0.12-3) UNRELEASED; urgency=low
|
||||
|
||||
* Added utils
|
||||
|
||||
-- Deon George <deon@leenooks.net> Thu, 25 Oct 2018 15:50:00 +1100
|
||||
magicka (0.12-2) UNRELEASED; urgency=low
|
||||
|
||||
* Pull Commiet 03c8db5
|
||||
|
||||
-- Deon George <deon@leenooks.net> Thu, 25 Oct 2018 09:30:00 +1100
|
||||
magicka (0.12-1) UNRELEASED; urgency=low
|
||||
|
||||
* Initial release.
|
||||
|
||||
-- Deon George <deon@leenooks.net> Thu, 18 Oct 2018 22:30:20 +1100
|
|
@ -1 +0,0 @@
|
|||
10
|
|
@ -1,17 +0,0 @@
|
|||
Source: magicka
|
||||
Maintainer: Deon George <deon@leenooks.net>
|
||||
Build-Depends: debhelper (>= 8.0.0)
|
||||
Standards-Version: 3.9.8
|
||||
Section: bbs
|
||||
|
||||
Package: magicka
|
||||
Priority: optional
|
||||
Architecture: any
|
||||
Depends: ${shlibs:Depends}, ${misc:Depends}
|
||||
Description: This is the Magicka BBS
|
||||
Magicka BBS is a bulletin board system (BBS) for UN*X like systems. It is known
|
||||
to run on Linux, FreeBSD, NetBSD, OpenBSD, Dragonfly BSD, Openindiana(Illumos)
|
||||
and macOS.
|
||||
Magicka is meant to be a modern BBS system, using modern technologies, like
|
||||
Sqlite3, long filenames etc while still retaining the classic BBS feel. ANSI
|
||||
& Telnet, and good old ZModem.
|
|
@ -1,19 +0,0 @@
|
|||
--- a/deps/libb64-1.2/Makefile
|
||||
+++ b/deps/libb64-1.2/Makefile
|
||||
@@ -1,3 +1,5 @@
|
||||
+CFLAGS:=
|
||||
+
|
||||
all: all_src all_base64
|
||||
|
||||
all_src:
|
||||
--- a/GNUmakefile.debian
|
||||
+++ b/GNUmakefile.debian
|
||||
@@ -143,7 +143,7 @@
|
||||
install -m644 dist/menus/mail.mnu ${DESTDIR}${datarootdir}/magicka/menus/mail.mnu
|
||||
|
||||
echo "You should now create a user to run magicka"
|
||||
- echo "and assuming that user is magicka:
|
||||
+ echo "and assuming that user is magicka:"
|
||||
echo " "
|
||||
echo " chown -R magicka:magicka ${datarootdir}/magicka/scripts/data"
|
||||
echo " chown -R magicka:magicka ${localstatedir}/magicka"
|
|
@ -1 +0,0 @@
|
|||
makefile.patch
|
|
@ -1,44 +0,0 @@
|
|||
#!/usr/bin/make -f
|
||||
%:
|
||||
dh $@
|
||||
|
||||
override_dh_auto_clean:
|
||||
make clean || true
|
||||
rm -f deps/Xmodem/libzmodem.a
|
||||
rm -f deps/cdk-5.0-20161210/Makefile
|
||||
rm -f deps/cdk-5.0-20161210/cdk-config
|
||||
rm -f deps/cdk-5.0-20161210/cli/Makefile
|
||||
rm -f deps/cdk-5.0-20161210/config.log
|
||||
rm -f deps/cdk-5.0-20161210/config.status
|
||||
rm -f deps/cdk-5.0-20161210/demos/Makefile
|
||||
rm -f deps/cdk-5.0-20161210/examples/Makefile
|
||||
rm -f deps/cdk-5.0-20161210/include/cdk_config.h
|
||||
rm -f deps/cdk-5.0-20161210/include/cdk_version.h
|
||||
rm -f deps/jsmn/jsmn.o
|
||||
rm -f deps/jsmn/libjsmn.a
|
||||
rm -f deps/libb64-1.2/base64/depend
|
||||
rm -f deps/libb64-1.2/src/depend
|
||||
rm -f deps/libuuid/Makefile
|
||||
rm -f deps/libuuid/Makefile.in
|
||||
rm -f deps/libuuid/aclocal.m4
|
||||
rm -f deps/libuuid/config.h
|
||||
rm -f deps/libuuid/config.log
|
||||
rm -f deps/libuuid/config.status
|
||||
rm -f deps/libuuid/configure
|
||||
rm -f deps/libuuid/libtool
|
||||
rm -f deps/libuuid/ltmain.sh
|
||||
rm -f deps/libuuid/stamp-h1
|
||||
rm -f deps/libuuid/uuid.pc
|
||||
git checkout deps/libuuid/config.h.in
|
||||
|
||||
override_dh_auto_configure:
|
||||
echo "NOOP"
|
||||
|
||||
override_dh_autoreconf:
|
||||
echo "NOOP"
|
||||
|
||||
override_dh_auto_build:
|
||||
DESTDIR=$$(pwd)/debian/magicka/ make -f GNUmakefile.debian -j1 www
|
||||
|
||||
override_dh_auto_install:
|
||||
DESTDIR=$$(pwd)/debian/magicka/ make -f GNUmakefile.debian -j1 install
|
|
@ -1 +0,0 @@
|
|||
3.0 (quilt)
|
|
@ -1,19 +0,0 @@
|
|||
Copyright © 2001 Edward A. Falk
|
||||
|
||||
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 AUTHORS OR COPYRIGHT HOLDERS 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.
|
|
@ -1,42 +0,0 @@
|
|||
# $Id: Makefile,v 1.2 2001/10/25 23:56:29 efalk Exp $
|
||||
|
||||
INC = -I..
|
||||
|
||||
#OPT = -g
|
||||
OPT = -O
|
||||
|
||||
CFLAGS = $(OPT) $(INC) -DHAVE_STRDUP
|
||||
|
||||
AR = ar
|
||||
RANLIB = ranlib
|
||||
|
||||
HDRS = crctab.h seriallog.h xmodem.h zmodem.h
|
||||
|
||||
SRCS = crctab.c seriallog.c zmodem.c zmodemr.c zmodemsys.c zmodemt.c zmutil.c
|
||||
|
||||
OBJS = $(SRCS:.c=.o)
|
||||
|
||||
libzmodem.a: $(OBJS)
|
||||
-rm -f libzmodem.a
|
||||
$(AR) cru libzmodem.a $(OBJS)
|
||||
$(RANLIB) libzmodem.a
|
||||
|
||||
clean:
|
||||
rm -f *.o *.s *.i
|
||||
|
||||
clobber: clean
|
||||
rm -f *.a tags
|
||||
|
||||
tags: $(SRCS) $(HDRS)
|
||||
ctags *.[ch]
|
||||
|
||||
.SUFFIXES: .i .s
|
||||
|
||||
.c.i:
|
||||
$(CC) -E $(CFLAGS) $*.c > $@
|
||||
|
||||
.c.s:
|
||||
$(CC) -S $(CFLAGS) $*.c
|
||||
|
||||
depend:
|
||||
makedepend -- $(CFLAGS) -- $(SRCS)
|
|
@ -1,197 +0,0 @@
|
|||
#ifndef lint
|
||||
static const char rcsid[] = "$Id: checkcrc.c,v 1.2 2001/10/25 23:56:29 efalk Exp $" ;
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "crctab.h"
|
||||
|
||||
|
||||
static u_char msg0[] = {
|
||||
0x2a, 0x18, 0x43, 0x0a, 0x00, 0x00, 0x00, 0x00,
|
||||
0xbc, 0xef, 0x92, 0x8c,} ;
|
||||
static u_char msg0c[] = {
|
||||
0x2a, 0x18, 0x43, 0x0a, 0x00, 0x00, 0x00, 0x00,
|
||||
0xbc, 0xef, 0x92, 0x8c, 0x0b, 0xdf,} ;
|
||||
static u_char msg1[] = {
|
||||
0x0a, 0x23, 0x69, 0x6e,
|
||||
0x63, 0x6c, 0x75, 0x64, 0x65, 0x20, 0x3c, 0x73,
|
||||
0x79, 0x73, 0x2f, 0x74, 0x65, 0x72, 0x6d, 0x69,
|
||||
0x6f, 0x73, 0x2e, 0x68, 0x3e, 0x0a, 0x23, 0x69,
|
||||
0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x20, 0x22,
|
||||
0x78, 0x6d, 0x6f, 0x64, 0x65, 0x6d, 0x2e, 0x68,
|
||||
0x22, 0x0a, 0x0a, 0x0a, 0x69, 0x6e, 0x74, 0x0a,
|
||||
0x73, 0x65, 0x6e, 0x64, 0x43, 0x61, 0x6e, 0x63,
|
||||
0x65, 0x6c, 0x28, 0x29, 0x0a, 0x7b, 0x0a, 0x09,
|
||||
0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x73,
|
||||
0x65, 0x6e, 0x64, 0x46, 0x6c, 0x75, 0x73, 0x68,
|
||||
0x28, 0x43, 0x41, 0x4e, 0x29, 0x20, 0x7c, 0x7c,
|
||||
0x20, 0x73, 0x65, 0x6e, 0x64, 0x46, 0x6c, 0x75,
|
||||
0x73, 0x68, 0x28, 0x43, 0x41, 0x4e, 0x29, 0x20,
|
||||
0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x0a, 0x09, 0x2f,
|
||||
0x2a, 0x20, 0x73, 0x65, 0x6e, 0x64, 0x20, 0x6f,
|
||||
0x6e, 0x65, 0x20, 0x63, 0x68, 0x61, 0x72, 0x61,
|
||||
0x63, 0x74, 0x65, 0x72, 0x2c, 0x20, 0x72, 0x65,
|
||||
0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e, 0x6f, 0x6e,
|
||||
0x7a, 0x65, 0x72, 0x6f, 0x20, 0x6f, 0x6e, 0x20,
|
||||
0x65, 0x72, 0x72, 0x6f, 0x72, 0x20, 0x2a, 0x2f,
|
||||
0x0a, 0x69, 0x6e, 0x74, 0x0a, 0x73, 0x65, 0x6e,
|
||||
0x64, 0x46, 0x6c, 0x75, 0x73, 0x68, 0x28, 0x63,
|
||||
0x29, 0x0a, 0x09, 0x63, 0x68, 0x61, 0x72, 0x09,
|
||||
0x63, 0x20, 0x3b, 0x0a, 0x7b, 0x0a, 0x09, 0x2f,
|
||||
0x2a, 0x20, 0x66, 0x69, 0x72, 0x73, 0x74, 0x2c,
|
||||
0x20, 0x66, 0x6c, 0x75, 0x73, 0x68, 0x20, 0x69,
|
||||
0x6e, 0x70, 0x75, 0x74, 0x20, 0x70, 0x6f, 0x72,
|
||||
0x74, 0x20, 0x2a, 0x2f, 0x0a, 0x09, 0x2f, 0x2a,
|
||||
0x20, 0x54, 0x4f, 0x44, 0x4f, 0x3a, 0x20, 0x63,
|
||||
0x61, 0x6c, 0x6c, 0x65, 0x72, 0x20, 0x70, 0x72,
|
||||
0x6f, 0x76, 0x69, 0x64, 0x65, 0x20, 0x61, 0x20,
|
||||
0x77, 0x61, 0x79, 0x20, 0x18, 0x69, 0x4c, 0x5b,
|
||||
0x62, 0x0f,
|
||||
0x2a, 0x18, 0x43, 0x0a, 0x00, 0x00,
|
||||
0x00, 0x00, 0xbc, 0xef, 0x92, 0x8c, 0x0a, 0x23,
|
||||
0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x20,
|
||||
0x3c, 0x73, 0x79, 0x73, 0x2f, 0x74, 0x65, 0x72,
|
||||
0x6d, 0x69, 0x6f, 0x73, 0x2e, 0x68, 0x3e, 0x0a,
|
||||
0x23, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65,
|
||||
0x20, 0x22, 0x78, 0x6d, 0x6f, 0x64, 0x65, 0x6d,
|
||||
0x2e, 0x68, 0x22, 0x0a, 0x0a, 0x0a, 0x69, 0x6e,
|
||||
0x74, 0x0a, 0x73, 0x65, 0x6e, 0x64, 0x43, 0x61,
|
||||
0x6e, 0x63, 0x65, 0x6c, 0x28, 0x29, 0x0a, 0x7b,
|
||||
0x0a, 0x09, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e,
|
||||
0x20, 0x73, 0x65, 0x6e, 0x64, 0x46, 0x6c, 0x75,
|
||||
0x73, 0x68, 0x28, 0x43, 0x41, 0x4e, 0x29, 0x20,
|
||||
0x7c, 0x7c, 0x20, 0x73, 0x65, 0x6e, 0x64, 0x46,
|
||||
0x6c, 0x75, 0x73, 0x68, 0x28, 0x43, 0x41, 0x4e,
|
||||
0x29, 0x20, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x0a,
|
||||
0x09, 0x2f, 0x2a, 0x20, 0x73, 0x65, 0x6e, 0x64,
|
||||
0x20, 0x6f, 0x6e, 0x65, 0x20, 0x63, 0x68, 0x61,
|
||||
0x72, 0x61, 0x63, 0x74, 0x65, 0x72, 0x2c, 0x20,
|
||||
0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x6e,
|
||||
0x6f, 0x6e, 0x7a, 0x65, 0x72, 0x6f, 0x20, 0x6f,
|
||||
0x6e, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x20,
|
||||
0x2a, 0x2f, 0x0a, 0x69, 0x6e, 0x74, 0x0a, 0x73,
|
||||
0x65, 0x6e, 0x64, 0x46, 0x6c, 0x75, 0x73, 0x68,
|
||||
0x28, 0x63, 0x29, 0x0a, 0x09, 0x63, 0x68, 0x61,
|
||||
0x72, 0x09, 0x63, 0x20, 0x3b, 0x0a, 0x7b, 0x0a,
|
||||
0x09, 0x2f, 0x2a, 0x20, 0x66, 0x69, 0x72, 0x73,
|
||||
0x74, 0x2c, 0x20, 0x66, 0x6c, 0x75, 0x73, 0x68,
|
||||
0x20, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x20, 0x70,
|
||||
0x6f, 0x72, 0x74, 0x20, 0x2a, 0x2f, 0x0a, 0x09,
|
||||
0x2f, 0x2a, 0x20, 0x54, 0x4f, 0x44, 0x4f, 0x3a,
|
||||
0x20, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x20,
|
||||
0x70, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x20,
|
||||
0x61, 0x20, 0x77, 0x61, 0x79, 0x20, 0x18, 0x6b,
|
||||
0x60, 0x3a, 0x6c, 0xe1,
|
||||
} ;
|
||||
static u_char msg2[] = {1} ;
|
||||
|
||||
#ifdef COMMENT
|
||||
#define updcrc(cp, crc) ( crctab[((crc >> 8) & 255)] ^ (crc << 8) ^ cp)
|
||||
#define updcrc(cp, crc) ( crctab[((crc>>8)^cp) & 255] ^ (crc<<8) )
|
||||
#endif /* COMMENT */
|
||||
|
||||
static int addcrc(int data, int crc) ;
|
||||
|
||||
|
||||
main()
|
||||
{
|
||||
u_short crc16 ;
|
||||
u_long crc32 ;
|
||||
int i,j ;
|
||||
u_long k ;
|
||||
u_char *msg = msg0 ;
|
||||
int len = sizeof(msg0) ;
|
||||
|
||||
|
||||
/* crc16 of message */
|
||||
|
||||
crc16 = 0 ;
|
||||
crc32 = 0xffffffff ;
|
||||
|
||||
for(i=0; i<len; ++i)
|
||||
{
|
||||
crc16 = addcrc(msg[i], crc16) ;
|
||||
}
|
||||
|
||||
printf("crc16=%4.4hx, ~crc16=%4.4hx\n", crc16, ~crc16&0xffff) ;
|
||||
|
||||
crc16 = addcrc(0, crc16) ;
|
||||
crc16 = addcrc(0, crc16) ;
|
||||
|
||||
printf("crc16=%4.4hx, ~crc16=%4.4hx\n", crc16, ~crc16&0xffff) ;
|
||||
|
||||
|
||||
/* crc of reception */
|
||||
|
||||
j = crc16 ;
|
||||
crc16 = 0 ;
|
||||
crc32 = 0xffffffff ;
|
||||
|
||||
for(i=0; i<len; ++i)
|
||||
{
|
||||
crc16 = addcrc(msg[i], crc16) ;
|
||||
}
|
||||
|
||||
printf("crc16=%4.4hx, ~crc16=%4.4hx\n", crc16, ~crc16&0xffff) ;
|
||||
|
||||
crc16 = addcrc(j>>8, crc16) ;
|
||||
crc16 = addcrc(j&0xff, crc16) ;
|
||||
|
||||
printf("crc16=%4.4hx, ~crc16=%4.4hx\n", crc16, ~crc16&0xffff) ;
|
||||
|
||||
|
||||
|
||||
#ifdef COMMENT
|
||||
crc16 = 0 ;
|
||||
crc32 = 0xffffffff ;
|
||||
|
||||
for(i=0; i<len; ++i)
|
||||
{
|
||||
crc16 = updcrc(msg[i], crc16) ;
|
||||
crc32 = UPDC32(msg[i], crc32) ;
|
||||
printf("%4.4x\n", crc16) ;
|
||||
}
|
||||
|
||||
printf("crc16=%4.4hx, ~crc16=%4.4hx\n", crc16, ~crc16&0xffff) ;
|
||||
printf("crc32=%8.8x, ~crc=%8.8x\n", crc32,~crc32) ;
|
||||
|
||||
|
||||
#ifdef COMMENT
|
||||
printf("\n") ;
|
||||
printf("%2.2x\n", crc16&0xff) ;
|
||||
printf("%2.2x\n", crc16>>8) ;
|
||||
#endif /* COMMENT */
|
||||
|
||||
i = crc16 ;
|
||||
crc16 = updcrc(i&0xff, crc16) ;
|
||||
crc16 = updcrc(i>>8, crc16) ;
|
||||
|
||||
k = ~crc32 ;
|
||||
crc32 = updcrc(k&0xff, crc32) ;
|
||||
crc32 = updcrc((k>>8)&0xff, crc32) ;
|
||||
crc32 = updcrc((k>>16)&0xff, crc32) ;
|
||||
crc32 = updcrc((k>>24)&0xff, crc32) ;
|
||||
|
||||
printf("crc16=%4.4hx, ~crc16=%4.4hx\n", crc16, ~crc16&0xffff) ;
|
||||
printf("crc32=%8.8x, ~crc=%8.8x\n", crc32,~crc32) ;
|
||||
#endif /* COMMENT */
|
||||
|
||||
exit(0) ;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
addcrc(int data, int crc)
|
||||
{
|
||||
int j ;
|
||||
crc ^= (unsigned short) data<<8;
|
||||
for(j=0; j<8; ++j) {
|
||||
if( crc & 0x8000 )
|
||||
crc = (crc<<1) ^ 0x1021;
|
||||
else
|
||||
crc <<= 1 ;
|
||||
}
|
||||
return crc & 0xffff ;
|
||||
}
|
|
@ -1,182 +0,0 @@
|
|||
#ifndef lint
|
||||
static const char rcsid[] = "$Id: crc.c,v 1.2 2001/10/25 23:56:29 efalk Exp $" ;
|
||||
#endif
|
||||
|
||||
/*% cc -O -K -dos % -o crc.exe
|
||||
*/
|
||||
|
||||
/*
|
||||
* Crc - 32 BIT ANSI X3.66 CRC checksum files
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#define OK 0
|
||||
#define ERROR (-1)
|
||||
#define LINT_ARGS
|
||||
|
||||
/**********************************************************************\
|
||||
|* *|
|
||||
|* Demonstration program to compute the 32-bit CRC used as the frame *|
|
||||
|* check sequence in ADCCP (ANSI X3.66, also known as FIPS PUB 71 *|
|
||||
|* and FED-STD-1003, the U.S. versions of CCITT's X.25 link-level *|
|
||||
|* protocol). The 32-bit FCS was added via the Federal Register, *|
|
||||
|* 1 June 1982, p.23798. I presume but don't know for certain that *|
|
||||
|* this polynomial is or will be included in CCITT V.41, which *|
|
||||
|* defines the 16-bit CRC (often called CRC-CCITT) polynomial. FIPS *|
|
||||
|* PUB 78 says that the 32-bit FCS reduces otherwise undetected *|
|
||||
|* errors by a factor of 10^-5 over 16-bit FCS. *|
|
||||
|* *|
|
||||
\**********************************************************************/
|
||||
|
||||
/* Need an unsigned type capable of holding 32 bits; */
|
||||
typedef unsigned long int UNS_32_BITS;
|
||||
|
||||
/*
|
||||
* Copyright (C) 1986 Gary S. Brown. You may use this program, or
|
||||
* code or tables extracted from it, as desired without restriction.
|
||||
*/
|
||||
/* First, the polynomial itself and its table of feedback terms. The */
|
||||
/* polynomial is */
|
||||
/* X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0 */
|
||||
/* Note that we take it "backwards" and put the highest-order term in */
|
||||
/* the lowest-order bit. The X^32 term is "implied"; the LSB is the */
|
||||
/* X^31 term, etc. The X^0 term (usually shown as "+1") results in */
|
||||
/* the MSB being 1. */
|
||||
|
||||
/* Note that the usual hardware shift register implementation, which */
|
||||
/* is what we're using (we're merely optimizing it by doing eight-bit */
|
||||
/* chunks at a time) shifts bits into the lowest-order term. In our */
|
||||
/* implementation, that means shifting towards the right. Why do we */
|
||||
/* do it this way? Because the calculated CRC must be transmitted in */
|
||||
/* order from highest-order term to lowest-order term. UARTs transmit */
|
||||
/* characters in order from LSB to MSB. By storing the CRC this way, */
|
||||
/* we hand it to the UART in the order low-byte to high-byte; the UART */
|
||||
/* sends each low-bit to hight-bit; and the result is transmission bit */
|
||||
/* by bit from highest- to lowest-order term without requiring any bit */
|
||||
/* shuffling on our part. Reception works similarly. */
|
||||
|
||||
/* The feedback terms table consists of 256, 32-bit entries. Notes: */
|
||||
/* */
|
||||
/* 1. The table can be generated at runtime if desired; code to do so */
|
||||
/* is shown later. It might not be obvious, but the feedback */
|
||||
/* terms simply represent the results of eight shift/xor opera- */
|
||||
/* tions for all combinations of data and CRC register values. */
|
||||
/* */
|
||||
/* 2. The CRC accumulation logic is the same for all CRC polynomials, */
|
||||
/* be they sixteen or thirty-two bits wide. You simply choose the */
|
||||
/* appropriate table. Alternatively, because the table can be */
|
||||
/* generated at runtime, you can start by generating the table for */
|
||||
/* the polynomial in question and use exactly the same "updcrc", */
|
||||
/* if your application needn't simultaneously handle two CRC */
|
||||
/* polynomials. (Note, however, that XMODEM is strange.) */
|
||||
/* */
|
||||
/* 3. For 16-bit CRCs, the table entries need be only 16 bits wide; */
|
||||
/* of course, 32-bit entries work OK if the high 16 bits are zero. */
|
||||
/* */
|
||||
/* 4. The values must be right-shifted by eight bits by the "updcrc" */
|
||||
/* logic; the shift must be unsigned (bring in zeroes). On some */
|
||||
/* hardware you could probably optimize the shift in assembler by */
|
||||
/* using byte-swap instructions. */
|
||||
|
||||
static UNS_32_BITS crc_32_tab[] = { /* CRC polynomial 0xedb88320 */
|
||||
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
|
||||
0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
|
||||
0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
|
||||
0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
|
||||
0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
|
||||
0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
|
||||
0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
|
||||
0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
|
||||
0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
|
||||
0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
|
||||
0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
|
||||
0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
|
||||
0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
|
||||
0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
|
||||
0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
|
||||
0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
|
||||
0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
|
||||
0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
|
||||
0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
|
||||
0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
|
||||
0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
|
||||
0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
|
||||
0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
|
||||
0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
|
||||
0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
|
||||
0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
|
||||
0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
|
||||
0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
|
||||
0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
|
||||
0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
|
||||
0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
|
||||
0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
|
||||
};
|
||||
|
||||
#define UPDC32(octet, crc) (crc_32_tab[((crc) ^ (octet)) & 0xff] ^ ((crc) >> 8))
|
||||
|
||||
int Block = 0; /* Pad file with 032's to multiple of Block */
|
||||
|
||||
main(argc, argv)
|
||||
char **argv;
|
||||
{
|
||||
register errors = 0;
|
||||
|
||||
if (! strcmp(argv[1], "-x")) {
|
||||
Block = 128; --argc; ++argv;
|
||||
}
|
||||
if (! strcmp(argv[1], "-k")) {
|
||||
Block = 1024; --argc; ++argv;
|
||||
}
|
||||
while( --argc > 0)
|
||||
errors |= crc32file( *++argv);
|
||||
exit(errors != 0);
|
||||
}
|
||||
|
||||
crc32file(name)
|
||||
char *name;
|
||||
{
|
||||
register FILE *fin;
|
||||
register unsigned long oldcrc32;
|
||||
register unsigned long crc32;
|
||||
register unsigned long oldcrc;
|
||||
register c;
|
||||
register long charcnt;
|
||||
register long l;
|
||||
|
||||
oldcrc32 = 0xFFFFFFFF; charcnt = 0;
|
||||
#ifdef M_I86SM
|
||||
if ((fin=fopen(name, "rb"))==NULL)
|
||||
#else
|
||||
if ((fin=fopen(name, "r"))==NULL)
|
||||
#endif
|
||||
{
|
||||
perror(name);
|
||||
return ERROR;
|
||||
}
|
||||
while ((c=getc(fin))!=EOF) {
|
||||
++charcnt;
|
||||
oldcrc32 = UPDC32(c, oldcrc32);
|
||||
}
|
||||
|
||||
if (ferror(fin)) {
|
||||
perror(name);
|
||||
fclose(fin); return ERROR;
|
||||
}
|
||||
else {
|
||||
if (Block) {
|
||||
for (l = charcnt; l % Block; ++l)
|
||||
oldcrc32 = UPDC32(032, oldcrc32);
|
||||
}
|
||||
crc32 = oldcrc32; oldcrc = oldcrc32 = ~oldcrc32;
|
||||
|
||||
printf("%08lX %7ld ", oldcrc, charcnt);
|
||||
if (Block == 128)
|
||||
printf("%5ld+%3ld ", charcnt/Block, charcnt%Block);
|
||||
if (Block == 1024)
|
||||
printf("%5ld+%4ld ", charcnt/Block, charcnt%Block);
|
||||
printf(" %s\n", name);
|
||||
}
|
||||
|
||||
fclose(fin); return OK;
|
||||
}
|
||||
|
|
@ -1,154 +0,0 @@
|
|||
#ifndef lint
|
||||
static const char rcsid[] = "$Id: crctab.c,v 1.2 2001/10/25 23:56:29 efalk Exp $" ;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Crc calculation stuff
|
||||
*/
|
||||
|
||||
/* crctab calculated by Mark G. Mendel, Network Systems Corporation */
|
||||
unsigned short crctab[256] = {
|
||||
0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
|
||||
0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,
|
||||
0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6,
|
||||
0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de,
|
||||
0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485,
|
||||
0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d,
|
||||
0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4,
|
||||
0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc,
|
||||
0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823,
|
||||
0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b,
|
||||
0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12,
|
||||
0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a,
|
||||
0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41,
|
||||
0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49,
|
||||
0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70,
|
||||
0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78,
|
||||
0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f,
|
||||
0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067,
|
||||
0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e,
|
||||
0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256,
|
||||
0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d,
|
||||
0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
|
||||
0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c,
|
||||
0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634,
|
||||
0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab,
|
||||
0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3,
|
||||
0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a,
|
||||
0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92,
|
||||
0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9,
|
||||
0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1,
|
||||
0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8,
|
||||
0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0
|
||||
};
|
||||
|
||||
/*
|
||||
* updcrc macro derived from article Copyright (C) 1986 Stephen Satchell.
|
||||
* NOTE: First argument must be in range 0 to 255.
|
||||
* Second argument is referenced twice.
|
||||
*
|
||||
* Programmers may incorporate any or all code into their programs,
|
||||
* giving proper credit within the source. Publication of the
|
||||
* source routines is permitted so long as proper credit is given
|
||||
* to Stephen Satchell, Satchell Evaluations and Chuck Forsberg,
|
||||
* Omen Technology.
|
||||
*/
|
||||
|
||||
#define updcrc(cp, crc) ( crctab[((crc >> 8) & 255)] ^ (crc << 8) ^ cp)
|
||||
|
||||
/*
|
||||
* Copyright (C) 1986 Gary S. Brown. You may use this program, or
|
||||
* code or tables extracted from it, as desired without restriction.
|
||||
*/
|
||||
|
||||
/* First, the polynomial itself and its table of feedback terms. The */
|
||||
/* polynomial is */
|
||||
/* X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0 */
|
||||
/* Note that we take it "backwards" and put the highest-order term in */
|
||||
/* the lowest-order bit. The X^32 term is "implied"; the LSB is the */
|
||||
/* X^31 term, etc. The X^0 term (usually shown as "+1") results in */
|
||||
/* the MSB being 1. */
|
||||
|
||||
/* Note that the usual hardware shift register implementation, which */
|
||||
/* is what we're using (we're merely optimizing it by doing eight-bit */
|
||||
/* chunks at a time) shifts bits into the lowest-order term. In our */
|
||||
/* implementation, that means shifting towards the right. Why do we */
|
||||
/* do it this way? Because the calculated CRC must be transmitted in */
|
||||
/* order from highest-order term to lowest-order term. UARTs transmit */
|
||||
/* characters in order from LSB to MSB. By storing the CRC this way, */
|
||||
/* we hand it to the UART in the order low-byte to high-byte; the UART */
|
||||
/* sends each low-bit to hight-bit; and the result is transmission bit */
|
||||
/* by bit from highest- to lowest-order term without requiring any bit */
|
||||
/* shuffling on our part. Reception works similarly. */
|
||||
|
||||
/* The feedback terms table consists of 256, 32-bit entries. Notes: */
|
||||
/* */
|
||||
/* The table can be generated at runtime if desired; code to do so */
|
||||
/* is shown later. It might not be obvious, but the feedback */
|
||||
/* terms simply represent the results of eight shift/xor opera- */
|
||||
/* tions for all combinations of data and CRC register values. */
|
||||
/* */
|
||||
/* The values must be right-shifted by eight bits by the "updcrc" */
|
||||
/* logic; the shift must be unsigned (bring in zeroes). On some */
|
||||
/* hardware you could probably optimize the shift in assembler by */
|
||||
/* using byte-swap instructions. */
|
||||
|
||||
unsigned long cr3tab[] = { /* CRC polynomial 0xedb88320 */
|
||||
0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f,
|
||||
0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
|
||||
0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, 0x1db71064, 0x6ab020f2,
|
||||
0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
|
||||
0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
|
||||
0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
|
||||
0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, 0x35b5a8fa, 0x42b2986c,
|
||||
0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
|
||||
0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423,
|
||||
0xcfba9599, 0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
|
||||
0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190, 0x01db7106,
|
||||
0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
|
||||
0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d,
|
||||
0x91646c97, 0xe6635c01, 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
|
||||
0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
|
||||
0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
|
||||
0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7,
|
||||
0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
|
||||
0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa,
|
||||
0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
|
||||
0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81,
|
||||
0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
|
||||
0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, 0xe3630b12, 0x94643b84,
|
||||
0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
|
||||
0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
|
||||
0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
|
||||
0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, 0xd6d6a3e8, 0xa1d1937e,
|
||||
0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
|
||||
0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55,
|
||||
0x316e8eef, 0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
|
||||
0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe, 0xb2bd0b28,
|
||||
0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
|
||||
0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f,
|
||||
0x72076785, 0x05005713, 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
|
||||
0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
|
||||
0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
|
||||
0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69,
|
||||
0x616bffd3, 0x166ccf45, 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
|
||||
0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc,
|
||||
0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
|
||||
0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693,
|
||||
0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
|
||||
0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d };
|
||||
|
||||
#ifdef NFGM
|
||||
long
|
||||
UPDC32(b, c)
|
||||
long c;
|
||||
{
|
||||
return (cr3tab[((int)c ^ b) & 0xff] ^ ((c >> 8) & 0x00FFFFFF));
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#define UPDC32(b, c) (cr3tab[((int)c ^ b) & 0xff] ^ ((c >> 8) & 0x00FFFFFF))
|
||||
#endif
|
||||
|
||||
/* End of crctab.c */
|
|
@ -1,13 +0,0 @@
|
|||
/* @(#)crctab.h 1.2 96/09/13 */
|
||||
|
||||
/*
|
||||
* Crc calculation stuff. See crctab.c
|
||||
*/
|
||||
|
||||
extern unsigned short crctab[256] ;
|
||||
|
||||
#define updcrc(cp, crc) ( crctab[((crc >> 8) & 255)] ^ (crc << 8) ^ cp)
|
||||
|
||||
extern unsigned long cr3tab[] ;
|
||||
|
||||
#define UPDC32(b, c) (cr3tab[((int)c ^ b) & 0xff] ^ ((c >> 8) & 0x00FFFFFF))
|
|
@ -1,913 +0,0 @@
|
|||
#ifndef lint
|
||||
static const char rcsid[] = "$Id: main.c,v 1.1.1.1 2001/03/08 00:01:48 efalk Exp $" ;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Copyright (c) 1995 by Edward A. Falk
|
||||
*/
|
||||
|
||||
|
||||
/**********
|
||||
*
|
||||
*
|
||||
* @ @ @@@ @@@ @ @
|
||||
* @@ @@ @ @ @ @@ @
|
||||
* @ @ @ @@@@@ @ @ @ @
|
||||
* @ @ @ @ @ @ @ @@
|
||||
* @ @ @ @ @ @@@ @ @
|
||||
*
|
||||
* MAIN - demonstration zmodem program
|
||||
*
|
||||
* This program implements the x,y,z-modem protocols, using the
|
||||
* zmodem library.
|
||||
*
|
||||
* Edward A. Falk
|
||||
*
|
||||
* Jan, 1995
|
||||
*
|
||||
*
|
||||
*
|
||||
**********/
|
||||
|
||||
static char usage [] =
|
||||
"usage: zmodem -r [options]\n\
|
||||
zmodem -s [options] file [file ...]\n\
|
||||
-r receive files\n\
|
||||
-s send files\n\
|
||||
- file allows you to transmit files with '-' in their names\n\
|
||||
-v verbose, more v's increase messages.\n\
|
||||
-l /dev/ttyX use specified serial port instead of /dev/tty\n\
|
||||
-b baud set baud rate\n\
|
||||
-x file use xmodem, specify filename\n\
|
||||
-y use ymodem\n\
|
||||
-k use 1k, packets (ymodem, xmodem)\n\
|
||||
-win nn set sliding window to nn bytes (send)\n\
|
||||
-buf nn set input buffer size to nn bytes (receive)\n\
|
||||
-L nn set packet length\n\
|
||||
-e escape control characters\n\
|
||||
-a ascii text\n\
|
||||
-i image (binary data)\n\
|
||||
-resume continue an interrupted transfer\n\
|
||||
-new transfer only if newer\n\
|
||||
-newl transfer only if newer or longer\n\
|
||||
-diff transfer only if dates or lengths differ\n\
|
||||
-crc transfer only if length or crc different\n\
|
||||
-apnd append to existing file\n\
|
||||
-clob force overwrite of existing files\n\
|
||||
-prot do not overwrite existing files\n\
|
||||
-chng change filename if destination exists\n\
|
||||
-noloc do not transfer unless destination exists\n\
|
||||
-[hq] this list\n" ;
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
/****
|
||||
*
|
||||
* Constants, typedefs, externals, globals, statics, macros, block data
|
||||
*
|
||||
****/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
#include <signal.h>
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/termios.h>
|
||||
#include <sys/param.h>
|
||||
|
||||
#include "zmodem.h"
|
||||
#include "seriallog.h"
|
||||
|
||||
extern int errno ;
|
||||
extern char *getenv() ;
|
||||
|
||||
|
||||
/* compile-time parameters */
|
||||
|
||||
#define ESCCTRL 0 /* control characters need to be escaped */
|
||||
|
||||
#if !defined(CRTSCTS) && defined(CNEW_RTSCTS)
|
||||
#define CRTSCTS CNEW_RTSCTS
|
||||
#endif
|
||||
|
||||
static int baud = 0 ; /* requested baud rate */
|
||||
static char *line = NULL ; /* requested serial line */
|
||||
static int verbose = 0 ;
|
||||
static int send = 0 ; /* send files */
|
||||
static int receive = 0 ; /* receive */
|
||||
static int xmodem = 0 ; /* use xmodem */
|
||||
static int ymodem = 0 ; /* use ymodem */
|
||||
static int escCtrl = ESCCTRL ;
|
||||
static int ascii = 0 ; /* translate line endings */
|
||||
static int binary = 0 ; /* don't translate line endings */
|
||||
static int resume = 0 ; /* resume interrupted transfers */
|
||||
static int xferType = 0 ; /* new,newl,diff,crc, etc. */
|
||||
static int noloc = 0 ;
|
||||
static int doCancel = 0 ;
|
||||
static int doLogging = 0 ;
|
||||
|
||||
static int Corrupt = 0 ; /* deliberately corrupt data */
|
||||
|
||||
static int fileErrs ; /* used to track errors per file */
|
||||
static int fileSent ; /* track amount sent */
|
||||
|
||||
static ZModem info ;
|
||||
|
||||
static int begun = 0 ;
|
||||
static struct termios old_settings, new_settings ;
|
||||
|
||||
static int FinishXmit(ZModem *info) ;
|
||||
static int DoReceive(ZModem *info) ;
|
||||
static int InitXmit(ZModem *info) ;
|
||||
static int XmitFile(char *filename, int f0, int f1, ZModem *info) ;
|
||||
static void SendFile() ;
|
||||
static void RcvFiles() ;
|
||||
static void RcvXmodem() ;
|
||||
static int getBaud() ;
|
||||
static void resetCom() ;
|
||||
static char *basename(char *name) ;
|
||||
|
||||
#ifdef SVr4
|
||||
static void sighandle(int) ;
|
||||
#else
|
||||
static void sighandle() ;
|
||||
#endif
|
||||
|
||||
extern FILE *SerialLogFile ;
|
||||
extern FILE *zmodemlogfile ;
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
char *progname ;
|
||||
|
||||
#ifdef COMMENT
|
||||
printf("%d\n", getpid()) ;
|
||||
#endif /* COMMENT */
|
||||
|
||||
info.ifd = info.ofd = -1 ;
|
||||
info.zrinitflags = 0 ;
|
||||
info.zsinitflags = 0 ;
|
||||
info.attn = NULL ;
|
||||
info.packetsize = 0 ;
|
||||
info.windowsize = 0 ;
|
||||
info.bufsize = 0 ;
|
||||
|
||||
progname = basename(argv[0]) ;
|
||||
if( strcmp(progname,"rz") == 0 )
|
||||
receive = 1 ;
|
||||
else if( strcmp(progname, "sz") == 0 )
|
||||
send = 1 ;
|
||||
|
||||
++argv, --argc ; /* skip program name */
|
||||
|
||||
/* parse options */
|
||||
|
||||
for(; argc > 0 && **argv == '-'; ++argv, --argc )
|
||||
{
|
||||
if( strcmp(*argv, "-r") == 0 )
|
||||
receive = 1 ;
|
||||
else if( strcmp(*argv, "-s") == 0 )
|
||||
send = 1 ;
|
||||
else if( strncmp(*argv, "-v", 2) == 0 )
|
||||
verbose += strlen(*argv)+1 ;
|
||||
else if( strcmp(*argv, "-l") == 0 && --argc > 0 )
|
||||
line = *++argv ;
|
||||
else if( strcmp(*argv, "-b") == 0 && --argc > 0 )
|
||||
baud = getBaud(atoi(*++argv)) ;
|
||||
else if( strcmp(*argv, "-x") == 0 )
|
||||
xmodem = 1 ;
|
||||
else if( strcmp(*argv, "-y") == 0 )
|
||||
ymodem = 1 ;
|
||||
else if( strcmp(*argv, "-win") == 0 && --argc > 0 )
|
||||
info.windowsize = atoi(*++argv) ;
|
||||
else if( strcmp(*argv, "-buf") == 0 && --argc > 0 )
|
||||
info.bufsize = atoi(*++argv) ;
|
||||
else if( strcmp(*argv, "-L") == 0 && --argc > 0 )
|
||||
info.packetsize = atoi(*++argv) ;
|
||||
else if( strcmp(*argv, "-k") == 0 )
|
||||
info.packetsize = 1024 ;
|
||||
else if( strcmp(*argv, "-e") == 0 )
|
||||
escCtrl = ESCCTL ;
|
||||
else if( strcmp(*argv, "-a") == 0 )
|
||||
ascii = 1 ;
|
||||
else if( strcmp(*argv, "-i") == 0 )
|
||||
binary = 1 ;
|
||||
else if( strcmp(*argv, "-resume") == 0 )
|
||||
resume = 1 ;
|
||||
else if( strcmp(*argv, "-new") == 0 )
|
||||
xferType = ZMNEW ;
|
||||
else if( strcmp(*argv, "-newl") == 0 )
|
||||
xferType = ZMNEWL ;
|
||||
else if( strcmp(*argv, "-diff") == 0 )
|
||||
xferType = ZMDIFF ;
|
||||
else if( strcmp(*argv, "-crc") == 0 )
|
||||
xferType = ZMCRC ;
|
||||
else if( strcmp(*argv, "-apnd") == 0 )
|
||||
xferType = ZMAPND ;
|
||||
else if( strcmp(*argv, "-clob") == 0 )
|
||||
xferType = ZMCLOB ;
|
||||
else if( strcmp(*argv, "-prot") == 0 )
|
||||
xferType = ZMPROT ;
|
||||
else if( strcmp(*argv, "-chng") == 0 )
|
||||
xferType = ZMCHNG ;
|
||||
else if( strcmp(*argv, "-noloc") == 0 )
|
||||
noloc = ZMSKNOLOC ;
|
||||
else if( strcmp(*argv, "-h") == 0 ||
|
||||
strcmp(*argv, "-q") == 0 )
|
||||
{
|
||||
fprintf(stderr, usage) ;
|
||||
exit(0) ;
|
||||
}
|
||||
else if( strcmp(*argv, "-corrupt") == 0 )
|
||||
Corrupt = 1 ;
|
||||
else if( strcmp(*argv, "-log") == 0 )
|
||||
doLogging = 1 ;
|
||||
else if( strcmp(*argv, "-") == 0 ) {
|
||||
++argv, --argc ; break ;
|
||||
}
|
||||
else {
|
||||
fprintf(stderr, "unknown argument '%s' or missing value\n%s",
|
||||
*argv, usage) ;
|
||||
exit(2) ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if( doLogging ) {
|
||||
if( (SerialLogFile = fopen("xfer.log", "w")) == NULL )
|
||||
perror("xfer.log") ;
|
||||
if( (zmodemlogfile = fopen("zmodem.log","w")) == NULL )
|
||||
perror("zmodem.log") ;
|
||||
}
|
||||
|
||||
|
||||
if( send ) {
|
||||
for(; argc > 0; ++argv, --argc ) /* process filenames */
|
||||
SendFile(*argv) ;
|
||||
FinishXmit(&info) ;
|
||||
}
|
||||
|
||||
else if( receive )
|
||||
{
|
||||
if( !xmodem )
|
||||
RcvFiles() ;
|
||||
else
|
||||
for(; argc > 0; ++argv, --argc ) /* process filenames */
|
||||
RcvXmodem(*argv) ;
|
||||
}
|
||||
|
||||
|
||||
else {
|
||||
fprintf(stderr,
|
||||
"either -s (send) or -r (receive) must be specified\n%s", usage) ;
|
||||
exit(2) ;
|
||||
}
|
||||
|
||||
resetCom() ;
|
||||
exit(0) ;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
sighandle(int arg)
|
||||
{
|
||||
doCancel = 1 ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void
|
||||
openCom()
|
||||
{
|
||||
char *ptr ;
|
||||
|
||||
if( line == NULL )
|
||||
line = getenv("RZSZLINE") ;
|
||||
|
||||
if( baud == 0 && (ptr = getenv("RZSZBAUD")) != NULL )
|
||||
baud = getBaud(atoi(ptr)) ;
|
||||
|
||||
if( line == NULL ) {
|
||||
info.ifd = 0 ;
|
||||
info.ofd = 1 ;
|
||||
}
|
||||
else if( (info.ifd = info.ofd = open(line, O_RDWR)) == -1 ) {
|
||||
fprintf(stderr,
|
||||
"cannot open %s, %s, use \"zmodem -h\" for more info\n",
|
||||
line, strerror(errno)) ;
|
||||
exit(2) ;
|
||||
}
|
||||
|
||||
/* assumption: setting attributes for one half of channel will
|
||||
* change both halves. This fails if different physical
|
||||
* devices are used.
|
||||
*/
|
||||
tcgetattr(info.ifd,&old_settings) ;
|
||||
new_settings = old_settings ;
|
||||
|
||||
#ifdef IUCLC
|
||||
new_settings.c_iflag &=
|
||||
~(ISTRIP|INLCR|IGNCR|ICRNL|IUCLC|IXON|IXOFF|IMAXBEL) ;
|
||||
#else
|
||||
new_settings.c_iflag &=
|
||||
~(ISTRIP|INLCR|IGNCR|ICRNL|IXON|IXOFF|IMAXBEL) ;
|
||||
#endif
|
||||
new_settings.c_oflag &= ~OPOST ;
|
||||
new_settings.c_cflag &= ~(CSIZE|PARENB) ;
|
||||
new_settings.c_cflag |= CS8 ;
|
||||
if( baud != 0 ) {
|
||||
cfsetospeed(&new_settings, baud) ;
|
||||
cfsetispeed(&new_settings, baud) ;
|
||||
}
|
||||
else
|
||||
baud = cfgetospeed(&old_settings) ;
|
||||
new_settings.c_lflag = 0 ;
|
||||
new_settings.c_cc[VMIN] = 32 ;
|
||||
new_settings.c_cc[VTIME] = 1 ;
|
||||
tcsetattr(info.ifd,TCSADRAIN, &new_settings) ;
|
||||
|
||||
info.zrinitflags = CANFDX|CANOVIO|CANBRK|CANFC32|escCtrl ;
|
||||
info.zsinitflags = escCtrl ;
|
||||
if( info.packetsize == 0 ) {
|
||||
if( xmodem || ymodem )
|
||||
info.packetsize = 128 ;
|
||||
/* TODO: what about future high-speed interfaces? */
|
||||
else if( baud < B2400 )
|
||||
info.packetsize = 256 ;
|
||||
else if( baud == B2400 )
|
||||
info.packetsize = 512 ;
|
||||
else
|
||||
info.packetsize = 1024 ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
resetCom()
|
||||
{
|
||||
tcsetattr(info.ifd,TCSADRAIN, &old_settings) ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void
|
||||
SendFile(char *filename)
|
||||
{
|
||||
int f0, f1 ;
|
||||
|
||||
fileErrs = 0 ;
|
||||
|
||||
if( !begun ) /* establish connection */
|
||||
{
|
||||
openCom() ;
|
||||
|
||||
signal(SIGINT, sighandle) ;
|
||||
signal(SIGTERM, sighandle) ;
|
||||
signal(SIGHUP, sighandle) ;
|
||||
|
||||
if( InitXmit(&info) ) {
|
||||
fprintf(stderr, "connect failed\n") ;
|
||||
resetCom() ;
|
||||
exit(1) ;
|
||||
}
|
||||
|
||||
begun = 1 ;
|
||||
}
|
||||
|
||||
if( ascii )
|
||||
f0 = ZCNL ;
|
||||
else if( binary )
|
||||
f0 = ZCBIN ;
|
||||
else if( resume )
|
||||
f0 = ZCRESUM ;
|
||||
else
|
||||
f0 = 0 ;
|
||||
|
||||
f1 = xferType | noloc ;
|
||||
|
||||
if( XmitFile(filename, f0,f1, &info) ) {
|
||||
fprintf(stderr, "connect failed\n") ;
|
||||
resetCom() ;
|
||||
exit(1) ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void
|
||||
RcvFiles()
|
||||
{
|
||||
openCom() ;
|
||||
|
||||
signal(SIGINT, sighandle) ;
|
||||
signal(SIGTERM, sighandle) ;
|
||||
|
||||
if( DoReceive(&info) ) {
|
||||
fprintf(stderr, "connect failed\n") ;
|
||||
resetCom() ;
|
||||
exit(1) ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void
|
||||
RcvXmodem(char *filename)
|
||||
{
|
||||
/* TODO: */
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
getBaud(int b)
|
||||
{
|
||||
switch(b) {
|
||||
case 50: return B50 ;
|
||||
case 75: return B75 ;
|
||||
case 110: return B110 ;
|
||||
case 134: return B134 ;
|
||||
case 150: return B150 ;
|
||||
case 200: return B200 ;
|
||||
case 300: return B300 ;
|
||||
case 600: return B600 ;
|
||||
case 1200: return B1200 ;
|
||||
case 1800: return B1800 ;
|
||||
case 2400: return B2400 ;
|
||||
case 4800: return B4800 ;
|
||||
case 9600: return B9600 ;
|
||||
case 19200: return B19200 ;
|
||||
case 38400: return B38400 ;
|
||||
default: return 0 ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* TEST: randomly corrupt every 1000th byte */
|
||||
static void
|
||||
corrupt(u_char *buffer, int len)
|
||||
{
|
||||
extern double drand48() ;
|
||||
|
||||
while( --len >= 0 ) {
|
||||
if( drand48() < 1./1000. )
|
||||
*buffer ^= 0x81 ;
|
||||
++buffer ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
doIO(ZModem *info)
|
||||
{
|
||||
fd_set readfds ;
|
||||
struct timeval timeout ;
|
||||
int i ;
|
||||
int len ;
|
||||
u_char buffer[1024] ;
|
||||
int done = 0 ;
|
||||
|
||||
while(!done)
|
||||
{
|
||||
FD_ZERO(&readfds) ;
|
||||
FD_SET(info->ifd, &readfds) ;
|
||||
timeout.tv_sec = info->timeout ;
|
||||
timeout.tv_usec = 0 ;
|
||||
i = select(info->ifd+1, &readfds,NULL,NULL, &timeout) ;
|
||||
if( doCancel ) {
|
||||
ZmodemAbort(info) ;
|
||||
fprintf(stderr, "cancelled by user\n") ;
|
||||
resetCom() ;
|
||||
exit(3) ;
|
||||
}
|
||||
if( i<0 )
|
||||
perror("select") ;
|
||||
else if( i==0 )
|
||||
done = ZmodemTimeout(info) ;
|
||||
else {
|
||||
len = read(info->ifd, buffer, sizeof(buffer)) ;
|
||||
if( Corrupt )
|
||||
corrupt(buffer, len) ;
|
||||
if( SerialLogFile != NULL )
|
||||
SerialLog(buffer, len, 1) ;
|
||||
done = ZmodemRcv(buffer, len, info) ;
|
||||
}
|
||||
}
|
||||
if( SerialLogFile != NULL )
|
||||
SerialLogFlush() ;
|
||||
return done ;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
InitXmit(ZModem *info)
|
||||
{
|
||||
int done ;
|
||||
|
||||
if( xmodem )
|
||||
done = XmodemTInit(info) ;
|
||||
else if( ymodem )
|
||||
done = YmodemTInit(info) ;
|
||||
else
|
||||
done = ZmodemTInit(info) ;
|
||||
if( !done )
|
||||
done = doIO(info) ;
|
||||
|
||||
return done != ZmDone ;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
XmitFile(char *filename, int f0, int f1, ZModem *info)
|
||||
{
|
||||
int done ;
|
||||
|
||||
done = ZmodemTFile(filename,filename, f0,f1,0,0,
|
||||
0,0, info) ;
|
||||
switch( done ) {
|
||||
case 0:
|
||||
if( verbose )
|
||||
fprintf(stderr, "Sending: \"%s\"\n", filename) ;
|
||||
break ;
|
||||
|
||||
case ZmErrCantOpen:
|
||||
fprintf(stderr, "cannot open file \"%s\": %s\n",
|
||||
filename, strerror(errno)) ;
|
||||
return 0 ;
|
||||
|
||||
case ZmFileTooLong:
|
||||
fprintf(stderr, "filename \"%s\" too long, skipping...\n",
|
||||
filename) ;
|
||||
return 0 ;
|
||||
|
||||
case ZmDone:
|
||||
return 0 ;
|
||||
|
||||
default:
|
||||
return 1 ;
|
||||
}
|
||||
|
||||
if( !done )
|
||||
done = doIO(info) ;
|
||||
|
||||
return done != ZmDone ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int
|
||||
FinishXmit(ZModem *info)
|
||||
{
|
||||
int done ;
|
||||
|
||||
done = ZmodemTFinish(info) ;
|
||||
if( !done )
|
||||
done = doIO(info) ;
|
||||
|
||||
return done != ZmDone ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int
|
||||
DoReceive(ZModem *info)
|
||||
{
|
||||
int done ;
|
||||
|
||||
if( ymodem )
|
||||
done = YmodemRInit(info) ;
|
||||
else
|
||||
done = ZmodemRInit(info) ;
|
||||
|
||||
if( !done )
|
||||
done = doIO(info) ;
|
||||
|
||||
return done != ZmDone ;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
ZXmitStr(u_char *buffer, int len, ZModem *info)
|
||||
{
|
||||
u_char b2[1024] ;
|
||||
|
||||
/* TEST: randomly corrupt every 1000th byte */
|
||||
if( Corrupt )
|
||||
{
|
||||
bcopy(buffer, b2, len) ;
|
||||
corrupt(b2, len) ;
|
||||
buffer = b2 ;
|
||||
}
|
||||
|
||||
if( SerialLogFile != NULL )
|
||||
SerialLog(buffer, len, 0) ;
|
||||
|
||||
if( write(info->ofd, buffer, len) != len )
|
||||
return ZmErrSys ;
|
||||
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ZIFlush(ZModem *info)
|
||||
{
|
||||
if( SerialLogFile != NULL )
|
||||
SerialLogFlush() ;
|
||||
|
||||
if( tcflush(info->ifd, TCIFLUSH) != 0 )
|
||||
perror("TCIFLUSH") ;
|
||||
}
|
||||
|
||||
void
|
||||
ZOFlush(ZModem *info)
|
||||
{
|
||||
if( SerialLogFile != NULL )
|
||||
SerialLogFlush() ;
|
||||
|
||||
if( tcflush(info->ifd, TCOFLUSH) != 0 )
|
||||
perror("TCOFLUSH") ;
|
||||
}
|
||||
|
||||
void
|
||||
ZStatus(int type, int j, char *str)
|
||||
{
|
||||
switch( type ) {
|
||||
case RcvByteCount:
|
||||
if( verbose >= 2 )
|
||||
fprintf(stderr, "received: %6d bytes\n", j) ;
|
||||
break ;
|
||||
case SndByteCount:
|
||||
fileSent = j ;
|
||||
if( verbose >= 2 )
|
||||
fprintf(stderr, "sent: %6d bytes\n", j) ;
|
||||
break ;
|
||||
case RcvTimeout:
|
||||
if( verbose )
|
||||
fprintf(stderr, "receiver timeouts: %2d\n", j) ;
|
||||
break ;
|
||||
case SndTimeout:
|
||||
if( verbose )
|
||||
fprintf(stderr, "sender timeouts: %2d\n", j) ;
|
||||
break ;
|
||||
case RmtCancel:
|
||||
fprintf(stderr, "transfer cancelled by remote\n") ;
|
||||
break ;
|
||||
case ProtocolErr:
|
||||
if( verbose >= 3 )
|
||||
fprintf(stderr, "protocol error: %2.2d\n", j) ;
|
||||
break ;
|
||||
case RemoteMessage:
|
||||
fprintf(stderr, "remote message: %s\n",str) ;
|
||||
break ;
|
||||
case DataErr:
|
||||
if( verbose >= 3 )
|
||||
fprintf(stderr, "data errors: %2d\n", j) ;
|
||||
#ifdef COMMENT
|
||||
if( ++fileErrs > 20 )
|
||||
{
|
||||
/* something's wrong */
|
||||
ZmodemAbort(&info) ;
|
||||
}
|
||||
#endif /* COMMENT */
|
||||
break ;
|
||||
case FileErr:
|
||||
fprintf(stderr, "cannot write file: %s\n", strerror(errno)) ;
|
||||
break ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
ZAttn(ZModem *info)
|
||||
{
|
||||
char *ptr ;
|
||||
|
||||
if( info->attn == NULL )
|
||||
return 0 ;
|
||||
|
||||
for(ptr = info->attn; *ptr != '\0'; ++ptr) {
|
||||
if( *ptr == ATTNBRK )
|
||||
tcsendbreak(info->ifd, 0) ;
|
||||
else if( *ptr == ATTNPSE )
|
||||
sleep(1) ;
|
||||
else
|
||||
write(info->ifd, ptr, 1) ;
|
||||
}
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
|
||||
FILE *
|
||||
ZOpenFile(char *name, u_long crc, ZModem *info)
|
||||
{
|
||||
struct stat buf ;
|
||||
int exists ; /* file already exists */
|
||||
static int changeCount = 0 ;
|
||||
char name2[MAXPATHLEN] ;
|
||||
int apnd = 0 ;
|
||||
int f0,f1 ;
|
||||
FILE *rval ;
|
||||
|
||||
/* TODO: if absolute path, do we want to allow it?
|
||||
* if relative path, do we want to prepend something?
|
||||
*/
|
||||
|
||||
if( *name == '/' ) /* for now, disallow absolute paths */
|
||||
return NULL ;
|
||||
|
||||
if( stat(name, &buf) == 0 )
|
||||
exists = 1 ;
|
||||
else if( errno == ENOENT )
|
||||
exists = 0 ;
|
||||
else
|
||||
return NULL ;
|
||||
|
||||
|
||||
/* if remote end has not specified transfer flags, we can
|
||||
* accept the local definitions
|
||||
*/
|
||||
|
||||
if( (f0=info->f0) == 0 ) {
|
||||
if( ascii )
|
||||
f0 = ZCNL ;
|
||||
else if( binary )
|
||||
f0 = ZCBIN ;
|
||||
else if( resume )
|
||||
f0 = ZCRESUM ;
|
||||
else
|
||||
f0 = 0 ;
|
||||
}
|
||||
|
||||
if( (f1=info->f1) == 0 )
|
||||
f1 = xferType | noloc ;
|
||||
|
||||
if( f0 == ZCRESUM ) { /* if exists, and we already have it, return */
|
||||
if( exists && buf.st_size == info->len )
|
||||
return NULL ;
|
||||
apnd = 1 ;
|
||||
}
|
||||
|
||||
/* reject if file not found and it most be there (ZMSKNOLOC) */
|
||||
if( !exists && (f1 & ZMSKNOLOC) )
|
||||
return NULL ;
|
||||
|
||||
switch( f1 & ZMMASK ) {
|
||||
case 0: /* Implementation-dependent. In this case, we
|
||||
* reject if file exists (and ZMSKNOLOC not set) */
|
||||
if( exists && !(f1 & ZMSKNOLOC) ) {
|
||||
fprintf(stderr, "%s already exists\n", name) ;
|
||||
return NULL ;
|
||||
}
|
||||
break ;
|
||||
|
||||
case ZMNEWL: /* take if newer or longer than file on disk */
|
||||
if( exists && info->date <= buf.st_mtime &&
|
||||
info->len <= buf.st_size ) {
|
||||
fprintf(stderr, "%s already exists\n", name) ;
|
||||
return NULL ;
|
||||
}
|
||||
break ;
|
||||
|
||||
case ZMCRC: /* take if different CRC or length */
|
||||
if( exists && info->len == buf.st_size && crc == FileCrc(name) )
|
||||
{
|
||||
fprintf(stderr, "%s already exists\n", name) ;
|
||||
return NULL ;
|
||||
}
|
||||
break ;
|
||||
|
||||
case ZMAPND: /* append */
|
||||
apnd = 1 ;
|
||||
case ZMCLOB: /* unconditional replace */
|
||||
break ;
|
||||
|
||||
case ZMNEW: /* take if newer than file on disk */
|
||||
if( exists && info->date <= buf.st_mtime ) {
|
||||
fprintf(stderr, "%s already exists and is newer\n", name) ;
|
||||
return NULL ;
|
||||
}
|
||||
break ;
|
||||
|
||||
case ZMDIFF: /* take if different date or length */
|
||||
if( exists && info->date == buf.st_mtime &&
|
||||
info->len == buf.st_size )
|
||||
{
|
||||
fprintf(stderr, "%s already exists\n", name) ;
|
||||
return NULL ;
|
||||
}
|
||||
break ;
|
||||
|
||||
case ZMPROT: /* only if dest does not exist */
|
||||
if( exists )
|
||||
{
|
||||
fprintf(stderr, "%s already exists\n", name) ;
|
||||
return NULL ;
|
||||
}
|
||||
break ;
|
||||
|
||||
case ZMCHNG: /* invent new filename if exists */
|
||||
if( exists ) {
|
||||
while( exists ) {
|
||||
sprintf(name2, "%s_%d", name, changeCount++) ;
|
||||
exists = stat(name2, &buf) == 0 || errno != ENOENT ;
|
||||
}
|
||||
name = name2 ;
|
||||
}
|
||||
break ;
|
||||
}
|
||||
|
||||
/* here if we've decided to accept */
|
||||
#ifdef COMMENT
|
||||
if( exists && !apnd && unlink(name) != 0 )
|
||||
return NULL ;
|
||||
#endif /* COMMENT */
|
||||
|
||||
/* TODO: build directory path if needed */
|
||||
|
||||
if( verbose )
|
||||
fprintf(stderr, "Receiving: \"%s\"\n", name) ;
|
||||
|
||||
rval = fopen(name, apnd ? "a" : "w") ;
|
||||
if( rval == NULL )
|
||||
perror(name) ;
|
||||
return rval ;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
ZWriteFile(u_char *buffer, int len, FILE *file, ZModem *info)
|
||||
{
|
||||
/* TODO: if ZCNL set in info->f0, convert
|
||||
* newlines to local convention
|
||||
*/
|
||||
|
||||
return fwrite(buffer, 1, len, file) == len ? 0 : ZmErrSys ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int
|
||||
ZCloseFile(ZModem *info)
|
||||
{
|
||||
struct timeval tvp[2] ;
|
||||
fclose(info->file) ;
|
||||
if( ymodem )
|
||||
truncate(info->filename, info->len) ;
|
||||
if( info->date != 0 ) {
|
||||
tvp[0].tv_sec = tvp[1].tv_sec = info->date ;
|
||||
tvp[0].tv_usec = tvp[1].tv_usec = 0 ;
|
||||
utimes(info->filename, tvp) ;
|
||||
}
|
||||
if( info->mode & 01000000 )
|
||||
chmod(info->filename, info->mode&0777) ;
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ZIdleStr(u_char *buffer, int len, ZModem *info)
|
||||
{
|
||||
#ifdef COMMENT
|
||||
fwrite(buffer, 1,len, stdout) ;
|
||||
#endif /* COMMENT */
|
||||
}
|
||||
|
||||
void
|
||||
ZFlowControl(int onoff, ZModem *info)
|
||||
{
|
||||
if( onoff ) {
|
||||
new_settings.c_iflag |= IXON|IXANY|IXOFF ;
|
||||
#ifdef COMMENT
|
||||
new_settings.c_cflag |= CRTSCTS ;
|
||||
#endif /* COMMENT */
|
||||
}
|
||||
else {
|
||||
new_settings.c_iflag &= ~(IXON|IXANY|IXOFF) ;
|
||||
new_settings.c_cflag &= ~CRTSCTS ;
|
||||
}
|
||||
tcsetattr(info->ifd,TCSADRAIN, &new_settings) ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static char *
|
||||
basename(char *name)
|
||||
{
|
||||
char *ptr ;
|
||||
|
||||
if( (ptr = strrchr(name, '/')) == NULL )
|
||||
return name ;
|
||||
else
|
||||
return ++ptr ;
|
||||
}
|
|
@ -1,155 +0,0 @@
|
|||
#ifndef lint
|
||||
static const char rcsid[] = "$Id: network.c,v 1.2 2001/10/25 23:56:29 efalk Exp $" ;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Copyright (c) 1995 by Edward A. Falk
|
||||
*/
|
||||
|
||||
|
||||
/**********
|
||||
*
|
||||
*
|
||||
* @ @ @@@@@ @@@@@ @ @ @@@ @@@@ @ @
|
||||
* @@ @ @ @ @ @ @ @ @ @ @ @
|
||||
* @ @ @ @@@ @ @ @ @ @ @ @@@@ @@@
|
||||
* @ @@ @ @ @ @ @ @ @ @ @ @ @
|
||||
* @ @ @@@@@ @ @ @ @@@ @ @ @ @
|
||||
*
|
||||
* NETWORK - Make network connection
|
||||
*
|
||||
* Routines provided here:
|
||||
*
|
||||
*
|
||||
* void
|
||||
* IpConnect()
|
||||
* Make IP connection according to parameters in gcomm.h
|
||||
*
|
||||
* void
|
||||
* IpDisConnect()
|
||||
* Close IP connection.
|
||||
*
|
||||
*
|
||||
*
|
||||
* Edward A. Falk
|
||||
*
|
||||
* January, 1995
|
||||
*
|
||||
*
|
||||
*
|
||||
**********/
|
||||
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <malloc.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <fcntl.h>
|
||||
#include <varargs.h>
|
||||
#include <errno.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/stat.h>
|
||||
#ifdef COMMENT
|
||||
#include <sys/ttold.h>
|
||||
#include <sys/termio.h>
|
||||
#endif /* COMMENT */
|
||||
#include <termio.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <netdb.h> /* stuff used by tcp/ip */
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
#include <sys/wait.h>
|
||||
#include <sys/signal.h>
|
||||
|
||||
#include "gcomm.h"
|
||||
|
||||
extern int errno ;
|
||||
#ifdef COMMENT
|
||||
extern char *sys_errlist[] ;
|
||||
#endif /* COMMENT */
|
||||
|
||||
|
||||
|
||||
void
|
||||
IpConnect()
|
||||
{
|
||||
int sockfd ;
|
||||
int i,j ;
|
||||
struct hostent *hostent ;
|
||||
struct sockaddr_in sockaddr ;
|
||||
int port ;
|
||||
|
||||
WindowStatus("Connecting...") ;
|
||||
|
||||
port = PortLookup(hostPort) ;
|
||||
if( port == -1 )
|
||||
return ;
|
||||
|
||||
bzero(&sockaddr, sizeof(sockaddr)) ;
|
||||
sockaddr.sin_family = AF_INET ;
|
||||
sockaddr.sin_port = htons(port) ;
|
||||
|
||||
hostent = gethostbyname(hostId) ;
|
||||
if( hostent != NULL )
|
||||
{
|
||||
sockaddr.sin_addr = *(struct in_addr *) hostent->h_addr ;
|
||||
}
|
||||
else if( isdigit(hostId[0]) )
|
||||
{
|
||||
i = sscanf(hostId, "%d.%d.%d.%d",
|
||||
&sockaddr.sin_addr.S_un.S_un_b.s_b1,
|
||||
&sockaddr.sin_addr.S_un.S_un_b.s_b2,
|
||||
&sockaddr.sin_addr.S_un.S_un_b.s_b3,
|
||||
&sockaddr.sin_addr.S_un.S_un_b.s_b4) ;
|
||||
if( i != 4 ) {
|
||||
WindowStatus("Host address must be in dd.dd.dd.dd format") ;
|
||||
return ;
|
||||
}
|
||||
}
|
||||
else {
|
||||
WindowStatus("Hostname not found") ;
|
||||
return ;
|
||||
}
|
||||
|
||||
sockfd = socket(AF_INET, SOCK_STREAM, 0) ;
|
||||
if( sockfd < 0 ) {
|
||||
WindowStatus("Cannot open socket: %s", sys_errlist[errno]) ;
|
||||
return ;
|
||||
}
|
||||
|
||||
i = connect(sockfd, &sockaddr, sizeof(sockaddr)) ;
|
||||
if( i < 0 ) {
|
||||
WindowStatus("Cannot connect to host: %s", sys_errlist[errno]) ;
|
||||
close(sockfd) ;
|
||||
return ;
|
||||
}
|
||||
|
||||
ifd = ofd = sockfd ;
|
||||
|
||||
i = fcntl(ifd, F_GETFL, 0) ;
|
||||
j = fcntl(ifd, F_SETFL, i|O_NDELAY) ;
|
||||
|
||||
connectionActive = 1 ;
|
||||
connectTime0 = time(NULL) ;
|
||||
WindowStatus("Connected") ;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
IpDisConnect()
|
||||
{
|
||||
if( ifd == -1 )
|
||||
return ;
|
||||
|
||||
close(ifd) ;
|
||||
ifd = ofd = -1 ;
|
||||
|
||||
connectionActive = 0 ;
|
||||
}
|
|
@ -1,600 +0,0 @@
|
|||
#ifndef lint
|
||||
static const char rcsid[] = "$Id: receive.c,v 1.2 2001/10/25 23:56:29 efalk Exp $" ;
|
||||
#endif
|
||||
|
||||
|
||||
#define TEST /* standalone test */
|
||||
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include "zmodem.h"
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/termios.h>
|
||||
#include <sys/termio.h> /* define TCSBRK */
|
||||
#include <sys/param.h>
|
||||
|
||||
extern int errno ;
|
||||
|
||||
static u_char zeros[4] = {0,0,0,0} ;
|
||||
|
||||
main(argc,argv)
|
||||
int argc ;
|
||||
char **argv ;
|
||||
{
|
||||
struct termios old_settings, new_settings ;
|
||||
fd_set readfds ;
|
||||
struct timeval timeout ;
|
||||
int i ;
|
||||
int len ;
|
||||
char buffer[1024] ;
|
||||
int done = 0 ;
|
||||
int filecount = 0 ;
|
||||
ZModem info ;
|
||||
|
||||
#ifdef TEST
|
||||
|
||||
static u_char Amsg0[] = {
|
||||
0x72, 0x7a, 0x0d, 0x2a, 0x2a, 0x18, 0x42, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30,
|
||||
0x30, 0x30, 0x30, 0x30, 0x30, 0x0d, 0x0a, 0x11,
|
||||
} ;
|
||||
static u_char Amsg1[] = {
|
||||
0x2a, 0x18, 0x43, 0x02, 0x00, 0x00, 0x00, 0x00,
|
||||
0x7d, 0xa4, 0xe2, 0xbc, 0x00, 0x18, 0x6b, 0x2f,
|
||||
0xaa, 0xb9, 0x9b, 0x2a, 0x18, 0x43, 0x02, 0x00,
|
||||
0x00, 0x00, 0x00, 0x7d, 0xa4, 0xe2, 0xbc,
|
||||
} ;
|
||||
static u_char Amsg2[] = {
|
||||
0x00, 0x18, 0x6b, 0x2f, 0xaa, 0xb9, 0x9b, 0x2a,
|
||||
0x18, 0x43, 0x04, 0x00, 0x00, 0x04, 0x00, 0xd9,
|
||||
0x94, 0xce, 0x57,
|
||||
} ;
|
||||
static u_char Amsg3[] = {
|
||||
0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x2e,
|
||||
0x63, 0x00, 0x31, 0x36, 0x39, 0x38, 0x36, 0x20,
|
||||
0x35, 0x37, 0x30, 0x30, 0x36, 0x36, 0x37, 0x36,
|
||||
0x37, 0x30, 0x20, 0x31, 0x30, 0x30, 0x36, 0x36,
|
||||
0x34, 0x20, 0x30, 0x20, 0x30, 0x20, 0x30, 0x20,
|
||||
0x30, 0x00, 0x18, 0x6b, 0x57, 0xed, 0x76, 0xb6,
|
||||
} ;
|
||||
static u_char Amsg4[] = {
|
||||
0x2a, 0x18, 0x43, 0x0a, 0x00, 0x00, 0x00, 0x00,
|
||||
0xbc, 0xef, 0x92, 0x8c, 0x0a, 0x23, 0x64, 0x65,
|
||||
0x66, 0x69, 0x6e, 0x65, 0x09, 0x54, 0x45, 0x53,
|
||||
0x54, 0x09, 0x2f, 0x2a, 0x20, 0x73, 0x74, 0x61,
|
||||
0x6e, 0x64, 0x61, 0x6c, 0x6f, 0x6e, 0x65, 0x20,
|
||||
0x74, 0x65, 0x73, 0x74, 0x20, 0x2a, 0x2f, 0x0a,
|
||||
0x0a, 0x23, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64,
|
||||
0x65, 0x20, 0x3c, 0x75, 0x6e, 0x69, 0x73, 0x74,
|
||||
0x64, 0x2e, 0x68, 0x3e, 0x0a, 0x23, 0x69, 0x6e,
|
||||
0x63, 0x6c, 0x75, 0x64, 0x65, 0x20, 0x3c, 0x73,
|
||||
0x74, 0x72, 0x69, 0x6e, 0x67, 0x2e, 0x68, 0x3e,
|
||||
0x0a, 0x23, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64,
|
||||
0x65, 0x20, 0x22, 0x7a, 0x6d, 0x6f, 0x64, 0x65,
|
||||
0x6d, 0x2e, 0x68, 0x22, 0x0a, 0x23, 0x69, 0x6e,
|
||||
0x63, 0x6c, 0x75, 0x64, 0x65, 0x20, 0x3c, 0x73,
|
||||
0x79, 0x73, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x2e,
|
||||
0x68, 0x3e, 0x0a, 0x0a, 0x23, 0x69, 0x6e, 0x63,
|
||||
0x6c, 0x75, 0x64, 0x65, 0x20, 0x3c, 0x66, 0x63,
|
||||
0x6e, 0x74, 0x6c, 0x2e, 0x68, 0x3e, 0x0a, 0x23,
|
||||
0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x20,
|
||||
0x3c, 0x65, 0x72, 0x72, 0x6e, 0x6f, 0x2e, 0x68,
|
||||
0x3e, 0x0a, 0x23, 0x69, 0x6e, 0x63, 0x6c, 0x75,
|
||||
0x64, 0x65, 0x20, 0x3c, 0x73, 0x79, 0x73, 0x2f,
|
||||
0x74, 0x69, 0x6d, 0x65, 0x2e, 0x68, 0x3e, 0x0a,
|
||||
0x23, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65,
|
||||
0x20, 0x3c, 0x73, 0x79, 0x73, 0x2f, 0x74, 0x65,
|
||||
0x72, 0x6d, 0x69, 0x6f, 0x73, 0x2e, 0x68, 0x3e,
|
||||
0x0a, 0x23, 0x69, 0x6e, 0x63, 0x6c, 0x75, 0x64,
|
||||
0x65, 0x20, 0x3c, 0x73, 0x79, 0x73, 0x2f, 0x74,
|
||||
0x65, 0x72, 0x6d, 0x69, 0x6f, 0x2e, 0x68, 0x3e,
|
||||
0x09, 0x09, 0x2f, 0x2a, 0x20, 0x64, 0x65, 0x66,
|
||||
0x69, 0x6e, 0x65, 0x20, 0x54, 0x43, 0x53, 0x42,
|
||||
0x52, 0x4b, 0x20, 0x2a, 0x2f, 0x0a, 0x23, 0x69,
|
||||
0x6e, 0x63, 0x6c, 0x75, 0x64, 0x65, 0x20, 0x3c,
|
||||
0x73, 0x79, 0x73, 0x2f, 0x70, 0x61, 0x72, 0x61,
|
||||
0x6d, 0x2e, 0x68, 0x3e, 0x0a, 0x0a, 0x65, 0x78,
|
||||
0x74, 0x65, 0x72, 0x6e, 0x09, 0x69, 0x6e, 0x74,
|
||||
0x09, 0x65, 0x72, 0x72, 0x6e, 0x6f, 0x20, 0x3b,
|
||||
0x0a, 0x0a, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63,
|
||||
0x09, 0x75, 0x5f, 0x63, 0x68, 0x61, 0x72, 0x09,
|
||||
0x7a, 0x65, 0x72, 0x6f, 0x73, 0x5b, 0x34, 0x5d,
|
||||
0x20, 0x3d, 0x20, 0x7b, 0x30, 0x2c, 0x30, 0x2c,
|
||||
0x30, 0x2c, 0x30, 0x7d, 0x20, 0x3b, 0x0a, 0x0a,
|
||||
0x6d, 0x61, 0x69, 0x6e, 0x28, 0x61, 0x72, 0x67,
|
||||
0x63, 0x2c, 0x61, 0x72, 0x67, 0x76, 0x29, 0x0a,
|
||||
0x09, 0x69, 0x6e, 0x74, 0x09, 0x61, 0x72, 0x67,
|
||||
0x63, 0x20, 0x3b, 0x0a, 0x09, 0x63, 0x68, 0x61,
|
||||
0x72, 0x09, 0x2a, 0x2a, 0x61, 0x72, 0x67, 0x76,
|
||||
0x20, 0x3b, 0x0a, 0x7b, 0x0a, 0x09, 0x73, 0x74,
|
||||
0x72, 0x75, 0x63, 0x74, 0x09, 0x74, 0x65, 0x72,
|
||||
0x6d, 0x69, 0x6f, 0x73, 0x09, 0x6f, 0x6c, 0x64,
|
||||
0x5f, 0x73, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67,
|
||||
0x73, 0x2c, 0x20, 0x6e, 0x65, 0x77, 0x5f, 0x73,
|
||||
0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x20,
|
||||
0x3b, 0x0a, 0x09, 0x66, 0x64, 0x5f, 0x73, 0x65,
|
||||
0x74, 0x09, 0x72, 0x65, 0x61, 0x64, 0x66, 0x64,
|
||||
0x73, 0x20, 0x3b, 0x0a, 0x09, 0x73, 0x74, 0x72,
|
||||
0x75, 0x63, 0x74, 0x20, 0x74, 0x69, 0x6d, 0x65,
|
||||
0x76, 0x61, 0x6c, 0x20, 0x74, 0x69, 0x6d, 0x65,
|
||||
0x6f, 0x75, 0x74, 0x20, 0x3b, 0x0a, 0x09, 0x69,
|
||||
0x6e, 0x74, 0x09, 0x69, 0x20, 0x3b, 0x0a, 0x09,
|
||||
0x69, 0x6e, 0x74, 0x09, 0x6c, 0x65, 0x6e, 0x20,
|
||||
0x3b, 0x0a, 0x09, 0x63, 0x68, 0x61, 0x72, 0x09,
|
||||
0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x5b, 0x31,
|
||||
0x30, 0x32, 0x34, 0x5d, 0x20, 0x3b, 0x0a, 0x09,
|
||||
0x69, 0x6e, 0x74, 0x09, 0x64, 0x6f, 0x6e, 0x65,
|
||||
0x20, 0x3d, 0x20, 0x30, 0x20, 0x3b, 0x0a, 0x09,
|
||||
0x69, 0x6e, 0x74, 0x09, 0x66, 0x69, 0x6c, 0x65,
|
||||
0x63, 0x6f, 0x75, 0x6e, 0x74, 0x20, 0x3d, 0x20,
|
||||
0x30, 0x20, 0x3b, 0x0a, 0x09, 0x5a, 0x4d, 0x6f,
|
||||
0x64, 0x65, 0x6d, 0x09, 0x69, 0x6e, 0x66, 0x6f,
|
||||
0x20, 0x3b, 0x0a, 0x0a, 0x23, 0x69, 0x66, 0x64,
|
||||
0x65, 0x66, 0x09, 0x54, 0x45, 0x53, 0x54, 0x0a,
|
||||
0x0a, 0x73, 0x74, 0x61, 0x74, 0x69, 0x63, 0x09,
|
||||
0x75, 0x5f, 0x63, 0x68, 0x61, 0x72, 0x09, 0x41,
|
||||
0x6d, 0x73, 0x67, 0x30, 0x5b, 0x5d, 0x20, 0x3d,
|
||||
0x20, 0x7b, 0x0a, 0x09, 0x20, 0x20, 0x30, 0x78,
|
||||
0x37, 0x32, 0x2c, 0x20, 0x30, 0x78, 0x37, 0x61,
|
||||
0x2c, 0x20, 0x30, 0x78, 0x30, 0x64, 0x2c, 0x20,
|
||||
0x30, 0x78, 0x32, 0x61, 0x2c, 0x20, 0x30, 0x78,
|
||||
0x32, 0x61, 0x2c, 0x20, 0x30, 0x78, 0x31, 0x38,
|
||||
0x2c, 0x20, 0x30, 0x78, 0x34, 0x32, 0x2c, 0x20,
|
||||
0x30, 0x78, 0x33, 0x30, 0x2c, 0x20, 0x0a, 0x09,
|
||||
0x20, 0x20, 0x30, 0x78, 0x33, 0x30, 0x2c, 0x20,
|
||||
0x30, 0x78, 0x33, 0x30, 0x2c, 0x20, 0x30, 0x78,
|
||||
0x33, 0x30, 0x2c, 0x20, 0x30, 0x78, 0x33, 0x30,
|
||||
0x2c, 0x20, 0x30, 0x78, 0x33, 0x30, 0x2c, 0x20,
|
||||
0x30, 0x78, 0x33, 0x30, 0x2c, 0x20, 0x30, 0x78,
|
||||
0x33, 0x30, 0x2c, 0x20, 0x30, 0x78, 0x33, 0x30,
|
||||
0x2c, 0x20, 0x0a, 0x09, 0x20, 0x20, 0x30, 0x78,
|
||||
0x33, 0x30, 0x2c, 0x20, 0x30, 0x78, 0x33, 0x30,
|
||||
0x2c, 0x20, 0x30, 0x78, 0x33, 0x30, 0x2c, 0x20,
|
||||
0x30, 0x78, 0x33, 0x30, 0x2c, 0x20, 0x30, 0x78,
|
||||
0x33, 0x30, 0x2c, 0x20, 0x30, 0x78, 0x30, 0x64,
|
||||
0x2c, 0x20, 0x30, 0x78, 0x30, 0x61, 0x2c, 0x20,
|
||||
0x30, 0x78, 0x31, 0x31, 0x2c, 0x20, 0x0a, 0x09,
|
||||
0x7d, 0x20, 0x3b, 0x0a, 0x73, 0x74, 0x61, 0x74,
|
||||
0x69, 0x63, 0x09, 0x75, 0x5f, 0x63, 0x68, 0x61,
|
||||
0x72, 0x09, 0x41, 0x6d, 0x73, 0x67, 0x31, 0x5b,
|
||||
0x5d, 0x20, 0x3d, 0x20, 0x7b, 0x0a, 0x09, 0x20,
|
||||
0x20, 0x30, 0x78, 0x32, 0x61, 0x2c, 0x20, 0x30,
|
||||
0x78, 0x31, 0x38, 0x2c, 0x20, 0x30, 0x78, 0x34,
|
||||
0x33, 0x2c, 0x20, 0x30, 0x78, 0x30, 0x34, 0x2c,
|
||||
0x20, 0x30, 0x78, 0x30, 0x30, 0x2c, 0x20, 0x30,
|
||||
0x78, 0x30, 0x30, 0x2c, 0x20, 0x30, 0x78, 0x30,
|
||||
0x30, 0x2c, 0x20, 0x30, 0x78, 0x30, 0x30, 0x2c,
|
||||
0x20, 0x0a, 0x09, 0x20, 0x20, 0x30, 0x78, 0x64,
|
||||
0x64, 0x2c, 0x20, 0x30, 0x78, 0x35, 0x31, 0x2c,
|
||||
0x20, 0x30, 0x78, 0x61, 0x32, 0x2c, 0x20, 0x30,
|
||||
0x78, 0x33, 0x33, 0x2c, 0x20, 0x30, 0x78, 0x37,
|
||||
0x35, 0x2c, 0x20, 0x30, 0x78, 0x37, 0x34, 0x2c,
|
||||
0x20, 0x30, 0x78, 0x36, 0x39, 0x2c, 0x20, 0x30,
|
||||
0x78, 0x36, 0x63, 0x2c, 0x20, 0x0a, 0x09, 0x20,
|
||||
0x20, 0x30, 0x78, 0x37, 0x33, 0x2c, 0x20, 0x30,
|
||||
0x78, 0x32, 0x65, 0x2c, 0x20, 0x30, 0x78, 0x36,
|
||||
0x33, 0x2c, 0x20, 0x30, 0x78, 0x30, 0x30, 0x2c,
|
||||
0x20, 0x30, 0x78, 0x33, 0x31, 0x2c, 0x20, 0x30,
|
||||
0x78, 0x33, 0x31, 0x2c, 0x20, 0x30, 0x78, 0x33,
|
||||
0x30, 0x2c, 0x20, 0x30, 0x78, 0x33, 0x37, 0x2c,
|
||||
0x20, 0x0a, 0x09, 0x20, 0x20, 0x30, 0x78, 0x32,
|
||||
0x30, 0x2c, 0x20, 0x30, 0x78, 0x33, 0x35, 0x2c,
|
||||
0x20, 0x30, 0x78, 0x33, 0x37, 0x2c, 0x20, 0x30,
|
||||
0x78, 0x33, 0x30, 0x2c, 0x20, 0x30, 0x78, 0x33,
|
||||
0x30, 0x2c, 0x20, 0x30, 0x78, 0x33, 0x30, 0x2c,
|
||||
0x20, 0x30, 0x78, 0x33, 0x35, 0x2c, 0x20, 0x30,
|
||||
0x78, 0x33, 0x36, 0x2c, 0x20, 0x0a, 0x09, 0x20,
|
||||
0x20, 0x30, 0x78, 0x33, 0x31, 0x2c, 0x20, 0x30,
|
||||
0x78, 0x33, 0x30, 0x2c, 0x20, 0x30, 0x78, 0x33,
|
||||
0x34, 0x2c, 0x20, 0x30, 0x78, 0x32, 0x30, 0x2c,
|
||||
0x20, 0x30, 0x78, 0x33, 0x18, 0x6a, 0xf8, 0x0e,
|
||||
0xd1, 0x2f, 0x31, 0x2c, 0x20, 0x30, 0x78, 0x33,
|
||||
0x30, 0x2c, 0x20, 0x30, 0x78, 0x33, 0x30, 0x2c,
|
||||
0x20, 0x30, 0x78, 0x33, 0x36, 0x2c, 0x20, 0x0a,
|
||||
0x09, 0x20, 0x20, 0x30, 0x78, 0x33, 0x36, 0x2c,
|
||||
0x20, 0x30, 0x78, 0x33, 0x34, 0x2c, 0x20, 0x30,
|
||||
0x78, 0x32, 0x30, 0x2c, 0x20, 0x30, 0x78, 0x33,
|
||||
0x30, 0x2c, 0x20, 0x30, 0x78, 0x32, 0x30, 0x2c,
|
||||
0x20, 0x30, 0x78, 0x33, 0x30, 0x2c, 0x20, 0x30,
|
||||
0x78, 0x32, 0x30, 0x2c, 0x20, 0x30, 0x78, 0x33,
|
||||
0x30, 0x2c, 0x20, 0x0a, 0x09, 0x20, 0x20, 0x30,
|
||||
0x78, 0x32, 0x30, 0x2c, 0x20, 0x30, 0x78, 0x33,
|
||||
0x30, 0x2c, 0x20, 0x30, 0x78, 0x30, 0x30, 0x2c,
|
||||
0x20, 0x30, 0x78, 0x31, 0x38, 0x2c, 0x20, 0x30,
|
||||
0x78, 0x36, 0x62, 0x2c, 0x20, 0x30, 0x78, 0x63,
|
||||
0x63, 0x2c, 0x20, 0x30, 0x78, 0x38, 0x38, 0x2c,
|
||||
0x20, 0x30, 0x78, 0x38, 0x36, 0x2c, 0x20, 0x0a,
|
||||
0x09, 0x20, 0x20, 0x30, 0x78, 0x31, 0x61, 0x2c,
|
||||
0x20, 0x0a, 0x09, 0x7d, 0x20, 0x3b, 0x0a, 0x73,
|
||||
0x74, 0x61, 0x74, 0x69, 0x63, 0x09, 0x75, 0x5f,
|
||||
0x63, 0x68, 0x61, 0x72, 0x09, 0x41, 0x6d, 0x73,
|
||||
0x67, 0x32, 0x5b, 0x5d, 0x20, 0x3d, 0x20, 0x7b,
|
||||
0x0a, 0x09, 0x20, 0x20, 0x30, 0x78, 0x32, 0x61,
|
||||
0x2c, 0x20, 0x30, 0x78, 0x31, 0x38, 0x2c, 0x20,
|
||||
0x30, 0x78, 0x34, 0x33, 0x2c, 0x20, 0x30, 0x78,
|
||||
0x30, 0x34, 0x2c, 0x20, 0x30, 0x78, 0x30, 0x30,
|
||||
0x2c, 0x20, 0x30, 0x78, 0x30, 0x30, 0x2c, 0x20,
|
||||
0x30, 0x78, 0x30, 0x30, 0x2c, 0x20, 0x30, 0x78,
|
||||
0x30, 0x30, 0x2c, 0x20, 0x0a, 0x09, 0x20, 0x20,
|
||||
0x30, 0x78, 0x64, 0x64, 0x2c, 0x20, 0x30, 0x78,
|
||||
0x35, 0x31, 0x2c, 0x20, 0x30, 0x78, 0x61, 0x32,
|
||||
0x2c, 0x20, 0x30, 0x78, 0x33, 0x33, 0x2c, 0x20,
|
||||
0x30, 0x78, 0x37, 0x35, 0x2c, 0x20, 0x30, 0x78,
|
||||
0x37, 0x34, 0x2c, 0x20, 0x30, 0x78, 0x36, 0x39,
|
||||
0x2c, 0x20, 0x30, 0x78, 0x36, 0x63, 0x2c, 0x20,
|
||||
0x0a, 0x09, 0x20, 0x20, 0x30, 0x78, 0x37, 0x33,
|
||||
0x2c, 0x20, 0x30, 0x78, 0x32, 0x65, 0x2c, 0x20,
|
||||
0x30, 0x78, 0x36, 0x33, 0x2c, 0x20, 0x30, 0x78,
|
||||
0x30, 0x30, 0x2c, 0x20, 0x30, 0x78, 0x33, 0x31,
|
||||
0x2c, 0x20, 0x30, 0x78, 0x33, 0x31, 0x2c, 0x20,
|
||||
0x30, 0x78, 0x33, 0x30, 0x2c, 0x20, 0x30, 0x78,
|
||||
0x33, 0x37, 0x2c, 0x20, 0x0a, 0x09, 0x20, 0x20,
|
||||
0x30, 0x78, 0x32, 0x30, 0x2c, 0x20, 0x30, 0x78,
|
||||
0x33, 0x35, 0x2c, 0x20, 0x30, 0x78, 0x33, 0x37,
|
||||
0x2c, 0x20, 0x30, 0x78, 0x33, 0x30, 0x2c, 0x20,
|
||||
0x30, 0x78, 0x33, 0x30, 0x2c, 0x20, 0x30, 0x78,
|
||||
0x33, 0x30, 0x2c, 0x20, 0x30, 0x78, 0x33, 0x35,
|
||||
0x2c, 0x20, 0x30, 0x78, 0x33, 0x36, 0x2c, 0x20,
|
||||
0x0a, 0x09, 0x20, 0x20, 0x30, 0x78, 0x33, 0x31,
|
||||
0x2c, 0x20, 0x30, 0x78, 0x33, 0x30, 0x2c, 0x20,
|
||||
0x30, 0x78, 0x33, 0x34, 0x2c, 0x20, 0x30, 0x78,
|
||||
0x32, 0x30, 0x2c, 0x20, 0x30, 0x78, 0x33, 0x31,
|
||||
0x2c, 0x20, 0x30, 0x78, 0x33, 0x30, 0x2c, 0x20,
|
||||
0x30, 0x78, 0x33, 0x30, 0x2c, 0x20, 0x30, 0x78,
|
||||
0x33, 0x36, 0x2c, 0x20, 0x0a, 0x09, 0x20, 0x20,
|
||||
0x30, 0x78, 0x33, 0x36, 0x2c, 0x20, 0x30, 0x78,
|
||||
0x33, 0x34, 0x2c, 0x20, 0x30, 0x78, 0x32, 0x30,
|
||||
0x2c, 0x20, 0x30, 0x78, 0x33, 0x30, 0x2c, 0x20,
|
||||
0x30, 0x78, 0x32, 0x30, 0x2c, 0x20, 0x30, 0x78,
|
||||
0x33, 0x30, 0x2c, 0x20, 0x30, 0x78, 0x32, 0x30,
|
||||
0x2c, 0x20, 0x30, 0x78, 0x33, 0x30, 0x2c, 0x20,
|
||||
0x0a, 0x09, 0x20, 0x20, 0x30, 0x78, 0x32, 0x30,
|
||||
0x2c, 0x20, 0x30, 0x78, 0x33, 0x30, 0x2c, 0x20,
|
||||
0x30, 0x78, 0x30, 0x30, 0x2c, 0x20, 0x30, 0x78,
|
||||
0x31, 0x38, 0x2c, 0x20, 0x30, 0x78, 0x36, 0x62,
|
||||
0x2c, 0x20, 0x30, 0x78, 0x63, 0x63, 0x2c, 0x20,
|
||||
0x30, 0x78, 0x38, 0x38, 0x2c, 0x20, 0x30, 0x78,
|
||||
0x38, 0x36, 0x2c, 0x20, 0x0a, 0x09, 0x20, 0x20,
|
||||
0x30, 0x78, 0x31, 0x61, 0x2c, 0x20, 0x0a, 0x09,
|
||||
0x7d, 0x20, 0x3b, 0x0a, 0x73, 0x74, 0x61, 0x74,
|
||||
0x69, 0x63, 0x09, 0x75, 0x5f, 0x63, 0x68, 0x61,
|
||||
0x72, 0x09, 0x41, 0x6d, 0x73, 0x67, 0x33, 0x5b,
|
||||
0x5d, 0x20, 0x3d, 0x20, 0x7b, 0x0a, 0x09, 0x20,
|
||||
0x20, 0x30, 0x78, 0x32, 0x61, 0x2c, 0x20, 0x30,
|
||||
0x78, 0x31, 0x38, 0x2c, 0x20, 0x30, 0x78, 0x34,
|
||||
0x33, 0x2c, 0x20, 0x30, 0x78, 0x30, 0x61, 0x2c,
|
||||
0x20, 0x30, 0x78, 0x30, 0x30, 0x2c, 0x20, 0x30,
|
||||
0x78, 0x30, 0x30, 0x2c, 0x20, 0x30, 0x78, 0x30,
|
||||
0x30, 0x2c, 0x20, 0x30, 0x78, 0x30, 0x30, 0x2c,
|
||||
0x20, 0x0a, 0x09, 0x20, 0x20, 0x30, 0x78, 0x62,
|
||||
0x63, 0x2c, 0x20, 0x30, 0x78, 0x65, 0x66, 0x2c,
|
||||
0x20, 0x30, 0x78, 0x39, 0x32, 0x2c, 0x20, 0x30,
|
||||
0x78, 0x38, 0x63, 0x2c, 0x20, 0x30, 0x78, 0x30,
|
||||
0x61, 0x2c, 0x20, 0x30, 0x78, 0x32, 0x33, 0x2c,
|
||||
0x20, 0x30, 0x78, 0x36, 0x39, 0x2c, 0x20, 0x30,
|
||||
0x78, 0x36, 0x65, 0x2c, 0x20, 0x0a, 0x09, 0x20,
|
||||
0x20, 0x30, 0x78, 0x36, 0x33, 0x2c, 0x20, 0x30,
|
||||
0x78, 0x36, 0x63, 0x2c, 0x20, 0x30, 0x78, 0x37,
|
||||
0x35, 0x2c, 0x20, 0x30, 0x78, 0x36, 0x34, 0x2c,
|
||||
0x20, 0x30, 0x78, 0x36, 0x35, 0x2c, 0x20, 0x30,
|
||||
0x78, 0x32, 0x30, 0x2c, 0x20, 0x30, 0x78, 0x33,
|
||||
0x63, 0x2c, 0x20, 0x30, 0x78, 0x37, 0x33, 0x2c,
|
||||
0x20, 0x0a, 0x09, 0x20, 0x20, 0x30, 0x78, 0x37,
|
||||
0x39, 0x2c, 0x20, 0x30, 0x78, 0x36, 0x33, 0x2c,
|
||||
0x20, 0x30, 0x78, 0x32, 0x66, 0x2c, 0x20, 0x30,
|
||||
0x78, 0x37, 0x34, 0x2c, 0x20, 0x30, 0x78, 0x36,
|
||||
0x35, 0x2c, 0x20, 0x30, 0x78, 0x37, 0x32, 0x2c,
|
||||
0x20, 0x30, 0x78, 0x36, 0x64, 0x2c, 0x20, 0x30,
|
||||
0x78, 0x36, 0x39, 0x2c, 0x20, 0x0a, 0x09, 0x20,
|
||||
0x20, 0x30, 0x78, 0x36, 0x66, 0x2c, 0x20, 0x30,
|
||||
0x78, 0x37, 0x33, 0x2c, 0x20, 0x30, 0x78, 0x32,
|
||||
0x65, 0x2c, 0x20, 0x30, 0x78, 0x36, 0x38, 0x2c,
|
||||
0x20, 0x30, 0x78, 0x33, 0x65, 0x2c, 0x20, 0x30,
|
||||
0x78, 0x30, 0x61, 0x2c, 0x20, 0x30, 0x78, 0x32,
|
||||
0x33, 0x2c, 0x20, 0x30, 0x78, 0x36, 0x39, 0x2c,
|
||||
0x20, 0x0a, 0x09, 0x20, 0x20, 0x30, 0x78, 0x36,
|
||||
0x65, 0x2c, 0x20, 0x30, 0x78, 0x36, 0x33, 0x2c,
|
||||
0x20, 0x30, 0x78, 0x36, 0x63, 0x2c, 0x20, 0x30,
|
||||
0x78, 0x37, 0x35, 0x2c, 0x20, 0x30, 0x78, 0x36,
|
||||
0x34, 0x2c, 0x20, 0x30, 0x78, 0x36, 0x35, 0x2c,
|
||||
0x20, 0x30, 0x78, 0x32, 0x30, 0x2c, 0x20, 0x30,
|
||||
0x78, 0x32, 0x32, 0x2c, 0x20, 0x0a, 0x09, 0x20,
|
||||
0x20, 0x30, 0x78, 0x37, 0x38, 0x2c, 0x20, 0x30,
|
||||
0x78, 0x36, 0x64, 0x2c, 0x20, 0x30, 0x78, 0x36,
|
||||
0x66, 0x2c, 0x20, 0x30, 0x78, 0x36, 0x34, 0x2c,
|
||||
0x20, 0x30, 0x78, 0x36, 0x35, 0x2c, 0x20, 0x30,
|
||||
0x78, 0x36, 0x64, 0x2c, 0x20, 0x30, 0x78, 0x32,
|
||||
0x65, 0x2c, 0x20, 0x30, 0x78, 0x36, 0x38, 0x2c,
|
||||
0x20, 0x0a, 0x09, 0x20, 0x20, 0x30, 0x78, 0x32,
|
||||
0x32, 0x2c, 0x20, 0x30, 0x78, 0x30, 0x61, 0x2c,
|
||||
0x20, 0x30, 0x78, 0x30, 0x61, 0x2c, 0x20, 0x30,
|
||||
0x78, 0x30, 0x61, 0x2c, 0x20, 0x30, 0x78, 0x36,
|
||||
0x39, 0x2c, 0x20, 0x30, 0x78, 0x36, 0x65, 0x2c,
|
||||
0x20, 0x30, 0x78, 0x37, 0x34, 0x2c, 0x20, 0x30,
|
||||
0x78, 0x30, 0x61, 0x2c, 0x20, 0x0a, 0x09, 0x20,
|
||||
0x20, 0x30, 0x78, 0x37, 0x33, 0x2c, 0x20, 0x30,
|
||||
0x78, 0x36, 0x35, 0x2c, 0x20, 0x30, 0x78, 0x36,
|
||||
0x65, 0x2c, 0x20, 0x30, 0x78, 0x36, 0x34, 0x2c,
|
||||
0x20, 0x30, 0x78, 0x34, 0x33, 0x2c, 0x20, 0x30,
|
||||
0x78, 0x36, 0x18, 0x6a, 0x4a, 0xe5, 0x72, 0x71,
|
||||
} ;
|
||||
|
||||
#define E(b) {b, sizeof(b)}
|
||||
static struct {u_char *am; int len} Amsgs[] = {
|
||||
E(Amsg0),
|
||||
E(Amsg1),
|
||||
E(Amsg2),
|
||||
E(Amsg3),
|
||||
E(Amsg4),} ;
|
||||
|
||||
#endif /* TEST */
|
||||
|
||||
/* try to trap uninit. variables */
|
||||
memset(&info,0xa5,sizeof(info)) ;
|
||||
|
||||
info.zrinitflags = CANFDX|CANOVIO|CANBRK|CANFC32 ;
|
||||
info.packetsize = 128 ;
|
||||
info.bufsize = 0 ;
|
||||
|
||||
#ifdef TEST
|
||||
done = ZmodemRInit(&info) ;
|
||||
for(i=0; !done; ++i )
|
||||
done = ZmodemRcv(Amsgs[i].am, Amsgs[i].len, &info) ;
|
||||
|
||||
#else
|
||||
if( argc < 2 )
|
||||
exit(2) ;
|
||||
|
||||
info.ifd = open(argv[1], O_RDWR) ;
|
||||
|
||||
if( info.ifd == -1 )
|
||||
exit(1) ;
|
||||
|
||||
tcgetattr(info.ifd,&old_settings) ;
|
||||
new_settings = old_settings ;
|
||||
|
||||
new_settings.c_iflag &=
|
||||
~(ISTRIP|INLCR|IGNCR|ICRNL|IUCLC|IXON|IXOFF|IMAXBEL) ;
|
||||
new_settings.c_oflag = 0 ;
|
||||
new_settings.c_cflag = B300|CS8|CREAD|CLOCAL ;
|
||||
new_settings.c_lflag = 0 ;
|
||||
new_settings.c_cc[VMIN] = 32 ;
|
||||
new_settings.c_cc[VTIME] = 1 ;
|
||||
tcsetattr(info.ifd,TCSADRAIN, &new_settings) ;
|
||||
|
||||
done = ZmodemRInit(&info) ;
|
||||
|
||||
while(!done)
|
||||
{
|
||||
FD_ZERO(&readfds) ;
|
||||
FD_SET(info.ifd, &readfds) ;
|
||||
timeout.tv_sec = info.timeout ;
|
||||
timeout.tv_usec = 0 ;
|
||||
i = select(info.ifd+1, &readfds,NULL,NULL, &timeout) ;
|
||||
if( i<0 )
|
||||
perror("select") ;
|
||||
else if( i==0 )
|
||||
done = ZmodemTimeout(&info) ;
|
||||
else {
|
||||
len = read(info.ifd, buffer, sizeof(buffer)) ;
|
||||
done = ZmodemRcv(buffer, len, &info) ;
|
||||
}
|
||||
}
|
||||
|
||||
tcsetattr(info.ifd,TCSADRAIN, &old_settings) ;
|
||||
#endif /* TEST */
|
||||
exit(0) ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
int
|
||||
ZXmitStr(buffer, len, info)
|
||||
u_char *buffer ;
|
||||
int len ;
|
||||
ZModem *info ;
|
||||
{
|
||||
int i,j ;
|
||||
u_char c ;
|
||||
extern double drand48() ;
|
||||
|
||||
#ifdef TEST
|
||||
for(i=0; i<len; i += 16)
|
||||
{
|
||||
printf(" ") ;
|
||||
for(j=0; j<16 && i+j<len; ++j)
|
||||
printf("%2.2x ", buffer[i+j]) ;
|
||||
for(; j<16; ++j)
|
||||
printf(" ") ;
|
||||
printf(" |") ;
|
||||
for(j=0; j<16 && i+j<len; ++j)
|
||||
putchar(((c=buffer[i+j]) < 040 || c >= 0177) ? '.' : c ) ;
|
||||
printf("|\n") ;
|
||||
}
|
||||
#else
|
||||
|
||||
#ifdef COMMENT
|
||||
/* TEST: randomly corrupt one out of every 300 bytes */
|
||||
for(i=0; i<len; ++i)
|
||||
if( drand48() < 1./300. ) {
|
||||
fprintf(stderr, "byte %d was %2.2x, is", i, buffer[i]) ;
|
||||
buffer[i] ^= 1<<(lrand48()&7) ;
|
||||
fprintf(stderr, " %2.2x\n", buffer[i]) ;
|
||||
}
|
||||
#endif /* COMMENT */
|
||||
|
||||
if( write(info->ifd, buffer, len) != len )
|
||||
return ZmErrSys ;
|
||||
#endif /* TEST */
|
||||
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ZIFlush(info)
|
||||
ZModem *info ;
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
ZOFlush(info)
|
||||
ZModem *info ;
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
ZStatus(i,j,str)
|
||||
{
|
||||
fprintf(stderr,"status %d=%d\n",i,j) ;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
ZAttn(info)
|
||||
ZModem *info ;
|
||||
{
|
||||
char *ptr ;
|
||||
int i = 0 ;
|
||||
|
||||
for(ptr = info->attn; *ptr != '\0'; ++ptr) {
|
||||
if( *ptr == ATTNBRK )
|
||||
ioctl(info->ifd, TCSBRK, 0) ;
|
||||
else if( *ptr == ATTNPSE )
|
||||
sleep(1) ;
|
||||
else
|
||||
write(info->ifd, ptr, 1) ;
|
||||
}
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
|
||||
FILE *
|
||||
ZOpenFile(name, crc, info)
|
||||
char *name ;
|
||||
u_long crc ;
|
||||
ZModem *info ;
|
||||
{
|
||||
struct stat buf ;
|
||||
int exists ; /* file already exists */
|
||||
static int changeCount = 0 ;
|
||||
char name2[MAXPATHLEN] ;
|
||||
int apnd = 0 ;
|
||||
int f0,f1,f2,f3 ;
|
||||
|
||||
/* TODO: if absolute path, do we want to allow it?
|
||||
* if relative path, do we want to prepend something?
|
||||
*/
|
||||
|
||||
if( *name == '/' ) /* for now, disallow absolute paths */
|
||||
return NULL ;
|
||||
|
||||
if( stat(name, &buf) == 0 )
|
||||
exists = 1 ;
|
||||
else if( errno == ENOENT )
|
||||
exists = 0 ;
|
||||
else
|
||||
return NULL ;
|
||||
|
||||
|
||||
/* if remote end has not specified transfer flags, we can
|
||||
* accept the local definitions
|
||||
*/
|
||||
|
||||
if( f0 == ZCRESUM ) { /* if exists, and we already have it, return */
|
||||
if( exists && buf.st_size == info->len )
|
||||
return NULL ;
|
||||
apnd = 1 ;
|
||||
}
|
||||
|
||||
/* reject if file not found and it most be there (ZMSKNOLOC) */
|
||||
if( !exists && (f1 & ZMSKNOLOC) )
|
||||
return NULL ;
|
||||
|
||||
switch( f1 & ZMMASK ) {
|
||||
case 0: /* Implementation-dependent. In this case, we
|
||||
* reject if file exists (and ZMSKNOLOC not set) */
|
||||
if( exists && !(f1 & ZMSKNOLOC) )
|
||||
return NULL ;
|
||||
break ;
|
||||
|
||||
case ZMNEWL: /* take if newer or longer than file on disk */
|
||||
if( exists && info->date <= buf.st_mtime &&
|
||||
info->len <= buf.st_size )
|
||||
return NULL ;
|
||||
break ;
|
||||
|
||||
case ZMCRC: /* take if different CRC or length */
|
||||
if( exists && info->len == buf.st_size && crc == FileCrc(name) )
|
||||
return NULL ;
|
||||
break ;
|
||||
|
||||
case ZMAPND: /* append */
|
||||
apnd = 1 ;
|
||||
case ZMCLOB: /* unconditional replace */
|
||||
break ;
|
||||
|
||||
case ZMNEW: /* take if newer than file on disk */
|
||||
if( exists && info->date <= buf.st_mtime )
|
||||
return NULL ;
|
||||
break ;
|
||||
|
||||
case ZMDIFF: /* take if different date or length */
|
||||
if( exists && info->date == buf.st_mtime &&
|
||||
info->len == buf.st_size )
|
||||
return NULL ;
|
||||
break ;
|
||||
|
||||
case ZMPROT: /* only if dest does not exist */
|
||||
if( exists )
|
||||
return NULL ;
|
||||
break ;
|
||||
|
||||
case ZMCHNG: /* invent new filename if exists */
|
||||
if( exists ) {
|
||||
while( exists ) {
|
||||
sprintf(name2, "%s_%d", name, changeCount++) ;
|
||||
exists = stat(name2, &buf) == 0 || errno != ENOENT ;
|
||||
}
|
||||
name = name2 ;
|
||||
}
|
||||
break ;
|
||||
}
|
||||
|
||||
/* here if we've decided to accept */
|
||||
if( exists && !apnd && unlink(name) != 0 )
|
||||
return NULL ;
|
||||
|
||||
/* TODO: build directory path if needed */
|
||||
|
||||
return fopen(name, apnd ? "a" : "w") ;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
ZWriteFile(buffer, len, file, info)
|
||||
u_char *buffer ;
|
||||
int len ;
|
||||
FILE *file ;
|
||||
ZModem *info ;
|
||||
{
|
||||
/* TODO: if ZCNL set in info->f0, convert
|
||||
* newlines to local convention
|
||||
*/
|
||||
|
||||
return fwrite(buffer, 1, len, file) == len ? 0 : ZmErrSys ;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
ZCloseFile(info)
|
||||
ZModem *info ;
|
||||
{
|
||||
fclose(info->file) ;
|
||||
chmod(info->filename, info->mode&0777) ;
|
||||
}
|
|
@ -1,327 +0,0 @@
|
|||
#ifndef lint
|
||||
static const char rcsid[] = "$Id: send.c,v 1.2 2001/10/25 23:56:29 efalk Exp $" ;
|
||||
#endif
|
||||
|
||||
|
||||
#define TEST /* standalone test */
|
||||
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include "zmodem.h"
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/termios.h>
|
||||
#include <sys/termio.h> /* define TCSBRK */
|
||||
#include <sys/param.h>
|
||||
|
||||
extern int errno ;
|
||||
|
||||
static u_char zeros[4] = {0,0,0,0} ;
|
||||
|
||||
main(argc,argv)
|
||||
int argc ;
|
||||
char **argv ;
|
||||
{
|
||||
struct termios old_settings, new_settings ;
|
||||
fd_set readfds ;
|
||||
struct timeval timeout ;
|
||||
int i ;
|
||||
int len ;
|
||||
char buffer[1024] ;
|
||||
int done = 0 ;
|
||||
int filecount = 0 ;
|
||||
ZModem info ;
|
||||
|
||||
#ifdef TEST
|
||||
|
||||
static u_char Amsg0[] = {
|
||||
0x43,
|
||||
} ;
|
||||
static u_char Amsg1[] = {
|
||||
0x06, 0x43,
|
||||
} ;
|
||||
static u_char Amsg2[] = {
|
||||
0x06,
|
||||
} ;
|
||||
static u_char Amsg3[] = {
|
||||
0x06,
|
||||
} ;
|
||||
static u_char Amsg4[] = {
|
||||
0x06, 0x43,
|
||||
} ;
|
||||
static u_char Amsg5[] = {
|
||||
0x06, 0x43,
|
||||
} ;
|
||||
static u_char Amsg6[] = {
|
||||
0x06,
|
||||
} ;
|
||||
static u_char Amsg7[] = {
|
||||
0x06,
|
||||
} ;
|
||||
static u_char Amsg8[] = {
|
||||
0x06,
|
||||
} ;
|
||||
static u_char Amsg9[] = {
|
||||
0x06, 0x43,
|
||||
} ;
|
||||
|
||||
|
||||
#define E(b) {b, sizeof(b)}
|
||||
static struct {u_char *bm; int len} Bmsgs[] = {
|
||||
E(Amsg0),
|
||||
E(Amsg1),
|
||||
E(Amsg2),
|
||||
E(Amsg3),
|
||||
E(Amsg4),
|
||||
E(Amsg5),
|
||||
E(Amsg6),
|
||||
E(Amsg7),
|
||||
E(Amsg8),
|
||||
E(Amsg9),} ;
|
||||
|
||||
|
||||
#endif /* TEST */
|
||||
|
||||
/* try to trap uninit. variables */
|
||||
memset(&info,0xa5,sizeof(info)) ;
|
||||
|
||||
info.zsinitflags = 0 ;
|
||||
info.attn = "\17\336" ;
|
||||
info.packetsize = 1024 ;
|
||||
info.windowsize = 4096 ;
|
||||
|
||||
#ifdef TEST
|
||||
done = YmodemTInit(&info) ;
|
||||
for(i=0; !done; ++i )
|
||||
done = ZmodemRcv(Bmsgs[i].bm, Bmsgs[i].len, &info) ;
|
||||
|
||||
done = ZmodemTFile("utils.c","utils.c", 0,0,0,0, 1,0, &info) ;
|
||||
for(; !done; ++i )
|
||||
done = ZmodemRcv(Bmsgs[i].bm, Bmsgs[i].len, &info) ;
|
||||
|
||||
done = ZmodemTFile("foo.c","foo.c", 0,0,0,0, 1,0, &info) ;
|
||||
for(; !done; ++i )
|
||||
done = ZmodemRcv(Bmsgs[i].bm, Bmsgs[i].len, &info) ;
|
||||
|
||||
done = ZmodemTFinish(info) ;
|
||||
|
||||
#else
|
||||
if( argc < 2 )
|
||||
exit(2) ;
|
||||
|
||||
info.ifd = open(argv[1], O_RDWR) ;
|
||||
|
||||
if( info.ifd == -1 )
|
||||
exit(1) ;
|
||||
|
||||
tcgetattr(info.ifd,&old_settings) ;
|
||||
new_settings = old_settings ;
|
||||
|
||||
new_settings.c_iflag &=
|
||||
~(ISTRIP|INLCR|IGNCR|ICRNL|IUCLC|IXON|IXOFF|IMAXBEL) ;
|
||||
new_settings.c_oflag = 0 ;
|
||||
new_settings.c_cflag = B300|CS8|CREAD|CLOCAL ;
|
||||
new_settings.c_lflag = 0 ;
|
||||
new_settings.c_cc[VMIN] = 32 ;
|
||||
new_settings.c_cc[VTIME] = 1 ;
|
||||
tcsetattr(info.ifd,TCSADRAIN, &new_settings) ;
|
||||
|
||||
InitXmit(&info) ;
|
||||
XmitFile("utils.c",1,0,&info) ;
|
||||
#ifdef COMMENT
|
||||
XmitFile("foo",1,0,&info) ;
|
||||
XmitFile("foo.c",1,0,&info) ;
|
||||
XmitFile("raw",1,0,&info) ;
|
||||
#endif /* COMMENT */
|
||||
FinishXmit(&info) ;
|
||||
|
||||
tcsetattr(info.ifd,TCSADRAIN, &old_settings) ;
|
||||
#endif /* TEST */
|
||||
exit(0) ;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
doIO(info)
|
||||
ZModem *info ;
|
||||
{
|
||||
fd_set readfds ;
|
||||
struct timeval timeout ;
|
||||
int i ;
|
||||
int len ;
|
||||
char buffer[1024] ;
|
||||
int done = 0 ;
|
||||
|
||||
while(!done)
|
||||
{
|
||||
FD_ZERO(&readfds) ;
|
||||
FD_SET(info->ifd, &readfds) ;
|
||||
timeout.tv_sec = info->timeout ;
|
||||
timeout.tv_usec = 0 ;
|
||||
i = select(info->ifd+1, &readfds,NULL,NULL, &timeout) ;
|
||||
if( i<0 )
|
||||
perror("select") ;
|
||||
else if( i==0 )
|
||||
done = ZmodemTimeout(info) ;
|
||||
else {
|
||||
len = read(info->ifd, buffer, sizeof(buffer)) ;
|
||||
done = ZmodemRcv(buffer, len, info) ;
|
||||
}
|
||||
}
|
||||
return done ;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
InitXmit(info)
|
||||
ZModem *info ;
|
||||
{
|
||||
int done ;
|
||||
|
||||
done = ZmodemTInit(info) ;
|
||||
if( !done )
|
||||
done = doIO(info) ;
|
||||
|
||||
return done != ZmDone ;
|
||||
}
|
||||
|
||||
|
||||
XmitFile(filename,nfiles,nbytes,info)
|
||||
char *filename ;
|
||||
int nfiles, nbytes ;
|
||||
ZModem *info ;
|
||||
{
|
||||
int done ;
|
||||
|
||||
done = ZmodemTFile(filename,filename, 0,ZMCLOB,0,0,
|
||||
nfiles,nbytes, info) ;
|
||||
if( done == ZmErrCantOpen || done == ZmFileTooLong )
|
||||
return 0 ;
|
||||
|
||||
if( !done )
|
||||
done = doIO(info) ;
|
||||
|
||||
return done != ZmDone ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
FinishXmit(info)
|
||||
ZModem *info ;
|
||||
{
|
||||
int done ;
|
||||
|
||||
done = ZmodemTFinish(info) ;
|
||||
if( !done )
|
||||
done = doIO(info) ;
|
||||
|
||||
return done != ZmDone ;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
ZXmitStr(buffer, len, info)
|
||||
u_char *buffer ;
|
||||
int len ;
|
||||
ZModem *info ;
|
||||
{
|
||||
int i,j ;
|
||||
u_char c ;
|
||||
extern double drand48() ;
|
||||
|
||||
#ifdef TEST
|
||||
for(i=0; i<len; i += 16)
|
||||
{
|
||||
printf(" ") ;
|
||||
for(j=0; j<16 && i+j<len; ++j)
|
||||
printf("%2.2x ", buffer[i+j]) ;
|
||||
for(; j<16; ++j)
|
||||
printf(" ") ;
|
||||
printf(" |") ;
|
||||
for(j=0; j<16 && i+j<len; ++j)
|
||||
putchar(((c=buffer[i+j]) < 040 || c >= 0177) ? '.' : c ) ;
|
||||
printf("|\n") ;
|
||||
}
|
||||
#else
|
||||
|
||||
#ifdef COMMENT
|
||||
/* TEST: randomly corrupt one out of every 300 bytes */
|
||||
for(i=0; i<len; ++i)
|
||||
if( drand48() < 1./300. ) {
|
||||
fprintf(stderr, "byte %d was %2.2x, is", i, buffer[i]) ;
|
||||
buffer[i] ^= 1<<(lrand48()&7) ;
|
||||
fprintf(stderr, " %2.2x\n", buffer[i]) ;
|
||||
}
|
||||
#endif /* COMMENT */
|
||||
|
||||
if( write(info->ifd, buffer, len) != len )
|
||||
return ZmErrSys ;
|
||||
#endif /* TEST */
|
||||
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ZIFlush(info)
|
||||
ZModem *info ;
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
ZOFlush(info)
|
||||
ZModem *info ;
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
ZStatus(i,j,str)
|
||||
{
|
||||
fprintf(stderr,"status %d=%d\n",i,j) ;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
ZAttn(info)
|
||||
ZModem *info ;
|
||||
{
|
||||
char *ptr ;
|
||||
int i = 0 ;
|
||||
|
||||
for(ptr = info->attn; *ptr != '\0'; ++ptr) {
|
||||
if( *ptr == ATTNBRK )
|
||||
ioctl(info->ifd, TCSBRK, 0) ;
|
||||
else if( *ptr == ATTNPSE )
|
||||
sleep(1) ;
|
||||
else
|
||||
write(info->ifd, ptr, 1) ;
|
||||
}
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
|
||||
FILE *
|
||||
ZOpenFile(name, f0,f1,f2,f3, len, date, mode, filesRem, bytesRem, crc)
|
||||
char *name ;
|
||||
int f0,f1,f2,f3, len, mode, filesRem, bytesRem ;
|
||||
long date ;
|
||||
u_long crc ;
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
ZWriteFile()
|
||||
{}
|
||||
|
||||
|
||||
ZCloseFile(info)
|
||||
ZModem *info ;
|
||||
{}
|
||||
|
||||
ZFlowControl(info)
|
||||
ZModem *info ;
|
||||
{}
|
|
@ -1,86 +0,0 @@
|
|||
#ifndef lint
|
||||
static const char rcsid[] = "$Id: seriallog.c,v 1.2 2001/10/25 23:56:29 efalk Exp $" ;
|
||||
#endif
|
||||
|
||||
/* seriallog routines. Write data to log file, tagged with timestamp
|
||||
* and channel.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <signal.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/uio.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include "seriallog.h"
|
||||
|
||||
static struct timeval timestamp = {0,0} ;
|
||||
|
||||
#define DTIME 1500 /* timeout, milliseconds */
|
||||
|
||||
static int which = -1 ; /* last transmitted */
|
||||
|
||||
static char obuf[4096] ;
|
||||
static int olen = -1 ;
|
||||
|
||||
FILE *SerialLogFile = NULL ;
|
||||
|
||||
/* flush out buffered text */
|
||||
|
||||
void
|
||||
SerialLogFlush()
|
||||
{
|
||||
int i ;
|
||||
|
||||
if( SerialLogFile == NULL )
|
||||
return ;
|
||||
|
||||
if( which != -1 && olen > 0 )
|
||||
{
|
||||
i = fwrite((char *)&which, sizeof(int), 1, SerialLogFile) ;
|
||||
i = fwrite((char *)×tamp, sizeof(timestamp), 1, SerialLogFile) ;
|
||||
i = fwrite((char *)&olen, sizeof(int), 1, SerialLogFile) ;
|
||||
i = fwrite(obuf, 1, olen, SerialLogFile) ;
|
||||
}
|
||||
fflush(SerialLogFile) ;
|
||||
|
||||
which = -1 ;
|
||||
olen = 0 ;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
SerialLog(const void *data, int len, int w)
|
||||
{
|
||||
struct timezone z ;
|
||||
struct timeval time ;
|
||||
int dt ;
|
||||
int i ;
|
||||
|
||||
if( SerialLogFile == NULL )
|
||||
return ;
|
||||
|
||||
gettimeofday(&time, &z) ;
|
||||
dt = (time.tv_sec - timestamp.tv_sec)*1000 +
|
||||
(time.tv_usec - timestamp.tv_usec)/1000 ;
|
||||
|
||||
if( w != which || dt > DTIME ) {
|
||||
SerialLogFlush() ;
|
||||
which = w ;
|
||||
timestamp = time ;
|
||||
}
|
||||
|
||||
while( len > 0 )
|
||||
{
|
||||
if( olen+len > sizeof(obuf) )
|
||||
SerialLogFlush() ;
|
||||
|
||||
i = len > sizeof(obuf) ? sizeof(obuf) : len ;
|
||||
bcopy(data, obuf+olen, i) ;
|
||||
olen += i ;
|
||||
len -= i ;
|
||||
}
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
/* $Id: seriallog.h,v 1.2 2001/10/25 23:56:29 efalk Exp $ */
|
||||
|
||||
#ifndef SERIALLOG_H
|
||||
#define SERIALLOG_H
|
||||
|
||||
|
||||
extern FILE *SerialLogFile ;
|
||||
extern void SerialLogFlush() ;
|
||||
extern void SerialLog(const void *data, int len, int w) ;
|
||||
|
||||
#endif
|
|
@ -1,133 +0,0 @@
|
|||
#ifndef lint
|
||||
static const char rcsid[] = "$Id: utils.c,v 1.2 2001/10/25 23:56:29 efalk Exp $" ;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Copyright (c) 1995 by Edward A. Falk
|
||||
*/
|
||||
|
||||
|
||||
/**********
|
||||
*
|
||||
*
|
||||
* @ @ @@@@@ @@@ @ @@@@
|
||||
* @ @ @ @ @ @
|
||||
* @ @ @ @ @ @@@
|
||||
* @ @ @ @ @ @
|
||||
* @@@ @ @@@ @@@@@ @@@@
|
||||
*
|
||||
* UTILS - utilities used by xmodem library.
|
||||
*
|
||||
* Routines provided here:
|
||||
*
|
||||
*
|
||||
* name (args)
|
||||
* Brief description.
|
||||
*
|
||||
* int sendCancel()
|
||||
*
|
||||
* send cancel string <CAN><CAN>
|
||||
*
|
||||
*
|
||||
* int sendFlush(c)
|
||||
* char c ;
|
||||
*
|
||||
* flush input, send one character, return nonzero on error
|
||||
*
|
||||
*
|
||||
* int sendChr(c)
|
||||
* char c ;
|
||||
*
|
||||
* send one character, return nonzero on error
|
||||
*
|
||||
*
|
||||
* int sendStr(str, len)
|
||||
* char *str ;
|
||||
* int len ;
|
||||
*
|
||||
* send string, return nonzero on error
|
||||
*
|
||||
*
|
||||
* int calcChecksum(ptr, count)
|
||||
* char *ptr ;
|
||||
* int count ;
|
||||
*
|
||||
* compute checksum (used by xmodem)
|
||||
*
|
||||
*
|
||||
* Edward A. Falk
|
||||
*
|
||||
* January, 1995
|
||||
*
|
||||
*
|
||||
*
|
||||
**********/
|
||||
|
||||
|
||||
|
||||
|
||||
#include <sys/termios.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include "xmodem.h"
|
||||
|
||||
|
||||
int
|
||||
sendCancel()
|
||||
{
|
||||
return sendFlush(CAN) || sendFlush(CAN) ;
|
||||
}
|
||||
|
||||
|
||||
/* send one character, return nonzero on error */
|
||||
int
|
||||
sendFlush(char c)
|
||||
{
|
||||
/* first, flush input port */
|
||||
/* TODO: caller provide a way to do this? */
|
||||
|
||||
if( xmRfd == -1 )
|
||||
return XmErrNotOpen ;
|
||||
|
||||
/* TODO: caller provides flush */
|
||||
if( ioctl(xmRfd, TCFLSH, TCIFLUSH) == -1 )
|
||||
return XmErrSys ;
|
||||
|
||||
return sendChr(c) ;
|
||||
}
|
||||
|
||||
|
||||
/* send one character, return nonzero on error */
|
||||
|
||||
int
|
||||
sendChr(char c)
|
||||
{
|
||||
/* TODO: caller provide character output func? */
|
||||
if( xmTfd == -1 )
|
||||
return XmErrNotOpen ;
|
||||
|
||||
return write(xmTfd, &c, 1) ==1 ? 0 : XmErrSys ;
|
||||
}
|
||||
|
||||
|
||||
/* send multiple characters, return nonzero on error */
|
||||
|
||||
int
|
||||
sendStr(char *str, int len)
|
||||
{
|
||||
/* TODO: caller provide character output func? */
|
||||
if( xmTfd == -1 )
|
||||
return XmErrNotOpen ;
|
||||
|
||||
return write(xmTfd, str, len) == len ? 0 : XmErrSys ;
|
||||
}
|
||||
|
||||
/* compute checksum */
|
||||
|
||||
int
|
||||
calcChecksum(char *ptr, int count)
|
||||
{
|
||||
register int csum = 0 ;
|
||||
while( --count >= 0 )
|
||||
csum += (u_char) *ptr++ ;
|
||||
return csum & 255 ;
|
||||
}
|
|
@ -1,111 +0,0 @@
|
|||
/* $Id: xmodem.h,v 1.2 2001/10/25 23:56:29 efalk Exp $ */
|
||||
|
||||
#include <sys/param.h>
|
||||
|
||||
|
||||
typedef int bool ;
|
||||
|
||||
typedef enum {
|
||||
Xmodem=0,
|
||||
XmodemCrc=1,
|
||||
WXmodem=2,
|
||||
Ymodem=3,
|
||||
YmodemG=4,
|
||||
} Protocol ;
|
||||
|
||||
|
||||
extern bool xmodem1k ; /* 1k blocks supported */
|
||||
extern bool fileInfo ; /* ymodem: send file attributes? */
|
||||
extern Protocol protocol ;
|
||||
extern int xmTfd ; /* transmit file descriptor */
|
||||
extern int xmRfd ; /* receive file descriptor */
|
||||
|
||||
extern int xmTimeout ; /* timeout, seconds */
|
||||
|
||||
extern char xmDefPath[MAXPATHLEN] ; /* default location (ymodem) */
|
||||
extern char xmFilename[MAXPATHLEN] ; /* current filename */
|
||||
|
||||
/* error code definitions */
|
||||
|
||||
#define XmDone -1 /* done */
|
||||
#define XmErrInt -2 /* internal error */
|
||||
#define XmErrSys -3 /* system error, see errno */
|
||||
#define XmErrNotOpen -4 /* communication channel not open */
|
||||
#define XmErrCantOpen -5 /* can't open file, see errno */
|
||||
#define XmErrInitTo -10 /* transmitter failed to respond to init req. */
|
||||
#define XmErrSequence -11 /* packet received out of sequence */
|
||||
#define XmErrCancel -12 /* cancelled by remote end */
|
||||
#define XmErrRcvTo -13 /* remote end timed out during transfer */
|
||||
|
||||
|
||||
#ifdef __STDC__
|
||||
|
||||
extern int XmodemRInit(char *path, Protocol p) ;
|
||||
/* start receive protocol */
|
||||
extern int XmodemRRcv(char c) ; /* call for each received char. */
|
||||
extern int XmodemRTimeout() ; /* call if xmTimeout expires */
|
||||
extern int XmodemRAbort() ; /* call to abort protocol */
|
||||
|
||||
extern int XmodemTInit(char *path, Protocol p) ;
|
||||
/* start transmit protocol */
|
||||
extern int XmodemTRcv(char c) ; /* call for each received char. */
|
||||
extern int XmodemTTimeout() ; /* call if xmTimeout expires */
|
||||
extern int XmodemTAbort() ; /* call to abort protocol */
|
||||
extern int XmodemTFinish() ; /* call after last file sent (ymodem) */
|
||||
|
||||
#else
|
||||
|
||||
extern int XmodemRInit() ; /* start receive protocol */
|
||||
extern int XmodemRRcv() ; /* call for each received char. */
|
||||
extern int XmodemRTimeout() ; /* call if xmTimeout expires */
|
||||
extern int XmodemRAbort() ; /* call to abort protocol */
|
||||
|
||||
extern int XmodemTInit() ; /* start transmit protocol */
|
||||
extern int XmodemTRcv() ; /* call for each received char. */
|
||||
extern int XmodemTTimeout() ; /* call if xmTimeout expires */
|
||||
extern int XmodemTAbort() ; /* call to abort protocol */
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* INTERNAL */
|
||||
|
||||
#define SOH 1 /* ^A */
|
||||
#define STX 2 /* ^B */
|
||||
#define EOT 4 /* ^D */
|
||||
#define ACK 6 /* ^F */
|
||||
#define DLE 16 /* ^P */
|
||||
#define XON 17 /* ^Q */
|
||||
#define XOFF 19 /* ^S */
|
||||
#define NAK 21 /* ^U */
|
||||
#define SYN 22 /* ^V */
|
||||
#define CAN 24 /* ^X */
|
||||
|
||||
#ifndef False
|
||||
#define False 0
|
||||
#define True 1
|
||||
#endif
|
||||
|
||||
#define MAXERROR 10
|
||||
#define INITTO 10 /* initialization timeout, basic xmodem */
|
||||
#define INITTO2 3 /* initialization timeout */
|
||||
#define PKTTO 5 /* in-packet receive timeout */
|
||||
|
||||
#define MAXPACKET 1024 /* max packet length */
|
||||
|
||||
|
||||
#ifdef __STDC__
|
||||
|
||||
extern int sendCancel(), sendFlush(char),
|
||||
sendChr(char), sendStr(char *,int) ;
|
||||
extern int calcrc(char *ptr, int count) ;
|
||||
extern int calcChecksum(char *ptr, int count) ;
|
||||
|
||||
#else
|
||||
|
||||
extern int sendCancel(), sendFlush(), sendChr(), sendStr() ;
|
||||
extern int calcrc() ;
|
||||
extern int calcChecksum() ;
|
||||
|
||||
#endif
|
|
@ -1,417 +0,0 @@
|
|||
#ifndef lint
|
||||
static const char rcsid[] = "$Id: xmodemr.c,v 1.1.1.1 2001/03/08 00:01:48 efalk Exp $" ;
|
||||
#endif lint
|
||||
|
||||
/*
|
||||
* Copyright (c) 1995 by Edward A. Falk
|
||||
*/
|
||||
|
||||
|
||||
/**********
|
||||
*
|
||||
*
|
||||
* @ @ @ @ @@@ @@@@ @@@@@ @ @ @@@@
|
||||
* @ @ @@ @@ @ @ @ @ @ @@ @@ @ @
|
||||
* @ @ @ @ @ @ @ @ @@@ @ @ @ @@@@
|
||||
* @ @ @ @ @ @ @ @ @ @ @ @ @ @ @
|
||||
* @ @ @ @ @ @@@ @@@@ @@@@@ @ @ @ @ @
|
||||
*
|
||||
* XMODEMR - receiver side of xmodem/ymodem protocol
|
||||
*
|
||||
* Caller sets flags defined in xmodem.h as appropriate.
|
||||
* (default is basic xmodem)
|
||||
*
|
||||
* This code is designed to be called from inside a larger
|
||||
* program, so it is implemented as a state machine where
|
||||
* practical.
|
||||
*
|
||||
*
|
||||
* functions:
|
||||
*
|
||||
* XmodemRInit(char *filename, Protocol p)
|
||||
* Initiate a receive
|
||||
*
|
||||
* XmodemRTimeout()
|
||||
* called after timeout expired
|
||||
*
|
||||
* XmodemRRcv(char c)
|
||||
* called after character received
|
||||
*
|
||||
* XmodemRAbort()
|
||||
* abort transfer
|
||||
*
|
||||
* all functions return 0 on success, 1 on abort
|
||||
*
|
||||
*
|
||||
*
|
||||
* Edward A. Falk
|
||||
*
|
||||
* January, 1995
|
||||
*
|
||||
*
|
||||
*
|
||||
**********/
|
||||
|
||||
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include "xmodem.h"
|
||||
|
||||
|
||||
/* TODO: WXmodem */
|
||||
|
||||
|
||||
bool xmodem1k = False ;
|
||||
Protocol protocol = Xmodem ;
|
||||
int xmTfd = -1 ;
|
||||
int xmRfd = -1 ;
|
||||
|
||||
int xmTimeout = 0 ;
|
||||
|
||||
char xmDefPath[MAXPATHLEN] ;
|
||||
char xmFilename[MAXPATHLEN] ;
|
||||
|
||||
typedef enum {
|
||||
Start, /* waiting to begin */
|
||||
Init, /* sent initial NAK, 'C' or 'W' */
|
||||
Packet, /* receiving a packet */
|
||||
Wait, /* wait for start of next packet */
|
||||
} XmodemState ;
|
||||
|
||||
static bool ymodem ;
|
||||
static XmodemState state = Start ;
|
||||
static int errorCount = 0 ;
|
||||
static int errorCount2 ;
|
||||
static int ignoreCount ;
|
||||
static int eotCount ; /* count EOT's, reject first one */
|
||||
static int inCount ; /* characters received this packet */
|
||||
static int pktLen ; /* length of this packet data */
|
||||
static int pktHdrLen ; /* id, cmpl, checksum or crc */
|
||||
static char packet[MAXPACKET+5], *optr ;
|
||||
static int packetId ; /* id of last received packet */
|
||||
static int packetCount ; /* # packets received */
|
||||
|
||||
static FILE *ofile ; /* output file fd */
|
||||
static int fileLen, fileDate, fileMode ;
|
||||
|
||||
static int XmodemRStart() ;
|
||||
static int processPacket() ;
|
||||
static int rejectPacket() ;
|
||||
static int acceptPacket() ;
|
||||
|
||||
|
||||
int
|
||||
XmodemRInit( char *file, Protocol prot )
|
||||
{
|
||||
int err ;
|
||||
|
||||
state = Start ;
|
||||
protocol = prot ;
|
||||
ymodem = prot == Ymodem || prot == YmodemG ;
|
||||
|
||||
if( ymodem )
|
||||
strcpy(xmDefPath, file) ;
|
||||
else
|
||||
strcpy(xmFilename, file) ;
|
||||
|
||||
eotCount = errorCount = errorCount2 = 0 ;
|
||||
|
||||
if( err=XmodemRStart() )
|
||||
return err ;
|
||||
|
||||
state = Init ;
|
||||
packetId = ymodem ? 255 : 0 ;
|
||||
packetCount = 0 ;
|
||||
|
||||
pktHdrLen = protocol == Xmodem ? 3 : 4 ;
|
||||
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
|
||||
/* send startup character */
|
||||
|
||||
static int
|
||||
XmodemRStart()
|
||||
{
|
||||
static char pchars[5] = {NAK,'C','W','C','C'} ;
|
||||
static int timeouts[5] = {INITTO, INITTO2, INITTO2, INITTO, INITTO} ;
|
||||
char c = pchars[(int)protocol] ;
|
||||
int err ;
|
||||
|
||||
if( err=sendFlush(c) )
|
||||
return err ;
|
||||
|
||||
xmTimeout = timeouts[(int)protocol] ;
|
||||
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
XmodemRRcv(char c)
|
||||
{
|
||||
errorCount = 0 ;
|
||||
|
||||
switch( state ) {
|
||||
case Start: /* shouldn't happen, ignore */
|
||||
if( c == CAN )
|
||||
return XmErrCancel ;
|
||||
break ;
|
||||
|
||||
case Init: /* waiting */
|
||||
case Wait:
|
||||
switch( c ) {
|
||||
case SOH:
|
||||
case STX:
|
||||
pktLen = c == STX ? 1024 : 128 ;
|
||||
inCount = 0 ;
|
||||
optr = packet ;
|
||||
state = Packet ;
|
||||
xmTimeout = PKTTO ;
|
||||
break ;
|
||||
|
||||
case EOT:
|
||||
if( ++eotCount > 1 ) {
|
||||
sendFlush(ACK) ;
|
||||
if( ymodem )
|
||||
return XmodemRInit() ; /* restart protocol */
|
||||
else
|
||||
return XmDone ;
|
||||
}
|
||||
else
|
||||
return rejectPacket() ; /* make xmitter try again */
|
||||
|
||||
case CAN: return XmErrCancel ;
|
||||
|
||||
default: /* ignore all others */
|
||||
if( ++ignoreCount > 1030 ) {
|
||||
ignoreCount = 0 ;
|
||||
return sendFlush(NAK) ;
|
||||
}
|
||||
break ;
|
||||
}
|
||||
break ;
|
||||
|
||||
|
||||
case Packet: /* mid packet */
|
||||
*optr++ = c ;
|
||||
if( ++inCount >= pktLen + pktHdrLen )
|
||||
ProcessPacket() ;
|
||||
break ;
|
||||
}
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
XmodemRTimeout()
|
||||
{
|
||||
if( ++errorCount > MAXERROR )
|
||||
return state == Init ? XmErrInitTo : XmErrRcvTo ;
|
||||
|
||||
switch( state ) {
|
||||
case Start: return -1 ; /* shouldn't happen */
|
||||
case Init:
|
||||
if( ++errorCount2 >= 3 )
|
||||
switch( protocol ) {
|
||||
case WXmodem: protocol = XmodemCrc ; errorCount2 = 0 ; break ;
|
||||
case XmodemCrc: protocol = Xmodem ; pktHdrLen = 3 ; break ;
|
||||
}
|
||||
return XmodemRStart() ;
|
||||
|
||||
case Wait: /* timeout while waiting */
|
||||
case Packet: /* timeout in mid packet */
|
||||
return rejectPacket() ;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
XmodemRAbort()
|
||||
{
|
||||
return sendCancel() ;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
ProcessPacket()
|
||||
{
|
||||
int id = (u_char)packet[0] ;
|
||||
int idc = (u_char)packet[1] ;
|
||||
int i ;
|
||||
|
||||
if( idc != 255-id )
|
||||
return rejectPacket() ;
|
||||
|
||||
if( id == packetId ) /* duplicate */
|
||||
return acceptPacket() ;
|
||||
|
||||
if( id != (packetId+1)%256 ) { /* out of sequence */
|
||||
(void) sendCancel() ;
|
||||
return XmErrSequence ;
|
||||
}
|
||||
|
||||
if( protocol == Xmodem )
|
||||
{
|
||||
/* compute checksum */
|
||||
register int csum = calcChecksum(packet+2, pktLen) ;
|
||||
if( csum != (u_char) packet[2+pktLen] )
|
||||
return rejectPacket() ;
|
||||
}
|
||||
else
|
||||
{
|
||||
int crc0 = (u_char)packet[pktLen+2] << 8 | (u_char)packet[pktLen+3] ;
|
||||
int crc1 = calcrc(packet+2, pktLen) ;
|
||||
if( crc0 != crc1 )
|
||||
return rejectPacket() ;
|
||||
}
|
||||
|
||||
/* it's a good packet */
|
||||
packetId = (packetId+1)%256 ;
|
||||
|
||||
|
||||
/* is this the first packet? */
|
||||
|
||||
if( packetCount == 0 )
|
||||
{
|
||||
if( ymodem )
|
||||
{
|
||||
if( packet[2] == '\0' ) /* last file */
|
||||
{
|
||||
(void) acceptPacket() ;
|
||||
return XmDone ;
|
||||
}
|
||||
|
||||
if( packet[2] == '/' )
|
||||
strcpy(xmFilename, packet+2) ;
|
||||
else {
|
||||
strcpy(xmFilename, xmDefPath) ;
|
||||
strcat(xmFilename, packet+2) ;
|
||||
}
|
||||
|
||||
fileLen = fileDate = fileMode = -1 ;
|
||||
sscanf(packet+2+strlen(packet)+1, "%d %o %o",
|
||||
&fileLen, &fileDate, &fileMode) ;
|
||||
}
|
||||
|
||||
if( (ofile = fopen(xmFilename, "w")) == NULL ) {
|
||||
sendCancel() ;
|
||||
return XmErrCantOpen ;
|
||||
}
|
||||
|
||||
if( ymodem ) {
|
||||
packetCount = 1 ;
|
||||
(void) acceptPacket() ;
|
||||
return sendFlush('C') ;
|
||||
}
|
||||
else
|
||||
state = Packet ;
|
||||
}
|
||||
|
||||
++packetCount ;
|
||||
|
||||
/* TODO: ymodem: if this is last packet, truncate it */
|
||||
if( (i=fwrite(packet+2, 1, pktLen, ofile)) != pktLen )
|
||||
{
|
||||
sendCancel() ;
|
||||
return XmErrSys ;
|
||||
}
|
||||
else
|
||||
return acceptPacket() ;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
rejectPacket()
|
||||
{
|
||||
state = Wait ;
|
||||
xmTimeout = INITTO ;
|
||||
return sendFlush(NAK) ;
|
||||
}
|
||||
|
||||
static int
|
||||
acceptPacket()
|
||||
{
|
||||
state = Wait ;
|
||||
xmTimeout = INITTO ;
|
||||
return sendFlush(ACK) ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifdef COMMENT /* stand-alone testing */
|
||||
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/termios.h>
|
||||
|
||||
|
||||
main(argc,argv)
|
||||
int argc ;
|
||||
char **argv ;
|
||||
{
|
||||
struct termios old_settings, new_settings ;
|
||||
fd_set readfds ;
|
||||
struct timeval timeout ;
|
||||
int i ;
|
||||
int len ;
|
||||
char buffer[1024] ;
|
||||
bool done = False ;
|
||||
|
||||
if( argc < 2 )
|
||||
exit(2) ;
|
||||
|
||||
xmTfd = xmRfd = open(argv[1], O_RDWR) ;
|
||||
|
||||
if( xmTfd == -1 )
|
||||
exit(1) ;
|
||||
|
||||
tcgetattr(xmTfd,&old_settings) ;
|
||||
new_settings = old_settings ;
|
||||
|
||||
new_settings.c_iflag &=
|
||||
~(ISTRIP|INLCR|IGNCR|ICRNL|IUCLC|IXON|IXOFF|IMAXBEL) ;
|
||||
new_settings.c_oflag = 0 ;
|
||||
new_settings.c_cflag = B300|CS8|CREAD|CLOCAL ;
|
||||
new_settings.c_lflag = 0 ;
|
||||
new_settings.c_cc[VMIN] = 32 ;
|
||||
new_settings.c_cc[VTIME] = 1 ;
|
||||
tcsetattr(xmTfd,TCSADRAIN, &new_settings) ;
|
||||
|
||||
|
||||
xmodem1k = 0 ;
|
||||
done = XmodemRInit("foo", XmodemCrc) != 0 ;
|
||||
#ifdef COMMENT
|
||||
xmodem1k = 1 ;
|
||||
done = XmodemRInit("./", Ymodem) != 0 ;
|
||||
#endif /* COMMENT */
|
||||
|
||||
while(!done)
|
||||
{
|
||||
FD_ZERO(&readfds) ;
|
||||
FD_SET(xmTfd, &readfds) ;
|
||||
timeout.tv_sec = xmTimeout ;
|
||||
timeout.tv_usec = 0 ;
|
||||
i = select(xmTfd+1, &readfds,NULL,NULL, &timeout) ;
|
||||
if( i<0 )
|
||||
perror("select") ;
|
||||
else if( i==0 )
|
||||
done = XmodemRTimeout() != 0 ;
|
||||
else {
|
||||
len = read(xmTfd, buffer, sizeof(buffer)) ;
|
||||
for(i=0; !done && i<len; ++i)
|
||||
done = XmodemRRcv(buffer[i]) != 0 ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
tcsetattr(xmTfd,TCSADRAIN, &old_settings) ;
|
||||
exit(0) ;
|
||||
}
|
||||
#endif /* COMMENT */
|
|
@ -1,410 +0,0 @@
|
|||
#ifndef lint
|
||||
static const char rcsid[] = "$Id: xmodemt.c,v 1.2 2001/10/25 23:56:29 efalk Exp $" ;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Copyright (c) 1995 by Edward A. Falk
|
||||
*/
|
||||
|
||||
|
||||
/**********
|
||||
*
|
||||
*
|
||||
* @ @ @ @ @@@ @@@@ @@@@@ @ @ @@@@@
|
||||
* @ @ @@ @@ @ @ @ @ @ @@ @@ @
|
||||
* @ @ @ @ @ @ @ @ @@@ @ @ @ @
|
||||
* @ @ @ @ @ @ @ @ @ @ @ @ @ @
|
||||
* @ @ @ @ @ @@@ @@@@ @@@@@ @ @ @ @
|
||||
*
|
||||
* XMODEMT - transmit side of xmodem protocol
|
||||
*
|
||||
* Caller sets flags defined in xmodem.h as appropriate.
|
||||
* (default is basic xmodem)
|
||||
*
|
||||
* This code is designed to be called from inside a larger
|
||||
* program, so it is implemented as a state machine where
|
||||
* practical.
|
||||
*
|
||||
* functions:
|
||||
*
|
||||
* XmodemTInit(char *filename, Protocol p)
|
||||
* Initiate a receive
|
||||
*
|
||||
* XmodemTTimeout()
|
||||
* called after timeout expired
|
||||
*
|
||||
* XmodemTRcv(char c)
|
||||
* called after character received
|
||||
*
|
||||
* XmodemTFinish()
|
||||
* last file (ymodem)
|
||||
*
|
||||
* XmodemTAbort()
|
||||
* abort transfer
|
||||
*
|
||||
* all functions return 0 on success, 1 on abort
|
||||
*
|
||||
* Edward A. Falk
|
||||
*
|
||||
* January, 1995
|
||||
*
|
||||
*
|
||||
*
|
||||
**********/
|
||||
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include "xmodem.h"
|
||||
|
||||
|
||||
bool fileInfo = False ;
|
||||
|
||||
/* TODO: WXmodem, YmodemG */
|
||||
|
||||
typedef enum {
|
||||
File, /* waiting for initial protocol character */
|
||||
FileWait, /* sent file header, waiting for ACK */
|
||||
Start, /* waiting to begin */
|
||||
Wait, /* sent a packet, waiting for ACK */
|
||||
Eot, /* sent an EOT, waiting for ACK */
|
||||
EndWait, /* sent null filename, waiting for ACK */
|
||||
} XmodemState ;
|
||||
|
||||
static XmodemState state = Start ;
|
||||
static bool ymodem ;
|
||||
static bool useCrc ; /* receiver wants crc */
|
||||
static int pktLen ; /* length of this packet data */
|
||||
static int pktMaxLen ;
|
||||
static char packet[MAXPACKET] ;
|
||||
static char pktHdr[3], pktCrc[2] ;
|
||||
static int packetId ; /* id of last received packet */
|
||||
static int packetCount ; /* # packets received */
|
||||
|
||||
static FILE *ifile = NULL ; /* input file fd */
|
||||
static int fileLen, fileDate, fileMode ;
|
||||
|
||||
static int sendFilename() ;
|
||||
static int sendPacket() ;
|
||||
static int buildPacket() ;
|
||||
static int resendPacket() ;
|
||||
|
||||
|
||||
int
|
||||
XmodemTInit( char *file, Protocol prot )
|
||||
{
|
||||
int err ;
|
||||
|
||||
protocol = prot ;
|
||||
ymodem = prot == Ymodem || prot == YmodemG ;
|
||||
state = ymodem ? File : Start ;
|
||||
|
||||
strcpy(xmFilename, file) ;
|
||||
|
||||
if( (ifile = fopen(xmFilename, "r")) == NULL ) {
|
||||
sendCancel() ;
|
||||
return XmErrCantOpen ;
|
||||
}
|
||||
|
||||
packetId = 1 ;
|
||||
packetCount = 0 ;
|
||||
pktMaxLen = xmodem1k ? 1024 : 128 ;
|
||||
|
||||
xmTimeout = 60 ;
|
||||
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
XmodemTRcv(char c)
|
||||
{
|
||||
if( c == CAN ) {
|
||||
if( ifile != NULL )
|
||||
fclose(ifile) ;
|
||||
return XmErrCancel ;
|
||||
}
|
||||
|
||||
switch( state ) {
|
||||
case File: /* waiting for command, ymodem */
|
||||
switch( c ) {
|
||||
case NAK: useCrc = False ; return sendFilename() ;
|
||||
case 'C': useCrc = True ; return sendFilename() ;
|
||||
}
|
||||
break ;
|
||||
|
||||
case FileWait: /* waiting for filename ACK */
|
||||
switch( c ) {
|
||||
case NAK: return resendPacket() ;
|
||||
case ACK: state = Start ; return 0 ;
|
||||
}
|
||||
|
||||
case Start: /* waiting for command, data */
|
||||
switch( c ) {
|
||||
case NAK: /* wants checksums */
|
||||
if( !ymodem )
|
||||
protocol = Xmodem ;
|
||||
useCrc = False ;
|
||||
return sendPacket() ;
|
||||
|
||||
case 'C': useCrc = True ; return sendPacket() ;
|
||||
|
||||
case 'W':
|
||||
if( !ymodem ) {
|
||||
protocol = WXmodem ;
|
||||
useCrc = True ;
|
||||
/* TODO: WXmodem */
|
||||
}
|
||||
}
|
||||
break ;
|
||||
|
||||
|
||||
case Wait: /* waiting for ACK */
|
||||
switch( c ) {
|
||||
case ACK: return sendPacket() ;
|
||||
case NAK: return resendPacket() ;
|
||||
}
|
||||
break ; /* ignore all other characters */
|
||||
|
||||
case Eot: /* waiting for ACK after EOT */
|
||||
switch( c ) {
|
||||
case ACK: return XmDone ;
|
||||
case NAK: return sendChr(EOT) ;
|
||||
}
|
||||
break ;
|
||||
|
||||
case EndWait: /* waiting for filename ACK */
|
||||
switch( c ) {
|
||||
case NAK: return resendPacket() ;
|
||||
case ACK: return XmDone ;
|
||||
}
|
||||
}
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
static int
|
||||
sendFilename()
|
||||
{
|
||||
int i ;
|
||||
char *ptr ;
|
||||
|
||||
pktLen = 128 ;
|
||||
|
||||
/* TODO: protect against long filenames */
|
||||
strcpy(packet, xmFilename) ;
|
||||
ptr = packet + strlen(packet) + 1 ;
|
||||
/* TODO: get file info */
|
||||
if( fileInfo ) {
|
||||
sprintf(ptr, "%d %o %o %o", 0,0,0100644) ;
|
||||
ptr += strlen(ptr) + 1 ;
|
||||
}
|
||||
|
||||
/* TODO: what if file desc buffer too big? */
|
||||
|
||||
if( ptr > packet+128 )
|
||||
pktLen = 1024 ;
|
||||
|
||||
i = pktLen - (ptr-packet) ;
|
||||
bzero(ptr, i) ;
|
||||
|
||||
state = FileWait ;
|
||||
packetId = 0 ;
|
||||
return buildPacket() ;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
XmodemTFinish()
|
||||
{
|
||||
int i ;
|
||||
char *ptr ;
|
||||
|
||||
pktLen = 128 ;
|
||||
bzero(packet, pktLen) ;
|
||||
|
||||
state = EndWait ;
|
||||
packetId = 0 ;
|
||||
return buildPacket() ;
|
||||
}
|
||||
|
||||
|
||||
static char *bufptr ;
|
||||
static int buflen = 0 ;
|
||||
|
||||
static int
|
||||
sendPacket()
|
||||
{
|
||||
int i ;
|
||||
|
||||
/* This code assumes that a incomplete reads can only happen
|
||||
* after EOF. This will fail with pipes.
|
||||
* TODO: try to make pipes work.
|
||||
*/
|
||||
|
||||
state = Wait ;
|
||||
|
||||
if( buflen > 0 ) /* previous incomplete packet */
|
||||
{
|
||||
memcpy(packet, bufptr, 128) ;
|
||||
bufptr += 128 ;
|
||||
if( buflen < 128 )
|
||||
for(i=buflen; i<128; ++i)
|
||||
packet[i] = 0x1a ;
|
||||
buflen -= 128 ;
|
||||
pktLen = 128 ;
|
||||
return buildPacket() ;
|
||||
}
|
||||
|
||||
if( (i=fread(packet, 1,pktMaxLen, ifile)) <= 0 ) /* EOF */
|
||||
{
|
||||
state = Eot ;
|
||||
return sendChr(EOT) ;
|
||||
}
|
||||
|
||||
else if( i == pktMaxLen ) /* full buffer */
|
||||
{
|
||||
pktLen = i ;
|
||||
return buildPacket() ;
|
||||
}
|
||||
|
||||
buflen = i ;
|
||||
bufptr = packet ;
|
||||
pktLen = 128 ;
|
||||
return buildPacket() ;
|
||||
}
|
||||
|
||||
static int
|
||||
buildPacket()
|
||||
{
|
||||
int i ;
|
||||
|
||||
pktHdr[0] = pktLen == 128 ? SOH : STX ;
|
||||
pktHdr[1] = (char)packetId ;
|
||||
pktHdr[2] = (char)(255-packetId) ;
|
||||
++packetId ;
|
||||
|
||||
if( useCrc ) {
|
||||
i = calcrc(packet, pktLen) ;
|
||||
pktCrc[0] = (char) (i>>8) ;
|
||||
pktCrc[1] = (char) (i & 0xff) ;
|
||||
}
|
||||
else
|
||||
pktCrc[0] = (char) calcChecksum(packet, pktLen) ;
|
||||
|
||||
return resendPacket() ;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
resendPacket()
|
||||
{
|
||||
int i ;
|
||||
|
||||
(i=sendStr(pktHdr, 3)) || (i=sendStr(packet, pktLen)) ||
|
||||
(i=sendStr(pktCrc, useCrc?2:1)) ;
|
||||
return i ;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
XmodemTTimeout()
|
||||
{
|
||||
switch( state ) {
|
||||
case File:
|
||||
case Start:
|
||||
return XmErrInitTo ;
|
||||
case FileWait:
|
||||
case Wait:
|
||||
case Eot:
|
||||
return XmErrRcvTo ;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
XmodemTAbort()
|
||||
{
|
||||
return sendCancel() ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/termios.h>
|
||||
|
||||
|
||||
main(argc,argv)
|
||||
int argc ;
|
||||
char **argv ;
|
||||
{
|
||||
struct termios old_settings, new_settings ;
|
||||
fd_set readfds ;
|
||||
struct timeval timeout ;
|
||||
int i ;
|
||||
int len ;
|
||||
char buffer[1024] ;
|
||||
bool done = False ;
|
||||
int filecount = 0 ;
|
||||
|
||||
if( argc < 2 )
|
||||
exit(2) ;
|
||||
|
||||
xmTfd = xmRfd = open(argv[1], O_RDWR) ;
|
||||
|
||||
if( xmTfd == -1 )
|
||||
exit(1) ;
|
||||
|
||||
tcgetattr(xmTfd,&old_settings) ;
|
||||
new_settings = old_settings ;
|
||||
|
||||
new_settings.c_iflag &=
|
||||
~(ISTRIP|INLCR|IGNCR|ICRNL|IUCLC|IXON|IXOFF|IMAXBEL) ;
|
||||
new_settings.c_oflag = 0 ;
|
||||
new_settings.c_cflag = B300|CS8|CREAD|CLOCAL ;
|
||||
new_settings.c_lflag = 0 ;
|
||||
new_settings.c_cc[VMIN] = 32 ;
|
||||
new_settings.c_cc[VTIME] = 1 ;
|
||||
tcsetattr(xmTfd,TCSADRAIN, &new_settings) ;
|
||||
|
||||
|
||||
xmodem1k = 1 ;
|
||||
done = XmodemTInit("xmodem.h", Ymodem) != 0 ;
|
||||
|
||||
while(!done)
|
||||
{
|
||||
FD_ZERO(&readfds) ;
|
||||
FD_SET(xmTfd, &readfds) ;
|
||||
timeout.tv_sec = xmTimeout ;
|
||||
timeout.tv_usec = 0 ;
|
||||
i = select(xmTfd+1, &readfds,NULL,NULL, &timeout) ;
|
||||
if( i<0 )
|
||||
perror("select") ;
|
||||
else if( i==0 )
|
||||
done = XmodemTTimeout() != 0 ;
|
||||
else {
|
||||
len = read(xmTfd, buffer, sizeof(buffer)) ;
|
||||
for(i=0; !done && i<len; ++i)
|
||||
done = XmodemTRcv(buffer[i]) != 0 ;
|
||||
}
|
||||
if( done ) {
|
||||
switch( ++filecount ) {
|
||||
case 1:
|
||||
done = XmodemTInit("crc.c", Ymodem) != 0 ;
|
||||
break ;
|
||||
case 2:
|
||||
done = XmodemTFinish() ;
|
||||
break ;
|
||||
case 3: break ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
tcsetattr(xmTfd,TCSADRAIN, &old_settings) ;
|
||||
exit(0) ;
|
||||
}
|
|
@ -1,900 +0,0 @@
|
|||
#ifndef lint
|
||||
static const char rcsid[] = "$Id: zmodem.c,v 1.1.1.1 2001/03/08 00:01:48 efalk Exp $" ;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Copyright (c) 1995 by Edward A. Falk
|
||||
*/
|
||||
|
||||
|
||||
/**********
|
||||
*
|
||||
*
|
||||
* @@@@@ @ @ @@@ @@@@ @@@@@ @ @
|
||||
* @ @@ @@ @ @ @ @ @ @@ @@
|
||||
* @ @ @ @ @ @ @ @ @@@ @ @ @
|
||||
* @ @ @ @ @ @ @ @ @ @ @ @
|
||||
* @@@@@ @ @ @ @@@ @@@@ @@@@@ @ @ @
|
||||
*
|
||||
* ZMODEM - main logic parser for zmodem library
|
||||
*
|
||||
*
|
||||
* Routines provided here:
|
||||
*
|
||||
*
|
||||
* name (args)
|
||||
* Brief description.
|
||||
*
|
||||
* int ZmodemRcv(u_char *buffer, int len, ZModem *info)
|
||||
* Call whenever characters are received. If this function
|
||||
* returns ZmDone, previous function has completed successfully,
|
||||
* either call ZmodemTFile() to start next file, or call
|
||||
* ZmodemTFinish() to terminate the session.
|
||||
*
|
||||
*
|
||||
* int
|
||||
* ZmodemTimeout(ZModem *info)
|
||||
* Call whenever the timeout period expires and no
|
||||
* characters have been received.
|
||||
*
|
||||
* int
|
||||
* ZmodemAttention(ZModem *info)
|
||||
* Call whenever the attention sequence has been received
|
||||
* from the remote end. It is safe to call this function
|
||||
* from an interrupt handler.
|
||||
*
|
||||
* int
|
||||
* ZmodemAbort(ZModem *info)
|
||||
* Call to abort transfer. Physical connection remains
|
||||
* open until you close it.
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
* Edward A. Falk
|
||||
*
|
||||
* January, 1995
|
||||
*
|
||||
*
|
||||
*
|
||||
**********/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
/****
|
||||
*
|
||||
* Constants, typedefs, externals, globals, statics, macros, block data
|
||||
*
|
||||
****/
|
||||
|
||||
|
||||
|
||||
/* TODO: sample input before initial send */
|
||||
/* TODO: more intelligent timeout dispatch */
|
||||
/* TODO: read all pending input before sending next data packet out */
|
||||
/* TODO: if received ZDATA while waiting for ZFILE/ZFIN, it's probably
|
||||
leftovers */
|
||||
/* TODO: enable flow control for zmodem, disable for X/YModem */
|
||||
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "zmodem.h"
|
||||
#include "crctab.h"
|
||||
|
||||
static u_char zeros[4] = {0,0,0,0} ;
|
||||
|
||||
|
||||
extern int YrcvChar( char c, register ZModem *info ) ;
|
||||
extern int YrcvTimeout( register ZModem *info ) ;
|
||||
extern void ZIdleStr(u_char *buffer, int len, ZModem *info) ;
|
||||
|
||||
|
||||
/* LEXICAL BOX: handle characters received from remote end.
|
||||
* These may be header, data or noise.
|
||||
*
|
||||
* This section is a finite state machine for parsing headers
|
||||
* and reading input data. The info->chrCount field is effectively
|
||||
* the state variable.
|
||||
*/
|
||||
|
||||
static int FinishChar( char c, register ZModem *info ) ;
|
||||
static int DataChar( u_char c, register ZModem *info ) ;
|
||||
static int HdrChar( u_char c, register ZModem *info ) ;
|
||||
static int IdleChar(u_char c, register ZModem *info) ;
|
||||
extern int YsendChar() ;
|
||||
|
||||
static int ZProtocol(), ZDataReceived() ;
|
||||
|
||||
|
||||
int
|
||||
ZmodemRcv( register u_char *str, int len, register ZModem *info )
|
||||
{
|
||||
register u_char c ;
|
||||
int err ;
|
||||
|
||||
info->rcvlen = len ;
|
||||
|
||||
while( --info->rcvlen >= 0 )
|
||||
{
|
||||
c = *str++ ;
|
||||
|
||||
if( c == CAN ) {
|
||||
if( ++info->canCount >= 5 ) {
|
||||
ZStatus(RmtCancel, 0, NULL) ;
|
||||
return ZmErrCancel ;
|
||||
}
|
||||
}
|
||||
else
|
||||
info->canCount = 0 ;
|
||||
|
||||
if( info->InputState == Ysend ) {
|
||||
if( (err = YsendChar(c, info)) )
|
||||
return err ;
|
||||
}
|
||||
else if( info->InputState == Yrcv ) {
|
||||
if( (err = YrcvChar(c, info)) )
|
||||
return err ;
|
||||
}
|
||||
|
||||
else if( c != XON && c != XOFF )
|
||||
{
|
||||
/* now look at what we have */
|
||||
|
||||
switch( info->InputState )
|
||||
{
|
||||
case Idle:
|
||||
if( (err = IdleChar(c, info)) )
|
||||
return err ;
|
||||
break ;
|
||||
|
||||
case Inhdr:
|
||||
if( (err = HdrChar(c, info)) )
|
||||
return err ;
|
||||
break ;
|
||||
|
||||
case Indata:
|
||||
if( (err = DataChar(c, info)) )
|
||||
return err ;
|
||||
break ;
|
||||
|
||||
case Finish:
|
||||
if( (err = FinishChar(c, info)) )
|
||||
return err ;
|
||||
break ;
|
||||
|
||||
default:
|
||||
break ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/* handle character input while idling
|
||||
* looking for ZPAD-ZDLE sequence which introduces a header
|
||||
*/
|
||||
|
||||
static int
|
||||
IdleChar(u_char c, register ZModem *info)
|
||||
{
|
||||
if( info->chrCount == 0 )
|
||||
{
|
||||
if( c == ZPAD )
|
||||
++info->chrCount ;
|
||||
else if( info->state == Sending && ++info->noiseCount > MaxNoise )
|
||||
info->waitflag = 1 ;
|
||||
else if( info->state == TStart && (c == 'C' || c == 'G' || c == NAK) )
|
||||
{
|
||||
/* switch to ymodem */
|
||||
info->state = YTStart ;
|
||||
info->InputState = Ysend ;
|
||||
info->Protocol = YMODEM ;
|
||||
return YsendChar(c, info) ;
|
||||
}
|
||||
else
|
||||
ZIdleStr(&c, 1, info) ;
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
switch( c ) {
|
||||
case ZPAD:
|
||||
++info->chrCount ;
|
||||
break ;
|
||||
case ZDLE:
|
||||
info->InputState = Inhdr ;
|
||||
info->chrCount=0 ;
|
||||
break ;
|
||||
default:
|
||||
while( --info->chrCount >= 0 )
|
||||
ZIdleStr((u_char *)"*", 1, info) ;
|
||||
info->chrCount = 0 ;
|
||||
break ;
|
||||
}
|
||||
}
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static u_int
|
||||
rcvHex( u_int i, char c )
|
||||
{
|
||||
if( c <= '9' )
|
||||
c -= '0' ;
|
||||
else if( c <= 'F' )
|
||||
c -= 'A'-10 ;
|
||||
else
|
||||
c -= 'a'-10 ;
|
||||
return (i<<4)+c ;
|
||||
}
|
||||
|
||||
/* handle character input in a header */
|
||||
|
||||
static int
|
||||
HdrChar( u_char c, register ZModem *info )
|
||||
{
|
||||
int i ;
|
||||
int crc=0 ;
|
||||
|
||||
if( c == ZDLE ) {
|
||||
info->escape = 1 ;
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
if( info->escape ) {
|
||||
info->escape = 0 ;
|
||||
switch( c ) {
|
||||
case ZRUB0: c = 0177 ; break ;
|
||||
case ZRUB1: c = 0377 ; break ;
|
||||
default: c ^= 0100 ; break ;
|
||||
}
|
||||
}
|
||||
|
||||
if( info->chrCount == 0 ) { /* waiting for format */
|
||||
switch( c ) {
|
||||
case ZHEX:
|
||||
case ZBIN:
|
||||
case ZBIN32:
|
||||
info->DataType = c ;
|
||||
info->chrCount = 1 ;
|
||||
info->crc = (info->DataType != ZBIN32) ? 0 : 0xffffffffL ;
|
||||
memset(info->hdrData,0,sizeof(info->hdrData)) ;
|
||||
break ;
|
||||
default:
|
||||
info->InputState = Idle ;
|
||||
info->chrCount = 0 ;
|
||||
return ZXmitHdrHex(ZNAK, zeros, info) ;
|
||||
}
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
|
||||
switch( info->DataType ) {
|
||||
/* hex header is 14 hex digits, cr, lf. Optional xon is ignored */
|
||||
case ZHEX:
|
||||
if( info->chrCount <= 14 && !isxdigit(c) ) {
|
||||
info->InputState = Idle ;
|
||||
info->chrCount = 0 ;
|
||||
return ZXmitHdrHex(ZNAK, zeros, info) ;
|
||||
}
|
||||
|
||||
if( info->chrCount <= 14 ) {
|
||||
i = (info->chrCount-1)/2 ;
|
||||
info->hdrData[i] = rcvHex(info->hdrData[i], c) ;
|
||||
}
|
||||
|
||||
if( info->chrCount == 16 ) {
|
||||
crc = 0 ;
|
||||
for(i=0; i<7; ++i)
|
||||
crc = updcrc(info->hdrData[i], crc) ;
|
||||
info->InputState = Idle ;
|
||||
info->chrCount = 0 ;
|
||||
if( (crc&0xffff) != 0 )
|
||||
return ZXmitHdrHex(ZNAK, zeros, info) ;
|
||||
else
|
||||
return ZProtocol(info) ;
|
||||
}
|
||||
else
|
||||
++info->chrCount ;
|
||||
break ;
|
||||
|
||||
|
||||
case ZBIN:
|
||||
/* binary header is type, 4 bytes data, 2 bytes CRC */
|
||||
info->hdrData[info->chrCount-1] = c ;
|
||||
info->crc = updcrc(c, info->crc) ;
|
||||
if( ++info->chrCount > 7 ) {
|
||||
info->InputState = Idle ;
|
||||
info->chrCount = 0 ;
|
||||
if( (crc&0xffff) != 0 )
|
||||
return ZXmitHdrHex(ZNAK, zeros, info) ;
|
||||
else
|
||||
return ZProtocol(info) ;
|
||||
}
|
||||
break ;
|
||||
|
||||
|
||||
case ZBIN32:
|
||||
/* binary32 header is type, 4 bytes data, 4 bytes CRC */
|
||||
info->hdrData[info->chrCount-1] = c ;
|
||||
info->crc = UPDC32(c, info->crc) ;
|
||||
if( ++info->chrCount > 9 ) {
|
||||
info->InputState = Idle ;
|
||||
info->chrCount = 0 ;
|
||||
if( info->crc != 0xdebb20e3 ) /* see note below */
|
||||
return ZXmitHdrHex(ZNAK, zeros, info) ;
|
||||
else
|
||||
return ZProtocol(info) ;
|
||||
}
|
||||
break ;
|
||||
}
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
/* handle character input in a data buffer */
|
||||
|
||||
static int
|
||||
DataChar( u_char c, register ZModem *info )
|
||||
{
|
||||
if( c == ZDLE ) {
|
||||
info->escape = 1 ;
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
if( info->escape ) {
|
||||
info->escape = 0 ;
|
||||
switch( c ) {
|
||||
case ZCRCE:
|
||||
case ZCRCG:
|
||||
case ZCRCQ:
|
||||
case ZCRCW:
|
||||
info->PacketType = c ;
|
||||
info->crcCount = (info->DataType == ZBIN32) ? 4 : 2 ;
|
||||
if( info->DataType == ZBIN )
|
||||
info->crc = updcrc(c, info->crc) ;
|
||||
else
|
||||
info->crc = UPDC32(c, info->crc) ;
|
||||
return 0 ;
|
||||
case ZRUB0: c = 0177 ; break ;
|
||||
case ZRUB1: c = 0377 ; break ;
|
||||
default: c ^= 0100 ; break ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
switch( info->DataType ) {
|
||||
/* TODO: are hex data packets ever used? */
|
||||
|
||||
case ZBIN:
|
||||
info->crc = updcrc(c, info->crc) ;
|
||||
if( info->crcCount == 0 )
|
||||
info->buffer[info->chrCount++] = c ;
|
||||
else if( --info->crcCount == 0 ) {
|
||||
return ZDataReceived(info, (info->crc&0xffff) == 0) ;
|
||||
}
|
||||
break ;
|
||||
|
||||
|
||||
case ZBIN32:
|
||||
info->crc = UPDC32(c, info->crc) ;
|
||||
if( info->crcCount == 0 )
|
||||
info->buffer[info->chrCount++] = c ;
|
||||
else if( --info->crcCount == 0 ) {
|
||||
return ZDataReceived(info, info->crc == 0xdebb20e3) ;
|
||||
}
|
||||
break ;
|
||||
}
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
|
||||
/* wait for "OO" */
|
||||
|
||||
static int
|
||||
FinishChar( char c, register ZModem *info )
|
||||
{
|
||||
if( c == 'O' ) {
|
||||
if( ++info->chrCount >= 2 )
|
||||
return ZmDone ;
|
||||
}
|
||||
else
|
||||
info->chrCount = 0 ;
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int ZPF() ;
|
||||
int Ignore() ;
|
||||
int AnswerChallenge() ;
|
||||
int GotAbort() ;
|
||||
int GotCancel() ;
|
||||
int GotCommand() ;
|
||||
int GotStderr() ;
|
||||
int RetDone() ;
|
||||
static int GotCommandData() ;
|
||||
static int GotStderrData() ;
|
||||
|
||||
/* PROTOCOL LOGIC: This section of code handles the actual
|
||||
* protocol. This is also driven by a finite state machine
|
||||
*
|
||||
* State tables are sorted by approximate frequency order to
|
||||
* reduce search time.
|
||||
*/
|
||||
|
||||
/* Extra ZRINIT headers are the receiver trying to resync. */
|
||||
|
||||
|
||||
|
||||
/* If compiling for Send Only or Receive Only, convert table
|
||||
* entries to no-ops so we don't have to link zmodem[rt].o
|
||||
*/
|
||||
|
||||
#if SendOnly
|
||||
#define RStartOps DoneOps
|
||||
#define RSinitWaitOps DoneOps
|
||||
#define RFileNameOps DoneOps
|
||||
#define RCrcOps DoneOps
|
||||
#define RFileOps DoneOps
|
||||
#define RDataOps DoneOps
|
||||
#define RFinishOps DoneOps
|
||||
#define GotFileName Ignore
|
||||
#define ResendCrcReq Ignore
|
||||
#define GotSinitData Ignore
|
||||
#define ResendRpos Ignore
|
||||
#define GotFileData Ignore
|
||||
#define SendRinit Ignore
|
||||
#else
|
||||
extern StateTable RStartOps[] ;
|
||||
extern StateTable RSinitWaitOps[] ;
|
||||
extern StateTable RFileNameOps[] ;
|
||||
extern StateTable RCrcOps[] ;
|
||||
extern StateTable RFileOps[] ;
|
||||
extern StateTable RDataOps[] ;
|
||||
extern StateTable RFinishOps[] ;
|
||||
extern int GotFileName() ;
|
||||
extern int ResendCrcReq() ;
|
||||
extern int GotSinitData() ;
|
||||
extern int ResendRpos() ;
|
||||
extern int GotFileData() ;
|
||||
extern int SendRinit() ;
|
||||
#endif
|
||||
|
||||
#if RcvOnly
|
||||
#define TStartOps DoneOps
|
||||
#define TInitOps DoneOps
|
||||
#define FileWaitOps DoneOps
|
||||
#define CrcWaitOps DoneOps
|
||||
#define SendingOps DoneOps
|
||||
#define SendDoneOps DoneOps
|
||||
#define SendWaitOps DoneOps
|
||||
#define SendEofOps DoneOps
|
||||
#define TFinishOps DoneOps
|
||||
#define SendMoreFileData Ignore
|
||||
#else
|
||||
extern StateTable TStartOps[] ;
|
||||
extern StateTable TInitOps[] ;
|
||||
extern StateTable FileWaitOps[] ;
|
||||
extern StateTable CrcWaitOps[] ;
|
||||
extern StateTable SendingOps[] ;
|
||||
extern StateTable SendDoneOps[] ;
|
||||
extern StateTable SendWaitOps[] ;
|
||||
extern StateTable SendEofOps[] ;
|
||||
extern StateTable TFinishOps[] ;
|
||||
extern int SendMoreFileData() ;
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
static StateTable CommandDataOps[] = {
|
||||
#ifdef COMMENT
|
||||
{ZRQINIT,f,1,1},
|
||||
{ZRINIT,f,1,1},
|
||||
{ZSINIT,f,1,1},
|
||||
{ZACK,f,1,1},
|
||||
{ZFILE,f,1,1},
|
||||
{ZSKIP,f,1,1},
|
||||
{ZNAK,f,1,1},
|
||||
{ZABORT,f,1,1,TFinish},
|
||||
{ZFIN,f,1,1},
|
||||
{ZRPOS,f,1,1},
|
||||
{ZDATA,f,1,1},
|
||||
{ZEOF,f,1,1},
|
||||
{ZFERR,f,1,1,TFinish},
|
||||
{ZCRC,f,1,1},
|
||||
{ZCHALLENGE,f,1,1},
|
||||
{ZCOMPL,f,1,1},
|
||||
{ZCAN,f,1,1},
|
||||
{ZFREECNT,f,1,1},
|
||||
{ZCOMMAND,f,1,1},
|
||||
{ZSTDERR,f,1,1},
|
||||
#endif /* COMMENT */
|
||||
{99,ZPF,0,0,CommandData},
|
||||
} ;
|
||||
|
||||
static StateTable CommandWaitOps[] = {
|
||||
#ifdef COMMENT
|
||||
{ZRQINIT,f,1,1},
|
||||
{ZRINIT,f,1,1},
|
||||
{ZSINIT,f,1,1},
|
||||
{ZACK,f,1,1},
|
||||
{ZFILE,f,1,1},
|
||||
{ZSKIP,f,1,1},
|
||||
{ZNAK,f,1,1},
|
||||
{ZABORT,f,1,1,TFinish},
|
||||
{ZFIN,f,1,1},
|
||||
{ZRPOS,f,1,1},
|
||||
{ZDATA,f,1,1},
|
||||
{ZEOF,f,1,1},
|
||||
{ZFERR,f,1,1,TFinish},
|
||||
{ZCRC,f,1,1},
|
||||
{ZCHALLENGE,f,1,1},
|
||||
{ZCOMPL,f,1,1},
|
||||
{ZCAN,f,1,1},
|
||||
{ZFREECNT,f,1,1},
|
||||
{ZCOMMAND,f,1,1},
|
||||
{ZSTDERR,f,1,1},
|
||||
#endif /* COMMENT */
|
||||
{99,ZPF,0,0,CommandWait},
|
||||
} ;
|
||||
|
||||
static StateTable StderrDataOps[] = {
|
||||
#ifdef COMMENT
|
||||
{ZRQINIT,f,1,1},
|
||||
{ZRINIT,f,1,1},
|
||||
{ZSINIT,f,1,1},
|
||||
{ZACK,f,1,1},
|
||||
{ZFILE,f,1,1},
|
||||
{ZSKIP,f,1,1},
|
||||
{ZNAK,f,1,1},
|
||||
{ZABORT,f,1,1,TFinish},
|
||||
{ZFIN,f,1,1},
|
||||
{ZRPOS,f,1,1},
|
||||
{ZDATA,f,1,1},
|
||||
{ZEOF,f,1,1},
|
||||
{ZFERR,f,1,1,TFinish},
|
||||
{ZCRC,f,1,1},
|
||||
{ZCHALLENGE,f,1,1},
|
||||
{ZCOMPL,f,1,1},
|
||||
{ZCAN,f,1,1},
|
||||
{ZFREECNT,f,1,1},
|
||||
{ZCOMMAND,f,1,1},
|
||||
{ZSTDERR,f,1,1},
|
||||
#endif /* COMMENT */
|
||||
{99,ZPF,0,0,StderrData},
|
||||
} ;
|
||||
|
||||
static StateTable DoneOps[] = {
|
||||
{99,ZPF,0,0,Done},
|
||||
} ;
|
||||
|
||||
|
||||
static StateTable *tables[] = {
|
||||
RStartOps,
|
||||
RSinitWaitOps,
|
||||
RFileNameOps,
|
||||
RCrcOps,
|
||||
RFileOps,
|
||||
RDataOps,
|
||||
RDataOps, /* RDataErr is the same as RData */
|
||||
RFinishOps,
|
||||
|
||||
TStartOps,
|
||||
TInitOps,
|
||||
FileWaitOps,
|
||||
CrcWaitOps,
|
||||
SendingOps,
|
||||
SendWaitOps,
|
||||
SendDoneOps,
|
||||
SendEofOps,
|
||||
TFinishOps,
|
||||
|
||||
CommandDataOps,
|
||||
CommandWaitOps,
|
||||
StderrDataOps,
|
||||
DoneOps,
|
||||
} ;
|
||||
|
||||
|
||||
char *hdrnames[] = {
|
||||
"ZRQINIT",
|
||||
"ZRINIT",
|
||||
"ZSINIT",
|
||||
"ZACK",
|
||||
"ZFILE",
|
||||
"ZSKIP",
|
||||
"ZNAK",
|
||||
"ZABORT",
|
||||
"ZFIN",
|
||||
"ZRPOS",
|
||||
"ZDATA",
|
||||
"ZEOF",
|
||||
"ZFERR",
|
||||
"ZCRC",
|
||||
"ZCHALLENGE",
|
||||
"ZCOMPL",
|
||||
"ZCAN",
|
||||
"ZFREECNT",
|
||||
"ZCOMMAND",
|
||||
"ZSTDERR",
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
/* This function is called (indirectly) by the ZmodemRcv()
|
||||
* function when a full header has been received.
|
||||
*/
|
||||
|
||||
static int
|
||||
ZProtocol( register ZModem *info )
|
||||
{
|
||||
register StateTable *table ;
|
||||
|
||||
zmodemlog("received %s: %2.2x %2.2x %2.2x %2.2x = %lx\n",
|
||||
hdrnames[info->hdrData[0]], info->hdrData[1],
|
||||
info->hdrData[2], info->hdrData[3], info->hdrData[4],
|
||||
ZDec4(info->hdrData+1)) ;
|
||||
|
||||
/* Flags are sent in F3 F2 F1 F0 order. Data is sent in P0 P1 P2 P3 */
|
||||
|
||||
info->timeoutCount = 0 ;
|
||||
info->noiseCount = 0 ;
|
||||
|
||||
table = tables[(int)info->state] ;
|
||||
while( table->type != 99 && table->type != info->hdrData[0] )
|
||||
++table ;
|
||||
|
||||
zmodemlog(" state %s => %s, iflush=%d, oflush=%d, call %x\n",
|
||||
sname(info), sname2(table->newstate), table->IFlush,
|
||||
table->OFlush, table->func) ;
|
||||
|
||||
info->state = table->newstate ;
|
||||
if( table->IFlush ) {info->rcvlen = 0 ; ZIFlush(info) ;}
|
||||
if( table->OFlush ) ZOFlush(info) ;
|
||||
return table->func(info) ;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
ZDataReceived( register ZModem *info, int crcGood )
|
||||
{
|
||||
switch( info->state ) {
|
||||
case RSinitWait: return GotSinitData(info, crcGood) ;
|
||||
case RFileName: return GotFileName(info, crcGood) ;
|
||||
case RData: return GotFileData(info, crcGood) ;
|
||||
case CommandData: return GotCommandData(info, crcGood) ;
|
||||
case StderrData: return GotStderrData(info, crcGood) ;
|
||||
default: return ZPF(info) ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
ZmodemTimeout( register ZModem *info )
|
||||
{
|
||||
/* timed out while waiting for input */
|
||||
|
||||
++info->timeoutCount ;
|
||||
|
||||
zmodemlog("timeout %d [%s]\n", info->timeoutCount, sname(info) ) ;
|
||||
|
||||
switch( info->state ) {
|
||||
/* receive */
|
||||
case RStart: /* waiting for INIT frame from other end */
|
||||
if( info->timeoutCount > 4 )
|
||||
return YmodemRInit(info) ;
|
||||
|
||||
case RSinitWait:
|
||||
case RFileName:
|
||||
if( info->timeout > 0 )
|
||||
ZStatus(SndTimeout, info->timeoutCount, NULL) ;
|
||||
if( info->timeoutCount > 4 )
|
||||
return ZmErrRcvTo ;
|
||||
info->state = RStart ;
|
||||
return SendRinit(info) ;
|
||||
|
||||
case RCrc:
|
||||
case RFile:
|
||||
case RData:
|
||||
ZStatus(SndTimeout, info->timeoutCount, NULL) ;
|
||||
if( info->timeoutCount > 2 ) {
|
||||
info->timeoutCount = 0 ;
|
||||
info->state = RStart ;
|
||||
return SendRinit(info) ;
|
||||
}
|
||||
return info->state == RCrc ? ResendCrcReq(info) : ResendRpos(info) ;
|
||||
|
||||
case RFinish:
|
||||
ZStatus(SndTimeout, info->timeoutCount, NULL) ;
|
||||
return ZmDone ;
|
||||
|
||||
case YRStart:
|
||||
case YRDataWait:
|
||||
case YRData:
|
||||
case YREOF:
|
||||
return YrcvTimeout(info) ;
|
||||
|
||||
/* transmit */
|
||||
case TStart: /* waiting for INIT frame from other end */
|
||||
case TInit: /* sent INIT, waiting for ZACK */
|
||||
case FileWait: /* sent file header, waiting for ZRPOS */
|
||||
case CrcWait: /* sent file crc, waiting for ZRPOS */
|
||||
case SendWait: /* waiting for ZACK */
|
||||
case SendEof: /* sent EOF, waiting for ZACK */
|
||||
case TFinish: /* sent ZFIN, waiting for ZFIN */
|
||||
case YTStart:
|
||||
case YTFile:
|
||||
case YTDataWait:
|
||||
case YTData:
|
||||
case YTEOF:
|
||||
case YTFin:
|
||||
ZStatus(RcvTimeout,0,NULL) ;
|
||||
return ZmErrRcvTo ;
|
||||
|
||||
case Sending: /* sending data subpackets, ready for int */
|
||||
return SendMoreFileData(info) ;
|
||||
|
||||
/* general */
|
||||
case CommandData: /* waiting for command data */
|
||||
case StderrData: /* waiting for stderr data */
|
||||
return ZmErrSndTo ;
|
||||
case CommandWait: /* waiting for command to execute */
|
||||
return ZmErrCmdTo ;
|
||||
case Done:
|
||||
return ZmDone ;
|
||||
default:
|
||||
return 0 ;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
ZmodemAttention( register ZModem *info )
|
||||
{
|
||||
/* attention received from remote end */
|
||||
if( info->state == Sending ) {
|
||||
ZOFlush(info) ;
|
||||
info->interrupt = 1 ;
|
||||
}
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
ZmodemAbort( register ZModem *info )
|
||||
{
|
||||
static u_char canistr[] = {
|
||||
CAN,CAN,CAN,CAN,CAN,CAN,CAN,CAN,8,8,8,8,8,8,8,8,8,8
|
||||
} ;
|
||||
info->state = Done ;
|
||||
ZIFlush(info) ;
|
||||
ZOFlush(info) ;
|
||||
return ZXmitStr(canistr, sizeof(canistr), info) ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* used to completely ignore headers */
|
||||
|
||||
int
|
||||
Ignore( ZModem *info )
|
||||
{
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
|
||||
/* ignore header contents, return ZmDone */
|
||||
|
||||
int
|
||||
RetDone( ZModem *info )
|
||||
{
|
||||
return ZmDone ;
|
||||
}
|
||||
|
||||
|
||||
/* ignore header contents, return ZmErrCancel */
|
||||
|
||||
int
|
||||
GotCancel( ZModem *info )
|
||||
{
|
||||
return ZmErrCancel ;
|
||||
}
|
||||
|
||||
|
||||
/* utility: set up to receive a data packet */
|
||||
|
||||
int
|
||||
dataSetup( register ZModem *info )
|
||||
{
|
||||
info->InputState = Indata ;
|
||||
info->chrCount = 0 ;
|
||||
info->crcCount = 0 ;
|
||||
info->crc = (info->DataType != ZBIN32) ? 0 : 0xffffffffL ;
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
|
||||
/* called when a remote command received. For now, we
|
||||
* refuse to execute commands. Send EPERM and ignore.
|
||||
*/
|
||||
int
|
||||
GotCommand( ZModem *info )
|
||||
{
|
||||
u_char rbuf[4] ;
|
||||
/* TODO: add command capability */
|
||||
|
||||
rbuf[0] = EPERM ;
|
||||
rbuf[1] = rbuf[2] = rbuf[3] = 0 ;
|
||||
return ZXmitHdrHex(ZCOMPL, rbuf, info) ;
|
||||
}
|
||||
|
||||
static int
|
||||
GotCommandData( register ZModem *info )
|
||||
{
|
||||
/* TODO */
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* called when the remote system wants to put something to
|
||||
* stderr
|
||||
*/
|
||||
int
|
||||
GotStderr( register ZModem *info )
|
||||
{
|
||||
info->InputState = Indata ;
|
||||
info->chrCount = 0 ;
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
static int
|
||||
GotStderrData( register ZModem *info )
|
||||
{
|
||||
info->buffer[info->chrCount] = '\0' ;
|
||||
ZStatus(RemoteMessage, info->chrCount, (char *)info->buffer) ;
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* Protocol failure: An unexpected packet arrived. This could
|
||||
* be from many sources, such as old pipelined info finally arriving
|
||||
* or a serial line with echo enabled. Report it and ignore it.
|
||||
*/
|
||||
|
||||
int
|
||||
ZPF( ZModem *info )
|
||||
{
|
||||
info->waitflag = 1 ; /* pause any in-progress transmission */
|
||||
ZStatus(ProtocolErr, info->hdrData[0], NULL) ;
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
AnswerChallenge( register ZModem *info )
|
||||
{
|
||||
return ZXmitHdrHex(ZACK, info->hdrData+1, info) ;
|
||||
}
|
||||
|
||||
int
|
||||
GotAbort( register ZModem *info )
|
||||
{
|
||||
ZStatus(RmtCancel, 0, NULL) ;
|
||||
return ZXmitHdrHex(ZFIN, zeros, info) ;
|
||||
}
|
||||
|
|
@ -1,709 +0,0 @@
|
|||
/* $Id: zmodem.h,v 1.2 2001/10/25 23:56:29 efalk Exp $ */
|
||||
|
||||
#ifndef ZMODEM_H
|
||||
#define ZMODEM_H
|
||||
|
||||
|
||||
/* Master header file for Zmodem protocol driver routines */
|
||||
|
||||
#if 0
|
||||
|
||||
These routines are intended to be incorportated into other programs,
|
||||
and do not constitute a zmodem program by themselves, although a
|
||||
demo zmodem program that uses these routines has been included.
|
||||
|
||||
All information pertaining to a transfer session is kept in a data
|
||||
structure defined by the caller. This makes it possible for the
|
||||
caller to drive multiple simultaneous sessions.
|
||||
|
||||
Caller provides I/O, timing and query routines. Caller remains
|
||||
in control at all times. Typical use is to call these routines
|
||||
from a select(2) loop.
|
||||
|
||||
Overview:
|
||||
|
||||
Transmit files:
|
||||
|
||||
1 Init ZModem structure and open communications channel.
|
||||
2 Call ZmodemTInit() to begin protocol.
|
||||
3 Read characters from remote end and pass them to
|
||||
ZmodemRcv() until ZmodemRcv() returns ZmDone or an error.
|
||||
4 Call ZmodemTFile() to begin transfer of a file.
|
||||
5 Read characters from remote end and pass them to
|
||||
ZmodemRcv() until ZmodemRcv() returns ZmDone or an error.
|
||||
6 repeat steps 4&5 for all files.
|
||||
7 Call ZmodemTFinish() to indicate that all files have been
|
||||
transfered.
|
||||
8 Read characters from remote end and pass them to
|
||||
ZmodemRcv() until ZmodemRcv() returns ZmDone or an error.
|
||||
|
||||
Receive files:
|
||||
|
||||
1 Init ZModem structure and open communications channel.
|
||||
2 Call ZmodemRInit() to begin protocol.
|
||||
3 Read characters from remote end and pass them to
|
||||
ZmodemRcv() until ZmodemRcv() returns ZmDone or an error.
|
||||
|
||||
|
||||
|
||||
In detail:
|
||||
|
||||
1) Create a ZModem structure as defined below and fill it in.
|
||||
|
||||
'ifd', 'ofd' are the file descriptors used for input and output.
|
||||
The interpretation of ifd and ofd is entirely up to the calling
|
||||
routines, since the caller will be providing I/O functions.
|
||||
|
||||
'zrinitflags' is composed of the flags described below.
|
||||
They describe the receive channel capabilities
|
||||
and affect how the protocol will be carried out.
|
||||
Define these to receive files. When sending files, these
|
||||
flags will be defined from the remote end.
|
||||
|
||||
'zsinitflags' is composed of the flags described below.
|
||||
They describe the transmit channel capabilities
|
||||
and affect how the protocol will be carried out.
|
||||
Define these to send files. When receiving files, these
|
||||
flags will be defined from the remote end.
|
||||
|
||||
'attn': For transmit, this is the optional nul-terminated
|
||||
attention string to be sent by the receiver to interrupt the
|
||||
transmission. For example, it might simply contain ^O to flush
|
||||
the buffers, or it might interrupt the sending program. Caller
|
||||
needs to handle this interrupt properly and call ZmodemAttention().
|
||||
|
||||
For receive, this is the optional nul-terminated attention string
|
||||
defined at the remote end. Caller needs to provide a function that
|
||||
can execute this sequence.
|
||||
|
||||
'timeout' is read-only, set by the zmodem package. It is the
|
||||
timeout value in seconds. If this much time passes without
|
||||
anything being received, caller should call the ZmodemTimeout()
|
||||
function. Note that timeout may be zero, in which case the
|
||||
ZTimeout function should be called immediately if no characters
|
||||
are ready to be received.
|
||||
|
||||
'packetsize' is set to the preferred data packet size. Define
|
||||
this when sending files. Recommended length values are 256
|
||||
bytes below 2400 bps, 512 at 2400 bps, and 1024 above 4800 bps
|
||||
or when the data link is known to be relatively error free.
|
||||
Ignored during receive.
|
||||
|
||||
'bufsize' is set to the size of the receive buffer size. Define
|
||||
this when receiving files. When sending files, this will be
|
||||
defined at the other end.
|
||||
|
||||
'windowsize' is used to prevent network connections from
|
||||
buffering too many characters during transmit. Setting
|
||||
'windowsize' to nonzero causes zmodem to request status reports
|
||||
from the receiver during transmit, and to pause if more than
|
||||
this many bytes have been sent but not yet acknowledged. Set
|
||||
to zero to turn off windowing. Ignored during receive.
|
||||
|
||||
Other fields are used to track the internal state of the zmodem
|
||||
driver functions.
|
||||
|
||||
Since this is a source package, you are, of course, free to extend
|
||||
the ZModem structure as you see fit.
|
||||
|
||||
|
||||
2) Define the following functions:
|
||||
|
||||
int
|
||||
ZXmitStr(u_char *str, int len, ZModem *info)
|
||||
Transmit a buffer. Return 0 on success, ZmErrSys on error.
|
||||
|
||||
void
|
||||
ZIFlush(ZModem *info)
|
||||
Flush all unread input on receive channel. Do nothing if
|
||||
this is not possible.
|
||||
|
||||
void
|
||||
ZOFlush(ZModem *info)
|
||||
Flush all buffered but not-yet-transmitted output
|
||||
on transmit channel. Do nothing if this is not possible.
|
||||
|
||||
int
|
||||
ZAttn(ZModem *info)
|
||||
Send attention signal defined in ZModem->attn. Do
|
||||
nothing if this field is NULL. Otherwise, this field
|
||||
is a nul-terminated character string to be
|
||||
transmitted. There are two special characters defined
|
||||
below: ATTNBRK (0335) indicates that a BREAK signal
|
||||
should be sent, and ATTNPSE (0336) represents a
|
||||
1-second pause.
|
||||
|
||||
void
|
||||
ZFlowControl(int onoff, ZModem *info)
|
||||
Turn flow control on or off depending on the onoff flag.
|
||||
|
||||
void
|
||||
ZStatus(int type, int value, char *status)
|
||||
Called to provide status information. Ignore or display
|
||||
at your option. Status string is not static, so copy
|
||||
it if you need it beyond this call. Type is defined
|
||||
below under "ZStatus() types".
|
||||
|
||||
FILE *
|
||||
ZOpenFile(char *name, u_long crc, ZModem *info)
|
||||
|
||||
Called when receiving files, this function decides
|
||||
whether or not to accept the specified file, and
|
||||
if so, opens it for writing and returns the stdio
|
||||
file handle. If this function decides not to accept
|
||||
the file, or cannot open the file, it returns NULL
|
||||
and the remote sender is told to skip this file.
|
||||
|
||||
info->f0-f3 are the transfer flags, described below under
|
||||
"ZFILE transfer flags". These describe the type of
|
||||
transfer desired (binary/ascii), and conditions for the
|
||||
transfer, such as 'transfer if source newer or longer'.
|
||||
|
||||
info->len is the length of the file in bytes. info->date is
|
||||
the last modification date of the file, in seconds since
|
||||
1-jan-1970. info->mode is the unix file mode + 01000000, or
|
||||
zero if not known. info->filesRem and info->bytesRem are the
|
||||
number of files and bytes remaining to be transferred
|
||||
if known, zero otherwise. 'crc' is the file crc-32 value.
|
||||
This is only provided if F1 contains ZMCRC.
|
||||
|
||||
int
|
||||
ZWriteFile(u_char *buffer, int len, FILE *file, ZModem *info)
|
||||
Write a buffer of data to the file. Normally, you would
|
||||
simply call fwrite(buffer, 1, len, file), but you may
|
||||
want to translate line endings, etc. File transfer
|
||||
flags are available as info->f0,f1,f2,f3.
|
||||
|
||||
Return 0 on success, ZmErrSys on failure, with errno
|
||||
describing the failure.
|
||||
|
||||
|
||||
int
|
||||
ZCloseFile(ZModem *info)
|
||||
Close file after successful completion. File modification
|
||||
date and modes should be set at this time.
|
||||
|
||||
void
|
||||
ZIdleStr(u_char *buffer, int len, ZModem *info)
|
||||
Called to pass text that is received out-of-protocol.
|
||||
This function may ignore or display this text at your
|
||||
option.
|
||||
|
||||
|
||||
3) Open the communications channel.
|
||||
|
||||
If possible, this should be a full-duplex channel with full
|
||||
8-bit transmission. Hardware flow control and/or XON/XOFF
|
||||
flow control should be enabled.
|
||||
|
||||
|
||||
4) Call these routines:
|
||||
|
||||
All functions return 0 on success, nonzero on failure. See
|
||||
"error code definitions", below.
|
||||
|
||||
Send:
|
||||
|
||||
int
|
||||
ZmodemTInit(ZModem *info)
|
||||
Begin a Zmodem transmit session.
|
||||
|
||||
int
|
||||
ZmodemRcv(u_char *buffer, int len, ZModem *info)
|
||||
Call whenever characters are received. If this function
|
||||
returns ZmDone, previous function has completed successfully,
|
||||
either call ZmodemTFile() to start next file, or call
|
||||
ZmodemTFinish() to terminate the session.
|
||||
|
||||
int
|
||||
ZmodemTimeout(ZModem *info)
|
||||
Call whenever the timeout period expires and no
|
||||
characters have been received.
|
||||
|
||||
int
|
||||
ZmodemAttention(ZModem *info)
|
||||
Call whenever the attention sequence has been received
|
||||
from the remote end. It is safe to call this function
|
||||
from an interrupt handler.
|
||||
|
||||
int
|
||||
ZmodemTFile(char *filename, char *rfilename,
|
||||
u_char f0,f1,f2,f3, int filesRem, int bytesRem, ZModem *info)
|
||||
Begin transmitting a file. If filename is not NULL,
|
||||
then this function will open it. Otherwise, info->file
|
||||
must point to a stdio stream that is open for input.
|
||||
It is preferable to provide the filename, so that
|
||||
Zmodem can transmit file size and other information.
|
||||
'rfilename' is the filename given to the remote end.
|
||||
This may be the same as filename, the file part of
|
||||
filename, or something else alltogether. 'rfilename'
|
||||
must not be longer than the smallest data packet the
|
||||
remote end might be willing to receive (about 200
|
||||
characters). f0-f3 are transfer flags, see "ZCBIN"
|
||||
below. 'filesRem' and 'bytesRem' are the number of files
|
||||
and bytes remaining to be transmitted, if known; zero if
|
||||
not.
|
||||
|
||||
If 'filename' cannot be accessed, ZmodemTFile() returns
|
||||
ZmErrCantOpen. The link is still established, so you
|
||||
need to either proceed with the next file or call
|
||||
ZmodemTFinish().
|
||||
|
||||
int
|
||||
ZmodemTFinish(ZModem *info)
|
||||
Call after final file transfer has completed successfully.
|
||||
|
||||
int
|
||||
ZmodemAbort(ZModem *info)
|
||||
Call to abort transfer. Physical connection remains
|
||||
open until you close it.
|
||||
|
||||
|
||||
Receive:
|
||||
|
||||
int
|
||||
ZmodemRInit(ZModem *info)
|
||||
Call to get ready to receive first file. This function
|
||||
will inform the sender that we are ready to receive.
|
||||
|
||||
int
|
||||
ZmodemRcv(u_char *buffer, int len, ZModem *info)
|
||||
Call whenever characters are received. If this
|
||||
function returns ZmDone, all file transfers have
|
||||
completed successfully.
|
||||
|
||||
int
|
||||
ZmodemTimeout(ZModem *info)
|
||||
Call whenever the timeout period expires and no
|
||||
characters have been received.
|
||||
|
||||
int
|
||||
ZmodemAbort(ZModem *info)
|
||||
Call to abort transfer.
|
||||
|
||||
Ymodem and Xmodem:
|
||||
|
||||
int YmodemTInit(ZModem *info)
|
||||
int XmodemTInit(ZModem *info)
|
||||
int YmodemRInit(ZModem *info)
|
||||
int XmodemRInit(ZModem *info)
|
||||
Same semantics as ZmodemTInit and ZmodemRInit. It is
|
||||
not normally necessary to call the Ymodem*Init() functions
|
||||
as the Zmodem protocol will automatically switch to Ymodem
|
||||
when needed.
|
||||
|
||||
|
||||
Utility:
|
||||
|
||||
u_long
|
||||
FileCrc(char *name)
|
||||
Return CRC-32 of file.
|
||||
|
||||
5) Return Values:
|
||||
|
||||
ZmDone Done. Proceed with next file or ZmodemTFinish
|
||||
(transmit) or exit (receive).
|
||||
|
||||
ZmErrInt Internal error. Link has been closed.
|
||||
ZmErrSys System error, see errno. Link is closed.
|
||||
ZmErrNotOpen not used.
|
||||
ZmFileTooLong not used.
|
||||
ZmFileCantWrite not used.
|
||||
ZmErrCantOpen Can not open file, see errno. Link is still open.
|
||||
ZmErrInitTo Transmitter failed to respond to init req. Link closed.
|
||||
ZmErrSequence Packet received out of sequence. Link is closed.
|
||||
ZmErrCancel Cancelled by remote end. Link is closed.
|
||||
ZmErrRcvTo Remote end timed out during transfer. Link is closed.
|
||||
ZmErrSndTo Remote end timed out during transfer. Link is closed.
|
||||
ZmErrCmdTo Remote end timed out during transfer. Link is closed.
|
||||
|
||||
Note that "link is closed" means that the remote end is (presumably)
|
||||
no longer operating. The actual communications channel is not
|
||||
closed unless you close it. "Link is still open" means that the
|
||||
remote end is still ready to receive the next file.
|
||||
|
||||
#endif
|
||||
|
||||
/* PARAMETERS
|
||||
*
|
||||
* The following #defines control the behavior of the Zmodem
|
||||
* package. Note that these may be replaced with variables
|
||||
* if you like. For example, "#define DoInitRZ" may be replaced
|
||||
* with "extern int DoInitRz" to use a global variable, or with
|
||||
* "#define DoInitRZ (info->doInitRz)" to use a variable you
|
||||
* add to the ZModem structure.
|
||||
*
|
||||
* It is assumed that the compiler is good enough to optimize
|
||||
* "if( 0 )" and "if( 1 )" cases. If not, you may wish to modify
|
||||
* the source code to use #ifdef instead.
|
||||
*/
|
||||
|
||||
#define DoInitRZ 1 /* send initial "rz\r" when transmitting */
|
||||
#define AllowCommand 0 /* allow remote end to execute commands */
|
||||
#define SendSample 1 /* sender can sample reverse channel */
|
||||
#define SendAttn 1 /* sender can be interrupted with Attn signal */
|
||||
#define ResponseTime 10 /* reasonable response time for sender to
|
||||
* respond to requests from receiver */
|
||||
#define SerialNo 1 /* receiver serial # */
|
||||
#define MaxNoise 64 /* max "noise" characters before transmission
|
||||
* pauses */
|
||||
#define MaxErrs 20 /* Max receive errors before cancel */
|
||||
#define AlwaysSinit 1 /* always send ZSINIT header, even if not
|
||||
* needed, this makes protocol more robust */
|
||||
|
||||
#define SendOnly 0 /* compiles smaller version for send only */
|
||||
#define RcvOnly 0 /* compiles smaller version for receive only */
|
||||
|
||||
/* constants */
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
|
||||
|
||||
|
||||
/* Internal State */
|
||||
|
||||
typedef enum zmstate {
|
||||
/* receive */
|
||||
RStart, /* sent RINIT, waiting for ZFILE or SINIT */
|
||||
RSinitWait, /* got SINIT, waiting for data */
|
||||
RFileName, /* got ZFILE, waiting for filename & info */
|
||||
RCrc, /* got filename, want crc too */
|
||||
RFile, /* got filename, ready to read */
|
||||
RData, /* reading data */
|
||||
RDataErr, /* encountered error, ignoring input */
|
||||
RFinish, /* sent ZFIN, waiting for 'OO' */
|
||||
|
||||
/* transmit */
|
||||
TStart, /* waiting for INIT frame from other end */
|
||||
TInit, /* received INIT, sent INIT, waiting for ZACK */
|
||||
FileWait, /* sent file header, waiting for ZRPOS */
|
||||
CrcWait, /* sent file crc, waiting for ZRPOS */
|
||||
Sending, /* sending data subpackets, ready for int */
|
||||
SendWait, /* waiting for ZACK */
|
||||
SendDone, /* file finished, need to send EOF */
|
||||
SendEof, /* sent EOF, waiting for ZACK */
|
||||
TFinish, /* sent ZFIN, waiting for ZFIN */
|
||||
|
||||
/* general */
|
||||
CommandData, /* waiting for command data */
|
||||
CommandWait, /* waiting for command to execute */
|
||||
StderrData, /* waiting for stderr data */
|
||||
Done,
|
||||
|
||||
/* x/ymodem transmit */
|
||||
YTStart, /* waiting for 'G', 'C' or NAK */
|
||||
YTFile, /* sent filename, waiting for ACK */
|
||||
YTDataWait, /* ready to send data, waiting for 'C' */
|
||||
YTData, /* sent data, waiting for ACK */
|
||||
YTEOF, /* sent eof, waiting for ACK */
|
||||
YTFin, /* sent null filename, waiting for ACK */
|
||||
|
||||
/* x/ymodem receive */
|
||||
YRStart, /* sent 'C', waiting for filename */
|
||||
YRDataWait, /* received filename, waiting for data */
|
||||
YRData, /* receiving filename or data */
|
||||
YREOF /* received first EOT, waiting for 2nd */
|
||||
|
||||
} ZMState ;
|
||||
|
||||
|
||||
|
||||
|
||||
typedef struct {
|
||||
int ifd ; /* input fd, for use by caller's routines */
|
||||
int ofd ; /* output fd, for use by caller's routines */
|
||||
FILE *file ; /* file being transfered */
|
||||
int zrinitflags ; /* receiver capabilities, see below */
|
||||
int zsinitflags ; /* sender capabilities, see below */
|
||||
char *attn ; /* attention string, see below */
|
||||
int timeout ; /* timeout value, in seconds */
|
||||
int bufsize ; /* receive buffer size, bytes */
|
||||
int packetsize ; /* preferred transmit packet size */
|
||||
int windowsize ; /* max window size */
|
||||
|
||||
/* file attributes: read-only */
|
||||
|
||||
int filesRem, bytesRem ;
|
||||
u_char f0,f1,f2,f3 ; /* file flags */
|
||||
int len,mode,fileType ; /* file flags */
|
||||
u_long date ; /* file date */
|
||||
|
||||
/* From here down, internal to Zmodem package */
|
||||
|
||||
ZMState state ; /* protocol internal state */
|
||||
char *filename ; /* filename */
|
||||
char *rfilename ; /* remote filename */
|
||||
int crc32 ; /* use 32-bit crc */
|
||||
int pktLen ; /* length of this packet */
|
||||
int DataType ; /* input data type */
|
||||
int PacketType ; /* type of this packet */
|
||||
int rcvlen ;
|
||||
int chrCount ; /* chars received in current header/buffer */
|
||||
int crcCount ; /* crc characters remaining at end of buffer */
|
||||
int canCount ; /* how many CAN chars received? */
|
||||
int noiseCount ; /* how many noise chars received? */
|
||||
int errorFlush ; /* ignore incoming data because of error */
|
||||
u_char *buffer ; /* data buffer */
|
||||
u_long offset ; /* file offset */
|
||||
u_long lastOffset ; /* last acknowledged offset */
|
||||
u_long zrposOffset ; /* last offset specified w/zrpos */
|
||||
int ylen, bufp ; /* len,location of last Ymodem packet */
|
||||
int fileEof ; /* file eof reached */
|
||||
int packetCount ; /* # packets received */
|
||||
int errCount ; /* how many data errors? */
|
||||
int timeoutCount ; /* how many times timed out? */
|
||||
int windowCount ; /* how much data sent in current window */
|
||||
int atSign ; /* last char was '@' */
|
||||
int lastCR ; /* last char was CR */
|
||||
int escCtrl ; /* other end requests ctrl chars be escaped */
|
||||
int escHibit ; /* other end requests hi bit be escaped */
|
||||
int escape ; /* next character is escaped */
|
||||
int interrupt ; /* received attention signal */
|
||||
int waitflag ; /* next send should wait */
|
||||
/* parser state */
|
||||
enum {Idle, Padding, Inhdr, Indata, Finish, Ysend, Yrcv} InputState ;
|
||||
enum {XMODEM, YMODEM, ZMODEM} Protocol ;
|
||||
u_char hdrData[9] ; /* header type and data */
|
||||
u_char fileFlags[4] ; /* file xfer flags */
|
||||
u_long crc ; /* crc of incoming header/data */
|
||||
enum {Full, StrWindow, SlidingWindow, Segmented} Streaming ;
|
||||
} ZModem ;
|
||||
|
||||
|
||||
/* ZRINIT flags. Describe receiver capabilities */
|
||||
|
||||
#define CANFDX 1 /* Rx is Full duplex */
|
||||
#define CANOVIO 2 /* Rx can overlap I/O */
|
||||
#define CANBRK 4 /* Rx can send a break */
|
||||
#define CANCRY 010 /* Rx can decrypt */
|
||||
#define CANLZW 020 /* Rx can uncompress */
|
||||
#define CANFC32 040 /* Rx can use 32-bit crc */
|
||||
#define ESCCTL 0100 /* Rx needs control chars escaped */
|
||||
#define ESC8 0200 /* Rx needs 8th bit escaped. */
|
||||
|
||||
/* ZSINIT flags. Describe sender capabilities */
|
||||
|
||||
#define TESCCTL 0100 /* Tx needs control chars escaped */
|
||||
#define TESC8 0200 /* Tx needs 8th bit escaped. */
|
||||
|
||||
|
||||
/* ZFILE transfer flags */
|
||||
|
||||
/* F0 */
|
||||
#define ZCBIN 1 /* binary transfer */
|
||||
#define ZCNL 2 /* convert NL to local eol convention */
|
||||
#define ZCRESUM 3 /* resume interrupted file xfer, or append to a
|
||||
growing file. */
|
||||
|
||||
/* F1 */
|
||||
#define ZMNEWL 1 /* transfer if source newer or longer */
|
||||
#define ZMCRC 2 /* transfer if different CRC or length */
|
||||
#define ZMAPND 3 /* append to existing file, if any */
|
||||
#define ZMCLOB 4 /* replace existing file */
|
||||
#define ZMNEW 5 /* transfer if source is newer */
|
||||
#define ZMDIFF 6 /* transfer if dates or lengths different */
|
||||
#define ZMPROT 7 /* protect: transfer only if dest doesn't exist */
|
||||
#define ZMCHNG 8 /* change filename if destination exists */
|
||||
#define ZMMASK 037 /* mask for above. */
|
||||
#define ZMSKNOLOC 0200 /* skip if not present at Rx end */
|
||||
|
||||
/* F2 */
|
||||
#define ZTLZW 1 /* lzw compression */
|
||||
#define ZTRLE 3 /* run-length encoding */
|
||||
|
||||
/* F3 */
|
||||
#define ZCANVHDR 1 /* variable headers ok */
|
||||
#define ZRWOVR 4 /* byte position for receive window override/256 */
|
||||
#define ZXSPARS 64 /* encoding for sparse file ops. */
|
||||
|
||||
|
||||
|
||||
/* ATTN string special characters. All other characters sent verbose */
|
||||
|
||||
#define ATTNBRK '\335' /* send break signal */
|
||||
#define ATTNPSE '\336' /* pause for one second */
|
||||
|
||||
|
||||
/* ZStatus() types */
|
||||
|
||||
#define RcvByteCount 0 /* value is # bytes received */
|
||||
#define SndByteCount 1 /* value is # bytes sent */
|
||||
#define RcvTimeout 2 /* receiver did not respond, aborting */
|
||||
#define SndTimeout 3 /* value is # of consecutive send timeouts */
|
||||
#define RmtCancel 4 /* remote end has cancelled */
|
||||
#define ProtocolErr 5 /* protocol error has occurred, val=hdr */
|
||||
#define RemoteMessage 6 /* message from remote end */
|
||||
#define DataErr 7 /* data error, val=error count */
|
||||
#define FileErr 8 /* error writing file, val=errno */
|
||||
#define FileBegin 9 /* file transfer begins, str=name */
|
||||
#define FileEnd 10 /* file transfer ends, str=name */
|
||||
#define FileSkip 11 /* file being skipped, str=name */
|
||||
|
||||
|
||||
/* error code definitions [O] means link still open */
|
||||
|
||||
#define ZmDone -1 /* done */
|
||||
#define ZmErrInt -2 /* internal error */
|
||||
#define ZmErrSys -3 /* system error, see errno */
|
||||
#define ZmErrNotOpen -4 /* communication channel not open */
|
||||
#define ZmErrCantOpen -5 /* can't open file, see errno [O] */
|
||||
#define ZmFileTooLong -6 /* remote filename too long [O] */
|
||||
#define ZmFileCantWrite -7 /* could not write file, see errno */
|
||||
#define ZmDataErr -8 /* too many data errors */
|
||||
#define ZmErrInitTo -10 /* transmitter failed to respond to init req. */
|
||||
#define ZmErrSequence -11 /* packet received out of sequence */
|
||||
#define ZmErrCancel -12 /* cancelled by remote end */
|
||||
#define ZmErrRcvTo -13 /* remote receiver timed out during transfer */
|
||||
#define ZmErrSndTo -14 /* remote sender timed out during transfer */
|
||||
#define ZmErrCmdTo -15 /* remote command timed out */
|
||||
|
||||
|
||||
/* zmodem-supplied functions: */
|
||||
|
||||
|
||||
extern int ZmodemTInit(ZModem *info) ;
|
||||
extern int ZmodemTFile(char *file, char *rmtname,
|
||||
u_int f0, u_int f1, u_int f2, u_int f3,
|
||||
int filesRem, int bytesRem, ZModem *info) ;
|
||||
extern int ZmodemTFinish(ZModem *info) ;
|
||||
extern int ZmodemAbort(ZModem *info) ;
|
||||
extern int ZmodemRInit(ZModem *info) ;
|
||||
extern int ZmodemRcv(u_char *str, int len, ZModem *info) ;
|
||||
extern int ZmodemTimeout(ZModem *info) ;
|
||||
extern int ZmodemAttention(ZModem *info) ;
|
||||
|
||||
extern int YmodemTInit(ZModem *info) ;
|
||||
extern int XmodemTInit(ZModem *info) ;
|
||||
extern int YmodemRInit(ZModem *info) ;
|
||||
extern int XmodemRInit(ZModem *info) ;
|
||||
|
||||
extern u_long FileCrc(char *name) ;
|
||||
extern char *sname(ZModem *) ;
|
||||
extern char *sname2(ZMState) ;
|
||||
|
||||
#ifdef DEBUG
|
||||
extern FILE *zmodemlogfile ;
|
||||
extern void zmodemlog(const char *, ...) ;
|
||||
#else
|
||||
#define zmodemlog
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
/* caller-supplied functions: */
|
||||
|
||||
|
||||
extern int ZXmitChr(u_char c, ZModem *info) ;
|
||||
extern int ZXmitStr(u_char *str, int len, ZModem *info) ;
|
||||
extern void ZIFlush(ZModem *info) ;
|
||||
extern void ZOFlush(ZModem *info) ;
|
||||
extern int ZAttn(ZModem *info) ;
|
||||
extern void ZStatus(int type, int value, char *status) ;
|
||||
extern FILE *ZOpenFile(char *name, u_long crc, ZModem *info) ;
|
||||
|
||||
|
||||
/* From here on down, internal to Zmodem package */
|
||||
|
||||
|
||||
/* ZModem character definitions */
|
||||
|
||||
#define ZDLE 030 /* zmodem escape is CAN */
|
||||
#define ZPAD '*' /* pad */
|
||||
#define ZBIN 'A' /* introduces 16-bit crc binary header */
|
||||
#define ZHEX 'B' /* introduces 16-bit crc hex header */
|
||||
#define ZBIN32 'C' /* introduces 32-bit crc binary header */
|
||||
#define ZBINR32 'D' /* introduces RLE packed binary frame w/32-bit crc */
|
||||
#define ZVBIN 'a' /* alternate ZBIN */
|
||||
#define ZVHEX 'b' /* alternate ZHEX */
|
||||
#define ZVBIN32 'c' /* alternate ZBIN32 */
|
||||
#define ZVBINR32 'd' /* alternate ZBINR32 */
|
||||
#define ZRESC 0177 /* RLE flag/escape character */
|
||||
|
||||
|
||||
|
||||
/* ZModem header type codes */
|
||||
|
||||
#define ZRQINIT 0 /* request receive init */
|
||||
#define ZRINIT 1 /* receive init */
|
||||
#define ZSINIT 2 /* send init sequence, define Attn */
|
||||
#define ZACK 3 /* ACK */
|
||||
#define ZFILE 4 /* file name, from sender */
|
||||
#define ZSKIP 5 /* skip file command, from receiver */
|
||||
#define ZNAK 6 /* last packet was garbled */
|
||||
#define ZABORT 7 /* abort */
|
||||
#define ZFIN 8 /* finish session */
|
||||
#define ZRPOS 9 /* resume file from this position, from receiver */
|
||||
#define ZDATA 10 /* data packets to follow, from sender */
|
||||
#define ZEOF 11 /* end of file, from sender */
|
||||
#define ZFERR 12 /* fatal i/o error, from receiver */
|
||||
#define ZCRC 13 /* request for file crc, from receiver */
|
||||
#define ZCHALLENGE 14 /* "send this number back to me", from receiver */
|
||||
#define ZCOMPL 15 /* request is complete */
|
||||
#define ZCAN 16 /* other end cancelled with CAN-CAN-CAN-CAN-CAN */
|
||||
#define ZFREECNT 17 /* request for free bytes on filesystem */
|
||||
#define ZCOMMAND 18 /* command, from sending program */
|
||||
#define ZSTDERR 19 /* output this message to stderr */
|
||||
|
||||
|
||||
/* ZDLE escape sequences */
|
||||
|
||||
|
||||
#define ZCRCE 'h' /* CRC next, frame ends, header follows */
|
||||
#define ZCRCG 'i' /* CRC next, frame continues nonstop */
|
||||
#define ZCRCQ 'j' /* CRC next, send ZACK, frame continues nonstop */
|
||||
#define ZCRCW 'k' /* CRC next, send ZACK, frame ends */
|
||||
#define ZRUB0 'l' /* translate to 0177 */
|
||||
#define ZRUB1 'm' /* translate to 0377 */
|
||||
|
||||
|
||||
/* ascii definitions */
|
||||
|
||||
#define SOH 1 /* ^A */
|
||||
#define STX 2 /* ^B */
|
||||
#define EOT 4 /* ^D */
|
||||
#define ACK 6 /* ^F */
|
||||
#define DLE 16 /* ^P */
|
||||
#define XON 17 /* ^Q */
|
||||
#define XOFF 19 /* ^S */
|
||||
#define NAK 21 /* ^U */
|
||||
#define SYN 22 /* ^V */
|
||||
#define CAN 24 /* ^X */
|
||||
|
||||
|
||||
|
||||
extern int ZXmitHdr() ;
|
||||
extern int ZXmitHdrHex() ;
|
||||
extern int ZXmitHdrBin() ;
|
||||
extern int ZXmitHdrBin32() ;
|
||||
extern u_char *putZdle( u_char *ptr, u_char c, ZModem *info ) ;
|
||||
|
||||
extern u_char *ZEnc4() ;
|
||||
extern u_long ZDec4() ;
|
||||
|
||||
|
||||
/* state table entry. There is one row of the table per
|
||||
* possible state. Each row is a row of all reasonable
|
||||
* inputs for this state. The entries are sorted so that
|
||||
* the most common inputs occur first, to reduce search time
|
||||
* Unexpected input is reported and ignored, as it might be
|
||||
* caused by echo or something.
|
||||
*
|
||||
* Extra ZRINIT headers are the receiver trying to resync.
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
int type ; /* frame type */
|
||||
int (*func)() ; /* transition function */
|
||||
int IFlush ; /* flag: flush input first */
|
||||
int OFlush ; /* flag: flush output first */
|
||||
ZMState newstate ; /* new state. May be overridden by func */
|
||||
} StateTable ;
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
|
@ -1,582 +0,0 @@
|
|||
#ifndef lint
|
||||
static const char rcsid[] = "$Id: zmodemdump.c,v 1.2 2001/10/25 23:56:29 efalk Exp $" ;
|
||||
#endif
|
||||
|
||||
|
||||
/* variation on serialmon companion program serialdump, which
|
||||
* interprets data as a zmodem dialog
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <signal.h>
|
||||
#include <time.h>
|
||||
#include <sys/termios.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "crctab.h"
|
||||
|
||||
#define MAXBUF 2048
|
||||
#define MAXLINE 16
|
||||
#define MAXHBUF 128
|
||||
#define OLINELEN (MAXLINE*2)
|
||||
|
||||
#define CAN 030
|
||||
#define XON 021
|
||||
|
||||
#define ZDLE 030
|
||||
#define ZPAD '*'
|
||||
#define ZBIN 'A'
|
||||
#define ZHEX 'B'
|
||||
#define ZBIN32 'C'
|
||||
#define ZBINR32 'D'
|
||||
#define ZVBIN 'a'
|
||||
#define ZVHEX 'b'
|
||||
#define ZVBIN32 'c'
|
||||
#define ZVBINR32 'd'
|
||||
#define ZRESC 0177
|
||||
|
||||
|
||||
#define ZRQINIT 0 /* request receive init */
|
||||
#define ZRINIT 1 /* receive init */
|
||||
#define ZSINIT 2 /* send init sequence, define Attn */
|
||||
#define ZACK 3 /* ACK */
|
||||
#define ZFILE 4 /* file name, from sender */
|
||||
#define ZSKIP 5 /* skip file command, from receiver */
|
||||
#define ZNAK 6 /* last packet was garbled */
|
||||
#define ZABORT 7 /* abort */
|
||||
#define ZFIN 8 /* finish session */
|
||||
#define ZRPOS 9 /* resume file from this position, from receiver */
|
||||
#define ZDATA 10 /* data packets to follow, from sender */
|
||||
#define ZEOF 11 /* end of file, from sender */
|
||||
#define ZFERR 12 /* fatal i/o error, from receiver */
|
||||
#define ZCRC 13 /* request for file crc, from receiver */
|
||||
#define ZCHALLENGE 14 /* "send this number back to me", from receiver */
|
||||
#define ZCOMPL 15 /* request is complete */
|
||||
#define ZCAN 16 /* other end cancelled with CAN-CAN-CAN-CAN-CAN */
|
||||
#define ZFREECNT 17 /* request for free bytes on filesystem */
|
||||
#define ZCOMMAND 18 /* command, from sending program */
|
||||
#define ZSTDERR 19 /* output this message to stderr */
|
||||
|
||||
#define ZCRCE 'h'
|
||||
#define ZCRCG 'i'
|
||||
#define ZCRCQ 'j'
|
||||
#define ZCRCW 'k'
|
||||
#define ZRUB0 'l'
|
||||
#define ZRUB1 'm'
|
||||
|
||||
typedef enum {Idle, Padding, HexHeader, Header16, Header32,
|
||||
InData, InCrc} ZState ;
|
||||
|
||||
typedef struct {
|
||||
ZState state ;
|
||||
int headertype ;
|
||||
int data[4] ;
|
||||
int crcBytes[4] ;
|
||||
int count ;
|
||||
int zdlePend ; /* ZDLE received */
|
||||
int crcCmd ;
|
||||
int crclen ;
|
||||
u_long crc ;
|
||||
} Zinfo ;
|
||||
|
||||
u_char buffer[MAXBUF] ;
|
||||
u_char line[MAXLINE] ;
|
||||
u_char hbuffer[MAXHBUF] ;
|
||||
int linecnt = 0 ;
|
||||
int hbufcnt = 0 ;
|
||||
|
||||
|
||||
main( int argc, char **argv )
|
||||
{
|
||||
int i,j ;
|
||||
int len ;
|
||||
int which ;
|
||||
struct timeval timestamp, oldtime ;
|
||||
struct tm *tm ;
|
||||
|
||||
Zinfo Ainfo, Binfo ;
|
||||
|
||||
printf("serial log. 'A' is application, 'B' is serial port\n\n") ;
|
||||
|
||||
oldtime.tv_sec = 0 ;
|
||||
|
||||
Ainfo.state = Binfo.state = Idle ;
|
||||
Ainfo.zdlePend = Binfo.zdlePend = 0 ;
|
||||
|
||||
while( (i=fread((char *)&which, sizeof(which), 1, stdin)) > 0 )
|
||||
{
|
||||
i = fread((char *)×tamp, sizeof(timestamp), 1, stdin) ;
|
||||
i = fread((char *)&len, sizeof(len), 1, stdin) ;
|
||||
if( timestamp.tv_sec != oldtime.tv_sec ||
|
||||
timestamp.tv_usec != oldtime.tv_usec )
|
||||
{
|
||||
if( linecnt > 0 )
|
||||
dumpLine() ;
|
||||
|
||||
tm = localtime(×tamp.tv_sec) ;
|
||||
printf("%c: %2d:%2.2d:%2.2d.%2.2d\n", 'A'+which,
|
||||
tm->tm_hour,tm->tm_min,tm->tm_sec, timestamp.tv_usec/10000 ) ;
|
||||
|
||||
oldtime = timestamp ;
|
||||
}
|
||||
|
||||
|
||||
while( len > 0 )
|
||||
{
|
||||
i = MAXBUF ;
|
||||
if( len < i ) i = len ;
|
||||
j = fread(buffer, 1, i, stdin) ;
|
||||
assert(j <= MAXBUF) ;
|
||||
len -= j ;
|
||||
parseData(which ? &Binfo : &Ainfo, j) ;
|
||||
}
|
||||
|
||||
while( len > 0 )
|
||||
{
|
||||
i = MAXLINE - linecnt ;
|
||||
if( len < i ) i = len ;
|
||||
assert(linecnt+i <= MAXLINE) ;
|
||||
j = fread(line+linecnt, 1, i, stdin) ;
|
||||
assert(linecnt+j <= MAXLINE) ;
|
||||
len -= j ;
|
||||
linecnt += j ;
|
||||
if( linecnt >= MAXLINE )
|
||||
dumpLine() ;
|
||||
}
|
||||
}
|
||||
if( linecnt > 0 )
|
||||
dumpLine() ;
|
||||
|
||||
exit(0) ;
|
||||
}
|
||||
|
||||
char
|
||||
toprintable(char c)
|
||||
{
|
||||
c &= 0177 ;
|
||||
if( c >= 0x20 && c <= 0x7e )
|
||||
return c ;
|
||||
else
|
||||
return '.' ;
|
||||
}
|
||||
|
||||
dumpLine()
|
||||
{
|
||||
int i,j ;
|
||||
|
||||
if( linecnt <= 0 )
|
||||
return ;
|
||||
|
||||
if( linecnt > MAXLINE ) linecnt = MAXLINE ;
|
||||
printf(" ") ;
|
||||
for(i=0; i<linecnt; ++i) {
|
||||
assert(i <= MAXLINE) ;
|
||||
printf("%2.2x ", line[i]) ;
|
||||
}
|
||||
for(; i<MAXLINE; ++i)
|
||||
printf(" ") ;
|
||||
printf("\t|") ;
|
||||
for(i=0; i<linecnt; ++i) {
|
||||
assert(i <= MAXLINE) ;
|
||||
printf("%c",toprintable(line[i])) ;
|
||||
}
|
||||
printf("|\n") ;
|
||||
|
||||
linecnt = 0 ;
|
||||
}
|
||||
|
||||
|
||||
static u_char hexHeaderStart[] = {ZPAD,ZPAD,ZDLE,ZHEX} ;
|
||||
static u_char header16Start[] = {ZPAD,ZDLE,ZBIN} ;
|
||||
static u_char header32Start[] = {ZPAD,ZDLE,ZBIN32} ;
|
||||
|
||||
parseData( Zinfo *info, int len )
|
||||
{
|
||||
u_char *ptr, c ;
|
||||
int idx ;
|
||||
|
||||
for(ptr = buffer; --len >= 0; ptr++) {
|
||||
assert(ptr >= buffer && ptr < buffer+MAXBUF) ;
|
||||
c = *ptr ;
|
||||
if( c != XON )
|
||||
switch( info->state ) {
|
||||
case Idle:
|
||||
if( c != ZPAD )
|
||||
dataChar(c) ;
|
||||
else {
|
||||
info->state = Padding ;
|
||||
info->count = 1 ;
|
||||
hbuffer[0] = c ;
|
||||
}
|
||||
break ;
|
||||
|
||||
case Padding:
|
||||
if( c == ZDLE ) {
|
||||
info->zdlePend = 1 ;
|
||||
}
|
||||
else if( info->zdlePend ) {
|
||||
info->zdlePend = 0 ;
|
||||
info->count = 0 ;
|
||||
switch(c) {
|
||||
case ZHEX:
|
||||
info->state = HexHeader ;
|
||||
info->crclen=2 ;
|
||||
info->crc = 0 ;
|
||||
break ;
|
||||
case ZBIN:
|
||||
info->state = Header16 ;
|
||||
info->crclen=2 ;
|
||||
info->crc = 0 ;
|
||||
break ;
|
||||
case ZBIN32:
|
||||
info->state = Header32 ;
|
||||
info->crclen=4 ;
|
||||
info->crc = 0xffffffff ;
|
||||
break ;
|
||||
default:
|
||||
cancelHeader(info) ; break ;
|
||||
}
|
||||
}
|
||||
else if( c == ZPAD )
|
||||
{
|
||||
if( info->count < 2 ) {
|
||||
assert(info->count < MAXHBUF) ;
|
||||
hbuffer[info->count++] = c ;
|
||||
}
|
||||
else
|
||||
dataChar(c) ;
|
||||
}
|
||||
else
|
||||
cancelHeader(info) ; break ;
|
||||
break ;
|
||||
|
||||
case HexHeader:
|
||||
if( c == ZDLE && !info->zdlePend ) {
|
||||
info->zdlePend = 1 ;
|
||||
break ;
|
||||
}
|
||||
|
||||
if( info->zdlePend ) {
|
||||
c = zdle(c) ;
|
||||
info->zdlePend = 0 ;
|
||||
}
|
||||
|
||||
idx = info->count++ ;
|
||||
assert(idx < MAXHBUF) ;
|
||||
hbuffer[idx] = c ;
|
||||
if( info->count >= 16 ) { /* end of header */
|
||||
info->headertype = hex2(hbuffer+0) ;
|
||||
info->data[0] = hex2(hbuffer+2) ;
|
||||
info->data[1] = hex2(hbuffer+4) ;
|
||||
info->data[2] = hex2(hbuffer+6) ;
|
||||
info->data[3] = hex2(hbuffer+8) ;
|
||||
info->crcBytes[0] = hex2(hbuffer+10) ;
|
||||
info->crcBytes[1] = hex2(hbuffer+12) ;
|
||||
displayHeader(info) ;
|
||||
}
|
||||
break ;
|
||||
|
||||
case Header16:
|
||||
if( c == ZDLE && !info->zdlePend ) {
|
||||
info->zdlePend = 1 ;
|
||||
break ;
|
||||
}
|
||||
|
||||
if( info->zdlePend ) {
|
||||
c = zdle(c) ;
|
||||
info->zdlePend = 0 ;
|
||||
}
|
||||
|
||||
idx = info->count++ ;
|
||||
assert(idx < MAXHBUF) ;
|
||||
hbuffer[idx] = c ;
|
||||
if( info->count >= 7 ) { /* end of header */
|
||||
info->headertype = hbuffer[0] ;
|
||||
info->data[0] = hbuffer[1] ;
|
||||
info->data[1] = hbuffer[2] ;
|
||||
info->data[2] = hbuffer[3] ;
|
||||
info->data[3] = hbuffer[4] ;
|
||||
info->crcBytes[0] = hbuffer[5] ;
|
||||
info->crcBytes[1] = hbuffer[6] ;
|
||||
displayHeader(info) ;
|
||||
}
|
||||
break ;
|
||||
|
||||
case Header32:
|
||||
if( c == ZDLE && !info->zdlePend ) {
|
||||
info->zdlePend = 1 ;
|
||||
break ;
|
||||
}
|
||||
|
||||
if( info->zdlePend ) {
|
||||
c = zdle(c) ;
|
||||
info->zdlePend = 0 ;
|
||||
}
|
||||
|
||||
idx = info->count++ ;
|
||||
assert(idx < MAXHBUF) ;
|
||||
hbuffer[idx] = c ;
|
||||
if( info->count >= 9 ) { /* end of header */
|
||||
info->headertype = hbuffer[0] ;
|
||||
info->data[0] = hbuffer[1] ;
|
||||
info->data[1] = hbuffer[2] ;
|
||||
info->data[2] = hbuffer[3] ;
|
||||
info->data[3] = hbuffer[4] ;
|
||||
info->crcBytes[0] = hbuffer[5] ;
|
||||
info->crcBytes[1] = hbuffer[6] ;
|
||||
info->crcBytes[2] = hbuffer[7] ;
|
||||
info->crcBytes[3] = hbuffer[8] ;
|
||||
displayHeader(info) ;
|
||||
}
|
||||
break ;
|
||||
|
||||
case InData:
|
||||
if( info->zdlePend )
|
||||
{
|
||||
info->zdlePend = 0 ;
|
||||
switch( c ) {
|
||||
case ZCRCE:
|
||||
case ZCRCW:
|
||||
case ZCRCG:
|
||||
case ZCRCQ:
|
||||
info->crcCmd = c ;
|
||||
dumpLine() ;
|
||||
info->state = InCrc ;
|
||||
info->count = 0 ;
|
||||
break ;
|
||||
default:
|
||||
c = zdle(c) ;
|
||||
dataChar(c) ;
|
||||
break ;
|
||||
}
|
||||
}
|
||||
else if( c == ZDLE )
|
||||
info->zdlePend = 1 ;
|
||||
else
|
||||
dataChar(c) ;
|
||||
break ;
|
||||
|
||||
case InCrc:
|
||||
if( info->zdlePend ) {
|
||||
c = zdle(c) ;
|
||||
info->zdlePend = 0 ;
|
||||
}
|
||||
|
||||
if( c == ZDLE )
|
||||
info->zdlePend = 1 ;
|
||||
else
|
||||
{
|
||||
dataChar(c) ;
|
||||
if( ++info->count >= info->crclen )
|
||||
{
|
||||
dumpCrc() ;
|
||||
switch( info->crcCmd ) {
|
||||
case ZCRCE:
|
||||
printf(" ZCRCE: end of frame, header follows\n") ;
|
||||
info->state = Idle ;
|
||||
break ;
|
||||
case ZCRCW:
|
||||
printf(" ZCRCW: end of frame, send ZACK\n") ;
|
||||
info->state = Idle ;
|
||||
break ;
|
||||
case ZCRCG:
|
||||
printf(" ZCRCG: more data follows:\n") ;
|
||||
info->state = InData ;
|
||||
break ;
|
||||
case ZCRCQ:
|
||||
printf(" ZCRCQ: send ZACK, more data follows:\n") ;
|
||||
info->state = InData ;
|
||||
break ;
|
||||
}
|
||||
}
|
||||
}
|
||||
break ;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* handle a character that's not part of the protocol */
|
||||
|
||||
dataChar(int c)
|
||||
{
|
||||
assert(linecnt < MAXLINE) ;
|
||||
line[linecnt++] = c ;
|
||||
if( linecnt >= MAXLINE )
|
||||
dumpLine() ;
|
||||
}
|
||||
|
||||
|
||||
/* here if we thought we were in a header, but were wrong */
|
||||
|
||||
cancelHeader( Zinfo *info )
|
||||
{
|
||||
int i ;
|
||||
|
||||
for(i=0; i<info->count; ++i) {
|
||||
assert(i < MAXHBUF) ;
|
||||
dataChar(hbuffer[i]) ;
|
||||
}
|
||||
|
||||
info->state = Idle ;
|
||||
}
|
||||
|
||||
|
||||
/* here to display a full header. CRC's not currently checked */
|
||||
|
||||
displayHeader( Zinfo *info )
|
||||
{
|
||||
int i ;
|
||||
u_long crc ;
|
||||
int h32 = info->state == Header32 ;
|
||||
static char *names[] = {
|
||||
"ZRQINIT", "ZRINIT", "ZSINIT", "ZACK", "ZFILE", "ZSKIP",
|
||||
"ZNAK", "ZABORT", "ZFIN", "ZRPOS", "ZDATA", "ZEOF", "ZFERR",
|
||||
"ZCRC", "ZCHALLENGE", "ZCOMPL", "ZCAN", "ZFREECNT",
|
||||
"ZCOMMAND", "ZSTDERR",} ;
|
||||
|
||||
dumpLine() ;
|
||||
|
||||
printf(" ") ;
|
||||
switch( info->state ) {
|
||||
case HexHeader: printf("hex header") ; break ;
|
||||
case Header16: printf("bin header") ; break ;
|
||||
case Header32: printf("bin32 header") ; break ;
|
||||
}
|
||||
printf(" %d: %s: d=[%x %x %x %x]", info->headertype,
|
||||
info->headertype <= ZSTDERR ? names[info->headertype] : "BAD HEADER",
|
||||
info->data[0], info->data[1], info->data[2], info->data[3]) ;
|
||||
switch( info->state ) {
|
||||
case HexHeader:
|
||||
case Header16:
|
||||
printf(" crc=[%x %x]", info->crcBytes[0], info->crcBytes[1]) ;
|
||||
break ;
|
||||
case Header32:
|
||||
printf(" crc=[%x %x %x %x]",
|
||||
info->crcBytes[0], info->crcBytes[1],
|
||||
info->crcBytes[2], info->crcBytes[3]) ;
|
||||
break ;
|
||||
}
|
||||
|
||||
switch( info->headertype ) {
|
||||
case ZRQINIT:
|
||||
case ZRINIT:
|
||||
case ZACK:
|
||||
case ZSKIP:
|
||||
case ZNAK:
|
||||
case ZABORT:
|
||||
case ZFIN:
|
||||
case ZRPOS:
|
||||
case ZEOF:
|
||||
case ZFERR:
|
||||
case ZCRC:
|
||||
case ZCHALLENGE:
|
||||
case ZCOMPL:
|
||||
case ZCAN:
|
||||
case ZFREECNT:
|
||||
case ZCOMMAND:
|
||||
printf("\n") ;
|
||||
info->state = Idle ;
|
||||
break ;
|
||||
|
||||
case ZSINIT:
|
||||
case ZFILE:
|
||||
case ZDATA:
|
||||
case ZSTDERR:
|
||||
printf(", data follows:\n") ;
|
||||
info->state = InData ;
|
||||
info->count = 0 ;
|
||||
break ;
|
||||
}
|
||||
|
||||
if( !h32 )
|
||||
{
|
||||
crc = 0 ;
|
||||
crc = updcrc(info->headertype, crc) ;
|
||||
crc = updcrc(info->data[0], crc) ;
|
||||
crc = updcrc(info->data[1], crc) ;
|
||||
crc = updcrc(info->data[2], crc) ;
|
||||
crc = updcrc(info->data[3], crc) ;
|
||||
crc = updcrc(info->crcBytes[0], crc) ;
|
||||
crc = updcrc(info->crcBytes[1], crc) ;
|
||||
if( crc&0xffff != 0 )
|
||||
printf(" CRC ERROR\n") ;
|
||||
}
|
||||
else
|
||||
{
|
||||
crc = 0xffffffff ;
|
||||
crc = UPDC32(info->headertype, crc) ;
|
||||
crc = UPDC32(info->data[0], crc) ;
|
||||
crc = UPDC32(info->data[1], crc) ;
|
||||
crc = UPDC32(info->data[2], crc) ;
|
||||
crc = UPDC32(info->data[3], crc) ;
|
||||
crc = UPDC32(info->crcBytes[0], crc) ;
|
||||
crc = UPDC32(info->crcBytes[1], crc) ;
|
||||
crc = UPDC32(info->crcBytes[2], crc) ;
|
||||
crc = UPDC32(info->crcBytes[3], crc) ;
|
||||
if( crc != 0xdebb20e3 )
|
||||
printf(" CRC ERROR\n") ;
|
||||
}
|
||||
}
|
||||
|
||||
dumpCrc()
|
||||
{
|
||||
int i,j ;
|
||||
|
||||
if( linecnt <= 0 )
|
||||
return ;
|
||||
|
||||
if( linecnt > MAXLINE ) linecnt = MAXLINE ;
|
||||
printf(" crc: ") ;
|
||||
for(i=0; i<linecnt; ++i) {
|
||||
assert(i < MAXLINE) ;
|
||||
printf("%2.2x ", line[i]) ;
|
||||
}
|
||||
printf("\n") ;
|
||||
|
||||
linecnt = 0 ;
|
||||
}
|
||||
|
||||
|
||||
/* return value of 2 hex digits */
|
||||
|
||||
int
|
||||
hex2(char *chrs)
|
||||
{
|
||||
return (hex1(chrs[0]) << 4) + hex1(chrs[1]) ;
|
||||
}
|
||||
|
||||
/* return value of a hex digit */
|
||||
|
||||
int
|
||||
hex1(int chr)
|
||||
{
|
||||
chr -= '0' ;
|
||||
if( chr > 9 )
|
||||
chr -= 'A'-'0'-10 ;
|
||||
if( chr > 15 )
|
||||
chr -= 'a' - 'A' ;
|
||||
|
||||
return chr ;
|
||||
}
|
||||
|
||||
|
||||
/* apply ZDLE to chr */
|
||||
|
||||
int
|
||||
zdle(int chr)
|
||||
{
|
||||
switch( chr ) {
|
||||
case ZRUB0: return 0177 ;
|
||||
case ZRUB1: return 0377 ;
|
||||
default:
|
||||
if( (chr & 0140) == 0100 )
|
||||
return chr ^ 0100 ;
|
||||
return -1 ;
|
||||
}
|
||||
}
|
|
@ -1,750 +0,0 @@
|
|||
#ifndef lint
|
||||
static const char rcsid[] = "$Id: zmodemr.c,v 1.1.1.1 2001/03/08 00:01:48 efalk Exp $" ;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Copyright (c) 1995 by Edward A. Falk
|
||||
*/
|
||||
|
||||
|
||||
/**********
|
||||
*
|
||||
*
|
||||
* @@@@@ @ @ @@@ @@@@ @@@@@ @ @ @@@@
|
||||
* @ @@ @@ @ @ @ @ @ @@ @@ @ @
|
||||
* @ @ @ @ @ @ @ @ @@@ @ @ @ @@@@
|
||||
* @ @ @ @ @ @ @ @ @ @ @ @ @ @
|
||||
* @@@@@ @ @ @ @@@ @@@@ @@@@@ @ @ @ @ @
|
||||
*
|
||||
* ZMODEMR - receive side of zmodem protocol
|
||||
*
|
||||
* receive side of zmodem protocol
|
||||
*
|
||||
* This code is designed to be called from inside a larger
|
||||
* program, so it is implemented as a state machine where
|
||||
* practical.
|
||||
*
|
||||
* functions:
|
||||
*
|
||||
* ZmodemRInit(ZModem *info)
|
||||
* Initiate a connection
|
||||
*
|
||||
* ZmodemRAbort(ZModem *info)
|
||||
* abort transfer
|
||||
*
|
||||
* all functions return 0 on success, 1 on failure
|
||||
*
|
||||
*
|
||||
* Edward A. Falk
|
||||
*
|
||||
* January, 1995
|
||||
*
|
||||
*
|
||||
*
|
||||
**********/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include "zmodem.h"
|
||||
#include "crctab.h"
|
||||
|
||||
extern int errno ;
|
||||
|
||||
extern int ZWriteFile(u_char *buffer, int len, FILE *, ZModem *);
|
||||
extern int ZCloseFile(ZModem *info) ;
|
||||
extern void ZFlowControl(int onoff, ZModem *info) ;
|
||||
|
||||
static u_char zeros[4] = {0,0,0,0} ;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int
|
||||
ZmodemRInit(ZModem *info)
|
||||
{
|
||||
info->packetCount = 0 ;
|
||||
info->offset = 0 ;
|
||||
info->errCount = 0 ;
|
||||
info->escCtrl = info->escHibit = info->atSign = info->escape = 0 ;
|
||||
info->InputState = Idle ;
|
||||
info->canCount = info->chrCount = 0 ;
|
||||
info->filename = NULL ;
|
||||
info->interrupt = 0 ;
|
||||
info->waitflag = 0 ;
|
||||
info->attn = NULL ;
|
||||
info->file = NULL ;
|
||||
|
||||
info->buffer = (u_char *)malloc(8192) ;
|
||||
|
||||
info->state = RStart ;
|
||||
info->timeoutCount = 0 ;
|
||||
|
||||
ZIFlush(info) ;
|
||||
|
||||
/* Don't send ZRINIT right away, there might be a ZRQINIT in
|
||||
* the input buffer. Instead, set timeout to zero and return.
|
||||
* This will allow ZmodemRcv() to check the input stream first.
|
||||
* If nothing found, a ZRINIT will be sent immediately.
|
||||
*/
|
||||
info->timeout = 0 ;
|
||||
|
||||
zmodemlog("ZmodemRInit[%s]: flush input, new state = RStart\n",
|
||||
sname(info)) ;
|
||||
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
int
|
||||
YmodemRInit(ZModem *info)
|
||||
{
|
||||
info->errCount = 0 ;
|
||||
info->InputState = Yrcv ;
|
||||
info->canCount = info->chrCount = 0 ;
|
||||
info->noiseCount = 0 ;
|
||||
info->filename = NULL ;
|
||||
info->file = NULL ;
|
||||
|
||||
if( info->buffer == NULL )
|
||||
info->buffer = (u_char *)malloc(1024) ;
|
||||
|
||||
info->state = YRStart ;
|
||||
info->packetCount = -1 ;
|
||||
info->timeoutCount = 0 ;
|
||||
info->timeout = 10 ;
|
||||
info->offset = 0 ;
|
||||
|
||||
ZIFlush(info) ;
|
||||
|
||||
return ZXmitStr((u_char *)"C", 1, info) ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
extern int ZPF() ;
|
||||
extern int Ignore() ;
|
||||
extern int GotCommand() ;
|
||||
extern int GotStderr() ;
|
||||
|
||||
int SendRinit() ;
|
||||
static int GotSinit() ;
|
||||
static int GotFile() ;
|
||||
static int GotFin() ;
|
||||
static int GotData() ;
|
||||
static int GotEof() ;
|
||||
static int GotFreecnt() ;
|
||||
static int GotFileCrc() ;
|
||||
int ResendCrcReq() ;
|
||||
int ResendRpos() ;
|
||||
|
||||
/* sent ZRINIT, waiting for ZSINIT or ZFILE */
|
||||
StateTable RStartOps[] = {
|
||||
{ZSINIT,GotSinit,0,1,RSinitWait}, /* SINIT, wait for attn str */
|
||||
{ZFILE,GotFile,0,0,RFileName}, /* FILE, wait for filename */
|
||||
{ZRQINIT,SendRinit,0,1,RStart}, /* sender confused, resend */
|
||||
{ZFIN,GotFin,1,0,RFinish}, /* sender shutting down */
|
||||
{ZNAK,SendRinit,1,0,RStart}, /* RINIT was bad, resend */
|
||||
#ifdef TODO
|
||||
{ZCOMPL,f,1,1,s},
|
||||
#endif /* TODO */
|
||||
{ZFREECNT,GotFreecnt,0,0,RStart}, /* sender wants free space */
|
||||
{ZCOMMAND,GotCommand,0,0,CommandData}, /* sender wants command */
|
||||
{ZSTDERR,GotStderr,0,0,StderrData}, /* sender wants to send msg */
|
||||
{99,ZPF,0,0,RStart}, /* anything else is an error */
|
||||
} ;
|
||||
|
||||
StateTable RSinitWaitOps[] = { /* waiting for data */
|
||||
{99,ZPF,0,0,RSinitWait},
|
||||
} ;
|
||||
|
||||
StateTable RFileNameOps[] = { /* waiting for file name */
|
||||
{99,ZPF,0,0,RFileName},
|
||||
} ;
|
||||
|
||||
StateTable RCrcOps[] = { /* waiting for CRC */
|
||||
{ZCRC,GotFileCrc,0,0,RFile}, /* sender sent it */
|
||||
{ZNAK,ResendCrcReq,0,0,RCrc}, /* ZCRC was bad, resend */
|
||||
{ZRQINIT,SendRinit,1,1,RStart}, /* sender confused, restart */
|
||||
{ZFIN,GotFin,1,1,RFinish}, /* sender signing off */
|
||||
{99,ZPF,0,0,RCrc},
|
||||
} ;
|
||||
|
||||
StateTable RFileOps[] = { /* waiting for ZDATA */
|
||||
{ZDATA,GotData,0,0,RData}, /* got it */
|
||||
{ZNAK,ResendRpos,0,0,RFile}, /* ZRPOS was bad, resend */
|
||||
{ZEOF,GotEof,0,0,RStart}, /* end of file */
|
||||
{ZRQINIT,SendRinit,1,1,RStart}, /* sender confused, restart */
|
||||
{ZFILE,ResendRpos,0,0,RFile}, /* ZRPOS was bad, resend */
|
||||
{ZFIN,GotFin,1,1,RFinish}, /* sender signing off */
|
||||
{99,ZPF,0,0,RFile},
|
||||
} ;
|
||||
|
||||
/* waiting for data, but a packet could possibly arrive due
|
||||
* to error recovery or something
|
||||
*/
|
||||
StateTable RDataOps[] = {
|
||||
{ZRQINIT,SendRinit,1,1,RStart}, /* sender confused, restart */
|
||||
{ZFILE,GotFile,0,1,RFileName}, /* start a new file (??) */
|
||||
{ZNAK,ResendRpos,1,1,RFile}, /* ZRPOS was bad, resend */
|
||||
{ZFIN,GotFin,1,1,RFinish}, /* sender signing off */
|
||||
{ZDATA,GotData,0,1,RData}, /* file data follows */
|
||||
{ZEOF,GotEof,1,1,RStart}, /* end of file */
|
||||
{99,ZPF,0,0,RData},
|
||||
} ;
|
||||
|
||||
/* here if we've sent ZFERR or ZABORT. Waiting for ZFIN */
|
||||
|
||||
StateTable RFinishOps[] = {
|
||||
{ZRQINIT,SendRinit,1,1,RStart}, /* sender confused, restart */
|
||||
{ZFILE,GotFile,1,1,RFileName}, /* start a new file */
|
||||
{ZNAK,GotFin,1,1,RFinish}, /* resend ZFIN */
|
||||
{ZFIN,GotFin,1,1,RFinish}, /* sender signing off */
|
||||
{99,ZPF,0,0,RFinish},
|
||||
} ;
|
||||
|
||||
|
||||
|
||||
|
||||
extern char *hdrnames[] ;
|
||||
|
||||
extern int dataSetup() ;
|
||||
|
||||
|
||||
/* RECEIVE-RELATED STUFF BELOW HERE */
|
||||
|
||||
|
||||
/* resend ZRINIT header in response to ZRQINIT or ZNAK header */
|
||||
|
||||
int
|
||||
SendRinit( register ZModem *info )
|
||||
{
|
||||
u_char dbuf[4] ;
|
||||
|
||||
#ifdef COMMENT
|
||||
if( info->timeoutCount >= 5 )
|
||||
/* TODO: switch to Ymodem */
|
||||
#endif /* COMMENT */
|
||||
|
||||
zmodemlog("SendRinit[%s]: send ZRINIT\n", sname(info)) ;
|
||||
|
||||
info->timeout = ResponseTime ;
|
||||
dbuf[0] = info->bufsize&0xff ;
|
||||
dbuf[1] = (info->bufsize>>8)&0xff ;
|
||||
dbuf[2] = 0 ;
|
||||
dbuf[3] = info->zrinitflags ;
|
||||
return ZXmitHdrHex(ZRINIT, dbuf, info) ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* received a ZSINIT header in response to ZRINIT */
|
||||
|
||||
static int
|
||||
GotSinit( register ZModem *info )
|
||||
{
|
||||
zmodemlog("GotSinit[%s]: call dataSetup\n", sname(info)) ;
|
||||
|
||||
info->zsinitflags = info->hdrData[4] ;
|
||||
info->escCtrl = info->zsinitflags & TESCCTL ;
|
||||
info->escHibit = info->zsinitflags & TESC8 ;
|
||||
ZFlowControl(1, info) ;
|
||||
return dataSetup(info) ;
|
||||
}
|
||||
|
||||
/* received rest of ZSINIT packet */
|
||||
|
||||
int
|
||||
GotSinitData( register ZModem *info, int crcGood )
|
||||
{
|
||||
info->InputState = Idle ;
|
||||
info->chrCount=0 ;
|
||||
info->state = RStart ;
|
||||
|
||||
zmodemlog("GotSinitData[%s]: crcGood=%d\n", sname(info), crcGood) ;
|
||||
|
||||
if( !crcGood )
|
||||
return ZXmitHdrHex(ZNAK, zeros, info) ;
|
||||
|
||||
if( info->attn != NULL )
|
||||
free(info->attn) ;
|
||||
info->attn = NULL ;
|
||||
if( info->buffer[0] != '\0' )
|
||||
info->attn = strdup((char *)info->buffer) ;
|
||||
return ZXmitHdrHex(ZACK, ZEnc4(SerialNo), info) ;
|
||||
}
|
||||
|
||||
|
||||
/* got ZFILE. Cache flags and set up to receive filename */
|
||||
|
||||
static int
|
||||
GotFile( register ZModem *info )
|
||||
{
|
||||
zmodemlog("GotFile[%s]: call dataSetup\n", sname(info)) ;
|
||||
|
||||
info->errCount = 0 ;
|
||||
info->f0 = info->hdrData[4] ;
|
||||
info->f1 = info->hdrData[3] ;
|
||||
info->f2 = info->hdrData[2] ;
|
||||
info->f3 = info->hdrData[1] ;
|
||||
return dataSetup(info) ;
|
||||
}
|
||||
|
||||
|
||||
/* utility: see if ZOpenFile wants this file, and if
|
||||
* so, request it from sender.
|
||||
*/
|
||||
|
||||
static int
|
||||
requestFile( register ZModem *info, u_long crc )
|
||||
{
|
||||
info->file = ZOpenFile((char *)info->buffer, crc, info) ;
|
||||
|
||||
if( info->file == NULL ) {
|
||||
zmodemlog("requestFile[%s]: send ZSKIP\n", sname(info)) ;
|
||||
|
||||
info->state = RStart ;
|
||||
ZStatus(FileSkip, 0, info->filename) ;
|
||||
return ZXmitHdrHex(ZSKIP, zeros, info) ;
|
||||
}
|
||||
else {
|
||||
zmodemlog("requestFile[%s]: send ZRPOS(%ld)\n",
|
||||
sname(info), info->offset) ;
|
||||
info->offset = info->f0 == ZCRESUM ? ftell(info->file) : 0 ;
|
||||
info->state = RFile ;
|
||||
ZStatus(FileBegin, 0, info->filename) ;
|
||||
return ZXmitHdrHex(ZRPOS, ZEnc4(info->offset), info) ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* parse filename info. */
|
||||
|
||||
static void
|
||||
parseFileName( register ZModem *info, char *fileinfo )
|
||||
{
|
||||
char *ptr ;
|
||||
int serial=0 ;
|
||||
|
||||
info->len = info->mode = info->filesRem =
|
||||
info->bytesRem = info->fileType = 0 ;
|
||||
ptr = fileinfo + strlen(fileinfo) + 1 ;
|
||||
if( info->filename != NULL )
|
||||
free(info->filename) ;
|
||||
info->filename = strdup(fileinfo) ;
|
||||
sscanf(ptr, "%d %lo %o %o %d %d %d", &info->len, &info->date,
|
||||
&info->mode, &serial, &info->filesRem, &info->bytesRem,
|
||||
&info->fileType) ;
|
||||
}
|
||||
|
||||
|
||||
/* got filename. Parse arguments from it and execute
|
||||
* policy function ZOpenFile(), provided by caller
|
||||
*/
|
||||
|
||||
int
|
||||
GotFileName( register ZModem *info, int crcGood )
|
||||
{
|
||||
info->InputState = Idle ;
|
||||
info->chrCount=0 ;
|
||||
|
||||
if( !crcGood ) {
|
||||
zmodemlog("GotFileName[%s]: bad crc, send ZNAK\n", sname(info)) ;
|
||||
info->state = RStart ;
|
||||
return ZXmitHdrHex(ZNAK, zeros, info) ;
|
||||
}
|
||||
|
||||
parseFileName(info, (char *)info->buffer) ;
|
||||
|
||||
if( (info->f1 & ZMMASK) == ZMCRC ) {
|
||||
info->state = RCrc ;
|
||||
return ZXmitHdrHex(ZCRC, zeros, info) ;
|
||||
}
|
||||
|
||||
zmodemlog("GotFileName[%s]: good crc, call requestFile\n",
|
||||
sname(info)) ;
|
||||
info->state = RFile ;
|
||||
return requestFile(info,0) ;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
ResendCrcReq(ZModem *info)
|
||||
{
|
||||
zmodemlog("ResendCrcReq[%s]: send ZCRC\n", sname(info)) ;
|
||||
return ZXmitHdrHex(ZCRC, zeros, info) ;
|
||||
}
|
||||
|
||||
|
||||
/* received file CRC, now we're ready to accept or reject */
|
||||
|
||||
static int
|
||||
GotFileCrc( register ZModem *info )
|
||||
{
|
||||
zmodemlog("GotFileCrc[%s]: call requestFile\n", sname(info)) ;
|
||||
return requestFile(info, ZDec4(info->hdrData+1)) ;
|
||||
}
|
||||
|
||||
|
||||
/* last ZRPOS was bad, resend it */
|
||||
|
||||
int
|
||||
ResendRpos( register ZModem *info )
|
||||
{
|
||||
zmodemlog("ResendRpos[%s]: send ZRPOS(%ld)\n",
|
||||
sname(info), info->offset) ;
|
||||
return ZXmitHdrHex(ZRPOS, ZEnc4(info->offset), info) ;
|
||||
}
|
||||
|
||||
|
||||
/* recevied ZDATA header */
|
||||
|
||||
static int
|
||||
GotData( register ZModem *info )
|
||||
{
|
||||
int err ;
|
||||
|
||||
zmodemlog("GotData[%s]:\n", sname(info)) ;
|
||||
|
||||
if( ZDec4(info->hdrData+1) != info->offset ) {
|
||||
if( info->attn != NULL && (err=ZAttn(info)) != 0 )
|
||||
return err ;
|
||||
zmodemlog(" bad, send ZRPOS(%ld)\n", info->offset);
|
||||
return ZXmitHdrHex(ZRPOS, ZEnc4(info->offset), info) ;
|
||||
}
|
||||
|
||||
/* Let's do it! */
|
||||
zmodemlog(" call dataSetup\n");
|
||||
return dataSetup(info) ;
|
||||
}
|
||||
|
||||
|
||||
/* Utility: flush input, send attn, send specified header */
|
||||
|
||||
static int
|
||||
fileError( register ZModem *info, int type, int data )
|
||||
{
|
||||
int err ;
|
||||
|
||||
info->InputState = Idle ;
|
||||
info->chrCount=0 ;
|
||||
|
||||
if( info->attn != NULL && (err=ZAttn(info)) != 0 )
|
||||
return err ;
|
||||
return ZXmitHdrHex(type, ZEnc4(data), info) ;
|
||||
}
|
||||
|
||||
/* received file data */
|
||||
|
||||
int
|
||||
GotFileData( register ZModem *info, int crcGood )
|
||||
{
|
||||
/* OK, now what? Fushing the buffers and executing the
|
||||
* attn sequence has likely chopped off the input stream
|
||||
* mid-packet. Now we switch to idle mode and treat all
|
||||
* incoming stuff like noise until we get a new valid
|
||||
* packet.
|
||||
*/
|
||||
|
||||
if( !crcGood ) { /* oh bugger, an error. */
|
||||
zmodemlog(
|
||||
"GotFileData[%s]: bad crc, send ZRPOS(%ld), new state = RFile\n",
|
||||
sname(info), info->offset) ;
|
||||
ZStatus(DataErr, ++info->errCount, NULL) ;
|
||||
if( info->errCount > MaxErrs ) {
|
||||
ZmodemAbort(info) ;
|
||||
return ZmDataErr ;
|
||||
}
|
||||
else {
|
||||
info->state = RFile ;
|
||||
info->InputState = Idle ;
|
||||
info->chrCount=0 ;
|
||||
return fileError(info, ZRPOS, info->offset) ;
|
||||
}
|
||||
}
|
||||
|
||||
if( ZWriteFile(info->buffer, info->chrCount, info->file, info) )
|
||||
{
|
||||
/* RED ALERT! Could not write the file. */
|
||||
ZStatus(FileErr, errno, NULL) ;
|
||||
info->state = RFinish ;
|
||||
info->InputState = Idle ;
|
||||
info->chrCount=0 ;
|
||||
return fileError(info, ZFERR, errno) ;
|
||||
}
|
||||
|
||||
zmodemlog("GotFileData[%s]: %ld.%d,",
|
||||
sname(info), info->offset, info->chrCount) ;
|
||||
info->offset += info->chrCount ;
|
||||
ZStatus(RcvByteCount, info->offset, NULL) ;
|
||||
|
||||
/* if this was the last data subpacket, leave data mode */
|
||||
if( info->PacketType == ZCRCE || info->PacketType == ZCRCW ) {
|
||||
zmodemlog(" ZCRCE|ZCRCW, new state RFile") ;
|
||||
info->state = RFile ;
|
||||
info->InputState = Idle ;
|
||||
info->chrCount=0 ;
|
||||
}
|
||||
else {
|
||||
zmodemlog(" call dataSetup") ;
|
||||
(void) dataSetup(info) ;
|
||||
}
|
||||
|
||||
if( info->PacketType == ZCRCQ || info->PacketType == ZCRCW ) {
|
||||
zmodemlog(", send ZACK\n") ;
|
||||
return ZXmitHdrHex(ZACK, ZEnc4(info->offset), info) ;
|
||||
}
|
||||
else
|
||||
zmodemlog("\n") ;
|
||||
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
|
||||
/* received ZEOF packet, file is now complete */
|
||||
|
||||
static int
|
||||
GotEof( register ZModem *info )
|
||||
{
|
||||
zmodemlog("GotEof[%s]: offset=%ld\n", sname(info), info->offset) ;
|
||||
if( ZDec4(info->hdrData+1) != info->offset ) {
|
||||
zmodemlog(" bad length, state = RFile\n") ;
|
||||
info->state = RFile ;
|
||||
return 0 ; /* it was probably spurious */
|
||||
}
|
||||
|
||||
/* TODO: if we can't close the file, send a ZFERR */
|
||||
|
||||
ZCloseFile(info) ; info->file = NULL ;
|
||||
ZStatus(FileEnd, 0, info->filename) ;
|
||||
if( info->filename != NULL ) {
|
||||
free(info->filename) ;
|
||||
info->filename = NULL ;
|
||||
}
|
||||
return SendRinit(info) ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* got ZFIN, respond in kind */
|
||||
|
||||
static int
|
||||
GotFin( register ZModem *info )
|
||||
{
|
||||
zmodemlog("GotFin[%s]: send ZFIN\n", sname(info)) ;
|
||||
info->InputState = Finish ;
|
||||
info->chrCount = 0 ;
|
||||
if( info->filename != NULL )
|
||||
free(info->filename) ;
|
||||
return ZXmitHdrHex(ZFIN, zeros, info) ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int
|
||||
GotFreecnt( register ZModem *info )
|
||||
{
|
||||
/* TODO: how do we find free space on system? */
|
||||
return ZXmitHdrHex(ZACK, ZEnc4(0xffffffff), info) ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* YMODEM */
|
||||
|
||||
static u_char AckStr[1] = {ACK} ;
|
||||
static u_char NakStr[1] = {NAK} ;
|
||||
static u_char CanStr[2] = {CAN,CAN} ;
|
||||
|
||||
static int ProcessPacket() ;
|
||||
static int acceptPacket() ;
|
||||
static int rejectPacket() ;
|
||||
static int calcCrc() ;
|
||||
|
||||
int
|
||||
YrcvChar( char c, register ZModem *info )
|
||||
{
|
||||
int err ;
|
||||
|
||||
if( info->canCount >= 2 ) {
|
||||
ZStatus(RmtCancel, 0, NULL) ;
|
||||
return ZmErrCancel ;
|
||||
}
|
||||
|
||||
switch( info->state ) {
|
||||
case YREOF:
|
||||
if( c == EOT ) {
|
||||
ZCloseFile(info) ; info->file = NULL ;
|
||||
ZStatus(FileEnd, 0, info->filename) ;
|
||||
if( info->filename != NULL )
|
||||
free(info->filename) ;
|
||||
if( (err = acceptPacket(info)) != 0 )
|
||||
return err ;
|
||||
info->packetCount = -1 ;
|
||||
info->offset = 0 ;
|
||||
info->state = YRStart ;
|
||||
return ZXmitStr((u_char *)"C", 1, info) ;
|
||||
}
|
||||
/* else, drop through */
|
||||
|
||||
case YRStart:
|
||||
case YRDataWait:
|
||||
switch( c ) {
|
||||
case SOH:
|
||||
case STX:
|
||||
info->pktLen = c == SOH ? (128+4) : (1024+4) ;
|
||||
info->state = YRData ;
|
||||
info->chrCount = 0 ;
|
||||
info->timeout = 1 ;
|
||||
info->noiseCount = 0 ;
|
||||
info->crc = 0 ;
|
||||
break ;
|
||||
|
||||
case EOT:
|
||||
/* ignore first EOT to protect against false eot */
|
||||
info->state = YREOF ;
|
||||
return rejectPacket(info) ;
|
||||
|
||||
default:
|
||||
if( ++info->noiseCount > 135 )
|
||||
return ZXmitStr(NakStr, 1, info) ;
|
||||
break ;
|
||||
}
|
||||
break ;
|
||||
|
||||
case YRData:
|
||||
info->buffer[info->chrCount++] = c ;
|
||||
if( info->chrCount >= info->pktLen )
|
||||
return ProcessPacket(info) ;
|
||||
break ;
|
||||
|
||||
default:
|
||||
break ;
|
||||
}
|
||||
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
YrcvTimeout( register ZModem *info )
|
||||
{
|
||||
switch( info->state )
|
||||
{
|
||||
case YRStart:
|
||||
if( info->timeoutCount >= 10 ) {
|
||||
(void) ZXmitStr(CanStr, 2, info) ;
|
||||
return ZmErrInitTo ;
|
||||
}
|
||||
return ZXmitStr((u_char *)"C", 1, info) ;
|
||||
|
||||
case YRDataWait:
|
||||
case YREOF:
|
||||
case YRData:
|
||||
if( info->timeoutCount >= 10 ) {
|
||||
(void) ZXmitStr(CanStr, 2, info) ;
|
||||
return ZmErrRcvTo ;
|
||||
}
|
||||
return ZXmitStr(NakStr, 1, info) ;
|
||||
default: return 0 ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static int
|
||||
ProcessPacket( register ZModem *info )
|
||||
{
|
||||
int idx = (u_char) info->buffer[0] ;
|
||||
int idxc = (u_char) info->buffer[1] ;
|
||||
int crc0, crc1 ;
|
||||
int err ;
|
||||
|
||||
info->state = YRDataWait ;
|
||||
|
||||
if( idxc != 255 - idx ) {
|
||||
ZStatus(DataErr, ++info->errCount, NULL) ;
|
||||
return rejectPacket(info) ;
|
||||
}
|
||||
|
||||
if( idx == (info->packetCount%256) ) /* quietly ignore dup */
|
||||
return acceptPacket(info) ;
|
||||
|
||||
if( idx != (info->packetCount+1)%256 ) { /* out of sequence */
|
||||
(void) ZXmitStr(CanStr, 2, info) ;
|
||||
return ZmErrSequence ;
|
||||
}
|
||||
|
||||
crc0 = (u_char)info->buffer[info->pktLen-2] << 8 |
|
||||
(u_char)info->buffer[info->pktLen-1] ;
|
||||
crc1 = calcCrc(info->buffer+2, info->pktLen-4) ;
|
||||
if( crc0 != crc1 ) {
|
||||
ZStatus(DataErr, ++info->errCount, NULL) ;
|
||||
return rejectPacket(info) ;
|
||||
}
|
||||
|
||||
++info->packetCount ;
|
||||
|
||||
if( info->packetCount == 0 ) /* packet 0 is filename */
|
||||
{
|
||||
if( info->buffer[2] == '\0' ) { /* null filename is FIN */
|
||||
(void) acceptPacket(info) ;
|
||||
return ZmDone ;
|
||||
}
|
||||
|
||||
parseFileName(info, (char *)info->buffer+2) ;
|
||||
info->file = ZOpenFile(info->filename, 0, info) ;
|
||||
if( info->file == NULL ) {
|
||||
(void) ZXmitStr(CanStr, 2, info) ;
|
||||
return ZmErrCantOpen ;
|
||||
}
|
||||
if( (err = acceptPacket(info)) != 0 )
|
||||
return err ;
|
||||
return ZXmitStr((u_char *)"C", 1, info) ;
|
||||
}
|
||||
|
||||
|
||||
if( ZWriteFile(info->buffer+2, info->pktLen-4, info->file, info) ) {
|
||||
ZStatus(FileErr, errno, NULL) ;
|
||||
(void) ZXmitStr(CanStr, 2, info) ;
|
||||
return ZmErrSys ;
|
||||
}
|
||||
info->offset += info->pktLen-4 ;
|
||||
ZStatus(RcvByteCount, info->offset, NULL) ;
|
||||
|
||||
(void) acceptPacket(info) ;
|
||||
return 0 ;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
rejectPacket( register ZModem *info )
|
||||
{
|
||||
info->timeout = 10 ;
|
||||
return ZXmitStr(NakStr, 1, info) ;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
acceptPacket( register ZModem *info )
|
||||
{
|
||||
info->state = YRDataWait ;
|
||||
info->timeout = 10 ;
|
||||
return ZXmitStr(AckStr, 1, info) ;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
calcCrc( u_char *str, int len )
|
||||
{
|
||||
int crc = 0 ;
|
||||
while( --len >= 0 )
|
||||
crc = updcrc(*str++, crc) ;
|
||||
crc = updcrc(0,crc) ; crc = updcrc(0,crc) ;
|
||||
return crc & 0xffff ;
|
||||
}
|
|
@ -1,21 +0,0 @@
|
|||
/* @(#)zmodemsys.c 1.1 95/06/28 Edward Falk */
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
/* small utilities for porting between systems */
|
||||
|
||||
|
||||
|
||||
#ifndef HAVE_STRDUP
|
||||
|
||||
char *
|
||||
strdup( char *str )
|
||||
{
|
||||
char *rval ;
|
||||
int len = strlen(str) + 1 ;
|
||||
rval = (char *)malloc(len) ;
|
||||
strcpy(rval,str) ;
|
||||
return rval ;
|
||||
}
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -1,408 +0,0 @@
|
|||
#ifndef lint
|
||||
static const char rcsid[] = "$Id: zmutil.c,v 1.1.1.1 2001/03/08 00:01:48 efalk Exp $" ;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Copyright (c) 1995 by Edward A. Falk
|
||||
*/
|
||||
|
||||
|
||||
/**********
|
||||
*
|
||||
*
|
||||
* @@@@@ @ @ @ @ @@@@@ @@@ @
|
||||
* @ @@ @@ @ @ @ @ @
|
||||
* @ @ @ @ @ @ @ @ @
|
||||
* @ @ @ @ @ @ @ @ @
|
||||
* @@@@@ @ @ @ @@@ @ @@@ @@@@@
|
||||
*
|
||||
* ZMUTIL - utilties used by zmodem protocol.
|
||||
*
|
||||
* Routines provided here:
|
||||
*
|
||||
*
|
||||
* int ZXmitHdrHex(type, data, info)
|
||||
* int type ;
|
||||
* u_char data[4] ;
|
||||
* ZModem *info ;
|
||||
*
|
||||
* transmit zmodem header in hex.
|
||||
*
|
||||
*
|
||||
* int ZXmitHdrBin(type, data, info)
|
||||
* int type ;
|
||||
* u_char data[4] ;
|
||||
* ZModem *info ;
|
||||
*
|
||||
* transmit zmodem header in binary.
|
||||
*
|
||||
*
|
||||
* int ZXmitHdrBin32(type, data, info)
|
||||
* int type ;
|
||||
* u_char data[4] ;
|
||||
* ZModem *info ;
|
||||
*
|
||||
* transmit zmodem header in binary with 32-bit crc.
|
||||
*
|
||||
*
|
||||
* int ZXmitHdr(type, format, data, info)
|
||||
* int type, format ;
|
||||
* u_char data[4] ;
|
||||
* ZModem *info ;
|
||||
*
|
||||
* transmit zmodem header
|
||||
*
|
||||
*
|
||||
* int ZXmitData(format, data, len, term, info)
|
||||
* int format, len ;
|
||||
* u_char term ;
|
||||
* u_char *data ;
|
||||
* ZModem *info ;
|
||||
*
|
||||
* transmit buffer of data.
|
||||
*
|
||||
*
|
||||
* u_long FileCrc(name)
|
||||
* char *name ;
|
||||
*
|
||||
* compute 32-bit crc for a file, returns 0 on not found
|
||||
*
|
||||
*
|
||||
* u_char *ZEnc4(n)
|
||||
* u_long n ;
|
||||
*
|
||||
* convert u_long to 4 bytes.
|
||||
*
|
||||
* u_long ZDec4(buf)
|
||||
* u_char buf[4] ;
|
||||
*
|
||||
* convert 4 bytes to u_long
|
||||
*
|
||||
*
|
||||
*
|
||||
* Edward A. Falk
|
||||
*
|
||||
* January, 1995
|
||||
*
|
||||
*
|
||||
*
|
||||
**********/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <time.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include "zmodem.h"
|
||||
#include "crctab.h"
|
||||
|
||||
|
||||
static char hexChars[] = "0123456789abcdef" ;
|
||||
|
||||
extern char *hdrnames[] ;
|
||||
|
||||
FILE *zmodemlogfile = NULL ;
|
||||
|
||||
|
||||
/* put a number as two hex digits */
|
||||
|
||||
static u_char *
|
||||
putHex( u_char *ptr, u_char c )
|
||||
{
|
||||
*ptr++ = hexChars[(c>>4)&0xf] ;
|
||||
*ptr++ = hexChars[c&0xf] ;
|
||||
return ptr ;
|
||||
}
|
||||
|
||||
|
||||
/* put a number with ZDLE escape if needed */
|
||||
|
||||
u_char *
|
||||
putZdle( register u_char *ptr, register u_char c, register ZModem *info )
|
||||
{
|
||||
register u_char c2 = c & 0177 ;
|
||||
|
||||
if( c == ZDLE || c2 == 020 || c2 == 021 || c2 == 023 ||
|
||||
c2 == 0177 || (c2 == 015 && info->atSign) ||
|
||||
#ifdef COMMENT
|
||||
c2 == 035 || (c2 == '~' && info->lastCR) ||
|
||||
#endif /* COMMENT */
|
||||
c2 == 035 ||
|
||||
(c2 < 040 && info->escCtrl) )
|
||||
{
|
||||
*ptr++ = ZDLE ;
|
||||
if( c == 0177 )
|
||||
*ptr = ZRUB0 ;
|
||||
else if( c == 0377 )
|
||||
*ptr = ZRUB1 ;
|
||||
else
|
||||
*ptr = c^0100 ;
|
||||
}
|
||||
else
|
||||
*ptr = c ;
|
||||
|
||||
info->atSign = c2 == '@' ;
|
||||
info->lastCR = c2 == '\r' ;
|
||||
|
||||
return ++ptr ;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
ZXmitHdrHex( int type, u_char data[4], ZModem *info )
|
||||
{
|
||||
u_char buffer[128] ;
|
||||
register u_char *ptr = buffer ;
|
||||
register u_int crc ;
|
||||
int i ;
|
||||
|
||||
zmodemlog("sending %s: %2.2x %2.2x %2.2x %2.2x = %lx\n",
|
||||
hdrnames[type], data[0], data[1], data[2], data[3],
|
||||
ZDec4(data)) ;
|
||||
|
||||
*ptr++ = ZPAD ;
|
||||
*ptr++ = ZPAD ;
|
||||
*ptr++ = ZDLE ;
|
||||
*ptr++ = ZHEX ;
|
||||
|
||||
ptr = putHex(ptr, type) ; crc = updcrc(type, 0) ;
|
||||
for( i=4; --i >= 0; ++data ) {
|
||||
ptr = putHex(ptr, *data) ;
|
||||
crc = updcrc(*data, crc) ;
|
||||
}
|
||||
crc = updcrc(0,crc) ; crc = updcrc(0,crc) ;
|
||||
ptr = putHex(ptr, (crc>>8)&0xff) ;
|
||||
ptr = putHex(ptr, crc&0xff) ;
|
||||
*ptr++ = '\r' ;
|
||||
*ptr++ = '\n' ;
|
||||
if( type != ZACK && type != ZFIN )
|
||||
*ptr++ = XON ;
|
||||
|
||||
return ZXmitStr(buffer, ptr-buffer, info) ;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
ZXmitHdrBin( int type, u_char data[4], register ZModem *info )
|
||||
{
|
||||
u_char buffer[128] ;
|
||||
register u_char *ptr = buffer ;
|
||||
register u_int crc ;
|
||||
int len ;
|
||||
|
||||
zmodemlog("sending %s: %2.2x %2.2x %2.2x %2.2x = %lx\n",
|
||||
hdrnames[type], data[0], data[1], data[2], data[3],
|
||||
ZDec4(data)) ;
|
||||
|
||||
*ptr++ = ZPAD ;
|
||||
*ptr++ = ZDLE ;
|
||||
*ptr++ = ZBIN ;
|
||||
|
||||
ptr = putZdle(ptr, type, info) ; crc = updcrc(type, 0) ;
|
||||
for( len=4; --len >= 0; ++data ) {
|
||||
ptr = putZdle(ptr, *data, info) ;
|
||||
crc = updcrc(*data, crc) ;
|
||||
}
|
||||
crc = updcrc(0,crc) ; crc = updcrc(0,crc) ;
|
||||
ptr = putZdle(ptr, (crc>>8)&0xff, info) ;
|
||||
ptr = putZdle(ptr, crc&0xff, info) ;
|
||||
|
||||
len = ptr-buffer ;
|
||||
return ZXmitStr(buffer, len, info) ;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
ZXmitHdrBin32( int type, u_char data[4], ZModem *info )
|
||||
{
|
||||
u_char buffer[128] ;
|
||||
register u_char *ptr = buffer ;
|
||||
register u_long crc ;
|
||||
int len ;
|
||||
|
||||
zmodemlog("sending %s: %2.2x %2.2x %2.2x %2.2x = %lx\n",
|
||||
hdrnames[type], data[0], data[1], data[2], data[3],
|
||||
ZDec4(data)) ;
|
||||
|
||||
*ptr++ = ZPAD ;
|
||||
*ptr++ = ZDLE ;
|
||||
*ptr++ = ZBIN32 ;
|
||||
ptr = putZdle(ptr, type, info) ; crc = UPDC32(type, 0xffffffffL) ;
|
||||
for( len=4; --len >= 0; ++data ) {
|
||||
ptr = putZdle(ptr, *data, info) ;
|
||||
crc = UPDC32(*data, crc) ;
|
||||
}
|
||||
crc = ~crc ;
|
||||
for(len=4; --len >= 0; crc >>= 8)
|
||||
ptr = putZdle(ptr, crc&0xff, info) ;
|
||||
|
||||
len = ptr-buffer ;
|
||||
return ZXmitStr(buffer, len, info) ;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
ZXmitHdr( int type, int format, u_char data[4], ZModem *info)
|
||||
{
|
||||
if( format == ZBIN && info->crc32 )
|
||||
format = ZBIN32 ;
|
||||
|
||||
switch( format ) {
|
||||
case ZHEX:
|
||||
return ZXmitHdrHex(type, data, info) ;
|
||||
|
||||
case ZBIN:
|
||||
return ZXmitHdrBin(type, data, info) ;
|
||||
|
||||
case ZBIN32:
|
||||
return ZXmitHdrBin32(type, data, info) ;
|
||||
|
||||
default:
|
||||
return 0 ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/* TODO: if input is not a file, need to keep old data
|
||||
* for possible retransmission */
|
||||
|
||||
int
|
||||
ZXmitData( int format, int len, u_char term, u_char *data, ZModem *info)
|
||||
{
|
||||
register u_char *ptr = info->buffer ;
|
||||
register u_int crc ;
|
||||
|
||||
if( format == ZBIN && info->crc32 )
|
||||
format = ZBIN32 ;
|
||||
|
||||
zmodemlog("ZXmiteData: fmt=%c, len=%d, term=%c\n", format, len, term) ;
|
||||
|
||||
crc = (format == ZBIN) ? 0 : 0xffffffff ;
|
||||
|
||||
while( --len >= 0 ) {
|
||||
if( format == ZBIN )
|
||||
crc = updcrc(*data, crc) ;
|
||||
else
|
||||
crc = UPDC32(*data, crc) ;
|
||||
ptr = putZdle(ptr, *data++, info) ;
|
||||
}
|
||||
|
||||
*ptr++ = ZDLE ;
|
||||
if( format == ZBIN )
|
||||
crc = updcrc(term, crc) ;
|
||||
else
|
||||
crc = UPDC32(term, crc) ;
|
||||
*ptr++ = term ;
|
||||
if( format == ZBIN ) {
|
||||
crc = updcrc(0,crc) ; crc = updcrc(0,crc) ;
|
||||
ptr = putZdle(ptr, (crc>>8)&0xff, info) ;
|
||||
ptr = putZdle(ptr, crc&0xff, info) ;
|
||||
}
|
||||
else {
|
||||
crc = ~crc ;
|
||||
for(len=4; --len >= 0; crc >>= 8)
|
||||
ptr = putZdle(ptr, crc&0xff, info) ;
|
||||
}
|
||||
|
||||
return ZXmitStr(info->buffer, ptr-info->buffer, info) ;
|
||||
}
|
||||
|
||||
|
||||
/* compute 32-bit crc for a file, returns 0 on not found */
|
||||
|
||||
u_long
|
||||
FileCrc( char *name )
|
||||
{
|
||||
u_long crc ;
|
||||
FILE *ifile = fopen(name, "r") ;
|
||||
int i ;
|
||||
|
||||
if( ifile == NULL ) /* shouldn't happen, since we did access(2) */
|
||||
return 0 ;
|
||||
|
||||
crc = 0xffffffff ;
|
||||
|
||||
while( (i=fgetc(ifile)) != EOF )
|
||||
crc = UPDC32(i, crc) ;
|
||||
|
||||
fclose(ifile) ;
|
||||
return ~crc ;
|
||||
}
|
||||
|
||||
|
||||
u_char *
|
||||
ZEnc4( u_long n )
|
||||
{
|
||||
static u_char buf[4] ;
|
||||
buf[0] = n&0xff ; n >>= 8 ;
|
||||
buf[1] = n&0xff ; n >>= 8 ;
|
||||
buf[2] = n&0xff ; n >>= 8 ;
|
||||
buf[3] = n&0xff ;
|
||||
return buf ;
|
||||
}
|
||||
|
||||
u_long
|
||||
ZDec4( u_char buf[4] )
|
||||
{
|
||||
return buf[0] | (buf[1]<<8) | (buf[2]<<16) | (buf[3]<<24) ;
|
||||
}
|
||||
|
||||
|
||||
char *
|
||||
sname2(ZMState state)
|
||||
{
|
||||
static char *names[] = {
|
||||
"RStart", "RSinitWait", "RFileName", "RCrc", "RFile", "RData",
|
||||
"RDataErr", "RFinish", "TStart", "TInit", "FileWait", "CrcWait",
|
||||
"Sending", "SendWait", "SendDone", "SendEof", "TFinish",
|
||||
"CommandData", "CommandWait", "StderrData", "Done", "YTStart",
|
||||
"YTFile", "YTDataWait", "YTData", "YTEOF", "YTFin", "YRStart",
|
||||
"YRDataWait", "YRData", "YREOF"} ;
|
||||
|
||||
return names[(int)state] ;
|
||||
|
||||
}
|
||||
|
||||
|
||||
char *
|
||||
sname(ZModem *info)
|
||||
{
|
||||
return sname2(info->state) ;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifdef DEBUG
|
||||
void
|
||||
zmodemlog(const char *fmt, ... )
|
||||
{
|
||||
va_list ap;
|
||||
struct timeval tv ;
|
||||
struct tm *tm ;
|
||||
static int do_ts = 1 ;
|
||||
|
||||
if( zmodemlogfile == NULL )
|
||||
return ;
|
||||
|
||||
if( do_ts ) {
|
||||
gettimeofday(&tv, NULL) ;
|
||||
tm = localtime(&tv.tv_sec) ;
|
||||
fprintf(zmodemlogfile, "%2.2d:%2.2d:%2.2d.%2.2ld: ",
|
||||
tm->tm_hour, tm->tm_min, tm->tm_sec,
|
||||
tv.tv_usec/10000) ;
|
||||
}
|
||||
do_ts = strchr(fmt, '\n') != NULL ;
|
||||
|
||||
va_start(ap, fmt) ;
|
||||
vfprintf(zmodemlogfile, fmt, ap) ;
|
||||
va_end(ap) ;
|
||||
}
|
||||
#endif /* DEBUG */
|
|
@ -1,427 +0,0 @@
|
|||
/*
|
||||
The contents of this file are subject to the Mozilla Public License
|
||||
Version 1.1 (the "License"); you may not use this file except in
|
||||
compliance with the License. You may obtain a copy of the License at
|
||||
http://www.mozilla.org/MPL/
|
||||
|
||||
Software distributed under the License is distributed on an "AS IS"
|
||||
basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
|
||||
License for the specific language governing rights and limitations
|
||||
under the License.
|
||||
|
||||
Alternatively, the contents of this file may be used under the terms
|
||||
of the GNU Lesser General Public license version 2 or later (LGPL2+),
|
||||
in which case the provisions of LGPL License are applicable instead of
|
||||
those above.
|
||||
|
||||
For feedback and questions about my Files and Projects please mail me,
|
||||
Alexander Matthes (Ziz) , ziz_at_mailbox.org
|
||||
*/
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "../../src/www_tree.h"
|
||||
|
||||
extern void unmangle_ansi(char *body, int len, char **body_out, int *body_len);
|
||||
|
||||
typedef struct selem *pelem;
|
||||
typedef struct selem {
|
||||
unsigned char digit[8];
|
||||
unsigned char digitcount;
|
||||
pelem next;
|
||||
} telem;
|
||||
|
||||
pelem parseInsert(char* s)
|
||||
{
|
||||
pelem firstelem=NULL;
|
||||
pelem momelem=NULL;
|
||||
unsigned char digit[8];
|
||||
unsigned char digitcount=0;
|
||||
int pos=0;
|
||||
for (pos=0;pos<1024;pos++)
|
||||
{
|
||||
if (s[pos]=='[')
|
||||
continue;
|
||||
if (s[pos]==';' || s[pos]==0)
|
||||
{
|
||||
if (digitcount==0)
|
||||
{
|
||||
digit[0]=0;
|
||||
digitcount=1;
|
||||
}
|
||||
|
||||
pelem newelem=(pelem)malloc(sizeof(telem));
|
||||
for (unsigned char a=0;a<8;a++)
|
||||
newelem->digit[a]=digit[a];
|
||||
newelem->digitcount=digitcount;
|
||||
newelem->next=NULL;
|
||||
if (momelem==NULL)
|
||||
firstelem=newelem;
|
||||
else
|
||||
momelem->next=newelem;
|
||||
momelem=newelem;
|
||||
digitcount=0;
|
||||
memset(digit,0,8);
|
||||
if (s[pos]==0)
|
||||
break;
|
||||
}
|
||||
else
|
||||
if (digitcount<8)
|
||||
{
|
||||
digit[digitcount]=s[pos]-'0';
|
||||
digitcount++;
|
||||
}
|
||||
}
|
||||
return firstelem;
|
||||
}
|
||||
|
||||
void deleteParse(pelem elem)
|
||||
{
|
||||
while (elem!=NULL)
|
||||
{
|
||||
pelem temp=elem->next;
|
||||
free(elem);
|
||||
elem=temp;
|
||||
}
|
||||
}
|
||||
|
||||
struct www_tag * aha(char *input, struct www_tag *parent)
|
||||
{
|
||||
//Searching Parameters
|
||||
char *unmangle_out;
|
||||
int unmangle_out_len;
|
||||
unmangle_ansi(input, strlen(input), &unmangle_out, &unmangle_out_len);
|
||||
|
||||
unmangle_out[unmangle_out_len] = '\0';
|
||||
|
||||
//Begin of Conversion
|
||||
unsigned int c;
|
||||
int fc = -1; //Standard Foreground Color //IRC-Color+8
|
||||
int bc = -1; //Standard Background Color //IRC-Color+8
|
||||
int ul = 0; //Not underlined
|
||||
int bo = 0; //Not bold
|
||||
int bl = 0; //No Blinking
|
||||
int ofc,obc,oul,obo,obl; //old values
|
||||
int line=0;
|
||||
int momline=0;
|
||||
int newline=-1;
|
||||
int temp;
|
||||
char *ptr = unmangle_out;
|
||||
int size = 256;
|
||||
int outat = 0;
|
||||
char minibuf[2];
|
||||
struct www_tag *child = NULL;
|
||||
stralloc data = EMPTY_STRALLOC;
|
||||
|
||||
while (*ptr != '\0')
|
||||
{
|
||||
c = *ptr++;
|
||||
if (c=='\033')
|
||||
{
|
||||
//Saving old values
|
||||
ofc=fc;
|
||||
obc=bc;
|
||||
oul=ul;
|
||||
obo=bo;
|
||||
obl=bl;
|
||||
//Searching the end (a letter) and safe the insert:
|
||||
c= *ptr++;
|
||||
if (c == '\0') {
|
||||
return parent;
|
||||
}
|
||||
if ( c == '[' ) // CSI code, see https://en.wikipedia.org/wiki/ANSI_escape_code#Colors
|
||||
{
|
||||
char buffer[1024];
|
||||
buffer[0] = '[';
|
||||
int counter=1;
|
||||
while ((c<'A') || ((c>'Z') && (c<'a')) || (c>'z'))
|
||||
{
|
||||
c=*ptr++;
|
||||
if (c == '\0') {
|
||||
return parent;
|
||||
}
|
||||
buffer[counter]=c;
|
||||
if (c=='>') //end of htop
|
||||
break;
|
||||
counter++;
|
||||
if (counter>1022)
|
||||
break;
|
||||
}
|
||||
buffer[counter-1]=0;
|
||||
pelem elem;
|
||||
switch (c)
|
||||
{
|
||||
case 'm':
|
||||
//printf("\n%s\n",buffer); //DEBUG
|
||||
elem=parseInsert(buffer);
|
||||
pelem momelem=elem;
|
||||
while (momelem!=NULL)
|
||||
{
|
||||
//jump over zeros
|
||||
int mompos=0;
|
||||
while (mompos<momelem->digitcount && momelem->digit[mompos]==0)
|
||||
mompos++;
|
||||
if (mompos==momelem->digitcount) //only zeros => delete all
|
||||
{
|
||||
bo=0;ul=0;bl=0;fc=-1;bc=-1;
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (momelem->digit[mompos])
|
||||
{
|
||||
case 1: if (mompos+1==momelem->digitcount) // 1, 1X not supported
|
||||
bo=1;
|
||||
break;
|
||||
case 2: if (mompos+1<momelem->digitcount) // 2X, 2 not supported
|
||||
switch (momelem->digit[mompos+1])
|
||||
{
|
||||
case 1: //Reset and double underline (which aha doesn't support)
|
||||
case 2: //Reset bold
|
||||
bo=0;
|
||||
break;
|
||||
case 4: //Reset underline
|
||||
ul=0;
|
||||
break;
|
||||
case 5: //Reset blink
|
||||
bl=0;
|
||||
break;
|
||||
case 7: //Reset Inverted
|
||||
if (bc == -1)
|
||||
bc = 8;
|
||||
if (fc == -1)
|
||||
fc = 9;
|
||||
temp = bc;
|
||||
bc = fc;
|
||||
fc = temp;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 3: if (mompos+1<momelem->digitcount) // 3X, 3 not supported
|
||||
fc=momelem->digit[mompos+1];
|
||||
break;
|
||||
case 4: if (mompos+1==momelem->digitcount) // 4
|
||||
ul=1;
|
||||
else // 4X
|
||||
bc=momelem->digit[mompos+1];
|
||||
break;
|
||||
case 5: if (mompos+1==momelem->digitcount) //5, 5X not supported
|
||||
bl=1;
|
||||
break;
|
||||
//6 and 6X not supported at all
|
||||
case 7: if (bc == -1) //7, 7X is mot defined (and supported)
|
||||
bc = 8;
|
||||
if (fc == -1)
|
||||
fc = 9;
|
||||
temp = bc;
|
||||
bc = fc;
|
||||
fc = temp;
|
||||
break;
|
||||
//8 and 9 not supported
|
||||
}
|
||||
}
|
||||
momelem=momelem->next;
|
||||
}
|
||||
deleteParse(elem);
|
||||
break;
|
||||
}
|
||||
//Checking the differences
|
||||
if ((fc!=ofc) || (bc!=obc) || (ul!=oul) || (bo!=obo) || (bl!=obl)) //ANY Change
|
||||
{
|
||||
if ((fc!=-1) || (bc!=-1) || (ul!=0) || (bo!=0) || (bl!=0))
|
||||
{
|
||||
if (data.len > 0) {
|
||||
stralloc_0(&data);
|
||||
struct www_tag *datatag = www_tag_new(NULL, data.s);
|
||||
free(data.s);
|
||||
data = EMPTY_STRALLOC;
|
||||
if (child == NULL) {
|
||||
www_tag_add_child(parent, datatag);
|
||||
} else {
|
||||
www_tag_add_child(child, datatag);
|
||||
www_tag_add_child(parent, child);
|
||||
}
|
||||
}
|
||||
child = www_tag_new("span", NULL);
|
||||
|
||||
stralloc output = EMPTY_STRALLOC;
|
||||
|
||||
switch (fc)
|
||||
{
|
||||
case 0:
|
||||
if (bo) {
|
||||
stralloc_cats(&output, "color:dimgray;");
|
||||
} else {
|
||||
stralloc_cats(&output, "color:dimgray;");
|
||||
}
|
||||
break; //Black
|
||||
case 1:
|
||||
if (bo) {
|
||||
stralloc_cats(&output, "color:#FF8888;");
|
||||
} else {
|
||||
stralloc_cats(&output, "color:red;");
|
||||
}
|
||||
break; //Red
|
||||
case 2:
|
||||
if (bo) {
|
||||
stralloc_cats(&output, "color:lime;");
|
||||
} else {
|
||||
stralloc_cats(&output, "color:#00FF00;");
|
||||
}
|
||||
break; //Green
|
||||
case 3:
|
||||
if (bo) {
|
||||
stralloc_cats(&output, "color:yellow;");
|
||||
} else {
|
||||
stralloc_cats(&output, "color:olive;");
|
||||
}
|
||||
break; //Yellow
|
||||
case 4:
|
||||
if (bo) {
|
||||
stralloc_cats(&output, "color:#8888FF;");
|
||||
} else {
|
||||
stralloc_cats(&output, "color:#0000FF;");
|
||||
}
|
||||
break; //Blue
|
||||
case 5:
|
||||
if (bo) {
|
||||
stralloc_cats(&output, "color:fuchsia;");
|
||||
} else {
|
||||
stralloc_cats(&output, "color:#FF00FF;");
|
||||
}
|
||||
break; //Purple
|
||||
case 6:
|
||||
if (bo) {
|
||||
stralloc_cats(&output, "color:aqua;");
|
||||
} else {
|
||||
stralloc_cats(&output, "color:#008888;");
|
||||
}
|
||||
break; //Cyan
|
||||
case 7:
|
||||
if (bo) {
|
||||
stralloc_cats(&output, "color:white;");
|
||||
} else {
|
||||
stralloc_cats(&output, "color:grey;");
|
||||
}
|
||||
break; //White
|
||||
case 8:
|
||||
stralloc_cats(&output, "color:black;");
|
||||
break; //Background Colour
|
||||
case 9:
|
||||
stralloc_cats(&output, "color:white;");
|
||||
break; //Foreground Color
|
||||
}
|
||||
switch (bc)
|
||||
{
|
||||
case 0:
|
||||
stralloc_cats(&output, "background-color:black;");
|
||||
break; //Black
|
||||
case 1:
|
||||
stralloc_cats(&output, "background-color:red;");
|
||||
break; //Red
|
||||
case 2:
|
||||
|
||||
stralloc_cats(&output, "background-color:lime;");
|
||||
break; //Green
|
||||
case 3:
|
||||
stralloc_cats(&output, "background-color:yellow;");
|
||||
break; //Yellow
|
||||
case 4:
|
||||
stralloc_cats(&output, "background-color:#3333FF;");
|
||||
break; //Blue
|
||||
case 5:
|
||||
stralloc_cats(&output, "background-color:fuchsia;");
|
||||
break; //Purple
|
||||
case 6:
|
||||
stralloc_cats(&output, "background-color:aqua;");
|
||||
break; //Cyan
|
||||
case 7:
|
||||
stralloc_cats(&output, "background-color:white;");
|
||||
break; //White
|
||||
case 8:
|
||||
stralloc_cats(&output, "background-color:black;");
|
||||
break; //Background Colour
|
||||
case 9:
|
||||
stralloc_cats(&output, "background-color:white;");
|
||||
break; //Foreground Colour
|
||||
}
|
||||
if (ul)
|
||||
{
|
||||
stralloc_cats(&output, "text-decoration:underline;");
|
||||
}
|
||||
if (bl)
|
||||
{
|
||||
stralloc_cats(&output, "text-decoration:blink;");
|
||||
}
|
||||
|
||||
stralloc_0(&output);
|
||||
www_tag_add_attrib(child, "style", output.s);
|
||||
free(output.s);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (c!=8)
|
||||
{
|
||||
line++;
|
||||
switch (c)
|
||||
{
|
||||
|
||||
case '\n':
|
||||
case 13:
|
||||
momline++;
|
||||
line=0;
|
||||
struct www_tag *brtag = www_tag_new("br", NULL);
|
||||
if (data.len > 0) {
|
||||
if (child != NULL) {
|
||||
stralloc_0(&data);
|
||||
struct www_tag *datatag = www_tag_new(NULL, data.s);
|
||||
free(data.s);
|
||||
data = EMPTY_STRALLOC;
|
||||
www_tag_add_child(child, datatag);
|
||||
www_tag_add_child(child, brtag);
|
||||
www_tag_add_child(parent, child);
|
||||
child = www_tag_duplicate(child);
|
||||
} else {
|
||||
stralloc_0(&data);
|
||||
struct www_tag *datatag = www_tag_new(NULL, data.s);
|
||||
free(data.s);
|
||||
data = EMPTY_STRALLOC;
|
||||
www_tag_add_child(parent, datatag);
|
||||
www_tag_add_child(parent, brtag);
|
||||
}
|
||||
} else {
|
||||
|
||||
|
||||
if (child != NULL) {
|
||||
www_tag_add_child(child, brtag);
|
||||
www_tag_add_child(parent, child);
|
||||
child = www_tag_duplicate(child);
|
||||
|
||||
} else {
|
||||
www_tag_add_child(parent, brtag);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default: {
|
||||
stralloc_append1(&data, c);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (data.len > 0) {
|
||||
stralloc_0(&data);
|
||||
struct www_tag *datatag = www_tag_new(NULL, data.s);
|
||||
free(data.s);
|
||||
data = EMPTY_STRALLOC;
|
||||
if (child == NULL) {
|
||||
www_tag_add_child(parent, datatag);
|
||||
} else {
|
||||
www_tag_add_child(child, datatag);
|
||||
www_tag_add_child(parent, child);
|
||||
}
|
||||
}
|
||||
free(unmangle_out);
|
||||
return parent;
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -1,92 +0,0 @@
|
|||
Modifications copyright Thomas Dickey 1999-2015,2016
|
||||
|
||||
The software and documentation are still under the same licensing are the
|
||||
original Cdk, but noting that substantial work and enhancements have been made,
|
||||
I've added my name as needed -TD
|
||||
|
||||
The original COPYING file follows (with corrections as noted in CHANGES).
|
||||
-------------------------------------------------------------------------------
|
||||
Cdk Copying Guide
|
||||
Copyright Mike Glover, 1995, 1996, 1997, 1998, 1999
|
||||
-------------------------------------------------------------------------------
|
||||
In order to copy Cdk around I have some requirements that will protect me,
|
||||
and possibly even you. First thing, I feel I should say that this little project
|
||||
of mine has taken quite a bit 'free' time and I have put a lot of work
|
||||
into it. I do ask that if anyone asks you about Cdk, tell them where you got it
|
||||
and who wrote it. If you see Cdk installed without this file on the system
|
||||
somewhere, then assume the copy the person has is a 'corrupt' version. I will
|
||||
not be responsible for any unfortunate results if someone else makes a personal
|
||||
modification to the Cdk library. I will also not be responsible if for some
|
||||
reason the installation of Cdk creates a negative effect on your machine. You
|
||||
do have my word that there are no "Trojan horses", worms, or other security
|
||||
worries lurking in this code. If there are I did not put them there and you
|
||||
should remove the version of Cdk you have and go get a proper copy. I hate
|
||||
virus writers as much as anyone else!
|
||||
|
||||
Instead of writing my own license (I'm a programmer, not a lawyer!) I'm going
|
||||
to adapt the BSD public license on public software. If you do not agree to
|
||||
this license then remove the Cdk distribution and we all will be happier in
|
||||
the end. Here is the complete BSD public license in its true form, for
|
||||
reference.
|
||||
|
||||
I will say one thing, Cdk is my copyright. I will continue to support any
|
||||
released versions out there as long as they are in their released form. I am
|
||||
releasing this into the "public" because I feel I have benefited from other
|
||||
people's hard work, I'd like to chip into the pot as well. This does NOT make
|
||||
Cdk public domain though. Cdk is still my copyright, and owned by me, I am
|
||||
merely stating this so I don't see 40 different versions of my code floating
|
||||
around with other people's names attached.
|
||||
|
||||
With that ugly stuff said, I will happily take any comments or questions about
|
||||
Cdk. Input is more than welcomed. In fact I encourage it. Feel free to mail
|
||||
me and ask questions you think the supplied documents don't cover. If I get
|
||||
enough I may build a FAQ to help newcomers. (We'll see how Cdk is accepted
|
||||
though).
|
||||
|
||||
For you Perl programmers, there is a Perl5 extension to Cdk. Look at your
|
||||
closest CPAN site under authors/id/GLOVER.
|
||||
|
||||
If you want to get a hold of me mail me at one of the following:
|
||||
glover@credit.erin.utoronto.ca
|
||||
mike@vexus.ca
|
||||
|
||||
The CDK Web page has several homes. They are:
|
||||
http://www.vexus.ca/CDK.html (official)
|
||||
http://www.datasoft.on.ca/~cdk (Sponsored by the nice folks at Datasoft)
|
||||
|
||||
ttfn,
|
||||
Mike
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
* Copyright (c) 1999, Mike Glover
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgment:
|
||||
* This product includes software developed by Mike Glover
|
||||
* and contributors.
|
||||
* 4. Neither the name of Mike Glover, nor the names of contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY MIKE GLOVER AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL MIKE GLOVER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
|
@ -1,76 +0,0 @@
|
|||
Cdk New Widget Guide
|
||||
Copyright Mike Glover, 1995, 1996, 1997, 1998, 1999
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
If you want to create a new widget for Cdk, and want it in the standard
|
||||
dist of Cdk, you will have to follow some requisites that I have. I state
|
||||
these because Cdk has been worked on for quite some time and I finally
|
||||
got it to a state where the functions calls are somewhat consistent. Any new
|
||||
widgets should adhere to this. The requirements are as follows:
|
||||
|
||||
* The function names should be like:
|
||||
newCDKXXX, destroyCDKXXX, setCDKXXX, drawCDKXX,...
|
||||
Any widgets with functions not in this format should be 'private'.
|
||||
If this is not the case one of three things will happen:
|
||||
1) The widget will not get accepted
|
||||
2) I will mail you back asking you to follow the standards.
|
||||
3) I will do it myself. (HIGHLY unlikely)
|
||||
|
||||
* The first parameter of the newCDKXXX function should be of type
|
||||
CDKSCREEN.
|
||||
* If applicable, the next two parameters should be xpos and ypos in
|
||||
that order.
|
||||
* If applicable, the next two parameters should be the height and
|
||||
width of the widget.
|
||||
* If the widget has a title, the next parameter should be a char *
|
||||
for the title.
|
||||
* If the widget has a label, the next parameter should be a char *
|
||||
for the label.
|
||||
* The last two parameters of the newCDKXXX function should be:
|
||||
Boolean box, Boolean shadow if the parameters apply.
|
||||
* The drawCDKXXX function should only have the pointer to the object and
|
||||
a Boolean box as it's parameters. (in that order)
|
||||
* The first parameters of any other function relating to the widget
|
||||
should be a pointer to the widget type. ie: CDKRADIO *, CDKFSELECT *...
|
||||
* A destroyCDKXXX function has to be provided as well as a drawCDKXXX
|
||||
function.
|
||||
* Try to contain anything specific to the widget in a single file. This
|
||||
keeps the overhead of misc. files from floating around.
|
||||
* Create a standalone header file which includes cdk.h if needed.
|
||||
|
||||
If you follow the guidelines, then the files you need to change to sew the new
|
||||
widget into Cdk, are:
|
||||
|
||||
cdkscreen.c So this widget will get refreshed on a refreshCDKScreen
|
||||
function call.
|
||||
binding.c To allow key bindings for the widget. If it is possible
|
||||
to have key bindings I stress that this be incorporated.
|
||||
cdk.h To add in the function def's to the header file. (ie:
|
||||
include the newly created header file.)
|
||||
Makefile Add in the new widget files.
|
||||
|
||||
If you have done all of this then what I need from you is the following:
|
||||
|
||||
* A diff of all the files from the dist. that you modified. Use
|
||||
patch, I prefer it. If you haven't got it, get it and use it. It makes
|
||||
life easy.
|
||||
* A copy of the new widget file.
|
||||
* tar this up and send it to me at
|
||||
glover@credit.erin.utoronto.ca or at mike@vexus.ca
|
||||
I will mail you back when I get it and I will tell you if everything is
|
||||
OK or not.
|
||||
|
||||
I hate to be such a nit pick, but if we follow the above standards, Cdk will
|
||||
evolve into a very nice library, with a lot of really nice widgets.
|
||||
|
||||
If you want to get a hold of me mail me at one of the following:
|
||||
glover@credit.erin.utoronto.ca
|
||||
mike@vexus.ca
|
||||
|
||||
The CDK Web page has several homes. They are:
|
||||
http://www.vexus.ca/CDK.html (official)
|
||||
http://www.datasoft.on.ca/~cdk (Sponsored by the nice folks at Datasoft)
|
||||
|
||||
|
||||
ttfn,
|
||||
Mike
|
|
@ -1,55 +0,0 @@
|
|||
Cdk Installation Guide
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
Cdk should build/work on any Unix system running SVr4 curses or X/Open curses.
|
||||
|
||||
The original INSTALL notes follow:
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Copyright Mike Glover, 1995, 1996, 1997, 1998, 1999
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
General
|
||||
-------
|
||||
This document details how to build and install the Cdk library. The first thing
|
||||
you should know is what compile options you may require. I have had the
|
||||
fortunate luck of being able to compile this library on the following
|
||||
platforms:
|
||||
* Sun/OS 4.1.*
|
||||
* Solaris 2.3/2.4/2.5/2.5.1/2.6
|
||||
* AIX 3.2.* (and even AIX 4.1 but there is no mention of this in the
|
||||
makefile. Sorry.)
|
||||
* HPUX 9.* (and even HPUX 10.* but there is no mention of this in the
|
||||
makefile. Sorry.)
|
||||
* Linux (all sorts Slackware, BSD, and Redhat)
|
||||
|
||||
Building
|
||||
--------
|
||||
To build the library cd into the Cdk distribution directory and follow
|
||||
the following steps:
|
||||
|
||||
1) Run configure. This will create a Makefile with a default
|
||||
install directory root of /usr/local. If you want to
|
||||
change the default install directory use the --prefix
|
||||
command line argument on configure. For example, if you
|
||||
want to install under /export/local instead, run the command:
|
||||
./configure --prefix="/export/local"
|
||||
|
||||
2) Type make. This will make the library, the example binaries
|
||||
and the demonstration binaries.
|
||||
|
||||
3) Type make install. This will install the CDK distribution. Look
|
||||
at step 1 if you want to install other than /usr/local.
|
||||
|
||||
4) Start to play. :)
|
||||
|
||||
If you want to get a hold of me mail me at one of the following:
|
||||
glover@credit.erin.utoronto.ca
|
||||
mike@vexus.ca
|
||||
|
||||
The CDK Web page has several homes. They are:
|
||||
http://www.vexus.ca/CDK.html (official)
|
||||
http://www.datasoft.on.ca/~cdk (Sponsered by the nice folks at Datasoft)
|
||||
|
||||
ttfn,
|
||||
Mike
|
|
@ -1,622 +0,0 @@
|
|||
# $Id: Makefile.in,v 1.123 2015/09/28 23:37:35 tom Exp $
|
||||
#
|
||||
# Copyright 2001-2014,2015 Thomas E. Dickey
|
||||
# Copyright 1999, Mike Glover
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
# 1. Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
# 3. All advertising materials mentioning features or use of this software
|
||||
# must display the following acknowledgment:
|
||||
# This product includes software developed by Mike Glover
|
||||
# and contributors.
|
||||
# 4. Neither the name of Mike Glover, nor the names of contributors
|
||||
# may be used to endorse or promote products derived from this software
|
||||
# without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY MIKE GLOVER AND CONTRIBUTORS ``AS IS'' AND
|
||||
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL MIKE GLOVER OR CONTRIBUTORS BE LIABLE
|
||||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
# SUCH DAMAGE.
|
||||
#
|
||||
SHELL = /bin/sh
|
||||
@SET_MAKE@
|
||||
MAKE_RECUR = @cf_cv_makeflags@ prefix=$(prefix)
|
||||
|
||||
PACKAGE = @PACKAGE@
|
||||
|
||||
CFG_ROOTNAME = @CFG_ROOTNAME@
|
||||
HDR_ROOTNAME = @HDR_ROOTNAME@
|
||||
LIB_ROOTNAME = @LIB_ROOTNAME@
|
||||
LIB_PREFIX = @LIB_PREFIX@
|
||||
LIB_SUFFIX = @DFT_LIB_SUFFIX@
|
||||
|
||||
VERSION_MAJOR = @VERSION_MAJOR@
|
||||
VERSION_MINOR = @VERSION_MINOR@
|
||||
VERSION = $(VERSION_MAJOR).$(VERSION_MINOR)
|
||||
REL_VERSION = @REL_VERSION@
|
||||
ABI_VERSION = @ABI_VERSION@
|
||||
|
||||
RESULTING_SYMS = @RESULTING_SYMS@
|
||||
VERSIONED_SYMS = @VERSIONED_SYMS@
|
||||
|
||||
@SET_SHLIB_VARS@
|
||||
CDKLIB = @LIB_TARGET@
|
||||
IMPORT_LIB = lib$(LIB_ROOTNAME).dll.a
|
||||
@MAKE_NORMAL@OLD_SHLIB_LINK = @LIB_PREFIX@$(LIB_ROOTNAME).so
|
||||
@MAKE_NORMAL@OLD_SONAME = $(OLD_SHLIB_LINK).$(VERSION_MAJOR)
|
||||
@MAKE_NORMAL@OLD_SHLIB_FILE = $(OLD_SONAME).$(VERSION_MINOR)
|
||||
|
||||
prefix = @prefix@
|
||||
exec_prefix = @exec_prefix@
|
||||
|
||||
top_srcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = $(srcdir)
|
||||
|
||||
x = @EXEEXT@
|
||||
o = .@OBJEXT@
|
||||
a = $(LIB_SUFFIX)
|
||||
|
||||
DESTDIR =
|
||||
bindir = @bindir@
|
||||
includedir = @includedir@
|
||||
libdir = @libdir@
|
||||
shlibdir = @shlibdir@
|
||||
datarootdir = @datarootdir@
|
||||
datadir = @datadir@
|
||||
mandir = @mandir@
|
||||
|
||||
DOCUMENT_DIR = $(DESTDIR)$(datadir)/doc/$(PACKAGE)
|
||||
BIN_DIR = $(DESTDIR)$(bindir)
|
||||
INCLUDE_DIR = $(DESTDIR)$(includedir)
|
||||
INCLUDE_SUBDIR = $(DESTDIR)$(includedir)/$(HDR_ROOTNAME)
|
||||
SHLIB_DIR = $(DESTDIR)$(shlibdir)
|
||||
LIB_DIR = $(DESTDIR)$(libdir)
|
||||
MAN_DIR = $(DESTDIR)$(mandir)/man@MAN_TAG@
|
||||
MANSECT = @MANSECT@
|
||||
|
||||
CC = @CC@
|
||||
CPP = @CPP@
|
||||
AR = @AR@
|
||||
RANLIB = @LIB_PREP@
|
||||
RM = rm -f
|
||||
LN_S = @LN_S@
|
||||
CTAGS = @CTAGS@
|
||||
ETAGS = @ETAGS@
|
||||
LINT = @LINT@
|
||||
LINT_OPTS = @LINT_OPTS@
|
||||
|
||||
LIBS = @LIBS@
|
||||
|
||||
CFLAGS = @CFLAGS@ @EXTRA_CFLAGS@
|
||||
CPPFLAGS = @DEFS@ -I./include -I$(srcdir)/include @CPPFLAGS@
|
||||
|
||||
LDFLAGS = @LDFLAGS@
|
||||
RPATH_LIST = @RPATH_LIST@
|
||||
|
||||
LIBTOOL = @LIBTOOL@ @ECHO_LT@
|
||||
LIBTOOL_OPTS = @LIBTOOL_OPTS@
|
||||
LIBTOOL_CLEAN = @LIB_CLEAN@
|
||||
LIBTOOL_COMPILE = @LIB_COMPILE@
|
||||
LIBTOOL_CREATE = @LIB_CREATE@ $(EXTRA_LDFLAGS)
|
||||
LIBTOOL_LINK = @LIB_LINK@
|
||||
LIBTOOL_INSTALL = @LIB_INSTALL@
|
||||
LIBTOOL_UNINSTALL = @LIB_UNINSTALL@
|
||||
LIBTOOL_VERSION = @LIBTOOL_VERSION@
|
||||
|
||||
INSTALL = @INSTALL@
|
||||
INSTALL_PROGRAM = $(LIBTOOL_INSTALL) @INSTALL_PROGRAM@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
INSTALL_LIB = $(LIBTOOL_INSTALL) $(INSTALL_DATA)
|
||||
UNINSTALL_LIB = $(LIBTOOL_UNINSTALL) $(RM)
|
||||
|
||||
.SUFFIXES: .c .o .lo .os .i
|
||||
|
||||
default :: $(CDKLIB)
|
||||
|
||||
#
|
||||
# Create the file lists.
|
||||
#
|
||||
AUTO_HDR = \
|
||||
include/dscale.h \
|
||||
include/fscale.h \
|
||||
include/fslider.h \
|
||||
include/scale.h \
|
||||
include/slider.h \
|
||||
include/uscale.h \
|
||||
include/uslider.h
|
||||
|
||||
AUTO_SRC = \
|
||||
dscale.c \
|
||||
fscale.c \
|
||||
fslider.c \
|
||||
scale.c \
|
||||
slider.c \
|
||||
uscale.c \
|
||||
uslider.c
|
||||
|
||||
AUTO_MAN = \
|
||||
man/cdk_dscale.3 \
|
||||
man/cdk_fscale.3 \
|
||||
man/cdk_fslider.3 \
|
||||
man/cdk_scale.3 \
|
||||
man/cdk_slider.3 \
|
||||
man/cdk_uscale.3 \
|
||||
man/cdk_uslider.3
|
||||
|
||||
MY_HDR = \
|
||||
include/cdk_config.h \
|
||||
$(AUTO_HDR)
|
||||
|
||||
CDKHDR = \
|
||||
alphalist.h \
|
||||
binding.h \
|
||||
button.h \
|
||||
buttonbox.h \
|
||||
calendar.h \
|
||||
cdk.h \
|
||||
cdk_compat.h \
|
||||
cdk_objs.h \
|
||||
cdk_params.h \
|
||||
cdk_test.h \
|
||||
cdk_util.h \
|
||||
cdk_version.h \
|
||||
cdkscreen.h \
|
||||
curdefs.h \
|
||||
dialog.h \
|
||||
draw.h \
|
||||
entry.h \
|
||||
fselect.h \
|
||||
graph.h \
|
||||
histogram.h \
|
||||
itemlist.h \
|
||||
label.h \
|
||||
marquee.h \
|
||||
matrix.h \
|
||||
mentry.h \
|
||||
menu.h \
|
||||
radio.h \
|
||||
scroll.h \
|
||||
scroller.h \
|
||||
selection.h \
|
||||
swindow.h \
|
||||
template.h \
|
||||
traverse.h \
|
||||
viewer.h
|
||||
|
||||
CDKSRC = \
|
||||
$(AUTO_SRC) \
|
||||
alphalist.c \
|
||||
binding.c \
|
||||
button.c \
|
||||
buttonbox.c \
|
||||
calendar.c \
|
||||
cdk.c \
|
||||
cdk_compat.c \
|
||||
cdk_display.c \
|
||||
cdk_objs.c \
|
||||
cdk_params.c \
|
||||
cdkscreen.c \
|
||||
debug.c \
|
||||
dialog.c \
|
||||
draw.c \
|
||||
entry.c \
|
||||
fselect.c \
|
||||
get_index.c \
|
||||
get_string.c \
|
||||
graph.c \
|
||||
histogram.c \
|
||||
itemlist.c \
|
||||
label.c \
|
||||
marquee.c \
|
||||
matrix.c \
|
||||
mentry.c \
|
||||
menu.c \
|
||||
popup_dialog.c \
|
||||
popup_label.c \
|
||||
position.c \
|
||||
radio.c \
|
||||
scroll.c \
|
||||
scroller.c \
|
||||
selection.c \
|
||||
swindow.c \
|
||||
select_file.c \
|
||||
template.c \
|
||||
traverse.c \
|
||||
version.c \
|
||||
view_file.c \
|
||||
view_info.c \
|
||||
viewer.c
|
||||
|
||||
CDKMAN = \
|
||||
cdk.3 \
|
||||
cdk_alphalist.3 \
|
||||
cdk_binding.3 \
|
||||
cdk_button.3 \
|
||||
cdk_buttonbox.3 \
|
||||
cdk_calendar.3 \
|
||||
cdk_compat.3 \
|
||||
cdk_dialog.3 \
|
||||
cdk_display.3 \
|
||||
cdk_draw.3 \
|
||||
cdk_entry.3 \
|
||||
cdk_fscale.3 \
|
||||
cdk_fselect.3 \
|
||||
cdk_graph.3 \
|
||||
cdk_histogram.3 \
|
||||
cdk_itemlist.3 \
|
||||
cdk_label.3 \
|
||||
cdk_marquee.3 \
|
||||
cdk_matrix.3 \
|
||||
cdk_mentry.3 \
|
||||
cdk_menu.3 \
|
||||
cdk_misc.3 \
|
||||
cdk_objs.3 \
|
||||
cdk_params.3 \
|
||||
cdk_position.3 \
|
||||
cdk_process.3 \
|
||||
cdk_radio.3 \
|
||||
cdk_scale.3 \
|
||||
cdk_screen.3 \
|
||||
cdk_scroll.3 \
|
||||
cdk_selection.3 \
|
||||
cdk_swindow.3 \
|
||||
cdk_template.3 \
|
||||
cdk_traverse.3 \
|
||||
cdk_util.3 \
|
||||
cdk_viewer.3
|
||||
|
||||
CDKREADME = EXPANDING NOTES TODO COPYING INSTALL README
|
||||
|
||||
OBJECTS = $(CDKSRC:.c=.o)
|
||||
CDKSHOBJS = $(CDKSRC:.c=.os)
|
||||
LIB_OBJECT = @LIB_OBJECT@
|
||||
|
||||
all sources :: $(AUTO_SRC)
|
||||
|
||||
$(OBJECTS) : include/cdk_config.h
|
||||
|
||||
#
|
||||
# Standard library directive.
|
||||
#
|
||||
all cdklib :: $(CDKLIB)
|
||||
|
||||
@MAKE_NORMAL@cdkshlib $(OLD_SHLIB_FILE) :: $(CDKSHOBJS)
|
||||
@MAKE_NORMAL@ gcc -shared -Wl,-soname=$(OLD_SONAME) $(LDFLAGS) $(LIBS) -o $(OLD_SHLIB_FILE) $(CDKSHOBJS)
|
||||
|
||||
#
|
||||
# Make the examples directory.
|
||||
#
|
||||
all examples ::
|
||||
cd examples && $(MAKE) $(MAKE_RECUR)
|
||||
|
||||
#
|
||||
# Make the demos directory.
|
||||
#
|
||||
all demos ::
|
||||
cd demos && $(MAKE) $(MAKE_RECUR)
|
||||
|
||||
#
|
||||
# Make the cli directory.
|
||||
#
|
||||
all cli ::
|
||||
cd cli && $(MAKE) $(MAKE_RECUR)
|
||||
|
||||
#
|
||||
# Make the generated manpages.
|
||||
#
|
||||
all manpages :: $(AUTO_MAN)
|
||||
|
||||
# Order of install-targets should match the order of uninstalls. Put the
|
||||
# documentation first, then the headers, and finally the library:
|
||||
# (un)installCDKReadme
|
||||
# (un)installCDKManPages
|
||||
# (un)installCDKHeaderFiles
|
||||
# (un)installCDKLibrary
|
||||
|
||||
#
|
||||
# This installs the informational readme files.
|
||||
#
|
||||
install \
|
||||
installCDKReadme :: $(DOCUMENT_DIR)
|
||||
@echo "Installing CDK Readme files in $(DOCUMENT_DIR)..."
|
||||
@for i in $(CDKREADME); do \
|
||||
echo " ... $$i"; \
|
||||
$(INSTALL_DATA) $(srcdir)/$$i $(DOCUMENT_DIR)/$$i; \
|
||||
done
|
||||
|
||||
uninstall \
|
||||
uninstallCDKReadme ::
|
||||
@echo "Uninstalling CDK Readme files from $(DOCUMENT_DIR)..."
|
||||
@- for i in $(CDKREADME); do \
|
||||
$(RM) $(DOCUMENT_DIR)/$$i; \
|
||||
done
|
||||
|
||||
#
|
||||
# This installs the CDK man pages.
|
||||
#
|
||||
install \
|
||||
installCDKManPages :: headers.sed $(MAN_DIR) manpage.sed $(AUTO_MAN)
|
||||
@echo "Installing the CDK man pages in $(MAN_DIR) ..."
|
||||
@for i in $(AUTO_MAN); do \
|
||||
$(SHELL) $(srcdir)/headers.sh \
|
||||
-x "$(INSTALL_DATA)" \
|
||||
-d $(MAN_DIR) \
|
||||
-s . \
|
||||
-t $(MANSECT) \
|
||||
-e manpage.sed $$i; \
|
||||
$(SHELL) $(srcdir)/manlinks.sh installing $(srcdir) $(MAN_DIR) $(MANSECT) $$i; \
|
||||
done
|
||||
@for i in $(CDKMAN); do \
|
||||
$(SHELL) $(srcdir)/headers.sh \
|
||||
-x "$(INSTALL_DATA)" \
|
||||
-d $(MAN_DIR) \
|
||||
-s . \
|
||||
-t $(MANSECT) \
|
||||
-e manpage.sed $(srcdir)/man/$$i; \
|
||||
$(SHELL) $(srcdir)/manlinks.sh installing $(srcdir) $(MAN_DIR) $(MANSECT) $(srcdir)/man/$$i; \
|
||||
done
|
||||
|
||||
uninstall \
|
||||
uninstallCDKManPages ::
|
||||
@echo "Uninstalling the CDK man pages from $(MAN_DIR) ..."
|
||||
@- for i in $(AUTO_MAN); do \
|
||||
$(SHELL) $(srcdir)/manlinks.sh removing $(srcdir) $(MAN_DIR) $(MANSECT) $(srcdir)/$$i; \
|
||||
done
|
||||
@- for i in $(CDKMAN); do \
|
||||
$(SHELL) $(srcdir)/manlinks.sh removing $(srcdir) $(MAN_DIR) $(MANSECT) $(srcdir)/man/$$i; \
|
||||
done
|
||||
|
||||
#
|
||||
# This installs the header files.
|
||||
#
|
||||
HDR_SUBDIR = @HDR_SUBDIR@ -h cdk.h
|
||||
HEADERS_SH = $(SHELL) $(srcdir)/headers.sh $(HDR_SUBDIR) -x "$(INSTALL_DATA)" -d $(INCLUDE_SUBDIR) -s $(srcdir)
|
||||
install \
|
||||
installCDKHeaderFiles :: \
|
||||
$(INCLUDE_DIR) \
|
||||
$(INCLUDE_SUBDIR) \
|
||||
headers.sed \
|
||||
$(MY_HDR)
|
||||
@echo "Installing CDK header files in $(INCLUDE_SUBDIR)..."
|
||||
$(HEADERS_SH) $(MY_HDR)
|
||||
@for i in $(CDKHDR); do \
|
||||
$(HEADERS_SH) include/$$i; \
|
||||
done
|
||||
@HDR_SUBDIR@ rm -f $(INCLUDE_DIR)/cdk.h && mv $(INCLUDE_SUBDIR)/cdk.h $(INCLUDE_DIR)/$(PACKAGE).h
|
||||
|
||||
uninstall \
|
||||
uninstallCDKHeaderFiles ::
|
||||
@echo "Uninstalling CDK header files from $(INCLUDE_SUBDIR)..."
|
||||
@- for i in $(MY_HDR); do \
|
||||
$(RM) $(INCLUDE_SUBDIR)/`basename $$i`; \
|
||||
done
|
||||
@- for i in $(CDKHDR); do \
|
||||
$(RM) $(INCLUDE_SUBDIR)/$$i; \
|
||||
done
|
||||
@HDR_SUBDIR@ rm -f $(INCLUDE_DIR)/cdk.h
|
||||
|
||||
#
|
||||
# This installs the CDK library.
|
||||
#
|
||||
install \
|
||||
installCDKLibrary :: $(SHLIB_DIR) $(CDKLIB)
|
||||
@echo "Installing CDK library"
|
||||
@$(INSTALL_LIB) $(CDKLIB) $(SHLIB_DIR)/$(CDKLIB)
|
||||
|
||||
uninstall \
|
||||
uninstallCDKLibrary ::
|
||||
@echo "Uninstalling CDK library"
|
||||
@- $(UNINSTALL_LIB) $(SHLIB_DIR)/$(CDKLIB)
|
||||
|
||||
@MAKE_DLLS@install \
|
||||
@MAKE_DLLS@installImportLibrary :: $(LIB_DIR) $(IMPORT_LIB)
|
||||
@MAKE_DLLS@ @echo "Installing Import library"
|
||||
@MAKE_DLLS@ @$(INSTALL_LIB) $(IMPORT_LIB) $(LIB_DIR)/$(IMPORT_LIB)
|
||||
|
||||
@MAKE_DLLS@uninstall \
|
||||
@MAKE_DLLS@uninstallImportLibrary ::
|
||||
@MAKE_DLLS@ @echo "Uninstalling Import library"
|
||||
@MAKE_DLLS@ @- $(UNINSTALL_LIB) $(LIB_DIR)/$(IMPORT_LIB)
|
||||
|
||||
#
|
||||
# This installs the CDK package-config script.
|
||||
#
|
||||
install \
|
||||
installCDKHeaderFiles \
|
||||
installCDKLibrary :: $(BIN_DIR) cdk-config
|
||||
@echo "Installing script $(CFG_ROOTNAME)$(VERSION_MAJOR)-config"
|
||||
@$(INSTALL) cdk-config $(BIN_DIR)/$(CFG_ROOTNAME)$(VERSION_MAJOR)-config
|
||||
|
||||
uninstall \
|
||||
uninstallCDKHeaderFiles \
|
||||
uninstallCDKLibrary :: cdk-config
|
||||
@echo "Uninstalling script $(CFG_ROOTNAME)$(VERSION_MAJOR)-config"
|
||||
@$(RM) $(BIN_DIR)/$(CFG_ROOTNAME)$(VERSION_MAJOR)-config
|
||||
|
||||
#
|
||||
# This installs the CDK shared library. The rules are for an RPM spec, and
|
||||
# not of general interest.
|
||||
#
|
||||
@MAKE_NORMAL@installCDKSHLibrary :: $(SHLIB_DIR) $(OLD_SHLIB_FILE)
|
||||
@MAKE_NORMAL@ @echo "Installing CDK library"
|
||||
@MAKE_NORMAL@ @ECHO_CC@$(INSTALL_DATA) $(OLD_SHLIB_FILE) $(SHLIB_DIR)
|
||||
@MAKE_NORMAL@ @ECHO_CC@$(SHELL) -c "cd $(SHLIB_DIR) && $(LN_S) $(OLD_SHLIB_FILE) $(OLD_SONAME)"
|
||||
@MAKE_NORMAL@ @ECHO_CC@$(SHELL) -c "cd $(SHLIB_DIR) && $(LN_S) $(OLD_SHLIB_FILE) $(OLD_SHLIB_LINK)"
|
||||
@MAKE_NORMAL@
|
||||
@MAKE_NORMAL@uninstall \
|
||||
@MAKE_NORMAL@uninstallCDKSHLibrary ::
|
||||
@MAKE_NORMAL@ @ECHO_CC@- $(RM) $(SHLIB_DIR)/$(LIB_BASENAME)
|
||||
@MAKE_NORMAL@ @ECHO_CC@- $(RM) $(SHLIB_DIR)/$(OLD_SONAME)
|
||||
@MAKE_NORMAL@ @ECHO_CC@- $(RM) $(SHLIB_DIR)/$(OLD_SHLIB_FILE)
|
||||
|
||||
headers.sed : $(srcdir)/headers.sh
|
||||
$(SHELL) $(srcdir)/headers.sh -p CDK $(HDR_SUBDIR) -c include/cdk_config.h -d $(INCLUDE_SUBDIR) -s $(srcdir)/include -i -s include -i
|
||||
|
||||
manpage.sed :
|
||||
@echo "creating $@"
|
||||
@echo "s/(3)/($(MANSECT))/g" >$@
|
||||
@echo "/^\.TH/s/\<3\>/$(MANSECT)/" >>$@
|
||||
|
||||
@MAKE_LOWER_TAGS@tags :
|
||||
@MAKE_LOWER_TAGS@ $(CTAGS) *.[ch] */*.[ch]
|
||||
|
||||
@MAKE_LOWER_TAGS@TAGS :
|
||||
@MAKE_LOWER_TAGS@ $(ETAGS) *.[ch] */*.[ch]
|
||||
|
||||
lint: $(AUTO_HDR) $(AUTO_SRC) $(CDKSRC)
|
||||
$(LINT) $(LINT_OPTS) $(CPPFLAGS) $(AUTO_SRC) $(CDKSRC)
|
||||
|
||||
all-lint: lint
|
||||
cd examples && $(MAKE) $(MAKE_RECUR) lint
|
||||
cd demos && $(MAKE) $(MAKE_RECUR) lint
|
||||
cd cli && $(MAKE) $(MAKE_RECUR) lint
|
||||
|
||||
#
|
||||
# Clean up after ourselves...
|
||||
#
|
||||
clean ::
|
||||
@- $(RM) -r autom4te.cache
|
||||
- $(LIBTOOL_CLEAN) $(RM) $(LIB_OBJECT) $(CDKLIB) $(RM_SHARED_OPTS)
|
||||
@MAKE_NORMAL@ - $(RM) *.os $(OLD_SHLIB_FILE)
|
||||
- $(RM) headers.sed manpage.sed core tags *.i *~
|
||||
$(RM) $(AUTO_HDR)
|
||||
$(RM) $(AUTO_SRC)
|
||||
$(RM) $(AUTO_MAN)
|
||||
|
||||
realclean :: clean
|
||||
cd examples && $(MAKE) $(MAKE_RECUR) clean
|
||||
cd demos && $(MAKE) $(MAKE_RECUR) clean
|
||||
cd cli && $(MAKE) $(MAKE_RECUR) clean
|
||||
|
||||
#
|
||||
# Use this to clean the distribution.
|
||||
#
|
||||
distclean :: realclean
|
||||
$(RM) config.cache config.log config.status
|
||||
cd examples && $(RM) Makefile
|
||||
cd demos && $(RM) Makefile
|
||||
cd cli && $(RM) Makefile
|
||||
$(RM) include/cdk_config.h
|
||||
$(RM) include/cdk_version.h
|
||||
$(RM) Makefile
|
||||
$(RM) cdk-config
|
||||
$(RM) mk_shared_lib.sh
|
||||
@- $(SHELL) -c 'if test "$(srcdir)" != . ; then \
|
||||
rmdir examples; \
|
||||
rmdir demos; \
|
||||
rmdir cli; \
|
||||
rmdir include; \
|
||||
fi'
|
||||
|
||||
#
|
||||
# Standard .c to .o compile line.
|
||||
#
|
||||
.c.o:
|
||||
@RULE_CC@
|
||||
@ECHO_CC@$(LIBTOOL_COMPILE) $(CC) $(CFLAGS) $(CPPFLAGS) -c $<
|
||||
|
||||
.c.lo:
|
||||
@RULE_CC@
|
||||
@ECHO_CC@$(LIBTOOL_COMPILE) $(CC) $(CFLAGS) $(CPPFLAGS) -c $<
|
||||
|
||||
.c.i:
|
||||
@RULE_CC@
|
||||
@ECHO_CC@$(CPP) $(CPPFLAGS) -E -C $< >$@
|
||||
|
||||
.c.os:
|
||||
@RULE_CC@
|
||||
@ECHO_CC@$(CC) $(CFLAGS) $(CPPFLAGS) -c -fPIC $< -o $@
|
||||
|
||||
man \
|
||||
$(BIN_DIR) \
|
||||
$(DOCUMENT_DIR) \
|
||||
$(INCLUDE_DIR) \
|
||||
$(INCLUDE_SUBDIR) \
|
||||
$(LIB_DIR) \
|
||||
$(MAN_DIR) : ; mkdir -p $@
|
||||
|
||||
#
|
||||
# Files generated from templates:
|
||||
#
|
||||
GEN_SCALE = $(SHELL) $(srcdir)/gen-scale.sh
|
||||
|
||||
SCALE_H = $(srcdir)/include/gen-scale.h
|
||||
SCALE_C = $(srcdir)/gen-scale.c
|
||||
SCALE_M = $(srcdir)/man/gen-scale.3
|
||||
|
||||
MKDIR_MAN = test -d man || mkdir man
|
||||
|
||||
include/dscale.h : $(SCALE_H)
|
||||
$(GEN_SCALE) DSCALE DScale Double double $(SCALE_H) >$@
|
||||
dscale.c : $(SCALE_C) $(AUTO_HDR)
|
||||
$(GEN_SCALE) DSCALE DScale Double double $(SCALE_C) >$@
|
||||
man/cdk_dscale.3 : $(SCALE_M) man
|
||||
-$(MKDIR_MAN)
|
||||
$(GEN_SCALE) DSCALE DScale Double double $(SCALE_M) >$@
|
||||
|
||||
include/fscale.h : $(SCALE_H)
|
||||
$(GEN_SCALE) FSCALE FScale Float float $(SCALE_H) >$@
|
||||
fscale.c : $(SCALE_C) $(AUTO_HDR)
|
||||
$(GEN_SCALE) FSCALE FScale Float float $(SCALE_C) >$@
|
||||
man/cdk_fscale.3 : $(SCALE_M) man
|
||||
-$(MKDIR_MAN)
|
||||
$(GEN_SCALE) FSCALE FScale Float float $(SCALE_M) >$@
|
||||
|
||||
include/scale.h : $(SCALE_H)
|
||||
$(GEN_SCALE) SCALE Scale Int int $(SCALE_H) >$@
|
||||
scale.c : $(SCALE_C) $(AUTO_HDR)
|
||||
$(GEN_SCALE) SCALE Scale Int int $(SCALE_C) >$@
|
||||
man/cdk_scale.3 : $(SCALE_M) man
|
||||
-$(MKDIR_MAN)
|
||||
$(GEN_SCALE) SCALE Scale Int int $(SCALE_M) >$@
|
||||
|
||||
include/uscale.h : $(SCALE_H)
|
||||
$(GEN_SCALE) USCALE UScale Unsigned unsigned $(SCALE_H) >$@
|
||||
uscale.c : $(SCALE_C) $(AUTO_HDR)
|
||||
$(GEN_SCALE) USCALE UScale Unsigned unsigned $(SCALE_C) >$@
|
||||
man/cdk_uscale.3 : $(SCALE_M) man
|
||||
-$(MKDIR_MAN)
|
||||
$(GEN_SCALE) USCALE UScale Unsigned unsigned $(SCALE_M) >$@
|
||||
|
||||
SLIDER_H = $(srcdir)/include/gen-slider.h
|
||||
SLIDER_C = $(srcdir)/gen-slider.c
|
||||
SLIDER_M = $(srcdir)/man/gen-slider.3
|
||||
|
||||
include/fslider.h : $(SLIDER_H)
|
||||
$(GEN_SCALE) FSLIDER FSlider Float float $(SLIDER_H) >$@
|
||||
fslider.c : $(SLIDER_C) $(AUTO_HDR)
|
||||
$(GEN_SCALE) FSLIDER FSlider Float float $(SLIDER_C) >$@
|
||||
man/cdk_fslider.3 : $(SLIDER_M) man
|
||||
-$(MKDIR_MAN)
|
||||
$(GEN_SCALE) FSLIDER FSlider Float float $(SLIDER_M) >$@
|
||||
|
||||
include/slider.h : $(SLIDER_H)
|
||||
$(GEN_SCALE) SLIDER Slider Int int $(SLIDER_H) >$@
|
||||
slider.c : $(SLIDER_C) $(AUTO_HDR)
|
||||
$(GEN_SCALE) SLIDER Slider Int int $(SLIDER_C) >$@
|
||||
man/cdk_slider.3 : $(SLIDER_M) man
|
||||
-$(MKDIR_MAN)
|
||||
$(GEN_SCALE) SLIDER Slider Int int $(SLIDER_M) >$@
|
||||
|
||||
include/uslider.h : $(SLIDER_H)
|
||||
$(GEN_SCALE) USLIDER USlider Unsigned unsigned $(SLIDER_H) >$@
|
||||
uslider.c : $(SLIDER_C) $(AUTO_HDR)
|
||||
$(GEN_SCALE) USLIDER USlider Unsigned unsigned $(SLIDER_C) >$@
|
||||
man/cdk_uslider.3 : $(SLIDER_M) man
|
||||
-$(MKDIR_MAN)
|
||||
$(GEN_SCALE) USLIDER USlider Unsigned unsigned $(SLIDER_M) >$@
|
|
@ -1,48 +0,0 @@
|
|||
Cdk Notes
|
||||
Copyright Mike Glover, 1995, 1996, 1997, 1998, 1999
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
This document states some of the testing and history of the Cdk widget set.
|
||||
|
||||
Cdk has gone through a major facelift since I first created it, and it's
|
||||
current look I like enough to release and attach my name to. :) I have made sure
|
||||
to remain as consistent as possible with function parameter positions, names,
|
||||
purposes, and what-not. I hope I have been, if not mail me tell me what you
|
||||
find inconsistent and I may change it. I say may because I don't want to kill
|
||||
anyone's code if I can help it. That is why I waited so long before releasing
|
||||
Cdk. I wanted it to be as stable as possible before sending it out into the
|
||||
world. I think it's stable, and hopefully so will you. There are a few things
|
||||
worth noting before continuing.
|
||||
|
||||
Cdk has gone through some fairly rigorous testing, but since I did the testing
|
||||
it may not be complete. I have complied the code with Purify (TM) and
|
||||
Centerline's Testcenter (TM) and both say my code is clean. There are no
|
||||
memory leaks, and the only problems exist in the curses library. If you use the
|
||||
Ncurses library, it has been cleaned. Of course I am not the best to ask. The
|
||||
only reason why I can say this is because I asked the Ncurses author. I don't
|
||||
know how clean it is. I will assume very clean.
|
||||
|
||||
But since I may not be able to see the forest for the trees, I'm willing to
|
||||
bet that bugs still do exist, and you folks will find them. If you do find bugs
|
||||
read the BUGS document supplied with this release to find out what to do.
|
||||
|
||||
I do not plan on changing the interface to Cdk, so any code developed in it now
|
||||
should pass the test of time. The only changes I can see are bug fixes and new
|
||||
widgets. Lets hope this wish of mine remains true...
|
||||
|
||||
There is an examples directory available which demonstrates all of the widgets
|
||||
and some extra concepts, it's a great place to tool around in before banging
|
||||
away at your own code.
|
||||
|
||||
If you want to get a hold of me mail me at one of the following:
|
||||
glover@credit.erin.utoronto.ca
|
||||
mike@vexus.ca
|
||||
|
||||
The CDK Web page has several homes. They are:
|
||||
http://www.vexus.ca/CDK.html (official)
|
||||
http://www.datasoft.on.ca/~cdk (Sponsered by the nice folks at Datasoft)
|
||||
|
||||
Have fun. :)
|
||||
|
||||
ttfn,
|
||||
Mike
|
|
@ -1,150 +0,0 @@
|
|||
-- $Id: README,v 1.10 2016/01/31 19:55:06 tom Exp $
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
Copyright Thomas Dickey 1999-2015,2016
|
||||
|
||||
This is a modified/enhanced version of Cdk. The original README contents are
|
||||
given below.
|
||||
|
||||
This version of Cdk is found at
|
||||
|
||||
http://invisible-island.net/cdk/
|
||||
ftp://invisible-island.net/cdk/
|
||||
|
||||
The intent of the modifications is to preserve nominal compatibility with the
|
||||
original Cdk, while fixing bugs and design limitations. Some macros such as
|
||||
ObjOf() have been introduced to move details out of individual widgets into
|
||||
common functionality (see the cdk_objs.h header). In addition, fixed array
|
||||
limits have been removed, using new functions in some instances which do not
|
||||
have the fixed limits.
|
||||
|
||||
Converting a program which uses the original Cdk is done by wrapping the widget
|
||||
pointers in ObjOf() for struct members which have been moved into the CDKOBJS
|
||||
struct. This is not a one-way conversion (for many applications), since a
|
||||
header cdk_compat.h defines ObjOf() and a few obsolete functions which may be
|
||||
used by older programs. By wrapping the widget pointers as needed in ObjOf(),
|
||||
one may compile the same source against the old/new versions of Cdk to check
|
||||
that the application is correctly upgraded.
|
||||
|
||||
Once converted, there are additional functions and widgets provided by the
|
||||
new version of Cdk. Bugs should (as noted on the webpage) be reported to me.
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
Cdk Readme Guide
|
||||
Copyright Mike Glover, 1995, 1996, 1997, 1998, 1999
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
Overview:
|
||||
---------
|
||||
Cdk stands for 'Curses Development Kit' and it currently contains 21 ready
|
||||
to use widgets which facilitate the speedy development of full screen
|
||||
curses programs. This little project of mine started as a test to see how
|
||||
compatible my Linux machine was to other UNIX breeds. While doing this I
|
||||
discovered Ncurses, and played with it. These widgets are the result of
|
||||
over a years worth of playing. The current complement of widgets are:
|
||||
|
||||
Widget Type Quick Description
|
||||
===========================================================================
|
||||
Alphalist Allows a user to select from a list of words, with
|
||||
the ability to narrow the search list by typing in a
|
||||
few characters of the desired word.
|
||||
Buttonbox This creates a multiple button widget.
|
||||
Calendar Creates a little simple calendar widget.
|
||||
Dialog Prompts the user with a message, and the user
|
||||
can pick an answer from the buttons provided.
|
||||
Entry Allows the user to enter various types of information.
|
||||
File Selector A file selector built from Cdk base widgets. This
|
||||
example shows how to create more complicated widgets
|
||||
using the Cdk widget library.
|
||||
Graph Draws a graph.
|
||||
Histogram Draws a histogram.
|
||||
Item List Creates a pop up field which allows the user to select
|
||||
one of several choices in a small field. Very useful
|
||||
for things like days of the week or month names.
|
||||
Label Displays messages in a pop up box, or the label can be
|
||||
considered part of the screen.
|
||||
Marquee Displays a message in a scrolling marquee.
|
||||
Matrix Creates a complex matrix with lots of options.
|
||||
Menu Creates a pull-down menu interface.
|
||||
Multiple Line Entry A multiple line entry field. Very useful
|
||||
for long fields. (like a description
|
||||
field)
|
||||
Radio List Creates a radio button list.
|
||||
Scale Creates a numeric scale. Used for allowing a user to
|
||||
pick a numeric value and restrict them to a range of
|
||||
values.
|
||||
Scrolling List Creates a scrolling list/menu list.
|
||||
Scrolling Window Creates a scrolling log file viewer. Can add
|
||||
information into the window while its running.
|
||||
A good widget for displaying the progress of
|
||||
something. (akin to a console window)
|
||||
Selection List Creates a multiple option selection list.
|
||||
Slider Akin to the scale widget, this widget provides a
|
||||
visual slide bar to represent the numeric value.
|
||||
Template Creates a entry field with character sensitive
|
||||
positions. Used for pre-formatted fields like
|
||||
dates and phone numbers.
|
||||
Viewer This is a file/information viewer. Very useful
|
||||
when you need to display loads of information.
|
||||
===========================================================================
|
||||
|
||||
Each widget has the ability to display color, or other character attributes.
|
||||
Cdk comes with a attribute/color format command set which allows a programmer
|
||||
to add colors and characters attributes simply.
|
||||
|
||||
The code has been cleaned using both Purify(TM) and Sun's Testcenter(TM),
|
||||
so it is as clean as a babies butt. :) Any leaks I have seen are in the curses
|
||||
libraries; there is nothing I can do about that, sorry. There should be no
|
||||
memory leaks within the code, it shouldn't core dump, and it shouldn't do
|
||||
anything unexpected. Unfortunately this probably is not the case. If you do
|
||||
see something like this tell me after you read the BUGS file.
|
||||
|
||||
Distribution:
|
||||
-------------
|
||||
This distribution has a full complement of manual pages, so any specifics to
|
||||
the widgets will not be addressed in this read me. If you want to get right in
|
||||
there, nroff the cdk.3 file in the man directory. It is the starting point
|
||||
for all the manual pages.
|
||||
|
||||
There are some other files to look at if you want to get anywhere. They are:
|
||||
|
||||
INSTALL - This will show you how to build Cdk and install it on your system.
|
||||
If there are any personal modifications that you think may be
|
||||
needed, read this file. In fact read it regardless. :)
|
||||
|
||||
COPYING - The legal stuff to protect my butt and all of the hard work that I
|
||||
have put into this library.
|
||||
|
||||
EXPANDING - You feel creative enough to add a widget, here are my requirements
|
||||
that you have to follow to make the integration of a new widget
|
||||
seamless.
|
||||
|
||||
BUGS - What to do when you find a bug. It also lists all of the bugs found,
|
||||
who found them, who fixed them, and when they were fixed. If you think
|
||||
you have found a bug look at this file. If you do not think you have
|
||||
the most up to date version of Cdk, go get it and try to replicate the
|
||||
problem. Then look at the BUGS file again. If it is NOT there, then you
|
||||
can mail me notifying me of a possible bug. I will try my hardest to get
|
||||
back to you, but I have a pretty busy schedule so don't expect an instant
|
||||
reply. This file will also explain how I would like any bug fixes sent to
|
||||
me.
|
||||
|
||||
NOTES - Misc babblings of myself somewhat related to this distribution.
|
||||
|
||||
TODO - A list of things I plan to do in the future. (sleep)
|
||||
|
||||
CHANGES - A list of changes from one release to another.
|
||||
|
||||
If you want to get a hold of me mail me at one of the following:
|
||||
glover@credit.erin.utoronto.ca
|
||||
mike@vexus.ca
|
||||
|
||||
The CDK Web page has several homes. They are:
|
||||
http://www.vexus.ca/CDK.html (official)
|
||||
http://www.datasoft.on.ca/~cdk (Sponsored by the nice folks at Datasoft)
|
||||
|
||||
ttfn,
|
||||
Mike
|
||||
|
||||
PS: There is also a Perl5 extension of this library for you Perl5 fans.
|
||||
Look under any CPAN site under the directory CPAN/authors/id/GLOVER.
|
|
@ -1,53 +0,0 @@
|
|||
Cdk To-Do List
|
||||
Copyright Mike Glover, 1995, 1996, 1997, 1998, 1999
|
||||
------------------------------------------------------------------------------
|
||||
|
||||
There are a few things that I am either currently working on, or going to
|
||||
work on in the near future. They are:
|
||||
|
||||
* Add more functions to the drawing routines. (yadda, yadda, yadda...)
|
||||
* Working on a tree widget...
|
||||
* Working on a tab list widget...
|
||||
* I would like to be able to have a captive shell widget. This
|
||||
would allow you to start a subshell and have the user interact
|
||||
with a spawned command via the captive shell. This would allow
|
||||
you to spawn an interactive command through the widget. If any
|
||||
one knows how to do this, please mail me. Maybe we'll work this
|
||||
through. (I WOULD LOVE TO ADD THIS, IF ANYONE HAS ANY IDEAS
|
||||
PLEASE MAIL ME)
|
||||
* I am thinking about adding an X windows element to Cdk using
|
||||
the Xforms library, because it seems to have roughly the same
|
||||
widgets as I do. The plan is to have a simple environment variable
|
||||
which tells the program what you want curses/X windows. We'll
|
||||
see how this goes.
|
||||
* I am going to (in the next revision), make the Cdk library more
|
||||
X like with the ability to set/get attributes of the widgets via
|
||||
functions. The proposed method is something like :
|
||||
|
||||
value = CdkEntryGetXXX (widget)
|
||||
CdkEntrySetXXX (widget, value)
|
||||
|
||||
Where XXX is a property of the widget. It would be nice to create
|
||||
a singlar widget type (CdkWidget) and to have generic functions
|
||||
set/get the properties. (this is all being thought of to phase
|
||||
in the X/Cdk idea mentioned above.)
|
||||
* I'm also working on fixing the way the default callback function
|
||||
for the widget editing functions is called. (i know this is brief,
|
||||
but it's there more to remind me of an idea which was spurred on by
|
||||
someone else's suggestion.)
|
||||
* Version 5 should have the ability to properly attach widgets
|
||||
together via constraints, positioning within forms, etc... The
|
||||
next inception should make it simpler to create home-grown widgets.
|
||||
(Version 5 may also only support Ncurses because I'm losing a lot
|
||||
of functionality by being backward compatible.)
|
||||
|
||||
If you want to get a hold of me mail me at one of the following:
|
||||
glover@credit.erin.utoronto.ca
|
||||
mike@vexus.ca
|
||||
|
||||
The CDK Web page has several homes. They are:
|
||||
http://www.vexus.ca/CDK.html (official)
|
||||
http://www.datasoft.on.ca/~cdk (Sponsored by the nice folks at Datasoft)
|
||||
|
||||
ttfn,
|
||||
Mike
|
|
@ -1 +0,0 @@
|
|||
6:1:4 5.0 20161210
|
File diff suppressed because it is too large
Load Diff
|
@ -1,939 +0,0 @@
|
|||
#include <cdk_int.h>
|
||||
|
||||
/*
|
||||
* $Author: tom $
|
||||
* $Date: 2016/11/20 18:39:12 $
|
||||
* $Revision: 1.111 $
|
||||
*/
|
||||
|
||||
/*
|
||||
* Declare file local prototypes.
|
||||
*/
|
||||
static BINDFN_PROTO (adjustAlphalistCB);
|
||||
static BINDFN_PROTO (completeWordCB);
|
||||
static int preProcessEntryField (EObjectType, void *, void *, chtype);
|
||||
static int createList (CDKALPHALIST *alphalist, CDK_CSTRING *list, int listSize);
|
||||
|
||||
DeclareSetXXchar (static, _setMy);
|
||||
DeclareCDKObjects (ALPHALIST, Alphalist, _setMy, String);
|
||||
|
||||
/*
|
||||
* This creates the alphalist widget.
|
||||
*/
|
||||
CDKALPHALIST *newCDKAlphalist (CDKSCREEN *cdkscreen,
|
||||
int xplace,
|
||||
int yplace,
|
||||
int height,
|
||||
int width,
|
||||
const char *title,
|
||||
const char *label,
|
||||
CDK_CSTRING *list,
|
||||
int listSize,
|
||||
chtype fillerChar,
|
||||
chtype highlight,
|
||||
boolean Box,
|
||||
boolean shadow)
|
||||
{
|
||||
/* *INDENT-EQLS* */
|
||||
CDKALPHALIST *alphalist = 0;
|
||||
int parentWidth = getmaxx (cdkscreen->window);
|
||||
int parentHeight = getmaxy (cdkscreen->window);
|
||||
int boxWidth;
|
||||
int boxHeight;
|
||||
int xpos = xplace;
|
||||
int ypos = yplace;
|
||||
int tempWidth = 0;
|
||||
int tempHeight = 0;
|
||||
int labelLen = 0;
|
||||
int x, junk2;
|
||||
/* *INDENT-OFF* */
|
||||
static const struct { int from; int to; } bindings[] = {
|
||||
{ CDK_BACKCHAR, KEY_PPAGE },
|
||||
{ CDK_FORCHAR, KEY_NPAGE },
|
||||
};
|
||||
/* *INDENT-ON* */
|
||||
|
||||
if ((alphalist = newCDKObject (CDKALPHALIST, &my_funcs)) == 0
|
||||
|| !createList (alphalist, list, listSize))
|
||||
{
|
||||
destroyCDKObject (alphalist);
|
||||
return (0);
|
||||
}
|
||||
|
||||
setCDKAlphalistBox (alphalist, Box);
|
||||
|
||||
/*
|
||||
* If the height is a negative value, the height will
|
||||
* be ROWS-height, otherwise, the height will be the
|
||||
* given height.
|
||||
*/
|
||||
boxHeight = setWidgetDimension (parentHeight, height, 0);
|
||||
|
||||
/*
|
||||
* If the width is a negative value, the width will
|
||||
* be COLS-width, otherwise, the width will be the
|
||||
* given width.
|
||||
*/
|
||||
boxWidth = setWidgetDimension (parentWidth, width, 0);
|
||||
|
||||
/* Translate the label char *pointer to a chtype pointer. */
|
||||
if (label != 0)
|
||||
{
|
||||
chtype *chtypeLabel = char2Chtype (label, &labelLen, &junk2);
|
||||
freeChtype (chtypeLabel);
|
||||
}
|
||||
|
||||
/* Rejustify the x and y positions if we need to. */
|
||||
alignxy (cdkscreen->window, &xpos, &ypos, boxWidth, boxHeight);
|
||||
|
||||
/* Make the file selector window. */
|
||||
alphalist->win = newwin (boxHeight, boxWidth, ypos, xpos);
|
||||
|
||||
if (alphalist->win == 0)
|
||||
{
|
||||
destroyCDKObject (alphalist);
|
||||
return (0);
|
||||
}
|
||||
keypad (alphalist->win, TRUE);
|
||||
|
||||
/* *INDENT-EQLS* Set some variables. */
|
||||
ScreenOf (alphalist) = cdkscreen;
|
||||
alphalist->parent = cdkscreen->window;
|
||||
alphalist->highlight = highlight;
|
||||
alphalist->fillerChar = fillerChar;
|
||||
alphalist->boxHeight = boxHeight;
|
||||
alphalist->boxWidth = boxWidth;
|
||||
initExitType (alphalist);
|
||||
alphalist->shadow = shadow;
|
||||
alphalist->shadowWin = 0;
|
||||
|
||||
/* Do we want a shadow? */
|
||||
if (shadow)
|
||||
{
|
||||
alphalist->shadowWin = newwin (boxHeight, boxWidth, ypos + 1, xpos + 1);
|
||||
}
|
||||
|
||||
/* Create the entry field. */
|
||||
tempWidth = (isFullWidth (width)
|
||||
? FULL
|
||||
: boxWidth - 2 - labelLen);
|
||||
alphalist->entryField = newCDKEntry (cdkscreen,
|
||||
getbegx (alphalist->win),
|
||||
getbegy (alphalist->win),
|
||||
title, label,
|
||||
A_NORMAL, fillerChar,
|
||||
vMIXED, tempWidth, 0, 512,
|
||||
Box, FALSE);
|
||||
if (alphalist->entryField == 0)
|
||||
{
|
||||
destroyCDKObject (alphalist);
|
||||
return (0);
|
||||
}
|
||||
setCDKEntryLLChar (alphalist->entryField, ACS_LTEE);
|
||||
setCDKEntryLRChar (alphalist->entryField, ACS_RTEE);
|
||||
|
||||
/* Set the key bindings for the entry field. */
|
||||
bindCDKObject (vENTRY,
|
||||
alphalist->entryField,
|
||||
KEY_UP,
|
||||
adjustAlphalistCB,
|
||||
alphalist);
|
||||
bindCDKObject (vENTRY,
|
||||
alphalist->entryField,
|
||||
KEY_DOWN,
|
||||
adjustAlphalistCB,
|
||||
alphalist);
|
||||
bindCDKObject (vENTRY,
|
||||
alphalist->entryField,
|
||||
KEY_NPAGE,
|
||||
adjustAlphalistCB,
|
||||
alphalist);
|
||||
bindCDKObject (vENTRY,
|
||||
alphalist->entryField,
|
||||
KEY_PPAGE,
|
||||
adjustAlphalistCB,
|
||||
alphalist);
|
||||
bindCDKObject (vENTRY,
|
||||
alphalist->entryField,
|
||||
KEY_TAB,
|
||||
completeWordCB,
|
||||
alphalist);
|
||||
|
||||
/* Set up the post-process function for the entry field. */
|
||||
setCDKEntryPreProcess (alphalist->entryField, preProcessEntryField, alphalist);
|
||||
|
||||
/*
|
||||
* Create the scrolling list. It overlaps the entry field by one line if
|
||||
* we are using box-borders.
|
||||
*/
|
||||
tempHeight = getmaxy (alphalist->entryField->win) - BorderOf (alphalist);
|
||||
tempWidth = (isFullWidth (width)
|
||||
? FULL
|
||||
: boxWidth - 1);
|
||||
alphalist->scrollField = newCDKScroll (cdkscreen,
|
||||
getbegx (alphalist->win),
|
||||
getbegy (alphalist->entryField->win)
|
||||
+ tempHeight,
|
||||
RIGHT,
|
||||
boxHeight - tempHeight,
|
||||
tempWidth,
|
||||
0, (CDK_CSTRING2)list, listSize,
|
||||
NONUMBERS, A_REVERSE,
|
||||
Box, FALSE);
|
||||
setCDKScrollULChar (alphalist->scrollField, ACS_LTEE);
|
||||
setCDKScrollURChar (alphalist->scrollField, ACS_RTEE);
|
||||
|
||||
/* Setup the key bindings. */
|
||||
for (x = 0; x < (int)SIZEOF (bindings); ++x)
|
||||
bindCDKObject (vALPHALIST,
|
||||
alphalist,
|
||||
(chtype)bindings[x].from,
|
||||
getcCDKBind,
|
||||
(void *)(long)bindings[x].to);
|
||||
|
||||
registerCDKObject (cdkscreen, vALPHALIST, alphalist);
|
||||
|
||||
return (alphalist);
|
||||
}
|
||||
|
||||
/*
|
||||
* This erases the file selector from the screen.
|
||||
*/
|
||||
static void _eraseCDKAlphalist (CDKOBJS *object)
|
||||
{
|
||||
if (validCDKObject (object))
|
||||
{
|
||||
CDKALPHALIST *alphalist = (CDKALPHALIST *)object;
|
||||
|
||||
eraseCDKScroll (alphalist->scrollField);
|
||||
eraseCDKEntry (alphalist->entryField);
|
||||
|
||||
eraseCursesWindow (alphalist->shadowWin);
|
||||
eraseCursesWindow (alphalist->win);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This moves the alphalist field to the given location.
|
||||
*/
|
||||
static void _moveCDKAlphalist (CDKOBJS *object,
|
||||
int xplace,
|
||||
int yplace,
|
||||
boolean relative,
|
||||
boolean refresh_flag)
|
||||
{
|
||||
CDKALPHALIST *alphalist = (CDKALPHALIST *)object;
|
||||
/* *INDENT-EQLS* */
|
||||
int currentX = getbegx (alphalist->win);
|
||||
int currentY = getbegy (alphalist->win);
|
||||
int xpos = xplace;
|
||||
int ypos = yplace;
|
||||
int xdiff = 0;
|
||||
int ydiff = 0;
|
||||
|
||||
/*
|
||||
* If this is a relative move, then we will adjust where we want
|
||||
* to move to.
|
||||
*/
|
||||
if (relative)
|
||||
{
|
||||
xpos = getbegx (alphalist->win) + xplace;
|
||||
ypos = getbegy (alphalist->win) + yplace;
|
||||
}
|
||||
|
||||
/* Adjust the window if we need to. */
|
||||
alignxy (WindowOf (alphalist), &xpos, &ypos, alphalist->boxWidth, alphalist->boxHeight);
|
||||
|
||||
/* Get the difference. */
|
||||
xdiff = currentX - xpos;
|
||||
ydiff = currentY - ypos;
|
||||
|
||||
/* Move the window to the new location. */
|
||||
moveCursesWindow (alphalist->win, -xdiff, -ydiff);
|
||||
moveCursesWindow (alphalist->shadowWin, -xdiff, -ydiff);
|
||||
|
||||
/* Move the sub-widgets. */
|
||||
moveCDKEntry (alphalist->entryField, xplace, yplace, relative, FALSE);
|
||||
moveCDKScroll (alphalist->scrollField, xplace, yplace, relative, FALSE);
|
||||
|
||||
/* Touch the windows so they 'move'. */
|
||||
refreshCDKWindow (WindowOf (alphalist));
|
||||
|
||||
/* Redraw the window, if they asked for it. */
|
||||
if (refresh_flag)
|
||||
{
|
||||
drawCDKAlphalist (alphalist, ObjOf (alphalist)->box);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* The alphalist's focus resides in the entry widget. But the scroll widget
|
||||
* will not draw items highlighted unless it has focus. Temporarily adjust the
|
||||
* focus of the scroll widget when drawing on it to get the right highlighting.
|
||||
*/
|
||||
#define SaveFocus(widget) \
|
||||
boolean save = HasFocusObj (ObjOf (widget->scrollField)); \
|
||||
HasFocusObj (ObjOf (widget->scrollField)) = \
|
||||
HasFocusObj (ObjOf (widget->entryField))
|
||||
|
||||
#define RestoreFocus(widget) \
|
||||
HasFocusObj (ObjOf (widget->scrollField)) = save
|
||||
|
||||
static void drawMyScroller (CDKALPHALIST *widget)
|
||||
{
|
||||
SaveFocus (widget);
|
||||
drawCDKScroll (widget->scrollField, ObjOf (widget->scrollField)->box);
|
||||
RestoreFocus (widget);
|
||||
}
|
||||
|
||||
static void injectMyScroller (CDKALPHALIST *widget, chtype key)
|
||||
{
|
||||
SaveFocus (widget);
|
||||
(void)injectCDKScroll (widget->scrollField, key);
|
||||
RestoreFocus (widget);
|
||||
}
|
||||
|
||||
/*
|
||||
* This draws the file selector widget.
|
||||
*/
|
||||
static void _drawCDKAlphalist (CDKOBJS *obj, boolean Box GCC_UNUSED)
|
||||
{
|
||||
CDKALPHALIST *alphalist = (CDKALPHALIST *)obj;
|
||||
|
||||
/* Does this widget have a shadow? */
|
||||
if (alphalist->shadowWin != 0)
|
||||
{
|
||||
drawShadow (alphalist->shadowWin);
|
||||
}
|
||||
|
||||
/* Draw in the entry field. */
|
||||
drawCDKEntry (alphalist->entryField, ObjOf (alphalist->entryField)->box);
|
||||
|
||||
/* Draw in the scroll field. */
|
||||
drawMyScroller (alphalist);
|
||||
}
|
||||
|
||||
/*
|
||||
* This activates the file selector.
|
||||
*/
|
||||
char *activateCDKAlphalist (CDKALPHALIST *alphalist, chtype *actions)
|
||||
{
|
||||
char *ret = 0;
|
||||
|
||||
/* Draw the widget. */
|
||||
drawCDKAlphalist (alphalist, ObjOf (alphalist)->box);
|
||||
|
||||
/* Activate the widget. */
|
||||
ret = activateCDKEntry (alphalist->entryField, actions);
|
||||
|
||||
/* Copy the exit type from the entry field. */
|
||||
copyExitType (alphalist, alphalist->entryField);
|
||||
|
||||
/* Determine the exit status. */
|
||||
if (alphalist->exitType != vEARLY_EXIT)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* This injects a single character into the alphalist.
|
||||
*/
|
||||
static int _injectCDKAlphalist (CDKOBJS *object, chtype input)
|
||||
{
|
||||
CDKALPHALIST *alphalist = (CDKALPHALIST *)object;
|
||||
char *ret;
|
||||
|
||||
/* Draw the widget. */
|
||||
drawCDKAlphalist (alphalist, ObjOf (alphalist)->box);
|
||||
|
||||
/* Inject a character into the widget. */
|
||||
ret = injectCDKEntry (alphalist->entryField, input);
|
||||
|
||||
/* Copy the exit type from the entry field. */
|
||||
copyExitType (alphalist, alphalist->entryField);
|
||||
|
||||
/* Determine the exit status. */
|
||||
if (alphalist->exitType == vEARLY_EXIT)
|
||||
ret = unknownString;
|
||||
|
||||
ResultOf (alphalist).valueString = ret;
|
||||
return (ret != unknownString);
|
||||
}
|
||||
|
||||
/*
|
||||
* This sets multiple attributes of the widget.
|
||||
*/
|
||||
void setCDKAlphalist (CDKALPHALIST *alphalist,
|
||||
CDK_CSTRING *list,
|
||||
int listSize,
|
||||
chtype fillerChar,
|
||||
chtype highlight,
|
||||
boolean Box)
|
||||
{
|
||||
setCDKAlphalistContents (alphalist, list, listSize);
|
||||
setCDKAlphalistFillerChar (alphalist, fillerChar);
|
||||
setCDKAlphalistHighlight (alphalist, highlight);
|
||||
setCDKAlphalistBox (alphalist, Box);
|
||||
}
|
||||
|
||||
/*
|
||||
* This function sets the information inside the file selector.
|
||||
*/
|
||||
void setCDKAlphalistContents (CDKALPHALIST *widget, CDK_CSTRING *list, int listSize)
|
||||
{
|
||||
CDKSCROLL *scrollp = widget->scrollField;
|
||||
CDKENTRY *entry = widget->entryField;
|
||||
|
||||
if (!createList (widget, list, listSize))
|
||||
return;
|
||||
|
||||
/* Set the information in the scrolling list. */
|
||||
setCDKScroll (scrollp,
|
||||
(CDK_CSTRING2)widget->list,
|
||||
widget->listSize,
|
||||
NONUMBERS,
|
||||
scrollp->highlight,
|
||||
ObjOf (scrollp)->box);
|
||||
|
||||
/* Clean out the entry field. */
|
||||
setCDKAlphalistCurrentItem (widget, 0);
|
||||
cleanCDKEntry (entry);
|
||||
|
||||
/* Redraw the widget. */
|
||||
eraseCDKAlphalist (widget);
|
||||
drawCDKAlphalist (widget, ObjOf (widget)->box);
|
||||
}
|
||||
|
||||
/*
|
||||
* This returns the contents of the widget.
|
||||
*/
|
||||
char **getCDKAlphalistContents (CDKALPHALIST *widget, int *size)
|
||||
{
|
||||
(*size) = widget->listSize;
|
||||
return widget->list;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get/set the current position in the scroll-widget.
|
||||
*/
|
||||
int getCDKAlphalistCurrentItem (CDKALPHALIST *widget)
|
||||
{
|
||||
return getCDKScrollCurrent (widget->scrollField);
|
||||
}
|
||||
|
||||
void setCDKAlphalistCurrentItem (CDKALPHALIST *widget, int item)
|
||||
{
|
||||
if (widget->listSize != 0)
|
||||
{
|
||||
setCDKScrollCurrent (widget->scrollField, item);
|
||||
setCDKEntryValue (widget->entryField,
|
||||
widget->list[getCDKScrollCurrentItem (widget->scrollField)]);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This sets the filler character of the entry field of the alphalist.
|
||||
*/
|
||||
void setCDKAlphalistFillerChar (CDKALPHALIST *alphalist, chtype fillerCharacter)
|
||||
{
|
||||
CDKENTRY *entry = (CDKENTRY *)alphalist->entryField;
|
||||
|
||||
alphalist->fillerChar = fillerCharacter;
|
||||
|
||||
setCDKEntryFillerChar (entry, fillerCharacter);
|
||||
}
|
||||
chtype getCDKAlphalistFillerChar (CDKALPHALIST *alphalist)
|
||||
{
|
||||
return alphalist->fillerChar;
|
||||
}
|
||||
|
||||
/*
|
||||
* This sets the highlight bar attributes.
|
||||
*/
|
||||
void setCDKAlphalistHighlight (CDKALPHALIST *alphalist, chtype highlight)
|
||||
{
|
||||
alphalist->highlight = highlight;
|
||||
}
|
||||
chtype getCDKAlphalistHighlight (CDKALPHALIST *alphalist)
|
||||
{
|
||||
return alphalist->highlight;
|
||||
}
|
||||
|
||||
/*
|
||||
* This sets whether or not the widget will be drawn with a box.
|
||||
*/
|
||||
void setCDKAlphalistBox (CDKALPHALIST *alphalist, boolean Box)
|
||||
{
|
||||
ObjOf (alphalist)->box = Box;
|
||||
ObjOf (alphalist)->borderSize = Box ? 1 : 0;
|
||||
}
|
||||
|
||||
boolean getCDKAlphalistBox (CDKALPHALIST *alphalist)
|
||||
{
|
||||
return ObjOf (alphalist)->box;
|
||||
}
|
||||
|
||||
/*
|
||||
* These functions set the drawing characters of the widget.
|
||||
*/
|
||||
static void _setMyULchar (CDKOBJS *object, chtype character)
|
||||
{
|
||||
CDKALPHALIST *alphalist = (CDKALPHALIST *)object;
|
||||
|
||||
setCDKEntryULChar (alphalist->entryField, character);
|
||||
}
|
||||
static void _setMyURchar (CDKOBJS *object, chtype character)
|
||||
{
|
||||
CDKALPHALIST *alphalist = (CDKALPHALIST *)object;
|
||||
|
||||
setCDKEntryURChar (alphalist->entryField, character);
|
||||
}
|
||||
static void _setMyLLchar (CDKOBJS *object, chtype character)
|
||||
{
|
||||
CDKALPHALIST *alphalist = (CDKALPHALIST *)object;
|
||||
|
||||
setCDKScrollLLChar (alphalist->scrollField, character);
|
||||
}
|
||||
static void _setMyLRchar (CDKOBJS *object, chtype character)
|
||||
{
|
||||
CDKALPHALIST *alphalist = (CDKALPHALIST *)object;
|
||||
|
||||
setCDKScrollLRChar (alphalist->scrollField, character);
|
||||
}
|
||||
static void _setMyVTchar (CDKOBJS *object, chtype character)
|
||||
{
|
||||
CDKALPHALIST *alphalist = (CDKALPHALIST *)object;
|
||||
|
||||
setCDKEntryVerticalChar (alphalist->entryField, character);
|
||||
setCDKScrollVerticalChar (alphalist->scrollField, character);
|
||||
}
|
||||
static void _setMyHZchar (CDKOBJS *object, chtype character)
|
||||
{
|
||||
CDKALPHALIST *alphalist = (CDKALPHALIST *)object;
|
||||
|
||||
setCDKEntryHorizontalChar (alphalist->entryField, character);
|
||||
setCDKScrollHorizontalChar (alphalist->scrollField, character);
|
||||
}
|
||||
static void _setMyBXattr (CDKOBJS *object, chtype character)
|
||||
{
|
||||
CDKALPHALIST *alphalist = (CDKALPHALIST *)object;
|
||||
|
||||
setCDKEntryBoxAttribute (alphalist->entryField, character);
|
||||
setCDKScrollBoxAttribute (alphalist->scrollField, character);
|
||||
}
|
||||
|
||||
/*
|
||||
* This sets the background attribute of the widget.
|
||||
*/
|
||||
static void _setBKattrAlphalist (CDKOBJS *obj, chtype attrib)
|
||||
{
|
||||
CDKALPHALIST *alphalist = (CDKALPHALIST *)obj;
|
||||
|
||||
setCDKEntryBackgroundAttrib (alphalist->entryField, attrib);
|
||||
setCDKScrollBackgroundAttrib (alphalist->scrollField, attrib);
|
||||
}
|
||||
|
||||
static void destroyInfo (CDKALPHALIST *widget)
|
||||
{
|
||||
CDKfreeStrings (widget->list);
|
||||
widget->list = 0;
|
||||
|
||||
widget->listSize = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* This destroys the file selector.
|
||||
*/
|
||||
static void _destroyCDKAlphalist (CDKOBJS *object)
|
||||
{
|
||||
if (object != 0)
|
||||
{
|
||||
CDKALPHALIST *alphalist = (CDKALPHALIST *)object;
|
||||
|
||||
destroyInfo (alphalist);
|
||||
|
||||
/* Clean the key bindings. */
|
||||
cleanCDKObjectBindings (vALPHALIST, alphalist);
|
||||
|
||||
destroyCDKEntry (alphalist->entryField);
|
||||
destroyCDKScroll (alphalist->scrollField);
|
||||
|
||||
/* Free up the window pointers. */
|
||||
deleteCursesWindow (alphalist->shadowWin);
|
||||
deleteCursesWindow (alphalist->win);
|
||||
|
||||
/* Unregister the object. */
|
||||
unregisterCDKObject (vALPHALIST, alphalist);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This function sets the pre-process function.
|
||||
*/
|
||||
void setCDKAlphalistPreProcess (CDKALPHALIST *alphalist,
|
||||
PROCESSFN callback,
|
||||
void *data)
|
||||
{
|
||||
setCDKEntryPreProcess (alphalist->entryField, callback, data);
|
||||
}
|
||||
|
||||
/*
|
||||
* This function sets the post-process function.
|
||||
*/
|
||||
void setCDKAlphalistPostProcess (CDKALPHALIST *alphalist,
|
||||
PROCESSFN callback,
|
||||
void *data)
|
||||
{
|
||||
setCDKEntryPostProcess (alphalist->entryField, callback, data);
|
||||
}
|
||||
|
||||
/*
|
||||
* Start of callback functions.
|
||||
*/
|
||||
static int adjustAlphalistCB (EObjectType objectType GCC_UNUSED, void
|
||||
*object GCC_UNUSED,
|
||||
void *clientData,
|
||||
chtype key)
|
||||
{
|
||||
/* *INDENT-EQLS* */
|
||||
CDKALPHALIST *alphalist = (CDKALPHALIST *)clientData;
|
||||
CDKSCROLL *scrollp = alphalist->scrollField;
|
||||
CDKENTRY *entry = alphalist->entryField;
|
||||
|
||||
if (scrollp->listSize > 0)
|
||||
{
|
||||
char *current;
|
||||
|
||||
/* Adjust the scrolling list. */
|
||||
injectMyScroller (alphalist, key);
|
||||
|
||||
/* Set the value in the entry field. */
|
||||
current = chtype2Char (scrollp->item[scrollp->currentItem]);
|
||||
setCDKEntryValue (entry, current);
|
||||
drawCDKEntry (entry, ObjOf (entry)->box);
|
||||
freeChar (current);
|
||||
return (TRUE);
|
||||
}
|
||||
Beep ();
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
/*
|
||||
* This is the heart-beat of the widget.
|
||||
*/
|
||||
static int preProcessEntryField (EObjectType cdktype GCC_UNUSED, void
|
||||
*object GCC_UNUSED,
|
||||
void *clientData,
|
||||
chtype input)
|
||||
{
|
||||
/* *INDENT-EQLS* */
|
||||
CDKALPHALIST *alphalist = (CDKALPHALIST *)clientData;
|
||||
CDKSCROLL *scrollp = alphalist->scrollField;
|
||||
CDKENTRY *entry = alphalist->entryField;
|
||||
int infoLen = ((entry->info != 0)
|
||||
? (int)strlen (entry->info)
|
||||
: 0);
|
||||
int result = 1;
|
||||
bool empty = FALSE;
|
||||
|
||||
/* Make sure the entry field isn't empty. */
|
||||
if (entry->info == 0)
|
||||
{
|
||||
empty = TRUE;
|
||||
}
|
||||
else if (isCDKObjectBind (ObjTypeOf (alphalist), ObjOf (alphalist), input))
|
||||
{
|
||||
result = 1; /* don't try to use this key in editing */
|
||||
}
|
||||
else if ((isChar (input) &&
|
||||
(isalnum (CharOf (input)) ||
|
||||
ispunct (input))) ||
|
||||
input == KEY_BACKSPACE ||
|
||||
input == KEY_DC)
|
||||
{
|
||||
int Index, difference, absoluteDifference, x;
|
||||
int currPos = (entry->screenCol + entry->leftChar);
|
||||
char *pattern = (char *)malloc ((size_t) infoLen + 2);
|
||||
|
||||
if (pattern != 0)
|
||||
{
|
||||
strcpy (pattern, entry->info);
|
||||
|
||||
if (input == KEY_BACKSPACE || input == KEY_DC)
|
||||
{
|
||||
if (input == KEY_BACKSPACE)
|
||||
--currPos;
|
||||
if (currPos >= 0)
|
||||
strcpy (pattern + currPos, entry->info + currPos + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
pattern[currPos] = (char)input;
|
||||
strcpy (pattern + currPos + 1, entry->info + currPos);
|
||||
}
|
||||
}
|
||||
|
||||
if (pattern == 0)
|
||||
{
|
||||
Beep ();
|
||||
}
|
||||
else if (strlen (pattern) == 0)
|
||||
{
|
||||
empty = TRUE;
|
||||
}
|
||||
else if ((Index = searchList ((CDK_CSTRING2)alphalist->list,
|
||||
alphalist->listSize,
|
||||
pattern)) >= 0)
|
||||
{
|
||||
/* *INDENT-EQLS* */
|
||||
difference = Index - scrollp->currentItem;
|
||||
absoluteDifference = abs (difference);
|
||||
|
||||
/*
|
||||
* If the difference is less than zero, then move up.
|
||||
* Otherwise move down.
|
||||
*
|
||||
* If the difference is greater than 10 jump to the new
|
||||
* index position. Otherwise provide the nice scroll.
|
||||
*/
|
||||
if (absoluteDifference <= 10)
|
||||
{
|
||||
for (x = 0; x < absoluteDifference; x++)
|
||||
{
|
||||
injectMyScroller (alphalist,
|
||||
(chtype)((difference <= 0)
|
||||
? KEY_UP
|
||||
: KEY_DOWN));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
setCDKScrollPosition (scrollp, Index);
|
||||
}
|
||||
drawMyScroller (alphalist);
|
||||
}
|
||||
else
|
||||
{
|
||||
Beep ();
|
||||
result = 0;
|
||||
}
|
||||
|
||||
if (pattern != 0)
|
||||
free (pattern);
|
||||
}
|
||||
|
||||
if (empty)
|
||||
{
|
||||
setCDKScrollPosition (scrollp, 0);
|
||||
drawMyScroller (alphalist);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* This tries to complete the word in the entry field.
|
||||
*/
|
||||
static int completeWordCB (EObjectType objectType GCC_UNUSED, void *object GCC_UNUSED,
|
||||
void *clientData,
|
||||
chtype key GCC_UNUSED)
|
||||
{
|
||||
/* *INDENT-EQLS* */
|
||||
CDKALPHALIST *alphalist = (CDKALPHALIST *)clientData;
|
||||
CDKENTRY *entry = (CDKENTRY *)alphalist->entryField;
|
||||
CDKSCROLL *scrollp = 0;
|
||||
int wordLength = 0;
|
||||
int Index = 0;
|
||||
int ret = 0;
|
||||
char **altWords = 0;
|
||||
|
||||
if (entry->info == 0)
|
||||
{
|
||||
Beep ();
|
||||
return (TRUE);
|
||||
}
|
||||
wordLength = (int)strlen (entry->info);
|
||||
|
||||
/* If the word length is equal to zero, just leave. */
|
||||
if (wordLength == 0)
|
||||
{
|
||||
Beep ();
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
/* Look for a unique word match. */
|
||||
Index = searchList ((CDK_CSTRING2)alphalist->list, alphalist->listSize, entry->info);
|
||||
|
||||
/* If the index is less than zero, return we didn't find a match. */
|
||||
if (Index < 0)
|
||||
{
|
||||
Beep ();
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
/* Did we find the last word in the list? */
|
||||
if (Index == alphalist->listSize - 1)
|
||||
{
|
||||
setCDKEntryValue (entry, alphalist->list[Index]);
|
||||
drawCDKEntry (entry, ObjOf (entry)->box);
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
/* Ok, we found a match, is the next item similar? */
|
||||
ret = strncmp (alphalist->list[Index + 1], entry->info, (size_t) wordLength);
|
||||
if (ret == 0)
|
||||
{
|
||||
int currentIndex = Index;
|
||||
int altCount = 0;
|
||||
unsigned used = 0;
|
||||
int selected;
|
||||
int height;
|
||||
int match;
|
||||
int x;
|
||||
|
||||
/* Start looking for alternate words. */
|
||||
/* FIXME: bsearch would be more suitable */
|
||||
while ((currentIndex < alphalist->listSize)
|
||||
&& (strncmp (alphalist->list[currentIndex],
|
||||
entry->info,
|
||||
(size_t) wordLength) == 0))
|
||||
{
|
||||
used = CDKallocStrings (&altWords,
|
||||
alphalist->list[currentIndex++],
|
||||
(unsigned)altCount++,
|
||||
used);
|
||||
}
|
||||
|
||||
/* Determine the height of the scrolling list. */
|
||||
height = (altCount < 8 ? altCount + 3 : 11);
|
||||
|
||||
/* Create a scrolling list of close matches. */
|
||||
scrollp = newCDKScroll (entry->obj.screen,
|
||||
CENTER, CENTER, RIGHT, height, -30,
|
||||
"<C></B/5>Possible Matches.",
|
||||
(CDK_CSTRING2)altWords, altCount,
|
||||
NUMBERS, A_REVERSE, TRUE, FALSE);
|
||||
|
||||
/* Allow them to select a close match. */
|
||||
match = activateCDKScroll (scrollp, 0);
|
||||
selected = scrollp->currentItem;
|
||||
|
||||
/* Check how they exited the list. */
|
||||
if (scrollp->exitType == vESCAPE_HIT)
|
||||
{
|
||||
/* Destroy the scrolling list. */
|
||||
destroyCDKScroll (scrollp);
|
||||
|
||||
/* Clean up. */
|
||||
CDKfreeStrings (altWords);
|
||||
|
||||
/* Beep at the user. */
|
||||
Beep ();
|
||||
|
||||
/* Redraw the alphalist and return. */
|
||||
drawCDKAlphalist (alphalist, ObjOf (alphalist)->box);
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
/* Destroy the scrolling list. */
|
||||
destroyCDKScroll (scrollp);
|
||||
|
||||
/* Set the entry field to the selected value. */
|
||||
setCDKEntry (entry,
|
||||
altWords[match],
|
||||
entry->min,
|
||||
entry->max,
|
||||
ObjOf (entry)->box);
|
||||
|
||||
/* Move the highlight bar down to the selected value. */
|
||||
for (x = 0; x < selected; x++)
|
||||
{
|
||||
injectMyScroller (alphalist, KEY_DOWN);
|
||||
}
|
||||
|
||||
/* Clean up. */
|
||||
CDKfreeStrings (altWords);
|
||||
|
||||
/* Redraw the alphalist. */
|
||||
drawCDKAlphalist (alphalist, ObjOf (alphalist)->box);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Set the entry field with the found item. */
|
||||
setCDKEntry (entry,
|
||||
alphalist->list[Index],
|
||||
entry->min,
|
||||
entry->max,
|
||||
ObjOf (entry)->box);
|
||||
drawCDKEntry (entry, ObjOf (entry)->box);
|
||||
}
|
||||
return (TRUE);
|
||||
}
|
||||
|
||||
static int createList (CDKALPHALIST *alphalist, CDK_CSTRING *list, int listSize)
|
||||
{
|
||||
int status = 0;
|
||||
|
||||
if (listSize >= 0)
|
||||
{
|
||||
char **newlist = typeCallocN (char *, listSize + 1);
|
||||
|
||||
if (newlist != 0)
|
||||
{
|
||||
int x;
|
||||
|
||||
/*
|
||||
* We'll sort the list before we use it. It would have been better to
|
||||
* declare list[] const and only modify the copy, but there may be
|
||||
* clients that rely on the old behavior.
|
||||
*/
|
||||
sortList (list, listSize);
|
||||
|
||||
/* Copy in the new information. */
|
||||
status = 1;
|
||||
for (x = 0; x < listSize; x++)
|
||||
{
|
||||
if ((newlist[x] = copyChar (list[x])) == 0)
|
||||
{
|
||||
status = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (status)
|
||||
{
|
||||
destroyInfo (alphalist);
|
||||
alphalist->listSize = listSize;
|
||||
alphalist->list = newlist;
|
||||
}
|
||||
else
|
||||
{
|
||||
CDKfreeStrings (newlist);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
destroyInfo (alphalist);
|
||||
status = TRUE;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
static void _focusCDKAlphalist (CDKOBJS *object)
|
||||
{
|
||||
CDKALPHALIST *widget = (CDKALPHALIST *)object;
|
||||
|
||||
FocusObj (ObjOf (widget->entryField));
|
||||
}
|
||||
|
||||
static void _unfocusCDKAlphalist (CDKOBJS *object)
|
||||
{
|
||||
CDKALPHALIST *widget = (CDKALPHALIST *)object;
|
||||
|
||||
UnfocusObj (ObjOf (widget->entryField));
|
||||
}
|
||||
|
||||
dummyRefreshData (Alphalist)
|
||||
|
||||
dummySaveData (Alphalist)
|
|
@ -1,230 +0,0 @@
|
|||
#include <cdk_int.h>
|
||||
|
||||
/*
|
||||
* $Author: tom $
|
||||
* $Date: 2011/05/16 22:36:08 $
|
||||
* $Revision: 1.56 $
|
||||
*
|
||||
* Notes:
|
||||
*
|
||||
* The cdktype parameter passed to bindCDKObject, etc., is redundant since
|
||||
* the object parameter also has the same information. For compatibility
|
||||
* just use it for a sanity check.
|
||||
*/
|
||||
|
||||
#ifndef KEY_MAX
|
||||
#define KEY_MAX 512
|
||||
#endif
|
||||
|
||||
static CDKOBJS *bindableObject (EObjectType * cdktype, void *object)
|
||||
{
|
||||
CDKOBJS *obj = (CDKOBJS *)object;
|
||||
|
||||
if (obj != 0 && *cdktype == ObjTypeOf (obj))
|
||||
{
|
||||
if (*cdktype == vFSELECT)
|
||||
{
|
||||
*cdktype = vENTRY;
|
||||
object = ((CDKFSELECT *)object)->entryField;
|
||||
}
|
||||
else if (*cdktype == vALPHALIST)
|
||||
{
|
||||
*cdktype = vENTRY;
|
||||
object = ((CDKALPHALIST *)object)->entryField;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
object = 0;
|
||||
}
|
||||
return (CDKOBJS *)object;
|
||||
}
|
||||
|
||||
/*
|
||||
* This inserts a binding.
|
||||
*/
|
||||
void bindCDKObject (EObjectType cdktype,
|
||||
void *object,
|
||||
chtype key,
|
||||
BINDFN function,
|
||||
void *data)
|
||||
{
|
||||
CDKOBJS *obj = bindableObject (&cdktype, object);
|
||||
|
||||
if ((key < KEY_MAX) && obj != 0)
|
||||
{
|
||||
if (key != 0 && (unsigned)key >= obj->bindingCount)
|
||||
{
|
||||
unsigned next = (unsigned) (key + 1);
|
||||
|
||||
if (obj->bindingList != 0)
|
||||
obj->bindingList = typeReallocN (CDKBINDING, obj->bindingList, next);
|
||||
else
|
||||
obj->bindingList = typeMallocN (CDKBINDING, next);
|
||||
|
||||
memset (&(obj->bindingList[obj->bindingCount]), 0,
|
||||
(next - obj->bindingCount) * sizeof (CDKBINDING));
|
||||
obj->bindingCount = next;
|
||||
}
|
||||
|
||||
if (obj->bindingList != 0)
|
||||
{
|
||||
obj->bindingList[key].bindFunction = function;
|
||||
obj->bindingList[key].bindData = data;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This removes a binding on an object.
|
||||
*/
|
||||
void unbindCDKObject (EObjectType cdktype, void *object, chtype key)
|
||||
{
|
||||
CDKOBJS *obj = bindableObject (&cdktype, object);
|
||||
|
||||
if (obj != 0 && ((unsigned)key < obj->bindingCount))
|
||||
{
|
||||
obj->bindingList[key].bindFunction = 0;
|
||||
obj->bindingList[key].bindData = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This removes all the bindings for the given objects.
|
||||
*/
|
||||
void cleanCDKObjectBindings (EObjectType cdktype, void *object)
|
||||
{
|
||||
CDKOBJS *obj = bindableObject (&cdktype, object);
|
||||
|
||||
if (obj != 0 && obj->bindingList != 0)
|
||||
{
|
||||
unsigned x;
|
||||
|
||||
for (x = 0; x < obj->bindingCount; x++)
|
||||
{
|
||||
(obj)->bindingList[x].bindFunction = 0;
|
||||
(obj)->bindingList[x].bindData = 0;
|
||||
}
|
||||
freeAndNull ((obj)->bindingList);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This checks to see if the binding for the key exists:
|
||||
* If it does then it runs the command and returns its value, normally TRUE.
|
||||
* If it doesn't it returns a FALSE. This way we can 'overwrite' coded
|
||||
* bindings.
|
||||
*/
|
||||
int checkCDKObjectBind (EObjectType cdktype, void *object, chtype key)
|
||||
{
|
||||
CDKOBJS *obj = bindableObject (&cdktype, object);
|
||||
|
||||
if (obj != 0 && ((unsigned)key < obj->bindingCount))
|
||||
{
|
||||
if ((obj)->bindingList[key].bindFunction != 0)
|
||||
{
|
||||
BINDFN function = obj->bindingList[key].bindFunction;
|
||||
void *data = obj->bindingList[key].bindData;
|
||||
|
||||
return function (cdktype, object, data, key);
|
||||
}
|
||||
}
|
||||
return (FALSE);
|
||||
}
|
||||
|
||||
/*
|
||||
* This checks to see if the binding for the key exists.
|
||||
*/
|
||||
bool isCDKObjectBind (EObjectType cdktype, void *object, chtype key)
|
||||
{
|
||||
bool result = FALSE;
|
||||
CDKOBJS *obj = bindableObject (&cdktype, object);
|
||||
|
||||
if (obj != 0 && ((unsigned)key < obj->bindingCount))
|
||||
{
|
||||
if ((obj)->bindingList[key].bindFunction != 0)
|
||||
result = TRUE;
|
||||
}
|
||||
return (result);
|
||||
}
|
||||
|
||||
/*
|
||||
* This is a dummy function used to ensure that the constant for mapping has
|
||||
* a distinct address.
|
||||
*/
|
||||
int getcCDKBind (EObjectType cdktype GCC_UNUSED,
|
||||
void *object GCC_UNUSED,
|
||||
void *clientData GCC_UNUSED,
|
||||
chtype input GCC_UNUSED)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read from the input window, filtering keycodes as needed.
|
||||
*/
|
||||
int getcCDKObject (CDKOBJS *obj)
|
||||
{
|
||||
EObjectType cdktype = ObjTypeOf (obj);
|
||||
CDKOBJS *test = bindableObject (&cdktype, obj);
|
||||
int result = wgetch (InputWindowOf (obj));
|
||||
|
||||
if (result >= 0
|
||||
&& test != 0
|
||||
&& (unsigned)result < test->bindingCount
|
||||
&& test->bindingList[result].bindFunction == getcCDKBind)
|
||||
{
|
||||
result = (int)(long)test->bindingList[result].bindData;
|
||||
}
|
||||
else if (test == 0
|
||||
|| (unsigned)result >= test->bindingCount
|
||||
|| test->bindingList[result].bindFunction == 0)
|
||||
{
|
||||
switch (result)
|
||||
{
|
||||
case '\r':
|
||||
case '\n':
|
||||
result = KEY_ENTER;
|
||||
break;
|
||||
case '\t':
|
||||
result = KEY_TAB;
|
||||
break;
|
||||
case DELETE:
|
||||
result = KEY_DC;
|
||||
break;
|
||||
case '\b': /* same as CTRL('H'), for ASCII */
|
||||
result = KEY_BACKSPACE;
|
||||
break;
|
||||
case CDK_BEGOFLINE:
|
||||
result = KEY_HOME;
|
||||
break;
|
||||
case CDK_ENDOFLINE:
|
||||
result = KEY_END;
|
||||
break;
|
||||
case CDK_FORCHAR:
|
||||
result = KEY_RIGHT;
|
||||
break;
|
||||
case CDK_BACKCHAR:
|
||||
result = KEY_LEFT;
|
||||
break;
|
||||
case CDK_NEXT:
|
||||
result = KEY_TAB;
|
||||
break;
|
||||
case CDK_PREV:
|
||||
result = KEY_BTAB;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Use this function rather than getcCDKObject(), since we can extend it to
|
||||
* handle wide-characters.
|
||||
*/
|
||||
int getchCDKObject (CDKOBJS *obj, boolean *functionKey)
|
||||
{
|
||||
int key = getcCDKObject (obj);
|
||||
*functionKey = (key >= KEY_MIN && key <= KEY_MAX);
|
||||
return key;
|
||||
}
|
|
@ -1,572 +0,0 @@
|
|||
#include <cdk_int.h>
|
||||
#include "button.h"
|
||||
#include <limits.h>
|
||||
|
||||
/*
|
||||
* $Author: Aarian.P.Aleahmad $
|
||||
* $Date: 2016/01/31 20:32:25 $
|
||||
* $Revision: 1.38 $
|
||||
*/
|
||||
|
||||
DeclareCDKObjects (BUTTON, Button, setCdk, Int);
|
||||
|
||||
/*
|
||||
* This creates a button widget.
|
||||
*/
|
||||
CDKBUTTON *newCDKButton (CDKSCREEN *cdkscreen,
|
||||
int xplace,
|
||||
int yplace,
|
||||
const char *text,
|
||||
tButtonCallback callback,
|
||||
boolean Box,
|
||||
boolean shadow)
|
||||
{
|
||||
/* *INDENT-EQLS* */
|
||||
CDKBUTTON *button = 0;
|
||||
int parentWidth = getmaxx (cdkscreen->window);
|
||||
int parentHeight = getmaxy (cdkscreen->window);
|
||||
int boxWidth = 0;
|
||||
int boxHeight;
|
||||
int xpos = xplace;
|
||||
int ypos = yplace;
|
||||
|
||||
if ((button = newCDKObject (CDKBUTTON, &my_funcs)) == 0)
|
||||
return (0);
|
||||
|
||||
setCDKButtonBox (button, Box);
|
||||
boxHeight = 1 + 2 * BorderOf (button);
|
||||
|
||||
/* Translate the char * to a chtype. */
|
||||
button->info = char2Chtype (text, &button->infoLen, &button->infoPos);
|
||||
boxWidth = MAXIMUM (boxWidth, button->infoLen) + 2 * BorderOf (button);
|
||||
|
||||
/* Create the string alignments. */
|
||||
button->infoPos = justifyString (boxWidth - 2 * BorderOf (button),
|
||||
button->infoLen, button->infoPos);
|
||||
|
||||
/*
|
||||
* Make sure we didn't extend beyond the dimensions of the window.
|
||||
*/
|
||||
boxWidth = (boxWidth > parentWidth ? parentWidth : boxWidth);
|
||||
boxHeight = (boxHeight > parentHeight ? parentHeight : boxHeight);
|
||||
|
||||
/* Rejustify the x and y positions if we need to. */
|
||||
alignxy (cdkscreen->window, &xpos, &ypos, boxWidth, boxHeight);
|
||||
|
||||
/* *INDENT-EQLS* Create the button. */
|
||||
ScreenOf (button) = cdkscreen;
|
||||
ObjOf (button)->fn = &my_funcs;
|
||||
button->parent = cdkscreen->window;
|
||||
button->win = newwin (boxHeight, boxWidth, ypos, xpos);
|
||||
button->shadowWin = (WINDOW *)NULL;
|
||||
button->xpos = xpos;
|
||||
button->ypos = ypos;
|
||||
button->boxWidth = boxWidth;
|
||||
button->boxHeight = boxHeight;
|
||||
button->callback = callback;
|
||||
button->callbackData = NULL;
|
||||
ObjOf (button)->inputWindow = button->win;
|
||||
ObjOf (button)->acceptsFocus = TRUE;
|
||||
initExitType (button);
|
||||
button->shadow = shadow;
|
||||
button->highlight = A_REVERSE;
|
||||
|
||||
/* Is the window NULL? */
|
||||
if (button->win == (WINDOW *)NULL)
|
||||
{
|
||||
destroyCDKObject (button);
|
||||
return (0);
|
||||
}
|
||||
|
||||
keypad (button->win, TRUE);
|
||||
|
||||
/* If a shadow was requested, then create the shadow window. */
|
||||
if (shadow)
|
||||
button->shadowWin = newwin (boxHeight, boxWidth, ypos + 1, xpos + 1);
|
||||
|
||||
/* Register this baby. */
|
||||
registerCDKObject (cdkscreen, vBUTTON, button);
|
||||
|
||||
/* Return the button pointer. */
|
||||
return (button);
|
||||
}
|
||||
|
||||
/*
|
||||
* This was added for the builder.
|
||||
*/
|
||||
int activateCDKButton (CDKBUTTON *button, chtype *actions)
|
||||
{
|
||||
chtype input = 0;
|
||||
boolean functionKey;
|
||||
int ret;
|
||||
|
||||
drawCDKButton (button, ObjOf (button)->box);
|
||||
|
||||
if (actions == 0)
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
input = (chtype)getchCDKObject (ObjOf (button), &functionKey);
|
||||
|
||||
/* Inject the character into the widget. */
|
||||
ret = injectCDKButton (button, input);
|
||||
if (button->exitType != vEARLY_EXIT)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int length = chlen (actions);
|
||||
int x = 0;
|
||||
|
||||
/* Inject each character one at a time. */
|
||||
for (x = 0; x < length; x++)
|
||||
{
|
||||
ret = injectCDKButton (button, actions[x]);
|
||||
if (button->exitType != vEARLY_EXIT)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Set the exit type and exit. */
|
||||
setExitType (button, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* This sets multiple attributes of the widget.
|
||||
*/
|
||||
void setCDKButton (CDKBUTTON *button, const char *mesg, boolean Box)
|
||||
{
|
||||
setCDKButtonMessage (button, mesg);
|
||||
setCDKButtonBox (button, Box);
|
||||
}
|
||||
|
||||
/*
|
||||
* This sets the information within the button.
|
||||
*/
|
||||
void setCDKButtonMessage (CDKBUTTON *button, const char *info)
|
||||
{
|
||||
/* Clean out the old message. */
|
||||
freeChtype (button->info);
|
||||
button->infoPos = 0;
|
||||
button->infoLen = 0;
|
||||
|
||||
/* Copy in the new message. */
|
||||
|
||||
button->info = char2Chtype (info, &button->infoLen, &button->infoPos);
|
||||
button->infoPos = justifyString (button->boxWidth - 2 * BorderOf (button),
|
||||
button->infoLen, button->infoPos);
|
||||
|
||||
/* Redraw the button widget. */
|
||||
eraseCDKButton (button);
|
||||
drawCDKButton (button, ObjOf (button)->box);
|
||||
}
|
||||
|
||||
chtype *getCDKButtonMessage (CDKBUTTON *button)
|
||||
{
|
||||
return button->info;
|
||||
}
|
||||
|
||||
/*
|
||||
* This sets the box flag for the button widget.
|
||||
*/
|
||||
void setCDKButtonBox (CDKBUTTON *button, boolean Box)
|
||||
{
|
||||
ObjOf (button)->box = Box;
|
||||
ObjOf (button)->borderSize = Box ? 1 : 0;
|
||||
}
|
||||
|
||||
boolean getCDKButtonBox (CDKBUTTON *button)
|
||||
{
|
||||
return ObjOf (button)->box;
|
||||
}
|
||||
|
||||
/*
|
||||
* This sets the background attribute of the widget.
|
||||
*/
|
||||
static void _setBKattrButton (CDKOBJS *object, chtype attrib)
|
||||
{
|
||||
if (object != 0)
|
||||
{
|
||||
CDKBUTTON *widget = (CDKBUTTON *)object;
|
||||
|
||||
wbkgd (widget->win, attrib);
|
||||
}
|
||||
}
|
||||
|
||||
static void drawCDKButtonText (CDKBUTTON *button)
|
||||
{
|
||||
int boxWidth = button->boxWidth;
|
||||
int i;
|
||||
|
||||
/* Draw in the message. */
|
||||
|
||||
for (i = 0; i < boxWidth - 2 * BorderOf (button); i++)
|
||||
{
|
||||
chtype c;
|
||||
int pos = button->infoPos;
|
||||
int len = button->infoLen;
|
||||
|
||||
if (i >= pos && (i - pos) < len)
|
||||
c = button->info[i - pos];
|
||||
else
|
||||
c = ' ';
|
||||
|
||||
if (HasFocusObj (button))
|
||||
{
|
||||
c = button->highlight | CharOf (c);
|
||||
}
|
||||
|
||||
(void)mvwaddch (button->win, BorderOf (button), i + BorderOf (button), c);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This draws the button widget.
|
||||
*/
|
||||
static void _drawCDKButton (CDKOBJS *object, boolean Box GCC_UNUSED)
|
||||
{
|
||||
CDKBUTTON *button = (CDKBUTTON *)object;
|
||||
|
||||
/* Is there a shadow? */
|
||||
if (button->shadowWin != (WINDOW *)NULL)
|
||||
{
|
||||
drawShadow (button->shadowWin);
|
||||
}
|
||||
|
||||
/* Box the widget if asked. */
|
||||
if (ObjOf (button)->box)
|
||||
{
|
||||
drawObjBox (button->win, ObjOf (button));
|
||||
}
|
||||
drawCDKButtonText (button);
|
||||
wrefresh (button->win);
|
||||
}
|
||||
|
||||
/*
|
||||
* This erases the button widget.
|
||||
*/
|
||||
static void _eraseCDKButton (CDKOBJS *object)
|
||||
{
|
||||
if (validCDKObject (object))
|
||||
{
|
||||
CDKBUTTON *button = (CDKBUTTON *)object;
|
||||
|
||||
eraseCursesWindow (button->win);
|
||||
eraseCursesWindow (button->shadowWin);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This moves the button field to the given location.
|
||||
*/
|
||||
static void _moveCDKButton (CDKOBJS *object,
|
||||
int xplace,
|
||||
int yplace,
|
||||
boolean relative,
|
||||
boolean refresh_flag)
|
||||
{
|
||||
CDKBUTTON *button = (CDKBUTTON *)object;
|
||||
int currentX = getbegx (button->win);
|
||||
int currentY = getbegy (button->win);
|
||||
int xpos = xplace;
|
||||
int ypos = yplace;
|
||||
int xdiff = 0;
|
||||
int ydiff = 0;
|
||||
|
||||
/*
|
||||
* If this is a relative move, then we will adjust where we want
|
||||
* to move to.
|
||||
*/
|
||||
if (relative)
|
||||
{
|
||||
xpos = getbegx (button->win) + xplace;
|
||||
ypos = getbegy (button->win) + yplace;
|
||||
}
|
||||
|
||||
/* Adjust the window if we need to. */
|
||||
alignxy (WindowOf (button), &xpos, &ypos, button->boxWidth,
|
||||
button->boxHeight);
|
||||
|
||||
/* Get the difference. */
|
||||
xdiff = currentX - xpos;
|
||||
ydiff = currentY - ypos;
|
||||
|
||||
/* Move the window to the new location. */
|
||||
moveCursesWindow (button->win, -xdiff, -ydiff);
|
||||
moveCursesWindow (button->shadowWin, -xdiff, -ydiff);
|
||||
|
||||
/* Touch the windows so they 'move'. */
|
||||
refreshCDKWindow (WindowOf (button));
|
||||
|
||||
/* Redraw the window, if they asked for it. */
|
||||
if (refresh_flag)
|
||||
{
|
||||
drawCDKButton (button, ObjOf (button)->box);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This allows the user to use the cursor keys to adjust the
|
||||
* position of the widget.
|
||||
*/
|
||||
void positionCDKButton (CDKBUTTON *button)
|
||||
{
|
||||
/* Declare some variables. */
|
||||
int origX = getbegx (button->win);
|
||||
int origY = getbegy (button->win);
|
||||
chtype key = (chtype)0;
|
||||
boolean functionKey;
|
||||
|
||||
/* Let them move the widget around until they hit return. */
|
||||
while (key != KEY_ENTER)
|
||||
{
|
||||
key = (chtype)getchCDKObject (ObjOf (button), &functionKey);
|
||||
if (key == KEY_UP || key == '8')
|
||||
{
|
||||
if (getbegy (button->win) > 0)
|
||||
{
|
||||
moveCDKButton (button, 0, -1, TRUE, TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
Beep ();
|
||||
}
|
||||
}
|
||||
else if (key == KEY_DOWN || key == '2')
|
||||
{
|
||||
if (getbegy (button->win) + getmaxy (button->win) <
|
||||
getmaxy (WindowOf (button)) - 1)
|
||||
{
|
||||
moveCDKButton (button, 0, 1, TRUE, TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
Beep ();
|
||||
}
|
||||
}
|
||||
else if (key == KEY_LEFT || key == '4')
|
||||
{
|
||||
if (getbegx (button->win) > 0)
|
||||
{
|
||||
moveCDKButton (button, -1, 0, TRUE, TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
Beep ();
|
||||
}
|
||||
}
|
||||
else if (key == KEY_RIGHT || key == '6')
|
||||
{
|
||||
if (getbegx (button->win) + getmaxx (button->win) < getmaxx
|
||||
(WindowOf (button)) - 1)
|
||||
{
|
||||
moveCDKButton (button, 1, 0, TRUE, TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
Beep ();
|
||||
}
|
||||
}
|
||||
else if (key == '7')
|
||||
{
|
||||
if (getbegy (button->win) > 0 && getbegx (button->win) > 0)
|
||||
{
|
||||
moveCDKButton (button, -1, -1, TRUE, TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
Beep ();
|
||||
}
|
||||
}
|
||||
else if (key == '9')
|
||||
{
|
||||
if (getbegx (button->win) + getmaxx (button->win) < getmaxx
|
||||
(WindowOf (button)) - 1 &&
|
||||
getbegy (button->win) > 0)
|
||||
{
|
||||
moveCDKButton (button, 1, -1, TRUE, TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
Beep ();
|
||||
}
|
||||
}
|
||||
else if (key == '1')
|
||||
{
|
||||
if (getbegx (button->win) > 0 && getbegx (button->win) +
|
||||
getmaxx (button->win) < getmaxx (WindowOf (button)) - 1)
|
||||
{
|
||||
moveCDKButton (button, -1, 1, TRUE, TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
Beep ();
|
||||
}
|
||||
}
|
||||
else if (key == '3')
|
||||
{
|
||||
if (getbegx (button->win) + getmaxx (button->win) <
|
||||
getmaxx (WindowOf (button)) - 1
|
||||
&& getbegy (button->win) + getmaxy (button->win) <
|
||||
getmaxy (WindowOf (button)) - 1)
|
||||
{
|
||||
moveCDKButton (button, 1, 1, TRUE, TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
Beep ();
|
||||
}
|
||||
}
|
||||
else if (key == '5')
|
||||
{
|
||||
moveCDKButton (button, CENTER, CENTER, FALSE, TRUE);
|
||||
}
|
||||
else if (key == 't')
|
||||
{
|
||||
moveCDKButton (button, getbegx (button->win), TOP, FALSE, TRUE);
|
||||
}
|
||||
else if (key == 'b')
|
||||
{
|
||||
moveCDKButton (button, getbegx (button->win), BOTTOM, FALSE, TRUE);
|
||||
}
|
||||
else if (key == 'l')
|
||||
{
|
||||
moveCDKButton (button, LEFT, getbegy (button->win), FALSE, TRUE);
|
||||
}
|
||||
else if (key == 'r')
|
||||
{
|
||||
moveCDKButton (button, RIGHT, getbegy (button->win), FALSE, TRUE);
|
||||
}
|
||||
else if (key == 'c')
|
||||
{
|
||||
moveCDKButton (button, CENTER, getbegy (button->win), FALSE, TRUE);
|
||||
}
|
||||
else if (key == 'C')
|
||||
{
|
||||
moveCDKButton (button, getbegx (button->win), CENTER, FALSE, TRUE);
|
||||
}
|
||||
else if (key == CDK_REFRESH)
|
||||
{
|
||||
eraseCDKScreen (ScreenOf (button));
|
||||
refreshCDKScreen (ScreenOf (button));
|
||||
}
|
||||
else if (key == KEY_ESC)
|
||||
{
|
||||
moveCDKButton (button, origX, origY, FALSE, TRUE);
|
||||
}
|
||||
else if (key != KEY_ENTER)
|
||||
{
|
||||
Beep ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This destroys the button object pointer.
|
||||
*/
|
||||
static void _destroyCDKButton (CDKOBJS *object)
|
||||
{
|
||||
if (object != 0)
|
||||
{
|
||||
CDKBUTTON *button = (CDKBUTTON *)object;
|
||||
|
||||
/* Free up the character pointers. */
|
||||
freeChtype (button->info);
|
||||
|
||||
/* Free up the window pointers. */
|
||||
deleteCursesWindow (button->shadowWin);
|
||||
deleteCursesWindow (button->win);
|
||||
|
||||
/* Clean the key bindings. */
|
||||
cleanCDKObjectBindings (vBUTTON, button);
|
||||
|
||||
/* Unregister the object. */
|
||||
unregisterCDKObject (vBUTTON, button);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This injects a single character into the widget.
|
||||
*/
|
||||
static int _injectCDKButton (CDKOBJS *object, chtype input)
|
||||
{
|
||||
CDKBUTTON *widget = (CDKBUTTON *)object;
|
||||
int ret = unknownInt;
|
||||
bool complete = FALSE;
|
||||
|
||||
setExitType (widget, 0);
|
||||
|
||||
/* Check a predefined binding. */
|
||||
if (checkCDKObjectBind (vBUTTON, widget, input) != 0)
|
||||
{
|
||||
checkEarlyExit (widget);
|
||||
complete = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (input)
|
||||
{
|
||||
case KEY_ESC:
|
||||
setExitType (widget, input);
|
||||
complete = TRUE;
|
||||
break;
|
||||
|
||||
case KEY_ERROR:
|
||||
setExitType (widget, input);
|
||||
complete = TRUE;
|
||||
break;
|
||||
|
||||
case KEY_ENTER:
|
||||
case SPACE:
|
||||
if (widget->callback)
|
||||
widget->callback (widget);
|
||||
setExitType (widget, KEY_ENTER);
|
||||
ret = 0;
|
||||
complete = TRUE;
|
||||
break;
|
||||
|
||||
case CDK_REFRESH:
|
||||
eraseCDKScreen (ScreenOf (widget));
|
||||
refreshCDKScreen (ScreenOf (widget));
|
||||
break;
|
||||
|
||||
default:
|
||||
Beep ();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!complete)
|
||||
{
|
||||
setExitType (widget, 0);
|
||||
}
|
||||
|
||||
ResultOf (widget).valueInt = ret;
|
||||
return (ret != unknownInt);
|
||||
}
|
||||
|
||||
static void _focusCDKButton (CDKOBJS *object)
|
||||
{
|
||||
CDKBUTTON *button = (CDKBUTTON *)object;
|
||||
|
||||
drawCDKButtonText (button);
|
||||
wrefresh (button->win);
|
||||
}
|
||||
|
||||
static void _unfocusCDKButton (CDKOBJS *object)
|
||||
{
|
||||
CDKBUTTON *button = (CDKBUTTON *)object;
|
||||
|
||||
drawCDKButtonText (button);
|
||||
wrefresh (button->win);
|
||||
}
|
||||
|
||||
dummyRefreshData (Button)
|
||||
|
||||
dummySaveData (Button)
|
|
@ -1,590 +0,0 @@
|
|||
#include <cdk_int.h>
|
||||
|
||||
/*
|
||||
* $Author: tom $
|
||||
* $Date: 2016/11/20 18:41:25 $
|
||||
* $Revision: 1.68 $
|
||||
*/
|
||||
|
||||
DeclareCDKObjects (BUTTONBOX, Buttonbox, setCdk, Int);
|
||||
|
||||
/*
|
||||
* This returns a CDK buttonbox widget pointer.
|
||||
*/
|
||||
CDKBUTTONBOX *newCDKButtonbox (CDKSCREEN *cdkscreen,
|
||||
int xPos,
|
||||
int yPos,
|
||||
int height,
|
||||
int width,
|
||||
const char *title,
|
||||
int rows,
|
||||
int cols,
|
||||
CDK_CSTRING2 buttons,
|
||||
int buttonCount,
|
||||
chtype highlight,
|
||||
boolean Box,
|
||||
boolean shadow)
|
||||
{
|
||||
/* *INDENT-EQLS* */
|
||||
CDKBUTTONBOX *buttonbox = 0;
|
||||
int parentWidth = getmaxx (cdkscreen->window);
|
||||
int parentHeight = getmaxy (cdkscreen->window);
|
||||
int boxWidth = 0;
|
||||
int boxHeight = 0;
|
||||
int maxColWidth = INT_MIN;
|
||||
int colWidth = 0;
|
||||
int xpos = xPos;
|
||||
int ypos = yPos;
|
||||
int currentButton = 0;
|
||||
int x, y, junk;
|
||||
|
||||
if (buttonCount <= 0
|
||||
|| (buttonbox = newCDKObject (CDKBUTTONBOX, &my_funcs)) == 0
|
||||
|| (buttonbox->button = typeCallocN (chtype *, buttonCount + 1)) == 0
|
||||
|| (buttonbox->buttonLen = typeCallocN (int, buttonCount + 1)) == 0
|
||||
|| (buttonbox->buttonPos = typeCallocN (int, buttonCount + 1)) == 0
|
||||
|| (buttonbox->columnWidths = typeCallocN (int, buttonCount + 1)) == 0)
|
||||
{
|
||||
destroyCDKObject (buttonbox);
|
||||
return (0);
|
||||
}
|
||||
|
||||
setCDKButtonboxBox (buttonbox, Box);
|
||||
|
||||
/* Set some default values for the widget. */
|
||||
buttonbox->rowAdjust = 0;
|
||||
buttonbox->colAdjust = 0;
|
||||
|
||||
/*
|
||||
* If the height is a negative value, the height will
|
||||
* be ROWS-height, otherwise, the height will be the
|
||||
* given height.
|
||||
*/
|
||||
boxHeight = setWidgetDimension (parentHeight, height, rows + 1);
|
||||
|
||||
/*
|
||||
* If the width is a negative value, the width will
|
||||
* be COLS-width, otherwise, the width will be the
|
||||
* given width.
|
||||
*/
|
||||
boxWidth = setWidgetDimension (parentWidth, width, 0);
|
||||
|
||||
boxWidth = setCdkTitle (ObjOf (buttonbox), title, boxWidth);
|
||||
|
||||
/* Translate the buttons char * to a chtype * */
|
||||
for (x = 0; x < buttonCount; x++)
|
||||
{
|
||||
buttonbox->button[x] = char2Chtype (buttons[x],
|
||||
&buttonbox->buttonLen[x],
|
||||
&junk);
|
||||
}
|
||||
|
||||
/* Set the button positions. */
|
||||
for (x = 0; x < cols; x++)
|
||||
{
|
||||
maxColWidth = INT_MIN;
|
||||
|
||||
/* Look for the widest item in this column. */
|
||||
for (y = 0; y < rows; y++)
|
||||
{
|
||||
if (currentButton < buttonCount)
|
||||
{
|
||||
maxColWidth = MAXIMUM (buttonbox->buttonLen[currentButton], maxColWidth);
|
||||
currentButton++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Keep the maximum column width for this column. */
|
||||
buttonbox->columnWidths[x] = maxColWidth;
|
||||
colWidth += maxColWidth;
|
||||
}
|
||||
boxWidth++;
|
||||
|
||||
/*
|
||||
* Make sure we didn't extend beyond the dimensions of the window.
|
||||
*/
|
||||
boxWidth = (boxWidth > parentWidth ? parentWidth : boxWidth);
|
||||
boxHeight = (boxHeight > parentHeight ? parentHeight : boxHeight);
|
||||
|
||||
/* Now we have to readjust the x and y positions. */
|
||||
alignxy (cdkscreen->window, &xpos, &ypos, boxWidth, boxHeight);
|
||||
|
||||
/* *INDENT-EQLS* Set up the buttonbox box attributes. */
|
||||
ScreenOf (buttonbox) = cdkscreen;
|
||||
buttonbox->parent = cdkscreen->window;
|
||||
buttonbox->win = newwin (boxHeight, boxWidth, ypos, xpos);
|
||||
buttonbox->shadowWin = 0;
|
||||
buttonbox->buttonCount = buttonCount;
|
||||
buttonbox->currentButton = 0;
|
||||
buttonbox->rows = rows;
|
||||
buttonbox->cols = (buttonCount < cols ? buttonCount : cols);
|
||||
buttonbox->boxHeight = boxHeight;
|
||||
buttonbox->boxWidth = boxWidth;
|
||||
buttonbox->highlight = highlight;
|
||||
initExitType (buttonbox);
|
||||
ObjOf (buttonbox)->acceptsFocus = TRUE;
|
||||
ObjOf (buttonbox)->inputWindow = buttonbox->win;
|
||||
buttonbox->shadow = shadow;
|
||||
buttonbox->ButtonAttrib = A_NORMAL;
|
||||
|
||||
/* Set up the row adjustment. */
|
||||
if (boxHeight - rows - TitleLinesOf (buttonbox) > 0)
|
||||
{
|
||||
buttonbox->rowAdjust = (int)((boxHeight
|
||||
- rows
|
||||
- TitleLinesOf (buttonbox)) / buttonbox->rows);
|
||||
}
|
||||
|
||||
/* Set the col adjustment. */
|
||||
if (boxWidth - colWidth > 0)
|
||||
{
|
||||
buttonbox->colAdjust = (int)((boxWidth - colWidth)
|
||||
/ buttonbox->cols) - 1;
|
||||
}
|
||||
|
||||
/* If we couldn't create the window, we should return a null value. */
|
||||
if (buttonbox->win == 0)
|
||||
{
|
||||
destroyCDKObject (buttonbox);
|
||||
return (0);
|
||||
}
|
||||
keypad (buttonbox->win, TRUE);
|
||||
|
||||
/* Was there a shadow? */
|
||||
if (shadow)
|
||||
{
|
||||
buttonbox->shadowWin = newwin (boxHeight, boxWidth, ypos + 1, xpos + 1);
|
||||
}
|
||||
|
||||
/* Register this baby. */
|
||||
registerCDKObject (cdkscreen, vBUTTONBOX, buttonbox);
|
||||
|
||||
/* Return the buttonbox box pointer. */
|
||||
return (buttonbox);
|
||||
}
|
||||
|
||||
/*
|
||||
* This activates the widget.
|
||||
*/
|
||||
int activateCDKButtonbox (CDKBUTTONBOX *buttonbox, chtype *actions)
|
||||
{
|
||||
chtype input = 0;
|
||||
boolean functionKey;
|
||||
int ret;
|
||||
|
||||
/* Draw the buttonbox box. */
|
||||
drawCDKButtonbox (buttonbox, ObjOf (buttonbox)->box);
|
||||
|
||||
if (actions == 0)
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
input = (chtype)getchCDKObject (ObjOf (buttonbox), &functionKey);
|
||||
|
||||
/* Inject the character into the widget. */
|
||||
ret = injectCDKButtonbox (buttonbox, input);
|
||||
if (buttonbox->exitType != vEARLY_EXIT)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int length = chlen (actions);
|
||||
int x = 0;
|
||||
|
||||
/* Inject each character one at a time. */
|
||||
for (x = 0; x < length; x++)
|
||||
{
|
||||
ret = injectCDKButtonbox (buttonbox, actions[x]);
|
||||
if (buttonbox->exitType != vEARLY_EXIT)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Set the exit type and exit. */
|
||||
setExitType (buttonbox, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* This injects a single character into the widget.
|
||||
*/
|
||||
static int _injectCDKButtonbox (CDKOBJS *object, chtype input)
|
||||
{
|
||||
/* *INDENT-EQLS* */
|
||||
CDKBUTTONBOX *widget = (CDKBUTTONBOX *)object;
|
||||
int lastButton = widget->buttonCount - 1;
|
||||
int ppReturn = 1;
|
||||
int ret = unknownInt;
|
||||
bool complete = FALSE;
|
||||
|
||||
/* Set the exit type. */
|
||||
setExitType (widget, 0);
|
||||
|
||||
/* Check if there is a pre-process function to be called. */
|
||||
if (PreProcessFuncOf (widget) != 0)
|
||||
{
|
||||
ppReturn = PreProcessFuncOf (widget) (vBUTTONBOX,
|
||||
widget,
|
||||
PreProcessDataOf (widget),
|
||||
input);
|
||||
}
|
||||
|
||||
/* Should we continue? */
|
||||
if (ppReturn != 0)
|
||||
{
|
||||
/* Check for a key binding. */
|
||||
if (checkCDKObjectBind (vBUTTONBOX, widget, input) != 0)
|
||||
{
|
||||
checkEarlyExit (widget);
|
||||
complete = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
int firstButton = 0;
|
||||
|
||||
switch (input)
|
||||
{
|
||||
case KEY_LEFT:
|
||||
case KEY_BTAB:
|
||||
case KEY_BACKSPACE:
|
||||
if ((widget->currentButton - widget->rows) < firstButton)
|
||||
{
|
||||
widget->currentButton = lastButton;
|
||||
}
|
||||
else
|
||||
{
|
||||
widget->currentButton -= widget->rows;
|
||||
}
|
||||
break;
|
||||
|
||||
case KEY_RIGHT:
|
||||
case KEY_TAB:
|
||||
case SPACE:
|
||||
if ((widget->currentButton + widget->rows) > lastButton)
|
||||
{
|
||||
widget->currentButton = firstButton;
|
||||
}
|
||||
else
|
||||
{
|
||||
widget->currentButton += widget->rows;
|
||||
}
|
||||
break;
|
||||
|
||||
case KEY_UP:
|
||||
if ((widget->currentButton - 1) < firstButton)
|
||||
{
|
||||
widget->currentButton = lastButton;
|
||||
}
|
||||
else
|
||||
{
|
||||
widget->currentButton--;
|
||||
}
|
||||
break;
|
||||
|
||||
case KEY_DOWN:
|
||||
if ((widget->currentButton + 1) > lastButton)
|
||||
{
|
||||
widget->currentButton = firstButton;
|
||||
}
|
||||
else
|
||||
{
|
||||
widget->currentButton++;
|
||||
}
|
||||
break;
|
||||
|
||||
case CDK_REFRESH:
|
||||
eraseCDKScreen (ScreenOf (widget));
|
||||
refreshCDKScreen (ScreenOf (widget));
|
||||
break;
|
||||
|
||||
case KEY_ESC:
|
||||
setExitType (widget, input);
|
||||
complete = TRUE;
|
||||
break;
|
||||
|
||||
case KEY_ERROR:
|
||||
setExitType (widget, input);
|
||||
complete = TRUE;
|
||||
break;
|
||||
|
||||
case KEY_ENTER:
|
||||
setExitType (widget, input);
|
||||
ret = widget->currentButton;
|
||||
complete = TRUE;
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Should we call a post-process? */
|
||||
if (!complete && (PostProcessFuncOf (widget) != 0))
|
||||
{
|
||||
PostProcessFuncOf (widget) (vBUTTONBOX,
|
||||
widget,
|
||||
PostProcessDataOf (widget),
|
||||
input);
|
||||
}
|
||||
}
|
||||
|
||||
if (!complete)
|
||||
{
|
||||
drawCDKButtonboxButtons (widget);
|
||||
setExitType (widget, 0);
|
||||
}
|
||||
|
||||
ResultOf (widget).valueInt = ret;
|
||||
return (ret != unknownInt);
|
||||
}
|
||||
|
||||
/*
|
||||
* This sets multiple attributes of the widget.
|
||||
*/
|
||||
void setCDKButtonbox (CDKBUTTONBOX *buttonbox, chtype highlight, boolean Box)
|
||||
{
|
||||
setCDKButtonboxHighlight (buttonbox, highlight);
|
||||
setCDKButtonboxBox (buttonbox, Box);
|
||||
}
|
||||
|
||||
/*
|
||||
* This sets the highlight attribute for the buttonboxs.
|
||||
*/
|
||||
void setCDKButtonboxHighlight (CDKBUTTONBOX *buttonbox, chtype highlight)
|
||||
{
|
||||
buttonbox->highlight = highlight;
|
||||
}
|
||||
chtype getCDKButtonboxHighlight (CDKBUTTONBOX *buttonbox)
|
||||
{
|
||||
return (chtype)buttonbox->highlight;
|
||||
}
|
||||
|
||||
/*
|
||||
* This sets the box attribute of the widget.
|
||||
*/
|
||||
void setCDKButtonboxBox (CDKBUTTONBOX *buttonbox, boolean Box)
|
||||
{
|
||||
ObjOf (buttonbox)->box = Box;
|
||||
ObjOf (buttonbox)->borderSize = Box ? 1 : 0;
|
||||
}
|
||||
boolean getCDKButtonboxBox (CDKBUTTONBOX *buttonbox)
|
||||
{
|
||||
return ObjOf (buttonbox)->box;
|
||||
}
|
||||
|
||||
/*
|
||||
* This sets the background attribute of the widget.
|
||||
*/
|
||||
static void _setBKattrButtonbox (CDKOBJS *object, chtype attrib)
|
||||
{
|
||||
if (object != 0)
|
||||
{
|
||||
CDKBUTTONBOX *widget = (CDKBUTTONBOX *)object;
|
||||
|
||||
wbkgd (widget->win, attrib);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This draws the buttonbox box widget.
|
||||
*/
|
||||
static void _drawCDKButtonbox (CDKOBJS *object, boolean Box)
|
||||
{
|
||||
CDKBUTTONBOX *buttonbox = (CDKBUTTONBOX *)object;
|
||||
|
||||
/* Is there a shadow? */
|
||||
if (buttonbox->shadowWin != 0)
|
||||
{
|
||||
drawShadow (buttonbox->shadowWin);
|
||||
}
|
||||
|
||||
/* Box the widget if they asked. */
|
||||
if (Box)
|
||||
{
|
||||
drawObjBox (buttonbox->win, ObjOf (buttonbox));
|
||||
}
|
||||
|
||||
/* Draw in the title if there is one. */
|
||||
drawCdkTitle (buttonbox->win, object);
|
||||
|
||||
/* Draw in the buttons. */
|
||||
drawCDKButtonboxButtons (buttonbox);
|
||||
}
|
||||
|
||||
/*
|
||||
* This draws the buttons on the button box widget.
|
||||
*/
|
||||
void drawCDKButtonboxButtons (CDKBUTTONBOX *buttonbox)
|
||||
{
|
||||
/* *INDENT-EQLS* */
|
||||
int row;
|
||||
int col = (int)(buttonbox->colAdjust / 2);
|
||||
int currentButton = 0;
|
||||
int x, y;
|
||||
int cur_row = -1;
|
||||
int cur_col = -1;
|
||||
|
||||
/* Draw the buttons. */
|
||||
while (currentButton < buttonbox->buttonCount)
|
||||
{
|
||||
for (x = 0; x < buttonbox->cols; x++)
|
||||
{
|
||||
row = TitleLinesOf (buttonbox) + BorderOf (buttonbox);
|
||||
|
||||
for (y = 0; y < buttonbox->rows; y++)
|
||||
{
|
||||
chtype attr = buttonbox->ButtonAttrib;
|
||||
if (currentButton == buttonbox->currentButton)
|
||||
{
|
||||
attr = buttonbox->highlight,
|
||||
cur_row = row;
|
||||
cur_col = col;
|
||||
}
|
||||
writeChtypeAttrib (buttonbox->win,
|
||||
col, row,
|
||||
buttonbox->button[currentButton],
|
||||
attr,
|
||||
HORIZONTAL, 0,
|
||||
buttonbox->buttonLen[currentButton]);
|
||||
row += (1 + buttonbox->rowAdjust);
|
||||
currentButton++;
|
||||
}
|
||||
col += buttonbox->columnWidths[x] + buttonbox->colAdjust + BorderOf (buttonbox);
|
||||
}
|
||||
}
|
||||
if (cur_row >= 0 && cur_col >= 0)
|
||||
wmove (buttonbox->win, cur_row, cur_col);
|
||||
wrefresh (buttonbox->win);
|
||||
}
|
||||
|
||||
/*
|
||||
* This erases the buttonbox box from the screen.
|
||||
*/
|
||||
static void _eraseCDKButtonbox (CDKOBJS *object)
|
||||
{
|
||||
if (validCDKObject (object))
|
||||
{
|
||||
CDKBUTTONBOX *buttonbox = (CDKBUTTONBOX *)object;
|
||||
|
||||
eraseCursesWindow (buttonbox->win);
|
||||
eraseCursesWindow (buttonbox->shadowWin);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This moves the buttonbox box to a new screen location.
|
||||
*/
|
||||
static void _moveCDKButtonbox (CDKOBJS *object,
|
||||
int xplace,
|
||||
int yplace,
|
||||
boolean relative,
|
||||
boolean refresh_flag)
|
||||
{
|
||||
CDKBUTTONBOX *buttonbox = (CDKBUTTONBOX *)object;
|
||||
/* *INDENT-EQLS* */
|
||||
int currentX = getbegx (buttonbox->win);
|
||||
int currentY = getbegy (buttonbox->win);
|
||||
int xpos = xplace;
|
||||
int ypos = yplace;
|
||||
int xdiff = 0;
|
||||
int ydiff = 0;
|
||||
|
||||
/*
|
||||
* If this is a relative move, then we will adjust where we want
|
||||
* to move to.
|
||||
*/
|
||||
if (relative)
|
||||
{
|
||||
xpos = getbegx (buttonbox->win) + xplace;
|
||||
ypos = getbegy (buttonbox->win) + yplace;
|
||||
}
|
||||
|
||||
/* Adjust the window if we need to. */
|
||||
alignxy (WindowOf (buttonbox), &xpos, &ypos, buttonbox->boxWidth, buttonbox->boxHeight);
|
||||
|
||||
/* Get the difference. */
|
||||
xdiff = currentX - xpos;
|
||||
ydiff = currentY - ypos;
|
||||
|
||||
/* Move the window to the new location. */
|
||||
moveCursesWindow (buttonbox->win, -xdiff, -ydiff);
|
||||
moveCursesWindow (buttonbox->shadowWin, -xdiff, -ydiff);
|
||||
|
||||
/* Touch the windows so they 'move'. */
|
||||
refreshCDKWindow (WindowOf (buttonbox));
|
||||
|
||||
/* Redraw the window, if they asked for it. */
|
||||
if (refresh_flag)
|
||||
{
|
||||
drawCDKButtonbox (buttonbox, ObjOf (buttonbox)->box);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This destroys the widget and all the memory associated with it.
|
||||
*/
|
||||
static void _destroyCDKButtonbox (CDKOBJS *object)
|
||||
{
|
||||
if (object != 0)
|
||||
{
|
||||
CDKBUTTONBOX *buttonbox = (CDKBUTTONBOX *)object;
|
||||
|
||||
cleanCdkTitle (object);
|
||||
CDKfreeChtypes (buttonbox->button);
|
||||
freeChecked (buttonbox->buttonLen);
|
||||
freeChecked (buttonbox->buttonPos);
|
||||
freeChecked (buttonbox->columnWidths);
|
||||
|
||||
/* Delete the windows. */
|
||||
deleteCursesWindow (buttonbox->shadowWin);
|
||||
deleteCursesWindow (buttonbox->win);
|
||||
|
||||
/* Clean the key bindings. */
|
||||
cleanCDKObjectBindings (vBUTTONBOX, buttonbox);
|
||||
|
||||
/* Unregister this object. */
|
||||
unregisterCDKObject (vBUTTONBOX, buttonbox);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
void setCDKButtonboxCurrentButton (CDKBUTTONBOX *buttonbox, int button)
|
||||
{
|
||||
if ((button >= 0) && (button < buttonbox->buttonCount))
|
||||
{
|
||||
buttonbox->currentButton = button;
|
||||
}
|
||||
}
|
||||
int getCDKButtonboxCurrentButton (CDKBUTTONBOX *buttonbox)
|
||||
{
|
||||
return buttonbox->currentButton;
|
||||
}
|
||||
int getCDKButtonboxButtonCount (CDKBUTTONBOX *buttonbox)
|
||||
{
|
||||
return buttonbox->buttonCount;
|
||||
}
|
||||
|
||||
static void _focusCDKButtonbox (CDKOBJS *object)
|
||||
{
|
||||
CDKBUTTONBOX *widget = (CDKBUTTONBOX *)object;
|
||||
|
||||
drawCDKButtonbox (widget, ObjOf (widget)->box);
|
||||
}
|
||||
|
||||
static void _unfocusCDKButtonbox (CDKOBJS *object)
|
||||
{
|
||||
CDKBUTTONBOX *widget = (CDKBUTTONBOX *)object;
|
||||
|
||||
drawCDKButtonbox (widget, ObjOf (widget)->box);
|
||||
}
|
||||
|
||||
dummyRefreshData (Buttonbox)
|
||||
|
||||
dummySaveData (Buttonbox)
|
|
@ -1,30 +0,0 @@
|
|||
#include "cdkscreen.h"
|
||||
|
||||
CDKScreen::CDKScreen()
|
||||
{
|
||||
cdkscreen = initCDKScreen(NULL);
|
||||
// Now, set up color.
|
||||
initCDKColor();
|
||||
}
|
||||
|
||||
CDKScreen::~CDKScreen()
|
||||
{
|
||||
destroyCDKScreen(cdkscreen);
|
||||
endCDK();
|
||||
}
|
||||
|
||||
CDKSCREEN *CDKScreen::screen(void)
|
||||
{
|
||||
return cdkscreen;
|
||||
}
|
||||
|
||||
void CDKScreen::refreshscr(void)
|
||||
{
|
||||
refreshCDKScreen(cdkscreen);
|
||||
}
|
||||
|
||||
void CDKScreen::erasescr(void)
|
||||
{
|
||||
eraseCDKScreen(cdkscreen);
|
||||
}
|
||||
|
|
@ -1,30 +0,0 @@
|
|||
#ifndef CDKSCREEN_H
|
||||
#define CDK_SCREEN_H
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include <cdk.h>
|
||||
}
|
||||
|
||||
class CDKScreen
|
||||
{
|
||||
// The window which curses uses.
|
||||
WINDOW *cursesWin;
|
||||
// The CDKSCREEN struct assigned to this object.
|
||||
CDKSCREEN *cdkscreen;
|
||||
public:
|
||||
// Constructor.
|
||||
CDKScreen();
|
||||
// Deconstructor.
|
||||
~CDKScreen();
|
||||
// Return a pointer to the CDKScreen structure.
|
||||
CDKSCREEN *screen(void);
|
||||
// Refresh the screen.
|
||||
// Note, this function is renamed to avoid clashing with the refresh() macro.
|
||||
void refreshscr(void);
|
||||
// Erase, but don't destroy, all widgets.
|
||||
// Note, this function is renamed to avoid clashing with the erase() macro.
|
||||
void erasescr(void);
|
||||
};
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load Diff
|
@ -1,136 +0,0 @@
|
|||
#!@SHELL@
|
||||
# $Id: cdk-config.in,v 1.5 2015/01/04 01:45:59 tom Exp $
|
||||
##############################################################################
|
||||
# Copyright (c) 2007-2013,2015 Thomas E. Dickey #
|
||||
# #
|
||||
# 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, distribute #
|
||||
# with modifications, 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 ABOVE COPYRIGHT HOLDERS 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(s) of the above copyright #
|
||||
# holders shall not be used in advertising or otherwise to promote the sale, #
|
||||
# use or other dealings in this Software without prior written #
|
||||
# authorization. #
|
||||
##############################################################################
|
||||
|
||||
prefix="@prefix@"
|
||||
exec_prefix="@exec_prefix@"
|
||||
|
||||
bindir="@bindir@"
|
||||
libdir="@libdir@"
|
||||
datarootdir="@datarootdir@"
|
||||
datadir="@datadir@"
|
||||
mandir="@mandir@"
|
||||
includedir="@includedir@"
|
||||
|
||||
THIS="@CFG_ROOTNAME@"
|
||||
XHDR="@HDR_ROOTNAME@"
|
||||
XLIB="@LIB_ROOTNAME@"
|
||||
|
||||
test $# = 0 && exec @SHELL@ $0 --error
|
||||
|
||||
while test $# -gt 0; do
|
||||
case "$1" in
|
||||
-*=*)
|
||||
ARG=`echo "$1" | sed 's/[-_a-zA-Z0-9]*=//'`
|
||||
;;
|
||||
*)
|
||||
ARG=
|
||||
;;
|
||||
esac
|
||||
|
||||
case "$1" in
|
||||
# basic configuration
|
||||
--prefix=*)
|
||||
prefix="$ARG"
|
||||
test -z "$exec_prefix" && exec_prefix="$ARG"
|
||||
;;
|
||||
--prefix)
|
||||
echo "$prefix"
|
||||
;;
|
||||
--exec-prefix=*)
|
||||
exec_prefix="$ARG"
|
||||
;;
|
||||
--exec-prefix)
|
||||
echo "$exec_prefix"
|
||||
;;
|
||||
# compile/link
|
||||
--cflags)
|
||||
INCS="-I$includedir/$XHDR"
|
||||
sed -e 's,^[ ]*,,' -e 's, [ ]*, ,g' -e 's,[ ]*$,,' <<-ENDECHO
|
||||
$INCS
|
||||
ENDECHO
|
||||
;;
|
||||
--libs)
|
||||
sed -e 's,^[ ]*,,' -e 's, [ ]*, ,g' -e 's,[ ]*$,,' <<-ENDECHO
|
||||
-L${libdir} -l${XLIB} @LIBS@
|
||||
ENDECHO
|
||||
;;
|
||||
# identification
|
||||
--version)
|
||||
echo "@VERSION_MAJOR@.@VERSION_MINOR@.@VERSION_PATCH@"
|
||||
;;
|
||||
--abi-version)
|
||||
echo "@VERSION@" | sed -e 's/:/./g'
|
||||
;;
|
||||
# locations
|
||||
--bindir)
|
||||
echo "${bindir}"
|
||||
;;
|
||||
--datadir)
|
||||
echo "${datadir}"
|
||||
;;
|
||||
--libdir)
|
||||
echo "${libdir}"
|
||||
;;
|
||||
--mandir)
|
||||
echo "${mandir}"
|
||||
;;
|
||||
# general info
|
||||
--help)
|
||||
cat <<ENDHELP
|
||||
Usage: ${THIS}-config [options]
|
||||
|
||||
Options:
|
||||
--prefix echos the package-prefix of ${THIS}
|
||||
--prefix=ARG sets the package-prefix of ${THIS}
|
||||
--exec-prefix echos the executable-prefix of ${THIS}
|
||||
--exec-prefix=ARG sets the executable-prefix of ${THIS}
|
||||
|
||||
--cflags echos the C compiler flags needed to compile with ${THIS}
|
||||
--libs echos the libraries needed to link with ${THIS}
|
||||
|
||||
--version echos the release+patchdate version of ${THIS}
|
||||
--abi-version echos the ABI version of ${THIS}
|
||||
|
||||
--bindir echos the directory containing ${THIS} programs
|
||||
--datadir echos the directory containing ${THIS} data
|
||||
--libdir echos the directory containing ${THIS} libraries
|
||||
--mandir echos the directory containing ${THIS} manpages
|
||||
|
||||
--help prints this message
|
||||
ENDHELP
|
||||
;;
|
||||
--error|*)
|
||||
@SHELL@ $0 --help 1>&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
# vile:shmode
|
File diff suppressed because it is too large
Load Diff
|
@ -1,67 +0,0 @@
|
|||
/*
|
||||
* $Id: cdk_compat.c,v 1.5 2005/12/28 21:43:35 tom Exp $
|
||||
* These are functions that are obsolete, but provided as a porting aid.
|
||||
* The obsolete functions use fixed limits, and inconsistent data handling.
|
||||
*/
|
||||
#include "cdk_compat.h"
|
||||
|
||||
/*
|
||||
* This opens the current directory and reads the contents.
|
||||
*/
|
||||
int getDirectoryContents (char *directory, char **list, int maxListSize)
|
||||
{
|
||||
char **temp = 0;
|
||||
int counter = CDKgetDirectoryContents (directory, &temp);
|
||||
int n;
|
||||
|
||||
for (n = 0; n < counter && n < maxListSize; ++n)
|
||||
{
|
||||
list[n] = copyChar (temp[n]);
|
||||
}
|
||||
CDKfreeStrings (temp);
|
||||
|
||||
return counter;
|
||||
}
|
||||
|
||||
/*
|
||||
* This reads a file and sticks it into the char ** provided.
|
||||
*/
|
||||
int readFile (char *filename, char **array, int maxlines)
|
||||
{
|
||||
char **temp = 0;
|
||||
int lines = CDKreadFile (filename, &temp);
|
||||
int n;
|
||||
|
||||
for (n = 0; n < maxlines; ++n)
|
||||
{
|
||||
if (n < lines)
|
||||
{
|
||||
array[n] = copyChar (temp[n]);
|
||||
}
|
||||
else
|
||||
{
|
||||
array[n] = copyChar ("");
|
||||
break;
|
||||
}
|
||||
}
|
||||
CDKfreeStrings (temp);
|
||||
|
||||
return (lines);
|
||||
}
|
||||
|
||||
/*
|
||||
* This splits a string into X parts given the split character.
|
||||
*/
|
||||
int splitString (char *string, char **items, char splitChar)
|
||||
{
|
||||
char **temp = CDKsplitString (string, splitChar);
|
||||
int chunks = 0;
|
||||
|
||||
for (chunks = 0; chunks < MAX_LINES && temp[chunks] != 0; ++chunks)
|
||||
{
|
||||
items[chunks] = copyChar (temp[chunks]);
|
||||
}
|
||||
CDKfreeStrings (temp);
|
||||
|
||||
return chunks;
|
||||
}
|
|
@ -1,131 +0,0 @@
|
|||
#include <cdk_int.h>
|
||||
|
||||
/*
|
||||
* $Author: tom $
|
||||
* $Date: 2012/03/20 09:54:37 $
|
||||
* $Revision: 1.4 $
|
||||
*/
|
||||
|
||||
/*
|
||||
* Given a character pointer, returns the equivalent display type.
|
||||
*/
|
||||
EDisplayType char2DisplayType (const char *string)
|
||||
{
|
||||
/* *INDENT-OFF* */
|
||||
static const struct {
|
||||
const char *name;
|
||||
EDisplayType code;
|
||||
} table[] = {
|
||||
{ "CHAR", vCHAR },
|
||||
{ "HCHAR", vHCHAR },
|
||||
{ "INT", vINT },
|
||||
{ "HINT", vHINT },
|
||||
{ "UCHAR", vUCHAR },
|
||||
{ "LCHAR", vLCHAR },
|
||||
{ "UHCHAR", vUHCHAR },
|
||||
{ "LHCHAR", vLHCHAR },
|
||||
{ "MIXED", vMIXED },
|
||||
{ "HMIXED", vHMIXED },
|
||||
{ "UMIXED", vUMIXED },
|
||||
{ "LMIXED", vLMIXED },
|
||||
{ "UHMIXED", vUHMIXED },
|
||||
{ "LHMIXED", vLHMIXED },
|
||||
{ "VIEWONLY", vVIEWONLY },
|
||||
{ 0, vINVALID },
|
||||
};
|
||||
/* *INDENT-ON* */
|
||||
|
||||
if (string != 0)
|
||||
{
|
||||
int n;
|
||||
for (n = 0; table[n].name != 0; n++)
|
||||
{
|
||||
if (!strcmp (string, table[n].name))
|
||||
return table[n].code;
|
||||
}
|
||||
}
|
||||
return (EDisplayType) vINVALID;
|
||||
}
|
||||
|
||||
/*
|
||||
* Tell if a display type is "hidden"
|
||||
*/
|
||||
boolean isHiddenDisplayType (EDisplayType type)
|
||||
{
|
||||
boolean result = FALSE;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case vHCHAR:
|
||||
case vHINT:
|
||||
case vHMIXED:
|
||||
case vLHCHAR:
|
||||
case vLHMIXED:
|
||||
case vUHCHAR:
|
||||
case vUHMIXED:
|
||||
result = TRUE;
|
||||
break;
|
||||
case vCHAR:
|
||||
case vINT:
|
||||
case vINVALID:
|
||||
case vLCHAR:
|
||||
case vLMIXED:
|
||||
case vMIXED:
|
||||
case vUCHAR:
|
||||
case vUMIXED:
|
||||
case vVIEWONLY:
|
||||
result = FALSE;
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Given a character input, check if it is allowed by the display type,
|
||||
* and return the character to apply to the display, or ERR if not.
|
||||
*/
|
||||
int filterByDisplayType (EDisplayType type, chtype input)
|
||||
{
|
||||
int result = CharOf (input);
|
||||
|
||||
if (!isChar (input))
|
||||
{
|
||||
result = ERR;
|
||||
}
|
||||
else if ((type == vINT ||
|
||||
type == vHINT) &&
|
||||
!isdigit (CharOf (result)))
|
||||
{
|
||||
result = ERR;
|
||||
}
|
||||
else if ((type == vCHAR ||
|
||||
type == vUCHAR ||
|
||||
type == vLCHAR ||
|
||||
type == vUHCHAR ||
|
||||
type == vLHCHAR) &&
|
||||
isdigit (CharOf (result)))
|
||||
{
|
||||
result = ERR;
|
||||
}
|
||||
else if (type == vVIEWONLY)
|
||||
{
|
||||
result = ERR;
|
||||
}
|
||||
else if ((type == vUCHAR ||
|
||||
type == vUHCHAR ||
|
||||
type == vUMIXED ||
|
||||
type == vUHMIXED) &&
|
||||
isalpha (CharOf (result)))
|
||||
{
|
||||
result = toupper (result);
|
||||
}
|
||||
else if ((type == vLCHAR ||
|
||||
type == vLHCHAR ||
|
||||
type == vLMIXED ||
|
||||
type == vLHMIXED) &&
|
||||
isalpha (CharOf (result)))
|
||||
{
|
||||
result = tolower (result);
|
||||
}
|
||||
return result;
|
||||
}
|
|
@ -1,230 +0,0 @@
|
|||
#include <cdk_int.h>
|
||||
|
||||
/*
|
||||
* Default method-functions for CDK objects.
|
||||
*
|
||||
* $Author: tom $
|
||||
* $Date: 2016/11/20 20:07:11 $
|
||||
* $Revision: 1.17 $
|
||||
*/
|
||||
|
||||
/*
|
||||
* Set the object's upper-left-corner line-drawing character.
|
||||
*/
|
||||
void setCdkULchar (CDKOBJS *obj, chtype ch)
|
||||
{
|
||||
obj->ULChar = ch;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the object's upper-right-corner line-drawing character.
|
||||
*/
|
||||
void setCdkURchar (CDKOBJS *obj, chtype ch)
|
||||
{
|
||||
obj->URChar = ch;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the object's lower-left-corner line-drawing character.
|
||||
*/
|
||||
void setCdkLLchar (CDKOBJS *obj, chtype ch)
|
||||
{
|
||||
obj->LLChar = ch;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the object's upper-right-corner line-drawing character.
|
||||
*/
|
||||
void setCdkLRchar (CDKOBJS *obj, chtype ch)
|
||||
{
|
||||
obj->LRChar = ch;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the object's horizontal line-drawing character.
|
||||
*/
|
||||
void setCdkHZchar (CDKOBJS *obj, chtype ch)
|
||||
{
|
||||
obj->HZChar = ch;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the object's vertical line-drawing character.
|
||||
*/
|
||||
void setCdkVTchar (CDKOBJS *obj, chtype ch)
|
||||
{
|
||||
obj->VTChar = ch;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the object's box-attributes.
|
||||
*/
|
||||
void setCdkBXattr (CDKOBJS *obj, chtype ch)
|
||||
{
|
||||
obj->BXAttr = ch;
|
||||
}
|
||||
|
||||
/*
|
||||
* This sets the background color of the widget.
|
||||
*/
|
||||
void setCDKObjectBackgroundColor (CDKOBJS *obj, const char *color)
|
||||
{
|
||||
chtype *holder = 0;
|
||||
int junk1, junk2;
|
||||
|
||||
/* Make sure the color isn't null. */
|
||||
if (color == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/* Convert the value of the environment variable to a chtype. */
|
||||
holder = char2Chtype (color, &junk1, &junk2);
|
||||
|
||||
/* Set the widget's background color. */
|
||||
SetBackAttrObj (obj, holder[0]);
|
||||
|
||||
/* Clean up. */
|
||||
freeChtype (holder);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the widget's title.
|
||||
*/
|
||||
int setCdkTitle (CDKOBJS *obj, const char *title, int boxWidth)
|
||||
{
|
||||
if (obj != 0)
|
||||
{
|
||||
cleanCdkTitle (obj);
|
||||
|
||||
if (title != 0)
|
||||
{
|
||||
char **temp = 0;
|
||||
int titleWidth;
|
||||
int x;
|
||||
int len;
|
||||
int align;
|
||||
|
||||
/* We need to split the title on \n. */
|
||||
temp = CDKsplitString (title, '\n');
|
||||
obj->titleLines = (int)CDKcountStrings ((CDK_CSTRING2)temp);
|
||||
|
||||
obj->title = typeCallocN (chtype *, obj->titleLines + 1);
|
||||
obj->titlePos = typeCallocN (int, obj->titleLines + 1);
|
||||
obj->titleLen = typeCallocN (int, obj->titleLines + 1);
|
||||
|
||||
if (boxWidth >= 0)
|
||||
{
|
||||
int maxWidth = 0;
|
||||
|
||||
/* We need to determine the widest title line. */
|
||||
for (x = 0; x < obj->titleLines; x++)
|
||||
{
|
||||
chtype *holder = char2Chtype (temp[x], &len, &align);
|
||||
maxWidth = MAXIMUM (maxWidth, len);
|
||||
freeChtype (holder);
|
||||
}
|
||||
boxWidth = MAXIMUM (boxWidth, maxWidth + 2 * obj->borderSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
boxWidth = -(boxWidth - 1);
|
||||
}
|
||||
|
||||
/* For each line in the title, convert from char * to chtype * */
|
||||
titleWidth = boxWidth - (2 * obj->borderSize);
|
||||
for (x = 0; x < obj->titleLines; x++)
|
||||
{
|
||||
obj->title[x] = char2Chtype (temp[x], &obj->titleLen[x],
|
||||
&obj->titlePos[x]);
|
||||
obj->titlePos[x] = justifyString (titleWidth, obj->titleLen[x],
|
||||
obj->titlePos[x]);
|
||||
}
|
||||
CDKfreeStrings (temp);
|
||||
}
|
||||
}
|
||||
return boxWidth;
|
||||
}
|
||||
|
||||
/*
|
||||
* Draw the widget's title.
|
||||
*/
|
||||
void drawCdkTitle (WINDOW *win, CDKOBJS *obj)
|
||||
{
|
||||
if (obj != 0)
|
||||
{
|
||||
int x;
|
||||
|
||||
for (x = 0; x < obj->titleLines; x++)
|
||||
{
|
||||
writeChtype (win,
|
||||
obj->titlePos[x] + obj->borderSize,
|
||||
x + obj->borderSize,
|
||||
obj->title[x],
|
||||
HORIZONTAL, 0,
|
||||
obj->titleLen[x]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove storage for the widget's title.
|
||||
*/
|
||||
void cleanCdkTitle (CDKOBJS *obj)
|
||||
{
|
||||
if (obj != 0)
|
||||
{
|
||||
CDKfreeChtypes (obj->title);
|
||||
obj->title = 0;
|
||||
|
||||
freeAndNull (obj->titlePos);
|
||||
freeAndNull (obj->titleLen);
|
||||
|
||||
obj->titleLines = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Set data for preprocessing.
|
||||
*/
|
||||
void setCDKObjectPreProcess (CDKOBJS *obj, PROCESSFN fn, void *data)
|
||||
{
|
||||
obj->preProcessFunction = fn;
|
||||
obj->preProcessData = data;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set data for postprocessing.
|
||||
*/
|
||||
void setCDKObjectPostProcess (CDKOBJS *obj, PROCESSFN fn, void *data)
|
||||
{
|
||||
obj->postProcessFunction = fn;
|
||||
obj->postProcessData = data;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the object's exit-type based on the input.
|
||||
* The .exitType field should have been part of the CDKOBJS struct, but it
|
||||
* is used too pervasively in older applications to move (yet).
|
||||
*/
|
||||
void setCdkExitType (CDKOBJS *obj, EExitType *type, chtype ch)
|
||||
{
|
||||
switch (ch)
|
||||
{
|
||||
case KEY_ERROR:
|
||||
*type = vERROR;
|
||||
break;
|
||||
case KEY_ESC:
|
||||
*type = vESCAPE_HIT;
|
||||
break;
|
||||
case KEY_TAB:
|
||||
case KEY_ENTER:
|
||||
*type = vNORMAL;
|
||||
break;
|
||||
case 0:
|
||||
*type = vEARLY_EXIT;
|
||||
break;
|
||||
}
|
||||
/* make the result available via ExitTypeOf(obj) */
|
||||
obj->exitType = *type;
|
||||
}
|
|
@ -1,250 +0,0 @@
|
|||
#include <cdk_int.h>
|
||||
|
||||
/*
|
||||
* Useful functions for command-line parsing.
|
||||
*
|
||||
* $Author: tom $
|
||||
* $Date: 2016/11/20 18:32:53 $
|
||||
* $Revision: 1.12 $
|
||||
*/
|
||||
|
||||
#define OPTION_ON ((char *)1)
|
||||
#define OPTION_OFF ((char *)0)
|
||||
|
||||
static void usage (char **argv,
|
||||
CDK_PARAMS * params,
|
||||
const char *options)
|
||||
{
|
||||
int n;
|
||||
const char *str;
|
||||
char *base = baseName (argv[0]);
|
||||
|
||||
fprintf (stderr, "Usage: %s [options]\n\nOptions:\n", base);
|
||||
|
||||
for (n = 1; n < MAX_CDK_PARAMS; ++n)
|
||||
{
|
||||
if (n != ':'
|
||||
&& (str = (strchr) (options, n)) != 0)
|
||||
{
|
||||
int value = (str[1] == ':');
|
||||
fprintf (stderr, " -%c", n);
|
||||
if (value)
|
||||
{
|
||||
fprintf (stderr, " (%s)\n",
|
||||
(params->allParams[n]
|
||||
? params->allParams[n]
|
||||
: "not set"));
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf (stderr, " (%s)\n",
|
||||
(params->allParams[n]
|
||||
? "set"
|
||||
: "not set"));
|
||||
}
|
||||
}
|
||||
}
|
||||
free (base);
|
||||
exit (EXIT_FAILURE);
|
||||
}
|
||||
|
||||
static int CDKparseSize (char *string, int fullSize)
|
||||
{
|
||||
int result;
|
||||
if (strcmp (string, "FULL") == 0)
|
||||
{
|
||||
result = fullSize;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = (int)strtol (string, (char **)0, 0);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse the string as one of CDK's positioning keywords, or an actual
|
||||
* position.
|
||||
*/
|
||||
int CDKparsePosition (const char *string)
|
||||
{
|
||||
int result;
|
||||
|
||||
if (string == 0)
|
||||
{
|
||||
result = NONE;
|
||||
}
|
||||
else if (strcmp (string, "TOP") == 0)
|
||||
{
|
||||
result = TOP;
|
||||
}
|
||||
else if (strcmp (string, "BOTTOM") == 0)
|
||||
{
|
||||
result = BOTTOM;
|
||||
}
|
||||
else if (strcmp (string, "LEFT") == 0)
|
||||
{
|
||||
result = LEFT;
|
||||
}
|
||||
else if (strcmp (string, "RIGHT") == 0)
|
||||
{
|
||||
result = RIGHT;
|
||||
}
|
||||
else if (strcmp (string, "CENTER") == 0)
|
||||
{
|
||||
result = CENTER;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = (int)strtol (string, (char **)0, 0);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Parse the given argc/argv command-line, with the options passed to
|
||||
* getopt()'s 3rd parameter.
|
||||
*/
|
||||
void CDKparseParams (int argc,
|
||||
char **argv,
|
||||
CDK_PARAMS * params,
|
||||
const char *options)
|
||||
{
|
||||
int code;
|
||||
|
||||
memset (params, 0, sizeof (*params));
|
||||
params->Box = TRUE;
|
||||
|
||||
while ((code = getopt (argc, argv, options)) != EOF)
|
||||
{
|
||||
const char *str;
|
||||
|
||||
if (code == '?' || (str = (strchr) (options, code)) == 0)
|
||||
{
|
||||
usage (argv, params, options);
|
||||
}
|
||||
else
|
||||
{
|
||||
params->allParams[code] = OPTION_ON;
|
||||
if (str[1] == ':')
|
||||
{
|
||||
params->allParams[code] = optarg;
|
||||
}
|
||||
switch (code)
|
||||
{
|
||||
case 'W':
|
||||
params->wValue = CDKparseSize (optarg, FULL);
|
||||
break;
|
||||
|
||||
case 'H':
|
||||
params->hValue = CDKparseSize (optarg, FULL);
|
||||
break;
|
||||
|
||||
case 'X':
|
||||
params->xValue = CDKparsePosition (optarg);
|
||||
break;
|
||||
|
||||
case 'Y':
|
||||
params->yValue = CDKparsePosition (optarg);
|
||||
break;
|
||||
|
||||
case 'N':
|
||||
params->Box = FALSE;
|
||||
break;
|
||||
|
||||
case 'S':
|
||||
params->Shadow = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Retrieve a numeric option-value, default=0.
|
||||
*/
|
||||
int CDKparamNumber (CDK_PARAMS * params, int option)
|
||||
{
|
||||
return CDKparamNumber2 (params, option, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Retrieve a numeric option-value, given default.
|
||||
*/
|
||||
int CDKparamNumber2 (CDK_PARAMS * params, int option, int missing)
|
||||
{
|
||||
return CDKparamValue (params, option, missing);
|
||||
}
|
||||
|
||||
/*
|
||||
* Retrieve the string value of an option, default=0.
|
||||
*/
|
||||
char *CDKparamString (CDK_PARAMS * params, int option)
|
||||
{
|
||||
return CDKparamString2 (params, option, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Retrieve the string value of an option, with default for missing value.
|
||||
*/
|
||||
char *CDKparamString2 (CDK_PARAMS * params, int option, const char *missing)
|
||||
{
|
||||
char *value = ((option > 0 && option < MAX_CDK_PARAMS)
|
||||
? params->allParams[option]
|
||||
: 0);
|
||||
if (value == 0)
|
||||
value = copyChar (missing);
|
||||
return value;
|
||||
}
|
||||
|
||||
/*
|
||||
* Retrieve an integer (or boolean) option value from the parsed command-line.
|
||||
* (prefer: CDKparamNumber).
|
||||
*/
|
||||
int CDKparamValue (CDK_PARAMS * params, int option, int missing)
|
||||
{
|
||||
int result;
|
||||
char *value = CDKparamString (params, option);
|
||||
|
||||
if (value == 0)
|
||||
{
|
||||
result = missing;
|
||||
}
|
||||
else if (strchr (CDK_CLI_PARAMS, option) != 0)
|
||||
{
|
||||
switch (option)
|
||||
{
|
||||
case 'H':
|
||||
result = params->hValue;
|
||||
break;
|
||||
case 'W':
|
||||
result = params->wValue;
|
||||
break;
|
||||
case 'X':
|
||||
result = params->xValue;
|
||||
break;
|
||||
case 'Y':
|
||||
result = params->yValue;
|
||||
break;
|
||||
case 'N':
|
||||
result = params->Box;
|
||||
break;
|
||||
case 'S':
|
||||
result = params->Shadow;
|
||||
break;
|
||||
default:
|
||||
result = missing;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (value == OPTION_ON)
|
||||
{
|
||||
result = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = (int)strtol (value, (char **)0, 0);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
|
@ -1,509 +0,0 @@
|
|||
#include <cdk_int.h>
|
||||
|
||||
#ifdef HAVE_SETLOCALE
|
||||
#include <locale.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* $Author: tom $
|
||||
* $Date: 2016/12/04 15:41:50 $
|
||||
* $Revision: 1.91 $
|
||||
*/
|
||||
|
||||
typedef struct _all_screens
|
||||
{
|
||||
struct _all_screens *link;
|
||||
CDKSCREEN *screen;
|
||||
}
|
||||
ALL_SCREENS;
|
||||
|
||||
static ALL_SCREENS *all_screens;
|
||||
|
||||
typedef struct _all_objects
|
||||
{
|
||||
struct _all_objects *link;
|
||||
CDKOBJS *object;
|
||||
}
|
||||
ALL_OBJECTS;
|
||||
|
||||
static ALL_OBJECTS *all_objects;
|
||||
|
||||
static boolean validObjType (CDKOBJS *obj, EObjectType type)
|
||||
{
|
||||
bool valid = FALSE;
|
||||
|
||||
if (obj != 0 && ObjTypeOf (obj) == type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case vALPHALIST:
|
||||
case vBUTTON:
|
||||
case vBUTTONBOX:
|
||||
case vCALENDAR:
|
||||
case vDIALOG:
|
||||
case vDSCALE:
|
||||
case vENTRY:
|
||||
case vFSCALE:
|
||||
case vFSELECT:
|
||||
case vFSLIDER:
|
||||
case vGRAPH:
|
||||
case vHISTOGRAM:
|
||||
case vITEMLIST:
|
||||
case vLABEL:
|
||||
case vMARQUEE:
|
||||
case vMATRIX:
|
||||
case vMENTRY:
|
||||
case vMENU:
|
||||
case vRADIO:
|
||||
case vSCALE:
|
||||
case vSCROLL:
|
||||
case vSELECTION:
|
||||
case vSLIDER:
|
||||
case vSWINDOW:
|
||||
case vTEMPLATE:
|
||||
case vUSCALE:
|
||||
case vUSLIDER:
|
||||
case vVIEWER:
|
||||
valid = TRUE;
|
||||
break;
|
||||
case vTRAVERSE: /* not really an object */
|
||||
case vNULL:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return valid;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set indices so the screen and object point to each other.
|
||||
*/
|
||||
static void setScreenIndex (CDKSCREEN *screen, int number, CDKOBJS *obj)
|
||||
{
|
||||
(obj)->screenIndex = number;
|
||||
(obj)->screen = screen;
|
||||
screen->object[number] = obj;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns true if we have done a "new" on this object but no "destroy"
|
||||
*/
|
||||
bool validCDKObject (CDKOBJS *obj)
|
||||
{
|
||||
bool result = FALSE;
|
||||
if (obj != 0)
|
||||
{
|
||||
ALL_OBJECTS *ptr;
|
||||
|
||||
for (ptr = all_objects; ptr != 0; ptr = ptr->link)
|
||||
{
|
||||
if (ptr->object == obj)
|
||||
{
|
||||
result = validObjType (obj, ObjTypeOf (obj));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Create a new object beginning with a CDKOBJS struct. The whole object is
|
||||
* initialized to zeroes except for special cases which have known values.
|
||||
*/
|
||||
void *_newCDKObject (unsigned size, const CDKFUNCS * funcs)
|
||||
{
|
||||
ALL_OBJECTS *item;
|
||||
CDKOBJS *result = 0;
|
||||
if ((item = typeCalloc (ALL_OBJECTS)) != 0)
|
||||
{
|
||||
if ((result = (CDKOBJS *)calloc (1, size)) != 0)
|
||||
{
|
||||
result->fn = funcs;
|
||||
result->hasFocus = TRUE;
|
||||
result->isVisible = TRUE;
|
||||
|
||||
item->link = all_objects;
|
||||
item->object = result;
|
||||
all_objects = item;
|
||||
|
||||
/* set default line-drawing characters */
|
||||
result->ULChar = ACS_ULCORNER;
|
||||
result->URChar = ACS_URCORNER;
|
||||
result->LLChar = ACS_LLCORNER;
|
||||
result->LRChar = ACS_LRCORNER;
|
||||
result->HZChar = ACS_HLINE;
|
||||
result->VTChar = ACS_VLINE;
|
||||
result->BXAttr = A_NORMAL;
|
||||
|
||||
/* set default exit-types */
|
||||
result->exitType = vNEVER_ACTIVATED;
|
||||
result->earlyExit = vNEVER_ACTIVATED;
|
||||
}
|
||||
else
|
||||
{
|
||||
free (item);
|
||||
}
|
||||
}
|
||||
return (void *)result;
|
||||
}
|
||||
|
||||
void _destroyCDKObject (CDKOBJS *obj)
|
||||
{
|
||||
if (validCDKObject (obj))
|
||||
{
|
||||
ALL_OBJECTS *p, *q;
|
||||
|
||||
for (p = all_objects, q = 0; p != 0; q = p, p = p->link)
|
||||
{
|
||||
if (p->object == obj)
|
||||
{
|
||||
/* delink it first, to avoid problems with recursion */
|
||||
if (q != 0)
|
||||
q->link = p->link;
|
||||
else
|
||||
all_objects = p->link;
|
||||
|
||||
MethodPtr (obj, destroyObj) (obj);
|
||||
free (obj);
|
||||
free (p);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This creates a new CDK screen.
|
||||
*/
|
||||
CDKSCREEN *initCDKScreen (WINDOW *window)
|
||||
{
|
||||
ALL_SCREENS *item;
|
||||
CDKSCREEN *screen = 0;
|
||||
|
||||
/* initialization, for the first time */
|
||||
if (all_screens == 0 || stdscr == 0 || window == 0)
|
||||
{
|
||||
/* Set up basic curses settings. */
|
||||
#ifdef HAVE_SETLOCALE
|
||||
setlocale (LC_ALL, "");
|
||||
#endif
|
||||
/* Initialize curses after setting the locale, since curses depends
|
||||
* on having a correct locale to reflect the terminal's encoding.
|
||||
*/
|
||||
if (stdscr == 0 || window == 0)
|
||||
{
|
||||
window = initscr ();
|
||||
}
|
||||
noecho ();
|
||||
cbreak ();
|
||||
}
|
||||
|
||||
if ((item = typeMalloc (ALL_SCREENS)) != 0)
|
||||
{
|
||||
if ((screen = typeCalloc (CDKSCREEN)) != 0)
|
||||
{
|
||||
item->link = all_screens;
|
||||
item->screen = screen;
|
||||
all_screens = item;
|
||||
|
||||
/* Initialize the CDKSCREEN pointer. */
|
||||
screen->objectCount = 0;
|
||||
screen->objectLimit = 2;
|
||||
screen->object = typeMallocN (CDKOBJS *, screen->objectLimit);
|
||||
screen->window = window;
|
||||
|
||||
/* OK, we are done. */
|
||||
}
|
||||
else
|
||||
{
|
||||
free (item);
|
||||
}
|
||||
}
|
||||
return (screen);
|
||||
}
|
||||
|
||||
/*
|
||||
* This registers a CDK object with a screen.
|
||||
*/
|
||||
void registerCDKObject (CDKSCREEN *screen, EObjectType cdktype, void *object)
|
||||
{
|
||||
CDKOBJS *obj = (CDKOBJS *)object;
|
||||
|
||||
if (screen->objectCount + 1 >= screen->objectLimit)
|
||||
{
|
||||
screen->objectLimit += 2;
|
||||
screen->objectLimit *= 2;
|
||||
screen->object = typeReallocN (CDKOBJS *, screen->object, screen->objectLimit);
|
||||
}
|
||||
if (validObjType (obj, cdktype))
|
||||
{
|
||||
setScreenIndex (screen, screen->objectCount++, obj);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This registers a CDK object with a screen.
|
||||
*/
|
||||
void reRegisterCDKObject (EObjectType cdktype, void *object)
|
||||
{
|
||||
CDKOBJS *obj = (CDKOBJS *)object;
|
||||
|
||||
registerCDKObject (obj->screen, cdktype, object);
|
||||
}
|
||||
|
||||
/*
|
||||
* This removes an object from the CDK screen.
|
||||
*/
|
||||
void unregisterCDKObject (EObjectType cdktype, void *object)
|
||||
{
|
||||
CDKOBJS *obj = (CDKOBJS *)object;
|
||||
|
||||
if (validObjType (obj, cdktype) && obj->screenIndex >= 0)
|
||||
{
|
||||
CDKSCREEN *screen = (obj)->screen;
|
||||
|
||||
if (screen != 0)
|
||||
{
|
||||
int Index = (obj)->screenIndex;
|
||||
int x;
|
||||
|
||||
obj->screenIndex = -1;
|
||||
|
||||
/*
|
||||
* Resequence the objects.
|
||||
*/
|
||||
for (x = Index; x < screen->objectCount - 1; x++)
|
||||
{
|
||||
setScreenIndex (screen, x, screen->object[x + 1]);
|
||||
}
|
||||
|
||||
if (screen->objectCount <= 1)
|
||||
{
|
||||
/* if no more objects, remove the array */
|
||||
freeAndNull (screen->object);
|
||||
screen->objectCount = 0;
|
||||
screen->objectLimit = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Reduce the list by one object. */
|
||||
screen->object[screen->objectCount--] = 0;
|
||||
|
||||
/*
|
||||
* Update the object-focus
|
||||
*/
|
||||
if (screen->objectFocus == Index)
|
||||
{
|
||||
screen->objectFocus--;
|
||||
(void)setCDKFocusNext (screen);
|
||||
}
|
||||
else if (screen->objectFocus > Index)
|
||||
{
|
||||
screen->objectFocus--;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#define validIndex(screen, n) ((n) >= 0 && (n) < (screen)->objectCount)
|
||||
|
||||
static void swapCDKIndices (CDKSCREEN *screen, int n1, int n2)
|
||||
{
|
||||
if (n1 != n2 && validIndex (screen, n1) && validIndex (screen, n2))
|
||||
{
|
||||
CDKOBJS *o1 = screen->object[n1];
|
||||
CDKOBJS *o2 = screen->object[n2];
|
||||
setScreenIndex (screen, n1, o2);
|
||||
setScreenIndex (screen, n2, o1);
|
||||
|
||||
if (screen->objectFocus == n1)
|
||||
screen->objectFocus = n2;
|
||||
else if (screen->objectFocus == n2)
|
||||
screen->objectFocus = n1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This 'brings' a CDK object to the top of the stack.
|
||||
*/
|
||||
void raiseCDKObject (EObjectType cdktype, void *object)
|
||||
{
|
||||
CDKOBJS *obj = (CDKOBJS *)object;
|
||||
|
||||
if (validObjType (obj, cdktype))
|
||||
{
|
||||
CDKSCREEN *screen = obj->screen;
|
||||
swapCDKIndices (screen, obj->screenIndex, screen->objectCount - 1);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This 'lowers' an object.
|
||||
*/
|
||||
void lowerCDKObject (EObjectType cdktype, void *object)
|
||||
{
|
||||
CDKOBJS *obj = (CDKOBJS *)object;
|
||||
|
||||
if (validObjType (obj, cdktype))
|
||||
{
|
||||
CDKSCREEN *screen = obj->screen;
|
||||
swapCDKIndices (screen, obj->screenIndex, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This calls refreshCDKScreen. (made consistent with widgets)
|
||||
*/
|
||||
void drawCDKScreen (CDKSCREEN *cdkscreen)
|
||||
{
|
||||
refreshCDKScreen (cdkscreen);
|
||||
}
|
||||
|
||||
/*
|
||||
* Refresh one CDK window.
|
||||
* FIXME: this should be rewritten to use the panel library, so it would not
|
||||
* be necessary to touch the window to ensure that it covers other windows.
|
||||
*/
|
||||
void refreshCDKWindow (WINDOW *win)
|
||||
{
|
||||
touchwin (win);
|
||||
wrefresh (win);
|
||||
}
|
||||
|
||||
/*
|
||||
* This refreshes all the objects in the screen.
|
||||
*/
|
||||
void refreshCDKScreen (CDKSCREEN *cdkscreen)
|
||||
{
|
||||
int objectCount = cdkscreen->objectCount;
|
||||
int x;
|
||||
int focused = -1;
|
||||
int visible = -1;
|
||||
|
||||
refreshCDKWindow (cdkscreen->window);
|
||||
|
||||
/* We erase all the invisible objects, then only
|
||||
* draw it all back, so that the objects
|
||||
* can overlap, and the visible ones will always
|
||||
* be drawn after all the invisible ones are erased */
|
||||
for (x = 0; x < objectCount; x++)
|
||||
{
|
||||
CDKOBJS *obj = cdkscreen->object[x];
|
||||
|
||||
if (validObjType (obj, ObjTypeOf (obj)))
|
||||
{
|
||||
if (obj->isVisible)
|
||||
{
|
||||
if (visible < 0)
|
||||
visible = x;
|
||||
if (obj->hasFocus && focused < 0)
|
||||
focused = x;
|
||||
}
|
||||
else
|
||||
{
|
||||
obj->fn->eraseObj (obj);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (x = 0; x < objectCount; x++)
|
||||
{
|
||||
CDKOBJS *obj = cdkscreen->object[x];
|
||||
|
||||
if (validObjType (obj, ObjTypeOf (obj)))
|
||||
{
|
||||
obj->hasFocus = (x == focused);
|
||||
|
||||
if (obj->isVisible)
|
||||
{
|
||||
obj->fn->drawObj (obj, obj->box);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This clears all the objects in the screen.
|
||||
*/
|
||||
void eraseCDKScreen (CDKSCREEN *cdkscreen)
|
||||
{
|
||||
int objectCount = cdkscreen->objectCount;
|
||||
int x;
|
||||
|
||||
/* We just call the drawObject function. */
|
||||
for (x = 0; x < objectCount; x++)
|
||||
{
|
||||
CDKOBJS *obj = cdkscreen->object[x];
|
||||
|
||||
if (validObjType (obj, ObjTypeOf (obj)))
|
||||
{
|
||||
obj->fn->eraseObj (obj);
|
||||
}
|
||||
}
|
||||
|
||||
/* Refresh the screen. */
|
||||
wrefresh (cdkscreen->window);
|
||||
}
|
||||
|
||||
/*
|
||||
* Destroy all of the objects on a screen
|
||||
*/
|
||||
void destroyCDKScreenObjects (CDKSCREEN *cdkscreen)
|
||||
{
|
||||
int x;
|
||||
|
||||
for (x = 0; x < cdkscreen->objectCount; x++)
|
||||
{
|
||||
CDKOBJS *obj = cdkscreen->object[x];
|
||||
int before = cdkscreen->objectCount;
|
||||
|
||||
if (validObjType (obj, ObjTypeOf (obj)))
|
||||
{
|
||||
MethodPtr (obj, eraseObj) (obj);
|
||||
_destroyCDKObject (obj);
|
||||
x -= (cdkscreen->objectCount - before);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This destroys a CDK screen.
|
||||
*/
|
||||
void destroyCDKScreen (CDKSCREEN *screen)
|
||||
{
|
||||
ALL_SCREENS *p, *q;
|
||||
|
||||
for (p = all_screens, q = 0; p != 0; q = p, p = p->link)
|
||||
{
|
||||
if (screen == p->screen)
|
||||
{
|
||||
if (q != 0)
|
||||
q->link = p->link;
|
||||
else
|
||||
all_screens = p->link;
|
||||
free (p);
|
||||
free (screen);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This is added to remain consistent.
|
||||
*/
|
||||
void endCDK (void)
|
||||
{
|
||||
/* Turn echoing back on. */
|
||||
echo ();
|
||||
|
||||
/* Turn off cbreak. */
|
||||
nocbreak ();
|
||||
|
||||
/* End the curses windows. */
|
||||
endwin ();
|
||||
|
||||
#ifdef HAVE_XCURSES
|
||||
XCursesExit ();
|
||||
#endif
|
||||
}
|
|
@ -1,107 +0,0 @@
|
|||
# $Id: Makefile.in,v 1.7 2013/07/19 23:55:03 tom Exp $
|
||||
#
|
||||
# Makefile for the cli directory.
|
||||
#
|
||||
SHELL = /bin/sh
|
||||
|
||||
prefix = @prefix@
|
||||
exec_prefix = @exec_prefix@
|
||||
|
||||
srcdir = @srcdir@
|
||||
VPATH = $(srcdir)
|
||||
|
||||
CC = @CC@
|
||||
RM = rm -f
|
||||
CTAGS = @CTAGS@
|
||||
ETAGS = @ETAGS@
|
||||
LINT = @LINT@
|
||||
LINT_OPTS = @LINT_OPTS@
|
||||
|
||||
LIBS = -l@LIB_ROOTNAME@ @LIBS@
|
||||
|
||||
LIBTOOL = @LIBTOOL@ @ECHO_LT@
|
||||
LIBTOOL_CLEAN = @LIB_CLEAN@
|
||||
LIBTOOL_LINK = @LIB_LINK@
|
||||
LINK = $(LIBTOOL_LINK)
|
||||
|
||||
x = @EXEEXT@
|
||||
o = .@OBJEXT@
|
||||
LOCAL_LIBDIR = @top_builddir@
|
||||
|
||||
CFLAGS = @CFLAGS@ @EXTRA_CFLAGS@
|
||||
CPPFLAGS = @DEFS@ -I../include -I$(srcdir)/../include -I. @CPPFLAGS@
|
||||
LDFLAGS = -L.. @LDFLAGS@ @LOCAL_LDFLAGS@
|
||||
|
||||
BINS = \
|
||||
cdkalphalist$x \
|
||||
cdkcalendar$x \
|
||||
cdkdialog$x \
|
||||
cdkentry$x \
|
||||
cdkfselect$x \
|
||||
cdkitemlist$x \
|
||||
cdklabel$x \
|
||||
cdkmatrix$x \
|
||||
cdkmentry$x \
|
||||
cdkradio$x \
|
||||
cdkscale$x \
|
||||
cdkscroll$x \
|
||||
cdkselection$x \
|
||||
cdkslider$x \
|
||||
cdktemplate$x \
|
||||
cdkviewer$x
|
||||
|
||||
CDKSRC = \
|
||||
cdkalphalist.c \
|
||||
cdkcalendar.c \
|
||||
cdkdialog.c \
|
||||
cdkentry.c \
|
||||
cdkfselect.c \
|
||||
cdkitemlist.c \
|
||||
cdklabel.c \
|
||||
cdkmatrix.c \
|
||||
cdkmentry.c \
|
||||
cdkradio.c \
|
||||
cdkscale.c \
|
||||
cdkscroll.c \
|
||||
cdkselection.c \
|
||||
cdkslider.c \
|
||||
cdktemplate.c \
|
||||
cdkviewer.c
|
||||
|
||||
LINKIT = @ECHO_LD@$(LINK) $(CFLAGS) $(CPPFLAGS) $? -o $@ $(LDFLAGS) $(LIBS)
|
||||
|
||||
all : $(BINS)
|
||||
|
||||
cdkalphalist$x : cdkalphalist.c ; $(LINKIT)
|
||||
cdkcalendar$x : cdkcalendar.c ; $(LINKIT)
|
||||
cdkdialog$x : cdkdialog.c ; $(LINKIT)
|
||||
cdkentry$x : cdkentry.c ; $(LINKIT)
|
||||
cdkfselect$x : cdkfselect.c ; $(LINKIT)
|
||||
cdkitemlist$x : cdkitemlist.c ; $(LINKIT)
|
||||
cdklabel$x : cdklabel.c ; $(LINKIT)
|
||||
cdkmatrix$x : cdkmatrix.c ; $(LINKIT)
|
||||
cdkmentry$x : cdkmentry.c ; $(LINKIT)
|
||||
cdkradio$x : cdkradio.c ; $(LINKIT)
|
||||
cdkscale$x : cdkscale.c ; $(LINKIT)
|
||||
cdkscroll$x : cdkscroll.c ; $(LINKIT)
|
||||
cdkselection$x : cdkselection.c ; $(LINKIT)
|
||||
cdkslider$x : cdkslider.c ; $(LINKIT)
|
||||
cdktemplate$x : cdktemplate.c ; $(LINKIT)
|
||||
cdkviewer$x : cdkviewer.c ; $(LINKIT)
|
||||
#
|
||||
# Standard clean directives.
|
||||
#
|
||||
clean::
|
||||
- $(LIBTOOL_CLEAN) $(RM) *.o core $(BINS)
|
||||
|
||||
distclean:: clean
|
||||
$(RM) Makefile
|
||||
|
||||
@MAKE_LOWER_TAGS@tags :
|
||||
@MAKE_LOWER_TAGS@ $(CTAGS) *.[ch] */*.[ch]
|
||||
|
||||
@MAKE_LOWER_TAGS@TAGS :
|
||||
@MAKE_LOWER_TAGS@ $(ETAGS) *.[ch] */*.[ch]
|
||||
|
||||
lint: $(CDKSRC)
|
||||
$(LINT) $(LINT_OPTS) $(CPPFLAGS) $(CDKSRC)
|
|
@ -1,276 +0,0 @@
|
|||
/* $Id: cdkalphalist.c,v 1.18 2016/12/04 15:22:16 tom Exp $ */
|
||||
|
||||
#include <cdk_test.h>
|
||||
|
||||
#ifdef XCURSES
|
||||
char *XCursesProgramName = "cdkalphalist";
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Declare file local prototypes.
|
||||
*/
|
||||
int widgetCB (EObjectType cdktype, void *object, void *clientData, chtype key);
|
||||
|
||||
/*
|
||||
* Define file local variables.
|
||||
*/
|
||||
static const char *FPUsage = "-l List | -f filename [-F Field Character] [-T Title] [-L Label] [-B Buttons] [-O Output File] [-X X Position] [-Y Y Position] [-H Height] [-W Width] [-N] [-S]";
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
int main (int argc, char **argv)
|
||||
{
|
||||
/* *INDENT-EQLS* */
|
||||
CDKSCREEN *cdkScreen = 0;
|
||||
CDKALPHALIST *widget = 0;
|
||||
CDKBUTTONBOX *buttonWidget = 0;
|
||||
char *CDK_WIDGET_COLOR = 0;
|
||||
char *answer = 0;
|
||||
char *buttons;
|
||||
char *temp = 0;
|
||||
chtype *holder = 0;
|
||||
chtype filler = A_NORMAL | '.';
|
||||
int scrollLines = -1;
|
||||
int buttonCount = 0;
|
||||
int shadowHeight = 0;
|
||||
FILE *fp = stderr;
|
||||
char **scrollList = 0;
|
||||
char **buttonList = 0;
|
||||
int j1, j2;
|
||||
|
||||
CDK_PARAMS params;
|
||||
boolean boxWidget;
|
||||
boolean shadowWidget;
|
||||
char *filename;
|
||||
char *label;
|
||||
char *list;
|
||||
char *outputFile;
|
||||
char *tempFiller;
|
||||
char *title;
|
||||
int height;
|
||||
int width;
|
||||
int xpos;
|
||||
int ypos;
|
||||
|
||||
CDKparseParams (argc, argv, ¶ms, "f:l:B:F:L:O:T:" CDK_CLI_PARAMS);
|
||||
|
||||
/* *INDENT-EQLS* */
|
||||
xpos = CDKparamValue (¶ms, 'X', CENTER);
|
||||
ypos = CDKparamValue (¶ms, 'Y', CENTER);
|
||||
height = CDKparamValue (¶ms, 'H', -1);
|
||||
width = CDKparamValue (¶ms, 'W', -1);
|
||||
boxWidget = CDKparamValue (¶ms, 'N', TRUE);
|
||||
shadowWidget = CDKparamValue (¶ms, 'S', FALSE);
|
||||
filename = CDKparamString (¶ms, 'f');
|
||||
list = CDKparamString (¶ms, 'l');
|
||||
buttons = CDKparamString (¶ms, 'B');
|
||||
tempFiller = CDKparamString (¶ms, 'F');
|
||||
label = CDKparamString (¶ms, 'L');
|
||||
outputFile = CDKparamString (¶ms, 'O');
|
||||
title = CDKparamString (¶ms, 'T');
|
||||
|
||||
/* If the user asked for an output file, try to open it. */
|
||||
if (outputFile != 0)
|
||||
{
|
||||
if ((fp = fopen (outputFile, "w")) == 0)
|
||||
{
|
||||
fprintf (stderr, "%s: Can not open output file %s\n", argv[0], outputFile);
|
||||
ExitProgram (CLI_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
/* Did they provide a list of items. */
|
||||
if (list == 0)
|
||||
{
|
||||
/* Maybe they gave a filename to use to read. */
|
||||
if (filename != 0)
|
||||
{
|
||||
/* Read the file in. */
|
||||
scrollLines = CDKreadFile (filename, &scrollList);
|
||||
|
||||
/* Check if there was an error. */
|
||||
if (scrollLines == -1)
|
||||
{
|
||||
fprintf (stderr, "Error: Could not open the file '%s'.\n", filename);
|
||||
ExitProgram (CLI_ERROR);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* They didn't provide anything. */
|
||||
fprintf (stderr, "Usage: %s %s\n", argv[0], FPUsage);
|
||||
ExitProgram (CLI_ERROR);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Split the scroll lines up. */
|
||||
scrollList = CDKsplitString (list, '\n');
|
||||
scrollLines = (int)CDKcountStrings ((CDK_CSTRING2)scrollList);
|
||||
}
|
||||
|
||||
cdkScreen = initCDKScreen (NULL);
|
||||
|
||||
/* Start color. */
|
||||
initCDKColor ();
|
||||
|
||||
/* Check if the user wants to set the background of the main screen. */
|
||||
if ((temp = getenv ("CDK_SCREEN_COLOR")) != 0)
|
||||
{
|
||||
holder = char2Chtype (temp, &j1, &j2);
|
||||
wbkgd (cdkScreen->window, holder[0]);
|
||||
wrefresh (cdkScreen->window);
|
||||
freeChtype (holder);
|
||||
}
|
||||
|
||||
/* Get the widget color background color. */
|
||||
if ((CDK_WIDGET_COLOR = getenv ("CDK_WIDGET_COLOR")) == 0)
|
||||
{
|
||||
CDK_WIDGET_COLOR = 0;
|
||||
}
|
||||
|
||||
/* If they set the filler character, set it now. */
|
||||
if (tempFiller != 0)
|
||||
{
|
||||
holder = char2Chtype (tempFiller, &j1, &j2);
|
||||
filler = holder[0];
|
||||
freeChtype (holder);
|
||||
}
|
||||
|
||||
/* Create the widget. */
|
||||
widget = newCDKAlphalist (cdkScreen, xpos, ypos,
|
||||
height, width,
|
||||
title, label,
|
||||
(CDK_CSTRING *)scrollList, scrollLines,
|
||||
filler, A_REVERSE,
|
||||
boxWidget, shadowWidget);
|
||||
|
||||
/* Make sure we could create the widget. */
|
||||
if (widget == 0)
|
||||
{
|
||||
CDKfreeStrings (scrollList);
|
||||
destroyCDKScreen (cdkScreen);
|
||||
endCDK ();
|
||||
|
||||
fprintf (stderr,
|
||||
"Error: Could not create the alphalist. "
|
||||
"Is the window too small?\n");
|
||||
|
||||
ExitProgram (CLI_ERROR);
|
||||
}
|
||||
|
||||
/* Split the buttons if they supplied some. */
|
||||
if (buttons != 0)
|
||||
{
|
||||
buttonList = CDKsplitString (buttons, '\n');
|
||||
buttonCount = (int)CDKcountStrings ((CDK_CSTRING2)buttonList);
|
||||
|
||||
buttonWidget = newCDKButtonbox (cdkScreen,
|
||||
getbegx (widget->win) + 1,
|
||||
(getbegy (widget->win)
|
||||
+ widget->boxHeight - 1),
|
||||
1, widget->boxWidth - 3,
|
||||
0, 1, buttonCount,
|
||||
(CDK_CSTRING2)buttonList, buttonCount,
|
||||
A_REVERSE, boxWidget, FALSE);
|
||||
CDKfreeStrings (buttonList);
|
||||
|
||||
setCDKButtonboxULChar (buttonWidget, ACS_LTEE);
|
||||
setCDKButtonboxURChar (buttonWidget, ACS_RTEE);
|
||||
|
||||
/*
|
||||
* We need to set the lower left and right
|
||||
* characters of the entry field.
|
||||
*/
|
||||
setCDKAlphalistLLChar (widget, ACS_LTEE);
|
||||
setCDKAlphalistLRChar (widget, ACS_RTEE);
|
||||
|
||||
/*
|
||||
* Bind the Tab key in the entry field to send a
|
||||
* Tab key to the button box widget.
|
||||
*/
|
||||
bindCDKObject (vENTRY, widget->entryField, KEY_RIGHT, widgetCB, buttonWidget);
|
||||
bindCDKObject (vENTRY, widget->entryField, KEY_LEFT, widgetCB, buttonWidget);
|
||||
bindCDKObject (vENTRY, widget->entryField, CDK_NEXT, widgetCB, buttonWidget);
|
||||
bindCDKObject (vENTRY, widget->entryField, CDK_PREV, widgetCB, buttonWidget);
|
||||
|
||||
setCDKButtonboxBackgroundColor (buttonWidget, CDK_WIDGET_COLOR);
|
||||
|
||||
drawCDKButtonbox (buttonWidget, boxWidget);
|
||||
}
|
||||
|
||||
/*
|
||||
* If the user asked for a shadow, we need to create one. Do this instead
|
||||
* of using the shadow parameter because the button widget is not part of
|
||||
* the main widget and if the user asks for both buttons and a shadow, we
|
||||
* need to create a shadow big enough for both widgets. Create the shadow
|
||||
* window using the widgets shadowWin element, so screen refreshes will draw
|
||||
* them as well.
|
||||
*/
|
||||
if (shadowWidget == TRUE)
|
||||
{
|
||||
/* Determine the height of the shadow window. */
|
||||
shadowHeight = (buttonWidget == 0 ?
|
||||
widget->boxHeight :
|
||||
widget->boxHeight + buttonWidget->boxHeight - 1);
|
||||
|
||||
/* Create the shadow window. */
|
||||
widget->shadowWin = newwin (shadowHeight,
|
||||
widget->boxWidth,
|
||||
getbegy (widget->win) + 1,
|
||||
getbegx (widget->win) + 1);
|
||||
|
||||
/* Make sure we could have created the shadow window. */
|
||||
if (widget->shadowWin != 0)
|
||||
{
|
||||
widget->shadow = TRUE;
|
||||
|
||||
/*
|
||||
* We force the widget and buttonWidget to be drawn so the
|
||||
* buttonbox widget will be drawn when the widget is activated.
|
||||
* Otherwise the shadow window will draw over the button widget.
|
||||
*/
|
||||
drawCDKAlphalist (widget, ObjOf (widget)->box);
|
||||
eraseCDKButtonbox (buttonWidget);
|
||||
drawCDKButtonbox (buttonWidget, ObjOf (buttonWidget)->box);
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if the user wants to set the background of the widget. */
|
||||
setCDKAlphalistBackgroundColor (widget, CDK_WIDGET_COLOR);
|
||||
|
||||
/* Activate the widget. */
|
||||
answer = copyChar (activateCDKAlphalist (widget, 0));
|
||||
|
||||
/* If there were buttons, get the button selected. */
|
||||
if (buttonWidget != 0)
|
||||
{
|
||||
destroyCDKButtonbox (buttonWidget);
|
||||
}
|
||||
|
||||
CDKfreeStrings (scrollList);
|
||||
|
||||
destroyCDKAlphalist (widget);
|
||||
destroyCDKScreen (cdkScreen);
|
||||
endCDK ();
|
||||
|
||||
/* Print out the answer. */
|
||||
if (answer != 0)
|
||||
{
|
||||
fprintf (fp, "%s\n", answer);
|
||||
freeChar (answer);
|
||||
}
|
||||
|
||||
/* Exit with the selected button. */
|
||||
ExitProgram (0);
|
||||
}
|
||||
|
||||
int widgetCB (EObjectType cdktype GCC_UNUSED, void *object GCC_UNUSED,
|
||||
void *clientData,
|
||||
chtype key)
|
||||
{
|
||||
CDKBUTTONBOX *buttonbox = (CDKBUTTONBOX *)clientData;
|
||||
(void)injectCDKButtonbox (buttonbox, key);
|
||||
return (TRUE);
|
||||
}
|
|
@ -1,252 +0,0 @@
|
|||
/* $Id: cdkcalendar.c,v 1.17 2016/12/04 15:22:16 tom Exp $ */
|
||||
|
||||
#include <cdk_test.h>
|
||||
|
||||
#ifdef XCURSES
|
||||
char *XCursesProgramName = "cdkcalendar";
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Declare file local prototypes.
|
||||
*/
|
||||
static int widgetCB (EObjectType cdktype, void *object, void *clientData, chtype key);
|
||||
|
||||
/*
|
||||
* Define file local variables.
|
||||
*/
|
||||
static void getTodaysDate (int *day, int *month, int *year);
|
||||
|
||||
int main (int argc, char **argv)
|
||||
{
|
||||
/* *INDENT-EQLS* */
|
||||
CDKSCREEN *cdkScreen = 0;
|
||||
CDKCALENDAR *widget = 0;
|
||||
CDKBUTTONBOX *buttonWidget = 0;
|
||||
struct tm *dateInfo = 0;
|
||||
time_t selected = 0;
|
||||
chtype dayAttrib = A_NORMAL;
|
||||
chtype monthAttrib = A_NORMAL;
|
||||
chtype yearAttrib = A_NORMAL;
|
||||
chtype highlight = A_REVERSE;
|
||||
chtype *holder = 0;
|
||||
char *CDK_WIDGET_COLOR = 0;
|
||||
char *temp = 0;
|
||||
int buttonCount = 0;
|
||||
int selection = 0;
|
||||
int shadowHeight = 0;
|
||||
FILE *fp = stderr;
|
||||
char **buttonList = 0;
|
||||
int j1, j2;
|
||||
|
||||
CDK_PARAMS params;
|
||||
boolean boxWidget;
|
||||
boolean shadowWidget;
|
||||
char *buttons;
|
||||
char *outputFile;
|
||||
char *title;
|
||||
int day;
|
||||
int month;
|
||||
int xpos;
|
||||
int year;
|
||||
int ypos;
|
||||
|
||||
getTodaysDate (&day, &month, &year);
|
||||
|
||||
CDKparseParams (argc, argv, ¶ms, "d:m:y:B:O:T:" CDK_MIN_PARAMS);
|
||||
|
||||
/* *INDENT-EQLS* */
|
||||
xpos = CDKparamValue (¶ms, 'X', CENTER);
|
||||
ypos = CDKparamValue (¶ms, 'Y', CENTER);
|
||||
boxWidget = CDKparamValue (¶ms, 'N', TRUE);
|
||||
shadowWidget = CDKparamValue (¶ms, 'S', FALSE);
|
||||
day = CDKparamValue (¶ms, 'd', day);
|
||||
month = CDKparamValue (¶ms, 'm', month);
|
||||
year = CDKparamValue (¶ms, 'y', year);
|
||||
buttons = CDKparamString (¶ms, 'B');
|
||||
outputFile = CDKparamString (¶ms, 'O');
|
||||
title = CDKparamString (¶ms, 'T');
|
||||
|
||||
/* If the user asked for an output file, try to open it. */
|
||||
if (outputFile != 0)
|
||||
{
|
||||
if ((fp = fopen (outputFile, "w")) == 0)
|
||||
{
|
||||
fprintf (stderr, "%s: Can not open output file %s\n", argv[0], outputFile);
|
||||
ExitProgram (CLI_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
cdkScreen = initCDKScreen (NULL);
|
||||
|
||||
/* Start color. */
|
||||
initCDKColor ();
|
||||
|
||||
/* Check if the user wants to set the background of the main screen. */
|
||||
if ((temp = getenv ("CDK_SCREEN_COLOR")) != 0)
|
||||
{
|
||||
holder = char2Chtype (temp, &j1, &j2);
|
||||
wbkgd (cdkScreen->window, holder[0]);
|
||||
wrefresh (cdkScreen->window);
|
||||
freeChtype (holder);
|
||||
}
|
||||
|
||||
/* Check if the user wants to set the background of the widget. */
|
||||
if ((CDK_WIDGET_COLOR = getenv ("CDK_WIDGET_COLOR")) == 0)
|
||||
{
|
||||
CDK_WIDGET_COLOR = 0;
|
||||
}
|
||||
|
||||
/* Create the calendar width. */
|
||||
widget = newCDKCalendar (cdkScreen, xpos, ypos, title,
|
||||
day, month, year,
|
||||
dayAttrib, monthAttrib,
|
||||
yearAttrib, highlight,
|
||||
boxWidget, shadowWidget);
|
||||
/* Check to make sure we created the dialog box. */
|
||||
if (widget == 0)
|
||||
{
|
||||
destroyCDKScreen (cdkScreen);
|
||||
endCDK ();
|
||||
|
||||
fprintf (stderr,
|
||||
"Error: Could not create the calendar. "
|
||||
"Is the window too small?\n");
|
||||
|
||||
ExitProgram (CLI_ERROR);
|
||||
}
|
||||
|
||||
/* Split the buttons if they supplied some. */
|
||||
if (buttons != 0)
|
||||
{
|
||||
/* Split the button list up. */
|
||||
buttonList = CDKsplitString (buttons, '\n');
|
||||
buttonCount = (int)CDKcountStrings ((CDK_CSTRING2) buttonList);
|
||||
|
||||
/* We need to create a buttonbox widget. */
|
||||
buttonWidget = newCDKButtonbox (cdkScreen,
|
||||
getbegx (widget->win),
|
||||
(getbegy (widget->win)
|
||||
+ widget->boxHeight - 1),
|
||||
1, widget->boxWidth - 1,
|
||||
0, 1, buttonCount,
|
||||
(CDK_CSTRING2) buttonList, buttonCount,
|
||||
A_REVERSE, boxWidget, FALSE);
|
||||
setCDKButtonboxULChar (buttonWidget, ACS_LTEE);
|
||||
setCDKButtonboxURChar (buttonWidget, ACS_RTEE);
|
||||
|
||||
/*
|
||||
* We need to set the lower left and right
|
||||
* characters of the widget.
|
||||
*/
|
||||
setCDKCalendarLLChar (widget, ACS_LTEE);
|
||||
setCDKCalendarLRChar (widget, ACS_RTEE);
|
||||
|
||||
/*
|
||||
* Bind the Tab key in the widget to send a
|
||||
* Tab key to the button box widget.
|
||||
*/
|
||||
bindCDKObject (vCALENDAR, widget, KEY_TAB, widgetCB, buttonWidget);
|
||||
bindCDKObject (vCALENDAR, widget, CDK_PREV, widgetCB, buttonWidget);
|
||||
bindCDKObject (vCALENDAR, widget, CDK_NEXT, widgetCB, buttonWidget);
|
||||
|
||||
/* Check if the user wants to set the background of the widget. */
|
||||
setCDKButtonboxBackgroundColor (buttonWidget, CDK_WIDGET_COLOR);
|
||||
|
||||
/* Draw the button widget. */
|
||||
drawCDKButtonbox (buttonWidget, boxWidget);
|
||||
}
|
||||
|
||||
/*
|
||||
* If the user asked for a shadow, we need to create one. Do this instead
|
||||
* of using the shadow parameter because the button widget is not part of
|
||||
* the main widget and if the user asks for both buttons and a shadow, we
|
||||
* need to create a shadow big enough for both widgets. Create the shadow
|
||||
* window using the widgets shadowWin element, so screen refreshes will draw
|
||||
* them as well.
|
||||
*/
|
||||
if (shadowWidget == TRUE)
|
||||
{
|
||||
/* Determine the height of the shadow window. */
|
||||
shadowHeight = (buttonWidget == 0 ?
|
||||
widget->boxHeight :
|
||||
widget->boxHeight + buttonWidget->boxHeight - 1);
|
||||
|
||||
/* Create the shadow window. */
|
||||
widget->shadowWin = newwin (shadowHeight,
|
||||
widget->boxWidth,
|
||||
getbegy (widget->win) + 1,
|
||||
getbegx (widget->win) + 1);
|
||||
|
||||
/* Make sure we could have created the shadow window. */
|
||||
if (widget->shadowWin != 0)
|
||||
{
|
||||
widget->shadow = TRUE;
|
||||
|
||||
/*
|
||||
* We force the widget and buttonWidget to be drawn so the
|
||||
* buttonbox widget will be drawn when the widget is activated.
|
||||
* Otherwise the shadow window will draw over the button widget.
|
||||
*/
|
||||
drawCDKCalendar (widget, ObjOf (widget)->box);
|
||||
eraseCDKButtonbox (buttonWidget);
|
||||
drawCDKButtonbox (buttonWidget, ObjOf (buttonWidget)->box);
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if the user wants to set the background of the widget. */
|
||||
setCDKCalendarBackgroundColor (widget, CDK_WIDGET_COLOR);
|
||||
|
||||
/* Activate the calendar widget. */
|
||||
selected = activateCDKCalendar (widget, 0);
|
||||
|
||||
/* If there were buttons, get the button selected. */
|
||||
if (buttonWidget != 0)
|
||||
{
|
||||
selection = buttonWidget->currentButton;
|
||||
destroyCDKButtonbox (buttonWidget);
|
||||
}
|
||||
|
||||
CDKfreeStrings (buttonList);
|
||||
|
||||
destroyCDKCalendar (widget);
|
||||
destroyCDKScreen (cdkScreen);
|
||||
endCDK ();
|
||||
|
||||
/* Print out the date selected. D/M/Y format. */
|
||||
dateInfo = gmtime (&selected);
|
||||
fprintf (fp, "%02d/%02d/%d\n",
|
||||
dateInfo->tm_mday,
|
||||
(dateInfo->tm_mon + 1),
|
||||
(dateInfo->tm_year + 1900));
|
||||
fclose (fp);
|
||||
|
||||
ExitProgram (selection);
|
||||
}
|
||||
|
||||
/*
|
||||
* This returns what day of the week the month starts on.
|
||||
*/
|
||||
static void getTodaysDate (int *day, int *month, int *year)
|
||||
{
|
||||
struct tm *dateInfo;
|
||||
time_t clck;
|
||||
|
||||
/* Determine the current time and determine if we are in DST. */
|
||||
time (&clck);
|
||||
dateInfo = gmtime (&clck);
|
||||
|
||||
/* Set the pointers accordingly. */
|
||||
(*day) = dateInfo->tm_mday;
|
||||
(*month) = dateInfo->tm_mon + 1;
|
||||
(*year) = dateInfo->tm_year + 1900;
|
||||
}
|
||||
|
||||
static int widgetCB (EObjectType cdktype GCC_UNUSED,
|
||||
void *object GCC_UNUSED,
|
||||
void *clientData,
|
||||
chtype key)
|
||||
{
|
||||
CDKBUTTONBOX *buttonbox = (CDKBUTTONBOX *)clientData;
|
||||
(void) injectCDKButtonbox (buttonbox, key);
|
||||
return (TRUE);
|
||||
}
|
|
@ -1,178 +0,0 @@
|
|||
/* $Id: cdkdialog.c,v 1.15 2016/12/04 15:22:16 tom Exp $ */
|
||||
|
||||
#include <cdk_test.h>
|
||||
|
||||
#ifdef XCURSES
|
||||
char *XCursesProgramName = "cdkdialog";
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Define file local variables.
|
||||
*/
|
||||
static const char *FPUsage = "-m Message String | -f filename [-B Buttons] [-O Output file] [-X X Position] [-Y Y Position] [-N] [-S]";
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
int main (int argc, char **argv)
|
||||
{
|
||||
/* *INDENT-EQLS* */
|
||||
CDKSCREEN *cdkScreen = 0;
|
||||
CDKDIALOG *widget = 0;
|
||||
char *CDK_WIDGET_COLOR = 0;
|
||||
char *button = 0;
|
||||
char *temp = 0;
|
||||
chtype *holder = 0;
|
||||
int answer = 0;
|
||||
int messageLines = -1;
|
||||
int buttonCount = 0;
|
||||
FILE *fp = stderr;
|
||||
char **messageList = 0;
|
||||
char **buttonList = 0;
|
||||
int j1, j2;
|
||||
|
||||
CDK_PARAMS params;
|
||||
boolean boxWidget;
|
||||
boolean shadowWidget;
|
||||
char *buttons;
|
||||
char *filename;
|
||||
char *outputFile;
|
||||
char *message;
|
||||
int xpos;
|
||||
int ypos;
|
||||
|
||||
CDKparseParams (argc, argv, ¶ms, "f:m:B:O:" CDK_MIN_PARAMS);
|
||||
|
||||
/* *INDENT-EQLS* */
|
||||
xpos = CDKparamValue (¶ms, 'X', CENTER);
|
||||
ypos = CDKparamValue (¶ms, 'Y', CENTER);
|
||||
boxWidget = CDKparamValue (¶ms, 'N', TRUE);
|
||||
shadowWidget = CDKparamValue (¶ms, 'S', FALSE);
|
||||
filename = CDKparamString (¶ms, 'f');
|
||||
message = CDKparamString (¶ms, 'm');
|
||||
buttons = CDKparamString (¶ms, 'B');
|
||||
outputFile = CDKparamString (¶ms, 'O');
|
||||
|
||||
/* If the user asked for an output file, try to open it. */
|
||||
if (outputFile != 0)
|
||||
{
|
||||
if ((fp = fopen (outputFile, "w")) == 0)
|
||||
{
|
||||
fprintf (stderr, "%s: Can not open output file %s\n", argv[0], outputFile);
|
||||
ExitProgram (CLI_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
/* Make sure we have a message to display. */
|
||||
if (message == 0)
|
||||
{
|
||||
/* No message, maybe they provided a file to read. */
|
||||
if (filename != 0)
|
||||
{
|
||||
/* Read the file in. */
|
||||
messageLines = CDKreadFile (filename, &messageList);
|
||||
|
||||
/* Check if there was an error. */
|
||||
if (messageLines == -1)
|
||||
{
|
||||
fprintf (stderr, "Error: Could not open the file %s\n", filename);
|
||||
ExitProgram (CLI_ERROR);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* No message, no file, it's an error. */
|
||||
fprintf (stderr, "Usage: %s %s\n", argv[0], FPUsage);
|
||||
ExitProgram (CLI_ERROR);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Split the message up. */
|
||||
messageList = CDKsplitString (message, '\n');
|
||||
messageLines = (int)CDKcountStrings ((CDK_CSTRING2)messageList);
|
||||
}
|
||||
|
||||
/* Set up the buttons for the dialog box. */
|
||||
if (buttons == 0)
|
||||
{
|
||||
buttonList = calloc(sizeof(char *), 3);
|
||||
buttonList[0] = copyChar ("OK");
|
||||
buttonList[1] = copyChar ("Cancel");
|
||||
buttonCount = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Split the button list up. */
|
||||
buttonList = CDKsplitString (buttons, '\n');
|
||||
buttonCount = (int)CDKcountStrings ((CDK_CSTRING2)buttonList);
|
||||
}
|
||||
|
||||
cdkScreen = initCDKScreen (NULL);
|
||||
|
||||
/* Start color. */
|
||||
initCDKColor ();
|
||||
|
||||
/* Check if the user wants to set the background of the main screen. */
|
||||
if ((temp = getenv ("CDK_SCREEN_COLOR")) != 0)
|
||||
{
|
||||
holder = char2Chtype (temp, &j1, &j2);
|
||||
wbkgd (cdkScreen->window, holder[0]);
|
||||
wrefresh (cdkScreen->window);
|
||||
freeChtype (holder);
|
||||
}
|
||||
|
||||
/* Get the widget color background color. */
|
||||
if ((CDK_WIDGET_COLOR = getenv ("CDK_WIDGET_COLOR")) == 0)
|
||||
{
|
||||
CDK_WIDGET_COLOR = 0;
|
||||
}
|
||||
|
||||
/* Create the dialog box. */
|
||||
widget = newCDKDialog (cdkScreen, xpos, ypos,
|
||||
(CDK_CSTRING2)messageList, messageLines,
|
||||
(CDK_CSTRING2)buttonList, buttonCount,
|
||||
A_REVERSE,
|
||||
boxWidget, boxWidget, shadowWidget);
|
||||
|
||||
/* Check to make sure we created the dialog box. */
|
||||
if (widget == 0)
|
||||
{
|
||||
CDKfreeStrings (messageList);
|
||||
CDKfreeStrings (buttonList);
|
||||
|
||||
destroyCDKScreen (cdkScreen);
|
||||
endCDK ();
|
||||
|
||||
fprintf (stderr,
|
||||
"Error: Could not create the dialog box. "
|
||||
"Is the window too small?\n");
|
||||
|
||||
ExitProgram (CLI_ERROR);
|
||||
}
|
||||
|
||||
/* Check if the user wants to set the background of the widget. */
|
||||
setCDKDialogBackgroundColor (widget, CDK_WIDGET_COLOR);
|
||||
|
||||
/* Activate the dialog box. */
|
||||
answer = activateCDKDialog (widget, 0);
|
||||
|
||||
/* End CDK. */
|
||||
destroyCDKDialog (widget);
|
||||
destroyCDKScreen (cdkScreen);
|
||||
endCDK ();
|
||||
|
||||
/* Print the name of the button selected. */
|
||||
if (answer >= 0)
|
||||
{
|
||||
button = copyChar (buttonList[answer]);
|
||||
fprintf (fp, "%s\n", button);
|
||||
freeChar (button);
|
||||
}
|
||||
|
||||
CDKfreeStrings (messageList);
|
||||
CDKfreeStrings (buttonList);
|
||||
|
||||
/* Exit with the button number picked. */
|
||||
ExitProgram (answer);
|
||||
}
|
|
@ -1,267 +0,0 @@
|
|||
/* $Id: cdkentry.c,v 1.16 2016/12/04 15:22:16 tom Exp $ */
|
||||
|
||||
#include <cdk_test.h>
|
||||
|
||||
#ifdef XCURSES
|
||||
char *XCursesProgramName = "cdkentry";
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Declare file local prototypes.
|
||||
*/
|
||||
static int widgetCB (EObjectType cdktype, void *object, void *clientData, chtype key);
|
||||
|
||||
/*
|
||||
* Define file local variables.
|
||||
*/
|
||||
static const char *FPUsage = "-f Field Width [-d Display Type] [-F Field Character] [-i Initial Value] [-m Minimum Length] [-M Maximum Length] [-T Title] [-L Label] [-B Buttons] [-O Output file] [-X X Position] [-Y Y Position] [-N] [-S]";
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
int main (int argc, char **argv)
|
||||
{
|
||||
/* *INDENT-EQLS* */
|
||||
CDKSCREEN *cdkScreen = 0;
|
||||
CDKENTRY *widget = 0;
|
||||
CDKBUTTONBOX *buttonWidget = 0;
|
||||
chtype *holder = 0;
|
||||
chtype fieldAttr = A_NORMAL;
|
||||
char *answer = 0;
|
||||
char *CDK_WIDGET_COLOR = 0;
|
||||
char *temp = 0;
|
||||
char filler = '.';
|
||||
EDisplayType dType = vMIXED;
|
||||
int buttonCount = 0;
|
||||
int selection = 0;
|
||||
int shadowHeight = 0;
|
||||
FILE *fp = stderr;
|
||||
char **buttonList = 0;
|
||||
int j1, j2;
|
||||
|
||||
CDK_PARAMS params;
|
||||
boolean boxWidget;
|
||||
boolean shadowWidget;
|
||||
char *buttons;
|
||||
char *outputFile;
|
||||
char *initValue;
|
||||
char *title;
|
||||
char *label;
|
||||
char *tempFiller;
|
||||
int maxValue;
|
||||
int fieldWidth;
|
||||
int minValue;
|
||||
int xpos;
|
||||
int ypos;
|
||||
|
||||
CDKparseParams (argc, argv, ¶ms, "d:f:i:m:B:F:L:M:O:T:" CDK_MIN_PARAMS);
|
||||
|
||||
/* *INDENT-EQLS* */
|
||||
xpos = CDKparamValue (¶ms, 'X', CENTER);
|
||||
ypos = CDKparamValue (¶ms, 'Y', CENTER);
|
||||
boxWidget = CDKparamValue (¶ms, 'N', TRUE);
|
||||
shadowWidget = CDKparamValue (¶ms, 'S', FALSE);
|
||||
minValue = CDKparamValue (¶ms, 'm', 0);
|
||||
fieldWidth = CDKparamValue (¶ms, 'f', 0);
|
||||
maxValue = CDKparamValue (¶ms, 'M', 256);
|
||||
initValue = CDKparamString (¶ms, 'i');
|
||||
buttons = CDKparamString (¶ms, 'B');
|
||||
tempFiller = CDKparamString (¶ms, 'F');
|
||||
label = CDKparamString (¶ms, 'L');
|
||||
outputFile = CDKparamString (¶ms, 'O');
|
||||
title = CDKparamString (¶ms, 'T');
|
||||
|
||||
if ((temp = CDKparamString (¶ms, 'd')) != 0)
|
||||
dType = char2DisplayType (temp);
|
||||
|
||||
/* Make sure all the command line parameters were provided. */
|
||||
if (fieldWidth <= 0)
|
||||
{
|
||||
fprintf (stderr, "Usage: %s %s\n", argv[0], FPUsage);
|
||||
ExitProgram (CLI_ERROR);
|
||||
}
|
||||
|
||||
/* If the user asked for an output file, try to open it. */
|
||||
if (outputFile != 0)
|
||||
{
|
||||
if ((fp = fopen (outputFile, "w")) == 0)
|
||||
{
|
||||
fprintf (stderr, "%s: Can not open output file %s\n", argv[0], outputFile);
|
||||
ExitProgram (CLI_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
cdkScreen = initCDKScreen (NULL);
|
||||
|
||||
/* Start color. */
|
||||
initCDKColor ();
|
||||
|
||||
/* Check if the user wants to set the background of the main screen. */
|
||||
if ((temp = getenv ("CDK_SCREEN_COLOR")) != 0)
|
||||
{
|
||||
holder = char2Chtype (temp, &j1, &j2);
|
||||
wbkgd (cdkScreen->window, holder[0]);
|
||||
wrefresh (cdkScreen->window);
|
||||
freeChtype (holder);
|
||||
}
|
||||
|
||||
/* Get the widget color background color. */
|
||||
if ((CDK_WIDGET_COLOR = getenv ("CDK_WIDGET_COLOR")) == 0)
|
||||
{
|
||||
CDK_WIDGET_COLOR = 0;
|
||||
}
|
||||
|
||||
/* If the set the filler character, set it now. */
|
||||
if (tempFiller != 0)
|
||||
{
|
||||
holder = char2Chtype (tempFiller, &j1, &j2);
|
||||
fieldAttr = A_ATTRIBUTES & holder[0];
|
||||
filler = (char)holder[0];
|
||||
freeChtype (holder);
|
||||
}
|
||||
|
||||
/* Create the entry widget. */
|
||||
widget = newCDKEntry (cdkScreen, xpos, ypos,
|
||||
title, label,
|
||||
fieldAttr,
|
||||
(chtype)filler | fieldAttr,
|
||||
dType, fieldWidth,
|
||||
minValue, maxValue,
|
||||
boxWidget, FALSE);
|
||||
|
||||
/* Check to make sure we created the dialog box. */
|
||||
if (widget == 0)
|
||||
{
|
||||
/* Shut down curses and CDK. */
|
||||
destroyCDKScreen (cdkScreen);
|
||||
endCDK ();
|
||||
|
||||
fprintf (stderr,
|
||||
"Error: Could not create the entry field. "
|
||||
"Is the window too small?\n");
|
||||
|
||||
ExitProgram (CLI_ERROR);
|
||||
}
|
||||
|
||||
/* Split the buttons if they supplied some. */
|
||||
if (buttons != 0)
|
||||
{
|
||||
buttonList = CDKsplitString (buttons, '\n');
|
||||
buttonCount = (int)CDKcountStrings ((CDK_CSTRING2)buttonList);
|
||||
|
||||
buttonWidget = newCDKButtonbox (cdkScreen,
|
||||
getbegx (widget->win),
|
||||
(getbegy (widget->win)
|
||||
+ widget->boxHeight - 1),
|
||||
1, widget->boxWidth - 1,
|
||||
0, 1, buttonCount,
|
||||
(CDK_CSTRING2)buttonList, buttonCount,
|
||||
A_REVERSE, boxWidget, FALSE);
|
||||
CDKfreeStrings (buttonList);
|
||||
|
||||
setCDKButtonboxULChar (buttonWidget, ACS_LTEE);
|
||||
setCDKButtonboxURChar (buttonWidget, ACS_RTEE);
|
||||
|
||||
/*
|
||||
* We need to set the lower left and right
|
||||
* characters of the entry field.
|
||||
*/
|
||||
setCDKEntryLLChar (widget, ACS_LTEE);
|
||||
setCDKEntryLRChar (widget, ACS_RTEE);
|
||||
|
||||
/*
|
||||
* Bind the Tab key in the entry field to send a
|
||||
* Tab key to the button box widget.
|
||||
*/
|
||||
bindCDKObject (vENTRY, widget, KEY_TAB, widgetCB, buttonWidget);
|
||||
bindCDKObject (vENTRY, widget, CDK_NEXT, widgetCB, buttonWidget);
|
||||
bindCDKObject (vENTRY, widget, CDK_PREV, widgetCB, buttonWidget);
|
||||
|
||||
/* Check if the user wants to set the background of the widget. */
|
||||
setCDKButtonboxBackgroundColor (buttonWidget, CDK_WIDGET_COLOR);
|
||||
|
||||
/* Draw the button widget. */
|
||||
drawCDKButtonbox (buttonWidget, boxWidget);
|
||||
}
|
||||
|
||||
/*
|
||||
* If the user asked for a shadow, we need to create one. Do this instead
|
||||
* of using the shadow parameter because the button widget is not part of
|
||||
* the main widget and if the user asks for both buttons and a shadow, we
|
||||
* need to create a shadow big enough for both widgets. Create the shadow
|
||||
* window using the widgets shadowWin element, so screen refreshes will draw
|
||||
* them as well.
|
||||
*/
|
||||
if (shadowWidget == TRUE)
|
||||
{
|
||||
/* Determine the height of the shadow window. */
|
||||
shadowHeight = (buttonWidget == 0 ?
|
||||
widget->boxHeight :
|
||||
widget->boxHeight + buttonWidget->boxHeight - 1);
|
||||
|
||||
/* Create the shadow window. */
|
||||
widget->shadowWin = newwin (shadowHeight,
|
||||
widget->boxWidth,
|
||||
getbegy (widget->win) + 1,
|
||||
getbegx (widget->win) + 1);
|
||||
|
||||
/* Make sure we could have created the shadow window. */
|
||||
if (widget->shadowWin != 0)
|
||||
{
|
||||
widget->shadow = TRUE;
|
||||
|
||||
/*
|
||||
* We force the widget and buttonWidget to be drawn so the
|
||||
* buttonbox widget will be drawn when the widget is activated.
|
||||
* Otherwise the shadow window will draw over the button widget.
|
||||
*/
|
||||
drawCDKEntry (widget, ObjOf (widget)->box);
|
||||
eraseCDKButtonbox (buttonWidget);
|
||||
drawCDKButtonbox (buttonWidget, ObjOf (buttonWidget)->box);
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if the user wants to set the background of the widget. */
|
||||
setCDKEntryBackgroundColor (widget, CDK_WIDGET_COLOR);
|
||||
|
||||
/* If there was an initial value, set it. */
|
||||
if (initValue != 0)
|
||||
{
|
||||
setCDKEntryValue (widget, initValue);
|
||||
}
|
||||
|
||||
/* Activate the widget. */
|
||||
answer = copyChar (activateCDKEntry (widget, 0));
|
||||
|
||||
/* If there were buttons, get the button selected. */
|
||||
if (buttonWidget != 0)
|
||||
{
|
||||
selection = buttonWidget->currentButton;
|
||||
destroyCDKButtonbox (buttonWidget);
|
||||
}
|
||||
|
||||
/* End CDK. */
|
||||
destroyCDKEntry (widget);
|
||||
destroyCDKScreen (cdkScreen);
|
||||
endCDK ();
|
||||
|
||||
/* Print the value from the widget. */
|
||||
if (answer != 0)
|
||||
{
|
||||
fprintf (fp, "%s\n", answer);
|
||||
freeChar (answer);
|
||||
}
|
||||
fclose (fp);
|
||||
|
||||
/* Exit with the button number picked. */
|
||||
ExitProgram (selection);
|
||||
}
|
||||
|
||||
static int widgetCB (EObjectType cdktype GCC_UNUSED, void *object GCC_UNUSED,
|
||||
void *clientData,
|
||||
chtype key)
|
||||
{
|
||||
CDKBUTTONBOX *buttonbox = (CDKBUTTONBOX *)clientData;
|
||||
(void)injectCDKButtonbox (buttonbox, key);
|
||||
return (TRUE);
|
||||
}
|
|
@ -1,238 +0,0 @@
|
|||
/* $Id: cdkfselect.c,v 1.14 2016/12/04 15:22:16 tom Exp $ */
|
||||
|
||||
#include <cdk_test.h>
|
||||
|
||||
#ifdef XCURSES
|
||||
char *XCursesProgramName = "cdkfselect";
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Declare file local prototypes.
|
||||
*/
|
||||
static int widgetCB (EObjectType cdktype, void *object, void *clientData, chtype key);
|
||||
|
||||
int main (int argc, char **argv)
|
||||
{
|
||||
/* *INDENT-EQLS* */
|
||||
CDKSCREEN *cdkScreen = 0;
|
||||
CDKFSELECT *widget = 0;
|
||||
CDKBUTTONBOX *buttonWidget = 0;
|
||||
char *filename = 0;
|
||||
char *CDK_WIDGET_COLOR = 0;
|
||||
char *temp = 0;
|
||||
chtype *holder = 0;
|
||||
int selection = 0;
|
||||
int shadowHeight = 0;
|
||||
int buttonCount = 0;
|
||||
FILE *fp = stderr;
|
||||
char **buttonList = 0;
|
||||
int j1, j2;
|
||||
|
||||
CDK_PARAMS params;
|
||||
boolean boxWidget;
|
||||
boolean shadowWidget;
|
||||
char *buttons;
|
||||
char *directory;
|
||||
char *label;
|
||||
char *outputFile;
|
||||
char *title;
|
||||
int height;
|
||||
int width;
|
||||
int xpos;
|
||||
int ypos;
|
||||
|
||||
CDKparseParams (argc, argv, ¶ms, "d:B:L:O:T:" CDK_CLI_PARAMS);
|
||||
|
||||
/* *INDENT-EQLS* */
|
||||
xpos = CDKparamValue (¶ms, 'X', CENTER);
|
||||
ypos = CDKparamValue (¶ms, 'Y', CENTER);
|
||||
height = CDKparamValue (¶ms, 'H', 0);
|
||||
width = CDKparamValue (¶ms, 'W', 0);
|
||||
boxWidget = CDKparamValue (¶ms, 'N', TRUE);
|
||||
shadowWidget = CDKparamValue (¶ms, 'S', FALSE);
|
||||
directory = CDKparamString (¶ms, 'd');
|
||||
buttons = CDKparamString (¶ms, 'B');
|
||||
label = CDKparamString (¶ms, 'L');
|
||||
outputFile = CDKparamString (¶ms, 'O');
|
||||
title = CDKparamString (¶ms, 'T');
|
||||
|
||||
/* If the user asked for an output file, try to open it. */
|
||||
if (outputFile != 0)
|
||||
{
|
||||
if ((fp = fopen (outputFile, "w")) == 0)
|
||||
{
|
||||
fprintf (stderr, "%s: Can not open output file %s\n", argv[0], outputFile);
|
||||
ExitProgram (CLI_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
/* If they didn't provide a directory, use . */
|
||||
if (directory == 0)
|
||||
{
|
||||
directory = copyChar (".");
|
||||
}
|
||||
|
||||
/* Set the label of the file selector if it hasn't been yet. */
|
||||
if (label == 0)
|
||||
{
|
||||
label = copyChar ("Directory: ");
|
||||
}
|
||||
|
||||
cdkScreen = initCDKScreen (NULL);
|
||||
|
||||
/* Start color. */
|
||||
initCDKColor ();
|
||||
|
||||
/* Check if the user wants to set the background of the main screen. */
|
||||
if ((temp = getenv ("CDK_SCREEN_COLOR")) != 0)
|
||||
{
|
||||
holder = char2Chtype (temp, &j1, &j2);
|
||||
wbkgd (cdkScreen->window, holder[0]);
|
||||
wrefresh (cdkScreen->window);
|
||||
freeChtype (holder);
|
||||
}
|
||||
|
||||
/* Get the widget color background color. */
|
||||
if ((CDK_WIDGET_COLOR = getenv ("CDK_WIDGET_COLOR")) == 0)
|
||||
{
|
||||
CDK_WIDGET_COLOR = 0;
|
||||
}
|
||||
|
||||
/* Create the file selector widget. */
|
||||
widget = newCDKFselect (cdkScreen, xpos, ypos, height, width,
|
||||
title, label, A_NORMAL, '.', A_REVERSE,
|
||||
"", "", "", "",
|
||||
boxWidget, shadowWidget);
|
||||
freeChar (label);
|
||||
|
||||
/* Check to make sure we created the file selector. */
|
||||
if (widget == 0)
|
||||
{
|
||||
CDKfreeStrings (buttonList);
|
||||
|
||||
destroyCDKScreen (cdkScreen);
|
||||
endCDK ();
|
||||
|
||||
fprintf (stderr,
|
||||
"Error: Could not create the file selector. "
|
||||
"Is the window too small?\n");
|
||||
|
||||
ExitProgram (CLI_ERROR);
|
||||
}
|
||||
|
||||
/* Split the buttons if they supplied some. */
|
||||
if (buttons != 0)
|
||||
{
|
||||
buttonList = CDKsplitString (buttons, '\n');
|
||||
buttonCount = (int)CDKcountStrings ((CDK_CSTRING2) buttonList);
|
||||
|
||||
/* We need to create a buttonbox widget. */
|
||||
buttonWidget = newCDKButtonbox (cdkScreen,
|
||||
getbegx (widget->win),
|
||||
(getbegy (widget->win)
|
||||
+ widget->boxHeight - 2),
|
||||
1, widget->boxWidth - 2,
|
||||
0, 1, buttonCount,
|
||||
(CDK_CSTRING2) buttonList, buttonCount,
|
||||
A_REVERSE, boxWidget, FALSE);
|
||||
CDKfreeStrings (buttonList);
|
||||
|
||||
setCDKButtonboxULChar (buttonWidget, ACS_LTEE);
|
||||
setCDKButtonboxURChar (buttonWidget, ACS_RTEE);
|
||||
|
||||
/*
|
||||
* We need to set the lower left and right
|
||||
* characters of the widget.
|
||||
*/
|
||||
setCDKFselectLLChar (widget, ACS_LTEE);
|
||||
setCDKFselectLRChar (widget, ACS_RTEE);
|
||||
|
||||
/*
|
||||
* Bind the Tab key in the widget to send a
|
||||
* Tab key to the button box widget.
|
||||
*/
|
||||
bindCDKObject (vFSELECT, widget, KEY_TAB, widgetCB, buttonWidget);
|
||||
bindCDKObject (vFSELECT, widget, CDK_NEXT, widgetCB, buttonWidget);
|
||||
bindCDKObject (vFSELECT, widget, CDK_PREV, widgetCB, buttonWidget);
|
||||
|
||||
/* Check if the user wants to set the background of the widget. */
|
||||
setCDKButtonboxBackgroundColor (buttonWidget, CDK_WIDGET_COLOR);
|
||||
|
||||
/* Draw the button widget. */
|
||||
drawCDKButtonbox (buttonWidget, boxWidget);
|
||||
}
|
||||
|
||||
/*
|
||||
* If the user asked for a shadow, we need to create one. Do this instead
|
||||
* of using the shadow parameter because the button widget is not part of
|
||||
* the main widget and if the user asks for both buttons and a shadow, we
|
||||
* need to create a shadow big enough for both widgets. Create the shadow
|
||||
* window using the widgets shadowWin element, so screen refreshes will draw
|
||||
* them as well.
|
||||
*/
|
||||
if (shadowWidget == TRUE)
|
||||
{
|
||||
/* Determine the height of the shadow window. */
|
||||
shadowHeight = (buttonWidget == 0 ?
|
||||
widget->boxHeight :
|
||||
widget->boxHeight + buttonWidget->boxHeight - 1);
|
||||
|
||||
/* Create the shadow window. */
|
||||
widget->shadowWin = newwin (shadowHeight,
|
||||
widget->boxWidth,
|
||||
getbegy (widget->win) + 1,
|
||||
getbegx (widget->win) + 1);
|
||||
|
||||
/* Make sure we could have created the shadow window. */
|
||||
if (widget->shadowWin != 0)
|
||||
{
|
||||
widget->shadow = TRUE;
|
||||
|
||||
/*
|
||||
* We force the widget and buttonWidget to be drawn so the
|
||||
* buttonbox widget will be drawn when the widget is activated.
|
||||
* Otherwise the shadow window will draw over the button widget.
|
||||
*/
|
||||
drawCDKFselect (widget, ObjOf (widget)->box);
|
||||
eraseCDKButtonbox (buttonWidget);
|
||||
drawCDKButtonbox (buttonWidget, ObjOf (buttonWidget)->box);
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if the user wants to set the background of the widget. */
|
||||
setCDKFselectBackgroundColor (widget, CDK_WIDGET_COLOR);
|
||||
|
||||
/* Set the information for the file selector. */
|
||||
setCDKFselectDirectory (widget, directory);
|
||||
|
||||
/* Activate the file selector. */
|
||||
filename = copyChar (activateCDKFselect (widget, 0));
|
||||
|
||||
/* If there were buttons, get the button selected. */
|
||||
if (buttonWidget != 0)
|
||||
{
|
||||
selection = buttonWidget->currentButton;
|
||||
destroyCDKButtonbox (buttonWidget);
|
||||
}
|
||||
|
||||
destroyCDKFselect (widget);
|
||||
destroyCDKScreen (cdkScreen);
|
||||
endCDK ();
|
||||
|
||||
/* Print the filename selected. */
|
||||
fprintf (fp, "%s\n", filename);
|
||||
freeChar (filename);
|
||||
fclose (fp);
|
||||
|
||||
ExitProgram (selection);
|
||||
}
|
||||
|
||||
static int widgetCB (EObjectType cdktype GCC_UNUSED,
|
||||
void *object GCC_UNUSED,
|
||||
void *clientData,
|
||||
chtype key)
|
||||
{
|
||||
CDKBUTTONBOX *buttonbox = (CDKBUTTONBOX *)clientData;
|
||||
(void) injectCDKButtonbox (buttonbox, key);
|
||||
return (TRUE);
|
||||
}
|
|
@ -1,271 +0,0 @@
|
|||
/* $Id: cdkitemlist.c,v 1.14 2016/12/04 15:22:16 tom Exp $ */
|
||||
|
||||
#include <cdk_test.h>
|
||||
|
||||
#ifdef XCURSES
|
||||
char *XCursesProgramName = "cdkitemlist";
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Declare file local prototypes.
|
||||
*/
|
||||
static int widgetCB (EObjectType cdktype, void *object, void *clientData, chtype key);
|
||||
|
||||
/*
|
||||
* Define file local variables.
|
||||
*/
|
||||
static const char *FPUsage = "-l List | -f filename [-d Default Item] [-T Title] [-L Label] [-B Buttons] [-O Output File] [-X X Position] [-Y Y Position] [-N] [-S]";
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
int main (int argc, char **argv)
|
||||
{
|
||||
/* *INDENT-EQLS* */
|
||||
CDKSCREEN *cdkScreen = 0;
|
||||
CDKITEMLIST *widget = 0;
|
||||
CDKBUTTONBOX *buttonWidget = 0;
|
||||
chtype *holder = 0;
|
||||
char *answer = 0;
|
||||
char *CDK_WIDGET_COLOR = 0;
|
||||
char *temp = 0;
|
||||
int ret = 0;
|
||||
int buttonCount = 0;
|
||||
int selection = 0;
|
||||
int shadowHeight = 0;
|
||||
FILE *fp = stderr;
|
||||
char **itemlistList = 0;
|
||||
char **buttonList = 0;
|
||||
int itemlistLines, j1, j2;
|
||||
|
||||
CDK_PARAMS params;
|
||||
boolean boxWidget;
|
||||
boolean shadowWidget;
|
||||
char *buttons;
|
||||
char *filename;
|
||||
char *label;
|
||||
char *list;
|
||||
char *outputFile;
|
||||
char *title;
|
||||
int defaultItem;
|
||||
int xpos;
|
||||
int ypos;
|
||||
|
||||
CDKparseParams (argc, argv, ¶ms, "d:f:l:B:L:O:T:" CDK_MIN_PARAMS);
|
||||
|
||||
/* *INDENT-EQLS* */
|
||||
xpos = CDKparamValue (¶ms, 'X', CENTER);
|
||||
ypos = CDKparamValue (¶ms, 'Y', CENTER);
|
||||
boxWidget = CDKparamValue (¶ms, 'N', TRUE);
|
||||
shadowWidget = CDKparamValue (¶ms, 'S', FALSE);
|
||||
defaultItem = CDKparamValue (¶ms, 'd', 0);
|
||||
filename = CDKparamString (¶ms, 'f');
|
||||
list = CDKparamString (¶ms, 'l');
|
||||
buttons = CDKparamString (¶ms, 'B');
|
||||
label = CDKparamString (¶ms, 'L');
|
||||
outputFile = CDKparamString (¶ms, 'O');
|
||||
title = CDKparamString (¶ms, 'T');
|
||||
|
||||
/* If the user asked for an output file, try to open it. */
|
||||
if (outputFile != 0)
|
||||
{
|
||||
if ((fp = fopen (outputFile, "w")) == 0)
|
||||
{
|
||||
fprintf (stderr, "%s: Can not open output file %s\n", argv[0], outputFile);
|
||||
ExitProgram (CLI_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
/* Did they provide a list of items. */
|
||||
if (list == 0)
|
||||
{
|
||||
/* Maybe they gave a filename to use to read. */
|
||||
if (filename != 0)
|
||||
{
|
||||
/* Read the file in. */
|
||||
itemlistLines = CDKreadFile (filename, &itemlistList);
|
||||
|
||||
/* Check if there was an error. */
|
||||
if (itemlistLines == -1)
|
||||
{
|
||||
fprintf (stderr, "Error: Could not open the file '%s'.\n", filename);
|
||||
ExitProgram (CLI_ERROR);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* They didn't provide anything. */
|
||||
fprintf (stderr, "Usage: %s %s\n", argv[0], FPUsage);
|
||||
ExitProgram (CLI_ERROR);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Split the itemlist lines up. */
|
||||
itemlistList = CDKsplitString (list, '\n');
|
||||
itemlistLines = (int)CDKcountStrings ((CDK_CSTRING2) itemlistList);
|
||||
}
|
||||
|
||||
cdkScreen = initCDKScreen (NULL);
|
||||
|
||||
/* Start color. */
|
||||
initCDKColor ();
|
||||
|
||||
/* Check if the user wants to set the background of the main screen. */
|
||||
if ((temp = getenv ("CDK_SCREEN_COLOR")) != 0)
|
||||
{
|
||||
holder = char2Chtype (temp, &j1, &j2);
|
||||
wbkgd (cdkScreen->window, holder[0]);
|
||||
wrefresh (cdkScreen->window);
|
||||
freeChtype (holder);
|
||||
}
|
||||
|
||||
/* Get the widget color background color. */
|
||||
if ((CDK_WIDGET_COLOR = getenv ("CDK_WIDGET_COLOR")) == 0)
|
||||
{
|
||||
CDK_WIDGET_COLOR = 0;
|
||||
}
|
||||
|
||||
/* Create the item list. */
|
||||
widget = newCDKItemlist (cdkScreen, xpos, ypos,
|
||||
title, label,
|
||||
(CDK_CSTRING2) itemlistList, itemlistLines,
|
||||
defaultItem,
|
||||
boxWidget, shadowWidget);
|
||||
|
||||
/* Make sure we could create the widget. */
|
||||
if (widget == 0)
|
||||
{
|
||||
CDKfreeStrings (itemlistList);
|
||||
|
||||
destroyCDKScreen (cdkScreen);
|
||||
endCDK ();
|
||||
|
||||
fprintf (stderr,
|
||||
"Error: Could not create the item list. "
|
||||
"Is the window too small?\n");
|
||||
|
||||
ExitProgram (CLI_ERROR);
|
||||
}
|
||||
|
||||
/* Split the buttons if they supplied some. */
|
||||
if (buttons != 0)
|
||||
{
|
||||
buttonList = CDKsplitString (buttons, '\n');
|
||||
buttonCount = (int)CDKcountStrings ((CDK_CSTRING2) buttonList);
|
||||
|
||||
/* We need to create a buttonbox widget. */
|
||||
buttonWidget = newCDKButtonbox (cdkScreen,
|
||||
getbegx (widget->win),
|
||||
(getbegy (widget->win)
|
||||
+ widget->boxHeight - 1),
|
||||
1, widget->boxWidth - 1,
|
||||
0, 1, buttonCount,
|
||||
(CDK_CSTRING2) buttonList, buttonCount,
|
||||
A_REVERSE, boxWidget, FALSE);
|
||||
CDKfreeStrings (buttonList);
|
||||
|
||||
setCDKButtonboxULChar (buttonWidget, ACS_LTEE);
|
||||
setCDKButtonboxURChar (buttonWidget, ACS_RTEE);
|
||||
|
||||
/*
|
||||
* We need to set the lower left and right
|
||||
* characters of the widget.
|
||||
*/
|
||||
setCDKItemlistLLChar (widget, ACS_LTEE);
|
||||
setCDKItemlistLRChar (widget, ACS_RTEE);
|
||||
|
||||
/*
|
||||
* Bind the Tab key in the widget to send a
|
||||
* Tab key to the button box widget.
|
||||
*/
|
||||
bindCDKObject (vITEMLIST, widget, KEY_TAB, widgetCB, buttonWidget);
|
||||
bindCDKObject (vITEMLIST, widget, CDK_NEXT, widgetCB, buttonWidget);
|
||||
bindCDKObject (vITEMLIST, widget, CDK_PREV, widgetCB, buttonWidget);
|
||||
|
||||
/* Check if the user wants to set the background of the widget. */
|
||||
setCDKButtonboxBackgroundColor (buttonWidget, CDK_WIDGET_COLOR);
|
||||
|
||||
/* Draw the button widget. */
|
||||
drawCDKButtonbox (buttonWidget, boxWidget);
|
||||
}
|
||||
|
||||
/*
|
||||
* If the user asked for a shadow, we need to create one. Do this instead
|
||||
* of using the shadow parameter because the button widget is not part of
|
||||
* the main widget and if the user asks for both buttons and a shadow, we
|
||||
* need to create a shadow big enough for both widgets. Create the shadow
|
||||
* window using the widgets shadowWin element, so screen refreshes will draw
|
||||
* them as well.
|
||||
*/
|
||||
if (shadowWidget == TRUE)
|
||||
{
|
||||
/* Determine the height of the shadow window. */
|
||||
shadowHeight = (buttonWidget == 0 ?
|
||||
widget->boxHeight :
|
||||
widget->boxHeight + buttonWidget->boxHeight - 1);
|
||||
|
||||
/* Create the shadow window. */
|
||||
widget->shadowWin = newwin (shadowHeight,
|
||||
widget->boxWidth,
|
||||
getbegy (widget->win) + 1,
|
||||
getbegx (widget->win) + 1);
|
||||
|
||||
/* Make sure we could have created the shadow window. */
|
||||
if (widget->shadowWin != 0)
|
||||
{
|
||||
widget->shadow = TRUE;
|
||||
|
||||
/*
|
||||
* We force the widget and buttonWidget to be drawn so the
|
||||
* buttonbox widget will be drawn when the widget is activated.
|
||||
* Otherwise the shadow window will draw over the button widget.
|
||||
*/
|
||||
drawCDKItemlist (widget, ObjOf (widget)->box);
|
||||
eraseCDKButtonbox (buttonWidget);
|
||||
drawCDKButtonbox (buttonWidget, ObjOf (buttonWidget)->box);
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if the user wants to set the background of the widget. */
|
||||
setCDKItemlistBackgroundColor (widget, CDK_WIDGET_COLOR);
|
||||
|
||||
/* Activate the item list. */
|
||||
ret = activateCDKItemlist (widget, 0);
|
||||
|
||||
/* If there were buttons, get the button selected. */
|
||||
if (buttonWidget != 0)
|
||||
{
|
||||
selection = buttonWidget->currentButton;
|
||||
destroyCDKButtonbox (buttonWidget);
|
||||
}
|
||||
|
||||
destroyCDKItemlist (widget);
|
||||
destroyCDKScreen (cdkScreen);
|
||||
endCDK ();
|
||||
|
||||
/* Print out the answer. */
|
||||
if (ret >= 0)
|
||||
{
|
||||
holder = char2Chtype (itemlistList[ret], &j1, &j2);
|
||||
answer = chtype2Char (holder);
|
||||
fprintf (fp, "%s\n", answer);
|
||||
freeChar (answer);
|
||||
freeChtype (holder);
|
||||
}
|
||||
CDKfreeStrings (itemlistList);
|
||||
fclose (fp);
|
||||
|
||||
/* Exit with the answer. */
|
||||
ExitProgram (selection);
|
||||
}
|
||||
|
||||
static int widgetCB (EObjectType cdktype GCC_UNUSED,
|
||||
void *object GCC_UNUSED,
|
||||
void *clientData,
|
||||
chtype key)
|
||||
{
|
||||
CDKBUTTONBOX *buttonbox = (CDKBUTTONBOX *)clientData;
|
||||
(void) injectCDKButtonbox (buttonbox, key);
|
||||
return (TRUE);
|
||||
}
|
|
@ -1,164 +0,0 @@
|
|||
/* $Id: cdklabel.c,v 1.15 2016/12/04 15:22:16 tom Exp $ */
|
||||
|
||||
#include <cdk_test.h>
|
||||
|
||||
#ifdef XCURSES
|
||||
char *XCursesProgramName = "cdklabel";
|
||||
#endif
|
||||
|
||||
#if !defined (HAVE_SLEEP) && defined (_WIN32) /* Mingw */
|
||||
#define sleep(x) _sleep(x*1000)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Declare file local variables.
|
||||
*/
|
||||
static const char *FPUsage = "-m Message String | -f filename [-c Command] [-p Pause Character] [-s Sleep] [-X X Position] [-Y Y Position] [-N] [-S]";
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
int main (int argc, char **argv)
|
||||
{
|
||||
/* *INDENT-EQLS* */
|
||||
CDKSCREEN *cdkScreen = 0;
|
||||
CDKLABEL *widget = 0;
|
||||
char *CDK_WIDGET_COLOR = 0;
|
||||
char *temp = 0;
|
||||
chtype *holder = 0;
|
||||
int messageLines = -1;
|
||||
char **messageList = 0;
|
||||
char tempCommand[1000];
|
||||
int j1, j2;
|
||||
|
||||
CDK_PARAMS params;
|
||||
boolean boxWidget;
|
||||
boolean shadowWidget;
|
||||
char *command;
|
||||
char *filename;
|
||||
char *message;
|
||||
char waitChar = 0;
|
||||
int sleepLength;
|
||||
int xpos;
|
||||
int ypos;
|
||||
|
||||
CDKparseParams (argc, argv, ¶ms, "c:f:m:p:s:" CDK_MIN_PARAMS);
|
||||
|
||||
/* *INDENT-EQLS* */
|
||||
xpos = CDKparamValue (¶ms, 'X', CENTER);
|
||||
ypos = CDKparamValue (¶ms, 'Y', CENTER);
|
||||
boxWidget = CDKparamValue (¶ms, 'N', TRUE);
|
||||
shadowWidget = CDKparamValue (¶ms, 'S', FALSE);
|
||||
sleepLength = CDKparamValue (¶ms, 's', 0);
|
||||
command = CDKparamString (¶ms, 'c');
|
||||
filename = CDKparamString (¶ms, 'f');
|
||||
message = CDKparamString (¶ms, 'm');
|
||||
|
||||
if ((temp = CDKparamString (¶ms, 'p')) != 0)
|
||||
waitChar = *temp;
|
||||
|
||||
/* Make sure we have a message to display. */
|
||||
if (message == 0)
|
||||
{
|
||||
/* No message, maybe they provided a file to read. */
|
||||
if (filename != 0)
|
||||
{
|
||||
/* Read the file in. */
|
||||
messageLines = CDKreadFile (filename, &messageList);
|
||||
|
||||
/* Check if there was an error. */
|
||||
if (messageLines == -1)
|
||||
{
|
||||
fprintf (stderr, "Error: Could not open the file %s\n", filename);
|
||||
ExitProgram (CLI_ERROR);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* No message, no file, it's an error. */
|
||||
fprintf (stderr, "Usage: %s %s\n", argv[0], FPUsage);
|
||||
ExitProgram (CLI_ERROR);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Split the message up. */
|
||||
messageList = CDKsplitString (message, '\n');
|
||||
messageLines = (int)CDKcountStrings ((CDK_CSTRING2) messageList);
|
||||
}
|
||||
|
||||
cdkScreen = initCDKScreen (NULL);
|
||||
|
||||
/* Start color. */
|
||||
initCDKColor ();
|
||||
|
||||
/* Check if the user wants to set the background of the main screen. */
|
||||
if ((temp = getenv ("CDK_SCREEN_COLOR")) != 0)
|
||||
{
|
||||
holder = char2Chtype (temp, &j1, &j2);
|
||||
wbkgd (cdkScreen->window, holder[0]);
|
||||
wrefresh (cdkScreen->window);
|
||||
freeChtype (holder);
|
||||
}
|
||||
|
||||
/* Get the widget color background color. */
|
||||
if ((CDK_WIDGET_COLOR = getenv ("CDK_WIDGET_COLOR")) == 0)
|
||||
{
|
||||
CDK_WIDGET_COLOR = 0;
|
||||
}
|
||||
|
||||
/* Create the label widget. */
|
||||
widget = newCDKLabel (cdkScreen, xpos, ypos,
|
||||
(CDK_CSTRING2) messageList, messageLines,
|
||||
boxWidget, shadowWidget);
|
||||
|
||||
/* Make sure we could create the widget. */
|
||||
if (widget == 0)
|
||||
{
|
||||
CDKfreeStrings (messageList);
|
||||
|
||||
destroyCDKScreen (cdkScreen);
|
||||
endCDK ();
|
||||
|
||||
fprintf (stderr,
|
||||
"Error: Could not create the label. "
|
||||
"Is the window too small?\n");
|
||||
|
||||
ExitProgram (CLI_ERROR);
|
||||
}
|
||||
|
||||
/* Check if the user wants to set the background of the widget. */
|
||||
setCDKLabelBackgroundColor (widget, CDK_WIDGET_COLOR);
|
||||
|
||||
/* Draw the widget. */
|
||||
drawCDKLabel (widget, boxWidget);
|
||||
|
||||
/* If they supplied a command, run it. */
|
||||
if (command != 0)
|
||||
{
|
||||
const char *fmt = "(sh -c %.*s) >/dev/null 2>&1";
|
||||
sprintf (tempCommand, fmt, (int)(sizeof (tempCommand) - strlen (fmt)), command);
|
||||
system (tempCommand);
|
||||
}
|
||||
|
||||
/* If they supplied a wait character, wait for the user to hit it. */
|
||||
if (waitChar != 0)
|
||||
{
|
||||
waitCDKLabel (widget, waitChar);
|
||||
}
|
||||
|
||||
/* If they supplied a sleep time, sleep for the given length. */
|
||||
if (sleepLength > 0)
|
||||
{
|
||||
sleep ((unsigned)sleepLength);
|
||||
}
|
||||
|
||||
CDKfreeStrings (messageList);
|
||||
|
||||
destroyCDKLabel (widget);
|
||||
destroyCDKScreen (cdkScreen);
|
||||
endCDK ();
|
||||
|
||||
/* Exit cleanly. */
|
||||
ExitProgram (0);
|
||||
}
|
|
@ -1,386 +0,0 @@
|
|||
/* $Id: cdkmatrix.c,v 1.19 2016/12/04 15:22:16 tom Exp $ */
|
||||
|
||||
#include <cdk_test.h>
|
||||
|
||||
#ifdef XCURSES
|
||||
char *XCursesProgramName = "cdkmatrix";
|
||||
#endif
|
||||
|
||||
#define MY_INFO(x,y) info[(x + 1) * cols + (y + 1)]
|
||||
|
||||
/*
|
||||
* Declare file local prototypes.
|
||||
*/
|
||||
static int widgetCB (EObjectType cdktype, void *object, void *clientData, chtype key);
|
||||
|
||||
/*
|
||||
* Define file local variables.
|
||||
*/
|
||||
static const char *FPUsage = "-r Row Titles -c Column Titles -v Visible Rows -w Column Widths [-t Column Types] [-d Default Values] [-F Field Character] [-T Title] [-B Buttons] [-O Output File] [-X X Position] [-Y Y Position] [-N] [-S]";
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
int main (int argc, char **argv)
|
||||
{
|
||||
/* *INDENT-EQLS* */
|
||||
CDKSCREEN *cdkScreen = 0;
|
||||
CDKMATRIX *widget = 0;
|
||||
CDKBUTTONBOX *buttonWidget = 0;
|
||||
chtype *holder = 0;
|
||||
char *buttons = 0;
|
||||
char *CDK_WIDGET_COLOR = 0;
|
||||
char *temp = 0;
|
||||
chtype filler = A_NORMAL | '.';
|
||||
int rows = -1;
|
||||
int cols = -1;
|
||||
int buttonCount = 0;
|
||||
int selection = 0;
|
||||
int shadowHeight = 0;
|
||||
FILE *fp = stderr;
|
||||
char **rowTitles;
|
||||
char **colTitles;
|
||||
char **rowTemp = 0;
|
||||
char **colTemp = 0;
|
||||
char **kolTemp = 0;
|
||||
char **buttonList = 0;
|
||||
int *colWidths;
|
||||
int *colTypes;
|
||||
int count, infoLines, x, y, j1, j2;
|
||||
|
||||
CDK_PARAMS params;
|
||||
boolean boxWidget;
|
||||
boolean shadowWidget;
|
||||
char *defaultValue;
|
||||
char *myColTitles;
|
||||
char *myColTypes;
|
||||
char *myColWidths;
|
||||
char *myFiller;
|
||||
char *myRowTitles;
|
||||
char *outputFile;
|
||||
char *title;
|
||||
int vrows;
|
||||
int xpos;
|
||||
int ypos;
|
||||
|
||||
CDKparseParams (argc, argv, ¶ms, "c:d:r:t:w:v:B:F:O:T:" CDK_MIN_PARAMS);
|
||||
|
||||
/* *INDENT-EQLS* */
|
||||
xpos = CDKparamValue (¶ms, 'X', CENTER);
|
||||
ypos = CDKparamValue (¶ms, 'Y', CENTER);
|
||||
boxWidget = CDKparamValue (¶ms, 'N', TRUE);
|
||||
shadowWidget = CDKparamValue (¶ms, 'S', FALSE);
|
||||
vrows = CDKparamValue (¶ms, 'v', -1);
|
||||
myColTitles = CDKparamString (¶ms, 'c');
|
||||
defaultValue = CDKparamString (¶ms, 'd');
|
||||
myRowTitles = CDKparamString (¶ms, 'r');
|
||||
myColTypes = CDKparamString (¶ms, 't');
|
||||
myColWidths = CDKparamString (¶ms, 'w');
|
||||
buttons = CDKparamString (¶ms, 'B');
|
||||
myFiller = CDKparamString (¶ms, 'F');
|
||||
outputFile = CDKparamString (¶ms, 'O');
|
||||
title = CDKparamString (¶ms, 'T');
|
||||
|
||||
/* If the user asked for an output file, try to open it. */
|
||||
if (outputFile != 0)
|
||||
{
|
||||
if ((fp = fopen (outputFile, "w")) == 0)
|
||||
{
|
||||
fprintf (stderr, "%s: Can not open output file %s\n", argv[0], outputFile);
|
||||
ExitProgram (CLI_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
/* Make sure all the needed command line parameters were provided. */
|
||||
if ((myRowTitles == 0) ||
|
||||
(myColTitles == 0) ||
|
||||
(myColWidths == 0) ||
|
||||
(vrows == -1))
|
||||
{
|
||||
fprintf (stderr, "Usage: %s %s\n", argv[0], FPUsage);
|
||||
ExitProgram (CLI_ERROR);
|
||||
}
|
||||
|
||||
/* Convert the char * titles to a char **, offset by one */
|
||||
rowTemp = CDKsplitString (myRowTitles, '\n');
|
||||
rows = (int)CDKcountStrings ((CDK_CSTRING2)rowTemp);
|
||||
rowTitles = (char **)calloc ((size_t) rows + 1, sizeof (char *));
|
||||
for (x = 0; x < rows; x++)
|
||||
{
|
||||
rowTitles[x + 1] = rowTemp[x];
|
||||
}
|
||||
|
||||
colTemp = CDKsplitString (myColTitles, '\n');
|
||||
cols = (int)CDKcountStrings ((CDK_CSTRING2)colTemp);
|
||||
colTitles = (char **)calloc ((size_t) cols + 1, sizeof (char *));
|
||||
for (x = 0; x < cols; x++)
|
||||
{
|
||||
colTitles[x + 1] = colTemp[x];
|
||||
}
|
||||
|
||||
/* Convert the column widths. */
|
||||
kolTemp = CDKsplitString (myColWidths, '\n');
|
||||
count = (int)CDKcountStrings ((CDK_CSTRING2)kolTemp);
|
||||
colWidths = (int *)calloc ((size_t) count + 1, sizeof (int));
|
||||
for (x = 0; x < count; x++)
|
||||
{
|
||||
colWidths[x + 1] = atoi (kolTemp[x]);
|
||||
}
|
||||
|
||||
/* If they passed in the column types, convert them. */
|
||||
if (myColTypes != 0)
|
||||
{
|
||||
char **ss = CDKsplitString (myColTypes, '\n');
|
||||
count = (int)CDKcountStrings ((CDK_CSTRING2)ss);
|
||||
colTypes = (int *)calloc ((size_t) MAXIMUM (cols, count) + 1, sizeof (int));
|
||||
for (x = 0; x < count; x++)
|
||||
{
|
||||
colTypes[x + 1] = char2DisplayType (ss[x]);
|
||||
}
|
||||
CDKfreeStrings (ss);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* If they didn't set default values. */
|
||||
colTypes = (int *)calloc ((size_t) cols + 1, sizeof (int));
|
||||
for (x = 0; x < cols; x++)
|
||||
{
|
||||
colTypes[x + 1] = vMIXED;
|
||||
}
|
||||
}
|
||||
|
||||
cdkScreen = initCDKScreen (NULL);
|
||||
|
||||
/* Start color. */
|
||||
initCDKColor ();
|
||||
|
||||
/* Check if the user wants to set the background of the main screen. */
|
||||
if ((temp = getenv ("CDK_SCREEN_COLOR")) != 0)
|
||||
{
|
||||
holder = char2Chtype (temp, &j1, &j2);
|
||||
wbkgd (cdkScreen->window, holder[0]);
|
||||
wrefresh (cdkScreen->window);
|
||||
freeChtype (holder);
|
||||
}
|
||||
|
||||
/* Get the widget color background color. */
|
||||
if ((CDK_WIDGET_COLOR = getenv ("CDK_WIDGET_COLOR")) == 0)
|
||||
{
|
||||
CDK_WIDGET_COLOR = 0;
|
||||
}
|
||||
|
||||
/* If the set the filler character, set it now. */
|
||||
if (myFiller != 0)
|
||||
{
|
||||
holder = char2Chtype (myFiller, &j1, &j2);
|
||||
filler = holder[0];
|
||||
freeChtype (holder);
|
||||
}
|
||||
|
||||
/* Create the matrix widget. */
|
||||
widget = newCDKMatrix (cdkScreen, xpos, ypos,
|
||||
rows, cols, vrows, cols,
|
||||
title, (CDK_CSTRING2)rowTitles, (CDK_CSTRING2)colTitles,
|
||||
colWidths, colTypes, 1, 1,
|
||||
filler, COL,
|
||||
boxWidget, TRUE, shadowWidget);
|
||||
free (rowTitles);
|
||||
free (colTitles);
|
||||
|
||||
/* Make sure we could create the widget. */
|
||||
if (widget == 0)
|
||||
{
|
||||
/* Shut down curses and CDK. */
|
||||
destroyCDKScreen (cdkScreen);
|
||||
endCDK ();
|
||||
|
||||
fprintf (stderr,
|
||||
"Error: Cannot create the matrix. "
|
||||
"Is the window too small?\n");
|
||||
|
||||
ExitProgram (CLI_ERROR);
|
||||
}
|
||||
|
||||
/*
|
||||
* If the user sent in a file of default values, read it and
|
||||
* stick the values read in from the file into the matrix.
|
||||
*/
|
||||
if (defaultValue != 0)
|
||||
{
|
||||
size_t limit = (size_t) ((rows + 1) * (cols + 1));
|
||||
char **info = (char **)calloc (limit, sizeof (char *));
|
||||
char **lineTemp = 0;
|
||||
|
||||
/* Read the file. */
|
||||
infoLines = CDKreadFile (defaultValue, &lineTemp);
|
||||
if (infoLines > 0)
|
||||
{
|
||||
int *subSize = (int *)calloc ((size_t) infoLines + 1, sizeof (int));
|
||||
|
||||
/* For each line, split on a CTRL-V. */
|
||||
for (x = 0; x < infoLines; x++)
|
||||
{
|
||||
char **ss = CDKsplitString (lineTemp[x], CTRL ('V'));
|
||||
subSize[x + 1] = (int)CDKcountStrings ((CDK_CSTRING2)ss);
|
||||
for (y = 0; y < subSize[x + 1]; y++)
|
||||
{
|
||||
MY_INFO (x, y) = ss[y];
|
||||
}
|
||||
free (ss);
|
||||
}
|
||||
CDKfreeStrings (lineTemp);
|
||||
|
||||
setCDKMatrixCells (widget, (CDK_CSTRING2)info, rows, cols, subSize);
|
||||
|
||||
for (x = 0; x < infoLines; x++)
|
||||
{
|
||||
for (y = 0; y < subSize[x + 1]; y++)
|
||||
{
|
||||
freeChar (MY_INFO (x, y));
|
||||
}
|
||||
}
|
||||
free (info);
|
||||
free (subSize);
|
||||
}
|
||||
}
|
||||
|
||||
/* Split the buttons if they supplied some. */
|
||||
if (buttons != 0)
|
||||
{
|
||||
/* Split the button list up. */
|
||||
buttonList = CDKsplitString (buttons, '\n');
|
||||
buttonCount = (int)CDKcountStrings ((CDK_CSTRING2)buttonList);
|
||||
|
||||
/* We need to create a buttonbox widget. */
|
||||
buttonWidget = newCDKButtonbox (cdkScreen,
|
||||
getbegx (widget->win),
|
||||
(getbegy (widget->win)
|
||||
+ widget->boxHeight - 1),
|
||||
1, widget->boxWidth - 1,
|
||||
NULL, 1, buttonCount,
|
||||
(CDK_CSTRING2)buttonList, buttonCount,
|
||||
A_REVERSE, boxWidget, FALSE);
|
||||
|
||||
setCDKButtonboxULChar (buttonWidget, ACS_LTEE);
|
||||
setCDKButtonboxURChar (buttonWidget, ACS_RTEE);
|
||||
|
||||
/*
|
||||
* We need to set the lower left and right
|
||||
* characters of the widget.
|
||||
*/
|
||||
setCDKMatrixLLChar (widget, ACS_LTEE);
|
||||
setCDKMatrixLRChar (widget, ACS_RTEE);
|
||||
|
||||
/*
|
||||
* Bind the Tab key in the widget to send a
|
||||
* Tab key to the button box widget.
|
||||
*/
|
||||
bindCDKObject (vMATRIX, widget, KEY_TAB, widgetCB, buttonWidget);
|
||||
bindCDKObject (vMATRIX, widget, CDK_NEXT, widgetCB, buttonWidget);
|
||||
bindCDKObject (vMATRIX, widget, CDK_PREV, widgetCB, buttonWidget);
|
||||
|
||||
/* Check if the user wants to set the background of the widget. */
|
||||
setCDKButtonboxBackgroundColor (buttonWidget, CDK_WIDGET_COLOR);
|
||||
|
||||
/* Draw the button widget. */
|
||||
drawCDKButtonbox (buttonWidget, boxWidget);
|
||||
}
|
||||
|
||||
/*
|
||||
* If the user asked for a shadow, we need to create one. Do this instead
|
||||
* of using the shadow parameter because the button widget is not part of
|
||||
* the main widget and if the user asks for both buttons and a shadow, we
|
||||
* need to create a shadow big enough for both widgets. Create the shadow
|
||||
* window using the widgets shadowWin element, so screen refreshes will draw
|
||||
* them as well.
|
||||
*/
|
||||
if (shadowWidget == TRUE)
|
||||
{
|
||||
/* Determine the height of the shadow window. */
|
||||
shadowHeight = (buttonWidget == (CDKBUTTONBOX *)NULL ?
|
||||
widget->boxHeight :
|
||||
widget->boxHeight + buttonWidget->boxHeight - 1);
|
||||
|
||||
/* Create the shadow window. */
|
||||
widget->shadowWin = newwin (shadowHeight,
|
||||
widget->boxWidth,
|
||||
getbegy (widget->win) + 1,
|
||||
getbegx (widget->win) + 1);
|
||||
|
||||
/* Make sure we could have created the shadow window. */
|
||||
if (widget->shadowWin != 0)
|
||||
{
|
||||
widget->shadow = TRUE;
|
||||
|
||||
/*
|
||||
* We force the widget and buttonWidget to be drawn so the
|
||||
* buttonbox widget will be drawn when the widget is activated.
|
||||
* Otherwise the shadow window will draw over the button widget.
|
||||
*/
|
||||
drawCDKMatrix (widget, ObjOf (widget)->box);
|
||||
eraseCDKButtonbox (buttonWidget);
|
||||
drawCDKButtonbox (buttonWidget, ObjOf (buttonWidget)->box);
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if the user wants to set the background of the widget. */
|
||||
setCDKMatrixBackgroundColor (widget, CDK_WIDGET_COLOR);
|
||||
|
||||
/* Let them play. */
|
||||
activateCDKMatrix (widget, 0);
|
||||
|
||||
/* Print out the matrix cells. */
|
||||
if (widget->exitType == vNORMAL)
|
||||
{
|
||||
for (x = 0; x < widget->rows; x++)
|
||||
{
|
||||
for (y = 0; y < widget->cols; y++)
|
||||
{
|
||||
char *data = getCDKMatrixCell (widget, x, y);
|
||||
if (data != 0)
|
||||
{
|
||||
fprintf (fp, "%s%c", data, CTRL ('V'));
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf (fp, "%c", CTRL ('V'));
|
||||
}
|
||||
}
|
||||
fprintf (fp, "\n");
|
||||
}
|
||||
}
|
||||
|
||||
/* If there were buttons, get the button selected. */
|
||||
if (buttonWidget != 0)
|
||||
{
|
||||
selection = buttonWidget->currentButton;
|
||||
destroyCDKButtonbox (buttonWidget);
|
||||
}
|
||||
|
||||
/* cleanup (not really needed) */
|
||||
CDKfreeStrings (buttonList);
|
||||
free (colTypes);
|
||||
free (colWidths);
|
||||
|
||||
CDKfreeStrings (rowTemp);
|
||||
CDKfreeStrings (colTemp);
|
||||
CDKfreeStrings (kolTemp);
|
||||
|
||||
destroyCDKMatrix (widget);
|
||||
destroyCDKScreen (cdkScreen);
|
||||
endCDK ();
|
||||
|
||||
/* do this late, in case it was stderr */
|
||||
fclose (fp);
|
||||
|
||||
ExitProgram (selection);
|
||||
}
|
||||
|
||||
static int widgetCB (EObjectType cdktype GCC_UNUSED, void *object GCC_UNUSED,
|
||||
void *clientData,
|
||||
chtype key)
|
||||
{
|
||||
CDKBUTTONBOX *buttonbox = (CDKBUTTONBOX *)clientData;
|
||||
(void)injectCDKButtonbox (buttonbox, key);
|
||||
return (TRUE);
|
||||
}
|
|
@ -1,270 +0,0 @@
|
|||
/* $Id: cdkmentry.c,v 1.14 2016/12/04 15:22:16 tom Exp $ */
|
||||
|
||||
#include <cdk_test.h>
|
||||
|
||||
#ifdef XCURSES
|
||||
char *XCursesProgramName = "cdkmentry";
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Declare file local prototypes.
|
||||
*/
|
||||
static int widgetCB (EObjectType cdktype, void *object, void *clientData, chtype key);
|
||||
|
||||
/*
|
||||
* Define file local variables.
|
||||
*/
|
||||
static const char *FPUsage = "-f Field Width -s Screen Rows -v Virtual Rows [-d Display Type] [-F Field Character] [-i Initial Value] [-m Minimum Length] [-T Title] [-L Label] [-B Buttons] [-O Output file] [-X X Position] [-Y Y Position] [-N] [-S]";
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
int main (int argc, char **argv)
|
||||
{
|
||||
/* *INDENT-EQLS* */
|
||||
CDKSCREEN *cdkScreen = 0;
|
||||
CDKMENTRY *widget = 0;
|
||||
CDKBUTTONBOX *buttonWidget = 0;
|
||||
chtype *holder = 0;
|
||||
chtype fieldAttr = 0;
|
||||
char *answer = 0;
|
||||
char *CDK_WIDGET_COLOR = 0;
|
||||
char *temp = 0;
|
||||
char filler = '.';
|
||||
EDisplayType dType = vMIXED;
|
||||
int buttonCount = 0;
|
||||
int selection = 0;
|
||||
int shadowHeight = 0;
|
||||
FILE *fp = stderr;
|
||||
char **buttonList = 0;
|
||||
int j1, j2;
|
||||
|
||||
CDK_PARAMS params;
|
||||
boolean boxWidget;
|
||||
boolean shadowWidget;
|
||||
char *buttons;
|
||||
char *initValue;
|
||||
char *label;
|
||||
char *outputFile;
|
||||
char *tempFiller;
|
||||
char *title;
|
||||
int fieldWidth;
|
||||
int min;
|
||||
int screenRows;
|
||||
int virtualRows;
|
||||
int xpos;
|
||||
int ypos;
|
||||
|
||||
CDKparseParams (argc, argv, ¶ms, "d:f:i:m:s:v:B:F:L:O:T:" CDK_MIN_PARAMS);
|
||||
|
||||
/* *INDENT-EQLS* */
|
||||
xpos = CDKparamValue (¶ms, 'X', CENTER);
|
||||
ypos = CDKparamValue (¶ms, 'Y', CENTER);
|
||||
boxWidget = CDKparamValue (¶ms, 'N', TRUE);
|
||||
shadowWidget = CDKparamValue (¶ms, 'S', FALSE);
|
||||
fieldWidth = CDKparamValue (¶ms, 'f', 0);
|
||||
min = CDKparamValue (¶ms, 'm', 0);
|
||||
screenRows = CDKparamValue (¶ms, 's', 0);
|
||||
virtualRows = CDKparamValue (¶ms, 'v', 0);
|
||||
initValue = CDKparamString (¶ms, 'i');
|
||||
buttons = CDKparamString (¶ms, 'B');
|
||||
tempFiller = CDKparamString (¶ms, 'F');
|
||||
label = CDKparamString (¶ms, 'L');
|
||||
outputFile = CDKparamString (¶ms, 'O');
|
||||
title = CDKparamString (¶ms, 'T');
|
||||
|
||||
if ((temp = CDKparamString (¶ms, 'd')) != 0)
|
||||
dType = char2DisplayType (temp);
|
||||
|
||||
/* Make sure all the command line parameters were provided. */
|
||||
if ((fieldWidth <= 0) || (screenRows <= 0) || (virtualRows <= 0))
|
||||
{
|
||||
fprintf (stderr, "Usage: %s %s\n", argv[0], FPUsage);
|
||||
ExitProgram (CLI_ERROR);
|
||||
}
|
||||
|
||||
/* If the user asked for an output file, try to open it. */
|
||||
if (outputFile != 0)
|
||||
{
|
||||
if ((fp = fopen (outputFile, "w")) == 0)
|
||||
{
|
||||
fprintf (stderr, "%s: Can not open output file %s\n", argv[0], outputFile);
|
||||
ExitProgram (CLI_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
cdkScreen = initCDKScreen (NULL);
|
||||
|
||||
/* Start color. */
|
||||
initCDKColor ();
|
||||
|
||||
/* Check if the user wants to set the background of the main screen. */
|
||||
if ((temp = getenv ("CDK_SCREEN_COLOR")) != 0)
|
||||
{
|
||||
holder = char2Chtype (temp, &j1, &j2);
|
||||
wbkgd (cdkScreen->window, holder[0]);
|
||||
wrefresh (cdkScreen->window);
|
||||
freeChtype (holder);
|
||||
}
|
||||
|
||||
/* Get the widget color background color. */
|
||||
if ((CDK_WIDGET_COLOR = getenv ("CDK_WIDGET_COLOR")) == 0)
|
||||
{
|
||||
CDK_WIDGET_COLOR = 0;
|
||||
}
|
||||
|
||||
/* If the set the filler character, set it now. */
|
||||
if (tempFiller != 0)
|
||||
{
|
||||
holder = char2Chtype (tempFiller, &j1, &j2);
|
||||
fieldAttr = A_ATTRIBUTES & holder[0];
|
||||
filler = (char)holder[0];
|
||||
freeChtype (holder);
|
||||
}
|
||||
/* Create the mentry widget. */
|
||||
widget = newCDKMentry (cdkScreen, xpos, ypos,
|
||||
title, label,
|
||||
fieldAttr,
|
||||
(chtype)filler | fieldAttr,
|
||||
dType, fieldWidth,
|
||||
screenRows, virtualRows,
|
||||
min, boxWidget, shadowWidget);
|
||||
|
||||
/* Check to make sure we created the dialog box. */
|
||||
if (widget == 0)
|
||||
{
|
||||
/* Shut down curses and CDK. */
|
||||
destroyCDKScreen (cdkScreen);
|
||||
endCDK ();
|
||||
|
||||
fprintf (stderr,
|
||||
"Error: Could not create the multiple line entry field. "
|
||||
"Is the window too small?\n");
|
||||
|
||||
ExitProgram (CLI_ERROR);
|
||||
}
|
||||
|
||||
/* Split the buttons if they supplied some. */
|
||||
if (buttons != 0)
|
||||
{
|
||||
buttonList = CDKsplitString (buttons, '\n');
|
||||
buttonCount = (int)CDKcountStrings ((CDK_CSTRING2) buttonList);
|
||||
|
||||
/* We need to create a buttonbox widget. */
|
||||
buttonWidget = newCDKButtonbox (cdkScreen,
|
||||
getbegx (widget->win),
|
||||
(getbegy (widget->win)
|
||||
+ widget->boxHeight - 1),
|
||||
1, widget->boxWidth - 1,
|
||||
NULL, 1, buttonCount,
|
||||
(CDK_CSTRING2) buttonList, buttonCount,
|
||||
A_REVERSE, boxWidget, FALSE);
|
||||
CDKfreeStrings (buttonList);
|
||||
|
||||
setCDKButtonboxULChar (buttonWidget, ACS_LTEE);
|
||||
setCDKButtonboxURChar (buttonWidget, ACS_RTEE);
|
||||
|
||||
/*
|
||||
* We need to set the lower left and right
|
||||
* characters of the widget.
|
||||
*/
|
||||
setCDKMentryLLChar (widget, ACS_LTEE);
|
||||
setCDKMentryLRChar (widget, ACS_RTEE);
|
||||
|
||||
/*
|
||||
* Bind the Tab key in the widget to send a
|
||||
* Tab key to the button box widget.
|
||||
*/
|
||||
bindCDKObject (vMENTRY, widget, KEY_TAB, widgetCB, buttonWidget);
|
||||
bindCDKObject (vMENTRY, widget, CDK_NEXT, widgetCB, buttonWidget);
|
||||
bindCDKObject (vMENTRY, widget, CDK_PREV, widgetCB, buttonWidget);
|
||||
|
||||
/* Check if the user wants to set the background of the widget. */
|
||||
setCDKButtonboxBackgroundColor (buttonWidget, CDK_WIDGET_COLOR);
|
||||
|
||||
/* Draw the button widget. */
|
||||
drawCDKButtonbox (buttonWidget, boxWidget);
|
||||
}
|
||||
|
||||
/*
|
||||
* If the user asked for a shadow, we need to create one. Do this instead
|
||||
* of using the shadow parameter because the button widget is not part of
|
||||
* the main widget and if the user asks for both buttons and a shadow, we
|
||||
* need to create a shadow big enough for both widgets. Create the shadow
|
||||
* window using the widgets shadowWin element, so screen refreshes will draw
|
||||
* them as well.
|
||||
*/
|
||||
if (shadowWidget == TRUE)
|
||||
{
|
||||
/* Determine the height of the shadow window. */
|
||||
shadowHeight = (buttonWidget == (CDKBUTTONBOX *)NULL ?
|
||||
widget->boxHeight :
|
||||
widget->boxHeight + buttonWidget->boxHeight - 1);
|
||||
|
||||
/* Create the shadow window. */
|
||||
widget->shadowWin = newwin (shadowHeight,
|
||||
widget->boxWidth,
|
||||
getbegy (widget->win) + 1,
|
||||
getbegx (widget->win) + 1);
|
||||
|
||||
/* Make sure we could have created the shadow window. */
|
||||
if (widget->shadowWin != 0)
|
||||
{
|
||||
widget->shadow = TRUE;
|
||||
|
||||
/*
|
||||
* We force the widget and buttonWidget to be drawn so the
|
||||
* buttonbox widget will be drawn when the widget is activated.
|
||||
* Otherwise the shadow window will draw over the button widget.
|
||||
*/
|
||||
drawCDKMentry (widget, ObjOf (widget)->box);
|
||||
eraseCDKButtonbox (buttonWidget);
|
||||
drawCDKButtonbox (buttonWidget, ObjOf (buttonWidget)->box);
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if the user wants to set the background of the widget. */
|
||||
setCDKMentryBackgroundColor (widget, CDK_WIDGET_COLOR);
|
||||
|
||||
/* If there was an initial value, set it. */
|
||||
if (initValue != 0)
|
||||
{
|
||||
setCDKMentryValue (widget, initValue);
|
||||
}
|
||||
|
||||
/* Activate the widget. */
|
||||
answer = copyChar (activateCDKMentry (widget, 0));
|
||||
|
||||
/* If there were buttons, get the button selected. */
|
||||
if (buttonWidget != 0)
|
||||
{
|
||||
selection = buttonWidget->currentButton;
|
||||
destroyCDKButtonbox (buttonWidget);
|
||||
}
|
||||
|
||||
/* End CDK. */
|
||||
destroyCDKMentry (widget);
|
||||
destroyCDKScreen (cdkScreen);
|
||||
endCDK ();
|
||||
|
||||
/* Print the value from the widget. */
|
||||
if (answer != 0)
|
||||
{
|
||||
fprintf (fp, "%s\n", answer);
|
||||
freeChar (answer);
|
||||
}
|
||||
fclose (fp);
|
||||
|
||||
/* Exit with the button number picked. */
|
||||
ExitProgram (selection);
|
||||
}
|
||||
|
||||
static int widgetCB (EObjectType cdktype GCC_UNUSED,
|
||||
void *object GCC_UNUSED,
|
||||
void *clientData,
|
||||
chtype key)
|
||||
{
|
||||
CDKBUTTONBOX *buttonbox = (CDKBUTTONBOX *)clientData;
|
||||
(void) injectCDKButtonbox (buttonbox, key);
|
||||
return (TRUE);
|
||||
}
|
|
@ -1,293 +0,0 @@
|
|||
/* $Id: cdkradio.c,v 1.13 2016/12/04 15:22:16 tom Exp $ */
|
||||
|
||||
#include <cdk_test.h>
|
||||
|
||||
#ifdef XCURSES
|
||||
char *XCursesProgramName = "cdkradio";
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Declare file local prototypes.
|
||||
*/
|
||||
static int widgetCB (EObjectType cdktype, void *object, void *clientData, chtype key);
|
||||
|
||||
/*
|
||||
* Define file local variables.
|
||||
*/
|
||||
static const char *FPUsage = "-l List | -f filename [-c Choice Character] [-d Default Item] [-s Scroll Bar Position] [-n Numbers] [-i Item Index] [-T Title] [-B Buttons] [-O Output File] [-X X Position] [-Y Y Position] [-H Height] [-W Width] [-N] [-S]";
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
int main (int argc, char **argv)
|
||||
{
|
||||
/* *INDENT-EQLS* */
|
||||
CDKSCREEN *cdkScreen = 0;
|
||||
CDKRADIO *widget = 0;
|
||||
CDKBUTTONBOX *buttonWidget = 0;
|
||||
char *buttons = 0;
|
||||
char *CDK_WIDGET_COLOR = 0;
|
||||
char *temp = 0;
|
||||
chtype *holder = 0;
|
||||
chtype *choiceChar = 0;
|
||||
int answer = 0;
|
||||
int spos = NONE;
|
||||
int scrollLines = -1;
|
||||
int buttonCount = 0;
|
||||
int selection = 0;
|
||||
int shadowHeight = 0;
|
||||
FILE *fp = stderr;
|
||||
char **buttonList = 0;
|
||||
char **scrollList = 0;
|
||||
int j1, j2;
|
||||
|
||||
CDK_PARAMS params;
|
||||
boolean boxWidget;
|
||||
boolean numberOutput;
|
||||
boolean shadowWidget;
|
||||
const char *choice;
|
||||
char *filename;
|
||||
char *list;
|
||||
char *outputFile;
|
||||
char *title;
|
||||
int defaultItem;
|
||||
int height;
|
||||
int width;
|
||||
int xpos;
|
||||
int ypos;
|
||||
|
||||
CDKparseParams (argc, argv, ¶ms, "l:f:s:c:d:iB:O:T:" CDK_CLI_PARAMS);
|
||||
|
||||
/* *INDENT-EQLS* */
|
||||
xpos = CDKparamValue (¶ms, 'X', CENTER);
|
||||
ypos = CDKparamValue (¶ms, 'Y', CENTER);
|
||||
height = CDKparamValue (¶ms, 'H', 10);
|
||||
width = CDKparamValue (¶ms, 'W', 1);
|
||||
boxWidget = CDKparamValue (¶ms, 'N', TRUE);
|
||||
shadowWidget = CDKparamValue (¶ms, 'S', FALSE);
|
||||
defaultItem = CDKparamValue (¶ms, 'd', 0);
|
||||
numberOutput = CDKparamValue (¶ms, 'i', FALSE);
|
||||
filename = CDKparamString (¶ms, 'f');
|
||||
list = CDKparamString (¶ms, 'l');
|
||||
buttons = CDKparamString (¶ms, 'B');
|
||||
outputFile = CDKparamString (¶ms, 'O');
|
||||
title = CDKparamString (¶ms, 'T');
|
||||
|
||||
if ((choice = CDKparamString (¶ms, 'c')) == 0)
|
||||
choice = "</R>X";
|
||||
|
||||
spos = CDKparsePosition (CDKparamString (¶ms, 's'));
|
||||
|
||||
/* If the user asked for an output file, try to open it. */
|
||||
if (outputFile != 0)
|
||||
{
|
||||
if ((fp = fopen (outputFile, "w")) == 0)
|
||||
{
|
||||
fprintf (stderr, "%s: Can not open output file %s\n", argv[0], outputFile);
|
||||
ExitProgram (CLI_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
/* Did they provide a list of items. */
|
||||
if (list == 0)
|
||||
{
|
||||
/* Maybe they gave a filename to use to read. */
|
||||
if (filename != 0)
|
||||
{
|
||||
/* Read the file in. */
|
||||
scrollLines = CDKreadFile (filename, &scrollList);
|
||||
|
||||
/* Check if there was an error. */
|
||||
if (scrollLines == -1)
|
||||
{
|
||||
fprintf (stderr, "Error: Could not open the file '%s'.\n", filename);
|
||||
ExitProgram (CLI_ERROR);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* They didn't provide anything. */
|
||||
fprintf (stderr, "Usage: %s %s\n", argv[0], FPUsage);
|
||||
ExitProgram (CLI_ERROR);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Split the scroll lines up. */
|
||||
scrollList = CDKsplitString (list, '\n');
|
||||
scrollLines = (int)CDKcountStrings ((CDK_CSTRING2) scrollList);
|
||||
}
|
||||
|
||||
cdkScreen = initCDKScreen (NULL);
|
||||
|
||||
/* Start color. */
|
||||
initCDKColor ();
|
||||
|
||||
/* Check if the user wants to set the background of the main screen. */
|
||||
if ((temp = getenv ("CDK_SCREEN_COLOR")) != 0)
|
||||
{
|
||||
holder = char2Chtype (temp, &j1, &j2);
|
||||
wbkgd (cdkScreen->window, holder[0]);
|
||||
wrefresh (cdkScreen->window);
|
||||
freeChtype (holder);
|
||||
}
|
||||
|
||||
/* Get the widget color background color. */
|
||||
if ((CDK_WIDGET_COLOR = getenv ("CDK_WIDGET_COLOR")) == 0)
|
||||
{
|
||||
CDK_WIDGET_COLOR = 0;
|
||||
}
|
||||
|
||||
/* Convert the char * choiceChar to a chtype * */
|
||||
choiceChar = char2Chtype (choice, &j1, &j2);
|
||||
|
||||
/* Create the scrolling list. */
|
||||
widget = newCDKRadio (cdkScreen, xpos, ypos, spos,
|
||||
height, width, title,
|
||||
(CDK_CSTRING2) scrollList, scrollLines,
|
||||
choiceChar[0], defaultItem,
|
||||
A_REVERSE,
|
||||
boxWidget, shadowWidget);
|
||||
free (choiceChar);
|
||||
|
||||
/* Make sure we could create the widget. */
|
||||
if (widget == 0)
|
||||
{
|
||||
CDKfreeStrings (scrollList);
|
||||
|
||||
destroyCDKScreen (cdkScreen);
|
||||
endCDK ();
|
||||
|
||||
fprintf (stderr,
|
||||
"Error: Could not create the radio list. "
|
||||
"Is the window too small?\n");
|
||||
|
||||
ExitProgram (CLI_ERROR);
|
||||
}
|
||||
|
||||
/* Split the buttons if they supplied some. */
|
||||
if (buttons != 0)
|
||||
{
|
||||
/* Split the button list up. */
|
||||
buttonList = CDKsplitString (buttons, '\n');
|
||||
buttonCount = (int)CDKcountStrings ((CDK_CSTRING2) buttonList);
|
||||
|
||||
/* We need to create a buttonbox widget. */
|
||||
buttonWidget = newCDKButtonbox (cdkScreen,
|
||||
getbegx (widget->win),
|
||||
(getbegy (widget->win)
|
||||
+ widget->boxHeight - 1),
|
||||
1, widget->boxWidth - 1,
|
||||
NULL, 1, buttonCount,
|
||||
(CDK_CSTRING2) buttonList, buttonCount,
|
||||
A_REVERSE, boxWidget, FALSE);
|
||||
CDKfreeStrings (buttonList);
|
||||
|
||||
setCDKButtonboxULChar (buttonWidget, ACS_LTEE);
|
||||
setCDKButtonboxURChar (buttonWidget, ACS_RTEE);
|
||||
|
||||
/*
|
||||
* We need to set the lower left and right
|
||||
* characters of the widget.
|
||||
*/
|
||||
setCDKRadioLLChar (widget, ACS_LTEE);
|
||||
setCDKRadioLRChar (widget, ACS_RTEE);
|
||||
|
||||
/*
|
||||
* Bind the Tab key in the widget to send a
|
||||
* Tab key to the button box widget.
|
||||
*/
|
||||
bindCDKObject (vRADIO, widget, KEY_TAB, widgetCB, buttonWidget);
|
||||
bindCDKObject (vRADIO, widget, CDK_NEXT, widgetCB, buttonWidget);
|
||||
bindCDKObject (vRADIO, widget, CDK_PREV, widgetCB, buttonWidget);
|
||||
|
||||
/* Check if the user wants to set the background of the widget. */
|
||||
setCDKButtonboxBackgroundColor (buttonWidget, CDK_WIDGET_COLOR);
|
||||
|
||||
/* Draw the button widget. */
|
||||
drawCDKButtonbox (buttonWidget, boxWidget);
|
||||
}
|
||||
|
||||
/*
|
||||
* If the user asked for a shadow, we need to create one. Do this instead
|
||||
* of using the shadow parameter because the button widget is not part of
|
||||
* the main widget and if the user asks for both buttons and a shadow, we
|
||||
* need to create a shadow big enough for both widgets. Create the shadow
|
||||
* window using the widgets shadowWin element, so screen refreshes will draw
|
||||
* them as well.
|
||||
*/
|
||||
if (shadowWidget == TRUE)
|
||||
{
|
||||
/* Determine the height of the shadow window. */
|
||||
shadowHeight = (buttonWidget == (CDKBUTTONBOX *)NULL ?
|
||||
widget->boxHeight :
|
||||
widget->boxHeight + buttonWidget->boxHeight - 1);
|
||||
|
||||
/* Create the shadow window. */
|
||||
widget->shadowWin = newwin (shadowHeight,
|
||||
widget->boxWidth,
|
||||
getbegy (widget->win) + 1,
|
||||
getbegx (widget->win) + 1);
|
||||
|
||||
if (widget->shadowWin != 0)
|
||||
{
|
||||
widget->shadow = TRUE;
|
||||
|
||||
/*
|
||||
* We force the widget and buttonWidget to be drawn so the
|
||||
* buttonbox widget will be drawn when the widget is activated.
|
||||
* Otherwise the shadow window will draw over the button widget.
|
||||
*/
|
||||
drawCDKRadio (widget, ObjOf (widget)->box);
|
||||
eraseCDKButtonbox (buttonWidget);
|
||||
drawCDKButtonbox (buttonWidget, ObjOf (buttonWidget)->box);
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if the user wants to set the background of the widget. */
|
||||
setCDKRadioBackgroundColor (widget, CDK_WIDGET_COLOR);
|
||||
|
||||
/* Activate the scrolling list. */
|
||||
answer = activateCDKRadio (widget, 0);
|
||||
|
||||
/* If there were buttons, get the button selected. */
|
||||
if (buttonWidget != 0)
|
||||
{
|
||||
selection = buttonWidget->currentButton;
|
||||
destroyCDKButtonbox (buttonWidget);
|
||||
}
|
||||
|
||||
/* Shut down curses. */
|
||||
destroyCDKRadio (widget);
|
||||
destroyCDKScreen (cdkScreen);
|
||||
endCDK ();
|
||||
|
||||
/* Print out the answer. */
|
||||
if (answer >= 0)
|
||||
{
|
||||
if (numberOutput == TRUE)
|
||||
{
|
||||
fprintf (fp, "%d\n", answer);
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf (fp, "%s\n", scrollList[answer]);
|
||||
}
|
||||
}
|
||||
fclose (fp);
|
||||
|
||||
CDKfreeStrings (scrollList);
|
||||
|
||||
/* Exit with the button selected. */
|
||||
ExitProgram (selection);
|
||||
}
|
||||
|
||||
static int widgetCB (EObjectType cdktype GCC_UNUSED,
|
||||
void *object GCC_UNUSED,
|
||||
void *clientData,
|
||||
chtype key)
|
||||
{
|
||||
CDKBUTTONBOX *buttonbox = (CDKBUTTONBOX *)clientData;
|
||||
(void) injectCDKButtonbox (buttonbox, key);
|
||||
return (TRUE);
|
||||
}
|
|
@ -1,281 +0,0 @@
|
|||
/* $Id: cdkscale.c,v 1.14 2016/12/04 15:22:16 tom Exp $ */
|
||||
|
||||
#include <cdk_test.h>
|
||||
|
||||
#ifdef XCURSES
|
||||
char *XCursesProgramName = "cdkscale";
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Declare file local prototypes.
|
||||
*/
|
||||
static int widgetCB (EObjectType cdktype, void *object, void *clientData, chtype key);
|
||||
|
||||
/*
|
||||
* Define file local variables.
|
||||
*/
|
||||
static const char *FPUsage = "-f Field Width -l Low Value -h High Value [-s Initial Value]] [-i Increment Value] [-a Accelerated Increment Value] [-T Title] [-L Label] [-B Buttons] [-O Output File] [-X X Position] [-Y Y Position] [-N] [-S]";
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
int main (int argc, char **argv)
|
||||
{
|
||||
/* *INDENT-EQLS* */
|
||||
CDKSCREEN *cdkScreen = 0;
|
||||
CDKSCALE *widget = 0;
|
||||
CDKBUTTONBOX *buttonWidget = 0;
|
||||
char *CDK_WIDGET_COLOR = 0;
|
||||
char *temp = 0;
|
||||
chtype *holder = 0;
|
||||
int answer = 0;
|
||||
int buttonCount = 0;
|
||||
int selection = 0;
|
||||
int shadowHeight = 0;
|
||||
FILE *fp = stderr;
|
||||
char **buttonList = 0;
|
||||
int tmp, j1, j2;
|
||||
|
||||
CDK_PARAMS params;
|
||||
boolean boxWidget;
|
||||
boolean shadowWidget;
|
||||
char *buttons;
|
||||
char *label;
|
||||
char *outputFile;
|
||||
char *title;
|
||||
int fieldWidth;
|
||||
int incrementStep;
|
||||
int acceleratedStep;
|
||||
int initValue;
|
||||
int lowValue;
|
||||
int highValue;
|
||||
int xpos;
|
||||
int ypos;
|
||||
|
||||
CDKparseParams (argc, argv, ¶ms, "a:f:h:i:l:s:B:L:O:T:" CDK_MIN_PARAMS);
|
||||
|
||||
/* *INDENT-EQLS* */
|
||||
xpos = CDKparamValue (¶ms, 'X', CENTER);
|
||||
ypos = CDKparamValue (¶ms, 'Y', CENTER);
|
||||
boxWidget = CDKparamValue (¶ms, 'N', TRUE);
|
||||
shadowWidget = CDKparamValue (¶ms, 'S', FALSE);
|
||||
acceleratedStep = CDKparamValue (¶ms, 'a', -1);
|
||||
fieldWidth = CDKparamValue (¶ms, 'f', 0);
|
||||
highValue = CDKparamValue (¶ms, 'h', INT_MIN);
|
||||
incrementStep = CDKparamValue (¶ms, 'i', 1);
|
||||
lowValue = CDKparamValue (¶ms, 'l', INT_MAX);
|
||||
initValue = CDKparamValue (¶ms, 's', INT_MIN);
|
||||
buttons = CDKparamString (¶ms, 'B');
|
||||
label = CDKparamString (¶ms, 'L');
|
||||
outputFile = CDKparamString (¶ms, 'O');
|
||||
title = CDKparamString (¶ms, 'T');
|
||||
|
||||
incrementStep = abs (incrementStep);
|
||||
|
||||
/* Make sure all the command line parameters were provided. */
|
||||
if (fieldWidth <= 0)
|
||||
{
|
||||
fprintf (stderr, "Usage: %s %s\n", argv[0], FPUsage);
|
||||
ExitProgram (CLI_ERROR);
|
||||
}
|
||||
|
||||
/* Make sure the user supplied the low/high values. */
|
||||
if ((lowValue == INT_MAX) || (highValue == INT_MIN))
|
||||
{
|
||||
fprintf (stderr, "Usage: %s %s\n", argv[0], FPUsage);
|
||||
ExitProgram (CLI_ERROR);
|
||||
}
|
||||
|
||||
/* If the user asked for an output file, try to open it. */
|
||||
if (outputFile != 0)
|
||||
{
|
||||
if ((fp = fopen (outputFile, "w")) == 0)
|
||||
{
|
||||
fprintf (stderr, "%s: Can not open output file %s\n", argv[0], outputFile);
|
||||
ExitProgram (CLI_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
/* Make sure the low is lower than the high (and vice versa). */
|
||||
if (lowValue > highValue)
|
||||
{
|
||||
/* *INDENT-EQLS* */
|
||||
tmp = lowValue;
|
||||
lowValue = highValue;
|
||||
highValue = tmp;
|
||||
}
|
||||
|
||||
/* Make sure the starting value is in range. */
|
||||
if (initValue < lowValue)
|
||||
{
|
||||
initValue = lowValue;
|
||||
}
|
||||
else if (initValue > highValue)
|
||||
{
|
||||
initValue = highValue;
|
||||
}
|
||||
|
||||
/* Check if the accelerated incremnt value was set. */
|
||||
if (acceleratedStep <= 0)
|
||||
{
|
||||
acceleratedStep = (int)((highValue - lowValue) / 10);
|
||||
acceleratedStep = MAXIMUM (1, acceleratedStep);
|
||||
}
|
||||
|
||||
cdkScreen = initCDKScreen (NULL);
|
||||
|
||||
/* Start color. */
|
||||
initCDKColor ();
|
||||
|
||||
/* Check if the user wants to set the background of the main screen. */
|
||||
if ((temp = getenv ("CDK_SCREEN_COLOR")) != 0)
|
||||
{
|
||||
holder = char2Chtype (temp, &j1, &j2);
|
||||
wbkgd (cdkScreen->window, holder[0]);
|
||||
wrefresh (cdkScreen->window);
|
||||
freeChtype (holder);
|
||||
}
|
||||
|
||||
/* Get the widget color background color. */
|
||||
if ((CDK_WIDGET_COLOR = getenv ("CDK_WIDGET_COLOR")) == 0)
|
||||
{
|
||||
CDK_WIDGET_COLOR = 0;
|
||||
}
|
||||
|
||||
/* Create the entry widget. */
|
||||
widget = newCDKScale (cdkScreen, xpos, ypos,
|
||||
title, label,
|
||||
A_NORMAL, fieldWidth,
|
||||
initValue, lowValue, highValue,
|
||||
incrementStep, acceleratedStep,
|
||||
boxWidget, shadowWidget);
|
||||
|
||||
/* Check to make sure we created the dialog box. */
|
||||
if (widget == 0)
|
||||
{
|
||||
/* Shut down curses and CDK. */
|
||||
destroyCDKScreen (cdkScreen);
|
||||
endCDK ();
|
||||
|
||||
fprintf (stderr,
|
||||
"Error: Could not create the numeric scale field. "
|
||||
"Is the window too small?\n");
|
||||
|
||||
ExitProgram (CLI_ERROR);
|
||||
}
|
||||
|
||||
/* Split the buttons if they supplied some. */
|
||||
if (buttons != 0)
|
||||
{
|
||||
/* Split the button list up. */
|
||||
buttonList = CDKsplitString (buttons, '\n');
|
||||
buttonCount = (int)CDKcountStrings ((CDK_CSTRING2) buttonList);
|
||||
|
||||
/* We need to create a buttonbox widget. */
|
||||
buttonWidget = newCDKButtonbox (cdkScreen,
|
||||
getbegx (widget->win),
|
||||
(getbegy (widget->win)
|
||||
+ widget->boxHeight - 1),
|
||||
1, widget->boxWidth - 1,
|
||||
0, 1, buttonCount,
|
||||
(CDK_CSTRING2) buttonList, buttonCount,
|
||||
A_REVERSE, boxWidget, FALSE);
|
||||
CDKfreeStrings (buttonList);
|
||||
|
||||
setCDKButtonboxULChar (buttonWidget, ACS_LTEE);
|
||||
setCDKButtonboxURChar (buttonWidget, ACS_RTEE);
|
||||
|
||||
/*
|
||||
* We need to set the lower left and right
|
||||
* characters of the widget.
|
||||
*/
|
||||
setCDKScaleLLChar (widget, ACS_LTEE);
|
||||
setCDKScaleLRChar (widget, ACS_RTEE);
|
||||
|
||||
/*
|
||||
* Bind the Tab key in the widget to send a
|
||||
* Tab key to the button box widget.
|
||||
*/
|
||||
bindCDKObject (vSCALE, widget, KEY_TAB, widgetCB, buttonWidget);
|
||||
bindCDKObject (vSCALE, widget, CDK_NEXT, widgetCB, buttonWidget);
|
||||
bindCDKObject (vSCALE, widget, CDK_PREV, widgetCB, buttonWidget);
|
||||
|
||||
/* Check if the user wants to set the background of the widget. */
|
||||
setCDKButtonboxBackgroundColor (buttonWidget, CDK_WIDGET_COLOR);
|
||||
|
||||
/* Draw the button widget. */
|
||||
drawCDKButtonbox (buttonWidget, boxWidget);
|
||||
}
|
||||
|
||||
/*
|
||||
* If the user asked for a shadow, we need to create one. Do this instead
|
||||
* of using the shadow parameter because the button widget is not part of
|
||||
* the main widget and if the user asks for both buttons and a shadow, we
|
||||
* need to create a shadow big enough for both widgets. Create the shadow
|
||||
* window using the widgets shadowWin element, so screen refreshes will draw
|
||||
* them as well.
|
||||
*/
|
||||
if (shadowWidget == TRUE)
|
||||
{
|
||||
/* Determine the height of the shadow window. */
|
||||
shadowHeight = (buttonWidget == 0 ?
|
||||
widget->boxHeight :
|
||||
widget->boxHeight + buttonWidget->boxHeight - 1);
|
||||
|
||||
/* Create the shadow window. */
|
||||
widget->shadowWin = newwin (shadowHeight,
|
||||
widget->boxWidth,
|
||||
getbegy (widget->win) + 1,
|
||||
getbegx (widget->win) + 1);
|
||||
|
||||
/* Make sure we could have created the shadow window. */
|
||||
if (widget->shadowWin != 0)
|
||||
{
|
||||
widget->shadow = TRUE;
|
||||
|
||||
/*
|
||||
* We force the widget and buttonWidget to be drawn so the
|
||||
* buttonbox widget will be drawn when the widget is activated.
|
||||
* Otherwise the shadow window will draw over the button widget.
|
||||
*/
|
||||
drawCDKScale (widget, ObjOf (widget)->box);
|
||||
eraseCDKButtonbox (buttonWidget);
|
||||
drawCDKButtonbox (buttonWidget, ObjOf (buttonWidget)->box);
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if the user wants to set the background of the widget. */
|
||||
setCDKScaleBackgroundColor (widget, CDK_WIDGET_COLOR);
|
||||
|
||||
/* Activate the widget. */
|
||||
answer = activateCDKScale (widget, 0);
|
||||
|
||||
/* If there were buttons, get the button selected. */
|
||||
if (buttonWidget != 0)
|
||||
{
|
||||
selection = buttonWidget->currentButton;
|
||||
destroyCDKButtonbox (buttonWidget);
|
||||
}
|
||||
|
||||
/* End CDK. */
|
||||
destroyCDKScale (widget);
|
||||
destroyCDKScreen (cdkScreen);
|
||||
endCDK ();
|
||||
|
||||
/* Print the value from the widget. */
|
||||
fprintf (fp, "%d\n", answer);
|
||||
fclose (fp);
|
||||
|
||||
/* Exit with the answer. */
|
||||
ExitProgram (selection);
|
||||
}
|
||||
|
||||
static int widgetCB (EObjectType cdktype GCC_UNUSED,
|
||||
void *object GCC_UNUSED,
|
||||
void *clientData,
|
||||
chtype key)
|
||||
{
|
||||
CDKBUTTONBOX *buttonbox = (CDKBUTTONBOX *)clientData;
|
||||
(void) injectCDKButtonbox (buttonbox, key);
|
||||
return (TRUE);
|
||||
}
|
|
@ -1,284 +0,0 @@
|
|||
/* $Id: cdkscroll.c,v 1.13 2016/12/04 15:22:16 tom Exp $ */
|
||||
|
||||
#include <cdk_test.h>
|
||||
|
||||
#ifdef XCURSES
|
||||
char *XCursesProgramName = "cdkscroll";
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Declare file local prototypes.
|
||||
*/
|
||||
static int widgetCB (EObjectType cdktype, void *object, void *clientData, chtype key);
|
||||
|
||||
/*
|
||||
* Define file local variables.
|
||||
*/
|
||||
static const char *FPUsage = "-l List | -f filename [-s Scroll Bar Position] [-n Numbers] [-i Item Index] [-T Title] [-B Buttons] [-O Output File] [-X X Position] [-Y Y Position] [-H Height] [-W Width] [-N] [-S]";
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
int main (int argc, char **argv)
|
||||
{
|
||||
/* *INDENT-EQLS* */
|
||||
CDKSCREEN *cdkScreen = 0;
|
||||
CDKSCROLL *widget = 0;
|
||||
CDKBUTTONBOX *buttonWidget = 0;
|
||||
char *CDK_WIDGET_COLOR = 0;
|
||||
char *temp = 0;
|
||||
chtype *holder = 0;
|
||||
int answer = 0;
|
||||
int spos = NONE;
|
||||
int buttonCount = 0;
|
||||
int selection = 0;
|
||||
int scrollLines = -1;
|
||||
int shadowHeight = 0;
|
||||
FILE *fp = stderr;
|
||||
char **scrollList = 0;
|
||||
char **buttonList = 0;
|
||||
int j1, j2;
|
||||
|
||||
CDK_PARAMS params;
|
||||
boolean boxWidget;
|
||||
boolean shadowWidget;
|
||||
char *buttons;
|
||||
char *filename;
|
||||
char *list;
|
||||
char *outputFile;
|
||||
char *title;
|
||||
int height;
|
||||
int numberOutput;
|
||||
int numbers;
|
||||
int width;
|
||||
int xpos;
|
||||
int ypos;
|
||||
|
||||
CDKparseParams (argc, argv, ¶ms, "f:il:ns:B:O:T:" CDK_CLI_PARAMS);
|
||||
|
||||
/* *INDENT-EQLS* */
|
||||
xpos = CDKparamValue (¶ms, 'X', CENTER);
|
||||
ypos = CDKparamValue (¶ms, 'Y', CENTER);
|
||||
height = CDKparamValue (¶ms, 'H', 1);
|
||||
width = CDKparamValue (¶ms, 'W', 1);
|
||||
boxWidget = CDKparamValue (¶ms, 'N', TRUE);
|
||||
shadowWidget = CDKparamValue (¶ms, 'S', FALSE);
|
||||
numberOutput = CDKparamValue (¶ms, 'i', FALSE);
|
||||
numbers = CDKparamValue (¶ms, 'n', FALSE);
|
||||
filename = CDKparamString (¶ms, 'f');
|
||||
list = CDKparamString (¶ms, 'l');
|
||||
buttons = CDKparamString (¶ms, 'B');
|
||||
outputFile = CDKparamString (¶ms, 'O');
|
||||
title = CDKparamString (¶ms, 'T');
|
||||
|
||||
spos = CDKparsePosition (CDKparamString (¶ms, 's'));
|
||||
|
||||
/* If the user asked for an output file, try to open it. */
|
||||
if (outputFile != 0)
|
||||
{
|
||||
if ((fp = fopen (outputFile, "w")) == 0)
|
||||
{
|
||||
fprintf (stderr, "%s: Can not open output file %s\n", argv[0], outputFile);
|
||||
ExitProgram (CLI_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
/* Did they provide a list of items. */
|
||||
if (list == 0)
|
||||
{
|
||||
/* Maybe they gave a filename to use to read. */
|
||||
if (filename != 0)
|
||||
{
|
||||
/* Read the file in. */
|
||||
scrollLines = CDKreadFile (filename, &scrollList);
|
||||
|
||||
/* Check if there was an error. */
|
||||
if (scrollLines == -1)
|
||||
{
|
||||
fprintf (stderr, "Error: Could not open the file '%s'.\n", filename);
|
||||
ExitProgram (CLI_ERROR);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* They didn't provide anything. */
|
||||
fprintf (stderr, "Usage: %s %s\n", argv[0], FPUsage);
|
||||
ExitProgram (CLI_ERROR);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Split the scroll lines up. */
|
||||
scrollList = CDKsplitString (list, '\n');
|
||||
scrollLines = (int)CDKcountStrings ((CDK_CSTRING2) scrollList);
|
||||
}
|
||||
|
||||
cdkScreen = initCDKScreen (NULL);
|
||||
|
||||
/* Start color. */
|
||||
initCDKColor ();
|
||||
|
||||
/* Check if the user wants to set the background of the main screen. */
|
||||
if ((temp = getenv ("CDK_SCREEN_COLOR")) != 0)
|
||||
{
|
||||
holder = char2Chtype (temp, &j1, &j2);
|
||||
wbkgd (cdkScreen->window, holder[0]);
|
||||
wrefresh (cdkScreen->window);
|
||||
freeChtype (holder);
|
||||
}
|
||||
|
||||
/* Get the widget color background color. */
|
||||
if ((CDK_WIDGET_COLOR = getenv ("CDK_WIDGET_COLOR")) == 0)
|
||||
{
|
||||
CDK_WIDGET_COLOR = 0;
|
||||
}
|
||||
|
||||
/* Create the scrolling list. */
|
||||
widget = newCDKScroll (cdkScreen, xpos, ypos, spos,
|
||||
height, width, title,
|
||||
(CDK_CSTRING2) scrollList, scrollLines,
|
||||
numbers, A_REVERSE,
|
||||
boxWidget, shadowWidget);
|
||||
|
||||
/* Make sure we could create the widget. */
|
||||
if (widget == 0)
|
||||
{
|
||||
CDKfreeStrings (scrollList);
|
||||
|
||||
destroyCDKScreen (cdkScreen);
|
||||
endCDK ();
|
||||
|
||||
fprintf (stderr,
|
||||
"Error: Could not create the scrolling list. "
|
||||
"Is the window too small?\n");
|
||||
|
||||
ExitProgram (CLI_ERROR);
|
||||
}
|
||||
|
||||
/* Split the buttons if they supplied some. */
|
||||
if (buttons != 0)
|
||||
{
|
||||
/* Split the button list up. */
|
||||
buttonList = CDKsplitString (buttons, '\n');
|
||||
buttonCount = (int)CDKcountStrings ((CDK_CSTRING2) buttonList);
|
||||
|
||||
/* We need to create a buttonbox widget. */
|
||||
buttonWidget = newCDKButtonbox (cdkScreen,
|
||||
getbegx (widget->win),
|
||||
(getbegy (widget->win)
|
||||
+ widget->boxHeight - 1),
|
||||
1, widget->boxWidth - 1,
|
||||
0, 1, buttonCount,
|
||||
(CDK_CSTRING2) buttonList, buttonCount,
|
||||
A_REVERSE, boxWidget, FALSE);
|
||||
CDKfreeStrings (buttonList);
|
||||
|
||||
setCDKButtonboxULChar (buttonWidget, ACS_LTEE);
|
||||
setCDKButtonboxURChar (buttonWidget, ACS_RTEE);
|
||||
|
||||
/*
|
||||
* We need to set the lower left and right
|
||||
* characters of the widget.
|
||||
*/
|
||||
setCDKScrollLLChar (widget, ACS_LTEE);
|
||||
setCDKScrollLRChar (widget, ACS_RTEE);
|
||||
|
||||
/*
|
||||
* Bind the Tab key in the widget to send a
|
||||
* Tab key to the button box widget.
|
||||
*/
|
||||
bindCDKObject (vSCROLL, widget, KEY_TAB, widgetCB, buttonWidget);
|
||||
bindCDKObject (vSCROLL, widget, CDK_NEXT, widgetCB, buttonWidget);
|
||||
bindCDKObject (vSCROLL, widget, CDK_PREV, widgetCB, buttonWidget);
|
||||
|
||||
/* Check if the user wants to set the background of the widget. */
|
||||
setCDKButtonboxBackgroundColor (buttonWidget, CDK_WIDGET_COLOR);
|
||||
|
||||
/* Draw the button widget. */
|
||||
drawCDKButtonbox (buttonWidget, boxWidget);
|
||||
}
|
||||
|
||||
/*
|
||||
* If the user asked for a shadow, we need to create one. Do this instead
|
||||
* of using the shadow parameter because the button widget is not part of
|
||||
* the main widget and if the user asks for both buttons and a shadow, we
|
||||
* need to create a shadow big enough for both widgets. Create the shadow
|
||||
* window using the widgets shadowWin element, so screen refreshes will draw
|
||||
* them as well.
|
||||
*/
|
||||
if (shadowWidget == TRUE)
|
||||
{
|
||||
/* Determine the height of the shadow window. */
|
||||
shadowHeight = (buttonWidget == 0 ?
|
||||
widget->boxHeight :
|
||||
widget->boxHeight + buttonWidget->boxHeight - 1);
|
||||
|
||||
/* Create the shadow window. */
|
||||
widget->shadowWin = newwin (shadowHeight,
|
||||
widget->boxWidth,
|
||||
getbegy (widget->win) + 1,
|
||||
getbegx (widget->win) + 1);
|
||||
|
||||
/* Make sure we could have created the shadow window. */
|
||||
if (widget->shadowWin != 0)
|
||||
{
|
||||
widget->shadow = TRUE;
|
||||
|
||||
/*
|
||||
* We force the widget and buttonWidget to be drawn so the
|
||||
* buttonbox widget will be drawn when the widget is activated.
|
||||
* Otherwise the shadow window will draw over the button widget.
|
||||
*/
|
||||
drawCDKScroll (widget, ObjOf (widget)->box);
|
||||
eraseCDKButtonbox (buttonWidget);
|
||||
drawCDKButtonbox (buttonWidget, ObjOf (buttonWidget)->box);
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if the user wants to set the background of the widget. */
|
||||
setCDKScrollBackgroundColor (widget, CDK_WIDGET_COLOR);
|
||||
|
||||
/* Activate the scrolling list. */
|
||||
answer = activateCDKScroll (widget, 0);
|
||||
|
||||
/* If there were buttons, get the button selected. */
|
||||
if (buttonWidget != 0)
|
||||
{
|
||||
selection = buttonWidget->currentButton;
|
||||
destroyCDKButtonbox (buttonWidget);
|
||||
}
|
||||
|
||||
/* Shut down curses. */
|
||||
destroyCDKScroll (widget);
|
||||
destroyCDKScreen (cdkScreen);
|
||||
endCDK ();
|
||||
|
||||
/* Print out the answer. */
|
||||
if (answer >= 0)
|
||||
{
|
||||
if (numberOutput == TRUE)
|
||||
{
|
||||
fprintf (fp, "%d\n", answer);
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf (fp, "%s\n", scrollList[answer]);
|
||||
}
|
||||
}
|
||||
fclose (fp);
|
||||
|
||||
CDKfreeStrings (scrollList);
|
||||
|
||||
/* Exit with the answer. */
|
||||
ExitProgram (selection);
|
||||
}
|
||||
|
||||
static int widgetCB (EObjectType cdktype GCC_UNUSED,
|
||||
void *object GCC_UNUSED,
|
||||
void *clientData,
|
||||
chtype key)
|
||||
{
|
||||
CDKBUTTONBOX *buttonbox = (CDKBUTTONBOX *)clientData;
|
||||
(void) injectCDKButtonbox (buttonbox, key);
|
||||
return (TRUE);
|
||||
}
|
|
@ -1,341 +0,0 @@
|
|||
/* $Id: cdkselection.c,v 1.15 2016/12/04 15:22:16 tom Exp $ */
|
||||
|
||||
#include <cdk_test.h>
|
||||
|
||||
#ifdef XCURSES
|
||||
char *XCursesProgramName = "cdkselection";
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Declare file local prototypes.
|
||||
*/
|
||||
static int widgetCB (EObjectType cdktype, void *object, void *clientData, chtype key);
|
||||
|
||||
/*
|
||||
* Define file local variables.
|
||||
*/
|
||||
static const char *FPUsage = "-l List | -f filename [-c Choices ] [-s Selection Bar Position] [-T Title] [-B Buttons] [-O Output File] [-X X Position] [-Y Y Position] [-H Height] [-W Width] [-N] [-S]";
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
int main (int argc, char **argv)
|
||||
{
|
||||
/* *INDENT-EQLS* */
|
||||
CDKSCREEN *cdkScreen = 0;
|
||||
CDKSELECTION *widget = 0;
|
||||
CDKBUTTONBOX *buttonWidget = 0;
|
||||
chtype *holder = 0;
|
||||
char *item = 0;
|
||||
char *CDK_WIDGET_COLOR = 0;
|
||||
char *temp = 0;
|
||||
int scrollLines = -1;
|
||||
int choiceSize = -1;
|
||||
int buttonCount = 0;
|
||||
int selection = 0;
|
||||
int shadowHeight = 0;
|
||||
FILE *fp = stderr;
|
||||
char **scrollList = 0;
|
||||
char **choiceList = 0;
|
||||
char **buttonList = 0;
|
||||
char **items = 0;
|
||||
int choiceValues[MAX_ITEMS];
|
||||
int editModes[MAX_ITEMS];
|
||||
int x, fields, j1, j2;
|
||||
|
||||
CDK_PARAMS params;
|
||||
boolean boxWidget;
|
||||
boolean shadowWidget;
|
||||
char *buttons;
|
||||
char *choices;
|
||||
char *filename;
|
||||
char *list;
|
||||
char *outputFile;
|
||||
char *title;
|
||||
int height;
|
||||
int numbers;
|
||||
int spos;
|
||||
int width;
|
||||
int xpos;
|
||||
int ypos;
|
||||
|
||||
CDKparseParams (argc, argv, ¶ms, "c:f:ln:s:B:O:T:" CDK_CLI_PARAMS);
|
||||
|
||||
/* *INDENT-EQLS* */
|
||||
xpos = CDKparamValue (¶ms, 'X', CENTER);
|
||||
ypos = CDKparamValue (¶ms, 'Y', CENTER);
|
||||
height = CDKparamValue (¶ms, 'H', 10);
|
||||
width = CDKparamValue (¶ms, 'W', 10);
|
||||
boxWidget = CDKparamValue (¶ms, 'N', TRUE);
|
||||
shadowWidget = CDKparamValue (¶ms, 'S', FALSE);
|
||||
choices = CDKparamString (¶ms, 'c');
|
||||
filename = CDKparamString (¶ms, 'f');
|
||||
list = CDKparamString (¶ms, 'l');
|
||||
buttons = CDKparamString (¶ms, 'B');
|
||||
outputFile = CDKparamString (¶ms, 'O');
|
||||
title = CDKparamString (¶ms, 'T');
|
||||
numbers = CDKparamValue (¶ms, 'n', FALSE);
|
||||
spos = CDKparsePosition (CDKparamString (¶ms, 's'));
|
||||
|
||||
/* If the user asked for an output file, try to open it. */
|
||||
if (outputFile != 0)
|
||||
{
|
||||
if ((fp = fopen (outputFile, "w")) == 0)
|
||||
{
|
||||
fprintf (stderr, "%s: Can not open output file %s\n", argv[0], outputFile);
|
||||
ExitProgram (CLI_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
/* Did they provide a list of items. */
|
||||
if (list == 0)
|
||||
{
|
||||
/* Maybe they gave a filename to use to read. */
|
||||
if (filename != 0)
|
||||
{
|
||||
/* Read the file in. */
|
||||
scrollLines = CDKreadFile (filename, &scrollList);
|
||||
|
||||
/* Check if there was an error. */
|
||||
if (scrollLines == -1)
|
||||
{
|
||||
fprintf (stderr, "Error: Could not open the file '%s'.\n", filename);
|
||||
ExitProgram (CLI_ERROR);
|
||||
}
|
||||
|
||||
/*
|
||||
* For each line, we will split on a CTRL-V and look for a selection
|
||||
* value/edit mode. The format of the input file can be the following:
|
||||
* Index value [choice value] [edit flag]
|
||||
*/
|
||||
for (x = 0; x < scrollLines; x++)
|
||||
{
|
||||
/* Split the line on CTRL-V. */
|
||||
items = CDKsplitString (scrollList[x], CTRL ('V'));
|
||||
fields = (int)CDKcountStrings ((CDK_CSTRING2)items);
|
||||
|
||||
/* Check the field count. */
|
||||
if (fields == 1)
|
||||
{
|
||||
choiceValues[x] = 0;
|
||||
editModes[x] = 0;
|
||||
}
|
||||
else if (fields == 2)
|
||||
{
|
||||
freeChar (scrollList[x]);
|
||||
scrollList[x] = copyChar (items[0]);
|
||||
|
||||
choiceValues[x] = (int)atoi (items[1]);
|
||||
editModes[x] = 0;
|
||||
}
|
||||
else if (fields == 3)
|
||||
{
|
||||
freeChar (scrollList[x]);
|
||||
scrollList[x] = copyChar (items[0]);
|
||||
|
||||
choiceValues[x] = (int)atoi (items[1]);
|
||||
editModes[x] = (int)atoi (items[2]);
|
||||
}
|
||||
|
||||
CDKfreeStrings (items);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* They didn't provide anything. */
|
||||
fprintf (stderr, "Usage: %s %s\n", argv[0], FPUsage);
|
||||
ExitProgram (CLI_ERROR);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Split the scroll lines up. */
|
||||
scrollList = CDKsplitString (list, '\n');
|
||||
scrollLines = (int)CDKcountStrings ((CDK_CSTRING2)scrollList);
|
||||
}
|
||||
|
||||
/* Did they supply a chopice list. */
|
||||
if (choices == 0)
|
||||
{
|
||||
choiceList = calloc(sizeof(char *), 3);
|
||||
choiceList[0] = copyChar ("Yes ");
|
||||
choiceList[1] = copyChar ("No ");
|
||||
choiceSize = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Split the choices up. */
|
||||
choiceList = CDKsplitString (choices, '\n');
|
||||
choiceSize = (int)CDKcountStrings ((CDK_CSTRING2)choiceList);
|
||||
}
|
||||
|
||||
cdkScreen = initCDKScreen (NULL);
|
||||
|
||||
/* Start color. */
|
||||
initCDKColor ();
|
||||
|
||||
/* Check if the user wants to set the background of the main screen. */
|
||||
if ((temp = getenv ("CDK_SCREEN_COLOR")) != 0)
|
||||
{
|
||||
holder = char2Chtype (temp, &j1, &j2);
|
||||
wbkgd (cdkScreen->window, holder[0]);
|
||||
wrefresh (cdkScreen->window);
|
||||
freeChtype (holder);
|
||||
}
|
||||
|
||||
/* Get the widget color background color. */
|
||||
if ((CDK_WIDGET_COLOR = getenv ("CDK_WIDGET_COLOR")) == 0)
|
||||
{
|
||||
CDK_WIDGET_COLOR = 0;
|
||||
}
|
||||
|
||||
/* Create the scrolling list. */
|
||||
widget = newCDKSelection (cdkScreen, xpos, ypos, spos,
|
||||
height, width, title,
|
||||
(CDK_CSTRING2)scrollList, scrollLines,
|
||||
(CDK_CSTRING2)choiceList, choiceSize,
|
||||
A_REVERSE,
|
||||
boxWidget, shadowWidget);
|
||||
CDKfreeStrings (choiceList);
|
||||
|
||||
/* Make sure we could create the widget. */
|
||||
if (widget == 0)
|
||||
{
|
||||
CDKfreeStrings (scrollList);
|
||||
|
||||
destroyCDKScreen (cdkScreen);
|
||||
endCDK ();
|
||||
|
||||
fprintf (stderr,
|
||||
"Error: Could not create the selection list. "
|
||||
"Is the window too small?\n");
|
||||
|
||||
ExitProgram (CLI_ERROR);
|
||||
}
|
||||
|
||||
/* Set up the default selection choices. */
|
||||
setCDKSelectionChoices (widget, choiceValues);
|
||||
|
||||
/* Split the buttons if they supplied some. */
|
||||
if (buttons != 0)
|
||||
{
|
||||
/* Split the button list up. */
|
||||
buttonList = CDKsplitString (buttons, '\n');
|
||||
buttonCount = (int)CDKcountStrings ((CDK_CSTRING2)buttonList);
|
||||
|
||||
/* We need to create a buttonbox widget. */
|
||||
buttonWidget = newCDKButtonbox (cdkScreen,
|
||||
getbegx (widget->win),
|
||||
(getbegy (widget->win)
|
||||
+ widget->boxHeight - 1),
|
||||
1, widget->boxWidth - 1,
|
||||
0, 1, buttonCount,
|
||||
(CDK_CSTRING2)buttonList, buttonCount,
|
||||
A_REVERSE, boxWidget, FALSE);
|
||||
CDKfreeStrings (buttonList);
|
||||
|
||||
setCDKButtonboxULChar (buttonWidget, ACS_LTEE);
|
||||
setCDKButtonboxURChar (buttonWidget, ACS_RTEE);
|
||||
|
||||
/*
|
||||
* We need to set the lower left and right
|
||||
* characters of the widget.
|
||||
*/
|
||||
setCDKSelectionLLChar (widget, ACS_LTEE);
|
||||
setCDKSelectionLRChar (widget, ACS_RTEE);
|
||||
|
||||
/*
|
||||
* Bind the Tab key in the widget to send a
|
||||
* Tab key to the button box widget.
|
||||
*/
|
||||
bindCDKObject (vSELECTION, widget, KEY_TAB, widgetCB, buttonWidget);
|
||||
bindCDKObject (vSELECTION, widget, CDK_NEXT, widgetCB, buttonWidget);
|
||||
bindCDKObject (vSELECTION, widget, CDK_PREV, widgetCB, buttonWidget);
|
||||
|
||||
/* Check if the user wants to set the background of the widget. */
|
||||
setCDKButtonboxBackgroundColor (buttonWidget, CDK_WIDGET_COLOR);
|
||||
|
||||
/* Draw the button widget. */
|
||||
drawCDKButtonbox (buttonWidget, boxWidget);
|
||||
}
|
||||
|
||||
/*
|
||||
* If the user asked for a shadow, we need to create one. Do this instead
|
||||
* of using the shadow parameter because the button widget is not part of
|
||||
* the main widget and if the user asks for both buttons and a shadow, we
|
||||
* need to create a shadow big enough for both widgets. Create the shadow
|
||||
* window using the widgets shadowWin element, so screen refreshes will draw
|
||||
* them as well.
|
||||
*/
|
||||
if (shadowWidget == TRUE)
|
||||
{
|
||||
/* Determine the height of the shadow window. */
|
||||
shadowHeight = (buttonWidget == 0 ?
|
||||
widget->boxHeight :
|
||||
widget->boxHeight + buttonWidget->boxHeight - 1);
|
||||
|
||||
/* Create the shadow window. */
|
||||
widget->shadowWin = newwin (shadowHeight,
|
||||
widget->boxWidth,
|
||||
getbegy (widget->win) + 1,
|
||||
getbegx (widget->win) + 1);
|
||||
|
||||
/* Make sure we could have created the shadow window. */
|
||||
if (widget->shadowWin != 0)
|
||||
{
|
||||
widget->shadow = TRUE;
|
||||
|
||||
/*
|
||||
* We force the widget and buttonWidget to be drawn so the
|
||||
* buttonbox widget will be drawn when the widget is activated.
|
||||
* Otherwise the shadow window will draw over the button widget.
|
||||
*/
|
||||
drawCDKSelection (widget, ObjOf (widget)->box);
|
||||
eraseCDKButtonbox (buttonWidget);
|
||||
drawCDKButtonbox (buttonWidget, ObjOf (buttonWidget)->box);
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if the user wants to set the background of the widget. */
|
||||
setCDKSelectionBackgroundColor (widget, CDK_WIDGET_COLOR);
|
||||
|
||||
/* Set up the default selection modes. */
|
||||
setCDKSelectionModes (widget, editModes);
|
||||
|
||||
/* Activate the selection list. */
|
||||
activateCDKSelection (widget, 0);
|
||||
|
||||
/* If there were buttons, get the button selected. */
|
||||
if (buttonWidget != 0)
|
||||
{
|
||||
selection = buttonWidget->currentButton;
|
||||
destroyCDKButtonbox (buttonWidget);
|
||||
}
|
||||
|
||||
/* Print out the answer. */
|
||||
for (x = 0; x < scrollLines; x++)
|
||||
{
|
||||
holder = char2Chtype (scrollList[x], &j1, &j2);
|
||||
item = chtype2Char (holder);
|
||||
fprintf (fp, "%d %s\n", widget->selections[x], item);
|
||||
freeChtype (holder);
|
||||
freeChar (item);
|
||||
}
|
||||
|
||||
CDKfreeStrings (scrollList);
|
||||
|
||||
/* Shut down curses. */
|
||||
destroyCDKSelection (widget);
|
||||
destroyCDKScreen (cdkScreen);
|
||||
endCDK ();
|
||||
ExitProgram (selection);
|
||||
}
|
||||
|
||||
static int widgetCB (EObjectType cdktype GCC_UNUSED, void *object GCC_UNUSED,
|
||||
void *clientData,
|
||||
chtype key)
|
||||
{
|
||||
CDKBUTTONBOX *buttonbox = (CDKBUTTONBOX *)clientData;
|
||||
(void)injectCDKButtonbox (buttonbox, key);
|
||||
return (TRUE);
|
||||
}
|
|
@ -1,290 +0,0 @@
|
|||
/* $Id: cdkslider.c,v 1.14 2016/12/04 15:22:16 tom Exp $ */
|
||||
|
||||
#include <cdk_test.h>
|
||||
|
||||
#ifdef XCURSES
|
||||
char *XCursesProgramName = "cdkslider";
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Declare file local prototypes.
|
||||
*/
|
||||
static int widgetCB (EObjectType cdktype, void *object, void *clientData, chtype key);
|
||||
|
||||
/*
|
||||
* Define file local variables.
|
||||
*/
|
||||
static const char *FPUsage = "-f Field Width -l Low Value -h High Value [-s Initial Value]] [-i Increment Value] [-a Accelerated Increment Value] [-F Field Character] [-T Title] [-L Label] [-B Buttons] [-O Output File] [-X X Position] [-Y Y Position] [-N] [-S]";
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
int main (int argc, char **argv)
|
||||
{
|
||||
/* *INDENT-EQLS* */
|
||||
CDKSCREEN *cdkScreen = 0;
|
||||
CDKSLIDER *widget = 0;
|
||||
CDKBUTTONBOX *buttonWidget = 0;
|
||||
char *CDK_WIDGET_COLOR = 0;
|
||||
char *temp = 0;
|
||||
chtype *holder = 0;
|
||||
chtype fieldAttr = A_REVERSE | ' ';
|
||||
int answer = 0;
|
||||
int buttonCount = 0;
|
||||
int selection = 0;
|
||||
int shadowHeight = 0;
|
||||
FILE *fp = stderr;
|
||||
char **buttonList = 0;
|
||||
int j1, j2, tmp;
|
||||
|
||||
CDK_PARAMS params;
|
||||
boolean boxWidget;
|
||||
boolean shadowWidget;
|
||||
char *barAttribute;
|
||||
char *buttons;
|
||||
char *label;
|
||||
char *outputFile;
|
||||
char *title;
|
||||
int fieldWidth;
|
||||
int incrementStep;
|
||||
int acceleratedStep;
|
||||
int initValue;
|
||||
int lowValue;
|
||||
int highValue;
|
||||
int xpos;
|
||||
int ypos;
|
||||
|
||||
CDKparseParams (argc, argv, ¶ms, "a:f:h:i:l:s:B:F:L:O:T:" CDK_MIN_PARAMS);
|
||||
|
||||
/* *INDENT-EQLS* */
|
||||
xpos = CDKparamValue (¶ms, 'X', CENTER);
|
||||
ypos = CDKparamValue (¶ms, 'Y', CENTER);
|
||||
boxWidget = CDKparamValue (¶ms, 'N', TRUE);
|
||||
shadowWidget = CDKparamValue (¶ms, 'S', FALSE);
|
||||
acceleratedStep = CDKparamValue (¶ms, 'a', -1);
|
||||
fieldWidth = CDKparamValue (¶ms, 'f', 0);
|
||||
highValue = CDKparamValue (¶ms, 'h', INT_MIN);
|
||||
incrementStep = CDKparamValue (¶ms, 'i', 1);
|
||||
lowValue = CDKparamValue (¶ms, 'l', INT_MAX);
|
||||
initValue = CDKparamValue (¶ms, 's', INT_MIN);
|
||||
buttons = CDKparamString (¶ms, 'B');
|
||||
barAttribute = CDKparamString (¶ms, 'F');
|
||||
label = CDKparamString (¶ms, 'L');
|
||||
outputFile = CDKparamString (¶ms, 'O');
|
||||
title = CDKparamString (¶ms, 'T');
|
||||
incrementStep = abs (incrementStep);
|
||||
|
||||
/* Make sure all the command line parameters were provided. */
|
||||
if (fieldWidth <= 0)
|
||||
{
|
||||
fprintf (stderr, "Usage: %s %s\n", argv[0], FPUsage);
|
||||
ExitProgram (CLI_ERROR);
|
||||
}
|
||||
|
||||
/* Make sure the user supplied the low/high values. */
|
||||
if ((lowValue == INT_MAX) || (highValue == INT_MIN))
|
||||
{
|
||||
fprintf (stderr, "Usage: %s %s\n", argv[0], FPUsage);
|
||||
ExitProgram (CLI_ERROR);
|
||||
}
|
||||
|
||||
/* If the user asked for an output file, try to open it. */
|
||||
if (outputFile != 0)
|
||||
{
|
||||
if ((fp = fopen (outputFile, "w")) == 0)
|
||||
{
|
||||
fprintf (stderr, "%s: Can not open output file %s\n", argv[0], outputFile);
|
||||
ExitProgram (CLI_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
/* Make sure the low is lower than the high (and vice versa). */
|
||||
if (lowValue > highValue)
|
||||
{
|
||||
tmp = lowValue;
|
||||
lowValue = highValue;
|
||||
highValue = tmp;
|
||||
}
|
||||
|
||||
/* Make sure the starting value is in range. */
|
||||
if (initValue < lowValue)
|
||||
{
|
||||
initValue = lowValue;
|
||||
}
|
||||
else if (initValue > highValue)
|
||||
{
|
||||
initValue = highValue;
|
||||
}
|
||||
|
||||
/* Check if the accelerated incremnt value was set. */
|
||||
if (acceleratedStep <= 0)
|
||||
{
|
||||
acceleratedStep = (int)((highValue - lowValue) / 10);
|
||||
acceleratedStep = MAXIMUM (1, acceleratedStep);
|
||||
}
|
||||
|
||||
cdkScreen = initCDKScreen (NULL);
|
||||
|
||||
/* Start color. */
|
||||
initCDKColor ();
|
||||
|
||||
/* Check if the user wants to set the background of the main screen. */
|
||||
if ((temp = getenv ("CDK_SCREEN_COLOR")) != 0)
|
||||
{
|
||||
holder = char2Chtype (temp, &j1, &j2);
|
||||
wbkgd (cdkScreen->window, holder[0]);
|
||||
wrefresh (cdkScreen->window);
|
||||
freeChtype (holder);
|
||||
}
|
||||
|
||||
/* Get the widget color background color. */
|
||||
if ((CDK_WIDGET_COLOR = getenv ("CDK_WIDGET_COLOR")) == 0)
|
||||
{
|
||||
CDK_WIDGET_COLOR = 0;
|
||||
}
|
||||
|
||||
/* Did the user ask to change the bar attribute? */
|
||||
if (barAttribute != 0)
|
||||
{
|
||||
holder = char2Chtype (barAttribute, &j1, &j2);
|
||||
fieldAttr = holder[0];
|
||||
freeChtype (holder);
|
||||
}
|
||||
|
||||
/* Create the entry widget. */
|
||||
widget = newCDKSlider (cdkScreen, xpos, ypos,
|
||||
title, label,
|
||||
fieldAttr, fieldWidth,
|
||||
initValue, lowValue, highValue,
|
||||
incrementStep, acceleratedStep,
|
||||
boxWidget, shadowWidget);
|
||||
|
||||
/* Check to make sure we created the dialog box. */
|
||||
if (widget == 0)
|
||||
{
|
||||
/* Shut down curses and CDK. */
|
||||
destroyCDKScreen (cdkScreen);
|
||||
endCDK ();
|
||||
|
||||
fprintf (stderr,
|
||||
"Error: Could not create the numeric slider field. "
|
||||
"Is the window too small?\n");
|
||||
|
||||
ExitProgram (CLI_ERROR);
|
||||
}
|
||||
|
||||
/* Split the buttons if they supplied some. */
|
||||
if (buttons != 0)
|
||||
{
|
||||
/* Split the button list up. */
|
||||
buttonList = CDKsplitString (buttons, '\n');
|
||||
buttonCount = (int)CDKcountStrings ((CDK_CSTRING2) buttonList);
|
||||
|
||||
/* We need to create a buttonbox widget. */
|
||||
buttonWidget = newCDKButtonbox (cdkScreen,
|
||||
getbegx (widget->win),
|
||||
(getbegy (widget->win)
|
||||
+ widget->boxHeight - 1),
|
||||
1, widget->boxWidth - 1,
|
||||
0, 1, buttonCount,
|
||||
(CDK_CSTRING2) buttonList, buttonCount,
|
||||
A_REVERSE, boxWidget, FALSE);
|
||||
CDKfreeStrings (buttonList);
|
||||
|
||||
setCDKButtonboxULChar (buttonWidget, ACS_LTEE);
|
||||
setCDKButtonboxURChar (buttonWidget, ACS_RTEE);
|
||||
|
||||
/*
|
||||
* We need to set the lower left and right
|
||||
* characters of the widget.
|
||||
*/
|
||||
setCDKSliderLLChar (widget, ACS_LTEE);
|
||||
setCDKSliderLRChar (widget, ACS_RTEE);
|
||||
|
||||
/*
|
||||
* Bind the Tab key in the widget to send a
|
||||
* Tab key to the button box widget.
|
||||
*/
|
||||
bindCDKObject (vSLIDER, widget, KEY_TAB, widgetCB, buttonWidget);
|
||||
bindCDKObject (vSLIDER, widget, CDK_NEXT, widgetCB, buttonWidget);
|
||||
bindCDKObject (vSLIDER, widget, CDK_PREV, widgetCB, buttonWidget);
|
||||
|
||||
/* Check if the user wants to set the background of the widget. */
|
||||
setCDKButtonboxBackgroundColor (buttonWidget, CDK_WIDGET_COLOR);
|
||||
|
||||
/* Draw the button widget. */
|
||||
drawCDKButtonbox (buttonWidget, boxWidget);
|
||||
}
|
||||
|
||||
/*
|
||||
* If the user asked for a shadow, we need to create one. Do this instead
|
||||
* of using the shadow parameter because the button widget is not part of
|
||||
* the main widget and if the user asks for both buttons and a shadow, we
|
||||
* need to create a shadow big enough for both widgets. Create the shadow
|
||||
* window using the widgets shadowWin element, so screen refreshes will draw
|
||||
* them as well.
|
||||
*/
|
||||
if (shadowWidget == TRUE)
|
||||
{
|
||||
/* Determine the height of the shadow window. */
|
||||
shadowHeight = (buttonWidget == 0 ?
|
||||
widget->boxHeight :
|
||||
widget->boxHeight + buttonWidget->boxHeight - 1);
|
||||
|
||||
/* Create the shadow window. */
|
||||
widget->shadowWin = newwin (shadowHeight,
|
||||
widget->boxWidth,
|
||||
getbegy (widget->win) + 1,
|
||||
getbegx (widget->win) + 1);
|
||||
|
||||
/* Make sure we could have created the shadow window. */
|
||||
if (widget->shadowWin != 0)
|
||||
{
|
||||
widget->shadow = TRUE;
|
||||
|
||||
/*
|
||||
* We force the widget and buttonWidget to be drawn so the
|
||||
* buttonbox widget will be drawn when the widget is activated.
|
||||
* Otherwise the shadow window will draw over the button widget.
|
||||
*/
|
||||
drawCDKSlider (widget, ObjOf (widget)->box);
|
||||
eraseCDKButtonbox (buttonWidget);
|
||||
drawCDKButtonbox (buttonWidget, ObjOf (buttonWidget)->box);
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if the user wants to set the background of the widget. */
|
||||
setCDKSliderBackgroundColor (widget, CDK_WIDGET_COLOR);
|
||||
|
||||
/* Activate the widget. */
|
||||
answer = activateCDKSlider (widget, 0);
|
||||
|
||||
/* If there were buttons, get the button selected. */
|
||||
if (buttonWidget != 0)
|
||||
{
|
||||
selection = buttonWidget->currentButton;
|
||||
destroyCDKButtonbox (buttonWidget);
|
||||
}
|
||||
|
||||
/* End CDK. */
|
||||
destroyCDKSlider (widget);
|
||||
destroyCDKScreen (cdkScreen);
|
||||
endCDK ();
|
||||
|
||||
/* Print the value from the widget. */
|
||||
fprintf (fp, "%d\n", answer);
|
||||
fclose (fp);
|
||||
|
||||
/* Exit with the button selected. */
|
||||
ExitProgram (selection);
|
||||
}
|
||||
|
||||
static int widgetCB (EObjectType cdktype GCC_UNUSED,
|
||||
void *object GCC_UNUSED,
|
||||
void *clientData,
|
||||
chtype key)
|
||||
{
|
||||
CDKBUTTONBOX *buttonbox = (CDKBUTTONBOX *)clientData;
|
||||
(void) injectCDKButtonbox (buttonbox, key);
|
||||
return (TRUE);
|
||||
}
|
|
@ -1,264 +0,0 @@
|
|||
/* $Id: cdktemplate.c,v 1.14 2016/12/04 15:22:16 tom Exp $ */
|
||||
|
||||
#include <cdk_test.h>
|
||||
|
||||
#ifdef XCURSES
|
||||
char *XCursesProgramName = "cdktemplate";
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Declare file local prototypes.
|
||||
*/
|
||||
static int widgetCB (EObjectType cdktype, void *object, void *clientData, chtype key);
|
||||
|
||||
/*
|
||||
* Define file local variables.
|
||||
*/
|
||||
static const char *FPUsage = "-p Plate [-o Overlay] [-P Mix Plate] [-d Default Answer] [-m Minimum Length] [-T Title] [-L Label] [-B Buttons] [-O Output file] [-X X Position] [-Y Y Position] [-N] [-S]";
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
int main (int argc, char **argv)
|
||||
{
|
||||
/* *INDENT-EQLS* */
|
||||
CDKSCREEN *cdkScreen = 0;
|
||||
CDKTEMPLATE *widget = 0;
|
||||
CDKBUTTONBOX *buttonWidget = 0;
|
||||
char *answer = 0;
|
||||
char *tmp = 0;
|
||||
char *CDK_WIDGET_COLOR = 0;
|
||||
char *temp = 0;
|
||||
chtype *holder = 0;
|
||||
int buttonCount = 0;
|
||||
int selection = 0;
|
||||
int shadowHeight = 0;
|
||||
FILE *fp = stderr;
|
||||
char **buttonList = 0;
|
||||
int j1, j2;
|
||||
|
||||
CDK_PARAMS params;
|
||||
boolean boxWidget;
|
||||
boolean mixPlate;
|
||||
boolean shadowWidget;
|
||||
char *buttons;
|
||||
char *defaultAnswer;
|
||||
char *label;
|
||||
char *my_overlay;
|
||||
char *outputFile;
|
||||
char *plate;
|
||||
char *title;
|
||||
int minimum;
|
||||
int xpos;
|
||||
int ypos;
|
||||
|
||||
CDKparseParams (argc, argv, ¶ms, "d:m:o:p:B:L:O:P:T:" CDK_MIN_PARAMS);
|
||||
|
||||
/* *INDENT-EQLS* */
|
||||
xpos = CDKparamValue (¶ms, 'X', CENTER);
|
||||
ypos = CDKparamValue (¶ms, 'Y', CENTER);
|
||||
boxWidget = CDKparamValue (¶ms, 'N', TRUE);
|
||||
shadowWidget = CDKparamValue (¶ms, 'S', FALSE);
|
||||
minimum = CDKparamValue (¶ms, 'm', 0);
|
||||
mixPlate = CDKparamValue (¶ms, 'P', FALSE);
|
||||
defaultAnswer = CDKparamString (¶ms, 'd');
|
||||
my_overlay = CDKparamString (¶ms, 'o');
|
||||
plate = CDKparamString (¶ms, 'p');
|
||||
buttons = CDKparamString (¶ms, 'B');
|
||||
label = CDKparamString (¶ms, 'L');
|
||||
outputFile = CDKparamString (¶ms, 'O');
|
||||
title = CDKparamString (¶ms, 'T');
|
||||
|
||||
/* Make sure all the command line parameters were provided. */
|
||||
if (plate == 0)
|
||||
{
|
||||
fprintf (stderr, "Usage: %s %s\n", argv[0], FPUsage);
|
||||
ExitProgram (CLI_ERROR);
|
||||
}
|
||||
|
||||
/* If the user asked for an output file, try to open it. */
|
||||
if (outputFile != 0)
|
||||
{
|
||||
if ((fp = fopen (outputFile, "w")) == 0)
|
||||
{
|
||||
fprintf (stderr, "%s: Can not open output file %s\n", argv[0], outputFile);
|
||||
ExitProgram (CLI_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
cdkScreen = initCDKScreen (NULL);
|
||||
|
||||
/* Start color. */
|
||||
initCDKColor ();
|
||||
|
||||
/* Check if the user wants to set the background of the main screen. */
|
||||
if ((temp = getenv ("CDK_SCREEN_COLOR")) != 0)
|
||||
{
|
||||
holder = char2Chtype (temp, &j1, &j2);
|
||||
wbkgd (cdkScreen->window, holder[0]);
|
||||
wrefresh (cdkScreen->window);
|
||||
freeChtype (holder);
|
||||
}
|
||||
|
||||
/* Get the widget color background color. */
|
||||
if ((CDK_WIDGET_COLOR = getenv ("CDK_WIDGET_COLOR")) == 0)
|
||||
{
|
||||
CDK_WIDGET_COLOR = 0;
|
||||
}
|
||||
|
||||
/* Create the template widget. */
|
||||
widget = newCDKTemplate (cdkScreen, xpos, ypos,
|
||||
title, label,
|
||||
plate, my_overlay,
|
||||
boxWidget, shadowWidget);
|
||||
|
||||
/* Check to make sure we created the widget. */
|
||||
if (widget == 0)
|
||||
{
|
||||
/* Shut down curses and CDK. */
|
||||
destroyCDKScreen (cdkScreen);
|
||||
endCDK ();
|
||||
|
||||
fprintf (stderr,
|
||||
"Error: Could not create the template field. "
|
||||
"Is the window too small?\n");
|
||||
|
||||
ExitProgram (CLI_ERROR);
|
||||
}
|
||||
|
||||
/* Split the buttons if they supplied some. */
|
||||
if (buttons != 0)
|
||||
{
|
||||
/* Split the button list up. */
|
||||
buttonList = CDKsplitString (buttons, '\n');
|
||||
buttonCount = (int)CDKcountStrings ((CDK_CSTRING2) buttonList);
|
||||
|
||||
/* We need to create a buttonbox widget. */
|
||||
buttonWidget = newCDKButtonbox (cdkScreen,
|
||||
getbegx (widget->win),
|
||||
(getbegy (widget->win)
|
||||
+ widget->boxHeight - 1),
|
||||
1, widget->boxWidth - 1,
|
||||
0, 1, buttonCount,
|
||||
(CDK_CSTRING2) buttonList, buttonCount,
|
||||
A_REVERSE, boxWidget, FALSE);
|
||||
setCDKButtonboxULChar (buttonWidget, ACS_LTEE);
|
||||
setCDKButtonboxURChar (buttonWidget, ACS_RTEE);
|
||||
|
||||
/*
|
||||
* We need to set the lower left and right
|
||||
* characters of the widget.
|
||||
*/
|
||||
setCDKTemplateLLChar (widget, ACS_LTEE);
|
||||
setCDKTemplateLRChar (widget, ACS_RTEE);
|
||||
|
||||
/*
|
||||
* Bind the Tab key in the widget to send a
|
||||
* Tab key to the button box widget.
|
||||
*/
|
||||
bindCDKObject (vTEMPLATE, widget, KEY_TAB, widgetCB, buttonWidget);
|
||||
bindCDKObject (vTEMPLATE, widget, CDK_NEXT, widgetCB, buttonWidget);
|
||||
bindCDKObject (vTEMPLATE, widget, CDK_PREV, widgetCB, buttonWidget);
|
||||
|
||||
/* Check if the user wants to set the background of the widget. */
|
||||
setCDKButtonboxBackgroundColor (buttonWidget, CDK_WIDGET_COLOR);
|
||||
|
||||
/* Draw the button widget. */
|
||||
drawCDKButtonbox (buttonWidget, boxWidget);
|
||||
}
|
||||
|
||||
/*
|
||||
* If the user asked for a shadow, we need to create one. Do this instead
|
||||
* of using the shadow parameter because the button widget is not part of
|
||||
* the main widget and if the user asks for both buttons and a shadow, we
|
||||
* need to create a shadow big enough for both widgets. Create the shadow
|
||||
* window using the widgets shadowWin element, so screen refreshes will draw
|
||||
* them as well.
|
||||
*/
|
||||
if (shadowWidget == TRUE)
|
||||
{
|
||||
/* Determine the height of the shadow window. */
|
||||
shadowHeight = (buttonWidget == 0 ?
|
||||
widget->boxHeight :
|
||||
widget->boxHeight + buttonWidget->boxHeight - 1);
|
||||
|
||||
/* Create the shadow window. */
|
||||
widget->shadowWin = newwin (shadowHeight,
|
||||
widget->boxWidth,
|
||||
getbegy (widget->win) + 1,
|
||||
getbegx (widget->win) + 1);
|
||||
|
||||
/* Make sure we could have created the shadow window. */
|
||||
if (widget->shadowWin != 0)
|
||||
{
|
||||
widget->shadow = TRUE;
|
||||
|
||||
/*
|
||||
* We force the widget and buttonWidget to be drawn so the
|
||||
* buttonbox widget will be drawn when the widget is activated.
|
||||
* Otherwise the shadow window will draw over the button widget.
|
||||
*/
|
||||
drawCDKTemplate (widget, ObjOf (widget)->box);
|
||||
eraseCDKButtonbox (buttonWidget);
|
||||
drawCDKButtonbox (buttonWidget, ObjOf (buttonWidget)->box);
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if the user wants to set the background of the widget. */
|
||||
setCDKTemplateBackgroundColor (widget, CDK_WIDGET_COLOR);
|
||||
|
||||
/* If a default answer were proivded, set it in the widget. */
|
||||
if (defaultAnswer != 0)
|
||||
{
|
||||
setCDKTemplateValue (widget, defaultAnswer);
|
||||
}
|
||||
|
||||
/* If the user asked for a minimum value, set it. */
|
||||
setCDKTemplateMin (widget, minimum);
|
||||
|
||||
/* Activate the widget. */
|
||||
tmp = activateCDKTemplate (widget, 0);
|
||||
|
||||
/* If the user asked for plate mixing, give it to them. */
|
||||
if (mixPlate == TRUE)
|
||||
{
|
||||
answer = mixCDKTemplate (widget);
|
||||
}
|
||||
else
|
||||
{
|
||||
answer = copyChar (tmp);
|
||||
}
|
||||
|
||||
/* If there were buttons, get the button selected. */
|
||||
if (buttonWidget != 0)
|
||||
{
|
||||
selection = buttonWidget->currentButton;
|
||||
destroyCDKButtonbox (buttonWidget);
|
||||
}
|
||||
|
||||
/* End CDK. */
|
||||
destroyCDKTemplate (widget);
|
||||
destroyCDKScreen (cdkScreen);
|
||||
endCDK ();
|
||||
|
||||
/* Print the value from the widget. */
|
||||
if (answer != 0)
|
||||
{
|
||||
fprintf (fp, "%s\n", answer);
|
||||
freeChar (answer);
|
||||
}
|
||||
fclose (fp);
|
||||
|
||||
/* Exit with the button number picked. */
|
||||
ExitProgram (selection);
|
||||
}
|
||||
|
||||
static int widgetCB (EObjectType cdktype GCC_UNUSED,
|
||||
void *object GCC_UNUSED,
|
||||
void *clientData,
|
||||
chtype key)
|
||||
{
|
||||
CDKBUTTONBOX *buttonbox = (CDKBUTTONBOX *)clientData;
|
||||
(void) injectCDKButtonbox (buttonbox, key);
|
||||
return (TRUE);
|
||||
}
|
|
@ -1,285 +0,0 @@
|
|||
/* $Id: cdkviewer.c,v 1.15 2016/12/04 15:22:16 tom Exp $ */
|
||||
|
||||
#include <cdk_test.h>
|
||||
|
||||
#ifdef XCURSES
|
||||
char *XCursesProgramName = "cdkviewer";
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Declare file local prototypes.
|
||||
*/
|
||||
static void saveInformation (CDKVIEWER *widget);
|
||||
static int dumpViewer (CDKVIEWER *widget, char *filename);
|
||||
static int widgetCB (EObjectType cdktype, void *object, void *clientData, chtype key);
|
||||
|
||||
/*
|
||||
* Define file local variables.
|
||||
*/
|
||||
static const char *FPUsage = "-f filename [-i Interpret] [-l Show Line Stats] [-T Title] [-B Buttons] [-X X Position] [-Y Y Position] [-H Height] [-W Width] [-N] [-S]";
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
int main (int argc, char **argv)
|
||||
{
|
||||
/* *INDENT-EQLS* */
|
||||
CDKSCREEN *cdkScreen = 0;
|
||||
CDKVIEWER *widget = 0;
|
||||
char *filename = 0;
|
||||
char *CDK_WIDGET_COLOR = 0;
|
||||
char *temp = 0;
|
||||
chtype *holder = 0;
|
||||
int answer = 0;
|
||||
int messageLines = -1;
|
||||
int buttonCount = 0;
|
||||
char **messageList = 0;
|
||||
char **buttonList = 0;
|
||||
char tempTitle[256];
|
||||
int j1, j2;
|
||||
|
||||
CDK_PARAMS params;
|
||||
boolean boxWidget;
|
||||
boolean interpret;
|
||||
boolean shadowWidget;
|
||||
boolean showInfoLine;
|
||||
char *buttons;
|
||||
char *title;
|
||||
int height;
|
||||
int width;
|
||||
int xpos;
|
||||
int ypos;
|
||||
|
||||
CDKparseParams (argc, argv, ¶ms, "f:il:B:T:" CDK_CLI_PARAMS);
|
||||
|
||||
/* *INDENT-EQLS* */
|
||||
xpos = CDKparamValue (¶ms, 'X', CENTER);
|
||||
ypos = CDKparamValue (¶ms, 'Y', CENTER);
|
||||
height = CDKparamValue (¶ms, 'H', 20);
|
||||
width = CDKparamValue (¶ms, 'W', 60);
|
||||
boxWidget = CDKparamValue (¶ms, 'N', TRUE);
|
||||
shadowWidget = CDKparamValue (¶ms, 'S', FALSE);
|
||||
interpret = CDKparamValue (¶ms, 'i', FALSE);
|
||||
showInfoLine = CDKparamValue (¶ms, 'l', FALSE);
|
||||
filename = CDKparamString (¶ms, 'f');
|
||||
buttons = CDKparamString (¶ms, 'B');
|
||||
title = CDKparamString (¶ms, 'T');
|
||||
|
||||
/* Make sure they gave us a file to read. */
|
||||
if (filename == 0)
|
||||
{
|
||||
fprintf (stderr, "Usage: %s %s\n", argv[0], FPUsage);
|
||||
ExitProgram (CLI_ERROR);
|
||||
}
|
||||
|
||||
/* Read the file in. */
|
||||
messageLines = CDKreadFile (filename, &messageList);
|
||||
|
||||
/* Check if there was an error. */
|
||||
if (messageLines == -1)
|
||||
{
|
||||
fprintf (stderr, "Error: Could not open the file %s\n", filename);
|
||||
ExitProgram (CLI_ERROR);
|
||||
}
|
||||
|
||||
/* Set up the buttons of the viewer. */
|
||||
if (buttons == 0)
|
||||
{
|
||||
/* *INDENT-EQLS* */
|
||||
buttonList = calloc(sizeof(char *), 3);
|
||||
buttonList[0] = copyChar ("OK");
|
||||
buttonList[1] = copyChar ("Cancel");
|
||||
buttonCount = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Split the button list up. */
|
||||
buttonList = CDKsplitString (buttons, '\n');
|
||||
buttonCount = (int)CDKcountStrings ((CDK_CSTRING2)buttonList);
|
||||
}
|
||||
|
||||
/* Set up the title of the viewer. */
|
||||
if (title == 0)
|
||||
{
|
||||
sprintf (tempTitle, "<C>Filename: </U>%s<!U>", filename);
|
||||
title = copyChar (tempTitle);
|
||||
}
|
||||
|
||||
cdkScreen = initCDKScreen (NULL);
|
||||
|
||||
/* Start color. */
|
||||
initCDKColor ();
|
||||
|
||||
/* Check if the user wants to set the background of the main screen. */
|
||||
if ((temp = getenv ("CDK_SCREEN_COLOR")) != 0)
|
||||
{
|
||||
holder = char2Chtype (temp, &j1, &j2);
|
||||
wbkgd (cdkScreen->window, holder[0]);
|
||||
wrefresh (cdkScreen->window);
|
||||
freeChtype (holder);
|
||||
}
|
||||
|
||||
/* Get the widget color background color. */
|
||||
if ((CDK_WIDGET_COLOR = getenv ("CDK_WIDGET_COLOR")) == 0)
|
||||
{
|
||||
CDK_WIDGET_COLOR = 0;
|
||||
}
|
||||
|
||||
/* Create the viewer widget. */
|
||||
widget = newCDKViewer (cdkScreen, xpos, ypos, height, width,
|
||||
(CDK_CSTRING2)buttonList, buttonCount, A_REVERSE,
|
||||
boxWidget, shadowWidget);
|
||||
|
||||
/* Check to make sure we created the file viewer. */
|
||||
if (widget == 0)
|
||||
{
|
||||
CDKfreeStrings (messageList);
|
||||
CDKfreeStrings (buttonList);
|
||||
|
||||
/* Shut down curses and CDK. */
|
||||
destroyCDKScreen (cdkScreen);
|
||||
endCDK ();
|
||||
|
||||
fprintf (stderr,
|
||||
"Error: Could not create the file viewer. "
|
||||
"Is the window too small?\n");
|
||||
|
||||
ExitProgram (CLI_ERROR);
|
||||
}
|
||||
|
||||
/* Check if the user wants to set the background of the widget. */
|
||||
setCDKViewerBackgroundColor (widget, CDK_WIDGET_COLOR);
|
||||
|
||||
/* Set a binding for saving the info. */
|
||||
bindCDKObject (vVIEWER, widget, 'S', widgetCB, 0);
|
||||
|
||||
/* Set the information needed for the viewer. */
|
||||
setCDKViewer (widget, title, (CDK_CSTRING2)messageList, messageLines,
|
||||
A_REVERSE, interpret, showInfoLine, TRUE);
|
||||
|
||||
/* Activate the viewer. */
|
||||
answer = activateCDKViewer (widget, 0);
|
||||
|
||||
CDKfreeStrings (messageList);
|
||||
CDKfreeStrings (buttonList);
|
||||
|
||||
destroyCDKViewer (widget);
|
||||
destroyCDKScreen (cdkScreen);
|
||||
endCDK ();
|
||||
|
||||
/* Exit with the button number picked. */
|
||||
ExitProgram (answer);
|
||||
}
|
||||
|
||||
/*
|
||||
* This function allows the user to dump the
|
||||
* information from the viewer into a file.
|
||||
*/
|
||||
static void saveInformation (CDKVIEWER *widget)
|
||||
{
|
||||
/* *INDENT-EQLS* */
|
||||
CDKENTRY *entry = 0;
|
||||
char *filename = 0;
|
||||
char temp[256];
|
||||
const char *mesg[10];
|
||||
int linesSaved;
|
||||
|
||||
/* Create the entry field to get the filename. */
|
||||
entry = newCDKEntry (ScreenOf (widget), CENTER, CENTER,
|
||||
"<C></B/5>Enter the filename of the save file.",
|
||||
"Filename: ",
|
||||
A_NORMAL, '_', vMIXED,
|
||||
20, 1, 256,
|
||||
TRUE, FALSE);
|
||||
|
||||
/* Get the filename. */
|
||||
filename = activateCDKEntry (entry, 0);
|
||||
|
||||
/* Did they hit escape? */
|
||||
if (entry->exitType == vESCAPE_HIT)
|
||||
{
|
||||
/* Popup a message. */
|
||||
mesg[0] = "<C></B/5>Save Canceled.";
|
||||
mesg[1] = "<C>Escape hit. Scrolling window information not saved.";
|
||||
mesg[2] = " ";
|
||||
mesg[3] = "<C>Press any key to continue.";
|
||||
popupLabel (ScreenOf (widget), (CDK_CSTRING2)mesg, 4);
|
||||
|
||||
destroyCDKEntry (entry);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Write the contents of the viewer to the file. */
|
||||
linesSaved = dumpViewer (widget, filename);
|
||||
|
||||
/* Was the save successful? */
|
||||
if (linesSaved == -1)
|
||||
{
|
||||
/* Nope, tell 'em. */
|
||||
mesg[0] = "<C></B/16>Error";
|
||||
mesg[1] = "<C>Could not save to the file.";
|
||||
sprintf (temp, "<C>(%s)", filename);
|
||||
mesg[2] = temp;
|
||||
mesg[3] = " ";
|
||||
mesg[4] = "<C>Press any key to continue.";
|
||||
popupLabel (ScreenOf (widget), (CDK_CSTRING2)mesg, 5);
|
||||
}
|
||||
else
|
||||
{
|
||||
char *msg_1;
|
||||
|
||||
mesg[0] = "<C></B/5>Save Successful";
|
||||
sprintf (temp, "<C>There were %d lines saved to the file", linesSaved);
|
||||
mesg[1] = msg_1 = copyChar (temp);
|
||||
sprintf (temp, "<C>(%s)", filename);
|
||||
mesg[2] = temp;
|
||||
mesg[3] = " ";
|
||||
mesg[4] = "<C>Press any key to continue.";
|
||||
popupLabel (ScreenOf (widget), (CDK_CSTRING2)mesg, 5);
|
||||
freeChar (msg_1);
|
||||
}
|
||||
|
||||
destroyCDKEntry (entry);
|
||||
eraseCDKScreen (ScreenOf (widget));
|
||||
drawCDKScreen (ScreenOf (widget));
|
||||
}
|
||||
|
||||
/*
|
||||
* This actually dumps the information from the viewer to a file.
|
||||
*/
|
||||
static int dumpViewer (CDKVIEWER *widget, char *filename)
|
||||
{
|
||||
/* *INDENT-EQLS* */
|
||||
FILE *outputFile = 0;
|
||||
char *rawLine = 0;
|
||||
int listSize;
|
||||
chtype **list = getCDKViewerInfo (widget, &listSize);
|
||||
int x;
|
||||
|
||||
/* Try to open the file. */
|
||||
if ((outputFile = fopen (filename, "w")) == 0)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Start writing out the file. */
|
||||
for (x = 0; x < listSize; x++)
|
||||
{
|
||||
rawLine = chtype2Char (list[x]);
|
||||
fprintf (outputFile, "%s\n", rawLine);
|
||||
freeChar (rawLine);
|
||||
}
|
||||
|
||||
/* Close the file and return the number of lines written. */
|
||||
fclose (outputFile);
|
||||
return listSize;
|
||||
}
|
||||
|
||||
static int widgetCB (EObjectType cdktype GCC_UNUSED, void *object,
|
||||
void *clientData GCC_UNUSED,
|
||||
chtype key GCC_UNUSED)
|
||||
{
|
||||
CDKVIEWER *widget = (CDKVIEWER *)object;
|
||||
saveInformation (widget);
|
||||
return (TRUE);
|
||||
}
|
|
@ -1,116 +0,0 @@
|
|||
#!/bin/sh
|
||||
# $Id: alphalist.sh,v 1.7 2005/12/27 16:04:57 tom Exp $
|
||||
|
||||
#
|
||||
# Description:
|
||||
# This demonstrates the CDK command line
|
||||
# interface to the alphalist widget.
|
||||
#
|
||||
|
||||
#
|
||||
# This gets the password file.
|
||||
#
|
||||
getPasswordFile()
|
||||
{
|
||||
system=$1
|
||||
file=$2
|
||||
|
||||
#
|
||||
# Depeding on the system, get the password file
|
||||
# using nicat, ypcat, or just plain old /etc/passwd
|
||||
#
|
||||
if [ "$system" = "NIS" ]; then
|
||||
niscat passwd.org_dir > $file
|
||||
elif [ "$system" = "YP" ]; then
|
||||
ypcat passwd > $file
|
||||
else
|
||||
cp /etc/passwd $file
|
||||
fi
|
||||
}
|
||||
|
||||
#
|
||||
# This displays account information.
|
||||
#
|
||||
displayAccountInformation()
|
||||
{
|
||||
userAccount=$1
|
||||
passwordFile=$2
|
||||
|
||||
#
|
||||
# Get the user account information.
|
||||
#
|
||||
line=`grep "^${userAccount}" $passwordFile`
|
||||
uid=`echo $line | cut -d: -f3`
|
||||
gid=`echo $line | cut -d: -f4`
|
||||
info=`echo $line | cut -d: -f5`
|
||||
home=`echo $line | cut -d: -f6`
|
||||
shell=`echo $line | cut -d: -f7`
|
||||
|
||||
#
|
||||
# Create the label message information.
|
||||
#
|
||||
accountMessage="<C></U>Account
|
||||
<C><#HL(30)>
|
||||
Account: </U>${userAccount}
|
||||
UID : </U>${uid}
|
||||
GID : </U>${gid}
|
||||
Info : </U>${info}
|
||||
Home : </U>${home}
|
||||
Shell : </U>${shell}
|
||||
<C><#HL(30)>
|
||||
<C>Hit </R>space<!R> to continue"
|
||||
|
||||
#
|
||||
# Create the popup label.
|
||||
#
|
||||
${CDK_LABEL} -m "${accountMessage}" -p " "
|
||||
}
|
||||
|
||||
#
|
||||
# Create some global variables.
|
||||
#
|
||||
CDK_ALPHALIST="${CDK_BINDIR=..}/cdkalphalist"
|
||||
CDK_LABEL="${CDK_BINDIR=..}/cdklabel"
|
||||
|
||||
tmpPass="${TMPDIR=/tmp}/sl.$$"
|
||||
output="${TMPDIR=/tmp}/alphalist.$$"
|
||||
userAccounts="${TMPDIR=/tmp}/ua.$$"
|
||||
|
||||
#
|
||||
# Create the message for the scrolling list.
|
||||
#
|
||||
title="<C>Pick an account
|
||||
<C>you want to view."
|
||||
|
||||
#
|
||||
# Get the password file and stick it into the temp file.
|
||||
#
|
||||
#getPasswordFile "YP" "$tmpPass"
|
||||
#getPasswordFile "NIS" "$tmpPass"
|
||||
getPasswordFile "Other" "$tmpPass"
|
||||
|
||||
#
|
||||
# Get the user account from the password file.
|
||||
#
|
||||
awk 'BEGIN {FS=":"} {printf "%s\n", $1}' $tmpPass | sort > ${userAccounts}
|
||||
|
||||
#
|
||||
# Create the scrolling list.
|
||||
#
|
||||
${CDK_ALPHALIST} -T "${title}" -f ${userAccounts} -H -10 -W -20 2> ${output}
|
||||
selected=$?
|
||||
test $selected = 255 && exit 1
|
||||
|
||||
answer=`sed -e 's/^[ ]*//' -e 's/[ ]*$//' ${output}`
|
||||
|
||||
#
|
||||
# Display the account information.
|
||||
#
|
||||
if [ -n "$answer" ]; then
|
||||
displayAccountInformation $answer $tmpPass
|
||||
fi
|
||||
|
||||
#
|
||||
# Clean up.
|
||||
#
|
||||
rm -f ${output} ${tmpPass} ${userAccounts}
|
|
@ -1,89 +0,0 @@
|
|||
#!/bin/sh
|
||||
# $Id: calendar.sh,v 1.3 2005/12/27 15:53:06 tom Exp $
|
||||
|
||||
#
|
||||
# Description:
|
||||
# This demonstrates the CDK command line
|
||||
# interface to the celendar widget.
|
||||
#
|
||||
|
||||
#
|
||||
# Create some global variables.
|
||||
#
|
||||
CDK_CALENDAR="${CDK_BINDIR=..}/cdkcalendar"
|
||||
CDK_LABEL="${CDK_BINDIR=..}/cdklabel"
|
||||
|
||||
date="${TMPDIR=/tmp}/cal.$$"
|
||||
tmp="${TMPDIR=/tmp}/tmp.$$"
|
||||
|
||||
xpos=CENTER
|
||||
ypos=CENTER
|
||||
|
||||
#
|
||||
# Get today's date.
|
||||
#
|
||||
day=`date +%d`
|
||||
month=`date +%m`
|
||||
year=`date +%Y`
|
||||
|
||||
#
|
||||
# Chop up the command line.
|
||||
#
|
||||
set -- `getopt d:m:y:X:Y: $*`
|
||||
if [ $? != 0 ]
|
||||
then
|
||||
echo $USAGE
|
||||
exit 2
|
||||
fi
|
||||
for c in $*
|
||||
do
|
||||
case $c in
|
||||
-d) day=$2; shift 2;;
|
||||
-m) month=$2; shift 2;;
|
||||
-y) year=$2; shift 2;;
|
||||
-X) xpos=$2; shift 2;;
|
||||
-Y) ypos=$2; shift 2;;
|
||||
--) shift; break;;
|
||||
esac
|
||||
done
|
||||
|
||||
#
|
||||
# Create the title and buttons.
|
||||
#
|
||||
title="<C><#HL(22)>
|
||||
<C>Select a date
|
||||
<C><#HL(22)>"
|
||||
buttons=" OK
|
||||
Cancel "
|
||||
|
||||
#
|
||||
# Create the calendar widget.
|
||||
#
|
||||
${CDK_CALENDAR} -B "${buttons}" -d ${day} -m ${month} -y ${year} -T "${title}" -X ${xpos} -Y ${ypos} -O ${date} -S
|
||||
selected=$?
|
||||
test $selected = 255 && exit 1
|
||||
|
||||
answer=`cat ${date}`
|
||||
|
||||
#
|
||||
# Create the message for the label widget.
|
||||
#
|
||||
echo "<C>You chose the following date" > ${tmp}
|
||||
echo " " >> ${tmp}
|
||||
echo "<C><#HL(10)>" >> ${tmp}
|
||||
echo "<C>${answer}" >> ${tmp}
|
||||
echo "<C><#HL(10)>" >> ${tmp}
|
||||
echo " " >> ${tmp}
|
||||
echo "<C>You chose button #${selected}" >> ${tmp}
|
||||
echo " " >> ${tmp}
|
||||
echo "<C>Hit </R>space<!R> to continue." >> ${tmp}
|
||||
|
||||
#
|
||||
# Create the label widget to display the information.
|
||||
#
|
||||
${CDK_LABEL} -f ${tmp} -p " "
|
||||
|
||||
#
|
||||
# Clean up.
|
||||
#
|
||||
rm -f ${tmp} ${date}
|
|
@ -1,88 +0,0 @@
|
|||
#!/bin/sh
|
||||
# $Id: dialog.sh,v 1.3 2005/12/27 15:53:06 tom Exp $
|
||||
|
||||
#
|
||||
# Description:
|
||||
# This demonstrates the CDK command line
|
||||
# interface to the dialog widget.
|
||||
#
|
||||
|
||||
#
|
||||
# Create some global variables.
|
||||
#
|
||||
CDK_DIALOG="${CDK_BINDIR=..}/cdkdialog"
|
||||
CDK_LABEL="${CDK_BINDIR=..}/cdklabel"
|
||||
|
||||
output="${TMPDIR=/tmp}/dialog_output.$$"
|
||||
tmp="${TMPDIR=/tmp}/tmp.$$"
|
||||
|
||||
#
|
||||
# Create the message for the scrolling list.
|
||||
#
|
||||
message="<C>Pick which command
|
||||
<C>you wish to run."
|
||||
|
||||
#
|
||||
# Create the button labels.
|
||||
#
|
||||
commands="</B>who
|
||||
</B>w
|
||||
</B>uptime
|
||||
</B>date
|
||||
</B>pwd
|
||||
</B>whoami
|
||||
</B>df
|
||||
</B>fortune"
|
||||
|
||||
#
|
||||
# Create the dialog box.
|
||||
#
|
||||
${CDK_DIALOG} -m "${message}" -B "${commands}" 2> ${output}
|
||||
selection=$?
|
||||
if [ "$selection" -eq 255 ]; then
|
||||
exit;
|
||||
fi
|
||||
|
||||
#
|
||||
# Create the message for the label widget.
|
||||
#
|
||||
echo "<C>Here is the result of the command" > ${tmp}
|
||||
echo " " >> ${tmp}
|
||||
|
||||
#
|
||||
# Determine which command to run.
|
||||
#
|
||||
if [ "${selection}" -eq 0 ]; then
|
||||
who | awk '{printf "</B>%s\n", $0}' >> ${tmp}
|
||||
elif [ "${selection}" -eq 1 ]; then
|
||||
w | awk '{printf "</B>%s\n", $0}' >> ${tmp}
|
||||
elif [ "${selection}" -eq 2 ]; then
|
||||
uptime | awk '{printf "<C></B>%s\n", $0}' >> ${tmp}
|
||||
elif [ "${selection}" -eq 3 ]; then
|
||||
date | awk '{printf "<C></B>%s\n", $0}' >> ${tmp}
|
||||
elif [ "${selection}" -eq 4 ]; then
|
||||
pwd | awk '{printf "<C></B>%s\n", $0}' >> ${tmp}
|
||||
elif [ "${selection}" -eq 5 ]; then
|
||||
whoami | awk '{printf "<C></B>%s\n", $0}' >> ${tmp}
|
||||
elif [ "${selection}" -eq 6 ]; then
|
||||
#
|
||||
# We will use the label demo to do this.
|
||||
#
|
||||
./label.sh
|
||||
rm -f ${tmp} ${output} ${fileSystemList}
|
||||
exit 0;
|
||||
elif [ "${selection}" -eq 7 ]; then
|
||||
fortune | awk '{printf "</B>%s\n", $0}' >> ${tmp}
|
||||
fi
|
||||
echo " " >> ${tmp}
|
||||
echo "<C>Hit </R>space<!R> to continue." >> ${tmp}
|
||||
|
||||
#
|
||||
# Create the label widget to display the information.
|
||||
#
|
||||
${CDK_LABEL} -f ${tmp} -p " "
|
||||
|
||||
#
|
||||
# Clean up.
|
||||
#
|
||||
rm -f ${tmp} ${output} ${fileSystemList}
|
|
@ -1,54 +0,0 @@
|
|||
#!/bin/sh
|
||||
# $Id: entry.sh,v 1.3 2005/12/27 15:53:06 tom Exp $
|
||||
|
||||
#
|
||||
# Description:
|
||||
# This demonstrates the CDK command line
|
||||
# interface to the entry widget.
|
||||
#
|
||||
|
||||
#
|
||||
# Create some global variables.
|
||||
#
|
||||
CDK_ENTRY="${CDK_BINDIR=..}/cdkentry"
|
||||
CDK_LABEL="${CDK_BINDIR=..}/cdklabel"
|
||||
|
||||
output="${TMPDIR=/tmp}/entry_output.$$"
|
||||
tmp="${TMPDIR=/tmp}/tmp.$$"
|
||||
|
||||
#
|
||||
# Create the title.
|
||||
#
|
||||
title="<C> Type a simple string. "
|
||||
buttons=" OK
|
||||
Cancel "
|
||||
|
||||
#
|
||||
# Create the entry box.
|
||||
#
|
||||
${CDK_ENTRY} -f 20 -T "${title}" -B "${buttons}" -F "</5>_ " -O ${output} -S
|
||||
selected=$?
|
||||
test $selected = 255 && exit 1
|
||||
|
||||
answer=`cat ${output}`
|
||||
|
||||
#
|
||||
# Create the message for the label widget.
|
||||
#
|
||||
echo "<C>Here is the string you typed in" > ${tmp}
|
||||
echo " " >> ${tmp}
|
||||
echo "<C></R>${answer}" >> ${tmp}
|
||||
echo " " >> ${tmp}
|
||||
echo "<C>You chose button #${selected}" >> ${tmp}
|
||||
echo " " >> ${tmp}
|
||||
echo "<C>Hit </R>space<!R> to continue." >> ${tmp}
|
||||
|
||||
#
|
||||
# Create the label widget to display the information.
|
||||
#
|
||||
${CDK_LABEL} -f ${tmp} -p " "
|
||||
|
||||
#
|
||||
# Clean up.
|
||||
#
|
||||
rm -f ${tmp} ${output}
|
|
@ -1,82 +0,0 @@
|
|||
#!/bin/sh
|
||||
# $Id: fselect.sh,v 1.4 2005/12/27 17:56:05 tom Exp $
|
||||
|
||||
#
|
||||
# Description:
|
||||
# This demonstrates the CDK command line
|
||||
# interface to the file selection widget.
|
||||
#
|
||||
|
||||
#
|
||||
# Create some global variables.
|
||||
#
|
||||
CDK_FSELECT="${CDK_BINDIR=..}/cdkfselect"
|
||||
CDK_LABEL="${CDK_BINDIR=..}/cdklabel"
|
||||
|
||||
directory="."
|
||||
label="File: "
|
||||
title="<C>Select a file"
|
||||
|
||||
buttons=" OK
|
||||
Cancel "
|
||||
|
||||
xpos="CENTER"
|
||||
ypos="CENTER"
|
||||
|
||||
width=0
|
||||
height=-5
|
||||
|
||||
tmp="${TMPDIR=/tmp}/tmp.$$"
|
||||
file="${TMPDIR=/tmp}/fs.$$"
|
||||
|
||||
#
|
||||
# Chop up the command line.
|
||||
#
|
||||
set -- `getopt d:L:T:X:Y:W:H: $*`
|
||||
if [ $? != 0 ]
|
||||
then
|
||||
echo $USAGE
|
||||
exit 2
|
||||
fi
|
||||
for c in $*
|
||||
do
|
||||
case $c in
|
||||
-d) directory=$2; shift 2;;
|
||||
-T) title=$2; shift 2;;
|
||||
-L) label=$2; shift 2;;
|
||||
-X) xpos=$2; shift 2;;
|
||||
-Y) ypos=$2; shift 2;;
|
||||
-W) width=$2; shift 2;;
|
||||
-H) height=$2; shift 2;;
|
||||
--) shift; break;;
|
||||
esac
|
||||
done
|
||||
|
||||
#
|
||||
# Create the CDK file selector.
|
||||
#
|
||||
${CDK_FSELECT} -d "${directory}" -T "${title}" -L "${label}" -X ${xpos} -Y ${ypos} -W ${width} -H ${height} -B "${buttons}" 2> ${file}
|
||||
selected=$?
|
||||
test $selected = 255 && exit 1
|
||||
|
||||
answer=`cat ${file}`
|
||||
|
||||
#
|
||||
# Diplay the file the user selected.
|
||||
#
|
||||
echo "<C>You selected the following file" > ${tmp}
|
||||
echo " " >> ${tmp}
|
||||
echo "<C><#HL(10)>" >> ${tmp}
|
||||
echo "<C></B>${answer}" >> ${tmp}
|
||||
echo "<C><#HL(10)>" >> ${tmp}
|
||||
echo " " >> ${tmp}
|
||||
echo "<C>You chose button #${selected}" >> ${tmp}
|
||||
echo " " >> ${tmp}
|
||||
echo "<C>Press </R>space<!R> to continue." >> ${tmp}
|
||||
|
||||
${CDK_LABEL} -f ${tmp} -p " "
|
||||
|
||||
#
|
||||
# Clean up.
|
||||
#
|
||||
rm -f ${tmp} ${file}
|
|
@ -1,135 +0,0 @@
|
|||
#!/bin/sh
|
||||
# $Id: itemlist.sh,v 1.3 2005/12/27 15:53:06 tom Exp $
|
||||
|
||||
#
|
||||
# Description:
|
||||
# This demonstrates the CDK command line
|
||||
# interface to the itemlist list widget.
|
||||
#
|
||||
|
||||
#
|
||||
# This gets the password file.
|
||||
#
|
||||
getPasswordFile()
|
||||
{
|
||||
system=$1
|
||||
file=$2
|
||||
|
||||
#
|
||||
# Depeding on the system, get the password file
|
||||
# using nicat, ypcat, or just plain old /etc/passwd
|
||||
#
|
||||
if [ "$system" = "NIS" ]; then
|
||||
niscat passwd.org_dir | sort > $file
|
||||
elif [ "$system" = "YP" ]; then
|
||||
ypcat passwd | sort > $file
|
||||
else
|
||||
sort /etc/passwd > $file
|
||||
fi
|
||||
}
|
||||
|
||||
#
|
||||
# This displays account information.
|
||||
#
|
||||
displayAccountInformation()
|
||||
{
|
||||
userAccount=$1
|
||||
passwordFile=$2
|
||||
|
||||
#
|
||||
# Get the user account information.
|
||||
#
|
||||
line=`grep "^${userAccount}" $passwordFile`
|
||||
uid=`echo $line | cut -d: -f3`
|
||||
gid=`echo $line | cut -d: -f4`
|
||||
info=`echo $line | cut -d: -f5`
|
||||
home=`echo $line | cut -d: -f6`
|
||||
shell=`echo $line | cut -d: -f7`
|
||||
|
||||
#
|
||||
# Create the label message information.
|
||||
#
|
||||
accountMessage="<C></U>Account
|
||||
<C><#HL(30)>
|
||||
Account: </U>${userAccount}
|
||||
UID : </U>${uid}
|
||||
GID : </U>${gid}
|
||||
Info : </U>${info}
|
||||
Home : </U>${home}
|
||||
Shell : </U>${shell}
|
||||
<C><#HL(30)>
|
||||
<C>Hit </R>space<!R> to continue"
|
||||
|
||||
#
|
||||
# Create the popup label.
|
||||
#
|
||||
${CDK_LABEL} -m "${accountMessage}" -p " "
|
||||
}
|
||||
|
||||
#
|
||||
# Create some global variables.
|
||||
#
|
||||
CDK_ITEMLIST="${CDK_BINDIR=..}/cdkitemlist"
|
||||
CDK_LABEL="${CDK_BINDIR=..}/cdklabel"
|
||||
|
||||
tmpPass="${TMPDIR=/tmp}/sl.$$"
|
||||
output="${TMPDIR=/tmp}/output.$$"
|
||||
userAccounts="${TMPDIR=/tmp}/ua.$$"
|
||||
|
||||
TYPE="Other";
|
||||
|
||||
#
|
||||
# Chop up the command line.
|
||||
#
|
||||
set -- `getopt nNh $*`
|
||||
if [ $? != 0 ]
|
||||
then
|
||||
echo $USAGE
|
||||
exit 2
|
||||
fi
|
||||
for c in $*
|
||||
do
|
||||
case $c in
|
||||
-n) TYPE="YP"; shift;;
|
||||
-N) TYPE="NIS"; shift;;
|
||||
-h) echo "$0 [-n YP] [-N NIS+] [-h]"; exit 0;;
|
||||
--) shift; break;;
|
||||
esac
|
||||
done
|
||||
|
||||
#
|
||||
# Create the message for the item list.
|
||||
#
|
||||
title="<C>Pick an account you want to view."
|
||||
label="Account Name "
|
||||
buttons=" OK
|
||||
Cancel "
|
||||
|
||||
#
|
||||
# Get the password file and stick it into the temp file.
|
||||
#
|
||||
getPasswordFile "${TYPE}" "$tmpPass"
|
||||
|
||||
#
|
||||
# Get the user account from the password file.
|
||||
#
|
||||
awk 'BEGIN {FS=":"} {printf "</R>%s\n", $1}' $tmpPass | sort > ${userAccounts}
|
||||
|
||||
#
|
||||
# Create the item list.
|
||||
#
|
||||
${CDK_ITEMLIST} -d 3 -L "${label}" -T "${title}" -B "${buttons}" -f "${userAccounts}" 2> ${output}
|
||||
selected=$?
|
||||
test $selected = 255 && exit 1
|
||||
|
||||
answer=`cat ${output}`
|
||||
|
||||
#
|
||||
# Display the account information.
|
||||
#
|
||||
displayAccountInformation $answer $tmpPass
|
||||
|
||||
#
|
||||
# Clean up.
|
||||
#
|
||||
rm -f ${output} ${tmpPass} ${userAccounts}
|
|
@ -1,81 +0,0 @@
|
|||
#!/bin/sh
|
||||
# $Id: label.sh,v 1.3 2005/12/27 15:53:06 tom Exp $
|
||||
|
||||
#
|
||||
# Description:
|
||||
# This demonstrates the CDK command line
|
||||
# interface to the label widget.
|
||||
#
|
||||
|
||||
#
|
||||
# Create some global variables.
|
||||
#
|
||||
CDK_LABEL="${CDK_BINDIR=..}/cdklabel"
|
||||
|
||||
dfTmp="${TMPDIR=/tmp}/label.$$"
|
||||
tmp="${TMPDIR=/tmp}/tmp.$$"
|
||||
top="${TMPDIR=/tmp}/dfTop.$$"
|
||||
bottom="${TMPDIR=/tmp}/dfBottom.$$"
|
||||
|
||||
#
|
||||
# Get the filesystem information.
|
||||
#
|
||||
getDiskInfo()
|
||||
{
|
||||
fileName=$1;
|
||||
command="df"
|
||||
|
||||
#
|
||||
# Determine the type of operating system.
|
||||
#
|
||||
machine=`uname -s`
|
||||
if [ "$machine" = "SunOS" ]; then
|
||||
level=`uname -r`
|
||||
|
||||
if [ "$level" -gt 4 ]; then
|
||||
command="df -kl"
|
||||
fi
|
||||
else
|
||||
if [ "$machine" = "AIX" ]; then
|
||||
command="df -i"
|
||||
fi
|
||||
fi
|
||||
|
||||
#
|
||||
# Run the command.
|
||||
#
|
||||
${command} > ${fileName}
|
||||
}
|
||||
|
||||
#
|
||||
# Get the disk information.
|
||||
#
|
||||
getDiskInfo ${dfTmp}
|
||||
|
||||
#
|
||||
# Bold the first line of the df command.
|
||||
#
|
||||
head -1 ${dfTmp} | awk '{printf "</B>%s\n", $0}' > ${top}
|
||||
tail +2 ${dfTmp} > ${bottom}
|
||||
|
||||
#
|
||||
# Create the message for the label widget.
|
||||
#
|
||||
echo "<C>This is the current" > ${tmp}
|
||||
echo "<C>status of your local filesystems." >> ${tmp}
|
||||
echo "<C><#HL(2)>" >> ${tmp}
|
||||
cat ${top} >> ${tmp}
|
||||
cat ${bottom} >> ${tmp}
|
||||
echo "<C><#HL(2)>" >> ${tmp}
|
||||
echo "" >> ${tmp}
|
||||
echo "<C>Hit </R>space<!R> to continue." >> ${tmp}
|
||||
|
||||
#
|
||||
# Create the label widget to display the information.
|
||||
#
|
||||
${CDK_LABEL} -f "${tmp}" -p " " -c "ls" -S
|
||||
|
||||
#
|
||||
# Clean up.
|
||||
#
|
||||
rm -f ${tmp} ${output} ${dfTmp} ${top} ${bottom}
|
|
@ -1,123 +0,0 @@
|
|||
#!/bin/sh
|
||||
# $Id: matrix.sh,v 1.4 2005/12/27 17:07:00 tom Exp $
|
||||
|
||||
#
|
||||
# Description:
|
||||
# This demonstrates the CDK command line
|
||||
# interface to the matrix widget.
|
||||
#
|
||||
|
||||
#
|
||||
# Create some global variables.
|
||||
#
|
||||
CDK_MATRIX="${CDK_BINDIR=..}/cdkmatrix"
|
||||
CDK_LABEL="${CDK_BINDIR=..}/cdklabel"
|
||||
|
||||
fileSystemList="${TMPDIR=/tmp}/fsList.$$"
|
||||
info="${TMPDIR=/tmp}/fsInfo.$$"
|
||||
diskInfo="${TMPDIR=/tmp}/diskInfo.$$"
|
||||
tmp="${TMPDIR=/tmp}/tmp.$$"
|
||||
|
||||
#
|
||||
# Get the filesystem information.
|
||||
#
|
||||
getDiskInfo()
|
||||
{
|
||||
fileName=$1;
|
||||
command="df"
|
||||
|
||||
#
|
||||
# Determine the type of operating system.
|
||||
#
|
||||
machine=`uname -s`
|
||||
if [ "$machine" = "SunOS" ]; then
|
||||
level=`uname -r`
|
||||
|
||||
if [ "$level" -gt 4 ]; then
|
||||
command="df -kl"
|
||||
fi
|
||||
else
|
||||
if [ "$machine" = "AIX" ]; then
|
||||
command="df -i"
|
||||
fi
|
||||
fi
|
||||
|
||||
#
|
||||
# Run the command.
|
||||
#
|
||||
${command} > ${fileName}
|
||||
}
|
||||
|
||||
#
|
||||
# Get the disk information.
|
||||
#
|
||||
getDiskInfo ${diskInfo}
|
||||
|
||||
#
|
||||
# Create the row titles.
|
||||
#
|
||||
rowTitles=`tail +2 ${diskInfo} | awk '{printf "%s\n", $1}'`
|
||||
|
||||
#
|
||||
# Create the column titles.
|
||||
#
|
||||
colTitles="KBytes
|
||||
Used
|
||||
Avail
|
||||
Capacity
|
||||
Mounted on"
|
||||
|
||||
#
|
||||
# Define the matrix title.
|
||||
#
|
||||
title="<C></U>Current Filesystem Information"
|
||||
|
||||
#
|
||||
# Create the data file to fill in the matrix.
|
||||
#
|
||||
tail +2 ${diskInfo} | awk '{printf "%s%s%s%s%s\n", $2, $3, $4, $5, $6}' > ${info}
|
||||
|
||||
#
|
||||
# Set the widths of the columns.
|
||||
#
|
||||
colWidths="5
|
||||
5
|
||||
5
|
||||
5
|
||||
5"
|
||||
|
||||
#
|
||||
# Set the cells as uneditable.
|
||||
#
|
||||
types="VIEWONLY
|
||||
VIEWONLY
|
||||
VIEWONLY
|
||||
VIEWONLY
|
||||
VIEWONLY"
|
||||
|
||||
buttons=" OK
|
||||
Cancel "
|
||||
|
||||
#
|
||||
# Start the matrix.
|
||||
#
|
||||
${CDK_MATRIX} -r "${rowTitles}" -c "${colTitles}" -v 3 -w "${colWidths}" -d "${info}" -t "${types}" -T "${title}" -B "${buttons}" -O"$tmp"
|
||||
selected=$?
|
||||
test $selected = 255 && exit 1
|
||||
|
||||
#
|
||||
# Create the message for the label widget.
|
||||
#
|
||||
echo "<C>You chose button #${selected}" > ${tmp}
|
||||
echo " " >> ${tmp}
|
||||
echo "<C>Hit </R>space<!R> to continue." >> ${tmp}
|
||||
|
||||
#
|
||||
# Create the label widget to display the information.
|
||||
#
|
||||
${CDK_LABEL} -f "${tmp}" -p " "
|
||||
|
||||
#
|
||||
# Clean up.
|
||||
#
|
||||
rm -f ${info} ${fileSystemList} ${tmp} ${diskInfo}
|
|
@ -1,54 +0,0 @@
|
|||
#!/bin/sh
|
||||
# $Id: mentry.sh,v 1.3 2005/12/27 15:53:06 tom Exp $
|
||||
|
||||
#
|
||||
# Description:
|
||||
# This demonstrates the CDK command line
|
||||
# interface to the multiple line entry widget.
|
||||
#
|
||||
|
||||
#
|
||||
# Create some global variables.
|
||||
#
|
||||
CDK_MENTRY="${CDK_BINDIR=..}/cdkmentry"
|
||||
CDK_LABEL="${CDK_BINDIR=..}/cdklabel"
|
||||
|
||||
output="${TMPDIR=/tmp}/mentry_output.$$"
|
||||
tmp="${TMPDIR=/tmp}/tmp.$$"
|
||||
|
||||
#
|
||||
# Create the title.
|
||||
#
|
||||
title="<C>Type in a short message."
|
||||
buttons=" OK
|
||||
Cancel "
|
||||
|
||||
#
|
||||
# Create the mentry box.
|
||||
#
|
||||
${CDK_MENTRY} -s 5 -v 10 -f 20 -T "${title}" -B "${buttons}" -F '_' -O ${output}
|
||||
selected=$?
|
||||
test $selected = 255 && exit 1
|
||||
|
||||
answer=`cat ${output}`
|
||||
|
||||
#
|
||||
# Create the message for the label widget.
|
||||
#
|
||||
echo "<C>Here is the message you typed in" > ${tmp}
|
||||
echo " " >> ${tmp}
|
||||
echo "<C></R>${answer}" >> ${tmp}
|
||||
echo " " >> ${tmp}
|
||||
echo "<C>You chose button #${selected}" >> ${tmp}
|
||||
echo " " >> ${tmp}
|
||||
echo "<C>Hit </R>space<!R> to continue." >> ${tmp}
|
||||
|
||||
#
|
||||
# Create the label widget to display the information.
|
||||
#
|
||||
${CDK_LABEL} -f ${tmp} -p " "
|
||||
|
||||
#
|
||||
# Clean up.
|
||||
#
|
||||
rm -f ${tmp} ${output}
|
|
@ -1,95 +0,0 @@
|
|||
#!/bin/sh
|
||||
# $Id: radio.sh,v 1.3 2005/12/27 15:53:06 tom Exp $
|
||||
|
||||
#
|
||||
# Description:
|
||||
# This demonstrates the CDK command line
|
||||
# interface to the radio widget.
|
||||
#
|
||||
|
||||
#
|
||||
# Create some global variables.
|
||||
#
|
||||
CDK_RADIO="${CDK_BINDIR=..}/cdkradio"
|
||||
CDK_LABEL="${CDK_BINDIR=..}/cdklabel"
|
||||
|
||||
fileSystemList="${TMPDIR=/tmp}/fsList.$$"
|
||||
diskInfo="${TMPDIR=/tmp}/diskInfo.$$"
|
||||
output="${TMPDIR=/tmp}/radio_output.$$"
|
||||
tmp="${TMPDIR=/tmp}/tmp.$$"
|
||||
|
||||
#
|
||||
# Get the filesystem information.
|
||||
#
|
||||
getDiskInfo()
|
||||
{
|
||||
fileName=$1;
|
||||
command="df"
|
||||
|
||||
#
|
||||
# Determine the type of operating system.
|
||||
#
|
||||
machine=`uname -s`
|
||||
if [ "$machine" = "SunOS" ]; then
|
||||
level=`uname -r`
|
||||
|
||||
if [ "$level" -gt 4 ]; then
|
||||
command="df -kl"
|
||||
fi
|
||||
else
|
||||
if [ "$machine" = "AIX" ]; then
|
||||
command="df -i"
|
||||
fi
|
||||
fi
|
||||
|
||||
#
|
||||
# Run the command.
|
||||
#
|
||||
${command} > ${fileName}
|
||||
}
|
||||
|
||||
#
|
||||
# Create the title for the scrolling list.
|
||||
#
|
||||
title="<C>Pick a filesystem to view."
|
||||
buttons=" OK
|
||||
Cancel "
|
||||
|
||||
#
|
||||
# Get a list of the local filesystems.
|
||||
#
|
||||
getDiskInfo ${diskInfo}
|
||||
|
||||
#
|
||||
# Create the file system list.
|
||||
#
|
||||
grep "^/" ${diskInfo} | awk '{printf "%s\n", $1}' > ${fileSystemList}
|
||||
|
||||
#
|
||||
# Create the radio list.
|
||||
#
|
||||
${CDK_RADIO} -T "${title}" -f "${fileSystemList}" -c "</U>*" -B "${buttons}" 2> $output
|
||||
selected=$?
|
||||
test $selected = 255 && exit 1
|
||||
|
||||
#
|
||||
# The selection is now in the file $output.
|
||||
#
|
||||
fs=`cat ${output}`
|
||||
echo "<C></R>File Statistics on the filesystem ${fs}" > ${tmp}
|
||||
echo " " >> ${tmp}
|
||||
grep "${fs}" ${diskInfo} | awk '{printf "</B>%s\n", $0}' >> ${tmp}
|
||||
echo " " >> ${tmp}
|
||||
echo "<C>You chose button #${selected}" >> ${tmp}
|
||||
echo " " >> ${tmp}
|
||||
echo "<C>Hit </R>space<!R> to continue." >> ${tmp}
|
||||
|
||||
#
|
||||
# Create the label widget to display the information.
|
||||
#
|
||||
${CDK_LABEL} -f ${tmp} -p " "
|
||||
|
||||
#
|
||||
# Clean up.
|
||||
#
|
||||
rm -f ${tmp} ${output} ${fileSystemList} ${diskInfo}
|
|
@ -1,55 +0,0 @@
|
|||
#!/bin/sh
|
||||
# $Id: scale.sh,v 1.3 2005/12/27 15:53:06 tom Exp $
|
||||
|
||||
#
|
||||
# Description:
|
||||
# This demonstrates the CDK command line
|
||||
# interface to the scale widget.
|
||||
#
|
||||
|
||||
#
|
||||
# Create some global variables.
|
||||
#
|
||||
CDK_SCALE="${CDK_BINDIR=..}/cdkscale"
|
||||
CDK_LABEL="${CDK_BINDIR=..}/cdklabel"
|
||||
|
||||
output="${TMPDIR=/tmp}/scale_output.$$"
|
||||
tmp="${TMPDIR=/tmp}/tmp.$$"
|
||||
|
||||
#
|
||||
# Create the title.
|
||||
#
|
||||
title="<C>Enter a value using the cursor keys."
|
||||
label="</R>Value"
|
||||
buttons=" OK
|
||||
Cancel "
|
||||
|
||||
#
|
||||
# Create the scale box.
|
||||
#
|
||||
${CDK_SCALE} -f 20 -l 0 -h 100 -i 5 -L "${label}" -T "${title}" -B "${buttons}" -O ${output}
|
||||
selected=$?
|
||||
test $selected = 255 && exit 1
|
||||
|
||||
answer=`cat ${output}`
|
||||
|
||||
#
|
||||
# Create the message for the label widget.
|
||||
#
|
||||
echo "<C>Here is the value you selected" > ${tmp}
|
||||
echo " " >> ${tmp}
|
||||
echo "<C></R>${answer}" >> ${tmp}
|
||||
echo " " >> ${tmp}
|
||||
echo "<C>You chose button #${selected}" >> ${tmp}
|
||||
echo " " >> ${tmp}
|
||||
echo "<C>Hit </R>space<!R> to continue." >> ${tmp}
|
||||
|
||||
#
|
||||
# Create the label widget to display the information.
|
||||
#
|
||||
${CDK_LABEL} -f ${tmp} -p " "
|
||||
|
||||
#
|
||||
# Clean up.
|
||||
#
|
||||
rm -f ${tmp} ${output}
|
|
@ -1,136 +0,0 @@
|
|||
#!/bin/sh
|
||||
# $Id: scroll.sh,v 1.3 2005/12/27 15:53:06 tom Exp $
|
||||
|
||||
#
|
||||
# Description:
|
||||
# This demonstrates the CDK command line
|
||||
# interface to the scrolling list widget.
|
||||
#
|
||||
|
||||
#
|
||||
# This gets the password file.
|
||||
#
|
||||
getPasswordFile()
|
||||
{
|
||||
system=$1
|
||||
file=$2
|
||||
|
||||
#
|
||||
# Depeding on the system, get the password file
|
||||
# using nicat, ypcat, or just plain old /etc/passwd
|
||||
#
|
||||
if [ "$system" = "NIS" ]; then
|
||||
niscat passwd.org_dir > $file
|
||||
elif [ "$system" = "YP" ]; then
|
||||
ypcat passwd > $file
|
||||
else
|
||||
cp /etc/passwd $file
|
||||
fi
|
||||
}
|
||||
|
||||
#
|
||||
# This displays account information.
|
||||
#
|
||||
displayAccountInformation()
|
||||
{
|
||||
userAccount=$1
|
||||
passwordFile=$2
|
||||
|
||||
#
|
||||
# Get the user account information.
|
||||
#
|
||||
line=`grep "^${userAccount}" $passwordFile`
|
||||
uid=`echo $line | cut -d: -f3`
|
||||
gid=`echo $line | cut -d: -f4`
|
||||
info=`echo $line | cut -d: -f5`
|
||||
home=`echo $line | cut -d: -f6`
|
||||
shell=`echo $line | cut -d: -f7`
|
||||
|
||||
#
|
||||
# Create the label message information.
|
||||
#
|
||||
accountMessage="<C></U>Account
|
||||
<C><#HL(30)>
|
||||
Account: </U>${userAccount}
|
||||
UID : </U>${uid}
|
||||
GID : </U>${gid}
|
||||
Info : </U>${info}
|
||||
Home : </U>${home}
|
||||
Shell : </U>${shell}
|
||||
<C><#HL(30)>
|
||||
<C>Hit </R>space<!R> to continue"
|
||||
|
||||
#
|
||||
# Create the popup label.
|
||||
#
|
||||
${CDK_LABEL} -m "${accountMessage}" -p " "
|
||||
}
|
||||
|
||||
#
|
||||
# Create some global variables.
|
||||
#
|
||||
CDK_SCROLL="${CDK_BINDIR=..}/cdkscroll"
|
||||
CDK_LABEL="${CDK_BINDIR=..}/cdklabel"
|
||||
|
||||
tmpPass="${TMPDIR=/tmp}/sl.$$"
|
||||
output="${TMPDIR=/tmp}/output.$$"
|
||||
userAccounts="${TMPDIR=/tmp}/ua.$$"
|
||||
|
||||
TYPE="Other"
|
||||
|
||||
#
|
||||
# Chop up the command line.
|
||||
#
|
||||
set -- `getopt nNh $*`
|
||||
if [ $? != 0 ]
|
||||
then
|
||||
echo $USAGE
|
||||
exit 2
|
||||
fi
|
||||
for c in $*
|
||||
do
|
||||
case $c in
|
||||
-n) TYPE="YP"; shift;;
|
||||
-N) TYPE="NIS"; shift;;
|
||||
-h) echo "$0 [-n YP] [-N NIS+] [-h]"; exit 0;;
|
||||
--) shift; break;;
|
||||
esac
|
||||
done
|
||||
|
||||
#
|
||||
# Create the message for the scrolling list.
|
||||
#
|
||||
title="<C><#HL(30)>
|
||||
<C>Pick an account you want to view.
|
||||
<C><#HL(30)>"
|
||||
buttons=" OK
|
||||
Cancel "
|
||||
|
||||
#
|
||||
# Get the password file and stick it into the temp file.
|
||||
#
|
||||
getPasswordFile "${TYPE}" "$tmpPass"
|
||||
|
||||
#
|
||||
# Get the user account from the password file.
|
||||
#
|
||||
awk 'BEGIN {FS=":"} {printf "%s\n", $1}' $tmpPass | sort > ${userAccounts}
|
||||
|
||||
#
|
||||
# Create the scrolling list.
|
||||
#
|
||||
${CDK_SCROLL} -T "${title}" -f ${userAccounts} -n -B "${buttons}" 2> ${output}
|
||||
selected=$?
|
||||
test $selected = 255 && exit 1
|
||||
|
||||
answer=`cat ${output}`
|
||||
|
||||
#
|
||||
# Display the account information.
|
||||
#
|
||||
displayAccountInformation $answer $tmpPass
|
||||
|
||||
#
|
||||
# Clean up.
|
||||
#
|
||||
rm -f ${output} ${tmpPass} ${userAccounts}
|
|
@ -1,191 +0,0 @@
|
|||
#!/bin/sh
|
||||
# $Id: selection.sh,v 1.4 2005/12/27 17:56:58 tom Exp $
|
||||
|
||||
#
|
||||
# Description:
|
||||
# This demonstrates the CDK command line
|
||||
# interface to the selection widget.
|
||||
#
|
||||
|
||||
#
|
||||
# This gets the password file.
|
||||
#
|
||||
getPasswordFile()
|
||||
{
|
||||
system=$1
|
||||
file=$2
|
||||
|
||||
#
|
||||
# Depending on the system, get the password file
|
||||
# using nicat, ypcat, or just plain old /etc/passwd
|
||||
#
|
||||
if [ "$system" = "NIS" ]; then
|
||||
niscat passwd.org_dir > $file
|
||||
elif [ "$system" = "YP" ]; then
|
||||
ypcat passwd > $file
|
||||
else
|
||||
cp /etc/passwd $file
|
||||
fi
|
||||
}
|
||||
|
||||
#
|
||||
# This displays account information.
|
||||
#
|
||||
displayAccountInformation()
|
||||
{
|
||||
totalSelections=$1
|
||||
currentSelection=$2
|
||||
userAccount=$3
|
||||
passwordFile=$4
|
||||
|
||||
#
|
||||
# Get the user account information.
|
||||
#
|
||||
line=`grep "^${userAccount}" $passwordFile`
|
||||
uid=`echo $line | cut -d: -f3`
|
||||
gid=`echo $line | cut -d: -f4`
|
||||
info=`echo $line | cut -d: -f5`
|
||||
home=`echo $line | cut -d: -f6`
|
||||
shell=`echo $line | cut -d: -f7`
|
||||
|
||||
#
|
||||
# Create the label message information.
|
||||
#
|
||||
accountMessage="<C></U>Account ${currentSelection}/${totalSelections}
|
||||
<C><#HL(30)>
|
||||
Account: </U>${userAccount}
|
||||
UID : </U>${uid}
|
||||
GID : </U>${gid}
|
||||
Info : </U>${info}
|
||||
Home : </U>${home}
|
||||
Shell : </U>${shell}
|
||||
<C><#HL(30)>
|
||||
<C>Hit </R>space<!R> to continue"
|
||||
|
||||
#
|
||||
# Create the popup label.
|
||||
#
|
||||
${CDK_LABEL} -m "${accountMessage}" -p " "
|
||||
}
|
||||
|
||||
#
|
||||
# Define where the CDK widgets are.
|
||||
#
|
||||
CDK_SELECTION="${CDK_BINDIR=..}/cdkselection"
|
||||
CDK_LABEL="${CDK_BINDIR=..}/cdklabel"
|
||||
|
||||
TYPE="Other"
|
||||
|
||||
#
|
||||
# Define the output files.
|
||||
#
|
||||
accountList="${TMPDIR=/tmp}/accList.$$"
|
||||
userAccounts="${TMPDIR=/tmp}/userAccList.$$"
|
||||
output="${TMPDIR=/tmp}/selection_output.$$"
|
||||
tmpPass="${TMPDIR=/tmp}/ps.$$"
|
||||
tmp="${TMPDIR=/tmp}/tmp.$$"
|
||||
|
||||
#
|
||||
# Chop up the command line.
|
||||
#
|
||||
set -- `getopt nNh $*`
|
||||
if [ $? != 0 ]
|
||||
then
|
||||
echo $USAGE
|
||||
exit 2
|
||||
fi
|
||||
for c in $*
|
||||
do
|
||||
case $c in
|
||||
-n) TYPE="YP"; shift;;
|
||||
-N) TYPE="NIS"; shift;;
|
||||
-h) echo "$0 [-n YP] [-N NIS+] [-h]"; exit 0;;
|
||||
--) shift; break;;
|
||||
esac
|
||||
done
|
||||
|
||||
#
|
||||
# Create the message for the selection list.
|
||||
#
|
||||
title="<C>Pick a user account to view."
|
||||
|
||||
#
|
||||
# Get the password file and stick it into the temp file.
|
||||
#
|
||||
getPasswordFile "${TYPE}" "$tmpPass"
|
||||
|
||||
#
|
||||
# Create the user account list.
|
||||
#
|
||||
awk 'BEGIN {FS=":"} {printf "%s\n", $1}' $tmpPass | sort > ${userAccounts}
|
||||
awk '{printf "<C></B>%s\n", $1}' ${userAccounts} > ${accountList}
|
||||
accounts=`cat ${userAccounts}`
|
||||
|
||||
#
|
||||
# Create the choices list.
|
||||
#
|
||||
choices="<C></B>No
|
||||
<C></B> Yes "
|
||||
buttons=" OK
|
||||
Cancel "
|
||||
|
||||
#
|
||||
# Create the selection list.
|
||||
#
|
||||
${CDK_SELECTION} -T "${title}" -f "${accountList}" -c "${choices}" -B "${buttons}" 2> $output
|
||||
selected=$?
|
||||
test $selected = 255 && exit 1
|
||||
|
||||
#
|
||||
# Initialize the variables.
|
||||
#
|
||||
selection=""
|
||||
value=""
|
||||
|
||||
#
|
||||
# Count how many were selected.
|
||||
#
|
||||
count=`grep -c "^1" ${output}`
|
||||
current=0
|
||||
|
||||
#
|
||||
# Create the label.
|
||||
#
|
||||
for i in `cat ${output}`
|
||||
do
|
||||
#
|
||||
# Since every other variable is value/selection, we
|
||||
# store every other value in the correct variable.
|
||||
#
|
||||
if [ "$value" = "" ]; then
|
||||
value="$i"
|
||||
else
|
||||
selection="$i"
|
||||
|
||||
#
|
||||
# Only display the selected accounts.
|
||||
#
|
||||
if [ "$value" -eq 1 ]; then
|
||||
#
|
||||
# Increment our counter.
|
||||
#
|
||||
current=`expr $current + 1`
|
||||
|
||||
#
|
||||
# Display the account information.
|
||||
#
|
||||
displayAccountInformation $count $current $selection $tmpPass
|
||||
fi
|
||||
|
||||
#
|
||||
# Reset the variables.
|
||||
#
|
||||
value=""
|
||||
selection=""
|
||||
fi
|
||||
done
|
||||
|
||||
#
|
||||
# Clean up.
|
||||
#
|
||||
rm -f ${accountList} ${userAccounts} ${output} ${tmpPass} ${tmp}
|
|
@ -1,55 +0,0 @@
|
|||
#!/bin/sh
|
||||
# $Id: slider.sh,v 1.4 2005/12/27 15:53:06 tom Exp $
|
||||
|
||||
#
|
||||
# Description:
|
||||
# This demonstrates the CDK command line
|
||||
# interface to the slider widget.
|
||||
#
|
||||
|
||||
#
|
||||
# Create some global variables.
|
||||
#
|
||||
CDK_SLIDER="${CDK_BINDIR=..}/cdkslider"
|
||||
CDK_LABEL="${CDK_BINDIR=..}/cdklabel"
|
||||
|
||||
output="${TMPDIR=/tmp}/slider_output.$$"
|
||||
tmp="${TMPDIR=/tmp}/tmp.$$"
|
||||
|
||||
#
|
||||
# Create the title.
|
||||
#
|
||||
title="<C>Enter a value using the cursor keys"
|
||||
label="Value: "
|
||||
buttons=" OK
|
||||
Cancel "
|
||||
|
||||
#
|
||||
# Create the slider box.
|
||||
#
|
||||
${CDK_SLIDER} -f 20 -l 0 -h 100 -i 5 -L "${label}" -T "${title}" -F "</R>*" -B "${buttons}" -O ${output}
|
||||
selected=$?
|
||||
test $selected = 255 && exit 1
|
||||
|
||||
answer=`cat ${output}`
|
||||
|
||||
#
|
||||
# Create the message for the label widget.
|
||||
#
|
||||
echo "<C>Here is the value you selected" > ${tmp}
|
||||
echo " " >> ${tmp}
|
||||
echo "<C></R>${answer}" >> ${tmp}
|
||||
echo " " >> ${tmp}
|
||||
echo "<C>You chose button #${selected}" >> ${tmp}
|
||||
echo " " >> ${tmp}
|
||||
echo "<C>Hit </R>space<!R> to continue." >> ${tmp}
|
||||
|
||||
#
|
||||
# Create the label widget to display the information.
|
||||
#
|
||||
${CDK_LABEL} -f ${tmp} -p " "
|
||||
|
||||
#
|
||||
# Clean up.
|
||||
#
|
||||
rm -f ${tmp} ${output}
|
|
@ -1,55 +0,0 @@
|
|||
#!/bin/sh
|
||||
# $Id: template.sh,v 1.3 2005/12/27 15:53:06 tom Exp $
|
||||
|
||||
#
|
||||
# Description:
|
||||
# This demonstrates the CDK command line
|
||||
# interface to the template widget.
|
||||
#
|
||||
|
||||
#
|
||||
# Create some global variables.
|
||||
#
|
||||
CDK_TEMPLATE="${CDK_BINDIR=..}/cdktemplate"
|
||||
CDK_LABEL="${CDK_BINDIR=..}/cdklabel"
|
||||
|
||||
output="${TMPDIR=/tmp}/template_output.$$"
|
||||
tmp="${TMPDIR=/tmp}/tmp.$$"
|
||||
|
||||
#
|
||||
# Create the title.
|
||||
#
|
||||
title="<C> Type in the
|
||||
<C>IP Address for this machine."
|
||||
buttons=" OK
|
||||
Cancel "
|
||||
|
||||
#
|
||||
# Create the template box.
|
||||
#
|
||||
${CDK_TEMPLATE} -p "###.###.###.###" -o "___.___.___.___" -T "${title}" -P -B "${buttons}" 2> ${output}
|
||||
selected=$?
|
||||
test $selected = 255 && exit 1
|
||||
|
||||
answer=`cat ${output}`
|
||||
|
||||
#
|
||||
# Create the message for the label widget.
|
||||
#
|
||||
echo "<C>Here is the IP you typed in" > ${tmp}
|
||||
echo " " >> ${tmp}
|
||||
echo "<C></R>${answer}" >> ${tmp}
|
||||
echo " " >> ${tmp}
|
||||
echo "<C>You chose button #${selected}" >> ${tmp}
|
||||
echo " " >> ${tmp}
|
||||
echo "<C>Hit </R>space<!R> to continue." >> ${tmp}
|
||||
|
||||
#
|
||||
# Create the label widget to display the information.
|
||||
#
|
||||
${CDK_LABEL} -f ${tmp} -p " "
|
||||
|
||||
#
|
||||
# Clean up.
|
||||
#
|
||||
rm -f ${tmp} ${output}
|
|
@ -1,76 +0,0 @@
|
|||
#!/bin/sh
|
||||
# $Id: viewer.sh,v 1.3 2005/12/27 15:53:06 tom Exp $
|
||||
|
||||
#
|
||||
# Description:
|
||||
# This demonstrates the CDK command line
|
||||
# interface to the viewer widget.
|
||||
#
|
||||
|
||||
#
|
||||
# Create some global variables.
|
||||
#
|
||||
CDK_FSELECT="${CDK_BINDIR=..}/cdkfselect"
|
||||
CDK_VIEWER="${CDK_BINDIR=..}/cdkviewer"
|
||||
|
||||
tmp="${TMPDIR=/tmp}/tmp.$$"
|
||||
file="${TMPDIR=/tmp}/fs.$$"
|
||||
|
||||
directory="."
|
||||
xpos=CENTER
|
||||
ypos=CENTER
|
||||
width="-2"
|
||||
height="0"
|
||||
interpret=0
|
||||
|
||||
#
|
||||
# Chop up the command line.
|
||||
#
|
||||
set -- `getopt d:x:y:w:h:i $*`
|
||||
if [ $? != 0 ]
|
||||
then
|
||||
echo $USAGE
|
||||
exit 2
|
||||
fi
|
||||
for c in $*
|
||||
do
|
||||
case $c in
|
||||
-d) directory=$2; shift 2;;
|
||||
-x) xpos=$2; shift 2;;
|
||||
-y) ypos=$2; shift 2;;
|
||||
-w) width=$2; shift 2;;
|
||||
-h) height=$2; shift 2;;
|
||||
-i) interpret=1; shift 1;;
|
||||
--) shift; break;;
|
||||
esac
|
||||
done
|
||||
|
||||
#
|
||||
# Create the CDK file selector.
|
||||
#
|
||||
${CDK_FSELECT} -T "<C>Select a file" -d "${directory}" 2> ${file}
|
||||
selected=$?
|
||||
test $selected = 255 && exit 1
|
||||
|
||||
answer=`cat ${file}`
|
||||
|
||||
#
|
||||
# Create the title and buttons for the viewer.
|
||||
#
|
||||
title="<C>CDK File Viewer Widget
|
||||
<C></U>${answer}"
|
||||
buttons="OK"
|
||||
|
||||
#
|
||||
# Create the file viewer.
|
||||
#
|
||||
if [ "$interpret" -eq 1 ]; then
|
||||
${CDK_VIEWER} -f "${answer}" -T "${title}" -B "${buttons}" -i -X ${xpos} -Y ${ypos} -H "${height}" -W "${width}"
|
||||
else
|
||||
${CDK_VIEWER} -f "${answer}" -T "${title}" -B "${buttons}" -X ${xpos} -Y ${ypos} -H "${height}" -W "${width}" -B "${buttons}"
|
||||
fi
|
||||
|
||||
#
|
||||
# Clean up.
|
||||
#
|
||||
rm -f ${tmp} ${file}
|
|
@ -1,686 +0,0 @@
|
|||
#!/bin/sh
|
||||
# $Id: adduser,v 1.3 2002/07/16 22:24:53 tom Exp $
|
||||
|
||||
#
|
||||
# Written by: Mike Glover, March 1997
|
||||
# E-mail : vexus@home.com, glover@credit.erin.utoronto.ca
|
||||
#
|
||||
# Purpose:
|
||||
# This is a graphical adduser program. The widgets are
|
||||
# the CDK command line widgets provided by the CDK
|
||||
# distribution. If you have any questions about CDK,
|
||||
# or the command line widgets please feel free to mail
|
||||
# me at one of the two above addresses.
|
||||
#
|
||||
|
||||
#
|
||||
# Copyright 2000, Mike Glover
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
# 1. Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
# 3. All advertising materials mentioning features or use of this software
|
||||
# must display the following acknowledgment:
|
||||
# This product includes software developed by Mike Glover
|
||||
# and contributors.
|
||||
# 4. Neither the name of Mike Glover nor the names of contributors
|
||||
# may be used to endorse or promote products derived from this software
|
||||
# without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY MIKE GLOVER AND CONTRIBUTORS ``AS IS'' AND
|
||||
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
# ARE DISCLAIMED. IN NO EVENT SHALL MIKE GLOVER OR CONTRIBUTORS BE LIABLE
|
||||
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
# SUCH DAMAGE.
|
||||
#
|
||||
|
||||
#
|
||||
# Set the screen and widget colors.
|
||||
#
|
||||
CDK_WIDGET_COLOR="</5>"; export CDK_WIDGET_COLOR
|
||||
CDK_SCREEN_COLOR="</1>"; export CDK_SCREEN_COLOR
|
||||
|
||||
#
|
||||
# Set up some variables.
|
||||
#
|
||||
CDK_DIALOG="../cdkdialog"
|
||||
CDK_ENTRY="../cdkentry"
|
||||
CDK_SCROLL="../cdkscroll"
|
||||
tmpFile="/tmp/tmp.$$"
|
||||
tmpInfo="/tmp/adduserInfo.$$"
|
||||
shellFile="/tmp/shells.$$"
|
||||
ACCOUNT_SHELL=""
|
||||
ACCOUNT_INFO=""
|
||||
ACCOUNT_NAME=""
|
||||
ACCOUNT_HOME=""
|
||||
ACCOUNT_GID=""
|
||||
ACCOUNT_UID=""
|
||||
GROUP_NAME=""
|
||||
CURRENT_FUNCTION=1;
|
||||
|
||||
#
|
||||
# This quits the program.
|
||||
#
|
||||
quitProgram()
|
||||
{
|
||||
#
|
||||
# The person has decided to quit.
|
||||
#
|
||||
buttons="< OK >"
|
||||
message="<C></B><#HL(30)>
|
||||
<C></B>Add New User Canceled
|
||||
<C></B>Program exiting
|
||||
<C></B><#HL(30)>"
|
||||
${CDK_DIALOG} -m "${message}" -B "${buttons}" -N 2> /dev/null
|
||||
exit;
|
||||
}
|
||||
|
||||
#
|
||||
# This warns the user to what is about to happen. It
|
||||
# gives them a safe 'out'
|
||||
#
|
||||
warnUser()
|
||||
{
|
||||
#
|
||||
# Pop up a little message telling the user what is
|
||||
# about to happen.
|
||||
#
|
||||
message="<C></B>Adding New User
|
||||
|
||||
You are about to add a new user. If you do not want to
|
||||
do this, move the cursor to the cancel button and hit
|
||||
return. This will exit this program. Otherwise hit
|
||||
return to continue."
|
||||
buttons="< OK >
|
||||
< Cancel >"
|
||||
${CDK_DIALOG} -m "${message}" -B "${buttons}" 2> /dev/null
|
||||
if [ $? -ne 0 ]; then
|
||||
quitProgram;
|
||||
fi
|
||||
}
|
||||
|
||||
#
|
||||
# This gets the account name from the user.
|
||||
#
|
||||
getAccountName()
|
||||
{
|
||||
#
|
||||
# Keep doing this until we hit an account which does not
|
||||
# already exist.
|
||||
#
|
||||
count=1;
|
||||
while [ $count -ne 0 ]; do
|
||||
#
|
||||
# Get the account name from the user.
|
||||
#
|
||||
buttons="Next
|
||||
Cancel"
|
||||
label="</24/B>Account Name: "
|
||||
title="<C></B>Account Name
|
||||
|
||||
<C>The name is the identity of the account which the
|
||||
<C>user will use to access the system.
|
||||
|
||||
"
|
||||
|
||||
${CDK_ENTRY} -i "${ACCOUNT_NAME}" -f 15 -m 3 -F "</56/B>_" -T "${title}" -L "${label}" -B "${buttons}" 2> ${tmpFile}
|
||||
selected=$?
|
||||
ACCOUNT_NAME=`cat ${tmpFile}`
|
||||
|
||||
#
|
||||
# Check the selected button.
|
||||
#
|
||||
if [ $selected -eq 0 ]; then
|
||||
DIRECTION=1; export DIRECTION;
|
||||
else
|
||||
quitProgram;
|
||||
fi
|
||||
|
||||
#
|
||||
# Look for the account name in the password file.
|
||||
#
|
||||
count=`grep -c "^${ACCOUNT_NAME}" /etc/passwd`
|
||||
if [ ${count} -eq 1 ]; then
|
||||
buttons="< OK >"
|
||||
message="<C></B>Account Found
|
||||
|
||||
<C>The account you provided
|
||||
<C></B>${ACCOUNT_NAME}
|
||||
<C>already exists in the password file. Please pick
|
||||
<C>another account name."
|
||||
${CDK_DIALOG} -m "${message}" -B "${buttons}" 2> /dev/null
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
#
|
||||
# This gets the account information.
|
||||
#
|
||||
getAccountInfo()
|
||||
{
|
||||
#
|
||||
# Set up the entry field.
|
||||
#
|
||||
buttons="Next
|
||||
Previous
|
||||
Cancel"
|
||||
label="</24/B>Personal Info: "
|
||||
title="<C></B>Account Information.
|
||||
|
||||
Enter in </B>${ACCOUNT_NAME}<!B>'s personal information. This is usually the
|
||||
account holders name, phone number, or extension. This is fairly freeform.
|
||||
The only character you can not use is a colon (:). If you do all colons will
|
||||
be stripped out by this process.
|
||||
|
||||
"
|
||||
${CDK_ENTRY} -f 40 -i "${ACCOUNT_INFO}" -F "</56/B>_" -T "${title}" -L "${label}" -B "${buttons}" 2> ${tmpFile}
|
||||
selected=$?
|
||||
ACCOUNT_INFO=`cat ${tmpFile} | tr ':' ' '`
|
||||
|
||||
#
|
||||
# Check the selected button.
|
||||
#
|
||||
if [ $selected -eq 0 ]; then
|
||||
DIRECTION=1; export DIRECTION;
|
||||
elif [ $selected -eq 1 ]; then
|
||||
DIRECTION=-1; export DIRECTION;
|
||||
return;
|
||||
else
|
||||
quitProgram;
|
||||
fi
|
||||
}
|
||||
|
||||
#
|
||||
# This gets the account GID.
|
||||
#
|
||||
getAccountGID()
|
||||
{
|
||||
#
|
||||
# Get the 'users' GID from /etc/group.
|
||||
#
|
||||
if [ "$ACCOUNT_GID" = "" ]; then
|
||||
count=`grep -c "^users" /etc/group`
|
||||
if [ $count -eq 0 ]; then
|
||||
USER_GID="100";
|
||||
else
|
||||
USER_GID=`grep "^users" /etc/group | cut -d: -f3`
|
||||
fi
|
||||
else
|
||||
USER_GID="$ACCOUNT_GID";
|
||||
fi
|
||||
|
||||
#
|
||||
# Keep doing this until we get a GID which exists.
|
||||
#
|
||||
count=0;
|
||||
while [ $count -eq 0 ]; do
|
||||
#
|
||||
# Get the GID.
|
||||
#
|
||||
buttons="Next
|
||||
Previous
|
||||
Cancel"
|
||||
label="</24/B>Account GID: "
|
||||
title="<C></B>Account GID
|
||||
|
||||
The GID (Group IDentification) must be a number which already
|
||||
exists in the /etc/group file. The default group </B>users<!B>
|
||||
has been provided for you.
|
||||
|
||||
"
|
||||
${CDK_ENTRY} -f 6 -m 1 -i "${USER_GID}" -F "</56/B>_" -T "${title}" -L "${label}" -B "${buttons}" 2> ${tmpFile}
|
||||
selected=$?
|
||||
ACCOUNT_GID=`cat ${tmpFile}`
|
||||
|
||||
#
|
||||
# Check the selected button.
|
||||
#
|
||||
if [ $selected -eq 0 ]; then
|
||||
DIRECTION=1; export DIRECTION;
|
||||
elif [ $selected -eq 1 ]; then
|
||||
DIRECTION=-1; export DIRECTION;
|
||||
return;
|
||||
else
|
||||
quitProgram;
|
||||
fi
|
||||
|
||||
#
|
||||
# Look for GID in the /etc/group
|
||||
#
|
||||
count=`grep -c ".*:.*:${ACCOUNT_GID}:" /etc/group`
|
||||
if [ ${count} -eq 0 ]; then
|
||||
buttons="< OK >"
|
||||
message="<C></B>Error: No Such GID
|
||||
|
||||
<C>The GID you provided does not exist.
|
||||
<C>Please pick a GID which does exist.
|
||||
"
|
||||
${CDK_DIALOG} -m "${message}" -B "${buttons}" 2> /dev/null
|
||||
if [ $? -ne 0 ]; then
|
||||
quitProgram;
|
||||
fi
|
||||
else
|
||||
#
|
||||
# Get the group name for later.
|
||||
#
|
||||
GROUP_NAME=`grep ".*:.*:${ACCOUNT_GID}:" /etc/group | cut -d: -f1`
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
#
|
||||
# This gets the account UID.
|
||||
#
|
||||
getAccountUID()
|
||||
{
|
||||
#
|
||||
# Try to find the next available UID.
|
||||
#
|
||||
if [ "$ACCOUNT_UID" = "" ]; then
|
||||
nextUID=`awk 'BEGIN {FS=":"} {print $3}' /etc/passwd | sort -n | grep -v "65535" | tail -1`
|
||||
nextUID=`expr $nextUID + 1`
|
||||
else
|
||||
nextUID="$ACCOUNT_UID"
|
||||
fi
|
||||
|
||||
#
|
||||
# Keep doing this until we get a UID which does not exist.
|
||||
#
|
||||
count=1;
|
||||
while [ $count -ne 0 ]; do
|
||||
#
|
||||
# Get the UID.
|
||||
#
|
||||
buttons="Next
|
||||
Previous
|
||||
Cancel"
|
||||
label="</24/B>Account UID: "
|
||||
title="<C></B>Account UID
|
||||
|
||||
The UID (User IDentification) must be a number which does not
|
||||
already exist in the /etc/passwd file. The value filled in is
|
||||
the next available UID found from the password file.
|
||||
|
||||
"
|
||||
${CDK_ENTRY} -f 6 -i "${nextUID}" -m 1 -F "</56/B>_" -T "${title}" -L "${label}" -B "${buttons}" 2> ${tmpFile}
|
||||
selected=$?
|
||||
ACCOUNT_UID=`cat ${tmpFile}`
|
||||
|
||||
#
|
||||
# Check the selected button.
|
||||
#
|
||||
if [ $selected -eq 0 ]; then
|
||||
DIRECTION=1; export DIRECTION;
|
||||
elif [ $selected -eq 1 ]; then
|
||||
DIRECTION=-1; export DIRECTION;
|
||||
return;
|
||||
else
|
||||
quitProgram;
|
||||
fi
|
||||
|
||||
#
|
||||
# Look for UID in the /etc/passwd
|
||||
#
|
||||
count=`grep -c ".*:.*:${ACCOUNT_UID}:" /etc/passwd`
|
||||
if [ ${count} -ne 0 ]; then
|
||||
owner=`grep ".*:.*:${ACCOUNT_UID}:" /etc/passwd | head -1 |cut -d: -f1`
|
||||
buttons="< OK >"
|
||||
message="<C></B>Error: Duplicate UID
|
||||
|
||||
<C>The UID you provided is already owned by
|
||||
<C>the account </B>$owner<!B>. Please pick a
|
||||
<C>UID which does not already exist.
|
||||
"
|
||||
${CDK_DIALOG} -m "${message}" -B "${buttons}" 2> /dev/null
|
||||
if [ $? -ne 0 ]; then
|
||||
quitProgram;
|
||||
fi
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
#
|
||||
# This gets the account home directory.
|
||||
#
|
||||
getAccountHome()
|
||||
{
|
||||
if [ "${ACCOUNT_HOME}" = "" ]; then
|
||||
defaultHome="/home/${ACCOUNT_NAME}"
|
||||
else
|
||||
defaultHome="${ACCOUNT_HOME}"
|
||||
fi
|
||||
|
||||
#
|
||||
# Set up the entry field.
|
||||
#
|
||||
buttons="Next
|
||||
Previous
|
||||
Cancel"
|
||||
label="</24/B>Home Directory: "
|
||||
title="<C></B>Account Home Directory.
|
||||
|
||||
Enter in the account's home directory. If the directory
|
||||
does not currently exist, it will be created in the account
|
||||
creation phase of this process. A reasonable default value
|
||||
for the home directory has been provided.
|
||||
|
||||
"
|
||||
${CDK_ENTRY} -f 20 -F "</56/B>_" -i "${defaultHome}" -T "${title}" -L "${label}" -B "${buttons}" 2> ${tmpFile}
|
||||
selected=$?
|
||||
ACCOUNT_HOME=`cat ${tmpFile}`
|
||||
|
||||
#
|
||||
# Check the selected button.
|
||||
#
|
||||
if [ $selected -eq 0 ]; then
|
||||
DIRECTION=1; export DIRECTION;
|
||||
elif [ $selected -eq 1 ]; then
|
||||
DIRECTION=-1; export DIRECTION;
|
||||
return;
|
||||
else
|
||||
quitProgram;
|
||||
fi
|
||||
}
|
||||
|
||||
#
|
||||
# This gets the shell the user want to assign to
|
||||
# the account.
|
||||
#
|
||||
getAccountShell()
|
||||
{
|
||||
count=0;
|
||||
|
||||
while [ "$count" -eq 0 ]; do
|
||||
#
|
||||
# Get the shell they want to use.
|
||||
#
|
||||
buttons="Next
|
||||
Previous
|
||||
Cancel"
|
||||
title="<C>Account Shell
|
||||
|
||||
Pick one of the shells to use. If you want to use a
|
||||
custom shell, pick </B>Custom<!B> and you will be
|
||||
prompted for it's path.
|
||||
"
|
||||
echo "Custom" > ${shellFile}
|
||||
cat /etc/shells >> ${shellFile}
|
||||
${CDK_SCROLL} -H 5 -W 10 -T "${title}" -f ${shellFile} -B "${buttons}" 2> ${tmpFile}
|
||||
selected=$?
|
||||
ACCOUNT_SHELL=`cat ${tmpFile}`
|
||||
|
||||
#
|
||||
# Check the selected buttons.
|
||||
#
|
||||
if [ $selected -eq 0 ]; then
|
||||
DIRECTION=1; export DIRECTION;
|
||||
count=1;
|
||||
elif [ $selected -eq 1 ]; then
|
||||
DIRECTION=-1; export DIRECTION;
|
||||
return;
|
||||
else
|
||||
quitProgram;
|
||||
fi
|
||||
|
||||
#
|
||||
# Check the answer.
|
||||
#
|
||||
if [ "$ACCOUNT_SHELL" = "Custom" ]; then
|
||||
#
|
||||
# Get the shell from the user.
|
||||
#
|
||||
buttons="Next
|
||||
Previuous
|
||||
Cancel"
|
||||
label="</24/B>Shell Pathname: "
|
||||
title="<C></B>Custom Account Shell
|
||||
|
||||
Enter in the path to the custom shell. The authenticity
|
||||
of the shell will not be checked here. It is assumed that
|
||||
the shell will exist when the account is ready to be used.
|
||||
|
||||
"
|
||||
${CDK_ENTRY} -f 20 -F "</56/B>_" -T "${title}" -L "${label}" -B "${buttons}" 2> ${tmpFile}
|
||||
selected=$?
|
||||
ACCOUNT_SHELL=`cat ${tmpFile}`
|
||||
|
||||
#
|
||||
# Check the selected buttons.
|
||||
#
|
||||
if [ $selected -eq 0 ]; then
|
||||
DIRECTION=1; export DIRECTION;
|
||||
count=1;
|
||||
elif [ $selected -eq 1 ]; then
|
||||
count=0;
|
||||
else
|
||||
quitProgram;
|
||||
fi
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
#
|
||||
# This confirms the new account information.
|
||||
#
|
||||
confirmAccount()
|
||||
{
|
||||
message="<C></B>Confirm New Account.
|
||||
You are about to add an account with the following
|
||||
information:
|
||||
|
||||
<C><#HL(30)>
|
||||
Account Name : </B>$ACCOUNT_NAME
|
||||
Account Info : </B>$ACCOUNT_INFO
|
||||
Account Home : </B>$ACCOUNT_HOME
|
||||
Account Shell: </B>$ACCOUNT_SHELL
|
||||
Account UID : </B>$ACCOUNT_UID
|
||||
Account GID : </B>$ACCOUNT_GID
|
||||
<C><#HL(30)>
|
||||
|
||||
Are you sure you want to do this. Hit </R>Yes<!R> if you
|
||||
want to add the account; hit </R>No<!R> if you want to
|
||||
edit the information; hit </R>Cancel<!R> if you want to
|
||||
abandon all information.
|
||||
"
|
||||
buttons="< Yes >
|
||||
< No >
|
||||
< Cancel >"
|
||||
${CDK_DIALOG} -m "${message}" -B "${buttons}" 2> /dev/null
|
||||
answer=$?
|
||||
|
||||
#
|
||||
# Check the answer.
|
||||
#
|
||||
if [ "$answer" -eq 2 -o "$answer" -eq 255 ]; then
|
||||
quitProgram;
|
||||
fi
|
||||
if [ "$answer" -eq 0 ]; then
|
||||
confirm=1; export confirm;
|
||||
else
|
||||
confirm=0; export confirm;
|
||||
fi
|
||||
}
|
||||
|
||||
#
|
||||
# Find out if the user wants to change the password
|
||||
# or not.
|
||||
#
|
||||
changeAccountPassword()
|
||||
{
|
||||
buttons="< Yes >
|
||||
< No >"
|
||||
message="<C></B>Change Account Password Now
|
||||
|
||||
Since the account was added without a password, this account
|
||||
can be logged in to without providing a password. Would you
|
||||
like to change the account's password now?
|
||||
"
|
||||
${CDK_DIALOG} -m "${message}" -B "${buttons}" 2> /dev/null
|
||||
answer=$?
|
||||
if [ "$answer" -eq 0 ]; then
|
||||
passwd $ACCOUNT_NAME
|
||||
fi
|
||||
}
|
||||
|
||||
#
|
||||
# This verifies the users ability to modify the
|
||||
# password file.
|
||||
#
|
||||
checkPermissions()
|
||||
{
|
||||
#
|
||||
# Try to touch the passwd file.
|
||||
#
|
||||
touch /etc/passwd >/dev/null 2>&1
|
||||
if [ $? -ne 0 ]; then
|
||||
#
|
||||
# Can't touch the password file. Let's tell them and go.
|
||||
#
|
||||
buttons="< Log Into Root Now >
|
||||
< Exit >"
|
||||
message="<C></B>Can Not Edit Password File
|
||||
|
||||
It appears that you do not have permission to edit the
|
||||
password file. To add a new user to this machine you
|
||||
must be logged in as root. Would you like to su to root
|
||||
now or exit and log in. If you try to su now, this
|
||||
program will be restarted.
|
||||
"
|
||||
${CDK_DIALOG} -m "${message}" -B "${buttons}" 2> /dev/null
|
||||
if [ $? -eq 0 ]; then
|
||||
su root -c "$0"
|
||||
fi
|
||||
exit;
|
||||
fi
|
||||
}
|
||||
|
||||
#
|
||||
# This creates the account and copies all needed
|
||||
# information.
|
||||
#
|
||||
createAccount()
|
||||
{
|
||||
if [ ! -d "$ACCOUNT_HOME" ]; then
|
||||
mkdir $ACCOUNT_HOME
|
||||
fi
|
||||
if [ "$ACCOUNT_SHELL" = "/bin/sh" ]; then
|
||||
cp /etc/profile ${ACCOUNT_HOME}/.profile
|
||||
fi
|
||||
if [ "$ACCOUNT_SHELL" = "/bin/bash" ]; then
|
||||
cp /etc/profile ${ACCOUNT_HOME}/.profile
|
||||
fi
|
||||
if [ "$ACCOUNT_SHELL" = "/bin/csh" ]; then
|
||||
cp /etc/csh.cshrc ${ACCOUNT_HOME}/.cshrc
|
||||
cp /etc/csh.login ${ACCOUNT_HOME}/.login
|
||||
fi
|
||||
if [ "$ACCOUNT_SHELL" = "/bin/tcsh" ]; then
|
||||
cp /etc/csh.cshrc ${ACCOUNT_HOME}/.cshrc
|
||||
cp /etc/csh.login ${ACCOUNT_HOME}/.login
|
||||
fi
|
||||
chown -R ${ACCOUNT_NAME}.${GROUP_NAME} $ACCOUNT_HOME
|
||||
}
|
||||
|
||||
###########################################################
|
||||
#
|
||||
# This is the start of the info retrieval.
|
||||
#
|
||||
###########################################################
|
||||
|
||||
#
|
||||
# Set up the intermiediate functions so we can go
|
||||
# backward and forward.
|
||||
#
|
||||
function1()
|
||||
{
|
||||
getAccountName;
|
||||
}
|
||||
function2()
|
||||
{
|
||||
getAccountInfo;
|
||||
}
|
||||
function3()
|
||||
{
|
||||
getAccountGID;
|
||||
}
|
||||
function4()
|
||||
{
|
||||
getAccountUID;
|
||||
}
|
||||
function5()
|
||||
{
|
||||
getAccountHome;
|
||||
}
|
||||
function6()
|
||||
{
|
||||
getAccountShell;
|
||||
}
|
||||
function7()
|
||||
{
|
||||
confirmAccount;
|
||||
}
|
||||
|
||||
#
|
||||
# Make sure the user has permission to edit the password file.
|
||||
#
|
||||
checkPermissions;
|
||||
|
||||
#
|
||||
# Tell the user what they are about to do.
|
||||
#
|
||||
warnUser;
|
||||
|
||||
#
|
||||
# Call the functions to get the needed info.
|
||||
#
|
||||
confirm=0;
|
||||
NUMBER=0;
|
||||
DIRECTION=1;
|
||||
while [ "$confirm" -eq 0 ]; do
|
||||
NUMBER=`expr $NUMBER + $DIRECTION`
|
||||
if [ $NUMBER -le 0 ]; then
|
||||
NUMBER = 1;
|
||||
fi
|
||||
CURRENT_FUNCTION="function${NUMBER}";
|
||||
$CURRENT_FUNCTION;
|
||||
done
|
||||
|
||||
#
|
||||
# Add the account to the password file.
|
||||
#
|
||||
cp /etc/passwd /etc/passwd.old
|
||||
echo "${ACCOUNT_NAME}::${ACCOUNT_UID}:${ACCOUNT_GID}:${ACCOUNT_INFO}:${ACCOUNT_HOME}:${ACCOUNT_SHELL}" >> /etc/passwd
|
||||
|
||||
#
|
||||
# Find out if the user wants to change the password or not.
|
||||
#
|
||||
changeAccountPassword;
|
||||
|
||||
#
|
||||
# Create the account and copy . files.
|
||||
#
|
||||
createAccount;
|
||||
|
||||
#
|
||||
# Pop up a last little message and tell the user everything
|
||||
# if OK.
|
||||
#
|
||||
buttons="< OK >"
|
||||
message="<C></B>Account Add Complete
|
||||
|
||||
The account </B>${ACCOUNT_NAME}<!B> has been added to the password
|
||||
file. You should be able to log in under this account
|
||||
now.
|
||||
"
|
||||
${CDK_DIALOG} -m "${message}" -B "${buttons}" 2> /dev/null
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue