From 0cc9b20c15460213e488bf5e70963b941482f628 Mon Sep 17 00:00:00 2001 From: William Harrington Date: Tue, 14 Jan 2025 16:06:02 -0600 Subject: Add source. --- CHANGES | 107 ++++++++++++ LICENSE | 36 ++++ Makefile.in | 75 +++++++++ README.FIRST | 65 ++++++++ TODO | 25 +++ config | 175 ++++++++++++++++++++ config.diag | 5 + config.dist | 12 ++ config.pkg | 9 + html/README | 4 + html/index.html | 10 ++ html/toc.html | 35 ++++ sdk/bin/clean | 22 +++ sdk/bin/config | 175 ++++++++++++++++++++ sdk/bin/config.sub | 38 +++++ sdk/bin/diag | 171 +++++++++++++++++++ sdk/bin/dist | 63 +++++++ sdk/bin/disthtml | 31 ++++ sdk/bin/install.bind | 55 ++++++ sdk/bin/install.help | 12 ++ sdk/bin/install.make | 112 +++++++++++++ sdk/bin/instinit | 61 +++++++ sdk/bin/instman | 32 ++++ sdk/bin/instso | 39 +++++ sdk/bin/instsvc | 27 +++ sdk/bin/rootsudo | 6 + sdk/config.h | 16 ++ sdk/dev/Makefile.in | 19 +++ sdk/dev/bind.conf | 0 sdk/dev/empty.c | 15 ++ sdk/dev/flowctrl.c | 47 ++++++ sdk/dev/format.c | 64 +++++++ sdk/dev/inkey.c | 76 +++++++++ sdk/dev/input.c | 34 ++++ sdk/dev/interactive.c | 35 ++++ sdk/dev/make.conf | 5 + sdk/dev/speed.c | 75 +++++++++ sdk/dev/stty.c | 29 ++++ sdk/dev/termcap.h | 17 ++ sdk/dev/tty.h | 72 ++++++++ sdk/dev/waitfor.c | 39 +++++ sdk/dev/waitsync.c | 32 ++++ sdk/dev/xmit.c | 31 ++++ sdk/net/Makefile.in | 19 +++ sdk/net/bind.conf | 0 sdk/net/gethost.c | 39 +++++ sdk/net/getservice.c | 45 +++++ sdk/net/getsocket.c | 43 +++++ sdk/net/init.c | 20 +++ sdk/net/make.conf | 4 + sdk/net/msgport.c | 84 ++++++++++ sdk/net/msgport.h | 47 ++++++ sdk/net/netaddr.c | 28 ++++ sdk/net/snmptrap.c | 165 ++++++++++++++++++ sdk/net/socket.h | 61 +++++++ sdk/net/sockname.c | 62 +++++++ sdk/net/stream.h | 45 +++++ sdk/net/tcpsocket.c | 42 +++++ sdk/net/tcpstream.c | 88 ++++++++++ sdk/net/trap.h | 30 ++++ sdk/net/udpsocket.c | 36 ++++ sdk/other/Makefile.in | 22 +++ sdk/other/atob.c | 47 ++++++ sdk/other/bcd.c | 125 ++++++++++++++ sdk/other/bind.conf | 1 + sdk/other/ccount.c | 45 +++++ sdk/other/confdir.c | 105 ++++++++++++ sdk/other/config.c | 437 ++++++++++++++++++++++++++++++++++++++++++++++++ sdk/other/config.h | 67 ++++++++ sdk/other/env.c | 36 ++++ sdk/other/env.h | 31 ++++ sdk/other/expand.c | 36 ++++ sdk/other/fatal.c | 23 +++ sdk/other/filename.c | 74 +++++++++ sdk/other/files.h | 52 ++++++ sdk/other/fncat.c | 30 ++++ sdk/other/getargv.c | 57 +++++++ sdk/other/hex.c | 44 +++++ sdk/other/isftype.c | 22 +++ sdk/other/make.conf | 2 + sdk/other/memalloc.c | 35 ++++ sdk/other/memdup.c | 22 +++ sdk/other/memfree.c | 38 +++++ sdk/other/memory.h | 103 ++++++++++++ sdk/other/mempool.c | 49 ++++++ sdk/other/memrelease.c | 43 +++++ sdk/other/memreq.c | 59 +++++++ sdk/other/picture.c | 112 +++++++++++++ sdk/other/search.c | 46 +++++ sdk/other/strblank.c | 24 +++ sdk/other/strcopy.c | 61 +++++++ sdk/other/strcvt.h | 56 +++++++ sdk/other/strdiff.c | 24 +++ sdk/other/string.h | 65 ++++++++ sdk/other/strint.c | 51 ++++++ sdk/other/strpos.c | 46 +++++ sdk/other/strreq.c | 39 +++++ sdk/other/strtrim.c | 45 +++++ sdk/other/token.c | 50 ++++++ sdk/other/xval.c | 28 ++++ sdk/proc/Makefile.in | 18 ++ sdk/proc/bind.conf | 1 + sdk/proc/make.conf | 5 + sdk/proc/pdetach.c | 78 +++++++++ sdk/proc/priority.c | 73 ++++++++ sdk/proc/process.h | 57 +++++++ sdk/proc/spawn.c | 92 ++++++++++ sdk/std/Makefile.in | 18 ++ sdk/std/bind.conf | 69 ++++++++ sdk/std/files.h | 47 ++++++ sdk/std/help.conf | 4 + sdk/std/limits.h | 97 +++++++++++ sdk/std/make.conf | 102 ++++++++++++ sdk/std/math.h | 31 ++++ sdk/std/poll.h | 21 +++ sdk/std/posix1_lim.h | 92 ++++++++++ sdk/std/process.h | 99 +++++++++++ sdk/std/select.h | 21 +++ sdk/std/signal.h | 11 ++ sdk/std/string.c | 110 ++++++++++++ sdk/std/string.h | 75 +++++++++ sdk/std/sysexits.h | 118 +++++++++++++ sdk/std/time.h | 23 +++ sdk/std/types.h | 54 ++++++ sdk/std/utmp.c | 49 ++++++ sdk/std/utmp.h | 31 ++++ speak.lsm | 23 +++ spktrapd/README.NOW | 8 + spo256/Makefile.in | 34 ++++ spo256/README | 24 +++ spo256/chars.c | 339 +++++++++++++++++++++++++++++++++++++ spo256/client.c | 40 +++++ spo256/currency.c | 43 +++++ spo256/getidx.c | 98 +++++++++++ spo256/getspo.c | 68 ++++++++ spo256/number.c | 132 +++++++++++++++ spo256/speak.1 | 46 +++++ spo256/speak.8 | 39 +++++ spo256/speak.c | 86 ++++++++++ spo256/speak.conf.7 | 72 ++++++++ spo256/speak.h | 48 ++++++ spo256/speak.init | 54 ++++++ spo256/spo.c | 161 ++++++++++++++++++ spo256/spo256.8 | 98 +++++++++++ spo256/word.c | 38 +++++ spo256/words.c | 34 ++++ utils/Makefile.in | 31 ++++ utils/README | 9 + utils/down.8 | 44 +++++ utils/down.c | 129 +++++++++++++++ utils/say.1 | 35 ++++ utils/say.c | 34 ++++ utils/vmon.8 | 65 ++++++++ utils/vmon.c | 442 +++++++++++++++++++++++++++++++++++++++++++++++++ 154 files changed, 8788 insertions(+) create mode 100644 CHANGES create mode 100644 LICENSE create mode 100644 Makefile.in create mode 100644 README.FIRST create mode 100644 TODO create mode 100755 config create mode 100644 config.diag create mode 100644 config.dist create mode 100644 config.pkg create mode 100644 html/README create mode 100644 html/index.html create mode 100755 html/toc.html create mode 100755 sdk/bin/clean create mode 100755 sdk/bin/config create mode 100755 sdk/bin/config.sub create mode 100755 sdk/bin/diag create mode 100755 sdk/bin/dist create mode 100755 sdk/bin/disthtml create mode 100755 sdk/bin/install.bind create mode 100755 sdk/bin/install.help create mode 100755 sdk/bin/install.make create mode 100755 sdk/bin/instinit create mode 100755 sdk/bin/instman create mode 100755 sdk/bin/instso create mode 100755 sdk/bin/instsvc create mode 100755 sdk/bin/rootsudo create mode 100644 sdk/config.h create mode 100644 sdk/dev/Makefile.in create mode 100644 sdk/dev/bind.conf create mode 100644 sdk/dev/empty.c create mode 100644 sdk/dev/flowctrl.c create mode 100644 sdk/dev/format.c create mode 100644 sdk/dev/inkey.c create mode 100644 sdk/dev/input.c create mode 100644 sdk/dev/interactive.c create mode 100644 sdk/dev/make.conf create mode 100644 sdk/dev/speed.c create mode 100644 sdk/dev/stty.c create mode 100644 sdk/dev/termcap.h create mode 100644 sdk/dev/tty.h create mode 100644 sdk/dev/waitfor.c create mode 100644 sdk/dev/waitsync.c create mode 100644 sdk/dev/xmit.c create mode 100644 sdk/net/Makefile.in create mode 100644 sdk/net/bind.conf create mode 100644 sdk/net/gethost.c create mode 100644 sdk/net/getservice.c create mode 100644 sdk/net/getsocket.c create mode 100644 sdk/net/init.c create mode 100644 sdk/net/make.conf create mode 100644 sdk/net/msgport.c create mode 100644 sdk/net/msgport.h create mode 100644 sdk/net/netaddr.c create mode 100644 sdk/net/snmptrap.c create mode 100644 sdk/net/socket.h create mode 100644 sdk/net/sockname.c create mode 100644 sdk/net/stream.h create mode 100644 sdk/net/tcpsocket.c create mode 100644 sdk/net/tcpstream.c create mode 100644 sdk/net/trap.h create mode 100644 sdk/net/udpsocket.c create mode 100644 sdk/other/Makefile.in create mode 100644 sdk/other/atob.c create mode 100644 sdk/other/bcd.c create mode 100644 sdk/other/bind.conf create mode 100644 sdk/other/ccount.c create mode 100644 sdk/other/confdir.c create mode 100644 sdk/other/config.c create mode 100644 sdk/other/config.h create mode 100644 sdk/other/env.c create mode 100644 sdk/other/env.h create mode 100644 sdk/other/expand.c create mode 100644 sdk/other/fatal.c create mode 100644 sdk/other/filename.c create mode 100644 sdk/other/files.h create mode 100644 sdk/other/fncat.c create mode 100644 sdk/other/getargv.c create mode 100644 sdk/other/hex.c create mode 100644 sdk/other/isftype.c create mode 100644 sdk/other/make.conf create mode 100644 sdk/other/memalloc.c create mode 100644 sdk/other/memdup.c create mode 100644 sdk/other/memfree.c create mode 100644 sdk/other/memory.h create mode 100644 sdk/other/mempool.c create mode 100644 sdk/other/memrelease.c create mode 100644 sdk/other/memreq.c create mode 100644 sdk/other/picture.c create mode 100644 sdk/other/search.c create mode 100644 sdk/other/strblank.c create mode 100644 sdk/other/strcopy.c create mode 100644 sdk/other/strcvt.h create mode 100644 sdk/other/strdiff.c create mode 100644 sdk/other/string.h create mode 100644 sdk/other/strint.c create mode 100644 sdk/other/strpos.c create mode 100644 sdk/other/strreq.c create mode 100644 sdk/other/strtrim.c create mode 100644 sdk/other/token.c create mode 100644 sdk/other/xval.c create mode 100644 sdk/proc/Makefile.in create mode 100644 sdk/proc/bind.conf create mode 100644 sdk/proc/make.conf create mode 100644 sdk/proc/pdetach.c create mode 100644 sdk/proc/priority.c create mode 100644 sdk/proc/process.h create mode 100644 sdk/proc/spawn.c create mode 100644 sdk/std/Makefile.in create mode 100644 sdk/std/bind.conf create mode 100644 sdk/std/files.h create mode 100644 sdk/std/help.conf create mode 100644 sdk/std/limits.h create mode 100644 sdk/std/make.conf create mode 100644 sdk/std/math.h create mode 100644 sdk/std/poll.h create mode 100644 sdk/std/posix1_lim.h create mode 100644 sdk/std/process.h create mode 100644 sdk/std/select.h create mode 100644 sdk/std/signal.h create mode 100644 sdk/std/string.c create mode 100644 sdk/std/string.h create mode 100644 sdk/std/sysexits.h create mode 100644 sdk/std/time.h create mode 100644 sdk/std/types.h create mode 100644 sdk/std/utmp.c create mode 100644 sdk/std/utmp.h create mode 100644 speak.lsm create mode 100644 spktrapd/README.NOW create mode 100644 spo256/Makefile.in create mode 100644 spo256/README create mode 100644 spo256/chars.c create mode 100644 spo256/client.c create mode 100644 spo256/currency.c create mode 100644 spo256/getidx.c create mode 100644 spo256/getspo.c create mode 100644 spo256/number.c create mode 100644 spo256/speak.1 create mode 100644 spo256/speak.8 create mode 100644 spo256/speak.c create mode 100644 spo256/speak.conf.7 create mode 100644 spo256/speak.h create mode 100644 spo256/speak.init create mode 100644 spo256/spo.c create mode 100644 spo256/spo256.8 create mode 100644 spo256/word.c create mode 100644 spo256/words.c create mode 100644 utils/Makefile.in create mode 100644 utils/README create mode 100644 utils/down.8 create mode 100644 utils/down.c create mode 100644 utils/say.1 create mode 100644 utils/say.c create mode 100644 utils/vmon.8 create mode 100644 utils/vmon.c diff --git a/CHANGES b/CHANGES new file mode 100644 index 0000000..7a6638a --- /dev/null +++ b/CHANGES @@ -0,0 +1,107 @@ +0.2 Initial Release 1/13/97 + + Includes spo256-al2 server. Maintained by David Sugar + . + +0.2pl1 Patch Update 1/16/97 + + Updated build/dist and added config.dist. This should make for + better control of distribution sets off a live production system. + This also solves 'second level' production problems off a + distribution set. + + Updated build/instinit to allow automatic linkage of the speak.init + service script to a free 'S' slot in rc3.d. Instinit is now smarter + about how it handles startup script installation, especially for + Linux. Care with speak.init should still be taken for non-Linux + systems. + + Replaced missing config.c in sdk/std. + + Fixed vstat bug where it would fall-through into vmon code. + + Updated vmon to use more portable utent() routines instead of + directly accessing the utmp file. This was to improve portability. + + Updated vmon to use utmp routines to determine uptime if + /proc/uptime does not exist. This should help with porting + to non-Linux systems, or with Linux systems when 'proc' is + not installed. + + Made statfs() dependent code conditional, and active only + for linux, to prevent problems when compiling on non-Linux + operating systems. Code will need to be added to drive + external "df" image if no statfs() service is supported. + +0.2pl2 Patch Update 1/27/97 + + Found problem in tcpsocket.c, which would not compile correctly + on some sites. + + Added diag build script "Make diag" target to re-mail system + diagnostic reports. + + Added "config.diag" for "Make diag". + +0.3 Second Release 2/14/97 + + Changed sdk 'dev' stty support to improve stty setup operations. + This involved minor code changes to getspo.c. + + Changed sdk 'net' binding code to standardize handling of network + addresses passed as strings using getnetaddr(). + + The [interface] bind = option may now be used to restrict the + speak port to a specific subnet interface address. This + should keep the rest of the internet out of speak ports! + + Changed spo256 server to use a "character-state" parser in place + of the prior simplified token scanning routines. This is closer + to the original WorldVU server, and is implimented much more + cleanly. + + The server now also recognizes special "server" specific commands + that may be embedded in the output stream. These server commands + are prefixed with an and appear inside <>'s. Server + commands allow some direct interaction with the server, such as + being able to force specific pronouniation rules. More advanced + devices (beyond the SPO) may someday make use of server commands + to force change of tone, inflection, or volume. + + The [vmon] settings in speak.conf have changes to support control + of timer intervals for monitoring system status. The new interval + option is meant for when we add mailbox and user login tracking. + This controls the interval for such short duration events, in + minutes. The 'frequency' option indicates how many times per + hour you want vmon to announce. Once is usually quite enough. + If you are upgrading, you will want to check the speak.conf + file in the distribution. + + Vmon can now watch for and notify when new mail arrives in + specified user accounts. This behavior is controlled with + the new [vmon] entries in speak.conf for 'maildir=' and + 'mailbox='. Maildir should point the mail spool directory + (typically /var/spool/mail) and one or more mailbox lines + can be used to list those user accounts you want to have + verbal mail notification for. + +1.0 + + The entire build and sdk process has been redone and unified for + improved portability. No functional changes have been made in the + application. The major difference, initially, is that, instead of + performing a "make config", one now executes ./config to start the + build process going for the package. + + We have also standardized 'config' around a hybrid file structure + that is fully consistent with the Linux file naming standard, can + comply with BSD file layouts, is compatible with most UNIX's, + and automatically recognizes secure TSW "Linux" release 1 and gnu/ + glib 2.x introduced file naming and ownership conventions. + Support for TSW-LR1 html documentation and software package + redistribution conventions are implied in the new 'config'. This + release will be available in source and binary rpm format for any + rpm managed Linux system. + + + diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..61dbe05 --- /dev/null +++ b/LICENSE @@ -0,0 +1,36 @@ +Copyright (c) 1997 Tycho Softworks. All rights reserved. + +This source is made freely available for public use, and may be +redistributed in source and/or binary forms, with or without +modification, provided that the following conditions are met: + +1. Redistributions of modified source code must retain all + original copyright notices when present. + +2. Redistributions of modified source code or binary archives + must include this license agreement unmodified. + +3. Neither the name of Tycho Softworks nor the names of it's + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +4. Where Berkeley (BSD) licensed source or header files may be used + within this distribution, such use is hereby acknowledged and + subject to the original terms and conditions as specified in + the comments of said specific source files. + +THIS SOFTWARE IS PROVIDED BY THE TYCHO SOFTWORKS ``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 TYCHO SOFTWORKS 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. + +Any comments or questions in regards to this license or that arise +from it's use may be addressed to "dyfet@tycho.com". + diff --git a/Makefile.in b/Makefile.in new file mode 100644 index 0000000..55dfe1b --- /dev/null +++ b/Makefile.in @@ -0,0 +1,75 @@ +# +# Top level project Makefile for "speak". +# $ProjectHeader: speak 0.4 Mon, 24 Mar 1997 12:25:37 -0500 dyfet $ +# Copyright (c) 1997 by Tycho Softworks. +# +# Targets: +# [none] default as 'make all' +# [all] create config if missing, then build all +# [install] build and install spo server and utils +# [dist] create distribution archive +# [web] build online (web) published distribution +# [clean] clean up a build +# [config] build initial configuration +# [reconfig] rebuild changed configuration +# [diag] send diagnostic e-mail +# [get] and [put] replicate source tree + +# Insert any default configuration values in CONFIGURE. + +CONFIGURE= + +# Internal use for source tree replication + +SOURCES = /mnt/share/source/shared/speak +EXCLUDE = --exclude Makefile --exclude config.cache +RSYNC = rsync -auSC $(EXCLUDE) + +all: config + @cd sdk/std ; make + @cd sdk/dev ; make + @cd sdk/net ; make + @cd sdk/other ; make + @cd sdk/proc ; make + @cd spo256 ; make + @cd utils ; make + +get: + $(RSYNC) $(SOURCES)/* . + ./config + +put: + $(RSYNC) * $(SOURCES) + +install: + @cd spo256 ; make install + @cd utils ; make install + +dist: + @cp -f /etc/speak.conf spo256 + @sdk/bin/dist $(DISTDIR) + +web: + @sdk/bin/disthtml $(HTMLDIR) $(MANDIR) + +clean: + @cd sdk/std ; make clean + @cd sdk/net ; make clean + @cd sdk/dev ; make clean + @cd sdk/other ; make clean + @cd sdk/proc ; make clean + @cd spo256 ; make clean + @cd utils ; make clean + @build/clean + +config: + @echo "Creating Speak Project Configuration ---" + @sdk/bin/config + +reconfig: + -@rm config.cache + @sdk/bin/config + +diag: + @sdk/bin/diag | mail -s "Speak Diagnostic Report" dyfet@tycho.com + diff --git a/README.FIRST b/README.FIRST new file mode 100644 index 0000000..37403ab --- /dev/null +++ b/README.FIRST @@ -0,0 +1,65 @@ +SPO256-AL2 based Text-to-Speech Network Services Version 0.2 + +This package comprises a new stand-alone release of the standard 'text to +speech' interface service and tools as first covered in the SPO article +appearing in Linux Journal, January 1997. Generic support for using the +SPO256-AL2 based board, and potentially other alternate network accessible +text-to-speech resources, is now more cleanly supported in a portable manner +that should allow use under virtually any UNIX'oid OS. This release +supersedes the initial WorldVU based source release originally described +in Linux Journal. + +This new release includes a new and portable SPO256 text-to-speech server, +some glue scripts for init.d in Linux to use the SPO as a normal system +'service', and many of the standard utilities re-written in a more +generic form. The new server should do a better job of parsing textual +documents into natural sounding speech as new rules for handling common +abbreviations and to improve word pacing have been added. + +The source for the SPO256-AL2 server is now more modular and more fully +documented. The utilities now include standard man pages. The server +now supports alternate forms of operation for use in client scripts. + +If you do not have the Linux Journal article in question, the SPO256 is +essentially a serial based text-to-speech board of limited utility. The +SPO256-AL2 (Vocoder) chip was originally used in many products, including +the Matel speak-and-spell(tm) toy, and offers limited text-to-speech +translation services. The SPO256 server augments the limited translation +capabilities of the SPO256 chipset and offers a network accessible resource +for text-to-speech notifications, such as system alerts, user logins, etc. + +This new server assumes a standard TCP 'service' has been defined in +/etc/services. You should edit the /etc/services file to include an entry +like the following (though a different port number may be used): + +speak 800/tcp # SPO256 text-to-speech network resource + +You will also need to copy speak.conf to /etc and modify it as needed. + +While the SPO256-AL2 is the primary hardware interface supported in this +package, other alternate text-to-speech devices may be added later that +will also use the "speak" port service. In particular, a re-implementation +of rsynth is being considered. Since the utilities talk to a standard +tcp port interface, they remain unchanged regardless of the underlying +hardware used to produce text-to-speech output. + +To build the software package, first run ./config. Config will genorate +the Makefiles. Config will then start 'make'. The configuration system +will attempt to identify the OS it is running under, compiler options, etc. +This may work under most UNIX operating systems, so the SPO package should +not be assumed to be a Linux-only utility. Once make completes successfully, +perform a 'make install'. This will update the /etc/services file and install +the application binaries. If you have difficulty with the new source +configuration tool, please review build/config.doc. + +Please examine the speak.conf and speak.init files, and relocate them as +needed. Further documentation may be found within the supplied man pages. +Comments may be addressed to David Sugar . The SPO256- +AL2 Text-to-Speech board ("Computalker") may be ordered through B&G Micro, +P.O. Box 280298, Dallas, TX 75228 (214) 271-5546. Linux Journal may be +found http://www.ssc.com/lj. + + + + + diff --git a/TODO b/TODO new file mode 100644 index 0000000..5fba52f --- /dev/null +++ b/TODO @@ -0,0 +1,25 @@ +Many things... + +* Build a "rsynth" based server. Change primary 'make' to request + server type, as in 'make rsynth', 'make spo256', or 'make utils', + the latter to build utilities only on a machine without it's own + server. + +* Add support for retrieving "index" status and time-sync rondeveus + by supporting a "inquire" sequence for the server to respond to. + Time-sync would be with "" server tag, which would force + the server to 'tcdrain' the port and then return a response. The + "" tag would retrieve an index. Other 'tag' options for + volume control, pitch, inflection, etc, may also need to be added + for rsynth, although the SPO does not support these features. + +* Build spksnmpd for rule based verbalization of specific snmp trap + events. + +* Add user login monitoring to vmon. + +* Add external "df" code to vmon for systems that have no statfs() + call. + +* Build rpm package for speak. + diff --git a/config b/config new file mode 100755 index 0000000..a701bc8 --- /dev/null +++ b/config @@ -0,0 +1,175 @@ +#!/bin/sh + +# +# Reload defaults +# + +BUILD=sdk +CONFIG=sdk/config.h + +if test -f config.cache ; then + . ./config.cache +fi +echo -n >config.cache + +if test -f config.pkg ; then + . ./config.pkg +fi + +# +# Load bindings +# + +if test -f config.pkg ; then + . ./config.pkg +fi + +if test -f config.make ; then + echo -n >config.make +fi + +if test -f $CONFIG ; then + echo -n >$CONFIG +fi + +if test -f $BUILD/bin/config.sub ; then + . $BUILD/bin/config.sub +fi + +BIND_OPTS='host' + +if test -z "$CONFIG_HOST" ; then + if test -d /usr/local/include ; then + CONFIG_HOST=/usr/local + fi + if test -d /usr/include ; then + CONFIG_HOST=/usr + fi +fi + +opt_host() { + CONFIG_HOST="$1" + return 0 +} + +if test ! -z "$BIND" ; then + for bind in $BIND ; do + if test -d $BUILD/$bind ; then + . $BUILD/$bind/bind.conf + else + . $BUILD/bin/$bind.bind + fi + done +fi + +# +# Parse command line arguments. +# +err='' + +if test ! -z "$CONFIG_FLAGS" ; then + for arg in $CONFIG_FLAGS ; do + for opt in $BIND_OPTS ; do + case "$arg" in + $opt=* | -$opt=* | --$opt=* ) + opt_$opt `echo "$arg" | sed 's/[-_a-zA-Z0-9]*=//'` + break + ;; + esac + done + done +fi + + +if test ! -z "$*" ; then + for arg in $* ; do + err=$arg + for opt in $BIND_OPTS ; do + case "$arg" in + $opt=* | -$opt=* | --$opt=* ) + opt_$opt `echo "$arg" | sed 's/[-_a-zA-Z0-9]*=//'` + err='' + break + ;; + esac + done + if test ! -z "$err" ; then + break + fi + done +fi + +CONFIG_FLAGS='' + +if test ! -z "$err" ; then + echo "config: $err: invalid option." + echo + echo "Valid Options:" + echo -n >config.help + if test ! -z "$BIND" ; then + for use in $BIND ; do + if test -f $BUILD/$use/help.conf ; then + cat $BUILD/$use/help.conf >>config.help + fi + if test -f $BUILD/bin/$use.help ; then + cat $BUILD/bin/$use.help >>config.help + fi + done + sort >$CONFIG +echo "#define __CONFIG_H__" >>$CONFIG + +CONFIG_LIBS="" + +if test ! -z "$BIND" ; then + for bind in $BIND ; do + if test -d $BUILD/$bind ; then + . $BUILD/$bind/make.conf + CONFIG_LIBS='-l'$bind' '"$CONFIG_LIBS" + MAKEFILES="$MAKEFILES"' '$BUILD/$bind/Makefile + else + . $BUILD/bin/$bind.make + fi + done +fi + +if test ! -z "$CONFIG_LIBS" ; then + echo "LIBS=$CONFIG_LIBS" >>config.make +fi + +if test ! -z "$MAKEFILES" ; then + for makefile in $MAKEFILES ; do + cat config.make >$makefile + cat $makefile.in >>$makefile + done +fi + +echo "#endif" >>$CONFIG + + +if test -z "$CONFIG_CACHE" ; then + CONFIG_CACHE='config.cache' + CONFIG_FLAGS='' +else + CONFIG_FIRST='' +fi + +echo "CONFIG_CACHE="$CONFIG_CACHE >>config.cache + +if test -f conftest.c ; then + rm -f conftest.c +fi + +if test -f conftest.o ; then + rm conftest.o +fi + +if test ! -z "$CONFIG_FIRST" ; then + $CONFIG_FIRST +fi + diff --git a/config.diag b/config.diag new file mode 100644 index 0000000..15a36f3 --- /dev/null +++ b/config.diag @@ -0,0 +1,5 @@ +# Gather startup services info + +startup='yes' +files='/etc/rc.d/rc.serial' + diff --git a/config.dist b/config.dist new file mode 100644 index 0000000..2ec39c8 --- /dev/null +++ b/config.dist @@ -0,0 +1,12 @@ +version="1.0" +package="speak" +examine="utils sdk spo256 spktrapd html" +config="config.pkg config.dist config.diag config sdk/bin/*" +include="Makefile.in README.FIRST CHANGES TODO LICENSE speak.lsm" + +manpages="down.8 say.1 speak.1 speak.conf.7 spo256.8 vmon.8" +txtpages="CHANGES LICENSE README.FIRST TARGETS TODO" +lsmpages="speak.lsm" +htmlpages="index.html toc.html" +htmlhome=packages/speak + diff --git a/config.pkg b/config.pkg new file mode 100644 index 0000000..9c7aa53 --- /dev/null +++ b/config.pkg @@ -0,0 +1,9 @@ +# +# Denote package bindings +# +BIND='install std proc other net dev' +MAKEFILES='Makefile spo256/Makefile utils/Makefile' +CONFIG_FLAGS=$CONFIG_FLAGS +CONFIG_FIRST='make' +CONFIG_INSTALL='make install' + diff --git a/html/README b/html/README new file mode 100644 index 0000000..5a4f414 --- /dev/null +++ b/html/README @@ -0,0 +1,4 @@ +This directory holds html templates used as part of make 'web' when +building a html redistribution directory. Otherwise, this directory may +be ignored. + diff --git a/html/index.html b/html/index.html new file mode 100644 index 0000000..ad54365 --- /dev/null +++ b/html/index.html @@ -0,0 +1,10 @@ + + +UNIX Speak Server 0.2pl2 + + + + + + + diff --git a/html/toc.html b/html/toc.html new file mode 100755 index 0000000..429ec78 --- /dev/null +++ b/html/toc.html @@ -0,0 +1,35 @@ + + + + + +TOC + + + + + +

General

