This commit was manufactured by cvs2svn to create branch 'rtems-4-6-branch'.

Sprout from master 2003-02-11 23:44:41 UTC Joel Sherrill <joel.sherrill@OARcorp.com> '2003-02-11	Joel Sherrill <joel@OARcorp.com>'
Cherrypick from rtemsdoc-4-5-branch 1997-05-27 12:40:10 UTC Joel Sherrill <joel.sherrill@OARcorp.com> 'base RTEMS documentation':
    doc/common/treedef.tex
Delete:
    bootstrap
    c/src/ada/.cvsignore
    c/src/ada/ChangeLog
    c/src/ada/Makefile.am
    c/src/ada/rtems-multiprocessing.adb
    c/src/ada/rtems-multiprocessing.ads
    c/src/ada/rtems.adb
    c/src/ada/rtems.ads
    c/src/lib/libcpu/powerpc/new-exceptions/ChangeLog
    c/src/lib/libcpu/powerpc/new-exceptions/cpu.c
    c/src/lib/libcpu/powerpc/new-exceptions/cpu_asm.S
    c/src/lib/libcpu/powerpc/old-exceptions/ChangeLog
    c/src/lib/libcpu/powerpc/old-exceptions/README
    c/src/lib/libcpu/powerpc/old-exceptions/TODO
    c/src/lib/libcpu/powerpc/old-exceptions/cpu.c
    c/src/lib/libcpu/powerpc/old-exceptions/cpu_asm.S
    c/src/lib/libcpu/powerpc/old-exceptions/irq_stub.S
    c/src/lib/libcpu/powerpc/old-exceptions/ppccache.c
    c/src/lib/libcpu/powerpc/old-exceptions/rtems/score/ppc_offs.h
    c/src/libchip/shmdr/.cvsignore
    c/src/libchip/shmdr/README
    c/src/libchip/shmdr/addlq.c
    c/src/libchip/shmdr/cnvpkt.c
    c/src/libchip/shmdr/dump.c
    c/src/libchip/shmdr/fatal.c
    c/src/libchip/shmdr/getlq.c
    c/src/libchip/shmdr/getpkt.c
    c/src/libchip/shmdr/init.c
    c/src/libchip/shmdr/initlq.c
    c/src/libchip/shmdr/intr.c
    c/src/libchip/shmdr/mpci.h
    c/src/libchip/shmdr/mpisr.c
    c/src/libchip/shmdr/poll.c
    c/src/libchip/shmdr/receive.c
    c/src/libchip/shmdr/retpkt.c
    c/src/libchip/shmdr/send.c
    c/src/libchip/shmdr/setckvec.c
    c/src/libchip/shmdr/shm_driver.h
    cpukit/ftpd/Makefile.am
    cpukit/ftpd/ftpd.c
    cpukit/ftpd/ftpd.h
    cpukit/httpd/.cvsignore
    cpukit/httpd/Makefile.am
    cpukit/httpd/NOTES
    cpukit/httpd/asp.c
    cpukit/httpd/balloc.c
    cpukit/httpd/default.c
    cpukit/httpd/ej.h
    cpukit/httpd/ejIntrn.h
    cpukit/httpd/ejlex.c
    cpukit/httpd/ejparse.c
    cpukit/httpd/emfdb.c
    cpukit/httpd/emfdb.h
    cpukit/httpd/form.c
    cpukit/httpd/h.c
    cpukit/httpd/handler.c
    cpukit/httpd/license.txt
    cpukit/httpd/md5.h
    cpukit/httpd/md5c.c
    cpukit/httpd/mime.c
    cpukit/httpd/misc.c
    cpukit/httpd/ringq.c
    cpukit/httpd/rom.c
    cpukit/httpd/rtems_webserver.h
    cpukit/httpd/security.c
    cpukit/httpd/sock.c
    cpukit/httpd/socket.c
    cpukit/httpd/sym.c
    cpukit/httpd/uemf.c
    cpukit/httpd/uemf.h
    cpukit/httpd/um.c
    cpukit/httpd/um.h
    cpukit/httpd/url.c
    cpukit/httpd/value.c
    cpukit/httpd/wbase64.c
    cpukit/httpd/webcomp.c
    cpukit/httpd/webmain.c
    cpukit/httpd/webpage.c
    cpukit/httpd/webrom.c
    cpukit/httpd/webs.c
    cpukit/httpd/webs.h
    cpukit/httpd/websuemf.c
    cpukit/httpd/wsIntrn.h
    cpukit/libnetworking/netinet/in_cksum_arm.h
    cpukit/libnetworking/netinet/in_cksum_i386.h
    cpukit/libnetworking/netinet/in_cksum_m68k.h
    cpukit/libnetworking/netinet/in_cksum_powerpc.h
    cpukit/pppd/Makefile.am
    cpukit/pppd/README
    cpukit/pppd/STATUS
    cpukit/pppd/auth.c
    cpukit/pppd/cbcp.c
    cpukit/pppd/cbcp.h
    cpukit/pppd/ccp.c
    cpukit/pppd/ccp.h
    cpukit/pppd/chap.c
    cpukit/pppd/chap.h
    cpukit/pppd/chap_ms.c
    cpukit/pppd/chap_ms.h
    cpukit/pppd/chat.c
    cpukit/pppd/demand.c
    cpukit/pppd/example/Makefile-user
    cpukit/pppd/example/README
    cpukit/pppd/example/init.c
    cpukit/pppd/example/netconfig.h
    cpukit/pppd/example/ppp.conf
    cpukit/pppd/example/pppd.options
    cpukit/pppd/example/pppdapp.c
    cpukit/pppd/example/system.h
    cpukit/pppd/fsm.c
    cpukit/pppd/fsm.h
    cpukit/pppd/ipcp.c
    cpukit/pppd/ipcp.h
    cpukit/pppd/ipxcp.c
    cpukit/pppd/ipxcp.h
    cpukit/pppd/lcp.c
    cpukit/pppd/lcp.h
    cpukit/pppd/magic.c
    cpukit/pppd/magic.h
    cpukit/pppd/md4.c
    cpukit/pppd/md4.h
    cpukit/pppd/md5.c
    cpukit/pppd/md5.h
    cpukit/pppd/options.c
    cpukit/pppd/patchlevel.h
    cpukit/pppd/pathnames.h
    cpukit/pppd/pppd.8
    cpukit/pppd/pppd.h
    cpukit/pppd/rtemsdialer.h
    cpukit/pppd/rtemsmain.c
    cpukit/pppd/rtemspppd.c
    cpukit/pppd/rtemspppd.h
    cpukit/pppd/sys-rtems.c
    cpukit/pppd/upap.c
    cpukit/pppd/upap.h
    cpukit/pppd/utils.c
    cpukit/rtems/src/clocktodtoseconds.c
    cpukit/rtems/src/clocktodvalidate.c
    cpukit/score/cpu/arm/rtems/asm.h
    cpukit/score/cpu/c4x/rtems/asm.h
    cpukit/score/cpu/c4x/rtems/tic4x/c4xio.h
    cpukit/score/cpu/h8300/rtems/asm.h
    cpukit/score/cpu/i386/rtems/asm.h
    cpukit/score/cpu/m68k/rtems/asm.h
    cpukit/score/cpu/m68k/rtems/m68k/m68302.h
    cpukit/score/cpu/m68k/rtems/m68k/m68360.h
    cpukit/score/cpu/m68k/rtems/m68k/qsm.h
    cpukit/score/cpu/m68k/rtems/m68k/sim.h
    cpukit/score/cpu/mips/rtems/asm.h
    cpukit/score/cpu/mips/rtems/mips/idtcpu.h
    cpukit/score/cpu/mips/rtems/mips/iregdef.h
    cpukit/score/cpu/no_cpu/rtems/asm.h
    cpukit/score/cpu/or32/rtems/asm.h
    cpukit/score/cpu/powerpc/rtems/asm.h
    cpukit/score/cpu/sh/rtems/asm.h
    cpukit/score/cpu/sparc/rtems/asm.h
    cpukit/telnetd/Makefile.am
    cpukit/telnetd/README
    cpukit/telnetd/icmds.c
    cpukit/telnetd/pty.c
    cpukit/telnetd/pty.h
    cpukit/telnetd/telnetd.c
    cpukit/telnetd/telnetd.h
    cpukit/zlib/doc/rfc1950.txt
    cpukit/zlib/doc/rfc1951.txt
    cpukit/zlib/doc/rfc1952.txt
    testsuites/.cvsignore
    testsuites/ChangeLog
    testsuites/Makefile.am
    testsuites/PROBLEMS
    testsuites/README
    testsuites/configure.ac
    testsuites/itrontests/.cvsignore
    testsuites/itrontests/ChangeLog
    testsuites/itrontests/Makefile.am
    testsuites/itrontests/README
    testsuites/itrontests/configure.ac
    testsuites/itrontests/itronhello/.cvsignore
    testsuites/itrontests/itronhello/Makefile.am
    testsuites/itrontests/itronhello/init.c
    testsuites/itrontests/itronhello/itronhello.doc
    testsuites/itrontests/itronhello/itronhello.scn
    testsuites/itrontests/itronhello/system.h
    testsuites/itrontests/itronmbf01/.cvsignore
    testsuites/itrontests/itronmbf01/Makefile.am
    testsuites/itrontests/itronmbf01/init.c
    testsuites/itrontests/itronmbf01/itronmbf01.doc
    testsuites/itrontests/itronmbf01/itronmbf01.scn
    testsuites/itrontests/itronmbf01/system.h
    testsuites/itrontests/itronmbox01/.cvsignore
    testsuites/itrontests/itronmbox01/Makefile.am
    testsuites/itrontests/itronmbox01/init.c
    testsuites/itrontests/itronmbox01/itronmbox01.doc
    testsuites/itrontests/itronmbox01/itronmbox01.scn
    testsuites/itrontests/itronmbox01/system.h
    testsuites/itrontests/itronsem01/.cvsignore
    testsuites/itrontests/itronsem01/Makefile.am
    testsuites/itrontests/itronsem01/init.c
    testsuites/itrontests/itronsem01/itronsem01.doc
    testsuites/itrontests/itronsem01/itronsem01.scn
    testsuites/itrontests/itronsem01/system.h
    testsuites/itrontests/itrontask01/.cvsignore
    testsuites/itrontests/itrontask01/Makefile.am
    testsuites/itrontests/itrontask01/init.c
    testsuites/itrontests/itrontask01/itrontask01.doc
    testsuites/itrontests/itrontask01/itrontask01.scn
    testsuites/itrontests/itrontask01/system.h
    testsuites/itrontests/itrontask01/task1.c
    testsuites/itrontests/itrontask02/.cvsignore
    testsuites/itrontests/itrontask02/Makefile.am
    testsuites/itrontests/itrontask02/dormant.c
    testsuites/itrontests/itrontask02/init.c
    testsuites/itrontests/itrontask02/itrontask02.doc
    testsuites/itrontests/itrontask02/itrontask02.scn
    testsuites/itrontests/itrontask02/system.h
    testsuites/itrontests/itrontask03/.cvsignore
    testsuites/itrontests/itrontask03/Makefile.am
    testsuites/itrontests/itrontask03/init.c
    testsuites/itrontests/itrontask03/itrontask03.doc
    testsuites/itrontests/itrontask03/itrontask03.scn
    testsuites/itrontests/itrontask03/preempt.c
    testsuites/itrontests/itrontask03/system.h
    testsuites/itrontests/itrontask03/task1.c
    testsuites/itrontests/itrontask03/task2.c
    testsuites/itrontests/itrontask03/task3.c
    testsuites/itrontests/itrontask04/.cvsignore
    testsuites/itrontests/itrontask04/Makefile.am
    testsuites/itrontests/itrontask04/init.c
    testsuites/itrontests/itrontask04/itrontask04.doc
    testsuites/itrontests/itrontask04/itrontask04.scn
    testsuites/itrontests/itrontask04/system.h
    testsuites/itrontests/itrontask04/task1.c
    testsuites/itrontests/itrontask04/task2.c
    testsuites/itrontests/itrontask04/task3.c
    testsuites/itrontests/itrontests.am
    testsuites/itrontests/itrontime01/.cvsignore
    testsuites/itrontests/itrontime01/Makefile.am
    testsuites/itrontests/itrontime01/init.c
    testsuites/itrontests/itrontime01/itrontime01.doc
    testsuites/itrontests/itrontime01/itrontime01.scn
    testsuites/itrontests/itrontime01/system.h
    testsuites/libtests/.cvsignore
    testsuites/libtests/ChangeLog
    testsuites/libtests/Makefile.am
    testsuites/libtests/README
    testsuites/libtests/configure.ac
    testsuites/libtests/cpuuse/.cvsignore
    testsuites/libtests/cpuuse/Makefile.am
    testsuites/libtests/cpuuse/cpuuse.scn
    testsuites/libtests/cpuuse/init.c
    testsuites/libtests/cpuuse/system.h
    testsuites/libtests/cpuuse/task1.c
    testsuites/libtests/cpuuse/task2.c
    testsuites/libtests/cpuuse/task3.c
    testsuites/libtests/cpuuse/tswitch.c
    testsuites/libtests/libtests.am
    testsuites/libtests/malloctest/.cvsignore
    testsuites/libtests/malloctest/Makefile.am
    testsuites/libtests/malloctest/init.c
    testsuites/libtests/malloctest/malloctest.scn
    testsuites/libtests/malloctest/system.h
    testsuites/libtests/malloctest/task1.c
    testsuites/libtests/monitor/.cvsignore
    testsuites/libtests/monitor/Makefile.am
    testsuites/libtests/monitor/init.c
    testsuites/libtests/monitor/system.h
    testsuites/libtests/putenvtest/.cvsignore
    testsuites/libtests/putenvtest/Makefile.am
    testsuites/libtests/putenvtest/init.c
    testsuites/libtests/rtems++/.cvsignore
    testsuites/libtests/rtems++/Init.cc
    testsuites/libtests/rtems++/Makefile.am
    testsuites/libtests/rtems++/System.h
    testsuites/libtests/rtems++/Task1.cc
    testsuites/libtests/rtems++/Task2.cc
    testsuites/libtests/rtems++/Task3.cc
    testsuites/libtests/rtems++/rtems++.doc
    testsuites/libtests/rtems++/rtems++.scn
    testsuites/libtests/rtmonuse/.cvsignore
    testsuites/libtests/rtmonuse/Makefile.am
    testsuites/libtests/rtmonuse/getall.c
    testsuites/libtests/rtmonuse/init.c
    testsuites/libtests/rtmonuse/rtmonuse.scn
    testsuites/libtests/rtmonuse/system.h
    testsuites/libtests/rtmonuse/task1.c
    testsuites/libtests/stackchk/.cvsignore
    testsuites/libtests/stackchk/Makefile.am
    testsuites/libtests/stackchk/blow.c
    testsuites/libtests/stackchk/init.c
    testsuites/libtests/stackchk/stackchk.scn
    testsuites/libtests/stackchk/system.h
    testsuites/libtests/stackchk/task1.c
    testsuites/libtests/termios/.cvsignore
    testsuites/libtests/termios/Makefile.am
    testsuites/libtests/termios/README
    testsuites/libtests/termios/init.c
    testsuites/mptests/.cvsignore
    testsuites/mptests/ChangeLog
    testsuites/mptests/Makefile.am
    testsuites/mptests/README
    testsuites/mptests/configure.ac
    testsuites/mptests/mp01/.cvsignore
    testsuites/mptests/mp01/Makefile.am
    testsuites/mptests/mp01/init.c
    testsuites/mptests/mp01/node1/.cvsignore
    testsuites/mptests/mp01/node1/Makefile.am
    testsuites/mptests/mp01/node1/mp01.doc
    testsuites/mptests/mp01/node1/mp01.scn
    testsuites/mptests/mp01/node2/.cvsignore
    testsuites/mptests/mp01/node2/Makefile.am
    testsuites/mptests/mp01/node2/mp01.doc
    testsuites/mptests/mp01/node2/mp01.scn
    testsuites/mptests/mp01/system.h
    testsuites/mptests/mp01/task1.c
    testsuites/mptests/mp02/.cvsignore
    testsuites/mptests/mp02/Makefile.am
    testsuites/mptests/mp02/init.c
    testsuites/mptests/mp02/node1/.cvsignore
    testsuites/mptests/mp02/node1/Makefile.am
    testsuites/mptests/mp02/node1/mp02.doc
    testsuites/mptests/mp02/node1/mp02.scn
    testsuites/mptests/mp02/node2/.cvsignore
    testsuites/mptests/mp02/node2/Makefile.am
    testsuites/mptests/mp02/node2/mp02.doc
    testsuites/mptests/mp02/node2/mp02.scn
    testsuites/mptests/mp02/system.h
    testsuites/mptests/mp02/task1.c
    testsuites/mptests/mp03/.cvsignore
    testsuites/mptests/mp03/Makefile.am
    testsuites/mptests/mp03/delay.c
    testsuites/mptests/mp03/init.c
    testsuites/mptests/mp03/node1/.cvsignore
    testsuites/mptests/mp03/node1/Makefile.am
    testsuites/mptests/mp03/node1/mp03.doc
    testsuites/mptests/mp03/node1/mp03.scn
    testsuites/mptests/mp03/node2/.cvsignore
    testsuites/mptests/mp03/node2/Makefile.am
    testsuites/mptests/mp03/node2/mp03.doc
    testsuites/mptests/mp03/node2/mp03.scn
    testsuites/mptests/mp03/system.h
    testsuites/mptests/mp03/task1.c
    testsuites/mptests/mp04/.cvsignore
    testsuites/mptests/mp04/Makefile.am
    testsuites/mptests/mp04/init.c
    testsuites/mptests/mp04/node1/.cvsignore
    testsuites/mptests/mp04/node1/Makefile.am
    testsuites/mptests/mp04/node1/mp04.doc
    testsuites/mptests/mp04/node1/mp04.scn
    testsuites/mptests/mp04/node2/.cvsignore
    testsuites/mptests/mp04/node2/Makefile.am
    testsuites/mptests/mp04/node2/mp04.doc
    testsuites/mptests/mp04/node2/mp04.scn
    testsuites/mptests/mp04/system.h
    testsuites/mptests/mp04/task1.c
    testsuites/mptests/mp05/.cvsignore
    testsuites/mptests/mp05/Makefile.am
    testsuites/mptests/mp05/asr.c
    testsuites/mptests/mp05/init.c
    testsuites/mptests/mp05/node1/.cvsignore
    testsuites/mptests/mp05/node1/Makefile.am
    testsuites/mptests/mp05/node1/mp05.doc
    testsuites/mptests/mp05/node1/mp05.scn
    testsuites/mptests/mp05/node2/.cvsignore
    testsuites/mptests/mp05/node2/Makefile.am
    testsuites/mptests/mp05/node2/mp05.doc
    testsuites/mptests/mp05/node2/mp05.scn
    testsuites/mptests/mp05/system.h
    testsuites/mptests/mp05/task1.c
    testsuites/mptests/mp06/.cvsignore
    testsuites/mptests/mp06/Makefile.am
    testsuites/mptests/mp06/init.c
    testsuites/mptests/mp06/node1/.cvsignore
    testsuites/mptests/mp06/node1/Makefile.am
    testsuites/mptests/mp06/node1/mp06.doc
    testsuites/mptests/mp06/node1/mp06.scn
    testsuites/mptests/mp06/node2/.cvsignore
    testsuites/mptests/mp06/node2/Makefile.am
    testsuites/mptests/mp06/node2/mp06.doc
    testsuites/mptests/mp06/node2/mp06.scn
    testsuites/mptests/mp06/system.h
    testsuites/mptests/mp06/task1.c
    testsuites/mptests/mp07/.cvsignore
    testsuites/mptests/mp07/Makefile.am
    testsuites/mptests/mp07/init.c
    testsuites/mptests/mp07/node1/.cvsignore
    testsuites/mptests/mp07/node1/Makefile.am
    testsuites/mptests/mp07/node1/mp07.doc
    testsuites/mptests/mp07/node1/mp07.scn
    testsuites/mptests/mp07/node2/.cvsignore
    testsuites/mptests/mp07/node2/Makefile.am
    testsuites/mptests/mp07/node2/mp07.doc
    testsuites/mptests/mp07/node2/mp07.scn
    testsuites/mptests/mp07/system.h
    testsuites/mptests/mp07/task1.c
    testsuites/mptests/mp08/.cvsignore
    testsuites/mptests/mp08/Makefile.am
    testsuites/mptests/mp08/init.c
    testsuites/mptests/mp08/node1/.cvsignore
    testsuites/mptests/mp08/node1/Makefile.am
    testsuites/mptests/mp08/node1/mp08.doc
    testsuites/mptests/mp08/node1/mp08.scn
    testsuites/mptests/mp08/node2/.cvsignore
    testsuites/mptests/mp08/node2/Makefile.am
    testsuites/mptests/mp08/node2/mp08.doc
    testsuites/mptests/mp08/node2/mp08.scn
    testsuites/mptests/mp08/system.h
    testsuites/mptests/mp08/task1.c
    testsuites/mptests/mp09/.cvsignore
    testsuites/mptests/mp09/Makefile.am
    testsuites/mptests/mp09/init.c
    testsuites/mptests/mp09/node1/.cvsignore
    testsuites/mptests/mp09/node1/Makefile.am
    testsuites/mptests/mp09/node1/mp09.doc
    testsuites/mptests/mp09/node1/mp09.scn
    testsuites/mptests/mp09/node2/.cvsignore
    testsuites/mptests/mp09/node2/Makefile.am
    testsuites/mptests/mp09/node2/mp09.doc
    testsuites/mptests/mp09/node2/mp09.scn
    testsuites/mptests/mp09/recvmsg.c
    testsuites/mptests/mp09/sendmsg.c
    testsuites/mptests/mp09/system.h
    testsuites/mptests/mp09/task1.c
    testsuites/mptests/mp10/.cvsignore
    testsuites/mptests/mp10/Makefile.am
    testsuites/mptests/mp10/init.c
    testsuites/mptests/mp10/node1/.cvsignore
    testsuites/mptests/mp10/node1/Makefile.am
    testsuites/mptests/mp10/node1/mp10.doc
    testsuites/mptests/mp10/node1/mp10.scn
    testsuites/mptests/mp10/node2/.cvsignore
    testsuites/mptests/mp10/node2/Makefile.am
    testsuites/mptests/mp10/node2/mp10.doc
    testsuites/mptests/mp10/node2/mp10.scn
    testsuites/mptests/mp10/system.h
    testsuites/mptests/mp10/task1.c
    testsuites/mptests/mp10/task2.c
    testsuites/mptests/mp10/task3.c
    testsuites/mptests/mp11/.cvsignore
    testsuites/mptests/mp11/Makefile.am
    testsuites/mptests/mp11/init.c
    testsuites/mptests/mp11/node1/.cvsignore
    testsuites/mptests/mp11/node1/Makefile.am
    testsuites/mptests/mp11/node1/mp11.doc
    testsuites/mptests/mp11/node1/mp11.scn
    testsuites/mptests/mp11/node2/.cvsignore
    testsuites/mptests/mp11/node2/Makefile.am
    testsuites/mptests/mp11/node2/mp11.doc
    testsuites/mptests/mp11/node2/mp11.scn
    testsuites/mptests/mp11/system.h
    testsuites/mptests/mp12/.cvsignore
    testsuites/mptests/mp12/Makefile.am
    testsuites/mptests/mp12/init.c
    testsuites/mptests/mp12/node1/.cvsignore
    testsuites/mptests/mp12/node1/Makefile.am
    testsuites/mptests/mp12/node1/mp12.doc
    testsuites/mptests/mp12/node1/mp12.scn
    testsuites/mptests/mp12/node2/.cvsignore
    testsuites/mptests/mp12/node2/Makefile.am
    testsuites/mptests/mp12/node2/mp12.doc
    testsuites/mptests/mp12/node2/mp12.scn
    testsuites/mptests/mp12/system.h
    testsuites/mptests/mp13/.cvsignore
    testsuites/mptests/mp13/Makefile.am
    testsuites/mptests/mp13/init.c
    testsuites/mptests/mp13/node1/.cvsignore
    testsuites/mptests/mp13/node1/Makefile.am
    testsuites/mptests/mp13/node1/mp13.doc
    testsuites/mptests/mp13/node1/mp13.scn
    testsuites/mptests/mp13/node2/.cvsignore
    testsuites/mptests/mp13/node2/Makefile.am
    testsuites/mptests/mp13/node2/mp13.doc
    testsuites/mptests/mp13/node2/mp13.scn
    testsuites/mptests/mp13/system.h
    testsuites/mptests/mp13/task1.c
    testsuites/mptests/mp13/task2.c
    testsuites/mptests/mp14/.cvsignore
    testsuites/mptests/mp14/Makefile.am
    testsuites/mptests/mp14/delay.c
    testsuites/mptests/mp14/evtask1.c
    testsuites/mptests/mp14/evtmtask.c
    testsuites/mptests/mp14/exit.c
    testsuites/mptests/mp14/init.c
    testsuites/mptests/mp14/msgtask1.c
    testsuites/mptests/mp14/node1/.cvsignore
    testsuites/mptests/mp14/node1/Makefile.am
    testsuites/mptests/mp14/node1/mp14.doc
    testsuites/mptests/mp14/node1/mp14.scn
    testsuites/mptests/mp14/node2/.cvsignore
    testsuites/mptests/mp14/node2/Makefile.am
    testsuites/mptests/mp14/node2/mp14.doc
    testsuites/mptests/mp14/node2/mp14.scn
    testsuites/mptests/mp14/pttask1.c
    testsuites/mptests/mp14/smtask1.c
    testsuites/mptests/mp14/system.h
    testsuites/mptests/mptests.am
    testsuites/psxtests/.cvsignore
    testsuites/psxtests/ChangeLog
    testsuites/psxtests/Makefile.am
    testsuites/psxtests/configure.ac
    testsuites/psxtests/include/.cvsignore
    testsuites/psxtests/include/Makefile.am
    testsuites/psxtests/include/pmacros.h
    testsuites/psxtests/psx01/.cvsignore
    testsuites/psxtests/psx01/Makefile.am
    testsuites/psxtests/psx01/init.c
    testsuites/psxtests/psx01/psx01.scn
    testsuites/psxtests/psx01/system.h
    testsuites/psxtests/psx01/task.c
    testsuites/psxtests/psx02/.cvsignore
    testsuites/psxtests/psx02/Makefile.am
    testsuites/psxtests/psx02/init.c
    testsuites/psxtests/psx02/psx02.scn
    testsuites/psxtests/psx02/system.h
    testsuites/psxtests/psx02/task.c
    testsuites/psxtests/psx03/.cvsignore
    testsuites/psxtests/psx03/Makefile.am
    testsuites/psxtests/psx03/init.c
    testsuites/psxtests/psx03/psx03.scn
    testsuites/psxtests/psx03/system.h
    testsuites/psxtests/psx03/task.c
    testsuites/psxtests/psx04/.cvsignore
    testsuites/psxtests/psx04/Makefile.am
    testsuites/psxtests/psx04/init.c
    testsuites/psxtests/psx04/psx04.scn
    testsuites/psxtests/psx04/system.h
    testsuites/psxtests/psx04/task1.c
    testsuites/psxtests/psx04/task2.c
    testsuites/psxtests/psx04/task3.c
    testsuites/psxtests/psx05/.cvsignore
    testsuites/psxtests/psx05/Makefile.am
    testsuites/psxtests/psx05/init.c
    testsuites/psxtests/psx05/psx05.scn
    testsuites/psxtests/psx05/system.h
    testsuites/psxtests/psx05/task.c
    testsuites/psxtests/psx05/task2.c
    testsuites/psxtests/psx05/task3.c
    testsuites/psxtests/psx06/.cvsignore
    testsuites/psxtests/psx06/Makefile.am
    testsuites/psxtests/psx06/init.c
    testsuites/psxtests/psx06/psx06.scn
    testsuites/psxtests/psx06/system.h
    testsuites/psxtests/psx06/task.c
    testsuites/psxtests/psx06/task2.c
    testsuites/psxtests/psx07/.cvsignore
    testsuites/psxtests/psx07/Makefile.am
    testsuites/psxtests/psx07/init.c
    testsuites/psxtests/psx07/psx07.scn
    testsuites/psxtests/psx07/system.h
    testsuites/psxtests/psx07/task.c
    testsuites/psxtests/psx08/.cvsignore
    testsuites/psxtests/psx08/Makefile.am
    testsuites/psxtests/psx08/init.c
    testsuites/psxtests/psx08/psx08.scn
    testsuites/psxtests/psx08/system.h
    testsuites/psxtests/psx08/task1.c
    testsuites/psxtests/psx08/task2.c
    testsuites/psxtests/psx08/task3.c
    testsuites/psxtests/psx09/.cvsignore
    testsuites/psxtests/psx09/Makefile.am
    testsuites/psxtests/psx09/init.c
    testsuites/psxtests/psx09/psx09.scn
    testsuites/psxtests/psx09/system.h
    testsuites/psxtests/psx10/.cvsignore
    testsuites/psxtests/psx10/Makefile.am
    testsuites/psxtests/psx10/init.c
    testsuites/psxtests/psx10/psx10.scn
    testsuites/psxtests/psx10/system.h
    testsuites/psxtests/psx10/task.c
    testsuites/psxtests/psx10/task2.c
    testsuites/psxtests/psx10/task3.c
    testsuites/psxtests/psx11/.cvsignore
    testsuites/psxtests/psx11/Makefile.am
    testsuites/psxtests/psx11/init.c
    testsuites/psxtests/psx11/psx11.scn
    testsuites/psxtests/psx11/system.h
    testsuites/psxtests/psx11/task.c
    testsuites/psxtests/psx12/.cvsignore
    testsuites/psxtests/psx12/Makefile.am
    testsuites/psxtests/psx12/init.c
    testsuites/psxtests/psx12/psx12.scn
    testsuites/psxtests/psx12/system.h
    testsuites/psxtests/psx12/task.c
    testsuites/psxtests/psx13/.cvsignore
    testsuites/psxtests/psx13/Makefile.am
    testsuites/psxtests/psx13/main.c
    testsuites/psxtests/psx13/psx13.scn
    testsuites/psxtests/psx13/test.c
    testsuites/psxtests/psxcancel/.cvsignore
    testsuites/psxtests/psxcancel/Makefile.am
    testsuites/psxtests/psxcancel/init.c
    testsuites/psxtests/psxcancel/psxcancel.scn
    testsuites/psxtests/psxchroot01/.cvsignore
    testsuites/psxtests/psxchroot01/Makefile.am
    testsuites/psxtests/psxchroot01/main.c
    testsuites/psxtests/psxchroot01/psxchroot01.scn
    testsuites/psxtests/psxchroot01/test.c
    testsuites/psxtests/psxfile01/.cvsignore
    testsuites/psxtests/psxfile01/Makefile.am
    testsuites/psxtests/psxfile01/main.c
    testsuites/psxtests/psxfile01/psxfile01.scn
    testsuites/psxtests/psxfile01/test.c
    testsuites/psxtests/psxfile01/test_cat.c
    testsuites/psxtests/psxfile01/test_extend.c
    testsuites/psxtests/psxfile01/test_write.c
    testsuites/psxtests/psxhdrs/.cvsignore
    testsuites/psxtests/psxhdrs/Makefile.am
    testsuites/psxtests/psxhdrs/clock01.c
    testsuites/psxtests/psxhdrs/clock02.c
    testsuites/psxtests/psxhdrs/clock03.c
    testsuites/psxtests/psxhdrs/clock04.c
    testsuites/psxtests/psxhdrs/clock05.c
    testsuites/psxtests/psxhdrs/clock06.c
    testsuites/psxtests/psxhdrs/cond01.c
    testsuites/psxtests/psxhdrs/cond02.c
    testsuites/psxtests/psxhdrs/cond03.c
    testsuites/psxtests/psxhdrs/cond04.c
    testsuites/psxtests/psxhdrs/cond05.c
    testsuites/psxtests/psxhdrs/cond06.c
    testsuites/psxtests/psxhdrs/cond07.c
    testsuites/psxtests/psxhdrs/cond08.c
    testsuites/psxtests/psxhdrs/cond09.c
    testsuites/psxtests/psxhdrs/cond10.c
    testsuites/psxtests/psxhdrs/key01.c
    testsuites/psxtests/psxhdrs/key02.c
    testsuites/psxtests/psxhdrs/key03.c
    testsuites/psxtests/psxhdrs/key04.c
    testsuites/psxtests/psxhdrs/mutex01.c
    testsuites/psxtests/psxhdrs/mutex02.c
    testsuites/psxtests/psxhdrs/mutex03.c
    testsuites/psxtests/psxhdrs/mutex04.c
    testsuites/psxtests/psxhdrs/mutex05.c
    testsuites/psxtests/psxhdrs/mutex06.c
    testsuites/psxtests/psxhdrs/mutex07.c
    testsuites/psxtests/psxhdrs/mutex08.c
    testsuites/psxtests/psxhdrs/mutex09.c
    testsuites/psxtests/psxhdrs/mutex10.c
    testsuites/psxtests/psxhdrs/mutex11.c
    testsuites/psxtests/psxhdrs/mutex12.c
    testsuites/psxtests/psxhdrs/mutex13.c
    testsuites/psxtests/psxhdrs/mutex14.c
    testsuites/psxtests/psxhdrs/mutex15.c
    testsuites/psxtests/psxhdrs/mutex16.c
    testsuites/psxtests/psxhdrs/proc01.c
    testsuites/psxtests/psxhdrs/proc02.c
    testsuites/psxtests/psxhdrs/proc03.c
    testsuites/psxtests/psxhdrs/proc04.c
    testsuites/psxtests/psxhdrs/proc05.c
    testsuites/psxtests/psxhdrs/proc06.c
    testsuites/psxtests/psxhdrs/proc07.c
    testsuites/psxtests/psxhdrs/proc08.c
    testsuites/psxtests/psxhdrs/proc09.c
    testsuites/psxtests/psxhdrs/proc10.c
    testsuites/psxtests/psxhdrs/proc11.c
    testsuites/psxtests/psxhdrs/proc12.c
    testsuites/psxtests/psxhdrs/proc13.c
    testsuites/psxtests/psxhdrs/proc14.c
    testsuites/psxtests/psxhdrs/pthread01.c
    testsuites/psxtests/psxhdrs/pthread02.c
    testsuites/psxtests/psxhdrs/pthread03.c
    testsuites/psxtests/psxhdrs/pthread04.c
    testsuites/psxtests/psxhdrs/pthread05.c
    testsuites/psxtests/psxhdrs/pthread06.c
    testsuites/psxtests/psxhdrs/pthread07.c
    testsuites/psxtests/psxhdrs/pthread08.c
    testsuites/psxtests/psxhdrs/pthread09.c
    testsuites/psxtests/psxhdrs/pthread10.c
    testsuites/psxtests/psxhdrs/pthread11.c
    testsuites/psxtests/psxhdrs/pthread12.c
    testsuites/psxtests/psxhdrs/pthread13.c
    testsuites/psxtests/psxhdrs/pthread14.c
    testsuites/psxtests/psxhdrs/pthread15.c
    testsuites/psxtests/psxhdrs/pthread16.c
    testsuites/psxtests/psxhdrs/pthread17.c
    testsuites/psxtests/psxhdrs/pthread18.c
    testsuites/psxtests/psxhdrs/pthread19.c
    testsuites/psxtests/psxhdrs/pthread20.c
    testsuites/psxtests/psxhdrs/pthread21.c
    testsuites/psxtests/psxhdrs/pthread22.c
    testsuites/psxtests/psxhdrs/pthread23.c
    testsuites/psxtests/psxhdrs/pthread24.c
    testsuites/psxtests/psxhdrs/pthread25.c
    testsuites/psxtests/psxhdrs/pthread26.c
    testsuites/psxtests/psxhdrs/pthread27.c
    testsuites/psxtests/psxhdrs/pthread28.c
    testsuites/psxtests/psxhdrs/pthread29.c
    testsuites/psxtests/psxhdrs/pthread30.c
    testsuites/psxtests/psxhdrs/pthread31.c
    testsuites/psxtests/psxhdrs/pthread32.c
    testsuites/psxtests/psxhdrs/pthread33.c
    testsuites/psxtests/psxhdrs/pthread34.c
    testsuites/psxtests/psxhdrs/pthread35.c
    testsuites/psxtests/psxhdrs/pthread36.c
    testsuites/psxtests/psxhdrs/sched01.c
    testsuites/psxtests/psxhdrs/sched02.c
    testsuites/psxtests/psxhdrs/sched03.c
    testsuites/psxtests/psxhdrs/sched04.c
    testsuites/psxtests/psxhdrs/sched05.c
    testsuites/psxtests/psxhdrs/sched06.c
    testsuites/psxtests/psxhdrs/sched07.c
    testsuites/psxtests/psxhdrs/sched08.c
    testsuites/psxtests/psxhdrs/signal01.c
    testsuites/psxtests/psxhdrs/signal02.c
    testsuites/psxtests/psxhdrs/signal03.c
    testsuites/psxtests/psxhdrs/signal04.c
    testsuites/psxtests/psxhdrs/signal05.c
    testsuites/psxtests/psxhdrs/signal06.c
    testsuites/psxtests/psxhdrs/signal07.c
    testsuites/psxtests/psxhdrs/signal08.c
    testsuites/psxtests/psxhdrs/signal09.c
    testsuites/psxtests/psxhdrs/signal10.c
    testsuites/psxtests/psxhdrs/signal11.c
    testsuites/psxtests/psxhdrs/signal12.c
    testsuites/psxtests/psxhdrs/signal13.c
    testsuites/psxtests/psxhdrs/signal14.c
    testsuites/psxtests/psxhdrs/signal15.c
    testsuites/psxtests/psxhdrs/signal16.c
    testsuites/psxtests/psxhdrs/signal17.c
    testsuites/psxtests/psxhdrs/signal18.c
    testsuites/psxtests/psxhdrs/signal19.c
    testsuites/psxtests/psxhdrs/signal20.c
    testsuites/psxtests/psxhdrs/signal21.c
    testsuites/psxtests/psxhdrs/signal22.c
    testsuites/psxtests/psxhdrs/time01.c
    testsuites/psxtests/psxhdrs/time02.c
    testsuites/psxtests/psxhdrs/time03.c
    testsuites/psxtests/psxhdrs/time04.c
    testsuites/psxtests/psxhdrs/time05.c
    testsuites/psxtests/psxhdrs/time06.c
    testsuites/psxtests/psxhdrs/time07.c
    testsuites/psxtests/psxhdrs/time08.c
    testsuites/psxtests/psxhdrs/time09.c
    testsuites/psxtests/psxhdrs/time10.c
    testsuites/psxtests/psxhdrs/time11.c
    testsuites/psxtests/psxhdrs/time12.c
    testsuites/psxtests/psxhdrs/time13.c
    testsuites/psxtests/psxhdrs/timer01.c
    testsuites/psxtests/psxhdrs/timer02.c
    testsuites/psxtests/psxhdrs/timer03.c
    testsuites/psxtests/psxhdrs/timer04.c
    testsuites/psxtests/psxhdrs/timer05.c
    testsuites/psxtests/psxhdrs/timer06.c
    testsuites/psxtests/psxmount/.cvsignore
    testsuites/psxtests/psxmount/Makefile.am
    testsuites/psxtests/psxmount/main.c
    testsuites/psxtests/psxmount/psxmount.scn
    testsuites/psxtests/psxmount/test.c
    testsuites/psxtests/psxmsgq01/.cvsignore
    testsuites/psxtests/psxmsgq01/Makefile.am
    testsuites/psxtests/psxmsgq01/init.c
    testsuites/psxtests/psxmsgq01/psxmsgq01.scn
    testsuites/psxtests/psxmsgq01/system.h
    testsuites/psxtests/psxreaddir/.cvsignore
    testsuites/psxtests/psxreaddir/Makefile.am
    testsuites/psxtests/psxreaddir/main.c
    testsuites/psxtests/psxreaddir/psxreaddir.scn
    testsuites/psxtests/psxreaddir/test.c
    testsuites/psxtests/psxsem01/.cvsignore
    testsuites/psxtests/psxsem01/Makefile.am
    testsuites/psxtests/psxsem01/init.c
    testsuites/psxtests/psxsem01/psxsem01.scn
    testsuites/psxtests/psxsem01/system.h
    testsuites/psxtests/psxstat/.cvsignore
    testsuites/psxtests/psxstat/Makefile.am
    testsuites/psxtests/psxstat/main.c
    testsuites/psxtests/psxstat/psxstat.scn
    testsuites/psxtests/psxstat/test.c
    testsuites/psxtests/psxtests.am
    testsuites/psxtests/psxtime/.cvsignore
    testsuites/psxtests/psxtime/Makefile.am
    testsuites/psxtests/psxtime/main.c
    testsuites/psxtests/psxtime/psxtime.scn
    testsuites/psxtests/psxtime/test.c
    testsuites/psxtests/psxtimer/.cvsignore
    testsuites/psxtests/psxtimer/Makefile.am
    testsuites/psxtests/psxtimer/psxtimer.c
    testsuites/psxtests/psxtimer/psxtimer.scn
    testsuites/psxtests/psxtimer/system.h
    testsuites/samples/.cvsignore
    testsuites/samples/ChangeLog
    testsuites/samples/Makefile.am
    testsuites/samples/README
    testsuites/samples/base_mp/.cvsignore
    testsuites/samples/base_mp/Makefile.am
    testsuites/samples/base_mp/apptask.c
    testsuites/samples/base_mp/init.c
    testsuites/samples/base_mp/node1/.cvsignore
    testsuites/samples/base_mp/node1/Makefile.am
    testsuites/samples/base_mp/node1/base_mp.doc
    testsuites/samples/base_mp/node1/base_mp.scn
    testsuites/samples/base_mp/node2/.cvsignore
    testsuites/samples/base_mp/node2/Makefile.am
    testsuites/samples/base_mp/node2/base_mp.doc
    testsuites/samples/base_mp/node2/base_mp.scn
    testsuites/samples/base_mp/system.h
    testsuites/samples/base_sp/.cvsignore
    testsuites/samples/base_sp/Makefile.am
    testsuites/samples/base_sp/apptask.c
    testsuites/samples/base_sp/base_sp.doc
    testsuites/samples/base_sp/base_sp.scn
    testsuites/samples/base_sp/init.c
    testsuites/samples/base_sp/system.h
    testsuites/samples/cdtest/.cvsignore
    testsuites/samples/cdtest/Makefile.am
    testsuites/samples/cdtest/cdtest.scn
    testsuites/samples/cdtest/init.c
    testsuites/samples/cdtest/main.cc
    testsuites/samples/cdtest/system.h
    testsuites/samples/configure.ac
    testsuites/samples/hello/.cvsignore
    testsuites/samples/hello/Makefile.am
    testsuites/samples/hello/hello.doc
    testsuites/samples/hello/hello.scn
    testsuites/samples/hello/init.c
    testsuites/samples/hello/system.h
    testsuites/samples/loopback/.cvsignore
    testsuites/samples/loopback/Makefile.am
    testsuites/samples/loopback/README
    testsuites/samples/loopback/init.c
    testsuites/samples/loopback/loopback.scn
    testsuites/samples/minimum/.cvsignore
    testsuites/samples/minimum/Makefile.am
    testsuites/samples/minimum/init.c
    testsuites/samples/minimum/minimum.doc
    testsuites/samples/minimum/minimum.scn
    testsuites/samples/paranoia/.cvsignore
    testsuites/samples/paranoia/Makefile.am
    testsuites/samples/paranoia/init.c
    testsuites/samples/paranoia/paranoia.c
    testsuites/samples/paranoia/paranoia.doc
    testsuites/samples/paranoia/system.h
    testsuites/samples/sample.am
    testsuites/samples/ticker/.cvsignore
    testsuites/samples/ticker/Makefile.am
    testsuites/samples/ticker/init.c
    testsuites/samples/ticker/system.h
    testsuites/samples/ticker/tasks.c
    testsuites/samples/ticker/ticker.doc
    testsuites/samples/ticker/ticker.scn
    testsuites/samples/unlimited/.cvsignore
    testsuites/samples/unlimited/Makefile.am
    testsuites/samples/unlimited/init.c
    testsuites/samples/unlimited/system.h
    testsuites/samples/unlimited/test1.c
    testsuites/samples/unlimited/test2.c
    testsuites/samples/unlimited/test3.c
    testsuites/samples/unlimited/unlimited.doc
    testsuites/samples/unlimited/unlimited.scn
    testsuites/sptests/.cvsignore
    testsuites/sptests/ChangeLog
    testsuites/sptests/Makefile.am
    testsuites/sptests/README
    testsuites/sptests/configure.ac
    testsuites/sptests/sp01/.cvsignore
    testsuites/sptests/sp01/Makefile.am
    testsuites/sptests/sp01/init.c
    testsuites/sptests/sp01/sp01.doc
    testsuites/sptests/sp01/sp01.scn
    testsuites/sptests/sp01/system.h
    testsuites/sptests/sp01/task1.c
    testsuites/sptests/sp02/.cvsignore
    testsuites/sptests/sp02/Makefile.am
    testsuites/sptests/sp02/init.c
    testsuites/sptests/sp02/preempt.c
    testsuites/sptests/sp02/sp02.doc
    testsuites/sptests/sp02/sp02.scn
    testsuites/sptests/sp02/system.h
    testsuites/sptests/sp02/task1.c
    testsuites/sptests/sp02/task2.c
    testsuites/sptests/sp02/task3.c
    testsuites/sptests/sp03/.cvsignore
    testsuites/sptests/sp03/Makefile.am
    testsuites/sptests/sp03/init.c
    testsuites/sptests/sp03/sp03.doc
    testsuites/sptests/sp03/sp03.scn
    testsuites/sptests/sp03/system.h
    testsuites/sptests/sp03/task1.c
    testsuites/sptests/sp03/task2.c
    testsuites/sptests/sp04/.cvsignore
    testsuites/sptests/sp04/Makefile.am
    testsuites/sptests/sp04/init.c
    testsuites/sptests/sp04/sp04.doc
    testsuites/sptests/sp04/sp04.scn
    testsuites/sptests/sp04/system.h
    testsuites/sptests/sp04/task1.c
    testsuites/sptests/sp04/task2.c
    testsuites/sptests/sp04/task3.c
    testsuites/sptests/sp04/tswitch.c
    testsuites/sptests/sp05/.cvsignore
    testsuites/sptests/sp05/Makefile.am
    testsuites/sptests/sp05/init.c
    testsuites/sptests/sp05/sp05.doc
    testsuites/sptests/sp05/sp05.scn
    testsuites/sptests/sp05/system.h
    testsuites/sptests/sp05/task1.c
    testsuites/sptests/sp05/task2.c
    testsuites/sptests/sp05/task3.c
    testsuites/sptests/sp06/.cvsignore
    testsuites/sptests/sp06/Makefile.am
    testsuites/sptests/sp06/init.c
    testsuites/sptests/sp06/sp06.doc
    testsuites/sptests/sp06/sp06.scn
    testsuites/sptests/sp06/system.h
    testsuites/sptests/sp06/task1.c
    testsuites/sptests/sp06/task2.c
    testsuites/sptests/sp06/task3.c
    testsuites/sptests/sp07/.cvsignore
    testsuites/sptests/sp07/Makefile.am
    testsuites/sptests/sp07/init.c
    testsuites/sptests/sp07/sp07.doc
    testsuites/sptests/sp07/sp07.scn
    testsuites/sptests/sp07/system.h
    testsuites/sptests/sp07/task1.c
    testsuites/sptests/sp07/task2.c
    testsuites/sptests/sp07/task3.c
    testsuites/sptests/sp07/task4.c
    testsuites/sptests/sp07/taskexit.c
    testsuites/sptests/sp07/tcreate.c
    testsuites/sptests/sp07/tdelete.c
    testsuites/sptests/sp07/trestart.c
    testsuites/sptests/sp07/tstart.c
    testsuites/sptests/sp08/.cvsignore
    testsuites/sptests/sp08/Makefile.am
    testsuites/sptests/sp08/init.c
    testsuites/sptests/sp08/sp08.doc
    testsuites/sptests/sp08/sp08.scn
    testsuites/sptests/sp08/system.h
    testsuites/sptests/sp08/task1.c
    testsuites/sptests/sp09/.cvsignore
    testsuites/sptests/sp09/Makefile.am
    testsuites/sptests/sp09/delay.c
    testsuites/sptests/sp09/init.c
    testsuites/sptests/sp09/isr.c
    testsuites/sptests/sp09/screen01.c
    testsuites/sptests/sp09/screen02.c
    testsuites/sptests/sp09/screen03.c
    testsuites/sptests/sp09/screen04.c
    testsuites/sptests/sp09/screen05.c
    testsuites/sptests/sp09/screen06.c
    testsuites/sptests/sp09/screen07.c
    testsuites/sptests/sp09/screen08.c
    testsuites/sptests/sp09/screen09.c
    testsuites/sptests/sp09/screen10.c
    testsuites/sptests/sp09/screen11.c
    testsuites/sptests/sp09/screen12.c
    testsuites/sptests/sp09/screen13.c
    testsuites/sptests/sp09/screen14.c
    testsuites/sptests/sp09/sp09.doc
    testsuites/sptests/sp09/sp09.scn
    testsuites/sptests/sp09/system.h
    testsuites/sptests/sp09/task1.c
    testsuites/sptests/sp09/task2.c
    testsuites/sptests/sp09/task3.c
    testsuites/sptests/sp09/task4.c
    testsuites/sptests/sp11/.cvsignore
    testsuites/sptests/sp11/Makefile.am
    testsuites/sptests/sp11/init.c
    testsuites/sptests/sp11/sp11.doc
    testsuites/sptests/sp11/sp11.scn
    testsuites/sptests/sp11/system.h
    testsuites/sptests/sp11/task1.c
    testsuites/sptests/sp11/task2.c
    testsuites/sptests/sp11/timer.c
    testsuites/sptests/sp12/.cvsignore
    testsuites/sptests/sp12/Makefile.am
    testsuites/sptests/sp12/init.c
    testsuites/sptests/sp12/pridrv.c
    testsuites/sptests/sp12/pritask.c
    testsuites/sptests/sp12/sp12.doc
    testsuites/sptests/sp12/sp12.scn
    testsuites/sptests/sp12/system.h
    testsuites/sptests/sp12/task1.c
    testsuites/sptests/sp12/task2.c
    testsuites/sptests/sp12/task3.c
    testsuites/sptests/sp12/task4.c
    testsuites/sptests/sp12/task5.c
    testsuites/sptests/sp13/.cvsignore
    testsuites/sptests/sp13/Makefile.am
    testsuites/sptests/sp13/fillbuff.c
    testsuites/sptests/sp13/init.c
    testsuites/sptests/sp13/putbuff.c
    testsuites/sptests/sp13/sp13.doc
    testsuites/sptests/sp13/sp13.scn
    testsuites/sptests/sp13/system.h
    testsuites/sptests/sp13/task1.c
    testsuites/sptests/sp13/task2.c
    testsuites/sptests/sp13/task3.c
    testsuites/sptests/sp14/.cvsignore
    testsuites/sptests/sp14/Makefile.am
    testsuites/sptests/sp14/asr.c
    testsuites/sptests/sp14/init.c
    testsuites/sptests/sp14/sp14.doc
    testsuites/sptests/sp14/sp14.scn
    testsuites/sptests/sp14/system.h
    testsuites/sptests/sp14/task1.c
    testsuites/sptests/sp14/task2.c
    testsuites/sptests/sp15/.cvsignore
    testsuites/sptests/sp15/Makefile.am
    testsuites/sptests/sp15/init.c
    testsuites/sptests/sp15/sp15.doc
    testsuites/sptests/sp15/sp15.scn
    testsuites/sptests/sp15/system.h
    testsuites/sptests/sp15/task1.c
    testsuites/sptests/sp16/.cvsignore
    testsuites/sptests/sp16/Makefile.am
    testsuites/sptests/sp16/init.c
    testsuites/sptests/sp16/sp16.doc
    testsuites/sptests/sp16/sp16.scn
    testsuites/sptests/sp16/system.h
    testsuites/sptests/sp16/task1.c
    testsuites/sptests/sp16/task2.c
    testsuites/sptests/sp16/task3.c
    testsuites/sptests/sp16/task4.c
    testsuites/sptests/sp16/task5.c
    testsuites/sptests/sp17/.cvsignore
    testsuites/sptests/sp17/Makefile.am
    testsuites/sptests/sp17/asr.c
    testsuites/sptests/sp17/init.c
    testsuites/sptests/sp17/sp17.doc
    testsuites/sptests/sp17/sp17.scn
    testsuites/sptests/sp17/system.h
    testsuites/sptests/sp17/task1.c
    testsuites/sptests/sp17/task2.c
    testsuites/sptests/sp19/.cvsignore
    testsuites/sptests/sp19/Makefile.am
    testsuites/sptests/sp19/first.c
    testsuites/sptests/sp19/fptask.c
    testsuites/sptests/sp19/fptest.h
    testsuites/sptests/sp19/init.c
    testsuites/sptests/sp19/inttest.h
    testsuites/sptests/sp19/sp19.doc
    testsuites/sptests/sp19/sp19.scn
    testsuites/sptests/sp19/system.h
    testsuites/sptests/sp19/task1.c
    testsuites/sptests/sp20/.cvsignore
    testsuites/sptests/sp20/Makefile.am
    testsuites/sptests/sp20/getall.c
    testsuites/sptests/sp20/init.c
    testsuites/sptests/sp20/sp20.doc
    testsuites/sptests/sp20/sp20.scn
    testsuites/sptests/sp20/system.h
    testsuites/sptests/sp20/task1.c
    testsuites/sptests/sp21/.cvsignore
    testsuites/sptests/sp21/Makefile.am
    testsuites/sptests/sp21/init.c
    testsuites/sptests/sp21/sp21.doc
    testsuites/sptests/sp21/sp21.scn
    testsuites/sptests/sp21/system.h
    testsuites/sptests/sp21/task1.c
    testsuites/sptests/sp22/.cvsignore
    testsuites/sptests/sp22/Makefile.am
    testsuites/sptests/sp22/delay.c
    testsuites/sptests/sp22/init.c
    testsuites/sptests/sp22/prtime.c
    testsuites/sptests/sp22/sp22.doc
    testsuites/sptests/sp22/sp22.scn
    testsuites/sptests/sp22/system.h
    testsuites/sptests/sp22/task1.c
    testsuites/sptests/sp23/.cvsignore
    testsuites/sptests/sp23/Makefile.am
    testsuites/sptests/sp23/init.c
    testsuites/sptests/sp23/sp23.doc
    testsuites/sptests/sp23/sp23.scn
    testsuites/sptests/sp23/system.h
    testsuites/sptests/sp23/task1.c
    testsuites/sptests/sp24/.cvsignore
    testsuites/sptests/sp24/Makefile.am
    testsuites/sptests/sp24/init.c
    testsuites/sptests/sp24/resume.c
    testsuites/sptests/sp24/sp24.doc
    testsuites/sptests/sp24/sp24.scn
    testsuites/sptests/sp24/system.h
    testsuites/sptests/sp24/task1.c
    testsuites/sptests/sp25/.cvsignore
    testsuites/sptests/sp25/Makefile.am
    testsuites/sptests/sp25/init.c
    testsuites/sptests/sp25/sp25.doc
    testsuites/sptests/sp25/sp25.scn
    testsuites/sptests/sp25/system.h
    testsuites/sptests/sp25/task1.c
    testsuites/sptests/sp26/.cvsignore
    testsuites/sptests/sp26/Makefile.am
    testsuites/sptests/sp26/init.c
    testsuites/sptests/sp26/sp26.doc
    testsuites/sptests/sp26/sp26.scn
    testsuites/sptests/sp26/system.h
    testsuites/sptests/sp26/task1.c
    testsuites/sptests/sp27/.cvsignore
    testsuites/sptests/sp27/Makefile.am
    testsuites/sptests/sp27/init.c
    testsuites/sptests/sp27/sp27.doc
    testsuites/sptests/sp27/sp27.scn
    testsuites/sptests/sp28/.cvsignore
    testsuites/sptests/sp28/Makefile.am
    testsuites/sptests/sp28/init.c
    testsuites/sptests/sp28/sp28.doc
    testsuites/sptests/sp28/sp28.scn
    testsuites/sptests/sp29/.cvsignore
    testsuites/sptests/sp29/Makefile.am
    testsuites/sptests/sp29/init.c
    testsuites/sptests/sp29/sp29.doc
    testsuites/sptests/sp29/sp29.scn
    testsuites/sptests/sp30/.cvsignore
    testsuites/sptests/sp30/Makefile.am
    testsuites/sptests/sp30/init.c
    testsuites/sptests/sp30/resume.c
    testsuites/sptests/sp30/sp30.doc
    testsuites/sptests/sp30/sp30.scn
    testsuites/sptests/sp30/system.h
    testsuites/sptests/sp30/task1.c
    testsuites/sptests/sp31/.cvsignore
    testsuites/sptests/sp31/Makefile.am
    testsuites/sptests/sp31/delay.c
    testsuites/sptests/sp31/init.c
    testsuites/sptests/sp31/prtime.c
    testsuites/sptests/sp31/sp31.doc
    testsuites/sptests/sp31/sp31.scn
    testsuites/sptests/sp31/system.h
    testsuites/sptests/sp31/task1.c
    testsuites/sptests/sp32/.cvsignore
    testsuites/sptests/sp32/Makefile.am
    testsuites/sptests/sp32/init.c
    testsuites/sptests/sp32/sp32.scn
    testsuites/sptests/spfatal/.cvsignore
    testsuites/sptests/spfatal/Makefile.am
    testsuites/sptests/spfatal/README
    testsuites/sptests/spfatal/fatal.c
    testsuites/sptests/spfatal/init.c
    testsuites/sptests/spfatal/puterr.c
    testsuites/sptests/spfatal/spfatal.doc
    testsuites/sptests/spfatal/spfatal.scn
    testsuites/sptests/spfatal/system.h
    testsuites/sptests/spfatal/task1.c
    testsuites/sptests/spsize/.cvsignore
    testsuites/sptests/spsize/Makefile.am
    testsuites/sptests/spsize/getint.c
    testsuites/sptests/spsize/init.c
    testsuites/sptests/spsize/size.c
    testsuites/sptests/spsize/size.scn
    testsuites/sptests/spsize/system.h
    testsuites/sptests/sptests.am
    testsuites/support/.cvsignore
    testsuites/support/ChangeLog
    testsuites/support/Makefile.am
    testsuites/support/configure.ac
    testsuites/support/include/.cvsignore
    testsuites/support/include/buffer_test_io.h
    testsuites/support/include/tmacros.h
    testsuites/tmitrontests/.cvsignore
    testsuites/tmitrontests/ChangeLog
    testsuites/tmitrontests/Makefile.am
    testsuites/tmitrontests/README
    testsuites/tmitrontests/configure.ac
    testsuites/tmitrontests/include/.cvsignore
    testsuites/tmitrontests/include/Makefile.am
    testsuites/tmitrontests/include/timesys.h
    testsuites/tmitrontests/tmitronsem01/.cvsignore
    testsuites/tmitrontests/tmitronsem01/Makefile.am
    testsuites/tmitrontests/tmitronsem01/init.c
    testsuites/tmitrontests/tmitronsem01/system.h
    testsuites/tmitrontests/tmitronsem01/tmitronsem01.doc
    testsuites/tmitrontests/tmitrontests.am
    testsuites/tmtests/.cvsignore
    testsuites/tmtests/ChangeLog
    testsuites/tmtests/Makefile.am
    testsuites/tmtests/README
    testsuites/tmtests/configure.ac
    testsuites/tmtests/include/.cvsignore
    testsuites/tmtests/include/Makefile.am
    testsuites/tmtests/include/timesys.h
    testsuites/tmtests/tm01/.cvsignore
    testsuites/tmtests/tm01/Makefile.am
    testsuites/tmtests/tm01/system.h
    testsuites/tmtests/tm01/task1.c
    testsuites/tmtests/tm01/tm01.doc
    testsuites/tmtests/tm02/.cvsignore
    testsuites/tmtests/tm02/Makefile.am
    testsuites/tmtests/tm02/system.h
    testsuites/tmtests/tm02/task1.c
    testsuites/tmtests/tm02/tm02.doc
    testsuites/tmtests/tm03/.cvsignore
    testsuites/tmtests/tm03/Makefile.am
    testsuites/tmtests/tm03/system.h
    testsuites/tmtests/tm03/task1.c
    testsuites/tmtests/tm03/tm03.doc
    testsuites/tmtests/tm04/.cvsignore
    testsuites/tmtests/tm04/Makefile.am
    testsuites/tmtests/tm04/system.h
    testsuites/tmtests/tm04/task1.c
    testsuites/tmtests/tm04/tm04.doc
    testsuites/tmtests/tm05/.cvsignore
    testsuites/tmtests/tm05/Makefile.am
    testsuites/tmtests/tm05/system.h
    testsuites/tmtests/tm05/task1.c
    testsuites/tmtests/tm05/tm05.doc
    testsuites/tmtests/tm06/.cvsignore
    testsuites/tmtests/tm06/Makefile.am
    testsuites/tmtests/tm06/system.h
    testsuites/tmtests/tm06/task1.c
    testsuites/tmtests/tm06/tm06.doc
    testsuites/tmtests/tm07/.cvsignore
    testsuites/tmtests/tm07/Makefile.am
    testsuites/tmtests/tm07/system.h
    testsuites/tmtests/tm07/task1.c
    testsuites/tmtests/tm07/tm07.doc
    testsuites/tmtests/tm08/.cvsignore
    testsuites/tmtests/tm08/Makefile.am
    testsuites/tmtests/tm08/system.h
    testsuites/tmtests/tm08/task1.c
    testsuites/tmtests/tm08/tm08.doc
    testsuites/tmtests/tm09/.cvsignore
    testsuites/tmtests/tm09/Makefile.am
    testsuites/tmtests/tm09/system.h
    testsuites/tmtests/tm09/task1.c
    testsuites/tmtests/tm09/tm09.doc
    testsuites/tmtests/tm10/.cvsignore
    testsuites/tmtests/tm10/Makefile.am
    testsuites/tmtests/tm10/system.h
    testsuites/tmtests/tm10/task1.c
    testsuites/tmtests/tm10/tm10.doc
    testsuites/tmtests/tm11/.cvsignore
    testsuites/tmtests/tm11/Makefile.am
    testsuites/tmtests/tm11/system.h
    testsuites/tmtests/tm11/task1.c
    testsuites/tmtests/tm11/tm11.doc
    testsuites/tmtests/tm12/.cvsignore
    testsuites/tmtests/tm12/Makefile.am
    testsuites/tmtests/tm12/system.h
    testsuites/tmtests/tm12/task1.c
    testsuites/tmtests/tm12/tm12.doc
    testsuites/tmtests/tm13/.cvsignore
    testsuites/tmtests/tm13/Makefile.am
    testsuites/tmtests/tm13/system.h
    testsuites/tmtests/tm13/task1.c
    testsuites/tmtests/tm13/tm13.doc
    testsuites/tmtests/tm14/.cvsignore
    testsuites/tmtests/tm14/Makefile.am
    testsuites/tmtests/tm14/system.h
    testsuites/tmtests/tm14/task1.c
    testsuites/tmtests/tm14/tm14.doc
    testsuites/tmtests/tm15/.cvsignore
    testsuites/tmtests/tm15/Makefile.am
    testsuites/tmtests/tm15/system.h
    testsuites/tmtests/tm15/task1.c
    testsuites/tmtests/tm15/tm15.doc
    testsuites/tmtests/tm16/.cvsignore
    testsuites/tmtests/tm16/Makefile.am
    testsuites/tmtests/tm16/system.h
    testsuites/tmtests/tm16/task1.c
    testsuites/tmtests/tm16/tm16.doc
    testsuites/tmtests/tm17/.cvsignore
    testsuites/tmtests/tm17/Makefile.am
    testsuites/tmtests/tm17/system.h
    testsuites/tmtests/tm17/task1.c
    testsuites/tmtests/tm17/tm17.doc
    testsuites/tmtests/tm18/.cvsignore
    testsuites/tmtests/tm18/Makefile.am
    testsuites/tmtests/tm18/system.h
    testsuites/tmtests/tm18/task1.c
    testsuites/tmtests/tm18/tm18.doc
    testsuites/tmtests/tm19/.cvsignore
    testsuites/tmtests/tm19/Makefile.am
    testsuites/tmtests/tm19/system.h
    testsuites/tmtests/tm19/task1.c
    testsuites/tmtests/tm19/tm19.doc
    testsuites/tmtests/tm20/.cvsignore
    testsuites/tmtests/tm20/Makefile.am
    testsuites/tmtests/tm20/system.h
    testsuites/tmtests/tm20/task1.c
    testsuites/tmtests/tm20/tm20.doc
    testsuites/tmtests/tm21/.cvsignore
    testsuites/tmtests/tm21/Makefile.am
    testsuites/tmtests/tm21/system.h
    testsuites/tmtests/tm21/task1.c
    testsuites/tmtests/tm21/tm21.doc
    testsuites/tmtests/tm22/.cvsignore
    testsuites/tmtests/tm22/Makefile.am
    testsuites/tmtests/tm22/system.h
    testsuites/tmtests/tm22/task1.c
    testsuites/tmtests/tm22/tm22.doc
    testsuites/tmtests/tm23/.cvsignore
    testsuites/tmtests/tm23/Makefile.am
    testsuites/tmtests/tm23/system.h
    testsuites/tmtests/tm23/task1.c
    testsuites/tmtests/tm23/tm23.doc
    testsuites/tmtests/tm24/.cvsignore
    testsuites/tmtests/tm24/Makefile.am
    testsuites/tmtests/tm24/system.h
    testsuites/tmtests/tm24/task1.c
    testsuites/tmtests/tm24/tm24.doc
    testsuites/tmtests/tm25/.cvsignore
    testsuites/tmtests/tm25/Makefile.am
    testsuites/tmtests/tm25/system.h
    testsuites/tmtests/tm25/task1.c
    testsuites/tmtests/tm25/tm25.doc
    testsuites/tmtests/tm26/.cvsignore
    testsuites/tmtests/tm26/Makefile.am
    testsuites/tmtests/tm26/fptest.h
    testsuites/tmtests/tm26/system.h
    testsuites/tmtests/tm26/task1.c
    testsuites/tmtests/tm26/tm26.doc
    testsuites/tmtests/tm27/.cvsignore
    testsuites/tmtests/tm27/Makefile.am
    testsuites/tmtests/tm27/system.h
    testsuites/tmtests/tm27/task1.c
    testsuites/tmtests/tm27/tm27.doc
    testsuites/tmtests/tm28/.cvsignore
    testsuites/tmtests/tm28/Makefile.am
    testsuites/tmtests/tm28/system.h
    testsuites/tmtests/tm28/task1.c
    testsuites/tmtests/tm28/tm28.doc
    testsuites/tmtests/tm29/.cvsignore
    testsuites/tmtests/tm29/Makefile.am
    testsuites/tmtests/tm29/system.h
    testsuites/tmtests/tm29/task1.c
    testsuites/tmtests/tm29/tm29.doc
    testsuites/tmtests/tmck/.cvsignore
    testsuites/tmtests/tmck/Makefile.am
    testsuites/tmtests/tmck/system.h
    testsuites/tmtests/tmck/task1.c
    testsuites/tmtests/tmck/tmck.doc
    testsuites/tmtests/tmoverhd/.cvsignore
    testsuites/tmtests/tmoverhd/Makefile.am
    testsuites/tmtests/tmoverhd/dumrtems.h
    testsuites/tmtests/tmoverhd/empty.c
    testsuites/tmtests/tmoverhd/system.h
    testsuites/tmtests/tmoverhd/testtask.c
    testsuites/tmtests/tmoverhd/tmoverhd.doc
    testsuites/tmtests/tmtests.am
    testsuites/tools/.cvsignore
    testsuites/tools/ChangeLog
    testsuites/tools/Makefile.am
    testsuites/tools/configure.ac
    testsuites/tools/generic/.cvsignore
    testsuites/tools/generic/ChangeLog
    testsuites/tools/generic/Makefile.am
    testsuites/tools/generic/configure.ac
    testsuites/tools/generic/difftest.in
    testsuites/tools/generic/sorttimes.in
This commit is contained in:
cvs2git
2003-02-11 23:44:42 +00:00
parent eed014937a
commit d8daeafaba
1338 changed files with 0 additions and 131909 deletions

194
bootstrap
View File

@@ -1,194 +0,0 @@
#! /bin/sh
#
# helps bootstrapping, when checked out from CVS
# requires GNU autoconf and GNU automake
#
# $Id$
# this is not meant to be exported outside the source tree
# NOTE: Inspired by libtool's autogen script
# to be run from the toplevel directory of RTEMS'
# source tree
AUTOCONF_VERS=2\.57
AUTOMAKE_VERS=1\.7\.2
progname=`basename $0`
top_srcdir=`dirname $0`
verbose="";
quiet="false"
mode="generate"
usage()
{
echo
echo "usage: ${progname} [-h|-q|-v]"
echo
echo "options:"
echo " -h .. display this message and exit";
echo " -q .. quiet, don't display directories";
echo " -v .. verbose, pass -v to automake when invoking automake"
echo " -c .. clean, remove all aclocal/autoconf/automake generated files"
echo
exit 1;
}
generate_bspdir_acinclude()
{
cat << EOF > acinclude.m4~
# RTEMS_CHECK_BSPDIR(RTEMS_BSP)
AC_DEFUN([RTEMS_CHECK_BSPDIR],
[
RTEMS_BSP_ALIAS(ifelse([\$1],,[\${RTEMS_BSP}],[\$1]),bspdir)
case "\$bspdir" in
EOF
for i in */bsp_specs; do
d=`dirname $i`
cat << EOF >> acinclude.m4~
$d )
AC_CONFIG_SUBDIRS([$d]);;
EOF
done
cat << EOF >> acinclude.m4~
*)
AC_MSG_ERROR([Invalid BSP]);;
esac
])
EOF
if cmp -s acinclude.m4 acinclude.m4~ 2>/dev/null; then
echo "acinclude.m4 is unchanged";
else
cp acinclude.m4~ acinclude.m4
fi
rm -f acinclude.m4~
}
if test ! -f $top_srcdir/aclocal/version.m4; then
echo "${progname}:"
echo " Installation problem: Can't find file aclocal/version.m4"
exit 1;
fi
while test $# -gt 0; do
case $1 in
-h|--he|--hel|--help)
usage ;;
-q|--qu|--qui|--quie|--quiet)
quiet="true";
shift;;
-v|--ve|--ver|--verb|--verbo|--verbos|--verbose)
verbose="-v";
shift;;
-c|--cl|--cle|--clea|--clean)
mode="clean";
shift;;
-*) echo "unknown option $1" ;
usage ;;
*) echo "invalid parameter $1" ;
usage ;;
esac
done
case $mode in
generate)
AUTOCONF=${AUTOCONF-autoconf}
if test -z "$AUTOCONF"; then
echo "You must have autoconf installed to run $program"
fi
if test -z "`$AUTOCONF --version 2>/dev/null | grep -e \" $AUTOCONF_VERS\"`"; then
cat << EOF
RTEMS requires autoconf version $AUTOCONF_VERS.
You are trying to use $AUTOCONF which does not seem to be sufficient
EOF
exit 1
fi
AUTOMAKE=${AUTOMAKE-automake}
if test -z "$AUTOMAKE"; then
echo "You must have automake installed to run $program"
fi
if test -z "`$AUTOMAKE --version 2>/dev/null | grep -e \" $AUTOMAKE_VERS\"`"; then
cat << EOF
RTEMS requires automake version $AUTOMAKE_VERS.
You are trying to use $AUTOMAKE which does not seem to be sufficient
EOF
exit 1
fi
case $top_srcdir in
/* ) aclocal_dir=$top_srcdir
;;
*) aclocal_dir=`pwd`/$top_srcdir
;;
esac
confs=`find . \( -name 'configure.in' -o -name 'configure.ac' \) -print`
for i in $confs; do
dir=`dirname $i`;
configure=`basename $i`;
( test "$quiet" = "true" || echo "$dir";
cd $dir;
test -n "`grep RTEMS_CHECK_BSPDIR ${configure}`" && \
generate_bspdir_acinclude;
pat="s,\$(RTEMS_TOPdir),${aclocal_dir},g"
aclocal_args=`grep '^[ ]*ACLOCAL_AMFLAGS' Makefile.am | \
sed -e 's%.*ACLOCAL_AMFLAGS.*\=[ ]*%%g' -e $pat ` ;
test "$verbose" = "-v" && echo "aclocal $aclocal_args"
aclocal $aclocal_args;
test -n "`grep CONFIG_HEADER ${configure}`" && autoheader \
&& test "$verbose" = "-v" && echo "autoheader";
test -n "`grep RTEMS_BSP_CONFIGURE ${configure}`" && autoheader \
&& test "$verbose" = "-v" && echo "autoheader";
test -f Makefile.am && automake -a -c $verbose ;
autoconf;
test -f Makefile.am && test -n "`grep 'stamp-h\.in' Makefile.in`" \
&& echo timestamp > stamp-h.in
)
done
;;
clean)
test "$quiet" = "true" || echo "removing automake generated Makefile.in files"
files=`find . -name 'Makefile.am' -print | sed -e 's%\.am%\.in%g'` ;
for i in $files; do if test -f $i; then
rm -f $i
test "$verbose" = "-v" && echo "$i"
fi; done
test "$quiet" = "true" || echo "removing configure files"
files=`find . -name 'configure' -print` ;
test "$verbose" = "-v" && test -n "$files" && echo "$files" ;
for i in $files; do if test -f $i; then
rm -f $i config.guess config.sub depcomp install-sh mdate-sh missing \
mkinstalldirs texinfo.tex
test "$verbose" = "-v" && echo "$i"
fi; done
test "$quiet" = "true" || echo "removing aclocal.m4 files"
files=`find . -name 'aclocal.m4' -print` ;
test "$verbose" = "-v" && test -n "$files" && echo "$files" ;
for i in $files; do if test -f $i; then
rm -f $i
test "$verbose" = "-v" && echo "$i"
fi; done
find . -name '*~' -print | xargs rm -f
find . -name 'bspopts.h*' -print | xargs rm -f
find . -name '*.orig' -print | xargs rm -f
find . -name '*.rej' -print | xargs rm -f
find . -name 'config.status' -print | xargs rm -f
find . -name 'config.log' -print | xargs rm -f
find . -name 'config.cache' -print | xargs rm -f
find . -name 'Makefile' -print | xargs rm -f
find . -name '.deps' -print | xargs rm -rf
find . -name '.libs' -print | xargs rm -rf
find . -name 'stamp-h.in' | xargs rm -rf
find . -name 'autom4te*.cache' | xargs rm -rf
;;
esac

View File

@@ -1,14 +0,0 @@
aclocal.m4
autom4te*.cache
config.cache
config.guess
config.log
config.status
config.sub
configure
depcomp
install-sh
Makefile
Makefile.in
missing
mkinstalldirs

View File

@@ -1,62 +0,0 @@
2003-02-11 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
* configure.ac: AM_INIT_AUTOMAKE([1.7.2]).
2003-02-11 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
* configure.ac: AC_PREREQ(2.57).
2003-02-03 Joel Sherrill <joel@OARcorp.com>
PR 338/filesystem
* rtems.adb, rtems.ads: Side-effect of fixing reentrancy problem with
rtems_io_lookup_name() (API change).
2003-01-03 Joel Sherrill <joel@OARcorp.com>
* rtems.ads: Corrected Configuration_Table record definition to
match current RTEMS source. sp01 now runs.
2002-11-19 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
* configure.ac: Fix package name.
2002-10-29 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
* configure.ac: Remove AC_ENABLE_MULTILIB.
* Makefile.am: Add CVS-Id.
2002-10-25 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
* configure.ac: Add nostdinc to AM_INIT_AUTOMAKE.
2002-10-21 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
* .cvsignore: Reformat.
Add autom4te*cache.
Remove autom4te.cache.
2002-08-30 Joel Sherrill <joel@OARcorp.com>
* rtems.adb (IO_Initialize): Make this match the C prototype.
2002-08-27 Joel Sherrill <joel@OARcorp.com>
* rtems.ads: Corrected binding for Io_Initialize.
2001-08-23 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
* configure.ac: New.
* Makefile.am: New.
* .cvsignore: New.
2001-02-01 Joel Sherrill <joel@OARcorp.com>
* rtems.ads, rtems.adb: Formatting cleaned up. Task based timer
directives added. This is Timer_Initiate_Server,
Timer_Server_Fire_After, and Timer_Server_Fire_When.
2001-02-01 Joel Sherrill <joel@OARcorp.com>
* ChangeLog: New file.

View File

@@ -1,24 +0,0 @@
#
# $Id$
#
ACLOCAL_AMFLAGS = -I ../aclocal
$(PROJECT_INCLUDE)/adainclude:
$(mkinstalldirs) $@
$(PROJECT_INCLUDE)/adainclude/%: %
$(INSTALL_DATA) $< $@
adaincludedir = $(includedir)/adainclude
adainclude_HEADERS = rtems.adb rtems.ads
adainclude_HEADERS += rtems-multiprocessing.adb rtems-multiprocessing.ads
TMPINSTALL_FILES = \
$(PROJECT_INCLUDE)/adainclude \
$(adainclude_HEADERS:%=$(PROJECT_INCLUDE)/adainclude/%) \
$(nodist_adalib_HEADERS:%=$(PROJECT_INCLUDE)/adainclude/%)
all-local: $(TMPINSTALL_FILES)
include $(top_srcdir)/../automake/local.am

View File

@@ -1,38 +0,0 @@
--
-- RTEMS Multiprocessing Manager/ Body
--
-- DESCRIPTION:
--
-- This package provides the interface to the Multiprocessing Manager
-- of the RTEMS API.
--
-- DEPENDENCIES:
--
--
-- COPYRIGHT (c) 1997.
-- On-Line Applications Research Corporation (OAR).
--
-- The license and distribution terms for this file may in
-- the file LICENSE in this distribution or at
-- http://www.OARcorp.com/rtems/license.html.
--
-- $Id$
--
package body RTEMS.Multiprocessing is
--
-- Announce
--
procedure Announce is
procedure Multiprocessing_Announce_Base;
pragma Import (C, Multiprocessing_Announce_Base,
"rtems_multiprocessing_announce");
begin
Multiprocessing_Announce_Base;
end Announce;
end RTEMS.Multiprocessing;

View File

@@ -1,30 +0,0 @@
--
-- RTEMS Multiprocessing Manager/ Specification
--
-- DESCRIPTION:
--
-- This package provides the interface to the Multiprocessing Manager
-- of the RTEMS API.
--
-- DEPENDENCIES:
--
--
-- COPYRIGHT (c) 1997.
-- On-Line Applications Research Corporation (OAR).
--
-- The license and distribution terms for this file may in
-- the file LICENSE in this distribution or at
-- http://www.OARcorp.com/rtems/license.html.
--
-- $Id$
--
package RTEMS.Multiprocessing is
--
-- Multiprocessing Manager
--
procedure Announce;
end RTEMS.Multiprocessing;

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,86 +0,0 @@
2003-02-11 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
* configure.ac: AM_INIT_AUTOMAKE([1.7.2]).
2003-02-11 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
* configure.ac: AC_PREREQ(2.57).
2002-12-17 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
* Makefile.am: Don't include @RTEMS_BSP@.cfg.
* configure.ac: Remove RTEMS_CHECK_CUSTOM_BSP.
2002-11-01 Joel Sherrill <joel@OARcorp.com>
* cpu.c: Currently only the mpc8260 BSP supports interrupt nesting.
NOTE: These needs to be generalized as the patch is applied to other
BSPs.
2002-10-21 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
* .cvsignore: Reformat.
Add autom4te*cache.
Remove autom4te.cache.
2002-08-11 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
* Makefile.am: Use .$(OBJEXT) instead of .o.
2001-05-14 Till Straumann <strauman@slac.stanford.edu>
* cpu.c: Per PR211 fix
saving/restoring floating point context. The fpsave and fprestore
routines are only used in a executing context which _is_ fp and hence
has the FPU enabled. The current behavior required the FPU always to
be on which is very dangerous if lazy context switching is used.
[Joel Note: Some ports explicitly enabled the FPU in the FP save and
restore routines to avoid this.]
The patch also makes sure (on powerpc only) that the FPU is disabled
for integer tasks. Note that this is crucial if deferred fp context
switching is used. Otherwise, fp context corruption may go undetected!
Also note that even tasks which merely push/pop FP registers to/from
the stack without modifying them still MUST be FP tasks - otherwise
(if lazy FP context switching is used), FP register corruption (of
other, FP, tasks may occur)!
Furthermore, (on PPC) by default, lazy FP context save/restore
is _disabled_.
2002-04-18 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
* rtems/score/cpu.h: Removed.
* Makefile.am: Reflect changes above.
2001-04-03 Joel Sherrill <joel@OARcorp.com>
* Per PR94, all rtems/score/CPUtypes.h are named rtems/score/types.h.
* rtems/score/cpu.h: Account for name change.
2002-03-27 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
* configure.ac:
AC_INIT(package,_RTEMS_VERSION,_RTEMS_BUGS).
AM_INIT_AUTOMAKE([no-define foreign 1.6]).
* Makefile.am: Remove AUTOMAKE_OPTIONS.
2001-11-28 Joel Sherrill <joel@OARcorp.com>,
This was tracked as PR91.
* rtems/score/cpu.h: Added CPU_PROVIDES_ISR_IS_IN_PROGRESS macro which
is used to specify if the port uses the standard macro for this (FALSE).
A TRUE setting indicates the port provides its own implementation.
* rtems/score/c_isr.inl: Deleted and contents merged into cpu.c.
* cpu.c: Received contents of c_isr.inl.
* Makefile.am: Deleted reference to c_isr.inl.
2001-11-26 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
* .cvsignore: Add aclocal.m4, autom4te.*, config.*, configure.
2001-11-21 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
* Makefile.am: Preinstall c_isr.inl (HACK).
* ChangeLog: New file.

View File

@@ -1,148 +0,0 @@
/*
* PowerPC CPU Dependent Source
*
* Author: Andrew Bray <andy@i-cubed.co.uk>
*
* COPYRIGHT (c) 1995 by i-cubed ltd.
*
* To anyone who acknowledges that this file is provided "AS IS"
* without any express or implied warranty:
* permission to use, copy, modify, and distribute this file
* for any purpose is hereby granted without fee, provided that
* the above copyright notice and this notice appears in all
* copies, and that the name of i-cubed limited not be used in
* advertising or publicity pertaining to distribution of the
* software without specific, written prior permission.
* i-cubed limited makes no representations about the suitability
* of this software for any purpose.
*
* Derived from c/src/exec/cpu/no_cpu/cpu.c:
*
* COPYRIGHT (c) 1989-1997.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be found in
* the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
* $Id$
*/
#include <rtems/system.h>
#include <rtems/score/isr.h>
#include <rtems/score/context.h>
#include <rtems/score/thread.h>
#include <rtems/score/interr.h>
/* _CPU_Initialize
*
* This routine performs processor dependent initialization.
*
* INPUT PARAMETERS:
* cpu_table - CPU table to initialize
* thread_dispatch - address of disptaching routine
*/
void _CPU_Initialize(
rtems_cpu_table *cpu_table,
void (*thread_dispatch) /* ignored on this CPU */
)
{
_CPU_Table = *cpu_table;
}
/*PAGE
*
* _CPU_Context_Initialize
*/
void _CPU_Context_Initialize(
Context_Control *the_context,
unsigned32 *stack_base,
unsigned32 size,
unsigned32 new_level,
void *entry_point,
boolean is_fp
)
{
unsigned32 msr_value;
unsigned32 sp;
sp = (unsigned32)stack_base + size - CPU_MINIMUM_STACK_FRAME_SIZE;
*((unsigned32 *)sp) = 0;
the_context->gpr1 = sp;
_CPU_MSR_GET( msr_value );
if (!(new_level & CPU_MODES_INTERRUPT_MASK)) {
msr_value |= MSR_EE;
}
else {
msr_value &= ~MSR_EE;
}
the_context->msr = msr_value;
/*
* The FP bit of the MSR should only be enabled if this is a floating
* point task. Unfortunately, the vfprintf_r routine in newlib
* ends up pushing a floating point register regardless of whether or
* not a floating point number is being printed. Serious restructuring
* of vfprintf.c will be required to avoid this behavior. At this
* time (7 July 1997), this restructuring is not being done.
*/
/* Till Straumann: For deferred FPContext save/restore, make sure integer
* tasks have no FPU access in order to catch violations.
* Otherwise, the FP registers may be corrupted.
* Since we set the_contex->msr using our current MSR,
* we must make sure MSR_FP is off if (!is_fp)...
*/
#if defined(CPU_USE_DEFERRED_FP_SWITCH) && (CPU_USE_DEFERRED_FP_SWITCH==TRUE)
if ( is_fp )
#endif
the_context->msr |= PPC_MSR_FP;
#if defined(CPU_USE_DEFERRED_FP_SWITCH) && (CPU_USE_DEFERRED_FP_SWITCH==TRUE)
else
the_context->msr &= ~PPC_MSR_FP;
#endif
the_context->pc = (unsigned32)entry_point;
}
/*PAGE
*
* _CPU_Install_interrupt_stack
*/
void _CPU_Install_interrupt_stack( void )
{
}
/*PAGE
*
* This is the PowerPC specific implementation of the routine which
* returns TRUE if an interrupt is in progress.
*/
boolean _ISR_Is_in_progress( void )
{
/*
* Until the patch on PR288 is in all new exception BSPs, this is
* the safest thing to do.
*/
#ifdef mpc8260
return (_ISR_Nest_level != 0);
#else
register unsigned int isr_nesting_level;
/*
* Move from special purpose register 0 (mfspr SPRG0, r3)
*/
asm volatile ("mfspr %0, 272" : "=r" (isr_nesting_level));
return isr_nesting_level;
#endif
}

View File

@@ -1,405 +0,0 @@
/* cpu_asm.s 1.1 - 95/12/04
*
* This file contains the assembly code for the PowerPC implementation
* of RTEMS.
*
* Author: Andrew Bray <andy@i-cubed.co.uk>
*
* COPYRIGHT (c) 1995 by i-cubed ltd.
*
* To anyone who acknowledges that this file is provided "AS IS"
* without any express or implied warranty:
* permission to use, copy, modify, and distribute this file
* for any purpose is hereby granted without fee, provided that
* the above copyright notice and this notice appears in all
* copies, and that the name of i-cubed limited not be used in
* advertising or publicity pertaining to distribution of the
* software without specific, written prior permission.
* i-cubed limited makes no representations about the suitability
* of this software for any purpose.
*
* Derived from c/src/exec/cpu/no_cpu/cpu_asm.c:
*
* COPYRIGHT (c) 1989-1997.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may in
* the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
* $Id$
*/
#include <asm.h>
/*
* Offsets for various Contexts
*/
.set GP_1, 0
.set GP_2, (GP_1 + 4)
.set GP_13, (GP_2 + 4)
.set GP_14, (GP_13 + 4)
.set GP_15, (GP_14 + 4)
.set GP_16, (GP_15 + 4)
.set GP_17, (GP_16 + 4)
.set GP_18, (GP_17 + 4)
.set GP_19, (GP_18 + 4)
.set GP_20, (GP_19 + 4)
.set GP_21, (GP_20 + 4)
.set GP_22, (GP_21 + 4)
.set GP_23, (GP_22 + 4)
.set GP_24, (GP_23 + 4)
.set GP_25, (GP_24 + 4)
.set GP_26, (GP_25 + 4)
.set GP_27, (GP_26 + 4)
.set GP_28, (GP_27 + 4)
.set GP_29, (GP_28 + 4)
.set GP_30, (GP_29 + 4)
.set GP_31, (GP_30 + 4)
.set GP_CR, (GP_31 + 4)
.set GP_PC, (GP_CR + 4)
.set GP_MSR, (GP_PC + 4)
#if (PPC_HAS_DOUBLE==1)
.set FP_SIZE, 8
#define LDF lfd
#define STF stfd
#else
.set FP_SIZE, 4
#define LDF lfs
#define STF stfs
#endif
.set FP_0, 0
.set FP_1, (FP_0 + FP_SIZE)
.set FP_2, (FP_1 + FP_SIZE)
.set FP_3, (FP_2 + FP_SIZE)
.set FP_4, (FP_3 + FP_SIZE)
.set FP_5, (FP_4 + FP_SIZE)
.set FP_6, (FP_5 + FP_SIZE)
.set FP_7, (FP_6 + FP_SIZE)
.set FP_8, (FP_7 + FP_SIZE)
.set FP_9, (FP_8 + FP_SIZE)
.set FP_10, (FP_9 + FP_SIZE)
.set FP_11, (FP_10 + FP_SIZE)
.set FP_12, (FP_11 + FP_SIZE)
.set FP_13, (FP_12 + FP_SIZE)
.set FP_14, (FP_13 + FP_SIZE)
.set FP_15, (FP_14 + FP_SIZE)
.set FP_16, (FP_15 + FP_SIZE)
.set FP_17, (FP_16 + FP_SIZE)
.set FP_18, (FP_17 + FP_SIZE)
.set FP_19, (FP_18 + FP_SIZE)
.set FP_20, (FP_19 + FP_SIZE)
.set FP_21, (FP_20 + FP_SIZE)
.set FP_22, (FP_21 + FP_SIZE)
.set FP_23, (FP_22 + FP_SIZE)
.set FP_24, (FP_23 + FP_SIZE)
.set FP_25, (FP_24 + FP_SIZE)
.set FP_26, (FP_25 + FP_SIZE)
.set FP_27, (FP_26 + FP_SIZE)
.set FP_28, (FP_27 + FP_SIZE)
.set FP_29, (FP_28 + FP_SIZE)
.set FP_30, (FP_29 + FP_SIZE)
.set FP_31, (FP_30 + FP_SIZE)
.set FP_FPSCR, (FP_31 + FP_SIZE)
.set IP_LINK, 0
.set IP_0, (IP_LINK + 8)
.set IP_2, (IP_0 + 4)
.set IP_3, (IP_2 + 4)
.set IP_4, (IP_3 + 4)
.set IP_5, (IP_4 + 4)
.set IP_6, (IP_5 + 4)
.set IP_7, (IP_6 + 4)
.set IP_8, (IP_7 + 4)
.set IP_9, (IP_8 + 4)
.set IP_10, (IP_9 + 4)
.set IP_11, (IP_10 + 4)
.set IP_12, (IP_11 + 4)
.set IP_13, (IP_12 + 4)
.set IP_28, (IP_13 + 4)
.set IP_29, (IP_28 + 4)
.set IP_30, (IP_29 + 4)
.set IP_31, (IP_30 + 4)
.set IP_CR, (IP_31 + 4)
.set IP_CTR, (IP_CR + 4)
.set IP_XER, (IP_CTR + 4)
.set IP_LR, (IP_XER + 4)
.set IP_PC, (IP_LR + 4)
.set IP_MSR, (IP_PC + 4)
.set IP_END, (IP_MSR + 16)
BEGIN_CODE
/*
* _CPU_Context_save_fp_context
*
* This routine is responsible for saving the FP context
* at *fp_context_ptr. If the point to load the FP context
* from is changed then the pointer is modified by this routine.
*
* Sometimes a macro implementation of this is in cpu.h which dereferences
* the ** and a similarly named routine in this file is passed something
* like a (Context_Control_fp *). The general rule on making this decision
* is to avoid writing assembly language.
*/
ALIGN (PPC_CACHE_ALIGNMENT, PPC_CACHE_ALIGN_POWER)
PUBLIC_PROC (_CPU_Context_save_fp)
PROC (_CPU_Context_save_fp):
#if (PPC_HAS_FPU == 1)
lwz r3, 0(r3)
STF f0, FP_0(r3)
STF f1, FP_1(r3)
STF f2, FP_2(r3)
STF f3, FP_3(r3)
STF f4, FP_4(r3)
STF f5, FP_5(r3)
STF f6, FP_6(r3)
STF f7, FP_7(r3)
STF f8, FP_8(r3)
STF f9, FP_9(r3)
STF f10, FP_10(r3)
STF f11, FP_11(r3)
STF f12, FP_12(r3)
STF f13, FP_13(r3)
STF f14, FP_14(r3)
STF f15, FP_15(r3)
STF f16, FP_16(r3)
STF f17, FP_17(r3)
STF f18, FP_18(r3)
STF f19, FP_19(r3)
STF f20, FP_20(r3)
STF f21, FP_21(r3)
STF f22, FP_22(r3)
STF f23, FP_23(r3)
STF f24, FP_24(r3)
STF f25, FP_25(r3)
STF f26, FP_26(r3)
STF f27, FP_27(r3)
STF f28, FP_28(r3)
STF f29, FP_29(r3)
STF f30, FP_30(r3)
STF f31, FP_31(r3)
mffs f2
STF f2, FP_FPSCR(r3)
#endif
blr
/*
* _CPU_Context_restore_fp_context
*
* This routine is responsible for restoring the FP context
* at *fp_context_ptr. If the point to load the FP context
* from is changed then the pointer is modified by this routine.
*
* Sometimes a macro implementation of this is in cpu.h which dereferences
* the ** and a similarly named routine in this file is passed something
* like a (Context_Control_fp *). The general rule on making this decision
* is to avoid writing assembly language.
*/
ALIGN (PPC_CACHE_ALIGNMENT, PPC_CACHE_ALIGN_POWER)
PUBLIC_PROC (_CPU_Context_restore_fp)
PROC (_CPU_Context_restore_fp):
#if (PPC_HAS_FPU == 1)
lwz r3, 0(r3)
LDF f2, FP_FPSCR(r3)
mtfsf 255, f2
LDF f0, FP_0(r3)
LDF f1, FP_1(r3)
LDF f2, FP_2(r3)
LDF f3, FP_3(r3)
LDF f4, FP_4(r3)
LDF f5, FP_5(r3)
LDF f6, FP_6(r3)
LDF f7, FP_7(r3)
LDF f8, FP_8(r3)
LDF f9, FP_9(r3)
LDF f10, FP_10(r3)
LDF f11, FP_11(r3)
LDF f12, FP_12(r3)
LDF f13, FP_13(r3)
LDF f14, FP_14(r3)
LDF f15, FP_15(r3)
LDF f16, FP_16(r3)
LDF f17, FP_17(r3)
LDF f18, FP_18(r3)
LDF f19, FP_19(r3)
LDF f20, FP_20(r3)
LDF f21, FP_21(r3)
LDF f22, FP_22(r3)
LDF f23, FP_23(r3)
LDF f24, FP_24(r3)
LDF f25, FP_25(r3)
LDF f26, FP_26(r3)
LDF f27, FP_27(r3)
LDF f28, FP_28(r3)
LDF f29, FP_29(r3)
LDF f30, FP_30(r3)
LDF f31, FP_31(r3)
#endif
blr
/* _CPU_Context_switch
*
* This routine performs a normal non-FP context switch.
*/
ALIGN (PPC_CACHE_ALIGNMENT, PPC_CACHE_ALIGN_POWER)
PUBLIC_PROC (_CPU_Context_switch)
PROC (_CPU_Context_switch):
sync
isync
/* This assumes that all the registers are in the given order */
li r5, 32
addi r3,r3,-4
#if ( PPC_USE_DATA_CACHE )
dcbz r5, r3
#endif
stw r1, GP_1+4(r3)
stw r2, GP_2+4(r3)
#if (PPC_USE_MULTIPLE == 1)
addi r3, r3, GP_18+4
#if ( PPC_USE_DATA_CACHE )
dcbz r5, r3
#endif
stmw r13, GP_13-GP_18(r3)
#else
stw r13, GP_13+4(r3)
stw r14, GP_14+4(r3)
stw r15, GP_15+4(r3)
stw r16, GP_16+4(r3)
stw r17, GP_17+4(r3)
stwu r18, GP_18+4(r3)
#if ( PPC_USE_DATA_CACHE )
dcbz r5, r3
#endif
stw r19, GP_19-GP_18(r3)
stw r20, GP_20-GP_18(r3)
stw r21, GP_21-GP_18(r3)
stw r22, GP_22-GP_18(r3)
stw r23, GP_23-GP_18(r3)
stw r24, GP_24-GP_18(r3)
stw r25, GP_25-GP_18(r3)
stw r26, GP_26-GP_18(r3)
stw r27, GP_27-GP_18(r3)
stw r28, GP_28-GP_18(r3)
stw r29, GP_29-GP_18(r3)
stw r30, GP_30-GP_18(r3)
stw r31, GP_31-GP_18(r3)
#endif
#if ( PPC_USE_DATA_CACHE )
dcbt r0, r4
#endif
mfcr r6
stw r6, GP_CR-GP_18(r3)
mflr r7
stw r7, GP_PC-GP_18(r3)
mfmsr r8
stw r8, GP_MSR-GP_18(r3)
#if ( PPC_USE_DATA_CACHE )
dcbt r5, r4
#endif
lwz r1, GP_1(r4)
lwz r2, GP_2(r4)
#if (PPC_USE_MULTIPLE == 1)
addi r4, r4, GP_19
#if ( PPC_USE_DATA_CACHE )
dcbt r5, r4
#endif
lmw r13, GP_13-GP_19(r4)
#else
lwz r13, GP_13(r4)
lwz r14, GP_14(r4)
lwz r15, GP_15(r4)
lwz r16, GP_16(r4)
lwz r17, GP_17(r4)
lwz r18, GP_18(r4)
lwzu r19, GP_19(r4)
#if ( PPC_USE_DATA_CACHE )
dcbt r5, r4
#endif
lwz r20, GP_20-GP_19(r4)
lwz r21, GP_21-GP_19(r4)
lwz r22, GP_22-GP_19(r4)
lwz r23, GP_23-GP_19(r4)
lwz r24, GP_24-GP_19(r4)
lwz r25, GP_25-GP_19(r4)
lwz r26, GP_26-GP_19(r4)
lwz r27, GP_27-GP_19(r4)
lwz r28, GP_28-GP_19(r4)
lwz r29, GP_29-GP_19(r4)
lwz r30, GP_30-GP_19(r4)
lwz r31, GP_31-GP_19(r4)
#endif
lwz r6, GP_CR-GP_19(r4)
lwz r7, GP_PC-GP_19(r4)
lwz r8, GP_MSR-GP_19(r4)
mtcrf 255, r6
mtlr r7
mtmsr r8
blr
/*
* _CPU_Context_restore
*
* This routine is generallu used only to restart self in an
* efficient manner. It may simply be a label in _CPU_Context_switch.
*
* NOTE: May be unnecessary to reload some registers.
*/
/*
* ACB: Don't worry about cache optimisation here - this is not THAT critical.
*/
ALIGN (PPC_CACHE_ALIGNMENT, PPC_CACHE_ALIGN_POWER)
PUBLIC_PROC (_CPU_Context_restore)
PROC (_CPU_Context_restore):
lwz r5, GP_CR(r3)
lwz r6, GP_PC(r3)
lwz r7, GP_MSR(r3)
mtcrf 255, r5
mtlr r6
mtmsr r7
lwz r1, GP_1(r3)
lwz r2, GP_2(r3)
#if (PPC_USE_MULTIPLE == 1)
lmw r13, GP_13(r3)
#else
lwz r13, GP_13(r3)
lwz r14, GP_14(r3)
lwz r15, GP_15(r3)
lwz r16, GP_16(r3)
lwz r17, GP_17(r3)
lwz r18, GP_18(r3)
lwz r19, GP_19(r3)
lwz r20, GP_20(r3)
lwz r21, GP_21(r3)
lwz r22, GP_22(r3)
lwz r23, GP_23(r3)
lwz r24, GP_24(r3)
lwz r25, GP_25(r3)
lwz r26, GP_26(r3)
lwz r27, GP_27(r3)
lwz r28, GP_28(r3)
lwz r29, GP_29(r3)
lwz r30, GP_30(r3)
lwz r31, GP_31(r3)
#endif
blr

View File

@@ -1,78 +0,0 @@
2003-02-11 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
* configure.ac: AM_INIT_AUTOMAKE([1.7.2]).
2003-02-11 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
* configure.ac: AC_PREREQ(2.57).
2002-12-17 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
* Makefile.am: Don't include @RTEMS_BSP@.cfg.
* configure.ac: Remove RTEMS_CHECK_CUSTOM_BSP.
2002-10-21 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
* .cvsignore: Reformat.
Add autom4te*cache.
Remove autom4te.cache.
2002-09-14 Joel Sherrill <joel@OARcorp.com>
* cpu.c: Include declaration of variable i in ifdef USE_SPRG to
eliminate warning.
2002-08-11 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
* Makefile.am: Use .$(OBJEXT) instead of .o.
2002-07-21 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
* Makefile.am: Fix oversights in previous patch.
2002-07-21 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
* rtems.S: Remove.
* Makefile.am: Reflect having removed rtems.S. Use AM_CPPFLAGS
instead of INCLUDES (Latest automake standard).
2002-04-30 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
* cpu.c: Include <rtems/powerpc/cache.h>.
2002-04-18 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
* rtems/score/cpu.h: Removed.
* Makefile.am: Reflect changes above.
2001-04-03 Joel Sherrill <joel@OARcorp.com>
* Per PR94, all rtems/score/CPUtypes.h are named rtems/score/types.h.
* rtems/score/cpu.h: Account for name change.
2002-03-27 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
* configure.ac:
AC_INIT(package,_RTEMS_VERSION,_RTEMS_BUGS).
AM_INIT_AUTOMAKE([no-define foreign 1.6]).
* Makefile.am: Remove AUTOMAKE_OPTIONS.
2001-11-28 Joel Sherrill <joel@OARcorp.com>,
This was tracked as PR91.
* rtems/score/cpu.h: Added CPU_PROVIDES_ISR_IS_IN_PROGRESS macro which
is used to specify if the port uses the standard macro for this (FALSE).
A TRUE setting indicates the port provides its own implementation.
* rtems/score/c_isr.inl: Deleted and contents merged into cpu.c.
* cpu.c: Received contents of c_isr.inl.
* Makefile.am: Deleted reference to c_isr.inl.
2001-11-26 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
* .cvsignore: Add aclocal.m4, autom4te.*, config.*, configure.
2001-11-21 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
* Makefile.am: Preinstall c_isr.inl (HACK).
* ChangeLog: New file.

View File

@@ -1,80 +0,0 @@
#
# $Id$
#
There are various issues regarding this port:
1) Legal
This port is written by Andrew Bray <andy@i-cubed.co.uk>, and
is copyright 1995 i-cubed ltd.
This port was later updated by Joel Sherrill <joel@OARcorp.com>
to test the support for the PPC603, PPC603e, and MPC604. This
was tested on the PowerPC simulator PSIM and a VMEbus single board
computer.
2) CPU support.
This release fully supports the PPC403GA, PPC403GB, PPC603, PPC603e,
MPC604, MPC750, and numerous MPC8xx processors. A good faith attempt
has been made to include support other models based upon available
documentation including the MPC5xx. There are two interrupt structures
supported by the PowerPC port. The newer structure is supported by
all the MPC750 and MPC604 BSPs. This structure is required to use
the RDBG remote debugging support.
This port was originally written and tested on the PPC403GA (using
software floating point). Current ports are tested primarily on
60x CPUs using the PowerPC simulator PSIM.
Andrew Bray received assistance during the initial porting effort
from IBM and Blue Micro and we would like to gratefully acknowledge
that help.
The support for the PPC602 processor is incomplete as only sketchy
data is currently available. Perhaps this model has been dropped.
3) Application Binary Interface
In the context of RTEMS, the ABI is of interest for the following
aspects:
a) Register usage. Which registers are used to provide static variable
linkage, stack pointer etc.
b) Function calling convention. How parameters are passed, how function
variables should be invoked, how values are returned, etc.
c) Stack frame layout.
I am aware of a number of ABIs for the PowerPC:
a) The PowerOpen ABI. This is the original Power ABI used on the RS/6000.
This is the only ABI supported by versions of GCC before 2.7.0.
b) The SVR4 ABI. This is the ABI defined by SunSoft for the Solaris port
to the PowerPC.
c) The Embedded ABI. This is an embedded ABI for PowerPC use, which has no
operating system interface defined. It is promoted by SunSoft, Motorola,
and Cygnus Support. Cygnus are porting the GNU toolchain to this ABI.
d) GCC 2.7.0. This compiler is partway along the road to supporting the EABI,
but is currently halfway in between.
This port was built and tested using the PowerOpen ABI, with the following
caveat: we used an ELF assembler and linker. So some attention may be
required on the assembler files to get them through a traditional (XCOFF)
PowerOpen assembler.
This port contains support for the other ABIs, but this may prove to be
incomplete as it is untested.
The RTEMS PowerPC port supports EABI as the primary ABI. The powerpc-rtems
GNU toolset configuration is EABI.
Andrew Bray, 4 December 1995
Joel Sherrill, 16 July 1997

View File

@@ -1,8 +0,0 @@
#
# $Id$
#
Todo list:
Maybe decode external interrupts like the HPPA does.
See c/src/lib/libcpu/powerpc/ppc403/ictrl/* for implementation on ppc403

View File

@@ -1,895 +0,0 @@
/*
* PowerPC CPU Dependent Source
*
* Author: Andrew Bray <andy@i-cubed.co.uk>
*
* COPYRIGHT (c) 1995 by i-cubed ltd.
*
* To anyone who acknowledges that this file is provided "AS IS"
* without any express or implied warranty:
* permission to use, copy, modify, and distribute this file
* for any purpose is hereby granted without fee, provided that
* the above copyright notice and this notice appears in all
* copies, and that the name of i-cubed limited not be used in
* advertising or publicity pertaining to distribution of the
* software without specific, written prior permission.
* i-cubed limited makes no representations about the suitability
* of this software for any purpose.
*
* Derived from c/src/exec/cpu/no_cpu/cpu.c:
*
* COPYRIGHT (c) 1989-1997.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be found in
* the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
* $Id$
*/
#include <rtems/system.h>
#include <rtems/score/isr.h>
#include <rtems/score/context.h>
#include <rtems/score/thread.h>
#include <rtems/score/interr.h>
#include <rtems/powerpc/cache.h>
/*
* These are for testing purposes.
*/
/* _CPU_Initialize
*
* This routine performs processor dependent initialization.
*
* INPUT PARAMETERS:
* cpu_table - CPU table to initialize
* thread_dispatch - address of disptaching routine
*/
static void ppc_spurious(int, CPU_Interrupt_frame *);
int _CPU_spurious_count = 0;
int _CPU_last_spurious = 0;
void _CPU_Initialize(
rtems_cpu_table *cpu_table,
void (*thread_dispatch) /* ignored on this CPU */
)
{
#if (PPC_USE_SPRG)
int i;
#endif
#if (PPC_ABI != PPC_ABI_POWEROPEN)
register unsigned32 r2 = 0;
#if (PPC_ABI != PPC_ABI_GCC27)
register unsigned32 r13 = 0;
asm ("mr %0,13" : "=r" ((r13)) : "0" ((r13)));
_CPU_IRQ_info.Default_r13 = r13;
#endif
asm ("mr %0,2" : "=r" ((r2)) : "0" ((r2)));
_CPU_IRQ_info.Default_r2 = r2;
#endif
_CPU_IRQ_info.Nest_level = &_ISR_Nest_level;
_CPU_IRQ_info.Disable_level = &_Thread_Dispatch_disable_level;
/* fill in _CPU_IRQ_info.Vector_table later */
#if (PPC_ABI == PPC_ABI_POWEROPEN)
_CPU_IRQ_info.Dispatch_r2 = ((unsigned32 *)_Thread_Dispatch)[1];
#endif
_CPU_IRQ_info.Switch_necessary = &_Context_Switch_necessary;
_CPU_IRQ_info.Signal = &_ISR_Signals_to_thread_executing;
#if (PPC_USE_SPRG)
i = (int)&_CPU_IRQ_info;
asm volatile("mtspr 0x113, %0" : "=r" (i) : "0" (i)); /* SPRG 3 */
#endif
/*
* Store Msr Value in the IRQ info structure.
*/
_CPU_MSR_Value(_CPU_IRQ_info.msr_initial);
#if (PPC_USE_SPRG)
i = _CPU_IRQ_info.msr_initial;
asm volatile("mtspr 0x112, %0" : "=r" (i) : "0" (i)); /* SPRG 2 */
#endif
_CPU_Table = *cpu_table;
}
/*
* _CPU_Initialize_vectors()
*
* Support routine to initialize the RTEMS vector table after it is allocated.
*
* PowerPC Specific Information:
*
* Complete initialization since the table is now allocated.
*/
void _CPU_Initialize_vectors(void)
{
int i;
proc_ptr handler = (proc_ptr)ppc_spurious;
_CPU_IRQ_info.Vector_table = _ISR_Vector_table;
if ( _CPU_Table.spurious_handler )
handler = (proc_ptr)_CPU_Table.spurious_handler;
for (i = 0; i < PPC_INTERRUPT_MAX; i++)
_ISR_Vector_table[i] = handler;
}
/*PAGE
*
* _CPU_ISR_Calculate_level
*
* The PowerPC puts its interrupt enable status in the MSR register
* which also contains things like endianness control. To be more
* awkward, the layout varies from processor to processor. This
* is why it was necessary to adopt a scheme which allowed the user
* to specify specifically which interrupt sources were enabled.
*/
unsigned32 _CPU_ISR_Calculate_level(
unsigned32 new_level
)
{
register unsigned32 new_msr = 0;
/*
* Set the critical interrupt enable bit
*/
#if (PPC_HAS_RFCI)
if ( !(new_level & PPC_INTERRUPT_LEVEL_CE) )
new_msr |= PPC_MSR_CE;
#endif
if ( !(new_level & PPC_INTERRUPT_LEVEL_ME) )
new_msr |= PPC_MSR_ME;
if ( !(new_level & PPC_INTERRUPT_LEVEL_EE) )
new_msr |= PPC_MSR_EE;
return new_msr;
}
/*PAGE
*
* _CPU_ISR_Set_level
*
* This routine sets the requested level in the MSR.
*/
void _CPU_ISR_Set_level(
unsigned32 new_level
)
{
register unsigned32 tmp = 0;
register unsigned32 new_msr;
new_msr = _CPU_ISR_Calculate_level( new_level );
asm volatile (
"mfmsr %0; andc %0,%0,%1; and %2, %2, %1; or %0, %0, %2; mtmsr %0" :
"=&r" ((tmp)) :
"r" ((PPC_MSR_DISABLE_MASK)), "r" ((new_msr)), "0" ((tmp))
);
}
/*PAGE
*
* _CPU_ISR_Get_level
*
* This routine gets the current interrupt level from the MSR and
* converts it to an RTEMS interrupt level.
*/
unsigned32 _CPU_ISR_Get_level( void )
{
unsigned32 level = 0;
unsigned32 msr;
asm volatile("mfmsr %0" : "=r" ((msr)));
msr &= PPC_MSR_DISABLE_MASK;
/*
* Set the critical interrupt enable bit
*/
#if (PPC_HAS_RFCI)
if ( !(msr & PPC_MSR_CE) )
level |= PPC_INTERRUPT_LEVEL_CE;
#endif
if ( !(msr & PPC_MSR_ME) )
level |= PPC_INTERRUPT_LEVEL_ME;
if ( !(msr & PPC_MSR_EE) )
level |= PPC_INTERRUPT_LEVEL_EE;
return level;
}
/*PAGE
*
* _CPU_Context_Initialize
*/
#if (PPC_ABI == PPC_ABI_POWEROPEN)
#define CPU_MINIMUM_STACK_FRAME_SIZE 56
#else /* PPC_ABI_SVR4 or PPC_ABI_EABI */
#define CPU_MINIMUM_STACK_FRAME_SIZE 8
#endif
void _CPU_Context_Initialize(
Context_Control *the_context,
unsigned32 *stack_base,
unsigned32 size,
unsigned32 new_level,
void *entry_point,
boolean is_fp
)
{
unsigned32 msr_value;
unsigned32 sp;
sp = (unsigned32)stack_base + size - CPU_MINIMUM_STACK_FRAME_SIZE;
*((unsigned32 *)sp) = 0;
the_context->gpr1 = sp;
the_context->msr = _CPU_ISR_Calculate_level( new_level );
/*
* The FP bit of the MSR should only be enabled if this is a floating
* point task. Unfortunately, the vfprintf_r routine in newlib
* ends up pushing a floating point register regardless of whether or
* not a floating point number is being printed. Serious restructuring
* of vfprintf.c will be required to avoid this behavior. At this
* time (7 July 1997), this restructuring is not being done.
*/
/*if ( is_fp ) */
the_context->msr |= PPC_MSR_FP;
/*
* Calculate the task's MSR value:
*
* + Set the exception prefix bit to point to the exception table
* + Force the RI bit
* + Use the DR and IR bits
*/
_CPU_MSR_Value( msr_value );
the_context->msr |= (msr_value & PPC_MSR_EP);
the_context->msr |= PPC_MSR_RI;
the_context->msr |= msr_value & (PPC_MSR_DR|PPC_MSR_IR);
#if (PPC_ABI == PPC_ABI_POWEROPEN)
{ unsigned32 *desc = (unsigned32 *)entry_point;
the_context->pc = desc[0];
the_context->gpr2 = desc[1];
}
#endif
#if (PPC_ABI == PPC_ABI_SVR4)
{ unsigned r13 = 0;
asm volatile ("mr %0, 13" : "=r" ((r13)));
the_context->pc = (unsigned32)entry_point;
the_context->gpr13 = r13;
}
#endif
#if (PPC_ABI == PPC_ABI_EABI)
{ unsigned32 r2 = 0;
unsigned r13 = 0;
asm volatile ("mr %0,2; mr %1,13" : "=r" ((r2)), "=r" ((r13)));
the_context->pc = (unsigned32)entry_point;
the_context->gpr2 = r2;
the_context->gpr13 = r13;
}
#endif
}
/* _CPU_ISR_install_vector
*
* This kernel routine installs the RTEMS handler for the
* specified vector.
*
* Input parameters:
* vector - interrupt vector number
* old_handler - former ISR for this vector number
* new_handler - replacement ISR for this vector number
*
* Output parameters: NONE
*
*/
void _CPU_ISR_install_vector(
unsigned32 vector,
proc_ptr new_handler,
proc_ptr *old_handler
)
{
proc_ptr ignored;
*old_handler = _ISR_Vector_table[ vector ];
/*
* If the interrupt vector table is a table of pointer to isr entry
* points, then we need to install the appropriate RTEMS interrupt
* handler for this vector number.
*/
/*
* Install the wrapper so this ISR can be invoked properly.
*/
if (_CPU_Table.exceptions_in_RAM)
_CPU_ISR_install_raw_handler( vector, _ISR_Handler, &ignored );
/*
* We put the actual user ISR address in '_ISR_vector_table'. This will
* be used by the _ISR_Handler so the user gets control.
*/
_ISR_Vector_table[ vector ] = new_handler ? (ISR_Handler_entry)new_handler :
_CPU_Table.spurious_handler ?
(ISR_Handler_entry)_CPU_Table.spurious_handler :
(ISR_Handler_entry)ppc_spurious;
}
/*PAGE
*
* _CPU_Install_interrupt_stack
*/
void _CPU_Install_interrupt_stack( void )
{
#if (PPC_ABI == PPC_ABI_POWEROPEN || PPC_ABI == PPC_ABI_GCC27)
_CPU_IRQ_info.Stack = _CPU_Interrupt_stack_high - 56;
#else
_CPU_IRQ_info.Stack = _CPU_Interrupt_stack_high - 8;
#endif
}
/* Handle a spurious interrupt */
static void ppc_spurious(int v, CPU_Interrupt_frame *i)
{
#if 0
printf("Spurious interrupt on vector %d from %08.8x\n",
v, i->pc);
#endif
#if defined(ppc403) || defined(ppc405)
if (v == PPC_IRQ_EXTERNAL)
{
register int r = 0;
asm volatile("mtdcr 0x42, %0" :
"=&r" ((r)) : "0" ((r))); /* EXIER */
}
else if (v == PPC_IRQ_PIT)
{
register int r = 0x08000000;
asm volatile("mtspr 0x3d8, %0" :
"=&r" ((r)) : "0" ((r))); /* TSR */
}
else if (v == PPC_IRQ_FIT)
{
register int r = 0x04000000;
asm volatile("mtspr 0x3d8, %0" :
"=&r" ((r)) : "0" ((r))); /* TSR */
}
#endif
++_CPU_spurious_count;
_CPU_last_spurious = v;
}
void _CPU_Fatal_error(unsigned32 _error)
{
asm volatile ("mr 3, %0" : : "r" ((_error)));
asm volatile ("tweq 5,5");
asm volatile ("li 0,0; mtmsr 0");
while (1) ;
}
#define PPC_SYNCHRONOUS_TRAP_BIT_MASK 0x100
#define PPC_ASYNCHRONOUS_TRAP( _trap ) (_trap)
#define PPC_SYNCHRONOUS_TRAP ( _trap ) ((_trap)+PPC_SYNCHRONOUS_TRAP_BIT_MASK)
#define PPC_REAL_TRAP_NUMBER ( _trap ) ((_trap)%PPC_SYNCHRONOUS_TRAP_BIT_MASK)
const CPU_Trap_table_entry _CPU_Trap_slot_template = {
#if (PPC_ABI == PPC_ABI_POWEROPEN || PPC_ABI == PPC_ABI_GCC27)
#error " Vector install not tested."
#if (PPC_HAS_FPU)
#error " Vector install not tested."
0x9421feb0, /* stwu r1, -(20*4 + 18*8 + IP_END)(r1) */
#else
#error " Vector install not tested."
0x9421ff40, /* stwu r1, -(20*4 + IP_END)(r1) */
#endif
#else
0x9421ff90, /* stwu r1, -(IP_END)(r1) */
#endif
0x90010008, /* stw %r0, IP_0(%r1) */
0x38000000, /* li %r0, PPC_IRQ */
0x48000002 /* ba PROC (_ISR_Handler) */
};
#if defined(mpc860) || defined(mpc821)
const CPU_Trap_table_entry _CPU_Trap_slot_template_m860 = {
0x7c0803ac, /* mtlr %r0 */
0x81210028, /* lwz %r9, IP_9(%r1) */
0x38000000, /* li %r0, PPC_IRQ */
0x48000002 /* b PROC (_ISR_Handler) */
};
#endif /* mpc860 */
unsigned32 ppc_exception_vector_addr(
unsigned32 vector
);
/*PAGE
*
* _CPU_ISR_install_raw_handler
*
* This routine installs the specified handler as a "raw" non-executive
* supported trap handler (a.k.a. interrupt service routine).
*
* Input Parameters:
* vector - trap table entry number plus synchronous
* vs. asynchronous information
* new_handler - address of the handler to be installed
* old_handler - pointer to an address of the handler previously installed
*
* Output Parameters: NONE
* *new_handler - address of the handler previously installed
*
* NOTE:
*
* This routine is based on the SPARC routine _CPU_ISR_install_raw_handler.
* Install a software trap handler as an executive interrupt handler
* (which is desirable since RTEMS takes care of window and register issues),
* then the executive needs to know that the return address is to the trap
* rather than the instruction following the trap.
*
*/
void _CPU_ISR_install_raw_handler(
unsigned32 vector,
proc_ptr new_handler,
proc_ptr *old_handler
)
{
unsigned32 real_vector;
CPU_Trap_table_entry *slot;
unsigned32 u32_handler=0;
/*
* Get the "real" trap number for this vector ignoring the synchronous
* versus asynchronous indicator included with our vector numbers.
*/
real_vector = vector;
/*
* Get the current base address of the trap table and calculate a pointer
* to the slot we are interested in.
*/
slot = (CPU_Trap_table_entry *)ppc_exception_vector_addr( real_vector );
/*
* Get the address of the old_handler from the trap table.
*
* NOTE: The old_handler returned will be bogus if it does not follow
* the RTEMS model.
*/
#define HIGH_BITS_MASK 0xFFFFFC00
#define HIGH_BITS_SHIFT 10
#define LOW_BITS_MASK 0x000003FF
if (slot->stwu_r1 == _CPU_Trap_slot_template.stwu_r1) {
/*
* Set u32_handler = to target address
*/
u32_handler = slot->b_Handler & 0x03fffffc;
/* IMD FIX: sign extend address fragment... */
if (u32_handler & 0x02000000) {
u32_handler |= 0xfc000000;
}
*old_handler = (proc_ptr) u32_handler;
} else
/* There are two kinds of handlers for the MPC860. One is the 'standard'
* one like above. The other is for the cascaded interrupts from the SIU
* and CPM. Therefore we must check for the alternate one if the standard
* one is not present
*/
#if defined(mpc860) || defined(mpc821)
if (slot->stwu_r1 == _CPU_Trap_slot_template_m860.stwu_r1) {
/*
* Set u32_handler = to target address
*/
u32_handler = slot->b_Handler & 0x03fffffc;
*old_handler = (proc_ptr) u32_handler;
} else
#endif /* mpc860 */
*old_handler = 0;
/*
* Copy the template to the slot and then fix it.
*/
#if defined(mpc860) || defined(mpc821)
if (vector >= PPC_IRQ_IRQ0)
*slot = _CPU_Trap_slot_template_m860;
else
#endif /* mpc860 */
*slot = _CPU_Trap_slot_template;
u32_handler = (unsigned32) new_handler;
/*
* IMD FIX: insert address fragment only (bits 6..29)
* therefore check for proper address range
* and remove unwanted bits
*/
if ((u32_handler & 0xfc000000) == 0xfc000000) {
u32_handler &= ~0xfc000000;
}
else if ((u32_handler & 0xfc000000) != 0x00000000) {
_Internal_error_Occurred(INTERNAL_ERROR_CORE,
TRUE,
u32_handler);
}
slot->b_Handler |= u32_handler;
slot->li_r0_IRQ |= vector;
_CPU_Data_Cache_Block_Flush( slot );
}
unsigned32 ppc_exception_vector_addr(
unsigned32 vector
)
{
#if (!PPC_HAS_EVPR)
unsigned32 Msr;
#endif
unsigned32 Top = 0;
unsigned32 Offset = 0x000;
#if (PPC_HAS_EXCEPTION_PREFIX)
_CPU_MSR_Value ( Msr );
if ( ( Msr & PPC_MSR_EP) != 0 ) /* Vectors at FFFx_xxxx */
Top = 0xfff00000;
#elif (PPC_HAS_EVPR)
asm volatile( "mfspr %0,0x3d6" : "=r" (Top)); /* EVPR */
Top = Top & 0xffff0000;
#endif
switch ( vector ) {
case PPC_IRQ_SYSTEM_RESET: /* on 40x aka PPC_IRQ_CRIT */
Offset = 0x00100;
break;
case PPC_IRQ_MCHECK:
Offset = 0x00200;
break;
case PPC_IRQ_PROTECT:
Offset = 0x00300;
break;
case PPC_IRQ_ISI:
Offset = 0x00400;
break;
case PPC_IRQ_EXTERNAL:
Offset = 0x00500;
break;
case PPC_IRQ_ALIGNMENT:
Offset = 0x00600;
break;
case PPC_IRQ_PROGRAM:
Offset = 0x00700;
break;
case PPC_IRQ_NOFP:
Offset = 0x00800;
break;
case PPC_IRQ_DECREMENTER:
Offset = 0x00900;
break;
case PPC_IRQ_RESERVED_A:
Offset = 0x00a00;
break;
case PPC_IRQ_RESERVED_B:
Offset = 0x00b00;
break;
case PPC_IRQ_SCALL:
Offset = 0x00c00;
break;
case PPC_IRQ_TRACE:
Offset = 0x00d00;
break;
case PPC_IRQ_FP_ASST:
Offset = 0x00e00;
break;
#if defined(ppc403) || defined(ppc405)
/* PPC_IRQ_CRIT is the same vector as PPC_IRQ_RESET
case PPC_IRQ_CRIT:
Offset = 0x00100;
break;
*/
case PPC_IRQ_PIT:
Offset = 0x01000;
break;
case PPC_IRQ_FIT:
Offset = 0x01010;
break;
case PPC_IRQ_WATCHDOG:
Offset = 0x01020;
break;
case PPC_IRQ_DEBUG:
Offset = 0x02000;
break;
#elif defined(ppc601)
case PPC_IRQ_TRACE:
Offset = 0x02000;
break;
#elif defined(ppc603)
case PPC_IRQ_TRANS_MISS:
Offset = 0x1000;
break;
case PPC_IRQ_DATA_LOAD:
Offset = 0x1100;
break;
case PPC_IRQ_DATA_STORE:
Offset = 0x1200;
break;
case PPC_IRQ_ADDR_BRK:
Offset = 0x1300;
break;
case PPC_IRQ_SYS_MGT:
Offset = 0x1400;
break;
#elif defined(ppc603e)
case PPC_TLB_INST_MISS:
Offset = 0x1000;
break;
case PPC_TLB_LOAD_MISS:
Offset = 0x1100;
break;
case PPC_TLB_STORE_MISS:
Offset = 0x1200;
break;
case PPC_IRQ_ADDRBRK:
Offset = 0x1300;
break;
case PPC_IRQ_SYS_MGT:
Offset = 0x1400;
break;
#elif defined(mpc604)
case PPC_IRQ_ADDR_BRK:
Offset = 0x1300;
break;
case PPC_IRQ_SYS_MGT:
Offset = 0x1400;
break;
#elif defined(mpc860) || defined(mpc821)
case PPC_IRQ_EMULATE:
Offset = 0x1000;
break;
case PPC_IRQ_INST_MISS:
Offset = 0x1100;
break;
case PPC_IRQ_DATA_MISS:
Offset = 0x1200;
break;
case PPC_IRQ_INST_ERR:
Offset = 0x1300;
break;
case PPC_IRQ_DATA_ERR:
Offset = 0x1400;
break;
case PPC_IRQ_DATA_BPNT:
Offset = 0x1c00;
break;
case PPC_IRQ_INST_BPNT:
Offset = 0x1d00;
break;
case PPC_IRQ_IO_BPNT:
Offset = 0x1e00;
break;
case PPC_IRQ_DEV_PORT:
Offset = 0x1f00;
break;
case PPC_IRQ_IRQ0:
Offset = 0x2000;
break;
case PPC_IRQ_LVL0:
Offset = 0x2040;
break;
case PPC_IRQ_IRQ1:
Offset = 0x2080;
break;
case PPC_IRQ_LVL1:
Offset = 0x20c0;
break;
case PPC_IRQ_IRQ2:
Offset = 0x2100;
break;
case PPC_IRQ_LVL2:
Offset = 0x2140;
break;
case PPC_IRQ_IRQ3:
Offset = 0x2180;
break;
case PPC_IRQ_LVL3:
Offset = 0x21c0;
break;
case PPC_IRQ_IRQ4:
Offset = 0x2200;
break;
case PPC_IRQ_LVL4:
Offset = 0x2240;
break;
case PPC_IRQ_IRQ5:
Offset = 0x2280;
break;
case PPC_IRQ_LVL5:
Offset = 0x22c0;
break;
case PPC_IRQ_IRQ6:
Offset = 0x2300;
break;
case PPC_IRQ_LVL6:
Offset = 0x2340;
break;
case PPC_IRQ_IRQ7:
Offset = 0x2380;
break;
case PPC_IRQ_LVL7:
Offset = 0x23c0;
break;
case PPC_IRQ_CPM_ERROR:
Offset = 0x2400;
break;
case PPC_IRQ_CPM_PC4:
Offset = 0x2410;
break;
case PPC_IRQ_CPM_PC5:
Offset = 0x2420;
break;
case PPC_IRQ_CPM_SMC2:
Offset = 0x2430;
break;
case PPC_IRQ_CPM_SMC1:
Offset = 0x2440;
break;
case PPC_IRQ_CPM_SPI:
Offset = 0x2450;
break;
case PPC_IRQ_CPM_PC6:
Offset = 0x2460;
break;
case PPC_IRQ_CPM_TIMER4:
Offset = 0x2470;
break;
case PPC_IRQ_CPM_RESERVED_8:
Offset = 0x2480;
break;
case PPC_IRQ_CPM_PC7:
Offset = 0x2490;
break;
case PPC_IRQ_CPM_PC8:
Offset = 0x24a0;
break;
case PPC_IRQ_CPM_PC9:
Offset = 0x24b0;
break;
case PPC_IRQ_CPM_TIMER3:
Offset = 0x24c0;
break;
case PPC_IRQ_CPM_RESERVED_D:
Offset = 0x24d0;
break;
case PPC_IRQ_CPM_PC10:
Offset = 0x24e0;
break;
case PPC_IRQ_CPM_PC11:
Offset = 0x24f0;
break;
case PPC_IRQ_CPM_I2C:
Offset = 0x2500;
break;
case PPC_IRQ_CPM_RISC_TIMER:
Offset = 0x2510;
break;
case PPC_IRQ_CPM_TIMER2:
Offset = 0x2520;
break;
case PPC_IRQ_CPM_RESERVED_13:
Offset = 0x2530;
break;
case PPC_IRQ_CPM_IDMA2:
Offset = 0x2540;
break;
case PPC_IRQ_CPM_IDMA1:
Offset = 0x2550;
break;
case PPC_IRQ_CPM_SDMA_ERROR:
Offset = 0x2560;
break;
case PPC_IRQ_CPM_PC12:
Offset = 0x2570;
break;
case PPC_IRQ_CPM_PC13:
Offset = 0x2580;
break;
case PPC_IRQ_CPM_TIMER1:
Offset = 0x2590;
break;
case PPC_IRQ_CPM_PC14:
Offset = 0x25a0;
break;
case PPC_IRQ_CPM_SCC4:
Offset = 0x25b0;
break;
case PPC_IRQ_CPM_SCC3:
Offset = 0x25c0;
break;
case PPC_IRQ_CPM_SCC2:
Offset = 0x25d0;
break;
case PPC_IRQ_CPM_SCC1:
Offset = 0x25e0;
break;
case PPC_IRQ_CPM_PC15:
Offset = 0x25f0;
break;
#endif
}
Top += Offset;
return Top;
}
/*PAGE
*
* This is the PowerPC specific implementation of the routine which
* returns TRUE if an interrupt is in progress.
*
* NOTE: This is the same as the generic version. But since the
* PowerPC is still supporting old and new exception processing
* models and the new exception processing model has a hardware
* way of doing this, we have to provide this capability here
* for symmetry.
*/
boolean _ISR_Is_in_progress( void )
{
return (_ISR_Nest_level != 0);
}

View File

@@ -1,653 +0,0 @@
/* cpu_asm.s 1.1 - 95/12/04
*
* This file contains the assembly code for the PowerPC implementation
* of RTEMS.
*
* Author: Andrew Bray <andy@i-cubed.co.uk>
*
* COPYRIGHT (c) 1995 by i-cubed ltd.
*
* To anyone who acknowledges that this file is provided "AS IS"
* without any express or implied warranty:
* permission to use, copy, modify, and distribute this file
* for any purpose is hereby granted without fee, provided that
* the above copyright notice and this notice appears in all
* copies, and that the name of i-cubed limited not be used in
* advertising or publicity pertaining to distribution of the
* software without specific, written prior permission.
* i-cubed limited makes no representations about the suitability
* of this software for any purpose.
*
* Derived from c/src/exec/cpu/no_cpu/cpu_asm.c:
*
* COPYRIGHT (c) 1989-1997.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may in
* the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
* $Id$
*/
/*
* FIXME: This file is bsp-dependent.
*/
#include <bspopts.h>
#include <asm.h>
#include <rtems/score/ppc_offs.h>
BEGIN_CODE
/*
* _CPU_Context_save_fp_context
*
* This routine is responsible for saving the FP context
* at *fp_context_ptr. If the point to load the FP context
* from is changed then the pointer is modified by this routine.
*
* Sometimes a macro implementation of this is in cpu.h which dereferences
* the ** and a similarly named routine in this file is passed something
* like a (Context_Control_fp *). The general rule on making this decision
* is to avoid writing assembly language.
*/
ALIGN (PPC_CACHE_ALIGNMENT, PPC_CACHE_ALIGN_POWER)
PUBLIC_PROC (_CPU_Context_save_fp)
PROC (_CPU_Context_save_fp):
#if (PPC_HAS_FPU == 1)
lwz r3, 0(r3)
#if (PPC_HAS_DOUBLE == 1)
stfd f0, FP_0(r3)
stfd f1, FP_1(r3)
stfd f2, FP_2(r3)
stfd f3, FP_3(r3)
stfd f4, FP_4(r3)
stfd f5, FP_5(r3)
stfd f6, FP_6(r3)
stfd f7, FP_7(r3)
stfd f8, FP_8(r3)
stfd f9, FP_9(r3)
stfd f10, FP_10(r3)
stfd f11, FP_11(r3)
stfd f12, FP_12(r3)
stfd f13, FP_13(r3)
stfd f14, FP_14(r3)
stfd f15, FP_15(r3)
stfd f16, FP_16(r3)
stfd f17, FP_17(r3)
stfd f18, FP_18(r3)
stfd f19, FP_19(r3)
stfd f20, FP_20(r3)
stfd f21, FP_21(r3)
stfd f22, FP_22(r3)
stfd f23, FP_23(r3)
stfd f24, FP_24(r3)
stfd f25, FP_25(r3)
stfd f26, FP_26(r3)
stfd f27, FP_27(r3)
stfd f28, FP_28(r3)
stfd f29, FP_29(r3)
stfd f30, FP_30(r3)
stfd f31, FP_31(r3)
mffs f2
stfd f2, FP_FPSCR(r3)
#else
stfs f0, FP_0(r3)
stfs f1, FP_1(r3)
stfs f2, FP_2(r3)
stfs f3, FP_3(r3)
stfs f4, FP_4(r3)
stfs f5, FP_5(r3)
stfs f6, FP_6(r3)
stfs f7, FP_7(r3)
stfs f8, FP_8(r3)
stfs f9, FP_9(r3)
stfs f10, FP_10(r3)
stfs f11, FP_11(r3)
stfs f12, FP_12(r3)
stfs f13, FP_13(r3)
stfs f14, FP_14(r3)
stfs f15, FP_15(r3)
stfs f16, FP_16(r3)
stfs f17, FP_17(r3)
stfs f18, FP_18(r3)
stfs f19, FP_19(r3)
stfs f20, FP_20(r3)
stfs f21, FP_21(r3)
stfs f22, FP_22(r3)
stfs f23, FP_23(r3)
stfs f24, FP_24(r3)
stfs f25, FP_25(r3)
stfs f26, FP_26(r3)
stfs f27, FP_27(r3)
stfs f28, FP_28(r3)
stfs f29, FP_29(r3)
stfs f30, FP_30(r3)
stfs f31, FP_31(r3)
mffs f2
stfs f2, FP_FPSCR(r3)
#endif
#endif
blr
/*
* _CPU_Context_restore_fp_context
*
* This routine is responsible for restoring the FP context
* at *fp_context_ptr. If the point to load the FP context
* from is changed then the pointer is modified by this routine.
*
* Sometimes a macro implementation of this is in cpu.h which dereferences
* the ** and a similarly named routine in this file is passed something
* like a (Context_Control_fp *). The general rule on making this decision
* is to avoid writing assembly language.
*/
ALIGN (PPC_CACHE_ALIGNMENT, PPC_CACHE_ALIGN_POWER)
PUBLIC_PROC (_CPU_Context_restore_fp)
PROC (_CPU_Context_restore_fp):
#if (PPC_HAS_FPU == 1)
lwz r3, 0(r3)
#if (PPC_HAS_DOUBLE == 1)
lfd f2, FP_FPSCR(r3)
mtfsf 255, f2
lfd f0, FP_0(r3)
lfd f1, FP_1(r3)
lfd f2, FP_2(r3)
lfd f3, FP_3(r3)
lfd f4, FP_4(r3)
lfd f5, FP_5(r3)
lfd f6, FP_6(r3)
lfd f7, FP_7(r3)
lfd f8, FP_8(r3)
lfd f9, FP_9(r3)
lfd f10, FP_10(r3)
lfd f11, FP_11(r3)
lfd f12, FP_12(r3)
lfd f13, FP_13(r3)
lfd f14, FP_14(r3)
lfd f15, FP_15(r3)
lfd f16, FP_16(r3)
lfd f17, FP_17(r3)
lfd f18, FP_18(r3)
lfd f19, FP_19(r3)
lfd f20, FP_20(r3)
lfd f21, FP_21(r3)
lfd f22, FP_22(r3)
lfd f23, FP_23(r3)
lfd f24, FP_24(r3)
lfd f25, FP_25(r3)
lfd f26, FP_26(r3)
lfd f27, FP_27(r3)
lfd f28, FP_28(r3)
lfd f29, FP_29(r3)
lfd f30, FP_30(r3)
lfd f31, FP_31(r3)
#else
lfs f2, FP_FPSCR(r3)
mtfsf 255, f2
lfs f0, FP_0(r3)
lfs f1, FP_1(r3)
lfs f2, FP_2(r3)
lfs f3, FP_3(r3)
lfs f4, FP_4(r3)
lfs f5, FP_5(r3)
lfs f6, FP_6(r3)
lfs f7, FP_7(r3)
lfs f8, FP_8(r3)
lfs f9, FP_9(r3)
lfs f10, FP_10(r3)
lfs f11, FP_11(r3)
lfs f12, FP_12(r3)
lfs f13, FP_13(r3)
lfs f14, FP_14(r3)
lfs f15, FP_15(r3)
lfs f16, FP_16(r3)
lfs f17, FP_17(r3)
lfs f18, FP_18(r3)
lfs f19, FP_19(r3)
lfs f20, FP_20(r3)
lfs f21, FP_21(r3)
lfs f22, FP_22(r3)
lfs f23, FP_23(r3)
lfs f24, FP_24(r3)
lfs f25, FP_25(r3)
lfs f26, FP_26(r3)
lfs f27, FP_27(r3)
lfs f28, FP_28(r3)
lfs f29, FP_29(r3)
lfs f30, FP_30(r3)
lfs f31, FP_31(r3)
#endif
#endif
blr
/* _CPU_Context_switch
*
* This routine performs a normal non-FP context switch.
*/
ALIGN (PPC_CACHE_ALIGNMENT, PPC_CACHE_ALIGN_POWER)
PUBLIC_PROC (_CPU_Context_switch)
PROC (_CPU_Context_switch):
sync
isync
#if (PPC_CACHE_ALIGNMENT == 4) /* No cache */
stw r1, GP_1(r3)
lwz r1, GP_1(r4)
stw r2, GP_2(r3)
lwz r2, GP_2(r4)
#if (PPC_USE_MULTIPLE == 1)
stmw r13, GP_13(r3)
lmw r13, GP_13(r4)
#else
stw r13, GP_13(r3)
lwz r13, GP_13(r4)
stw r14, GP_14(r3)
lwz r14, GP_14(r4)
stw r15, GP_15(r3)
lwz r15, GP_15(r4)
stw r16, GP_16(r3)
lwz r16, GP_16(r4)
stw r17, GP_17(r3)
lwz r17, GP_17(r4)
stw r18, GP_18(r3)
lwz r18, GP_18(r4)
stw r19, GP_19(r3)
lwz r19, GP_19(r4)
stw r20, GP_20(r3)
lwz r20, GP_20(r4)
stw r21, GP_21(r3)
lwz r21, GP_21(r4)
stw r22, GP_22(r3)
lwz r22, GP_22(r4)
stw r23, GP_23(r3)
lwz r23, GP_23(r4)
stw r24, GP_24(r3)
lwz r24, GP_24(r4)
stw r25, GP_25(r3)
lwz r25, GP_25(r4)
stw r26, GP_26(r3)
lwz r26, GP_26(r4)
stw r27, GP_27(r3)
lwz r27, GP_27(r4)
stw r28, GP_28(r3)
lwz r28, GP_28(r4)
stw r29, GP_29(r3)
lwz r29, GP_29(r4)
stw r30, GP_30(r3)
lwz r30, GP_30(r4)
stw r31, GP_31(r3)
lwz r31, GP_31(r4)
#endif
mfcr r5
stw r5, GP_CR(r3)
lwz r5, GP_CR(r4)
mflr r6
mtcrf 255, r5
stw r6, GP_PC(r3)
lwz r6, GP_PC(r4)
mfmsr r7
mtlr r6
stw r7, GP_MSR(r3)
lwz r7, GP_MSR(r4)
mtmsr r7
#endif
#if (PPC_CACHE_ALIGNMENT == 16)
/* This assumes that all the registers are in the given order */
li r5, 16
addi r3,r3,-4
#if ( PPC_USE_DATA_CACHE )
dcbz r5, r3
#endif
stw r1, GP_1+4(r3)
stw r2, GP_2+4(r3)
#if (PPC_USE_MULTIPLE == 1)
addi r3, r3, GP_14+4
#if ( PPC_USE_DATA_CACHE )
dcbz r5, r3
#endif
addi r3, r3, GP_18-GP_14
#if ( PPC_USE_DATA_CACHE )
dcbz r5, r3
#endif
addi r3, r3, GP_22-GP_18
#if ( PPC_USE_DATA_CACHE )
dcbz r5, r3
#endif
addi r3, r3, GP_26-GP_22
#if ( PPC_USE_DATA_CACHE )
dcbz r5, r3
#endif
stmw r13, GP_13-GP_26(r3)
#else
stw r13, GP_13+4(r3)
stwu r14, GP_14+4(r3)
#if ( PPC_USE_DATA_CACHE )
dcbz r5, r3
#endif
stw r15, GP_15-GP_14(r3)
stw r16, GP_16-GP_14(r3)
stw r17, GP_17-GP_14(r3)
stwu r18, GP_18-GP_14(r3)
#if ( PPC_USE_DATA_CACHE )
dcbz r5, r3
#endif
stw r19, GP_19-GP_18(r3)
stw r20, GP_20-GP_18(r3)
stw r21, GP_21-GP_18(r3)
stwu r22, GP_22-GP_18(r3)
#if ( PPC_USE_DATA_CACHE )
dcbz r5, r3
#endif
stw r23, GP_23-GP_22(r3)
stw r24, GP_24-GP_22(r3)
stw r25, GP_25-GP_22(r3)
stwu r26, GP_26-GP_22(r3)
#if ( PPC_USE_DATA_CACHE )
dcbz r5, r3
#endif
stw r27, GP_27-GP_26(r3)
stw r28, GP_28-GP_26(r3)
stw r29, GP_29-GP_26(r3)
stw r30, GP_30-GP_26(r3)
stw r31, GP_31-GP_26(r3)
#endif
#if ( PPC_USE_DATA_CACHE )
dcbt r0, r4
#endif
mfcr r6
stw r6, GP_CR-GP_26(r3)
mflr r7
stw r7, GP_PC-GP_26(r3)
mfmsr r8
stw r8, GP_MSR-GP_26(r3)
#if ( PPC_USE_DATA_CACHE )
dcbt r5, r4
#endif
lwz r1, GP_1(r4)
lwz r2, GP_2(r4)
#if (PPC_USE_MULTIPLE == 1)
addi r4, r4, GP_15
#if ( PPC_USE_DATA_CACHE )
dcbt r5, r4
#endif
addi r4, r4, GP_19-GP_15
#if ( PPC_USE_DATA_CACHE )
dcbt r5, r4
#endif
addi r4, r4, GP_23-GP_19
#if ( PPC_USE_DATA_CACHE )
dcbt r5, r4
#endif
addi r4, r4, GP_27-GP_23
#if ( PPC_USE_DATA_CACHE )
dcbt r5, r4
#endif
lmw r13, GP_13-GP_27(r4)
#else
lwz r13, GP_13(r4)
lwz r14, GP_14(r4)
lwzu r15, GP_15(r4)
#if ( PPC_USE_DATA_CACHE )
dcbt r5, r4
#endif
lwz r16, GP_16-GP_15(r4)
lwz r17, GP_17-GP_15(r4)
lwz r18, GP_18-GP_15(r4)
lwzu r19, GP_19-GP_15(r4)
#if ( PPC_USE_DATA_CACHE )
dcbt r5, r4
#endif
lwz r20, GP_20-GP_19(r4)
lwz r21, GP_21-GP_19(r4)
lwz r22, GP_22-GP_19(r4)
lwzu r23, GP_23-GP_19(r4)
#if ( PPC_USE_DATA_CACHE )
dcbt r5, r4
#endif
lwz r24, GP_24-GP_23(r4)
lwz r25, GP_25-GP_23(r4)
lwz r26, GP_26-GP_23(r4)
lwzu r27, GP_27-GP_23(r4)
#if ( PPC_USE_DATA_CACHE )
dcbt r5, r4
#endif
lwz r28, GP_28-GP_27(r4)
lwz r29, GP_29-GP_27(r4)
lwz r30, GP_30-GP_27(r4)
lwz r31, GP_31-GP_27(r4)
#endif
lwz r6, GP_CR-GP_27(r4)
lwz r7, GP_PC-GP_27(r4)
lwz r8, GP_MSR-GP_27(r4)
mtcrf 255, r6
mtlr r7
mtmsr r8
#endif
#if (PPC_CACHE_ALIGNMENT == 32)
/* This assumes that all the registers are in the given order */
li r5, 32
addi r3,r3,-4
#if ( PPC_USE_DATA_CACHE )
dcbz r5, r3
#endif
stw r1, GP_1+4(r3)
stw r2, GP_2+4(r3)
#if (PPC_USE_MULTIPLE == 1)
addi r3, r3, GP_18+4
#if ( PPC_USE_DATA_CACHE )
dcbz r5, r3
#endif
stmw r13, GP_13-GP_18(r3)
#else
stw r13, GP_13+4(r3)
stw r14, GP_14+4(r3)
stw r15, GP_15+4(r3)
stw r16, GP_16+4(r3)
stw r17, GP_17+4(r3)
stwu r18, GP_18+4(r3)
#if ( PPC_USE_DATA_CACHE )
dcbz r5, r3
#endif
stw r19, GP_19-GP_18(r3)
stw r20, GP_20-GP_18(r3)
stw r21, GP_21-GP_18(r3)
stw r22, GP_22-GP_18(r3)
stw r23, GP_23-GP_18(r3)
stw r24, GP_24-GP_18(r3)
stw r25, GP_25-GP_18(r3)
stw r26, GP_26-GP_18(r3)
stw r27, GP_27-GP_18(r3)
stw r28, GP_28-GP_18(r3)
stw r29, GP_29-GP_18(r3)
stw r30, GP_30-GP_18(r3)
stw r31, GP_31-GP_18(r3)
#endif
#if ( PPC_USE_DATA_CACHE )
dcbt r0, r4
#endif
mfcr r6
stw r6, GP_CR-GP_18(r3)
mflr r7
stw r7, GP_PC-GP_18(r3)
mfmsr r8
stw r8, GP_MSR-GP_18(r3)
#if ( PPC_USE_DATA_CACHE )
dcbt r5, r4
#endif
lwz r1, GP_1(r4)
lwz r2, GP_2(r4)
#if (PPC_USE_MULTIPLE == 1)
addi r4, r4, GP_19
#if ( PPC_USE_DATA_CACHE )
dcbt r5, r4
#endif
lmw r13, GP_13-GP_19(r4)
#else
lwz r13, GP_13(r4)
lwz r14, GP_14(r4)
lwz r15, GP_15(r4)
lwz r16, GP_16(r4)
lwz r17, GP_17(r4)
lwz r18, GP_18(r4)
lwzu r19, GP_19(r4)
#if ( PPC_USE_DATA_CACHE )
dcbt r5, r4
#endif
lwz r20, GP_20-GP_19(r4)
lwz r21, GP_21-GP_19(r4)
lwz r22, GP_22-GP_19(r4)
lwz r23, GP_23-GP_19(r4)
lwz r24, GP_24-GP_19(r4)
lwz r25, GP_25-GP_19(r4)
lwz r26, GP_26-GP_19(r4)
lwz r27, GP_27-GP_19(r4)
lwz r28, GP_28-GP_19(r4)
lwz r29, GP_29-GP_19(r4)
lwz r30, GP_30-GP_19(r4)
lwz r31, GP_31-GP_19(r4)
#endif
lwz r6, GP_CR-GP_19(r4)
lwz r7, GP_PC-GP_19(r4)
lwz r8, GP_MSR-GP_19(r4)
mtcrf 255, r6
mtlr r7
mtmsr r8
#endif
blr
/*
* _CPU_Context_restore
*
* This routine is generallu used only to restart self in an
* efficient manner. It may simply be a label in _CPU_Context_switch.
*
* NOTE: May be unnecessary to reload some registers.
*/
/*
* ACB: Don't worry about cache optimisation here - this is not THAT critical.
*/
ALIGN (PPC_CACHE_ALIGNMENT, PPC_CACHE_ALIGN_POWER)
PUBLIC_PROC (_CPU_Context_restore)
PROC (_CPU_Context_restore):
lwz r5, GP_CR(r3)
lwz r6, GP_PC(r3)
lwz r7, GP_MSR(r3)
mtcrf 255, r5
mtlr r6
mtmsr r7
lwz r1, GP_1(r3)
lwz r2, GP_2(r3)
#if (PPC_USE_MULTIPLE == 1)
lmw r13, GP_13(r3)
#else
lwz r13, GP_13(r3)
lwz r14, GP_14(r3)
lwz r15, GP_15(r3)
lwz r16, GP_16(r3)
lwz r17, GP_17(r3)
lwz r18, GP_18(r3)
lwz r19, GP_19(r3)
lwz r20, GP_20(r3)
lwz r21, GP_21(r3)
lwz r22, GP_22(r3)
lwz r23, GP_23(r3)
lwz r24, GP_24(r3)
lwz r25, GP_25(r3)
lwz r26, GP_26(r3)
lwz r27, GP_27(r3)
lwz r28, GP_28(r3)
lwz r29, GP_29(r3)
lwz r30, GP_30(r3)
lwz r31, GP_31(r3)
#endif
blr
/* Individual interrupt prologues look like this:
* #if (PPC_ABI == PPC_ABI_POWEROPEN || PPC_ABI == PPC_ABI_GCC27)
* #if (PPC_HAS_FPU)
* stwu r1, -(20*4 + 18*8 + IP_END)(r1)
* #else
* stwu r1, -(20*4 + IP_END)(r1)
* #endif
* #else
* stwu r1, -(IP_END)(r1)
* #endif
* stw r0, IP_0(r1)
*
* li r0, vectornum
* b PROC (_ISR_Handler{,C})
*/
/* void __ISR_Handler()
*
* This routine provides the RTEMS interrupt management.
* The vector number is in r0. R0 has already been stacked.
*
*/
ALIGN (PPC_CACHE_ALIGNMENT, PPC_CACHE_ALIGN_POWER)
PUBLIC_PROC (_ISR_Handler)
PROC (_ISR_Handler):
#define LABEL(x) x
/* XXX ??
#define MTSAVE(x) mtspr sprg0, x
#define MFSAVE(x) mfspr x, sprg0
*/
#define MTPC(x) mtspr srr0, x
#define MFPC(x) mfspr x, srr0
#define MTMSR(x) mtspr srr1, x
#define MFMSR(x) mfspr x, srr1
#include "irq_stub.S"
rfi
#if (PPC_HAS_RFCI == 1)
/* void __ISR_HandlerC()
*
* This routine provides the RTEMS interrupt management.
* For critical interrupts
*
*/
ALIGN (PPC_CACHE_ALIGNMENT, PPC_CACHE_ALIGN_POWER)
PUBLIC_PROC (_ISR_HandlerC)
PROC (_ISR_HandlerC):
#undef LABEL
#undef MTSAVE
#undef MFSAVE
#undef MTPC
#undef MFPC
#undef MTMSR
#undef MFMSR
#define LABEL(x) x##_C
/* XXX??
#define MTSAVE(x) mtspr sprg1, x
#define MFSAVE(x) mfspr x, sprg1
*/
#define MTPC(x) mtspr srr2, x
#define MFPC(x) mfspr x, srr2
#define MTMSR(x) mtspr srr3, x
#define MFMSR(x) mfspr x, srr3
#include "irq_stub.S"
rfci
#endif
/* PowerOpen descriptors for indirect function calls.
*/
#if (PPC_ABI == PPC_ABI_POWEROPEN)
DESCRIPTOR (_CPU_Context_save_fp)
DESCRIPTOR (_CPU_Context_restore_fp)
DESCRIPTOR (_CPU_Context_switch)
DESCRIPTOR (_CPU_Context_restore)
DESCRIPTOR (_ISR_Handler)
#if (PPC_HAS_RFCI == 1)
DESCRIPTOR (_ISR_HandlerC)
#endif
#endif

View File

@@ -1,275 +0,0 @@
/*
* This file contains the interrupt handler assembly code for the PowerPC
* implementation of RTEMS. It is #included from cpu_asm.s.
*
* Author: Andrew Bray <andy@i-cubed.co.uk>
*
* COPYRIGHT (c) 1995 by i-cubed ltd.
*
* To anyone who acknowledges that this file is provided "AS IS"
* without any express or implied warranty:
* permission to use, copy, modify, and distribute this file
* for any purpose is hereby granted without fee, provided that
* the above copyright notice and this notice appears in all
* copies, and that the name of i-cubed limited not be used in
* advertising or publicity pertaining to distribution of the
* software without specific, written prior permission.
* i-cubed limited makes no representations about the suitability
* of this software for any purpose.
*
* $Id$
*/
/*
* FIXME: this file is bsp dependent.
*/
#include <bspopts.h>
/* void __ISR_Handler()
*
* This routine provides the RTEMS interrupt management.
* The vector number is in r0. R0 has already been stacked.
*
*/
PUBLIC_VAR (_CPU_IRQ_info )
/* Finish off the interrupt frame */
stw r2, IP_2(r1)
stw r3, IP_3(r1)
stw r4, IP_4(r1)
stw r5, IP_5(r1)
stw r6, IP_6(r1)
stw r7, IP_7(r1)
stw r8, IP_8(r1)
stw r9, IP_9(r1)
stw r10, IP_10(r1)
stw r11, IP_11(r1)
stw r12, IP_12(r1)
stw r13, IP_13(r1)
stmw r28, IP_28(r1)
mfcr r5
mfctr r6
mfxer r7
mflr r8
MFPC (r9)
MFMSR (r10)
/* Establish addressing */
#if (PPC_USE_SPRG)
mfspr r11, sprg3
#else
lis r11,_CPU_IRQ_info@ha
addi r11,r11,_CPU_IRQ_info@l
#endif
#if ( PPC_USE_DATA_CACHE )
dcbt r0, r11
#endif
stw r5, IP_CR(r1)
stw r6, IP_CTR(r1)
stw r7, IP_XER(r1)
stw r8, IP_LR(r1)
stw r9, IP_PC(r1)
stw r10, IP_MSR(r1)
lwz r30, Vector_table(r11)
slwi r4,r0,2
lwz r28, Nest_level(r11)
add r4, r4, r30
lwz r30, 0(r28)
mr r3, r0
lwz r31, Stack(r11)
/*
* #if ( CPU_HAS_SOFTWARE_INTERRUPT_STACK == TRUE )
* if ( _ISR_Nest_level == 0 )
* switch to software interrupt stack
* #endif
*/
/* Switch stacks, here we must prevent ALL interrupts */
#if (PPC_USE_SPRG)
mfmsr r5
mfspr r6, sprg2
#else
lwz r6,msr_initial(r11)
lis r5,~PPC_MSR_DISABLE_MASK@ha
ori r5,r5,~PPC_MSR_DISABLE_MASK@l
and r6,r6,r5
mfmsr r5
#endif
mtmsr r6
cmpwi r30, 0
lwz r29, Disable_level(r11)
subf r31,r1,r31
bne LABEL (nested)
stwux r1,r1,r31
LABEL (nested):
/*
* _ISR_Nest_level++;
*/
lwz r31, 0(r29)
addi r30,r30,1
stw r30,0(r28)
/* From here on out, interrupts can be re-enabled. RTEMS
* convention says not.
*/
lwz r4,0(r4)
/*
* _Thread_Dispatch_disable_level++;
*/
addi r31,r31,1
stw r31, 0(r29)
/* SCE 980217
*
* We need address translation ON when we call our ISR routine
mtmsr r5
*/
/*
* (*_ISR_Vector_table[ vector ])( vector );
*/
#if (PPC_ABI == PPC_ABI_POWEROPEN)
lwz r6,0(r4)
lwz r2,4(r4)
mtlr r6
lwz r11,8(r4)
#endif
#if (PPC_ABI == PPC_ABI_GCC27)
lwz r2, Default_r2(r11)
mtlr r4
#lwz r2, 0(r2)
#endif
#if (PPC_ABI == PPC_ABI_SVR4 || PPC_ABI == PPC_ABI_EABI)
mtlr r4
lwz r2, Default_r2(r11)
lwz r13, Default_r13(r11)
#lwz r2, 0(r2)
#lwz r13, 0(r13)
#endif
mr r4,r1
blrl
/* NOP marker for debuggers */
or r6,r6,r6
/* We must re-disable the interrupts */
#if (PPC_USE_SPRG)
mfspr r11, sprg3
mfspr r0, sprg2
#else
lis r11,_CPU_IRQ_info@ha
addi r11,r11,_CPU_IRQ_info@l
lwz r0,msr_initial(r11)
lis r30,~PPC_MSR_DISABLE_MASK@ha
ori r30,r30,~PPC_MSR_DISABLE_MASK@l
and r0,r0,r30
#endif
mtmsr r0
lwz r30, 0(r28)
lwz r31, 0(r29)
/*
* if (--Thread_Dispatch_disable,--_ISR_Nest_level)
* goto easy_exit;
*/
addi r30, r30, -1
cmpwi r30, 0
addi r31, r31, -1
stw r30, 0(r28)
stw r31, 0(r29)
bne LABEL (easy_exit)
cmpwi r31, 0
lwz r30, Switch_necessary(r11)
/*
* #if ( CPU_HAS_SOFTWARE_INTERRUPT_STACK == TRUE )
* restore stack
* #endif
*/
lwz r1,0(r1)
bne LABEL (easy_exit)
lwz r30, 0(r30)
lwz r31, Signal(r11)
/*
* if ( _Context_Switch_necessary )
* goto switch
*/
cmpwi r30, 0
lwz r28, 0(r31)
li r6,0
bne LABEL (switch)
/*
* if ( !_ISR_Signals_to_thread_executing )
* goto easy_exit
* _ISR_Signals_to_thread_executing = 0;
*/
cmpwi r28, 0
beq LABEL (easy_exit)
/*
* switch:
* call _Thread_Dispatch() or prepare to return to _ISR_Dispatch
*/
LABEL (switch):
stw r6, 0(r31)
/* Re-enable interrupts */
lwz r0, IP_MSR(r1)
#if (PPC_ABI == PPC_ABI_POWEROPEN)
lwz r2, Dispatch_r2(r11)
#else
/* R2 and R13 still hold their values from the last call */
#endif
mtmsr r0
bl SYM (_Thread_Dispatch)
/* NOP marker for debuggers */
or r6,r6,r6
/*
* prepare to get out of interrupt
*/
/* Re-disable IRQs */
#if (PPC_USE_SPRG)
mfspr r0, sprg2
#else
lis r11,_CPU_IRQ_info@ha
addi r11,r11,_CPU_IRQ_info@l
lwz r0,msr_initial(r11)
lis r5,~PPC_MSR_DISABLE_MASK@ha
ori r5,r5,~PPC_MSR_DISABLE_MASK@l
and r0,r0,r5
#endif
mtmsr r0
/*
* easy_exit:
* prepare to get out of interrupt
* return from interrupt
*/
LABEL (easy_exit):
lwz r5, IP_CR(r1)
lwz r6, IP_CTR(r1)
lwz r7, IP_XER(r1)
lwz r8, IP_LR(r1)
lwz r9, IP_PC(r1)
lwz r10, IP_MSR(r1)
mtcrf 255,r5
mtctr r6
mtxer r7
mtlr r8
MTPC (r9)
MTMSR (r10)
lwz r0, IP_0(r1)
lwz r2, IP_2(r1)
lwz r3, IP_3(r1)
lwz r4, IP_4(r1)
lwz r5, IP_5(r1)
lwz r6, IP_6(r1)
lwz r7, IP_7(r1)
lwz r8, IP_8(r1)
lwz r9, IP_9(r1)
lwz r10, IP_10(r1)
lwz r11, IP_11(r1)
lwz r12, IP_12(r1)
lwz r13, IP_13(r1)
lmw r28, IP_28(r1)
lwz r1, 0(r1)

View File

@@ -1,61 +0,0 @@
/*
* PowerPC Cache enable routines
*
* $Id$
*/
#include <rtems/system.h>
#define PPC_Get_HID0( _value ) \
do { \
_value = 0; /* to avoid warnings */ \
asm volatile( \
"mfspr %0, 0x3f0;" /* get HID0 */ \
"isync" \
: "=r" (_value) \
: "0" (_value) \
); \
} while (0)
#define PPC_Set_HID0( _value ) \
do { \
asm volatile( \
"isync;" \
"mtspr 0x3f0, %0;" /* load HID0 */ \
"isync" \
: "=r" (_value) \
: "0" (_value) \
); \
} while (0)
void powerpc_instruction_cache_enable ()
{
unsigned32 value;
/*
* Enable the instruction cache
*/
PPC_Get_HID0( value );
value |= 0x00008000; /* Set ICE bit */
PPC_Set_HID0( value );
}
void powerpc_data_cache_enable ()
{
unsigned32 value;
/*
* enable data cache
*/
PPC_Get_HID0( value );
value |= 0x00004000; /* set DCE bit */
PPC_Set_HID0( value );
}

View File

@@ -1,166 +0,0 @@
/* -*- asm -*- */
#ifndef __PPC_OFFS_H
#define __PPC_OFFS_H
/*
* Offsets for various Contexts
*/
.set GP_1, 0
.set GP_2, (GP_1 + 4)
.set GP_13, (GP_2 + 4)
.set GP_14, (GP_13 + 4)
.set GP_15, (GP_14 + 4)
.set GP_16, (GP_15 + 4)
.set GP_17, (GP_16 + 4)
.set GP_18, (GP_17 + 4)
.set GP_19, (GP_18 + 4)
.set GP_20, (GP_19 + 4)
.set GP_21, (GP_20 + 4)
.set GP_22, (GP_21 + 4)
.set GP_23, (GP_22 + 4)
.set GP_24, (GP_23 + 4)
.set GP_25, (GP_24 + 4)
.set GP_26, (GP_25 + 4)
.set GP_27, (GP_26 + 4)
.set GP_28, (GP_27 + 4)
.set GP_29, (GP_28 + 4)
.set GP_30, (GP_29 + 4)
.set GP_31, (GP_30 + 4)
.set GP_CR, (GP_31 + 4)
.set GP_PC, (GP_CR + 4)
.set GP_MSR, (GP_PC + 4)
#if (PPC_HAS_DOUBLE == 1)
.set FP_0, 0
.set FP_1, (FP_0 + 8)
.set FP_2, (FP_1 + 8)
.set FP_3, (FP_2 + 8)
.set FP_4, (FP_3 + 8)
.set FP_5, (FP_4 + 8)
.set FP_6, (FP_5 + 8)
.set FP_7, (FP_6 + 8)
.set FP_8, (FP_7 + 8)
.set FP_9, (FP_8 + 8)
.set FP_10, (FP_9 + 8)
.set FP_11, (FP_10 + 8)
.set FP_12, (FP_11 + 8)
.set FP_13, (FP_12 + 8)
.set FP_14, (FP_13 + 8)
.set FP_15, (FP_14 + 8)
.set FP_16, (FP_15 + 8)
.set FP_17, (FP_16 + 8)
.set FP_18, (FP_17 + 8)
.set FP_19, (FP_18 + 8)
.set FP_20, (FP_19 + 8)
.set FP_21, (FP_20 + 8)
.set FP_22, (FP_21 + 8)
.set FP_23, (FP_22 + 8)
.set FP_24, (FP_23 + 8)
.set FP_25, (FP_24 + 8)
.set FP_26, (FP_25 + 8)
.set FP_27, (FP_26 + 8)
.set FP_28, (FP_27 + 8)
.set FP_29, (FP_28 + 8)
.set FP_30, (FP_29 + 8)
.set FP_31, (FP_30 + 8)
.set FP_FPSCR, (FP_31 + 8)
#else
.set FP_0, 0
.set FP_1, (FP_0 + 4)
.set FP_2, (FP_1 + 4)
.set FP_3, (FP_2 + 4)
.set FP_4, (FP_3 + 4)
.set FP_5, (FP_4 + 4)
.set FP_6, (FP_5 + 4)
.set FP_7, (FP_6 + 4)
.set FP_8, (FP_7 + 4)
.set FP_9, (FP_8 + 4)
.set FP_10, (FP_9 + 4)
.set FP_11, (FP_10 + 4)
.set FP_12, (FP_11 + 4)
.set FP_13, (FP_12 + 4)
.set FP_14, (FP_13 + 4)
.set FP_15, (FP_14 + 4)
.set FP_16, (FP_15 + 4)
.set FP_17, (FP_16 + 4)
.set FP_18, (FP_17 + 4)
.set FP_19, (FP_18 + 4)
.set FP_20, (FP_19 + 4)
.set FP_21, (FP_20 + 4)
.set FP_22, (FP_21 + 4)
.set FP_23, (FP_22 + 4)
.set FP_24, (FP_23 + 4)
.set FP_25, (FP_24 + 4)
.set FP_26, (FP_25 + 4)
.set FP_27, (FP_26 + 4)
.set FP_28, (FP_27 + 4)
.set FP_29, (FP_28 + 4)
.set FP_30, (FP_29 + 4)
.set FP_31, (FP_30 + 4)
.set FP_FPSCR, (FP_31 + 4)
#endif
.set IP_LINK, 0
#if (PPC_ABI == PPC_ABI_POWEROPEN || PPC_ABI == PPC_ABI_GCC27)
.set IP_0, (IP_LINK + 56)
#else
.set IP_0, (IP_LINK + 8)
#endif
.set IP_2, (IP_0 + 4)
.set IP_3, (IP_2 + 4)
.set IP_4, (IP_3 + 4)
.set IP_5, (IP_4 + 4)
.set IP_6, (IP_5 + 4)
.set IP_7, (IP_6 + 4)
.set IP_8, (IP_7 + 4)
.set IP_9, (IP_8 + 4)
.set IP_10, (IP_9 + 4)
.set IP_11, (IP_10 + 4)
.set IP_12, (IP_11 + 4)
.set IP_13, (IP_12 + 4)
.set IP_28, (IP_13 + 4)
.set IP_29, (IP_28 + 4)
.set IP_30, (IP_29 + 4)
.set IP_31, (IP_30 + 4)
.set IP_CR, (IP_31 + 4)
.set IP_CTR, (IP_CR + 4)
.set IP_XER, (IP_CTR + 4)
.set IP_LR, (IP_XER + 4)
.set IP_PC, (IP_LR + 4)
.set IP_MSR, (IP_PC + 4)
.set IP_END, (IP_MSR + 16)
/* _CPU_IRQ_info offsets */
/* These must be in this order */
.set Nest_level, 0
.set Disable_level, 4
.set Vector_table, 8
.set Stack, 12
#if (PPC_ABI == PPC_ABI_POWEROPEN)
.set Dispatch_r2, 16
.set Switch_necessary, 20
#else
.set Default_r2, 16
#if (PPC_ABI != PPC_ABI_GCC27)
.set Default_r13, 20
.set Switch_necessary, 24
#else
.set Switch_necessary, 20
#endif
#endif
.set Signal, Switch_necessary + 4
.set msr_initial, Signal + 4
#endif /* __PPC_OFFS_H */

View File

@@ -1,2 +0,0 @@
Makefile
Makefile.in

View File

@@ -1,9 +0,0 @@
#
# $Id$
#
The mpci.h file provided in here is too simple for an MPCI with
multiple ways to get to a node.
This version of the shm driver needs to be reorganized to follow
the better model of the Ada version.

View File

@@ -1,42 +0,0 @@
/* void Shm_Locked_queue_Add( lq_cb, ecb )
*
* This routine adds an envelope control block to a shared memory queue.
*
* Input parameters:
* lq_cb - pointer to a locked queue control block
* ecb - pointer to an envelope control block
*
* Output parameters: NONE
*
* COPYRIGHT (c) 1989-1999.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
* $Id$
*/
#include <rtems.h>
#include "shm_driver.h"
void Shm_Locked_queue_Add(
Shm_Locked_queue_Control *lq_cb,
Shm_Envelope_control *ecb
)
{
rtems_unsigned32 index;
ecb->next = Shm_Locked_queue_End_of_list;
ecb->queue = lq_cb->owner;
index = ecb->index;
Shm_Lock( lq_cb );
if ( Shm_Convert(lq_cb->front) != Shm_Locked_queue_End_of_list )
Shm_Envelopes[ Shm_Convert(lq_cb->rear) ].next = index;
else
lq_cb->front = index;
lq_cb->rear = index;
Shm_Unlock( lq_cb );
}

View File

@@ -1,41 +0,0 @@
/* void Shm_Convert_packet( &packet )
*
* This routine is the shared memory locked queue MPCI driver routine
* used to convert the RTEMS's information in a packet from non-native
* format to processor native format.
*
* Input parameters:
* packet - pointer to a packet
*
* Output parameters:
* *packet - packet in native format
*
* NOTE: Message buffers are not manipulated.
* Endian conversion is currently the only conversion.
*
* COPYRIGHT (c) 1989-1999.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
* $Id$
*/
#include <rtems.h>
#include "shm_driver.h"
void Shm_Convert_packet(
rtems_packet_prefix *packet
)
{
rtems_unsigned32 *pkt, i;
pkt = (rtems_unsigned32 *) packet;
for ( i=RTEMS_MINIMUN_HETERO_CONVERSION ; i ; i--, pkt++ )
*pkt = CPU_swap_u32( *pkt );
for ( i=packet->to_convert ; i ; i--, pkt++ )
*pkt = CPU_swap_u32( *pkt );
}

View File

@@ -1,50 +0,0 @@
/*
* This routine is invoked following a reset to report the statistics
* gathered during the previous execution.
*
* Input parameters: NONE
*
* Output parameters: NONE
*
* COPYRIGHT (c) 1989-1999.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
* $Id$
*/
#include <rtems.h>
#include <stdio.h>
#include "shm_driver.h"
void
Shm_Print_statistics(void)
{
rtems_unsigned32 ticks;
rtems_unsigned32 ticks_per_second;
rtems_unsigned32 seconds;
int packets_per_second;
(void) rtems_clock_get( RTEMS_CLOCK_GET_TICKS_SINCE_BOOT, &ticks );
(void) rtems_clock_get( RTEMS_CLOCK_GET_TICKS_PER_SECOND, &ticks_per_second );
seconds = ticks / ticks_per_second;
if ( seconds == 0 )
seconds = 1;
packets_per_second = Shm_Receive_message_count / seconds;
if ( (Shm_Receive_message_count % seconds) >= (seconds / 2) )
packets_per_second++;
printf( "\n\nSHMDR STATISTICS (NODE %d)\n", Shm_Local_node );
printf( "TICKS SINCE BOOT = %d\n", ticks );
printf( "TICKS PER SECOND = %d\n", ticks_per_second );
printf( "ISRs=%d\n", Shm_Interrupt_count );
printf( "RECV=%d\n", Shm_Receive_message_count );
printf( "NULL=%d\n", Shm_Null_message_count );
printf( "PKTS/SEC=%d\n", packets_per_second );
}

View File

@@ -1,38 +0,0 @@
/* void MPCI_Fatal( error )
*
* This routine is the shared memory driver fatal error handler.
*
* Input parameters:
* error - fatal error code
*
* Output parameters: NEVER RETURNS
*
* COPYRIGHT (c) 1989-1999.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
* $Id$
*/
#include <rtems.h>
#include "shm_driver.h"
void MPCI_Fatal(
Internal_errors_Source source,
boolean is_internal,
rtems_unsigned32 error
)
{
/* Eventually need to attempt to broadcast a K_FATAL message
* without checking for all possible errors (do not want to
* recurse).
*
* Also need to avoid using Shm_Node_statuses if the driver has not been
* initialized.
*/
Shm_Local_node_status->error = Shm_Convert(error);
}

View File

@@ -1,47 +0,0 @@
/* Shm_Envelope_control *Shm_Locked_queue_Get( lq_cb )
*
* This routine returns an envelope control block from a shared
* memory queue.
*
* Input parameters:
* lq_cb - pointer to a locked queue control block
*
* Output parameters:
* returns - pointer to an envelope control block
* - NULL if no envelopes on specified queue
*
* COPYRIGHT (c) 1989-1999.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
* $Id$
*/
#include <rtems.h>
#include <shm_driver.h>
Shm_Envelope_control *Shm_Locked_queue_Get(
Shm_Locked_queue_Control *lq_cb
)
{
Shm_Envelope_control *tmp_ecb;
rtems_unsigned32 tmpfront;
tmp_ecb = NULL;
Shm_Lock( lq_cb );
tmpfront = Shm_Convert(lq_cb->front);
if ( tmpfront != Shm_Locked_queue_End_of_list ) {
tmp_ecb = &Shm_Envelopes[ tmpfront ];
lq_cb->front = tmp_ecb->next;
if ( tmp_ecb->next == Shm_Locked_queue_End_of_list )
lq_cb->rear = Shm_Locked_queue_End_of_list;
tmp_ecb->next = Shm_Locked_queue_Not_on_list;
}
Shm_Unlock( lq_cb );
return( tmp_ecb );
}

View File

@@ -1,35 +0,0 @@
/* Shm_Get_packet
*
* This routine is the shared memory locked queue MPCI driver
* routine used to obtain an empty message packet.
*
* Input parameters:
* packet - address of pointer to packet
*
* Output parameters:
* *(cpb->get_packet) - address of allocated packet
*
* COPYRIGHT (c) 1989-1999.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
* $Id$
*/
#include <rtems.h>
#include "shm_driver.h"
rtems_mpci_entry Shm_Get_packet(
rtems_packet_prefix **packet
)
{
Shm_Envelope_control *ecb;
ecb = Shm_Allocate_envelope();
if ( !ecb )
rtems_fatal_error_occurred ( SHM_NO_FREE_PKTS );
*packet = Shm_Envelope_control_to_packet_prefix_pointer( ecb );
}

View File

@@ -1,253 +0,0 @@
/* Shm_Initialization
*
* This routine is the shared memory communications initerface
* driver initialization routine.
*
* Input parameters: NONE
*
* Output parameters: NONE
*
* COPYRIGHT (c) 1989-1999.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
* $Id$
*/
#define _SHM_INIT
#include <rtems.h>
#include <shm_driver.h>
#include <string.h> /* memset() */
#include <stdlib.h> /* malloc() */
#include <assert.h>
/*
* User extension to install MPCI_Fatal as a fatal error
* handler extension
*/
rtems_extensions_table MPCI_Shm_extensions;
rtems_mpci_entry Shm_Initialization( void )
{
rtems_unsigned32 i, all_initialized;
rtems_unsigned32 interrupt_cause, interrupt_value;
void *interrupt_address;
Shm_Node_status_control *nscb;
rtems_unsigned32 extension_id; /* for installation of MPCI_Fatal */
rtems_unsigned32 remaining_memory;
/* XXX these should use "public" methods to set their values.... */
rtems_configuration_table *configuration = _Configuration_Table;
rtems_multiprocessing_table *mp_configuration = _Configuration_MP_table;
Shm_RTEMS_Configuration = configuration;
Shm_RTEMS_MP_Configuration = mp_configuration;
Shm_Local_node = Shm_RTEMS_MP_Configuration->node;
Shm_Maximum_nodes = Shm_RTEMS_MP_Configuration->maximum_nodes;
Shm_Get_configuration( Shm_Local_node, &Shm_Configuration );
Shm_Interrupt_table = (Shm_Interrupt_information *) malloc(
sizeof(Shm_Interrupt_information) * (Shm_Maximum_nodes + 1)
);
assert( Shm_Interrupt_table );
Shm_Receive_message_count = 0;
Shm_Null_message_count = 0;
Shm_Interrupt_count = 0;
/*
* Set the Node Status indicators
*/
Shm_Pending_initialization =
Shm_Convert(rtems_build_name( 'P', 'E', 'N', 'D' ));
Shm_Initialization_complete =
Shm_Convert(rtems_build_name( 'C', 'O', 'M', 'P' ));
Shm_Active_node =
Shm_Convert(rtems_build_name( 'A', 'C', 'T', 'V' ));
/*
* Initialize the constants used by the Locked Queue code.
*/
Shm_Locked_queue_End_of_list = Shm_Convert( 0xffffffff );
Shm_Locked_queue_Not_on_list = Shm_Convert( 0xfffffffe );
/*
* Set the base addresses for the:
* + Node Status Table
* + Free Pool and Receive Queues
* + Envelopes
*/
Shm_Node_statuses = (Shm_Node_status_control *) START_NS_CBS;
Shm_Locked_queues = (Shm_Locked_queue_Control *) START_LQ_CBS;
Shm_Envelopes = (Shm_Envelope_control *) START_ENVELOPES;
/*
* Calculate the maximum number of envelopes which can be
* placed the remaining shared memory.
*/
remaining_memory =
((void *)Shm_Configuration->base + Shm_Configuration->length) -
((void *)Shm_Envelopes);
Shm_Maximum_envelopes = remaining_memory / sizeof( Shm_Envelope_control );
Shm_Maximum_envelopes -= 1;
/*
* Set the pointer to the receive queue for the local node.
* When we receive a node, we will get it from here before
* processing it.
*/
Shm_Local_receive_queue = &Shm_Locked_queues[ Shm_Local_node ];
Shm_Local_node_status = &Shm_Node_statuses[ Shm_Local_node ];
/*
* Convert local interrupt cause information into the
* neutral format so other nodes will be able to
* understand it.
*/
interrupt_address =
(void *) Shm_Convert( (rtems_unsigned32)Shm_Configuration->Intr.address );
interrupt_value = Shm_Convert( Shm_Configuration->Intr.value );
interrupt_cause = Shm_Convert( Shm_Configuration->Intr.length );
if ( Shm_Configuration->poll_intr == POLLED_MODE ) Shm_setclockvec();
else Shm_setvec();
if ( Shm_Is_master_node() ) {
/*
* Zero out the shared memory area.
*/
(void) memset(
(void *) Shm_Configuration->base,
0,
Shm_Configuration->length
);
/*
* Initialize all of the locked queues (the free envelope
* pool and a receive queue per node) and set all of the
* node's status so they will be waiting to initialization
* to complete.
*/
Shm_Locked_queue_Initialize( FREE_ENV_CB, FREE_ENV_POOL );
for ( i=SHM_FIRST_NODE ; i<=Shm_Maximum_nodes ; i++ ) {
Shm_Initialize_receive_queue( i );
Shm_Node_statuses[ i ].status = Shm_Pending_initialization;
Shm_Node_statuses[ i ].error = 0;
}
/*
* Initialize all of the envelopes and place them in the
* free pool.
*/
for ( i=0 ; i<Shm_Maximum_envelopes ; i++ ) {
Shm_Envelopes[ i ].index = Shm_Convert(i);
Shm_Free_envelope( &Shm_Envelopes[ i ] );
}
/*
* Initialize this node's interrupt information in the
* shared area so other nodes can interrupt us.
*/
Shm_Local_node_status->int_address = (rtems_unsigned32) interrupt_address;
Shm_Local_node_status->int_value = interrupt_value;
Shm_Local_node_status->int_length = interrupt_cause;
Shm_Local_node_status->status = Shm_Initialization_complete;
/*
* Loop until all nodes have completed initialization.
*/
do {
all_initialized = 1;
for ( i = SHM_FIRST_NODE ; i <= Shm_Maximum_nodes ; i++ )
if ( Shm_Node_statuses[ i ].status != Shm_Initialization_complete )
all_initialized = 0;
} while ( all_initialized == 0 );
/*
* Tell the other nodes we think that the system is up.
*/
for ( i = SHM_FIRST_NODE ; i <= Shm_Maximum_nodes ; i++ )
Shm_Node_statuses[ i ].status = Shm_Active_node;
} else { /* is not MASTER node */
/*
* Initialize the node status for the non-master nodes.
* Because the master node zeroes out memory, it is
* necessary for them to keep putting their values in
* the node status area until the master says they
* should become active.
*/
Shm_Local_node_status->status = Shm_Pending_initialization;
do {
if ( Shm_Local_node_status->status == Shm_Pending_initialization ) {
/*
* Initialize this node's interrupt information in the
* shared area so other nodes can interrupt us.
*/
Shm_Local_node_status->int_address =
(rtems_unsigned32) interrupt_address;
Shm_Local_node_status->int_value = interrupt_value;
Shm_Local_node_status->int_length = interrupt_cause;
Shm_Local_node_status->status = Shm_Initialization_complete;
}
} while ( Shm_Local_node_status->status != Shm_Active_node ) ;
}
/*
* Initialize the Interrupt Information Table
*/
for ( i = SHM_FIRST_NODE ; i <= Shm_Maximum_nodes ; i++ ) {
nscb = &Shm_Node_statuses[ i ];
Shm_Interrupt_table[i].address = Shm_Convert_address(
(void *)Shm_Convert(((vol_u32) nscb->int_address))
);
Shm_Interrupt_table[i].value = Shm_Convert( nscb->int_value );
Shm_Interrupt_table[i].length = Shm_Convert( nscb->int_length );
}
MPCI_Shm_extensions.fatal = MPCI_Fatal;
(void) rtems_extension_create(
rtems_build_name( 'M', 'P', 'E', 'X' ),
&MPCI_Shm_extensions,
&extension_id
);
}

View File

@@ -1,34 +0,0 @@
/* void Shm_Locked_queue_Initialize( lq_cb, owner )
*
* This routine initializes a shared memory locked queue.
*
* Input parameters:
* lq_cb - pointer to the control block of the queue
* to be initialized
* owner - unique idenitifier of who owns this queue.
*
* Output parameters: NONE
*
* COPYRIGHT (c) 1989-1999.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
* $Id$
*/
#include <rtems.h>
#include "shm_driver.h"
void Shm_Locked_queue_Initialize(
Shm_Locked_queue_Control *lq_cb,
rtems_unsigned32 owner
)
{
Shm_Initialize_lock( lq_cb );
lq_cb->front = Shm_Locked_queue_End_of_list;
lq_cb->rear = Shm_Locked_queue_End_of_list;
lq_cb->owner = Shm_Convert(owner);
}

View File

@@ -1,57 +0,0 @@
/* void Shm_Cause_interrupt( node )
*
* This routine is the shared memory driver routine which
* generates interrupts to other CPUs.
*
* It uses the information placed in the node status control
* block by each node. For example, when used with the Motorola
* MVME136 board, the MPCSR is used.
*
* Input parameters:
* node - destination of this packet (0 = broadcast)
*
* Output parameters: NONE
*
* COPYRIGHT (c) 1989-1999.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
* $Id$
*/
#include <rtems.h>
#include "shm_driver.h"
void Shm_Cause_interrupt(
rtems_unsigned32 node
)
{
Shm_Interrupt_information *intr;
rtems_unsigned8 *u8;
rtems_unsigned16 *u16;
rtems_unsigned32 *u32;
rtems_unsigned32 value;
intr = &Shm_Interrupt_table[node];
value = intr->value;
switch ( intr->length ) {
case NO_INTERRUPT:
break;
case BYTE:
u8 = (rtems_unsigned8 *)intr->address;
*u8 = (rtems_unsigned8) value;
break;
case WORD:
u16 = (rtems_unsigned16 *)intr->address;
*u16 = (rtems_unsigned16) value;
break;
case LONG:
u32 = (rtems_unsigned32 *)intr->address;
*u32 = (rtems_unsigned32) value;
break;
}
}

View File

@@ -1,58 +0,0 @@
/* mpci.h
*
* This include file contains all the renaming necessary to
* have an application use the Shared Memory Driver as its
* sole mechanism for MPCI.
*
* COPYRIGHT (c) 1989-1999.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
* $Id$
*/
#ifndef __SHM_MPCI_h
#define __SHM_MPCI_h
#ifdef __cplusplus
extern "C" {
#endif
#include <shm_driver.h>
#define MPCI_Initialization( _configuration ) \
Shm_Initialization( _configuration )
#define MPCI_Get_packet( _the_packet ) \
Shm_Get_packet( _the_packet )
#define MPCI_Return_packet( _the_packet ) \
Shm_Return_packet( _the_packet )
#define MPCI_Receive_packet( _the_packet ) \
Shm_Receive_packet( _the_packet )
#define MPCI_Send_packet( _destination, _the_packet ) \
Shm_Send_packet( _destination, _the_packet )
/* Unnecessary... mapped in shm_driver.h
#define MPCI_Fatal( _the_error ) \
Shm_Fatal( _the_error )
*/
#define MPCI_Enable_statistics()
#define MPCI_Print_statistics() \
Shm_Print_statistics()
/* no need to rename the MPCI_Table either */
#ifdef __cplusplus
}
#endif
#endif
/* end of include file */

View File

@@ -1,22 +0,0 @@
/* _Shm_isr()
*
* COPYRIGHT (c) 1989-1999.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
* $Id$
*/
#include <rtems.h>
#include "shm_driver.h"
rtems_isr Shm_isr(
rtems_vector_number vector
)
{
Shm_Interrupt_count += 1;
rtems_multiprocessing_announce();
}

View File

@@ -1,52 +0,0 @@
/* void Shm_Poll()
*
* This routine polls to see if a packet has arrived. If one
* has it informs the executive. It is typically called from
* the clock tick interrupt service routine.
*
* Input parameters: NONE
*
* Output parameters: NONE
*
* COPYRIGHT (c) 1989-1999.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
* $Id$
*/
#include <rtems.h>
#include <rtems/score/sysstate.h>
#include <rtems/libio.h>
#include "shm_driver.h"
void Shm_Poll()
{
rtems_unsigned32 tmpfront;
rtems_libio_ioctl_args_t args;
/* invoke clock isr */
args.iop = 0;
args.command = rtems_build_name('I', 'S', 'R', ' ');
(void) rtems_io_control(rtems_clock_major, rtems_clock_minor, &args);
/*
* Check for msgs only if we are "up"
* This avoids a race condition where we may get a clock
* interrupt before MPCI has completed its init
*/
if (_System_state_Is_up(_System_state_Get()))
{
tmpfront = Shm_Local_receive_queue->front;
if ( Shm_Convert(tmpfront) != Shm_Locked_queue_End_of_list )
{
rtems_multiprocessing_announce();
Shm_Interrupt_count++;
}
}
}

View File

@@ -1,43 +0,0 @@
/* Shm_Receive_packet
*
* This routine is the shared memory locked queue MPCI driver routine
* used to obtain a packet containing a message from this node's
* receive queue.
*
* Input parameters:
* packet - address of a pointer to a packet
*
* Output parameters:
* *(rpb->packet) - pointer to packet
* NULL if no packet currently available
*
* COPYRIGHT (c) 1989-1999.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
* $Id$
*/
#include <rtems.h>
#include "shm_driver.h"
rtems_mpci_entry Shm_Receive_packet(
rtems_packet_prefix **packet
)
{
Shm_Envelope_control *ecb;
ecb = Shm_Locked_queue_Get( Shm_Local_receive_queue );
if ( ecb ) {
*(packet) = Shm_Envelope_control_to_packet_prefix_pointer( ecb );
if ( ecb->Preamble.endian != Shm_Configuration->format )
Shm_Convert_packet( *packet );
Shm_Receive_message_count++;
} else {
*(packet) = NULL;
Shm_Null_message_count++;
}
}

View File

@@ -1,31 +0,0 @@
/* Shm_Return_packet
*
* This routine is the shared memory locked queue MPCI driver
* routine used to return a message packet to a free envelope
* pool accessible by this node.
*
* Input parameters:
* packet - address of pointer to packet
*
* Output parameters: NONE
*
* COPYRIGHT (c) 1989-1999.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
* $Id$
*/
#include <rtems.h>
#include "shm_driver.h"
rtems_mpci_entry Shm_Return_packet(
rtems_packet_prefix *packet
)
{
Shm_Free_envelope( Shm_Packet_prefix_to_envelope_control_pointer(packet) );
}

View File

@@ -1,60 +0,0 @@
/* Shm_Send_packet
*
* This routine is the shared memory driver locked queue write
* MPCI driver routine. This routine sends the specified packet
* to the destination specified by "node". A "node" value of
* zero designates that this packet is to be broadcasted.
*
* Input parameters:
* node - destination of this packet (0 = broadcast)
* packet - address of packet
*
* Output parameters: NONE
*
* COPYRIGHT (c) 1989-1999.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
* $Id$
*/
#include <rtems.h>
#include "shm_driver.h"
struct pkt_cpy {
rtems_unsigned32 packet[MAX_PACKET_SIZE/4];
};
rtems_mpci_entry Shm_Send_packet(
rtems_unsigned32 node,
rtems_packet_prefix *packet
)
{
Shm_Envelope_control *ecb, *tmp_ecb;
rtems_unsigned32 nnum;
ecb = Shm_Packet_prefix_to_envelope_control_pointer( packet );
if ( node ) {
Shm_Build_preamble( ecb, node );
Shm_Build_postamble( ecb );
Shm_Append_to_receive_queue( node, ecb );
(*Shm_Configuration->cause_intr)( node );
}
else {
for( nnum = SHM_FIRST_NODE ; nnum <= Shm_Maximum_nodes ; nnum++ )
if ( Shm_Local_node != nnum ) {
tmp_ecb = Shm_Allocate_envelope();
if ( !tmp_ecb )
rtems_fatal_error_occurred( SHM_NO_FREE_PKTS );
Shm_Build_preamble( tmp_ecb, nnum );
*((struct pkt_cpy *)tmp_ecb->packet) = *((struct pkt_cpy *)packet);
Shm_Build_postamble( tmp_ecb );
Shm_Append_to_receive_queue( nnum, tmp_ecb );
(*Shm_Configuration->cause_intr)( nnum );
}
Shm_Free_envelope( ecb );
}
}

View File

@@ -1,33 +0,0 @@
/* Shm_setclockvec
*
* This routines installs the shared memory clock interrupt handler
* used when the driver is used in polling mode.
*
* INPUT PARAMETERS: NONE
*
* OUTPUT PARAMETERS: NONE
*
* COPYRIGHT (c) 1989-1999.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
* $Id$
*/
#include <rtems.h>
#include <rtems/libio.h>
#include "shm_driver.h"
rtems_isr Shm_setclockvec()
{
rtems_libio_ioctl_args_t args;
args.iop = 0;
args.command = rtems_build_name('N', 'E', 'W', ' ');
args.buffer = (void *) Shm_Poll;
(void) rtems_io_control(rtems_clock_major, rtems_clock_minor, &args);
}

View File

@@ -1,544 +0,0 @@
/* shm_driver.h
*
* This include file contains all the constants, structures,
* and global variables for this RTEMS based shared memory
* communications interface driver.
*
* Processor board dependencies are in other files.
*
* COPYRIGHT (c) 1989-1999.
* On-Line Applications Research Corporation (OAR).
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
* $Id$
*/
#ifndef __SHM_h
#define __SHM_h
#include <clockdrv.h>
#ifdef __cplusplus
extern "C" {
#endif
/* The information contained in the Node Status, Locked Queue, and
* Envelope Control Blocks must be maintained in a NEUTRAL format.
* Currently the neutral format may be selected as big or little
* endian by simply defining either NEUTRAL_BIG or NEUTRAL_LITTLE.
*
* It is CRITICAL to note that the neutral format can ONLY be
* changed by modifying this file and recompiling the ENTIRE
* SHM driver including ALL target specific support files.
*
* The following table details the memory contents for the endian
* field of the Node Status Control Block in the various
* data format configurations (data is in hexadecimal):
*
* NEUTRAL NATIVE BYTE 0 BYTE 1 BYTE 2 BYTE 3
* ======= ====== ====== ====== ====== ======
* BIG BIG 00 00 00 01
* BIG LITTLE 10 00 00 00
* LITTLE BIG 01 00 00 00
* LITTLE LITTLE 00 00 00 10
*
*
* NOTE: XXX
* PORTABILITY OF LOCKING INSTRUCTIONS
* ===================================
* The locking mechanism described below is not
* general enough. Where the hardware supports
* it we should use "atomic swap" instructions
* so the values in the lock can be tailored to
* support a CPU with only weak atomic memory
* instructions. There are combinations of
* CPUs with inflexible atomic memory instructions
* which appear to be incompatible. For example,
* the SPARClite instruction uses a byte which is
* 0xFF when locked. The PA-RISC uses 1 to indicate
* locked and 0 when unlocked. These CPUs appear to
* have incompatible lock instructions. But
* they could be used in a heterogenous system
* with does not mix SPARCs and PA-RISCs. For
* example, the i386 and SPARC or i386 and SPARC
* could work together. The bottom line is that
* not every CPU will work together using this
* locking scheme. There are supposed to be
* algorithms to do this without hardware assist
* and one of these should be incorporated into
* the shared memory driver.
*
* The most flexible scheme using the instructions
* of the various CPUs for efficiency would be to use
* "atomic swaps" wherever possible. Make the lock
* and unlock configurable much like BIG vs LITTLE
* endian use of shared memory is now. The values
* of the lock could then reflect the "worst"
* CPU in a system. This still results in mixes
* of CPUs which are incompatible.
*
* The current locking mechanism is based upon the MC68020
* "tas" instruction which is atomic. All ports to other CPUs
* comply with the restrictive placement of lock bit by this
* instruction. The lock bit is the most significant bit in a
* big-endian rtems_unsigned32. On other processors, the lock is
* typically implemented via an atomic swap or atomic modify
* bits type instruction.
*/
#define NEUTRAL_BIG
#ifdef NEUTRAL_BIG
#define SHM_BIG 0x00000001
#define SHM_LITTLE 0x10000000
#endif
#ifdef NEUTRAL_LITTLE
#define SHM_BIG 0x01000000
#define SHM_LITTLE 0x00000010
#endif
/*
* The following are the values used to fill in the lock field. Some CPUs
* are able to write only a single value into field. By making the
* lock and unlock values configurable, CPUs which support "atomic swap"
* instructions can generally be made to work in any heterogeneous
* configuration. However, it is possible for two CPUs to be incompatible
* in regards to the lock field values. This occurs when two CPUs
* which write only a single value to the field are used in a system
* but the two CPUs write different incompatible values.
*
* NOTE: The following is a first attempt at defining values which
* have a chance at working together. The m68k should use
* chk2 instead of tas to be less restrictive. Target endian
* problems (like the Force CPU386 which has (broken) big endian
* view of the VMEbus address space) are not addressed yet.
*/
#if defined(__i960__)
#define SHM_LOCK_VALUE 0x00000080
#define SHM_UNLOCK_VALUE 0
#elif defined(__mc68000__)
#define SHM_LOCK_VALUE 0x80000000
#define SHM_UNLOCK_VALUE 0
#define SHM_LOCK_VALUE 0x80000000
#define SHM_UNLOCK_VALUE 0
#elif defined(__i386__)
#define SHM_LOCK_VALUE 0x80000000
#define SHM_UNLOCK_VALUE 0
#elif defined(__mips__)
#define SHM_LOCK_VALUE 0x80000000
#define SHM_UNLOCK_VALUE 0
#elif defined(__hppa__)
#define SHM_LOCK_VALUE 0
#define SHM_UNLOCK_VALUE 1
#elif defined(__PPC__)
#define SHM_LOCK_VALUE 1
#define SHM_UNLOCK_VALUE 0
#elif defined(__unix__)
#define SHM_LOCK_VALUE 0
#define SHM_UNLOCK_VALUE 1
#elif defined(_AM29K)
#define SHM_LOCK_VALUE 0
#define SHM_UNLOCK_VALUE 1
#elif defined(no_cpu) /* for this values are irrelevant */
#define SHM_LOCK_VALUE 1
#define SHM_UNLOCK_VALUE 0
#else
#error "shm_driver.h - no SHM_LOCK_VALUE defined for this CPU architecture"
#endif
#define Shm_Convert( value ) \
((Shm_Configuration->convert) ? \
(*Shm_Configuration->convert)(value) : (value))
/* constants */
#define SHM_MASTER 1 /* master initialization node */
#define SHM_FIRST_NODE 1
/* size constants */
#define KILOBYTE (1024)
#define MEGABYTE (1024*1024)
/* inter-node interrupt values */
#define NO_INTERRUPT 0 /* used for polled nodes */
#define BYTE 1
#define WORD 2
#define LONG 4
/* operational mode constants -- used in SHM Configuration Table */
#define POLLED_MODE 0
#define INTR_MODE 1
/* error codes */
#define NO_ERROR 0
#define SHM_NO_FREE_PKTS 0xf0000
/* null pointers of different types */
#define NULL_ENV_CB ((Shm_Envelope_control *) 0)
#define NULL_CONVERT 0
/*
* size of stuff before preamble in envelope.
* It must be a constant since we will use it to generate MAX_PACKET_SIZE
*/
#define SHM_ENVELOPE_PREFIX_OVERHEAD (4 * sizeof(vol_u32))
/*
* The following is adjusted so envelopes are MAX_ENVELOPE_SIZE bytes long.
* It must be >= RTEMS_MINIMUM_PACKET_SIZE in mppkt.h.
*/
#ifndef MAX_ENVELOPE_SIZE
#define MAX_ENVELOPE_SIZE 0x180
#endif
#define MAX_PACKET_SIZE (MAX_ENVELOPE_SIZE - \
SHM_ENVELOPE_PREFIX_OVERHEAD + \
sizeof(Shm_Envelope_preamble) + \
sizeof(Shm_Envelope_postamble))
/* constants pertinent to Locked Queue routines */
#define LQ_UNLOCKED SHM_UNLOCK_VALUE
#define LQ_LOCKED SHM_LOCK_VALUE
/* constants related to the Free Envelope Pool */
#define FREE_ENV_POOL 0
#define FREE_ENV_CB (&Shm_Locked_queues[ FREE_ENV_POOL ])
/* The following are important when dealing with
* the shared memory communications interface area.
*
* NOTE: The starting address and length of the shared memory
* is defined in a system dependent file.
*/
#define START_NS_CBS ((void *)Shm_Configuration->base)
#define START_LQ_CBS ((START_NS_CBS) + \
( (sizeof (Shm_Node_status_control)) * (Shm_Maximum_nodes + 1) ) )
#define START_ENVELOPES ( ((void *) START_LQ_CBS) + \
( (sizeof (Shm_Locked_queue_Control)) * (Shm_Maximum_nodes + 1) ) )
#define END_SHMCI_AREA ( (void *) START_ENVELOPES + \
( (sizeof (Shm_Envelope_control)) * Shm_Maximum_envelopes ) )
#define END_SHARED_MEM (START_NS_CBS+Shm_Configuration->length)
/* macros */
#define Shm_Is_master_node() \
( SHM_MASTER == Shm_Local_node )
#define Shm_Free_envelope( ecb ) \
Shm_Locked_queue_Add( FREE_ENV_CB, (ecb) )
#define Shm_Allocate_envelope() \
Shm_Locked_queue_Get(FREE_ENV_CB)
#define Shm_Initialize_receive_queue(node) \
Shm_Locked_queue_Initialize( &Shm_Locked_queues[node], node )
#define Shm_Append_to_receive_queue(node, ecb) \
Shm_Locked_queue_Add( &Shm_Locked_queues[node], (ecb) )
#define Shm_Envelope_control_to_packet_prefix_pointer(ecb) \
((void *)(ecb)->packet)
#define Shm_Packet_prefix_to_envelope_control_pointer( pkt ) \
((Shm_Envelope_control *)((rtems_unsigned8 *)(pkt) - \
(sizeof(Shm_Envelope_preamble) + SHM_ENVELOPE_PREFIX_OVERHEAD)))
#define Shm_Build_preamble(ecb, node) \
(ecb)->Preamble.endian = Shm_Configuration->format
#define Shm_Build_postamble( ecb )
/* volatile types */
typedef volatile rtems_unsigned8 vol_u8;
typedef volatile rtems_unsigned32 vol_u32;
/* shm control information */
struct shm_info {
vol_u32 not_currently_used_0;
vol_u32 not_currently_used_1;
vol_u32 not_currently_used_2;
vol_u32 not_currently_used_3;
};
typedef struct {
/*byte start_of_text;*/
vol_u32 endian;
vol_u32 not_currently_used_0;
vol_u32 not_currently_used_1;
vol_u32 not_currently_used_2;
} Shm_Envelope_preamble;
typedef struct {
} Shm_Envelope_postamble;
/* WARNING! If you change this structure, don't forget to change
* SHM_ENVELOPE_PREFIX_OVERHEAD and
* Shm_Packet_prefix_to_envelope_control_pointer() above.
*/
/* This comment block describes the contents of each field
* of the Envelope Control Block:
*
* next - The index of the next envelope on this queue.
* queue - The index of the queue this envelope is on.
* index - The index of this envelope.
* Preamble - Generic packet preamble. One day this structure
* could be enhanced to contain routing information.
* packet - RTEMS MPCI packet. Untouched by SHM Driver
* other than copying and format conversion as
* documented in the RTEMS User's Guide.
* Postamble - Generic packet postamble. One day this structure
* could be enhanced to contain checksum information.
*/
typedef struct {
vol_u32 next; /* next envelope on queue */
vol_u32 queue; /* queue on which this resides */
vol_u32 index; /* index into array of envelopes*/
vol_u32 pad0; /* insure the next one is aligned */
Shm_Envelope_preamble Preamble; /* header information */
vol_u8 packet[MAX_PACKET_SIZE]; /* RTEMS INFO */
Shm_Envelope_postamble Postamble;/* trailer information */
} Shm_Envelope_control;
/* This comment block describes the contents of each field
* of the Locked Queue Control Block:
*
* lock - Lock used to insure mutually exclusive access.
* front - Index of first envelope on queue. This field
* is used to remove head of queue (receive).
* rear - Index of last envelope on queue. This field
* is used to add evelope to queue (send).
* owner - The node number of the recipient (owning) node.
* RTEMS does not use the node number zero (0).
* The zero node is used by the SHM Driver for the
* Free Envelope Queue shared by all nodes.
*/
typedef struct {
vol_u32 lock; /* lock field for this queue */
vol_u32 front; /* first envelope on queue */
vol_u32 rear; /* last envelope on queue */
vol_u32 owner; /* receiving (i.e. owning) node */
} Shm_Locked_queue_Control;
/* This comment block describes the contents of each field
* of the Node Status Control Block:
*
* status - Node status. Current values are Pending Initialization,
* Initialization Complete, and Active Node. Other values
* could be added to enhance fault tolerance.
* error - Zero if the node has not failed. Otherwise,
* this field contains a status indicating the
* failure reason.
* int_address, int_value, and int_length
* - These field are the Interrupt Information table
* for this node in neutral format. This is how
* each node knows how to generate interrupts.
*/
typedef struct {
vol_u32 status; /* node status information */
vol_u32 error; /* fatal error code */
vol_u32 int_address; /* write here for interrupt */
vol_u32 int_value; /* this value causes interrupt */
vol_u32 int_length; /* for this length (0,1,2,4) */
vol_u32 not_currently_used_0;
vol_u32 not_currently_used_1;
vol_u32 not_currently_used_2;
} Shm_Node_status_control;
/* This comment block describes the contents of each field
* of the Interrupt Information Table. This table describes
* how another node can generate an interrupt to this node.
* This information is target board dependent. If the
* SHM Driver is in POLLED_MODE, then all fields should
* be initialized to NO_INTERRUPT.
*
* address - The address to which another node should
* write to cause an interrupt.
* value - The value which must be written
* length - The size of the value to write. Valid
* values are BYTE, WORD, and LONG.
*
* NOTE: The Node Status Control Block contains this
* information in neutral format and not in a
* structure to avoid potential alignment problems.
*/
typedef struct {
vol_u32 *address; /* write here for interrupt */
vol_u32 value; /* this value causes interrupt */
vol_u32 length; /* for this length (0,1,2,4) */
} Shm_Interrupt_information;
/* SHM Configuration Table
*
* This comment block describes the contents of each field
* of the SHM Configuration Table.
*
* base - The base address of the shared memory. This
* address may be specific to this node.
* length - The length of the shared memory in bytes.
* format - The natural format for rtems_unsigned32's in the
* shared memory. Valid values are currently
* only SHM_LITTLE and SHM_BIG.
* convert - The address of the routine which converts
* between neutral and local format.
* poll_intr - The operational mode of the driver. Some
* target boards may not provide hardware for
* an interprocessor interrupt. If POLLED_MODE
* is selected, the SHM driver will install a
* wrapper around the Clock_isr() to poll for
* incoming packets. Throughput is dependent
* on the time between clock interrupts.
* Valid values are POLLED_MODE and INTR_MODE.
* cause_intr - This is the address of the routine used to
* write to a particular address and cause an
* interrupt on another node. This routine
* may need to be target dependent if something
* other than a normal write from C does not work.
* Intr - This structure describes the operation required
* to cause an interrupt to this node. The actual
* contents of this structure are described above.
*/
struct shm_config_info {
vol_u32 *base; /* base address of SHM */
vol_u32 length; /* length (in bytes) of SHM */
vol_u32 format; /* SHM is big or little endian */
vol_u32 (*convert)();/* neutral conversion routine */
vol_u32 poll_intr;/* POLLED or INTR driven mode */
void (*cause_intr)( rtems_unsigned32 );
Shm_Interrupt_information Intr; /* cause intr information */
};
typedef struct shm_config_info shm_config_table;
/* global variables */
#ifdef _SHM_INIT
#define SHM_EXTERN
#else
#define SHM_EXTERN extern
#endif
SHM_EXTERN shm_config_table *Shm_Configuration;
SHM_EXTERN Shm_Interrupt_information *Shm_Interrupt_table;
SHM_EXTERN Shm_Node_status_control *Shm_Node_statuses;
SHM_EXTERN Shm_Locked_queue_Control *Shm_Locked_queues;
SHM_EXTERN Shm_Envelope_control *Shm_Envelopes;
SHM_EXTERN rtems_configuration_table *Shm_RTEMS_Configuration;
SHM_EXTERN rtems_multiprocessing_table *Shm_RTEMS_MP_Configuration;
SHM_EXTERN rtems_unsigned32 Shm_Receive_message_count;
SHM_EXTERN rtems_unsigned32 Shm_Null_message_count;
SHM_EXTERN rtems_unsigned32 Shm_Interrupt_count;
SHM_EXTERN rtems_unsigned32 Shm_Local_node;
SHM_EXTERN Shm_Locked_queue_Control *Shm_Local_receive_queue;
SHM_EXTERN Shm_Node_status_control *Shm_Local_node_status;
SHM_EXTERN rtems_unsigned32 Shm_isrstat;
/* reported by shmdr */
SHM_EXTERN rtems_unsigned32 Shm_Pending_initialization;
SHM_EXTERN rtems_unsigned32 Shm_Initialization_complete;
SHM_EXTERN rtems_unsigned32 Shm_Active_node;
SHM_EXTERN rtems_unsigned32 Shm_Maximum_nodes;
SHM_EXTERN rtems_unsigned32 Shm_Maximum_envelopes;
SHM_EXTERN rtems_unsigned32 Shm_Locked_queue_End_of_list;
SHM_EXTERN rtems_unsigned32 Shm_Locked_queue_Not_on_list;
/* functions */
/* locked queue routines */
void Shm_Locked_queue_Add(
Shm_Locked_queue_Control *, Shm_Envelope_control * );
Shm_Envelope_control *Shm_Locked_queue_Get( Shm_Locked_queue_Control * );
void Shm_Locked_queue_Initialize(
Shm_Locked_queue_Control *, rtems_unsigned32 );
/* Shm_Initialize_lock is CPU dependent */
/* Shm_Lock is CPU dependent */
/* Shm_Unlock is CPU dependent */
/* portable routines */
void Init_env_pool();
void Shm_Print_statistics( void );
void MPCI_Fatal( Internal_errors_Source, boolean, rtems_unsigned32 );
rtems_task Shm_Cause_interrupt( rtems_unsigned32 );
void Shm_Poll();
void Shm_setclockvec();
void Shm_Convert_packet( rtems_packet_prefix * );
/* CPU specific routines are inlined in shmcpu.h */
/* target specific routines */
void *Shm_Convert_address( void * );
void Shm_Get_configuration( rtems_unsigned32, shm_config_table ** );
void Shm_isr();
void Shm_setvec( void );
void Shm_Initialize_lock( Shm_Locked_queue_Control * );
void Shm_Lock( Shm_Locked_queue_Control * );
void Shm_Unlock( Shm_Locked_queue_Control * );
/* MPCI entry points */
rtems_mpci_entry Shm_Get_packet(
rtems_packet_prefix **
);
rtems_mpci_entry Shm_Initialization( void );
rtems_mpci_entry Shm_Receive_packet(
rtems_packet_prefix **
);
rtems_mpci_entry Shm_Return_packet(
rtems_packet_prefix *
);
rtems_mpci_entry Shm_Send_packet(
rtems_unsigned32,
rtems_packet_prefix *
);
extern rtems_mpci_table MPCI_table;
#ifdef _SHM_INIT
/* multiprocessor communications interface (MPCI) table */
rtems_mpci_table MPCI_table = {
100000, /* default timeout value in ticks */
MAX_PACKET_SIZE, /* maximum packet size */
Shm_Initialization, /* initialization procedure */
Shm_Get_packet, /* get packet procedure */
Shm_Return_packet, /* return packet procedure */
Shm_Send_packet, /* packet send procedure */
Shm_Receive_packet /* packet receive procedure */
};
#endif
#ifdef __cplusplus
}
#endif
#endif
/* end of include file */

View File

@@ -1,44 +0,0 @@
##
## $Id$
##
include_rtemsdir = $(includedir)/rtems
LIBNAME = lib.a
LIB = $(ARCH)/$(LIBNAME)
C_FILES = ftpd.c
OBJS = $(C_FILES:%.c=$(ARCH)/%.$(OBJEXT))
include $(top_srcdir)/../../../automake/compile.am
include $(top_srcdir)/../../../automake/lib.am
#
# Add local stuff here using +=
#
$(LIB): $(OBJS)
$(make-library)
all-local: $(PREINSTALL_FILES) $(ARCH) $(OBJS) $(LIB)
.PRECIOUS: $(LIB)
EXTRA_DIST = ftpd.c ftpd.h
include_HEADERS = ftpd.h
include_rtems_HEADERS =
PREINSTALL_FILES = $(PROJECT_INCLUDE) \
$(include_HEADERS:%=$(PROJECT_INCLUDE)/%) \
$(include_rtems_HEADERS:%=$(PROJECT_INCLUDE)/rtems/%)
$(PROJECT_INCLUDE)/%.h: %.h
$(INSTALL_DATA) $< $@
$(PROJECT_INCLUDE)/rtems:
@$(mkinstalldirs) $@
$(PROJECT_INCLUDE)/rtems/%.h: %.h
$(INSTALL_DATA) $< $@
include $(top_srcdir)/../../../automake/local.am

File diff suppressed because it is too large Load Diff

View File

@@ -1,57 +0,0 @@
/*
* FTP Server Information
*
* $Id$
*/
#ifndef __FTPD_H__
#define __FTPD_H__
#define FTPD_CONTROL_PORT 21
/* FTPD access control flags */
enum
{
FTPD_NO_WRITE = 0x1,
FTPD_NO_READ = 0x2,
FTPD_NO_RW = FTPD_NO_WRITE | FTPD_NO_READ
};
typedef int (*rtems_ftpd_hookfunction)(unsigned char *, unsigned long);
struct rtems_ftpd_hook
{
char *filename;
rtems_ftpd_hookfunction hook_function;
};
struct rtems_ftpd_configuration
{
rtems_task_priority priority; /* FTPD task priority */
unsigned long max_hook_filesize; /* Maximum buffersize */
/* for hooks */
int port; /* Well-known port */
struct rtems_ftpd_hook *hooks; /* List of hooks */
char const *root; /* Root for FTPD or 0 for / */
int tasks_count; /* Max. connections */
int idle; /* Idle timeout in seoconds
or 0 for no (inf) timeout */
int access; /* 0 - r/w, 1 - read-only,
2 - write-only,
3 - browse-only */
};
/*
* Reply codes.
*/
#define PRELIM 1 /* positive preliminary */
#define COMPLETE 2 /* positive completion */
#define CONTINUE 3 /* positive intermediate */
#define TRANSIENT 4 /* transient negative completion */
#define ERROR 5 /* permanent negative completion */
int rtems_initialize_ftpd();
#endif /* __FTPD_H__ */

View File

@@ -1,2 +0,0 @@
Makefile
Makefile.in

View File

@@ -1,59 +0,0 @@
##
## $Id$
##
include_goaheaddir = $(includedir)/goahead
LIBNAME = lib.a
LIB = $(ARCH)/$(LIBNAME)
C_FILES = asp.c balloc.c default.c ejlex.c ejparse.c emfdb.c form.c \
h.c handler.c md5c.c mime.c misc.c webpage.c ringq.c rom.c security.c \
sock.c socket.c sym.c uemf.c um.c url.c value.c wbase64.c webrom.c webs.c \
websuemf.c webmain.c
OBJS = $(C_FILES:%.c=$(ARCH)/%.$(OBJEXT))
H_FILES = ej.h ejIntrn.h emfdb.h md5.h uemf.h um.h webs.h wsIntrn.h
include $(top_srcdir)/../../../automake/compile.am
include $(top_srcdir)/../../../automake/lib.am
#
# Add local stuff here using +=
#
AM_CPPFLAGS += -DWEBS -DUEMF -DOS="RTEMS"
$(LIB): $(OBJS)
$(make-library)
$(PROJECT_INCLUDE):
$(mkinstalldirs) $@
$(PROJECT_INCLUDE)/goahead:
$(mkinstalldirs) $@
$(PROJECT_INCLUDE)/goahead/%.h: %.h
$(INSTALL_DATA) $< $@
$(PROJECT_INCLUDE)/rtems_webserver.h: rtems_webserver.h
$(INSTALL_DATA) $< $@
PREINSTALL_FILES = $(PROJECT_INCLUDE) $(PROJECT_INCLUDE)/rtems_webserver.h \
$(PROJECT_INCLUDE)/goahead $(H_FILES:%.h=$(PROJECT_INCLUDE)/goahead/%.h)
if HAS_POSIX
include_HEADERS = rtems_webserver.h
include_goahead_HEADERS = $(H_FILES)
all-local: $(PREINSTALL_FILES) $(ARCH) $(OBJS) $(LIB)
endif
.PRECIOUS: $(LIB)
EXTRA_DIST = asp.c balloc.c default.c ej.h ejlex.c ejparse.c form.c h.c \
handler.c mime.c misc.c ringq.c rom.c rtems_webserver.h security.c \
sock.c socket.c sym.c uemf.c uemf.h um.h url.c value.c wbase64.c webcomp.c \
webmain.c webpage.c webrom.c webs.c webs.h websuemf.c wsIntrn.h
include $(top_srcdir)/../../../automake/local.am

View File

@@ -1,29 +0,0 @@
#
# $Id$
#
Notes on merging GoAhead Webs 2.1. Eventually RTEMS should be supported
in their distributions and this directory removed.
Applied patch from Antti P Miettinen <antti.p.miettinen@nokia.com>.
Obtain the original distribution from http://www.goahead.com for
documentation.
Tailoring
=========
socket.c is RTEMS specific
Renames
=======
Distributed as This Directory
============== ================
base64.c wbase64.c
page.c webpage.c
RTEMS Specific Additions
========================
webmain.c
rtems_webserver.h

View File

@@ -1,319 +0,0 @@
/*
* asp.c -- Active Server Page Support
*
* Copyright (c) GoAhead Software Inc., 1995-2000. All Rights Reserved.
*
* See the file "license.txt" for usage and redistribution license requirements
*/
/******************************** Description *********************************/
/*
* The ASP module processes ASP pages and executes embedded scripts. It
* support an open scripting architecture with in-built support for
* Ejscript(TM).
*/
/********************************* Includes ***********************************/
#include "wsIntrn.h"
/********************************** Locals ************************************/
static sym_fd_t websAspFunctions = -1; /* Symbol table of functions */
static int aspOpenCount = 0; /* count of apps using this module */
/***************************** Forward Declarations ***************************/
static char_t *strtokcmp(char_t *s1, char_t *s2);
static char_t *skipWhite(char_t *s);
/************************************* Code ***********************************/
/*
* Create script spaces and commands
*/
int websAspOpen()
{
if (++aspOpenCount == 1) {
/*
* Create the table for ASP functions
*/
websAspFunctions = symOpen(WEBS_SYM_INIT * 2);
/*
* Create standard ASP commands
*/
websAspDefine(T("write"), websAspWrite);
}
return 0;
}
/************************************* Code ***********************************/
/*
* Close Asp symbol table.
*/
void websAspClose()
{
if (--aspOpenCount <= 0) {
if (websAspFunctions != -1) {
symClose(websAspFunctions);
websAspFunctions = -1;
}
}
}
/******************************************************************************/
/*
* Process ASP requests and expand all scripting commands. We read the
* entire ASP page into memory and then process. If you have really big
* documents, it is better to make them plain HTML files rather than ASPs.
*/
int websAspRequest(webs_t wp, char_t *lpath)
{
websStatType sbuf;
char *rbuf;
char_t *token, *lang, *result, *path, *ep, *cp, *buf, *nextp;
char_t *last;
int rc, engine, len, ejid;
a_assert(websValid(wp));
a_assert(lpath && *lpath);
rc = -1;
buf = NULL;
rbuf = NULL;
engine = EMF_SCRIPT_EJSCRIPT;
wp->flags |= WEBS_HEADER_DONE;
path = websGetRequestPath(wp);
/*
* Create Ejscript instance in case it is needed
*/
ejid = ejOpenEngine(wp->cgiVars, websAspFunctions);
if (ejid < 0) {
websError(wp, 200, T("Can't create Ejscript engine"));
goto done;
}
ejSetUserHandle(ejid, (int) wp);
if (websPageStat(wp, lpath, path, &sbuf) < 0) {
websError(wp, 200, T("Can't stat %s"), lpath);
goto done;
}
/*
* Create a buffer to hold the ASP file in-memory
*/
len = sbuf.size * sizeof(char);
if ((rbuf = balloc(B_L, len + 1)) == NULL) {
websError(wp, 200, T("Can't get memory"));
goto done;
}
rbuf[len] = '\0';
if (websPageReadData(wp, rbuf, len) != len) {
websError(wp, 200, T("Cant read %s"), lpath);
goto done;
}
websPageClose(wp);
/*
* Convert to UNICODE if necessary.
*/
if ((buf = ballocAscToUni(rbuf, len)) == NULL) {
websError(wp, 200, T("Can't get memory"));
goto done;
}
/*
* Scan for the next "<%"
*/
last = buf;
rc = 0;
while (rc == 0 && *last && ((nextp = gstrstr(last, T("<%"))) != NULL)) {
websWriteBlock(wp, last, (nextp - last));
nextp = skipWhite(nextp + 2);
/*
* Decode the language
*/
token = T("language");
if ((lang = strtokcmp(nextp, token)) != NULL) {
if ((cp = strtokcmp(lang, T("=javascript"))) != NULL) {
engine = EMF_SCRIPT_EJSCRIPT;
} else {
cp = nextp;
}
nextp = cp;
}
/*
* Find tailing bracket and then evaluate the script
*/
if ((ep = gstrstr(nextp, T("%>"))) != NULL) {
*ep = '\0';
last = ep + 2;
nextp = skipWhite(nextp);
/*
* Handle backquoted newlines
*/
for (cp = nextp; *cp; ) {
if (*cp == '\\' && (cp[1] == '\r' || cp[1] == '\n')) {
*cp++ = ' ';
while (*cp == '\r' || *cp == '\n') {
*cp++ = ' ';
}
} else {
cp++;
}
}
/*
* Now call the relevant script engine. Output is done directly
* by the ASP script procedure by calling websWrite()
*/
if (*nextp) {
result = NULL;
if (engine == EMF_SCRIPT_EJSCRIPT) {
rc = scriptEval(engine, nextp, &result, ejid);
} else {
rc = scriptEval(engine, nextp, &result, (int) wp);
}
if (rc < 0) {
/*
* On an error, discard all output accumulated so far
* and store the error in the result buffer. Be careful if the
* user has called websError() already.
*/
if (websValid(wp)) {
if (result) {
websWrite(wp, T("<h2><b>ASP Error: %s</b></h2>\n"),
result);
websWrite(wp, T("<pre>%s</pre>"), nextp);
bfree(B_L, result);
} else {
websWrite(wp, T("<h2><b>ASP Error</b></h2>\n%s\n"),
nextp);
}
websWrite(wp, T("</body></html>\n"));
rc = 0;
}
goto done;
}
}
} else {
websError(wp, 200, T("Unterminated script in %s: \n"), lpath);
rc = -1;
goto done;
}
}
/*
* Output any trailing HTML page text
*/
if (last && *last && rc == 0) {
websWriteBlock(wp, last, gstrlen(last));
}
rc = 0;
/*
* Common exit and cleanup
*/
done:
if (websValid(wp)) {
websPageClose(wp);
if (ejid >= 0) {
ejCloseEngine(ejid);
}
}
bfreeSafe(B_L, buf);
bfreeSafe(B_L, rbuf);
return rc;
}
/******************************************************************************/
/*
* Define an ASP Ejscript function. Bind an ASP name to a C procedure.
*/
int websAspDefine(char_t *name,
int (*fn)(int ejid, webs_t wp, int argc, char_t **argv))
{
return ejSetGlobalFunctionDirect(websAspFunctions, name,
(int (*)(int, void*, int, char_t**)) fn);
}
/******************************************************************************/
/*
* Asp write command. This implemements <% write("text"); %> command
*/
int websAspWrite(int ejid, webs_t wp, int argc, char_t **argv)
{
int i;
a_assert(websValid(wp));
for (i = 0; i < argc; ) {
a_assert(argv);
if (websWriteBlock(wp, argv[i], gstrlen(argv[i])) < 0) {
return -1;
}
if (++i < argc) {
if (websWriteBlock(wp, T(" "), 2) < 0) {
return -1;
}
}
}
return 0;
}
/******************************************************************************/
/*
* strtokcmp -- Find s2 in s1. We skip leading white space in s1.
* Return a pointer to the location in s1 after s2 ends.
*/
static char_t *strtokcmp(char_t *s1, char_t *s2)
{
int len;
s1 = skipWhite(s1);
len = gstrlen(s2);
for (len = gstrlen(s2); len > 0 && (tolower(*s1) == tolower(*s2)); len--) {
if (*s2 == '\0') {
return s1;
}
s1++;
s2++;
}
if (len == 0) {
return s1;
}
return NULL;
}
/******************************************************************************/
/*
* Skip white space
*/
static char_t *skipWhite(char_t *s)
{
a_assert(s);
if (s == NULL) {
return s;
}
while (*s && gisspace(*s)) {
s++;
}
return s;
}
/******************************************************************************/

View File

@@ -1,966 +0,0 @@
/*
* balloc.c -- Block allocation module
*
* Copyright (c) GoAhead Software Inc., 1995-2000. All Rights Reserved.
*
* See the file "license.txt" for usage and redistribution license requirements
*/
/******************************** Description *********************************/
/*
* This module implements a very fast block allocation scheme suitable for
* ROMed environments. It maintains block class queues for rapid allocation
* and minimal fragmentation. This module does not coalesce blocks. The
* storage space may be populated statically or via the traditional malloc
* mechanisms. Large blocks greater than the maximum class size may be
* allocated from the O/S or run-time system via malloc. To permit the use
* of malloc, call bopen with flags set to B_USE_MALLOC (this is the default).
* It is recommended that bopen be called first thing in the application.
* If it is not, it will be called with default values on the first call to
* balloc(). Note that this code is not designed for multi-threading purposes
* and it depends on newly declared variables being initialized to zero.
*/
/********************************* Includes ***********************************/
#define IN_BALLOC
#if UEMF
#include "uemf.h"
#else
#include "basic/basicInternal.h"
#endif
#include <stdarg.h>
#include <stdlib.h>
#if !NO_BALLOC
/********************************* Defines ************************************/
/*
* Define B_STATS if you wish to track memory block and stack usage
*/
#if B_STATS
/*
* Optional statistics
*/
typedef struct {
long alloc; /* Block allocation calls */
long inuse; /* Blocks in use */
} bStatsType;
typedef struct {
char_t file[FNAMESIZE];
long allocated; /* Bytes currently allocated */
long count; /* Current block count */
long times; /* Count of alloc attempts */
long largest; /* largest allocated here */
int q;
} bStatsFileType;
/*
* This one is very expensive but great stats
*/
typedef struct {
void *ptr; /* Pointer to memory */
bStatsFileType *who; /* Who allocated the memory */
} bStatsBlkType;
static bStatsType bStats[B_MAX_CLASS]; /* Per class stats */
static bStatsFileType bStatsFiles[B_MAX_FILES];/* Per file stats */
static bStatsBlkType bStatsBlks[B_MAX_BLOCKS];/* Per block stats */
static int bStatsBlksMax = 0; /* Max block entry */
static int bStatsFilesMax = 0; /* Max file entry */
static int bStatsMemInUse = 0; /* Memory currently in use */
static int bStatsBallocInUse = 0; /* Memory currently balloced */
static int bStatsMemMax = 0; /* Max memory ever used */
static int bStatsBallocMax = 0; /* Max memory ever balloced */
static void *bStackMin = (void*) -1;/* Miniumum stack position */
static void *bStackStart; /* Starting stack position */
static int bStatsMemMalloc = 0; /* Malloced memory */
#endif /* B_STATS */
/*
* ROUNDUP4(size) returns the next higher integer value of size that is
* divisible by 4, or the value of size if size is divisible by 4.
* ROUNDUP4() is used in aligning memory allocations on 4-byte boundaries.
*
* Note: ROUNDUP4() is only required on some operating systems (IRIX).
*/
#define ROUNDUP4(size) ((size) % 4) ? (size) + (4 - ((size) % 4)) : (size)
/********************************** Locals ************************************/
/*
* bQhead blocks are created as the original memory allocation is freed up.
* See bfree.
*/
static bType *bQhead[B_MAX_CLASS]; /* Per class block q head */
static char *bFreeBuf; /* Pointer to free memory */
static char *bFreeNext; /* Pointer to next free mem */
static int bFreeSize; /* Size of free memory */
static int bFreeLeft; /* Size of free left for use */
static int bFlags = B_USE_MALLOC; /* Default to auto-malloc */
static int bopenCount = 0; /* Num tasks using balloc */
/*************************** Forward Declarations *****************************/
#if B_STATS
static void bStatsAlloc(B_ARGS_DEC, void *ptr, int q, int size);
static void bStatsFree(B_ARGS_DEC, void *ptr, int q, int size);
static void bstatsWrite(int handle, char_t *fmt, ...);
static int bStatsFileSort(const void *cp1, const void *cp2);
#endif /* B_STATS */
#if B_FILL || B_VERIFY_CAUSES_SEVERE_OVERHEAD
static void bFillBlock(void *buf, int bufsize);
#endif
#if B_VERIFY_CAUSES_SEVERE_OVERHEAD
static void verifyUsedBlock(bType *bp, int q);
static void verifyFreeBlock(bType *bp, int q);
void verifyBallocSpace();
#endif
static int ballocGetSize(int size, int *q);
/********************************** Code **************************************/
/*
* Initialize the balloc module. bopen should be called the very first thing
* after the application starts and bclose should be called the last thing
* before exiting. If bopen is not called, it will be called on the first
* allocation with default values. "buf" points to memory to use of size
* "bufsize". If buf is NULL, memory is allocated using malloc. flags may
* be set to B_USE_MALLOC if using malloc is okay. This routine will allocate
* an initial buffer of size bufsize for use by the application.
*/
int bopen(void *buf, int bufsize, int flags)
{
bFlags = flags;
#if BASTARD_TESTING
srand(time(0L));
#endif /* BASTARD_TESTING */
/*
* If bopen already called by a shared process, just increment the count
* and return;
*/
if (++bopenCount > 1) {
return 0;
}
if (buf == NULL) {
if (bufsize == 0) {
bufsize = B_DEFAULT_MEM;
}
#ifdef IRIX
bufsize = ROUNDUP4(bufsize);
#endif
if ((buf = malloc(bufsize)) == NULL) {
return -1;
}
#if B_STATS
bStatsMemMalloc += bufsize;
#endif
} else {
bFlags |= B_USER_BUF;
}
bFreeSize = bFreeLeft = bufsize;
bFreeBuf = bFreeNext = buf;
memset(bQhead, 0, sizeof(bQhead));
#if B_FILL || B_VERIFY_CAUSES_SEVERE_OVERHEAD
bFillBlock(buf, bufsize);
#endif
#if B_STATS
bStackStart = &buf;
#endif
#if B_VERIFY_CAUSES_SEVERE_OVERHEAD
verifyFreeBlock(buf, bufsize);
#endif
return 0;
}
/******************************************************************************/
/*
* Close down the balloc module and free all malloced memory.
*/
void bclose()
{
#if B_VERIFY_CAUSES_SEVERE_OVERHEAD
verifyBallocSpace();
#endif
if (--bopenCount <= 0 && !(bFlags & B_USER_BUF)) {
free(bFreeBuf);
bopenCount = 0;
}
}
/******************************************************************************/
/*
* Allocate a block of the requested size. First check the block
* queues for a suitable one.
*/
void *balloc(B_ARGS_DEC, int size)
{
bType *bp;
int q, memSize;
/*
* Call bopen with default values if the application has not yet done so
*/
if (bFreeBuf == NULL) {
if (bopen(NULL, B_DEFAULT_MEM, 0) < 0) {
return NULL;
}
}
#if B_VERIFY_CAUSES_SEVERE_OVERHEAD
verifyBallocSpace();
#endif
if (size < 0) {
return NULL;
}
#if BASTARD_TESTING
if (rand() == 0x7fff) {
return NULL;
}
#endif /* BASTARD_TESTING */
memSize = ballocGetSize(size, &q);
if (q >= B_MAX_CLASS) {
/*
* Size if bigger than the maximum class. Malloc if use has been okayed
*/
if (bFlags & B_USE_MALLOC) {
#if B_STATS
bstats(0, NULL);
#endif
#ifdef IRIX
memSize = ROUNDUP4(memSize);
#endif
bp = (bType*) malloc(memSize);
if (bp == NULL) {
traceRaw(T("B: malloc failed\n"));
return NULL;
}
#if B_STATS
bStatsMemMalloc += memSize;
#endif
#if B_FILL || B_VERIFY_CAUSES_SEVERE_OVERHEAD
bFillBlock(bp, memSize);
#endif
} else {
traceRaw(T("B: malloc failed\n"));
return NULL;
}
/*
* the u.size is the actual size allocated for data
*/
bp->u.size = memSize - sizeof(bType);
bp->flags = B_MALLOCED;
} else if ((bp = bQhead[q]) != NULL) {
/*
* Take first block off the relevant q if non-empty
*/
bQhead[q] = bp->u.next;
#if B_VERIFY_CAUSES_SEVERE_OVERHEAD
verifyFreeBlock(bp, q);
#endif
#if B_FILL || B_VERIFY_CAUSES_SEVERE_OVERHEAD
bFillBlock(bp, memSize);
#endif
bp->u.size = memSize - sizeof(bType);
bp->flags = 0;
} else {
if (bFreeLeft > memSize) {
/*
* The q was empty, and the free list has spare memory so
* create a new block out of the primary free block
*/
bp = (bType*) bFreeNext;
#if B_VERIFY_CAUSES_SEVERE_OVERHEAD
verifyFreeBlock(bp, q);
#endif
bFreeNext += memSize;
bFreeLeft -= memSize;
#if B_FILL || B_VERIFY_CAUSES_SEVERE_OVERHEAD
bFillBlock(bp, memSize);
#endif
bp->u.size = memSize - sizeof(bType);
bp->flags = 0;
} else if (bFlags & B_USE_MALLOC) {
#if B_STATS
static int once = 0;
if (once++ == 0) {
bstats(0, NULL);
}
#endif
/*
* Nothing left on the primary free list, so malloc a new block
*/
#ifdef IRIX
memSize = ROUNDUP4(memSize);
#endif
if ((bp = (bType*) malloc(memSize)) == NULL) {
traceRaw(T("B: malloc failed\n"));
return NULL;
}
#if B_STATS
bStatsMemMalloc += memSize;
#endif
#if B_FILL || B_VERIFY_CAUSES_SEVERE_OVERHEAD
bFillBlock(bp, memSize);
#endif
bp->u.size = memSize - sizeof(bType);
bp->flags = B_MALLOCED;
} else {
traceRaw(T("B: malloc failed\n"));
return NULL;
}
}
#if B_STATS
bStatsAlloc(B_ARGS, bp, q, memSize);
#endif
bp->flags |= B_INTEGRITY;
/*
* The following is a good place to put a breakpoint when trying to reduce
* determine and reduce maximum memory use.
*/
#if 0
#if B_STATS
if (bStatsBallocInUse == bStatsBallocMax) {
bstats(0, NULL);
}
#endif
#endif
return (void*) ((char*) bp + sizeof(bType));
}
/******************************************************************************/
/*
* Free a block back to the relevant free q. We don't free back to the O/S
* or run time system unless the block is greater than the maximum class size.
* We also do not coalesce blocks.
*/
void bfree(B_ARGS_DEC, void *mp)
{
bType *bp;
int q, memSize;
#if B_VERIFY_CAUSES_SEVERE_OVERHEAD
verifyBallocSpace();
#endif
bp = (bType*) ((char*) mp - sizeof(bType));
a_assert((bp->flags & B_INTEGRITY_MASK) == B_INTEGRITY);
if ((bp->flags & B_INTEGRITY_MASK) != B_INTEGRITY) {
return;
}
memSize = ballocGetSize(bp->u.size, &q);
#if B_VERIFY_CAUSES_SEVERE_OVERHEAD
verifyUsedBlock(bp,q);
#endif
#if B_STATS
bStatsFree(B_ARGS, bp, q, bp->u.size+sizeof(bType));
#endif
if (bp->flags & B_MALLOCED) {
free(bp);
return;
}
#if B_VERIFY_CAUSES_SEVERE_OVERHEAD
bFillBlock(bp, memSize);
#endif
/*
* Simply link onto the head of the relevant q
*/
bp->u.next = bQhead[q];
bQhead[q] = bp;
bp->flags = B_FILL_WORD;
}
/******************************************************************************/
/*
* Safe free
*/
void bfreeSafe(B_ARGS_DEC, void *mp)
{
if (mp) {
bfree(B_ARGS, mp);
}
}
/******************************************************************************/
#if UNICODE
/*
* Duplicate a string, allow NULL pointers and then dup an empty string.
*/
char *bstrdupA(B_ARGS_DEC, char *s)
{
char *cp;
int len;
if (s == NULL) {
s = "";
}
len = strlen(s) + 1;
if (cp = balloc(B_ARGS, len)) {
strcpy(cp, s);
}
return cp;
}
#endif /* UNICODE */
/******************************************************************************/
/*
* Duplicate an ascii string, allow NULL pointers and then dup an empty string.
* If UNICODE, bstrdup above works with wide chars, so we need this routine
* for ascii strings.
*/
char_t *bstrdup(B_ARGS_DEC, char_t *s)
{
char_t *cp;
int len;
if (s == NULL) {
s = T("");
}
len = gstrlen(s) + 1;
if ((cp = balloc(B_ARGS, len * sizeof(char_t))) != NULL) {
gstrcpy(cp, s);
}
return cp;
}
/******************************************************************************/
/*
* Reallocate a block. Allow NULL pointers and just do a malloc.
* Note: if the realloc fails, we return NULL and the previous buffer is
* preserved.
*/
void *brealloc(B_ARGS_DEC, void *mp, int newsize)
{
bType *bp;
void *newbuf;
if (mp == NULL) {
return balloc(B_ARGS, newsize);
}
bp = (bType*) ((char*) mp - sizeof(bType));
a_assert((bp->flags & B_INTEGRITY_MASK) == B_INTEGRITY);
/*
* If the allocated memory already has enough room just return the previously
* allocated address.
*/
if (bp->u.size >= newsize) {
return mp;
}
if ((newbuf = balloc(B_ARGS, newsize)) != NULL) {
memcpy(newbuf, mp, bp->u.size);
bfree(B_ARGS, mp);
}
return newbuf;
}
/******************************************************************************/
/*
* Find the size of the block to be balloc'ed. It takes in a size, finds the
* smallest binary block it fits into, adds an overhead amount and returns.
* q is the binary size used to keep track of block sizes in use. Called
* from both balloc and bfree.
*/
static int ballocGetSize(int size, int *q)
{
int mask;
mask = (size == 0) ? 0 : (size-1) >> B_SHIFT;
for (*q = 0; mask; mask >>= 1) {
*q = *q + 1;
}
return ((1 << (B_SHIFT + *q)) + sizeof(bType));
}
/******************************************************************************/
#if B_FILL || B_VERIFY_CAUSES_SEVERE_OVERHEAD
/*
* Fill the block (useful during development to catch zero fill assumptions)
*/
static void bFillBlock(void *buf, int bufsize)
{
memset(buf, B_FILL_CHAR, bufsize);
}
#endif
/******************************************************************************/
#if B_STATS
/*
* Statistics. Do output via calling the writefn callback function with
* "handle" as the output file handle.
*/
void bstats(int handle, void (*writefn)(int handle, char_t *fmt, ...))
{
bStatsFileType *fp, *files;
bStatsBlkType *blkp;
bType *bp;
char_t *cp;
int q, count, mem, total, len;
static int recurseProtect = 0;
if (recurseProtect++ > 0) {
recurseProtect--;
return;
}
if (writefn == NULL) {
writefn = bstatsWrite;
}
/*
* Print stats for each memory block
*/
(*writefn)(handle, T("\nMemory Stats\n"));
/*
* The following tabular format is now used for the output.
* Q Size Free Bytes Inuse Bytes Allocs
* dd ddddd ddd ddddd dddd ddddd dddd
*/
(*writefn)(handle, " Q Size Free Bytes Inuse Bytes Allocs\n");
total = 0;
for (q = 0; q < B_MAX_CLASS; q++) {
count = 0;
for (bp = bQhead[q]; bp; bp = bp->u.next) {
count++;
}
mem = count * (1 << (q + B_SHIFT));
total += mem;
(*writefn)(handle,
T("%2d %5d %4d %6d %4d %5d %4d\n"),
q, 1 << (q + B_SHIFT), count, mem, bStats[q].inuse,
bStats[q].inuse * (1 << (q + B_SHIFT)), bStats[q].alloc);
}
(*writefn)(handle, T("\n"));
/*
* Print summary stats
*
* bFreeSize Initial memory reserved with bopen call
* bStatsMemMalloc memory from calls to system MALLOC
* bStatsMemMax
* bStatsBallocMax largest amount of memory from balloc calls
* bStatsMemInUse
* bStatsBallocInUse present balloced memory being used
* bStatsBlksMax);
* bStackStart
* bStackMin);
* total);
* bFreeLeft);
*
*/
(*writefn)(handle, T("Initial free list size %7d\n"), bFreeSize);
(*writefn)(handle, T("Max memory malloced %7d\n"), bStatsMemMalloc);
(*writefn)(handle, T("Max memory ever used %7d\n"), bStatsMemMax);
(*writefn)(handle, T("Max memory ever balloced %7d\n"), bStatsBallocMax);
(*writefn)(handle, T("Memory currently in use %7d\n"), bStatsMemInUse);
(*writefn)(handle, T("Memory currently balloced %7d\n"), bStatsBallocInUse);
(*writefn)(handle, T("Max blocks allocated %7d\n"), bStatsBlksMax);
(*writefn)(handle, T("Maximum stack used %7d\n"),
(int) bStackStart - (int) bStackMin);
(*writefn)(handle, T("Free memory on all queues %7d\n"), total);
(*writefn)(handle, T("Free list buffer left %7d\n"), bFreeLeft);
(*writefn)(handle, T("Total free memory %7d\n"), bFreeLeft + total);
/*
* Print per file allocation stats. Sort the copied table.
*/
len = sizeof(bStatsFileType) * B_MAX_FILES;
files = malloc(len);
if (files == NULL) {
(*writefn)(handle, T("Can't allocate stats memory\n"));
recurseProtect--;
return;
}
memcpy(files, bStatsFiles, len);
qsort(files, bStatsFilesMax, sizeof(bStatsFileType), bStatsFileSort);
(*writefn)(handle, T("\nMemory Currently Allocated\n"));
total = 0;
(*writefn)(handle,
T(" bytes, blocks in use, total times,")
T("largest, q\n"));
for (fp = files; fp < &files[bStatsFilesMax]; fp++) {
if (fp->file[0]) {
(*writefn)(handle, T("%18s, %7d, %5d, %6d, %7d,%4d\n"),
fp->file, fp->allocated, fp->count, fp->times, fp->largest,
fp->q);
total += fp->allocated;
}
}
(*writefn)(handle, T("\nTotal allocated %7d\n\n"), total);
/*
* Dump the actual strings
*/
(*writefn)(handle, T("\nStrings\n"));
for (blkp = &bStatsBlks[bStatsBlksMax - 1]; blkp >= bStatsBlks; blkp--) {
if (blkp->ptr) {
cp = (char_t*) ((char*) blkp->ptr + sizeof(bType));
fp = blkp->who;
if (gisalnum(*cp)) {
(*writefn)(handle, T("%-50s allocated by %s\n"), cp,
fp->file);
}
}
}
free(files);
recurseProtect--;
}
/******************************************************************************/
/*
* File sort function. Used to sort per file stats
*/
static int bStatsFileSort(const void *cp1, const void *cp2)
{
bStatsFileType *s1, *s2;
s1 = (bStatsFileType*) cp1;
s2 = (bStatsFileType*) cp2;
if (s1->allocated < s2->allocated)
return -1;
else if (s1->allocated == s2->allocated)
return 0;
return 1;
}
/******************************************************************************/
/*
* Accumulate allocation statistics
*/
static void bStatsAlloc(B_ARGS_DEC, void *ptr, int q, int size)
{
int memSize;
bStatsFileType *fp;
bStatsBlkType *bp;
char_t name[FNAMESIZE + 10];
gsprintf(name, T("%s:%d"), B_ARGS);
bStats[q].alloc++;
bStats[q].inuse++;
bStatsMemInUse += size;
if (bStatsMemInUse > bStatsMemMax) {
bStatsMemMax = bStatsMemInUse;
}
memSize = (1 << (B_SHIFT + q)) + sizeof(bType);
bStatsBallocInUse += memSize;
if (bStatsBallocInUse > bStatsBallocMax) {
bStatsBallocMax = bStatsBallocInUse;
}
/*
* Track maximum stack usage. Assumes a stack growth down. Approximate as
* we only measure this on block allocation.
*/
if ((void*) &file < bStackMin) {
bStackMin = (void*) &file;
}
/*
* Find the file and adjust the stats for this file
*/
for (fp = bStatsFiles; fp < &bStatsFiles[bStatsFilesMax]; fp++) {
if (fp->file[0] == file[0] && gstrcmp(fp->file, name) == 0) {
fp->allocated += size;
fp->count++;
fp->times++;
if (fp->largest < size) {
fp->largest = size;
fp->q = q;
}
break;
}
}
/*
* New entry: find the first free slot and create a new entry
*/
if (fp >= &bStatsFiles[bStatsFilesMax]) {
for (fp = bStatsFiles; fp < &bStatsFiles[B_MAX_FILES]; fp++) {
if (fp->file[0] == '\0') {
gstrncpy(fp->file, name, TSZ(fp->file));
fp->allocated += size;
fp->count++;
fp->times++;
fp->largest = size;
fp->q = q;
if ((fp - bStatsFiles) >= bStatsFilesMax) {
bStatsFilesMax = (fp - bStatsFiles) + 1;
}
break;
}
}
}
/*
* Update the per block stats. Allocate a new slot.
*/
for (bp = bStatsBlks; bp < &bStatsBlks[B_MAX_BLOCKS]; bp++) {
if (bp->ptr == NULL) {
bp->ptr = ptr;
bp->who = fp;
if ((bp - bStatsBlks) >= bStatsBlksMax) {
bStatsBlksMax = (bp - bStatsBlks) + 1;
}
break;
}
}
}
/******************************************************************************/
/*
* Free statistics
*/
static void bStatsFree(B_ARGS_DEC, void *ptr, int q, int size)
{
int memSize;
bStatsFileType *fp;
bStatsBlkType *bp;
memSize = (1 << (B_SHIFT + q)) + sizeof(bType);
bStatsMemInUse -= size;
bStatsBallocInUse -= memSize;
bStats[q].inuse--;
/*
* Update the per block stats. Try from the end first
*/
for (bp = &bStatsBlks[bStatsBlksMax - 1]; bp >= bStatsBlks; bp--) {
if (bp->ptr == ptr) {
bp->ptr = NULL;
fp = bp->who;
bp->who = NULL;
fp->allocated -= size;
fp->count--;
return;
}
}
}
/******************************************************************************/
/*
* Default output function. Just send to trace channel.
*/
#undef sprintf
static void bstatsWrite(int handle, char_t *fmt, ...)
{
va_list args;
char_t buf[BUF_MAX];
va_start(args, fmt);
vsprintf(buf, fmt, args);
va_end(args);
traceRaw(buf);
}
#else /* not B_STATS */
/******************************************************************************/
/*
* Dummy bstats for external calls that aren't protected by #if B_STATS.
*/
void bstats(int handle, void (*writefn)(int handle, char_t *fmt, ...))
{
}
#endif /* B_STATS */
/******************************************************************************/
#if B_VERIFY_CAUSES_SEVERE_OVERHEAD
/*
* The following routines verify the integrity of the balloc memory space.
* These functions use the B_FILL feature. Corruption is defined
* as bad integrity flags in allocated blocks or data other than B_FILL_CHAR
* being found anywhere in the space which is unallocated and that is not a
* next pointer in the free queues. a_assert is called if any corruption is
* found. CAUTION: These functions add severe processing overhead and should
* only be used when searching for a tough corruption problem.
*/
/******************************************************************************/
/*
* verifyUsedBlock verifies that a block which was previously allocated is
* still uncorrupted.
*/
static void verifyUsedBlock(bType *bp, int q)
{
int memSize, size;
char *p;
memSize = (1 << (B_SHIFT + q)) + sizeof(bType);
a_assert((bp->flags & ~B_MALLOCED) == B_INTEGRITY);
size = bp->u.size;
for (p = ((char *)bp)+sizeof(bType)+size; p < ((char*)bp)+memSize; p++) {
a_assert(*p == B_FILL_CHAR);
}
}
/******************************************************************************/
/*
* verifyFreeBlock verifies that a previously free'd block in one of the queues
* is still uncorrupted.
*/
static void verifyFreeBlock(bType *bp, int q)
{
int memSize;
char *p;
memSize = (1 << (B_SHIFT + q)) + sizeof(bType);
for (p = ((char *)bp)+sizeof(void*); p < ((char*)bp)+memSize; p++) {
a_assert(*p == B_FILL_CHAR);
}
bp = (bType *)p;
a_assert((bp->flags & ~B_MALLOCED) == B_INTEGRITY ||
bp->flags == B_FILL_WORD);
}
/******************************************************************************/
/*
* verifyBallocSpace reads through the entire balloc memory space and
* verifies that all allocated blocks are uncorrupted and that, with the
* exception of free list next pointers, all other unallocated space is
* filled with B_FILL_CHAR.
*/
void verifyBallocSpace()
{
int q;
char *p;
bType *bp;
/*
* First verify all the free blocks.
*/
for (q = 0; q < B_MAX_CLASS; q++) {
for (bp = bQhead[q]; bp != NULL; bp = bp->u.next) {
verifyFreeBlock(bp, q);
}
}
/*
* Now verify other space
*/
p = bFreeBuf;
while (p < (bFreeBuf + bFreeSize)) {
bp = (bType *)p;
if (bp->u.size > 0xFFFFF) {
p += sizeof(bp->u);
while (p < (bFreeBuf + bFreeSize) && *p == B_FILL_CHAR) {
p++;
}
} else {
a_assert(((bp->flags & ~B_MALLOCED) == B_INTEGRITY) ||
bp->flags == B_FILL_WORD);
p += (sizeof(bType) + bp->u.size);
while (p < (bFreeBuf + bFreeSize) && *p == B_FILL_CHAR) {
p++;
}
}
}
}
#endif /* B_VERIFY_CAUSES_SEVERE_OVERHEAD */
/******************************************************************************/
#else /* NO_BALLOC */
int bopen(void *buf, int bufsize, int flags)
{
return 0;
}
/******************************************************************************/
void bclose()
{
}
/******************************************************************************/
void bstats(int handle, void (*writefn)(int handle, char_t *fmt, ...))
{
}
/******************************************************************************/
char_t *bstrdupNoBalloc(char_t *s)
{
#if UNICODE
if (s) {
return wcsdup(s);
} else {
return wcsdup(T(""));
}
#else
return bstrdupANoBalloc(s);
#endif
}
/******************************************************************************/
char *bstrdupANoBalloc(char *s)
{
char* buf;
if (s == NULL) {
s = "";
}
buf = malloc(strlen(s)+1);
strcpy(buf, s);
return buf;
}
#endif /* NO_BALLOC */
/******************************************************************************/

View File

@@ -1,402 +0,0 @@
/*
* default.c -- Default URL handler. Includes support for ASP.
*
* Copyright (c) GoAhead Software Inc., 1995-2000. All Rights Reserved.
*
* See the file "license.txt" for usage and redistribution license requirements
*
* $Id$
*/
/******************************** Description *********************************/
/*
* This module provides default URL handling and Active Server Page support.
*
* In many cases we don't check the return code of calls to websWrite as
* it is easier, smaller and non-fatal to continue even when the requesting
* browser has gone away.
*/
/********************************* Includes ***********************************/
#include "wsIntrn.h"
/*********************************** Locals ***********************************/
static char_t *websDefaultPage; /* Default page name */
static char_t *websDefaultDir; /* Default Web page directory */
/**************************** Forward Declarations ****************************/
static void websDefaultWriteEvent(webs_t wp);
/*********************************** Code *************************************/
/*
* Process a default URL request. This will validate the URL and handle "../"
* and will provide support for Active Server Pages. As the handler is the
* last handler to run, it always indicates that it has handled the URL
* by returning 1.
*/
int websDefaultHandler(webs_t wp, char_t *urlPrefix, char_t *webDir, int arg,
char_t *url, char_t *path, char_t *query)
{
websStatType sbuf;
char_t *lpath, *tmp, *date;
int bytes, flags, nchars;
a_assert(websValid(wp));
a_assert(url && *url);
a_assert(path);
a_assert(query);
/*
* Validate the URL and ensure that ".."s don't give access to unwanted files
*/
flags = websGetRequestFlags(wp);
if (websValidateUrl(wp, path) < 0) {
websError(wp, 500, T("Invalid URL %s"), url);
return 1;
}
lpath = websGetRequestLpath(wp);
nchars = gstrlen(lpath) - 1;
if (lpath[nchars] == '/' || lpath[nchars] == '\\') {
lpath[nchars] = '\0';
}
/*
* If the file is a directory, redirect using the nominated default page
*/
if (websPageIsDirectory(lpath)) {
nchars = gstrlen(path);
if (path[nchars-1] == '/' || path[nchars-1] == '\\') {
path[--nchars] = '\0';
}
nchars += gstrlen(websDefaultPage) + 2;
fmtAlloc(&tmp, nchars, T("%s/%s"), path, websDefaultPage);
websRedirect(wp, tmp);
bfreeSafe(B_L, tmp);
return 1;
}
/*
* Open the document. Stat for later use.
*/
if (websPageOpen(wp, lpath, path, SOCKET_RDONLY | SOCKET_BINARY,
0666) < 0) {
websError(wp, 400,
T("Cannot open URL <b>%s</b>"), url);
return 1;
}
if (websPageStat(wp, lpath, path, &sbuf) < 0) {
websError(wp, 400, T("Cannot stat page for URL <b>%s</b>"),
url);
return 1;
}
/*
* If the page has not been modified since the user last received it and it
* is not dynamically generated each time (ASP), then optimize request by
* sending a 304 Use local copy response
*/
websStats.localHits++;
#if WEBS_IF_MODIFIED_SUPPORT
if (flags & WEBS_IF_MODIFIED && !(flags & WEBS_ASP)) {
if (sbuf.mtime <= wp->since) {
websWrite(wp, T("HTTP/1.0 304 Use local copy\r\n"));
/*
* by license terms the following line of code must
* not be modified.
*/
websWrite(wp, T("Server: %s\r\n"), WEBS_NAME);
if (flags & WEBS_KEEP_ALIVE) {
websWrite(wp, T("Connection: keep-alive\r\n"));
}
websWrite(wp, T("\r\n"));
websSetRequestFlags(wp, flags |= WEBS_HEADER_DONE);
websDone(wp, 304);
return 1;
}
}
#endif
/*
* Output the normal HTTP response header
*/
if ((date = websGetDateString(NULL)) != NULL) {
websWrite(wp, T("HTTP/1.0 200 OK\r\nDate: %s\r\n"), date);
/*
* By license terms the following line of code must not be modified.
*/
websWrite(wp, T("Server: %s\r\n"), WEBS_NAME);
bfree(B_L, date);
}
flags |= WEBS_HEADER_DONE;
/*
* If this is an ASP request, ensure the remote browser doesn't cache it.
* Send back both HTTP/1.0 and HTTP/1.1 cache control directives
*/
if (flags & WEBS_ASP) {
bytes = 0;
websWrite(wp, T("Pragma: no-cache\r\nCache-Control: no-cache\r\n"));
} else {
if ((date = websGetDateString(&sbuf)) != NULL) {
websWrite(wp, T("Last-modified: %s\r\n"), date);
bfree(B_L, date);
}
bytes = sbuf.size;
}
if (bytes) {
websWrite(wp, T("Content-length: %d\r\n"), bytes);
websSetRequestBytes(wp, bytes);
}
websWrite(wp, T("Content-type: %s\r\n"), websGetRequestType(wp));
if ((flags & WEBS_KEEP_ALIVE) && !(flags & WEBS_ASP)) {
websWrite(wp, T("Connection: keep-alive\r\n"));
}
websWrite(wp, T("\r\n"));
/*
* All done if the browser did a HEAD request
*/
if (flags & WEBS_HEAD_REQUEST) {
websDone(wp, 200);
return 1;
}
/*
* Evaluate ASP requests
*/
if (flags & WEBS_ASP) {
if (websAspRequest(wp, lpath) < 0) {
return 1;
}
websDone(wp, 200);
return 1;
}
#ifdef WEBS_SSL_SUPPORT
if (wp->flags & WEBS_SECURE) {
websDefaultWriteEvent(wp);
} else {
websSetRequestSocketHandler(wp, SOCKET_WRITABLE, websDefaultWriteEvent);
}
#else
/*
* For normal web documents, return the data via background write
*/
websSetRequestSocketHandler(wp, SOCKET_WRITABLE, websDefaultWriteEvent);
#endif
return 1;
}
/******************************************************************************/
/*
* Validate the URL path and process ".." path segments. Return -1 if the URL
* is bad.
*/
int websValidateUrl(webs_t wp, char_t *path)
{
char_t *parts[64]; /* Array of ptr's to URL parts */
char_t *token, *dir, *lpath;
int i, len, npart;
a_assert(websValid(wp));
a_assert(path);
dir = websGetRequestDir(wp);
if (dir == NULL || *dir == '\0') {
return -1;
}
/*
* Copy the string so we don't destroy the original
*/
path = bstrdup(B_L, path);
websDecodeUrl(path, path, gstrlen(path));
len = npart = 0;
parts[0] = NULL;
token = gstrtok(path, T("/"));
/*
* Look at each directory segment and process "." and ".." segments
* Don't allow the browser to pop outside the root web.
*/
while (token != NULL) {
if (gstrcmp(token, T("..")) == 0) {
if (npart > 0) {
npart--;
}
} else if (gstrcmp(token, T(".")) != 0) {
parts[npart] = token;
len += gstrlen(token) + 1;
npart++;
}
token = gstrtok(NULL, T("/"));
}
/*
* Create local path for document. Need extra space all "/" and null.
*/
if (npart || (gstrcmp(path, T("/")) == 0) || (path[0] == '\0')) {
lpath = balloc(B_L, (gstrlen(dir) + 1 + len + 1) * sizeof(char_t));
gstrcpy(lpath, dir);
for (i = 0; i < npart; i++) {
gstrcat(lpath, T("/"));
gstrcat(lpath, parts[i]);
}
websSetRequestLpath(wp, lpath);
bfree(B_L, path);
bfree(B_L, lpath);
} else {
bfree(B_L, path);
return -1;
}
return 0;
}
/******************************************************************************/
/*
* Do output back to the browser in the background. This is a socket
* write handler.
*/
static void websDefaultWriteEvent(webs_t wp)
{
int len, wrote, flags, bytes, written;
char *buf;
a_assert(websValid(wp));
flags = websGetRequestFlags(wp);
websMarkTime(wp);
wrote = bytes = 0;
written = websGetRequestWritten(wp);
/*
* We only do this for non-ASP documents
*/
if ( !(flags & WEBS_ASP)) {
bytes = websGetRequestBytes(wp);
/*
* Note: websWriteDataNonBlock may return less than we wanted. It will
* return -1 on a socket error
*/
if ((buf = balloc(B_L, PAGE_READ_BUFSIZE)) == NULL) {
websError(wp, 200, T("Can't get memory"));
}
else {
while ((len = websPageReadData(wp, buf, PAGE_READ_BUFSIZE)) > 0) {
if ((wrote = websWriteDataNonBlock(wp, buf, len)) < 0) {
break;
}
written += wrote;
if (wrote != len) {
websPageSeek(wp, - (len - wrote));
break;
}
}
/*
* Safety. If we are at EOF, we must be done
*/
if (len == 0) {
a_assert(written >= bytes);
written = bytes;
}
bfree(B_L, buf);
}
}
/*
* We're done if an error, or all bytes output
*/
websSetRequestWritten(wp, written);
if (wrote < 0 || written >= bytes) {
websDone(wp, 200);
}
}
/******************************************************************************/
/*
* Closing down. Free resources.
*/
void websDefaultClose()
{
if (websDefaultPage) {
bfree(B_L, websDefaultPage);
websDefaultPage = NULL;
}
if (websDefaultDir) {
bfree(B_L, websDefaultDir);
websDefaultDir = NULL;
}
}
/******************************************************************************/
/*
* Get the default page for URL requests ending in "/"
*/
char_t *websGetDefaultPage()
{
return websDefaultPage;
}
/******************************************************************************/
/*
* Get the default web directory
*/
char_t *websGetDefaultDir()
{
return websDefaultDir;
}
/******************************************************************************/
/*
* Set the default page for URL requests ending in "/"
*/
void websSetDefaultPage(char_t *page)
{
a_assert(page && *page);
if (websDefaultPage) {
bfree(B_L, websDefaultPage);
}
websDefaultPage = bstrdup(B_L, page);
}
/******************************************************************************/
/*
* Set the default web directory
*/
void websSetDefaultDir(char_t *dir)
{
a_assert(dir && *dir);
if (websDefaultDir) {
bfree(B_L, websDefaultDir);
}
websDefaultDir = bstrdup(B_L, dir);
}
/******************************************************************************/

View File

@@ -1,44 +0,0 @@
/*
* ej.h -- Ejscript(TM) header
*
* Copyright (c) GoAhead Software Inc., 1992-2000. All Rights Reserved.
*
* See the file "license.txt" for information on usage and redistribution
*/
#ifndef _h_EJ
#define _h_EJ 1
/******************************** Description *********************************/
/*
* GoAhead Ejscript(TM) header. This defines the Ejscript API and internal
* structures.
*/
/********************************* Includes ***********************************/
#if ! UEMF
#include "basic/basic.h"
#include "emf/emf.h"
#else
#include "uemf.h"
#endif
/********************************** Defines ***********************************/
/******************************** Prototypes **********************************/
extern int ejArgs(int argc, char_t **argv, char_t *fmt, ...);
extern void ejSetResult(int eid, char_t *s);
extern int ejOpenEngine(sym_fd_t variables, sym_fd_t functions);
extern void ejCloseEngine(int eid);
extern int ejSetGlobalFunction(int eid, char_t *name,
int (*fn)(int eid, void *handle, int argc, char_t **argv));
extern void ejSetVar(int eid, char_t *var, char_t *value);
extern int ejGetVar(int eid, char_t *var, char_t **value);
extern char_t *ejEval(int eid, char_t *script, char_t **emsg);
#endif /* _h_EJ */
/*****************************************************************************/

View File

@@ -1,228 +0,0 @@
/*
* ejIntrn.h -- Ejscript(TM) header
*
* Copyright (c) GoAhead Software, Inc., 1992-2000
*
* See the file "license.txt" for information on usage and redistribution
*/
#ifndef _h_EJINTERNAL
#define _h_EJINTERNAL 1
/******************************** Description *********************************/
/*
* GoAhead Ejscript(TM) header. This defines the Ejscript API and internal
* structures.
*/
/********************************* Includes ***********************************/
#include <ctype.h>
#include <stdarg.h>
#include <stdlib.h>
#if CE
#if ! UEMF
#include <io.h>
#endif
#endif
#if LYNX
#include <unistd.h>
#endif
#ifdef QNX4
#include <dirent.h>
#endif
#if UEMF
#include "uemf.h"
#else
#include <param.h>
#include <stat.h>
#include "basic/basicInternal.h"
#include "emf/emfInternal.h"
#endif
#include "ej.h"
/********************************** Defines ***********************************/
/*
* Constants
*/
#define EJ_INC 110 /* Growth for tags/tokens */
#define EJ_SCRIPT_INC 1023 /* Growth for ej scripts */
#define EJ_OFFSET 1 /* hAlloc doesn't like 0 entries */
#define EJ_MAX_RECURSE 100 /* Sanity for maximum recursion */
/*
* Ejscript Lexical analyser tokens
*/
#define TOK_ERR -1 /* Any error */
#define TOK_LPAREN 1 /* ( */
#define TOK_RPAREN 2 /* ) */
#define TOK_IF 3 /* if */
#define TOK_ELSE 4 /* else */
#define TOK_LBRACE 5 /* { */
#define TOK_RBRACE 6 /* } */
#define TOK_LOGICAL 7 /* ||, &&, ! */
#define TOK_EXPR 8 /* +, -, /, % */
#define TOK_SEMI 9 /* ; */
#define TOK_LITERAL 10 /* literal string */
#define TOK_FUNCTION 11 /* function name */
#define TOK_NEWLINE 12 /* newline white space */
#define TOK_ID 13 /* function name */
#define TOK_EOF 14 /* End of script */
#define TOK_COMMA 15 /* Comma */
#define TOK_VAR 16 /* var */
#define TOK_ASSIGNMENT 17 /* = */
#define TOK_FOR 18 /* for */
#define TOK_INC_DEC 19 /* ++, -- */
#define TOK_RETURN 20 /* return */
/*
* Expression operators
*/
#define EXPR_LESS 1 /* < */
#define EXPR_LESSEQ 2 /* <= */
#define EXPR_GREATER 3 /* > */
#define EXPR_GREATEREQ 4 /* >= */
#define EXPR_EQ 5 /* == */
#define EXPR_NOTEQ 6 /* != */
#define EXPR_PLUS 7 /* + */
#define EXPR_MINUS 8 /* - */
#define EXPR_DIV 9 /* / */
#define EXPR_MOD 10 /* % */
#define EXPR_LSHIFT 11 /* << */
#define EXPR_RSHIFT 12 /* >> */
#define EXPR_MUL 13 /* * */
#define EXPR_ASSIGNMENT 14 /* = */
#define EXPR_INC 15 /* ++ */
#define EXPR_DEC 16 /* -- */
#define EXPR_BOOL_COMP 17 /* ! */
/*
* Conditional operators
*/
#define COND_AND 1 /* && */
#define COND_OR 2 /* || */
#define COND_NOT 3 /* ! */
/*
* States
*/
#define STATE_ERR -1 /* Error state */
#define STATE_EOF 1 /* End of file */
#define STATE_COND 2 /* Parsing a "(conditional)" stmt */
#define STATE_COND_DONE 3
#define STATE_RELEXP 4 /* Parsing a relational expr */
#define STATE_RELEXP_DONE 5
#define STATE_EXPR 6 /* Parsing an expression */
#define STATE_EXPR_DONE 7
#define STATE_STMT 8 /* Parsing General statement */
#define STATE_STMT_DONE 9
#define STATE_STMT_BLOCK_DONE 10 /* End of block "}" */
#define STATE_ARG_LIST 11 /* Function arg list */
#define STATE_ARG_LIST_DONE 12
#define STATE_DEC_LIST 16 /* Declaration list */
#define STATE_DEC_LIST_DONE 17
#define STATE_DEC 18
#define STATE_DEC_DONE 19
#define STATE_RET 20 /* Return statement */
#define STATE_BEGIN STATE_STMT
/*
* Flags. Used in ej_t and as parameter to parse()
*/
#define FLAGS_EXE 0x1 /* Execute statements */
#define FLAGS_VARIABLES 0x2 /* Allocated variables store */
#define FLAGS_FUNCTIONS 0x4 /* Allocated function store */
/*
* Function call structure
*/
typedef struct {
char_t *fname; /* Function name */
char_t **args; /* Args for function (halloc) */
int nArgs; /* Number of args */
} ejfunc_t;
/*
* EJ evaluation block structure
*/
typedef struct ejEval {
ringq_t tokbuf; /* Current token */
ringq_t script; /* Input script for parsing */
char_t *putBackToken; /* Putback token string */
int putBackTokenId; /* Putback token ID */
char_t *line; /* Current line */
int lineLength; /* Current line length */
int lineNumber; /* Parse line number */
int lineColumn; /* Column in line */
} ejinput_t;
/*
* Per Ejscript session structure
*/
typedef struct ej {
ejinput_t *input; /* Input evaluation block */
sym_fd_t functions; /* Symbol table for functions */
sym_fd_t *variables; /* hAlloc list of variables */
int variableMax; /* Number of entries */
ejfunc_t *func; /* Current function */
char_t *result; /* Current expression result */
char_t *error; /* Error message */
char_t *token; /* Pointer to token string */
int tid; /* Current token id */
int eid; /* Halloc handle */
int flags; /* Flags */
int userHandle; /* User defined handle */
} ej_t;
/******************************** Prototypes **********************************/
extern int ejOpenBlock(int eid);
extern int ejCloseBlock(int eid, int vid);
extern char_t *ejEvalBlock(int eid, char_t *script, char_t **emsg);
#ifndef __NO_EJ_FILE
extern char_t *ejEvalFile(int eid, char_t *path, char_t **emsg);
#endif
extern int ejRemoveGlobalFunction(int eid, char_t *name);
extern void *ejGetGlobalFunction(int eid, char_t *name);
extern int ejSetGlobalFunctionDirect(sym_fd_t functions, char_t *name,
int (*fn)(int eid, void *handle, int argc, char_t **argv));
extern void ejError(ej_t* ep, char_t* fmt, ...);
extern void ejSetUserHandle(int eid, int handle);
extern int ejGetUserHandle(int eid);
extern int ejGetLineNumber(int eid);
extern char_t *ejGetResult(int eid);
extern void ejSetLocalVar(int eid, char_t *var, char_t *value);
extern void ejSetGlobalVar(int eid, char_t *var, char_t *value);
extern int ejLexOpen(ej_t* ep);
extern void ejLexClose(ej_t* ep);
extern int ejLexOpenScript(ej_t* ep, char_t *script);
extern void ejLexCloseScript(ej_t* ep);
extern void ejLexSaveInputState(ej_t* ep, ejinput_t* state);
extern void ejLexFreeInputState(ej_t* ep, ejinput_t* state);
extern void ejLexRestoreInputState(ej_t* ep, ejinput_t* state);
extern int ejLexGetToken(ej_t* ep, int state);
extern void ejLexPutbackToken(ej_t* ep, int tid, char_t *string);
extern sym_fd_t ejGetVariableTable(int eid);
extern sym_fd_t ejGetFunctionTable(int eid);
extern int ejEmfOpen(int eid);
extern void ejEmfClose(int eid);
extern int ejEmfDbRead(int eid, void *handle, int argc, char_t **argv);
extern int ejEmfDbReadKeyed(int eid, void *handle, int argc, char_t **argv);
extern int ejEmfDbTableGetNrow(int eid, void *handle, int argc, char_t **argv);
extern int ejEmfDbDeleteRow(int eid, void *handle, int argc, char_t **argv);
extern int ejEmfTrace(int eid, void *handle, int argc, char_t **argv);
extern int ejEmfDbWrite(int eid, void *handle, int argc, char_t **argv);
extern int ejEmfDbCollectTable(int eid, void *handle, int argc, char_t **argv);
#endif /* _h_EJINTERNAL */

View File

@@ -1,713 +0,0 @@
/*
* ejlex.c -- Ejscript(TM) Lexical Analyser
*
* Copyright (c) GoAhead Software Inc., 1995-2000. All Rights Reserved.
*
* See the file "license.txt" for usage and redistribution license requirements
*/
/******************************** Description *********************************/
/*
* Ejscript lexical analyser. This implementes a lexical analyser for a
* a subset of the JavaScript language.
*/
/********************************** Includes **********************************/
#include "ejIntrn.h"
#if UEMF
#include "uemf.h"
#else
#include "basic/basicInternal.h"
#endif
/********************************** Defines ***********************************/
#define OCTAL 8
#define HEX 16
/****************************** Forward Declarations **************************/
static int getLexicalToken(ej_t* ep, int state);
static int tokenAddChar(ej_t *ep, int c);
static int inputGetc(ej_t* ep);
static void inputPutback(ej_t* ep, int c);
static int charConvert(ej_t* ep, int base, int maxDig);
/************************************* Code ***********************************/
/*
* Setup the lexical analyser
*/
int ejLexOpen(ej_t* ep)
{
return 0;
}
/******************************************************************************/
/*
* Close the lexicial analyser
*/
void ejLexClose(ej_t* ep)
{
}
/******************************************************************************/
/*
* Open a new input script
*/
int ejLexOpenScript(ej_t* ep, char_t *script)
{
ejinput_t *ip;
a_assert(ep);
a_assert(script);
if ((ep->input = balloc(B_L, sizeof(ejinput_t))) == NULL) {
return -1;
}
ip = ep->input;
memset(ip, 0, sizeof(*ip));
a_assert(ip);
a_assert(ip->putBackToken == NULL);
a_assert(ip->putBackTokenId == 0);
/*
* Create the parse token buffer and script buffer
*/
if (ringqOpen(&ip->tokbuf, EJ_INC, -1) < 0) {
return -1;
}
if (ringqOpen(&ip->script, EJ_SCRIPT_INC, -1) < 0) {
return -1;
}
/*
* Put the Ejscript into a ring queue for easy parsing
*/
ringqPutStr(&ip->script, script);
ip->lineNumber = 1;
ip->lineLength = 0;
ip->lineColumn = 0;
ip->line = NULL;
return 0;
}
/******************************************************************************/
/*
* Close the input script
*/
void ejLexCloseScript(ej_t* ep)
{
ejinput_t *ip;
a_assert(ep);
ip = ep->input;
a_assert(ip);
if (ip->putBackToken) {
bfree(B_L, ip->putBackToken);
ip->putBackToken = NULL;
}
ip->putBackTokenId = 0;
if (ip->line) {
bfree(B_L, ip->line);
ip->line = NULL;
}
ringqClose(&ip->tokbuf);
ringqClose(&ip->script);
bfree(B_L, ip);
}
/******************************************************************************/
/*
* Save the input state
*/
void ejLexSaveInputState(ej_t* ep, ejinput_t* state)
{
ejinput_t *ip;
a_assert(ep);
ip = ep->input;
a_assert(ip);
*state = *ip;
if (ip->putBackToken) {
state->putBackToken = bstrdup(B_L, ip->putBackToken);
}
}
/******************************************************************************/
/*
* Restore the input state
*/
void ejLexRestoreInputState(ej_t* ep, ejinput_t* state)
{
ejinput_t *ip;
a_assert(ep);
ip = ep->input;
a_assert(ip);
ip->tokbuf = state->tokbuf;
ip->script = state->script;
ip->putBackTokenId = state->putBackTokenId;
if (ip->putBackToken) {
bfree(B_L, ip->putBackToken);
}
if (state->putBackToken) {
ip->putBackToken = bstrdup(B_L, state->putBackToken);
}
}
/******************************************************************************/
/*
* Free a saved input state
*/
void ejLexFreeInputState(ej_t* ep, ejinput_t* state)
{
if (state->putBackToken) {
bfree(B_L, state->putBackToken);
state->putBackToken = NULL;
}
}
/******************************************************************************/
/*
* Get the next Ejscript token
*/
int ejLexGetToken(ej_t* ep, int state)
{
ep->tid = getLexicalToken(ep, state);
trace(9, T("ejGetToken: %d, \"%s\"\n"), ep->tid, ep->token);
return ep->tid;
}
/******************************************************************************/
/*
* Get the next Ejscript token
*/
static int getLexicalToken(ej_t* ep, int state)
{
ringq_t *inq, *tokq;
ejinput_t* ip;
int done, tid, c, quote, style;
a_assert(ep);
ip = ep->input;
a_assert(ip);
inq = &ip->script;
tokq = &ip->tokbuf;
ep->tid = -1;
tid = -1;
ep->token = T("");
ringqFlush(tokq);
if (ip->putBackTokenId > 0) {
ringqPutStr(tokq, ip->putBackToken);
tid = ip->putBackTokenId;
ip->putBackTokenId = 0;
ep->token = (char_t*) tokq->servp;
return tid;
}
if ((c = inputGetc(ep)) < 0) {
return TOK_EOF;
}
for (done = 0; !done; ) {
switch (c) {
case -1:
return TOK_EOF;
case ' ':
case '\t':
case '\r':
do {
if ((c = inputGetc(ep)) < 0)
break;
} while (c == ' ' || c == '\t' || c == '\r');
break;
case '\n':
return TOK_NEWLINE;
case '(':
tokenAddChar(ep, c);
return TOK_LPAREN;
case ')':
tokenAddChar(ep, c);
return TOK_RPAREN;
case '{':
tokenAddChar(ep, c);
return TOK_LBRACE;
case '}':
tokenAddChar(ep, c);
return TOK_RBRACE;
case '+':
if ((c = inputGetc(ep)) < 0) {
ejError(ep, T("Syntax Error"));
return TOK_ERR;
}
if (c != '+' ) {
inputPutback(ep, c);
tokenAddChar(ep, EXPR_PLUS);
return TOK_EXPR;
}
tokenAddChar(ep, EXPR_INC);
return TOK_INC_DEC;
case '-':
if ((c = inputGetc(ep)) < 0) {
ejError(ep, T("Syntax Error"));
return TOK_ERR;
}
if (c != '-' ) {
inputPutback(ep, c);
tokenAddChar(ep, EXPR_MINUS);
return TOK_EXPR;
}
tokenAddChar(ep, EXPR_DEC);
return TOK_INC_DEC;
case '*':
tokenAddChar(ep, EXPR_MUL);
return TOK_EXPR;
case '%':
tokenAddChar(ep, EXPR_MOD);
return TOK_EXPR;
case '/':
/*
* Handle the division operator and comments
*/
if ((c = inputGetc(ep)) < 0) {
ejError(ep, T("Syntax Error"));
return TOK_ERR;
}
if (c != '*' && c != '/') {
inputPutback(ep, c);
tokenAddChar(ep, EXPR_DIV);
return TOK_EXPR;
}
style = c;
/*
* Eat comments. Both C and C++ comment styles are supported.
*/
while (1) {
if ((c = inputGetc(ep)) < 0) {
ejError(ep, T("Syntax Error"));
return TOK_ERR;
}
if (c == '\n' && style == '/') {
break;
} else if (c == '*') {
c = inputGetc(ep);
if (style == '/') {
if (c == '\n') {
break;
}
} else {
if (c == '/') {
break;
}
}
}
}
/*
* Continue looking for a token, so get the next character
*/
if ((c = inputGetc(ep)) < 0) {
return TOK_EOF;
}
break;
case '<': /* < and <= */
if ((c = inputGetc(ep)) < 0) {
ejError(ep, T("Syntax Error"));
return TOK_ERR;
}
if (c == '<') {
tokenAddChar(ep, EXPR_LSHIFT);
return TOK_EXPR;
} else if (c == '=') {
tokenAddChar(ep, EXPR_LESSEQ);
return TOK_EXPR;
}
tokenAddChar(ep, EXPR_LESS);
inputPutback(ep, c);
return TOK_EXPR;
case '>': /* > and >= */
if ((c = inputGetc(ep)) < 0) {
ejError(ep, T("Syntax Error"));
return TOK_ERR;
}
if (c == '>') {
tokenAddChar(ep, EXPR_RSHIFT);
return TOK_EXPR;
} else if (c == '=') {
tokenAddChar(ep, EXPR_GREATEREQ);
return TOK_EXPR;
}
tokenAddChar(ep, EXPR_GREATER);
inputPutback(ep, c);
return TOK_EXPR;
case '=': /* "==" */
if ((c = inputGetc(ep)) < 0) {
ejError(ep, T("Syntax Error"));
return TOK_ERR;
}
if (c == '=') {
tokenAddChar(ep, EXPR_EQ);
return TOK_EXPR;
}
inputPutback(ep, c);
return TOK_ASSIGNMENT;
case '!': /* "!=" or "!"*/
if ((c = inputGetc(ep)) < 0) {
ejError(ep, T("Syntax Error"));
return TOK_ERR;
}
if (c == '=') {
tokenAddChar(ep, EXPR_NOTEQ);
return TOK_EXPR;
}
inputPutback(ep, c);
tokenAddChar(ep, EXPR_BOOL_COMP);
return TOK_EXPR;
case ';':
tokenAddChar(ep, c);
return TOK_SEMI;
case ',':
tokenAddChar(ep, c);
return TOK_COMMA;
case '|': /* "||" */
if ((c = inputGetc(ep)) < 0 || c != '|') {
ejError(ep, T("Syntax Error"));
return TOK_ERR;
}
tokenAddChar(ep, COND_OR);
return TOK_LOGICAL;
case '&': /* "&&" */
if ((c = inputGetc(ep)) < 0 || c != '&') {
ejError(ep, T("Syntax Error"));
return TOK_ERR;
}
tokenAddChar(ep, COND_AND);
return TOK_LOGICAL;
case '\"': /* String quote */
case '\'':
quote = c;
if ((c = inputGetc(ep)) < 0) {
ejError(ep, T("Syntax Error"));
return TOK_ERR;
}
while (c != quote) {
/*
* check for escape sequence characters
*/
if (c == '\\') {
c = inputGetc(ep);
if (gisdigit(c)) {
/*
* octal support, \101 maps to 65 = 'A'. put first char
* back so converter will work properly.
*/
inputPutback(ep, c);
c = charConvert(ep, OCTAL, 3);
} else {
switch (c) {
case 'n':
c = '\n'; break;
case 'b':
c = '\b'; break;
case 'f':
c = '\f'; break;
case 'r':
c = '\r'; break;
case 't':
c = '\t'; break;
case 'x':
/*
* hex support, \x41 maps to 65 = 'A'
*/
c = charConvert(ep, HEX, 2);
break;
case 'u':
/*
* unicode support, \x0401 maps to 65 = 'A'
*/
c = charConvert(ep, HEX, 2);
c = c*16 + charConvert(ep, HEX, 2);
break;
case '\'':
case '\"':
case '\\':
break;
default:
ejError(ep, T("Invalid Escape Sequence"));
return TOK_ERR;
}
}
if (tokenAddChar(ep, c) < 0) {
return TOK_ERR;
}
} else {
if (tokenAddChar(ep, c) < 0) {
return TOK_ERR;
}
}
if ((c = inputGetc(ep)) < 0) {
ejError(ep, T("Unmatched Quote"));
return TOK_ERR;
}
}
return TOK_LITERAL;
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
do {
if (tokenAddChar(ep, c) < 0) {
return TOK_ERR;
}
if ((c = inputGetc(ep)) < 0)
break;
} while (gisdigit(c));
inputPutback(ep, c);
return TOK_LITERAL;
default:
/*
* Identifiers or a function names
*/
while (1) {
if (c == '\\') {
/*
* just ignore any \ characters.
*/
} else if (tokenAddChar(ep, c) < 0) {
break;
}
if ((c = inputGetc(ep)) < 0) {
break;
}
if (!gisalnum(c) && c != '$' && c != '_' &&
c != '\\') {
break;
}
}
if (! gisalpha(*tokq->servp) && *tokq->servp != '$' &&
*tokq->servp != '_') {
ejError(ep, T("Invalid identifier %s"), tokq->servp);
return TOK_ERR;
}
/*
* Check for reserved words (only "if", "else", "var", "for"
* and "return" at the moment)
*/
if (state == STATE_STMT) {
if (gstrcmp(ep->token, T("if")) == 0) {
return TOK_IF;
} else if (gstrcmp(ep->token, T("else")) == 0) {
return TOK_ELSE;
} else if (gstrcmp(ep->token, T("var")) == 0) {
return TOK_VAR;
} else if (gstrcmp(ep->token, T("for")) == 0) {
return TOK_FOR;
} else if (gstrcmp(ep->token, T("return")) == 0) {
if ((c == ';') || (c == '(')) {
inputPutback(ep, c);
}
return TOK_RETURN;
}
}
/*
* Skip white space after token to find out whether this is
* a function or not.
*/
while (c == ' ' || c == '\t' || c == '\r' || c == '\n') {
if ((c = inputGetc(ep)) < 0)
break;
}
tid = (c == '(') ? TOK_FUNCTION : TOK_ID;
done++;
}
}
/*
* Putback the last extra character for next time
*/
inputPutback(ep, c);
return tid;
}
/******************************************************************************/
/*
* Putback the last token read
*/
void ejLexPutbackToken(ej_t* ep, int tid, char_t *string)
{
ejinput_t* ip;
a_assert(ep);
ip = ep->input;
a_assert(ip);
if (ip->putBackToken) {
bfree(B_L, ip->putBackToken);
}
ip->putBackTokenId = tid;
ip->putBackToken = bstrdup(B_L, string);
}
/******************************************************************************/
/*
* Add a character to the token ringq buffer
*/
static int tokenAddChar(ej_t *ep, int c)
{
ejinput_t* ip;
a_assert(ep);
ip = ep->input;
a_assert(ip);
if (ringqPutc(&ip->tokbuf, (char_t) c) < 0) {
ejError(ep, T("Token too big"));
return -1;
}
* ((char_t*) ip->tokbuf.endp) = '\0';
ep->token = (char_t*) ip->tokbuf.servp;
return 0;
}
/******************************************************************************/
/*
* Get another input character
*/
static int inputGetc(ej_t* ep)
{
ejinput_t *ip;
int c, len;
a_assert(ep);
ip = ep->input;
if ((len = ringqLen(&ip->script)) == 0) {
return -1;
}
c = ringqGetc(&ip->script);
if (c == '\n') {
ip->lineNumber++;
ip->lineColumn = 0;
} else {
if ((ip->lineColumn + 2) >= ip->lineLength) {
ip->lineLength += EJ_INC;
ip->line = brealloc(B_L, ip->line, ip->lineLength * sizeof(char_t));
}
ip->line[ip->lineColumn++] = c;
ip->line[ip->lineColumn] = '\0';
}
return c;
}
/******************************************************************************/
/*
* Putback a character onto the input queue
*/
static void inputPutback(ej_t* ep, int c)
{
ejinput_t *ip;
a_assert(ep);
ip = ep->input;
ringqInsertc(&ip->script, (char_t) c);
ip->lineColumn--;
ip->line[ip->lineColumn] = '\0';
}
/******************************************************************************/
/*
* Convert a hex or octal character back to binary, return original char if
* not a hex digit
*/
static int charConvert(ej_t* ep, int base, int maxDig)
{
int i, c, lval, convChar;
lval = 0;
for (i = 0; i < maxDig; i++) {
if ((c = inputGetc(ep)) < 0) {
break;
}
/*
* Initialize to out of range value
*/
convChar = base;
if (gisdigit(c)) {
convChar = c - '0';
} else if (c >= 'a' && c <= 'f') {
convChar = c - 'a' + 10;
} else if (c >= 'A' && c <= 'F') {
convChar = c - 'A' + 10;
}
/*
* if unexpected character then return it to buffer.
*/
if (convChar >= base) {
inputPutback(ep, c);
break;
}
lval = (lval * base) + convChar;
}
return lval;
}
/******************************************************************************/

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,102 +0,0 @@
/*
* emfdb.h -- EMF database compatability functions for GoAhead WebServer.
*
* Copyright (c) GoAhead Software Inc., 1995-2000. All Rights Reserved.
*
* See the file "license.txt" for usage and redistribution license requirements
*
* $Id$
*/
/******************************** Description *********************************/
/*
* Emf-like textfile database support for WebServer 2.1.
*/
/********************************* Includes ***********************************/
#ifndef _h_EMFDB
#define _h_EMFDB 1
#if ! UEMF
#include "basic/basic.h"
#include "emf/emf.h"
#else
#include "uemf.h"
#endif
/********************************* Defines ************************************/
#define T_INT 0
#define T_STRING 1
#define DB_OK 0
#define DB_ERR_GENERAL -1
#define DB_ERR_COL_NOT_FOUND -2
#define DB_ERR_COL_DELETED -3
#define DB_ERR_ROW_NOT_FOUND -4
#define DB_ERR_ROW_DELETED -5
#define DB_ERR_TABLE_NOT_FOUND -6
#define DB_ERR_TABLE_DELETED -7
#define DB_ERR_BAD_FORMAT -8
typedef struct dbTable_s {
char_t *name;
int nColumns;
char_t **columnNames;
int *columnTypes;
int nRows;
int **rows;
} dbTable_t;
/********************************** Prototypes ********************************/
/*
* Add a schema to the module-internal schema database
*/
extern int dbRegisterDBSchema(dbTable_t *sTable);
extern int dbOpen(char_t *databasename, char_t *filename,
int (*gettime)(int did), int flags);
extern void dbClose(int did);
extern int dbGetTableId(int did, char_t *tname);
extern char_t *dbGetTableName(int did, int tid);
extern int dbReadInt(int did, char_t *table, char_t *column, int row,
int *returnValue);
extern int dbReadStr(int did, char_t *table, char_t *column, int row,
char_t **returnValue);
extern int dbWriteInt(int did, char_t *table, char_t *column, int row,
int idata);
extern int dbWriteStr(int did, char_t *table, char_t *column, int row,
char_t *s);
extern int dbAddRow(int did, char_t *table);
extern int dbDeleteRow(int did, char_t *table, int rid);
extern int dbSetTableNrow(int did, char_t *table, int nNewRows);
extern int dbGetTableNrow(int did, char_t *table);
/*
* Dump the contents of a database to file
*/
extern int dbSave(int did, char_t *filename, int flags);
/*
* Load the contents of a database to file
*/
extern int dbLoad(int did, char_t *filename, int flags);
/*
* Search for a data in a given column
*/
extern int dbSearchStr(int did, char_t *table, char_t *column,
char_t *value, int flags);
extern void dbZero(int did);
extern char_t *basicGetProductDir();
extern void basicSetProductDir(char_t *proddir);
#endif /* _h_EMFDB */
/******************************************************************************/

View File

@@ -1,166 +0,0 @@
/*
* form.c -- Form processing (in-memory CGI) for the GoAhead Web server
*
* Copyright (c) GoAhead Software Inc., 1995-2000. All Rights Reserved.
*
* See the file "license.txt" for usage and redistribution license requirements
*/
/********************************** Description *******************************/
/*
* This module implements the /goform handler. It emulates CGI processing
* but performs this in-process and not as an external process. This enables
* a very high performance implementation with easy parsing and decoding
* of query strings and posted data.
*/
/*********************************** Includes *********************************/
#include "wsIntrn.h"
/************************************ Locals **********************************/
static sym_fd_t formSymtab = -1; /* Symbol table for form handlers */
/************************************* Code ***********************************/
/*
* Process a form request. Returns 1 always to indicate it handled the URL
*/
int websFormHandler(webs_t wp, char_t *urlPrefix, char_t *webDir, int arg,
char_t *url, char_t *path, char_t *query)
{
sym_t *sp;
char_t formBuf[FNAMESIZE];
char_t *cp, *formName;
int (*fn)(void *sock, char_t *path, char_t *args);
a_assert(websValid(wp));
a_assert(url && *url);
a_assert(path && *path == '/');
websStats.formHits++;
/*
* Extract the form name
*/
gstrncpy(formBuf, path, TSZ(formBuf));
if ((formName = gstrchr(&formBuf[1], '/')) == NULL) {
websError(wp, 200, T("Missing form name"));
return 1;
}
formName++;
if ((cp = gstrchr(formName, '/')) != NULL) {
*cp = '\0';
}
/*
* Lookup the C form function first and then try tcl (no javascript support
* yet).
*/
sp = symLookup(formSymtab, formName);
if (sp == NULL) {
websError(wp, 200, T("Form %s is not defined"), formName);
} else {
fn = (int (*)(void *, char_t *, char_t *)) sp->content.value.integer;
a_assert(fn);
if (fn) {
/*
* For good practice, forms must call websDone()
*/
(*fn)((void*) wp, formName, query);
/*
* Remove the test to force websDone, since this prevents
* the server "push" from a form>
*/
#if 0 /* push */
if (websValid(wp)) {
websError(wp, 200, T("Form didn't call websDone"));
}
#endif /* push */
}
}
return 1;
}
/******************************************************************************/
/*
* Define a form function in the "form" map space.
*/
int websFormDefine(char_t *name, void (*fn)(webs_t wp, char_t *path,
char_t *query))
{
a_assert(name && *name);
a_assert(fn);
if (fn == NULL) {
return -1;
}
symEnter(formSymtab, name, valueInteger((int) fn), (int) NULL);
return 0;
}
/******************************************************************************/
/*
* Open the symbol table for forms.
*/
void websFormOpen()
{
formSymtab = symOpen(WEBS_SYM_INIT);
}
/******************************************************************************/
/*
* Close the symbol table for forms.
*/
void websFormClose()
{
if (formSymtab != -1) {
symClose(formSymtab);
formSymtab = -1;
}
}
/******************************************************************************/
/*
* Write a webs header. This is a convenience routine to write a common
* header for a form back to the browser.
*/
void websHeader(webs_t wp)
{
a_assert(websValid(wp));
websWrite(wp, T("HTTP/1.0 200 OK\n"));
/*
* By license terms the following line of code must not be modified
*/
websWrite(wp, T("Server: %s\r\n"), WEBS_NAME);
websWrite(wp, T("Pragma: no-cache\n"));
websWrite(wp, T("Cache-control: no-cache\n"));
websWrite(wp, T("Content-Type: text/html\n"));
websWrite(wp, T("\n"));
websWrite(wp, T("<html>\n"));
}
/******************************************************************************/
/*
* Write a webs footer
*/
void websFooter(webs_t wp)
{
a_assert(websValid(wp));
websWrite(wp, T("</html>\n"));
}
/******************************************************************************/

View File

@@ -1,193 +0,0 @@
/*
* h.c -- Handle allocation module
*
* Copyright (c) GoAhead Software Inc., 1995-2000. All Rights Reserved.
* See the file "license.txt" for usage and redistribution license requirements
*/
/******************************** Description *********************************/
/*
* This module provides a simple API to allocate and free handles
* It maintains a dynamic array of pointers. These usually point to
* per-handle structures.
*/
/********************************* Includes ***********************************/
#if UEMF
#include "uemf.h"
#else
#include "basic/basicInternal.h"
#endif
/********************************** Defines ***********************************/
/*
* The handle list stores the length of the list and the number of used
* handles in the first two words. These are hidden from the caller by
* returning a pointer to the third word to the caller
*/
#define H_LEN 0 /* First entry holds length of list */
#define H_USED 1 /* Second entry holds number of used */
#define H_OFFSET 2 /* Offset to real start of list */
#define H_INCR 16 /* Grow handle list in chunks this size */
/*********************************** Code *************************************/
/*
* Allocate a new file handle. On the first call, the caller must set the
* handle map to be a pointer to a null pointer. *map points to the second
* element in the handle array.
*/
#if B_STATS
int HALLOC(B_ARGS_DEC, void ***map)
#else
int hAlloc(void ***map)
#endif
{
int *mp;
int handle, len, memsize, incr;
a_assert(map);
if (*map == NULL) {
incr = H_INCR;
memsize = (incr + H_OFFSET) * sizeof(void**);
#if B_STATS
if ((mp = (int*) balloc(B_ARGS, memsize)) == NULL) {
#else
if ((mp = (int*) balloc(B_L, memsize)) == NULL) {
#endif
return -1;
}
memset(mp, 0, memsize);
mp[H_LEN] = incr;
mp[H_USED] = 0;
*map = (void**) &mp[H_OFFSET];
} else {
mp = &((*(int**)map)[-H_OFFSET]);
}
len = mp[H_LEN];
/*
* Find the first null handle
*/
if (mp[H_USED] < mp[H_LEN]) {
for (handle = 0; handle < len; handle++) {
if (mp[handle+H_OFFSET] == 0) {
mp[H_USED]++;
return handle;
}
}
} else {
handle = len;
}
/*
* No free handle so grow the handle list. Grow list in chunks of H_INCR.
*/
len += H_INCR;
memsize = (len + H_OFFSET) * sizeof(void**);
if ((mp = (int*) brealloc(B_L, (void*) mp, memsize)) == NULL) {
return -1;
}
*map = (void**) &mp[H_OFFSET];
mp[H_LEN] = len;
memset(&mp[H_OFFSET + len - H_INCR], 0, sizeof(int*) * H_INCR);
mp[H_USED]++;
return handle;
}
/******************************************************************************/
/*
* Free a handle. This function returns the value of the largest
* handle in use plus 1, to be saved as a max value.
*/
int hFree(void ***map, int handle)
{
int *mp;
int len;
a_assert(map);
mp = &((*(int**)map)[-H_OFFSET]);
a_assert(mp[H_LEN] >= H_INCR);
a_assert(mp[handle + H_OFFSET]);
a_assert(mp[H_USED]);
mp[handle + H_OFFSET] = 0;
if (--(mp[H_USED]) == 0) {
bfree(B_L, (void*) mp);
*map = NULL;
}
/*
* Find the greatest handle number in use.
*/
if (*map == NULL) {
handle = -1;
} else {
len = mp[H_LEN];
if (mp[H_USED] < mp[H_LEN]) {
for (handle = len - 1; handle >= 0; handle--) {
if (mp[handle + H_OFFSET])
break;
}
} else {
handle = len;
}
}
return handle + 1;
}
/******************************************************************************/
/*
* Allocate an entry in the halloc array.
*/
#if B_STATS
int HALLOCENTRY(B_ARGS_DEC, void ***list, int *max, int size)
#else
int hAllocEntry(void ***list, int *max, int size)
#endif
{
char_t *cp;
int id;
a_assert(list);
a_assert(max);
#if B_STATS
if ((id = HALLOC(B_ARGS, (void***) list)) < 0) {
#else
if ((id = hAlloc((void***) list)) < 0) {
#endif
return -1;
}
if (size > 0) {
#if B_STATS
if ((cp = balloc(B_ARGS, size)) == NULL) {
#else
if ((cp = balloc(B_L, size)) == NULL) {
#endif
hFree(list, id);
return -1;
}
a_assert(cp);
memset(cp, 0, size);
(*list)[id] = (void*) cp;
}
if (id >= *max) {
*max = id + 1;
}
return id;
}
/******************************************************************************/

View File

@@ -1,361 +0,0 @@
/*
* handler.c -- URL handler support
*
* Copyright (c) GoAhead Software Inc., 1995-2000. All Rights Reserved.
*
* See the file "license.txt" for usage and redistribution license requirements
*/
/******************************** Description *********************************/
/*
* This module implements a URL handler interface and API to permit
* the addition of user definable URL processors.
*/
/********************************* Includes ***********************************/
#include "wsIntrn.h"
/*********************************** Locals ***********************************/
static websUrlHandlerType *websUrlHandler; /* URL handler list */
static int websUrlHandlerMax; /* Number of entries */
static int urlHandlerOpenCount = 0; /* count of apps */
/**************************** Forward Declarations ****************************/
static int websUrlHandlerSort(const void *p1, const void *p2);
static int websPublishHandler(webs_t wp, char_t *urlPrefix, char_t *webDir,
int sid, char_t *url, char_t *path, char_t *query);
static int websTidyUrl(webs_t wp);
/*********************************** Code *************************************/
/*
* Initialize the URL handler module
*/
int websUrlHandlerOpen()
{
if (++urlHandlerOpenCount == 1) {
websAspOpen();
websUrlHandler = NULL;
websUrlHandlerMax = 0;
}
return 0;
}
/******************************************************************************/
/*
* Close the URL handler module
*/
void websUrlHandlerClose()
{
websUrlHandlerType *sp;
if (--urlHandlerOpenCount <= 0) {
websAspClose();
for (sp = websUrlHandler; sp < &websUrlHandler[websUrlHandlerMax];
sp++) {
bfree(B_L, sp->urlPrefix);
if (sp->webDir) {
bfree(B_L, sp->webDir);
}
}
bfree(B_L, websUrlHandler);
websUrlHandlerMax = 0;
}
}
/******************************************************************************/
/*
* Define a new URL handler. urlPrefix is the URL prefix to match. webDir is
* an optional root directory path for a web directory. arg is an optional
* arg to pass to the URL handler. flags defines the matching order. Valid
* flags include WEBS_HANDLER_LAST, WEBS_HANDLER_FIRST. If multiple users
* specify last or first, their order is defined alphabetically by the
* urlPrefix.
*/
int websUrlHandlerDefine(char_t *urlPrefix, char_t *webDir, int arg,
int (*handler)(webs_t wp, char_t *urlPrefix, char_t *webdir, int arg,
char_t *url, char_t *path, char_t *query), int flags)
{
websUrlHandlerType *sp;
int len;
a_assert(urlPrefix);
a_assert(handler);
/*
* Grow the URL handler array to create a new slot
*/
len = (websUrlHandlerMax + 1) * sizeof(websUrlHandlerType);
if ((websUrlHandler = brealloc(B_L, websUrlHandler, len)) == NULL) {
return -1;
}
sp = &websUrlHandler[websUrlHandlerMax++];
memset(sp, 0, sizeof(websUrlHandlerType));
sp->urlPrefix = bstrdup(B_L, urlPrefix);
sp->len = gstrlen(sp->urlPrefix);
if (webDir) {
sp->webDir = bstrdup(B_L, webDir);
} else {
sp->webDir = bstrdup(B_L, T(""));
}
sp->handler = handler;
sp->arg = arg;
sp->flags = flags;
/*
* Sort in decreasing URL length order observing the flags for first and last
*/
qsort(websUrlHandler, websUrlHandlerMax, sizeof(websUrlHandlerType),
websUrlHandlerSort);
return 0;
}
/******************************************************************************/
/*
* Delete an existing URL handler. We don't reclaim the space of the old
* handler, just NULL the entry. Return -1 if handler is not found.
*/
int websUrlHandlerDelete(int (*handler)(webs_t wp, char_t *urlPrefix,
char_t *webDir, int arg, char_t *url, char_t *path, char_t *query))
{
websUrlHandlerType *sp;
int i;
for (i = 0; i < websUrlHandlerMax; i++) {
sp = &websUrlHandler[i];
if (sp->handler == handler) {
sp->handler = NULL;
return 0;
}
}
return -1;
}
/******************************************************************************/
/*
* Sort in decreasing URL length order observing the flags for first and last
*/
static int websUrlHandlerSort(const void *p1, const void *p2)
{
websUrlHandlerType *s1, *s2;
int rc;
a_assert(p1);
a_assert(p2);
s1 = (websUrlHandlerType*) p1;
s2 = (websUrlHandlerType*) p2;
if ((s1->flags & WEBS_HANDLER_FIRST) || (s2->flags & WEBS_HANDLER_LAST)) {
return -1;
}
if ((s2->flags & WEBS_HANDLER_FIRST) || (s1->flags & WEBS_HANDLER_LAST)) {
return 1;
}
if ((rc = gstrcmp(s1->urlPrefix, s2->urlPrefix)) == 0) {
if (s1->len < s2->len) {
return 1;
} else if (s1->len > s2->len) {
return -1;
}
}
return -rc;
}
/******************************************************************************/
/*
* Publish a new web directory (Use the default URL handler)
*/
int websPublish(char_t *urlPrefix, char_t *path)
{
return websUrlHandlerDefine(urlPrefix, path, 0, websPublishHandler, 0);
}
/******************************************************************************/
/*
* Return the directory for a given prefix. Ignore empty prefixes
*/
char_t *websGetPublishDir(char_t *path, char_t **urlPrefix)
{
websUrlHandlerType *sp;
int i;
for (i = 0; i < websUrlHandlerMax; i++) {
sp = &websUrlHandler[i];
if (sp->urlPrefix[0] == '\0') {
continue;
}
if (sp->handler && gstrncmp(sp->urlPrefix, path, sp->len) == 0) {
if (urlPrefix) {
*urlPrefix = sp->urlPrefix;
}
return sp->webDir;
}
}
return NULL;
}
/******************************************************************************/
/*
* Publish URL handler. We just patch the web page Directory and let the
* default handler do the rest.
*/
static int websPublishHandler(webs_t wp, char_t *urlPrefix, char_t *webDir,
int sid, char_t *url, char_t *path, char_t *query)
{
int len;
a_assert(websValid(wp));
a_assert(path);
/*
* Trim the urlPrefix off the path and set the webdirectory. Add one to step
* over the trailing '/'
*/
len = gstrlen(urlPrefix) + 1;
websSetRequestPath(wp, webDir, &path[len]);
return 0;
}
/******************************************************************************/
/*
* See if any valid handlers are defined for this request. If so, call them
* and continue calling valid handlers until one accepts the request.
* Return true if a handler was invoked, else return FALSE.
*/
int websUrlHandlerRequest(webs_t wp)
{
websUrlHandlerType *sp;
int i, first;
a_assert(websValid(wp));
/*
* Delete the socket handler as we don't want to start reading any
* data on the connection as it may be for the next pipelined HTTP/1.1
* request if using Keep Alive
*/
socketDeleteHandler(wp->sid);
wp->state = WEBS_PROCESSING;
websStats.handlerHits++;
websSetRequestPath(wp, websGetDefaultDir(), NULL);
websTidyUrl(wp);
/*
* We loop over each handler in order till one accepts the request.
* The security handler will handle the request if access is NOT allowed.
*/
first = 1;
for (i = 0; i < websUrlHandlerMax; i++) {
sp = &websUrlHandler[i];
if (sp->handler && gstrncmp(sp->urlPrefix, wp->path, sp->len) == 0) {
if (first) {
websSetEnv(wp);
first = 0;
}
if ((*sp->handler)(wp, sp->urlPrefix, sp->webDir, sp->arg,
wp->url, wp->path, wp->query)) {
return 1;
}
if (!websValid(wp)) {
trace(0,
T("webs: handler %s called websDone, but didn't return 1\n"),
sp->urlPrefix);
return 1;
}
}
}
/*
* If no handler processed the request, then return an error. Note: It is
* the handlers responsibility to call websDone
*/
if (i >= websUrlHandlerMax) {
websError(wp, 200, T("No handler for this URL %s"), wp->url);
}
return 0;
}
/******************************************************************************/
/*
* Tidy up the URL path. Return -1 if the URL is bad.
* Used to eliminate repeated directory delimiters ('/').
*/
static int websTidyUrl(webs_t wp)
{
char_t *parts[64]; /* Array of ptr's to URL parts */
char_t *token, *url, *tidyurl;
int i, len, npart;
a_assert(websValid(wp));
/*
* Copy the string so we don't destroy the original (yet)
*/
url = bstrdup(B_L, wp->url);
websDecodeUrl(url, url, gstrlen(url));
len = npart = 0;
parts[0] = NULL;
token = gstrtok(url, T("/"));
/*
* Look at each directory segment and process "." and ".." segments
* Don't allow the browser to pop outside the root web.
*/
while (token != NULL) {
if (gstrcmp(token, T("..")) == 0) {
if (npart > 0) {
npart--;
}
} else if (gstrcmp(token, T(".")) != 0) {
parts[npart] = token;
len += gstrlen(token) + 1;
npart++;
}
token = gstrtok(NULL, T("/"));
}
/*
* Re-construct URL. Need extra space all "/" and null.
*/
if (npart || (gstrcmp(url, T("/")) == 0) || (url[0] == '\0')) {
tidyurl = balloc(B_L, (len + 2) * sizeof(char_t));
*tidyurl = '\0';
for (i = 0; i < npart; i++) {
gstrcat(tidyurl, T("/"));
gstrcat(tidyurl, parts[i]);
}
bfree(B_L, url);
bfree(B_L, wp->url);
wp->url = tidyurl;
return 0;
} else {
bfree(B_L, url);
return -1;
}
}
/******************************************************************************/

View File

@@ -1,124 +0,0 @@
License Agreement
THIS LICENSE ALLOWS ONLY THE LIMITED USE OF GO AHEAD SOFTWARE, INC. PROPRIETARY CODE. PLEASE CAREFULLY READ THIS AGREEMENT AS IT PERTAINS TO THIS LICENSE, YOU CERTIFY THAT YOU WILL USE THE SOFTWARE ONLY IN THE MANNER PERMITTED HEREIN.
1. Definitions.
1.1 "Documentation" means any documentation GoAhead includes with the Original Code.
1.2 "GoAhead" means Go Ahead Software, Inc.
1.3 "Intellectual Property Rights" means all rights, whether now existing or hereinafter acquired, in and to trade secrets, patents, copyrights, trademarks, know-how, as well as moral rights and similar rights of any type under the laws of any governmental authority, domestic or foreign, including rights in and to all applications and registrations relating to any of the foregoing.
1.4 "License" or "Agreement" means this document.
1.5 "Modifications" means any addition to or deletion from the substance or structure of either the Original Code or any previous Modifications.
1.6 "Original Code" means the Source Code to GoAhead<61>s proprietary computer software entitled GoAhead WebServer.
1.7 "Response Header" means the first portion of the response message output by the GoAhead WebServer, containing but not limited to, header fields for date, content-type, server identification and cache control.
1.8 "Server Identification Field" means the field in the Response Header which contains the text "Server: GoAhead-Webs".
1.9 "You" means an individual or a legal entity exercising rights under, and complying with all of the terms of, this license or a future version of this license. For legal entities, "You" includes any entity which controls, is controlled by, or is under common control with You. For purposes of this definition, "control" means (a) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (b) ownership of fifty percent (50%) or more of the outstanding shares or beneficial ownership of such entity.
2. Source Code License.
2.1 Limited Source Code Grant.
GoAhead hereby grants You a world-wide, royalty-free, non-exclusive license, subject to third party intellectual property claims, to use, reproduce, modify, copy and distribute the Original Code.
2.2 Binary Code.
GoAhead hereby grants You a world-wide, royalty-free, non-exclusive license to copy and distribute the binary code versions of the Original Code together with Your Modifications.
2.3 License Back to GoAhead.
You hereby grant in both source code and binary code to GoAhead a world-wide, royalty-free, non-exclusive license to copy, modify, display, use and sublicense any Modifications You make that are distributed or planned for distribution. Within 30 days of either such event, You agree to ship to GoAhead a file containing the Modifications (in a media to be determined by the parties), including any programmers<72> notes and other programmers<72> materials. Additionally, You will provide to GoAhead a complete description of the product, the product code or model number, the date on which the product is initially shipped, and a contact name, phone number and e-mail address for future correspondence. GoAhead will keep confidential all data specifically marked as such.
2.4 Restrictions on Use.
You may sublicense Modifications to third parties such as subcontractors or OEM's provided that You enter into license agreements with such third parties that bind such third parties to all the obligations under this Agreement applicable to you and that are otherwise substantially similar in scope and application to this Agreement.
3. Term.
This Agreement and license are effective from the time You accept the terms of this Agreement until this Agreement is terminated. You may terminate this Agreement at any time by uninstalling or destroying all copies of the Original Code including any and all binary versions and removing any Modifications to the Original Code existing in any products. This Agreement will terminate immediately and without further notice if You fail to comply with any provision of this Agreement. All restrictions on use, and all other provisions that may reasonably be interpreted to survive termination of this Agreement, will survive termination of this Agreement for any reason. Upon termination, You agree to uninstall or destroy all copies of the Original Code, Modifications, and Documentation.
4. Trademarks and Brand.
4.1 License and Use.
GoAhead hereby grants to You a limited world-wide, royalty-free, non-exclusive license to use the GoAhead trade names, trademarks, logos, service marks and product designations posted in Exhibit A (collectively, the "GoAhead Marks") in connection with the activities by You under this Agreement. Additionally, GoAhead grants You a license under the terms above to such GoAhead trademarks as shall be identified at a URL (the "URL") provided by GoAhead. The use by You of GoAhead Marks shall be in accordance with GoAhead<61>s trademark policies regarding trademark usage as established at the web site designated by the URL, or as otherwise communicated to You by GoAhead at its sole discretion. You understand and agree that any use of GoAhead Marks in connection with this Agreement shall not create any right, title or interest in or to such GoAhead Marks and that all such use and goodwill associated with GoAhead Marks will inure to the benefit of GoAhead.
4.2 Promotion by You of GoAhead WebServer Mark.
In consideration for the licenses granted by GoAhead to You herein, You agree to notify GoAhead when You incorporate the GoAhead WebServer in Your product and to inform GoAhead when such product begins to ship. You agree to promote the Original Code by prominently and visibly displaying a graphic of the GoAhead WebServer mark on the initial web page of Your product that is displayed each time a user connects to it. You also agree that GoAhead may identify your company as a user of the GoAhead WebServer in conjunction with its own marketing efforts. You may further promote the Original Code by displaying the GoAhead WebServer mark in marketing and promotional materials such as the home page of your web site or web pages promoting the product.
4.3 Placement of Copyright Notice by You.
You agree to include copies of the following notice (the "Notice") regarding proprietary rights in all copies of the products that You distribute, as follows: (i) embedded in the object code; and (ii) on the title pages of all documentation. Furthermore, You agree to use commercially reasonable efforts to cause any licensees of your products to embed the Notice in object code and on the title pages or relevant documentation. The Notice is as follows: Copyright (c) 20xx GoAhead Software, Inc. All Rights Reserved. Unless GoAhead otherwise instructs, the year 20xx is to be replaced with the year during which the release of the Original Code containing the notice is issued by GoAhead. If this year is not supplied with Documentation, GoAhead will supply it upon request.
4.4 No Modifications to Server Identification Field.
You agree not to remove or modify the Server identification Field contained in the Response Header as defined in Section 1.6 and 1.7.
5. Warranty Disclaimers.
THE ORIGINAL CODE, THE DOCUMENTATION AND THE MEDIA UPON WHICH THE ORIGINAL CODE IS RECORDED (IF ANY) ARE PROVIDED "AS IS" AND WITHOUT WARRANTIES OF ANY KIND, EXPRESS, STATUTORY OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
The entire risk as to the quality and performance of the Original Code (including any Modifications You make) and the Documentation is with You. Should the Original Code or the Documentation prove defective, You (and not GoAhead or its distributors, licensors or dealers) assume the entire cost of all necessary servicing or repair. GoAhead does not warrant that the functions contained in the Original Code will meet your requirements or operate in the combination that You may select for use, that the operation of the Original Code will be uninterrupted or error free, or that defects in the Original Code will be corrected. No oral or written statement by GoAhead or by a representative of GoAhead shall create a warranty or increase the scope of this warranty.
GOAHEAD DOES NOT WARRANT THE ORIGINAL CODE AGAINST INFRINGEMENT OR THE LIKE WITH RESPECT TO ANY COPYRIGHT, PATENT, TRADE SECRET, TRADEMARK OR OTHER PROPRIETARY RIGHT OF ANY THIRD PARTY AND DOES NOT WARRANT THAT THE ORIGINAL CODE DOES NOT INCLUDE ANY VIRUS, SOFTWARE ROUTINE OR OTHER SOFTWARE DESIGNED TO PERMIT UNAUTHORIZED ACCESS, TO DISABLE, ERASE OR OTHERWISE HARM SOFTWARE, HARDWARE OR DATA, OR TO PERFORM ANY OTHER SUCH ACTIONS.
Any warranties that by law survive the foregoing disclaimers shall terminate ninety (90) days from the date You received the Original Code.
6. Limitation of Liability.
YOUR SOLE REMEDIES AND GOAHEAD'S ENTIRE LIABILITY ARE SET FORTH ABOVE. IN NO EVENT WILL GOAHEAD OR ITS DISTRIBUTORS OR DEALERS BE LIABLE FOR DIRECT, INDIRECT, INCIDENTAL OR CONSEQUENTIAL DAMAGES RESULTING FROM THE USE OF THE ORIGINAL CODE, THE INABILITY TO USE THE ORIGINAL CODE, OR ANY DEFECT IN THE ORIGINAL CODE, INCLUDING ANY LOST PROFITS, EVEN IF THEY HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
You agree that GoAhead and its distributors and dealers will not be LIABLE for defense or indemnity with respect to any claim against You by any third party arising from your possession or use of the Original Code or the Documentation.
In no event will GoAhead<61>s total liability to You for all damages, losses, and causes of action (whether in contract, tort, including negligence, or otherwise) exceed the amount You paid for this product.
SOME STATES DO NOT ALLOW LIMITATIONS ON HOW LONG AN IMPLIED WARRANTY LASTS, AND SOME STATES DO NOT ALLOW THE EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO THE ABOVE LIMITATIONS OR EXCLUSIONS MAY NOT APPLY TO YOU. THIS WARRANTY GIVES YOU SPECIFIC LEGAL RIGHTS AND YOU MAY ALSO HAVE OTHER RIGHTS WHICH VARY FROM STATE TO STATE.
7. Indemnification by You.
You agree to indemnify and hold GoAhead harmless against any and all claims, losses, damages and costs (including legal expenses and reasonable counsel fees) arising out of any claim of a third party with respect to the contents of the Your products, and any intellectual property rights or other rights or interests related thereto.
8. High Risk Activities.
The Original Code is not fault-tolerant and is not designed , manufactured or intended for use or resale as online control equipment in hazardous environments requiring fail-safe performance, such as in the operation of nuclear facilities, aircraft navigation or communication systems, air traffic control, direct life support machines or weapons systems, in which the failure of the Original Code could lead directly to death, personal injury, or severe physical or environmental damage. GoAhead and its suppliers specifically disclaim any express or implied warranty of fitness for any high risk uses listed above.
9. Government Restricted Rights.
For units of the Department of Defense, use, duplication, or disclosure by the Government is subject to restrictions as set forth in subparagraph (c)(1)(ii) of the Rights in Technical Data and Computer Software clause at DFARS 252.227-7013. Contractor/manufacturer is GoAhead Software, Inc., 10900 N.E. 8th Street, Suite 750, Bellevue, Washington 98004.
If the Commercial Computer Software Restricted rights clause at FAR 52.227-19 or its successors apply, the Software and Documentation constitute restricted computer software as defined in that clause and the Government shall not have the license for published software set forth in subparagraph (c)(3) of that clause.
The Original Code (i) was developed at private expense, and no part of it was developed with governmental funds; (ii) is a trade secret of GoAhead (or its licensor(s)) for all purposes of the Freedom of Information Act; (iii) is "restricted computer software" subject to limited utilization as provided in the contract between the vendor and the governmental entity; and (iv) in all respects is proprietary data belonging solely to GoAhead (or its licensor(s)).
10. Governing Law and Interpretation.
This Agreement shall be interpreted under and governed by the laws of the State of Washington, without regard to its rules governing the conflict of laws. If any provision of this Agreement is held illegal or unenforceable by a court or tribunal of competent jurisdiction, the remaining provisions of this Agreement shall remain in effect and the invalid provision deemed modified to the least degree necessary to remedy such invalidity.
11. Entire Agreement.
This Agreement is the complete agreement between GoAhead and You and supersedes all prior agreements, oral or written, with respect to the subject matter hereof.
If You have any questions concerning this Agreement, You may write to GoAhead Software, Inc., 10900 N.E. 8th Street, Suite 750, Bellevue, Washington 98004 or send e-mail to info@goahead.com.
BY CLICKING ON THE "Register" BUTTON ON THE REGISTRATION FORM, YOU ACCEPT AND AGREE TO BE BOUND BY ALL OF THE TERMS AND CONDITIONS SET FORTH IN THIS AGREEMENT. IF YOU DO NOT WISH TO ACCEPT THIS LICENSE OR YOU DO NOT QUALIFY FOR A LICENSE BASED ON THE TERMS SET FORTH ABOVE, YOU MUST NOT CLICK THE "Register" BUTTON.
Exhibit A
GoAhead Trademarks, Logos, and Product Designation Information
01/28/00

View File

@@ -1,48 +0,0 @@
/* MD5.H - header file for MD5C.C
*/
/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
rights reserved.
License to copy and use this software is granted provided that it
is identified as the "RSA Data Security, Inc. MD5 Message-Digest
Algorithm" in all material mentioning or referencing this software
or this function.
License is also granted to make and use derivative works provided
that such works are identified as "derived from the RSA Data
Security, Inc. MD5 Message-Digest Algorithm" in all material
mentioning or referencing the derived work.
RSA Data Security, Inc. makes no representations concerning either
the merchantability of this software or the suitability of this
software for any particular purpose. It is provided "as is"
without express or implied warranty of any kind.
These notices must be retained in any copies of any part of this
documentation and/or software.
*/
#ifndef _h_MD5
#define _h_MD5 1
#ifndef UINT4
#define UINT4 unsigned long
#endif
#ifndef POINTER
#define POINTER unsigned char *
#endif
/* MD5 context. */
typedef struct {
UINT4 state[4]; /* state (ABCD) */
UINT4 count[2]; /* number of bits, modulo 2^64 (lsb first) */
unsigned char buffer[64]; /* input buffer */
} MD5_CONTEXT;
extern void MD5Init (MD5_CONTEXT *);
extern void MD5Update (MD5_CONTEXT *, unsigned char *, unsigned int);
extern void MD5Final (unsigned char [16], MD5_CONTEXT *);
#endif /* _h_MD5 */

View File

@@ -1,335 +0,0 @@
/* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
*/
/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
rights reserved.
License to copy and use this software is granted provided that it
is identified as the "RSA Data Security, Inc. MD5 Message-Digest
Algorithm" in all material mentioning or referencing this software
or this function.
License is also granted to make and use derivative works provided
that such works are identified as "derived from the RSA Data
Security, Inc. MD5 Message-Digest Algorithm" in all material
mentioning or referencing the derived work.
RSA Data Security, Inc. makes no representations concerning either
the merchantability of this software or the suitability of this
software for any particular purpose. It is provided "as is"
without express or implied warranty of any kind.
These notices must be retained in any copies of any part of this
documentation and/or software.
*/
#include "md5.h"
/* Constants for MD5Transform routine.
*/
#define S11 7
#define S12 12
#define S13 17
#define S14 22
#define S21 5
#define S22 9
#define S23 14
#define S24 20
#define S31 4
#define S32 11
#define S33 16
#define S34 23
#define S41 6
#define S42 10
#define S43 15
#define S44 21
static void MD5Transform (UINT4 [4], unsigned char [64]);
static void Encode (unsigned char *, UINT4 *, unsigned int);
static void Decode (UINT4 *, unsigned char *, unsigned int);
static void MD5_memcpy (POINTER, POINTER, unsigned int);
static void MD5_memset (POINTER, int, unsigned int);
static unsigned char PADDING[64] = {
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
/*
* Note: The following MD5 macros can be implemented as functions
* for code compactness, (at the expense of execution speed).
*/
/* F, G, H and I are basic MD5 functions.
*/
#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
#define H(x, y, z) ((x) ^ (y) ^ (z))
#define I(x, y, z) ((y) ^ ((x) | (~z)))
/* ROTATE_LEFT rotates x left n bits.
*/
#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
Rotation is separate from addition to prevent recomputation.
*/
#define FF(a, b, c, d, x, s, ac) { \
(a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
#define GG(a, b, c, d, x, s, ac) { \
(a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
#define HH(a, b, c, d, x, s, ac) { \
(a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
#define II(a, b, c, d, x, s, ac) { \
(a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
(a) = ROTATE_LEFT ((a), (s)); \
(a) += (b); \
}
/* MD5 initialization. Begins an MD5 operation, writing a new context.
*/
void MD5Init (context)
MD5_CONTEXT *context; /* context */
{
context->count[0] = context->count[1] = 0;
/* Load magic initialization constants.
*/
context->state[0] = 0x67452301;
context->state[1] = 0xefcdab89;
context->state[2] = 0x98badcfe;
context->state[3] = 0x10325476;
}
/* MD5 block update operation. Continues an MD5 message-digest
operation, processing another message block, and updating the
context.
*/
void MD5Update (context, input, inputLen)
MD5_CONTEXT *context; /* context */
unsigned char *input; /* input block */
unsigned int inputLen; /* length of input block */
{
unsigned int i, index, partLen;
/* Compute number of bytes mod 64 */
index = (unsigned int)((context->count[0] >> 3) & 0x3F);
/* Update number of bits */
if ((context->count[0] += ((UINT4)inputLen << 3))
< ((UINT4)inputLen << 3))
context->count[1]++;
context->count[1] += ((UINT4)inputLen >> 29);
partLen = 64 - index;
/* Transform as many times as possible.
*/
if (inputLen >= partLen) {
MD5_memcpy
((POINTER)&context->buffer[index], (POINTER)input, partLen);
MD5Transform (context->state, context->buffer);
for (i = partLen; i + 63 < inputLen; i += 64)
MD5Transform (context->state, &input[i]);
index = 0;
}
else
i = 0;
/* Buffer remaining input */
MD5_memcpy
((POINTER)&context->buffer[index], (POINTER)&input[i],
inputLen-i);
}
/* MD5 finalization. Ends an MD5 message-digest operation, writing the
the message digest and zeroizing the context.
*/
void MD5Final (digest, context)
unsigned char digest[16]; /* message digest */
MD5_CONTEXT *context; /* context */
{
unsigned char bits[8];
unsigned int index, padLen;
/* Save number of bits */
Encode (bits, context->count, 8);
/* Pad out to 56 mod 64.
*/
index = (unsigned int)((context->count[0] >> 3) & 0x3f);
padLen = (index < 56) ? (56 - index) : (120 - index);
MD5Update (context, PADDING, padLen);
/* Append length (before padding) */
MD5Update (context, bits, 8);
/* Store state in digest */
Encode (digest, context->state, 16);
/* Zeroize sensitive information.
*/
MD5_memset ((POINTER)context, 0, sizeof (*context));
}
/* MD5 basic transformation. Transforms state based on block.
*/
static void MD5Transform (state, block)
UINT4 state[4];
unsigned char block[64];
{
UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
Decode (x, block, 64);
/* Round 1 */
FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
/* Round 2 */
GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */
GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
/* Round 3 */
HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */
HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
/* Round 4 */
II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
state[0] += a;
state[1] += b;
state[2] += c;
state[3] += d;
/* Zeroize sensitive information.
*/
MD5_memset ((POINTER)x, 0, sizeof (x));
}
/* Encodes input (UINT4) into output (unsigned char). Assumes len is
a multiple of 4.
*/
static void Encode (output, input, len)
unsigned char *output;
UINT4 *input;
unsigned int len;
{
unsigned int i, j;
for (i = 0, j = 0; j < len; i++, j += 4) {
output[j] = (unsigned char)(input[i] & 0xff);
output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
}
}
/* Decodes input (unsigned char) into output (UINT4). Assumes len is
a multiple of 4.
*/
static void Decode (output, input, len)
UINT4 *output;
unsigned char *input;
unsigned int len;
{
unsigned int i, j;
for (i = 0, j = 0; j < len; i++, j += 4)
output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) |
(((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24);
}
/* Note: Replace "for loop" with standard memcpy if possible.
*/
static void MD5_memcpy (output, input, len)
POINTER output;
POINTER input;
unsigned int len;
{
unsigned int i;
for (i = 0; i < len; i++)
output[i] = input[i];
}
/* Note: Replace "for loop" with standard memset if possible.
*/
static void MD5_memset (output, value, len)
POINTER output;
int value;
unsigned int len;
{
unsigned int i;
for (i = 0; i < len; i++)
((char *)output)[i] = (char)value;
}

View File

@@ -1,112 +0,0 @@
/*
* mime.c -- Web server mime types
*
* Copyright (c) GoAhead Software Inc., 1995-2000. All Rights Reserved.
*
* See the file "license.txt" for usage and redistribution license requirements
*/
/******************************** Description *********************************/
/*
* Mime types and file extensions. This module maps URL extensions to
* content types.
*/
/********************************* Includes ***********************************/
#include "wsIntrn.h"
/******************************** Global Data *********************************/
/*
* Addd entries to the MimeList as required for your content
*/
websMimeType websMimeList[] = {
{ T("application/java"), T(".class") },
{ T("application/java"), T(".jar") },
{ T("text/html"), T(".asp") },
{ T("text/html"), T(".htm") },
{ T("text/html"), T(".html") },
{ T("image/gif"), T(".gif") },
{ T("image/jpeg"), T(".jpg") },
{ T("text/css"), T(".css") },
{ T("text/plain"), T(".txt") },
#if MORE_MIME_TYPES
{ T("application/binary"), T(".exe") },
{ T("application/compress"), T(".z") },
{ T("application/gzip"), T(".gz") },
{ T("application/octet-stream"), T(".bin") },
{ T("application/oda"), T(".oda") },
{ T("application/pdf"), T(".pdf") },
{ T("application/postscript"), T(".ai") },
{ T("application/postscript"), T(".eps") },
{ T("application/postscript"), T(".ps") },
{ T("application/rtf"), T(".rtf") },
{ T("application/x-bcpio"), T(".bcpio") },
{ T("application/x-cpio"), T(".cpio") },
{ T("application/x-csh"), T(".csh") },
{ T("application/x-dvi"), T(".dvi") },
{ T("application/x-gtar"), T(".gtar") },
{ T("application/x-hdf"), T(".hdf") },
{ T("application/x-latex"), T(".latex") },
{ T("application/x-mif"), T(".mif") },
{ T("application/x-netcdf"), T(".nc") },
{ T("application/x-netcdf"), T(".cdf") },
{ T("application/x-ns-proxy-autoconfig"), T(".pac") },
{ T("application/x-patch"), T(".patch") },
{ T("application/x-sh"), T(".sh") },
{ T("application/x-shar"), T(".shar") },
{ T("application/x-sv4cpio"), T(".sv4cpio") },
{ T("application/x-sv4crc"), T(".sv4crc") },
{ T("application/x-tar"), T(".tar") },
{ T("application/x-tcl"), T(".tcl") },
{ T("application/x-tex"), T(".tex") },
{ T("application/x-texinfo"), T(".texinfo") },
{ T("application/x-texinfo"), T(".texi") },
{ T("application/x-troff"), T(".t") },
{ T("application/x-troff"), T(".tr") },
{ T("application/x-troff"), T(".roff") },
{ T("application/x-troff-man"), T(".man") },
{ T("application/x-troff-me"), T(".me") },
{ T("application/x-troff-ms"), T(".ms") },
{ T("application/x-ustar"), T(".ustar") },
{ T("application/x-wais-source"), T(".src") },
{ T("application/zip"), T(".zip") },
{ T("audio/basic"), T(".au snd") },
{ T("audio/x-aiff"), T(".aif") },
{ T("audio/x-aiff"), T(".aiff") },
{ T("audio/x-aiff"), T(".aifc") },
{ T("audio/x-wav"), T(".wav") },
{ T("audio/x-wav"), T(".ram") },
{ T("image/ief"), T(".ief") },
{ T("image/jpeg"), T(".jpeg") },
{ T("image/jpeg"), T(".jpe") },
{ T("image/tiff"), T(".tiff") },
{ T("image/tiff"), T(".tif") },
{ T("image/x-cmu-raster"), T(".ras") },
{ T("image/x-portable-anymap"), T(".pnm") },
{ T("image/x-portable-bitmap"), T(".pbm") },
{ T("image/x-portable-graymap"), T(".pgm") },
{ T("image/x-portable-pixmap"), T(".ppm") },
{ T("image/x-rgb"), T(".rgb") },
{ T("image/x-xbitmap"), T(".xbm") },
{ T("image/x-xpixmap"), T(".xpm") },
{ T("image/x-xwindowdump"), T(".xwd") },
{ T("text/html"), T(".cfm") },
{ T("text/html"), T(".shtm") },
{ T("text/html"), T(".shtml") },
{ T("text/richtext"), T(".rtx") },
{ T("text/tab-separated-values"), T(".tsv") },
{ T("text/x-setext"), T(".etx") },
{ T("video/mpeg"), T(".mpeg mpg mpe") },
{ T("video/quicktime"), T(".qt") },
{ T("video/quicktime"), T(".mov") },
{ T("video/x-msvideo"), T(".avi") },
{ T("video/x-sgi-movie"), T(".movie") },
#endif
{ NULL, NULL},
};
/*****************************************************************************/

View File

@@ -1,652 +0,0 @@
/*
* misc.c -- Miscellaneous routines.
*
* Copyright (c) GoAhead Software Inc., 1995-2000. All Rights Reserved.
*
* See the file "license.txt" for usage and redistribution license requirements
*/
/********************************* Includes ***********************************/
#if UEMF
#include "uemf.h"
#else
#include "basic/basicInternal.h"
#endif
/********************************* Defines ************************************/
/*
* Sprintf buffer structure. Make the increment 64 so that
* a balloc can use a 64 byte block.
*/
#define STR_REALLOC 0x1 /* Reallocate the buffer as required */
#define STR_INC 64 /* Growth increment */
typedef struct {
char_t *s; /* Pointer to buffer */
int size; /* Current buffer size */
int max; /* Maximum buffer size */
int count; /* Buffer count */
int flags; /* Allocation flags */
} strbuf_t;
/*
* Sprintf formatting flags
*/
enum flag {
flag_none = 0,
flag_minus = 1,
flag_plus = 2,
flag_space = 4,
flag_hash = 8,
flag_zero = 16,
flag_short = 32,
flag_long = 64
};
/************************** Forward Declarations ******************************/
static int dsnprintf(char_t **s, int size, char_t *fmt, va_list arg,
int msize);
static void put_char(strbuf_t *buf, char_t c);
static void put_string(strbuf_t *buf, char_t *s, int len,
int width, int prec, enum flag f);
static void put_ulong(strbuf_t *buf, unsigned long int value, int base,
int upper, char_t *prefix, int width, int prec, enum flag f);
/************************************ Code ************************************/
/*
* "basename" returns a pointer to the last component of a pathname
* LINUX and LynxOS have their own basename function
*/
#if ! LINUX && ! LYNX && ! __rtems__
char_t *basename(char_t *name)
{
char_t *cp;
#if NW || WIN
if (((cp = gstrrchr(name, '\\')) == NULL) &&
((cp = gstrrchr(name, '/')) == NULL)) {
return name;
#else
if ((cp = gstrrchr(name, '/')) == NULL) {
return name;
#endif
} else if (*(cp + 1) == '\0' && cp == name) {
return name;
} else if (*(cp + 1) == '\0' && cp != name) {
return T("");
} else {
return ++cp;
}
}
#endif /* ! LINUX & ! LYNX */
/******************************************************************************/
/*
* Returns a pointer to the directory component of a pathname. bufsize is
* the size of the buffer in BYTES!
*/
char_t *dirname(char_t *buf, char_t *name, int bufsize)
{
char_t *cp;
int len;
a_assert(name);
a_assert(buf);
a_assert(bufsize > 0);
#if WIN || NW
if ((cp = gstrrchr(name, '/')) == NULL &&
(cp = gstrrchr(name, '\\')) == NULL)
#else
if ((cp = gstrrchr(name, '/')) == NULL)
#endif
{
gstrcpy(buf, T("."));
return buf;
}
if ((*(cp + 1) == '\0' && cp == name)) {
gstrncpy(buf, T("."), TSZ(bufsize));
gstrcpy(buf, T("."));
return buf;
}
len = cp - name;
if (len < bufsize) {
gstrncpy(buf, name, len);
buf[len] = '\0';
} else {
gstrncpy(buf, name, TSZ(bufsize));
buf[bufsize - 1] = '\0';
}
return buf;
}
/******************************************************************************/
/*
* sprintf and vsprintf are bad, ok. You can easily clobber memory. Use
* fmtAlloc and fmtValloc instead! These functions do _not_ support floating
* point, like %e, %f, %g...
*/
int fmtAlloc(char_t **s, int n, char_t *fmt, ...)
{
va_list ap;
int result;
a_assert(s);
a_assert(fmt);
*s = NULL;
va_start(ap, fmt);
result = dsnprintf(s, n, fmt, ap, 0);
va_end(ap);
return result;
}
/******************************************************************************/
/*
* Support a static buffer version for small buffers only!
*/
int fmtStatic(char_t *s, int n, char_t *fmt, ...)
{
va_list ap;
int result;
a_assert(s);
a_assert(fmt);
a_assert(n <= 256);
if (n <= 0) {
return -1;
}
va_start(ap, fmt);
result = dsnprintf(&s, n, fmt, ap, 0);
va_end(ap);
return result;
}
/******************************************************************************/
/*
* This function appends the formatted string to the supplied string,
* reallocing if required.
*/
int fmtRealloc(char_t **s, int n, int msize, char_t *fmt, ...)
{
va_list ap;
int result;
a_assert(s);
a_assert(fmt);
if (msize == -1) {
*s = NULL;
}
va_start(ap, fmt);
result = dsnprintf(s, n, fmt, ap, msize);
va_end(ap);
return result;
}
/******************************************************************************/
/*
* A vsprintf replacement.
*/
int fmtValloc(char_t **s, int n, char_t *fmt, va_list arg)
{
a_assert(s);
a_assert(fmt);
*s = NULL;
return dsnprintf(s, n, fmt, arg, 0);
}
/******************************************************************************/
/*
* Dynamic sprintf implementation. Supports dynamic buffer allocation.
* This function can be called multiple times to grow an existing allocated
* buffer. In this case, msize is set to the size of the previously allocated
* buffer. The buffer will be realloced, as required. If msize is set, we
* return the size of the allocated buffer for use with the next call. For
* the first call, msize can be set to -1.
*/
static int dsnprintf(char_t **s, int size, char_t *fmt, va_list arg, int msize)
{
strbuf_t buf;
char_t c;
a_assert(s);
a_assert(fmt);
memset(&buf, 0, sizeof(buf));
buf.s = *s;
if (*s == NULL || msize != 0) {
buf.max = size;
buf.flags |= STR_REALLOC;
if (msize != 0) {
buf.size = max(msize, 0);
}
if (*s != NULL && msize != 0) {
buf.count = gstrlen(*s);
}
} else {
buf.size = size;
}
while ((c = *fmt++) != '\0') {
if (c != '%' || (c = *fmt++) == '%') {
put_char(&buf, c);
} else {
enum flag f = flag_none;
int width = 0;
int prec = -1;
for ( ; c != '\0'; c = *fmt++) {
if (c == '-') {
f |= flag_minus;
} else if (c == '+') {
f |= flag_plus;
} else if (c == ' ') {
f |= flag_space;
} else if (c == '#') {
f |= flag_hash;
} else if (c == '0') {
f |= flag_zero;
} else {
break;
}
}
if (c == '*') {
width = va_arg(arg, int);
if (width < 0) {
f |= flag_minus;
width = -width;
}
c = *fmt++;
} else {
for ( ; gisdigit((int)c); c = *fmt++) {
width = width * 10 + (c - '0');
}
}
if (c == '.') {
f &= ~flag_zero;
c = *fmt++;
if (c == '*') {
prec = va_arg(arg, int);
c = *fmt++;
} else {
for (prec = 0; gisdigit((int)c); c = *fmt++) {
prec = prec * 10 + (c - '0');
}
}
}
if (c == 'h' || c == 'l') {
f |= (c == 'h' ? flag_short : flag_long);
c = *fmt++;
}
if (c == 'd' || c == 'i') {
long int value;
if (f & flag_short) {
value = (short int) va_arg(arg, int);
} else if (f & flag_long) {
value = va_arg(arg, long int);
} else {
value = va_arg(arg, int);
}
if (value >= 0) {
if (f & flag_plus) {
put_ulong(&buf, value, 10, 0, T("+"), width, prec, f);
} else if (f & flag_space) {
put_ulong(&buf, value, 10, 0, T(" "), width, prec, f);
} else {
put_ulong(&buf, value, 10, 0, NULL, width, prec, f);
}
} else {
put_ulong(&buf, -value, 10, 0, T("-"), width, prec, f);
}
} else if (c == 'o' || c == 'u' || c == 'x' || c == 'X') {
unsigned long int value;
if (f & flag_short) {
value = (unsigned short int) va_arg(arg, unsigned int);
} else if (f & flag_long) {
value = va_arg(arg, unsigned long int);
} else {
value = va_arg(arg, unsigned int);
}
if (c == 'o') {
if (f & flag_hash && value != 0) {
put_ulong(&buf, value, 8, 0, T("0"), width, prec, f);
} else {
put_ulong(&buf, value, 8, 0, NULL, width, prec, f);
}
} else if (c == 'u') {
put_ulong(&buf, value, 10, 0, NULL, width, prec, f);
} else {
if (f & flag_hash && value != 0) {
if (c == 'x') {
put_ulong(&buf, value, 16, 0, T("0x"), width,
prec, f);
} else {
put_ulong(&buf, value, 16, 1, T("0X"), width,
prec, f);
}
} else {
put_ulong(&buf, value, 16, 0, NULL, width, prec, f);
}
}
} else if (c == 'c') {
char_t value = va_arg(arg, int);
put_char(&buf, value);
} else if (c == 's' || c == 'S') {
char_t *value = va_arg(arg, char_t *);
if (value == NULL) {
put_string(&buf, T("(null)"), -1, width, prec, f);
} else if (f & flag_hash) {
put_string(&buf,
value + 1, (char_t) *value, width, prec, f);
} else {
put_string(&buf, value, -1, width, prec, f);
}
} else if (c == 'p') {
void *value = va_arg(arg, void *);
put_ulong(&buf,
(unsigned long int) value, 16, 0, T("0x"), width, prec, f);
} else if (c == 'n') {
if (f & flag_short) {
short int *value = va_arg(arg, short int *);
*value = buf.count;
} else if (f & flag_long) {
long int *value = va_arg(arg, long int *);
*value = buf.count;
} else {
int *value = va_arg(arg, int *);
*value = buf.count;
}
} else {
put_char(&buf, c);
}
}
}
if (buf.s == NULL) {
put_char(&buf, '\0');
}
/*
* If the user requested a dynamic buffer (*s == NULL), ensure it is returned.
*/
if (*s == NULL || msize != 0) {
*s = buf.s;
}
if (*s != NULL && size > 0) {
if (buf.count < size) {
(*s)[buf.count] = '\0';
} else {
(*s)[buf.size - 1] = '\0';
}
}
if (msize != 0) {
return buf.size;
}
return buf.count;
}
/******************************************************************************/
/*
* Add a character to a string buffer
*/
static void put_char(strbuf_t *buf, char_t c)
{
if (buf->count >= (buf->size - 1)) {
if (! (buf->flags & STR_REALLOC)) {
return;
}
buf->size += STR_INC;
if (buf->size > buf->max && buf->size > STR_INC) {
/*
* Caller should increase the size of the calling buffer
*/
buf->size -= STR_INC;
return;
}
if (buf->s == NULL) {
buf->s = balloc(B_L, buf->size * sizeof(char_t));
} else {
buf->s = brealloc(B_L, buf->s, buf->size * sizeof(char_t));
}
}
buf->s[buf->count] = c;
if (c != '\0') {
++buf->count;
}
}
/******************************************************************************/
/*
* Add a string to a string buffer
*/
static void put_string(strbuf_t *buf, char_t *s, int len, int width,
int prec, enum flag f)
{
int i;
if (len < 0) {
len = strnlen(s, prec >= 0 ? prec : ULONG_MAX);
} else if (prec >= 0 && prec < len) {
len = prec;
}
if (width > len && !(f & flag_minus)) {
for (i = len; i < width; ++i) {
put_char(buf, ' ');
}
}
for (i = 0; i < len; ++i) {
put_char(buf, s[i]);
}
if (width > len && f & flag_minus) {
for (i = len; i < width; ++i) {
put_char(buf, ' ');
}
}
}
/******************************************************************************/
/*
* Add a long to a string buffer
*/
static void put_ulong(strbuf_t *buf, unsigned long int value, int base,
int upper, char_t *prefix, int width, int prec, enum flag f)
{
unsigned long x, x2;
int len, zeros, i;
for (len = 1, x = 1; x < ULONG_MAX / base; ++len, x = x2) {
x2 = x * base;
if (x2 > value) {
break;
}
}
zeros = (prec > len) ? prec - len : 0;
width -= zeros + len;
if (prefix != NULL) {
width -= strnlen(prefix, ULONG_MAX);
}
if (!(f & flag_minus)) {
if (f & flag_zero) {
for (i = 0; i < width; ++i) {
put_char(buf, '0');
}
} else {
for (i = 0; i < width; ++i) {
put_char(buf, ' ');
}
}
}
if (prefix != NULL) {
put_string(buf, prefix, -1, 0, -1, flag_none);
}
for (i = 0; i < zeros; ++i) {
put_char(buf, '0');
}
for ( ; x > 0; x /= base) {
int digit = (value / x) % base;
put_char(buf, (char) ((digit < 10 ? '0' : (upper ? 'A' : 'a') - 10) +
digit));
}
if (f & flag_minus) {
for (i = 0; i < width; ++i) {
put_char(buf, ' ');
}
}
}
/******************************************************************************/
/*
* Convert an ansi string to a unicode string. On an error, we return the
* original ansi string which is better than returning NULL. nBytes is the
* size of the destination buffer (ubuf) in _bytes_.
*/
char_t *ascToUni(char_t *ubuf, char *str, int nBytes)
{
#if UNICODE
if (MultiByteToWideChar(CP_ACP, 0, str, nBytes / sizeof(char_t), ubuf,
nBytes / sizeof(char_t)) < 0) {
return (char_t*) str;
}
#else
memcpy(ubuf, str, nBytes);
#endif
return ubuf;
}
/******************************************************************************/
/*
* Convert a unicode string to an ansi string. On an error, return the
* original unicode string which is better than returning NULL.
* N.B. nBytes is the number of _bytes_ in the destination buffer, buf.
*/
char *uniToAsc(char *buf, char_t *ustr, int nBytes)
{
#if UNICODE
if (WideCharToMultiByte(CP_ACP, 0, ustr, nBytes, buf, nBytes, NULL,
NULL) < 0) {
return (char*) ustr;
}
#else
memcpy(buf, ustr, nBytes);
#endif
return (char*) buf;
}
/******************************************************************************/
/*
* allocate (balloc) a buffer and do ascii to unicode conversion into it.
* cp points to the ascii buffer. alen is the length of the buffer to be
* converted not including a terminating NULL. Return a pointer to the
* unicode buffer which must be bfree'd later. Return NULL on failure to
* get buffer. The buffer returned is NULL terminated.
*/
char_t *ballocAscToUni(char *cp, int alen)
{
char_t *unip;
int ulen;
ulen = (alen + 1) * sizeof(char_t);
if ((unip = balloc(B_L, ulen)) == NULL) {
return NULL;
}
ascToUni(unip, cp, ulen);
unip[alen] = 0;
return unip;
}
/******************************************************************************/
/*
* allocate (balloc) a buffer and do unicode to ascii conversion into it.
* unip points to the unicoded string. ulen is the number of characters
* in the unicode string not including a teminating null. Return a pointer
* to the ascii buffer which must be bfree'd later. Return NULL on failure
* to get buffer. The buffer returned is NULL terminated.
*/
char *ballocUniToAsc(char_t *unip, int ulen)
{
char * cp;
if ((cp = balloc(B_L, ulen+1)) == NULL) {
return NULL;
}
uniToAsc(cp, unip, ulen);
cp[ulen] = '\0';
return cp;
}
/******************************************************************************/
/*
* convert a hex string to an integer. The end of the string or a non-hex
* character will indicate the end of the hex specification.
*/
unsigned int hextoi(char_t *hexstring)
{
register char_t *h;
register unsigned int c, v;
v = 0;
h = hexstring;
if (*h == '0' && (*(h+1) == 'x' || *(h+1) == 'X')) {
h += 2;
}
while ((c = (unsigned int)*h++) != 0) {
if (c >= '0' && c <= '9') {
c -= '0';
} else if (c >= 'a' && c <= 'f') {
c = (c - 'a') + 10;
} else if (c >= 'A' && c <= 'F') {
c = (c - 'A') + 10;
} else {
break;
}
v = (v * 0x10) + c;
}
return v;
}
/******************************************************************************/
/*
* convert a string to an integer. If the string starts with "0x" or "0X"
* a hexidecimal conversion is done.
*/
unsigned int gstrtoi(char_t *s)
{
if (*s == '0' && (*(s+1) == 'x' || *(s+1) == 'X')) {
s += 2;
return hextoi(s);
}
return gatoi(s);
}
/******************************************************************************/

View File

@@ -1,582 +0,0 @@
/*
* ringq.c -- Ring queue buffering module
*
* Copyright (c) GoAhead Software Inc., 1995-2000. All Rights Reserved.
*
* See the file "license.txt" for usage and redistribution license requirements
*/
/******************************** Description *********************************/
/*
* A ring queue allows maximum utilization of memory for data storage and is
* ideal for input/output buffering. This module provides a highly efficient
* implementation and a vehicle for dynamic strings.
*
* WARNING: This is a public implementation and callers have full access to
* the queue structure and pointers. Change this module very carefully.
*
* This module follows the open/close model.
*
* Operation of a ringq where rq is a pointer to a ringq :
*
* rq->buflen contains the size of the buffer.
* rq->buf will point to the start of the buffer.
* rq->servp will point to the first (un-consumed) data byte.
* rq->endp will point to the next free location to which new data is added
* rq->endbuf will point to one past the end of the buffer.
*
* Eg. If the ringq contains the data "abcdef", it might look like :
*
* +-------------------------------------------------------------------+
* | | | | | | | | a | b | c | d | e | f | | | | |
* +-------------------------------------------------------------------+
* ^ ^ ^ ^
* | | | |
* rq->buf rq->servp rq->endp rq->enduf
*
* The queue is empty when servp == endp. This means that the queue will hold
* at most rq->buflen -1 bytes. It is the filler's responsibility to ensure
* the ringq is never filled such that servp == endp.
*
* It is the filler's responsibility to "wrap" the endp back to point to
* rq->buf when the pointer steps past the end. Correspondingly it is the
* consumers responsibility to "wrap" the servp when it steps to rq->endbuf.
* The ringqPutc and ringqGetc routines will do this automatically.
*/
/********************************* Includes ***********************************/
#if UEMF
#include "uemf.h"
#else
#include "basic/basicInternal.h"
#endif
/*********************************** Defines **********************************/
/*
* Faster than a function call
*/
#define RINGQ_LEN(rq) \
((rq->servp > rq->endp) ? \
(rq->buflen + (rq->endp - rq->servp)) : \
(rq->endp - rq->servp))
/***************************** Forward Declarations ***************************/
static int ringqGrow(ringq_t *rq);
static int getBinBlockSize(int size);
int ringqGrowCalls = 0;
/*********************************** Code *************************************/
/*
* Create a new ringq. "increment" is the amount to increase the size of the
* ringq should it need to grow to accomodate data being added. "maxsize" is
* an upper limit (sanity level) beyond which the q must not grow. Set maxsize
* to -1 to imply no upper limit. The buffer for the ringq is always
* dynamically allocated. Set maxsize
*/
int ringqOpen(ringq_t *rq, int initSize, int maxsize)
{
int increment;
a_assert(rq);
a_assert(initSize >= 0);
increment = getBinBlockSize(initSize);
if ((rq->buf = balloc(B_L, (increment))) == NULL) {
return -1;
}
rq->maxsize = maxsize;
rq->buflen = increment;
rq->increment = increment;
rq->endbuf = &rq->buf[rq->buflen];
rq->servp = rq->buf;
rq->endp = rq->buf;
*rq->servp = '\0';
return 0;
}
/******************************************************************************/
/*
* Delete a ringq and free the ringq buffer.
*/
void ringqClose(ringq_t *rq)
{
a_assert(rq);
a_assert(rq->buflen == (rq->endbuf - rq->buf));
if (rq == NULL) {
return;
}
ringqFlush(rq);
bfree(B_L, (char*) rq->buf);
rq->buf = NULL;
}
/******************************************************************************/
/*
* Return the length of the data in the ringq. Users must fill the queue to
* a high water mark of at most one less than the queue size.
*/
int ringqLen(ringq_t *rq)
{
a_assert(rq);
a_assert(rq->buflen == (rq->endbuf - rq->buf));
if (rq->servp > rq->endp) {
return rq->buflen + rq->endp - rq->servp;
} else {
return rq->endp - rq->servp;
}
}
/******************************************************************************/
/*
* Get a byte from the queue
*/
int ringqGetc(ringq_t *rq)
{
char_t c;
char_t* cp;
a_assert(rq);
a_assert(rq->buflen == (rq->endbuf - rq->buf));
if (rq->servp == rq->endp) {
return -1;
}
cp = (char_t*) rq->servp;
c = *cp++;
rq->servp = (unsigned char *) cp;
if (rq->servp >= rq->endbuf) {
rq->servp = rq->buf;
}
return c;
}
/******************************************************************************/
/*
* Add a char to the queue. Note if being used to store wide strings
* this does not add a trailing '\0'. Grow the q as required.
*/
int ringqPutc(ringq_t *rq, char_t c)
{
char_t *cp;
a_assert(rq);
a_assert(rq->buflen == (rq->endbuf - rq->buf));
if ((ringqPutBlkMax(rq) < (int) sizeof(char_t)) && !ringqGrow(rq)) {
return -1;
}
cp = (char_t*) rq->endp;
*cp++ = (char_t) c;
rq->endp = (unsigned char *) cp;
if (rq->endp >= rq->endbuf) {
rq->endp = rq->buf;
}
return 0;
}
/******************************************************************************/
/*
* Insert a wide character at the front of the queue
*/
int ringqInsertc(ringq_t *rq, char_t c)
{
char_t *cp;
a_assert(rq);
a_assert(rq->buflen == (rq->endbuf - rq->buf));
if (ringqPutBlkMax(rq) < (int) sizeof(char_t) && !ringqGrow(rq)) {
return -1;
}
if (rq->servp <= rq->buf) {
rq->servp = rq->endbuf;
}
cp = (char_t*) rq->servp;
*--cp = (char_t) c;
rq->servp = (unsigned char *) cp;
return 0;
}
/******************************************************************************/
/*
* Add a string to the queue. Add a trailing null (maybe two nulls)
*/
int ringqPutStr(ringq_t *rq, char_t *str)
{
int rc;
a_assert(rq);
a_assert(str);
a_assert(rq->buflen == (rq->endbuf - rq->buf));
rc = ringqPutBlk(rq, (unsigned char*) str, gstrlen(str) * sizeof(char_t));
*((char_t*) rq->endp) = (char_t) '\0';
return rc;
}
/******************************************************************************/
/*
* Add a null terminator. This does NOT increase the size of the queue
*/
void ringqAddNull(ringq_t *rq)
{
a_assert(rq);
a_assert(rq->buflen == (rq->endbuf - rq->buf));
*((char_t*) rq->endp) = (char_t) '\0';
}
/******************************************************************************/
#if UNICODE
/*
* Get a byte from the queue
*/
int ringqGetcA(ringq_t *rq)
{
unsigned char c;
a_assert(rq);
a_assert(rq->buflen == (rq->endbuf - rq->buf));
if (rq->servp == rq->endp) {
return -1;
}
c = *rq->servp++;
if (rq->servp >= rq->endbuf) {
rq->servp = rq->buf;
}
return c;
}
/******************************************************************************/
/*
* Add a byte to the queue. Note if being used to store strings this does not
* add a trailing '\0'. Grow the q as required.
*/
int ringqPutcA(ringq_t *rq, char c)
{
a_assert(rq);
a_assert(rq->buflen == (rq->endbuf - rq->buf));
if (ringqPutBlkMax(rq) == 0 && !ringqGrow(rq)) {
return -1;
}
*rq->endp++ = (unsigned char) c;
if (rq->endp >= rq->endbuf) {
rq->endp = rq->buf;
}
return 0;
}
/******************************************************************************/
/*
* Insert a byte at the front of the queue
*/
int ringqInsertcA(ringq_t *rq, char c)
{
a_assert(rq);
a_assert(rq->buflen == (rq->endbuf - rq->buf));
if (ringqPutBlkMax(rq) == 0 && !ringqGrow(rq)) {
return -1;
}
if (rq->servp <= rq->buf) {
rq->servp = rq->endbuf;
}
*--rq->servp = (unsigned char) c;
return 0;
}
/******************************************************************************/
/*
* Add a string to the queue. Add a trailing null (not really in the q).
* ie. beyond the last valid byte.
*/
int ringqPutStrA(ringq_t *rq, char *str)
{
int rc;
a_assert(rq);
a_assert(str);
a_assert(rq->buflen == (rq->endbuf - rq->buf));
rc = ringqPutBlk(rq, (unsigned char*) str, strlen(str));
rq->endp[0] = '\0';
return rc;
}
#endif /* UNICODE */
/******************************************************************************/
/*
* Add a block of data to the ringq. Return the number of bytes added.
* Grow the q as required.
*/
int ringqPutBlk(ringq_t *rq, unsigned char *buf, int size)
{
int this, bytes_put;
a_assert(rq);
a_assert(rq->buflen == (rq->endbuf - rq->buf));
a_assert(buf);
a_assert(0 <= size);
/*
* Loop adding the maximum bytes we can add in a single straight line copy
*/
bytes_put = 0;
while (size > 0) {
this = min(ringqPutBlkMax(rq), size);
if (this <= 0) {
if (! ringqGrow(rq)) {
break;
}
this = min(ringqPutBlkMax(rq), size);
}
memcpy(rq->endp, buf, this);
buf += this;
rq->endp += this;
size -= this;
bytes_put += this;
if (rq->endp >= rq->endbuf) {
rq->endp = rq->buf;
}
}
return bytes_put;
}
/******************************************************************************/
/*
* Get a block of data from the ringq. Return the number of bytes returned.
*/
int ringqGetBlk(ringq_t *rq, unsigned char *buf, int size)
{
int this, bytes_read;
a_assert(rq);
a_assert(rq->buflen == (rq->endbuf - rq->buf));
a_assert(buf);
a_assert(0 <= size && size < rq->buflen);
/*
* Loop getting the maximum bytes we can get in a single straight line copy
*/
bytes_read = 0;
while (size > 0) {
this = ringqGetBlkMax(rq);
this = min(this, size);
if (this <= 0) {
break;
}
memcpy(buf, rq->servp, this);
buf += this;
rq->servp += this;
size -= this;
bytes_read += this;
if (rq->servp >= rq->endbuf) {
rq->servp = rq->buf;
}
}
return bytes_read;
}
/******************************************************************************/
/*
* Return the maximum number of bytes the ring q can accept via a single
* block copy. Useful if the user is doing their own data insertion.
*/
int ringqPutBlkMax(ringq_t *rq)
{
int space, in_a_line;
a_assert(rq);
a_assert(rq->buflen == (rq->endbuf - rq->buf));
space = rq->buflen - RINGQ_LEN(rq) - 1;
in_a_line = rq->endbuf - rq->endp;
return min(in_a_line, space);
}
/******************************************************************************/
/*
* Return the maximum number of bytes the ring q can provide via a single
* block copy. Useful if the user is doing their own data retrieval.
*/
int ringqGetBlkMax(ringq_t *rq)
{
int len, in_a_line;
a_assert(rq);
a_assert(rq->buflen == (rq->endbuf - rq->buf));
len = RINGQ_LEN(rq);
in_a_line = rq->endbuf - rq->servp;
return min(in_a_line, len);
}
/******************************************************************************/
/*
* Adjust the endp pointer after the user has copied data into the queue.
*/
void ringqPutBlkAdj(ringq_t *rq, int size)
{
a_assert(rq);
a_assert(rq->buflen == (rq->endbuf - rq->buf));
a_assert(0 <= size && size < rq->buflen);
rq->endp += size;
if (rq->endp >= rq->endbuf) {
rq->endp -= rq->buflen;
}
/*
* Flush the queue if the endp pointer is corrupted via a bad size
*/
if (rq->endp >= rq->endbuf) {
error(E_L, E_LOG, T("Bad end pointer"));
ringqFlush(rq);
}
}
/******************************************************************************/
/*
* Adjust the servp pointer after the user has copied data from the queue.
*/
void ringqGetBlkAdj(ringq_t *rq, int size)
{
a_assert(rq);
a_assert(rq->buflen == (rq->endbuf - rq->buf));
a_assert(0 < size && size < rq->buflen);
rq->servp += size;
if (rq->servp >= rq->endbuf) {
rq->servp -= rq->buflen;
}
/*
* Flush the queue if the servp pointer is corrupted via a bad size
*/
if (rq->servp >= rq->endbuf) {
error(E_L, E_LOG, T("Bad serv pointer"));
ringqFlush(rq);
}
}
/******************************************************************************/
/*
* Flush all data in a ring q. Reset the pointers.
*/
void ringqFlush(ringq_t *rq)
{
a_assert(rq);
a_assert(rq->servp);
rq->servp = rq->buf;
rq->endp = rq->buf;
if (rq->servp) {
*rq->servp = '\0';
}
}
/******************************************************************************/
/*
* Grow the buffer. Return true if the buffer can be grown. Grow using
* the increment size specified when opening the ringq. Don't grow beyond
* the maximum possible size.
*/
static int ringqGrow(ringq_t *rq)
{
unsigned char *newbuf;
int len;
a_assert(rq);
if (rq->maxsize >= 0 && rq->buflen >= rq->maxsize) {
return 0;
}
len = ringqLen(rq);
if ((newbuf = balloc(B_L, rq->buflen + rq->increment)) == NULL) {
return 0;
}
ringqGetBlk(rq, newbuf, ringqLen(rq));
bfree(B_L, (char*) rq->buf);
#if OLD
rq->endp = &newbuf[endp];
rq->servp = &newbuf[servp];
rq->endbuf = &newbuf[rq->buflen];
rq->buf = newbuf;
#endif
rq->buflen += rq->increment;
rq->endp = newbuf;
rq->servp = newbuf;
rq->buf = newbuf;
rq->endbuf = &rq->buf[rq->buflen];
ringqPutBlk(rq, newbuf, len);
/*
* Double the increment so the next grow will line up with balloc'ed memory
*/
rq->increment = getBinBlockSize(2 * rq->increment);
return 1;
}
/******************************************************************************/
/*
* Find the smallest binary memory size that "size" will fit into. This
* makes the ringq and ringqGrow routines much more efficient. The balloc
* routine likes powers of 2 minus 1.
*/
static int getBinBlockSize(int size)
{
int q;
size = size >> B_SHIFT;
for (q = 0; size; size >>= 1) {
q++;
}
return (1 << (B_SHIFT + q));
}
/******************************************************************************/

View File

@@ -1,191 +0,0 @@
/*
* rom.c -- Support for ROMed page retrieval.
*
* Copyright (c) GoAhead Software Inc., 1995-2000. All Rights Reserved.
*
* See the file "license.txt" for usage and redistribution license requirements
*/
/******************************** Description *********************************/
/*
* This module provides web page retrieval from compiled web pages. Use the
* webcomp program to compile web pages and link into the GoAhead WebServer.
* This module uses a hashed symbol table for fast page lookup.
*
* Usage: webcomp -f webPageFileList -p Prefix >webrom.c
*/
/********************************* Includes ***********************************/
#include <stdlib.h>
#include "wsIntrn.h"
/******************************** Local Data **********************************/
#if WEBS_PAGE_ROM
sym_fd_t romTab; /* Symbol table for web pages */
/*********************************** Code *************************************/
/*
* Open the ROM module
*/
int websRomOpen()
{
websRomPageIndexType *wip;
int nchars;
char_t name[SYM_MAX];
romTab = symOpen(WEBS_SYM_INIT);
for (wip = websRomPageIndex; wip->path; wip++) {
gstrncpy(name, wip->path, SYM_MAX);
nchars = gstrlen(name) - 1;
if (nchars > 0 &&
(name[nchars] == '/' || name[nchars] == '\\')) {
name[nchars] = '\0';
}
symEnter(romTab, name, valueInteger((int) wip), 0);
}
return 0;
}
/******************************************************************************/
/*
* Close the ROM module
*/
void websRomClose()
{
symClose(romTab);
}
/******************************************************************************/
/*
* Open a web page
*/
int websRomPageOpen(webs_t wp, char_t *path, int mode, int perm)
{
websRomPageIndexType *wip;
sym_t *sp;
a_assert(websValid(wp));
a_assert(path && *path);
if ((sp = symLookup(romTab, path)) == NULL) {
return -1;
}
wip = (websRomPageIndexType*) sp->content.value.integer;
wip->pos = 0;
return (wp->docfd = wip - websRomPageIndex);
}
/******************************************************************************/
/*
* Close a web page
*/
void websRomPageClose(int fd)
{
}
/******************************************************************************/
/*
* Stat a web page
*/
int websRomPageStat(char_t *path, websStatType *sbuf)
{
websRomPageIndexType *wip;
sym_t *sp;
a_assert(path && *path);
if ((sp = symLookup(romTab, path)) == NULL) {
return -1;
}
wip = (websRomPageIndexType*) sp->content.value.integer;
memset(sbuf, 0, sizeof(websStatType));
sbuf->size = wip->size;
if (wip->page == NULL) {
sbuf->isDir = 1;
}
return 0;
}
/******************************************************************************/
/*
* Read a web page
*/
int websRomPageReadData(webs_t wp, char *buf, int nBytes)
{
websRomPageIndexType *wip;
int len;
a_assert(websValid(wp));
a_assert(buf);
a_assert(wp->docfd >= 0);
wip = &websRomPageIndex[wp->docfd];
len = min(wip->size - wip->pos, nBytes);
memcpy(buf, &wip->page[wip->pos], len);
wip->pos += len;
return len;
}
/******************************************************************************/
/*
* Position a web page
*/
long websRomPageSeek(webs_t wp, long offset, int origin)
{
websRomPageIndexType *wip;
long pos;
a_assert(websValid(wp));
a_assert(origin == SEEK_SET || origin == SEEK_CUR || origin == SEEK_END);
a_assert(wp->docfd >= 0);
wip = &websRomPageIndex[wp->docfd];
if (origin != SEEK_SET && origin != SEEK_CUR && origin != SEEK_END) {
errno = EINVAL;
return -1;
}
if (wp->docfd < 0) {
errno = EBADF;
return -1;
}
pos = offset;
switch (origin) {
case SEEK_CUR:
pos = wip->pos + offset;
break;
case SEEK_END:
pos = wip->size + offset;
break;
default:
break;
}
if (pos < 0) {
errno = EBADF;
return -1;
}
return (wip->pos = pos);
}
#endif /* WEBS_PAGE_ROM */
/******************************************************************************/

View File

@@ -1,7 +0,0 @@
/*
* rtems_webserver.h --
*
*/
int rtems_initialize_webserver();

View File

@@ -1,230 +0,0 @@
/*
* security.c -- Security handler
*
* Copyright (c) GoAhead Software Inc., 1995-2000. All Rights Reserved.
*
* See the file "license.txt" for usage and redistribution license requirements
*/
/******************************** Description *********************************/
/*
* This module provides a basic security policy.
*/
/********************************* Includes ***********************************/
#include "wsIntrn.h"
#include "um.h"
#ifdef DIGEST_ACCESS_SUPPORT
#include "websda.h"
#endif
/********************************** Defines ***********************************/
/*
* The following #defines change the behaviour of security in the absence
* of User Management.
* Note that use of User management functions require prior calling of
* umInit() to behave correctly
*/
#ifndef USER_MANAGEMENT_SUPPORT
#define umGetAccessMethodForURL(url) AM_FULL
#define umUserExists(userid) 0
#define umUserCanAccessURL(userid, url) 1
#define umGetUserPassword(userid) websGetPassword()
#define umGetAccessLimitSecure(accessLimit) 0
#define umGetAccessLimit(url) NULL
#endif
/******************************** Local Data **********************************/
static char_t websPassword[WEBS_MAX_PASS]; /* Access password (decoded) */
#ifdef _DEBUG
static int debugSecurity = 1;
#else
static int debugSecurity = 0;
#endif
/*********************************** Code *************************************/
/*
* Determine if this request should be honored
*/
int websSecurityHandler(webs_t wp, char_t *urlPrefix, char_t *webDir, int arg,
char_t *url, char_t *path, char_t *query)
{
char_t *type, *userid, *password, *accessLimit;
int flags, nRet;
accessMeth_t am;
a_assert(websValid(wp));
a_assert(url && *url);
a_assert(path && *path);
/*
* Get the critical request details
*/
type = websGetRequestType(wp);
password = websGetRequestPassword(wp);
userid = websGetRequestUserName(wp);
flags = websGetRequestFlags(wp);
/*
* Get the access limit for the URL. Exit if none found.
*/
accessLimit = umGetAccessLimit(path);
if (accessLimit == NULL) {
return 0;
}
/*
* Check to see if URL must be encrypted
*/
#ifdef WEBS_SSL_SUPPORT
nRet = umGetAccessLimitSecure(accessLimit);
if (nRet && ((flags | WEBS_SECURE) == 0)) {
websStats.access++;
websError(wp, 200, T("Access Denied\nSecure access is required."));
trace(3, T("SEC: Non-secure access attempted on <%s>\n"), path);
return 1;
}
#endif
/*
* Get the access limit for the URL
*/
am = umGetAccessMethodForURL(accessLimit);
nRet = 0;
if ((flags & WEBS_LOCAL_REQUEST) && (debugSecurity == 0)) {
/*
* Local access is always allowed (defeat when debugging)
*/
} else if (am == AM_NONE) {
/*
* URL is supposed to be hidden! Make like it wasn't found.
*/
websStats.access++;
websError(wp, 400, T("Page Not Found"));
nRet = 1;
} else if (userid && *userid) {
if (!umUserExists(userid)) {
websStats.access++;
websError(wp, 200, T("Access Denied\nUnknown User"));
trace(3, T("SEC: Unknown user <%s> attempted to access <%s>\n"),
userid, path);
nRet = 1;
} else if (!umUserCanAccessURL(userid, accessLimit)) {
websStats.access++;
websError(wp, 403, T("Access Denied\nProhibited User"));
nRet = 1;
} else if (password && * password) {
char_t * userpass = umGetUserPassword(userid);
if (userpass) {
if (gstrcmp(password, userpass) != 0) {
websStats.access++;
websError(wp, 200, T("Access Denied\nWrong Password"));
trace(3, T("SEC: Password fail for user <%s>")
T("attempt to access <%s>\n"), userid, path);
nRet = 1;
} else {
/*
* User and password check out.
*/
}
bfree (B_L, userpass);
}
#ifdef DIGEST_ACCESS_SUPPORT
} else if (flags & WEBS_AUTH_DIGEST) {
char_t *digestCalc;
/*
* Check digest for equivalence
*/
wp->password = umGetUserPassword(userid);
a_assert(wp->digest);
a_assert(wp->nonce);
a_assert(wp->password);
digestCalc = websCalcDigest(wp);
a_assert(digestCalc);
if (gstrcmp(wp->digest, digestCalc) != 0) {
websStats.access++;
websError(wp, 200, T("Access Denied\nWrong Password"));
nRet = 1;
}
bfree (B_L, digestCalc);
#endif
} else {
/*
* No password has been specified
*/
#ifdef DIGEST_ACCESS_SUPPORT
if (am == AM_DIGEST) {
wp->flags |= WEBS_AUTH_DIGEST;
}
#endif
websStats.errors++;
websError(wp, 401,
T("Access to this document requires a password"));
nRet = 1;
}
} else if (am != AM_FULL) {
/*
* This will cause the browser to display a password / username
* dialog
*/
#ifdef DIGEST_ACCESS_SUPPORT
if (am == AM_DIGEST) {
wp->flags |= WEBS_AUTH_DIGEST;
}
#endif
websStats.errors++;
websError(wp, 401, T("Access to this document requires a User ID"));
nRet = 1;
}
bfree(B_L, accessLimit);
return nRet;
}
/******************************************************************************/
/*
* Delete the default security handler
*/
void websSecurityDelete()
{
websUrlHandlerDelete(websSecurityHandler);
}
/******************************************************************************/
/*
* Store the new password, expect a decoded password. Store in websPassword in
* the decoded form.
*/
void websSetPassword(char_t *password)
{
a_assert(password);
gstrncpy(websPassword, password, TSZ(websPassword));
}
/******************************************************************************/
/*
* Get password, return the decoded form
*/
char_t *websGetPassword()
{
return bstrdup(B_L, websPassword);
}
/******************************************************************************/

View File

@@ -1,789 +0,0 @@
/*
* sock.c -- Posix Socket upper layer support module for general posix use
*
* Copyright (c) GoAhead Software Inc., 1995-2000. All Rights Reserved.
*/
/******************************** Description *********************************/
/*
* Posix Socket Module. This supports blocking and non-blocking buffered
* socket I/O.
*/
/********************************** Includes **********************************/
#include <string.h>
#include <stdlib.h>
#if UEMF
#include "uemf.h"
#else
#include <socket.h>
#include <types.h>
#include <unistd.h>
#include "emfInternal.h"
#endif
/************************************ Locals **********************************/
socket_t **socketList; /* List of open sockets */
int socketMax; /* Maximum size of socket */
int socketHighestFd = -1; /* Highest socket fd opened */
/***************************** Forward Declarations ***************************/
static int socketDoOutput(socket_t *sp, char *buf, int toWrite, int *errCode);
static int tryAlternateSendTo(int sock, char *buf, int toWrite, int i,
struct sockaddr *server);
/*********************************** Code *************************************/
/*
* Write to a socket. Absorb as much data as the socket can buffer. Block if
* the socket is in blocking mode. Returns -1 on error, otherwise the number
* of bytes written.
*/
int socketWrite(int sid, char *buf, int bufsize)
{
socket_t *sp;
ringq_t *rq;
int len, bytesWritten, room;
a_assert(buf);
a_assert(bufsize >= 0);
if ((sp = socketPtr(sid)) == NULL) {
return -1;
}
/*
* Loop adding as much data to the output ringq as we can absorb. Initiate a
* flush when the ringq is too full and continue. Block in socketFlush if the
* socket is in blocking mode.
*/
rq = &sp->outBuf;
for (bytesWritten = 0; bufsize > 0; ) {
if ((room = ringqPutBlkMax(rq)) == 0) {
if (socketFlush(sid) < 0) {
return -1;
}
if ((room = ringqPutBlkMax(rq)) == 0) {
if (sp->flags & SOCKET_BLOCK) {
#if WIN || CE
int errCode;
if (! socketWaitForEvent(sp, FD_WRITE | SOCKET_WRITABLE,
&errCode)) {
return -1;
}
#endif
continue;
}
break;
}
continue;
}
len = min(room, bufsize);
ringqPutBlk(rq, (unsigned char *) buf, len);
bytesWritten += len;
bufsize -= len;
buf += len;
}
return bytesWritten;
}
/******************************************************************************/
/*
* Write a string to a socket
*/
int socketWriteString(int sid, char_t *buf)
{
#if UNICODE
char *byteBuf;
int r, len;
len = gstrlen(buf);
byteBuf = ballocUniToAsc(buf, len);
r = socketWrite(sid, byteBuf, len);
bfreeSafe(B_L, byteBuf);
return r;
#else
return socketWrite(sid, buf, strlen(buf));
#endif /* UNICODE */
}
/******************************************************************************/
/*
* Read from a socket. Return the number of bytes read if successful. This
* may be less than the requested "bufsize" and may be zero. Return -1 for
* errors. Return 0 for EOF. Otherwise return the number of bytes read.
* If this routine returns zero it indicates an EOF condition.
* which can be verified with socketEof()
* Note: this ignores the line buffer, so a previous socketGets
* which read a partial line may cause a subsequent socketRead to miss some
* data. This routine may block if the socket is in blocking mode.
*
*/
int socketRead(int sid, char *buf, int bufsize)
{
socket_t *sp;
ringq_t *rq;
int len, room, errCode, bytesRead;
a_assert(buf);
a_assert(bufsize > 0);
if ((sp = socketPtr(sid)) == NULL) {
return -1;
}
if (sp->flags & SOCKET_EOF) {
return 0;
}
rq = &sp->inBuf;
for (bytesRead = 0; bufsize > 0; ) {
len = min(ringqLen(rq), bufsize);
if (len <= 0) {
/*
* if blocking mode and already have data, exit now or it may block
* forever.
*/
if ((sp->flags & SOCKET_BLOCK) &&
(bytesRead > 0)) {
break;
}
/*
* This flush is critical for readers of datagram packets. If the
* buffer is not big enough to read the whole datagram in one hit,
* the recvfrom call will fail.
*/
ringqFlush(rq);
room = ringqPutBlkMax(rq);
len = socketGetInput(sid, (char *) rq->endp, room, &errCode);
if (len < 0) {
if (errCode == EWOULDBLOCK) {
if ((sp->flags & SOCKET_BLOCK) &&
(bytesRead == 0)) {
continue;
}
if (bytesRead >= 0) {
return bytesRead;
}
}
return -1;
} else if (len == 0) {
/*
* If bytesRead is 0, this is EOF since socketRead should never
* be called unless there is data yet to be read. Set the flag.
* Then pass back the number of bytes read.
*/
if (bytesRead == 0) {
sp->flags |= SOCKET_EOF;
}
return bytesRead;
}
ringqPutBlkAdj(rq, len);
len = min(len, bufsize);
}
memcpy(&buf[bytesRead], rq->servp, len);
ringqGetBlkAdj(rq, len);
bufsize -= len;
bytesRead += len;
}
return bytesRead;
}
/******************************************************************************/
/*
* Get a string from a socket. This returns data in *buf in a malloced string
* after trimming the '\n'. If there is zero bytes returned, *buf will be set
* to NULL. If doing non-blocking I/O, it returns -1 for error, EOF or when
* no complete line yet read. If doing blocking I/O, it will block until an
* entire line is read. If a partial line is read socketInputBuffered or
* socketEof can be used to distinguish between EOF and partial line still
* buffered. This routine eats and ignores carriage returns.
*/
int socketGets(int sid, char_t **buf)
{
socket_t *sp;
ringq_t *lq;
char c;
int rc, len;
a_assert(buf);
*buf = NULL;
if ((sp = socketPtr(sid)) == NULL) {
return -1;
}
lq = &sp->lineBuf;
while (1) {
if ((rc = socketRead(sid, &c, 1)) < 0) {
return rc;
}
if (rc == 0) {
/*
* If there is a partial line and we are at EOF, pretend we saw a '\n'
*/
if (ringqLen(lq) > 0 && (sp->flags & SOCKET_EOF)) {
c = '\n';
} else {
return -1;
}
}
/*
* If a newline is seen, return the data excluding the new line to the
* caller. If carriage return is seen, just eat it.
*/
if (c == '\n') {
len = ringqLen(lq);
if (len > 0) {
*buf = ballocAscToUni(lq->servp, len);
} else {
*buf = NULL;
}
ringqFlush(lq);
return len;
} else if (c == '\r') {
continue;
}
ringqPutcA(lq, c);
}
return 0;
}
/******************************************************************************/
/*
* Flush the socket. Block if the socket is in blocking mode.
* This will return -1 on errors and 0 if successful.
*/
int socketFlush(int sid)
{
socket_t *sp;
ringq_t *rq;
int len, bytesWritten, errCode;
if ((sp = socketPtr(sid)) == NULL) {
return -1;
}
rq = &sp->outBuf;
/*
* Set the background flushing flag which socketEventProc will check to
* continue the flush.
*/
if (! (sp->flags & SOCKET_BLOCK)) {
sp->flags |= SOCKET_FLUSHING;
}
/*
* Break from loop if not blocking after initiating output. If we are blocking
* we wait for a write event.
*/
while (ringqLen(rq) > 0) {
len = ringqGetBlkMax(&sp->outBuf);
bytesWritten = socketDoOutput(sp, (char*) rq->servp, len, &errCode);
if (bytesWritten < 0) {
if (errCode == EINTR) {
continue;
} else if (errCode == EWOULDBLOCK || errCode == EAGAIN) {
#if WIN || CE
if (sp->flags & SOCKET_BLOCK) {
int errCode;
if (! socketWaitForEvent(sp, FD_WRITE | SOCKET_WRITABLE,
&errCode)) {
return -1;
}
continue;
}
#endif
/*
* Ensure we get a FD_WRITE message when the socket can absorb
* more data (non-blocking only.) Store the user's mask if we
* haven't done it already.
*/
if (sp->saveMask < 0 ) {
sp->saveMask = sp->handlerMask;
socketRegisterInterest(sp,
sp->handlerMask | SOCKET_WRITABLE);
}
return 0;
}
return -1;
}
ringqGetBlkAdj(rq, bytesWritten);
}
/*
* If the buffer is empty, reset the ringq pointers to point to the start
* of the buffer. This is essential to ensure that datagrams get written
* in one single I/O operation.
*/
if (ringqLen(rq) == 0) {
ringqFlush(rq);
}
/*
* Restore the users mask if it was saved by the non-blocking code above.
* Note: saveMask = -1 if empty. socketRegisterInterest will set handlerMask
*/
if (sp->saveMask >= 0) {
socketRegisterInterest(sp, sp->saveMask);
sp->saveMask = -1;
}
sp->flags &= ~SOCKET_FLUSHING;
return 0;
}
/******************************************************************************/
/*
* Return the count of input characters buffered. We look at both the line
* buffer and the input (raw) buffer. Return -1 on error or EOF.
*/
int socketInputBuffered(int sid)
{
socket_t *sp;
if ((sp = socketPtr(sid)) == NULL) {
return -1;
}
if (socketEof(sid)) {
return -1;
}
return ringqLen(&sp->lineBuf) + ringqLen(&sp->inBuf);
}
/******************************************************************************/
/*
* Return true if EOF
*/
int socketEof(int sid)
{
socket_t *sp;
if ((sp = socketPtr(sid)) == NULL) {
return -1;
}
return sp->flags & SOCKET_EOF;
}
/******************************************************************************/
/*
* Return the number of bytes the socket can absorb without blocking
*/
int socketCanWrite(int sid)
{
socket_t *sp;
if ((sp = socketPtr(sid)) == NULL) {
return -1;
}
return sp->outBuf.buflen - ringqLen(&sp->outBuf) - 1;
}
/******************************************************************************/
/*
* Add one to allow the user to write exactly SOCKET_BUFSIZ
*/
void socketSetBufferSize(int sid, int in, int line, int out)
{
socket_t *sp;
if ((sp = socketPtr(sid)) == NULL) {
return;
}
if (in >= 0) {
ringqClose(&sp->inBuf);
in++;
ringqOpen(&sp->inBuf, in, in);
}
if (line >= 0) {
ringqClose(&sp->lineBuf);
line++;
ringqOpen(&sp->lineBuf, line, line);
}
if (out >= 0) {
ringqClose(&sp->outBuf);
out++;
ringqOpen(&sp->outBuf, out, out);
}
}
/******************************************************************************/
/*
* Create a user handler for this socket. The handler called whenever there
* is an event of interest as defined by handlerMask (SOCKET_READABLE, ...)
*/
void socketCreateHandler(int sid, int handlerMask, socketHandler_t handler,
int data)
{
socket_t *sp;
if ((sp = socketPtr(sid)) == NULL) {
return;
}
sp->handler = handler;
sp->handler_data = data;
socketRegisterInterest(sp, handlerMask);
}
/******************************************************************************/
/*
* Delete a handler
*/
void socketDeleteHandler(int sid)
{
socket_t *sp;
if ((sp = socketPtr(sid)) == NULL) {
return;
}
sp->handler = NULL;
socketRegisterInterest(sp, 0);
}
/******************************************************************************/
/*
* Socket output procedure. Return -1 on errors otherwise return the number
* of bytes written.
*/
static int socketDoOutput(socket_t *sp, char *buf, int toWrite, int *errCode)
{
struct sockaddr_in server;
int bytes;
a_assert(sp);
a_assert(buf);
a_assert(toWrite > 0);
a_assert(errCode);
*errCode = 0;
#if WIN || CE
if ((sp->flags & SOCKET_ASYNC)
&& ! socketWaitForEvent(sp, FD_CONNECT, errCode)) {
return -1;
}
#endif
/*
* Write the data
*/
if (sp->flags & SOCKET_BROADCAST) {
server.sin_family = AF_INET;
#if UEMF || LITTLEFOOT
server.sin_addr.s_addr = INADDR_BROADCAST;
#else
server.sin_addr.s_addr = inet_addr(basicGetBroadcastAddress());
#endif
server.sin_port = htons((short)(sp->port & 0xFFFF));
if ((bytes = sendto(sp->sock, buf, toWrite, 0,
(struct sockaddr *) &server, sizeof(server))) < 0) {
bytes = tryAlternateSendTo(sp->sock, buf, toWrite, 0,
(struct sockaddr *) &server);
}
} else if (sp->flags & SOCKET_DATAGRAM) {
server.sin_family = AF_INET;
server.sin_addr.s_addr = inet_addr(sp->host);
server.sin_port = htons((short)(sp->port & 0xFFFF));
bytes = sendto(sp->sock, buf, toWrite, 0,
(struct sockaddr *) &server, sizeof(server));
} else {
bytes = send(sp->sock, buf, toWrite, 0);
}
if (bytes < 0) {
*errCode = socketGetError();
#if WIN || CE
sp->currentEvents &= ~FD_WRITE;
#endif
return -1;
} else if (bytes == 0 && bytes != toWrite) {
*errCode = EWOULDBLOCK;
#if WIN || CE
sp->currentEvents &= ~FD_WRITE;
#endif
return -1;
}
/*
* Ensure we get to write some more data real soon if the socket can absorb
* more data
*/
#if !UEMF
#if WIN
if (sp->interestEvents & FD_WRITE) {
emfTime_t blockTime = { 0, 0 };
emfSetMaxBlockTime(&blockTime);
}
#endif /* WIN */
#endif
return bytes;
}
/******************************************************************************/
/*
* If the sendto failed, swap the first two bytes in the
* sockaddr structure. This is a kludge due to a change in
* VxWorks between versions 5.3 and 5.4, but we want the
* product to run on either.
*/
static int tryAlternateSendTo(int sock, char *buf, int toWrite, int i,
struct sockaddr *server)
{
#if VXWORKS
char *ptr;
ptr = (char *)server;
*ptr = *(ptr+1);
*(ptr+1) = 0;
return sendto(sock, buf, toWrite, i, server, sizeof(struct sockaddr));
#else
return -1;
#endif /* VXWORKS */
}
/******************************************************************************/
/*
* Allocate a new socket structure
*/
int socketAlloc(char *host, int port, socketAccept_t accept, int flags)
{
socket_t *sp;
int sid;
if ((sid = hAllocEntry((void***) &socketList, &socketMax,
sizeof(socket_t))) < 0) {
return -1;
}
sp = socketList[sid];
sp->sid = sid;
sp->accept = accept;
sp->port = port;
sp->fileHandle = -1;
sp->saveMask = -1;
if (host) {
strncpy(sp->host, host, sizeof(sp->host));
}
/*
* Preserve only specified flags from the callers open
*/
a_assert((flags & ~(SOCKET_BROADCAST|SOCKET_DATAGRAM|SOCKET_BLOCK|
SOCKET_LISTENING)) == 0);
sp->flags = flags & (SOCKET_BROADCAST | SOCKET_DATAGRAM | SOCKET_BLOCK|
SOCKET_LISTENING);
/*
* Add one to allow the user to write exactly SOCKET_BUFSIZ
*/
ringqOpen(&sp->inBuf, SOCKET_BUFSIZ, SOCKET_BUFSIZ);
ringqOpen(&sp->outBuf, SOCKET_BUFSIZ + 1, SOCKET_BUFSIZ + 1);
ringqOpen(&sp->lineBuf, SOCKET_BUFSIZ, -1);
return sid;
}
/******************************************************************************/
/*
* Free a socket structure
*/
void socketFree(int sid)
{
socket_t *sp;
char_t buf[256];
int i;
if ((sp = socketPtr(sid)) == NULL) {
return;
}
/*
* To close a socket, remove any registered interests, set it to
* non-blocking so that the recv which follows won't block, do a
* shutdown on it so peers on the other end will receive a FIN,
* then read any data not yet retrieved from the receive buffer,
* and finally close it. If these steps are not all performed
* RESETs may be sent to the other end causing problems.
*/
socketRegisterInterest(sp, 0);
if (sp->sock >= 0) {
socketSetBlock(sid, 0);
if (shutdown(sp->sock, 1) >= 0) {
recv(sp->sock, buf, sizeof(buf), 0);
}
#if WIN || CE
closesocket(sp->sock);
#else
close(sp->sock);
#endif
}
ringqClose(&sp->inBuf);
ringqClose(&sp->outBuf);
ringqClose(&sp->lineBuf);
bfree(B_L, sp);
socketMax = hFree((void***) &socketList, sid);
/*
* Calculate the new highest socket number
*/
socketHighestFd = -1;
for (i = 0; i < socketMax; i++) {
if ((sp = socketList[i]) == NULL) {
continue;
}
socketHighestFd = max(socketHighestFd, sp->sock);
}
}
/******************************************************************************/
/*
* Validate a socket handle
*/
socket_t *socketPtr(int sid)
{
if (sid < 0 || sid >= socketMax || socketList[sid] == NULL) {
a_assert(NULL);
errno = EBADF;
return NULL;
}
a_assert(socketList[sid]);
return socketList[sid];
}
/******************************************************************************/
/*
* Get the operating system error code
*/
int socketGetError()
{
#if WIN || CE
switch (WSAGetLastError()) {
case WSAEWOULDBLOCK:
return EWOULDBLOCK;
case WSAECONNRESET:
return ECONNRESET;
case WSAENETDOWN:
return ENETDOWN;
case WSAEPROCLIM:
return EAGAIN;
case WSAEINTR:
return EINTR;
default:
return EINVAL;
}
#else
return errno;
#endif
}
/******************************************************************************/
/*
* Return the underlying socket handle
*/
int socketGetHandle(int sid)
{
socket_t *sp;
if ((sp = socketPtr(sid)) == NULL) {
return -1;
}
return sp->sock;
}
/******************************************************************************/
/*
* Get blocking mode
*/
int socketGetBlock(int sid)
{
socket_t *sp;
if ((sp = socketPtr(sid)) == NULL) {
a_assert(0);
return 0;
}
return (sp->flags & SOCKET_BLOCK);
}
/******************************************************************************/
/*
* Get mode
*/
int socketGetMode(int sid)
{
socket_t *sp;
if ((sp = socketPtr(sid)) == NULL) {
a_assert(0);
return 0;
}
return sp->flags;
}
/******************************************************************************/
/*
* Set mode
*/
void socketSetMode(int sid, int mode)
{
socket_t *sp;
if ((sp = socketPtr(sid)) == NULL) {
a_assert(0);
return;
}
sp->flags = mode;
}
/******************************************************************************/
/*
* Get port.
*/
int socketGetPort(int sid)
{
socket_t *sp;
if ((sp = socketPtr(sid)) == NULL) {
return -1;
}
return sp->port;
}
/******************************************************************************/

File diff suppressed because it is too large Load Diff

View File

@@ -1,473 +0,0 @@
/*
* sym.c -- Symbol Table module
*
* Copyright (c) GoAhead Software Inc., 1995-2000. All Rights Reserved.
*
* See the file "license.txt" for usage and redistribution license requirements
*/
/******************************** Description *********************************/
/*
* This module implements a highly efficient generic symbol table with
* update and access routines. Symbols are simple character strings and
* the values they take can be flexible types as defined by value_t.
* This modules allows multiple symbol tables to be created.
*/
/********************************* Includes ***********************************/
#if UEMF
#include "uemf.h"
#else
#include "basic/basicInternal.h"
#endif
/********************************* Defines ************************************/
typedef struct { /* Symbol table descriptor */
int inuse; /* Is this entry in use */
int hash_size; /* Size of the table below */
sym_t **hash_table; /* Allocated at run time */
} sym_tabent_t;
/********************************* Globals ************************************/
static sym_tabent_t **sym; /* List of symbol tables */
static int symMax; /* One past the max symbol table */
static int symOpenCount = 0; /* Count of apps using sym */
static int htIndex; /* Current location in table */
static sym_t* next; /* Next symbol in iteration */
/**************************** Forward Declarations ****************************/
static int hashIndex(sym_tabent_t *tp, char_t *name);
static sym_t *hash(sym_tabent_t *tp, char_t *name);
static int calcPrime(int size);
/*********************************** Code *************************************/
/*
* Open the symbol table subSystem.
*/
int symSubOpen()
{
if (++symOpenCount == 1) {
symMax = 0;
sym = NULL;
}
return 0;
}
/******************************************************************************/
/*
* Close the symbol table subSystem.
*/
void symSubClose()
{
if (--symOpenCount <= 0) {
symOpenCount = 0;
}
}
/******************************************************************************/
/*
* Create a symbol table.
*/
sym_fd_t symOpen(int hash_size)
{
sym_fd_t sd;
sym_tabent_t *tp;
a_assert(hash_size > 2);
/*
* Create a new handle for this symbol table
*/
if ((sd = hAlloc((void***) &sym)) < 0) {
return -1;
}
/*
* Create a new symbol table structure and zero
*/
if ((tp = (sym_tabent_t*) balloc(B_L, sizeof(sym_tabent_t))) == NULL) {
symMax = hFree((void***) &sym, sd);
return -1;
}
memset(tp, 0, sizeof(sym_tabent_t));
if (sd >= symMax) {
symMax = sd + 1;
}
a_assert(0 <= sd && sd < symMax);
sym[sd] = tp;
/*
* Now create the hash table for fast indexing.
*/
tp->hash_size = calcPrime(hash_size);
tp->hash_table = (sym_t**) balloc(B_L, tp->hash_size * sizeof(sym_t*));
a_assert(tp->hash_table);
memset(tp->hash_table, 0, tp->hash_size * sizeof(sym_t*));
return sd;
}
/******************************************************************************/
/*
* Close this symbol table. Call a cleanup function to allow the caller
* to free resources associated with each symbol table entry.
*/
void symClose(sym_fd_t sd)
{
sym_tabent_t *tp;
sym_t *sp, *forw;
int i;
a_assert(0 <= sd && sd < symMax);
tp = sym[sd];
a_assert(tp);
/*
* Free all symbols in the hash table, then the hash table itself.
*/
for (i = 0; i < tp->hash_size; i++) {
for (sp = tp->hash_table[i]; sp; sp = forw) {
forw = sp->forw;
valueFree(&sp->name);
valueFree(&sp->content);
bfree(B_L, (void*) sp);
sp = forw;
}
}
bfree(B_L, (void*) tp->hash_table);
symMax = hFree((void***) &sym, sd);
bfree(B_L, (void*) tp);
}
/******************************************************************************/
/*
* Return the first symbol in the hashtable if there is one. This call is used
* as the first step in traversing the table. A call to symFirst should be
* followed by calls to symNext to get all the rest of the entries.
*/
sym_t* symFirst(sym_fd_t sd)
{
sym_tabent_t *tp;
sym_t *sp, *forw;
int i;
a_assert(0 <= sd && sd < symMax);
tp = sym[sd];
a_assert(tp);
/*
* Find the first symbol in the hashtable and return a pointer to it.
*/
for (i = 0; i < tp->hash_size; i++) {
for (sp = tp->hash_table[i]; sp; sp = forw) {
forw = sp->forw;
if (forw == NULL) {
htIndex = i + 1;
next = tp->hash_table[htIndex];
} else {
htIndex = i;
next = forw;
}
return sp;
}
}
return NULL;
}
/******************************************************************************/
/*
* Return the next symbol in the hashtable if there is one. See symFirst.
*/
sym_t* symNext(sym_fd_t sd)
{
sym_tabent_t *tp;
sym_t *sp, *forw;
int i;
a_assert(0 <= sd && sd < symMax);
tp = sym[sd];
a_assert(tp);
/*
* Find the first symbol in the hashtable and return a pointer to it.
*/
for (i = htIndex; i < tp->hash_size; i++) {
for (sp = next; sp; sp = forw) {
forw = sp->forw;
if (forw == NULL) {
htIndex = i + 1;
next = tp->hash_table[htIndex];
} else {
htIndex = i;
next = forw;
}
return sp;
}
next = tp->hash_table[i + 1];
}
return NULL;
}
/******************************************************************************/
/*
* Lookup a symbol and return a pointer to the symbol entry. If not present
* then return a NULL.
*/
sym_t *symLookup(sym_fd_t sd, char_t *name)
{
sym_tabent_t *tp;
sym_t *sp;
char_t *cp;
a_assert(0 <= sd && sd < symMax);
if ((tp = sym[sd]) == NULL) {
return NULL;
}
if (name == NULL || *name == '\0') {
return NULL;
}
/*
* Do an initial hash and then follow the link chain to find the right entry
*/
for (sp = hash(tp, name); sp; sp = sp->forw) {
cp = sp->name.value.string;
if (cp[0] == name[0] && gstrcmp(cp, name) == 0) {
break;
}
}
return sp;
}
/******************************************************************************/
/*
* Enter a symbol into the table. If already there, update its value.
* Always succeeds if memory available. We allocate a copy of "name" here
* so it can be a volatile variable. The value "v" is just a copy of the
* passed in value, so it MUST be persistent.
*/
sym_t *symEnter(sym_fd_t sd, char_t *name, value_t v, int arg)
{
sym_tabent_t *tp;
sym_t *sp, *last;
char_t *cp;
int hindex;
a_assert(name);
a_assert(0 <= sd && sd < symMax);
tp = sym[sd];
a_assert(tp);
/*
* Calculate the first daisy-chain from the hash table. If non-zero, then
* we have daisy-chain, so scan it and look for the symbol.
*/
last = NULL;
hindex = hashIndex(tp, name);
if ((sp = tp->hash_table[hindex]) != NULL) {
for (; sp; sp = sp->forw) {
cp = sp->name.value.string;
if (cp[0] == name[0] && gstrcmp(cp, name) == 0) {
break;
}
last = sp;
}
if (sp) {
/*
* Found, so update the value
* If the caller stores handles which require freeing, they
* will be lost here. It is the callers responsibility to free
* resources before overwriting existing contents. We will here
* free allocated strings which occur due to value_instring().
* We should consider providing the cleanup function on the open rather
* than the close and then we could call it here and solve the problem.
*/
if (sp->content.valid) {
valueFree(&sp->content);
}
sp->content = v;
sp->arg = arg;
return sp;
}
/*
* Not found so allocate and append to the daisy-chain
*/
sp = (sym_t*) balloc(B_L, sizeof(sym_t));
if (sp == NULL) {
return NULL;
}
sp->name = valueString(name, VALUE_ALLOCATE);
sp->content = v;
sp->forw = (sym_t*) NULL;
sp->arg = arg;
last->forw = sp;
} else {
/*
* Daisy chain is empty so we need to start the chain
*/
sp = (sym_t*) balloc(B_L, sizeof(sym_t));
if (sp == NULL) {
return NULL;
}
tp->hash_table[hindex] = sp;
tp->hash_table[hashIndex(tp, name)] = sp;
sp->forw = (sym_t*) NULL;
sp->content = v;
sp->arg = arg;
sp->name = valueString(name, VALUE_ALLOCATE);
}
return sp;
}
/******************************************************************************/
/*
* Delete a symbol from a table
*/
int symDelete(sym_fd_t sd, char_t *name)
{
sym_tabent_t *tp;
sym_t *sp, *last;
char_t *cp;
int hindex;
a_assert(name && *name);
a_assert(0 <= sd && sd < symMax);
tp = sym[sd];
a_assert(tp);
/*
* Calculate the first daisy-chain from the hash table. If non-zero, then
* we have daisy-chain, so scan it and look for the symbol.
*/
last = NULL;
hindex = hashIndex(tp, name);
if ((sp = tp->hash_table[hindex]) != NULL) {
for ( ; sp; sp = sp->forw) {
cp = sp->name.value.string;
if (cp[0] == name[0] && gstrcmp(cp, name) == 0) {
break;
}
last = sp;
}
}
if (sp == (sym_t*) NULL) { /* Not Found */
return -1;
}
/*
* Unlink and free the symbol. Last will be set if the element to be deleted
* is not first in the chain.
*/
if (last) {
last->forw = sp->forw;
} else {
tp->hash_table[hindex] = sp->forw;
}
valueFree(&sp->name);
valueFree(&sp->content);
bfree(B_L, (void*) sp);
return 0;
}
/******************************************************************************/
/*
* Hash a symbol and return a pointer to the hash daisy-chain list
* All symbols reside on the chain (ie. none stored in the hash table itself)
*/
static sym_t *hash(sym_tabent_t *tp, char_t *name)
{
a_assert(tp);
return tp->hash_table[hashIndex(tp, name)];
}
/******************************************************************************/
/*
* Compute the hash function and return an index into the hash table
* We use a basic additive function that is then made modulo the size of the
* table.
*/
static int hashIndex(sym_tabent_t *tp, char_t *name)
{
unsigned int sum;
int i;
a_assert(tp);
/*
* Add in each character shifted up progressively by 7 bits. The shift
* amount is rounded so as to not shift too far. It thus cycles with each
* new cycle placing character shifted up by one bit.
*/
i = 0;
sum = 0;
while (*name) {
sum += (((int) *name++) << i);
i = (i + 7) % (BITS(int) - BITSPERBYTE);
}
return sum % tp->hash_size;
}
/******************************************************************************/
/*
* Check if this number is a prime
*/
static int isPrime(int n)
{
int i, max;
a_assert(n > 0);
max = n / 2;
for (i = 2; i <= max; i++) {
if (n % i == 0) {
return 0;
}
}
return 1;
}
/******************************************************************************/
/*
* Calculate the largest prime smaller than size.
*/
static int calcPrime(int size)
{
int count;
a_assert(size > 0);
for (count = size; count > 0; count--) {
if (isPrime(count)) {
return count;
}
}
return 1;
}
/******************************************************************************/

View File

@@ -1,281 +0,0 @@
/*
* uemf.c -- GoAhead Micro Embedded Management Framework
*
* Copyright (c) GoAhead Software Inc., 1995-2000. All Rights Reserved.
*
* See the file "license.txt" for usage and redistribution license requirements
*/
/********************************** Description *******************************/
/*
* This module provides compatibility with the full GoAhead EMF.
* It is a collection of routines which permits the GoAhead WebServer to
* run stand-alone and to also load as a solution pack under the GoAhead EMF.
*/
/*********************************** Includes *********************************/
#include "uemf.h"
/********************************** Local Data ********************************/
int emfInst; /* Application instance handle */
/****************************** Forward Declarations **************************/
extern void defaultErrorHandler(int etype, char_t *buf);
static void (*errorHandler)(int etype, char_t *msg) = defaultErrorHandler;
extern void defaultTraceHandler(int level, char_t *buf);
static void (*traceHandler)(int level, char_t *buf) = defaultTraceHandler;
/************************************* Code ***********************************/
/*
* Error message that doesn't need user attention. Customize this code
* to direct error messages to wherever the developer wishes
*/
void error(E_ARGS_DEC, int etype, char_t *fmt, ...)
{
va_list args;
char_t *fmtBuf, *buf;
va_start(args, fmt);
fmtValloc(&fmtBuf, E_MAX_ERROR, fmt, args);
if (etype == E_LOG) {
fmtAlloc(&buf, E_MAX_ERROR, T("%s\n"), fmtBuf);
#if DEV
} else if (etype == E_ASSERT) {
fmtAlloc(&buf, E_MAX_ERROR,
T("Assertion %s, failed at %s %d\n"), fmtBuf, E_ARGS);
#endif
} else if (etype == E_USER) {
fmtAlloc(&buf, E_MAX_ERROR, T("%s\n"), fmtBuf);
}
va_end(args);
bfree(B_L, fmtBuf);
if (errorHandler) {
errorHandler(etype, buf);
}
bfreeSafe(B_L, buf);
}
/******************************************************************************/
/*
* Replace the default error handler. Return pointer to old error handler.
*/
void (*errorSetHandler(void (*function)(int etype, char_t *msg))) \
(int etype, char_t *msg)
{
void (*oldHandler)(int etype, char_t *buf);
oldHandler = errorHandler;
errorHandler = function;
return oldHandler;
}
/******************************************************************************/
/*
* Trace log. Customize this function to log trace output
*/
void trace(int level, char_t *fmt, ...)
{
va_list args;
char_t *buf;
va_start(args, fmt);
fmtValloc(&buf, VALUE_MAX_STRING, fmt, args);
if (traceHandler) {
traceHandler(level, buf);
}
bfreeSafe(B_L, buf);
va_end(args);
}
/******************************************************************************/
/*
* Trace log. Customize this function to log trace output
*/
void traceRaw(char_t *buf)
{
if (traceHandler) {
traceHandler(0, buf);
}
}
/******************************************************************************/
/*
* Replace the default trace handler. Return a pointer to the old handler.
*/
void (*traceSetHandler(void (*function)(int level, char_t *buf)))
(int level, char *buf)
{
void (*oldHandler)(int level, char_t *buf);
oldHandler = traceHandler;
if (function) {
traceHandler = function;
}
return oldHandler;
}
/******************************************************************************/
/*
* Save the instance handle
*/
void emfInstSet(int inst)
{
emfInst = inst;
}
/******************************************************************************/
/*
* Get the instance handle
*/
int emfInstGet()
{
return emfInst;
}
/******************************************************************************/
/*
* Convert a string to lower case
*/
char_t *strlower(char_t *string)
{
char_t *s;
a_assert(string);
if (string == NULL) {
return NULL;
}
s = string;
while (*s) {
if (gisupper(*s)) {
*s = (char_t) gtolower(*s);
}
s++;
}
*s = '\0';
return string;
}
/******************************************************************************/
/*
* Convert a string to upper case
*/
char_t *strupper(char_t *string)
{
char_t *s;
a_assert(string);
if (string == NULL) {
return NULL;
}
s = string;
while (*s) {
if (gislower(*s)) {
*s = (char_t) gtoupper(*s);
}
s++;
}
*s = '\0';
return string;
}
/******************************************************************************/
/*
* Convert integer to ascii string. Allow a NULL string in which case we
* allocate a dynamic buffer.
*/
char_t *stritoa(int n, char_t *string, int width)
{
char_t *cp, *lim, *s;
char_t buf[16]; /* Just temp to hold number */
int next, minus;
a_assert(string && width > 0);
if (string == NULL) {
if (width == 0) {
width = 10;
}
if ((string = balloc(B_L, width + 1)) == NULL) {
return NULL;
}
}
if (n < 0) {
minus = 1;
n = -n;
width--;
} else {
minus = 0;
}
cp = buf;
lim = &buf[width - 1];
while (n > 9 && cp < lim) {
next = n;
n /= 10;
*cp++ = (char_t) (next - n * 10 + '0');
}
if (cp < lim) {
*cp++ = (char_t) (n + '0');
}
s = string;
if (minus) {
*s++ = '-';
}
while (cp > buf) {
*s++ = *--cp;
}
*s++ = '\0';
return string;
}
/******************************************************************************/
/*
* Stubs
*/
char_t *basicGetProduct()
{
return T("uemf");
}
char_t *basicGetAddress()
{
return T("localhost");
}
int errorOpen(char_t *pname)
{
return 0;
}
void errorClose()
{
}
/******************************************************************************/

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,184 +0,0 @@
/*
* um.h -- GoAhead User Management public header
*
* Copyright (c) GoAhead Software Inc., 1992-2000. All Rights Reserved.
*
* See the file "license.txt" for information on usage and redistribution
*
* $Id$
*/
#ifndef _h_UM
#define _h_UM 1
/******************************** Description *********************************/
/*
* GoAhead User Management header. This defines the User Management
* public APIs. Include this header for files that contain access to
* user inquiry or management.
*/
/********************************* Includes ***********************************/
#if ! UEMF
#include "basic/basic.h"
#include "emf/emf.h"
#else
#include "uemf.h"
#endif
/********************************** Defines ***********************************/
/*
* Error Return Flags
*/
#define UM_OK 0
#define UM_ERR_GENERAL -1
#define UM_ERR_NOT_FOUND -2
#define UM_ERR_PROTECTED -3
#define UM_ERR_DUPLICATE -4
#define UM_ERR_IN_USE -5
#define UM_ERR_BAD_NAME -6
#define UM_ERR_BAD_PASSWORD -7
/*
* Privilege Masks
*/
#define PRIV_NONE 0x00
#define PRIV_READ 0x01
#define PRIV_WRITE 0x02
#define PRIV_ADMIN 0x04
/*
* User classes
*/
typedef short bool_t;
#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif
typedef enum {
AM_NONE = 0,
AM_FULL,
AM_BASIC,
AM_DIGEST,
AM_INVALID
} accessMeth_t;
/********************************** Prototypes ********************************/
/*
* umOpen() must be called before accessing User Management functions
*/
extern int umOpen();
/*
* umClose() should be called before shutdown to free memory
*/
extern void umClose();
/*
* umCommit() persists the user management database
*/
extern int umCommit(char_t *filename);
/*
* umRestore() loads the user management database
*/
extern int umRestore(char_t *filename);
/*
* umUser functions use a user ID for a key
*/
extern int umAddUser(char_t *user, char_t *password,
char_t *group, bool_t protect, bool_t disabled);
extern int umDeleteUser(char_t *user);
extern char_t *umGetFirstUser();
extern char_t *umGetNextUser(char_t *lastUser);
extern bool_t umUserExists(char_t *user);
extern char_t *umGetUserPassword(char_t *user);
extern int umSetUserPassword(char_t *user, char_t *password);
extern char_t *umGetUserGroup(char_t *user);
extern int umSetUserGroup(char_t *user, char_t *password);
extern bool_t umGetUserEnabled(char_t *user);
extern int umSetUserEnabled(char_t *user, bool_t enabled);
extern bool_t umGetUserProtected(char_t *user);
extern int umSetUserProtected(char_t *user, bool_t protect);
/*
* umGroup functions use a group name for a key
*/
extern int umAddGroup(char_t *group, short privilege,
accessMeth_t am, bool_t protect, bool_t disabled);
extern int umDeleteGroup(char_t *group);
extern char_t *umGetFirstGroup();
extern char_t *umGetNextGroup(char_t *lastUser);
extern bool_t umGroupExists(char_t *group);
extern bool_t umGetGroupInUse(char_t *group);
extern accessMeth_t umGetGroupAccessMethod(char_t *group);
extern int umSetGroupAccessMethod(char_t *group, accessMeth_t am);
extern bool_t umGetGroupEnabled(char_t *group);
extern int umSetGroupEnabled(char_t *group, bool_t enabled);
extern short umGetGroupPrivilege(char_t *group);
extern int umSetGroupPrivilege(char_t *group, short privileges);
extern bool_t umGetGroupProtected(char_t *group);
extern int umSetGroupProtected(char_t *group, bool_t protect);
/*
* umAccessLimit functions use a URL as a key
*/
extern int umAddAccessLimit(char_t *url, accessMeth_t am,
short secure, char_t *group);
extern int umDeleteAccessLimit(char_t *url);
extern char_t *umGetFirstAccessLimit();
extern char_t *umGetNextAccessLimit(char_t *lastUser);
/*
* Returns the name of an ancestor access limit if
*/
extern char_t *umGetAccessLimit(char_t *url);
extern bool_t umAccessLimitExists(char_t *url);
extern accessMeth_t umGetAccessLimitMethod(char_t *url);
extern int umSetAccessLimitMethod(char_t *url, accessMeth_t am);
extern short umGetAccessLimitSecure(char_t *url);
extern int umSetAccessLimitSecure(char_t *url, short secure);
extern char_t *umGetAccessLimitGroup(char_t *url);
extern int umSetAccessLimitGroup(char_t *url, char_t *group);
/*
* Convenience Functions
*/
extern accessMeth_t umGetAccessMethodForURL(char_t *url);
extern bool_t umUserCanAccessURL(char_t *user, char_t *url);
#endif /* _h_UM */
/******************************************************************************/

View File

@@ -1,210 +0,0 @@
/*
* url.c -- Parse URLs
*
* Copyright (c) GoAhead Software Inc., 1995-2000. All Rights Reserved.
*
* See the file "license.txt" for usage and redistribution license requirements
*/
/******************************** Description *********************************/
/*
* This module parses URLs into their components.
*/
/********************************* Includes ***********************************/
#include "wsIntrn.h"
/********************************* Statics ************************************/
/*
* htmExt is declared in this way to avoid a Linux and Solaris segmentation
* fault when a constant string is passed to strlower which could change its
* argument.
*/
char_t htmExt[] = T(".htm");
/*********************************** Code *************************************/
/*
* Return the mime type for the given URL given a URL.
* The caller supplies the buffer to hold the result.
* charCnt is the number of characters the buffer will hold, ascii or UNICODE.
*/
char_t *websUrlType(char_t *url, char_t *buf, int charCnt)
{
sym_t *sp;
char_t *ext, *parsebuf;
a_assert(url && *url);
a_assert(buf && charCnt > 0);
if (url == NULL || *url == '\0') {
gstrcpy(buf, T("text/plain"));
return buf;
}
if (websUrlParse(url, &parsebuf, NULL, NULL, NULL, NULL, NULL,
NULL, &ext) < 0) {
gstrcpy(buf, T("text/plain"));
return buf;
}
strlower(ext);
/*
* Lookup the mime type symbol table to find the relevant content type
*/
if ((sp = symLookup(websMime, ext)) != NULL) {
gstrncpy(buf, sp->content.value.string, charCnt);
} else {
gstrcpy(buf, T("text/plain"));
}
bfree(B_L, parsebuf);
return buf;
}
/******************************************************************************/
/*
* Parse the URL. A buffer is allocated to store the parsed URL in *pbuf.
* This must be freed by the caller. NOTE: tag is not yet fully supported.
*/
int websUrlParse(char_t *url, char_t **pbuf, char_t **phost, char_t **ppath,
char_t **pport, char_t **pquery, char_t **pproto, char_t **ptag,
char_t **pext)
{
char_t *tok, *cp, *host, *path, *port, *proto, *tag, *query, *ext;
char_t *last_delim, *hostbuf, *portbuf, *buf;
int c, len, ulen;
a_assert(url);
a_assert(pbuf);
ulen = gstrlen(url);
/*
* We allocate enough to store separate hostname and port number fields.
* As there are 3 strings in the one buffer, we need room for 3 null chars.
* We allocate MAX_PORT_LEN char_t's for the port number.
*/
len = ulen * 2 + MAX_PORT_LEN + 3;
if ((buf = balloc(B_L, len * sizeof(char_t))) == NULL) {
return -1;
}
portbuf = &buf[len - MAX_PORT_LEN - 1];
hostbuf = &buf[ulen+1];
gstrcpy(buf, url);
url = buf;
/*
* Convert the current listen port to a string. We use this if the URL has
* no explicit port setting
*/
stritoa(websGetPort(), portbuf, MAX_PORT_LEN);
port = portbuf;
path = T("/");
proto = T("http");
host = T("localhost");
query = T("");
ext = htmExt;
tag = T("");
if (gstrncmp(url, T("http://"), 7) == 0) {
tok = &url[7];
tok[-3] = '\0';
proto = url;
host = tok;
for (cp = tok; *cp; cp++) {
if (*cp == '/') {
break;
}
if (*cp == ':') {
*cp++ = '\0';
port = cp;
tok = cp;
}
}
if ((cp = gstrchr(tok, '/')) != NULL) {
/*
* If a full URL is supplied, we need to copy the host and port
* portions into static buffers.
*/
c = *cp;
*cp = '\0';
gstrncpy(hostbuf, host, ulen);
gstrncpy(portbuf, port, MAX_PORT_LEN);
*cp = c;
host = hostbuf;
port = portbuf;
path = cp;
tok = cp;
}
} else {
path = url;
tok = url;
}
/*
* Parse the query string
*/
if ((cp = gstrchr(tok, '?')) != NULL) {
*cp++ = '\0';
query = cp;
path = tok;
tok = query;
}
/*
* Parse the fragment identifier
*/
if ((cp = gstrchr(tok, '#')) != NULL) {
*cp++ = '\0';
if (*query == 0) {
path = tok;
}
}
/*
* Only do the following if asked for the extension
*/
if (pext) {
if ((cp = gstrrchr(path, '.')) != NULL) {
if ((last_delim = gstrrchr(path, '/')) != NULL) {
if (last_delim > cp) {
ext = htmExt;
} else {
ext = cp;
}
} else {
ext = cp;
}
} else {
if (path[gstrlen(path) - 1] == '/') {
ext = htmExt;
}
}
}
/*
* Pass back the fields requested (if not NULL)
*/
if (phost)
*phost = host;
if (ppath)
*ppath = path;
if (pport)
*pport = port;
if (pproto)
*pproto = proto;
if (pquery)
*pquery = query;
if (ptag)
*ptag = tag;
if (pext)
*pext = ext;
*pbuf = buf;
return 0;
}
/******************************************************************************/

File diff suppressed because it is too large Load Diff

View File

@@ -1,147 +0,0 @@
/*
* base64.c -- Base64 Mime encoding
*
* Copyright (c) GoAhead Software Inc., 1995-2000. All Rights Reserved.
*
* See the file "license.txt" for usage and redistribution license requirements
*/
/******************************** Description *********************************/
/*
* The base64 command encodes and decodes a string in mime base64 format
*/
/********************************* Includes ***********************************/
#include "wsIntrn.h"
/******************************** Local Data **********************************/
/*
* Mapping of ANSI chars to base64 Mime encoding alphabet (see below)
*/
static char_t map64[] = {
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1,
-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,
-1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
};
static char_t alphabet64[] = {
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
'w', 'x', 'y', 'z', '0', '1', '2', '3',
'4', '5', '6', '7', '8', '9', '+', '/',
};
/*********************************** Code *************************************/
/*
* Decode a buffer from "string" and into "outbuf"
*/
int websDecode64(char_t *outbuf, char_t *string, int outlen)
{
unsigned long shiftbuf;
char_t *cp, *op;
int c, i, j, shift;
op = outbuf;
*op = '\0';
cp = string;
while (*cp && *cp != '=') {
/*
* Map 4 (6bit) input bytes and store in a single long (shiftbuf)
*/
shiftbuf = 0;
shift = 18;
for (i = 0; i < 4 && *cp && *cp != '='; i++, cp++) {
c = map64[*cp & 0xff];
if (c == -1) {
error(E_L, E_LOG, T("Bad string: %s at %c index %d"), string,
c, i);
return -1;
}
shiftbuf = shiftbuf | (c << shift);
shift -= 6;
}
/*
* Interpret as 3 normal 8 bit bytes (fill in reverse order).
* Check for potential buffer overflow before filling.
*/
--i;
if ((op + i) >= &outbuf[outlen]) {
gstrcpy(outbuf, T("String too big"));
return -1;
}
for (j = 0; j < i; j++) {
*op++ = (char_t) ((shiftbuf >> (8 * (2 - j))) & 0xff);
}
*op = '\0';
}
return 0;
}
/******************************************************************************/
/*
* Encode a buffer from "string" into "outbuf"
*/
void websEncode64(char_t *outbuf, char_t *string, int outlen)
{
unsigned long shiftbuf;
char_t *cp, *op;
int x, i, j, shift;
op = outbuf;
*op = '\0';
cp = string;
while (*cp) {
/*
* Take three characters and create a 24 bit number in shiftbuf
*/
shiftbuf = 0;
for (j = 2; j >= 0 && *cp; j--, cp++) {
shiftbuf |= ((*cp & 0xff) << (j * 8));
}
/*
* Now convert shiftbuf to 4 base64 letters. The i,j magic calculates
* how many letters need to be output.
*/
shift = 18;
for (i = ++j; i < 4 && op < &outbuf[outlen] ; i++) {
x = (shiftbuf >> shift) & 0x3f;
*op++ = alphabet64[(shiftbuf >> shift) & 0x3f];
shift -= 6;
}
/*
* Pad at the end with '='
*/
while (j-- > 0) {
*op++ = '=';
}
*op = '\0';
}
}
/******************************************************************************/

View File

@@ -1,186 +0,0 @@
/*
* webcomp -- Compile web pages into C source
*
* Copyright (c) GoAhead Software Inc., 1995-2000. All Rights Reserved.
*
* See the file "license.txt" for usage and redistribution license requirements
*/
/******************************** Description *********************************/
/*
* Usage: webcomp prefix filelist >webrom.c
*
* filelist is a file containing the pathnames of all web pages
* prefix is a path prefix to remove from all the web page pathnames
* webrom.c is the resulting C source file to compile and link.
*/
/********************************* Includes ***********************************/
#include "wsIntrn.h"
/**************************** Forward Declarations ****************************/
static int compile(char_t *fileList, char_t *prefix);
static void usage();
/*********************************** Code *************************************/
/*
* Main program for webpack test harness
*/
int gmain(int argc, char_t* argv[])
{
char_t *fileList, *prefix;
fileList = NULL;
if (argc != 3) {
usage();
}
prefix = argv[1];
fileList = argv[2];
if (compile(fileList, prefix) < 0) {
return -1;
}
return 0;
}
/******************************************************************************/
/*
* Output usage message
*/
static void usage()
{
fprintf(stderr, "usage: webcomp prefix filelist >output.c\n");
exit(2);
}
/******************************************************************************/
/*
* Compile the web pages
*/
static int compile(char_t *fileList, char_t *prefix)
{
gstat_t sbuf;
FILE *lp;
time_t now;
char_t file[FNAMESIZE];
char_t *cp, *sl;
char buf[512];
unsigned char *p;
int j, i, len, fd, nFile;
/*
* Open list of files
*/
if ((lp = fopen(fileList, "r")) == NULL) {
fprintf(stderr, "Can't open file list %s\n", fileList);
return -1;
}
time(&now);
fprintf(stdout, "/*\n * webrom.c -- Compiled Web Pages\n *\n");
fprintf(stdout, " * Compiled by GoAhead WebCompile: %s */\n\n",
gctime(&now));
fprintf(stdout, "#include \"wsIntrn.h\"\n\n");
fprintf(stdout, "#ifndef WEBS_PAGE_ROM\n");
fprintf(stdout, "websRomPageIndexType websRomPageIndex[] = {\n");
fprintf(stdout, " { 0, 0, 0 },\n};\n");
fprintf(stdout, "#else\n");
/*
* Open each input file and compile each web page
*/
nFile = 0;
while (fgets(file, sizeof(file), lp) != NULL) {
if ((p = strchr(file, '\n')) || (p = strchr(file, '\r'))) {
*p = '\0';
}
if (*file == '\0') {
continue;
}
if (gstat(file, &sbuf) == 0 && sbuf.st_mode & S_IFDIR) {
continue;
}
if ((fd = gopen(file, O_RDONLY | O_BINARY)) < 0) {
fprintf(stderr, "Can't open file %s\n", file);
return -1;
}
fprintf(stdout, "static const unsigned char page_%d[] = {\n", nFile);
while ((len = read(fd, buf, sizeof(buf))) > 0) {
p = buf;
for (i = 0; i < len; ) {
fprintf(stdout, " ");
for (j = 0; p < &buf[len] && j < 16; j++, p++) {
fprintf(stdout, "%3d,", *p);
}
i += j;
fprintf(stdout, "\n");
}
}
fprintf(stdout, " 0 };\n\n");
close(fd);
nFile++;
}
fclose(lp);
/*
* Now output the page index
*/
fprintf(stdout, "websRomPageIndexType websRomPageIndex[] = {\n");
if ((lp = fopen(fileList, "r")) == NULL) {
fprintf(stderr, "Can't open file list %s\n", fileList);
return -1;
}
nFile = 0;
while (fgets(file, sizeof(file), lp) != NULL) {
if ((p = strchr(file, '\n')) || (p = strchr(file, '\r'))) {
*p = '\0';
}
if (*file == '\0') {
continue;
}
/*
* Remove the prefix and add a leading "/" when we print the path
*/
if (strncmp(file, prefix, gstrlen(prefix)) == 0) {
cp = &file[gstrlen(prefix)];
} else {
cp = file;
}
while((sl = strchr(file, '\\')) != NULL) {
*sl = '/';
}
if (*cp == '/') {
cp++;
}
if (gstat(file, &sbuf) == 0 && sbuf.st_mode & S_IFDIR) {
fprintf(stdout, " { T(\"/%s\"), 0, 0 },\n", cp);
continue;
}
fprintf(stdout, " { T(\"/%s\"), page_%d, %d },\n", cp, nFile,
sbuf.st_size);
nFile++;
}
fclose(lp);
fprintf(stdout, " { 0, 0, 0 },\n");
fprintf(stdout, "};\n");
fprintf(stdout, "#endif /* WEBS_PAGE_ROM */\n");
fclose(lp);
fflush(stdout);
return 0;
}
/******************************************************************************/

View File

@@ -1,499 +0,0 @@
/*
* main.c -- Main program for the GoAhead WebServer (RTEMS version)
*
* Copyright (c) Go Ahead Software Inc., 1995-1999. All Rights Reserved.
*
* See the file "license.txt" for usage and redistribution license requirements
*
* $Id$
*/
/******************************** Description *********************************/
/*
* Main program for for the GoAhead WebServer. This is a demonstration
* main program to initialize and configure the web server.
*/
/********************************* Includes ***********************************/
#include "uemf.h"
#include "wsIntrn.h"
#include <signal.h>
#include <sys/time.h>
#include <pthread.h>
#include <rtems.h>
#include <rtems/error.h>
#ifdef WEBS_SSL_SUPPORT
#include "websSSL.h"
#endif
#ifdef USER_MANAGEMENT_SUPPORT
#include "um.h"
void formDefineUserMgmt(void);
#endif
/*********************************** Locals ***********************************/
/*
* Change configuration here
*/
extern const char *tftpServer;
/* static char_t *rootWeb = T("goahead"); * Root web directory */
static char_t *password = T(""); /* Security password */
static int port = 80; /* Server port */
static int retries = 5; /* Server port retries */
static int finished; /* Finished flag */
/*
* Structure to hold timer events
*/
typedef struct {
void (*routine)(long arg); /* Timer routine */
long arg; /* Argument to routine */
} websTimer_t;
/* The following holds the pointer to an allocated websTimer_t structure .
* Using this method only one timer can be active at a time, but
* for the WebServer, this should be OK.
*/
websTimer_t *tp;
/****************************** Forward Declarations **************************/
static int initWebs();
static int aspTest(int eid, webs_t wp, int argc, char_t **argv);
static void formTest(webs_t wp, char_t *path, char_t *query);
static int websHomePageHandler(webs_t wp, char_t *urlPrefix, char_t *webDir,
int arg, char_t* url, char_t* path, char_t* query);
static void timerProc(int signo);
#if B_STATS
static void printMemStats(int handle, char_t *fmt, ...);
static void memLeaks();
#endif
static timer_t timer_id;
static void rtems_httpd_daemon();
/*********************************** Code *************************************/
/*
* Main -- entry point from RTEMS
*/
int rtems_initialize_webserver()
{
rtems_status_code sc;
rtems_id tid;
int priority;
/***********************************************************************
* Default HTTPD priority.
**********************************************************************/
priority = 40;
sc = rtems_task_create(rtems_build_name('H', 'T', 'P', 'D'),
priority, 8*1024,
RTEMS_PREEMPT | RTEMS_NO_TIMESLICE | RTEMS_NO_ASR |
RTEMS_INTERRUPT_LEVEL(0),
RTEMS_NO_FLOATING_POINT | RTEMS_LOCAL,
&tid);
if (sc != RTEMS_SUCCESSFUL)
{
return(RTEMS_UNSATISFIED);
}
sc = rtems_task_start(tid, rtems_httpd_daemon, 0);
if (sc != RTEMS_SUCCESSFUL)
{
return(RTEMS_UNSATISFIED);
}
return(RTEMS_SUCCESSFUL);
}
static void
rtems_httpd_daemon()
{
/*
* Initialize the memory allocator. Allow use of malloc and start with a
* 10K heap.
*/
bopen(NULL, (10 * 1024), B_USE_MALLOC);
/*
* Initialize the web server
*/
if (initWebs() < 0) {
rtems_panic("Unable to initialize Web server !!\n");
}
#ifdef WEBS_SSL_SUPPORT
websSSLOpen();
#endif
/*
* Basic event loop. SocketReady returns true when a socket is ready for
* service. SocketSelect will block until an event occurs. SocketProcess
* will actually do the servicing.
*/
while (!finished) {
if (socketReady(-1) || socketSelect(-1, 2000)) {
socketProcess(-1);
}
/*websCgiCleanup();*/
emfSchedProcess();
}
#ifdef WEBS_SSL_SUPPORT
websSSLClose();
#endif
#ifdef USER_MANAGEMENT_SUPPORT
umClose();
#endif
/*
* Close the socket module, report memory leaks and close the memory allocator
*/
websCloseServer();
websDefaultClose();
socketClose();
symSubClose();
#if B_STATS
memLeaks();
#endif
bclose();
rtems_task_delete( RTEMS_SELF );
}
/******************************************************************************/
/*
* Initialize the web server.
*/
static int initWebs()
{
struct hostent* hp;
struct in_addr intaddr;
char host[128], webdir[128];
char_t wbuf[128];
/*
* Initialize the socket subsystem
*/
socketOpen();
/*
* Define the local Ip address, host name, default home page and the
* root web directory.
*/
if (gethostname(host, sizeof(host)) < 0) {
error(E_L, E_LOG, T("Can't get hostname"));
return -1;
}
/* intaddr.s_addr = (unsigned long) hostGetByName(host); */
if ((hp = gethostbyname(host)) == NULL) {
error(E_L, E_LOG, T("Can't get host address"));
return -1;
}
memcpy((char *) &intaddr, (char *) hp->h_addr_list[0],
(size_t) hp->h_length);
#if 0
/*
* Set /TFTP/x.y.z.w/goahead as the root web. Modify to suit your needs
*/
sprintf(webdir, "/TFTP/%s/%s", tftpServer, rootWeb);
#else
sprintf(webdir, "/");
#endif
/*
* Configure the web server options before opening the web server
*/
websSetDefaultDir(webdir);
ascToUni(wbuf, inet_ntoa(intaddr), sizeof(wbuf));
websSetIpaddr(wbuf);
ascToUni(wbuf, host, sizeof(wbuf));
websSetHost(wbuf);
/*
* Configure the web server options before opening the web server
*/
#if 0
websSetDefaultPage(T("default.asp"));
#else
websSetDefaultPage(T("index.html"));
#endif
websSetPassword(password);
/*
* Open the web server on the given port. If that port is taken, try
* the next sequential port for up to "retries" attempts.
*/
websOpenServer(port, retries);
/*
* First create the URL handlers. Note: handlers are called in sorted order
* with the longest path handler examined first. Here we define the security
* handler, forms handler and the default web page handler.
*/
websUrlHandlerDefine(T(""), NULL, 0, websSecurityHandler,
WEBS_HANDLER_FIRST);
websUrlHandlerDefine(T("/goform"), NULL, 0, websFormHandler, 0);
websUrlHandlerDefine(T(""), NULL, 0, websDefaultHandler,
WEBS_HANDLER_LAST);
/*
* Now define two test procedures. Replace these with your application
* relevant ASP script procedures and form functions.
*/
websAspDefine(T("aspTest"), aspTest);
websFormDefine(T("formTest"), formTest);
/*
* Create a handler for the default home page
*/
websUrlHandlerDefine(T("/"), NULL, 0, websHomePageHandler, 0);
return 0;
}
/******************************************************************************/
/*
* Test Javascript binding for ASP. This will be invoked when "aspTest" is
* embedded in an ASP page. See web/asp.asp for usage. Set browser to
* "localhost/asp.asp" to test.
*/
static int aspTest(int eid, webs_t wp, int argc, char_t **argv)
{
char_t *name, *address;
if (ejArgs(argc, argv, T("%s %s"), &name, &address) < 2) {
websError(wp, 400, T("Insufficient args\n"));
return -1;
}
return websWrite(wp, T("Name: %s, Address %s"), name, address);
}
/******************************************************************************/
/*
* Test form for posted data (in-memory CGI). This will be called when the
* form in web/asp.asp is invoked. Set browser to "localhost/asp.asp" to test.
*/
static void formTest(webs_t wp, char_t *path, char_t *query)
{
char_t *name, *address;
name = websGetVar(wp, T("name"), T("Joe Smith"));
address = websGetVar(wp, T("address"), T("1212 Milky Way Ave."));
websHeader(wp);
websWrite(wp, T("<body><h2>Name: %s, Address: %s</h2>\n"), name, address);
websFooter(wp);
websDone(wp, 200);
}
/******************************************************************************/
/*
* Create a timer to invoke the routine in "delay" milliseconds.
*/
void *emfCreateTimer(int delay, void (*routine)(long arg), long arg)
{
/* this variable is only used in the if'ed 0 section below */
#if 0
struct sigaction act;
#endif
struct itimerspec its = { {0,0}, {0,0} };
struct sigevent se;
int status;
if ((tp = balloc(B_L, sizeof(websTimer_t)))) {
tp->routine = routine;
tp->arg = arg;
}
else {
return NULL;
}
se.sigev_notify = SIGEV_THREAD;
se.sigev_value.sival_ptr = tp;
se.sigev_notify_function = (void (*)(union sigval)) timerProc;
/*
* NOT POSIX?
* se.sigev_notify_attributes = NULL;
*/
status = timer_create(CLOCK_REALTIME, &se, &timer_id);
if (status != 0) {
bfree(B_L, tp);
return NULL;
}
/* convert delay millisecs to secs and usecs required by struct */
its.it_value.tv_sec = delay / 1000;
its.it_value.tv_nsec = (delay % 1000) * 1000000;
status = timer_settime(timer_id, 0, &its, 0);
if (status != 0) {
bfree(B_L, tp);
return NULL;
}
#if 0
act.sa_flags = 0;
sigemptyset(&act.sa_mask);
act.sa_handler = timerProc;
sigaction(SIGALRM, &act, NULL);
/* convert delay millisecs to secs and usecs required by struct */
its.it_value.tv_sec = delay / 1000;
its.it_value.tv_usec = (delay % 1000) * 1000;
if (setitimer(ITIMER_REAL, &its, NULL) == -1) {
bfree(B_L, tp);
return NULL;
}
#endif
return tp;
}
/******************************************************************************/
/*
* Delete a timer
*/
void emfDeleteTimer(void * id)
{
websTimer_t *wtp;
/*struct itimerval its = { {0,0}, {0,0} };*/
wtp = (websTimer_t *)id;
/* setitimer(ITIMER_REAL, &its, NULL);*/
timer_delete(timer_id);
bfree(B_L, wtp);
}
/******************************************************************************/
/*
* Timer handler
*/
static void timerProc(int signo)
{
websTimer_t wtp = *tp;
/* Copy the timer structure to a local first and delete it before calling
* the function, since the function could create another timer. In this
* implementation, only one timer can be allocated at a time.
*/
bfree(B_L, tp);
(wtp.routine)(wtp.arg);
}
/******************************************************************************/
/*
* Home page handler
*/
static int websHomePageHandler(webs_t wp, char_t *urlPrefix, char_t *webDir,
int arg, char_t* url, char_t* path, char_t* query)
{
/*
* If the empty or "/" URL is invoked, redirect default URLs to the home page
*/
if (*url == '\0' || gstrcmp(url, T("/")) == 0) {
#if 0
websRedirect(wp, T("home.asp"));
#else
websRedirect(wp, T("index.html"));
#endif
return 1;
}
return 0;
}
/******************************************************************************/
#if B_STATS
static void memLeaks()
{
int fd=1;
/* if ((fd = gopen(T("leak.txt"), O_CREAT | O_TRUNC | O_WRONLY)) >= 0) { */
bstats(fd, printMemStats);
/*
close(fd);
}
*/
}
/******************************************************************************/
/*
* Print memory usage / leaks
*/
static void printMemStats(int handle, char_t *fmt, ...)
{
va_list args;
char_t buf[256];
va_start(args, fmt);
vsprintf(buf, fmt, args);
va_end(args);
write(handle, buf, strlen(buf));
}
#endif
/*****************************************************************************/
/*****************************************************************************/
/*
* Default error handler. The developer should insert code to handle
* error messages in the desired manner.
*/
void defaultErrorHandler(int etype, char_t *msg)
{
#if 1
write(1, msg, gstrlen(msg));
#endif
}
/*****************************************************************************/
/*
* Trace log. Customize this function to log trace output
*/
void defaultTraceHandler(int level, char_t *buf)
{
/*
* The following code would write all trace regardless of level
* to stdout.
*/
#if 1
if (buf) {
write(1, buf, gstrlen(buf));
}
#endif
}
/*****************************************************************************/
/*
* Returns a pointer to an allocated qualified unique temporary file name.
* This filename must eventually be deleted with bfree();
*/
char_t *websGetCgiCommName()
{
char_t *pname1, *pname2;
pname1 = tempnam(NULL, T("cgi"));
pname2 = bstrdup(B_L, pname1);
free(pname1);
return pname2;
}

View File

@@ -1,140 +0,0 @@
/*
* Page.c -- Support for page retrieval.
*
* Copyright (c) GoAhead Software Inc., 1995-2000. All Rights Reserved.
*
* See the file "license.txt" for usage and redistribution license requirements
*/
/******************************** Description *********************************/
/*
* This module provides page retrieval handling. It provides support for
* reading web pages from file systems and has expansion for ROMed web
* pages.
*/
/********************************* Includes ***********************************/
#include "wsIntrn.h"
/*********************************** Code *************************************/
/*
* Open a web page. lpath is the local filename. path is the URL path name.
*/
int websPageOpen(webs_t wp, char_t *lpath, char_t *path, int mode, int perm)
{
a_assert(websValid(wp));
#if WEBS_PAGE_ROM
return websRomPageOpen(wp, path, mode, perm);
#else
return (wp->docfd = gopen(lpath, mode, perm));
#endif /* WEBS_PAGE_ROM */
}
/******************************************************************************/
/*
* Close a web page
*/
void websPageClose(webs_t wp)
{
a_assert(websValid(wp));
#if WEBS_PAGE_ROM
websRomPageClose(wp->docfd);
#else
if (wp->docfd >= 0) {
close(wp->docfd);
wp->docfd = -1;
}
#endif
}
/******************************************************************************/
/*
* Stat a web page lpath is the local filename. path is the URL path name.
*/
int websPageStat(webs_t wp, char_t *lpath, char_t *path, websStatType* sbuf)
{
#if WEBS_PAGE_ROM
return websRomPageStat(path, sbuf);
#else
gstat_t s;
if (gstat(lpath, &s) < 0) {
return -1;
}
sbuf->size = s.st_size;
sbuf->mtime = s.st_mtime;
sbuf->isDir = s.st_mode & S_IFDIR;
return 0;
#endif
}
/******************************************************************************/
/*
* Is this file a directory?
*/
int websPageIsDirectory(char_t *lpath)
{
#if WEBS_PAGE_ROM
websStatType sbuf;
if (websRomPageStat(lpath, &sbuf) >= 0) {
return(sbuf.isDir);
} else {
return 0;
}
#else
gstat_t sbuf;
if (gstat(lpath, &sbuf) >= 0) {
return(sbuf.st_mode & S_IFDIR);
} else {
return 0;
}
#endif
}
/******************************************************************************/
/*
* Read a web page. Returns the number of _bytes_ read.
* len is the size of buf, in bytes.
*/
int websPageReadData(webs_t wp, char *buf, int nBytes)
{
#if WEBS_PAGE_ROM
a_assert(websValid(wp));
return websRomPageReadData(wp, buf, nBytes);
#else
a_assert(websValid(wp));
return read(wp->docfd, buf, nBytes);
#endif
}
/******************************************************************************/
/*
* Move file pointer offset bytes.
*/
void websPageSeek(webs_t wp, long offset)
{
a_assert(websValid(wp));
#if WEBS_PAGE_ROM
websRomPageSeek(wp, offset, SEEK_CUR);
#else
lseek(wp->docfd, offset, SEEK_CUR);
#endif
}
/******************************************************************************/

View File

@@ -1,13 +0,0 @@
/*
* webrom.c -- Compiled Web Pages
*
* Copyright (c) GoAhead Software Inc., 1995-2000. All Rights Reserved.
*
* See the file "license.txt" for usage and redistribution license requirements
*/
#include "wsIntrn.h"
websRomPageIndexType websRomPageIndex[] = {
{ 0, 0, 0 },
};

File diff suppressed because it is too large Load Diff

View File

@@ -1,229 +0,0 @@
/*
* webs.h -- GoAhead Web public header
*
* Copyright (c) GoAhead Software Inc., 1992-2000. All Rights Reserved.
*
* See the file "license.txt" for information on usage and redistribution
*/
#ifndef _h_WEBS
#define _h_WEBS 1
/******************************** Description *********************************/
/*
* GoAhead Web Server header. This defines the Web public APIs.
* Include this header for files that contain ASP or Form procedures.
* Include wsIntrn.h when creating URL handlers.
*/
/********************************* Includes ***********************************/
#include "ej.h"
#ifdef WEBS_SSL_SUPPORT
#include "websSSL.h"
#endif
/********************************** Defines ***********************************/
/*
* By license terms the server software name defined in the following line of
* code must not be modified.
*/
#define WEBS_NAME T("GoAhead-Webs")
#define WEBS_VERSION T("2.1")
#define WEBS_HEADER_BUFINC 512 /* Header buffer size */
#define WEBS_ASP_BUFINC 512 /* Asp expansion increment */
#define WEBS_MAX_PASS 32 /* Size of password */
#define WEBS_BUFSIZE 1000 /* websWrite max output string */
#define WEBS_MAX_HEADER (5 * 1024) /* Sanity check header */
#define WEBS_MAX_URL 4096 /* Maximum URL size for sanity */
#define WEBS_SOCKET_BUFSIZ 256 /* Bytes read from socket */
#define WEBS_HTTP_PORT T("httpPort")
#define CGI_BIN T("cgi-bin")
/*
* Request flags. Also returned by websGetRequestFlags().
*/
#define WEBS_LOCAL_PAGE 0x1 /* Request for local webs page */
#define WEBS_KEEP_ALIVE 0x2 /* HTTP/1.1 keep alive */
#define WEBS_DONT_USE_CACHE 0x4 /* Not implemented cache support */
#define WEBS_COOKIE 0x8 /* Cookie supplied in request */
#define WEBS_IF_MODIFIED 0x10 /* If-modified-since in request */
#define WEBS_POST_REQUEST 0x20 /* Post request operation */
#define WEBS_LOCAL_REQUEST 0x40 /* Request from this system */
#define WEBS_HOME_PAGE 0x80 /* Request for the home page */
#define WEBS_ASP 0x100 /* ASP request */
#define WEBS_HEAD_REQUEST 0x200 /* Head request */
#define WEBS_CLEN 0x400 /* Request had a content length */
#define WEBS_FORM 0x800 /* Request is a form */
#define WEBS_REQUEST_DONE 0x1000 /* Request complete */
#define WEBS_POST_DATA 0x2000 /* Already appended post data */
#define WEBS_CGI_REQUEST 0x4000 /* cgi-bin request */
#define WEBS_SECURE 0x8000 /* connection uses SSL */
#define WEBS_AUTH_BASIC 0x10000 /* Basic authentication request */
#define WEBS_AUTH_DIGEST 0x20000 /* Digest authentication request */
#define WEBS_HEADER_DONE 0x40000 /* Already output the HTTP header */
/*
* URL handler flags
*/
#define WEBS_HANDLER_FIRST 0x1 /* Process this handler first */
#define WEBS_HANDLER_LAST 0x2 /* Process this handler last */
/*
* Per socket connection webs structure
*/
typedef struct websRec {
ringq_t header; /* Header dynamic string */
time_t since; /* Parsed if-modified-since time */
sym_fd_t cgiVars; /* CGI standard variables */
sym_fd_t cgiQuery; /* CGI decoded query string */
time_t timestamp; /* Last transaction with browser */
int timeout; /* Timeout handle */
char_t ipaddr[32]; /* Connecting ipaddress */
char_t type[64]; /* Mime type */
char_t *dir; /* Directory containing the page */
char_t *path; /* Path name without query */
char_t *url; /* Full request url */
char_t *host; /* Requested host */
char_t *lpath; /* Cache local path name */
char_t *query; /* Request query */
char_t *decodedQuery; /* Decoded request query */
char_t *authType; /* Authorization type (Basic/DAA) */
char_t *password; /* Authorization password */
char_t *userName; /* Authorization username */
char_t *cookie; /* Cookie string */
char_t *userAgent; /* User agent (browser) */
char_t *protocol; /* Protocol (normally HTTP) */
char_t *protoVersion; /* Protocol version */
int sid; /* Socket id (handler) */
int listenSid; /* Listen Socket id */
int port; /* Request port number */
int state; /* Current state */
int flags; /* Current flags -- see above */
int code; /* Request result code */
int clen; /* Content length */
int wid; /* Index into webs */
char_t *cgiStdin; /* filename for CGI stdin */
int docfd; /* Document file descriptor */
int numbytes; /* Bytes to transfer to browser */
int written; /* Bytes actually transferred */
void (*writeSocket)(struct websRec *wp);
#ifdef DIGEST_ACCESS_SUPPORT
char_t *realm; /* usually the same as "host" from websRec */
char_t *nonce; /* opaque-to-client string sent by server */
char_t *digest; /* digest form of user password */
char_t *uri; /* URI found in DAA header */
char_t *opaque; /* opaque value passed from server */
char_t *nc; /* nonce count */
char_t *cnonce; /* check nonce */
char_t *qop; /* quality operator */
#endif
#ifdef WEBS_SSL_SUPPORT
websSSL_t *wsp; /* SSL data structure */
#endif
} websRec;
typedef websRec *webs_t;
typedef websRec websType;
/******************************** Prototypes **********************************/
extern int websAccept(int sid, char *ipaddr, int port, int listenSid);
extern int websAspDefine(char_t *name,
int (*fn)(int ejid, webs_t wp, int argc, char_t **argv));
extern int websAspRequest(webs_t wp, char_t *lpath);
extern void websCloseListen();
extern int websDecode64(char_t *outbuf, char_t *string, int buflen);
extern void websDecodeUrl(char_t *token, char_t *decoded, int len);
extern void websDone(webs_t wp, int code);
extern void websEncode64(char_t *outbuf, char_t *string, int buflen);
extern void websError(webs_t wp, int code, char_t *msg, ...);
extern void websFooter(webs_t wp);
extern int websFormDefine(char_t *name, void (*fn)(webs_t wp,
char_t *path, char_t *query));
extern char_t *websGetDefaultDir();
extern char_t *websGetDefaultPage();
extern char_t *websGetHostUrl();
extern char_t *websGetIpaddrUrl();
extern char_t *websGetPassword();
extern int websGetPort();
extern char_t *websGetPublishDir(char_t *path, char_t **urlPrefix);
extern char_t *websGetRealm();
extern int websGetRequestBytes(webs_t wp);
extern char_t *websGetRequestDir(webs_t wp);
extern int websGetRequestFlags(webs_t wp);
extern char_t *websGetRequestIpaddr(webs_t wp);
extern char_t *websGetRequestLpath(webs_t wp);
extern char_t *websGetRequestPath(webs_t wp);
extern char_t *websGetRequestPassword(webs_t wp);
extern char_t *websGetRequestType(webs_t wp);
extern int websGetRequestWritten(webs_t wp);
extern char_t *websGetVar(webs_t wp, char_t *var, char_t *def);
extern int websCompareVar(webs_t wp, char_t *var, char_t *value);
extern void websHeader(webs_t wp);
extern int websOpenListen(int port, int retries);
extern int websPageOpen(webs_t wp, char_t *lpath, char_t *path,
int mode, int perm);
extern void websPageClose(webs_t wp);
extern int websPublish(char_t *urlPrefix, char_t *path);
extern void websRedirect(webs_t wp, char_t *url);
extern void websSecurityDelete();
extern int websSecurityHandler(webs_t wp, char_t *urlPrefix,
char_t *webDir, int arg, char_t *url, char_t *path,
char_t *query);
extern void websSetDefaultDir(char_t *dir);
extern void websSetDefaultPage(char_t *page);
extern void websSetEnv(webs_t wp);
extern void websSetHost(char_t *host);
extern void websSetIpaddr(char_t *ipaddr);
extern void websSetPassword(char_t *password);
extern void websSetRealm(char_t *realmName);
extern void websSetRequestBytes(webs_t wp, int bytes);
extern void websSetRequestFlags(webs_t wp, int flags);
extern void websSetRequestLpath(webs_t wp, char_t *lpath);
extern void websSetRequestPath(webs_t wp, char_t *dir, char_t *path);
extern char_t *websGetRequestUserName(webs_t wp);
extern void websSetRequestWritten(webs_t wp, int written);
extern void websSetVar(webs_t wp, char_t *var, char_t *value);
extern int websTestVar(webs_t wp, char_t *var);
extern void websTimeoutCancel(webs_t wp);
extern int websUrlHandlerDefine(char_t *urlPrefix, char_t *webDir,
int arg, int (*fn)(webs_t wp, char_t *urlPrefix,
char_t *webDir, int arg, char_t *url, char_t *path,
char_t *query), int flags);
extern int websUrlHandlerDelete(int (*fn)(webs_t wp, char_t *urlPrefix,
char_t *webDir, int arg, char_t *url, char_t *path,
char_t *query));
extern int websUrlHandlerRequest(webs_t wp);
extern int websUrlParse(char_t *url, char_t **buf, char_t **host,
char_t **path, char_t **port, char_t **query,
char_t **proto, char_t **tag, char_t **ext);
extern char_t *websUrlType(char_t *webs, char_t *buf, int charCnt);
extern int websWrite(webs_t wp, char_t* fmt, ...);
extern int websWriteBlock(webs_t wp, char_t *buf, int nChars);
extern int websWriteDataNonBlock(webs_t wp, char *buf, int nChars);
extern int websValid(webs_t wp);
extern int websValidateUrl(webs_t wp, char_t *path);
extern void websMarkTime(webs_t wp);
/*
* The following prototypes are used by the SSL patch found in websSSL.c
*/
extern int websAlloc(int sid);
extern void websFree(webs_t wp);
extern void websTimeout(void *arg, int id);
extern void websReadEvent(webs_t wp);
/*
* Prototypes for functions available when running as part of the
* GoAhead Embedded Management Framework (EMF)
*/
#if EMF
extern void websFormExplain(webs_t wp, char_t *path, char_t *query);
#endif
#endif /* _h_WEBS */
/******************************************************************************/

View File

@@ -1,210 +0,0 @@
/*
* websuemf.c -- GoAhead Micro Embedded Management Framework
*
* Copyright (c) GoAhead Software Inc., 1995-2000. All Rights Reserved.
*
* See the file "license.txt" for usage and redistribution license requirements
*/
/********************************** Description *******************************/
/*
* This modules provides compatibility with the full GoAhead EMF.
*/
/*********************************** Includes *********************************/
#include "ejIntrn.h"
#include "wsIntrn.h"
/*********************************** Defines **********************************/
/*
* This structure stores scheduled events.
*/
typedef struct {
void (*routine)(void *arg, int id);
void *arg;
time_t at;
int schedid;
} sched_t;
/*********************************** Locals ***********************************/
static sched_t **sched;
static int schedMax;
/************************************* Code ***********************************/
/*
* Evaluate a script
*/
int scriptEval(int engine, char_t *cmd, char_t **result, int chan)
{
int ejid;
if (engine == EMF_SCRIPT_EJSCRIPT) {
ejid = (int) chan;
if (ejEval(ejid, cmd, NULL) ) {
return 0;
} else {
return -1;
}
}
return -1;
}
/******************************************************************************/
/*
* Compare strings, ignoring case: normal strcmp return codes.
*
* WARNING: It is not good form to increment or decrement pointers inside a
* "call" to tolower et al. These can be MACROS, and have undesired side
* effects.
*/
int strcmpci(char_t *s1, char_t *s2)
{
int rc;
a_assert(s1 && s2);
if (s1 == NULL || s2 == NULL) {
return 0;
}
if (s1 == s2) {
return 0;
}
do {
rc = gtolower(*s1) - gtolower(*s2);
if (*s1 == '\0') {
break;
}
s1++;
s2++;
} while (rc == 0);
return rc;
}
/******************************************************************************/
/*
* This function is called when a scheduled process time has come.
*/
void TimerProc(int schedid)
{
sched_t *s;
a_assert(0 <= schedid && schedid < schedMax);
s = sched[schedid];
a_assert(s);
(s->routine)(s->arg, s->schedid);
}
/******************************************************************************/
/*
* Schedule an event in delay milliseconds time. We will use 1 second
* granularity for webServer.
*/
int emfSchedCallback(int delay, emfSchedProc *proc, void *arg)
{
sched_t *s;
int schedid;
if ((schedid = hAllocEntry((void***) &sched, &schedMax,
sizeof(sched_t))) < 0) {
return -1;
}
s = sched[schedid];
s->routine = proc;
s->arg = arg;
s->schedid = schedid;
/*
* Round the delay up to seconds.
*/
s->at = ((delay + 500) / 1000) + time(0);
return schedid;
}
/******************************************************************************/
/*
* Reschedule to a new delay.
*/
void emfReschedCallback(int schedid, int delay)
{
sched_t *s;
if (sched == NULL || schedid == -1 || schedid >= schedMax ||
(s = sched[schedid]) == NULL) {
return;
}
s->at = ((delay + 500) / 1000) + time(0);
}
/******************************************************************************/
void emfUnschedCallback(int schedid)
{
sched_t *s;
if (sched == NULL || schedid == -1 || schedid >= schedMax ||
(s = sched[schedid]) == NULL) {
return;
}
bfree(B_L, s);
schedMax = hFree((void***) &sched, schedid);
}
/******************************************************************************/
/*
* Take the tasks off the queue in a round robin fashion.
*/
void emfSchedProcess()
{
sched_t *s;
int schedid;
static int next = 0;
/*
* If schedMax is 0, there are no tasks scheduled, so just return.
*/
if (schedMax <= 0) {
return;
}
/*
* If next >= schedMax, the schedule queue was reduced in our absence
* so reset next to 0 to start from the begining of the queue again.
*/
if (next >= schedMax) {
next = 0;
}
schedid = next;
for (;;) {
if ((s = sched[schedid]) != NULL && (int)s->at <= (int)time(0)) {
TimerProc(schedid);
next = schedid + 1;
return;
}
if (++schedid >= schedMax) {
schedid = 0;
}
if (schedid == next) {
/*
* We've gone all the way through the queue without finding
* anything to do so just return.
*/
return;
}
}
}
/******************************************************************************/

View File

@@ -1,301 +0,0 @@
/*
* wsIntrn.h -- Internal GoAhead Web server header
*
* Copyright (c) GoAhead Software Inc., 1992-2000. All Rights Reserved.
*
* See the file "license.txt" for information on usage and redistribution
*/
#ifndef _h_WEBS_INTERNAL
#define _h_WEBS_INTERNAL 1
/******************************** Description *********************************/
/*
* Internal GoAhead Web Server header. This defines the Web private APIs
* Include this header when you want to create URL handlers.
*/
/*********************************** Defines **********************************/
/*
* Define this to enable login of web accesses to a file
* #define WEBS_LOG_SUPPORT 1
*
* Define this to enable HTTP/1.1 keep alive support
* #define WEBS_KEEP_ALIVE_SUPPORT 1
*
* Define this to enable if-modified-since support
* #define WEBS_IF_MODIFIED_SUPPORT 1
*
* Define this to support proxy capability and track local vs remote request
* Note: this is not yet fully implemented.
* #define WEBS_PROXY_SUPPORT 1
*
* Define this to support reading pages from ROM
* #define WEBS_PAGE_ROM 1
*
* Define this to enable memory allocation and stack usage tracking
* #define B_STATS 1
*/
/********************************** Includes **********************************/
#include <ctype.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#if WIN
#include <fcntl.h>
#include <sys/stat.h>
#include <io.h>
#endif
#if CE
#if ! UEMF
#include <io.h>
#endif
#endif
#if NW
#include <fcntl.h>
#include <sys/stat.h>
#endif
#if SCOV5
#include <fcntl.h>
#include <sys/stat.h>
#include <signal.h>
#include <unistd.h>
#endif
#if LYNX
#include <fcntl.h>
#include <sys/stat.h>
#include <signal.h>
#include <unistd.h>
#endif
#if UNIX
#include <fcntl.h>
#include <sys/stat.h>
#include <signal.h>
#include <unistd.h>
#endif
#if QNX4
#include <fcntl.h>
#include <sys/stat.h>
#include <signal.h>
#include <unistd.h>
#include <unix.h>
#endif
#if UW
#include <fcntl.h>
#include <sys/stat.h>
#endif
#if VXWORKS
#include <vxWorks.h>
#include <fcntl.h>
#include <sys/stat.h>
#endif
#if SOLARIS
#include <macros.h>
#include <fcntl.h>
#include <sys/stat.h>
#endif
#if UEMF
#include "uemf.h"
#include "ejIntrn.h"
#else
#include "emf/emfInternal.h"
#include "ej/ejIntrn.h"
#endif
#include "webs.h"
/********************************** Defines ***********************************/
/*
* Read handler flags and state
*/
#define WEBS_BEGIN 0x1 /* Beginning state */
#define WEBS_HEADER 0x2 /* Ready to read first line */
#define WEBS_POST 0x4 /* POST without content */
#define WEBS_POST_CLEN 0x8 /* Ready to read content for POST */
#define WEBS_PROCESSING 0x10 /* Processing request */
#define WEBS_KEEP_TIMEOUT 15000 /* Keep-alive timeout (15 secs) */
#define WEBS_TIMEOUT 60000 /* General request timeout (60) */
#define PAGE_READ_BUFSIZE 512 /* bytes read from page files */
#define MAX_PORT_LEN 10 /* max digits in port number */
#define WEBS_SYM_INIT 64 /* initial # of sym table entries */
#define WEBS_VERSION_STR T("2.1.3") /* version of web server s/w */
/*
* URL handler structure. Stores the leading URL path and the handler
* function to call when the URL path is seen.
*/
typedef struct {
int (*handler)(webs_t wp, char_t *urlPrefix, char_t *webDir, int arg,
char_t *url, char_t *path,
char_t *query); /* Callback URL handler function */
char_t *webDir; /* Web directory if required */
char_t *urlPrefix; /* URL leading prefix */
int len; /* Length of urlPrefix for speed */
int arg; /* Argument to provide to handler */
int flags; /* Flags */
} websUrlHandlerType;
/*
* Webs statistics
*/
typedef struct {
long errors; /* General errors */
long redirects;
long net_requests;
long activeNetRequests;
long activeBrowserRequests;
long timeouts;
long access; /* Access violations */
long localHits;
long remoteHits;
long formHits;
long cgiHits;
long handlerHits;
} websStatsType;
extern websStatsType websStats; /* Web access stats */
/*
* Error code list
*/
typedef struct {
int code; /* HTTP error code */
char_t *msg; /* HTTP error message */
} websErrorType;
/*
* Mime type list
*/
typedef struct {
char_t *type; /* Mime type */
char_t *ext; /* File extension */
} websMimeType;
/*
* File information structure.
*/
typedef struct {
unsigned long size; /* File length */
int isDir; /* Set if directory */
time_t mtime; /* Modified time */
} websStatType;
/*
* Compiled Rom Page Index
*/
typedef struct {
char_t *path; /* Web page URL path */
const unsigned char *page; /* Web page data */
int size; /* Size of web page in bytes */
int pos; /* Current read position */
} websRomPageIndexType;
/*
* Defines for file open.
*/
#ifndef CE
#define SOCKET_RDONLY O_RDONLY
#define SOCKET_BINARY O_BINARY
#else /* CE */
#define SOCKET_RDONLY 0x1
#define SOCKET_BINARY 0x2
#endif /* CE */
extern websRomPageIndexType websRomPageIndex[];
extern websMimeType websMimeList[]; /* List of mime types */
extern sym_fd_t websMime; /* Set of mime types */
extern webs_t* webs; /* Session list head */
extern int websMax; /* List size */
extern char_t websHost[64]; /* Name of this host */
extern char_t websIpaddr[64]; /* IP address of this host */
extern char_t *websHostUrl; /* URL for this host */
extern char_t *websIpaddrUrl; /* URL for this host */
extern int websPort; /* Port number */
/******************************** Prototypes **********************************/
extern int websAspOpen();
extern void websAspClose();
extern void websFormOpen();
extern void websFormClose();
extern int websAspWrite(int ejid, webs_t wp, int argc, char_t **argv);
extern void websDefaultClose();
extern int websDefaultHandler(webs_t wp, char_t *urlPrefix,
char_t *webDir, int arg, char_t *url, char_t *path,
char_t *query);
extern int websFormHandler(webs_t wp, char_t *urlPrefix, char_t *webDir,
int arg, char_t *url, char_t *path, char_t *query);
extern int websCgiHandler(webs_t wp, char_t *urlPrefix, char_t *webDir,
int arg, char_t *url, char_t *path, char_t *query);
extern void websCgiCleanup();
extern int websCheckCgiProc(int handle);
extern char_t *websGetCgiCommName();
extern int websLaunchCgiProc(char_t *cgiPath, char_t **argp,
char_t **envp, char_t *stdIn, char_t *stdOut);
extern int websOpen(int sid);
extern void websResponse(webs_t wp, int code, char_t *msg,
char_t *redirect);
extern int websJavaScriptEval(webs_t wp, char_t *script);
extern int websPageReadData(webs_t wp, char *buf, int nBytes);
extern int websPageOpen(webs_t wp, char_t *lpath, char_t *path, int mode,
int perm);
extern void websPageClose(webs_t wp);
extern void websPageSeek(webs_t wp, long offset);
extern int websPageStat(webs_t wp, char_t *lpath, char_t *path,
websStatType *sbuf);
extern int websPageIsDirectory(char_t *lpath);
extern int websRomOpen();
extern void websRomClose();
extern int websRomPageOpen(webs_t wp, char_t *path, int mode, int perm);
extern void websRomPageClose(int fd);
extern int websRomPageReadData(webs_t wp, char *buf, int len);
extern int websRomPageStat(char_t *path, websStatType *sbuf);
extern long websRomPageSeek(webs_t wp, long offset, int origin);
extern void websSetRequestSocketHandler(webs_t wp, int mask,
void (*fn)(webs_t wp));
extern int websSolutionHandler(webs_t wp, char_t *urlPrefix,
char_t *webDir, int arg, char_t *url, char_t *path,
char_t *query);
extern void websUrlHandlerClose();
extern int websUrlHandlerOpen();
extern int websOpenServer(int port, int retries);
extern void websCloseServer();
extern char_t* websGetDateString(websStatType* sbuf);
extern int strcmpci(char_t* s1, char_t* s2);
/*
* Prototypes for functions available when running as part of the
* GoAhead Embedded Management Framework (EMF)
*/
#if EMF
extern int websEmfOpen();
extern void websEmfClose();
extern void websSetEmfEnvironment(webs_t wp);
#endif
#if CE
extern int writeUniToAsc(int fid, void *buf, unsigned int len);
extern int readAscToUni(int fid, void **buf, unsigned int len);
#endif
#endif /* _h_WEBS_INTERNAL */
/******************************************************************************/

View File

@@ -1,276 +0,0 @@
/* $NetBSD: in_cksum_arm.c,v 1.3 2001/12/08 21:18:50 chris Exp $ */
/*
* ARM version:
*
* Copyright (c) 1997 Mark Brinicome
* Copyright (c) 1997 Causality Limited
*
* Based on the sparc version.
*/
/*
* Sparc version:
*
* Copyright (c) 1995 Zubin Dittia.
* Copyright (c) 1995 Matthew R. Green.
* Copyright (c) 1994 Charles M. Hannum.
* Copyright (c) 1992, 1993
* The 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.
*
* @(#)in_cksum.c 8.1 (Berkeley) 6/11/93
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/mbuf.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <netinet/ip_var.h>
/*
* Checksum routine for Internet Protocol family headers.
*
* This routine is very heavily used in the network
* code and should be modified for each CPU to be as fast as possible.
*
* ARM version.
*/
#define ADD64 __asm __volatile(" \n\
ldmia %0!, {%2, %3, %4, %5} \n\
adds %1,%7,%2; adcs %1,%1,%3 \n\
adcs %1,%1,%4; adcs %1,%1,%5 \n\
ldmia %0!, {%2, %3, %4, %5} \n\
adcs %1,%1,%2; adcs %1,%1,%3 \n\
adcs %1,%1,%4; adcs %1,%1,%5 \n\
ldmia %0!, {%2, %3, %4, %5} \n\
adcs %1,%1,%2; adcs %1,%1,%3 \n\
adcs %1,%1,%4; adcs %1,%1,%5 \n\
ldmia %0!, {%2, %3, %4, %5} \n\
adcs %1,%1,%2; adcs %1,%1,%3 \n\
adcs %1,%1,%4; adcs %1,%1,%5 \n\
adcs %1,%1,#0\n" \
: "=r" (w), "=r" (sum), "=&r" (tmp1), "=&r" (tmp2), "=&r" (tmp3), "=&r" (tmp4) \
: "0" (w), "r" (sum) \
: "cc")
#define ADD32 __asm __volatile(" \n\
ldmia %0!, {%2, %3, %4, %5} \n\
adds %1,%7,%2; adcs %1,%1,%3 \n\
adcs %1,%1,%4; adcs %1,%1,%5 \n\
ldmia %0!, {%2, %3, %4, %5} \n\
adcs %1,%1,%2; adcs %1,%1,%3 \n\
adcs %1,%1,%4; adcs %1,%1,%5 \n\
adcs %1,%1,#0\n" \
: "=r" (w), "=r" (sum), "=&r" (tmp1), "=&r" (tmp2), "=&r" (tmp3), "=&r" (tmp4) \
: "0" (w), "r" (sum) \
: "cc")
#define ADD16 __asm __volatile(" \n\
ldmia %0!, {%2, %3, %4, %5} \n\
adds %1,%7,%2; adcs %1,%1,%3 \n\
adcs %1,%1,%4; adcs %1,%1,%5 \n\
adcs %1,%1,#0\n" \
: "=r" (w), "=r" (sum), "=&r" (tmp1), "=&r" (tmp2), "=&r" (tmp3), "=&r" (tmp4) \
: "0" (w), "r" (sum) \
: "cc")
#define ADD8 __asm __volatile(" \n\
ldmia %0!, {%2, %3} \n\
adds %1,%5,%2; adcs %1,%1,%3 \n\
adcs %1,%1,#0\n" \
: "=r" (w), "=r" (sum), "=&r" (tmp1), "=&r" (tmp2) \
: "0" (w), "r" (sum) \
: "cc" )
#define ADD4 __asm __volatile(" \n\
ldr %2,[%0],#4 \n\
adds %1,%4,%2 \n\
adcs %1,%1,#0\n" \
: "=r" (w), "=r" (sum), "=&r" (tmp1) \
: "0" (w), "r" (sum) \
: "cc")
/*#define REDUCE {sum = (sum & 0xffff) + (sum >> 16);}*/
#define REDUCE __asm __volatile(" \n\
mov %2, #0x00ff \n\
orr %2, %2, #0xff00 \n\
and %2, %0, %2 \n\
add %0, %2, %0, lsr #16\n" \
: "=r" (sum) \
: "0" (sum), "r" (tmp1))
#define ADDCARRY {if (sum > 0xffff) sum -= 0xffff;}
#define ROL {sum = sum << 8;} /* depends on recent REDUCE */
#define ADDBYTE {ROL; sum += (*w << 8); byte_swapped ^= 1;}
#define ADDSHORT {sum += *(u_short *)w;}
#define ADVANCE(n) {w += n; mlen -= n;}
#define ADVANCEML(n) {mlen -= n;}
static __inline__ int
in_cksum_internal(struct mbuf *m, int off, int len, u_int sum)
{
u_char *w;
int mlen = 0;
int byte_swapped = 0;
/*
* Declare four temporary registers for use by the asm code. We
* allow the compiler to pick which specific machine registers to
* use, instead of hard-coding this in the asm code above.
*/
register u_int tmp1=0, tmp2, tmp3, tmp4;
for (; m && len; m = m->m_next) {
if (m->m_len == 0)
continue;
w = mtod(m, u_char *) + off;
mlen = m->m_len - off;
off = 0;
if (len < mlen)
mlen = len;
len -= mlen;
/*
* Ensure that we're aligned on a word boundary here so
* that we can do 32 bit operations below.
*/
if ((3 & (long)w) != 0) {
REDUCE;
if ((1 & (long)w) != 0 && mlen >= 1) {
ADDBYTE;
ADVANCE(1);
}
if ((2 & (long)w) != 0 && mlen >= 2) {
ADDSHORT;
ADVANCE(2);
}
}
/*
* Do as many 32 bit operations as possible using the
* 64/32/16/8/4 macro's above, using as many as possible of
* these.
*/
while (mlen >= 64) {
ADD64;
ADVANCEML(64);
}
if (mlen >= 32) {
ADD32;
ADVANCEML(32);
}
if (mlen >= 16) {
ADD16;
ADVANCEML(16);
}
if (mlen >= 8) {
ADD8;
ADVANCEML(8);
}
if (mlen >= 4) {
ADD4;
ADVANCEML(4)
}
if (mlen == 0)
continue;
REDUCE;
if (mlen >= 2) {
ADDSHORT;
ADVANCE(2);
}
if (mlen == 1) {
ADDBYTE;
}
}
if (byte_swapped) {
REDUCE;
ROL;
}
REDUCE;
ADDCARRY;
return (0xffff ^ sum);
}
int
in_cksum(m, len)
struct mbuf *m;
int len;
{
int cksum;
cksum =in_cksum_internal(m, 0, len, 0);
return cksum;
}
int
in4_cksum(m, nxt, off, len)
struct mbuf *m;
u_int8_t nxt;
int off, len;
{
u_int sum = 0;
if (nxt != 0) {
/* for ADD macros */
register u_int tmp1, tmp2, tmp3, tmp4;
u_char *w;
struct ipovly ipov;
/* pseudo header */
if (off < sizeof(struct ipovly))
panic("in4_cksum: offset too short");
if (m->m_len < sizeof(struct ip))
panic("in4_cksum: bad mbuf chain");
bzero(&ipov, sizeof(ipov));
ipov.ih_len = htons(len);
ipov.ih_pr = nxt;
ipov.ih_src = mtod(m, struct ip *)->ip_src;
ipov.ih_dst = mtod(m, struct ip *)->ip_dst;
w = (u_char *)&ipov;
/* assumes sizeof(ipov) == 20 */
ADD16;
ADD4;
}
/* skip unnecessary part */
while (m && off > 0) {
if (m->m_len > off)
break;
off -= m->m_len;
m = m->m_next;
}
return (in_cksum_internal(m, off, len, sum));
}

View File

@@ -1,204 +0,0 @@
/*
* Checksum routine for Internet Protocol family headers.
*
* This routine is very heavily used in the network
* code and should be modified for each CPU to be as fast as possible.
*
* This implementation is 386 version.
*
* $Id$
*/
#include <stdio.h> /* for puts */
#undef ADDCARRY
#define ADDCARRY(x) if ((x) > 0xffff) (x) -= 0xffff
#define REDUCE {sum = (sum & 0xffff) + (sum >> 16); ADDCARRY(sum);}
/*
* Thanks to gcc we don't have to guess
* which registers contain sum & w.
*/
#define ADD(n) __asm__ volatile \
("addl " #n "(%2), %0" : "=r" (sum) : "0" (sum), "r" (w))
#define ADDC(n) __asm__ volatile \
("adcl " #n "(%2), %0" : "=r" (sum) : "0" (sum), "r" (w))
#define LOAD(n) __asm__ volatile \
("movb " #n "(%1), %0" : "=r" (junk) : "r" (w))
#define MOP __asm__ volatile \
("adcl $0, %0" : "=r" (sum) : "0" (sum))
int
in_cksum(m, len)
register struct mbuf *m;
register int len;
{
register u_short *w;
register unsigned sum = 0;
register int mlen = 0;
int byte_swapped = 0;
union { char c[2]; u_short s; } su;
for (;m && len; m = m->m_next) {
if (m->m_len == 0)
continue;
w = mtod(m, u_short *);
if (mlen == -1) {
/*
* The first byte of this mbuf is the continuation
* of a word spanning between this mbuf and the
* last mbuf.
*/
/* su.c[0] is already saved when scanning previous
* mbuf. sum was REDUCEd when we found mlen == -1
*/
su.c[1] = *(u_char *)w;
sum += su.s;
w = (u_short *)((char *)w + 1);
mlen = m->m_len - 1;
len--;
} else
mlen = m->m_len;
if (len < mlen)
mlen = len;
len -= mlen;
/*
* Force to long boundary so we do longword aligned
* memory operations
*/
if (3 & (int) w) {
REDUCE;
if ((1 & (int) w) && (mlen > 0)) {
sum <<= 8;
su.c[0] = *(char *)w;
w = (u_short *)((char *)w + 1);
mlen--;
byte_swapped = 1;
}
if ((2 & (int) w) && (mlen >= 2)) {
sum += *w++;
mlen -= 2;
}
}
/*
* Advance to a 486 cache line boundary.
*/
if (4 & (int) w && mlen >= 4) {
ADD(0);
MOP;
w += 2;
mlen -= 4;
}
if (8 & (int) w && mlen >= 8) {
ADD(0);
ADDC(4);
MOP;
w += 4;
mlen -= 8;
}
/*
* Do as much of the checksum as possible 32 bits at at time.
* In fact, this loop is unrolled to make overhead from
* branches &c small.
*/
mlen -= 1;
while ((mlen -= 32) >= 0) {
u_char junk;
/*
* Add with carry 16 words and fold in the last
* carry by adding a 0 with carry.
*
* The early ADD(16) and the LOAD(32) are to load
* the next 2 cache lines in advance on 486's. The
* 486 has a penalty of 2 clock cycles for loading
* a cache line, plus whatever time the external
* memory takes to load the first word(s) addressed.
* These penalties are unavoidable. Subsequent
* accesses to a cache line being loaded (and to
* other external memory?) are delayed until the
* whole load finishes. These penalties are mostly
* avoided by not accessing external memory for
* 8 cycles after the ADD(16) and 12 cycles after
* the LOAD(32). The loop terminates when mlen
* is initially 33 (not 32) to guaranteed that
* the LOAD(32) is within bounds.
*/
ADD(16);
ADDC(0);
ADDC(4);
ADDC(8);
ADDC(12);
LOAD(32);
ADDC(20);
ADDC(24);
ADDC(28);
MOP;
w += 16;
}
mlen += 32 + 1;
if (mlen >= 32) {
ADD(16);
ADDC(0);
ADDC(4);
ADDC(8);
ADDC(12);
ADDC(20);
ADDC(24);
ADDC(28);
MOP;
w += 16;
mlen -= 32;
}
if (mlen >= 16) {
ADD(0);
ADDC(4);
ADDC(8);
ADDC(12);
MOP;
w += 8;
mlen -= 16;
}
if (mlen >= 8) {
ADD(0);
ADDC(4);
MOP;
w += 4;
mlen -= 8;
}
if (mlen == 0 && byte_swapped == 0)
continue; /* worth 1% maybe ?? */
REDUCE;
while ((mlen -= 2) >= 0) {
sum += *w++;
}
if (byte_swapped) {
sum <<= 8;
byte_swapped = 0;
if (mlen == -1) {
su.c[1] = *(char *)w;
sum += su.s;
mlen = 0;
} else
mlen = -1;
} else if (mlen == -1)
/*
* This mbuf has odd number of bytes.
* There could be a word split betwen
* this mbuf and the next mbuf.
* Save the last byte (to prepend to next mbuf).
*/
su.c[0] = *(char *)w;
}
if (len)
puts("cksum: out of data");
if (mlen == -1) {
/* The last mbuf has odd # of bytes. Follow the
standard (the odd byte is shifted left by 8 bits) */
su.c[1] = 0;
sum += su.s;
}
REDUCE;
return (~sum & 0xffff);
}

View File

@@ -1,223 +0,0 @@
/*
* Copyright (c) 1988, 1992, 1993
* The 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.
*
* @(#)in_cksum.c 8.1 (Berkeley) 6/10/93
* $Id$
*/
#include <sys/param.h>
#include <sys/mbuf.h>
#if (defined (__mcf5200__))
# define IS_COLDFIRE 1
#else
# define IS_COLDFIRE 0
#endif
#define REDUCE { sum = (sum & 0xFFFF) + (sum >> 16); if (sum > 0xFFFF) sum -= 0xFFFF; }
/*
* Motorola 68k version of Internet Protocol Checksum routine
* W. Eric Norum
* Saskatchewan Accelerator Laboratory
* August, 1998
*/
int
in_cksum(m, len)
struct mbuf *m;
int len;
{
unsigned short *w;
unsigned long sum = 0;
int mlen = 0;
int byte_swapped = 0;
union {
char c[2];
u_short s;
} s_util;
for ( ; m && len ; m = m->m_next) {
if (m->m_len == 0)
continue;
w = mtod(m, u_short *);
if (mlen == -1) {
/*
* The first byte of this mbuf is the continuation
* of a word spanning between this mbuf and the
* last mbuf.
*
* s_util.c[0] is already saved when scanning previous
* mbuf.
*/
s_util.c[1] = *(char *)w;
sum += s_util.s;
w = (u_short *)((char *)w + 1);
mlen = m->m_len - 1;
len--;
} else
mlen = m->m_len;
if (len < mlen)
mlen = len;
len -= mlen;
/*
* Force to longword boundary.
*/
if (3 & (int)w) {
REDUCE;
if ((1 & (int) w) && (mlen > 0)) {
sum <<= 8;
s_util.c[0] = *(u_char *)w;
w = (u_short *)((char *)w + 1);
mlen--;
byte_swapped = 1;
}
if ((2 & (int) w) && (mlen >= 2)) {
sum += *w++;
mlen -= 2;
}
}
/*
* Sum all the longwords in the buffer.
* See RFC 1071 -- Computing the Internet Checksum.
* It should work for all 68k family members.
*/
{
unsigned long tcnt = mlen, t1;
__asm__ volatile (
"movel %2,%3\n\t"
"lsrl #6,%2 | count/64 = # loop traversals\n\t"
"andl #0x3c,%3 | Then find fractions of a chunk\n\t"
"negl %3\n\t | Each long uses 4 instruction bytes\n\t"
#if IS_COLDFIRE
"addql #1,%2 | Clear X (extended carry flag)\n\t"
"subql #1,%2 | \n\t"
#else
"andi #0xf,%%cc | Clear X (extended carry flag)\n\t"
#endif
"jmp %%pc@(lcsum2_lbl-.-2:b,%3) | Jump into loop\n"
"lcsum1_lbl: | Begin inner loop...\n\t"
"movel %1@+,%3 | 0: Fetch 32-bit word\n\t"
"addxl %3,%0 | Add word + previous carry\n\t"
"movel %1@+,%3 | 1: Fetch 32-bit word\n\t"
"addxl %3,%0 | Add word + previous carry\n\t"
"movel %1@+,%3 | 2: Fetch 32-bit word\n\t"
"addxl %3,%0 | Add word + previous carry\n\t"
"movel %1@+,%3 | 3: Fetch 32-bit word\n\t"
"addxl %3,%0 | Add word + previous carry\n\t"
"movel %1@+,%3 | 4: Fetch 32-bit word\n\t"
"addxl %3,%0 | Add word + previous carry\n\t"
"movel %1@+,%3 | 5: Fetch 32-bit word\n\t"
"addxl %3,%0 | Add word + previous carry\n\t"
"movel %1@+,%3 | 6: Fetch 32-bit word\n\t"
"addxl %3,%0 | Add word + previous carry\n\t"
"movel %1@+,%3 | 7: Fetch 32-bit word\n\t"
"addxl %3,%0 | Add word + previous carry\n\t"
"movel %1@+,%3 | 8: Fetch 32-bit word\n\t"
"addxl %3,%0 | Add word + previous carry\n\t"
"movel %1@+,%3 | 9: Fetch 32-bit word\n\t"
"addxl %3,%0 | Add word + previous carry\n\t"
"movel %1@+,%3 | A: Fetch 32-bit word\n\t"
"addxl %3,%0 | Add word + previous carry\n\t"
"movel %1@+,%3 | B: Fetch 32-bit word\n\t"
"addxl %3,%0 | Add word + previous carry\n\t"
"movel %1@+,%3 | C: Fetch 32-bit word\n\t"
"addxl %3,%0 | Add word + previous carry\n\t"
"movel %1@+,%3 | D: Fetch 32-bit word\n\t"
"addxl %3,%0 | Add word + previous carry\n\t"
"movel %1@+,%3 | E: Fetch 32-bit word\n\t"
"addxl %3,%0 | Add word + previous carry\n\t"
"movel %1@+,%3 | F: Fetch 32-bit word\n\t"
"addxl %3,%0 | Add word + previous carry\n"
"lcsum2_lbl: | End of unrolled loop\n\t"
#if IS_COLDFIRE
"moveq #0,%3 | Add in last carry\n\t"
"addxl %3,%0 |\n\t"
"subql #1,%2 | Update loop count\n\t"
"bplb lcsum1_lbl | Loop (with X clear) if not done\n\t"
"movel #0xffff,%2 | Get word mask\n\t"
"movel %0,%3 | Fold 32 bit sum to 16 bits\n\t"
"swap %3 |\n\t"
"andl %2,%0 | Mask to 16-bit sum\n\t"
"andl %2,%3 | Mask to 16-bit sum\n\t"
"addl %3,%0 |\n\t"
"movel %0,%3 | Add in last carry\n\t"
"swap %3 |\n\t"
"addl %3,%0 |\n\t"
"andl %2,%0 | Mask to 16-bit sum\n\t"
#else
"dbf %2,lcsum1_lbl | (NB- dbf doesn't affect X)\n\t"
"movel %0,%3 | Fold 32 bit sum to 16 bits\n\t"
"swap %3 | (NB- swap doesn't affect X)\n\t"
"addxw %3,%0 |\n\t"
"moveq #0,%3 | Add in last carry\n\t"
"addxw %3,%0 |\n\t"
"andl #0xffff,%0 | Mask to 16-bit sum\n"
#endif
:
"=d" (sum), "=a" (w), "=d" (tcnt) , "=d" (t1) :
"0" (sum), "1" (w), "2" (tcnt) :
"cc", "memory");
}
mlen &= 3;
/*
* Soak up the last 1, 2 or 3 bytes
*/
while ((mlen -= 2) >= 0)
sum += *w++;
if (byte_swapped) {
REDUCE;
sum <<= 8;
byte_swapped = 0;
if (mlen == -1) {
s_util.c[1] = *(char *)w;
sum += s_util.s;
mlen = 0;
} else
mlen = -1;
} else if (mlen == -1)
s_util.c[0] = *(char *)w;
}
if (len)
sum = 0xDEAD;
if (mlen == -1) {
/* The last mbuf has odd # of bytes. Follow the
standard (the odd byte may be shifted left by 8 bits
or not as determined by endian-ness of the machine) */
s_util.c[1] = 0;
sum += s_util.s;
}
REDUCE;
return (~sum & 0xffff);
}

View File

@@ -1,173 +0,0 @@
/*
* Checksum routine for Internet Protocol family headers.
*
* This routine is very heavily used in the network
* code and should be modified for each CPU to be as fast as possible.
*
* This implementation is the PowerPC version.
*
* $Id$
*/
#include <stdio.h> /* for puts */
#undef ADDCARRY
#define ADDCARRY(x) if ((x) > 0xffff) (x) -= 0xffff
#define REDUCE {sum = (sum & 0xffff) + (sum >> 16); ADDCARRY(sum);}
/*
* Thanks to gcc we don't have to guess
* which registers contain sum & w.
*/
#define LDTMP(n) tmp = *((u_int *)((u_char *)w + n))
#define ADD(n) \
LDTMP(n); \
__asm__ volatile("addc %0,%0,%2" : "=r" (sum) : "0" (sum), "r" (tmp))
#define ADDC(n) \
LDTMP(n); \
__asm__ volatile("adde %0,%0,%2" : "=r" (sum) : "0" (sum), "r" (tmp))
#define MOP \
tmp = 0; \
__asm__ volatile("adde %0,%0,%2" : "=r" (sum) : "0" (sum), "r" (tmp))
#define LOAD(n) junk = (u_char) *((volatile u_char *) w + n)
int
in_cksum(m, len)
register struct mbuf *m;
register int len;
{
u_char junk;
register u_short *w;
register unsigned sum = 0;
register unsigned tmp;
register int mlen = 0;
int byte_swapped = 0;
union { char c[2]; u_short s; } su;
for (;m && len; m = m->m_next) {
if (m->m_len == 0)
continue;
w = mtod(m, u_short *);
if (mlen == -1) {
/*
* The first byte of this mbuf is the continuation
* of a word spanning between this mbuf and the
* last mbuf.
*/
/* su.c[0] is already saved when scanning previous
* mbuf. sum was REDUCEd when we found mlen == -1
*/
su.c[1] = *(u_char *)w;
sum += su.s;
w = (u_short *)((char *)w + 1);
mlen = m->m_len - 1;
len--;
} else
mlen = m->m_len;
if (len < mlen)
mlen = len;
len -= mlen;
/*
* Force to long boundary so we do longword aligned
* memory operations
*/
if (3 & (int) w) {
REDUCE;
if ((1 & (int) w) && (mlen > 0)) {
sum <<= 8;
su.c[0] = *(char *)w;
w = (u_short *)((char *)w + 1);
mlen--;
byte_swapped = 1;
}
if ((2 & (int) w) && (mlen >= 2)) {
sum += *w++;
mlen -= 2;
}
}
/*
* Do as much of the checksum as possible 32 bits at at time.
* In fact, this loop is unrolled to keep overhead from
* branches small.
*/
while (mlen >= 32) {
/*
* Add with carry 16 words and fold in the last
* carry by adding a 0 with carry.
*
* The early ADD(16) and the LOAD(32) are intended
* to help get the data into the cache.
*/
ADD(16);
ADDC(0);
ADDC(4);
ADDC(8);
ADDC(12);
LOAD(32);
ADDC(20);
ADDC(24);
ADDC(28);
MOP;
w += 16;
mlen -= 32;
}
if (mlen >= 16) {
ADD(0);
ADDC(4);
ADDC(8);
ADDC(12);
MOP;
w += 8;
mlen -= 16;
}
if (mlen >= 8) {
ADD(0);
ADDC(4);
MOP;
w += 4;
mlen -= 8;
}
if (mlen == 0 && byte_swapped == 0)
continue; /* worth 1% maybe ?? */
REDUCE;
while ((mlen -= 2) >= 0) {
sum += *w++;
}
if (byte_swapped) {
sum <<= 8;
byte_swapped = 0;
if (mlen == -1) {
su.c[1] = *(char *)w;
sum += su.s;
mlen = 0;
} else
mlen = -1;
} else if (mlen == -1)
/*
* This mbuf has odd number of bytes.
* There could be a word split betwen
* this mbuf and the next mbuf.
* Save the last byte (to prepend to next mbuf).
*/
su.c[0] = *(char *)w;
}
if (len)
puts("cksum: out of data");
if (mlen == -1) {
/* The last mbuf has odd # of bytes. Follow the
standard (the odd byte is shifted left by 8 bits) */
su.c[1] = 0;
sum += su.s;
}
REDUCE;
return (~sum & 0xffff);
}

View File

@@ -1,41 +0,0 @@
##
## $Id$
##
LIBNAME = lib.a
LIB = $(ARCH)/$(LIBNAME)
C_FILES = auth.c ccp.c chap.c chap_ms.c chat.c demand.c fsm.c ipcp.c lcp.c \
magic.c options.c upap.c md4.c md5.c utils.c sys-rtems.c rtemsmain.c \
rtemspppd.c
OBJS = $(C_FILES:%.c=$(ARCH)/%.$(OBJEXT))
include $(top_srcdir)/../../../automake/compile.am
include $(top_srcdir)/../../../automake/lib.am
#
# Add local stuff here using +=
#
$(LIB): $(OBJS)
$(make-library)
all-local: $(PREINSTALL_FILES) $(ARCH) $(OBJS) $(LIB)
.PRECIOUS: $(LIB)
EXTRA_DIST = auth.c ccp.c ccp.h chap.c chap.h chap_ms.c chap_ms.h \
chat.c demand.c fsm.c fsm.h ipcp.c ipcp.h ipxcp.c ipxcp.h \
lcp.c lcp.h magic.c magic.h md4.c md4.h md5.c md5.h options.c \
patchlevel.h pathnames.h pppd.h rtemsdialer.h rtemsmain.c rtemspppd.c \
rtemspppd.h sys-rtems.c upap.c upap.h utils.c
include_HEADERS = rtemspppd.h rtemsdialer.h
PREINSTALL_FILES = $(PROJECT_INCLUDE) $(include_HEADERS:%=$(PROJECT_INCLUDE)/%)
$(PROJECT_INCLUDE)/%.h: %.h
$(INSTALL_DATA) $< $@
include $(top_srcdir)/../../../automake/local.am

View File

@@ -1,29 +0,0 @@
#
# $Id$
#
This directory contains a port of ppp-2.3.11. The official site for
the original source for this PPP implementation is:
ftp://cs.anu.edu.au/pub/software/ppp
================================================================
History
The original port was of 2.3.5 by Tomasz Domin <dot@comarch.pl> of
ComArch SA and was initially only tested on the mpc823. He
provided the modem driver as well.
The port was updated to 2.3.11 by Mike Siers <mikes@poliac.com>
who added an example test.
Updated the chat program to return the correct errors and support
the ABORT commands. Removed some dead code and did a lot of
testing on a new Coldfire BSP. Version seems to be very stable.
Update code to use RTEMS pppd network drivers. Now the pppd
software is not dependent on using task driven mode. This
change improved stablity and performance. This was updated
by Mike Siers <mikes@poliac.com>.
=================================================================

View File

@@ -1,27 +0,0 @@
#
# $Id$
#
The pppd application seems to very stable. It has been tested using
the example application with the i386/pc586 and m68k/sbc5206e BSPs.
The tests were executed using a null modem serial cable to connect
with a UNIX box running either the ppp or pppd application and with
an external modem to dial up a local ISP.
If you have problems getting your target to make consistent connections
with an ISP, the problem is most likely with the ppp options. First
try using the "novj" and "noaccomp" options. If you have questions
about what other option values are available for the rtems_pppd_set_option
function, please look at the pppd.8 man page file or the the source code.
The majority of options that are documented in man page should work
with this function call.
The pppd code had now been updated to use it's own RTEMS network
drivers. This removes the requirement for the task driven termios
support. This update has fixed the large packet ping problem.
Currently, I do not know of any problems with the port.
If you find any other problems or fix some problems, please post your
changes to the RTEMS mailing list.
Good Luck

File diff suppressed because it is too large Load Diff

View File

@@ -1,456 +0,0 @@
/*
* cbcp - Call Back Configuration Protocol.
*
* Copyright (c) 1995 Pedro Roque Marques
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by Pedro Roque Marques. The name of the author may not be used to
* endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
#define RCSID "$Id$"
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/time.h>
#include "pppd.h"
#include "cbcp.h"
#include "fsm.h"
#include "lcp.h"
static const char rcsid[] = RCSID;
/*
* Options.
*/
static int setcbcp __P((char **));
static option_t cbcp_option_list[] = {
{ "callback", o_special, setcbcp,
"Ask for callback" },
{ NULL }
};
/*
* Protocol entry points.
*/
static void cbcp_init __P((int unit));
static void cbcp_open __P((int unit));
static void cbcp_lowerup __P((int unit));
static void cbcp_input __P((int unit, u_char *pkt, int len));
static void cbcp_protrej __P((int unit));
static int cbcp_printpkt __P((u_char *pkt, int len,
void (*printer) __P((void *, char *, ...)),
void *arg));
struct protent cbcp_protent = {
PPP_CBCP,
cbcp_init,
cbcp_input,
cbcp_protrej,
cbcp_lowerup,
NULL,
cbcp_open,
NULL,
cbcp_printpkt,
NULL,
0,
"CBCP",
NULL,
cbcp_option_list,
NULL,
NULL,
NULL
};
cbcp_state cbcp[NUM_PPP];
/* internal prototypes */
static void cbcp_recvreq __P((cbcp_state *us, char *pckt, int len));
static void cbcp_resp __P((cbcp_state *us));
static void cbcp_up __P((cbcp_state *us));
static void cbcp_recvack __P((cbcp_state *us, char *pckt, int len));
static void cbcp_send __P((cbcp_state *us, u_char code, u_char *buf, int len));
/* option processing */
static int
setcbcp(argv)
char **argv;
{
lcp_wantoptions[0].neg_cbcp = 1;
cbcp_protent.enabled_flag = 1;
cbcp[0].us_number = strdup(*argv);
if (cbcp[0].us_number == 0)
novm("callback number");
cbcp[0].us_type |= (1 << CB_CONF_USER);
cbcp[0].us_type |= (1 << CB_CONF_ADMIN);
return (1);
}
/* init state */
static void
cbcp_init(iface)
int iface;
{
cbcp_state *us;
us = &cbcp[iface];
memset(us, 0, sizeof(cbcp_state));
us->us_unit = iface;
us->us_type |= (1 << CB_CONF_NO);
}
/* lower layer is up */
static void
cbcp_lowerup(iface)
int iface;
{
cbcp_state *us = &cbcp[iface];
dbglog("cbcp_lowerup");
dbglog("want: %d", us->us_type);
if (us->us_type == CB_CONF_USER)
dbglog("phone no: %s", us->us_number);
}
static void
cbcp_open(unit)
int unit;
{
dbglog("cbcp_open");
}
/* process an incomming packet */
static void
cbcp_input(unit, inpacket, pktlen)
int unit;
u_char *inpacket;
int pktlen;
{
u_char *inp;
u_char code, id;
u_short len;
cbcp_state *us = &cbcp[unit];
inp = inpacket;
if (pktlen < CBCP_MINLEN) {
error("CBCP packet is too small");
return;
}
GETCHAR(code, inp);
GETCHAR(id, inp);
GETSHORT(len, inp);
#if 0
if (len > pktlen) {
error("CBCP packet: invalid length");
return;
}
#endif
len -= CBCP_MINLEN;
switch(code) {
case CBCP_REQ:
us->us_id = id;
cbcp_recvreq(us, inp, len);
break;
case CBCP_RESP:
dbglog("CBCP_RESP received");
break;
case CBCP_ACK:
if (id != us->us_id)
dbglog("id doesn't match: expected %d recv %d",
us->us_id, id);
cbcp_recvack(us, inp, len);
break;
default:
break;
}
}
/* protocol was rejected by foe */
void cbcp_protrej(int iface)
{
}
char *cbcp_codenames[] = {
"Request", "Response", "Ack"
};
char *cbcp_optionnames[] = {
"NoCallback",
"UserDefined",
"AdminDefined",
"List"
};
/* pretty print a packet */
static int
cbcp_printpkt(p, plen, printer, arg)
u_char *p;
int plen;
void (*printer) __P((void *, char *, ...));
void *arg;
{
int code, opt, id, len, olen, delay;
u_char *pstart;
if (plen < HEADERLEN)
return 0;
pstart = p;
GETCHAR(code, p);
GETCHAR(id, p);
GETSHORT(len, p);
if (len < HEADERLEN || len > plen)
return 0;
if (code >= 1 && code <= sizeof(cbcp_codenames) / sizeof(char *))
printer(arg, " %s", cbcp_codenames[code-1]);
else
printer(arg, " code=0x%x", code);
printer(arg, " id=0x%x", id);
len -= HEADERLEN;
switch (code) {
case CBCP_REQ:
case CBCP_RESP:
case CBCP_ACK:
while(len >= 2) {
GETCHAR(opt, p);
GETCHAR(olen, p);
if (olen < 2 || olen > len) {
break;
}
printer(arg, " <");
len -= olen;
if (opt >= 1 && opt <= sizeof(cbcp_optionnames) / sizeof(char *))
printer(arg, " %s", cbcp_optionnames[opt-1]);
else
printer(arg, " option=0x%x", opt);
if (olen > 2) {
GETCHAR(delay, p);
printer(arg, " delay = %d", delay);
}
if (olen > 3) {
int addrt;
char str[256];
GETCHAR(addrt, p);
memcpy(str, p, olen - 4);
str[olen - 4] = 0;
printer(arg, " number = %s", str);
}
printer(arg, ">");
break;
}
default:
break;
}
for (; len > 0; --len) {
GETCHAR(code, p);
printer(arg, " %.2x", code);
}
return p - pstart;
}
/* received CBCP request */
static void
cbcp_recvreq(us, pckt, pcktlen)
cbcp_state *us;
char *pckt;
int pcktlen;
{
u_char type, opt_len, delay, addr_type;
char address[256];
int len = pcktlen;
address[0] = 0;
while (len) {
dbglog("length: %d", len);
GETCHAR(type, pckt);
GETCHAR(opt_len, pckt);
if (opt_len > 2)
GETCHAR(delay, pckt);
us->us_allowed |= (1 << type);
switch(type) {
case CB_CONF_NO:
dbglog("no callback allowed");
break;
case CB_CONF_USER:
dbglog("user callback allowed");
if (opt_len > 4) {
GETCHAR(addr_type, pckt);
memcpy(address, pckt, opt_len - 4);
address[opt_len - 4] = 0;
if (address[0])
dbglog("address: %s", address);
}
break;
case CB_CONF_ADMIN:
dbglog("user admin defined allowed");
break;
case CB_CONF_LIST:
break;
}
len -= opt_len;
}
cbcp_resp(us);
}
static void
cbcp_resp(us)
cbcp_state *us;
{
u_char cb_type;
u_char buf[256];
u_char *bufp = buf;
int len = 0;
cb_type = us->us_allowed & us->us_type;
dbglog("cbcp_resp cb_type=%d", cb_type);
#if 0
if (!cb_type)
lcp_down(us->us_unit);
#endif
if (cb_type & ( 1 << CB_CONF_USER ) ) {
dbglog("cbcp_resp CONF_USER");
PUTCHAR(CB_CONF_USER, bufp);
len = 3 + 1 + strlen(us->us_number) + 1;
PUTCHAR(len , bufp);
PUTCHAR(5, bufp); /* delay */
PUTCHAR(1, bufp);
BCOPY(us->us_number, bufp, strlen(us->us_number) + 1);
cbcp_send(us, CBCP_RESP, buf, len);
return;
}
if (cb_type & ( 1 << CB_CONF_ADMIN ) ) {
dbglog("cbcp_resp CONF_ADMIN");
PUTCHAR(CB_CONF_ADMIN, bufp);
len = 3;
PUTCHAR(len, bufp);
PUTCHAR(5, bufp); /* delay */
cbcp_send(us, CBCP_RESP, buf, len);
return;
}
if (cb_type & ( 1 << CB_CONF_NO ) ) {
dbglog("cbcp_resp CONF_NO");
PUTCHAR(CB_CONF_NO, bufp);
len = 3;
PUTCHAR(len , bufp);
PUTCHAR(0, bufp);
cbcp_send(us, CBCP_RESP, buf, len);
start_networks();
return;
}
}
static void
cbcp_send(us, code, buf, len)
cbcp_state *us;
u_char code;
u_char *buf;
int len;
{
u_char *outp;
int outlen;
outp = outpacket_buf;
outlen = 4 + len;
MAKEHEADER(outp, PPP_CBCP);
PUTCHAR(code, outp);
PUTCHAR(us->us_id, outp);
PUTSHORT(outlen, outp);
if (len)
BCOPY(buf, outp, len);
output(us->us_unit, outpacket_buf, outlen + PPP_HDRLEN);
}
static void
cbcp_recvack(us, pckt, len)
cbcp_state *us;
char *pckt;
int len;
{
u_char type, delay, addr_type;
int opt_len;
char address[256];
if (len) {
GETCHAR(type, pckt);
GETCHAR(opt_len, pckt);
if (opt_len > 2)
GETCHAR(delay, pckt);
if (opt_len > 4) {
GETCHAR(addr_type, pckt);
memcpy(address, pckt, opt_len - 4);
address[opt_len - 4] = 0;
if (address[0])
dbglog("peer will call: %s", address);
}
if (type == CB_CONF_NO)
return;
}
cbcp_up(us);
}
/* ok peer will do callback */
static void
cbcp_up(us)
cbcp_state *us;
{
persist = 0;
lcp_close(0, "Call me back, please");
status = EXIT_CALLBACK;
}

View File

@@ -1,26 +0,0 @@
#ifndef CBCP_H
#define CBCP_H
typedef struct cbcp_state {
int us_unit; /* Interface unit number */
u_char us_id; /* Current id */
u_char us_allowed;
int us_type;
char *us_number; /* Telefone Number */
} cbcp_state;
extern cbcp_state cbcp[];
extern struct protent cbcp_protent;
#define CBCP_MINLEN 4
#define CBCP_REQ 1
#define CBCP_RESP 2
#define CBCP_ACK 3
#define CB_CONF_NO 1
#define CB_CONF_USER 2
#define CB_CONF_ADMIN 3
#define CB_CONF_LIST 4
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -1,48 +0,0 @@
/*
* ccp.h - Definitions for PPP Compression Control Protocol.
*
* Copyright (c) 1994 The Australian National University.
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and its
* documentation is hereby granted, provided that the above copyright
* notice appears in all copies. This software is provided without any
* warranty, express or implied. The Australian National University
* makes no representations about the suitability of this software for
* any purpose.
*
* IN NO EVENT SHALL THE AUSTRALIAN NATIONAL UNIVERSITY BE LIABLE TO ANY
* PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
* ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
* THE AUSTRALIAN NATIONAL UNIVERSITY HAVE BEEN ADVISED OF THE POSSIBILITY
* OF SUCH DAMAGE.
*
* THE AUSTRALIAN NATIONAL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
* ON AN "AS IS" BASIS, AND THE AUSTRALIAN NATIONAL UNIVERSITY HAS NO
* OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS,
* OR MODIFICATIONS.
*
* $Id$
*/
typedef struct ccp_options {
bool bsd_compress; /* do BSD Compress? */
bool deflate; /* do Deflate? */
bool predictor_1; /* do Predictor-1? */
bool predictor_2; /* do Predictor-2? */
bool deflate_correct; /* use correct code for deflate? */
bool deflate_draft; /* use draft RFC code for deflate? */
u_short bsd_bits; /* # bits/code for BSD Compress */
u_short deflate_size; /* lg(window size) for Deflate */
short method; /* code for chosen compression method */
} ccp_options;
extern fsm ccp_fsm[];
extern ccp_options ccp_wantoptions[];
extern ccp_options ccp_gotoptions[];
extern ccp_options ccp_allowoptions[];
extern ccp_options ccp_hisoptions[];
extern struct protent ccp_protent;

View File

@@ -1,860 +0,0 @@
/*
* chap.c - Challenge Handshake Authentication Protocol.
*
* Copyright (c) 1993 The Australian National University.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the Australian National University. The name of the University
* may not be used to endorse or promote products derived from this
* software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* Copyright (c) 1991 Gregory M. Christy.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by Gregory M. Christy. The name of the author may not be used to
* endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
#define RCSID "$Id$"
/*
* TODO:
*/
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/time.h>
#include "pppd.h"
#include "chap.h"
#include "md5.h"
#ifdef CHAPMS
#include "chap_ms.h"
#endif
static const char rcsid[] = RCSID;
/*
* Command-line options.
*/
static option_t chap_option_list[] = {
{ "chap-restart", o_int, &chap[0].timeouttime,
"Set timeout for CHAP" },
{ "chap-max-challenge", o_int, &chap[0].max_transmits,
"Set max #xmits for challenge" },
{ "chap-interval", o_int, &chap[0].chal_interval,
"Set interval for rechallenge" },
#ifdef MSLANMAN
{ "ms-lanman", o_bool, &ms_lanman,
"Use LanMan passwd when using MS-CHAP", 1 },
#endif
{ NULL }
};
/*
* Protocol entry points.
*/
static void ChapInit __P((int));
static void ChapLowerUp __P((int));
static void ChapLowerDown __P((int));
static void ChapInput __P((int, u_char *, int));
static void ChapProtocolReject __P((int));
static int ChapPrintPkt __P((u_char *, int,
void (*) __P((void *, char *, ...)), void *));
struct protent chap_protent = {
PPP_CHAP,
ChapInit,
ChapInput,
ChapProtocolReject,
ChapLowerUp,
ChapLowerDown,
NULL,
NULL,
ChapPrintPkt,
NULL,
1,
"CHAP",
NULL,
chap_option_list,
NULL,
NULL,
NULL
};
chap_state chap[NUM_PPP]; /* CHAP state; one for each unit */
static void ChapChallengeTimeout __P((void *));
static void ChapResponseTimeout __P((void *));
static void ChapReceiveChallenge __P((chap_state *, u_char *, int, int));
static void ChapRechallenge __P((void *));
static void ChapReceiveResponse __P((chap_state *, u_char *, int, int));
static void ChapReceiveSuccess __P((chap_state *, u_char *, u_char, int));
static void ChapReceiveFailure __P((chap_state *, u_char *, u_char, int));
static void ChapSendStatus __P((chap_state *, int));
static void ChapSendChallenge __P((chap_state *));
static void ChapSendResponse __P((chap_state *));
static void ChapGenChallenge __P((chap_state *));
extern double drand48 __P((void));
extern void srand48 __P((long));
/*
* ChapInit - Initialize a CHAP unit.
*/
static void
ChapInit(unit)
int unit;
{
chap_state *cstate = &chap[unit];
BZERO(cstate, sizeof(*cstate));
cstate->unit = unit;
cstate->clientstate = CHAPCS_INITIAL;
cstate->serverstate = CHAPSS_INITIAL;
cstate->timeouttime = CHAP_DEFTIMEOUT;
cstate->max_transmits = CHAP_DEFTRANSMITS;
/* random number generator is initialized in magic_init */
}
/*
* ChapAuthWithPeer - Authenticate us with our peer (start client).
*
*/
void
ChapAuthWithPeer(unit, our_name, digest)
int unit;
char *our_name;
int digest;
{
chap_state *cstate = &chap[unit];
cstate->resp_name = our_name;
cstate->resp_type = digest;
if (cstate->clientstate == CHAPCS_INITIAL ||
cstate->clientstate == CHAPCS_PENDING) {
/* lower layer isn't up - wait until later */
cstate->clientstate = CHAPCS_PENDING;
return;
}
/*
* We get here as a result of LCP coming up.
* So even if CHAP was open before, we will
* have to re-authenticate ourselves.
*/
cstate->clientstate = CHAPCS_LISTEN;
}
/*
* ChapAuthPeer - Authenticate our peer (start server).
*/
void
ChapAuthPeer(unit, our_name, digest)
int unit;
char *our_name;
int digest;
{
chap_state *cstate = &chap[unit];
cstate->chal_name = our_name;
cstate->chal_type = digest;
if (cstate->serverstate == CHAPSS_INITIAL ||
cstate->serverstate == CHAPSS_PENDING) {
/* lower layer isn't up - wait until later */
cstate->serverstate = CHAPSS_PENDING;
return;
}
ChapGenChallenge(cstate);
ChapSendChallenge(cstate); /* crank it up dude! */
cstate->serverstate = CHAPSS_INITIAL_CHAL;
}
/*
* ChapChallengeTimeout - Timeout expired on sending challenge.
*/
static void
ChapChallengeTimeout(arg)
void *arg;
{
chap_state *cstate = (chap_state *) arg;
/* if we aren't sending challenges, don't worry. then again we */
/* probably shouldn't be here either */
if (cstate->serverstate != CHAPSS_INITIAL_CHAL &&
cstate->serverstate != CHAPSS_RECHALLENGE)
return;
if (cstate->chal_transmits >= cstate->max_transmits) {
/* give up on peer */
error("Peer failed to respond to CHAP challenge");
cstate->serverstate = CHAPSS_BADAUTH;
auth_peer_fail(cstate->unit, PPP_CHAP);
return;
}
ChapSendChallenge(cstate); /* Re-send challenge */
}
/*
* ChapResponseTimeout - Timeout expired on sending response.
*/
static void
ChapResponseTimeout(arg)
void *arg;
{
chap_state *cstate = (chap_state *) arg;
/* if we aren't sending a response, don't worry. */
if (cstate->clientstate != CHAPCS_RESPONSE)
return;
ChapSendResponse(cstate); /* re-send response */
}
/*
* ChapRechallenge - Time to challenge the peer again.
*/
static void
ChapRechallenge(arg)
void *arg;
{
chap_state *cstate = (chap_state *) arg;
/* if we aren't sending a response, don't worry. */
if (cstate->serverstate != CHAPSS_OPEN)
return;
ChapGenChallenge(cstate);
ChapSendChallenge(cstate);
cstate->serverstate = CHAPSS_RECHALLENGE;
}
/*
* ChapLowerUp - The lower layer is up.
*
* Start up if we have pending requests.
*/
static void
ChapLowerUp(unit)
int unit;
{
chap_state *cstate = &chap[unit];
if (cstate->clientstate == CHAPCS_INITIAL)
cstate->clientstate = CHAPCS_CLOSED;
else if (cstate->clientstate == CHAPCS_PENDING)
cstate->clientstate = CHAPCS_LISTEN;
if (cstate->serverstate == CHAPSS_INITIAL)
cstate->serverstate = CHAPSS_CLOSED;
else if (cstate->serverstate == CHAPSS_PENDING) {
ChapGenChallenge(cstate);
ChapSendChallenge(cstate);
cstate->serverstate = CHAPSS_INITIAL_CHAL;
}
}
/*
* ChapLowerDown - The lower layer is down.
*
* Cancel all timeouts.
*/
static void
ChapLowerDown(unit)
int unit;
{
chap_state *cstate = &chap[unit];
/* Timeout(s) pending? Cancel if so. */
if (cstate->serverstate == CHAPSS_INITIAL_CHAL ||
cstate->serverstate == CHAPSS_RECHALLENGE)
UNTIMEOUT(ChapChallengeTimeout, cstate);
else if (cstate->serverstate == CHAPSS_OPEN
&& cstate->chal_interval != 0)
UNTIMEOUT(ChapRechallenge, cstate);
if (cstate->clientstate == CHAPCS_RESPONSE)
UNTIMEOUT(ChapResponseTimeout, cstate);
cstate->clientstate = CHAPCS_INITIAL;
cstate->serverstate = CHAPSS_INITIAL;
}
/*
* ChapProtocolReject - Peer doesn't grok CHAP.
*/
static void
ChapProtocolReject(unit)
int unit;
{
chap_state *cstate = &chap[unit];
if (cstate->serverstate != CHAPSS_INITIAL &&
cstate->serverstate != CHAPSS_CLOSED)
auth_peer_fail(unit, PPP_CHAP);
if (cstate->clientstate != CHAPCS_INITIAL &&
cstate->clientstate != CHAPCS_CLOSED)
auth_withpeer_fail(unit, PPP_CHAP);
ChapLowerDown(unit); /* shutdown chap */
}
/*
* ChapInput - Input CHAP packet.
*/
static void
ChapInput(unit, inpacket, packet_len)
int unit;
u_char *inpacket;
int packet_len;
{
chap_state *cstate = &chap[unit];
u_char *inp;
u_char code, id;
int len;
/*
* Parse header (code, id and length).
* If packet too short, drop it.
*/
inp = inpacket;
if (packet_len < CHAP_HEADERLEN) {
CHAPDEBUG(("ChapInput: rcvd short header."));
return;
}
GETCHAR(code, inp);
GETCHAR(id, inp);
GETSHORT(len, inp);
if (len < CHAP_HEADERLEN) {
CHAPDEBUG(("ChapInput: rcvd illegal length."));
return;
}
if (len > packet_len) {
CHAPDEBUG(("ChapInput: rcvd short packet."));
return;
}
len -= CHAP_HEADERLEN;
/*
* Action depends on code (as in fact it usually does :-).
*/
switch (code) {
case CHAP_CHALLENGE:
ChapReceiveChallenge(cstate, inp, id, len);
break;
case CHAP_RESPONSE:
ChapReceiveResponse(cstate, inp, id, len);
break;
case CHAP_FAILURE:
ChapReceiveFailure(cstate, inp, id, len);
break;
case CHAP_SUCCESS:
ChapReceiveSuccess(cstate, inp, id, len);
break;
default: /* Need code reject? */
warn("Unknown CHAP code (%d) received.", code);
break;
}
}
/*
* ChapReceiveChallenge - Receive Challenge and send Response.
*/
static void
ChapReceiveChallenge(cstate, inp, id, len)
chap_state *cstate;
u_char *inp;
int id;
int len;
{
int rchallenge_len;
u_char *rchallenge;
int secret_len;
char secret[MAXSECRETLEN];
char rhostname[256];
MD5_CTX mdContext;
u_char hash[MD5_SIGNATURE_SIZE];
if (cstate->clientstate == CHAPCS_CLOSED ||
cstate->clientstate == CHAPCS_PENDING) {
CHAPDEBUG(("ChapReceiveChallenge: in state %d", cstate->clientstate));
return;
}
if (len < 2) {
CHAPDEBUG(("ChapReceiveChallenge: rcvd short packet."));
return;
}
GETCHAR(rchallenge_len, inp);
len -= sizeof (u_char) + rchallenge_len; /* now name field length */
if (len < 0) {
CHAPDEBUG(("ChapReceiveChallenge: rcvd short packet."));
return;
}
rchallenge = inp;
INCPTR(rchallenge_len, inp);
if (len >= sizeof(rhostname))
len = sizeof(rhostname) - 1;
BCOPY(inp, rhostname, len);
rhostname[len] = '\000';
/* Microsoft doesn't send their name back in the PPP packet */
if (explicit_remote || (remote_name[0] != 0 && rhostname[0] == 0)) {
strlcpy(rhostname, remote_name, sizeof(rhostname));
CHAPDEBUG(("ChapReceiveChallenge: using '%q' as remote name",
rhostname));
}
/* get secret for authenticating ourselves with the specified host */
if (!get_secret(cstate->unit, cstate->resp_name, rhostname,
secret, &secret_len, 0)) {
secret_len = 0; /* assume null secret if can't find one */
warn("No CHAP secret found for authenticating us to %q", rhostname);
}
/* cancel response send timeout if necessary */
if (cstate->clientstate == CHAPCS_RESPONSE)
UNTIMEOUT(ChapResponseTimeout, cstate);
cstate->resp_id = id;
cstate->resp_transmits = 0;
/* generate MD based on negotiated type */
switch (cstate->resp_type) {
case CHAP_DIGEST_MD5:
MD5Init(&mdContext);
MD5Update(&mdContext, &cstate->resp_id, 1);
MD5Update(&mdContext, secret, secret_len);
MD5Update(&mdContext, rchallenge, rchallenge_len);
MD5Final(hash, &mdContext);
BCOPY(hash, cstate->response, MD5_SIGNATURE_SIZE);
cstate->resp_length = MD5_SIGNATURE_SIZE;
break;
#ifdef CHAPMS
case CHAP_MICROSOFT:
ChapMS(cstate, rchallenge, rchallenge_len, secret, secret_len);
break;
#endif
default:
CHAPDEBUG(("unknown digest type %d", cstate->resp_type));
return;
}
BZERO(secret, sizeof(secret));
ChapSendResponse(cstate);
}
/*
* ChapReceiveResponse - Receive and process response.
*/
static void
ChapReceiveResponse(cstate, inp, id, len)
chap_state *cstate;
u_char *inp;
int id;
int len;
{
u_char *remmd, remmd_len;
int secret_len, old_state;
int code;
char rhostname[256];
MD5_CTX mdContext;
char secret[MAXSECRETLEN];
u_char hash[MD5_SIGNATURE_SIZE];
if (cstate->serverstate == CHAPSS_CLOSED ||
cstate->serverstate == CHAPSS_PENDING) {
CHAPDEBUG(("ChapReceiveResponse: in state %d", cstate->serverstate));
return;
}
if (id != cstate->chal_id)
return; /* doesn't match ID of last challenge */
/*
* If we have received a duplicate or bogus Response,
* we have to send the same answer (Success/Failure)
* as we did for the first Response we saw.
*/
if (cstate->serverstate == CHAPSS_OPEN) {
ChapSendStatus(cstate, CHAP_SUCCESS);
return;
}
if (cstate->serverstate == CHAPSS_BADAUTH) {
ChapSendStatus(cstate, CHAP_FAILURE);
return;
}
if (len < 2) {
CHAPDEBUG(("ChapReceiveResponse: rcvd short packet."));
return;
}
GETCHAR(remmd_len, inp); /* get length of MD */
remmd = inp; /* get pointer to MD */
INCPTR(remmd_len, inp);
len -= sizeof (u_char) + remmd_len;
if (len < 0) {
CHAPDEBUG(("ChapReceiveResponse: rcvd short packet."));
return;
}
UNTIMEOUT(ChapChallengeTimeout, cstate);
if (len >= sizeof(rhostname))
len = sizeof(rhostname) - 1;
BCOPY(inp, rhostname, len);
rhostname[len] = '\000';
/*
* Get secret for authenticating them with us,
* do the hash ourselves, and compare the result.
*/
code = CHAP_FAILURE;
if (!get_secret(cstate->unit, (explicit_remote? remote_name: rhostname),
cstate->chal_name, secret, &secret_len, 1)) {
warn("No CHAP secret found for authenticating %q", rhostname);
} else {
/* generate MD based on negotiated type */
switch (cstate->chal_type) {
case CHAP_DIGEST_MD5: /* only MD5 is defined for now */
if (remmd_len != MD5_SIGNATURE_SIZE)
break; /* it's not even the right length */
MD5Init(&mdContext);
MD5Update(&mdContext, &cstate->chal_id, 1);
MD5Update(&mdContext, secret, secret_len);
MD5Update(&mdContext, cstate->challenge, cstate->chal_len);
MD5Final(hash, &mdContext);
/* compare local and remote MDs and send the appropriate status */
if (memcmp (hash, remmd, MD5_SIGNATURE_SIZE) == 0)
code = CHAP_SUCCESS; /* they are the same! */
break;
default:
CHAPDEBUG(("unknown digest type %d", cstate->chal_type));
}
}
BZERO(secret, sizeof(secret));
ChapSendStatus(cstate, code);
if (code == CHAP_SUCCESS) {
old_state = cstate->serverstate;
cstate->serverstate = CHAPSS_OPEN;
if (old_state == CHAPSS_INITIAL_CHAL) {
auth_peer_success(cstate->unit, PPP_CHAP, rhostname, len);
}
if (cstate->chal_interval != 0)
TIMEOUT(ChapRechallenge, cstate, cstate->chal_interval);
notice("CHAP peer authentication succeeded for %q", rhostname);
} else {
error("CHAP peer authentication failed for remote host %q", rhostname);
cstate->serverstate = CHAPSS_BADAUTH;
auth_peer_fail(cstate->unit, PPP_CHAP);
}
}
/*
* ChapReceiveSuccess - Receive Success
*/
static void
ChapReceiveSuccess(cstate, inp, id, len)
chap_state *cstate;
u_char *inp;
u_char id;
int len;
{
if (cstate->clientstate == CHAPCS_OPEN)
/* presumably an answer to a duplicate response */
return;
if (cstate->clientstate != CHAPCS_RESPONSE) {
/* don't know what this is */
CHAPDEBUG(("ChapReceiveSuccess: in state %d\n", cstate->clientstate));
return;
}
UNTIMEOUT(ChapResponseTimeout, cstate);
/*
* Print message.
*/
if (len > 0)
PRINTMSG(inp, len);
cstate->clientstate = CHAPCS_OPEN;
auth_withpeer_success(cstate->unit, PPP_CHAP);
}
/*
* ChapReceiveFailure - Receive failure.
*/
static void
ChapReceiveFailure(cstate, inp, id, len)
chap_state *cstate;
u_char *inp;
u_char id;
int len;
{
if (cstate->clientstate != CHAPCS_RESPONSE) {
/* don't know what this is */
CHAPDEBUG(("ChapReceiveFailure: in state %d\n", cstate->clientstate));
return;
}
UNTIMEOUT(ChapResponseTimeout, cstate);
/*
* Print message.
*/
if (len > 0)
PRINTMSG(inp, len);
error("CHAP authentication failed");
auth_withpeer_fail(cstate->unit, PPP_CHAP);
}
/*
* ChapSendChallenge - Send an Authenticate challenge.
*/
static void
ChapSendChallenge(cstate)
chap_state *cstate;
{
u_char *outp;
int chal_len, name_len;
int outlen;
chal_len = cstate->chal_len;
name_len = strlen(cstate->chal_name);
outlen = CHAP_HEADERLEN + sizeof (u_char) + chal_len + name_len;
outp = outpacket_buf;
MAKEHEADER(outp, PPP_CHAP); /* paste in a CHAP header */
PUTCHAR(CHAP_CHALLENGE, outp);
PUTCHAR(cstate->chal_id, outp);
PUTSHORT(outlen, outp);
PUTCHAR(chal_len, outp); /* put length of challenge */
BCOPY(cstate->challenge, outp, chal_len);
INCPTR(chal_len, outp);
BCOPY(cstate->chal_name, outp, name_len); /* append hostname */
output(cstate->unit, outpacket_buf, outlen + PPP_HDRLEN);
TIMEOUT(ChapChallengeTimeout, cstate, cstate->timeouttime);
++cstate->chal_transmits;
}
/*
* ChapSendStatus - Send a status response (ack or nak).
*/
static void
ChapSendStatus(cstate, code)
chap_state *cstate;
int code;
{
u_char *outp;
int outlen, msglen;
char msg[256];
if (code == CHAP_SUCCESS)
slprintf(msg, sizeof(msg), "Welcome to %s.", hostname);
else
slprintf(msg, sizeof(msg), "I don't like you. Go 'way.");
msglen = strlen(msg);
outlen = CHAP_HEADERLEN + msglen;
outp = outpacket_buf;
MAKEHEADER(outp, PPP_CHAP); /* paste in a header */
PUTCHAR(code, outp);
PUTCHAR(cstate->chal_id, outp);
PUTSHORT(outlen, outp);
BCOPY(msg, outp, msglen);
output(cstate->unit, outpacket_buf, outlen + PPP_HDRLEN);
}
/*
* ChapGenChallenge is used to generate a pseudo-random challenge string of
* a pseudo-random length between min_len and max_len. The challenge
* string and its length are stored in *cstate, and various other fields of
* *cstate are initialized.
*/
static void
ChapGenChallenge(cstate)
chap_state *cstate;
{
int chal_len;
u_char *ptr = cstate->challenge;
int i;
/* pick a random challenge length between MIN_CHALLENGE_LENGTH and
MAX_CHALLENGE_LENGTH */
chal_len = (unsigned) ((drand48() *
(MAX_CHALLENGE_LENGTH - MIN_CHALLENGE_LENGTH)) +
MIN_CHALLENGE_LENGTH);
cstate->chal_len = chal_len;
cstate->chal_id = ++cstate->id;
cstate->chal_transmits = 0;
/* generate a random string */
for (i = 0; i < chal_len; i++)
*ptr++ = (char) (drand48() * 0xff);
}
/*
* ChapSendResponse - send a response packet with values as specified
* in *cstate.
*/
/* ARGSUSED */
static void
ChapSendResponse(cstate)
chap_state *cstate;
{
u_char *outp;
int outlen, md_len, name_len;
md_len = cstate->resp_length;
name_len = strlen(cstate->resp_name);
outlen = CHAP_HEADERLEN + sizeof (u_char) + md_len + name_len;
outp = outpacket_buf;
MAKEHEADER(outp, PPP_CHAP);
PUTCHAR(CHAP_RESPONSE, outp); /* we are a response */
PUTCHAR(cstate->resp_id, outp); /* copy id from challenge packet */
PUTSHORT(outlen, outp); /* packet length */
PUTCHAR(md_len, outp); /* length of MD */
BCOPY(cstate->response, outp, md_len); /* copy MD to buffer */
INCPTR(md_len, outp);
BCOPY(cstate->resp_name, outp, name_len); /* append our name */
/* send the packet */
output(cstate->unit, outpacket_buf, outlen + PPP_HDRLEN);
cstate->clientstate = CHAPCS_RESPONSE;
TIMEOUT(ChapResponseTimeout, cstate, cstate->timeouttime);
++cstate->resp_transmits;
}
/*
* ChapPrintPkt - print the contents of a CHAP packet.
*/
static char *ChapCodenames[] = {
"Challenge", "Response", "Success", "Failure"
};
static int
ChapPrintPkt(p, plen, printer, arg)
u_char *p;
int plen;
void (*printer) __P((void *, char *, ...));
void *arg;
{
int code, id, len;
int clen, nlen;
u_char x;
if (plen < CHAP_HEADERLEN)
return 0;
GETCHAR(code, p);
GETCHAR(id, p);
GETSHORT(len, p);
if (len < CHAP_HEADERLEN || len > plen)
return 0;
if (code >= 1 && code <= sizeof(ChapCodenames) / sizeof(char *))
printer(arg, " %s", ChapCodenames[code-1]);
else
printer(arg, " code=0x%x", code);
printer(arg, " id=0x%x", id);
len -= CHAP_HEADERLEN;
switch (code) {
case CHAP_CHALLENGE:
case CHAP_RESPONSE:
if (len < 1)
break;
clen = p[0];
if (len < clen + 1)
break;
++p;
nlen = len - clen - 1;
printer(arg, " <");
for (; clen > 0; --clen) {
GETCHAR(x, p);
printer(arg, "%.2x", x);
}
printer(arg, ">, name = ");
print_string((char *)p, nlen, printer, arg);
break;
case CHAP_FAILURE:
case CHAP_SUCCESS:
printer(arg, " ");
print_string((char *)p, len, printer, arg);
break;
default:
for (clen = len; clen > 0; --clen) {
GETCHAR(x, p);
printer(arg, " %.2x", x);
}
}
return len + CHAP_HEADERLEN;
}

View File

@@ -1,124 +0,0 @@
/*
* chap.h - Challenge Handshake Authentication Protocol definitions.
*
* Copyright (c) 1993 The Australian National University.
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the Australian National University. The name of the University
* may not be used to endorse or promote products derived from this
* software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* Copyright (c) 1991 Gregory M. Christy
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the author.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* $Id$
*/
#ifndef __CHAP_INCLUDE__
/* Code + ID + length */
#define CHAP_HEADERLEN 4
/*
* CHAP codes.
*/
#define CHAP_DIGEST_MD5 5 /* use MD5 algorithm */
#define MD5_SIGNATURE_SIZE 16 /* 16 bytes in a MD5 message digest */
#define CHAP_MICROSOFT 0x80 /* use Microsoft-compatible alg. */
#define MS_CHAP_RESPONSE_LEN 49 /* Response length for MS-CHAP */
#define CHAP_CHALLENGE 1
#define CHAP_RESPONSE 2
#define CHAP_SUCCESS 3
#define CHAP_FAILURE 4
/*
* Challenge lengths (for challenges we send) and other limits.
*/
#define MIN_CHALLENGE_LENGTH 16
#define MAX_CHALLENGE_LENGTH 24
#define MAX_RESPONSE_LENGTH 64 /* sufficient for MD5 or MS-CHAP */
/*
* Each interface is described by a chap structure.
*/
typedef struct chap_state {
int unit; /* Interface unit number */
int clientstate; /* Client state */
int serverstate; /* Server state */
u_char challenge[MAX_CHALLENGE_LENGTH]; /* last challenge string sent */
u_char chal_len; /* challenge length */
u_char chal_id; /* ID of last challenge */
u_char chal_type; /* hash algorithm for challenges */
u_char id; /* Current id */
char *chal_name; /* Our name to use with challenge */
int chal_interval; /* Time until we challenge peer again */
int timeouttime; /* Timeout time in seconds */
int max_transmits; /* Maximum # of challenge transmissions */
int chal_transmits; /* Number of transmissions of challenge */
int resp_transmits; /* Number of transmissions of response */
u_char response[MAX_RESPONSE_LENGTH]; /* Response to send */
u_char resp_length; /* length of response */
u_char resp_id; /* ID for response messages */
u_char resp_type; /* hash algorithm for responses */
char *resp_name; /* Our name to send with response */
} chap_state;
/*
* Client (peer) states.
*/
#define CHAPCS_INITIAL 0 /* Lower layer down, not opened */
#define CHAPCS_CLOSED 1 /* Lower layer up, not opened */
#define CHAPCS_PENDING 2 /* Auth us to peer when lower up */
#define CHAPCS_LISTEN 3 /* Listening for a challenge */
#define CHAPCS_RESPONSE 4 /* Sent response, waiting for status */
#define CHAPCS_OPEN 5 /* We've received Success */
/*
* Server (authenticator) states.
*/
#define CHAPSS_INITIAL 0 /* Lower layer down, not opened */
#define CHAPSS_CLOSED 1 /* Lower layer up, not opened */
#define CHAPSS_PENDING 2 /* Auth peer when lower up */
#define CHAPSS_INITIAL_CHAL 3 /* We've sent the first challenge */
#define CHAPSS_OPEN 4 /* We've sent a Success msg */
#define CHAPSS_RECHALLENGE 5 /* We've sent another challenge */
#define CHAPSS_BADAUTH 6 /* We've sent a Failure msg */
/*
* Timeouts.
*/
#define CHAP_DEFTIMEOUT 5 /* Timeout time in seconds */
#define CHAP_DEFTRANSMITS 10 /* max # times to send challenge */
extern chap_state chap[];
void ChapAuthWithPeer __P((int, char *, int));
void ChapAuthPeer __P((int, char *, int));
extern struct protent chap_protent;
#define __CHAP_INCLUDE__
#endif /* __CHAP_INCLUDE__ */

View File

@@ -1,338 +0,0 @@
/*
* chap_ms.c - Microsoft MS-CHAP compatible implementation.
*
* Copyright (c) 1995 Eric Rosenquist, Strata Software Limited.
* http://www.strataware.com/
*
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by Eric Rosenquist. The name of the author may not be used to
* endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
/*
* Modifications by Lauri Pesonen / lpesonen@clinet.fi, april 1997
*
* Implemented LANManager type password response to MS-CHAP challenges.
* Now pppd provides both NT style and LANMan style blocks, and the
* prefered is set by option "ms-lanman". Default is to use NT.
* The hash text (StdText) was taken from Win95 RASAPI32.DLL.
*
* You should also use DOMAIN\\USERNAME as described in README.MSCHAP80
*/
#define RCSID "$Id$"
#ifdef CHAPMS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/time.h>
#include <unistd.h>
#ifdef HAVE_CRYPT_H
#include <crypt.h>
#endif
#include "pppd.h"
#include "chap.h"
#include "chap_ms.h"
#include "md4.h"
#ifndef USE_CRYPT
#include <des.h>
#endif
static const char rcsid[] = RCSID;
typedef struct {
u_char LANManResp[24];
u_char NTResp[24];
u_char UseNT; /* If 1, ignore the LANMan response field */
} MS_ChapResponse;
/* We use MS_CHAP_RESPONSE_LEN, rather than sizeof(MS_ChapResponse),
in case this struct gets padded. */
static void ChallengeResponse __P((u_char *, u_char *, u_char *));
static void DesEncrypt __P((u_char *, u_char *, u_char *));
static void MakeKey __P((u_char *, u_char *));
static u_char Get7Bits __P((u_char *, int));
static void ChapMS_NT __P((char *, int, char *, int, MS_ChapResponse *));
#ifdef MSLANMAN
static void ChapMS_LANMan __P((char *, int, char *, int, MS_ChapResponse *));
#endif
#ifdef USE_CRYPT
static void Expand __P((u_char *, u_char *));
static void Collapse __P((u_char *, u_char *));
#endif
#ifdef MSLANMAN
bool ms_lanman = 0; /* Use LanMan password instead of NT */
/* Has meaning only with MS-CHAP challenges */
#endif
static void
ChallengeResponse(challenge, pwHash, response)
u_char *challenge; /* IN 8 octets */
u_char *pwHash; /* IN 16 octets */
u_char *response; /* OUT 24 octets */
{
char ZPasswordHash[21];
BZERO(ZPasswordHash, sizeof(ZPasswordHash));
BCOPY(pwHash, ZPasswordHash, MD4_SIGNATURE_SIZE);
#if 0
dbglog("ChallengeResponse - ZPasswordHash %.*B",
sizeof(ZPasswordHash), ZPasswordHash);
#endif
DesEncrypt(challenge, ZPasswordHash + 0, response + 0);
DesEncrypt(challenge, ZPasswordHash + 7, response + 8);
DesEncrypt(challenge, ZPasswordHash + 14, response + 16);
#if 0
dbglog("ChallengeResponse - response %.24B", response);
#endif
}
#ifdef USE_CRYPT
static void
DesEncrypt(clear, key, cipher)
u_char *clear; /* IN 8 octets */
u_char *key; /* IN 7 octets */
u_char *cipher; /* OUT 8 octets */
{
u_char des_key[8];
u_char crypt_key[66];
u_char des_input[66];
MakeKey(key, des_key);
Expand(des_key, crypt_key);
setkey(crypt_key);
#if 0
CHAPDEBUG((LOG_INFO, "DesEncrypt: 8 octet input : %.8B", clear));
#endif
Expand(clear, des_input);
encrypt(des_input, 0);
Collapse(des_input, cipher);
#if 0
CHAPDEBUG((LOG_INFO, "DesEncrypt: 8 octet output: %.8B", cipher));
#endif
}
#else /* USE_CRYPT */
static void
DesEncrypt(clear, key, cipher)
u_char *clear; /* IN 8 octets */
u_char *key; /* IN 7 octets */
u_char *cipher; /* OUT 8 octets */
{
des_cblock des_key;
des_key_schedule key_schedule;
MakeKey(key, des_key);
des_set_key(&des_key, key_schedule);
#if 0
CHAPDEBUG((LOG_INFO, "DesEncrypt: 8 octet input : %.8B", clear));
#endif
des_ecb_encrypt((des_cblock *)clear, (des_cblock *)cipher, key_schedule, 1);
#if 0
CHAPDEBUG((LOG_INFO, "DesEncrypt: 8 octet output: %.8B", cipher));
#endif
}
#endif /* USE_CRYPT */
static u_char Get7Bits(input, startBit)
u_char *input;
int startBit;
{
register unsigned int word;
word = (unsigned)input[startBit / 8] << 8;
word |= (unsigned)input[startBit / 8 + 1];
word >>= 15 - (startBit % 8 + 7);
return word & 0xFE;
}
#ifdef USE_CRYPT
/* in == 8-byte string (expanded version of the 56-bit key)
* out == 64-byte string where each byte is either 1 or 0
* Note that the low-order "bit" is always ignored by by setkey()
*/
static void Expand(in, out)
u_char *in;
u_char *out;
{
int j, c;
int i;
for(i = 0; i < 64; in++){
c = *in;
for(j = 7; j >= 0; j--)
*out++ = (c >> j) & 01;
i += 8;
}
}
/* The inverse of Expand
*/
static void Collapse(in, out)
u_char *in;
u_char *out;
{
int j;
int i;
unsigned int c;
for (i = 0; i < 64; i += 8, out++) {
c = 0;
for (j = 7; j >= 0; j--, in++)
c |= *in << j;
*out = c & 0xff;
}
}
#endif
static void MakeKey(key, des_key)
u_char *key; /* IN 56 bit DES key missing parity bits */
u_char *des_key; /* OUT 64 bit DES key with parity bits added */
{
des_key[0] = Get7Bits(key, 0);
des_key[1] = Get7Bits(key, 7);
des_key[2] = Get7Bits(key, 14);
des_key[3] = Get7Bits(key, 21);
des_key[4] = Get7Bits(key, 28);
des_key[5] = Get7Bits(key, 35);
des_key[6] = Get7Bits(key, 42);
des_key[7] = Get7Bits(key, 49);
#ifndef USE_CRYPT
des_set_odd_parity((des_cblock *)des_key);
#endif
#if 0
CHAPDEBUG((LOG_INFO, "MakeKey: 56-bit input : %.7B", key));
CHAPDEBUG((LOG_INFO, "MakeKey: 64-bit output: %.8B", des_key));
#endif
}
static void
ChapMS_NT(rchallenge, rchallenge_len, secret, secret_len, response)
char *rchallenge;
int rchallenge_len;
char *secret;
int secret_len;
MS_ChapResponse *response;
{
int i;
#ifdef __NetBSD__
/* NetBSD uses the libc md4 routines which take bytes instead of bits */
int mdlen = secret_len * 2;
#else
int mdlen = secret_len * 2 * 8;
#endif
MD4_CTX md4Context;
u_char hash[MD4_SIGNATURE_SIZE];
u_char unicodePassword[MAX_NT_PASSWORD * 2];
/* Initialize the Unicode version of the secret (== password). */
/* This implicitly supports 8-bit ISO8859/1 characters. */
BZERO(unicodePassword, sizeof(unicodePassword));
for (i = 0; i < secret_len; i++)
unicodePassword[i * 2] = (u_char)secret[i];
MD4Init(&md4Context);
MD4Update(&md4Context, unicodePassword, mdlen);
MD4Final(hash, &md4Context); /* Tell MD4 we're done */
ChallengeResponse(rchallenge, hash, response->NTResp);
}
#ifdef MSLANMAN
static u_char *StdText = (u_char *)"KGS!@#$%"; /* key from rasapi32.dll */
static void
ChapMS_LANMan(rchallenge, rchallenge_len, secret, secret_len, response)
char *rchallenge;
int rchallenge_len;
char *secret;
int secret_len;
MS_ChapResponse *response;
{
int i;
u_char UcasePassword[MAX_NT_PASSWORD]; /* max is actually 14 */
u_char PasswordHash[MD4_SIGNATURE_SIZE];
/* LANMan password is case insensitive */
BZERO(UcasePassword, sizeof(UcasePassword));
for (i = 0; i < secret_len; i++)
UcasePassword[i] = (u_char)toupper(secret[i]);
DesEncrypt( StdText, UcasePassword + 0, PasswordHash + 0 );
DesEncrypt( StdText, UcasePassword + 7, PasswordHash + 8 );
ChallengeResponse(rchallenge, PasswordHash, response->LANManResp);
}
#endif
void
ChapMS(cstate, rchallenge, rchallenge_len, secret, secret_len)
chap_state *cstate;
char *rchallenge;
int rchallenge_len;
char *secret;
int secret_len;
{
MS_ChapResponse response;
#if 0
CHAPDEBUG((LOG_INFO, "ChapMS: secret is '%.*s'", secret_len, secret));
#endif
BZERO(&response, sizeof(response));
/* Calculate both always */
ChapMS_NT(rchallenge, rchallenge_len, secret, secret_len, &response);
#ifdef MSLANMAN
ChapMS_LANMan(rchallenge, rchallenge_len, secret, secret_len, &response);
/* prefered method is set by option */
response.UseNT = !ms_lanman;
#else
response.UseNT = 1;
#endif
BCOPY(&response, cstate->response, MS_CHAP_RESPONSE_LEN);
cstate->resp_length = MS_CHAP_RESPONSE_LEN;
}
#endif /* CHAPMS */

View File

@@ -1,33 +0,0 @@
/*
* chap.h - Challenge Handshake Authentication Protocol definitions.
*
* Copyright (c) 1995 Eric Rosenquist, Strata Software Limited.
* http://www.strataware.com/
*
* All rights reserved.
*
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by Eric Rosenquist. The name of the author may not be used to
* endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* $Id$
*/
#ifndef __CHAPMS_INCLUDE__
#define MD4_SIGNATURE_SIZE 16 /* 16 bytes in a MD4 message digest */
#define MAX_NT_PASSWORD 256 /* Maximum number of (Unicode) chars in an NT password */
void ChapMS __P((chap_state *, char *, int, char *, int));
#define __CHAPMS_INCLUDE__
#endif /* __CHAPMS_INCLUDE__ */

View File

@@ -1,818 +0,0 @@
/*
* Chat -- a program for automatic session establishment (i.e. dial
* the phone and log in).
*
* Standard termination codes:
* 0 - successful completion of the script
* 1 - invalid argument, expect string too large, etc.
* 2 - error on an I/O operation or fatal error condition.
* 3 - timeout waiting for a simple string.
* 4 - the first string declared as "ABORT"
* 5 - the second string declared as "ABORT"
* 6 - ... and so on for successive ABORT strings.
*
* This software is in the public domain.
*
* -----------------
* 22-May-99 added environment substitutuion, enabled with -E switch.
* Andreas Arens <andras@cityweb.de>.
*
* 12-May-99 added a feature to read data to be sent from a file,
* if the send string starts with @. Idea from gpk <gpk@onramp.net>.
*
* added -T and -U option and \T and \U substitution to pass a phone
* number into chat script. Two are needed for some ISDN TA applications.
* Keith Dart <kdart@cisco.com>
*
*
* Added SAY keyword to send output to stderr.
* This allows to turn ECHO OFF and to output specific, user selected,
* text to give progress messages. This best works when stderr
* exists (i.e.: pppd in nodetach mode).
*
* Added HANGUP directives to allow for us to be called
* back. When HANGUP is set to NO, chat will not hangup at HUP signal.
* We rely on timeouts in that case.
*
* Added CLR_ABORT to clear previously set ABORT string. This has been
* dictated by the HANGUP above as "NO CARRIER" (for example) must be
* an ABORT condition until we know the other host is going to close
* the connection for call back. As soon as we have completed the
* first stage of the call back sequence, "NO CARRIER" is a valid, non
* fatal string. As soon as we got called back (probably get "CONNECT"),
* we should re-arm the ABORT "NO CARRIER". Hence the CLR_ABORT command.
* Note that CLR_ABORT packs the abort_strings[] array so that we do not
* have unused entries not being reclaimed.
*
* In the same vein as above, added CLR_REPORT keyword.
*
* Allow for comments. Line starting with '#' are comments and are
* ignored. If a '#' is to be expected as the first character, the
* expect string must be quoted.
*
*
* Francis Demierre <Francis@SwissMail.Com>
* Thu May 15 17:15:40 MET DST 1997
*
*
* Added -r "report file" switch & REPORT keyword.
* Robert Geer <bgeer@xmission.com>
*
* Added -s "use stderr" and -S "don't use syslog" switches.
* June 18, 1997
* Karl O. Pinc <kop@meme.com>
*
*
* Added -e "echo" switch & ECHO keyword
* Dick Streefland <dicks@tasking.nl>
*
*
* Considerable updates and modifications by
* Al Longyear <longyear@pobox.com>
* Paul Mackerras <paulus@cs.anu.edu.au>
*
*
* The original author is:
*
* Karl Fox <karl@MorningStar.Com>
* Morning Star Technologies, Inc.
* 1760 Zollinger Road
* Columbus, OH 43221
* (614)451-1883
*
*/
#include <stdio.h>
#include <ctype.h>
#include <time.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <syslog.h>
#include <termios.h>
#include "pppd.h"
#undef TERMIOS
#define TERMIOS
#define STR_LEN 1024
char temp2[STR_LEN];
#ifndef SIGTYPE
#define SIGTYPE void
#endif
#undef __P
#undef __V
#ifdef __STDC__
#include <stdarg.h>
#define __V(x) x
#define __P(x) x
#else
#include <varargs.h>
#define __V(x) (va_alist) va_dcl
#define __P(x) ()
#define const
#endif
#ifndef O_NONBLOCK
#define O_NONBLOCK O_NDELAY
#endif
/*************** Micro getopt() *********************************************/
#define OPTION(c,v) (_O&2&&**v?*(*v)++:!c||_O&4?0:(!(_O&1)&& \
(--c,++v),_O=4,c&&**v=='-'&&v[0][1]?*++*v=='-'\
&&!v[0][1]?(--c,++v,0):(_O=2,*(*v)++):0))
#define OPTARG(c,v) (_O&2?**v||(++v,--c)?(_O=1,--c,*v++): \
(_O=4,(char*)0):(char*)0)
#define OPTONLYARG(c,v) (_O&2&&**v?(_O=1,--c,*v++):(char*)0)
#define ARG(c,v) (c?(--c,*v++):(char*)0)
#if 0
static int _O = 0; /* Internal state */
#endif
/*************** Micro getopt() *********************************************/
char *program_name;
#define MAX_ABORTS 16
#define MAX_REPORTS 16
#define DEFAULT_CHAT_TIMEOUT 45
#define MAX_TIMEOUTS 10
int echo = 0;
int quiet = 0;
int report = 0;
int use_env = 0;
int exit_code = 0;
char *report_file = (char *) 0;
char *chat_file = (char *) 0;
char *phone_num = (char *) 0;
char *phone_num2 = (char *) 0;
static int ttyfd;
static int timeout = DEFAULT_CHAT_TIMEOUT;
#ifdef TERMIOS
#define term_parms struct termios
#define get_term_param(param) tcgetattr(0, param)
#define set_term_param(param) tcsetattr(0, TCSANOW, param)
struct termios saved_tty_parameters;
#endif
char *fail_reason = (char *)0;
char fail_buffer[50];
char *abort_string[MAX_ABORTS]={"BUSY","NO DIALTONE","NO CARRIER","NO ANSWER","RING\r\nRING"};
int n_aborts = 5;
int abort_next = 0, timeout_next = 0, echo_next = 0;
int clear_abort_next = 0;
char *report_string[MAX_REPORTS] ;
char report_buffer[50] ;
int n_reports = 0, report_next = 0, report_gathering = 0 ;
int clear_report_next = 0;
int say_next = 0, hup_next = 0;
void *dup_mem __P((void *b, size_t c));
void *copy_of __P((char *s));
void break_sequence __P((void));
static int get_string __P((register char *string));
static int put_string __P((register char *s));
static int write_char __P((int c));
static int put_char __P((int c));
static int get_char __P((void));
void chat_send __P((register char *s));
static char *character __P((int c));
void chat_expect __P((register char *s));
static char *clean __P((register char *s, int sending));
char *expect_strtok __P((char *, char *));
int chatmain __P((int, int, char *));
void *dup_mem(b, c)
void *b;
size_t c;
{
void *ans = malloc (c);
if (!ans)
return NULL;
memcpy(ans, b, c);
return ans;
}
void *copy_of (s)
char *s;
{
return dup_mem(s, strlen (s) + 1);
}
char *getnextcommand(char **string)
{
char *buf=*string,*res;
res=strchr(buf,'|');
if (res==NULL)
return NULL;
*res='\0';
*string=res+1;
return buf;
}
int chatmain(int fd, int mode, char *pScript)
{
char *arg;
/* initialize exit code */
exit_code = 0;
ttyfd = fd;
if ( debug ) {
dbglog("chat_main: %s\n", pScript);
}
/* get first expect string */
arg = getnextcommand(&pScript);
while (( arg != NULL ) && ( exit_code == 0 )) {
/* process the expect string */
chat_expect(arg);
if ( exit_code == 0 ) {
/* get the next send string */
arg = getnextcommand(&pScript);
if ( arg != NULL ) {
/* process the send string */
chat_send(arg);
/* get the next expect string */
arg = getnextcommand(&pScript);
}
}
}
ttyfd = (int)-1;
return ( exit_code );
}
void break_sequence()
{
tcsendbreak(ttyfd, 0);
}
/*
* 'Clean up' this string.
*/
static char *clean(s, sending)
register char *s;
int sending; /* set to 1 when sending (putting) this string. */
{
char temp[STR_LEN], env_str[STR_LEN], cur_chr;
register char *s1, *phchar;
int add_return = sending;
#define isoctal(chr) (((chr) >= '0') && ((chr) <= '7'))
#define isalnumx(chr) ((((chr) >= '0') && ((chr) <= '9')) \
|| (((chr) >= 'a') && ((chr) <= 'z')) \
|| (((chr) >= 'A') && ((chr) <= 'Z')) \
|| (chr) == '_')
s1 = temp;
while (*s) {
cur_chr = *s++;
if (cur_chr == '^') {
cur_chr = *s++;
if (cur_chr == '\0') {
*s1++ = '^';
break;
}
cur_chr &= 0x1F;
if (cur_chr != 0) {
*s1++ = cur_chr;
}
continue;
}
if (use_env && cur_chr == '$') { /* ARI */
phchar = env_str;
while (isalnumx(*s))
*phchar++ = *s++;
*phchar = '\0';
phchar = getenv(env_str);
if (phchar)
while (*phchar)
*s1++ = *phchar++;
continue;
}
if (cur_chr != '\\') {
*s1++ = cur_chr;
continue;
}
cur_chr = *s++;
if (cur_chr == '\0') {
if (sending) {
*s1++ = '\\';
*s1++ = '\\';
}
break;
}
switch (cur_chr) {
case 'b':
*s1++ = '\b';
break;
case 'c':
if (sending && *s == '\0')
add_return = 0;
else
*s1++ = cur_chr;
break;
case '\\':
case 'K':
case 'p':
case 'd':
if (sending)
*s1++ = '\\';
*s1++ = cur_chr;
break;
case 'T':
if (sending && phone_num) {
for (phchar = phone_num; *phchar != '\0'; phchar++)
*s1++ = *phchar;
}
else {
*s1++ = '\\';
*s1++ = 'T';
}
break;
case 'U':
if (sending && phone_num2) {
for (phchar = phone_num2; *phchar != '\0'; phchar++)
*s1++ = *phchar;
}
else {
*s1++ = '\\';
*s1++ = 'U';
}
break;
case 'q':
quiet = 1;
break;
case 'r':
*s1++ = '\r';
break;
case 'n':
*s1++ = '\n';
break;
case 's':
*s1++ = ' ';
break;
case 't':
*s1++ = '\t';
break;
case 'N':
if (sending) {
*s1++ = '\\';
*s1++ = '\0';
}
else
*s1++ = 'N';
break;
case '$': /* ARI */
if (use_env) {
*s1++ = cur_chr;
break;
}
/* FALL THROUGH */
default:
if (isoctal (cur_chr)) {
cur_chr &= 0x07;
if (isoctal (*s)) {
cur_chr <<= 3;
cur_chr |= *s++ - '0';
if (isoctal (*s)) {
cur_chr <<= 3;
cur_chr |= *s++ - '0';
}
}
if (cur_chr != 0 || sending) {
if (sending && (cur_chr == '\\' || cur_chr == 0))
*s1++ = '\\';
*s1++ = cur_chr;
}
break;
}
if (sending)
*s1++ = '\\';
*s1++ = cur_chr;
break;
}
}
if (add_return)
*s1++ = '\r';
*s1++ = '\0'; /* guarantee closure */
*s1++ = '\0'; /* terminate the string */
return dup_mem (temp, (size_t) (s1 - temp)); /* may have embedded nuls */
}
/*
* A modified version of 'strtok'. This version skips \ sequences.
*/
char *expect_strtok (s, term)
char *s, *term;
{
static char *str = "";
int escape_flag = 0;
char *result;
/*
* If a string was specified then do initial processing.
*/
if (s)
str = s;
/*
* If this is the escape flag then reset it and ignore the character.
*/
if (*str)
result = str;
else
result = (char *) 0;
while (*str) {
if (escape_flag) {
escape_flag = 0;
++str;
continue;
}
if (*str == '\\') {
++str;
escape_flag = 1;
continue;
}
/*
* If this is not in the termination string, continue.
*/
if (strchr (term, *str) == (char *) 0) {
++str;
continue;
}
/*
* This is the terminator. Mark the end of the string and stop.
*/
*str++ = '\0';
break;
}
return (result);
}
/*
* Process the expect string
*/
void chat_expect (s)
char *s;
{
char *expect;
char *reply;
if (strcmp(s, "HANGUP") == 0) {
++hup_next;
return;
}
if (strcmp(s, "ABORT") == 0) {
++abort_next;
return;
}
if (strcmp(s, "CLR_ABORT") == 0) {
++clear_abort_next;
return;
}
if (strcmp(s, "REPORT") == 0) {
++report_next;
return;
}
if (strcmp(s, "CLR_REPORT") == 0) {
++clear_report_next;
return;
}
if (strcmp(s, "TIMEOUT") == 0) {
++timeout_next;
return;
}
if (strcmp(s, "ECHO") == 0) {
++echo_next;
return;
}
if (strcmp(s, "SAY") == 0) {
++say_next;
return;
}
/*
* Fetch the expect and reply string.
*/
for (;;) {
expect = expect_strtok (s, "-");
s = (char *) 0;
if (expect == (char *) 0)
return;
reply = expect_strtok (s, "-");
/*
* Handle the expect string. If successful then exit.
*/
if (get_string (expect))
return;
/*
* If there is a sub-reply string then send it. Otherwise any condition
* is terminal.
*/
if (reply == (char *) 0 || exit_code != 3)
break;
chat_send (reply);
}
}
/*
* Translate the input character to the appropriate string for printing
* the data.
*/
static char *character(c)
int c;
{
static char string[10];
char *meta;
meta = (c & 0x80) ? "M-" : "";
c &= 0x7F;
if (c < 32)
sprintf(string, "%s^%c", meta, (int)c + '@');
else if (c == 127)
sprintf(string, "%s^?", meta);
else
sprintf(string, "%s%c", meta, c);
return (string);
}
/*
* process the reply string
*/
void chat_send (s)
register char *s;
{
/* char file_data[STR_LEN]; */
if (say_next) {
say_next = 0;
s = clean(s, 1);
write(2, s, strlen(s));
free(s);
return;
}
if (hup_next) {
hup_next = 0;
return;
}
if (echo_next) {
echo_next = 0;
echo = (strcmp(s, "ON") == 0);
return;
}
if (abort_next) {
char *s1;
abort_next = 0;
if ( n_aborts < MAX_ABORTS ) {
s1 = clean(s, 0);
if (( strlen(s1) <= strlen(s) ) &&
( strlen(s1) < sizeof(fail_buffer))) {
abort_string[n_aborts++] = s1;
}
}
return;
}
if (clear_abort_next) {
clear_abort_next = 0;
return;
}
if (report_next) {
report_next = 0;
return;
}
if (clear_report_next) {
clear_report_next = 0;
return;
}
if (timeout_next) {
timeout_next = 0;
timeout = atoi(s);
if (timeout <= 0)
timeout = DEFAULT_CHAT_TIMEOUT;
return;
}
if (strcmp(s, "EOT") == 0)
s = "^D\\c";
else if (strcmp(s, "BREAK") == 0)
s = "\\K\\c";
if (!put_string(s)) {
exit_code = 2;
}
}
static int get_char()
{
int status;
char c;
int tries=MAX_TIMEOUTS;
while(tries)
{
status = read(ttyfd, &c, 1);
switch (status) {
case 1:
return ((int)c & 0x7F);
default:
tries--;
}
}
return -1;
}
static int put_char(c)
int c;
{
char ch = c;
write(ttyfd, &ch, 1);
return 0;
}
static int write_char (c)
int c;
{
if (put_char(c) < 0) {
return (0);
}
return (1);
}
static int put_string (s)
register char *s;
{
quiet = 0;
s = clean(s, 1);
while (*s) {
register char c = *s++;
if (c != '\\') {
if (!write_char (c))
return 0;
continue;
}
c = *s++;
switch (c) {
case 'd':
sleep(1);
break;
case 'K':
break_sequence();
break;
case 'p':
#if 0 /* FIXME!!! */
usleep(10000); /* 1/100th of a second (arg is microseconds) */
#else
sleep(1);
#endif
break;
default:
if (!write_char (c))
return 0;
break;
}
}
return (1);
}
/*
* 'Wait for' this string to appear on this file descriptor.
*/
static int get_string(string)
register char *string;
{
int c, len, minlen;
register char *s = temp2, *end = s + STR_LEN;
char *logged = temp2;
struct termios tios;
memset(temp2, 0, sizeof(temp2));
tcgetattr(ttyfd, &tios);
tios.c_cc[VMIN] = 0;
tios.c_cc[VTIME] = timeout*10/MAX_TIMEOUTS;
tcsetattr(ttyfd, TCSANOW, &tios);
string = clean(string, 0);
len = strlen(string);
minlen = (len > sizeof(fail_buffer)? len: sizeof(fail_buffer)) - 1;
if (len > STR_LEN) {
exit_code = 1;
return 0;
}
if (len == 0) {
return (1);
}
while ( (c = get_char()) >= 0) {
int n, abort_len;
*s++ = c;
*s=0;
if (s - temp2 >= len &&
c == string[len - 1] &&
strncmp(s - len, string, len) == 0) {
return (1);
}
for (n = 0; n < n_aborts; ++n) {
if (s - temp2 >= (abort_len = strlen(abort_string[n])) &&
strncmp(s - abort_len, abort_string[n], abort_len) == 0) {
exit_code = n + 4;
strcpy(fail_reason = fail_buffer, abort_string[n]);
return (0);
}
}
if (s >= end) {
if (logged < s - minlen) {
logged = s;
}
s -= minlen;
memmove(temp2, s, minlen);
logged = temp2 + (logged - s);
s = temp2 + minlen;
}
}
exit_code = 3;
return (0);
}

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