+ +
  • About
  • +
  • Changes
  • +
  • Download
  • +
  • Feedback
  • +
  • License
  • +
  • Readme
  • +
  • Targets
  • +
  • Todo
  • +
    +

    Manpages

    + +
  • down.8
  • +
  • say.1
  • +
  • speak.1
  • +
  • speak.conf.7
  • +
  • spo256.8
  • +
  • vmon.8
  • +
    +

     

    + + + diff --git a/sdk/bin/clean b/sdk/bin/clean new file mode 100755 index 0000000..2667461 --- /dev/null +++ b/sdk/bin/clean @@ -0,0 +1,22 @@ +#!/bin/sh +flist=`find . -name core -follow -print` +if [ ! -z "$flist" ] ; then + rm $flist +fi + +flist=`find . -name "*~" -follow -print` +if [ ! -z "$flist" ] ; then + rm $flist +fi + +flist=`find . -name "*.tar.gz" -follow -print` +if [ ! -z "$flist" ] ; then + rm $flist +fi + +flist=`find . -name "config.c*" -follow -print` +if [ ! -z "$flist" ] ; then + rm $flist +fi + + diff --git a/sdk/bin/config b/sdk/bin/config new file mode 100755 index 0000000..a701bc8 --- /dev/null +++ b/sdk/bin/config @@ -0,0 +1,175 @@ +#!/bin/sh + +# +# Reload defaults +# + +BUILD=sdk +CONFIG=sdk/config.h + +if test -f config.cache ; then + . ./config.cache +fi +echo -n >config.cache + +if test -f config.pkg ; then + . ./config.pkg +fi + +# +# Load bindings +# + +if test -f config.pkg ; then + . ./config.pkg +fi + +if test -f config.make ; then + echo -n >config.make +fi + +if test -f $CONFIG ; then + echo -n >$CONFIG +fi + +if test -f $BUILD/bin/config.sub ; then + . $BUILD/bin/config.sub +fi + +BIND_OPTS='host' + +if test -z "$CONFIG_HOST" ; then + if test -d /usr/local/include ; then + CONFIG_HOST=/usr/local + fi + if test -d /usr/include ; then + CONFIG_HOST=/usr + fi +fi + +opt_host() { + CONFIG_HOST="$1" + return 0 +} + +if test ! -z "$BIND" ; then + for bind in $BIND ; do + if test -d $BUILD/$bind ; then + . $BUILD/$bind/bind.conf + else + . $BUILD/bin/$bind.bind + fi + done +fi + +# +# Parse command line arguments. +# +err='' + +if test ! -z "$CONFIG_FLAGS" ; then + for arg in $CONFIG_FLAGS ; do + for opt in $BIND_OPTS ; do + case "$arg" in + $opt=* | -$opt=* | --$opt=* ) + opt_$opt `echo "$arg" | sed 's/[-_a-zA-Z0-9]*=//'` + break + ;; + esac + done + done +fi + + +if test ! -z "$*" ; then + for arg in $* ; do + err=$arg + for opt in $BIND_OPTS ; do + case "$arg" in + $opt=* | -$opt=* | --$opt=* ) + opt_$opt `echo "$arg" | sed 's/[-_a-zA-Z0-9]*=//'` + err='' + break + ;; + esac + done + if test ! -z "$err" ; then + break + fi + done +fi + +CONFIG_FLAGS='' + +if test ! -z "$err" ; then + echo "config: $err: invalid option." + echo + echo "Valid Options:" + echo -n >config.help + if test ! -z "$BIND" ; then + for use in $BIND ; do + if test -f $BUILD/$use/help.conf ; then + cat $BUILD/$use/help.conf >>config.help + fi + if test -f $BUILD/bin/$use.help ; then + cat $BUILD/bin/$use.help >>config.help + fi + done + sort >$CONFIG +echo "#define __CONFIG_H__" >>$CONFIG + +CONFIG_LIBS="" + +if test ! -z "$BIND" ; then + for bind in $BIND ; do + if test -d $BUILD/$bind ; then + . $BUILD/$bind/make.conf + CONFIG_LIBS='-l'$bind' '"$CONFIG_LIBS" + MAKEFILES="$MAKEFILES"' '$BUILD/$bind/Makefile + else + . $BUILD/bin/$bind.make + fi + done +fi + +if test ! -z "$CONFIG_LIBS" ; then + echo "LIBS=$CONFIG_LIBS" >>config.make +fi + +if test ! -z "$MAKEFILES" ; then + for makefile in $MAKEFILES ; do + cat config.make >$makefile + cat $makefile.in >>$makefile + done +fi + +echo "#endif" >>$CONFIG + + +if test -z "$CONFIG_CACHE" ; then + CONFIG_CACHE='config.cache' + CONFIG_FLAGS='' +else + CONFIG_FIRST='' +fi + +echo "CONFIG_CACHE="$CONFIG_CACHE >>config.cache + +if test -f conftest.c ; then + rm -f conftest.c +fi + +if test -f conftest.o ; then + rm conftest.o +fi + +if test ! -z "$CONFIG_FIRST" ; then + $CONFIG_FIRST +fi + diff --git a/sdk/bin/config.sub b/sdk/bin/config.sub new file mode 100755 index 0000000..81a7488 --- /dev/null +++ b/sdk/bin/config.sub @@ -0,0 +1,38 @@ +fn_find_fpath() { + save_ifs="$IFS" + IFS="${IFS}:" + for dir in $3 ; do + if test $1 $dir/$2 ; then + IFS="$save_ifs" + return 0 + fi + done + IFS="$save_ifs" + return 1 +} + +fn_find_type() { + fail=$1 + shift + text=$1 + shift + for fn in $* ; do + if test -f "$fn" ; then + grep "$text" <$fn >/dev/null + if test ! $? = 1 ; then + return 1 + fi + fi + done + echo "#define "$fail >>$CONFIG + return 0 +} + +fn_find_file() { + if test ! -f $2 ; then + echo "#define "$1 >>$CONFIG + return 1 + fi + return 0 +} + diff --git a/sdk/bin/diag b/sdk/bin/diag new file mode 100755 index 0000000..aa56844 --- /dev/null +++ b/sdk/bin/diag @@ -0,0 +1,171 @@ +#!/bin/sh + +files='' +ldd='no' +gcc='no' +hardware='no' +startup='no' +drivers='no' +symbols='no' +tracer='' + +if [ -f /usr/bin/strace ] ; then + tracer='strace' +fi + +if [ -f /bin/strace ] ; then + tracer='strace' +fi + +if [ -f /sbin/strace ] ; then + tracer='strace' +fi + +if [ -f /bin/ldd ] ; then + ldd='yes' +fi + +if [ -f /usr/bin/ldd ] ; then + ldd='yes' +fi + +if [ -f /usr/bin/gcc ] ; then + gcc='yes' +fi + +if [ -f /usr/local/bin/gcc ] ; then + gcc='yes' +fi + +if [ -f config.diag ] ; then + . ./config.diag +fi + +if [ ! -z "$title" ] ; then + echo $title +fi + +if [ ! -z "$strace" ] ; then + for trace in $strace ; do + echo + ls -l $trace + if [ $ldd = 'yes' ] ; then + echo + echo "Library map for " $trace + ldd $trace + fi + if [ $symbols = 'yes' ] ; then + echo + nm $trace + fi + if [ ! -z "$tracer" ] ; then + echo + $tracer $opts $trace 2>&1 + fi + done +fi + +echo +echo -n "System Type: " +uname -s + +echo -n "Achitecture: " +uname -m + +echo -n "Release: " +uname -r + +if [ $gcc = 'yes' ] ; then + echo + echo "GCC Information:" + gcc -v 2>&1 +fi + +if [ -f /proc/meminfo ] ; then + echo + echo "Memory:" + cat /proc/meminfo +fi + +echo "" +echo "Disks:" +df + +if [ $startup = 'yes' ] ; then + + if [ -d /etc/rc.d ] ; then + echo + echo "Services:" + ls -l /etc/rc.d + if [ -d /etc/rc.d/rc3.d ] ; then + echo + echo "Startup:" + ls /etc/rc.d/rc3.d + fi + fi +fi + +if [ -f config.cache ] ; then + echo + echo "Configuration:" + cat config.cache +fi + +if [ -f config.cc ] ; then + echo + echo "Compiler:" + cat config.cc +fi + +if [ ! -z "$files" ] ; then + for file in $files ; do + if [ -f $file ] ; then + echo + echo "Found: " $file + echo + cat $file + fi + done +fi + +if [ $drivers = 'yes' ] ; then + + if [ -f /proc/modules ] ; then + echo + echo "Modules:" + cat /proc/modules + fi +fi + +if [ $hardware = 'yes' ] ; then + + if [ -f /proc/devices ] ; then + echo + echo "Devices:" + cat /proc/devices + fi + + if [ -f /proc/ioports ] ; then + echo + echo "Ports:" + cat /proc/ioports + fi + + if [ -f /proc/interrupts ] ; then + echo + echo "Interrupts:" + cat /proc/interrupts + fi + + if [ -f /proc/dma ] ; then + echo + echo "DMA:" + cat /proc/dma + fi + + if [ -f /proc/cpuinfo ] ; then + echo + cat /proc/cpuinfo + fi +fi + diff --git a/sdk/bin/dist b/sdk/bin/dist new file mode 100755 index 0000000..43c6ef9 --- /dev/null +++ b/sdk/bin/dist @@ -0,0 +1,63 @@ +#!/bin/sh + +if test ! -f config.dist ; then + echo "dist: config.dist missing!" +fi + +# defaults! + +distdir=$1 +config="config.dist config.pkg build" +exclude="*.o *.a config.cc config.cache config *.tar.gz *~ core Makefile" +exclude_exe="true" +exclude_files=".EXCLUDE" + +. ./config.dist + +root=`pwd` +dist=$package'-'$version +cd .. + +if test ! $dist = $root ; then + rm -f $dist + ln -s $root $dist +fi + +xlist=$dist/.EXCLUDE +echo -n >$xlist +for file in $exclude_files ; do + echo $dist/$file >>$xlist +done + +flist="" + +for cfg in $include $config ; do + flist=$flist' '$dist/$cfg +done + +for dir in $examine ; do + flist=$flist' '$dist/$dir + if test $exclude_exe = "true" ; then + find $dist/$dir -perm +1 -type f -follow -print >>$xlist + fi + for deny in $exclude ; do + find $dist/$dir -follow -name $deny -print >>$xlist + done +done + +target=$dist/$dist.tar.gz +if test -d $distdir ; then + rm -f $distdir/${package}*.tar.gz + target=$distdir/$dist.tar.gz + if test -f $dist/$package'.lsm' ; then + cp -f $dist/$package'.lsm' $distdir + fi +fi + +tar -X $xlist -cvhzf $target $flist + +if [ ! $dist = $root ] ; then + rm $dist +fi + + diff --git a/sdk/bin/disthtml b/sdk/bin/disthtml new file mode 100755 index 0000000..4caa151 --- /dev/null +++ b/sdk/bin/disthtml @@ -0,0 +1,31 @@ +#!/bin/sh + +manprefix=$2 + +if test -f config.dist ; then + . ./config.dist +fi + +if test -z $htmlhome ; then + htmlhome=$1/$package +else + htmlhome=$1/$htmlhome +fi + +man2html $manprefix $manpages $htmlhome + +for lsmpage in $lsmpages ; do + echo "Creating $lsmpage.html..." + lsm2html $lsmpage >$htmlhome/$lsmpage.html +done + +for txtpage in $txtpages ; do + echo "Creating $txtpage.txt" + cp $txtpage $htmlhome/$txtpage.txt +done + +for htmlpage in $htmlpages ; do + echo "Copying $htmlpage" + cp -f html/$htmlpage $htmlhome/$htmlpage +done + diff --git a/sdk/bin/install.bind b/sdk/bin/install.bind new file mode 100755 index 0000000..1a00236 --- /dev/null +++ b/sdk/bin/install.bind @@ -0,0 +1,55 @@ +BIND_OPTS=$BIND_OPTS' prefix eprefix share bindir sbindir confdir mandir infodir libdir slibdir root htmldir distdir' + +opt_prefix() { + CONFIG_PREFIX="$1" +} + +opt_eprefix() { + CONFIG_EPREFIX="$1" +} + +opt_share() { + CONFIG_SHARE="$1" +} + +opt_bindir() { + CONFIG_BINDIR="$1" +} + +opt_sbindir() { + CONFIG_SBINDIR="$1" +} + +opt_confdir() { + CONFIG_CONFDIR="$1" +} + +opt_root() { + CONFIG_ROOT="$1" +} + +opt_libdir() { + CONFIG_LIBDIR="$1" +} + +opt_slibdir() { + CONFIG_SLIBDIR="$1" +} + +opt_mandir() { + CONFIG_MANDIR="$1" +} + +opt_infodir() { + CONFIG_INFODIR="$1" +} + +opt_htmldir() { + CONFIG_HTMLDIR="$1" +} + +opt_distdir() { + CONFIG_DISTDIR="$1" +} + + diff --git a/sdk/bin/install.help b/sdk/bin/install.help new file mode 100755 index 0000000..6907439 --- /dev/null +++ b/sdk/bin/install.help @@ -0,0 +1,12 @@ +--root= Installation root offset (NONE) +--prefix= Default installation prefix (/usr) +--eprefix= Execution installation prefix (/usr) +--bindir= Bin directory ($exec-prefix/bin) +--sbindir= System bin directory ($exec-prefix/sbin) +--libdir= Library directory ($exec-prefix/lib) +--slibdir= System library directory ($exec-prefix/lib) +--confdir= Config file directory (/etc) +--share= Shared data directory ($prefix/share) +--mandir= Manual directory ($share/man) +--infodir= Info file directory ($share/info) +--htmldir= HTML Documentation ($share/html) diff --git a/sdk/bin/install.make b/sdk/bin/install.make new file mode 100755 index 0000000..fc63cc6 --- /dev/null +++ b/sdk/bin/install.make @@ -0,0 +1,112 @@ +echo "root="$CONFIG_ROOT >>config.make + +if test -z "$CONFIG_PREFIX" ; then + echo 'prefix=$(root)'$CONFIG_HOST >>config.make +else + echo 'prefix=$(root)'$CONFIG_PREFIX >>config.make +fi + +if test -z "$CONFIG_EPREFIX" ; then + echo 'eprefix=$(prefix)' >>config.make +else + echo 'eprefix=$(root)'$CONFIG_EPREFIX >>config.make +fi + +if test -z "$CONFIG_SHARE" ; then + if test -d $CONFIG_HOST/share ; then + echo 'share=$(prefix)/share' >>config.make + else + echo 'share=$(prefix)' >>config.make + fi +else + echo 'share=$(root)'$CONFIG_SHARE >>config.make +fi + + +if test -z "$CONFIG_CONFDIR" ; then + echo 'SYSCONFDIR=$(root)/etc' >>config.make +else + echo 'SYSCONFDIR=$(root)'$CONFIG_CONFDIR >>config.make +fi + +if test -z "$CONFIG_BINDIR" ; then + echo 'BINDIR=$(eprefix)/bin' >>config.make +else + echo 'BINDIR=$(root)'$CONFIG_BINDIR >>config.make +fi + +if test -z "$CONFIG_SBINDIR" ; then + if test -d $CONFIG_HOST/sbin ; then + echo 'SBINDIR=$(eprefix)/sbin' >>config.make + else + echo 'SBINDIR=$(root)/etc' >>config.make + fi +else + echo 'SBINDIR=$(root)'$CONFIG_SBINDIR >>config.make +fi + +if test -z "$CONFIG_LIBDIR" ; then + echo 'LIBDIR=$(eprefix)/lib' >>config.make +else + echo 'LIBDIR=$(root)'$CONFIG_LIBDIR >>config.make +fi + +if test -z "$CONFIG_SLIBDIR" ; then + echo 'SLIBDIR=$(root)/lib' >>config.make +else + echo 'SLIBDIR=$(root)'$CONFIG_SLIBDIR >>config.make +fi + +if test -z "$CONFIG_MANDIR" ; then + if test -d $CONFIG_HOST/share/man ; then + echo 'MANDIR=$(share)/man' >>config.make + else + echo 'MANDIR=$(prefix)/man' >>config.make + fi +else + echo 'MANDIR=$(root)'$CONFIG_MANDIR >>config.make +fi + +if test -z "$CONFIG_INFODIR" ; then + if test -d $CONFIG_HOST/share/info ; then + echo 'INFODIR=$(share)/info' >>config.make + else + echo 'INFODIR=$(prefix)/info' >>config.make + fi +else + echo 'INFODIR=$(root)'$CONFIG_INFODIR >>config.make +fi + +if test -z "$CONFIG_HTMLDIR" ; then + if test -d $CONFIG_HOST/share/html ; then + echo 'HTMLDIR=$(share)/html' >>config.make + else + echo 'HTMLDIR=$(prefix)/html' >>config.make + fi +else + echo 'HTMLDIR=$(root)'$CONFIG_HTMLDIR >>config.make +fi + +if test -z "$CONFIG_DISTDIR" ; then + if test -d $CONFIG_HOST/share/dist ; then + echo 'DISTDIR=$(share)/dist' >>config.make + else + echo 'DISTDIR=$(prefix)/dist' >>config.make + fi +else + echo 'DISTDIR=$(root)'$CONFIG_DISTDIR >>config.make +fi + +echo "CONFIG_ROOT="$CONFIG_ROOT >>config.cache +echo "CONFIG_PREFIX="$CONFIG_PREFIX >>config.cache +echo "CONFIG_EPREFIX="$CONFIG_EPREFIX >>config.cache +echo "CONFIG_SHARE="$CONFIG_SHARE >>config.cache +echo "CONFIG_CONFDIR="$CONFIG_CONFDIR >>config.cache +echo "CONFIG_BINDIR="$CONFIG_BINDIR >>config.cache +echo "CONFIG_SBINDIR="$CONFIG_SBINDIR >>config.cache +echo "CONFIG_LIBDIR="$CONFIG_LIBDIR >>config.cache +echo "CONFIG_SLIBDIR="$CONFIG_SLIBDIR >>config.cache +echo "CONFIG_INFODIR="$CONFIG_INFODIR >>config.cache +echo "CONFIG_MANDIR="$CONFIG_MANDIR >>config.cache +echo "CONFIG_HTMLDIR="$CONFIG_HTMLDIR >>config.cache +echo "CONFIG_DISTDIR="$CONFIG_DISTDIR >>config.cache diff --git a/sdk/bin/instinit b/sdk/bin/instinit new file mode 100755 index 0000000..fdd0899 --- /dev/null +++ b/sdk/bin/instinit @@ -0,0 +1,61 @@ +#!/bin/sh +run=/etc/rc.d +levels="" +base=$1 + +if [ ! -d $run ] ; then + exit 0 +fi + +if [ -d $run/init.d ] ; then + levels=$run + init='../init.d/'$1'.init' + run=$run/init.d + target=$1'.init' +else + target='rc.'$1 + levels='false' +fi + +source=$1'.init' +shift + +if [ ! -f "$run/$target" ] ; then + echo 'Adding '$target' to '$run + if [ -f /etc/sudo.conf ] ; then + sudo root install -o root -m 0700 $source $run/$target + else + su root -c "install -o root -m 0700 $source $run/$target" + fi +else + exit 0 +fi + +if [ -z "$BASH" ] ; then + exit 0 +fi + +if [ -z "$levels" ] ; then + exit 0 +fi + +initial=$1 +shift + +for level in $* ; do + runlvl=$levels'/rc'$level'.d' + if [ ! -d $runlvl ] ; then + continue + fi + cd $runlvl + count=$initial + while [ -f *$count* ] ; do + count=$[count + 1] + done + target='S'$count$base + echo 'Adding '$target' to '$runlvl + ln -s $init $target +done + + + diff --git a/sdk/bin/instman b/sdk/bin/instman new file mode 100755 index 0000000..d8ca6f7 --- /dev/null +++ b/sdk/bin/instman @@ -0,0 +1,32 @@ +#!/bin/sh +prefix=$1 +set=$2 +shift +shift + +for page in $* ; do + source=$page'.'$set + target="" + if [ -d $prefix/man$set ] ; then + mandir=$prefix/man$set + target=$mandir/$page'.'$set + fi + if [ -z $target ] ; then + roff=nroff + if [ -f /usr/lib/groff ] ; then + roff="groff -Tascii" + fi + if [ -f /usr/local/lib/groff ] ; then + roff="groff -Tascii" + fi + if [ -d $prefix/cat$set ] ; then + mandir=$prefix/cat$set + target=$mandir/$page.set + $roff -man <$source >$page'.man' + source=$page'.man' + fi + fi + echo 'Adding '$page' to '$mandir + install -g man -m 0664 $source $target +done + diff --git a/sdk/bin/instso b/sdk/bin/instso new file mode 100755 index 0000000..148a82a --- /dev/null +++ b/sdk/bin/instso @@ -0,0 +1,39 @@ +#!/bin/sh + +prefix=$1 +libname=$2 +version=$3 + +# find project root. + +root=`dirname $0` +root=`dirname $root` + +# fetch package 'version' level from project root (config.dist). + +if [ -f $root/config.dist ] ; then + . $root/config.dist +fi + +if [ ! -d $(prefix)/lib ] ; then + prefix=$/usr + if [ ! -d /usr/lib ] ; then + exit 0 + fi +fi + +prefix=$prefix/lib +echo 'Installing '$libname'.so to '$prefix +cp -f $libname'.so' $(prefix)/$(libname)'.so.'$version +ldconfig -n $(prefix) + +liblist=`find $(prefix) -name "$(libname).so.*" -type f -print` +for lib in $liblist ; do + if [ ! $lib = $libname'.so.'$version ] ; then + rm $lib + fi +done + +ldconfig -n $(prefix) + + diff --git a/sdk/bin/instsvc b/sdk/bin/instsvc new file mode 100755 index 0000000..468fe2a --- /dev/null +++ b/sdk/bin/instsvc @@ -0,0 +1,27 @@ +#!/bin/sh + +etc='/etc' + +if [ ! -d "$etc" ] ; then + etc='' + if [ -d /config ] ; then + etc='/config' + fi +fi + +if [ -z "$etc" ] ; then + exit 0 +fi + +svc=$etc/$1 +shift +base=$1 +shift +line=$base" $*" + +grep "^$base" <$svc >/dev/null +if [ $? = 1 ] ; then + echo "Adding $base to $svc" + echo $line >>$svc +fi + diff --git a/sdk/bin/rootsudo b/sdk/bin/rootsudo new file mode 100755 index 0000000..3ff65f1 --- /dev/null +++ b/sdk/bin/rootsudo @@ -0,0 +1,6 @@ +#!/bin/sh +if [ -f /etc/sudo.conf ] ; then + sudo root $* +else + su root -c "$*" +fi diff --git a/sdk/config.h b/sdk/config.h new file mode 100644 index 0000000..6af2aa5 --- /dev/null +++ b/sdk/config.h @@ -0,0 +1,16 @@ +#ifndef __CONFIG_H__ +#define __CONFIG_H__ +#define EMPTY 0 +#define UCHAR_T_MISSING +#define FD_T_MISSING +#define STRLWR_F_MISSING +#define STRISTR_F_MISSING +#define PROCESS_H_MISSING +#define SYS_SELECT_H_MISSING +#define SELECT_H_MISSING +#define POLL_H_MISSING +#define SYS_POLL_H_MISSING +#define SYSCONF_H_MISSING +#define ENV_H_MISSING +#define IO_H_MISSING +#endif diff --git a/sdk/dev/Makefile.in b/sdk/dev/Makefile.in new file mode 100644 index 0000000..1375154 --- /dev/null +++ b/sdk/dev/Makefile.in @@ -0,0 +1,19 @@ +# +# Template to build device interface library. +# $Id$ +# Copyright (c) 1997 by Tycho Softworks. +# + +OBJS = inkey.o empty.o input.o waitfor.o waitsync.o xmit.o \ + speed.o format.o flowctrl.o interactive.o stty.o + +.c.o: + $(CC) $(CFLAGS) $(OPTIMIZE) -I.. -o $@ -c $< + $(AR) r ../lib/libdev.a $@ + +all: $(OBJS) + ranlib ../lib/libdev.a + +clean: + rm *.o + diff --git a/sdk/dev/bind.conf b/sdk/dev/bind.conf new file mode 100644 index 0000000..e69de29 diff --git a/sdk/dev/empty.c b/sdk/dev/empty.c new file mode 100644 index 0000000..87114a3 --- /dev/null +++ b/sdk/dev/empty.c @@ -0,0 +1,15 @@ +/* + * Empty the serial input fifo buffer. + * $Id$ + * Copyright (c) 1997 by Tycho Softworks. + * For conditions of distribution and reuse see product license. + */ + +#include + +void empty(int fd) +{ + while(inkey(fd, 0) > -1) + continue; +} + diff --git a/sdk/dev/flowctrl.c b/sdk/dev/flowctrl.c new file mode 100644 index 0000000..7977b1c --- /dev/null +++ b/sdk/dev/flowctrl.c @@ -0,0 +1,47 @@ +/* + * Serial line flow control option settings. + * $Id$ + * Copyright (c) 1997 by Tycho Softworks. + * For conditions of distribution and reuse see product license. + */ + +#include +#ifndef TERMIOS_H_MISSING +#include +#endif + +#ifndef CRTSCTS +#ifdef CTSFLOW +#define CRTSCTS CTSFLOW | CRTSFL +#endif +#endif + +int setflowctrl(stty_t stty, FLOWCONTROL flow) +{ +#ifndef TERMIOS_H_MISSING + + struct termios *tios = stty; + tios->c_cflag &= ~CRTSCTS; + tios->c_iflag &= ~(IXON | IXOFF | IXANY); + + switch(flow) + { + case FC_HARD: + tios->c_cflag |= CRTSCTS; + break; + case FC_SOFT: + tios->c_iflag |= (IXON | IXOFF | IXANY); + break; + case FC_FULL: + tios->c_cflag |= CRTSCTS; + tios->c_iflag |= (IXON | IXOFF | IXANY); + break; + } +#endif + return 0; +} + + + + + diff --git a/sdk/dev/format.c b/sdk/dev/format.c new file mode 100644 index 0000000..508ec6c --- /dev/null +++ b/sdk/dev/format.c @@ -0,0 +1,64 @@ +/* + * Specify serial port data line format. + * $Id$ + * Copyright (c) 1997 by Tycho Softworks. + * For conditions of distribution and reuse see product license. + */ + +#include +#ifndef TERMIOS_H_MISSING +#include +#endif + +int setformat(stty_t stty, char *format) +{ +#ifndef TERMIOS_H_MISSING + struct termios *tios = stty; + + tios->c_cflag &= ~CSIZE; + if(format[2] == '1') + tios->c_cflag &= ~CSTOPB; + else + tios->c_cflag |= CSTOPB; + + switch(format[0]) + { + case '5': + tios->c_cflag |= CS5; + break; + case '6': + tios->c_cflag |= CS6; + break; + case '7': + tios->c_cflag |= CS7; + break; + case '8': + tios->c_cflag |= CS8; + break; + } + + switch(format[1]) + { + case 'n': + case 'N': + tios->c_cflag &= ~(PARODD | PARENB); + break; + case 'e': + case 'E': + tios->c_cflag |= PARENB; + tios->c_cflag &= ~PARODD; + break; + case 'o': + case 'O': + tios->c_cflag |= (PARENB | PARODD); + break; + } + +#endif + return 0; +} + + + + + diff --git a/sdk/dev/inkey.c b/sdk/dev/inkey.c new file mode 100644 index 0000000..1003905 --- /dev/null +++ b/sdk/dev/inkey.c @@ -0,0 +1,76 @@ +/* + * Wait and read single byte input from device. + * $Id$ + * Copyright (c) 1997 by Tycho Softworks. + * For conditions of distribution and reuse see product license. + */ + +#include +#include +#include + +#ifndef SYS_POLL_H_MISSING +#define USE_POLL +#endif + +#ifndef POLL_H_MISSING +#define USE_POLL +#endif + +#ifdef USE_POLL + +int inkey(fd_t fd, int timeout) +{ + struct pollfd poller; + uchar buf; + + poller.fd = fd; + poller.revents = 0; + poller.events = POLLIN ; + + if(!poll(&poller, 1, timeout)) + return -1; + + if(poller.revents & (POLLERR | POLLHUP)) + return -1; + + if(read(fd, &buf, 1) != 1) + return -1; + + return buf; +} + +#else + +int inkey(fd_t fd, int timeout) +{ + fd_set inp,out,exc; + struct timeval timer; + uchar buf; + + FD_ZERO(&inp); + FD_ZERO(&out); + FD_ZERO(&exc); + + FD_SET(fd, &inp); + FD_SET(fd, &exc); + + timer.tv_sec = timeout / 1000; + timer.tv_usec = timeout % 1000; + + if(!select(fd + 1, &inp, &out, &exc, &timer)) + return -1; + + if(FD_ISSET(fd, &exc)) + return -1; + + if(FD_ISSET(fd, &inp)) + { + if(read(fd, &buf, 1) != 1) + return -1; + return buf; + } + return -1; +} + +#endif diff --git a/sdk/dev/input.c b/sdk/dev/input.c new file mode 100644 index 0000000..95494d3 --- /dev/null +++ b/sdk/dev/input.c @@ -0,0 +1,34 @@ +/* + * Read a line of input from device. + * $Id$ + * Copyright (c) 1997 by Tycho Softworks. + * For conditions of distribution and reuse see product license. + */ + +#include +#include + +int input(int fd, uchar *buf, size_t len, int timeout, const uchar *term) +{ + int key; + int idx = 0; + + while(idx < len) + { + key = inkey(fd, timeout); + if(key < 0) + return idx; + + if(!key) + continue; + + buf[idx++] = (uchar)(key & 0xff); + if(strchr((char *)term, key)) + break; + } + buf[idx] = 0; + return idx; +} + + + diff --git a/sdk/dev/interactive.c b/sdk/dev/interactive.c new file mode 100644 index 0000000..be998e6 --- /dev/null +++ b/sdk/dev/interactive.c @@ -0,0 +1,35 @@ +/* + * Select raw or "interactive" terminal mode for device. + * $Id$ + * Copyright (c) 1997 by Tycho Softworks. + * For conditions of distribution and reuse see product license. + */ + +#include +#ifndef TERMIOS_H_MISSING +#include +#endif + +bool interactive(stty_t stty, bool mode) +{ +#ifndef TERMIOS_H_MISSING + + struct termios *tios = stty; + + if(mode) + { + + } + else + { + tios->c_oflag = 0; + tios->c_lflag = 0; + } +#endif + return mode; +} + + + + + diff --git a/sdk/dev/make.conf b/sdk/dev/make.conf new file mode 100644 index 0000000..8a396ea --- /dev/null +++ b/sdk/dev/make.conf @@ -0,0 +1,5 @@ +inc=$CONFIG_HOST/include +fn_find_file TERMIOS_H_MISSING $inc/termios.h +fn_find_file TERMIO_H_MISSING $inc/termio.h +fn_find_file TERMCAP_H_MISSING $inc/termcap.h + diff --git a/sdk/dev/speed.c b/sdk/dev/speed.c new file mode 100644 index 0000000..f9fee56 --- /dev/null +++ b/sdk/dev/speed.c @@ -0,0 +1,75 @@ +/* + * Specify serial communications speed. + * $Id$ + * Copyright (c) 1997 by Tycho Softworks. + * For conditions of distribution and reuse see product license. + */ + +#include +#ifndef TERMIOS_H_MISSING +#include +#endif + +int setspeed(stty_t tios, ulong speed) +{ + +#ifdef B38400 + int rate = B38400; +#else + int rate = B19200; +#endif + + switch(speed) + { + case 110: + rate = B110; + break; + case 300: + rate = B300; + break; + case 600: + rate = B600; + break; + case 1200: + rate = B1200; + break; + case 2400: + rate = B2400; + break; + case 4800: + rate = B4800; + break; + case 9600: + rate = B9600; + break; + case 19200: + rate = B19200; + break; +#ifdef B38400 + case 38400: + rate = B38400; + break; +#endif +#ifdef B57600 + case 57600: + rate = B57600; + break; +#endif +#ifdef B115200 + case 115200: + rate = B115200; + break; +#endif + } + +#ifndef TERMIOS_H_MISSING + cfsetospeed(tios, rate); + cfsetispeed(tios, rate); +#endif + return rate; +} + + + + + diff --git a/sdk/dev/stty.c b/sdk/dev/stty.c new file mode 100644 index 0000000..9a465da --- /dev/null +++ b/sdk/dev/stty.c @@ -0,0 +1,29 @@ +/* + * Portable routines to get and set serial device attributes. + * $Id$ + * Copyright (c) 1997 by Tycho Softworks. + * For conditions of distribution and reuse see product license. + */ + +#include + +#ifndef TERMIOS_H_MISSING +#include + +stty_t getstty(fd_t fd) +{ + stty_t stty = (stty_t)malloc(sizeof(struct termios)); + tcgetattr(fd, stty); + return stty; +} + +void putstty(fd_t fd, stty_t stty, bool now) +{ + if(now) + tcsetattr(fd, TCSANOW, stty); + else + tcsetattr(fd, TCSADRAIN, stty); + free(stty); +} +#endif + diff --git a/sdk/dev/termcap.h b/sdk/dev/termcap.h new file mode 100644 index 0000000..e2cbb5b --- /dev/null +++ b/sdk/dev/termcap.h @@ -0,0 +1,17 @@ +/* + * Portable termcap header. + * $Id$ + * Copyright (c) 1997 by Tycho Softworks. + * For conditions on distribution and reuse see product license. + */ + +#ifndef __DEV_TERMCAP_H__ +#define __DEV_TERMCAP_H__ + +#ifndef TERMCAP_H_MISSING +#include +#else +#endif + +#endif + diff --git a/sdk/dev/tty.h b/sdk/dev/tty.h new file mode 100644 index 0000000..3ff02ca --- /dev/null +++ b/sdk/dev/tty.h @@ -0,0 +1,72 @@ +/* + * Portable serial interface control and operation. + * $Id$ + * Copyright (c) 1997 by Tycho Softworks. + * For conditions of distribution and reuse see product license. + */ + +#ifndef __DEV_TTY_H__ +#define __DEV_TTY_H__ + +#ifndef __STD_TYPES_H__ +#include +#endif + +#ifndef __STD_FILES_H__ +#include +#endif + +typedef void *stty_t; + +#ifdef __cplusplus +extern "C" { +#endif + +#define ulock_device(lck) ulock_file(lck) + +typedef enum +{ + FC_NONE, + FC_HARD, + FC_SOFT, + FC_FULL +} FLOWCONTROL; + +#ifdef __NAMESPACE +#define lock_device __NAMESPACE(lock_device) +#define setspeed __NAMESPACE(setspeed) +#define setformat __NAMESPACE(setformat) +#define setflowctrl __NAMESPACE(setflowctrl) +#define waitfor __NAMESPACE(waitfor) +#define waitsync __NAMESPACE(waitsync) +#define input __NAMESPACE(input) +#define dropdtr __NAMESPACE(dropdtr) +#define inkey __NAMESPACE(inkey) +#define interactive __NAMESPACE(interactive) +#define readcrc __NAMESPACE(readcrc) +#define writecrc __NAMESPACE(writecrc) +#define readcsum __NAMESPACE(readcsum) +#define writecsum __NAMESPACE(writecsum) +#define xmit __NAMESPACE(xmit) +#define empty __NAMESPACE(empty) +#endif + +stty_t getstty(fd_t fd); +void putstty(fd_t fd, stty_t stty, bool now); +int setspeed(stty_t stty, ulong speed); +int setformat(stty_t stty, char *format); +int setflowctrl(stty_t stty, FLOWCONTROL flow); +int waitfor(fd_t fd, uchar *str, size_t len, int timeout, ulong maxbytes); +int waitsync(fd_t fd, uchar *list, size_t len, int timeout, ulong maxbytes); +int input(fd_t fd, uchar *buf, size_t len, int timeout, const uchar *term); +int dropdtr(fd_t fd); +int inkey(fd_t fd, int timeout); +bool interactive(stty_t stty, bool mode); +int xmit(fd_t fd, char *str); +void empty(fd_t fd); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/sdk/dev/waitfor.c b/sdk/dev/waitfor.c new file mode 100644 index 0000000..36fabec --- /dev/null +++ b/sdk/dev/waitfor.c @@ -0,0 +1,39 @@ +/* + * Wait for specified input from device. + * $Id$ + * Copyright (c) 1997 by Tycho Softworks. + * For conditions on redistribution and reuse see product license. + */ + +#include +#include + +int waitfor(int fd, uchar *list, size_t len, int timeout, ulong max) +{ + int key; + int idx = 0; + uchar *mem = (uchar *)malloc(len); + + while(max--) + { + key = inkey(fd, timeout); + if(key < 0) + return key; + + if(idx < len) + mem[idx++] = (uchar)(key & 0xff); + else + { + for(idx = 0; idx < len; ++idx) + mem[idx] = mem[idx + 1]; + + mem[len - 1] = (uchar)(key & 0xff); + } + if(!memcmp(mem, list, len)) + return 0; + } + return -1; +} + + + diff --git a/sdk/dev/waitsync.c b/sdk/dev/waitsync.c new file mode 100644 index 0000000..f4596e1 --- /dev/null +++ b/sdk/dev/waitsync.c @@ -0,0 +1,32 @@ +/* + * Wait for a sync input value from a device. + * $Id$ + * Copyright (c) 1997 by Tycho Softworks. + * For conditions of distribution and reuse see product license. + */ + +#include + +int waitsync(int fd, uchar *list, size_t len, int timeout, ulong max) +{ + int key; + int idx; + uchar buf; + + while(max--) + { + key = inkey(fd, timeout); + if(key < 0) + return key; + + buf = (uchar)(key & 0xff); + + for(idx = 0; idx < len; ++idx) + if(list[idx] == buf) + return buf; + } + return -1; +} + + + diff --git a/sdk/dev/xmit.c b/sdk/dev/xmit.c new file mode 100644 index 0000000..471736d --- /dev/null +++ b/sdk/dev/xmit.c @@ -0,0 +1,31 @@ +/* + * Write output to a device and ignore any incoming (echo) data. + * $Id$ + * Copyright (c) 1997 by Tycho Softworks. + * For conditions of distribution and reuse see product license. + */ + +#include + +int xmit(int fd, char *str) +{ + int len = strlen(str); + int stat; + + while(inkey(fd, 2) > -1) + continue; + + stat = write(fd, str, len); + if(stat < 0) + return stat; + + len = stat; + while(len--) + if(inkey(fd, 0) < 0) + break; + + return stat; +} + + + diff --git a/sdk/net/Makefile.in b/sdk/net/Makefile.in new file mode 100644 index 0000000..bc890f5 --- /dev/null +++ b/sdk/net/Makefile.in @@ -0,0 +1,19 @@ +# +# Template to build net makefile. +# $Id$ +# Copyright (c) 1997 by Tycho Softworks. +# + +OBJS = snmptrap.o gethost.o getservice.o getsocket.o sockname.o \ + tcpsocket.o udpsocket.o init.o tcpstream.o msgport.o netaddr.o + +.c.o: + $(CC) $(CFLAGS) $(OPTIMIZE) -I.. -o $@ -c $< + $(AR) r ../lib/libnet.a $@ + +all: $(OBJS) + ranlib ../lib/libnet.a + +clean: + rm *.o + diff --git a/sdk/net/bind.conf b/sdk/net/bind.conf new file mode 100644 index 0000000..e69de29 diff --git a/sdk/net/gethost.c b/sdk/net/gethost.c new file mode 100644 index 0000000..f74997c --- /dev/null +++ b/sdk/net/gethost.c @@ -0,0 +1,39 @@ +/* + * Portable and simple host name lookup fuction. + * $Id$ + * Copyright (c) 1997 by Tycho Softworks. + * For conditions of distribution and reuse see product license. + */ + +#include + +struct hostent *gethost(const char *hostname) +{ + static struct in_addr saddr; + struct hostent *hp; + static struct hostent np; + static char host[24]; + static char *alias[] = {NULL}; + static struct in_addr *alist[] = {&saddr, NULL}; + + if(!hostname) + return NULL; + + if(isdigit(*hostname)) + { + saddr.s_addr = inet_addr(hostname); + hp = gethostbyaddr((void *)&saddr, sizeof(struct in_addr), AF_INET); + if(hp) + return hp; + + strcpy(host, hostname); + np.h_name = host; + np.h_aliases = alias; + np.h_addrtype = AF_INET; + np.h_length = 4; + np.h_addr_list = (char **)alist; + return &np; + } + else + return gethostbyname(hostname); +} diff --git a/sdk/net/getservice.c b/sdk/net/getservice.c new file mode 100644 index 0000000..fed448e --- /dev/null +++ b/sdk/net/getservice.c @@ -0,0 +1,45 @@ +/* + * Simple portable service name lookup. + * $Id$ + * Copyright (c) 1997 by Tycho Softworks. + * For conditions of distribution and reuse see product license. + */ + +#include +#include + +int getservice(const char *service) +{ + char servname[32]; + char *p; + struct servent *svc; + struct protoent *proto; + + if(isdigit(*service)) + return atoi(service); + + strcpy(servname, service); + p = strchr(servname, '/'); + if(!p) + strcat(servname, "/tcp"); + + p = strchr(servname, '/'); + *(p++) = 0; + if(isdigit(*p)) + { + proto = getprotobynumber(atoi(p)); + if(!proto) + return 0; + + p = proto->p_name; + } + svc = getservbyname(servname, p); + if(!svc) + return 0; + + return ntohs(svc->s_port); +} + + + + diff --git a/sdk/net/getsocket.c b/sdk/net/getsocket.c new file mode 100644 index 0000000..83ca68a --- /dev/null +++ b/sdk/net/getsocket.c @@ -0,0 +1,43 @@ +#include +#include + +SOCKET getsocket(const char *host, int port, int socktype) +{ + SOCKET so; + struct hostent *hp; + struct sockaddr_in saddr; + struct in_addr *aptr; + char *sp, *p; + char *dup = strdup(host); + + so = socket(AF_INET, socktype, 0); + if(so == INVALID_SOCKET) + { + free(dup); + return so; + } + + sp = dup; + while(NULL != (p = strtok(sp, " ;:\t"))) + { + sp = NULL; + hp = gethost(p); + if(!hp) + continue; + + saddr.sin_family = hp->h_addrtype; + saddr.sin_port = htons(port); + while( (aptr = (struct in_addr *)*(hp->h_addr_list)++) != NULL) + saddr.sin_addr = *aptr; + + if(connect(so, (struct sockaddr *)&saddr, sizeof(saddr))) + continue; + + free(dup); + return so; + } + endsocket(so); + free(dup); + return INVALID_SOCKET; +} + diff --git a/sdk/net/init.c b/sdk/net/init.c new file mode 100644 index 0000000..02575a7 --- /dev/null +++ b/sdk/net/init.c @@ -0,0 +1,20 @@ +/* + * Needed for "winsock" compatibility only. + * $Id$ + * Copyright (c) 1997 by Tycho Softworks. + * For conditions of distribution and reuse see product license. + */ + +#include + +bool init_socket(void) +{ + return TRUE; +} + +void endsocket(SOCKET so) +{ + shutdown(so, 2); + close(so); +} + diff --git a/sdk/net/make.conf b/sdk/net/make.conf new file mode 100644 index 0000000..36fbb70 --- /dev/null +++ b/sdk/net/make.conf @@ -0,0 +1,4 @@ +if test -f $CONFIG_HOST/lib/libsocket.a ; then + CONFIG_LIBS=$CONFIG_LIBS' -lsocket' +fi + diff --git a/sdk/net/msgport.c b/sdk/net/msgport.c new file mode 100644 index 0000000..39c1109 --- /dev/null +++ b/sdk/net/msgport.c @@ -0,0 +1,84 @@ +/* + * Portable network messaging routines. + * $Id$ + * Copyright (c) 1997 by Tycho Softworks. + * For conditions of distribution and reuse see product license. + */ + +#include +#include + +static ushort sequence = 0; + +SOCKET create_msgport(char *mask, int port, int backlog) +{ + if(backlog) + return tcpsocket(mask, port, backlog); + else + return udpsocket(mask, port); +} + +size_t send_msgport(SOCKET so, SOCKMSG *buf, size_t len, bool flag) +{ + size_t stat; + + memset(buf, 0, sizeof(SOCKMSG)); + if(flag) + ++sequence; + buf->header.len = htonl(len); + buf->sequence = sequence; + + stat = send(so, buf, len + sizeof(SOCKMSG), 0); + if (stat > 0) + return stat - sizeof(SOCKMSG); + return stat; +} + +size_t recv_msgport(SOCKET so, SOCKMSG *buf, size_t len, bool any) +{ + int alen; + size_t mlen; + size_t stat; + SOCKMSG saddr; + + for(;;) + { + alen = recv(so, &saddr, sizeof(saddr), MSG_PEEK); + if(alen < 0) + return stat; + + mlen = ntohl(saddr.header.len); + if (mlen > len) + mlen = len; + + stat = recvfrom(so, buf, mlen + sizeof(saddr), 0, (struct sockaddr *)&saddr, &alen); + memcpy(buf, &saddr, alen); + if (stat > 0) + { + if(any && buf->sequence != sequence) + continue; + + return stat - sizeof(SOCKMSG); + } + return stat; + } +} + +size_t reply_msgport(SOCKET so, SOCKMSG *buf, SOCKMSG *org, size_t len) +{ + size_t stat; + SOCKMSG saddr; + + if(!org) + org = buf; + + memcpy(&saddr, org, sizeof(saddr)); + buf->header.len = htonl(len); + stat = sendto(so, buf, len + sizeof(SOCKMSG), 0, (struct sockaddr *)&saddr, sizeof(saddr)); + if (stat > 0) + return stat - sizeof(SOCKMSG); + return stat; +} + + + diff --git a/sdk/net/msgport.h b/sdk/net/msgport.h new file mode 100644 index 0000000..f7817e4 --- /dev/null +++ b/sdk/net/msgport.h @@ -0,0 +1,47 @@ +/* + * Portable network messaging routines. + * $Id$ + * Copyright (c) 1997 by Tycho Softworks. + * For conditions of distribution and reuse see product license. + */ + +#ifndef __NET_MSGPORT_H__ +#define __NET_MSGPORT_H__ + +#ifndef __NET_SOCKET_H__ +#include +#endif + +typedef struct +{ + union + { + struct sockaddr_in addr; + long len; + } header; + ushort sequence; + uchar body[ EMPTY ]; +} SOCKMSG; + +/* msgport control options */ + +enum +{ + MSGPORT_TIMEOUT +}; + +#define attach_tcp(host, port) getsocket(host, port, SOCK_STREAM) +#define attach_udp(host, port) getsocket(host, port, SOCK_DGRAM) + +#ifdef __NAMESPACE +#define create_msgport __NAMESPACE(create_msgport) +#define send_msgport __NAMESPACE(send_msgport) +#define recv_msgport __NAMESPACE(recv_msgport) +#define reply_msgport __NAMESPACE(reply_msgport) +#endif + +SOCKET create_msgport(char *mask, int port, int backlog); +size_t send_msgport(SOCKET so, SOCKMSG *buf, size_t len, bool inc); +size_t recv_msgport(SOCKET so, SOCKMSG *buf, size_t maxlen, bool any); +size_t reply_msgport(SOCKET so, SOCKMSG *buf, SOCKMSG *org, size_t len); +#endif diff --git a/sdk/net/netaddr.c b/sdk/net/netaddr.c new file mode 100644 index 0000000..c156505 --- /dev/null +++ b/sdk/net/netaddr.c @@ -0,0 +1,28 @@ +/* + * Convert network mask or address string into a "BIND" filter mask. + * $Id$ + * Copyright (c) 1997 by Tycho Softworks. + * For conditions of distribution and reuse see product license. + */ + +#include +#include + +struct in_addr *getnetaddr(const char *mask) +{ + static struct in_addr addr; + struct in_addr *aptr; + struct hostent *hp; + + if(!mask) + mask = "0.0.0.0"; + + hp = gethost(mask); + if(!hp) + return NULL; + + while((aptr = (struct in_addr *)*(hp->h_addr_list)++) != NULL) + addr = *aptr; + + return &addr; +} diff --git a/sdk/net/snmptrap.c b/sdk/net/snmptrap.c new file mode 100644 index 0000000..17c9f7c --- /dev/null +++ b/sdk/net/snmptrap.c @@ -0,0 +1,165 @@ +/* + * Generic snmp trap generation routine. + * $Id$ + * Copyright (c) 1997 by Tycho Softworks. + * For conditions of distribution and reuse see product license. + */ + +#include +#include + +int snmptrap(char *host, char *agent, char *community, int id, char *enterprise, char *describe, long ut) +{ + static uchar sysvar[] = {0x06, 0x08, 0x2b, 0x06, 0x01, 0x02, 0x01, 0x01, 0x01, 0x00, 0x04}; + + uchar pkt[256] = {0x30, 0x82, 0x00, 0x00, 0x02, 0x01, 0x00, 0x04}; + char console[129]; + int len; + int pos; + int l1 = 45; + int l2 = 39; + int l3 = 16; + int l2pos; + int l3pos; + int v1; + char *p; + int v2; + ulong hostip; + struct hostent *hp; + struct sockaddr_in target; + struct in_addr *aptr; + int i1, i2; + SOCKET so; + + if(!describe) + describe = ""; + + if(!host) + host = "localhost"; + + if(!agent) + agent = "localhost"; + + hp = gethost(agent); + if(!hp) + return -1; + + while( (aptr = (struct in_addr *)*(hp->h_addr_list)++) != NULL) + memcpy(&hostip, aptr, 4); + + if(!community) + community = "PUBLIC"; + + if(!enterprise) + enterprise = "1.3.6.1.4.1.3.1.1"; + + + so = socket(AF_INET, SOCK_DGRAM, 0); + if(so == INVALID_SOCKET) + return -1; + + len = strlen(community); + l1 = l1 + len + 1; + pkt[8] = (uchar)len; + strcpy((char *)pkt + 9, community); + pos = 9 + len; + pkt[pos++] = 0xa4; + l2pos = pos++; + pkt[pos++] = 0x06; + len = 0; + + v1 = atoi(enterprise); + enterprise = strchr(enterprise, '.'); + v2 = atoi(++enterprise); + len = 1; + pkt[pos + len] = (uchar)(v1 * 40 + v2); + + while(NULL !=(enterprise = strchr(enterprise, '.'))) + pkt[pos + (++len)] = (uchar)atoi(++enterprise); + + pkt[pos] = len; + pos += len + 1; + l1 += len; + l2 += len; + + pkt[pos++] = 0x40; + pkt[pos++] = 0x04; + memcpy(pkt + pos, &hostip, 4); + pos += 4; + + i2 = 0; + i1 = id; + if(id > 5 || id < 0) + { + i1 = 6; + i2 = abs(id); + } + + pkt[pos++] = 0x02; + pkt[pos++] = 0x01; + pkt[pos++] = (uchar)i1; + pkt[pos++] = 0x02; + if(i2 > -1 && i2 < 128) + { + pkt[pos++] = 0x01; + pkt[pos++] = (uchar)i2; + } + else + { + pkt[pos++] = 0x02; + pkt[pos++] = (uchar)(i2 / 256); + pkt[pos++] = (uchar)(i2 % 256); + ++l1; + ++l2; + } + pkt[pos++] = 0x43; + pkt[pos++] = 0x03; + pkt[pos++] = (uchar)((ut / 0x10000) % 256); + pkt[pos++] = (uchar)((ut / 0x100) % 256); + pkt[pos++] = (uchar)(ut % 256); + pkt[pos++] = 0x30; + pkt[pos++] = 0x82; + pkt[pos++] = 0; + l3pos = pos++; + + len = strlen(describe); + pkt[pos++] = 0x30; + pkt[pos++] = 0x82; + pkt[pos++] = 0x00; + pkt[pos++] = len + 12; + memcpy(pkt + pos, sysvar, 11); + pos += 11; + pkt[pos++] = (uchar)len; + strcpy((char *)pkt + pos, describe); + + l1 += len; + l2 += len; + l3 += len; + pos += len; + + pkt[2] = (uchar)(l1 / 256); + pkt[3] = (uchar)(l1 % 256); + pkt[l2pos] = (uchar)l2; + pkt[l3pos] = (uchar)l3; + + + strcpy(console, host); + host = strtok(console, ":\t; \t\n"); + while(NULL != host) + { + hp = gethost(host); + if(!hp) + return -1; + + while( (aptr = (struct in_addr *)*(hp->h_addr_list)++) != NULL) + target.sin_addr = *aptr; + + target.sin_family = hp->h_addrtype; + target.sin_port = htons(SNMP_TRAP_PORT); + host = strtok(NULL, ":\t;"); + sendto(so, pkt, pos, 0, (struct sockaddr *)&target, sizeof(struct sockaddr)); + } + endsocket(so); + return 0; +} + diff --git a/sdk/net/socket.h b/sdk/net/socket.h new file mode 100644 index 0000000..b9bd190 --- /dev/null +++ b/sdk/net/socket.h @@ -0,0 +1,61 @@ +/* + * Portable include for access of socket services. + * $Id$ + * Copyright (c) 1997 by Tycho Softworks. + * For conditions of distribution and reuse see product license. + */ + +#ifndef __NET_SOCKET_H__ +#define __NET_SOCKET_H__ + +#ifndef __STD_FILES_H__ +#include +#endif + +#ifndef __STD_TYPES_H__ +#include +#endif + +#include +#include +#include +#include + +typedef int SOCKET; +#define INVALID_SOCKET -1 + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __NAMESPACE +#define init_sockets __NAMESPACE(init_sockets) +#define gethost __NAMESPACE(gethost) +#define getservice __NAMESPACE(getservice) +#define peername __NAMESPACE(peername) +#define peeraddr __NAMESPACE(peeraddr) +#define homename __NAMESPACE(homename) +#define homeaddr __NAMESPACE(homeaddr) +#define endsocket __NAMESPACE(endsocket) +#define udpsocket __NAMESPACE(udpsocket) +#define tcpsocket __NAMESPACE(tcpsocket) +#define getsocket __NAMESPACE(getsocket) +#endif + +bool init_sockets(void); +struct hostent *gethost(const char *host); +struct in_addr *getnetaddr(const char *addr); +int getservice(const char *service); +char *peername(SOCKET so); +char *peeraddr(SOCKET so); +char *homename(SOCKET so); +char *homeaddr(SOCKET so); +void endsocket(SOCKET so); +SOCKET udpsocket(char *mask, int port); +SOCKET tcpsocket(char *mask, int port, int backlog); +SOCKET getsocket(const char *host, int port, int socktype); +#ifdef __cplusplus +} +#endif + +#endif diff --git a/sdk/net/sockname.c b/sdk/net/sockname.c new file mode 100644 index 0000000..a8e9aad --- /dev/null +++ b/sdk/net/sockname.c @@ -0,0 +1,62 @@ +/* + * Portable socket and peer name services. + * $Id$ + * Copyright (c) 1997 by Tycho Softworks. + * For conditions of distribution and reuse see product license. + */ + +#include + +char *homename(SOCKET so) +{ + struct hostent *hp; + struct sockaddr_in sin; + int len = sizeof(sin); + + if(getsockname(so, (struct sockaddr *)&sin, &len) < 0) + return NULL; + + hp = gethostbyaddr((char *)&sin.sin_addr, sizeof(struct in_addr), AF_INET); + if(hp) + return (char *)hp->h_name; + else + return inet_ntoa(sin.sin_addr); +} + +char *homeaddr(SOCKET so) +{ + struct sockaddr_in sin; + int len = sizeof(sin); + + if(getsockname(so, (struct sockaddr *)&sin, &len) < 0) + return NULL; + + return inet_ntoa(sin.sin_addr); +} + +char *peername(SOCKET so) +{ + struct hostent *hp; + struct sockaddr_in sin; + int len = sizeof(sin); + + if(getpeername(so, (struct sockaddr *)&sin, &len) < 0) + return NULL; + + hp = gethostbyaddr((char *)&sin.sin_addr, sizeof(struct in_addr), AF_INET); + if(hp) + return (char *)hp->h_name; + else + return inet_ntoa(sin.sin_addr); +} + +char *peeraddr(SOCKET so) +{ + struct sockaddr_in sin; + int len = sizeof(sin); + + if(getpeername(so, (struct sockaddr *)&sin, &len) < 0) + return NULL; + + return inet_ntoa(sin.sin_addr); +} diff --git a/sdk/net/stream.h b/sdk/net/stream.h new file mode 100644 index 0000000..268d881 --- /dev/null +++ b/sdk/net/stream.h @@ -0,0 +1,45 @@ +/* + * Stream oriented TCP session routines. + * $Id$ + * Copyright (c) 1997 by Tycho Softworks. + * For conditions of distribution and reuse see product license. + */ + +#ifndef __NET_STREAM_H__ +#define __NET_STREAM_H__ + +#ifndef __NET_SOCKET_H__ +#include +#endif + +#define tcppeer(fp) peername(fileno(fp)) +#define tcphome(fp) homename(fileno(fp)) + +typedef FILE *STREAM; + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __NAMESPACE +#define opentcp __NAMESPACE(opentcp) +#define accepttcp __NAMESPACE(accepttcp) +#define gettcp __NAMESPACE(gettcp) +#define puttcp __NAMESPACE(puttcp) +#define closetcp __NAMESPACE(closetcp) +#define buftcp __NAMESPACE(buftcp) +#endif + +STREAM opentcp(const char *hostname, int port); +STREAM accepttcp(SOCKET so); +char *gettcp(char *buf, size_t count, STREAM fp); +int puttcp(char *str, STREAM fp); +void closetcp(STREAM fp); +int buftcp(STREAM fp, int size); + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/sdk/net/tcpsocket.c b/sdk/net/tcpsocket.c new file mode 100644 index 0000000..b5e61bf --- /dev/null +++ b/sdk/net/tcpsocket.c @@ -0,0 +1,42 @@ +/* + * Create and bind a tcp socket for a server. + * $Id$ + * Copyright (c) 1997 by Tycho Softworks. + * For conditions of distribution and reuse see product license. + */ + +#include + +SOCKET tcpsocket(char *mask, int port, int backlog) +{ + SOCKET so; + struct sockaddr_in saddr; + struct in_addr *aptr; + + so = socket(AF_INET, SOCK_STREAM, 0); + if(so == INVALID_SOCKET) + return so; + + memset(&saddr, 0, sizeof(saddr)); + saddr.sin_family = AF_INET; + saddr.sin_port = htons(port); + aptr = getnetaddr(mask); + if(!aptr) + { + endsocket(so); + return INVALID_SOCKET; + } + saddr.sin_addr = *aptr; + + if(bind(so, (struct sockaddr *)&saddr, sizeof(saddr))) + { + endsocket(so); + return INVALID_SOCKET; + } + if(listen(so, backlog)) + { + endsocket(so); + return INVALID_SOCKET; + } + return so; +} diff --git a/sdk/net/tcpstream.c b/sdk/net/tcpstream.c new file mode 100644 index 0000000..b39645d --- /dev/null +++ b/sdk/net/tcpstream.c @@ -0,0 +1,88 @@ +/* + * Portable TCP session stream functions. + * $Id$ + * Copyright (c) 1997 by Tycho Softworks. + * For conditions of distribution and reuse see product license. + */ + +#include +#include + +STREAM opentcp(const char *host, int port) +{ + SOCKET so = getsocket(host, port, SOCK_STREAM); + FILE *fp; + + if(so == INVALID_SOCKET) + return NULL; + + fp = fdopen(so, "r+"); + if(!fp) + { + endsocket(so); + return NULL; + } + buftcp(fp, 0); + return fp; +} + +char *gettcp(char *buf, size_t count, STREAM fp) +{ + memset(buf, 0, count); + if(!fgets(buf, count, fp)) + return NULL; + + return buf; +} + +int puttcp(char *buf, STREAM fp) +{ + int err; + err = fputs(buf, fp); + fflush(fp); + return err; +} + +void closetcp(STREAM fp) +{ + SOCKET so = fileno(fp); + + fflush(fp); + shutdown(so, 2); + fclose(fp); +} + +int buftcp(STREAM fp, int size) +{ + fflush(fp); + + if(!size) + return setvbuf(fp, NULL, _IOLBF, 1024); + else + return setvbuf(fp, NULL, _IOFBF, size); +} + +STREAM accepttcp(SOCKET so) +{ + struct sockaddr addr; + int len; + int si; + FILE *fp; + + len = sizeof(addr); + si = accept(so, &addr, &len); + if(si < 0) + return NULL; + + fp = fdopen(si, "r+"); + if(!fp) + { + shutdown(si, 2); + close(si); + return NULL; + } + + buftcp(fp, 0); + return fp; +} + diff --git a/sdk/net/trap.h b/sdk/net/trap.h new file mode 100644 index 0000000..b903d5d --- /dev/null +++ b/sdk/net/trap.h @@ -0,0 +1,30 @@ +/* + * Define SNMP Traps. + * $Id$ + * Copyright (c) 1997 by Tycho Softworks. + * For conditions of distribution and reuse see product license. + */ + +#ifndef __NET_TRAP_H__ + +#ifndef __NET_SOCKET_H__ +#include +#endif + +#define SNMP_TRAP_PORT 162 +#define SNMP_TRAP_COLDSTART 0 +#define SNMP_TRAP_WARMSTART 1 +#define SNMP_TRAP_LINKDOWN 2 +#define SNMP_TRAP_LINKUP 3 +#define SNMP_TRAP_AUTHFAIL 4 +#define SNMP_TRAP_EGPNEIGHBORLOSS 5 +#define SNMP_TRAP_ENTERPRISESPECIFIC 6 + +#ifdef __NAMESPACE +#define snmptrap __NAMESPACE(snmptrap) +#endif + +int snmptrap(char *target, char *host, char *community, int id, char *enterprise, char *describe, long uptime); + + +#endif diff --git a/sdk/net/udpsocket.c b/sdk/net/udpsocket.c new file mode 100644 index 0000000..2127ac3 --- /dev/null +++ b/sdk/net/udpsocket.c @@ -0,0 +1,36 @@ +/* + * Create and bind a udp socket for a server. + * $Id$ + * Copyright (c) 1997 by Tycho Softworks. + * For conditions of distribution and reuse see product license. + */ + +#include + +SOCKET udpsocket(char *mask, int port) +{ + SOCKET so; + struct sockaddr_in saddr; + struct in_addr *aptr; + + so = socket(AF_INET, SOCK_DGRAM, 0); + if(so == INVALID_SOCKET) + return so; + + saddr.sin_family = AF_INET; + saddr.sin_port = htons(port); + aptr = getnetaddr(mask); + if(!aptr) + { + endsocket(so); + return INVALID_SOCKET; + } + saddr.sin_addr = *aptr; + + if(bind(so, (struct sockaddr *)&saddr, sizeof(saddr))) + { + endsocket(so); + return INVALID_SOCKET; + } + return so; +} diff --git a/sdk/other/Makefile.in b/sdk/other/Makefile.in new file mode 100644 index 0000000..17dd18a --- /dev/null +++ b/sdk/other/Makefile.in @@ -0,0 +1,22 @@ +# +# Template to build our "other" object modules(libother.a) +# $Id: Makefile.in 1.2 Wed, 19 Mar 1997 12:44:53 -0500 dyfet $ +# Copyright (c) 1997 by Tycho Softworks. +# + +OBJS = memalloc.o memdup.o memfree.o mempool.o memrelease.o \ + memreq.o config.o confdir.o bcd.o env.o atob.o strint.o \ + expand.o picture.o xval.o hex.o strcopy.o strdiff.o \ + strblank.o strpos.o strreq.o strtrim.o ccount.o filename.o \ + isftype.o getargv.o search.o token.o fatal.o fncat.o + +.c.o: + $(CC) $(CFLAGS) $(OPTIMIZE) -I.. -o $@ -c $< + $(AR) r ../lib/libother.a $@ + +all: $(OBJS) + ranlib ../lib/libother.a + +clean: + rm *.o + diff --git a/sdk/other/atob.c b/sdk/other/atob.c new file mode 100644 index 0000000..1535f7a --- /dev/null +++ b/sdk/other/atob.c @@ -0,0 +1,47 @@ +/* + * Convert ASCII text into binary value. + * $Id: atob.c 1.2 Wed, 19 Mar 1997 12:44:53 -0500 dyfet $ + * Copyright (c) 1997 by Tycho Softworks. + * For conditions of distribution and use, see product license. + * + * Functions: + * atob() - convert null terminated ASCII string to boolean value. + */ + +#include + +/* + * Convert null terminated ASCII string to boolean value. + * + * Abstract: + * The input string can be numeric; such as "0" or "1", or alpha; + * such as "T" for true, "F" for false, or "Y" or "N". Only the + * first character of the string is examined. Upper/lower case is + * ignored. + * + * Parameters: + * str - null terminated ASCII string. + * + * Returns: + * logical value of input string. + * + * Exceptions: + * Any unrecognized string value, or a NULL string, return FALSE. + */ + +bool atob(const char *str) +{ + if(!str) + return FALSE; + + switch(*str) + { + case '0': + case 'f': + case 'F': + case 'n': + case 'N': + return FALSE; + } + return TRUE; +} diff --git a/sdk/other/bcd.c b/sdk/other/bcd.c new file mode 100644 index 0000000..3bd6144 --- /dev/null +++ b/sdk/other/bcd.c @@ -0,0 +1,125 @@ +/* + * Convert ASCII numbers to or from BCD representations. + * $Id: bcd.c 1.2 Wed, 19 Mar 1997 12:44:53 -0500 dyfet $ + * Copyright (c) 1997 by Tycho Softworks. + * For condititions of distribution and use, see product license. + * + * Abstract: + * BCD is a format for storing packed decimal data within a nibble. + * We assume "big endian" BCD, in that the high nibble contains the + * first digit within a byte. Any unused digits are filled with the + * nibble value of $F. This module provides the services needed to + * convert BCD data to and from ASCII strings. + * + * Functions: + * str2bcd() - convert ASCII string to packed bcd. + * bcd2str() - convert packed bcd to ASCII string. + */ + +#include + +/* + * Convert null terminated ASCII string to packed bcd data. + * + * Abstract: + * An ASCII input string is converted to binary packed decimal + * data. Any unused digits are filled with $f. The size specified + * for digits is filled, either with available digits from the input + * string, or with $f nibbles once no more digits are available. + * + * Paramaters: + * bcd - pointer to start of bcd data to store. + * str - null terminated input string. + * max - maximum number of digits in bcd data. + * + * Returns: + * pointer to first non-BCD digit in input string. + * + * Exceptions: + * If NULL input string, returns NULL. If more digits exist in + * the input string than are available in bcd storage (data + * overflow), the remaining digits are ignored. + */ + +char *str2bcd(uchar *bcd, char *str, int max) +{ + uchar packed = 0xff; + bool low = FALSE; + + if(!str) + return NULL; + + while(isdigit(*str)) + { + packed = packed / 16; + packed |= ((*(str++) - '0') * 16); + if(low) + { + *(bcd++) = packed; + packed = 0xff; + if(!--max) + return str; + + low = FALSE; + } + else + low = TRUE; + } + if(low) + { + *(bcd++) = packed; + --max; + } + while(max--) + *(bcd++) = 0xff; + + return str; +} + +/* + * Convert binary coded data to ASCII text. + * + * Abstract: + * A block of bcd data of up to a specified length is read, each + * digit being converted to an ASCII character code. If a $f is + * found before 'len' digits are examined, then the program + * completes with a shorter number. + * + * Paramaters: + * str - start of output string to receive converted data. + * bcd - bcd data input. + * len - maximum number of bcd digits. + * + * Return: + * pointer to next available bcd number in memory (or past end of + * bcd data block). The output string (str) is also given a null + * terminating byte. + * + * Exceptions: + * A NULL bcd pointer returns a NULL string. + */ + +uchar *bcd2str(char *str, uchar *bcd, int len) +{ + uchar nib1, nib2; + if(!bcd) + return NULL; + + while(len--) + { + nib1 = *bcd / 16; + nib2 = *bcd % 16; + if(nib1 < 16) + *(str++) = nib1 + '0'; + else + break; + if(nib2 < 16) + *(str++) = nib2 + '0'; + else + break; + ++bcd; + } + *str = 0; + return bcd; +} + diff --git a/sdk/other/bind.conf b/sdk/other/bind.conf new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/sdk/other/bind.conf @@ -0,0 +1 @@ + diff --git a/sdk/other/ccount.c b/sdk/other/ccount.c new file mode 100644 index 0000000..ec53a98 --- /dev/null +++ b/sdk/other/ccount.c @@ -0,0 +1,45 @@ +/* + * Count character occurances in string. + * $Id: ccount.c 1.2 Wed, 19 Mar 1997 12:44:53 -0500 dyfet $ + * Copyright (c) 1997 by Tycho Softworks. + * For conditions of distribution and use see product license. + * + * Functions: + * ccount() - count characters in string. + */ + +#include + +/* + * Count character occurances in ASCII string. + * + * Abstract: + * A list of possible characters to look for is passed to ccount, + * along with the null terminated ASCII string to look for those + * characters within. + * + * Parameters: + * str - string to examine and count occurances in. + * list - list (null terminated) of characters to search for. + * + * Exceptions: + * Either a NULL list or string is considered to hold no found + * characters (returns 0). + */ + +int ccount(const char *str, const char *list) +{ + int count = 0; + + if(!str || !list) + return 0; + + while(NULL != (str = strpbrk(str, list))) + { + ++count; + ++str; + } + return count; +} + + diff --git a/sdk/other/confdir.c b/sdk/other/confdir.c new file mode 100644 index 0000000..cabc475 --- /dev/null +++ b/sdk/other/confdir.c @@ -0,0 +1,105 @@ +/* + * Routines to access directory of section names in a config file. + * $Id$ + * Copyright (c) 1997 by Tycho Softworks. + * For conditions of distribution and use see product license. + * + * Abstract: + * These routines may be used to scan the 'directory' of [] section + * names within a config file, much like the MS-DOS find_first() and + * find_next() directory routines. + * + * Functions: + * this_config() - internal routine to return section name. + * first_config() - goto first named [] section within the config file. + * next_config() - skip to the next named [] section. + */ + +#include +#include +#include + +#ifndef LBUF +#define LBUF 1024 +#endif + +/* + * Internal program to support parsing of found section name. + */ + +static char *this_config(CONFIG *cfg) +{ + char *p; + + if(feof(cfg->cfg_fp)) + return NULL; + + if(cfg->cfg_lbuf[0] != '[') + return NULL; + + cfg->cfg_flag = TRUE; + p = strtok(cfg->cfg_lbuf, "[]\n\r"); + return p; +} + +/* + * Automatically seek the very first [] section within a config file. + * + * Paramaters: + * cfg - config object pointer. + * + * Returns: + * Name string of first [] name in config file. + * + * Exceptions: + * If no [] section in config file, NULL cfg pointer, or file + * error, returns NULL. + */ + +char *first_config(CONFIG *cfg) +{ + if(!cfg) + return NULL; + + fseek(cfg->cfg_fp, 0l, SEEK_SET); + return next_config(cfg); +} + +/* + * Skip to the next named [] section within a config file. + * + * Paramaters: + * cfg - config object pointer. + * + * Returns: + * Name string of next named [] section in config file. + * + * Exceptions: + * Returns NULL if cfg invalid or end of file reached. + * + */ + +char *next_config(CONFIG *cfg) +{ + if(!cfg) + return NULL; + + if(feof(cfg->cfg_fp)) + return NULL; + + for(;;) + { + fgets(cfg->cfg_lbuf, LBUF - 1, cfg->cfg_fp); + if(feof(cfg->cfg_fp)) + return NULL; + + if(cfg->cfg_lbuf[0] == '[') + return this_config(cfg); + } +} + + + + + + diff --git a/sdk/other/config.c b/sdk/other/config.c new file mode 100644 index 0000000..e274b85 --- /dev/null +++ b/sdk/other/config.c @@ -0,0 +1,437 @@ +/* + * Routines to access and parse standard text config files. + * $Id: config.c 1.2 Wed, 19 Mar 1997 12:44:53 -0500 dyfet $ + * Copyright (c) 1997 by Tycho Softworks. + * For conditions of distribution and use see product license. + * + * Abstract: + * These routines are used to open and parse human readable '.conf' + * files, such as those which may be stored in the /etc directory. + * The .conf file is parsed as a sectioned text file, with the name + * for each logical section appearing in []'s. Entries within each + * section are typically in the format 'keyword = value', though + * there are exceptions for multi-line fixed size lists, in + * the form 'keyword = { list }', and repeated lines. Comments may + * also appear within .conf files. + * + * Functions: + * sys_config() - find and open a /etc or /etc/prior .conf file. + * open_config() - open any text file as a config file. + * read_config() - read a keyword = value pair from current section. + * seek_config() - seek a named [] section within the config file. + * get_config() - tests current input for a specified keyword. + * usr_config() - user specific resource config file. + */ + +#include +#include +#include +#include +#include + +/* + * When searching for 'system' .conf files, which are normally held in + * /etc, also search in /etc/prior. This is used so that a human + * readable .conf file can momentarily be moved into '/etc/prior' and + * still be usable while a GUI system management program is in the middle + * building a new .conf file. + */ + +#ifndef CFGPATH +#define CFGPATH "/etc:/etc/prior" +#endif + +/* + * Maximum working space for single or multi-line input records being + * parsed. + */ + +#ifndef LBUF +#define LBUF 1024 +#endif + +#ifndef SUFFIX +#define SUFFIX ".conf" +#endif + +/* + * Open a system .conf file, as found in the system config directories. + * + * Abstract: + * This function finds a .conf file in either the /etc or /etc/prior + * directory. /etc/prior is searched if the current .conf file is + * not found (in /etc), as may happen if it is in the middle of + * being re-built by a management application. This provides an + * initial function which may be used to open most .conf files. + * + * Paramaters: + * cfg_name - 'base' filename of system .conf file to open. + * + * Returns: + * pointer to active CONFIG object for specified filename. + * + * Exceptions: + * If the file is not found, a NULL pointer is returned. + */ + +CONFIG *sys_config(const char *cfg_name) +{ + char cfgname[PATH_MAX + 1]; + + strcpy(cfgname, cfg_name); + strcat(cfgname, SUFFIX); + return open_config(search(CFGPATH, cfgname)); +} + +/* + * Open any specified filename as a .conf file. + * + * Abstract: + * This function opens the specified file as a 'config' file for use + * in config file parsing routines. Any filename may be specified + * and opened as a config file with this routine. + * + * Paramaters: + * config_name - full pathname of a .conf file to open. + * + * Returns: + * pointer to a newly allocated CONFIG parsing object for the + * specified filename. + * + * Exceptions: + * If the file is not found, a NULL pointer is returned. + */ + + +CONFIG *open_config(const char *config_name) +{ + CONFIG *new; + char *env; + + if(NULL == (new = (CONFIG *)malloc(sizeof(CONFIG) + LBUF))) + return NULL; + + if(NULL == (new->cfg_fp = fopen(config_name, "r"))) + { + free(new); + return NULL; + } + new->cfg_flag = FALSE; + return new; +} + +/* + * Close an open config file and destroy the CONFIG parser object. + */ + +void close_config(CONFIG *cfg) +{ + if(!cfg) + return; + + fclose(cfg->cfg_fp); + free(cfg); +} + +/* Read a line of ASCII text input from an open config file. + * + * Abstract: + * This routine extracts a line of input from an open config file. + * The input line extracted and returned is a "keyword = value" line + * found within the current [] section. If the end of the current + * [] section has been reached, then no further input is returned. + * + * Lines which contain comments are automatically skipped. Comments + * include those lines which begin with a '#' or ';' character. + * Empty lines are also automatically skipped. + * + * Special {} subsections may also be used to specify language + * variant .conf values. When these subsection identifiers are found + * and the current language found in the ENV (LANG=) does not match + * the language for the specified {} section, the entire {} section + * is skipped. + * + * The input line retreived automatically has lead and trailing + * whitespaces removed. + * + * Paramaters: + * cfg - a 'config' parser object. + * + * Returns: + * ASCII text for 'keyword = value' item from config file. + * + * Exceptions: + * A NULL is returned when the current [] section has been completed, + * when at the end of the file, or if any error occurs while reading. + */ + +char *read_config(CONFIG *cfg) +{ + char *p, *q; + int skip = 0; + + if(!cfg) + return NULL; + + if(!cfg->cfg_flag) + return NULL; + + for(;;) + { + fgets(cfg->cfg_lbuf, LBUF - 1, cfg->cfg_fp); + if(feof(cfg->cfg_fp) || cfg->cfg_lbuf[0] == '[' || ferror(cfg->cfg_fp)) + { + cfg->cfg_flag = FALSE; + return NULL; + } + p = strtrim(cfg->cfg_lbuf, __SPACES); + + if(*p == '{') + { + skip = 1; + p = strtok(p, "{}| \t"); + while(p) + { + if(!stricmp(p, "all")) + skip = 0; + if(!stricmp(p, language())) + skip = 0; + p = strtok(NULL, "{}| \t"); + } + continue; + } + + if(!*p || *p == '!' || *p == '#' || *p == ';' || skip) + continue; + + return p; + } +} + +/* + * Seek a named [] section within the .conf file to begin input. + * + * Abstract: + * The named section is found within the .conf file. Once + * found, all read_config() input will be returned from the + * specified [] section. Section names are case insensitive. + * + * Paramaters: + * cfg - config object pointer. + * seek_name - name of config [] section to find. + * + * Returns: + * TRUE if the section name is found in the .conf file , FALSE if + * not. + * + * Exceptions: + * If a NULL cfg or seek_name is passed, the search always fails. + * If a file error is found, the search always fails. The maximum + * size of a [] section name that is tested is 22 characters. + */ + +bool seek_config(CONFIG *cfg, const char *seek_name) +{ + char group[25]; + int len; + + if(!cfg || !seek_name) + return FALSE; + + cfg->cfg_flag = FALSE; /* mark as outside old [] section */ + + len = strlen(seek_name); + if (len > 22) + len = 22; + + memset(group, 0, sizeof(group)); + + if(*seek_name != '[') + strcpy(group, "["); + + strncat(group, seek_name, len); + + if(*seek_name != '[' && strlen(seek_name) < 23) + strcat(group, "]"); + + fseek(cfg->cfg_fp, 0l, SEEK_SET); + len = strlen(group); + for(;;) + { + fgets(cfg->cfg_lbuf, LBUF - 1, cfg->cfg_fp); + if(feof(cfg->cfg_fp) || ferror(cfg->cfg_fp)) + return FALSE; + + if(!strnicmp(group, cfg->cfg_lbuf, len)) + { + cfg->cfg_flag = TRUE; + return TRUE; + } + } +} + +/* + * Parse and test a keyword value pair from current config input. + * + * Abstract: + * This routine is commonly used to search the current input line + * that is returned by read_config() for a specified keyword. The + * current input line is assumed to be in the form 'keyword = value'. + * lead and trailing spaces around the '=' are ignored, as is keyword + * case. White spaces within a keyword are also ignored. + * + * Assuming the keyword requested is found in the current input line, + * the 'value' string is returned. If the keyword being tested is + * a multi-line keyword = { list }, then all lines for the value are + * scanned and loaded into the config line buffer. If the special + * '+' entry is found in the config file, then the keyword is assumed + * to be a continuation of the last one found. + * + * A value is normally stripped of all lead and trailing spaces. If + * these need to be preserved, then the value may be put in single + * or double quotes. + * + * Since get_config() only looks at the current input line buffered + * by read_config(), a test for every possible keyword the application + * may need should be performed after each successful read_config() + * for a given [] section. + * + * Paramaters: + * cfg - config object pointer. + * keyword - keyword to test for. + * + * Returns: + * Value string if keyword is found in current input line, else NULL. + * + * Exceptions: + * If a NULL pointer or keyword is used, a NULL value is returned. + */ + +char *get_config(CONFIG *cfg, const char *keyword) +{ + char *cbuf; + char *out, *p; + int pos = 0; + bool found = FALSE; + + if(!cfg || !keyword) + return NULL; + + cbuf = cfg->cfg_lbuf; + + if(*cbuf == '+') /* alternate multi-line syntax */ + { + if(!stricmp(cfg->cfg_test, keyword)) + return strltrim(++cbuf, __SPACES); + else + return NULL; + } + + while((pos < 33) && *cbuf && (*cbuf != '=')) + { + if((*cbuf != ' ') && (*cbuf != '_') && (*cbuf != '\t')) + cfg->cfg_test[pos++] = *(cbuf++); + else + ++cbuf; + } + cfg->cfg_test[pos] = 0; + out = p = strltrim(++cbuf, __SPACES); + switch(*p) + { + case '{': + cbuf = p; + while(!found) + { + while(*(++p)) + { + if(*p == '}') + { + found = TRUE; + *p = 0; + } + else + *(cbuf++) = *p; + } + + if(!found) + { + p = cbuf; + fgets(p, LBUF - 1 + (int)(cfg->cfg_lbuf - p), cfg->cfg_fp); + if(feof(cfg->cfg_fp) || *p == '[') + { + cfg->cfg_flag = FALSE; + *p = 0; + break; + } + *(cbuf++) = '\n'; + p = strtrim(p, __SPACES); + } + } + *cbuf = 0; + out = strltrim(++out, __SPACES); + break; + case '\'': + case '\"': + while(*(++p)) + { + if(*p == *out) + { + *p = 0; + break; + } + } + out = strltrim(++out, __SPACES); + break; + } + if(!stricmp(cfg->cfg_test, keyword)) + return out; + else + return NULL; +} + +/* + * Find config file in user's home directory. + * + * Abstract: + * In addition to searching for a master config file in /etc, many + * applications may support an optional user specific 'rc' or config + * file in the user's own home directory, which, if found, may + * override global defaults. This ability is easily supported with + * the usr_config() service, which looks for a named .config file + * in the user's home. + * + * Paramaters: + * Filename of '.config' file to look for in a user's home directory, + * without the leading '.'. + * + * Returns: + * Config object pointer if file is found in user's home, otherwise + * a NULL pointer. + * + * Exceptions: + * A NULL filename will result in a NULL object being returned. + */ + +CONFIG *usr_config(const char *name) +{ + char path[NAME_MAX + 1]; + + if(!name) + return NULL; + + strcpy(path, homedir()); + fncat(path, "."); + strcat(path, name); + return open_config(path); +} + + + + + + + + + + + diff --git a/sdk/other/config.h b/sdk/other/config.h new file mode 100644 index 0000000..4d76d1a --- /dev/null +++ b/sdk/other/config.h @@ -0,0 +1,67 @@ +/* + * Portable human readable config text file parsing routines. + * $Id: config.h 1.2 Wed, 19 Mar 1997 12:44:53 -0500 dyfet $ + * Copyright (c) 1997 by Tycho Softworks. + * For conditions of distribution and use see product license. + * + * Abstract: + * The config routines allow locating, opening, and parsing of + * human readable .conf files. These .conf files are broken into + * seperate named [] sections, each of which may be individually + * located and examined, and config data. Config data is usually + * in the form of a 'keyword = value' statement. + * + * Data types: + * CONFIG - object line parse buffer for an open config file. + */ + +#ifndef __OTHER_CONFIG_H__ +#define __OTHER_CONFIG_H__ + +#ifndef __OTHER_STRING_H__ +#include +#endif + +#ifndef __OTHER_FILES_H__ +#include +#endif + +typedef struct +{ + bool cfg_flag; + FILE *cfg_fp; + char cfg_test[33]; + char cfg_lbuf[ EMPTY ]; +} CONFIG; + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __NAMESPACE +#define open_config __NAMESPACE(open_config) +#define sys_config __NAMESPACE(sys_config) +#define usr_config __NAMESPACE(usr_config) +#define first_config __NAMESPACE(first_config) +#define next_config __NAMESPACE(next_config) +#define seek_config __NAMESPACE(seek_config) +#define read_config __NAMESPACE(read_config) +#define close_config __NAMESPACE(close_config) +#define get_config __NAMESPACE(get_config) +#endif + +CONFIG *open_config(const char *name); +CONFIG *sys_config(const char *name); +CONFIG *usr_config(const char *name); +char *first_config(CONFIG *cfg); +char *next_config(CONFIG *cfg); +bool seek_config(CONFIG *cfg, const char *name); +char *read_config(CONFIG *cfg); +void close_config(CONFIG *cfg); +char *get_config(CONFIG *cfg, const char *option); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/sdk/other/env.c b/sdk/other/env.c new file mode 100644 index 0000000..cf3dfb0 --- /dev/null +++ b/sdk/other/env.c @@ -0,0 +1,36 @@ +/* + * Common values found in process environment space. + * $Id$ + * Copyright (c) 1997 by Tycho Softworks. + * See conditions of distribution and reuse see product license. + */ + +#include +#include + +char *homedir(void) +{ + char *env = getenv("HOME"); + + if(!env) + env = "/"; + + return env; +} + +char *language(void) +{ + static char lbuf[32] = "default"; + + char *env = getenv("LANG"); + + if(env) + { + strncpy(lbuf, env, 31); + lbuf[31] = 0; + strtok(lbuf, "._"); + } + return lbuf; +} + + diff --git a/sdk/other/env.h b/sdk/other/env.h new file mode 100644 index 0000000..96b70e3 --- /dev/null +++ b/sdk/other/env.h @@ -0,0 +1,31 @@ +/* + * Portable process environment routines. + * $Id$ + * Copyright (c) 1997 by Tycho Softworks. + * For conditions of distribution and reuse see product license. + */ + +#ifndef __OTHER_ENV_H__ +#define __OTHER_ENV_H__ + +#ifndef __STD_PROCESS_H__ +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __NAMESPACE +#define homedir __NAMESPACE(homedir) +#define language __NAMESPACE(language) +#endif + +char *homedir(void); +char *language(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/sdk/other/expand.c b/sdk/other/expand.c new file mode 100644 index 0000000..8005957 --- /dev/null +++ b/sdk/other/expand.c @@ -0,0 +1,36 @@ +/* + * String expansion and normalization of 'plain text' line data. + * $Id$ + * Copyright (c) 1997 by Tycho Softworks. + * For conditions of distribution and reuse see product license. + */ + +#include + +char *expand(const char *s) +{ + static char buf[320]; + + int pos = 0; + + while(*s) + { + if(*s == '\t') + { + buf[pos++] = ' '; + while(pos % 8) + buf[pos++] = ' '; + } + else if (*s > 31) + buf[pos++] = *s; + else + { + buf[pos++] = '^'; + buf[pos++] = *s + '@'; + } + ++s; + } + buf[pos] = 0; + return buf; +} + diff --git a/sdk/other/fatal.c b/sdk/other/fatal.c new file mode 100644 index 0000000..fd3ef54 --- /dev/null +++ b/sdk/other/fatal.c @@ -0,0 +1,23 @@ +/* + * Print error message to stderr and exit with status code. + * $Id$ + * Copyright (c) 1997 by Tycho Softworks. + * For conditions of distribution and reuse see product license. + */ + +#include +#include +#include +#include + +void fatal(int excode, const char *format, ...) +{ + va_list args; + + va_start(args, format); + vfprintf(stderr, format, args); + va_end(args); + exit(excode); +} + + diff --git a/sdk/other/filename.c b/sdk/other/filename.c new file mode 100644 index 0000000..2a7275e --- /dev/null +++ b/sdk/other/filename.c @@ -0,0 +1,74 @@ +/* + * Portable file and directory name functions. + * $Id$ + * Copyright (c) 1997 by Tycho Softworks. + * For conditions of distribution and reuse see product license. + */ + +#include +#include +#include + +char *dirname(char *path) +{ + char *p = basename(path); + if(p == path) + return "."; + + *(--p) = 0; + return path; +} + +char *basename(const char *path) +{ + char *p = strrchr(path, '/'); +#if defined(_MSDOS) || defined(_OS2) || defined(_WIN32) + char *p1 = strrchr(path, '\\'); + p = max(p, p1); +#endif + + if(p) + return ++p; + else + return (char *)path; +} + +char *extfname(const char *path) +{ + char *e = strrchr(pathfname(path), '.'); + + if(e) + return e; + else + return ""; +} + +bool ispath(const char *p) +{ + if(strchr(p, '/')) + return TRUE; +#if defined(_MSDOS) || defined(_OS2) || defined(_WIN32) + if(strchr(p, '\\')) + return TRUE; +#endif + return FALSE; +} + +bool isroot(const char *p) +{ +#if defined(_MSDOS) || defined(_OS2) || defined(_WIN32) + if(!strncmp(p, "\\\\", 2)) + return TRUE; + + if(p[1] == ':') + return TRUE; +#else + if(*p == '/') + return TRUE; +#endif + return FALSE; +} + + + + diff --git a/sdk/other/files.h b/sdk/other/files.h new file mode 100644 index 0000000..7e9f421 --- /dev/null +++ b/sdk/other/files.h @@ -0,0 +1,52 @@ +/* + * Portable support for file manipulation and access related functions. + * $Id$ + * Copyright (c) 1997 by Tycho Softworks. + * For conditions of distribution and reuse see product license. + */ + +#ifndef __OTHER_FILES_H__ +#define __OTHER_FILES_H__ + +#ifndef __STD_FILES_H__ +#include +#endif + +#define isdir(fpath) isftype(fpath, S_IFDIR) +#define isfile(fpath) isftype(fpath, S_IFREG) +#define islink(fpath) isftype(fpath, S_IFLNK) +#define isfifo(fpath) isftype(fpath, S_IFIFO) +#define pathfname(fn) basename(fn) +#define rewind(fd) lseek(fd, (off_t)0, SEEK_SET) + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __NAMESPACE +#define isnewfile __NAMESPACE(isnewfile) +#define isftype __NAMESPACE(isftype) +#define ispath __NAMESPACE(ispath) +#define isroot __NAMESPACE(isroot) +#define fncat __NAMESPACE(fncat) +#define search __NAMESPACE(search) +#define basename __NAMESPACE(basename) +#define dirname __NAMESPACE(dirname) +#define extfname __NAMESPACE(extfname) +#endif + +bool isnewfile(const char *from, const char *to); +bool isftype(const char *fpath, int ftype); +bool ispath(const char *fpath); +bool isroot(const char *fpath); +char *fncat(char *prefix, const char *suffix); +char *search(const char *path, const char *fname); +char *basename(const char *path); +char *dirname(char *path); +char *extfname(const char *path); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/sdk/other/fncat.c b/sdk/other/fncat.c new file mode 100644 index 0000000..1d8e3e7 --- /dev/null +++ b/sdk/other/fncat.c @@ -0,0 +1,30 @@ +/* + * Concatenate filenames. + * $Id$ + * Copyright (c) 1997 by Tycho Softworks. + * For conditions of distribution and reuse review product license. + */ + +#include +#include + +char *fncat(char *prefix, const char *suffix) +{ + char *t = tail(prefix); + + if(!*prefix) + { + strcpy(prefix, suffix); + return prefix; + }; + + if(*(--t) != '/') + { + *(++t) = '/'; + *(++t) = 0; + } + + strcat(prefix, suffix); + return prefix; +} + diff --git a/sdk/other/getargv.c b/sdk/other/getargv.c new file mode 100644 index 0000000..bae4d4f --- /dev/null +++ b/sdk/other/getargv.c @@ -0,0 +1,57 @@ +/* + * Portable routines to create argv[] argument lists for exec and spawn. + * $Id$ + * Copyright (c) 1997 by Tycho Softworks. + * For conditions of distribution and reuse see product license. + */ + +#include + +int getargv(char *base[], char *cbuf) +{ + int arg = 0; + int qflag = 0; + int sflag = 1; + + while(*cbuf) + { + switch(*cbuf) + { + case ' ': + case '\t': + if(qflag) + break; + if(!sflag) + { + *cbuf = 0; + sflag = 1; + } + break; + case '\"': + if(!qflag) + { + *cbuf = 0; + base[arg++] = cbuf + 1; + sflag = 0; + qflag = 1; + } + else + { + *cbuf = 0; + sflag = 1; + qflag = 0; + } + break; + default: + if(sflag) + { + base[arg++] = cbuf; + sflag = 0; + } + } + ++cbuf; + } + base[arg] = NULL; + return arg; +} + diff --git a/sdk/other/hex.c b/sdk/other/hex.c new file mode 100644 index 0000000..ae5ccec --- /dev/null +++ b/sdk/other/hex.c @@ -0,0 +1,44 @@ +/* + * Hex digit conversion functions. + * $Id$ + * Copyright (c) 1997 by Tycho Softworks. + * For conditions of distribution and reuse see product license. + */ + +#include + +char hex(int digit) +{ + if(digit < 10) + return '0' + digit; + else + return '7' + digit; +}; + +char *hexbyte(uchar v) +{ + static char h[3]; + + h[0] = hex(v / 16); + h[1] = hex(v % 16); + h[2] = 0; + return h; +}; + +char *hexshort(ushort v) +{ + static char h[5]; + + strcpy(h, hexbyte((uchar)(v / 256))); + strcpy(h + 2, hexbyte((uchar)(v % 256))); + return h; +}; + +char *hexlong(ulong v) +{ + static char h[9]; + + strcpy(h, hexshort((ushort)(v / 65536))); + strcpy(h + 4, hexshort((ushort)(v % 65536))); + return h; +}; diff --git a/sdk/other/isftype.c b/sdk/other/isftype.c new file mode 100644 index 0000000..bee42ca --- /dev/null +++ b/sdk/other/isftype.c @@ -0,0 +1,22 @@ +/* + * File type testing routine. + * $Id$ + * Copyright (c) 1997 by Tycho Softworks. + * For conditions of distribution and reuse see product license. + */ + +#include + +bool isftype(const char *path, int ftype) +{ + struct stat ino; + + if(stat(path, &ino)) + return FALSE; + + if((ino.st_mode & S_IFMT) == ftype) + return TRUE; + + return FALSE; +} + diff --git a/sdk/other/make.conf b/sdk/other/make.conf new file mode 100644 index 0000000..e8b05bd --- /dev/null +++ b/sdk/other/make.conf @@ -0,0 +1,2 @@ +fn_find_file MEMORY_H_MISSING $inc/memory.h + diff --git a/sdk/other/memalloc.c b/sdk/other/memalloc.c new file mode 100644 index 0000000..6d31108 --- /dev/null +++ b/sdk/other/memalloc.c @@ -0,0 +1,35 @@ +/* + * Advanced memory pool allocation scheme. + * $Id$ + * Copyright (c) 1997 by Tycho Softworks. + * For conditions of distribution and reuse consult product license. + */ + +#include +#include + +void *memalloc(MEMPOOL *mem, int len) +{ + _MEMFREE *free = mem->mem_free; + _MEMCELL *cell = NULL; + + len = align(len, __OBJALIGN); + + while(free) + { + if(free->size == len) + { + cell = free->list; + break; + } + free = free->next; + } + + if(cell) + { + free->list = cell->next; + return cell; + } + + return memreq(mem, len); +} diff --git a/sdk/other/memdup.c b/sdk/other/memdup.c new file mode 100644 index 0000000..af1f3cf --- /dev/null +++ b/sdk/other/memdup.c @@ -0,0 +1,22 @@ +/* + * Duplicate object into a memory pool. + * $Id$ + * Copyright (c) 1997 by Tycho Softworks. + * For conditions of distribution and reuse see product license. + */ + +#include +#include + +void *memdup(void *obj, size_t size) +{ + void *new = (void *)malloc(size); + + if(!new) + return NULL; + + memcpy(new, obj, size); + return new; +} + + diff --git a/sdk/other/memfree.c b/sdk/other/memfree.c new file mode 100644 index 0000000..1939f14 --- /dev/null +++ b/sdk/other/memfree.c @@ -0,0 +1,38 @@ +/* + * Advanced free space deallocation for memory pools. + * $Id$ + * Copyright (c) 1997 by Tycho Softworks. + * For conditions of distribution and reuse see product license. + */ + +#include +#include + +void memfree(MEMPOOL *mem, void *obj, int len) +{ + _MEMFREE *free = mem->mem_free; + _MEMCELL *cell = (_MEMCELL *)obj; + len = align(len, __OBJALIGN); + + while(free) + { + if(free->size == len) + break; + + free = free->next; + } + + if(!free) + { + free = memreq(mem, sizeof(_MEMFREE)); + free->list = NULL; + free->next = mem->mem_free; + mem->mem_free = free; + } + + if(free) + { + cell->next = free->list; + free->list = cell; + } +} diff --git a/sdk/other/memory.h b/sdk/other/memory.h new file mode 100644 index 0000000..902edd2 --- /dev/null +++ b/sdk/other/memory.h @@ -0,0 +1,103 @@ +/* + * Portable memory manipulation and management routines. + * $Id$ + * Copyright (c) 1997 by Tycho Softworks. + * For conditions of distribution and reuse see product license. + */ + +#ifndef __OTHER_MEMORY_H__ +#define __OTHER_MEMORY_H__ + +#ifndef __STD_TYPES_H__ +#include +#endif + +#ifndef MEMORY_H_MISSING +#include +#endif + +#ifndef __MEMALIGN +#define __MEMALIGN sizeof(ptr_t) +#endif + +#ifndef __OBJALIGN +#define __OBJALIGN __MEMALIGN +#endif + +struct _mempool; +struct _mempage; +struct _memfree; +struct _memcell; + +typedef struct _mempool +{ + int mem_psize; + int mem_pcount; + int mem_pused; + void *(*mem_pfault)(struct _mempool *mem, int reqsize); + struct _memfree *mem_free; + struct _mempage *mem_reuse; + struct _mempage *mem_last; +} MEMPOOL; + +typedef struct _mempage +{ + struct _mempage *page_next; + int page_used; + uchar page[ EMPTY ]; +} MEMPAGE; + +typedef struct _memfree +{ + struct _memfree *next; + struct _memcell *list; + int size; +} _MEMFREE; + +typedef struct _memcell +{ + void *next; +} _MEMCELL; + +#define memfault(mem, fault) mem->mem_pfault = fault; +#define memfirst(mem) ((MEMPAGE *)((char *)(mem) - sizeof(MEMPAGE))) + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __NAMESPACE +#define mempool __NAMESPACE(mempool) +#define memreuse __NAMESPACE(memreuse) +#define memrelease __NAMESPACE(memrelease) +#define memreq __NAMESPACE(memreq) +#define memlreq __NAMESPACE(memlreq) +#define strreq __NAMESPACE(strreq) +#define strlreq __NAMESPACE(strlreq) +#define memdup __NAMESPACE(memdup) +#define memalloc __NAMESPACE(memalloc) +#define memfree __NAMESPACE(memfree) +#endif + +MEMPOOL *mempool(int psize, int pcount); +void memreuse(MEMPOOL *mem); +void memrelease(MEMPOOL *mem); +void *memreq(MEMPOOL *mem, size_t memsize); +void *memlreq(MEMPOOL *mem, size_t memsize); +char *strreq(MEMPOOL *mem, const char *str); +char *strlreq(MEMPOOL *mem, const char *str); +void *memdup(void *, size_t); + +/* more advanced allocation schemes */ + +void *memalloc(MEMPOOL *mem, int memsize); +void memfree(MEMPOOL *mem, void *obj, int memsize); + +#ifdef __cplusplus +} +#endif + +#endif + + + diff --git a/sdk/other/mempool.c b/sdk/other/mempool.c new file mode 100644 index 0000000..ef27638 --- /dev/null +++ b/sdk/other/mempool.c @@ -0,0 +1,49 @@ +/* + * Memory pool creation. + * $Id$ + * Copyright (c) 1997 by Tycho Softworks. + * For conditions of distribution and reuse see product license. + */ + +#include +#include +#include +#include + +static void *fault(MEMPOOL *mem, int request) +{ + fputs("* mempool: memory pool exhausted\n", stderr); + exit(EX_SOFTWARE); +} + +MEMPOOL *mempool(int psize, int pcount) +{ + char *page; + MEMPAGE *first; + MEMPOOL *pool; + + psize = align(psize, __MEMALIGN); + if(NULL == (page = (char *)malloc(psize))) + return NULL; + + first = (MEMPAGE *)page; + pool = (MEMPOOL *)(page + sizeof(MEMPAGE)); + + first->page_next = NULL; + first->page_used = sizeof(MEMPOOL); + + pool->mem_psize = psize - sizeof(MEMPAGE); + pool->mem_pcount = pcount; + pool->mem_pused = 1; + pool->mem_pfault = fault; + pool->mem_reuse = NULL; + pool->mem_last = first; + pool->mem_free = NULL; + return pool; +} + + + + + + diff --git a/sdk/other/memrelease.c b/sdk/other/memrelease.c new file mode 100644 index 0000000..144bff6 --- /dev/null +++ b/sdk/other/memrelease.c @@ -0,0 +1,43 @@ +/* + * Relallocate and release memory pools. + * $Id$ + * Copyright (c) 1997 by Tycho Softworks. + * For conditions of distribution and reuse see product license. + */ + +#include + +void memrelease(MEMPOOL *mem) +{ + MEMPAGE *page = memfirst(mem); + MEMPAGE *next; + + while(page) + { + next = page->page_next; + free(page); + page = next; + } +} + +void memreuse(MEMPOOL *mem) +{ + MEMPAGE *page = memfirst(mem); + MEMPAGE *next; + + page = page->page_next; + while(page) + { + next = page->page_next; + free(page); + page = next; + } + mem->mem_pused = 1; + mem->mem_free = NULL; + page = mem->mem_last = memfirst(mem); + page->page_used = 0; + page->page_next = NULL; +} + + + diff --git a/sdk/other/memreq.c b/sdk/other/memreq.c new file mode 100644 index 0000000..16f8433 --- /dev/null +++ b/sdk/other/memreq.c @@ -0,0 +1,59 @@ +/* + * Copy strings and objects into a memory pool. + * $Id$ + * Copyright (c) 1997 by Tycho Softworks. + * For conditions of distribution and reuse see product license. + */ + +#include +#include + +static void *memrequest(MEMPOOL *mem, MEMPAGE *page, size_t len) +{ + int psize = mem->mem_psize; + void *obj; + + /* align objects to ptr field size */ + + len = align(len, __OBJALIGN); + + if(len > mem->mem_psize) + return (*mem->mem_pfault)(mem, len); + + while(page) + { + if(page->page_used + len <= psize) + { + obj = &page->page[page->page_used]; + page->page_used += len; + return obj; + } + page = page->page_next; + } + + if(mem->mem_pused >= mem->mem_pcount) + return (*mem->mem_pfault)(mem, len); + + ++mem->mem_pused; + page = (MEMPAGE *)malloc(psize + sizeof(MEMPAGE)); + if(!page) + return (*mem->mem_pfault)(mem, len); + + mem->mem_last->page_next = page; + mem->mem_last = page; + page->page_used = len; + page->page_next = NULL; + return page->page; +} + +void *memlreq(MEMPOOL *mem, size_t len) +{ + return memrequest(mem, mem->mem_last, len); +} + +void *memreq(MEMPOOL *mem, size_t len) +{ + return memrequest(mem, memfirst(mem), len); +} + + diff --git a/sdk/other/picture.c b/sdk/other/picture.c new file mode 100644 index 0000000..3ff2dba --- /dev/null +++ b/sdk/other/picture.c @@ -0,0 +1,112 @@ +/* + * String formatting of numeric data. + * $Id$ + * Copyright (c) 1997 by Tycho Softworks. + * For conditions of distribution and reuse see product license. + */ + +#include + +char *picture(char *buf, const char *pict, long value) +{ + char *bp = buf, *tp; + long shift = 0; + int sign = 0; + int zfill = 0; + int digit; + int currency = 0; + int digits = 0; + + if(value < 0) + { + ++sign; + value = -value; + } + + while(*pict) + { + switch(*pict) + { + case '$': + ++currency; + *(bp++) = ' '; + ++pict; + break; + case '+': + if(sign) + *(bp++) = ' '; + else + *(bp++) = '+'; + ++pict; + break; + case '-': + if(sign) + *(bp++) = '-'; + else + *(bp++) = ' '; + ++pict; + break; + case '9': + case '0': + shift *= 10; + if(!shift) + shift = 1; + default: + *(bp++) = *(pict++); + } + } + if(value >= shift * 10) + { + bp = buf; + while(*bp) + { + if(isdigit(*bp)) + *bp = '#'; + ++bp; + } + return buf; + } + bp = tp = buf; + while(*bp) + { + switch(*bp) + { + case ',': + if(*(bp - 1) == '#') + { + *bp = '#'; + break; + } + if(!zfill) + *bp = ' '; + break; + case '#': + if(!digits) + if(shift > value) + break; + case '0': + ++zfill; + case '9': + ++digits; + digit = (int)(value / shift); + if((digit > 0) || (shift == 1)) + ++zfill; + if(!zfill && !digit) + digit = (int)(' ' - '0'); + *bp = (char)('0' + digit); + if(isdigit(*bp) && currency) + { + currency = 0; + *(tp - 1) = '$'; + } + value %= shift; + shift /= 10; + } + if(*bp != '#') + *(tp++) = *bp; + ++bp; + } + *tp = 0; + return buf; +} + diff --git a/sdk/other/search.c b/sdk/other/search.c new file mode 100644 index 0000000..15963bf --- /dev/null +++ b/sdk/other/search.c @@ -0,0 +1,46 @@ +/* + * File path search routines. + * $Id$ + * Copyright (c) 1997 by Tycho Softworks. + * For conditions of distribution and reuse see product license. + */ + +#include +#include +#include + +#ifdef QNX +#define PATHMARK "!" +#endif + +#ifndef PATHMARK +#define PATHMARK ":" +#endif + +char *search(const char *path, const char *file) +{ + static char buf[PATH_MAX + 1]; + char pbuf[PATH_MAX + 1]; + char *p; + + if(!path) + return NULL; + + strcpy(pbuf, path); + + p = strtok(pbuf, PATHMARK); + + while(p) + { + if(*p) + fncat(strcpy(buf, p), file); + else + strcpy(buf, file); + if(isfile(buf)) + return buf; + p = strtok(NULL, PATHMARK); + } + return NULL; +} + + diff --git a/sdk/other/strblank.c b/sdk/other/strblank.c new file mode 100644 index 0000000..d3e8d18 --- /dev/null +++ b/sdk/other/strblank.c @@ -0,0 +1,24 @@ +/* + * Test for blank strings. + * $Id$ + * Copyright (c) 1997 by Tycho Softworks. + * For conditions of distribution and reuse see product license. + */ + +#include + +char __SPACES[] = " \t\r\n"; + +bool strblank(const char *str) +{ + if(!str) + return TRUE; + + while(*str) + { + if(!strchr(__SPACES, *str)) + return FALSE; + ++str; + } + return TRUE; +} diff --git a/sdk/other/strcopy.c b/sdk/other/strcopy.c new file mode 100644 index 0000000..077f897 --- /dev/null +++ b/sdk/other/strcopy.c @@ -0,0 +1,61 @@ +/* + * String copying defined for supporting over-lapping strings 'insertion'. + * $Id$ + * Copyright (c) 1997 by Tycho Softworks. + * For conditions of distribution and reuse see product license. + */ + +#include + +static char *revcopy(char *to, const char *from, size_t count) +{ + while(count--) + *(to--) = *(from--); + + *to = *from; + return to; +}; + +char *strcopy(char *to, const char *from) +{ + char *s1 = to; + int l = from - to; + int l2 = len(from); + + if(!to || !from) + return NULL; + + if(l > 0 && l <= l2) + return revcopy(to + l2, from + l2, l2); + + ++l2; + while(l2--) + *(to++) = *(from++); + + return s1; +}; + +char *strncopy(char *to, const char *from, int l2) +{ + char *s1 = to; + int l = from - to; + if(len(from) < l2) + return strcopy(to, from); + + if(!to || !from) + return NULL; + + if(l > 0 && l <= l2) + { + to[l2] = 0; + --l2; + return revcopy(to + l2, from + l2, l2); + } + + while(l2--) + *(to++) = *(from++); + + *to = 0; + return s1; +}; + diff --git a/sdk/other/strcvt.h b/sdk/other/strcvt.h new file mode 100644 index 0000000..443c820 --- /dev/null +++ b/sdk/other/strcvt.h @@ -0,0 +1,56 @@ +/* + * Portable string handling routines. + * $Id$ + * Copyright (c) 1997 by Tycho Softworks. + * For conditions of distribution and reuse see product license. + */ + +#ifndef __OTHER_STRCVT_H__ +#define __OTHER_STRCVT_H__ + +#ifndef __STD_STRING_H__ +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __NAMESPACE +#define __SPACES __NAMESPACE(__SPACES) +#endif + +extern char __SPACES[]; + +#ifdef __NAMESPACE +#define atob __NAMESPACE(atob) +#define strint __NAMESPACE(strint) +#define picture __NAMESPACE(picture) +#define expand __NAMESPACE(expand) +#define xdigit __NAMESPACE(xdigit) +#define xtol __NAMESPACE(xtol) +#define hex __NAMESPACE(hex) +#define hexbyte __NAMESPACE(hexbyte) +#define hexshort __NAMESPACE(hexshort) +#define hexlong __NAMESPACE(hexlong) +#define str2bcd __NAMESPACE(str2bcd) +#define bcd2str __NAMESPACE(bcd2str) +#endif + +bool atob(const char *str); +char *strint(long i, int z); +char *picture(char *buf, const char *pict, long value); +char *expand(const char *str); +int xdigit(char digit); +ulong xtol(const char *digit); +char hex(int value); +char *hexbyte(uchar); +char *hexshort(ushort); +char *hexlong(ulong); +char *str2bcd(uchar *bcd, char *str, int max); +uchar *bcd2str(char *str, uchar *bcd, int len); +#ifdef __cplusplus +} +#endif + +#endif diff --git a/sdk/other/strdiff.c b/sdk/other/strdiff.c new file mode 100644 index 0000000..a0297f6 --- /dev/null +++ b/sdk/other/strdiff.c @@ -0,0 +1,24 @@ +/* + * Often used to evaluate similarity of soundex codes. + * $Id$ + * Copyright (c) 1997 by Tycho Softworks. + * For conditions of distribution and reuse see product license. + */ + +#include +#include + +int strdiff(const char *s1, const char *s2) +{ + int l1 = len(s1); + int l2 = len(s2); + int l = min(l1, l2); + int dif = abs(l1 - l2); + + while(l--) + { + if(*(s1++) != *(s2++)) + ++dif; + } + return dif; +} diff --git a/sdk/other/string.h b/sdk/other/string.h new file mode 100644 index 0000000..5db8cd4 --- /dev/null +++ b/sdk/other/string.h @@ -0,0 +1,65 @@ +/* + * Portable string handling routines. + * $Id$ + * Copyright (c) 1997 by Tycho Softworks. + * For conditions of distribution and reuse see product license. + */ + +#ifndef __OTHER_STRINGS_H__ +#define __OTHER_STRINGS_H__ + +#ifndef __STD_STRING_H__ +#include +#endif + +#ifndef __STD_TYPES_H__ +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __NAMESPACE +#define __SPACES __NAMESPACE(__SPACES) +#endif + +extern char __SPACES[]; + +#ifdef __NAMESPACE +#define strblank __NAMESPACE(strblank) +#define strtrim __NAMESPACE(strtrim) +#define strrtrim __NAMESPACE(strrtrim) +#define strltrim __NAMESPACE(strltrim) +#define right __NAMESPACE(right) +#define left __NAMESPACE(left) +#define ccount __NAMESPACE(ccount) +#define tail __NAMESPACE(tail) +#define field __NAMESPACE(field) +#define token __NAMESPACE(token) +#define strcopy __NAMESPACE(strcopy) +#define strncopy __NAMESPACE(strncopy) +#define strdiff __NAMESPACE(strdiff) +#define getargv __NAMESPACE(getargv) +#endif + +bool strblank(const char *str); +char *strtrim(char *s, const char *trim); +char *strrtrim(char *s, const char *trim); +char *strltrim(char *s, const char *trim); +char *right(char *str, size_t len); +char *left(char *str, size_t len); +int ccount(const char *str, const char *list); +char *tail(const char *str); +char *field(char **ptr, const char *tok); +char *token(char **ptr, const char *tok); +char *strcopy(char *to, const char *from); +char *strncopy(char *to, const char *from, int len); +int strdiff(const char *s1, const char *s2); +int getargv(char *base[], char *str); +void fatal(int exitcode, const char *format, ...); +#ifdef __cplusplus +} +#endif + +#endif diff --git a/sdk/other/strint.c b/sdk/other/strint.c new file mode 100644 index 0000000..f4291a1 --- /dev/null +++ b/sdk/other/strint.c @@ -0,0 +1,51 @@ +/* + * Convert integer to string, with optional leading zeros. + * $Id$ + * Copyright (c) 1997 by Tycho Softworks. + * For conditions of distribution and reuse see product license. + */ + +#include + +char *strint(long i, int z) +{ + static char buf[30]; + char b1[30]; + char *p = buf, *q = b1; + unsigned u; + + if(!i) + { + if(z < 1) + z = 1; + while(z--) + *(p++) = '0'; + *p = 0; + return buf; + } + if((i < 0) && !z) + { + i = -i; + buf[0] = '-'; + ++p; + } + u = (unsigned)i; + + while(u > 0) + { + *(q++) = (char)(u % 10) + '0'; + u /= 10; + } + *q = 0; + z -= strlen(b1); + while(z-- > 0) + *(p++) = '0'; + + while(q > b1) + *(p++) = *(--q); + *p = 0; + return buf; +} + + + diff --git a/sdk/other/strpos.c b/sdk/other/strpos.c new file mode 100644 index 0000000..79afbf5 --- /dev/null +++ b/sdk/other/strpos.c @@ -0,0 +1,46 @@ +/* + * String pointer manipulation routines. + * $Id$ + * Copyright (c) 1997 by Tycho Softworks. + * For conditions of distribution and reuse see product license. + */ + +#include + +char *tail(const char *tail) +{ + if(!tail) + return NULL; + + while(*tail) + ++tail; + + return (char *)tail; +} + +char *left(char *str, size_t pos) +{ + if(!str) + return NULL; + + if(pos < strlen(str)) + str[pos] = 0; + + return str; +}; + +char *right(char *s, size_t l) +{ + size_t len; + + if(!s) + return NULL; + + len = strlen(s); + if(len <= l) + return s; + + return s + len - l; +} + + diff --git a/sdk/other/strreq.c b/sdk/other/strreq.c new file mode 100644 index 0000000..fb69b95 --- /dev/null +++ b/sdk/other/strreq.c @@ -0,0 +1,39 @@ +/* + * Memory pool string copy. + * $Id$ + * Copyright (c) 1997 by Tycho Softworks. + * For conditions of distribution and reuse see product license. + */ + +#include + +char *strreq(MEMPOOL *mem, const char *str) +{ + char *newstr; + + if(!str) + return NULL; + + newstr = memreq(mem, strlen(str) + 1); + if(!newstr) + return NULL; + + strcpy(newstr, str); + return newstr; +} + +char *strlreq(MEMPOOL *mem, const char *str) +{ + char *newstr; + + if(!str) + return NULL; + + newstr = memlreq(mem, strlen(str) + 1); + if(!newstr) + return NULL; + + strcpy(newstr, str); + return newstr; +} + diff --git a/sdk/other/strtrim.c b/sdk/other/strtrim.c new file mode 100644 index 0000000..9afcfd5 --- /dev/null +++ b/sdk/other/strtrim.c @@ -0,0 +1,45 @@ +/* + * Portable string trimming routines. + * $Id$ + * Copyright (c) 1997 by Tycho Softworks. + * For conditions of distribution and reuse see product license. + */ + +#include + +char *strtrim(char *str, const char *trim) +{ + return strltrim(strrtrim(str, trim), trim); +} + +char *strrtrim(char *str, const char *trim) +{ + char *end; + + if(!str) + return NULL; + + end = str + strlen(str); + + while(end-- > str) + { + if(!strchr(trim, *end)) + return str; + *end = 0; + } + return str; +} + +char *strltrim(char *str, const char *trim) +{ + if(!str) + return NULL; + + while(*str) + { + if(!strchr(trim, *str)) + return str; + ++str; + } + return str; +} diff --git a/sdk/other/token.c b/sdk/other/token.c new file mode 100644 index 0000000..c9846ed --- /dev/null +++ b/sdk/other/token.c @@ -0,0 +1,50 @@ +/* + * Alternate thread-safe string token parsing. + * $Id$ + * Copyright (c) 1997 by Tycho Softworks. + * For conditions of distribution and reuse see product license. + */ + +#include + +char *token(char **ptr, const char *tok) +{ + char *p; + char *brk; + + if(strblank(*ptr)) + return NULL; + + p = strltrim(*ptr, tok); + brk = strpbrk(p, tok); + if(brk) + { + *brk = 0; + *ptr = strltrim(++brk, tok); + if(!(**ptr)) + *ptr = NULL; + } + else + *ptr = NULL; + return p; +} + +char *field(char **ptr, const char *tok) +{ + char *p = *ptr; + char *brk; + + if(strblank(p)) + return NULL; + + brk = strpbrk(p, tok); + if(brk) + { + *brk = 0; + *ptr = ++brk; + } + else + *ptr = NULL; + + return p; +} diff --git a/sdk/other/xval.c b/sdk/other/xval.c new file mode 100644 index 0000000..c7d1276 --- /dev/null +++ b/sdk/other/xval.c @@ -0,0 +1,28 @@ +/* + * Hex digit conversions. + * $Id$ + * Copyright (c) 1997 by Tycho Softworks. + * For conditions of distribution and reuse see product license. + */ + +#include + +int xdigit(char c) +{ + if(c > '9') + return upper(c) - '7'; + + return digit(c); +}; + +ulong xtol(const char *s) +{ + ulong v = 0l; + + while(isxdigit(*s)) + { + v = v << 4 | xdigit(*s); + ++s; + } + return v; +}; diff --git a/sdk/proc/Makefile.in b/sdk/proc/Makefile.in new file mode 100644 index 0000000..94ae3cb --- /dev/null +++ b/sdk/proc/Makefile.in @@ -0,0 +1,18 @@ +# +# Template to build our "other" object modules(libother.a) +# $Id: Makefile.in 1.2 Wed, 19 Mar 1997 12:44:53 -0500 dyfet $ +# Copyright (c) 1997 by Tycho Softworks. +# + +OBJS = spawn.o pdetach.o priority.o + +.c.o: + $(CC) $(CFLAGS) $(OPTIMIZE) -I.. -o $@ -c $< + $(AR) r ../lib/libproc.a $@ + +all: $(OBJS) + ranlib ../lib/libproc.a + +clean: + rm *.o + diff --git a/sdk/proc/bind.conf b/sdk/proc/bind.conf new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/sdk/proc/bind.conf @@ -0,0 +1 @@ + diff --git a/sdk/proc/make.conf b/sdk/proc/make.conf new file mode 100644 index 0000000..2ce0aaa --- /dev/null +++ b/sdk/proc/make.conf @@ -0,0 +1,5 @@ +inc=$CONFIG_HOST/include + +fn_find_file SYS_RESOURCE_H_MISSING $inc/sys/resource.h +fn_find_type SETPRIORITY_F_MISSING setpriority $inc/sys/resource.h + diff --git a/sdk/proc/pdetach.c b/sdk/proc/pdetach.c new file mode 100644 index 0000000..40814e4 --- /dev/null +++ b/sdk/proc/pdetach.c @@ -0,0 +1,78 @@ +/* + * Deamon-ify a user process; detach from controlling terminal and parent. + * $Id: daemon.c 1.2 Wed, 19 Mar 1997 12:44:53 -0500 dyfet $ + * Copyright (c) 1997 by Tycho Softworks. + * For conditions on distribution and reuse see product license. + * + * Abstract: + * Daemon processes are commonly used in UNIX to build server + * applications. This module captures the essense of functionality + * required to make a process into a daemon within a single function + * call. + * + * Functions: + * daemon() - convert user process into a daemon. + */ + +#include +#include + +/* Daemonify a user process under UNIX. + * + * Abstract: + * In UNIX, a user process becomes a daemon by detaching itself from + * it's parent process and establishes it's own process group. A + * daemon may also detach itself from it's controlling terminal. + * This is usually accomplished through fork(). + * + * Paramaters: + * flag - specifies daemon mode of operation: + * D_KEEPALL keeps all files open. + * D_KEEPSTDIO keeps stdio (stdin, stdout, stderr) open. + * D_KEEPNONIO detaches from stdio, keeps other files. + * D_KEEPNONE closes all open files. + * + * Returns: + * New pid of user process running as a daemon. + * + * Exceptions: + * Any failure terminates the process. No error message is possible + * since the process may already be detached from user I/O. + */ + +pid_t pdetach(int flag) +{ + pid_t pid; + int max = OPEN_MAX; + int i; + + signal(SIGHUP, SIG_IGN); + + i = 0; + if(flag == D_KEEPSTDIO) + i = 3; + + if(flag == D_KEEPNONIO) + max = 3; + + while((i < max) && (flag != D_KEEPALL)) + close(i++); + + pid = fork(); + if(pid < 0) + return pid; + + if(pid > 0) + exit(EX_OK); + + setsid(); + setpgid(0, getpid()); + pid = fork(); + if(pid < 0) + return pid; + + if(pid > 0) + exit(EX_OK); + + return getpid(); +} diff --git a/sdk/proc/priority.c b/sdk/proc/priority.c new file mode 100644 index 0000000..8818567 --- /dev/null +++ b/sdk/proc/priority.c @@ -0,0 +1,73 @@ +/* + * Specify process for soft realtime scheduling treatment. + * $Id$ + * Copyright (c) 1997 by Tycho Softworks. + * For conditions of distribution and reuse see product license. + */ + +#include +#include + +#ifndef SYS_RESOURCE_H_MISSING +#include +#endif + +#ifndef SETPRIORITY_F_MISSING + +int priority(int pri) +{ +#ifdef _POSIX_PRIORITY_SCHEDULING + #define _P __P + + #include + + struct sched_param p; +#endif + int newpri = getpriority(PRIO_PROCESS, 0) - pri - 1; + + if(setpriority(PRIO_PROCESS, 0, newpri)) + return -1; + +#ifdef _POSIX_MEMLOCK + #include + + if(mlockall(MCL_CURRENT | MCL_FUTURE)) + return -1; +#endif + +#ifdef _POSIX_PRIORITY_SCHEDULING + if(pri > 0) + { + p.sched_priority = sched_get_priority_min(SCHED_RR) + pri - 1; + if(sched_setscheduler(0, SCHED_RR, &p)) + return -1; + } +#endif + + return 0; +} + +#else + +int priority(int priority) +{ + return nice(- priority - 1); +} +#endif + +#ifdef _POSIX_PRIORITY_SCHEDULING +#include + +void yield(void) +{ + sched_yield(); +} +#else + +void yield(void) +{ + sleep(0); +} +#endif + + diff --git a/sdk/proc/process.h b/sdk/proc/process.h new file mode 100644 index 0000000..d65b765 --- /dev/null +++ b/sdk/proc/process.h @@ -0,0 +1,57 @@ +/* + * Portable process handling routines. + * $Id$ + * Copyright (c) 1997 by Tycho Softworks. + * For conditions of distribution and reuse see product license. + */ + +#ifndef __PROC_PROCESS_H__ +#define __PROC_PROCESS_H__ + +#ifndef __STD_PROCESS_H__ +#include +#endif + +/* Spawn services under UNIX fork() */ + +#define P_NOWAIT 0x00 /* Default, run concurrent */ +#define P_WAIT 0x01 /* Wait for and return exit status */ +#define P_BACKGROUND 0x02 /* Detach child from our stdio */ +#define P_SESSION 0x04 /* Use setsid() on child */ +#define P_OVERLAY 0x08 /* Really 'exec' called via spawn */ + +/* Some common/portable spawn varients and masks */ + +#define P_DETACH P_NOWAIT | P_SESSION | P_BACKGROUND +#define P_NOWAITO P_NOWAIT | P_SESSION + +/* Daemon initialization options */ + +#define D_KEEPSTDIO 0 /* Daemon keeps stdio connection */ +#define D_KEEPALL 1 /* Daemon keeps all open files */ +#define D_KEEPNONIO 2 /* Detach from stdio, keep others open */ +#define D_KEEPNONE 3 /* Deamon closes all files */ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Common process invokation services using fork() */ + +#ifdef __NAMESPACE +#define spawnv __NAMESPACE(spawnv) +#define spawnvp __NAMESPACE(spawnvp) +#define pdetach __NAMESPACE(pdetach) +#define priority __NAMEPSACE(priority) +#endif + +int spawnv(const int P_mode, const char *path, char *const argv[]); +int spawnvp(const int P_mode, const char *path, char *const argv[]); +pid_t pdetach(const int D_flag); /* Make current process a daemon */ +int priority(int pri); /* set realtime priorities */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/sdk/proc/spawn.c b/sdk/proc/spawn.c new file mode 100644 index 0000000..2b6d7db --- /dev/null +++ b/sdk/proc/spawn.c @@ -0,0 +1,92 @@ +/* + * Spawn services built on fork() for those libc's that lack spawning. + * $Id$ + * Copyright (c) 1997 by Tycho Softworks. + * For conditions of distribution and reuse see product license. + */ + +#include +#include + +static void spawn_redirect(int io, int mode) +{ + int fd = open("/dev/null", mode); + + if(fd < 0) + exit(EX_OSFILE); + + if(fd != io) + { + dup2(fd, io); + close(fd); + } +} + +static int spawn_wait(pid_t pid, int mode) +{ + int waitflag = mode & P_WAIT; + + /* -1 on fork failure */ + + if(pid == -1) + return -1; + + if(!waitflag) + return pid; + + waitpid(pid, &waitflag, 0); + return WEXITSTATUS(waitflag); +} + +static void spawn_mode(int mode) +{ + int i; + + if(mode & P_BACKGROUND) + { + spawn_redirect(0, O_RDONLY); + spawn_redirect(1, O_WRONLY); + spawn_redirect(2, O_WRONLY); + } + + for(i = 3; i < OPEN_MAX; ++i) + close(i); + + if(mode & P_SESSION) + setsid(); +} + +int spawnv(const int mode, const char *path, char *const argv[]) +{ + pid_t pid = 0; + int status; + + if(!(mode & P_OVERLAY)) + pid = fork(); + + if(pid) + return spawn_wait(pid, mode); + + spawn_mode(mode); + execv(path, argv); + exit(EX_UNAVAILABLE); + return -1; +} + +int spawnvp(const int mode, const char *path, char *const argv[]) +{ + pid_t pid = 0; + int status; + + if(!(mode & P_OVERLAY)) + pid = fork(); + + if(pid) + return spawn_wait(pid, mode); + + spawn_mode(mode); + execvp(path, argv); + exit(EX_UNAVAILABLE); + return -1; +} + diff --git a/sdk/std/Makefile.in b/sdk/std/Makefile.in new file mode 100644 index 0000000..d8f600b --- /dev/null +++ b/sdk/std/Makefile.in @@ -0,0 +1,18 @@ +# +# Template to build standard sdk object modules(libstd.a) +# $Id: Makefile.in 1.2 Wed, 19 Mar 1997 12:44:53 -0500 dyfet $ +# Copyright (c) 1997 by Tycho Softworks. +# + +OBJS = string.o utmp.o + +.c.o: + $(CC) $(CFLAGS) $(OPTIMIZE) -I.. -o $@ -c $< + $(AR) r ../lib/libstd.a $@ + +all: $(OBJS) + ranlib ../lib/libstd.a + +clean: + rm *.o + diff --git a/sdk/std/bind.conf b/sdk/std/bind.conf new file mode 100644 index 0000000..65ee123 --- /dev/null +++ b/sdk/std/bind.conf @@ -0,0 +1,69 @@ +BIND_OPTS=$BIND_OPTS' cc optimize cflags arch' +OPTIMIZE='' +CFLAGS='' + +if test -z "$CONFIG_CC" ; then + + echo -n "Analyzing C Compiler..." + + if test -z "$CONFIG_ARCH" ; then + CONFIG_ARCH=`uname -m`"-"`uname` + fi + + if fn_find_fpath -x gcc $PATH ; then + CONFIG_CC='gcc' + echo "gcc" + else + if test -z "$CONFIG_CC" ; then + CONFIG_CC='cc' + echo 'cc' + fi + fi +fi + +opt_optimize() { + OPTIMIZE="$1" + CONFIG_COPT="$1" + return 0 +} + +opt_cflags() { + CONFIG_ENDIAN="" + CONFIG_CFLAGS="$1" + CFLAGS="$1" +} + +opt_cc() { + CONFIG_CC="$1" + CONFIG_COPT="$OPTIMIZE" + CONFIG_CFLAGS="$CFLAGS" + return 0 +} + +opt_arch() { + CONFIG_ENDIAN="" + CONFIG_ARCH="$1" + if test "gcc" = $CONFIG_CC ; then + CONFIG_COPT="$OPTIMIZE" + if test -d /usr/local/lib/gcc-lib ; then + GCC_LIB='/usr/local/lib/gcc-lib' + fi + if test -d /usr/lib/gcc-lib ; then + GCC_LIB='/usr/lib/gcc-lib' + fi + if fn_find_fpath -d "$1" "$GCC_LIB"':/usr:/usr/local' ; then + CONFIG_CFLAGS='-b '"$1" + else + echo "config: $1: unsupported gcc architecture" + exit -1 + fi + if -d /usr/$1/include ; then + CONFIG_HOST=/usr/$1 + fi + if -d /usr/local/$1/include ; then + CONFIG_HOST=/usr/local/$1 + fi + fi + return 0 +} + diff --git a/sdk/std/files.h b/sdk/std/files.h new file mode 100644 index 0000000..84ad33a --- /dev/null +++ b/sdk/std/files.h @@ -0,0 +1,47 @@ +/* + * Portable support for file manipulation and access related functions. + * $Id$ + * Copyright (c) 1997 by Tycho Softworks. + * For conditions of distribution and reuse see product license. + */ + +#ifndef __STD_FILES_H__ +#define __STD_FILES_H__ + +#ifndef __STD_TYPES_H__ +#include +#endif + +#include +#include + +#ifndef UNISTD_H_MISSING +#include +#endif + +#ifndef SYS_FCNTL_H_MISSING +#include +#else +#ifndef FCNTL_H_MISSING +#include +#endif +#endif + +#ifndef IO_H_MISSING +#include +#endif + +#ifndef __STD_TYPES_H__ +#include +#endif + + +#ifdef OFF_T_MISSING +typedef long off_t; +#endif + +#ifdef FD_T_MISSING +typedef int fd_t; +#endif + +#endif diff --git a/sdk/std/help.conf b/sdk/std/help.conf new file mode 100644 index 0000000..71dfb97 --- /dev/null +++ b/sdk/std/help.conf @@ -0,0 +1,4 @@ +--arch= Compiler Architecture / Cross-Compile +--cc= Specify C Compiler to use +--cflags= Specify Compiler Options +--optimize= Specify Compiler Optimizations diff --git a/sdk/std/limits.h b/sdk/std/limits.h new file mode 100644 index 0000000..0766fe3 --- /dev/null +++ b/sdk/std/limits.h @@ -0,0 +1,97 @@ +/* + * Portable re-definition of limits header file. + * $Id$ + * Copyright (c) 1997 by Tycho Softworks. + * For conditions of distribution and reuse see product license. + */ + +#ifndef __STD_LIMITS_H__ +#define __STD_LIMITS_H__ + +#include + +#ifndef __CONFIG_H__ +#include +#endif + +#ifndef POSIX1_LIM_H_MISSING +#include +#else +#ifndef UNISTD_H_MISSING +#include +#endif +#include +#endif + +#ifndef NR_OPEN +#ifdef OPEN_MAX +#define NR_OPEN OPEN_MAX +#else +#define NR_OPEN _POSIX_OPEN_MAX +#endif +#endif + +#ifndef NGROUPS_MAX +#define NGROUPS_MAX _POSIX_NGROUPS_MAX +#endif + +#ifndef CHILD_MAX +#define CHILD_MAX _POSIX_CHILD_MAX +#endif + +#ifndef ARG_MAX +#define ARG_MAX _POSIX_ARG_MAX +#endif + +#ifndef LINK_MAX +#define LINK_MAX _POSIX_LINK_MAX +#endif + +#ifndef MAX_CANON +#define MAX_CANON _POSIX_MAX_CANON +#endif + +#ifndef MAX_INPUT +#define MAX_INPUT _POSIX_MAX_INPUT +#endif + +#ifndef NAME_MAX +#define NAME_MAX _POSIX_NAME_MAX +#endif + +#ifndef PATH_MAX +#define PATH_MAX _POSIX_PATH_MAX +#endif + +#ifndef PIPE_BUF +#define PIPE_BUF _POSIX_PIPE_BUF +#endif + +#ifndef SSIZE_MAX +#define SSIZE_MAX INT_MAX +#endif + +#ifndef STREAM_MAX +#define STREAM_MAX OPEN_MAX +#endif + +#ifndef TZONE_MAX +#define TZONE_MAX _POSIX_TZONE_MAX +#endif + +#ifdef MSDOS +#if !defined(GNU) && !defined(__386__) +#if defined(__BORLANDC__) && (defined(__SMALL__) || defined(__MEDIUM__)) +#define MEM_SEGMENT_MAX 16 +#endif +#if defined(M_I86SM) || defined(M_I86MM)) +#define MEM_SEGMENT_MAX 16 +#endif +#endif +#endif + +#ifndef MEM_SEGMENT_MAX +#define MEM_SEGMENT_MAX 32 +#endif + +#endif diff --git a/sdk/std/make.conf b/sdk/std/make.conf new file mode 100644 index 0000000..bf20113 --- /dev/null +++ b/sdk/std/make.conf @@ -0,0 +1,102 @@ +if test "$CONFIG_CC" = gcc ; then + + CONFIG_FPIC='-fpic' + CONFIG_EMPTY="0" + if test -z "$CONFIG_GCC_GFLAG" ; then + echo 'void f(){}' >conftest.c + if gcc -g -c conftest.c 2>&1 >/dev/null ; then + CONFIG_CFLAGS='-g '$CONFIG_CFLAGS + CONFIG_GCC_GFLAG='yes' + else + CONFIG_GCC_GFLAG='no' + fi + fi + if test -z "$CONFIG_COPT" ; then + case "$CONFIG_ARCH" in + i486* | i586* | i686*) + CONFIG_COPT='-O2 -m486' + ;; + *) + CONFIG_COPT='-O2' + esac + fi +else + CONFIG_FPIC='' + CONFIG_EMPTY="" + if test -z "$CONFIG_CFLAGS" ; then + case "$CONFIG_ARCH" in + *-SCO_SV) + CONFIG_CFLAGS='-b elf' + CONFIG_COPT='-O3' + CONFIG_FPIC='-KPIC' + ;; + esac + fi + + if test -z "$CONFIG_COPT" ; then + CONFIG_COPT='-O' + fi +fi + +echo "#define EMPTY "$CONFIG_EMPTY >>$CONFIG + +echo "CC="$CONFIG_CC >>config.make +echo "CFLAGS="$CONFIG_CFLAGS >>config.make +echo "PICFLAG="$CONFIG_FPIC >>config.make +echo "OPTIMIZE="$CONFIG_COPT >>config.make + +inc=$CONFIG_HOST/include +typelist=`find $inc -name types.h -follow -print` + +echo 'CONFIG_CC="'$CONFIG_CC'"' >>config.cache +echo 'CONFIG_COPT="'$CONFIG_COPT'"' >>config.cache +echo 'CONFIG_ARCH="'$CONFIG_ARCH'"' >>config.cache +echo 'CONFIG_CFLAGS="'$CONFIG_CFLAGS'"' >>config.cache +echo 'CONFIG_PICFLAG="'$CONFIG_FPIC'"' >>config.cache +echo 'CONFIG_GCC_GFLAG="'$CONFIG_GCC_GFLAG'"' >>config.cache +echo 'CONFIG_HOST="'$CONFIG_HOST'"' >>config.cache + +fn_find_type UCHAR_T_MISSING "uchar;" $typelist +fn_find_type USHORT_T_MISSING "ushort;" $typelist +fn_find_type ULONG_T_MISSING "ulong;" $typelist +fn_find_type SIZE_T_MISSING "size_t;" $typelist +fn_find_type SSIZE_T_MISSING "ssize_t;" $typelist +fn_find_type PID_T_MISSING "pid_t;" $typelist $inc/unistd.h +fn_find_type OFF_T_MISSING "off_t;" $typelist $inc/stdio.h $inc/fcntl.h $inc/sys/fcntl.h $inc/io.h +fn_find_type FD_T_MISSING "fd_t;" $typelist:$inc/stdio.h + +if fn_find_type GNUSTRING_F_MISSING "strcasecmp" $inc/string.h ; then + fn_find_type STRICMP_F_MISSING "stricmp" $inc/string.h +fi + +fn_find_type STRLWR_F_MISSING "strlwr" $inc/string.h +fn_find_type STRDUP_F_MISSING "strdup" $inc/string.h +fn_find_type STRISTR_F_MISSING "stristr" $inc/string.h +fn_find_type SELECT_F_MISSING "select" $inc/select.h $inc/sys/select.h $inc/sys/time.h +fn_find_type GETUTENT_F_MISSING "getutent" $inc/utmp.h + +fn_find_type UT_USER_I_MISSING "ut_user" $inc/utmp.h + +fn_find_file POSIX1_LIM_H_MISSING $inc/posix1_lim.h +fn_find_file PROCESS_H_MISSING $inc/process.h +fn_find_file UNISTD_H_MISSING $inc/unistd.h +fn_find_file POSIX2_LIM_H_MISSING $inc/posix2_lim.h +fn_find_file SYS_SELECT_H_MISSING $inc/sys/select.h +fn_find_file SELECT_H_MISSING $inc/select.h +fn_find_file POLL_H_MISSING $inc/poll.h +fn_find_file SYS_POLL_H_MISSING $inc/sys/poll.h + +if fn_find_file WAIT_H_MISSING $inc/wait.h ; then + fn_find_file SYS_WAIT_H_MISSING $inc/sys/wait.h +fi +fn_find_file POSIX_OPT_H_MISSING $inc/posix_opt.h +fn_find_file CONFNAME_H_MISSING $inc/confname.h +fn_find_file SYSCONF_H_MISSING $inc/sysconf.h +fn_find_file ENV_H_MISSING $inc/env.h +fn_find_file SYSEXITS_H_MISSING $inc/sysexits.h +fn_find_file SYS_TIME_H_MISSING $inc/sys/time.h +if fn_find_file SYS_FCNTL_H_MISSING $inc/sys/fcntl.h ; then + fn_find_file FCNTL_H_MISSING $inc/fcntl.h +fi +fn_find_file IO_H_MISSING $inc/io.h + diff --git a/sdk/std/math.h b/sdk/std/math.h new file mode 100644 index 0000000..d1eb298 --- /dev/null +++ b/sdk/std/math.h @@ -0,0 +1,31 @@ +/* + * Common math functions and macros. + * $Id$ + * Copyright (c) 1997 by Tycho Softworks. + * For conditions of distribution and reuse see product license. + */ + +#ifndef __STD_MATH_H__ +#define __STD_MATH_H__ + +#ifndef __STD_TYPES_H__ +#include +#endif + +#ifndef min +#define min(a, b) ((a)<(b)?(a):(b)) +#endif + +#ifndef max +#define max(a, b) ((a)>(b)?(a):(b)) +#endif + +#ifndef abs +#define abs(a) ((a)<0?(-a):(a)) +#endif + +#ifndef align +#define align(x, s) ((((x) + (s) - 1) / (s)) *(s)) +#endif + +#endif diff --git a/sdk/std/poll.h b/sdk/std/poll.h new file mode 100644 index 0000000..a9eb3f9 --- /dev/null +++ b/sdk/std/poll.h @@ -0,0 +1,21 @@ +/* + * Find or insert replacement "poll" routine. + * $Id$ + * Copyright (c) 1997 by Tycho Softworks. + * For conditions of distribution and use see product license. + */ + +#ifndef __STD_POLL_H__ +#define __STD_POLL_H__ + +#ifdef POLL_H_MISSING +#ifndef SYS_POLL_H_MISSING +#include +#endif +#else +#include +#endif + +#include + +#endif diff --git a/sdk/std/posix1_lim.h b/sdk/std/posix1_lim.h new file mode 100644 index 0000000..5520f22 --- /dev/null +++ b/sdk/std/posix1_lim.h @@ -0,0 +1,92 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* + * POSIX Standard: 2.9.2 Minimum Values Added to + */ + +#ifndef _POSIX1_LIMITS_H + +#define _POSIX1_LIMITS_H 1 + + +/* These are the standard-mandated minimum values. */ + +/* Maximum length of arguments to `execve', including environment. */ +#define _POSIX_ARG_MAX 4096 + +/* Maximum simultaneous processes per real user ID. */ +#define _POSIX_CHILD_MAX 6 + +/* Maximum link count of a file. */ +#define _POSIX_LINK_MAX 8 + +/* Number of bytes in a terminal canonical input queue. */ +#define _POSIX_MAX_CANON 255 + +/* Number of bytes for which space will be + available in a terminal input queue. */ +#define _POSIX_MAX_INPUT 255 + +/* Number of simultaneous supplementary group IDs per process. */ +#define _POSIX_NGROUPS_MAX 0 + +/* Number of files one process can have open at once. */ +#define _POSIX_OPEN_MAX 16 + +/* Number of bytes in a filename. */ +#define _POSIX_NAME_MAX 14 + +/* Number of bytes in a pathname. */ +#define _POSIX_PATH_MAX 255 + +/* Number of bytes than can be written atomically to a pipe. */ +#define _POSIX_PIPE_BUF 512 + +/* Largest value of a `ssize_t'. */ +#define _POSIX_SSIZE_MAX 32767 + +/* Number of streams a process can have open at once. */ +#define _POSIX_STREAM_MAX 8 + +/* Number of bytes in `tzname'. */ +#define _POSIX_TZNAME_MAX 3 + + +/* don't even think about changing it without checking tzfile.h + * in source code dir ./time first. + */ +#undef TZNAME_MAX +#define TZNAME_MAX 50 + +#ifndef SSIZE_MAX +#define SSIZE_MAX INT_MAX +#endif + +#ifndef STREAM_MAX +#define STREAM_MAX OPEN_MAX +#endif + +/* This value is a guaranteed minimum maximum. + The current maximum can be got from `sysconf'. */ + +#ifndef NGROUPS_MAX +#define NGROUPS_MAX _POSIX_NGROUPS_MAX +#endif + +#endif /* posix1_limits.h */ diff --git a/sdk/std/process.h b/sdk/std/process.h new file mode 100644 index 0000000..2fdf6ae --- /dev/null +++ b/sdk/std/process.h @@ -0,0 +1,99 @@ +/* + * Portable process handling routines. + * $Id$ + * Copyright (c) 1997 by Tycho Softworks. + * For conditions of distribution and reuse see product license. + */ + +#ifndef __STD_PROCESS_H__ +#define __STD_PROCESS_H__ + +#ifndef __STD_TYPES_H__ +#include +#endif + +#ifndef __STD_LIMITS_H__ +#include +#endif + +#ifndef POSIX2_LIM_H_MISSING +#include +#endif + +#ifndef POSIX_OPT_H_MISSING +#include +#endif + +#ifndef UNISTD_H_MISSING +#include +#endif + +#ifndef _SC_OPEN_MAX +#ifndef CONFNAME_H_MISSING +#include +#else +#ifndef SYSCONF_H_MISSING +#include +#endif +#endif +#endif + +#ifndef PROCESS_H_MISSING +#include +#endif + +#ifndef WAIT_H_MISSING +#include +#else +#ifndef SYS_WAIT_H_MISSING +#include +#endif +#endif + +#ifndef ENV_H_MISSING +#include +#endif + +#ifndef SYSEXITS_H_MISSING +#include +#else +#include +#endif + +/* We now re-evaluate system limits using runtime sysconf() values */ + +#ifdef _SC_ARG_MAX +#undef ARG_MAX +#define ARG_MAX (sysconf(_SC_ARG_MAX)) +#endif + +#ifdef _SC_CHILD_MAX +#undef CHILD_MAX +#define CHILD_MAX (sysconf(_SC_CHILD_MAX)) +#endif + +#ifdef _SC_NGROUPS_MAX +#undef NGROUPS_MAX +#define NGROUPS_MAX (sysconf(_SC_NGROUPS_MAX)) +#endif + +#ifdef _SC_OPEN_MAX +#undef OPEN_MAX +#define OPEN_MAX (sysconf(_SC_OPEN_MAX)) +#endif + +#ifdef _SC_STREAM_MAX +#undef STREAM_MAX +#define STREAM_MAX (sysconf(_SC_STREAM_MAX)) +#endif + +#ifdef _SC_TZNAME_MAX +#undef TZNAME_MAX +#define TZNAME_MAX (sysconf(_SC_TZNAME_MAX)) +#endif + +#ifdef PID_T_MISSING +typedef int pid_t; +#endif + +#endif diff --git a/sdk/std/select.h b/sdk/std/select.h new file mode 100644 index 0000000..2812581 --- /dev/null +++ b/sdk/std/select.h @@ -0,0 +1,21 @@ +/* + * Find or use "replacement" select routines. + * $Id$ + * Copyright (c) 1997 by Tycho Softworks. + * For conditions of distribution and use see license. + */ + +#ifndef __STD_SELECT_H__ +#define __STD_SELECT_H__ + +#ifdef SELECT_H_MISSING +#ifndef SYS_SELECT_H_MISSING +#include +#endif +#else +#include +#endif + +#include + +#endif diff --git a/sdk/std/signal.h b/sdk/std/signal.h new file mode 100644 index 0000000..b56b48a --- /dev/null +++ b/sdk/std/signal.h @@ -0,0 +1,11 @@ +#ifndef __STD_SIGNAL_H__ +#define __STD_SIGNAL_H__ + +#ifndef __CONFIG_H__ +#include +#endif + +#include + +#endif + diff --git a/sdk/std/string.c b/sdk/std/string.c new file mode 100644 index 0000000..6f9649e --- /dev/null +++ b/sdk/std/string.c @@ -0,0 +1,110 @@ +/* + * Define constants used by other string services and case insensitive + * compare and conversion functions missing in some libc distributions. + * $Id$ + * Copyright (c) 1997 by Tycho Softworks. + * For conditions of distribution and reuse see product license. + */ + +#include + +#ifdef STRLWR_F_MISSING + +char *strlwr(char *s) +{ + char *old; + + if(!s) + return NULL; + + old=s; + while(*s = (char)tolower(*s)) + ++s; + + return old; +} + +char *strupr(char *s) +{ + char *old; + + if(!s) + return NULL; + + old=s; + while(*s = (char)toupper(*s)) + ++s; + return old; +} + +#endif + +#ifdef STRDUP_F_MISSING + +char *strdup(str) +char *str; +{ + char *new = (char *)malloc(strlen(str) + 1); + if(!new) + return NULL; + + return strcpy(new, str); +} + +#endif + +#ifdef STRICMP_F_MISSING + +int stricmp(const char *s1, const char *s2) +{ + int t; + + while(*s1 && *s2) + { + if (t=tolower(*s1)-tolower(*s2)) + return t; + + ++s1; + ++s2; + } + return tolower(*s1)-tolower(*s2); +} + +int strnicmp(const char *s1,const char *s2, size_t n) +{ + int t; + + while (n--) + { + if (t=tolower(*s1)-tolower(*s2)) + return t; + + if (!*s1) + return 0; + + ++s1; + ++s2; + } + return 0; +} + +#endif + +#ifdef STRISTR_F_MISSING + +char *stristr(char *s1, const char *s2) +{ + int len = strlen(s2); + int count = strlen(s1) - len + 1; + + while(count--) + { + if(!strnicmp(s1, s2, len)) + return s1; + ++s1; + } + return NULL; +} + +#endif + diff --git a/sdk/std/string.h b/sdk/std/string.h new file mode 100644 index 0000000..bf642cf --- /dev/null +++ b/sdk/std/string.h @@ -0,0 +1,75 @@ +/* + * Portable string handling routines. + * $Id$ + * Copyright (c) 1997 by Tycho Softworks. + * For conditions of distribution and reuse see product license. + */ + +#ifndef __STD_STRINGS_H__ +#define __STD_STRINGS_H__ + +#ifndef __STD_TYPES_H__ +#include +#endif + +#include +#include + +#ifndef STRCASECMP_F_MISSING +#define stricmp(s1, s2) strcasecmp(s1, s2) +#define strnicmp(s1, s2, n) strncasecmp(s1, s2, n) +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __NAMESPACE +#define __SPACES __NAMESPACE(__SPACES) +#endif + +extern char __SPACES[]; + +#ifdef STRICMP_F_MISSING +#ifdef __NAMESPACE +#define stricmp __NAMESPACE(stricmp) +#define strnicmp __NAMESPACE(strnicmp) +#endif + +int stricmp(const char *s1, const char *s2); +int strnicmp(const char *s1, const char *s2, size_t n); +#endif + +#ifdef STRLWR_F_MISSING + +#ifdef __NAMESPACE +#define strupr __NAMESPACE(strupr) +#define strlwr __NAMESPACE(strlwr) +#endif + +char *strlwr(char *s1); +char *strupr(char *s2); +#endif + +#ifdef STRDUP_F_MISSING + +#ifdef __NAMESPACE +#define strdup __NAMESPACE(strdup) +#endif + +char *strdup(const char *s); +#endif + +#ifdef STRISTR_F_MISSING +#ifdef __NAMESPACE +#define stristr __NAMESPACE(stristr) +#endif + +char *stristr(char *s1, const char *s2); +#endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/sdk/std/sysexits.h b/sdk/std/sysexits.h new file mode 100644 index 0000000..208ec0e --- /dev/null +++ b/sdk/std/sysexits.h @@ -0,0 +1,118 @@ +/* + * Copyright (c) 1987 Regents of the University of California. + * 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 acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS 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. + * + * @(#)sysexits.h 4.8 (Berkeley) 4/3/91 + */ + +#ifndef _SYSEXITS_H +#define _SYSEXITS_H + +/* + * SYSEXITS.H -- Exit status codes for system programs. + * + * This include file attempts to categorize possible error + * exit statuses for system programs, notably delivermail + * and the Berkeley network. + * + * Error numbers begin at EX__BASE to reduce the possibility of + * clashing with other exit statuses that random programs may + * already return. The meaning of the codes is approximately + * as follows: + * + * EX_USAGE -- The command was used incorrectly, e.g., with + * the wrong number of arguments, a bad flag, a bad + * syntax in a parameter, or whatever. + * EX_DATAERR -- The input data was incorrect in some way. + * This should only be used for user's data & not + * system files. + * EX_NOINPUT -- An input file (not a system file) did not + * exist or was not readable. This could also include + * errors like "No message" to a mailer (if it cared + * to catch it). + * EX_NOUSER -- The user specified did not exist. This might + * be used for mail addresses or remote logins. + * EX_NOHOST -- The host specified did not exist. This is used + * in mail addresses or network requests. + * EX_UNAVAILABLE -- A service is unavailable. This can occur + * if a support program or file does not exist. This + * can also be used as a catchall message when something + * you wanted to do doesn't work, but you don't know + * why. + * EX_SOFTWARE -- An internal software error has been detected. + * This should be limited to non-operating system related + * errors as possible. + * EX_OSERR -- An operating system error has been detected. + * This is intended to be used for such things as "cannot + * fork", "cannot create pipe", or the like. It includes + * things like getuid returning a user that does not + * exist in the passwd file. + * EX_OSFILE -- Some system file (e.g., /etc/passwd, /etc/utmp, + * etc.) does not exist, cannot be opened, or has some + * sort of error (e.g., syntax error). + * EX_CANTCREAT -- A (user specified) output file cannot be + * created. + * EX_IOERR -- An error occurred while doing I/O on some file. + * EX_TEMPFAIL -- temporary failure, indicating something that + * is not really an error. In sendmail, this means + * that a mailer (e.g.) could not create a connection, + * and the request should be reattempted later. + * EX_PROTOCOL -- the remote system returned something that + * was "not possible" during a protocol exchange. + * EX_NOPERM -- You did not have sufficient permission to + * perform the operation. This is not intended for + * file system problems, which should use NOINPUT or + * CANTCREAT, but rather for higher level permissions. + */ + +#define EX_OK 0 /* successful termination */ + +#define EX__BASE 64 /* base value for error messages */ + +#define EX_USAGE 64 /* command line usage error */ +#define EX_DATAERR 65 /* data format error */ +#define EX_NOINPUT 66 /* cannot open input */ +#define EX_NOUSER 67 /* addressee unknown */ +#define EX_NOHOST 68 /* host name unknown */ +#define EX_UNAVAILABLE 69 /* service unavailable */ +#define EX_SOFTWARE 70 /* internal software error */ +#define EX_OSERR 71 /* system error (e.g., can't fork) */ +#define EX_OSFILE 72 /* critical OS file missing */ +#define EX_CANTCREAT 73 /* can't create (user) output file */ +#define EX_IOERR 74 /* input/output error */ +#define EX_TEMPFAIL 75 /* temp failure; user is invited to retry */ +#define EX_PROTOCOL 76 /* remote error in protocol */ +#define EX_NOPERM 77 /* permission denied */ +#define EX_CONFIG 78 /* configuration error */ + +#define EX__MAX 78 /* maximum listed value */ + +#endif /* !_SYSEXITS_H */ diff --git a/sdk/std/time.h b/sdk/std/time.h new file mode 100644 index 0000000..45c42cb --- /dev/null +++ b/sdk/std/time.h @@ -0,0 +1,23 @@ +/* + * Portable header access into time functions. + * $Id$ + * Copyright (c) 1997 by Tycho Softworks. + * For conditions of distribution and reuse see product license. + */ + +#ifndef __STD_TIME_H__ +#define __STD_TIME_H__ + +#ifndef __CONFIG_H__ +#include +#endif + +#include + +#ifndef SYS_TIME_H_MISSING +#include +#endif + +#endif + + diff --git a/sdk/std/types.h b/sdk/std/types.h new file mode 100644 index 0000000..ebd4ea7 --- /dev/null +++ b/sdk/std/types.h @@ -0,0 +1,54 @@ +/* + * Portable common datatype declarations. + * $Id$ + * Copyright (c) 1997 by Tycho Softworks. + * For conditions of distribution and reuse see product license. + */ + +#ifndef __STD_TYPES_H__ +#define __STD_TYPES_H__ + +#ifndef __CONFIG_H__ +#include +#endif + +#include +#include + +#ifdef UCHAR_T_MISSING +typedef unsigned char uchar; +#endif + +#ifdef USHORT_T_MISSING +typedef unsigned short ushort; +#endif + +#ifdef ULONG_T_MISSING +typedef unsigned long ulong; +#endif + +#ifdef __cplusplus +enum +{ + FALSE=0, + TRUE +}; +#else +typedef enum +{ + FALSE=0, + TRUE +} bool; +#endif + +typedef void *ptr_t; + +#ifdef SIZE_T_MISSING +typedef unsigned int size_t; +#endif + +#ifdef SSIZE_T_MISSING +typedef int ssize_t; +#endif + +#endif diff --git a/sdk/std/utmp.c b/sdk/std/utmp.c new file mode 100644 index 0000000..78cbf64 --- /dev/null +++ b/sdk/std/utmp.c @@ -0,0 +1,49 @@ +/* + * Portable emulation of utmp access routines, such as for broken BSD. + * $Id$ + * Copyright (c) 1997 by Tycho Softworks. + * For conditions of distribution and use see license. + */ + +#include +#include + +#ifdef GETUTENT_F_MISSING + +static fd_t ut = -1; +static struct utmp utmp; + +void setutent(void) +{ + if(ut < 0) + ut = open(_PATH_UTMP, O_RDONLY); + if(ut < 0) + return; + + lseek(ut, 0l, SEEK_SET); +} + +void endutent(void) +{ + if(ut > -1) + { + close(ut); + ut = -1; + } +} + +struct utmp *getutent(void) +{ + if(ut < 0) + setutent(); + + if(ut < 0) + return NULL; + + if(read(ut, &utmp, sizeof(utmp)) < sizeof(utmp)) + return NULL; + + return &utmp; +} + +#endif diff --git a/sdk/std/utmp.h b/sdk/std/utmp.h new file mode 100644 index 0000000..2ac67f4 --- /dev/null +++ b/sdk/std/utmp.h @@ -0,0 +1,31 @@ +/* + * utmp file access interface, local or ported. + * $Id$ + * Copyright (c) 1997 by Tycho Softworks. + * For conditions of distribution and use see license. + */ + +#ifndef __STD_UTMP_H__ +#define __STD_UTMP_H__ + +#ifndef __STD_TYPES_H__ +#include +#endif + +#include + +#ifndef _UTMP_PATH +#define _UTMP_PATH "/etc/utmp.h" +#endif + +#ifdef UT_USER_I_MISSING +#define ut_user ut_name +#endif + +#ifdef GETUTENT_F_MISSING +void setutent(void); +void endutent(void); +struct utmp *getutent(void); +#endif + +#endif diff --git a/speak.lsm b/speak.lsm new file mode 100644 index 0000000..d96b4d5 --- /dev/null +++ b/speak.lsm @@ -0,0 +1,23 @@ +Begin3 +Title: SPO256-AL2 Text-to-Speech Services +Version: 1.0 +Entered-date: March 23, 1997 +Description: This package comprises a network TCP text-to-speech server + designed for the SPO256-AL2 text-to-speech board, as + described in the January '97 issue of the Linux Journal. + This server is now implemented as a generic rc.d startable + "service" with standardized (server independent) utilities, + and may be used to develop other network-wide text-to-speech + services for different hardware. This release adds new + functionality to both the server and vmon utilities. +Keywords: talk, cti, tsw, tycho, lj, spo256, vocoder +Author: dyfet@tycho.com (David Sugar) +Maintained-by: dyfet@tycho.com (David Sugar) +Primary-site: ftp.tycho.com /dist + 58 kb speak-0.3.tar.gz + 1 kb speak.lsm +Alternate-site: sunsite.unc.edu: no idea where +Original-site: http://www.tycho.com/packages/speak +Platform: Should be portable to virtually any UNIX system. +Copying-policy: Free, public, terms similar to BSD on redistribution. +End diff --git a/spktrapd/README.NOW b/spktrapd/README.NOW new file mode 100644 index 0000000..957e196 --- /dev/null +++ b/spktrapd/README.NOW @@ -0,0 +1,8 @@ +Future package! + +The spktrapd module will be a snmptrapd that redirects snmp traps verbally to +the speak service using device and enterprise specific rules and tables. +This will allow verbal monitering and alerts for a variety of network +devices. + + diff --git a/spo256/Makefile.in b/spo256/Makefile.in new file mode 100644 index 0000000..6e21ea4 --- /dev/null +++ b/spo256/Makefile.in @@ -0,0 +1,34 @@ +# +# Template to build spo256-AL2 text-to-speech server. +# $Id: Makefile.in 1.2 Mon, 24 Mar 1997 12:25:37 -0500 dyfet $ +# Copyright (c) 1997 by Tycho Softworks. +# + +OBJS = speak.o spo.o getspo.o words.o chars.o getidx.o client.o \ + number.o currency.o +PROGS = spo256 +START = 10 +RUNLVLS = 3 + +all: $(PROGS) + +install: $(PROGS) + install -s -g bin $(PROGS) $(SBINDIR) + ln -sf $(SBINDIR)/spo256 $(BINDIR)/speak + install -g bin speak.conf $(SYSCONFDIR) + ../sdk/bin/instinit speak $(START) $(RUNLVLS) + ../sdk/bin/instsvc services speak 800/tcp \# SPO256-AL2 Text-to-Speech service + ../sdk/bin/instman $(MANDIR) 1 speak + ../sdk/bin/instman $(MANDIR) 7 speak.conf + ../sdk/bin/instman $(MANDIR) 8 spo256 + +clean: + -rm $(PROGS) + -rm $(OBJS) + +.c.o: + $(CC) $(CFLAGS) $(OPTIMIZE) -I../sdk -o $@ -c $< + +spo256: $(OBJS) + $(CC) $(CFLAGS) -L../sdk/lib $(LIBS) -o $@ $(OBJS) $(LIBS) + diff --git a/spo256/README b/spo256/README new file mode 100644 index 0000000..29c2fae --- /dev/null +++ b/spo256/README @@ -0,0 +1,24 @@ +This particular SPO256 server is able to translate common usages for numbers +and perform word substitution. For example, the number 123.45 is pronounced +as "one hundred twenty three point four five". Internet names and addresses +are also pronounced correctly to a large extent. The support of different +usages and idioms in this server is not yet as complete as the WorldVU SPO +server, but this is being worked on. + +The SPO server was rewritten in release 0.3 with a character state parser +to allow better parsing for and pacing of spoken text. The 0.3 state +parser now recognizes embedded server command sequences as well as text +that is to be spoken. Embedded server commands are proceeded by the + character, and appear in <>'s, using a format much like mark-up tags. +For example, word "spelling" can be turned on or off with and +. The current tags supported by the SPO256 server are found +in the spo256 man page. More tags will be added as they appear feasable to +create. + +This SPO server differs from the original WorldVU server in that it can +also be used in a client role to pipe standard output to the server. One +can enter "cat filename | spo256 localhost" (or "cat filename | speak +localhost") to redirect output to the spo server running on the local +machine, for example. + + diff --git a/spo256/chars.c b/spo256/chars.c new file mode 100644 index 0000000..e4b2a2a --- /dev/null +++ b/spo256/chars.c @@ -0,0 +1,339 @@ +/* + * Character state parser for text-to-speech server. + * $Id: chars.c 1.2 Mon, 24 Mar 1997 12:25:37 -0500 dyfet $ + * Copyright (c) 1997 by Tycho Softworks. + * For conditions of distribution and reuse see product license. + */ + +#include +#include +#include +#include +#include "speak.h" + +enum +{ + CH_IGNORE, + CH_PERIOD, + CH_QUOTE, + CH_ESCAPE, + CH_SPACE, + CH_ALPHA, + CH_NUMERIC, + CH_PUNCT, +}; + +static uchar map[256]; +static uchar word[256]; +static int cpos = 0; +static bool init = FALSE; +static void (*state)(uchar ch); +static bool quote; + +static void s_hex(uchar ch); +static void s_num(uchar ch); +static void s_cmd(uchar ch); +static void s_leadcmd(uchar ch); +static void s_abbrev(uchar ch); +static void s_point(uchar ch); +static void s_word(uchar ch); +static void s_idle(uchar ch); + +static void s_hex(uchar ch) +{ + switch(ch) + { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + case 'a': + case 'A': + case 'b': + case 'B': + case 'c': + case 'C': + case 'd': + case 'D': + case 'e': + case 'E': + case 'f': + case 'F': + word[cpos++] = ch; + break; + default: + word[cpos] = 0; + number(word); + state = s_idle; + s_idle(ch); + } +} + +static void s_num(uchar ch) +{ + switch(map[ch]) + { + case CH_NUMERIC: + word[cpos++] = ch; + break; + default: + switch(ch) + { + case 'e': + case '^': + word[cpos++] = ch; + number(word); + cpos = 0; + spo_word("raised"); + spo_word("to"); + spo_word("the"); + spo_word("power"); + break; + case ':': + case '/': + case '.': + word[cpos++] = ch; + break; + case '%': + word[cpos] = 0; + number(word); + state = s_idle; + spo_word("percent"); + break; + case 'x': + case 'X': + if(cpos == 1) + { + cpos = 0; + state = s_hex; + break; + } + default: + word[cpos] = 0; + number(word); + state = s_idle; + s_idle(ch); + } + } +} + +static void s_cmd(uchar ch) +{ + if(ch == '>') + { + word[cpos] = 0; + spo_cmd((char *)word); + state = s_idle; + } + else + word[cpos++] = ch; +} + +static void s_leadcmd(uchar ch) +{ + if(ch == '<') + state = s_cmd; + else + { + state = s_idle; + s_idle(ch); + } +} + +static void s_abbrev(uchar ch) +{ + switch(map[ch]) + { + case CH_SPACE: + abbrev((char *)word); + state = s_idle; + break; + default: + spo_word((char *)word); + cpos = 0; + spo_word("dot"); + state = s_word; + s_word(ch); + } +} + +static void s_point(uchar ch) +{ + switch(map[ch]) + { + case CH_ALPHA: + state = s_word; + case CH_PERIOD: + spo_word("dot"); + break; + case CH_NUMERIC: + spo_word("point"); + state = s_num; + break; + default: + state = s_idle; + break; + } +} + +static void s_word(uchar ch) +{ + switch(map[ch]) + { + case CH_PERIOD: + if(!cpos) + state = s_point; + else + state = s_abbrev; + word[cpos++] = '.'; + word[cpos] = 0; + break; + case CH_PUNCT: + case CH_ALPHA: + case CH_NUMERIC: + if(cpos < 255) + word[cpos++] = ch; + break; + case CH_SPACE: + word[cpos] = 0; + spo_word((char *)word); + state = s_idle; + break; + default: + switch(ch) + { + case '\'': + word[cpos++] = ch; + break; + default: + word[cpos] = 0; + spo_word((char *)word); + spo_pause(P_WORD); + state = s_idle; + s_idle(ch); + } + } +} + +static void s_idle(uchar ch) +{ + cpos = 0; + switch(map[ch]) + { + case CH_NUMERIC: + state = s_num; + s_num(ch); + break; + case CH_ALPHA: + state = s_word; + s_word(ch); + break; + case CH_ESCAPE: + state = s_leadcmd; + break; + case CH_SPACE: + spo_pause(P_WORD); + break; + case CH_QUOTE: + if(quote) + { + spo_word("end"); + quote = FALSE; + } + else + quote = TRUE; + spo_word("quote"); + break; + default: + switch(ch) + { + case '$': + word[0] = '$'; + cpos = 1; + state = s_num; + break; + case '*': + spo_word("times"); + break; + case '/': + spo_word("divided"); + spo_word("by"); + break; + case '+': + spo_word("plus"); + break; + case '-': + spo_word("minus"); + break; + case '&': + spo_word("and"); + break; + case '|': + spo_word("or"); + break; + case '~': + spo_word("not"); + break; + case ')': + spo_word("end"); + case '(': + spo_word("parenthesis"); + break; + case '=': + spo_word("equals"); + break; + case '<': + spo_word("less"); + spo_word("than"); + break; + case '>': + spo_word("greater"); + spo_word("than"); + break; + default: + spo_pause(P_WORD); + } + } +} + +void chars(FILE *fp) +{ + int i, ch; + + quote = FALSE; + state = s_idle; + + if(!init) + { + for(i = 0; i < 256; ++i) + map[i] = CH_IGNORE; + + map[27] = CH_ESCAPE; + + for(i = 33; i < 127; ++i) + map[i] = CH_PUNCT; + + map[9] = map[13] = map[10] = map[32] = CH_SPACE; + for(i = 48; i < 58; ++i) + map[i] = CH_NUMERIC; + + for(i = 0; i < 26; ++i) + { + map[i + 65] = CH_ALPHA; + map[i + 97] = CH_ALPHA; + } + map['.'] = CH_PERIOD; + map['\"'] = CH_QUOTE; + } + + while(EOF != (ch = fgetc(fp))) + (*state)(ch); + + (*state)(0); +} diff --git a/spo256/client.c b/spo256/client.c new file mode 100644 index 0000000..b43696f --- /dev/null +++ b/spo256/client.c @@ -0,0 +1,40 @@ +/* + * Client operating mode. + * $Id: client.c 1.2 Mon, 24 Mar 1997 12:25:37 -0500 dyfet $ + * Copyright (c) 1997 by Tycho Softworks. + * For conditions of distribution and reuse see product license. + * + * Abstract: + * The client mode of operation will connect to SPO256 server and + * redirect standard output to the server. This allows the speak + * (spo256) image to be used to terminate pipes. + */ + +#include +#include +#include +#include +#include +#include +#include "speak.h" + +void client(char *hostname, ushort port) +{ + STREAM fp = opentcp(hostname, port); + char buf[1024]; + + if(!fp) + fatal(EX_UNAVAILABLE, "spo256: %s: unkown host\n", hostname); + + gettcp(buf, sizeof(buf) - 1, fp); /* get banner line */ + while(!feof(stdin)) + { + fgets(buf, sizeof(buf) - 1, stdin); + if(feof(stdin)) + break; + + puttcp(buf, fp); + } + closetcp(fp); + exit(0); +} diff --git a/spo256/currency.c b/spo256/currency.c new file mode 100644 index 0000000..b79c036 --- /dev/null +++ b/spo256/currency.c @@ -0,0 +1,43 @@ +/* + * Currency rules, for USD. + * $Id: currency.c 1.2 Mon, 24 Mar 1997 12:25:37 -0500 dyfet $ + * Copyright (c) 1997 by Tycho Softworks. + * For conditions of distribution and reuse see product license. + */ + +#include +#include +#include "speak.h" + +void currency(char *str) +{ + char *cents; + ++str; + + cents = strchr(str, '.'); + if(cents) + *(cents++) = 0; + + if(atol(str) != 0) + { + number(str); + if(atol(str) > 1) + spo_word("dollars"); + else + spo_word("dollar"); + } + + if(cents) + { + if(atol(str) > 0) + spo_word("and"); + + number(cents); + if(atoi(cents) > 1) + spo_word("cent"); + else + spo_word("cents"); + } +} + + diff --git a/spo256/getidx.c b/spo256/getidx.c new file mode 100644 index 0000000..70a730c --- /dev/null +++ b/spo256/getidx.c @@ -0,0 +1,98 @@ +/* + * Build word and abbreviation index in memory from .conf. + * $Id: getidx.c 1.2 Mon, 24 Mar 1997 12:25:37 -0500 dyfet $ + * Copyright (c) 1997 by Tycho Softworks. + * For conditions of distribution and reuse see product license. + */ + +#include +#include +#include +#include +#include +#include "speak.h" + +MEMPOOL *mem; +IDX **widx, **aidx; + +static int key(uchar *str) +{ + unsigned int k = 0; + int len = strlen((char *)str); + + while(*str) + { + k = (k * 7) | (*str & 0x1f); + ++str; + } + + k |= len; + + return (k % KEYSIZE); +} + +void getidx(CONFIG *cfg) +{ + int i; + char *p, *q; + IDX *new; + + mem = mempool(16384, 16); + + widx = (IDX **)memreq(mem, sizeof(IDX *) * KEYSIZE); + aidx = (IDX **)memreq(mem, sizeof(IDX *) * KEYSIZE); + + + for(i = 0; i < KEYSIZE; ++i) + widx[i] = aidx[i] = NULL; + + seek_config(cfg, "words"); + while(NULL != (p = read_config(cfg))) + { + q = strchr(p, '='); + if(!q) + continue; + + *(q++) = 0; + p = strtrim(p, __SPACES); + q = strtrim(q, __SPACES); + i = key((uchar *)p); + new = memlreq(mem, sizeof(IDX)); + new->word_link = widx[i]; + widx[i] = new; + new->word_key = strreq(mem, p); + new->word_spo = strreq(mem, q); + } + seek_config(cfg, "abbrev"); + while(NULL != (p = read_config(cfg))) + { + q = strchr(p, '='); + if(!q) + continue; + + *(q++) = 0; + p = strtrim(p, __SPACES); + q = strtrim(q, __SPACES); + i = key((uchar *)p); + new = memlreq(mem, sizeof(IDX)); + new->word_link = aidx[i]; + aidx[i] = new; + new->word_key = strreq(mem, p); + new->word_spo = strreq(mem, q); + } +} + +char *find(IDX **table, char *str) +{ + IDX *next = table[key((uchar *)str)]; + + + while(next) + { + if(!stricmp(str, next->word_key)) + return next->word_spo; + + next = next->word_link; + } + return NULL; +} diff --git a/spo256/getspo.c b/spo256/getspo.c new file mode 100644 index 0000000..5ff64d7 --- /dev/null +++ b/spo256/getspo.c @@ -0,0 +1,68 @@ +/* + * Parse .conf file interface spec for spo communications. + * $Id: getspo.c 1.2 Mon, 24 Mar 1997 12:25:37 -0500 dyfet $ + * Copyright (c) 1997 by Tycho Softworks. + * For conditions of distribution and reuse see product license. + */ + +#include +#include +#include +#include +#include + +char *mask = NULL; + +int getspo(CONFIG *cfg) +{ + int spo = -1; + char *p; + stty_t stty; + + if(!seek_config(cfg, "interface")) + fatal(EX_CONFIG, "spo256: [interface]: missing from speak.conf\n"); + + while(NULL != read_config(cfg)) + { + if(NULL != (p = get_config(cfg, "bind"))) + { + mask = strdup(p); + continue; + } + + if(NULL != (p = get_config(cfg, "device"))) + { + spo = open(p, O_RDWR); + if(spo < 0) + fatal(EX_UNAVAILABLE, "spo256: %s: cannot access\n", p); + stty = getstty(spo); + interactive(stty, FALSE); + setflowctrl(stty, FC_HARD); + continue; + } + + if(NULL != (p = get_config(cfg, "speed"))) + { + if(spo < 0) + fatal(EX_CONFIG, "spo256: set speed for unspecified device\n"); + setspeed(stty, atol(p)); + continue; + } + + if(NULL != (p = get_config(cfg, "parity"))) + { + if(spo < 0) + fatal(EX_CONFIG, "spo256: set format for unspecified device\n"); + if(!stricmp(p, "even")) + setformat(stty, "7e1"); + if(!stricmp(p, "odd")) + setformat(stty, "7o1"); + if(!stricmp(p, "none")) + setformat(stty, "8n1"); + continue; + } + } + putstty(spo, stty, TRUE); + return spo; +} + diff --git a/spo256/number.c b/spo256/number.c new file mode 100644 index 0000000..16c662a --- /dev/null +++ b/spo256/number.c @@ -0,0 +1,132 @@ +/* + * Number base pronounciation rules and special cases. + * $Id: number.c 1.2 Mon, 24 Mar 1997 12:25:37 -0500 dyfet $ + * Copyright (c) 1997 by Tycho Softworks. + * For conditions of distribution and reuse see product license. + */ + +#include +#include +#include "speak.h" + +static char *nteen[] = { + "ten", "eleven", "twelve", "thirteen", "fourteen", + "fifteen", "sixteen", "seventeen", "eighteen", "nineteen"}; + +static char *n10[] = { + "zero", "ten", "twenty", "thirty", "fourty", + "fifty", "sixty", "seventy", "eighty", "ninety"}; + + +static void digits(long value) +{ + bool hundred = FALSE; + char buf[2]; + + if(value >= 100) + { + digits(value / 100); + spo_word("hundred"); + value %= 100; + hundred = TRUE; + } + + if(!value && hundred) + return; + + if(value >= 20) + { + spo_word(n10[value / 10]); + value %= 10; + if(!value) + return; + } + + if(value < 10) + { + buf[0] = value + '0'; + buf[1] = 0; + spo_word(buf); + return; + } + spo_word(nteen[value - 10]); +} + +void number(char *str) +{ + char *p; + long value = atol(str); + + if(lit || spell) + { + spo_word(str); + return; + } + + /* Check for w.x.y.z as "w dot x dot y dot z" */ + + if(ccount(str, ".") > 1) + { + while(NULL != (p = strchr(str, '.'))) + { + *(p++) = 0; + number(str); + str = p; + } + number(str); + return; + } + + if(NULL != (p = strchr(str, '.'))) + { + *(p++) = 0; + number(str); + spo_word("point"); + spo_word(p); + return; + } + + if(NULL != (p = strchr(str, ':'))) + { + digits(atol(str)); + ++p; + if(atol(p) < 10) + if(atol(p)) + write(spo, " O ", 2); + + if(atol(p)) + digits(atol(p)); + + if(NULL != (p = strchr(p, ':'))) + { + spo_word("and"); + digits(atol(++p)); + spo_word("seconds"); + } + else + { + p = str; + if(strchr(p, 'a') || strchr(p, 'A')) + write(spo, "A M ", 5); + if(strchr(p, 'p') || strchr(p, 'P')) + write(spo, "P M ", 5); + } + return; + } + + if(value >= 1000000l) + { + digits(value / 1000000l); + spo_word("million"); + value %= 1000000l; + } + + if(value >= 1000) + { + digits(value / 1000); + spo_word("thousand"); + value %= 1000; + } + + digits(value); +} diff --git a/spo256/speak.1 b/spo256/speak.1 new file mode 100644 index 0000000..8ceac59 --- /dev/null +++ b/spo256/speak.1 @@ -0,0 +1,46 @@ +.TH "speak" "1" "January 1997" "Speak 0.2" "Text-to-Speech" +.PP +.SH NAME +.PP +\fBspeak\fP - send output to text-to-speech service. +.PP +.SH SYNOPSIS +.PP +\fBspeak\fP [\fIhostname\fP] +.PP +.SH DESCRIPTION +.PP +The Text-to-speech package introduces a standard TCP/IP port service for +attaching text-to-speech resources to your network. These resources can +be used to monitor system status, provide verbal alarms, etc. This network +service may be accessed by telnetting to a machine running a "speak" server, +or by using the various application utilities, such as \fBspeak\fP. +.PP + +The \fBspeak\fP program will capture and redirect all standard input to the +network speech server, such as \fBspo256\fP, running either on the +local machine ("\fIlocalhost\fP"), or to the server running on the host +specified as a command line argument. \fBspeak\fP is normally used to +terminate a pipe, such as in "\fIcat filename | speak\fP". The TCP service +port used for the connection is specified in \fI/etc/services\fP. + +.PP +While most of the text-to-speech programs are separately written, the +\fBspeak\fP program is normally an alias for the actual server itself, +such as the \fBspo256\fP program. This was intentional, as future +versions of speak may drive hardware directly in an alternate usage +(such as "\fIspeak /dev/ttyxx\fP"), as well as redirecting output to a named +host. + +.PP +.SH SEE ALSO +.PP +.BR say (1), +.BR down (8), +.BR spo256 (8), +.BR services (7) +.PP +.SH AUTHOR +.PP +David Sugar (dyfet@tycho.com) +.PP diff --git a/spo256/speak.8 b/spo256/speak.8 new file mode 100644 index 0000000..aaeceef --- /dev/null +++ b/spo256/speak.8 @@ -0,0 +1,39 @@ +.TH "spo256" "8" "1997" "Text-to-Speech services" "Tycho Softworks" +.PP +.SH "NAME spo256 \- SPO256-AL2 Text-to-Speech Server" +.PP +.SH "SYNOPSIS" +.PP +\fBspo256\fP +.br +\fBspeak\fP [hostname] +.PP +.SH "DESCRIPTION" +.PP +.SH "FILES" +.PP +The spo256 server configuration may be found in \fB/etc/speak.conf\fP. +.PP +.SH "SEE ALSO" +.PP +.IP +.IP o +\fBdown(8)\fP: Shuts down the system. +.IP +.IP o +\fBsay(1)\fP: Sends output to a "speak" server. +.IP +.IP o +\fBservices(5)\fP: Installed TCP/IP network services. +.IP +.PP +.SH "DIAGNOSTICS" +.PP +\fBspo256\fP will warn and fail to load if the "speak" services entry +is missing, if the device cannot be opened, or if the speak.conf file +is missing. +.PP +.SH "AUTHOR" +.PP +David Sugar (dyfet@tycho.com) +.PP diff --git a/spo256/speak.c b/spo256/speak.c new file mode 100644 index 0000000..7de099f --- /dev/null +++ b/spo256/speak.c @@ -0,0 +1,86 @@ +/* + * Base (main) for spo server. + * $Id: speak.c 1.2 Mon, 24 Mar 1997 12:25:37 -0500 dyfet $ + * Copyright (c) 1997 by Tycho Softworks. + * For conditions of distribution and reuse see product license. + * + * Abstract: + * Establish basic operating environment for SPO256-AL2 text-to-speech + * server. This module verifies system configuration, parses the + * config files for word lists that are stored in the quick-lookup + * internal hash word subsitution database, binds the server to a tcp + * network port, and accepts client requests. + */ + +#include +#include +#include +#include +#include +#include +#include "speak.h" + +int spo; /* device id of spo */ +FILE *io; + +void main(int argc, char **argv) +{ + int port = getservice("speak"); + CONFIG *cfg; + SOCKET so; + char buf[1024]; + + if(!port) + fatal(EX_UNAVAILABLE, "spo256: speak: service not defined in /etc/services\n"); + + if(argc < 1 || argc > 2) + fatal(EX_USAGE, "use: spo256 [hostname]\n"); + + if(argc > 1) + client(argv[1], port); + + if(!stricmp(pathfname(argv[0]), "speak")) + client("localhost", port); + + if(NULL == (cfg = sys_config("speak"))) + fatal(EX_CONFIG, "spo256: speak.conf: config file missing\n"); + + /* get device configuration */ + + spo = getspo(cfg); + + getidx(cfg); + close_config(cfg); + + /* bind server to socket */ + + so = tcpsocket(mask, port, 5); + if(so == INVALID_SOCKET) + fatal(EX_UNAVAILABLE, "spo256: %d: failed to bind port\n", port); + + /* now, make ourselves a daemon */ + + pdetach(D_KEEPNONIO); + + /* Main loop of server. The server accepts one connection in + turn from each requesting user application. The remaining + application requests are kept in backlog while the current + application is served. This assures non-overlapping speech. + */ + + for(;;) + { + io = accepttcp(so); + if(!io) + continue; + + spo_init(); + puttcp("SPO256-AL2 Text-to-Speech Server 1.0\r\n", io); + + chars(io); + + spo_pause(P_END); + closetcp(io); + } +} + diff --git a/spo256/speak.conf.7 b/spo256/speak.conf.7 new file mode 100644 index 0000000..ccc3e57 --- /dev/null +++ b/spo256/speak.conf.7 @@ -0,0 +1,72 @@ +.TH "speak.conf" "7" "January 1997" "Speak 0.2" "Text-to-Speech" +.PP +.SH NAME +.PP +\fBspeak.conf\fP - configuration file for text-to-speech services. +.PP +.SH SYNOPSIS +.PP +\fBspeak.conf\fP +.PP +.SH DESCRIPTION +.PP +The \fBspeak.conf\fP file is a text edit-able configuration file used by the +text-to-speech server and various text-to-speech utilities. +.PP +\fBspeak.conf\fP is divided into sections, donated with "[]"'s. These +sections include hardware parameters for the text-to-speech server used on the +local machine, translation tables used for phonetic dictionaries by text-to- +speech servers, and runtime default information for specific programs. On +machines that do not run their own text-to-speech server, \fBspeak.conf\fP +will still be used to specify runtime defaults for utility programs that are +present. +.PP +.SH FILE FORMAT +.PP +The file consists of sections and parameters. A section begins with the +name of the section in square brackets and continues until the next section +begins. Sections contain parameters of the form \'name = value`'. +.PP +The file is line-based text - that is, each newline-terminated line +represents either a comment, a section name, or a parameter. Parameters +in the .conf file normally do not appear on multiple lines, except for +several specific exceptions (lists and tables) that are not used in this +package. +.PP +Section and parameter names are not case sensitive. +.PP +Only the first equal sign in a parameter is significant. Whitepsaces before +or after the = are ignored. Leading and trailing whitespaces are ignored. +Whitepaces within a parameter name are also ignored, while whitespaces +within a parameter value are preserved. +.PP +Any line beginning with a semicolon or a pound sign is treated as a comment +and is ignored. +.PP +Any line containing a list, in the form 'name = { v1 v2 v3 }' may be +continued over multiple lines if the terminating '}' is not found in the +current line. +.PP +Any line beginning with a plus is considered a repeat of the "name =" portion +of the last parameter line. This is often used to build up hostname lists +when multiple hostnames may be specified. +.PP +The parameter value may either be quoted or unquoted. Quoted parameters +values may be used to specify lead or trailing spaces which would otherwise +be ignored. Either matching single or double quotes may be used, and the +quotes are not kept as part of the value returned to the application. +.PP +Parameter values may either be strings, numeric values, or boolean flags. +When a boolean parameter is used, the characters "T" for 'true' and "F" for +'false' may be used. The full word, "true" and "false", may also be +spelled out. "Y" or "Yes" and "N" or "No" may also be used for "true" or +"false". +.PP +.SH SEE ALSO +.PP +.BR speak (1) +.PP +.SH AUTHOR +.PP +David Sugar (dyfet@tycho.com) +.PP diff --git a/spo256/speak.h b/spo256/speak.h new file mode 100644 index 0000000..07b9875 --- /dev/null +++ b/spo256/speak.h @@ -0,0 +1,48 @@ +/* + * Master header for spo server. + * $Id$ + * Copyright (c) 1997 by Tycho Softworks. + * For conditions of distribution and use see license. + * + * Abstract: + * Define internal hash index system to quickly find text for + * substitutions. The spo-256 is driven by substitution tables + * which provide alternate spellings to adjust mis-pronounced + * speech. + */ + +typedef enum +{ + P_END, /* Finish line off, send SPO-end mark */ + P_LINE, /* Send nl because we have a empty line */ + P_SENTANCE, /* Pause at end of sentance (nl) */ + P_WORD /* Inter-word delay (spaces) */ +} PAUSE; + +#define KEYSIZE 791 /* Size of internal hash database keyrange */ + +typedef struct _idx +{ + struct _idx *word_link; /* hash link chain */ + char *word_key; /* initial word & hash key */ + char *word_spo; /* substitute spelling */ +} IDX; + +extern int spo; +extern IDX **widx, **aidx; +extern char *mask; +extern FILE *io; +extern bool echo, spell, lit; + +void abbrev(char *str); +int getspo(CONFIG *cfg); +void getidx(CONFIG *cfg); +char *find(IDX **table, char *str); +void client(char *hostname, ushort port); + +void spo_init(void); +void spo_cmd(char *str); +void spo_word(char *str); +void spo_pause(PAUSE); +void spo_begquote(void); +void spo_endquote(void); diff --git a/spo256/speak.init b/spo256/speak.init new file mode 100644 index 0000000..0c46b8a --- /dev/null +++ b/spo256/speak.init @@ -0,0 +1,54 @@ +#!/bin/sh + +# modify FILESYSTEMS to activate and use vmon. +FILESYSTEMS="/" + +mode=$1 + +if [ $# = 0 ] ; then + mode='rc' +fi + +if [ ! "$mode" = 'rc' ] ; then + # Source function library. + . /etc/rc.d/init.d/functions + + # Source networking configuration. + . /etc/sysconfig/network + + # Check that networking is up. + [ ${NETWORKING} = "no" ] && exit 0 +fi + +# See how we were called. +case "$mode" in + rc) + echo "Starting SPO256-AL2 server" + spo256 + if [ ! -z "$FILESYSTEMS" ] ; then + vmon $FILESYSTEMS + fi + ;; + start) + echo -n "Starting SPO256-AL2 speech services: " + daemon spo256 + if [ ! -z "$FILESYSTEMS" ] ; then + daemon vmon $FILESYSTEMS + fi + echo + touch /var/lock/subsys/speak + ;; + stop) + echo -n "Shutting down SPO256-AL2 speech services: " + killproc spo256 + if [ ! -z "$FILESYSTEMS" ] ; then + killproc vmon + fi + rm -f /var/lock/subsys/speak + echo "" + ;; + *) + echo "Usage: speak.init {start|stop}" + exit 1 +esac + diff --git a/spo256/spo.c b/spo256/spo.c new file mode 100644 index 0000000..5c4f7ec --- /dev/null +++ b/spo256/spo.c @@ -0,0 +1,161 @@ +/* + * SPO256 low level operations. + * $Id: spo.c 1.2 Mon, 24 Mar 1997 12:25:37 -0500 dyfet $ + * Copyright (c) 1997 by Tycho Softworks. + * For conditions on distribution and reuse see product license. + * + * Abstract: + * Key SPO translation modules. This includes the word substution + * module, the numeric pronounciation system, pause control, and + * other low level spo services. + */ + +#include +#include +#include "speak.h" + +/* + * Flags and operating mode properties that may now be effected by + * server commands. + */ + +bool echo = FALSE; /* echo SPO output to user? */ +bool spell = FALSE; /* spell all words? */ +bool lit = FALSE; /* literally pronounce as is? */ + +/* + * A new 'init' function is added to initialize operating state for + * each new connection. This assures that spo command sequences + * issued from a previous session are not left in effect. + */ + +void spo_init(void) +{ + echo = FALSE; /* echo off by default */ + spell = FALSE; + lit = FALSE; +}; + +/* + * Interpret server specific commands embedded in + * sequences. The SPO has limited options to effect in this manner. + */ + +void spo_cmd(char *str) +{ + if(!stricmp(str, "echo")) + { + echo = TRUE; + return; + } + + if(!stricmp(str, "/echo")) + { + echo = FALSE; + return; + } + + if(!stricmp(str, "spell")) + { + spell = TRUE; + return; + } + + if(!stricmp(str, "/spell")) + { + spell = FALSE; + return; + } + + if(!stricmp(str, "lit")) + { + lit = TRUE; + return; + } + + if(!stricmp(str, "/lit")) + { + lit = FALSE; + return; + } +}; + +/* + * Pause spo output between words, numbers, and empty lines, so that + * words are properly announciated. This is typically accomplished with + * spaces and newline control. + */ + +void spo_pause(PAUSE p) +{ + switch(p) + { + case P_WORD: + write(spo, " ", 1); + if(echo) + puttcp(" ", io); + break; + case P_SENTANCE: + write(spo, " \n", 2); + if(echo) + puttcp(" \n", io); + break; + case P_LINE: + write(spo, " \r\n", 3); + if(echo) + puttcp(" \r\n", io); + break; + case P_END: + write(spo, "\r\n", 2); + } +} + +/* Announce quoted text. */ + +void spo_begquote(void) +{ + spo_word("quote"); +} + +void spo_endquote(void) +{ + spo_word("end"); + spo_begquote(); +} + +/* + * This performs low level lookup and pronounciation of words, either + * in the originally submitted spelling, or in the spo dictionary + * spelling. + */ + +void spo_word(char *word) +{ + char *p = find(widx, word); + if(!p) + p = word; + + if(lit) + p = word; + + if(spell) + { + p = word; + while(*p) + { + write(spo, p, 1); + if(echo) + fputc(*p, io); + spo_pause(P_WORD); + ++p; + } + } + else + { + write(spo, p, strlen(p)); + if(echo) + puttcp(p, io); + } + spo_pause(P_WORD); +} + diff --git a/spo256/spo256.8 b/spo256/spo256.8 new file mode 100644 index 0000000..a0826ad --- /dev/null +++ b/spo256/spo256.8 @@ -0,0 +1,98 @@ +.TH "spo256" "8" "January 1997" "Speak 0.2" "Text-to-Speech" +.PP +.SH NAME +.PP +\fBspo256\fP - text-to-speech server for SPO256-AL2 chipset. +.PP +.SH SYNOPSIS +.PP +\fBspo256\fP +.PP +.SH DESCRIPTION +.PP +The \fBspo256\fP server provides a TCP/IP service interface for controlling +a serial based SPO256-AL2 text-to-speech chip. The server binds to the +"\fIspeak\fP" port defined in /etc/services and attaches to the serial +tty device specified in the [\fIinterface\fP] section of \fBspeak.conf\fP. +The server accepts a single TCP session from a client application at a time, +streaming that client's text to the SPO device. The server corrects +pronunciation of words, numbers, and common usages by performing in-stream +text substitution before sending output to the SPO. +.PP +.SH INSTALLATION +.PP +The \fBspo256\fP server is meant to be started during system initialization +(usually for run level 3). A \fBspeak.init\fP script is installed into +/etc/rc.d, and this script will be linked to a numbered phase in the +/etc/rc3.d directory. This final linkage is now part of the 'make install' +supplied and should work for Linux, and perhaps other UNIX systems with +similar rc.d directory and file layouts. The \fBspo256\fP service can +normally start immediately after network services (\fIS10network\fP) have ran. +.PP +For BSD style systems, the speak.init script is installed as 'rc.speak'. For +systems that have different naming schemes for the rc.d scripts, some +additional work may be needed to correctly install speak.init. The +\fBspo256\fP server may also be ran directly from the command line For +testing, and the \fBspo256\fP command can simply be added to the +\fIrc.local\fP file. +.PP +The make install will add an entry to \fB/etc/services\fP for the TCP speak +port. By default, I normally use port 800. Since no effort has been made +to register text-to-speech as a defined Internet port service, it is quite +conceivable port 800 may at some point be defined for another service. If +this happens, simply edit the /etc/services file as needed. +.PP +The [\fIinterface\fP] section of \fB/etc/speak.conf\fP will need to be +edited before you start \fBspo256\fP for the first time. The entry for +\fIdevice\fP should be given the correct tty serial port where your SPO +board is attached. The speed I choose to use is 2400bps, which is the +maximum speed the board is capable of. Valid values for parity include +"odd", "even", and "none". Also verify board jumpers +are set for the speed and data format specified in [\fIinterface\fP]. +.PP +.SH "CORRECTIVE SPEECH" +.PP +The [\fIwords\fP] section of \fBspeak.conf\fP holds a list of text +substitutions. These substitutions correct the inability of the SPO to +correctly pronounce may words. Since the SPO provides no direct access +to the low-level phonetic dictionary, these substitute spellings may +appear odd. Sometimes, words are broken into multiple words with spaces, +such as "online", which is sent to the SPO as "on lyne". Basically, +through trial and error, one can build up a substitution table that works +for the device. +.PP +The [\fIabbrev\fP] section simply provides the meaning behind commonly +used abbreviations, so that they are spoken out correctly. Abbreviations +are presumed to terminate with a '.', such as "Dr.", "Mr.", and are +represented in a table separate from the text substitution table. +.PP +.SH SERVER COMMANDS +.PP +Server commands were introduced with the third release of the SPO256 +server. These commands are formed as "tags" which appear as part of the +output stream sent to the server. These tags are preceeded by the +character, and are held in <>'s (much like HTML tags). Server commands +that are supported by different speech servers may very widly to support +features such as volume level, tone, inflection, etc. The limited set +of commands supported by the SPO server are as follows: +.PP +The <\fIecho\fP> and <\fI/echo\fP> tags may be used to turn echo on and +off. When echo is enabled, the output that is actually sent to the SPO +device (including corrected spellings) is also echo'd back to the client +that is connected to the server. +.PP +The <\fIspell\fP> and <\fI/spell\fP> tags may be used to turn spelling of +words on and off. In spelling mode, each letter of each word is spoken. +This should not be confused with <\fIlit\fP> and <\fI/lit\fP>, which are +used to disable the word lookup function so that text as actually sent +to the server is sent unprocessed to the SPO board. +.PP +.SH SEE ALSO +.PP +.BR speak.conf (7), +.BR services (7) +.PP +.SH AUTHOR +.PP +David Sugar (dyfet@tycho.com) +.PP diff --git a/spo256/word.c b/spo256/word.c new file mode 100644 index 0000000..2150837 --- /dev/null +++ b/spo256/word.c @@ -0,0 +1,38 @@ +/* + + Word base pronounciation rules and special cases. +*/ + +#include +#include +#include +#include +#include "speak.h" + +void word(char *str) +{ + char *p; + + /* Internet x@y as "x at y" */ + + if(NULL != (p = strchr(str, '@'))) + { + *(p++) = 0; + word(str); + word("at"); + word(p); + return; + } + + /* Check for x.y.z as "x dot y dot z" */ + + while(NULL != (p = strchr(str, '.'))) + { + *(p++) = 0; + spo_word(str); + spo_word("dot"); + str = p; + } + + spo_word(str); +} diff --git a/spo256/words.c b/spo256/words.c new file mode 100644 index 0000000..19c8d57 --- /dev/null +++ b/spo256/words.c @@ -0,0 +1,34 @@ +/* + + Each line of input from the client application is examined and split + into words, numbers, abbreviations, and special catagories for further + translation from free-form text to SPO spoken speech. Generally a + word is a collection of characters grouped by white-space markers + (nl, tab, and space). Special consideration is also given to quoting + properties. Additional rules may be applied once words have been + catagorized. +*/ + +#include +#include +#include +#include "speak.h" + +void abbrev(char *str) +{ + char *p; + + if(!lit && !spell) + p = find(aidx, str); + + if(p) + spo_word(p); + else + { + p = tail(str); + *(--p) = 0; + spo_word(str); + spo_pause(P_SENTANCE); + } +} + diff --git a/utils/Makefile.in b/utils/Makefile.in new file mode 100644 index 0000000..8ff750c --- /dev/null +++ b/utils/Makefile.in @@ -0,0 +1,31 @@ +# +# Template to build speak utilities. +# $Id: Makefile.in 1.2 Mon, 24 Mar 1997 12:25:37 -0500 dyfet $ +# Copyright (c) 1997 by Tycho Softworks. +# + +UPROGS = say +SPROGS = down vmon +PROGS = $(SPROGS) $(UPROGS) + +all: $(PROGS) + +install: $(PROGS) + install -s -g bin $(UPROGS) $(BINDIR) + install -s -g bin $(SPROGS) $(SBINDIR) + ln -sf $(SBINDIR)/vmon $(SBINDIR)/vstat + ../sdk/bin/instman $(MANDIR) 1 say + ../sdk/bin/instman $(MANDIR) 8 down vmon + +clean: + rm $(PROGS) + +say: say.c + $(CC) $(CFLAGS) $(OPTIMIZE) -I../sdk -L../sdk/lib -o $@ say.c $(LIBS) + +down: down.c + $(CC) $(CFLAGS) $(OPTIMIZE) -I../sdk -L../sdk/lib -o $@ down.c $(LIBS) + +vmon: vmon.c + $(CC) $(CFLAGS) $(OPTIMIZE) -I../sdk -L../sdk/lib -o $@ vmon.c $(LIBS) + diff --git a/utils/README b/utils/README new file mode 100644 index 0000000..66d3435 --- /dev/null +++ b/utils/README @@ -0,0 +1,9 @@ +This section includes portable 'speak' service based utilities. These +utilities are being ported from the original WorldVU SPO speak services. So +far, only "say", "down", and "vmon" have been ported. Additional +utilities to be added will include a new non-WorldVU related user session +announcement daemon, perhaps as part of vmon. The original user session +monitoring utility was closely tied into the WorldVU user cluster +monitoring system. + + diff --git a/utils/down.8 b/utils/down.8 new file mode 100644 index 0000000..fe0b81d --- /dev/null +++ b/utils/down.8 @@ -0,0 +1,44 @@ +.TH "down" "8" "January 1997" "Speak 0.2" "Text-to-Speech" +.PP +.SH NAME +.PP +\fBdown\fP - warn and then shutdown system. +.PP +.SH SYNOPSIS +.PP +\fBdown\fP [\fIseconds\fP] +.PP +.SH DESCRIPTION +.PP +The Text-to-speech package introduces a standard TCP/IP port service for +attaching text-to-speech resources to your network. These resources can +be used to monitor system status, provide verbal alarms, etc. This network +service may be accessed by telnetting to a machine running a "speak" server, +or by using the various application utilities, such as \fBdown\fP. +.PP + +The \fBdown\fP program will provide a warning with a countdown that may +be aborted. When the countdown reaches 0, your system will begin a normal +shutdown and reboot. The warning and countdown is shown on screen and +spoken over the text-to-speech interface. The \fBdown\fP program uses the +[\fIdown\fP] information in \fBspeak.conf\fP for default values. Only an +alternate countdown (in seconds) may be specified via a command line +argument. + +.PP +The [\fIdown\fP] section specifies a default timer to use, the hostname +where the speech server is running, and the program to execute to bring +the system down. If you are using \fBdown\fP on a machine that does not +have it's own text-to-speech server, then you will need to create a local +\fB/etc/speak.conf\fP file on that machine with at minimum a [\fIdown\fP] +section with an entry for the text-to-speech host server to use. + +.PP +.SH SEE ALSO +.PP +.BR speak.conf (7) +.PP +.SH AUTHOR +.PP +David Sugar (dyfet@tycho.com) +.PP diff --git a/utils/down.c b/utils/down.c new file mode 100644 index 0000000..66d9d19 --- /dev/null +++ b/utils/down.c @@ -0,0 +1,129 @@ +/* + * A verbal system shutdown utility. + * $Id: down.c 1.2 Mon, 24 Mar 1997 12:25:37 -0500 dyfet $ + * Copyright (c) 1997 by Tycho Softworks. + * For conditions of distribution and reuse see product license. + * + * Abstract: + * A verbal system shutdown utility. You may need to adjust the name + * of the shutdown program used. This gives some warning and then + * initiates the shutdown processing, unless cancelled in time. + */ + +#include +#include +#include +#include +#include +#include + +static char host[128] = "localhost"; +static char halt[60] = "/sbin/halt"; +static char abort_msg[] = "System shutdown overriden. Resuming normal operation.\n"; +static char down_msg[] = "%s system shutdown sequence initiated. You have %d seconds to override.\n"; +static int timer = 10; +static STREAM fp = NULL; + +/* + * If the user aborts the shutdown, then we send the cancellation message + * and gracefully exit the scene. + */ + +static void abort_sig() +{ + if(fp) + { + puttcp(abort_msg, fp); + closetcp(fp); + } + fputs("\n", stdout); + exit(-1); +} + +void main(int argc, char **argv) +{ + char *p; + char *reboot = halt; + int port = getservice("speak"); + CONFIG *cfg = sys_config("speak"); + char hostname[128]; + + if(argc < 1 || argc > 2) + fatal(EX_USAGE, "use: down [timer]\n"); + + if(!port) + fatal(EX_UNAVAILABLE, "down: speak: service unlisted in /etc/services\n"); + + if(!cfg) + fatal(EX_CONFIG, "down: speak.conf: config missing\n"); + + seek_config(cfg, "down"); + while(read_config(cfg)) + { + if(NULL != (p = get_config(cfg, "timer"))) + { + timer = atoi(p); + continue; + } + + if(NULL != (p = get_config(cfg, "halt"))) + { + strcpy(halt, p); + continue; + } + + if(NULL != (p = get_config(cfg, "host"))) + { + strcpy(host, p); + continue; + } + + if(NULL != (p = get_config(cfg, "server"))) + { + strcpy(host, p); + continue; + } + } + close_config(cfg); + if(argc > 1) + timer = atoi(argv[1]); + + fp = opentcp(host, port); + if(!fp) + fatal(EX_UNAVAILABLE, "down: %s: speak service unreachable\n", host); + + printf("System shutdown initiated...use to override; "); + fflush(stdout); + signal(SIGINT, abort_sig); + gettcp(hostname, 127, fp); + gethostname(hostname, 80); + fprintf(fp, down_msg, hostname, timer); + fflush(fp); + sleep(strlen(down_msg) / 9 + 1); + + /* count down timer until 0 */ + + while(timer) + { + printf("%d ", timer); + fflush(stdout); + fprintf(fp, "%d\n", timer); + fflush(fp); + sleep(1); + --timer; + } + + /* too late now!! */ + + signal(SIGINT, SIG_IGN); + printf("\n"); + closetcp(fp); + + /* detach return to user and execute reboot program */ + + pdetach(D_KEEPALL); + argv[0] = reboot; + argv[1] = NULL; + execvp(reboot, argv); +} + diff --git a/utils/say.1 b/utils/say.1 new file mode 100644 index 0000000..1807b76 --- /dev/null +++ b/utils/say.1 @@ -0,0 +1,35 @@ +.TH "say" "1" "January 1997" "Speak 0.2" "Text-to-Speech" +.PP +.SH NAME +.PP +\fBsay\fP - send output string to text-to-speech service. +.PP +.SH SYNOPSIS +.PP +\fBspeak\fP \fIhostname\fP "\fImessage\fP" +.PP +.SH DESCRIPTION +.PP +The Text-to-speech package introduces a standard TCP/IP port service for +attaching text-to-speech resources to your network. These resources can +be used to monitor system status, provide verbal alarms, etc. This network +service may be accessed by telnetting to a machine running a "speak" server, +or by using the various application utilities, such as \fBsay\fP. +.PP + +The \fBsay\fP program will send a specified string of text to a specified +network speech server. The intent is to use say to produce verbal output +much like the way "echo" may be used to create screen output. \fBsay\fP +will form a momentary connection with the speech server (such as +\fBspo256\fP), send the message, and then disconnect. The TCP +service port used for the connection is specified in \fI/etc/services\fP. + +.PP +.SH SEE ALSO +.PP +.BR speak (1) +.PP +.SH AUTHOR +.PP +David Sugar (dyfet@tycho.com) +.PP diff --git a/utils/say.c b/utils/say.c new file mode 100644 index 0000000..b774eaf --- /dev/null +++ b/utils/say.c @@ -0,0 +1,34 @@ +/* + * Send text to speech server. May be used in script files. + * $Id: say.c 1.2 Mon, 24 Mar 1997 12:25:37 -0500 dyfet $ + * Copyright (c) 1997 by Tycho Softworks. + * For conditions on distribution and reuse see product license. + */ + +#include +#include +#include + +void main(int argc, char **argv) +{ + STREAM fp; + int port = getservice("speak"); + char buf[128]; + + if(argc != 3) + fatal(EX_USAGE, "use: say host \"message\"\n"); + + if(!port) + fatal(EX_UNAVAILABLE, "say: speak: service not in /etc/services\n"); + + fp = opentcp(argv[1], port); + if(!fp) + fatal(EX_UNAVAILABLE, "say: %s: speak service unavailable\n", argv[1]); + + gettcp(buf, 127, fp); + puttcp(argv[2], fp); + puttcp("\n", fp); + closetcp(fp); +} + + diff --git a/utils/vmon.8 b/utils/vmon.8 new file mode 100644 index 0000000..84a1308 --- /dev/null +++ b/utils/vmon.8 @@ -0,0 +1,65 @@ +.TH "vmon" "8" "January 1997" "Speak 0.2" "Text-to-Speech" +.PP +.SH NAME +.PP +\fBvmon\fP - monitor system status (town crier). +.PP +.SH SYNOPSIS +.PP +\fBvmon\fP \fIfilesystems\fP +.br +\fBvstat\fP \fIfilesystems\fP +.PP +.SH DESCRIPTION +.PP +The Text-to-speech package introduces a standard TCP/IP port service for +attaching text-to-speech resources to your network. These resources can +be used to monitor system status, provide verbal alarms, etc. This network +service may be accessed by telnetting to a machine running a "speak" server, +or by using the various application utilities, such as \fBvmon\fP. +.PP + +The \fBvmon\fP program will monitor the specified list of file systems. +If any of these file systems exceed a maximum "quota" (such as over 90% +capacity in blocks or i-node use), then the monitor will send verbal +alerts every 5 minutes. This quota, and other parameters for vmon, may +be found in the [\fIvmon\fP] section of \fBspeak.conf\fP. +.PP + +The \fBvmon\fP program will also announce current system status once +every hour. This system status includes the total used capacity of +all file systems being monitored, how long the system has been up, and +how many users are currently logged in (excluding root). This hourly +announcement can be used to determine a given system is still alive. +.PP + +The \fBvmon\fP program will now also monitor specified user mailboxes +for new mail and announce when new mail arrives. The users to be +monitored are specified in the [\fIvmon\fP] section of \fBspeak.conf\fP. +Simply list mailbox= entries for each mailbox you wish to monitor. See +the example speak.conf included with the distribution. +.PP + +The \fBvmon\fP program can also be ran as \fBvstat\fP. When used as +\fBvstat\fP, the program performs an immediate system check, announces, +and then terminates. You can either use \fBvstat\fP from a crontab or +start \fBvmon\fP from \fBspeak.init\fP. You may also start \fBvmon\fP +from a \fBrc.local\fP file. Please check the \fBspeak.init\fP file +to add any file systems you wish to monitor. By default, the root +filesystem is enabled in \fBspeak.init\fP. +.PP + +A mute option may also be specified in the [\fIvmon\fP] section of +\fBspeak.conf\fP. This option mutes voice output during certain times of +the day. This is normally specified by 24 hour clock in hours, hence 18-7 +means to mute output anytime after 18' hours (6pm) and anytime before 7' +hours (7am). +.PP +.SH SEE ALSO +.PP +.BR speak.conf (7) +.PP +.SH AUTHOR +.PP +David Sugar (dyfet@tycho.com) +.PP diff --git a/utils/vmon.c b/utils/vmon.c new file mode 100644 index 0000000..e1015b4 --- /dev/null +++ b/utils/vmon.c @@ -0,0 +1,442 @@ +/* Verbal monitor system status. + * $Id: vmon.c 1.2 Mon, 24 Mar 1997 12:25:37 -0500 dyfet $ + * Copyright (c) 1997 by Tycho Softworks. + * For conditions on distribution and reuse see product license. + * + * Abstract: + * Monitor system status in background. This service is normally + * started with the speech server. It may also be ran as 'vstat' + * to perform immediate notification. + */ + +#include +#include +#include +#include +#include +#include + +/* For systems that use statfs! */ + +#ifdef __linux__ +#include +#define __statfs__ +#endif + +typedef struct _MAILBOX +{ + struct _MAILBOX *next; + time_t update; + ulong size; + char name[0]; +} MAILBOX; + +static int freq = 3600; +static int timer = 3600; +static int interval = 300; +static int iter; +static int orig_timer; +static int alert = 90; /* warn on 90% full */ +static char alertmsg[] = "emergency alert emergency alert \r\n"; +static char **fs; +static char host[128] = "localhost"; +static int mute[2] = {24, 0}; + +static char *vmailbox(MAILBOX *mbox) +{ + struct stat ino; + static char buf[80]; + + if(stat(mbox->name, &ino)) + return NULL; + + if(!ino.st_size) + { + mbox->size = 0; + return NULL; + } + + if(ino.st_size == mbox->size) + return NULL; + + if(mbox->size == -1) + { + mbox->size = ino.st_size; + return NULL; + } + + mbox->size = ino.st_size; + sprintf(buf, "User %s has new mail\n", mbox->name); + return buf; +} + +static void vmbox(MAILBOX *box, int port) +{ + STREAM fp = NULL; + char *p; + time_t now; + struct tm *dt; + char buf[128]; + + time(&now); + dt = localtime(&now); + if(dt->tm_hour > mute[0] || dt->tm_hour < mute[1]) + return; + + while(box) + { + p = vmailbox(box); + if(!p) + { + box = box->next; + continue; + } + if(!fp) + { + fp = opentcp(host, port); + if(!fp) + return; + + gettcp(buf, sizeof(buf) - 1, fp); + } + puttcp(p, fp); + box = box->next; + } + if(fp) + closetcp(fp); +} + +static int vstat(int port) +{ + int i = 0; + char *f; + long btotal = 0; + long bfree = 0; + bool failed = FALSE; + STREAM fp = NULL; +#ifdef __statfs__ + struct statfs fnode; +#endif + int blocks, inodes; + char buf[128]; + int newtimer = orig_timer; + time_t now; + static prior = -1; + struct tm *dt; + int apm, hour; + char *apmstr[] = {" A M ", " P M "}; + int fd; + struct utmp *utmp, uptime; + int users = 0; + int utcnt = 0; + +#ifdef __statfs__ + while(fs[i]) + { + if(!statfs(fs[i], &fnode)) + { + btotal += fnode.f_blocks; + bfree += fnode.f_bfree; + blocks = 100 - (int)(fnode.f_ffree / (fnode.f_files / 100l)); + inodes = 100 - (int)(fnode.f_bfree / (fnode.f_blocks / 100l)); + if((blocks < alert) && (inodes < alert)) + { + ++i; + continue; + } + } + else + { + inodes = 0; + blocks = 0; + failed = TRUE; + } + if(!fp) + { + fp = opentcp(host, port); + if(!fp) + { + newtimer = 300; + break; + } + gettcp(buf, 128, fp); + puttcp(alertmsg, fp); + } + + if(blocks > alert) + fprintf(fp, "File system %s is %d percent full.\r\n", fs[i], blocks); + + if(inodes > alert) + fprintf(fp, "File system %s i-node table is %d percent full.\r\n", fs[i], inodes); + + if(failed) + fprintf(fp, "File system %s is dismounted or failed\r\n", fs[i]); + + fflush(fp); + newtimer = 60; + ++i; + } +#endif + + if(fp) + closetcp(fp); + + time(&now); + if(prior == (now / freq)) + return newtimer; + + if(prior == -1) + prior = now / freq - 1; + else + prior = now / freq; + + dt = localtime(&now); + hour = dt->tm_hour % 12; + if(dt->tm_hour > mute[0] || dt->tm_hour < mute[1]) + return newtimer; + + if(!hour) + hour = 12; + + if(dt->tm_hour > 11) + apm = 1; + else + apm = 0; + + fp = opentcp(host, port); + if(!fp) + return newtimer; + + gettcp(buf, 128, fp); + fprintf(fp, "It is %d:%d %s \r\n", hour, dt->tm_min, apmstr[apm]); + fflush(fp); + + fd = open("/proc/uptime", O_RDONLY); + hour = -1; + if(fd > -1) + { + read(fd, buf, 128); + close(fd); + hour = atol(buf) / 3600; + } + +#if defined(BOOT_TIME) || defined(RUN_LVL) + if(hour == -1) + { + utmp = NULL; + memset(&uptime, 0, sizeof(uptime)); +#ifdef BOOT_TIME + setutent(); + uptime.ut_type = BOOT_TIME; + utmp = getutid(&uptime); +#endif +#ifdef RUN_LVL + if(!utmp) + { + setutent(); + uptime.ut_type = RUN_LVL; + utmp = getutid(&uptime); + } +#endif + if(utmp) + hour = (now - utmp->ut_time) / 3600l; + + endutent(); + } +#endif + + if(hour > -1) + { + if(hour == 1) + fprintf(fp, "The system has been up 1 hour\r\n"); + else if(hour < 48) + fprintf(fp, "The system has been up %d hours\r\n", hour); + else + fprintf(fp, "The system has been up %d days\r\n", hour / 24); + fflush(fp); + } + + setutent(); + while(NULL != (utmp = getutent())) + { + ++utcnt; + +#ifdef USER_PROCESS + if(utmp->ut_type != USER_PROCESS) + continue; +#endif + + utmp->ut_user[sizeof(utmp->ut_user)] = 0; + if(!strcmp(utmp->ut_user, "root")) + continue; + + if(!utmp->ut_user[0]) + continue; + + if(!utmp->ut_line[0]) + continue; + +#ifdef USER_PROCESS + if(kill(utmp->ut_pid, 0)) + continue; +#endif + + ++users; + } + endutent(); + + if(utcnt) + { + if(!users) + fprintf(fp, "There are no users online\r\n"); + else if(users == 1) + fprintf(fp, "There is 1 user online\r\n"); + else + fprintf(fp, "There are %d users online\r\n", users); + fflush(fp); + } + + if(btotal) + { + fprintf(fp, "The main system drives are at %d percent of capacity\r\n", + 100 - (int)(bfree / (btotal / 100))); + fflush(fp); + } + + closetcp(fp); + return newtimer; +} + +void main(int argc, char **argv) +{ + int port = getservice("speak"); + char *maildir = getenv("MAILDIR"); + MAILBOX *mbox = NULL, *newbox; + char *prog = basename(*argv); + CONFIG *cfg = sys_config("speak"); + time_t now; + char *p; + + if(argc < 2) + fatal(EX_USAGE, "use %s filesystems...\n", prog); + + if(!maildir) + maildir = "/var/spool/mail"; + + fs = ++argv; + + if(!port) + fatal(EX_UNAVAILABLE, "%s: speak: service unavailable\n", prog); + + if(!cfg) + fatal(EX_UNAVAILABLE, "%s: speak.conf: missing\n", prog); + + seek_config(cfg, "vmon"); + while(read_config(cfg)) + { + if(NULL != (p = get_config(cfg, "mailbox"))) + { + p = strtok(p, __SPACES); + while(p) + { + newbox = (MAILBOX *)malloc(sizeof(MAILBOX) + strlen(p) + 1); + newbox->next = mbox; + time(&newbox->update); + newbox->size = -1l; + strcpy(newbox->name, p); + mbox = newbox; + p = strtok(NULL, __SPACES); + } + continue; + } + + if(NULL != (p = get_config(cfg, "interval"))) + { + interval = atoi(p) * 60; + continue; + } + + if(NULL != (p = get_config(cfg, "frequency"))) + { + timer = 3600 / atoi(p); + continue; + } + + if(NULL != (p = get_config(cfg, "server"))) + { + strcpy(host, p); + continue; + } + + if(NULL != (p = get_config(cfg, "host"))) + { + strcpy(host, p); + continue; + } + + if(NULL != (p = get_config(cfg, "alert"))) + { + alert = atoi(p); + continue; + } + + if(NULL != (p = get_config(cfg, "timer"))) + { + timer = atoi(p) * 60; + continue; + } + + if(NULL != (p = get_config(cfg, "mute"))) + { + mute[0] = atoi(p); + p = strchr(p, '-'); + if(p) + mute[1] = atoi(strtrim(++p, __SPACES)); + continue; + } + + if(NULL != (p = get_config(cfg, "maildir"))) + { + maildir = strdup(p); + continue; + } + + } + close_config(cfg); + + if(stricmp(prog, "vmon")) + { + vstat(port); + exit(0); + } + + pdetach(D_KEEPNONE); + + chdir(maildir); + freq = timer; + orig_timer = timer; + time(&now); + for(;;) + { + timer = vstat(port); + iter = interval; + for(;;) + { + vmbox(mbox, port); + sleep(iter); + time(&now); + iter = timer - (now % timer) - 1; + + if(iter > interval) + iter = interval; + + if(iter < 2) + { + sleep(iter + 2); + break; + } + } + } +} + + -- cgit v1.2.3-54-g00ecf